From 718c552901d703c502ccbefdfc3c9028d608b947 Mon Sep 17 00:00:00 2001 From: orivej Date: Thu, 10 Feb 2022 16:44:49 +0300 Subject: Restoring authorship annotation for . Commit 1 of 2. --- contrib/tools/python3/src/Modules/_abc.c | 1548 +- contrib/tools/python3/src/Modules/_asynciomodule.c | 6282 ++-- contrib/tools/python3/src/Modules/_bisectmodule.c | 290 +- .../python3/src/Modules/_blake2/blake2b_impl.c | 850 +- .../python3/src/Modules/_blake2/blake2module.c | 190 +- .../tools/python3/src/Modules/_blake2/blake2ns.h | 64 +- .../python3/src/Modules/_blake2/blake2s_impl.c | 850 +- .../src/Modules/_blake2/clinic/blake2b_impl.c.h | 224 +- .../src/Modules/_blake2/clinic/blake2s_impl.c.h | 224 +- .../src/Modules/_blake2/impl/blake2-config.h | 122 +- .../python3/src/Modules/_blake2/impl/blake2-impl.h | 222 +- .../python3/src/Modules/_blake2/impl/blake2.h | 156 +- .../src/Modules/_blake2/impl/blake2b-load-sse2.h | 118 +- .../src/Modules/_blake2/impl/blake2b-load-sse41.h | 786 +- .../python3/src/Modules/_blake2/impl/blake2b-ref.c | 618 +- .../src/Modules/_blake2/impl/blake2b-round.h | 292 +- .../python3/src/Modules/_blake2/impl/blake2b.c | 678 +- .../src/Modules/_blake2/impl/blake2s-load-sse2.h | 100 +- .../src/Modules/_blake2/impl/blake2s-load-sse41.h | 440 +- .../src/Modules/_blake2/impl/blake2s-load-xop.h | 350 +- .../python3/src/Modules/_blake2/impl/blake2s-ref.c | 586 +- .../src/Modules/_blake2/impl/blake2s-round.h | 152 +- .../python3/src/Modules/_blake2/impl/blake2s.c | 642 +- contrib/tools/python3/src/Modules/_bz2module.c | 1474 +- contrib/tools/python3/src/Modules/_codecsmodule.c | 1940 +- .../tools/python3/src/Modules/_collectionsmodule.c | 4584 +-- .../tools/python3/src/Modules/_contextvarsmodule.c | 104 +- contrib/tools/python3/src/Modules/_csv.c | 3156 +- .../tools/python3/src/Modules/_ctypes/_ctypes.c | 11386 ++++---- .../tools/python3/src/Modules/_ctypes/callbacks.c | 1084 +- .../tools/python3/src/Modules/_ctypes/callproc.c | 3466 +-- contrib/tools/python3/src/Modules/_ctypes/cfield.c | 3022 +- contrib/tools/python3/src/Modules/_ctypes/ctypes.h | 730 +- .../python3/src/Modules/_ctypes/ctypes_dlfcn.h | 54 +- .../python3/src/Modules/_ctypes/darwin/dlfcn.h | 168 +- .../src/Modules/_ctypes/darwin/dlfcn_simple.c | 544 +- .../tools/python3/src/Modules/_ctypes/stgdict.c | 1182 +- .../tools/python3/src/Modules/_datetimemodule.c | 13554 ++++----- .../tools/python3/src/Modules/_decimal/_decimal.c | 11690 ++++---- .../python3/src/Modules/_decimal/docstrings.h | 1768 +- .../src/Modules/_decimal/libmpdec/basearith.c | 1298 +- .../src/Modules/_decimal/libmpdec/basearith.h | 428 +- .../python3/src/Modules/_decimal/libmpdec/bits.h | 368 +- .../src/Modules/_decimal/libmpdec/constants.c | 256 +- .../src/Modules/_decimal/libmpdec/constants.h | 168 +- .../src/Modules/_decimal/libmpdec/context.c | 562 +- .../src/Modules/_decimal/libmpdec/convolute.c | 338 +- .../src/Modules/_decimal/libmpdec/convolute.h | 90 +- .../python3/src/Modules/_decimal/libmpdec/crt.c | 350 +- .../python3/src/Modules/_decimal/libmpdec/crt.h | 84 +- .../src/Modules/_decimal/libmpdec/difradix2.c | 340 +- .../src/Modules/_decimal/libmpdec/difradix2.h | 86 +- .../python3/src/Modules/_decimal/libmpdec/fnt.c | 148 +- .../python3/src/Modules/_decimal/libmpdec/fnt.h | 86 +- .../src/Modules/_decimal/libmpdec/fourstep.c | 506 +- .../src/Modules/_decimal/libmpdec/fourstep.h | 86 +- .../python3/src/Modules/_decimal/libmpdec/io.c | 3140 +- .../src/Modules/_decimal/libmpdec/mpalloc.h | 90 +- .../python3/src/Modules/_decimal/libmpdec/mpd_io.h | 108 +- .../src/Modules/_decimal/libmpdec/mpdecimal.c | 17040 +++++------ .../src/Modules/_decimal/libmpdec/mpdecimal.h | 1576 +- .../src/Modules/_decimal/libmpdec/numbertheory.c | 254 +- .../src/Modules/_decimal/libmpdec/numbertheory.h | 142 +- .../src/Modules/_decimal/libmpdec/sixstep.c | 416 +- .../src/Modules/_decimal/libmpdec/sixstep.h | 86 +- .../src/Modules/_decimal/libmpdec/transpose.c | 540 +- .../src/Modules/_decimal/libmpdec/transpose.h | 114 +- .../src/Modules/_decimal/libmpdec/typearith.h | 1326 +- .../src/Modules/_decimal/libmpdec/umodarith.h | 1284 +- .../src/Modules/_decimal/libmpdec/vccompat.h | 94 +- contrib/tools/python3/src/Modules/_elementtree.c | 7652 ++--- .../tools/python3/src/Modules/_functoolsmodule.c | 2586 +- contrib/tools/python3/src/Modules/_hashopenssl.c | 1218 +- contrib/tools/python3/src/Modules/_heapqmodule.c | 1118 +- contrib/tools/python3/src/Modules/_io/_iomodule.c | 1476 +- contrib/tools/python3/src/Modules/_io/_iomodule.h | 370 +- contrib/tools/python3/src/Modules/_io/bufferedio.c | 5282 ++-- contrib/tools/python3/src/Modules/_io/bytesio.c | 2178 +- .../python3/src/Modules/_io/clinic/_iomodule.c.h | 312 +- .../python3/src/Modules/_io/clinic/bufferedio.c.h | 884 +- .../python3/src/Modules/_io/clinic/bytesio.c.h | 846 +- .../python3/src/Modules/_io/clinic/fileio.c.h | 718 +- .../python3/src/Modules/_io/clinic/iobase.c.h | 542 +- .../python3/src/Modules/_io/clinic/stringio.c.h | 546 +- .../python3/src/Modules/_io/clinic/textio.c.h | 956 +- .../src/Modules/_io/clinic/winconsoleio.c.h | 644 +- contrib/tools/python3/src/Modules/_io/fileio.c | 2414 +- contrib/tools/python3/src/Modules/_io/iobase.c | 2088 +- contrib/tools/python3/src/Modules/_io/stringio.c | 2064 +- contrib/tools/python3/src/Modules/_io/textio.c | 6296 ++-- .../tools/python3/src/Modules/_io/winconsoleio.c | 2318 +- contrib/tools/python3/src/Modules/_json.c | 3320 +-- contrib/tools/python3/src/Modules/_localemodule.c | 1432 +- contrib/tools/python3/src/Modules/_lsprof.c | 1584 +- contrib/tools/python3/src/Modules/_lzmamodule.c | 2988 +- contrib/tools/python3/src/Modules/_math.c | 530 +- contrib/tools/python3/src/Modules/_math.h | 82 +- .../src/Modules/_multiprocessing/multiprocessing.c | 438 +- .../src/Modules/_multiprocessing/multiprocessing.h | 186 +- .../src/Modules/_multiprocessing/semaphore.c | 1338 +- contrib/tools/python3/src/Modules/_opcode.c | 150 +- contrib/tools/python3/src/Modules/_operator.c | 3430 +-- contrib/tools/python3/src/Modules/_pickle.c | 15690 +++++----- .../tools/python3/src/Modules/_posixsubprocess.c | 1568 +- contrib/tools/python3/src/Modules/_queuemodule.c | 782 +- contrib/tools/python3/src/Modules/_randommodule.c | 898 +- contrib/tools/python3/src/Modules/_scproxy.c | 516 +- .../src/Modules/_sha3/clinic/sha3module.c.h | 168 +- .../python3/src/Modules/_sha3/kcp/KeccakHash.c | 164 +- .../python3/src/Modules/_sha3/kcp/KeccakHash.h | 228 +- .../src/Modules/_sha3/kcp/KeccakP-1600-64.macros | 4416 +-- .../src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h | 74 +- .../src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h | 98 +- .../src/Modules/_sha3/kcp/KeccakP-1600-SnP.h | 14 +- .../Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c | 2324 +- .../Modules/_sha3/kcp/KeccakP-1600-opt64-config.h | 6 +- .../src/Modules/_sha3/kcp/KeccakP-1600-opt64.c | 948 +- .../_sha3/kcp/KeccakP-1600-unrolling.macros | 370 +- .../python3/src/Modules/_sha3/kcp/KeccakSponge.c | 184 +- .../python3/src/Modules/_sha3/kcp/KeccakSponge.h | 344 +- .../python3/src/Modules/_sha3/kcp/KeccakSponge.inc | 664 +- .../src/Modules/_sha3/kcp/PlSnP-Fallback.inc | 514 +- .../python3/src/Modules/_sha3/kcp/SnP-Relaned.h | 268 +- .../tools/python3/src/Modules/_sha3/kcp/align.h | 70 +- .../tools/python3/src/Modules/_sha3/sha3module.c | 1436 +- contrib/tools/python3/src/Modules/_sqlite/cache.c | 696 +- contrib/tools/python3/src/Modules/_sqlite/cache.h | 146 +- .../tools/python3/src/Modules/_sqlite/connection.c | 3552 +-- .../tools/python3/src/Modules/_sqlite/connection.h | 244 +- contrib/tools/python3/src/Modules/_sqlite/cursor.c | 1722 +- contrib/tools/python3/src/Modules/_sqlite/cursor.h | 138 +- .../python3/src/Modules/_sqlite/microprotocols.c | 232 +- .../python3/src/Modules/_sqlite/microprotocols.h | 102 +- contrib/tools/python3/src/Modules/_sqlite/module.c | 918 +- contrib/tools/python3/src/Modules/_sqlite/module.h | 104 +- .../python3/src/Modules/_sqlite/prepare_protocol.c | 160 +- .../python3/src/Modules/_sqlite/prepare_protocol.h | 82 +- contrib/tools/python3/src/Modules/_sqlite/row.c | 474 +- contrib/tools/python3/src/Modules/_sqlite/row.h | 78 +- .../tools/python3/src/Modules/_sqlite/statement.c | 958 +- .../tools/python3/src/Modules/_sqlite/statement.h | 118 +- contrib/tools/python3/src/Modules/_sqlite/util.c | 260 +- contrib/tools/python3/src/Modules/_sqlite/util.h | 94 +- contrib/tools/python3/src/Modules/_sqlite/ya.make | 84 +- contrib/tools/python3/src/Modules/_sre.c | 5564 ++-- contrib/tools/python3/src/Modules/_ssl.c | 12408 ++++---- contrib/tools/python3/src/Modules/_ssl_data.h | 2556 +- contrib/tools/python3/src/Modules/_stat.c | 1024 +- contrib/tools/python3/src/Modules/_struct.c | 4412 +-- contrib/tools/python3/src/Modules/_threadmodule.c | 2642 +- contrib/tools/python3/src/Modules/_tracemalloc.c | 2764 +- contrib/tools/python3/src/Modules/_weakref.c | 304 +- contrib/tools/python3/src/Modules/_winapi.c | 3710 +-- .../python3/src/Modules/_xxtestfuzz/_xxtestfuzz.c | 94 +- .../tools/python3/src/Modules/_xxtestfuzz/fuzzer.c | 236 +- contrib/tools/python3/src/Modules/addrinfo.h | 336 +- contrib/tools/python3/src/Modules/arraymodule.c | 5910 ++-- contrib/tools/python3/src/Modules/atexitmodule.c | 654 +- contrib/tools/python3/src/Modules/audioop.c | 3734 +-- contrib/tools/python3/src/Modules/binascii.c | 2874 +- .../python3/src/Modules/cjkcodecs/_codecs_cn.c | 896 +- .../python3/src/Modules/cjkcodecs/_codecs_hk.c | 382 +- .../src/Modules/cjkcodecs/_codecs_iso2022.c | 2286 +- .../python3/src/Modules/cjkcodecs/_codecs_jp.c | 1520 +- .../python3/src/Modules/cjkcodecs/_codecs_kr.c | 936 +- .../python3/src/Modules/cjkcodecs/_codecs_tw.c | 286 +- .../python3/src/Modules/cjkcodecs/alg_jisx0201.h | 130 +- .../python3/src/Modules/cjkcodecs/cjkcodecs.h | 794 +- .../Modules/cjkcodecs/clinic/multibytecodec.c.h | 608 +- .../src/Modules/cjkcodecs/emu_jisx0213_2000.h | 108 +- .../python3/src/Modules/cjkcodecs/mappings_cn.h | 8206 +++--- .../python3/src/Modules/cjkcodecs/mappings_hk.h | 4756 +-- .../src/Modules/cjkcodecs/mappings_jisx0213_pair.h | 118 +- .../python3/src/Modules/cjkcodecs/mappings_jp.h | 9530 +++--- .../python3/src/Modules/cjkcodecs/mappings_kr.h | 6502 ++--- .../python3/src/Modules/cjkcodecs/mappings_tw.h | 5266 ++-- .../python3/src/Modules/cjkcodecs/multibytecodec.c | 4028 +-- .../python3/src/Modules/cjkcodecs/multibytecodec.h | 258 +- contrib/tools/python3/src/Modules/clinic/_abc.c.h | 298 +- .../python3/src/Modules/clinic/_asynciomodule.c.h | 1218 +- .../python3/src/Modules/clinic/_bz2module.c.h | 332 +- .../python3/src/Modules/clinic/_codecsmodule.c.h | 2694 +- .../src/Modules/clinic/_contextvarsmodule.c.h | 42 +- .../python3/src/Modules/clinic/_cryptmodule.c.h | 68 +- .../python3/src/Modules/clinic/_cursesmodule.c.h | 126 +- .../python3/src/Modules/clinic/_datetimemodule.c.h | 68 +- .../python3/src/Modules/clinic/_dbmmodule.c.h | 276 +- .../python3/src/Modules/clinic/_elementtree.c.h | 1222 +- .../python3/src/Modules/clinic/_gdbmmodule.c.h | 488 +- .../python3/src/Modules/clinic/_hashopenssl.c.h | 174 +- .../python3/src/Modules/clinic/_lzmamodule.c.h | 490 +- .../tools/python3/src/Modules/clinic/_opcode.c.h | 60 +- .../tools/python3/src/Modules/clinic/_operator.c.h | 2590 +- .../tools/python3/src/Modules/clinic/_pickle.c.h | 998 +- .../python3/src/Modules/clinic/_queuemodule.c.h | 410 +- contrib/tools/python3/src/Modules/clinic/_sre.c.h | 1398 +- contrib/tools/python3/src/Modules/clinic/_ssl.c.h | 2266 +- .../tools/python3/src/Modules/clinic/_struct.c.h | 568 +- .../tools/python3/src/Modules/clinic/_tkinter.c.h | 1220 +- .../python3/src/Modules/clinic/_tracemalloc.c.h | 368 +- .../tools/python3/src/Modules/clinic/_weakref.c.h | 116 +- .../tools/python3/src/Modules/clinic/_winapi.c.h | 1900 +- .../python3/src/Modules/clinic/arraymodule.c.h | 866 +- .../tools/python3/src/Modules/clinic/audioop.c.h | 1704 +- .../tools/python3/src/Modules/clinic/binascii.c.h | 1010 +- .../python3/src/Modules/clinic/cmathmodule.c.h | 1644 +- .../python3/src/Modules/clinic/fcntlmodule.c.h | 352 +- .../tools/python3/src/Modules/clinic/gcmodule.c.h | 632 +- .../tools/python3/src/Modules/clinic/grpmodule.c.h | 160 +- .../python3/src/Modules/clinic/mathmodule.c.h | 898 +- .../tools/python3/src/Modules/clinic/md5module.c.h | 176 +- .../python3/src/Modules/clinic/posixmodule.c.h | 14412 +++++----- .../tools/python3/src/Modules/clinic/pwdmodule.c.h | 130 +- .../tools/python3/src/Modules/clinic/pyexpat.c.h | 512 +- .../tools/python3/src/Modules/clinic/resource.c.h | 308 +- .../python3/src/Modules/clinic/sha1module.c.h | 176 +- .../python3/src/Modules/clinic/sha256module.c.h | 220 +- .../python3/src/Modules/clinic/sha512module.c.h | 220 +- .../python3/src/Modules/clinic/signalmodule.c.h | 812 +- .../python3/src/Modules/clinic/spwdmodule.c.h | 134 +- .../python3/src/Modules/clinic/symtablemodule.c.h | 54 +- .../python3/src/Modules/clinic/unicodedata.c.h | 708 +- .../python3/src/Modules/clinic/zlibmodule.c.h | 880 +- contrib/tools/python3/src/Modules/cmathmodule.c | 2792 +- contrib/tools/python3/src/Modules/config.c | 594 +- contrib/tools/python3/src/Modules/errnomodule.c | 1250 +- contrib/tools/python3/src/Modules/faulthandler.c | 2520 +- contrib/tools/python3/src/Modules/fcntlmodule.c | 1304 +- contrib/tools/python3/src/Modules/gcmodule.c | 2516 +- contrib/tools/python3/src/Modules/getaddrinfo.c | 1276 +- contrib/tools/python3/src/Modules/getbuildinfo.c | 130 +- contrib/tools/python3/src/Modules/getnameinfo.c | 428 +- contrib/tools/python3/src/Modules/getpath.c | 1058 +- contrib/tools/python3/src/Modules/grpmodule.c | 460 +- contrib/tools/python3/src/Modules/hashlib.h | 116 +- .../tools/python3/src/Modules/itertoolsmodule.c | 8596 +++--- contrib/tools/python3/src/Modules/main.c | 628 +- contrib/tools/python3/src/Modules/mathmodule.c | 4674 +-- contrib/tools/python3/src/Modules/md5module.c | 1142 +- contrib/tools/python3/src/Modules/mmapmodule.c | 2850 +- contrib/tools/python3/src/Modules/overlapped.c | 3290 +-- contrib/tools/python3/src/Modules/parsermodule.c | 2304 +- contrib/tools/python3/src/Modules/posixmodule.c | 28636 +++++++++---------- contrib/tools/python3/src/Modules/posixmodule.h | 46 +- contrib/tools/python3/src/Modules/pwdmodule.c | 440 +- contrib/tools/python3/src/Modules/pyexpat.c | 3280 +-- contrib/tools/python3/src/Modules/resource.c | 862 +- contrib/tools/python3/src/Modules/rotatingtree.c | 242 +- contrib/tools/python3/src/Modules/rotatingtree.h | 54 +- contrib/tools/python3/src/Modules/selectmodule.c | 3848 +-- contrib/tools/python3/src/Modules/sha1module.c | 1098 +- contrib/tools/python3/src/Modules/sha256module.c | 1396 +- contrib/tools/python3/src/Modules/sha512module.c | 1504 +- contrib/tools/python3/src/Modules/signalmodule.c | 2958 +- contrib/tools/python3/src/Modules/socketmodule.c | 16032 +++++------ contrib/tools/python3/src/Modules/socketmodule.h | 578 +- contrib/tools/python3/src/Modules/spwdmodule.c | 460 +- contrib/tools/python3/src/Modules/sre.h | 174 +- contrib/tools/python3/src/Modules/sre_constants.h | 194 +- contrib/tools/python3/src/Modules/sre_lib.h | 3060 +- contrib/tools/python3/src/Modules/symtablemodule.c | 216 +- contrib/tools/python3/src/Modules/syslogmodule.c | 554 +- contrib/tools/python3/src/Modules/termios.c | 1902 +- contrib/tools/python3/src/Modules/testcapi_long.h | 414 +- contrib/tools/python3/src/Modules/timemodule.c | 3382 +-- contrib/tools/python3/src/Modules/tkinter.h | 54 +- contrib/tools/python3/src/Modules/unicodedata.c | 2662 +- contrib/tools/python3/src/Modules/unicodedata_db.h | 11462 ++++---- contrib/tools/python3/src/Modules/unicodename_db.h | 3286 +-- contrib/tools/python3/src/Modules/winreparse.h | 108 +- contrib/tools/python3/src/Modules/ya.make | 280 +- contrib/tools/python3/src/Modules/zlibmodule.c | 2636 +- 272 files changed, 238981 insertions(+), 238981 deletions(-) (limited to 'contrib/tools/python3/src/Modules') diff --git a/contrib/tools/python3/src/Modules/_abc.c b/contrib/tools/python3/src/Modules/_abc.c index 709b52ff96b..82b12be329e 100644 --- a/contrib/tools/python3/src/Modules/_abc.c +++ b/contrib/tools/python3/src/Modules/_abc.c @@ -1,29 +1,29 @@ -/* ABCMeta implementation */ - -#include "Python.h" -#include "clinic/_abc.c.h" - -/*[clinic input] -module _abc -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=964f5328e1aefcda]*/ - -PyDoc_STRVAR(_abc__doc__, -"Module contains faster C implementation of abc.ABCMeta"); - -_Py_IDENTIFIER(__abstractmethods__); -_Py_IDENTIFIER(__class__); -_Py_IDENTIFIER(__dict__); -_Py_IDENTIFIER(__bases__); -_Py_IDENTIFIER(_abc_impl); -_Py_IDENTIFIER(__subclasscheck__); -_Py_IDENTIFIER(__subclasshook__); - +/* ABCMeta implementation */ + +#include "Python.h" +#include "clinic/_abc.c.h" + +/*[clinic input] +module _abc +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=964f5328e1aefcda]*/ + +PyDoc_STRVAR(_abc__doc__, +"Module contains faster C implementation of abc.ABCMeta"); + +_Py_IDENTIFIER(__abstractmethods__); +_Py_IDENTIFIER(__class__); +_Py_IDENTIFIER(__dict__); +_Py_IDENTIFIER(__bases__); +_Py_IDENTIFIER(_abc_impl); +_Py_IDENTIFIER(__subclasscheck__); +_Py_IDENTIFIER(__subclasshook__); + typedef struct { PyTypeObject *_abc_data_type; unsigned long long abc_invalidation_counter; } _abcmodule_state; - + static inline _abcmodule_state* get_abc_state(PyObject *module) { @@ -32,17 +32,17 @@ get_abc_state(PyObject *module) return (_abcmodule_state *)state; } -/* This object stores internal state for ABCs. - Note that we can use normal sets for caches, - since they are never iterated over. */ -typedef struct { - PyObject_HEAD - PyObject *_abc_registry; - PyObject *_abc_cache; /* Normal set of weak references. */ - PyObject *_abc_negative_cache; /* Normal set of weak references. */ - unsigned long long _abc_negative_cache_version; -} _abc_data; - +/* This object stores internal state for ABCs. + Note that we can use normal sets for caches, + since they are never iterated over. */ +typedef struct { + PyObject_HEAD + PyObject *_abc_registry; + PyObject *_abc_cache; /* Normal set of weak references. */ + PyObject *_abc_negative_cache; /* Normal set of weak references. */ + unsigned long long _abc_negative_cache_version; +} _abc_data; + static int abc_data_traverse(_abc_data *self, visitproc visit, void *arg) { @@ -62,40 +62,40 @@ abc_data_clear(_abc_data *self) return 0; } -static void -abc_data_dealloc(_abc_data *self) -{ +static void +abc_data_dealloc(_abc_data *self) +{ PyTypeObject *tp = Py_TYPE(self); (void)abc_data_clear(self); tp->tp_free(self); Py_DECREF(tp); -} - -static PyObject * -abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - _abc_data *self = (_abc_data *) type->tp_alloc(type, 0); +} + +static PyObject * +abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + _abc_data *self = (_abc_data *) type->tp_alloc(type, 0); _abcmodule_state *state = NULL; - if (self == NULL) { - return NULL; - } - + if (self == NULL) { + return NULL; + } + state = PyType_GetModuleState(type); if (state == NULL) { Py_DECREF(self); return NULL; } - self->_abc_registry = NULL; - self->_abc_cache = NULL; - self->_abc_negative_cache = NULL; + self->_abc_registry = NULL; + self->_abc_cache = NULL; + self->_abc_negative_cache = NULL; self->_abc_negative_cache_version = state->abc_invalidation_counter; - return (PyObject *) self; -} - -PyDoc_STRVAR(abc_data_doc, -"Internal state held by ABC machinery."); - + return (PyObject *) self; +} + +PyDoc_STRVAR(abc_data_doc, +"Internal state held by ABC machinery."); + static PyType_Slot _abc_data_type_spec_slots[] = { {Py_tp_doc, (void *)abc_data_doc}, {Py_tp_new, abc_data_new}, @@ -103,8 +103,8 @@ static PyType_Slot _abc_data_type_spec_slots[] = { {Py_tp_traverse, abc_data_traverse}, {Py_tp_clear, abc_data_clear}, {0, 0} -}; - +}; + static PyType_Spec _abc_data_type_spec = { .name = "_abc._abc_data", .basicsize = sizeof(_abc_data), @@ -112,743 +112,743 @@ static PyType_Spec _abc_data_type_spec = { .slots = _abc_data_type_spec_slots, }; -static _abc_data * +static _abc_data * _get_impl(PyObject *module, PyObject *self) -{ +{ _abcmodule_state *state = get_abc_state(module); - PyObject *impl = _PyObject_GetAttrId(self, &PyId__abc_impl); - if (impl == NULL) { - return NULL; - } + PyObject *impl = _PyObject_GetAttrId(self, &PyId__abc_impl); + if (impl == NULL) { + return NULL; + } if (!Py_IS_TYPE(impl, state->_abc_data_type)) { - PyErr_SetString(PyExc_TypeError, "_abc_impl is set to a wrong type"); - Py_DECREF(impl); - return NULL; - } - return (_abc_data *)impl; -} - -static int -_in_weak_set(PyObject *set, PyObject *obj) -{ - if (set == NULL || PySet_GET_SIZE(set) == 0) { - return 0; - } - PyObject *ref = PyWeakref_NewRef(obj, NULL); - if (ref == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_Clear(); - return 0; - } - return -1; - } - int res = PySet_Contains(set, ref); - Py_DECREF(ref); - return res; -} - -static PyObject * -_destroy(PyObject *setweakref, PyObject *objweakref) -{ - PyObject *set; - set = PyWeakref_GET_OBJECT(setweakref); - if (set == Py_None) { - Py_RETURN_NONE; - } - Py_INCREF(set); - if (PySet_Discard(set, objweakref) < 0) { - Py_DECREF(set); - return NULL; - } - Py_DECREF(set); - Py_RETURN_NONE; -} - -static PyMethodDef _destroy_def = { - "_destroy", (PyCFunction) _destroy, METH_O -}; - -static int -_add_to_weak_set(PyObject **pset, PyObject *obj) -{ - if (*pset == NULL) { - *pset = PySet_New(NULL); - if (*pset == NULL) { - return -1; - } - } - - PyObject *set = *pset; - PyObject *ref, *wr; - PyObject *destroy_cb; - wr = PyWeakref_NewRef(set, NULL); - if (wr == NULL) { - return -1; - } - destroy_cb = PyCFunction_NewEx(&_destroy_def, wr, NULL); - if (destroy_cb == NULL) { - Py_DECREF(wr); - return -1; - } - ref = PyWeakref_NewRef(obj, destroy_cb); - Py_DECREF(destroy_cb); - if (ref == NULL) { - Py_DECREF(wr); - return -1; - } - int ret = PySet_Add(set, ref); - Py_DECREF(wr); - Py_DECREF(ref); - return ret; -} - -/*[clinic input] -_abc._reset_registry - - self: object - / - -Internal ABC helper to reset registry of a given class. - -Should be only used by refleak.py -[clinic start generated code]*/ - -static PyObject * -_abc__reset_registry(PyObject *module, PyObject *self) -/*[clinic end generated code: output=92d591a43566cc10 input=12a0b7eb339ac35c]*/ -{ + PyErr_SetString(PyExc_TypeError, "_abc_impl is set to a wrong type"); + Py_DECREF(impl); + return NULL; + } + return (_abc_data *)impl; +} + +static int +_in_weak_set(PyObject *set, PyObject *obj) +{ + if (set == NULL || PySet_GET_SIZE(set) == 0) { + return 0; + } + PyObject *ref = PyWeakref_NewRef(obj, NULL); + if (ref == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + return 0; + } + return -1; + } + int res = PySet_Contains(set, ref); + Py_DECREF(ref); + return res; +} + +static PyObject * +_destroy(PyObject *setweakref, PyObject *objweakref) +{ + PyObject *set; + set = PyWeakref_GET_OBJECT(setweakref); + if (set == Py_None) { + Py_RETURN_NONE; + } + Py_INCREF(set); + if (PySet_Discard(set, objweakref) < 0) { + Py_DECREF(set); + return NULL; + } + Py_DECREF(set); + Py_RETURN_NONE; +} + +static PyMethodDef _destroy_def = { + "_destroy", (PyCFunction) _destroy, METH_O +}; + +static int +_add_to_weak_set(PyObject **pset, PyObject *obj) +{ + if (*pset == NULL) { + *pset = PySet_New(NULL); + if (*pset == NULL) { + return -1; + } + } + + PyObject *set = *pset; + PyObject *ref, *wr; + PyObject *destroy_cb; + wr = PyWeakref_NewRef(set, NULL); + if (wr == NULL) { + return -1; + } + destroy_cb = PyCFunction_NewEx(&_destroy_def, wr, NULL); + if (destroy_cb == NULL) { + Py_DECREF(wr); + return -1; + } + ref = PyWeakref_NewRef(obj, destroy_cb); + Py_DECREF(destroy_cb); + if (ref == NULL) { + Py_DECREF(wr); + return -1; + } + int ret = PySet_Add(set, ref); + Py_DECREF(wr); + Py_DECREF(ref); + return ret; +} + +/*[clinic input] +_abc._reset_registry + + self: object + / + +Internal ABC helper to reset registry of a given class. + +Should be only used by refleak.py +[clinic start generated code]*/ + +static PyObject * +_abc__reset_registry(PyObject *module, PyObject *self) +/*[clinic end generated code: output=92d591a43566cc10 input=12a0b7eb339ac35c]*/ +{ _abc_data *impl = _get_impl(module, self); - if (impl == NULL) { - return NULL; - } - if (impl->_abc_registry != NULL && PySet_Clear(impl->_abc_registry) < 0) { - Py_DECREF(impl); - return NULL; - } - Py_DECREF(impl); - Py_RETURN_NONE; -} - -/*[clinic input] -_abc._reset_caches - - self: object - / - -Internal ABC helper to reset both caches of a given class. - -Should be only used by refleak.py -[clinic start generated code]*/ - -static PyObject * -_abc__reset_caches(PyObject *module, PyObject *self) -/*[clinic end generated code: output=f296f0d5c513f80c input=c0ac616fd8acfb6f]*/ -{ + if (impl == NULL) { + return NULL; + } + if (impl->_abc_registry != NULL && PySet_Clear(impl->_abc_registry) < 0) { + Py_DECREF(impl); + return NULL; + } + Py_DECREF(impl); + Py_RETURN_NONE; +} + +/*[clinic input] +_abc._reset_caches + + self: object + / + +Internal ABC helper to reset both caches of a given class. + +Should be only used by refleak.py +[clinic start generated code]*/ + +static PyObject * +_abc__reset_caches(PyObject *module, PyObject *self) +/*[clinic end generated code: output=f296f0d5c513f80c input=c0ac616fd8acfb6f]*/ +{ _abc_data *impl = _get_impl(module, self); - if (impl == NULL) { - return NULL; - } - if (impl->_abc_cache != NULL && PySet_Clear(impl->_abc_cache) < 0) { - Py_DECREF(impl); - return NULL; - } - /* also the second cache */ - if (impl->_abc_negative_cache != NULL && - PySet_Clear(impl->_abc_negative_cache) < 0) { - Py_DECREF(impl); - return NULL; - } - Py_DECREF(impl); - Py_RETURN_NONE; -} - -/*[clinic input] -_abc._get_dump - - self: object - / - -Internal ABC helper for cache and registry debugging. - -Return shallow copies of registry, of both caches, and -negative cache version. Don't call this function directly, -instead use ABC._dump_registry() for a nice repr. -[clinic start generated code]*/ - -static PyObject * -_abc__get_dump(PyObject *module, PyObject *self) -/*[clinic end generated code: output=9d9569a8e2c1c443 input=2c5deb1bfe9e3c79]*/ -{ + if (impl == NULL) { + return NULL; + } + if (impl->_abc_cache != NULL && PySet_Clear(impl->_abc_cache) < 0) { + Py_DECREF(impl); + return NULL; + } + /* also the second cache */ + if (impl->_abc_negative_cache != NULL && + PySet_Clear(impl->_abc_negative_cache) < 0) { + Py_DECREF(impl); + return NULL; + } + Py_DECREF(impl); + Py_RETURN_NONE; +} + +/*[clinic input] +_abc._get_dump + + self: object + / + +Internal ABC helper for cache and registry debugging. + +Return shallow copies of registry, of both caches, and +negative cache version. Don't call this function directly, +instead use ABC._dump_registry() for a nice repr. +[clinic start generated code]*/ + +static PyObject * +_abc__get_dump(PyObject *module, PyObject *self) +/*[clinic end generated code: output=9d9569a8e2c1c443 input=2c5deb1bfe9e3c79]*/ +{ _abc_data *impl = _get_impl(module, self); - if (impl == NULL) { - return NULL; - } - PyObject *res = Py_BuildValue("NNNK", - PySet_New(impl->_abc_registry), - PySet_New(impl->_abc_cache), - PySet_New(impl->_abc_negative_cache), - impl->_abc_negative_cache_version); - Py_DECREF(impl); - return res; -} - -// Compute set of abstract method names. -static int -compute_abstract_methods(PyObject *self) -{ - int ret = -1; - PyObject *abstracts = PyFrozenSet_New(NULL); - if (abstracts == NULL) { - return -1; - } - - PyObject *ns = NULL, *items = NULL, *bases = NULL; // Py_XDECREF()ed on error. - - /* Stage 1: direct abstract methods. */ - ns = _PyObject_GetAttrId(self, &PyId___dict__); - if (!ns) { - goto error; - } - - // We can't use PyDict_Next(ns) even when ns is dict because - // _PyObject_IsAbstract() can mutate ns. - items = PyMapping_Items(ns); - if (!items) { - goto error; - } - assert(PyList_Check(items)); - for (Py_ssize_t pos = 0; pos < PyList_GET_SIZE(items); pos++) { - PyObject *it = PySequence_Fast( - PyList_GET_ITEM(items, pos), - "items() returned non-iterable"); - if (!it) { - goto error; - } - if (PySequence_Fast_GET_SIZE(it) != 2) { - PyErr_SetString(PyExc_TypeError, - "items() returned item which size is not 2"); - Py_DECREF(it); - goto error; - } - - // borrowed - PyObject *key = PySequence_Fast_GET_ITEM(it, 0); - PyObject *value = PySequence_Fast_GET_ITEM(it, 1); - // items or it may be cleared while accessing __abstractmethod__ - // So we need to keep strong reference for key - Py_INCREF(key); - int is_abstract = _PyObject_IsAbstract(value); - if (is_abstract < 0 || - (is_abstract && PySet_Add(abstracts, key) < 0)) { - Py_DECREF(it); - Py_DECREF(key); - goto error; - } - Py_DECREF(key); - Py_DECREF(it); - } - - /* Stage 2: inherited abstract methods. */ - bases = _PyObject_GetAttrId(self, &PyId___bases__); - if (!bases) { - goto error; - } - if (!PyTuple_Check(bases)) { - PyErr_SetString(PyExc_TypeError, "__bases__ is not tuple"); - goto error; - } - - for (Py_ssize_t pos = 0; pos < PyTuple_GET_SIZE(bases); pos++) { - PyObject *item = PyTuple_GET_ITEM(bases, pos); // borrowed - PyObject *base_abstracts, *iter; - - if (_PyObject_LookupAttrId(item, &PyId___abstractmethods__, - &base_abstracts) < 0) { - goto error; - } - if (base_abstracts == NULL) { - continue; - } - if (!(iter = PyObject_GetIter(base_abstracts))) { - Py_DECREF(base_abstracts); - goto error; - } - Py_DECREF(base_abstracts); - PyObject *key, *value; - while ((key = PyIter_Next(iter))) { - if (_PyObject_LookupAttr(self, key, &value) < 0) { - Py_DECREF(key); - Py_DECREF(iter); - goto error; - } - if (value == NULL) { - Py_DECREF(key); - continue; - } - - int is_abstract = _PyObject_IsAbstract(value); - Py_DECREF(value); - if (is_abstract < 0 || - (is_abstract && PySet_Add(abstracts, key) < 0)) - { - Py_DECREF(key); - Py_DECREF(iter); - goto error; - } - Py_DECREF(key); - } - Py_DECREF(iter); - if (PyErr_Occurred()) { - goto error; - } - } - - if (_PyObject_SetAttrId(self, &PyId___abstractmethods__, abstracts) < 0) { - goto error; - } - - ret = 0; -error: - Py_DECREF(abstracts); - Py_XDECREF(ns); - Py_XDECREF(items); - Py_XDECREF(bases); - return ret; -} - -/*[clinic input] -_abc._abc_init - - self: object - / - -Internal ABC helper for class set-up. Should be never used outside abc module. -[clinic start generated code]*/ - -static PyObject * -_abc__abc_init(PyObject *module, PyObject *self) -/*[clinic end generated code: output=594757375714cda1 input=8d7fe470ff77f029]*/ -{ + if (impl == NULL) { + return NULL; + } + PyObject *res = Py_BuildValue("NNNK", + PySet_New(impl->_abc_registry), + PySet_New(impl->_abc_cache), + PySet_New(impl->_abc_negative_cache), + impl->_abc_negative_cache_version); + Py_DECREF(impl); + return res; +} + +// Compute set of abstract method names. +static int +compute_abstract_methods(PyObject *self) +{ + int ret = -1; + PyObject *abstracts = PyFrozenSet_New(NULL); + if (abstracts == NULL) { + return -1; + } + + PyObject *ns = NULL, *items = NULL, *bases = NULL; // Py_XDECREF()ed on error. + + /* Stage 1: direct abstract methods. */ + ns = _PyObject_GetAttrId(self, &PyId___dict__); + if (!ns) { + goto error; + } + + // We can't use PyDict_Next(ns) even when ns is dict because + // _PyObject_IsAbstract() can mutate ns. + items = PyMapping_Items(ns); + if (!items) { + goto error; + } + assert(PyList_Check(items)); + for (Py_ssize_t pos = 0; pos < PyList_GET_SIZE(items); pos++) { + PyObject *it = PySequence_Fast( + PyList_GET_ITEM(items, pos), + "items() returned non-iterable"); + if (!it) { + goto error; + } + if (PySequence_Fast_GET_SIZE(it) != 2) { + PyErr_SetString(PyExc_TypeError, + "items() returned item which size is not 2"); + Py_DECREF(it); + goto error; + } + + // borrowed + PyObject *key = PySequence_Fast_GET_ITEM(it, 0); + PyObject *value = PySequence_Fast_GET_ITEM(it, 1); + // items or it may be cleared while accessing __abstractmethod__ + // So we need to keep strong reference for key + Py_INCREF(key); + int is_abstract = _PyObject_IsAbstract(value); + if (is_abstract < 0 || + (is_abstract && PySet_Add(abstracts, key) < 0)) { + Py_DECREF(it); + Py_DECREF(key); + goto error; + } + Py_DECREF(key); + Py_DECREF(it); + } + + /* Stage 2: inherited abstract methods. */ + bases = _PyObject_GetAttrId(self, &PyId___bases__); + if (!bases) { + goto error; + } + if (!PyTuple_Check(bases)) { + PyErr_SetString(PyExc_TypeError, "__bases__ is not tuple"); + goto error; + } + + for (Py_ssize_t pos = 0; pos < PyTuple_GET_SIZE(bases); pos++) { + PyObject *item = PyTuple_GET_ITEM(bases, pos); // borrowed + PyObject *base_abstracts, *iter; + + if (_PyObject_LookupAttrId(item, &PyId___abstractmethods__, + &base_abstracts) < 0) { + goto error; + } + if (base_abstracts == NULL) { + continue; + } + if (!(iter = PyObject_GetIter(base_abstracts))) { + Py_DECREF(base_abstracts); + goto error; + } + Py_DECREF(base_abstracts); + PyObject *key, *value; + while ((key = PyIter_Next(iter))) { + if (_PyObject_LookupAttr(self, key, &value) < 0) { + Py_DECREF(key); + Py_DECREF(iter); + goto error; + } + if (value == NULL) { + Py_DECREF(key); + continue; + } + + int is_abstract = _PyObject_IsAbstract(value); + Py_DECREF(value); + if (is_abstract < 0 || + (is_abstract && PySet_Add(abstracts, key) < 0)) + { + Py_DECREF(key); + Py_DECREF(iter); + goto error; + } + Py_DECREF(key); + } + Py_DECREF(iter); + if (PyErr_Occurred()) { + goto error; + } + } + + if (_PyObject_SetAttrId(self, &PyId___abstractmethods__, abstracts) < 0) { + goto error; + } + + ret = 0; +error: + Py_DECREF(abstracts); + Py_XDECREF(ns); + Py_XDECREF(items); + Py_XDECREF(bases); + return ret; +} + +/*[clinic input] +_abc._abc_init + + self: object + / + +Internal ABC helper for class set-up. Should be never used outside abc module. +[clinic start generated code]*/ + +static PyObject * +_abc__abc_init(PyObject *module, PyObject *self) +/*[clinic end generated code: output=594757375714cda1 input=8d7fe470ff77f029]*/ +{ _abcmodule_state *state = get_abc_state(module); - PyObject *data; - if (compute_abstract_methods(self) < 0) { - return NULL; - } - - /* Set up inheritance registry. */ + PyObject *data; + if (compute_abstract_methods(self) < 0) { + return NULL; + } + + /* Set up inheritance registry. */ data = abc_data_new(state->_abc_data_type, NULL, NULL); - if (data == NULL) { - return NULL; - } - if (_PyObject_SetAttrId(self, &PyId__abc_impl, data) < 0) { - Py_DECREF(data); - return NULL; - } - Py_DECREF(data); - Py_RETURN_NONE; -} - -/*[clinic input] -_abc._abc_register - - self: object - subclass: object - / - -Internal ABC helper for subclasss registration. Should be never used outside abc module. -[clinic start generated code]*/ - -static PyObject * -_abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) -/*[clinic end generated code: output=7851e7668c963524 input=ca589f8c3080e67f]*/ -{ - if (!PyType_Check(subclass)) { - PyErr_SetString(PyExc_TypeError, "Can only register classes"); - return NULL; - } - int result = PyObject_IsSubclass(subclass, self); - if (result > 0) { - Py_INCREF(subclass); - return subclass; /* Already a subclass. */ - } - if (result < 0) { - return NULL; - } - /* Subtle: test for cycles *after* testing for "already a subclass"; - this means we allow X.register(X) and interpret it as a no-op. */ - result = PyObject_IsSubclass(self, subclass); - if (result > 0) { - /* This would create a cycle, which is bad for the algorithm below. */ - PyErr_SetString(PyExc_RuntimeError, "Refusing to create an inheritance cycle"); - return NULL; - } - if (result < 0) { - return NULL; - } + if (data == NULL) { + return NULL; + } + if (_PyObject_SetAttrId(self, &PyId__abc_impl, data) < 0) { + Py_DECREF(data); + return NULL; + } + Py_DECREF(data); + Py_RETURN_NONE; +} + +/*[clinic input] +_abc._abc_register + + self: object + subclass: object + / + +Internal ABC helper for subclasss registration. Should be never used outside abc module. +[clinic start generated code]*/ + +static PyObject * +_abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) +/*[clinic end generated code: output=7851e7668c963524 input=ca589f8c3080e67f]*/ +{ + if (!PyType_Check(subclass)) { + PyErr_SetString(PyExc_TypeError, "Can only register classes"); + return NULL; + } + int result = PyObject_IsSubclass(subclass, self); + if (result > 0) { + Py_INCREF(subclass); + return subclass; /* Already a subclass. */ + } + if (result < 0) { + return NULL; + } + /* Subtle: test for cycles *after* testing for "already a subclass"; + this means we allow X.register(X) and interpret it as a no-op. */ + result = PyObject_IsSubclass(self, subclass); + if (result > 0) { + /* This would create a cycle, which is bad for the algorithm below. */ + PyErr_SetString(PyExc_RuntimeError, "Refusing to create an inheritance cycle"); + return NULL; + } + if (result < 0) { + return NULL; + } _abc_data *impl = _get_impl(module, self); - if (impl == NULL) { - return NULL; - } - if (_add_to_weak_set(&impl->_abc_registry, subclass) < 0) { - Py_DECREF(impl); - return NULL; - } - Py_DECREF(impl); - - /* Invalidate negative cache */ + if (impl == NULL) { + return NULL; + } + if (_add_to_weak_set(&impl->_abc_registry, subclass) < 0) { + Py_DECREF(impl); + return NULL; + } + Py_DECREF(impl); + + /* Invalidate negative cache */ get_abc_state(module)->abc_invalidation_counter++; - - Py_INCREF(subclass); - return subclass; -} - - -/*[clinic input] -_abc._abc_instancecheck - - self: object - instance: object - / - -Internal ABC helper for instance checks. Should be never used outside abc module. -[clinic start generated code]*/ - -static PyObject * -_abc__abc_instancecheck_impl(PyObject *module, PyObject *self, - PyObject *instance) -/*[clinic end generated code: output=b8b5148f63b6b56f input=a4f4525679261084]*/ -{ - PyObject *subtype, *result = NULL, *subclass = NULL; + + Py_INCREF(subclass); + return subclass; +} + + +/*[clinic input] +_abc._abc_instancecheck + + self: object + instance: object + / + +Internal ABC helper for instance checks. Should be never used outside abc module. +[clinic start generated code]*/ + +static PyObject * +_abc__abc_instancecheck_impl(PyObject *module, PyObject *self, + PyObject *instance) +/*[clinic end generated code: output=b8b5148f63b6b56f input=a4f4525679261084]*/ +{ + PyObject *subtype, *result = NULL, *subclass = NULL; _abc_data *impl = _get_impl(module, self); - if (impl == NULL) { - return NULL; - } - - subclass = _PyObject_GetAttrId(instance, &PyId___class__); - if (subclass == NULL) { - Py_DECREF(impl); - return NULL; - } - /* Inline the cache checking. */ - int incache = _in_weak_set(impl->_abc_cache, subclass); - if (incache < 0) { - goto end; - } - if (incache > 0) { - result = Py_True; - Py_INCREF(result); - goto end; - } - subtype = (PyObject *)Py_TYPE(instance); - if (subtype == subclass) { + if (impl == NULL) { + return NULL; + } + + subclass = _PyObject_GetAttrId(instance, &PyId___class__); + if (subclass == NULL) { + Py_DECREF(impl); + return NULL; + } + /* Inline the cache checking. */ + int incache = _in_weak_set(impl->_abc_cache, subclass); + if (incache < 0) { + goto end; + } + if (incache > 0) { + result = Py_True; + Py_INCREF(result); + goto end; + } + subtype = (PyObject *)Py_TYPE(instance); + if (subtype == subclass) { if (impl->_abc_negative_cache_version == get_abc_state(module)->abc_invalidation_counter) { - incache = _in_weak_set(impl->_abc_negative_cache, subclass); - if (incache < 0) { - goto end; - } - if (incache > 0) { - result = Py_False; - Py_INCREF(result); - goto end; - } - } - /* Fall back to the subclass check. */ + incache = _in_weak_set(impl->_abc_negative_cache, subclass); + if (incache < 0) { + goto end; + } + if (incache > 0) { + result = Py_False; + Py_INCREF(result); + goto end; + } + } + /* Fall back to the subclass check. */ result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, subclass); - goto end; - } + goto end; + } result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, subclass); - if (result == NULL) { - goto end; - } - - switch (PyObject_IsTrue(result)) { - case -1: - Py_DECREF(result); - result = NULL; - break; - case 0: - Py_DECREF(result); + if (result == NULL) { + goto end; + } + + switch (PyObject_IsTrue(result)) { + case -1: + Py_DECREF(result); + result = NULL; + break; + case 0: + Py_DECREF(result); result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, subtype); - break; - case 1: // Nothing to do. - break; - default: - Py_UNREACHABLE(); - } - -end: - Py_XDECREF(impl); - Py_XDECREF(subclass); - return result; -} - - + break; + case 1: // Nothing to do. + break; + default: + Py_UNREACHABLE(); + } + +end: + Py_XDECREF(impl); + Py_XDECREF(subclass); + return result; +} + + // Return -1 when exception occurred. -// Return 1 when result is set. -// Return 0 otherwise. -static int subclasscheck_check_registry(_abc_data *impl, PyObject *subclass, - PyObject **result); - -/*[clinic input] -_abc._abc_subclasscheck - - self: object - subclass: object - / - -Internal ABC helper for subclasss checks. Should be never used outside abc module. -[clinic start generated code]*/ - -static PyObject * -_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, - PyObject *subclass) -/*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/ -{ - if (!PyType_Check(subclass)) { - PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class"); - return NULL; - } - - PyObject *ok, *subclasses = NULL, *result = NULL; +// Return 1 when result is set. +// Return 0 otherwise. +static int subclasscheck_check_registry(_abc_data *impl, PyObject *subclass, + PyObject **result); + +/*[clinic input] +_abc._abc_subclasscheck + + self: object + subclass: object + / + +Internal ABC helper for subclasss checks. Should be never used outside abc module. +[clinic start generated code]*/ + +static PyObject * +_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, + PyObject *subclass) +/*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/ +{ + if (!PyType_Check(subclass)) { + PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class"); + return NULL; + } + + PyObject *ok, *subclasses = NULL, *result = NULL; _abcmodule_state *state = NULL; - Py_ssize_t pos; - int incache; + Py_ssize_t pos; + int incache; _abc_data *impl = _get_impl(module, self); - if (impl == NULL) { - return NULL; - } - - /* 1. Check cache. */ - incache = _in_weak_set(impl->_abc_cache, subclass); - if (incache < 0) { - goto end; - } - if (incache > 0) { - result = Py_True; - goto end; - } - + if (impl == NULL) { + return NULL; + } + + /* 1. Check cache. */ + incache = _in_weak_set(impl->_abc_cache, subclass); + if (incache < 0) { + goto end; + } + if (incache > 0) { + result = Py_True; + goto end; + } + state = get_abc_state(module); - /* 2. Check negative cache; may have to invalidate. */ + /* 2. Check negative cache; may have to invalidate. */ if (impl->_abc_negative_cache_version < state->abc_invalidation_counter) { - /* Invalidate the negative cache. */ - if (impl->_abc_negative_cache != NULL && - PySet_Clear(impl->_abc_negative_cache) < 0) - { - goto end; - } + /* Invalidate the negative cache. */ + if (impl->_abc_negative_cache != NULL && + PySet_Clear(impl->_abc_negative_cache) < 0) + { + goto end; + } impl->_abc_negative_cache_version = state->abc_invalidation_counter; - } - else { - incache = _in_weak_set(impl->_abc_negative_cache, subclass); - if (incache < 0) { - goto end; - } - if (incache > 0) { - result = Py_False; - goto end; - } - } - - /* 3. Check the subclass hook. */ + } + else { + incache = _in_weak_set(impl->_abc_negative_cache, subclass); + if (incache < 0) { + goto end; + } + if (incache > 0) { + result = Py_False; + goto end; + } + } + + /* 3. Check the subclass hook. */ ok = _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId___subclasshook__, subclass); - if (ok == NULL) { - goto end; - } - if (ok == Py_True) { - Py_DECREF(ok); - if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { - goto end; - } - result = Py_True; - goto end; - } - if (ok == Py_False) { - Py_DECREF(ok); - if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) { - goto end; - } - result = Py_False; - goto end; - } - if (ok != Py_NotImplemented) { - Py_DECREF(ok); - PyErr_SetString(PyExc_AssertionError, "__subclasshook__ must return either" - " False, True, or NotImplemented"); - goto end; - } - Py_DECREF(ok); - - /* 4. Check if it's a direct subclass. */ - PyObject *mro = ((PyTypeObject *)subclass)->tp_mro; - assert(PyTuple_Check(mro)); - for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) { - PyObject *mro_item = PyTuple_GET_ITEM(mro, pos); - assert(mro_item != NULL); - if ((PyObject *)self == mro_item) { - if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { - goto end; - } - result = Py_True; - goto end; - } - } - - /* 5. Check if it's a subclass of a registered class (recursive). */ - if (subclasscheck_check_registry(impl, subclass, &result)) { + if (ok == NULL) { + goto end; + } + if (ok == Py_True) { + Py_DECREF(ok); + if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { + goto end; + } + result = Py_True; + goto end; + } + if (ok == Py_False) { + Py_DECREF(ok); + if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) { + goto end; + } + result = Py_False; + goto end; + } + if (ok != Py_NotImplemented) { + Py_DECREF(ok); + PyErr_SetString(PyExc_AssertionError, "__subclasshook__ must return either" + " False, True, or NotImplemented"); + goto end; + } + Py_DECREF(ok); + + /* 4. Check if it's a direct subclass. */ + PyObject *mro = ((PyTypeObject *)subclass)->tp_mro; + assert(PyTuple_Check(mro)); + for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) { + PyObject *mro_item = PyTuple_GET_ITEM(mro, pos); + assert(mro_item != NULL); + if ((PyObject *)self == mro_item) { + if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { + goto end; + } + result = Py_True; + goto end; + } + } + + /* 5. Check if it's a subclass of a registered class (recursive). */ + if (subclasscheck_check_registry(impl, subclass, &result)) { // Exception occurred or result is set. - goto end; - } - - /* 6. Check if it's a subclass of a subclass (recursive). */ - subclasses = PyObject_CallMethod(self, "__subclasses__", NULL); - if (subclasses == NULL) { - goto end; - } - if (!PyList_Check(subclasses)) { - PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list"); - goto end; - } - for (pos = 0; pos < PyList_GET_SIZE(subclasses); pos++) { - PyObject *scls = PyList_GET_ITEM(subclasses, pos); - Py_INCREF(scls); - int r = PyObject_IsSubclass(subclass, scls); - Py_DECREF(scls); - if (r > 0) { - if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { - goto end; - } - result = Py_True; - goto end; - } - if (r < 0) { - goto end; - } - } - - /* No dice; update negative cache. */ - if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) { - goto end; - } - result = Py_False; - -end: - Py_DECREF(impl); - Py_XDECREF(subclasses); - Py_XINCREF(result); - return result; -} - - -static int -subclasscheck_check_registry(_abc_data *impl, PyObject *subclass, - PyObject **result) -{ - // Fast path: check subclass is in weakref directly. - int ret = _in_weak_set(impl->_abc_registry, subclass); - if (ret < 0) { - *result = NULL; - return -1; - } - if (ret > 0) { - *result = Py_True; - return 1; - } - - if (impl->_abc_registry == NULL) { - return 0; - } - Py_ssize_t registry_size = PySet_Size(impl->_abc_registry); - if (registry_size == 0) { - return 0; - } - // Weakref callback may remove entry from set. - // So we take snapshot of registry first. - PyObject **copy = PyMem_Malloc(sizeof(PyObject*) * registry_size); - if (copy == NULL) { - PyErr_NoMemory(); - return -1; - } - PyObject *key; - Py_ssize_t pos = 0; - Py_hash_t hash; - Py_ssize_t i = 0; - - while (_PySet_NextEntry(impl->_abc_registry, &pos, &key, &hash)) { - Py_INCREF(key); - copy[i++] = key; - } - assert(i == registry_size); - - for (i = 0; i < registry_size; i++) { - PyObject *rkey = PyWeakref_GetObject(copy[i]); - if (rkey == NULL) { - // Someone inject non-weakref type in the registry. - ret = -1; - break; - } - if (rkey == Py_None) { - continue; - } - Py_INCREF(rkey); - int r = PyObject_IsSubclass(subclass, rkey); - Py_DECREF(rkey); - if (r < 0) { - ret = -1; - break; - } - if (r > 0) { - if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { - ret = -1; - break; - } - *result = Py_True; - ret = 1; - break; - } - } - - for (i = 0; i < registry_size; i++) { - Py_DECREF(copy[i]); - } - PyMem_Free(copy); - return ret; -} - -/*[clinic input] -_abc.get_cache_token - -Returns the current ABC cache token. - -The token is an opaque object (supporting equality testing) identifying the -current version of the ABC cache for virtual subclasses. The token changes -with every call to register() on any ABC. -[clinic start generated code]*/ - -static PyObject * -_abc_get_cache_token_impl(PyObject *module) -/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/ -{ + goto end; + } + + /* 6. Check if it's a subclass of a subclass (recursive). */ + subclasses = PyObject_CallMethod(self, "__subclasses__", NULL); + if (subclasses == NULL) { + goto end; + } + if (!PyList_Check(subclasses)) { + PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list"); + goto end; + } + for (pos = 0; pos < PyList_GET_SIZE(subclasses); pos++) { + PyObject *scls = PyList_GET_ITEM(subclasses, pos); + Py_INCREF(scls); + int r = PyObject_IsSubclass(subclass, scls); + Py_DECREF(scls); + if (r > 0) { + if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { + goto end; + } + result = Py_True; + goto end; + } + if (r < 0) { + goto end; + } + } + + /* No dice; update negative cache. */ + if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) { + goto end; + } + result = Py_False; + +end: + Py_DECREF(impl); + Py_XDECREF(subclasses); + Py_XINCREF(result); + return result; +} + + +static int +subclasscheck_check_registry(_abc_data *impl, PyObject *subclass, + PyObject **result) +{ + // Fast path: check subclass is in weakref directly. + int ret = _in_weak_set(impl->_abc_registry, subclass); + if (ret < 0) { + *result = NULL; + return -1; + } + if (ret > 0) { + *result = Py_True; + return 1; + } + + if (impl->_abc_registry == NULL) { + return 0; + } + Py_ssize_t registry_size = PySet_Size(impl->_abc_registry); + if (registry_size == 0) { + return 0; + } + // Weakref callback may remove entry from set. + // So we take snapshot of registry first. + PyObject **copy = PyMem_Malloc(sizeof(PyObject*) * registry_size); + if (copy == NULL) { + PyErr_NoMemory(); + return -1; + } + PyObject *key; + Py_ssize_t pos = 0; + Py_hash_t hash; + Py_ssize_t i = 0; + + while (_PySet_NextEntry(impl->_abc_registry, &pos, &key, &hash)) { + Py_INCREF(key); + copy[i++] = key; + } + assert(i == registry_size); + + for (i = 0; i < registry_size; i++) { + PyObject *rkey = PyWeakref_GetObject(copy[i]); + if (rkey == NULL) { + // Someone inject non-weakref type in the registry. + ret = -1; + break; + } + if (rkey == Py_None) { + continue; + } + Py_INCREF(rkey); + int r = PyObject_IsSubclass(subclass, rkey); + Py_DECREF(rkey); + if (r < 0) { + ret = -1; + break; + } + if (r > 0) { + if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { + ret = -1; + break; + } + *result = Py_True; + ret = 1; + break; + } + } + + for (i = 0; i < registry_size; i++) { + Py_DECREF(copy[i]); + } + PyMem_Free(copy); + return ret; +} + +/*[clinic input] +_abc.get_cache_token + +Returns the current ABC cache token. + +The token is an opaque object (supporting equality testing) identifying the +current version of the ABC cache for virtual subclasses. The token changes +with every call to register() on any ABC. +[clinic start generated code]*/ + +static PyObject * +_abc_get_cache_token_impl(PyObject *module) +/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/ +{ _abcmodule_state *state = get_abc_state(module); return PyLong_FromUnsignedLongLong(state->abc_invalidation_counter); -} - +} + static struct PyMethodDef _abcmodule_methods[] = { - _ABC_GET_CACHE_TOKEN_METHODDEF - _ABC__ABC_INIT_METHODDEF - _ABC__RESET_REGISTRY_METHODDEF - _ABC__RESET_CACHES_METHODDEF - _ABC__GET_DUMP_METHODDEF - _ABC__ABC_REGISTER_METHODDEF - _ABC__ABC_INSTANCECHECK_METHODDEF - _ABC__ABC_SUBCLASSCHECK_METHODDEF - {NULL, NULL} /* sentinel */ -}; - + _ABC_GET_CACHE_TOKEN_METHODDEF + _ABC__ABC_INIT_METHODDEF + _ABC__RESET_REGISTRY_METHODDEF + _ABC__RESET_CACHES_METHODDEF + _ABC__GET_DUMP_METHODDEF + _ABC__ABC_REGISTER_METHODDEF + _ABC__ABC_INSTANCECHECK_METHODDEF + _ABC__ABC_SUBCLASSCHECK_METHODDEF + {NULL, NULL} /* sentinel */ +}; + static int _abcmodule_exec(PyObject *module) { @@ -889,20 +889,20 @@ static PyModuleDef_Slot _abcmodule_slots[] = { {0, NULL} }; -static struct PyModuleDef _abcmodule = { - PyModuleDef_HEAD_INIT, - "_abc", - _abc__doc__, +static struct PyModuleDef _abcmodule = { + PyModuleDef_HEAD_INIT, + "_abc", + _abc__doc__, sizeof(_abcmodule_state), _abcmodule_methods, _abcmodule_slots, _abcmodule_traverse, _abcmodule_clear, _abcmodule_free, -}; - -PyMODINIT_FUNC -PyInit__abc(void) -{ +}; + +PyMODINIT_FUNC +PyInit__abc(void) +{ return PyModuleDef_Init(&_abcmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/_asynciomodule.c b/contrib/tools/python3/src/Modules/_asynciomodule.c index a1421cf5dbe..fd152ed0472 100644 --- a/contrib/tools/python3/src/Modules/_asynciomodule.c +++ b/contrib/tools/python3/src/Modules/_asynciomodule.c @@ -1,296 +1,296 @@ -#include "Python.h" +#include "Python.h" #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include // offsetof() - - -/*[clinic input] -module _asyncio -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/ - - -/* identifiers used from some functions */ -_Py_IDENTIFIER(__asyncio_running_event_loop__); + + +/*[clinic input] +module _asyncio +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/ + + +/* identifiers used from some functions */ +_Py_IDENTIFIER(__asyncio_running_event_loop__); _Py_IDENTIFIER(_asyncio_future_blocking); -_Py_IDENTIFIER(add_done_callback); -_Py_IDENTIFIER(call_soon); -_Py_IDENTIFIER(cancel); -_Py_IDENTIFIER(get_event_loop); -_Py_IDENTIFIER(send); -_Py_IDENTIFIER(throw); - - -/* State of the _asyncio module */ -static PyObject *asyncio_mod; -static PyObject *traceback_extract_stack; -static PyObject *asyncio_get_event_loop_policy; -static PyObject *asyncio_future_repr_info_func; -static PyObject *asyncio_iscoroutine_func; -static PyObject *asyncio_task_get_stack_func; -static PyObject *asyncio_task_print_stack_func; -static PyObject *asyncio_task_repr_info_func; -static PyObject *asyncio_InvalidStateError; -static PyObject *asyncio_CancelledError; -static PyObject *context_kwname; +_Py_IDENTIFIER(add_done_callback); +_Py_IDENTIFIER(call_soon); +_Py_IDENTIFIER(cancel); +_Py_IDENTIFIER(get_event_loop); +_Py_IDENTIFIER(send); +_Py_IDENTIFIER(throw); + + +/* State of the _asyncio module */ +static PyObject *asyncio_mod; +static PyObject *traceback_extract_stack; +static PyObject *asyncio_get_event_loop_policy; +static PyObject *asyncio_future_repr_info_func; +static PyObject *asyncio_iscoroutine_func; +static PyObject *asyncio_task_get_stack_func; +static PyObject *asyncio_task_print_stack_func; +static PyObject *asyncio_task_repr_info_func; +static PyObject *asyncio_InvalidStateError; +static PyObject *asyncio_CancelledError; +static PyObject *context_kwname; static int module_initialized; - -static PyObject *cached_running_holder; -static volatile uint64_t cached_running_holder_tsid; - + +static PyObject *cached_running_holder; +static volatile uint64_t cached_running_holder_tsid; + /* Counter for autogenerated Task names */ static uint64_t task_name_counter = 0; - -/* WeakSet containing all alive tasks. */ -static PyObject *all_tasks; - -/* Dictionary containing tasks that are currently active in - all running event loops. {EventLoop: Task} */ -static PyObject *current_tasks; - -/* An isinstance type cache for the 'is_coroutine()' function. */ -static PyObject *iscoroutine_typecache; - - -typedef enum { - STATE_PENDING, - STATE_CANCELLED, - STATE_FINISHED -} fut_state; - -#define FutureObj_HEAD(prefix) \ - PyObject_HEAD \ - PyObject *prefix##_loop; \ - PyObject *prefix##_callback0; \ - PyObject *prefix##_context0; \ - PyObject *prefix##_callbacks; \ - PyObject *prefix##_exception; \ - PyObject *prefix##_result; \ - PyObject *prefix##_source_tb; \ + +/* WeakSet containing all alive tasks. */ +static PyObject *all_tasks; + +/* Dictionary containing tasks that are currently active in + all running event loops. {EventLoop: Task} */ +static PyObject *current_tasks; + +/* An isinstance type cache for the 'is_coroutine()' function. */ +static PyObject *iscoroutine_typecache; + + +typedef enum { + STATE_PENDING, + STATE_CANCELLED, + STATE_FINISHED +} fut_state; + +#define FutureObj_HEAD(prefix) \ + PyObject_HEAD \ + PyObject *prefix##_loop; \ + PyObject *prefix##_callback0; \ + PyObject *prefix##_context0; \ + PyObject *prefix##_callbacks; \ + PyObject *prefix##_exception; \ + PyObject *prefix##_result; \ + PyObject *prefix##_source_tb; \ PyObject *prefix##_cancel_msg; \ - fut_state prefix##_state; \ - int prefix##_log_tb; \ - int prefix##_blocking; \ - PyObject *dict; \ + fut_state prefix##_state; \ + int prefix##_log_tb; \ + int prefix##_blocking; \ + PyObject *dict; \ PyObject *prefix##_weakreflist; \ _PyErr_StackItem prefix##_cancelled_exc_state; - -typedef struct { - FutureObj_HEAD(fut) -} FutureObj; - -typedef struct { - FutureObj_HEAD(task) - PyObject *task_fut_waiter; - PyObject *task_coro; + +typedef struct { + FutureObj_HEAD(fut) +} FutureObj; + +typedef struct { + FutureObj_HEAD(task) + PyObject *task_fut_waiter; + PyObject *task_coro; PyObject *task_name; - PyObject *task_context; - int task_must_cancel; - int task_log_destroy_pending; -} TaskObj; - -typedef struct { - PyObject_HEAD - TaskObj *sw_task; - PyObject *sw_arg; -} TaskStepMethWrapper; - -typedef struct { - PyObject_HEAD - TaskObj *ww_task; -} TaskWakeupMethWrapper; - -typedef struct { - PyObject_HEAD - PyObject *rl_loop; -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - pid_t rl_pid; -#endif -} PyRunningLoopHolder; - - -static PyTypeObject FutureType; -static PyTypeObject TaskType; -static PyTypeObject PyRunningLoopHolder_Type; - - + PyObject *task_context; + int task_must_cancel; + int task_log_destroy_pending; +} TaskObj; + +typedef struct { + PyObject_HEAD + TaskObj *sw_task; + PyObject *sw_arg; +} TaskStepMethWrapper; + +typedef struct { + PyObject_HEAD + TaskObj *ww_task; +} TaskWakeupMethWrapper; + +typedef struct { + PyObject_HEAD + PyObject *rl_loop; +#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) + pid_t rl_pid; +#endif +} PyRunningLoopHolder; + + +static PyTypeObject FutureType; +static PyTypeObject TaskType; +static PyTypeObject PyRunningLoopHolder_Type; + + #define Future_CheckExact(obj) Py_IS_TYPE(obj, &FutureType) #define Task_CheckExact(obj) Py_IS_TYPE(obj, &TaskType) - -#define Future_Check(obj) PyObject_TypeCheck(obj, &FutureType) -#define Task_Check(obj) PyObject_TypeCheck(obj, &TaskType) - -#include "clinic/_asynciomodule.c.h" - - -/*[clinic input] -class _asyncio.Future "FutureObj *" "&Future_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=00d3e4abca711e0f]*/ - - -/* Get FutureIter from Future */ -static PyObject * future_new_iter(PyObject *); - -static PyRunningLoopHolder * new_running_loop_holder(PyObject *); - - -static int -_is_coroutine(PyObject *coro) -{ - /* 'coro' is not a native coroutine, call asyncio.iscoroutine() - to check if it's another coroutine flavour. - - Do this check after 'future_init()'; in case we need to raise - an error, __del__ needs a properly initialized object. - */ + +#define Future_Check(obj) PyObject_TypeCheck(obj, &FutureType) +#define Task_Check(obj) PyObject_TypeCheck(obj, &TaskType) + +#include "clinic/_asynciomodule.c.h" + + +/*[clinic input] +class _asyncio.Future "FutureObj *" "&Future_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=00d3e4abca711e0f]*/ + + +/* Get FutureIter from Future */ +static PyObject * future_new_iter(PyObject *); + +static PyRunningLoopHolder * new_running_loop_holder(PyObject *); + + +static int +_is_coroutine(PyObject *coro) +{ + /* 'coro' is not a native coroutine, call asyncio.iscoroutine() + to check if it's another coroutine flavour. + + Do this check after 'future_init()'; in case we need to raise + an error, __del__ needs a properly initialized object. + */ PyObject *res = PyObject_CallOneArg(asyncio_iscoroutine_func, coro); - if (res == NULL) { - return -1; - } - - int is_res_true = PyObject_IsTrue(res); - Py_DECREF(res); - if (is_res_true <= 0) { - return is_res_true; - } - - if (PySet_GET_SIZE(iscoroutine_typecache) < 100) { - /* Just in case we don't want to cache more than 100 - positive types. That shouldn't ever happen, unless - someone stressing the system on purpose. - */ - if (PySet_Add(iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) { - return -1; - } - } - - return 1; -} - - -static inline int -is_coroutine(PyObject *coro) -{ - if (PyCoro_CheckExact(coro)) { - return 1; - } - - /* Check if `type(coro)` is in the cache. - Caching makes is_coroutine() function almost as fast as - PyCoro_CheckExact() for non-native coroutine-like objects - (like coroutines compiled with Cython). - - asyncio.iscoroutine() has its own type caching mechanism. - This cache allows us to avoid the cost of even calling - a pure-Python function in 99.9% cases. - */ - int has_it = PySet_Contains( - iscoroutine_typecache, (PyObject*) Py_TYPE(coro)); - if (has_it == 0) { - /* type(coro) is not in iscoroutine_typecache */ - return _is_coroutine(coro); - } - - /* either an error has occurred or - type(coro) is in iscoroutine_typecache - */ - return has_it; -} - - -static PyObject * -get_future_loop(PyObject *fut) -{ - /* Implementation of `asyncio.futures._get_loop` */ - - _Py_IDENTIFIER(get_loop); - _Py_IDENTIFIER(_loop); - PyObject *getloop; - - if (Future_CheckExact(fut) || Task_CheckExact(fut)) { - PyObject *loop = ((FutureObj *)fut)->fut_loop; - Py_INCREF(loop); - return loop; - } - - if (_PyObject_LookupAttrId(fut, &PyId_get_loop, &getloop) < 0) { - return NULL; - } - if (getloop != NULL) { + if (res == NULL) { + return -1; + } + + int is_res_true = PyObject_IsTrue(res); + Py_DECREF(res); + if (is_res_true <= 0) { + return is_res_true; + } + + if (PySet_GET_SIZE(iscoroutine_typecache) < 100) { + /* Just in case we don't want to cache more than 100 + positive types. That shouldn't ever happen, unless + someone stressing the system on purpose. + */ + if (PySet_Add(iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) { + return -1; + } + } + + return 1; +} + + +static inline int +is_coroutine(PyObject *coro) +{ + if (PyCoro_CheckExact(coro)) { + return 1; + } + + /* Check if `type(coro)` is in the cache. + Caching makes is_coroutine() function almost as fast as + PyCoro_CheckExact() for non-native coroutine-like objects + (like coroutines compiled with Cython). + + asyncio.iscoroutine() has its own type caching mechanism. + This cache allows us to avoid the cost of even calling + a pure-Python function in 99.9% cases. + */ + int has_it = PySet_Contains( + iscoroutine_typecache, (PyObject*) Py_TYPE(coro)); + if (has_it == 0) { + /* type(coro) is not in iscoroutine_typecache */ + return _is_coroutine(coro); + } + + /* either an error has occurred or + type(coro) is in iscoroutine_typecache + */ + return has_it; +} + + +static PyObject * +get_future_loop(PyObject *fut) +{ + /* Implementation of `asyncio.futures._get_loop` */ + + _Py_IDENTIFIER(get_loop); + _Py_IDENTIFIER(_loop); + PyObject *getloop; + + if (Future_CheckExact(fut) || Task_CheckExact(fut)) { + PyObject *loop = ((FutureObj *)fut)->fut_loop; + Py_INCREF(loop); + return loop; + } + + if (_PyObject_LookupAttrId(fut, &PyId_get_loop, &getloop) < 0) { + return NULL; + } + if (getloop != NULL) { PyObject *res = PyObject_CallNoArgs(getloop); - Py_DECREF(getloop); - return res; - } - - return _PyObject_GetAttrId(fut, &PyId__loop); -} - - -static int -get_running_loop(PyObject **loop) -{ - PyObject *rl; - - PyThreadState *ts = PyThreadState_Get(); + Py_DECREF(getloop); + return res; + } + + return _PyObject_GetAttrId(fut, &PyId__loop); +} + + +static int +get_running_loop(PyObject **loop) +{ + PyObject *rl; + + PyThreadState *ts = PyThreadState_Get(); uint64_t ts_id = PyThreadState_GetID(ts); if (ts_id == cached_running_holder_tsid && cached_running_holder != NULL) { - // Fast path, check the cache. - rl = cached_running_holder; // borrowed - } - else { + // Fast path, check the cache. + rl = cached_running_holder; // borrowed + } + else { PyObject *ts_dict = _PyThreadState_GetDict(ts); // borrowed if (ts_dict == NULL) { - goto not_found; - } - - rl = _PyDict_GetItemIdWithError( + goto not_found; + } + + rl = _PyDict_GetItemIdWithError( ts_dict, &PyId___asyncio_running_event_loop__); // borrowed - if (rl == NULL) { - if (PyErr_Occurred()) { - goto error; - } - else { - goto not_found; - } - } - - cached_running_holder = rl; // borrowed + if (rl == NULL) { + if (PyErr_Occurred()) { + goto error; + } + else { + goto not_found; + } + } + + cached_running_holder = rl; // borrowed cached_running_holder_tsid = ts_id; - } - + } + assert(Py_IS_TYPE(rl, &PyRunningLoopHolder_Type)); - PyObject *running_loop = ((PyRunningLoopHolder *)rl)->rl_loop; - - if (running_loop == Py_None) { - goto not_found; - } - -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - /* On Windows there is no getpid, but there is also no os.fork(), - so there is no need for this check. - */ - if (getpid() != ((PyRunningLoopHolder *)rl)->rl_pid) { - goto not_found; - } -#endif - - Py_INCREF(running_loop); - *loop = running_loop; - return 0; - -not_found: - *loop = NULL; - return 0; - -error: - *loop = NULL; - return -1; -} - - -static int -set_running_loop(PyObject *loop) -{ + PyObject *running_loop = ((PyRunningLoopHolder *)rl)->rl_loop; + + if (running_loop == Py_None) { + goto not_found; + } + +#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) + /* On Windows there is no getpid, but there is also no os.fork(), + so there is no need for this check. + */ + if (getpid() != ((PyRunningLoopHolder *)rl)->rl_pid) { + goto not_found; + } +#endif + + Py_INCREF(running_loop); + *loop = running_loop; + return 0; + +not_found: + *loop = NULL; + return 0; + +error: + *loop = NULL; + return -1; +} + + +static int +set_running_loop(PyObject *loop) +{ PyObject *ts_dict = NULL; PyThreadState *tstate = PyThreadState_Get(); @@ -298,311 +298,311 @@ set_running_loop(PyObject *loop) ts_dict = _PyThreadState_GetDict(tstate); // borrowed } - if (ts_dict == NULL) { - PyErr_SetString( - PyExc_RuntimeError, "thread-local storage is not available"); - return -1; - } - - PyRunningLoopHolder *rl = new_running_loop_holder(loop); - if (rl == NULL) { - return -1; - } - - if (_PyDict_SetItemId( - ts_dict, &PyId___asyncio_running_event_loop__, (PyObject *)rl) < 0) - { - Py_DECREF(rl); // will cleanup loop & current_pid - return -1; - } - Py_DECREF(rl); - + if (ts_dict == NULL) { + PyErr_SetString( + PyExc_RuntimeError, "thread-local storage is not available"); + return -1; + } + + PyRunningLoopHolder *rl = new_running_loop_holder(loop); + if (rl == NULL) { + return -1; + } + + if (_PyDict_SetItemId( + ts_dict, &PyId___asyncio_running_event_loop__, (PyObject *)rl) < 0) + { + Py_DECREF(rl); // will cleanup loop & current_pid + return -1; + } + Py_DECREF(rl); + cached_running_holder = (PyObject *)rl; cached_running_holder_tsid = PyThreadState_GetID(tstate); - return 0; -} - - -static PyObject * -get_event_loop(void) -{ - PyObject *loop; - PyObject *policy; - - if (get_running_loop(&loop)) { - return NULL; - } - if (loop != NULL) { - return loop; - } - + return 0; +} + + +static PyObject * +get_event_loop(void) +{ + PyObject *loop; + PyObject *policy; + + if (get_running_loop(&loop)) { + return NULL; + } + if (loop != NULL) { + return loop; + } + policy = PyObject_CallNoArgs(asyncio_get_event_loop_policy); - if (policy == NULL) { - return NULL; - } - + if (policy == NULL) { + return NULL; + } + loop = _PyObject_CallMethodIdNoArgs(policy, &PyId_get_event_loop); - Py_DECREF(policy); - return loop; -} - - -static int -call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx) -{ - PyObject *handle; - PyObject *stack[3]; - Py_ssize_t nargs; - - if (ctx == NULL) { - handle = _PyObject_CallMethodIdObjArgs( - loop, &PyId_call_soon, func, arg, NULL); - } - else { - /* Use FASTCALL to pass a keyword-only argument to call_soon */ - - PyObject *callable = _PyObject_GetAttrId(loop, &PyId_call_soon); - if (callable == NULL) { - return -1; - } - - /* All refs in 'stack' are borrowed. */ - nargs = 1; - stack[0] = func; - if (arg != NULL) { - stack[1] = arg; - nargs++; - } - stack[nargs] = (PyObject *)ctx; - + Py_DECREF(policy); + return loop; +} + + +static int +call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx) +{ + PyObject *handle; + PyObject *stack[3]; + Py_ssize_t nargs; + + if (ctx == NULL) { + handle = _PyObject_CallMethodIdObjArgs( + loop, &PyId_call_soon, func, arg, NULL); + } + else { + /* Use FASTCALL to pass a keyword-only argument to call_soon */ + + PyObject *callable = _PyObject_GetAttrId(loop, &PyId_call_soon); + if (callable == NULL) { + return -1; + } + + /* All refs in 'stack' are borrowed. */ + nargs = 1; + stack[0] = func; + if (arg != NULL) { + stack[1] = arg; + nargs++; + } + stack[nargs] = (PyObject *)ctx; + handle = PyObject_Vectorcall(callable, stack, nargs, context_kwname); - Py_DECREF(callable); - } - - if (handle == NULL) { - return -1; - } - Py_DECREF(handle); - return 0; -} - - -static inline int -future_is_alive(FutureObj *fut) -{ - return fut->fut_loop != NULL; -} - - -static inline int -future_ensure_alive(FutureObj *fut) -{ - if (!future_is_alive(fut)) { - PyErr_SetString(PyExc_RuntimeError, - "Future object is not initialized."); - return -1; - } - return 0; -} - - -#define ENSURE_FUTURE_ALIVE(fut) \ - do { \ - assert(Future_Check(fut) || Task_Check(fut)); \ - if (future_ensure_alive((FutureObj*)fut)) { \ - return NULL; \ - } \ - } while(0); - - -static int -future_schedule_callbacks(FutureObj *fut) -{ - Py_ssize_t len; - Py_ssize_t i; - - if (fut->fut_callback0 != NULL) { - /* There's a 1st callback */ - - int ret = call_soon( - fut->fut_loop, fut->fut_callback0, - (PyObject *)fut, fut->fut_context0); - - Py_CLEAR(fut->fut_callback0); - Py_CLEAR(fut->fut_context0); - if (ret) { - /* If an error occurs in pure-Python implementation, - all callbacks are cleared. */ - Py_CLEAR(fut->fut_callbacks); - return ret; - } - - /* we called the first callback, now try calling - callbacks from the 'fut_callbacks' list. */ - } - - if (fut->fut_callbacks == NULL) { - /* No more callbacks, return. */ - return 0; - } - - len = PyList_GET_SIZE(fut->fut_callbacks); - if (len == 0) { - /* The list of callbacks was empty; clear it and return. */ - Py_CLEAR(fut->fut_callbacks); - return 0; - } - - for (i = 0; i < len; i++) { - PyObject *cb_tup = PyList_GET_ITEM(fut->fut_callbacks, i); - PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0); - PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1); - - if (call_soon(fut->fut_loop, cb, (PyObject *)fut, ctx)) { - /* If an error occurs in pure-Python implementation, - all callbacks are cleared. */ - Py_CLEAR(fut->fut_callbacks); - return -1; - } - } - - Py_CLEAR(fut->fut_callbacks); - return 0; -} - - -static int -future_init(FutureObj *fut, PyObject *loop) -{ - PyObject *res; - int is_true; - _Py_IDENTIFIER(get_debug); - - // Same to FutureObj_clear() but not clearing fut->dict - Py_CLEAR(fut->fut_loop); - Py_CLEAR(fut->fut_callback0); - Py_CLEAR(fut->fut_context0); - Py_CLEAR(fut->fut_callbacks); - Py_CLEAR(fut->fut_result); - Py_CLEAR(fut->fut_exception); - Py_CLEAR(fut->fut_source_tb); + Py_DECREF(callable); + } + + if (handle == NULL) { + return -1; + } + Py_DECREF(handle); + return 0; +} + + +static inline int +future_is_alive(FutureObj *fut) +{ + return fut->fut_loop != NULL; +} + + +static inline int +future_ensure_alive(FutureObj *fut) +{ + if (!future_is_alive(fut)) { + PyErr_SetString(PyExc_RuntimeError, + "Future object is not initialized."); + return -1; + } + return 0; +} + + +#define ENSURE_FUTURE_ALIVE(fut) \ + do { \ + assert(Future_Check(fut) || Task_Check(fut)); \ + if (future_ensure_alive((FutureObj*)fut)) { \ + return NULL; \ + } \ + } while(0); + + +static int +future_schedule_callbacks(FutureObj *fut) +{ + Py_ssize_t len; + Py_ssize_t i; + + if (fut->fut_callback0 != NULL) { + /* There's a 1st callback */ + + int ret = call_soon( + fut->fut_loop, fut->fut_callback0, + (PyObject *)fut, fut->fut_context0); + + Py_CLEAR(fut->fut_callback0); + Py_CLEAR(fut->fut_context0); + if (ret) { + /* If an error occurs in pure-Python implementation, + all callbacks are cleared. */ + Py_CLEAR(fut->fut_callbacks); + return ret; + } + + /* we called the first callback, now try calling + callbacks from the 'fut_callbacks' list. */ + } + + if (fut->fut_callbacks == NULL) { + /* No more callbacks, return. */ + return 0; + } + + len = PyList_GET_SIZE(fut->fut_callbacks); + if (len == 0) { + /* The list of callbacks was empty; clear it and return. */ + Py_CLEAR(fut->fut_callbacks); + return 0; + } + + for (i = 0; i < len; i++) { + PyObject *cb_tup = PyList_GET_ITEM(fut->fut_callbacks, i); + PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0); + PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1); + + if (call_soon(fut->fut_loop, cb, (PyObject *)fut, ctx)) { + /* If an error occurs in pure-Python implementation, + all callbacks are cleared. */ + Py_CLEAR(fut->fut_callbacks); + return -1; + } + } + + Py_CLEAR(fut->fut_callbacks); + return 0; +} + + +static int +future_init(FutureObj *fut, PyObject *loop) +{ + PyObject *res; + int is_true; + _Py_IDENTIFIER(get_debug); + + // Same to FutureObj_clear() but not clearing fut->dict + Py_CLEAR(fut->fut_loop); + Py_CLEAR(fut->fut_callback0); + Py_CLEAR(fut->fut_context0); + Py_CLEAR(fut->fut_callbacks); + Py_CLEAR(fut->fut_result); + Py_CLEAR(fut->fut_exception); + Py_CLEAR(fut->fut_source_tb); Py_CLEAR(fut->fut_cancel_msg); _PyErr_ClearExcState(&fut->fut_cancelled_exc_state); - - fut->fut_state = STATE_PENDING; - fut->fut_log_tb = 0; - fut->fut_blocking = 0; - - if (loop == Py_None) { - loop = get_event_loop(); - if (loop == NULL) { - return -1; - } - } - else { - Py_INCREF(loop); - } - fut->fut_loop = loop; - + + fut->fut_state = STATE_PENDING; + fut->fut_log_tb = 0; + fut->fut_blocking = 0; + + if (loop == Py_None) { + loop = get_event_loop(); + if (loop == NULL) { + return -1; + } + } + else { + Py_INCREF(loop); + } + fut->fut_loop = loop; + res = _PyObject_CallMethodIdNoArgs(fut->fut_loop, &PyId_get_debug); - if (res == NULL) { - return -1; - } - is_true = PyObject_IsTrue(res); - Py_DECREF(res); - if (is_true < 0) { - return -1; - } - if (is_true && !_Py_IsFinalizing()) { - /* Only try to capture the traceback if the interpreter is not being - finalized. The original motivation to add a `_Py_IsFinalizing()` - call was to prevent SIGSEGV when a Future is created in a __del__ - method, which is called during the interpreter shutdown and the - traceback module is already unloaded. - */ + if (res == NULL) { + return -1; + } + is_true = PyObject_IsTrue(res); + Py_DECREF(res); + if (is_true < 0) { + return -1; + } + if (is_true && !_Py_IsFinalizing()) { + /* Only try to capture the traceback if the interpreter is not being + finalized. The original motivation to add a `_Py_IsFinalizing()` + call was to prevent SIGSEGV when a Future is created in a __del__ + method, which is called during the interpreter shutdown and the + traceback module is already unloaded. + */ fut->fut_source_tb = PyObject_CallNoArgs(traceback_extract_stack); - if (fut->fut_source_tb == NULL) { - return -1; - } - } - - return 0; -} - -static PyObject * -future_set_result(FutureObj *fut, PyObject *res) -{ - if (future_ensure_alive(fut)) { - return NULL; - } - - if (fut->fut_state != STATE_PENDING) { - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); - return NULL; - } - - assert(!fut->fut_result); - Py_INCREF(res); - fut->fut_result = res; - fut->fut_state = STATE_FINISHED; - - if (future_schedule_callbacks(fut) == -1) { - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject * -future_set_exception(FutureObj *fut, PyObject *exc) -{ - PyObject *exc_val = NULL; - - if (fut->fut_state != STATE_PENDING) { - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); - return NULL; - } - - if (PyExceptionClass_Check(exc)) { + if (fut->fut_source_tb == NULL) { + return -1; + } + } + + return 0; +} + +static PyObject * +future_set_result(FutureObj *fut, PyObject *res) +{ + if (future_ensure_alive(fut)) { + return NULL; + } + + if (fut->fut_state != STATE_PENDING) { + PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + return NULL; + } + + assert(!fut->fut_result); + Py_INCREF(res); + fut->fut_result = res; + fut->fut_state = STATE_FINISHED; + + if (future_schedule_callbacks(fut) == -1) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +future_set_exception(FutureObj *fut, PyObject *exc) +{ + PyObject *exc_val = NULL; + + if (fut->fut_state != STATE_PENDING) { + PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + return NULL; + } + + if (PyExceptionClass_Check(exc)) { exc_val = PyObject_CallNoArgs(exc); - if (exc_val == NULL) { - return NULL; - } - if (fut->fut_state != STATE_PENDING) { - Py_DECREF(exc_val); - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); - return NULL; - } - } - else { - exc_val = exc; - Py_INCREF(exc_val); - } - if (!PyExceptionInstance_Check(exc_val)) { - Py_DECREF(exc_val); - PyErr_SetString(PyExc_TypeError, "invalid exception object"); - return NULL; - } + if (exc_val == NULL) { + return NULL; + } + if (fut->fut_state != STATE_PENDING) { + Py_DECREF(exc_val); + PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + return NULL; + } + } + else { + exc_val = exc; + Py_INCREF(exc_val); + } + if (!PyExceptionInstance_Check(exc_val)) { + Py_DECREF(exc_val); + PyErr_SetString(PyExc_TypeError, "invalid exception object"); + return NULL; + } if (Py_IS_TYPE(exc_val, (PyTypeObject *)PyExc_StopIteration)) { - Py_DECREF(exc_val); - PyErr_SetString(PyExc_TypeError, - "StopIteration interacts badly with generators " - "and cannot be raised into a Future"); - return NULL; - } - - assert(!fut->fut_exception); - fut->fut_exception = exc_val; - fut->fut_state = STATE_FINISHED; - - if (future_schedule_callbacks(fut) == -1) { - return NULL; - } - - fut->fut_log_tb = 1; - Py_RETURN_NONE; -} - + Py_DECREF(exc_val); + PyErr_SetString(PyExc_TypeError, + "StopIteration interacts badly with generators " + "and cannot be raised into a Future"); + return NULL; + } + + assert(!fut->fut_exception); + fut->fut_exception = exc_val; + fut->fut_state = STATE_FINISHED; + + if (future_schedule_callbacks(fut) == -1) { + return NULL; + } + + fut->fut_log_tb = 1; + Py_RETURN_NONE; +} + static PyObject * create_cancelled_error(PyObject *msg) { @@ -625,1753 +625,1753 @@ future_set_cancelled_error(FutureObj *fut) _PyErr_ChainStackItem(&fut->fut_cancelled_exc_state); } -static int -future_get_result(FutureObj *fut, PyObject **result) -{ - if (fut->fut_state == STATE_CANCELLED) { +static int +future_get_result(FutureObj *fut, PyObject **result) +{ + if (fut->fut_state == STATE_CANCELLED) { future_set_cancelled_error(fut); - return -1; - } + return -1; + } + + if (fut->fut_state != STATE_FINISHED) { + PyErr_SetString(asyncio_InvalidStateError, "Result is not set."); + return -1; + } + + fut->fut_log_tb = 0; + if (fut->fut_exception != NULL) { + Py_INCREF(fut->fut_exception); + *result = fut->fut_exception; + return 1; + } + + Py_INCREF(fut->fut_result); + *result = fut->fut_result; + return 0; +} + +static PyObject * +future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) +{ + if (!future_is_alive(fut)) { + PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object"); + return NULL; + } + + if (fut->fut_state != STATE_PENDING) { + /* The future is done/cancelled, so schedule the callback + right away. */ + if (call_soon(fut->fut_loop, arg, (PyObject*) fut, ctx)) { + return NULL; + } + } + else { + /* The future is pending, add a callback. + + Callbacks in the future object are stored as follows: + + callback0 -- a pointer to the first callback + callbacks -- a list of 2nd, 3rd, ... callbacks + + Invariants: + + * callbacks != NULL: + There are some callbacks in in the list. Just + add the new callback to it. + + * callbacks == NULL and callback0 == NULL: + This is the first callback. Set it to callback0. + + * callbacks == NULL and callback0 != NULL: + This is a second callback. Initialize callbacks + with a new list and add the new callback to it. + */ + + if (fut->fut_callbacks == NULL && fut->fut_callback0 == NULL) { + Py_INCREF(arg); + fut->fut_callback0 = arg; + Py_INCREF(ctx); + fut->fut_context0 = ctx; + } + else { + PyObject *tup = PyTuple_New(2); + if (tup == NULL) { + return NULL; + } + Py_INCREF(arg); + PyTuple_SET_ITEM(tup, 0, arg); + Py_INCREF(ctx); + PyTuple_SET_ITEM(tup, 1, (PyObject *)ctx); + + if (fut->fut_callbacks != NULL) { + int err = PyList_Append(fut->fut_callbacks, tup); + if (err) { + Py_DECREF(tup); + return NULL; + } + Py_DECREF(tup); + } + else { + fut->fut_callbacks = PyList_New(1); + if (fut->fut_callbacks == NULL) { + return NULL; + } + + PyList_SET_ITEM(fut->fut_callbacks, 0, tup); /* borrow */ + } + } + } + + Py_RETURN_NONE; +} + +static PyObject * +future_cancel(FutureObj *fut, PyObject *msg) +{ + fut->fut_log_tb = 0; + + if (fut->fut_state != STATE_PENDING) { + Py_RETURN_FALSE; + } + fut->fut_state = STATE_CANCELLED; + + Py_XINCREF(msg); + Py_XSETREF(fut->fut_cancel_msg, msg); - if (fut->fut_state != STATE_FINISHED) { - PyErr_SetString(asyncio_InvalidStateError, "Result is not set."); - return -1; - } + if (future_schedule_callbacks(fut) == -1) { + return NULL; + } + + Py_RETURN_TRUE; +} + +/*[clinic input] +_asyncio.Future.__init__ + + * + loop: object = None + +This class is *almost* compatible with concurrent.futures.Future. + + Differences: + + - result() and exception() do not take a timeout argument and + raise an exception when the future isn't done yet. + + - Callbacks registered with add_done_callback() are always called + via the event loop's call_soon_threadsafe(). + + - This class is not compatible with the wait() and as_completed() + methods in the concurrent.futures package. +[clinic start generated code]*/ + +static int +_asyncio_Future___init___impl(FutureObj *self, PyObject *loop) +/*[clinic end generated code: output=9ed75799eaccb5d6 input=89af317082bc0bf8]*/ + +{ + return future_init(self, loop); +} + +static int +FutureObj_clear(FutureObj *fut) +{ + Py_CLEAR(fut->fut_loop); + Py_CLEAR(fut->fut_callback0); + Py_CLEAR(fut->fut_context0); + Py_CLEAR(fut->fut_callbacks); + Py_CLEAR(fut->fut_result); + Py_CLEAR(fut->fut_exception); + Py_CLEAR(fut->fut_source_tb); + Py_CLEAR(fut->fut_cancel_msg); + _PyErr_ClearExcState(&fut->fut_cancelled_exc_state); + Py_CLEAR(fut->dict); + return 0; +} + +static int +FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg) +{ + Py_VISIT(fut->fut_loop); + Py_VISIT(fut->fut_callback0); + Py_VISIT(fut->fut_context0); + Py_VISIT(fut->fut_callbacks); + Py_VISIT(fut->fut_result); + Py_VISIT(fut->fut_exception); + Py_VISIT(fut->fut_source_tb); + Py_VISIT(fut->fut_cancel_msg); + Py_VISIT(fut->dict); - fut->fut_log_tb = 0; - if (fut->fut_exception != NULL) { - Py_INCREF(fut->fut_exception); - *result = fut->fut_exception; - return 1; - } + _PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state; + Py_VISIT(exc_state->exc_type); + Py_VISIT(exc_state->exc_value); + Py_VISIT(exc_state->exc_traceback); - Py_INCREF(fut->fut_result); - *result = fut->fut_result; - return 0; -} + return 0; +} + +/*[clinic input] +_asyncio.Future.result + +Return the result this future represents. + +If the future has been cancelled, raises CancelledError. If the +future's result isn't yet available, raises InvalidStateError. If +the future is done and has an exception set, this exception is raised. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_result_impl(FutureObj *self) +/*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/ +{ + PyObject *result; + + if (!future_is_alive(self)) { + PyErr_SetString(asyncio_InvalidStateError, + "Future object is not initialized."); + return NULL; + } + + int res = future_get_result(self, &result); + + if (res == -1) { + return NULL; + } + + if (res == 0) { + return result; + } + + assert(res == 1); + + PyErr_SetObject(PyExceptionInstance_Class(result), result); + Py_DECREF(result); + return NULL; +} + +/*[clinic input] +_asyncio.Future.exception + +Return the exception that was set on this future. + +The exception (or None if no exception was set) is returned only if +the future is done. If the future has been cancelled, raises +CancelledError. If the future isn't done yet, raises +InvalidStateError. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_exception_impl(FutureObj *self) +/*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/ +{ + if (!future_is_alive(self)) { + PyErr_SetString(asyncio_InvalidStateError, + "Future object is not initialized."); + return NULL; + } + + if (self->fut_state == STATE_CANCELLED) { + future_set_cancelled_error(self); + return NULL; + } + + if (self->fut_state != STATE_FINISHED) { + PyErr_SetString(asyncio_InvalidStateError, "Exception is not set."); + return NULL; + } + + if (self->fut_exception != NULL) { + self->fut_log_tb = 0; + Py_INCREF(self->fut_exception); + return self->fut_exception; + } + + Py_RETURN_NONE; +} + +/*[clinic input] +_asyncio.Future.set_result + + result: object + / + +Mark the future done and set its result. + +If the future is already done when this method is called, raises +InvalidStateError. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_set_result(FutureObj *self, PyObject *result) +/*[clinic end generated code: output=1ec2e6bcccd6f2ce input=8b75172c2a7b05f1]*/ +{ + ENSURE_FUTURE_ALIVE(self) + return future_set_result(self, result); +} + +/*[clinic input] +_asyncio.Future.set_exception + + exception: object + / + +Mark the future done and set an exception. + +If the future is already done when this method is called, raises +InvalidStateError. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_set_exception(FutureObj *self, PyObject *exception) +/*[clinic end generated code: output=f1c1b0cd321be360 input=e45b7d7aa71cc66d]*/ +{ + ENSURE_FUTURE_ALIVE(self) + return future_set_exception(self, exception); +} + +/*[clinic input] +_asyncio.Future.add_done_callback + + fn: object + / + * + context: object = NULL + +Add a callback to be run when the future becomes done. + +The callback is called with a single argument - the future object. If +the future is already done when this is called, the callback is +scheduled with call_soon. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn, + PyObject *context) +/*[clinic end generated code: output=7ce635bbc9554c1e input=15ab0693a96e9533]*/ +{ + if (context == NULL) { + context = PyContext_CopyCurrent(); + if (context == NULL) { + return NULL; + } + PyObject *res = future_add_done_callback(self, fn, context); + Py_DECREF(context); + return res; + } + return future_add_done_callback(self, fn, context); +} + +/*[clinic input] +_asyncio.Future.remove_done_callback + + fn: object + / + +Remove all instances of a callback from the "call when done" list. + +Returns the number of callbacks removed. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) +/*[clinic end generated code: output=5ab1fb52b24ef31f input=0a43280a149d505b]*/ +{ + PyObject *newlist; + Py_ssize_t len, i, j=0; + Py_ssize_t cleared_callback0 = 0; + + ENSURE_FUTURE_ALIVE(self) + + if (self->fut_callback0 != NULL) { + int cmp = PyObject_RichCompareBool(self->fut_callback0, fn, Py_EQ); + if (cmp == -1) { + return NULL; + } + if (cmp == 1) { + /* callback0 == fn */ + Py_CLEAR(self->fut_callback0); + Py_CLEAR(self->fut_context0); + cleared_callback0 = 1; + } + } + + if (self->fut_callbacks == NULL) { + return PyLong_FromSsize_t(cleared_callback0); + } + + len = PyList_GET_SIZE(self->fut_callbacks); + if (len == 0) { + Py_CLEAR(self->fut_callbacks); + return PyLong_FromSsize_t(cleared_callback0); + } + + if (len == 1) { + PyObject *cb_tup = PyList_GET_ITEM(self->fut_callbacks, 0); + int cmp = PyObject_RichCompareBool( + PyTuple_GET_ITEM(cb_tup, 0), fn, Py_EQ); + if (cmp == -1) { + return NULL; + } + if (cmp == 1) { + /* callbacks[0] == fn */ + Py_CLEAR(self->fut_callbacks); + return PyLong_FromSsize_t(1 + cleared_callback0); + } + /* callbacks[0] != fn and len(callbacks) == 1 */ + return PyLong_FromSsize_t(cleared_callback0); + } + + newlist = PyList_New(len); + if (newlist == NULL) { + return NULL; + } + + for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) { + int ret; + PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i); + Py_INCREF(item); + ret = PyObject_RichCompareBool(PyTuple_GET_ITEM(item, 0), fn, Py_EQ); + if (ret == 0) { + if (j < len) { + PyList_SET_ITEM(newlist, j, item); + j++; + continue; + } + ret = PyList_Append(newlist, item); + } + Py_DECREF(item); + if (ret < 0) { + goto fail; + } + } + + if (j == 0) { + Py_CLEAR(self->fut_callbacks); + Py_DECREF(newlist); + return PyLong_FromSsize_t(len + cleared_callback0); + } + + if (j < len) { + Py_SET_SIZE(newlist, j); + } + j = PyList_GET_SIZE(newlist); + len = PyList_GET_SIZE(self->fut_callbacks); + if (j != len) { + if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) { + goto fail; + } + } + Py_DECREF(newlist); + return PyLong_FromSsize_t(len - j + cleared_callback0); + +fail: + Py_DECREF(newlist); + return NULL; +} + +/*[clinic input] +_asyncio.Future.cancel + + msg: object = None -static PyObject * -future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) +Cancel the future and schedule callbacks. + +If the future is already done or cancelled, return False. Otherwise, +change the future's state to cancelled, schedule the callbacks and +return True. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg) +/*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/ +{ + ENSURE_FUTURE_ALIVE(self) + return future_cancel(self, msg); +} + +/*[clinic input] +_asyncio.Future.cancelled + +Return True if the future was cancelled. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_cancelled_impl(FutureObj *self) +/*[clinic end generated code: output=145197ced586357d input=943ab8b7b7b17e45]*/ +{ + if (future_is_alive(self) && self->fut_state == STATE_CANCELLED) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +/*[clinic input] +_asyncio.Future.done + +Return True if the future is done. + +Done means either that a result / exception are available, or that the +future was cancelled. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_done_impl(FutureObj *self) +/*[clinic end generated code: output=244c5ac351145096 input=28d7b23fdb65d2ac]*/ +{ + if (!future_is_alive(self) || self->fut_state == STATE_PENDING) { + Py_RETURN_FALSE; + } + else { + Py_RETURN_TRUE; + } +} + +/*[clinic input] +_asyncio.Future.get_loop + +Return the event loop the Future is bound to. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future_get_loop_impl(FutureObj *self) +/*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/ +{ + ENSURE_FUTURE_ALIVE(self) + Py_INCREF(self->fut_loop); + return self->fut_loop; +} + +static PyObject * +FutureObj_get_blocking(FutureObj *fut, void *Py_UNUSED(ignored)) +{ + if (future_is_alive(fut) && fut->fut_blocking) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +static int +FutureObj_set_blocking(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored)) +{ + if (future_ensure_alive(fut)) { + return -1; + } + if (val == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + + int is_true = PyObject_IsTrue(val); + if (is_true < 0) { + return -1; + } + fut->fut_blocking = is_true; + return 0; +} + +static PyObject * +FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored)) +{ + ENSURE_FUTURE_ALIVE(fut) + if (fut->fut_log_tb) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +static int +FutureObj_set_log_traceback(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored)) +{ + if (val == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + int is_true = PyObject_IsTrue(val); + if (is_true < 0) { + return -1; + } + if (is_true) { + PyErr_SetString(PyExc_ValueError, + "_log_traceback can only be set to False"); + return -1; + } + fut->fut_log_tb = is_true; + return 0; +} + +static PyObject * +FutureObj_get_loop(FutureObj *fut, void *Py_UNUSED(ignored)) +{ + if (!future_is_alive(fut)) { + Py_RETURN_NONE; + } + Py_INCREF(fut->fut_loop); + return fut->fut_loop; +} + +static PyObject * +FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored)) +{ + Py_ssize_t i; + + ENSURE_FUTURE_ALIVE(fut) + + if (fut->fut_callback0 == NULL) { + if (fut->fut_callbacks == NULL) { + Py_RETURN_NONE; + } + + Py_INCREF(fut->fut_callbacks); + return fut->fut_callbacks; + } + + Py_ssize_t len = 1; + if (fut->fut_callbacks != NULL) { + len += PyList_GET_SIZE(fut->fut_callbacks); + } + + + PyObject *new_list = PyList_New(len); + if (new_list == NULL) { + return NULL; + } + + PyObject *tup0 = PyTuple_New(2); + if (tup0 == NULL) { + Py_DECREF(new_list); + return NULL; + } + + Py_INCREF(fut->fut_callback0); + PyTuple_SET_ITEM(tup0, 0, fut->fut_callback0); + assert(fut->fut_context0 != NULL); + Py_INCREF(fut->fut_context0); + PyTuple_SET_ITEM(tup0, 1, (PyObject *)fut->fut_context0); + + PyList_SET_ITEM(new_list, 0, tup0); + + if (fut->fut_callbacks != NULL) { + for (i = 0; i < PyList_GET_SIZE(fut->fut_callbacks); i++) { + PyObject *cb = PyList_GET_ITEM(fut->fut_callbacks, i); + Py_INCREF(cb); + PyList_SET_ITEM(new_list, i + 1, cb); + } + } + + return new_list; +} + +static PyObject * +FutureObj_get_result(FutureObj *fut, void *Py_UNUSED(ignored)) +{ + ENSURE_FUTURE_ALIVE(fut) + if (fut->fut_result == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(fut->fut_result); + return fut->fut_result; +} + +static PyObject * +FutureObj_get_exception(FutureObj *fut, void *Py_UNUSED(ignored)) +{ + ENSURE_FUTURE_ALIVE(fut) + if (fut->fut_exception == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(fut->fut_exception); + return fut->fut_exception; +} + +static PyObject * +FutureObj_get_source_traceback(FutureObj *fut, void *Py_UNUSED(ignored)) +{ + if (!future_is_alive(fut) || fut->fut_source_tb == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(fut->fut_source_tb); + return fut->fut_source_tb; +} + +static PyObject * +FutureObj_get_cancel_message(FutureObj *fut, void *Py_UNUSED(ignored)) { - if (!future_is_alive(fut)) { - PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object"); - return NULL; - } - - if (fut->fut_state != STATE_PENDING) { - /* The future is done/cancelled, so schedule the callback - right away. */ - if (call_soon(fut->fut_loop, arg, (PyObject*) fut, ctx)) { - return NULL; - } - } - else { - /* The future is pending, add a callback. - - Callbacks in the future object are stored as follows: - - callback0 -- a pointer to the first callback - callbacks -- a list of 2nd, 3rd, ... callbacks - - Invariants: - - * callbacks != NULL: - There are some callbacks in in the list. Just - add the new callback to it. - - * callbacks == NULL and callback0 == NULL: - This is the first callback. Set it to callback0. - - * callbacks == NULL and callback0 != NULL: - This is a second callback. Initialize callbacks - with a new list and add the new callback to it. - */ - - if (fut->fut_callbacks == NULL && fut->fut_callback0 == NULL) { - Py_INCREF(arg); - fut->fut_callback0 = arg; - Py_INCREF(ctx); - fut->fut_context0 = ctx; - } - else { - PyObject *tup = PyTuple_New(2); - if (tup == NULL) { - return NULL; - } - Py_INCREF(arg); - PyTuple_SET_ITEM(tup, 0, arg); - Py_INCREF(ctx); - PyTuple_SET_ITEM(tup, 1, (PyObject *)ctx); - - if (fut->fut_callbacks != NULL) { - int err = PyList_Append(fut->fut_callbacks, tup); - if (err) { - Py_DECREF(tup); - return NULL; - } - Py_DECREF(tup); - } - else { - fut->fut_callbacks = PyList_New(1); - if (fut->fut_callbacks == NULL) { - return NULL; - } - - PyList_SET_ITEM(fut->fut_callbacks, 0, tup); /* borrow */ - } - } + if (fut->fut_cancel_msg == NULL) { + Py_RETURN_NONE; } - - Py_RETURN_NONE; + Py_INCREF(fut->fut_cancel_msg); + return fut->fut_cancel_msg; } -static PyObject * -future_cancel(FutureObj *fut, PyObject *msg) +static int +FutureObj_set_cancel_message(FutureObj *fut, PyObject *msg, + void *Py_UNUSED(ignored)) { - fut->fut_log_tb = 0; - - if (fut->fut_state != STATE_PENDING) { - Py_RETURN_FALSE; + if (msg == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; } - fut->fut_state = STATE_CANCELLED; - - Py_XINCREF(msg); + Py_INCREF(msg); Py_XSETREF(fut->fut_cancel_msg, msg); - - if (future_schedule_callbacks(fut) == -1) { - return NULL; - } - - Py_RETURN_TRUE; -} - -/*[clinic input] -_asyncio.Future.__init__ - - * - loop: object = None - -This class is *almost* compatible with concurrent.futures.Future. - - Differences: - - - result() and exception() do not take a timeout argument and - raise an exception when the future isn't done yet. - - - Callbacks registered with add_done_callback() are always called - via the event loop's call_soon_threadsafe(). - - - This class is not compatible with the wait() and as_completed() - methods in the concurrent.futures package. -[clinic start generated code]*/ - -static int -_asyncio_Future___init___impl(FutureObj *self, PyObject *loop) -/*[clinic end generated code: output=9ed75799eaccb5d6 input=89af317082bc0bf8]*/ - -{ - return future_init(self, loop); -} - -static int -FutureObj_clear(FutureObj *fut) -{ - Py_CLEAR(fut->fut_loop); - Py_CLEAR(fut->fut_callback0); - Py_CLEAR(fut->fut_context0); - Py_CLEAR(fut->fut_callbacks); - Py_CLEAR(fut->fut_result); - Py_CLEAR(fut->fut_exception); - Py_CLEAR(fut->fut_source_tb); - Py_CLEAR(fut->fut_cancel_msg); - _PyErr_ClearExcState(&fut->fut_cancelled_exc_state); - Py_CLEAR(fut->dict); - return 0; -} - -static int -FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg) -{ - Py_VISIT(fut->fut_loop); - Py_VISIT(fut->fut_callback0); - Py_VISIT(fut->fut_context0); - Py_VISIT(fut->fut_callbacks); - Py_VISIT(fut->fut_result); - Py_VISIT(fut->fut_exception); - Py_VISIT(fut->fut_source_tb); - Py_VISIT(fut->fut_cancel_msg); - Py_VISIT(fut->dict); - - _PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state; - Py_VISIT(exc_state->exc_type); - Py_VISIT(exc_state->exc_value); - Py_VISIT(exc_state->exc_traceback); - return 0; } -/*[clinic input] -_asyncio.Future.result - -Return the result this future represents. - -If the future has been cancelled, raises CancelledError. If the -future's result isn't yet available, raises InvalidStateError. If -the future is done and has an exception set, this exception is raised. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future_result_impl(FutureObj *self) -/*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/ -{ - PyObject *result; - - if (!future_is_alive(self)) { - PyErr_SetString(asyncio_InvalidStateError, - "Future object is not initialized."); - return NULL; - } - - int res = future_get_result(self, &result); - - if (res == -1) { - return NULL; - } - - if (res == 0) { - return result; - } - - assert(res == 1); - - PyErr_SetObject(PyExceptionInstance_Class(result), result); - Py_DECREF(result); - return NULL; -} - -/*[clinic input] -_asyncio.Future.exception - -Return the exception that was set on this future. - -The exception (or None if no exception was set) is returned only if -the future is done. If the future has been cancelled, raises -CancelledError. If the future isn't done yet, raises -InvalidStateError. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future_exception_impl(FutureObj *self) -/*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/ -{ - if (!future_is_alive(self)) { - PyErr_SetString(asyncio_InvalidStateError, - "Future object is not initialized."); - return NULL; - } - - if (self->fut_state == STATE_CANCELLED) { - future_set_cancelled_error(self); - return NULL; - } - - if (self->fut_state != STATE_FINISHED) { - PyErr_SetString(asyncio_InvalidStateError, "Exception is not set."); - return NULL; - } - - if (self->fut_exception != NULL) { - self->fut_log_tb = 0; - Py_INCREF(self->fut_exception); - return self->fut_exception; - } - - Py_RETURN_NONE; -} - -/*[clinic input] -_asyncio.Future.set_result - - result: object - / - -Mark the future done and set its result. - -If the future is already done when this method is called, raises -InvalidStateError. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future_set_result(FutureObj *self, PyObject *result) -/*[clinic end generated code: output=1ec2e6bcccd6f2ce input=8b75172c2a7b05f1]*/ -{ - ENSURE_FUTURE_ALIVE(self) - return future_set_result(self, result); -} - -/*[clinic input] -_asyncio.Future.set_exception - - exception: object - / - -Mark the future done and set an exception. - -If the future is already done when this method is called, raises -InvalidStateError. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future_set_exception(FutureObj *self, PyObject *exception) -/*[clinic end generated code: output=f1c1b0cd321be360 input=e45b7d7aa71cc66d]*/ -{ - ENSURE_FUTURE_ALIVE(self) - return future_set_exception(self, exception); -} - -/*[clinic input] -_asyncio.Future.add_done_callback - - fn: object - / - * - context: object = NULL - -Add a callback to be run when the future becomes done. - -The callback is called with a single argument - the future object. If -the future is already done when this is called, the callback is -scheduled with call_soon. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn, - PyObject *context) -/*[clinic end generated code: output=7ce635bbc9554c1e input=15ab0693a96e9533]*/ -{ - if (context == NULL) { - context = PyContext_CopyCurrent(); - if (context == NULL) { - return NULL; - } - PyObject *res = future_add_done_callback(self, fn, context); - Py_DECREF(context); - return res; - } - return future_add_done_callback(self, fn, context); -} - -/*[clinic input] -_asyncio.Future.remove_done_callback - - fn: object - / - -Remove all instances of a callback from the "call when done" list. - -Returns the number of callbacks removed. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) -/*[clinic end generated code: output=5ab1fb52b24ef31f input=0a43280a149d505b]*/ -{ - PyObject *newlist; - Py_ssize_t len, i, j=0; - Py_ssize_t cleared_callback0 = 0; - - ENSURE_FUTURE_ALIVE(self) - - if (self->fut_callback0 != NULL) { - int cmp = PyObject_RichCompareBool(self->fut_callback0, fn, Py_EQ); - if (cmp == -1) { - return NULL; - } - if (cmp == 1) { - /* callback0 == fn */ - Py_CLEAR(self->fut_callback0); - Py_CLEAR(self->fut_context0); - cleared_callback0 = 1; - } - } - - if (self->fut_callbacks == NULL) { - return PyLong_FromSsize_t(cleared_callback0); - } - - len = PyList_GET_SIZE(self->fut_callbacks); - if (len == 0) { - Py_CLEAR(self->fut_callbacks); - return PyLong_FromSsize_t(cleared_callback0); - } - - if (len == 1) { - PyObject *cb_tup = PyList_GET_ITEM(self->fut_callbacks, 0); - int cmp = PyObject_RichCompareBool( - PyTuple_GET_ITEM(cb_tup, 0), fn, Py_EQ); - if (cmp == -1) { - return NULL; - } - if (cmp == 1) { - /* callbacks[0] == fn */ - Py_CLEAR(self->fut_callbacks); - return PyLong_FromSsize_t(1 + cleared_callback0); - } - /* callbacks[0] != fn and len(callbacks) == 1 */ - return PyLong_FromSsize_t(cleared_callback0); - } - - newlist = PyList_New(len); - if (newlist == NULL) { - return NULL; - } - - for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) { - int ret; - PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i); - Py_INCREF(item); - ret = PyObject_RichCompareBool(PyTuple_GET_ITEM(item, 0), fn, Py_EQ); - if (ret == 0) { - if (j < len) { - PyList_SET_ITEM(newlist, j, item); - j++; - continue; - } - ret = PyList_Append(newlist, item); - } - Py_DECREF(item); - if (ret < 0) { - goto fail; - } - } - - if (j == 0) { - Py_CLEAR(self->fut_callbacks); - Py_DECREF(newlist); - return PyLong_FromSsize_t(len + cleared_callback0); - } - - if (j < len) { - Py_SET_SIZE(newlist, j); - } - j = PyList_GET_SIZE(newlist); - len = PyList_GET_SIZE(self->fut_callbacks); - if (j != len) { - if (PyList_SetSlice(self->fut_callbacks, 0, len, newlist) < 0) { - goto fail; - } - } - Py_DECREF(newlist); - return PyLong_FromSsize_t(len - j + cleared_callback0); - -fail: - Py_DECREF(newlist); - return NULL; -} - -/*[clinic input] -_asyncio.Future.cancel - - msg: object = None - -Cancel the future and schedule callbacks. - -If the future is already done or cancelled, return False. Otherwise, -change the future's state to cancelled, schedule the callbacks and -return True. -[clinic start generated code]*/ - static PyObject * -_asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg) -/*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/ -{ - ENSURE_FUTURE_ALIVE(self) - return future_cancel(self, msg); -} +FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(PENDING); + _Py_IDENTIFIER(CANCELLED); + _Py_IDENTIFIER(FINISHED); + PyObject *ret = NULL; + + ENSURE_FUTURE_ALIVE(fut) + + switch (fut->fut_state) { + case STATE_PENDING: + ret = _PyUnicode_FromId(&PyId_PENDING); + break; + case STATE_CANCELLED: + ret = _PyUnicode_FromId(&PyId_CANCELLED); + break; + case STATE_FINISHED: + ret = _PyUnicode_FromId(&PyId_FINISHED); + break; + default: + assert (0); + } + Py_XINCREF(ret); + return ret; +} + +/*[clinic input] +_asyncio.Future._make_cancelled_error -/*[clinic input] -_asyncio.Future.cancelled +Create the CancelledError to raise if the Future is cancelled. -Return True if the future was cancelled. +This should only be called once when handling a cancellation since +it erases the context exception value. [clinic start generated code]*/ static PyObject * -_asyncio_Future_cancelled_impl(FutureObj *self) -/*[clinic end generated code: output=145197ced586357d input=943ab8b7b7b17e45]*/ +_asyncio_Future__make_cancelled_error_impl(FutureObj *self) +/*[clinic end generated code: output=a5df276f6c1213de input=ac6effe4ba795ecc]*/ { - if (future_is_alive(self) && self->fut_state == STATE_CANCELLED) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -/*[clinic input] -_asyncio.Future.done - -Return True if the future is done. - -Done means either that a result / exception are available, or that the -future was cancelled. -[clinic start generated code]*/ + PyObject *exc = create_cancelled_error(self->fut_cancel_msg); + _PyErr_StackItem *exc_state = &self->fut_cancelled_exc_state; + /* Transfer ownership of exc_value from exc_state to exc since we are + done with it. */ + PyException_SetContext(exc, exc_state->exc_value); + exc_state->exc_value = NULL; -static PyObject * -_asyncio_Future_done_impl(FutureObj *self) -/*[clinic end generated code: output=244c5ac351145096 input=28d7b23fdb65d2ac]*/ -{ - if (!future_is_alive(self) || self->fut_state == STATE_PENDING) { - Py_RETURN_FALSE; - } - else { - Py_RETURN_TRUE; - } + return exc; } /*[clinic input] -_asyncio.Future.get_loop - -Return the event loop the Future is bound to. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future_get_loop_impl(FutureObj *self) -/*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/ -{ - ENSURE_FUTURE_ALIVE(self) - Py_INCREF(self->fut_loop); - return self->fut_loop; -} - +_asyncio.Future._repr_info +[clinic start generated code]*/ + +static PyObject * +_asyncio_Future__repr_info_impl(FutureObj *self) +/*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/ +{ + return PyObject_CallOneArg(asyncio_future_repr_info_func, (PyObject *)self); +} + +static PyObject * +FutureObj_repr(FutureObj *fut) +{ + _Py_IDENTIFIER(_repr_info); + + ENSURE_FUTURE_ALIVE(fut) + + PyObject *rinfo = _PyObject_CallMethodIdNoArgs((PyObject*)fut, + &PyId__repr_info); + if (rinfo == NULL) { + return NULL; + } + + PyObject *rinfo_s = PyUnicode_Join(NULL, rinfo); + Py_DECREF(rinfo); + if (rinfo_s == NULL) { + return NULL; + } + + PyObject *rstr = PyUnicode_FromFormat("<%s %U>", + _PyType_Name(Py_TYPE(fut)), rinfo_s); + Py_DECREF(rinfo_s); + return rstr; +} + +static void +FutureObj_finalize(FutureObj *fut) +{ + _Py_IDENTIFIER(call_exception_handler); + _Py_IDENTIFIER(message); + _Py_IDENTIFIER(exception); + _Py_IDENTIFIER(future); + _Py_IDENTIFIER(source_traceback); + + PyObject *error_type, *error_value, *error_traceback; + PyObject *context; + PyObject *message = NULL; + PyObject *func; + + if (!fut->fut_log_tb) { + return; + } + assert(fut->fut_exception != NULL); + fut->fut_log_tb = 0; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + context = PyDict_New(); + if (context == NULL) { + goto finally; + } + + message = PyUnicode_FromFormat( + "%s exception was never retrieved", _PyType_Name(Py_TYPE(fut))); + if (message == NULL) { + goto finally; + } + + if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || + _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 || + _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) { + goto finally; + } + if (fut->fut_source_tb != NULL) { + if (_PyDict_SetItemId(context, &PyId_source_traceback, + fut->fut_source_tb) < 0) { + goto finally; + } + } + + func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler); + if (func != NULL) { + PyObject *res = PyObject_CallOneArg(func, context); + if (res == NULL) { + PyErr_WriteUnraisable(func); + } + else { + Py_DECREF(res); + } + Py_DECREF(func); + } + +finally: + Py_XDECREF(context); + Py_XDECREF(message); + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + static PyObject * -FutureObj_get_blocking(FutureObj *fut, void *Py_UNUSED(ignored)) +future_cls_getitem(PyObject *cls, PyObject *type) { - if (future_is_alive(fut) && fut->fut_blocking) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } + Py_INCREF(cls); + return cls; } - -static int -FutureObj_set_blocking(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored)) -{ - if (future_ensure_alive(fut)) { - return -1; - } - if (val == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - - int is_true = PyObject_IsTrue(val); - if (is_true < 0) { - return -1; - } - fut->fut_blocking = is_true; - return 0; -} - -static PyObject * -FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored)) -{ - ENSURE_FUTURE_ALIVE(fut) - if (fut->fut_log_tb) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -static int -FutureObj_set_log_traceback(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored)) -{ - if (val == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - int is_true = PyObject_IsTrue(val); - if (is_true < 0) { - return -1; - } - if (is_true) { - PyErr_SetString(PyExc_ValueError, - "_log_traceback can only be set to False"); - return -1; - } - fut->fut_log_tb = is_true; - return 0; -} - -static PyObject * -FutureObj_get_loop(FutureObj *fut, void *Py_UNUSED(ignored)) -{ - if (!future_is_alive(fut)) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_loop); - return fut->fut_loop; -} - -static PyObject * -FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored)) -{ - Py_ssize_t i; - - ENSURE_FUTURE_ALIVE(fut) - - if (fut->fut_callback0 == NULL) { - if (fut->fut_callbacks == NULL) { - Py_RETURN_NONE; - } - - Py_INCREF(fut->fut_callbacks); - return fut->fut_callbacks; - } - - Py_ssize_t len = 1; - if (fut->fut_callbacks != NULL) { - len += PyList_GET_SIZE(fut->fut_callbacks); - } - - - PyObject *new_list = PyList_New(len); - if (new_list == NULL) { - return NULL; - } - - PyObject *tup0 = PyTuple_New(2); - if (tup0 == NULL) { - Py_DECREF(new_list); - return NULL; - } - - Py_INCREF(fut->fut_callback0); - PyTuple_SET_ITEM(tup0, 0, fut->fut_callback0); - assert(fut->fut_context0 != NULL); - Py_INCREF(fut->fut_context0); - PyTuple_SET_ITEM(tup0, 1, (PyObject *)fut->fut_context0); - - PyList_SET_ITEM(new_list, 0, tup0); - - if (fut->fut_callbacks != NULL) { - for (i = 0; i < PyList_GET_SIZE(fut->fut_callbacks); i++) { - PyObject *cb = PyList_GET_ITEM(fut->fut_callbacks, i); - Py_INCREF(cb); - PyList_SET_ITEM(new_list, i + 1, cb); - } - } - - return new_list; -} - -static PyObject * -FutureObj_get_result(FutureObj *fut, void *Py_UNUSED(ignored)) -{ - ENSURE_FUTURE_ALIVE(fut) - if (fut->fut_result == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_result); - return fut->fut_result; -} - -static PyObject * -FutureObj_get_exception(FutureObj *fut, void *Py_UNUSED(ignored)) -{ - ENSURE_FUTURE_ALIVE(fut) - if (fut->fut_exception == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_exception); - return fut->fut_exception; -} - -static PyObject * -FutureObj_get_source_traceback(FutureObj *fut, void *Py_UNUSED(ignored)) -{ - if (!future_is_alive(fut) || fut->fut_source_tb == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_source_tb); - return fut->fut_source_tb; -} - -static PyObject * -FutureObj_get_cancel_message(FutureObj *fut, void *Py_UNUSED(ignored)) -{ - if (fut->fut_cancel_msg == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(fut->fut_cancel_msg); - return fut->fut_cancel_msg; -} - -static int -FutureObj_set_cancel_message(FutureObj *fut, PyObject *msg, - void *Py_UNUSED(ignored)) -{ - if (msg == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - Py_INCREF(msg); - Py_XSETREF(fut->fut_cancel_msg, msg); - return 0; -} - -static PyObject * -FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored)) -{ - _Py_IDENTIFIER(PENDING); - _Py_IDENTIFIER(CANCELLED); - _Py_IDENTIFIER(FINISHED); - PyObject *ret = NULL; - - ENSURE_FUTURE_ALIVE(fut) - - switch (fut->fut_state) { - case STATE_PENDING: - ret = _PyUnicode_FromId(&PyId_PENDING); - break; - case STATE_CANCELLED: - ret = _PyUnicode_FromId(&PyId_CANCELLED); - break; - case STATE_FINISHED: - ret = _PyUnicode_FromId(&PyId_FINISHED); - break; - default: - assert (0); - } - Py_XINCREF(ret); - return ret; -} - -/*[clinic input] -_asyncio.Future._make_cancelled_error - -Create the CancelledError to raise if the Future is cancelled. - -This should only be called once when handling a cancellation since -it erases the context exception value. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future__make_cancelled_error_impl(FutureObj *self) -/*[clinic end generated code: output=a5df276f6c1213de input=ac6effe4ba795ecc]*/ -{ - PyObject *exc = create_cancelled_error(self->fut_cancel_msg); - _PyErr_StackItem *exc_state = &self->fut_cancelled_exc_state; - /* Transfer ownership of exc_value from exc_state to exc since we are - done with it. */ - PyException_SetContext(exc, exc_state->exc_value); - exc_state->exc_value = NULL; - - return exc; -} - -/*[clinic input] -_asyncio.Future._repr_info -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future__repr_info_impl(FutureObj *self) -/*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/ -{ - return PyObject_CallOneArg(asyncio_future_repr_info_func, (PyObject *)self); -} - -static PyObject * -FutureObj_repr(FutureObj *fut) -{ - _Py_IDENTIFIER(_repr_info); - - ENSURE_FUTURE_ALIVE(fut) - - PyObject *rinfo = _PyObject_CallMethodIdNoArgs((PyObject*)fut, - &PyId__repr_info); - if (rinfo == NULL) { - return NULL; - } - - PyObject *rinfo_s = PyUnicode_Join(NULL, rinfo); - Py_DECREF(rinfo); - if (rinfo_s == NULL) { - return NULL; - } - - PyObject *rstr = PyUnicode_FromFormat("<%s %U>", - _PyType_Name(Py_TYPE(fut)), rinfo_s); - Py_DECREF(rinfo_s); - return rstr; -} - -static void -FutureObj_finalize(FutureObj *fut) -{ - _Py_IDENTIFIER(call_exception_handler); - _Py_IDENTIFIER(message); - _Py_IDENTIFIER(exception); - _Py_IDENTIFIER(future); - _Py_IDENTIFIER(source_traceback); - - PyObject *error_type, *error_value, *error_traceback; - PyObject *context; - PyObject *message = NULL; - PyObject *func; - - if (!fut->fut_log_tb) { - return; - } - assert(fut->fut_exception != NULL); - fut->fut_log_tb = 0; - - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - context = PyDict_New(); - if (context == NULL) { - goto finally; - } - - message = PyUnicode_FromFormat( - "%s exception was never retrieved", _PyType_Name(Py_TYPE(fut))); - if (message == NULL) { - goto finally; - } - - if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || - _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 || - _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) { - goto finally; - } - if (fut->fut_source_tb != NULL) { - if (_PyDict_SetItemId(context, &PyId_source_traceback, - fut->fut_source_tb) < 0) { - goto finally; - } - } - - func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler); - if (func != NULL) { - PyObject *res = PyObject_CallOneArg(func, context); - if (res == NULL) { - PyErr_WriteUnraisable(func); - } - else { - Py_DECREF(res); - } - Py_DECREF(func); - } - -finally: - Py_XDECREF(context); - Py_XDECREF(message); - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); -} - -static PyObject * -future_cls_getitem(PyObject *cls, PyObject *type) -{ - Py_INCREF(cls); - return cls; -} - -static PyAsyncMethods FutureType_as_async = { - (unaryfunc)future_new_iter, /* am_await */ - 0, /* am_aiter */ - 0 /* am_anext */ -}; - -static PyMethodDef FutureType_methods[] = { - _ASYNCIO_FUTURE_RESULT_METHODDEF - _ASYNCIO_FUTURE_EXCEPTION_METHODDEF - _ASYNCIO_FUTURE_SET_RESULT_METHODDEF - _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF - _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF - _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF - _ASYNCIO_FUTURE_CANCEL_METHODDEF - _ASYNCIO_FUTURE_CANCELLED_METHODDEF - _ASYNCIO_FUTURE_DONE_METHODDEF - _ASYNCIO_FUTURE_GET_LOOP_METHODDEF + +static PyAsyncMethods FutureType_as_async = { + (unaryfunc)future_new_iter, /* am_await */ + 0, /* am_aiter */ + 0 /* am_anext */ +}; + +static PyMethodDef FutureType_methods[] = { + _ASYNCIO_FUTURE_RESULT_METHODDEF + _ASYNCIO_FUTURE_EXCEPTION_METHODDEF + _ASYNCIO_FUTURE_SET_RESULT_METHODDEF + _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF + _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF + _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF + _ASYNCIO_FUTURE_CANCEL_METHODDEF + _ASYNCIO_FUTURE_CANCELLED_METHODDEF + _ASYNCIO_FUTURE_DONE_METHODDEF + _ASYNCIO_FUTURE_GET_LOOP_METHODDEF _ASYNCIO_FUTURE__MAKE_CANCELLED_ERROR_METHODDEF - _ASYNCIO_FUTURE__REPR_INFO_METHODDEF + _ASYNCIO_FUTURE__REPR_INFO_METHODDEF {"__class_getitem__", future_cls_getitem, METH_O|METH_CLASS, NULL}, - {NULL, NULL} /* Sentinel */ -}; - -#define FUTURE_COMMON_GETSETLIST \ - {"_state", (getter)FutureObj_get_state, NULL, NULL}, \ - {"_asyncio_future_blocking", (getter)FutureObj_get_blocking, \ - (setter)FutureObj_set_blocking, NULL}, \ - {"_loop", (getter)FutureObj_get_loop, NULL, NULL}, \ - {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL}, \ - {"_result", (getter)FutureObj_get_result, NULL, NULL}, \ - {"_exception", (getter)FutureObj_get_exception, NULL, NULL}, \ - {"_log_traceback", (getter)FutureObj_get_log_traceback, \ - (setter)FutureObj_set_log_traceback, NULL}, \ - {"_source_traceback", (getter)FutureObj_get_source_traceback, \ - NULL, NULL}, \ - {"_cancel_message", (getter)FutureObj_get_cancel_message, \ - (setter)FutureObj_set_cancel_message, NULL}, - -static PyGetSetDef FutureType_getsetlist[] = { - FUTURE_COMMON_GETSETLIST - {NULL} /* Sentinel */ -}; - -static void FutureObj_dealloc(PyObject *self); - -static PyTypeObject FutureType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.Future", - sizeof(FutureObj), /* tp_basicsize */ - .tp_dealloc = FutureObj_dealloc, - .tp_as_async = &FutureType_as_async, - .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - .tp_doc = _asyncio_Future___init____doc__, - .tp_traverse = (traverseproc)FutureObj_traverse, - .tp_clear = (inquiry)FutureObj_clear, - .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist), - .tp_iter = (getiterfunc)future_new_iter, - .tp_methods = FutureType_methods, - .tp_getset = FutureType_getsetlist, - .tp_dictoffset = offsetof(FutureObj, dict), - .tp_init = (initproc)_asyncio_Future___init__, - .tp_new = PyType_GenericNew, - .tp_finalize = (destructor)FutureObj_finalize, -}; - -static void -FutureObj_dealloc(PyObject *self) -{ - FutureObj *fut = (FutureObj *)self; - - if (Future_CheckExact(fut)) { - /* When fut is subclass of Future, finalizer is called from - * subtype_dealloc. - */ - if (PyObject_CallFinalizerFromDealloc(self) < 0) { - // resurrected. - return; - } - } - - PyObject_GC_UnTrack(self); - - if (fut->fut_weakreflist != NULL) { - PyObject_ClearWeakRefs(self); - } - - (void)FutureObj_clear(fut); - Py_TYPE(fut)->tp_free(fut); -} - - -/*********************** Future Iterator **************************/ - -typedef struct { - PyObject_HEAD - FutureObj *future; -} futureiterobject; - - -#define FI_FREELIST_MAXLEN 255 -static futureiterobject *fi_freelist = NULL; -static Py_ssize_t fi_freelist_len = 0; - - -static void -FutureIter_dealloc(futureiterobject *it) -{ - PyObject_GC_UnTrack(it); - Py_CLEAR(it->future); - - if (fi_freelist_len < FI_FREELIST_MAXLEN) { - fi_freelist_len++; - it->future = (FutureObj*) fi_freelist; - fi_freelist = it; - } - else { - PyObject_GC_Del(it); - } -} - -static PyObject * -FutureIter_iternext(futureiterobject *it) -{ - PyObject *res; - FutureObj *fut = it->future; - - if (fut == NULL) { - return NULL; - } - - if (fut->fut_state == STATE_PENDING) { - if (!fut->fut_blocking) { - fut->fut_blocking = 1; - Py_INCREF(fut); - return (PyObject *)fut; - } - PyErr_SetString(PyExc_RuntimeError, - "await wasn't used with future"); - return NULL; - } - - it->future = NULL; - res = _asyncio_Future_result_impl(fut); - if (res != NULL) { - /* The result of the Future is not an exception. */ - (void)_PyGen_SetStopIterationValue(res); - Py_DECREF(res); - } - - Py_DECREF(fut); - return NULL; -} - -static PyObject * -FutureIter_send(futureiterobject *self, PyObject *unused) -{ - /* Future.__iter__ doesn't care about values that are pushed to the - * generator, it just returns self.result(). - */ - return FutureIter_iternext(self); -} - -static PyObject * -FutureIter_throw(futureiterobject *self, PyObject *args) -{ - PyObject *type, *val = NULL, *tb = NULL; - if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb)) - return NULL; - - if (val == Py_None) { - val = NULL; - } - if (tb == Py_None) { - tb = NULL; - } else if (tb != NULL && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback"); - return NULL; - } - - Py_INCREF(type); - Py_XINCREF(val); - Py_XINCREF(tb); - - if (PyExceptionClass_Check(type)) { - PyErr_NormalizeException(&type, &val, &tb); - /* No need to call PyException_SetTraceback since we'll be calling - PyErr_Restore for `type`, `val`, and `tb`. */ - } else if (PyExceptionInstance_Check(type)) { - if (val) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto fail; - } - val = type; - type = PyExceptionInstance_Class(type); - Py_INCREF(type); - if (tb == NULL) - tb = PyException_GetTraceback(val); - } else { - PyErr_SetString(PyExc_TypeError, - "exceptions must be classes deriving BaseException or " - "instances of such a class"); - goto fail; - } - - Py_CLEAR(self->future); - - PyErr_Restore(type, val, tb); - - return NULL; - - fail: - Py_DECREF(type); - Py_XDECREF(val); - Py_XDECREF(tb); - return NULL; -} - -static PyObject * -FutureIter_close(futureiterobject *self, PyObject *arg) -{ - Py_CLEAR(self->future); - Py_RETURN_NONE; -} - -static int -FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->future); - return 0; -} - -static PyMethodDef FutureIter_methods[] = { - {"send", (PyCFunction)FutureIter_send, METH_O, NULL}, - {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL}, - {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL}, - {NULL, NULL} /* Sentinel */ -}; - -static PyTypeObject FutureIterType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.FutureIter", - .tp_basicsize = sizeof(futureiterobject), - .tp_itemsize = 0, - .tp_dealloc = (destructor)FutureIter_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)FutureIter_traverse, - .tp_iter = PyObject_SelfIter, - .tp_iternext = (iternextfunc)FutureIter_iternext, - .tp_methods = FutureIter_methods, -}; - -static PyObject * -future_new_iter(PyObject *fut) -{ - futureiterobject *it; - - if (!PyObject_TypeCheck(fut, &FutureType)) { - PyErr_BadInternalCall(); - return NULL; - } - - ENSURE_FUTURE_ALIVE(fut) - - if (fi_freelist_len) { - fi_freelist_len--; - it = fi_freelist; - fi_freelist = (futureiterobject*) it->future; - it->future = NULL; - _Py_NewReference((PyObject*) it); - } - else { - it = PyObject_GC_New(futureiterobject, &FutureIterType); - if (it == NULL) { - return NULL; - } - } - - Py_INCREF(fut); - it->future = (FutureObj*)fut; - PyObject_GC_Track(it); - return (PyObject*)it; -} - - -/*********************** Task **************************/ - - -/*[clinic input] -class _asyncio.Task "TaskObj *" "&Task_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/ - -static int task_call_step_soon(TaskObj *, PyObject *); -static PyObject * task_wakeup(TaskObj *, PyObject *); -static PyObject * task_step(TaskObj *, PyObject *); - -/* ----- Task._step wrapper */ - -static int -TaskStepMethWrapper_clear(TaskStepMethWrapper *o) -{ - Py_CLEAR(o->sw_task); - Py_CLEAR(o->sw_arg); - return 0; -} - -static void -TaskStepMethWrapper_dealloc(TaskStepMethWrapper *o) -{ - PyObject_GC_UnTrack(o); - (void)TaskStepMethWrapper_clear(o); - Py_TYPE(o)->tp_free(o); -} - -static PyObject * -TaskStepMethWrapper_call(TaskStepMethWrapper *o, - PyObject *args, PyObject *kwds) -{ - if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) { - PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments"); - return NULL; - } - if (args != NULL && PyTuple_GET_SIZE(args) != 0) { - PyErr_SetString(PyExc_TypeError, "function takes no positional arguments"); - return NULL; - } - return task_step(o->sw_task, o->sw_arg); -} - -static int -TaskStepMethWrapper_traverse(TaskStepMethWrapper *o, - visitproc visit, void *arg) -{ - Py_VISIT(o->sw_task); - Py_VISIT(o->sw_arg); - return 0; -} - -static PyObject * -TaskStepMethWrapper_get___self__(TaskStepMethWrapper *o, void *Py_UNUSED(ignored)) -{ - if (o->sw_task) { - Py_INCREF(o->sw_task); - return (PyObject*)o->sw_task; - } - Py_RETURN_NONE; -} - -static PyGetSetDef TaskStepMethWrapper_getsetlist[] = { - {"__self__", (getter)TaskStepMethWrapper_get___self__, NULL, NULL}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject TaskStepMethWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "TaskStepMethWrapper", - .tp_basicsize = sizeof(TaskStepMethWrapper), - .tp_itemsize = 0, - .tp_getset = TaskStepMethWrapper_getsetlist, - .tp_dealloc = (destructor)TaskStepMethWrapper_dealloc, - .tp_call = (ternaryfunc)TaskStepMethWrapper_call, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)TaskStepMethWrapper_traverse, - .tp_clear = (inquiry)TaskStepMethWrapper_clear, -}; - -static PyObject * -TaskStepMethWrapper_new(TaskObj *task, PyObject *arg) -{ - TaskStepMethWrapper *o; - o = PyObject_GC_New(TaskStepMethWrapper, &TaskStepMethWrapper_Type); - if (o == NULL) { - return NULL; - } - - Py_INCREF(task); - o->sw_task = task; - - Py_XINCREF(arg); - o->sw_arg = arg; - - PyObject_GC_Track(o); - return (PyObject*) o; -} - -/* ----- Task._wakeup wrapper */ - -static PyObject * -TaskWakeupMethWrapper_call(TaskWakeupMethWrapper *o, - PyObject *args, PyObject *kwds) -{ - PyObject *fut; - - if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) { - PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments"); - return NULL; - } - if (!PyArg_ParseTuple(args, "O", &fut)) { - return NULL; - } - - return task_wakeup(o->ww_task, fut); -} - -static int -TaskWakeupMethWrapper_clear(TaskWakeupMethWrapper *o) -{ - Py_CLEAR(o->ww_task); - return 0; -} - -static int -TaskWakeupMethWrapper_traverse(TaskWakeupMethWrapper *o, - visitproc visit, void *arg) -{ - Py_VISIT(o->ww_task); - return 0; -} - -static void -TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) -{ - PyObject_GC_UnTrack(o); - (void)TaskWakeupMethWrapper_clear(o); - Py_TYPE(o)->tp_free(o); -} - -static PyObject * -TaskWakeupMethWrapper_get___self__(TaskWakeupMethWrapper *o, void *Py_UNUSED(ignored)) -{ - if (o->ww_task) { - Py_INCREF(o->ww_task); - return (PyObject*)o->ww_task; - } - Py_RETURN_NONE; -} - -static PyGetSetDef TaskWakeupMethWrapper_getsetlist[] = { - {"__self__", (getter)TaskWakeupMethWrapper_get___self__, NULL, NULL}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject TaskWakeupMethWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "TaskWakeupMethWrapper", - .tp_basicsize = sizeof(TaskWakeupMethWrapper), - .tp_itemsize = 0, - .tp_dealloc = (destructor)TaskWakeupMethWrapper_dealloc, - .tp_call = (ternaryfunc)TaskWakeupMethWrapper_call, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)TaskWakeupMethWrapper_traverse, - .tp_clear = (inquiry)TaskWakeupMethWrapper_clear, - .tp_getset = TaskWakeupMethWrapper_getsetlist, -}; - -static PyObject * -TaskWakeupMethWrapper_new(TaskObj *task) -{ - TaskWakeupMethWrapper *o; - o = PyObject_GC_New(TaskWakeupMethWrapper, &TaskWakeupMethWrapper_Type); - if (o == NULL) { - return NULL; - } - - Py_INCREF(task); - o->ww_task = task; - - PyObject_GC_Track(o); - return (PyObject*) o; -} - -/* ----- Task introspection helpers */ - -static int -register_task(PyObject *task) -{ - _Py_IDENTIFIER(add); - - PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, - &PyId_add, task); - if (res == NULL) { - return -1; - } - Py_DECREF(res); - return 0; -} - - -static int -unregister_task(PyObject *task) -{ - _Py_IDENTIFIER(discard); - - PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, - &PyId_discard, task); - if (res == NULL) { - return -1; - } - Py_DECREF(res); - return 0; -} - - -static int -enter_task(PyObject *loop, PyObject *task) -{ - PyObject *item; - Py_hash_t hash; - hash = PyObject_Hash(loop); - if (hash == -1) { - return -1; - } - item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash); - if (item != NULL) { - Py_INCREF(item); - PyErr_Format( - PyExc_RuntimeError, - "Cannot enter into task %R while another " \ - "task %R is being executed.", - task, item, NULL); - Py_DECREF(item); - return -1; - } - if (PyErr_Occurred()) { - return -1; - } - return _PyDict_SetItem_KnownHash(current_tasks, loop, task, hash); -} - - -static int -leave_task(PyObject *loop, PyObject *task) -/*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/ -{ - PyObject *item; - Py_hash_t hash; - hash = PyObject_Hash(loop); - if (hash == -1) { - return -1; - } - item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash); - if (item != task) { - if (item == NULL) { - /* Not entered, replace with None */ - item = Py_None; - } - PyErr_Format( - PyExc_RuntimeError, - "Leaving task %R does not match the current task %R.", - task, item, NULL); - return -1; - } - return _PyDict_DelItem_KnownHash(current_tasks, loop, hash); -} - -/* ----- Task */ - -/*[clinic input] -_asyncio.Task.__init__ - - coro: object - * - loop: object = None - name: object = None - -A coroutine wrapped in a Future. -[clinic start generated code]*/ - -static int -_asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, - PyObject *name) -/*[clinic end generated code: output=88b12b83d570df50 input=352a3137fe60091d]*/ -{ - if (future_init((FutureObj*)self, loop)) { - return -1; - } - - int is_coro = is_coroutine(coro); - if (is_coro == -1) { - return -1; - } - if (is_coro == 0) { - self->task_log_destroy_pending = 0; - PyErr_Format(PyExc_TypeError, - "a coroutine was expected, got %R", - coro, NULL); - return -1; - } - - Py_XSETREF(self->task_context, PyContext_CopyCurrent()); - if (self->task_context == NULL) { - return -1; - } - - Py_CLEAR(self->task_fut_waiter); - self->task_must_cancel = 0; - self->task_log_destroy_pending = 1; - Py_INCREF(coro); - Py_XSETREF(self->task_coro, coro); - - if (name == Py_None) { - name = PyUnicode_FromFormat("Task-%" PRIu64, ++task_name_counter); - } else if (!PyUnicode_CheckExact(name)) { - name = PyObject_Str(name); - } else { - Py_INCREF(name); - } - Py_XSETREF(self->task_name, name); - if (self->task_name == NULL) { - return -1; - } - - if (task_call_step_soon(self, NULL)) { - return -1; - } - return register_task((PyObject*)self); -} - -static int -TaskObj_clear(TaskObj *task) -{ - (void)FutureObj_clear((FutureObj*) task); - Py_CLEAR(task->task_context); - Py_CLEAR(task->task_coro); - Py_CLEAR(task->task_name); - Py_CLEAR(task->task_fut_waiter); - return 0; -} - -static int -TaskObj_traverse(TaskObj *task, visitproc visit, void *arg) -{ - Py_VISIT(task->task_context); - Py_VISIT(task->task_coro); - Py_VISIT(task->task_name); - Py_VISIT(task->task_fut_waiter); - (void)FutureObj_traverse((FutureObj*) task, visit, arg); - return 0; -} - -static PyObject * -TaskObj_get_log_destroy_pending(TaskObj *task, void *Py_UNUSED(ignored)) -{ - if (task->task_log_destroy_pending) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -static int -TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val, void *Py_UNUSED(ignored)) -{ - if (val == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - int is_true = PyObject_IsTrue(val); - if (is_true < 0) { - return -1; - } - task->task_log_destroy_pending = is_true; - return 0; -} - -static PyObject * -TaskObj_get_must_cancel(TaskObj *task, void *Py_UNUSED(ignored)) -{ - if (task->task_must_cancel) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - + {NULL, NULL} /* Sentinel */ +}; + +#define FUTURE_COMMON_GETSETLIST \ + {"_state", (getter)FutureObj_get_state, NULL, NULL}, \ + {"_asyncio_future_blocking", (getter)FutureObj_get_blocking, \ + (setter)FutureObj_set_blocking, NULL}, \ + {"_loop", (getter)FutureObj_get_loop, NULL, NULL}, \ + {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL}, \ + {"_result", (getter)FutureObj_get_result, NULL, NULL}, \ + {"_exception", (getter)FutureObj_get_exception, NULL, NULL}, \ + {"_log_traceback", (getter)FutureObj_get_log_traceback, \ + (setter)FutureObj_set_log_traceback, NULL}, \ + {"_source_traceback", (getter)FutureObj_get_source_traceback, \ + NULL, NULL}, \ + {"_cancel_message", (getter)FutureObj_get_cancel_message, \ + (setter)FutureObj_set_cancel_message, NULL}, + +static PyGetSetDef FutureType_getsetlist[] = { + FUTURE_COMMON_GETSETLIST + {NULL} /* Sentinel */ +}; + +static void FutureObj_dealloc(PyObject *self); + +static PyTypeObject FutureType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_asyncio.Future", + sizeof(FutureObj), /* tp_basicsize */ + .tp_dealloc = FutureObj_dealloc, + .tp_as_async = &FutureType_as_async, + .tp_repr = (reprfunc)FutureObj_repr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .tp_doc = _asyncio_Future___init____doc__, + .tp_traverse = (traverseproc)FutureObj_traverse, + .tp_clear = (inquiry)FutureObj_clear, + .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist), + .tp_iter = (getiterfunc)future_new_iter, + .tp_methods = FutureType_methods, + .tp_getset = FutureType_getsetlist, + .tp_dictoffset = offsetof(FutureObj, dict), + .tp_init = (initproc)_asyncio_Future___init__, + .tp_new = PyType_GenericNew, + .tp_finalize = (destructor)FutureObj_finalize, +}; + +static void +FutureObj_dealloc(PyObject *self) +{ + FutureObj *fut = (FutureObj *)self; + + if (Future_CheckExact(fut)) { + /* When fut is subclass of Future, finalizer is called from + * subtype_dealloc. + */ + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + // resurrected. + return; + } + } + + PyObject_GC_UnTrack(self); + + if (fut->fut_weakreflist != NULL) { + PyObject_ClearWeakRefs(self); + } + + (void)FutureObj_clear(fut); + Py_TYPE(fut)->tp_free(fut); +} + + +/*********************** Future Iterator **************************/ + +typedef struct { + PyObject_HEAD + FutureObj *future; +} futureiterobject; + + +#define FI_FREELIST_MAXLEN 255 +static futureiterobject *fi_freelist = NULL; +static Py_ssize_t fi_freelist_len = 0; + + +static void +FutureIter_dealloc(futureiterobject *it) +{ + PyObject_GC_UnTrack(it); + Py_CLEAR(it->future); + + if (fi_freelist_len < FI_FREELIST_MAXLEN) { + fi_freelist_len++; + it->future = (FutureObj*) fi_freelist; + fi_freelist = it; + } + else { + PyObject_GC_Del(it); + } +} + +static PyObject * +FutureIter_iternext(futureiterobject *it) +{ + PyObject *res; + FutureObj *fut = it->future; + + if (fut == NULL) { + return NULL; + } + + if (fut->fut_state == STATE_PENDING) { + if (!fut->fut_blocking) { + fut->fut_blocking = 1; + Py_INCREF(fut); + return (PyObject *)fut; + } + PyErr_SetString(PyExc_RuntimeError, + "await wasn't used with future"); + return NULL; + } + + it->future = NULL; + res = _asyncio_Future_result_impl(fut); + if (res != NULL) { + /* The result of the Future is not an exception. */ + (void)_PyGen_SetStopIterationValue(res); + Py_DECREF(res); + } + + Py_DECREF(fut); + return NULL; +} + +static PyObject * +FutureIter_send(futureiterobject *self, PyObject *unused) +{ + /* Future.__iter__ doesn't care about values that are pushed to the + * generator, it just returns self.result(). + */ + return FutureIter_iternext(self); +} + +static PyObject * +FutureIter_throw(futureiterobject *self, PyObject *args) +{ + PyObject *type, *val = NULL, *tb = NULL; + if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb)) + return NULL; + + if (val == Py_None) { + val = NULL; + } + if (tb == Py_None) { + tb = NULL; + } else if (tb != NULL && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback"); + return NULL; + } + + Py_INCREF(type); + Py_XINCREF(val); + Py_XINCREF(tb); + + if (PyExceptionClass_Check(type)) { + PyErr_NormalizeException(&type, &val, &tb); + /* No need to call PyException_SetTraceback since we'll be calling + PyErr_Restore for `type`, `val`, and `tb`. */ + } else if (PyExceptionInstance_Check(type)) { + if (val) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto fail; + } + val = type; + type = PyExceptionInstance_Class(type); + Py_INCREF(type); + if (tb == NULL) + tb = PyException_GetTraceback(val); + } else { + PyErr_SetString(PyExc_TypeError, + "exceptions must be classes deriving BaseException or " + "instances of such a class"); + goto fail; + } + + Py_CLEAR(self->future); + + PyErr_Restore(type, val, tb); + + return NULL; + + fail: + Py_DECREF(type); + Py_XDECREF(val); + Py_XDECREF(tb); + return NULL; +} + +static PyObject * +FutureIter_close(futureiterobject *self, PyObject *arg) +{ + Py_CLEAR(self->future); + Py_RETURN_NONE; +} + +static int +FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->future); + return 0; +} + +static PyMethodDef FutureIter_methods[] = { + {"send", (PyCFunction)FutureIter_send, METH_O, NULL}, + {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL}, + {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL}, + {NULL, NULL} /* Sentinel */ +}; + +static PyTypeObject FutureIterType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_asyncio.FutureIter", + .tp_basicsize = sizeof(futureiterobject), + .tp_itemsize = 0, + .tp_dealloc = (destructor)FutureIter_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)FutureIter_traverse, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)FutureIter_iternext, + .tp_methods = FutureIter_methods, +}; + +static PyObject * +future_new_iter(PyObject *fut) +{ + futureiterobject *it; + + if (!PyObject_TypeCheck(fut, &FutureType)) { + PyErr_BadInternalCall(); + return NULL; + } + + ENSURE_FUTURE_ALIVE(fut) + + if (fi_freelist_len) { + fi_freelist_len--; + it = fi_freelist; + fi_freelist = (futureiterobject*) it->future; + it->future = NULL; + _Py_NewReference((PyObject*) it); + } + else { + it = PyObject_GC_New(futureiterobject, &FutureIterType); + if (it == NULL) { + return NULL; + } + } + + Py_INCREF(fut); + it->future = (FutureObj*)fut; + PyObject_GC_Track(it); + return (PyObject*)it; +} + + +/*********************** Task **************************/ + + +/*[clinic input] +class _asyncio.Task "TaskObj *" "&Task_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/ + +static int task_call_step_soon(TaskObj *, PyObject *); +static PyObject * task_wakeup(TaskObj *, PyObject *); +static PyObject * task_step(TaskObj *, PyObject *); + +/* ----- Task._step wrapper */ + +static int +TaskStepMethWrapper_clear(TaskStepMethWrapper *o) +{ + Py_CLEAR(o->sw_task); + Py_CLEAR(o->sw_arg); + return 0; +} + +static void +TaskStepMethWrapper_dealloc(TaskStepMethWrapper *o) +{ + PyObject_GC_UnTrack(o); + (void)TaskStepMethWrapper_clear(o); + Py_TYPE(o)->tp_free(o); +} + +static PyObject * +TaskStepMethWrapper_call(TaskStepMethWrapper *o, + PyObject *args, PyObject *kwds) +{ + if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) { + PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments"); + return NULL; + } + if (args != NULL && PyTuple_GET_SIZE(args) != 0) { + PyErr_SetString(PyExc_TypeError, "function takes no positional arguments"); + return NULL; + } + return task_step(o->sw_task, o->sw_arg); +} + +static int +TaskStepMethWrapper_traverse(TaskStepMethWrapper *o, + visitproc visit, void *arg) +{ + Py_VISIT(o->sw_task); + Py_VISIT(o->sw_arg); + return 0; +} + +static PyObject * +TaskStepMethWrapper_get___self__(TaskStepMethWrapper *o, void *Py_UNUSED(ignored)) +{ + if (o->sw_task) { + Py_INCREF(o->sw_task); + return (PyObject*)o->sw_task; + } + Py_RETURN_NONE; +} + +static PyGetSetDef TaskStepMethWrapper_getsetlist[] = { + {"__self__", (getter)TaskStepMethWrapper_get___self__, NULL, NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject TaskStepMethWrapper_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "TaskStepMethWrapper", + .tp_basicsize = sizeof(TaskStepMethWrapper), + .tp_itemsize = 0, + .tp_getset = TaskStepMethWrapper_getsetlist, + .tp_dealloc = (destructor)TaskStepMethWrapper_dealloc, + .tp_call = (ternaryfunc)TaskStepMethWrapper_call, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)TaskStepMethWrapper_traverse, + .tp_clear = (inquiry)TaskStepMethWrapper_clear, +}; + +static PyObject * +TaskStepMethWrapper_new(TaskObj *task, PyObject *arg) +{ + TaskStepMethWrapper *o; + o = PyObject_GC_New(TaskStepMethWrapper, &TaskStepMethWrapper_Type); + if (o == NULL) { + return NULL; + } + + Py_INCREF(task); + o->sw_task = task; + + Py_XINCREF(arg); + o->sw_arg = arg; + + PyObject_GC_Track(o); + return (PyObject*) o; +} + +/* ----- Task._wakeup wrapper */ + +static PyObject * +TaskWakeupMethWrapper_call(TaskWakeupMethWrapper *o, + PyObject *args, PyObject *kwds) +{ + PyObject *fut; + + if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) { + PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments"); + return NULL; + } + if (!PyArg_ParseTuple(args, "O", &fut)) { + return NULL; + } + + return task_wakeup(o->ww_task, fut); +} + +static int +TaskWakeupMethWrapper_clear(TaskWakeupMethWrapper *o) +{ + Py_CLEAR(o->ww_task); + return 0; +} + +static int +TaskWakeupMethWrapper_traverse(TaskWakeupMethWrapper *o, + visitproc visit, void *arg) +{ + Py_VISIT(o->ww_task); + return 0; +} + +static void +TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) +{ + PyObject_GC_UnTrack(o); + (void)TaskWakeupMethWrapper_clear(o); + Py_TYPE(o)->tp_free(o); +} + static PyObject * -TaskObj_get_coro(TaskObj *task, void *Py_UNUSED(ignored)) +TaskWakeupMethWrapper_get___self__(TaskWakeupMethWrapper *o, void *Py_UNUSED(ignored)) { - if (task->task_coro) { - Py_INCREF(task->task_coro); - return task->task_coro; + if (o->ww_task) { + Py_INCREF(o->ww_task); + return (PyObject*)o->ww_task; } - Py_RETURN_NONE; } -static PyObject * -TaskObj_get_fut_waiter(TaskObj *task, void *Py_UNUSED(ignored)) -{ - if (task->task_fut_waiter) { - Py_INCREF(task->task_fut_waiter); - return task->task_fut_waiter; - } +static PyGetSetDef TaskWakeupMethWrapper_getsetlist[] = { + {"__self__", (getter)TaskWakeupMethWrapper_get___self__, NULL, NULL}, + {NULL} /* Sentinel */ +}; - Py_RETURN_NONE; -} +static PyTypeObject TaskWakeupMethWrapper_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "TaskWakeupMethWrapper", + .tp_basicsize = sizeof(TaskWakeupMethWrapper), + .tp_itemsize = 0, + .tp_dealloc = (destructor)TaskWakeupMethWrapper_dealloc, + .tp_call = (ternaryfunc)TaskWakeupMethWrapper_call, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)TaskWakeupMethWrapper_traverse, + .tp_clear = (inquiry)TaskWakeupMethWrapper_clear, + .tp_getset = TaskWakeupMethWrapper_getsetlist, +}; + +static PyObject * +TaskWakeupMethWrapper_new(TaskObj *task) +{ + TaskWakeupMethWrapper *o; + o = PyObject_GC_New(TaskWakeupMethWrapper, &TaskWakeupMethWrapper_Type); + if (o == NULL) { + return NULL; + } + + Py_INCREF(task); + o->ww_task = task; + + PyObject_GC_Track(o); + return (PyObject*) o; +} + +/* ----- Task introspection helpers */ + +static int +register_task(PyObject *task) +{ + _Py_IDENTIFIER(add); + + PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, + &PyId_add, task); + if (res == NULL) { + return -1; + } + Py_DECREF(res); + return 0; +} + + +static int +unregister_task(PyObject *task) +{ + _Py_IDENTIFIER(discard); + + PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, + &PyId_discard, task); + if (res == NULL) { + return -1; + } + Py_DECREF(res); + return 0; +} + + +static int +enter_task(PyObject *loop, PyObject *task) +{ + PyObject *item; + Py_hash_t hash; + hash = PyObject_Hash(loop); + if (hash == -1) { + return -1; + } + item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash); + if (item != NULL) { + Py_INCREF(item); + PyErr_Format( + PyExc_RuntimeError, + "Cannot enter into task %R while another " \ + "task %R is being executed.", + task, item, NULL); + Py_DECREF(item); + return -1; + } + if (PyErr_Occurred()) { + return -1; + } + return _PyDict_SetItem_KnownHash(current_tasks, loop, task, hash); +} + + +static int +leave_task(PyObject *loop, PyObject *task) +/*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/ +{ + PyObject *item; + Py_hash_t hash; + hash = PyObject_Hash(loop); + if (hash == -1) { + return -1; + } + item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash); + if (item != task) { + if (item == NULL) { + /* Not entered, replace with None */ + item = Py_None; + } + PyErr_Format( + PyExc_RuntimeError, + "Leaving task %R does not match the current task %R.", + task, item, NULL); + return -1; + } + return _PyDict_DelItem_KnownHash(current_tasks, loop, hash); +} + +/* ----- Task */ + +/*[clinic input] +_asyncio.Task.__init__ + + coro: object + * + loop: object = None + name: object = None + +A coroutine wrapped in a Future. +[clinic start generated code]*/ + +static int +_asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, + PyObject *name) +/*[clinic end generated code: output=88b12b83d570df50 input=352a3137fe60091d]*/ +{ + if (future_init((FutureObj*)self, loop)) { + return -1; + } + + int is_coro = is_coroutine(coro); + if (is_coro == -1) { + return -1; + } + if (is_coro == 0) { + self->task_log_destroy_pending = 0; + PyErr_Format(PyExc_TypeError, + "a coroutine was expected, got %R", + coro, NULL); + return -1; + } + + Py_XSETREF(self->task_context, PyContext_CopyCurrent()); + if (self->task_context == NULL) { + return -1; + } + + Py_CLEAR(self->task_fut_waiter); + self->task_must_cancel = 0; + self->task_log_destroy_pending = 1; + Py_INCREF(coro); + Py_XSETREF(self->task_coro, coro); + + if (name == Py_None) { + name = PyUnicode_FromFormat("Task-%" PRIu64, ++task_name_counter); + } else if (!PyUnicode_CheckExact(name)) { + name = PyObject_Str(name); + } else { + Py_INCREF(name); + } + Py_XSETREF(self->task_name, name); + if (self->task_name == NULL) { + return -1; + } -/*[clinic input] + if (task_call_step_soon(self, NULL)) { + return -1; + } + return register_task((PyObject*)self); +} + +static int +TaskObj_clear(TaskObj *task) +{ + (void)FutureObj_clear((FutureObj*) task); + Py_CLEAR(task->task_context); + Py_CLEAR(task->task_coro); + Py_CLEAR(task->task_name); + Py_CLEAR(task->task_fut_waiter); + return 0; +} + +static int +TaskObj_traverse(TaskObj *task, visitproc visit, void *arg) +{ + Py_VISIT(task->task_context); + Py_VISIT(task->task_coro); + Py_VISIT(task->task_name); + Py_VISIT(task->task_fut_waiter); + (void)FutureObj_traverse((FutureObj*) task, visit, arg); + return 0; +} + +static PyObject * +TaskObj_get_log_destroy_pending(TaskObj *task, void *Py_UNUSED(ignored)) +{ + if (task->task_log_destroy_pending) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +static int +TaskObj_set_log_destroy_pending(TaskObj *task, PyObject *val, void *Py_UNUSED(ignored)) +{ + if (val == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + int is_true = PyObject_IsTrue(val); + if (is_true < 0) { + return -1; + } + task->task_log_destroy_pending = is_true; + return 0; +} + +static PyObject * +TaskObj_get_must_cancel(TaskObj *task, void *Py_UNUSED(ignored)) +{ + if (task->task_must_cancel) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +static PyObject * +TaskObj_get_coro(TaskObj *task, void *Py_UNUSED(ignored)) +{ + if (task->task_coro) { + Py_INCREF(task->task_coro); + return task->task_coro; + } + + Py_RETURN_NONE; +} + +static PyObject * +TaskObj_get_fut_waiter(TaskObj *task, void *Py_UNUSED(ignored)) +{ + if (task->task_fut_waiter) { + Py_INCREF(task->task_fut_waiter); + return task->task_fut_waiter; + } + + Py_RETURN_NONE; +} + +/*[clinic input] _asyncio.Task._make_cancelled_error - + Create the CancelledError to raise if the Task is cancelled. - + This should only be called once when handling a cancellation since it erases the context exception value. -[clinic start generated code]*/ - -static PyObject * +[clinic start generated code]*/ + +static PyObject * _asyncio_Task__make_cancelled_error_impl(TaskObj *self) /*[clinic end generated code: output=55a819e8b4276fab input=52c0e32de8e2f840]*/ -{ +{ FutureObj *fut = (FutureObj*)self; return _asyncio_Future__make_cancelled_error_impl(fut); -} - - -/*[clinic input] -_asyncio.Task._repr_info -[clinic start generated code]*/ - -static PyObject * -_asyncio_Task__repr_info_impl(TaskObj *self) -/*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/ -{ +} + + +/*[clinic input] +_asyncio.Task._repr_info +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task__repr_info_impl(TaskObj *self) +/*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/ +{ return PyObject_CallOneArg(asyncio_task_repr_info_func, (PyObject *)self); -} - -/*[clinic input] -_asyncio.Task.cancel - +} + +/*[clinic input] +_asyncio.Task.cancel + msg: object = None -Request that this task cancel itself. - -This arranges for a CancelledError to be thrown into the -wrapped coroutine on the next cycle through the event loop. -The coroutine then has a chance to clean up or even deny -the request using try/except/finally. - -Unlike Future.cancel, this does not guarantee that the -task will be cancelled: the exception might be caught and -acted upon, delaying cancellation of the task or preventing -cancellation completely. The task may also return a value or -raise a different exception. - -Immediately after this method is called, Task.cancelled() will -not return True (unless the task was already cancelled). A -task will be marked as cancelled when the wrapped coroutine -terminates with a CancelledError exception (even if cancel() -was not called). -[clinic start generated code]*/ - -static PyObject * +Request that this task cancel itself. + +This arranges for a CancelledError to be thrown into the +wrapped coroutine on the next cycle through the event loop. +The coroutine then has a chance to clean up or even deny +the request using try/except/finally. + +Unlike Future.cancel, this does not guarantee that the +task will be cancelled: the exception might be caught and +acted upon, delaying cancellation of the task or preventing +cancellation completely. The task may also return a value or +raise a different exception. + +Immediately after this method is called, Task.cancelled() will +not return True (unless the task was already cancelled). A +task will be marked as cancelled when the wrapped coroutine +terminates with a CancelledError exception (even if cancel() +was not called). +[clinic start generated code]*/ + +static PyObject * _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) /*[clinic end generated code: output=c66b60d41c74f9f1 input=f4ff8e8ffc5f1c00]*/ -{ - self->task_log_tb = 0; - - if (self->task_state != STATE_PENDING) { - Py_RETURN_FALSE; - } - - if (self->task_fut_waiter) { - PyObject *res; - int is_true; - +{ + self->task_log_tb = 0; + + if (self->task_state != STATE_PENDING) { + Py_RETURN_FALSE; + } + + if (self->task_fut_waiter) { + PyObject *res; + int is_true; + res = _PyObject_CallMethodIdOneArg(self->task_fut_waiter, &PyId_cancel, msg); - if (res == NULL) { - return NULL; - } - - is_true = PyObject_IsTrue(res); - Py_DECREF(res); - if (is_true < 0) { - return NULL; - } - - if (is_true) { - Py_RETURN_TRUE; - } - } - - self->task_must_cancel = 1; + if (res == NULL) { + return NULL; + } + + is_true = PyObject_IsTrue(res); + Py_DECREF(res); + if (is_true < 0) { + return NULL; + } + + if (is_true) { + Py_RETURN_TRUE; + } + } + + self->task_must_cancel = 1; Py_XINCREF(msg); Py_XSETREF(self->task_cancel_msg, msg); - Py_RETURN_TRUE; -} - -/*[clinic input] -_asyncio.Task.get_stack - - * - limit: object = None - -Return the list of stack frames for this task's coroutine. - -If the coroutine is not done, this returns the stack where it is -suspended. If the coroutine has completed successfully or was -cancelled, this returns an empty list. If the coroutine was -terminated by an exception, this returns the list of traceback -frames. - -The frames are always ordered from oldest to newest. - -The optional limit gives the maximum number of frames to -return; by default all available frames are returned. Its -meaning differs depending on whether a stack or a traceback is -returned: the newest frames of a stack are returned, but the -oldest frames of a traceback are returned. (This matches the -behavior of the traceback module.) - -For reasons beyond our control, only one stack frame is -returned for a suspended coroutine. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit) -/*[clinic end generated code: output=c9aeeeebd1e18118 input=05b323d42b809b90]*/ -{ - return PyObject_CallFunctionObjArgs( - asyncio_task_get_stack_func, self, limit, NULL); -} - -/*[clinic input] -_asyncio.Task.print_stack - - * - limit: object = None - file: object = None - -Print the stack or traceback for this task's coroutine. - -This produces output similar to that of the traceback module, -for the frames retrieved by get_stack(). The limit argument -is passed to get_stack(). The file argument is an I/O stream -to which the output is written; by default output is written -to sys.stderr. -[clinic start generated code]*/ - -static PyObject * -_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, - PyObject *file) -/*[clinic end generated code: output=7339e10314cd3f4d input=1a0352913b7fcd92]*/ -{ - return PyObject_CallFunctionObjArgs( - asyncio_task_print_stack_func, self, limit, file, NULL); -} - -/*[clinic input] -_asyncio.Task.set_result - - result: object - / -[clinic start generated code]*/ - -static PyObject * -_asyncio_Task_set_result(TaskObj *self, PyObject *result) -/*[clinic end generated code: output=1dcae308bfcba318 input=9d1a00c07be41bab]*/ -{ - PyErr_SetString(PyExc_RuntimeError, - "Task does not support set_result operation"); - return NULL; -} - -/*[clinic input] -_asyncio.Task.set_exception - - exception: object - / -[clinic start generated code]*/ - -static PyObject * -_asyncio_Task_set_exception(TaskObj *self, PyObject *exception) -/*[clinic end generated code: output=bc377fc28067303d input=9a8f65c83dcf893a]*/ -{ - PyErr_SetString(PyExc_RuntimeError, - "Task does not support set_exception operation"); - return NULL; -} - + Py_RETURN_TRUE; +} + +/*[clinic input] +_asyncio.Task.get_stack + + * + limit: object = None + +Return the list of stack frames for this task's coroutine. + +If the coroutine is not done, this returns the stack where it is +suspended. If the coroutine has completed successfully or was +cancelled, this returns an empty list. If the coroutine was +terminated by an exception, this returns the list of traceback +frames. + +The frames are always ordered from oldest to newest. + +The optional limit gives the maximum number of frames to +return; by default all available frames are returned. Its +meaning differs depending on whether a stack or a traceback is +returned: the newest frames of a stack are returned, but the +oldest frames of a traceback are returned. (This matches the +behavior of the traceback module.) + +For reasons beyond our control, only one stack frame is +returned for a suspended coroutine. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit) +/*[clinic end generated code: output=c9aeeeebd1e18118 input=05b323d42b809b90]*/ +{ + return PyObject_CallFunctionObjArgs( + asyncio_task_get_stack_func, self, limit, NULL); +} + +/*[clinic input] +_asyncio.Task.print_stack + + * + limit: object = None + file: object = None + +Print the stack or traceback for this task's coroutine. + +This produces output similar to that of the traceback module, +for the frames retrieved by get_stack(). The limit argument +is passed to get_stack(). The file argument is an I/O stream +to which the output is written; by default output is written +to sys.stderr. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, + PyObject *file) +/*[clinic end generated code: output=7339e10314cd3f4d input=1a0352913b7fcd92]*/ +{ + return PyObject_CallFunctionObjArgs( + asyncio_task_print_stack_func, self, limit, file, NULL); +} + +/*[clinic input] +_asyncio.Task.set_result + + result: object + / +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_set_result(TaskObj *self, PyObject *result) +/*[clinic end generated code: output=1dcae308bfcba318 input=9d1a00c07be41bab]*/ +{ + PyErr_SetString(PyExc_RuntimeError, + "Task does not support set_result operation"); + return NULL; +} + +/*[clinic input] +_asyncio.Task.set_exception + + exception: object + / +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_set_exception(TaskObj *self, PyObject *exception) +/*[clinic end generated code: output=bc377fc28067303d input=9a8f65c83dcf893a]*/ +{ + PyErr_SetString(PyExc_RuntimeError, + "Task does not support set_exception operation"); + return NULL; +} + /*[clinic input] _asyncio.Task.get_coro [clinic start generated code]*/ - + static PyObject * _asyncio_Task_get_coro_impl(TaskObj *self) /*[clinic end generated code: output=bcac27c8cc6c8073 input=d2e8606c42a7b403]*/ @@ -2420,73 +2420,73 @@ _asyncio_Task_set_name(TaskObj *self, PyObject *value) Py_RETURN_NONE; } -static void -TaskObj_finalize(TaskObj *task) -{ - _Py_IDENTIFIER(call_exception_handler); - _Py_IDENTIFIER(task); - _Py_IDENTIFIER(message); - _Py_IDENTIFIER(source_traceback); - - PyObject *context; - PyObject *message = NULL; - PyObject *func; - PyObject *error_type, *error_value, *error_traceback; - - if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) { - goto done; - } - - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - context = PyDict_New(); - if (context == NULL) { - goto finally; - } - - message = PyUnicode_FromString("Task was destroyed but it is pending!"); - if (message == NULL) { - goto finally; - } - - if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || - _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0) - { - goto finally; - } - - if (task->task_source_tb != NULL) { - if (_PyDict_SetItemId(context, &PyId_source_traceback, - task->task_source_tb) < 0) - { - goto finally; - } - } - - func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler); - if (func != NULL) { +static void +TaskObj_finalize(TaskObj *task) +{ + _Py_IDENTIFIER(call_exception_handler); + _Py_IDENTIFIER(task); + _Py_IDENTIFIER(message); + _Py_IDENTIFIER(source_traceback); + + PyObject *context; + PyObject *message = NULL; + PyObject *func; + PyObject *error_type, *error_value, *error_traceback; + + if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) { + goto done; + } + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + context = PyDict_New(); + if (context == NULL) { + goto finally; + } + + message = PyUnicode_FromString("Task was destroyed but it is pending!"); + if (message == NULL) { + goto finally; + } + + if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || + _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0) + { + goto finally; + } + + if (task->task_source_tb != NULL) { + if (_PyDict_SetItemId(context, &PyId_source_traceback, + task->task_source_tb) < 0) + { + goto finally; + } + } + + func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler); + if (func != NULL) { PyObject *res = PyObject_CallOneArg(func, context); - if (res == NULL) { - PyErr_WriteUnraisable(func); - } - else { - Py_DECREF(res); - } - Py_DECREF(func); - } - -finally: - Py_XDECREF(context); - Py_XDECREF(message); - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); - -done: - FutureObj_finalize((FutureObj*)task); -} - + if (res == NULL) { + PyErr_WriteUnraisable(func); + } + else { + Py_DECREF(res); + } + Py_DECREF(func); + } + +finally: + Py_XDECREF(context); + Py_XDECREF(message); + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); + +done: + FutureObj_finalize((FutureObj*)task); +} + static PyObject * task_cls_getitem(PyObject *cls, PyObject *type) { @@ -2494,234 +2494,234 @@ task_cls_getitem(PyObject *cls, PyObject *type) return cls; } -static void TaskObj_dealloc(PyObject *); /* Needs Task_CheckExact */ - -static PyMethodDef TaskType_methods[] = { - _ASYNCIO_FUTURE_RESULT_METHODDEF - _ASYNCIO_FUTURE_EXCEPTION_METHODDEF - _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF - _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF - _ASYNCIO_FUTURE_CANCELLED_METHODDEF - _ASYNCIO_FUTURE_DONE_METHODDEF - _ASYNCIO_TASK_SET_RESULT_METHODDEF - _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF - _ASYNCIO_TASK_CANCEL_METHODDEF - _ASYNCIO_TASK_GET_STACK_METHODDEF - _ASYNCIO_TASK_PRINT_STACK_METHODDEF +static void TaskObj_dealloc(PyObject *); /* Needs Task_CheckExact */ + +static PyMethodDef TaskType_methods[] = { + _ASYNCIO_FUTURE_RESULT_METHODDEF + _ASYNCIO_FUTURE_EXCEPTION_METHODDEF + _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF + _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF + _ASYNCIO_FUTURE_CANCELLED_METHODDEF + _ASYNCIO_FUTURE_DONE_METHODDEF + _ASYNCIO_TASK_SET_RESULT_METHODDEF + _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF + _ASYNCIO_TASK_CANCEL_METHODDEF + _ASYNCIO_TASK_GET_STACK_METHODDEF + _ASYNCIO_TASK_PRINT_STACK_METHODDEF _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF - _ASYNCIO_TASK__REPR_INFO_METHODDEF + _ASYNCIO_TASK__REPR_INFO_METHODDEF _ASYNCIO_TASK_GET_NAME_METHODDEF _ASYNCIO_TASK_SET_NAME_METHODDEF _ASYNCIO_TASK_GET_CORO_METHODDEF {"__class_getitem__", task_cls_getitem, METH_O|METH_CLASS, NULL}, - {NULL, NULL} /* Sentinel */ -}; - -static PyGetSetDef TaskType_getsetlist[] = { - FUTURE_COMMON_GETSETLIST - {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending, - (setter)TaskObj_set_log_destroy_pending, NULL}, - {"_must_cancel", (getter)TaskObj_get_must_cancel, NULL, NULL}, - {"_coro", (getter)TaskObj_get_coro, NULL, NULL}, - {"_fut_waiter", (getter)TaskObj_get_fut_waiter, NULL, NULL}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject TaskType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.Task", - sizeof(TaskObj), /* tp_basicsize */ - .tp_base = &FutureType, - .tp_dealloc = TaskObj_dealloc, - .tp_as_async = &FutureType_as_async, - .tp_repr = (reprfunc)FutureObj_repr, + {NULL, NULL} /* Sentinel */ +}; + +static PyGetSetDef TaskType_getsetlist[] = { + FUTURE_COMMON_GETSETLIST + {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending, + (setter)TaskObj_set_log_destroy_pending, NULL}, + {"_must_cancel", (getter)TaskObj_get_must_cancel, NULL, NULL}, + {"_coro", (getter)TaskObj_get_coro, NULL, NULL}, + {"_fut_waiter", (getter)TaskObj_get_fut_waiter, NULL, NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject TaskType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_asyncio.Task", + sizeof(TaskObj), /* tp_basicsize */ + .tp_base = &FutureType, + .tp_dealloc = TaskObj_dealloc, + .tp_as_async = &FutureType_as_async, + .tp_repr = (reprfunc)FutureObj_repr, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - .tp_doc = _asyncio_Task___init____doc__, - .tp_traverse = (traverseproc)TaskObj_traverse, - .tp_clear = (inquiry)TaskObj_clear, - .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist), - .tp_iter = (getiterfunc)future_new_iter, - .tp_methods = TaskType_methods, - .tp_getset = TaskType_getsetlist, - .tp_dictoffset = offsetof(TaskObj, dict), - .tp_init = (initproc)_asyncio_Task___init__, - .tp_new = PyType_GenericNew, - .tp_finalize = (destructor)TaskObj_finalize, -}; - -static void -TaskObj_dealloc(PyObject *self) -{ - TaskObj *task = (TaskObj *)self; - - if (Task_CheckExact(self)) { - /* When fut is subclass of Task, finalizer is called from - * subtype_dealloc. - */ - if (PyObject_CallFinalizerFromDealloc(self) < 0) { - // resurrected. - return; - } - } - - PyObject_GC_UnTrack(self); - - if (task->task_weakreflist != NULL) { - PyObject_ClearWeakRefs(self); - } - - (void)TaskObj_clear(task); - Py_TYPE(task)->tp_free(task); -} - -static int -task_call_step_soon(TaskObj *task, PyObject *arg) -{ - PyObject *cb = TaskStepMethWrapper_new(task, arg); - if (cb == NULL) { - return -1; - } - - int ret = call_soon(task->task_loop, cb, NULL, task->task_context); - Py_DECREF(cb); - return ret; -} - -static PyObject * -task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) -{ - PyObject* msg; - - va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - msg = PyUnicode_FromFormatV(format, vargs); - va_end(vargs); - - if (msg == NULL) { - return NULL; - } - + .tp_doc = _asyncio_Task___init____doc__, + .tp_traverse = (traverseproc)TaskObj_traverse, + .tp_clear = (inquiry)TaskObj_clear, + .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist), + .tp_iter = (getiterfunc)future_new_iter, + .tp_methods = TaskType_methods, + .tp_getset = TaskType_getsetlist, + .tp_dictoffset = offsetof(TaskObj, dict), + .tp_init = (initproc)_asyncio_Task___init__, + .tp_new = PyType_GenericNew, + .tp_finalize = (destructor)TaskObj_finalize, +}; + +static void +TaskObj_dealloc(PyObject *self) +{ + TaskObj *task = (TaskObj *)self; + + if (Task_CheckExact(self)) { + /* When fut is subclass of Task, finalizer is called from + * subtype_dealloc. + */ + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + // resurrected. + return; + } + } + + PyObject_GC_UnTrack(self); + + if (task->task_weakreflist != NULL) { + PyObject_ClearWeakRefs(self); + } + + (void)TaskObj_clear(task); + Py_TYPE(task)->tp_free(task); +} + +static int +task_call_step_soon(TaskObj *task, PyObject *arg) +{ + PyObject *cb = TaskStepMethWrapper_new(task, arg); + if (cb == NULL) { + return -1; + } + + int ret = call_soon(task->task_loop, cb, NULL, task->task_context); + Py_DECREF(cb); + return ret; +} + +static PyObject * +task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) +{ + PyObject* msg; + + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + msg = PyUnicode_FromFormatV(format, vargs); + va_end(vargs); + + if (msg == NULL) { + return NULL; + } + PyObject *e = PyObject_CallOneArg(et, msg); - Py_DECREF(msg); - if (e == NULL) { - return NULL; - } - - if (task_call_step_soon(task, e) == -1) { - Py_DECREF(e); - return NULL; - } - - Py_DECREF(e); - Py_RETURN_NONE; -} - -static PyObject * -task_step_impl(TaskObj *task, PyObject *exc) -{ - int res; - int clear_exc = 0; - PyObject *result = NULL; - PyObject *coro; - PyObject *o; - - if (task->task_state != STATE_PENDING) { - PyErr_Format(asyncio_InvalidStateError, - "_step(): already done: %R %R", - task, - exc ? exc : Py_None); - goto fail; - } - - if (task->task_must_cancel) { - assert(exc != Py_None); - - if (exc) { - /* Check if exc is a CancelledError */ - res = PyObject_IsInstance(exc, asyncio_CancelledError); - if (res == -1) { - /* An error occurred, abort */ - goto fail; - } - if (res == 0) { - /* exc is not CancelledError; reset it to NULL */ - exc = NULL; - } - } - - if (!exc) { - /* exc was not a CancelledError */ + Py_DECREF(msg); + if (e == NULL) { + return NULL; + } + + if (task_call_step_soon(task, e) == -1) { + Py_DECREF(e); + return NULL; + } + + Py_DECREF(e); + Py_RETURN_NONE; +} + +static PyObject * +task_step_impl(TaskObj *task, PyObject *exc) +{ + int res; + int clear_exc = 0; + PyObject *result = NULL; + PyObject *coro; + PyObject *o; + + if (task->task_state != STATE_PENDING) { + PyErr_Format(asyncio_InvalidStateError, + "_step(): already done: %R %R", + task, + exc ? exc : Py_None); + goto fail; + } + + if (task->task_must_cancel) { + assert(exc != Py_None); + + if (exc) { + /* Check if exc is a CancelledError */ + res = PyObject_IsInstance(exc, asyncio_CancelledError); + if (res == -1) { + /* An error occurred, abort */ + goto fail; + } + if (res == 0) { + /* exc is not CancelledError; reset it to NULL */ + exc = NULL; + } + } + + if (!exc) { + /* exc was not a CancelledError */ exc = create_cancelled_error(task->task_cancel_msg); - if (!exc) { - goto fail; - } - clear_exc = 1; - } - - task->task_must_cancel = 0; - } - - Py_CLEAR(task->task_fut_waiter); - - coro = task->task_coro; - if (coro == NULL) { - PyErr_SetString(PyExc_RuntimeError, "uninitialized Task object"); + if (!exc) { + goto fail; + } + clear_exc = 1; + } + + task->task_must_cancel = 0; + } + + Py_CLEAR(task->task_fut_waiter); + + coro = task->task_coro; + if (coro == NULL) { + PyErr_SetString(PyExc_RuntimeError, "uninitialized Task object"); if (clear_exc) { /* We created 'exc' during this call */ Py_DECREF(exc); } - return NULL; - } - - if (exc == NULL) { - if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) { - result = _PyGen_Send((PyGenObject*)coro, Py_None); - } - else { + return NULL; + } + + if (exc == NULL) { + if (PyGen_CheckExact(coro) || PyCoro_CheckExact(coro)) { + result = _PyGen_Send((PyGenObject*)coro, Py_None); + } + else { result = _PyObject_CallMethodIdOneArg(coro, &PyId_send, Py_None); - } - } - else { + } + } + else { result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc); - if (clear_exc) { - /* We created 'exc' during this call */ - Py_DECREF(exc); - } - } - - if (result == NULL) { - PyObject *et, *ev, *tb; - - if (_PyGen_FetchStopIterationValue(&o) == 0) { - /* The error is StopIteration and that means that - the underlying coroutine has resolved */ + if (clear_exc) { + /* We created 'exc' during this call */ + Py_DECREF(exc); + } + } + + if (result == NULL) { + PyObject *et, *ev, *tb; + + if (_PyGen_FetchStopIterationValue(&o) == 0) { + /* The error is StopIteration and that means that + the underlying coroutine has resolved */ PyObject *res; - if (task->task_must_cancel) { - // Task is cancelled right before coro stops. - task->task_must_cancel = 0; + if (task->task_must_cancel) { + // Task is cancelled right before coro stops. + task->task_must_cancel = 0; res = future_cancel((FutureObj*)task, task->task_cancel_msg); - } + } else { res = future_set_result((FutureObj*)task, o); } - Py_DECREF(o); - - if (res == NULL) { - return NULL; - } - Py_DECREF(res); - Py_RETURN_NONE; - } - - if (PyErr_ExceptionMatches(asyncio_CancelledError)) { - /* CancelledError */ + Py_DECREF(o); + + if (res == NULL) { + return NULL; + } + Py_DECREF(res); + Py_RETURN_NONE; + } + + if (PyErr_ExceptionMatches(asyncio_CancelledError)) { + /* CancelledError */ PyErr_Fetch(&et, &ev, &tb); FutureObj *fut = (FutureObj*)task; @@ -2731,64 +2731,64 @@ task_step_impl(TaskObj *task, PyObject *exc) exc_state->exc_traceback = tb; return future_cancel(fut, NULL); - } - - /* Some other exception; pop it and call Task.set_exception() */ - PyErr_Fetch(&et, &ev, &tb); - - assert(et); - if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { - PyErr_NormalizeException(&et, &ev, &tb); - } - if (tb != NULL) { - PyException_SetTraceback(ev, tb); - } - o = future_set_exception((FutureObj*)task, ev); - if (!o) { - /* An exception in Task.set_exception() */ - Py_DECREF(et); - Py_XDECREF(tb); - Py_XDECREF(ev); - goto fail; - } - assert(o == Py_None); - Py_DECREF(o); - + } + + /* Some other exception; pop it and call Task.set_exception() */ + PyErr_Fetch(&et, &ev, &tb); + + assert(et); + if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { + PyErr_NormalizeException(&et, &ev, &tb); + } + if (tb != NULL) { + PyException_SetTraceback(ev, tb); + } + o = future_set_exception((FutureObj*)task, ev); + if (!o) { + /* An exception in Task.set_exception() */ + Py_DECREF(et); + Py_XDECREF(tb); + Py_XDECREF(ev); + goto fail; + } + assert(o == Py_None); + Py_DECREF(o); + if (PyErr_GivenExceptionMatches(et, PyExc_KeyboardInterrupt) || PyErr_GivenExceptionMatches(et, PyExc_SystemExit)) { /* We've got a KeyboardInterrupt or a SystemError; re-raise it */ - PyErr_Restore(et, ev, tb); - goto fail; - } - - Py_DECREF(et); - Py_XDECREF(tb); - Py_XDECREF(ev); - - Py_RETURN_NONE; - } - - if (result == (PyObject*)task) { - /* We have a task that wants to await on itself */ - goto self_await; - } - - /* Check if `result` is FutureObj or TaskObj (and not a subclass) */ - if (Future_CheckExact(result) || Task_CheckExact(result)) { - PyObject *wrapper; - PyObject *res; - FutureObj *fut = (FutureObj*)result; - - /* Check if `result` future is attached to a different loop */ - if (fut->fut_loop != task->task_loop) { - goto different_loop; - } - + PyErr_Restore(et, ev, tb); + goto fail; + } + + Py_DECREF(et); + Py_XDECREF(tb); + Py_XDECREF(ev); + + Py_RETURN_NONE; + } + + if (result == (PyObject*)task) { + /* We have a task that wants to await on itself */ + goto self_await; + } + + /* Check if `result` is FutureObj or TaskObj (and not a subclass) */ + if (Future_CheckExact(result) || Task_CheckExact(result)) { + PyObject *wrapper; + PyObject *res; + FutureObj *fut = (FutureObj*)result; + + /* Check if `result` future is attached to a different loop */ + if (fut->fut_loop != task->task_loop) { + goto different_loop; + } + if (!fut->fut_blocking) { goto yield_insteadof_yf; } - + fut->fut_blocking = 0; /* result.add_done_callback(task._wakeup) */ @@ -2814,30 +2814,30 @@ task_step_impl(TaskObj *task, PyObject *exc) task->task_cancel_msg); if (r == NULL) { return NULL; - } + } is_true = PyObject_IsTrue(r); Py_DECREF(r); if (is_true < 0) { return NULL; - } + } else if (is_true) { task->task_must_cancel = 0; } } - + Py_RETURN_NONE; } - + /* Check if `result` is None */ if (result == Py_None) { /* Bare yield relinquishes control for one event loop iteration. */ if (task_call_step_soon(task, NULL)) { goto fail; - } + } return result; - } - - /* Check if `result` is a Future-compatible object */ + } + + /* Check if `result` is a Future-compatible object */ if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) { goto fail; } @@ -2850,34 +2850,34 @@ task_step_impl(TaskObj *task, PyObject *exc) Py_DECREF(o); if (blocking < 0) { goto fail; - } + } /* Check if `result` future is attached to a different loop */ PyObject *oloop = get_future_loop(result); if (oloop == NULL) { - goto fail; - } + goto fail; + } if (oloop != task->task_loop) { Py_DECREF(oloop); goto different_loop; - } + } Py_DECREF(oloop); - + if (!blocking) { goto yield_insteadof_yf; } - + /* result._asyncio_future_blocking = False */ if (_PyObject_SetAttrId( result, &PyId__asyncio_future_blocking, Py_False) == -1) { goto fail; } - + wrapper = TaskWakeupMethWrapper_new(task); if (wrapper == NULL) { goto fail; } - + /* result.add_done_callback(task._wakeup) */ PyObject *add_cb = _PyObject_GetAttrId( result, &PyId_add_done_callback); @@ -2895,10 +2895,10 @@ task_step_impl(TaskObj *task, PyObject *exc) goto fail; } Py_DECREF(res); - + /* task._fut_waiter = result */ task->task_fut_waiter = result; /* no incref is necessary */ - + if (task->task_must_cancel) { PyObject *r; int is_true; @@ -2906,584 +2906,584 @@ task_step_impl(TaskObj *task, PyObject *exc) task->task_cancel_msg); if (r == NULL) { return NULL; - } + } is_true = PyObject_IsTrue(r); Py_DECREF(r); if (is_true < 0) { return NULL; - } + } else if (is_true) { task->task_must_cancel = 0; } - } - + } + Py_RETURN_NONE; - } - + } + Py_XDECREF(o); - /* Check if `result` is a generator */ + /* Check if `result` is a generator */ res = PyObject_IsInstance(result, (PyObject*)&PyGen_Type); if (res < 0) { - goto fail; - } + goto fail; + } if (res) { - /* `result` is a generator */ - o = task_set_error_soon( - task, PyExc_RuntimeError, - "yield was used instead of yield from for " - "generator in task %R with %R", task, result); - Py_DECREF(result); - return o; - } - - /* The `result` is none of the above */ - o = task_set_error_soon( - task, PyExc_RuntimeError, "Task got bad yield: %R", result); - Py_DECREF(result); - return o; - -self_await: - o = task_set_error_soon( - task, PyExc_RuntimeError, - "Task cannot await on itself: %R", task); - Py_DECREF(result); - return o; - -yield_insteadof_yf: - o = task_set_error_soon( - task, PyExc_RuntimeError, - "yield was used instead of yield from " - "in task %R with %R", - task, result); - Py_DECREF(result); - return o; - -different_loop: - o = task_set_error_soon( - task, PyExc_RuntimeError, - "Task %R got Future %R attached to a different loop", - task, result); - Py_DECREF(result); - return o; - -fail: - Py_XDECREF(result); - return NULL; -} - -static PyObject * -task_step(TaskObj *task, PyObject *exc) -{ - PyObject *res; - - if (enter_task(task->task_loop, (PyObject*)task) < 0) { - return NULL; - } - - res = task_step_impl(task, exc); - - if (res == NULL) { - PyObject *et, *ev, *tb; - PyErr_Fetch(&et, &ev, &tb); - leave_task(task->task_loop, (PyObject*)task); - _PyErr_ChainExceptions(et, ev, tb); - return NULL; - } - else { + /* `result` is a generator */ + o = task_set_error_soon( + task, PyExc_RuntimeError, + "yield was used instead of yield from for " + "generator in task %R with %R", task, result); + Py_DECREF(result); + return o; + } + + /* The `result` is none of the above */ + o = task_set_error_soon( + task, PyExc_RuntimeError, "Task got bad yield: %R", result); + Py_DECREF(result); + return o; + +self_await: + o = task_set_error_soon( + task, PyExc_RuntimeError, + "Task cannot await on itself: %R", task); + Py_DECREF(result); + return o; + +yield_insteadof_yf: + o = task_set_error_soon( + task, PyExc_RuntimeError, + "yield was used instead of yield from " + "in task %R with %R", + task, result); + Py_DECREF(result); + return o; + +different_loop: + o = task_set_error_soon( + task, PyExc_RuntimeError, + "Task %R got Future %R attached to a different loop", + task, result); + Py_DECREF(result); + return o; + +fail: + Py_XDECREF(result); + return NULL; +} + +static PyObject * +task_step(TaskObj *task, PyObject *exc) +{ + PyObject *res; + + if (enter_task(task->task_loop, (PyObject*)task) < 0) { + return NULL; + } + + res = task_step_impl(task, exc); + + if (res == NULL) { + PyObject *et, *ev, *tb; + PyErr_Fetch(&et, &ev, &tb); + leave_task(task->task_loop, (PyObject*)task); + _PyErr_ChainExceptions(et, ev, tb); + return NULL; + } + else { if (leave_task(task->task_loop, (PyObject*)task) < 0) { - Py_DECREF(res); - return NULL; - } - else { - return res; - } - } -} - -static PyObject * -task_wakeup(TaskObj *task, PyObject *o) -{ - PyObject *et, *ev, *tb; - PyObject *result; - assert(o); - - if (Future_CheckExact(o) || Task_CheckExact(o)) { - PyObject *fut_result = NULL; - int res = future_get_result((FutureObj*)o, &fut_result); - - switch(res) { - case -1: - assert(fut_result == NULL); - break; /* exception raised */ - case 0: - Py_DECREF(fut_result); - return task_step(task, NULL); - default: - assert(res == 1); - result = task_step(task, fut_result); - Py_DECREF(fut_result); - return result; - } - } - else { - PyObject *fut_result = PyObject_CallMethod(o, "result", NULL); - if (fut_result != NULL) { - Py_DECREF(fut_result); - return task_step(task, NULL); - } - /* exception raised */ - } - - PyErr_Fetch(&et, &ev, &tb); - if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { - PyErr_NormalizeException(&et, &ev, &tb); - } - - result = task_step(task, ev); - - Py_DECREF(et); - Py_XDECREF(tb); - Py_XDECREF(ev); - - return result; -} - - -/*********************** Functions **************************/ - - -/*[clinic input] -_asyncio._get_running_loop - -Return the running event loop or None. - -This is a low-level function intended to be used by event loops. -This function is thread-specific. - -[clinic start generated code]*/ - -static PyObject * -_asyncio__get_running_loop_impl(PyObject *module) -/*[clinic end generated code: output=b4390af721411a0a input=0a21627e25a4bd43]*/ -{ - PyObject *loop; - if (get_running_loop(&loop)) { - return NULL; - } - if (loop == NULL) { - /* There's no currently running event loop */ - Py_RETURN_NONE; - } - return loop; -} - -/*[clinic input] -_asyncio._set_running_loop - loop: 'O' - / - -Set the running event loop. - -This is a low-level function intended to be used by event loops. -This function is thread-specific. -[clinic start generated code]*/ - -static PyObject * -_asyncio__set_running_loop(PyObject *module, PyObject *loop) -/*[clinic end generated code: output=ae56bf7a28ca189a input=4c9720233d606604]*/ -{ - if (set_running_loop(loop)) { - return NULL; - } - Py_RETURN_NONE; -} - -/*[clinic input] -_asyncio.get_event_loop - -Return an asyncio event loop. - -When called from a coroutine or a callback (e.g. scheduled with -call_soon or similar API), this function will always return the -running event loop. - -If there is no running event loop set, the function will return -the result of `get_event_loop_policy().get_event_loop()` call. -[clinic start generated code]*/ - -static PyObject * -_asyncio_get_event_loop_impl(PyObject *module) -/*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/ -{ - return get_event_loop(); -} - -/*[clinic input] -_asyncio.get_running_loop - -Return the running event loop. Raise a RuntimeError if there is none. - -This function is thread-specific. -[clinic start generated code]*/ - -static PyObject * -_asyncio_get_running_loop_impl(PyObject *module) -/*[clinic end generated code: output=c247b5f9e529530e input=2a3bf02ba39f173d]*/ -{ - PyObject *loop; - if (get_running_loop(&loop)) { - return NULL; - } - if (loop == NULL) { - /* There's no currently running event loop */ - PyErr_SetString( - PyExc_RuntimeError, "no running event loop"); - } - return loop; -} - -/*[clinic input] -_asyncio._register_task - - task: object - -Register a new task in asyncio as executed by loop. - -Returns None. -[clinic start generated code]*/ - -static PyObject * -_asyncio__register_task_impl(PyObject *module, PyObject *task) -/*[clinic end generated code: output=8672dadd69a7d4e2 input=21075aaea14dfbad]*/ -{ - if (register_task(task) < 0) { - return NULL; - } - Py_RETURN_NONE; -} - - -/*[clinic input] -_asyncio._unregister_task - - task: object - -Unregister a task. - -Returns None. -[clinic start generated code]*/ - -static PyObject * -_asyncio__unregister_task_impl(PyObject *module, PyObject *task) -/*[clinic end generated code: output=6e5585706d568a46 input=28fb98c3975f7bdc]*/ -{ - if (unregister_task(task) < 0) { - return NULL; - } - Py_RETURN_NONE; -} - - -/*[clinic input] -_asyncio._enter_task - - loop: object - task: object - -Enter into task execution or resume suspended task. - -Task belongs to loop. - -Returns None. -[clinic start generated code]*/ - -static PyObject * -_asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task) -/*[clinic end generated code: output=a22611c858035b73 input=de1b06dca70d8737]*/ -{ - if (enter_task(loop, task) < 0) { - return NULL; - } - Py_RETURN_NONE; -} - - -/*[clinic input] -_asyncio._leave_task - - loop: object - task: object - -Leave task execution or suspend a task. - -Task belongs to loop. - -Returns None. -[clinic start generated code]*/ - -static PyObject * -_asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task) -/*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/ -{ - if (leave_task(loop, task) < 0) { - return NULL; - } - Py_RETURN_NONE; -} - - -/*********************** PyRunningLoopHolder ********************/ - - -static PyRunningLoopHolder * -new_running_loop_holder(PyObject *loop) -{ - PyRunningLoopHolder *rl = PyObject_New( - PyRunningLoopHolder, &PyRunningLoopHolder_Type); - if (rl == NULL) { - return NULL; - } - -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - rl->rl_pid = getpid(); -#endif - - Py_INCREF(loop); - rl->rl_loop = loop; - - return rl; -} - - -static void -PyRunningLoopHolder_tp_dealloc(PyRunningLoopHolder *rl) -{ + Py_DECREF(res); + return NULL; + } + else { + return res; + } + } +} + +static PyObject * +task_wakeup(TaskObj *task, PyObject *o) +{ + PyObject *et, *ev, *tb; + PyObject *result; + assert(o); + + if (Future_CheckExact(o) || Task_CheckExact(o)) { + PyObject *fut_result = NULL; + int res = future_get_result((FutureObj*)o, &fut_result); + + switch(res) { + case -1: + assert(fut_result == NULL); + break; /* exception raised */ + case 0: + Py_DECREF(fut_result); + return task_step(task, NULL); + default: + assert(res == 1); + result = task_step(task, fut_result); + Py_DECREF(fut_result); + return result; + } + } + else { + PyObject *fut_result = PyObject_CallMethod(o, "result", NULL); + if (fut_result != NULL) { + Py_DECREF(fut_result); + return task_step(task, NULL); + } + /* exception raised */ + } + + PyErr_Fetch(&et, &ev, &tb); + if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { + PyErr_NormalizeException(&et, &ev, &tb); + } + + result = task_step(task, ev); + + Py_DECREF(et); + Py_XDECREF(tb); + Py_XDECREF(ev); + + return result; +} + + +/*********************** Functions **************************/ + + +/*[clinic input] +_asyncio._get_running_loop + +Return the running event loop or None. + +This is a low-level function intended to be used by event loops. +This function is thread-specific. + +[clinic start generated code]*/ + +static PyObject * +_asyncio__get_running_loop_impl(PyObject *module) +/*[clinic end generated code: output=b4390af721411a0a input=0a21627e25a4bd43]*/ +{ + PyObject *loop; + if (get_running_loop(&loop)) { + return NULL; + } + if (loop == NULL) { + /* There's no currently running event loop */ + Py_RETURN_NONE; + } + return loop; +} + +/*[clinic input] +_asyncio._set_running_loop + loop: 'O' + / + +Set the running event loop. + +This is a low-level function intended to be used by event loops. +This function is thread-specific. +[clinic start generated code]*/ + +static PyObject * +_asyncio__set_running_loop(PyObject *module, PyObject *loop) +/*[clinic end generated code: output=ae56bf7a28ca189a input=4c9720233d606604]*/ +{ + if (set_running_loop(loop)) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_asyncio.get_event_loop + +Return an asyncio event loop. + +When called from a coroutine or a callback (e.g. scheduled with +call_soon or similar API), this function will always return the +running event loop. + +If there is no running event loop set, the function will return +the result of `get_event_loop_policy().get_event_loop()` call. +[clinic start generated code]*/ + +static PyObject * +_asyncio_get_event_loop_impl(PyObject *module) +/*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/ +{ + return get_event_loop(); +} + +/*[clinic input] +_asyncio.get_running_loop + +Return the running event loop. Raise a RuntimeError if there is none. + +This function is thread-specific. +[clinic start generated code]*/ + +static PyObject * +_asyncio_get_running_loop_impl(PyObject *module) +/*[clinic end generated code: output=c247b5f9e529530e input=2a3bf02ba39f173d]*/ +{ + PyObject *loop; + if (get_running_loop(&loop)) { + return NULL; + } + if (loop == NULL) { + /* There's no currently running event loop */ + PyErr_SetString( + PyExc_RuntimeError, "no running event loop"); + } + return loop; +} + +/*[clinic input] +_asyncio._register_task + + task: object + +Register a new task in asyncio as executed by loop. + +Returns None. +[clinic start generated code]*/ + +static PyObject * +_asyncio__register_task_impl(PyObject *module, PyObject *task) +/*[clinic end generated code: output=8672dadd69a7d4e2 input=21075aaea14dfbad]*/ +{ + if (register_task(task) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +/*[clinic input] +_asyncio._unregister_task + + task: object + +Unregister a task. + +Returns None. +[clinic start generated code]*/ + +static PyObject * +_asyncio__unregister_task_impl(PyObject *module, PyObject *task) +/*[clinic end generated code: output=6e5585706d568a46 input=28fb98c3975f7bdc]*/ +{ + if (unregister_task(task) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +/*[clinic input] +_asyncio._enter_task + + loop: object + task: object + +Enter into task execution or resume suspended task. + +Task belongs to loop. + +Returns None. +[clinic start generated code]*/ + +static PyObject * +_asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task) +/*[clinic end generated code: output=a22611c858035b73 input=de1b06dca70d8737]*/ +{ + if (enter_task(loop, task) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +/*[clinic input] +_asyncio._leave_task + + loop: object + task: object + +Leave task execution or suspend a task. + +Task belongs to loop. + +Returns None. +[clinic start generated code]*/ + +static PyObject * +_asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task) +/*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/ +{ + if (leave_task(loop, task) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +/*********************** PyRunningLoopHolder ********************/ + + +static PyRunningLoopHolder * +new_running_loop_holder(PyObject *loop) +{ + PyRunningLoopHolder *rl = PyObject_New( + PyRunningLoopHolder, &PyRunningLoopHolder_Type); + if (rl == NULL) { + return NULL; + } + +#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) + rl->rl_pid = getpid(); +#endif + + Py_INCREF(loop); + rl->rl_loop = loop; + + return rl; +} + + +static void +PyRunningLoopHolder_tp_dealloc(PyRunningLoopHolder *rl) +{ if (cached_running_holder == (PyObject *)rl) { cached_running_holder = NULL; } - Py_CLEAR(rl->rl_loop); - PyObject_Free(rl); -} - - -static PyTypeObject PyRunningLoopHolder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_RunningLoopHolder", - sizeof(PyRunningLoopHolder), - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_dealloc = (destructor)PyRunningLoopHolder_tp_dealloc, -}; - - -/*********************** Module **************************/ - - -static void -module_free_freelists(void) -{ - PyObject *next; - PyObject *current; - - next = (PyObject*) fi_freelist; - while (next != NULL) { - assert(fi_freelist_len > 0); - fi_freelist_len--; - - current = next; - next = (PyObject*) ((futureiterobject*) current)->future; - PyObject_GC_Del(current); - } - assert(fi_freelist_len == 0); - fi_freelist = NULL; -} - - -static void -module_free(void *m) -{ - Py_CLEAR(asyncio_mod); - Py_CLEAR(traceback_extract_stack); - Py_CLEAR(asyncio_future_repr_info_func); - Py_CLEAR(asyncio_get_event_loop_policy); - Py_CLEAR(asyncio_iscoroutine_func); - Py_CLEAR(asyncio_task_get_stack_func); - Py_CLEAR(asyncio_task_print_stack_func); - Py_CLEAR(asyncio_task_repr_info_func); - Py_CLEAR(asyncio_InvalidStateError); - Py_CLEAR(asyncio_CancelledError); - - Py_CLEAR(all_tasks); - Py_CLEAR(current_tasks); - Py_CLEAR(iscoroutine_typecache); - - Py_CLEAR(context_kwname); - - module_free_freelists(); + Py_CLEAR(rl->rl_loop); + PyObject_Free(rl); +} + + +static PyTypeObject PyRunningLoopHolder_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_RunningLoopHolder", + sizeof(PyRunningLoopHolder), + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_dealloc = (destructor)PyRunningLoopHolder_tp_dealloc, +}; + + +/*********************** Module **************************/ + + +static void +module_free_freelists(void) +{ + PyObject *next; + PyObject *current; + + next = (PyObject*) fi_freelist; + while (next != NULL) { + assert(fi_freelist_len > 0); + fi_freelist_len--; + + current = next; + next = (PyObject*) ((futureiterobject*) current)->future; + PyObject_GC_Del(current); + } + assert(fi_freelist_len == 0); + fi_freelist = NULL; +} + + +static void +module_free(void *m) +{ + Py_CLEAR(asyncio_mod); + Py_CLEAR(traceback_extract_stack); + Py_CLEAR(asyncio_future_repr_info_func); + Py_CLEAR(asyncio_get_event_loop_policy); + Py_CLEAR(asyncio_iscoroutine_func); + Py_CLEAR(asyncio_task_get_stack_func); + Py_CLEAR(asyncio_task_print_stack_func); + Py_CLEAR(asyncio_task_repr_info_func); + Py_CLEAR(asyncio_InvalidStateError); + Py_CLEAR(asyncio_CancelledError); + + Py_CLEAR(all_tasks); + Py_CLEAR(current_tasks); + Py_CLEAR(iscoroutine_typecache); + + Py_CLEAR(context_kwname); + + module_free_freelists(); module_initialized = 0; -} - -static int -module_init(void) -{ - PyObject *module = NULL; +} + +static int +module_init(void) +{ + PyObject *module = NULL; if (module_initialized) { return 0; } - - asyncio_mod = PyImport_ImportModule("asyncio"); - if (asyncio_mod == NULL) { - goto fail; - } - - current_tasks = PyDict_New(); - if (current_tasks == NULL) { - goto fail; - } - - iscoroutine_typecache = PySet_New(NULL); - if (iscoroutine_typecache == NULL) { - goto fail; - } - - + + asyncio_mod = PyImport_ImportModule("asyncio"); + if (asyncio_mod == NULL) { + goto fail; + } + + current_tasks = PyDict_New(); + if (current_tasks == NULL) { + goto fail; + } + + iscoroutine_typecache = PySet_New(NULL); + if (iscoroutine_typecache == NULL) { + goto fail; + } + + context_kwname = Py_BuildValue("(s)", "context"); - if (context_kwname == NULL) { - goto fail; - } - -#define WITH_MOD(NAME) \ - Py_CLEAR(module); \ - module = PyImport_ImportModule(NAME); \ - if (module == NULL) { \ - goto fail; \ - } - -#define GET_MOD_ATTR(VAR, NAME) \ - VAR = PyObject_GetAttrString(module, NAME); \ - if (VAR == NULL) { \ - goto fail; \ - } - - WITH_MOD("asyncio.events") - GET_MOD_ATTR(asyncio_get_event_loop_policy, "get_event_loop_policy") - - WITH_MOD("asyncio.base_futures") - GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info") + if (context_kwname == NULL) { + goto fail; + } + +#define WITH_MOD(NAME) \ + Py_CLEAR(module); \ + module = PyImport_ImportModule(NAME); \ + if (module == NULL) { \ + goto fail; \ + } + +#define GET_MOD_ATTR(VAR, NAME) \ + VAR = PyObject_GetAttrString(module, NAME); \ + if (VAR == NULL) { \ + goto fail; \ + } + + WITH_MOD("asyncio.events") + GET_MOD_ATTR(asyncio_get_event_loop_policy, "get_event_loop_policy") + + WITH_MOD("asyncio.base_futures") + GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info") WITH_MOD("asyncio.exceptions") - GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError") - GET_MOD_ATTR(asyncio_CancelledError, "CancelledError") - - WITH_MOD("asyncio.base_tasks") - GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info") - GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack") - GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack") - - WITH_MOD("asyncio.coroutines") - GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine") - - WITH_MOD("traceback") - GET_MOD_ATTR(traceback_extract_stack, "extract_stack") - - PyObject *weak_set; - WITH_MOD("weakref") - GET_MOD_ATTR(weak_set, "WeakSet"); + GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError") + GET_MOD_ATTR(asyncio_CancelledError, "CancelledError") + + WITH_MOD("asyncio.base_tasks") + GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info") + GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack") + GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack") + + WITH_MOD("asyncio.coroutines") + GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine") + + WITH_MOD("traceback") + GET_MOD_ATTR(traceback_extract_stack, "extract_stack") + + PyObject *weak_set; + WITH_MOD("weakref") + GET_MOD_ATTR(weak_set, "WeakSet"); all_tasks = PyObject_CallNoArgs(weak_set); - Py_CLEAR(weak_set); - if (all_tasks == NULL) { - goto fail; - } - + Py_CLEAR(weak_set); + if (all_tasks == NULL) { + goto fail; + } + module_initialized = 1; - Py_DECREF(module); - return 0; - -fail: - Py_CLEAR(module); - module_free(NULL); - return -1; - -#undef WITH_MOD -#undef GET_MOD_ATTR -} - -PyDoc_STRVAR(module_doc, "Accelerator module for asyncio"); - -static PyMethodDef asyncio_methods[] = { - _ASYNCIO_GET_EVENT_LOOP_METHODDEF - _ASYNCIO_GET_RUNNING_LOOP_METHODDEF - _ASYNCIO__GET_RUNNING_LOOP_METHODDEF - _ASYNCIO__SET_RUNNING_LOOP_METHODDEF - _ASYNCIO__REGISTER_TASK_METHODDEF - _ASYNCIO__UNREGISTER_TASK_METHODDEF - _ASYNCIO__ENTER_TASK_METHODDEF - _ASYNCIO__LEAVE_TASK_METHODDEF - {NULL, NULL} -}; - -static struct PyModuleDef _asynciomodule = { - PyModuleDef_HEAD_INIT, /* m_base */ - "_asyncio", /* m_name */ - module_doc, /* m_doc */ - -1, /* m_size */ - asyncio_methods, /* m_methods */ - NULL, /* m_slots */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - (freefunc)module_free /* m_free */ -}; - - -PyMODINIT_FUNC -PyInit__asyncio(void) -{ - if (module_init() < 0) { - return NULL; - } - if (PyType_Ready(&FutureIterType) < 0) { - return NULL; - } - if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) { - return NULL; - } + Py_DECREF(module); + return 0; + +fail: + Py_CLEAR(module); + module_free(NULL); + return -1; + +#undef WITH_MOD +#undef GET_MOD_ATTR +} + +PyDoc_STRVAR(module_doc, "Accelerator module for asyncio"); + +static PyMethodDef asyncio_methods[] = { + _ASYNCIO_GET_EVENT_LOOP_METHODDEF + _ASYNCIO_GET_RUNNING_LOOP_METHODDEF + _ASYNCIO__GET_RUNNING_LOOP_METHODDEF + _ASYNCIO__SET_RUNNING_LOOP_METHODDEF + _ASYNCIO__REGISTER_TASK_METHODDEF + _ASYNCIO__UNREGISTER_TASK_METHODDEF + _ASYNCIO__ENTER_TASK_METHODDEF + _ASYNCIO__LEAVE_TASK_METHODDEF + {NULL, NULL} +}; + +static struct PyModuleDef _asynciomodule = { + PyModuleDef_HEAD_INIT, /* m_base */ + "_asyncio", /* m_name */ + module_doc, /* m_doc */ + -1, /* m_size */ + asyncio_methods, /* m_methods */ + NULL, /* m_slots */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + (freefunc)module_free /* m_free */ +}; + + +PyMODINIT_FUNC +PyInit__asyncio(void) +{ + if (module_init() < 0) { + return NULL; + } + if (PyType_Ready(&FutureIterType) < 0) { + return NULL; + } + if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) { + return NULL; + } if (PyType_Ready(&TaskWakeupMethWrapper_Type) < 0) { - return NULL; - } - if (PyType_Ready(&PyRunningLoopHolder_Type) < 0) { - return NULL; - } - - PyObject *m = PyModule_Create(&_asynciomodule); - if (m == NULL) { - return NULL; - } - + return NULL; + } + if (PyType_Ready(&PyRunningLoopHolder_Type) < 0) { + return NULL; + } + + PyObject *m = PyModule_Create(&_asynciomodule); + if (m == NULL) { + return NULL; + } + /* FutureType and TaskType are made ready by PyModule_AddType() calls below. */ if (PyModule_AddType(m, &FutureType) < 0) { Py_DECREF(m); - return NULL; - } - + return NULL; + } + if (PyModule_AddType(m, &TaskType) < 0) { Py_DECREF(m); - return NULL; - } - - Py_INCREF(all_tasks); - if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) { - Py_DECREF(all_tasks); + return NULL; + } + + Py_INCREF(all_tasks); + if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) { + Py_DECREF(all_tasks); Py_DECREF(m); - return NULL; - } - - Py_INCREF(current_tasks); - if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) { - Py_DECREF(current_tasks); + return NULL; + } + + Py_INCREF(current_tasks); + if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) { + Py_DECREF(current_tasks); Py_DECREF(m); - return NULL; - } - - return m; -} + return NULL; + } + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_bisectmodule.c b/contrib/tools/python3/src/Modules/_bisectmodule.c index 82d800d9a87..152e83fd2b5 100644 --- a/contrib/tools/python3/src/Modules/_bisectmodule.c +++ b/contrib/tools/python3/src/Modules/_bisectmodule.c @@ -1,11 +1,11 @@ -/* Bisection algorithms. Drop in replacement for bisect.py - -Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru). -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" - +/* Bisection algorithms. Drop in replacement for bisect.py + +Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru). +*/ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" + /*[clinic input] module _bisect [clinic start generated code]*/ @@ -13,44 +13,44 @@ module _bisect #include "clinic/_bisectmodule.c.h" -_Py_IDENTIFIER(insert); - +_Py_IDENTIFIER(insert); + static inline Py_ssize_t -internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) -{ - PyObject *litem; - Py_ssize_t mid; - int res; - - if (lo < 0) { - PyErr_SetString(PyExc_ValueError, "lo must be non-negative"); - return -1; - } - if (hi == -1) { - hi = PySequence_Size(list); - if (hi < 0) - return -1; - } - while (lo < hi) { - /* The (size_t)cast ensures that the addition and subsequent division - are performed as unsigned operations, avoiding difficulties from - signed overflow. (See issue 13496.) */ - mid = ((size_t)lo + hi) / 2; - litem = PySequence_GetItem(list, mid); - if (litem == NULL) - return -1; - res = PyObject_RichCompareBool(item, litem, Py_LT); - Py_DECREF(litem); - if (res < 0) - return -1; - if (res) - hi = mid; - else - lo = mid + 1; - } - return lo; -} - +internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) +{ + PyObject *litem; + Py_ssize_t mid; + int res; + + if (lo < 0) { + PyErr_SetString(PyExc_ValueError, "lo must be non-negative"); + return -1; + } + if (hi == -1) { + hi = PySequence_Size(list); + if (hi < 0) + return -1; + } + while (lo < hi) { + /* The (size_t)cast ensures that the addition and subsequent division + are performed as unsigned operations, avoiding difficulties from + signed overflow. (See issue 13496.) */ + mid = ((size_t)lo + hi) / 2; + litem = PySequence_GetItem(list, mid); + if (litem == NULL) + return -1; + res = PyObject_RichCompareBool(item, litem, Py_LT); + Py_DECREF(litem); + if (res < 0) + return -1; + if (res) + hi = mid; + else + lo = mid + 1; + } + return lo; +} + /*[clinic input] _bisect.bisect_right -> Py_ssize_t @@ -73,13 +73,13 @@ static Py_ssize_t _bisect_bisect_right_impl(PyObject *module, PyObject *a, PyObject *x, Py_ssize_t lo, Py_ssize_t hi) /*[clinic end generated code: output=419e150cf1d2a235 input=e72212b282c83375]*/ -{ +{ return internal_bisect_right(a, x, lo, hi); -} - +} + /*[clinic input] _bisect.insort_right - + a: object x: object lo: Py_ssize_t = 0 @@ -93,65 +93,65 @@ Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. [clinic start generated code]*/ -static PyObject * +static PyObject * _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, Py_ssize_t lo, Py_ssize_t hi) /*[clinic end generated code: output=c2caa3d4cd02035a input=d1c45bfa68182669]*/ -{ +{ PyObject *result; Py_ssize_t index = internal_bisect_right(a, x, lo, hi); - if (index < 0) - return NULL; + if (index < 0) + return NULL; if (PyList_CheckExact(a)) { if (PyList_Insert(a, index, x) < 0) - return NULL; + return NULL; } else { result = _PyObject_CallMethodId(a, &PyId_insert, "nO", index, x); - if (result == NULL) - return NULL; - Py_DECREF(result); - } - - Py_RETURN_NONE; -} - + if (result == NULL) + return NULL; + Py_DECREF(result); + } + + Py_RETURN_NONE; +} + static inline Py_ssize_t -internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) -{ - PyObject *litem; - Py_ssize_t mid; - int res; - - if (lo < 0) { - PyErr_SetString(PyExc_ValueError, "lo must be non-negative"); - return -1; - } - if (hi == -1) { - hi = PySequence_Size(list); - if (hi < 0) - return -1; - } - while (lo < hi) { - /* The (size_t)cast ensures that the addition and subsequent division - are performed as unsigned operations, avoiding difficulties from - signed overflow. (See issue 13496.) */ - mid = ((size_t)lo + hi) / 2; - litem = PySequence_GetItem(list, mid); - if (litem == NULL) - return -1; - res = PyObject_RichCompareBool(litem, item, Py_LT); - Py_DECREF(litem); - if (res < 0) - return -1; - if (res) - lo = mid + 1; - else - hi = mid; - } - return lo; -} - +internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi) +{ + PyObject *litem; + Py_ssize_t mid; + int res; + + if (lo < 0) { + PyErr_SetString(PyExc_ValueError, "lo must be non-negative"); + return -1; + } + if (hi == -1) { + hi = PySequence_Size(list); + if (hi < 0) + return -1; + } + while (lo < hi) { + /* The (size_t)cast ensures that the addition and subsequent division + are performed as unsigned operations, avoiding difficulties from + signed overflow. (See issue 13496.) */ + mid = ((size_t)lo + hi) / 2; + litem = PySequence_GetItem(list, mid); + if (litem == NULL) + return -1; + res = PyObject_RichCompareBool(litem, item, Py_LT); + Py_DECREF(litem); + if (res < 0) + return -1; + if (res) + lo = mid + 1; + else + hi = mid; + } + return lo; +} + /*[clinic input] _bisect.bisect_left -> Py_ssize_t @@ -175,11 +175,11 @@ static Py_ssize_t _bisect_bisect_left_impl(PyObject *module, PyObject *a, PyObject *x, Py_ssize_t lo, Py_ssize_t hi) /*[clinic end generated code: output=af82168bc2856f24 input=2bd90f34afe5609f]*/ -{ +{ return internal_bisect_left(a, x, lo, hi); -} - - +} + + /*[clinic input] _bisect.insort_left @@ -196,59 +196,59 @@ Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. [clinic start generated code]*/ -static PyObject * +static PyObject * _bisect_insort_left_impl(PyObject *module, PyObject *a, PyObject *x, Py_ssize_t lo, Py_ssize_t hi) /*[clinic end generated code: output=9e8356c0844a182b input=bc4583308bce00cc]*/ -{ +{ PyObject *result; Py_ssize_t index = internal_bisect_left(a, x, lo, hi); - if (index < 0) - return NULL; + if (index < 0) + return NULL; if (PyList_CheckExact(a)) { if (PyList_Insert(a, index, x) < 0) - return NULL; - } else { + return NULL; + } else { result = _PyObject_CallMethodId(a, &PyId_insert, "nO", index, x); - if (result == NULL) - return NULL; - Py_DECREF(result); - } - - Py_RETURN_NONE; -} - -static PyMethodDef bisect_methods[] = { + if (result == NULL) + return NULL; + Py_DECREF(result); + } + + Py_RETURN_NONE; +} + +static PyMethodDef bisect_methods[] = { _BISECT_BISECT_RIGHT_METHODDEF _BISECT_INSORT_RIGHT_METHODDEF _BISECT_BISECT_LEFT_METHODDEF _BISECT_INSORT_LEFT_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(module_doc, -"Bisection algorithms.\n\ -\n\ -This module provides support for maintaining a list in sorted order without\n\ -having to sort the list after each insertion. For long lists of items with\n\ -expensive comparison operations, this can be an improvement over the more\n\ -common approach.\n"); - - -static struct PyModuleDef _bisectmodule = { - PyModuleDef_HEAD_INIT, - "_bisect", - module_doc, - -1, - bisect_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__bisect(void) -{ - return PyModule_Create(&_bisectmodule); -} + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(module_doc, +"Bisection algorithms.\n\ +\n\ +This module provides support for maintaining a list in sorted order without\n\ +having to sort the list after each insertion. For long lists of items with\n\ +expensive comparison operations, this can be an improvement over the more\n\ +common approach.\n"); + + +static struct PyModuleDef _bisectmodule = { + PyModuleDef_HEAD_INIT, + "_bisect", + module_doc, + -1, + bisect_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__bisect(void) +{ + return PyModule_Create(&_bisectmodule); +} diff --git a/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c b/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c index 7fb1296f8b2..69e136f4340 100644 --- a/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c +++ b/contrib/tools/python3/src/Modules/_blake2/blake2b_impl.c @@ -1,437 +1,437 @@ -/* - * Written in 2013 by Dmitry Chestnykh - * Modified for CPython by Christian Heimes - * - * To the extent possible under law, the author have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ - */ - -/* WARNING: autogenerated file! - * - * The blake2s_impl.c is autogenerated from blake2b_impl.c. - */ - -#include "Python.h" -#include "pystrhex.h" - -#include "../hashlib.h" -#include "blake2ns.h" - -#define HAVE_BLAKE2B 1 -#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) - -#include "impl/blake2.h" -#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ - -/* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+ - * https://bugs.python.org/issue31834 */ -#if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__) -#include "impl/blake2b.c" -#else -#include "impl/blake2b-ref.c" -#endif - - -extern PyTypeObject PyBlake2_BLAKE2bType; - -typedef struct { - PyObject_HEAD - blake2b_param param; - blake2b_state state; - PyThread_type_lock lock; -} BLAKE2bObject; - -#include "clinic/blake2b_impl.c.h" - -/*[clinic input] -module _blake2 -class _blake2.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d47b0527b39c673f]*/ - - -static BLAKE2bObject * -new_BLAKE2bObject(PyTypeObject *type) -{ - BLAKE2bObject *self; - self = (BLAKE2bObject *)type->tp_alloc(type, 0); - if (self != NULL) { - self->lock = NULL; - } - return self; -} - -/*[clinic input] -@classmethod -_blake2.blake2b.__new__ as py_blake2b_new - data: object(c_default="NULL") = b'' - / - * - digest_size: int(c_default="BLAKE2B_OUTBYTES") = _blake2.blake2b.MAX_DIGEST_SIZE - key: Py_buffer(c_default="NULL", py_default="b''") = None - salt: Py_buffer(c_default="NULL", py_default="b''") = None - person: Py_buffer(c_default="NULL", py_default="b''") = None - fanout: int = 1 - depth: int = 1 +/* + * Written in 2013 by Dmitry Chestnykh + * Modified for CPython by Christian Heimes + * + * To the extent possible under law, the author have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* WARNING: autogenerated file! + * + * The blake2s_impl.c is autogenerated from blake2b_impl.c. + */ + +#include "Python.h" +#include "pystrhex.h" + +#include "../hashlib.h" +#include "blake2ns.h" + +#define HAVE_BLAKE2B 1 +#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) + +#include "impl/blake2.h" +#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ + +/* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+ + * https://bugs.python.org/issue31834 */ +#if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__) +#include "impl/blake2b.c" +#else +#include "impl/blake2b-ref.c" +#endif + + +extern PyTypeObject PyBlake2_BLAKE2bType; + +typedef struct { + PyObject_HEAD + blake2b_param param; + blake2b_state state; + PyThread_type_lock lock; +} BLAKE2bObject; + +#include "clinic/blake2b_impl.c.h" + +/*[clinic input] +module _blake2 +class _blake2.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d47b0527b39c673f]*/ + + +static BLAKE2bObject * +new_BLAKE2bObject(PyTypeObject *type) +{ + BLAKE2bObject *self; + self = (BLAKE2bObject *)type->tp_alloc(type, 0); + if (self != NULL) { + self->lock = NULL; + } + return self; +} + +/*[clinic input] +@classmethod +_blake2.blake2b.__new__ as py_blake2b_new + data: object(c_default="NULL") = b'' + / + * + digest_size: int(c_default="BLAKE2B_OUTBYTES") = _blake2.blake2b.MAX_DIGEST_SIZE + key: Py_buffer(c_default="NULL", py_default="b''") = None + salt: Py_buffer(c_default="NULL", py_default="b''") = None + person: Py_buffer(c_default="NULL", py_default="b''") = None + fanout: int = 1 + depth: int = 1 leaf_size: unsigned_long = 0 node_offset: unsigned_long_long = 0 - node_depth: int = 0 - inner_size: int = 0 - last_node: bool = False + node_depth: int = 0 + inner_size: int = 0 + last_node: bool = False usedforsecurity: bool = True - -Return a new BLAKE2b hash object. -[clinic start generated code]*/ - -static PyObject * -py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, - Py_buffer *key, Py_buffer *salt, Py_buffer *person, + +Return a new BLAKE2b hash object. +[clinic start generated code]*/ + +static PyObject * +py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, int fanout, int depth, unsigned long leaf_size, unsigned long long node_offset, int node_depth, int inner_size, int last_node, int usedforsecurity) /*[clinic end generated code: output=32bfd8f043c6896f input=b947312abff46977]*/ -{ - BLAKE2bObject *self = NULL; - Py_buffer buf; - - self = new_BLAKE2bObject(type); - if (self == NULL) { - goto error; - } - - /* Zero parameter block. */ - memset(&self->param, 0, sizeof(self->param)); - - /* Set digest size. */ - if (digest_size <= 0 || digest_size > BLAKE2B_OUTBYTES) { - PyErr_Format(PyExc_ValueError, - "digest_size must be between 1 and %d bytes", - BLAKE2B_OUTBYTES); - goto error; - } - self->param.digest_length = digest_size; - - /* Set salt parameter. */ - if ((salt->obj != NULL) && salt->len) { - if (salt->len > BLAKE2B_SALTBYTES) { - PyErr_Format(PyExc_ValueError, - "maximum salt length is %d bytes", - BLAKE2B_SALTBYTES); - goto error; - } - memcpy(self->param.salt, salt->buf, salt->len); - } - - /* Set personalization parameter. */ - if ((person->obj != NULL) && person->len) { - if (person->len > BLAKE2B_PERSONALBYTES) { - PyErr_Format(PyExc_ValueError, - "maximum person length is %d bytes", - BLAKE2B_PERSONALBYTES); - goto error; - } - memcpy(self->param.personal, person->buf, person->len); - } - - /* Set tree parameters. */ - if (fanout < 0 || fanout > 255) { - PyErr_SetString(PyExc_ValueError, - "fanout must be between 0 and 255"); - goto error; - } - self->param.fanout = (uint8_t)fanout; - - if (depth <= 0 || depth > 255) { - PyErr_SetString(PyExc_ValueError, - "depth must be between 1 and 255"); - goto error; - } - self->param.depth = (uint8_t)depth; - +{ + BLAKE2bObject *self = NULL; + Py_buffer buf; + + self = new_BLAKE2bObject(type); + if (self == NULL) { + goto error; + } + + /* Zero parameter block. */ + memset(&self->param, 0, sizeof(self->param)); + + /* Set digest size. */ + if (digest_size <= 0 || digest_size > BLAKE2B_OUTBYTES) { + PyErr_Format(PyExc_ValueError, + "digest_size must be between 1 and %d bytes", + BLAKE2B_OUTBYTES); + goto error; + } + self->param.digest_length = digest_size; + + /* Set salt parameter. */ + if ((salt->obj != NULL) && salt->len) { + if (salt->len > BLAKE2B_SALTBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum salt length is %d bytes", + BLAKE2B_SALTBYTES); + goto error; + } + memcpy(self->param.salt, salt->buf, salt->len); + } + + /* Set personalization parameter. */ + if ((person->obj != NULL) && person->len) { + if (person->len > BLAKE2B_PERSONALBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum person length is %d bytes", + BLAKE2B_PERSONALBYTES); + goto error; + } + memcpy(self->param.personal, person->buf, person->len); + } + + /* Set tree parameters. */ + if (fanout < 0 || fanout > 255) { + PyErr_SetString(PyExc_ValueError, + "fanout must be between 0 and 255"); + goto error; + } + self->param.fanout = (uint8_t)fanout; + + if (depth <= 0 || depth > 255) { + PyErr_SetString(PyExc_ValueError, + "depth must be between 1 and 255"); + goto error; + } + self->param.depth = (uint8_t)depth; + if (leaf_size > 0xFFFFFFFFU) { PyErr_SetString(PyExc_OverflowError, "leaf_size is too large"); goto error; - } - // NB: Simple assignment here would be incorrect on big endian platforms. - store32(&(self->param.leaf_length), leaf_size); - -#ifdef HAVE_BLAKE2S - if (node_offset > 0xFFFFFFFFFFFFULL) { - /* maximum 2**48 - 1 */ - PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); - goto error; - } - store48(&(self->param.node_offset), node_offset); -#else - // NB: Simple assignment here would be incorrect on big endian platforms. - store64(&(self->param.node_offset), node_offset); -#endif - - if (node_depth < 0 || node_depth > 255) { - PyErr_SetString(PyExc_ValueError, - "node_depth must be between 0 and 255"); - goto error; - } - self->param.node_depth = node_depth; - - if (inner_size < 0 || inner_size > BLAKE2B_OUTBYTES) { - PyErr_Format(PyExc_ValueError, - "inner_size must be between 0 and is %d", - BLAKE2B_OUTBYTES); - goto error; - } - self->param.inner_length = inner_size; - - /* Set key length. */ - if ((key->obj != NULL) && key->len) { - if (key->len > BLAKE2B_KEYBYTES) { - PyErr_Format(PyExc_ValueError, - "maximum key length is %d bytes", - BLAKE2B_KEYBYTES); - goto error; - } - self->param.key_length = (uint8_t)key->len; - } - - /* Initialize hash state. */ - if (blake2b_init_param(&self->state, &self->param) < 0) { - PyErr_SetString(PyExc_RuntimeError, - "error initializing hash state"); - goto error; - } - - /* Set last node flag (must come after initialization). */ - self->state.last_node = last_node; - - /* Process key block if any. */ - if (self->param.key_length) { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset(block, 0, sizeof(block)); - memcpy(block, key->buf, key->len); - blake2b_update(&self->state, block, sizeof(block)); - secure_zero_memory(block, sizeof(block)); - } - - /* Process initial data if any. */ - if (data != NULL) { - GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); - - if (buf.len >= HASHLIB_GIL_MINSIZE) { - Py_BEGIN_ALLOW_THREADS - blake2b_update(&self->state, buf.buf, buf.len); - Py_END_ALLOW_THREADS - } else { - blake2b_update(&self->state, buf.buf, buf.len); - } - PyBuffer_Release(&buf); - } - - return (PyObject *)self; - - error: - if (self != NULL) { - Py_DECREF(self); - } - return NULL; -} - -/*[clinic input] -_blake2.blake2b.copy - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2b_copy_impl(BLAKE2bObject *self) -/*[clinic end generated code: output=ff6acee5f93656ae input=e383c2d199fd8a2e]*/ -{ - BLAKE2bObject *cpy; - - if ((cpy = new_BLAKE2bObject(Py_TYPE(self))) == NULL) - return NULL; - - ENTER_HASHLIB(self); - cpy->param = self->param; - cpy->state = self->state; - LEAVE_HASHLIB(self); - return (PyObject *)cpy; -} - -/*[clinic input] -_blake2.blake2b.update - - data: object - / - -Update this hash object's state with the provided bytes-like object. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2b_update(BLAKE2bObject *self, PyObject *data) -/*[clinic end generated code: output=010dfcbe22654359 input=ffc4aa6a6a225d31]*/ -{ - Py_buffer buf; - - GET_BUFFER_VIEW_OR_ERROUT(data, &buf); - - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) - self->lock = PyThread_allocate_lock(); - - if (self->lock != NULL) { - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); - blake2b_update(&self->state, buf.buf, buf.len); - PyThread_release_lock(self->lock); - Py_END_ALLOW_THREADS - } else { - blake2b_update(&self->state, buf.buf, buf.len); - } - PyBuffer_Release(&buf); - - Py_RETURN_NONE; -} - -/*[clinic input] -_blake2.blake2b.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2b_digest_impl(BLAKE2bObject *self) -/*[clinic end generated code: output=a5864660f4bfc61a input=7d21659e9c5fff02]*/ -{ - uint8_t digest[BLAKE2B_OUTBYTES]; - blake2b_state state_cpy; - - ENTER_HASHLIB(self); - state_cpy = self->state; - blake2b_final(&state_cpy, digest, self->param.digest_length); - LEAVE_HASHLIB(self); - return PyBytes_FromStringAndSize((const char *)digest, - self->param.digest_length); -} - -/*[clinic input] -_blake2.blake2b.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2b_hexdigest_impl(BLAKE2bObject *self) -/*[clinic end generated code: output=b5598a87d8794a60 input=76930f6946351f56]*/ -{ - uint8_t digest[BLAKE2B_OUTBYTES]; - blake2b_state state_cpy; - - ENTER_HASHLIB(self); - state_cpy = self->state; - blake2b_final(&state_cpy, digest, self->param.digest_length); - LEAVE_HASHLIB(self); - return _Py_strhex((const char *)digest, self->param.digest_length); -} - - -static PyMethodDef py_blake2b_methods[] = { - _BLAKE2_BLAKE2B_COPY_METHODDEF - _BLAKE2_BLAKE2B_DIGEST_METHODDEF - _BLAKE2_BLAKE2B_HEXDIGEST_METHODDEF - _BLAKE2_BLAKE2B_UPDATE_METHODDEF - {NULL, NULL} -}; - - - -static PyObject * -py_blake2b_get_name(BLAKE2bObject *self, void *closure) -{ - return PyUnicode_FromString("blake2b"); -} - - - -static PyObject * -py_blake2b_get_block_size(BLAKE2bObject *self, void *closure) -{ - return PyLong_FromLong(BLAKE2B_BLOCKBYTES); -} - - - -static PyObject * -py_blake2b_get_digest_size(BLAKE2bObject *self, void *closure) -{ - return PyLong_FromLong(self->param.digest_length); -} - - -static PyGetSetDef py_blake2b_getsetters[] = { - {"name", (getter)py_blake2b_get_name, - NULL, NULL, NULL}, - {"block_size", (getter)py_blake2b_get_block_size, - NULL, NULL, NULL}, - {"digest_size", (getter)py_blake2b_get_digest_size, - NULL, NULL, NULL}, - {NULL} -}; - - -static void -py_blake2b_dealloc(PyObject *self) -{ - BLAKE2bObject *obj = (BLAKE2bObject *)self; - - /* Try not to leave state in memory. */ - secure_zero_memory(&obj->param, sizeof(obj->param)); - secure_zero_memory(&obj->state, sizeof(obj->state)); - if (obj->lock) { - PyThread_free_lock(obj->lock); - obj->lock = NULL; - } - PyObject_Del(self); -} - - -PyTypeObject PyBlake2_BLAKE2bType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_blake2.blake2b", /* tp_name */ - sizeof(BLAKE2bObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - py_blake2b_dealloc, /* tp_dealloc */ + } + // NB: Simple assignment here would be incorrect on big endian platforms. + store32(&(self->param.leaf_length), leaf_size); + +#ifdef HAVE_BLAKE2S + if (node_offset > 0xFFFFFFFFFFFFULL) { + /* maximum 2**48 - 1 */ + PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); + goto error; + } + store48(&(self->param.node_offset), node_offset); +#else + // NB: Simple assignment here would be incorrect on big endian platforms. + store64(&(self->param.node_offset), node_offset); +#endif + + if (node_depth < 0 || node_depth > 255) { + PyErr_SetString(PyExc_ValueError, + "node_depth must be between 0 and 255"); + goto error; + } + self->param.node_depth = node_depth; + + if (inner_size < 0 || inner_size > BLAKE2B_OUTBYTES) { + PyErr_Format(PyExc_ValueError, + "inner_size must be between 0 and is %d", + BLAKE2B_OUTBYTES); + goto error; + } + self->param.inner_length = inner_size; + + /* Set key length. */ + if ((key->obj != NULL) && key->len) { + if (key->len > BLAKE2B_KEYBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum key length is %d bytes", + BLAKE2B_KEYBYTES); + goto error; + } + self->param.key_length = (uint8_t)key->len; + } + + /* Initialize hash state. */ + if (blake2b_init_param(&self->state, &self->param) < 0) { + PyErr_SetString(PyExc_RuntimeError, + "error initializing hash state"); + goto error; + } + + /* Set last node flag (must come after initialization). */ + self->state.last_node = last_node; + + /* Process key block if any. */ + if (self->param.key_length) { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, sizeof(block)); + memcpy(block, key->buf, key->len); + blake2b_update(&self->state, block, sizeof(block)); + secure_zero_memory(block, sizeof(block)); + } + + /* Process initial data if any. */ + if (data != NULL) { + GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); + + if (buf.len >= HASHLIB_GIL_MINSIZE) { + Py_BEGIN_ALLOW_THREADS + blake2b_update(&self->state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + blake2b_update(&self->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)self; + + error: + if (self != NULL) { + Py_DECREF(self); + } + return NULL; +} + +/*[clinic input] +_blake2.blake2b.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2b_copy_impl(BLAKE2bObject *self) +/*[clinic end generated code: output=ff6acee5f93656ae input=e383c2d199fd8a2e]*/ +{ + BLAKE2bObject *cpy; + + if ((cpy = new_BLAKE2bObject(Py_TYPE(self))) == NULL) + return NULL; + + ENTER_HASHLIB(self); + cpy->param = self->param; + cpy->state = self->state; + LEAVE_HASHLIB(self); + return (PyObject *)cpy; +} + +/*[clinic input] +_blake2.blake2b.update + + data: object + / + +Update this hash object's state with the provided bytes-like object. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2b_update(BLAKE2bObject *self, PyObject *data) +/*[clinic end generated code: output=010dfcbe22654359 input=ffc4aa6a6a225d31]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(data, &buf); + + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) + self->lock = PyThread_allocate_lock(); + + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + blake2b_update(&self->state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + blake2b_update(&self->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + + Py_RETURN_NONE; +} + +/*[clinic input] +_blake2.blake2b.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2b_digest_impl(BLAKE2bObject *self) +/*[clinic end generated code: output=a5864660f4bfc61a input=7d21659e9c5fff02]*/ +{ + uint8_t digest[BLAKE2B_OUTBYTES]; + blake2b_state state_cpy; + + ENTER_HASHLIB(self); + state_cpy = self->state; + blake2b_final(&state_cpy, digest, self->param.digest_length); + LEAVE_HASHLIB(self); + return PyBytes_FromStringAndSize((const char *)digest, + self->param.digest_length); +} + +/*[clinic input] +_blake2.blake2b.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2b_hexdigest_impl(BLAKE2bObject *self) +/*[clinic end generated code: output=b5598a87d8794a60 input=76930f6946351f56]*/ +{ + uint8_t digest[BLAKE2B_OUTBYTES]; + blake2b_state state_cpy; + + ENTER_HASHLIB(self); + state_cpy = self->state; + blake2b_final(&state_cpy, digest, self->param.digest_length); + LEAVE_HASHLIB(self); + return _Py_strhex((const char *)digest, self->param.digest_length); +} + + +static PyMethodDef py_blake2b_methods[] = { + _BLAKE2_BLAKE2B_COPY_METHODDEF + _BLAKE2_BLAKE2B_DIGEST_METHODDEF + _BLAKE2_BLAKE2B_HEXDIGEST_METHODDEF + _BLAKE2_BLAKE2B_UPDATE_METHODDEF + {NULL, NULL} +}; + + + +static PyObject * +py_blake2b_get_name(BLAKE2bObject *self, void *closure) +{ + return PyUnicode_FromString("blake2b"); +} + + + +static PyObject * +py_blake2b_get_block_size(BLAKE2bObject *self, void *closure) +{ + return PyLong_FromLong(BLAKE2B_BLOCKBYTES); +} + + + +static PyObject * +py_blake2b_get_digest_size(BLAKE2bObject *self, void *closure) +{ + return PyLong_FromLong(self->param.digest_length); +} + + +static PyGetSetDef py_blake2b_getsetters[] = { + {"name", (getter)py_blake2b_get_name, + NULL, NULL, NULL}, + {"block_size", (getter)py_blake2b_get_block_size, + NULL, NULL, NULL}, + {"digest_size", (getter)py_blake2b_get_digest_size, + NULL, NULL, NULL}, + {NULL} +}; + + +static void +py_blake2b_dealloc(PyObject *self) +{ + BLAKE2bObject *obj = (BLAKE2bObject *)self; + + /* Try not to leave state in memory. */ + secure_zero_memory(&obj->param, sizeof(obj->param)); + secure_zero_memory(&obj->state, sizeof(obj->state)); + if (obj->lock) { + PyThread_free_lock(obj->lock); + obj->lock = NULL; + } + PyObject_Del(self); +} + + +PyTypeObject PyBlake2_BLAKE2bType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_blake2.blake2b", /* tp_name */ + sizeof(BLAKE2bObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + py_blake2b_dealloc, /* tp_dealloc */ 0, /*tp_vectorcall_offset*/ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - py_blake2b_new__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - py_blake2b_methods, /* tp_methods */ - 0, /* tp_members */ - py_blake2b_getsetters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - py_blake2b_new, /* tp_new */ -}; + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + py_blake2b_new__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + py_blake2b_methods, /* tp_methods */ + 0, /* tp_members */ + py_blake2b_getsetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + py_blake2b_new, /* tp_new */ +}; diff --git a/contrib/tools/python3/src/Modules/_blake2/blake2module.c b/contrib/tools/python3/src/Modules/_blake2/blake2module.c index ff142c9f3ed..66d4d0b16ee 100644 --- a/contrib/tools/python3/src/Modules/_blake2/blake2module.c +++ b/contrib/tools/python3/src/Modules/_blake2/blake2module.c @@ -1,99 +1,99 @@ -/* - * Written in 2013 by Dmitry Chestnykh - * Modified for CPython by Christian Heimes - * - * To the extent possible under law, the author have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ - */ - -#include "Python.h" - -#include "impl/blake2.h" - -extern PyTypeObject PyBlake2_BLAKE2bType; -extern PyTypeObject PyBlake2_BLAKE2sType; - - -PyDoc_STRVAR(blake2mod__doc__, -"_blake2b provides BLAKE2b for hashlib\n" -); - - -static struct PyMethodDef blake2mod_functions[] = { - {NULL, NULL} -}; - -static struct PyModuleDef blake2_module = { - PyModuleDef_HEAD_INIT, - "_blake2", - blake2mod__doc__, - -1, - blake2mod_functions, - NULL, - NULL, - NULL, - NULL -}; - -#define ADD_INT(d, name, value) do { \ - PyObject *x = PyLong_FromLong(value); \ - if (!x) { \ - Py_DECREF(m); \ - return NULL; \ - } \ - if (PyDict_SetItemString(d, name, x) < 0) { \ - Py_DECREF(m); \ - return NULL; \ - } \ - Py_DECREF(x); \ -} while(0) - - -PyMODINIT_FUNC -PyInit__blake2(void) -{ - PyObject *m; - PyObject *d; - - m = PyModule_Create(&blake2_module); - if (m == NULL) - return NULL; - - /* BLAKE2b */ +/* + * Written in 2013 by Dmitry Chestnykh + * Modified for CPython by Christian Heimes + * + * To the extent possible under law, the author have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ + */ + +#include "Python.h" + +#include "impl/blake2.h" + +extern PyTypeObject PyBlake2_BLAKE2bType; +extern PyTypeObject PyBlake2_BLAKE2sType; + + +PyDoc_STRVAR(blake2mod__doc__, +"_blake2b provides BLAKE2b for hashlib\n" +); + + +static struct PyMethodDef blake2mod_functions[] = { + {NULL, NULL} +}; + +static struct PyModuleDef blake2_module = { + PyModuleDef_HEAD_INIT, + "_blake2", + blake2mod__doc__, + -1, + blake2mod_functions, + NULL, + NULL, + NULL, + NULL +}; + +#define ADD_INT(d, name, value) do { \ + PyObject *x = PyLong_FromLong(value); \ + if (!x) { \ + Py_DECREF(m); \ + return NULL; \ + } \ + if (PyDict_SetItemString(d, name, x) < 0) { \ + Py_DECREF(m); \ + return NULL; \ + } \ + Py_DECREF(x); \ +} while(0) + + +PyMODINIT_FUNC +PyInit__blake2(void) +{ + PyObject *m; + PyObject *d; + + m = PyModule_Create(&blake2_module); + if (m == NULL) + return NULL; + + /* BLAKE2b */ Py_SET_TYPE(&PyBlake2_BLAKE2bType, &PyType_Type); if (PyModule_AddType(m, &PyBlake2_BLAKE2bType) < 0) { - return NULL; - } - - d = PyBlake2_BLAKE2bType.tp_dict; - ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES); - ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES); - ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES); - ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); - - PyModule_AddIntConstant(m, "BLAKE2B_SALT_SIZE", BLAKE2B_SALTBYTES); - PyModule_AddIntConstant(m, "BLAKE2B_PERSON_SIZE", BLAKE2B_PERSONALBYTES); - PyModule_AddIntConstant(m, "BLAKE2B_MAX_KEY_SIZE", BLAKE2B_KEYBYTES); - PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); - - /* BLAKE2s */ + return NULL; + } + + d = PyBlake2_BLAKE2bType.tp_dict; + ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES); + ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES); + ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES); + ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); + + PyModule_AddIntConstant(m, "BLAKE2B_SALT_SIZE", BLAKE2B_SALTBYTES); + PyModule_AddIntConstant(m, "BLAKE2B_PERSON_SIZE", BLAKE2B_PERSONALBYTES); + PyModule_AddIntConstant(m, "BLAKE2B_MAX_KEY_SIZE", BLAKE2B_KEYBYTES); + PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); + + /* BLAKE2s */ Py_SET_TYPE(&PyBlake2_BLAKE2sType, &PyType_Type); if (PyModule_AddType(m, &PyBlake2_BLAKE2sType) < 0) { - return NULL; - } - - d = PyBlake2_BLAKE2sType.tp_dict; - ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES); - ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES); - ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES); - ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); - - PyModule_AddIntConstant(m, "BLAKE2S_SALT_SIZE", BLAKE2S_SALTBYTES); - PyModule_AddIntConstant(m, "BLAKE2S_PERSON_SIZE", BLAKE2S_PERSONALBYTES); - PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES); - PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); - - return m; -} + return NULL; + } + + d = PyBlake2_BLAKE2sType.tp_dict; + ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES); + ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES); + ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES); + ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); + + PyModule_AddIntConstant(m, "BLAKE2S_SALT_SIZE", BLAKE2S_SALTBYTES); + PyModule_AddIntConstant(m, "BLAKE2S_PERSON_SIZE", BLAKE2S_PERSONALBYTES); + PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES); + PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_blake2/blake2ns.h b/contrib/tools/python3/src/Modules/_blake2/blake2ns.h index 53bce8e0fcd..462d67b3411 100644 --- a/contrib/tools/python3/src/Modules/_blake2/blake2ns.h +++ b/contrib/tools/python3/src/Modules/_blake2/blake2ns.h @@ -1,32 +1,32 @@ -/* Prefix all public blake2 symbols with PyBlake2_ - */ - -#ifndef Py_BLAKE2_NS -#define Py_BLAKE2_NS - -#define blake2b PyBlake2_blake2b -#define blake2b_compress PyBlake2_blake2b_compress -#define blake2b_final PyBlake2_blake2b_final -#define blake2b_init PyBlake2_blake2b_init -#define blake2b_init_key PyBlake2_blake2b_init_key -#define blake2b_init_param PyBlake2_blake2b_init_param -#define blake2b_update PyBlake2_blake2b_update -#define blake2bp PyBlake2_blake2bp -#define blake2bp_final PyBlake2_blake2bp_final -#define blake2bp_init PyBlake2_blake2bp_init -#define blake2bp_init_key PyBlake2_blake2bp_init_key -#define blake2bp_update PyBlake2_blake2bp_update -#define blake2s PyBlake2_blake2s -#define blake2s_compress PyBlake2_blake2s_compress -#define blake2s_final PyBlake2_blake2s_final -#define blake2s_init PyBlake2_blake2s_init -#define blake2s_init_key PyBlake2_blake2s_init_key -#define blake2s_init_param PyBlake2_blake2s_init_param -#define blake2s_update PyBlake2_blake2s_update -#define blake2sp PyBlake2_blake2sp -#define blake2sp_final PyBlake2_blake2sp_final -#define blake2sp_init PyBlake2_blake2sp_init -#define blake2sp_init_key PyBlake2_blake2sp_init_key -#define blake2sp_update PyBlake2_blake2sp_update - -#endif /* Py_BLAKE2_NS */ +/* Prefix all public blake2 symbols with PyBlake2_ + */ + +#ifndef Py_BLAKE2_NS +#define Py_BLAKE2_NS + +#define blake2b PyBlake2_blake2b +#define blake2b_compress PyBlake2_blake2b_compress +#define blake2b_final PyBlake2_blake2b_final +#define blake2b_init PyBlake2_blake2b_init +#define blake2b_init_key PyBlake2_blake2b_init_key +#define blake2b_init_param PyBlake2_blake2b_init_param +#define blake2b_update PyBlake2_blake2b_update +#define blake2bp PyBlake2_blake2bp +#define blake2bp_final PyBlake2_blake2bp_final +#define blake2bp_init PyBlake2_blake2bp_init +#define blake2bp_init_key PyBlake2_blake2bp_init_key +#define blake2bp_update PyBlake2_blake2bp_update +#define blake2s PyBlake2_blake2s +#define blake2s_compress PyBlake2_blake2s_compress +#define blake2s_final PyBlake2_blake2s_final +#define blake2s_init PyBlake2_blake2s_init +#define blake2s_init_key PyBlake2_blake2s_init_key +#define blake2s_init_param PyBlake2_blake2s_init_param +#define blake2s_update PyBlake2_blake2s_update +#define blake2sp PyBlake2_blake2sp +#define blake2sp_final PyBlake2_blake2sp_final +#define blake2sp_init PyBlake2_blake2sp_init +#define blake2sp_init_key PyBlake2_blake2sp_init_key +#define blake2sp_update PyBlake2_blake2sp_update + +#endif /* Py_BLAKE2_NS */ diff --git a/contrib/tools/python3/src/Modules/_blake2/blake2s_impl.c b/contrib/tools/python3/src/Modules/_blake2/blake2s_impl.c index e3e90d0587b..e12089dcacf 100644 --- a/contrib/tools/python3/src/Modules/_blake2/blake2s_impl.c +++ b/contrib/tools/python3/src/Modules/_blake2/blake2s_impl.c @@ -1,437 +1,437 @@ -/* - * Written in 2013 by Dmitry Chestnykh - * Modified for CPython by Christian Heimes - * - * To the extent possible under law, the author have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ - */ - -/* WARNING: autogenerated file! - * - * The blake2s_impl.c is autogenerated from blake2s_impl.c. - */ - -#include "Python.h" -#include "pystrhex.h" - -#include "../hashlib.h" -#include "blake2ns.h" - -#define HAVE_BLAKE2S 1 -#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) - -#include "impl/blake2.h" -#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ - -/* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+ - * https://bugs.python.org/issue31834 */ -#if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__) -#include "impl/blake2s.c" -#else -#include "impl/blake2s-ref.c" -#endif - - -extern PyTypeObject PyBlake2_BLAKE2sType; - -typedef struct { - PyObject_HEAD - blake2s_param param; - blake2s_state state; - PyThread_type_lock lock; -} BLAKE2sObject; - -#include "clinic/blake2s_impl.c.h" - -/*[clinic input] -module _blake2 -class _blake2.blake2s "BLAKE2sObject *" "&PyBlake2_BLAKE2sType" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b79d7ffe07286ce]*/ - - -static BLAKE2sObject * -new_BLAKE2sObject(PyTypeObject *type) -{ - BLAKE2sObject *self; - self = (BLAKE2sObject *)type->tp_alloc(type, 0); - if (self != NULL) { - self->lock = NULL; - } - return self; -} - -/*[clinic input] -@classmethod -_blake2.blake2s.__new__ as py_blake2s_new - data: object(c_default="NULL") = b'' - / - * - digest_size: int(c_default="BLAKE2S_OUTBYTES") = _blake2.blake2s.MAX_DIGEST_SIZE - key: Py_buffer(c_default="NULL", py_default="b''") = None - salt: Py_buffer(c_default="NULL", py_default="b''") = None - person: Py_buffer(c_default="NULL", py_default="b''") = None - fanout: int = 1 - depth: int = 1 +/* + * Written in 2013 by Dmitry Chestnykh + * Modified for CPython by Christian Heimes + * + * To the extent possible under law, the author have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* WARNING: autogenerated file! + * + * The blake2s_impl.c is autogenerated from blake2s_impl.c. + */ + +#include "Python.h" +#include "pystrhex.h" + +#include "../hashlib.h" +#include "blake2ns.h" + +#define HAVE_BLAKE2S 1 +#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) + +#include "impl/blake2.h" +#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ + +/* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+ + * https://bugs.python.org/issue31834 */ +#if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__) +#include "impl/blake2s.c" +#else +#include "impl/blake2s-ref.c" +#endif + + +extern PyTypeObject PyBlake2_BLAKE2sType; + +typedef struct { + PyObject_HEAD + blake2s_param param; + blake2s_state state; + PyThread_type_lock lock; +} BLAKE2sObject; + +#include "clinic/blake2s_impl.c.h" + +/*[clinic input] +module _blake2 +class _blake2.blake2s "BLAKE2sObject *" "&PyBlake2_BLAKE2sType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b79d7ffe07286ce]*/ + + +static BLAKE2sObject * +new_BLAKE2sObject(PyTypeObject *type) +{ + BLAKE2sObject *self; + self = (BLAKE2sObject *)type->tp_alloc(type, 0); + if (self != NULL) { + self->lock = NULL; + } + return self; +} + +/*[clinic input] +@classmethod +_blake2.blake2s.__new__ as py_blake2s_new + data: object(c_default="NULL") = b'' + / + * + digest_size: int(c_default="BLAKE2S_OUTBYTES") = _blake2.blake2s.MAX_DIGEST_SIZE + key: Py_buffer(c_default="NULL", py_default="b''") = None + salt: Py_buffer(c_default="NULL", py_default="b''") = None + person: Py_buffer(c_default="NULL", py_default="b''") = None + fanout: int = 1 + depth: int = 1 leaf_size: unsigned_long = 0 node_offset: unsigned_long_long = 0 - node_depth: int = 0 - inner_size: int = 0 - last_node: bool = False + node_depth: int = 0 + inner_size: int = 0 + last_node: bool = False usedforsecurity: bool = True - -Return a new BLAKE2s hash object. -[clinic start generated code]*/ - -static PyObject * -py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, - Py_buffer *key, Py_buffer *salt, Py_buffer *person, + +Return a new BLAKE2s hash object. +[clinic start generated code]*/ + +static PyObject * +py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, int fanout, int depth, unsigned long leaf_size, unsigned long long node_offset, int node_depth, int inner_size, int last_node, int usedforsecurity) /*[clinic end generated code: output=556181f73905c686 input=4dda87723f23abb0]*/ -{ - BLAKE2sObject *self = NULL; - Py_buffer buf; - - self = new_BLAKE2sObject(type); - if (self == NULL) { - goto error; - } - - /* Zero parameter block. */ - memset(&self->param, 0, sizeof(self->param)); - - /* Set digest size. */ - if (digest_size <= 0 || digest_size > BLAKE2S_OUTBYTES) { - PyErr_Format(PyExc_ValueError, - "digest_size must be between 1 and %d bytes", - BLAKE2S_OUTBYTES); - goto error; - } - self->param.digest_length = digest_size; - - /* Set salt parameter. */ - if ((salt->obj != NULL) && salt->len) { - if (salt->len > BLAKE2S_SALTBYTES) { - PyErr_Format(PyExc_ValueError, - "maximum salt length is %d bytes", - BLAKE2S_SALTBYTES); - goto error; - } - memcpy(self->param.salt, salt->buf, salt->len); - } - - /* Set personalization parameter. */ - if ((person->obj != NULL) && person->len) { - if (person->len > BLAKE2S_PERSONALBYTES) { - PyErr_Format(PyExc_ValueError, - "maximum person length is %d bytes", - BLAKE2S_PERSONALBYTES); - goto error; - } - memcpy(self->param.personal, person->buf, person->len); - } - - /* Set tree parameters. */ - if (fanout < 0 || fanout > 255) { - PyErr_SetString(PyExc_ValueError, - "fanout must be between 0 and 255"); - goto error; - } - self->param.fanout = (uint8_t)fanout; - - if (depth <= 0 || depth > 255) { - PyErr_SetString(PyExc_ValueError, - "depth must be between 1 and 255"); - goto error; - } - self->param.depth = (uint8_t)depth; - +{ + BLAKE2sObject *self = NULL; + Py_buffer buf; + + self = new_BLAKE2sObject(type); + if (self == NULL) { + goto error; + } + + /* Zero parameter block. */ + memset(&self->param, 0, sizeof(self->param)); + + /* Set digest size. */ + if (digest_size <= 0 || digest_size > BLAKE2S_OUTBYTES) { + PyErr_Format(PyExc_ValueError, + "digest_size must be between 1 and %d bytes", + BLAKE2S_OUTBYTES); + goto error; + } + self->param.digest_length = digest_size; + + /* Set salt parameter. */ + if ((salt->obj != NULL) && salt->len) { + if (salt->len > BLAKE2S_SALTBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum salt length is %d bytes", + BLAKE2S_SALTBYTES); + goto error; + } + memcpy(self->param.salt, salt->buf, salt->len); + } + + /* Set personalization parameter. */ + if ((person->obj != NULL) && person->len) { + if (person->len > BLAKE2S_PERSONALBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum person length is %d bytes", + BLAKE2S_PERSONALBYTES); + goto error; + } + memcpy(self->param.personal, person->buf, person->len); + } + + /* Set tree parameters. */ + if (fanout < 0 || fanout > 255) { + PyErr_SetString(PyExc_ValueError, + "fanout must be between 0 and 255"); + goto error; + } + self->param.fanout = (uint8_t)fanout; + + if (depth <= 0 || depth > 255) { + PyErr_SetString(PyExc_ValueError, + "depth must be between 1 and 255"); + goto error; + } + self->param.depth = (uint8_t)depth; + if (leaf_size > 0xFFFFFFFFU) { PyErr_SetString(PyExc_OverflowError, "leaf_size is too large"); goto error; - } - // NB: Simple assignment here would be incorrect on big endian platforms. - store32(&(self->param.leaf_length), leaf_size); - -#ifdef HAVE_BLAKE2S - if (node_offset > 0xFFFFFFFFFFFFULL) { - /* maximum 2**48 - 1 */ - PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); - goto error; - } - store48(&(self->param.node_offset), node_offset); -#else - // NB: Simple assignment here would be incorrect on big endian platforms. - store64(&(self->param.node_offset), node_offset); -#endif - - if (node_depth < 0 || node_depth > 255) { - PyErr_SetString(PyExc_ValueError, - "node_depth must be between 0 and 255"); - goto error; - } - self->param.node_depth = node_depth; - - if (inner_size < 0 || inner_size > BLAKE2S_OUTBYTES) { - PyErr_Format(PyExc_ValueError, - "inner_size must be between 0 and is %d", - BLAKE2S_OUTBYTES); - goto error; - } - self->param.inner_length = inner_size; - - /* Set key length. */ - if ((key->obj != NULL) && key->len) { - if (key->len > BLAKE2S_KEYBYTES) { - PyErr_Format(PyExc_ValueError, - "maximum key length is %d bytes", - BLAKE2S_KEYBYTES); - goto error; - } - self->param.key_length = (uint8_t)key->len; - } - - /* Initialize hash state. */ - if (blake2s_init_param(&self->state, &self->param) < 0) { - PyErr_SetString(PyExc_RuntimeError, - "error initializing hash state"); - goto error; - } - - /* Set last node flag (must come after initialization). */ - self->state.last_node = last_node; - - /* Process key block if any. */ - if (self->param.key_length) { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset(block, 0, sizeof(block)); - memcpy(block, key->buf, key->len); - blake2s_update(&self->state, block, sizeof(block)); - secure_zero_memory(block, sizeof(block)); - } - - /* Process initial data if any. */ - if (data != NULL) { - GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); - - if (buf.len >= HASHLIB_GIL_MINSIZE) { - Py_BEGIN_ALLOW_THREADS - blake2s_update(&self->state, buf.buf, buf.len); - Py_END_ALLOW_THREADS - } else { - blake2s_update(&self->state, buf.buf, buf.len); - } - PyBuffer_Release(&buf); - } - - return (PyObject *)self; - - error: - if (self != NULL) { - Py_DECREF(self); - } - return NULL; -} - -/*[clinic input] -_blake2.blake2s.copy - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2s_copy_impl(BLAKE2sObject *self) -/*[clinic end generated code: output=5b90131c4eae275e input=0b9d44942f0fe4b2]*/ -{ - BLAKE2sObject *cpy; - - if ((cpy = new_BLAKE2sObject(Py_TYPE(self))) == NULL) - return NULL; - - ENTER_HASHLIB(self); - cpy->param = self->param; - cpy->state = self->state; - LEAVE_HASHLIB(self); - return (PyObject *)cpy; -} - -/*[clinic input] -_blake2.blake2s.update - - data: object - / - -Update this hash object's state with the provided bytes-like object. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2s_update(BLAKE2sObject *self, PyObject *data) -/*[clinic end generated code: output=757dc087fec37815 input=97500db2f9de4aaa]*/ -{ - Py_buffer buf; - - GET_BUFFER_VIEW_OR_ERROUT(data, &buf); - - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) - self->lock = PyThread_allocate_lock(); - - if (self->lock != NULL) { - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); - blake2s_update(&self->state, buf.buf, buf.len); - PyThread_release_lock(self->lock); - Py_END_ALLOW_THREADS - } else { - blake2s_update(&self->state, buf.buf, buf.len); - } - PyBuffer_Release(&buf); - - Py_RETURN_NONE; -} - -/*[clinic input] -_blake2.blake2s.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2s_digest_impl(BLAKE2sObject *self) -/*[clinic end generated code: output=40c566ca4bc6bc51 input=f41e0b8d6d937454]*/ -{ - uint8_t digest[BLAKE2S_OUTBYTES]; - blake2s_state state_cpy; - - ENTER_HASHLIB(self); - state_cpy = self->state; - blake2s_final(&state_cpy, digest, self->param.digest_length); - LEAVE_HASHLIB(self); - return PyBytes_FromStringAndSize((const char *)digest, - self->param.digest_length); -} - -/*[clinic input] -_blake2.blake2s.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -_blake2_blake2s_hexdigest_impl(BLAKE2sObject *self) -/*[clinic end generated code: output=15153eb5e59c52eb input=c77a1321567e8952]*/ -{ - uint8_t digest[BLAKE2S_OUTBYTES]; - blake2s_state state_cpy; - - ENTER_HASHLIB(self); - state_cpy = self->state; - blake2s_final(&state_cpy, digest, self->param.digest_length); - LEAVE_HASHLIB(self); - return _Py_strhex((const char *)digest, self->param.digest_length); -} - - -static PyMethodDef py_blake2s_methods[] = { - _BLAKE2_BLAKE2S_COPY_METHODDEF - _BLAKE2_BLAKE2S_DIGEST_METHODDEF - _BLAKE2_BLAKE2S_HEXDIGEST_METHODDEF - _BLAKE2_BLAKE2S_UPDATE_METHODDEF - {NULL, NULL} -}; - - - -static PyObject * -py_blake2s_get_name(BLAKE2sObject *self, void *closure) -{ - return PyUnicode_FromString("blake2s"); -} - - - -static PyObject * -py_blake2s_get_block_size(BLAKE2sObject *self, void *closure) -{ - return PyLong_FromLong(BLAKE2S_BLOCKBYTES); -} - - - -static PyObject * -py_blake2s_get_digest_size(BLAKE2sObject *self, void *closure) -{ - return PyLong_FromLong(self->param.digest_length); -} - - -static PyGetSetDef py_blake2s_getsetters[] = { - {"name", (getter)py_blake2s_get_name, - NULL, NULL, NULL}, - {"block_size", (getter)py_blake2s_get_block_size, - NULL, NULL, NULL}, - {"digest_size", (getter)py_blake2s_get_digest_size, - NULL, NULL, NULL}, - {NULL} -}; - - -static void -py_blake2s_dealloc(PyObject *self) -{ - BLAKE2sObject *obj = (BLAKE2sObject *)self; - - /* Try not to leave state in memory. */ - secure_zero_memory(&obj->param, sizeof(obj->param)); - secure_zero_memory(&obj->state, sizeof(obj->state)); - if (obj->lock) { - PyThread_free_lock(obj->lock); - obj->lock = NULL; - } - PyObject_Del(self); -} - - -PyTypeObject PyBlake2_BLAKE2sType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_blake2.blake2s", /* tp_name */ - sizeof(BLAKE2sObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - py_blake2s_dealloc, /* tp_dealloc */ + } + // NB: Simple assignment here would be incorrect on big endian platforms. + store32(&(self->param.leaf_length), leaf_size); + +#ifdef HAVE_BLAKE2S + if (node_offset > 0xFFFFFFFFFFFFULL) { + /* maximum 2**48 - 1 */ + PyErr_SetString(PyExc_OverflowError, "node_offset is too large"); + goto error; + } + store48(&(self->param.node_offset), node_offset); +#else + // NB: Simple assignment here would be incorrect on big endian platforms. + store64(&(self->param.node_offset), node_offset); +#endif + + if (node_depth < 0 || node_depth > 255) { + PyErr_SetString(PyExc_ValueError, + "node_depth must be between 0 and 255"); + goto error; + } + self->param.node_depth = node_depth; + + if (inner_size < 0 || inner_size > BLAKE2S_OUTBYTES) { + PyErr_Format(PyExc_ValueError, + "inner_size must be between 0 and is %d", + BLAKE2S_OUTBYTES); + goto error; + } + self->param.inner_length = inner_size; + + /* Set key length. */ + if ((key->obj != NULL) && key->len) { + if (key->len > BLAKE2S_KEYBYTES) { + PyErr_Format(PyExc_ValueError, + "maximum key length is %d bytes", + BLAKE2S_KEYBYTES); + goto error; + } + self->param.key_length = (uint8_t)key->len; + } + + /* Initialize hash state. */ + if (blake2s_init_param(&self->state, &self->param) < 0) { + PyErr_SetString(PyExc_RuntimeError, + "error initializing hash state"); + goto error; + } + + /* Set last node flag (must come after initialization). */ + self->state.last_node = last_node; + + /* Process key block if any. */ + if (self->param.key_length) { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset(block, 0, sizeof(block)); + memcpy(block, key->buf, key->len); + blake2s_update(&self->state, block, sizeof(block)); + secure_zero_memory(block, sizeof(block)); + } + + /* Process initial data if any. */ + if (data != NULL) { + GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); + + if (buf.len >= HASHLIB_GIL_MINSIZE) { + Py_BEGIN_ALLOW_THREADS + blake2s_update(&self->state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + blake2s_update(&self->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)self; + + error: + if (self != NULL) { + Py_DECREF(self); + } + return NULL; +} + +/*[clinic input] +_blake2.blake2s.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2s_copy_impl(BLAKE2sObject *self) +/*[clinic end generated code: output=5b90131c4eae275e input=0b9d44942f0fe4b2]*/ +{ + BLAKE2sObject *cpy; + + if ((cpy = new_BLAKE2sObject(Py_TYPE(self))) == NULL) + return NULL; + + ENTER_HASHLIB(self); + cpy->param = self->param; + cpy->state = self->state; + LEAVE_HASHLIB(self); + return (PyObject *)cpy; +} + +/*[clinic input] +_blake2.blake2s.update + + data: object + / + +Update this hash object's state with the provided bytes-like object. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2s_update(BLAKE2sObject *self, PyObject *data) +/*[clinic end generated code: output=757dc087fec37815 input=97500db2f9de4aaa]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(data, &buf); + + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) + self->lock = PyThread_allocate_lock(); + + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + blake2s_update(&self->state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + blake2s_update(&self->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + + Py_RETURN_NONE; +} + +/*[clinic input] +_blake2.blake2s.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2s_digest_impl(BLAKE2sObject *self) +/*[clinic end generated code: output=40c566ca4bc6bc51 input=f41e0b8d6d937454]*/ +{ + uint8_t digest[BLAKE2S_OUTBYTES]; + blake2s_state state_cpy; + + ENTER_HASHLIB(self); + state_cpy = self->state; + blake2s_final(&state_cpy, digest, self->param.digest_length); + LEAVE_HASHLIB(self); + return PyBytes_FromStringAndSize((const char *)digest, + self->param.digest_length); +} + +/*[clinic input] +_blake2.blake2s.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +_blake2_blake2s_hexdigest_impl(BLAKE2sObject *self) +/*[clinic end generated code: output=15153eb5e59c52eb input=c77a1321567e8952]*/ +{ + uint8_t digest[BLAKE2S_OUTBYTES]; + blake2s_state state_cpy; + + ENTER_HASHLIB(self); + state_cpy = self->state; + blake2s_final(&state_cpy, digest, self->param.digest_length); + LEAVE_HASHLIB(self); + return _Py_strhex((const char *)digest, self->param.digest_length); +} + + +static PyMethodDef py_blake2s_methods[] = { + _BLAKE2_BLAKE2S_COPY_METHODDEF + _BLAKE2_BLAKE2S_DIGEST_METHODDEF + _BLAKE2_BLAKE2S_HEXDIGEST_METHODDEF + _BLAKE2_BLAKE2S_UPDATE_METHODDEF + {NULL, NULL} +}; + + + +static PyObject * +py_blake2s_get_name(BLAKE2sObject *self, void *closure) +{ + return PyUnicode_FromString("blake2s"); +} + + + +static PyObject * +py_blake2s_get_block_size(BLAKE2sObject *self, void *closure) +{ + return PyLong_FromLong(BLAKE2S_BLOCKBYTES); +} + + + +static PyObject * +py_blake2s_get_digest_size(BLAKE2sObject *self, void *closure) +{ + return PyLong_FromLong(self->param.digest_length); +} + + +static PyGetSetDef py_blake2s_getsetters[] = { + {"name", (getter)py_blake2s_get_name, + NULL, NULL, NULL}, + {"block_size", (getter)py_blake2s_get_block_size, + NULL, NULL, NULL}, + {"digest_size", (getter)py_blake2s_get_digest_size, + NULL, NULL, NULL}, + {NULL} +}; + + +static void +py_blake2s_dealloc(PyObject *self) +{ + BLAKE2sObject *obj = (BLAKE2sObject *)self; + + /* Try not to leave state in memory. */ + secure_zero_memory(&obj->param, sizeof(obj->param)); + secure_zero_memory(&obj->state, sizeof(obj->state)); + if (obj->lock) { + PyThread_free_lock(obj->lock); + obj->lock = NULL; + } + PyObject_Del(self); +} + + +PyTypeObject PyBlake2_BLAKE2sType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_blake2.blake2s", /* tp_name */ + sizeof(BLAKE2sObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + py_blake2s_dealloc, /* tp_dealloc */ 0, /*tp_vectorcall_offset*/ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - py_blake2s_new__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - py_blake2s_methods, /* tp_methods */ - 0, /* tp_members */ - py_blake2s_getsetters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - py_blake2s_new, /* tp_new */ -}; + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + py_blake2s_new__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + py_blake2s_methods, /* tp_methods */ + 0, /* tp_members */ + py_blake2s_getsetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + py_blake2s_new, /* tp_new */ +}; diff --git a/contrib/tools/python3/src/Modules/_blake2/clinic/blake2b_impl.c.h b/contrib/tools/python3/src/Modules/_blake2/clinic/blake2b_impl.c.h index 07258c31c9b..0133a5e3d45 100644 --- a/contrib/tools/python3/src/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/contrib/tools/python3/src/Modules/_blake2/clinic/blake2b_impl.c.h @@ -1,51 +1,51 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(py_blake2b_new__doc__, -"blake2b(data=b\'\', /, *, digest_size=_blake2.blake2b.MAX_DIGEST_SIZE,\n" -" key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(py_blake2b_new__doc__, +"blake2b(data=b\'\', /, *, digest_size=_blake2.blake2b.MAX_DIGEST_SIZE,\n" +" key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" " node_offset=0, node_depth=0, inner_size=0, last_node=False,\n" " usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new BLAKE2b hash object."); - -static PyObject * -py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, - Py_buffer *key, Py_buffer *salt, Py_buffer *person, +"--\n" +"\n" +"Return a new BLAKE2b hash object."); + +static PyObject * +py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, int fanout, int depth, unsigned long leaf_size, unsigned long long node_offset, int node_depth, int inner_size, int last_node, int usedforsecurity); - -static PyObject * -py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; + +static PyObject * +py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "blake2b", 0}; PyObject *argsbuf[13]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *data = NULL; - int digest_size = BLAKE2B_OUTBYTES; - Py_buffer key = {NULL, NULL}; - Py_buffer salt = {NULL, NULL}; - Py_buffer person = {NULL, NULL}; - int fanout = 1; - int depth = 1; + PyObject *data = NULL; + int digest_size = BLAKE2B_OUTBYTES; + Py_buffer key = {NULL, NULL}; + Py_buffer salt = {NULL, NULL}; + Py_buffer person = {NULL, NULL}; + int fanout = 1; + int depth = 1; unsigned long leaf_size = 0; unsigned long long node_offset = 0; - int node_depth = 0; - int inner_size = 0; - int last_node = 0; + int node_depth = 0; + int inner_size = 0; + int last_node = 0; int usedforsecurity = 1; - + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional_posonly; } @@ -192,84 +192,84 @@ skip_optional_posonly: } skip_optional_kwonly: return_value = py_blake2b_new_impl(type, data, digest_size, &key, &salt, &person, fanout, depth, leaf_size, node_offset, node_depth, inner_size, last_node, usedforsecurity); - -exit: - /* Cleanup for key */ - if (key.obj) { - PyBuffer_Release(&key); - } - /* Cleanup for salt */ - if (salt.obj) { - PyBuffer_Release(&salt); - } - /* Cleanup for person */ - if (person.obj) { - PyBuffer_Release(&person); - } - - return return_value; -} - -PyDoc_STRVAR(_blake2_blake2b_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define _BLAKE2_BLAKE2B_COPY_METHODDEF \ - {"copy", (PyCFunction)_blake2_blake2b_copy, METH_NOARGS, _blake2_blake2b_copy__doc__}, - -static PyObject * -_blake2_blake2b_copy_impl(BLAKE2bObject *self); - -static PyObject * -_blake2_blake2b_copy(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _blake2_blake2b_copy_impl(self); -} - -PyDoc_STRVAR(_blake2_blake2b_update__doc__, -"update($self, data, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided bytes-like object."); - -#define _BLAKE2_BLAKE2B_UPDATE_METHODDEF \ - {"update", (PyCFunction)_blake2_blake2b_update, METH_O, _blake2_blake2b_update__doc__}, - -PyDoc_STRVAR(_blake2_blake2b_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define _BLAKE2_BLAKE2B_DIGEST_METHODDEF \ - {"digest", (PyCFunction)_blake2_blake2b_digest, METH_NOARGS, _blake2_blake2b_digest__doc__}, - -static PyObject * -_blake2_blake2b_digest_impl(BLAKE2bObject *self); - -static PyObject * -_blake2_blake2b_digest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _blake2_blake2b_digest_impl(self); -} - -PyDoc_STRVAR(_blake2_blake2b_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define _BLAKE2_BLAKE2B_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)_blake2_blake2b_hexdigest, METH_NOARGS, _blake2_blake2b_hexdigest__doc__}, - -static PyObject * -_blake2_blake2b_hexdigest_impl(BLAKE2bObject *self); - -static PyObject * -_blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _blake2_blake2b_hexdigest_impl(self); -} + +exit: + /* Cleanup for key */ + if (key.obj) { + PyBuffer_Release(&key); + } + /* Cleanup for salt */ + if (salt.obj) { + PyBuffer_Release(&salt); + } + /* Cleanup for person */ + if (person.obj) { + PyBuffer_Release(&person); + } + + return return_value; +} + +PyDoc_STRVAR(_blake2_blake2b_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define _BLAKE2_BLAKE2B_COPY_METHODDEF \ + {"copy", (PyCFunction)_blake2_blake2b_copy, METH_NOARGS, _blake2_blake2b_copy__doc__}, + +static PyObject * +_blake2_blake2b_copy_impl(BLAKE2bObject *self); + +static PyObject * +_blake2_blake2b_copy(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2_blake2b_copy_impl(self); +} + +PyDoc_STRVAR(_blake2_blake2b_update__doc__, +"update($self, data, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided bytes-like object."); + +#define _BLAKE2_BLAKE2B_UPDATE_METHODDEF \ + {"update", (PyCFunction)_blake2_blake2b_update, METH_O, _blake2_blake2b_update__doc__}, + +PyDoc_STRVAR(_blake2_blake2b_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define _BLAKE2_BLAKE2B_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_blake2_blake2b_digest, METH_NOARGS, _blake2_blake2b_digest__doc__}, + +static PyObject * +_blake2_blake2b_digest_impl(BLAKE2bObject *self); + +static PyObject * +_blake2_blake2b_digest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2_blake2b_digest_impl(self); +} + +PyDoc_STRVAR(_blake2_blake2b_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define _BLAKE2_BLAKE2B_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_blake2_blake2b_hexdigest, METH_NOARGS, _blake2_blake2b_hexdigest__doc__}, + +static PyObject * +_blake2_blake2b_hexdigest_impl(BLAKE2bObject *self); + +static PyObject * +_blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2_blake2b_hexdigest_impl(self); +} /*[clinic end generated code: output=2d6d0fe9aa42a42a input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_blake2/clinic/blake2s_impl.c.h b/contrib/tools/python3/src/Modules/_blake2/clinic/blake2s_impl.c.h index 71c5706fb66..9e122fe6388 100644 --- a/contrib/tools/python3/src/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/contrib/tools/python3/src/Modules/_blake2/clinic/blake2s_impl.c.h @@ -1,51 +1,51 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(py_blake2s_new__doc__, -"blake2s(data=b\'\', /, *, digest_size=_blake2.blake2s.MAX_DIGEST_SIZE,\n" -" key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(py_blake2s_new__doc__, +"blake2s(data=b\'\', /, *, digest_size=_blake2.blake2s.MAX_DIGEST_SIZE,\n" +" key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" " node_offset=0, node_depth=0, inner_size=0, last_node=False,\n" " usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new BLAKE2s hash object."); - -static PyObject * -py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, - Py_buffer *key, Py_buffer *salt, Py_buffer *person, +"--\n" +"\n" +"Return a new BLAKE2s hash object."); + +static PyObject * +py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, + Py_buffer *key, Py_buffer *salt, Py_buffer *person, int fanout, int depth, unsigned long leaf_size, unsigned long long node_offset, int node_depth, int inner_size, int last_node, int usedforsecurity); - -static PyObject * -py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; + +static PyObject * +py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "blake2s", 0}; PyObject *argsbuf[13]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *data = NULL; - int digest_size = BLAKE2S_OUTBYTES; - Py_buffer key = {NULL, NULL}; - Py_buffer salt = {NULL, NULL}; - Py_buffer person = {NULL, NULL}; - int fanout = 1; - int depth = 1; + PyObject *data = NULL; + int digest_size = BLAKE2S_OUTBYTES; + Py_buffer key = {NULL, NULL}; + Py_buffer salt = {NULL, NULL}; + Py_buffer person = {NULL, NULL}; + int fanout = 1; + int depth = 1; unsigned long leaf_size = 0; unsigned long long node_offset = 0; - int node_depth = 0; - int inner_size = 0; - int last_node = 0; + int node_depth = 0; + int inner_size = 0; + int last_node = 0; int usedforsecurity = 1; - + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional_posonly; } @@ -192,84 +192,84 @@ skip_optional_posonly: } skip_optional_kwonly: return_value = py_blake2s_new_impl(type, data, digest_size, &key, &salt, &person, fanout, depth, leaf_size, node_offset, node_depth, inner_size, last_node, usedforsecurity); - -exit: - /* Cleanup for key */ - if (key.obj) { - PyBuffer_Release(&key); - } - /* Cleanup for salt */ - if (salt.obj) { - PyBuffer_Release(&salt); - } - /* Cleanup for person */ - if (person.obj) { - PyBuffer_Release(&person); - } - - return return_value; -} - -PyDoc_STRVAR(_blake2_blake2s_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define _BLAKE2_BLAKE2S_COPY_METHODDEF \ - {"copy", (PyCFunction)_blake2_blake2s_copy, METH_NOARGS, _blake2_blake2s_copy__doc__}, - -static PyObject * -_blake2_blake2s_copy_impl(BLAKE2sObject *self); - -static PyObject * -_blake2_blake2s_copy(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _blake2_blake2s_copy_impl(self); -} - -PyDoc_STRVAR(_blake2_blake2s_update__doc__, -"update($self, data, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided bytes-like object."); - -#define _BLAKE2_BLAKE2S_UPDATE_METHODDEF \ - {"update", (PyCFunction)_blake2_blake2s_update, METH_O, _blake2_blake2s_update__doc__}, - -PyDoc_STRVAR(_blake2_blake2s_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define _BLAKE2_BLAKE2S_DIGEST_METHODDEF \ - {"digest", (PyCFunction)_blake2_blake2s_digest, METH_NOARGS, _blake2_blake2s_digest__doc__}, - -static PyObject * -_blake2_blake2s_digest_impl(BLAKE2sObject *self); - -static PyObject * -_blake2_blake2s_digest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _blake2_blake2s_digest_impl(self); -} - -PyDoc_STRVAR(_blake2_blake2s_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define _BLAKE2_BLAKE2S_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)_blake2_blake2s_hexdigest, METH_NOARGS, _blake2_blake2s_hexdigest__doc__}, - -static PyObject * -_blake2_blake2s_hexdigest_impl(BLAKE2sObject *self); - -static PyObject * -_blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _blake2_blake2s_hexdigest_impl(self); -} + +exit: + /* Cleanup for key */ + if (key.obj) { + PyBuffer_Release(&key); + } + /* Cleanup for salt */ + if (salt.obj) { + PyBuffer_Release(&salt); + } + /* Cleanup for person */ + if (person.obj) { + PyBuffer_Release(&person); + } + + return return_value; +} + +PyDoc_STRVAR(_blake2_blake2s_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define _BLAKE2_BLAKE2S_COPY_METHODDEF \ + {"copy", (PyCFunction)_blake2_blake2s_copy, METH_NOARGS, _blake2_blake2s_copy__doc__}, + +static PyObject * +_blake2_blake2s_copy_impl(BLAKE2sObject *self); + +static PyObject * +_blake2_blake2s_copy(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2_blake2s_copy_impl(self); +} + +PyDoc_STRVAR(_blake2_blake2s_update__doc__, +"update($self, data, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided bytes-like object."); + +#define _BLAKE2_BLAKE2S_UPDATE_METHODDEF \ + {"update", (PyCFunction)_blake2_blake2s_update, METH_O, _blake2_blake2s_update__doc__}, + +PyDoc_STRVAR(_blake2_blake2s_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define _BLAKE2_BLAKE2S_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_blake2_blake2s_digest, METH_NOARGS, _blake2_blake2s_digest__doc__}, + +static PyObject * +_blake2_blake2s_digest_impl(BLAKE2sObject *self); + +static PyObject * +_blake2_blake2s_digest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2_blake2s_digest_impl(self); +} + +PyDoc_STRVAR(_blake2_blake2s_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define _BLAKE2_BLAKE2S_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_blake2_blake2s_hexdigest, METH_NOARGS, _blake2_blake2s_hexdigest__doc__}, + +static PyObject * +_blake2_blake2s_hexdigest_impl(BLAKE2sObject *self); + +static PyObject * +_blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _blake2_blake2s_hexdigest_impl(self); +} /*[clinic end generated code: output=c80d8d06ce40a192 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2-config.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2-config.h index f5dd6faa9e6..1af4a479665 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2-config.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2-config.h @@ -1,71 +1,71 @@ -/* - BLAKE2 reference source code package - optimized C implementations - +/* + BLAKE2 reference source code package - optimized C implementations + Written in 2012 by Samuel Neves - + To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. - + You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2_CONFIG_H__ -#define __BLAKE2_CONFIG_H__ - +*/ +#pragma once +#ifndef __BLAKE2_CONFIG_H__ +#define __BLAKE2_CONFIG_H__ + #if defined(__SSE2__) -#define HAVE_SSE2 -#endif - -#if defined(__SSSE3__) -#define HAVE_SSSE3 -#endif - -#if defined(__SSE4_1__) +#define HAVE_SSE2 +#endif + +#if defined(__SSSE3__) +#define HAVE_SSSE3 +#endif + +#if defined(__SSE4_1__) #define HAVE_SSE4_1 -#endif - -#if defined(__AVX__) -#define HAVE_AVX -#endif - -#if defined(__XOP__) -#define HAVE_XOP -#endif - - -#ifdef HAVE_AVX2 -#ifndef HAVE_AVX -#define HAVE_AVX -#endif -#endif - -#ifdef HAVE_XOP -#ifndef HAVE_AVX -#define HAVE_AVX -#endif -#endif - -#ifdef HAVE_AVX +#endif + +#if defined(__AVX__) +#define HAVE_AVX +#endif + +#if defined(__XOP__) +#define HAVE_XOP +#endif + + +#ifdef HAVE_AVX2 +#ifndef HAVE_AVX +#define HAVE_AVX +#endif +#endif + +#ifdef HAVE_XOP +#ifndef HAVE_AVX +#define HAVE_AVX +#endif +#endif + +#ifdef HAVE_AVX #ifndef HAVE_SSE4_1 #define HAVE_SSE4_1 -#endif -#endif - -#ifdef HAVE_SSE41 -#ifndef HAVE_SSSE3 -#define HAVE_SSSE3 -#endif -#endif - -#ifdef HAVE_SSSE3 -#define HAVE_SSE2 -#endif - -#if !defined(HAVE_SSE2) -#error "This code requires at least SSE2." -#endif - -#endif - +#endif +#endif + +#ifdef HAVE_SSE41 +#ifndef HAVE_SSSE3 +#define HAVE_SSSE3 +#endif +#endif + +#ifdef HAVE_SSSE3 +#define HAVE_SSE2 +#endif + +#if !defined(HAVE_SSE2) +#error "This code requires at least SSE2." +#endif + +#endif + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2-impl.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2-impl.h index 9d2fbb72fc1..3ad6122f55d 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2-impl.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2-impl.h @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,140 +9,140 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2_IMPL_H__ -#define __BLAKE2_IMPL_H__ - +*/ +#pragma once +#ifndef __BLAKE2_IMPL_H__ +#define __BLAKE2_IMPL_H__ + #if defined(_WIN32) || defined(WIN32) #include #endif #include -#include -#include - +#include +#include + #define BLAKE2_IMPL_CAT(x,y) x ## y #define BLAKE2_IMPL_EVAL(x,y) BLAKE2_IMPL_CAT(x,y) #define BLAKE2_IMPL_NAME(fun) BLAKE2_IMPL_EVAL(fun, SUFFIX) static inline uint32_t load32( const void *src ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - uint32_t w; +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint32_t w; memcpy( &w, src, sizeof( w ) ); - return w; -#else + return w; +#else const uint8_t *p = ( uint8_t * )src; - uint32_t w = *p++; - w |= ( uint32_t )( *p++ ) << 8; - w |= ( uint32_t )( *p++ ) << 16; - w |= ( uint32_t )( *p++ ) << 24; - return w; -#endif -} - + uint32_t w = *p++; + w |= ( uint32_t )( *p++ ) << 8; + w |= ( uint32_t )( *p++ ) << 16; + w |= ( uint32_t )( *p++ ) << 24; + return w; +#endif +} + static inline uint64_t load64( const void *src ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - uint64_t w; +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint64_t w; memcpy( &w, src, sizeof( w ) ); - return w; -#else + return w; +#else const uint8_t *p = ( uint8_t * )src; - uint64_t w = *p++; - w |= ( uint64_t )( *p++ ) << 8; - w |= ( uint64_t )( *p++ ) << 16; - w |= ( uint64_t )( *p++ ) << 24; - w |= ( uint64_t )( *p++ ) << 32; - w |= ( uint64_t )( *p++ ) << 40; - w |= ( uint64_t )( *p++ ) << 48; - w |= ( uint64_t )( *p++ ) << 56; - return w; -#endif -} - + uint64_t w = *p++; + w |= ( uint64_t )( *p++ ) << 8; + w |= ( uint64_t )( *p++ ) << 16; + w |= ( uint64_t )( *p++ ) << 24; + w |= ( uint64_t )( *p++ ) << 32; + w |= ( uint64_t )( *p++ ) << 40; + w |= ( uint64_t )( *p++ ) << 48; + w |= ( uint64_t )( *p++ ) << 56; + return w; +#endif +} + static inline void store32( void *dst, uint32_t w ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) +{ +#if defined(NATIVE_LITTLE_ENDIAN) memcpy( dst, &w, sizeof( w ) ); -#else - uint8_t *p = ( uint8_t * )dst; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; -#endif -} - +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + static inline void store64( void *dst, uint64_t w ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) +{ +#if defined(NATIVE_LITTLE_ENDIAN) memcpy( dst, &w, sizeof( w ) ); -#else - uint8_t *p = ( uint8_t * )dst; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; -#endif -} - +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + static inline uint64_t load48( const void *src ) -{ - const uint8_t *p = ( const uint8_t * )src; - uint64_t w = *p++; - w |= ( uint64_t )( *p++ ) << 8; - w |= ( uint64_t )( *p++ ) << 16; - w |= ( uint64_t )( *p++ ) << 24; - w |= ( uint64_t )( *p++ ) << 32; - w |= ( uint64_t )( *p++ ) << 40; - return w; -} - +{ + const uint8_t *p = ( const uint8_t * )src; + uint64_t w = *p++; + w |= ( uint64_t )( *p++ ) << 8; + w |= ( uint64_t )( *p++ ) << 16; + w |= ( uint64_t )( *p++ ) << 24; + w |= ( uint64_t )( *p++ ) << 32; + w |= ( uint64_t )( *p++ ) << 40; + return w; +} + static inline void store48( void *dst, uint64_t w ) -{ - uint8_t *p = ( uint8_t * )dst; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; -} - +{ + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +} + static inline uint32_t rotl32( const uint32_t w, const unsigned c ) -{ - return ( w << c ) | ( w >> ( 32 - c ) ); -} - +{ + return ( w << c ) | ( w >> ( 32 - c ) ); +} + static inline uint64_t rotl64( const uint64_t w, const unsigned c ) -{ - return ( w << c ) | ( w >> ( 64 - c ) ); -} - +{ + return ( w << c ) | ( w >> ( 64 - c ) ); +} + static inline uint32_t rotr32( const uint32_t w, const unsigned c ) -{ - return ( w >> c ) | ( w << ( 32 - c ) ); -} - +{ + return ( w >> c ) | ( w << ( 32 - c ) ); +} + static inline uint64_t rotr64( const uint64_t w, const unsigned c ) -{ - return ( w >> c ) | ( w << ( 64 - c ) ); -} - -/* prevents compiler optimizing out memset() */ +{ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + +/* prevents compiler optimizing out memset() */ static inline void secure_zero_memory(void *v, size_t n) -{ +{ #if defined(_WIN32) || defined(WIN32) SecureZeroMemory(v, n); #elif defined(__hpux) - static void *(*const volatile memset_v)(void *, int, size_t) = &memset; - memset_v(v, 0, n); + static void *(*const volatile memset_v)(void *, int, size_t) = &memset; + memset_v(v, 0, n); #else // prioritize first the general C11 call #if defined(HAVE_MEMSET_S) @@ -156,7 +156,7 @@ static inline void secure_zero_memory(void *v, size_t n) __asm__ __volatile__("" :: "r"(v) : "memory"); #endif #endif -} - -#endif - +} + +#endif + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2.h index a08d82efefe..67cf58ae1de 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2.h @@ -1,4 +1,4 @@ -/* +/* BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,14 +9,14 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2_H__ -#define __BLAKE2_H__ - -#include -#include - +*/ +#pragma once +#ifndef __BLAKE2_H__ +#define __BLAKE2_H__ + +#include +#include + #if defined(_WIN32) || defined(__CYGWIN__) #define BLAKE2_DLL_IMPORT __declspec(dllimport) #define BLAKE2_DLL_EXPORT __declspec(dllexport) @@ -29,8 +29,8 @@ #define BLAKE2_DLL_IMPORT #define BLAKE2_DLL_EXPORT #define BLAKE2_DLL_PRIVATE -#endif - +#endif + #if defined(BLAKE2_DLL) #if defined(BLAKE2_DLL_EXPORTS) // defined if we are building the DLL #define BLAKE2_API BLAKE2_DLL_EXPORT @@ -41,32 +41,32 @@ #else #define BLAKE2_API #define BLAKE2_PRIVATE -#endif - -#if defined(__cplusplus) -extern "C" { +#endif + +#if defined(__cplusplus) +extern "C" { #elif defined(_MSC_VER) && !defined(inline) #define inline __inline -#endif - - enum blake2s_constant - { - BLAKE2S_BLOCKBYTES = 64, - BLAKE2S_OUTBYTES = 32, - BLAKE2S_KEYBYTES = 32, - BLAKE2S_SALTBYTES = 8, - BLAKE2S_PERSONALBYTES = 8 - }; - - enum blake2b_constant - { - BLAKE2B_BLOCKBYTES = 128, - BLAKE2B_OUTBYTES = 64, - BLAKE2B_KEYBYTES = 64, - BLAKE2B_SALTBYTES = 16, - BLAKE2B_PERSONALBYTES = 16 - }; - +#endif + + enum blake2s_constant + { + BLAKE2S_BLOCKBYTES = 64, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, + BLAKE2S_PERSONALBYTES = 8 + }; + + enum blake2b_constant + { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 + }; + #pragma pack(push, 1) typedef struct __blake2s_param { @@ -83,17 +83,17 @@ extern "C" { uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32 } blake2s_param; - typedef struct __blake2s_state - { - uint32_t h[8]; - uint32_t t[2]; - uint32_t f[2]; - uint8_t buf[2 * BLAKE2S_BLOCKBYTES]; + typedef struct __blake2s_state + { + uint32_t h[8]; + uint32_t t[2]; + uint32_t f[2]; + uint8_t buf[2 * BLAKE2S_BLOCKBYTES]; uint32_t buflen; uint8_t outlen; - uint8_t last_node; - } blake2s_state; - + uint8_t last_node; + } blake2s_state; + typedef struct __blake2b_param { uint8_t digest_length; // 1 @@ -109,69 +109,69 @@ extern "C" { uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64 } blake2b_param; - typedef struct __blake2b_state - { - uint64_t h[8]; - uint64_t t[2]; - uint64_t f[2]; - uint8_t buf[2 * BLAKE2B_BLOCKBYTES]; + typedef struct __blake2b_state + { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[2 * BLAKE2B_BLOCKBYTES]; uint32_t buflen; uint8_t outlen; - uint8_t last_node; - } blake2b_state; - - typedef struct __blake2sp_state - { - blake2s_state S[8][1]; - blake2s_state R[1]; + uint8_t last_node; + } blake2b_state; + + typedef struct __blake2sp_state + { + blake2s_state S[8][1]; + blake2s_state R[1]; uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; uint32_t buflen; uint8_t outlen; - } blake2sp_state; - - typedef struct __blake2bp_state - { - blake2b_state S[4][1]; - blake2b_state R[1]; + } blake2sp_state; + + typedef struct __blake2bp_state + { + blake2b_state S[4][1]; + blake2b_state R[1]; uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; uint32_t buflen; uint8_t outlen; - } blake2bp_state; -#pragma pack(pop) - + } blake2bp_state; +#pragma pack(pop) + // Streaming API BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen ); BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ); BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ); - + BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen ); BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ); BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ); - + BLAKE2_API int blake2sp_init( blake2sp_state *S, size_t outlen ); BLAKE2_API int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); BLAKE2_API int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen ); BLAKE2_API int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen ); - + BLAKE2_API int blake2bp_init( blake2bp_state *S, size_t outlen ); BLAKE2_API int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); BLAKE2_API int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen ); BLAKE2_API int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen ); - + // Simple API BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - + BLAKE2_API int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); BLAKE2_API int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#if defined(__cplusplus) -} -#endif - -#endif - + +#if defined(__cplusplus) +} +#endif + +#endif + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-load-sse2.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-load-sse2.h index 1ba153c87d7..45c28f8b79a 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-load-sse2.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-load-sse2.h @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,60 +9,60 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2B_LOAD_SSE2_H__ -#define __BLAKE2B_LOAD_SSE2_H__ - -#define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) -#define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) -#define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) -#define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) -#define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) -#define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) -#define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) -#define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) -#define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5) -#define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2) -#define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7) -#define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1) -#define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13) -#define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12) -#define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4) -#define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0) -#define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2) -#define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4) -#define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6) -#define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8) -#define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0) -#define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11) -#define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15) -#define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14) -#define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14) -#define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13) -#define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9) -#define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2) -#define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12) -#define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1) -#define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8) -#define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6) -#define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11) -#define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3) -#define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1) -#define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4) -#define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7) -#define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6) -#define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3) -#define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12) -#define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) -#define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) -#define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) -#define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) -#define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) -#define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) -#define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) -#define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) - - -#endif - +*/ +#pragma once +#ifndef __BLAKE2B_LOAD_SSE2_H__ +#define __BLAKE2B_LOAD_SSE2_H__ + +#define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) +#define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) +#define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) +#define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) +#define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) +#define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) +#define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) +#define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5) +#define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2) +#define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7) +#define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1) +#define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13) +#define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4) +#define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0) +#define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2) +#define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4) +#define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6) +#define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8) +#define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0) +#define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11) +#define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15) +#define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14) +#define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14) +#define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13) +#define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9) +#define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2) +#define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12) +#define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1) +#define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8) +#define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6) +#define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11) +#define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3) +#define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1) +#define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4) +#define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7) +#define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6) +#define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3) +#define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12) +#define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) +#define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) +#define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) +#define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) +#define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) +#define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) +#define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) + + +#endif + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-load-sse41.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-load-sse41.h index f6c1bc8393f..8e935f6f120 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-load-sse41.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-load-sse41.h @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,394 +9,394 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2B_LOAD_SSE41_H__ -#define __BLAKE2B_LOAD_SSE41_H__ - -#define LOAD_MSG_0_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m0, m1); \ -b1 = _mm_unpacklo_epi64(m2, m3); \ -} while(0) - - -#define LOAD_MSG_0_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m0, m1); \ -b1 = _mm_unpackhi_epi64(m2, m3); \ -} while(0) - - -#define LOAD_MSG_0_3(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m4, m5); \ -b1 = _mm_unpacklo_epi64(m6, m7); \ -} while(0) - - -#define LOAD_MSG_0_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m4, m5); \ -b1 = _mm_unpackhi_epi64(m6, m7); \ -} while(0) - - -#define LOAD_MSG_1_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m7, m2); \ -b1 = _mm_unpackhi_epi64(m4, m6); \ -} while(0) - - -#define LOAD_MSG_1_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m5, m4); \ -b1 = _mm_alignr_epi8(m3, m7, 8); \ -} while(0) - - -#define LOAD_MSG_1_3(b0, b1) \ -do \ -{ \ -b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ -b1 = _mm_unpackhi_epi64(m5, m2); \ -} while(0) - - -#define LOAD_MSG_1_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m6, m1); \ -b1 = _mm_unpackhi_epi64(m3, m1); \ -} while(0) - - -#define LOAD_MSG_2_1(b0, b1) \ -do \ -{ \ -b0 = _mm_alignr_epi8(m6, m5, 8); \ -b1 = _mm_unpackhi_epi64(m2, m7); \ -} while(0) - - -#define LOAD_MSG_2_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m4, m0); \ -b1 = _mm_blend_epi16(m1, m6, 0xF0); \ -} while(0) - - -#define LOAD_MSG_2_3(b0, b1) \ -do \ -{ \ -b0 = _mm_blend_epi16(m5, m1, 0xF0); \ -b1 = _mm_unpackhi_epi64(m3, m4); \ -} while(0) - - -#define LOAD_MSG_2_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m7, m3); \ -b1 = _mm_alignr_epi8(m2, m0, 8); \ -} while(0) - - -#define LOAD_MSG_3_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m3, m1); \ -b1 = _mm_unpackhi_epi64(m6, m5); \ -} while(0) - - -#define LOAD_MSG_3_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m4, m0); \ -b1 = _mm_unpacklo_epi64(m6, m7); \ -} while(0) - - -#define LOAD_MSG_3_3(b0, b1) \ -do \ -{ \ -b0 = _mm_blend_epi16(m1, m2, 0xF0); \ -b1 = _mm_blend_epi16(m2, m7, 0xF0); \ -} while(0) - - -#define LOAD_MSG_3_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m3, m5); \ -b1 = _mm_unpacklo_epi64(m0, m4); \ -} while(0) - - -#define LOAD_MSG_4_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m4, m2); \ -b1 = _mm_unpacklo_epi64(m1, m5); \ -} while(0) - - -#define LOAD_MSG_4_2(b0, b1) \ -do \ -{ \ -b0 = _mm_blend_epi16(m0, m3, 0xF0); \ -b1 = _mm_blend_epi16(m2, m7, 0xF0); \ -} while(0) - - -#define LOAD_MSG_4_3(b0, b1) \ -do \ -{ \ -b0 = _mm_blend_epi16(m7, m5, 0xF0); \ -b1 = _mm_blend_epi16(m3, m1, 0xF0); \ -} while(0) - - -#define LOAD_MSG_4_4(b0, b1) \ -do \ -{ \ -b0 = _mm_alignr_epi8(m6, m0, 8); \ -b1 = _mm_blend_epi16(m4, m6, 0xF0); \ -} while(0) - - -#define LOAD_MSG_5_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m1, m3); \ -b1 = _mm_unpacklo_epi64(m0, m4); \ -} while(0) - - -#define LOAD_MSG_5_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m6, m5); \ -b1 = _mm_unpackhi_epi64(m5, m1); \ -} while(0) - - -#define LOAD_MSG_5_3(b0, b1) \ -do \ -{ \ -b0 = _mm_blend_epi16(m2, m3, 0xF0); \ -b1 = _mm_unpackhi_epi64(m7, m0); \ -} while(0) - - -#define LOAD_MSG_5_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m6, m2); \ -b1 = _mm_blend_epi16(m7, m4, 0xF0); \ -} while(0) - - -#define LOAD_MSG_6_1(b0, b1) \ -do \ -{ \ -b0 = _mm_blend_epi16(m6, m0, 0xF0); \ -b1 = _mm_unpacklo_epi64(m7, m2); \ -} while(0) - - -#define LOAD_MSG_6_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m2, m7); \ -b1 = _mm_alignr_epi8(m5, m6, 8); \ -} while(0) - - -#define LOAD_MSG_6_3(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m0, m3); \ -b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \ -} while(0) - - -#define LOAD_MSG_6_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m3, m1); \ -b1 = _mm_blend_epi16(m1, m5, 0xF0); \ -} while(0) - - -#define LOAD_MSG_7_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m6, m3); \ -b1 = _mm_blend_epi16(m6, m1, 0xF0); \ -} while(0) - - -#define LOAD_MSG_7_2(b0, b1) \ -do \ -{ \ -b0 = _mm_alignr_epi8(m7, m5, 8); \ -b1 = _mm_unpackhi_epi64(m0, m4); \ -} while(0) - - -#define LOAD_MSG_7_3(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m2, m7); \ -b1 = _mm_unpacklo_epi64(m4, m1); \ -} while(0) - - -#define LOAD_MSG_7_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m0, m2); \ -b1 = _mm_unpacklo_epi64(m3, m5); \ -} while(0) - - -#define LOAD_MSG_8_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m3, m7); \ -b1 = _mm_alignr_epi8(m0, m5, 8); \ -} while(0) - - -#define LOAD_MSG_8_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m7, m4); \ -b1 = _mm_alignr_epi8(m4, m1, 8); \ -} while(0) - - -#define LOAD_MSG_8_3(b0, b1) \ -do \ -{ \ -b0 = m6; \ -b1 = _mm_alignr_epi8(m5, m0, 8); \ -} while(0) - - -#define LOAD_MSG_8_4(b0, b1) \ -do \ -{ \ -b0 = _mm_blend_epi16(m1, m3, 0xF0); \ -b1 = m2; \ -} while(0) - - -#define LOAD_MSG_9_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m5, m4); \ -b1 = _mm_unpackhi_epi64(m3, m0); \ -} while(0) - - -#define LOAD_MSG_9_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m1, m2); \ -b1 = _mm_blend_epi16(m3, m2, 0xF0); \ -} while(0) - - -#define LOAD_MSG_9_3(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m7, m4); \ -b1 = _mm_unpackhi_epi64(m1, m6); \ -} while(0) - - -#define LOAD_MSG_9_4(b0, b1) \ -do \ -{ \ -b0 = _mm_alignr_epi8(m7, m5, 8); \ -b1 = _mm_unpacklo_epi64(m6, m0); \ -} while(0) - - -#define LOAD_MSG_10_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m0, m1); \ -b1 = _mm_unpacklo_epi64(m2, m3); \ -} while(0) - - -#define LOAD_MSG_10_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m0, m1); \ -b1 = _mm_unpackhi_epi64(m2, m3); \ -} while(0) - - -#define LOAD_MSG_10_3(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m4, m5); \ -b1 = _mm_unpacklo_epi64(m6, m7); \ -} while(0) - - -#define LOAD_MSG_10_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpackhi_epi64(m4, m5); \ -b1 = _mm_unpackhi_epi64(m6, m7); \ -} while(0) - - -#define LOAD_MSG_11_1(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m7, m2); \ -b1 = _mm_unpackhi_epi64(m4, m6); \ -} while(0) - - -#define LOAD_MSG_11_2(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m5, m4); \ -b1 = _mm_alignr_epi8(m3, m7, 8); \ -} while(0) - - -#define LOAD_MSG_11_3(b0, b1) \ -do \ -{ \ -b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ -b1 = _mm_unpackhi_epi64(m5, m2); \ -} while(0) - - -#define LOAD_MSG_11_4(b0, b1) \ -do \ -{ \ -b0 = _mm_unpacklo_epi64(m6, m1); \ -b1 = _mm_unpackhi_epi64(m3, m1); \ -} while(0) - - -#endif - +*/ +#pragma once +#ifndef __BLAKE2B_LOAD_SSE41_H__ +#define __BLAKE2B_LOAD_SSE41_H__ + +#define LOAD_MSG_0_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m0, m1); \ +b1 = _mm_unpacklo_epi64(m2, m3); \ +} while(0) + + +#define LOAD_MSG_0_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m0, m1); \ +b1 = _mm_unpackhi_epi64(m2, m3); \ +} while(0) + + +#define LOAD_MSG_0_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m4, m5); \ +b1 = _mm_unpacklo_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_0_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m4, m5); \ +b1 = _mm_unpackhi_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_1_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m7, m2); \ +b1 = _mm_unpackhi_epi64(m4, m6); \ +} while(0) + + +#define LOAD_MSG_1_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m5, m4); \ +b1 = _mm_alignr_epi8(m3, m7, 8); \ +} while(0) + + +#define LOAD_MSG_1_3(b0, b1) \ +do \ +{ \ +b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ +b1 = _mm_unpackhi_epi64(m5, m2); \ +} while(0) + + +#define LOAD_MSG_1_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m6, m1); \ +b1 = _mm_unpackhi_epi64(m3, m1); \ +} while(0) + + +#define LOAD_MSG_2_1(b0, b1) \ +do \ +{ \ +b0 = _mm_alignr_epi8(m6, m5, 8); \ +b1 = _mm_unpackhi_epi64(m2, m7); \ +} while(0) + + +#define LOAD_MSG_2_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m4, m0); \ +b1 = _mm_blend_epi16(m1, m6, 0xF0); \ +} while(0) + + +#define LOAD_MSG_2_3(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m5, m1, 0xF0); \ +b1 = _mm_unpackhi_epi64(m3, m4); \ +} while(0) + + +#define LOAD_MSG_2_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m7, m3); \ +b1 = _mm_alignr_epi8(m2, m0, 8); \ +} while(0) + + +#define LOAD_MSG_3_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m3, m1); \ +b1 = _mm_unpackhi_epi64(m6, m5); \ +} while(0) + + +#define LOAD_MSG_3_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m4, m0); \ +b1 = _mm_unpacklo_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_3_3(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m1, m2, 0xF0); \ +b1 = _mm_blend_epi16(m2, m7, 0xF0); \ +} while(0) + + +#define LOAD_MSG_3_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m3, m5); \ +b1 = _mm_unpacklo_epi64(m0, m4); \ +} while(0) + + +#define LOAD_MSG_4_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m4, m2); \ +b1 = _mm_unpacklo_epi64(m1, m5); \ +} while(0) + + +#define LOAD_MSG_4_2(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m0, m3, 0xF0); \ +b1 = _mm_blend_epi16(m2, m7, 0xF0); \ +} while(0) + + +#define LOAD_MSG_4_3(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m7, m5, 0xF0); \ +b1 = _mm_blend_epi16(m3, m1, 0xF0); \ +} while(0) + + +#define LOAD_MSG_4_4(b0, b1) \ +do \ +{ \ +b0 = _mm_alignr_epi8(m6, m0, 8); \ +b1 = _mm_blend_epi16(m4, m6, 0xF0); \ +} while(0) + + +#define LOAD_MSG_5_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m1, m3); \ +b1 = _mm_unpacklo_epi64(m0, m4); \ +} while(0) + + +#define LOAD_MSG_5_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m6, m5); \ +b1 = _mm_unpackhi_epi64(m5, m1); \ +} while(0) + + +#define LOAD_MSG_5_3(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m2, m3, 0xF0); \ +b1 = _mm_unpackhi_epi64(m7, m0); \ +} while(0) + + +#define LOAD_MSG_5_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m6, m2); \ +b1 = _mm_blend_epi16(m7, m4, 0xF0); \ +} while(0) + + +#define LOAD_MSG_6_1(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m6, m0, 0xF0); \ +b1 = _mm_unpacklo_epi64(m7, m2); \ +} while(0) + + +#define LOAD_MSG_6_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m2, m7); \ +b1 = _mm_alignr_epi8(m5, m6, 8); \ +} while(0) + + +#define LOAD_MSG_6_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m0, m3); \ +b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \ +} while(0) + + +#define LOAD_MSG_6_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m3, m1); \ +b1 = _mm_blend_epi16(m1, m5, 0xF0); \ +} while(0) + + +#define LOAD_MSG_7_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m6, m3); \ +b1 = _mm_blend_epi16(m6, m1, 0xF0); \ +} while(0) + + +#define LOAD_MSG_7_2(b0, b1) \ +do \ +{ \ +b0 = _mm_alignr_epi8(m7, m5, 8); \ +b1 = _mm_unpackhi_epi64(m0, m4); \ +} while(0) + + +#define LOAD_MSG_7_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m2, m7); \ +b1 = _mm_unpacklo_epi64(m4, m1); \ +} while(0) + + +#define LOAD_MSG_7_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m0, m2); \ +b1 = _mm_unpacklo_epi64(m3, m5); \ +} while(0) + + +#define LOAD_MSG_8_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m3, m7); \ +b1 = _mm_alignr_epi8(m0, m5, 8); \ +} while(0) + + +#define LOAD_MSG_8_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m7, m4); \ +b1 = _mm_alignr_epi8(m4, m1, 8); \ +} while(0) + + +#define LOAD_MSG_8_3(b0, b1) \ +do \ +{ \ +b0 = m6; \ +b1 = _mm_alignr_epi8(m5, m0, 8); \ +} while(0) + + +#define LOAD_MSG_8_4(b0, b1) \ +do \ +{ \ +b0 = _mm_blend_epi16(m1, m3, 0xF0); \ +b1 = m2; \ +} while(0) + + +#define LOAD_MSG_9_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m5, m4); \ +b1 = _mm_unpackhi_epi64(m3, m0); \ +} while(0) + + +#define LOAD_MSG_9_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m1, m2); \ +b1 = _mm_blend_epi16(m3, m2, 0xF0); \ +} while(0) + + +#define LOAD_MSG_9_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m7, m4); \ +b1 = _mm_unpackhi_epi64(m1, m6); \ +} while(0) + + +#define LOAD_MSG_9_4(b0, b1) \ +do \ +{ \ +b0 = _mm_alignr_epi8(m7, m5, 8); \ +b1 = _mm_unpacklo_epi64(m6, m0); \ +} while(0) + + +#define LOAD_MSG_10_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m0, m1); \ +b1 = _mm_unpacklo_epi64(m2, m3); \ +} while(0) + + +#define LOAD_MSG_10_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m0, m1); \ +b1 = _mm_unpackhi_epi64(m2, m3); \ +} while(0) + + +#define LOAD_MSG_10_3(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m4, m5); \ +b1 = _mm_unpacklo_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_10_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpackhi_epi64(m4, m5); \ +b1 = _mm_unpackhi_epi64(m6, m7); \ +} while(0) + + +#define LOAD_MSG_11_1(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m7, m2); \ +b1 = _mm_unpackhi_epi64(m4, m6); \ +} while(0) + + +#define LOAD_MSG_11_2(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m5, m4); \ +b1 = _mm_alignr_epi8(m3, m7, 8); \ +} while(0) + + +#define LOAD_MSG_11_3(b0, b1) \ +do \ +{ \ +b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ +b1 = _mm_unpackhi_epi64(m5, m2); \ +} while(0) + + +#define LOAD_MSG_11_4(b0, b1) \ +do \ +{ \ +b0 = _mm_unpacklo_epi64(m6, m1); \ +b1 = _mm_unpackhi_epi64(m3, m1); \ +} while(0) + + +#endif + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-ref.c b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-ref.c index e58c43659d9..257e7d2c488 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-ref.c +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-ref.c @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - reference C implementations +/* + BLAKE2 reference source code package - reference C implementations Written in 2012 by Samuel Neves @@ -9,142 +9,142 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ - -#include -#include -#include - -#include "blake2.h" -#include "blake2-impl.h" - -static const uint64_t blake2b_IV[8] = -{ - 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL -}; - -static const uint8_t blake2b_sigma[12][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } -}; - - +*/ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + + static inline int blake2b_set_lastnode( blake2b_state *S ) -{ +{ S->f[1] = ~0ULL; - return 0; -} - + return 0; +} + static inline int blake2b_clear_lastnode( blake2b_state *S ) -{ +{ S->f[1] = 0ULL; - return 0; -} - -/* Some helper functions, not necessarily useful */ + return 0; +} + +/* Some helper functions, not necessarily useful */ static inline int blake2b_set_lastblock( blake2b_state *S ) -{ - if( S->last_node ) blake2b_set_lastnode( S ); - +{ + if( S->last_node ) blake2b_set_lastnode( S ); + S->f[0] = ~0ULL; - return 0; -} - + return 0; +} + static inline int blake2b_clear_lastblock( blake2b_state *S ) -{ - if( S->last_node ) blake2b_clear_lastnode( S ); - +{ + if( S->last_node ) blake2b_clear_lastnode( S ); + S->f[0] = 0ULL; - return 0; -} - + return 0; +} + static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) -{ - S->t[0] += inc; - S->t[1] += ( S->t[0] < inc ); - return 0; -} - - - +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); + return 0; +} + + + // Parameter-related functions static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length ) -{ - P->digest_length = digest_length; - return 0; -} - +{ + P->digest_length = digest_length; + return 0; +} + static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) -{ - P->fanout = fanout; - return 0; -} - +{ + P->fanout = fanout; + return 0; +} + static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth ) -{ - P->depth = depth; - return 0; -} - +{ + P->depth = depth; + return 0; +} + static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) -{ - store32( &P->leaf_length, leaf_length ); - return 0; -} - +{ + store32( &P->leaf_length, leaf_length ); + return 0; +} + static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset ) -{ - store64( &P->node_offset, node_offset ); - return 0; -} - +{ + store64( &P->node_offset, node_offset ); + return 0; +} + static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) -{ - P->node_depth = node_depth; - return 0; -} - +{ + P->node_depth = node_depth; + return 0; +} + static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length ) -{ - P->inner_length = inner_length; - return 0; -} - +{ + P->inner_length = inner_length; + return 0; +} + static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) -{ - memcpy( P->salt, salt, BLAKE2B_SALTBYTES ); - return 0; -} - +{ + memcpy( P->salt, salt, BLAKE2B_SALTBYTES ); + return 0; +} + static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] ) -{ - memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); - return 0; -} - +{ + memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); + return 0; +} + static inline int blake2b_init0( blake2b_state *S ) -{ - memset( S, 0, sizeof( blake2b_state ) ); - +{ + memset( S, 0, sizeof( blake2b_state ) ); + for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; - - return 0; -} - + + return 0; +} + #if defined(__cplusplus) extern "C" { #endif @@ -158,222 +158,222 @@ extern "C" { } #endif -/* init xors IV with input parameter block */ -int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) -{ - blake2b_init0( S ); +/* init xors IV with input parameter block */ +int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + blake2b_init0( S ); uint8_t *p = ( uint8_t * )( P ); - - /* IV XOR ParamBlock */ + + /* IV XOR ParamBlock */ for( size_t i = 0; i < 8; ++i ) - S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); - + S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + S->outlen = P->digest_length; - return 0; -} - - - + return 0; +} + + + int blake2b_init( blake2b_state *S, size_t outlen ) -{ - blake2b_param P[1]; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + P->digest_length = ( uint8_t ) outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store64( &P->node_offset, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memset( P->reserved, 0, sizeof( P->reserved ) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - return blake2b_init_param( S, P ); -} - - + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store64( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2b_init_param( S, P ); +} + + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2b_param P[1]; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; - +{ + blake2b_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; + P->digest_length = ( uint8_t ) outlen; P->key_length = ( uint8_t ) keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store64( &P->node_offset, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memset( P->reserved, 0, sizeof( P->reserved ) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - - if( blake2b_init_param( S, P ) < 0 ) return -1; - - { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset( block, 0, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); - secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - -static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) -{ - uint64_t m[16]; - uint64_t v[16]; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store64( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2b_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) +{ + uint64_t m[16]; + uint64_t v[16]; size_t i; - - for( i = 0; i < 16; ++i ) - m[i] = load64( block + i * sizeof( m[i] ) ); - - for( i = 0; i < 8; ++i ) - v[i] = S->h[i]; - - v[ 8] = blake2b_IV[0]; - v[ 9] = blake2b_IV[1]; - v[10] = blake2b_IV[2]; - v[11] = blake2b_IV[3]; - v[12] = S->t[0] ^ blake2b_IV[4]; - v[13] = S->t[1] ^ blake2b_IV[5]; - v[14] = S->f[0] ^ blake2b_IV[6]; - v[15] = S->f[1] ^ blake2b_IV[7]; -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2b_sigma[r][2*i+0]]; \ - d = rotr64(d ^ a, 32); \ - c = c + d; \ - b = rotr64(b ^ c, 24); \ - a = a + b + m[blake2b_sigma[r][2*i+1]]; \ - d = rotr64(d ^ a, 16); \ - c = c + d; \ - b = rotr64(b ^ c, 63); \ - } while(0) -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - ROUND( 10 ); - ROUND( 11 ); - - for( i = 0; i < 8; ++i ) - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - -#undef G -#undef ROUND - return 0; -} - + + for( i = 0; i < 16; ++i ) + m[i] = load64( block + i * sizeof( m[i] ) ); + + for( i = 0; i < 8; ++i ) + v[i] = S->h[i]; + + v[ 8] = blake2b_IV[0]; + v[ 9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = S->t[0] ^ blake2b_IV[4]; + v[13] = S->t[1] ^ blake2b_IV[5]; + v[14] = S->f[0] ^ blake2b_IV[6]; + v[15] = S->f[1] ^ blake2b_IV[7]; +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2*i+0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2*i+1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + + for( i = 0; i < 8; ++i ) + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + +#undef G +#undef ROUND + return 0; +} + int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) -{ - while( inlen > 0 ) - { +{ + while( inlen > 0 ) + { uint32_t left = S->buflen; uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left; - - if( inlen > fill ) - { + + if( inlen > fill ) + { memcpy( S->buf + left, in, fill ); // Fill buffer - S->buflen += fill; - blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + S->buflen += fill; + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); // Compress memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left - S->buflen -= BLAKE2B_BLOCKBYTES; - in += fill; - inlen -= fill; - } + S->buflen -= BLAKE2B_BLOCKBYTES; + in += fill; + inlen -= fill; + } else // inlen <= fill - { + { memcpy( S->buf + left, in, inlen ); S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress - in += inlen; - inlen -= inlen; - } - } - - return 0; -} - + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ) -{ +{ uint8_t buffer[BLAKE2B_OUTBYTES]; size_t i; - + if(S->outlen != outlen) return -1; - - if( S->buflen > BLAKE2B_BLOCKBYTES ) - { - blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - blake2b_compress( S, S->buf ); - S->buflen -= BLAKE2B_BLOCKBYTES; + + if( S->buflen > BLAKE2B_BLOCKBYTES ) + { + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); + S->buflen -= BLAKE2B_BLOCKBYTES; memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); - } - - blake2b_increment_counter( S, S->buflen ); - blake2b_set_lastblock( S ); - memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ - blake2b_compress( S, S->buf ); - - for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ - store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - - memcpy( out, buffer, outlen ); - return 0; -} - + } + + blake2b_increment_counter( S, S->buflen ); + blake2b_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ + blake2b_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + return 0; +} + int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - blake2b_state S[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if( NULL == key && keylen > 0 ) return -1; - - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - if( keylen > BLAKE2B_KEYBYTES ) return -1; - - if( keylen > 0 ) - { - if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; - } - else - { - if( blake2b_init( S, outlen ) < 0 ) return -1; - } - +{ + blake2b_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if( NULL == key && keylen > 0 ) return -1; + + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + if( keylen > BLAKE2B_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2b_init( S, outlen ) < 0 ) return -1; + } + if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0 ) return -1; return blake2b_final( S, out, outlen ); -} - - +} + + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-round.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-round.h index cebc22550da..a003b0bac68 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-round.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b-round.h @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,152 +9,152 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2B_ROUND_H__ -#define __BLAKE2B_ROUND_H__ - +*/ +#pragma once +#ifndef __BLAKE2B_ROUND_H__ +#define __BLAKE2B_ROUND_H__ + #define LOAD(p) _mm_load_si128( (__m128i *)(p) ) #define STORE(p,r) _mm_store_si128((__m128i *)(p), r) #define LOADU(p) _mm_loadu_si128( (__m128i *)(p) ) -#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) - -#define TOF(reg) _mm_castsi128_ps((reg)) -#define TOI(reg) _mm_castps_si128((reg)) - -#define LIKELY(x) __builtin_expect((x),1) - - -/* Microarchitecture-specific macros */ -#ifndef HAVE_XOP -#ifdef HAVE_SSSE3 -#define _mm_roti_epi64(x, c) \ - (-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \ - : (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \ - : (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \ - : (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \ - : _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c)))) -#else -#define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-(c)) )) -#endif -#else -/* ... */ -#endif - - - -#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ - row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ - row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ - \ - row4l = _mm_xor_si128(row4l, row1l); \ - row4h = _mm_xor_si128(row4h, row1h); \ - \ - row4l = _mm_roti_epi64(row4l, -32); \ - row4h = _mm_roti_epi64(row4h, -32); \ - \ - row3l = _mm_add_epi64(row3l, row4l); \ - row3h = _mm_add_epi64(row3h, row4h); \ - \ - row2l = _mm_xor_si128(row2l, row3l); \ - row2h = _mm_xor_si128(row2h, row3h); \ - \ - row2l = _mm_roti_epi64(row2l, -24); \ - row2h = _mm_roti_epi64(row2h, -24); \ - -#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ - row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ - row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ - \ - row4l = _mm_xor_si128(row4l, row1l); \ - row4h = _mm_xor_si128(row4h, row1h); \ - \ - row4l = _mm_roti_epi64(row4l, -16); \ - row4h = _mm_roti_epi64(row4h, -16); \ - \ - row3l = _mm_add_epi64(row3l, row4l); \ - row3h = _mm_add_epi64(row3h, row4h); \ - \ - row2l = _mm_xor_si128(row2l, row3l); \ - row2h = _mm_xor_si128(row2h, row3h); \ - \ - row2l = _mm_roti_epi64(row2l, -63); \ - row2h = _mm_roti_epi64(row2h, -63); \ - -#if defined(HAVE_SSSE3) -#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ - t0 = _mm_alignr_epi8(row2h, row2l, 8); \ - t1 = _mm_alignr_epi8(row2l, row2h, 8); \ - row2l = t0; \ - row2h = t1; \ - \ - t0 = row3l; \ - row3l = row3h; \ - row3h = t0; \ - \ - t0 = _mm_alignr_epi8(row4h, row4l, 8); \ - t1 = _mm_alignr_epi8(row4l, row4h, 8); \ - row4l = t1; \ - row4h = t0; - -#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ - t0 = _mm_alignr_epi8(row2l, row2h, 8); \ - t1 = _mm_alignr_epi8(row2h, row2l, 8); \ - row2l = t0; \ - row2h = t1; \ - \ - t0 = row3l; \ - row3l = row3h; \ - row3h = t0; \ - \ - t0 = _mm_alignr_epi8(row4l, row4h, 8); \ - t1 = _mm_alignr_epi8(row4h, row4l, 8); \ - row4l = t1; \ - row4h = t0; -#else - -#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ - t0 = row4l;\ - t1 = row2l;\ - row4l = row3l;\ - row3l = row3h;\ - row3h = row4l;\ - row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \ - row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \ - row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \ - row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1)) - -#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ - t0 = row3l;\ - row3l = row3h;\ - row3h = t0;\ - t0 = row2l;\ - t1 = row4l;\ - row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \ - row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \ - row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \ - row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1)) - -#endif - +#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) + +#define TOF(reg) _mm_castsi128_ps((reg)) +#define TOI(reg) _mm_castps_si128((reg)) + +#define LIKELY(x) __builtin_expect((x),1) + + +/* Microarchitecture-specific macros */ +#ifndef HAVE_XOP +#ifdef HAVE_SSSE3 +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \ + : (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c)))) +#else +#define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-(c)) )) +#endif +#else +/* ... */ +#endif + + + +#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -32); \ + row4h = _mm_roti_epi64(row4h, -32); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -24); \ + row2h = _mm_roti_epi64(row2h, -24); \ + +#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -16); \ + row4h = _mm_roti_epi64(row4h, -16); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -63); \ + row2h = _mm_roti_epi64(row2h, -63); \ + +#if defined(HAVE_SSSE3) +#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = _mm_alignr_epi8(row2h, row2l, 8); \ + t1 = _mm_alignr_epi8(row2l, row2h, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4h, row4l, 8); \ + t1 = _mm_alignr_epi8(row4l, row4h, 8); \ + row4l = t1; \ + row4h = t0; + +#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = _mm_alignr_epi8(row2l, row2h, 8); \ + t1 = _mm_alignr_epi8(row2h, row2l, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4l, row4h, 8); \ + t1 = _mm_alignr_epi8(row4h, row4l, 8); \ + row4l = t1; \ + row4h = t0; +#else + +#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = row4l;\ + t1 = row2l;\ + row4l = row3l;\ + row3l = row3h;\ + row3h = row4l;\ + row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \ + row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \ + row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \ + row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1)) + +#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ + t0 = row3l;\ + row3l = row3h;\ + row3h = t0;\ + t0 = row2l;\ + t1 = row4l;\ + row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \ + row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \ + row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \ + row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1)) + +#endif + #if defined(HAVE_SSE4_1) -#include "blake2b-load-sse41.h" -#else -#include "blake2b-load-sse2.h" -#endif - -#define ROUND(r) \ - LOAD_MSG_ ##r ##_1(b0, b1); \ - G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ - LOAD_MSG_ ##r ##_2(b0, b1); \ - G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ - DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ - LOAD_MSG_ ##r ##_3(b0, b1); \ - G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ - LOAD_MSG_ ##r ##_4(b0, b1); \ - G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ - UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); - -#endif - +#include "blake2b-load-sse41.h" +#else +#include "blake2b-load-sse2.h" +#endif + +#define ROUND(r) \ + LOAD_MSG_ ##r ##_1(b0, b1); \ + G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + LOAD_MSG_ ##r ##_2(b0, b1); \ + G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ + LOAD_MSG_ ##r ##_3(b0, b1); \ + G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + LOAD_MSG_ ##r ##_4(b0, b1); \ + G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ + UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); + +#endif + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b.c b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b.c index c1068e86405..7742ed32e6b 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2b.c +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2b.c @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,23 +9,23 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ - -#include -#include -#include - -#include "blake2.h" -#include "blake2-impl.h" - -#include "blake2-config.h" - +*/ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +#include "blake2-config.h" + #if defined(_MSC_VER) #include -#endif +#endif #if defined(HAVE_SSE2) -#include +#include // MSVC only defines _mm_set_epi64x for x86_64... #if defined(_MSC_VER) && !defined(_M_X64) static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 ) @@ -35,158 +35,158 @@ static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 ) #endif #endif -#if defined(HAVE_SSSE3) -#include -#endif +#if defined(HAVE_SSSE3) +#include +#endif #if defined(HAVE_SSE4_1) -#include -#endif -#if defined(HAVE_AVX) -#include -#endif +#include +#endif +#if defined(HAVE_AVX) +#include +#endif #if defined(HAVE_XOP) && !defined(_MSC_VER) -#include -#endif - - - -#include "blake2b-round.h" - -static const uint64_t blake2b_IV[8] = -{ - 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL -}; - -static const uint8_t blake2b_sigma[12][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } -}; - - -/* Some helper functions, not necessarily useful */ +#include +#endif + + + +#include "blake2b-round.h" + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + + +/* Some helper functions, not necessarily useful */ static inline int blake2b_set_lastnode( blake2b_state *S ) -{ +{ S->f[1] = ~0ULL; - return 0; -} - + return 0; +} + static inline int blake2b_clear_lastnode( blake2b_state *S ) -{ +{ S->f[1] = 0ULL; - return 0; -} - + return 0; +} + static inline int blake2b_set_lastblock( blake2b_state *S ) -{ - if( S->last_node ) blake2b_set_lastnode( S ); - +{ + if( S->last_node ) blake2b_set_lastnode( S ); + S->f[0] = ~0ULL; - return 0; -} - + return 0; +} + static inline int blake2b_clear_lastblock( blake2b_state *S ) -{ - if( S->last_node ) blake2b_clear_lastnode( S ); - +{ + if( S->last_node ) blake2b_clear_lastnode( S ); + S->f[0] = 0ULL; - return 0; -} - - + return 0; +} + + static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) -{ +{ #if defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__)) // ADD/ADC chain - __uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0]; - t += inc; - S->t[0] = ( uint64_t )( t >> 0 ); - S->t[1] = ( uint64_t )( t >> 64 ); -#else - S->t[0] += inc; - S->t[1] += ( S->t[0] < inc ); -#endif - return 0; -} - - + __uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0]; + t += inc; + S->t[0] = ( uint64_t )( t >> 0 ); + S->t[1] = ( uint64_t )( t >> 64 ); +#else + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +#endif + return 0; +} + + // Parameter-related functions static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length ) -{ - P->digest_length = digest_length; - return 0; -} - +{ + P->digest_length = digest_length; + return 0; +} + static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) -{ - P->fanout = fanout; - return 0; -} - +{ + P->fanout = fanout; + return 0; +} + static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth ) -{ - P->depth = depth; - return 0; -} - +{ + P->depth = depth; + return 0; +} + static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) -{ - P->leaf_length = leaf_length; - return 0; -} - +{ + P->leaf_length = leaf_length; + return 0; +} + static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset ) -{ - P->node_offset = node_offset; - return 0; -} - +{ + P->node_offset = node_offset; + return 0; +} + static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) -{ - P->node_depth = node_depth; - return 0; -} - +{ + P->node_depth = node_depth; + return 0; +} + static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length ) -{ - P->inner_length = inner_length; - return 0; -} - +{ + P->inner_length = inner_length; + return 0; +} + static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) -{ - memcpy( P->salt, salt, BLAKE2B_SALTBYTES ); - return 0; -} - +{ + memcpy( P->salt, salt, BLAKE2B_SALTBYTES ); + return 0; +} + static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] ) -{ - memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); - return 0; -} - +{ + memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); + return 0; +} + static inline int blake2b_init0( blake2b_state *S ) -{ - memset( S, 0, sizeof( blake2b_state ) ); - +{ + memset( S, 0, sizeof( blake2b_state ) ); + for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; - - return 0; -} - + + return 0; +} + #if defined(__cplusplus) @@ -202,235 +202,235 @@ extern "C" { } #endif -/* init xors IV with input parameter block */ -int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) -{ +/* init xors IV with input parameter block */ +int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ uint8_t *p, *h, *v; //blake2b_init0( S ); v = ( uint8_t * )( blake2b_IV ); h = ( uint8_t * )( S->h ); p = ( uint8_t * )( P ); - /* IV XOR ParamBlock */ - memset( S, 0, sizeof( blake2b_state ) ); - + /* IV XOR ParamBlock */ + memset( S, 0, sizeof( blake2b_state ) ); + for( int i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; - + S->outlen = P->digest_length; - return 0; -} - - -/* Some sort of default parameter block initialization, for sequential blake2b */ + return 0; +} + + +/* Some sort of default parameter block initialization, for sequential blake2b */ int blake2b_init( blake2b_state *S, size_t outlen ) -{ +{ if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - const blake2b_param P = - { + const blake2b_param P = + { ( uint8_t ) outlen, - 0, - 1, - 1, - 0, - 0, - 0, - 0, - {0}, - {0}, - {0} - }; + 0, + 1, + 1, + 0, + 0, + 0, + 0, + {0}, + {0}, + {0} + }; return blake2b_init_param( S, &P ); } - + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) { - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; - - const blake2b_param P = - { + + const blake2b_param P = + { ( uint8_t ) outlen, ( uint8_t ) keylen, - 1, - 1, - 0, - 0, - 0, - 0, - {0}, - {0}, - {0} - }; - - if( blake2b_init_param( S, &P ) < 0 ) - return 0; - - { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset( block, 0, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); - secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - + 1, + 1, + 0, + 0, + 0, + 0, + {0}, + {0}, + {0} + }; + + if( blake2b_init_param( S, &P ) < 0 ) + return 0; + + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + static inline int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) -{ - __m128i row1l, row1h; - __m128i row2l, row2h; - __m128i row3l, row3h; - __m128i row4l, row4h; - __m128i b0, b1; - __m128i t0, t1; -#if defined(HAVE_SSSE3) && !defined(HAVE_XOP) - const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 ); - const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 ); -#endif +{ + __m128i row1l, row1h; + __m128i row2l, row2h; + __m128i row3l, row3h; + __m128i row4l, row4h; + __m128i b0, b1; + __m128i t0, t1; +#if defined(HAVE_SSSE3) && !defined(HAVE_XOP) + const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 ); + const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 ); +#endif #if defined(HAVE_SSE4_1) - const __m128i m0 = LOADU( block + 00 ); - const __m128i m1 = LOADU( block + 16 ); - const __m128i m2 = LOADU( block + 32 ); - const __m128i m3 = LOADU( block + 48 ); - const __m128i m4 = LOADU( block + 64 ); - const __m128i m5 = LOADU( block + 80 ); - const __m128i m6 = LOADU( block + 96 ); - const __m128i m7 = LOADU( block + 112 ); -#else - const uint64_t m0 = ( ( uint64_t * )block )[ 0]; - const uint64_t m1 = ( ( uint64_t * )block )[ 1]; - const uint64_t m2 = ( ( uint64_t * )block )[ 2]; - const uint64_t m3 = ( ( uint64_t * )block )[ 3]; - const uint64_t m4 = ( ( uint64_t * )block )[ 4]; - const uint64_t m5 = ( ( uint64_t * )block )[ 5]; - const uint64_t m6 = ( ( uint64_t * )block )[ 6]; - const uint64_t m7 = ( ( uint64_t * )block )[ 7]; - const uint64_t m8 = ( ( uint64_t * )block )[ 8]; - const uint64_t m9 = ( ( uint64_t * )block )[ 9]; - const uint64_t m10 = ( ( uint64_t * )block )[10]; - const uint64_t m11 = ( ( uint64_t * )block )[11]; - const uint64_t m12 = ( ( uint64_t * )block )[12]; - const uint64_t m13 = ( ( uint64_t * )block )[13]; - const uint64_t m14 = ( ( uint64_t * )block )[14]; - const uint64_t m15 = ( ( uint64_t * )block )[15]; -#endif - row1l = LOADU( &S->h[0] ); - row1h = LOADU( &S->h[2] ); - row2l = LOADU( &S->h[4] ); - row2h = LOADU( &S->h[6] ); - row3l = LOADU( &blake2b_IV[0] ); - row3h = LOADU( &blake2b_IV[2] ); - row4l = _mm_xor_si128( LOADU( &blake2b_IV[4] ), LOADU( &S->t[0] ) ); - row4h = _mm_xor_si128( LOADU( &blake2b_IV[6] ), LOADU( &S->f[0] ) ); - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - ROUND( 10 ); - ROUND( 11 ); - row1l = _mm_xor_si128( row3l, row1l ); - row1h = _mm_xor_si128( row3h, row1h ); - STOREU( &S->h[0], _mm_xor_si128( LOADU( &S->h[0] ), row1l ) ); - STOREU( &S->h[2], _mm_xor_si128( LOADU( &S->h[2] ), row1h ) ); - row2l = _mm_xor_si128( row4l, row2l ); - row2h = _mm_xor_si128( row4h, row2h ); - STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) ); - STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) ); - return 0; -} - - + const __m128i m0 = LOADU( block + 00 ); + const __m128i m1 = LOADU( block + 16 ); + const __m128i m2 = LOADU( block + 32 ); + const __m128i m3 = LOADU( block + 48 ); + const __m128i m4 = LOADU( block + 64 ); + const __m128i m5 = LOADU( block + 80 ); + const __m128i m6 = LOADU( block + 96 ); + const __m128i m7 = LOADU( block + 112 ); +#else + const uint64_t m0 = ( ( uint64_t * )block )[ 0]; + const uint64_t m1 = ( ( uint64_t * )block )[ 1]; + const uint64_t m2 = ( ( uint64_t * )block )[ 2]; + const uint64_t m3 = ( ( uint64_t * )block )[ 3]; + const uint64_t m4 = ( ( uint64_t * )block )[ 4]; + const uint64_t m5 = ( ( uint64_t * )block )[ 5]; + const uint64_t m6 = ( ( uint64_t * )block )[ 6]; + const uint64_t m7 = ( ( uint64_t * )block )[ 7]; + const uint64_t m8 = ( ( uint64_t * )block )[ 8]; + const uint64_t m9 = ( ( uint64_t * )block )[ 9]; + const uint64_t m10 = ( ( uint64_t * )block )[10]; + const uint64_t m11 = ( ( uint64_t * )block )[11]; + const uint64_t m12 = ( ( uint64_t * )block )[12]; + const uint64_t m13 = ( ( uint64_t * )block )[13]; + const uint64_t m14 = ( ( uint64_t * )block )[14]; + const uint64_t m15 = ( ( uint64_t * )block )[15]; +#endif + row1l = LOADU( &S->h[0] ); + row1h = LOADU( &S->h[2] ); + row2l = LOADU( &S->h[4] ); + row2h = LOADU( &S->h[6] ); + row3l = LOADU( &blake2b_IV[0] ); + row3h = LOADU( &blake2b_IV[2] ); + row4l = _mm_xor_si128( LOADU( &blake2b_IV[4] ), LOADU( &S->t[0] ) ); + row4h = _mm_xor_si128( LOADU( &blake2b_IV[6] ), LOADU( &S->f[0] ) ); + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + row1l = _mm_xor_si128( row3l, row1l ); + row1h = _mm_xor_si128( row3h, row1h ); + STOREU( &S->h[0], _mm_xor_si128( LOADU( &S->h[0] ), row1l ) ); + STOREU( &S->h[2], _mm_xor_si128( LOADU( &S->h[2] ), row1h ) ); + row2l = _mm_xor_si128( row4l, row2l ); + row2h = _mm_xor_si128( row4h, row2h ); + STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) ); + STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) ); + return 0; +} + + int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) -{ - while( inlen > 0 ) - { +{ + while( inlen > 0 ) + { uint32_t left = S->buflen; uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left; - - if( inlen > fill ) - { + + if( inlen > fill ) + { memcpy( S->buf + left, in, fill ); // Fill buffer - S->buflen += fill; - blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + S->buflen += fill; + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); // Compress memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left - S->buflen -= BLAKE2B_BLOCKBYTES; - in += fill; - inlen -= fill; - } + S->buflen -= BLAKE2B_BLOCKBYTES; + in += fill; + inlen -= fill; + } else // inlen <= fill - { - memcpy( S->buf + left, in, inlen ); + { + memcpy( S->buf + left, in, inlen ); S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress - in += inlen; - inlen -= inlen; - } - } - - return 0; -} - - + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + + int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ) -{ +{ if(S->outlen != outlen) return -1; - - if( S->buflen > BLAKE2B_BLOCKBYTES ) - { - blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - blake2b_compress( S, S->buf ); - S->buflen -= BLAKE2B_BLOCKBYTES; + + if( S->buflen > BLAKE2B_BLOCKBYTES ) + { + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); + S->buflen -= BLAKE2B_BLOCKBYTES; memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); - } - - blake2b_increment_counter( S, S->buflen ); - blake2b_set_lastblock( S ); - memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ - blake2b_compress( S, S->buf ); - memcpy( out, &S->h[0], outlen ); - return 0; -} - - + } + + blake2b_increment_counter( S, S->buflen ); + blake2b_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ + blake2b_compress( S, S->buf ); + memcpy( out, &S->h[0], outlen ); + return 0; +} + + int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - blake2b_state S[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if( NULL == key && keylen > 0 ) return -1; - - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - if( keylen > BLAKE2B_KEYBYTES ) return -1; - - if( keylen ) - { - if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; - } - else - { - if( blake2b_init( S, outlen ) < 0 ) return -1; - } - +{ + blake2b_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if( NULL == key && keylen > 0 ) return -1; + + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + if( keylen > BLAKE2B_KEYBYTES ) return -1; + + if( keylen ) + { + if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2b_init( S, outlen ) < 0 ) return -1; + } + if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0) return -1; return blake2b_final( S, out, outlen ); -} - -#if defined(SUPERCOP) -int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) -{ - return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 ); -} -#endif +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 ); +} +#endif diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-sse2.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-sse2.h index b24483cf931..bdd8fe25c94 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-sse2.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-sse2.h @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,51 +9,51 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2S_LOAD_SSE2_H__ -#define __BLAKE2S_LOAD_SSE2_H__ - -#define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0) -#define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1) -#define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m14,m12,m10,m8) -#define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m15,m13,m11,m9) -#define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14) -#define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10) -#define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m5,m11,m0,m1) -#define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m3,m7,m2,m12) -#define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11) -#define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8) -#define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m9,m7,m3,m10) -#define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m4,m1,m6,m14) -#define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7) -#define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9) -#define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m15,m4,m5,m2) -#define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m8,m0,m10,m6) -#define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9) -#define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0) -#define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m3,m6,m11,m14) -#define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m13,m8,m12,m1) -#define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2) -#define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12) -#define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m1,m15,m7,m4) -#define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m9,m14,m5,m13) -#define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12) -#define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5) -#define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m8,m9,m6,m0) -#define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m11,m2,m3,m7) -#define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13) -#define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11) -#define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m2,m8,m15,m5) -#define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m10,m6,m4,m0) -#define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6) -#define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15) -#define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m10,m1,m13,m12) -#define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m5,m4,m7,m2) -#define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10) -#define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2) -#define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m13,m3,m9,m15) -#define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m0,m12,m14,m11) - - -#endif +*/ +#pragma once +#ifndef __BLAKE2S_LOAD_SSE2_H__ +#define __BLAKE2S_LOAD_SSE2_H__ + +#define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0) +#define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1) +#define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m14,m12,m10,m8) +#define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m15,m13,m11,m9) +#define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14) +#define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10) +#define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m5,m11,m0,m1) +#define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m3,m7,m2,m12) +#define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11) +#define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8) +#define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m9,m7,m3,m10) +#define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m4,m1,m6,m14) +#define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7) +#define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9) +#define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m15,m4,m5,m2) +#define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m8,m0,m10,m6) +#define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9) +#define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0) +#define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m3,m6,m11,m14) +#define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m13,m8,m12,m1) +#define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2) +#define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12) +#define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m1,m15,m7,m4) +#define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m9,m14,m5,m13) +#define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12) +#define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5) +#define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m8,m9,m6,m0) +#define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m11,m2,m3,m7) +#define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13) +#define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11) +#define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m2,m8,m15,m5) +#define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m10,m6,m4,m0) +#define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6) +#define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15) +#define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m10,m1,m13,m12) +#define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m5,m4,m7,m2) +#define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10) +#define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2) +#define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m13,m3,m9,m15) +#define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m0,m12,m14,m11) + + +#endif diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-sse41.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-sse41.h index 3ac12eb6f5d..83385750ed7 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-sse41.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-sse41.h @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,221 +9,221 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2S_LOAD_SSE41_H__ -#define __BLAKE2S_LOAD_SSE41_H__ - -#define LOAD_MSG_0_1(buf) \ -buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0))); - -#define LOAD_MSG_0_2(buf) \ -buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1))); - -#define LOAD_MSG_0_3(buf) \ -buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(2,0,2,0))); - -#define LOAD_MSG_0_4(buf) \ -buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(3,1,3,1))); - -#define LOAD_MSG_1_1(buf) \ -t0 = _mm_blend_epi16(m1, m2, 0x0C); \ -t1 = _mm_slli_si128(m3, 4); \ -t2 = _mm_blend_epi16(t0, t1, 0xF0); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); - -#define LOAD_MSG_1_2(buf) \ -t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \ -t1 = _mm_blend_epi16(m1,m3,0xC0); \ -t2 = _mm_blend_epi16(t0, t1, 0xF0); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); - -#define LOAD_MSG_1_3(buf) \ -t0 = _mm_slli_si128(m1, 4); \ -t1 = _mm_blend_epi16(m2, t0, 0x30); \ -t2 = _mm_blend_epi16(m0, t1, 0xF0); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); - -#define LOAD_MSG_1_4(buf) \ -t0 = _mm_unpackhi_epi32(m0,m1); \ -t1 = _mm_slli_si128(m3, 4); \ -t2 = _mm_blend_epi16(t0, t1, 0x0C); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); - -#define LOAD_MSG_2_1(buf) \ -t0 = _mm_unpackhi_epi32(m2,m3); \ -t1 = _mm_blend_epi16(m3,m1,0x0C); \ -t2 = _mm_blend_epi16(t0, t1, 0x0F); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); - -#define LOAD_MSG_2_2(buf) \ -t0 = _mm_unpacklo_epi32(m2,m0); \ -t1 = _mm_blend_epi16(t0, m0, 0xF0); \ -t2 = _mm_slli_si128(m3, 8); \ -buf = _mm_blend_epi16(t1, t2, 0xC0); - -#define LOAD_MSG_2_3(buf) \ -t0 = _mm_blend_epi16(m0, m2, 0x3C); \ -t1 = _mm_srli_si128(m1, 12); \ -t2 = _mm_blend_epi16(t0,t1,0x03); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,3,2)); - -#define LOAD_MSG_2_4(buf) \ -t0 = _mm_slli_si128(m3, 4); \ -t1 = _mm_blend_epi16(m0, m1, 0x33); \ -t2 = _mm_blend_epi16(t1, t0, 0xC0); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,1,2,3)); - -#define LOAD_MSG_3_1(buf) \ -t0 = _mm_unpackhi_epi32(m0,m1); \ -t1 = _mm_unpackhi_epi32(t0, m2); \ -t2 = _mm_blend_epi16(t1, m3, 0x0C); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); - -#define LOAD_MSG_3_2(buf) \ -t0 = _mm_slli_si128(m2, 8); \ -t1 = _mm_blend_epi16(m3,m0,0x0C); \ -t2 = _mm_blend_epi16(t1, t0, 0xC0); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); - -#define LOAD_MSG_3_3(buf) \ -t0 = _mm_blend_epi16(m0,m1,0x0F); \ -t1 = _mm_blend_epi16(t0, m3, 0xC0); \ -buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); - -#define LOAD_MSG_3_4(buf) \ -t0 = _mm_unpacklo_epi32(m0,m2); \ -t1 = _mm_unpackhi_epi32(m1,m2); \ -buf = _mm_unpacklo_epi64(t1,t0); - -#define LOAD_MSG_4_1(buf) \ -t0 = _mm_unpacklo_epi64(m1,m2); \ -t1 = _mm_unpackhi_epi64(m0,m2); \ -t2 = _mm_blend_epi16(t0,t1,0x33); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); - -#define LOAD_MSG_4_2(buf) \ -t0 = _mm_unpackhi_epi64(m1,m3); \ -t1 = _mm_unpacklo_epi64(m0,m1); \ -buf = _mm_blend_epi16(t0,t1,0x33); - -#define LOAD_MSG_4_3(buf) \ -t0 = _mm_unpackhi_epi64(m3,m1); \ -t1 = _mm_unpackhi_epi64(m2,m0); \ -buf = _mm_blend_epi16(t1,t0,0x33); - -#define LOAD_MSG_4_4(buf) \ -t0 = _mm_blend_epi16(m0,m2,0x03); \ -t1 = _mm_slli_si128(t0, 8); \ -t2 = _mm_blend_epi16(t1,m3,0x0F); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,0,3)); - -#define LOAD_MSG_5_1(buf) \ -t0 = _mm_unpackhi_epi32(m0,m1); \ -t1 = _mm_unpacklo_epi32(m0,m2); \ -buf = _mm_unpacklo_epi64(t0,t1); - -#define LOAD_MSG_5_2(buf) \ -t0 = _mm_srli_si128(m2, 4); \ -t1 = _mm_blend_epi16(m0,m3,0x03); \ -buf = _mm_blend_epi16(t1,t0,0x3C); - -#define LOAD_MSG_5_3(buf) \ -t0 = _mm_blend_epi16(m1,m0,0x0C); \ -t1 = _mm_srli_si128(m3, 4); \ -t2 = _mm_blend_epi16(t0,t1,0x30); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0)); - -#define LOAD_MSG_5_4(buf) \ -t0 = _mm_unpacklo_epi64(m1,m2); \ -t1= _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,2,0,1)); \ -buf = _mm_blend_epi16(t0,t1,0x33); - -#define LOAD_MSG_6_1(buf) \ -t0 = _mm_slli_si128(m1, 12); \ -t1 = _mm_blend_epi16(m0,m3,0x33); \ -buf = _mm_blend_epi16(t1,t0,0xC0); - -#define LOAD_MSG_6_2(buf) \ -t0 = _mm_blend_epi16(m3,m2,0x30); \ -t1 = _mm_srli_si128(m1, 4); \ -t2 = _mm_blend_epi16(t0,t1,0x03); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0)); - -#define LOAD_MSG_6_3(buf) \ -t0 = _mm_unpacklo_epi64(m0,m2); \ -t1 = _mm_srli_si128(m1, 4); \ -buf = _mm_shuffle_epi32(_mm_blend_epi16(t0,t1,0x0C), _MM_SHUFFLE(2,3,1,0)); - -#define LOAD_MSG_6_4(buf) \ -t0 = _mm_unpackhi_epi32(m1,m2); \ -t1 = _mm_unpackhi_epi64(m0,t0); \ -buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); - -#define LOAD_MSG_7_1(buf) \ -t0 = _mm_unpackhi_epi32(m0,m1); \ -t1 = _mm_blend_epi16(t0,m3,0x0F); \ -buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1)); - -#define LOAD_MSG_7_2(buf) \ -t0 = _mm_blend_epi16(m2,m3,0x30); \ -t1 = _mm_srli_si128(m0,4); \ -t2 = _mm_blend_epi16(t0,t1,0x03); \ -buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3)); - -#define LOAD_MSG_7_3(buf) \ -t0 = _mm_unpackhi_epi64(m0,m3); \ -t1 = _mm_unpacklo_epi64(m1,m2); \ -t2 = _mm_blend_epi16(t0,t1,0x3C); \ -buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,3,1)); - -#define LOAD_MSG_7_4(buf) \ -t0 = _mm_unpacklo_epi32(m0,m1); \ -t1 = _mm_unpackhi_epi32(m1,m2); \ -buf = _mm_unpacklo_epi64(t0,t1); - -#define LOAD_MSG_8_1(buf) \ -t0 = _mm_unpackhi_epi32(m1,m3); \ -t1 = _mm_unpacklo_epi64(t0,m0); \ -t2 = _mm_blend_epi16(t1,m2,0xC0); \ -buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2)); - -#define LOAD_MSG_8_2(buf) \ -t0 = _mm_unpackhi_epi32(m0,m3); \ -t1 = _mm_blend_epi16(m2,t0,0xF0); \ -buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3)); - -#define LOAD_MSG_8_3(buf) \ -t0 = _mm_blend_epi16(m2,m0,0x0C); \ -t1 = _mm_slli_si128(t0,4); \ -buf = _mm_blend_epi16(t1,m3,0x0F); - -#define LOAD_MSG_8_4(buf) \ -t0 = _mm_blend_epi16(m1,m0,0x30); \ -buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(1,0,3,2)); - -#define LOAD_MSG_9_1(buf) \ -t0 = _mm_blend_epi16(m0,m2,0x03); \ -t1 = _mm_blend_epi16(m1,m2,0x30); \ -t2 = _mm_blend_epi16(t1,t0,0x0F); \ -buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2)); - -#define LOAD_MSG_9_2(buf) \ -t0 = _mm_slli_si128(m0,4); \ -t1 = _mm_blend_epi16(m1,t0,0xC0); \ -buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3)); - -#define LOAD_MSG_9_3(buf) \ -t0 = _mm_unpackhi_epi32(m0,m3); \ -t1 = _mm_unpacklo_epi32(m2,m3); \ -t2 = _mm_unpackhi_epi64(t0,t1); \ -buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(3,0,2,1)); - -#define LOAD_MSG_9_4(buf) \ -t0 = _mm_blend_epi16(m3,m2,0xC0); \ -t1 = _mm_unpacklo_epi32(m0,m3); \ -t2 = _mm_blend_epi16(t0,t1,0x0F); \ -buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3)); - -#endif - +*/ +#pragma once +#ifndef __BLAKE2S_LOAD_SSE41_H__ +#define __BLAKE2S_LOAD_SSE41_H__ + +#define LOAD_MSG_0_1(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0))); + +#define LOAD_MSG_0_2(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1))); + +#define LOAD_MSG_0_3(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(2,0,2,0))); + +#define LOAD_MSG_0_4(buf) \ +buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(3,1,3,1))); + +#define LOAD_MSG_1_1(buf) \ +t0 = _mm_blend_epi16(m1, m2, 0x0C); \ +t1 = _mm_slli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); + +#define LOAD_MSG_1_2(buf) \ +t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \ +t1 = _mm_blend_epi16(m1,m3,0xC0); \ +t2 = _mm_blend_epi16(t0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_1_3(buf) \ +t0 = _mm_slli_si128(m1, 4); \ +t1 = _mm_blend_epi16(m2, t0, 0x30); \ +t2 = _mm_blend_epi16(m0, t1, 0xF0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_1_4(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_slli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0, t1, 0x0C); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); + +#define LOAD_MSG_2_1(buf) \ +t0 = _mm_unpackhi_epi32(m2,m3); \ +t1 = _mm_blend_epi16(m3,m1,0x0C); \ +t2 = _mm_blend_epi16(t0, t1, 0x0F); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + +#define LOAD_MSG_2_2(buf) \ +t0 = _mm_unpacklo_epi32(m2,m0); \ +t1 = _mm_blend_epi16(t0, m0, 0xF0); \ +t2 = _mm_slli_si128(m3, 8); \ +buf = _mm_blend_epi16(t1, t2, 0xC0); + +#define LOAD_MSG_2_3(buf) \ +t0 = _mm_blend_epi16(m0, m2, 0x3C); \ +t1 = _mm_srli_si128(m1, 12); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,3,2)); + +#define LOAD_MSG_2_4(buf) \ +t0 = _mm_slli_si128(m3, 4); \ +t1 = _mm_blend_epi16(m0, m1, 0x33); \ +t2 = _mm_blend_epi16(t1, t0, 0xC0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,1,2,3)); + +#define LOAD_MSG_3_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_unpackhi_epi32(t0, m2); \ +t2 = _mm_blend_epi16(t1, m3, 0x0C); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); + +#define LOAD_MSG_3_2(buf) \ +t0 = _mm_slli_si128(m2, 8); \ +t1 = _mm_blend_epi16(m3,m0,0x0C); \ +t2 = _mm_blend_epi16(t1, t0, 0xC0); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); + +#define LOAD_MSG_3_3(buf) \ +t0 = _mm_blend_epi16(m0,m1,0x0F); \ +t1 = _mm_blend_epi16(t0, m3, 0xC0); \ +buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); + +#define LOAD_MSG_3_4(buf) \ +t0 = _mm_unpacklo_epi32(m0,m2); \ +t1 = _mm_unpackhi_epi32(m1,m2); \ +buf = _mm_unpacklo_epi64(t1,t0); + +#define LOAD_MSG_4_1(buf) \ +t0 = _mm_unpacklo_epi64(m1,m2); \ +t1 = _mm_unpackhi_epi64(m0,m2); \ +t2 = _mm_blend_epi16(t0,t1,0x33); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); + +#define LOAD_MSG_4_2(buf) \ +t0 = _mm_unpackhi_epi64(m1,m3); \ +t1 = _mm_unpacklo_epi64(m0,m1); \ +buf = _mm_blend_epi16(t0,t1,0x33); + +#define LOAD_MSG_4_3(buf) \ +t0 = _mm_unpackhi_epi64(m3,m1); \ +t1 = _mm_unpackhi_epi64(m2,m0); \ +buf = _mm_blend_epi16(t1,t0,0x33); + +#define LOAD_MSG_4_4(buf) \ +t0 = _mm_blend_epi16(m0,m2,0x03); \ +t1 = _mm_slli_si128(t0, 8); \ +t2 = _mm_blend_epi16(t1,m3,0x0F); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,0,3)); + +#define LOAD_MSG_5_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_unpacklo_epi32(m0,m2); \ +buf = _mm_unpacklo_epi64(t0,t1); + +#define LOAD_MSG_5_2(buf) \ +t0 = _mm_srli_si128(m2, 4); \ +t1 = _mm_blend_epi16(m0,m3,0x03); \ +buf = _mm_blend_epi16(t1,t0,0x3C); + +#define LOAD_MSG_5_3(buf) \ +t0 = _mm_blend_epi16(m1,m0,0x0C); \ +t1 = _mm_srli_si128(m3, 4); \ +t2 = _mm_blend_epi16(t0,t1,0x30); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0)); + +#define LOAD_MSG_5_4(buf) \ +t0 = _mm_unpacklo_epi64(m1,m2); \ +t1= _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,2,0,1)); \ +buf = _mm_blend_epi16(t0,t1,0x33); + +#define LOAD_MSG_6_1(buf) \ +t0 = _mm_slli_si128(m1, 12); \ +t1 = _mm_blend_epi16(m0,m3,0x33); \ +buf = _mm_blend_epi16(t1,t0,0xC0); + +#define LOAD_MSG_6_2(buf) \ +t0 = _mm_blend_epi16(m3,m2,0x30); \ +t1 = _mm_srli_si128(m1, 4); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0)); + +#define LOAD_MSG_6_3(buf) \ +t0 = _mm_unpacklo_epi64(m0,m2); \ +t1 = _mm_srli_si128(m1, 4); \ +buf = _mm_shuffle_epi32(_mm_blend_epi16(t0,t1,0x0C), _MM_SHUFFLE(2,3,1,0)); + +#define LOAD_MSG_6_4(buf) \ +t0 = _mm_unpackhi_epi32(m1,m2); \ +t1 = _mm_unpackhi_epi64(m0,t0); \ +buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); + +#define LOAD_MSG_7_1(buf) \ +t0 = _mm_unpackhi_epi32(m0,m1); \ +t1 = _mm_blend_epi16(t0,m3,0x0F); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1)); + +#define LOAD_MSG_7_2(buf) \ +t0 = _mm_blend_epi16(m2,m3,0x30); \ +t1 = _mm_srli_si128(m0,4); \ +t2 = _mm_blend_epi16(t0,t1,0x03); \ +buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3)); + +#define LOAD_MSG_7_3(buf) \ +t0 = _mm_unpackhi_epi64(m0,m3); \ +t1 = _mm_unpacklo_epi64(m1,m2); \ +t2 = _mm_blend_epi16(t0,t1,0x3C); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,3,1)); + +#define LOAD_MSG_7_4(buf) \ +t0 = _mm_unpacklo_epi32(m0,m1); \ +t1 = _mm_unpackhi_epi32(m1,m2); \ +buf = _mm_unpacklo_epi64(t0,t1); + +#define LOAD_MSG_8_1(buf) \ +t0 = _mm_unpackhi_epi32(m1,m3); \ +t1 = _mm_unpacklo_epi64(t0,m0); \ +t2 = _mm_blend_epi16(t1,m2,0xC0); \ +buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2)); + +#define LOAD_MSG_8_2(buf) \ +t0 = _mm_unpackhi_epi32(m0,m3); \ +t1 = _mm_blend_epi16(m2,t0,0xF0); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3)); + +#define LOAD_MSG_8_3(buf) \ +t0 = _mm_blend_epi16(m2,m0,0x0C); \ +t1 = _mm_slli_si128(t0,4); \ +buf = _mm_blend_epi16(t1,m3,0x0F); + +#define LOAD_MSG_8_4(buf) \ +t0 = _mm_blend_epi16(m1,m0,0x30); \ +buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(1,0,3,2)); + +#define LOAD_MSG_9_1(buf) \ +t0 = _mm_blend_epi16(m0,m2,0x03); \ +t1 = _mm_blend_epi16(m1,m2,0x30); \ +t2 = _mm_blend_epi16(t1,t0,0x0F); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2)); + +#define LOAD_MSG_9_2(buf) \ +t0 = _mm_slli_si128(m0,4); \ +t1 = _mm_blend_epi16(m1,t0,0xC0); \ +buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3)); + +#define LOAD_MSG_9_3(buf) \ +t0 = _mm_unpackhi_epi32(m0,m3); \ +t1 = _mm_unpacklo_epi32(m2,m3); \ +t2 = _mm_unpackhi_epi64(t0,t1); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(3,0,2,1)); + +#define LOAD_MSG_9_4(buf) \ +t0 = _mm_blend_epi16(m3,m2,0xC0); \ +t1 = _mm_unpacklo_epi32(m0,m3); \ +t2 = _mm_blend_epi16(t0,t1,0x0F); \ +buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3)); + +#endif + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-xop.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-xop.h index ac591a77d19..52c289b1c90 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-xop.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-load-xop.h @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,181 +9,181 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2S_LOAD_XOP_H__ -#define __BLAKE2S_LOAD_XOP_H__ - +*/ +#pragma once +#ifndef __BLAKE2S_LOAD_XOP_H__ +#define __BLAKE2S_LOAD_XOP_H__ + #define TOB(x) ((x)*4*0x01010101 + 0x03020100) // ..or not TOB - -/* Basic VPPERM emulation, for testing purposes */ + +/* Basic VPPERM emulation, for testing purposes */ /*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel) -{ - const __m128i sixteen = _mm_set1_epi8(16); - const __m128i t0 = _mm_shuffle_epi8(src1, sel); - const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen)); - const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen), +{ + const __m128i sixteen = _mm_set1_epi8(16); + const __m128i t0 = _mm_shuffle_epi8(src1, sel); + const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen)); + const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen), _mm_cmpgt_epi8(sel, sixteen)); // (>=16) = 0xff : 00 - return _mm_blendv_epi8(t0, s1, mask); + return _mm_blendv_epi8(t0, s1, mask); }*/ - -#define LOAD_MSG_0_1(buf) \ -buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); - -#define LOAD_MSG_0_2(buf) \ -buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); - -#define LOAD_MSG_0_3(buf) \ -buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); - -#define LOAD_MSG_0_4(buf) \ -buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); - -#define LOAD_MSG_1_1(buf) \ -t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(5),TOB(0),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); - -#define LOAD_MSG_1_2(buf) \ -t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(2),TOB(0),TOB(4),TOB(6)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); - -#define LOAD_MSG_1_3(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(0),TOB(0),TOB(1)) ); \ -buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); - -#define LOAD_MSG_1_4(buf) \ -t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(7),TOB(2),TOB(0)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); - -#define LOAD_MSG_2_1(buf) \ -t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(1),TOB(0),TOB(7)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(4),TOB(0)) ); - -#define LOAD_MSG_2_2(buf) \ -t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(2),TOB(0),TOB(4)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(0)) ); - -#define LOAD_MSG_2_3(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(7),TOB(3),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); - -#define LOAD_MSG_2_4(buf) \ -t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(1),TOB(6),TOB(0)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); - -#define LOAD_MSG_3_1(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(3),TOB(7)) ); \ -t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(1),TOB(0)) ); - -#define LOAD_MSG_3_2(buf) \ -t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(1),TOB(5)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(1),TOB(0)) ); - -#define LOAD_MSG_3_3(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(5),TOB(2)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); - -#define LOAD_MSG_3_4(buf) \ -t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ -buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(6),TOB(0)) ); - -#define LOAD_MSG_4_1(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(5),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(5)) ); - -#define LOAD_MSG_4_2(buf) \ -t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(7),TOB(0)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); - -#define LOAD_MSG_4_3(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(6),TOB(0),TOB(0)) ); \ -t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); - -#define LOAD_MSG_4_4(buf) \ -t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(4),TOB(0),TOB(1)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(4),TOB(0)) ); - -#define LOAD_MSG_5_1(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(2)) ); \ -buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(1),TOB(0)) ); - -#define LOAD_MSG_5_2(buf) \ -t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(6),TOB(0)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); - -#define LOAD_MSG_5_3(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(0),TOB(7),TOB(4)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); - -#define LOAD_MSG_5_4(buf) \ -t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(5),TOB(0),TOB(1),TOB(0)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(5)) ); - -#define LOAD_MSG_6_1(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(0),TOB(1),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(4)) ); - -#define LOAD_MSG_6_2(buf) \ -t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(6),TOB(0),TOB(0),TOB(1)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(7),TOB(0)) ); - -#define LOAD_MSG_6_3(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(5),TOB(1),TOB(0)) ); - -#define LOAD_MSG_6_4(buf) \ -t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(3),TOB(7)) ); \ -buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); - -#define LOAD_MSG_7_1(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(0),TOB(7),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(5)) ); - -#define LOAD_MSG_7_2(buf) \ -t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(5),TOB(1),TOB(0),TOB(7)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); - -#define LOAD_MSG_7_3(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(2),TOB(0),TOB(0),TOB(5)) ); \ -t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); - -#define LOAD_MSG_7_4(buf) \ -t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(6),TOB(4),TOB(0)) ); \ -buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(0)) ); - -#define LOAD_MSG_8_1(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ -t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); - -#define LOAD_MSG_8_2(buf) \ -t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(4),TOB(3),TOB(5),TOB(0)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) ); - -#define LOAD_MSG_8_3(buf) \ -t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \ -#define LOAD_MSG_8_4(buf) \ -buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) ); - -#define LOAD_MSG_9_1(buf) \ -t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(7),TOB(0),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(4),TOB(6)) ); - -#define LOAD_MSG_9_2(buf) \ -buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(6),TOB(4),TOB(2)) ); - -#define LOAD_MSG_9_3(buf) \ -t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(3),TOB(5),TOB(0)) ); \ -buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(7)) ); - -#define LOAD_MSG_9_4(buf) \ -t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(7)) ); \ -buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) ); - -#endif - +#define LOAD_MSG_0_1(buf) \ +buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); + +#define LOAD_MSG_0_2(buf) \ +buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); + +#define LOAD_MSG_0_3(buf) \ +buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); + +#define LOAD_MSG_0_4(buf) \ +buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); + +#define LOAD_MSG_1_1(buf) \ +t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(5),TOB(0),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); + +#define LOAD_MSG_1_2(buf) \ +t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(2),TOB(0),TOB(4),TOB(6)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); + +#define LOAD_MSG_1_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(0),TOB(0),TOB(1)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); + +#define LOAD_MSG_1_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(7),TOB(2),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); + +#define LOAD_MSG_2_1(buf) \ +t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(1),TOB(0),TOB(7)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(4),TOB(0)) ); + +#define LOAD_MSG_2_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(2),TOB(0),TOB(4)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_2_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(7),TOB(3),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); + +#define LOAD_MSG_2_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(1),TOB(6),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); + +#define LOAD_MSG_3_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(3),TOB(7)) ); \ +t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(1),TOB(0)) ); + +#define LOAD_MSG_3_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(1),TOB(5)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(1),TOB(0)) ); + +#define LOAD_MSG_3_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(5),TOB(2)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_3_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ +buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(6),TOB(0)) ); + +#define LOAD_MSG_4_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(5),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(5)) ); + +#define LOAD_MSG_4_2(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(7),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_4_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(6),TOB(0),TOB(0)) ); \ +t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); + +#define LOAD_MSG_4_4(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(4),TOB(0),TOB(1)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(4),TOB(0)) ); + +#define LOAD_MSG_5_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(2)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_5_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(6),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); + +#define LOAD_MSG_5_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(0),TOB(7),TOB(4)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); + +#define LOAD_MSG_5_4(buf) \ +t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(5),TOB(0),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(5)) ); + +#define LOAD_MSG_6_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(0),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(4)) ); + +#define LOAD_MSG_6_2(buf) \ +t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(6),TOB(0),TOB(0),TOB(1)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(7),TOB(0)) ); + +#define LOAD_MSG_6_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(5),TOB(1),TOB(0)) ); + +#define LOAD_MSG_6_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(3),TOB(7)) ); \ +buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_7_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(0),TOB(7),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(5)) ); + +#define LOAD_MSG_7_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(5),TOB(1),TOB(0),TOB(7)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); + +#define LOAD_MSG_7_3(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(2),TOB(0),TOB(0),TOB(5)) ); \ +t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); + +#define LOAD_MSG_7_4(buf) \ +t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(6),TOB(4),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(0)) ); + +#define LOAD_MSG_8_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ +t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); + +#define LOAD_MSG_8_2(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(4),TOB(3),TOB(5),TOB(0)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) ); + +#define LOAD_MSG_8_3(buf) \ +t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \ + +#define LOAD_MSG_8_4(buf) \ +buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) ); + +#define LOAD_MSG_9_1(buf) \ +t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(7),TOB(0),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(4),TOB(6)) ); + +#define LOAD_MSG_9_2(buf) \ +buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(6),TOB(4),TOB(2)) ); + +#define LOAD_MSG_9_3(buf) \ +t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(3),TOB(5),TOB(0)) ); \ +buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(7)) ); + +#define LOAD_MSG_9_4(buf) \ +t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(7)) ); \ +buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) ); + +#endif + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-ref.c b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-ref.c index ab86cc1b34e..2b3b1b02052 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-ref.c +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-ref.c @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - reference C implementations +/* + BLAKE2 reference source code package - reference C implementations Written in 2012 by Samuel Neves @@ -9,135 +9,135 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ - -#include -#include -#include - -#include "blake2.h" -#include "blake2-impl.h" - -static const uint32_t blake2s_IV[8] = -{ - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL -}; - -static const uint8_t blake2s_sigma[10][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , -}; - +*/ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +static const uint32_t blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8_t blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + static inline int blake2s_set_lastnode( blake2s_state *S ) -{ +{ S->f[1] = ~0U; - return 0; -} - + return 0; +} + static inline int blake2s_clear_lastnode( blake2s_state *S ) -{ +{ S->f[1] = 0U; - return 0; -} - -/* Some helper functions, not necessarily useful */ + return 0; +} + +/* Some helper functions, not necessarily useful */ static inline int blake2s_set_lastblock( blake2s_state *S ) -{ - if( S->last_node ) blake2s_set_lastnode( S ); - +{ + if( S->last_node ) blake2s_set_lastnode( S ); + S->f[0] = ~0U; - return 0; -} - + return 0; +} + static inline int blake2s_clear_lastblock( blake2s_state *S ) -{ - if( S->last_node ) blake2s_clear_lastnode( S ); - +{ + if( S->last_node ) blake2s_clear_lastnode( S ); + S->f[0] = 0U; - return 0; -} - + return 0; +} + static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) -{ - S->t[0] += inc; - S->t[1] += ( S->t[0] < inc ); - return 0; -} - +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); + return 0; +} + // Parameter-related functions static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) -{ - P->digest_length = digest_length; - return 0; -} - +{ + P->digest_length = digest_length; + return 0; +} + static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) -{ - P->fanout = fanout; - return 0; -} - +{ + P->fanout = fanout; + return 0; +} + static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) -{ - P->depth = depth; - return 0; -} - +{ + P->depth = depth; + return 0; +} + static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) -{ - store32( &P->leaf_length, leaf_length ); - return 0; -} - +{ + store32( &P->leaf_length, leaf_length ); + return 0; +} + static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) -{ - store48( P->node_offset, node_offset ); - return 0; -} - +{ + store48( P->node_offset, node_offset ); + return 0; +} + static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) -{ - P->node_depth = node_depth; - return 0; -} - +{ + P->node_depth = node_depth; + return 0; +} + static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) -{ - P->inner_length = inner_length; - return 0; -} - +{ + P->inner_length = inner_length; + return 0; +} + static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) -{ - memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); - return 0; -} - +{ + memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); + return 0; +} + static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) -{ - memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); - return 0; -} - +{ + memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); + return 0; +} + static inline int blake2s_init0( blake2s_state *S ) -{ - memset( S, 0, sizeof( blake2s_state ) ); - +{ + memset( S, 0, sizeof( blake2s_state ) ); + for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; - - return 0; -} - + + return 0; +} + #if defined(__cplusplus) extern "C" { #endif @@ -151,218 +151,218 @@ extern "C" { } #endif -/* init2 xors IV with input parameter block */ -int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) -{ - blake2s_init0( S ); +/* init2 xors IV with input parameter block */ +int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + blake2s_init0( S ); uint32_t *p = ( uint32_t * )( P ); - - /* IV XOR ParamBlock */ + + /* IV XOR ParamBlock */ for( size_t i = 0; i < 8; ++i ) - S->h[i] ^= load32( &p[i] ); - + S->h[i] ^= load32( &p[i] ); + S->outlen = P->digest_length; - return 0; -} - - + return 0; +} + + // Sequential blake2s initialization int blake2s_init( blake2s_state *S, size_t outlen ) -{ - blake2s_param P[1]; - - /* Move interval verification here? */ - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - +{ + blake2s_param P[1]; + + /* Move interval verification here? */ + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + P->digest_length = ( uint8_t) outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store48( &P->node_offset, 0 ); - P->node_depth = 0; - P->inner_length = 0; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store48( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; // memset(P->reserved, 0, sizeof(P->reserved) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - return blake2s_init_param( S, P ); -} - + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + return blake2s_init_param( S, P ); +} + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2s_param P[1]; - - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - +{ + blake2s_param P[1]; + + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; + P->digest_length = ( uint8_t ) outlen; P->key_length = ( uint8_t ) keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store48( &P->node_offset, 0 ); - P->node_depth = 0; - P->inner_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store48( &P->node_offset, 0 ); + P->node_depth = 0; + P->inner_length = 0; // memset(P->reserved, 0, sizeof(P->reserved) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - - if( blake2s_init_param( S, P ) < 0 ) return -1; - - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - -static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) -{ - uint32_t m[16]; - uint32_t v[16]; - + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + if( blake2s_init_param( S, P ) < 0 ) return -1; + + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + +static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) +{ + uint32_t m[16]; + uint32_t v[16]; + for( size_t i = 0; i < 16; ++i ) - m[i] = load32( block + i * sizeof( m[i] ) ); - + m[i] = load32( block + i * sizeof( m[i] ) ); + for( size_t i = 0; i < 8; ++i ) - v[i] = S->h[i]; - - v[ 8] = blake2s_IV[0]; - v[ 9] = blake2s_IV[1]; - v[10] = blake2s_IV[2]; - v[11] = blake2s_IV[3]; - v[12] = S->t[0] ^ blake2s_IV[4]; - v[13] = S->t[1] ^ blake2s_IV[5]; - v[14] = S->f[0] ^ blake2s_IV[6]; - v[15] = S->f[1] ^ blake2s_IV[7]; -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2s_sigma[r][2*i+0]]; \ - d = rotr32(d ^ a, 16); \ - c = c + d; \ - b = rotr32(b ^ c, 12); \ - a = a + b + m[blake2s_sigma[r][2*i+1]]; \ - d = rotr32(d ^ a, 8); \ - c = c + d; \ - b = rotr32(b ^ c, 7); \ - } while(0) -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - + v[i] = S->h[i]; + + v[ 8] = blake2s_IV[0]; + v[ 9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = S->t[0] ^ blake2s_IV[4]; + v[13] = S->t[1] ^ blake2s_IV[5]; + v[14] = S->f[0] ^ blake2s_IV[6]; + v[15] = S->f[1] ^ blake2s_IV[7]; +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2*i+0]]; \ + d = rotr32(d ^ a, 16); \ + c = c + d; \ + b = rotr32(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2*i+1]]; \ + d = rotr32(d ^ a, 8); \ + c = c + d; \ + b = rotr32(b ^ c, 7); \ + } while(0) +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + for( size_t i = 0; i < 8; ++i ) - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - -#undef G -#undef ROUND - return 0; -} - - + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + +#undef G +#undef ROUND + return 0; +} + + int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) -{ - while( inlen > 0 ) - { +{ + while( inlen > 0 ) + { uint32_t left = S->buflen; uint32_t fill = 2 * BLAKE2S_BLOCKBYTES - left; - - if( inlen > fill ) - { + + if( inlen > fill ) + { memcpy( S->buf + left, in, fill ); // Fill buffer - S->buflen += fill; - blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + S->buflen += fill; + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S->buf ); // Compress memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left - S->buflen -= BLAKE2S_BLOCKBYTES; - in += fill; - inlen -= fill; - } + S->buflen -= BLAKE2S_BLOCKBYTES; + in += fill; + inlen -= fill; + } else // inlen <= fill - { + { memcpy( S->buf + left, in, inlen ); S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress - in += inlen; - inlen -= inlen; - } - } - - return 0; -} - + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) -{ +{ uint8_t buffer[BLAKE2S_OUTBYTES]; size_t i; - + if(S->outlen != outlen) return -1; - - if( S->buflen > BLAKE2S_BLOCKBYTES ) - { - blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); - S->buflen -= BLAKE2S_BLOCKBYTES; + + if( S->buflen > BLAKE2S_BLOCKBYTES ) + { + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); + S->buflen -= BLAKE2S_BLOCKBYTES; memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); - } - - blake2s_increment_counter( S, ( uint32_t )S->buflen ); - blake2s_set_lastblock( S ); - memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ - blake2s_compress( S, S->buf ); - - for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ - store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - - memcpy( out, buffer, outlen ); - return 0; -} - + } + + blake2s_increment_counter( S, ( uint32_t )S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + return 0; +} + int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - blake2s_state S[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - +{ + blake2s_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + if ( NULL == key && keylen > 0 ) return -1; - - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( keylen > BLAKE2S_KEYBYTES ) return -1; - - if( keylen > 0 ) - { - if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; - } - else - { - if( blake2s_init( S, outlen ) < 0 ) return -1; - } - + + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( keylen > BLAKE2S_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2s_init( S, outlen ) < 0 ) return -1; + } + if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1; return blake2s_final( S, out, outlen ); -} - +} + diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-round.h b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-round.h index 1e2f2b7f59b..8d530a73e32 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-round.h +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s-round.h @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,83 +9,83 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2S_ROUND_H__ -#define __BLAKE2S_ROUND_H__ - +*/ +#pragma once +#ifndef __BLAKE2S_ROUND_H__ +#define __BLAKE2S_ROUND_H__ + #define LOAD(p) _mm_load_si128( (__m128i *)(p) ) #define STORE(p,r) _mm_store_si128((__m128i *)(p), r) #define LOADU(p) _mm_loadu_si128( (__m128i *)(p) ) -#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) - -#define TOF(reg) _mm_castsi128_ps((reg)) -#define TOI(reg) _mm_castps_si128((reg)) - -#define LIKELY(x) __builtin_expect((x),1) - - -/* Microarchitecture-specific macros */ -#ifndef HAVE_XOP -#ifdef HAVE_SSSE3 -#define _mm_roti_epi32(r, c) ( \ - (8==-(c)) ? _mm_shuffle_epi8(r,r8) \ - : (16==-(c)) ? _mm_shuffle_epi8(r,r16) \ - : _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) ) -#else -#define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) -#endif -#else -/* ... */ -#endif - - -#define G1(row1,row2,row3,row4,buf) \ - row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ - row4 = _mm_xor_si128( row4, row1 ); \ - row4 = _mm_roti_epi32(row4, -16); \ - row3 = _mm_add_epi32( row3, row4 ); \ - row2 = _mm_xor_si128( row2, row3 ); \ - row2 = _mm_roti_epi32(row2, -12); - -#define G2(row1,row2,row3,row4,buf) \ - row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ - row4 = _mm_xor_si128( row4, row1 ); \ - row4 = _mm_roti_epi32(row4, -8); \ - row3 = _mm_add_epi32( row3, row4 ); \ - row2 = _mm_xor_si128( row2, row3 ); \ - row2 = _mm_roti_epi32(row2, -7); - -#define DIAGONALIZE(row1,row2,row3,row4) \ - row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \ - row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ - row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) ); - -#define UNDIAGONALIZE(row1,row2,row3,row4) \ - row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \ - row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ - row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) ); - -#if defined(HAVE_XOP) -#include "blake2s-load-xop.h" +#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) + +#define TOF(reg) _mm_castsi128_ps((reg)) +#define TOI(reg) _mm_castps_si128((reg)) + +#define LIKELY(x) __builtin_expect((x),1) + + +/* Microarchitecture-specific macros */ +#ifndef HAVE_XOP +#ifdef HAVE_SSSE3 +#define _mm_roti_epi32(r, c) ( \ + (8==-(c)) ? _mm_shuffle_epi8(r,r8) \ + : (16==-(c)) ? _mm_shuffle_epi8(r,r16) \ + : _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) ) +#else +#define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) +#endif +#else +/* ... */ +#endif + + +#define G1(row1,row2,row3,row4,buf) \ + row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ + row4 = _mm_xor_si128( row4, row1 ); \ + row4 = _mm_roti_epi32(row4, -16); \ + row3 = _mm_add_epi32( row3, row4 ); \ + row2 = _mm_xor_si128( row2, row3 ); \ + row2 = _mm_roti_epi32(row2, -12); + +#define G2(row1,row2,row3,row4,buf) \ + row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ + row4 = _mm_xor_si128( row4, row1 ); \ + row4 = _mm_roti_epi32(row4, -8); \ + row3 = _mm_add_epi32( row3, row4 ); \ + row2 = _mm_xor_si128( row2, row3 ); \ + row2 = _mm_roti_epi32(row2, -7); + +#define DIAGONALIZE(row1,row2,row3,row4) \ + row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \ + row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ + row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) ); + +#define UNDIAGONALIZE(row1,row2,row3,row4) \ + row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \ + row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ + row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) ); + +#if defined(HAVE_XOP) +#include "blake2s-load-xop.h" #elif defined(HAVE_SSE4_1) -#include "blake2s-load-sse41.h" -#else -#include "blake2s-load-sse2.h" -#endif - -#define ROUND(r) \ - LOAD_MSG_ ##r ##_1(buf1); \ - G1(row1,row2,row3,row4,buf1); \ - LOAD_MSG_ ##r ##_2(buf2); \ - G2(row1,row2,row3,row4,buf2); \ - DIAGONALIZE(row1,row2,row3,row4); \ - LOAD_MSG_ ##r ##_3(buf3); \ - G1(row1,row2,row3,row4,buf3); \ - LOAD_MSG_ ##r ##_4(buf4); \ - G2(row1,row2,row3,row4,buf4); \ - UNDIAGONALIZE(row1,row2,row3,row4); \ +#include "blake2s-load-sse41.h" +#else +#include "blake2s-load-sse2.h" +#endif + +#define ROUND(r) \ + LOAD_MSG_ ##r ##_1(buf1); \ + G1(row1,row2,row3,row4,buf1); \ + LOAD_MSG_ ##r ##_2(buf2); \ + G2(row1,row2,row3,row4,buf2); \ + DIAGONALIZE(row1,row2,row3,row4); \ + LOAD_MSG_ ##r ##_3(buf3); \ + G1(row1,row2,row3,row4,buf3); \ + LOAD_MSG_ ##r ##_4(buf4); \ + G2(row1,row2,row3,row4,buf4); \ + UNDIAGONALIZE(row1,row2,row3,row4); \ + +#endif -#endif - diff --git a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s.c b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s.c index 47514685b8f..224a95d4189 100644 --- a/contrib/tools/python3/src/Modules/_blake2/impl/blake2s.c +++ b/contrib/tools/python3/src/Modules/_blake2/impl/blake2s.c @@ -1,5 +1,5 @@ -/* - BLAKE2 reference source code package - optimized C implementations +/* + BLAKE2 reference source code package - optimized C implementations Written in 2012 by Samuel Neves @@ -9,23 +9,23 @@ You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see . -*/ - -#include -#include -#include - -#include "blake2.h" -#include "blake2-impl.h" - -#include "blake2-config.h" - +*/ + +#include +#include +#include + +#include "blake2.h" +#include "blake2-impl.h" + +#include "blake2-config.h" + #if defined(_MSC_VER) #include #endif - + #if defined(HAVE_SSE2) -#include +#include // MSVC only defines _mm_set_epi64x for x86_64... #if defined(_MSC_VER) && !defined(_M_X64) static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 ) @@ -36,145 +36,145 @@ static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 ) #endif -#if defined(HAVE_SSSE3) -#include -#endif +#if defined(HAVE_SSSE3) +#include +#endif #if defined(HAVE_SSE4_1) -#include -#endif -#if defined(HAVE_AVX) -#include -#endif +#include +#endif +#if defined(HAVE_AVX) +#include +#endif #if defined(HAVE_XOP) && !defined(_MSC_VER) -#include -#endif - -#include "blake2s-round.h" - -static const uint32_t blake2s_IV[8] = -{ - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL -}; - -static const uint8_t blake2s_sigma[10][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , -}; - - -/* Some helper functions, not necessarily useful */ +#include +#endif + +#include "blake2s-round.h" + +static const uint32_t blake2s_IV[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static const uint8_t blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + + +/* Some helper functions, not necessarily useful */ static inline int blake2s_set_lastnode( blake2s_state *S ) -{ +{ S->f[1] = ~0U; - return 0; -} - + return 0; +} + static inline int blake2s_clear_lastnode( blake2s_state *S ) -{ +{ S->f[1] = 0U; - return 0; -} - + return 0; +} + static inline int blake2s_set_lastblock( blake2s_state *S ) -{ - if( S->last_node ) blake2s_set_lastnode( S ); - +{ + if( S->last_node ) blake2s_set_lastnode( S ); + S->f[0] = ~0U; - return 0; -} - + return 0; +} + static inline int blake2s_clear_lastblock( blake2s_state *S ) -{ - if( S->last_node ) blake2s_clear_lastnode( S ); - +{ + if( S->last_node ) blake2s_clear_lastnode( S ); + S->f[0] = 0U; - return 0; -} - + return 0; +} + static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) -{ - uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0]; - t += inc; - S->t[0] = ( uint32_t )( t >> 0 ); - S->t[1] = ( uint32_t )( t >> 32 ); - return 0; -} - - +{ + uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0]; + t += inc; + S->t[0] = ( uint32_t )( t >> 0 ); + S->t[1] = ( uint32_t )( t >> 32 ); + return 0; +} + + // Parameter-related functions static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) -{ - P->digest_length = digest_length; - return 0; -} - +{ + P->digest_length = digest_length; + return 0; +} + static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) -{ - P->fanout = fanout; - return 0; -} - +{ + P->fanout = fanout; + return 0; +} + static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) -{ - P->depth = depth; - return 0; -} - +{ + P->depth = depth; + return 0; +} + static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) -{ - P->leaf_length = leaf_length; - return 0; -} - +{ + P->leaf_length = leaf_length; + return 0; +} + static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) -{ - store48( P->node_offset, node_offset ); - return 0; -} - +{ + store48( P->node_offset, node_offset ); + return 0; +} + static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) -{ - P->node_depth = node_depth; - return 0; -} - +{ + P->node_depth = node_depth; + return 0; +} + static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) -{ - P->inner_length = inner_length; - return 0; -} - +{ + P->inner_length = inner_length; + return 0; +} + static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) -{ - memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); - return 0; -} - +{ + memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); + return 0; +} + static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) -{ - memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); - return 0; -} - +{ + memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); + return 0; +} + static inline int blake2s_init0( blake2s_state *S ) -{ - memset( S, 0, sizeof( blake2s_state ) ); - +{ + memset( S, 0, sizeof( blake2s_state ) ); + for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; - - return 0; -} - + + return 0; +} + #if defined(__cplusplus) extern "C" { #endif @@ -189,227 +189,227 @@ extern "C" { #endif -/* init2 xors IV with input parameter block */ -int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) -{ +/* init2 xors IV with input parameter block */ +int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ uint8_t *p, *h, *v; //blake2s_init0( S ); v = ( uint8_t * )( blake2s_IV ); h = ( uint8_t * )( S->h ); p = ( uint8_t * )( P ); - /* IV XOR ParamBlock */ - memset( S, 0, sizeof( blake2s_state ) ); - + /* IV XOR ParamBlock */ + memset( S, 0, sizeof( blake2s_state ) ); + for( int i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; - + S->outlen = P->digest_length; - return 0; -} - - -/* Some sort of default parameter block initialization, for sequential blake2s */ + return 0; +} + + +/* Some sort of default parameter block initialization, for sequential blake2s */ int blake2s_init( blake2s_state *S, size_t outlen ) -{ +{ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - const blake2s_param P = - { - outlen, - 0, - 1, - 1, - 0, - {0}, - 0, - 0, - {0}, - {0} - }; - return blake2s_init_param( S, &P ); -} - - + const blake2s_param P = + { + outlen, + 0, + 1, + 1, + 0, + {0}, + 0, + 0, + {0}, + {0} + }; + return blake2s_init_param( S, &P ); +} + + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ +{ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1; - const blake2s_param P = - { - outlen, - keylen, - 1, - 1, - 0, - {0}, - 0, - 0, - {0}, - {0} - }; - - if( blake2s_init_param( S, &P ) < 0 ) - return -1; - - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - - + const blake2s_param P = + { + outlen, + keylen, + 1, + 1, + 0, + {0}, + 0, + 0, + {0}, + {0} + }; + + if( blake2s_init_param( S, &P ) < 0 ) + return -1; + + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + + static inline int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) -{ - __m128i row1, row2, row3, row4; - __m128i buf1, buf2, buf3, buf4; +{ + __m128i row1, row2, row3, row4; + __m128i buf1, buf2, buf3, buf4; #if defined(HAVE_SSE4_1) - __m128i t0, t1; -#if !defined(HAVE_XOP) - __m128i t2; -#endif -#endif - __m128i ff0, ff1; -#if defined(HAVE_SSSE3) && !defined(HAVE_XOP) - const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ); - const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 ); -#endif + __m128i t0, t1; +#if !defined(HAVE_XOP) + __m128i t2; +#endif +#endif + __m128i ff0, ff1; +#if defined(HAVE_SSSE3) && !defined(HAVE_XOP) + const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ); + const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 ); +#endif #if defined(HAVE_SSE4_1) - const __m128i m0 = LOADU( block + 00 ); - const __m128i m1 = LOADU( block + 16 ); - const __m128i m2 = LOADU( block + 32 ); - const __m128i m3 = LOADU( block + 48 ); -#else - const uint32_t m0 = ( ( uint32_t * )block )[ 0]; - const uint32_t m1 = ( ( uint32_t * )block )[ 1]; - const uint32_t m2 = ( ( uint32_t * )block )[ 2]; - const uint32_t m3 = ( ( uint32_t * )block )[ 3]; - const uint32_t m4 = ( ( uint32_t * )block )[ 4]; - const uint32_t m5 = ( ( uint32_t * )block )[ 5]; - const uint32_t m6 = ( ( uint32_t * )block )[ 6]; - const uint32_t m7 = ( ( uint32_t * )block )[ 7]; - const uint32_t m8 = ( ( uint32_t * )block )[ 8]; - const uint32_t m9 = ( ( uint32_t * )block )[ 9]; - const uint32_t m10 = ( ( uint32_t * )block )[10]; - const uint32_t m11 = ( ( uint32_t * )block )[11]; - const uint32_t m12 = ( ( uint32_t * )block )[12]; - const uint32_t m13 = ( ( uint32_t * )block )[13]; - const uint32_t m14 = ( ( uint32_t * )block )[14]; - const uint32_t m15 = ( ( uint32_t * )block )[15]; -#endif - row1 = ff0 = LOADU( &S->h[0] ); - row2 = ff1 = LOADU( &S->h[4] ); - row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A ); - row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOADU( &S->t[0] ) ); - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) ); - STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) ); - return 0; -} - + const __m128i m0 = LOADU( block + 00 ); + const __m128i m1 = LOADU( block + 16 ); + const __m128i m2 = LOADU( block + 32 ); + const __m128i m3 = LOADU( block + 48 ); +#else + const uint32_t m0 = ( ( uint32_t * )block )[ 0]; + const uint32_t m1 = ( ( uint32_t * )block )[ 1]; + const uint32_t m2 = ( ( uint32_t * )block )[ 2]; + const uint32_t m3 = ( ( uint32_t * )block )[ 3]; + const uint32_t m4 = ( ( uint32_t * )block )[ 4]; + const uint32_t m5 = ( ( uint32_t * )block )[ 5]; + const uint32_t m6 = ( ( uint32_t * )block )[ 6]; + const uint32_t m7 = ( ( uint32_t * )block )[ 7]; + const uint32_t m8 = ( ( uint32_t * )block )[ 8]; + const uint32_t m9 = ( ( uint32_t * )block )[ 9]; + const uint32_t m10 = ( ( uint32_t * )block )[10]; + const uint32_t m11 = ( ( uint32_t * )block )[11]; + const uint32_t m12 = ( ( uint32_t * )block )[12]; + const uint32_t m13 = ( ( uint32_t * )block )[13]; + const uint32_t m14 = ( ( uint32_t * )block )[14]; + const uint32_t m15 = ( ( uint32_t * )block )[15]; +#endif + row1 = ff0 = LOADU( &S->h[0] ); + row2 = ff1 = LOADU( &S->h[4] ); + row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A ); + row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOADU( &S->t[0] ) ); + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) ); + STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) ); + return 0; +} + int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) -{ - while( inlen > 0 ) - { - size_t left = S->buflen; - size_t fill = 2 * BLAKE2S_BLOCKBYTES - left; - - if( inlen > fill ) - { +{ + while( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = 2 * BLAKE2S_BLOCKBYTES - left; + + if( inlen > fill ) + { memcpy( S->buf + left, in, fill ); // Fill buffer - S->buflen += fill; - blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + S->buflen += fill; + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S->buf ); // Compress memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left - S->buflen -= BLAKE2S_BLOCKBYTES; - in += fill; - inlen -= fill; - } - else /* inlen <= fill */ - { - memcpy( S->buf + left, in, inlen ); + S->buflen -= BLAKE2S_BLOCKBYTES; + in += fill; + inlen -= fill; + } + else /* inlen <= fill */ + { + memcpy( S->buf + left, in, inlen ); S->buflen += inlen; // Be lazy, do not compress - in += inlen; - inlen -= inlen; - } - } - - return 0; -} - + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) -{ +{ uint8_t buffer[BLAKE2S_OUTBYTES]; - + if(outlen != S->outlen ) return -1; - - if( S->buflen > BLAKE2S_BLOCKBYTES ) - { - blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); - S->buflen -= BLAKE2S_BLOCKBYTES; + + if( S->buflen > BLAKE2S_BLOCKBYTES ) + { + blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); + blake2s_compress( S, S->buf ); + S->buflen -= BLAKE2S_BLOCKBYTES; memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); - } - - blake2s_increment_counter( S, ( uint32_t )S->buflen ); - blake2s_set_lastblock( S ); - memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ - blake2s_compress( S, S->buf ); - + } + + blake2s_increment_counter( S, ( uint32_t )S->buflen ); + blake2s_set_lastblock( S ); + memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + blake2s_compress( S, S->buf ); + for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ - store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - - memcpy( out, buffer, outlen ); - return 0; -} - + store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, outlen ); + return 0; +} + int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - blake2s_state S[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if ( NULL == key && keylen > 0) return -1; - - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( keylen > BLAKE2S_KEYBYTES ) return -1; - - if( keylen > 0 ) - { - if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; - } - else - { - if( blake2s_init( S, outlen ) < 0 ) return -1; - } - +{ + blake2s_state S[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if ( NULL == key && keylen > 0) return -1; + + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( keylen > BLAKE2S_KEYBYTES ) return -1; + + if( keylen > 0 ) + { + if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; + } + else + { + if( blake2s_init( S, outlen ) < 0 ) return -1; + } + if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1; return blake2s_final( S, out, outlen ); -} - -#if defined(SUPERCOP) -int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) -{ +} + +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, (size_t)inlen, 0 ); -} -#endif - +} +#endif + diff --git a/contrib/tools/python3/src/Modules/_bz2module.c b/contrib/tools/python3/src/Modules/_bz2module.c index 880632c6234..0875f803670 100644 --- a/contrib/tools/python3/src/Modules/_bz2module.c +++ b/contrib/tools/python3/src/Modules/_bz2module.c @@ -1,731 +1,731 @@ -/* _bz2 - Low-level Python interface to libbzip2. */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" +/* _bz2 - Low-level Python interface to libbzip2. */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" #include "structmember.h" // PyMemberDef - -#include -#include - - -#ifndef BZ_CONFIG_ERROR -#define BZ2_bzCompress bzCompress -#define BZ2_bzCompressInit bzCompressInit -#define BZ2_bzCompressEnd bzCompressEnd -#define BZ2_bzDecompress bzDecompress -#define BZ2_bzDecompressInit bzDecompressInit -#define BZ2_bzDecompressEnd bzDecompressEnd -#endif /* ! BZ_CONFIG_ERROR */ - - -#define ACQUIRE_LOCK(obj) do { \ - if (!PyThread_acquire_lock((obj)->lock, 0)) { \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock((obj)->lock, 1); \ - Py_END_ALLOW_THREADS \ - } } while (0) -#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock) - - -typedef struct { - PyObject_HEAD - bz_stream bzs; - int flushed; - PyThread_type_lock lock; -} BZ2Compressor; - -typedef struct { - PyObject_HEAD - bz_stream bzs; - char eof; /* T_BOOL expects a char */ - PyObject *unused_data; - char needs_input; - char *input_buffer; - size_t input_buffer_size; - - /* bzs->avail_in is only 32 bit, so we store the true length - separately. Conversion and looping is encapsulated in - decompress_buf() */ - size_t bzs_avail_in_real; - PyThread_type_lock lock; -} BZ2Decompressor; - -static PyTypeObject BZ2Compressor_Type; -static PyTypeObject BZ2Decompressor_Type; - -/* Helper functions. */ - -static int -catch_bz2_error(int bzerror) -{ - switch(bzerror) { - case BZ_OK: - case BZ_RUN_OK: - case BZ_FLUSH_OK: - case BZ_FINISH_OK: - case BZ_STREAM_END: - return 0; - -#ifdef BZ_CONFIG_ERROR - case BZ_CONFIG_ERROR: - PyErr_SetString(PyExc_SystemError, - "libbzip2 was not compiled correctly"); - return 1; -#endif - case BZ_PARAM_ERROR: - PyErr_SetString(PyExc_ValueError, - "Internal error - " - "invalid parameters passed to libbzip2"); - return 1; - case BZ_MEM_ERROR: - PyErr_NoMemory(); - return 1; - case BZ_DATA_ERROR: - case BZ_DATA_ERROR_MAGIC: - PyErr_SetString(PyExc_OSError, "Invalid data stream"); - return 1; - case BZ_IO_ERROR: - PyErr_SetString(PyExc_OSError, "Unknown I/O error"); - return 1; - case BZ_UNEXPECTED_EOF: - PyErr_SetString(PyExc_EOFError, - "Compressed file ended before the logical " - "end-of-stream was detected"); - return 1; - case BZ_SEQUENCE_ERROR: - PyErr_SetString(PyExc_RuntimeError, - "Internal error - " - "Invalid sequence of commands sent to libbzip2"); - return 1; - default: - PyErr_Format(PyExc_OSError, - "Unrecognized error from libbzip2: %d", bzerror); - return 1; - } -} - -#if BUFSIZ < 8192 -#define INITIAL_BUFFER_SIZE 8192 -#else -#define INITIAL_BUFFER_SIZE BUFSIZ -#endif - -static int -grow_buffer(PyObject **buf, Py_ssize_t max_length) -{ - /* Expand the buffer by an amount proportional to the current size, - giving us amortized linear-time behavior. Use a less-than-double - growth factor to avoid excessive allocation. */ - size_t size = PyBytes_GET_SIZE(*buf); - size_t new_size = size + (size >> 3) + 6; - - if (max_length > 0 && new_size > (size_t) max_length) - new_size = (size_t) max_length; - - if (new_size > size) { - return _PyBytes_Resize(buf, new_size); - } else { /* overflow */ - PyErr_SetString(PyExc_OverflowError, - "Unable to allocate buffer - output too large"); - return -1; - } -} - - -/* BZ2Compressor class. */ - -static PyObject * -compress(BZ2Compressor *c, char *data, size_t len, int action) -{ - size_t data_size = 0; - PyObject *result; - - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); - if (result == NULL) - return NULL; - - c->bzs.next_in = data; - c->bzs.avail_in = 0; - c->bzs.next_out = PyBytes_AS_STRING(result); - c->bzs.avail_out = INITIAL_BUFFER_SIZE; - for (;;) { - char *this_out; - int bzerror; - - /* On a 64-bit system, len might not fit in avail_in (an unsigned int). - Do compression in chunks of no more than UINT_MAX bytes each. */ - if (c->bzs.avail_in == 0 && len > 0) { - c->bzs.avail_in = (unsigned int)Py_MIN(len, UINT_MAX); - len -= c->bzs.avail_in; - } - - /* In regular compression mode, stop when input data is exhausted. */ - if (action == BZ_RUN && c->bzs.avail_in == 0) - break; - - if (c->bzs.avail_out == 0) { - size_t buffer_left = PyBytes_GET_SIZE(result) - data_size; - if (buffer_left == 0) { - if (grow_buffer(&result, -1) < 0) - goto error; - c->bzs.next_out = PyBytes_AS_STRING(result) + data_size; - buffer_left = PyBytes_GET_SIZE(result) - data_size; - } - c->bzs.avail_out = (unsigned int)Py_MIN(buffer_left, UINT_MAX); - } - - Py_BEGIN_ALLOW_THREADS - this_out = c->bzs.next_out; - bzerror = BZ2_bzCompress(&c->bzs, action); - data_size += c->bzs.next_out - this_out; - Py_END_ALLOW_THREADS - if (catch_bz2_error(bzerror)) - goto error; - - /* In flushing mode, stop when all buffered data has been flushed. */ - if (action == BZ_FINISH && bzerror == BZ_STREAM_END) - break; - } - if (data_size != (size_t)PyBytes_GET_SIZE(result)) - if (_PyBytes_Resize(&result, data_size) < 0) - goto error; - return result; - -error: - Py_XDECREF(result); - return NULL; -} - -/*[clinic input] -module _bz2 -class _bz2.BZ2Compressor "BZ2Compressor *" "&BZ2Compressor_Type" -class _bz2.BZ2Decompressor "BZ2Decompressor *" "&BZ2Decompressor_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=dc7d7992a79f9cb7]*/ - -#include "clinic/_bz2module.c.h" - -/*[clinic input] -_bz2.BZ2Compressor.compress - - data: Py_buffer - / - -Provide data to the compressor object. - -Returns a chunk of compressed data if possible, or b'' otherwise. - -When you have finished providing data to the compressor, call the -flush() method to finish the compression process. -[clinic start generated code]*/ - -static PyObject * -_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data) -/*[clinic end generated code: output=59365426e941fbcc input=85c963218070fc4c]*/ -{ - PyObject *result = NULL; - - ACQUIRE_LOCK(self); - if (self->flushed) - PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); - else - result = compress(self, data->buf, data->len, BZ_RUN); - RELEASE_LOCK(self); - return result; -} - -/*[clinic input] -_bz2.BZ2Compressor.flush - -Finish the compression process. - -Returns the compressed data left in internal buffers. - -The compressor object may not be used after this method is called. -[clinic start generated code]*/ - -static PyObject * -_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self) -/*[clinic end generated code: output=3ef03fc1b092a701 input=d64405d3c6f76691]*/ -{ - PyObject *result = NULL; - - ACQUIRE_LOCK(self); - if (self->flushed) - PyErr_SetString(PyExc_ValueError, "Repeated call to flush()"); - else { - self->flushed = 1; - result = compress(self, NULL, 0, BZ_FINISH); - } - RELEASE_LOCK(self); - return result; -} - -static void* -BZ2_Malloc(void* ctx, int items, int size) -{ - if (items < 0 || size < 0) - return NULL; - if (size != 0 && (size_t)items > (size_t)PY_SSIZE_T_MAX / (size_t)size) - return NULL; - /* PyMem_Malloc() cannot be used: compress() and decompress() - release the GIL */ - return PyMem_RawMalloc((size_t)items * (size_t)size); -} - -static void -BZ2_Free(void* ctx, void *ptr) -{ - PyMem_RawFree(ptr); -} - -/*[clinic input] -_bz2.BZ2Compressor.__init__ - - compresslevel: int = 9 - Compression level, as a number between 1 and 9. - / - -Create a compressor object for compressing data incrementally. - -For one-shot compression, use the compress() function instead. -[clinic start generated code]*/ - -static int -_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel) -/*[clinic end generated code: output=c4e6adfd02963827 input=4e1ff7b8394b6e9a]*/ -{ - int bzerror; - - if (!(1 <= compresslevel && compresslevel <= 9)) { - PyErr_SetString(PyExc_ValueError, - "compresslevel must be between 1 and 9"); - return -1; - } - - self->lock = PyThread_allocate_lock(); - if (self->lock == NULL) { - PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return -1; - } - - self->bzs.opaque = NULL; - self->bzs.bzalloc = BZ2_Malloc; - self->bzs.bzfree = BZ2_Free; - bzerror = BZ2_bzCompressInit(&self->bzs, compresslevel, 0, 0); - if (catch_bz2_error(bzerror)) - goto error; - - return 0; - -error: - PyThread_free_lock(self->lock); - self->lock = NULL; - return -1; -} - -static void -BZ2Compressor_dealloc(BZ2Compressor *self) -{ - BZ2_bzCompressEnd(&self->bzs); - if (self->lock != NULL) - PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyMethodDef BZ2Compressor_methods[] = { - _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF - _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF - {NULL} -}; - - -static PyTypeObject BZ2Compressor_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_bz2.BZ2Compressor", /* tp_name */ - sizeof(BZ2Compressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)BZ2Compressor_dealloc, /* tp_dealloc */ + +#include +#include + + +#ifndef BZ_CONFIG_ERROR +#define BZ2_bzCompress bzCompress +#define BZ2_bzCompressInit bzCompressInit +#define BZ2_bzCompressEnd bzCompressEnd +#define BZ2_bzDecompress bzDecompress +#define BZ2_bzDecompressInit bzDecompressInit +#define BZ2_bzDecompressEnd bzDecompressEnd +#endif /* ! BZ_CONFIG_ERROR */ + + +#define ACQUIRE_LOCK(obj) do { \ + if (!PyThread_acquire_lock((obj)->lock, 0)) { \ + Py_BEGIN_ALLOW_THREADS \ + PyThread_acquire_lock((obj)->lock, 1); \ + Py_END_ALLOW_THREADS \ + } } while (0) +#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock) + + +typedef struct { + PyObject_HEAD + bz_stream bzs; + int flushed; + PyThread_type_lock lock; +} BZ2Compressor; + +typedef struct { + PyObject_HEAD + bz_stream bzs; + char eof; /* T_BOOL expects a char */ + PyObject *unused_data; + char needs_input; + char *input_buffer; + size_t input_buffer_size; + + /* bzs->avail_in is only 32 bit, so we store the true length + separately. Conversion and looping is encapsulated in + decompress_buf() */ + size_t bzs_avail_in_real; + PyThread_type_lock lock; +} BZ2Decompressor; + +static PyTypeObject BZ2Compressor_Type; +static PyTypeObject BZ2Decompressor_Type; + +/* Helper functions. */ + +static int +catch_bz2_error(int bzerror) +{ + switch(bzerror) { + case BZ_OK: + case BZ_RUN_OK: + case BZ_FLUSH_OK: + case BZ_FINISH_OK: + case BZ_STREAM_END: + return 0; + +#ifdef BZ_CONFIG_ERROR + case BZ_CONFIG_ERROR: + PyErr_SetString(PyExc_SystemError, + "libbzip2 was not compiled correctly"); + return 1; +#endif + case BZ_PARAM_ERROR: + PyErr_SetString(PyExc_ValueError, + "Internal error - " + "invalid parameters passed to libbzip2"); + return 1; + case BZ_MEM_ERROR: + PyErr_NoMemory(); + return 1; + case BZ_DATA_ERROR: + case BZ_DATA_ERROR_MAGIC: + PyErr_SetString(PyExc_OSError, "Invalid data stream"); + return 1; + case BZ_IO_ERROR: + PyErr_SetString(PyExc_OSError, "Unknown I/O error"); + return 1; + case BZ_UNEXPECTED_EOF: + PyErr_SetString(PyExc_EOFError, + "Compressed file ended before the logical " + "end-of-stream was detected"); + return 1; + case BZ_SEQUENCE_ERROR: + PyErr_SetString(PyExc_RuntimeError, + "Internal error - " + "Invalid sequence of commands sent to libbzip2"); + return 1; + default: + PyErr_Format(PyExc_OSError, + "Unrecognized error from libbzip2: %d", bzerror); + return 1; + } +} + +#if BUFSIZ < 8192 +#define INITIAL_BUFFER_SIZE 8192 +#else +#define INITIAL_BUFFER_SIZE BUFSIZ +#endif + +static int +grow_buffer(PyObject **buf, Py_ssize_t max_length) +{ + /* Expand the buffer by an amount proportional to the current size, + giving us amortized linear-time behavior. Use a less-than-double + growth factor to avoid excessive allocation. */ + size_t size = PyBytes_GET_SIZE(*buf); + size_t new_size = size + (size >> 3) + 6; + + if (max_length > 0 && new_size > (size_t) max_length) + new_size = (size_t) max_length; + + if (new_size > size) { + return _PyBytes_Resize(buf, new_size); + } else { /* overflow */ + PyErr_SetString(PyExc_OverflowError, + "Unable to allocate buffer - output too large"); + return -1; + } +} + + +/* BZ2Compressor class. */ + +static PyObject * +compress(BZ2Compressor *c, char *data, size_t len, int action) +{ + size_t data_size = 0; + PyObject *result; + + result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); + if (result == NULL) + return NULL; + + c->bzs.next_in = data; + c->bzs.avail_in = 0; + c->bzs.next_out = PyBytes_AS_STRING(result); + c->bzs.avail_out = INITIAL_BUFFER_SIZE; + for (;;) { + char *this_out; + int bzerror; + + /* On a 64-bit system, len might not fit in avail_in (an unsigned int). + Do compression in chunks of no more than UINT_MAX bytes each. */ + if (c->bzs.avail_in == 0 && len > 0) { + c->bzs.avail_in = (unsigned int)Py_MIN(len, UINT_MAX); + len -= c->bzs.avail_in; + } + + /* In regular compression mode, stop when input data is exhausted. */ + if (action == BZ_RUN && c->bzs.avail_in == 0) + break; + + if (c->bzs.avail_out == 0) { + size_t buffer_left = PyBytes_GET_SIZE(result) - data_size; + if (buffer_left == 0) { + if (grow_buffer(&result, -1) < 0) + goto error; + c->bzs.next_out = PyBytes_AS_STRING(result) + data_size; + buffer_left = PyBytes_GET_SIZE(result) - data_size; + } + c->bzs.avail_out = (unsigned int)Py_MIN(buffer_left, UINT_MAX); + } + + Py_BEGIN_ALLOW_THREADS + this_out = c->bzs.next_out; + bzerror = BZ2_bzCompress(&c->bzs, action); + data_size += c->bzs.next_out - this_out; + Py_END_ALLOW_THREADS + if (catch_bz2_error(bzerror)) + goto error; + + /* In flushing mode, stop when all buffered data has been flushed. */ + if (action == BZ_FINISH && bzerror == BZ_STREAM_END) + break; + } + if (data_size != (size_t)PyBytes_GET_SIZE(result)) + if (_PyBytes_Resize(&result, data_size) < 0) + goto error; + return result; + +error: + Py_XDECREF(result); + return NULL; +} + +/*[clinic input] +module _bz2 +class _bz2.BZ2Compressor "BZ2Compressor *" "&BZ2Compressor_Type" +class _bz2.BZ2Decompressor "BZ2Decompressor *" "&BZ2Decompressor_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=dc7d7992a79f9cb7]*/ + +#include "clinic/_bz2module.c.h" + +/*[clinic input] +_bz2.BZ2Compressor.compress + + data: Py_buffer + / + +Provide data to the compressor object. + +Returns a chunk of compressed data if possible, or b'' otherwise. + +When you have finished providing data to the compressor, call the +flush() method to finish the compression process. +[clinic start generated code]*/ + +static PyObject * +_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data) +/*[clinic end generated code: output=59365426e941fbcc input=85c963218070fc4c]*/ +{ + PyObject *result = NULL; + + ACQUIRE_LOCK(self); + if (self->flushed) + PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); + else + result = compress(self, data->buf, data->len, BZ_RUN); + RELEASE_LOCK(self); + return result; +} + +/*[clinic input] +_bz2.BZ2Compressor.flush + +Finish the compression process. + +Returns the compressed data left in internal buffers. + +The compressor object may not be used after this method is called. +[clinic start generated code]*/ + +static PyObject * +_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self) +/*[clinic end generated code: output=3ef03fc1b092a701 input=d64405d3c6f76691]*/ +{ + PyObject *result = NULL; + + ACQUIRE_LOCK(self); + if (self->flushed) + PyErr_SetString(PyExc_ValueError, "Repeated call to flush()"); + else { + self->flushed = 1; + result = compress(self, NULL, 0, BZ_FINISH); + } + RELEASE_LOCK(self); + return result; +} + +static void* +BZ2_Malloc(void* ctx, int items, int size) +{ + if (items < 0 || size < 0) + return NULL; + if (size != 0 && (size_t)items > (size_t)PY_SSIZE_T_MAX / (size_t)size) + return NULL; + /* PyMem_Malloc() cannot be used: compress() and decompress() + release the GIL */ + return PyMem_RawMalloc((size_t)items * (size_t)size); +} + +static void +BZ2_Free(void* ctx, void *ptr) +{ + PyMem_RawFree(ptr); +} + +/*[clinic input] +_bz2.BZ2Compressor.__init__ + + compresslevel: int = 9 + Compression level, as a number between 1 and 9. + / + +Create a compressor object for compressing data incrementally. + +For one-shot compression, use the compress() function instead. +[clinic start generated code]*/ + +static int +_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel) +/*[clinic end generated code: output=c4e6adfd02963827 input=4e1ff7b8394b6e9a]*/ +{ + int bzerror; + + if (!(1 <= compresslevel && compresslevel <= 9)) { + PyErr_SetString(PyExc_ValueError, + "compresslevel must be between 1 and 9"); + return -1; + } + + self->lock = PyThread_allocate_lock(); + if (self->lock == NULL) { + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + return -1; + } + + self->bzs.opaque = NULL; + self->bzs.bzalloc = BZ2_Malloc; + self->bzs.bzfree = BZ2_Free; + bzerror = BZ2_bzCompressInit(&self->bzs, compresslevel, 0, 0); + if (catch_bz2_error(bzerror)) + goto error; + + return 0; + +error: + PyThread_free_lock(self->lock); + self->lock = NULL; + return -1; +} + +static void +BZ2Compressor_dealloc(BZ2Compressor *self) +{ + BZ2_bzCompressEnd(&self->bzs); + if (self->lock != NULL) + PyThread_free_lock(self->lock); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyMethodDef BZ2Compressor_methods[] = { + _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF + _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF + {NULL} +}; + + +static PyTypeObject BZ2Compressor_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_bz2.BZ2Compressor", /* tp_name */ + sizeof(BZ2Compressor), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)BZ2Compressor_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - _bz2_BZ2Compressor___init____doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BZ2Compressor_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _bz2_BZ2Compressor___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/* BZ2Decompressor class. */ - -/* Decompress data of length d->bzs_avail_in_real in d->bzs.next_in. The output - buffer is allocated dynamically and returned. At most max_length bytes are - returned, so some of the input may not be consumed. d->bzs.next_in and - d->bzs_avail_in_real are updated to reflect the consumed input. */ -static PyObject* -decompress_buf(BZ2Decompressor *d, Py_ssize_t max_length) -{ - /* data_size is strictly positive, but because we repeatedly have to - compare against max_length and PyBytes_GET_SIZE we declare it as - signed */ - Py_ssize_t data_size = 0; - PyObject *result; - bz_stream *bzs = &d->bzs; - - if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE) - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); - else - result = PyBytes_FromStringAndSize(NULL, max_length); - if (result == NULL) - return NULL; - - bzs->next_out = PyBytes_AS_STRING(result); - for (;;) { - int bzret; - size_t avail; - - /* On a 64-bit system, buffer length might not fit in avail_out, so we - do decompression in chunks of no more than UINT_MAX bytes - each. Note that the expression for `avail` is guaranteed to be - positive, so the cast is safe. */ - avail = (size_t) (PyBytes_GET_SIZE(result) - data_size); - bzs->avail_out = (unsigned int)Py_MIN(avail, UINT_MAX); - bzs->avail_in = (unsigned int)Py_MIN(d->bzs_avail_in_real, UINT_MAX); - d->bzs_avail_in_real -= bzs->avail_in; - - Py_BEGIN_ALLOW_THREADS - bzret = BZ2_bzDecompress(bzs); - data_size = bzs->next_out - PyBytes_AS_STRING(result); - d->bzs_avail_in_real += bzs->avail_in; - Py_END_ALLOW_THREADS - if (catch_bz2_error(bzret)) - goto error; - if (bzret == BZ_STREAM_END) { - d->eof = 1; - break; - } else if (d->bzs_avail_in_real == 0) { - break; - } else if (bzs->avail_out == 0) { - if (data_size == max_length) - break; - if (data_size == PyBytes_GET_SIZE(result) && - grow_buffer(&result, max_length) == -1) - goto error; - bzs->next_out = PyBytes_AS_STRING(result) + data_size; - } - } - if (data_size != PyBytes_GET_SIZE(result)) - if (_PyBytes_Resize(&result, data_size) == -1) - goto error; - - return result; - -error: - Py_XDECREF(result); - return NULL; -} - - -static PyObject * -decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length) -{ - char input_buffer_in_use; - PyObject *result; - bz_stream *bzs = &d->bzs; - - /* Prepend unconsumed input if necessary */ - if (bzs->next_in != NULL) { - size_t avail_now, avail_total; - - /* Number of bytes we can append to input buffer */ - avail_now = (d->input_buffer + d->input_buffer_size) - - (bzs->next_in + d->bzs_avail_in_real); - - /* Number of bytes we can append if we move existing - contents to beginning of buffer (overwriting - consumed input) */ - avail_total = d->input_buffer_size - d->bzs_avail_in_real; - - if (avail_total < len) { - size_t offset = bzs->next_in - d->input_buffer; - char *tmp; - size_t new_size = d->input_buffer_size + len - avail_now; - - /* Assign to temporary variable first, so we don't - lose address of allocated buffer if realloc fails */ - tmp = PyMem_Realloc(d->input_buffer, new_size); - if (tmp == NULL) { - PyErr_SetNone(PyExc_MemoryError); - return NULL; - } - d->input_buffer = tmp; - d->input_buffer_size = new_size; - - bzs->next_in = d->input_buffer + offset; - } - else if (avail_now < len) { - memmove(d->input_buffer, bzs->next_in, - d->bzs_avail_in_real); - bzs->next_in = d->input_buffer; - } - memcpy((void*)(bzs->next_in + d->bzs_avail_in_real), data, len); - d->bzs_avail_in_real += len; - input_buffer_in_use = 1; - } - else { - bzs->next_in = data; - d->bzs_avail_in_real = len; - input_buffer_in_use = 0; - } - - result = decompress_buf(d, max_length); - if(result == NULL) { - bzs->next_in = NULL; - return NULL; - } - - if (d->eof) { - d->needs_input = 0; - if (d->bzs_avail_in_real > 0) { - Py_XSETREF(d->unused_data, - PyBytes_FromStringAndSize(bzs->next_in, d->bzs_avail_in_real)); - if (d->unused_data == NULL) - goto error; - } - } - else if (d->bzs_avail_in_real == 0) { - bzs->next_in = NULL; - d->needs_input = 1; - } - else { - d->needs_input = 0; - - /* If we did not use the input buffer, we now have - to copy the tail from the caller's buffer into the - input buffer */ - if (!input_buffer_in_use) { - - /* Discard buffer if it's too small - (resizing it may needlessly copy the current contents) */ - if (d->input_buffer != NULL && - d->input_buffer_size < d->bzs_avail_in_real) { - PyMem_Free(d->input_buffer); - d->input_buffer = NULL; - } - - /* Allocate if necessary */ - if (d->input_buffer == NULL) { - d->input_buffer = PyMem_Malloc(d->bzs_avail_in_real); - if (d->input_buffer == NULL) { - PyErr_SetNone(PyExc_MemoryError); - goto error; - } - d->input_buffer_size = d->bzs_avail_in_real; - } - - /* Copy tail */ - memcpy(d->input_buffer, bzs->next_in, d->bzs_avail_in_real); - bzs->next_in = d->input_buffer; - } - } - - return result; - -error: - Py_XDECREF(result); - return NULL; -} - -/*[clinic input] -_bz2.BZ2Decompressor.decompress - - data: Py_buffer - max_length: Py_ssize_t=-1 - -Decompress *data*, returning uncompressed data as bytes. - -If *max_length* is nonnegative, returns at most *max_length* bytes of -decompressed data. If this limit is reached and further output can be -produced, *self.needs_input* will be set to ``False``. In this case, the next -call to *decompress()* may provide *data* as b'' to obtain more of the output. - -If all of the input data was decompressed and returned (either because this -was less than *max_length* bytes, or because *max_length* was negative), -*self.needs_input* will be set to True. - -Attempting to decompress data after the end of stream is reached raises an -EOFError. Any data found after the end of the stream is ignored and saved in -the unused_data attribute. -[clinic start generated code]*/ - -static PyObject * -_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, - Py_ssize_t max_length) -/*[clinic end generated code: output=23e41045deb240a3 input=52e1ffc66a8ea624]*/ -{ - PyObject *result = NULL; - - ACQUIRE_LOCK(self); - if (self->eof) - PyErr_SetString(PyExc_EOFError, "End of stream already reached"); - else - result = decompress(self, data->buf, data->len, max_length); - RELEASE_LOCK(self); - return result; -} - -/*[clinic input] -_bz2.BZ2Decompressor.__init__ - -Create a decompressor object for decompressing data incrementally. - -For one-shot decompression, use the decompress() function instead. -[clinic start generated code]*/ - -static int -_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self) -/*[clinic end generated code: output=e4d2b9bb866ab8f1 input=95f6500dcda60088]*/ -{ - int bzerror; - - PyThread_type_lock lock = PyThread_allocate_lock(); - if (lock == NULL) { - PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return -1; - } - if (self->lock != NULL) { - PyThread_free_lock(self->lock); - } - self->lock = lock; - - self->needs_input = 1; - self->bzs_avail_in_real = 0; - self->input_buffer = NULL; - self->input_buffer_size = 0; - Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0)); - if (self->unused_data == NULL) - goto error; - - bzerror = BZ2_bzDecompressInit(&self->bzs, 0, 0); - if (catch_bz2_error(bzerror)) - goto error; - - return 0; - -error: - Py_CLEAR(self->unused_data); - PyThread_free_lock(self->lock); - self->lock = NULL; - return -1; -} - -static void -BZ2Decompressor_dealloc(BZ2Decompressor *self) -{ - if(self->input_buffer != NULL) - PyMem_Free(self->input_buffer); - BZ2_bzDecompressEnd(&self->bzs); - Py_CLEAR(self->unused_data); - if (self->lock != NULL) - PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyMethodDef BZ2Decompressor_methods[] = { - _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF - {NULL} -}; - -PyDoc_STRVAR(BZ2Decompressor_eof__doc__, -"True if the end-of-stream marker has been reached."); - -PyDoc_STRVAR(BZ2Decompressor_unused_data__doc__, -"Data found after the end of the compressed stream."); - -PyDoc_STRVAR(BZ2Decompressor_needs_input_doc, -"True if more input is needed before more decompressed data can be produced."); - -static PyMemberDef BZ2Decompressor_members[] = { - {"eof", T_BOOL, offsetof(BZ2Decompressor, eof), - READONLY, BZ2Decompressor_eof__doc__}, - {"unused_data", T_OBJECT_EX, offsetof(BZ2Decompressor, unused_data), - READONLY, BZ2Decompressor_unused_data__doc__}, - {"needs_input", T_BOOL, offsetof(BZ2Decompressor, needs_input), READONLY, - BZ2Decompressor_needs_input_doc}, - {NULL} -}; - -static PyTypeObject BZ2Decompressor_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_bz2.BZ2Decompressor", /* tp_name */ - sizeof(BZ2Decompressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)BZ2Decompressor_dealloc,/* tp_dealloc */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + _bz2_BZ2Compressor___init____doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BZ2Compressor_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + _bz2_BZ2Compressor___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + + +/* BZ2Decompressor class. */ + +/* Decompress data of length d->bzs_avail_in_real in d->bzs.next_in. The output + buffer is allocated dynamically and returned. At most max_length bytes are + returned, so some of the input may not be consumed. d->bzs.next_in and + d->bzs_avail_in_real are updated to reflect the consumed input. */ +static PyObject* +decompress_buf(BZ2Decompressor *d, Py_ssize_t max_length) +{ + /* data_size is strictly positive, but because we repeatedly have to + compare against max_length and PyBytes_GET_SIZE we declare it as + signed */ + Py_ssize_t data_size = 0; + PyObject *result; + bz_stream *bzs = &d->bzs; + + if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE) + result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); + else + result = PyBytes_FromStringAndSize(NULL, max_length); + if (result == NULL) + return NULL; + + bzs->next_out = PyBytes_AS_STRING(result); + for (;;) { + int bzret; + size_t avail; + + /* On a 64-bit system, buffer length might not fit in avail_out, so we + do decompression in chunks of no more than UINT_MAX bytes + each. Note that the expression for `avail` is guaranteed to be + positive, so the cast is safe. */ + avail = (size_t) (PyBytes_GET_SIZE(result) - data_size); + bzs->avail_out = (unsigned int)Py_MIN(avail, UINT_MAX); + bzs->avail_in = (unsigned int)Py_MIN(d->bzs_avail_in_real, UINT_MAX); + d->bzs_avail_in_real -= bzs->avail_in; + + Py_BEGIN_ALLOW_THREADS + bzret = BZ2_bzDecompress(bzs); + data_size = bzs->next_out - PyBytes_AS_STRING(result); + d->bzs_avail_in_real += bzs->avail_in; + Py_END_ALLOW_THREADS + if (catch_bz2_error(bzret)) + goto error; + if (bzret == BZ_STREAM_END) { + d->eof = 1; + break; + } else if (d->bzs_avail_in_real == 0) { + break; + } else if (bzs->avail_out == 0) { + if (data_size == max_length) + break; + if (data_size == PyBytes_GET_SIZE(result) && + grow_buffer(&result, max_length) == -1) + goto error; + bzs->next_out = PyBytes_AS_STRING(result) + data_size; + } + } + if (data_size != PyBytes_GET_SIZE(result)) + if (_PyBytes_Resize(&result, data_size) == -1) + goto error; + + return result; + +error: + Py_XDECREF(result); + return NULL; +} + + +static PyObject * +decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length) +{ + char input_buffer_in_use; + PyObject *result; + bz_stream *bzs = &d->bzs; + + /* Prepend unconsumed input if necessary */ + if (bzs->next_in != NULL) { + size_t avail_now, avail_total; + + /* Number of bytes we can append to input buffer */ + avail_now = (d->input_buffer + d->input_buffer_size) + - (bzs->next_in + d->bzs_avail_in_real); + + /* Number of bytes we can append if we move existing + contents to beginning of buffer (overwriting + consumed input) */ + avail_total = d->input_buffer_size - d->bzs_avail_in_real; + + if (avail_total < len) { + size_t offset = bzs->next_in - d->input_buffer; + char *tmp; + size_t new_size = d->input_buffer_size + len - avail_now; + + /* Assign to temporary variable first, so we don't + lose address of allocated buffer if realloc fails */ + tmp = PyMem_Realloc(d->input_buffer, new_size); + if (tmp == NULL) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } + d->input_buffer = tmp; + d->input_buffer_size = new_size; + + bzs->next_in = d->input_buffer + offset; + } + else if (avail_now < len) { + memmove(d->input_buffer, bzs->next_in, + d->bzs_avail_in_real); + bzs->next_in = d->input_buffer; + } + memcpy((void*)(bzs->next_in + d->bzs_avail_in_real), data, len); + d->bzs_avail_in_real += len; + input_buffer_in_use = 1; + } + else { + bzs->next_in = data; + d->bzs_avail_in_real = len; + input_buffer_in_use = 0; + } + + result = decompress_buf(d, max_length); + if(result == NULL) { + bzs->next_in = NULL; + return NULL; + } + + if (d->eof) { + d->needs_input = 0; + if (d->bzs_avail_in_real > 0) { + Py_XSETREF(d->unused_data, + PyBytes_FromStringAndSize(bzs->next_in, d->bzs_avail_in_real)); + if (d->unused_data == NULL) + goto error; + } + } + else if (d->bzs_avail_in_real == 0) { + bzs->next_in = NULL; + d->needs_input = 1; + } + else { + d->needs_input = 0; + + /* If we did not use the input buffer, we now have + to copy the tail from the caller's buffer into the + input buffer */ + if (!input_buffer_in_use) { + + /* Discard buffer if it's too small + (resizing it may needlessly copy the current contents) */ + if (d->input_buffer != NULL && + d->input_buffer_size < d->bzs_avail_in_real) { + PyMem_Free(d->input_buffer); + d->input_buffer = NULL; + } + + /* Allocate if necessary */ + if (d->input_buffer == NULL) { + d->input_buffer = PyMem_Malloc(d->bzs_avail_in_real); + if (d->input_buffer == NULL) { + PyErr_SetNone(PyExc_MemoryError); + goto error; + } + d->input_buffer_size = d->bzs_avail_in_real; + } + + /* Copy tail */ + memcpy(d->input_buffer, bzs->next_in, d->bzs_avail_in_real); + bzs->next_in = d->input_buffer; + } + } + + return result; + +error: + Py_XDECREF(result); + return NULL; +} + +/*[clinic input] +_bz2.BZ2Decompressor.decompress + + data: Py_buffer + max_length: Py_ssize_t=-1 + +Decompress *data*, returning uncompressed data as bytes. + +If *max_length* is nonnegative, returns at most *max_length* bytes of +decompressed data. If this limit is reached and further output can be +produced, *self.needs_input* will be set to ``False``. In this case, the next +call to *decompress()* may provide *data* as b'' to obtain more of the output. + +If all of the input data was decompressed and returned (either because this +was less than *max_length* bytes, or because *max_length* was negative), +*self.needs_input* will be set to True. + +Attempting to decompress data after the end of stream is reached raises an +EOFError. Any data found after the end of the stream is ignored and saved in +the unused_data attribute. +[clinic start generated code]*/ + +static PyObject * +_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, + Py_ssize_t max_length) +/*[clinic end generated code: output=23e41045deb240a3 input=52e1ffc66a8ea624]*/ +{ + PyObject *result = NULL; + + ACQUIRE_LOCK(self); + if (self->eof) + PyErr_SetString(PyExc_EOFError, "End of stream already reached"); + else + result = decompress(self, data->buf, data->len, max_length); + RELEASE_LOCK(self); + return result; +} + +/*[clinic input] +_bz2.BZ2Decompressor.__init__ + +Create a decompressor object for decompressing data incrementally. + +For one-shot decompression, use the decompress() function instead. +[clinic start generated code]*/ + +static int +_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self) +/*[clinic end generated code: output=e4d2b9bb866ab8f1 input=95f6500dcda60088]*/ +{ + int bzerror; + + PyThread_type_lock lock = PyThread_allocate_lock(); + if (lock == NULL) { + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + return -1; + } + if (self->lock != NULL) { + PyThread_free_lock(self->lock); + } + self->lock = lock; + + self->needs_input = 1; + self->bzs_avail_in_real = 0; + self->input_buffer = NULL; + self->input_buffer_size = 0; + Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0)); + if (self->unused_data == NULL) + goto error; + + bzerror = BZ2_bzDecompressInit(&self->bzs, 0, 0); + if (catch_bz2_error(bzerror)) + goto error; + + return 0; + +error: + Py_CLEAR(self->unused_data); + PyThread_free_lock(self->lock); + self->lock = NULL; + return -1; +} + +static void +BZ2Decompressor_dealloc(BZ2Decompressor *self) +{ + if(self->input_buffer != NULL) + PyMem_Free(self->input_buffer); + BZ2_bzDecompressEnd(&self->bzs); + Py_CLEAR(self->unused_data); + if (self->lock != NULL) + PyThread_free_lock(self->lock); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyMethodDef BZ2Decompressor_methods[] = { + _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF + {NULL} +}; + +PyDoc_STRVAR(BZ2Decompressor_eof__doc__, +"True if the end-of-stream marker has been reached."); + +PyDoc_STRVAR(BZ2Decompressor_unused_data__doc__, +"Data found after the end of the compressed stream."); + +PyDoc_STRVAR(BZ2Decompressor_needs_input_doc, +"True if more input is needed before more decompressed data can be produced."); + +static PyMemberDef BZ2Decompressor_members[] = { + {"eof", T_BOOL, offsetof(BZ2Decompressor, eof), + READONLY, BZ2Decompressor_eof__doc__}, + {"unused_data", T_OBJECT_EX, offsetof(BZ2Decompressor, unused_data), + READONLY, BZ2Decompressor_unused_data__doc__}, + {"needs_input", T_BOOL, offsetof(BZ2Decompressor, needs_input), READONLY, + BZ2Decompressor_needs_input_doc}, + {NULL} +}; + +static PyTypeObject BZ2Decompressor_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_bz2.BZ2Decompressor", /* tp_name */ + sizeof(BZ2Decompressor), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)BZ2Decompressor_dealloc,/* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - _bz2_BZ2Decompressor___init____doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BZ2Decompressor_methods, /* tp_methods */ - BZ2Decompressor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _bz2_BZ2Decompressor___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/* Module initialization. */ - + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + _bz2_BZ2Decompressor___init____doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BZ2Decompressor_methods, /* tp_methods */ + BZ2Decompressor_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + _bz2_BZ2Decompressor___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + + +/* Module initialization. */ + static int _bz2_exec(PyObject *module) { @@ -745,20 +745,20 @@ static struct PyModuleDef_Slot _bz2_slots[] = { {0, NULL} }; -static struct PyModuleDef _bz2module = { - PyModuleDef_HEAD_INIT, - "_bz2", - NULL, +static struct PyModuleDef _bz2module = { + PyModuleDef_HEAD_INIT, + "_bz2", + NULL, 0, - NULL, + NULL, _bz2_slots, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__bz2(void) -{ + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__bz2(void) +{ return PyModuleDef_Init(&_bz2module); -} +} diff --git a/contrib/tools/python3/src/Modules/_codecsmodule.c b/contrib/tools/python3/src/Modules/_codecsmodule.c index cbe5cc50f1c..c28caa44c69 100644 --- a/contrib/tools/python3/src/Modules/_codecsmodule.c +++ b/contrib/tools/python3/src/Modules/_codecsmodule.c @@ -1,1068 +1,1068 @@ -/* ------------------------------------------------------------------------ - - _codecs -- Provides access to the codec registry and the builtin - codecs. - - This module should never be imported directly. The standard library - module "codecs" wraps this builtin module for use within Python. - - The codec registry is accessible via: - - register(search_function) -> None - - lookup(encoding) -> CodecInfo object - - The builtin Unicode codecs use the following interface: - - _encode(Unicode_object[,errors='strict']) -> - (string object, bytes consumed) - - _decode(char_buffer_obj[,errors='strict']) -> - (Unicode object, bytes consumed) - - These s are available: utf_8, unicode_escape, +/* ------------------------------------------------------------------------ + + _codecs -- Provides access to the codec registry and the builtin + codecs. + + This module should never be imported directly. The standard library + module "codecs" wraps this builtin module for use within Python. + + The codec registry is accessible via: + + register(search_function) -> None + + lookup(encoding) -> CodecInfo object + + The builtin Unicode codecs use the following interface: + + _encode(Unicode_object[,errors='strict']) -> + (string object, bytes consumed) + + _decode(char_buffer_obj[,errors='strict']) -> + (Unicode object, bytes consumed) + + These s are available: utf_8, unicode_escape, raw_unicode_escape, latin_1, ascii (7-bit), mbcs (on win32). - - -Written by Marc-Andre Lemburg (mal@lemburg.com). - -Copyright (c) Corporation for National Research Initiatives. - - ------------------------------------------------------------------------ */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" - -#ifdef MS_WINDOWS -#include -#endif - -/*[clinic input] -module _codecs -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/ - -#include "clinic/_codecsmodule.c.h" - -/* --- Registry ----------------------------------------------------------- */ - -/*[clinic input] -_codecs.register - search_function: object - / - -Register a codec search function. - -Search functions are expected to take one argument, the encoding name in -all lower case letters, and either return None, or a tuple of functions -(encoder, decoder, stream_reader, stream_writer) (or a CodecInfo object). -[clinic start generated code]*/ - -static PyObject * -_codecs_register(PyObject *module, PyObject *search_function) -/*[clinic end generated code: output=d1bf21e99db7d6d3 input=369578467955cae4]*/ -{ - if (PyCodec_Register(search_function)) - return NULL; - - Py_RETURN_NONE; -} - -/*[clinic input] -_codecs.lookup - encoding: str - / - -Looks up a codec tuple in the Python codec registry and returns a CodecInfo object. -[clinic start generated code]*/ - -static PyObject * -_codecs_lookup_impl(PyObject *module, const char *encoding) -/*[clinic end generated code: output=9f0afa572080c36d input=3c572c0db3febe9c]*/ -{ - return _PyCodec_Lookup(encoding); -} - -/*[clinic input] -_codecs.encode - obj: object - encoding: str(c_default="NULL") = "utf-8" - errors: str(c_default="NULL") = "strict" - -Encodes obj using the codec registered for encoding. - -The default encoding is 'utf-8'. errors may be given to set a -different error handling scheme. Default is 'strict' meaning that encoding -errors raise a ValueError. Other possible values are 'ignore', 'replace' -and 'backslashreplace' as well as any other name registered with -codecs.register_error that can handle ValueErrors. -[clinic start generated code]*/ - -static PyObject * -_codecs_encode_impl(PyObject *module, PyObject *obj, const char *encoding, - const char *errors) -/*[clinic end generated code: output=385148eb9a067c86 input=cd5b685040ff61f0]*/ -{ - if (encoding == NULL) - encoding = PyUnicode_GetDefaultEncoding(); - - /* Encode via the codec registry */ - return PyCodec_Encode(obj, encoding, errors); -} - -/*[clinic input] -_codecs.decode - obj: object - encoding: str(c_default="NULL") = "utf-8" - errors: str(c_default="NULL") = "strict" - -Decodes obj using the codec registered for encoding. - -Default encoding is 'utf-8'. errors may be given to set a -different error handling scheme. Default is 'strict' meaning that encoding -errors raise a ValueError. Other possible values are 'ignore', 'replace' -and 'backslashreplace' as well as any other name registered with -codecs.register_error that can handle ValueErrors. -[clinic start generated code]*/ - -static PyObject * -_codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding, - const char *errors) -/*[clinic end generated code: output=679882417dc3a0bd input=7702c0cc2fa1add6]*/ -{ - if (encoding == NULL) - encoding = PyUnicode_GetDefaultEncoding(); - - /* Decode via the codec registry */ - return PyCodec_Decode(obj, encoding, errors); -} - -/* --- Helpers ------------------------------------------------------------ */ - -/*[clinic input] -_codecs._forget_codec - - encoding: str - / - -Purge the named codec from the internal codec lookup cache -[clinic start generated code]*/ - -static PyObject * -_codecs__forget_codec_impl(PyObject *module, const char *encoding) -/*[clinic end generated code: output=0bde9f0a5b084aa2 input=18d5d92d0e386c38]*/ -{ - if (_PyCodec_Forget(encoding) < 0) { - return NULL; - }; - Py_RETURN_NONE; -} - -static -PyObject *codec_tuple(PyObject *decoded, - Py_ssize_t len) -{ - if (decoded == NULL) - return NULL; - return Py_BuildValue("Nn", decoded, len); -} - -/* --- String codecs ------------------------------------------------------ */ -/*[clinic input] -_codecs.escape_decode - data: Py_buffer(accept={str, buffer}) + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +Copyright (c) Corporation for National Research Initiatives. + + ------------------------------------------------------------------------ */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" + +#ifdef MS_WINDOWS +#include +#endif + +/*[clinic input] +module _codecs +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/ + +#include "clinic/_codecsmodule.c.h" + +/* --- Registry ----------------------------------------------------------- */ + +/*[clinic input] +_codecs.register + search_function: object + / + +Register a codec search function. + +Search functions are expected to take one argument, the encoding name in +all lower case letters, and either return None, or a tuple of functions +(encoder, decoder, stream_reader, stream_writer) (or a CodecInfo object). +[clinic start generated code]*/ + +static PyObject * +_codecs_register(PyObject *module, PyObject *search_function) +/*[clinic end generated code: output=d1bf21e99db7d6d3 input=369578467955cae4]*/ +{ + if (PyCodec_Register(search_function)) + return NULL; + + Py_RETURN_NONE; +} + +/*[clinic input] +_codecs.lookup + encoding: str + / + +Looks up a codec tuple in the Python codec registry and returns a CodecInfo object. +[clinic start generated code]*/ + +static PyObject * +_codecs_lookup_impl(PyObject *module, const char *encoding) +/*[clinic end generated code: output=9f0afa572080c36d input=3c572c0db3febe9c]*/ +{ + return _PyCodec_Lookup(encoding); +} + +/*[clinic input] +_codecs.encode + obj: object + encoding: str(c_default="NULL") = "utf-8" + errors: str(c_default="NULL") = "strict" + +Encodes obj using the codec registered for encoding. + +The default encoding is 'utf-8'. errors may be given to set a +different error handling scheme. Default is 'strict' meaning that encoding +errors raise a ValueError. Other possible values are 'ignore', 'replace' +and 'backslashreplace' as well as any other name registered with +codecs.register_error that can handle ValueErrors. +[clinic start generated code]*/ + +static PyObject * +_codecs_encode_impl(PyObject *module, PyObject *obj, const char *encoding, + const char *errors) +/*[clinic end generated code: output=385148eb9a067c86 input=cd5b685040ff61f0]*/ +{ + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + + /* Encode via the codec registry */ + return PyCodec_Encode(obj, encoding, errors); +} + +/*[clinic input] +_codecs.decode + obj: object + encoding: str(c_default="NULL") = "utf-8" + errors: str(c_default="NULL") = "strict" + +Decodes obj using the codec registered for encoding. + +Default encoding is 'utf-8'. errors may be given to set a +different error handling scheme. Default is 'strict' meaning that encoding +errors raise a ValueError. Other possible values are 'ignore', 'replace' +and 'backslashreplace' as well as any other name registered with +codecs.register_error that can handle ValueErrors. +[clinic start generated code]*/ + +static PyObject * +_codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding, + const char *errors) +/*[clinic end generated code: output=679882417dc3a0bd input=7702c0cc2fa1add6]*/ +{ + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + + /* Decode via the codec registry */ + return PyCodec_Decode(obj, encoding, errors); +} + +/* --- Helpers ------------------------------------------------------------ */ + +/*[clinic input] +_codecs._forget_codec + + encoding: str + / + +Purge the named codec from the internal codec lookup cache +[clinic start generated code]*/ + +static PyObject * +_codecs__forget_codec_impl(PyObject *module, const char *encoding) +/*[clinic end generated code: output=0bde9f0a5b084aa2 input=18d5d92d0e386c38]*/ +{ + if (_PyCodec_Forget(encoding) < 0) { + return NULL; + }; + Py_RETURN_NONE; +} + +static +PyObject *codec_tuple(PyObject *decoded, + Py_ssize_t len) +{ + if (decoded == NULL) + return NULL; + return Py_BuildValue("Nn", decoded, len); +} + +/* --- String codecs ------------------------------------------------------ */ +/*[clinic input] +_codecs.escape_decode + data: Py_buffer(accept={str, buffer}) errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_escape_decode_impl(PyObject *module, Py_buffer *data, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_escape_decode_impl(PyObject *module, Py_buffer *data, + const char *errors) /*[clinic end generated code: output=505200ba8056979a input=77298a561c90bd82]*/ -{ - PyObject *decoded = PyBytes_DecodeEscape(data->buf, data->len, - errors, 0, NULL); - return codec_tuple(decoded, data->len); -} - -/*[clinic input] -_codecs.escape_encode - data: object(subclass_of='&PyBytes_Type') +{ + PyObject *decoded = PyBytes_DecodeEscape(data->buf, data->len, + errors, 0, NULL); + return codec_tuple(decoded, data->len); +} + +/*[clinic input] +_codecs.escape_encode + data: object(subclass_of='&PyBytes_Type') errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_escape_encode_impl(PyObject *module, PyObject *data, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_escape_encode_impl(PyObject *module, PyObject *data, + const char *errors) /*[clinic end generated code: output=4af1d477834bab34 input=8f4b144799a94245]*/ -{ - Py_ssize_t size; - Py_ssize_t newsize; - PyObject *v; - - size = PyBytes_GET_SIZE(data); - if (size > PY_SSIZE_T_MAX / 4) { - PyErr_SetString(PyExc_OverflowError, - "string is too large to encode"); - return NULL; - } - newsize = 4*size; - v = PyBytes_FromStringAndSize(NULL, newsize); - - if (v == NULL) { - return NULL; - } - else { - Py_ssize_t i; - char c; - char *p = PyBytes_AS_STRING(v); - - for (i = 0; i < size; i++) { - /* There's at least enough room for a hex escape */ - assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); - c = PyBytes_AS_STRING(data)[i]; - if (c == '\'' || c == '\\') - *p++ = '\\', *p++ = c; - else if (c == '\t') - *p++ = '\\', *p++ = 't'; - else if (c == '\n') - *p++ = '\\', *p++ = 'n'; - else if (c == '\r') - *p++ = '\\', *p++ = 'r'; - else if (c < ' ' || c >= 0x7f) { - *p++ = '\\'; - *p++ = 'x'; - *p++ = Py_hexdigits[(c & 0xf0) >> 4]; - *p++ = Py_hexdigits[c & 0xf]; - } - else - *p++ = c; - } - *p = '\0'; - if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { - return NULL; - } - } - - return codec_tuple(v, size); -} - -/* --- Decoder ------------------------------------------------------------ */ -/*[clinic input] -_codecs.utf_7_decode - data: Py_buffer +{ + Py_ssize_t size; + Py_ssize_t newsize; + PyObject *v; + + size = PyBytes_GET_SIZE(data); + if (size > PY_SSIZE_T_MAX / 4) { + PyErr_SetString(PyExc_OverflowError, + "string is too large to encode"); + return NULL; + } + newsize = 4*size; + v = PyBytes_FromStringAndSize(NULL, newsize); + + if (v == NULL) { + return NULL; + } + else { + Py_ssize_t i; + char c; + char *p = PyBytes_AS_STRING(v); + + for (i = 0; i < size; i++) { + /* There's at least enough room for a hex escape */ + assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); + c = PyBytes_AS_STRING(data)[i]; + if (c == '\'' || c == '\\') + *p++ = '\\', *p++ = c; + else if (c == '\t') + *p++ = '\\', *p++ = 't'; + else if (c == '\n') + *p++ = '\\', *p++ = 'n'; + else if (c == '\r') + *p++ = '\\', *p++ = 'r'; + else if (c < ' ' || c >= 0x7f) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = Py_hexdigits[(c & 0xf0) >> 4]; + *p++ = Py_hexdigits[c & 0xf]; + } + else + *p++ = c; + } + *p = '\0'; + if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { + return NULL; + } + } + + return codec_tuple(v, size); +} + +/* --- Decoder ------------------------------------------------------------ */ +/*[clinic input] +_codecs.utf_7_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=0cd3a944a32a4089 input=22c395d357815d26]*/ -{ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF7Stateful(data->buf, data->len, - errors, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.utf_8_decode - data: Py_buffer +{ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF7Stateful(data->buf, data->len, + errors, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] +_codecs.utf_8_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=10f74dec8d9bb8bf input=f611b3867352ba59]*/ -{ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF8Stateful(data->buf, data->len, - errors, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.utf_16_decode - data: Py_buffer +{ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF8Stateful(data->buf, data->len, + errors, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] +_codecs.utf_16_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=783b442abcbcc2d0 input=191d360bd7309180]*/ -{ - int byteorder = 0; - /* This is overwritten unless final is true. */ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, - errors, &byteorder, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.utf_16_le_decode - data: Py_buffer +{ + int byteorder = 0; + /* This is overwritten unless final is true. */ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] +_codecs.utf_16_le_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=899b9e6364379dcd input=c6904fdc27fb4724]*/ -{ - int byteorder = -1; - /* This is overwritten unless final is true. */ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, - errors, &byteorder, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.utf_16_be_decode - data: Py_buffer +{ + int byteorder = -1; + /* This is overwritten unless final is true. */ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] +_codecs.utf_16_be_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=49f6465ea07669c8 input=e49012400974649b]*/ -{ - int byteorder = 1; - /* This is overwritten unless final is true. */ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, - errors, &byteorder, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/* This non-standard version also provides access to the byteorder - parameter of the builtin UTF-16 codec. - - It returns a tuple (unicode, bytesread, byteorder) with byteorder - being the value in effect at the end of data. - -*/ -/*[clinic input] -_codecs.utf_16_ex_decode - data: Py_buffer +{ + int byteorder = 1; + /* This is overwritten unless final is true. */ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/* This non-standard version also provides access to the byteorder + parameter of the builtin UTF-16 codec. + + It returns a tuple (unicode, bytesread, byteorder) with byteorder + being the value in effect at the end of data. + +*/ +/*[clinic input] +_codecs.utf_16_ex_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - byteorder: int = 0 - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int byteorder, int final) + byteorder: int = 0 + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int byteorder, int final) /*[clinic end generated code: output=0f385f251ecc1988 input=5a9c19f2e6b6cf0e]*/ -{ - /* This is overwritten unless final is true. */ - Py_ssize_t consumed = data->len; - - PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, - errors, &byteorder, - final ? NULL : &consumed); - if (decoded == NULL) - return NULL; - return Py_BuildValue("Nni", decoded, consumed, byteorder); -} - -/*[clinic input] -_codecs.utf_32_decode - data: Py_buffer +{ + /* This is overwritten unless final is true. */ + Py_ssize_t consumed = data->len; + + PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + if (decoded == NULL) + return NULL; + return Py_BuildValue("Nni", decoded, consumed, byteorder); +} + +/*[clinic input] +_codecs.utf_32_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=2fc961807f7b145f input=fd7193965627eb58]*/ -{ - int byteorder = 0; - /* This is overwritten unless final is true. */ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, - errors, &byteorder, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.utf_32_le_decode - data: Py_buffer +{ + int byteorder = 0; + /* This is overwritten unless final is true. */ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] +_codecs.utf_32_le_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=ec8f46b67a94f3e6 input=9078ec70acfe7613]*/ -{ - int byteorder = -1; - /* This is overwritten unless final is true. */ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, - errors, &byteorder, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.utf_32_be_decode - data: Py_buffer +{ + int byteorder = -1; + /* This is overwritten unless final is true. */ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] +_codecs.utf_32_be_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=ff82bae862c92c4e input=f1ae1bbbb86648ff]*/ -{ - int byteorder = 1; - /* This is overwritten unless final is true. */ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, - errors, &byteorder, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/* This non-standard version also provides access to the byteorder - parameter of the builtin UTF-32 codec. - - It returns a tuple (unicode, bytesread, byteorder) with byteorder - being the value in effect at the end of data. - -*/ -/*[clinic input] -_codecs.utf_32_ex_decode - data: Py_buffer +{ + int byteorder = 1; + /* This is overwritten unless final is true. */ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/* This non-standard version also provides access to the byteorder + parameter of the builtin UTF-32 codec. + + It returns a tuple (unicode, bytesread, byteorder) with byteorder + being the value in effect at the end of data. + +*/ +/*[clinic input] +_codecs.utf_32_ex_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - byteorder: int = 0 - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int byteorder, int final) + byteorder: int = 0 + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int byteorder, int final) /*[clinic end generated code: output=6bfb177dceaf4848 input=e46a73bc859d0bd0]*/ -{ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, - errors, &byteorder, - final ? NULL : &consumed); - if (decoded == NULL) - return NULL; - return Py_BuildValue("Nni", decoded, consumed, byteorder); -} - -/*[clinic input] -_codecs.unicode_escape_decode - data: Py_buffer(accept={str, buffer}) +{ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + if (decoded == NULL) + return NULL; + return Py_BuildValue("Nni", decoded, consumed, byteorder); +} + +/*[clinic input] +_codecs.unicode_escape_decode + data: Py_buffer(accept={str, buffer}) errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = True - / -[clinic start generated code]*/ - -static PyObject * -_codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, + / +[clinic start generated code]*/ + +static PyObject * +_codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) /*[clinic end generated code: output=b284f97b12c635ee input=6154f039a9f7c639]*/ -{ +{ Py_ssize_t consumed = data->len; PyObject *decoded = _PyUnicode_DecodeUnicodeEscapeStateful(data->buf, data->len, errors, final ? NULL : &consumed); return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.raw_unicode_escape_decode - data: Py_buffer(accept={str, buffer}) +} + +/*[clinic input] +_codecs.raw_unicode_escape_decode + data: Py_buffer(accept={str, buffer}) errors: str(accept={str, NoneType}) = None final: bool(accept={int}) = True - / -[clinic start generated code]*/ - -static PyObject * -_codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, + / +[clinic start generated code]*/ + +static PyObject * +_codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) /*[clinic end generated code: output=11dbd96301e2879e input=2d166191beb3235a]*/ -{ +{ Py_ssize_t consumed = data->len; PyObject *decoded = _PyUnicode_DecodeRawUnicodeEscapeStateful(data->buf, data->len, errors, final ? NULL : &consumed); return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.latin_1_decode - data: Py_buffer +} + +/*[clinic input] +_codecs.latin_1_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_latin_1_decode_impl(PyObject *module, Py_buffer *data, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_latin_1_decode_impl(PyObject *module, Py_buffer *data, + const char *errors) /*[clinic end generated code: output=07f3dfa3f72c7d8f input=76ca58fd6dcd08c7]*/ -{ - PyObject *decoded = PyUnicode_DecodeLatin1(data->buf, data->len, errors); - return codec_tuple(decoded, data->len); -} - -/*[clinic input] -_codecs.ascii_decode - data: Py_buffer +{ + PyObject *decoded = PyUnicode_DecodeLatin1(data->buf, data->len, errors); + return codec_tuple(decoded, data->len); +} + +/*[clinic input] +_codecs.ascii_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_ascii_decode_impl(PyObject *module, Py_buffer *data, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_ascii_decode_impl(PyObject *module, Py_buffer *data, + const char *errors) /*[clinic end generated code: output=2627d72058d42429 input=e428a267a04b4481]*/ -{ - PyObject *decoded = PyUnicode_DecodeASCII(data->buf, data->len, errors); - return codec_tuple(decoded, data->len); -} - -/*[clinic input] -_codecs.charmap_decode - data: Py_buffer +{ + PyObject *decoded = PyUnicode_DecodeASCII(data->buf, data->len, errors); + return codec_tuple(decoded, data->len); +} + +/*[clinic input] +_codecs.charmap_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None mapping: object = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, PyObject *mapping) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, PyObject *mapping) /*[clinic end generated code: output=2c335b09778cf895 input=15b69df43458eb40]*/ -{ - PyObject *decoded; - - if (mapping == Py_None) - mapping = NULL; - - decoded = PyUnicode_DecodeCharmap(data->buf, data->len, mapping, errors); - return codec_tuple(decoded, data->len); -} - -#ifdef MS_WINDOWS - -/*[clinic input] -_codecs.mbcs_decode - data: Py_buffer +{ + PyObject *decoded; + + if (mapping == Py_None) + mapping = NULL; + + decoded = PyUnicode_DecodeCharmap(data->buf, data->len, mapping, errors); + return codec_tuple(decoded, data->len); +} + +#ifdef MS_WINDOWS + +/*[clinic input] +_codecs.mbcs_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=39b65b8598938c4b input=1c1d50f08fa53789]*/ -{ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeMBCSStateful(data->buf, data->len, - errors, final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.oem_decode - data: Py_buffer +{ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeMBCSStateful(data->buf, data->len, + errors, final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] +_codecs.oem_decode + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_oem_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_oem_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final) /*[clinic end generated code: output=da1617612f3fcad8 input=81b67cba811022e5]*/ -{ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeCodePageStateful(CP_OEMCP, - data->buf, data->len, errors, final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -/*[clinic input] -_codecs.code_page_decode - codepage: int - data: Py_buffer +{ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeCodePageStateful(CP_OEMCP, + data->buf, data->len, errors, final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +/*[clinic input] +_codecs.code_page_decode + codepage: int + data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False - / -[clinic start generated code]*/ - -static PyObject * -_codecs_code_page_decode_impl(PyObject *module, int codepage, - Py_buffer *data, const char *errors, int final) + final: bool(accept={int}) = False + / +[clinic start generated code]*/ + +static PyObject * +_codecs_code_page_decode_impl(PyObject *module, int codepage, + Py_buffer *data, const char *errors, int final) /*[clinic end generated code: output=53008ea967da3fff input=c5f58d036cb63575]*/ -{ - Py_ssize_t consumed = data->len; - PyObject *decoded = PyUnicode_DecodeCodePageStateful(codepage, - data->buf, data->len, - errors, - final ? NULL : &consumed); - return codec_tuple(decoded, consumed); -} - -#endif /* MS_WINDOWS */ - -/* --- Encoder ------------------------------------------------------------ */ - -/*[clinic input] -_codecs.readbuffer_encode - data: Py_buffer(accept={str, buffer}) +{ + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeCodePageStateful(codepage, + data->buf, data->len, + errors, + final ? NULL : &consumed); + return codec_tuple(decoded, consumed); +} + +#endif /* MS_WINDOWS */ + +/* --- Encoder ------------------------------------------------------------ */ + +/*[clinic input] +_codecs.readbuffer_encode + data: Py_buffer(accept={str, buffer}) errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_readbuffer_encode_impl(PyObject *module, Py_buffer *data, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_readbuffer_encode_impl(PyObject *module, Py_buffer *data, + const char *errors) /*[clinic end generated code: output=c645ea7cdb3d6e86 input=aa10cfdf252455c5]*/ -{ - PyObject *result = PyBytes_FromStringAndSize(data->buf, data->len); - return codec_tuple(result, data->len); -} - -/*[clinic input] -_codecs.utf_7_encode - str: unicode +{ + PyObject *result = PyBytes_FromStringAndSize(data->buf, data->len); + return codec_tuple(result, data->len); +} + +/*[clinic input] +_codecs.utf_7_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_7_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_7_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=0feda21ffc921bc8 input=2546dbbb3fa53114]*/ -{ - return codec_tuple(_PyUnicode_EncodeUTF7(str, 0, 0, errors), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.utf_8_encode - str: unicode +{ + return codec_tuple(_PyUnicode_EncodeUTF7(str, 0, 0, errors), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.utf_8_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_8_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_8_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=02bf47332b9c796c input=a3e71ae01c3f93f3]*/ -{ - return codec_tuple(_PyUnicode_AsUTF8String(str, errors), - PyUnicode_GET_LENGTH(str)); -} - -/* This version provides access to the byteorder parameter of the - builtin UTF-16 codecs as optional third argument. It defaults to 0 - which means: use the native byte order and prepend the data with a - BOM mark. - -*/ - -/*[clinic input] -_codecs.utf_16_encode - str: unicode +{ + return codec_tuple(_PyUnicode_AsUTF8String(str, errors), + PyUnicode_GET_LENGTH(str)); +} + +/* This version provides access to the byteorder parameter of the + builtin UTF-16 codecs as optional third argument. It defaults to 0 + which means: use the native byte order and prepend the data with a + BOM mark. + +*/ + +/*[clinic input] +_codecs.utf_16_encode + str: unicode errors: str(accept={str, NoneType}) = None - byteorder: int = 0 - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_16_encode_impl(PyObject *module, PyObject *str, - const char *errors, int byteorder) + byteorder: int = 0 + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_16_encode_impl(PyObject *module, PyObject *str, + const char *errors, int byteorder) /*[clinic end generated code: output=c654e13efa2e64e4 input=68cdc2eb8338555d]*/ -{ - return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, byteorder), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.utf_16_le_encode - str: unicode +{ + return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, byteorder), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.utf_16_le_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=431b01e55f2d4995 input=83d042706eed6798]*/ -{ - return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, -1), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.utf_16_be_encode - str: unicode +{ + return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, -1), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.utf_16_be_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=96886a6fd54dcae3 input=6f1e9e623b03071b]*/ -{ - return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, +1), - PyUnicode_GET_LENGTH(str)); -} - -/* This version provides access to the byteorder parameter of the - builtin UTF-32 codecs as optional third argument. It defaults to 0 - which means: use the native byte order and prepend the data with a - BOM mark. - -*/ - -/*[clinic input] -_codecs.utf_32_encode - str: unicode +{ + return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, +1), + PyUnicode_GET_LENGTH(str)); +} + +/* This version provides access to the byteorder parameter of the + builtin UTF-32 codecs as optional third argument. It defaults to 0 + which means: use the native byte order and prepend the data with a + BOM mark. + +*/ + +/*[clinic input] +_codecs.utf_32_encode + str: unicode errors: str(accept={str, NoneType}) = None - byteorder: int = 0 - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_32_encode_impl(PyObject *module, PyObject *str, - const char *errors, int byteorder) + byteorder: int = 0 + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_32_encode_impl(PyObject *module, PyObject *str, + const char *errors, int byteorder) /*[clinic end generated code: output=5c760da0c09a8b83 input=8ec4c64d983bc52b]*/ -{ - return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, byteorder), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.utf_32_le_encode - str: unicode +{ + return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, byteorder), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.utf_32_le_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=b65cd176de8e36d6 input=f0918d41de3eb1b1]*/ -{ - return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, -1), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.utf_32_be_encode - str: unicode +{ + return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, -1), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.utf_32_be_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=1d9e71a9358709e9 input=967a99a95748b557]*/ -{ - return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, +1), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.unicode_escape_encode - str: unicode +{ + return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, +1), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.unicode_escape_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=66271b30bc4f7a3c input=8c4de07597054e33]*/ -{ - return codec_tuple(PyUnicode_AsUnicodeEscapeString(str), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.raw_unicode_escape_encode - str: unicode +{ + return codec_tuple(PyUnicode_AsUnicodeEscapeString(str), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.raw_unicode_escape_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=a66a806ed01c830a input=4aa6f280d78e4574]*/ -{ - return codec_tuple(PyUnicode_AsRawUnicodeEscapeString(str), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.latin_1_encode - str: unicode +{ + return codec_tuple(PyUnicode_AsRawUnicodeEscapeString(str), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.latin_1_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_latin_1_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_latin_1_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=2c28c83a27884e08 input=ec3ef74bf85c5c5d]*/ -{ - return codec_tuple(_PyUnicode_AsLatin1String(str, errors), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.ascii_encode - str: unicode +{ + return codec_tuple(_PyUnicode_AsLatin1String(str, errors), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.ascii_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_ascii_encode_impl(PyObject *module, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_ascii_encode_impl(PyObject *module, PyObject *str, + const char *errors) /*[clinic end generated code: output=b5e035182d33befc input=93e6e602838bd3de]*/ -{ - return codec_tuple(_PyUnicode_AsASCIIString(str, errors), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.charmap_encode - str: unicode +{ + return codec_tuple(_PyUnicode_AsASCIIString(str, errors), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.charmap_encode + str: unicode errors: str(accept={str, NoneType}) = None mapping: object = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_charmap_encode_impl(PyObject *module, PyObject *str, - const char *errors, PyObject *mapping) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_charmap_encode_impl(PyObject *module, PyObject *str, + const char *errors, PyObject *mapping) /*[clinic end generated code: output=047476f48495a9e9 input=2a98feae73dadce8]*/ -{ - if (mapping == Py_None) - mapping = NULL; - - return codec_tuple(_PyUnicode_EncodeCharmap(str, mapping, errors), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.charmap_build - map: unicode - / -[clinic start generated code]*/ - -static PyObject * -_codecs_charmap_build_impl(PyObject *module, PyObject *map) -/*[clinic end generated code: output=bb073c27031db9ac input=d91a91d1717dbc6d]*/ -{ - return PyUnicode_BuildEncodingMap(map); -} - -#ifdef MS_WINDOWS - -/*[clinic input] -_codecs.mbcs_encode - str: unicode +{ + if (mapping == Py_None) + mapping = NULL; + + return codec_tuple(_PyUnicode_EncodeCharmap(str, mapping, errors), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.charmap_build + map: unicode + / +[clinic start generated code]*/ + +static PyObject * +_codecs_charmap_build_impl(PyObject *module, PyObject *map) +/*[clinic end generated code: output=bb073c27031db9ac input=d91a91d1717dbc6d]*/ +{ + return PyUnicode_BuildEncodingMap(map); +} + +#ifdef MS_WINDOWS + +/*[clinic input] +_codecs.mbcs_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors) /*[clinic end generated code: output=76e2e170c966c080 input=2e932fc289ea5a5b]*/ -{ - return codec_tuple(PyUnicode_EncodeCodePage(CP_ACP, str, errors), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.oem_encode - str: unicode +{ + return codec_tuple(PyUnicode_EncodeCodePage(CP_ACP, str, errors), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.oem_encode + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors) /*[clinic end generated code: output=65d5982c737de649 input=9eac86dc21eb14f2]*/ -{ - return codec_tuple(PyUnicode_EncodeCodePage(CP_OEMCP, str, errors), - PyUnicode_GET_LENGTH(str)); -} - -/*[clinic input] -_codecs.code_page_encode - code_page: int - str: unicode +{ + return codec_tuple(PyUnicode_EncodeCodePage(CP_OEMCP, str, errors), + PyUnicode_GET_LENGTH(str)); +} + +/*[clinic input] +_codecs.code_page_encode + code_page: int + str: unicode errors: str(accept={str, NoneType}) = None - / -[clinic start generated code]*/ - -static PyObject * -_codecs_code_page_encode_impl(PyObject *module, int code_page, PyObject *str, - const char *errors) + / +[clinic start generated code]*/ + +static PyObject * +_codecs_code_page_encode_impl(PyObject *module, int code_page, PyObject *str, + const char *errors) /*[clinic end generated code: output=45673f6085657a9e input=7d18a33bc8cd0f94]*/ -{ - return codec_tuple(PyUnicode_EncodeCodePage(code_page, str, errors), - PyUnicode_GET_LENGTH(str)); -} - -#endif /* MS_WINDOWS */ - -/* --- Error handler registry --------------------------------------------- */ - -/*[clinic input] -_codecs.register_error - errors: str - handler: object - / - -Register the specified error handler under the name errors. - -handler must be a callable object, that will be called with an exception -instance containing information about the location of the encoding/decoding -error and must return a (replacement, new position) tuple. -[clinic start generated code]*/ - -static PyObject * -_codecs_register_error_impl(PyObject *module, const char *errors, - PyObject *handler) -/*[clinic end generated code: output=fa2f7d1879b3067d input=5e6709203c2e33fe]*/ -{ - if (PyCodec_RegisterError(errors, handler)) - return NULL; - Py_RETURN_NONE; -} - -/*[clinic input] -_codecs.lookup_error - name: str - / - -lookup_error(errors) -> handler - -Return the error handler for the specified error handling name or raise a -LookupError, if no handler exists under this name. -[clinic start generated code]*/ - -static PyObject * -_codecs_lookup_error_impl(PyObject *module, const char *name) -/*[clinic end generated code: output=087f05dc0c9a98cc input=4775dd65e6235aba]*/ -{ - return PyCodec_LookupError(name); -} - -/* --- Module API --------------------------------------------------------- */ - -static PyMethodDef _codecs_functions[] = { - _CODECS_REGISTER_METHODDEF - _CODECS_LOOKUP_METHODDEF - _CODECS_ENCODE_METHODDEF - _CODECS_DECODE_METHODDEF - _CODECS_ESCAPE_ENCODE_METHODDEF - _CODECS_ESCAPE_DECODE_METHODDEF - _CODECS_UTF_8_ENCODE_METHODDEF - _CODECS_UTF_8_DECODE_METHODDEF - _CODECS_UTF_7_ENCODE_METHODDEF - _CODECS_UTF_7_DECODE_METHODDEF - _CODECS_UTF_16_ENCODE_METHODDEF - _CODECS_UTF_16_LE_ENCODE_METHODDEF - _CODECS_UTF_16_BE_ENCODE_METHODDEF - _CODECS_UTF_16_DECODE_METHODDEF - _CODECS_UTF_16_LE_DECODE_METHODDEF - _CODECS_UTF_16_BE_DECODE_METHODDEF - _CODECS_UTF_16_EX_DECODE_METHODDEF - _CODECS_UTF_32_ENCODE_METHODDEF - _CODECS_UTF_32_LE_ENCODE_METHODDEF - _CODECS_UTF_32_BE_ENCODE_METHODDEF - _CODECS_UTF_32_DECODE_METHODDEF - _CODECS_UTF_32_LE_DECODE_METHODDEF - _CODECS_UTF_32_BE_DECODE_METHODDEF - _CODECS_UTF_32_EX_DECODE_METHODDEF - _CODECS_UNICODE_ESCAPE_ENCODE_METHODDEF - _CODECS_UNICODE_ESCAPE_DECODE_METHODDEF - _CODECS_RAW_UNICODE_ESCAPE_ENCODE_METHODDEF - _CODECS_RAW_UNICODE_ESCAPE_DECODE_METHODDEF - _CODECS_LATIN_1_ENCODE_METHODDEF - _CODECS_LATIN_1_DECODE_METHODDEF - _CODECS_ASCII_ENCODE_METHODDEF - _CODECS_ASCII_DECODE_METHODDEF - _CODECS_CHARMAP_ENCODE_METHODDEF - _CODECS_CHARMAP_DECODE_METHODDEF - _CODECS_CHARMAP_BUILD_METHODDEF - _CODECS_READBUFFER_ENCODE_METHODDEF - _CODECS_MBCS_ENCODE_METHODDEF - _CODECS_MBCS_DECODE_METHODDEF - _CODECS_OEM_ENCODE_METHODDEF - _CODECS_OEM_DECODE_METHODDEF - _CODECS_CODE_PAGE_ENCODE_METHODDEF - _CODECS_CODE_PAGE_DECODE_METHODDEF - _CODECS_REGISTER_ERROR_METHODDEF - _CODECS_LOOKUP_ERROR_METHODDEF - _CODECS__FORGET_CODEC_METHODDEF - {NULL, NULL} /* sentinel */ -}; - +{ + return codec_tuple(PyUnicode_EncodeCodePage(code_page, str, errors), + PyUnicode_GET_LENGTH(str)); +} + +#endif /* MS_WINDOWS */ + +/* --- Error handler registry --------------------------------------------- */ + +/*[clinic input] +_codecs.register_error + errors: str + handler: object + / + +Register the specified error handler under the name errors. + +handler must be a callable object, that will be called with an exception +instance containing information about the location of the encoding/decoding +error and must return a (replacement, new position) tuple. +[clinic start generated code]*/ + +static PyObject * +_codecs_register_error_impl(PyObject *module, const char *errors, + PyObject *handler) +/*[clinic end generated code: output=fa2f7d1879b3067d input=5e6709203c2e33fe]*/ +{ + if (PyCodec_RegisterError(errors, handler)) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +_codecs.lookup_error + name: str + / + +lookup_error(errors) -> handler + +Return the error handler for the specified error handling name or raise a +LookupError, if no handler exists under this name. +[clinic start generated code]*/ + +static PyObject * +_codecs_lookup_error_impl(PyObject *module, const char *name) +/*[clinic end generated code: output=087f05dc0c9a98cc input=4775dd65e6235aba]*/ +{ + return PyCodec_LookupError(name); +} + +/* --- Module API --------------------------------------------------------- */ + +static PyMethodDef _codecs_functions[] = { + _CODECS_REGISTER_METHODDEF + _CODECS_LOOKUP_METHODDEF + _CODECS_ENCODE_METHODDEF + _CODECS_DECODE_METHODDEF + _CODECS_ESCAPE_ENCODE_METHODDEF + _CODECS_ESCAPE_DECODE_METHODDEF + _CODECS_UTF_8_ENCODE_METHODDEF + _CODECS_UTF_8_DECODE_METHODDEF + _CODECS_UTF_7_ENCODE_METHODDEF + _CODECS_UTF_7_DECODE_METHODDEF + _CODECS_UTF_16_ENCODE_METHODDEF + _CODECS_UTF_16_LE_ENCODE_METHODDEF + _CODECS_UTF_16_BE_ENCODE_METHODDEF + _CODECS_UTF_16_DECODE_METHODDEF + _CODECS_UTF_16_LE_DECODE_METHODDEF + _CODECS_UTF_16_BE_DECODE_METHODDEF + _CODECS_UTF_16_EX_DECODE_METHODDEF + _CODECS_UTF_32_ENCODE_METHODDEF + _CODECS_UTF_32_LE_ENCODE_METHODDEF + _CODECS_UTF_32_BE_ENCODE_METHODDEF + _CODECS_UTF_32_DECODE_METHODDEF + _CODECS_UTF_32_LE_DECODE_METHODDEF + _CODECS_UTF_32_BE_DECODE_METHODDEF + _CODECS_UTF_32_EX_DECODE_METHODDEF + _CODECS_UNICODE_ESCAPE_ENCODE_METHODDEF + _CODECS_UNICODE_ESCAPE_DECODE_METHODDEF + _CODECS_RAW_UNICODE_ESCAPE_ENCODE_METHODDEF + _CODECS_RAW_UNICODE_ESCAPE_DECODE_METHODDEF + _CODECS_LATIN_1_ENCODE_METHODDEF + _CODECS_LATIN_1_DECODE_METHODDEF + _CODECS_ASCII_ENCODE_METHODDEF + _CODECS_ASCII_DECODE_METHODDEF + _CODECS_CHARMAP_ENCODE_METHODDEF + _CODECS_CHARMAP_DECODE_METHODDEF + _CODECS_CHARMAP_BUILD_METHODDEF + _CODECS_READBUFFER_ENCODE_METHODDEF + _CODECS_MBCS_ENCODE_METHODDEF + _CODECS_MBCS_DECODE_METHODDEF + _CODECS_OEM_ENCODE_METHODDEF + _CODECS_OEM_DECODE_METHODDEF + _CODECS_CODE_PAGE_ENCODE_METHODDEF + _CODECS_CODE_PAGE_DECODE_METHODDEF + _CODECS_REGISTER_ERROR_METHODDEF + _CODECS_LOOKUP_ERROR_METHODDEF + _CODECS__FORGET_CODEC_METHODDEF + {NULL, NULL} /* sentinel */ +}; + static PyModuleDef_Slot _codecs_slots[] = { {0, NULL} }; -static struct PyModuleDef codecsmodule = { - PyModuleDef_HEAD_INIT, - "_codecs", - NULL, +static struct PyModuleDef codecsmodule = { + PyModuleDef_HEAD_INIT, + "_codecs", + NULL, 0, - _codecs_functions, + _codecs_functions, _codecs_slots, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__codecs(void) -{ + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__codecs(void) +{ return PyModuleDef_Init(&codecsmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/_collectionsmodule.c b/contrib/tools/python3/src/Modules/_collectionsmodule.c index 2e19b83dcec..0c786f696eb 100644 --- a/contrib/tools/python3/src/Modules/_collectionsmodule.c +++ b/contrib/tools/python3/src/Modules/_collectionsmodule.c @@ -1,12 +1,12 @@ -#include "Python.h" +#include "Python.h" #include "structmember.h" // PyMemberDef - -#ifdef STDC_HEADERS -#include -#else + +#ifdef STDC_HEADERS +#include +#else #include // size_t -#endif - +#endif + /*[clinic input] module _collections class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type" @@ -16,1982 +16,1982 @@ class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type" static PyTypeObject tuplegetter_type; #include "clinic/_collectionsmodule.c.h" -/* collections module implementation of a deque() datatype - Written and maintained by Raymond D. Hettinger -*/ - -/* The block length may be set to any number over 1. Larger numbers - * reduce the number of calls to the memory allocator, give faster - * indexing and rotation, and reduce the link to data overhead ratio. - * Making the block length a power of two speeds-up the modulo - * and division calculations in deque_item() and deque_ass_item(). - */ - -#define BLOCKLEN 64 -#define CENTER ((BLOCKLEN - 1) / 2) - -/* Data for deque objects is stored in a doubly-linked list of fixed - * length blocks. This assures that appends or pops never move any - * other data elements besides the one being appended or popped. - * - * Another advantage is that it completely avoids use of realloc(), - * resulting in more predictable performance. - * - * Textbook implementations of doubly-linked lists store one datum - * per link, but that gives them a 200% memory overhead (a prev and - * next link for each datum) and it costs one malloc() call per data - * element. By using fixed-length blocks, the link to data ratio is - * significantly improved and there are proportionally fewer calls - * to malloc() and free(). The data blocks of consecutive pointers - * also improve cache locality. - * - * The list of blocks is never empty, so d.leftblock and d.rightblock - * are never equal to NULL. The list is not circular. - * - * A deque d's first element is at d.leftblock[leftindex] - * and its last element is at d.rightblock[rightindex]. - * - * Unlike Python slice indices, these indices are inclusive on both - * ends. This makes the algorithms for left and right operations - * more symmetrical and it simplifies the design. - * - * The indices, d.leftindex and d.rightindex are always in the range: - * 0 <= index < BLOCKLEN - * - * And their exact relationship is: - * (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex - * - * Whenever d.leftblock == d.rightblock, then: - * d.leftindex + d.len - 1 == d.rightindex - * - * However, when d.leftblock != d.rightblock, the d.leftindex and - * d.rightindex become indices into distinct blocks and either may - * be larger than the other. - * - * Empty deques have: - * d.len == 0 - * d.leftblock == d.rightblock - * d.leftindex == CENTER + 1 - * d.rightindex == CENTER - * - * Checking for d.len == 0 is the intended way to see whether d is empty. - */ - -typedef struct BLOCK { - struct BLOCK *leftlink; - PyObject *data[BLOCKLEN]; - struct BLOCK *rightlink; -} block; - -typedef struct { - PyObject_VAR_HEAD - block *leftblock; - block *rightblock; - Py_ssize_t leftindex; /* 0 <= leftindex < BLOCKLEN */ - Py_ssize_t rightindex; /* 0 <= rightindex < BLOCKLEN */ - size_t state; /* incremented whenever the indices move */ - Py_ssize_t maxlen; /* maxlen is -1 for unbounded deques */ - PyObject *weakreflist; -} dequeobject; - -static PyTypeObject deque_type; - -/* For debug builds, add error checking to track the endpoints - * in the chain of links. The goal is to make sure that link - * assignments only take place at endpoints so that links already - * in use do not get overwritten. - * - * CHECK_END should happen before each assignment to a block's link field. - * MARK_END should happen whenever a link field becomes a new endpoint. - * This happens when new blocks are added or whenever an existing - * block is freed leaving another existing block as the new endpoint. - */ - -#ifndef NDEBUG -#define MARK_END(link) link = NULL; -#define CHECK_END(link) assert(link == NULL); -#define CHECK_NOT_END(link) assert(link != NULL); -#else -#define MARK_END(link) -#define CHECK_END(link) -#define CHECK_NOT_END(link) -#endif - -/* A simple freelisting scheme is used to minimize calls to the memory - allocator. It accommodates common use cases where new blocks are being - added at about the same rate as old blocks are being freed. - */ - -#define MAXFREEBLOCKS 16 -static Py_ssize_t numfreeblocks = 0; -static block *freeblocks[MAXFREEBLOCKS]; - -static block * -newblock(void) { - block *b; - if (numfreeblocks) { - numfreeblocks--; - return freeblocks[numfreeblocks]; - } - b = PyMem_Malloc(sizeof(block)); - if (b != NULL) { - return b; - } - PyErr_NoMemory(); - return NULL; -} - -static void -freeblock(block *b) -{ - if (numfreeblocks < MAXFREEBLOCKS) { - freeblocks[numfreeblocks] = b; - numfreeblocks++; - } else { - PyMem_Free(b); - } -} - -static PyObject * -deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - dequeobject *deque; - block *b; - - /* create dequeobject structure */ - deque = (dequeobject *)type->tp_alloc(type, 0); - if (deque == NULL) - return NULL; - - b = newblock(); - if (b == NULL) { - Py_DECREF(deque); - return NULL; - } - MARK_END(b->leftlink); - MARK_END(b->rightlink); - - assert(BLOCKLEN >= 2); +/* collections module implementation of a deque() datatype + Written and maintained by Raymond D. Hettinger +*/ + +/* The block length may be set to any number over 1. Larger numbers + * reduce the number of calls to the memory allocator, give faster + * indexing and rotation, and reduce the link to data overhead ratio. + * Making the block length a power of two speeds-up the modulo + * and division calculations in deque_item() and deque_ass_item(). + */ + +#define BLOCKLEN 64 +#define CENTER ((BLOCKLEN - 1) / 2) + +/* Data for deque objects is stored in a doubly-linked list of fixed + * length blocks. This assures that appends or pops never move any + * other data elements besides the one being appended or popped. + * + * Another advantage is that it completely avoids use of realloc(), + * resulting in more predictable performance. + * + * Textbook implementations of doubly-linked lists store one datum + * per link, but that gives them a 200% memory overhead (a prev and + * next link for each datum) and it costs one malloc() call per data + * element. By using fixed-length blocks, the link to data ratio is + * significantly improved and there are proportionally fewer calls + * to malloc() and free(). The data blocks of consecutive pointers + * also improve cache locality. + * + * The list of blocks is never empty, so d.leftblock and d.rightblock + * are never equal to NULL. The list is not circular. + * + * A deque d's first element is at d.leftblock[leftindex] + * and its last element is at d.rightblock[rightindex]. + * + * Unlike Python slice indices, these indices are inclusive on both + * ends. This makes the algorithms for left and right operations + * more symmetrical and it simplifies the design. + * + * The indices, d.leftindex and d.rightindex are always in the range: + * 0 <= index < BLOCKLEN + * + * And their exact relationship is: + * (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex + * + * Whenever d.leftblock == d.rightblock, then: + * d.leftindex + d.len - 1 == d.rightindex + * + * However, when d.leftblock != d.rightblock, the d.leftindex and + * d.rightindex become indices into distinct blocks and either may + * be larger than the other. + * + * Empty deques have: + * d.len == 0 + * d.leftblock == d.rightblock + * d.leftindex == CENTER + 1 + * d.rightindex == CENTER + * + * Checking for d.len == 0 is the intended way to see whether d is empty. + */ + +typedef struct BLOCK { + struct BLOCK *leftlink; + PyObject *data[BLOCKLEN]; + struct BLOCK *rightlink; +} block; + +typedef struct { + PyObject_VAR_HEAD + block *leftblock; + block *rightblock; + Py_ssize_t leftindex; /* 0 <= leftindex < BLOCKLEN */ + Py_ssize_t rightindex; /* 0 <= rightindex < BLOCKLEN */ + size_t state; /* incremented whenever the indices move */ + Py_ssize_t maxlen; /* maxlen is -1 for unbounded deques */ + PyObject *weakreflist; +} dequeobject; + +static PyTypeObject deque_type; + +/* For debug builds, add error checking to track the endpoints + * in the chain of links. The goal is to make sure that link + * assignments only take place at endpoints so that links already + * in use do not get overwritten. + * + * CHECK_END should happen before each assignment to a block's link field. + * MARK_END should happen whenever a link field becomes a new endpoint. + * This happens when new blocks are added or whenever an existing + * block is freed leaving another existing block as the new endpoint. + */ + +#ifndef NDEBUG +#define MARK_END(link) link = NULL; +#define CHECK_END(link) assert(link == NULL); +#define CHECK_NOT_END(link) assert(link != NULL); +#else +#define MARK_END(link) +#define CHECK_END(link) +#define CHECK_NOT_END(link) +#endif + +/* A simple freelisting scheme is used to minimize calls to the memory + allocator. It accommodates common use cases where new blocks are being + added at about the same rate as old blocks are being freed. + */ + +#define MAXFREEBLOCKS 16 +static Py_ssize_t numfreeblocks = 0; +static block *freeblocks[MAXFREEBLOCKS]; + +static block * +newblock(void) { + block *b; + if (numfreeblocks) { + numfreeblocks--; + return freeblocks[numfreeblocks]; + } + b = PyMem_Malloc(sizeof(block)); + if (b != NULL) { + return b; + } + PyErr_NoMemory(); + return NULL; +} + +static void +freeblock(block *b) +{ + if (numfreeblocks < MAXFREEBLOCKS) { + freeblocks[numfreeblocks] = b; + numfreeblocks++; + } else { + PyMem_Free(b); + } +} + +static PyObject * +deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + dequeobject *deque; + block *b; + + /* create dequeobject structure */ + deque = (dequeobject *)type->tp_alloc(type, 0); + if (deque == NULL) + return NULL; + + b = newblock(); + if (b == NULL) { + Py_DECREF(deque); + return NULL; + } + MARK_END(b->leftlink); + MARK_END(b->rightlink); + + assert(BLOCKLEN >= 2); Py_SET_SIZE(deque, 0); - deque->leftblock = b; - deque->rightblock = b; - deque->leftindex = CENTER + 1; - deque->rightindex = CENTER; - deque->state = 0; - deque->maxlen = -1; - deque->weakreflist = NULL; - - return (PyObject *)deque; -} - -static PyObject * -deque_pop(dequeobject *deque, PyObject *unused) -{ - PyObject *item; - block *prevblock; - - if (Py_SIZE(deque) == 0) { - PyErr_SetString(PyExc_IndexError, "pop from an empty deque"); - return NULL; - } - item = deque->rightblock->data[deque->rightindex]; - deque->rightindex--; + deque->leftblock = b; + deque->rightblock = b; + deque->leftindex = CENTER + 1; + deque->rightindex = CENTER; + deque->state = 0; + deque->maxlen = -1; + deque->weakreflist = NULL; + + return (PyObject *)deque; +} + +static PyObject * +deque_pop(dequeobject *deque, PyObject *unused) +{ + PyObject *item; + block *prevblock; + + if (Py_SIZE(deque) == 0) { + PyErr_SetString(PyExc_IndexError, "pop from an empty deque"); + return NULL; + } + item = deque->rightblock->data[deque->rightindex]; + deque->rightindex--; Py_SET_SIZE(deque, Py_SIZE(deque) - 1); - deque->state++; - - if (deque->rightindex < 0) { - if (Py_SIZE(deque)) { - prevblock = deque->rightblock->leftlink; - assert(deque->leftblock != deque->rightblock); - freeblock(deque->rightblock); - CHECK_NOT_END(prevblock); - MARK_END(prevblock->rightlink); - deque->rightblock = prevblock; - deque->rightindex = BLOCKLEN - 1; - } else { - assert(deque->leftblock == deque->rightblock); - assert(deque->leftindex == deque->rightindex+1); - /* re-center instead of freeing a block */ - deque->leftindex = CENTER + 1; - deque->rightindex = CENTER; - } - } - return item; -} - -PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element."); - -static PyObject * -deque_popleft(dequeobject *deque, PyObject *unused) -{ - PyObject *item; - block *prevblock; - - if (Py_SIZE(deque) == 0) { - PyErr_SetString(PyExc_IndexError, "pop from an empty deque"); - return NULL; - } - assert(deque->leftblock != NULL); - item = deque->leftblock->data[deque->leftindex]; - deque->leftindex++; + deque->state++; + + if (deque->rightindex < 0) { + if (Py_SIZE(deque)) { + prevblock = deque->rightblock->leftlink; + assert(deque->leftblock != deque->rightblock); + freeblock(deque->rightblock); + CHECK_NOT_END(prevblock); + MARK_END(prevblock->rightlink); + deque->rightblock = prevblock; + deque->rightindex = BLOCKLEN - 1; + } else { + assert(deque->leftblock == deque->rightblock); + assert(deque->leftindex == deque->rightindex+1); + /* re-center instead of freeing a block */ + deque->leftindex = CENTER + 1; + deque->rightindex = CENTER; + } + } + return item; +} + +PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element."); + +static PyObject * +deque_popleft(dequeobject *deque, PyObject *unused) +{ + PyObject *item; + block *prevblock; + + if (Py_SIZE(deque) == 0) { + PyErr_SetString(PyExc_IndexError, "pop from an empty deque"); + return NULL; + } + assert(deque->leftblock != NULL); + item = deque->leftblock->data[deque->leftindex]; + deque->leftindex++; Py_SET_SIZE(deque, Py_SIZE(deque) - 1); - deque->state++; - - if (deque->leftindex == BLOCKLEN) { - if (Py_SIZE(deque)) { - assert(deque->leftblock != deque->rightblock); - prevblock = deque->leftblock->rightlink; - freeblock(deque->leftblock); - CHECK_NOT_END(prevblock); - MARK_END(prevblock->leftlink); - deque->leftblock = prevblock; - deque->leftindex = 0; - } else { - assert(deque->leftblock == deque->rightblock); - assert(deque->leftindex == deque->rightindex+1); - /* re-center instead of freeing a block */ - deque->leftindex = CENTER + 1; - deque->rightindex = CENTER; - } - } - return item; -} - -PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element."); - -/* The deque's size limit is d.maxlen. The limit can be zero or positive. - * If there is no limit, then d.maxlen == -1. - * - * After an item is added to a deque, we check to see if the size has - * grown past the limit. If it has, we get the size back down to the limit - * by popping an item off of the opposite end. The methods that can - * trigger this are append(), appendleft(), extend(), and extendleft(). - * - * The macro to check whether a deque needs to be trimmed uses a single - * unsigned test that returns true whenever 0 <= maxlen < Py_SIZE(deque). - */ - -#define NEEDS_TRIM(deque, maxlen) ((size_t)(maxlen) < (size_t)(Py_SIZE(deque))) - + deque->state++; + + if (deque->leftindex == BLOCKLEN) { + if (Py_SIZE(deque)) { + assert(deque->leftblock != deque->rightblock); + prevblock = deque->leftblock->rightlink; + freeblock(deque->leftblock); + CHECK_NOT_END(prevblock); + MARK_END(prevblock->leftlink); + deque->leftblock = prevblock; + deque->leftindex = 0; + } else { + assert(deque->leftblock == deque->rightblock); + assert(deque->leftindex == deque->rightindex+1); + /* re-center instead of freeing a block */ + deque->leftindex = CENTER + 1; + deque->rightindex = CENTER; + } + } + return item; +} + +PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element."); + +/* The deque's size limit is d.maxlen. The limit can be zero or positive. + * If there is no limit, then d.maxlen == -1. + * + * After an item is added to a deque, we check to see if the size has + * grown past the limit. If it has, we get the size back down to the limit + * by popping an item off of the opposite end. The methods that can + * trigger this are append(), appendleft(), extend(), and extendleft(). + * + * The macro to check whether a deque needs to be trimmed uses a single + * unsigned test that returns true whenever 0 <= maxlen < Py_SIZE(deque). + */ + +#define NEEDS_TRIM(deque, maxlen) ((size_t)(maxlen) < (size_t)(Py_SIZE(deque))) + static inline int -deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) -{ - if (deque->rightindex == BLOCKLEN - 1) { - block *b = newblock(); - if (b == NULL) - return -1; - b->leftlink = deque->rightblock; - CHECK_END(deque->rightblock->rightlink); - deque->rightblock->rightlink = b; - deque->rightblock = b; - MARK_END(b->rightlink); - deque->rightindex = -1; - } +deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) +{ + if (deque->rightindex == BLOCKLEN - 1) { + block *b = newblock(); + if (b == NULL) + return -1; + b->leftlink = deque->rightblock; + CHECK_END(deque->rightblock->rightlink); + deque->rightblock->rightlink = b; + deque->rightblock = b; + MARK_END(b->rightlink); + deque->rightindex = -1; + } Py_SET_SIZE(deque, Py_SIZE(deque) + 1); - deque->rightindex++; - deque->rightblock->data[deque->rightindex] = item; - if (NEEDS_TRIM(deque, maxlen)) { - PyObject *olditem = deque_popleft(deque, NULL); - Py_DECREF(olditem); - } else { - deque->state++; - } - return 0; -} - -static PyObject * -deque_append(dequeobject *deque, PyObject *item) -{ - Py_INCREF(item); - if (deque_append_internal(deque, item, deque->maxlen) < 0) - return NULL; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque."); - + deque->rightindex++; + deque->rightblock->data[deque->rightindex] = item; + if (NEEDS_TRIM(deque, maxlen)) { + PyObject *olditem = deque_popleft(deque, NULL); + Py_DECREF(olditem); + } else { + deque->state++; + } + return 0; +} + +static PyObject * +deque_append(dequeobject *deque, PyObject *item) +{ + Py_INCREF(item); + if (deque_append_internal(deque, item, deque->maxlen) < 0) + return NULL; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque."); + static inline int -deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) -{ - if (deque->leftindex == 0) { - block *b = newblock(); - if (b == NULL) - return -1; - b->rightlink = deque->leftblock; - CHECK_END(deque->leftblock->leftlink); - deque->leftblock->leftlink = b; - deque->leftblock = b; - MARK_END(b->leftlink); - deque->leftindex = BLOCKLEN; - } +deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) +{ + if (deque->leftindex == 0) { + block *b = newblock(); + if (b == NULL) + return -1; + b->rightlink = deque->leftblock; + CHECK_END(deque->leftblock->leftlink); + deque->leftblock->leftlink = b; + deque->leftblock = b; + MARK_END(b->leftlink); + deque->leftindex = BLOCKLEN; + } Py_SET_SIZE(deque, Py_SIZE(deque) + 1); - deque->leftindex--; - deque->leftblock->data[deque->leftindex] = item; - if (NEEDS_TRIM(deque, deque->maxlen)) { - PyObject *olditem = deque_pop(deque, NULL); - Py_DECREF(olditem); - } else { - deque->state++; - } - return 0; -} - -static PyObject * -deque_appendleft(dequeobject *deque, PyObject *item) -{ - Py_INCREF(item); - if (deque_appendleft_internal(deque, item, deque->maxlen) < 0) - return NULL; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque."); - -static PyObject* -finalize_iterator(PyObject *it) -{ - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); - else { - Py_DECREF(it); - return NULL; - } - } - Py_DECREF(it); - Py_RETURN_NONE; -} - -/* Run an iterator to exhaustion. Shortcut for - the extend/extendleft methods when maxlen == 0. */ -static PyObject* -consume_iterator(PyObject *it) -{ - PyObject *(*iternext)(PyObject *); - PyObject *item; - - iternext = *Py_TYPE(it)->tp_iternext; - while ((item = iternext(it)) != NULL) { - Py_DECREF(item); - } - return finalize_iterator(it); -} - -static PyObject * -deque_extend(dequeobject *deque, PyObject *iterable) -{ - PyObject *it, *item; - PyObject *(*iternext)(PyObject *); - Py_ssize_t maxlen = deque->maxlen; - - /* Handle case where id(deque) == id(iterable) */ - if ((PyObject *)deque == iterable) { - PyObject *result; - PyObject *s = PySequence_List(iterable); - if (s == NULL) - return NULL; - result = deque_extend(deque, s); - Py_DECREF(s); - return result; - } - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - if (maxlen == 0) - return consume_iterator(it); - - /* Space saving heuristic. Start filling from the left */ - if (Py_SIZE(deque) == 0) { - assert(deque->leftblock == deque->rightblock); - assert(deque->leftindex == deque->rightindex+1); - deque->leftindex = 1; - deque->rightindex = 0; - } - - iternext = *Py_TYPE(it)->tp_iternext; - while ((item = iternext(it)) != NULL) { + deque->leftindex--; + deque->leftblock->data[deque->leftindex] = item; + if (NEEDS_TRIM(deque, deque->maxlen)) { + PyObject *olditem = deque_pop(deque, NULL); + Py_DECREF(olditem); + } else { + deque->state++; + } + return 0; +} + +static PyObject * +deque_appendleft(dequeobject *deque, PyObject *item) +{ + Py_INCREF(item); + if (deque_appendleft_internal(deque, item, deque->maxlen) < 0) + return NULL; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque."); + +static PyObject* +finalize_iterator(PyObject *it) +{ + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else { + Py_DECREF(it); + return NULL; + } + } + Py_DECREF(it); + Py_RETURN_NONE; +} + +/* Run an iterator to exhaustion. Shortcut for + the extend/extendleft methods when maxlen == 0. */ +static PyObject* +consume_iterator(PyObject *it) +{ + PyObject *(*iternext)(PyObject *); + PyObject *item; + + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { + Py_DECREF(item); + } + return finalize_iterator(it); +} + +static PyObject * +deque_extend(dequeobject *deque, PyObject *iterable) +{ + PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + Py_ssize_t maxlen = deque->maxlen; + + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extend(deque, s); + Py_DECREF(s); + return result; + } + + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + + if (maxlen == 0) + return consume_iterator(it); + + /* Space saving heuristic. Start filling from the left */ + if (Py_SIZE(deque) == 0) { + assert(deque->leftblock == deque->rightblock); + assert(deque->leftindex == deque->rightindex+1); + deque->leftindex = 1; + deque->rightindex = 0; + } + + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { if (deque_append_internal(deque, item, maxlen) == -1) { Py_DECREF(item); Py_DECREF(it); return NULL; - } - } - return finalize_iterator(it); -} - -PyDoc_STRVAR(extend_doc, -"Extend the right side of the deque with elements from the iterable"); - -static PyObject * -deque_extendleft(dequeobject *deque, PyObject *iterable) -{ - PyObject *it, *item; - PyObject *(*iternext)(PyObject *); - Py_ssize_t maxlen = deque->maxlen; - - /* Handle case where id(deque) == id(iterable) */ - if ((PyObject *)deque == iterable) { - PyObject *result; - PyObject *s = PySequence_List(iterable); - if (s == NULL) - return NULL; - result = deque_extendleft(deque, s); - Py_DECREF(s); - return result; - } - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - if (maxlen == 0) - return consume_iterator(it); - - /* Space saving heuristic. Start filling from the right */ - if (Py_SIZE(deque) == 0) { - assert(deque->leftblock == deque->rightblock); - assert(deque->leftindex == deque->rightindex+1); - deque->leftindex = BLOCKLEN - 1; - deque->rightindex = BLOCKLEN - 2; - } - - iternext = *Py_TYPE(it)->tp_iternext; - while ((item = iternext(it)) != NULL) { + } + } + return finalize_iterator(it); +} + +PyDoc_STRVAR(extend_doc, +"Extend the right side of the deque with elements from the iterable"); + +static PyObject * +deque_extendleft(dequeobject *deque, PyObject *iterable) +{ + PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + Py_ssize_t maxlen = deque->maxlen; + + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extendleft(deque, s); + Py_DECREF(s); + return result; + } + + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + + if (maxlen == 0) + return consume_iterator(it); + + /* Space saving heuristic. Start filling from the right */ + if (Py_SIZE(deque) == 0) { + assert(deque->leftblock == deque->rightblock); + assert(deque->leftindex == deque->rightindex+1); + deque->leftindex = BLOCKLEN - 1; + deque->rightindex = BLOCKLEN - 2; + } + + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { if (deque_appendleft_internal(deque, item, maxlen) == -1) { Py_DECREF(item); Py_DECREF(it); return NULL; - } - } - return finalize_iterator(it); -} - -PyDoc_STRVAR(extendleft_doc, -"Extend the left side of the deque with elements from the iterable"); - -static PyObject * -deque_inplace_concat(dequeobject *deque, PyObject *other) -{ - PyObject *result; - - result = deque_extend(deque, other); - if (result == NULL) - return result; - Py_INCREF(deque); - Py_DECREF(result); - return (PyObject *)deque; -} - -static PyObject * + } + } + return finalize_iterator(it); +} + +PyDoc_STRVAR(extendleft_doc, +"Extend the left side of the deque with elements from the iterable"); + +static PyObject * +deque_inplace_concat(dequeobject *deque, PyObject *other) +{ + PyObject *result; + + result = deque_extend(deque, other); + if (result == NULL) + return result; + Py_INCREF(deque); + Py_DECREF(result); + return (PyObject *)deque; +} + +static PyObject * deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored)) -{ - PyObject *result; - dequeobject *old_deque = (dequeobject *)deque; +{ + PyObject *result; + dequeobject *old_deque = (dequeobject *)deque; if (Py_IS_TYPE(deque, &deque_type)) { - dequeobject *new_deque; - PyObject *rv; - - new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL); - if (new_deque == NULL) - return NULL; - new_deque->maxlen = old_deque->maxlen; - /* Fast path for the deque_repeat() common case where len(deque) == 1 */ - if (Py_SIZE(deque) == 1) { - PyObject *item = old_deque->leftblock->data[old_deque->leftindex]; - rv = deque_append(new_deque, item); - } else { - rv = deque_extend(new_deque, deque); - } - if (rv != NULL) { - Py_DECREF(rv); - return (PyObject *)new_deque; - } - Py_DECREF(new_deque); - return NULL; - } - if (old_deque->maxlen < 0) + dequeobject *new_deque; + PyObject *rv; + + new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL); + if (new_deque == NULL) + return NULL; + new_deque->maxlen = old_deque->maxlen; + /* Fast path for the deque_repeat() common case where len(deque) == 1 */ + if (Py_SIZE(deque) == 1) { + PyObject *item = old_deque->leftblock->data[old_deque->leftindex]; + rv = deque_append(new_deque, item); + } else { + rv = deque_extend(new_deque, deque); + } + if (rv != NULL) { + Py_DECREF(rv); + return (PyObject *)new_deque; + } + Py_DECREF(new_deque); + return NULL; + } + if (old_deque->maxlen < 0) result = PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)), deque); - else - result = PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", - deque, old_deque->maxlen, NULL); - if (result != NULL && !PyObject_TypeCheck(result, &deque_type)) { - PyErr_Format(PyExc_TypeError, - "%.200s() must return a deque, not %.200s", - Py_TYPE(deque)->tp_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; - } - return result; -} - -PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); - -static PyObject * -deque_concat(dequeobject *deque, PyObject *other) -{ - PyObject *new_deque, *result; - int rv; - - rv = PyObject_IsInstance(other, (PyObject *)&deque_type); - if (rv <= 0) { - if (rv == 0) { - PyErr_Format(PyExc_TypeError, - "can only concatenate deque (not \"%.200s\") to deque", + else + result = PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", + deque, old_deque->maxlen, NULL); + if (result != NULL && !PyObject_TypeCheck(result, &deque_type)) { + PyErr_Format(PyExc_TypeError, + "%.200s() must return a deque, not %.200s", + Py_TYPE(deque)->tp_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + return result; +} + +PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); + +static PyObject * +deque_concat(dequeobject *deque, PyObject *other) +{ + PyObject *new_deque, *result; + int rv; + + rv = PyObject_IsInstance(other, (PyObject *)&deque_type); + if (rv <= 0) { + if (rv == 0) { + PyErr_Format(PyExc_TypeError, + "can only concatenate deque (not \"%.200s\") to deque", Py_TYPE(other)->tp_name); - } - return NULL; - } - + } + return NULL; + } + new_deque = deque_copy((PyObject *)deque, NULL); - if (new_deque == NULL) - return NULL; - result = deque_extend((dequeobject *)new_deque, other); - if (result == NULL) { - Py_DECREF(new_deque); - return NULL; - } - Py_DECREF(result); - return new_deque; -} - -static int -deque_clear(dequeobject *deque) -{ - block *b; - block *prevblock; - block *leftblock; - Py_ssize_t leftindex; - Py_ssize_t n, m; - PyObject *item; - PyObject **itemptr, **limit; - - if (Py_SIZE(deque) == 0) - return 0; - - /* During the process of clearing a deque, decrefs can cause the - deque to mutate. To avoid fatal confusion, we have to make the - deque empty before clearing the blocks and never refer to - anything via deque->ref while clearing. (This is the same - technique used for clearing lists, sets, and dicts.) - - Making the deque empty requires allocating a new empty block. In - the unlikely event that memory is full, we fall back to an - alternate method that doesn't require a new block. Repeating - pops in a while-loop is slower, possibly re-entrant (and a clever - adversary could cause it to never terminate). - */ - - b = newblock(); - if (b == NULL) { - PyErr_Clear(); - goto alternate_method; - } - - /* Remember the old size, leftblock, and leftindex */ - n = Py_SIZE(deque); - leftblock = deque->leftblock; - leftindex = deque->leftindex; - - /* Set the deque to be empty using the newly allocated block */ - MARK_END(b->leftlink); - MARK_END(b->rightlink); + if (new_deque == NULL) + return NULL; + result = deque_extend((dequeobject *)new_deque, other); + if (result == NULL) { + Py_DECREF(new_deque); + return NULL; + } + Py_DECREF(result); + return new_deque; +} + +static int +deque_clear(dequeobject *deque) +{ + block *b; + block *prevblock; + block *leftblock; + Py_ssize_t leftindex; + Py_ssize_t n, m; + PyObject *item; + PyObject **itemptr, **limit; + + if (Py_SIZE(deque) == 0) + return 0; + + /* During the process of clearing a deque, decrefs can cause the + deque to mutate. To avoid fatal confusion, we have to make the + deque empty before clearing the blocks and never refer to + anything via deque->ref while clearing. (This is the same + technique used for clearing lists, sets, and dicts.) + + Making the deque empty requires allocating a new empty block. In + the unlikely event that memory is full, we fall back to an + alternate method that doesn't require a new block. Repeating + pops in a while-loop is slower, possibly re-entrant (and a clever + adversary could cause it to never terminate). + */ + + b = newblock(); + if (b == NULL) { + PyErr_Clear(); + goto alternate_method; + } + + /* Remember the old size, leftblock, and leftindex */ + n = Py_SIZE(deque); + leftblock = deque->leftblock; + leftindex = deque->leftindex; + + /* Set the deque to be empty using the newly allocated block */ + MARK_END(b->leftlink); + MARK_END(b->rightlink); Py_SET_SIZE(deque, 0); - deque->leftblock = b; - deque->rightblock = b; - deque->leftindex = CENTER + 1; - deque->rightindex = CENTER; - deque->state++; - - /* Now the old size, leftblock, and leftindex are disconnected from - the empty deque and we can use them to decref the pointers. - */ - m = (BLOCKLEN - leftindex > n) ? n : BLOCKLEN - leftindex; - itemptr = &leftblock->data[leftindex]; - limit = itemptr + m; - n -= m; - while (1) { - if (itemptr == limit) { - if (n == 0) - break; - CHECK_NOT_END(leftblock->rightlink); - prevblock = leftblock; - leftblock = leftblock->rightlink; - m = (n > BLOCKLEN) ? BLOCKLEN : n; - itemptr = leftblock->data; - limit = itemptr + m; - n -= m; - freeblock(prevblock); - } - item = *(itemptr++); - Py_DECREF(item); - } - CHECK_END(leftblock->rightlink); - freeblock(leftblock); - return 0; - - alternate_method: - while (Py_SIZE(deque)) { - item = deque_pop(deque, NULL); - assert (item != NULL); - Py_DECREF(item); - } - return 0; -} - -static PyObject * + deque->leftblock = b; + deque->rightblock = b; + deque->leftindex = CENTER + 1; + deque->rightindex = CENTER; + deque->state++; + + /* Now the old size, leftblock, and leftindex are disconnected from + the empty deque and we can use them to decref the pointers. + */ + m = (BLOCKLEN - leftindex > n) ? n : BLOCKLEN - leftindex; + itemptr = &leftblock->data[leftindex]; + limit = itemptr + m; + n -= m; + while (1) { + if (itemptr == limit) { + if (n == 0) + break; + CHECK_NOT_END(leftblock->rightlink); + prevblock = leftblock; + leftblock = leftblock->rightlink; + m = (n > BLOCKLEN) ? BLOCKLEN : n; + itemptr = leftblock->data; + limit = itemptr + m; + n -= m; + freeblock(prevblock); + } + item = *(itemptr++); + Py_DECREF(item); + } + CHECK_END(leftblock->rightlink); + freeblock(leftblock); + return 0; + + alternate_method: + while (Py_SIZE(deque)) { + item = deque_pop(deque, NULL); + assert (item != NULL); + Py_DECREF(item); + } + return 0; +} + +static PyObject * deque_clearmethod(dequeobject *deque, PyObject *Py_UNUSED(ignored)) -{ - deque_clear(deque); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(clear_doc, "Remove all elements from the deque."); - -static PyObject * -deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) -{ - Py_ssize_t i, m, size; - PyObject *seq; - PyObject *rv; - - size = Py_SIZE(deque); - if (size == 0 || n == 1) { - Py_INCREF(deque); - return (PyObject *)deque; - } - - if (n <= 0) { - deque_clear(deque); - Py_INCREF(deque); - return (PyObject *)deque; - } - - if (size == 1) { - /* common case, repeating a single element */ - PyObject *item = deque->leftblock->data[deque->leftindex]; - - if (deque->maxlen >= 0 && n > deque->maxlen) - n = deque->maxlen; - - deque->state++; - for (i = 0 ; i < n-1 ; ) { - if (deque->rightindex == BLOCKLEN - 1) { - block *b = newblock(); - if (b == NULL) { +{ + deque_clear(deque); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(clear_doc, "Remove all elements from the deque."); + +static PyObject * +deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) +{ + Py_ssize_t i, m, size; + PyObject *seq; + PyObject *rv; + + size = Py_SIZE(deque); + if (size == 0 || n == 1) { + Py_INCREF(deque); + return (PyObject *)deque; + } + + if (n <= 0) { + deque_clear(deque); + Py_INCREF(deque); + return (PyObject *)deque; + } + + if (size == 1) { + /* common case, repeating a single element */ + PyObject *item = deque->leftblock->data[deque->leftindex]; + + if (deque->maxlen >= 0 && n > deque->maxlen) + n = deque->maxlen; + + deque->state++; + for (i = 0 ; i < n-1 ; ) { + if (deque->rightindex == BLOCKLEN - 1) { + block *b = newblock(); + if (b == NULL) { Py_SET_SIZE(deque, Py_SIZE(deque) + i); - return NULL; - } - b->leftlink = deque->rightblock; - CHECK_END(deque->rightblock->rightlink); - deque->rightblock->rightlink = b; - deque->rightblock = b; - MARK_END(b->rightlink); - deque->rightindex = -1; - } - m = n - 1 - i; - if (m > BLOCKLEN - 1 - deque->rightindex) - m = BLOCKLEN - 1 - deque->rightindex; - i += m; - while (m--) { - deque->rightindex++; - Py_INCREF(item); - deque->rightblock->data[deque->rightindex] = item; - } - } + return NULL; + } + b->leftlink = deque->rightblock; + CHECK_END(deque->rightblock->rightlink); + deque->rightblock->rightlink = b; + deque->rightblock = b; + MARK_END(b->rightlink); + deque->rightindex = -1; + } + m = n - 1 - i; + if (m > BLOCKLEN - 1 - deque->rightindex) + m = BLOCKLEN - 1 - deque->rightindex; + i += m; + while (m--) { + deque->rightindex++; + Py_INCREF(item); + deque->rightblock->data[deque->rightindex] = item; + } + } Py_SET_SIZE(deque, Py_SIZE(deque) + i); - Py_INCREF(deque); - return (PyObject *)deque; - } - - if ((size_t)size > PY_SSIZE_T_MAX / (size_t)n) { - return PyErr_NoMemory(); - } - - seq = PySequence_List((PyObject *)deque); - if (seq == NULL) - return seq; - - /* Reduce the number of repetitions when maxlen would be exceeded */ - if (deque->maxlen >= 0 && n * size > deque->maxlen) - n = (deque->maxlen + size - 1) / size; - - for (i = 0 ; i < n-1 ; i++) { - rv = deque_extend(deque, seq); - if (rv == NULL) { - Py_DECREF(seq); - return NULL; - } - Py_DECREF(rv); - } - Py_INCREF(deque); - Py_DECREF(seq); - return (PyObject *)deque; -} - -static PyObject * -deque_repeat(dequeobject *deque, Py_ssize_t n) -{ - dequeobject *new_deque; - PyObject *rv; - + Py_INCREF(deque); + return (PyObject *)deque; + } + + if ((size_t)size > PY_SSIZE_T_MAX / (size_t)n) { + return PyErr_NoMemory(); + } + + seq = PySequence_List((PyObject *)deque); + if (seq == NULL) + return seq; + + /* Reduce the number of repetitions when maxlen would be exceeded */ + if (deque->maxlen >= 0 && n * size > deque->maxlen) + n = (deque->maxlen + size - 1) / size; + + for (i = 0 ; i < n-1 ; i++) { + rv = deque_extend(deque, seq); + if (rv == NULL) { + Py_DECREF(seq); + return NULL; + } + Py_DECREF(rv); + } + Py_INCREF(deque); + Py_DECREF(seq); + return (PyObject *)deque; +} + +static PyObject * +deque_repeat(dequeobject *deque, Py_ssize_t n) +{ + dequeobject *new_deque; + PyObject *rv; + new_deque = (dequeobject *)deque_copy((PyObject *) deque, NULL); - if (new_deque == NULL) - return NULL; - rv = deque_inplace_repeat(new_deque, n); - Py_DECREF(new_deque); - return rv; -} - -/* The rotate() method is part of the public API and is used internally -as a primitive for other methods. - -Rotation by 1 or -1 is a common case, so any optimizations for high -volume rotations should take care not to penalize the common case. - -Conceptually, a rotate by one is equivalent to a pop on one side and an -append on the other. However, a pop/append pair is unnecessarily slow -because it requires an incref/decref pair for an object located randomly -in memory. It is better to just move the object pointer from one block -to the next without changing the reference count. - -When moving batches of pointers, it is tempting to use memcpy() but that -proved to be slower than a simple loop for a variety of reasons. -Memcpy() cannot know in advance that we're copying pointers instead of -bytes, that the source and destination are pointer aligned and -non-overlapping, that moving just one pointer is a common case, that we -never need to move more than BLOCKLEN pointers, and that at least one -pointer is always moved. - -For high volume rotations, newblock() and freeblock() are never called -more than once. Previously emptied blocks are immediately reused as a -destination block. If a block is left-over at the end, it is freed. -*/ - -static int -_deque_rotate(dequeobject *deque, Py_ssize_t n) -{ - block *b = NULL; - block *leftblock = deque->leftblock; - block *rightblock = deque->rightblock; - Py_ssize_t leftindex = deque->leftindex; - Py_ssize_t rightindex = deque->rightindex; - Py_ssize_t len=Py_SIZE(deque), halflen=len>>1; - int rv = -1; - - if (len <= 1) - return 0; - if (n > halflen || n < -halflen) { - n %= len; - if (n > halflen) - n -= len; - else if (n < -halflen) - n += len; - } - assert(len > 1); - assert(-halflen <= n && n <= halflen); - - deque->state++; - while (n > 0) { - if (leftindex == 0) { - if (b == NULL) { - b = newblock(); - if (b == NULL) - goto done; - } - b->rightlink = leftblock; - CHECK_END(leftblock->leftlink); - leftblock->leftlink = b; - leftblock = b; - MARK_END(b->leftlink); - leftindex = BLOCKLEN; - b = NULL; - } - assert(leftindex > 0); - { - PyObject **src, **dest; - Py_ssize_t m = n; - - if (m > rightindex + 1) - m = rightindex + 1; - if (m > leftindex) - m = leftindex; - assert (m > 0 && m <= len); - rightindex -= m; - leftindex -= m; - src = &rightblock->data[rightindex + 1]; - dest = &leftblock->data[leftindex]; - n -= m; - do { - *(dest++) = *(src++); - } while (--m); - } - if (rightindex < 0) { - assert(leftblock != rightblock); - assert(b == NULL); - b = rightblock; - CHECK_NOT_END(rightblock->leftlink); - rightblock = rightblock->leftlink; - MARK_END(rightblock->rightlink); - rightindex = BLOCKLEN - 1; - } - } - while (n < 0) { - if (rightindex == BLOCKLEN - 1) { - if (b == NULL) { - b = newblock(); - if (b == NULL) - goto done; - } - b->leftlink = rightblock; - CHECK_END(rightblock->rightlink); - rightblock->rightlink = b; - rightblock = b; - MARK_END(b->rightlink); - rightindex = -1; - b = NULL; - } - assert (rightindex < BLOCKLEN - 1); - { - PyObject **src, **dest; - Py_ssize_t m = -n; - - if (m > BLOCKLEN - leftindex) - m = BLOCKLEN - leftindex; - if (m > BLOCKLEN - 1 - rightindex) - m = BLOCKLEN - 1 - rightindex; - assert (m > 0 && m <= len); - src = &leftblock->data[leftindex]; - dest = &rightblock->data[rightindex + 1]; - leftindex += m; - rightindex += m; - n += m; - do { - *(dest++) = *(src++); - } while (--m); - } - if (leftindex == BLOCKLEN) { - assert(leftblock != rightblock); - assert(b == NULL); - b = leftblock; - CHECK_NOT_END(leftblock->rightlink); - leftblock = leftblock->rightlink; - MARK_END(leftblock->leftlink); - leftindex = 0; - } - } - rv = 0; -done: - if (b != NULL) - freeblock(b); - deque->leftblock = leftblock; - deque->rightblock = rightblock; - deque->leftindex = leftindex; - deque->rightindex = rightindex; - - return rv; -} - -static PyObject * -deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) -{ - Py_ssize_t n=1; - - if (!_PyArg_ParseStack(args, nargs, "|n:rotate", &n)) { - return NULL; - } - - if (!_deque_rotate(deque, n)) - Py_RETURN_NONE; - return NULL; -} - -PyDoc_STRVAR(rotate_doc, -"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left."); - -static PyObject * -deque_reverse(dequeobject *deque, PyObject *unused) -{ - block *leftblock = deque->leftblock; - block *rightblock = deque->rightblock; - Py_ssize_t leftindex = deque->leftindex; - Py_ssize_t rightindex = deque->rightindex; - Py_ssize_t n = Py_SIZE(deque) >> 1; - PyObject *tmp; - - while (--n >= 0) { - /* Validate that pointers haven't met in the middle */ - assert(leftblock != rightblock || leftindex < rightindex); - CHECK_NOT_END(leftblock); - CHECK_NOT_END(rightblock); - - /* Swap */ - tmp = leftblock->data[leftindex]; - leftblock->data[leftindex] = rightblock->data[rightindex]; - rightblock->data[rightindex] = tmp; - - /* Advance left block/index pair */ - leftindex++; - if (leftindex == BLOCKLEN) { - leftblock = leftblock->rightlink; - leftindex = 0; - } - - /* Step backwards with the right block/index pair */ - rightindex--; - if (rightindex < 0) { - rightblock = rightblock->leftlink; - rightindex = BLOCKLEN - 1; - } - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(reverse_doc, -"D.reverse() -- reverse *IN PLACE*"); - -static PyObject * -deque_count(dequeobject *deque, PyObject *v) -{ - block *b = deque->leftblock; - Py_ssize_t index = deque->leftindex; - Py_ssize_t n = Py_SIZE(deque); - Py_ssize_t count = 0; - size_t start_state = deque->state; - PyObject *item; - int cmp; - - while (--n >= 0) { - CHECK_NOT_END(b); - item = b->data[index]; - Py_INCREF(item); - cmp = PyObject_RichCompareBool(item, v, Py_EQ); - Py_DECREF(item); - if (cmp < 0) - return NULL; - count += cmp; - - if (start_state != deque->state) { - PyErr_SetString(PyExc_RuntimeError, - "deque mutated during iteration"); - return NULL; - } - - /* Advance left block/index pair */ - index++; - if (index == BLOCKLEN) { - b = b->rightlink; - index = 0; - } - } - return PyLong_FromSsize_t(count); -} - -PyDoc_STRVAR(count_doc, -"D.count(value) -> integer -- return number of occurrences of value"); - -static int -deque_contains(dequeobject *deque, PyObject *v) -{ - block *b = deque->leftblock; - Py_ssize_t index = deque->leftindex; - Py_ssize_t n = Py_SIZE(deque); - size_t start_state = deque->state; - PyObject *item; - int cmp; - - while (--n >= 0) { - CHECK_NOT_END(b); - item = b->data[index]; + if (new_deque == NULL) + return NULL; + rv = deque_inplace_repeat(new_deque, n); + Py_DECREF(new_deque); + return rv; +} + +/* The rotate() method is part of the public API and is used internally +as a primitive for other methods. + +Rotation by 1 or -1 is a common case, so any optimizations for high +volume rotations should take care not to penalize the common case. + +Conceptually, a rotate by one is equivalent to a pop on one side and an +append on the other. However, a pop/append pair is unnecessarily slow +because it requires an incref/decref pair for an object located randomly +in memory. It is better to just move the object pointer from one block +to the next without changing the reference count. + +When moving batches of pointers, it is tempting to use memcpy() but that +proved to be slower than a simple loop for a variety of reasons. +Memcpy() cannot know in advance that we're copying pointers instead of +bytes, that the source and destination are pointer aligned and +non-overlapping, that moving just one pointer is a common case, that we +never need to move more than BLOCKLEN pointers, and that at least one +pointer is always moved. + +For high volume rotations, newblock() and freeblock() are never called +more than once. Previously emptied blocks are immediately reused as a +destination block. If a block is left-over at the end, it is freed. +*/ + +static int +_deque_rotate(dequeobject *deque, Py_ssize_t n) +{ + block *b = NULL; + block *leftblock = deque->leftblock; + block *rightblock = deque->rightblock; + Py_ssize_t leftindex = deque->leftindex; + Py_ssize_t rightindex = deque->rightindex; + Py_ssize_t len=Py_SIZE(deque), halflen=len>>1; + int rv = -1; + + if (len <= 1) + return 0; + if (n > halflen || n < -halflen) { + n %= len; + if (n > halflen) + n -= len; + else if (n < -halflen) + n += len; + } + assert(len > 1); + assert(-halflen <= n && n <= halflen); + + deque->state++; + while (n > 0) { + if (leftindex == 0) { + if (b == NULL) { + b = newblock(); + if (b == NULL) + goto done; + } + b->rightlink = leftblock; + CHECK_END(leftblock->leftlink); + leftblock->leftlink = b; + leftblock = b; + MARK_END(b->leftlink); + leftindex = BLOCKLEN; + b = NULL; + } + assert(leftindex > 0); + { + PyObject **src, **dest; + Py_ssize_t m = n; + + if (m > rightindex + 1) + m = rightindex + 1; + if (m > leftindex) + m = leftindex; + assert (m > 0 && m <= len); + rightindex -= m; + leftindex -= m; + src = &rightblock->data[rightindex + 1]; + dest = &leftblock->data[leftindex]; + n -= m; + do { + *(dest++) = *(src++); + } while (--m); + } + if (rightindex < 0) { + assert(leftblock != rightblock); + assert(b == NULL); + b = rightblock; + CHECK_NOT_END(rightblock->leftlink); + rightblock = rightblock->leftlink; + MARK_END(rightblock->rightlink); + rightindex = BLOCKLEN - 1; + } + } + while (n < 0) { + if (rightindex == BLOCKLEN - 1) { + if (b == NULL) { + b = newblock(); + if (b == NULL) + goto done; + } + b->leftlink = rightblock; + CHECK_END(rightblock->rightlink); + rightblock->rightlink = b; + rightblock = b; + MARK_END(b->rightlink); + rightindex = -1; + b = NULL; + } + assert (rightindex < BLOCKLEN - 1); + { + PyObject **src, **dest; + Py_ssize_t m = -n; + + if (m > BLOCKLEN - leftindex) + m = BLOCKLEN - leftindex; + if (m > BLOCKLEN - 1 - rightindex) + m = BLOCKLEN - 1 - rightindex; + assert (m > 0 && m <= len); + src = &leftblock->data[leftindex]; + dest = &rightblock->data[rightindex + 1]; + leftindex += m; + rightindex += m; + n += m; + do { + *(dest++) = *(src++); + } while (--m); + } + if (leftindex == BLOCKLEN) { + assert(leftblock != rightblock); + assert(b == NULL); + b = leftblock; + CHECK_NOT_END(leftblock->rightlink); + leftblock = leftblock->rightlink; + MARK_END(leftblock->leftlink); + leftindex = 0; + } + } + rv = 0; +done: + if (b != NULL) + freeblock(b); + deque->leftblock = leftblock; + deque->rightblock = rightblock; + deque->leftindex = leftindex; + deque->rightindex = rightindex; + + return rv; +} + +static PyObject * +deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) +{ + Py_ssize_t n=1; + + if (!_PyArg_ParseStack(args, nargs, "|n:rotate", &n)) { + return NULL; + } + + if (!_deque_rotate(deque, n)) + Py_RETURN_NONE; + return NULL; +} + +PyDoc_STRVAR(rotate_doc, +"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left."); + +static PyObject * +deque_reverse(dequeobject *deque, PyObject *unused) +{ + block *leftblock = deque->leftblock; + block *rightblock = deque->rightblock; + Py_ssize_t leftindex = deque->leftindex; + Py_ssize_t rightindex = deque->rightindex; + Py_ssize_t n = Py_SIZE(deque) >> 1; + PyObject *tmp; + + while (--n >= 0) { + /* Validate that pointers haven't met in the middle */ + assert(leftblock != rightblock || leftindex < rightindex); + CHECK_NOT_END(leftblock); + CHECK_NOT_END(rightblock); + + /* Swap */ + tmp = leftblock->data[leftindex]; + leftblock->data[leftindex] = rightblock->data[rightindex]; + rightblock->data[rightindex] = tmp; + + /* Advance left block/index pair */ + leftindex++; + if (leftindex == BLOCKLEN) { + leftblock = leftblock->rightlink; + leftindex = 0; + } + + /* Step backwards with the right block/index pair */ + rightindex--; + if (rightindex < 0) { + rightblock = rightblock->leftlink; + rightindex = BLOCKLEN - 1; + } + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(reverse_doc, +"D.reverse() -- reverse *IN PLACE*"); + +static PyObject * +deque_count(dequeobject *deque, PyObject *v) +{ + block *b = deque->leftblock; + Py_ssize_t index = deque->leftindex; + Py_ssize_t n = Py_SIZE(deque); + Py_ssize_t count = 0; + size_t start_state = deque->state; + PyObject *item; + int cmp; + + while (--n >= 0) { + CHECK_NOT_END(b); + item = b->data[index]; Py_INCREF(item); - cmp = PyObject_RichCompareBool(item, v, Py_EQ); + cmp = PyObject_RichCompareBool(item, v, Py_EQ); Py_DECREF(item); - if (cmp) { - return cmp; - } - if (start_state != deque->state) { - PyErr_SetString(PyExc_RuntimeError, - "deque mutated during iteration"); - return -1; - } - index++; - if (index == BLOCKLEN) { - b = b->rightlink; - index = 0; - } - } - return 0; -} - -static Py_ssize_t -deque_len(dequeobject *deque) -{ - return Py_SIZE(deque); -} - -static PyObject * -deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) -{ - Py_ssize_t i, n, start=0, stop=Py_SIZE(deque); - PyObject *v, *item; - block *b = deque->leftblock; - Py_ssize_t index = deque->leftindex; - size_t start_state = deque->state; - int cmp; - - if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index", &v, - _PyEval_SliceIndexNotNone, &start, - _PyEval_SliceIndexNotNone, &stop)) { - return NULL; - } - - if (start < 0) { - start += Py_SIZE(deque); - if (start < 0) - start = 0; - } - if (stop < 0) { - stop += Py_SIZE(deque); - if (stop < 0) - stop = 0; - } - if (stop > Py_SIZE(deque)) - stop = Py_SIZE(deque); - if (start > stop) - start = stop; - assert(0 <= start && start <= stop && stop <= Py_SIZE(deque)); - - for (i=0 ; i < start - BLOCKLEN ; i += BLOCKLEN) { - b = b->rightlink; - } - for ( ; i < start ; i++) { - index++; - if (index == BLOCKLEN) { - b = b->rightlink; - index = 0; - } - } - - n = stop - i; - while (--n >= 0) { - CHECK_NOT_END(b); - item = b->data[index]; - cmp = PyObject_RichCompareBool(item, v, Py_EQ); - if (cmp > 0) - return PyLong_FromSsize_t(stop - n - 1); - if (cmp < 0) - return NULL; - if (start_state != deque->state) { - PyErr_SetString(PyExc_RuntimeError, - "deque mutated during iteration"); - return NULL; - } - index++; - if (index == BLOCKLEN) { - b = b->rightlink; - index = 0; - } - } - PyErr_Format(PyExc_ValueError, "%R is not in deque", v); - return NULL; -} - -PyDoc_STRVAR(index_doc, -"D.index(value, [start, [stop]]) -> integer -- return first index of value.\n" -"Raises ValueError if the value is not present."); - -/* insert(), remove(), and delitem() are implemented in terms of - rotate() for simplicity and reasonable performance near the end - points. If for some reason these methods become popular, it is not - hard to re-implement this using direct data movement (similar to - the code used in list slice assignments) and achieve a performance - boost (by moving each pointer only once instead of twice). -*/ - -static PyObject * -deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) -{ - Py_ssize_t index; - Py_ssize_t n = Py_SIZE(deque); - PyObject *value; - PyObject *rv; - - if (!_PyArg_ParseStack(args, nargs, "nO:insert", &index, &value)) { - return NULL; - } - - if (deque->maxlen == Py_SIZE(deque)) { - PyErr_SetString(PyExc_IndexError, "deque already at its maximum size"); - return NULL; - } - if (index >= n) - return deque_append(deque, value); - if (index <= -n || index == 0) - return deque_appendleft(deque, value); - if (_deque_rotate(deque, -index)) - return NULL; - if (index < 0) - rv = deque_append(deque, value); - else - rv = deque_appendleft(deque, value); - if (rv == NULL) - return NULL; - Py_DECREF(rv); - if (_deque_rotate(deque, index)) - return NULL; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(insert_doc, -"D.insert(index, object) -- insert object before index"); - -static PyObject * -deque_remove(dequeobject *deque, PyObject *value) -{ - Py_ssize_t i, n=Py_SIZE(deque); - - for (i=0 ; ileftblock->data[deque->leftindex]; - int cmp = PyObject_RichCompareBool(item, value, Py_EQ); - - if (Py_SIZE(deque) != n) { - PyErr_SetString(PyExc_IndexError, - "deque mutated during remove()."); - return NULL; - } - if (cmp > 0) { - PyObject *tgt = deque_popleft(deque, NULL); - assert (tgt != NULL); - if (_deque_rotate(deque, i)) - return NULL; - Py_DECREF(tgt); - Py_RETURN_NONE; - } - else if (cmp < 0) { - _deque_rotate(deque, i); - return NULL; - } - _deque_rotate(deque, -1); - } - PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque"); - return NULL; -} - -PyDoc_STRVAR(remove_doc, -"D.remove(value) -- remove first occurrence of value."); - -static int -valid_index(Py_ssize_t i, Py_ssize_t limit) -{ - /* The cast to size_t lets us use just a single comparison - to check whether i is in the range: 0 <= i < limit */ - return (size_t) i < (size_t) limit; -} - -static PyObject * -deque_item(dequeobject *deque, Py_ssize_t i) -{ - block *b; - PyObject *item; - Py_ssize_t n, index=i; - - if (!valid_index(i, Py_SIZE(deque))) { - PyErr_SetString(PyExc_IndexError, "deque index out of range"); - return NULL; - } - - if (i == 0) { - i = deque->leftindex; - b = deque->leftblock; - } else if (i == Py_SIZE(deque) - 1) { - i = deque->rightindex; - b = deque->rightblock; - } else { - i += deque->leftindex; - n = (Py_ssize_t)((size_t) i / BLOCKLEN); - i = (Py_ssize_t)((size_t) i % BLOCKLEN); - if (index < (Py_SIZE(deque) >> 1)) { - b = deque->leftblock; - while (--n >= 0) - b = b->rightlink; - } else { - n = (Py_ssize_t)( - ((size_t)(deque->leftindex + Py_SIZE(deque) - 1)) - / BLOCKLEN - n); - b = deque->rightblock; - while (--n >= 0) - b = b->leftlink; - } - } - item = b->data[i]; - Py_INCREF(item); - return item; -} - -static int -deque_del_item(dequeobject *deque, Py_ssize_t i) -{ - PyObject *item; - int rv; - - assert (i >= 0 && i < Py_SIZE(deque)); - if (_deque_rotate(deque, -i)) - return -1; - item = deque_popleft(deque, NULL); - rv = _deque_rotate(deque, i); - assert (item != NULL); - Py_DECREF(item); - return rv; -} - -static int -deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) -{ - PyObject *old_value; - block *b; - Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i; - - if (!valid_index(i, len)) { - PyErr_SetString(PyExc_IndexError, "deque index out of range"); - return -1; - } - if (v == NULL) - return deque_del_item(deque, i); - - i += deque->leftindex; - n = (Py_ssize_t)((size_t) i / BLOCKLEN); - i = (Py_ssize_t)((size_t) i % BLOCKLEN); - if (index <= halflen) { - b = deque->leftblock; - while (--n >= 0) - b = b->rightlink; - } else { - n = (Py_ssize_t)( - ((size_t)(deque->leftindex + Py_SIZE(deque) - 1)) - / BLOCKLEN - n); - b = deque->rightblock; - while (--n >= 0) - b = b->leftlink; - } - Py_INCREF(v); - old_value = b->data[i]; - b->data[i] = v; - Py_DECREF(old_value); - return 0; -} - -static void -deque_dealloc(dequeobject *deque) -{ - PyObject_GC_UnTrack(deque); - if (deque->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) deque); - if (deque->leftblock != NULL) { - deque_clear(deque); - assert(deque->leftblock != NULL); - freeblock(deque->leftblock); - } - deque->leftblock = NULL; - deque->rightblock = NULL; - Py_TYPE(deque)->tp_free(deque); -} - -static int -deque_traverse(dequeobject *deque, visitproc visit, void *arg) -{ - block *b; - PyObject *item; - Py_ssize_t index; - Py_ssize_t indexlo = deque->leftindex; - Py_ssize_t indexhigh; - - for (b = deque->leftblock; b != deque->rightblock; b = b->rightlink) { - for (index = indexlo; index < BLOCKLEN ; index++) { - item = b->data[index]; - Py_VISIT(item); - } - indexlo = 0; - } - indexhigh = deque->rightindex; - for (index = indexlo; index <= indexhigh; index++) { - item = b->data[index]; - Py_VISIT(item); - } - return 0; -} - -static PyObject * -deque_reduce(dequeobject *deque, PyObject *Py_UNUSED(ignored)) -{ - PyObject *dict, *it; - _Py_IDENTIFIER(__dict__); - - if (_PyObject_LookupAttrId((PyObject *)deque, &PyId___dict__, &dict) < 0) { - return NULL; - } - if (dict == NULL) { - dict = Py_None; - Py_INCREF(dict); - } - - it = PyObject_GetIter((PyObject *)deque); - if (it == NULL) { - Py_DECREF(dict); - return NULL; - } - - if (deque->maxlen < 0) { - return Py_BuildValue("O()NN", Py_TYPE(deque), dict, it); - } - else { - return Py_BuildValue("O(()n)NN", Py_TYPE(deque), deque->maxlen, dict, it); - } -} - -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - -static PyObject * -deque_repr(PyObject *deque) -{ - PyObject *aslist, *result; - int i; - - i = Py_ReprEnter(deque); - if (i != 0) { - if (i < 0) - return NULL; - return PyUnicode_FromString("[...]"); - } - - aslist = PySequence_List(deque); - if (aslist == NULL) { - Py_ReprLeave(deque); - return NULL; - } - if (((dequeobject *)deque)->maxlen >= 0) - result = PyUnicode_FromFormat("%s(%R, maxlen=%zd)", - _PyType_Name(Py_TYPE(deque)), aslist, - ((dequeobject *)deque)->maxlen); - else - result = PyUnicode_FromFormat("%s(%R)", - _PyType_Name(Py_TYPE(deque)), aslist); - Py_ReprLeave(deque); - Py_DECREF(aslist); - return result; -} - -static PyObject * -deque_richcompare(PyObject *v, PyObject *w, int op) -{ - PyObject *it1=NULL, *it2=NULL, *x, *y; - Py_ssize_t vs, ws; - int b, cmp=-1; - - if (!PyObject_TypeCheck(v, &deque_type) || - !PyObject_TypeCheck(w, &deque_type)) { - Py_RETURN_NOTIMPLEMENTED; - } - - /* Shortcuts */ - vs = Py_SIZE((dequeobject *)v); - ws = Py_SIZE((dequeobject *)w); - if (op == Py_EQ) { - if (v == w) - Py_RETURN_TRUE; - if (vs != ws) - Py_RETURN_FALSE; - } - if (op == Py_NE) { - if (v == w) - Py_RETURN_FALSE; - if (vs != ws) - Py_RETURN_TRUE; - } - - /* Search for the first index where items are different */ - it1 = PyObject_GetIter(v); - if (it1 == NULL) - goto done; - it2 = PyObject_GetIter(w); - if (it2 == NULL) - goto done; - for (;;) { - x = PyIter_Next(it1); - if (x == NULL && PyErr_Occurred()) - goto done; - y = PyIter_Next(it2); - if (x == NULL || y == NULL) - break; - b = PyObject_RichCompareBool(x, y, Py_EQ); - if (b == 0) { - cmp = PyObject_RichCompareBool(x, y, op); - Py_DECREF(x); - Py_DECREF(y); - goto done; - } - Py_DECREF(x); - Py_DECREF(y); - if (b < 0) - goto done; - } - /* We reached the end of one deque or both */ - Py_XDECREF(x); - Py_XDECREF(y); - if (PyErr_Occurred()) - goto done; - switch (op) { - case Py_LT: cmp = y != NULL; break; /* if w was longer */ - case Py_LE: cmp = x == NULL; break; /* if v was not longer */ - case Py_EQ: cmp = x == y; break; /* if we reached the end of both */ - case Py_NE: cmp = x != y; break; /* if one deque continues */ - case Py_GT: cmp = x != NULL; break; /* if v was longer */ - case Py_GE: cmp = y == NULL; break; /* if w was not longer */ - } - -done: - Py_XDECREF(it1); - Py_XDECREF(it2); - if (cmp == 1) - Py_RETURN_TRUE; - if (cmp == 0) - Py_RETURN_FALSE; - return NULL; -} - -static int -deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs) -{ - PyObject *iterable = NULL; - PyObject *maxlenobj = NULL; - Py_ssize_t maxlen = -1; - char *kwlist[] = {"iterable", "maxlen", 0}; - - if (kwdargs == NULL && PyTuple_GET_SIZE(args) <= 2) { - if (PyTuple_GET_SIZE(args) > 0) { - iterable = PyTuple_GET_ITEM(args, 0); - } - if (PyTuple_GET_SIZE(args) > 1) { - maxlenobj = PyTuple_GET_ITEM(args, 1); - } - } else { - if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist, - &iterable, &maxlenobj)) - return -1; - } - if (maxlenobj != NULL && maxlenobj != Py_None) { - maxlen = PyLong_AsSsize_t(maxlenobj); - if (maxlen == -1 && PyErr_Occurred()) - return -1; - if (maxlen < 0) { - PyErr_SetString(PyExc_ValueError, "maxlen must be non-negative"); - return -1; - } - } - deque->maxlen = maxlen; - if (Py_SIZE(deque) > 0) - deque_clear(deque); - if (iterable != NULL) { - PyObject *rv = deque_extend(deque, iterable); - if (rv == NULL) - return -1; - Py_DECREF(rv); - } - return 0; -} - -static PyObject * -deque_sizeof(dequeobject *deque, void *unused) -{ - Py_ssize_t res; - Py_ssize_t blocks; - - res = _PyObject_SIZE(Py_TYPE(deque)); - blocks = (size_t)(deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN; - assert(deque->leftindex + Py_SIZE(deque) - 1 == - (blocks - 1) * BLOCKLEN + deque->rightindex); - res += blocks * sizeof(block); - return PyLong_FromSsize_t(res); -} - -PyDoc_STRVAR(sizeof_doc, -"D.__sizeof__() -- size of D in memory, in bytes"); - -static int -deque_bool(dequeobject *deque) -{ - return Py_SIZE(deque) != 0; -} - -static PyObject * -deque_get_maxlen(dequeobject *deque, void *Py_UNUSED(ignored)) -{ - if (deque->maxlen < 0) - Py_RETURN_NONE; - return PyLong_FromSsize_t(deque->maxlen); -} - - -/* deque object ********************************************************/ - -static PyGetSetDef deque_getset[] = { - {"maxlen", (getter)deque_get_maxlen, (setter)NULL, - "maximum size of a deque or None if unbounded"}, - {0} -}; - -static PySequenceMethods deque_as_sequence = { - (lenfunc)deque_len, /* sq_length */ - (binaryfunc)deque_concat, /* sq_concat */ - (ssizeargfunc)deque_repeat, /* sq_repeat */ - (ssizeargfunc)deque_item, /* sq_item */ - 0, /* sq_slice */ - (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)deque_contains, /* sq_contains */ - (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ - (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */ -}; - -static PyNumberMethods deque_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - (inquiry)deque_bool, /* nb_bool */ - 0, /* nb_invert */ - }; - -static PyObject *deque_iter(dequeobject *deque); + if (cmp < 0) + return NULL; + count += cmp; + + if (start_state != deque->state) { + PyErr_SetString(PyExc_RuntimeError, + "deque mutated during iteration"); + return NULL; + } + + /* Advance left block/index pair */ + index++; + if (index == BLOCKLEN) { + b = b->rightlink; + index = 0; + } + } + return PyLong_FromSsize_t(count); +} + +PyDoc_STRVAR(count_doc, +"D.count(value) -> integer -- return number of occurrences of value"); + +static int +deque_contains(dequeobject *deque, PyObject *v) +{ + block *b = deque->leftblock; + Py_ssize_t index = deque->leftindex; + Py_ssize_t n = Py_SIZE(deque); + size_t start_state = deque->state; + PyObject *item; + int cmp; + + while (--n >= 0) { + CHECK_NOT_END(b); + item = b->data[index]; + Py_INCREF(item); + cmp = PyObject_RichCompareBool(item, v, Py_EQ); + Py_DECREF(item); + if (cmp) { + return cmp; + } + if (start_state != deque->state) { + PyErr_SetString(PyExc_RuntimeError, + "deque mutated during iteration"); + return -1; + } + index++; + if (index == BLOCKLEN) { + b = b->rightlink; + index = 0; + } + } + return 0; +} + +static Py_ssize_t +deque_len(dequeobject *deque) +{ + return Py_SIZE(deque); +} + +static PyObject * +deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) +{ + Py_ssize_t i, n, start=0, stop=Py_SIZE(deque); + PyObject *v, *item; + block *b = deque->leftblock; + Py_ssize_t index = deque->leftindex; + size_t start_state = deque->state; + int cmp; + + if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index", &v, + _PyEval_SliceIndexNotNone, &start, + _PyEval_SliceIndexNotNone, &stop)) { + return NULL; + } + + if (start < 0) { + start += Py_SIZE(deque); + if (start < 0) + start = 0; + } + if (stop < 0) { + stop += Py_SIZE(deque); + if (stop < 0) + stop = 0; + } + if (stop > Py_SIZE(deque)) + stop = Py_SIZE(deque); + if (start > stop) + start = stop; + assert(0 <= start && start <= stop && stop <= Py_SIZE(deque)); + + for (i=0 ; i < start - BLOCKLEN ; i += BLOCKLEN) { + b = b->rightlink; + } + for ( ; i < start ; i++) { + index++; + if (index == BLOCKLEN) { + b = b->rightlink; + index = 0; + } + } + + n = stop - i; + while (--n >= 0) { + CHECK_NOT_END(b); + item = b->data[index]; + cmp = PyObject_RichCompareBool(item, v, Py_EQ); + if (cmp > 0) + return PyLong_FromSsize_t(stop - n - 1); + if (cmp < 0) + return NULL; + if (start_state != deque->state) { + PyErr_SetString(PyExc_RuntimeError, + "deque mutated during iteration"); + return NULL; + } + index++; + if (index == BLOCKLEN) { + b = b->rightlink; + index = 0; + } + } + PyErr_Format(PyExc_ValueError, "%R is not in deque", v); + return NULL; +} + +PyDoc_STRVAR(index_doc, +"D.index(value, [start, [stop]]) -> integer -- return first index of value.\n" +"Raises ValueError if the value is not present."); + +/* insert(), remove(), and delitem() are implemented in terms of + rotate() for simplicity and reasonable performance near the end + points. If for some reason these methods become popular, it is not + hard to re-implement this using direct data movement (similar to + the code used in list slice assignments) and achieve a performance + boost (by moving each pointer only once instead of twice). +*/ + +static PyObject * +deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) +{ + Py_ssize_t index; + Py_ssize_t n = Py_SIZE(deque); + PyObject *value; + PyObject *rv; + + if (!_PyArg_ParseStack(args, nargs, "nO:insert", &index, &value)) { + return NULL; + } + + if (deque->maxlen == Py_SIZE(deque)) { + PyErr_SetString(PyExc_IndexError, "deque already at its maximum size"); + return NULL; + } + if (index >= n) + return deque_append(deque, value); + if (index <= -n || index == 0) + return deque_appendleft(deque, value); + if (_deque_rotate(deque, -index)) + return NULL; + if (index < 0) + rv = deque_append(deque, value); + else + rv = deque_appendleft(deque, value); + if (rv == NULL) + return NULL; + Py_DECREF(rv); + if (_deque_rotate(deque, index)) + return NULL; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(insert_doc, +"D.insert(index, object) -- insert object before index"); + +static PyObject * +deque_remove(dequeobject *deque, PyObject *value) +{ + Py_ssize_t i, n=Py_SIZE(deque); + + for (i=0 ; ileftblock->data[deque->leftindex]; + int cmp = PyObject_RichCompareBool(item, value, Py_EQ); + + if (Py_SIZE(deque) != n) { + PyErr_SetString(PyExc_IndexError, + "deque mutated during remove()."); + return NULL; + } + if (cmp > 0) { + PyObject *tgt = deque_popleft(deque, NULL); + assert (tgt != NULL); + if (_deque_rotate(deque, i)) + return NULL; + Py_DECREF(tgt); + Py_RETURN_NONE; + } + else if (cmp < 0) { + _deque_rotate(deque, i); + return NULL; + } + _deque_rotate(deque, -1); + } + PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque"); + return NULL; +} + +PyDoc_STRVAR(remove_doc, +"D.remove(value) -- remove first occurrence of value."); + +static int +valid_index(Py_ssize_t i, Py_ssize_t limit) +{ + /* The cast to size_t lets us use just a single comparison + to check whether i is in the range: 0 <= i < limit */ + return (size_t) i < (size_t) limit; +} + +static PyObject * +deque_item(dequeobject *deque, Py_ssize_t i) +{ + block *b; + PyObject *item; + Py_ssize_t n, index=i; + + if (!valid_index(i, Py_SIZE(deque))) { + PyErr_SetString(PyExc_IndexError, "deque index out of range"); + return NULL; + } + + if (i == 0) { + i = deque->leftindex; + b = deque->leftblock; + } else if (i == Py_SIZE(deque) - 1) { + i = deque->rightindex; + b = deque->rightblock; + } else { + i += deque->leftindex; + n = (Py_ssize_t)((size_t) i / BLOCKLEN); + i = (Py_ssize_t)((size_t) i % BLOCKLEN); + if (index < (Py_SIZE(deque) >> 1)) { + b = deque->leftblock; + while (--n >= 0) + b = b->rightlink; + } else { + n = (Py_ssize_t)( + ((size_t)(deque->leftindex + Py_SIZE(deque) - 1)) + / BLOCKLEN - n); + b = deque->rightblock; + while (--n >= 0) + b = b->leftlink; + } + } + item = b->data[i]; + Py_INCREF(item); + return item; +} + +static int +deque_del_item(dequeobject *deque, Py_ssize_t i) +{ + PyObject *item; + int rv; + + assert (i >= 0 && i < Py_SIZE(deque)); + if (_deque_rotate(deque, -i)) + return -1; + item = deque_popleft(deque, NULL); + rv = _deque_rotate(deque, i); + assert (item != NULL); + Py_DECREF(item); + return rv; +} + +static int +deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) +{ + PyObject *old_value; + block *b; + Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i; + + if (!valid_index(i, len)) { + PyErr_SetString(PyExc_IndexError, "deque index out of range"); + return -1; + } + if (v == NULL) + return deque_del_item(deque, i); + + i += deque->leftindex; + n = (Py_ssize_t)((size_t) i / BLOCKLEN); + i = (Py_ssize_t)((size_t) i % BLOCKLEN); + if (index <= halflen) { + b = deque->leftblock; + while (--n >= 0) + b = b->rightlink; + } else { + n = (Py_ssize_t)( + ((size_t)(deque->leftindex + Py_SIZE(deque) - 1)) + / BLOCKLEN - n); + b = deque->rightblock; + while (--n >= 0) + b = b->leftlink; + } + Py_INCREF(v); + old_value = b->data[i]; + b->data[i] = v; + Py_DECREF(old_value); + return 0; +} + +static void +deque_dealloc(dequeobject *deque) +{ + PyObject_GC_UnTrack(deque); + if (deque->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) deque); + if (deque->leftblock != NULL) { + deque_clear(deque); + assert(deque->leftblock != NULL); + freeblock(deque->leftblock); + } + deque->leftblock = NULL; + deque->rightblock = NULL; + Py_TYPE(deque)->tp_free(deque); +} + +static int +deque_traverse(dequeobject *deque, visitproc visit, void *arg) +{ + block *b; + PyObject *item; + Py_ssize_t index; + Py_ssize_t indexlo = deque->leftindex; + Py_ssize_t indexhigh; + + for (b = deque->leftblock; b != deque->rightblock; b = b->rightlink) { + for (index = indexlo; index < BLOCKLEN ; index++) { + item = b->data[index]; + Py_VISIT(item); + } + indexlo = 0; + } + indexhigh = deque->rightindex; + for (index = indexlo; index <= indexhigh; index++) { + item = b->data[index]; + Py_VISIT(item); + } + return 0; +} + +static PyObject * +deque_reduce(dequeobject *deque, PyObject *Py_UNUSED(ignored)) +{ + PyObject *dict, *it; + _Py_IDENTIFIER(__dict__); + + if (_PyObject_LookupAttrId((PyObject *)deque, &PyId___dict__, &dict) < 0) { + return NULL; + } + if (dict == NULL) { + dict = Py_None; + Py_INCREF(dict); + } + + it = PyObject_GetIter((PyObject *)deque); + if (it == NULL) { + Py_DECREF(dict); + return NULL; + } + + if (deque->maxlen < 0) { + return Py_BuildValue("O()NN", Py_TYPE(deque), dict, it); + } + else { + return Py_BuildValue("O(()n)NN", Py_TYPE(deque), deque->maxlen, dict, it); + } +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyObject * +deque_repr(PyObject *deque) +{ + PyObject *aslist, *result; + int i; + + i = Py_ReprEnter(deque); + if (i != 0) { + if (i < 0) + return NULL; + return PyUnicode_FromString("[...]"); + } + + aslist = PySequence_List(deque); + if (aslist == NULL) { + Py_ReprLeave(deque); + return NULL; + } + if (((dequeobject *)deque)->maxlen >= 0) + result = PyUnicode_FromFormat("%s(%R, maxlen=%zd)", + _PyType_Name(Py_TYPE(deque)), aslist, + ((dequeobject *)deque)->maxlen); + else + result = PyUnicode_FromFormat("%s(%R)", + _PyType_Name(Py_TYPE(deque)), aslist); + Py_ReprLeave(deque); + Py_DECREF(aslist); + return result; +} + +static PyObject * +deque_richcompare(PyObject *v, PyObject *w, int op) +{ + PyObject *it1=NULL, *it2=NULL, *x, *y; + Py_ssize_t vs, ws; + int b, cmp=-1; + + if (!PyObject_TypeCheck(v, &deque_type) || + !PyObject_TypeCheck(w, &deque_type)) { + Py_RETURN_NOTIMPLEMENTED; + } + + /* Shortcuts */ + vs = Py_SIZE((dequeobject *)v); + ws = Py_SIZE((dequeobject *)w); + if (op == Py_EQ) { + if (v == w) + Py_RETURN_TRUE; + if (vs != ws) + Py_RETURN_FALSE; + } + if (op == Py_NE) { + if (v == w) + Py_RETURN_FALSE; + if (vs != ws) + Py_RETURN_TRUE; + } + + /* Search for the first index where items are different */ + it1 = PyObject_GetIter(v); + if (it1 == NULL) + goto done; + it2 = PyObject_GetIter(w); + if (it2 == NULL) + goto done; + for (;;) { + x = PyIter_Next(it1); + if (x == NULL && PyErr_Occurred()) + goto done; + y = PyIter_Next(it2); + if (x == NULL || y == NULL) + break; + b = PyObject_RichCompareBool(x, y, Py_EQ); + if (b == 0) { + cmp = PyObject_RichCompareBool(x, y, op); + Py_DECREF(x); + Py_DECREF(y); + goto done; + } + Py_DECREF(x); + Py_DECREF(y); + if (b < 0) + goto done; + } + /* We reached the end of one deque or both */ + Py_XDECREF(x); + Py_XDECREF(y); + if (PyErr_Occurred()) + goto done; + switch (op) { + case Py_LT: cmp = y != NULL; break; /* if w was longer */ + case Py_LE: cmp = x == NULL; break; /* if v was not longer */ + case Py_EQ: cmp = x == y; break; /* if we reached the end of both */ + case Py_NE: cmp = x != y; break; /* if one deque continues */ + case Py_GT: cmp = x != NULL; break; /* if v was longer */ + case Py_GE: cmp = y == NULL; break; /* if w was not longer */ + } + +done: + Py_XDECREF(it1); + Py_XDECREF(it2); + if (cmp == 1) + Py_RETURN_TRUE; + if (cmp == 0) + Py_RETURN_FALSE; + return NULL; +} + +static int +deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs) +{ + PyObject *iterable = NULL; + PyObject *maxlenobj = NULL; + Py_ssize_t maxlen = -1; + char *kwlist[] = {"iterable", "maxlen", 0}; + + if (kwdargs == NULL && PyTuple_GET_SIZE(args) <= 2) { + if (PyTuple_GET_SIZE(args) > 0) { + iterable = PyTuple_GET_ITEM(args, 0); + } + if (PyTuple_GET_SIZE(args) > 1) { + maxlenobj = PyTuple_GET_ITEM(args, 1); + } + } else { + if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist, + &iterable, &maxlenobj)) + return -1; + } + if (maxlenobj != NULL && maxlenobj != Py_None) { + maxlen = PyLong_AsSsize_t(maxlenobj); + if (maxlen == -1 && PyErr_Occurred()) + return -1; + if (maxlen < 0) { + PyErr_SetString(PyExc_ValueError, "maxlen must be non-negative"); + return -1; + } + } + deque->maxlen = maxlen; + if (Py_SIZE(deque) > 0) + deque_clear(deque); + if (iterable != NULL) { + PyObject *rv = deque_extend(deque, iterable); + if (rv == NULL) + return -1; + Py_DECREF(rv); + } + return 0; +} + +static PyObject * +deque_sizeof(dequeobject *deque, void *unused) +{ + Py_ssize_t res; + Py_ssize_t blocks; + + res = _PyObject_SIZE(Py_TYPE(deque)); + blocks = (size_t)(deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN; + assert(deque->leftindex + Py_SIZE(deque) - 1 == + (blocks - 1) * BLOCKLEN + deque->rightindex); + res += blocks * sizeof(block); + return PyLong_FromSsize_t(res); +} + +PyDoc_STRVAR(sizeof_doc, +"D.__sizeof__() -- size of D in memory, in bytes"); + +static int +deque_bool(dequeobject *deque) +{ + return Py_SIZE(deque) != 0; +} + +static PyObject * +deque_get_maxlen(dequeobject *deque, void *Py_UNUSED(ignored)) +{ + if (deque->maxlen < 0) + Py_RETURN_NONE; + return PyLong_FromSsize_t(deque->maxlen); +} + + +/* deque object ********************************************************/ + +static PyGetSetDef deque_getset[] = { + {"maxlen", (getter)deque_get_maxlen, (setter)NULL, + "maximum size of a deque or None if unbounded"}, + {0} +}; + +static PySequenceMethods deque_as_sequence = { + (lenfunc)deque_len, /* sq_length */ + (binaryfunc)deque_concat, /* sq_concat */ + (ssizeargfunc)deque_repeat, /* sq_repeat */ + (ssizeargfunc)deque_item, /* sq_item */ + 0, /* sq_slice */ + (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)deque_contains, /* sq_contains */ + (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ + (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */ +}; + +static PyNumberMethods deque_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + (inquiry)deque_bool, /* nb_bool */ + 0, /* nb_invert */ + }; + +static PyObject *deque_iter(dequeobject *deque); static PyObject *deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored)); -PyDoc_STRVAR(reversed_doc, - "D.__reversed__() -- return a reverse iterator over the deque"); - -static PyMethodDef deque_methods[] = { - {"append", (PyCFunction)deque_append, - METH_O, append_doc}, - {"appendleft", (PyCFunction)deque_appendleft, - METH_O, appendleft_doc}, - {"clear", (PyCFunction)deque_clearmethod, - METH_NOARGS, clear_doc}, +PyDoc_STRVAR(reversed_doc, + "D.__reversed__() -- return a reverse iterator over the deque"); + +static PyMethodDef deque_methods[] = { + {"append", (PyCFunction)deque_append, + METH_O, append_doc}, + {"appendleft", (PyCFunction)deque_appendleft, + METH_O, appendleft_doc}, + {"clear", (PyCFunction)deque_clearmethod, + METH_NOARGS, clear_doc}, {"__copy__", deque_copy, - METH_NOARGS, copy_doc}, + METH_NOARGS, copy_doc}, {"copy", deque_copy, - METH_NOARGS, copy_doc}, - {"count", (PyCFunction)deque_count, - METH_O, count_doc}, - {"extend", (PyCFunction)deque_extend, - METH_O, extend_doc}, - {"extendleft", (PyCFunction)deque_extendleft, - METH_O, extendleft_doc}, + METH_NOARGS, copy_doc}, + {"count", (PyCFunction)deque_count, + METH_O, count_doc}, + {"extend", (PyCFunction)deque_extend, + METH_O, extend_doc}, + {"extendleft", (PyCFunction)deque_extendleft, + METH_O, extendleft_doc}, {"index", (PyCFunction)(void(*)(void))deque_index, - METH_FASTCALL, index_doc}, + METH_FASTCALL, index_doc}, {"insert", (PyCFunction)(void(*)(void))deque_insert, - METH_FASTCALL, insert_doc}, - {"pop", (PyCFunction)deque_pop, - METH_NOARGS, pop_doc}, - {"popleft", (PyCFunction)deque_popleft, - METH_NOARGS, popleft_doc}, - {"__reduce__", (PyCFunction)deque_reduce, - METH_NOARGS, reduce_doc}, - {"remove", (PyCFunction)deque_remove, - METH_O, remove_doc}, - {"__reversed__", (PyCFunction)deque_reviter, - METH_NOARGS, reversed_doc}, - {"reverse", (PyCFunction)deque_reverse, - METH_NOARGS, reverse_doc}, + METH_FASTCALL, insert_doc}, + {"pop", (PyCFunction)deque_pop, + METH_NOARGS, pop_doc}, + {"popleft", (PyCFunction)deque_popleft, + METH_NOARGS, popleft_doc}, + {"__reduce__", (PyCFunction)deque_reduce, + METH_NOARGS, reduce_doc}, + {"remove", (PyCFunction)deque_remove, + METH_O, remove_doc}, + {"__reversed__", (PyCFunction)deque_reviter, + METH_NOARGS, reversed_doc}, + {"reverse", (PyCFunction)deque_reverse, + METH_NOARGS, reverse_doc}, {"rotate", (PyCFunction)(void(*)(void))deque_rotate, - METH_FASTCALL, rotate_doc}, - {"__sizeof__", (PyCFunction)deque_sizeof, - METH_NOARGS, sizeof_doc}, + METH_FASTCALL, rotate_doc}, + {"__sizeof__", (PyCFunction)deque_sizeof, + METH_NOARGS, sizeof_doc}, {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(deque_doc, -"deque([iterable[, maxlen]]) --> deque object\n\ -\n\ -A list-like sequence optimized for data accesses near its endpoints."); - -static PyTypeObject deque_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "collections.deque", /* tp_name */ - sizeof(dequeobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)deque_dealloc, /* tp_dealloc */ + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(deque_doc, +"deque([iterable[, maxlen]]) --> deque object\n\ +\n\ +A list-like sequence optimized for data accesses near its endpoints."); + +static PyTypeObject deque_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "collections.deque", /* tp_name */ + sizeof(dequeobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)deque_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - deque_repr, /* tp_repr */ - &deque_as_number, /* tp_as_number */ - &deque_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - deque_doc, /* tp_doc */ - (traverseproc)deque_traverse, /* tp_traverse */ - (inquiry)deque_clear, /* tp_clear */ - (richcmpfunc)deque_richcompare, /* tp_richcompare */ - offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/ - (getiterfunc)deque_iter, /* tp_iter */ - 0, /* tp_iternext */ - deque_methods, /* tp_methods */ - 0, /* tp_members */ - deque_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)deque_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - deque_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - -/*********************** Deque Iterator **************************/ - -typedef struct { - PyObject_HEAD - block *b; - Py_ssize_t index; - dequeobject *deque; - size_t state; /* state when the iterator is created */ - Py_ssize_t counter; /* number of items remaining for iteration */ -} dequeiterobject; - -static PyTypeObject dequeiter_type; - -static PyObject * -deque_iter(dequeobject *deque) -{ - dequeiterobject *it; - - it = PyObject_GC_New(dequeiterobject, &dequeiter_type); - if (it == NULL) - return NULL; - it->b = deque->leftblock; - it->index = deque->leftindex; - Py_INCREF(deque); - it->deque = deque; - it->state = deque->state; - it->counter = Py_SIZE(deque); - PyObject_GC_Track(it); - return (PyObject *)it; -} - -static int -dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg) -{ - Py_VISIT(dio->deque); - return 0; -} - -static void -dequeiter_dealloc(dequeiterobject *dio) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(dio); - Py_XDECREF(dio->deque); - PyObject_GC_Del(dio); -} - -static PyObject * -dequeiter_next(dequeiterobject *it) -{ - PyObject *item; - - if (it->deque->state != it->state) { - it->counter = 0; - PyErr_SetString(PyExc_RuntimeError, - "deque mutated during iteration"); - return NULL; - } - if (it->counter == 0) - return NULL; - assert (!(it->b == it->deque->rightblock && - it->index > it->deque->rightindex)); - - item = it->b->data[it->index]; - it->index++; - it->counter--; - if (it->index == BLOCKLEN && it->counter > 0) { - CHECK_NOT_END(it->b->rightlink); - it->b = it->b->rightlink; - it->index = 0; - } - Py_INCREF(item); - return item; -} - -static PyObject * -dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - Py_ssize_t i, index=0; - PyObject *deque; - dequeiterobject *it; - if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index)) - return NULL; - assert(type == &dequeiter_type); - - it = (dequeiterobject*)deque_iter((dequeobject *)deque); - if (!it) - return NULL; - /* consume items from the queue */ - for(i=0; icounter) { - Py_DECREF(it); - return NULL; - } else - break; - } - } - return (PyObject*)it; -} - -static PyObject * + deque_repr, /* tp_repr */ + &deque_as_number, /* tp_as_number */ + &deque_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + PyObject_HashNotImplemented, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + /* tp_flags */ + deque_doc, /* tp_doc */ + (traverseproc)deque_traverse, /* tp_traverse */ + (inquiry)deque_clear, /* tp_clear */ + (richcmpfunc)deque_richcompare, /* tp_richcompare */ + offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/ + (getiterfunc)deque_iter, /* tp_iter */ + 0, /* tp_iternext */ + deque_methods, /* tp_methods */ + 0, /* tp_members */ + deque_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)deque_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + deque_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +/*********************** Deque Iterator **************************/ + +typedef struct { + PyObject_HEAD + block *b; + Py_ssize_t index; + dequeobject *deque; + size_t state; /* state when the iterator is created */ + Py_ssize_t counter; /* number of items remaining for iteration */ +} dequeiterobject; + +static PyTypeObject dequeiter_type; + +static PyObject * +deque_iter(dequeobject *deque) +{ + dequeiterobject *it; + + it = PyObject_GC_New(dequeiterobject, &dequeiter_type); + if (it == NULL) + return NULL; + it->b = deque->leftblock; + it->index = deque->leftindex; + Py_INCREF(deque); + it->deque = deque; + it->state = deque->state; + it->counter = Py_SIZE(deque); + PyObject_GC_Track(it); + return (PyObject *)it; +} + +static int +dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg) +{ + Py_VISIT(dio->deque); + return 0; +} + +static void +dequeiter_dealloc(dequeiterobject *dio) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(dio); + Py_XDECREF(dio->deque); + PyObject_GC_Del(dio); +} + +static PyObject * +dequeiter_next(dequeiterobject *it) +{ + PyObject *item; + + if (it->deque->state != it->state) { + it->counter = 0; + PyErr_SetString(PyExc_RuntimeError, + "deque mutated during iteration"); + return NULL; + } + if (it->counter == 0) + return NULL; + assert (!(it->b == it->deque->rightblock && + it->index > it->deque->rightindex)); + + item = it->b->data[it->index]; + it->index++; + it->counter--; + if (it->index == BLOCKLEN && it->counter > 0) { + CHECK_NOT_END(it->b->rightlink); + it->b = it->b->rightlink; + it->index = 0; + } + Py_INCREF(item); + return item; +} + +static PyObject * +dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + Py_ssize_t i, index=0; + PyObject *deque; + dequeiterobject *it; + if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index)) + return NULL; + assert(type == &dequeiter_type); + + it = (dequeiterobject*)deque_iter((dequeobject *)deque); + if (!it) + return NULL; + /* consume items from the queue */ + for(i=0; icounter) { + Py_DECREF(it); + return NULL; + } else + break; + } + } + return (PyObject*)it; +} + +static PyObject * dequeiter_len(dequeiterobject *it, PyObject *Py_UNUSED(ignored)) -{ - return PyLong_FromSsize_t(it->counter); -} - -PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); - -static PyObject * +{ + return PyLong_FromSsize_t(it->counter); +} + +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); + +static PyObject * dequeiter_reduce(dequeiterobject *it, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, Py_SIZE(it->deque) - it->counter); -} - -static PyMethodDef dequeiter_methods[] = { - {"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc}, - {"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject dequeiter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_collections._deque_iterator", /* tp_name */ - sizeof(dequeiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)dequeiter_dealloc, /* tp_dealloc */ +{ + return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, Py_SIZE(it->deque) - it->counter); +} + +static PyMethodDef dequeiter_methods[] = { + {"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject dequeiter_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_collections._deque_iterator", /* tp_name */ + sizeof(dequeiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dequeiter_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)dequeiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)dequeiter_next, /* tp_iternext */ - dequeiter_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - dequeiter_new, /* tp_new */ - 0, -}; - -/*********************** Deque Reverse Iterator **************************/ - -static PyTypeObject dequereviter_type; - -static PyObject * + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)dequeiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)dequeiter_next, /* tp_iternext */ + dequeiter_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + dequeiter_new, /* tp_new */ + 0, +}; + +/*********************** Deque Reverse Iterator **************************/ + +static PyTypeObject dequereviter_type; + +static PyObject * deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored)) -{ - dequeiterobject *it; - - it = PyObject_GC_New(dequeiterobject, &dequereviter_type); - if (it == NULL) - return NULL; - it->b = deque->rightblock; - it->index = deque->rightindex; - Py_INCREF(deque); - it->deque = deque; - it->state = deque->state; - it->counter = Py_SIZE(deque); - PyObject_GC_Track(it); - return (PyObject *)it; -} - -static PyObject * -dequereviter_next(dequeiterobject *it) -{ - PyObject *item; - if (it->counter == 0) - return NULL; - - if (it->deque->state != it->state) { - it->counter = 0; - PyErr_SetString(PyExc_RuntimeError, - "deque mutated during iteration"); - return NULL; - } - assert (!(it->b == it->deque->leftblock && - it->index < it->deque->leftindex)); - - item = it->b->data[it->index]; - it->index--; - it->counter--; - if (it->index < 0 && it->counter > 0) { - CHECK_NOT_END(it->b->leftlink); - it->b = it->b->leftlink; - it->index = BLOCKLEN - 1; - } - Py_INCREF(item); - return item; -} - -static PyObject * -dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - Py_ssize_t i, index=0; - PyObject *deque; - dequeiterobject *it; - if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index)) - return NULL; - assert(type == &dequereviter_type); - +{ + dequeiterobject *it; + + it = PyObject_GC_New(dequeiterobject, &dequereviter_type); + if (it == NULL) + return NULL; + it->b = deque->rightblock; + it->index = deque->rightindex; + Py_INCREF(deque); + it->deque = deque; + it->state = deque->state; + it->counter = Py_SIZE(deque); + PyObject_GC_Track(it); + return (PyObject *)it; +} + +static PyObject * +dequereviter_next(dequeiterobject *it) +{ + PyObject *item; + if (it->counter == 0) + return NULL; + + if (it->deque->state != it->state) { + it->counter = 0; + PyErr_SetString(PyExc_RuntimeError, + "deque mutated during iteration"); + return NULL; + } + assert (!(it->b == it->deque->leftblock && + it->index < it->deque->leftindex)); + + item = it->b->data[it->index]; + it->index--; + it->counter--; + if (it->index < 0 && it->counter > 0) { + CHECK_NOT_END(it->b->leftlink); + it->b = it->b->leftlink; + it->index = BLOCKLEN - 1; + } + Py_INCREF(item); + return item; +} + +static PyObject * +dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + Py_ssize_t i, index=0; + PyObject *deque; + dequeiterobject *it; + if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index)) + return NULL; + assert(type == &dequereviter_type); + it = (dequeiterobject*)deque_reviter((dequeobject *)deque, NULL); - if (!it) - return NULL; - /* consume items from the queue */ - for(i=0; icounter) { - Py_DECREF(it); - return NULL; - } else - break; - } - } - return (PyObject*)it; -} - -static PyTypeObject dequereviter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_collections._deque_reverse_iterator", /* tp_name */ - sizeof(dequeiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)dequeiter_dealloc, /* tp_dealloc */ + if (!it) + return NULL; + /* consume items from the queue */ + for(i=0; icounter) { + Py_DECREF(it); + return NULL; + } else + break; + } + } + return (PyObject*)it; +} + +static PyTypeObject dequereviter_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_collections._deque_reverse_iterator", /* tp_name */ + sizeof(dequeiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dequeiter_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)dequeiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)dequereviter_next, /* tp_iternext */ - dequeiter_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - dequereviter_new, /* tp_new */ - 0, -}; - -/* defaultdict type *********************************************************/ - -typedef struct { - PyDictObject dict; - PyObject *default_factory; -} defdictobject; - -static PyTypeObject defdict_type; /* Forward */ - -PyDoc_STRVAR(defdict_missing_doc, -"__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\ - if self.default_factory is None: raise KeyError((key,))\n\ - self[key] = value = self.default_factory()\n\ - return value\n\ -"); - -static PyObject * -defdict_missing(defdictobject *dd, PyObject *key) -{ - PyObject *factory = dd->default_factory; - PyObject *value; - if (factory == NULL || factory == Py_None) { - /* XXX Call dict.__missing__(key) */ - PyObject *tup; - tup = PyTuple_Pack(1, key); - if (!tup) return NULL; - PyErr_SetObject(PyExc_KeyError, tup); - Py_DECREF(tup); - return NULL; - } + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)dequeiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)dequereviter_next, /* tp_iternext */ + dequeiter_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + dequereviter_new, /* tp_new */ + 0, +}; + +/* defaultdict type *********************************************************/ + +typedef struct { + PyDictObject dict; + PyObject *default_factory; +} defdictobject; + +static PyTypeObject defdict_type; /* Forward */ + +PyDoc_STRVAR(defdict_missing_doc, +"__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\ + if self.default_factory is None: raise KeyError((key,))\n\ + self[key] = value = self.default_factory()\n\ + return value\n\ +"); + +static PyObject * +defdict_missing(defdictobject *dd, PyObject *key) +{ + PyObject *factory = dd->default_factory; + PyObject *value; + if (factory == NULL || factory == Py_None) { + /* XXX Call dict.__missing__(key) */ + PyObject *tup; + tup = PyTuple_Pack(1, key); + if (!tup) return NULL; + PyErr_SetObject(PyExc_KeyError, tup); + Py_DECREF(tup); + return NULL; + } value = _PyObject_CallNoArg(factory); - if (value == NULL) - return value; - if (PyObject_SetItem((PyObject *)dd, key, value) < 0) { - Py_DECREF(value); - return NULL; - } - return value; -} - + if (value == NULL) + return value; + if (PyObject_SetItem((PyObject *)dd, key, value) < 0) { + Py_DECREF(value); + return NULL; + } + return value; +} + static inline PyObject* new_defdict(defdictobject *dd, PyObject *arg) { @@ -1999,141 +1999,141 @@ new_defdict(defdictobject *dd, PyObject *arg) dd->default_factory ? dd->default_factory : Py_None, arg, NULL); } -PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D."); - -static PyObject * +PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D."); + +static PyObject * defdict_copy(defdictobject *dd, PyObject *Py_UNUSED(ignored)) -{ - /* This calls the object's class. That only works for subclasses - whose class constructor has the same signature. Subclasses that - define a different constructor signature must override copy(). - */ +{ + /* This calls the object's class. That only works for subclasses + whose class constructor has the same signature. Subclasses that + define a different constructor signature must override copy(). + */ return new_defdict(dd, (PyObject*)dd); -} - -static PyObject * +} + +static PyObject * defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored)) -{ - /* __reduce__ must return a 5-tuple as follows: - - - factory function - - tuple of args for the factory function - - additional state (here None) - - sequence iterator (here None) - - dictionary iterator (yielding successive (key, value) pairs - - This API is used by pickle.py and copy.py. - - For this to be useful with pickle.py, the default_factory - must be picklable; e.g., None, a built-in, or a global - function in a module or package. - - Both shallow and deep copying are supported, but for deep - copying, the default_factory must be deep-copyable; e.g. None, - or a built-in (functions are not copyable at this time). - - This only works for subclasses as long as their constructor - signature is compatible; the first argument must be the - optional default_factory, defaulting to None. - */ - PyObject *args; - PyObject *items; - PyObject *iter; - PyObject *result; - _Py_IDENTIFIER(items); - - if (dd->default_factory == NULL || dd->default_factory == Py_None) - args = PyTuple_New(0); - else - args = PyTuple_Pack(1, dd->default_factory); - if (args == NULL) - return NULL; +{ + /* __reduce__ must return a 5-tuple as follows: + + - factory function + - tuple of args for the factory function + - additional state (here None) + - sequence iterator (here None) + - dictionary iterator (yielding successive (key, value) pairs + + This API is used by pickle.py and copy.py. + + For this to be useful with pickle.py, the default_factory + must be picklable; e.g., None, a built-in, or a global + function in a module or package. + + Both shallow and deep copying are supported, but for deep + copying, the default_factory must be deep-copyable; e.g. None, + or a built-in (functions are not copyable at this time). + + This only works for subclasses as long as their constructor + signature is compatible; the first argument must be the + optional default_factory, defaulting to None. + */ + PyObject *args; + PyObject *items; + PyObject *iter; + PyObject *result; + _Py_IDENTIFIER(items); + + if (dd->default_factory == NULL || dd->default_factory == Py_None) + args = PyTuple_New(0); + else + args = PyTuple_Pack(1, dd->default_factory); + if (args == NULL) + return NULL; items = _PyObject_CallMethodIdNoArgs((PyObject *)dd, &PyId_items); - if (items == NULL) { - Py_DECREF(args); - return NULL; - } - iter = PyObject_GetIter(items); - if (iter == NULL) { - Py_DECREF(items); - Py_DECREF(args); - return NULL; - } - result = PyTuple_Pack(5, Py_TYPE(dd), args, - Py_None, Py_None, iter); - Py_DECREF(iter); - Py_DECREF(items); - Py_DECREF(args); - return result; -} - -static PyMethodDef defdict_methods[] = { - {"__missing__", (PyCFunction)defdict_missing, METH_O, - defdict_missing_doc}, - {"copy", (PyCFunction)defdict_copy, METH_NOARGS, - defdict_copy_doc}, - {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS, - defdict_copy_doc}, - {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS, - reduce_doc}, + if (items == NULL) { + Py_DECREF(args); + return NULL; + } + iter = PyObject_GetIter(items); + if (iter == NULL) { + Py_DECREF(items); + Py_DECREF(args); + return NULL; + } + result = PyTuple_Pack(5, Py_TYPE(dd), args, + Py_None, Py_None, iter); + Py_DECREF(iter); + Py_DECREF(items); + Py_DECREF(args); + return result; +} + +static PyMethodDef defdict_methods[] = { + {"__missing__", (PyCFunction)defdict_missing, METH_O, + defdict_missing_doc}, + {"copy", (PyCFunction)defdict_copy, METH_NOARGS, + defdict_copy_doc}, + {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS, + defdict_copy_doc}, + {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS, + reduce_doc}, {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL} -}; - -static PyMemberDef defdict_members[] = { - {"default_factory", T_OBJECT, - offsetof(defdictobject, default_factory), 0, - PyDoc_STR("Factory for default value called by __missing__().")}, - {NULL} -}; - -static void -defdict_dealloc(defdictobject *dd) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(dd); - Py_CLEAR(dd->default_factory); - PyDict_Type.tp_dealloc((PyObject *)dd); -} - -static PyObject * -defdict_repr(defdictobject *dd) -{ - PyObject *baserepr; - PyObject *defrepr; - PyObject *result; - baserepr = PyDict_Type.tp_repr((PyObject *)dd); - if (baserepr == NULL) - return NULL; - if (dd->default_factory == NULL) - defrepr = PyUnicode_FromString("None"); - else - { - int status = Py_ReprEnter(dd->default_factory); - if (status != 0) { - if (status < 0) { - Py_DECREF(baserepr); - return NULL; - } - defrepr = PyUnicode_FromString("..."); - } - else - defrepr = PyObject_Repr(dd->default_factory); - Py_ReprLeave(dd->default_factory); - } - if (defrepr == NULL) { - Py_DECREF(baserepr); - return NULL; - } - result = PyUnicode_FromFormat("%s(%U, %U)", - _PyType_Name(Py_TYPE(dd)), - defrepr, baserepr); - Py_DECREF(defrepr); - Py_DECREF(baserepr); - return result; -} - + {NULL} +}; + +static PyMemberDef defdict_members[] = { + {"default_factory", T_OBJECT, + offsetof(defdictobject, default_factory), 0, + PyDoc_STR("Factory for default value called by __missing__().")}, + {NULL} +}; + +static void +defdict_dealloc(defdictobject *dd) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(dd); + Py_CLEAR(dd->default_factory); + PyDict_Type.tp_dealloc((PyObject *)dd); +} + +static PyObject * +defdict_repr(defdictobject *dd) +{ + PyObject *baserepr; + PyObject *defrepr; + PyObject *result; + baserepr = PyDict_Type.tp_repr((PyObject *)dd); + if (baserepr == NULL) + return NULL; + if (dd->default_factory == NULL) + defrepr = PyUnicode_FromString("None"); + else + { + int status = Py_ReprEnter(dd->default_factory); + if (status != 0) { + if (status < 0) { + Py_DECREF(baserepr); + return NULL; + } + defrepr = PyUnicode_FromString("..."); + } + else + defrepr = PyObject_Repr(dd->default_factory); + Py_ReprLeave(dd->default_factory); + } + if (defrepr == NULL) { + Py_DECREF(baserepr); + return NULL; + } + result = PyUnicode_FromFormat("%s(%U, %U)", + _PyType_Name(Py_TYPE(dd)), + defrepr, baserepr); + Py_DECREF(defrepr); + Py_DECREF(baserepr); + return result; +} + static PyObject* defdict_or(PyObject* left, PyObject* right) { @@ -2166,114 +2166,114 @@ static PyNumberMethods defdict_as_number = { .nb_or = defdict_or, }; -static int -defdict_traverse(PyObject *self, visitproc visit, void *arg) -{ - Py_VISIT(((defdictobject *)self)->default_factory); - return PyDict_Type.tp_traverse(self, visit, arg); -} - -static int -defdict_tp_clear(defdictobject *dd) -{ - Py_CLEAR(dd->default_factory); - return PyDict_Type.tp_clear((PyObject *)dd); -} - -static int -defdict_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - defdictobject *dd = (defdictobject *)self; - PyObject *olddefault = dd->default_factory; - PyObject *newdefault = NULL; - PyObject *newargs; - int result; - if (args == NULL || !PyTuple_Check(args)) - newargs = PyTuple_New(0); - else { - Py_ssize_t n = PyTuple_GET_SIZE(args); - if (n > 0) { - newdefault = PyTuple_GET_ITEM(args, 0); - if (!PyCallable_Check(newdefault) && newdefault != Py_None) { - PyErr_SetString(PyExc_TypeError, - "first argument must be callable or None"); - return -1; - } - } - newargs = PySequence_GetSlice(args, 1, n); - } - if (newargs == NULL) - return -1; - Py_XINCREF(newdefault); - dd->default_factory = newdefault; - result = PyDict_Type.tp_init(self, newargs, kwds); - Py_DECREF(newargs); - Py_XDECREF(olddefault); - return result; -} - -PyDoc_STRVAR(defdict_doc, +static int +defdict_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(((defdictobject *)self)->default_factory); + return PyDict_Type.tp_traverse(self, visit, arg); +} + +static int +defdict_tp_clear(defdictobject *dd) +{ + Py_CLEAR(dd->default_factory); + return PyDict_Type.tp_clear((PyObject *)dd); +} + +static int +defdict_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + defdictobject *dd = (defdictobject *)self; + PyObject *olddefault = dd->default_factory; + PyObject *newdefault = NULL; + PyObject *newargs; + int result; + if (args == NULL || !PyTuple_Check(args)) + newargs = PyTuple_New(0); + else { + Py_ssize_t n = PyTuple_GET_SIZE(args); + if (n > 0) { + newdefault = PyTuple_GET_ITEM(args, 0); + if (!PyCallable_Check(newdefault) && newdefault != Py_None) { + PyErr_SetString(PyExc_TypeError, + "first argument must be callable or None"); + return -1; + } + } + newargs = PySequence_GetSlice(args, 1, n); + } + if (newargs == NULL) + return -1; + Py_XINCREF(newdefault); + dd->default_factory = newdefault; + result = PyDict_Type.tp_init(self, newargs, kwds); + Py_DECREF(newargs); + Py_XDECREF(olddefault); + return result; +} + +PyDoc_STRVAR(defdict_doc, "defaultdict(default_factory=None, /, [...]) --> dict with default factory\n\ -\n\ -The default factory is called without arguments to produce\n\ -a new value when a key is not present, in __getitem__ only.\n\ -A defaultdict compares equal to a dict with the same items.\n\ -All remaining arguments are treated the same as if they were\n\ -passed to the dict constructor, including keyword arguments.\n\ -"); - -/* See comment in xxsubtype.c */ -#define DEFERRED_ADDRESS(ADDR) 0 - -static PyTypeObject defdict_type = { - PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) - "collections.defaultdict", /* tp_name */ - sizeof(defdictobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)defdict_dealloc, /* tp_dealloc */ +\n\ +The default factory is called without arguments to produce\n\ +a new value when a key is not present, in __getitem__ only.\n\ +A defaultdict compares equal to a dict with the same items.\n\ +All remaining arguments are treated the same as if they were\n\ +passed to the dict constructor, including keyword arguments.\n\ +"); + +/* See comment in xxsubtype.c */ +#define DEFERRED_ADDRESS(ADDR) 0 + +static PyTypeObject defdict_type = { + PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) + "collections.defaultdict", /* tp_name */ + sizeof(defdictobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)defdict_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)defdict_repr, /* tp_repr */ + (reprfunc)defdict_repr, /* tp_repr */ &defdict_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - defdict_doc, /* tp_doc */ - defdict_traverse, /* tp_traverse */ - (inquiry)defdict_tp_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - defdict_methods, /* tp_methods */ - defdict_members, /* tp_members */ - 0, /* tp_getset */ - DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - defdict_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - 0, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - -/* helper function for Counter *********************************************/ - + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + /* tp_flags */ + defdict_doc, /* tp_doc */ + defdict_traverse, /* tp_traverse */ + (inquiry)defdict_tp_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset*/ + 0, /* tp_iter */ + 0, /* tp_iternext */ + defdict_methods, /* tp_methods */ + defdict_members, /* tp_members */ + 0, /* tp_getset */ + DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + defdict_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + 0, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + +/* helper function for Counter *********************************************/ + /*[clinic input] _collections._count_elements - + mapping: object iterable: object / @@ -2281,112 +2281,112 @@ _collections._count_elements Count elements in the iterable, updating the mapping [clinic start generated code]*/ -static PyObject * +static PyObject * _collections__count_elements_impl(PyObject *module, PyObject *mapping, PyObject *iterable) /*[clinic end generated code: output=7e0c1789636b3d8f input=e79fad04534a0b45]*/ -{ - _Py_IDENTIFIER(get); - _Py_IDENTIFIER(__setitem__); +{ + _Py_IDENTIFIER(get); + _Py_IDENTIFIER(__setitem__); PyObject *it, *oldval; - PyObject *newval = NULL; - PyObject *key = NULL; - PyObject *bound_get = NULL; - PyObject *mapping_get; - PyObject *dict_get; - PyObject *mapping_setitem; - PyObject *dict_setitem; - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - /* Only take the fast path when get() and __setitem__() - * have not been overridden. - */ - mapping_get = _PyType_LookupId(Py_TYPE(mapping), &PyId_get); - dict_get = _PyType_LookupId(&PyDict_Type, &PyId_get); - mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__); - dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__); - - if (mapping_get != NULL && mapping_get == dict_get && - mapping_setitem != NULL && mapping_setitem == dict_setitem && - PyDict_Check(mapping)) - { - while (1) { - /* Fast path advantages: - 1. Eliminate double hashing - (by re-using the same hash for both the get and set) - 2. Avoid argument overhead of PyObject_CallFunctionObjArgs - (argument tuple creation and parsing) - 3. Avoid indirection through a bound method object - (creates another argument tuple) - 4. Avoid initial increment from zero - (reuse an existing one-object instead) - */ - Py_hash_t hash; - - key = PyIter_Next(it); - if (key == NULL) - break; - - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) - { - hash = PyObject_Hash(key); - if (hash == -1) - goto done; - } - - oldval = _PyDict_GetItem_KnownHash(mapping, key, hash); - if (oldval == NULL) { - if (PyErr_Occurred()) - goto done; - if (_PyDict_SetItem_KnownHash(mapping, key, _PyLong_One, hash) < 0) - goto done; - } else { - newval = PyNumber_Add(oldval, _PyLong_One); - if (newval == NULL) - goto done; - if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0) - goto done; - Py_CLEAR(newval); - } - Py_DECREF(key); - } - } else { - bound_get = _PyObject_GetAttrId(mapping, &PyId_get); - if (bound_get == NULL) - goto done; - - while (1) { - key = PyIter_Next(it); - if (key == NULL) - break; - oldval = PyObject_CallFunctionObjArgs(bound_get, key, _PyLong_Zero, NULL); - if (oldval == NULL) - break; - newval = PyNumber_Add(oldval, _PyLong_One); - Py_DECREF(oldval); - if (newval == NULL) - break; - if (PyObject_SetItem(mapping, key, newval) < 0) - break; - Py_CLEAR(newval); - Py_DECREF(key); - } - } - -done: - Py_DECREF(it); - Py_XDECREF(key); - Py_XDECREF(newval); - Py_XDECREF(bound_get); - if (PyErr_Occurred()) - return NULL; - Py_RETURN_NONE; -} - + PyObject *newval = NULL; + PyObject *key = NULL; + PyObject *bound_get = NULL; + PyObject *mapping_get; + PyObject *dict_get; + PyObject *mapping_setitem; + PyObject *dict_setitem; + + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + + /* Only take the fast path when get() and __setitem__() + * have not been overridden. + */ + mapping_get = _PyType_LookupId(Py_TYPE(mapping), &PyId_get); + dict_get = _PyType_LookupId(&PyDict_Type, &PyId_get); + mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__); + dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__); + + if (mapping_get != NULL && mapping_get == dict_get && + mapping_setitem != NULL && mapping_setitem == dict_setitem && + PyDict_Check(mapping)) + { + while (1) { + /* Fast path advantages: + 1. Eliminate double hashing + (by re-using the same hash for both the get and set) + 2. Avoid argument overhead of PyObject_CallFunctionObjArgs + (argument tuple creation and parsing) + 3. Avoid indirection through a bound method object + (creates another argument tuple) + 4. Avoid initial increment from zero + (reuse an existing one-object instead) + */ + Py_hash_t hash; + + key = PyIter_Next(it); + if (key == NULL) + break; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) + goto done; + } + + oldval = _PyDict_GetItem_KnownHash(mapping, key, hash); + if (oldval == NULL) { + if (PyErr_Occurred()) + goto done; + if (_PyDict_SetItem_KnownHash(mapping, key, _PyLong_One, hash) < 0) + goto done; + } else { + newval = PyNumber_Add(oldval, _PyLong_One); + if (newval == NULL) + goto done; + if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0) + goto done; + Py_CLEAR(newval); + } + Py_DECREF(key); + } + } else { + bound_get = _PyObject_GetAttrId(mapping, &PyId_get); + if (bound_get == NULL) + goto done; + + while (1) { + key = PyIter_Next(it); + if (key == NULL) + break; + oldval = PyObject_CallFunctionObjArgs(bound_get, key, _PyLong_Zero, NULL); + if (oldval == NULL) + break; + newval = PyNumber_Add(oldval, _PyLong_One); + Py_DECREF(oldval); + if (newval == NULL) + break; + if (PyObject_SetItem(mapping, key, newval) < 0) + break; + Py_CLEAR(newval); + Py_DECREF(key); + } + } + +done: + Py_DECREF(it); + Py_XDECREF(key); + Py_XDECREF(newval); + Py_XDECREF(bound_get); + if (PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + /* Helper function for namedtuple() ************************************/ typedef struct { @@ -2556,19 +2556,19 @@ static PyTypeObject tuplegetter_type = { }; -/* module level code ********************************************************/ - +/* module level code ********************************************************/ + PyDoc_STRVAR(collections_doc, -"High performance data structures.\n\ -- deque: ordered collection accessible from endpoints only\n\ -- defaultdict: dict subclass with a default value factory\n\ -"); - +"High performance data structures.\n\ +- deque: ordered collection accessible from endpoints only\n\ +- defaultdict: dict subclass with a default value factory\n\ +"); + static struct PyMethodDef collections_methods[] = { _COLLECTIONS__COUNT_ELEMENTS_METHODDEF - {NULL, NULL} /* sentinel */ -}; - + {NULL, NULL} /* sentinel */ +}; + static int collections_exec(PyObject *module) { PyTypeObject *typelist[] = { @@ -2596,20 +2596,20 @@ static struct PyModuleDef_Slot collections_slots[] = { {0, NULL} }; -static struct PyModuleDef _collectionsmodule = { - PyModuleDef_HEAD_INIT, - "_collections", +static struct PyModuleDef _collectionsmodule = { + PyModuleDef_HEAD_INIT, + "_collections", collections_doc, 0, collections_methods, collections_slots, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__collections(void) -{ + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__collections(void) +{ return PyModuleDef_Init(&_collectionsmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/_contextvarsmodule.c b/contrib/tools/python3/src/Modules/_contextvarsmodule.c index d6d7f375d12..31c54dd83bd 100644 --- a/contrib/tools/python3/src/Modules/_contextvarsmodule.c +++ b/contrib/tools/python3/src/Modules/_contextvarsmodule.c @@ -1,61 +1,61 @@ -#include "Python.h" - -#include "clinic/_contextvarsmodule.c.h" - -/*[clinic input] -module _contextvars -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a0955718c8b8cea6]*/ - - -/*[clinic input] -_contextvars.copy_context -[clinic start generated code]*/ - -static PyObject * -_contextvars_copy_context_impl(PyObject *module) -/*[clinic end generated code: output=1fcd5da7225c4fa9 input=89bb9ae485888440]*/ -{ - return PyContext_CopyCurrent(); -} - - -PyDoc_STRVAR(module_doc, "Context Variables"); - -static PyMethodDef _contextvars_methods[] = { - _CONTEXTVARS_COPY_CONTEXT_METHODDEF - {NULL, NULL} -}; - +#include "Python.h" + +#include "clinic/_contextvarsmodule.c.h" + +/*[clinic input] +module _contextvars +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a0955718c8b8cea6]*/ + + +/*[clinic input] +_contextvars.copy_context +[clinic start generated code]*/ + +static PyObject * +_contextvars_copy_context_impl(PyObject *module) +/*[clinic end generated code: output=1fcd5da7225c4fa9 input=89bb9ae485888440]*/ +{ + return PyContext_CopyCurrent(); +} + + +PyDoc_STRVAR(module_doc, "Context Variables"); + +static PyMethodDef _contextvars_methods[] = { + _CONTEXTVARS_COPY_CONTEXT_METHODDEF + {NULL, NULL} +}; + static int _contextvars_exec(PyObject *m) -{ - Py_INCREF(&PyContext_Type); - if (PyModule_AddObject(m, "Context", - (PyObject *)&PyContext_Type) < 0) - { - Py_DECREF(&PyContext_Type); +{ + Py_INCREF(&PyContext_Type); + if (PyModule_AddObject(m, "Context", + (PyObject *)&PyContext_Type) < 0) + { + Py_DECREF(&PyContext_Type); return -1; - } - - Py_INCREF(&PyContextVar_Type); - if (PyModule_AddObject(m, "ContextVar", - (PyObject *)&PyContextVar_Type) < 0) - { - Py_DECREF(&PyContextVar_Type); + } + + Py_INCREF(&PyContextVar_Type); + if (PyModule_AddObject(m, "ContextVar", + (PyObject *)&PyContextVar_Type) < 0) + { + Py_DECREF(&PyContextVar_Type); return -1; - } - - Py_INCREF(&PyContextToken_Type); - if (PyModule_AddObject(m, "Token", - (PyObject *)&PyContextToken_Type) < 0) - { - Py_DECREF(&PyContextToken_Type); + } + + Py_INCREF(&PyContextToken_Type); + if (PyModule_AddObject(m, "Token", + (PyObject *)&PyContextToken_Type) < 0) + { + Py_DECREF(&PyContextToken_Type); return -1; - } - + } + return 0; -} +} static struct PyModuleDef_Slot _contextvars_slots[] = { {Py_mod_exec, _contextvars_exec}, diff --git a/contrib/tools/python3/src/Modules/_csv.c b/contrib/tools/python3/src/Modules/_csv.c index 029f473ae87..c37c1f23f2e 100644 --- a/contrib/tools/python3/src/Modules/_csv.c +++ b/contrib/tools/python3/src/Modules/_csv.c @@ -1,26 +1,26 @@ -/* csv module */ - -/* - -This module provides the low-level underpinnings of a CSV reading/writing -module. Users should not use this module directly, but import the csv.py -module instead. - -*/ - -#define MODULE_VERSION "1.0" - -#include "Python.h" +/* csv module */ + +/* + +This module provides the low-level underpinnings of a CSV reading/writing +module. Users should not use this module directly, but import the csv.py +module instead. + +*/ + +#define MODULE_VERSION "1.0" + +#include "Python.h" #include "structmember.h" // PyMemberDef #include - - -typedef struct { - PyObject *error_obj; /* CSV exception */ - PyObject *dialects; /* Dialect registry */ - long field_limit; /* max parsed field size */ -} _csvstate; - + + +typedef struct { + PyObject *error_obj; /* CSV exception */ + PyObject *dialects; /* Dialect registry */ + long field_limit; /* max parsed field size */ +} _csvstate; + static inline _csvstate* get_csv_state(PyObject *module) { @@ -28,243 +28,243 @@ get_csv_state(PyObject *module) assert(state != NULL); return (_csvstate *)state; } - -static int -_csv_clear(PyObject *m) -{ + +static int +_csv_clear(PyObject *m) +{ Py_CLEAR(get_csv_state(m)->error_obj); Py_CLEAR(get_csv_state(m)->dialects); - return 0; -} - -static int -_csv_traverse(PyObject *m, visitproc visit, void *arg) -{ + return 0; +} + +static int +_csv_traverse(PyObject *m, visitproc visit, void *arg) +{ Py_VISIT(get_csv_state(m)->error_obj); Py_VISIT(get_csv_state(m)->dialects); - return 0; -} - -static void -_csv_free(void *m) -{ - _csv_clear((PyObject *)m); -} - -static struct PyModuleDef _csvmodule; - -#define _csvstate_global ((_csvstate *)PyModule_GetState(PyState_FindModule(&_csvmodule))) - -typedef enum { - START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD, - IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD, - EAT_CRNL,AFTER_ESCAPED_CRNL -} ParserState; - -typedef enum { - QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE -} QuoteStyle; - -typedef struct { - QuoteStyle style; - const char *name; -} StyleDesc; - -static const StyleDesc quote_styles[] = { - { QUOTE_MINIMAL, "QUOTE_MINIMAL" }, - { QUOTE_ALL, "QUOTE_ALL" }, - { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" }, - { QUOTE_NONE, "QUOTE_NONE" }, - { 0 } -}; - -typedef struct { - PyObject_HEAD - + return 0; +} + +static void +_csv_free(void *m) +{ + _csv_clear((PyObject *)m); +} + +static struct PyModuleDef _csvmodule; + +#define _csvstate_global ((_csvstate *)PyModule_GetState(PyState_FindModule(&_csvmodule))) + +typedef enum { + START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD, + IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD, + EAT_CRNL,AFTER_ESCAPED_CRNL +} ParserState; + +typedef enum { + QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE +} QuoteStyle; + +typedef struct { + QuoteStyle style; + const char *name; +} StyleDesc; + +static const StyleDesc quote_styles[] = { + { QUOTE_MINIMAL, "QUOTE_MINIMAL" }, + { QUOTE_ALL, "QUOTE_ALL" }, + { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" }, + { QUOTE_NONE, "QUOTE_NONE" }, + { 0 } +}; + +typedef struct { + PyObject_HEAD + char doublequote; /* is " represented by ""? */ char skipinitialspace; /* ignore spaces following delimiter? */ char strict; /* raise exception on bad CSV */ - int quoting; /* style of quoting to write */ + int quoting; /* style of quoting to write */ Py_UCS4 delimiter; /* field separator */ Py_UCS4 quotechar; /* quote character */ Py_UCS4 escapechar; /* escape character */ PyObject *lineterminator; /* string to write between records */ - -} DialectObj; - -static PyTypeObject Dialect_Type; - -typedef struct { - PyObject_HEAD - - PyObject *input_iter; /* iterate over this for input lines */ - - DialectObj *dialect; /* parsing dialect */ - - PyObject *fields; /* field list for current record */ - ParserState state; /* current CSV parse state */ - Py_UCS4 *field; /* temporary buffer */ - Py_ssize_t field_size; /* size of allocated buffer */ - Py_ssize_t field_len; /* length of current field */ - int numeric_field; /* treat field as numeric */ - unsigned long line_num; /* Source-file line number */ -} ReaderObj; - -static PyTypeObject Reader_Type; - + +} DialectObj; + +static PyTypeObject Dialect_Type; + +typedef struct { + PyObject_HEAD + + PyObject *input_iter; /* iterate over this for input lines */ + + DialectObj *dialect; /* parsing dialect */ + + PyObject *fields; /* field list for current record */ + ParserState state; /* current CSV parse state */ + Py_UCS4 *field; /* temporary buffer */ + Py_ssize_t field_size; /* size of allocated buffer */ + Py_ssize_t field_len; /* length of current field */ + int numeric_field; /* treat field as numeric */ + unsigned long line_num; /* Source-file line number */ +} ReaderObj; + +static PyTypeObject Reader_Type; + #define ReaderObject_Check(v) Py_IS_TYPE(v, &Reader_Type) - -typedef struct { - PyObject_HEAD - + +typedef struct { + PyObject_HEAD + PyObject *write; /* write output lines to this file */ - - DialectObj *dialect; /* parsing dialect */ - - Py_UCS4 *rec; /* buffer for parser.join */ - Py_ssize_t rec_size; /* size of allocated record */ - Py_ssize_t rec_len; /* length of record */ - int num_fields; /* number of fields in record */ -} WriterObj; - -static PyTypeObject Writer_Type; - -/* - * DIALECT class - */ - -static PyObject * -get_dialect_from_registry(PyObject * name_obj) -{ - PyObject *dialect_obj; - + + DialectObj *dialect; /* parsing dialect */ + + Py_UCS4 *rec; /* buffer for parser.join */ + Py_ssize_t rec_size; /* size of allocated record */ + Py_ssize_t rec_len; /* length of record */ + int num_fields; /* number of fields in record */ +} WriterObj; + +static PyTypeObject Writer_Type; + +/* + * DIALECT class + */ + +static PyObject * +get_dialect_from_registry(PyObject * name_obj) +{ + PyObject *dialect_obj; + dialect_obj = PyDict_GetItemWithError(_csvstate_global->dialects, name_obj); - if (dialect_obj == NULL) { - if (!PyErr_Occurred()) - PyErr_Format(_csvstate_global->error_obj, "unknown dialect"); - } - else - Py_INCREF(dialect_obj); - return dialect_obj; -} - -static PyObject * -get_string(PyObject *str) -{ - Py_XINCREF(str); - return str; -} - -static PyObject * -get_nullchar_as_None(Py_UCS4 c) -{ - if (c == '\0') { - Py_RETURN_NONE; - } - else - return PyUnicode_FromOrdinal(c); -} - -static PyObject * -Dialect_get_lineterminator(DialectObj *self, void *Py_UNUSED(ignored)) -{ - return get_string(self->lineterminator); -} - -static PyObject * -Dialect_get_delimiter(DialectObj *self, void *Py_UNUSED(ignored)) -{ - return get_nullchar_as_None(self->delimiter); -} - -static PyObject * -Dialect_get_escapechar(DialectObj *self, void *Py_UNUSED(ignored)) -{ - return get_nullchar_as_None(self->escapechar); -} - -static PyObject * -Dialect_get_quotechar(DialectObj *self, void *Py_UNUSED(ignored)) -{ - return get_nullchar_as_None(self->quotechar); -} - -static PyObject * -Dialect_get_quoting(DialectObj *self, void *Py_UNUSED(ignored)) -{ - return PyLong_FromLong(self->quoting); -} - -static int + if (dialect_obj == NULL) { + if (!PyErr_Occurred()) + PyErr_Format(_csvstate_global->error_obj, "unknown dialect"); + } + else + Py_INCREF(dialect_obj); + return dialect_obj; +} + +static PyObject * +get_string(PyObject *str) +{ + Py_XINCREF(str); + return str; +} + +static PyObject * +get_nullchar_as_None(Py_UCS4 c) +{ + if (c == '\0') { + Py_RETURN_NONE; + } + else + return PyUnicode_FromOrdinal(c); +} + +static PyObject * +Dialect_get_lineterminator(DialectObj *self, void *Py_UNUSED(ignored)) +{ + return get_string(self->lineterminator); +} + +static PyObject * +Dialect_get_delimiter(DialectObj *self, void *Py_UNUSED(ignored)) +{ + return get_nullchar_as_None(self->delimiter); +} + +static PyObject * +Dialect_get_escapechar(DialectObj *self, void *Py_UNUSED(ignored)) +{ + return get_nullchar_as_None(self->escapechar); +} + +static PyObject * +Dialect_get_quotechar(DialectObj *self, void *Py_UNUSED(ignored)) +{ + return get_nullchar_as_None(self->quotechar); +} + +static PyObject * +Dialect_get_quoting(DialectObj *self, void *Py_UNUSED(ignored)) +{ + return PyLong_FromLong(self->quoting); +} + +static int _set_bool(const char *name, char *target, PyObject *src, bool dflt) -{ - if (src == NULL) - *target = dflt; - else { - int b = PyObject_IsTrue(src); - if (b < 0) - return -1; +{ + if (src == NULL) + *target = dflt; + else { + int b = PyObject_IsTrue(src); + if (b < 0) + return -1; *target = (char)b; - } - return 0; -} - -static int -_set_int(const char *name, int *target, PyObject *src, int dflt) -{ - if (src == NULL) - *target = dflt; - else { - int value; - if (!PyLong_CheckExact(src)) { - PyErr_Format(PyExc_TypeError, - "\"%s\" must be an integer", name); - return -1; - } - value = _PyLong_AsInt(src); - if (value == -1 && PyErr_Occurred()) { - return -1; - } - *target = value; - } - return 0; -} - -static int + } + return 0; +} + +static int +_set_int(const char *name, int *target, PyObject *src, int dflt) +{ + if (src == NULL) + *target = dflt; + else { + int value; + if (!PyLong_CheckExact(src)) { + PyErr_Format(PyExc_TypeError, + "\"%s\" must be an integer", name); + return -1; + } + value = _PyLong_AsInt(src); + if (value == -1 && PyErr_Occurred()) { + return -1; + } + *target = value; + } + return 0; +} + +static int _set_char_or_none(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) -{ +{ if (src == NULL) { - *target = dflt; + *target = dflt; } - else { - *target = '\0'; - if (src != Py_None) { - if (!PyUnicode_Check(src)) { - PyErr_Format(PyExc_TypeError, + else { + *target = '\0'; + if (src != Py_None) { + if (!PyUnicode_Check(src)) { + PyErr_Format(PyExc_TypeError, "\"%s\" must be string or None, not %.200s", name, Py_TYPE(src)->tp_name); - return -1; - } + return -1; + } Py_ssize_t len = PyUnicode_GetLength(src); if (len < 0) { return -1; } - if (len > 1) { - PyErr_Format(PyExc_TypeError, - "\"%s\" must be a 1-character string", - name); - return -1; - } - /* PyUnicode_READY() is called in PyUnicode_GetLength() */ + if (len > 1) { + PyErr_Format(PyExc_TypeError, + "\"%s\" must be a 1-character string", + name); + return -1; + } + /* PyUnicode_READY() is called in PyUnicode_GetLength() */ else { - *target = PyUnicode_READ_CHAR(src, 0); + *target = PyUnicode_READ_CHAR(src, 0); } - } - } - return 0; -} - -static int + } + } + return 0; +} + +static int _set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) { if (src == NULL) { @@ -297,144 +297,144 @@ _set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) } static int -_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt) -{ - if (src == NULL) - *target = PyUnicode_DecodeASCII(dflt, strlen(dflt), NULL); - else { - if (src == Py_None) - *target = NULL; - else if (!PyUnicode_Check(src)) { - PyErr_Format(PyExc_TypeError, - "\"%s\" must be a string", name); - return -1; - } - else { - if (PyUnicode_READY(src) == -1) - return -1; - Py_INCREF(src); - Py_XSETREF(*target, src); - } - } - return 0; -} - -static int -dialect_check_quoting(int quoting) -{ - const StyleDesc *qs; - - for (qs = quote_styles; qs->name; qs++) { - if ((int)qs->style == quoting) - return 0; - } - PyErr_Format(PyExc_TypeError, "bad \"quoting\" value"); - return -1; -} - -#define D_OFF(x) offsetof(DialectObj, x) - -static struct PyMemberDef Dialect_memberlist[] = { +_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt) +{ + if (src == NULL) + *target = PyUnicode_DecodeASCII(dflt, strlen(dflt), NULL); + else { + if (src == Py_None) + *target = NULL; + else if (!PyUnicode_Check(src)) { + PyErr_Format(PyExc_TypeError, + "\"%s\" must be a string", name); + return -1; + } + else { + if (PyUnicode_READY(src) == -1) + return -1; + Py_INCREF(src); + Py_XSETREF(*target, src); + } + } + return 0; +} + +static int +dialect_check_quoting(int quoting) +{ + const StyleDesc *qs; + + for (qs = quote_styles; qs->name; qs++) { + if ((int)qs->style == quoting) + return 0; + } + PyErr_Format(PyExc_TypeError, "bad \"quoting\" value"); + return -1; +} + +#define D_OFF(x) offsetof(DialectObj, x) + +static struct PyMemberDef Dialect_memberlist[] = { { "skipinitialspace", T_BOOL, D_OFF(skipinitialspace), READONLY }, { "doublequote", T_BOOL, D_OFF(doublequote), READONLY }, { "strict", T_BOOL, D_OFF(strict), READONLY }, - { NULL } -}; - -static PyGetSetDef Dialect_getsetlist[] = { - { "delimiter", (getter)Dialect_get_delimiter}, - { "escapechar", (getter)Dialect_get_escapechar}, - { "lineterminator", (getter)Dialect_get_lineterminator}, - { "quotechar", (getter)Dialect_get_quotechar}, - { "quoting", (getter)Dialect_get_quoting}, - {NULL}, -}; - -static void -Dialect_dealloc(DialectObj *self) -{ - Py_XDECREF(self->lineterminator); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static char *dialect_kws[] = { - "dialect", - "delimiter", - "doublequote", - "escapechar", - "lineterminator", - "quotechar", - "quoting", - "skipinitialspace", - "strict", - NULL -}; - -static PyObject * -dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - DialectObj *self; - PyObject *ret = NULL; - PyObject *dialect = NULL; - PyObject *delimiter = NULL; - PyObject *doublequote = NULL; - PyObject *escapechar = NULL; - PyObject *lineterminator = NULL; - PyObject *quotechar = NULL; - PyObject *quoting = NULL; - PyObject *skipinitialspace = NULL; - PyObject *strict = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|OOOOOOOOO", dialect_kws, - &dialect, - &delimiter, - &doublequote, - &escapechar, - &lineterminator, - "echar, - "ing, - &skipinitialspace, - &strict)) - return NULL; - - if (dialect != NULL) { - if (PyUnicode_Check(dialect)) { - dialect = get_dialect_from_registry(dialect); - if (dialect == NULL) - return NULL; - } - else - Py_INCREF(dialect); - /* Can we reuse this instance? */ - if (PyObject_TypeCheck(dialect, &Dialect_Type) && - delimiter == NULL && - doublequote == NULL && - escapechar == NULL && - lineterminator == NULL && - quotechar == NULL && - quoting == NULL && - skipinitialspace == NULL && - strict == NULL) - return dialect; - } - - self = (DialectObj *)type->tp_alloc(type, 0); - if (self == NULL) { - Py_XDECREF(dialect); - return NULL; - } - self->lineterminator = NULL; - - Py_XINCREF(delimiter); - Py_XINCREF(doublequote); - Py_XINCREF(escapechar); - Py_XINCREF(lineterminator); - Py_XINCREF(quotechar); - Py_XINCREF(quoting); - Py_XINCREF(skipinitialspace); - Py_XINCREF(strict); - if (dialect != NULL) { + { NULL } +}; + +static PyGetSetDef Dialect_getsetlist[] = { + { "delimiter", (getter)Dialect_get_delimiter}, + { "escapechar", (getter)Dialect_get_escapechar}, + { "lineterminator", (getter)Dialect_get_lineterminator}, + { "quotechar", (getter)Dialect_get_quotechar}, + { "quoting", (getter)Dialect_get_quoting}, + {NULL}, +}; + +static void +Dialect_dealloc(DialectObj *self) +{ + Py_XDECREF(self->lineterminator); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static char *dialect_kws[] = { + "dialect", + "delimiter", + "doublequote", + "escapechar", + "lineterminator", + "quotechar", + "quoting", + "skipinitialspace", + "strict", + NULL +}; + +static PyObject * +dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + DialectObj *self; + PyObject *ret = NULL; + PyObject *dialect = NULL; + PyObject *delimiter = NULL; + PyObject *doublequote = NULL; + PyObject *escapechar = NULL; + PyObject *lineterminator = NULL; + PyObject *quotechar = NULL; + PyObject *quoting = NULL; + PyObject *skipinitialspace = NULL; + PyObject *strict = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|OOOOOOOOO", dialect_kws, + &dialect, + &delimiter, + &doublequote, + &escapechar, + &lineterminator, + "echar, + "ing, + &skipinitialspace, + &strict)) + return NULL; + + if (dialect != NULL) { + if (PyUnicode_Check(dialect)) { + dialect = get_dialect_from_registry(dialect); + if (dialect == NULL) + return NULL; + } + else + Py_INCREF(dialect); + /* Can we reuse this instance? */ + if (PyObject_TypeCheck(dialect, &Dialect_Type) && + delimiter == NULL && + doublequote == NULL && + escapechar == NULL && + lineterminator == NULL && + quotechar == NULL && + quoting == NULL && + skipinitialspace == NULL && + strict == NULL) + return dialect; + } + + self = (DialectObj *)type->tp_alloc(type, 0); + if (self == NULL) { + Py_XDECREF(dialect); + return NULL; + } + self->lineterminator = NULL; + + Py_XINCREF(delimiter); + Py_XINCREF(doublequote); + Py_XINCREF(escapechar); + Py_XINCREF(lineterminator); + Py_XINCREF(quotechar); + Py_XINCREF(quoting); + Py_XINCREF(skipinitialspace); + Py_XINCREF(strict); + if (dialect != NULL) { #define DIALECT_GETATTR(v, n) \ do { \ if (v == NULL) { \ @@ -443,772 +443,772 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyErr_Clear(); \ } \ } while (0) - DIALECT_GETATTR(delimiter, "delimiter"); - DIALECT_GETATTR(doublequote, "doublequote"); - DIALECT_GETATTR(escapechar, "escapechar"); - DIALECT_GETATTR(lineterminator, "lineterminator"); - DIALECT_GETATTR(quotechar, "quotechar"); - DIALECT_GETATTR(quoting, "quoting"); - DIALECT_GETATTR(skipinitialspace, "skipinitialspace"); - DIALECT_GETATTR(strict, "strict"); - } - - /* check types and convert to C values */ -#define DIASET(meth, name, target, src, dflt) \ - if (meth(name, target, src, dflt)) \ - goto err - DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ','); + DIALECT_GETATTR(delimiter, "delimiter"); + DIALECT_GETATTR(doublequote, "doublequote"); + DIALECT_GETATTR(escapechar, "escapechar"); + DIALECT_GETATTR(lineterminator, "lineterminator"); + DIALECT_GETATTR(quotechar, "quotechar"); + DIALECT_GETATTR(quoting, "quoting"); + DIALECT_GETATTR(skipinitialspace, "skipinitialspace"); + DIALECT_GETATTR(strict, "strict"); + } + + /* check types and convert to C values */ +#define DIASET(meth, name, target, src, dflt) \ + if (meth(name, target, src, dflt)) \ + goto err + DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ','); DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, true); DIASET(_set_char_or_none, "escapechar", &self->escapechar, escapechar, 0); - DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n"); + DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n"); DIASET(_set_char_or_none, "quotechar", &self->quotechar, quotechar, '"'); - DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL); + DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL); DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, false); DIASET(_set_bool, "strict", &self->strict, strict, false); - - /* validate options */ - if (dialect_check_quoting(self->quoting)) - goto err; - if (self->delimiter == 0) { - PyErr_SetString(PyExc_TypeError, - "\"delimiter\" must be a 1-character string"); - goto err; - } - if (quotechar == Py_None && quoting == NULL) - self->quoting = QUOTE_NONE; - if (self->quoting != QUOTE_NONE && self->quotechar == 0) { - PyErr_SetString(PyExc_TypeError, - "quotechar must be set if quoting enabled"); - goto err; - } - if (self->lineterminator == 0) { - PyErr_SetString(PyExc_TypeError, "lineterminator must be set"); - goto err; - } - - ret = (PyObject *)self; - Py_INCREF(self); -err: - Py_XDECREF(self); - Py_XDECREF(dialect); - Py_XDECREF(delimiter); - Py_XDECREF(doublequote); - Py_XDECREF(escapechar); - Py_XDECREF(lineterminator); - Py_XDECREF(quotechar); - Py_XDECREF(quoting); - Py_XDECREF(skipinitialspace); - Py_XDECREF(strict); - return ret; -} - - -PyDoc_STRVAR(Dialect_Type_doc, -"CSV dialect\n" -"\n" -"The Dialect type records CSV parsing and generation options.\n"); - -static PyTypeObject Dialect_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_csv.Dialect", /* tp_name */ - sizeof(DialectObj), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)Dialect_dealloc, /* tp_dealloc */ + + /* validate options */ + if (dialect_check_quoting(self->quoting)) + goto err; + if (self->delimiter == 0) { + PyErr_SetString(PyExc_TypeError, + "\"delimiter\" must be a 1-character string"); + goto err; + } + if (quotechar == Py_None && quoting == NULL) + self->quoting = QUOTE_NONE; + if (self->quoting != QUOTE_NONE && self->quotechar == 0) { + PyErr_SetString(PyExc_TypeError, + "quotechar must be set if quoting enabled"); + goto err; + } + if (self->lineterminator == 0) { + PyErr_SetString(PyExc_TypeError, "lineterminator must be set"); + goto err; + } + + ret = (PyObject *)self; + Py_INCREF(self); +err: + Py_XDECREF(self); + Py_XDECREF(dialect); + Py_XDECREF(delimiter); + Py_XDECREF(doublequote); + Py_XDECREF(escapechar); + Py_XDECREF(lineterminator); + Py_XDECREF(quotechar); + Py_XDECREF(quoting); + Py_XDECREF(skipinitialspace); + Py_XDECREF(strict); + return ret; +} + + +PyDoc_STRVAR(Dialect_Type_doc, +"CSV dialect\n" +"\n" +"The Dialect type records CSV parsing and generation options.\n"); + +static PyTypeObject Dialect_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_csv.Dialect", /* tp_name */ + sizeof(DialectObj), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)Dialect_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - Dialect_Type_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - Dialect_memberlist, /* tp_members */ - Dialect_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - dialect_new, /* tp_new */ - 0, /* tp_free */ -}; - -/* - * Return an instance of the dialect type, given a Python instance or kwarg - * description of the dialect - */ -static PyObject * -_call_dialect(PyObject *dialect_inst, PyObject *kwargs) -{ - PyObject *type = (PyObject *)&Dialect_Type; - if (dialect_inst) { + (reprfunc)0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Dialect_Type_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + Dialect_memberlist, /* tp_members */ + Dialect_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + dialect_new, /* tp_new */ + 0, /* tp_free */ +}; + +/* + * Return an instance of the dialect type, given a Python instance or kwarg + * description of the dialect + */ +static PyObject * +_call_dialect(PyObject *dialect_inst, PyObject *kwargs) +{ + PyObject *type = (PyObject *)&Dialect_Type; + if (dialect_inst) { return PyObject_VectorcallDict(type, &dialect_inst, 1, kwargs); - } - else { + } + else { return PyObject_VectorcallDict(type, NULL, 0, kwargs); - } -} - -/* - * READER - */ -static int -parse_save_field(ReaderObj *self) -{ - PyObject *field; - - field = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, - (void *) self->field, self->field_len); - if (field == NULL) - return -1; - self->field_len = 0; - if (self->numeric_field) { - PyObject *tmp; - - self->numeric_field = 0; - tmp = PyNumber_Float(field); - Py_DECREF(field); - if (tmp == NULL) - return -1; - field = tmp; - } - if (PyList_Append(self->fields, field) < 0) { - Py_DECREF(field); - return -1; - } - Py_DECREF(field); - return 0; -} - -static int -parse_grow_buff(ReaderObj *self) -{ - assert((size_t)self->field_size <= PY_SSIZE_T_MAX / sizeof(Py_UCS4)); - - Py_ssize_t field_size_new = self->field_size ? 2 * self->field_size : 4096; - Py_UCS4 *field_new = self->field; - PyMem_Resize(field_new, Py_UCS4, field_size_new); - if (field_new == NULL) { - PyErr_NoMemory(); - return 0; - } - self->field = field_new; - self->field_size = field_size_new; - return 1; -} - -static int -parse_add_char(ReaderObj *self, Py_UCS4 c) -{ - if (self->field_len >= _csvstate_global->field_limit) { - PyErr_Format(_csvstate_global->error_obj, "field larger than field limit (%ld)", - _csvstate_global->field_limit); - return -1; - } - if (self->field_len == self->field_size && !parse_grow_buff(self)) - return -1; - self->field[self->field_len++] = c; - return 0; -} - -static int -parse_process_char(ReaderObj *self, Py_UCS4 c) -{ - DialectObj *dialect = self->dialect; - - switch (self->state) { - case START_RECORD: - /* start of record */ - if (c == '\0') - /* empty line - return [] */ - break; - else if (c == '\n' || c == '\r') { - self->state = EAT_CRNL; - break; - } - /* normal character - handle as START_FIELD */ - self->state = START_FIELD; - /* fallthru */ - case START_FIELD: - /* expecting field */ - if (c == '\n' || c == '\r' || c == '\0') { - /* save empty field - return [fields] */ - if (parse_save_field(self) < 0) - return -1; - self->state = (c == '\0' ? START_RECORD : EAT_CRNL); - } - else if (c == dialect->quotechar && - dialect->quoting != QUOTE_NONE) { - /* start quoted field */ - self->state = IN_QUOTED_FIELD; - } - else if (c == dialect->escapechar) { - /* possible escaped character */ - self->state = ESCAPED_CHAR; - } - else if (c == ' ' && dialect->skipinitialspace) - /* ignore space at start of field */ - ; - else if (c == dialect->delimiter) { - /* save empty field */ - if (parse_save_field(self) < 0) - return -1; - } - else { - /* begin new unquoted field */ - if (dialect->quoting == QUOTE_NONNUMERIC) - self->numeric_field = 1; - if (parse_add_char(self, c) < 0) - return -1; - self->state = IN_FIELD; - } - break; - - case ESCAPED_CHAR: - if (c == '\n' || c=='\r') { - if (parse_add_char(self, c) < 0) - return -1; - self->state = AFTER_ESCAPED_CRNL; - break; - } - if (c == '\0') - c = '\n'; - if (parse_add_char(self, c) < 0) - return -1; - self->state = IN_FIELD; - break; - - case AFTER_ESCAPED_CRNL: - if (c == '\0') - break; - /*fallthru*/ - - case IN_FIELD: - /* in unquoted field */ - if (c == '\n' || c == '\r' || c == '\0') { - /* end of line - return [fields] */ - if (parse_save_field(self) < 0) - return -1; - self->state = (c == '\0' ? START_RECORD : EAT_CRNL); - } - else if (c == dialect->escapechar) { - /* possible escaped character */ - self->state = ESCAPED_CHAR; - } - else if (c == dialect->delimiter) { - /* save field - wait for new field */ - if (parse_save_field(self) < 0) - return -1; - self->state = START_FIELD; - } - else { - /* normal character - save in field */ - if (parse_add_char(self, c) < 0) - return -1; - } - break; - - case IN_QUOTED_FIELD: - /* in quoted field */ - if (c == '\0') - ; - else if (c == dialect->escapechar) { - /* Possible escape character */ - self->state = ESCAPE_IN_QUOTED_FIELD; - } - else if (c == dialect->quotechar && - dialect->quoting != QUOTE_NONE) { - if (dialect->doublequote) { - /* doublequote; " represented by "" */ - self->state = QUOTE_IN_QUOTED_FIELD; - } - else { - /* end of quote part of field */ - self->state = IN_FIELD; - } - } - else { - /* normal character - save in field */ - if (parse_add_char(self, c) < 0) - return -1; - } - break; - - case ESCAPE_IN_QUOTED_FIELD: - if (c == '\0') - c = '\n'; - if (parse_add_char(self, c) < 0) - return -1; - self->state = IN_QUOTED_FIELD; - break; - - case QUOTE_IN_QUOTED_FIELD: - /* doublequote - seen a quote in a quoted field */ - if (dialect->quoting != QUOTE_NONE && - c == dialect->quotechar) { - /* save "" as " */ - if (parse_add_char(self, c) < 0) - return -1; - self->state = IN_QUOTED_FIELD; - } - else if (c == dialect->delimiter) { - /* save field - wait for new field */ - if (parse_save_field(self) < 0) - return -1; - self->state = START_FIELD; - } - else if (c == '\n' || c == '\r' || c == '\0') { - /* end of line - return [fields] */ - if (parse_save_field(self) < 0) - return -1; - self->state = (c == '\0' ? START_RECORD : EAT_CRNL); - } - else if (!dialect->strict) { - if (parse_add_char(self, c) < 0) - return -1; - self->state = IN_FIELD; - } - else { - /* illegal */ - PyErr_Format(_csvstate_global->error_obj, "'%c' expected after '%c'", - dialect->delimiter, - dialect->quotechar); - return -1; - } - break; - - case EAT_CRNL: - if (c == '\n' || c == '\r') - ; - else if (c == '\0') - self->state = START_RECORD; - else { - PyErr_Format(_csvstate_global->error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?"); - return -1; - } - break; - - } - return 0; -} - -static int -parse_reset(ReaderObj *self) -{ - Py_XSETREF(self->fields, PyList_New(0)); - if (self->fields == NULL) - return -1; - self->field_len = 0; - self->state = START_RECORD; - self->numeric_field = 0; - return 0; -} - -static PyObject * -Reader_iternext(ReaderObj *self) -{ - PyObject *fields = NULL; - Py_UCS4 c; - Py_ssize_t pos, linelen; - unsigned int kind; + } +} + +/* + * READER + */ +static int +parse_save_field(ReaderObj *self) +{ + PyObject *field; + + field = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, + (void *) self->field, self->field_len); + if (field == NULL) + return -1; + self->field_len = 0; + if (self->numeric_field) { + PyObject *tmp; + + self->numeric_field = 0; + tmp = PyNumber_Float(field); + Py_DECREF(field); + if (tmp == NULL) + return -1; + field = tmp; + } + if (PyList_Append(self->fields, field) < 0) { + Py_DECREF(field); + return -1; + } + Py_DECREF(field); + return 0; +} + +static int +parse_grow_buff(ReaderObj *self) +{ + assert((size_t)self->field_size <= PY_SSIZE_T_MAX / sizeof(Py_UCS4)); + + Py_ssize_t field_size_new = self->field_size ? 2 * self->field_size : 4096; + Py_UCS4 *field_new = self->field; + PyMem_Resize(field_new, Py_UCS4, field_size_new); + if (field_new == NULL) { + PyErr_NoMemory(); + return 0; + } + self->field = field_new; + self->field_size = field_size_new; + return 1; +} + +static int +parse_add_char(ReaderObj *self, Py_UCS4 c) +{ + if (self->field_len >= _csvstate_global->field_limit) { + PyErr_Format(_csvstate_global->error_obj, "field larger than field limit (%ld)", + _csvstate_global->field_limit); + return -1; + } + if (self->field_len == self->field_size && !parse_grow_buff(self)) + return -1; + self->field[self->field_len++] = c; + return 0; +} + +static int +parse_process_char(ReaderObj *self, Py_UCS4 c) +{ + DialectObj *dialect = self->dialect; + + switch (self->state) { + case START_RECORD: + /* start of record */ + if (c == '\0') + /* empty line - return [] */ + break; + else if (c == '\n' || c == '\r') { + self->state = EAT_CRNL; + break; + } + /* normal character - handle as START_FIELD */ + self->state = START_FIELD; + /* fallthru */ + case START_FIELD: + /* expecting field */ + if (c == '\n' || c == '\r' || c == '\0') { + /* save empty field - return [fields] */ + if (parse_save_field(self) < 0) + return -1; + self->state = (c == '\0' ? START_RECORD : EAT_CRNL); + } + else if (c == dialect->quotechar && + dialect->quoting != QUOTE_NONE) { + /* start quoted field */ + self->state = IN_QUOTED_FIELD; + } + else if (c == dialect->escapechar) { + /* possible escaped character */ + self->state = ESCAPED_CHAR; + } + else if (c == ' ' && dialect->skipinitialspace) + /* ignore space at start of field */ + ; + else if (c == dialect->delimiter) { + /* save empty field */ + if (parse_save_field(self) < 0) + return -1; + } + else { + /* begin new unquoted field */ + if (dialect->quoting == QUOTE_NONNUMERIC) + self->numeric_field = 1; + if (parse_add_char(self, c) < 0) + return -1; + self->state = IN_FIELD; + } + break; + + case ESCAPED_CHAR: + if (c == '\n' || c=='\r') { + if (parse_add_char(self, c) < 0) + return -1; + self->state = AFTER_ESCAPED_CRNL; + break; + } + if (c == '\0') + c = '\n'; + if (parse_add_char(self, c) < 0) + return -1; + self->state = IN_FIELD; + break; + + case AFTER_ESCAPED_CRNL: + if (c == '\0') + break; + /*fallthru*/ + + case IN_FIELD: + /* in unquoted field */ + if (c == '\n' || c == '\r' || c == '\0') { + /* end of line - return [fields] */ + if (parse_save_field(self) < 0) + return -1; + self->state = (c == '\0' ? START_RECORD : EAT_CRNL); + } + else if (c == dialect->escapechar) { + /* possible escaped character */ + self->state = ESCAPED_CHAR; + } + else if (c == dialect->delimiter) { + /* save field - wait for new field */ + if (parse_save_field(self) < 0) + return -1; + self->state = START_FIELD; + } + else { + /* normal character - save in field */ + if (parse_add_char(self, c) < 0) + return -1; + } + break; + + case IN_QUOTED_FIELD: + /* in quoted field */ + if (c == '\0') + ; + else if (c == dialect->escapechar) { + /* Possible escape character */ + self->state = ESCAPE_IN_QUOTED_FIELD; + } + else if (c == dialect->quotechar && + dialect->quoting != QUOTE_NONE) { + if (dialect->doublequote) { + /* doublequote; " represented by "" */ + self->state = QUOTE_IN_QUOTED_FIELD; + } + else { + /* end of quote part of field */ + self->state = IN_FIELD; + } + } + else { + /* normal character - save in field */ + if (parse_add_char(self, c) < 0) + return -1; + } + break; + + case ESCAPE_IN_QUOTED_FIELD: + if (c == '\0') + c = '\n'; + if (parse_add_char(self, c) < 0) + return -1; + self->state = IN_QUOTED_FIELD; + break; + + case QUOTE_IN_QUOTED_FIELD: + /* doublequote - seen a quote in a quoted field */ + if (dialect->quoting != QUOTE_NONE && + c == dialect->quotechar) { + /* save "" as " */ + if (parse_add_char(self, c) < 0) + return -1; + self->state = IN_QUOTED_FIELD; + } + else if (c == dialect->delimiter) { + /* save field - wait for new field */ + if (parse_save_field(self) < 0) + return -1; + self->state = START_FIELD; + } + else if (c == '\n' || c == '\r' || c == '\0') { + /* end of line - return [fields] */ + if (parse_save_field(self) < 0) + return -1; + self->state = (c == '\0' ? START_RECORD : EAT_CRNL); + } + else if (!dialect->strict) { + if (parse_add_char(self, c) < 0) + return -1; + self->state = IN_FIELD; + } + else { + /* illegal */ + PyErr_Format(_csvstate_global->error_obj, "'%c' expected after '%c'", + dialect->delimiter, + dialect->quotechar); + return -1; + } + break; + + case EAT_CRNL: + if (c == '\n' || c == '\r') + ; + else if (c == '\0') + self->state = START_RECORD; + else { + PyErr_Format(_csvstate_global->error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?"); + return -1; + } + break; + + } + return 0; +} + +static int +parse_reset(ReaderObj *self) +{ + Py_XSETREF(self->fields, PyList_New(0)); + if (self->fields == NULL) + return -1; + self->field_len = 0; + self->state = START_RECORD; + self->numeric_field = 0; + return 0; +} + +static PyObject * +Reader_iternext(ReaderObj *self) +{ + PyObject *fields = NULL; + Py_UCS4 c; + Py_ssize_t pos, linelen; + unsigned int kind; const void *data; - PyObject *lineobj; - - if (parse_reset(self) < 0) - return NULL; - do { - lineobj = PyIter_Next(self->input_iter); - if (lineobj == NULL) { - /* End of input OR exception */ - if (!PyErr_Occurred() && (self->field_len != 0 || - self->state == IN_QUOTED_FIELD)) { - if (self->dialect->strict) - PyErr_SetString(_csvstate_global->error_obj, - "unexpected end of data"); - else if (parse_save_field(self) >= 0) - break; - } - return NULL; - } - if (!PyUnicode_Check(lineobj)) { - PyErr_Format(_csvstate_global->error_obj, - "iterator should return strings, " - "not %.200s " - "(did you open the file in text mode?)", + PyObject *lineobj; + + if (parse_reset(self) < 0) + return NULL; + do { + lineobj = PyIter_Next(self->input_iter); + if (lineobj == NULL) { + /* End of input OR exception */ + if (!PyErr_Occurred() && (self->field_len != 0 || + self->state == IN_QUOTED_FIELD)) { + if (self->dialect->strict) + PyErr_SetString(_csvstate_global->error_obj, + "unexpected end of data"); + else if (parse_save_field(self) >= 0) + break; + } + return NULL; + } + if (!PyUnicode_Check(lineobj)) { + PyErr_Format(_csvstate_global->error_obj, + "iterator should return strings, " + "not %.200s " + "(did you open the file in text mode?)", Py_TYPE(lineobj)->tp_name - ); - Py_DECREF(lineobj); - return NULL; - } - if (PyUnicode_READY(lineobj) == -1) { - Py_DECREF(lineobj); - return NULL; - } - ++self->line_num; - kind = PyUnicode_KIND(lineobj); - data = PyUnicode_DATA(lineobj); - pos = 0; - linelen = PyUnicode_GET_LENGTH(lineobj); - while (linelen--) { - c = PyUnicode_READ(kind, data, pos); - if (c == '\0') { - Py_DECREF(lineobj); - PyErr_Format(_csvstate_global->error_obj, + ); + Py_DECREF(lineobj); + return NULL; + } + if (PyUnicode_READY(lineobj) == -1) { + Py_DECREF(lineobj); + return NULL; + } + ++self->line_num; + kind = PyUnicode_KIND(lineobj); + data = PyUnicode_DATA(lineobj); + pos = 0; + linelen = PyUnicode_GET_LENGTH(lineobj); + while (linelen--) { + c = PyUnicode_READ(kind, data, pos); + if (c == '\0') { + Py_DECREF(lineobj); + PyErr_Format(_csvstate_global->error_obj, "line contains NUL"); - goto err; - } - if (parse_process_char(self, c) < 0) { - Py_DECREF(lineobj); - goto err; - } - pos++; - } - Py_DECREF(lineobj); - if (parse_process_char(self, 0) < 0) - goto err; - } while (self->state != START_RECORD); - - fields = self->fields; - self->fields = NULL; -err: - return fields; -} - -static void -Reader_dealloc(ReaderObj *self) -{ - PyObject_GC_UnTrack(self); - Py_XDECREF(self->dialect); - Py_XDECREF(self->input_iter); - Py_XDECREF(self->fields); - if (self->field != NULL) - PyMem_Free(self->field); - PyObject_GC_Del(self); -} - -static int -Reader_traverse(ReaderObj *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dialect); - Py_VISIT(self->input_iter); - Py_VISIT(self->fields); - return 0; -} - -static int -Reader_clear(ReaderObj *self) -{ - Py_CLEAR(self->dialect); - Py_CLEAR(self->input_iter); - Py_CLEAR(self->fields); - return 0; -} - -PyDoc_STRVAR(Reader_Type_doc, -"CSV reader\n" -"\n" -"Reader objects are responsible for reading and parsing tabular data\n" -"in CSV format.\n" -); - -static struct PyMethodDef Reader_methods[] = { - { NULL, NULL } -}; -#define R_OFF(x) offsetof(ReaderObj, x) - -static struct PyMemberDef Reader_memberlist[] = { - { "dialect", T_OBJECT, R_OFF(dialect), READONLY }, - { "line_num", T_ULONG, R_OFF(line_num), READONLY }, - { NULL } -}; - - -static PyTypeObject Reader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_csv.reader", /*tp_name*/ - sizeof(ReaderObj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)Reader_dealloc, /*tp_dealloc*/ + goto err; + } + if (parse_process_char(self, c) < 0) { + Py_DECREF(lineobj); + goto err; + } + pos++; + } + Py_DECREF(lineobj); + if (parse_process_char(self, 0) < 0) + goto err; + } while (self->state != START_RECORD); + + fields = self->fields; + self->fields = NULL; +err: + return fields; +} + +static void +Reader_dealloc(ReaderObj *self) +{ + PyObject_GC_UnTrack(self); + Py_XDECREF(self->dialect); + Py_XDECREF(self->input_iter); + Py_XDECREF(self->fields); + if (self->field != NULL) + PyMem_Free(self->field); + PyObject_GC_Del(self); +} + +static int +Reader_traverse(ReaderObj *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dialect); + Py_VISIT(self->input_iter); + Py_VISIT(self->fields); + return 0; +} + +static int +Reader_clear(ReaderObj *self) +{ + Py_CLEAR(self->dialect); + Py_CLEAR(self->input_iter); + Py_CLEAR(self->fields); + return 0; +} + +PyDoc_STRVAR(Reader_Type_doc, +"CSV reader\n" +"\n" +"Reader objects are responsible for reading and parsing tabular data\n" +"in CSV format.\n" +); + +static struct PyMethodDef Reader_methods[] = { + { NULL, NULL } +}; +#define R_OFF(x) offsetof(ReaderObj, x) + +static struct PyMemberDef Reader_memberlist[] = { + { "dialect", T_OBJECT, R_OFF(dialect), READONLY }, + { "line_num", T_ULONG, R_OFF(line_num), READONLY }, + { NULL } +}; + + +static PyTypeObject Reader_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_csv.reader", /*tp_name*/ + sizeof(ReaderObj), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)Reader_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ + (getattrfunc)0, /*tp_getattr*/ + (setattrfunc)0, /*tp_setattr*/ 0, /*tp_as_async*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - Reader_Type_doc, /*tp_doc*/ - (traverseproc)Reader_traverse, /*tp_traverse*/ - (inquiry)Reader_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - PyObject_SelfIter, /*tp_iter*/ - (getiterfunc)Reader_iternext, /*tp_iternext*/ - Reader_methods, /*tp_methods*/ - Reader_memberlist, /*tp_members*/ - 0, /*tp_getset*/ - -}; - -static PyObject * -csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args) -{ - PyObject * iterator, * dialect = NULL; - ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type); - - if (!self) - return NULL; - - self->dialect = NULL; - self->fields = NULL; - self->input_iter = NULL; - self->field = NULL; - self->field_size = 0; - self->line_num = 0; - - if (parse_reset(self) < 0) { - Py_DECREF(self); - return NULL; - } - - if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) { - Py_DECREF(self); - return NULL; - } - self->input_iter = PyObject_GetIter(iterator); - if (self->input_iter == NULL) { - Py_DECREF(self); - return NULL; - } - self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args); - if (self->dialect == NULL) { - Py_DECREF(self); - return NULL; - } - - PyObject_GC_Track(self); - return (PyObject *)self; -} - -/* - * WRITER - */ -/* ---------------------------------------------------------------- */ -static void -join_reset(WriterObj *self) -{ - self->rec_len = 0; - self->num_fields = 0; -} - -#define MEM_INCR 32768 - -/* Calculate new record length or append field to record. Return new - * record length. - */ -static Py_ssize_t + (reprfunc)0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + (hashfunc)0, /*tp_hash*/ + (ternaryfunc)0, /*tp_call*/ + (reprfunc)0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + Reader_Type_doc, /*tp_doc*/ + (traverseproc)Reader_traverse, /*tp_traverse*/ + (inquiry)Reader_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + PyObject_SelfIter, /*tp_iter*/ + (getiterfunc)Reader_iternext, /*tp_iternext*/ + Reader_methods, /*tp_methods*/ + Reader_memberlist, /*tp_members*/ + 0, /*tp_getset*/ + +}; + +static PyObject * +csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args) +{ + PyObject * iterator, * dialect = NULL; + ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type); + + if (!self) + return NULL; + + self->dialect = NULL; + self->fields = NULL; + self->input_iter = NULL; + self->field = NULL; + self->field_size = 0; + self->line_num = 0; + + if (parse_reset(self) < 0) { + Py_DECREF(self); + return NULL; + } + + if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) { + Py_DECREF(self); + return NULL; + } + self->input_iter = PyObject_GetIter(iterator); + if (self->input_iter == NULL) { + Py_DECREF(self); + return NULL; + } + self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args); + if (self->dialect == NULL) { + Py_DECREF(self); + return NULL; + } + + PyObject_GC_Track(self); + return (PyObject *)self; +} + +/* + * WRITER + */ +/* ---------------------------------------------------------------- */ +static void +join_reset(WriterObj *self) +{ + self->rec_len = 0; + self->num_fields = 0; +} + +#define MEM_INCR 32768 + +/* Calculate new record length or append field to record. Return new + * record length. + */ +static Py_ssize_t join_append_data(WriterObj *self, unsigned int field_kind, const void *field_data, - Py_ssize_t field_len, int *quoted, - int copy_phase) -{ - DialectObj *dialect = self->dialect; - int i; - Py_ssize_t rec_len; - -#define INCLEN \ - do {\ - if (!copy_phase && rec_len == PY_SSIZE_T_MAX) { \ - goto overflow; \ - } \ - rec_len++; \ - } while(0) - -#define ADDCH(c) \ - do {\ - if (copy_phase) \ - self->rec[rec_len] = c;\ - INCLEN;\ - } while(0) - - rec_len = self->rec_len; - - /* If this is not the first field we need a field separator */ - if (self->num_fields > 0) - ADDCH(dialect->delimiter); - - /* Handle preceding quote */ - if (copy_phase && *quoted) - ADDCH(dialect->quotechar); - - /* Copy/count field data */ - /* If field is null just pass over */ - for (i = 0; field_data && (i < field_len); i++) { - Py_UCS4 c = PyUnicode_READ(field_kind, field_data, i); - int want_escape = 0; - - if (c == dialect->delimiter || - c == dialect->escapechar || - c == dialect->quotechar || - PyUnicode_FindChar( - dialect->lineterminator, c, 0, - PyUnicode_GET_LENGTH(dialect->lineterminator), 1) >= 0) { - if (dialect->quoting == QUOTE_NONE) - want_escape = 1; - else { - if (c == dialect->quotechar) { - if (dialect->doublequote) - ADDCH(dialect->quotechar); - else - want_escape = 1; - } - if (!want_escape) - *quoted = 1; - } - if (want_escape) { - if (!dialect->escapechar) { - PyErr_Format(_csvstate_global->error_obj, - "need to escape, but no escapechar set"); - return -1; - } - ADDCH(dialect->escapechar); - } - } - /* Copy field character into record buffer. - */ - ADDCH(c); - } - - if (*quoted) { - if (copy_phase) - ADDCH(dialect->quotechar); - else { - INCLEN; /* starting quote */ - INCLEN; /* ending quote */ - } - } - return rec_len; - - overflow: - PyErr_NoMemory(); - return -1; -#undef ADDCH -#undef INCLEN -} - -static int -join_check_rec_size(WriterObj *self, Py_ssize_t rec_len) -{ - assert(rec_len >= 0); - - if (rec_len > self->rec_size) { - size_t rec_size_new = (size_t)(rec_len / MEM_INCR + 1) * MEM_INCR; - Py_UCS4 *rec_new = self->rec; - PyMem_Resize(rec_new, Py_UCS4, rec_size_new); - if (rec_new == NULL) { - PyErr_NoMemory(); - return 0; - } - self->rec = rec_new; - self->rec_size = (Py_ssize_t)rec_size_new; - } - return 1; -} - -static int -join_append(WriterObj *self, PyObject *field, int quoted) -{ - unsigned int field_kind = -1; + Py_ssize_t field_len, int *quoted, + int copy_phase) +{ + DialectObj *dialect = self->dialect; + int i; + Py_ssize_t rec_len; + +#define INCLEN \ + do {\ + if (!copy_phase && rec_len == PY_SSIZE_T_MAX) { \ + goto overflow; \ + } \ + rec_len++; \ + } while(0) + +#define ADDCH(c) \ + do {\ + if (copy_phase) \ + self->rec[rec_len] = c;\ + INCLEN;\ + } while(0) + + rec_len = self->rec_len; + + /* If this is not the first field we need a field separator */ + if (self->num_fields > 0) + ADDCH(dialect->delimiter); + + /* Handle preceding quote */ + if (copy_phase && *quoted) + ADDCH(dialect->quotechar); + + /* Copy/count field data */ + /* If field is null just pass over */ + for (i = 0; field_data && (i < field_len); i++) { + Py_UCS4 c = PyUnicode_READ(field_kind, field_data, i); + int want_escape = 0; + + if (c == dialect->delimiter || + c == dialect->escapechar || + c == dialect->quotechar || + PyUnicode_FindChar( + dialect->lineterminator, c, 0, + PyUnicode_GET_LENGTH(dialect->lineterminator), 1) >= 0) { + if (dialect->quoting == QUOTE_NONE) + want_escape = 1; + else { + if (c == dialect->quotechar) { + if (dialect->doublequote) + ADDCH(dialect->quotechar); + else + want_escape = 1; + } + if (!want_escape) + *quoted = 1; + } + if (want_escape) { + if (!dialect->escapechar) { + PyErr_Format(_csvstate_global->error_obj, + "need to escape, but no escapechar set"); + return -1; + } + ADDCH(dialect->escapechar); + } + } + /* Copy field character into record buffer. + */ + ADDCH(c); + } + + if (*quoted) { + if (copy_phase) + ADDCH(dialect->quotechar); + else { + INCLEN; /* starting quote */ + INCLEN; /* ending quote */ + } + } + return rec_len; + + overflow: + PyErr_NoMemory(); + return -1; +#undef ADDCH +#undef INCLEN +} + +static int +join_check_rec_size(WriterObj *self, Py_ssize_t rec_len) +{ + assert(rec_len >= 0); + + if (rec_len > self->rec_size) { + size_t rec_size_new = (size_t)(rec_len / MEM_INCR + 1) * MEM_INCR; + Py_UCS4 *rec_new = self->rec; + PyMem_Resize(rec_new, Py_UCS4, rec_size_new); + if (rec_new == NULL) { + PyErr_NoMemory(); + return 0; + } + self->rec = rec_new; + self->rec_size = (Py_ssize_t)rec_size_new; + } + return 1; +} + +static int +join_append(WriterObj *self, PyObject *field, int quoted) +{ + unsigned int field_kind = -1; const void *field_data = NULL; - Py_ssize_t field_len = 0; - Py_ssize_t rec_len; - - if (field != NULL) { - if (PyUnicode_READY(field) == -1) - return 0; - field_kind = PyUnicode_KIND(field); - field_data = PyUnicode_DATA(field); - field_len = PyUnicode_GET_LENGTH(field); - } - rec_len = join_append_data(self, field_kind, field_data, field_len, - "ed, 0); - if (rec_len < 0) - return 0; - - /* grow record buffer if necessary */ - if (!join_check_rec_size(self, rec_len)) - return 0; - - self->rec_len = join_append_data(self, field_kind, field_data, field_len, - "ed, 1); - self->num_fields++; - - return 1; -} - -static int -join_append_lineterminator(WriterObj *self) -{ - Py_ssize_t terminator_len, i; - unsigned int term_kind; + Py_ssize_t field_len = 0; + Py_ssize_t rec_len; + + if (field != NULL) { + if (PyUnicode_READY(field) == -1) + return 0; + field_kind = PyUnicode_KIND(field); + field_data = PyUnicode_DATA(field); + field_len = PyUnicode_GET_LENGTH(field); + } + rec_len = join_append_data(self, field_kind, field_data, field_len, + "ed, 0); + if (rec_len < 0) + return 0; + + /* grow record buffer if necessary */ + if (!join_check_rec_size(self, rec_len)) + return 0; + + self->rec_len = join_append_data(self, field_kind, field_data, field_len, + "ed, 1); + self->num_fields++; + + return 1; +} + +static int +join_append_lineterminator(WriterObj *self) +{ + Py_ssize_t terminator_len, i; + unsigned int term_kind; const void *term_data; - - terminator_len = PyUnicode_GET_LENGTH(self->dialect->lineterminator); - if (terminator_len == -1) - return 0; - - /* grow record buffer if necessary */ - if (!join_check_rec_size(self, self->rec_len + terminator_len)) - return 0; - - term_kind = PyUnicode_KIND(self->dialect->lineterminator); - term_data = PyUnicode_DATA(self->dialect->lineterminator); - for (i = 0; i < terminator_len; i++) - self->rec[self->rec_len + i] = PyUnicode_READ(term_kind, term_data, i); - self->rec_len += terminator_len; - - return 1; -} - -PyDoc_STRVAR(csv_writerow_doc, -"writerow(iterable)\n" -"\n" -"Construct and write a CSV record from an iterable of fields. Non-string\n" -"elements will be converted to string."); - -static PyObject * -csv_writerow(WriterObj *self, PyObject *seq) -{ - DialectObj *dialect = self->dialect; - PyObject *iter, *field, *line, *result; - - iter = PyObject_GetIter(seq); + + terminator_len = PyUnicode_GET_LENGTH(self->dialect->lineterminator); + if (terminator_len == -1) + return 0; + + /* grow record buffer if necessary */ + if (!join_check_rec_size(self, self->rec_len + terminator_len)) + return 0; + + term_kind = PyUnicode_KIND(self->dialect->lineterminator); + term_data = PyUnicode_DATA(self->dialect->lineterminator); + for (i = 0; i < terminator_len; i++) + self->rec[self->rec_len + i] = PyUnicode_READ(term_kind, term_data, i); + self->rec_len += terminator_len; + + return 1; +} + +PyDoc_STRVAR(csv_writerow_doc, +"writerow(iterable)\n" +"\n" +"Construct and write a CSV record from an iterable of fields. Non-string\n" +"elements will be converted to string."); + +static PyObject * +csv_writerow(WriterObj *self, PyObject *seq) +{ + DialectObj *dialect = self->dialect; + PyObject *iter, *field, *line, *result; + + iter = PyObject_GetIter(seq); if (iter == NULL) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Format(_csvstate_global->error_obj, @@ -1217,506 +1217,506 @@ csv_writerow(WriterObj *self, PyObject *seq) } return NULL; } - - /* Join all fields in internal buffer. - */ - join_reset(self); - while ((field = PyIter_Next(iter))) { - int append_ok; - int quoted; - - switch (dialect->quoting) { - case QUOTE_NONNUMERIC: - quoted = !PyNumber_Check(field); - break; - case QUOTE_ALL: - quoted = 1; - break; - default: - quoted = 0; - break; - } - - if (PyUnicode_Check(field)) { - append_ok = join_append(self, field, quoted); - Py_DECREF(field); - } - else if (field == Py_None) { - append_ok = join_append(self, NULL, quoted); - Py_DECREF(field); - } - else { - PyObject *str; - - str = PyObject_Str(field); - Py_DECREF(field); - if (str == NULL) { - Py_DECREF(iter); - return NULL; - } - append_ok = join_append(self, str, quoted); - Py_DECREF(str); - } - if (!append_ok) { - Py_DECREF(iter); - return NULL; - } - } - Py_DECREF(iter); - if (PyErr_Occurred()) - return NULL; - - if (self->num_fields > 0 && self->rec_len == 0) { - if (dialect->quoting == QUOTE_NONE) { - PyErr_Format(_csvstate_global->error_obj, - "single empty field record must be quoted"); - return NULL; - } - self->num_fields--; - if (!join_append(self, NULL, 1)) - return NULL; - } - - /* Add line terminator. - */ + + /* Join all fields in internal buffer. + */ + join_reset(self); + while ((field = PyIter_Next(iter))) { + int append_ok; + int quoted; + + switch (dialect->quoting) { + case QUOTE_NONNUMERIC: + quoted = !PyNumber_Check(field); + break; + case QUOTE_ALL: + quoted = 1; + break; + default: + quoted = 0; + break; + } + + if (PyUnicode_Check(field)) { + append_ok = join_append(self, field, quoted); + Py_DECREF(field); + } + else if (field == Py_None) { + append_ok = join_append(self, NULL, quoted); + Py_DECREF(field); + } + else { + PyObject *str; + + str = PyObject_Str(field); + Py_DECREF(field); + if (str == NULL) { + Py_DECREF(iter); + return NULL; + } + append_ok = join_append(self, str, quoted); + Py_DECREF(str); + } + if (!append_ok) { + Py_DECREF(iter); + return NULL; + } + } + Py_DECREF(iter); + if (PyErr_Occurred()) + return NULL; + + if (self->num_fields > 0 && self->rec_len == 0) { + if (dialect->quoting == QUOTE_NONE) { + PyErr_Format(_csvstate_global->error_obj, + "single empty field record must be quoted"); + return NULL; + } + self->num_fields--; + if (!join_append(self, NULL, 1)) + return NULL; + } + + /* Add line terminator. + */ if (!join_append_lineterminator(self)) { - return NULL; + return NULL; } - - line = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, - (void *) self->rec, self->rec_len); + + line = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, + (void *) self->rec, self->rec_len); if (line == NULL) { - return NULL; + return NULL; } result = PyObject_CallOneArg(self->write, line); - Py_DECREF(line); - return result; -} - -PyDoc_STRVAR(csv_writerows_doc, -"writerows(iterable of iterables)\n" -"\n" -"Construct and write a series of iterables to a csv file. Non-string\n" -"elements will be converted to string."); - -static PyObject * -csv_writerows(WriterObj *self, PyObject *seqseq) -{ - PyObject *row_iter, *row_obj, *result; - - row_iter = PyObject_GetIter(seqseq); - if (row_iter == NULL) { - return NULL; - } - while ((row_obj = PyIter_Next(row_iter))) { - result = csv_writerow(self, row_obj); - Py_DECREF(row_obj); - if (!result) { - Py_DECREF(row_iter); - return NULL; - } - else - Py_DECREF(result); - } - Py_DECREF(row_iter); - if (PyErr_Occurred()) - return NULL; - Py_RETURN_NONE; -} - -static struct PyMethodDef Writer_methods[] = { - { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc}, - { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc}, - { NULL, NULL } -}; - -#define W_OFF(x) offsetof(WriterObj, x) - -static struct PyMemberDef Writer_memberlist[] = { - { "dialect", T_OBJECT, W_OFF(dialect), READONLY }, - { NULL } -}; - -static void -Writer_dealloc(WriterObj *self) -{ - PyObject_GC_UnTrack(self); - Py_XDECREF(self->dialect); + Py_DECREF(line); + return result; +} + +PyDoc_STRVAR(csv_writerows_doc, +"writerows(iterable of iterables)\n" +"\n" +"Construct and write a series of iterables to a csv file. Non-string\n" +"elements will be converted to string."); + +static PyObject * +csv_writerows(WriterObj *self, PyObject *seqseq) +{ + PyObject *row_iter, *row_obj, *result; + + row_iter = PyObject_GetIter(seqseq); + if (row_iter == NULL) { + return NULL; + } + while ((row_obj = PyIter_Next(row_iter))) { + result = csv_writerow(self, row_obj); + Py_DECREF(row_obj); + if (!result) { + Py_DECREF(row_iter); + return NULL; + } + else + Py_DECREF(result); + } + Py_DECREF(row_iter); + if (PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + +static struct PyMethodDef Writer_methods[] = { + { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc}, + { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc}, + { NULL, NULL } +}; + +#define W_OFF(x) offsetof(WriterObj, x) + +static struct PyMemberDef Writer_memberlist[] = { + { "dialect", T_OBJECT, W_OFF(dialect), READONLY }, + { NULL } +}; + +static void +Writer_dealloc(WriterObj *self) +{ + PyObject_GC_UnTrack(self); + Py_XDECREF(self->dialect); Py_XDECREF(self->write); - if (self->rec != NULL) - PyMem_Free(self->rec); - PyObject_GC_Del(self); -} - -static int -Writer_traverse(WriterObj *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dialect); + if (self->rec != NULL) + PyMem_Free(self->rec); + PyObject_GC_Del(self); +} + +static int +Writer_traverse(WriterObj *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dialect); Py_VISIT(self->write); - return 0; -} - -static int -Writer_clear(WriterObj *self) -{ - Py_CLEAR(self->dialect); + return 0; +} + +static int +Writer_clear(WriterObj *self) +{ + Py_CLEAR(self->dialect); Py_CLEAR(self->write); - return 0; -} - -PyDoc_STRVAR(Writer_Type_doc, -"CSV writer\n" -"\n" -"Writer objects are responsible for generating tabular data\n" -"in CSV format from sequence input.\n" -); - -static PyTypeObject Writer_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_csv.writer", /*tp_name*/ - sizeof(WriterObj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)Writer_dealloc, /*tp_dealloc*/ + return 0; +} + +PyDoc_STRVAR(Writer_Type_doc, +"CSV writer\n" +"\n" +"Writer objects are responsible for generating tabular data\n" +"in CSV format from sequence input.\n" +); + +static PyTypeObject Writer_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_csv.writer", /*tp_name*/ + sizeof(WriterObj), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)Writer_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ + (getattrfunc)0, /*tp_getattr*/ + (setattrfunc)0, /*tp_setattr*/ 0, /*tp_as_async*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - Writer_Type_doc, - (traverseproc)Writer_traverse, /*tp_traverse*/ - (inquiry)Writer_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - (getiterfunc)0, /*tp_iter*/ - (getiterfunc)0, /*tp_iternext*/ - Writer_methods, /*tp_methods*/ - Writer_memberlist, /*tp_members*/ - 0, /*tp_getset*/ -}; - -static PyObject * -csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) -{ - PyObject * output_file, * dialect = NULL; - WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type); - _Py_IDENTIFIER(write); - - if (!self) - return NULL; - - self->dialect = NULL; + (reprfunc)0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + (hashfunc)0, /*tp_hash*/ + (ternaryfunc)0, /*tp_call*/ + (reprfunc)0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + Writer_Type_doc, + (traverseproc)Writer_traverse, /*tp_traverse*/ + (inquiry)Writer_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + (getiterfunc)0, /*tp_iter*/ + (getiterfunc)0, /*tp_iternext*/ + Writer_methods, /*tp_methods*/ + Writer_memberlist, /*tp_members*/ + 0, /*tp_getset*/ +}; + +static PyObject * +csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) +{ + PyObject * output_file, * dialect = NULL; + WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type); + _Py_IDENTIFIER(write); + + if (!self) + return NULL; + + self->dialect = NULL; self->write = NULL; - - self->rec = NULL; - self->rec_size = 0; - self->rec_len = 0; - self->num_fields = 0; - - if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) { - Py_DECREF(self); - return NULL; - } + + self->rec = NULL; + self->rec_size = 0; + self->rec_len = 0; + self->num_fields = 0; + + if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) { + Py_DECREF(self); + return NULL; + } if (_PyObject_LookupAttrId(output_file, &PyId_write, &self->write) < 0) { Py_DECREF(self); return NULL; } if (self->write == NULL || !PyCallable_Check(self->write)) { - PyErr_SetString(PyExc_TypeError, - "argument 1 must have a \"write\" method"); - Py_DECREF(self); - return NULL; - } - self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args); - if (self->dialect == NULL) { - Py_DECREF(self); - return NULL; - } - PyObject_GC_Track(self); - return (PyObject *)self; -} - -/* - * DIALECT REGISTRY - */ -static PyObject * -csv_list_dialects(PyObject *module, PyObject *args) -{ - return PyDict_Keys(_csvstate_global->dialects); -} - -static PyObject * -csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) -{ - PyObject *name_obj, *dialect_obj = NULL; - PyObject *dialect; - - if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj)) - return NULL; - if (!PyUnicode_Check(name_obj)) { - PyErr_SetString(PyExc_TypeError, - "dialect name must be a string"); - return NULL; - } - if (PyUnicode_READY(name_obj) == -1) - return NULL; - dialect = _call_dialect(dialect_obj, kwargs); - if (dialect == NULL) - return NULL; - if (PyDict_SetItem(_csvstate_global->dialects, name_obj, dialect) < 0) { - Py_DECREF(dialect); - return NULL; - } - Py_DECREF(dialect); - Py_RETURN_NONE; -} - -static PyObject * -csv_unregister_dialect(PyObject *module, PyObject *name_obj) -{ + PyErr_SetString(PyExc_TypeError, + "argument 1 must have a \"write\" method"); + Py_DECREF(self); + return NULL; + } + self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args); + if (self->dialect == NULL) { + Py_DECREF(self); + return NULL; + } + PyObject_GC_Track(self); + return (PyObject *)self; +} + +/* + * DIALECT REGISTRY + */ +static PyObject * +csv_list_dialects(PyObject *module, PyObject *args) +{ + return PyDict_Keys(_csvstate_global->dialects); +} + +static PyObject * +csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) +{ + PyObject *name_obj, *dialect_obj = NULL; + PyObject *dialect; + + if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj)) + return NULL; + if (!PyUnicode_Check(name_obj)) { + PyErr_SetString(PyExc_TypeError, + "dialect name must be a string"); + return NULL; + } + if (PyUnicode_READY(name_obj) == -1) + return NULL; + dialect = _call_dialect(dialect_obj, kwargs); + if (dialect == NULL) + return NULL; + if (PyDict_SetItem(_csvstate_global->dialects, name_obj, dialect) < 0) { + Py_DECREF(dialect); + return NULL; + } + Py_DECREF(dialect); + Py_RETURN_NONE; +} + +static PyObject * +csv_unregister_dialect(PyObject *module, PyObject *name_obj) +{ if (PyDict_DelItem(_csvstate_global->dialects, name_obj) < 0) { if (PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Format(_csvstate_global->error_obj, "unknown dialect"); } return NULL; } - Py_RETURN_NONE; -} - -static PyObject * -csv_get_dialect(PyObject *module, PyObject *name_obj) -{ - return get_dialect_from_registry(name_obj); -} - -static PyObject * -csv_field_size_limit(PyObject *module, PyObject *args) -{ - PyObject *new_limit = NULL; - long old_limit = _csvstate_global->field_limit; - - if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit)) - return NULL; - if (new_limit != NULL) { - if (!PyLong_CheckExact(new_limit)) { - PyErr_Format(PyExc_TypeError, - "limit must be an integer"); - return NULL; - } - _csvstate_global->field_limit = PyLong_AsLong(new_limit); - if (_csvstate_global->field_limit == -1 && PyErr_Occurred()) { - _csvstate_global->field_limit = old_limit; - return NULL; - } - } - return PyLong_FromLong(old_limit); -} - -/* - * MODULE - */ - -PyDoc_STRVAR(csv_module_doc, -"CSV parsing and writing.\n" -"\n" -"This module provides classes that assist in the reading and writing\n" -"of Comma Separated Value (CSV) files, and implements the interface\n" -"described by PEP 305. Although many CSV files are simple to parse,\n" -"the format is not formally defined by a stable specification and\n" -"is subtle enough that parsing lines of a CSV file with something\n" -"like line.split(\",\") is bound to fail. The module supports three\n" -"basic APIs: reading, writing, and registration of dialects.\n" -"\n" -"\n" -"DIALECT REGISTRATION:\n" -"\n" -"Readers and writers support a dialect argument, which is a convenient\n" -"handle on a group of settings. When the dialect argument is a string,\n" -"it identifies one of the dialects previously registered with the module.\n" -"If it is a class or instance, the attributes of the argument are used as\n" -"the settings for the reader or writer:\n" -"\n" -" class excel:\n" -" delimiter = ','\n" -" quotechar = '\"'\n" -" escapechar = None\n" -" doublequote = True\n" -" skipinitialspace = False\n" -" lineterminator = '\\r\\n'\n" -" quoting = QUOTE_MINIMAL\n" -"\n" -"SETTINGS:\n" -"\n" + Py_RETURN_NONE; +} + +static PyObject * +csv_get_dialect(PyObject *module, PyObject *name_obj) +{ + return get_dialect_from_registry(name_obj); +} + +static PyObject * +csv_field_size_limit(PyObject *module, PyObject *args) +{ + PyObject *new_limit = NULL; + long old_limit = _csvstate_global->field_limit; + + if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit)) + return NULL; + if (new_limit != NULL) { + if (!PyLong_CheckExact(new_limit)) { + PyErr_Format(PyExc_TypeError, + "limit must be an integer"); + return NULL; + } + _csvstate_global->field_limit = PyLong_AsLong(new_limit); + if (_csvstate_global->field_limit == -1 && PyErr_Occurred()) { + _csvstate_global->field_limit = old_limit; + return NULL; + } + } + return PyLong_FromLong(old_limit); +} + +/* + * MODULE + */ + +PyDoc_STRVAR(csv_module_doc, +"CSV parsing and writing.\n" +"\n" +"This module provides classes that assist in the reading and writing\n" +"of Comma Separated Value (CSV) files, and implements the interface\n" +"described by PEP 305. Although many CSV files are simple to parse,\n" +"the format is not formally defined by a stable specification and\n" +"is subtle enough that parsing lines of a CSV file with something\n" +"like line.split(\",\") is bound to fail. The module supports three\n" +"basic APIs: reading, writing, and registration of dialects.\n" +"\n" +"\n" +"DIALECT REGISTRATION:\n" +"\n" +"Readers and writers support a dialect argument, which is a convenient\n" +"handle on a group of settings. When the dialect argument is a string,\n" +"it identifies one of the dialects previously registered with the module.\n" +"If it is a class or instance, the attributes of the argument are used as\n" +"the settings for the reader or writer:\n" +"\n" +" class excel:\n" +" delimiter = ','\n" +" quotechar = '\"'\n" +" escapechar = None\n" +" doublequote = True\n" +" skipinitialspace = False\n" +" lineterminator = '\\r\\n'\n" +" quoting = QUOTE_MINIMAL\n" +"\n" +"SETTINGS:\n" +"\n" " * quotechar - specifies a one-character string to use as the\n" -" quoting character. It defaults to '\"'.\n" +" quoting character. It defaults to '\"'.\n" " * delimiter - specifies a one-character string to use as the\n" -" field separator. It defaults to ','.\n" -" * skipinitialspace - specifies how to interpret whitespace which\n" -" immediately follows a delimiter. It defaults to False, which\n" -" means that whitespace immediately following a delimiter is part\n" -" of the following field.\n" +" field separator. It defaults to ','.\n" +" * skipinitialspace - specifies how to interpret whitespace which\n" +" immediately follows a delimiter. It defaults to False, which\n" +" means that whitespace immediately following a delimiter is part\n" +" of the following field.\n" " * lineterminator - specifies the character sequence which should\n" -" terminate rows.\n" -" * quoting - controls when quotes should be generated by the writer.\n" -" It can take on any of the following module constants:\n" -"\n" -" csv.QUOTE_MINIMAL means only when required, for example, when a\n" -" field contains either the quotechar or the delimiter\n" -" csv.QUOTE_ALL means that quotes are always placed around fields.\n" -" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n" -" fields which do not parse as integers or floating point\n" -" numbers.\n" -" csv.QUOTE_NONE means that quotes are never placed around fields.\n" +" terminate rows.\n" +" * quoting - controls when quotes should be generated by the writer.\n" +" It can take on any of the following module constants:\n" +"\n" +" csv.QUOTE_MINIMAL means only when required, for example, when a\n" +" field contains either the quotechar or the delimiter\n" +" csv.QUOTE_ALL means that quotes are always placed around fields.\n" +" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n" +" fields which do not parse as integers or floating point\n" +" numbers.\n" +" csv.QUOTE_NONE means that quotes are never placed around fields.\n" " * escapechar - specifies a one-character string used to escape\n" -" the delimiter when quoting is set to QUOTE_NONE.\n" -" * doublequote - controls the handling of quotes inside fields. When\n" -" True, two consecutive quotes are interpreted as one during read,\n" -" and when writing, each quote character embedded in the data is\n" -" written as two quotes\n"); - -PyDoc_STRVAR(csv_reader_doc, -" csv_reader = reader(iterable [, dialect='excel']\n" -" [optional keyword args])\n" -" for row in csv_reader:\n" -" process(row)\n" -"\n" -"The \"iterable\" argument can be any object that returns a line\n" -"of input for each iteration, such as a file object or a list. The\n" -"optional \"dialect\" parameter is discussed below. The function\n" -"also accepts optional keyword arguments which override settings\n" -"provided by the dialect.\n" -"\n" -"The returned object is an iterator. Each iteration returns a row\n" -"of the CSV file (which can span multiple input lines).\n"); - -PyDoc_STRVAR(csv_writer_doc, -" csv_writer = csv.writer(fileobj [, dialect='excel']\n" -" [optional keyword args])\n" -" for row in sequence:\n" -" csv_writer.writerow(row)\n" -"\n" -" [or]\n" -"\n" -" csv_writer = csv.writer(fileobj [, dialect='excel']\n" -" [optional keyword args])\n" -" csv_writer.writerows(rows)\n" -"\n" -"The \"fileobj\" argument can be any object that supports the file API.\n"); - -PyDoc_STRVAR(csv_list_dialects_doc, -"Return a list of all know dialect names.\n" -" names = csv.list_dialects()"); - -PyDoc_STRVAR(csv_get_dialect_doc, -"Return the dialect instance associated with name.\n" -" dialect = csv.get_dialect(name)"); - -PyDoc_STRVAR(csv_register_dialect_doc, -"Create a mapping from a string name to a dialect class.\n" -" dialect = csv.register_dialect(name[, dialect[, **fmtparams]])"); - -PyDoc_STRVAR(csv_unregister_dialect_doc, -"Delete the name/dialect mapping associated with a string name.\n" -" csv.unregister_dialect(name)"); - -PyDoc_STRVAR(csv_field_size_limit_doc, -"Sets an upper limit on parsed fields.\n" -" csv.field_size_limit([limit])\n" -"\n" -"Returns old limit. If limit is not given, no new limit is set and\n" -"the old limit is returned"); - -static struct PyMethodDef csv_methods[] = { +" the delimiter when quoting is set to QUOTE_NONE.\n" +" * doublequote - controls the handling of quotes inside fields. When\n" +" True, two consecutive quotes are interpreted as one during read,\n" +" and when writing, each quote character embedded in the data is\n" +" written as two quotes\n"); + +PyDoc_STRVAR(csv_reader_doc, +" csv_reader = reader(iterable [, dialect='excel']\n" +" [optional keyword args])\n" +" for row in csv_reader:\n" +" process(row)\n" +"\n" +"The \"iterable\" argument can be any object that returns a line\n" +"of input for each iteration, such as a file object or a list. The\n" +"optional \"dialect\" parameter is discussed below. The function\n" +"also accepts optional keyword arguments which override settings\n" +"provided by the dialect.\n" +"\n" +"The returned object is an iterator. Each iteration returns a row\n" +"of the CSV file (which can span multiple input lines).\n"); + +PyDoc_STRVAR(csv_writer_doc, +" csv_writer = csv.writer(fileobj [, dialect='excel']\n" +" [optional keyword args])\n" +" for row in sequence:\n" +" csv_writer.writerow(row)\n" +"\n" +" [or]\n" +"\n" +" csv_writer = csv.writer(fileobj [, dialect='excel']\n" +" [optional keyword args])\n" +" csv_writer.writerows(rows)\n" +"\n" +"The \"fileobj\" argument can be any object that supports the file API.\n"); + +PyDoc_STRVAR(csv_list_dialects_doc, +"Return a list of all know dialect names.\n" +" names = csv.list_dialects()"); + +PyDoc_STRVAR(csv_get_dialect_doc, +"Return the dialect instance associated with name.\n" +" dialect = csv.get_dialect(name)"); + +PyDoc_STRVAR(csv_register_dialect_doc, +"Create a mapping from a string name to a dialect class.\n" +" dialect = csv.register_dialect(name[, dialect[, **fmtparams]])"); + +PyDoc_STRVAR(csv_unregister_dialect_doc, +"Delete the name/dialect mapping associated with a string name.\n" +" csv.unregister_dialect(name)"); + +PyDoc_STRVAR(csv_field_size_limit_doc, +"Sets an upper limit on parsed fields.\n" +" csv.field_size_limit([limit])\n" +"\n" +"Returns old limit. If limit is not given, no new limit is set and\n" +"the old limit is returned"); + +static struct PyMethodDef csv_methods[] = { { "reader", (PyCFunction)(void(*)(void))csv_reader, - METH_VARARGS | METH_KEYWORDS, csv_reader_doc}, + METH_VARARGS | METH_KEYWORDS, csv_reader_doc}, { "writer", (PyCFunction)(void(*)(void))csv_writer, - METH_VARARGS | METH_KEYWORDS, csv_writer_doc}, - { "list_dialects", (PyCFunction)csv_list_dialects, - METH_NOARGS, csv_list_dialects_doc}, + METH_VARARGS | METH_KEYWORDS, csv_writer_doc}, + { "list_dialects", (PyCFunction)csv_list_dialects, + METH_NOARGS, csv_list_dialects_doc}, { "register_dialect", (PyCFunction)(void(*)(void))csv_register_dialect, - METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc}, - { "unregister_dialect", (PyCFunction)csv_unregister_dialect, - METH_O, csv_unregister_dialect_doc}, - { "get_dialect", (PyCFunction)csv_get_dialect, - METH_O, csv_get_dialect_doc}, - { "field_size_limit", (PyCFunction)csv_field_size_limit, - METH_VARARGS, csv_field_size_limit_doc}, - { NULL, NULL } -}; - -static struct PyModuleDef _csvmodule = { - PyModuleDef_HEAD_INIT, - "_csv", - csv_module_doc, - sizeof(_csvstate), - csv_methods, - NULL, - _csv_traverse, - _csv_clear, - _csv_free -}; - -PyMODINIT_FUNC -PyInit__csv(void) -{ - PyObject *module; - const StyleDesc *style; - - if (PyType_Ready(&Reader_Type) < 0) - return NULL; - - if (PyType_Ready(&Writer_Type) < 0) - return NULL; - - /* Create the module and add the functions */ - module = PyModule_Create(&_csvmodule); - if (module == NULL) - return NULL; - - /* Add version to the module. */ - if (PyModule_AddStringConstant(module, "__version__", - MODULE_VERSION) == -1) - return NULL; - - /* Set the field limit */ + METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc}, + { "unregister_dialect", (PyCFunction)csv_unregister_dialect, + METH_O, csv_unregister_dialect_doc}, + { "get_dialect", (PyCFunction)csv_get_dialect, + METH_O, csv_get_dialect_doc}, + { "field_size_limit", (PyCFunction)csv_field_size_limit, + METH_VARARGS, csv_field_size_limit_doc}, + { NULL, NULL } +}; + +static struct PyModuleDef _csvmodule = { + PyModuleDef_HEAD_INIT, + "_csv", + csv_module_doc, + sizeof(_csvstate), + csv_methods, + NULL, + _csv_traverse, + _csv_clear, + _csv_free +}; + +PyMODINIT_FUNC +PyInit__csv(void) +{ + PyObject *module; + const StyleDesc *style; + + if (PyType_Ready(&Reader_Type) < 0) + return NULL; + + if (PyType_Ready(&Writer_Type) < 0) + return NULL; + + /* Create the module and add the functions */ + module = PyModule_Create(&_csvmodule); + if (module == NULL) + return NULL; + + /* Add version to the module. */ + if (PyModule_AddStringConstant(module, "__version__", + MODULE_VERSION) == -1) + return NULL; + + /* Set the field limit */ get_csv_state(module)->field_limit = 128 * 1024; - /* Do I still need to add this var to the Module Dict? */ - - /* Add _dialects dictionary */ + /* Do I still need to add this var to the Module Dict? */ + + /* Add _dialects dictionary */ get_csv_state(module)->dialects = PyDict_New(); if (get_csv_state(module)->dialects == NULL) - return NULL; + return NULL; Py_INCREF(get_csv_state(module)->dialects); if (PyModule_AddObject(module, "_dialects", get_csv_state(module)->dialects)) - return NULL; - - /* Add quote styles into dictionary */ - for (style = quote_styles; style->name; style++) { - if (PyModule_AddIntConstant(module, style->name, - style->style) == -1) - return NULL; - } - + return NULL; + + /* Add quote styles into dictionary */ + for (style = quote_styles; style->name; style++) { + if (PyModule_AddIntConstant(module, style->name, + style->style) == -1) + return NULL; + } + if (PyModule_AddType(module, &Dialect_Type)) { - return NULL; + return NULL; } - - /* Add the CSV exception object to the module. */ + + /* Add the CSV exception object to the module. */ get_csv_state(module)->error_obj = PyErr_NewException("_csv.Error", NULL, NULL); if (get_csv_state(module)->error_obj == NULL) - return NULL; + return NULL; Py_INCREF(get_csv_state(module)->error_obj); PyModule_AddObject(module, "Error", get_csv_state(module)->error_obj); - return module; -} + return module; +} diff --git a/contrib/tools/python3/src/Modules/_ctypes/_ctypes.c b/contrib/tools/python3/src/Modules/_ctypes/_ctypes.c index 0f7b8003f20..189c4caa47d 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/_ctypes.c +++ b/contrib/tools/python3/src/Modules/_ctypes/_ctypes.c @@ -1,398 +1,398 @@ -/* - ToDo: - - Get rid of the checker (and also the converters) field in PyCFuncPtrObject and - StgDictObject, and replace them by slot functions in StgDictObject. - - think about a buffer-like object (memory? bytes?) - - Should POINTER(c_char) and POINTER(c_wchar) have a .value property? - What about c_char and c_wchar arrays then? - - Add from_mmap, from_file, from_string metaclass methods. - - Maybe we can get away with from_file (calls read) and with a from_buffer - method? - - And what about the to_mmap, to_file, to_str(?) methods? They would clobber - the namespace, probably. So, functions instead? And we already have memmove... -*/ - -/* - -Name methods, members, getsets -============================================================================== - -PyCStructType_Type __new__(), from_address(), __mul__(), from_param() -UnionType_Type __new__(), from_address(), __mul__(), from_param() -PyCPointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type() -PyCArrayType_Type __new__(), from_address(), __mul__(), from_param() -PyCSimpleType_Type __new__(), from_address(), __mul__(), from_param() - -PyCData_Type - Struct_Type __new__(), __init__() - PyCPointer_Type __new__(), __init__(), _as_parameter_, contents - PyCArray_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__() - Simple_Type __new__(), __init__(), _as_parameter_ - -PyCField_Type -PyCStgDict_Type - -============================================================================== - -class methods -------------- - -It has some similarity to the byref() construct compared to pointer() -from_address(addr) - - construct an instance from a given memory block (sharing this memory block) - -from_param(obj) - - typecheck and convert a Python object into a C function call parameter - The result may be an instance of the type, or an integer or tuple - (typecode, value[, obj]) - -instance methods/properties ---------------------------- - -_as_parameter_ - - convert self into a C function call parameter - This is either an integer, or a 3-tuple (typecode, value, obj) - -functions ---------- - -sizeof(cdata) - - return the number of bytes the buffer contains - -sizeof(ctype) - - return the number of bytes the buffer of an instance would contain - -byref(cdata) - -addressof(cdata) - -pointer(cdata) - -POINTER(ctype) - -bytes(cdata) - - return the buffer contents as a sequence of bytes (which is currently a string) - -*/ - -/* - * PyCStgDict_Type - * PyCStructType_Type - * UnionType_Type - * PyCPointerType_Type - * PyCArrayType_Type - * PyCSimpleType_Type - * - * PyCData_Type - * Struct_Type - * Union_Type - * PyCArray_Type - * Simple_Type - * PyCPointer_Type - * PyCField_Type - * - */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" +/* + ToDo: + + Get rid of the checker (and also the converters) field in PyCFuncPtrObject and + StgDictObject, and replace them by slot functions in StgDictObject. + + think about a buffer-like object (memory? bytes?) + + Should POINTER(c_char) and POINTER(c_wchar) have a .value property? + What about c_char and c_wchar arrays then? + + Add from_mmap, from_file, from_string metaclass methods. + + Maybe we can get away with from_file (calls read) and with a from_buffer + method? + + And what about the to_mmap, to_file, to_str(?) methods? They would clobber + the namespace, probably. So, functions instead? And we already have memmove... +*/ + +/* + +Name methods, members, getsets +============================================================================== + +PyCStructType_Type __new__(), from_address(), __mul__(), from_param() +UnionType_Type __new__(), from_address(), __mul__(), from_param() +PyCPointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type() +PyCArrayType_Type __new__(), from_address(), __mul__(), from_param() +PyCSimpleType_Type __new__(), from_address(), __mul__(), from_param() + +PyCData_Type + Struct_Type __new__(), __init__() + PyCPointer_Type __new__(), __init__(), _as_parameter_, contents + PyCArray_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__() + Simple_Type __new__(), __init__(), _as_parameter_ + +PyCField_Type +PyCStgDict_Type + +============================================================================== + +class methods +------------- + +It has some similarity to the byref() construct compared to pointer() +from_address(addr) + - construct an instance from a given memory block (sharing this memory block) + +from_param(obj) + - typecheck and convert a Python object into a C function call parameter + The result may be an instance of the type, or an integer or tuple + (typecode, value[, obj]) + +instance methods/properties +--------------------------- + +_as_parameter_ + - convert self into a C function call parameter + This is either an integer, or a 3-tuple (typecode, value, obj) + +functions +--------- + +sizeof(cdata) + - return the number of bytes the buffer contains + +sizeof(ctype) + - return the number of bytes the buffer of an instance would contain + +byref(cdata) + +addressof(cdata) + +pointer(cdata) + +POINTER(ctype) + +bytes(cdata) + - return the buffer contents as a sequence of bytes (which is currently a string) + +*/ + +/* + * PyCStgDict_Type + * PyCStructType_Type + * UnionType_Type + * PyCPointerType_Type + * PyCArrayType_Type + * PyCSimpleType_Type + * + * PyCData_Type + * Struct_Type + * Union_Type + * PyCArray_Type + * Simple_Type + * PyCPointer_Type + * PyCField_Type + * + */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" #include "structmember.h" // PyMemberDef - -#include -#ifdef MS_WIN32 -#include -#include -#include -#ifndef IS_INTRESOURCE -#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0) -#endif -#else -#include "ctypes_dlfcn.h" -#endif -#include "ctypes.h" - -PyObject *PyExc_ArgError = NULL; - -/* This dict maps ctypes types to POINTER types */ -PyObject *_ctypes_ptrtype_cache = NULL; - -static PyTypeObject Simple_Type; - -/* a callable object used for unpickling */ -static PyObject *_unpickle; - - - -/****************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *key; - PyObject *dict; -} DictRemoverObject; - -static void -_DictRemover_dealloc(PyObject *myself) -{ - DictRemoverObject *self = (DictRemoverObject *)myself; - Py_XDECREF(self->key); - Py_XDECREF(self->dict); - Py_TYPE(self)->tp_free(myself); -} - -static PyObject * -_DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw) -{ - DictRemoverObject *self = (DictRemoverObject *)myself; - if (self->key && self->dict) { + +#include +#ifdef MS_WIN32 +#include +#include +#include +#ifndef IS_INTRESOURCE +#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0) +#endif +#else +#include "ctypes_dlfcn.h" +#endif +#include "ctypes.h" + +PyObject *PyExc_ArgError = NULL; + +/* This dict maps ctypes types to POINTER types */ +PyObject *_ctypes_ptrtype_cache = NULL; + +static PyTypeObject Simple_Type; + +/* a callable object used for unpickling */ +static PyObject *_unpickle; + + + +/****************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *key; + PyObject *dict; +} DictRemoverObject; + +static void +_DictRemover_dealloc(PyObject *myself) +{ + DictRemoverObject *self = (DictRemoverObject *)myself; + Py_XDECREF(self->key); + Py_XDECREF(self->dict); + Py_TYPE(self)->tp_free(myself); +} + +static PyObject * +_DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw) +{ + DictRemoverObject *self = (DictRemoverObject *)myself; + if (self->key && self->dict) { if (-1 == PyDict_DelItem(self->dict, self->key)) { _PyErr_WriteUnraisableMsg("on calling _ctypes.DictRemover", NULL); } - Py_CLEAR(self->key); - Py_CLEAR(self->dict); - } - Py_RETURN_NONE; -} - -static PyTypeObject DictRemover_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.DictRemover", /* tp_name */ - sizeof(DictRemoverObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - _DictRemover_dealloc, /* tp_dealloc */ + Py_CLEAR(self->key); + Py_CLEAR(self->dict); + } + Py_RETURN_NONE; +} + +static PyTypeObject DictRemover_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.DictRemover", /* tp_name */ + sizeof(DictRemoverObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + _DictRemover_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - _DictRemover_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ -/* XXX should participate in GC? */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - "deletes a key from a dictionary", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ -}; - -int -PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item) -{ - PyObject *obj; - DictRemoverObject *remover; - PyObject *proxy; - int result; - - obj = _PyObject_CallNoArg((PyObject *)&DictRemover_Type); - if (obj == NULL) - return -1; - - remover = (DictRemoverObject *)obj; - assert(remover->key == NULL); - assert(remover->dict == NULL); - Py_INCREF(key); - remover->key = key; - Py_INCREF(dict); - remover->dict = dict; - - proxy = PyWeakref_NewProxy(item, obj); - Py_DECREF(obj); - if (proxy == NULL) - return -1; - - result = PyDict_SetItem(dict, key, proxy); - Py_DECREF(proxy); - return result; -} - -PyObject * -PyDict_GetItemProxy(PyObject *dict, PyObject *key) -{ - PyObject *result; + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + _DictRemover_call, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ +/* XXX should participate in GC? */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "deletes a key from a dictionary", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ +}; + +int +PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item) +{ + PyObject *obj; + DictRemoverObject *remover; + PyObject *proxy; + int result; + + obj = _PyObject_CallNoArg((PyObject *)&DictRemover_Type); + if (obj == NULL) + return -1; + + remover = (DictRemoverObject *)obj; + assert(remover->key == NULL); + assert(remover->dict == NULL); + Py_INCREF(key); + remover->key = key; + Py_INCREF(dict); + remover->dict = dict; + + proxy = PyWeakref_NewProxy(item, obj); + Py_DECREF(obj); + if (proxy == NULL) + return -1; + + result = PyDict_SetItem(dict, key, proxy); + Py_DECREF(proxy); + return result; +} + +PyObject * +PyDict_GetItemProxy(PyObject *dict, PyObject *key) +{ + PyObject *result; PyObject *item = PyDict_GetItemWithError(dict, key); - - if (item == NULL) - return NULL; - if (!PyWeakref_CheckProxy(item)) - return item; - result = PyWeakref_GET_OBJECT(item); - if (result == Py_None) - return NULL; - return result; -} - -/******************************************************************/ - -/* - Allocate a memory block for a pep3118 format string, filled with - a suitable PEP 3118 type code corresponding to the given ctypes - type. Returns NULL on failure, with the error indicator set. - - This produces type codes in the standard size mode (cf. struct module), - since the endianness may need to be swapped to a non-native one - later on. - */ -static char * -_ctypes_alloc_format_string_for_type(char code, int big_endian) -{ - char *result; - char pep_code = '\0'; - - switch (code) { -#if SIZEOF_INT == 2 - case 'i': pep_code = 'h'; break; - case 'I': pep_code = 'H'; break; -#elif SIZEOF_INT == 4 - case 'i': pep_code = 'i'; break; - case 'I': pep_code = 'I'; break; -#elif SIZEOF_INT == 8 - case 'i': pep_code = 'q'; break; - case 'I': pep_code = 'Q'; break; -#else -# error SIZEOF_INT has an unexpected value -#endif /* SIZEOF_INT */ -#if SIZEOF_LONG == 4 - case 'l': pep_code = 'l'; break; - case 'L': pep_code = 'L'; break; -#elif SIZEOF_LONG == 8 - case 'l': pep_code = 'q'; break; - case 'L': pep_code = 'Q'; break; -#else -# error SIZEOF_LONG has an unexpected value -#endif /* SIZEOF_LONG */ -#if SIZEOF__BOOL == 1 - case '?': pep_code = '?'; break; -#elif SIZEOF__BOOL == 2 - case '?': pep_code = 'H'; break; -#elif SIZEOF__BOOL == 4 - case '?': pep_code = 'L'; break; -#elif SIZEOF__BOOL == 8 - case '?': pep_code = 'Q'; break; -#else -# error SIZEOF__BOOL has an unexpected value -#endif /* SIZEOF__BOOL */ - default: - /* The standard-size code is the same as the ctypes one */ - pep_code = code; - break; - } - - result = PyMem_Malloc(3); - if (result == NULL) { - PyErr_NoMemory(); - return NULL; - } - - result[0] = big_endian ? '>' : '<'; - result[1] = pep_code; - result[2] = '\0'; - return result; -} - -/* - Allocate a memory block for a pep3118 format string, copy prefix (if - non-null) and suffix into it. Returns NULL on failure, with the error - indicator set. If called with a suffix of NULL the error indicator must - already be set. - */ -char * -_ctypes_alloc_format_string(const char *prefix, const char *suffix) -{ - size_t len; - char *result; - - if (suffix == NULL) { - assert(PyErr_Occurred()); - return NULL; - } - len = strlen(suffix); - if (prefix) - len += strlen(prefix); - result = PyMem_Malloc(len + 1); - if (result == NULL) { - PyErr_NoMemory(); - return NULL; - } - if (prefix) - strcpy(result, prefix); - else - result[0] = '\0'; - strcat(result, suffix); - return result; -} - -/* - Allocate a memory block for a pep3118 format string, adding - the given prefix (if non-null), an additional shape prefix, and a suffix. - Returns NULL on failure, with the error indicator set. If called with - a suffix of NULL the error indicator must already be set. - */ -char * -_ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape, - const char *prefix, const char *suffix) -{ - char *new_prefix; - char *result; - char buf[32]; - Py_ssize_t prefix_len; - int k; - - prefix_len = 32 * ndim + 3; - if (prefix) - prefix_len += strlen(prefix); - new_prefix = PyMem_Malloc(prefix_len); - if (new_prefix == NULL) { - PyErr_NoMemory(); - return NULL; - } - new_prefix[0] = '\0'; - if (prefix) - strcpy(new_prefix, prefix); - if (ndim > 0) { - /* Add the prefix "(shape[0],shape[1],...,shape[ndim-1])" */ - strcat(new_prefix, "("); - for (k = 0; k < ndim; ++k) { - if (k < ndim-1) { - sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]); - } else { - sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]); - } - strcat(new_prefix, buf); - } - } - result = _ctypes_alloc_format_string(new_prefix, suffix); - PyMem_Free(new_prefix); - return result; -} - + + if (item == NULL) + return NULL; + if (!PyWeakref_CheckProxy(item)) + return item; + result = PyWeakref_GET_OBJECT(item); + if (result == Py_None) + return NULL; + return result; +} + +/******************************************************************/ + +/* + Allocate a memory block for a pep3118 format string, filled with + a suitable PEP 3118 type code corresponding to the given ctypes + type. Returns NULL on failure, with the error indicator set. + + This produces type codes in the standard size mode (cf. struct module), + since the endianness may need to be swapped to a non-native one + later on. + */ +static char * +_ctypes_alloc_format_string_for_type(char code, int big_endian) +{ + char *result; + char pep_code = '\0'; + + switch (code) { +#if SIZEOF_INT == 2 + case 'i': pep_code = 'h'; break; + case 'I': pep_code = 'H'; break; +#elif SIZEOF_INT == 4 + case 'i': pep_code = 'i'; break; + case 'I': pep_code = 'I'; break; +#elif SIZEOF_INT == 8 + case 'i': pep_code = 'q'; break; + case 'I': pep_code = 'Q'; break; +#else +# error SIZEOF_INT has an unexpected value +#endif /* SIZEOF_INT */ +#if SIZEOF_LONG == 4 + case 'l': pep_code = 'l'; break; + case 'L': pep_code = 'L'; break; +#elif SIZEOF_LONG == 8 + case 'l': pep_code = 'q'; break; + case 'L': pep_code = 'Q'; break; +#else +# error SIZEOF_LONG has an unexpected value +#endif /* SIZEOF_LONG */ +#if SIZEOF__BOOL == 1 + case '?': pep_code = '?'; break; +#elif SIZEOF__BOOL == 2 + case '?': pep_code = 'H'; break; +#elif SIZEOF__BOOL == 4 + case '?': pep_code = 'L'; break; +#elif SIZEOF__BOOL == 8 + case '?': pep_code = 'Q'; break; +#else +# error SIZEOF__BOOL has an unexpected value +#endif /* SIZEOF__BOOL */ + default: + /* The standard-size code is the same as the ctypes one */ + pep_code = code; + break; + } + + result = PyMem_Malloc(3); + if (result == NULL) { + PyErr_NoMemory(); + return NULL; + } + + result[0] = big_endian ? '>' : '<'; + result[1] = pep_code; + result[2] = '\0'; + return result; +} + +/* + Allocate a memory block for a pep3118 format string, copy prefix (if + non-null) and suffix into it. Returns NULL on failure, with the error + indicator set. If called with a suffix of NULL the error indicator must + already be set. + */ +char * +_ctypes_alloc_format_string(const char *prefix, const char *suffix) +{ + size_t len; + char *result; + + if (suffix == NULL) { + assert(PyErr_Occurred()); + return NULL; + } + len = strlen(suffix); + if (prefix) + len += strlen(prefix); + result = PyMem_Malloc(len + 1); + if (result == NULL) { + PyErr_NoMemory(); + return NULL; + } + if (prefix) + strcpy(result, prefix); + else + result[0] = '\0'; + strcat(result, suffix); + return result; +} + +/* + Allocate a memory block for a pep3118 format string, adding + the given prefix (if non-null), an additional shape prefix, and a suffix. + Returns NULL on failure, with the error indicator set. If called with + a suffix of NULL the error indicator must already be set. + */ +char * +_ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape, + const char *prefix, const char *suffix) +{ + char *new_prefix; + char *result; + char buf[32]; + Py_ssize_t prefix_len; + int k; + + prefix_len = 32 * ndim + 3; + if (prefix) + prefix_len += strlen(prefix); + new_prefix = PyMem_Malloc(prefix_len); + if (new_prefix == NULL) { + PyErr_NoMemory(); + return NULL; + } + new_prefix[0] = '\0'; + if (prefix) + strcpy(new_prefix, prefix); + if (ndim > 0) { + /* Add the prefix "(shape[0],shape[1],...,shape[ndim-1])" */ + strcat(new_prefix, "("); + for (k = 0; k < ndim; ++k) { + if (k < ndim-1) { + sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]); + } else { + sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]); + } + strcat(new_prefix, buf); + } + } + result = _ctypes_alloc_format_string(new_prefix, suffix); + PyMem_Free(new_prefix); + return result; +} + /* StructParamObject and StructParam_Type are used in _ctypes_callproc() for argument.keep to call PyMem_Free(ptr) on Py_DECREF(argument). @@ -422,21 +422,21 @@ static PyTypeObject StructParam_Type = { }; -/* - PyCStructType_Type - a meta type/class. Creating a new class using this one as - __metaclass__ will call the constructor StructUnionType_new. It replaces the - tp_dict member with a new instance of StgDict, and initializes the C - accessible fields somehow. -*/ - -static PyCArgObject * -StructUnionType_paramfunc(CDataObject *self) -{ - PyCArgObject *parg; +/* + PyCStructType_Type - a meta type/class. Creating a new class using this one as + __metaclass__ will call the constructor StructUnionType_new. It replaces the + tp_dict member with a new instance of StgDict, and initializes the C + accessible fields somehow. +*/ + +static PyCArgObject * +StructUnionType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; PyObject *obj; - StgDictObject *stgdict; + StgDictObject *stgdict; void *ptr; - + if ((size_t)self->b_size > sizeof(void*)) { ptr = PyMem_Malloc(self->b_size); if (ptr == NULL) { @@ -461,69 +461,69 @@ StructUnionType_paramfunc(CDataObject *self) Py_INCREF(obj); } - parg = PyCArgObject_new(); + parg = PyCArgObject_new(); if (parg == NULL) { Py_DECREF(obj); - return NULL; + return NULL; } - - parg->tag = 'V'; - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for structure/union instances */ - parg->pffi_type = &stgdict->ffi_type_pointer; + + parg->tag = 'V'; + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for structure/union instances */ + parg->pffi_type = &stgdict->ffi_type_pointer; parg->value.p = ptr; - parg->size = self->b_size; + parg->size = self->b_size; parg->obj = obj; - return parg; -} - -static PyObject * -StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct) -{ - PyTypeObject *result; - PyObject *fields; - StgDictObject *dict; + return parg; +} + +static PyObject * +StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct) +{ + PyTypeObject *result; + PyObject *fields; + StgDictObject *dict; _Py_IDENTIFIER(_abstract_); _Py_IDENTIFIER(_fields_); - - /* create the new instance (which is a class, - since we are a metatype!) */ - result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); - if (!result) - return NULL; - - /* keep this for bw compatibility */ + + /* create the new instance (which is a class, + since we are a metatype!) */ + result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); + if (!result) + return NULL; + + /* keep this for bw compatibility */ if (_PyDict_GetItemIdWithError(result->tp_dict, &PyId__abstract_)) - return (PyObject *)result; + return (PyObject *)result; if (PyErr_Occurred()) { Py_DECREF(result); return NULL; } - - dict = (StgDictObject *)_PyObject_CallNoArg((PyObject *)&PyCStgDict_Type); - if (!dict) { - Py_DECREF(result); - return NULL; - } + + dict = (StgDictObject *)_PyObject_CallNoArg((PyObject *)&PyCStgDict_Type); + if (!dict) { + Py_DECREF(result); + return NULL; + } if (!isStruct) { dict->flags |= TYPEFLAG_HASUNION; } - /* replace the class dict by our updated stgdict, which holds info - about storage requirements of the instances */ - if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) { - Py_DECREF(result); - Py_DECREF((PyObject *)dict); - return NULL; - } - Py_SETREF(result->tp_dict, (PyObject *)dict); - dict->format = _ctypes_alloc_format_string(NULL, "B"); - if (dict->format == NULL) { - Py_DECREF(result); - return NULL; - } - - dict->paramfunc = StructUnionType_paramfunc; - + /* replace the class dict by our updated stgdict, which holds info + about storage requirements of the instances */ + if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) { + Py_DECREF(result); + Py_DECREF((PyObject *)dict); + return NULL; + } + Py_SETREF(result->tp_dict, (PyObject *)dict); + dict->format = _ctypes_alloc_format_string(NULL, "B"); + if (dict->format == NULL) { + Py_DECREF(result); + return NULL; + } + + dict->paramfunc = StructUnionType_paramfunc; + fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_); if (fields) { if (_PyObject_SetAttrId((PyObject *)result, &PyId__fields_, fields) < 0) { @@ -537,5344 +537,5344 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt return NULL; } else { - StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base); - - if (basedict == NULL) - return (PyObject *)result; - /* copy base dict */ - if (-1 == PyCStgDict_clone(dict, basedict)) { - Py_DECREF(result); - return NULL; - } - dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */ - basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */ - return (PyObject *)result; - } -} - -static PyObject * -PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - return StructUnionType_new(type, args, kwds, 1); -} - -static PyObject * -UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - return StructUnionType_new(type, args, kwds, 0); -} - -static const char from_address_doc[] = -"C.from_address(integer) -> C instance\naccess a C instance at the specified address"; - -static PyObject * -CDataType_from_address(PyObject *type, PyObject *value) -{ - void *buf; - if (!PyLong_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "integer expected"); + StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base); + + if (basedict == NULL) + return (PyObject *)result; + /* copy base dict */ + if (-1 == PyCStgDict_clone(dict, basedict)) { + Py_DECREF(result); + return NULL; + } + dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */ + basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */ + return (PyObject *)result; + } +} + +static PyObject * +PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return StructUnionType_new(type, args, kwds, 1); +} + +static PyObject * +UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return StructUnionType_new(type, args, kwds, 0); +} + +static const char from_address_doc[] = +"C.from_address(integer) -> C instance\naccess a C instance at the specified address"; + +static PyObject * +CDataType_from_address(PyObject *type, PyObject *value) +{ + void *buf; + if (!PyLong_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "integer expected"); + return NULL; + } + buf = (void *)PyLong_AsVoidPtr(value); + if (PyErr_Occurred()) + return NULL; + return PyCData_AtAddress(type, buf); +} + +static const char from_buffer_doc[] = +"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer"; + +static int +KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep); + +static PyObject * +CDataType_from_buffer(PyObject *type, PyObject *args) +{ + PyObject *obj; + PyObject *mv; + PyObject *result; + Py_buffer *buffer; + Py_ssize_t offset = 0; + + StgDictObject *dict = PyType_stgdict(type); + if (!dict) { + PyErr_SetString(PyExc_TypeError, "abstract class"); + return NULL; + } + + if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) + return NULL; + + mv = PyMemoryView_FromObject(obj); + if (mv == NULL) + return NULL; + + buffer = PyMemoryView_GET_BUFFER(mv); + + if (buffer->readonly) { + PyErr_SetString(PyExc_TypeError, + "underlying buffer is not writable"); + Py_DECREF(mv); + return NULL; + } + + if (!PyBuffer_IsContiguous(buffer, 'C')) { + PyErr_SetString(PyExc_TypeError, + "underlying buffer is not C contiguous"); + Py_DECREF(mv); + return NULL; + } + + if (offset < 0) { + PyErr_SetString(PyExc_ValueError, + "offset cannot be negative"); + Py_DECREF(mv); + return NULL; + } + + if (dict->size > buffer->len - offset) { + PyErr_Format(PyExc_ValueError, + "Buffer size too small " + "(%zd instead of at least %zd bytes)", + buffer->len, dict->size + offset); + Py_DECREF(mv); + return NULL; + } + + if (PySys_Audit("ctypes.cdata/buffer", "nnn", + (Py_ssize_t)buffer->buf, buffer->len, offset) < 0) { + Py_DECREF(mv); return NULL; } - buf = (void *)PyLong_AsVoidPtr(value); - if (PyErr_Occurred()) - return NULL; - return PyCData_AtAddress(type, buf); -} - -static const char from_buffer_doc[] = -"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer"; - -static int -KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep); - -static PyObject * -CDataType_from_buffer(PyObject *type, PyObject *args) -{ - PyObject *obj; - PyObject *mv; - PyObject *result; - Py_buffer *buffer; - Py_ssize_t offset = 0; - StgDictObject *dict = PyType_stgdict(type); - if (!dict) { - PyErr_SetString(PyExc_TypeError, "abstract class"); + result = PyCData_AtAddress(type, (char *)buffer->buf + offset); + if (result == NULL) { + Py_DECREF(mv); + return NULL; + } + + if (-1 == KeepRef((CDataObject *)result, -1, mv)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +static const char from_buffer_copy_doc[] = +"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"; + +static PyObject * +GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + +static PyObject * +CDataType_from_buffer_copy(PyObject *type, PyObject *args) +{ + Py_buffer buffer; + Py_ssize_t offset = 0; + PyObject *result; + StgDictObject *dict = PyType_stgdict(type); + if (!dict) { + PyErr_SetString(PyExc_TypeError, "abstract class"); + return NULL; + } + + if (!PyArg_ParseTuple(args, "y*|n:from_buffer_copy", &buffer, &offset)) + return NULL; + + if (offset < 0) { + PyErr_SetString(PyExc_ValueError, + "offset cannot be negative"); + PyBuffer_Release(&buffer); + return NULL; + } + + if (dict->size > buffer.len - offset) { + PyErr_Format(PyExc_ValueError, + "Buffer size too small (%zd instead of at least %zd bytes)", + buffer.len, dict->size + offset); + PyBuffer_Release(&buffer); + return NULL; + } + + if (PySys_Audit("ctypes.cdata/buffer", "nnn", + (Py_ssize_t)buffer.buf, buffer.len, offset) < 0) { + PyBuffer_Release(&buffer); return NULL; } - if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) + result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL); + if (result != NULL) { + memcpy(((CDataObject *)result)->b_ptr, + (char *)buffer.buf + offset, dict->size); + } + PyBuffer_Release(&buffer); + return result; +} + +static const char in_dll_doc[] = +"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll"; + +static PyObject * +CDataType_in_dll(PyObject *type, PyObject *args) +{ + PyObject *dll; + char *name; + PyObject *obj; + void *handle; + void *address; + + if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name)) + return NULL; + if (PySys_Audit("ctypes.dlsym", "O", args) < 0) { return NULL; - - mv = PyMemoryView_FromObject(obj); - if (mv == NULL) + } + + obj = PyObject_GetAttrString(dll, "_handle"); + if (!obj) + return NULL; + if (!PyLong_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "the _handle attribute of the second argument must be an integer"); + Py_DECREF(obj); + return NULL; + } + handle = (void *)PyLong_AsVoidPtr(obj); + Py_DECREF(obj); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "could not convert the _handle attribute to a pointer"); + return NULL; + } + +#ifdef MS_WIN32 + Py_BEGIN_ALLOW_THREADS + address = (void *)GetProcAddress(handle, name); + Py_END_ALLOW_THREADS + if (!address) { + PyErr_Format(PyExc_ValueError, + "symbol '%s' not found", + name); + return NULL; + } +#else + address = (void *)ctypes_dlsym(handle, name); + if (!address) { +#ifdef __CYGWIN__ +/* dlerror() isn't very helpful on cygwin */ + PyErr_Format(PyExc_ValueError, + "symbol '%s' not found", + name); +#else + PyErr_SetString(PyExc_ValueError, ctypes_dlerror()); +#endif + return NULL; + } +#endif + return PyCData_AtAddress(type, address); +} + +static const char from_param_doc[] = +"Convert a Python object into a function call parameter."; + +static PyObject * +CDataType_from_param(PyObject *type, PyObject *value) +{ + _Py_IDENTIFIER(_as_parameter_); + PyObject *as_parameter; + int res = PyObject_IsInstance(value, type); + if (res == -1) + return NULL; + if (res) { + Py_INCREF(value); + return value; + } + if (PyCArg_CheckExact(value)) { + PyCArgObject *p = (PyCArgObject *)value; + PyObject *ob = p->obj; + const char *ob_name; + StgDictObject *dict; + dict = PyType_stgdict(type); + + /* If we got a PyCArgObject, we must check if the object packed in it + is an instance of the type's dict->proto */ + if(dict && ob) { + res = PyObject_IsInstance(ob, dict->proto); + if (res == -1) + return NULL; + if (res) { + Py_INCREF(value); + return value; + } + } + ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???"; + PyErr_Format(PyExc_TypeError, + "expected %s instance instead of pointer to %s", + ((PyTypeObject *)type)->tp_name, ob_name); + return NULL; + } + + if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { return NULL; - - buffer = PyMemoryView_GET_BUFFER(mv); - - if (buffer->readonly) { - PyErr_SetString(PyExc_TypeError, - "underlying buffer is not writable"); - Py_DECREF(mv); + } + if (as_parameter) { + value = CDataType_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } + PyErr_Format(PyExc_TypeError, + "expected %s instance instead of %s", + ((PyTypeObject *)type)->tp_name, + Py_TYPE(value)->tp_name); + return NULL; +} + +static PyMethodDef CDataType_methods[] = { + { "from_param", CDataType_from_param, METH_O, from_param_doc }, + { "from_address", CDataType_from_address, METH_O, from_address_doc }, + { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, + { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, + { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc }, + { NULL, NULL }, +}; + +static PyObject * +CDataType_repeat(PyObject *self, Py_ssize_t length) +{ + if (length < 0) + return PyErr_Format(PyExc_ValueError, + "Array length must be >= 0, not %zd", + length); + return PyCArrayType_from_ctype(self, length); +} + +static PySequenceMethods CDataType_as_sequence = { + 0, /* inquiry sq_length; */ + 0, /* binaryfunc sq_concat; */ + CDataType_repeat, /* intargfunc sq_repeat; */ + 0, /* intargfunc sq_item; */ + 0, /* intintargfunc sq_slice; */ + 0, /* intobjargproc sq_ass_item; */ + 0, /* intintobjargproc sq_ass_slice; */ + 0, /* objobjproc sq_contains; */ + + 0, /* binaryfunc sq_inplace_concat; */ + 0, /* intargfunc sq_inplace_repeat; */ +}; + +static int +CDataType_clear(PyTypeObject *self) +{ + StgDictObject *dict = PyType_stgdict((PyObject *)self); + if (dict) + Py_CLEAR(dict->proto); + return PyType_Type.tp_clear((PyObject *)self); +} + +static int +CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg) +{ + StgDictObject *dict = PyType_stgdict((PyObject *)self); + if (dict) + Py_VISIT(dict->proto); + return PyType_Type.tp_traverse((PyObject *)self, visit, arg); +} + +static int +PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value) +{ + /* XXX Should we disallow deleting _fields_? */ + if (-1 == PyType_Type.tp_setattro(self, key, value)) + return -1; + + if (value && PyUnicode_Check(key) && + _PyUnicode_EqualToASCIIString(key, "_fields_")) + return PyCStructUnionType_update_stgdict(self, value, 1); + return 0; +} + + +static int +UnionType_setattro(PyObject *self, PyObject *key, PyObject *value) +{ + /* XXX Should we disallow deleting _fields_? */ + if (-1 == PyObject_GenericSetAttr(self, key, value)) + return -1; + + if (PyUnicode_Check(key) && + _PyUnicode_EqualToASCIIString(key, "_fields_")) + return PyCStructUnionType_update_stgdict(self, value, 0); + return 0; +} + + +PyTypeObject PyCStructType_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.PyCStructType", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &CDataType_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + PyCStructType_setattro, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + "metatype for the CData Objects", /* tp_doc */ + (traverseproc)CDataType_traverse, /* tp_traverse */ + (inquiry)CDataType_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + CDataType_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyCStructType_new, /* tp_new */ + 0, /* tp_free */ +}; + +static PyTypeObject UnionType_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.UnionType", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &CDataType_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + UnionType_setattro, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + "metatype for the CData Objects", /* tp_doc */ + (traverseproc)CDataType_traverse, /* tp_traverse */ + (inquiry)CDataType_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + CDataType_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + UnionType_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/******************************************************************/ + +/* + +The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be +created. It must check for a _type_ attribute in the class. Since are no +runtime created properties, a CField is probably *not* needed ? + +class IntPointer(Pointer): + _type_ = "i" + +The PyCPointer_Type provides the functionality: a contents method/property, a +size property/method, and the sequence protocol. + +*/ + +static int +PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto) +{ + if (!proto || !PyType_Check(proto)) { + PyErr_SetString(PyExc_TypeError, + "_type_ must be a type"); + return -1; + } + if (!PyType_stgdict(proto)) { + PyErr_SetString(PyExc_TypeError, + "_type_ must have storage info"); + return -1; + } + Py_INCREF(proto); + Py_XSETREF(stgdict->proto, proto); + return 0; +} + +static PyCArgObject * +PyCPointerType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + + parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; + Py_INCREF(self); + parg->obj = (PyObject *)self; + parg->value.p = *(void **)self->b_ptr; + return parg; +} + +static PyObject * +PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyTypeObject *result; + StgDictObject *stgdict; + PyObject *proto; + PyObject *typedict; + _Py_IDENTIFIER(_type_); + + typedict = PyTuple_GetItem(args, 2); + if (!typedict) + return NULL; +/* + stgdict items size, align, length contain info about pointers itself, + stgdict->proto has info about the pointed to type! +*/ + stgdict = (StgDictObject *)_PyObject_CallNoArg( + (PyObject *)&PyCStgDict_Type); + if (!stgdict) + return NULL; + stgdict->size = sizeof(void *); + stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; + stgdict->length = 1; + stgdict->ffi_type_pointer = ffi_type_pointer; + stgdict->paramfunc = PyCPointerType_paramfunc; + stgdict->flags |= TYPEFLAG_ISPOINTER; + + proto = _PyDict_GetItemIdWithError(typedict, &PyId__type_); /* Borrowed ref */ + if (proto) { + StgDictObject *itemdict; + const char *current_format; + if (-1 == PyCPointerType_SetProto(stgdict, proto)) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } + itemdict = PyType_stgdict(proto); + /* PyCPointerType_SetProto has verified proto has a stgdict. */ + assert(itemdict); + /* If itemdict->format is NULL, then this is a pointer to an + incomplete type. We create a generic format string + 'pointer to bytes' in this case. XXX Better would be to + fix the format string later... + */ + current_format = itemdict->format ? itemdict->format : "B"; + if (itemdict->shape != NULL) { + /* pointer to an array: the shape needs to be prefixed */ + stgdict->format = _ctypes_alloc_format_string_with_shape( + itemdict->ndim, itemdict->shape, "&", current_format); + } else { + stgdict->format = _ctypes_alloc_format_string("&", current_format); + } + if (stgdict->format == NULL) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } + } + else if (PyErr_Occurred()) { + Py_DECREF((PyObject *)stgdict); return NULL; } + + /* create the new instance (which is a class, + since we are a metatype!) */ + result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); + if (result == NULL) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } + + /* replace the class dict by our updated spam dict */ + if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { + Py_DECREF(result); + Py_DECREF((PyObject *)stgdict); + return NULL; + } + Py_SETREF(result->tp_dict, (PyObject *)stgdict); + + return (PyObject *)result; +} + + +static PyObject * +PyCPointerType_set_type(PyTypeObject *self, PyObject *type) +{ + StgDictObject *dict; + _Py_IDENTIFIER(_type_); + + dict = PyType_stgdict((PyObject *)self); + if (!dict) { + PyErr_SetString(PyExc_TypeError, + "abstract class"); + return NULL; + } + + if (-1 == PyCPointerType_SetProto(dict, type)) + return NULL; + + if (-1 == _PyDict_SetItemId((PyObject *)dict, &PyId__type_, type)) + return NULL; + + Py_RETURN_NONE; +} + +static PyObject *_byref(PyObject *); + +static PyObject * +PyCPointerType_from_param(PyObject *type, PyObject *value) +{ + StgDictObject *typedict; + + if (value == Py_None) { + /* ConvParam will convert to a NULL pointer later */ + Py_INCREF(value); + return value; + } + + typedict = PyType_stgdict(type); + if (!typedict) { + PyErr_SetString(PyExc_TypeError, + "abstract class"); + return NULL; + } + + /* If we expect POINTER(), but receive a instance, accept + it by calling byref(). + */ + switch (PyObject_IsInstance(value, typedict->proto)) { + case 1: + Py_INCREF(value); /* _byref steals a refcount */ + return _byref(value); + case -1: + return NULL; + default: + break; + } + + if (PointerObject_Check(value) || ArrayObject_Check(value)) { + /* Array instances are also pointers when + the item types are the same. + */ + StgDictObject *v = PyObject_stgdict(value); + assert(v); /* Cannot be NULL for pointer or array objects */ + int ret = PyObject_IsSubclass(v->proto, typedict->proto); + if (ret < 0) { + return NULL; + } + if (ret) { + Py_INCREF(value); + return value; + } + } + return CDataType_from_param(type, value); +} + +static PyMethodDef PyCPointerType_methods[] = { + { "from_address", CDataType_from_address, METH_O, from_address_doc }, + { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, + { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, + { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc}, + { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc}, + { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O }, + { NULL, NULL }, +}; + +PyTypeObject PyCPointerType_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.PyCPointerType", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &CDataType_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + "metatype for the Pointer Objects", /* tp_doc */ + (traverseproc)CDataType_traverse, /* tp_traverse */ + (inquiry)CDataType_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyCPointerType_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyCPointerType_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/******************************************************************/ +/* + PyCArrayType_Type +*/ +/* + PyCArrayType_new ensures that the new Array subclass created has a _length_ + attribute, and a _type_ attribute. +*/ + +static int +CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) +{ + char *ptr; + Py_ssize_t size; + Py_buffer view; + + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0) + return -1; + size = view.len; + ptr = view.buf; + if (size > self->b_size) { + PyErr_SetString(PyExc_ValueError, + "byte string too long"); + goto fail; + } + + memcpy(self->b_ptr, ptr, size); + + PyBuffer_Release(&view); + return 0; + fail: + PyBuffer_Release(&view); + return -1; +} + +static PyObject * +CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored)) +{ + return PyBytes_FromStringAndSize(self->b_ptr, self->b_size); +} + +static PyObject * +CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored)) +{ + Py_ssize_t i; + char *ptr = self->b_ptr; + for (i = 0; i < self->b_size; ++i) + if (*ptr++ == '\0') + break; + return PyBytes_FromStringAndSize(self->b_ptr, i); +} + +static int +CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) +{ + const char *ptr; + Py_ssize_t size; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete attribute"); + return -1; + } + + if (!PyBytes_Check(value)) { + PyErr_Format(PyExc_TypeError, + "bytes expected instead of %s instance", + Py_TYPE(value)->tp_name); + return -1; + } else + Py_INCREF(value); + size = PyBytes_GET_SIZE(value); + if (size > self->b_size) { + PyErr_SetString(PyExc_ValueError, + "byte string too long"); + Py_DECREF(value); + return -1; + } + + ptr = PyBytes_AS_STRING(value); + memcpy(self->b_ptr, ptr, size); + if (size < self->b_size) + self->b_ptr[size] = '\0'; + Py_DECREF(value); + + return 0; +} + +static PyGetSetDef CharArray_getsets[] = { + { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw, + "value", NULL }, + { "value", (getter)CharArray_get_value, (setter)CharArray_set_value, + "string value"}, + { NULL, NULL } +}; + +#ifdef CTYPES_UNICODE +static PyObject * +WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored)) +{ + Py_ssize_t i; + wchar_t *ptr = (wchar_t *)self->b_ptr; + for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i) + if (*ptr++ == (wchar_t)0) + break; + return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i); +} + +static int +WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) +{ + Py_ssize_t result = 0; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete attribute"); + return -1; + } + if (!PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "unicode string expected instead of %s instance", + Py_TYPE(value)->tp_name); + return -1; + } else + Py_INCREF(value); + + Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0); + if (len < 0) { + return -1; + } + // PyUnicode_AsWideChar() returns number of wchars including trailing null byte, + // when it is called with NULL. + if (((size_t)len-1) > self->b_size/sizeof(wchar_t)) { + PyErr_SetString(PyExc_ValueError, "string too long"); + result = -1; + goto done; + } + result = PyUnicode_AsWideChar(value, + (wchar_t *)self->b_ptr, + self->b_size/sizeof(wchar_t)); + if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t)) + ((wchar_t *)self->b_ptr)[result] = (wchar_t)0; + done: + Py_DECREF(value); + + return result >= 0 ? 0 : -1; +} + +static PyGetSetDef WCharArray_getsets[] = { + { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value, + "string value"}, + { NULL, NULL } +}; +#endif + +/* + The next three functions copied from Python's typeobject.c. + + They are used to attach methods, members, or getsets to a type *after* it + has been created: Arrays of characters have additional getsets to treat them + as strings. + */ +/* +static int +add_methods(PyTypeObject *type, PyMethodDef *meth) +{ + PyObject *dict = type->tp_dict; + for (; meth->ml_name != NULL; meth++) { + PyObject *descr; + descr = PyDescr_NewMethod(type, meth); + if (descr == NULL) + return -1; + if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + } + return 0; +} + +static int +add_members(PyTypeObject *type, PyMemberDef *memb) +{ + PyObject *dict = type->tp_dict; + for (; memb->name != NULL; memb++) { + PyObject *descr; + descr = PyDescr_NewMember(type, memb); + if (descr == NULL) + return -1; + if (PyDict_SetItemString(dict, memb->name, descr) < 0) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + } + return 0; +} +*/ + +static int +add_getset(PyTypeObject *type, PyGetSetDef *gsp) +{ + PyObject *dict = type->tp_dict; + for (; gsp->name != NULL; gsp++) { + PyObject *descr; + descr = PyDescr_NewGetSet(type, gsp); + if (descr == NULL) + return -1; + if (PyDict_SetItemString(dict, gsp->name, descr) < 0) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + } + return 0; +} + +static PyCArgObject * +PyCArrayType_paramfunc(CDataObject *self) +{ + PyCArgObject *p = PyCArgObject_new(); + if (p == NULL) + return NULL; + p->tag = 'P'; + p->pffi_type = &ffi_type_pointer; + p->value.p = (char *)self->b_ptr; + Py_INCREF(self); + p->obj = (PyObject *)self; + return p; +} + +static PyObject * +PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + _Py_IDENTIFIER(_length_); + _Py_IDENTIFIER(_type_); + PyTypeObject *result; + StgDictObject *stgdict; + StgDictObject *itemdict; + PyObject *length_attr, *type_attr; + Py_ssize_t length; + Py_ssize_t itemsize, itemalign; + + /* create the new instance (which is a class, + since we are a metatype!) */ + result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); + if (result == NULL) + return NULL; + + /* Initialize these variables to NULL so that we can simplify error + handling by using Py_XDECREF. */ + stgdict = NULL; + type_attr = NULL; + + if (_PyObject_LookupAttrId((PyObject *)result, &PyId__length_, &length_attr) < 0) { + goto error; + } + if (!length_attr) { + PyErr_SetString(PyExc_AttributeError, + "class must define a '_length_' attribute"); + goto error; + } - if (!PyBuffer_IsContiguous(buffer, 'C')) { + if (!PyLong_Check(length_attr)) { + Py_DECREF(length_attr); PyErr_SetString(PyExc_TypeError, - "underlying buffer is not C contiguous"); - Py_DECREF(mv); - return NULL; + "The '_length_' attribute must be an integer"); + goto error; } - if (offset < 0) { + if (_PyLong_Sign(length_attr) == -1) { + Py_DECREF(length_attr); PyErr_SetString(PyExc_ValueError, - "offset cannot be negative"); - Py_DECREF(mv); - return NULL; + "The '_length_' attribute must not be negative"); + goto error; } - if (dict->size > buffer->len - offset) { - PyErr_Format(PyExc_ValueError, - "Buffer size too small " - "(%zd instead of at least %zd bytes)", - buffer->len, dict->size + offset); - Py_DECREF(mv); - return NULL; + length = PyLong_AsSsize_t(length_attr); + Py_DECREF(length_attr); + if (length == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "The '_length_' attribute is too large"); + } + goto error; + } + + if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &type_attr) < 0) { + goto error; } - - if (PySys_Audit("ctypes.cdata/buffer", "nnn", - (Py_ssize_t)buffer->buf, buffer->len, offset) < 0) { - Py_DECREF(mv); + if (!type_attr) { + PyErr_SetString(PyExc_AttributeError, + "class must define a '_type_' attribute"); + goto error; + } + + stgdict = (StgDictObject *)_PyObject_CallNoArg( + (PyObject *)&PyCStgDict_Type); + if (!stgdict) + goto error; + + itemdict = PyType_stgdict(type_attr); + if (!itemdict) { + PyErr_SetString(PyExc_TypeError, + "_type_ must have storage info"); + goto error; + } + + assert(itemdict->format); + stgdict->format = _ctypes_alloc_format_string(NULL, itemdict->format); + if (stgdict->format == NULL) + goto error; + stgdict->ndim = itemdict->ndim + 1; + stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t) * stgdict->ndim); + if (stgdict->shape == NULL) { + PyErr_NoMemory(); + goto error; + } + stgdict->shape[0] = length; + if (stgdict->ndim > 1) { + memmove(&stgdict->shape[1], itemdict->shape, + sizeof(Py_ssize_t) * (stgdict->ndim - 1)); + } + + itemsize = itemdict->size; + if (itemsize != 0 && length > PY_SSIZE_T_MAX / itemsize) { + PyErr_SetString(PyExc_OverflowError, + "array too large"); + goto error; + } + + itemalign = itemdict->align; + + if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) + stgdict->flags |= TYPEFLAG_HASPOINTER; + + stgdict->size = itemsize * length; + stgdict->align = itemalign; + stgdict->length = length; + stgdict->proto = type_attr; + type_attr = NULL; + + stgdict->paramfunc = &PyCArrayType_paramfunc; + + /* Arrays are passed as pointers to function calls. */ + stgdict->ffi_type_pointer = ffi_type_pointer; + + /* replace the class dict by our updated spam dict */ + if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) + goto error; + Py_SETREF(result->tp_dict, (PyObject *)stgdict); /* steal the reference */ + stgdict = NULL; + + /* Special case for character arrays. + A permanent annoyance: char arrays are also strings! + */ + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { + if (-1 == add_getset(result, CharArray_getsets)) + goto error; +#ifdef CTYPES_UNICODE + } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { + if (-1 == add_getset(result, WCharArray_getsets)) + goto error; +#endif + } + + return (PyObject *)result; +error: + Py_XDECREF((PyObject*)stgdict); + Py_XDECREF(type_attr); + Py_DECREF(result); + return NULL; +} + +PyTypeObject PyCArrayType_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.PyCArrayType", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &CDataType_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "metatype for the Array Objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + CDataType_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyCArrayType_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/******************************************************************/ +/* + PyCSimpleType_Type +*/ +/* + +PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid +_type_ attribute. + +*/ + +static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; + +static PyObject * +c_wchar_p_from_param(PyObject *type, PyObject *value) +{ + _Py_IDENTIFIER(_as_parameter_); + PyObject *as_parameter; + int res; + if (value == Py_None) { + Py_RETURN_NONE; + } + if (PyUnicode_Check(value)) { + PyCArgObject *parg; + struct fielddesc *fd = _ctypes_get_fielddesc("Z"); + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + parg->pffi_type = &ffi_type_pointer; + parg->tag = 'Z'; + parg->obj = fd->setfunc(&parg->value, value, 0); + if (parg->obj == NULL) { + Py_DECREF(parg); + return NULL; + } + return (PyObject *)parg; + } + res = PyObject_IsInstance(value, type); + if (res == -1) + return NULL; + if (res) { + Py_INCREF(value); + return value; + } + if (ArrayObject_Check(value) || PointerObject_Check(value)) { + /* c_wchar array instance or pointer(c_wchar(...)) */ + StgDictObject *dt = PyObject_stgdict(value); + StgDictObject *dict; + assert(dt); /* Cannot be NULL for pointer or array objects */ + dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; + if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { + Py_INCREF(value); + return value; + } + } + if (PyCArg_CheckExact(value)) { + /* byref(c_char(...)) */ + PyCArgObject *a = (PyCArgObject *)value; + StgDictObject *dict = PyObject_stgdict(a->obj); + if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { + Py_INCREF(value); + return value; + } + } + + if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { return NULL; } - - result = PyCData_AtAddress(type, (char *)buffer->buf + offset); - if (result == NULL) { - Py_DECREF(mv); + if (as_parameter) { + value = c_wchar_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } + /* XXX better message */ + PyErr_SetString(PyExc_TypeError, + "wrong type"); + return NULL; +} + +static PyObject * +c_char_p_from_param(PyObject *type, PyObject *value) +{ + _Py_IDENTIFIER(_as_parameter_); + PyObject *as_parameter; + int res; + if (value == Py_None) { + Py_RETURN_NONE; + } + if (PyBytes_Check(value)) { + PyCArgObject *parg; + struct fielddesc *fd = _ctypes_get_fielddesc("z"); + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + parg->pffi_type = &ffi_type_pointer; + parg->tag = 'z'; + parg->obj = fd->setfunc(&parg->value, value, 0); + if (parg->obj == NULL) { + Py_DECREF(parg); + return NULL; + } + return (PyObject *)parg; + } + res = PyObject_IsInstance(value, type); + if (res == -1) + return NULL; + if (res) { + Py_INCREF(value); + return value; + } + if (ArrayObject_Check(value) || PointerObject_Check(value)) { + /* c_char array instance or pointer(c_char(...)) */ + StgDictObject *dt = PyObject_stgdict(value); + StgDictObject *dict; + assert(dt); /* Cannot be NULL for pointer or array objects */ + dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; + if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { + Py_INCREF(value); + return value; + } + } + if (PyCArg_CheckExact(value)) { + /* byref(c_char(...)) */ + PyCArgObject *a = (PyCArgObject *)value; + StgDictObject *dict = PyObject_stgdict(a->obj); + if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { + Py_INCREF(value); + return value; + } + } + + if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { return NULL; } - - if (-1 == KeepRef((CDataObject *)result, -1, mv)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -static const char from_buffer_copy_doc[] = -"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"; - -static PyObject * -GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); - -static PyObject * -CDataType_from_buffer_copy(PyObject *type, PyObject *args) -{ - Py_buffer buffer; - Py_ssize_t offset = 0; - PyObject *result; - StgDictObject *dict = PyType_stgdict(type); - if (!dict) { - PyErr_SetString(PyExc_TypeError, "abstract class"); - return NULL; - } - - if (!PyArg_ParseTuple(args, "y*|n:from_buffer_copy", &buffer, &offset)) - return NULL; - - if (offset < 0) { - PyErr_SetString(PyExc_ValueError, - "offset cannot be negative"); - PyBuffer_Release(&buffer); - return NULL; - } - - if (dict->size > buffer.len - offset) { - PyErr_Format(PyExc_ValueError, - "Buffer size too small (%zd instead of at least %zd bytes)", - buffer.len, dict->size + offset); - PyBuffer_Release(&buffer); - return NULL; - } - - if (PySys_Audit("ctypes.cdata/buffer", "nnn", - (Py_ssize_t)buffer.buf, buffer.len, offset) < 0) { - PyBuffer_Release(&buffer); - return NULL; - } - - result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL); - if (result != NULL) { - memcpy(((CDataObject *)result)->b_ptr, - (char *)buffer.buf + offset, dict->size); - } - PyBuffer_Release(&buffer); - return result; -} - -static const char in_dll_doc[] = -"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll"; - -static PyObject * -CDataType_in_dll(PyObject *type, PyObject *args) -{ - PyObject *dll; - char *name; - PyObject *obj; - void *handle; - void *address; - - if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name)) - return NULL; - if (PySys_Audit("ctypes.dlsym", "O", args) < 0) { - return NULL; - } - - obj = PyObject_GetAttrString(dll, "_handle"); - if (!obj) - return NULL; - if (!PyLong_Check(obj)) { - PyErr_SetString(PyExc_TypeError, - "the _handle attribute of the second argument must be an integer"); - Py_DECREF(obj); - return NULL; - } - handle = (void *)PyLong_AsVoidPtr(obj); - Py_DECREF(obj); - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "could not convert the _handle attribute to a pointer"); - return NULL; - } - -#ifdef MS_WIN32 - Py_BEGIN_ALLOW_THREADS - address = (void *)GetProcAddress(handle, name); - Py_END_ALLOW_THREADS - if (!address) { - PyErr_Format(PyExc_ValueError, - "symbol '%s' not found", - name); - return NULL; - } -#else - address = (void *)ctypes_dlsym(handle, name); - if (!address) { -#ifdef __CYGWIN__ -/* dlerror() isn't very helpful on cygwin */ - PyErr_Format(PyExc_ValueError, - "symbol '%s' not found", - name); -#else - PyErr_SetString(PyExc_ValueError, ctypes_dlerror()); -#endif - return NULL; - } -#endif - return PyCData_AtAddress(type, address); -} - -static const char from_param_doc[] = -"Convert a Python object into a function call parameter."; - -static PyObject * -CDataType_from_param(PyObject *type, PyObject *value) -{ + if (as_parameter) { + value = c_char_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } + /* XXX better message */ + PyErr_SetString(PyExc_TypeError, + "wrong type"); + return NULL; +} + +static PyObject * +c_void_p_from_param(PyObject *type, PyObject *value) +{ _Py_IDENTIFIER(_as_parameter_); - PyObject *as_parameter; - int res = PyObject_IsInstance(value, type); - if (res == -1) - return NULL; - if (res) { - Py_INCREF(value); - return value; - } - if (PyCArg_CheckExact(value)) { - PyCArgObject *p = (PyCArgObject *)value; - PyObject *ob = p->obj; - const char *ob_name; - StgDictObject *dict; - dict = PyType_stgdict(type); - - /* If we got a PyCArgObject, we must check if the object packed in it - is an instance of the type's dict->proto */ - if(dict && ob) { - res = PyObject_IsInstance(ob, dict->proto); - if (res == -1) - return NULL; - if (res) { - Py_INCREF(value); - return value; - } - } - ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???"; - PyErr_Format(PyExc_TypeError, - "expected %s instance instead of pointer to %s", - ((PyTypeObject *)type)->tp_name, ob_name); - return NULL; - } - + StgDictObject *stgd; + PyObject *as_parameter; + int res; + +/* None */ + if (value == Py_None) { + Py_RETURN_NONE; + } + /* Should probably allow buffer interface as well */ +/* int, long */ + if (PyLong_Check(value)) { + PyCArgObject *parg; + struct fielddesc *fd = _ctypes_get_fielddesc("P"); + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + parg->pffi_type = &ffi_type_pointer; + parg->tag = 'P'; + parg->obj = fd->setfunc(&parg->value, value, 0); + if (parg->obj == NULL) { + Py_DECREF(parg); + return NULL; + } + return (PyObject *)parg; + } + /* XXX struni: remove later */ +/* bytes */ + if (PyBytes_Check(value)) { + PyCArgObject *parg; + struct fielddesc *fd = _ctypes_get_fielddesc("z"); + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + parg->pffi_type = &ffi_type_pointer; + parg->tag = 'z'; + parg->obj = fd->setfunc(&parg->value, value, 0); + if (parg->obj == NULL) { + Py_DECREF(parg); + return NULL; + } + return (PyObject *)parg; + } +/* unicode */ + if (PyUnicode_Check(value)) { + PyCArgObject *parg; + struct fielddesc *fd = _ctypes_get_fielddesc("Z"); + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + parg->pffi_type = &ffi_type_pointer; + parg->tag = 'Z'; + parg->obj = fd->setfunc(&parg->value, value, 0); + if (parg->obj == NULL) { + Py_DECREF(parg); + return NULL; + } + return (PyObject *)parg; + } +/* c_void_p instance (or subclass) */ + res = PyObject_IsInstance(value, type); + if (res == -1) + return NULL; + if (res) { + /* c_void_p instances */ + Py_INCREF(value); + return value; + } +/* ctypes array or pointer instance */ + if (ArrayObject_Check(value) || PointerObject_Check(value)) { + /* Any array or pointer is accepted */ + Py_INCREF(value); + return value; + } +/* byref(...) */ + if (PyCArg_CheckExact(value)) { + /* byref(c_xxx()) */ + PyCArgObject *a = (PyCArgObject *)value; + if (a->tag == 'P') { + Py_INCREF(value); + return value; + } + } +/* function pointer */ + if (PyCFuncPtrObject_Check(value)) { + PyCArgObject *parg; + PyCFuncPtrObject *func; + func = (PyCFuncPtrObject *)value; + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + parg->pffi_type = &ffi_type_pointer; + parg->tag = 'P'; + Py_INCREF(value); + parg->value.p = *(void **)func->b_ptr; + parg->obj = value; + return (PyObject *)parg; + } +/* c_char_p, c_wchar_p */ + stgd = PyObject_stgdict(value); + if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)) { + PyCArgObject *parg; + + switch (PyUnicode_AsUTF8(stgd->proto)[0]) { + case 'z': /* c_char_p */ + case 'Z': /* c_wchar_p */ + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + parg->pffi_type = &ffi_type_pointer; + parg->tag = 'Z'; + Py_INCREF(value); + parg->obj = value; + /* Remember: b_ptr points to where the pointer is stored! */ + parg->value.p = *(void **)(((CDataObject *)value)->b_ptr); + return (PyObject *)parg; + } + } + if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { return NULL; } - if (as_parameter) { - value = CDataType_from_param(type, as_parameter); - Py_DECREF(as_parameter); - return value; - } - PyErr_Format(PyExc_TypeError, - "expected %s instance instead of %s", - ((PyTypeObject *)type)->tp_name, - Py_TYPE(value)->tp_name); - return NULL; -} - -static PyMethodDef CDataType_methods[] = { - { "from_param", CDataType_from_param, METH_O, from_param_doc }, - { "from_address", CDataType_from_address, METH_O, from_address_doc }, - { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, - { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, - { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc }, - { NULL, NULL }, -}; - -static PyObject * -CDataType_repeat(PyObject *self, Py_ssize_t length) -{ - if (length < 0) - return PyErr_Format(PyExc_ValueError, - "Array length must be >= 0, not %zd", - length); - return PyCArrayType_from_ctype(self, length); -} - -static PySequenceMethods CDataType_as_sequence = { - 0, /* inquiry sq_length; */ - 0, /* binaryfunc sq_concat; */ - CDataType_repeat, /* intargfunc sq_repeat; */ - 0, /* intargfunc sq_item; */ - 0, /* intintargfunc sq_slice; */ - 0, /* intobjargproc sq_ass_item; */ - 0, /* intintobjargproc sq_ass_slice; */ - 0, /* objobjproc sq_contains; */ - - 0, /* binaryfunc sq_inplace_concat; */ - 0, /* intargfunc sq_inplace_repeat; */ -}; - -static int -CDataType_clear(PyTypeObject *self) -{ - StgDictObject *dict = PyType_stgdict((PyObject *)self); - if (dict) - Py_CLEAR(dict->proto); - return PyType_Type.tp_clear((PyObject *)self); -} - -static int -CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg) -{ - StgDictObject *dict = PyType_stgdict((PyObject *)self); - if (dict) - Py_VISIT(dict->proto); - return PyType_Type.tp_traverse((PyObject *)self, visit, arg); -} - -static int -PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value) -{ - /* XXX Should we disallow deleting _fields_? */ - if (-1 == PyType_Type.tp_setattro(self, key, value)) - return -1; - - if (value && PyUnicode_Check(key) && - _PyUnicode_EqualToASCIIString(key, "_fields_")) - return PyCStructUnionType_update_stgdict(self, value, 1); - return 0; -} - - -static int -UnionType_setattro(PyObject *self, PyObject *key, PyObject *value) -{ - /* XXX Should we disallow deleting _fields_? */ - if (-1 == PyObject_GenericSetAttr(self, key, value)) - return -1; - - if (PyUnicode_Check(key) && - _PyUnicode_EqualToASCIIString(key, "_fields_")) - return PyCStructUnionType_update_stgdict(self, value, 0); - return 0; -} - - -PyTypeObject PyCStructType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCStructType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - PyCStructType_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the CData Objects", /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCStructType_new, /* tp_new */ - 0, /* tp_free */ -}; - -static PyTypeObject UnionType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.UnionType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - UnionType_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the CData Objects", /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - UnionType_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/******************************************************************/ - -/* - -The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be -created. It must check for a _type_ attribute in the class. Since are no -runtime created properties, a CField is probably *not* needed ? - -class IntPointer(Pointer): - _type_ = "i" - -The PyCPointer_Type provides the functionality: a contents method/property, a -size property/method, and the sequence protocol. - -*/ - -static int -PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto) -{ - if (!proto || !PyType_Check(proto)) { - PyErr_SetString(PyExc_TypeError, - "_type_ must be a type"); - return -1; - } - if (!PyType_stgdict(proto)) { - PyErr_SetString(PyExc_TypeError, - "_type_ must have storage info"); - return -1; - } - Py_INCREF(proto); - Py_XSETREF(stgdict->proto, proto); - return 0; -} - -static PyCArgObject * -PyCPointerType_paramfunc(CDataObject *self) -{ - PyCArgObject *parg; - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - - parg->tag = 'P'; - parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; - parg->value.p = *(void **)self->b_ptr; - return parg; -} - -static PyObject * -PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyTypeObject *result; - StgDictObject *stgdict; - PyObject *proto; - PyObject *typedict; - _Py_IDENTIFIER(_type_); - - typedict = PyTuple_GetItem(args, 2); - if (!typedict) - return NULL; -/* - stgdict items size, align, length contain info about pointers itself, - stgdict->proto has info about the pointed to type! -*/ + if (as_parameter) { + value = c_void_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } + /* XXX better message */ + PyErr_SetString(PyExc_TypeError, + "wrong type"); + return NULL; +} + +static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O }; +static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O }; +static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O }; + +static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds, + PyObject *proto, struct fielddesc *fmt) +{ + PyTypeObject *result; + StgDictObject *stgdict; + PyObject *name = PyTuple_GET_ITEM(args, 0); + PyObject *newname; + PyObject *swapped_args; + static PyObject *suffix; + Py_ssize_t i; + + swapped_args = PyTuple_New(PyTuple_GET_SIZE(args)); + if (!swapped_args) + return NULL; + + if (suffix == NULL) +#ifdef WORDS_BIGENDIAN + suffix = PyUnicode_InternFromString("_le"); +#else + suffix = PyUnicode_InternFromString("_be"); +#endif + if (suffix == NULL) { + Py_DECREF(swapped_args); + return NULL; + } + + newname = PyUnicode_Concat(name, suffix); + if (newname == NULL) { + Py_DECREF(swapped_args); + return NULL; + } + + PyTuple_SET_ITEM(swapped_args, 0, newname); + for (i=1; isize = sizeof(void *); - stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; - stgdict->length = 1; - stgdict->ffi_type_pointer = ffi_type_pointer; - stgdict->paramfunc = PyCPointerType_paramfunc; - stgdict->flags |= TYPEFLAG_ISPOINTER; - - proto = _PyDict_GetItemIdWithError(typedict, &PyId__type_); /* Borrowed ref */ - if (proto) { - StgDictObject *itemdict; - const char *current_format; - if (-1 == PyCPointerType_SetProto(stgdict, proto)) { - Py_DECREF((PyObject *)stgdict); - return NULL; - } - itemdict = PyType_stgdict(proto); - /* PyCPointerType_SetProto has verified proto has a stgdict. */ - assert(itemdict); - /* If itemdict->format is NULL, then this is a pointer to an - incomplete type. We create a generic format string - 'pointer to bytes' in this case. XXX Better would be to - fix the format string later... - */ - current_format = itemdict->format ? itemdict->format : "B"; - if (itemdict->shape != NULL) { - /* pointer to an array: the shape needs to be prefixed */ - stgdict->format = _ctypes_alloc_format_string_with_shape( - itemdict->ndim, itemdict->shape, "&", current_format); - } else { - stgdict->format = _ctypes_alloc_format_string("&", current_format); - } - if (stgdict->format == NULL) { - Py_DECREF((PyObject *)stgdict); - return NULL; - } - } - else if (PyErr_Occurred()) { - Py_DECREF((PyObject *)stgdict); - return NULL; - } - - /* create the new instance (which is a class, - since we are a metatype!) */ - result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); - if (result == NULL) { - Py_DECREF((PyObject *)stgdict); - return NULL; - } - - /* replace the class dict by our updated spam dict */ - if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { - Py_DECREF(result); - Py_DECREF((PyObject *)stgdict); - return NULL; - } - Py_SETREF(result->tp_dict, (PyObject *)stgdict); - - return (PyObject *)result; -} - - -static PyObject * -PyCPointerType_set_type(PyTypeObject *self, PyObject *type) -{ - StgDictObject *dict; + if (!stgdict) { + Py_DECREF(result); + return NULL; + } + + stgdict->ffi_type_pointer = *fmt->pffi_type; + stgdict->align = fmt->pffi_type->alignment; + stgdict->length = 0; + stgdict->size = fmt->pffi_type->size; + stgdict->setfunc = fmt->setfunc_swapped; + stgdict->getfunc = fmt->getfunc_swapped; + + Py_INCREF(proto); + stgdict->proto = proto; + + /* replace the class dict by our updated spam dict */ + if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { + Py_DECREF(result); + Py_DECREF((PyObject *)stgdict); + return NULL; + } + Py_SETREF(result->tp_dict, (PyObject *)stgdict); + + return (PyObject *)result; +} + +static PyCArgObject * +PyCSimpleType_paramfunc(CDataObject *self) +{ + StgDictObject *dict; + const char *fmt; + PyCArgObject *parg; + struct fielddesc *fd; + + dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ + fmt = PyUnicode_AsUTF8(dict->proto); + assert(fmt); + + fd = _ctypes_get_fielddesc(fmt); + assert(fd); + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + + parg->tag = fmt[0]; + parg->pffi_type = fd->pffi_type; + Py_INCREF(self); + parg->obj = (PyObject *)self; + memcpy(&parg->value, self->b_ptr, self->b_size); + return parg; +} + +static PyObject * +PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ _Py_IDENTIFIER(_type_); - - dict = PyType_stgdict((PyObject *)self); - if (!dict) { - PyErr_SetString(PyExc_TypeError, - "abstract class"); - return NULL; - } - - if (-1 == PyCPointerType_SetProto(dict, type)) - return NULL; - - if (-1 == _PyDict_SetItemId((PyObject *)dict, &PyId__type_, type)) - return NULL; - - Py_RETURN_NONE; -} - -static PyObject *_byref(PyObject *); - -static PyObject * -PyCPointerType_from_param(PyObject *type, PyObject *value) -{ - StgDictObject *typedict; - - if (value == Py_None) { - /* ConvParam will convert to a NULL pointer later */ - Py_INCREF(value); - return value; - } - - typedict = PyType_stgdict(type); - if (!typedict) { - PyErr_SetString(PyExc_TypeError, - "abstract class"); + PyTypeObject *result; + StgDictObject *stgdict; + PyObject *proto; + const char *proto_str; + Py_ssize_t proto_len; + PyMethodDef *ml; + struct fielddesc *fmt; + + /* create the new instance (which is a class, + since we are a metatype!) */ + result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); + if (result == NULL) + return NULL; + + if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &proto) < 0) { return NULL; } - - /* If we expect POINTER(), but receive a instance, accept - it by calling byref(). - */ - switch (PyObject_IsInstance(value, typedict->proto)) { - case 1: - Py_INCREF(value); /* _byref steals a refcount */ - return _byref(value); - case -1: + if (!proto) { + PyErr_SetString(PyExc_AttributeError, + "class must define a '_type_' attribute"); + error: + Py_XDECREF(proto); + Py_DECREF(result); + return NULL; + } + if (PyUnicode_Check(proto)) { + proto_str = PyUnicode_AsUTF8AndSize(proto, &proto_len); + if (!proto_str) + goto error; + } else { + PyErr_SetString(PyExc_TypeError, + "class must define a '_type_' string attribute"); + goto error; + } + if (proto_len != 1) { + PyErr_SetString(PyExc_ValueError, + "class must define a '_type_' attribute " + "which must be a string of length 1"); + goto error; + } + if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) { + PyErr_Format(PyExc_AttributeError, + "class must define a '_type_' attribute which must be\n" + "a single character string containing one of '%s'.", + SIMPLE_TYPE_CHARS); + goto error; + } + fmt = _ctypes_get_fielddesc(proto_str); + if (fmt == NULL) { + PyErr_Format(PyExc_ValueError, + "_type_ '%s' not supported", proto_str); + goto error; + } + + stgdict = (StgDictObject *)_PyObject_CallNoArg( + (PyObject *)&PyCStgDict_Type); + if (!stgdict) + goto error; + + stgdict->ffi_type_pointer = *fmt->pffi_type; + stgdict->align = fmt->pffi_type->alignment; + stgdict->length = 0; + stgdict->size = fmt->pffi_type->size; + stgdict->setfunc = fmt->setfunc; + stgdict->getfunc = fmt->getfunc; +#ifdef WORDS_BIGENDIAN + stgdict->format = _ctypes_alloc_format_string_for_type(proto_str[0], 1); +#else + stgdict->format = _ctypes_alloc_format_string_for_type(proto_str[0], 0); +#endif + if (stgdict->format == NULL) { + Py_DECREF(result); + Py_DECREF(proto); + Py_DECREF((PyObject *)stgdict); + return NULL; + } + + stgdict->paramfunc = PyCSimpleType_paramfunc; +/* + if (result->tp_base != &Simple_Type) { + stgdict->setfunc = NULL; + stgdict->getfunc = NULL; + } +*/ + + /* This consumes the refcount on proto which we have */ + stgdict->proto = proto; + + /* replace the class dict by our updated spam dict */ + if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { + Py_DECREF(result); + Py_DECREF((PyObject *)stgdict); + return NULL; + } + Py_SETREF(result->tp_dict, (PyObject *)stgdict); + + /* Install from_param class methods in ctypes base classes. + Overrides the PyCSimpleType_from_param generic method. + */ + if (result->tp_base == &Simple_Type) { + switch (*proto_str) { + case 'z': /* c_char_p */ + ml = &c_char_p_method; + stgdict->flags |= TYPEFLAG_ISPOINTER; + break; + case 'Z': /* c_wchar_p */ + ml = &c_wchar_p_method; + stgdict->flags |= TYPEFLAG_ISPOINTER; + break; + case 'P': /* c_void_p */ + ml = &c_void_p_method; + stgdict->flags |= TYPEFLAG_ISPOINTER; + break; + case 's': + case 'X': + case 'O': + ml = NULL; + stgdict->flags |= TYPEFLAG_ISPOINTER; + break; + default: + ml = NULL; + break; + } + + if (ml) { + PyObject *meth; + int x; + meth = PyDescr_NewClassMethod(result, ml); + if (!meth) { + Py_DECREF(result); + return NULL; + } + x = PyDict_SetItemString(result->tp_dict, + ml->ml_name, + meth); + Py_DECREF(meth); + if (x == -1) { + Py_DECREF(result); + return NULL; + } + } + } + + if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { + PyObject *swapped = CreateSwappedType(type, args, kwds, + proto, fmt); + StgDictObject *sw_dict; + if (swapped == NULL) { + Py_DECREF(result); + return NULL; + } + sw_dict = PyType_stgdict(swapped); +#ifdef WORDS_BIGENDIAN + PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped); + PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result); + PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result); + PyObject_SetAttrString(swapped, "__ctype_le__", swapped); + /* We are creating the type for the OTHER endian */ + sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1); +#else + PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped); + PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result); + PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result); + PyObject_SetAttrString(swapped, "__ctype_be__", swapped); + /* We are creating the type for the OTHER endian */ + sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1); +#endif + Py_DECREF(swapped); + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } + }; + + return (PyObject *)result; +} + +/* + * This is a *class method*. + * Convert a parameter into something that ConvParam can handle. + */ +static PyObject * +PyCSimpleType_from_param(PyObject *type, PyObject *value) +{ + _Py_IDENTIFIER(_as_parameter_); + StgDictObject *dict; + const char *fmt; + PyCArgObject *parg; + struct fielddesc *fd; + PyObject *as_parameter; + int res; + + /* If the value is already an instance of the requested type, + we can use it as is */ + res = PyObject_IsInstance(value, type); + if (res == -1) + return NULL; + if (res) { + Py_INCREF(value); + return value; + } + + dict = PyType_stgdict(type); + if (!dict) { + PyErr_SetString(PyExc_TypeError, + "abstract class"); + return NULL; + } + + /* I think we can rely on this being a one-character string */ + fmt = PyUnicode_AsUTF8(dict->proto); + assert(fmt); + + fd = _ctypes_get_fielddesc(fmt); + assert(fd); + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + + parg->tag = fmt[0]; + parg->pffi_type = fd->pffi_type; + parg->obj = fd->setfunc(&parg->value, value, 0); + if (parg->obj) + return (PyObject *)parg; + PyErr_Clear(); + Py_DECREF(parg); + + if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { return NULL; - default: - break; - } - - if (PointerObject_Check(value) || ArrayObject_Check(value)) { - /* Array instances are also pointers when - the item types are the same. - */ - StgDictObject *v = PyObject_stgdict(value); - assert(v); /* Cannot be NULL for pointer or array objects */ - int ret = PyObject_IsSubclass(v->proto, typedict->proto); - if (ret < 0) { - return NULL; - } - if (ret) { - Py_INCREF(value); - return value; - } } - return CDataType_from_param(type, value); -} - -static PyMethodDef PyCPointerType_methods[] = { - { "from_address", CDataType_from_address, METH_O, from_address_doc }, - { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, - { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, - { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc}, - { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc}, - { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O }, - { NULL, NULL }, -}; - -PyTypeObject PyCPointerType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCPointerType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ + if (as_parameter) { + if (Py_EnterRecursiveCall("while processing _as_parameter_")) { + Py_DECREF(as_parameter); + return NULL; + } + value = PyCSimpleType_from_param(type, as_parameter); + Py_LeaveRecursiveCall(); + Py_DECREF(as_parameter); + return value; + } + PyErr_SetString(PyExc_TypeError, + "wrong type"); + return NULL; +} + +static PyMethodDef PyCSimpleType_methods[] = { + { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc }, + { "from_address", CDataType_from_address, METH_O, from_address_doc }, + { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, + { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, + { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc}, + { NULL, NULL }, +}; + +PyTypeObject PyCSimpleType_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.PyCSimpleType", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the Pointer Objects", /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PyCPointerType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCPointerType_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/******************************************************************/ -/* - PyCArrayType_Type -*/ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &CDataType_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "metatype for the PyCSimpleType Objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyCSimpleType_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyCSimpleType_new, /* tp_new */ + 0, /* tp_free */ +}; + +/******************************************************************/ +/* + PyCFuncPtrType_Type + */ + +static PyObject * +converters_from_argtypes(PyObject *ob) +{ + _Py_IDENTIFIER(from_param); + PyObject *converters; + Py_ssize_t i; + Py_ssize_t nArgs; + + ob = PySequence_Tuple(ob); /* new reference */ + if (!ob) { + PyErr_SetString(PyExc_TypeError, + "_argtypes_ must be a sequence of types"); + return NULL; + } + + nArgs = PyTuple_GET_SIZE(ob); + converters = PyTuple_New(nArgs); + if (!converters) { + Py_DECREF(ob); + return NULL; + } + + /* I have to check if this is correct. Using c_char, which has a size + of 1, will be assumed to be pushed as only one byte! + Aren't these promoted to integers by the C compiler and pushed as 4 bytes? + */ + + for (i = 0; i < nArgs; ++i) { + PyObject *cnv; + PyObject *tp = PyTuple_GET_ITEM(ob, i); /* - PyCArrayType_new ensures that the new Array subclass created has a _length_ - attribute, and a _type_ attribute. -*/ - -static int -CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) -{ - char *ptr; - Py_ssize_t size; - Py_buffer view; - - if (value == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0) - return -1; - size = view.len; - ptr = view.buf; - if (size > self->b_size) { - PyErr_SetString(PyExc_ValueError, - "byte string too long"); - goto fail; - } - - memcpy(self->b_ptr, ptr, size); - - PyBuffer_Release(&view); - return 0; - fail: - PyBuffer_Release(&view); - return -1; -} - -static PyObject * -CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored)) -{ - return PyBytes_FromStringAndSize(self->b_ptr, self->b_size); -} - -static PyObject * -CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored)) -{ - Py_ssize_t i; - char *ptr = self->b_ptr; - for (i = 0; i < self->b_size; ++i) - if (*ptr++ == '\0') - break; - return PyBytes_FromStringAndSize(self->b_ptr, i); -} - -static int -CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) -{ - const char *ptr; - Py_ssize_t size; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "can't delete attribute"); - return -1; - } - - if (!PyBytes_Check(value)) { - PyErr_Format(PyExc_TypeError, - "bytes expected instead of %s instance", - Py_TYPE(value)->tp_name); - return -1; - } else - Py_INCREF(value); - size = PyBytes_GET_SIZE(value); - if (size > self->b_size) { - PyErr_SetString(PyExc_ValueError, - "byte string too long"); - Py_DECREF(value); - return -1; - } - - ptr = PyBytes_AS_STRING(value); - memcpy(self->b_ptr, ptr, size); - if (size < self->b_size) - self->b_ptr[size] = '\0'; - Py_DECREF(value); - - return 0; -} - -static PyGetSetDef CharArray_getsets[] = { - { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw, - "value", NULL }, - { "value", (getter)CharArray_get_value, (setter)CharArray_set_value, - "string value"}, - { NULL, NULL } -}; - -#ifdef CTYPES_UNICODE -static PyObject * -WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored)) -{ - Py_ssize_t i; - wchar_t *ptr = (wchar_t *)self->b_ptr; - for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i) - if (*ptr++ == (wchar_t)0) - break; - return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i); -} - -static int -WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) -{ - Py_ssize_t result = 0; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "can't delete attribute"); - return -1; - } - if (!PyUnicode_Check(value)) { - PyErr_Format(PyExc_TypeError, - "unicode string expected instead of %s instance", - Py_TYPE(value)->tp_name); - return -1; - } else - Py_INCREF(value); - - Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0); - if (len < 0) { - return -1; - } - // PyUnicode_AsWideChar() returns number of wchars including trailing null byte, - // when it is called with NULL. - if (((size_t)len-1) > self->b_size/sizeof(wchar_t)) { - PyErr_SetString(PyExc_ValueError, "string too long"); - result = -1; - goto done; - } - result = PyUnicode_AsWideChar(value, - (wchar_t *)self->b_ptr, - self->b_size/sizeof(wchar_t)); - if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t)) - ((wchar_t *)self->b_ptr)[result] = (wchar_t)0; - done: - Py_DECREF(value); - - return result >= 0 ? 0 : -1; -} - -static PyGetSetDef WCharArray_getsets[] = { - { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value, - "string value"}, - { NULL, NULL } -}; -#endif - -/* - The next three functions copied from Python's typeobject.c. - - They are used to attach methods, members, or getsets to a type *after* it - has been created: Arrays of characters have additional getsets to treat them - as strings. - */ -/* -static int -add_methods(PyTypeObject *type, PyMethodDef *meth) -{ - PyObject *dict = type->tp_dict; - for (; meth->ml_name != NULL; meth++) { - PyObject *descr; - descr = PyDescr_NewMethod(type, meth); - if (descr == NULL) - return -1; - if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - } - return 0; -} - -static int -add_members(PyTypeObject *type, PyMemberDef *memb) -{ - PyObject *dict = type->tp_dict; - for (; memb->name != NULL; memb++) { - PyObject *descr; - descr = PyDescr_NewMember(type, memb); - if (descr == NULL) - return -1; - if (PyDict_SetItemString(dict, memb->name, descr) < 0) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - } - return 0; -} -*/ - -static int -add_getset(PyTypeObject *type, PyGetSetDef *gsp) -{ - PyObject *dict = type->tp_dict; - for (; gsp->name != NULL; gsp++) { - PyObject *descr; - descr = PyDescr_NewGetSet(type, gsp); - if (descr == NULL) - return -1; - if (PyDict_SetItemString(dict, gsp->name, descr) < 0) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - } - return 0; -} - -static PyCArgObject * -PyCArrayType_paramfunc(CDataObject *self) -{ - PyCArgObject *p = PyCArgObject_new(); - if (p == NULL) - return NULL; - p->tag = 'P'; - p->pffi_type = &ffi_type_pointer; - p->value.p = (char *)self->b_ptr; - Py_INCREF(self); - p->obj = (PyObject *)self; - return p; -} - -static PyObject * -PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - _Py_IDENTIFIER(_length_); - _Py_IDENTIFIER(_type_); - PyTypeObject *result; - StgDictObject *stgdict; - StgDictObject *itemdict; - PyObject *length_attr, *type_attr; - Py_ssize_t length; - Py_ssize_t itemsize, itemalign; - - /* create the new instance (which is a class, - since we are a metatype!) */ - result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); - if (result == NULL) - return NULL; - - /* Initialize these variables to NULL so that we can simplify error - handling by using Py_XDECREF. */ - stgdict = NULL; - type_attr = NULL; - - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__length_, &length_attr) < 0) { - goto error; - } - if (!length_attr) { - PyErr_SetString(PyExc_AttributeError, - "class must define a '_length_' attribute"); - goto error; - } - - if (!PyLong_Check(length_attr)) { - Py_DECREF(length_attr); - PyErr_SetString(PyExc_TypeError, - "The '_length_' attribute must be an integer"); - goto error; - } - - if (_PyLong_Sign(length_attr) == -1) { - Py_DECREF(length_attr); - PyErr_SetString(PyExc_ValueError, - "The '_length_' attribute must not be negative"); - goto error; - } - - length = PyLong_AsSsize_t(length_attr); - Py_DECREF(length_attr); - if (length == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - PyErr_SetString(PyExc_OverflowError, - "The '_length_' attribute is too large"); - } - goto error; - } - - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &type_attr) < 0) { - goto error; - } - if (!type_attr) { - PyErr_SetString(PyExc_AttributeError, - "class must define a '_type_' attribute"); - goto error; - } - - stgdict = (StgDictObject *)_PyObject_CallNoArg( - (PyObject *)&PyCStgDict_Type); - if (!stgdict) - goto error; - - itemdict = PyType_stgdict(type_attr); - if (!itemdict) { - PyErr_SetString(PyExc_TypeError, - "_type_ must have storage info"); - goto error; - } - - assert(itemdict->format); - stgdict->format = _ctypes_alloc_format_string(NULL, itemdict->format); - if (stgdict->format == NULL) - goto error; - stgdict->ndim = itemdict->ndim + 1; - stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t) * stgdict->ndim); - if (stgdict->shape == NULL) { - PyErr_NoMemory(); - goto error; - } - stgdict->shape[0] = length; - if (stgdict->ndim > 1) { - memmove(&stgdict->shape[1], itemdict->shape, - sizeof(Py_ssize_t) * (stgdict->ndim - 1)); - } - - itemsize = itemdict->size; - if (itemsize != 0 && length > PY_SSIZE_T_MAX / itemsize) { - PyErr_SetString(PyExc_OverflowError, - "array too large"); - goto error; - } - - itemalign = itemdict->align; - - if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) - stgdict->flags |= TYPEFLAG_HASPOINTER; - - stgdict->size = itemsize * length; - stgdict->align = itemalign; - stgdict->length = length; - stgdict->proto = type_attr; - type_attr = NULL; - - stgdict->paramfunc = &PyCArrayType_paramfunc; - - /* Arrays are passed as pointers to function calls. */ - stgdict->ffi_type_pointer = ffi_type_pointer; - - /* replace the class dict by our updated spam dict */ - if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) - goto error; - Py_SETREF(result->tp_dict, (PyObject *)stgdict); /* steal the reference */ - stgdict = NULL; - - /* Special case for character arrays. - A permanent annoyance: char arrays are also strings! - */ - if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { - if (-1 == add_getset(result, CharArray_getsets)) - goto error; -#ifdef CTYPES_UNICODE - } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { - if (-1 == add_getset(result, WCharArray_getsets)) - goto error; -#endif - } - - return (PyObject *)result; -error: - Py_XDECREF((PyObject*)stgdict); - Py_XDECREF(type_attr); - Py_DECREF(result); - return NULL; -} - -PyTypeObject PyCArrayType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCArrayType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "metatype for the Array Objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCArrayType_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/******************************************************************/ -/* - PyCSimpleType_Type -*/ -/* - -PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid -_type_ attribute. - -*/ - -static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; - -static PyObject * -c_wchar_p_from_param(PyObject *type, PyObject *value) -{ - _Py_IDENTIFIER(_as_parameter_); - PyObject *as_parameter; - int res; - if (value == Py_None) { - Py_RETURN_NONE; - } - if (PyUnicode_Check(value)) { - PyCArgObject *parg; - struct fielddesc *fd = _ctypes_get_fielddesc("Z"); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'Z'; - parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; - } - return (PyObject *)parg; - } - res = PyObject_IsInstance(value, type); - if (res == -1) - return NULL; - if (res) { - Py_INCREF(value); - return value; - } - if (ArrayObject_Check(value) || PointerObject_Check(value)) { - /* c_wchar array instance or pointer(c_wchar(...)) */ - StgDictObject *dt = PyObject_stgdict(value); - StgDictObject *dict; - assert(dt); /* Cannot be NULL for pointer or array objects */ - dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; - if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { - Py_INCREF(value); - return value; - } - } - if (PyCArg_CheckExact(value)) { - /* byref(c_char(...)) */ - PyCArgObject *a = (PyCArgObject *)value; - StgDictObject *dict = PyObject_stgdict(a->obj); - if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { - Py_INCREF(value); - return value; - } - } - - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { - return NULL; - } - if (as_parameter) { - value = c_wchar_p_from_param(type, as_parameter); - Py_DECREF(as_parameter); - return value; - } - /* XXX better message */ - PyErr_SetString(PyExc_TypeError, - "wrong type"); - return NULL; -} - -static PyObject * -c_char_p_from_param(PyObject *type, PyObject *value) -{ - _Py_IDENTIFIER(_as_parameter_); - PyObject *as_parameter; - int res; - if (value == Py_None) { - Py_RETURN_NONE; - } - if (PyBytes_Check(value)) { - PyCArgObject *parg; - struct fielddesc *fd = _ctypes_get_fielddesc("z"); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'z'; - parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; - } - return (PyObject *)parg; - } - res = PyObject_IsInstance(value, type); - if (res == -1) - return NULL; - if (res) { - Py_INCREF(value); - return value; - } - if (ArrayObject_Check(value) || PointerObject_Check(value)) { - /* c_char array instance or pointer(c_char(...)) */ - StgDictObject *dt = PyObject_stgdict(value); - StgDictObject *dict; - assert(dt); /* Cannot be NULL for pointer or array objects */ - dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; - if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { - Py_INCREF(value); - return value; - } - } - if (PyCArg_CheckExact(value)) { - /* byref(c_char(...)) */ - PyCArgObject *a = (PyCArgObject *)value; - StgDictObject *dict = PyObject_stgdict(a->obj); - if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { - Py_INCREF(value); - return value; - } - } - - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { - return NULL; - } - if (as_parameter) { - value = c_char_p_from_param(type, as_parameter); - Py_DECREF(as_parameter); - return value; - } - /* XXX better message */ - PyErr_SetString(PyExc_TypeError, - "wrong type"); - return NULL; -} - -static PyObject * -c_void_p_from_param(PyObject *type, PyObject *value) -{ - _Py_IDENTIFIER(_as_parameter_); - StgDictObject *stgd; - PyObject *as_parameter; - int res; - -/* None */ - if (value == Py_None) { - Py_RETURN_NONE; - } - /* Should probably allow buffer interface as well */ -/* int, long */ - if (PyLong_Check(value)) { - PyCArgObject *parg; - struct fielddesc *fd = _ctypes_get_fielddesc("P"); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'P'; - parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; - } - return (PyObject *)parg; - } - /* XXX struni: remove later */ -/* bytes */ - if (PyBytes_Check(value)) { - PyCArgObject *parg; - struct fielddesc *fd = _ctypes_get_fielddesc("z"); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'z'; - parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; - } - return (PyObject *)parg; - } -/* unicode */ - if (PyUnicode_Check(value)) { - PyCArgObject *parg; - struct fielddesc *fd = _ctypes_get_fielddesc("Z"); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'Z'; - parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; - } - return (PyObject *)parg; - } -/* c_void_p instance (or subclass) */ - res = PyObject_IsInstance(value, type); - if (res == -1) - return NULL; - if (res) { - /* c_void_p instances */ - Py_INCREF(value); - return value; - } -/* ctypes array or pointer instance */ - if (ArrayObject_Check(value) || PointerObject_Check(value)) { - /* Any array or pointer is accepted */ - Py_INCREF(value); - return value; - } -/* byref(...) */ - if (PyCArg_CheckExact(value)) { - /* byref(c_xxx()) */ - PyCArgObject *a = (PyCArgObject *)value; - if (a->tag == 'P') { - Py_INCREF(value); - return value; - } - } -/* function pointer */ - if (PyCFuncPtrObject_Check(value)) { - PyCArgObject *parg; - PyCFuncPtrObject *func; - func = (PyCFuncPtrObject *)value; - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'P'; - Py_INCREF(value); - parg->value.p = *(void **)func->b_ptr; - parg->obj = value; - return (PyObject *)parg; - } -/* c_char_p, c_wchar_p */ - stgd = PyObject_stgdict(value); - if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)) { - PyCArgObject *parg; - - switch (PyUnicode_AsUTF8(stgd->proto)[0]) { - case 'z': /* c_char_p */ - case 'Z': /* c_wchar_p */ - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'Z'; - Py_INCREF(value); - parg->obj = value; - /* Remember: b_ptr points to where the pointer is stored! */ - parg->value.p = *(void **)(((CDataObject *)value)->b_ptr); - return (PyObject *)parg; - } - } - - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { - return NULL; - } - if (as_parameter) { - value = c_void_p_from_param(type, as_parameter); - Py_DECREF(as_parameter); - return value; - } - /* XXX better message */ - PyErr_SetString(PyExc_TypeError, - "wrong type"); - return NULL; -} - -static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O }; -static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O }; -static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O }; - -static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds, - PyObject *proto, struct fielddesc *fmt) -{ - PyTypeObject *result; - StgDictObject *stgdict; - PyObject *name = PyTuple_GET_ITEM(args, 0); - PyObject *newname; - PyObject *swapped_args; - static PyObject *suffix; - Py_ssize_t i; - - swapped_args = PyTuple_New(PyTuple_GET_SIZE(args)); - if (!swapped_args) - return NULL; - - if (suffix == NULL) -#ifdef WORDS_BIGENDIAN - suffix = PyUnicode_InternFromString("_le"); -#else - suffix = PyUnicode_InternFromString("_be"); -#endif - if (suffix == NULL) { - Py_DECREF(swapped_args); - return NULL; - } - - newname = PyUnicode_Concat(name, suffix); - if (newname == NULL) { - Py_DECREF(swapped_args); - return NULL; - } - - PyTuple_SET_ITEM(swapped_args, 0, newname); - for (i=1; iffi_type_pointer = *fmt->pffi_type; - stgdict->align = fmt->pffi_type->alignment; - stgdict->length = 0; - stgdict->size = fmt->pffi_type->size; - stgdict->setfunc = fmt->setfunc_swapped; - stgdict->getfunc = fmt->getfunc_swapped; - - Py_INCREF(proto); - stgdict->proto = proto; - - /* replace the class dict by our updated spam dict */ - if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { - Py_DECREF(result); - Py_DECREF((PyObject *)stgdict); - return NULL; - } - Py_SETREF(result->tp_dict, (PyObject *)stgdict); - - return (PyObject *)result; -} - -static PyCArgObject * -PyCSimpleType_paramfunc(CDataObject *self) -{ - StgDictObject *dict; - const char *fmt; - PyCArgObject *parg; - struct fielddesc *fd; - - dict = PyObject_stgdict((PyObject *)self); - assert(dict); /* Cannot be NULL for CDataObject instances */ - fmt = PyUnicode_AsUTF8(dict->proto); - assert(fmt); - - fd = _ctypes_get_fielddesc(fmt); - assert(fd); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - - parg->tag = fmt[0]; - parg->pffi_type = fd->pffi_type; - Py_INCREF(self); - parg->obj = (PyObject *)self; - memcpy(&parg->value, self->b_ptr, self->b_size); - return parg; -} - -static PyObject * -PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - _Py_IDENTIFIER(_type_); - PyTypeObject *result; - StgDictObject *stgdict; - PyObject *proto; - const char *proto_str; - Py_ssize_t proto_len; - PyMethodDef *ml; - struct fielddesc *fmt; - - /* create the new instance (which is a class, - since we are a metatype!) */ - result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); - if (result == NULL) - return NULL; - - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &proto) < 0) { - return NULL; - } - if (!proto) { - PyErr_SetString(PyExc_AttributeError, - "class must define a '_type_' attribute"); - error: - Py_XDECREF(proto); - Py_DECREF(result); - return NULL; - } - if (PyUnicode_Check(proto)) { - proto_str = PyUnicode_AsUTF8AndSize(proto, &proto_len); - if (!proto_str) - goto error; - } else { - PyErr_SetString(PyExc_TypeError, - "class must define a '_type_' string attribute"); - goto error; - } - if (proto_len != 1) { - PyErr_SetString(PyExc_ValueError, - "class must define a '_type_' attribute " - "which must be a string of length 1"); - goto error; - } - if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) { - PyErr_Format(PyExc_AttributeError, - "class must define a '_type_' attribute which must be\n" - "a single character string containing one of '%s'.", - SIMPLE_TYPE_CHARS); - goto error; - } - fmt = _ctypes_get_fielddesc(proto_str); - if (fmt == NULL) { - PyErr_Format(PyExc_ValueError, - "_type_ '%s' not supported", proto_str); - goto error; - } - - stgdict = (StgDictObject *)_PyObject_CallNoArg( - (PyObject *)&PyCStgDict_Type); - if (!stgdict) - goto error; - - stgdict->ffi_type_pointer = *fmt->pffi_type; - stgdict->align = fmt->pffi_type->alignment; - stgdict->length = 0; - stgdict->size = fmt->pffi_type->size; - stgdict->setfunc = fmt->setfunc; - stgdict->getfunc = fmt->getfunc; -#ifdef WORDS_BIGENDIAN - stgdict->format = _ctypes_alloc_format_string_for_type(proto_str[0], 1); -#else - stgdict->format = _ctypes_alloc_format_string_for_type(proto_str[0], 0); -#endif - if (stgdict->format == NULL) { - Py_DECREF(result); - Py_DECREF(proto); - Py_DECREF((PyObject *)stgdict); - return NULL; - } - - stgdict->paramfunc = PyCSimpleType_paramfunc; -/* - if (result->tp_base != &Simple_Type) { - stgdict->setfunc = NULL; - stgdict->getfunc = NULL; - } -*/ - - /* This consumes the refcount on proto which we have */ - stgdict->proto = proto; - - /* replace the class dict by our updated spam dict */ - if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { - Py_DECREF(result); - Py_DECREF((PyObject *)stgdict); - return NULL; - } - Py_SETREF(result->tp_dict, (PyObject *)stgdict); - - /* Install from_param class methods in ctypes base classes. - Overrides the PyCSimpleType_from_param generic method. - */ - if (result->tp_base == &Simple_Type) { - switch (*proto_str) { - case 'z': /* c_char_p */ - ml = &c_char_p_method; - stgdict->flags |= TYPEFLAG_ISPOINTER; - break; - case 'Z': /* c_wchar_p */ - ml = &c_wchar_p_method; - stgdict->flags |= TYPEFLAG_ISPOINTER; - break; - case 'P': /* c_void_p */ - ml = &c_void_p_method; - stgdict->flags |= TYPEFLAG_ISPOINTER; - break; - case 's': - case 'X': - case 'O': - ml = NULL; - stgdict->flags |= TYPEFLAG_ISPOINTER; - break; - default: - ml = NULL; - break; - } - - if (ml) { - PyObject *meth; - int x; - meth = PyDescr_NewClassMethod(result, ml); - if (!meth) { - Py_DECREF(result); - return NULL; - } - x = PyDict_SetItemString(result->tp_dict, - ml->ml_name, - meth); - Py_DECREF(meth); - if (x == -1) { - Py_DECREF(result); - return NULL; - } - } - } - - if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { - PyObject *swapped = CreateSwappedType(type, args, kwds, - proto, fmt); - StgDictObject *sw_dict; - if (swapped == NULL) { - Py_DECREF(result); - return NULL; - } - sw_dict = PyType_stgdict(swapped); -#ifdef WORDS_BIGENDIAN - PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped); - PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result); - PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result); - PyObject_SetAttrString(swapped, "__ctype_le__", swapped); - /* We are creating the type for the OTHER endian */ - sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1); -#else - PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped); - PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result); - PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result); - PyObject_SetAttrString(swapped, "__ctype_be__", swapped); - /* We are creating the type for the OTHER endian */ - sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1); -#endif - Py_DECREF(swapped); - if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } - }; - - return (PyObject *)result; -} - -/* - * This is a *class method*. - * Convert a parameter into something that ConvParam can handle. - */ -static PyObject * -PyCSimpleType_from_param(PyObject *type, PyObject *value) -{ - _Py_IDENTIFIER(_as_parameter_); - StgDictObject *dict; - const char *fmt; - PyCArgObject *parg; - struct fielddesc *fd; - PyObject *as_parameter; - int res; - - /* If the value is already an instance of the requested type, - we can use it as is */ - res = PyObject_IsInstance(value, type); - if (res == -1) - return NULL; - if (res) { - Py_INCREF(value); - return value; - } - - dict = PyType_stgdict(type); - if (!dict) { - PyErr_SetString(PyExc_TypeError, - "abstract class"); - return NULL; - } - - /* I think we can rely on this being a one-character string */ - fmt = PyUnicode_AsUTF8(dict->proto); - assert(fmt); - - fd = _ctypes_get_fielddesc(fmt); - assert(fd); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - - parg->tag = fmt[0]; - parg->pffi_type = fd->pffi_type; - parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj) - return (PyObject *)parg; - PyErr_Clear(); - Py_DECREF(parg); - - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { - return NULL; - } - if (as_parameter) { - if (Py_EnterRecursiveCall("while processing _as_parameter_")) { - Py_DECREF(as_parameter); - return NULL; - } - value = PyCSimpleType_from_param(type, as_parameter); - Py_LeaveRecursiveCall(); - Py_DECREF(as_parameter); - return value; - } - PyErr_SetString(PyExc_TypeError, - "wrong type"); - return NULL; -} - -static PyMethodDef PyCSimpleType_methods[] = { - { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc }, - { "from_address", CDataType_from_address, METH_O, from_address_doc }, - { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, - { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, - { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc}, - { NULL, NULL }, -}; - -PyTypeObject PyCSimpleType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCSimpleType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "metatype for the PyCSimpleType Objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PyCSimpleType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCSimpleType_new, /* tp_new */ - 0, /* tp_free */ -}; - -/******************************************************************/ -/* - PyCFuncPtrType_Type - */ - -static PyObject * -converters_from_argtypes(PyObject *ob) -{ - _Py_IDENTIFIER(from_param); - PyObject *converters; - Py_ssize_t i; - Py_ssize_t nArgs; - - ob = PySequence_Tuple(ob); /* new reference */ - if (!ob) { - PyErr_SetString(PyExc_TypeError, - "_argtypes_ must be a sequence of types"); - return NULL; - } - - nArgs = PyTuple_GET_SIZE(ob); - converters = PyTuple_New(nArgs); - if (!converters) { - Py_DECREF(ob); - return NULL; - } - - /* I have to check if this is correct. Using c_char, which has a size - of 1, will be assumed to be pushed as only one byte! - Aren't these promoted to integers by the C compiler and pushed as 4 bytes? - */ - - for (i = 0; i < nArgs; ++i) { - PyObject *cnv; - PyObject *tp = PyTuple_GET_ITEM(ob, i); -/* - * The following checks, relating to bpo-16575 and bpo-16576, have been - * disabled. The reason is that, although there is a definite problem with - * how libffi handles unions (https://github.com/libffi/libffi/issues/33), - * there are numerous libraries which pass structures containing unions - * by values - especially on Windows but examples also exist on Linux - * (https://bugs.python.org/msg359834). - * - * It may not be possible to get proper support for unions and bitfields - * until support is forthcoming in libffi, but for now, adding the checks - * has caused problems in otherwise-working software, which suggests it - * is better to disable the checks. - * - * Although specific examples reported relate specifically to unions and - * not bitfields, the bitfields check is also being disabled as a - * precaution. - - StgDictObject *stgdict = PyType_stgdict(tp); - - if (stgdict != NULL) { - if (stgdict->flags & TYPEFLAG_HASUNION) { - Py_DECREF(converters); - Py_DECREF(ob); - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "item %zd in _argtypes_ passes a union by " - "value, which is unsupported.", - i + 1); - } - return NULL; - } - if (stgdict->flags & TYPEFLAG_HASBITFIELD) { - Py_DECREF(converters); - Py_DECREF(ob); - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "item %zd in _argtypes_ passes a struct/" - "union with a bitfield by value, which is " - "unsupported.", - i + 1); - } - return NULL; - } - } - */ - - if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) { - Py_DECREF(converters); - Py_DECREF(ob); - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_TypeError, - "item %zd in _argtypes_ has no from_param method", - i+1); - } - return NULL; - } - PyTuple_SET_ITEM(converters, i, cnv); - } - Py_DECREF(ob); - return converters; -} - -static int -make_funcptrtype_dict(StgDictObject *stgdict) -{ - PyObject *ob; - PyObject *converters = NULL; - _Py_IDENTIFIER(_flags_); - _Py_IDENTIFIER(_argtypes_); - _Py_IDENTIFIER(_restype_); - _Py_IDENTIFIER(_check_retval_); - - stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; - stgdict->length = 1; - stgdict->size = sizeof(void *); - stgdict->setfunc = NULL; - stgdict->getfunc = NULL; - stgdict->ffi_type_pointer = ffi_type_pointer; - - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_); - if (!ob || !PyLong_Check(ob)) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "class must define _flags_ which must be an integer"); - } - return -1; - } - stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER; - - /* _argtypes_ is optional... */ - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_); - if (ob) { - converters = converters_from_argtypes(ob); - if (!converters) - return -1; - Py_INCREF(ob); - stgdict->argtypes = ob; - stgdict->converters = converters; - } - else if (PyErr_Occurred()) { - return -1; - } - - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_); - if (ob) { - if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { - PyErr_SetString(PyExc_TypeError, - "_restype_ must be a type, a callable, or None"); - return -1; - } - Py_INCREF(ob); - stgdict->restype = ob; - if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, - &stgdict->checker) < 0) - { - return -1; - } - } - else if (PyErr_Occurred()) { - return -1; - } -/* XXX later, maybe. - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_); - if (ob) { - if (!PyCallable_Check(ob)) { - PyErr_SetString(PyExc_TypeError, - "_errcheck_ must be callable"); - return -1; - } - Py_INCREF(ob); - stgdict->errcheck = ob; - } - else if (PyErr_Occurred()) { - return -1; - } -*/ - return 0; -} - -static PyCArgObject * -PyCFuncPtrType_paramfunc(CDataObject *self) -{ - PyCArgObject *parg; - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - - parg->tag = 'P'; - parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; - parg->value.p = *(void **)self->b_ptr; - return parg; -} - -static PyObject * -PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyTypeObject *result; - StgDictObject *stgdict; - - stgdict = (StgDictObject *)_PyObject_CallNoArg( - (PyObject *)&PyCStgDict_Type); - if (!stgdict) - return NULL; - - stgdict->paramfunc = PyCFuncPtrType_paramfunc; - /* We do NOT expose the function signature in the format string. It - is impossible, generally, because the only requirement for the - argtypes items is that they have a .from_param method - we do not - know the types of the arguments (although, in practice, most - argtypes would be a ctypes type). - */ - stgdict->format = _ctypes_alloc_format_string(NULL, "X{}"); - if (stgdict->format == NULL) { - Py_DECREF((PyObject *)stgdict); - return NULL; - } - stgdict->flags |= TYPEFLAG_ISPOINTER; - - /* create the new instance (which is a class, - since we are a metatype!) */ - result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); - if (result == NULL) { - Py_DECREF((PyObject *)stgdict); - return NULL; - } - - /* replace the class dict by our updated storage dict */ - if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { - Py_DECREF(result); - Py_DECREF((PyObject *)stgdict); - return NULL; - } - Py_SETREF(result->tp_dict, (PyObject *)stgdict); - - if (-1 == make_funcptrtype_dict(stgdict)) { - Py_DECREF(result); - return NULL; - } - - return (PyObject *)result; -} - -PyTypeObject PyCFuncPtrType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCFuncPtrType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for C function pointers", /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCFuncPtrType_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/***************************************************************** - * Code to keep needed objects alive - */ - -static CDataObject * -PyCData_GetContainer(CDataObject *self) -{ - while (self->b_base) - self = self->b_base; - if (self->b_objects == NULL) { - if (self->b_length) { - self->b_objects = PyDict_New(); - if (self->b_objects == NULL) - return NULL; - } else { - Py_INCREF(Py_None); - self->b_objects = Py_None; - } - } - return self; -} - -static PyObject * -GetKeepedObjects(CDataObject *target) -{ - CDataObject *container; - container = PyCData_GetContainer(target); - if (container == NULL) - return NULL; - return container->b_objects; -} - -static PyObject * -unique_key(CDataObject *target, Py_ssize_t index) -{ - char string[256]; - char *cp = string; - size_t bytes_left; - - Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2); - cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int)); - while (target->b_base) { - bytes_left = sizeof(string) - (cp - string) - 1; - /* Hex format needs 2 characters per byte */ - if (bytes_left < sizeof(Py_ssize_t) * 2) { - PyErr_SetString(PyExc_ValueError, - "ctypes object structure too deep"); - return NULL; - } - cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int)); - target = target->b_base; - } - return PyUnicode_FromStringAndSize(string, cp-string); -} - -/* - * Keep a reference to 'keep' in the 'target', at index 'index'. - * - * If 'keep' is None, do nothing. - * - * Otherwise create a dictionary (if it does not yet exist) id the root - * objects 'b_objects' item, which will store the 'keep' object under a unique - * key. - * - * The unique_key helper travels the target's b_base pointer down to the root, - * building a string containing hex-formatted indexes found during traversal, - * separated by colons. - * - * The index tuple is used as a key into the root object's b_objects dict. - * - * Note: This function steals a refcount of the third argument, even if it - * fails! - */ -static int -KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep) -{ - int result; - CDataObject *ob; - PyObject *key; - -/* Optimization: no need to store None */ - if (keep == Py_None) { - Py_DECREF(Py_None); - return 0; - } - ob = PyCData_GetContainer(target); - if (ob == NULL) { - Py_DECREF(keep); - return -1; - } - if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) { - Py_XSETREF(ob->b_objects, keep); /* refcount consumed */ - return 0; - } - key = unique_key(target, index); - if (key == NULL) { - Py_DECREF(keep); - return -1; - } - result = PyDict_SetItem(ob->b_objects, key, keep); - Py_DECREF(key); - Py_DECREF(keep); - return result; -} - -/******************************************************************/ -/* - PyCData_Type - */ -static int -PyCData_traverse(CDataObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->b_objects); - Py_VISIT((PyObject *)self->b_base); - return 0; -} - -static int -PyCData_clear(CDataObject *self) -{ - Py_CLEAR(self->b_objects); - if ((self->b_needsfree) - && _CDataObject_HasExternalBuffer(self)) - PyMem_Free(self->b_ptr); - self->b_ptr = NULL; - Py_CLEAR(self->b_base); - return 0; -} - -static void -PyCData_dealloc(PyObject *self) -{ - PyCData_clear((CDataObject *)self); - Py_TYPE(self)->tp_free(self); -} - -static PyMemberDef PyCData_members[] = { - { "_b_base_", T_OBJECT, - offsetof(CDataObject, b_base), READONLY, - "the base object" }, - { "_b_needsfree_", T_INT, - offsetof(CDataObject, b_needsfree), READONLY, - "whether the object owns the memory or not" }, - { "_objects", T_OBJECT, - offsetof(CDataObject, b_objects), READONLY, - "internal objects tree (NEVER CHANGE THIS OBJECT!)"}, - { NULL }, -}; - -static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags) -{ - CDataObject *self = (CDataObject *)myself; - StgDictObject *dict = PyObject_stgdict(myself); - Py_ssize_t i; - - if (view == NULL) return 0; - - view->buf = self->b_ptr; - view->obj = myself; - Py_INCREF(myself); - view->len = self->b_size; - view->readonly = 0; - /* use default format character if not set */ - view->format = dict->format ? dict->format : "B"; - view->ndim = dict->ndim; - view->shape = dict->shape; - view->itemsize = self->b_size; - if (view->itemsize) { - for (i = 0; i < view->ndim; ++i) { - view->itemsize /= dict->shape[i]; - } - } - view->strides = NULL; - view->suboffsets = NULL; - view->internal = NULL; - return 0; -} - -static PyBufferProcs PyCData_as_buffer = { - PyCData_NewGetBuffer, - NULL, -}; - -/* - * CData objects are mutable, so they cannot be hashable! - */ -static Py_hash_t -PyCData_nohash(PyObject *self) -{ - PyErr_SetString(PyExc_TypeError, "unhashable type"); - return -1; -} - -static PyObject * -PyCData_reduce(PyObject *myself, PyObject *args) -{ - CDataObject *self = (CDataObject *)myself; - - if (PyObject_stgdict(myself)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) { - PyErr_SetString(PyExc_ValueError, - "ctypes objects containing pointers cannot be pickled"); - return NULL; - } - PyObject *dict = PyObject_GetAttrString(myself, "__dict__"); - if (dict == NULL) { - return NULL; - } - return Py_BuildValue("O(O(NN))", _unpickle, Py_TYPE(myself), dict, - PyBytes_FromStringAndSize(self->b_ptr, self->b_size)); -} - -static PyObject * -PyCData_setstate(PyObject *myself, PyObject *args) -{ - void *data; - Py_ssize_t len; - int res; - PyObject *dict, *mydict; - CDataObject *self = (CDataObject *)myself; - if (!PyArg_ParseTuple(args, "O!s#", - &PyDict_Type, &dict, &data, &len)) - { - return NULL; - } - if (len > self->b_size) - len = self->b_size; - memmove(self->b_ptr, data, len); - mydict = PyObject_GetAttrString(myself, "__dict__"); - if (mydict == NULL) { - return NULL; - } - if (!PyDict_Check(mydict)) { - PyErr_Format(PyExc_TypeError, - "%.200s.__dict__ must be a dictionary, not %.200s", - Py_TYPE(myself)->tp_name, Py_TYPE(mydict)->tp_name); - Py_DECREF(mydict); - return NULL; - } - res = PyDict_Update(mydict, dict); - Py_DECREF(mydict); - if (res == -1) - return NULL; - Py_RETURN_NONE; -} - -/* - * default __ctypes_from_outparam__ method returns self. - */ -static PyObject * -PyCData_from_outparam(PyObject *self, PyObject *args) -{ - Py_INCREF(self); - return self; -} - -static PyMethodDef PyCData_methods[] = { - { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, }, - { "__reduce__", PyCData_reduce, METH_NOARGS, }, - { "__setstate__", PyCData_setstate, METH_VARARGS, }, - { NULL, NULL }, -}; - -PyTypeObject PyCData_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes._CData", - sizeof(CDataObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - PyCData_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyCData_nohash, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ - (traverseproc)PyCData_traverse, /* tp_traverse */ - (inquiry)PyCData_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PyCData_methods, /* tp_methods */ - PyCData_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ -}; - -static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict) -{ - if ((size_t)dict->size <= sizeof(obj->b_value)) { - /* No need to call malloc, can use the default buffer */ - obj->b_ptr = (char *)&obj->b_value; - /* The b_needsfree flag does not mean that we actually did - call PyMem_Malloc to allocate the memory block; instead it - means we are the *owner* of the memory and are responsible - for freeing resources associated with the memory. This is - also the reason that b_needsfree is exposed to Python. - */ - obj->b_needsfree = 1; - } else { - /* In python 2.4, and ctypes 0.9.6, the malloc call took about - 33% of the creation time for c_int(). - */ - obj->b_ptr = (char *)PyMem_Malloc(dict->size); - if (obj->b_ptr == NULL) { - PyErr_NoMemory(); - return -1; - } - obj->b_needsfree = 1; - memset(obj->b_ptr, 0, dict->size); - } - obj->b_size = dict->size; - return 0; -} - -PyObject * -PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr) -{ - CDataObject *cmem; - StgDictObject *dict; - - assert(PyType_Check(type)); - dict = PyType_stgdict(type); - if (!dict) { - PyErr_SetString(PyExc_TypeError, - "abstract class"); - return NULL; - } - dict->flags |= DICTFLAG_FINAL; - cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0); - if (cmem == NULL) - return NULL; - assert(CDataObject_Check(cmem)); - - cmem->b_length = dict->length; - cmem->b_size = dict->size; - if (base) { /* use base's buffer */ - assert(CDataObject_Check(base)); - cmem->b_ptr = adr; - cmem->b_needsfree = 0; - Py_INCREF(base); - cmem->b_base = (CDataObject *)base; - cmem->b_index = index; - } else { /* copy contents of adr */ - if (-1 == PyCData_MallocBuffer(cmem, dict)) { - Py_DECREF(cmem); - return NULL; - } - memcpy(cmem->b_ptr, adr, dict->size); - cmem->b_index = index; - } - return (PyObject *)cmem; -} - -/* - Box a memory block into a CData instance. -*/ -PyObject * -PyCData_AtAddress(PyObject *type, void *buf) -{ - CDataObject *pd; - StgDictObject *dict; - - if (PySys_Audit("ctypes.cdata", "n", (Py_ssize_t)buf) < 0) { - return NULL; - } - - assert(PyType_Check(type)); - dict = PyType_stgdict(type); - if (!dict) { - PyErr_SetString(PyExc_TypeError, - "abstract class"); - return NULL; - } - dict->flags |= DICTFLAG_FINAL; - - pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0); - if (!pd) - return NULL; - assert(CDataObject_Check(pd)); - pd->b_ptr = (char *)buf; - pd->b_length = dict->length; - pd->b_size = dict->size; - return (PyObject *)pd; -} - -/* - This function returns TRUE for c_int, c_void_p, and these kind of - classes. FALSE otherwise FALSE also for subclasses of c_int and - such. -*/ -int _ctypes_simple_instance(PyObject *obj) -{ - PyTypeObject *type = (PyTypeObject *)obj; - - if (PyCSimpleTypeObject_Check(type)) - return type->tp_base != &Simple_Type; - return 0; -} - -PyObject * -PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, - Py_ssize_t index, Py_ssize_t size, char *adr) -{ - StgDictObject *dict; - if (getfunc) - return getfunc(adr, size); - assert(type); - dict = PyType_stgdict(type); - if (dict && dict->getfunc && !_ctypes_simple_instance(type)) - return dict->getfunc(adr, size); - return PyCData_FromBaseObj(type, src, index, adr); -} - -/* - Helper function for PyCData_set below. -*/ -static PyObject * -_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, - Py_ssize_t size, char *ptr) -{ - CDataObject *src; - int err; - - if (setfunc) - return setfunc(ptr, value, size); - - if (!CDataObject_Check(value)) { - StgDictObject *dict = PyType_stgdict(type); - if (dict && dict->setfunc) - return dict->setfunc(ptr, value, size); - /* - If value is a tuple, we try to call the type with the tuple - and use the result! - */ - assert(PyType_Check(type)); - if (PyTuple_Check(value)) { - PyObject *ob; - PyObject *result; - ob = PyObject_CallObject(type, value); - if (ob == NULL) { - _ctypes_extend_error(PyExc_RuntimeError, "(%s) ", - ((PyTypeObject *)type)->tp_name); - return NULL; - } - result = _PyCData_set(dst, type, setfunc, ob, - size, ptr); - Py_DECREF(ob); - return result; - } else if (value == Py_None && PyCPointerTypeObject_Check(type)) { - *(void **)ptr = NULL; - Py_RETURN_NONE; - } else { - PyErr_Format(PyExc_TypeError, - "expected %s instance, got %s", - ((PyTypeObject *)type)->tp_name, - Py_TYPE(value)->tp_name); - return NULL; - } - } - src = (CDataObject *)value; - - err = PyObject_IsInstance(value, type); - if (err == -1) - return NULL; - if (err) { - memcpy(ptr, - src->b_ptr, - size); - - if (PyCPointerTypeObject_Check(type)) { - /* XXX */ - } - - value = GetKeepedObjects(src); - if (value == NULL) - return NULL; - - Py_INCREF(value); - return value; - } - - if (PyCPointerTypeObject_Check(type) - && ArrayObject_Check(value)) { - StgDictObject *p1, *p2; - PyObject *keep; - p1 = PyObject_stgdict(value); - assert(p1); /* Cannot be NULL for array instances */ - p2 = PyType_stgdict(type); - assert(p2); /* Cannot be NULL for pointer types */ - - if (p1->proto != p2->proto) { - PyErr_Format(PyExc_TypeError, - "incompatible types, %s instance instead of %s instance", - Py_TYPE(value)->tp_name, - ((PyTypeObject *)type)->tp_name); - return NULL; - } - *(void **)ptr = src->b_ptr; - - keep = GetKeepedObjects(src); - if (keep == NULL) - return NULL; - - /* - We are assigning an array object to a field which represents - a pointer. This has the same effect as converting an array - into a pointer. So, again, we have to keep the whole object - pointed to (which is the array in this case) alive, and not - only it's object list. So we create a tuple, containing - b_objects list PLUS the array itself, and return that! - */ - return PyTuple_Pack(2, keep, value); - } - PyErr_Format(PyExc_TypeError, - "incompatible types, %s instance instead of %s instance", - Py_TYPE(value)->tp_name, - ((PyTypeObject *)type)->tp_name); - return NULL; -} - -/* - * Set a slice in object 'dst', which has the type 'type', - * to the value 'value'. - */ -int -PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, - Py_ssize_t index, Py_ssize_t size, char *ptr) -{ - CDataObject *mem = (CDataObject *)dst; - PyObject *result; - - if (!CDataObject_Check(dst)) { - PyErr_SetString(PyExc_TypeError, - "not a ctype instance"); - return -1; - } - - result = _PyCData_set(mem, type, setfunc, value, - size, ptr); - if (result == NULL) - return -1; - - /* KeepRef steals a refcount from it's last argument */ - /* If KeepRef fails, we are stumped. The dst memory block has already - been changed */ - return KeepRef(mem, index, result); -} - - -/******************************************************************/ -static PyObject * -GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - CDataObject *obj; - StgDictObject *dict; - - dict = PyType_stgdict((PyObject *)type); - if (!dict) { - PyErr_SetString(PyExc_TypeError, - "abstract class"); - return NULL; - } - dict->flags |= DICTFLAG_FINAL; - - obj = (CDataObject *)type->tp_alloc(type, 0); - if (!obj) - return NULL; - - obj->b_base = NULL; - obj->b_index = 0; - obj->b_objects = NULL; - obj->b_length = dict->length; - - if (-1 == PyCData_MallocBuffer(obj, dict)) { - Py_DECREF(obj); - return NULL; - } - return (PyObject *)obj; -} -/*****************************************************************/ -/* - PyCFuncPtr_Type -*/ - -static int -PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) -{ - if (ob && !PyCallable_Check(ob)) { - PyErr_SetString(PyExc_TypeError, - "the errcheck attribute must be callable"); - return -1; - } - Py_XINCREF(ob); - Py_XSETREF(self->errcheck, ob); - return 0; -} - -static PyObject * -PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) -{ - if (self->errcheck) { - Py_INCREF(self->errcheck); - return self->errcheck; - } - Py_RETURN_NONE; -} - -static int -PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) -{ - _Py_IDENTIFIER(_check_retval_); - PyObject *checker, *oldchecker; - if (ob == NULL) { - oldchecker = self->checker; - self->checker = NULL; - Py_CLEAR(self->restype); - Py_XDECREF(oldchecker); - return 0; - } - if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { - PyErr_SetString(PyExc_TypeError, - "restype must be a type, a callable, or None"); - return -1; - } - if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, &checker) < 0) { - return -1; - } - oldchecker = self->checker; - self->checker = checker; - Py_INCREF(ob); - Py_XSETREF(self->restype, ob); - Py_XDECREF(oldchecker); - return 0; -} - -static PyObject * -PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) -{ - StgDictObject *dict; - if (self->restype) { - Py_INCREF(self->restype); - return self->restype; - } - dict = PyObject_stgdict((PyObject *)self); - assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ - if (dict->restype) { - Py_INCREF(dict->restype); - return dict->restype; - } else { - Py_RETURN_NONE; - } -} - -static int -PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) -{ - PyObject *converters; - - if (ob == NULL || ob == Py_None) { - Py_CLEAR(self->converters); - Py_CLEAR(self->argtypes); - } else { - converters = converters_from_argtypes(ob); - if (!converters) - return -1; - Py_XSETREF(self->converters, converters); - Py_INCREF(ob); - Py_XSETREF(self->argtypes, ob); - } - return 0; -} - -static PyObject * -PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) -{ - StgDictObject *dict; - if (self->argtypes) { - Py_INCREF(self->argtypes); - return self->argtypes; - } - dict = PyObject_stgdict((PyObject *)self); - assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ - if (dict->argtypes) { - Py_INCREF(dict->argtypes); - return dict->argtypes; - } else { - Py_RETURN_NONE; - } -} - -static PyGetSetDef PyCFuncPtr_getsets[] = { - { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck, - "a function to check for errors", NULL }, - { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype, - "specify the result type", NULL }, - { "argtypes", (getter)PyCFuncPtr_get_argtypes, - (setter)PyCFuncPtr_set_argtypes, - "specify the argument types", NULL }, - { NULL, NULL } -}; - -#ifdef MS_WIN32 -static PPROC FindAddress(void *handle, const char *name, PyObject *type) -{ - PPROC address; -#ifdef MS_WIN64 - /* win64 has no stdcall calling conv, so it should - also not have the name mangling of it. - */ - Py_BEGIN_ALLOW_THREADS - address = (PPROC)GetProcAddress(handle, name); - Py_END_ALLOW_THREADS - return address; -#else - char *mangled_name; - int i; - StgDictObject *dict; - - Py_BEGIN_ALLOW_THREADS - address = (PPROC)GetProcAddress(handle, name); - Py_END_ALLOW_THREADS - if (address) - return address; - if (((size_t)name & ~0xFFFF) == 0) { - return NULL; - } - - dict = PyType_stgdict((PyObject *)type); - /* It should not happen that dict is NULL, but better be safe */ - if (dict==NULL || dict->flags & FUNCFLAG_CDECL) - return address; - - /* for stdcall, try mangled names: - funcname -> _funcname@ - where n is 0, 4, 8, 12, ..., 128 - */ - mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */ - if (!mangled_name) - return NULL; - for (i = 0; i < 32; ++i) { - sprintf(mangled_name, "_%s@%d", name, i*4); - Py_BEGIN_ALLOW_THREADS - address = (PPROC)GetProcAddress(handle, mangled_name); - Py_END_ALLOW_THREADS - if (address) - return address; - } - return NULL; -#endif -} -#endif - -/* Return 1 if usable, 0 else and exception set. */ -static int -_check_outarg_type(PyObject *arg, Py_ssize_t index) -{ - StgDictObject *dict; - - if (PyCPointerTypeObject_Check(arg)) - return 1; - - if (PyCArrayTypeObject_Check(arg)) - return 1; - - dict = PyType_stgdict(arg); - if (dict - /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */ - && PyUnicode_Check(dict->proto) -/* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */ - && (strchr("PzZ", PyUnicode_AsUTF8(dict->proto)[0]))) { - return 1; - } - - PyErr_Format(PyExc_TypeError, - "'out' parameter %d must be a pointer type, not %s", - Py_SAFE_DOWNCAST(index, Py_ssize_t, int), - PyType_Check(arg) ? - ((PyTypeObject *)arg)->tp_name : - Py_TYPE(arg)->tp_name); - return 0; -} - -/* Returns 1 on success, 0 on error */ -static int -_validate_paramflags(PyTypeObject *type, PyObject *paramflags) -{ - Py_ssize_t i, len; - StgDictObject *dict; - PyObject *argtypes; - - dict = PyType_stgdict((PyObject *)type); - if (!dict) { - PyErr_SetString(PyExc_TypeError, - "abstract class"); - return 0; - } - argtypes = dict->argtypes; - - if (paramflags == NULL || dict->argtypes == NULL) - return 1; - - if (!PyTuple_Check(paramflags)) { - PyErr_SetString(PyExc_TypeError, - "paramflags must be a tuple or None"); - return 0; - } - - len = PyTuple_GET_SIZE(paramflags); - if (len != PyTuple_GET_SIZE(dict->argtypes)) { - PyErr_SetString(PyExc_ValueError, - "paramflags must have the same length as argtypes"); - return 0; - } - - for (i = 0; i < len; ++i) { - PyObject *item = PyTuple_GET_ITEM(paramflags, i); - int flag; - char *name; - PyObject *defval; - PyObject *typ; - if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) { - PyErr_SetString(PyExc_TypeError, - "paramflags must be a sequence of (int [,string [,value]]) tuples"); - return 0; - } - typ = PyTuple_GET_ITEM(argtypes, i); - switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) { - case 0: - case PARAMFLAG_FIN: - case PARAMFLAG_FIN | PARAMFLAG_FLCID: - case PARAMFLAG_FIN | PARAMFLAG_FOUT: - break; - case PARAMFLAG_FOUT: - if (!_check_outarg_type(typ, i+1)) - return 0; - break; - default: - PyErr_Format(PyExc_TypeError, - "paramflag value %d not supported", - flag); - return 0; - } - } - return 1; -} - -static int -_get_name(PyObject *obj, const char **pname) -{ -#ifdef MS_WIN32 - if (PyLong_Check(obj)) { - /* We have to use MAKEINTRESOURCEA for Windows CE. - Works on Windows as well, of course. - */ - *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF); - return 1; - } -#endif - if (PyBytes_Check(obj)) { - *pname = PyBytes_AS_STRING(obj); - return *pname ? 1 : 0; - } - if (PyUnicode_Check(obj)) { - *pname = PyUnicode_AsUTF8(obj); - return *pname ? 1 : 0; - } - PyErr_SetString(PyExc_TypeError, - "function name must be string, bytes object or integer"); - return 0; -} - - -static PyObject * -PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - const char *name; - int (* address)(void); - PyObject *ftuple; - PyObject *dll; - PyObject *obj; - PyCFuncPtrObject *self; - void *handle; - PyObject *paramflags = NULL; - - if (!PyArg_ParseTuple(args, "O|O", &ftuple, ¶mflags)) - return NULL; - if (paramflags == Py_None) - paramflags = NULL; - - ftuple = PySequence_Tuple(ftuple); - if (!ftuple) - /* Here ftuple is a borrowed reference */ - return NULL; - - if (!PyArg_ParseTuple(ftuple, "O&O;illegal func_spec argument", - _get_name, &name, &dll)) - { - Py_DECREF(ftuple); - return NULL; - } - -#ifdef MS_WIN32 - if (PySys_Audit("ctypes.dlsym", - ((uintptr_t)name & ~0xFFFF) ? "Os" : "On", - dll, name) < 0) { - Py_DECREF(ftuple); - return NULL; - } -#else - if (PySys_Audit("ctypes.dlsym", "Os", dll, name) < 0) { - Py_DECREF(ftuple); - return NULL; - } -#endif - - obj = PyObject_GetAttrString(dll, "_handle"); - if (!obj) { - Py_DECREF(ftuple); - return NULL; - } - if (!PyLong_Check(obj)) { - PyErr_SetString(PyExc_TypeError, - "the _handle attribute of the second argument must be an integer"); - Py_DECREF(ftuple); - Py_DECREF(obj); - return NULL; - } - handle = (void *)PyLong_AsVoidPtr(obj); - Py_DECREF(obj); - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "could not convert the _handle attribute to a pointer"); - Py_DECREF(ftuple); - return NULL; - } - -#ifdef MS_WIN32 - address = FindAddress(handle, name, (PyObject *)type); - if (!address) { - if (!IS_INTRESOURCE(name)) - PyErr_Format(PyExc_AttributeError, - "function '%s' not found", - name); - else - PyErr_Format(PyExc_AttributeError, - "function ordinal %d not found", - (WORD)(size_t)name); - Py_DECREF(ftuple); - return NULL; - } -#else - address = (PPROC)ctypes_dlsym(handle, name); - if (!address) { -#ifdef __CYGWIN__ -/* dlerror() isn't very helpful on cygwin */ - PyErr_Format(PyExc_AttributeError, - "function '%s' not found", - name); -#else - PyErr_SetString(PyExc_AttributeError, ctypes_dlerror()); -#endif - Py_DECREF(ftuple); - return NULL; - } -#endif - if (!_validate_paramflags(type, paramflags)) { - Py_DECREF(ftuple); - return NULL; - } - - self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); - if (!self) { - Py_DECREF(ftuple); - return NULL; - } - - Py_XINCREF(paramflags); - self->paramflags = paramflags; - - *(void **)self->b_ptr = address; - Py_INCREF(dll); - Py_DECREF(ftuple); - if (-1 == KeepRef((CDataObject *)self, 0, dll)) { - Py_DECREF((PyObject *)self); - return NULL; - } - - Py_INCREF(self); - self->callable = (PyObject *)self; - return (PyObject *)self; -} - -#ifdef MS_WIN32 -static PyObject * -PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyCFuncPtrObject *self; - int index; - char *name = NULL; - PyObject *paramflags = NULL; - GUID *iid = NULL; - Py_ssize_t iid_len = 0; - - if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, ¶mflags, &iid, &iid_len)) - return NULL; - if (paramflags == Py_None) - paramflags = NULL; - - if (!_validate_paramflags(type, paramflags)) - return NULL; - - self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); - self->index = index + 0x1000; - Py_XINCREF(paramflags); - self->paramflags = paramflags; - if (iid_len == sizeof(GUID)) - self->iid = iid; - return (PyObject *)self; -} -#endif - -/* - PyCFuncPtr_new accepts different argument lists in addition to the standard - _basespec_ keyword arg: - - one argument form - "i" - function address - "O" - must be a callable, creates a C callable function - - two or more argument forms (the third argument is a paramflags tuple) - "(sO)|..." - (function name, dll object (with an integer handle)), paramflags - "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags - "is|..." - vtable index, method name, creates callable calling COM vtbl -*/ -static PyObject * -PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyCFuncPtrObject *self; - PyObject *callable; - StgDictObject *dict; - CThunkObject *thunk; - - if (PyTuple_GET_SIZE(args) == 0) - return GenericPyCData_new(type, args, kwds); - - if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0))) - return PyCFuncPtr_FromDll(type, args, kwds); - -#ifdef MS_WIN32 - if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0))) - return PyCFuncPtr_FromVtblIndex(type, args, kwds); -#endif - - if (1 == PyTuple_GET_SIZE(args) - && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) { - CDataObject *ob; - void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0)); - if (ptr == NULL && PyErr_Occurred()) - return NULL; - ob = (CDataObject *)GenericPyCData_new(type, args, kwds); - if (ob == NULL) - return NULL; - *(void **)ob->b_ptr = ptr; - return (PyObject *)ob; - } - - if (!PyArg_ParseTuple(args, "O", &callable)) - return NULL; - if (!PyCallable_Check(callable)) { - PyErr_SetString(PyExc_TypeError, - "argument must be callable or integer function address"); - return NULL; - } - - /* XXX XXX This would allow passing additional options. For COM - method *implementations*, we would probably want different - behaviour than in 'normal' callback functions: return a HRESULT if - an exception occurs in the callback, and print the traceback not - only on the console, but also to OutputDebugString() or something - like that. - */ -/* - if (kwds && _PyDict_GetItemIdWithError(kwds, &PyId_options)) { - ... - } - else if (PyErr_Occurred()) { - return NULL; - } -*/ - - dict = PyType_stgdict((PyObject *)type); - /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */ - if (!dict || !dict->argtypes) { - PyErr_SetString(PyExc_TypeError, - "cannot construct instance of this class:" - " no argtypes"); - return NULL; - } - - thunk = _ctypes_alloc_callback(callable, - dict->argtypes, - dict->restype, - dict->flags); - if (!thunk) - return NULL; - - self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); - if (self == NULL) { - Py_DECREF(thunk); - return NULL; - } - - Py_INCREF(callable); - self->callable = callable; - - self->thunk = thunk; - *(void **)self->b_ptr = (void *)thunk->pcl_exec; - - Py_INCREF((PyObject *)thunk); /* for KeepRef */ - if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) { - Py_DECREF((PyObject *)self); - return NULL; - } - return (PyObject *)self; -} - - -/* - _byref consumes a refcount to its argument -*/ -static PyObject * -_byref(PyObject *obj) -{ - PyCArgObject *parg; - if (!CDataObject_Check(obj)) { - PyErr_SetString(PyExc_TypeError, - "expected CData instance"); - return NULL; - } - - parg = PyCArgObject_new(); - if (parg == NULL) { - Py_DECREF(obj); - return NULL; - } - - parg->tag = 'P'; - parg->pffi_type = &ffi_type_pointer; - parg->obj = obj; - parg->value.p = ((CDataObject *)obj)->b_ptr; - return (PyObject *)parg; -} - -static PyObject * -_get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds) -{ - PyObject *v; - - if (*pindex < PyTuple_GET_SIZE(inargs)) { - v = PyTuple_GET_ITEM(inargs, *pindex); - ++*pindex; - Py_INCREF(v); - return v; - } - if (kwds && name) { - v = PyDict_GetItemWithError(kwds, name); - if (v) { - ++*pindex; - Py_INCREF(v); - return v; - } - else if (PyErr_Occurred()) { - return NULL; - } - } - if (defval) { - Py_INCREF(defval); - return defval; - } - /* we can't currently emit a better error message */ - if (name) - PyErr_Format(PyExc_TypeError, - "required argument '%S' missing", name); - else - PyErr_Format(PyExc_TypeError, - "not enough arguments"); - return NULL; -} - -/* - This function implements higher level functionality plus the ability to call - functions with keyword arguments by looking at parameter flags. parameter - flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer - specifying the direction of the data transfer for this parameter - 'in', - 'out' or 'inout' (zero means the same as 'in'). The second entry is the - parameter name, and the third is the default value if the parameter is - missing in the function call. - - This function builds and returns a new tuple 'callargs' which contains the - parameters to use in the call. Items on this tuple are copied from the - 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the - 'argtypes' tuple for 'out' parameters. It also calculates numretvals which - is the number of return values for the function, outmask/inoutmask are - bitmasks containing indexes into the callargs tuple specifying which - parameters have to be returned. _build_result builds the return value of the - function. -*/ -static PyObject * -_build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, - PyObject *inargs, PyObject *kwds, - int *poutmask, int *pinoutmask, unsigned int *pnumretvals) -{ - PyObject *paramflags = self->paramflags; - PyObject *callargs; - StgDictObject *dict; - Py_ssize_t i, len; - int inargs_index = 0; - /* It's a little bit difficult to determine how many arguments the - function call requires/accepts. For simplicity, we count the consumed - args and compare this to the number of supplied args. */ - Py_ssize_t actual_args; - - *poutmask = 0; - *pinoutmask = 0; - *pnumretvals = 0; - - /* Trivial cases, where we either return inargs itself, or a slice of it. */ - if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) { -#ifdef MS_WIN32 - if (self->index) - return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs)); -#endif - Py_INCREF(inargs); - return inargs; - } - - len = PyTuple_GET_SIZE(argtypes); - callargs = PyTuple_New(len); /* the argument tuple we build */ - if (callargs == NULL) - return NULL; - -#ifdef MS_WIN32 - /* For a COM method, skip the first arg */ - if (self->index) { - inargs_index = 1; - } -#endif - for (i = 0; i < len; ++i) { - PyObject *item = PyTuple_GET_ITEM(paramflags, i); - PyObject *ob; - unsigned int flag; - PyObject *name = NULL; - PyObject *defval = NULL; - - /* This way seems to be ~2 us faster than the PyArg_ParseTuple - calls below. */ - /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */ - Py_ssize_t tsize = PyTuple_GET_SIZE(item); - flag = PyLong_AsUnsignedLongMask(PyTuple_GET_ITEM(item, 0)); - name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL; - defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL; - - switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) { - case PARAMFLAG_FIN | PARAMFLAG_FLCID: - /* ['in', 'lcid'] parameter. Always taken from defval, - if given, else the integer 0. */ - if (defval == NULL) - defval = _PyLong_Zero; - Py_INCREF(defval); - PyTuple_SET_ITEM(callargs, i, defval); - break; - case (PARAMFLAG_FIN | PARAMFLAG_FOUT): - *pinoutmask |= (1 << i); /* mark as inout arg */ - (*pnumretvals)++; - /* fall through */ - case 0: - case PARAMFLAG_FIN: - /* 'in' parameter. Copy it from inargs. */ - ob =_get_arg(&inargs_index, name, defval, inargs, kwds); - if (ob == NULL) - goto error; - PyTuple_SET_ITEM(callargs, i, ob); - break; - case PARAMFLAG_FOUT: - /* XXX Refactor this code into a separate function. */ - /* 'out' parameter. - argtypes[i] must be a POINTER to a c type. - - Cannot by supplied in inargs, but a defval will be used - if available. XXX Should we support getting it from kwds? - */ - if (defval) { - /* XXX Using mutable objects as defval will - make the function non-threadsafe, unless we - copy the object in each invocation */ - Py_INCREF(defval); - PyTuple_SET_ITEM(callargs, i, defval); - *poutmask |= (1 << i); /* mark as out arg */ - (*pnumretvals)++; - break; - } - ob = PyTuple_GET_ITEM(argtypes, i); - dict = PyType_stgdict(ob); - if (dict == NULL) { - /* Cannot happen: _validate_paramflags() - would not accept such an object */ - PyErr_Format(PyExc_RuntimeError, - "NULL stgdict unexpected"); - goto error; - } - if (PyUnicode_Check(dict->proto)) { - PyErr_Format( - PyExc_TypeError, - "%s 'out' parameter must be passed as default value", - ((PyTypeObject *)ob)->tp_name); - goto error; - } - if (PyCArrayTypeObject_Check(ob)) - ob = _PyObject_CallNoArg(ob); - else - /* Create an instance of the pointed-to type */ - ob = _PyObject_CallNoArg(dict->proto); - /* - XXX Is the following correct any longer? - We must not pass a byref() to the array then but - the array instance itself. Then, we cannot retrieve - the result from the PyCArgObject. - */ - if (ob == NULL) - goto error; - /* The .from_param call that will occur later will pass this - as a byref parameter. */ - PyTuple_SET_ITEM(callargs, i, ob); - *poutmask |= (1 << i); /* mark as out arg */ - (*pnumretvals)++; - break; - default: - PyErr_Format(PyExc_ValueError, - "paramflag %u not yet implemented", flag); - goto error; - break; - } - } - - /* We have counted the arguments we have consumed in 'inargs_index'. This - must be the same as len(inargs) + len(kwds), otherwise we have - either too much or not enough arguments. */ - - actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_GET_SIZE(kwds) : 0); - if (actual_args != inargs_index) { - /* When we have default values or named parameters, this error - message is misleading. See unittests/test_paramflags.py - */ - PyErr_Format(PyExc_TypeError, - "call takes exactly %d arguments (%zd given)", - inargs_index, actual_args); - goto error; - } - - /* outmask is a bitmask containing indexes into callargs. Items at - these indexes contain values to return. - */ - return callargs; - error: - Py_DECREF(callargs); - return NULL; -} - -/* See also: - http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp -*/ -/* - Build return value of a function. - - Consumes the refcount on result and callargs. -*/ -static PyObject * -_build_result(PyObject *result, PyObject *callargs, - int outmask, int inoutmask, unsigned int numretvals) -{ - unsigned int i, index; - int bit; - PyObject *tup = NULL; - - if (callargs == NULL) - return result; - if (result == NULL || numretvals == 0) { - Py_DECREF(callargs); - return result; - } - Py_DECREF(result); - - /* tup will not be allocated if numretvals == 1 */ - /* allocate tuple to hold the result */ - if (numretvals > 1) { - tup = PyTuple_New(numretvals); - if (tup == NULL) { - Py_DECREF(callargs); - return NULL; - } - } - - index = 0; - for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) { - PyObject *v; - if (bit & inoutmask) { - v = PyTuple_GET_ITEM(callargs, i); - Py_INCREF(v); - if (numretvals == 1) { - Py_DECREF(callargs); - return v; - } - PyTuple_SET_ITEM(tup, index, v); - index++; - } else if (bit & outmask) { - _Py_IDENTIFIER(__ctypes_from_outparam__); - - v = PyTuple_GET_ITEM(callargs, i); - v = _PyObject_CallMethodIdNoArgs(v, &PyId___ctypes_from_outparam__); - if (v == NULL || numretvals == 1) { - Py_DECREF(callargs); - return v; - } - PyTuple_SET_ITEM(tup, index, v); - index++; - } - if (index == numretvals) - break; - } - - Py_DECREF(callargs); - return tup; -} - -static PyObject * -PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds) -{ - PyObject *restype; - PyObject *converters; - PyObject *checker; - PyObject *argtypes; - StgDictObject *dict = PyObject_stgdict((PyObject *)self); - PyObject *result; - PyObject *callargs; - PyObject *errcheck; -#ifdef MS_WIN32 - IUnknown *piunk = NULL; -#endif - void *pProc = NULL; - - int inoutmask; - int outmask; - unsigned int numretvals; - - assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ - restype = self->restype ? self->restype : dict->restype; - converters = self->converters ? self->converters : dict->converters; - checker = self->checker ? self->checker : dict->checker; - argtypes = self->argtypes ? self->argtypes : dict->argtypes; -/* later, we probably want to have an errcheck field in stgdict */ - errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */; - - - pProc = *(void **)self->b_ptr; -#ifdef MS_WIN32 - if (self->index) { - /* It's a COM method */ - CDataObject *this; - this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */ - if (!this) { - PyErr_SetString(PyExc_ValueError, - "native com method call without 'this' parameter"); - return NULL; - } - if (!CDataObject_Check(this)) { - PyErr_SetString(PyExc_TypeError, - "Expected a COM this pointer as first argument"); - return NULL; - } - /* there should be more checks? No, in Python */ - /* First arg is a pointer to an interface instance */ - if (!this->b_ptr || *(void **)this->b_ptr == NULL) { - PyErr_SetString(PyExc_ValueError, - "NULL COM pointer access"); - return NULL; - } - piunk = *(IUnknown **)this->b_ptr; - if (NULL == piunk->lpVtbl) { - PyErr_SetString(PyExc_ValueError, - "COM method call without VTable"); - return NULL; - } - pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000]; - } -#endif - callargs = _build_callargs(self, argtypes, - inargs, kwds, - &outmask, &inoutmask, &numretvals); - if (callargs == NULL) - return NULL; - - if (converters) { - int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters), - Py_ssize_t, int); - int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs), - Py_ssize_t, int); - - if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) { - /* For cdecl functions, we allow more actual arguments - than the length of the argtypes tuple. - */ - if (required > actual) { - Py_DECREF(callargs); - PyErr_Format(PyExc_TypeError, - "this function takes at least %d argument%s (%d given)", - required, - required == 1 ? "" : "s", - actual); - return NULL; - } - } else if (required != actual) { - Py_DECREF(callargs); - PyErr_Format(PyExc_TypeError, - "this function takes %d argument%s (%d given)", - required, - required == 1 ? "" : "s", - actual); - return NULL; - } - } - - result = _ctypes_callproc(pProc, - callargs, -#ifdef MS_WIN32 - piunk, - self->iid, -#endif - dict->flags, - converters, - restype, - checker); -/* The 'errcheck' protocol */ - if (result != NULL && errcheck) { - PyObject *v = PyObject_CallFunctionObjArgs(errcheck, - result, - self, - callargs, - NULL); - /* If the errcheck function failed, return NULL. - If the errcheck function returned callargs unchanged, - continue normal processing. - If the errcheck function returned something else, - use that as result. - */ - if (v == NULL || v != callargs) { - Py_DECREF(result); - Py_DECREF(callargs); - return v; - } - Py_DECREF(v); - } - - return _build_result(result, callargs, - outmask, inoutmask, numretvals); -} - -static int -PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->callable); - Py_VISIT(self->restype); - Py_VISIT(self->checker); - Py_VISIT(self->errcheck); - Py_VISIT(self->argtypes); - Py_VISIT(self->converters); - Py_VISIT(self->paramflags); - Py_VISIT(self->thunk); - return PyCData_traverse((CDataObject *)self, visit, arg); -} - -static int -PyCFuncPtr_clear(PyCFuncPtrObject *self) -{ - Py_CLEAR(self->callable); - Py_CLEAR(self->restype); - Py_CLEAR(self->checker); - Py_CLEAR(self->errcheck); - Py_CLEAR(self->argtypes); - Py_CLEAR(self->converters); - Py_CLEAR(self->paramflags); - Py_CLEAR(self->thunk); - return PyCData_clear((CDataObject *)self); -} - -static void -PyCFuncPtr_dealloc(PyCFuncPtrObject *self) -{ - PyCFuncPtr_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -PyCFuncPtr_repr(PyCFuncPtrObject *self) -{ -#ifdef MS_WIN32 - if (self->index) - return PyUnicode_FromFormat("", - self->index - 0x1000, - Py_TYPE(self)->tp_name, - self); -#endif - return PyUnicode_FromFormat("<%s object at %p>", - Py_TYPE(self)->tp_name, - self); -} - -static int -PyCFuncPtr_bool(PyCFuncPtrObject *self) -{ - return ((*(void **)self->b_ptr != NULL) -#ifdef MS_WIN32 - || (self->index != 0) -#endif - ); -} - -static PyNumberMethods PyCFuncPtr_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - (inquiry)PyCFuncPtr_bool, /* nb_bool */ -}; - -PyTypeObject PyCFuncPtr_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCFuncPtr", - sizeof(PyCFuncPtrObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)PyCFuncPtr_repr, /* tp_repr */ - &PyCFuncPtr_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)PyCFuncPtr_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Function Pointer", /* tp_doc */ - (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */ - (inquiry)PyCFuncPtr_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - PyCFuncPtr_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCFuncPtr_new, /* tp_new */ - 0, /* tp_free */ -}; - -/*****************************************************************/ -/* - Struct_Type -*/ -/* - This function is called to initialize a Structure or Union with positional - arguments. It calls itself recursively for all Structure or Union base - classes, then retrieves the _fields_ member to associate the argument - position with the correct field name. - - Returns -1 on error, or the index of next argument on success. - */ -static Py_ssize_t -_init_pos_args(PyObject *self, PyTypeObject *type, - PyObject *args, PyObject *kwds, - Py_ssize_t index) -{ - StgDictObject *dict; - PyObject *fields; - Py_ssize_t i; - _Py_IDENTIFIER(_fields_); - - if (PyType_stgdict((PyObject *)type->tp_base)) { - index = _init_pos_args(self, type->tp_base, - args, kwds, - index); - if (index == -1) - return -1; - } - - dict = PyType_stgdict((PyObject *)type); - fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_); - if (fields == NULL) { - if (PyErr_Occurred()) { - return -1; - } - return index; - } - - for (i = 0; - i < dict->length && (i+index) < PyTuple_GET_SIZE(args); - ++i) { - PyObject *pair = PySequence_GetItem(fields, i); - PyObject *name, *val; - int res; - if (!pair) - return -1; - name = PySequence_GetItem(pair, 0); - if (!name) { - Py_DECREF(pair); - return -1; - } - val = PyTuple_GET_ITEM(args, i + index); - if (kwds) { - if (PyDict_GetItemWithError(kwds, name)) { - PyErr_Format(PyExc_TypeError, - "duplicate values for field %R", - name); - Py_DECREF(pair); - Py_DECREF(name); - return -1; - } - else if (PyErr_Occurred()) { - Py_DECREF(pair); - Py_DECREF(name); - return -1; - } - } - - res = PyObject_SetAttr(self, name, val); - Py_DECREF(pair); - Py_DECREF(name); - if (res == -1) - return -1; - } - return index + dict->length; -} - -static int -Struct_init(PyObject *self, PyObject *args, PyObject *kwds) -{ -/* Optimization possible: Store the attribute names _fields_[x][0] - * in C accessible fields somewhere ? - */ - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "args not a tuple?"); - return -1; - } - if (PyTuple_GET_SIZE(args)) { - Py_ssize_t res = _init_pos_args(self, Py_TYPE(self), - args, kwds, 0); - if (res == -1) - return -1; - if (res < PyTuple_GET_SIZE(args)) { - PyErr_SetString(PyExc_TypeError, - "too many initializers"); - return -1; - } - } - - if (kwds) { - PyObject *key, *value; - Py_ssize_t pos = 0; - while(PyDict_Next(kwds, &pos, &key, &value)) { - if (-1 == PyObject_SetAttr(self, key, value)) - return -1; - } - } - return 0; -} - -static PyTypeObject Struct_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.Structure", - sizeof(CDataObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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 */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Structure base class", /* tp_doc */ - (traverseproc)PyCData_traverse, /* tp_traverse */ - (inquiry)PyCData_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - Struct_init, /* tp_init */ - 0, /* tp_alloc */ - GenericPyCData_new, /* tp_new */ - 0, /* tp_free */ -}; - -static PyTypeObject Union_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.Union", - sizeof(CDataObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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 */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Union base class", /* tp_doc */ - (traverseproc)PyCData_traverse, /* tp_traverse */ - (inquiry)PyCData_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - Struct_init, /* tp_init */ - 0, /* tp_alloc */ - GenericPyCData_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/******************************************************************/ -/* - PyCArray_Type -*/ -static int -Array_init(CDataObject *self, PyObject *args, PyObject *kw) -{ - Py_ssize_t i; - Py_ssize_t n; - - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "args not a tuple?"); - return -1; - } - n = PyTuple_GET_SIZE(args); - for (i = 0; i < n; ++i) { - PyObject *v; - v = PyTuple_GET_ITEM(args, i); - if (-1 == PySequence_SetItem((PyObject *)self, i, v)) - return -1; - } - return 0; -} - -static PyObject * -Array_item(PyObject *myself, Py_ssize_t index) -{ - CDataObject *self = (CDataObject *)myself; - Py_ssize_t offset, size; - StgDictObject *stgdict; - - - if (index < 0 || index >= self->b_length) { - PyErr_SetString(PyExc_IndexError, - "invalid index"); - return NULL; - } - - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for array instances */ - /* Would it be clearer if we got the item size from - stgdict->proto's stgdict? - */ - size = stgdict->size / stgdict->length; - offset = index * size; - - return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self, - index, size, self->b_ptr + offset); -} - -static PyObject * -Array_subscript(PyObject *myself, PyObject *item) -{ - CDataObject *self = (CDataObject *)myself; - - 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 += self->b_length; - return Array_item(myself, i); - } - else if (PySlice_Check(item)) { - StgDictObject *stgdict, *itemdict; - PyObject *proto; - PyObject *np; - Py_ssize_t start, stop, step, slicelen, i; - size_t cur; - - if (PySlice_Unpack(item, &start, &stop, &step) < 0) { - return NULL; - } - slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step); - - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for array object instances */ - proto = stgdict->proto; - itemdict = PyType_stgdict(proto); - assert(itemdict); /* proto is the item type of the array, a - ctypes type, so this cannot be NULL */ - - if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { - char *ptr = (char *)self->b_ptr; - char *dest; - - if (slicelen <= 0) - return PyBytes_FromStringAndSize("", 0); - if (step == 1) { - return PyBytes_FromStringAndSize(ptr + start, - slicelen); - } - dest = (char *)PyMem_Malloc(slicelen); - - if (dest == NULL) - return PyErr_NoMemory(); - - for (cur = start, i = 0; i < slicelen; - cur += step, i++) { - dest[i] = ptr[cur]; - } - - np = PyBytes_FromStringAndSize(dest, slicelen); - PyMem_Free(dest); - return np; - } -#ifdef CTYPES_UNICODE - if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { - wchar_t *ptr = (wchar_t *)self->b_ptr; - wchar_t *dest; + * The following checks, relating to bpo-16575 and bpo-16576, have been + * disabled. The reason is that, although there is a definite problem with + * how libffi handles unions (https://github.com/libffi/libffi/issues/33), + * there are numerous libraries which pass structures containing unions + * by values - especially on Windows but examples also exist on Linux + * (https://bugs.python.org/msg359834). + * + * It may not be possible to get proper support for unions and bitfields + * until support is forthcoming in libffi, but for now, adding the checks + * has caused problems in otherwise-working software, which suggests it + * is better to disable the checks. + * + * Although specific examples reported relate specifically to unions and + * not bitfields, the bitfields check is also being disabled as a + * precaution. - if (slicelen <= 0) - return PyUnicode_New(0, 0); - if (step == 1) { - return PyUnicode_FromWideChar(ptr + start, - slicelen); - } + StgDictObject *stgdict = PyType_stgdict(tp); - dest = PyMem_New(wchar_t, slicelen); - if (dest == NULL) { - PyErr_NoMemory(); + if (stgdict != NULL) { + if (stgdict->flags & TYPEFLAG_HASUNION) { + Py_DECREF(converters); + Py_DECREF(ob); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "item %zd in _argtypes_ passes a union by " + "value, which is unsupported.", + i + 1); + } return NULL; } - - for (cur = start, i = 0; i < slicelen; - cur += step, i++) { - dest[i] = ptr[cur]; + if (stgdict->flags & TYPEFLAG_HASBITFIELD) { + Py_DECREF(converters); + Py_DECREF(ob); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "item %zd in _argtypes_ passes a struct/" + "union with a bitfield by value, which is " + "unsupported.", + i + 1); + } + return NULL; } - - np = PyUnicode_FromWideChar(dest, slicelen); - PyMem_Free(dest); - return np; } -#endif - - np = PyList_New(slicelen); - if (np == NULL) - return NULL; + */ - for (cur = start, i = 0; i < slicelen; - cur += step, i++) { - PyObject *v = Array_item(myself, cur); - if (v == NULL) { - Py_DECREF(np); - return NULL; + if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) { + Py_DECREF(converters); + Py_DECREF(ob); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "item %zd in _argtypes_ has no from_param method", + i+1); } - PyList_SET_ITEM(np, i, v); + return NULL; } - return np; - } - else { - PyErr_SetString(PyExc_TypeError, - "indices must be integers"); - return NULL; - } - -} - -static int -Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value) -{ - CDataObject *self = (CDataObject *)myself; - Py_ssize_t size, offset; - StgDictObject *stgdict; - char *ptr; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "Array does not support item deletion"); - return -1; - } - - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for array object instances */ - if (index < 0 || index >= stgdict->length) { - PyErr_SetString(PyExc_IndexError, - "invalid index"); - return -1; - } - size = stgdict->size / stgdict->length; - offset = index * size; - ptr = self->b_ptr + offset; - - return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, - index, size, ptr); -} - -static int -Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value) -{ - CDataObject *self = (CDataObject *)myself; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "Array does not support item deletion"); - return -1; - } - - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += self->b_length; - return Array_ass_item(myself, i, value); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelen, otherlen, i; - size_t cur; - - if (PySlice_Unpack(item, &start, &stop, &step) < 0) { - return -1; + PyTuple_SET_ITEM(converters, i, cnv); + } + Py_DECREF(ob); + return converters; +} + +static int +make_funcptrtype_dict(StgDictObject *stgdict) +{ + PyObject *ob; + PyObject *converters = NULL; + _Py_IDENTIFIER(_flags_); + _Py_IDENTIFIER(_argtypes_); + _Py_IDENTIFIER(_restype_); + _Py_IDENTIFIER(_check_retval_); + + stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; + stgdict->length = 1; + stgdict->size = sizeof(void *); + stgdict->setfunc = NULL; + stgdict->getfunc = NULL; + stgdict->ffi_type_pointer = ffi_type_pointer; + + ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_); + if (!ob || !PyLong_Check(ob)) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "class must define _flags_ which must be an integer"); } - slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step); - if ((step < 0 && start < stop) || - (step > 0 && start > stop)) - stop = start; - - otherlen = PySequence_Length(value); - if (otherlen != slicelen) { - PyErr_SetString(PyExc_ValueError, - "Can only assign sequence of same size"); + return -1; + } + stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER; + + /* _argtypes_ is optional... */ + ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_); + if (ob) { + converters = converters_from_argtypes(ob); + if (!converters) return -1; - } - for (cur = start, i = 0; i < otherlen; cur += step, i++) { - PyObject *item = PySequence_GetItem(value, i); - int result; - if (item == NULL) - return -1; - result = Array_ass_item(myself, cur, item); - Py_DECREF(item); - if (result == -1) - return -1; - } - return 0; - } - else { - PyErr_SetString(PyExc_TypeError, - "indices must be integer"); + Py_INCREF(ob); + stgdict->argtypes = ob; + stgdict->converters = converters; + } + else if (PyErr_Occurred()) { return -1; } -} - -static Py_ssize_t -Array_length(PyObject *myself) -{ - CDataObject *self = (CDataObject *)myself; - return self->b_length; -} - -static PyMethodDef Array_methods[] = { - {"__class_getitem__", (PyCFunction)Py_GenericAlias, - METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - { NULL, NULL } -}; - -static PySequenceMethods Array_as_sequence = { - Array_length, /* sq_length; */ - 0, /* sq_concat; */ - 0, /* sq_repeat; */ - Array_item, /* sq_item; */ - 0, /* sq_slice; */ - Array_ass_item, /* sq_ass_item; */ - 0, /* sq_ass_slice; */ - 0, /* sq_contains; */ - - 0, /* sq_inplace_concat; */ - 0, /* sq_inplace_repeat; */ -}; - -static PyMappingMethods Array_as_mapping = { - Array_length, - Array_subscript, - Array_ass_subscript, -}; - -PyTypeObject PyCArray_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.Array", - sizeof(CDataObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &Array_as_sequence, /* tp_as_sequence */ - &Array_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ - (traverseproc)PyCData_traverse, /* tp_traverse */ - (inquiry)PyCData_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Array_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)Array_init, /* tp_init */ - 0, /* tp_alloc */ - GenericPyCData_new, /* tp_new */ - 0, /* tp_free */ -}; - -PyObject * -PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length) -{ - static PyObject *cache; - PyObject *key; - PyObject *result; - char name[256]; - PyObject *len; - - if (cache == NULL) { - cache = PyDict_New(); - if (cache == NULL) - return NULL; - } - len = PyLong_FromSsize_t(length); - if (len == NULL) - return NULL; - key = PyTuple_Pack(2, itemtype, len); - Py_DECREF(len); - if (!key) - return NULL; - result = PyDict_GetItemProxy(cache, key); - if (result) { - Py_INCREF(result); - Py_DECREF(key); - return result; - } + + ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_); + if (ob) { + if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { + PyErr_SetString(PyExc_TypeError, + "_restype_ must be a type, a callable, or None"); + return -1; + } + Py_INCREF(ob); + stgdict->restype = ob; + if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, + &stgdict->checker) < 0) + { + return -1; + } + } else if (PyErr_Occurred()) { - Py_DECREF(key); - return NULL; - } - - if (!PyType_Check(itemtype)) { - PyErr_SetString(PyExc_TypeError, - "Expected a type object"); - Py_DECREF(key); - return NULL; - } -#ifdef MS_WIN64 - sprintf(name, "%.200s_Array_%Id", - ((PyTypeObject *)itemtype)->tp_name, length); -#else - sprintf(name, "%.200s_Array_%ld", - ((PyTypeObject *)itemtype)->tp_name, (long)length); -#endif - - result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type, - "s(O){s:n,s:O}", - name, - &PyCArray_Type, - "_length_", - length, - "_type_", - itemtype - ); - if (result == NULL) { - Py_DECREF(key); - return NULL; - } - if (-1 == PyDict_SetItemProxy(cache, key, result)) { - Py_DECREF(key); - Py_DECREF(result); - return NULL; - } - Py_DECREF(key); - return result; -} - - -/******************************************************************/ -/* - Simple_Type -*/ - -static int -Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) -{ - PyObject *result; - StgDictObject *dict = PyObject_stgdict((PyObject *)self); - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "can't delete attribute"); return -1; } - assert(dict); /* Cannot be NULL for CDataObject instances */ - assert(dict->setfunc); - result = dict->setfunc(self->b_ptr, value, dict->size); - if (!result) - return -1; - - /* consumes the refcount the setfunc returns */ - return KeepRef(self, 0, result); -} - -static int -Simple_init(CDataObject *self, PyObject *args, PyObject *kw) -{ - PyObject *value = NULL; - if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value)) +/* XXX later, maybe. + ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_); + if (ob) { + if (!PyCallable_Check(ob)) { + PyErr_SetString(PyExc_TypeError, + "_errcheck_ must be callable"); + return -1; + } + Py_INCREF(ob); + stgdict->errcheck = ob; + } + else if (PyErr_Occurred()) { return -1; - if (value) - return Simple_set_value(self, value, NULL); - return 0; -} - -static PyObject * -Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored)) -{ - StgDictObject *dict; - dict = PyObject_stgdict((PyObject *)self); - assert(dict); /* Cannot be NULL for CDataObject instances */ - assert(dict->getfunc); - return dict->getfunc(self->b_ptr, self->b_size); -} - -static PyGetSetDef Simple_getsets[] = { - { "value", (getter)Simple_get_value, (setter)Simple_set_value, - "current value", NULL }, - { NULL, NULL } -}; - -static PyObject * -Simple_from_outparm(PyObject *self, PyObject *args) -{ - if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) { - Py_INCREF(self); - return self; - } - /* call stgdict->getfunc */ - return Simple_get_value((CDataObject *)self, NULL); -} - -static PyMethodDef Simple_methods[] = { - { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, }, - { NULL, NULL }, -}; - -static int Simple_bool(CDataObject *self) -{ - return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size); -} - -static PyNumberMethods Simple_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - (inquiry)Simple_bool, /* nb_bool */ -}; - -/* "%s(%s)" % (self.__class__.__name__, self.value) */ -static PyObject * -Simple_repr(CDataObject *self) -{ - PyObject *val, *result; - - if (Py_TYPE(self)->tp_base != &Simple_Type) { - return PyUnicode_FromFormat("<%s object at %p>", - Py_TYPE(self)->tp_name, self); } - - val = Simple_get_value(self, NULL); - if (val == NULL) - return NULL; - - result = PyUnicode_FromFormat("%s(%R)", - Py_TYPE(self)->tp_name, val); - Py_DECREF(val); - return result; -} - -static PyTypeObject Simple_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes._SimpleCData", - sizeof(CDataObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ +*/ + return 0; +} + +static PyCArgObject * +PyCFuncPtrType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + + parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; + Py_INCREF(self); + parg->obj = (PyObject *)self; + parg->value.p = *(void **)self->b_ptr; + return parg; +} + +static PyObject * +PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyTypeObject *result; + StgDictObject *stgdict; + + stgdict = (StgDictObject *)_PyObject_CallNoArg( + (PyObject *)&PyCStgDict_Type); + if (!stgdict) + return NULL; + + stgdict->paramfunc = PyCFuncPtrType_paramfunc; + /* We do NOT expose the function signature in the format string. It + is impossible, generally, because the only requirement for the + argtypes items is that they have a .from_param method - we do not + know the types of the arguments (although, in practice, most + argtypes would be a ctypes type). + */ + stgdict->format = _ctypes_alloc_format_string(NULL, "X{}"); + if (stgdict->format == NULL) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } + stgdict->flags |= TYPEFLAG_ISPOINTER; + + /* create the new instance (which is a class, + since we are a metatype!) */ + result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); + if (result == NULL) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } + + /* replace the class dict by our updated storage dict */ + if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { + Py_DECREF(result); + Py_DECREF((PyObject *)stgdict); + return NULL; + } + Py_SETREF(result->tp_dict, (PyObject *)stgdict); + + if (-1 == make_funcptrtype_dict(stgdict)) { + Py_DECREF(result); + return NULL; + } + + return (PyObject *)result; +} + +PyTypeObject PyCFuncPtrType_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.PyCFuncPtrType", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)&Simple_repr, /* tp_repr */ - &Simple_as_number, /* 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 */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ - (traverseproc)PyCData_traverse, /* tp_traverse */ - (inquiry)PyCData_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Simple_methods, /* tp_methods */ - 0, /* tp_members */ - Simple_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)Simple_init, /* tp_init */ - 0, /* tp_alloc */ - GenericPyCData_new, /* tp_new */ - 0, /* tp_free */ -}; - -/******************************************************************/ -/* - PyCPointer_Type -*/ -static PyObject * -Pointer_item(PyObject *myself, Py_ssize_t index) -{ - CDataObject *self = (CDataObject *)myself; - Py_ssize_t size; - Py_ssize_t offset; - StgDictObject *stgdict, *itemdict; - PyObject *proto; - - if (*(void **)self->b_ptr == NULL) { - PyErr_SetString(PyExc_ValueError, - "NULL pointer access"); + 0, /* tp_repr */ + 0, /* tp_as_number */ + &CDataType_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + "metatype for C function pointers", /* tp_doc */ + (traverseproc)CDataType_traverse, /* tp_traverse */ + (inquiry)CDataType_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + CDataType_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyCFuncPtrType_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/***************************************************************** + * Code to keep needed objects alive + */ + +static CDataObject * +PyCData_GetContainer(CDataObject *self) +{ + while (self->b_base) + self = self->b_base; + if (self->b_objects == NULL) { + if (self->b_length) { + self->b_objects = PyDict_New(); + if (self->b_objects == NULL) + return NULL; + } else { + Py_INCREF(Py_None); + self->b_objects = Py_None; + } + } + return self; +} + +static PyObject * +GetKeepedObjects(CDataObject *target) +{ + CDataObject *container; + container = PyCData_GetContainer(target); + if (container == NULL) + return NULL; + return container->b_objects; +} + +static PyObject * +unique_key(CDataObject *target, Py_ssize_t index) +{ + char string[256]; + char *cp = string; + size_t bytes_left; + + Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2); + cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int)); + while (target->b_base) { + bytes_left = sizeof(string) - (cp - string) - 1; + /* Hex format needs 2 characters per byte */ + if (bytes_left < sizeof(Py_ssize_t) * 2) { + PyErr_SetString(PyExc_ValueError, + "ctypes object structure too deep"); + return NULL; + } + cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int)); + target = target->b_base; + } + return PyUnicode_FromStringAndSize(string, cp-string); +} + +/* + * Keep a reference to 'keep' in the 'target', at index 'index'. + * + * If 'keep' is None, do nothing. + * + * Otherwise create a dictionary (if it does not yet exist) id the root + * objects 'b_objects' item, which will store the 'keep' object under a unique + * key. + * + * The unique_key helper travels the target's b_base pointer down to the root, + * building a string containing hex-formatted indexes found during traversal, + * separated by colons. + * + * The index tuple is used as a key into the root object's b_objects dict. + * + * Note: This function steals a refcount of the third argument, even if it + * fails! + */ +static int +KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep) +{ + int result; + CDataObject *ob; + PyObject *key; + +/* Optimization: no need to store None */ + if (keep == Py_None) { + Py_DECREF(Py_None); + return 0; + } + ob = PyCData_GetContainer(target); + if (ob == NULL) { + Py_DECREF(keep); + return -1; + } + if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) { + Py_XSETREF(ob->b_objects, keep); /* refcount consumed */ + return 0; + } + key = unique_key(target, index); + if (key == NULL) { + Py_DECREF(keep); + return -1; + } + result = PyDict_SetItem(ob->b_objects, key, keep); + Py_DECREF(key); + Py_DECREF(keep); + return result; +} + +/******************************************************************/ +/* + PyCData_Type + */ +static int +PyCData_traverse(CDataObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->b_objects); + Py_VISIT((PyObject *)self->b_base); + return 0; +} + +static int +PyCData_clear(CDataObject *self) +{ + Py_CLEAR(self->b_objects); + if ((self->b_needsfree) + && _CDataObject_HasExternalBuffer(self)) + PyMem_Free(self->b_ptr); + self->b_ptr = NULL; + Py_CLEAR(self->b_base); + return 0; +} + +static void +PyCData_dealloc(PyObject *self) +{ + PyCData_clear((CDataObject *)self); + Py_TYPE(self)->tp_free(self); +} + +static PyMemberDef PyCData_members[] = { + { "_b_base_", T_OBJECT, + offsetof(CDataObject, b_base), READONLY, + "the base object" }, + { "_b_needsfree_", T_INT, + offsetof(CDataObject, b_needsfree), READONLY, + "whether the object owns the memory or not" }, + { "_objects", T_OBJECT, + offsetof(CDataObject, b_objects), READONLY, + "internal objects tree (NEVER CHANGE THIS OBJECT!)"}, + { NULL }, +}; + +static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags) +{ + CDataObject *self = (CDataObject *)myself; + StgDictObject *dict = PyObject_stgdict(myself); + Py_ssize_t i; + + if (view == NULL) return 0; + + view->buf = self->b_ptr; + view->obj = myself; + Py_INCREF(myself); + view->len = self->b_size; + view->readonly = 0; + /* use default format character if not set */ + view->format = dict->format ? dict->format : "B"; + view->ndim = dict->ndim; + view->shape = dict->shape; + view->itemsize = self->b_size; + if (view->itemsize) { + for (i = 0; i < view->ndim; ++i) { + view->itemsize /= dict->shape[i]; + } + } + view->strides = NULL; + view->suboffsets = NULL; + view->internal = NULL; + return 0; +} + +static PyBufferProcs PyCData_as_buffer = { + PyCData_NewGetBuffer, + NULL, +}; + +/* + * CData objects are mutable, so they cannot be hashable! + */ +static Py_hash_t +PyCData_nohash(PyObject *self) +{ + PyErr_SetString(PyExc_TypeError, "unhashable type"); + return -1; +} + +static PyObject * +PyCData_reduce(PyObject *myself, PyObject *args) +{ + CDataObject *self = (CDataObject *)myself; + + if (PyObject_stgdict(myself)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) { + PyErr_SetString(PyExc_ValueError, + "ctypes objects containing pointers cannot be pickled"); + return NULL; + } + PyObject *dict = PyObject_GetAttrString(myself, "__dict__"); + if (dict == NULL) { return NULL; } - - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for pointer object instances */ - - proto = stgdict->proto; - assert(proto); - itemdict = PyType_stgdict(proto); - assert(itemdict); /* proto is the item type of the pointer, a ctypes - type, so this cannot be NULL */ - - size = itemdict->size; - offset = index * itemdict->size; - - return PyCData_get(proto, stgdict->getfunc, (PyObject *)self, - index, size, (*(char **)self->b_ptr) + offset); -} - -static int -Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value) -{ - CDataObject *self = (CDataObject *)myself; - Py_ssize_t size; - Py_ssize_t offset; - StgDictObject *stgdict, *itemdict; - PyObject *proto; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "Pointer does not support item deletion"); - return -1; - } - - if (*(void **)self->b_ptr == NULL) { - PyErr_SetString(PyExc_ValueError, - "NULL pointer access"); - return -1; - } - - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for pointer instances */ - - proto = stgdict->proto; - assert(proto); - - itemdict = PyType_stgdict(proto); - assert(itemdict); /* Cannot be NULL because the itemtype of a pointer - is always a ctypes type */ - - size = itemdict->size; - offset = index * itemdict->size; - - return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value, - index, size, (*(char **)self->b_ptr) + offset); -} - -static PyObject * -Pointer_get_contents(CDataObject *self, void *closure) -{ - StgDictObject *stgdict; - - if (*(void **)self->b_ptr == NULL) { - PyErr_SetString(PyExc_ValueError, - "NULL pointer access"); + return Py_BuildValue("O(O(NN))", _unpickle, Py_TYPE(myself), dict, + PyBytes_FromStringAndSize(self->b_ptr, self->b_size)); +} + +static PyObject * +PyCData_setstate(PyObject *myself, PyObject *args) +{ + void *data; + Py_ssize_t len; + int res; + PyObject *dict, *mydict; + CDataObject *self = (CDataObject *)myself; + if (!PyArg_ParseTuple(args, "O!s#", + &PyDict_Type, &dict, &data, &len)) + { + return NULL; + } + if (len > self->b_size) + len = self->b_size; + memmove(self->b_ptr, data, len); + mydict = PyObject_GetAttrString(myself, "__dict__"); + if (mydict == NULL) { + return NULL; + } + if (!PyDict_Check(mydict)) { + PyErr_Format(PyExc_TypeError, + "%.200s.__dict__ must be a dictionary, not %.200s", + Py_TYPE(myself)->tp_name, Py_TYPE(mydict)->tp_name); + Py_DECREF(mydict); + return NULL; + } + res = PyDict_Update(mydict, dict); + Py_DECREF(mydict); + if (res == -1) + return NULL; + Py_RETURN_NONE; +} + +/* + * default __ctypes_from_outparam__ method returns self. + */ +static PyObject * +PyCData_from_outparam(PyObject *self, PyObject *args) +{ + Py_INCREF(self); + return self; +} + +static PyMethodDef PyCData_methods[] = { + { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, }, + { "__reduce__", PyCData_reduce, METH_NOARGS, }, + { "__setstate__", PyCData_setstate, METH_VARARGS, }, + { NULL, NULL }, +}; + +PyTypeObject PyCData_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes._CData", + sizeof(CDataObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + PyCData_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + PyCData_nohash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + &PyCData_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "XXX to be provided", /* tp_doc */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyCData_methods, /* tp_methods */ + PyCData_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ +}; + +static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict) +{ + if ((size_t)dict->size <= sizeof(obj->b_value)) { + /* No need to call malloc, can use the default buffer */ + obj->b_ptr = (char *)&obj->b_value; + /* The b_needsfree flag does not mean that we actually did + call PyMem_Malloc to allocate the memory block; instead it + means we are the *owner* of the memory and are responsible + for freeing resources associated with the memory. This is + also the reason that b_needsfree is exposed to Python. + */ + obj->b_needsfree = 1; + } else { + /* In python 2.4, and ctypes 0.9.6, the malloc call took about + 33% of the creation time for c_int(). + */ + obj->b_ptr = (char *)PyMem_Malloc(dict->size); + if (obj->b_ptr == NULL) { + PyErr_NoMemory(); + return -1; + } + obj->b_needsfree = 1; + memset(obj->b_ptr, 0, dict->size); + } + obj->b_size = dict->size; + return 0; +} + +PyObject * +PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr) +{ + CDataObject *cmem; + StgDictObject *dict; + + assert(PyType_Check(type)); + dict = PyType_stgdict(type); + if (!dict) { + PyErr_SetString(PyExc_TypeError, + "abstract class"); + return NULL; + } + dict->flags |= DICTFLAG_FINAL; + cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0); + if (cmem == NULL) + return NULL; + assert(CDataObject_Check(cmem)); + + cmem->b_length = dict->length; + cmem->b_size = dict->size; + if (base) { /* use base's buffer */ + assert(CDataObject_Check(base)); + cmem->b_ptr = adr; + cmem->b_needsfree = 0; + Py_INCREF(base); + cmem->b_base = (CDataObject *)base; + cmem->b_index = index; + } else { /* copy contents of adr */ + if (-1 == PyCData_MallocBuffer(cmem, dict)) { + Py_DECREF(cmem); + return NULL; + } + memcpy(cmem->b_ptr, adr, dict->size); + cmem->b_index = index; + } + return (PyObject *)cmem; +} + +/* + Box a memory block into a CData instance. +*/ +PyObject * +PyCData_AtAddress(PyObject *type, void *buf) +{ + CDataObject *pd; + StgDictObject *dict; + + if (PySys_Audit("ctypes.cdata", "n", (Py_ssize_t)buf) < 0) { return NULL; } - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for pointer instances */ - return PyCData_FromBaseObj(stgdict->proto, - (PyObject *)self, 0, - *(void **)self->b_ptr); -} - -static int -Pointer_set_contents(CDataObject *self, PyObject *value, void *closure) -{ - StgDictObject *stgdict; - CDataObject *dst; - PyObject *keep; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "Pointer does not support item deletion"); + assert(PyType_Check(type)); + dict = PyType_stgdict(type); + if (!dict) { + PyErr_SetString(PyExc_TypeError, + "abstract class"); + return NULL; + } + dict->flags |= DICTFLAG_FINAL; + + pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0); + if (!pd) + return NULL; + assert(CDataObject_Check(pd)); + pd->b_ptr = (char *)buf; + pd->b_length = dict->length; + pd->b_size = dict->size; + return (PyObject *)pd; +} + +/* + This function returns TRUE for c_int, c_void_p, and these kind of + classes. FALSE otherwise FALSE also for subclasses of c_int and + such. +*/ +int _ctypes_simple_instance(PyObject *obj) +{ + PyTypeObject *type = (PyTypeObject *)obj; + + if (PyCSimpleTypeObject_Check(type)) + return type->tp_base != &Simple_Type; + return 0; +} + +PyObject * +PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, + Py_ssize_t index, Py_ssize_t size, char *adr) +{ + StgDictObject *dict; + if (getfunc) + return getfunc(adr, size); + assert(type); + dict = PyType_stgdict(type); + if (dict && dict->getfunc && !_ctypes_simple_instance(type)) + return dict->getfunc(adr, size); + return PyCData_FromBaseObj(type, src, index, adr); +} + +/* + Helper function for PyCData_set below. +*/ +static PyObject * +_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, + Py_ssize_t size, char *ptr) +{ + CDataObject *src; + int err; + + if (setfunc) + return setfunc(ptr, value, size); + + if (!CDataObject_Check(value)) { + StgDictObject *dict = PyType_stgdict(type); + if (dict && dict->setfunc) + return dict->setfunc(ptr, value, size); + /* + If value is a tuple, we try to call the type with the tuple + and use the result! + */ + assert(PyType_Check(type)); + if (PyTuple_Check(value)) { + PyObject *ob; + PyObject *result; + ob = PyObject_CallObject(type, value); + if (ob == NULL) { + _ctypes_extend_error(PyExc_RuntimeError, "(%s) ", + ((PyTypeObject *)type)->tp_name); + return NULL; + } + result = _PyCData_set(dst, type, setfunc, ob, + size, ptr); + Py_DECREF(ob); + return result; + } else if (value == Py_None && PyCPointerTypeObject_Check(type)) { + *(void **)ptr = NULL; + Py_RETURN_NONE; + } else { + PyErr_Format(PyExc_TypeError, + "expected %s instance, got %s", + ((PyTypeObject *)type)->tp_name, + Py_TYPE(value)->tp_name); + return NULL; + } + } + src = (CDataObject *)value; + + err = PyObject_IsInstance(value, type); + if (err == -1) + return NULL; + if (err) { + memcpy(ptr, + src->b_ptr, + size); + + if (PyCPointerTypeObject_Check(type)) { + /* XXX */ + } + + value = GetKeepedObjects(src); + if (value == NULL) + return NULL; + + Py_INCREF(value); + return value; + } + + if (PyCPointerTypeObject_Check(type) + && ArrayObject_Check(value)) { + StgDictObject *p1, *p2; + PyObject *keep; + p1 = PyObject_stgdict(value); + assert(p1); /* Cannot be NULL for array instances */ + p2 = PyType_stgdict(type); + assert(p2); /* Cannot be NULL for pointer types */ + + if (p1->proto != p2->proto) { + PyErr_Format(PyExc_TypeError, + "incompatible types, %s instance instead of %s instance", + Py_TYPE(value)->tp_name, + ((PyTypeObject *)type)->tp_name); + return NULL; + } + *(void **)ptr = src->b_ptr; + + keep = GetKeepedObjects(src); + if (keep == NULL) + return NULL; + + /* + We are assigning an array object to a field which represents + a pointer. This has the same effect as converting an array + into a pointer. So, again, we have to keep the whole object + pointed to (which is the array in this case) alive, and not + only it's object list. So we create a tuple, containing + b_objects list PLUS the array itself, and return that! + */ + return PyTuple_Pack(2, keep, value); + } + PyErr_Format(PyExc_TypeError, + "incompatible types, %s instance instead of %s instance", + Py_TYPE(value)->tp_name, + ((PyTypeObject *)type)->tp_name); + return NULL; +} + +/* + * Set a slice in object 'dst', which has the type 'type', + * to the value 'value'. + */ +int +PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, + Py_ssize_t index, Py_ssize_t size, char *ptr) +{ + CDataObject *mem = (CDataObject *)dst; + PyObject *result; + + if (!CDataObject_Check(dst)) { + PyErr_SetString(PyExc_TypeError, + "not a ctype instance"); + return -1; + } + + result = _PyCData_set(mem, type, setfunc, value, + size, ptr); + if (result == NULL) + return -1; + + /* KeepRef steals a refcount from it's last argument */ + /* If KeepRef fails, we are stumped. The dst memory block has already + been changed */ + return KeepRef(mem, index, result); +} + + +/******************************************************************/ +static PyObject * +GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + CDataObject *obj; + StgDictObject *dict; + + dict = PyType_stgdict((PyObject *)type); + if (!dict) { + PyErr_SetString(PyExc_TypeError, + "abstract class"); + return NULL; + } + dict->flags |= DICTFLAG_FINAL; + + obj = (CDataObject *)type->tp_alloc(type, 0); + if (!obj) + return NULL; + + obj->b_base = NULL; + obj->b_index = 0; + obj->b_objects = NULL; + obj->b_length = dict->length; + + if (-1 == PyCData_MallocBuffer(obj, dict)) { + Py_DECREF(obj); + return NULL; + } + return (PyObject *)obj; +} +/*****************************************************************/ +/* + PyCFuncPtr_Type +*/ + +static int +PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) +{ + if (ob && !PyCallable_Check(ob)) { + PyErr_SetString(PyExc_TypeError, + "the errcheck attribute must be callable"); + return -1; + } + Py_XINCREF(ob); + Py_XSETREF(self->errcheck, ob); + return 0; +} + +static PyObject * +PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) +{ + if (self->errcheck) { + Py_INCREF(self->errcheck); + return self->errcheck; + } + Py_RETURN_NONE; +} + +static int +PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) +{ + _Py_IDENTIFIER(_check_retval_); + PyObject *checker, *oldchecker; + if (ob == NULL) { + oldchecker = self->checker; + self->checker = NULL; + Py_CLEAR(self->restype); + Py_XDECREF(oldchecker); + return 0; + } + if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { + PyErr_SetString(PyExc_TypeError, + "restype must be a type, a callable, or None"); + return -1; + } + if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, &checker) < 0) { return -1; } - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for pointer instances */ - assert(stgdict->proto); - if (!CDataObject_Check(value)) { - int res = PyObject_IsInstance(value, stgdict->proto); - if (res == -1) - return -1; - if (!res) { - PyErr_Format(PyExc_TypeError, - "expected %s instead of %s", - ((PyTypeObject *)(stgdict->proto))->tp_name, - Py_TYPE(value)->tp_name); - return -1; - } + oldchecker = self->checker; + self->checker = checker; + Py_INCREF(ob); + Py_XSETREF(self->restype, ob); + Py_XDECREF(oldchecker); + return 0; +} + +static PyObject * +PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) +{ + StgDictObject *dict; + if (self->restype) { + Py_INCREF(self->restype); + return self->restype; + } + dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ + if (dict->restype) { + Py_INCREF(dict->restype); + return dict->restype; + } else { + Py_RETURN_NONE; + } +} + +static int +PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) +{ + PyObject *converters; + + if (ob == NULL || ob == Py_None) { + Py_CLEAR(self->converters); + Py_CLEAR(self->argtypes); + } else { + converters = converters_from_argtypes(ob); + if (!converters) + return -1; + Py_XSETREF(self->converters, converters); + Py_INCREF(ob); + Py_XSETREF(self->argtypes, ob); + } + return 0; +} + +static PyObject * +PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) +{ + StgDictObject *dict; + if (self->argtypes) { + Py_INCREF(self->argtypes); + return self->argtypes; + } + dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ + if (dict->argtypes) { + Py_INCREF(dict->argtypes); + return dict->argtypes; + } else { + Py_RETURN_NONE; + } +} + +static PyGetSetDef PyCFuncPtr_getsets[] = { + { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck, + "a function to check for errors", NULL }, + { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype, + "specify the result type", NULL }, + { "argtypes", (getter)PyCFuncPtr_get_argtypes, + (setter)PyCFuncPtr_set_argtypes, + "specify the argument types", NULL }, + { NULL, NULL } +}; + +#ifdef MS_WIN32 +static PPROC FindAddress(void *handle, const char *name, PyObject *type) +{ + PPROC address; +#ifdef MS_WIN64 + /* win64 has no stdcall calling conv, so it should + also not have the name mangling of it. + */ + Py_BEGIN_ALLOW_THREADS + address = (PPROC)GetProcAddress(handle, name); + Py_END_ALLOW_THREADS + return address; +#else + char *mangled_name; + int i; + StgDictObject *dict; + + Py_BEGIN_ALLOW_THREADS + address = (PPROC)GetProcAddress(handle, name); + Py_END_ALLOW_THREADS + if (address) + return address; + if (((size_t)name & ~0xFFFF) == 0) { + return NULL; + } + + dict = PyType_stgdict((PyObject *)type); + /* It should not happen that dict is NULL, but better be safe */ + if (dict==NULL || dict->flags & FUNCFLAG_CDECL) + return address; + + /* for stdcall, try mangled names: + funcname -> _funcname@ + where n is 0, 4, 8, 12, ..., 128 + */ + mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */ + if (!mangled_name) + return NULL; + for (i = 0; i < 32; ++i) { + sprintf(mangled_name, "_%s@%d", name, i*4); + Py_BEGIN_ALLOW_THREADS + address = (PPROC)GetProcAddress(handle, mangled_name); + Py_END_ALLOW_THREADS + if (address) + return address; + } + return NULL; +#endif +} +#endif + +/* Return 1 if usable, 0 else and exception set. */ +static int +_check_outarg_type(PyObject *arg, Py_ssize_t index) +{ + StgDictObject *dict; + + if (PyCPointerTypeObject_Check(arg)) + return 1; + + if (PyCArrayTypeObject_Check(arg)) + return 1; + + dict = PyType_stgdict(arg); + if (dict + /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */ + && PyUnicode_Check(dict->proto) +/* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */ + && (strchr("PzZ", PyUnicode_AsUTF8(dict->proto)[0]))) { + return 1; + } + + PyErr_Format(PyExc_TypeError, + "'out' parameter %d must be a pointer type, not %s", + Py_SAFE_DOWNCAST(index, Py_ssize_t, int), + PyType_Check(arg) ? + ((PyTypeObject *)arg)->tp_name : + Py_TYPE(arg)->tp_name); + return 0; +} + +/* Returns 1 on success, 0 on error */ +static int +_validate_paramflags(PyTypeObject *type, PyObject *paramflags) +{ + Py_ssize_t i, len; + StgDictObject *dict; + PyObject *argtypes; + + dict = PyType_stgdict((PyObject *)type); + if (!dict) { + PyErr_SetString(PyExc_TypeError, + "abstract class"); + return 0; + } + argtypes = dict->argtypes; + + if (paramflags == NULL || dict->argtypes == NULL) + return 1; + + if (!PyTuple_Check(paramflags)) { + PyErr_SetString(PyExc_TypeError, + "paramflags must be a tuple or None"); + return 0; + } + + len = PyTuple_GET_SIZE(paramflags); + if (len != PyTuple_GET_SIZE(dict->argtypes)) { + PyErr_SetString(PyExc_ValueError, + "paramflags must have the same length as argtypes"); + return 0; + } + + for (i = 0; i < len; ++i) { + PyObject *item = PyTuple_GET_ITEM(paramflags, i); + int flag; + char *name; + PyObject *defval; + PyObject *typ; + if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) { + PyErr_SetString(PyExc_TypeError, + "paramflags must be a sequence of (int [,string [,value]]) tuples"); + return 0; + } + typ = PyTuple_GET_ITEM(argtypes, i); + switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) { + case 0: + case PARAMFLAG_FIN: + case PARAMFLAG_FIN | PARAMFLAG_FLCID: + case PARAMFLAG_FIN | PARAMFLAG_FOUT: + break; + case PARAMFLAG_FOUT: + if (!_check_outarg_type(typ, i+1)) + return 0; + break; + default: + PyErr_Format(PyExc_TypeError, + "paramflag value %d not supported", + flag); + return 0; + } + } + return 1; +} + +static int +_get_name(PyObject *obj, const char **pname) +{ +#ifdef MS_WIN32 + if (PyLong_Check(obj)) { + /* We have to use MAKEINTRESOURCEA for Windows CE. + Works on Windows as well, of course. + */ + *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF); + return 1; + } +#endif + if (PyBytes_Check(obj)) { + *pname = PyBytes_AS_STRING(obj); + return *pname ? 1 : 0; + } + if (PyUnicode_Check(obj)) { + *pname = PyUnicode_AsUTF8(obj); + return *pname ? 1 : 0; + } + PyErr_SetString(PyExc_TypeError, + "function name must be string, bytes object or integer"); + return 0; +} + + +static PyObject * +PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + const char *name; + int (* address)(void); + PyObject *ftuple; + PyObject *dll; + PyObject *obj; + PyCFuncPtrObject *self; + void *handle; + PyObject *paramflags = NULL; + + if (!PyArg_ParseTuple(args, "O|O", &ftuple, ¶mflags)) + return NULL; + if (paramflags == Py_None) + paramflags = NULL; + + ftuple = PySequence_Tuple(ftuple); + if (!ftuple) + /* Here ftuple is a borrowed reference */ + return NULL; + + if (!PyArg_ParseTuple(ftuple, "O&O;illegal func_spec argument", + _get_name, &name, &dll)) + { + Py_DECREF(ftuple); + return NULL; + } + +#ifdef MS_WIN32 + if (PySys_Audit("ctypes.dlsym", + ((uintptr_t)name & ~0xFFFF) ? "Os" : "On", + dll, name) < 0) { + Py_DECREF(ftuple); + return NULL; } - - dst = (CDataObject *)value; - *(void **)self->b_ptr = dst->b_ptr; - - /* - A Pointer instance must keep the value it points to alive. So, a - pointer instance has b_length set to 2 instead of 1, and we set - 'value' itself as the second item of the b_objects list, additionally. - */ - Py_INCREF(value); - if (-1 == KeepRef(self, 1, value)) - return -1; - - keep = GetKeepedObjects(dst); - if (keep == NULL) - return -1; - - Py_INCREF(keep); - return KeepRef(self, 0, keep); -} - -static PyGetSetDef Pointer_getsets[] = { - { "contents", (getter)Pointer_get_contents, - (setter)Pointer_set_contents, - "the object this pointer points to (read-write)", NULL }, - { NULL, NULL } -}; - -static int -Pointer_init(CDataObject *self, PyObject *args, PyObject *kw) -{ - PyObject *value = NULL; - - if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value)) - return -1; - if (value == NULL) - return 0; - return Pointer_set_contents(self, value, NULL); -} - -static PyObject * -Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - StgDictObject *dict = PyType_stgdict((PyObject *)type); - if (!dict || !dict->proto) { - PyErr_SetString(PyExc_TypeError, - "Cannot create instance: has no _type_"); +#else + if (PySys_Audit("ctypes.dlsym", "Os", dll, name) < 0) { + Py_DECREF(ftuple); return NULL; } - return GenericPyCData_new(type, args, kw); -} +#endif -static PyObject * -Pointer_subscript(PyObject *myself, PyObject *item) -{ - CDataObject *self = (CDataObject *)myself; - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return NULL; - return Pointer_item(myself, i); + obj = PyObject_GetAttrString(dll, "_handle"); + if (!obj) { + Py_DECREF(ftuple); + return NULL; + } + if (!PyLong_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "the _handle attribute of the second argument must be an integer"); + Py_DECREF(ftuple); + Py_DECREF(obj); + return NULL; + } + handle = (void *)PyLong_AsVoidPtr(obj); + Py_DECREF(obj); + if (PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "could not convert the _handle attribute to a pointer"); + Py_DECREF(ftuple); + return NULL; + } + +#ifdef MS_WIN32 + address = FindAddress(handle, name, (PyObject *)type); + if (!address) { + if (!IS_INTRESOURCE(name)) + PyErr_Format(PyExc_AttributeError, + "function '%s' not found", + name); + else + PyErr_Format(PyExc_AttributeError, + "function ordinal %d not found", + (WORD)(size_t)name); + Py_DECREF(ftuple); + return NULL; + } +#else + address = (PPROC)ctypes_dlsym(handle, name); + if (!address) { +#ifdef __CYGWIN__ +/* dlerror() isn't very helpful on cygwin */ + PyErr_Format(PyExc_AttributeError, + "function '%s' not found", + name); +#else + PyErr_SetString(PyExc_AttributeError, ctypes_dlerror()); +#endif + Py_DECREF(ftuple); + return NULL; + } +#endif + if (!_validate_paramflags(type, paramflags)) { + Py_DECREF(ftuple); + return NULL; + } + + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); + if (!self) { + Py_DECREF(ftuple); + return NULL; + } + + Py_XINCREF(paramflags); + self->paramflags = paramflags; + + *(void **)self->b_ptr = address; + Py_INCREF(dll); + Py_DECREF(ftuple); + if (-1 == KeepRef((CDataObject *)self, 0, dll)) { + Py_DECREF((PyObject *)self); + return NULL; + } + + Py_INCREF(self); + self->callable = (PyObject *)self; + return (PyObject *)self; +} + +#ifdef MS_WIN32 +static PyObject * +PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyCFuncPtrObject *self; + int index; + char *name = NULL; + PyObject *paramflags = NULL; + GUID *iid = NULL; + Py_ssize_t iid_len = 0; + + if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, ¶mflags, &iid, &iid_len)) + return NULL; + if (paramflags == Py_None) + paramflags = NULL; + + if (!_validate_paramflags(type, paramflags)) + return NULL; + + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); + self->index = index + 0x1000; + Py_XINCREF(paramflags); + self->paramflags = paramflags; + if (iid_len == sizeof(GUID)) + self->iid = iid; + return (PyObject *)self; +} +#endif + +/* + PyCFuncPtr_new accepts different argument lists in addition to the standard + _basespec_ keyword arg: + + one argument form + "i" - function address + "O" - must be a callable, creates a C callable function + + two or more argument forms (the third argument is a paramflags tuple) + "(sO)|..." - (function name, dll object (with an integer handle)), paramflags + "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags + "is|..." - vtable index, method name, creates callable calling COM vtbl +*/ +static PyObject * +PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyCFuncPtrObject *self; + PyObject *callable; + StgDictObject *dict; + CThunkObject *thunk; + + if (PyTuple_GET_SIZE(args) == 0) + return GenericPyCData_new(type, args, kwds); + + if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0))) + return PyCFuncPtr_FromDll(type, args, kwds); + +#ifdef MS_WIN32 + if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0))) + return PyCFuncPtr_FromVtblIndex(type, args, kwds); +#endif + + if (1 == PyTuple_GET_SIZE(args) + && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) { + CDataObject *ob; + void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0)); + if (ptr == NULL && PyErr_Occurred()) + return NULL; + ob = (CDataObject *)GenericPyCData_new(type, args, kwds); + if (ob == NULL) + return NULL; + *(void **)ob->b_ptr = ptr; + return (PyObject *)ob; + } + + if (!PyArg_ParseTuple(args, "O", &callable)) + return NULL; + if (!PyCallable_Check(callable)) { + PyErr_SetString(PyExc_TypeError, + "argument must be callable or integer function address"); + return NULL; + } + + /* XXX XXX This would allow passing additional options. For COM + method *implementations*, we would probably want different + behaviour than in 'normal' callback functions: return a HRESULT if + an exception occurs in the callback, and print the traceback not + only on the console, but also to OutputDebugString() or something + like that. + */ +/* + if (kwds && _PyDict_GetItemIdWithError(kwds, &PyId_options)) { + ... + } + else if (PyErr_Occurred()) { + return NULL; } - else if (PySlice_Check(item)) { - PySliceObject *slice = (PySliceObject *)item; - Py_ssize_t start, stop, step; - PyObject *np; - StgDictObject *stgdict, *itemdict; - PyObject *proto; - Py_ssize_t i, len; - size_t cur; - - /* Since pointers have no length, and we want to apply - different semantics to negative indices than normal - slicing, we have to dissect the slice object ourselves.*/ - if (slice->step == Py_None) { - step = 1; - } - else { - step = PyNumber_AsSsize_t(slice->step, - PyExc_ValueError); - if (step == -1 && PyErr_Occurred()) - return NULL; - if (step == 0) { - PyErr_SetString(PyExc_ValueError, - "slice step cannot be zero"); - return NULL; - } - } - if (slice->start == Py_None) { - if (step < 0) { - PyErr_SetString(PyExc_ValueError, - "slice start is required " - "for step < 0"); - return NULL; - } - start = 0; - } - else { - start = PyNumber_AsSsize_t(slice->start, - PyExc_ValueError); - if (start == -1 && PyErr_Occurred()) - return NULL; +*/ + + dict = PyType_stgdict((PyObject *)type); + /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */ + if (!dict || !dict->argtypes) { + PyErr_SetString(PyExc_TypeError, + "cannot construct instance of this class:" + " no argtypes"); + return NULL; + } + + thunk = _ctypes_alloc_callback(callable, + dict->argtypes, + dict->restype, + dict->flags); + if (!thunk) + return NULL; + + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); + if (self == NULL) { + Py_DECREF(thunk); + return NULL; + } + + Py_INCREF(callable); + self->callable = callable; + + self->thunk = thunk; + *(void **)self->b_ptr = (void *)thunk->pcl_exec; + + Py_INCREF((PyObject *)thunk); /* for KeepRef */ + if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) { + Py_DECREF((PyObject *)self); + return NULL; + } + return (PyObject *)self; +} + + +/* + _byref consumes a refcount to its argument +*/ +static PyObject * +_byref(PyObject *obj) +{ + PyCArgObject *parg; + if (!CDataObject_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "expected CData instance"); + return NULL; + } + + parg = PyCArgObject_new(); + if (parg == NULL) { + Py_DECREF(obj); + return NULL; + } + + parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; + parg->obj = obj; + parg->value.p = ((CDataObject *)obj)->b_ptr; + return (PyObject *)parg; +} + +static PyObject * +_get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds) +{ + PyObject *v; + + if (*pindex < PyTuple_GET_SIZE(inargs)) { + v = PyTuple_GET_ITEM(inargs, *pindex); + ++*pindex; + Py_INCREF(v); + return v; + } + if (kwds && name) { + v = PyDict_GetItemWithError(kwds, name); + if (v) { + ++*pindex; + Py_INCREF(v); + return v; } - if (slice->stop == Py_None) { - PyErr_SetString(PyExc_ValueError, - "slice stop is required"); + else if (PyErr_Occurred()) { return NULL; } - stop = PyNumber_AsSsize_t(slice->stop, - PyExc_ValueError); - if (stop == -1 && PyErr_Occurred()) - return NULL; - if ((step > 0 && start > stop) || - (step < 0 && start < stop)) - len = 0; - else if (step > 0) - len = (stop - start - 1) / step + 1; - else - len = (stop - start + 1) / step + 1; - - stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); /* Cannot be NULL for pointer instances */ - proto = stgdict->proto; - assert(proto); - itemdict = PyType_stgdict(proto); - assert(itemdict); - if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { - char *ptr = *(char **)self->b_ptr; - char *dest; - - if (len <= 0) - return PyBytes_FromStringAndSize("", 0); - if (step == 1) { - return PyBytes_FromStringAndSize(ptr + start, - len); - } - dest = (char *)PyMem_Malloc(len); - if (dest == NULL) - return PyErr_NoMemory(); - for (cur = start, i = 0; i < len; cur += step, i++) { - dest[i] = ptr[cur]; - } - np = PyBytes_FromStringAndSize(dest, len); - PyMem_Free(dest); - return np; + } + if (defval) { + Py_INCREF(defval); + return defval; + } + /* we can't currently emit a better error message */ + if (name) + PyErr_Format(PyExc_TypeError, + "required argument '%S' missing", name); + else + PyErr_Format(PyExc_TypeError, + "not enough arguments"); + return NULL; +} + +/* + This function implements higher level functionality plus the ability to call + functions with keyword arguments by looking at parameter flags. parameter + flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer + specifying the direction of the data transfer for this parameter - 'in', + 'out' or 'inout' (zero means the same as 'in'). The second entry is the + parameter name, and the third is the default value if the parameter is + missing in the function call. + + This function builds and returns a new tuple 'callargs' which contains the + parameters to use in the call. Items on this tuple are copied from the + 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the + 'argtypes' tuple for 'out' parameters. It also calculates numretvals which + is the number of return values for the function, outmask/inoutmask are + bitmasks containing indexes into the callargs tuple specifying which + parameters have to be returned. _build_result builds the return value of the + function. +*/ +static PyObject * +_build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, + PyObject *inargs, PyObject *kwds, + int *poutmask, int *pinoutmask, unsigned int *pnumretvals) +{ + PyObject *paramflags = self->paramflags; + PyObject *callargs; + StgDictObject *dict; + Py_ssize_t i, len; + int inargs_index = 0; + /* It's a little bit difficult to determine how many arguments the + function call requires/accepts. For simplicity, we count the consumed + args and compare this to the number of supplied args. */ + Py_ssize_t actual_args; + + *poutmask = 0; + *pinoutmask = 0; + *pnumretvals = 0; + + /* Trivial cases, where we either return inargs itself, or a slice of it. */ + if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) { +#ifdef MS_WIN32 + if (self->index) + return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs)); +#endif + Py_INCREF(inargs); + return inargs; + } + + len = PyTuple_GET_SIZE(argtypes); + callargs = PyTuple_New(len); /* the argument tuple we build */ + if (callargs == NULL) + return NULL; + +#ifdef MS_WIN32 + /* For a COM method, skip the first arg */ + if (self->index) { + inargs_index = 1; + } +#endif + for (i = 0; i < len; ++i) { + PyObject *item = PyTuple_GET_ITEM(paramflags, i); + PyObject *ob; + unsigned int flag; + PyObject *name = NULL; + PyObject *defval = NULL; + + /* This way seems to be ~2 us faster than the PyArg_ParseTuple + calls below. */ + /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */ + Py_ssize_t tsize = PyTuple_GET_SIZE(item); + flag = PyLong_AsUnsignedLongMask(PyTuple_GET_ITEM(item, 0)); + name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL; + defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL; + + switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) { + case PARAMFLAG_FIN | PARAMFLAG_FLCID: + /* ['in', 'lcid'] parameter. Always taken from defval, + if given, else the integer 0. */ + if (defval == NULL) + defval = _PyLong_Zero; + Py_INCREF(defval); + PyTuple_SET_ITEM(callargs, i, defval); + break; + case (PARAMFLAG_FIN | PARAMFLAG_FOUT): + *pinoutmask |= (1 << i); /* mark as inout arg */ + (*pnumretvals)++; + /* fall through */ + case 0: + case PARAMFLAG_FIN: + /* 'in' parameter. Copy it from inargs. */ + ob =_get_arg(&inargs_index, name, defval, inargs, kwds); + if (ob == NULL) + goto error; + PyTuple_SET_ITEM(callargs, i, ob); + break; + case PARAMFLAG_FOUT: + /* XXX Refactor this code into a separate function. */ + /* 'out' parameter. + argtypes[i] must be a POINTER to a c type. + + Cannot by supplied in inargs, but a defval will be used + if available. XXX Should we support getting it from kwds? + */ + if (defval) { + /* XXX Using mutable objects as defval will + make the function non-threadsafe, unless we + copy the object in each invocation */ + Py_INCREF(defval); + PyTuple_SET_ITEM(callargs, i, defval); + *poutmask |= (1 << i); /* mark as out arg */ + (*pnumretvals)++; + break; + } + ob = PyTuple_GET_ITEM(argtypes, i); + dict = PyType_stgdict(ob); + if (dict == NULL) { + /* Cannot happen: _validate_paramflags() + would not accept such an object */ + PyErr_Format(PyExc_RuntimeError, + "NULL stgdict unexpected"); + goto error; + } + if (PyUnicode_Check(dict->proto)) { + PyErr_Format( + PyExc_TypeError, + "%s 'out' parameter must be passed as default value", + ((PyTypeObject *)ob)->tp_name); + goto error; + } + if (PyCArrayTypeObject_Check(ob)) + ob = _PyObject_CallNoArg(ob); + else + /* Create an instance of the pointed-to type */ + ob = _PyObject_CallNoArg(dict->proto); + /* + XXX Is the following correct any longer? + We must not pass a byref() to the array then but + the array instance itself. Then, we cannot retrieve + the result from the PyCArgObject. + */ + if (ob == NULL) + goto error; + /* The .from_param call that will occur later will pass this + as a byref parameter. */ + PyTuple_SET_ITEM(callargs, i, ob); + *poutmask |= (1 << i); /* mark as out arg */ + (*pnumretvals)++; + break; + default: + PyErr_Format(PyExc_ValueError, + "paramflag %u not yet implemented", flag); + goto error; + break; + } + } + + /* We have counted the arguments we have consumed in 'inargs_index'. This + must be the same as len(inargs) + len(kwds), otherwise we have + either too much or not enough arguments. */ + + actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_GET_SIZE(kwds) : 0); + if (actual_args != inargs_index) { + /* When we have default values or named parameters, this error + message is misleading. See unittests/test_paramflags.py + */ + PyErr_Format(PyExc_TypeError, + "call takes exactly %d arguments (%zd given)", + inargs_index, actual_args); + goto error; + } + + /* outmask is a bitmask containing indexes into callargs. Items at + these indexes contain values to return. + */ + return callargs; + error: + Py_DECREF(callargs); + return NULL; +} + +/* See also: + http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp +*/ +/* + Build return value of a function. + + Consumes the refcount on result and callargs. +*/ +static PyObject * +_build_result(PyObject *result, PyObject *callargs, + int outmask, int inoutmask, unsigned int numretvals) +{ + unsigned int i, index; + int bit; + PyObject *tup = NULL; + + if (callargs == NULL) + return result; + if (result == NULL || numretvals == 0) { + Py_DECREF(callargs); + return result; + } + Py_DECREF(result); + + /* tup will not be allocated if numretvals == 1 */ + /* allocate tuple to hold the result */ + if (numretvals > 1) { + tup = PyTuple_New(numretvals); + if (tup == NULL) { + Py_DECREF(callargs); + return NULL; + } + } + + index = 0; + for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) { + PyObject *v; + if (bit & inoutmask) { + v = PyTuple_GET_ITEM(callargs, i); + Py_INCREF(v); + if (numretvals == 1) { + Py_DECREF(callargs); + return v; + } + PyTuple_SET_ITEM(tup, index, v); + index++; + } else if (bit & outmask) { + _Py_IDENTIFIER(__ctypes_from_outparam__); + + v = PyTuple_GET_ITEM(callargs, i); + v = _PyObject_CallMethodIdNoArgs(v, &PyId___ctypes_from_outparam__); + if (v == NULL || numretvals == 1) { + Py_DECREF(callargs); + return v; + } + PyTuple_SET_ITEM(tup, index, v); + index++; + } + if (index == numretvals) + break; + } + + Py_DECREF(callargs); + return tup; +} + +static PyObject * +PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds) +{ + PyObject *restype; + PyObject *converters; + PyObject *checker; + PyObject *argtypes; + StgDictObject *dict = PyObject_stgdict((PyObject *)self); + PyObject *result; + PyObject *callargs; + PyObject *errcheck; +#ifdef MS_WIN32 + IUnknown *piunk = NULL; +#endif + void *pProc = NULL; + + int inoutmask; + int outmask; + unsigned int numretvals; + + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ + restype = self->restype ? self->restype : dict->restype; + converters = self->converters ? self->converters : dict->converters; + checker = self->checker ? self->checker : dict->checker; + argtypes = self->argtypes ? self->argtypes : dict->argtypes; +/* later, we probably want to have an errcheck field in stgdict */ + errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */; + + + pProc = *(void **)self->b_ptr; +#ifdef MS_WIN32 + if (self->index) { + /* It's a COM method */ + CDataObject *this; + this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */ + if (!this) { + PyErr_SetString(PyExc_ValueError, + "native com method call without 'this' parameter"); + return NULL; + } + if (!CDataObject_Check(this)) { + PyErr_SetString(PyExc_TypeError, + "Expected a COM this pointer as first argument"); + return NULL; + } + /* there should be more checks? No, in Python */ + /* First arg is a pointer to an interface instance */ + if (!this->b_ptr || *(void **)this->b_ptr == NULL) { + PyErr_SetString(PyExc_ValueError, + "NULL COM pointer access"); + return NULL; + } + piunk = *(IUnknown **)this->b_ptr; + if (NULL == piunk->lpVtbl) { + PyErr_SetString(PyExc_ValueError, + "COM method call without VTable"); + return NULL; + } + pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000]; + } +#endif + callargs = _build_callargs(self, argtypes, + inargs, kwds, + &outmask, &inoutmask, &numretvals); + if (callargs == NULL) + return NULL; + + if (converters) { + int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters), + Py_ssize_t, int); + int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs), + Py_ssize_t, int); + + if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) { + /* For cdecl functions, we allow more actual arguments + than the length of the argtypes tuple. + */ + if (required > actual) { + Py_DECREF(callargs); + PyErr_Format(PyExc_TypeError, + "this function takes at least %d argument%s (%d given)", + required, + required == 1 ? "" : "s", + actual); + return NULL; + } + } else if (required != actual) { + Py_DECREF(callargs); + PyErr_Format(PyExc_TypeError, + "this function takes %d argument%s (%d given)", + required, + required == 1 ? "" : "s", + actual); + return NULL; + } + } + + result = _ctypes_callproc(pProc, + callargs, +#ifdef MS_WIN32 + piunk, + self->iid, +#endif + dict->flags, + converters, + restype, + checker); +/* The 'errcheck' protocol */ + if (result != NULL && errcheck) { + PyObject *v = PyObject_CallFunctionObjArgs(errcheck, + result, + self, + callargs, + NULL); + /* If the errcheck function failed, return NULL. + If the errcheck function returned callargs unchanged, + continue normal processing. + If the errcheck function returned something else, + use that as result. + */ + if (v == NULL || v != callargs) { + Py_DECREF(result); + Py_DECREF(callargs); + return v; + } + Py_DECREF(v); + } + + return _build_result(result, callargs, + outmask, inoutmask, numretvals); +} + +static int +PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->callable); + Py_VISIT(self->restype); + Py_VISIT(self->checker); + Py_VISIT(self->errcheck); + Py_VISIT(self->argtypes); + Py_VISIT(self->converters); + Py_VISIT(self->paramflags); + Py_VISIT(self->thunk); + return PyCData_traverse((CDataObject *)self, visit, arg); +} + +static int +PyCFuncPtr_clear(PyCFuncPtrObject *self) +{ + Py_CLEAR(self->callable); + Py_CLEAR(self->restype); + Py_CLEAR(self->checker); + Py_CLEAR(self->errcheck); + Py_CLEAR(self->argtypes); + Py_CLEAR(self->converters); + Py_CLEAR(self->paramflags); + Py_CLEAR(self->thunk); + return PyCData_clear((CDataObject *)self); +} + +static void +PyCFuncPtr_dealloc(PyCFuncPtrObject *self) +{ + PyCFuncPtr_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject * +PyCFuncPtr_repr(PyCFuncPtrObject *self) +{ +#ifdef MS_WIN32 + if (self->index) + return PyUnicode_FromFormat("", + self->index - 0x1000, + Py_TYPE(self)->tp_name, + self); +#endif + return PyUnicode_FromFormat("<%s object at %p>", + Py_TYPE(self)->tp_name, + self); +} + +static int +PyCFuncPtr_bool(PyCFuncPtrObject *self) +{ + return ((*(void **)self->b_ptr != NULL) +#ifdef MS_WIN32 + || (self->index != 0) +#endif + ); +} + +static PyNumberMethods PyCFuncPtr_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + (inquiry)PyCFuncPtr_bool, /* nb_bool */ +}; + +PyTypeObject PyCFuncPtr_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.PyCFuncPtr", + sizeof(PyCFuncPtrObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)PyCFuncPtr_repr, /* tp_repr */ + &PyCFuncPtr_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)PyCFuncPtr_call, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + &PyCData_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Function Pointer", /* tp_doc */ + (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */ + (inquiry)PyCFuncPtr_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + PyCFuncPtr_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyCFuncPtr_new, /* tp_new */ + 0, /* tp_free */ +}; + +/*****************************************************************/ +/* + Struct_Type +*/ +/* + This function is called to initialize a Structure or Union with positional + arguments. It calls itself recursively for all Structure or Union base + classes, then retrieves the _fields_ member to associate the argument + position with the correct field name. + + Returns -1 on error, or the index of next argument on success. + */ +static Py_ssize_t +_init_pos_args(PyObject *self, PyTypeObject *type, + PyObject *args, PyObject *kwds, + Py_ssize_t index) +{ + StgDictObject *dict; + PyObject *fields; + Py_ssize_t i; + _Py_IDENTIFIER(_fields_); + + if (PyType_stgdict((PyObject *)type->tp_base)) { + index = _init_pos_args(self, type->tp_base, + args, kwds, + index); + if (index == -1) + return -1; + } + + dict = PyType_stgdict((PyObject *)type); + fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_); + if (fields == NULL) { + if (PyErr_Occurred()) { + return -1; } -#ifdef CTYPES_UNICODE - if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { - wchar_t *ptr = *(wchar_t **)self->b_ptr; - wchar_t *dest; - - if (len <= 0) - return PyUnicode_New(0, 0); - if (step == 1) { - return PyUnicode_FromWideChar(ptr + start, - len); + return index; + } + + for (i = 0; + i < dict->length && (i+index) < PyTuple_GET_SIZE(args); + ++i) { + PyObject *pair = PySequence_GetItem(fields, i); + PyObject *name, *val; + int res; + if (!pair) + return -1; + name = PySequence_GetItem(pair, 0); + if (!name) { + Py_DECREF(pair); + return -1; + } + val = PyTuple_GET_ITEM(args, i + index); + if (kwds) { + if (PyDict_GetItemWithError(kwds, name)) { + PyErr_Format(PyExc_TypeError, + "duplicate values for field %R", + name); + Py_DECREF(pair); + Py_DECREF(name); + return -1; } - dest = PyMem_New(wchar_t, len); - if (dest == NULL) - return PyErr_NoMemory(); - for (cur = start, i = 0; i < len; cur += step, i++) { - dest[i] = ptr[cur]; + else if (PyErr_Occurred()) { + Py_DECREF(pair); + Py_DECREF(name); + return -1; } - np = PyUnicode_FromWideChar(dest, len); - PyMem_Free(dest); - return np; - } -#endif - - np = PyList_New(len); - if (np == NULL) - return NULL; + } + + res = PyObject_SetAttr(self, name, val); + Py_DECREF(pair); + Py_DECREF(name); + if (res == -1) + return -1; + } + return index + dict->length; +} + +static int +Struct_init(PyObject *self, PyObject *args, PyObject *kwds) +{ +/* Optimization possible: Store the attribute names _fields_[x][0] + * in C accessible fields somewhere ? + */ + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, + "args not a tuple?"); + return -1; + } + if (PyTuple_GET_SIZE(args)) { + Py_ssize_t res = _init_pos_args(self, Py_TYPE(self), + args, kwds, 0); + if (res == -1) + return -1; + if (res < PyTuple_GET_SIZE(args)) { + PyErr_SetString(PyExc_TypeError, + "too many initializers"); + return -1; + } + } + + if (kwds) { + PyObject *key, *value; + Py_ssize_t pos = 0; + while(PyDict_Next(kwds, &pos, &key, &value)) { + if (-1 == PyObject_SetAttr(self, key, value)) + return -1; + } + } + return 0; +} + +static PyTypeObject Struct_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.Structure", + sizeof(CDataObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 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 */ + &PyCData_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Structure base class", /* tp_doc */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + Struct_init, /* tp_init */ + 0, /* tp_alloc */ + GenericPyCData_new, /* tp_new */ + 0, /* tp_free */ +}; + +static PyTypeObject Union_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.Union", + sizeof(CDataObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 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 */ + &PyCData_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Union base class", /* tp_doc */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + Struct_init, /* tp_init */ + 0, /* tp_alloc */ + GenericPyCData_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/******************************************************************/ +/* + PyCArray_Type +*/ +static int +Array_init(CDataObject *self, PyObject *args, PyObject *kw) +{ + Py_ssize_t i; + Py_ssize_t n; + + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, + "args not a tuple?"); + return -1; + } + n = PyTuple_GET_SIZE(args); + for (i = 0; i < n; ++i) { + PyObject *v; + v = PyTuple_GET_ITEM(args, i); + if (-1 == PySequence_SetItem((PyObject *)self, i, v)) + return -1; + } + return 0; +} + +static PyObject * +Array_item(PyObject *myself, Py_ssize_t index) +{ + CDataObject *self = (CDataObject *)myself; + Py_ssize_t offset, size; + StgDictObject *stgdict; + + + if (index < 0 || index >= self->b_length) { + PyErr_SetString(PyExc_IndexError, + "invalid index"); + return NULL; + } + + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for array instances */ + /* Would it be clearer if we got the item size from + stgdict->proto's stgdict? + */ + size = stgdict->size / stgdict->length; + offset = index * size; + + return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self, + index, size, self->b_ptr + offset); +} + +static PyObject * +Array_subscript(PyObject *myself, PyObject *item) +{ + CDataObject *self = (CDataObject *)myself; + + 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 += self->b_length; + return Array_item(myself, i); + } + else if (PySlice_Check(item)) { + StgDictObject *stgdict, *itemdict; + PyObject *proto; + PyObject *np; + Py_ssize_t start, stop, step, slicelen, i; + size_t cur; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return NULL; + } + slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step); + + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for array object instances */ + proto = stgdict->proto; + itemdict = PyType_stgdict(proto); + assert(itemdict); /* proto is the item type of the array, a + ctypes type, so this cannot be NULL */ + + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { + char *ptr = (char *)self->b_ptr; + char *dest; + + if (slicelen <= 0) + return PyBytes_FromStringAndSize("", 0); + if (step == 1) { + return PyBytes_FromStringAndSize(ptr + start, + slicelen); + } + dest = (char *)PyMem_Malloc(slicelen); + + if (dest == NULL) + return PyErr_NoMemory(); + + for (cur = start, i = 0; i < slicelen; + cur += step, i++) { + dest[i] = ptr[cur]; + } + + np = PyBytes_FromStringAndSize(dest, slicelen); + PyMem_Free(dest); + return np; + } +#ifdef CTYPES_UNICODE + if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { + wchar_t *ptr = (wchar_t *)self->b_ptr; + wchar_t *dest; + + if (slicelen <= 0) + return PyUnicode_New(0, 0); + if (step == 1) { + return PyUnicode_FromWideChar(ptr + start, + slicelen); + } + + dest = PyMem_New(wchar_t, slicelen); + if (dest == NULL) { + PyErr_NoMemory(); + return NULL; + } + + for (cur = start, i = 0; i < slicelen; + cur += step, i++) { + dest[i] = ptr[cur]; + } + + np = PyUnicode_FromWideChar(dest, slicelen); + PyMem_Free(dest); + return np; + } +#endif + + np = PyList_New(slicelen); + if (np == NULL) + return NULL; + + for (cur = start, i = 0; i < slicelen; + cur += step, i++) { + PyObject *v = Array_item(myself, cur); + if (v == NULL) { + Py_DECREF(np); + return NULL; + } + PyList_SET_ITEM(np, i, v); + } + return np; + } + else { + PyErr_SetString(PyExc_TypeError, + "indices must be integers"); + return NULL; + } + +} + +static int +Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value) +{ + CDataObject *self = (CDataObject *)myself; + Py_ssize_t size, offset; + StgDictObject *stgdict; + char *ptr; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "Array does not support item deletion"); + return -1; + } + + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for array object instances */ + if (index < 0 || index >= stgdict->length) { + PyErr_SetString(PyExc_IndexError, + "invalid index"); + return -1; + } + size = stgdict->size / stgdict->length; + offset = index * size; + ptr = self->b_ptr + offset; + + return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, + index, size, ptr); +} + +static int +Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value) +{ + CDataObject *self = (CDataObject *)myself; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "Array does not support item deletion"); + return -1; + } + + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->b_length; + return Array_ass_item(myself, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelen, otherlen, i; + size_t cur; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return -1; + } + slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step); + if ((step < 0 && start < stop) || + (step > 0 && start > stop)) + stop = start; + + otherlen = PySequence_Length(value); + if (otherlen != slicelen) { + PyErr_SetString(PyExc_ValueError, + "Can only assign sequence of same size"); + return -1; + } + for (cur = start, i = 0; i < otherlen; cur += step, i++) { + PyObject *item = PySequence_GetItem(value, i); + int result; + if (item == NULL) + return -1; + result = Array_ass_item(myself, cur, item); + Py_DECREF(item); + if (result == -1) + return -1; + } + return 0; + } + else { + PyErr_SetString(PyExc_TypeError, + "indices must be integer"); + return -1; + } +} + +static Py_ssize_t +Array_length(PyObject *myself) +{ + CDataObject *self = (CDataObject *)myself; + return self->b_length; +} + +static PyMethodDef Array_methods[] = { + {"__class_getitem__", (PyCFunction)Py_GenericAlias, + METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, + { NULL, NULL } +}; - for (cur = start, i = 0; i < len; cur += step, i++) { - PyObject *v = Pointer_item(myself, cur); - PyList_SET_ITEM(np, i, v); - } - return np; - } - else { - PyErr_SetString(PyExc_TypeError, - "Pointer indices must be integer"); +static PySequenceMethods Array_as_sequence = { + Array_length, /* sq_length; */ + 0, /* sq_concat; */ + 0, /* sq_repeat; */ + Array_item, /* sq_item; */ + 0, /* sq_slice; */ + Array_ass_item, /* sq_ass_item; */ + 0, /* sq_ass_slice; */ + 0, /* sq_contains; */ + + 0, /* sq_inplace_concat; */ + 0, /* sq_inplace_repeat; */ +}; + +static PyMappingMethods Array_as_mapping = { + Array_length, + Array_subscript, + Array_ass_subscript, +}; + +PyTypeObject PyCArray_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.Array", + sizeof(CDataObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &Array_as_sequence, /* tp_as_sequence */ + &Array_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + &PyCData_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "XXX to be provided", /* tp_doc */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Array_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Array_init, /* tp_init */ + 0, /* tp_alloc */ + GenericPyCData_new, /* tp_new */ + 0, /* tp_free */ +}; + +PyObject * +PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length) +{ + static PyObject *cache; + PyObject *key; + PyObject *result; + char name[256]; + PyObject *len; + + if (cache == NULL) { + cache = PyDict_New(); + if (cache == NULL) + return NULL; + } + len = PyLong_FromSsize_t(length); + if (len == NULL) + return NULL; + key = PyTuple_Pack(2, itemtype, len); + Py_DECREF(len); + if (!key) + return NULL; + result = PyDict_GetItemProxy(cache, key); + if (result) { + Py_INCREF(result); + Py_DECREF(key); + return result; + } + else if (PyErr_Occurred()) { + Py_DECREF(key); return NULL; } -} - -static PySequenceMethods Pointer_as_sequence = { - 0, /* inquiry sq_length; */ - 0, /* binaryfunc sq_concat; */ - 0, /* intargfunc sq_repeat; */ - Pointer_item, /* intargfunc sq_item; */ - 0, /* intintargfunc sq_slice; */ - Pointer_ass_item, /* intobjargproc sq_ass_item; */ - 0, /* intintobjargproc sq_ass_slice; */ - 0, /* objobjproc sq_contains; */ - /* Added in release 2.0 */ - 0, /* binaryfunc sq_inplace_concat; */ - 0, /* intargfunc sq_inplace_repeat; */ -}; - -static PyMappingMethods Pointer_as_mapping = { - 0, - Pointer_subscript, -}; - -static int -Pointer_bool(CDataObject *self) -{ - return (*(void **)self->b_ptr != NULL); -} - -static PyNumberMethods Pointer_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - (inquiry)Pointer_bool, /* nb_bool */ -}; - -PyTypeObject PyCPointer_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes._Pointer", - sizeof(CDataObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ + + if (!PyType_Check(itemtype)) { + PyErr_SetString(PyExc_TypeError, + "Expected a type object"); + Py_DECREF(key); + return NULL; + } +#ifdef MS_WIN64 + sprintf(name, "%.200s_Array_%Id", + ((PyTypeObject *)itemtype)->tp_name, length); +#else + sprintf(name, "%.200s_Array_%ld", + ((PyTypeObject *)itemtype)->tp_name, (long)length); +#endif + + result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type, + "s(O){s:n,s:O}", + name, + &PyCArray_Type, + "_length_", + length, + "_type_", + itemtype + ); + if (result == NULL) { + Py_DECREF(key); + return NULL; + } + if (-1 == PyDict_SetItemProxy(cache, key, result)) { + Py_DECREF(key); + Py_DECREF(result); + return NULL; + } + Py_DECREF(key); + return result; +} + + +/******************************************************************/ +/* + Simple_Type +*/ + +static int +Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) +{ + PyObject *result; + StgDictObject *dict = PyObject_stgdict((PyObject *)self); + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete attribute"); + return -1; + } + assert(dict); /* Cannot be NULL for CDataObject instances */ + assert(dict->setfunc); + result = dict->setfunc(self->b_ptr, value, dict->size); + if (!result) + return -1; + + /* consumes the refcount the setfunc returns */ + return KeepRef(self, 0, result); +} + +static int +Simple_init(CDataObject *self, PyObject *args, PyObject *kw) +{ + PyObject *value = NULL; + if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value)) + return -1; + if (value) + return Simple_set_value(self, value, NULL); + return 0; +} + +static PyObject * +Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored)) +{ + StgDictObject *dict; + dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ + assert(dict->getfunc); + return dict->getfunc(self->b_ptr, self->b_size); +} + +static PyGetSetDef Simple_getsets[] = { + { "value", (getter)Simple_get_value, (setter)Simple_set_value, + "current value", NULL }, + { NULL, NULL } +}; + +static PyObject * +Simple_from_outparm(PyObject *self, PyObject *args) +{ + if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) { + Py_INCREF(self); + return self; + } + /* call stgdict->getfunc */ + return Simple_get_value((CDataObject *)self, NULL); +} + +static PyMethodDef Simple_methods[] = { + { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, }, + { NULL, NULL }, +}; + +static int Simple_bool(CDataObject *self) +{ + return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size); +} + +static PyNumberMethods Simple_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + (inquiry)Simple_bool, /* nb_bool */ +}; + +/* "%s(%s)" % (self.__class__.__name__, self.value) */ +static PyObject * +Simple_repr(CDataObject *self) +{ + PyObject *val, *result; + + if (Py_TYPE(self)->tp_base != &Simple_Type) { + return PyUnicode_FromFormat("<%s object at %p>", + Py_TYPE(self)->tp_name, self); + } + + val = Simple_get_value(self, NULL); + if (val == NULL) + return NULL; + + result = PyUnicode_FromFormat("%s(%R)", + Py_TYPE(self)->tp_name, val); + Py_DECREF(val); + return result; +} + +static PyTypeObject Simple_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes._SimpleCData", + sizeof(CDataObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - &Pointer_as_number, /* tp_as_number */ - &Pointer_as_sequence, /* tp_as_sequence */ - &Pointer_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - &PyCData_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ - (traverseproc)PyCData_traverse, /* tp_traverse */ - (inquiry)PyCData_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - Pointer_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)Pointer_init, /* tp_init */ - 0, /* tp_alloc */ - Pointer_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/******************************************************************/ -/* - * Module initialization. - */ - -static const char module_docs[] = -"Create and manipulate C compatible data types in Python."; - -#ifdef MS_WIN32 - -static const char comerror_doc[] = "Raised when a COM method call failed."; - -int -comerror_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - PyObject *hresult, *text, *details; - PyObject *a; - int status; - - if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) - return -1; - - if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details)) - return -1; - - a = PySequence_GetSlice(args, 1, PyTuple_GET_SIZE(args)); - if (!a) - return -1; - status = PyObject_SetAttrString(self, "args", a); - Py_DECREF(a); - if (status < 0) - return -1; - - if (PyObject_SetAttrString(self, "hresult", hresult) < 0) - return -1; - - if (PyObject_SetAttrString(self, "text", text) < 0) - return -1; - - if (PyObject_SetAttrString(self, "details", details) < 0) - return -1; - - Py_INCREF(args); - Py_SETREF(((PyBaseExceptionObject *)self)->args, args); - - return 0; -} - -static PyTypeObject PyComError_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.COMError", /* tp_name */ - sizeof(PyBaseExceptionObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ + (reprfunc)&Simple_repr, /* tp_repr */ + &Simple_as_number, /* 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 */ + &PyCData_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "XXX to be provided", /* tp_doc */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Simple_methods, /* tp_methods */ + 0, /* tp_members */ + Simple_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Simple_init, /* tp_init */ + 0, /* tp_alloc */ + GenericPyCData_new, /* tp_new */ + 0, /* tp_free */ +}; + +/******************************************************************/ +/* + PyCPointer_Type +*/ +static PyObject * +Pointer_item(PyObject *myself, Py_ssize_t index) +{ + CDataObject *self = (CDataObject *)myself; + Py_ssize_t size; + Py_ssize_t offset; + StgDictObject *stgdict, *itemdict; + PyObject *proto; + + if (*(void **)self->b_ptr == NULL) { + PyErr_SetString(PyExc_ValueError, + "NULL pointer access"); + return NULL; + } + + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for pointer object instances */ + + proto = stgdict->proto; + assert(proto); + itemdict = PyType_stgdict(proto); + assert(itemdict); /* proto is the item type of the pointer, a ctypes + type, so this cannot be NULL */ + + size = itemdict->size; + offset = index * itemdict->size; + + return PyCData_get(proto, stgdict->getfunc, (PyObject *)self, + index, size, (*(char **)self->b_ptr) + offset); +} + +static int +Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value) +{ + CDataObject *self = (CDataObject *)myself; + Py_ssize_t size; + Py_ssize_t offset; + StgDictObject *stgdict, *itemdict; + PyObject *proto; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "Pointer does not support item deletion"); + return -1; + } + + if (*(void **)self->b_ptr == NULL) { + PyErr_SetString(PyExc_ValueError, + "NULL pointer access"); + return -1; + } + + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for pointer instances */ + + proto = stgdict->proto; + assert(proto); + + itemdict = PyType_stgdict(proto); + assert(itemdict); /* Cannot be NULL because the itemtype of a pointer + is always a ctypes type */ + + size = itemdict->size; + offset = index * itemdict->size; + + return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value, + index, size, (*(char **)self->b_ptr) + offset); +} + +static PyObject * +Pointer_get_contents(CDataObject *self, void *closure) +{ + StgDictObject *stgdict; + + if (*(void **)self->b_ptr == NULL) { + PyErr_SetString(PyExc_ValueError, + "NULL pointer access"); + return NULL; + } + + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for pointer instances */ + return PyCData_FromBaseObj(stgdict->proto, + (PyObject *)self, 0, + *(void **)self->b_ptr); +} + +static int +Pointer_set_contents(CDataObject *self, PyObject *value, void *closure) +{ + StgDictObject *stgdict; + CDataObject *dst; + PyObject *keep; + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "Pointer does not support item deletion"); + return -1; + } + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for pointer instances */ + assert(stgdict->proto); + if (!CDataObject_Check(value)) { + int res = PyObject_IsInstance(value, stgdict->proto); + if (res == -1) + return -1; + if (!res) { + PyErr_Format(PyExc_TypeError, + "expected %s instead of %s", + ((PyTypeObject *)(stgdict->proto))->tp_name, + Py_TYPE(value)->tp_name); + return -1; + } + } + + dst = (CDataObject *)value; + *(void **)self->b_ptr = dst->b_ptr; + + /* + A Pointer instance must keep the value it points to alive. So, a + pointer instance has b_length set to 2 instead of 1, and we set + 'value' itself as the second item of the b_objects list, additionally. + */ + Py_INCREF(value); + if (-1 == KeepRef(self, 1, value)) + return -1; + + keep = GetKeepedObjects(dst); + if (keep == NULL) + return -1; + + Py_INCREF(keep); + return KeepRef(self, 0, keep); +} + +static PyGetSetDef Pointer_getsets[] = { + { "contents", (getter)Pointer_get_contents, + (setter)Pointer_set_contents, + "the object this pointer points to (read-write)", NULL }, + { NULL, NULL } +}; + +static int +Pointer_init(CDataObject *self, PyObject *args, PyObject *kw) +{ + PyObject *value = NULL; + + if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value)) + return -1; + if (value == NULL) + return 0; + return Pointer_set_contents(self, value, NULL); +} + +static PyObject * +Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + StgDictObject *dict = PyType_stgdict((PyObject *)type); + if (!dict || !dict->proto) { + PyErr_SetString(PyExc_TypeError, + "Cannot create instance: has no _type_"); + return NULL; + } + return GenericPyCData_new(type, args, kw); +} + +static PyObject * +Pointer_subscript(PyObject *myself, PyObject *item) +{ + CDataObject *self = (CDataObject *)myself; + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + return Pointer_item(myself, i); + } + else if (PySlice_Check(item)) { + PySliceObject *slice = (PySliceObject *)item; + Py_ssize_t start, stop, step; + PyObject *np; + StgDictObject *stgdict, *itemdict; + PyObject *proto; + Py_ssize_t i, len; + size_t cur; + + /* Since pointers have no length, and we want to apply + different semantics to negative indices than normal + slicing, we have to dissect the slice object ourselves.*/ + if (slice->step == Py_None) { + step = 1; + } + else { + step = PyNumber_AsSsize_t(slice->step, + PyExc_ValueError); + if (step == -1 && PyErr_Occurred()) + return NULL; + if (step == 0) { + PyErr_SetString(PyExc_ValueError, + "slice step cannot be zero"); + return NULL; + } + } + if (slice->start == Py_None) { + if (step < 0) { + PyErr_SetString(PyExc_ValueError, + "slice start is required " + "for step < 0"); + return NULL; + } + start = 0; + } + else { + start = PyNumber_AsSsize_t(slice->start, + PyExc_ValueError); + if (start == -1 && PyErr_Occurred()) + return NULL; + } + if (slice->stop == Py_None) { + PyErr_SetString(PyExc_ValueError, + "slice stop is required"); + return NULL; + } + stop = PyNumber_AsSsize_t(slice->stop, + PyExc_ValueError); + if (stop == -1 && PyErr_Occurred()) + return NULL; + if ((step > 0 && start > stop) || + (step < 0 && start < stop)) + len = 0; + else if (step > 0) + len = (stop - start - 1) / step + 1; + else + len = (stop - start + 1) / step + 1; + + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for pointer instances */ + proto = stgdict->proto; + assert(proto); + itemdict = PyType_stgdict(proto); + assert(itemdict); + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { + char *ptr = *(char **)self->b_ptr; + char *dest; + + if (len <= 0) + return PyBytes_FromStringAndSize("", 0); + if (step == 1) { + return PyBytes_FromStringAndSize(ptr + start, + len); + } + dest = (char *)PyMem_Malloc(len); + if (dest == NULL) + return PyErr_NoMemory(); + for (cur = start, i = 0; i < len; cur += step, i++) { + dest[i] = ptr[cur]; + } + np = PyBytes_FromStringAndSize(dest, len); + PyMem_Free(dest); + return np; + } +#ifdef CTYPES_UNICODE + if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { + wchar_t *ptr = *(wchar_t **)self->b_ptr; + wchar_t *dest; + + if (len <= 0) + return PyUnicode_New(0, 0); + if (step == 1) { + return PyUnicode_FromWideChar(ptr + start, + len); + } + dest = PyMem_New(wchar_t, len); + if (dest == NULL) + return PyErr_NoMemory(); + for (cur = start, i = 0; i < len; cur += step, i++) { + dest[i] = ptr[cur]; + } + np = PyUnicode_FromWideChar(dest, len); + PyMem_Free(dest); + return np; + } +#endif + + np = PyList_New(len); + if (np == NULL) + return NULL; + + for (cur = start, i = 0; i < len; cur += step, i++) { + PyObject *v = Pointer_item(myself, cur); + PyList_SET_ITEM(np, i, v); + } + return np; + } + else { + PyErr_SetString(PyExc_TypeError, + "Pointer indices must be integer"); + return NULL; + } +} + +static PySequenceMethods Pointer_as_sequence = { + 0, /* inquiry sq_length; */ + 0, /* binaryfunc sq_concat; */ + 0, /* intargfunc sq_repeat; */ + Pointer_item, /* intargfunc sq_item; */ + 0, /* intintargfunc sq_slice; */ + Pointer_ass_item, /* intobjargproc sq_ass_item; */ + 0, /* intintobjargproc sq_ass_slice; */ + 0, /* objobjproc sq_contains; */ + /* Added in release 2.0 */ + 0, /* binaryfunc sq_inplace_concat; */ + 0, /* intargfunc sq_inplace_repeat; */ +}; + +static PyMappingMethods Pointer_as_mapping = { + 0, + Pointer_subscript, +}; + +static int +Pointer_bool(CDataObject *self) +{ + return (*(void **)self->b_ptr != NULL); +} + +static PyNumberMethods Pointer_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + (inquiry)Pointer_bool, /* nb_bool */ +}; + +PyTypeObject PyCPointer_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes._Pointer", + sizeof(CDataObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + &Pointer_as_number, /* tp_as_number */ + &Pointer_as_sequence, /* tp_as_sequence */ + &Pointer_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + &PyCData_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "XXX to be provided", /* tp_doc */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + Pointer_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Pointer_init, /* tp_init */ + 0, /* tp_alloc */ + Pointer_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/******************************************************************/ +/* + * Module initialization. + */ + +static const char module_docs[] = +"Create and manipulate C compatible data types in Python."; + +#ifdef MS_WIN32 + +static const char comerror_doc[] = "Raised when a COM method call failed."; + +int +comerror_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *hresult, *text, *details; + PyObject *a; + int status; + + if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) + return -1; + + if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details)) + return -1; + + a = PySequence_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + if (!a) + return -1; + status = PyObject_SetAttrString(self, "args", a); + Py_DECREF(a); + if (status < 0) + return -1; + + if (PyObject_SetAttrString(self, "hresult", hresult) < 0) + return -1; + + if (PyObject_SetAttrString(self, "text", text) < 0) + return -1; + + if (PyObject_SetAttrString(self, "details", details) < 0) + return -1; + + Py_INCREF(args); + Py_SETREF(((PyBaseExceptionObject *)self)->args, args); + + return 0; +} + +static PyTypeObject PyComError_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.COMError", /* tp_name */ + sizeof(PyBaseExceptionObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR(comerror_doc), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)comerror_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - - -static int -create_comerror(void) -{ - PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception; - if (PyType_Ready(&PyComError_Type) < 0) - return -1; - Py_INCREF(&PyComError_Type); - ComError = (PyObject*)&PyComError_Type; - return 0; -} - -#endif - -static PyObject * -string_at(const char *ptr, int size) -{ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + PyDoc_STR(comerror_doc), /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)comerror_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + + +static int +create_comerror(void) +{ + PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception; + if (PyType_Ready(&PyComError_Type) < 0) + return -1; + Py_INCREF(&PyComError_Type); + ComError = (PyObject*)&PyComError_Type; + return 0; +} + +#endif + +static PyObject * +string_at(const char *ptr, int size) +{ if (PySys_Audit("ctypes.string_at", "ni", (Py_ssize_t)ptr, size) < 0) { return NULL; } - if (size == -1) - return PyBytes_FromStringAndSize(ptr, strlen(ptr)); - return PyBytes_FromStringAndSize(ptr, size); -} - -static int -cast_check_pointertype(PyObject *arg) -{ - StgDictObject *dict; - - if (PyCPointerTypeObject_Check(arg)) - return 1; - if (PyCFuncPtrTypeObject_Check(arg)) - return 1; - dict = PyType_stgdict(arg); - if (dict != NULL && dict->proto != NULL) { - if (PyUnicode_Check(dict->proto) - && (strchr("sPzUZXO", PyUnicode_AsUTF8(dict->proto)[0]))) { - /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */ - return 1; - } - } - PyErr_Format(PyExc_TypeError, - "cast() argument 2 must be a pointer type, not %s", - PyType_Check(arg) - ? ((PyTypeObject *)arg)->tp_name - : Py_TYPE(arg)->tp_name); - return 0; -} - -static PyObject * -cast(void *ptr, PyObject *src, PyObject *ctype) -{ - CDataObject *result; - if (0 == cast_check_pointertype(ctype)) - return NULL; - result = (CDataObject *)_PyObject_CallNoArg(ctype); - if (result == NULL) - return NULL; - - /* - The casted objects '_objects' member: - - It must certainly contain the source objects one. - It must contain the source object itself. - */ - if (CDataObject_Check(src)) { - CDataObject *obj = (CDataObject *)src; - CDataObject *container; - - /* PyCData_GetContainer will initialize src.b_objects, we need - this so it can be shared */ - container = PyCData_GetContainer(obj); - if (container == NULL) - goto failed; - - /* But we need a dictionary! */ - if (obj->b_objects == Py_None) { - Py_DECREF(Py_None); - obj->b_objects = PyDict_New(); - if (obj->b_objects == NULL) - goto failed; - } - Py_XINCREF(obj->b_objects); - result->b_objects = obj->b_objects; - if (result->b_objects && PyDict_CheckExact(result->b_objects)) { - PyObject *index; - int rc; - index = PyLong_FromVoidPtr((void *)src); - if (index == NULL) - goto failed; - rc = PyDict_SetItem(result->b_objects, index, src); - Py_DECREF(index); - if (rc == -1) - goto failed; - } - } - /* Should we assert that result is a pointer type? */ - memcpy(result->b_ptr, &ptr, sizeof(void *)); - return (PyObject *)result; - - failed: - Py_DECREF(result); - return NULL; -} - -#ifdef CTYPES_UNICODE -static PyObject * -wstring_at(const wchar_t *ptr, int size) -{ - Py_ssize_t ssize = size; + if (size == -1) + return PyBytes_FromStringAndSize(ptr, strlen(ptr)); + return PyBytes_FromStringAndSize(ptr, size); +} + +static int +cast_check_pointertype(PyObject *arg) +{ + StgDictObject *dict; + + if (PyCPointerTypeObject_Check(arg)) + return 1; + if (PyCFuncPtrTypeObject_Check(arg)) + return 1; + dict = PyType_stgdict(arg); + if (dict != NULL && dict->proto != NULL) { + if (PyUnicode_Check(dict->proto) + && (strchr("sPzUZXO", PyUnicode_AsUTF8(dict->proto)[0]))) { + /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */ + return 1; + } + } + PyErr_Format(PyExc_TypeError, + "cast() argument 2 must be a pointer type, not %s", + PyType_Check(arg) + ? ((PyTypeObject *)arg)->tp_name + : Py_TYPE(arg)->tp_name); + return 0; +} + +static PyObject * +cast(void *ptr, PyObject *src, PyObject *ctype) +{ + CDataObject *result; + if (0 == cast_check_pointertype(ctype)) + return NULL; + result = (CDataObject *)_PyObject_CallNoArg(ctype); + if (result == NULL) + return NULL; + + /* + The casted objects '_objects' member: + + It must certainly contain the source objects one. + It must contain the source object itself. + */ + if (CDataObject_Check(src)) { + CDataObject *obj = (CDataObject *)src; + CDataObject *container; + + /* PyCData_GetContainer will initialize src.b_objects, we need + this so it can be shared */ + container = PyCData_GetContainer(obj); + if (container == NULL) + goto failed; + + /* But we need a dictionary! */ + if (obj->b_objects == Py_None) { + Py_DECREF(Py_None); + obj->b_objects = PyDict_New(); + if (obj->b_objects == NULL) + goto failed; + } + Py_XINCREF(obj->b_objects); + result->b_objects = obj->b_objects; + if (result->b_objects && PyDict_CheckExact(result->b_objects)) { + PyObject *index; + int rc; + index = PyLong_FromVoidPtr((void *)src); + if (index == NULL) + goto failed; + rc = PyDict_SetItem(result->b_objects, index, src); + Py_DECREF(index); + if (rc == -1) + goto failed; + } + } + /* Should we assert that result is a pointer type? */ + memcpy(result->b_ptr, &ptr, sizeof(void *)); + return (PyObject *)result; + + failed: + Py_DECREF(result); + return NULL; +} + +#ifdef CTYPES_UNICODE +static PyObject * +wstring_at(const wchar_t *ptr, int size) +{ + Py_ssize_t ssize = size; if (PySys_Audit("ctypes.wstring_at", "nn", (Py_ssize_t)ptr, ssize) < 0) { return NULL; } - if (ssize == -1) - ssize = wcslen(ptr); - return PyUnicode_FromWideChar(ptr, ssize); -} -#endif - - -static struct PyModuleDef _ctypesmodule = { - PyModuleDef_HEAD_INIT, - "_ctypes", - module_docs, - -1, - _ctypes_module_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__ctypes(void) -{ - PyObject *m; - -/* Note: - ob_type is the metatype (the 'type'), defaults to PyType_Type, - tp_base is the base type, defaults to 'object' aka PyBaseObject_Type. -*/ - m = PyModule_Create(&_ctypesmodule); - if (!m) - return NULL; - - _ctypes_ptrtype_cache = PyDict_New(); - if (_ctypes_ptrtype_cache == NULL) - return NULL; - - PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache); - - _unpickle = PyObject_GetAttrString(m, "_unpickle"); - if (_unpickle == NULL) - return NULL; - - if (PyType_Ready(&PyCArg_Type) < 0) - return NULL; - - if (PyType_Ready(&PyCThunk_Type) < 0) - return NULL; - - /* StgDict is derived from PyDict_Type */ - PyCStgDict_Type.tp_base = &PyDict_Type; - if (PyType_Ready(&PyCStgDict_Type) < 0) - return NULL; - - /************************************************* - * - * Metaclasses - */ - - PyCStructType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCStructType_Type) < 0) - return NULL; - - UnionType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&UnionType_Type) < 0) - return NULL; - - PyCPointerType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCPointerType_Type) < 0) - return NULL; - - PyCArrayType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCArrayType_Type) < 0) - return NULL; - - PyCSimpleType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCSimpleType_Type) < 0) - return NULL; - - PyCFuncPtrType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PyCFuncPtrType_Type) < 0) - return NULL; - - /************************************************* - * - * Classes using a custom metaclass - */ - - if (PyType_Ready(&PyCData_Type) < 0) - return NULL; - + if (ssize == -1) + ssize = wcslen(ptr); + return PyUnicode_FromWideChar(ptr, ssize); +} +#endif + + +static struct PyModuleDef _ctypesmodule = { + PyModuleDef_HEAD_INIT, + "_ctypes", + module_docs, + -1, + _ctypes_module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__ctypes(void) +{ + PyObject *m; + +/* Note: + ob_type is the metatype (the 'type'), defaults to PyType_Type, + tp_base is the base type, defaults to 'object' aka PyBaseObject_Type. +*/ + m = PyModule_Create(&_ctypesmodule); + if (!m) + return NULL; + + _ctypes_ptrtype_cache = PyDict_New(); + if (_ctypes_ptrtype_cache == NULL) + return NULL; + + PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache); + + _unpickle = PyObject_GetAttrString(m, "_unpickle"); + if (_unpickle == NULL) + return NULL; + + if (PyType_Ready(&PyCArg_Type) < 0) + return NULL; + + if (PyType_Ready(&PyCThunk_Type) < 0) + return NULL; + + /* StgDict is derived from PyDict_Type */ + PyCStgDict_Type.tp_base = &PyDict_Type; + if (PyType_Ready(&PyCStgDict_Type) < 0) + return NULL; + + /************************************************* + * + * Metaclasses + */ + + PyCStructType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCStructType_Type) < 0) + return NULL; + + UnionType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&UnionType_Type) < 0) + return NULL; + + PyCPointerType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCPointerType_Type) < 0) + return NULL; + + PyCArrayType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCArrayType_Type) < 0) + return NULL; + + PyCSimpleType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCSimpleType_Type) < 0) + return NULL; + + PyCFuncPtrType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCFuncPtrType_Type) < 0) + return NULL; + + /************************************************* + * + * Classes using a custom metaclass + */ + + if (PyType_Ready(&PyCData_Type) < 0) + return NULL; + Py_SET_TYPE(&Struct_Type, &PyCStructType_Type); - Struct_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&Struct_Type) < 0) - return NULL; - Py_INCREF(&Struct_Type); - PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type); - + Struct_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&Struct_Type) < 0) + return NULL; + Py_INCREF(&Struct_Type); + PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type); + Py_SET_TYPE(&Union_Type, &UnionType_Type); - Union_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&Union_Type) < 0) - return NULL; - Py_INCREF(&Union_Type); - PyModule_AddObject(m, "Union", (PyObject *)&Union_Type); - + Union_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&Union_Type) < 0) + return NULL; + Py_INCREF(&Union_Type); + PyModule_AddObject(m, "Union", (PyObject *)&Union_Type); + Py_SET_TYPE(&PyCPointer_Type, &PyCPointerType_Type); - PyCPointer_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&PyCPointer_Type) < 0) - return NULL; - Py_INCREF(&PyCPointer_Type); - PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type); - + PyCPointer_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCPointer_Type) < 0) + return NULL; + Py_INCREF(&PyCPointer_Type); + PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type); + Py_SET_TYPE(&PyCArray_Type, &PyCArrayType_Type); - PyCArray_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&PyCArray_Type) < 0) - return NULL; - Py_INCREF(&PyCArray_Type); - PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type); - + PyCArray_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCArray_Type) < 0) + return NULL; + Py_INCREF(&PyCArray_Type); + PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type); + Py_SET_TYPE(&Simple_Type, &PyCSimpleType_Type); - Simple_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&Simple_Type) < 0) - return NULL; - Py_INCREF(&Simple_Type); - PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type); - + Simple_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&Simple_Type) < 0) + return NULL; + Py_INCREF(&Simple_Type); + PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type); + Py_SET_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type); - PyCFuncPtr_Type.tp_base = &PyCData_Type; - if (PyType_Ready(&PyCFuncPtr_Type) < 0) - return NULL; - Py_INCREF(&PyCFuncPtr_Type); - PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type); - - /************************************************* - * - * Simple classes - */ - - /* PyCField_Type is derived from PyBaseObject_Type */ - if (PyType_Ready(&PyCField_Type) < 0) - return NULL; - - /************************************************* - * - * Other stuff - */ - - DictRemover_Type.tp_new = PyType_GenericNew; - if (PyType_Ready(&DictRemover_Type) < 0) - return NULL; - + PyCFuncPtr_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCFuncPtr_Type) < 0) + return NULL; + Py_INCREF(&PyCFuncPtr_Type); + PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type); + + /************************************************* + * + * Simple classes + */ + + /* PyCField_Type is derived from PyBaseObject_Type */ + if (PyType_Ready(&PyCField_Type) < 0) + return NULL; + + /************************************************* + * + * Other stuff + */ + + DictRemover_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&DictRemover_Type) < 0) + return NULL; + if (PyType_Ready(&StructParam_Type) < 0) { return NULL; } -#ifdef MS_WIN32 - if (create_comerror() < 0) - return NULL; - PyModule_AddObject(m, "COMError", ComError); - - PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT)); - PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL)); -#endif - PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL)); - PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO)); - PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR)); - PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI)); - PyModule_AddStringConstant(m, "__version__", "1.1.0"); - - PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove)); - PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset)); - PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at)); - PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast)); -#ifdef CTYPES_UNICODE - PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at)); -#endif - -/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */ -#if !HAVE_DECL_RTLD_LOCAL -#define RTLD_LOCAL 0 -#endif - -/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as - RTLD_LOCAL. -*/ -#if !HAVE_DECL_RTLD_GLOBAL -#define RTLD_GLOBAL RTLD_LOCAL -#endif - - PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL)); - PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL)); - - PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); - if (PyExc_ArgError) { - Py_INCREF(PyExc_ArgError); - PyModule_AddObject(m, "ArgumentError", PyExc_ArgError); - } - return m; -} - -/* - Local Variables: - compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~" - End: -*/ +#ifdef MS_WIN32 + if (create_comerror() < 0) + return NULL; + PyModule_AddObject(m, "COMError", ComError); + + PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT)); + PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL)); +#endif + PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL)); + PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO)); + PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR)); + PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI)); + PyModule_AddStringConstant(m, "__version__", "1.1.0"); + + PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove)); + PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset)); + PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at)); + PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast)); +#ifdef CTYPES_UNICODE + PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at)); +#endif + +/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */ +#if !HAVE_DECL_RTLD_LOCAL +#define RTLD_LOCAL 0 +#endif + +/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as + RTLD_LOCAL. +*/ +#if !HAVE_DECL_RTLD_GLOBAL +#define RTLD_GLOBAL RTLD_LOCAL +#endif + + PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL)); + PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL)); + + PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL); + if (PyExc_ArgError) { + Py_INCREF(PyExc_ArgError); + PyModule_AddObject(m, "ArgumentError", PyExc_ArgError); + } + return m; +} + +/* + Local Variables: + compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~" + End: +*/ diff --git a/contrib/tools/python3/src/Modules/_ctypes/callbacks.c b/contrib/tools/python3/src/Modules/_ctypes/callbacks.c index 0dc82428171..5f0d65efa6b 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/callbacks.c +++ b/contrib/tools/python3/src/Modules/_ctypes/callbacks.c @@ -1,279 +1,279 @@ -#include "Python.h" -#include "frameobject.h" - +#include "Python.h" +#include "frameobject.h" + #include -#include -#ifdef MS_WIN32 -#include -#include -#endif -#include "ctypes.h" - -/**************************************************************/ - -static void -CThunkObject_dealloc(PyObject *myself) -{ - CThunkObject *self = (CThunkObject *)myself; - PyObject_GC_UnTrack(self); - Py_XDECREF(self->converters); - Py_XDECREF(self->callable); - Py_XDECREF(self->restype); - if (self->pcl_write) +#include +#ifdef MS_WIN32 +#include +#include +#endif +#include "ctypes.h" + +/**************************************************************/ + +static void +CThunkObject_dealloc(PyObject *myself) +{ + CThunkObject *self = (CThunkObject *)myself; + PyObject_GC_UnTrack(self); + Py_XDECREF(self->converters); + Py_XDECREF(self->callable); + Py_XDECREF(self->restype); + if (self->pcl_write) Py_ffi_closure_free(self->pcl_write); - PyObject_GC_Del(self); -} - -static int -CThunkObject_traverse(PyObject *myself, visitproc visit, void *arg) -{ - CThunkObject *self = (CThunkObject *)myself; - Py_VISIT(self->converters); - Py_VISIT(self->callable); - Py_VISIT(self->restype); - return 0; -} - -static int -CThunkObject_clear(PyObject *myself) -{ - CThunkObject *self = (CThunkObject *)myself; - Py_CLEAR(self->converters); - Py_CLEAR(self->callable); - Py_CLEAR(self->restype); - return 0; -} - -PyTypeObject PyCThunk_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CThunkObject", - sizeof(CThunkObject), /* tp_basicsize */ - sizeof(ffi_type), /* tp_itemsize */ - CThunkObject_dealloc, /* tp_dealloc */ + PyObject_GC_Del(self); +} + +static int +CThunkObject_traverse(PyObject *myself, visitproc visit, void *arg) +{ + CThunkObject *self = (CThunkObject *)myself; + Py_VISIT(self->converters); + Py_VISIT(self->callable); + Py_VISIT(self->restype); + return 0; +} + +static int +CThunkObject_clear(PyObject *myself) +{ + CThunkObject *self = (CThunkObject *)myself; + Py_CLEAR(self->converters); + Py_CLEAR(self->callable); + Py_CLEAR(self->restype); + return 0; +} + +PyTypeObject PyCThunk_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.CThunkObject", + sizeof(CThunkObject), /* tp_basicsize */ + sizeof(ffi_type), /* tp_itemsize */ + CThunkObject_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "CThunkObject", /* tp_doc */ - CThunkObject_traverse, /* tp_traverse */ - CThunkObject_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ -}; - -/**************************************************************/ - -static void -PrintError(const char *msg, ...) -{ - char buf[512]; - PyObject *f = PySys_GetObject("stderr"); - va_list marker; - - va_start(marker, msg); + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + "CThunkObject", /* tp_doc */ + CThunkObject_traverse, /* tp_traverse */ + CThunkObject_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ +}; + +/**************************************************************/ + +static void +PrintError(const char *msg, ...) +{ + char buf[512]; + PyObject *f = PySys_GetObject("stderr"); + va_list marker; + + va_start(marker, msg); PyOS_vsnprintf(buf, sizeof(buf), msg, marker); - va_end(marker); - if (f != NULL && f != Py_None) - PyFile_WriteString(buf, f); - PyErr_Print(); -} - - -#ifdef MS_WIN32 -/* - * We must call AddRef() on non-NULL COM pointers we receive as arguments - * to callback functions - these functions are COM method implementations. - * The Python instances we create have a __del__ method which calls Release(). - * - * The presence of a class attribute named '_needs_com_addref_' triggers this - * behaviour. It would also be possible to call the AddRef() Python method, - * after checking for PyObject_IsTrue(), but this would probably be somewhat - * slower. - */ -static void -TryAddRef(StgDictObject *dict, CDataObject *obj) -{ - IUnknown *punk; + va_end(marker); + if (f != NULL && f != Py_None) + PyFile_WriteString(buf, f); + PyErr_Print(); +} + + +#ifdef MS_WIN32 +/* + * We must call AddRef() on non-NULL COM pointers we receive as arguments + * to callback functions - these functions are COM method implementations. + * The Python instances we create have a __del__ method which calls Release(). + * + * The presence of a class attribute named '_needs_com_addref_' triggers this + * behaviour. It would also be possible to call the AddRef() Python method, + * after checking for PyObject_IsTrue(), but this would probably be somewhat + * slower. + */ +static void +TryAddRef(StgDictObject *dict, CDataObject *obj) +{ + IUnknown *punk; _Py_IDENTIFIER(_needs_com_addref_); - + if (!_PyDict_GetItemIdWithError((PyObject *)dict, &PyId__needs_com_addref_)) { if (PyErr_Occurred()) { PrintError("getting _needs_com_addref_"); } - return; - } - - punk = *(IUnknown **)obj->b_ptr; - if (punk) - punk->lpVtbl->AddRef(punk); - return; -} -#endif - -/****************************************************************************** - * - * Call the python object with all arguments - * - */ -static void _CallPythonObject(void *mem, - ffi_type *restype, - SETFUNC setfunc, - PyObject *callable, - PyObject *converters, - int flags, - void **pArgs) -{ - Py_ssize_t i; - PyObject *result; - PyObject *arglist = NULL; - Py_ssize_t nArgs; - PyObject *error_object = NULL; - int *space; - PyGILState_STATE state = PyGILState_Ensure(); - - nArgs = PySequence_Length(converters); - /* Hm. What to return in case of error? - For COM, 0xFFFFFFFF seems better than 0. - */ - if (nArgs < 0) { - PrintError("BUG: PySequence_Length"); - goto Done; + return; } - - arglist = PyTuple_New(nArgs); - if (!arglist) { - PrintError("PyTuple_New()"); - goto Done; - } - for (i = 0; i < nArgs; ++i) { - /* Note: new reference! */ - PyObject *cnv = PySequence_GetItem(converters, i); - StgDictObject *dict; - if (cnv) - dict = PyType_stgdict(cnv); - else { + + punk = *(IUnknown **)obj->b_ptr; + if (punk) + punk->lpVtbl->AddRef(punk); + return; +} +#endif + +/****************************************************************************** + * + * Call the python object with all arguments + * + */ +static void _CallPythonObject(void *mem, + ffi_type *restype, + SETFUNC setfunc, + PyObject *callable, + PyObject *converters, + int flags, + void **pArgs) +{ + Py_ssize_t i; + PyObject *result; + PyObject *arglist = NULL; + Py_ssize_t nArgs; + PyObject *error_object = NULL; + int *space; + PyGILState_STATE state = PyGILState_Ensure(); + + nArgs = PySequence_Length(converters); + /* Hm. What to return in case of error? + For COM, 0xFFFFFFFF seems better than 0. + */ + if (nArgs < 0) { + PrintError("BUG: PySequence_Length"); + goto Done; + } + + arglist = PyTuple_New(nArgs); + if (!arglist) { + PrintError("PyTuple_New()"); + goto Done; + } + for (i = 0; i < nArgs; ++i) { + /* Note: new reference! */ + PyObject *cnv = PySequence_GetItem(converters, i); + StgDictObject *dict; + if (cnv) + dict = PyType_stgdict(cnv); + else { PrintError("Getting argument converter %zd\n", i); - goto Done; - } - - if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) { - PyObject *v = dict->getfunc(*pArgs, dict->size); - if (!v) { + goto Done; + } + + if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) { + PyObject *v = dict->getfunc(*pArgs, dict->size); + if (!v) { PrintError("create argument %zd:\n", i); - Py_DECREF(cnv); - goto Done; - } - PyTuple_SET_ITEM(arglist, i, v); - /* XXX XXX XX - We have the problem that c_byte or c_short have dict->size of - 1 resp. 4, but these parameters are pushed as sizeof(int) bytes. - BTW, the same problem occurs when they are pushed as parameters - */ - } else if (dict) { - /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */ - CDataObject *obj = (CDataObject *)_PyObject_CallNoArg(cnv); - if (!obj) { + Py_DECREF(cnv); + goto Done; + } + PyTuple_SET_ITEM(arglist, i, v); + /* XXX XXX XX + We have the problem that c_byte or c_short have dict->size of + 1 resp. 4, but these parameters are pushed as sizeof(int) bytes. + BTW, the same problem occurs when they are pushed as parameters + */ + } else if (dict) { + /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */ + CDataObject *obj = (CDataObject *)_PyObject_CallNoArg(cnv); + if (!obj) { PrintError("create argument %zd:\n", i); - Py_DECREF(cnv); - goto Done; - } - if (!CDataObject_Check(obj)) { - Py_DECREF(obj); - Py_DECREF(cnv); + Py_DECREF(cnv); + goto Done; + } + if (!CDataObject_Check(obj)) { + Py_DECREF(obj); + Py_DECREF(cnv); PrintError("unexpected result of create argument %zd:\n", i); - goto Done; - } - memcpy(obj->b_ptr, *pArgs, dict->size); - PyTuple_SET_ITEM(arglist, i, (PyObject *)obj); -#ifdef MS_WIN32 - TryAddRef(dict, obj); -#endif - } else { - PyErr_SetString(PyExc_TypeError, - "cannot build parameter"); + goto Done; + } + memcpy(obj->b_ptr, *pArgs, dict->size); + PyTuple_SET_ITEM(arglist, i, (PyObject *)obj); +#ifdef MS_WIN32 + TryAddRef(dict, obj); +#endif + } else { + PyErr_SetString(PyExc_TypeError, + "cannot build parameter"); PrintError("Parsing argument %zd\n", i); - Py_DECREF(cnv); - goto Done; - } - Py_DECREF(cnv); - /* XXX error handling! */ - pArgs++; - } - - if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { - error_object = _ctypes_get_errobj(&space); - if (error_object == NULL) - goto Done; - if (flags & FUNCFLAG_USE_ERRNO) { - int temp = space[0]; - space[0] = errno; - errno = temp; - } -#ifdef MS_WIN32 - if (flags & FUNCFLAG_USE_LASTERROR) { - int temp = space[1]; - space[1] = GetLastError(); - SetLastError(temp); - } -#endif - } - - result = PyObject_CallObject(callable, arglist); + Py_DECREF(cnv); + goto Done; + } + Py_DECREF(cnv); + /* XXX error handling! */ + pArgs++; + } + + if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { + error_object = _ctypes_get_errobj(&space); + if (error_object == NULL) + goto Done; + if (flags & FUNCFLAG_USE_ERRNO) { + int temp = space[0]; + space[0] = errno; + errno = temp; + } +#ifdef MS_WIN32 + if (flags & FUNCFLAG_USE_LASTERROR) { + int temp = space[1]; + space[1] = GetLastError(); + SetLastError(temp); + } +#endif + } + + result = PyObject_CallObject(callable, arglist); if (result == NULL) { _PyErr_WriteUnraisableMsg("on calling ctypes callback function", callable); } - -#ifdef MS_WIN32 - if (flags & FUNCFLAG_USE_LASTERROR) { - int temp = space[1]; - space[1] = GetLastError(); - SetLastError(temp); - } -#endif - if (flags & FUNCFLAG_USE_ERRNO) { - int temp = space[0]; - space[0] = errno; - errno = temp; - } - Py_XDECREF(error_object); - + +#ifdef MS_WIN32 + if (flags & FUNCFLAG_USE_LASTERROR) { + int temp = space[1]; + space[1] = GetLastError(); + SetLastError(temp); + } +#endif + if (flags & FUNCFLAG_USE_ERRNO) { + int temp = space[0]; + space[0] = errno; + errno = temp; + } + Py_XDECREF(error_object); + if (restype != &ffi_type_void && result) { - assert(setfunc); + assert(setfunc); -#ifdef WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN /* See the corresponding code in _ctypes_callproc(): in callproc.c, around line 1219. */ if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg)) { - mem = (char *)mem + sizeof(ffi_arg) - restype->size; + mem = (char *)mem + sizeof(ffi_arg) - restype->size; } -#endif - - /* keep is an object we have to keep alive so that the result - stays valid. If there is no such object, the setfunc will - have returned Py_None. - - If there is such an object, we have no choice than to keep - it alive forever - but a refcount and/or memory leak will - be the result. EXCEPT when restype is py_object - Python - itself knows how to manage the refcount of these objects. - */ +#endif + + /* keep is an object we have to keep alive so that the result + stays valid. If there is no such object, the setfunc will + have returned Py_None. + + If there is such an object, we have no choice than to keep + it alive forever - but a refcount and/or memory leak will + be the result. EXCEPT when restype is py_object - Python + itself knows how to manage the refcount of these objects. + */ PyObject *keep = setfunc(mem, result, 0); if (keep == NULL) { @@ -284,132 +284,132 @@ static void _CallPythonObject(void *mem, } else if (keep == Py_None) { /* Nothing to keep */ - Py_DECREF(keep); + Py_DECREF(keep); } - else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) { - if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning, - "memory leak in callback function.", - 1)) + else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) { + if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning, + "memory leak in callback function.", + 1)) { _PyErr_WriteUnraisableMsg("on converting result " "of ctypes callback function", callable); } - } - } - - Py_XDECREF(result); - - Done: - Py_XDECREF(arglist); - PyGILState_Release(state); -} - -static void closure_fcn(ffi_cif *cif, - void *resp, - void **args, - void *userdata) -{ - CThunkObject *p = (CThunkObject *)userdata; - - _CallPythonObject(resp, - p->ffi_restype, - p->setfunc, - p->callable, - p->converters, - p->flags, - args); -} - -static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) -{ - CThunkObject *p; - Py_ssize_t i; - - p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs); - if (p == NULL) { - return NULL; - } - - p->pcl_write = NULL; - p->pcl_exec = NULL; - memset(&p->cif, 0, sizeof(p->cif)); - p->flags = 0; - p->converters = NULL; - p->callable = NULL; - p->restype = NULL; - p->setfunc = NULL; - p->ffi_restype = NULL; - - for (i = 0; i < nArgs + 1; ++i) - p->atypes[i] = NULL; - PyObject_GC_Track((PyObject *)p); - return p; -} - -CThunkObject *_ctypes_alloc_callback(PyObject *callable, - PyObject *converters, - PyObject *restype, - int flags) -{ - int result; - CThunkObject *p; - Py_ssize_t nArgs, i; - ffi_abi cc; - - nArgs = PySequence_Size(converters); - p = CThunkObject_new(nArgs); - if (p == NULL) - return NULL; - - assert(CThunk_CheckExact((PyObject *)p)); - + } + } + + Py_XDECREF(result); + + Done: + Py_XDECREF(arglist); + PyGILState_Release(state); +} + +static void closure_fcn(ffi_cif *cif, + void *resp, + void **args, + void *userdata) +{ + CThunkObject *p = (CThunkObject *)userdata; + + _CallPythonObject(resp, + p->ffi_restype, + p->setfunc, + p->callable, + p->converters, + p->flags, + args); +} + +static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) +{ + CThunkObject *p; + Py_ssize_t i; + + p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs); + if (p == NULL) { + return NULL; + } + + p->pcl_write = NULL; + p->pcl_exec = NULL; + memset(&p->cif, 0, sizeof(p->cif)); + p->flags = 0; + p->converters = NULL; + p->callable = NULL; + p->restype = NULL; + p->setfunc = NULL; + p->ffi_restype = NULL; + + for (i = 0; i < nArgs + 1; ++i) + p->atypes[i] = NULL; + PyObject_GC_Track((PyObject *)p); + return p; +} + +CThunkObject *_ctypes_alloc_callback(PyObject *callable, + PyObject *converters, + PyObject *restype, + int flags) +{ + int result; + CThunkObject *p; + Py_ssize_t nArgs, i; + ffi_abi cc; + + nArgs = PySequence_Size(converters); + p = CThunkObject_new(nArgs); + if (p == NULL) + return NULL; + + assert(CThunk_CheckExact((PyObject *)p)); + p->pcl_write = Py_ffi_closure_alloc(sizeof(ffi_closure), &p->pcl_exec); - if (p->pcl_write == NULL) { - PyErr_NoMemory(); - goto error; - } - - p->flags = flags; - for (i = 0; i < nArgs; ++i) { - PyObject *cnv = PySequence_GetItem(converters, i); - if (cnv == NULL) - goto error; - p->atypes[i] = _ctypes_get_ffi_type(cnv); - Py_DECREF(cnv); - } - p->atypes[i] = NULL; - - Py_INCREF(restype); - p->restype = restype; - if (restype == Py_None) { - p->setfunc = NULL; - p->ffi_restype = &ffi_type_void; - } else { - StgDictObject *dict = PyType_stgdict(restype); - if (dict == NULL || dict->setfunc == NULL) { - PyErr_SetString(PyExc_TypeError, - "invalid result type for callback function"); - goto error; - } - p->setfunc = dict->setfunc; - p->ffi_restype = &dict->ffi_type_pointer; - } - - cc = FFI_DEFAULT_ABI; + if (p->pcl_write == NULL) { + PyErr_NoMemory(); + goto error; + } + + p->flags = flags; + for (i = 0; i < nArgs; ++i) { + PyObject *cnv = PySequence_GetItem(converters, i); + if (cnv == NULL) + goto error; + p->atypes[i] = _ctypes_get_ffi_type(cnv); + Py_DECREF(cnv); + } + p->atypes[i] = NULL; + + Py_INCREF(restype); + p->restype = restype; + if (restype == Py_None) { + p->setfunc = NULL; + p->ffi_restype = &ffi_type_void; + } else { + StgDictObject *dict = PyType_stgdict(restype); + if (dict == NULL || dict->setfunc == NULL) { + PyErr_SetString(PyExc_TypeError, + "invalid result type for callback function"); + goto error; + } + p->setfunc = dict->setfunc; + p->ffi_restype = &dict->ffi_type_pointer; + } + + cc = FFI_DEFAULT_ABI; #if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64) && !defined(_M_ARM) - if ((flags & FUNCFLAG_CDECL) == 0) - cc = FFI_STDCALL; -#endif - result = ffi_prep_cif(&p->cif, cc, - Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int), - _ctypes_get_ffi_type(restype), - &p->atypes[0]); - if (result != FFI_OK) { - PyErr_Format(PyExc_RuntimeError, - "ffi_prep_cif failed with %d", result); - goto error; - } + if ((flags & FUNCFLAG_CDECL) == 0) + cc = FFI_STDCALL; +#endif + result = ffi_prep_cif(&p->cif, cc, + Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int), + _ctypes_get_ffi_type(restype), + &p->atypes[0]); + if (result != FFI_OK) { + PyErr_Format(PyExc_RuntimeError, + "ffi_prep_cif failed with %d", result); + goto error; + } #if HAVE_FFI_PREP_CLOSURE_LOC # if USING_APPLE_OS_LIBFFI # define HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *) @@ -426,11 +426,11 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, #if USING_APPLE_OS_LIBFFI && defined(__arm64__) PyErr_Format(PyExc_NotImplementedError, "ffi_prep_closure_loc() is missing"); goto error; -#else +#else #if defined(__clang__) || defined(MACOSX) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif +#endif #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -446,177 +446,177 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, #endif } - if (result != FFI_OK) { - PyErr_Format(PyExc_RuntimeError, - "ffi_prep_closure failed with %d", result); - goto error; - } - - Py_INCREF(converters); - p->converters = converters; - Py_INCREF(callable); - p->callable = callable; - return p; - - error: - Py_XDECREF(p); - return NULL; -} - -#ifdef MS_WIN32 - -static void LoadPython(void) -{ - if (!Py_IsInitialized()) { + if (result != FFI_OK) { + PyErr_Format(PyExc_RuntimeError, + "ffi_prep_closure failed with %d", result); + goto error; + } + + Py_INCREF(converters); + p->converters = converters; + Py_INCREF(callable); + p->callable = callable; + return p; + + error: + Py_XDECREF(p); + return NULL; +} + +#ifdef MS_WIN32 + +static void LoadPython(void) +{ + if (!Py_IsInitialized()) { Py_Initialize(); - } -} - -/******************************************************************/ - -long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) -{ - PyObject *mod, *func, *result; - long retval; - static PyObject *context; - - if (context == NULL) - context = PyUnicode_InternFromString("_ctypes.DllGetClassObject"); - - mod = PyImport_ImportModuleNoBlock("ctypes"); - if (!mod) { - PyErr_WriteUnraisable(context ? context : Py_None); - /* There has been a warning before about this already */ - return E_FAIL; - } - - func = PyObject_GetAttrString(mod, "DllGetClassObject"); - Py_DECREF(mod); - if (!func) { - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - - { - PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid); - PyObject *py_riid = PyLong_FromVoidPtr((void *)riid); - PyObject *py_ppv = PyLong_FromVoidPtr(ppv); - if (!py_rclsid || !py_riid || !py_ppv) { - Py_XDECREF(py_rclsid); - Py_XDECREF(py_riid); - Py_XDECREF(py_ppv); - Py_DECREF(func); - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - result = PyObject_CallFunctionObjArgs(func, - py_rclsid, - py_riid, - py_ppv, - NULL); - Py_DECREF(py_rclsid); - Py_DECREF(py_riid); - Py_DECREF(py_ppv); - } - Py_DECREF(func); - if (!result) { - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - - retval = PyLong_AsLong(result); - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(context ? context : Py_None); - retval = E_FAIL; - } - Py_DECREF(result); - return retval; -} - -STDAPI DllGetClassObject(REFCLSID rclsid, - REFIID riid, - LPVOID *ppv) -{ - long result; - PyGILState_STATE state; - - LoadPython(); - state = PyGILState_Ensure(); - result = Call_GetClassObject(rclsid, riid, ppv); - PyGILState_Release(state); - return result; -} - -long Call_CanUnloadNow(void) -{ - PyObject *mod, *func, *result; - long retval; - static PyObject *context; - - if (context == NULL) - context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow"); - - mod = PyImport_ImportModuleNoBlock("ctypes"); - if (!mod) { -/* OutputDebugString("Could not import ctypes"); */ - /* We assume that this error can only occur when shutting - down, so we silently ignore it */ - PyErr_Clear(); - return E_FAIL; - } - /* Other errors cannot be raised, but are printed to stderr */ - func = PyObject_GetAttrString(mod, "DllCanUnloadNow"); - Py_DECREF(mod); - if (!func) { - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - - result = _PyObject_CallNoArg(func); - Py_DECREF(func); - if (!result) { - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - - retval = PyLong_AsLong(result); - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(context ? context : Py_None); - retval = E_FAIL; - } - Py_DECREF(result); - return retval; -} - -/* - DllRegisterServer and DllUnregisterServer still missing -*/ - -STDAPI DllCanUnloadNow(void) -{ - long result; - PyGILState_STATE state = PyGILState_Ensure(); - result = Call_CanUnloadNow(); - PyGILState_Release(state); - return result; -} - -#ifndef Py_NO_ENABLE_SHARED -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes) -{ - switch(fdwReason) { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - break; - } - return TRUE; -} -#endif - -#endif - -/* - Local Variables: - compile-command: "cd .. && python setup.py -q build_ext" - End: -*/ + } +} + +/******************************************************************/ + +long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + PyObject *mod, *func, *result; + long retval; + static PyObject *context; + + if (context == NULL) + context = PyUnicode_InternFromString("_ctypes.DllGetClassObject"); + + mod = PyImport_ImportModuleNoBlock("ctypes"); + if (!mod) { + PyErr_WriteUnraisable(context ? context : Py_None); + /* There has been a warning before about this already */ + return E_FAIL; + } + + func = PyObject_GetAttrString(mod, "DllGetClassObject"); + Py_DECREF(mod); + if (!func) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + + { + PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid); + PyObject *py_riid = PyLong_FromVoidPtr((void *)riid); + PyObject *py_ppv = PyLong_FromVoidPtr(ppv); + if (!py_rclsid || !py_riid || !py_ppv) { + Py_XDECREF(py_rclsid); + Py_XDECREF(py_riid); + Py_XDECREF(py_ppv); + Py_DECREF(func); + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + result = PyObject_CallFunctionObjArgs(func, + py_rclsid, + py_riid, + py_ppv, + NULL); + Py_DECREF(py_rclsid); + Py_DECREF(py_riid); + Py_DECREF(py_ppv); + } + Py_DECREF(func); + if (!result) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + + retval = PyLong_AsLong(result); + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(context ? context : Py_None); + retval = E_FAIL; + } + Py_DECREF(result); + return retval; +} + +STDAPI DllGetClassObject(REFCLSID rclsid, + REFIID riid, + LPVOID *ppv) +{ + long result; + PyGILState_STATE state; + + LoadPython(); + state = PyGILState_Ensure(); + result = Call_GetClassObject(rclsid, riid, ppv); + PyGILState_Release(state); + return result; +} + +long Call_CanUnloadNow(void) +{ + PyObject *mod, *func, *result; + long retval; + static PyObject *context; + + if (context == NULL) + context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow"); + + mod = PyImport_ImportModuleNoBlock("ctypes"); + if (!mod) { +/* OutputDebugString("Could not import ctypes"); */ + /* We assume that this error can only occur when shutting + down, so we silently ignore it */ + PyErr_Clear(); + return E_FAIL; + } + /* Other errors cannot be raised, but are printed to stderr */ + func = PyObject_GetAttrString(mod, "DllCanUnloadNow"); + Py_DECREF(mod); + if (!func) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + + result = _PyObject_CallNoArg(func); + Py_DECREF(func); + if (!result) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + + retval = PyLong_AsLong(result); + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(context ? context : Py_None); + retval = E_FAIL; + } + Py_DECREF(result); + return retval; +} + +/* + DllRegisterServer and DllUnregisterServer still missing +*/ + +STDAPI DllCanUnloadNow(void) +{ + long result; + PyGILState_STATE state = PyGILState_Ensure(); + result = Call_CanUnloadNow(); + PyGILState_Release(state); + return result; +} + +#ifndef Py_NO_ENABLE_SHARED +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes) +{ + switch(fdwReason) { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + } + return TRUE; +} +#endif + +#endif + +/* + Local Variables: + compile-command: "cd .. && python setup.py -q build_ext" + End: +*/ diff --git a/contrib/tools/python3/src/Modules/_ctypes/callproc.c b/contrib/tools/python3/src/Modules/_ctypes/callproc.c index 287bec47aa2..1fab40b0384 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/callproc.c +++ b/contrib/tools/python3/src/Modules/_ctypes/callproc.c @@ -1,518 +1,518 @@ -/* - * History: First version dated from 3/97, derived from my SCMLIB version - * for win16. - */ -/* - * Related Work: - * - calldll http://www.nightmare.com/software.html - * - libffi http://sourceware.cygnus.com/libffi/ - * - ffcall http://clisp.cons.org/~haible/packages-ffcall.html - * and, of course, Don Beaudry's MESS package, but this is more ctypes - * related. - */ - - -/* - How are functions called, and how are parameters converted to C ? - - 1. _ctypes.c::PyCFuncPtr_call receives an argument tuple 'inargs' and a - keyword dictionary 'kwds'. - - 2. After several checks, _build_callargs() is called which returns another - tuple 'callargs'. This may be the same tuple as 'inargs', a slice of - 'inargs', or a completely fresh tuple, depending on several things (is it a - COM method?, are 'paramflags' available?). - - 3. _build_callargs also calculates bitarrays containing indexes into - the callargs tuple, specifying how to build the return value(s) of - the function. - - 4. _ctypes_callproc is then called with the 'callargs' tuple. _ctypes_callproc first - allocates two arrays. The first is an array of 'struct argument' items, the - second array has 'void *' entries. - - 5. If 'converters' are present (converters is a sequence of argtypes' - from_param methods), for each item in 'callargs' converter is called and the - result passed to ConvParam. If 'converters' are not present, each argument - is directly passed to ConvParm. - - 6. For each arg, ConvParam stores the contained C data (or a pointer to it, - for structures) into the 'struct argument' array. - - 7. Finally, a loop fills the 'void *' array so that each item points to the - data contained in or pointed to by the 'struct argument' array. - - 8. The 'void *' argument array is what _call_function_pointer - expects. _call_function_pointer then has very little to do - only some - libffi specific stuff, then it calls ffi_call. - - So, there are 4 data structures holding processed arguments: - - the inargs tuple (in PyCFuncPtr_call) - - the callargs tuple (in PyCFuncPtr_call) - - the 'struct arguments' array - - the 'void *' array - - */ - -#include "Python.h" +/* + * History: First version dated from 3/97, derived from my SCMLIB version + * for win16. + */ +/* + * Related Work: + * - calldll http://www.nightmare.com/software.html + * - libffi http://sourceware.cygnus.com/libffi/ + * - ffcall http://clisp.cons.org/~haible/packages-ffcall.html + * and, of course, Don Beaudry's MESS package, but this is more ctypes + * related. + */ + + +/* + How are functions called, and how are parameters converted to C ? + + 1. _ctypes.c::PyCFuncPtr_call receives an argument tuple 'inargs' and a + keyword dictionary 'kwds'. + + 2. After several checks, _build_callargs() is called which returns another + tuple 'callargs'. This may be the same tuple as 'inargs', a slice of + 'inargs', or a completely fresh tuple, depending on several things (is it a + COM method?, are 'paramflags' available?). + + 3. _build_callargs also calculates bitarrays containing indexes into + the callargs tuple, specifying how to build the return value(s) of + the function. + + 4. _ctypes_callproc is then called with the 'callargs' tuple. _ctypes_callproc first + allocates two arrays. The first is an array of 'struct argument' items, the + second array has 'void *' entries. + + 5. If 'converters' are present (converters is a sequence of argtypes' + from_param methods), for each item in 'callargs' converter is called and the + result passed to ConvParam. If 'converters' are not present, each argument + is directly passed to ConvParm. + + 6. For each arg, ConvParam stores the contained C data (or a pointer to it, + for structures) into the 'struct argument' array. + + 7. Finally, a loop fills the 'void *' array so that each item points to the + data contained in or pointed to by the 'struct argument' array. + + 8. The 'void *' argument array is what _call_function_pointer + expects. _call_function_pointer then has very little to do - only some + libffi specific stuff, then it calls ffi_call. + + So, there are 4 data structures holding processed arguments: + - the inargs tuple (in PyCFuncPtr_call) + - the callargs tuple (in PyCFuncPtr_call) + - the 'struct arguments' array + - the 'void *' array + + */ + +#include "Python.h" #include "structmember.h" // PyMemberDef - + #include -#ifdef MS_WIN32 -#include -#include -#include -#else -#include "ctypes_dlfcn.h" -#endif - +#ifdef MS_WIN32 +#include +#include +#include +#else +#include "ctypes_dlfcn.h" +#endif + #ifdef __APPLE__ #include #endif -#ifdef MS_WIN32 -#include -#endif - -#include -#include "ctypes.h" -#ifdef HAVE_ALLOCA_H -/* AIX needs alloca.h for alloca() */ -#include -#endif - -#ifdef _Py_MEMORY_SANITIZER -#include -#endif - -#if defined(_DEBUG) || defined(__MINGW32__) -/* Don't use structured exception handling on Windows if this is defined. - MingW, AFAIK, doesn't support it. -*/ -#define DONT_USE_SEH -#endif - -#define CTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem" - -static void pymem_destructor(PyObject *ptr) -{ - void *p = PyCapsule_GetPointer(ptr, CTYPES_CAPSULE_NAME_PYMEM); - if (p) { - PyMem_Free(p); - } -} - -/* - ctypes maintains thread-local storage that has space for two error numbers: - private copies of the system 'errno' value and, on Windows, the system error code - accessed by the GetLastError() and SetLastError() api functions. - - Foreign functions created with CDLL(..., use_errno=True), when called, swap - the system 'errno' value with the private copy just before the actual - function call, and swapped again immediately afterwards. The 'use_errno' - parameter defaults to False, in this case 'ctypes_errno' is not touched. - - On Windows, foreign functions created with CDLL(..., use_last_error=True) or - WinDLL(..., use_last_error=True) swap the system LastError value with the - ctypes private copy. - +#ifdef MS_WIN32 +#include +#endif + +#include +#include "ctypes.h" +#ifdef HAVE_ALLOCA_H +/* AIX needs alloca.h for alloca() */ +#include +#endif + +#ifdef _Py_MEMORY_SANITIZER +#include +#endif + +#if defined(_DEBUG) || defined(__MINGW32__) +/* Don't use structured exception handling on Windows if this is defined. + MingW, AFAIK, doesn't support it. +*/ +#define DONT_USE_SEH +#endif + +#define CTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem" + +static void pymem_destructor(PyObject *ptr) +{ + void *p = PyCapsule_GetPointer(ptr, CTYPES_CAPSULE_NAME_PYMEM); + if (p) { + PyMem_Free(p); + } +} + +/* + ctypes maintains thread-local storage that has space for two error numbers: + private copies of the system 'errno' value and, on Windows, the system error code + accessed by the GetLastError() and SetLastError() api functions. + + Foreign functions created with CDLL(..., use_errno=True), when called, swap + the system 'errno' value with the private copy just before the actual + function call, and swapped again immediately afterwards. The 'use_errno' + parameter defaults to False, in this case 'ctypes_errno' is not touched. + + On Windows, foreign functions created with CDLL(..., use_last_error=True) or + WinDLL(..., use_last_error=True) swap the system LastError value with the + ctypes private copy. + The values are also swapped immediately before and after ctypes callback - functions are called, if the callbacks are constructed using the new - optional use_errno parameter set to True: CFUNCTYPE(..., use_errno=TRUE) or - WINFUNCTYPE(..., use_errno=True). - - New ctypes functions are provided to access the ctypes private copies from - Python: - - - ctypes.set_errno(value) and ctypes.set_last_error(value) store 'value' in - the private copy and returns the previous value. - - - ctypes.get_errno() and ctypes.get_last_error() returns the current ctypes - private copies value. -*/ - -/* - This function creates and returns a thread-local Python object that has - space to store two integer error numbers; once created the Python object is - kept alive in the thread state dictionary as long as the thread itself. -*/ -PyObject * -_ctypes_get_errobj(int **pspace) -{ - PyObject *dict = PyThreadState_GetDict(); - PyObject *errobj; - static PyObject *error_object_name; - if (dict == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "cannot get thread state"); - return NULL; - } - if (error_object_name == NULL) { - error_object_name = PyUnicode_InternFromString("ctypes.error_object"); - if (error_object_name == NULL) - return NULL; - } + functions are called, if the callbacks are constructed using the new + optional use_errno parameter set to True: CFUNCTYPE(..., use_errno=TRUE) or + WINFUNCTYPE(..., use_errno=True). + + New ctypes functions are provided to access the ctypes private copies from + Python: + + - ctypes.set_errno(value) and ctypes.set_last_error(value) store 'value' in + the private copy and returns the previous value. + + - ctypes.get_errno() and ctypes.get_last_error() returns the current ctypes + private copies value. +*/ + +/* + This function creates and returns a thread-local Python object that has + space to store two integer error numbers; once created the Python object is + kept alive in the thread state dictionary as long as the thread itself. +*/ +PyObject * +_ctypes_get_errobj(int **pspace) +{ + PyObject *dict = PyThreadState_GetDict(); + PyObject *errobj; + static PyObject *error_object_name; + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); + return NULL; + } + if (error_object_name == NULL) { + error_object_name = PyUnicode_InternFromString("ctypes.error_object"); + if (error_object_name == NULL) + return NULL; + } errobj = PyDict_GetItemWithError(dict, error_object_name); - if (errobj) { - if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) { - PyErr_SetString(PyExc_RuntimeError, - "ctypes.error_object is an invalid capsule"); - return NULL; - } - Py_INCREF(errobj); - } + if (errobj) { + if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) { + PyErr_SetString(PyExc_RuntimeError, + "ctypes.error_object is an invalid capsule"); + return NULL; + } + Py_INCREF(errobj); + } else if (!PyErr_Occurred()) { void *space = PyMem_Calloc(2, sizeof(int)); - if (space == NULL) - return NULL; - errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); - if (errobj == NULL) { - PyMem_Free(space); - return NULL; - } - if (-1 == PyDict_SetItem(dict, error_object_name, - errobj)) { - Py_DECREF(errobj); - return NULL; - } - } + if (space == NULL) + return NULL; + errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); + if (errobj == NULL) { + PyMem_Free(space); + return NULL; + } + if (-1 == PyDict_SetItem(dict, error_object_name, + errobj)) { + Py_DECREF(errobj); + return NULL; + } + } else { return NULL; } - *pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM); - return errobj; -} - -static PyObject * -get_error_internal(PyObject *self, PyObject *args, int index) -{ - int *space; - PyObject *errobj = _ctypes_get_errobj(&space); - PyObject *result; - - if (errobj == NULL) - return NULL; - result = PyLong_FromLong(space[index]); - Py_DECREF(errobj); - return result; -} - -static PyObject * -set_error_internal(PyObject *self, PyObject *args, int index) -{ - int new_errno, old_errno; - PyObject *errobj; - int *space; - + *pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM); + return errobj; +} + +static PyObject * +get_error_internal(PyObject *self, PyObject *args, int index) +{ + int *space; + PyObject *errobj = _ctypes_get_errobj(&space); + PyObject *result; + + if (errobj == NULL) + return NULL; + result = PyLong_FromLong(space[index]); + Py_DECREF(errobj); + return result; +} + +static PyObject * +set_error_internal(PyObject *self, PyObject *args, int index) +{ + int new_errno, old_errno; + PyObject *errobj; + int *space; + if (!PyArg_ParseTuple(args, "i", &new_errno)) { - return NULL; - } - errobj = _ctypes_get_errobj(&space); - if (errobj == NULL) - return NULL; - old_errno = space[index]; - space[index] = new_errno; - Py_DECREF(errobj); - return PyLong_FromLong(old_errno); -} - -static PyObject * -get_errno(PyObject *self, PyObject *args) -{ + return NULL; + } + errobj = _ctypes_get_errobj(&space); + if (errobj == NULL) + return NULL; + old_errno = space[index]; + space[index] = new_errno; + Py_DECREF(errobj); + return PyLong_FromLong(old_errno); +} + +static PyObject * +get_errno(PyObject *self, PyObject *args) +{ if (PySys_Audit("ctypes.get_errno", NULL) < 0) { return NULL; } - return get_error_internal(self, args, 0); -} - -static PyObject * -set_errno(PyObject *self, PyObject *args) -{ + return get_error_internal(self, args, 0); +} + +static PyObject * +set_errno(PyObject *self, PyObject *args) +{ if (PySys_Audit("ctypes.set_errno", "O", args) < 0) { return NULL; } - return set_error_internal(self, args, 0); -} - -#ifdef MS_WIN32 - -static PyObject * -get_last_error(PyObject *self, PyObject *args) -{ + return set_error_internal(self, args, 0); +} + +#ifdef MS_WIN32 + +static PyObject * +get_last_error(PyObject *self, PyObject *args) +{ if (PySys_Audit("ctypes.get_last_error", NULL) < 0) { return NULL; } - return get_error_internal(self, args, 1); -} - -static PyObject * -set_last_error(PyObject *self, PyObject *args) -{ + return get_error_internal(self, args, 1); +} + +static PyObject * +set_last_error(PyObject *self, PyObject *args) +{ if (PySys_Audit("ctypes.set_last_error", "O", args) < 0) { return NULL; } - return set_error_internal(self, args, 1); -} - -PyObject *ComError; - -static WCHAR *FormatError(DWORD code) -{ - WCHAR *lpMsgBuf; - DWORD n; + return set_error_internal(self, args, 1); +} + +PyObject *ComError; + +static WCHAR *FormatError(DWORD code) +{ + WCHAR *lpMsgBuf; + DWORD n; n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - code, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPWSTR) &lpMsgBuf, - 0, - NULL); - if (n) { - while (iswspace(lpMsgBuf[n-1])) - --n; - lpMsgBuf[n] = L'\0'; /* rstrip() */ - } - return lpMsgBuf; -} - -#ifndef DONT_USE_SEH -static void SetException(DWORD code, EXCEPTION_RECORD *pr) -{ + NULL, + code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPWSTR) &lpMsgBuf, + 0, + NULL); + if (n) { + while (iswspace(lpMsgBuf[n-1])) + --n; + lpMsgBuf[n] = L'\0'; /* rstrip() */ + } + return lpMsgBuf; +} + +#ifndef DONT_USE_SEH +static void SetException(DWORD code, EXCEPTION_RECORD *pr) +{ if (PySys_Audit("ctypes.seh_exception", "I", code) < 0) { /* An exception was set by the audit hook */ return; } - /* The 'code' is a normal win32 error code so it could be handled by - PyErr_SetFromWindowsErr(). However, for some errors, we have additional - information not included in the error code. We handle those here and - delegate all others to the generic function. */ - switch (code) { - case EXCEPTION_ACCESS_VIOLATION: - /* The thread attempted to read from or write - to a virtual address for which it does not - have the appropriate access. */ - if (pr->ExceptionInformation[0] == 0) - PyErr_Format(PyExc_OSError, - "exception: access violation reading %p", - pr->ExceptionInformation[1]); - else - PyErr_Format(PyExc_OSError, - "exception: access violation writing %p", - pr->ExceptionInformation[1]); - break; - - case EXCEPTION_BREAKPOINT: - /* A breakpoint was encountered. */ - PyErr_SetString(PyExc_OSError, - "exception: breakpoint encountered"); - break; - - case EXCEPTION_DATATYPE_MISALIGNMENT: - /* The thread attempted to read or write data that is - misaligned on hardware that does not provide - alignment. For example, 16-bit values must be - aligned on 2-byte boundaries, 32-bit values on - 4-byte boundaries, and so on. */ - PyErr_SetString(PyExc_OSError, - "exception: datatype misalignment"); - break; - - case EXCEPTION_SINGLE_STEP: - /* A trace trap or other single-instruction mechanism - signaled that one instruction has been executed. */ - PyErr_SetString(PyExc_OSError, - "exception: single step"); - break; - - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - /* The thread attempted to access an array element - that is out of bounds, and the underlying hardware - supports bounds checking. */ - PyErr_SetString(PyExc_OSError, - "exception: array bounds exceeded"); - break; - - case EXCEPTION_FLT_DENORMAL_OPERAND: - /* One of the operands in a floating-point operation - is denormal. A denormal value is one that is too - small to represent as a standard floating-point - value. */ - PyErr_SetString(PyExc_OSError, - "exception: floating-point operand denormal"); - break; - - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - /* The thread attempted to divide a floating-point - value by a floating-point divisor of zero. */ - PyErr_SetString(PyExc_OSError, - "exception: float divide by zero"); - break; - - case EXCEPTION_FLT_INEXACT_RESULT: - /* The result of a floating-point operation cannot be - represented exactly as a decimal fraction. */ - PyErr_SetString(PyExc_OSError, - "exception: float inexact"); - break; - - case EXCEPTION_FLT_INVALID_OPERATION: - /* This exception represents any floating-point - exception not included in this list. */ - PyErr_SetString(PyExc_OSError, - "exception: float invalid operation"); - break; - - case EXCEPTION_FLT_OVERFLOW: - /* The exponent of a floating-point operation is - greater than the magnitude allowed by the - corresponding type. */ - PyErr_SetString(PyExc_OSError, - "exception: float overflow"); - break; - - case EXCEPTION_FLT_STACK_CHECK: - /* The stack overflowed or underflowed as the result - of a floating-point operation. */ - PyErr_SetString(PyExc_OSError, - "exception: stack over/underflow"); - break; - - case EXCEPTION_STACK_OVERFLOW: - /* The stack overflowed or underflowed as the result - of a floating-point operation. */ - PyErr_SetString(PyExc_OSError, - "exception: stack overflow"); - break; - - case EXCEPTION_FLT_UNDERFLOW: - /* The exponent of a floating-point operation is less - than the magnitude allowed by the corresponding - type. */ - PyErr_SetString(PyExc_OSError, - "exception: float underflow"); - break; - - case EXCEPTION_INT_DIVIDE_BY_ZERO: - /* The thread attempted to divide an integer value by - an integer divisor of zero. */ - PyErr_SetString(PyExc_OSError, - "exception: integer divide by zero"); - break; - - case EXCEPTION_INT_OVERFLOW: - /* The result of an integer operation caused a carry - out of the most significant bit of the result. */ - PyErr_SetString(PyExc_OSError, - "exception: integer overflow"); - break; - - case EXCEPTION_PRIV_INSTRUCTION: - /* The thread attempted to execute an instruction - whose operation is not allowed in the current - machine mode. */ - PyErr_SetString(PyExc_OSError, - "exception: privileged instruction"); - break; - - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - /* The thread attempted to continue execution after a - noncontinuable exception occurred. */ - PyErr_SetString(PyExc_OSError, - "exception: nocontinuable"); - break; - - default: - PyErr_SetFromWindowsErr(code); - break; - } -} - -static DWORD HandleException(EXCEPTION_POINTERS *ptrs, - DWORD *pdw, EXCEPTION_RECORD *record) -{ - *pdw = ptrs->ExceptionRecord->ExceptionCode; - *record = *ptrs->ExceptionRecord; - /* We don't want to catch breakpoint exceptions, they are used to attach - * a debugger to the process. - */ - if (*pdw == EXCEPTION_BREAKPOINT) - return EXCEPTION_CONTINUE_SEARCH; - return EXCEPTION_EXECUTE_HANDLER; -} -#endif - -static PyObject * -check_hresult(PyObject *self, PyObject *args) -{ - HRESULT hr; - if (!PyArg_ParseTuple(args, "i", &hr)) - return NULL; - if (FAILED(hr)) - return PyErr_SetFromWindowsErr(hr); - return PyLong_FromLong(hr); -} - -#endif - -/**************************************************************/ - -PyCArgObject * -PyCArgObject_new(void) -{ - PyCArgObject *p; - p = PyObject_New(PyCArgObject, &PyCArg_Type); - if (p == NULL) - return NULL; - p->pffi_type = NULL; - p->tag = '\0'; - p->obj = NULL; - memset(&p->value, 0, sizeof(p->value)); - return p; -} - -static void -PyCArg_dealloc(PyCArgObject *self) -{ - Py_XDECREF(self->obj); - PyObject_Del(self); -} - -static int -is_literal_char(unsigned char c) -{ - return c < 128 && _PyUnicode_IsPrintable(c) && c != '\\' && c != '\''; -} - -static PyObject * -PyCArg_repr(PyCArgObject *self) -{ - switch(self->tag) { - case 'b': - case 'B': + /* The 'code' is a normal win32 error code so it could be handled by + PyErr_SetFromWindowsErr(). However, for some errors, we have additional + information not included in the error code. We handle those here and + delegate all others to the generic function. */ + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: + /* The thread attempted to read from or write + to a virtual address for which it does not + have the appropriate access. */ + if (pr->ExceptionInformation[0] == 0) + PyErr_Format(PyExc_OSError, + "exception: access violation reading %p", + pr->ExceptionInformation[1]); + else + PyErr_Format(PyExc_OSError, + "exception: access violation writing %p", + pr->ExceptionInformation[1]); + break; + + case EXCEPTION_BREAKPOINT: + /* A breakpoint was encountered. */ + PyErr_SetString(PyExc_OSError, + "exception: breakpoint encountered"); + break; + + case EXCEPTION_DATATYPE_MISALIGNMENT: + /* The thread attempted to read or write data that is + misaligned on hardware that does not provide + alignment. For example, 16-bit values must be + aligned on 2-byte boundaries, 32-bit values on + 4-byte boundaries, and so on. */ + PyErr_SetString(PyExc_OSError, + "exception: datatype misalignment"); + break; + + case EXCEPTION_SINGLE_STEP: + /* A trace trap or other single-instruction mechanism + signaled that one instruction has been executed. */ + PyErr_SetString(PyExc_OSError, + "exception: single step"); + break; + + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + /* The thread attempted to access an array element + that is out of bounds, and the underlying hardware + supports bounds checking. */ + PyErr_SetString(PyExc_OSError, + "exception: array bounds exceeded"); + break; + + case EXCEPTION_FLT_DENORMAL_OPERAND: + /* One of the operands in a floating-point operation + is denormal. A denormal value is one that is too + small to represent as a standard floating-point + value. */ + PyErr_SetString(PyExc_OSError, + "exception: floating-point operand denormal"); + break; + + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + /* The thread attempted to divide a floating-point + value by a floating-point divisor of zero. */ + PyErr_SetString(PyExc_OSError, + "exception: float divide by zero"); + break; + + case EXCEPTION_FLT_INEXACT_RESULT: + /* The result of a floating-point operation cannot be + represented exactly as a decimal fraction. */ + PyErr_SetString(PyExc_OSError, + "exception: float inexact"); + break; + + case EXCEPTION_FLT_INVALID_OPERATION: + /* This exception represents any floating-point + exception not included in this list. */ + PyErr_SetString(PyExc_OSError, + "exception: float invalid operation"); + break; + + case EXCEPTION_FLT_OVERFLOW: + /* The exponent of a floating-point operation is + greater than the magnitude allowed by the + corresponding type. */ + PyErr_SetString(PyExc_OSError, + "exception: float overflow"); + break; + + case EXCEPTION_FLT_STACK_CHECK: + /* The stack overflowed or underflowed as the result + of a floating-point operation. */ + PyErr_SetString(PyExc_OSError, + "exception: stack over/underflow"); + break; + + case EXCEPTION_STACK_OVERFLOW: + /* The stack overflowed or underflowed as the result + of a floating-point operation. */ + PyErr_SetString(PyExc_OSError, + "exception: stack overflow"); + break; + + case EXCEPTION_FLT_UNDERFLOW: + /* The exponent of a floating-point operation is less + than the magnitude allowed by the corresponding + type. */ + PyErr_SetString(PyExc_OSError, + "exception: float underflow"); + break; + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + /* The thread attempted to divide an integer value by + an integer divisor of zero. */ + PyErr_SetString(PyExc_OSError, + "exception: integer divide by zero"); + break; + + case EXCEPTION_INT_OVERFLOW: + /* The result of an integer operation caused a carry + out of the most significant bit of the result. */ + PyErr_SetString(PyExc_OSError, + "exception: integer overflow"); + break; + + case EXCEPTION_PRIV_INSTRUCTION: + /* The thread attempted to execute an instruction + whose operation is not allowed in the current + machine mode. */ + PyErr_SetString(PyExc_OSError, + "exception: privileged instruction"); + break; + + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + /* The thread attempted to continue execution after a + noncontinuable exception occurred. */ + PyErr_SetString(PyExc_OSError, + "exception: nocontinuable"); + break; + + default: + PyErr_SetFromWindowsErr(code); + break; + } +} + +static DWORD HandleException(EXCEPTION_POINTERS *ptrs, + DWORD *pdw, EXCEPTION_RECORD *record) +{ + *pdw = ptrs->ExceptionRecord->ExceptionCode; + *record = *ptrs->ExceptionRecord; + /* We don't want to catch breakpoint exceptions, they are used to attach + * a debugger to the process. + */ + if (*pdw == EXCEPTION_BREAKPOINT) + return EXCEPTION_CONTINUE_SEARCH; + return EXCEPTION_EXECUTE_HANDLER; +} +#endif + +static PyObject * +check_hresult(PyObject *self, PyObject *args) +{ + HRESULT hr; + if (!PyArg_ParseTuple(args, "i", &hr)) + return NULL; + if (FAILED(hr)) + return PyErr_SetFromWindowsErr(hr); + return PyLong_FromLong(hr); +} + +#endif + +/**************************************************************/ + +PyCArgObject * +PyCArgObject_new(void) +{ + PyCArgObject *p; + p = PyObject_New(PyCArgObject, &PyCArg_Type); + if (p == NULL) + return NULL; + p->pffi_type = NULL; + p->tag = '\0'; + p->obj = NULL; + memset(&p->value, 0, sizeof(p->value)); + return p; +} + +static void +PyCArg_dealloc(PyCArgObject *self) +{ + Py_XDECREF(self->obj); + PyObject_Del(self); +} + +static int +is_literal_char(unsigned char c) +{ + return c < 128 && _PyUnicode_IsPrintable(c) && c != '\\' && c != '\''; +} + +static PyObject * +PyCArg_repr(PyCArgObject *self) +{ + switch(self->tag) { + case 'b': + case 'B': return PyUnicode_FromFormat("", - self->tag, self->value.b); - case 'h': - case 'H': + self->tag, self->value.b); + case 'h': + case 'H': return PyUnicode_FromFormat("", - self->tag, self->value.h); - case 'i': - case 'I': + self->tag, self->value.h); + case 'i': + case 'I': return PyUnicode_FromFormat("", - self->tag, self->value.i); - case 'l': - case 'L': + self->tag, self->value.i); + case 'l': + case 'L': return PyUnicode_FromFormat("", - self->tag, self->value.l); - - case 'q': - case 'Q': + self->tag, self->value.l); + + case 'q': + case 'Q': return PyUnicode_FromFormat("", - self->tag, self->value.q); - case 'd': + self->tag, self->value.q); + case 'd': case 'f': { PyObject *f = PyFloat_FromDouble((self->tag == 'f') ? self->value.f : self->value.d); if (f == NULL) { @@ -522,314 +522,314 @@ PyCArg_repr(PyCArgObject *self) Py_DECREF(f); return result; } - case 'c': - if (is_literal_char((unsigned char)self->value.c)) { + case 'c': + if (is_literal_char((unsigned char)self->value.c)) { return PyUnicode_FromFormat("", - self->tag, self->value.c); - } - else { + self->tag, self->value.c); + } + else { return PyUnicode_FromFormat("", - self->tag, (unsigned char)self->value.c); - } - -/* Hm, are these 'z' and 'Z' codes useful at all? - Shouldn't they be replaced by the functionality of c_string - and c_wstring ? -*/ - case 'z': - case 'Z': - case 'P': + self->tag, (unsigned char)self->value.c); + } + +/* Hm, are these 'z' and 'Z' codes useful at all? + Shouldn't they be replaced by the functionality of c_string + and c_wstring ? +*/ + case 'z': + case 'Z': + case 'P': return PyUnicode_FromFormat("", - self->tag, self->value.p); - break; - - default: - if (is_literal_char((unsigned char)self->tag)) { + self->tag, self->value.p); + break; + + default: + if (is_literal_char((unsigned char)self->tag)) { return PyUnicode_FromFormat("", (unsigned char)self->tag, (void *)self); - } - else { + } + else { return PyUnicode_FromFormat("", (unsigned char)self->tag, (void *)self); - } - } -} - -static PyMemberDef PyCArgType_members[] = { - { "_obj", T_OBJECT, - offsetof(PyCArgObject, obj), READONLY, - "the wrapped object" }, - { NULL }, -}; - -PyTypeObject PyCArg_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "CArgObject", - sizeof(PyCArgObject), - 0, - (destructor)PyCArg_dealloc, /* tp_dealloc */ + } + } +} + +static PyMemberDef PyCArgType_members[] = { + { "_obj", T_OBJECT, + offsetof(PyCArgObject, obj), READONLY, + "the wrapped object" }, + { NULL }, +}; + +PyTypeObject PyCArg_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "CArgObject", + sizeof(PyCArgObject), + 0, + (destructor)PyCArg_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)PyCArg_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 */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - PyCArgType_members, /* tp_members */ -}; - -/****************************************************************/ -/* - * Convert a PyObject * into a parameter suitable to pass to an - * C function call. - * - * 1. Python integers are converted to C int and passed by value. - * Py_None is converted to a C NULL pointer. - * - * 2. 3-tuples are expected to have a format character in the first - * item, which must be 'i', 'f', 'd', 'q', or 'P'. - * The second item will have to be an integer, float, double, long long - * or integer (denoting an address void *), will be converted to the - * corresponding C data type and passed by value. - * - * 3. Other Python objects are tested for an '_as_parameter_' attribute. - * The value of this attribute must be an integer which will be passed - * by value, or a 2-tuple or 3-tuple which will be used according - * to point 2 above. The third item (if any), is ignored. It is normally - * used to keep the object alive where this parameter refers to. - * XXX This convention is dangerous - you can construct arbitrary tuples - * in Python and pass them. Would it be safer to use a custom container - * datatype instead of a tuple? - * - * 4. Other Python objects cannot be passed as parameters - an exception is raised. - * - * 5. ConvParam will store the converted result in a struct containing format - * and value. - */ - -union result { - char c; - char b; - short h; - int i; - long l; - long long q; - long double D; - double d; - float f; - void *p; -}; - -struct argument { - ffi_type *ffi_type; - PyObject *keep; - union result value; -}; - -/* - * Convert a single Python object into a PyCArgObject and return it. - */ -static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) -{ - StgDictObject *dict; - pa->keep = NULL; /* so we cannot forget it later */ - - dict = PyObject_stgdict(obj); - if (dict) { - PyCArgObject *carg; - assert(dict->paramfunc); - /* If it has an stgdict, it is a CDataObject */ - carg = dict->paramfunc((CDataObject *)obj); - if (carg == NULL) - return -1; - pa->ffi_type = carg->pffi_type; - memcpy(&pa->value, &carg->value, sizeof(pa->value)); - pa->keep = (PyObject *)carg; - return 0; - } - - if (PyCArg_CheckExact(obj)) { - PyCArgObject *carg = (PyCArgObject *)obj; - pa->ffi_type = carg->pffi_type; - Py_INCREF(obj); - pa->keep = obj; - memcpy(&pa->value, &carg->value, sizeof(pa->value)); - return 0; - } - - /* check for None, integer, string or unicode and use directly if successful */ - if (obj == Py_None) { - pa->ffi_type = &ffi_type_pointer; - pa->value.p = NULL; - return 0; - } - - if (PyLong_Check(obj)) { - pa->ffi_type = &ffi_type_sint; - pa->value.i = (long)PyLong_AsUnsignedLong(obj); - if (pa->value.i == -1 && PyErr_Occurred()) { - PyErr_Clear(); - pa->value.i = PyLong_AsLong(obj); - if (pa->value.i == -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_OverflowError, - "int too long to convert"); - return -1; - } - } - return 0; - } - - if (PyBytes_Check(obj)) { - pa->ffi_type = &ffi_type_pointer; - pa->value.p = PyBytes_AsString(obj); - Py_INCREF(obj); - pa->keep = obj; - return 0; - } - -#ifdef CTYPES_UNICODE - if (PyUnicode_Check(obj)) { - pa->ffi_type = &ffi_type_pointer; - pa->value.p = PyUnicode_AsWideCharString(obj, NULL); - if (pa->value.p == NULL) - return -1; - pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); - if (!pa->keep) { - PyMem_Free(pa->value.p); - return -1; - } - return 0; - } -#endif - - { + (reprfunc)PyCArg_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 */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + PyCArgType_members, /* tp_members */ +}; + +/****************************************************************/ +/* + * Convert a PyObject * into a parameter suitable to pass to an + * C function call. + * + * 1. Python integers are converted to C int and passed by value. + * Py_None is converted to a C NULL pointer. + * + * 2. 3-tuples are expected to have a format character in the first + * item, which must be 'i', 'f', 'd', 'q', or 'P'. + * The second item will have to be an integer, float, double, long long + * or integer (denoting an address void *), will be converted to the + * corresponding C data type and passed by value. + * + * 3. Other Python objects are tested for an '_as_parameter_' attribute. + * The value of this attribute must be an integer which will be passed + * by value, or a 2-tuple or 3-tuple which will be used according + * to point 2 above. The third item (if any), is ignored. It is normally + * used to keep the object alive where this parameter refers to. + * XXX This convention is dangerous - you can construct arbitrary tuples + * in Python and pass them. Would it be safer to use a custom container + * datatype instead of a tuple? + * + * 4. Other Python objects cannot be passed as parameters - an exception is raised. + * + * 5. ConvParam will store the converted result in a struct containing format + * and value. + */ + +union result { + char c; + char b; + short h; + int i; + long l; + long long q; + long double D; + double d; + float f; + void *p; +}; + +struct argument { + ffi_type *ffi_type; + PyObject *keep; + union result value; +}; + +/* + * Convert a single Python object into a PyCArgObject and return it. + */ +static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) +{ + StgDictObject *dict; + pa->keep = NULL; /* so we cannot forget it later */ + + dict = PyObject_stgdict(obj); + if (dict) { + PyCArgObject *carg; + assert(dict->paramfunc); + /* If it has an stgdict, it is a CDataObject */ + carg = dict->paramfunc((CDataObject *)obj); + if (carg == NULL) + return -1; + pa->ffi_type = carg->pffi_type; + memcpy(&pa->value, &carg->value, sizeof(pa->value)); + pa->keep = (PyObject *)carg; + return 0; + } + + if (PyCArg_CheckExact(obj)) { + PyCArgObject *carg = (PyCArgObject *)obj; + pa->ffi_type = carg->pffi_type; + Py_INCREF(obj); + pa->keep = obj; + memcpy(&pa->value, &carg->value, sizeof(pa->value)); + return 0; + } + + /* check for None, integer, string or unicode and use directly if successful */ + if (obj == Py_None) { + pa->ffi_type = &ffi_type_pointer; + pa->value.p = NULL; + return 0; + } + + if (PyLong_Check(obj)) { + pa->ffi_type = &ffi_type_sint; + pa->value.i = (long)PyLong_AsUnsignedLong(obj); + if (pa->value.i == -1 && PyErr_Occurred()) { + PyErr_Clear(); + pa->value.i = PyLong_AsLong(obj); + if (pa->value.i == -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_OverflowError, + "int too long to convert"); + return -1; + } + } + return 0; + } + + if (PyBytes_Check(obj)) { + pa->ffi_type = &ffi_type_pointer; + pa->value.p = PyBytes_AsString(obj); + Py_INCREF(obj); + pa->keep = obj; + return 0; + } + +#ifdef CTYPES_UNICODE + if (PyUnicode_Check(obj)) { + pa->ffi_type = &ffi_type_pointer; + pa->value.p = PyUnicode_AsWideCharString(obj, NULL); + if (pa->value.p == NULL) + return -1; + pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); + if (!pa->keep) { + PyMem_Free(pa->value.p); + return -1; + } + return 0; + } +#endif + + { _Py_IDENTIFIER(_as_parameter_); - PyObject *arg; + PyObject *arg; if (_PyObject_LookupAttrId(obj, &PyId__as_parameter_, &arg) < 0) { return -1; } - /* Which types should we exactly allow here? - integers are required for using Python classes - as parameters (they have to expose the '_as_parameter_' - attribute) - */ - if (arg) { - int result; - result = ConvParam(arg, index, pa); - Py_DECREF(arg); - return result; - } - PyErr_Format(PyExc_TypeError, - "Don't know how to convert parameter %d", - Py_SAFE_DOWNCAST(index, Py_ssize_t, int)); - return -1; - } -} - + /* Which types should we exactly allow here? + integers are required for using Python classes + as parameters (they have to expose the '_as_parameter_' + attribute) + */ + if (arg) { + int result; + result = ConvParam(arg, index, pa); + Py_DECREF(arg); + return result; + } + PyErr_Format(PyExc_TypeError, + "Don't know how to convert parameter %d", + Py_SAFE_DOWNCAST(index, Py_ssize_t, int)); + return -1; + } +} + #if defined(MS_WIN32) && !defined(_WIN32_WCE) -/* -Per: https://msdn.microsoft.com/en-us/library/7572ztz4.aspx +/* +Per: https://msdn.microsoft.com/en-us/library/7572ztz4.aspx To be returned by value in RAX, user-defined types must have a length -of 1, 2, 4, 8, 16, 32, or 64 bits -*/ +of 1, 2, 4, 8, 16, 32, or 64 bits +*/ int can_return_struct_as_int(size_t s) -{ - return s == 1 || s == 2 || s == 4; -} - +{ + return s == 1 || s == 2 || s == 4; +} + int can_return_struct_as_sint64(size_t s) -{ +{ #ifdef _M_ARM // 8 byte structs cannot be returned in a register on ARM32 return 0; #else - return s == 8; -#endif -} + return s == 8; #endif - - -ffi_type *_ctypes_get_ffi_type(PyObject *obj) -{ - StgDictObject *dict; - if (obj == NULL) - return &ffi_type_sint; - dict = PyType_stgdict(obj); - if (dict == NULL) - return &ffi_type_sint; -#if defined(MS_WIN32) && !defined(_WIN32_WCE) - /* This little trick works correctly with MSVC. - It returns small structures in registers - */ - if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT) { - if (can_return_struct_as_int(dict->ffi_type_pointer.size)) - return &ffi_type_sint32; - else if (can_return_struct_as_sint64 (dict->ffi_type_pointer.size)) - return &ffi_type_sint64; - } +} #endif - return &dict->ffi_type_pointer; -} - - -/* - * libffi uses: - * - * ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, - * unsigned int nargs, - * ffi_type *rtype, - * ffi_type **atypes); - * - * and then - * - * void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); - */ -static int _call_function_pointer(int flags, - PPROC pProc, - void **avalues, - ffi_type **atypes, - ffi_type *restype, - void *resmem, + + +ffi_type *_ctypes_get_ffi_type(PyObject *obj) +{ + StgDictObject *dict; + if (obj == NULL) + return &ffi_type_sint; + dict = PyType_stgdict(obj); + if (dict == NULL) + return &ffi_type_sint; +#if defined(MS_WIN32) && !defined(_WIN32_WCE) + /* This little trick works correctly with MSVC. + It returns small structures in registers + */ + if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT) { + if (can_return_struct_as_int(dict->ffi_type_pointer.size)) + return &ffi_type_sint32; + else if (can_return_struct_as_sint64 (dict->ffi_type_pointer.size)) + return &ffi_type_sint64; + } +#endif + return &dict->ffi_type_pointer; +} + + +/* + * libffi uses: + * + * ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, + * unsigned int nargs, + * ffi_type *rtype, + * ffi_type **atypes); + * + * and then + * + * void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); + */ +static int _call_function_pointer(int flags, + PPROC pProc, + void **avalues, + ffi_type **atypes, + ffi_type *restype, + void *resmem, int argcount, int argtypecount) -{ - PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */ - PyObject *error_object = NULL; - int *space; - ffi_cif cif; - int cc; +{ + PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */ + PyObject *error_object = NULL; + int *space; + ffi_cif cif; + int cc; #if defined(MS_WIN32) && !defined(DONT_USE_SEH) - DWORD dwExceptionCode = 0; - EXCEPTION_RECORD record; -#endif - /* XXX check before here */ - if (restype == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "No ffi_type for result"); - return -1; - } - - cc = FFI_DEFAULT_ABI; + DWORD dwExceptionCode = 0; + EXCEPTION_RECORD record; +#endif + /* XXX check before here */ + if (restype == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "No ffi_type for result"); + return -1; + } + + cc = FFI_DEFAULT_ABI; #if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) && !defined(_M_ARM) - if ((flags & FUNCFLAG_CDECL) == 0) - cc = FFI_STDCALL; -#endif + if ((flags & FUNCFLAG_CDECL) == 0) + cc = FFI_STDCALL; +#endif # if USING_APPLE_OS_LIBFFI # define HAVE_FFI_PREP_CIF_VAR_RUNTIME __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *) @@ -854,9 +854,9 @@ static int _call_function_pointer(int flags, PyErr_SetString(PyExc_NotImplementedError, "ffi_prep_cif_var() is missing"); return -1; } - } + } #endif - + #if HAVE_FFI_PREP_CIF_VAR if (is_variadic) { if (HAVE_FFI_PREP_CIF_VAR_RUNTIME) { @@ -896,234 +896,234 @@ static int _call_function_pointer(int flags, } } - if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { - error_object = _ctypes_get_errobj(&space); - if (error_object == NULL) - return -1; - } - if ((flags & FUNCFLAG_PYTHONAPI) == 0) - Py_UNBLOCK_THREADS - if (flags & FUNCFLAG_USE_ERRNO) { - int temp = space[0]; - space[0] = errno; - errno = temp; - } -#ifdef MS_WIN32 - if (flags & FUNCFLAG_USE_LASTERROR) { - int temp = space[1]; - space[1] = GetLastError(); - SetLastError(temp); - } -#ifndef DONT_USE_SEH - __try { -#endif -#endif - ffi_call(&cif, (void *)pProc, resmem, avalues); -#ifdef MS_WIN32 -#ifndef DONT_USE_SEH - } - __except (HandleException(GetExceptionInformation(), - &dwExceptionCode, &record)) { - ; - } -#endif - if (flags & FUNCFLAG_USE_LASTERROR) { - int temp = space[1]; - space[1] = GetLastError(); - SetLastError(temp); - } -#endif - if (flags & FUNCFLAG_USE_ERRNO) { - int temp = space[0]; - space[0] = errno; - errno = temp; - } - if ((flags & FUNCFLAG_PYTHONAPI) == 0) - Py_BLOCK_THREADS - Py_XDECREF(error_object); -#ifdef MS_WIN32 -#ifndef DONT_USE_SEH - if (dwExceptionCode) { - SetException(dwExceptionCode, &record); - return -1; - } -#endif -#endif - if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred()) - return -1; - return 0; -} - -/* - * Convert the C value in result into a Python object, depending on restype. - * - * - If restype is NULL, return a Python integer. - * - If restype is None, return None. - * - If restype is a simple ctypes type (c_int, c_void_p), call the type's getfunc, - * pass the result to checker and return the result. - * - If restype is another ctypes type, return an instance of that. - * - Otherwise, call restype and return the result. - */ -static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker) -{ - StgDictObject *dict; - PyObject *retval, *v; - - if (restype == NULL) - return PyLong_FromLong(*(int *)result); - - if (restype == Py_None) { - Py_RETURN_NONE; - } - - dict = PyType_stgdict(restype); - if (dict == NULL) - return PyObject_CallFunction(restype, "i", *(int *)result); - - if (dict->getfunc && !_ctypes_simple_instance(restype)) { - retval = dict->getfunc(result, dict->size); - /* If restype is py_object (detected by comparing getfunc with - O_get), we have to call Py_DECREF because O_get has already - called Py_INCREF. - */ - if (dict->getfunc == _ctypes_get_fielddesc("O")->getfunc) { - Py_DECREF(retval); - } - } else - retval = PyCData_FromBaseObj(restype, NULL, 0, result); - - if (!checker || !retval) - return retval; - + if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { + error_object = _ctypes_get_errobj(&space); + if (error_object == NULL) + return -1; + } + if ((flags & FUNCFLAG_PYTHONAPI) == 0) + Py_UNBLOCK_THREADS + if (flags & FUNCFLAG_USE_ERRNO) { + int temp = space[0]; + space[0] = errno; + errno = temp; + } +#ifdef MS_WIN32 + if (flags & FUNCFLAG_USE_LASTERROR) { + int temp = space[1]; + space[1] = GetLastError(); + SetLastError(temp); + } +#ifndef DONT_USE_SEH + __try { +#endif +#endif + ffi_call(&cif, (void *)pProc, resmem, avalues); +#ifdef MS_WIN32 +#ifndef DONT_USE_SEH + } + __except (HandleException(GetExceptionInformation(), + &dwExceptionCode, &record)) { + ; + } +#endif + if (flags & FUNCFLAG_USE_LASTERROR) { + int temp = space[1]; + space[1] = GetLastError(); + SetLastError(temp); + } +#endif + if (flags & FUNCFLAG_USE_ERRNO) { + int temp = space[0]; + space[0] = errno; + errno = temp; + } + if ((flags & FUNCFLAG_PYTHONAPI) == 0) + Py_BLOCK_THREADS + Py_XDECREF(error_object); +#ifdef MS_WIN32 +#ifndef DONT_USE_SEH + if (dwExceptionCode) { + SetException(dwExceptionCode, &record); + return -1; + } +#endif +#endif + if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred()) + return -1; + return 0; +} + +/* + * Convert the C value in result into a Python object, depending on restype. + * + * - If restype is NULL, return a Python integer. + * - If restype is None, return None. + * - If restype is a simple ctypes type (c_int, c_void_p), call the type's getfunc, + * pass the result to checker and return the result. + * - If restype is another ctypes type, return an instance of that. + * - Otherwise, call restype and return the result. + */ +static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker) +{ + StgDictObject *dict; + PyObject *retval, *v; + + if (restype == NULL) + return PyLong_FromLong(*(int *)result); + + if (restype == Py_None) { + Py_RETURN_NONE; + } + + dict = PyType_stgdict(restype); + if (dict == NULL) + return PyObject_CallFunction(restype, "i", *(int *)result); + + if (dict->getfunc && !_ctypes_simple_instance(restype)) { + retval = dict->getfunc(result, dict->size); + /* If restype is py_object (detected by comparing getfunc with + O_get), we have to call Py_DECREF because O_get has already + called Py_INCREF. + */ + if (dict->getfunc == _ctypes_get_fielddesc("O")->getfunc) { + Py_DECREF(retval); + } + } else + retval = PyCData_FromBaseObj(restype, NULL, 0, result); + + if (!checker || !retval) + return retval; + v = PyObject_CallOneArg(checker, retval); - if (v == NULL) - _PyTraceback_Add("GetResult", "_ctypes/callproc.c", __LINE__-2); - Py_DECREF(retval); - return v; -} - -/* - * Raise a new exception 'exc_class', adding additional text to the original - * exception string. - */ -void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...) -{ - va_list vargs; - PyObject *tp, *v, *tb, *s, *cls_str, *msg_str; - - va_start(vargs, fmt); - s = PyUnicode_FromFormatV(fmt, vargs); - va_end(vargs); - if (!s) - return; - - PyErr_Fetch(&tp, &v, &tb); - PyErr_NormalizeException(&tp, &v, &tb); - cls_str = PyObject_Str(tp); - if (cls_str) { - PyUnicode_AppendAndDel(&s, cls_str); - PyUnicode_AppendAndDel(&s, PyUnicode_FromString(": ")); - if (s == NULL) - goto error; - } else - PyErr_Clear(); - msg_str = PyObject_Str(v); - if (msg_str) - PyUnicode_AppendAndDel(&s, msg_str); - else { - PyErr_Clear(); - PyUnicode_AppendAndDel(&s, PyUnicode_FromString("???")); - } - if (s == NULL) - goto error; - PyErr_SetObject(exc_class, s); -error: - Py_XDECREF(tp); - Py_XDECREF(v); - Py_XDECREF(tb); - Py_XDECREF(s); -} - - -#ifdef MS_WIN32 - -static PyObject * -GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) -{ - HRESULT hr; - ISupportErrorInfo *psei = NULL; - IErrorInfo *pei = NULL; - BSTR descr=NULL, helpfile=NULL, source=NULL; - GUID guid; - DWORD helpcontext=0; - LPOLESTR progid; - PyObject *obj; - LPOLESTR text; - - /* We absolutely have to release the GIL during COM method calls, - otherwise we may get a deadlock! - */ - Py_BEGIN_ALLOW_THREADS - - hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei); - if (FAILED(hr)) - goto failed; - - hr = psei->lpVtbl->InterfaceSupportsErrorInfo(psei, riid); - psei->lpVtbl->Release(psei); - if (FAILED(hr)) - goto failed; - - hr = GetErrorInfo(0, &pei); - if (hr != S_OK) - goto failed; - - pei->lpVtbl->GetDescription(pei, &descr); - pei->lpVtbl->GetGUID(pei, &guid); - pei->lpVtbl->GetHelpContext(pei, &helpcontext); - pei->lpVtbl->GetHelpFile(pei, &helpfile); - pei->lpVtbl->GetSource(pei, &source); - - pei->lpVtbl->Release(pei); - - failed: - Py_END_ALLOW_THREADS - - progid = NULL; - ProgIDFromCLSID(&guid, &progid); - - text = FormatError(errcode); - obj = Py_BuildValue( - "iu(uuuiu)", - errcode, - text, - descr, source, helpfile, helpcontext, - progid); - if (obj) { - PyErr_SetObject(ComError, obj); - Py_DECREF(obj); - } - LocalFree(text); - - if (descr) - SysFreeString(descr); - if (helpfile) - SysFreeString(helpfile); - if (source) - SysFreeString(source); - - return NULL; -} -#endif - -#if (defined(__x86_64__) && (defined(__MINGW64__) || defined(__CYGWIN__))) || \ - defined(__aarch64__) || defined(__riscv) -#define CTYPES_PASS_BY_REF_HACK -#define POW2(x) (((x & ~(x - 1)) == x) ? x : 0) -#define IS_PASS_BY_REF(x) (x > 8 || !POW2(x)) -#endif - -/* + if (v == NULL) + _PyTraceback_Add("GetResult", "_ctypes/callproc.c", __LINE__-2); + Py_DECREF(retval); + return v; +} + +/* + * Raise a new exception 'exc_class', adding additional text to the original + * exception string. + */ +void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...) +{ + va_list vargs; + PyObject *tp, *v, *tb, *s, *cls_str, *msg_str; + + va_start(vargs, fmt); + s = PyUnicode_FromFormatV(fmt, vargs); + va_end(vargs); + if (!s) + return; + + PyErr_Fetch(&tp, &v, &tb); + PyErr_NormalizeException(&tp, &v, &tb); + cls_str = PyObject_Str(tp); + if (cls_str) { + PyUnicode_AppendAndDel(&s, cls_str); + PyUnicode_AppendAndDel(&s, PyUnicode_FromString(": ")); + if (s == NULL) + goto error; + } else + PyErr_Clear(); + msg_str = PyObject_Str(v); + if (msg_str) + PyUnicode_AppendAndDel(&s, msg_str); + else { + PyErr_Clear(); + PyUnicode_AppendAndDel(&s, PyUnicode_FromString("???")); + } + if (s == NULL) + goto error; + PyErr_SetObject(exc_class, s); +error: + Py_XDECREF(tp); + Py_XDECREF(v); + Py_XDECREF(tb); + Py_XDECREF(s); +} + + +#ifdef MS_WIN32 + +static PyObject * +GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) +{ + HRESULT hr; + ISupportErrorInfo *psei = NULL; + IErrorInfo *pei = NULL; + BSTR descr=NULL, helpfile=NULL, source=NULL; + GUID guid; + DWORD helpcontext=0; + LPOLESTR progid; + PyObject *obj; + LPOLESTR text; + + /* We absolutely have to release the GIL during COM method calls, + otherwise we may get a deadlock! + */ + Py_BEGIN_ALLOW_THREADS + + hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei); + if (FAILED(hr)) + goto failed; + + hr = psei->lpVtbl->InterfaceSupportsErrorInfo(psei, riid); + psei->lpVtbl->Release(psei); + if (FAILED(hr)) + goto failed; + + hr = GetErrorInfo(0, &pei); + if (hr != S_OK) + goto failed; + + pei->lpVtbl->GetDescription(pei, &descr); + pei->lpVtbl->GetGUID(pei, &guid); + pei->lpVtbl->GetHelpContext(pei, &helpcontext); + pei->lpVtbl->GetHelpFile(pei, &helpfile); + pei->lpVtbl->GetSource(pei, &source); + + pei->lpVtbl->Release(pei); + + failed: + Py_END_ALLOW_THREADS + + progid = NULL; + ProgIDFromCLSID(&guid, &progid); + + text = FormatError(errcode); + obj = Py_BuildValue( + "iu(uuuiu)", + errcode, + text, + descr, source, helpfile, helpcontext, + progid); + if (obj) { + PyErr_SetObject(ComError, obj); + Py_DECREF(obj); + } + LocalFree(text); + + if (descr) + SysFreeString(descr); + if (helpfile) + SysFreeString(helpfile); + if (source) + SysFreeString(source); + + return NULL; +} +#endif + +#if (defined(__x86_64__) && (defined(__MINGW64__) || defined(__CYGWIN__))) || \ + defined(__aarch64__) || defined(__riscv) +#define CTYPES_PASS_BY_REF_HACK +#define POW2(x) (((x & ~(x - 1)) == x) ? x : 0) +#define IS_PASS_BY_REF(x) (x > 8 || !POW2(x)) +#endif + +/* * bpo-13097: Max number of arguments _ctypes_callproc will accept. * * This limit is enforced for the `alloca()` call in `_ctypes_callproc`, @@ -1132,40 +1132,40 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) #define CTYPES_MAX_ARGCOUNT 1024 /* - * Requirements, must be ensured by the caller: - * - argtuple is tuple of arguments - * - argtypes is either NULL, or a tuple of the same size as argtuple - * - * - XXX various requirements for restype, not yet collected - */ -PyObject *_ctypes_callproc(PPROC pProc, - PyObject *argtuple, -#ifdef MS_WIN32 - IUnknown *pIunk, - GUID *iid, -#endif - int flags, - PyObject *argtypes, /* misleading name: This is a tuple of - methods, not types: the .from_param - class methods of the types */ - PyObject *restype, - PyObject *checker) -{ - Py_ssize_t i, n, argcount, argtype_count; - void *resbuf; - struct argument *args, *pa; - ffi_type **atypes; - ffi_type *rtype; - void **avalues; - PyObject *retval = NULL; - - n = argcount = PyTuple_GET_SIZE(argtuple); -#ifdef MS_WIN32 - /* an optional COM object this pointer */ - if (pIunk) - ++argcount; -#endif - + * Requirements, must be ensured by the caller: + * - argtuple is tuple of arguments + * - argtypes is either NULL, or a tuple of the same size as argtuple + * + * - XXX various requirements for restype, not yet collected + */ +PyObject *_ctypes_callproc(PPROC pProc, + PyObject *argtuple, +#ifdef MS_WIN32 + IUnknown *pIunk, + GUID *iid, +#endif + int flags, + PyObject *argtypes, /* misleading name: This is a tuple of + methods, not types: the .from_param + class methods of the types */ + PyObject *restype, + PyObject *checker) +{ + Py_ssize_t i, n, argcount, argtype_count; + void *resbuf; + struct argument *args, *pa; + ffi_type **atypes; + ffi_type *rtype; + void **avalues; + PyObject *retval = NULL; + + n = argcount = PyTuple_GET_SIZE(argtuple); +#ifdef MS_WIN32 + /* an optional COM object this pointer */ + if (pIunk) + ++argcount; +#endif + if (argcount > CTYPES_MAX_ARGCOUNT) { PyErr_Format(PyExc_ArgError, "too many arguments (%zi), maximum is %i", @@ -1173,199 +1173,199 @@ PyObject *_ctypes_callproc(PPROC pProc, return NULL; } - args = (struct argument *)alloca(sizeof(struct argument) * argcount); - if (!args) { - PyErr_NoMemory(); - return NULL; - } - memset(args, 0, sizeof(struct argument) * argcount); - argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0; -#ifdef MS_WIN32 - if (pIunk) { - args[0].ffi_type = &ffi_type_pointer; - args[0].value.p = pIunk; - pa = &args[1]; - } else -#endif - pa = &args[0]; - - /* Convert the arguments */ - for (i = 0; i < n; ++i, ++pa) { - PyObject *converter; - PyObject *arg; - int err; - - arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */ - /* For cdecl functions, we allow more actual arguments - than the length of the argtypes tuple. - This is checked in _ctypes::PyCFuncPtr_Call - */ - if (argtypes && argtype_count > i) { - PyObject *v; - converter = PyTuple_GET_ITEM(argtypes, i); + args = (struct argument *)alloca(sizeof(struct argument) * argcount); + if (!args) { + PyErr_NoMemory(); + return NULL; + } + memset(args, 0, sizeof(struct argument) * argcount); + argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0; +#ifdef MS_WIN32 + if (pIunk) { + args[0].ffi_type = &ffi_type_pointer; + args[0].value.p = pIunk; + pa = &args[1]; + } else +#endif + pa = &args[0]; + + /* Convert the arguments */ + for (i = 0; i < n; ++i, ++pa) { + PyObject *converter; + PyObject *arg; + int err; + + arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */ + /* For cdecl functions, we allow more actual arguments + than the length of the argtypes tuple. + This is checked in _ctypes::PyCFuncPtr_Call + */ + if (argtypes && argtype_count > i) { + PyObject *v; + converter = PyTuple_GET_ITEM(argtypes, i); v = PyObject_CallOneArg(converter, arg); - if (v == NULL) { + if (v == NULL) { _ctypes_extend_error(PyExc_ArgError, "argument %zd: ", i+1); - goto cleanup; - } - - err = ConvParam(v, i+1, pa); - Py_DECREF(v); - if (-1 == err) { + goto cleanup; + } + + err = ConvParam(v, i+1, pa); + Py_DECREF(v); + if (-1 == err) { _ctypes_extend_error(PyExc_ArgError, "argument %zd: ", i+1); - goto cleanup; - } - } else { - err = ConvParam(arg, i+1, pa); - if (-1 == err) { + goto cleanup; + } + } else { + err = ConvParam(arg, i+1, pa); + if (-1 == err) { _ctypes_extend_error(PyExc_ArgError, "argument %zd: ", i+1); - goto cleanup; /* leaking ? */ - } - } - } - - rtype = _ctypes_get_ffi_type(restype); - resbuf = alloca(max(rtype->size, sizeof(ffi_arg))); - -#ifdef _Py_MEMORY_SANITIZER - /* ffi_call actually initializes resbuf, but from asm, which - * MemorySanitizer can't detect. Avoid false positives from MSan. */ - if (resbuf != NULL) { - __msan_unpoison(resbuf, max(rtype->size, sizeof(ffi_arg))); - } -#endif - avalues = (void **)alloca(sizeof(void *) * argcount); - atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount); - if (!resbuf || !avalues || !atypes) { - PyErr_NoMemory(); - goto cleanup; - } - for (i = 0; i < argcount; ++i) { - atypes[i] = args[i].ffi_type; -#ifdef CTYPES_PASS_BY_REF_HACK - size_t size = atypes[i]->size; - if (IS_PASS_BY_REF(size)) { - void *tmp = alloca(size); - if (atypes[i]->type == FFI_TYPE_STRUCT) - memcpy(tmp, args[i].value.p, size); - else - memcpy(tmp, (void*)&args[i].value, size); - - avalues[i] = tmp; - } - else -#endif - if (atypes[i]->type == FFI_TYPE_STRUCT) - avalues[i] = (void *)args[i].value.p; - else - avalues[i] = (void *)&args[i].value; - } - - if (-1 == _call_function_pointer(flags, pProc, avalues, atypes, - rtype, resbuf, + goto cleanup; /* leaking ? */ + } + } + } + + rtype = _ctypes_get_ffi_type(restype); + resbuf = alloca(max(rtype->size, sizeof(ffi_arg))); + +#ifdef _Py_MEMORY_SANITIZER + /* ffi_call actually initializes resbuf, but from asm, which + * MemorySanitizer can't detect. Avoid false positives from MSan. */ + if (resbuf != NULL) { + __msan_unpoison(resbuf, max(rtype->size, sizeof(ffi_arg))); + } +#endif + avalues = (void **)alloca(sizeof(void *) * argcount); + atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount); + if (!resbuf || !avalues || !atypes) { + PyErr_NoMemory(); + goto cleanup; + } + for (i = 0; i < argcount; ++i) { + atypes[i] = args[i].ffi_type; +#ifdef CTYPES_PASS_BY_REF_HACK + size_t size = atypes[i]->size; + if (IS_PASS_BY_REF(size)) { + void *tmp = alloca(size); + if (atypes[i]->type == FFI_TYPE_STRUCT) + memcpy(tmp, args[i].value.p, size); + else + memcpy(tmp, (void*)&args[i].value, size); + + avalues[i] = tmp; + } + else +#endif + if (atypes[i]->type == FFI_TYPE_STRUCT) + avalues[i] = (void *)args[i].value.p; + else + avalues[i] = (void *)&args[i].value; + } + + if (-1 == _call_function_pointer(flags, pProc, avalues, atypes, + rtype, resbuf, Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int), Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int))) - goto cleanup; - -#ifdef WORDS_BIGENDIAN - /* libffi returns the result in a buffer with sizeof(ffi_arg). This - causes problems on big endian machines, since the result buffer - address cannot simply be used as result pointer, instead we must - adjust the pointer value: - */ - /* - XXX I should find out and clarify why this is needed at all, - especially why adjusting for ffi_type_float must be avoided on - 64-bit platforms. - */ - if (rtype->type != FFI_TYPE_FLOAT - && rtype->type != FFI_TYPE_STRUCT - && rtype->size < sizeof(ffi_arg)) + goto cleanup; + +#ifdef WORDS_BIGENDIAN + /* libffi returns the result in a buffer with sizeof(ffi_arg). This + causes problems on big endian machines, since the result buffer + address cannot simply be used as result pointer, instead we must + adjust the pointer value: + */ + /* + XXX I should find out and clarify why this is needed at all, + especially why adjusting for ffi_type_float must be avoided on + 64-bit platforms. + */ + if (rtype->type != FFI_TYPE_FLOAT + && rtype->type != FFI_TYPE_STRUCT + && rtype->size < sizeof(ffi_arg)) { - resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size; - } -#endif - -#ifdef MS_WIN32 - if (iid && pIunk) { - if (*(int *)resbuf & 0x80000000) - retval = GetComError(*(HRESULT *)resbuf, iid, pIunk); - else - retval = PyLong_FromLong(*(int *)resbuf); - } else if (flags & FUNCFLAG_HRESULT) { - if (*(int *)resbuf & 0x80000000) - retval = PyErr_SetFromWindowsErr(*(int *)resbuf); - else - retval = PyLong_FromLong(*(int *)resbuf); - } else -#endif - retval = GetResult(restype, resbuf, checker); - cleanup: - for (i = 0; i < argcount; ++i) - Py_XDECREF(args[i].keep); - return retval; -} - -static int -_parse_voidp(PyObject *obj, void **address) -{ - *address = PyLong_AsVoidPtr(obj); - if (*address == NULL) - return 0; - return 1; -} - -#ifdef MS_WIN32 - -static const char format_error_doc[] = -"FormatError([integer]) -> string\n\ -\n\ -Convert a win32 error code into a string. If the error code is not\n\ -given, the return value of a call to GetLastError() is used.\n"; -static PyObject *format_error(PyObject *self, PyObject *args) -{ - PyObject *result; - wchar_t *lpMsgBuf; - DWORD code = 0; - if (!PyArg_ParseTuple(args, "|i:FormatError", &code)) - return NULL; - if (code == 0) - code = GetLastError(); - lpMsgBuf = FormatError(code); - if (lpMsgBuf) { - result = PyUnicode_FromWideChar(lpMsgBuf, wcslen(lpMsgBuf)); - LocalFree(lpMsgBuf); - } else { - result = PyUnicode_FromString(""); - } - return result; -} - -static const char load_library_doc[] = + resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size; + } +#endif + +#ifdef MS_WIN32 + if (iid && pIunk) { + if (*(int *)resbuf & 0x80000000) + retval = GetComError(*(HRESULT *)resbuf, iid, pIunk); + else + retval = PyLong_FromLong(*(int *)resbuf); + } else if (flags & FUNCFLAG_HRESULT) { + if (*(int *)resbuf & 0x80000000) + retval = PyErr_SetFromWindowsErr(*(int *)resbuf); + else + retval = PyLong_FromLong(*(int *)resbuf); + } else +#endif + retval = GetResult(restype, resbuf, checker); + cleanup: + for (i = 0; i < argcount; ++i) + Py_XDECREF(args[i].keep); + return retval; +} + +static int +_parse_voidp(PyObject *obj, void **address) +{ + *address = PyLong_AsVoidPtr(obj); + if (*address == NULL) + return 0; + return 1; +} + +#ifdef MS_WIN32 + +static const char format_error_doc[] = +"FormatError([integer]) -> string\n\ +\n\ +Convert a win32 error code into a string. If the error code is not\n\ +given, the return value of a call to GetLastError() is used.\n"; +static PyObject *format_error(PyObject *self, PyObject *args) +{ + PyObject *result; + wchar_t *lpMsgBuf; + DWORD code = 0; + if (!PyArg_ParseTuple(args, "|i:FormatError", &code)) + return NULL; + if (code == 0) + code = GetLastError(); + lpMsgBuf = FormatError(code); + if (lpMsgBuf) { + result = PyUnicode_FromWideChar(lpMsgBuf, wcslen(lpMsgBuf)); + LocalFree(lpMsgBuf); + } else { + result = PyUnicode_FromString(""); + } + return result; +} + +static const char load_library_doc[] = "LoadLibrary(name, load_flags) -> handle\n\ -\n\ -Load an executable (usually a DLL), and return a handle to it.\n\ -The handle may be used to locate exported functions in this\n\ +\n\ +Load an executable (usually a DLL), and return a handle to it.\n\ +The handle may be used to locate exported functions in this\n\ module. load_flags are as defined for LoadLibraryEx in the\n\ Windows API.\n"; -static PyObject *load_library(PyObject *self, PyObject *args) -{ - const WCHAR *name; - PyObject *nameobj; +static PyObject *load_library(PyObject *self, PyObject *args) +{ + const WCHAR *name; + PyObject *nameobj; int load_flags = 0; - HMODULE hMod; + HMODULE hMod; DWORD err; - + if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags)) - return NULL; - + return NULL; + _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS - name = _PyUnicode_AsUnicode(nameobj); + name = _PyUnicode_AsUnicode(nameobj); _Py_COMP_DIAG_POP - if (!name) - return NULL; - + if (!name) + return NULL; + if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) { return NULL; } @@ -1388,24 +1388,24 @@ _Py_COMP_DIAG_POP } else if (err) { return PyErr_SetFromWindowsErr(err); } -#ifdef _WIN64 - return PyLong_FromVoidPtr(hMod); -#else - return Py_BuildValue("i", hMod); -#endif -} - -static const char free_library_doc[] = -"FreeLibrary(handle) -> void\n\ -\n\ -Free the handle of an executable previously loaded by LoadLibrary.\n"; -static PyObject *free_library(PyObject *self, PyObject *args) -{ - void *hMod; +#ifdef _WIN64 + return PyLong_FromVoidPtr(hMod); +#else + return Py_BuildValue("i", hMod); +#endif +} + +static const char free_library_doc[] = +"FreeLibrary(handle) -> void\n\ +\n\ +Free the handle of an executable previously loaded by LoadLibrary.\n"; +static PyObject *free_library(PyObject *self, PyObject *args) +{ + void *hMod; BOOL result; DWORD err; - if (!PyArg_ParseTuple(args, "O&:FreeLibrary", &_parse_voidp, &hMod)) - return NULL; + if (!PyArg_ParseTuple(args, "O&:FreeLibrary", &_parse_voidp, &hMod)) + return NULL; Py_BEGIN_ALLOW_THREADS result = FreeLibrary((HMODULE)hMod); @@ -1415,41 +1415,41 @@ static PyObject *free_library(PyObject *self, PyObject *args) if (!result) { return PyErr_SetFromWindowsErr(err); } - Py_RETURN_NONE; -} - -static const char copy_com_pointer_doc[] = -"CopyComPointer(src, dst) -> HRESULT value\n"; - -static PyObject * -copy_com_pointer(PyObject *self, PyObject *args) -{ - PyObject *p1, *p2, *r = NULL; - struct argument a, b; - IUnknown *src, **pdst; - if (!PyArg_ParseTuple(args, "OO:CopyComPointer", &p1, &p2)) - return NULL; - a.keep = b.keep = NULL; - - if (-1 == ConvParam(p1, 0, &a) || -1 == ConvParam(p2, 1, &b)) - goto done; - src = (IUnknown *)a.value.p; - pdst = (IUnknown **)b.value.p; - - if (pdst == NULL) - r = PyLong_FromLong(E_POINTER); - else { - if (src) - src->lpVtbl->AddRef(src); - *pdst = src; - r = PyLong_FromLong(S_OK); - } - done: - Py_XDECREF(a.keep); - Py_XDECREF(b.keep); - return r; -} -#else + Py_RETURN_NONE; +} + +static const char copy_com_pointer_doc[] = +"CopyComPointer(src, dst) -> HRESULT value\n"; + +static PyObject * +copy_com_pointer(PyObject *self, PyObject *args) +{ + PyObject *p1, *p2, *r = NULL; + struct argument a, b; + IUnknown *src, **pdst; + if (!PyArg_ParseTuple(args, "OO:CopyComPointer", &p1, &p2)) + return NULL; + a.keep = b.keep = NULL; + + if (-1 == ConvParam(p1, 0, &a) || -1 == ConvParam(p2, 1, &b)) + goto done; + src = (IUnknown *)a.value.p; + pdst = (IUnknown **)b.value.p; + + if (pdst == NULL) + r = PyLong_FromLong(E_POINTER); + else { + if (src) + src->lpVtbl->AddRef(src); + *pdst = src; + r = PyLong_FromLong(S_OK); + } + done: + Py_XDECREF(a.keep); + Py_XDECREF(b.keep); + return r; +} +#else #ifdef __APPLE__ #ifdef HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH #define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME \ @@ -1458,7 +1458,7 @@ copy_com_pointer(PyObject *self, PyObject *args) // Support the deprecated case of compiling on an older macOS version static void *libsystem_b_handle; static bool (*_dyld_shared_cache_contains_path)(const char *path); - + __attribute__((constructor)) void load_dyld_shared_cache_contains_path(void) { libsystem_b_handle = dlopen("/usr/lib/libSystem.B.dylib", RTLD_LAZY); if (libsystem_b_handle != NULL) { @@ -1510,248 +1510,248 @@ static PyObject *py_dyld_shared_cache_contains_path(PyObject *self, PyObject *ar } #endif -static PyObject *py_dl_open(PyObject *self, PyObject *args) -{ - PyObject *name, *name2; +static PyObject *py_dl_open(PyObject *self, PyObject *args) +{ + PyObject *name, *name2; const char *name_str; - void * handle; -#if HAVE_DECL_RTLD_LOCAL - int mode = RTLD_NOW | RTLD_LOCAL; -#else - /* cygwin doesn't define RTLD_LOCAL */ - int mode = RTLD_NOW; -#endif - if (!PyArg_ParseTuple(args, "O|i:dlopen", &name, &mode)) - return NULL; - mode |= RTLD_NOW; - if (name != Py_None) { - if (PyUnicode_FSConverter(name, &name2) == 0) - return NULL; + void * handle; +#if HAVE_DECL_RTLD_LOCAL + int mode = RTLD_NOW | RTLD_LOCAL; +#else + /* cygwin doesn't define RTLD_LOCAL */ + int mode = RTLD_NOW; +#endif + if (!PyArg_ParseTuple(args, "O|i:dlopen", &name, &mode)) + return NULL; + mode |= RTLD_NOW; + if (name != Py_None) { + if (PyUnicode_FSConverter(name, &name2) == 0) + return NULL; name_str = PyBytes_AS_STRING(name2); - } else { - name_str = NULL; - name2 = NULL; - } + } else { + name_str = NULL; + name2 = NULL; + } if (PySys_Audit("ctypes.dlopen", "O", name) < 0) { return NULL; } - handle = ctypes_dlopen(name_str, mode); - Py_XDECREF(name2); - if (!handle) { - const char *errmsg = ctypes_dlerror(); - if (!errmsg) - errmsg = "dlopen() error"; - PyErr_SetString(PyExc_OSError, - errmsg); - return NULL; - } - return PyLong_FromVoidPtr(handle); -} - -static PyObject *py_dl_close(PyObject *self, PyObject *args) -{ - void *handle; - - if (!PyArg_ParseTuple(args, "O&:dlclose", &_parse_voidp, &handle)) - return NULL; - if (dlclose(handle)) { - PyErr_SetString(PyExc_OSError, - ctypes_dlerror()); - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject *py_dl_sym(PyObject *self, PyObject *args) -{ - char *name; - void *handle; - void *ptr; - - if (!PyArg_ParseTuple(args, "O&s:dlsym", - &_parse_voidp, &handle, &name)) - return NULL; + handle = ctypes_dlopen(name_str, mode); + Py_XDECREF(name2); + if (!handle) { + const char *errmsg = ctypes_dlerror(); + if (!errmsg) + errmsg = "dlopen() error"; + PyErr_SetString(PyExc_OSError, + errmsg); + return NULL; + } + return PyLong_FromVoidPtr(handle); +} + +static PyObject *py_dl_close(PyObject *self, PyObject *args) +{ + void *handle; + + if (!PyArg_ParseTuple(args, "O&:dlclose", &_parse_voidp, &handle)) + return NULL; + if (dlclose(handle)) { + PyErr_SetString(PyExc_OSError, + ctypes_dlerror()); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject *py_dl_sym(PyObject *self, PyObject *args) +{ + char *name; + void *handle; + void *ptr; + + if (!PyArg_ParseTuple(args, "O&s:dlsym", + &_parse_voidp, &handle, &name)) + return NULL; if (PySys_Audit("ctypes.dlsym/handle", "O", args) < 0) { return NULL; } - ptr = ctypes_dlsym((void*)handle, name); - if (!ptr) { - PyErr_SetString(PyExc_OSError, - ctypes_dlerror()); - return NULL; - } - return PyLong_FromVoidPtr(ptr); -} -#endif - -/* - * Only for debugging so far: So that we can call CFunction instances - * - * XXX Needs to accept more arguments: flags, argtypes, restype - */ -static PyObject * -call_function(PyObject *self, PyObject *args) -{ - void *func; - PyObject *arguments; - PyObject *result; - - if (!PyArg_ParseTuple(args, - "O&O!", - &_parse_voidp, &func, - &PyTuple_Type, &arguments)) - return NULL; + ptr = ctypes_dlsym((void*)handle, name); + if (!ptr) { + PyErr_SetString(PyExc_OSError, + ctypes_dlerror()); + return NULL; + } + return PyLong_FromVoidPtr(ptr); +} +#endif + +/* + * Only for debugging so far: So that we can call CFunction instances + * + * XXX Needs to accept more arguments: flags, argtypes, restype + */ +static PyObject * +call_function(PyObject *self, PyObject *args) +{ + void *func; + PyObject *arguments; + PyObject *result; + + if (!PyArg_ParseTuple(args, + "O&O!", + &_parse_voidp, &func, + &PyTuple_Type, &arguments)) + return NULL; if (PySys_Audit("ctypes.call_function", "nO", (Py_ssize_t)func, arguments) < 0) { return NULL; } - - result = _ctypes_callproc((PPROC)func, - arguments, -#ifdef MS_WIN32 - NULL, - NULL, -#endif - 0, /* flags */ - NULL, /* self->argtypes */ - NULL, /* self->restype */ - NULL); /* checker */ - return result; -} - -/* - * Only for debugging so far: So that we can call CFunction instances - * - * XXX Needs to accept more arguments: flags, argtypes, restype - */ -static PyObject * -call_cdeclfunction(PyObject *self, PyObject *args) -{ - void *func; - PyObject *arguments; - PyObject *result; - - if (!PyArg_ParseTuple(args, - "O&O!", - &_parse_voidp, &func, - &PyTuple_Type, &arguments)) - return NULL; + + result = _ctypes_callproc((PPROC)func, + arguments, +#ifdef MS_WIN32 + NULL, + NULL, +#endif + 0, /* flags */ + NULL, /* self->argtypes */ + NULL, /* self->restype */ + NULL); /* checker */ + return result; +} + +/* + * Only for debugging so far: So that we can call CFunction instances + * + * XXX Needs to accept more arguments: flags, argtypes, restype + */ +static PyObject * +call_cdeclfunction(PyObject *self, PyObject *args) +{ + void *func; + PyObject *arguments; + PyObject *result; + + if (!PyArg_ParseTuple(args, + "O&O!", + &_parse_voidp, &func, + &PyTuple_Type, &arguments)) + return NULL; if (PySys_Audit("ctypes.call_function", "nO", (Py_ssize_t)func, arguments) < 0) { return NULL; } - - result = _ctypes_callproc((PPROC)func, - arguments, -#ifdef MS_WIN32 - NULL, - NULL, -#endif - FUNCFLAG_CDECL, /* flags */ - NULL, /* self->argtypes */ - NULL, /* self->restype */ - NULL); /* checker */ - return result; -} - -/***************************************************************** - * functions - */ -static const char sizeof_doc[] = -"sizeof(C type) -> integer\n" -"sizeof(C instance) -> integer\n" -"Return the size in bytes of a C instance"; - -static PyObject * -sizeof_func(PyObject *self, PyObject *obj) -{ - StgDictObject *dict; - - dict = PyType_stgdict(obj); - if (dict) - return PyLong_FromSsize_t(dict->size); - - if (CDataObject_Check(obj)) - return PyLong_FromSsize_t(((CDataObject *)obj)->b_size); - PyErr_SetString(PyExc_TypeError, - "this type has no size"); - return NULL; -} - -static const char alignment_doc[] = -"alignment(C type) -> integer\n" -"alignment(C instance) -> integer\n" -"Return the alignment requirements of a C instance"; - -static PyObject * -align_func(PyObject *self, PyObject *obj) -{ - StgDictObject *dict; - - dict = PyType_stgdict(obj); - if (dict) - return PyLong_FromSsize_t(dict->align); - - dict = PyObject_stgdict(obj); - if (dict) - return PyLong_FromSsize_t(dict->align); - - PyErr_SetString(PyExc_TypeError, - "no alignment info"); - return NULL; -} - -static const char byref_doc[] = -"byref(C instance[, offset=0]) -> byref-object\n" -"Return a pointer lookalike to a C instance, only usable\n" -"as function argument"; - -/* - * We must return something which can be converted to a parameter, - * but still has a reference to self. - */ -static PyObject * -byref(PyObject *self, PyObject *args) -{ - PyCArgObject *parg; - PyObject *obj; - PyObject *pyoffset = NULL; - Py_ssize_t offset = 0; - - if (!PyArg_UnpackTuple(args, "byref", 1, 2, - &obj, &pyoffset)) - return NULL; - if (pyoffset) { - offset = PyNumber_AsSsize_t(pyoffset, NULL); - if (offset == -1 && PyErr_Occurred()) - return NULL; - } - if (!CDataObject_Check(obj)) { - PyErr_Format(PyExc_TypeError, - "byref() argument must be a ctypes instance, not '%s'", - Py_TYPE(obj)->tp_name); - return NULL; - } - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - - parg->tag = 'P'; - parg->pffi_type = &ffi_type_pointer; - Py_INCREF(obj); - parg->obj = obj; - parg->value.p = (char *)((CDataObject *)obj)->b_ptr + offset; - return (PyObject *)parg; -} - -static const char addressof_doc[] = -"addressof(C instance) -> integer\n" -"Return the address of the C instance internal buffer"; - -static PyObject * -addressof(PyObject *self, PyObject *obj) -{ + + result = _ctypes_callproc((PPROC)func, + arguments, +#ifdef MS_WIN32 + NULL, + NULL, +#endif + FUNCFLAG_CDECL, /* flags */ + NULL, /* self->argtypes */ + NULL, /* self->restype */ + NULL); /* checker */ + return result; +} + +/***************************************************************** + * functions + */ +static const char sizeof_doc[] = +"sizeof(C type) -> integer\n" +"sizeof(C instance) -> integer\n" +"Return the size in bytes of a C instance"; + +static PyObject * +sizeof_func(PyObject *self, PyObject *obj) +{ + StgDictObject *dict; + + dict = PyType_stgdict(obj); + if (dict) + return PyLong_FromSsize_t(dict->size); + + if (CDataObject_Check(obj)) + return PyLong_FromSsize_t(((CDataObject *)obj)->b_size); + PyErr_SetString(PyExc_TypeError, + "this type has no size"); + return NULL; +} + +static const char alignment_doc[] = +"alignment(C type) -> integer\n" +"alignment(C instance) -> integer\n" +"Return the alignment requirements of a C instance"; + +static PyObject * +align_func(PyObject *self, PyObject *obj) +{ + StgDictObject *dict; + + dict = PyType_stgdict(obj); + if (dict) + return PyLong_FromSsize_t(dict->align); + + dict = PyObject_stgdict(obj); + if (dict) + return PyLong_FromSsize_t(dict->align); + + PyErr_SetString(PyExc_TypeError, + "no alignment info"); + return NULL; +} + +static const char byref_doc[] = +"byref(C instance[, offset=0]) -> byref-object\n" +"Return a pointer lookalike to a C instance, only usable\n" +"as function argument"; + +/* + * We must return something which can be converted to a parameter, + * but still has a reference to self. + */ +static PyObject * +byref(PyObject *self, PyObject *args) +{ + PyCArgObject *parg; + PyObject *obj; + PyObject *pyoffset = NULL; + Py_ssize_t offset = 0; + + if (!PyArg_UnpackTuple(args, "byref", 1, 2, + &obj, &pyoffset)) + return NULL; + if (pyoffset) { + offset = PyNumber_AsSsize_t(pyoffset, NULL); + if (offset == -1 && PyErr_Occurred()) + return NULL; + } + if (!CDataObject_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "byref() argument must be a ctypes instance, not '%s'", + Py_TYPE(obj)->tp_name); + return NULL; + } + + parg = PyCArgObject_new(); + if (parg == NULL) + return NULL; + + parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; + Py_INCREF(obj); + parg->obj = obj; + parg->value.p = (char *)((CDataObject *)obj)->b_ptr + offset; + return (PyObject *)parg; +} + +static const char addressof_doc[] = +"addressof(C instance) -> integer\n" +"Return the address of the C instance internal buffer"; + +static PyObject * +addressof(PyObject *self, PyObject *obj) +{ if (!CDataObject_Check(obj)) { PyErr_SetString(PyExc_TypeError, "invalid type"); @@ -1761,202 +1761,202 @@ addressof(PyObject *self, PyObject *obj) return NULL; } return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr); -} - -static int -converter(PyObject *obj, void **address) -{ - *address = PyLong_AsVoidPtr(obj); - return *address != NULL; -} - -static PyObject * -My_PyObj_FromPtr(PyObject *self, PyObject *args) -{ - PyObject *ob; +} + +static int +converter(PyObject *obj, void **address) +{ + *address = PyLong_AsVoidPtr(obj); + return *address != NULL; +} + +static PyObject * +My_PyObj_FromPtr(PyObject *self, PyObject *args) +{ + PyObject *ob; if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) { - return NULL; + return NULL; } if (PySys_Audit("ctypes.PyObj_FromPtr", "(O)", ob) < 0) { return NULL; } - Py_INCREF(ob); - return ob; -} - -static PyObject * -My_Py_INCREF(PyObject *self, PyObject *arg) -{ - Py_INCREF(arg); /* that's what this function is for */ - Py_INCREF(arg); /* that for returning it */ - return arg; -} - -static PyObject * -My_Py_DECREF(PyObject *self, PyObject *arg) -{ - Py_DECREF(arg); /* that's what this function is for */ - Py_INCREF(arg); /* that's for returning it */ - return arg; -} - -static PyObject * -resize(PyObject *self, PyObject *args) -{ - CDataObject *obj; - StgDictObject *dict; - Py_ssize_t size; - - if (!PyArg_ParseTuple(args, - "On:resize", - &obj, &size)) - return NULL; - - dict = PyObject_stgdict((PyObject *)obj); - if (dict == NULL) { - PyErr_SetString(PyExc_TypeError, - "excepted ctypes instance"); - return NULL; - } - if (size < dict->size) { - PyErr_Format(PyExc_ValueError, - "minimum size is %zd", - dict->size); - return NULL; - } - if (obj->b_needsfree == 0) { - PyErr_Format(PyExc_ValueError, - "Memory cannot be resized because this object doesn't own it"); - return NULL; - } - if ((size_t)size <= sizeof(obj->b_value)) { - /* internal default buffer is large enough */ - obj->b_size = size; - goto done; - } - if (!_CDataObject_HasExternalBuffer(obj)) { - /* We are currently using the objects default buffer, but it - isn't large enough any more. */ + Py_INCREF(ob); + return ob; +} + +static PyObject * +My_Py_INCREF(PyObject *self, PyObject *arg) +{ + Py_INCREF(arg); /* that's what this function is for */ + Py_INCREF(arg); /* that for returning it */ + return arg; +} + +static PyObject * +My_Py_DECREF(PyObject *self, PyObject *arg) +{ + Py_DECREF(arg); /* that's what this function is for */ + Py_INCREF(arg); /* that's for returning it */ + return arg; +} + +static PyObject * +resize(PyObject *self, PyObject *args) +{ + CDataObject *obj; + StgDictObject *dict; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, + "On:resize", + &obj, &size)) + return NULL; + + dict = PyObject_stgdict((PyObject *)obj); + if (dict == NULL) { + PyErr_SetString(PyExc_TypeError, + "excepted ctypes instance"); + return NULL; + } + if (size < dict->size) { + PyErr_Format(PyExc_ValueError, + "minimum size is %zd", + dict->size); + return NULL; + } + if (obj->b_needsfree == 0) { + PyErr_Format(PyExc_ValueError, + "Memory cannot be resized because this object doesn't own it"); + return NULL; + } + if ((size_t)size <= sizeof(obj->b_value)) { + /* internal default buffer is large enough */ + obj->b_size = size; + goto done; + } + if (!_CDataObject_HasExternalBuffer(obj)) { + /* We are currently using the objects default buffer, but it + isn't large enough any more. */ void *ptr = PyMem_Calloc(1, size); - if (ptr == NULL) - return PyErr_NoMemory(); - memmove(ptr, obj->b_ptr, obj->b_size); - obj->b_ptr = ptr; - obj->b_size = size; - } else { - void * ptr = PyMem_Realloc(obj->b_ptr, size); - if (ptr == NULL) - return PyErr_NoMemory(); - obj->b_ptr = ptr; - obj->b_size = size; - } - done: - Py_RETURN_NONE; -} - -static PyObject * -unpickle(PyObject *self, PyObject *args) -{ - PyObject *typ, *state, *meth, *obj, *result; - _Py_IDENTIFIER(__new__); - _Py_IDENTIFIER(__setstate__); - - if (!PyArg_ParseTuple(args, "OO!", &typ, &PyTuple_Type, &state)) - return NULL; + if (ptr == NULL) + return PyErr_NoMemory(); + memmove(ptr, obj->b_ptr, obj->b_size); + obj->b_ptr = ptr; + obj->b_size = size; + } else { + void * ptr = PyMem_Realloc(obj->b_ptr, size); + if (ptr == NULL) + return PyErr_NoMemory(); + obj->b_ptr = ptr; + obj->b_size = size; + } + done: + Py_RETURN_NONE; +} + +static PyObject * +unpickle(PyObject *self, PyObject *args) +{ + PyObject *typ, *state, *meth, *obj, *result; + _Py_IDENTIFIER(__new__); + _Py_IDENTIFIER(__setstate__); + + if (!PyArg_ParseTuple(args, "OO!", &typ, &PyTuple_Type, &state)) + return NULL; obj = _PyObject_CallMethodIdOneArg(typ, &PyId___new__, typ); - if (obj == NULL) - return NULL; - - meth = _PyObject_GetAttrId(obj, &PyId___setstate__); - if (meth == NULL) { - goto error; - } - - result = PyObject_Call(meth, state, NULL); - Py_DECREF(meth); - if (result == NULL) { - goto error; - } - Py_DECREF(result); - - return obj; - -error: - Py_DECREF(obj); - return NULL; -} - -static PyObject * -POINTER(PyObject *self, PyObject *cls) -{ - PyObject *result; - PyTypeObject *typ; - PyObject *key; - char *buf; - + if (obj == NULL) + return NULL; + + meth = _PyObject_GetAttrId(obj, &PyId___setstate__); + if (meth == NULL) { + goto error; + } + + result = PyObject_Call(meth, state, NULL); + Py_DECREF(meth); + if (result == NULL) { + goto error; + } + Py_DECREF(result); + + return obj; + +error: + Py_DECREF(obj); + return NULL; +} + +static PyObject * +POINTER(PyObject *self, PyObject *cls) +{ + PyObject *result; + PyTypeObject *typ; + PyObject *key; + char *buf; + result = PyDict_GetItemWithError(_ctypes_ptrtype_cache, cls); - if (result) { - Py_INCREF(result); - return result; - } + if (result) { + Py_INCREF(result); + return result; + } else if (PyErr_Occurred()) { return NULL; } - if (PyUnicode_CheckExact(cls)) { - const char *name = PyUnicode_AsUTF8(cls); - if (name == NULL) - return NULL; - buf = PyMem_Malloc(strlen(name) + 3 + 1); - if (buf == NULL) - return PyErr_NoMemory(); - sprintf(buf, "LP_%s", name); - result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), - "s(O){}", - buf, - &PyCPointer_Type); - PyMem_Free(buf); - if (result == NULL) - return result; - key = PyLong_FromVoidPtr(result); - if (key == NULL) { - Py_DECREF(result); - return NULL; - } - } else if (PyType_Check(cls)) { - typ = (PyTypeObject *)cls; - buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1); - if (buf == NULL) - return PyErr_NoMemory(); - sprintf(buf, "LP_%s", typ->tp_name); - result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), - "s(O){sO}", - buf, - &PyCPointer_Type, - "_type_", cls); - PyMem_Free(buf); - if (result == NULL) - return result; - Py_INCREF(cls); - key = cls; - } else { - PyErr_SetString(PyExc_TypeError, "must be a ctypes type"); - return NULL; - } - if (-1 == PyDict_SetItem(_ctypes_ptrtype_cache, key, result)) { - Py_DECREF(result); - Py_DECREF(key); - return NULL; - } - Py_DECREF(key); - return result; -} - -static PyObject * -pointer(PyObject *self, PyObject *arg) -{ - PyObject *result; - PyObject *typ; - + if (PyUnicode_CheckExact(cls)) { + const char *name = PyUnicode_AsUTF8(cls); + if (name == NULL) + return NULL; + buf = PyMem_Malloc(strlen(name) + 3 + 1); + if (buf == NULL) + return PyErr_NoMemory(); + sprintf(buf, "LP_%s", name); + result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), + "s(O){}", + buf, + &PyCPointer_Type); + PyMem_Free(buf); + if (result == NULL) + return result; + key = PyLong_FromVoidPtr(result); + if (key == NULL) { + Py_DECREF(result); + return NULL; + } + } else if (PyType_Check(cls)) { + typ = (PyTypeObject *)cls; + buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1); + if (buf == NULL) + return PyErr_NoMemory(); + sprintf(buf, "LP_%s", typ->tp_name); + result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), + "s(O){sO}", + buf, + &PyCPointer_Type, + "_type_", cls); + PyMem_Free(buf); + if (result == NULL) + return result; + Py_INCREF(cls); + key = cls; + } else { + PyErr_SetString(PyExc_TypeError, "must be a ctypes type"); + return NULL; + } + if (-1 == PyDict_SetItem(_ctypes_ptrtype_cache, key, result)) { + Py_DECREF(result); + Py_DECREF(key); + return NULL; + } + Py_DECREF(key); + return result; +} + +static PyObject * +pointer(PyObject *self, PyObject *arg) +{ + PyObject *result; + PyObject *typ; + typ = PyDict_GetItemWithError(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)); if (typ) { return PyObject_CallOneArg(typ, arg); @@ -1964,82 +1964,82 @@ pointer(PyObject *self, PyObject *arg) else if (PyErr_Occurred()) { return NULL; } - typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); - if (typ == NULL) + typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); + if (typ == NULL) return NULL; result = PyObject_CallOneArg(typ, arg); - Py_DECREF(typ); - return result; -} - -static PyObject * -buffer_info(PyObject *self, PyObject *arg) -{ - StgDictObject *dict = PyType_stgdict(arg); - PyObject *shape; - Py_ssize_t i; - - if (dict == NULL) - dict = PyObject_stgdict(arg); - if (dict == NULL) { - PyErr_SetString(PyExc_TypeError, - "not a ctypes type or object"); - return NULL; - } - shape = PyTuple_New(dict->ndim); - if (shape == NULL) - return NULL; - for (i = 0; i < (int)dict->ndim; ++i) - PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i])); - - if (PyErr_Occurred()) { - Py_DECREF(shape); - return NULL; - } - return Py_BuildValue("siN", dict->format, dict->ndim, shape); -} - - - -PyMethodDef _ctypes_module_methods[] = { - {"get_errno", get_errno, METH_NOARGS}, - {"set_errno", set_errno, METH_VARARGS}, - {"POINTER", POINTER, METH_O }, - {"pointer", pointer, METH_O }, - {"_unpickle", unpickle, METH_VARARGS }, - {"buffer_info", buffer_info, METH_O, "Return buffer interface information"}, - {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"}, -#ifdef MS_WIN32 - {"get_last_error", get_last_error, METH_NOARGS}, - {"set_last_error", set_last_error, METH_VARARGS}, - {"CopyComPointer", copy_com_pointer, METH_VARARGS, copy_com_pointer_doc}, - {"FormatError", format_error, METH_VARARGS, format_error_doc}, - {"LoadLibrary", load_library, METH_VARARGS, load_library_doc}, - {"FreeLibrary", free_library, METH_VARARGS, free_library_doc}, - {"_check_HRESULT", check_hresult, METH_VARARGS}, -#else - {"dlopen", py_dl_open, METH_VARARGS, - "dlopen(name, flag={RTLD_GLOBAL|RTLD_LOCAL}) open a shared library"}, - {"dlclose", py_dl_close, METH_VARARGS, "dlclose a library"}, - {"dlsym", py_dl_sym, METH_VARARGS, "find symbol in shared library"}, -#endif + Py_DECREF(typ); + return result; +} + +static PyObject * +buffer_info(PyObject *self, PyObject *arg) +{ + StgDictObject *dict = PyType_stgdict(arg); + PyObject *shape; + Py_ssize_t i; + + if (dict == NULL) + dict = PyObject_stgdict(arg); + if (dict == NULL) { + PyErr_SetString(PyExc_TypeError, + "not a ctypes type or object"); + return NULL; + } + shape = PyTuple_New(dict->ndim); + if (shape == NULL) + return NULL; + for (i = 0; i < (int)dict->ndim; ++i) + PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i])); + + if (PyErr_Occurred()) { + Py_DECREF(shape); + return NULL; + } + return Py_BuildValue("siN", dict->format, dict->ndim, shape); +} + + + +PyMethodDef _ctypes_module_methods[] = { + {"get_errno", get_errno, METH_NOARGS}, + {"set_errno", set_errno, METH_VARARGS}, + {"POINTER", POINTER, METH_O }, + {"pointer", pointer, METH_O }, + {"_unpickle", unpickle, METH_VARARGS }, + {"buffer_info", buffer_info, METH_O, "Return buffer interface information"}, + {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"}, +#ifdef MS_WIN32 + {"get_last_error", get_last_error, METH_NOARGS}, + {"set_last_error", set_last_error, METH_VARARGS}, + {"CopyComPointer", copy_com_pointer, METH_VARARGS, copy_com_pointer_doc}, + {"FormatError", format_error, METH_VARARGS, format_error_doc}, + {"LoadLibrary", load_library, METH_VARARGS, load_library_doc}, + {"FreeLibrary", free_library, METH_VARARGS, free_library_doc}, + {"_check_HRESULT", check_hresult, METH_VARARGS}, +#else + {"dlopen", py_dl_open, METH_VARARGS, + "dlopen(name, flag={RTLD_GLOBAL|RTLD_LOCAL}) open a shared library"}, + {"dlclose", py_dl_close, METH_VARARGS, "dlclose a library"}, + {"dlsym", py_dl_sym, METH_VARARGS, "find symbol in shared library"}, +#endif #ifdef __APPLE__ {"_dyld_shared_cache_contains_path", py_dyld_shared_cache_contains_path, METH_VARARGS, "check if path is in the shared cache"}, #endif - {"alignment", align_func, METH_O, alignment_doc}, - {"sizeof", sizeof_func, METH_O, sizeof_doc}, - {"byref", byref, METH_VARARGS, byref_doc}, - {"addressof", addressof, METH_O, addressof_doc}, - {"call_function", call_function, METH_VARARGS }, - {"call_cdeclfunction", call_cdeclfunction, METH_VARARGS }, - {"PyObj_FromPtr", My_PyObj_FromPtr, METH_VARARGS }, - {"Py_INCREF", My_Py_INCREF, METH_O }, - {"Py_DECREF", My_Py_DECREF, METH_O }, - {NULL, NULL} /* Sentinel */ -}; - -/* - Local Variables: - compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~" - End: -*/ + {"alignment", align_func, METH_O, alignment_doc}, + {"sizeof", sizeof_func, METH_O, sizeof_doc}, + {"byref", byref, METH_VARARGS, byref_doc}, + {"addressof", addressof, METH_O, addressof_doc}, + {"call_function", call_function, METH_VARARGS }, + {"call_cdeclfunction", call_cdeclfunction, METH_VARARGS }, + {"PyObj_FromPtr", My_PyObj_FromPtr, METH_VARARGS }, + {"Py_INCREF", My_Py_INCREF, METH_O }, + {"Py_DECREF", My_Py_DECREF, METH_O }, + {NULL, NULL} /* Sentinel */ +}; + +/* + Local Variables: + compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~" + End: +*/ diff --git a/contrib/tools/python3/src/Modules/_ctypes/cfield.c b/contrib/tools/python3/src/Modules/_ctypes/cfield.c index 26477776664..1aea58f1c41 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/cfield.c +++ b/contrib/tools/python3/src/Modules/_ctypes/cfield.c @@ -1,474 +1,474 @@ -#include "Python.h" +#include "Python.h" #include "pycore_byteswap.h" // _Py_bswap32() - -#include -#ifdef MS_WIN32 -#include -#include -#endif -#include "ctypes.h" - - -#define CTYPES_CFIELD_CAPSULE_NAME_PYMEM "_ctypes/cfield.c pymem" - -static void pymem_destructor(PyObject *ptr) -{ - void *p = PyCapsule_GetPointer(ptr, CTYPES_CFIELD_CAPSULE_NAME_PYMEM); - if (p) { - PyMem_Free(p); - } -} - - -/******************************************************************/ -/* - PyCField_Type -*/ -static PyObject * -PyCField_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - CFieldObject *obj; - obj = (CFieldObject *)type->tp_alloc(type, 0); - return (PyObject *)obj; -} - -/* - * Expects the size, index and offset for the current field in *psize and - * *poffset, stores the total size so far in *psize, the offset for the next - * field in *poffset, the alignment requirements for the current field in + +#include +#ifdef MS_WIN32 +#include +#include +#endif +#include "ctypes.h" + + +#define CTYPES_CFIELD_CAPSULE_NAME_PYMEM "_ctypes/cfield.c pymem" + +static void pymem_destructor(PyObject *ptr) +{ + void *p = PyCapsule_GetPointer(ptr, CTYPES_CFIELD_CAPSULE_NAME_PYMEM); + if (p) { + PyMem_Free(p); + } +} + + +/******************************************************************/ +/* + PyCField_Type +*/ +static PyObject * +PyCField_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + CFieldObject *obj; + obj = (CFieldObject *)type->tp_alloc(type, 0); + return (PyObject *)obj; +} + +/* + * Expects the size, index and offset for the current field in *psize and + * *poffset, stores the total size so far in *psize, the offset for the next + * field in *poffset, the alignment requirements for the current field in * *palign, and returns a field descriptor for this field. - */ -/* - * bitfields extension: - * bitsize != 0: this is a bit field. - * pbitofs points to the current bit offset, this will be updated. - * prev_desc points to the type of the previous bitfield, if any. - */ -PyObject * -PyCField_FromDesc(PyObject *desc, Py_ssize_t index, - Py_ssize_t *pfield_size, int bitsize, int *pbitofs, - Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, - int pack, int big_endian) -{ - CFieldObject *self; - PyObject *proto; - Py_ssize_t size, align; - SETFUNC setfunc = NULL; - GETFUNC getfunc = NULL; - StgDictObject *dict; - int fieldtype; -#define NO_BITFIELD 0 -#define NEW_BITFIELD 1 -#define CONT_BITFIELD 2 -#define EXPAND_BITFIELD 3 - + */ +/* + * bitfields extension: + * bitsize != 0: this is a bit field. + * pbitofs points to the current bit offset, this will be updated. + * prev_desc points to the type of the previous bitfield, if any. + */ +PyObject * +PyCField_FromDesc(PyObject *desc, Py_ssize_t index, + Py_ssize_t *pfield_size, int bitsize, int *pbitofs, + Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, + int pack, int big_endian) +{ + CFieldObject *self; + PyObject *proto; + Py_ssize_t size, align; + SETFUNC setfunc = NULL; + GETFUNC getfunc = NULL; + StgDictObject *dict; + int fieldtype; +#define NO_BITFIELD 0 +#define NEW_BITFIELD 1 +#define CONT_BITFIELD 2 +#define EXPAND_BITFIELD 3 + self = (CFieldObject *)_PyObject_CallNoArg((PyObject *)&PyCField_Type); - if (self == NULL) - return NULL; - dict = PyType_stgdict(desc); - if (!dict) { - PyErr_SetString(PyExc_TypeError, - "has no _stginfo_"); - Py_DECREF(self); - return NULL; - } - if (bitsize /* this is a bitfield request */ - && *pfield_size /* we have a bitfield open */ -#ifdef MS_WIN32 - /* MSVC, GCC with -mms-bitfields */ - && dict->size * 8 == *pfield_size -#else - /* GCC */ - && dict->size * 8 <= *pfield_size -#endif - && (*pbitofs + bitsize) <= *pfield_size) { - /* continue bit field */ - fieldtype = CONT_BITFIELD; -#ifndef MS_WIN32 - } else if (bitsize /* this is a bitfield request */ - && *pfield_size /* we have a bitfield open */ - && dict->size * 8 >= *pfield_size - && (*pbitofs + bitsize) <= dict->size * 8) { - /* expand bit field */ - fieldtype = EXPAND_BITFIELD; -#endif - } else if (bitsize) { - /* start new bitfield */ - fieldtype = NEW_BITFIELD; - *pbitofs = 0; - *pfield_size = dict->size * 8; - } else { - /* not a bit field */ - fieldtype = NO_BITFIELD; - *pbitofs = 0; - *pfield_size = 0; - } - - size = dict->size; - proto = desc; - - /* Field descriptors for 'c_char * n' are be scpecial cased to - return a Python string instead of an Array object instance... - */ - if (PyCArrayTypeObject_Check(proto)) { - StgDictObject *adict = PyType_stgdict(proto); - StgDictObject *idict; - if (adict && adict->proto) { - idict = PyType_stgdict(adict->proto); - if (!idict) { - PyErr_SetString(PyExc_TypeError, - "has no _stginfo_"); - Py_DECREF(self); - return NULL; - } - if (idict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { - struct fielddesc *fd = _ctypes_get_fielddesc("s"); - getfunc = fd->getfunc; - setfunc = fd->setfunc; - } -#ifdef CTYPES_UNICODE - if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { - struct fielddesc *fd = _ctypes_get_fielddesc("U"); - getfunc = fd->getfunc; - setfunc = fd->setfunc; - } -#endif - } - } - - self->setfunc = setfunc; - self->getfunc = getfunc; - self->index = index; - - Py_INCREF(proto); - self->proto = proto; - - switch (fieldtype) { - case NEW_BITFIELD: - if (big_endian) - self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; - else - self->size = (bitsize << 16) + *pbitofs; - *pbitofs = bitsize; - /* fall through */ - case NO_BITFIELD: - if (pack) - align = min(pack, dict->align); - else - align = dict->align; - if (align && *poffset % align) { - Py_ssize_t delta = align - (*poffset % align); - *psize += delta; - *poffset += delta; - } - - if (bitsize == 0) - self->size = size; - *psize += size; - - self->offset = *poffset; - *poffset += size; - - *palign = align; - break; - - case EXPAND_BITFIELD: - *poffset += dict->size - *pfield_size/8; - *psize += dict->size - *pfield_size/8; - - *pfield_size = dict->size * 8; - - if (big_endian) - self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; - else - self->size = (bitsize << 16) + *pbitofs; - - self->offset = *poffset - size; /* poffset is already updated for the NEXT field */ - *pbitofs += bitsize; - break; - - case CONT_BITFIELD: - if (big_endian) - self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; - else - self->size = (bitsize << 16) + *pbitofs; - - self->offset = *poffset - size; /* poffset is already updated for the NEXT field */ - *pbitofs += bitsize; - break; - } - - return (PyObject *)self; -} - -static int -PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value) -{ - CDataObject *dst; - char *ptr; - if (!CDataObject_Check(inst)) { - PyErr_SetString(PyExc_TypeError, - "not a ctype instance"); - return -1; - } - dst = (CDataObject *)inst; - ptr = dst->b_ptr + self->offset; - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "can't delete attribute"); - return -1; - } - return PyCData_set(inst, self->proto, self->setfunc, value, - self->index, self->size, ptr); -} - -static PyObject * -PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type) -{ - CDataObject *src; - if (inst == NULL) { - Py_INCREF(self); - return (PyObject *)self; - } - if (!CDataObject_Check(inst)) { - PyErr_SetString(PyExc_TypeError, - "not a ctype instance"); - return NULL; - } - src = (CDataObject *)inst; - return PyCData_get(self->proto, self->getfunc, inst, - self->index, self->size, src->b_ptr + self->offset); -} - -static PyObject * -PyCField_get_offset(PyObject *self, void *data) -{ - return PyLong_FromSsize_t(((CFieldObject *)self)->offset); -} - -static PyObject * -PyCField_get_size(PyObject *self, void *data) -{ - return PyLong_FromSsize_t(((CFieldObject *)self)->size); -} - -static PyGetSetDef PyCField_getset[] = { - { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" }, - { "size", PyCField_get_size, NULL, "size in bytes of this field" }, - { NULL, NULL, NULL, NULL }, -}; - -static int -PyCField_traverse(CFieldObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->proto); - return 0; -} - -static int -PyCField_clear(CFieldObject *self) -{ - Py_CLEAR(self->proto); - return 0; -} - -static void -PyCField_dealloc(PyObject *self) -{ - PyCField_clear((CFieldObject *)self); + if (self == NULL) + return NULL; + dict = PyType_stgdict(desc); + if (!dict) { + PyErr_SetString(PyExc_TypeError, + "has no _stginfo_"); + Py_DECREF(self); + return NULL; + } + if (bitsize /* this is a bitfield request */ + && *pfield_size /* we have a bitfield open */ +#ifdef MS_WIN32 + /* MSVC, GCC with -mms-bitfields */ + && dict->size * 8 == *pfield_size +#else + /* GCC */ + && dict->size * 8 <= *pfield_size +#endif + && (*pbitofs + bitsize) <= *pfield_size) { + /* continue bit field */ + fieldtype = CONT_BITFIELD; +#ifndef MS_WIN32 + } else if (bitsize /* this is a bitfield request */ + && *pfield_size /* we have a bitfield open */ + && dict->size * 8 >= *pfield_size + && (*pbitofs + bitsize) <= dict->size * 8) { + /* expand bit field */ + fieldtype = EXPAND_BITFIELD; +#endif + } else if (bitsize) { + /* start new bitfield */ + fieldtype = NEW_BITFIELD; + *pbitofs = 0; + *pfield_size = dict->size * 8; + } else { + /* not a bit field */ + fieldtype = NO_BITFIELD; + *pbitofs = 0; + *pfield_size = 0; + } + + size = dict->size; + proto = desc; + + /* Field descriptors for 'c_char * n' are be scpecial cased to + return a Python string instead of an Array object instance... + */ + if (PyCArrayTypeObject_Check(proto)) { + StgDictObject *adict = PyType_stgdict(proto); + StgDictObject *idict; + if (adict && adict->proto) { + idict = PyType_stgdict(adict->proto); + if (!idict) { + PyErr_SetString(PyExc_TypeError, + "has no _stginfo_"); + Py_DECREF(self); + return NULL; + } + if (idict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { + struct fielddesc *fd = _ctypes_get_fielddesc("s"); + getfunc = fd->getfunc; + setfunc = fd->setfunc; + } +#ifdef CTYPES_UNICODE + if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { + struct fielddesc *fd = _ctypes_get_fielddesc("U"); + getfunc = fd->getfunc; + setfunc = fd->setfunc; + } +#endif + } + } + + self->setfunc = setfunc; + self->getfunc = getfunc; + self->index = index; + + Py_INCREF(proto); + self->proto = proto; + + switch (fieldtype) { + case NEW_BITFIELD: + if (big_endian) + self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; + else + self->size = (bitsize << 16) + *pbitofs; + *pbitofs = bitsize; + /* fall through */ + case NO_BITFIELD: + if (pack) + align = min(pack, dict->align); + else + align = dict->align; + if (align && *poffset % align) { + Py_ssize_t delta = align - (*poffset % align); + *psize += delta; + *poffset += delta; + } + + if (bitsize == 0) + self->size = size; + *psize += size; + + self->offset = *poffset; + *poffset += size; + + *palign = align; + break; + + case EXPAND_BITFIELD: + *poffset += dict->size - *pfield_size/8; + *psize += dict->size - *pfield_size/8; + + *pfield_size = dict->size * 8; + + if (big_endian) + self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; + else + self->size = (bitsize << 16) + *pbitofs; + + self->offset = *poffset - size; /* poffset is already updated for the NEXT field */ + *pbitofs += bitsize; + break; + + case CONT_BITFIELD: + if (big_endian) + self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; + else + self->size = (bitsize << 16) + *pbitofs; + + self->offset = *poffset - size; /* poffset is already updated for the NEXT field */ + *pbitofs += bitsize; + break; + } + + return (PyObject *)self; +} + +static int +PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value) +{ + CDataObject *dst; + char *ptr; + if (!CDataObject_Check(inst)) { + PyErr_SetString(PyExc_TypeError, + "not a ctype instance"); + return -1; + } + dst = (CDataObject *)inst; + ptr = dst->b_ptr + self->offset; + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete attribute"); + return -1; + } + return PyCData_set(inst, self->proto, self->setfunc, value, + self->index, self->size, ptr); +} + +static PyObject * +PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type) +{ + CDataObject *src; + if (inst == NULL) { + Py_INCREF(self); + return (PyObject *)self; + } + if (!CDataObject_Check(inst)) { + PyErr_SetString(PyExc_TypeError, + "not a ctype instance"); + return NULL; + } + src = (CDataObject *)inst; + return PyCData_get(self->proto, self->getfunc, inst, + self->index, self->size, src->b_ptr + self->offset); +} + +static PyObject * +PyCField_get_offset(PyObject *self, void *data) +{ + return PyLong_FromSsize_t(((CFieldObject *)self)->offset); +} + +static PyObject * +PyCField_get_size(PyObject *self, void *data) +{ + return PyLong_FromSsize_t(((CFieldObject *)self)->size); +} + +static PyGetSetDef PyCField_getset[] = { + { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" }, + { "size", PyCField_get_size, NULL, "size in bytes of this field" }, + { NULL, NULL, NULL, NULL }, +}; + +static int +PyCField_traverse(CFieldObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->proto); + return 0; +} + +static int +PyCField_clear(CFieldObject *self) +{ + Py_CLEAR(self->proto); + return 0; +} + +static void +PyCField_dealloc(PyObject *self) +{ + PyCField_clear((CFieldObject *)self); Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -PyCField_repr(CFieldObject *self) -{ - PyObject *result; - Py_ssize_t bits = self->size >> 16; - Py_ssize_t size = self->size & 0xFFFF; - const char *name; - - name = ((PyTypeObject *)self->proto)->tp_name; - - if (bits) - result = PyUnicode_FromFormat( - "", - name, self->offset, size, bits); - else - result = PyUnicode_FromFormat( - "", - name, self->offset, size); - return result; -} - -PyTypeObject PyCField_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CField", /* tp_name */ - sizeof(CFieldObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - PyCField_dealloc, /* tp_dealloc */ +} + +static PyObject * +PyCField_repr(CFieldObject *self) +{ + PyObject *result; + Py_ssize_t bits = self->size >> 16; + Py_ssize_t size = self->size & 0xFFFF; + const char *name; + + name = ((PyTypeObject *)self->proto)->tp_name; + + if (bits) + result = PyUnicode_FromFormat( + "", + name, self->offset, size, bits); + else + result = PyUnicode_FromFormat( + "", + name, self->offset, size); + return result; +} + +PyTypeObject PyCField_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.CField", /* tp_name */ + sizeof(CFieldObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + PyCField_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)PyCField_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 */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "Structure/Union member", /* tp_doc */ - (traverseproc)PyCField_traverse, /* tp_traverse */ - (inquiry)PyCField_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - PyCField_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - (descrgetfunc)PyCField_get, /* tp_descr_get */ - (descrsetfunc)PyCField_set, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCField_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/******************************************************************/ -/* - Accessor functions -*/ - -/* Derived from Modules/structmodule.c: - Helper routine to get a Python integer and raise the appropriate error - if it isn't one */ - -static int -get_long(PyObject *v, long *p) -{ - long x; - - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "int expected instead of float"); - return -1; - } - x = PyLong_AsUnsignedLongMask(v); - if (x == -1 && PyErr_Occurred()) - return -1; - *p = x; - return 0; -} - -/* Same, but handling unsigned long */ - -static int -get_ulong(PyObject *v, unsigned long *p) -{ - unsigned long x; - - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "int expected instead of float"); - return -1; - } - x = PyLong_AsUnsignedLongMask(v); - if (x == (unsigned long)-1 && PyErr_Occurred()) - return -1; - *p = x; - return 0; -} - -/* Same, but handling native long long. */ - -static int -get_longlong(PyObject *v, long long *p) -{ - long long x; - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "int expected instead of float"); - return -1; - } - x = PyLong_AsUnsignedLongLongMask(v); - if (x == -1 && PyErr_Occurred()) - return -1; - *p = x; - return 0; -} - -/* Same, but handling native unsigned long long. */ - -static int -get_ulonglong(PyObject *v, unsigned long long *p) -{ - unsigned long long x; - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "int expected instead of float"); - return -1; - } - x = PyLong_AsUnsignedLongLongMask(v); - if (x == (unsigned long long)-1 && PyErr_Occurred()) - return -1; - *p = x; - return 0; -} - -/***************************************************************** - * Integer fields, with bitfield support - */ - -/* how to decode the size field, for integer get/set functions */ -#define LOW_BIT(x) ((x) & 0xFFFF) -#define NUM_BITS(x) ((x) >> 16) - -/* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */ -#define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1) - -/* This macro CHANGES the first parameter IN PLACE. For proper sign handling, - we must first shift left, then right. -*/ -#define GET_BITFIELD(v, size) \ - if (NUM_BITS(size)) { \ - v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \ - v >>= (sizeof(v)*8 - NUM_BITS(size)); \ - } - -/* This macro RETURNS the first parameter with the bit field CHANGED. */ -#define SET(type, x, v, size) \ - (NUM_BITS(size) ? \ - ( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \ - : (type)v) - + (reprfunc)PyCField_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 */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + "Structure/Union member", /* tp_doc */ + (traverseproc)PyCField_traverse, /* tp_traverse */ + (inquiry)PyCField_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + PyCField_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + (descrgetfunc)PyCField_get, /* tp_descr_get */ + (descrsetfunc)PyCField_set, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyCField_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/******************************************************************/ +/* + Accessor functions +*/ + +/* Derived from Modules/structmodule.c: + Helper routine to get a Python integer and raise the appropriate error + if it isn't one */ + +static int +get_long(PyObject *v, long *p) +{ + long x; + + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); + return -1; + } + x = PyLong_AsUnsignedLongMask(v); + if (x == -1 && PyErr_Occurred()) + return -1; + *p = x; + return 0; +} + +/* Same, but handling unsigned long */ + +static int +get_ulong(PyObject *v, unsigned long *p) +{ + unsigned long x; + + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); + return -1; + } + x = PyLong_AsUnsignedLongMask(v); + if (x == (unsigned long)-1 && PyErr_Occurred()) + return -1; + *p = x; + return 0; +} + +/* Same, but handling native long long. */ + +static int +get_longlong(PyObject *v, long long *p) +{ + long long x; + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); + return -1; + } + x = PyLong_AsUnsignedLongLongMask(v); + if (x == -1 && PyErr_Occurred()) + return -1; + *p = x; + return 0; +} + +/* Same, but handling native unsigned long long. */ + +static int +get_ulonglong(PyObject *v, unsigned long long *p) +{ + unsigned long long x; + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "int expected instead of float"); + return -1; + } + x = PyLong_AsUnsignedLongLongMask(v); + if (x == (unsigned long long)-1 && PyErr_Occurred()) + return -1; + *p = x; + return 0; +} + +/***************************************************************** + * Integer fields, with bitfield support + */ + +/* how to decode the size field, for integer get/set functions */ +#define LOW_BIT(x) ((x) & 0xFFFF) +#define NUM_BITS(x) ((x) >> 16) + +/* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */ +#define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1) + +/* This macro CHANGES the first parameter IN PLACE. For proper sign handling, + we must first shift left, then right. +*/ +#define GET_BITFIELD(v, size) \ + if (NUM_BITS(size)) { \ + v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \ + v >>= (sizeof(v)*8 - NUM_BITS(size)); \ + } + +/* This macro RETURNS the first parameter with the bit field CHANGED. */ +#define SET(type, x, v, size) \ + (NUM_BITS(size) ? \ + ( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \ + : (type)v) + #if SIZEOF_SHORT == 2 # define SWAP_SHORT _Py_bswap16 #else # error "unsupported short size" #endif - + #if SIZEOF_INT == 4 # define SWAP_INT _Py_bswap32 -#else +#else # error "unsupported int size" -#endif - -#if SIZEOF_LONG == 4 +#endif + +#if SIZEOF_LONG == 4 # define SWAP_LONG _Py_bswap32 -#elif SIZEOF_LONG == 8 +#elif SIZEOF_LONG == 8 # define SWAP_LONG _Py_bswap64 #else # error "unsupported long size" -#endif +#endif #if SIZEOF_LONG_LONG == 8 # define SWAP_LONG_LONG _Py_bswap64 @@ -476,1118 +476,1118 @@ get_ulonglong(PyObject *v, unsigned long long *p) # error "unsupported long long size" #endif -/***************************************************************** - * The setter methods return an object which must be kept alive, to keep the - * data valid which has been stored in the memory block. The ctypes object - * instance inserts this object into its 'b_objects' list. - * - * For simple Python types like integers or characters, there is nothing that - * has to been kept alive, so Py_None is returned in these cases. But this - * makes inspecting the 'b_objects' list, which is accessible from Python for - * debugging, less useful. - * - * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value - * instead of Py_None. - */ - -#ifdef _CTYPES_DEBUG_KEEP -#define _RET(x) Py_INCREF(x); return x -#else -#define _RET(X) Py_RETURN_NONE -#endif - -/***************************************************************** - * integer accessor methods, supporting bit fields - */ - -static PyObject * -b_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - long val; - if (get_long(value, &val) < 0) - return NULL; - *(signed char *)ptr = SET(signed char, *(signed char *)ptr, val, size); - _RET(value); -} - - -static PyObject * -b_get(void *ptr, Py_ssize_t size) -{ - signed char val = *(signed char *)ptr; - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - -static PyObject * -B_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long val; - if (get_ulong(value, &val) < 0) - return NULL; - *(unsigned char *)ptr = SET(unsigned char, *(unsigned char*)ptr, val, size); - _RET(value); -} - - -static PyObject * -B_get(void *ptr, Py_ssize_t size) -{ - unsigned char val = *(unsigned char *)ptr; - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - -static PyObject * -h_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - long val; - short x; - if (get_long(value, &val) < 0) - return NULL; - memcpy(&x, ptr, sizeof(x)); - x = SET(short, x, val, size); - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - - -static PyObject * -h_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - long val; - short field; +/***************************************************************** + * The setter methods return an object which must be kept alive, to keep the + * data valid which has been stored in the memory block. The ctypes object + * instance inserts this object into its 'b_objects' list. + * + * For simple Python types like integers or characters, there is nothing that + * has to been kept alive, so Py_None is returned in these cases. But this + * makes inspecting the 'b_objects' list, which is accessible from Python for + * debugging, less useful. + * + * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value + * instead of Py_None. + */ + +#ifdef _CTYPES_DEBUG_KEEP +#define _RET(x) Py_INCREF(x); return x +#else +#define _RET(X) Py_RETURN_NONE +#endif + +/***************************************************************** + * integer accessor methods, supporting bit fields + */ + +static PyObject * +b_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + long val; + if (get_long(value, &val) < 0) + return NULL; + *(signed char *)ptr = SET(signed char, *(signed char *)ptr, val, size); + _RET(value); +} + + +static PyObject * +b_get(void *ptr, Py_ssize_t size) +{ + signed char val = *(signed char *)ptr; + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + +static PyObject * +B_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long val; + if (get_ulong(value, &val) < 0) + return NULL; + *(unsigned char *)ptr = SET(unsigned char, *(unsigned char*)ptr, val, size); + _RET(value); +} + + +static PyObject * +B_get(void *ptr, Py_ssize_t size) +{ + unsigned char val = *(unsigned char *)ptr; + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + +static PyObject * +h_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + long val; + short x; + if (get_long(value, &val) < 0) + return NULL; + memcpy(&x, ptr, sizeof(x)); + x = SET(short, x, val, size); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + + +static PyObject * +h_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + long val; + short field; if (get_long(value, &val) < 0) { - return NULL; + return NULL; } - memcpy(&field, ptr, sizeof(field)); + memcpy(&field, ptr, sizeof(field)); field = SWAP_SHORT(field); - field = SET(short, field, val, size); + field = SET(short, field, val, size); field = SWAP_SHORT(field); - memcpy(ptr, &field, sizeof(field)); - _RET(value); -} - -static PyObject * -h_get(void *ptr, Py_ssize_t size) -{ - short val; - memcpy(&val, ptr, sizeof(val)); - GET_BITFIELD(val, size); - return PyLong_FromLong((long)val); -} - -static PyObject * -h_get_sw(void *ptr, Py_ssize_t size) -{ - short val; - memcpy(&val, ptr, sizeof(val)); + memcpy(ptr, &field, sizeof(field)); + _RET(value); +} + +static PyObject * +h_get(void *ptr, Py_ssize_t size) +{ + short val; + memcpy(&val, ptr, sizeof(val)); + GET_BITFIELD(val, size); + return PyLong_FromLong((long)val); +} + +static PyObject * +h_get_sw(void *ptr, Py_ssize_t size) +{ + short val; + memcpy(&val, ptr, sizeof(val)); val = SWAP_SHORT(val); - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - -static PyObject * -H_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long val; - unsigned short x; - if (get_ulong(value, &val) < 0) - return NULL; - memcpy(&x, ptr, sizeof(x)); - x = SET(unsigned short, x, val, size); - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - -static PyObject * -H_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long val; - unsigned short field; + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + +static PyObject * +H_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long val; + unsigned short x; + if (get_ulong(value, &val) < 0) + return NULL; + memcpy(&x, ptr, sizeof(x)); + x = SET(unsigned short, x, val, size); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +H_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long val; + unsigned short field; if (get_ulong(value, &val) < 0) { - return NULL; + return NULL; } - memcpy(&field, ptr, sizeof(field)); + memcpy(&field, ptr, sizeof(field)); field = SWAP_SHORT(field); - field = SET(unsigned short, field, val, size); + field = SET(unsigned short, field, val, size); field = SWAP_SHORT(field); - memcpy(ptr, &field, sizeof(field)); - _RET(value); -} - - -static PyObject * -H_get(void *ptr, Py_ssize_t size) -{ - unsigned short val; - memcpy(&val, ptr, sizeof(val)); - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - -static PyObject * -H_get_sw(void *ptr, Py_ssize_t size) -{ - unsigned short val; - memcpy(&val, ptr, sizeof(val)); + memcpy(ptr, &field, sizeof(field)); + _RET(value); +} + + +static PyObject * +H_get(void *ptr, Py_ssize_t size) +{ + unsigned short val; + memcpy(&val, ptr, sizeof(val)); + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + +static PyObject * +H_get_sw(void *ptr, Py_ssize_t size) +{ + unsigned short val; + memcpy(&val, ptr, sizeof(val)); val = SWAP_SHORT(val); - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - -static PyObject * -i_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - long val; - int x; - if (get_long(value, &val) < 0) - return NULL; - memcpy(&x, ptr, sizeof(x)); - x = SET(int, x, val, size); - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - -static PyObject * -i_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - long val; - int field; + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + +static PyObject * +i_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + long val; + int x; + if (get_long(value, &val) < 0) + return NULL; + memcpy(&x, ptr, sizeof(x)); + x = SET(int, x, val, size); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +i_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + long val; + int field; if (get_long(value, &val) < 0) { - return NULL; + return NULL; } - memcpy(&field, ptr, sizeof(field)); - field = SWAP_INT(field); - field = SET(int, field, val, size); - field = SWAP_INT(field); - memcpy(ptr, &field, sizeof(field)); - _RET(value); -} - - -static PyObject * -i_get(void *ptr, Py_ssize_t size) -{ - int val; - memcpy(&val, ptr, sizeof(val)); - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - -static PyObject * -i_get_sw(void *ptr, Py_ssize_t size) -{ - int val; - memcpy(&val, ptr, sizeof(val)); - val = SWAP_INT(val); - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - + memcpy(&field, ptr, sizeof(field)); + field = SWAP_INT(field); + field = SET(int, field, val, size); + field = SWAP_INT(field); + memcpy(ptr, &field, sizeof(field)); + _RET(value); +} + + +static PyObject * +i_get(void *ptr, Py_ssize_t size) +{ + int val; + memcpy(&val, ptr, sizeof(val)); + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + +static PyObject * +i_get_sw(void *ptr, Py_ssize_t size) +{ + int val; + memcpy(&val, ptr, sizeof(val)); + val = SWAP_INT(val); + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + #ifndef MS_WIN32 /* http://msdn.microsoft.com/en-us/library/cc237864.aspx */ #define VARIANT_FALSE 0x0000 #define VARIANT_TRUE 0xFFFF #endif -/* short BOOL - VARIANT_BOOL */ -static PyObject * -vBOOL_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - switch (PyObject_IsTrue(value)) { - case -1: - return NULL; - case 0: - *(short int *)ptr = VARIANT_FALSE; - _RET(value); - default: - *(short int *)ptr = VARIANT_TRUE; - _RET(value); - } -} - -static PyObject * -vBOOL_get(void *ptr, Py_ssize_t size) -{ - return PyBool_FromLong((long)*(short int *)ptr); -} - -static PyObject * -bool_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - switch (PyObject_IsTrue(value)) { - case -1: - return NULL; - case 0: - *(_Bool *)ptr = 0; - _RET(value); - default: - *(_Bool *)ptr = 1; - _RET(value); - } -} - -static PyObject * -bool_get(void *ptr, Py_ssize_t size) -{ - return PyBool_FromLong((long)*(_Bool *)ptr); -} - -static PyObject * -I_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long val; - unsigned int x; - if (get_ulong(value, &val) < 0) - return NULL; - memcpy(&x, ptr, sizeof(x)); - x = SET(unsigned int, x, val, size); - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - -static PyObject * -I_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long val; - unsigned int field; +/* short BOOL - VARIANT_BOOL */ +static PyObject * +vBOOL_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + switch (PyObject_IsTrue(value)) { + case -1: + return NULL; + case 0: + *(short int *)ptr = VARIANT_FALSE; + _RET(value); + default: + *(short int *)ptr = VARIANT_TRUE; + _RET(value); + } +} + +static PyObject * +vBOOL_get(void *ptr, Py_ssize_t size) +{ + return PyBool_FromLong((long)*(short int *)ptr); +} + +static PyObject * +bool_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + switch (PyObject_IsTrue(value)) { + case -1: + return NULL; + case 0: + *(_Bool *)ptr = 0; + _RET(value); + default: + *(_Bool *)ptr = 1; + _RET(value); + } +} + +static PyObject * +bool_get(void *ptr, Py_ssize_t size) +{ + return PyBool_FromLong((long)*(_Bool *)ptr); +} + +static PyObject * +I_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long val; + unsigned int x; + if (get_ulong(value, &val) < 0) + return NULL; + memcpy(&x, ptr, sizeof(x)); + x = SET(unsigned int, x, val, size); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +I_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long val; + unsigned int field; if (get_ulong(value, &val) < 0) { - return NULL; + return NULL; } - memcpy(&field, ptr, sizeof(field)); - field = SWAP_INT(field); - field = SET(unsigned int, field, (unsigned int)val, size); - field = SWAP_INT(field); - memcpy(ptr, &field, sizeof(field)); - _RET(value); -} - - -static PyObject * -I_get(void *ptr, Py_ssize_t size) -{ - unsigned int val; - memcpy(&val, ptr, sizeof(val)); - GET_BITFIELD(val, size); - return PyLong_FromUnsignedLong(val); -} - -static PyObject * -I_get_sw(void *ptr, Py_ssize_t size) -{ - unsigned int val; - memcpy(&val, ptr, sizeof(val)); - val = SWAP_INT(val); - GET_BITFIELD(val, size); - return PyLong_FromUnsignedLong(val); -} - -static PyObject * -l_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - long val; - long x; - if (get_long(value, &val) < 0) - return NULL; - memcpy(&x, ptr, sizeof(x)); - x = SET(long, x, val, size); - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - -static PyObject * -l_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - long val; - long field; + memcpy(&field, ptr, sizeof(field)); + field = SWAP_INT(field); + field = SET(unsigned int, field, (unsigned int)val, size); + field = SWAP_INT(field); + memcpy(ptr, &field, sizeof(field)); + _RET(value); +} + + +static PyObject * +I_get(void *ptr, Py_ssize_t size) +{ + unsigned int val; + memcpy(&val, ptr, sizeof(val)); + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLong(val); +} + +static PyObject * +I_get_sw(void *ptr, Py_ssize_t size) +{ + unsigned int val; + memcpy(&val, ptr, sizeof(val)); + val = SWAP_INT(val); + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLong(val); +} + +static PyObject * +l_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + long val; + long x; + if (get_long(value, &val) < 0) + return NULL; + memcpy(&x, ptr, sizeof(x)); + x = SET(long, x, val, size); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +l_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + long val; + long field; if (get_long(value, &val) < 0) { - return NULL; + return NULL; } - memcpy(&field, ptr, sizeof(field)); - field = SWAP_LONG(field); - field = SET(long, field, val, size); - field = SWAP_LONG(field); - memcpy(ptr, &field, sizeof(field)); - _RET(value); -} - - -static PyObject * -l_get(void *ptr, Py_ssize_t size) -{ - long val; - memcpy(&val, ptr, sizeof(val)); - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - -static PyObject * -l_get_sw(void *ptr, Py_ssize_t size) -{ - long val; - memcpy(&val, ptr, sizeof(val)); - val = SWAP_LONG(val); - GET_BITFIELD(val, size); - return PyLong_FromLong(val); -} - -static PyObject * -L_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long val; - unsigned long x; - if (get_ulong(value, &val) < 0) - return NULL; - memcpy(&x, ptr, sizeof(x)); - x = SET(unsigned long, x, val, size); - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - -static PyObject * -L_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long val; - unsigned long field; + memcpy(&field, ptr, sizeof(field)); + field = SWAP_LONG(field); + field = SET(long, field, val, size); + field = SWAP_LONG(field); + memcpy(ptr, &field, sizeof(field)); + _RET(value); +} + + +static PyObject * +l_get(void *ptr, Py_ssize_t size) +{ + long val; + memcpy(&val, ptr, sizeof(val)); + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + +static PyObject * +l_get_sw(void *ptr, Py_ssize_t size) +{ + long val; + memcpy(&val, ptr, sizeof(val)); + val = SWAP_LONG(val); + GET_BITFIELD(val, size); + return PyLong_FromLong(val); +} + +static PyObject * +L_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long val; + unsigned long x; + if (get_ulong(value, &val) < 0) + return NULL; + memcpy(&x, ptr, sizeof(x)); + x = SET(unsigned long, x, val, size); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +L_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long val; + unsigned long field; if (get_ulong(value, &val) < 0) { - return NULL; + return NULL; } - memcpy(&field, ptr, sizeof(field)); - field = SWAP_LONG(field); - field = SET(unsigned long, field, val, size); - field = SWAP_LONG(field); - memcpy(ptr, &field, sizeof(field)); - _RET(value); -} - - -static PyObject * -L_get(void *ptr, Py_ssize_t size) -{ - unsigned long val; - memcpy(&val, ptr, sizeof(val)); - GET_BITFIELD(val, size); - return PyLong_FromUnsignedLong(val); -} - -static PyObject * -L_get_sw(void *ptr, Py_ssize_t size) -{ - unsigned long val; - memcpy(&val, ptr, sizeof(val)); - val = SWAP_LONG(val); - GET_BITFIELD(val, size); - return PyLong_FromUnsignedLong(val); -} - -static PyObject * -q_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - long long val; - long long x; - if (get_longlong(value, &val) < 0) - return NULL; - memcpy(&x, ptr, sizeof(x)); - x = SET(long long, x, val, size); - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - -static PyObject * -q_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - long long val; - long long field; + memcpy(&field, ptr, sizeof(field)); + field = SWAP_LONG(field); + field = SET(unsigned long, field, val, size); + field = SWAP_LONG(field); + memcpy(ptr, &field, sizeof(field)); + _RET(value); +} + + +static PyObject * +L_get(void *ptr, Py_ssize_t size) +{ + unsigned long val; + memcpy(&val, ptr, sizeof(val)); + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLong(val); +} + +static PyObject * +L_get_sw(void *ptr, Py_ssize_t size) +{ + unsigned long val; + memcpy(&val, ptr, sizeof(val)); + val = SWAP_LONG(val); + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLong(val); +} + +static PyObject * +q_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + long long val; + long long x; + if (get_longlong(value, &val) < 0) + return NULL; + memcpy(&x, ptr, sizeof(x)); + x = SET(long long, x, val, size); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +q_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + long long val; + long long field; if (get_longlong(value, &val) < 0) { - return NULL; + return NULL; } - memcpy(&field, ptr, sizeof(field)); + memcpy(&field, ptr, sizeof(field)); field = SWAP_LONG_LONG(field); - field = SET(long long, field, val, size); + field = SET(long long, field, val, size); field = SWAP_LONG_LONG(field); - memcpy(ptr, &field, sizeof(field)); - _RET(value); -} - -static PyObject * -q_get(void *ptr, Py_ssize_t size) -{ - long long val; - memcpy(&val, ptr, sizeof(val)); - GET_BITFIELD(val, size); - return PyLong_FromLongLong(val); -} - -static PyObject * -q_get_sw(void *ptr, Py_ssize_t size) -{ - long long val; - memcpy(&val, ptr, sizeof(val)); + memcpy(ptr, &field, sizeof(field)); + _RET(value); +} + +static PyObject * +q_get(void *ptr, Py_ssize_t size) +{ + long long val; + memcpy(&val, ptr, sizeof(val)); + GET_BITFIELD(val, size); + return PyLong_FromLongLong(val); +} + +static PyObject * +q_get_sw(void *ptr, Py_ssize_t size) +{ + long long val; + memcpy(&val, ptr, sizeof(val)); val = SWAP_LONG_LONG(val); - GET_BITFIELD(val, size); - return PyLong_FromLongLong(val); -} - -static PyObject * -Q_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long long val; - unsigned long long x; - if (get_ulonglong(value, &val) < 0) - return NULL; - memcpy(&x, ptr, sizeof(x)); - x = SET(long long, x, val, size); - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - -static PyObject * -Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - unsigned long long val; - unsigned long long field; + GET_BITFIELD(val, size); + return PyLong_FromLongLong(val); +} + +static PyObject * +Q_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long long val; + unsigned long long x; + if (get_ulonglong(value, &val) < 0) + return NULL; + memcpy(&x, ptr, sizeof(x)); + x = SET(long long, x, val, size); + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + unsigned long long val; + unsigned long long field; if (get_ulonglong(value, &val) < 0) { - return NULL; + return NULL; } - memcpy(&field, ptr, sizeof(field)); + memcpy(&field, ptr, sizeof(field)); field = SWAP_LONG_LONG(field); - field = SET(unsigned long long, field, val, size); + field = SET(unsigned long long, field, val, size); field = SWAP_LONG_LONG(field); - memcpy(ptr, &field, sizeof(field)); - _RET(value); -} - -static PyObject * -Q_get(void *ptr, Py_ssize_t size) -{ - unsigned long long val; - memcpy(&val, ptr, sizeof(val)); - GET_BITFIELD(val, size); - return PyLong_FromUnsignedLongLong(val); -} - -static PyObject * -Q_get_sw(void *ptr, Py_ssize_t size) -{ - unsigned long long val; - memcpy(&val, ptr, sizeof(val)); + memcpy(ptr, &field, sizeof(field)); + _RET(value); +} + +static PyObject * +Q_get(void *ptr, Py_ssize_t size) +{ + unsigned long long val; + memcpy(&val, ptr, sizeof(val)); + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLongLong(val); +} + +static PyObject * +Q_get_sw(void *ptr, Py_ssize_t size) +{ + unsigned long long val; + memcpy(&val, ptr, sizeof(val)); val = SWAP_LONG_LONG(val); - GET_BITFIELD(val, size); - return PyLong_FromUnsignedLongLong(val); -} - -/***************************************************************** - * non-integer accessor methods, not supporting bit fields - */ - - -static PyObject * -g_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - long double x; - - x = PyFloat_AsDouble(value); - if (x == -1 && PyErr_Occurred()) - return NULL; - memcpy(ptr, &x, sizeof(long double)); - _RET(value); -} - -static PyObject * -g_get(void *ptr, Py_ssize_t size) -{ - long double val; - memcpy(&val, ptr, sizeof(long double)); - return PyFloat_FromDouble(val); -} - -static PyObject * -d_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - double x; - - x = PyFloat_AsDouble(value); - if (x == -1 && PyErr_Occurred()) - return NULL; - memcpy(ptr, &x, sizeof(double)); - _RET(value); -} - -static PyObject * -d_get(void *ptr, Py_ssize_t size) -{ - double val; - memcpy(&val, ptr, sizeof(val)); - return PyFloat_FromDouble(val); -} - -static PyObject * -d_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - double x; - - x = PyFloat_AsDouble(value); - if (x == -1 && PyErr_Occurred()) - return NULL; -#ifdef WORDS_BIGENDIAN - if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1)) - return NULL; -#else - if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0)) - return NULL; -#endif - _RET(value); -} - -static PyObject * -d_get_sw(void *ptr, Py_ssize_t size) -{ -#ifdef WORDS_BIGENDIAN - return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1)); -#else - return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0)); -#endif -} - -static PyObject * -f_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - float x; - - x = (float)PyFloat_AsDouble(value); - if (x == -1 && PyErr_Occurred()) - return NULL; - memcpy(ptr, &x, sizeof(x)); - _RET(value); -} - -static PyObject * -f_get(void *ptr, Py_ssize_t size) -{ - float val; - memcpy(&val, ptr, sizeof(val)); - return PyFloat_FromDouble(val); -} - -static PyObject * -f_set_sw(void *ptr, PyObject *value, Py_ssize_t size) -{ - float x; - - x = (float)PyFloat_AsDouble(value); - if (x == -1 && PyErr_Occurred()) - return NULL; -#ifdef WORDS_BIGENDIAN - if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1)) - return NULL; -#else - if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0)) - return NULL; -#endif - _RET(value); -} - -static PyObject * -f_get_sw(void *ptr, Py_ssize_t size) -{ -#ifdef WORDS_BIGENDIAN - return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1)); -#else - return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0)); -#endif -} - -/* - py_object refcounts: - - 1. If we have a py_object instance, O_get must Py_INCREF the returned - object, of course. If O_get is called from a function result, no py_object - instance is created - so callproc.c::GetResult has to call Py_DECREF. - - 2. The memory block in py_object owns a refcount. So, py_object must call - Py_DECREF on destruction. Maybe only when b_needsfree is non-zero. -*/ -static PyObject * -O_get(void *ptr, Py_ssize_t size) -{ - PyObject *ob = *(PyObject **)ptr; - if (ob == NULL) { - if (!PyErr_Occurred()) - /* Set an error if not yet set */ - PyErr_SetString(PyExc_ValueError, - "PyObject is NULL"); - return NULL; - } - Py_INCREF(ob); - return ob; -} - -static PyObject * -O_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - /* Hm, does the memory block need it's own refcount or not? */ - *(PyObject **)ptr = value; - Py_INCREF(value); - return value; -} - - -static PyObject * -c_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - if (PyBytes_Check(value) && PyBytes_GET_SIZE(value) == 1) { - *(char *)ptr = PyBytes_AS_STRING(value)[0]; - _RET(value); - } - if (PyByteArray_Check(value) && PyByteArray_GET_SIZE(value) == 1) { - *(char *)ptr = PyByteArray_AS_STRING(value)[0]; - _RET(value); - } - if (PyLong_Check(value)) - { + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLongLong(val); +} + +/***************************************************************** + * non-integer accessor methods, not supporting bit fields + */ + + +static PyObject * +g_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + long double x; + + x = PyFloat_AsDouble(value); + if (x == -1 && PyErr_Occurred()) + return NULL; + memcpy(ptr, &x, sizeof(long double)); + _RET(value); +} + +static PyObject * +g_get(void *ptr, Py_ssize_t size) +{ + long double val; + memcpy(&val, ptr, sizeof(long double)); + return PyFloat_FromDouble(val); +} + +static PyObject * +d_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + double x; + + x = PyFloat_AsDouble(value); + if (x == -1 && PyErr_Occurred()) + return NULL; + memcpy(ptr, &x, sizeof(double)); + _RET(value); +} + +static PyObject * +d_get(void *ptr, Py_ssize_t size) +{ + double val; + memcpy(&val, ptr, sizeof(val)); + return PyFloat_FromDouble(val); +} + +static PyObject * +d_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + double x; + + x = PyFloat_AsDouble(value); + if (x == -1 && PyErr_Occurred()) + return NULL; +#ifdef WORDS_BIGENDIAN + if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1)) + return NULL; +#else + if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0)) + return NULL; +#endif + _RET(value); +} + +static PyObject * +d_get_sw(void *ptr, Py_ssize_t size) +{ +#ifdef WORDS_BIGENDIAN + return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1)); +#else + return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0)); +#endif +} + +static PyObject * +f_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + float x; + + x = (float)PyFloat_AsDouble(value); + if (x == -1 && PyErr_Occurred()) + return NULL; + memcpy(ptr, &x, sizeof(x)); + _RET(value); +} + +static PyObject * +f_get(void *ptr, Py_ssize_t size) +{ + float val; + memcpy(&val, ptr, sizeof(val)); + return PyFloat_FromDouble(val); +} + +static PyObject * +f_set_sw(void *ptr, PyObject *value, Py_ssize_t size) +{ + float x; + + x = (float)PyFloat_AsDouble(value); + if (x == -1 && PyErr_Occurred()) + return NULL; +#ifdef WORDS_BIGENDIAN + if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1)) + return NULL; +#else + if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0)) + return NULL; +#endif + _RET(value); +} + +static PyObject * +f_get_sw(void *ptr, Py_ssize_t size) +{ +#ifdef WORDS_BIGENDIAN + return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1)); +#else + return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0)); +#endif +} + +/* + py_object refcounts: + + 1. If we have a py_object instance, O_get must Py_INCREF the returned + object, of course. If O_get is called from a function result, no py_object + instance is created - so callproc.c::GetResult has to call Py_DECREF. + + 2. The memory block in py_object owns a refcount. So, py_object must call + Py_DECREF on destruction. Maybe only when b_needsfree is non-zero. +*/ +static PyObject * +O_get(void *ptr, Py_ssize_t size) +{ + PyObject *ob = *(PyObject **)ptr; + if (ob == NULL) { + if (!PyErr_Occurred()) + /* Set an error if not yet set */ + PyErr_SetString(PyExc_ValueError, + "PyObject is NULL"); + return NULL; + } + Py_INCREF(ob); + return ob; +} + +static PyObject * +O_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + /* Hm, does the memory block need it's own refcount or not? */ + *(PyObject **)ptr = value; + Py_INCREF(value); + return value; +} + + +static PyObject * +c_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + if (PyBytes_Check(value) && PyBytes_GET_SIZE(value) == 1) { + *(char *)ptr = PyBytes_AS_STRING(value)[0]; + _RET(value); + } + if (PyByteArray_Check(value) && PyByteArray_GET_SIZE(value) == 1) { + *(char *)ptr = PyByteArray_AS_STRING(value)[0]; + _RET(value); + } + if (PyLong_Check(value)) + { long longval = PyLong_AsLong(value); - if (longval < 0 || longval >= 256) - goto error; - *(char *)ptr = (char)longval; - _RET(value); - } - error: - PyErr_Format(PyExc_TypeError, - "one character bytes, bytearray or integer expected"); - return NULL; -} - - -static PyObject * -c_get(void *ptr, Py_ssize_t size) -{ - return PyBytes_FromStringAndSize((char *)ptr, 1); -} - -#ifdef CTYPES_UNICODE -/* u - a single wchar_t character */ -static PyObject * -u_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - Py_ssize_t len; - wchar_t chars[2]; - if (!PyUnicode_Check(value)) { - PyErr_Format(PyExc_TypeError, - "unicode string expected instead of %s instance", + if (longval < 0 || longval >= 256) + goto error; + *(char *)ptr = (char)longval; + _RET(value); + } + error: + PyErr_Format(PyExc_TypeError, + "one character bytes, bytearray or integer expected"); + return NULL; +} + + +static PyObject * +c_get(void *ptr, Py_ssize_t size) +{ + return PyBytes_FromStringAndSize((char *)ptr, 1); +} + +#ifdef CTYPES_UNICODE +/* u - a single wchar_t character */ +static PyObject * +u_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + Py_ssize_t len; + wchar_t chars[2]; + if (!PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "unicode string expected instead of %s instance", Py_TYPE(value)->tp_name); - return NULL; - } else - Py_INCREF(value); - - len = PyUnicode_AsWideChar(value, chars, 2); - if (len != 1) { - Py_DECREF(value); - PyErr_SetString(PyExc_TypeError, - "one character unicode string expected"); - return NULL; - } - - *(wchar_t *)ptr = chars[0]; - Py_DECREF(value); - - _RET(value); -} - - -static PyObject * -u_get(void *ptr, Py_ssize_t size) -{ - return PyUnicode_FromWideChar((wchar_t *)ptr, 1); -} - -/* U - a unicode string */ -static PyObject * -U_get(void *ptr, Py_ssize_t size) -{ - Py_ssize_t len; - wchar_t *p; - - size /= sizeof(wchar_t); /* we count character units here, not bytes */ - - /* We need 'result' to be able to count the characters with wcslen, - since ptr may not be NUL terminated. If the length is smaller (if - it was actually NUL terminated, we construct a new one and throw - away the result. - */ - /* chop off at the first NUL character, if any. */ - p = (wchar_t*)ptr; - for (len = 0; len < size; ++len) { - if (!p[len]) - break; - } - - return PyUnicode_FromWideChar((wchar_t *)ptr, len); -} - -static PyObject * -U_set(void *ptr, PyObject *value, Py_ssize_t length) -{ - /* It's easier to calculate in characters than in bytes */ - length /= sizeof(wchar_t); - - if (!PyUnicode_Check(value)) { - PyErr_Format(PyExc_TypeError, - "unicode string expected instead of %s instance", + return NULL; + } else + Py_INCREF(value); + + len = PyUnicode_AsWideChar(value, chars, 2); + if (len != 1) { + Py_DECREF(value); + PyErr_SetString(PyExc_TypeError, + "one character unicode string expected"); + return NULL; + } + + *(wchar_t *)ptr = chars[0]; + Py_DECREF(value); + + _RET(value); +} + + +static PyObject * +u_get(void *ptr, Py_ssize_t size) +{ + return PyUnicode_FromWideChar((wchar_t *)ptr, 1); +} + +/* U - a unicode string */ +static PyObject * +U_get(void *ptr, Py_ssize_t size) +{ + Py_ssize_t len; + wchar_t *p; + + size /= sizeof(wchar_t); /* we count character units here, not bytes */ + + /* We need 'result' to be able to count the characters with wcslen, + since ptr may not be NUL terminated. If the length is smaller (if + it was actually NUL terminated, we construct a new one and throw + away the result. + */ + /* chop off at the first NUL character, if any. */ + p = (wchar_t*)ptr; + for (len = 0; len < size; ++len) { + if (!p[len]) + break; + } + + return PyUnicode_FromWideChar((wchar_t *)ptr, len); +} + +static PyObject * +U_set(void *ptr, PyObject *value, Py_ssize_t length) +{ + /* It's easier to calculate in characters than in bytes */ + length /= sizeof(wchar_t); + + if (!PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "unicode string expected instead of %s instance", Py_TYPE(value)->tp_name); - return NULL; - } - + return NULL; + } + Py_ssize_t size = PyUnicode_AsWideChar(value, NULL, 0); if (size < 0) { - return NULL; + return NULL; } // PyUnicode_AsWideChar() returns number of wchars including trailing null byte, // when it is called with NULL. size--; assert(size >= 0); - if (size > length) { - PyErr_Format(PyExc_ValueError, - "string too long (%zd, maximum length %zd)", - size, length); - return NULL; - } else if (size < length-1) - /* copy terminating NUL character if there is space */ - size += 1; - - if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, size) == -1) { - return NULL; - } - - Py_INCREF(value); - return value; -} - -#endif - -static PyObject * -s_get(void *ptr, Py_ssize_t size) -{ - Py_ssize_t i; - char *p; - - p = (char *)ptr; - for (i = 0; i < size; ++i) { - if (*p++ == '\0') - break; - } - - return PyBytes_FromStringAndSize((char *)ptr, (Py_ssize_t)i); -} - -static PyObject * -s_set(void *ptr, PyObject *value, Py_ssize_t length) -{ + if (size > length) { + PyErr_Format(PyExc_ValueError, + "string too long (%zd, maximum length %zd)", + size, length); + return NULL; + } else if (size < length-1) + /* copy terminating NUL character if there is space */ + size += 1; + + if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, size) == -1) { + return NULL; + } + + Py_INCREF(value); + return value; +} + +#endif + +static PyObject * +s_get(void *ptr, Py_ssize_t size) +{ + Py_ssize_t i; + char *p; + + p = (char *)ptr; + for (i = 0; i < size; ++i) { + if (*p++ == '\0') + break; + } + + return PyBytes_FromStringAndSize((char *)ptr, (Py_ssize_t)i); +} + +static PyObject * +s_set(void *ptr, PyObject *value, Py_ssize_t length) +{ const char *data; - Py_ssize_t size; - - if(!PyBytes_Check(value)) { - PyErr_Format(PyExc_TypeError, - "expected bytes, %s found", + Py_ssize_t size; + + if(!PyBytes_Check(value)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %s found", Py_TYPE(value)->tp_name); - return NULL; - } - - data = PyBytes_AS_STRING(value); - size = strlen(data); /* XXX Why not Py_SIZE(value)? */ - if (size < length) { - /* This will copy the terminating NUL character - * if there is space for it. - */ - ++size; - } else if (size > length) { - PyErr_Format(PyExc_ValueError, - "bytes too long (%zd, maximum length %zd)", - size, length); - return NULL; - } - /* Also copy the terminating NUL character if there is space */ - memcpy((char *)ptr, data, size); - - _RET(value); -} - -static PyObject * -z_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - if (value == Py_None) { - *(char **)ptr = NULL; - Py_INCREF(value); - return value; - } - if (PyBytes_Check(value)) { + return NULL; + } + + data = PyBytes_AS_STRING(value); + size = strlen(data); /* XXX Why not Py_SIZE(value)? */ + if (size < length) { + /* This will copy the terminating NUL character + * if there is space for it. + */ + ++size; + } else if (size > length) { + PyErr_Format(PyExc_ValueError, + "bytes too long (%zd, maximum length %zd)", + size, length); + return NULL; + } + /* Also copy the terminating NUL character if there is space */ + memcpy((char *)ptr, data, size); + + _RET(value); +} + +static PyObject * +z_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + if (value == Py_None) { + *(char **)ptr = NULL; + Py_INCREF(value); + return value; + } + if (PyBytes_Check(value)) { *(const char **)ptr = PyBytes_AsString(value); - Py_INCREF(value); - return value; - } else if (PyLong_Check(value)) { -#if SIZEOF_VOID_P == SIZEOF_LONG_LONG - *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value); -#else - *(char **)ptr = (char *)PyLong_AsUnsignedLongMask(value); -#endif - _RET(value); - } - PyErr_Format(PyExc_TypeError, - "bytes or integer address expected instead of %s instance", + Py_INCREF(value); + return value; + } else if (PyLong_Check(value)) { +#if SIZEOF_VOID_P == SIZEOF_LONG_LONG + *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value); +#else + *(char **)ptr = (char *)PyLong_AsUnsignedLongMask(value); +#endif + _RET(value); + } + PyErr_Format(PyExc_TypeError, + "bytes or integer address expected instead of %s instance", Py_TYPE(value)->tp_name); - return NULL; -} - -static PyObject * -z_get(void *ptr, Py_ssize_t size) -{ - /* XXX What about invalid pointers ??? */ - if (*(void **)ptr) { - return PyBytes_FromStringAndSize(*(char **)ptr, - strlen(*(char **)ptr)); - } else { - Py_RETURN_NONE; - } -} - -#ifdef CTYPES_UNICODE -static PyObject * -Z_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - PyObject *keep; - wchar_t *buffer; + return NULL; +} + +static PyObject * +z_get(void *ptr, Py_ssize_t size) +{ + /* XXX What about invalid pointers ??? */ + if (*(void **)ptr) { + return PyBytes_FromStringAndSize(*(char **)ptr, + strlen(*(char **)ptr)); + } else { + Py_RETURN_NONE; + } +} + +#ifdef CTYPES_UNICODE +static PyObject * +Z_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + PyObject *keep; + wchar_t *buffer; Py_ssize_t bsize; - - if (value == Py_None) { - *(wchar_t **)ptr = NULL; - Py_INCREF(value); - return value; - } - if (PyLong_Check(value)) { -#if SIZEOF_VOID_P == SIZEOF_LONG_LONG - *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value); -#else - *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongMask(value); -#endif - Py_RETURN_NONE; - } - if (!PyUnicode_Check(value)) { - PyErr_Format(PyExc_TypeError, - "unicode string or integer address expected instead of %s instance", + + if (value == Py_None) { + *(wchar_t **)ptr = NULL; + Py_INCREF(value); + return value; + } + if (PyLong_Check(value)) { +#if SIZEOF_VOID_P == SIZEOF_LONG_LONG + *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value); +#else + *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongMask(value); +#endif + Py_RETURN_NONE; + } + if (!PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "unicode string or integer address expected instead of %s instance", Py_TYPE(value)->tp_name); - return NULL; - } - - /* We must create a wchar_t* buffer from the unicode object, - and keep it alive */ + return NULL; + } + + /* We must create a wchar_t* buffer from the unicode object, + and keep it alive */ buffer = PyUnicode_AsWideCharString(value, &bsize); - if (!buffer) - return NULL; - keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor); - if (!keep) { - PyMem_Free(buffer); - return NULL; - } - *(wchar_t **)ptr = buffer; - return keep; -} - -static PyObject * -Z_get(void *ptr, Py_ssize_t size) -{ - wchar_t *p; - p = *(wchar_t **)ptr; - if (p) { - return PyUnicode_FromWideChar(p, wcslen(p)); - } else { - Py_RETURN_NONE; - } -} -#endif - -#ifdef MS_WIN32 -static PyObject * -BSTR_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - BSTR bstr; - - /* convert value into a PyUnicodeObject or NULL */ - if (Py_None == value) { - value = NULL; - } else if (!PyUnicode_Check(value)) { - PyErr_Format(PyExc_TypeError, - "unicode string expected instead of %s instance", + if (!buffer) + return NULL; + keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor); + if (!keep) { + PyMem_Free(buffer); + return NULL; + } + *(wchar_t **)ptr = buffer; + return keep; +} + +static PyObject * +Z_get(void *ptr, Py_ssize_t size) +{ + wchar_t *p; + p = *(wchar_t **)ptr; + if (p) { + return PyUnicode_FromWideChar(p, wcslen(p)); + } else { + Py_RETURN_NONE; + } +} +#endif + +#ifdef MS_WIN32 +static PyObject * +BSTR_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + BSTR bstr; + + /* convert value into a PyUnicodeObject or NULL */ + if (Py_None == value) { + value = NULL; + } else if (!PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "unicode string expected instead of %s instance", Py_TYPE(value)->tp_name); - return NULL; - } - - /* create a BSTR from value */ - if (value) { - Py_ssize_t wsize; + return NULL; + } + + /* create a BSTR from value */ + if (value) { + Py_ssize_t wsize; wchar_t *wvalue = PyUnicode_AsWideCharString(value, &wsize); if (wvalue == NULL) { - return NULL; + return NULL; } - if ((unsigned) wsize != wsize) { - PyErr_SetString(PyExc_ValueError, "String too long for BSTR"); + if ((unsigned) wsize != wsize) { + PyErr_SetString(PyExc_ValueError, "String too long for BSTR"); PyMem_Free(wvalue); - return NULL; - } - bstr = SysAllocStringLen(wvalue, (unsigned)wsize); + return NULL; + } + bstr = SysAllocStringLen(wvalue, (unsigned)wsize); PyMem_Free(wvalue); - } else - bstr = NULL; - - /* free the previous contents, if any */ - if (*(BSTR *)ptr) - SysFreeString(*(BSTR *)ptr); - - /* and store it */ - *(BSTR *)ptr = bstr; - - /* We don't need to keep any other object */ - _RET(value); -} - - -static PyObject * -BSTR_get(void *ptr, Py_ssize_t size) -{ - BSTR p; - p = *(BSTR *)ptr; - if (p) - return PyUnicode_FromWideChar(p, SysStringLen(p)); - else { - /* Hm, it seems NULL pointer and zero length string are the - same in BSTR, see Don Box, p 81 - */ - Py_RETURN_NONE; - } -} -#endif - -static PyObject * -P_set(void *ptr, PyObject *value, Py_ssize_t size) -{ - void *v; - if (value == Py_None) { - *(void **)ptr = NULL; - _RET(value); - } - - if (!PyLong_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "cannot be converted to pointer"); - return NULL; - } - -#if SIZEOF_VOID_P <= SIZEOF_LONG - v = (void *)PyLong_AsUnsignedLongMask(value); -#else -#if SIZEOF_LONG_LONG < SIZEOF_VOID_P -# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)" -#endif - v = (void *)PyLong_AsUnsignedLongLongMask(value); -#endif - - if (PyErr_Occurred()) - return NULL; - - *(void **)ptr = v; - _RET(value); -} - -static PyObject * -P_get(void *ptr, Py_ssize_t size) -{ - if (*(void **)ptr == NULL) { - Py_RETURN_NONE; - } - return PyLong_FromVoidPtr(*(void **)ptr); -} - -static struct fielddesc formattable[] = { - { 's', s_set, s_get, &ffi_type_pointer}, - { 'b', b_set, b_get, &ffi_type_schar}, - { 'B', B_set, B_get, &ffi_type_uchar}, - { 'c', c_set, c_get, &ffi_type_schar}, - { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw}, - { 'g', g_set, g_get, &ffi_type_longdouble}, - { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw}, - { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw}, - { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw}, - { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw}, - { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw}, -/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ -/* As soon as we can get rid of the type codes, this is no longer a problem */ -#if SIZEOF_LONG == 4 - { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw}, - { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw}, -#elif SIZEOF_LONG == 8 - { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw}, - { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw}, -#else -# error -#endif -#if SIZEOF_LONG_LONG == 8 - { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw}, - { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw}, -#else -# error -#endif - { 'P', P_set, P_get, &ffi_type_pointer}, - { 'z', z_set, z_get, &ffi_type_pointer}, -#ifdef CTYPES_UNICODE - { 'u', u_set, u_get, NULL}, /* ffi_type set later */ - { 'U', U_set, U_get, &ffi_type_pointer}, - { 'Z', Z_set, Z_get, &ffi_type_pointer}, -#endif -#ifdef MS_WIN32 - { 'X', BSTR_set, BSTR_get, &ffi_type_pointer}, + } else + bstr = NULL; + + /* free the previous contents, if any */ + if (*(BSTR *)ptr) + SysFreeString(*(BSTR *)ptr); + + /* and store it */ + *(BSTR *)ptr = bstr; + + /* We don't need to keep any other object */ + _RET(value); +} + + +static PyObject * +BSTR_get(void *ptr, Py_ssize_t size) +{ + BSTR p; + p = *(BSTR *)ptr; + if (p) + return PyUnicode_FromWideChar(p, SysStringLen(p)); + else { + /* Hm, it seems NULL pointer and zero length string are the + same in BSTR, see Don Box, p 81 + */ + Py_RETURN_NONE; + } +} +#endif + +static PyObject * +P_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + void *v; + if (value == Py_None) { + *(void **)ptr = NULL; + _RET(value); + } + + if (!PyLong_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "cannot be converted to pointer"); + return NULL; + } + +#if SIZEOF_VOID_P <= SIZEOF_LONG + v = (void *)PyLong_AsUnsignedLongMask(value); +#else +#if SIZEOF_LONG_LONG < SIZEOF_VOID_P +# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)" +#endif + v = (void *)PyLong_AsUnsignedLongLongMask(value); +#endif + + if (PyErr_Occurred()) + return NULL; + + *(void **)ptr = v; + _RET(value); +} + +static PyObject * +P_get(void *ptr, Py_ssize_t size) +{ + if (*(void **)ptr == NULL) { + Py_RETURN_NONE; + } + return PyLong_FromVoidPtr(*(void **)ptr); +} + +static struct fielddesc formattable[] = { + { 's', s_set, s_get, &ffi_type_pointer}, + { 'b', b_set, b_get, &ffi_type_schar}, + { 'B', B_set, B_get, &ffi_type_uchar}, + { 'c', c_set, c_get, &ffi_type_schar}, + { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw}, + { 'g', g_set, g_get, &ffi_type_longdouble}, + { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw}, + { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw}, + { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw}, + { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw}, + { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw}, +/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ +/* As soon as we can get rid of the type codes, this is no longer a problem */ +#if SIZEOF_LONG == 4 + { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw}, + { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw}, +#elif SIZEOF_LONG == 8 + { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw}, + { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw}, +#else +# error +#endif +#if SIZEOF_LONG_LONG == 8 + { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw}, + { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw}, +#else +# error +#endif + { 'P', P_set, P_get, &ffi_type_pointer}, + { 'z', z_set, z_get, &ffi_type_pointer}, +#ifdef CTYPES_UNICODE + { 'u', u_set, u_get, NULL}, /* ffi_type set later */ + { 'U', U_set, U_get, &ffi_type_pointer}, + { 'Z', Z_set, Z_get, &ffi_type_pointer}, +#endif +#ifdef MS_WIN32 + { 'X', BSTR_set, BSTR_get, &ffi_type_pointer}, #endif - { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort}, -#if SIZEOF__BOOL == 1 - { '?', bool_set, bool_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */ -#elif SIZEOF__BOOL == SIZEOF_SHORT - { '?', bool_set, bool_get, &ffi_type_ushort}, -#elif SIZEOF__BOOL == SIZEOF_INT - { '?', bool_set, bool_get, &ffi_type_uint, I_set_sw, I_get_sw}, -#elif SIZEOF__BOOL == SIZEOF_LONG - { '?', bool_set, bool_get, &ffi_type_ulong, L_set_sw, L_get_sw}, -#elif SIZEOF__BOOL == SIZEOF_LONG_LONG - { '?', bool_set, bool_get, &ffi_type_ulong, Q_set_sw, Q_get_sw}, -#endif /* SIZEOF__BOOL */ - { 'O', O_set, O_get, &ffi_type_pointer}, - { 0, NULL, NULL, NULL}, -}; - -/* - Ideas: Implement VARIANT in this table, using 'V' code. - Use '?' as code for BOOL. -*/ - -struct fielddesc * -_ctypes_get_fielddesc(const char *fmt) -{ - static int initialized = 0; - struct fielddesc *table = formattable; - - if (!initialized) { - initialized = 1; -#ifdef CTYPES_UNICODE - if (sizeof(wchar_t) == sizeof(short)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; - else if (sizeof(wchar_t) == sizeof(int)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint; - else if (sizeof(wchar_t) == sizeof(long)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong; -#endif - } - - for (; table->code; ++table) { - if (table->code == fmt[0]) - return table; - } - return NULL; -} - -/*---------------- EOF ----------------*/ + { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort}, +#if SIZEOF__BOOL == 1 + { '?', bool_set, bool_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */ +#elif SIZEOF__BOOL == SIZEOF_SHORT + { '?', bool_set, bool_get, &ffi_type_ushort}, +#elif SIZEOF__BOOL == SIZEOF_INT + { '?', bool_set, bool_get, &ffi_type_uint, I_set_sw, I_get_sw}, +#elif SIZEOF__BOOL == SIZEOF_LONG + { '?', bool_set, bool_get, &ffi_type_ulong, L_set_sw, L_get_sw}, +#elif SIZEOF__BOOL == SIZEOF_LONG_LONG + { '?', bool_set, bool_get, &ffi_type_ulong, Q_set_sw, Q_get_sw}, +#endif /* SIZEOF__BOOL */ + { 'O', O_set, O_get, &ffi_type_pointer}, + { 0, NULL, NULL, NULL}, +}; + +/* + Ideas: Implement VARIANT in this table, using 'V' code. + Use '?' as code for BOOL. +*/ + +struct fielddesc * +_ctypes_get_fielddesc(const char *fmt) +{ + static int initialized = 0; + struct fielddesc *table = formattable; + + if (!initialized) { + initialized = 1; +#ifdef CTYPES_UNICODE + if (sizeof(wchar_t) == sizeof(short)) + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; + else if (sizeof(wchar_t) == sizeof(int)) + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint; + else if (sizeof(wchar_t) == sizeof(long)) + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong; +#endif + } + + for (; table->code; ++table) { + if (table->code == fmt[0]) + return table; + } + return NULL; +} + +/*---------------- EOF ----------------*/ diff --git a/contrib/tools/python3/src/Modules/_ctypes/ctypes.h b/contrib/tools/python3/src/Modules/_ctypes/ctypes.h index 0f422113a89..d6e7a89bf9b 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/ctypes.h +++ b/contrib/tools/python3/src/Modules/_ctypes/ctypes.h @@ -1,371 +1,371 @@ -#if defined (__SVR4) && defined (__sun) -# include -#endif - -#ifndef MS_WIN32 -#define max(a, b) ((a) > (b) ? (a) : (b)) -#define min(a, b) ((a) < (b) ? (a) : (b)) - -#define PARAMFLAG_FIN 0x1 -#define PARAMFLAG_FOUT 0x2 -#define PARAMFLAG_FLCID 0x4 -#endif - -typedef struct tagPyCArgObject PyCArgObject; -typedef struct tagCDataObject CDataObject; -typedef PyObject *(* GETFUNC)(void *, Py_ssize_t size); -typedef PyObject *(* SETFUNC)(void *, PyObject *value, Py_ssize_t size); -typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj); - -/* A default buffer in CDataObject, which can be used for small C types. If -this buffer is too small, PyMem_Malloc will be called to create a larger one, -and this one is not used. - -Making CDataObject a variable size object would be a better solution, but more -difficult in the presence of PyCFuncPtrObject. Maybe later. -*/ -union value { - char c[16]; - short s; - int i; - long l; - float f; - double d; - long long ll; - long double D; -}; - -/* - Hm. Are there CDataObject's which do not need the b_objects member? In - this case we probably should introduce b_flags to mark it as present... If - b_objects is not present/unused b_length is unneeded as well. -*/ - -struct tagCDataObject { - PyObject_HEAD - char *b_ptr; /* pointer to memory block */ - int b_needsfree; /* need _we_ free the memory? */ - CDataObject *b_base; /* pointer to base object or NULL */ - Py_ssize_t b_size; /* size of memory block in bytes */ - Py_ssize_t b_length; /* number of references we need */ - Py_ssize_t b_index; /* index of this object into base's - b_object list */ - PyObject *b_objects; /* dictionary of references we need to keep, or Py_None */ - union value b_value; -}; - -typedef struct { - PyObject_VAR_HEAD - ffi_closure *pcl_write; /* the C callable, writeable */ - void *pcl_exec; /* the C callable, executable */ - ffi_cif cif; - int flags; - PyObject *converters; - PyObject *callable; - PyObject *restype; - SETFUNC setfunc; - ffi_type *ffi_restype; - ffi_type *atypes[1]; -} CThunkObject; -extern PyTypeObject PyCThunk_Type; +#if defined (__SVR4) && defined (__sun) +# include +#endif + +#ifndef MS_WIN32 +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) + +#define PARAMFLAG_FIN 0x1 +#define PARAMFLAG_FOUT 0x2 +#define PARAMFLAG_FLCID 0x4 +#endif + +typedef struct tagPyCArgObject PyCArgObject; +typedef struct tagCDataObject CDataObject; +typedef PyObject *(* GETFUNC)(void *, Py_ssize_t size); +typedef PyObject *(* SETFUNC)(void *, PyObject *value, Py_ssize_t size); +typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj); + +/* A default buffer in CDataObject, which can be used for small C types. If +this buffer is too small, PyMem_Malloc will be called to create a larger one, +and this one is not used. + +Making CDataObject a variable size object would be a better solution, but more +difficult in the presence of PyCFuncPtrObject. Maybe later. +*/ +union value { + char c[16]; + short s; + int i; + long l; + float f; + double d; + long long ll; + long double D; +}; + +/* + Hm. Are there CDataObject's which do not need the b_objects member? In + this case we probably should introduce b_flags to mark it as present... If + b_objects is not present/unused b_length is unneeded as well. +*/ + +struct tagCDataObject { + PyObject_HEAD + char *b_ptr; /* pointer to memory block */ + int b_needsfree; /* need _we_ free the memory? */ + CDataObject *b_base; /* pointer to base object or NULL */ + Py_ssize_t b_size; /* size of memory block in bytes */ + Py_ssize_t b_length; /* number of references we need */ + Py_ssize_t b_index; /* index of this object into base's + b_object list */ + PyObject *b_objects; /* dictionary of references we need to keep, or Py_None */ + union value b_value; +}; + +typedef struct { + PyObject_VAR_HEAD + ffi_closure *pcl_write; /* the C callable, writeable */ + void *pcl_exec; /* the C callable, executable */ + ffi_cif cif; + int flags; + PyObject *converters; + PyObject *callable; + PyObject *restype; + SETFUNC setfunc; + ffi_type *ffi_restype; + ffi_type *atypes[1]; +} CThunkObject; +extern PyTypeObject PyCThunk_Type; #define CThunk_CheckExact(v) Py_IS_TYPE(v, &PyCThunk_Type) - -typedef struct { - /* First part identical to tagCDataObject */ - PyObject_HEAD - char *b_ptr; /* pointer to memory block */ - int b_needsfree; /* need _we_ free the memory? */ - CDataObject *b_base; /* pointer to base object or NULL */ - Py_ssize_t b_size; /* size of memory block in bytes */ - Py_ssize_t b_length; /* number of references we need */ - Py_ssize_t b_index; /* index of this object into base's - b_object list */ - PyObject *b_objects; /* list of references we need to keep */ - union value b_value; - /* end of tagCDataObject, additional fields follow */ - - CThunkObject *thunk; - PyObject *callable; - - /* These two fields will override the ones in the type's stgdict if - they are set */ - PyObject *converters; - PyObject *argtypes; - PyObject *restype; - PyObject *checker; - PyObject *errcheck; -#ifdef MS_WIN32 - int index; - GUID *iid; -#endif - PyObject *paramflags; -} PyCFuncPtrObject; - -extern PyTypeObject PyCStgDict_Type; + +typedef struct { + /* First part identical to tagCDataObject */ + PyObject_HEAD + char *b_ptr; /* pointer to memory block */ + int b_needsfree; /* need _we_ free the memory? */ + CDataObject *b_base; /* pointer to base object or NULL */ + Py_ssize_t b_size; /* size of memory block in bytes */ + Py_ssize_t b_length; /* number of references we need */ + Py_ssize_t b_index; /* index of this object into base's + b_object list */ + PyObject *b_objects; /* list of references we need to keep */ + union value b_value; + /* end of tagCDataObject, additional fields follow */ + + CThunkObject *thunk; + PyObject *callable; + + /* These two fields will override the ones in the type's stgdict if + they are set */ + PyObject *converters; + PyObject *argtypes; + PyObject *restype; + PyObject *checker; + PyObject *errcheck; +#ifdef MS_WIN32 + int index; + GUID *iid; +#endif + PyObject *paramflags; +} PyCFuncPtrObject; + +extern PyTypeObject PyCStgDict_Type; #define PyCStgDict_CheckExact(v) Py_IS_TYPE(v, &PyCStgDict_Type) -#define PyCStgDict_Check(v) PyObject_TypeCheck(v, &PyCStgDict_Type) - -extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); -extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); -extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); - - - -extern PyTypeObject PyCData_Type; +#define PyCStgDict_Check(v) PyObject_TypeCheck(v, &PyCStgDict_Type) + +extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); +extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); +extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); + + + +extern PyTypeObject PyCData_Type; #define CDataObject_CheckExact(v) Py_IS_TYPE(v, &PyCData_Type) -#define CDataObject_Check(v) PyObject_TypeCheck(v, &PyCData_Type) -#define _CDataObject_HasExternalBuffer(v) ((v)->b_ptr != (char *)&(v)->b_value) - -extern PyTypeObject PyCSimpleType_Type; +#define CDataObject_Check(v) PyObject_TypeCheck(v, &PyCData_Type) +#define _CDataObject_HasExternalBuffer(v) ((v)->b_ptr != (char *)&(v)->b_value) + +extern PyTypeObject PyCSimpleType_Type; #define PyCSimpleTypeObject_CheckExact(v) Py_IS_TYPE(v, &PyCSimpleType_Type) -#define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) - -extern PyTypeObject PyCField_Type; -extern struct fielddesc *_ctypes_get_fielddesc(const char *fmt); - - -extern PyObject * -PyCField_FromDesc(PyObject *desc, Py_ssize_t index, - Py_ssize_t *pfield_size, int bitsize, int *pbitofs, - Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, - int pack, int is_big_endian); - -extern PyObject *PyCData_AtAddress(PyObject *type, void *buf); -extern PyObject *PyCData_FromBytes(PyObject *type, char *data, Py_ssize_t length); - -extern PyTypeObject PyCArrayType_Type; -extern PyTypeObject PyCArray_Type; -extern PyTypeObject PyCPointerType_Type; -extern PyTypeObject PyCPointer_Type; -extern PyTypeObject PyCFuncPtr_Type; -extern PyTypeObject PyCFuncPtrType_Type; -extern PyTypeObject PyCStructType_Type; - -#define PyCArrayTypeObject_Check(v) PyObject_TypeCheck(v, &PyCArrayType_Type) -#define ArrayObject_Check(v) PyObject_TypeCheck(v, &PyCArray_Type) -#define PointerObject_Check(v) PyObject_TypeCheck(v, &PyCPointer_Type) -#define PyCPointerTypeObject_Check(v) PyObject_TypeCheck(v, &PyCPointerType_Type) -#define PyCFuncPtrObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtr_Type) -#define PyCFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtrType_Type) -#define PyCStructTypeObject_Check(v) PyObject_TypeCheck(v, &PyCStructType_Type) - -extern PyObject * -PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length); - -extern PyMethodDef _ctypes_module_methods[]; - -extern CThunkObject *_ctypes_alloc_callback(PyObject *callable, - PyObject *converters, - PyObject *restype, - int flags); -/* a table entry describing a predefined ctypes type */ -struct fielddesc { - char code; - SETFUNC setfunc; - GETFUNC getfunc; - ffi_type *pffi_type; /* always statically allocated */ - SETFUNC setfunc_swapped; - GETFUNC getfunc_swapped; -}; - -typedef struct { - PyObject_HEAD - Py_ssize_t offset; - Py_ssize_t size; - Py_ssize_t index; /* Index into CDataObject's - object array */ - PyObject *proto; /* a type or NULL */ - GETFUNC getfunc; /* getter function if proto is NULL */ - SETFUNC setfunc; /* setter function if proto is NULL */ - int anonymous; -} CFieldObject; - -/* A subclass of PyDictObject, used as the instance dictionary of ctypes - metatypes */ -typedef struct { - PyDictObject dict; /* first part identical to PyDictObject */ -/* The size and align fields are unneeded, they are in ffi_type as well. As - an experiment shows, it's trivial to get rid of them, the only thing to - remember is that in PyCArrayType_new the ffi_type fields must be filled in - - so far it was unneeded because libffi doesn't support arrays at all - (because they are passed as pointers to function calls anyway). But it's - too much risk to change that now, and there are other fields which doesn't - belong into this structure anyway. Maybe in ctypes 2.0... (ctypes 2000?) -*/ - Py_ssize_t size; /* number of bytes */ - Py_ssize_t align; /* alignment requirements */ - Py_ssize_t length; /* number of fields */ - ffi_type ffi_type_pointer; - PyObject *proto; /* Only for Pointer/ArrayObject */ - SETFUNC setfunc; /* Only for simple objects */ - GETFUNC getfunc; /* Only for simple objects */ - PARAMFUNC paramfunc; - - /* Following fields only used by PyCFuncPtrType_Type instances */ - PyObject *argtypes; /* tuple of CDataObjects */ - PyObject *converters; /* tuple([t.from_param for t in argtypes]) */ - PyObject *restype; /* CDataObject or NULL */ - PyObject *checker; - int flags; /* calling convention and such */ - +#define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) + +extern PyTypeObject PyCField_Type; +extern struct fielddesc *_ctypes_get_fielddesc(const char *fmt); + + +extern PyObject * +PyCField_FromDesc(PyObject *desc, Py_ssize_t index, + Py_ssize_t *pfield_size, int bitsize, int *pbitofs, + Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, + int pack, int is_big_endian); + +extern PyObject *PyCData_AtAddress(PyObject *type, void *buf); +extern PyObject *PyCData_FromBytes(PyObject *type, char *data, Py_ssize_t length); + +extern PyTypeObject PyCArrayType_Type; +extern PyTypeObject PyCArray_Type; +extern PyTypeObject PyCPointerType_Type; +extern PyTypeObject PyCPointer_Type; +extern PyTypeObject PyCFuncPtr_Type; +extern PyTypeObject PyCFuncPtrType_Type; +extern PyTypeObject PyCStructType_Type; + +#define PyCArrayTypeObject_Check(v) PyObject_TypeCheck(v, &PyCArrayType_Type) +#define ArrayObject_Check(v) PyObject_TypeCheck(v, &PyCArray_Type) +#define PointerObject_Check(v) PyObject_TypeCheck(v, &PyCPointer_Type) +#define PyCPointerTypeObject_Check(v) PyObject_TypeCheck(v, &PyCPointerType_Type) +#define PyCFuncPtrObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtr_Type) +#define PyCFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtrType_Type) +#define PyCStructTypeObject_Check(v) PyObject_TypeCheck(v, &PyCStructType_Type) + +extern PyObject * +PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length); + +extern PyMethodDef _ctypes_module_methods[]; + +extern CThunkObject *_ctypes_alloc_callback(PyObject *callable, + PyObject *converters, + PyObject *restype, + int flags); +/* a table entry describing a predefined ctypes type */ +struct fielddesc { + char code; + SETFUNC setfunc; + GETFUNC getfunc; + ffi_type *pffi_type; /* always statically allocated */ + SETFUNC setfunc_swapped; + GETFUNC getfunc_swapped; +}; + +typedef struct { + PyObject_HEAD + Py_ssize_t offset; + Py_ssize_t size; + Py_ssize_t index; /* Index into CDataObject's + object array */ + PyObject *proto; /* a type or NULL */ + GETFUNC getfunc; /* getter function if proto is NULL */ + SETFUNC setfunc; /* setter function if proto is NULL */ + int anonymous; +} CFieldObject; + +/* A subclass of PyDictObject, used as the instance dictionary of ctypes + metatypes */ +typedef struct { + PyDictObject dict; /* first part identical to PyDictObject */ +/* The size and align fields are unneeded, they are in ffi_type as well. As + an experiment shows, it's trivial to get rid of them, the only thing to + remember is that in PyCArrayType_new the ffi_type fields must be filled in - + so far it was unneeded because libffi doesn't support arrays at all + (because they are passed as pointers to function calls anyway). But it's + too much risk to change that now, and there are other fields which doesn't + belong into this structure anyway. Maybe in ctypes 2.0... (ctypes 2000?) +*/ + Py_ssize_t size; /* number of bytes */ + Py_ssize_t align; /* alignment requirements */ + Py_ssize_t length; /* number of fields */ + ffi_type ffi_type_pointer; + PyObject *proto; /* Only for Pointer/ArrayObject */ + SETFUNC setfunc; /* Only for simple objects */ + GETFUNC getfunc; /* Only for simple objects */ + PARAMFUNC paramfunc; + + /* Following fields only used by PyCFuncPtrType_Type instances */ + PyObject *argtypes; /* tuple of CDataObjects */ + PyObject *converters; /* tuple([t.from_param for t in argtypes]) */ + PyObject *restype; /* CDataObject or NULL */ + PyObject *checker; + int flags; /* calling convention and such */ + /* pep3118 fields, pointers need PyMem_Free */ - char *format; - int ndim; - Py_ssize_t *shape; -/* Py_ssize_t *strides; */ /* unused in ctypes */ -/* Py_ssize_t *suboffsets; */ /* unused in ctypes */ - -} StgDictObject; - -/**************************************************************** - StgDictObject fields - - setfunc and getfunc is only set for simple data types, it is copied from the - corresponding fielddesc entry. These are functions to set and get the value - in a memory block. - They should probably by used by other types as well. - - proto is only used for Pointer and Array types - it points to the item type - object. - - Probably all the magic ctypes methods (like from_param) should have C - callable wrappers in the StgDictObject. For simple data type, for example, - the fielddesc table could have entries for C codec from_param functions or - other methods as well, if a subtype overrides this method in Python at - construction time, or assigns to it later, tp_setattro should update the - StgDictObject function to a generic one. - - Currently, PyCFuncPtr types have 'converters' and 'checker' entries in their - type dict. They are only used to cache attributes from other entries, which - is wrong. - - One use case is the .value attribute that all simple types have. But some - complex structures, like VARIANT, represent a single value also, and should - have this attribute. - - Another use case is a _check_retval_ function, which is called when a ctypes - type is used as return type of a function to validate and compute the return - value. - - Common ctypes protocol: - - - setfunc: store a python value in a memory block - - getfunc: convert data from a memory block into a python value - - - checkfunc: validate and convert a return value from a function call - - toparamfunc: convert a python value into a function argument - -*****************************************************************/ - -/* May return NULL, but does not set an exception! */ -extern StgDictObject *PyType_stgdict(PyObject *obj); - -/* May return NULL, but does not set an exception! */ -extern StgDictObject *PyObject_stgdict(PyObject *self); - -extern int PyCStgDict_clone(StgDictObject *src, StgDictObject *dst); - -typedef int(* PPROC)(void); - -PyObject *_ctypes_callproc(PPROC pProc, - PyObject *arguments, -#ifdef MS_WIN32 - IUnknown *pIUnk, - GUID *iid, -#endif - int flags, - PyObject *argtypes, - PyObject *restype, - PyObject *checker); - - -#define FUNCFLAG_STDCALL 0x0 -#define FUNCFLAG_CDECL 0x1 -#define FUNCFLAG_HRESULT 0x2 -#define FUNCFLAG_PYTHONAPI 0x4 -#define FUNCFLAG_USE_ERRNO 0x8 -#define FUNCFLAG_USE_LASTERROR 0x10 - -#define TYPEFLAG_ISPOINTER 0x100 -#define TYPEFLAG_HASPOINTER 0x200 + char *format; + int ndim; + Py_ssize_t *shape; +/* Py_ssize_t *strides; */ /* unused in ctypes */ +/* Py_ssize_t *suboffsets; */ /* unused in ctypes */ + +} StgDictObject; + +/**************************************************************** + StgDictObject fields + + setfunc and getfunc is only set for simple data types, it is copied from the + corresponding fielddesc entry. These are functions to set and get the value + in a memory block. + They should probably by used by other types as well. + + proto is only used for Pointer and Array types - it points to the item type + object. + + Probably all the magic ctypes methods (like from_param) should have C + callable wrappers in the StgDictObject. For simple data type, for example, + the fielddesc table could have entries for C codec from_param functions or + other methods as well, if a subtype overrides this method in Python at + construction time, or assigns to it later, tp_setattro should update the + StgDictObject function to a generic one. + + Currently, PyCFuncPtr types have 'converters' and 'checker' entries in their + type dict. They are only used to cache attributes from other entries, which + is wrong. + + One use case is the .value attribute that all simple types have. But some + complex structures, like VARIANT, represent a single value also, and should + have this attribute. + + Another use case is a _check_retval_ function, which is called when a ctypes + type is used as return type of a function to validate and compute the return + value. + + Common ctypes protocol: + + - setfunc: store a python value in a memory block + - getfunc: convert data from a memory block into a python value + + - checkfunc: validate and convert a return value from a function call + - toparamfunc: convert a python value into a function argument + +*****************************************************************/ + +/* May return NULL, but does not set an exception! */ +extern StgDictObject *PyType_stgdict(PyObject *obj); + +/* May return NULL, but does not set an exception! */ +extern StgDictObject *PyObject_stgdict(PyObject *self); + +extern int PyCStgDict_clone(StgDictObject *src, StgDictObject *dst); + +typedef int(* PPROC)(void); + +PyObject *_ctypes_callproc(PPROC pProc, + PyObject *arguments, +#ifdef MS_WIN32 + IUnknown *pIUnk, + GUID *iid, +#endif + int flags, + PyObject *argtypes, + PyObject *restype, + PyObject *checker); + + +#define FUNCFLAG_STDCALL 0x0 +#define FUNCFLAG_CDECL 0x1 +#define FUNCFLAG_HRESULT 0x2 +#define FUNCFLAG_PYTHONAPI 0x4 +#define FUNCFLAG_USE_ERRNO 0x8 +#define FUNCFLAG_USE_LASTERROR 0x10 + +#define TYPEFLAG_ISPOINTER 0x100 +#define TYPEFLAG_HASPOINTER 0x200 #define TYPEFLAG_HASUNION 0x400 #define TYPEFLAG_HASBITFIELD 0x800 - -#define DICTFLAG_FINAL 0x1000 - -struct tagPyCArgObject { - PyObject_HEAD - ffi_type *pffi_type; - char tag; - union { - char c; - char b; - short h; - int i; - long l; - long long q; - long double D; - double d; - float f; - void *p; - } value; - PyObject *obj; - Py_ssize_t size; /* for the 'V' tag */ -}; - -extern PyTypeObject PyCArg_Type; + +#define DICTFLAG_FINAL 0x1000 + +struct tagPyCArgObject { + PyObject_HEAD + ffi_type *pffi_type; + char tag; + union { + char c; + char b; + short h; + int i; + long l; + long long q; + long double D; + double d; + float f; + void *p; + } value; + PyObject *obj; + Py_ssize_t size; /* for the 'V' tag */ +}; + +extern PyTypeObject PyCArg_Type; #define PyCArg_CheckExact(v) Py_IS_TYPE(v, &PyCArg_Type) -extern PyCArgObject *PyCArgObject_new(void); - -extern PyObject * -PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, - Py_ssize_t index, Py_ssize_t size, char *ptr); - -extern int -PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, - Py_ssize_t index, Py_ssize_t size, char *ptr); - -extern void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...); - -struct basespec { - CDataObject *base; - Py_ssize_t index; - char *adr; -}; - -extern char basespec_string[]; - -extern ffi_type *_ctypes_get_ffi_type(PyObject *obj); - -/* exception classes */ -extern PyObject *PyExc_ArgError; - -extern char *_ctypes_conversion_encoding; -extern char *_ctypes_conversion_errors; - -#if defined(HAVE_WCHAR_H) -# define CTYPES_UNICODE -#endif - - -extern void _ctypes_free_closure(void *); -extern void *_ctypes_alloc_closure(void); - -extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); -extern char *_ctypes_alloc_format_string(const char *prefix, const char *suffix); -extern char *_ctypes_alloc_format_string_with_shape(int ndim, - const Py_ssize_t *shape, - const char *prefix, const char *suffix); - -extern int _ctypes_simple_instance(PyObject *obj); - -extern PyObject *_ctypes_ptrtype_cache; -PyObject *_ctypes_get_errobj(int **pspace); - -#ifdef MS_WIN32 -extern PyObject *ComError; -#endif - +extern PyCArgObject *PyCArgObject_new(void); + +extern PyObject * +PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, + Py_ssize_t index, Py_ssize_t size, char *ptr); + +extern int +PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, + Py_ssize_t index, Py_ssize_t size, char *ptr); + +extern void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...); + +struct basespec { + CDataObject *base; + Py_ssize_t index; + char *adr; +}; + +extern char basespec_string[]; + +extern ffi_type *_ctypes_get_ffi_type(PyObject *obj); + +/* exception classes */ +extern PyObject *PyExc_ArgError; + +extern char *_ctypes_conversion_encoding; +extern char *_ctypes_conversion_errors; + +#if defined(HAVE_WCHAR_H) +# define CTYPES_UNICODE +#endif + + +extern void _ctypes_free_closure(void *); +extern void *_ctypes_alloc_closure(void); + +extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); +extern char *_ctypes_alloc_format_string(const char *prefix, const char *suffix); +extern char *_ctypes_alloc_format_string_with_shape(int ndim, + const Py_ssize_t *shape, + const char *prefix, const char *suffix); + +extern int _ctypes_simple_instance(PyObject *obj); + +extern PyObject *_ctypes_ptrtype_cache; +PyObject *_ctypes_get_errobj(int **pspace); + +#ifdef MS_WIN32 +extern PyObject *ComError; +#endif + #if USING_MALLOC_CLOSURE_DOT_C void Py_ffi_closure_free(void *p); void *Py_ffi_closure_alloc(size_t size, void** codeloc); @@ -374,8 +374,8 @@ void *Py_ffi_closure_alloc(size_t size, void** codeloc); #define Py_ffi_closure_alloc ffi_closure_alloc #endif -/* - Local Variables: - compile-command: "python setup.py -q build install --home ~" - End: -*/ +/* + Local Variables: + compile-command: "python setup.py -q build install --home ~" + End: +*/ diff --git a/contrib/tools/python3/src/Modules/_ctypes/ctypes_dlfcn.h b/contrib/tools/python3/src/Modules/_ctypes/ctypes_dlfcn.h index 54cdde9a4fd..b7f84f1dce7 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/ctypes_dlfcn.h +++ b/contrib/tools/python3/src/Modules/_ctypes/ctypes_dlfcn.h @@ -1,27 +1,27 @@ -#ifndef _CTYPES_DLFCN_H_ -#define _CTYPES_DLFCN_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef MS_WIN32 - -#include - -#ifndef CTYPES_DARWIN_DLFCN - -#define ctypes_dlsym dlsym -#define ctypes_dlerror dlerror -#define ctypes_dlopen dlopen -#define ctypes_dlclose dlclose -#define ctypes_dladdr dladdr - -#endif /* !CTYPES_DARWIN_DLFCN */ - -#endif /* !MS_WIN32 */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _CTYPES_DLFCN_H_ */ +#ifndef _CTYPES_DLFCN_H_ +#define _CTYPES_DLFCN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef MS_WIN32 + +#include + +#ifndef CTYPES_DARWIN_DLFCN + +#define ctypes_dlsym dlsym +#define ctypes_dlerror dlerror +#define ctypes_dlopen dlopen +#define ctypes_dlclose dlclose +#define ctypes_dladdr dladdr + +#endif /* !CTYPES_DARWIN_DLFCN */ + +#endif /* !MS_WIN32 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _CTYPES_DLFCN_H_ */ diff --git a/contrib/tools/python3/src/Modules/_ctypes/darwin/dlfcn.h b/contrib/tools/python3/src/Modules/_ctypes/darwin/dlfcn.h index a2afc3eeb84..58562b287bb 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/darwin/dlfcn.h +++ b/contrib/tools/python3/src/Modules/_ctypes/darwin/dlfcn.h @@ -1,84 +1,84 @@ -/* -Copyright (c) 2002 Jorge Acereda & - Peter O'Gorman - -Portions may be copyright others, see the AUTHORS file included with this -distribution. - -Maintained by Peter O'Gorman - -Bug Reports and other queries should go to - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -#ifndef _DLFCN_H_ -#define _DLFCN_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Structure filled in by dladdr(). - */ - -typedef struct dl_info { - const char *dli_fname; /* Pathname of shared object */ - void *dli_fbase; /* Base address of shared object */ - const char *dli_sname; /* Name of nearest symbol */ - void *dli_saddr; /* Address of nearest symbol */ -} Dl_info; - - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_2 -#warning CTYPES_DARWIN_DLFCN -#define CTYPES_DARWIN_DLFCN -extern void * (*ctypes_dlopen)(const char *path, int mode); -extern void * (*ctypes_dlsym)(void * handle, const char *symbol); -extern const char * (*ctypes_dlerror)(void); -extern int (*ctypes_dlclose)(void * handle); -extern int (*ctypes_dladdr)(const void *, Dl_info *); -#else -extern void * dlopen(const char *path, int mode); -extern void * dlsym(void * handle, const char *symbol); -extern const char * dlerror(void); -extern int dlclose(void * handle); -extern int dladdr(const void *, Dl_info *); -#endif - -#define RTLD_LAZY 0x1 -#define RTLD_NOW 0x2 -#define RTLD_LOCAL 0x4 -#define RTLD_GLOBAL 0x8 -#define RTLD_NOLOAD 0x10 -#define RTLD_NODELETE 0x80 - -/* These are from the Mac OS X 10.4 headers */ -#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */ -#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */ - -#ifdef __cplusplus -} -#endif - -#endif /* _DLFCN_H_ */ +/* +Copyright (c) 2002 Jorge Acereda & + Peter O'Gorman + +Portions may be copyright others, see the AUTHORS file included with this +distribution. + +Maintained by Peter O'Gorman + +Bug Reports and other queries should go to + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef _DLFCN_H_ +#define _DLFCN_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Structure filled in by dladdr(). + */ + +typedef struct dl_info { + const char *dli_fname; /* Pathname of shared object */ + void *dli_fbase; /* Base address of shared object */ + const char *dli_sname; /* Name of nearest symbol */ + void *dli_saddr; /* Address of nearest symbol */ +} Dl_info; + + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_2 +#warning CTYPES_DARWIN_DLFCN +#define CTYPES_DARWIN_DLFCN +extern void * (*ctypes_dlopen)(const char *path, int mode); +extern void * (*ctypes_dlsym)(void * handle, const char *symbol); +extern const char * (*ctypes_dlerror)(void); +extern int (*ctypes_dlclose)(void * handle); +extern int (*ctypes_dladdr)(const void *, Dl_info *); +#else +extern void * dlopen(const char *path, int mode); +extern void * dlsym(void * handle, const char *symbol); +extern const char * dlerror(void); +extern int dlclose(void * handle); +extern int dladdr(const void *, Dl_info *); +#endif + +#define RTLD_LAZY 0x1 +#define RTLD_NOW 0x2 +#define RTLD_LOCAL 0x4 +#define RTLD_GLOBAL 0x8 +#define RTLD_NOLOAD 0x10 +#define RTLD_NODELETE 0x80 + +/* These are from the Mac OS X 10.4 headers */ +#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */ +#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */ + +#ifdef __cplusplus +} +#endif + +#endif /* _DLFCN_H_ */ diff --git a/contrib/tools/python3/src/Modules/_ctypes/darwin/dlfcn_simple.c b/contrib/tools/python3/src/Modules/_ctypes/darwin/dlfcn_simple.c index 2b293bb8695..841fbdbb601 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/darwin/dlfcn_simple.c +++ b/contrib/tools/python3/src/Modules/_ctypes/darwin/dlfcn_simple.c @@ -1,272 +1,272 @@ -/* -Copyright (c) 2002 Peter O'Gorman - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - - -/* Just to prove that it isn't that hard to add Mac calls to your code :) - This works with pretty much everything, including kde3 xemacs and the gimp, - I'd guess that it'd work in at least 95% of cases, use this as your starting - point, rather than the mess that is dlfcn.c, assuming that your code does not - require ref counting or symbol lookups in dependent libraries -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dlfcn.h" - -#ifdef CTYPES_DARWIN_DLFCN - -#define ERR_STR_LEN 256 - -#ifndef MAC_OS_X_VERSION_10_3 -#define MAC_OS_X_VERSION_10_3 1030 -#endif - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 -#define DARWIN_HAS_DLOPEN -extern void * dlopen(const char *path, int mode) __attribute__((weak_import)); -extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import)); -extern const char * dlerror(void) __attribute__((weak_import)); -extern int dlclose(void * handle) __attribute__((weak_import)); -extern int dladdr(const void *, Dl_info *) __attribute__((weak_import)); -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */ - -#ifndef DARWIN_HAS_DLOPEN -#define dlopen darwin_dlopen -#define dlsym darwin_dlsym -#define dlerror darwin_dlerror -#define dlclose darwin_dlclose -#define dladdr darwin_dladdr -#endif - -void * (*ctypes_dlopen)(const char *path, int mode); -void * (*ctypes_dlsym)(void * handle, const char *symbol); -const char * (*ctypes_dlerror)(void); -int (*ctypes_dlclose)(void * handle); -int (*ctypes_dladdr)(const void *, Dl_info *); - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 -/* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */ - -static void *dlsymIntern(void *handle, const char *symbol); - -static const char *error(int setget, const char *str, ...); - -/* Set and get the error string for use by dlerror */ -static const char *error(int setget, const char *str, ...) -{ - static char errstr[ERR_STR_LEN]; - static int err_filled = 0; - const char *retval; - va_list arg; - if (setget == 0) - { - va_start(arg, str); - strncpy(errstr, "dlcompat: ", ERR_STR_LEN); - vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg); - va_end(arg); - err_filled = 1; - retval = NULL; - } - else - { - if (!err_filled) - retval = NULL; - else - retval = errstr; - err_filled = 0; - } - return retval; -} - -/* darwin_dlopen */ -static void *darwin_dlopen(const char *path, int mode) -{ - void *module = 0; - NSObjectFileImage ofi = 0; - NSObjectFileImageReturnCode ofirc; - - /* If we got no path, the app wants the global namespace, use -1 as the marker - in this case */ - if (!path) - return (void *)-1; - - /* Create the object file image, works for things linked with the -bundle arg to ld */ - ofirc = NSCreateObjectFileImageFromFile(path, &ofi); - switch (ofirc) - { - case NSObjectFileImageSuccess: - /* It was okay, so use NSLinkModule to link in the image */ - module = NSLinkModule(ofi, path, - NSLINKMODULE_OPTION_RETURN_ON_ERROR - | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE - | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW); - NSDestroyObjectFileImage(ofi); - break; - case NSObjectFileImageInappropriateFile: - /* It may have been a dynamic library rather than a bundle, try to load it */ - module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); - break; - default: - /* God knows what we got */ - error(0, "Can not open \"%s\"", path); - return 0; - } - if (!module) - error(0, "Can not open \"%s\"", path); - return module; - -} - -/* dlsymIntern is used by dlsym to find the symbol */ -static void *dlsymIntern(void *handle, const char *symbol) -{ - NSSymbol nssym = 0; - /* If the handle is -1, if is the app global context */ - if (handle == (void *)-1) - { - /* Global context, use NSLookupAndBindSymbol */ - if (NSIsSymbolNameDefined(symbol)) - { - nssym = NSLookupAndBindSymbol(symbol); - } - - } - /* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image - for libraries, and NSLookupSymbolInModule for bundles */ - else - { - /* Check for both possible magic numbers depending on x86/ppc byte order */ - if ((((struct mach_header *)handle)->magic == MH_MAGIC) || - (((struct mach_header *)handle)->magic == MH_CIGAM)) - { - if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol)) - { - nssym = NSLookupSymbolInImage((struct mach_header *)handle, - symbol, - NSLOOKUPSYMBOLINIMAGE_OPTION_BIND - | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); - } - - } - else - { - nssym = NSLookupSymbolInModule(handle, symbol); - } - } - if (!nssym) - { - error(0, "Symbol \"%s\" Not found", symbol); - return NULL; - } - return NSAddressOfSymbol(nssym); -} - -static const char *darwin_dlerror(void) -{ - return error(1, (char *)NULL); -} - -static int darwin_dlclose(void *handle) -{ - if ((((struct mach_header *)handle)->magic == MH_MAGIC) || - (((struct mach_header *)handle)->magic == MH_CIGAM)) - { - error(0, "Can't remove dynamic libraries on darwin"); - return 0; - } - if (!NSUnLinkModule(handle, 0)) - { - error(0, "unable to unlink module %s", NSNameOfModule(handle)); - return 1; - } - return 0; -} - - -/* dlsym, prepend the underscore and call dlsymIntern */ -static void *darwin_dlsym(void *handle, const char *symbol) -{ - static char undersym[257]; /* Saves calls to malloc(3) */ - int sym_len = strlen(symbol); - void *value = NULL; - char *malloc_sym = NULL; - - if (sym_len < 256) - { - snprintf(undersym, 256, "_%s", symbol); - value = dlsymIntern(handle, undersym); - } - else - { - malloc_sym = malloc(sym_len + 2); - if (malloc_sym) - { - sprintf(malloc_sym, "_%s", symbol); - value = dlsymIntern(handle, malloc_sym); - free(malloc_sym); - } - else - { - error(0, "Unable to allocate memory"); - } - } - return value; -} - -static int darwin_dladdr(const void *handle, Dl_info *info) { - return 0; -} -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */ - -#if __GNUC__ < 4 -#pragma CALL_ON_LOAD ctypes_dlfcn_init -#else -static void __attribute__ ((constructor)) ctypes_dlfcn_init(void); -static -#endif -void ctypes_dlfcn_init(void) { - if (dlopen != NULL) { - ctypes_dlsym = dlsym; - ctypes_dlopen = dlopen; - ctypes_dlerror = dlerror; - ctypes_dlclose = dlclose; - ctypes_dladdr = dladdr; - } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 - ctypes_dlsym = darwin_dlsym; - ctypes_dlopen = darwin_dlopen; - ctypes_dlerror = darwin_dlerror; - ctypes_dlclose = darwin_dlclose; - ctypes_dladdr = darwin_dladdr; -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */ - } -} - -#endif /* CTYPES_DARWIN_DLFCN */ +/* +Copyright (c) 2002 Peter O'Gorman + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +/* Just to prove that it isn't that hard to add Mac calls to your code :) + This works with pretty much everything, including kde3 xemacs and the gimp, + I'd guess that it'd work in at least 95% of cases, use this as your starting + point, rather than the mess that is dlfcn.c, assuming that your code does not + require ref counting or symbol lookups in dependent libraries +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dlfcn.h" + +#ifdef CTYPES_DARWIN_DLFCN + +#define ERR_STR_LEN 256 + +#ifndef MAC_OS_X_VERSION_10_3 +#define MAC_OS_X_VERSION_10_3 1030 +#endif + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 +#define DARWIN_HAS_DLOPEN +extern void * dlopen(const char *path, int mode) __attribute__((weak_import)); +extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import)); +extern const char * dlerror(void) __attribute__((weak_import)); +extern int dlclose(void * handle) __attribute__((weak_import)); +extern int dladdr(const void *, Dl_info *) __attribute__((weak_import)); +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */ + +#ifndef DARWIN_HAS_DLOPEN +#define dlopen darwin_dlopen +#define dlsym darwin_dlsym +#define dlerror darwin_dlerror +#define dlclose darwin_dlclose +#define dladdr darwin_dladdr +#endif + +void * (*ctypes_dlopen)(const char *path, int mode); +void * (*ctypes_dlsym)(void * handle, const char *symbol); +const char * (*ctypes_dlerror)(void); +int (*ctypes_dlclose)(void * handle); +int (*ctypes_dladdr)(const void *, Dl_info *); + +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 +/* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */ + +static void *dlsymIntern(void *handle, const char *symbol); + +static const char *error(int setget, const char *str, ...); + +/* Set and get the error string for use by dlerror */ +static const char *error(int setget, const char *str, ...) +{ + static char errstr[ERR_STR_LEN]; + static int err_filled = 0; + const char *retval; + va_list arg; + if (setget == 0) + { + va_start(arg, str); + strncpy(errstr, "dlcompat: ", ERR_STR_LEN); + vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg); + va_end(arg); + err_filled = 1; + retval = NULL; + } + else + { + if (!err_filled) + retval = NULL; + else + retval = errstr; + err_filled = 0; + } + return retval; +} + +/* darwin_dlopen */ +static void *darwin_dlopen(const char *path, int mode) +{ + void *module = 0; + NSObjectFileImage ofi = 0; + NSObjectFileImageReturnCode ofirc; + + /* If we got no path, the app wants the global namespace, use -1 as the marker + in this case */ + if (!path) + return (void *)-1; + + /* Create the object file image, works for things linked with the -bundle arg to ld */ + ofirc = NSCreateObjectFileImageFromFile(path, &ofi); + switch (ofirc) + { + case NSObjectFileImageSuccess: + /* It was okay, so use NSLinkModule to link in the image */ + module = NSLinkModule(ofi, path, + NSLINKMODULE_OPTION_RETURN_ON_ERROR + | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE + | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW); + NSDestroyObjectFileImage(ofi); + break; + case NSObjectFileImageInappropriateFile: + /* It may have been a dynamic library rather than a bundle, try to load it */ + module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); + break; + default: + /* God knows what we got */ + error(0, "Can not open \"%s\"", path); + return 0; + } + if (!module) + error(0, "Can not open \"%s\"", path); + return module; + +} + +/* dlsymIntern is used by dlsym to find the symbol */ +static void *dlsymIntern(void *handle, const char *symbol) +{ + NSSymbol nssym = 0; + /* If the handle is -1, if is the app global context */ + if (handle == (void *)-1) + { + /* Global context, use NSLookupAndBindSymbol */ + if (NSIsSymbolNameDefined(symbol)) + { + nssym = NSLookupAndBindSymbol(symbol); + } + + } + /* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image + for libraries, and NSLookupSymbolInModule for bundles */ + else + { + /* Check for both possible magic numbers depending on x86/ppc byte order */ + if ((((struct mach_header *)handle)->magic == MH_MAGIC) || + (((struct mach_header *)handle)->magic == MH_CIGAM)) + { + if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol)) + { + nssym = NSLookupSymbolInImage((struct mach_header *)handle, + symbol, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + } + + } + else + { + nssym = NSLookupSymbolInModule(handle, symbol); + } + } + if (!nssym) + { + error(0, "Symbol \"%s\" Not found", symbol); + return NULL; + } + return NSAddressOfSymbol(nssym); +} + +static const char *darwin_dlerror(void) +{ + return error(1, (char *)NULL); +} + +static int darwin_dlclose(void *handle) +{ + if ((((struct mach_header *)handle)->magic == MH_MAGIC) || + (((struct mach_header *)handle)->magic == MH_CIGAM)) + { + error(0, "Can't remove dynamic libraries on darwin"); + return 0; + } + if (!NSUnLinkModule(handle, 0)) + { + error(0, "unable to unlink module %s", NSNameOfModule(handle)); + return 1; + } + return 0; +} + + +/* dlsym, prepend the underscore and call dlsymIntern */ +static void *darwin_dlsym(void *handle, const char *symbol) +{ + static char undersym[257]; /* Saves calls to malloc(3) */ + int sym_len = strlen(symbol); + void *value = NULL; + char *malloc_sym = NULL; + + if (sym_len < 256) + { + snprintf(undersym, 256, "_%s", symbol); + value = dlsymIntern(handle, undersym); + } + else + { + malloc_sym = malloc(sym_len + 2); + if (malloc_sym) + { + sprintf(malloc_sym, "_%s", symbol); + value = dlsymIntern(handle, malloc_sym); + free(malloc_sym); + } + else + { + error(0, "Unable to allocate memory"); + } + } + return value; +} + +static int darwin_dladdr(const void *handle, Dl_info *info) { + return 0; +} +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */ + +#if __GNUC__ < 4 +#pragma CALL_ON_LOAD ctypes_dlfcn_init +#else +static void __attribute__ ((constructor)) ctypes_dlfcn_init(void); +static +#endif +void ctypes_dlfcn_init(void) { + if (dlopen != NULL) { + ctypes_dlsym = dlsym; + ctypes_dlopen = dlopen; + ctypes_dlerror = dlerror; + ctypes_dlclose = dlclose; + ctypes_dladdr = dladdr; + } else { +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 + ctypes_dlsym = darwin_dlsym; + ctypes_dlopen = darwin_dlopen; + ctypes_dlerror = darwin_dlerror; + ctypes_dlclose = darwin_dlclose; + ctypes_dladdr = darwin_dladdr; +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */ + } +} + +#endif /* CTYPES_DARWIN_DLFCN */ diff --git a/contrib/tools/python3/src/Modules/_ctypes/stgdict.c b/contrib/tools/python3/src/Modules/_ctypes/stgdict.c index bbef2921e6f..67f743e9ff4 100644 --- a/contrib/tools/python3/src/Modules/_ctypes/stgdict.c +++ b/contrib/tools/python3/src/Modules/_ctypes/stgdict.c @@ -1,369 +1,369 @@ -#include "Python.h" -#include -#ifdef MS_WIN32 -#include -#include -#include -#endif -#include "ctypes.h" - -/******************************************************************/ -/* - StdDict - a dictionary subclass, containing additional C accessible fields - - XXX blabla more -*/ - -/* Seems we need this, otherwise we get problems when calling - * PyDict_SetItem() (ma_lookup is NULL) - */ -static int -PyCStgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) -{ - if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) - return -1; - self->format = NULL; - self->ndim = 0; - self->shape = NULL; - return 0; -} - -static int -PyCStgDict_clear(StgDictObject *self) -{ - Py_CLEAR(self->proto); - Py_CLEAR(self->argtypes); - Py_CLEAR(self->converters); - Py_CLEAR(self->restype); - Py_CLEAR(self->checker); - return 0; -} - -static void -PyCStgDict_dealloc(StgDictObject *self) -{ - PyCStgDict_clear(self); - PyMem_Free(self->format); - PyMem_Free(self->shape); - PyMem_Free(self->ffi_type_pointer.elements); - PyDict_Type.tp_dealloc((PyObject *)self); -} - -static PyObject * -PyCStgDict_sizeof(StgDictObject *self, void *unused) -{ - Py_ssize_t res; - - res = _PyDict_SizeOf((PyDictObject *)self); - res += sizeof(StgDictObject) - sizeof(PyDictObject); - if (self->format) - res += strlen(self->format) + 1; - res += self->ndim * sizeof(Py_ssize_t); - if (self->ffi_type_pointer.elements) - res += (self->length + 1) * sizeof(ffi_type *); - return PyLong_FromSsize_t(res); -} - -int -PyCStgDict_clone(StgDictObject *dst, StgDictObject *src) -{ - char *d, *s; - Py_ssize_t size; - - PyCStgDict_clear(dst); - PyMem_Free(dst->ffi_type_pointer.elements); - PyMem_Free(dst->format); - dst->format = NULL; - PyMem_Free(dst->shape); - dst->shape = NULL; - dst->ffi_type_pointer.elements = NULL; - - d = (char *)dst; - s = (char *)src; - memcpy(d + sizeof(PyDictObject), - s + sizeof(PyDictObject), - sizeof(StgDictObject) - sizeof(PyDictObject)); - - Py_XINCREF(dst->proto); - Py_XINCREF(dst->argtypes); - Py_XINCREF(dst->converters); - Py_XINCREF(dst->restype); - Py_XINCREF(dst->checker); - - if (src->format) { - dst->format = PyMem_Malloc(strlen(src->format) + 1); - if (dst->format == NULL) { - PyErr_NoMemory(); - return -1; - } - strcpy(dst->format, src->format); - } - if (src->shape) { - dst->shape = PyMem_Malloc(sizeof(Py_ssize_t) * src->ndim); - if (dst->shape == NULL) { - PyErr_NoMemory(); - return -1; - } - memcpy(dst->shape, src->shape, - sizeof(Py_ssize_t) * src->ndim); - } - - if (src->ffi_type_pointer.elements == NULL) - return 0; - size = sizeof(ffi_type *) * (src->length + 1); - dst->ffi_type_pointer.elements = PyMem_Malloc(size); - if (dst->ffi_type_pointer.elements == NULL) { - PyErr_NoMemory(); - return -1; - } - memcpy(dst->ffi_type_pointer.elements, - src->ffi_type_pointer.elements, - size); - return 0; -} - -static struct PyMethodDef PyCStgDict_methods[] = { - {"__sizeof__", (PyCFunction)PyCStgDict_sizeof, METH_NOARGS}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyCStgDict_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "StgDict", - sizeof(StgDictObject), - 0, - (destructor)PyCStgDict_dealloc, /* tp_dealloc */ +#include "Python.h" +#include +#ifdef MS_WIN32 +#include +#include +#include +#endif +#include "ctypes.h" + +/******************************************************************/ +/* + StdDict - a dictionary subclass, containing additional C accessible fields + + XXX blabla more +*/ + +/* Seems we need this, otherwise we get problems when calling + * PyDict_SetItem() (ma_lookup is NULL) + */ +static int +PyCStgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) +{ + if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) + return -1; + self->format = NULL; + self->ndim = 0; + self->shape = NULL; + return 0; +} + +static int +PyCStgDict_clear(StgDictObject *self) +{ + Py_CLEAR(self->proto); + Py_CLEAR(self->argtypes); + Py_CLEAR(self->converters); + Py_CLEAR(self->restype); + Py_CLEAR(self->checker); + return 0; +} + +static void +PyCStgDict_dealloc(StgDictObject *self) +{ + PyCStgDict_clear(self); + PyMem_Free(self->format); + PyMem_Free(self->shape); + PyMem_Free(self->ffi_type_pointer.elements); + PyDict_Type.tp_dealloc((PyObject *)self); +} + +static PyObject * +PyCStgDict_sizeof(StgDictObject *self, void *unused) +{ + Py_ssize_t res; + + res = _PyDict_SizeOf((PyDictObject *)self); + res += sizeof(StgDictObject) - sizeof(PyDictObject); + if (self->format) + res += strlen(self->format) + 1; + res += self->ndim * sizeof(Py_ssize_t); + if (self->ffi_type_pointer.elements) + res += (self->length + 1) * sizeof(ffi_type *); + return PyLong_FromSsize_t(res); +} + +int +PyCStgDict_clone(StgDictObject *dst, StgDictObject *src) +{ + char *d, *s; + Py_ssize_t size; + + PyCStgDict_clear(dst); + PyMem_Free(dst->ffi_type_pointer.elements); + PyMem_Free(dst->format); + dst->format = NULL; + PyMem_Free(dst->shape); + dst->shape = NULL; + dst->ffi_type_pointer.elements = NULL; + + d = (char *)dst; + s = (char *)src; + memcpy(d + sizeof(PyDictObject), + s + sizeof(PyDictObject), + sizeof(StgDictObject) - sizeof(PyDictObject)); + + Py_XINCREF(dst->proto); + Py_XINCREF(dst->argtypes); + Py_XINCREF(dst->converters); + Py_XINCREF(dst->restype); + Py_XINCREF(dst->checker); + + if (src->format) { + dst->format = PyMem_Malloc(strlen(src->format) + 1); + if (dst->format == NULL) { + PyErr_NoMemory(); + return -1; + } + strcpy(dst->format, src->format); + } + if (src->shape) { + dst->shape = PyMem_Malloc(sizeof(Py_ssize_t) * src->ndim); + if (dst->shape == NULL) { + PyErr_NoMemory(); + return -1; + } + memcpy(dst->shape, src->shape, + sizeof(Py_ssize_t) * src->ndim); + } + + if (src->ffi_type_pointer.elements == NULL) + return 0; + size = sizeof(ffi_type *) * (src->length + 1); + dst->ffi_type_pointer.elements = PyMem_Malloc(size); + if (dst->ffi_type_pointer.elements == NULL) { + PyErr_NoMemory(); + return -1; + } + memcpy(dst->ffi_type_pointer.elements, + src->ffi_type_pointer.elements, + size); + return 0; +} + +static struct PyMethodDef PyCStgDict_methods[] = { + {"__sizeof__", (PyCFunction)PyCStgDict_sizeof, METH_NOARGS}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyCStgDict_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "StgDict", + sizeof(StgDictObject), + 0, + (destructor)PyCStgDict_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PyCStgDict_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)PyCStgDict_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ -}; - -/* May return NULL, but does not set an exception! */ -StgDictObject * -PyType_stgdict(PyObject *obj) -{ - PyTypeObject *type; - - if (!PyType_Check(obj)) - return NULL; - type = (PyTypeObject *)obj; - if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) - return NULL; - return (StgDictObject *)type->tp_dict; -} - -/* May return NULL, but does not set an exception! */ -/* - This function should be as fast as possible, so we don't call PyType_stgdict - above but inline the code, and avoid the PyType_Check(). -*/ -StgDictObject * -PyObject_stgdict(PyObject *self) -{ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PyCStgDict_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)PyCStgDict_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ +}; + +/* May return NULL, but does not set an exception! */ +StgDictObject * +PyType_stgdict(PyObject *obj) +{ + PyTypeObject *type; + + if (!PyType_Check(obj)) + return NULL; + type = (PyTypeObject *)obj; + if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) + return NULL; + return (StgDictObject *)type->tp_dict; +} + +/* May return NULL, but does not set an exception! */ +/* + This function should be as fast as possible, so we don't call PyType_stgdict + above but inline the code, and avoid the PyType_Check(). +*/ +StgDictObject * +PyObject_stgdict(PyObject *self) +{ PyTypeObject *type = Py_TYPE(self); - if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) - return NULL; - return (StgDictObject *)type->tp_dict; -} - -/* descr is the descriptor for a field marked as anonymous. Get all the - _fields_ descriptors from descr->proto, create new descriptors with offset - and index adjusted, and stuff them into type. - */ -static int -MakeFields(PyObject *type, CFieldObject *descr, - Py_ssize_t index, Py_ssize_t offset) -{ - Py_ssize_t i; - PyObject *fields; - PyObject *fieldlist; - - fields = PyObject_GetAttrString(descr->proto, "_fields_"); - if (fields == NULL) - return -1; - fieldlist = PySequence_Fast(fields, "_fields_ must be a sequence"); - Py_DECREF(fields); - if (fieldlist == NULL) - return -1; - - for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) { - PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */ - PyObject *fname, *ftype, *bits; - CFieldObject *fdescr; - CFieldObject *new_descr; - /* Convert to PyArg_UnpackTuple... */ - if (!PyArg_ParseTuple(pair, "OO|O", &fname, &ftype, &bits)) { - Py_DECREF(fieldlist); - return -1; - } - fdescr = (CFieldObject *)PyObject_GetAttr(descr->proto, fname); - if (fdescr == NULL) { - Py_DECREF(fieldlist); - return -1; - } + if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) + return NULL; + return (StgDictObject *)type->tp_dict; +} + +/* descr is the descriptor for a field marked as anonymous. Get all the + _fields_ descriptors from descr->proto, create new descriptors with offset + and index adjusted, and stuff them into type. + */ +static int +MakeFields(PyObject *type, CFieldObject *descr, + Py_ssize_t index, Py_ssize_t offset) +{ + Py_ssize_t i; + PyObject *fields; + PyObject *fieldlist; + + fields = PyObject_GetAttrString(descr->proto, "_fields_"); + if (fields == NULL) + return -1; + fieldlist = PySequence_Fast(fields, "_fields_ must be a sequence"); + Py_DECREF(fields); + if (fieldlist == NULL) + return -1; + + for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) { + PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */ + PyObject *fname, *ftype, *bits; + CFieldObject *fdescr; + CFieldObject *new_descr; + /* Convert to PyArg_UnpackTuple... */ + if (!PyArg_ParseTuple(pair, "OO|O", &fname, &ftype, &bits)) { + Py_DECREF(fieldlist); + return -1; + } + fdescr = (CFieldObject *)PyObject_GetAttr(descr->proto, fname); + if (fdescr == NULL) { + Py_DECREF(fieldlist); + return -1; + } if (!Py_IS_TYPE(fdescr, &PyCField_Type)) { - PyErr_SetString(PyExc_TypeError, "unexpected type"); - Py_DECREF(fdescr); - Py_DECREF(fieldlist); - return -1; - } - if (fdescr->anonymous) { - int rc = MakeFields(type, fdescr, - index + fdescr->index, - offset + fdescr->offset); - Py_DECREF(fdescr); - if (rc == -1) { - Py_DECREF(fieldlist); - return -1; - } - continue; - } - new_descr = (CFieldObject *)_PyObject_CallNoArg((PyObject *)&PyCField_Type); - if (new_descr == NULL) { - Py_DECREF(fdescr); - Py_DECREF(fieldlist); - return -1; - } + PyErr_SetString(PyExc_TypeError, "unexpected type"); + Py_DECREF(fdescr); + Py_DECREF(fieldlist); + return -1; + } + if (fdescr->anonymous) { + int rc = MakeFields(type, fdescr, + index + fdescr->index, + offset + fdescr->offset); + Py_DECREF(fdescr); + if (rc == -1) { + Py_DECREF(fieldlist); + return -1; + } + continue; + } + new_descr = (CFieldObject *)_PyObject_CallNoArg((PyObject *)&PyCField_Type); + if (new_descr == NULL) { + Py_DECREF(fdescr); + Py_DECREF(fieldlist); + return -1; + } assert(Py_IS_TYPE(new_descr, &PyCField_Type)); - new_descr->size = fdescr->size; - new_descr->offset = fdescr->offset + offset; - new_descr->index = fdescr->index + index; - new_descr->proto = fdescr->proto; - Py_XINCREF(new_descr->proto); - new_descr->getfunc = fdescr->getfunc; - new_descr->setfunc = fdescr->setfunc; - - Py_DECREF(fdescr); - - if (-1 == PyObject_SetAttr(type, fname, (PyObject *)new_descr)) { - Py_DECREF(fieldlist); - Py_DECREF(new_descr); - return -1; - } - Py_DECREF(new_descr); - } - Py_DECREF(fieldlist); - return 0; -} - -/* Iterate over the names in the type's _anonymous_ attribute, if present, - */ -static int -MakeAnonFields(PyObject *type) -{ + new_descr->size = fdescr->size; + new_descr->offset = fdescr->offset + offset; + new_descr->index = fdescr->index + index; + new_descr->proto = fdescr->proto; + Py_XINCREF(new_descr->proto); + new_descr->getfunc = fdescr->getfunc; + new_descr->setfunc = fdescr->setfunc; + + Py_DECREF(fdescr); + + if (-1 == PyObject_SetAttr(type, fname, (PyObject *)new_descr)) { + Py_DECREF(fieldlist); + Py_DECREF(new_descr); + return -1; + } + Py_DECREF(new_descr); + } + Py_DECREF(fieldlist); + return 0; +} + +/* Iterate over the names in the type's _anonymous_ attribute, if present, + */ +static int +MakeAnonFields(PyObject *type) +{ _Py_IDENTIFIER(_anonymous_); - PyObject *anon; - PyObject *anon_names; - Py_ssize_t i; - + PyObject *anon; + PyObject *anon_names; + Py_ssize_t i; + if (_PyObject_LookupAttrId(type, &PyId__anonymous_, &anon) < 0) { return -1; } - if (anon == NULL) { - return 0; - } - anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence"); - Py_DECREF(anon); - if (anon_names == NULL) - return -1; - - for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) { - PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */ - CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname); - if (descr == NULL) { - Py_DECREF(anon_names); - return -1; - } + if (anon == NULL) { + return 0; + } + anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence"); + Py_DECREF(anon); + if (anon_names == NULL) + return -1; + + for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) { + PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */ + CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname); + if (descr == NULL) { + Py_DECREF(anon_names); + return -1; + } if (!Py_IS_TYPE(descr, &PyCField_Type)) { - PyErr_Format(PyExc_AttributeError, - "'%U' is specified in _anonymous_ but not in " - "_fields_", - fname); - Py_DECREF(anon_names); - Py_DECREF(descr); - return -1; - } - descr->anonymous = 1; - - /* descr is in the field descriptor. */ - if (-1 == MakeFields(type, (CFieldObject *)descr, - ((CFieldObject *)descr)->index, - ((CFieldObject *)descr)->offset)) { - Py_DECREF(descr); - Py_DECREF(anon_names); - return -1; - } - Py_DECREF(descr); - } - - Py_DECREF(anon_names); - return 0; -} - -/* - Retrieve the (optional) _pack_ attribute from a type, the _fields_ attribute, - and create an StgDictObject. Used for Structure and Union subclasses. -*/ -int -PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) -{ + PyErr_Format(PyExc_AttributeError, + "'%U' is specified in _anonymous_ but not in " + "_fields_", + fname); + Py_DECREF(anon_names); + Py_DECREF(descr); + return -1; + } + descr->anonymous = 1; + + /* descr is in the field descriptor. */ + if (-1 == MakeFields(type, (CFieldObject *)descr, + ((CFieldObject *)descr)->index, + ((CFieldObject *)descr)->offset)) { + Py_DECREF(descr); + Py_DECREF(anon_names); + return -1; + } + Py_DECREF(descr); + } + + Py_DECREF(anon_names); + return 0; +} + +/* + Retrieve the (optional) _pack_ attribute from a type, the _fields_ attribute, + and create an StgDictObject. Used for Structure and Union subclasses. +*/ +int +PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) +{ _Py_IDENTIFIER(_swappedbytes_); _Py_IDENTIFIER(_use_broken_old_ctypes_structure_semantics_); _Py_IDENTIFIER(_pack_); - StgDictObject *stgdict, *basedict; - Py_ssize_t len, offset, size, align, i; - Py_ssize_t union_size, total_align; - Py_ssize_t field_size = 0; - int bitofs; + StgDictObject *stgdict, *basedict; + Py_ssize_t len, offset, size, align, i; + Py_ssize_t union_size, total_align; + Py_ssize_t field_size = 0; + int bitofs; PyObject *tmp; int isPacked; int pack; - Py_ssize_t ffi_ofs; - int big_endian; + Py_ssize_t ffi_ofs; + int big_endian; int arrays_seen = 0; - - /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to + + /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to be a way to use the old, broken semantics: _fields_ are not extended - but replaced in subclasses. - - XXX Remove this in ctypes 1.0! - */ - int use_broken_old_ctypes_semantics; - - if (fields == NULL) - return 0; - + but replaced in subclasses. + + XXX Remove this in ctypes 1.0! + */ + int use_broken_old_ctypes_semantics; + + if (fields == NULL) + return 0; + if (_PyObject_LookupAttrId(type, &PyId__swappedbytes_, &tmp) < 0) { return -1; } @@ -374,7 +374,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct else { big_endian = PY_BIG_ENDIAN; } - + if (_PyObject_LookupAttrId(type, &PyId__use_broken_old_ctypes_structure_semantics_, &tmp) < 0) { @@ -387,7 +387,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct else { use_broken_old_ctypes_semantics = 0; } - + if (_PyObject_LookupAttrId(type, &PyId__pack_, &tmp) < 0) { return -1; } @@ -403,44 +403,44 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct PyErr_SetString(PyExc_ValueError, "_pack_ must be a non-negative integer"); } - return -1; - } + return -1; + } } else { isPacked = 0; pack = 0; } - + len = PySequence_Size(fields); - if (len == -1) { + if (len == -1) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_SetString(PyExc_TypeError, "'_fields_' must be a sequence of pairs"); } - return -1; - } - - stgdict = PyType_stgdict(type); - if (!stgdict) - return -1; - /* If this structure/union is already marked final we cannot assign - _fields_ anymore. */ - - if (stgdict->flags & DICTFLAG_FINAL) {/* is final ? */ - PyErr_SetString(PyExc_AttributeError, - "_fields_ is final"); - return -1; - } - - if (stgdict->format) { - PyMem_Free(stgdict->format); - stgdict->format = NULL; - } - - if (stgdict->ffi_type_pointer.elements) - PyMem_Free(stgdict->ffi_type_pointer.elements); - - basedict = PyType_stgdict((PyObject *)((PyTypeObject *)type)->tp_base); + return -1; + } + + stgdict = PyType_stgdict(type); + if (!stgdict) + return -1; + /* If this structure/union is already marked final we cannot assign + _fields_ anymore. */ + + if (stgdict->flags & DICTFLAG_FINAL) {/* is final ? */ + PyErr_SetString(PyExc_AttributeError, + "_fields_ is final"); + return -1; + } + + if (stgdict->format) { + PyMem_Free(stgdict->format); + stgdict->format = NULL; + } + + if (stgdict->ffi_type_pointer.elements) + PyMem_Free(stgdict->ffi_type_pointer.elements); + + basedict = PyType_stgdict((PyObject *)((PyTypeObject *)type)->tp_base); if (basedict) { stgdict->flags |= (basedict->flags & (TYPEFLAG_HASUNION | TYPEFLAG_HASBITFIELD)); @@ -448,212 +448,212 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct if (!isStruct) { stgdict->flags |= TYPEFLAG_HASUNION; } - if (basedict && !use_broken_old_ctypes_semantics) { - size = offset = basedict->size; - align = basedict->align; - union_size = 0; - total_align = align ? align : 1; - stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; - stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, basedict->length + len + 1); - if (stgdict->ffi_type_pointer.elements == NULL) { - PyErr_NoMemory(); - return -1; - } - memset(stgdict->ffi_type_pointer.elements, 0, - sizeof(ffi_type *) * (basedict->length + len + 1)); - if (basedict->length > 0) { - memcpy(stgdict->ffi_type_pointer.elements, - basedict->ffi_type_pointer.elements, - sizeof(ffi_type *) * (basedict->length)); - } - ffi_ofs = basedict->length; - } else { - offset = 0; - size = 0; - align = 0; - union_size = 0; - total_align = 1; - stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; - stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, len + 1); - if (stgdict->ffi_type_pointer.elements == NULL) { - PyErr_NoMemory(); - return -1; - } - memset(stgdict->ffi_type_pointer.elements, 0, - sizeof(ffi_type *) * (len + 1)); - ffi_ofs = 0; - } - - assert(stgdict->format == NULL); - if (isStruct && !isPacked) { - stgdict->format = _ctypes_alloc_format_string(NULL, "T{"); - } else { - /* PEP3118 doesn't support union, or packed structures (well, - only standard packing, but we don't support the pep for - that). Use 'B' for bytes. */ - stgdict->format = _ctypes_alloc_format_string(NULL, "B"); - } - if (stgdict->format == NULL) - return -1; - -#define realdict ((PyObject *)&stgdict->dict) - for (i = 0; i < len; ++i) { - PyObject *name = NULL, *desc = NULL; - PyObject *pair = PySequence_GetItem(fields, i); - PyObject *prop; - StgDictObject *dict; - int bitsize = 0; - - if (!pair || !PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) { - PyErr_SetString(PyExc_TypeError, - "'_fields_' must be a sequence of (name, C type) pairs"); - Py_XDECREF(pair); - return -1; - } + if (basedict && !use_broken_old_ctypes_semantics) { + size = offset = basedict->size; + align = basedict->align; + union_size = 0; + total_align = align ? align : 1; + stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; + stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, basedict->length + len + 1); + if (stgdict->ffi_type_pointer.elements == NULL) { + PyErr_NoMemory(); + return -1; + } + memset(stgdict->ffi_type_pointer.elements, 0, + sizeof(ffi_type *) * (basedict->length + len + 1)); + if (basedict->length > 0) { + memcpy(stgdict->ffi_type_pointer.elements, + basedict->ffi_type_pointer.elements, + sizeof(ffi_type *) * (basedict->length)); + } + ffi_ofs = basedict->length; + } else { + offset = 0; + size = 0; + align = 0; + union_size = 0; + total_align = 1; + stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; + stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, len + 1); + if (stgdict->ffi_type_pointer.elements == NULL) { + PyErr_NoMemory(); + return -1; + } + memset(stgdict->ffi_type_pointer.elements, 0, + sizeof(ffi_type *) * (len + 1)); + ffi_ofs = 0; + } + + assert(stgdict->format == NULL); + if (isStruct && !isPacked) { + stgdict->format = _ctypes_alloc_format_string(NULL, "T{"); + } else { + /* PEP3118 doesn't support union, or packed structures (well, + only standard packing, but we don't support the pep for + that). Use 'B' for bytes. */ + stgdict->format = _ctypes_alloc_format_string(NULL, "B"); + } + if (stgdict->format == NULL) + return -1; + +#define realdict ((PyObject *)&stgdict->dict) + for (i = 0; i < len; ++i) { + PyObject *name = NULL, *desc = NULL; + PyObject *pair = PySequence_GetItem(fields, i); + PyObject *prop; + StgDictObject *dict; + int bitsize = 0; + + if (!pair || !PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) { + PyErr_SetString(PyExc_TypeError, + "'_fields_' must be a sequence of (name, C type) pairs"); + Py_XDECREF(pair); + return -1; + } if (PyCArrayTypeObject_Check(desc)) arrays_seen = 1; - dict = PyType_stgdict(desc); - if (dict == NULL) { - Py_DECREF(pair); - PyErr_Format(PyExc_TypeError, - "second item in _fields_ tuple (index %zd) must be a C type", - i); - return -1; - } - stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer; - if (dict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) - stgdict->flags |= TYPEFLAG_HASPOINTER; + dict = PyType_stgdict(desc); + if (dict == NULL) { + Py_DECREF(pair); + PyErr_Format(PyExc_TypeError, + "second item in _fields_ tuple (index %zd) must be a C type", + i); + return -1; + } + stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer; + if (dict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) + stgdict->flags |= TYPEFLAG_HASPOINTER; stgdict->flags |= dict->flags & (TYPEFLAG_HASUNION | TYPEFLAG_HASBITFIELD); - dict->flags |= DICTFLAG_FINAL; /* mark field type final */ - if (PyTuple_Size(pair) == 3) { /* bits specified */ + dict->flags |= DICTFLAG_FINAL; /* mark field type final */ + if (PyTuple_Size(pair) == 3) { /* bits specified */ stgdict->flags |= TYPEFLAG_HASBITFIELD; - switch(dict->ffi_type_pointer.type) { - case FFI_TYPE_UINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - break; - - case FFI_TYPE_SINT8: - case FFI_TYPE_SINT16: - case FFI_TYPE_SINT32: - if (dict->getfunc != _ctypes_get_fielddesc("c")->getfunc -#ifdef CTYPES_UNICODE - && dict->getfunc != _ctypes_get_fielddesc("u")->getfunc -#endif - ) - break; - /* else fall through */ - default: - PyErr_Format(PyExc_TypeError, - "bit fields not allowed for type %s", - ((PyTypeObject *)desc)->tp_name); - Py_DECREF(pair); - return -1; - } - if (bitsize <= 0 || bitsize > dict->size * 8) { - PyErr_SetString(PyExc_ValueError, - "number of bits invalid for bit field"); - Py_DECREF(pair); - return -1; - } - } else - bitsize = 0; - - if (isStruct && !isPacked) { - const char *fieldfmt = dict->format ? dict->format : "B"; - const char *fieldname = PyUnicode_AsUTF8(name); - char *ptr; - Py_ssize_t len; - char *buf; - - if (fieldname == NULL) - { - Py_DECREF(pair); - return -1; - } - - len = strlen(fieldname) + strlen(fieldfmt); - - buf = PyMem_Malloc(len + 2 + 1); - if (buf == NULL) { - Py_DECREF(pair); - PyErr_NoMemory(); - return -1; - } - sprintf(buf, "%s:%s:", fieldfmt, fieldname); - - ptr = stgdict->format; - if (dict->shape != NULL) { - stgdict->format = _ctypes_alloc_format_string_with_shape( - dict->ndim, dict->shape, stgdict->format, buf); - } else { - stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); - } - PyMem_Free(ptr); - PyMem_Free(buf); - - if (stgdict->format == NULL) { - Py_DECREF(pair); - return -1; - } - } - - if (isStruct) { - prop = PyCField_FromDesc(desc, i, - &field_size, bitsize, &bitofs, - &size, &offset, &align, - pack, big_endian); - } else /* union */ { - size = 0; - offset = 0; - align = 0; - prop = PyCField_FromDesc(desc, i, - &field_size, bitsize, &bitofs, - &size, &offset, &align, - pack, big_endian); - union_size = max(size, union_size); - } - total_align = max(align, total_align); - - if (!prop) { - Py_DECREF(pair); - return -1; - } - if (-1 == PyObject_SetAttr(type, name, prop)) { - Py_DECREF(prop); - Py_DECREF(pair); - return -1; - } - Py_DECREF(pair); - Py_DECREF(prop); - } -#undef realdict - - if (isStruct && !isPacked) { - char *ptr = stgdict->format; - stgdict->format = _ctypes_alloc_format_string(stgdict->format, "}"); - PyMem_Free(ptr); - if (stgdict->format == NULL) - return -1; - } - - if (!isStruct) - size = union_size; - - /* Adjust the size according to the alignment requirements */ - size = ((size + total_align - 1) / total_align) * total_align; - - stgdict->ffi_type_pointer.alignment = Py_SAFE_DOWNCAST(total_align, - Py_ssize_t, - unsigned short); - stgdict->ffi_type_pointer.size = size; - - stgdict->size = size; - stgdict->align = total_align; - stgdict->length = len; /* ADD ffi_ofs? */ - + switch(dict->ffi_type_pointer.type) { + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + break; + + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_SINT32: + if (dict->getfunc != _ctypes_get_fielddesc("c")->getfunc +#ifdef CTYPES_UNICODE + && dict->getfunc != _ctypes_get_fielddesc("u")->getfunc +#endif + ) + break; + /* else fall through */ + default: + PyErr_Format(PyExc_TypeError, + "bit fields not allowed for type %s", + ((PyTypeObject *)desc)->tp_name); + Py_DECREF(pair); + return -1; + } + if (bitsize <= 0 || bitsize > dict->size * 8) { + PyErr_SetString(PyExc_ValueError, + "number of bits invalid for bit field"); + Py_DECREF(pair); + return -1; + } + } else + bitsize = 0; + + if (isStruct && !isPacked) { + const char *fieldfmt = dict->format ? dict->format : "B"; + const char *fieldname = PyUnicode_AsUTF8(name); + char *ptr; + Py_ssize_t len; + char *buf; + + if (fieldname == NULL) + { + Py_DECREF(pair); + return -1; + } + + len = strlen(fieldname) + strlen(fieldfmt); + + buf = PyMem_Malloc(len + 2 + 1); + if (buf == NULL) { + Py_DECREF(pair); + PyErr_NoMemory(); + return -1; + } + sprintf(buf, "%s:%s:", fieldfmt, fieldname); + + ptr = stgdict->format; + if (dict->shape != NULL) { + stgdict->format = _ctypes_alloc_format_string_with_shape( + dict->ndim, dict->shape, stgdict->format, buf); + } else { + stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); + } + PyMem_Free(ptr); + PyMem_Free(buf); + + if (stgdict->format == NULL) { + Py_DECREF(pair); + return -1; + } + } + + if (isStruct) { + prop = PyCField_FromDesc(desc, i, + &field_size, bitsize, &bitofs, + &size, &offset, &align, + pack, big_endian); + } else /* union */ { + size = 0; + offset = 0; + align = 0; + prop = PyCField_FromDesc(desc, i, + &field_size, bitsize, &bitofs, + &size, &offset, &align, + pack, big_endian); + union_size = max(size, union_size); + } + total_align = max(align, total_align); + + if (!prop) { + Py_DECREF(pair); + return -1; + } + if (-1 == PyObject_SetAttr(type, name, prop)) { + Py_DECREF(prop); + Py_DECREF(pair); + return -1; + } + Py_DECREF(pair); + Py_DECREF(prop); + } +#undef realdict + + if (isStruct && !isPacked) { + char *ptr = stgdict->format; + stgdict->format = _ctypes_alloc_format_string(stgdict->format, "}"); + PyMem_Free(ptr); + if (stgdict->format == NULL) + return -1; + } + + if (!isStruct) + size = union_size; + + /* Adjust the size according to the alignment requirements */ + size = ((size + total_align - 1) / total_align) * total_align; + + stgdict->ffi_type_pointer.alignment = Py_SAFE_DOWNCAST(total_align, + Py_ssize_t, + unsigned short); + stgdict->ffi_type_pointer.size = size; + + stgdict->size = size; + stgdict->align = total_align; + stgdict->length = len; /* ADD ffi_ofs? */ + #define MAX_STRUCT_SIZE 16 if (arrays_seen && (size <= MAX_STRUCT_SIZE)) { @@ -888,14 +888,14 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct stgdict->ffi_type_pointer.elements = element_types; } - /* We did check that this flag was NOT set above, it must not - have been set until now. */ - if (stgdict->flags & DICTFLAG_FINAL) { - PyErr_SetString(PyExc_AttributeError, - "Structure or union cannot contain itself"); - return -1; - } - stgdict->flags |= DICTFLAG_FINAL; - - return MakeAnonFields(type); -} + /* We did check that this flag was NOT set above, it must not + have been set until now. */ + if (stgdict->flags & DICTFLAG_FINAL) { + PyErr_SetString(PyExc_AttributeError, + "Structure or union cannot contain itself"); + return -1; + } + stgdict->flags |= DICTFLAG_FINAL; + + return MakeAnonFields(type); +} diff --git a/contrib/tools/python3/src/Modules/_datetimemodule.c b/contrib/tools/python3/src/Modules/_datetimemodule.c index 96023754056..f010a08a5d1 100644 --- a/contrib/tools/python3/src/Modules/_datetimemodule.c +++ b/contrib/tools/python3/src/Modules/_datetimemodule.c @@ -1,25 +1,25 @@ -/* C implementation for the date/time type documented at - * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage - */ - +/* C implementation for the date/time type documented at + * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage + */ + /* bpo-35081: Defining this prevents including the C API capsule; * internal versions of the Py*_Check macros which do not require * the capsule are defined below */ #define _PY_DATETIME_IMPL -#include "Python.h" +#include "Python.h" #include "datetime.h" #include "structmember.h" // PyMemberDef - -#include - -#ifdef MS_WINDOWS -# include /* struct timeval */ -#endif - + +#include + +#ifdef MS_WINDOWS +# include /* struct timeval */ +#endif + #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) #define PyDate_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateType) - + #define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) #define PyDateTime_CheckExact(op) Py_IS_TYPE(op, &PyDateTime_DateTimeType) @@ -34,6501 +34,6501 @@ #define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType) -/*[clinic input] -module datetime -class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" +/*[clinic input] +module datetime +class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" class datetime.date "PyDateTime_Date *" "&PyDateTime_DateType" class datetime.IsoCalendarDate "PyDateTime_IsoCalendarDate *" "&PyDateTime_IsoCalendarDateType" -[clinic start generated code]*/ +[clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81bec0fa19837f63]*/ - -#include "clinic/_datetimemodule.c.h" - -/* We require that C int be at least 32 bits, and use int virtually - * everywhere. In just a few cases we use a temp long, where a Python - * API returns a C long. In such cases, we have to ensure that the - * final result fits in a C int (this can be an issue on 64-bit boxes). - */ -#if SIZEOF_INT < 4 -# error "_datetime.c requires that C int have at least 32 bits" -#endif - -#define MINYEAR 1 -#define MAXYEAR 9999 -#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */ - -/* Nine decimal digits is easy to communicate, and leaves enough room - * so that two delta days can be added w/o fear of overflowing a signed - * 32-bit int, and with plenty of room left over to absorb any possible - * carries from adding seconds. - */ -#define MAX_DELTA_DAYS 999999999 - -/* Rename the long macros in datetime.h to more reasonable short names. */ -#define GET_YEAR PyDateTime_GET_YEAR -#define GET_MONTH PyDateTime_GET_MONTH -#define GET_DAY PyDateTime_GET_DAY -#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR -#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE -#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND -#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND -#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD - -/* Date accessors for date and datetime. */ -#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \ - ((o)->data[1] = ((v) & 0x00ff))) -#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v)) -#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v)) - -/* Date/Time accessors for datetime. */ -#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v)) -#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v)) -#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v)) -#define DATE_SET_MICROSECOND(o, v) \ - (((o)->data[7] = ((v) & 0xff0000) >> 16), \ - ((o)->data[8] = ((v) & 0x00ff00) >> 8), \ - ((o)->data[9] = ((v) & 0x0000ff))) -#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v)) - -/* Time accessors for time. */ -#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR -#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE -#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND -#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND -#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD -#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v)) -#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v)) -#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v)) -#define TIME_SET_MICROSECOND(o, v) \ - (((o)->data[3] = ((v) & 0xff0000) >> 16), \ - ((o)->data[4] = ((v) & 0x00ff00) >> 8), \ - ((o)->data[5] = ((v) & 0x0000ff))) -#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v)) - -/* Delta accessors for timedelta. */ -#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days) -#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds) -#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds) - -#define SET_TD_DAYS(o, v) ((o)->days = (v)) -#define SET_TD_SECONDS(o, v) ((o)->seconds = (v)) -#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v)) - -/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns - * p->hastzinfo. - */ -#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo) -#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \ - ((PyDateTime_Time *)(p))->tzinfo : Py_None) -#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \ - ((PyDateTime_DateTime *)(p))->tzinfo : Py_None) -/* M is a char or int claiming to be a valid month. The macro is equivalent - * to the two-sided Python test - * 1 <= M <= 12 - */ -#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12) - -/* Forward declarations. */ -static PyTypeObject PyDateTime_DateType; -static PyTypeObject PyDateTime_DateTimeType; -static PyTypeObject PyDateTime_DeltaType; + +#include "clinic/_datetimemodule.c.h" + +/* We require that C int be at least 32 bits, and use int virtually + * everywhere. In just a few cases we use a temp long, where a Python + * API returns a C long. In such cases, we have to ensure that the + * final result fits in a C int (this can be an issue on 64-bit boxes). + */ +#if SIZEOF_INT < 4 +# error "_datetime.c requires that C int have at least 32 bits" +#endif + +#define MINYEAR 1 +#define MAXYEAR 9999 +#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */ + +/* Nine decimal digits is easy to communicate, and leaves enough room + * so that two delta days can be added w/o fear of overflowing a signed + * 32-bit int, and with plenty of room left over to absorb any possible + * carries from adding seconds. + */ +#define MAX_DELTA_DAYS 999999999 + +/* Rename the long macros in datetime.h to more reasonable short names. */ +#define GET_YEAR PyDateTime_GET_YEAR +#define GET_MONTH PyDateTime_GET_MONTH +#define GET_DAY PyDateTime_GET_DAY +#define DATE_GET_HOUR PyDateTime_DATE_GET_HOUR +#define DATE_GET_MINUTE PyDateTime_DATE_GET_MINUTE +#define DATE_GET_SECOND PyDateTime_DATE_GET_SECOND +#define DATE_GET_MICROSECOND PyDateTime_DATE_GET_MICROSECOND +#define DATE_GET_FOLD PyDateTime_DATE_GET_FOLD + +/* Date accessors for date and datetime. */ +#define SET_YEAR(o, v) (((o)->data[0] = ((v) & 0xff00) >> 8), \ + ((o)->data[1] = ((v) & 0x00ff))) +#define SET_MONTH(o, v) (PyDateTime_GET_MONTH(o) = (v)) +#define SET_DAY(o, v) (PyDateTime_GET_DAY(o) = (v)) + +/* Date/Time accessors for datetime. */ +#define DATE_SET_HOUR(o, v) (PyDateTime_DATE_GET_HOUR(o) = (v)) +#define DATE_SET_MINUTE(o, v) (PyDateTime_DATE_GET_MINUTE(o) = (v)) +#define DATE_SET_SECOND(o, v) (PyDateTime_DATE_GET_SECOND(o) = (v)) +#define DATE_SET_MICROSECOND(o, v) \ + (((o)->data[7] = ((v) & 0xff0000) >> 16), \ + ((o)->data[8] = ((v) & 0x00ff00) >> 8), \ + ((o)->data[9] = ((v) & 0x0000ff))) +#define DATE_SET_FOLD(o, v) (PyDateTime_DATE_GET_FOLD(o) = (v)) + +/* Time accessors for time. */ +#define TIME_GET_HOUR PyDateTime_TIME_GET_HOUR +#define TIME_GET_MINUTE PyDateTime_TIME_GET_MINUTE +#define TIME_GET_SECOND PyDateTime_TIME_GET_SECOND +#define TIME_GET_MICROSECOND PyDateTime_TIME_GET_MICROSECOND +#define TIME_GET_FOLD PyDateTime_TIME_GET_FOLD +#define TIME_SET_HOUR(o, v) (PyDateTime_TIME_GET_HOUR(o) = (v)) +#define TIME_SET_MINUTE(o, v) (PyDateTime_TIME_GET_MINUTE(o) = (v)) +#define TIME_SET_SECOND(o, v) (PyDateTime_TIME_GET_SECOND(o) = (v)) +#define TIME_SET_MICROSECOND(o, v) \ + (((o)->data[3] = ((v) & 0xff0000) >> 16), \ + ((o)->data[4] = ((v) & 0x00ff00) >> 8), \ + ((o)->data[5] = ((v) & 0x0000ff))) +#define TIME_SET_FOLD(o, v) (PyDateTime_TIME_GET_FOLD(o) = (v)) + +/* Delta accessors for timedelta. */ +#define GET_TD_DAYS(o) (((PyDateTime_Delta *)(o))->days) +#define GET_TD_SECONDS(o) (((PyDateTime_Delta *)(o))->seconds) +#define GET_TD_MICROSECONDS(o) (((PyDateTime_Delta *)(o))->microseconds) + +#define SET_TD_DAYS(o, v) ((o)->days = (v)) +#define SET_TD_SECONDS(o, v) ((o)->seconds = (v)) +#define SET_TD_MICROSECONDS(o, v) ((o)->microseconds = (v)) + +/* p is a pointer to a time or a datetime object; HASTZINFO(p) returns + * p->hastzinfo. + */ +#define HASTZINFO(p) (((_PyDateTime_BaseTZInfo *)(p))->hastzinfo) +#define GET_TIME_TZINFO(p) (HASTZINFO(p) ? \ + ((PyDateTime_Time *)(p))->tzinfo : Py_None) +#define GET_DT_TZINFO(p) (HASTZINFO(p) ? \ + ((PyDateTime_DateTime *)(p))->tzinfo : Py_None) +/* M is a char or int claiming to be a valid month. The macro is equivalent + * to the two-sided Python test + * 1 <= M <= 12 + */ +#define MONTH_IS_SANE(M) ((unsigned int)(M) - 1 < 12) + +/* Forward declarations. */ +static PyTypeObject PyDateTime_DateType; +static PyTypeObject PyDateTime_DateTimeType; +static PyTypeObject PyDateTime_DeltaType; static PyTypeObject PyDateTime_IsoCalendarDateType; -static PyTypeObject PyDateTime_TimeType; -static PyTypeObject PyDateTime_TZInfoType; -static PyTypeObject PyDateTime_TimeZoneType; - -static int check_tzinfo_subclass(PyObject *p); - -_Py_IDENTIFIER(as_integer_ratio); -_Py_IDENTIFIER(fromutc); -_Py_IDENTIFIER(isoformat); -_Py_IDENTIFIER(strftime); +static PyTypeObject PyDateTime_TimeType; +static PyTypeObject PyDateTime_TZInfoType; +static PyTypeObject PyDateTime_TimeZoneType; + +static int check_tzinfo_subclass(PyObject *p); + +_Py_IDENTIFIER(as_integer_ratio); +_Py_IDENTIFIER(fromutc); +_Py_IDENTIFIER(isoformat); +_Py_IDENTIFIER(strftime); + +/* --------------------------------------------------------------------------- + * Math utilities. + */ + +/* k = i+j overflows iff k differs in sign from both inputs, + * iff k^i has sign bit set and k^j has sign bit set, + * iff (k^i)&(k^j) has sign bit set. + */ +#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \ + ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0) + +/* Compute Python divmod(x, y), returning the quotient and storing the + * remainder into *r. The quotient is the floor of x/y, and that's + * the real point of this. C will probably truncate instead (C99 + * requires truncation; C89 left it implementation-defined). + * Simplification: we *require* that y > 0 here. That's appropriate + * for all the uses made of it. This simplifies the code and makes + * the overflow case impossible (divmod(LONG_MIN, -1) is the only + * overflow case). + */ +static int +divmod(int x, int y, int *r) +{ + int quo; + + assert(y > 0); + quo = x / y; + *r = x - quo * y; + if (*r < 0) { + --quo; + *r += y; + } + assert(0 <= *r && *r < y); + return quo; +} + +/* Nearest integer to m / n for integers m and n. Half-integer results + * are rounded to even. + */ +static PyObject * +divide_nearest(PyObject *m, PyObject *n) +{ + PyObject *result; + PyObject *temp; + + temp = _PyLong_DivmodNear(m, n); + if (temp == NULL) + return NULL; + result = PyTuple_GET_ITEM(temp, 0); + Py_INCREF(result); + Py_DECREF(temp); + + return result; +} + +/* --------------------------------------------------------------------------- + * General calendrical helper functions + */ + +/* For each month ordinal in 1..12, the number of days in that month, + * and the number of days before that month in the same year. These + * are correct for non-leap years only. + */ +static const int _days_in_month[] = { + 0, /* unused; this vector uses 1-based indexing */ + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +static const int _days_before_month[] = { + 0, /* unused; this vector uses 1-based indexing */ + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 +}; + +/* year -> 1 if leap year, else 0. */ +static int +is_leap(int year) +{ + /* Cast year to unsigned. The result is the same either way, but + * C can generate faster code for unsigned mod than for signed + * mod (especially for % 4 -- a good compiler should just grab + * the last 2 bits when the LHS is unsigned). + */ + const unsigned int ayear = (unsigned int)year; + return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0); +} + +/* year, month -> number of days in that month in that year */ +static int +days_in_month(int year, int month) +{ + assert(month >= 1); + assert(month <= 12); + if (month == 2 && is_leap(year)) + return 29; + else + return _days_in_month[month]; +} + +/* year, month -> number of days in year preceding first day of month */ +static int +days_before_month(int year, int month) +{ + int days; + + assert(month >= 1); + assert(month <= 12); + days = _days_before_month[month]; + if (month > 2 && is_leap(year)) + ++days; + return days; +} + +/* year -> number of days before January 1st of year. Remember that we + * start with year 1, so days_before_year(1) == 0. + */ +static int +days_before_year(int year) +{ + int y = year - 1; + /* This is incorrect if year <= 0; we really want the floor + * here. But so long as MINYEAR is 1, the smallest year this + * can see is 1. + */ + assert (year >= 1); + return y*365 + y/4 - y/100 + y/400; +} + +/* Number of days in 4, 100, and 400 year cycles. That these have + * the correct values is asserted in the module init function. + */ +#define DI4Y 1461 /* days_before_year(5); days in 4 years */ +#define DI100Y 36524 /* days_before_year(101); days in 100 years */ +#define DI400Y 146097 /* days_before_year(401); days in 400 years */ + +/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */ +static void +ord_to_ymd(int ordinal, int *year, int *month, int *day) +{ + int n, n1, n4, n100, n400, leapyear, preceding; + + /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of + * leap years repeats exactly every 400 years. The basic strategy is + * to find the closest 400-year boundary at or before ordinal, then + * work with the offset from that boundary to ordinal. Life is much + * clearer if we subtract 1 from ordinal first -- then the values + * of ordinal at 400-year boundaries are exactly those divisible + * by DI400Y: + * + * D M Y n n-1 + * -- --- ---- ---------- ---------------- + * 31 Dec -400 -DI400Y -DI400Y -1 + * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary + * ... + * 30 Dec 000 -1 -2 + * 31 Dec 000 0 -1 + * 1 Jan 001 1 0 400-year boundary + * 2 Jan 001 2 1 + * 3 Jan 001 3 2 + * ... + * 31 Dec 400 DI400Y DI400Y -1 + * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary + */ + assert(ordinal >= 1); + --ordinal; + n400 = ordinal / DI400Y; + n = ordinal % DI400Y; + *year = n400 * 400 + 1; + + /* Now n is the (non-negative) offset, in days, from January 1 of + * year, to the desired date. Now compute how many 100-year cycles + * precede n. + * Note that it's possible for n100 to equal 4! In that case 4 full + * 100-year cycles precede the desired day, which implies the + * desired day is December 31 at the end of a 400-year cycle. + */ + n100 = n / DI100Y; + n = n % DI100Y; + + /* Now compute how many 4-year cycles precede it. */ + n4 = n / DI4Y; + n = n % DI4Y; + + /* And now how many single years. Again n1 can be 4, and again + * meaning that the desired day is December 31 at the end of the + * 4-year cycle. + */ + n1 = n / 365; + n = n % 365; + + *year += n100 * 100 + n4 * 4 + n1; + if (n1 == 4 || n100 == 4) { + assert(n == 0); + *year -= 1; + *month = 12; + *day = 31; + return; + } + + /* Now the year is correct, and n is the offset from January 1. We + * find the month via an estimate that's either exact or one too + * large. + */ + leapyear = n1 == 3 && (n4 != 24 || n100 == 3); + assert(leapyear == is_leap(*year)); + *month = (n + 50) >> 5; + preceding = (_days_before_month[*month] + (*month > 2 && leapyear)); + if (preceding > n) { + /* estimate is too large */ + *month -= 1; + preceding -= days_in_month(*year, *month); + } + n -= preceding; + assert(0 <= n); + assert(n < days_in_month(*year, *month)); + + *day = n + 1; +} + +/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */ +static int +ymd_to_ord(int year, int month, int day) +{ + return days_before_year(year) + days_before_month(year, month) + day; +} + +/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */ +static int +weekday(int year, int month, int day) +{ + return (ymd_to_ord(year, month, day) + 6) % 7; +} + +/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the + * first calendar week containing a Thursday. + */ +static int +iso_week1_monday(int year) +{ + int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */ + /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */ + int first_weekday = (first_day + 6) % 7; + /* ordinal of closest Monday at or before 1/1 */ + int week1_monday = first_day - first_weekday; + + if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */ + week1_monday += 7; + return week1_monday; +} + +/* --------------------------------------------------------------------------- + * Range checkers. + */ + +/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0. + * If not, raise OverflowError and return -1. + */ +static int +check_delta_day_range(int days) +{ + if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS) + return 0; + PyErr_Format(PyExc_OverflowError, + "days=%d; must have magnitude <= %d", + days, MAX_DELTA_DAYS); + return -1; +} + +/* Check that date arguments are in range. Return 0 if they are. If they + * aren't, raise ValueError and return -1. + */ +static int +check_date_args(int year, int month, int day) +{ + + if (year < MINYEAR || year > MAXYEAR) { + PyErr_Format(PyExc_ValueError, "year %i is out of range", year); + return -1; + } + if (month < 1 || month > 12) { + PyErr_SetString(PyExc_ValueError, + "month must be in 1..12"); + return -1; + } + if (day < 1 || day > days_in_month(year, month)) { + PyErr_SetString(PyExc_ValueError, + "day is out of range for month"); + return -1; + } + return 0; +} + +/* Check that time arguments are in range. Return 0 if they are. If they + * aren't, raise ValueError and return -1. + */ +static int +check_time_args(int h, int m, int s, int us, int fold) +{ + if (h < 0 || h > 23) { + PyErr_SetString(PyExc_ValueError, + "hour must be in 0..23"); + return -1; + } + if (m < 0 || m > 59) { + PyErr_SetString(PyExc_ValueError, + "minute must be in 0..59"); + return -1; + } + if (s < 0 || s > 59) { + PyErr_SetString(PyExc_ValueError, + "second must be in 0..59"); + return -1; + } + if (us < 0 || us > 999999) { + PyErr_SetString(PyExc_ValueError, + "microsecond must be in 0..999999"); + return -1; + } + if (fold != 0 && fold != 1) { + PyErr_SetString(PyExc_ValueError, + "fold must be either 0 or 1"); + return -1; + } + return 0; +} + +/* --------------------------------------------------------------------------- + * Normalization utilities. + */ + +/* One step of a mixed-radix conversion. A "hi" unit is equivalent to + * factor "lo" units. factor must be > 0. If *lo is less than 0, or + * at least factor, enough of *lo is converted into "hi" units so that + * 0 <= *lo < factor. The input values must be such that int overflow + * is impossible. + */ +static void +normalize_pair(int *hi, int *lo, int factor) +{ + assert(factor > 0); + assert(lo != hi); + if (*lo < 0 || *lo >= factor) { + const int num_hi = divmod(*lo, factor, lo); + const int new_hi = *hi + num_hi; + assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi)); + *hi = new_hi; + } + assert(0 <= *lo && *lo < factor); +} + +/* Fiddle days (d), seconds (s), and microseconds (us) so that + * 0 <= *s < 24*3600 + * 0 <= *us < 1000000 + * The input values must be such that the internals don't overflow. + * The way this routine is used, we don't get close. + */ +static void +normalize_d_s_us(int *d, int *s, int *us) +{ + if (*us < 0 || *us >= 1000000) { + normalize_pair(s, us, 1000000); + /* |s| can't be bigger than about + * |original s| + |original us|/1000000 now. + */ + + } + if (*s < 0 || *s >= 24*3600) { + normalize_pair(d, s, 24*3600); + /* |d| can't be bigger than about + * |original d| + + * (|original s| + |original us|/1000000) / (24*3600) now. + */ + } + assert(0 <= *s && *s < 24*3600); + assert(0 <= *us && *us < 1000000); +} + +/* Fiddle years (y), months (m), and days (d) so that + * 1 <= *m <= 12 + * 1 <= *d <= days_in_month(*y, *m) + * The input values must be such that the internals don't overflow. + * The way this routine is used, we don't get close. + */ +static int +normalize_y_m_d(int *y, int *m, int *d) +{ + int dim; /* # of days in month */ + + /* In actual use, m is always the month component extracted from a + * date/datetime object. Therefore it is always in [1, 12] range. + */ + + assert(1 <= *m && *m <= 12); + + /* Now only day can be out of bounds (year may also be out of bounds + * for a datetime object, but we don't care about that here). + * If day is out of bounds, what to do is arguable, but at least the + * method here is principled and explainable. + */ + dim = days_in_month(*y, *m); + if (*d < 1 || *d > dim) { + /* Move day-1 days from the first of the month. First try to + * get off cheap if we're only one day out of range + * (adjustments for timezone alone can't be worse than that). + */ + if (*d == 0) { + --*m; + if (*m > 0) + *d = days_in_month(*y, *m); + else { + --*y; + *m = 12; + *d = 31; + } + } + else if (*d == dim + 1) { + /* move forward a day */ + ++*m; + *d = 1; + if (*m > 12) { + *m = 1; + ++*y; + } + } + else { + int ordinal = ymd_to_ord(*y, *m, 1) + + *d - 1; + if (ordinal < 1 || ordinal > MAXORDINAL) { + goto error; + } else { + ord_to_ymd(ordinal, y, m, d); + return 0; + } + } + } + assert(*m > 0); + assert(*d > 0); + if (MINYEAR <= *y && *y <= MAXYEAR) + return 0; + error: + PyErr_SetString(PyExc_OverflowError, + "date value out of range"); + return -1; + +} + +/* Fiddle out-of-bounds months and days so that the result makes some kind + * of sense. The parameters are both inputs and outputs. Returns < 0 on + * failure, where failure means the adjusted year is out of bounds. + */ +static int +normalize_date(int *year, int *month, int *day) +{ + return normalize_y_m_d(year, month, day); +} + +/* Force all the datetime fields into range. The parameters are both + * inputs and outputs. Returns < 0 on error. + */ +static int +normalize_datetime(int *year, int *month, int *day, + int *hour, int *minute, int *second, + int *microsecond) +{ + normalize_pair(second, microsecond, 1000000); + normalize_pair(minute, second, 60); + normalize_pair(hour, minute, 60); + normalize_pair(day, hour, 24); + return normalize_date(year, month, day); +} + +/* --------------------------------------------------------------------------- + * Basic object allocation: tp_alloc implementations. These allocate + * Python objects of the right size and type, and do the Python object- + * initialization bit. If there's not enough memory, they return NULL after + * setting MemoryError. All data members remain uninitialized trash. + * + * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo + * member is needed. This is ugly, imprecise, and possibly insecure. + * tp_basicsize for the time and datetime types is set to the size of the + * struct that has room for the tzinfo member, so subclasses in Python will + * allocate enough space for a tzinfo member whether or not one is actually + * needed. That's the "ugly and imprecise" parts. The "possibly insecure" + * part is that PyType_GenericAlloc() (which subclasses in Python end up + * using) just happens today to effectively ignore the nitems argument + * when tp_itemsize is 0, which it is for these type objects. If that + * changes, perhaps the callers of tp_alloc slots in this file should + * be changed to force a 0 nitems argument unless the type being allocated + * is a base type implemented in this file (so that tp_alloc is time_alloc + * or datetime_alloc below, which know about the nitems abuse). + */ + +static PyObject * +time_alloc(PyTypeObject *type, Py_ssize_t aware) +{ + PyObject *self; + + self = (PyObject *) + PyObject_MALLOC(aware ? + sizeof(PyDateTime_Time) : + sizeof(_PyDateTime_BaseTime)); + if (self == NULL) + return (PyObject *)PyErr_NoMemory(); + (void)PyObject_INIT(self, type); + return self; +} + +static PyObject * +datetime_alloc(PyTypeObject *type, Py_ssize_t aware) +{ + PyObject *self; + + self = (PyObject *) + PyObject_MALLOC(aware ? + sizeof(PyDateTime_DateTime) : + sizeof(_PyDateTime_BaseDateTime)); + if (self == NULL) + return (PyObject *)PyErr_NoMemory(); + (void)PyObject_INIT(self, type); + return self; +} + +/* --------------------------------------------------------------------------- + * Helpers for setting object fields. These work on pointers to the + * appropriate base class. + */ + +/* For date and datetime. */ +static void +set_date_fields(PyDateTime_Date *self, int y, int m, int d) +{ + self->hashcode = -1; + SET_YEAR(self, y); + SET_MONTH(self, m); + SET_DAY(self, d); +} + +/* --------------------------------------------------------------------------- + * String parsing utilities and helper functions + */ + +static const char * +parse_digits(const char *ptr, int *var, size_t num_digits) +{ + for (size_t i = 0; i < num_digits; ++i) { + unsigned int tmp = (unsigned int)(*(ptr++) - '0'); + if (tmp > 9) { + return NULL; + } + *var *= 10; + *var += (signed int)tmp; + } + + return ptr; +} + +static int +parse_isoformat_date(const char *dtstr, int *year, int *month, int *day) +{ + /* Parse the date components of the result of date.isoformat() + * + * Return codes: + * 0: Success + * -1: Failed to parse date component + * -2: Failed to parse dateseparator + */ + const char *p = dtstr; + p = parse_digits(p, year, 4); + if (NULL == p) { + return -1; + } + + if (*(p++) != '-') { + return -2; + } + + p = parse_digits(p, month, 2); + if (NULL == p) { + return -1; + } + + if (*(p++) != '-') { + return -2; + } + + p = parse_digits(p, day, 2); + if (p == NULL) { + return -1; + } + + return 0; +} + +static int +parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, + int *minute, int *second, int *microsecond) +{ + const char *p = tstr; + const char *p_end = tstr_end; + int *vals[3] = {hour, minute, second}; + + // Parse [HH[:MM[:SS]]] + for (size_t i = 0; i < 3; ++i) { + p = parse_digits(p, vals[i], 2); + if (NULL == p) { + return -3; + } + + char c = *(p++); + if (p >= p_end) { + return c != '\0'; + } + else if (c == ':') { + continue; + } + else if (c == '.') { + break; + } + else { + return -4; // Malformed time separator + } + } + + // Parse .fff[fff] + size_t len_remains = p_end - p; + if (!(len_remains == 6 || len_remains == 3)) { + return -3; + } + + p = parse_digits(p, microsecond, len_remains); + if (NULL == p) { + return -3; + } + + if (len_remains == 3) { + *microsecond *= 1000; + } + + // Return 1 if it's not the end of the string + return *p != '\0'; +} + +static int +parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute, + int *second, int *microsecond, int *tzoffset, + int *tzmicrosecond) +{ + // Parse the time portion of a datetime.isoformat() string + // + // Return codes: + // 0: Success (no tzoffset) + // 1: Success (with tzoffset) + // -3: Failed to parse time component + // -4: Failed to parse time separator + // -5: Malformed timezone string + + const char *p = dtstr; + const char *p_end = dtstr + dtlen; + + const char *tzinfo_pos = p; + do { + if (*tzinfo_pos == '+' || *tzinfo_pos == '-') { + break; + } + } while (++tzinfo_pos < p_end); + + int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second, + microsecond); + + if (rv < 0) { + return rv; + } + else if (tzinfo_pos == p_end) { + // We know that there's no time zone, so if there's stuff at the + // end of the string it's an error. + if (rv == 1) { + return -5; + } + else { + return 0; + } + } + + // Parse time zone component + // Valid formats are: + // - +HH:MM (len 6) + // - +HH:MM:SS (len 9) + // - +HH:MM:SS.ffffff (len 16) + size_t tzlen = p_end - tzinfo_pos; + if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) { + return -5; + } + + int tzsign = (*tzinfo_pos == '-') ? -1 : 1; + tzinfo_pos++; + int tzhour = 0, tzminute = 0, tzsecond = 0; + rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond, + tzmicrosecond); + + *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond); + *tzmicrosecond *= tzsign; + + return rv ? -5 : 1; +} + +/* --------------------------------------------------------------------------- + * Create various objects, mostly without range checking. + */ + +/* Create a date instance with no range checking. */ +static PyObject * +new_date_ex(int year, int month, int day, PyTypeObject *type) +{ + PyDateTime_Date *self; + + if (check_date_args(year, month, day) < 0) { + return NULL; + } + + self = (PyDateTime_Date *)(type->tp_alloc(type, 0)); + if (self != NULL) + set_date_fields(self, year, month, day); + return (PyObject *)self; +} + +#define new_date(year, month, day) \ + new_date_ex(year, month, day, &PyDateTime_DateType) + +// Forward declaration +static PyObject * +new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *); + +/* Create date instance with no range checking, or call subclass constructor */ +static PyObject * +new_date_subclass_ex(int year, int month, int day, PyObject *cls) +{ + PyObject *result; + // We have "fast path" constructors for two subclasses: date and datetime + if ((PyTypeObject *)cls == &PyDateTime_DateType) { + result = new_date_ex(year, month, day, (PyTypeObject *)cls); + } + else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) { + result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None, + (PyTypeObject *)cls); + } + else { + result = PyObject_CallFunction(cls, "iii", year, month, day); + } + + return result; +} + +/* Create a datetime instance with no range checking. */ +static PyObject * +new_datetime_ex2(int year, int month, int day, int hour, int minute, + int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type) +{ + PyDateTime_DateTime *self; + char aware = tzinfo != Py_None; + + if (check_date_args(year, month, day) < 0) { + return NULL; + } + if (check_time_args(hour, minute, second, usecond, fold) < 0) { + return NULL; + } + if (check_tzinfo_subclass(tzinfo) < 0) { + return NULL; + } + + self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware)); + if (self != NULL) { + self->hastzinfo = aware; + set_date_fields((PyDateTime_Date *)self, year, month, day); + DATE_SET_HOUR(self, hour); + DATE_SET_MINUTE(self, minute); + DATE_SET_SECOND(self, second); + DATE_SET_MICROSECOND(self, usecond); + if (aware) { + Py_INCREF(tzinfo); + self->tzinfo = tzinfo; + } + DATE_SET_FOLD(self, fold); + } + return (PyObject *)self; +} + +static PyObject * +new_datetime_ex(int year, int month, int day, int hour, int minute, + int second, int usecond, PyObject *tzinfo, PyTypeObject *type) +{ + return new_datetime_ex2(year, month, day, hour, minute, second, usecond, + tzinfo, 0, type); +} + +#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \ + new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \ + &PyDateTime_DateTimeType) + +static PyObject * +new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute, + int second, int usecond, PyObject *tzinfo, + int fold, PyObject *cls) { + PyObject* dt; + if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) { + // Use the fast path constructor + dt = new_datetime(year, month, day, hour, minute, second, usecond, + tzinfo, fold); + } else { + // Subclass + dt = PyObject_CallFunction(cls, "iiiiiiiO", + year, + month, + day, + hour, + minute, + second, + usecond, + tzinfo); + } + + return dt; +} + +static PyObject * +new_datetime_subclass_ex(int year, int month, int day, int hour, int minute, + int second, int usecond, PyObject *tzinfo, + PyObject *cls) { + return new_datetime_subclass_fold_ex(year, month, day, hour, minute, + second, usecond, tzinfo, 0, + cls); +} + +/* Create a time instance with no range checking. */ +static PyObject * +new_time_ex2(int hour, int minute, int second, int usecond, + PyObject *tzinfo, int fold, PyTypeObject *type) +{ + PyDateTime_Time *self; + char aware = tzinfo != Py_None; + + if (check_time_args(hour, minute, second, usecond, fold) < 0) { + return NULL; + } + if (check_tzinfo_subclass(tzinfo) < 0) { + return NULL; + } + + self = (PyDateTime_Time *) (type->tp_alloc(type, aware)); + if (self != NULL) { + self->hastzinfo = aware; + self->hashcode = -1; + TIME_SET_HOUR(self, hour); + TIME_SET_MINUTE(self, minute); + TIME_SET_SECOND(self, second); + TIME_SET_MICROSECOND(self, usecond); + if (aware) { + Py_INCREF(tzinfo); + self->tzinfo = tzinfo; + } + TIME_SET_FOLD(self, fold); + } + return (PyObject *)self; +} + +static PyObject * +new_time_ex(int hour, int minute, int second, int usecond, + PyObject *tzinfo, PyTypeObject *type) +{ + return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type); +} + +#define new_time(hh, mm, ss, us, tzinfo, fold) \ + new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType) + +/* Create a timedelta instance. Normalize the members iff normalize is + * true. Passing false is a speed optimization, if you know for sure + * that seconds and microseconds are already in their proper ranges. In any + * case, raises OverflowError and returns NULL if the normalized days is out + * of range. + */ +static PyObject * +new_delta_ex(int days, int seconds, int microseconds, int normalize, + PyTypeObject *type) +{ + PyDateTime_Delta *self; + + if (normalize) + normalize_d_s_us(&days, &seconds, µseconds); + assert(0 <= seconds && seconds < 24*3600); + assert(0 <= microseconds && microseconds < 1000000); + + if (check_delta_day_range(days) < 0) + return NULL; + + self = (PyDateTime_Delta *) (type->tp_alloc(type, 0)); + if (self != NULL) { + self->hashcode = -1; + SET_TD_DAYS(self, days); + SET_TD_SECONDS(self, seconds); + SET_TD_MICROSECONDS(self, microseconds); + } + return (PyObject *) self; +} + +#define new_delta(d, s, us, normalize) \ + new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType) + + +typedef struct +{ + PyObject_HEAD + PyObject *offset; + PyObject *name; +} PyDateTime_TimeZone; + +/* The interned UTC timezone instance */ +static PyObject *PyDateTime_TimeZone_UTC; +/* The interned Epoch datetime instance */ +static PyObject *PyDateTime_Epoch; + +/* Create new timezone instance checking offset range. This + function does not check the name argument. Caller must assure + that offset is a timedelta instance and name is either NULL + or a unicode object. */ +static PyObject * +create_timezone(PyObject *offset, PyObject *name) +{ + PyDateTime_TimeZone *self; + PyTypeObject *type = &PyDateTime_TimeZoneType; + + assert(offset != NULL); + assert(PyDelta_Check(offset)); + assert(name == NULL || PyUnicode_Check(name)); + + self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0)); + if (self == NULL) { + return NULL; + } + Py_INCREF(offset); + self->offset = offset; + Py_XINCREF(name); + self->name = name; + return (PyObject *)self; +} + +static int delta_bool(PyDateTime_Delta *self); + +static PyObject * +new_timezone(PyObject *offset, PyObject *name) +{ + assert(offset != NULL); + assert(PyDelta_Check(offset)); + assert(name == NULL || PyUnicode_Check(name)); + + if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) { + Py_INCREF(PyDateTime_TimeZone_UTC); + return PyDateTime_TimeZone_UTC; + } + if ((GET_TD_DAYS(offset) == -1 && + GET_TD_SECONDS(offset) == 0 && + GET_TD_MICROSECONDS(offset) < 1) || + GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { + PyErr_Format(PyExc_ValueError, "offset must be a timedelta" + " strictly between -timedelta(hours=24) and" + " timedelta(hours=24)," + " not %R.", offset); + return NULL; + } + + return create_timezone(offset, name); +} + +/* --------------------------------------------------------------------------- + * tzinfo helpers. + */ + +/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not + * raise TypeError and return -1. + */ +static int +check_tzinfo_subclass(PyObject *p) +{ + if (p == Py_None || PyTZInfo_Check(p)) + return 0; + PyErr_Format(PyExc_TypeError, + "tzinfo argument must be None or of a tzinfo subclass, " + "not type '%s'", + Py_TYPE(p)->tp_name); + return -1; +} + +/* If self has a tzinfo member, return a BORROWED reference to it. Else + * return NULL, which is NOT AN ERROR. There are no error returns here, + * and the caller must not decref the result. + */ +static PyObject * +get_tzinfo_member(PyObject *self) +{ + PyObject *tzinfo = NULL; + + if (PyDateTime_Check(self) && HASTZINFO(self)) + tzinfo = ((PyDateTime_DateTime *)self)->tzinfo; + else if (PyTime_Check(self) && HASTZINFO(self)) + tzinfo = ((PyDateTime_Time *)self)->tzinfo; + + return tzinfo; +} + +/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must + * be an instance of the tzinfo class. If the method returns None, this + * returns None. If the method doesn't return None or timedelta, TypeError is + * raised and this returns NULL. If it returns a timedelta and the value is + * out of range or isn't a whole number of minutes, ValueError is raised and + * this returns NULL. Else result is returned. + */ +static PyObject * +call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg) +{ + PyObject *offset; + + assert(tzinfo != NULL); + assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None); + assert(tzinfoarg != NULL); + + if (tzinfo == Py_None) + Py_RETURN_NONE; + offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg); + if (offset == Py_None || offset == NULL) + return offset; + if (PyDelta_Check(offset)) { + if ((GET_TD_DAYS(offset) == -1 && + GET_TD_SECONDS(offset) == 0 && + GET_TD_MICROSECONDS(offset) < 1) || + GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { + Py_DECREF(offset); + PyErr_Format(PyExc_ValueError, "offset must be a timedelta" + " strictly between -timedelta(hours=24) and" + " timedelta(hours=24)."); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "tzinfo.%s() must return None or " + "timedelta, not '%.200s'", + name, Py_TYPE(offset)->tp_name); + Py_DECREF(offset); + return NULL; + } + + return offset; +} + +/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the + * result. tzinfo must be an instance of the tzinfo class. If utcoffset() + * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset() + * doesn't return None or timedelta, TypeError is raised and this returns -1. + * If utcoffset() returns an out of range timedelta, + * ValueError is raised and this returns -1. Else *none is + * set to 0 and the offset is returned (as timedelta, positive east of UTC). + */ +static PyObject * +call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg) +{ + return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg); +} + +/* Call tzinfo.dst(tzinfoarg), and extract an integer from the + * result. tzinfo must be an instance of the tzinfo class. If dst() + * returns None, call_dst returns 0 and sets *none to 1. If dst() + * doesn't return None or timedelta, TypeError is raised and this + * returns -1. If dst() returns an invalid timedelta for a UTC offset, + * ValueError is raised and this returns -1. Else *none is set to 0 and + * the offset is returned (as timedelta, positive east of UTC). + */ +static PyObject * +call_dst(PyObject *tzinfo, PyObject *tzinfoarg) +{ + return call_tzinfo_method(tzinfo, "dst", tzinfoarg); +} + +/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be + * an instance of the tzinfo class or None. If tzinfo isn't None, and + * tzname() doesn't return None or a string, TypeError is raised and this + * returns NULL. If the result is a string, we ensure it is a Unicode + * string. + */ +static PyObject * +call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) +{ + PyObject *result; + _Py_IDENTIFIER(tzname); + + assert(tzinfo != NULL); + assert(check_tzinfo_subclass(tzinfo) >= 0); + assert(tzinfoarg != NULL); + + if (tzinfo == Py_None) + Py_RETURN_NONE; + + result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg); + + if (result == NULL || result == Py_None) + return result; + + if (!PyUnicode_Check(result)) { + PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must " + "return None or a string, not '%s'", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + result = NULL; + } + + return result; +} + +/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None, + * stuff + * ", tzinfo=" + repr(tzinfo) + * before the closing ")". + */ +static PyObject * +append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo) +{ + PyObject *temp; + + assert(PyUnicode_Check(repr)); + assert(tzinfo); + if (tzinfo == Py_None) + return repr; + /* Get rid of the trailing ')'. */ + assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')'); + temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1); + Py_DECREF(repr); + if (temp == NULL) + return NULL; + repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo); + Py_DECREF(temp); + return repr; +} + +/* repr is like "someclass(arg1, arg2)". If fold isn't 0, + * stuff + * ", fold=" + repr(tzinfo) + * before the closing ")". + */ +static PyObject * +append_keyword_fold(PyObject *repr, int fold) +{ + PyObject *temp; + + assert(PyUnicode_Check(repr)); + if (fold == 0) + return repr; + /* Get rid of the trailing ')'. */ + assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')'); + temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1); + Py_DECREF(repr); + if (temp == NULL) + return NULL; + repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold); + Py_DECREF(temp); + return repr; +} + +static inline PyObject * +tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) +{ + PyObject *tzinfo; + if (rv == 1) { + // Create a timezone from offset in seconds (0 returns UTC) + if (tzoffset == 0) { + Py_INCREF(PyDateTime_TimeZone_UTC); + return PyDateTime_TimeZone_UTC; + } + + PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1); + if (delta == NULL) { + return NULL; + } + tzinfo = new_timezone(delta, NULL); + Py_DECREF(delta); + } + else { + tzinfo = Py_None; + Py_INCREF(Py_None); + } + + return tzinfo; +} + +/* --------------------------------------------------------------------------- + * String format helpers. + */ + +static PyObject * +format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds) +{ + static const char * const DayNames[] = { + "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" + }; + static const char * const MonthNames[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date)); + + return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d", + DayNames[wday], MonthNames[GET_MONTH(date)-1], + GET_DAY(date), hours, minutes, seconds, + GET_YEAR(date)); +} + +static PyObject *delta_negative(PyDateTime_Delta *self); + +/* Add formatted UTC offset string to buf. buf has no more than + * buflen bytes remaining. The UTC offset is gotten by calling + * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into + * *buf, and that's all. Else the returned value is checked for sanity (an + * integer in range), and if that's OK it's converted to an hours & minutes + * string of the form + * sign HH sep MM [sep SS [. UUUUUU]] + * Returns 0 if everything is OK. If the return value from utcoffset() is + * bogus, an appropriate exception is set and -1 is returned. + */ +static int +format_utcoffset(char *buf, size_t buflen, const char *sep, + PyObject *tzinfo, PyObject *tzinfoarg) +{ + PyObject *offset; + int hours, minutes, seconds, microseconds; + char sign; + + assert(buflen >= 1); + + offset = call_utcoffset(tzinfo, tzinfoarg); + if (offset == NULL) + return -1; + if (offset == Py_None) { + Py_DECREF(offset); + *buf = '\0'; + return 0; + } + /* Offset is normalized, so it is negative if days < 0 */ + if (GET_TD_DAYS(offset) < 0) { + sign = '-'; + Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset)); + if (offset == NULL) + return -1; + } + else { + sign = '+'; + } + /* Offset is not negative here. */ + microseconds = GET_TD_MICROSECONDS(offset); + seconds = GET_TD_SECONDS(offset); + Py_DECREF(offset); + minutes = divmod(seconds, 60, &seconds); + hours = divmod(minutes, 60, &minutes); + if (microseconds) { + PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign, + hours, sep, minutes, sep, seconds, microseconds); + return 0; + } + if (seconds) { + PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours, + sep, minutes, sep, seconds); + return 0; + } + PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes); + return 0; +} + +static PyObject * +make_Zreplacement(PyObject *object, PyObject *tzinfoarg) +{ + PyObject *temp; + PyObject *tzinfo = get_tzinfo_member(object); + PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0); + _Py_IDENTIFIER(replace); + + if (Zreplacement == NULL) + return NULL; + if (tzinfo == Py_None || tzinfo == NULL) + return Zreplacement; + + assert(tzinfoarg != NULL); + temp = call_tzname(tzinfo, tzinfoarg); + if (temp == NULL) + goto Error; + if (temp == Py_None) { + Py_DECREF(temp); + return Zreplacement; + } + + assert(PyUnicode_Check(temp)); + /* Since the tzname is getting stuffed into the + * format, we have to double any % signs so that + * strftime doesn't treat them as format codes. + */ + Py_DECREF(Zreplacement); + Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%"); + Py_DECREF(temp); + if (Zreplacement == NULL) + return NULL; + if (!PyUnicode_Check(Zreplacement)) { + PyErr_SetString(PyExc_TypeError, + "tzname.replace() did not return a string"); + goto Error; + } + return Zreplacement; + + Error: + Py_DECREF(Zreplacement); + return NULL; +} + +static PyObject * +make_freplacement(PyObject *object) +{ + char freplacement[64]; + if (PyTime_Check(object)) + sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object)); + else if (PyDateTime_Check(object)) + sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object)); + else + sprintf(freplacement, "%06d", 0); + + return PyBytes_FromStringAndSize(freplacement, strlen(freplacement)); +} + +/* I sure don't want to reproduce the strftime code from the time module, + * so this imports the module and calls it. All the hair is due to + * giving special meanings to the %z, %Z and %f format codes via a + * preprocessing step on the format string. + * tzinfoarg is the argument to pass to the object's tzinfo method, if + * needed. + */ +static PyObject * +wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, + PyObject *tzinfoarg) +{ + PyObject *result = NULL; /* guilty until proved innocent */ + + PyObject *zreplacement = NULL; /* py string, replacement for %z */ + PyObject *Zreplacement = NULL; /* py string, replacement for %Z */ + PyObject *freplacement = NULL; /* py string, replacement for %f */ + + const char *pin; /* pointer to next char in input format */ + Py_ssize_t flen; /* length of input format */ + char ch; /* next char in input format */ + + PyObject *newfmt = NULL; /* py string, the output format */ + char *pnew; /* pointer to available byte in output format */ + size_t totalnew; /* number bytes total in output format buffer, + exclusive of trailing \0 */ + size_t usednew; /* number bytes used so far in output format buffer */ + + const char *ptoappend; /* ptr to string to append to output buffer */ + Py_ssize_t ntoappend; /* # of bytes to append to output buffer */ + + assert(object && format && timetuple); + assert(PyUnicode_Check(format)); + /* Convert the input format to a C string and size */ + pin = PyUnicode_AsUTF8AndSize(format, &flen); + if (!pin) + return NULL; + + /* Scan the input format, looking for %z/%Z/%f escapes, building + * a new format. Since computing the replacements for those codes + * is expensive, don't unless they're actually used. + */ + if (flen > INT_MAX - 1) { + PyErr_NoMemory(); + goto Done; + } + + totalnew = flen + 1; /* realistic if no %z/%Z */ + newfmt = PyBytes_FromStringAndSize(NULL, totalnew); + if (newfmt == NULL) goto Done; + pnew = PyBytes_AsString(newfmt); + usednew = 0; + + while ((ch = *pin++) != '\0') { + if (ch != '%') { + ptoappend = pin - 1; + ntoappend = 1; + } + else if ((ch = *pin++) == '\0') { + /* Null byte follows %, copy only '%'. + * + * Back the pin up one char so that we catch the null check + * the next time through the loop.*/ + pin--; + ptoappend = pin - 1; + ntoappend = 1; + } + /* A % has been seen and ch is the character after it. */ + else if (ch == 'z') { + if (zreplacement == NULL) { + /* format utcoffset */ + char buf[100]; + PyObject *tzinfo = get_tzinfo_member(object); + zreplacement = PyBytes_FromStringAndSize("", 0); + if (zreplacement == NULL) goto Done; + if (tzinfo != Py_None && tzinfo != NULL) { + assert(tzinfoarg != NULL); + if (format_utcoffset(buf, + sizeof(buf), + "", + tzinfo, + tzinfoarg) < 0) + goto Done; + Py_DECREF(zreplacement); + zreplacement = + PyBytes_FromStringAndSize(buf, + strlen(buf)); + if (zreplacement == NULL) + goto Done; + } + } + assert(zreplacement != NULL); + ptoappend = PyBytes_AS_STRING(zreplacement); + ntoappend = PyBytes_GET_SIZE(zreplacement); + } + else if (ch == 'Z') { + /* format tzname */ + if (Zreplacement == NULL) { + Zreplacement = make_Zreplacement(object, + tzinfoarg); + if (Zreplacement == NULL) + goto Done; + } + assert(Zreplacement != NULL); + assert(PyUnicode_Check(Zreplacement)); + ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement, + &ntoappend); + if (ptoappend == NULL) + goto Done; + } + else if (ch == 'f') { + /* format microseconds */ + if (freplacement == NULL) { + freplacement = make_freplacement(object); + if (freplacement == NULL) + goto Done; + } + assert(freplacement != NULL); + assert(PyBytes_Check(freplacement)); + ptoappend = PyBytes_AS_STRING(freplacement); + ntoappend = PyBytes_GET_SIZE(freplacement); + } + else { + /* percent followed by neither z nor Z */ + ptoappend = pin - 2; + ntoappend = 2; + } + + /* Append the ntoappend chars starting at ptoappend to + * the new format. + */ + if (ntoappend == 0) + continue; + assert(ptoappend != NULL); + assert(ntoappend > 0); + while (usednew + ntoappend > totalnew) { + if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */ + PyErr_NoMemory(); + goto Done; + } + totalnew <<= 1; + if (_PyBytes_Resize(&newfmt, totalnew) < 0) + goto Done; + pnew = PyBytes_AsString(newfmt) + usednew; + } + memcpy(pnew, ptoappend, ntoappend); + pnew += ntoappend; + usednew += ntoappend; + assert(usednew <= totalnew); + } /* end while() */ + + if (_PyBytes_Resize(&newfmt, usednew) < 0) + goto Done; + { + PyObject *format; + PyObject *time = PyImport_ImportModuleNoBlock("time"); + + if (time == NULL) + goto Done; + format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); + if (format != NULL) { + result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime, + format, timetuple, NULL); + Py_DECREF(format); + } + Py_DECREF(time); + } + Done: + Py_XDECREF(freplacement); + Py_XDECREF(zreplacement); + Py_XDECREF(Zreplacement); + Py_XDECREF(newfmt); + return result; +} + +/* --------------------------------------------------------------------------- + * Wrap functions from the time module. These aren't directly available + * from C. Perhaps they should be. + */ + +/* Call time.time() and return its result (a Python float). */ +static PyObject * +time_time(void) +{ + PyObject *result = NULL; + PyObject *time = PyImport_ImportModuleNoBlock("time"); + + if (time != NULL) { + _Py_IDENTIFIER(time); + + result = _PyObject_CallMethodIdNoArgs(time, &PyId_time); + Py_DECREF(time); + } + return result; +} + +/* Build a time.struct_time. The weekday and day number are automatically + * computed from the y,m,d args. + */ +static PyObject * +build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) +{ + PyObject *time; + PyObject *result; + _Py_IDENTIFIER(struct_time); + PyObject *args; + + + time = PyImport_ImportModuleNoBlock("time"); + if (time == NULL) { + return NULL; + } + + args = Py_BuildValue("iiiiiiiii", + y, m, d, + hh, mm, ss, + weekday(y, m, d), + days_before_month(y, m) + d, + dstflag); + if (args == NULL) { + Py_DECREF(time); + return NULL; + } + + result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args); + Py_DECREF(time); + Py_DECREF(args); + return result; +} + +/* --------------------------------------------------------------------------- + * Miscellaneous helpers. + */ + +/* The comparisons here all most naturally compute a cmp()-like result. + * This little helper turns that into a bool result for rich comparisons. + */ +static PyObject * +diff_to_bool(int diff, int op) +{ + Py_RETURN_RICHCOMPARE(diff, 0, op); +} + +/* Raises a "can't compare" TypeError and returns NULL. */ +static PyObject * +cmperror(PyObject *a, PyObject *b) +{ + PyErr_Format(PyExc_TypeError, + "can't compare %s to %s", + Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); + return NULL; +} + +/* --------------------------------------------------------------------------- + * Cached Python objects; these are set by the module init function. + */ + +/* Conversion factors. */ +static PyObject *us_per_ms = NULL; /* 1000 */ +static PyObject *us_per_second = NULL; /* 1000000 */ +static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */ +static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */ +static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */ +static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */ +static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */ + +/* --------------------------------------------------------------------------- + * Class implementations. + */ + +/* + * PyDateTime_Delta implementation. + */ + +/* Convert a timedelta to a number of us, + * (24*3600*self.days + self.seconds)*1000000 + self.microseconds + * as a Python int. + * Doing mixed-radix arithmetic by hand instead is excruciating in C, + * due to ubiquitous overflow possibilities. + */ +static PyObject * +delta_to_microseconds(PyDateTime_Delta *self) +{ + PyObject *x1 = NULL; + PyObject *x2 = NULL; + PyObject *x3 = NULL; + PyObject *result = NULL; + + x1 = PyLong_FromLong(GET_TD_DAYS(self)); + if (x1 == NULL) + goto Done; + x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */ + if (x2 == NULL) + goto Done; + Py_DECREF(x1); + x1 = NULL; + + /* x2 has days in seconds */ + x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */ + if (x1 == NULL) + goto Done; + x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */ + if (x3 == NULL) + goto Done; + Py_DECREF(x1); + Py_DECREF(x2); + /* x1 = */ x2 = NULL; + + /* x3 has days+seconds in seconds */ + x1 = PyNumber_Multiply(x3, us_per_second); /* us */ + if (x1 == NULL) + goto Done; + Py_DECREF(x3); + x3 = NULL; + + /* x1 has days+seconds in us */ + x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self)); + if (x2 == NULL) + goto Done; + result = PyNumber_Add(x1, x2); + assert(result == NULL || PyLong_CheckExact(result)); + +Done: + Py_XDECREF(x1); + Py_XDECREF(x2); + Py_XDECREF(x3); + return result; +} + +static PyObject * +checked_divmod(PyObject *a, PyObject *b) +{ + PyObject *result = PyNumber_Divmod(a, b); + if (result != NULL) { + if (!PyTuple_Check(result)) { + PyErr_Format(PyExc_TypeError, + "divmod() returned non-tuple (type %.200s)", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + if (PyTuple_GET_SIZE(result) != 2) { + PyErr_Format(PyExc_TypeError, + "divmod() returned a tuple of size %zd", + PyTuple_GET_SIZE(result)); + Py_DECREF(result); + return NULL; + } + } + return result; +} + +/* Convert a number of us (as a Python int) to a timedelta. + */ +static PyObject * +microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) +{ + int us; + int s; + int d; + + PyObject *tuple = NULL; + PyObject *num = NULL; + PyObject *result = NULL; + + tuple = checked_divmod(pyus, us_per_second); + if (tuple == NULL) { + goto Done; + } + + num = PyTuple_GET_ITEM(tuple, 1); /* us */ + us = _PyLong_AsInt(num); + num = NULL; + if (us == -1 && PyErr_Occurred()) { + goto Done; + } + if (!(0 <= us && us < 1000000)) { + goto BadDivmod; + } + + num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */ + Py_INCREF(num); + Py_DECREF(tuple); + + tuple = checked_divmod(num, seconds_per_day); + if (tuple == NULL) + goto Done; + Py_DECREF(num); + + num = PyTuple_GET_ITEM(tuple, 1); /* seconds */ + s = _PyLong_AsInt(num); + num = NULL; + if (s == -1 && PyErr_Occurred()) { + goto Done; + } + if (!(0 <= s && s < 24*3600)) { + goto BadDivmod; + } + + num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */ + Py_INCREF(num); + d = _PyLong_AsInt(num); + if (d == -1 && PyErr_Occurred()) { + goto Done; + } + result = new_delta_ex(d, s, us, 0, type); + +Done: + Py_XDECREF(tuple); + Py_XDECREF(num); + return result; + +BadDivmod: + PyErr_SetString(PyExc_TypeError, + "divmod() returned a value out of range"); + goto Done; +} + +#define microseconds_to_delta(pymicros) \ + microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType) + +static PyObject * +multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta) +{ + PyObject *pyus_in; + PyObject *pyus_out; + PyObject *result; + + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + + pyus_out = PyNumber_Multiply(intobj, pyus_in); + Py_DECREF(pyus_in); + if (pyus_out == NULL) + return NULL; + + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + return result; +} + +static PyObject * +get_float_as_integer_ratio(PyObject *floatobj) +{ + PyObject *ratio; + + assert(floatobj && PyFloat_Check(floatobj)); + ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio); + if (ratio == NULL) { + return NULL; + } + if (!PyTuple_Check(ratio)) { + PyErr_Format(PyExc_TypeError, + "unexpected return type from as_integer_ratio(): " + "expected tuple, got '%.200s'", + Py_TYPE(ratio)->tp_name); + Py_DECREF(ratio); + return NULL; + } + if (PyTuple_Size(ratio) != 2) { + PyErr_SetString(PyExc_ValueError, + "as_integer_ratio() must return a 2-tuple"); + Py_DECREF(ratio); + return NULL; + } + return ratio; +} + +/* op is 0 for multiplication, 1 for division */ +static PyObject * +multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op) +{ + PyObject *result = NULL; + PyObject *pyus_in = NULL, *temp, *pyus_out; + PyObject *ratio = NULL; + + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + ratio = get_float_as_integer_ratio(floatobj); + if (ratio == NULL) { + goto error; + } + temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op)); + Py_DECREF(pyus_in); + pyus_in = NULL; + if (temp == NULL) + goto error; + pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op)); + Py_DECREF(temp); + if (pyus_out == NULL) + goto error; + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + error: + Py_XDECREF(pyus_in); + Py_XDECREF(ratio); + + return result; +} + +static PyObject * +divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj) +{ + PyObject *pyus_in; + PyObject *pyus_out; + PyObject *result; + + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + + pyus_out = PyNumber_FloorDivide(pyus_in, intobj); + Py_DECREF(pyus_in); + if (pyus_out == NULL) + return NULL; + + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + return result; +} + +static PyObject * +divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *result; + + pyus_left = delta_to_microseconds(left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds(right); + if (pyus_right == NULL) { + Py_DECREF(pyus_left); + return NULL; + } + + result = PyNumber_FloorDivide(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + return result; +} + +static PyObject * +truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *result; + + pyus_left = delta_to_microseconds(left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds(right); + if (pyus_right == NULL) { + Py_DECREF(pyus_left); + return NULL; + } + + result = PyNumber_TrueDivide(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + return result; +} + +static PyObject * +truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i) +{ + PyObject *result; + PyObject *pyus_in, *pyus_out; + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + pyus_out = divide_nearest(pyus_in, i); + Py_DECREF(pyus_in); + if (pyus_out == NULL) + return NULL; + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + + return result; +} + +static PyObject * +delta_add(PyObject *left, PyObject *right) +{ + PyObject *result = Py_NotImplemented; + + if (PyDelta_Check(left) && PyDelta_Check(right)) { + /* delta + delta */ + /* The C-level additions can't overflow because of the + * invariant bounds. + */ + int days = GET_TD_DAYS(left) + GET_TD_DAYS(right); + int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right); + int microseconds = GET_TD_MICROSECONDS(left) + + GET_TD_MICROSECONDS(right); + result = new_delta(days, seconds, microseconds, 1); + } + + if (result == Py_NotImplemented) + Py_INCREF(result); + return result; +} + +static PyObject * +delta_negative(PyDateTime_Delta *self) +{ + return new_delta(-GET_TD_DAYS(self), + -GET_TD_SECONDS(self), + -GET_TD_MICROSECONDS(self), + 1); +} + +static PyObject * +delta_positive(PyDateTime_Delta *self) +{ + /* Could optimize this (by returning self) if this isn't a + * subclass -- but who uses unary + ? Approximately nobody. + */ + return new_delta(GET_TD_DAYS(self), + GET_TD_SECONDS(self), + GET_TD_MICROSECONDS(self), + 0); +} + +static PyObject * +delta_abs(PyDateTime_Delta *self) +{ + PyObject *result; + + assert(GET_TD_MICROSECONDS(self) >= 0); + assert(GET_TD_SECONDS(self) >= 0); + + if (GET_TD_DAYS(self) < 0) + result = delta_negative(self); + else + result = delta_positive(self); + + return result; +} + +static PyObject * +delta_subtract(PyObject *left, PyObject *right) +{ + PyObject *result = Py_NotImplemented; + + if (PyDelta_Check(left) && PyDelta_Check(right)) { + /* delta - delta */ + /* The C-level additions can't overflow because of the + * invariant bounds. + */ + int days = GET_TD_DAYS(left) - GET_TD_DAYS(right); + int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right); + int microseconds = GET_TD_MICROSECONDS(left) - + GET_TD_MICROSECONDS(right); + result = new_delta(days, seconds, microseconds, 1); + } + + if (result == Py_NotImplemented) + Py_INCREF(result); + return result; +} + +static int +delta_cmp(PyObject *self, PyObject *other) +{ + int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other); + if (diff == 0) { + diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other); + if (diff == 0) + diff = GET_TD_MICROSECONDS(self) - + GET_TD_MICROSECONDS(other); + } + return diff; +} + +static PyObject * +delta_richcompare(PyObject *self, PyObject *other, int op) +{ + if (PyDelta_Check(other)) { + int diff = delta_cmp(self, other); + return diff_to_bool(diff, op); + } + else { + Py_RETURN_NOTIMPLEMENTED; + } +} + +static PyObject *delta_getstate(PyDateTime_Delta *self); + +static Py_hash_t +delta_hash(PyDateTime_Delta *self) +{ + if (self->hashcode == -1) { + PyObject *temp = delta_getstate(self); + if (temp != NULL) { + self->hashcode = PyObject_Hash(temp); + Py_DECREF(temp); + } + } + return self->hashcode; +} + +static PyObject * +delta_multiply(PyObject *left, PyObject *right) +{ + PyObject *result = Py_NotImplemented; + + if (PyDelta_Check(left)) { + /* delta * ??? */ + if (PyLong_Check(right)) + result = multiply_int_timedelta(right, + (PyDateTime_Delta *) left); + else if (PyFloat_Check(right)) + result = multiply_truedivide_timedelta_float( + (PyDateTime_Delta *) left, right, 0); + } + else if (PyLong_Check(left)) + result = multiply_int_timedelta(left, + (PyDateTime_Delta *) right); + else if (PyFloat_Check(left)) + result = multiply_truedivide_timedelta_float( + (PyDateTime_Delta *) right, left, 0); + + if (result == Py_NotImplemented) + Py_INCREF(result); + return result; +} + +static PyObject * +delta_divide(PyObject *left, PyObject *right) +{ + PyObject *result = Py_NotImplemented; + + if (PyDelta_Check(left)) { + /* delta * ??? */ + if (PyLong_Check(right)) + result = divide_timedelta_int( + (PyDateTime_Delta *)left, + right); + else if (PyDelta_Check(right)) + result = divide_timedelta_timedelta( + (PyDateTime_Delta *)left, + (PyDateTime_Delta *)right); + } + + if (result == Py_NotImplemented) + Py_INCREF(result); + return result; +} + +static PyObject * +delta_truedivide(PyObject *left, PyObject *right) +{ + PyObject *result = Py_NotImplemented; + + if (PyDelta_Check(left)) { + if (PyDelta_Check(right)) + result = truedivide_timedelta_timedelta( + (PyDateTime_Delta *)left, + (PyDateTime_Delta *)right); + else if (PyFloat_Check(right)) + result = multiply_truedivide_timedelta_float( + (PyDateTime_Delta *)left, right, 1); + else if (PyLong_Check(right)) + result = truedivide_timedelta_int( + (PyDateTime_Delta *)left, right); + } + + if (result == Py_NotImplemented) + Py_INCREF(result); + return result; +} + +static PyObject * +delta_remainder(PyObject *left, PyObject *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *pyus_remainder; + PyObject *remainder; + + if (!PyDelta_Check(left) || !PyDelta_Check(right)) + Py_RETURN_NOTIMPLEMENTED; + + pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); + if (pyus_right == NULL) { + Py_DECREF(pyus_left); + return NULL; + } + + pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + if (pyus_remainder == NULL) + return NULL; + + remainder = microseconds_to_delta(pyus_remainder); + Py_DECREF(pyus_remainder); + if (remainder == NULL) + return NULL; + + return remainder; +} + +static PyObject * +delta_divmod(PyObject *left, PyObject *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *divmod; + PyObject *delta; + PyObject *result; + + if (!PyDelta_Check(left) || !PyDelta_Check(right)) + Py_RETURN_NOTIMPLEMENTED; + + pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); + if (pyus_right == NULL) { + Py_DECREF(pyus_left); + return NULL; + } + + divmod = checked_divmod(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + if (divmod == NULL) + return NULL; + + delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1)); + if (delta == NULL) { + Py_DECREF(divmod); + return NULL; + } + result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta); + Py_DECREF(delta); + Py_DECREF(divmod); + return result; +} + +/* Fold in the value of the tag ("seconds", "weeks", etc) component of a + * timedelta constructor. sofar is the # of microseconds accounted for + * so far, and there are factor microseconds per current unit, the number + * of which is given by num. num * factor is added to sofar in a + * numerically careful way, and that's the result. Any fractional + * microseconds left over (this can happen if num is a float type) are + * added into *leftover. + * Note that there are many ways this can give an error (NULL) return. + */ +static PyObject * +accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor, + double *leftover) +{ + PyObject *prod; + PyObject *sum; + + assert(num != NULL); + + if (PyLong_Check(num)) { + prod = PyNumber_Multiply(num, factor); + if (prod == NULL) + return NULL; + sum = PyNumber_Add(sofar, prod); + Py_DECREF(prod); + return sum; + } + + if (PyFloat_Check(num)) { + double dnum; + double fracpart; + double intpart; + PyObject *x; + PyObject *y; + + /* The Plan: decompose num into an integer part and a + * fractional part, num = intpart + fracpart. + * Then num * factor == + * intpart * factor + fracpart * factor + * and the LHS can be computed exactly in long arithmetic. + * The RHS is again broken into an int part and frac part. + * and the frac part is added into *leftover. + */ + dnum = PyFloat_AsDouble(num); + if (dnum == -1.0 && PyErr_Occurred()) + return NULL; + fracpart = modf(dnum, &intpart); + x = PyLong_FromDouble(intpart); + if (x == NULL) + return NULL; + + prod = PyNumber_Multiply(x, factor); + Py_DECREF(x); + if (prod == NULL) + return NULL; + + sum = PyNumber_Add(sofar, prod); + Py_DECREF(prod); + if (sum == NULL) + return NULL; + + if (fracpart == 0.0) + return sum; + /* So far we've lost no information. Dealing with the + * fractional part requires float arithmetic, and may + * lose a little info. + */ + assert(PyLong_CheckExact(factor)); + dnum = PyLong_AsDouble(factor); + + dnum *= fracpart; + fracpart = modf(dnum, &intpart); + x = PyLong_FromDouble(intpart); + if (x == NULL) { + Py_DECREF(sum); + return NULL; + } + + y = PyNumber_Add(sum, x); + Py_DECREF(sum); + Py_DECREF(x); + *leftover += fracpart; + return y; + } + + PyErr_Format(PyExc_TypeError, + "unsupported type for timedelta %s component: %s", + tag, Py_TYPE(num)->tp_name); + return NULL; +} + +static PyObject * +delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *self = NULL; + + /* Argument objects. */ + PyObject *day = NULL; + PyObject *second = NULL; + PyObject *us = NULL; + PyObject *ms = NULL; + PyObject *minute = NULL; + PyObject *hour = NULL; + PyObject *week = NULL; + + PyObject *x = NULL; /* running sum of microseconds */ + PyObject *y = NULL; /* temp sum of microseconds */ + double leftover_us = 0.0; + + static char *keywords[] = { + "days", "seconds", "microseconds", "milliseconds", + "minutes", "hours", "weeks", NULL + }; + + if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__", + keywords, + &day, &second, &us, + &ms, &minute, &hour, &week) == 0) + goto Done; + + x = PyLong_FromLong(0); + if (x == NULL) + goto Done; + +#define CLEANUP \ + Py_DECREF(x); \ + x = y; \ + if (x == NULL) \ + goto Done + + if (us) { + y = accum("microseconds", x, us, _PyLong_One, &leftover_us); + CLEANUP; + } + if (ms) { + y = accum("milliseconds", x, ms, us_per_ms, &leftover_us); + CLEANUP; + } + if (second) { + y = accum("seconds", x, second, us_per_second, &leftover_us); + CLEANUP; + } + if (minute) { + y = accum("minutes", x, minute, us_per_minute, &leftover_us); + CLEANUP; + } + if (hour) { + y = accum("hours", x, hour, us_per_hour, &leftover_us); + CLEANUP; + } + if (day) { + y = accum("days", x, day, us_per_day, &leftover_us); + CLEANUP; + } + if (week) { + y = accum("weeks", x, week, us_per_week, &leftover_us); + CLEANUP; + } + if (leftover_us) { + /* Round to nearest whole # of us, and add into x. */ + double whole_us = round(leftover_us); + int x_is_odd; + PyObject *temp; + + if (fabs(whole_us - leftover_us) == 0.5) { + /* We're exactly halfway between two integers. In order + * to do round-half-to-even, we must determine whether x + * is odd. Note that x is odd when it's last bit is 1. The + * code below uses bitwise and operation to check the last + * bit. */ + temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */ + if (temp == NULL) { + Py_DECREF(x); + goto Done; + } + x_is_odd = PyObject_IsTrue(temp); + Py_DECREF(temp); + if (x_is_odd == -1) { + Py_DECREF(x); + goto Done; + } + whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd; + } + + temp = PyLong_FromLong((long)whole_us); + + if (temp == NULL) { + Py_DECREF(x); + goto Done; + } + y = PyNumber_Add(x, temp); + Py_DECREF(temp); + CLEANUP; + } + + self = microseconds_to_delta_ex(x, type); + Py_DECREF(x); +Done: + return self; + +#undef CLEANUP +} + +static int +delta_bool(PyDateTime_Delta *self) +{ + return (GET_TD_DAYS(self) != 0 + || GET_TD_SECONDS(self) != 0 + || GET_TD_MICROSECONDS(self) != 0); +} + +static PyObject * +delta_repr(PyDateTime_Delta *self) +{ + PyObject *args = PyUnicode_FromString(""); + + if (args == NULL) { + return NULL; + } + + const char *sep = ""; + + if (GET_TD_DAYS(self) != 0) { + Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self))); + if (args == NULL) { + return NULL; + } + sep = ", "; + } + + if (GET_TD_SECONDS(self) != 0) { + Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep, + GET_TD_SECONDS(self))); + if (args == NULL) { + return NULL; + } + sep = ", "; + } + + if (GET_TD_MICROSECONDS(self) != 0) { + Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep, + GET_TD_MICROSECONDS(self))); + if (args == NULL) { + return NULL; + } + } + + if (PyUnicode_GET_LENGTH(args) == 0) { + Py_SETREF(args, PyUnicode_FromString("0")); + if (args == NULL) { + return NULL; + } + } + + PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name, + args); + Py_DECREF(args); + return repr; +} + +static PyObject * +delta_str(PyDateTime_Delta *self) +{ + int us = GET_TD_MICROSECONDS(self); + int seconds = GET_TD_SECONDS(self); + int minutes = divmod(seconds, 60, &seconds); + int hours = divmod(minutes, 60, &minutes); + int days = GET_TD_DAYS(self); + + if (days) { + if (us) + return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d", + days, (days == 1 || days == -1) ? "" : "s", + hours, minutes, seconds, us); + else + return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d", + days, (days == 1 || days == -1) ? "" : "s", + hours, minutes, seconds); + } else { + if (us) + return PyUnicode_FromFormat("%d:%02d:%02d.%06d", + hours, minutes, seconds, us); + else + return PyUnicode_FromFormat("%d:%02d:%02d", + hours, minutes, seconds); + } + +} + +/* Pickle support, a simple use of __reduce__. */ + +/* __getstate__ isn't exposed */ +static PyObject * +delta_getstate(PyDateTime_Delta *self) +{ + return Py_BuildValue("iii", GET_TD_DAYS(self), + GET_TD_SECONDS(self), + GET_TD_MICROSECONDS(self)); +} + +static PyObject * +delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *total_seconds; + PyObject *total_microseconds; + + total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self); + if (total_microseconds == NULL) + return NULL; + + total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second); + + Py_DECREF(total_microseconds); + return total_seconds; +} + +static PyObject * +delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored)) +{ + return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self)); +} + +#define OFFSET(field) offsetof(PyDateTime_Delta, field) + +static PyMemberDef delta_members[] = { + + {"days", T_INT, OFFSET(days), READONLY, + PyDoc_STR("Number of days.")}, + + {"seconds", T_INT, OFFSET(seconds), READONLY, + PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")}, + + {"microseconds", T_INT, OFFSET(microseconds), READONLY, + PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")}, + {NULL} +}; + +static PyMethodDef delta_methods[] = { + {"total_seconds", delta_total_seconds, METH_NOARGS, + PyDoc_STR("Total seconds in the duration.")}, + + {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + + {NULL, NULL}, +}; + +static const char delta_doc[] = +PyDoc_STR("Difference between two datetime values.\n\n" + "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, " + "minutes=0, hours=0, weeks=0)\n\n" + "All arguments are optional and default to 0.\n" + "Arguments may be integers or floats, and may be positive or negative."); + +static PyNumberMethods delta_as_number = { + delta_add, /* nb_add */ + delta_subtract, /* nb_subtract */ + delta_multiply, /* nb_multiply */ + delta_remainder, /* nb_remainder */ + delta_divmod, /* nb_divmod */ + 0, /* nb_power */ + (unaryfunc)delta_negative, /* nb_negative */ + (unaryfunc)delta_positive, /* nb_positive */ + (unaryfunc)delta_abs, /* nb_absolute */ + (inquiry)delta_bool, /* nb_bool */ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + 0, /*nb_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + 0, /*nb_inplace_add*/ + 0, /*nb_inplace_subtract*/ + 0, /*nb_inplace_multiply*/ + 0, /*nb_inplace_remainder*/ + 0, /*nb_inplace_power*/ + 0, /*nb_inplace_lshift*/ + 0, /*nb_inplace_rshift*/ + 0, /*nb_inplace_and*/ + 0, /*nb_inplace_xor*/ + 0, /*nb_inplace_or*/ + delta_divide, /* nb_floor_divide */ + delta_truedivide, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ +}; + +static PyTypeObject PyDateTime_DeltaType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.timedelta", /* tp_name */ + sizeof(PyDateTime_Delta), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)delta_repr, /* tp_repr */ + &delta_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)delta_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)delta_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + delta_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + delta_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + delta_methods, /* tp_methods */ + delta_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + delta_new, /* tp_new */ + 0, /* tp_free */ +}; + +/* + * PyDateTime_Date implementation. + */ + +/* Accessor properties. */ + +static PyObject * +date_year(PyDateTime_Date *self, void *unused) +{ + return PyLong_FromLong(GET_YEAR(self)); +} + +static PyObject * +date_month(PyDateTime_Date *self, void *unused) +{ + return PyLong_FromLong(GET_MONTH(self)); +} + +static PyObject * +date_day(PyDateTime_Date *self, void *unused) +{ + return PyLong_FromLong(GET_DAY(self)); +} + +static PyGetSetDef date_getset[] = { + {"year", (getter)date_year}, + {"month", (getter)date_month}, + {"day", (getter)date_day}, + {NULL} +}; + +/* Constructors. */ + +static char *date_kws[] = {"year", "month", "day", NULL}; + +static PyObject * +date_from_pickle(PyTypeObject *type, PyObject *state) +{ + PyDateTime_Date *me; + + me = (PyDateTime_Date *) (type->tp_alloc(type, 0)); + if (me != NULL) { + const char *pdata = PyBytes_AS_STRING(state); + memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE); + me->hashcode = -1; + } + return (PyObject *)me; +} + +static PyObject * +date_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *self = NULL; + int year; + int month; + int day; + + /* Check for invocation from pickle with __getstate__ state */ + if (PyTuple_GET_SIZE(args) == 1) { + PyObject *state = PyTuple_GET_ITEM(args, 0); + if (PyBytes_Check(state)) { + if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE && + MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) + { + return date_from_pickle(type, state); + } + } + else if (PyUnicode_Check(state)) { + if (PyUnicode_READY(state)) { + return NULL; + } + if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE && + MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2))) + { + state = PyUnicode_AsLatin1String(state); + if (state == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + /* More informative error message. */ + PyErr_SetString(PyExc_ValueError, + "Failed to encode latin1 string when unpickling " + "a date object. " + "pickle.load(data, encoding='latin1') is assumed."); + } + return NULL; + } + self = date_from_pickle(type, state); + Py_DECREF(state); + return self; + } + } + } + + if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws, + &year, &month, &day)) { + self = new_date_ex(year, month, day, type); + } + return self; +} + +static PyObject * +date_fromtimestamp(PyObject *cls, PyObject *obj) +{ + struct tm tm; + time_t t; + + if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1) + return NULL; + + if (_PyTime_localtime(t, &tm) != 0) + return NULL; + + return new_date_subclass_ex(tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + cls); +} + +/* Return new date from current time. + * We say this is equivalent to fromtimestamp(time.time()), and the + * only way to be sure of that is to *call* time.time(). That's not + * generally the same as calling C's time. + */ +static PyObject * +date_today(PyObject *cls, PyObject *dummy) +{ + PyObject *time; + PyObject *result; + _Py_IDENTIFIER(fromtimestamp); + + time = time_time(); + if (time == NULL) + return NULL; + + /* Note well: today() is a class method, so this may not call + * date.fromtimestamp. For example, it may call + * datetime.fromtimestamp. That's why we need all the accuracy + * time.time() delivers; if someone were gonzo about optimization, + * date.today() could get away with plain C time(). + */ + result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time); + Py_DECREF(time); + return result; +} + +/*[clinic input] +@classmethod +datetime.date.fromtimestamp -/* --------------------------------------------------------------------------- - * Math utilities. - */ + timestamp: object + / -/* k = i+j overflows iff k differs in sign from both inputs, - * iff k^i has sign bit set and k^j has sign bit set, - * iff (k^i)&(k^j) has sign bit set. - */ -#define SIGNED_ADD_OVERFLOWED(RESULT, I, J) \ - ((((RESULT) ^ (I)) & ((RESULT) ^ (J))) < 0) +Create a date from a POSIX timestamp. -/* Compute Python divmod(x, y), returning the quotient and storing the - * remainder into *r. The quotient is the floor of x/y, and that's - * the real point of this. C will probably truncate instead (C99 - * requires truncation; C89 left it implementation-defined). - * Simplification: we *require* that y > 0 here. That's appropriate - * for all the uses made of it. This simplifies the code and makes - * the overflow case impossible (divmod(LONG_MIN, -1) is the only - * overflow case). - */ -static int -divmod(int x, int y, int *r) -{ - int quo; +The timestamp is a number, e.g. created via time.time(), that is interpreted +as local time. +[clinic start generated code]*/ - assert(y > 0); - quo = x / y; - *r = x - quo * y; - if (*r < 0) { - --quo; - *r += y; - } - assert(0 <= *r && *r < y); - return quo; +static PyObject * +datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp) +/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/ +{ + return date_fromtimestamp((PyObject *) type, timestamp); } -/* Nearest integer to m / n for integers m and n. Half-integer results - * are rounded to even. +/* bpo-36025: This is a wrapper for API compatibility with the public C API, + * which expects a function that takes an *args tuple, whereas the argument + * clinic generates code that takes METH_O. */ static PyObject * -divide_nearest(PyObject *m, PyObject *n) -{ - PyObject *result; - PyObject *temp; - - temp = _PyLong_DivmodNear(m, n); - if (temp == NULL) - return NULL; - result = PyTuple_GET_ITEM(temp, 0); - Py_INCREF(result); - Py_DECREF(temp); - - return result; -} - -/* --------------------------------------------------------------------------- - * General calendrical helper functions - */ - -/* For each month ordinal in 1..12, the number of days in that month, - * and the number of days before that month in the same year. These - * are correct for non-leap years only. - */ -static const int _days_in_month[] = { - 0, /* unused; this vector uses 1-based indexing */ - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -static const int _days_before_month[] = { - 0, /* unused; this vector uses 1-based indexing */ - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 -}; - -/* year -> 1 if leap year, else 0. */ -static int -is_leap(int year) -{ - /* Cast year to unsigned. The result is the same either way, but - * C can generate faster code for unsigned mod than for signed - * mod (especially for % 4 -- a good compiler should just grab - * the last 2 bits when the LHS is unsigned). - */ - const unsigned int ayear = (unsigned int)year; - return ayear % 4 == 0 && (ayear % 100 != 0 || ayear % 400 == 0); -} - -/* year, month -> number of days in that month in that year */ -static int -days_in_month(int year, int month) -{ - assert(month >= 1); - assert(month <= 12); - if (month == 2 && is_leap(year)) - return 29; - else - return _days_in_month[month]; -} - -/* year, month -> number of days in year preceding first day of month */ -static int -days_before_month(int year, int month) -{ - int days; - - assert(month >= 1); - assert(month <= 12); - days = _days_before_month[month]; - if (month > 2 && is_leap(year)) - ++days; - return days; -} - -/* year -> number of days before January 1st of year. Remember that we - * start with year 1, so days_before_year(1) == 0. - */ -static int -days_before_year(int year) +datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args) { - int y = year - 1; - /* This is incorrect if year <= 0; we really want the floor - * here. But so long as MINYEAR is 1, the smallest year this - * can see is 1. - */ - assert (year >= 1); - return y*365 + y/4 - y/100 + y/400; -} + PyObject *timestamp; + PyObject *result = NULL; + + if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, ×tamp)) { + result = date_fromtimestamp(cls, timestamp); + } -/* Number of days in 4, 100, and 400 year cycles. That these have - * the correct values is asserted in the module init function. - */ -#define DI4Y 1461 /* days_before_year(5); days in 4 years */ -#define DI100Y 36524 /* days_before_year(101); days in 100 years */ -#define DI400Y 146097 /* days_before_year(401); days in 400 years */ + return result; +} + +/* Return new date from proleptic Gregorian ordinal. Raises ValueError if + * the ordinal is out of range. + */ +static PyObject * +date_fromordinal(PyObject *cls, PyObject *args) +{ + PyObject *result = NULL; + int ordinal; + + if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) { + int year; + int month; + int day; + + if (ordinal < 1) + PyErr_SetString(PyExc_ValueError, "ordinal must be " + ">= 1"); + else { + ord_to_ymd(ordinal, &year, &month, &day); + result = new_date_subclass_ex(year, month, day, cls); + } + } + return result; +} + +/* Return the new date from a string as generated by date.isoformat() */ +static PyObject * +date_fromisoformat(PyObject *cls, PyObject *dtstr) +{ + assert(dtstr != NULL); + + if (!PyUnicode_Check(dtstr)) { + PyErr_SetString(PyExc_TypeError, + "fromisoformat: argument must be str"); + return NULL; + } + + Py_ssize_t len; + + const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len); + if (dt_ptr == NULL) { + goto invalid_string_error; + } + + int year = 0, month = 0, day = 0; + + int rv; + if (len == 10) { + rv = parse_isoformat_date(dt_ptr, &year, &month, &day); + } + else { + rv = -1; + } + + if (rv < 0) { + goto invalid_string_error; + } + + return new_date_subclass_ex(year, month, day, cls); + +invalid_string_error: + PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr); + return NULL; +} + -/* ordinal -> year, month, day, considering 01-Jan-0001 as day 1. */ -static void -ord_to_ymd(int ordinal, int *year, int *month, int *day) +static PyObject * +date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) { - int n, n1, n4, n100, n400, leapyear, preceding; + static char *keywords[] = { + "year", "week", "day", NULL + }; - /* ordinal is a 1-based index, starting at 1-Jan-1. The pattern of - * leap years repeats exactly every 400 years. The basic strategy is - * to find the closest 400-year boundary at or before ordinal, then - * work with the offset from that boundary to ordinal. Life is much - * clearer if we subtract 1 from ordinal first -- then the values - * of ordinal at 400-year boundaries are exactly those divisible - * by DI400Y: - * - * D M Y n n-1 - * -- --- ---- ---------- ---------------- - * 31 Dec -400 -DI400Y -DI400Y -1 - * 1 Jan -399 -DI400Y +1 -DI400Y 400-year boundary - * ... - * 30 Dec 000 -1 -2 - * 31 Dec 000 0 -1 - * 1 Jan 001 1 0 400-year boundary - * 2 Jan 001 2 1 - * 3 Jan 001 3 2 - * ... - * 31 Dec 400 DI400Y DI400Y -1 - * 1 Jan 401 DI400Y +1 DI400Y 400-year boundary - */ - assert(ordinal >= 1); - --ordinal; - n400 = ordinal / DI400Y; - n = ordinal % DI400Y; - *year = n400 * 400 + 1; + int year, week, day; + if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar", + keywords, + &year, &week, &day) == 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Format(PyExc_ValueError, + "ISO calendar component out of range"); - /* Now n is the (non-negative) offset, in days, from January 1 of - * year, to the desired date. Now compute how many 100-year cycles - * precede n. - * Note that it's possible for n100 to equal 4! In that case 4 full - * 100-year cycles precede the desired day, which implies the - * desired day is December 31 at the end of a 400-year cycle. - */ - n100 = n / DI100Y; - n = n % DI100Y; + } + return NULL; + } - /* Now compute how many 4-year cycles precede it. */ - n4 = n / DI4Y; - n = n % DI4Y; + // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5) + if (year < MINYEAR || year > MAXYEAR) { + PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year); + return NULL; + } - /* And now how many single years. Again n1 can be 4, and again - * meaning that the desired day is December 31 at the end of the - * 4-year cycle. - */ - n1 = n / 365; - n = n % 365; + if (week <= 0 || week >= 53) { + int out_of_range = 1; + if (week == 53) { + // ISO years have 53 weeks in it on years starting with a Thursday + // and on leap years starting on Wednesday + int first_weekday = weekday(year, 1, 1); + if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) { + out_of_range = 0; + } + } - *year += n100 * 100 + n4 * 4 + n1; - if (n1 == 4 || n100 == 4) { - assert(n == 0); - *year -= 1; - *month = 12; - *day = 31; - return; + if (out_of_range) { + PyErr_Format(PyExc_ValueError, "Invalid week: %d", week); + return NULL; + } } - /* Now the year is correct, and n is the offset from January 1. We - * find the month via an estimate that's either exact or one too - * large. - */ - leapyear = n1 == 3 && (n4 != 24 || n100 == 3); - assert(leapyear == is_leap(*year)); - *month = (n + 50) >> 5; - preceding = (_days_before_month[*month] + (*month > 2 && leapyear)); - if (preceding > n) { - /* estimate is too large */ - *month -= 1; - preceding -= days_in_month(*year, *month); + if (day <= 0 || day >= 8) { + PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])", + day); + return NULL; } - n -= preceding; - assert(0 <= n); - assert(n < days_in_month(*year, *month)); - *day = n + 1; -} - -/* year, month, day -> ordinal, considering 01-Jan-0001 as day 1. */ -static int -ymd_to_ord(int year, int month, int day) -{ - return days_before_year(year) + days_before_month(year, month) + day; -} + // Convert (Y, W, D) to (Y, M, D) in-place + int day_1 = iso_week1_monday(year); -/* Day of week, where Monday==0, ..., Sunday==6. 1/1/1 was a Monday. */ -static int -weekday(int year, int month, int day) -{ - return (ymd_to_ord(year, month, day) + 6) % 7; -} + int month = week; + int day_offset = (month - 1)*7 + day - 1; -/* Ordinal of the Monday starting week 1 of the ISO year. Week 1 is the - * first calendar week containing a Thursday. - */ -static int -iso_week1_monday(int year) -{ - int first_day = ymd_to_ord(year, 1, 1); /* ord of 1/1 */ - /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */ - int first_weekday = (first_day + 6) % 7; - /* ordinal of closest Monday at or before 1/1 */ - int week1_monday = first_day - first_weekday; + ord_to_ymd(day_1 + day_offset, &year, &month, &day); - if (first_weekday > 3) /* if 1/1 was Fri, Sat, Sun */ - week1_monday += 7; - return week1_monday; + return new_date_subclass_ex(year, month, day, cls); } -/* --------------------------------------------------------------------------- - * Range checkers. - */ - -/* Check that -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS. If so, return 0. - * If not, raise OverflowError and return -1. - */ -static int -check_delta_day_range(int days) -{ - if (-MAX_DELTA_DAYS <= days && days <= MAX_DELTA_DAYS) - return 0; - PyErr_Format(PyExc_OverflowError, - "days=%d; must have magnitude <= %d", - days, MAX_DELTA_DAYS); - return -1; -} -/* Check that date arguments are in range. Return 0 if they are. If they - * aren't, raise ValueError and return -1. - */ -static int -check_date_args(int year, int month, int day) -{ +/* + * Date arithmetic. + */ + +/* date + timedelta -> date. If arg negate is true, subtract the timedelta + * instead. + */ +static PyObject * +add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate) +{ + PyObject *result = NULL; + int year = GET_YEAR(date); + int month = GET_MONTH(date); + int deltadays = GET_TD_DAYS(delta); + /* C-level overflow is impossible because |deltadays| < 1e9. */ + int day = GET_DAY(date) + (negate ? -deltadays : deltadays); + + if (normalize_date(&year, &month, &day) >= 0) + result = new_date_subclass_ex(year, month, day, + (PyObject* )Py_TYPE(date)); + return result; +} + +static PyObject * +date_add(PyObject *left, PyObject *right) +{ + if (PyDateTime_Check(left) || PyDateTime_Check(right)) + Py_RETURN_NOTIMPLEMENTED; + + if (PyDate_Check(left)) { + /* date + ??? */ + if (PyDelta_Check(right)) + /* date + delta */ + return add_date_timedelta((PyDateTime_Date *) left, + (PyDateTime_Delta *) right, + 0); + } + else { + /* ??? + date + * 'right' must be one of us, or we wouldn't have been called + */ + if (PyDelta_Check(left)) + /* delta + date */ + return add_date_timedelta((PyDateTime_Date *) right, + (PyDateTime_Delta *) left, + 0); + } + Py_RETURN_NOTIMPLEMENTED; +} + +static PyObject * +date_subtract(PyObject *left, PyObject *right) +{ + if (PyDateTime_Check(left) || PyDateTime_Check(right)) + Py_RETURN_NOTIMPLEMENTED; + + if (PyDate_Check(left)) { + if (PyDate_Check(right)) { + /* date - date */ + int left_ord = ymd_to_ord(GET_YEAR(left), + GET_MONTH(left), + GET_DAY(left)); + int right_ord = ymd_to_ord(GET_YEAR(right), + GET_MONTH(right), + GET_DAY(right)); + return new_delta(left_ord - right_ord, 0, 0, 0); + } + if (PyDelta_Check(right)) { + /* date - delta */ + return add_date_timedelta((PyDateTime_Date *) left, + (PyDateTime_Delta *) right, + 1); + } + } + Py_RETURN_NOTIMPLEMENTED; +} + + +/* Various ways to turn a date into a string. */ + +static PyObject * +date_repr(PyDateTime_Date *self) +{ + return PyUnicode_FromFormat("%s(%d, %d, %d)", + Py_TYPE(self)->tp_name, + GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); +} + +static PyObject * +date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) +{ + return PyUnicode_FromFormat("%04d-%02d-%02d", + GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); +} + +/* str() calls the appropriate isoformat() method. */ +static PyObject * +date_str(PyDateTime_Date *self) +{ + return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); +} + + +static PyObject * +date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) +{ + return format_ctime(self, 0, 0, 0); +} + +static PyObject * +date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) +{ + /* This method can be inherited, and needs to call the + * timetuple() method appropriate to self's class. + */ + PyObject *result; + PyObject *tuple; + PyObject *format; + _Py_IDENTIFIER(timetuple); + static char *keywords[] = {"format", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, + &format)) + return NULL; + + tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple); + if (tuple == NULL) + return NULL; + result = wrap_strftime((PyObject *)self, format, tuple, + (PyObject *)self); + Py_DECREF(tuple); + return result; +} + +static PyObject * +date_format(PyDateTime_Date *self, PyObject *args) +{ + PyObject *format; + + if (!PyArg_ParseTuple(args, "U:__format__", &format)) + return NULL; + + /* if the format is zero length, return str(self) */ + if (PyUnicode_GetLength(format) == 0) + return PyObject_Str((PyObject *)self); + + return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime, + format); +} + +/* ISO methods. */ + +static PyObject * +date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) +{ + int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); + + return PyLong_FromLong(dow + 1); +} + +PyDoc_STRVAR(iso_calendar_date__doc__, +"The result of date.isocalendar() or datetime.isocalendar()\n\n\ +This object may be accessed either as a tuple of\n\ + ((year, week, weekday)\n\ +or via the object attributes as named in the above tuple."); - if (year < MINYEAR || year > MAXYEAR) { - PyErr_Format(PyExc_ValueError, "year %i is out of range", year); - return -1; - } - if (month < 1 || month > 12) { - PyErr_SetString(PyExc_ValueError, - "month must be in 1..12"); - return -1; - } - if (day < 1 || day > days_in_month(year, month)) { - PyErr_SetString(PyExc_ValueError, - "day is out of range for month"); - return -1; - } - return 0; -} +typedef struct { + PyTupleObject tuple; +} PyDateTime_IsoCalendarDate; -/* Check that time arguments are in range. Return 0 if they are. If they - * aren't, raise ValueError and return -1. - */ -static int -check_time_args(int h, int m, int s, int us, int fold) +static PyObject * +iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self) { - if (h < 0 || h > 23) { - PyErr_SetString(PyExc_ValueError, - "hour must be in 0..23"); - return -1; - } - if (m < 0 || m > 59) { - PyErr_SetString(PyExc_ValueError, - "minute must be in 0..59"); - return -1; - } - if (s < 0 || s > 59) { - PyErr_SetString(PyExc_ValueError, - "second must be in 0..59"); - return -1; + PyObject* year = PyTuple_GetItem((PyObject *)self, 0); + if (year == NULL) { + return NULL; } - if (us < 0 || us > 999999) { - PyErr_SetString(PyExc_ValueError, - "microsecond must be in 0..999999"); - return -1; + PyObject* week = PyTuple_GetItem((PyObject *)self, 1); + if (week == NULL) { + return NULL; } - if (fold != 0 && fold != 1) { - PyErr_SetString(PyExc_ValueError, - "fold must be either 0 or 1"); - return -1; + PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2); + if (weekday == NULL) { + return NULL; } - return 0; -} - -/* --------------------------------------------------------------------------- - * Normalization utilities. - */ -/* One step of a mixed-radix conversion. A "hi" unit is equivalent to - * factor "lo" units. factor must be > 0. If *lo is less than 0, or - * at least factor, enough of *lo is converted into "hi" units so that - * 0 <= *lo < factor. The input values must be such that int overflow - * is impossible. - */ -static void -normalize_pair(int *hi, int *lo, int factor) -{ - assert(factor > 0); - assert(lo != hi); - if (*lo < 0 || *lo >= factor) { - const int num_hi = divmod(*lo, factor, lo); - const int new_hi = *hi + num_hi; - assert(! SIGNED_ADD_OVERFLOWED(new_hi, *hi, num_hi)); - *hi = new_hi; - } - assert(0 <= *lo && *lo < factor); + return PyUnicode_FromFormat("%.200s(year=%S, week=%S, weekday=%S)", + Py_TYPE(self)->tp_name, year, week, weekday); } -/* Fiddle days (d), seconds (s), and microseconds (us) so that - * 0 <= *s < 24*3600 - * 0 <= *us < 1000000 - * The input values must be such that the internals don't overflow. - * The way this routine is used, we don't get close. - */ -static void -normalize_d_s_us(int *d, int *s, int *us) +static PyObject * +iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) { - if (*us < 0 || *us >= 1000000) { - normalize_pair(s, us, 1000000); - /* |s| can't be bigger than about - * |original s| + |original us|/1000000 now. - */ + // Construct the tuple that this reduces to + PyObject * reduce_tuple = Py_BuildValue( + "O((OOO))", &PyTuple_Type, + PyTuple_GET_ITEM(self, 0), + PyTuple_GET_ITEM(self, 1), + PyTuple_GET_ITEM(self, 2) + ); - } - if (*s < 0 || *s >= 24*3600) { - normalize_pair(d, s, 24*3600); - /* |d| can't be bigger than about - * |original d| + - * (|original s| + |original us|/1000000) / (24*3600) now. - */ - } - assert(0 <= *s && *s < 24*3600); - assert(0 <= *us && *us < 1000000); + return reduce_tuple; } -/* Fiddle years (y), months (m), and days (d) so that - * 1 <= *m <= 12 - * 1 <= *d <= days_in_month(*y, *m) - * The input values must be such that the internals don't overflow. - * The way this routine is used, we don't get close. - */ -static int -normalize_y_m_d(int *y, int *m, int *d) +static PyObject * +iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused) { - int dim; /* # of days in month */ - - /* In actual use, m is always the month component extracted from a - * date/datetime object. Therefore it is always in [1, 12] range. - */ - - assert(1 <= *m && *m <= 12); - - /* Now only day can be out of bounds (year may also be out of bounds - * for a datetime object, but we don't care about that here). - * If day is out of bounds, what to do is arguable, but at least the - * method here is principled and explainable. - */ - dim = days_in_month(*y, *m); - if (*d < 1 || *d > dim) { - /* Move day-1 days from the first of the month. First try to - * get off cheap if we're only one day out of range - * (adjustments for timezone alone can't be worse than that). - */ - if (*d == 0) { - --*m; - if (*m > 0) - *d = days_in_month(*y, *m); - else { - --*y; - *m = 12; - *d = 31; - } - } - else if (*d == dim + 1) { - /* move forward a day */ - ++*m; - *d = 1; - if (*m > 12) { - *m = 1; - ++*y; - } - } - else { - int ordinal = ymd_to_ord(*y, *m, 1) + - *d - 1; - if (ordinal < 1 || ordinal > MAXORDINAL) { - goto error; - } else { - ord_to_ymd(ordinal, y, m, d); - return 0; - } - } + PyObject *year = PyTuple_GetItem((PyObject *)self, 0); + if (year == NULL) { + return NULL; } - assert(*m > 0); - assert(*d > 0); - if (MINYEAR <= *y && *y <= MAXYEAR) - return 0; - error: - PyErr_SetString(PyExc_OverflowError, - "date value out of range"); - return -1; - -} - -/* Fiddle out-of-bounds months and days so that the result makes some kind - * of sense. The parameters are both inputs and outputs. Returns < 0 on - * failure, where failure means the adjusted year is out of bounds. - */ -static int -normalize_date(int *year, int *month, int *day) -{ - return normalize_y_m_d(year, month, day); + Py_INCREF(year); + return year; } -/* Force all the datetime fields into range. The parameters are both - * inputs and outputs. Returns < 0 on error. - */ -static int -normalize_datetime(int *year, int *month, int *day, - int *hour, int *minute, int *second, - int *microsecond) +static PyObject * +iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused) { - normalize_pair(second, microsecond, 1000000); - normalize_pair(minute, second, 60); - normalize_pair(hour, minute, 60); - normalize_pair(day, hour, 24); - return normalize_date(year, month, day); + PyObject *week = PyTuple_GetItem((PyObject *)self, 1); + if (week == NULL) { + return NULL; + } + Py_INCREF(week); + return week; } -/* --------------------------------------------------------------------------- - * Basic object allocation: tp_alloc implementations. These allocate - * Python objects of the right size and type, and do the Python object- - * initialization bit. If there's not enough memory, they return NULL after - * setting MemoryError. All data members remain uninitialized trash. - * - * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo - * member is needed. This is ugly, imprecise, and possibly insecure. - * tp_basicsize for the time and datetime types is set to the size of the - * struct that has room for the tzinfo member, so subclasses in Python will - * allocate enough space for a tzinfo member whether or not one is actually - * needed. That's the "ugly and imprecise" parts. The "possibly insecure" - * part is that PyType_GenericAlloc() (which subclasses in Python end up - * using) just happens today to effectively ignore the nitems argument - * when tp_itemsize is 0, which it is for these type objects. If that - * changes, perhaps the callers of tp_alloc slots in this file should - * be changed to force a 0 nitems argument unless the type being allocated - * is a base type implemented in this file (so that tp_alloc is time_alloc - * or datetime_alloc below, which know about the nitems abuse). - */ - static PyObject * -time_alloc(PyTypeObject *type, Py_ssize_t aware) +iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused) { - PyObject *self; - - self = (PyObject *) - PyObject_MALLOC(aware ? - sizeof(PyDateTime_Time) : - sizeof(_PyDateTime_BaseTime)); - if (self == NULL) - return (PyObject *)PyErr_NoMemory(); - (void)PyObject_INIT(self, type); - return self; + PyObject *weekday = PyTuple_GetItem((PyObject *)self, 2); + if (weekday == NULL) { + return NULL; + } + Py_INCREF(weekday); + return weekday; } -static PyObject * -datetime_alloc(PyTypeObject *type, Py_ssize_t aware) -{ - PyObject *self; - - self = (PyObject *) - PyObject_MALLOC(aware ? - sizeof(PyDateTime_DateTime) : - sizeof(_PyDateTime_BaseDateTime)); - if (self == NULL) - return (PyObject *)PyErr_NoMemory(); - (void)PyObject_INIT(self, type); - return self; -} - -/* --------------------------------------------------------------------------- - * Helpers for setting object fields. These work on pointers to the - * appropriate base class. - */ - -/* For date and datetime. */ -static void -set_date_fields(PyDateTime_Date *self, int y, int m, int d) -{ - self->hashcode = -1; - SET_YEAR(self, y); - SET_MONTH(self, m); - SET_DAY(self, d); -} - -/* --------------------------------------------------------------------------- - * String parsing utilities and helper functions - */ - -static const char * -parse_digits(const char *ptr, int *var, size_t num_digits) -{ - for (size_t i = 0; i < num_digits; ++i) { - unsigned int tmp = (unsigned int)(*(ptr++) - '0'); - if (tmp > 9) { - return NULL; - } - *var *= 10; - *var += (signed int)tmp; - } - - return ptr; -} - -static int -parse_isoformat_date(const char *dtstr, int *year, int *month, int *day) -{ - /* Parse the date components of the result of date.isoformat() - * - * Return codes: - * 0: Success - * -1: Failed to parse date component - * -2: Failed to parse dateseparator - */ - const char *p = dtstr; - p = parse_digits(p, year, 4); - if (NULL == p) { - return -1; - } - - if (*(p++) != '-') { - return -2; - } - - p = parse_digits(p, month, 2); - if (NULL == p) { - return -1; - } - - if (*(p++) != '-') { - return -2; - } - - p = parse_digits(p, day, 2); - if (p == NULL) { - return -1; - } - - return 0; -} - -static int -parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, - int *minute, int *second, int *microsecond) -{ - const char *p = tstr; - const char *p_end = tstr_end; - int *vals[3] = {hour, minute, second}; - - // Parse [HH[:MM[:SS]]] - for (size_t i = 0; i < 3; ++i) { - p = parse_digits(p, vals[i], 2); - if (NULL == p) { - return -3; - } - - char c = *(p++); - if (p >= p_end) { - return c != '\0'; - } - else if (c == ':') { - continue; - } - else if (c == '.') { - break; - } - else { - return -4; // Malformed time separator - } - } - - // Parse .fff[fff] - size_t len_remains = p_end - p; - if (!(len_remains == 6 || len_remains == 3)) { - return -3; - } - - p = parse_digits(p, microsecond, len_remains); - if (NULL == p) { - return -3; - } - - if (len_remains == 3) { - *microsecond *= 1000; - } - - // Return 1 if it's not the end of the string - return *p != '\0'; -} - -static int -parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute, - int *second, int *microsecond, int *tzoffset, - int *tzmicrosecond) -{ - // Parse the time portion of a datetime.isoformat() string - // - // Return codes: - // 0: Success (no tzoffset) - // 1: Success (with tzoffset) - // -3: Failed to parse time component - // -4: Failed to parse time separator - // -5: Malformed timezone string - - const char *p = dtstr; - const char *p_end = dtstr + dtlen; - - const char *tzinfo_pos = p; - do { - if (*tzinfo_pos == '+' || *tzinfo_pos == '-') { - break; - } - } while (++tzinfo_pos < p_end); - - int rv = parse_hh_mm_ss_ff(dtstr, tzinfo_pos, hour, minute, second, - microsecond); - - if (rv < 0) { - return rv; - } - else if (tzinfo_pos == p_end) { - // We know that there's no time zone, so if there's stuff at the - // end of the string it's an error. - if (rv == 1) { - return -5; - } - else { - return 0; - } - } - - // Parse time zone component - // Valid formats are: - // - +HH:MM (len 6) - // - +HH:MM:SS (len 9) - // - +HH:MM:SS.ffffff (len 16) - size_t tzlen = p_end - tzinfo_pos; - if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) { - return -5; - } - - int tzsign = (*tzinfo_pos == '-') ? -1 : 1; - tzinfo_pos++; - int tzhour = 0, tzminute = 0, tzsecond = 0; - rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond, - tzmicrosecond); - - *tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond); - *tzmicrosecond *= tzsign; - - return rv ? -5 : 1; -} - -/* --------------------------------------------------------------------------- - * Create various objects, mostly without range checking. - */ - -/* Create a date instance with no range checking. */ -static PyObject * -new_date_ex(int year, int month, int day, PyTypeObject *type) -{ - PyDateTime_Date *self; - - if (check_date_args(year, month, day) < 0) { - return NULL; - } - - self = (PyDateTime_Date *)(type->tp_alloc(type, 0)); - if (self != NULL) - set_date_fields(self, year, month, day); - return (PyObject *)self; -} - -#define new_date(year, month, day) \ - new_date_ex(year, month, day, &PyDateTime_DateType) - -// Forward declaration -static PyObject * -new_datetime_ex(int, int, int, int, int, int, int, PyObject *, PyTypeObject *); - -/* Create date instance with no range checking, or call subclass constructor */ -static PyObject * -new_date_subclass_ex(int year, int month, int day, PyObject *cls) -{ - PyObject *result; - // We have "fast path" constructors for two subclasses: date and datetime - if ((PyTypeObject *)cls == &PyDateTime_DateType) { - result = new_date_ex(year, month, day, (PyTypeObject *)cls); - } - else if ((PyTypeObject *)cls == &PyDateTime_DateTimeType) { - result = new_datetime_ex(year, month, day, 0, 0, 0, 0, Py_None, - (PyTypeObject *)cls); - } - else { - result = PyObject_CallFunction(cls, "iii", year, month, day); - } - - return result; -} - -/* Create a datetime instance with no range checking. */ -static PyObject * -new_datetime_ex2(int year, int month, int day, int hour, int minute, - int second, int usecond, PyObject *tzinfo, int fold, PyTypeObject *type) -{ - PyDateTime_DateTime *self; - char aware = tzinfo != Py_None; - - if (check_date_args(year, month, day) < 0) { - return NULL; - } - if (check_time_args(hour, minute, second, usecond, fold) < 0) { - return NULL; - } - if (check_tzinfo_subclass(tzinfo) < 0) { - return NULL; - } - - self = (PyDateTime_DateTime *) (type->tp_alloc(type, aware)); - if (self != NULL) { - self->hastzinfo = aware; - set_date_fields((PyDateTime_Date *)self, year, month, day); - DATE_SET_HOUR(self, hour); - DATE_SET_MINUTE(self, minute); - DATE_SET_SECOND(self, second); - DATE_SET_MICROSECOND(self, usecond); - if (aware) { - Py_INCREF(tzinfo); - self->tzinfo = tzinfo; - } - DATE_SET_FOLD(self, fold); - } - return (PyObject *)self; -} - -static PyObject * -new_datetime_ex(int year, int month, int day, int hour, int minute, - int second, int usecond, PyObject *tzinfo, PyTypeObject *type) -{ - return new_datetime_ex2(year, month, day, hour, minute, second, usecond, - tzinfo, 0, type); -} - -#define new_datetime(y, m, d, hh, mm, ss, us, tzinfo, fold) \ - new_datetime_ex2(y, m, d, hh, mm, ss, us, tzinfo, fold, \ - &PyDateTime_DateTimeType) - -static PyObject * -new_datetime_subclass_fold_ex(int year, int month, int day, int hour, int minute, - int second, int usecond, PyObject *tzinfo, - int fold, PyObject *cls) { - PyObject* dt; - if ((PyTypeObject*)cls == &PyDateTime_DateTimeType) { - // Use the fast path constructor - dt = new_datetime(year, month, day, hour, minute, second, usecond, - tzinfo, fold); - } else { - // Subclass - dt = PyObject_CallFunction(cls, "iiiiiiiO", - year, - month, - day, - hour, - minute, - second, - usecond, - tzinfo); - } - - return dt; -} - -static PyObject * -new_datetime_subclass_ex(int year, int month, int day, int hour, int minute, - int second, int usecond, PyObject *tzinfo, - PyObject *cls) { - return new_datetime_subclass_fold_ex(year, month, day, hour, minute, - second, usecond, tzinfo, 0, - cls); -} - -/* Create a time instance with no range checking. */ -static PyObject * -new_time_ex2(int hour, int minute, int second, int usecond, - PyObject *tzinfo, int fold, PyTypeObject *type) -{ - PyDateTime_Time *self; - char aware = tzinfo != Py_None; - - if (check_time_args(hour, minute, second, usecond, fold) < 0) { - return NULL; - } - if (check_tzinfo_subclass(tzinfo) < 0) { - return NULL; - } - - self = (PyDateTime_Time *) (type->tp_alloc(type, aware)); - if (self != NULL) { - self->hastzinfo = aware; - self->hashcode = -1; - TIME_SET_HOUR(self, hour); - TIME_SET_MINUTE(self, minute); - TIME_SET_SECOND(self, second); - TIME_SET_MICROSECOND(self, usecond); - if (aware) { - Py_INCREF(tzinfo); - self->tzinfo = tzinfo; - } - TIME_SET_FOLD(self, fold); - } - return (PyObject *)self; -} - -static PyObject * -new_time_ex(int hour, int minute, int second, int usecond, - PyObject *tzinfo, PyTypeObject *type) -{ - return new_time_ex2(hour, minute, second, usecond, tzinfo, 0, type); -} - -#define new_time(hh, mm, ss, us, tzinfo, fold) \ - new_time_ex2(hh, mm, ss, us, tzinfo, fold, &PyDateTime_TimeType) - -/* Create a timedelta instance. Normalize the members iff normalize is - * true. Passing false is a speed optimization, if you know for sure - * that seconds and microseconds are already in their proper ranges. In any - * case, raises OverflowError and returns NULL if the normalized days is out - * of range. - */ -static PyObject * -new_delta_ex(int days, int seconds, int microseconds, int normalize, - PyTypeObject *type) -{ - PyDateTime_Delta *self; - - if (normalize) - normalize_d_s_us(&days, &seconds, µseconds); - assert(0 <= seconds && seconds < 24*3600); - assert(0 <= microseconds && microseconds < 1000000); - - if (check_delta_day_range(days) < 0) - return NULL; - - self = (PyDateTime_Delta *) (type->tp_alloc(type, 0)); - if (self != NULL) { - self->hashcode = -1; - SET_TD_DAYS(self, days); - SET_TD_SECONDS(self, seconds); - SET_TD_MICROSECONDS(self, microseconds); - } - return (PyObject *) self; -} - -#define new_delta(d, s, us, normalize) \ - new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType) - - -typedef struct -{ - PyObject_HEAD - PyObject *offset; - PyObject *name; -} PyDateTime_TimeZone; - -/* The interned UTC timezone instance */ -static PyObject *PyDateTime_TimeZone_UTC; -/* The interned Epoch datetime instance */ -static PyObject *PyDateTime_Epoch; - -/* Create new timezone instance checking offset range. This - function does not check the name argument. Caller must assure - that offset is a timedelta instance and name is either NULL - or a unicode object. */ -static PyObject * -create_timezone(PyObject *offset, PyObject *name) -{ - PyDateTime_TimeZone *self; - PyTypeObject *type = &PyDateTime_TimeZoneType; - - assert(offset != NULL); - assert(PyDelta_Check(offset)); - assert(name == NULL || PyUnicode_Check(name)); - - self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0)); - if (self == NULL) { - return NULL; - } - Py_INCREF(offset); - self->offset = offset; - Py_XINCREF(name); - self->name = name; - return (PyObject *)self; -} - -static int delta_bool(PyDateTime_Delta *self); - -static PyObject * -new_timezone(PyObject *offset, PyObject *name) -{ - assert(offset != NULL); - assert(PyDelta_Check(offset)); - assert(name == NULL || PyUnicode_Check(name)); - - if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) { - Py_INCREF(PyDateTime_TimeZone_UTC); - return PyDateTime_TimeZone_UTC; - } - if ((GET_TD_DAYS(offset) == -1 && - GET_TD_SECONDS(offset) == 0 && - GET_TD_MICROSECONDS(offset) < 1) || - GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { - PyErr_Format(PyExc_ValueError, "offset must be a timedelta" - " strictly between -timedelta(hours=24) and" - " timedelta(hours=24)," - " not %R.", offset); - return NULL; - } - - return create_timezone(offset, name); -} - -/* --------------------------------------------------------------------------- - * tzinfo helpers. - */ - -/* Ensure that p is None or of a tzinfo subclass. Return 0 if OK; if not - * raise TypeError and return -1. - */ -static int -check_tzinfo_subclass(PyObject *p) -{ - if (p == Py_None || PyTZInfo_Check(p)) - return 0; - PyErr_Format(PyExc_TypeError, - "tzinfo argument must be None or of a tzinfo subclass, " - "not type '%s'", - Py_TYPE(p)->tp_name); - return -1; -} - -/* If self has a tzinfo member, return a BORROWED reference to it. Else - * return NULL, which is NOT AN ERROR. There are no error returns here, - * and the caller must not decref the result. - */ -static PyObject * -get_tzinfo_member(PyObject *self) -{ - PyObject *tzinfo = NULL; - - if (PyDateTime_Check(self) && HASTZINFO(self)) - tzinfo = ((PyDateTime_DateTime *)self)->tzinfo; - else if (PyTime_Check(self) && HASTZINFO(self)) - tzinfo = ((PyDateTime_Time *)self)->tzinfo; - - return tzinfo; -} - -/* Call getattr(tzinfo, name)(tzinfoarg), and check the result. tzinfo must - * be an instance of the tzinfo class. If the method returns None, this - * returns None. If the method doesn't return None or timedelta, TypeError is - * raised and this returns NULL. If it returns a timedelta and the value is - * out of range or isn't a whole number of minutes, ValueError is raised and - * this returns NULL. Else result is returned. - */ -static PyObject * -call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg) -{ - PyObject *offset; - - assert(tzinfo != NULL); - assert(PyTZInfo_Check(tzinfo) || tzinfo == Py_None); - assert(tzinfoarg != NULL); - - if (tzinfo == Py_None) - Py_RETURN_NONE; - offset = PyObject_CallMethod(tzinfo, name, "O", tzinfoarg); - if (offset == Py_None || offset == NULL) - return offset; - if (PyDelta_Check(offset)) { - if ((GET_TD_DAYS(offset) == -1 && - GET_TD_SECONDS(offset) == 0 && - GET_TD_MICROSECONDS(offset) < 1) || - GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { - Py_DECREF(offset); - PyErr_Format(PyExc_ValueError, "offset must be a timedelta" - " strictly between -timedelta(hours=24) and" - " timedelta(hours=24)."); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, - "tzinfo.%s() must return None or " - "timedelta, not '%.200s'", - name, Py_TYPE(offset)->tp_name); - Py_DECREF(offset); - return NULL; - } - - return offset; -} - -/* Call tzinfo.utcoffset(tzinfoarg), and extract an integer from the - * result. tzinfo must be an instance of the tzinfo class. If utcoffset() - * returns None, call_utcoffset returns 0 and sets *none to 1. If uctoffset() - * doesn't return None or timedelta, TypeError is raised and this returns -1. - * If utcoffset() returns an out of range timedelta, - * ValueError is raised and this returns -1. Else *none is - * set to 0 and the offset is returned (as timedelta, positive east of UTC). - */ -static PyObject * -call_utcoffset(PyObject *tzinfo, PyObject *tzinfoarg) -{ - return call_tzinfo_method(tzinfo, "utcoffset", tzinfoarg); -} - -/* Call tzinfo.dst(tzinfoarg), and extract an integer from the - * result. tzinfo must be an instance of the tzinfo class. If dst() - * returns None, call_dst returns 0 and sets *none to 1. If dst() - * doesn't return None or timedelta, TypeError is raised and this - * returns -1. If dst() returns an invalid timedelta for a UTC offset, - * ValueError is raised and this returns -1. Else *none is set to 0 and - * the offset is returned (as timedelta, positive east of UTC). - */ -static PyObject * -call_dst(PyObject *tzinfo, PyObject *tzinfoarg) -{ - return call_tzinfo_method(tzinfo, "dst", tzinfoarg); -} - -/* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be - * an instance of the tzinfo class or None. If tzinfo isn't None, and - * tzname() doesn't return None or a string, TypeError is raised and this - * returns NULL. If the result is a string, we ensure it is a Unicode - * string. - */ -static PyObject * -call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) -{ - PyObject *result; - _Py_IDENTIFIER(tzname); - - assert(tzinfo != NULL); - assert(check_tzinfo_subclass(tzinfo) >= 0); - assert(tzinfoarg != NULL); - - if (tzinfo == Py_None) - Py_RETURN_NONE; - - result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg); - - if (result == NULL || result == Py_None) - return result; - - if (!PyUnicode_Check(result)) { - PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must " - "return None or a string, not '%s'", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; - } - - return result; -} - -/* repr is like "someclass(arg1, arg2)". If tzinfo isn't None, - * stuff - * ", tzinfo=" + repr(tzinfo) - * before the closing ")". - */ -static PyObject * -append_keyword_tzinfo(PyObject *repr, PyObject *tzinfo) -{ - PyObject *temp; - - assert(PyUnicode_Check(repr)); - assert(tzinfo); - if (tzinfo == Py_None) - return repr; - /* Get rid of the trailing ')'. */ - assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')'); - temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1); - Py_DECREF(repr); - if (temp == NULL) - return NULL; - repr = PyUnicode_FromFormat("%U, tzinfo=%R)", temp, tzinfo); - Py_DECREF(temp); - return repr; -} - -/* repr is like "someclass(arg1, arg2)". If fold isn't 0, - * stuff - * ", fold=" + repr(tzinfo) - * before the closing ")". - */ -static PyObject * -append_keyword_fold(PyObject *repr, int fold) -{ - PyObject *temp; - - assert(PyUnicode_Check(repr)); - if (fold == 0) - return repr; - /* Get rid of the trailing ')'. */ - assert(PyUnicode_READ_CHAR(repr, PyUnicode_GET_LENGTH(repr)-1) == ')'); - temp = PyUnicode_Substring(repr, 0, PyUnicode_GET_LENGTH(repr) - 1); - Py_DECREF(repr); - if (temp == NULL) - return NULL; - repr = PyUnicode_FromFormat("%U, fold=%d)", temp, fold); - Py_DECREF(temp); - return repr; -} - -static inline PyObject * -tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) -{ - PyObject *tzinfo; - if (rv == 1) { - // Create a timezone from offset in seconds (0 returns UTC) - if (tzoffset == 0) { - Py_INCREF(PyDateTime_TimeZone_UTC); - return PyDateTime_TimeZone_UTC; - } - - PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1); - if (delta == NULL) { - return NULL; - } - tzinfo = new_timezone(delta, NULL); - Py_DECREF(delta); - } - else { - tzinfo = Py_None; - Py_INCREF(Py_None); - } - - return tzinfo; -} - -/* --------------------------------------------------------------------------- - * String format helpers. - */ - -static PyObject * -format_ctime(PyDateTime_Date *date, int hours, int minutes, int seconds) -{ - static const char * const DayNames[] = { - "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" - }; - static const char * const MonthNames[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - - int wday = weekday(GET_YEAR(date), GET_MONTH(date), GET_DAY(date)); - - return PyUnicode_FromFormat("%s %s %2d %02d:%02d:%02d %04d", - DayNames[wday], MonthNames[GET_MONTH(date)-1], - GET_DAY(date), hours, minutes, seconds, - GET_YEAR(date)); -} - -static PyObject *delta_negative(PyDateTime_Delta *self); - -/* Add formatted UTC offset string to buf. buf has no more than - * buflen bytes remaining. The UTC offset is gotten by calling - * tzinfo.uctoffset(tzinfoarg). If that returns None, \0 is stored into - * *buf, and that's all. Else the returned value is checked for sanity (an - * integer in range), and if that's OK it's converted to an hours & minutes - * string of the form - * sign HH sep MM [sep SS [. UUUUUU]] - * Returns 0 if everything is OK. If the return value from utcoffset() is - * bogus, an appropriate exception is set and -1 is returned. - */ -static int -format_utcoffset(char *buf, size_t buflen, const char *sep, - PyObject *tzinfo, PyObject *tzinfoarg) -{ - PyObject *offset; - int hours, minutes, seconds, microseconds; - char sign; - - assert(buflen >= 1); - - offset = call_utcoffset(tzinfo, tzinfoarg); - if (offset == NULL) - return -1; - if (offset == Py_None) { - Py_DECREF(offset); - *buf = '\0'; - return 0; - } - /* Offset is normalized, so it is negative if days < 0 */ - if (GET_TD_DAYS(offset) < 0) { - sign = '-'; - Py_SETREF(offset, delta_negative((PyDateTime_Delta *)offset)); - if (offset == NULL) - return -1; - } - else { - sign = '+'; - } - /* Offset is not negative here. */ - microseconds = GET_TD_MICROSECONDS(offset); - seconds = GET_TD_SECONDS(offset); - Py_DECREF(offset); - minutes = divmod(seconds, 60, &seconds); - hours = divmod(minutes, 60, &minutes); - if (microseconds) { - PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d.%06d", sign, - hours, sep, minutes, sep, seconds, microseconds); - return 0; - } - if (seconds) { - PyOS_snprintf(buf, buflen, "%c%02d%s%02d%s%02d", sign, hours, - sep, minutes, sep, seconds); - return 0; - } - PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes); - return 0; -} - -static PyObject * -make_Zreplacement(PyObject *object, PyObject *tzinfoarg) -{ - PyObject *temp; - PyObject *tzinfo = get_tzinfo_member(object); - PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0); - _Py_IDENTIFIER(replace); - - if (Zreplacement == NULL) - return NULL; - if (tzinfo == Py_None || tzinfo == NULL) - return Zreplacement; - - assert(tzinfoarg != NULL); - temp = call_tzname(tzinfo, tzinfoarg); - if (temp == NULL) - goto Error; - if (temp == Py_None) { - Py_DECREF(temp); - return Zreplacement; - } - - assert(PyUnicode_Check(temp)); - /* Since the tzname is getting stuffed into the - * format, we have to double any % signs so that - * strftime doesn't treat them as format codes. - */ - Py_DECREF(Zreplacement); - Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%"); - Py_DECREF(temp); - if (Zreplacement == NULL) - return NULL; - if (!PyUnicode_Check(Zreplacement)) { - PyErr_SetString(PyExc_TypeError, - "tzname.replace() did not return a string"); - goto Error; - } - return Zreplacement; - - Error: - Py_DECREF(Zreplacement); - return NULL; -} - -static PyObject * -make_freplacement(PyObject *object) -{ - char freplacement[64]; - if (PyTime_Check(object)) - sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object)); - else if (PyDateTime_Check(object)) - sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object)); - else - sprintf(freplacement, "%06d", 0); - - return PyBytes_FromStringAndSize(freplacement, strlen(freplacement)); -} - -/* I sure don't want to reproduce the strftime code from the time module, - * so this imports the module and calls it. All the hair is due to - * giving special meanings to the %z, %Z and %f format codes via a - * preprocessing step on the format string. - * tzinfoarg is the argument to pass to the object's tzinfo method, if - * needed. - */ -static PyObject * -wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, - PyObject *tzinfoarg) -{ - PyObject *result = NULL; /* guilty until proved innocent */ - - PyObject *zreplacement = NULL; /* py string, replacement for %z */ - PyObject *Zreplacement = NULL; /* py string, replacement for %Z */ - PyObject *freplacement = NULL; /* py string, replacement for %f */ - - const char *pin; /* pointer to next char in input format */ - Py_ssize_t flen; /* length of input format */ - char ch; /* next char in input format */ - - PyObject *newfmt = NULL; /* py string, the output format */ - char *pnew; /* pointer to available byte in output format */ - size_t totalnew; /* number bytes total in output format buffer, - exclusive of trailing \0 */ - size_t usednew; /* number bytes used so far in output format buffer */ - - const char *ptoappend; /* ptr to string to append to output buffer */ - Py_ssize_t ntoappend; /* # of bytes to append to output buffer */ - - assert(object && format && timetuple); - assert(PyUnicode_Check(format)); - /* Convert the input format to a C string and size */ - pin = PyUnicode_AsUTF8AndSize(format, &flen); - if (!pin) - return NULL; - - /* Scan the input format, looking for %z/%Z/%f escapes, building - * a new format. Since computing the replacements for those codes - * is expensive, don't unless they're actually used. - */ - if (flen > INT_MAX - 1) { - PyErr_NoMemory(); - goto Done; - } - - totalnew = flen + 1; /* realistic if no %z/%Z */ - newfmt = PyBytes_FromStringAndSize(NULL, totalnew); - if (newfmt == NULL) goto Done; - pnew = PyBytes_AsString(newfmt); - usednew = 0; - - while ((ch = *pin++) != '\0') { - if (ch != '%') { - ptoappend = pin - 1; - ntoappend = 1; - } - else if ((ch = *pin++) == '\0') { - /* Null byte follows %, copy only '%'. - * - * Back the pin up one char so that we catch the null check - * the next time through the loop.*/ - pin--; - ptoappend = pin - 1; - ntoappend = 1; - } - /* A % has been seen and ch is the character after it. */ - else if (ch == 'z') { - if (zreplacement == NULL) { - /* format utcoffset */ - char buf[100]; - PyObject *tzinfo = get_tzinfo_member(object); - zreplacement = PyBytes_FromStringAndSize("", 0); - if (zreplacement == NULL) goto Done; - if (tzinfo != Py_None && tzinfo != NULL) { - assert(tzinfoarg != NULL); - if (format_utcoffset(buf, - sizeof(buf), - "", - tzinfo, - tzinfoarg) < 0) - goto Done; - Py_DECREF(zreplacement); - zreplacement = - PyBytes_FromStringAndSize(buf, - strlen(buf)); - if (zreplacement == NULL) - goto Done; - } - } - assert(zreplacement != NULL); - ptoappend = PyBytes_AS_STRING(zreplacement); - ntoappend = PyBytes_GET_SIZE(zreplacement); - } - else if (ch == 'Z') { - /* format tzname */ - if (Zreplacement == NULL) { - Zreplacement = make_Zreplacement(object, - tzinfoarg); - if (Zreplacement == NULL) - goto Done; - } - assert(Zreplacement != NULL); - assert(PyUnicode_Check(Zreplacement)); - ptoappend = PyUnicode_AsUTF8AndSize(Zreplacement, - &ntoappend); - if (ptoappend == NULL) - goto Done; - } - else if (ch == 'f') { - /* format microseconds */ - if (freplacement == NULL) { - freplacement = make_freplacement(object); - if (freplacement == NULL) - goto Done; - } - assert(freplacement != NULL); - assert(PyBytes_Check(freplacement)); - ptoappend = PyBytes_AS_STRING(freplacement); - ntoappend = PyBytes_GET_SIZE(freplacement); - } - else { - /* percent followed by neither z nor Z */ - ptoappend = pin - 2; - ntoappend = 2; - } - - /* Append the ntoappend chars starting at ptoappend to - * the new format. - */ - if (ntoappend == 0) - continue; - assert(ptoappend != NULL); - assert(ntoappend > 0); - while (usednew + ntoappend > totalnew) { - if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */ - PyErr_NoMemory(); - goto Done; - } - totalnew <<= 1; - if (_PyBytes_Resize(&newfmt, totalnew) < 0) - goto Done; - pnew = PyBytes_AsString(newfmt) + usednew; - } - memcpy(pnew, ptoappend, ntoappend); - pnew += ntoappend; - usednew += ntoappend; - assert(usednew <= totalnew); - } /* end while() */ - - if (_PyBytes_Resize(&newfmt, usednew) < 0) - goto Done; - { - PyObject *format; - PyObject *time = PyImport_ImportModuleNoBlock("time"); - - if (time == NULL) - goto Done; - format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); - if (format != NULL) { - result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime, - format, timetuple, NULL); - Py_DECREF(format); - } - Py_DECREF(time); - } - Done: - Py_XDECREF(freplacement); - Py_XDECREF(zreplacement); - Py_XDECREF(Zreplacement); - Py_XDECREF(newfmt); - return result; -} - -/* --------------------------------------------------------------------------- - * Wrap functions from the time module. These aren't directly available - * from C. Perhaps they should be. - */ - -/* Call time.time() and return its result (a Python float). */ -static PyObject * -time_time(void) -{ - PyObject *result = NULL; - PyObject *time = PyImport_ImportModuleNoBlock("time"); - - if (time != NULL) { - _Py_IDENTIFIER(time); - - result = _PyObject_CallMethodIdNoArgs(time, &PyId_time); - Py_DECREF(time); - } - return result; -} - -/* Build a time.struct_time. The weekday and day number are automatically - * computed from the y,m,d args. - */ -static PyObject * -build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) -{ - PyObject *time; - PyObject *result; - _Py_IDENTIFIER(struct_time); - PyObject *args; - - - time = PyImport_ImportModuleNoBlock("time"); - if (time == NULL) { - return NULL; - } - - args = Py_BuildValue("iiiiiiiii", - y, m, d, - hh, mm, ss, - weekday(y, m, d), - days_before_month(y, m) + d, - dstflag); - if (args == NULL) { - Py_DECREF(time); - return NULL; - } - - result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args); - Py_DECREF(time); - Py_DECREF(args); - return result; -} - -/* --------------------------------------------------------------------------- - * Miscellaneous helpers. - */ - -/* The comparisons here all most naturally compute a cmp()-like result. - * This little helper turns that into a bool result for rich comparisons. - */ -static PyObject * -diff_to_bool(int diff, int op) -{ - Py_RETURN_RICHCOMPARE(diff, 0, op); -} - -/* Raises a "can't compare" TypeError and returns NULL. */ -static PyObject * -cmperror(PyObject *a, PyObject *b) -{ - PyErr_Format(PyExc_TypeError, - "can't compare %s to %s", - Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); - return NULL; -} - -/* --------------------------------------------------------------------------- - * Cached Python objects; these are set by the module init function. - */ - -/* Conversion factors. */ -static PyObject *us_per_ms = NULL; /* 1000 */ -static PyObject *us_per_second = NULL; /* 1000000 */ -static PyObject *us_per_minute = NULL; /* 1e6 * 60 as Python int */ -static PyObject *us_per_hour = NULL; /* 1e6 * 3600 as Python int */ -static PyObject *us_per_day = NULL; /* 1e6 * 3600 * 24 as Python int */ -static PyObject *us_per_week = NULL; /* 1e6*3600*24*7 as Python int */ -static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */ - -/* --------------------------------------------------------------------------- - * Class implementations. - */ - -/* - * PyDateTime_Delta implementation. - */ - -/* Convert a timedelta to a number of us, - * (24*3600*self.days + self.seconds)*1000000 + self.microseconds - * as a Python int. - * Doing mixed-radix arithmetic by hand instead is excruciating in C, - * due to ubiquitous overflow possibilities. - */ -static PyObject * -delta_to_microseconds(PyDateTime_Delta *self) -{ - PyObject *x1 = NULL; - PyObject *x2 = NULL; - PyObject *x3 = NULL; - PyObject *result = NULL; - - x1 = PyLong_FromLong(GET_TD_DAYS(self)); - if (x1 == NULL) - goto Done; - x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */ - if (x2 == NULL) - goto Done; - Py_DECREF(x1); - x1 = NULL; - - /* x2 has days in seconds */ - x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */ - if (x1 == NULL) - goto Done; - x3 = PyNumber_Add(x1, x2); /* days and seconds in seconds */ - if (x3 == NULL) - goto Done; - Py_DECREF(x1); - Py_DECREF(x2); - /* x1 = */ x2 = NULL; - - /* x3 has days+seconds in seconds */ - x1 = PyNumber_Multiply(x3, us_per_second); /* us */ - if (x1 == NULL) - goto Done; - Py_DECREF(x3); - x3 = NULL; - - /* x1 has days+seconds in us */ - x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self)); - if (x2 == NULL) - goto Done; - result = PyNumber_Add(x1, x2); - assert(result == NULL || PyLong_CheckExact(result)); - -Done: - Py_XDECREF(x1); - Py_XDECREF(x2); - Py_XDECREF(x3); - return result; -} - -static PyObject * -checked_divmod(PyObject *a, PyObject *b) -{ - PyObject *result = PyNumber_Divmod(a, b); - if (result != NULL) { - if (!PyTuple_Check(result)) { - PyErr_Format(PyExc_TypeError, - "divmod() returned non-tuple (type %.200s)", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; - } - if (PyTuple_GET_SIZE(result) != 2) { - PyErr_Format(PyExc_TypeError, - "divmod() returned a tuple of size %zd", - PyTuple_GET_SIZE(result)); - Py_DECREF(result); - return NULL; - } - } - return result; -} - -/* Convert a number of us (as a Python int) to a timedelta. - */ -static PyObject * -microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) -{ - int us; - int s; - int d; - - PyObject *tuple = NULL; - PyObject *num = NULL; - PyObject *result = NULL; - - tuple = checked_divmod(pyus, us_per_second); - if (tuple == NULL) { - goto Done; - } - - num = PyTuple_GET_ITEM(tuple, 1); /* us */ - us = _PyLong_AsInt(num); - num = NULL; - if (us == -1 && PyErr_Occurred()) { - goto Done; - } - if (!(0 <= us && us < 1000000)) { - goto BadDivmod; - } - - num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */ - Py_INCREF(num); - Py_DECREF(tuple); - - tuple = checked_divmod(num, seconds_per_day); - if (tuple == NULL) - goto Done; - Py_DECREF(num); - - num = PyTuple_GET_ITEM(tuple, 1); /* seconds */ - s = _PyLong_AsInt(num); - num = NULL; - if (s == -1 && PyErr_Occurred()) { - goto Done; - } - if (!(0 <= s && s < 24*3600)) { - goto BadDivmod; - } - - num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */ - Py_INCREF(num); - d = _PyLong_AsInt(num); - if (d == -1 && PyErr_Occurred()) { - goto Done; - } - result = new_delta_ex(d, s, us, 0, type); - -Done: - Py_XDECREF(tuple); - Py_XDECREF(num); - return result; - -BadDivmod: - PyErr_SetString(PyExc_TypeError, - "divmod() returned a value out of range"); - goto Done; -} - -#define microseconds_to_delta(pymicros) \ - microseconds_to_delta_ex(pymicros, &PyDateTime_DeltaType) - -static PyObject * -multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta) -{ - PyObject *pyus_in; - PyObject *pyus_out; - PyObject *result; - - pyus_in = delta_to_microseconds(delta); - if (pyus_in == NULL) - return NULL; - - pyus_out = PyNumber_Multiply(intobj, pyus_in); - Py_DECREF(pyus_in); - if (pyus_out == NULL) - return NULL; - - result = microseconds_to_delta(pyus_out); - Py_DECREF(pyus_out); - return result; -} - -static PyObject * -get_float_as_integer_ratio(PyObject *floatobj) -{ - PyObject *ratio; - - assert(floatobj && PyFloat_Check(floatobj)); - ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio); - if (ratio == NULL) { - return NULL; - } - if (!PyTuple_Check(ratio)) { - PyErr_Format(PyExc_TypeError, - "unexpected return type from as_integer_ratio(): " - "expected tuple, got '%.200s'", - Py_TYPE(ratio)->tp_name); - Py_DECREF(ratio); - return NULL; - } - if (PyTuple_Size(ratio) != 2) { - PyErr_SetString(PyExc_ValueError, - "as_integer_ratio() must return a 2-tuple"); - Py_DECREF(ratio); - return NULL; - } - return ratio; -} - -/* op is 0 for multiplication, 1 for division */ -static PyObject * -multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, int op) -{ - PyObject *result = NULL; - PyObject *pyus_in = NULL, *temp, *pyus_out; - PyObject *ratio = NULL; - - pyus_in = delta_to_microseconds(delta); - if (pyus_in == NULL) - return NULL; - ratio = get_float_as_integer_ratio(floatobj); - if (ratio == NULL) { - goto error; - } - temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op)); - Py_DECREF(pyus_in); - pyus_in = NULL; - if (temp == NULL) - goto error; - pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op)); - Py_DECREF(temp); - if (pyus_out == NULL) - goto error; - result = microseconds_to_delta(pyus_out); - Py_DECREF(pyus_out); - error: - Py_XDECREF(pyus_in); - Py_XDECREF(ratio); - - return result; -} - -static PyObject * -divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj) -{ - PyObject *pyus_in; - PyObject *pyus_out; - PyObject *result; - - pyus_in = delta_to_microseconds(delta); - if (pyus_in == NULL) - return NULL; - - pyus_out = PyNumber_FloorDivide(pyus_in, intobj); - Py_DECREF(pyus_in); - if (pyus_out == NULL) - return NULL; - - result = microseconds_to_delta(pyus_out); - Py_DECREF(pyus_out); - return result; -} - -static PyObject * -divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) -{ - PyObject *pyus_left; - PyObject *pyus_right; - PyObject *result; - - pyus_left = delta_to_microseconds(left); - if (pyus_left == NULL) - return NULL; - - pyus_right = delta_to_microseconds(right); - if (pyus_right == NULL) { - Py_DECREF(pyus_left); - return NULL; - } - - result = PyNumber_FloorDivide(pyus_left, pyus_right); - Py_DECREF(pyus_left); - Py_DECREF(pyus_right); - return result; -} - -static PyObject * -truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) -{ - PyObject *pyus_left; - PyObject *pyus_right; - PyObject *result; - - pyus_left = delta_to_microseconds(left); - if (pyus_left == NULL) - return NULL; - - pyus_right = delta_to_microseconds(right); - if (pyus_right == NULL) { - Py_DECREF(pyus_left); - return NULL; - } - - result = PyNumber_TrueDivide(pyus_left, pyus_right); - Py_DECREF(pyus_left); - Py_DECREF(pyus_right); - return result; -} - -static PyObject * -truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i) -{ - PyObject *result; - PyObject *pyus_in, *pyus_out; - pyus_in = delta_to_microseconds(delta); - if (pyus_in == NULL) - return NULL; - pyus_out = divide_nearest(pyus_in, i); - Py_DECREF(pyus_in); - if (pyus_out == NULL) - return NULL; - result = microseconds_to_delta(pyus_out); - Py_DECREF(pyus_out); - - return result; -} - -static PyObject * -delta_add(PyObject *left, PyObject *right) -{ - PyObject *result = Py_NotImplemented; - - if (PyDelta_Check(left) && PyDelta_Check(right)) { - /* delta + delta */ - /* The C-level additions can't overflow because of the - * invariant bounds. - */ - int days = GET_TD_DAYS(left) + GET_TD_DAYS(right); - int seconds = GET_TD_SECONDS(left) + GET_TD_SECONDS(right); - int microseconds = GET_TD_MICROSECONDS(left) + - GET_TD_MICROSECONDS(right); - result = new_delta(days, seconds, microseconds, 1); - } - - if (result == Py_NotImplemented) - Py_INCREF(result); - return result; -} - -static PyObject * -delta_negative(PyDateTime_Delta *self) -{ - return new_delta(-GET_TD_DAYS(self), - -GET_TD_SECONDS(self), - -GET_TD_MICROSECONDS(self), - 1); -} - -static PyObject * -delta_positive(PyDateTime_Delta *self) -{ - /* Could optimize this (by returning self) if this isn't a - * subclass -- but who uses unary + ? Approximately nobody. - */ - return new_delta(GET_TD_DAYS(self), - GET_TD_SECONDS(self), - GET_TD_MICROSECONDS(self), - 0); -} - -static PyObject * -delta_abs(PyDateTime_Delta *self) -{ - PyObject *result; - - assert(GET_TD_MICROSECONDS(self) >= 0); - assert(GET_TD_SECONDS(self) >= 0); - - if (GET_TD_DAYS(self) < 0) - result = delta_negative(self); - else - result = delta_positive(self); - - return result; -} - -static PyObject * -delta_subtract(PyObject *left, PyObject *right) -{ - PyObject *result = Py_NotImplemented; - - if (PyDelta_Check(left) && PyDelta_Check(right)) { - /* delta - delta */ - /* The C-level additions can't overflow because of the - * invariant bounds. - */ - int days = GET_TD_DAYS(left) - GET_TD_DAYS(right); - int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right); - int microseconds = GET_TD_MICROSECONDS(left) - - GET_TD_MICROSECONDS(right); - result = new_delta(days, seconds, microseconds, 1); - } - - if (result == Py_NotImplemented) - Py_INCREF(result); - return result; -} - -static int -delta_cmp(PyObject *self, PyObject *other) -{ - int diff = GET_TD_DAYS(self) - GET_TD_DAYS(other); - if (diff == 0) { - diff = GET_TD_SECONDS(self) - GET_TD_SECONDS(other); - if (diff == 0) - diff = GET_TD_MICROSECONDS(self) - - GET_TD_MICROSECONDS(other); - } - return diff; -} - -static PyObject * -delta_richcompare(PyObject *self, PyObject *other, int op) -{ - if (PyDelta_Check(other)) { - int diff = delta_cmp(self, other); - return diff_to_bool(diff, op); - } - else { - Py_RETURN_NOTIMPLEMENTED; - } -} - -static PyObject *delta_getstate(PyDateTime_Delta *self); - -static Py_hash_t -delta_hash(PyDateTime_Delta *self) -{ - if (self->hashcode == -1) { - PyObject *temp = delta_getstate(self); - if (temp != NULL) { - self->hashcode = PyObject_Hash(temp); - Py_DECREF(temp); - } - } - return self->hashcode; -} - -static PyObject * -delta_multiply(PyObject *left, PyObject *right) -{ - PyObject *result = Py_NotImplemented; - - if (PyDelta_Check(left)) { - /* delta * ??? */ - if (PyLong_Check(right)) - result = multiply_int_timedelta(right, - (PyDateTime_Delta *) left); - else if (PyFloat_Check(right)) - result = multiply_truedivide_timedelta_float( - (PyDateTime_Delta *) left, right, 0); - } - else if (PyLong_Check(left)) - result = multiply_int_timedelta(left, - (PyDateTime_Delta *) right); - else if (PyFloat_Check(left)) - result = multiply_truedivide_timedelta_float( - (PyDateTime_Delta *) right, left, 0); - - if (result == Py_NotImplemented) - Py_INCREF(result); - return result; -} - -static PyObject * -delta_divide(PyObject *left, PyObject *right) -{ - PyObject *result = Py_NotImplemented; - - if (PyDelta_Check(left)) { - /* delta * ??? */ - if (PyLong_Check(right)) - result = divide_timedelta_int( - (PyDateTime_Delta *)left, - right); - else if (PyDelta_Check(right)) - result = divide_timedelta_timedelta( - (PyDateTime_Delta *)left, - (PyDateTime_Delta *)right); - } - - if (result == Py_NotImplemented) - Py_INCREF(result); - return result; -} - -static PyObject * -delta_truedivide(PyObject *left, PyObject *right) -{ - PyObject *result = Py_NotImplemented; - - if (PyDelta_Check(left)) { - if (PyDelta_Check(right)) - result = truedivide_timedelta_timedelta( - (PyDateTime_Delta *)left, - (PyDateTime_Delta *)right); - else if (PyFloat_Check(right)) - result = multiply_truedivide_timedelta_float( - (PyDateTime_Delta *)left, right, 1); - else if (PyLong_Check(right)) - result = truedivide_timedelta_int( - (PyDateTime_Delta *)left, right); - } - - if (result == Py_NotImplemented) - Py_INCREF(result); - return result; -} - -static PyObject * -delta_remainder(PyObject *left, PyObject *right) -{ - PyObject *pyus_left; - PyObject *pyus_right; - PyObject *pyus_remainder; - PyObject *remainder; - - if (!PyDelta_Check(left) || !PyDelta_Check(right)) - Py_RETURN_NOTIMPLEMENTED; - - pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); - if (pyus_left == NULL) - return NULL; - - pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); - if (pyus_right == NULL) { - Py_DECREF(pyus_left); - return NULL; - } - - pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right); - Py_DECREF(pyus_left); - Py_DECREF(pyus_right); - if (pyus_remainder == NULL) - return NULL; - - remainder = microseconds_to_delta(pyus_remainder); - Py_DECREF(pyus_remainder); - if (remainder == NULL) - return NULL; - - return remainder; -} - -static PyObject * -delta_divmod(PyObject *left, PyObject *right) -{ - PyObject *pyus_left; - PyObject *pyus_right; - PyObject *divmod; - PyObject *delta; - PyObject *result; - - if (!PyDelta_Check(left) || !PyDelta_Check(right)) - Py_RETURN_NOTIMPLEMENTED; - - pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); - if (pyus_left == NULL) - return NULL; - - pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); - if (pyus_right == NULL) { - Py_DECREF(pyus_left); - return NULL; - } - - divmod = checked_divmod(pyus_left, pyus_right); - Py_DECREF(pyus_left); - Py_DECREF(pyus_right); - if (divmod == NULL) - return NULL; - - delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1)); - if (delta == NULL) { - Py_DECREF(divmod); - return NULL; - } - result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta); - Py_DECREF(delta); - Py_DECREF(divmod); - return result; -} - -/* Fold in the value of the tag ("seconds", "weeks", etc) component of a - * timedelta constructor. sofar is the # of microseconds accounted for - * so far, and there are factor microseconds per current unit, the number - * of which is given by num. num * factor is added to sofar in a - * numerically careful way, and that's the result. Any fractional - * microseconds left over (this can happen if num is a float type) are - * added into *leftover. - * Note that there are many ways this can give an error (NULL) return. - */ -static PyObject * -accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor, - double *leftover) -{ - PyObject *prod; - PyObject *sum; - - assert(num != NULL); - - if (PyLong_Check(num)) { - prod = PyNumber_Multiply(num, factor); - if (prod == NULL) - return NULL; - sum = PyNumber_Add(sofar, prod); - Py_DECREF(prod); - return sum; - } - - if (PyFloat_Check(num)) { - double dnum; - double fracpart; - double intpart; - PyObject *x; - PyObject *y; - - /* The Plan: decompose num into an integer part and a - * fractional part, num = intpart + fracpart. - * Then num * factor == - * intpart * factor + fracpart * factor - * and the LHS can be computed exactly in long arithmetic. - * The RHS is again broken into an int part and frac part. - * and the frac part is added into *leftover. - */ - dnum = PyFloat_AsDouble(num); - if (dnum == -1.0 && PyErr_Occurred()) - return NULL; - fracpart = modf(dnum, &intpart); - x = PyLong_FromDouble(intpart); - if (x == NULL) - return NULL; - - prod = PyNumber_Multiply(x, factor); - Py_DECREF(x); - if (prod == NULL) - return NULL; - - sum = PyNumber_Add(sofar, prod); - Py_DECREF(prod); - if (sum == NULL) - return NULL; - - if (fracpart == 0.0) - return sum; - /* So far we've lost no information. Dealing with the - * fractional part requires float arithmetic, and may - * lose a little info. - */ - assert(PyLong_CheckExact(factor)); - dnum = PyLong_AsDouble(factor); - - dnum *= fracpart; - fracpart = modf(dnum, &intpart); - x = PyLong_FromDouble(intpart); - if (x == NULL) { - Py_DECREF(sum); - return NULL; - } - - y = PyNumber_Add(sum, x); - Py_DECREF(sum); - Py_DECREF(x); - *leftover += fracpart; - return y; - } - - PyErr_Format(PyExc_TypeError, - "unsupported type for timedelta %s component: %s", - tag, Py_TYPE(num)->tp_name); - return NULL; -} - -static PyObject * -delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - PyObject *self = NULL; - - /* Argument objects. */ - PyObject *day = NULL; - PyObject *second = NULL; - PyObject *us = NULL; - PyObject *ms = NULL; - PyObject *minute = NULL; - PyObject *hour = NULL; - PyObject *week = NULL; - - PyObject *x = NULL; /* running sum of microseconds */ - PyObject *y = NULL; /* temp sum of microseconds */ - double leftover_us = 0.0; - - static char *keywords[] = { - "days", "seconds", "microseconds", "milliseconds", - "minutes", "hours", "weeks", NULL - }; - - if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__", - keywords, - &day, &second, &us, - &ms, &minute, &hour, &week) == 0) - goto Done; - - x = PyLong_FromLong(0); - if (x == NULL) - goto Done; - -#define CLEANUP \ - Py_DECREF(x); \ - x = y; \ - if (x == NULL) \ - goto Done - - if (us) { - y = accum("microseconds", x, us, _PyLong_One, &leftover_us); - CLEANUP; - } - if (ms) { - y = accum("milliseconds", x, ms, us_per_ms, &leftover_us); - CLEANUP; - } - if (second) { - y = accum("seconds", x, second, us_per_second, &leftover_us); - CLEANUP; - } - if (minute) { - y = accum("minutes", x, minute, us_per_minute, &leftover_us); - CLEANUP; - } - if (hour) { - y = accum("hours", x, hour, us_per_hour, &leftover_us); - CLEANUP; - } - if (day) { - y = accum("days", x, day, us_per_day, &leftover_us); - CLEANUP; - } - if (week) { - y = accum("weeks", x, week, us_per_week, &leftover_us); - CLEANUP; - } - if (leftover_us) { - /* Round to nearest whole # of us, and add into x. */ - double whole_us = round(leftover_us); - int x_is_odd; - PyObject *temp; - - if (fabs(whole_us - leftover_us) == 0.5) { - /* We're exactly halfway between two integers. In order - * to do round-half-to-even, we must determine whether x - * is odd. Note that x is odd when it's last bit is 1. The - * code below uses bitwise and operation to check the last - * bit. */ - temp = PyNumber_And(x, _PyLong_One); /* temp <- x & 1 */ - if (temp == NULL) { - Py_DECREF(x); - goto Done; - } - x_is_odd = PyObject_IsTrue(temp); - Py_DECREF(temp); - if (x_is_odd == -1) { - Py_DECREF(x); - goto Done; - } - whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd; - } - - temp = PyLong_FromLong((long)whole_us); - - if (temp == NULL) { - Py_DECREF(x); - goto Done; - } - y = PyNumber_Add(x, temp); - Py_DECREF(temp); - CLEANUP; - } - - self = microseconds_to_delta_ex(x, type); - Py_DECREF(x); -Done: - return self; - -#undef CLEANUP -} - -static int -delta_bool(PyDateTime_Delta *self) -{ - return (GET_TD_DAYS(self) != 0 - || GET_TD_SECONDS(self) != 0 - || GET_TD_MICROSECONDS(self) != 0); -} - -static PyObject * -delta_repr(PyDateTime_Delta *self) -{ - PyObject *args = PyUnicode_FromString(""); - - if (args == NULL) { - return NULL; - } - - const char *sep = ""; - - if (GET_TD_DAYS(self) != 0) { - Py_SETREF(args, PyUnicode_FromFormat("days=%d", GET_TD_DAYS(self))); - if (args == NULL) { - return NULL; - } - sep = ", "; - } - - if (GET_TD_SECONDS(self) != 0) { - Py_SETREF(args, PyUnicode_FromFormat("%U%sseconds=%d", args, sep, - GET_TD_SECONDS(self))); - if (args == NULL) { - return NULL; - } - sep = ", "; - } - - if (GET_TD_MICROSECONDS(self) != 0) { - Py_SETREF(args, PyUnicode_FromFormat("%U%smicroseconds=%d", args, sep, - GET_TD_MICROSECONDS(self))); - if (args == NULL) { - return NULL; - } - } - - if (PyUnicode_GET_LENGTH(args) == 0) { - Py_SETREF(args, PyUnicode_FromString("0")); - if (args == NULL) { - return NULL; - } - } - - PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name, - args); - Py_DECREF(args); - return repr; -} - -static PyObject * -delta_str(PyDateTime_Delta *self) -{ - int us = GET_TD_MICROSECONDS(self); - int seconds = GET_TD_SECONDS(self); - int minutes = divmod(seconds, 60, &seconds); - int hours = divmod(minutes, 60, &minutes); - int days = GET_TD_DAYS(self); - - if (days) { - if (us) - return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d.%06d", - days, (days == 1 || days == -1) ? "" : "s", - hours, minutes, seconds, us); - else - return PyUnicode_FromFormat("%d day%s, %d:%02d:%02d", - days, (days == 1 || days == -1) ? "" : "s", - hours, minutes, seconds); - } else { - if (us) - return PyUnicode_FromFormat("%d:%02d:%02d.%06d", - hours, minutes, seconds, us); - else - return PyUnicode_FromFormat("%d:%02d:%02d", - hours, minutes, seconds); - } - -} - -/* Pickle support, a simple use of __reduce__. */ - -/* __getstate__ isn't exposed */ -static PyObject * -delta_getstate(PyDateTime_Delta *self) -{ - return Py_BuildValue("iii", GET_TD_DAYS(self), - GET_TD_SECONDS(self), - GET_TD_MICROSECONDS(self)); -} - -static PyObject * -delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *total_seconds; - PyObject *total_microseconds; - - total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self); - if (total_microseconds == NULL) - return NULL; - - total_seconds = PyNumber_TrueDivide(total_microseconds, us_per_second); - - Py_DECREF(total_microseconds); - return total_seconds; -} - -static PyObject * -delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self)); -} - -#define OFFSET(field) offsetof(PyDateTime_Delta, field) - -static PyMemberDef delta_members[] = { - - {"days", T_INT, OFFSET(days), READONLY, - PyDoc_STR("Number of days.")}, - - {"seconds", T_INT, OFFSET(seconds), READONLY, - PyDoc_STR("Number of seconds (>= 0 and less than 1 day).")}, - - {"microseconds", T_INT, OFFSET(microseconds), READONLY, - PyDoc_STR("Number of microseconds (>= 0 and less than 1 second).")}, - {NULL} -}; - -static PyMethodDef delta_methods[] = { - {"total_seconds", delta_total_seconds, METH_NOARGS, - PyDoc_STR("Total seconds in the duration.")}, - - {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, - PyDoc_STR("__reduce__() -> (cls, state)")}, - - {NULL, NULL}, -}; - -static const char delta_doc[] = -PyDoc_STR("Difference between two datetime values.\n\n" - "timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, " - "minutes=0, hours=0, weeks=0)\n\n" - "All arguments are optional and default to 0.\n" - "Arguments may be integers or floats, and may be positive or negative."); - -static PyNumberMethods delta_as_number = { - delta_add, /* nb_add */ - delta_subtract, /* nb_subtract */ - delta_multiply, /* nb_multiply */ - delta_remainder, /* nb_remainder */ - delta_divmod, /* nb_divmod */ - 0, /* nb_power */ - (unaryfunc)delta_negative, /* nb_negative */ - (unaryfunc)delta_positive, /* nb_positive */ - (unaryfunc)delta_abs, /* nb_absolute */ - (inquiry)delta_bool, /* nb_bool */ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ - 0, /*nb_int*/ - 0, /*nb_reserved*/ - 0, /*nb_float*/ - 0, /*nb_inplace_add*/ - 0, /*nb_inplace_subtract*/ - 0, /*nb_inplace_multiply*/ - 0, /*nb_inplace_remainder*/ - 0, /*nb_inplace_power*/ - 0, /*nb_inplace_lshift*/ - 0, /*nb_inplace_rshift*/ - 0, /*nb_inplace_and*/ - 0, /*nb_inplace_xor*/ - 0, /*nb_inplace_or*/ - delta_divide, /* nb_floor_divide */ - delta_truedivide, /* nb_true_divide */ - 0, /* nb_inplace_floor_divide */ - 0, /* nb_inplace_true_divide */ -}; - -static PyTypeObject PyDateTime_DeltaType = { - PyVarObject_HEAD_INIT(NULL, 0) - "datetime.timedelta", /* tp_name */ - sizeof(PyDateTime_Delta), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)delta_repr, /* tp_repr */ - &delta_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)delta_hash, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)delta_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - delta_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - delta_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - delta_methods, /* tp_methods */ - delta_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - delta_new, /* tp_new */ - 0, /* tp_free */ -}; - -/* - * PyDateTime_Date implementation. - */ - -/* Accessor properties. */ - -static PyObject * -date_year(PyDateTime_Date *self, void *unused) -{ - return PyLong_FromLong(GET_YEAR(self)); -} - -static PyObject * -date_month(PyDateTime_Date *self, void *unused) -{ - return PyLong_FromLong(GET_MONTH(self)); -} - -static PyObject * -date_day(PyDateTime_Date *self, void *unused) -{ - return PyLong_FromLong(GET_DAY(self)); -} - -static PyGetSetDef date_getset[] = { - {"year", (getter)date_year}, - {"month", (getter)date_month}, - {"day", (getter)date_day}, - {NULL} -}; - -/* Constructors. */ - -static char *date_kws[] = {"year", "month", "day", NULL}; - -static PyObject * -date_from_pickle(PyTypeObject *type, PyObject *state) -{ - PyDateTime_Date *me; - - me = (PyDateTime_Date *) (type->tp_alloc(type, 0)); - if (me != NULL) { - const char *pdata = PyBytes_AS_STRING(state); - memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE); - me->hashcode = -1; - } - return (PyObject *)me; -} - -static PyObject * -date_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - PyObject *self = NULL; - int year; - int month; - int day; - - /* Check for invocation from pickle with __getstate__ state */ - if (PyTuple_GET_SIZE(args) == 1) { - PyObject *state = PyTuple_GET_ITEM(args, 0); - if (PyBytes_Check(state)) { - if (PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE && - MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) - { - return date_from_pickle(type, state); - } - } - else if (PyUnicode_Check(state)) { - if (PyUnicode_READY(state)) { - return NULL; - } - if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATE_DATASIZE && - MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2))) - { - state = PyUnicode_AsLatin1String(state); - if (state == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { - /* More informative error message. */ - PyErr_SetString(PyExc_ValueError, - "Failed to encode latin1 string when unpickling " - "a date object. " - "pickle.load(data, encoding='latin1') is assumed."); - } - return NULL; - } - self = date_from_pickle(type, state); - Py_DECREF(state); - return self; - } - } - } - - if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws, - &year, &month, &day)) { - self = new_date_ex(year, month, day, type); - } - return self; -} - -static PyObject * -date_fromtimestamp(PyObject *cls, PyObject *obj) -{ - struct tm tm; - time_t t; - - if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1) - return NULL; - - if (_PyTime_localtime(t, &tm) != 0) - return NULL; - - return new_date_subclass_ex(tm.tm_year + 1900, - tm.tm_mon + 1, - tm.tm_mday, - cls); -} - -/* Return new date from current time. - * We say this is equivalent to fromtimestamp(time.time()), and the - * only way to be sure of that is to *call* time.time(). That's not - * generally the same as calling C's time. - */ -static PyObject * -date_today(PyObject *cls, PyObject *dummy) -{ - PyObject *time; - PyObject *result; - _Py_IDENTIFIER(fromtimestamp); - - time = time_time(); - if (time == NULL) - return NULL; - - /* Note well: today() is a class method, so this may not call - * date.fromtimestamp. For example, it may call - * datetime.fromtimestamp. That's why we need all the accuracy - * time.time() delivers; if someone were gonzo about optimization, - * date.today() could get away with plain C time(). - */ - result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time); - Py_DECREF(time); - return result; -} - -/*[clinic input] -@classmethod -datetime.date.fromtimestamp - - timestamp: object - / - -Create a date from a POSIX timestamp. - -The timestamp is a number, e.g. created via time.time(), that is interpreted -as local time. -[clinic start generated code]*/ - -static PyObject * -datetime_date_fromtimestamp(PyTypeObject *type, PyObject *timestamp) -/*[clinic end generated code: output=fd045fda58168869 input=eabb3fe7f40491fe]*/ -{ - return date_fromtimestamp((PyObject *) type, timestamp); -} - -/* bpo-36025: This is a wrapper for API compatibility with the public C API, - * which expects a function that takes an *args tuple, whereas the argument - * clinic generates code that takes METH_O. - */ -static PyObject * -datetime_date_fromtimestamp_capi(PyObject *cls, PyObject *args) -{ - PyObject *timestamp; - PyObject *result = NULL; - - if (PyArg_UnpackTuple(args, "fromtimestamp", 1, 1, ×tamp)) { - result = date_fromtimestamp(cls, timestamp); - } - - return result; -} - -/* Return new date from proleptic Gregorian ordinal. Raises ValueError if - * the ordinal is out of range. - */ -static PyObject * -date_fromordinal(PyObject *cls, PyObject *args) -{ - PyObject *result = NULL; - int ordinal; - - if (PyArg_ParseTuple(args, "i:fromordinal", &ordinal)) { - int year; - int month; - int day; - - if (ordinal < 1) - PyErr_SetString(PyExc_ValueError, "ordinal must be " - ">= 1"); - else { - ord_to_ymd(ordinal, &year, &month, &day); - result = new_date_subclass_ex(year, month, day, cls); - } - } - return result; -} - -/* Return the new date from a string as generated by date.isoformat() */ -static PyObject * -date_fromisoformat(PyObject *cls, PyObject *dtstr) -{ - assert(dtstr != NULL); - - if (!PyUnicode_Check(dtstr)) { - PyErr_SetString(PyExc_TypeError, - "fromisoformat: argument must be str"); - return NULL; - } - - Py_ssize_t len; - - const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr, &len); - if (dt_ptr == NULL) { - goto invalid_string_error; - } - - int year = 0, month = 0, day = 0; - - int rv; - if (len == 10) { - rv = parse_isoformat_date(dt_ptr, &year, &month, &day); - } - else { - rv = -1; - } - - if (rv < 0) { - goto invalid_string_error; - } - - return new_date_subclass_ex(year, month, day, cls); - -invalid_string_error: - PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr); - return NULL; -} - - -static PyObject * -date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) -{ - static char *keywords[] = { - "year", "week", "day", NULL - }; - - int year, week, day; - if (PyArg_ParseTupleAndKeywords(args, kw, "iii:fromisocalendar", - keywords, - &year, &week, &day) == 0) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - PyErr_Format(PyExc_ValueError, - "ISO calendar component out of range"); - - } - return NULL; - } - - // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5) - if (year < MINYEAR || year > MAXYEAR) { - PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year); - return NULL; - } - - if (week <= 0 || week >= 53) { - int out_of_range = 1; - if (week == 53) { - // ISO years have 53 weeks in it on years starting with a Thursday - // and on leap years starting on Wednesday - int first_weekday = weekday(year, 1, 1); - if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) { - out_of_range = 0; - } - } - - if (out_of_range) { - PyErr_Format(PyExc_ValueError, "Invalid week: %d", week); - return NULL; - } - } - - if (day <= 0 || day >= 8) { - PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])", - day); - return NULL; - } - - // Convert (Y, W, D) to (Y, M, D) in-place - int day_1 = iso_week1_monday(year); - - int month = week; - int day_offset = (month - 1)*7 + day - 1; - - ord_to_ymd(day_1 + day_offset, &year, &month, &day); - - return new_date_subclass_ex(year, month, day, cls); -} - - -/* - * Date arithmetic. - */ - -/* date + timedelta -> date. If arg negate is true, subtract the timedelta - * instead. - */ -static PyObject * -add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate) -{ - PyObject *result = NULL; - int year = GET_YEAR(date); - int month = GET_MONTH(date); - int deltadays = GET_TD_DAYS(delta); - /* C-level overflow is impossible because |deltadays| < 1e9. */ - int day = GET_DAY(date) + (negate ? -deltadays : deltadays); - - if (normalize_date(&year, &month, &day) >= 0) - result = new_date_subclass_ex(year, month, day, - (PyObject* )Py_TYPE(date)); - return result; -} - -static PyObject * -date_add(PyObject *left, PyObject *right) -{ - if (PyDateTime_Check(left) || PyDateTime_Check(right)) - Py_RETURN_NOTIMPLEMENTED; - - if (PyDate_Check(left)) { - /* date + ??? */ - if (PyDelta_Check(right)) - /* date + delta */ - return add_date_timedelta((PyDateTime_Date *) left, - (PyDateTime_Delta *) right, - 0); - } - else { - /* ??? + date - * 'right' must be one of us, or we wouldn't have been called - */ - if (PyDelta_Check(left)) - /* delta + date */ - return add_date_timedelta((PyDateTime_Date *) right, - (PyDateTime_Delta *) left, - 0); - } - Py_RETURN_NOTIMPLEMENTED; -} - -static PyObject * -date_subtract(PyObject *left, PyObject *right) -{ - if (PyDateTime_Check(left) || PyDateTime_Check(right)) - Py_RETURN_NOTIMPLEMENTED; - - if (PyDate_Check(left)) { - if (PyDate_Check(right)) { - /* date - date */ - int left_ord = ymd_to_ord(GET_YEAR(left), - GET_MONTH(left), - GET_DAY(left)); - int right_ord = ymd_to_ord(GET_YEAR(right), - GET_MONTH(right), - GET_DAY(right)); - return new_delta(left_ord - right_ord, 0, 0, 0); - } - if (PyDelta_Check(right)) { - /* date - delta */ - return add_date_timedelta((PyDateTime_Date *) left, - (PyDateTime_Delta *) right, - 1); - } - } - Py_RETURN_NOTIMPLEMENTED; -} - - -/* Various ways to turn a date into a string. */ - -static PyObject * -date_repr(PyDateTime_Date *self) -{ - return PyUnicode_FromFormat("%s(%d, %d, %d)", - Py_TYPE(self)->tp_name, - GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); -} - -static PyObject * -date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) -{ - return PyUnicode_FromFormat("%04d-%02d-%02d", - GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); -} - -/* str() calls the appropriate isoformat() method. */ -static PyObject * -date_str(PyDateTime_Date *self) -{ - return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); -} - - -static PyObject * -date_ctime(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) -{ - return format_ctime(self, 0, 0, 0); -} - -static PyObject * -date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) -{ - /* This method can be inherited, and needs to call the - * timetuple() method appropriate to self's class. - */ - PyObject *result; - PyObject *tuple; - PyObject *format; - _Py_IDENTIFIER(timetuple); - static char *keywords[] = {"format", NULL}; - - if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, - &format)) - return NULL; - - tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple); - if (tuple == NULL) - return NULL; - result = wrap_strftime((PyObject *)self, format, tuple, - (PyObject *)self); - Py_DECREF(tuple); - return result; -} - -static PyObject * -date_format(PyDateTime_Date *self, PyObject *args) -{ - PyObject *format; - - if (!PyArg_ParseTuple(args, "U:__format__", &format)) - return NULL; - - /* if the format is zero length, return str(self) */ - if (PyUnicode_GetLength(format) == 0) - return PyObject_Str((PyObject *)self); - - return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime, - format); -} - -/* ISO methods. */ - -static PyObject * -date_isoweekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) -{ - int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); - - return PyLong_FromLong(dow + 1); -} - -PyDoc_STRVAR(iso_calendar_date__doc__, -"The result of date.isocalendar() or datetime.isocalendar()\n\n\ -This object may be accessed either as a tuple of\n\ - ((year, week, weekday)\n\ -or via the object attributes as named in the above tuple."); - -typedef struct { - PyTupleObject tuple; -} PyDateTime_IsoCalendarDate; - -static PyObject * -iso_calendar_date_repr(PyDateTime_IsoCalendarDate *self) -{ - PyObject* year = PyTuple_GetItem((PyObject *)self, 0); - if (year == NULL) { - return NULL; - } - PyObject* week = PyTuple_GetItem((PyObject *)self, 1); - if (week == NULL) { - return NULL; - } - PyObject* weekday = PyTuple_GetItem((PyObject *)self, 2); - if (weekday == NULL) { - return NULL; - } - - return PyUnicode_FromFormat("%.200s(year=%S, week=%S, weekday=%S)", - Py_TYPE(self)->tp_name, year, week, weekday); -} - -static PyObject * -iso_calendar_date_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - // Construct the tuple that this reduces to - PyObject * reduce_tuple = Py_BuildValue( - "O((OOO))", &PyTuple_Type, - PyTuple_GET_ITEM(self, 0), - PyTuple_GET_ITEM(self, 1), - PyTuple_GET_ITEM(self, 2) - ); - - return reduce_tuple; -} - -static PyObject * -iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused) -{ - PyObject *year = PyTuple_GetItem((PyObject *)self, 0); - if (year == NULL) { - return NULL; - } - Py_INCREF(year); - return year; -} - -static PyObject * -iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused) -{ - PyObject *week = PyTuple_GetItem((PyObject *)self, 1); - if (week == NULL) { - return NULL; - } - Py_INCREF(week); - return week; -} - -static PyObject * -iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused) -{ - PyObject *weekday = PyTuple_GetItem((PyObject *)self, 2); - if (weekday == NULL) { - return NULL; - } - Py_INCREF(weekday); - return weekday; -} - -static PyGetSetDef iso_calendar_date_getset[] = { - {"year", (getter)iso_calendar_date_year}, - {"week", (getter)iso_calendar_date_week}, - {"weekday", (getter)iso_calendar_date_weekday}, - {NULL} -}; - -static PyMethodDef iso_calendar_date_methods[] = { - {"__reduce__", (PyCFunction)iso_calendar_date_reduce, METH_NOARGS, - PyDoc_STR("__reduce__() -> (cls, state)")}, - {NULL, NULL}, -}; - -static PyTypeObject PyDateTime_IsoCalendarDateType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "datetime.IsoCalendarDate", - .tp_basicsize = sizeof(PyDateTime_IsoCalendarDate), - .tp_repr = (reprfunc) iso_calendar_date_repr, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = iso_calendar_date__doc__, - .tp_methods = iso_calendar_date_methods, - .tp_getset = iso_calendar_date_getset, - // .tp_base = &PyTuple_Type, // filled in PyInit__datetime - .tp_new = iso_calendar_date_new, -}; - -/*[clinic input] -@classmethod -datetime.IsoCalendarDate.__new__ as iso_calendar_date_new - year: int - week: int - weekday: int -[clinic start generated code]*/ - -static PyObject * -iso_calendar_date_new_impl(PyTypeObject *type, int year, int week, - int weekday) -/*[clinic end generated code: output=383d33d8dc7183a2 input=4f2c663c9d19c4ee]*/ - -{ - PyDateTime_IsoCalendarDate *self; - self = (PyDateTime_IsoCalendarDate *) type->tp_alloc(type, 3); - if (self == NULL) { - return NULL; - } - - PyTuple_SET_ITEM(self, 0, PyLong_FromLong(year)); - PyTuple_SET_ITEM(self, 1, PyLong_FromLong(week)); - PyTuple_SET_ITEM(self, 2, PyLong_FromLong(weekday)); - - return (PyObject *)self; -} - -static PyObject * -date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) -{ - int year = GET_YEAR(self); - int week1_monday = iso_week1_monday(year); - int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self)); - int week; - int day; - - week = divmod(today - week1_monday, 7, &day); - if (week < 0) { - --year; - week1_monday = iso_week1_monday(year); - week = divmod(today - week1_monday, 7, &day); - } - else if (week >= 52 && today >= iso_week1_monday(year + 1)) { - ++year; - week = 0; - } - - PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType, - year, week + 1, day + 1); - if (v == NULL) { - return NULL; - } - return v; -} - -/* Miscellaneous methods. */ - -static PyObject * -date_richcompare(PyObject *self, PyObject *other, int op) -{ - if (PyDate_Check(other)) { - int diff = memcmp(((PyDateTime_Date *)self)->data, - ((PyDateTime_Date *)other)->data, - _PyDateTime_DATE_DATASIZE); - return diff_to_bool(diff, op); - } - else - Py_RETURN_NOTIMPLEMENTED; -} - -static PyObject * -date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) -{ - return build_struct_time(GET_YEAR(self), - GET_MONTH(self), - GET_DAY(self), - 0, 0, 0, -1); -} - -static PyObject * -date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw) -{ - PyObject *clone; - PyObject *tuple; - int year = GET_YEAR(self); - int month = GET_MONTH(self); - int day = GET_DAY(self); - - if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws, - &year, &month, &day)) - return NULL; - tuple = Py_BuildValue("iii", year, month, day); - if (tuple == NULL) - return NULL; - clone = date_new(Py_TYPE(self), tuple, NULL); - Py_DECREF(tuple); - return clone; -} - -static Py_hash_t -generic_hash(unsigned char *data, int len) -{ - return _Py_HashBytes(data, len); -} - - -static PyObject *date_getstate(PyDateTime_Date *self); - -static Py_hash_t -date_hash(PyDateTime_Date *self) -{ - if (self->hashcode == -1) { - self->hashcode = generic_hash( - (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE); - } - - return self->hashcode; -} - -static PyObject * -date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) -{ - return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self), - GET_DAY(self))); -} - -static PyObject * -date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) -{ - int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); - - return PyLong_FromLong(dow); -} - -/* Pickle support, a simple use of __reduce__. */ - -/* __getstate__ isn't exposed */ -static PyObject * -date_getstate(PyDateTime_Date *self) -{ - PyObject* field; - field = PyBytes_FromStringAndSize((char*)self->data, - _PyDateTime_DATE_DATASIZE); - return Py_BuildValue("(N)", field); -} - -static PyObject * -date_reduce(PyDateTime_Date *self, PyObject *arg) -{ - return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self)); -} - -static PyMethodDef date_methods[] = { - - /* Class methods: */ - DATETIME_DATE_FROMTIMESTAMP_METHODDEF - - {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS | - METH_CLASS, - PyDoc_STR("int -> date corresponding to a proleptic Gregorian " - "ordinal.")}, - - {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O | - METH_CLASS, - PyDoc_STR("str -> Construct a date from the output of date.isoformat()")}, - - {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("int, int, int -> Construct a date from the ISO year, week " - "number and weekday.\n\n" - "This is the inverse of the date.isocalendar() function")}, - - {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS, - PyDoc_STR("Current date or datetime: same as " - "self.__class__.fromtimestamp(time.time()).")}, - - /* Instance methods: */ - - {"ctime", (PyCFunction)date_ctime, METH_NOARGS, - PyDoc_STR("Return ctime() style string.")}, - - {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("format -> strftime() style string.")}, - - {"__format__", (PyCFunction)date_format, METH_VARARGS, - PyDoc_STR("Formats self with strftime.")}, - - {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS, - PyDoc_STR("Return time tuple, compatible with time.localtime().")}, - - {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS, - PyDoc_STR("Return a named tuple containing ISO year, week number, and " - "weekday.")}, - - {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS, - PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")}, - - {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS, - PyDoc_STR("Return the day of the week represented by the date.\n" - "Monday == 1 ... Sunday == 7")}, - - {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS, - PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year " - "1 is day 1.")}, - - {"weekday", (PyCFunction)date_weekday, METH_NOARGS, - PyDoc_STR("Return the day of the week represented by the date.\n" - "Monday == 0 ... Sunday == 6")}, - - {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Return date with new specified fields.")}, - - {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS, - PyDoc_STR("__reduce__() -> (cls, state)")}, - - {NULL, NULL} -}; - -static const char date_doc[] = -PyDoc_STR("date(year, month, day) --> date object"); - -static PyNumberMethods date_as_number = { - date_add, /* nb_add */ - date_subtract, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - 0, /* nb_bool */ -}; - -static PyTypeObject PyDateTime_DateType = { - PyVarObject_HEAD_INIT(NULL, 0) - "datetime.date", /* tp_name */ - sizeof(PyDateTime_Date), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)date_repr, /* tp_repr */ - &date_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)date_hash, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)date_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - date_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - date_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - date_methods, /* tp_methods */ - 0, /* tp_members */ - date_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - date_new, /* tp_new */ - 0, /* tp_free */ -}; - -/* - * PyDateTime_TZInfo implementation. - */ - -/* This is a pure abstract base class, so doesn't do anything beyond - * raising NotImplemented exceptions. Real tzinfo classes need - * to derive from this. This is mostly for clarity, and for efficiency in - * datetime and time constructors (their tzinfo arguments need to - * be subclasses of this tzinfo class, which is easy and quick to check). - * - * Note: For reasons having to do with pickling of subclasses, we have - * to allow tzinfo objects to be instantiated. This wasn't an issue - * in the Python implementation (__init__() could raise NotImplementedError - * there without ill effect), but doing so in the C implementation hit a - * brick wall. - */ - -static PyObject * -tzinfo_nogo(const char* methodname) -{ - PyErr_Format(PyExc_NotImplementedError, - "a tzinfo subclass must implement %s()", - methodname); - return NULL; -} - -/* Methods. A subclass must implement these. */ - -static PyObject * -tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt) -{ - return tzinfo_nogo("tzname"); -} - -static PyObject * -tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt) -{ - return tzinfo_nogo("utcoffset"); -} - -static PyObject * -tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt) -{ - return tzinfo_nogo("dst"); -} - - -static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date, - PyDateTime_Delta *delta, - int factor); -static PyObject *datetime_utcoffset(PyObject *self, PyObject *); -static PyObject *datetime_dst(PyObject *self, PyObject *); - -static PyObject * -tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt) -{ - PyObject *result = NULL; - PyObject *off = NULL, *dst = NULL; - PyDateTime_Delta *delta = NULL; - - if (!PyDateTime_Check(dt)) { - PyErr_SetString(PyExc_TypeError, - "fromutc: argument must be a datetime"); - return NULL; - } - if (GET_DT_TZINFO(dt) != (PyObject *)self) { - PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " - "is not self"); - return NULL; - } - - off = datetime_utcoffset(dt, NULL); - if (off == NULL) - return NULL; - if (off == Py_None) { - PyErr_SetString(PyExc_ValueError, "fromutc: non-None " - "utcoffset() result required"); - goto Fail; - } - - dst = datetime_dst(dt, NULL); - if (dst == NULL) - goto Fail; - if (dst == Py_None) { - PyErr_SetString(PyExc_ValueError, "fromutc: non-None " - "dst() result required"); - goto Fail; - } - - delta = (PyDateTime_Delta *)delta_subtract(off, dst); - if (delta == NULL) - goto Fail; - result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1); - if (result == NULL) - goto Fail; - - Py_DECREF(dst); - dst = call_dst(GET_DT_TZINFO(dt), result); - if (dst == NULL) - goto Fail; - if (dst == Py_None) - goto Inconsistent; - if (delta_bool((PyDateTime_Delta *)dst) != 0) { - Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result, - (PyDateTime_Delta *)dst, 1)); - if (result == NULL) - goto Fail; - } - Py_DECREF(delta); - Py_DECREF(dst); - Py_DECREF(off); - return result; - -Inconsistent: - PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave " - "inconsistent results; cannot convert"); - - /* fall through to failure */ -Fail: - Py_XDECREF(off); - Py_XDECREF(dst); - Py_XDECREF(delta); - Py_XDECREF(result); - return NULL; -} - -/* - * Pickle support. This is solely so that tzinfo subclasses can use - * pickling -- tzinfo itself is supposed to be uninstantiable. - */ - -static PyObject * -tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *args, *state; - PyObject *getinitargs, *getstate; - _Py_IDENTIFIER(__getinitargs__); - _Py_IDENTIFIER(__getstate__); - - if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) { - return NULL; - } - if (getinitargs != NULL) { - args = PyObject_CallNoArgs(getinitargs); - Py_DECREF(getinitargs); - } - else { - args = PyTuple_New(0); - } - if (args == NULL) { - return NULL; - } - - if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) { - Py_DECREF(args); - return NULL; - } - if (getstate != NULL) { - state = PyObject_CallNoArgs(getstate); - Py_DECREF(getstate); - if (state == NULL) { - Py_DECREF(args); - return NULL; - } - } - else { - PyObject **dictptr; - state = Py_None; - dictptr = _PyObject_GetDictPtr(self); - if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) { - state = *dictptr; - } - Py_INCREF(state); - } - - if (state == Py_None) { - Py_DECREF(state); - return Py_BuildValue("(ON)", Py_TYPE(self), args); - } - else - return Py_BuildValue("(ONN)", Py_TYPE(self), args, state); -} - -static PyMethodDef tzinfo_methods[] = { - - {"tzname", (PyCFunction)tzinfo_tzname, METH_O, - PyDoc_STR("datetime -> string name of time zone.")}, - - {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O, - PyDoc_STR("datetime -> timedelta showing offset from UTC, negative " - "values indicating West of UTC")}, - - {"dst", (PyCFunction)tzinfo_dst, METH_O, - PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")}, - - {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O, - PyDoc_STR("datetime in UTC -> datetime in local time.")}, - - {"__reduce__", tzinfo_reduce, METH_NOARGS, - PyDoc_STR("-> (cls, state)")}, - - {NULL, NULL} -}; - -static const char tzinfo_doc[] = -PyDoc_STR("Abstract base class for time zone info objects."); - -static PyTypeObject PyDateTime_TZInfoType = { - PyVarObject_HEAD_INIT(NULL, 0) - "datetime.tzinfo", /* tp_name */ - sizeof(PyDateTime_TZInfo), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - tzinfo_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - tzinfo_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ -}; - -static char *timezone_kws[] = {"offset", "name", NULL}; - -static PyObject * -timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - PyObject *offset; - PyObject *name = NULL; - if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws, - &PyDateTime_DeltaType, &offset, &name)) - return new_timezone(offset, name); - - return NULL; -} - -static void -timezone_dealloc(PyDateTime_TimeZone *self) -{ - Py_CLEAR(self->offset); - Py_CLEAR(self->name); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -timezone_richcompare(PyDateTime_TimeZone *self, - PyDateTime_TimeZone *other, int op) -{ - if (op != Py_EQ && op != Py_NE) - Py_RETURN_NOTIMPLEMENTED; - if (!PyTimezone_Check(other)) { - Py_RETURN_NOTIMPLEMENTED; - } - return delta_richcompare(self->offset, other->offset, op); -} - -static Py_hash_t -timezone_hash(PyDateTime_TimeZone *self) -{ - return delta_hash((PyDateTime_Delta *)self->offset); -} - -/* Check argument type passed to tzname, utcoffset, or dst methods. - Returns 0 for good argument. Returns -1 and sets exception info - otherwise. - */ -static int -_timezone_check_argument(PyObject *dt, const char *meth) -{ - if (dt == Py_None || PyDateTime_Check(dt)) - return 0; - PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance" - " or None, not %.200s", meth, Py_TYPE(dt)->tp_name); - return -1; -} - -static PyObject * -timezone_repr(PyDateTime_TimeZone *self) -{ - /* Note that although timezone is not subclassable, it is convenient - to use Py_TYPE(self)->tp_name here. */ - const char *type_name = Py_TYPE(self)->tp_name; - - if (((PyObject *)self) == PyDateTime_TimeZone_UTC) - return PyUnicode_FromFormat("%s.utc", type_name); - - if (self->name == NULL) - return PyUnicode_FromFormat("%s(%R)", type_name, self->offset); - - return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset, - self->name); -} - - -static PyObject * -timezone_str(PyDateTime_TimeZone *self) -{ - int hours, minutes, seconds, microseconds; - PyObject *offset; - char sign; - - if (self->name != NULL) { - Py_INCREF(self->name); - return self->name; - } - if ((PyObject *)self == PyDateTime_TimeZone_UTC || - (GET_TD_DAYS(self->offset) == 0 && - GET_TD_SECONDS(self->offset) == 0 && - GET_TD_MICROSECONDS(self->offset) == 0)) - return PyUnicode_FromString("UTC"); - /* Offset is normalized, so it is negative if days < 0 */ - if (GET_TD_DAYS(self->offset) < 0) { - sign = '-'; - offset = delta_negative((PyDateTime_Delta *)self->offset); - if (offset == NULL) - return NULL; - } - else { - sign = '+'; - offset = self->offset; - Py_INCREF(offset); - } - /* Offset is not negative here. */ - microseconds = GET_TD_MICROSECONDS(offset); - seconds = GET_TD_SECONDS(offset); - Py_DECREF(offset); - minutes = divmod(seconds, 60, &seconds); - hours = divmod(minutes, 60, &minutes); - if (microseconds != 0) { - return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d", - sign, hours, minutes, - seconds, microseconds); - } - if (seconds != 0) { - return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d", - sign, hours, minutes, seconds); - } - return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes); -} - -static PyObject * -timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt) -{ - if (_timezone_check_argument(dt, "tzname") == -1) - return NULL; - - return timezone_str(self); -} - -static PyObject * -timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt) -{ - if (_timezone_check_argument(dt, "utcoffset") == -1) - return NULL; - - Py_INCREF(self->offset); - return self->offset; -} - -static PyObject * -timezone_dst(PyObject *self, PyObject *dt) -{ - if (_timezone_check_argument(dt, "dst") == -1) - return NULL; - - Py_RETURN_NONE; -} - -static PyObject * -timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt) -{ - if (!PyDateTime_Check(dt)) { - PyErr_SetString(PyExc_TypeError, - "fromutc: argument must be a datetime"); - return NULL; - } - if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) { - PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " - "is not self"); - return NULL; - } - - return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1); -} - -static PyObject * -timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored)) -{ - if (self->name == NULL) - return Py_BuildValue("(O)", self->offset); - return Py_BuildValue("(OO)", self->offset, self->name); -} - -static PyMethodDef timezone_methods[] = { - {"tzname", (PyCFunction)timezone_tzname, METH_O, - PyDoc_STR("If name is specified when timezone is created, returns the name." - " Otherwise returns offset as 'UTC(+|-)HH:MM'.")}, - - {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O, - PyDoc_STR("Return fixed offset.")}, - - {"dst", (PyCFunction)timezone_dst, METH_O, - PyDoc_STR("Return None.")}, - - {"fromutc", (PyCFunction)timezone_fromutc, METH_O, - PyDoc_STR("datetime in UTC -> datetime in local time.")}, - - {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS, - PyDoc_STR("pickle support")}, - - {NULL, NULL} -}; - -static const char timezone_doc[] = -PyDoc_STR("Fixed offset from UTC implementation of tzinfo."); - -static PyTypeObject PyDateTime_TimeZoneType = { - PyVarObject_HEAD_INIT(NULL, 0) - "datetime.timezone", /* tp_name */ - sizeof(PyDateTime_TimeZone), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)timezone_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)timezone_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)timezone_hash, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)timezone_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - timezone_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)timezone_richcompare,/* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - timezone_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base; filled in PyInit__datetime */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - timezone_new, /* tp_new */ -}; - -/* - * PyDateTime_Time implementation. - */ - -/* Accessor properties. - */ - -static PyObject * -time_hour(PyDateTime_Time *self, void *unused) -{ - return PyLong_FromLong(TIME_GET_HOUR(self)); -} - -static PyObject * -time_minute(PyDateTime_Time *self, void *unused) -{ - return PyLong_FromLong(TIME_GET_MINUTE(self)); -} - -/* The name time_second conflicted with some platform header file. */ -static PyObject * -py_time_second(PyDateTime_Time *self, void *unused) -{ - return PyLong_FromLong(TIME_GET_SECOND(self)); -} - -static PyObject * -time_microsecond(PyDateTime_Time *self, void *unused) -{ - return PyLong_FromLong(TIME_GET_MICROSECOND(self)); -} - -static PyObject * -time_tzinfo(PyDateTime_Time *self, void *unused) -{ - PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; - Py_INCREF(result); - return result; -} - -static PyObject * -time_fold(PyDateTime_Time *self, void *unused) -{ - return PyLong_FromLong(TIME_GET_FOLD(self)); -} - -static PyGetSetDef time_getset[] = { - {"hour", (getter)time_hour}, - {"minute", (getter)time_minute}, - {"second", (getter)py_time_second}, - {"microsecond", (getter)time_microsecond}, - {"tzinfo", (getter)time_tzinfo}, - {"fold", (getter)time_fold}, - {NULL} -}; - -/* - * Constructors. - */ - -static char *time_kws[] = {"hour", "minute", "second", "microsecond", - "tzinfo", "fold", NULL}; - -static PyObject * -time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) -{ - PyDateTime_Time *me; - char aware = (char)(tzinfo != Py_None); - - if (aware && check_tzinfo_subclass(tzinfo) < 0) { - PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg"); - return NULL; - } - - me = (PyDateTime_Time *) (type->tp_alloc(type, aware)); - if (me != NULL) { - const char *pdata = PyBytes_AS_STRING(state); - - memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE); - me->hashcode = -1; - me->hastzinfo = aware; - if (aware) { - Py_INCREF(tzinfo); - me->tzinfo = tzinfo; - } - if (pdata[0] & (1 << 7)) { - me->data[0] -= 128; - me->fold = 1; - } - else { - me->fold = 0; - } - } - return (PyObject *)me; -} - -static PyObject * -time_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - PyObject *self = NULL; - int hour = 0; - int minute = 0; - int second = 0; - int usecond = 0; - PyObject *tzinfo = Py_None; - int fold = 0; - - /* Check for invocation from pickle with __getstate__ state */ - if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) { - PyObject *state = PyTuple_GET_ITEM(args, 0); - if (PyTuple_GET_SIZE(args) == 2) { - tzinfo = PyTuple_GET_ITEM(args, 1); - } - if (PyBytes_Check(state)) { - if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && - (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24) - { - return time_from_pickle(type, state, tzinfo); - } - } - else if (PyUnicode_Check(state)) { - if (PyUnicode_READY(state)) { - return NULL; - } - if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE && - (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24) - { - state = PyUnicode_AsLatin1String(state); - if (state == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { - /* More informative error message. */ - PyErr_SetString(PyExc_ValueError, - "Failed to encode latin1 string when unpickling " - "a time object. " - "pickle.load(data, encoding='latin1') is assumed."); - } - return NULL; - } - self = time_from_pickle(type, state, tzinfo); - Py_DECREF(state); - return self; - } - } - tzinfo = Py_None; - } - - if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws, - &hour, &minute, &second, &usecond, - &tzinfo, &fold)) { - self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold, - type); - } - return self; -} - -/* - * Destructor. - */ - -static void -time_dealloc(PyDateTime_Time *self) -{ - if (HASTZINFO(self)) { - Py_XDECREF(self->tzinfo); - } - Py_TYPE(self)->tp_free((PyObject *)self); -} - -/* - * Indirect access to tzinfo methods. - */ - -/* These are all METH_NOARGS, so don't need to check the arglist. */ -static PyObject * -time_utcoffset(PyObject *self, PyObject *unused) { - return call_utcoffset(GET_TIME_TZINFO(self), Py_None); -} - -static PyObject * -time_dst(PyObject *self, PyObject *unused) { - return call_dst(GET_TIME_TZINFO(self), Py_None); -} - -static PyObject * -time_tzname(PyDateTime_Time *self, PyObject *unused) { - return call_tzname(GET_TIME_TZINFO(self), Py_None); -} - -/* - * Various ways to turn a time into a string. - */ - -static PyObject * -time_repr(PyDateTime_Time *self) -{ - const char *type_name = Py_TYPE(self)->tp_name; - int h = TIME_GET_HOUR(self); - int m = TIME_GET_MINUTE(self); - int s = TIME_GET_SECOND(self); - int us = TIME_GET_MICROSECOND(self); - int fold = TIME_GET_FOLD(self); - PyObject *result = NULL; - - if (us) - result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)", - type_name, h, m, s, us); - else if (s) - result = PyUnicode_FromFormat("%s(%d, %d, %d)", - type_name, h, m, s); - else - result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m); - if (result != NULL && HASTZINFO(self)) - result = append_keyword_tzinfo(result, self->tzinfo); - if (result != NULL && fold) - result = append_keyword_fold(result, fold); - return result; -} - -static PyObject * -time_str(PyDateTime_Time *self) -{ - return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); -} - -static PyObject * -time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw) -{ - char buf[100]; - const char *timespec = NULL; - static char *keywords[] = {"timespec", NULL}; - PyObject *result; - int us = TIME_GET_MICROSECOND(self); - static const char *specs[][2] = { - {"hours", "%02d"}, - {"minutes", "%02d:%02d"}, - {"seconds", "%02d:%02d:%02d"}, - {"milliseconds", "%02d:%02d:%02d.%03d"}, - {"microseconds", "%02d:%02d:%02d.%06d"}, - }; - size_t given_spec; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, ×pec)) - return NULL; - - if (timespec == NULL || strcmp(timespec, "auto") == 0) { - if (us == 0) { - /* seconds */ - given_spec = 2; - } - else { - /* microseconds */ - given_spec = 4; - } - } - else { - for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) { - if (strcmp(timespec, specs[given_spec][0]) == 0) { - if (given_spec == 3) { - /* milliseconds */ - us = us / 1000; - } - break; - } - } - } - - if (given_spec == Py_ARRAY_LENGTH(specs)) { - PyErr_Format(PyExc_ValueError, "Unknown timespec value"); - return NULL; - } - else { - result = PyUnicode_FromFormat(specs[given_spec][1], - TIME_GET_HOUR(self), TIME_GET_MINUTE(self), - TIME_GET_SECOND(self), us); - } - - if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None) - return result; - - /* We need to append the UTC offset. */ - if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo, - Py_None) < 0) { - Py_DECREF(result); - return NULL; - } - PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf)); - return result; -} - -static PyObject * -time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw) -{ - PyObject *result; - PyObject *tuple; - PyObject *format; - static char *keywords[] = {"format", NULL}; - - if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, - &format)) - return NULL; - - /* Python's strftime does insane things with the year part of the - * timetuple. The year is forced to (the otherwise nonsensical) - * 1900 to work around that. - */ - tuple = Py_BuildValue("iiiiiiiii", - 1900, 1, 1, /* year, month, day */ - TIME_GET_HOUR(self), - TIME_GET_MINUTE(self), - TIME_GET_SECOND(self), - 0, 1, -1); /* weekday, daynum, dst */ - if (tuple == NULL) - return NULL; - assert(PyTuple_Size(tuple) == 9); - result = wrap_strftime((PyObject *)self, format, tuple, - Py_None); - Py_DECREF(tuple); - return result; -} - -/* - * Miscellaneous methods. - */ - -static PyObject * -time_richcompare(PyObject *self, PyObject *other, int op) -{ - PyObject *result = NULL; - PyObject *offset1, *offset2; - int diff; - - if (! PyTime_Check(other)) - Py_RETURN_NOTIMPLEMENTED; - - if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) { - diff = memcmp(((PyDateTime_Time *)self)->data, - ((PyDateTime_Time *)other)->data, - _PyDateTime_TIME_DATASIZE); - return diff_to_bool(diff, op); - } - offset1 = time_utcoffset(self, NULL); - if (offset1 == NULL) - return NULL; - offset2 = time_utcoffset(other, NULL); - if (offset2 == NULL) - goto done; - /* If they're both naive, or both aware and have the same offsets, - * we get off cheap. Note that if they're both naive, offset1 == - * offset2 == Py_None at this point. - */ - if ((offset1 == offset2) || - (PyDelta_Check(offset1) && PyDelta_Check(offset2) && - delta_cmp(offset1, offset2) == 0)) { - diff = memcmp(((PyDateTime_Time *)self)->data, - ((PyDateTime_Time *)other)->data, - _PyDateTime_TIME_DATASIZE); - result = diff_to_bool(diff, op); - } - /* The hard case: both aware with different UTC offsets */ - else if (offset1 != Py_None && offset2 != Py_None) { - int offsecs1, offsecs2; - assert(offset1 != offset2); /* else last "if" handled it */ - offsecs1 = TIME_GET_HOUR(self) * 3600 + - TIME_GET_MINUTE(self) * 60 + - TIME_GET_SECOND(self) - - GET_TD_DAYS(offset1) * 86400 - - GET_TD_SECONDS(offset1); - offsecs2 = TIME_GET_HOUR(other) * 3600 + - TIME_GET_MINUTE(other) * 60 + - TIME_GET_SECOND(other) - - GET_TD_DAYS(offset2) * 86400 - - GET_TD_SECONDS(offset2); - diff = offsecs1 - offsecs2; - if (diff == 0) - diff = TIME_GET_MICROSECOND(self) - - TIME_GET_MICROSECOND(other); - result = diff_to_bool(diff, op); - } - else if (op == Py_EQ) { - result = Py_False; - Py_INCREF(result); - } - else if (op == Py_NE) { - result = Py_True; - Py_INCREF(result); - } - else { - PyErr_SetString(PyExc_TypeError, - "can't compare offset-naive and " - "offset-aware times"); - } - done: - Py_DECREF(offset1); - Py_XDECREF(offset2); - return result; -} - -static Py_hash_t -time_hash(PyDateTime_Time *self) -{ - if (self->hashcode == -1) { - PyObject *offset, *self0; - if (TIME_GET_FOLD(self)) { - self0 = new_time_ex2(TIME_GET_HOUR(self), - TIME_GET_MINUTE(self), - TIME_GET_SECOND(self), - TIME_GET_MICROSECOND(self), - HASTZINFO(self) ? self->tzinfo : Py_None, - 0, Py_TYPE(self)); - if (self0 == NULL) - return -1; - } - else { - self0 = (PyObject *)self; - Py_INCREF(self0); - } - offset = time_utcoffset(self0, NULL); - Py_DECREF(self0); - - if (offset == NULL) - return -1; - - /* Reduce this to a hash of another object. */ - if (offset == Py_None) - self->hashcode = generic_hash( - (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE); - else { - PyObject *temp1, *temp2; - int seconds, microseconds; - assert(HASTZINFO(self)); - seconds = TIME_GET_HOUR(self) * 3600 + - TIME_GET_MINUTE(self) * 60 + - TIME_GET_SECOND(self); - microseconds = TIME_GET_MICROSECOND(self); - temp1 = new_delta(0, seconds, microseconds, 1); - if (temp1 == NULL) { - Py_DECREF(offset); - return -1; - } - temp2 = delta_subtract(temp1, offset); - Py_DECREF(temp1); - if (temp2 == NULL) { - Py_DECREF(offset); - return -1; - } - self->hashcode = PyObject_Hash(temp2); - Py_DECREF(temp2); - } - Py_DECREF(offset); - } - return self->hashcode; -} - -static PyObject * -time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) -{ - PyObject *clone; - PyObject *tuple; - int hh = TIME_GET_HOUR(self); - int mm = TIME_GET_MINUTE(self); - int ss = TIME_GET_SECOND(self); - int us = TIME_GET_MICROSECOND(self); - PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; - int fold = TIME_GET_FOLD(self); - - if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace", - time_kws, - &hh, &mm, &ss, &us, &tzinfo, &fold)) - return NULL; - if (fold != 0 && fold != 1) { - PyErr_SetString(PyExc_ValueError, - "fold must be either 0 or 1"); - return NULL; - } - tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo); - if (tuple == NULL) - return NULL; - clone = time_new(Py_TYPE(self), tuple, NULL); - if (clone != NULL) { - TIME_SET_FOLD(clone, fold); - } - Py_DECREF(tuple); - return clone; -} - -static PyObject * -time_fromisoformat(PyObject *cls, PyObject *tstr) { - assert(tstr != NULL); - - if (!PyUnicode_Check(tstr)) { - PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str"); - return NULL; - } - - Py_ssize_t len; - const char *p = PyUnicode_AsUTF8AndSize(tstr, &len); - - if (p == NULL) { - goto invalid_string_error; - } - - int hour = 0, minute = 0, second = 0, microsecond = 0; - int tzoffset, tzimicrosecond = 0; - int rv = parse_isoformat_time(p, len, - &hour, &minute, &second, µsecond, - &tzoffset, &tzimicrosecond); - - if (rv < 0) { - goto invalid_string_error; - } - - PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, - tzimicrosecond); - - if (tzinfo == NULL) { - return NULL; - } - - PyObject *t; - if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) { - t = new_time(hour, minute, second, microsecond, tzinfo, 0); - } else { - t = PyObject_CallFunction(cls, "iiiiO", - hour, minute, second, microsecond, tzinfo); - } - - Py_DECREF(tzinfo); - return t; - -invalid_string_error: - PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr); - return NULL; -} - - -/* Pickle support, a simple use of __reduce__. */ - -/* Let basestate be the non-tzinfo data string. - * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). - * So it's a tuple in any (non-error) case. - * __getstate__ isn't exposed. - */ -static PyObject * -time_getstate(PyDateTime_Time *self, int proto) -{ - PyObject *basestate; - PyObject *result = NULL; - - basestate = PyBytes_FromStringAndSize((char *)self->data, - _PyDateTime_TIME_DATASIZE); - if (basestate != NULL) { - if (proto > 3 && TIME_GET_FOLD(self)) - /* Set the first bit of the first byte */ - PyBytes_AS_STRING(basestate)[0] |= (1 << 7); - if (! HASTZINFO(self) || self->tzinfo == Py_None) - result = PyTuple_Pack(1, basestate); - else - result = PyTuple_Pack(2, basestate, self->tzinfo); - Py_DECREF(basestate); - } - return result; -} - -static PyObject * -time_reduce_ex(PyDateTime_Time *self, PyObject *args) -{ - int proto; - if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto)) - return NULL; - - return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto)); -} - -static PyObject * -time_reduce(PyDateTime_Time *self, PyObject *arg) -{ - return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2)); -} - -static PyMethodDef time_methods[] = { - - {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]" - "[+HH:MM].\n\n" - "The optional argument timespec specifies the number " - "of additional terms\nof the time to include. Valid " - "options are 'auto', 'hours', 'minutes',\n'seconds', " - "'milliseconds' and 'microseconds'.\n")}, - - {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("format -> strftime() style string.")}, - - {"__format__", (PyCFunction)date_format, METH_VARARGS, - PyDoc_STR("Formats self with strftime.")}, - - {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS, - PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, - - {"tzname", (PyCFunction)time_tzname, METH_NOARGS, - PyDoc_STR("Return self.tzinfo.tzname(self).")}, - - {"dst", (PyCFunction)time_dst, METH_NOARGS, - PyDoc_STR("Return self.tzinfo.dst(self).")}, - - {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Return time with new specified fields.")}, - - {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS, - PyDoc_STR("string -> time from time.isoformat() output")}, - - {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS, - PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, - - {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS, - PyDoc_STR("__reduce__() -> (cls, state)")}, - - {NULL, NULL} -}; - -static const char time_doc[] = -PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\ -\n\ -All arguments are optional. tzinfo may be None, or an instance of\n\ -a tzinfo subclass. The remaining arguments may be ints.\n"); - -static PyTypeObject PyDateTime_TimeType = { - PyVarObject_HEAD_INIT(NULL, 0) - "datetime.time", /* tp_name */ - sizeof(PyDateTime_Time), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)time_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)time_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)time_hash, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)time_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - time_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - time_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - time_methods, /* tp_methods */ - 0, /* tp_members */ - time_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - time_alloc, /* tp_alloc */ - time_new, /* tp_new */ - 0, /* tp_free */ -}; - -/* - * PyDateTime_DateTime implementation. - */ - -/* Accessor properties. Properties for day, month, and year are inherited - * from date. - */ - -static PyObject * -datetime_hour(PyDateTime_DateTime *self, void *unused) -{ - return PyLong_FromLong(DATE_GET_HOUR(self)); -} - -static PyObject * -datetime_minute(PyDateTime_DateTime *self, void *unused) -{ - return PyLong_FromLong(DATE_GET_MINUTE(self)); -} - -static PyObject * -datetime_second(PyDateTime_DateTime *self, void *unused) -{ - return PyLong_FromLong(DATE_GET_SECOND(self)); -} - -static PyObject * -datetime_microsecond(PyDateTime_DateTime *self, void *unused) -{ - return PyLong_FromLong(DATE_GET_MICROSECOND(self)); -} - -static PyObject * -datetime_tzinfo(PyDateTime_DateTime *self, void *unused) -{ - PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; - Py_INCREF(result); - return result; -} - -static PyObject * -datetime_fold(PyDateTime_DateTime *self, void *unused) -{ - return PyLong_FromLong(DATE_GET_FOLD(self)); -} - -static PyGetSetDef datetime_getset[] = { - {"hour", (getter)datetime_hour}, - {"minute", (getter)datetime_minute}, - {"second", (getter)datetime_second}, - {"microsecond", (getter)datetime_microsecond}, - {"tzinfo", (getter)datetime_tzinfo}, - {"fold", (getter)datetime_fold}, - {NULL} -}; - -/* - * Constructors. - */ - -static char *datetime_kws[] = { - "year", "month", "day", "hour", "minute", "second", - "microsecond", "tzinfo", "fold", NULL -}; - -static PyObject * -datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) -{ - PyDateTime_DateTime *me; - char aware = (char)(tzinfo != Py_None); - - if (aware && check_tzinfo_subclass(tzinfo) < 0) { - PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg"); - return NULL; - } - - me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware)); - if (me != NULL) { - const char *pdata = PyBytes_AS_STRING(state); - - memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE); - me->hashcode = -1; - me->hastzinfo = aware; - if (aware) { - Py_INCREF(tzinfo); - me->tzinfo = tzinfo; - } - if (pdata[2] & (1 << 7)) { - me->data[2] -= 128; - me->fold = 1; - } - else { - me->fold = 0; - } - } - return (PyObject *)me; -} - -static PyObject * -datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - PyObject *self = NULL; - int year; - int month; - int day; - int hour = 0; - int minute = 0; - int second = 0; - int usecond = 0; - int fold = 0; - PyObject *tzinfo = Py_None; - - /* Check for invocation from pickle with __getstate__ state */ - if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) { - PyObject *state = PyTuple_GET_ITEM(args, 0); - if (PyTuple_GET_SIZE(args) == 2) { - tzinfo = PyTuple_GET_ITEM(args, 1); - } - if (PyBytes_Check(state)) { - if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && - MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F)) - { - return datetime_from_pickle(type, state, tzinfo); - } - } - else if (PyUnicode_Check(state)) { - if (PyUnicode_READY(state)) { - return NULL; - } - if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE && - MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F)) - { - state = PyUnicode_AsLatin1String(state); - if (state == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { - /* More informative error message. */ - PyErr_SetString(PyExc_ValueError, - "Failed to encode latin1 string when unpickling " - "a datetime object. " - "pickle.load(data, encoding='latin1') is assumed."); - } - return NULL; - } - self = datetime_from_pickle(type, state, tzinfo); - Py_DECREF(state); - return self; - } - } - tzinfo = Py_None; - } - - if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws, - &year, &month, &day, &hour, &minute, - &second, &usecond, &tzinfo, &fold)) { - self = new_datetime_ex2(year, month, day, - hour, minute, second, usecond, - tzinfo, fold, type); - } - return self; -} - -/* TM_FUNC is the shared type of _PyTime_localtime() and - * _PyTime_gmtime(). */ -typedef int (*TM_FUNC)(time_t timer, struct tm*); - -/* As of version 2015f max fold in IANA database is - * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */ -static long long max_fold_seconds = 24 * 3600; -/* NB: date(1970,1,1).toordinal() == 719163 */ -static long long epoch = 719163LL * 24 * 60 * 60; - -static long long -utc_to_seconds(int year, int month, int day, - int hour, int minute, int second) -{ - long long ordinal; - - /* ymd_to_ord() doesn't support year <= 0 */ - if (year < MINYEAR || year > MAXYEAR) { - PyErr_Format(PyExc_ValueError, "year %i is out of range", year); - return -1; - } - - ordinal = ymd_to_ord(year, month, day); - return ((ordinal * 24 + hour) * 60 + minute) * 60 + second; -} - -static long long -local(long long u) -{ - struct tm local_time; - time_t t; - u -= epoch; - t = u; - if (t != u) { - PyErr_SetString(PyExc_OverflowError, - "timestamp out of range for platform time_t"); - return -1; - } - if (_PyTime_localtime(t, &local_time) != 0) - return -1; - return utc_to_seconds(local_time.tm_year + 1900, - local_time.tm_mon + 1, - local_time.tm_mday, - local_time.tm_hour, - local_time.tm_min, - local_time.tm_sec); -} - -/* Internal helper. - * Build datetime from a time_t and a distinct count of microseconds. - * Pass localtime or gmtime for f, to control the interpretation of timet. - */ -static PyObject * -datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, - PyObject *tzinfo) -{ - struct tm tm; - int year, month, day, hour, minute, second, fold = 0; - - if (f(timet, &tm) != 0) - return NULL; - - year = tm.tm_year + 1900; - month = tm.tm_mon + 1; - day = tm.tm_mday; - hour = tm.tm_hour; - minute = tm.tm_min; - /* The platform localtime/gmtime may insert leap seconds, - * indicated by tm.tm_sec > 59. We don't care about them, - * except to the extent that passing them on to the datetime - * constructor would raise ValueError for a reason that - * made no sense to the user. - */ - second = Py_MIN(59, tm.tm_sec); - - /* local timezone requires to compute fold */ - if (tzinfo == Py_None && f == _PyTime_localtime - /* On Windows, passing a negative value to local results - * in an OSError because localtime_s on Windows does - * not support negative timestamps. Unfortunately this - * means that fold detection for time values between - * 0 and max_fold_seconds will result in an identical - * error since we subtract max_fold_seconds to detect a - * fold. However, since we know there haven't been any - * folds in the interval [0, max_fold_seconds) in any - * timezone, we can hackily just forego fold detection - * for this time range. - */ -#ifdef MS_WINDOWS - && (timet - max_fold_seconds > 0) -#endif - ) { - long long probe_seconds, result_seconds, transition; - - result_seconds = utc_to_seconds(year, month, day, - hour, minute, second); - /* Probe max_fold_seconds to detect a fold. */ - probe_seconds = local(epoch + timet - max_fold_seconds); - if (probe_seconds == -1) - return NULL; - transition = result_seconds - probe_seconds - max_fold_seconds; - if (transition < 0) { - probe_seconds = local(epoch + timet + transition); - if (probe_seconds == -1) - return NULL; - if (probe_seconds == result_seconds) - fold = 1; - } - } - return new_datetime_subclass_fold_ex(year, month, day, hour, minute, - second, us, tzinfo, fold, cls); -} - -/* Internal helper. - * Build datetime from a Python timestamp. Pass localtime or gmtime for f, - * to control the interpretation of the timestamp. Since a double doesn't - * have enough bits to cover a datetime's full range of precision, it's - * better to call datetime_from_timet_and_us provided you have a way - * to get that much precision (e.g., C time() isn't good enough). - */ -static PyObject * -datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, - PyObject *tzinfo) -{ - time_t timet; - long us; - - if (_PyTime_ObjectToTimeval(timestamp, - &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1) - return NULL; - - return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); -} - -/* Internal helper. - * Build most accurate possible datetime for current time. Pass localtime or - * gmtime for f as appropriate. - */ -static PyObject * -datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo) -{ - _PyTime_t ts = _PyTime_GetSystemClock(); - time_t secs; - int us; - - if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0) - return NULL; - assert(0 <= us && us <= 999999); - - return datetime_from_timet_and_us(cls, f, secs, us, tzinfo); -} - -/*[clinic input] - -@classmethod -datetime.datetime.now - - tz: object = None - Timezone object. - -Returns new datetime object representing current time local to tz. - -If no tz is specified, uses local timezone. -[clinic start generated code]*/ - -static PyObject * -datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) -/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/ -{ - PyObject *self; - - /* Return best possible local time -- this isn't constrained by the - * precision of a timestamp. - */ - if (check_tzinfo_subclass(tz) < 0) - return NULL; - - self = datetime_best_possible((PyObject *)type, - tz == Py_None ? _PyTime_localtime : - _PyTime_gmtime, - tz); - if (self != NULL && tz != Py_None) { - /* Convert UTC to tzinfo's zone. */ - self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self); - } - return self; -} - -/* Return best possible UTC time -- this isn't constrained by the - * precision of a timestamp. - */ -static PyObject * -datetime_utcnow(PyObject *cls, PyObject *dummy) -{ - return datetime_best_possible(cls, _PyTime_gmtime, Py_None); -} - -/* Return new local datetime from timestamp (Python timestamp -- a double). */ -static PyObject * -datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) -{ - PyObject *self; - PyObject *timestamp; - PyObject *tzinfo = Py_None; - static char *keywords[] = {"timestamp", "tz", NULL}; - - if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp", - keywords, ×tamp, &tzinfo)) - return NULL; - if (check_tzinfo_subclass(tzinfo) < 0) - return NULL; - - self = datetime_from_timestamp(cls, - tzinfo == Py_None ? _PyTime_localtime : - _PyTime_gmtime, - timestamp, - tzinfo); - if (self != NULL && tzinfo != Py_None) { - /* Convert UTC to tzinfo's zone. */ - self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self); - } - return self; -} - -/* Return new UTC datetime from timestamp (Python timestamp -- a double). */ -static PyObject * -datetime_utcfromtimestamp(PyObject *cls, PyObject *args) -{ - PyObject *timestamp; - PyObject *result = NULL; - - if (PyArg_ParseTuple(args, "O:utcfromtimestamp", ×tamp)) - result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp, - Py_None); - return result; -} - -/* Return new datetime from _strptime.strptime_datetime(). */ -static PyObject * -datetime_strptime(PyObject *cls, PyObject *args) -{ - static PyObject *module = NULL; - PyObject *string, *format; - _Py_IDENTIFIER(_strptime_datetime); - - if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format)) - return NULL; - - if (module == NULL) { - module = PyImport_ImportModuleNoBlock("_strptime"); - if (module == NULL) - return NULL; - } - return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime, - cls, string, format, NULL); -} - -/* Return new datetime from date/datetime and time arguments. */ -static PyObject * -datetime_combine(PyObject *cls, PyObject *args, PyObject *kw) -{ - static char *keywords[] = {"date", "time", "tzinfo", NULL}; - PyObject *date; - PyObject *time; - PyObject *tzinfo = NULL; - PyObject *result = NULL; - - if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords, - &PyDateTime_DateType, &date, - &PyDateTime_TimeType, &time, &tzinfo)) { - if (tzinfo == NULL) { - if (HASTZINFO(time)) - tzinfo = ((PyDateTime_Time *)time)->tzinfo; - else - tzinfo = Py_None; - } - result = new_datetime_subclass_fold_ex(GET_YEAR(date), - GET_MONTH(date), - GET_DAY(date), - TIME_GET_HOUR(time), - TIME_GET_MINUTE(time), - TIME_GET_SECOND(time), - TIME_GET_MICROSECOND(time), - tzinfo, - TIME_GET_FOLD(time), - cls); - } - return result; -} - -static PyObject * -_sanitize_isoformat_str(PyObject *dtstr) -{ - // `fromisoformat` allows surrogate characters in exactly one position, - // the separator; to allow datetime_fromisoformat to make the simplifying - // assumption that all valid strings can be encoded in UTF-8, this function - // replaces any surrogate character separators with `T`. - // - // The result of this, if not NULL, returns a new reference - Py_ssize_t len = PyUnicode_GetLength(dtstr); - if (len < 0) { - return NULL; - } - - if (len <= 10 || - !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) { - Py_INCREF(dtstr); - return dtstr; - } - - PyObject *str_out = _PyUnicode_Copy(dtstr); - if (str_out == NULL) { - return NULL; - } - - if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) { - Py_DECREF(str_out); - return NULL; - } - - return str_out; -} - -static PyObject * -datetime_fromisoformat(PyObject *cls, PyObject *dtstr) -{ - assert(dtstr != NULL); - - if (!PyUnicode_Check(dtstr)) { - PyErr_SetString(PyExc_TypeError, - "fromisoformat: argument must be str"); - return NULL; - } - - PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr); - if (dtstr_clean == NULL) { - goto error; - } - - Py_ssize_t len; - const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len); - - if (dt_ptr == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { - // Encoding errors are invalid string errors at this point - goto invalid_string_error; - } - else { - goto error; - } - } - - const char *p = dt_ptr; - - int year = 0, month = 0, day = 0; - int hour = 0, minute = 0, second = 0, microsecond = 0; - int tzoffset = 0, tzusec = 0; - - // date has a fixed length of 10 - int rv = parse_isoformat_date(p, &year, &month, &day); - - if (!rv && len > 10) { - // In UTF-8, the length of multi-byte characters is encoded in the MSB - if ((p[10] & 0x80) == 0) { - p += 11; - } - else { - switch (p[10] & 0xf0) { - case 0xe0: - p += 13; - break; - case 0xf0: - p += 14; - break; - default: - p += 12; - break; - } - } - - len -= (p - dt_ptr); - rv = parse_isoformat_time(p, len, &hour, &minute, &second, - µsecond, &tzoffset, &tzusec); - } - if (rv < 0) { - goto invalid_string_error; - } - - PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec); - if (tzinfo == NULL) { - goto error; - } - - PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute, - second, microsecond, tzinfo, cls); - - Py_DECREF(tzinfo); - Py_DECREF(dtstr_clean); - return dt; - -invalid_string_error: - PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr); - -error: - Py_XDECREF(dtstr_clean); - - return NULL; -} - -/* - * Destructor. - */ - -static void -datetime_dealloc(PyDateTime_DateTime *self) -{ - if (HASTZINFO(self)) { - Py_XDECREF(self->tzinfo); - } - Py_TYPE(self)->tp_free((PyObject *)self); -} - -/* - * Indirect access to tzinfo methods. - */ - -/* These are all METH_NOARGS, so don't need to check the arglist. */ -static PyObject * -datetime_utcoffset(PyObject *self, PyObject *unused) { - return call_utcoffset(GET_DT_TZINFO(self), self); -} - -static PyObject * -datetime_dst(PyObject *self, PyObject *unused) { - return call_dst(GET_DT_TZINFO(self), self); -} - -static PyObject * -datetime_tzname(PyObject *self, PyObject *unused) { - return call_tzname(GET_DT_TZINFO(self), self); -} - -/* - * datetime arithmetic. - */ - -/* factor must be 1 (to add) or -1 (to subtract). The result inherits - * the tzinfo state of date. - */ -static PyObject * -add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta, - int factor) -{ - /* Note that the C-level additions can't overflow, because of - * invariant bounds on the member values. - */ - int year = GET_YEAR(date); - int month = GET_MONTH(date); - int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor; - int hour = DATE_GET_HOUR(date); - int minute = DATE_GET_MINUTE(date); - int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor; - int microsecond = DATE_GET_MICROSECOND(date) + - GET_TD_MICROSECONDS(delta) * factor; - - assert(factor == 1 || factor == -1); - if (normalize_datetime(&year, &month, &day, - &hour, &minute, &second, µsecond) < 0) { - return NULL; - } - - return new_datetime_subclass_ex(year, month, day, - hour, minute, second, microsecond, - HASTZINFO(date) ? date->tzinfo : Py_None, - (PyObject *)Py_TYPE(date)); -} - -static PyObject * -datetime_add(PyObject *left, PyObject *right) -{ - if (PyDateTime_Check(left)) { - /* datetime + ??? */ - if (PyDelta_Check(right)) - /* datetime + delta */ - return add_datetime_timedelta( - (PyDateTime_DateTime *)left, - (PyDateTime_Delta *)right, - 1); - } - else if (PyDelta_Check(left)) { - /* delta + datetime */ - return add_datetime_timedelta((PyDateTime_DateTime *) right, - (PyDateTime_Delta *) left, - 1); - } - Py_RETURN_NOTIMPLEMENTED; -} - -static PyObject * -datetime_subtract(PyObject *left, PyObject *right) -{ - PyObject *result = Py_NotImplemented; - - if (PyDateTime_Check(left)) { - /* datetime - ??? */ - if (PyDateTime_Check(right)) { - /* datetime - datetime */ - PyObject *offset1, *offset2, *offdiff = NULL; - int delta_d, delta_s, delta_us; - - if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) { - offset2 = offset1 = Py_None; - Py_INCREF(offset1); - Py_INCREF(offset2); - } - else { - offset1 = datetime_utcoffset(left, NULL); - if (offset1 == NULL) - return NULL; - offset2 = datetime_utcoffset(right, NULL); - if (offset2 == NULL) { - Py_DECREF(offset1); - return NULL; - } - if ((offset1 != Py_None) != (offset2 != Py_None)) { - PyErr_SetString(PyExc_TypeError, - "can't subtract offset-naive and " - "offset-aware datetimes"); - Py_DECREF(offset1); - Py_DECREF(offset2); - return NULL; - } - } - if ((offset1 != offset2) && - delta_cmp(offset1, offset2) != 0) { - offdiff = delta_subtract(offset1, offset2); - if (offdiff == NULL) { - Py_DECREF(offset1); - Py_DECREF(offset2); - return NULL; - } - } - Py_DECREF(offset1); - Py_DECREF(offset2); - delta_d = ymd_to_ord(GET_YEAR(left), - GET_MONTH(left), - GET_DAY(left)) - - ymd_to_ord(GET_YEAR(right), - GET_MONTH(right), - GET_DAY(right)); - /* These can't overflow, since the values are - * normalized. At most this gives the number of - * seconds in one day. - */ - delta_s = (DATE_GET_HOUR(left) - - DATE_GET_HOUR(right)) * 3600 + - (DATE_GET_MINUTE(left) - - DATE_GET_MINUTE(right)) * 60 + - (DATE_GET_SECOND(left) - - DATE_GET_SECOND(right)); - delta_us = DATE_GET_MICROSECOND(left) - - DATE_GET_MICROSECOND(right); - result = new_delta(delta_d, delta_s, delta_us, 1); - if (result == NULL) - return NULL; - - if (offdiff != NULL) { - Py_SETREF(result, delta_subtract(result, offdiff)); - Py_DECREF(offdiff); - } - } - else if (PyDelta_Check(right)) { - /* datetime - delta */ - result = add_datetime_timedelta( - (PyDateTime_DateTime *)left, - (PyDateTime_Delta *)right, - -1); - } - } - - if (result == Py_NotImplemented) - Py_INCREF(result); - return result; -} - -/* Various ways to turn a datetime into a string. */ - -static PyObject * -datetime_repr(PyDateTime_DateTime *self) -{ - const char *type_name = Py_TYPE(self)->tp_name; - PyObject *baserepr; - - if (DATE_GET_MICROSECOND(self)) { - baserepr = PyUnicode_FromFormat( - "%s(%d, %d, %d, %d, %d, %d, %d)", - type_name, - GET_YEAR(self), GET_MONTH(self), GET_DAY(self), - DATE_GET_HOUR(self), DATE_GET_MINUTE(self), - DATE_GET_SECOND(self), - DATE_GET_MICROSECOND(self)); - } - else if (DATE_GET_SECOND(self)) { - baserepr = PyUnicode_FromFormat( - "%s(%d, %d, %d, %d, %d, %d)", - type_name, - GET_YEAR(self), GET_MONTH(self), GET_DAY(self), - DATE_GET_HOUR(self), DATE_GET_MINUTE(self), - DATE_GET_SECOND(self)); - } - else { - baserepr = PyUnicode_FromFormat( - "%s(%d, %d, %d, %d, %d)", - type_name, - GET_YEAR(self), GET_MONTH(self), GET_DAY(self), - DATE_GET_HOUR(self), DATE_GET_MINUTE(self)); - } - if (baserepr != NULL && DATE_GET_FOLD(self) != 0) - baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self)); - if (baserepr == NULL || ! HASTZINFO(self)) - return baserepr; - return append_keyword_tzinfo(baserepr, self->tzinfo); -} - -static PyObject * -datetime_str(PyDateTime_DateTime *self) -{ - return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " "); -} - -static PyObject * -datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) -{ - int sep = 'T'; - char *timespec = NULL; - static char *keywords[] = {"sep", "timespec", NULL}; - char buffer[100]; - PyObject *result = NULL; - int us = DATE_GET_MICROSECOND(self); - static const char *specs[][2] = { - {"hours", "%04d-%02d-%02d%c%02d"}, - {"minutes", "%04d-%02d-%02d%c%02d:%02d"}, - {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"}, - {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"}, - {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"}, - }; - size_t given_spec; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, ×pec)) - return NULL; - - if (timespec == NULL || strcmp(timespec, "auto") == 0) { - if (us == 0) { - /* seconds */ - given_spec = 2; - } - else { - /* microseconds */ - given_spec = 4; - } - } - else { - for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) { - if (strcmp(timespec, specs[given_spec][0]) == 0) { - if (given_spec == 3) { - us = us / 1000; - } - break; - } - } - } - - if (given_spec == Py_ARRAY_LENGTH(specs)) { - PyErr_Format(PyExc_ValueError, "Unknown timespec value"); - return NULL; - } - else { - result = PyUnicode_FromFormat(specs[given_spec][1], - GET_YEAR(self), GET_MONTH(self), - GET_DAY(self), (int)sep, - DATE_GET_HOUR(self), DATE_GET_MINUTE(self), - DATE_GET_SECOND(self), us); - } - - if (!result || !HASTZINFO(self)) - return result; - - /* We need to append the UTC offset. */ - if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo, - (PyObject *)self) < 0) { - Py_DECREF(result); - return NULL; - } - PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer)); - return result; -} - -static PyObject * -datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) -{ - return format_ctime((PyDateTime_Date *)self, - DATE_GET_HOUR(self), - DATE_GET_MINUTE(self), - DATE_GET_SECOND(self)); -} - -/* Miscellaneous methods. */ - -static PyObject * -flip_fold(PyObject *dt) -{ - return new_datetime_ex2(GET_YEAR(dt), - GET_MONTH(dt), - GET_DAY(dt), - DATE_GET_HOUR(dt), - DATE_GET_MINUTE(dt), - DATE_GET_SECOND(dt), - DATE_GET_MICROSECOND(dt), - HASTZINFO(dt) ? - ((PyDateTime_DateTime *)dt)->tzinfo : Py_None, - !DATE_GET_FOLD(dt), - Py_TYPE(dt)); -} - -static PyObject * -get_flip_fold_offset(PyObject *dt) -{ - PyObject *result, *flip_dt; - - flip_dt = flip_fold(dt); - if (flip_dt == NULL) - return NULL; - result = datetime_utcoffset(flip_dt, NULL); - Py_DECREF(flip_dt); - return result; -} - -/* PEP 495 exception: Whenever one or both of the operands in - * inter-zone comparison is such that its utcoffset() depends - * on the value of its fold attribute, the result is False. - * - * Return 1 if exception applies, 0 if not, and -1 on error. - */ -static int -pep495_eq_exception(PyObject *self, PyObject *other, - PyObject *offset_self, PyObject *offset_other) -{ - int result = 0; - PyObject *flip_offset; - - flip_offset = get_flip_fold_offset(self); - if (flip_offset == NULL) - return -1; - if (flip_offset != offset_self && - delta_cmp(flip_offset, offset_self)) - { - result = 1; - goto done; - } - Py_DECREF(flip_offset); - - flip_offset = get_flip_fold_offset(other); - if (flip_offset == NULL) - return -1; - if (flip_offset != offset_other && - delta_cmp(flip_offset, offset_other)) - result = 1; - done: - Py_DECREF(flip_offset); - return result; -} - -static PyObject * -datetime_richcompare(PyObject *self, PyObject *other, int op) -{ - PyObject *result = NULL; - PyObject *offset1, *offset2; - int diff; - - if (! PyDateTime_Check(other)) { - if (PyDate_Check(other)) { - /* Prevent invocation of date_richcompare. We want to - return NotImplemented here to give the other object - a chance. But since DateTime is a subclass of - Date, if the other object is a Date, it would - compute an ordering based on the date part alone, - and we don't want that. So force unequal or - uncomparable here in that case. */ - if (op == Py_EQ) - Py_RETURN_FALSE; - if (op == Py_NE) - Py_RETURN_TRUE; - return cmperror(self, other); - } - Py_RETURN_NOTIMPLEMENTED; - } - - if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) { - diff = memcmp(((PyDateTime_DateTime *)self)->data, - ((PyDateTime_DateTime *)other)->data, - _PyDateTime_DATETIME_DATASIZE); - return diff_to_bool(diff, op); - } - offset1 = datetime_utcoffset(self, NULL); - if (offset1 == NULL) - return NULL; - offset2 = datetime_utcoffset(other, NULL); - if (offset2 == NULL) - goto done; - /* If they're both naive, or both aware and have the same offsets, - * we get off cheap. Note that if they're both naive, offset1 == - * offset2 == Py_None at this point. - */ - if ((offset1 == offset2) || - (PyDelta_Check(offset1) && PyDelta_Check(offset2) && - delta_cmp(offset1, offset2) == 0)) { - diff = memcmp(((PyDateTime_DateTime *)self)->data, - ((PyDateTime_DateTime *)other)->data, - _PyDateTime_DATETIME_DATASIZE); - if ((op == Py_EQ || op == Py_NE) && diff == 0) { - int ex = pep495_eq_exception(self, other, offset1, offset2); - if (ex == -1) - goto done; - if (ex) - diff = 1; - } - result = diff_to_bool(diff, op); - } - else if (offset1 != Py_None && offset2 != Py_None) { - PyDateTime_Delta *delta; - - assert(offset1 != offset2); /* else last "if" handled it */ - delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self, - other); - if (delta == NULL) - goto done; - diff = GET_TD_DAYS(delta); - if (diff == 0) - diff = GET_TD_SECONDS(delta) | - GET_TD_MICROSECONDS(delta); - Py_DECREF(delta); - if ((op == Py_EQ || op == Py_NE) && diff == 0) { - int ex = pep495_eq_exception(self, other, offset1, offset2); - if (ex == -1) - goto done; - if (ex) - diff = 1; - } - result = diff_to_bool(diff, op); - } - else if (op == Py_EQ) { - result = Py_False; - Py_INCREF(result); - } - else if (op == Py_NE) { - result = Py_True; - Py_INCREF(result); - } - else { - PyErr_SetString(PyExc_TypeError, - "can't compare offset-naive and " - "offset-aware datetimes"); - } - done: - Py_DECREF(offset1); - Py_XDECREF(offset2); - return result; -} - -static Py_hash_t -datetime_hash(PyDateTime_DateTime *self) -{ - if (self->hashcode == -1) { - PyObject *offset, *self0; - if (DATE_GET_FOLD(self)) { - self0 = new_datetime_ex2(GET_YEAR(self), - GET_MONTH(self), - GET_DAY(self), - DATE_GET_HOUR(self), - DATE_GET_MINUTE(self), - DATE_GET_SECOND(self), - DATE_GET_MICROSECOND(self), - HASTZINFO(self) ? self->tzinfo : Py_None, - 0, Py_TYPE(self)); - if (self0 == NULL) - return -1; - } - else { - self0 = (PyObject *)self; - Py_INCREF(self0); - } - offset = datetime_utcoffset(self0, NULL); - Py_DECREF(self0); - - if (offset == NULL) - return -1; - - /* Reduce this to a hash of another object. */ - if (offset == Py_None) - self->hashcode = generic_hash( - (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE); - else { - PyObject *temp1, *temp2; - int days, seconds; - - assert(HASTZINFO(self)); - days = ymd_to_ord(GET_YEAR(self), - GET_MONTH(self), - GET_DAY(self)); - seconds = DATE_GET_HOUR(self) * 3600 + - DATE_GET_MINUTE(self) * 60 + - DATE_GET_SECOND(self); - temp1 = new_delta(days, seconds, - DATE_GET_MICROSECOND(self), - 1); - if (temp1 == NULL) { - Py_DECREF(offset); - return -1; - } - temp2 = delta_subtract(temp1, offset); - Py_DECREF(temp1); - if (temp2 == NULL) { - Py_DECREF(offset); - return -1; - } - self->hashcode = PyObject_Hash(temp2); - Py_DECREF(temp2); - } - Py_DECREF(offset); - } - return self->hashcode; -} - -static PyObject * -datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) -{ - PyObject *clone; - PyObject *tuple; - int y = GET_YEAR(self); - int m = GET_MONTH(self); - int d = GET_DAY(self); - int hh = DATE_GET_HOUR(self); - int mm = DATE_GET_MINUTE(self); - int ss = DATE_GET_SECOND(self); - int us = DATE_GET_MICROSECOND(self); - PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; - int fold = DATE_GET_FOLD(self); - - if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace", - datetime_kws, - &y, &m, &d, &hh, &mm, &ss, &us, - &tzinfo, &fold)) - return NULL; - if (fold != 0 && fold != 1) { - PyErr_SetString(PyExc_ValueError, - "fold must be either 0 or 1"); - return NULL; - } - tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo); - if (tuple == NULL) - return NULL; - clone = datetime_new(Py_TYPE(self), tuple, NULL); - if (clone != NULL) { - DATE_SET_FOLD(clone, fold); - } - Py_DECREF(tuple); - return clone; -} - -static PyObject * -local_timezone_from_timestamp(time_t timestamp) -{ - PyObject *result = NULL; - PyObject *delta; - struct tm local_time_tm; - PyObject *nameo = NULL; - const char *zone = NULL; - - if (_PyTime_localtime(timestamp, &local_time_tm) != 0) - return NULL; -#ifdef HAVE_STRUCT_TM_TM_ZONE - zone = local_time_tm.tm_zone; - delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1); -#else /* HAVE_STRUCT_TM_TM_ZONE */ - { - PyObject *local_time, *utc_time; - struct tm utc_time_tm; - char buf[100]; - strftime(buf, sizeof(buf), "%Z", &local_time_tm); - zone = buf; - local_time = new_datetime(local_time_tm.tm_year + 1900, - local_time_tm.tm_mon + 1, - local_time_tm.tm_mday, - local_time_tm.tm_hour, - local_time_tm.tm_min, - local_time_tm.tm_sec, 0, Py_None, 0); - if (local_time == NULL) { - return NULL; - } - if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0) - return NULL; - utc_time = new_datetime(utc_time_tm.tm_year + 1900, - utc_time_tm.tm_mon + 1, - utc_time_tm.tm_mday, - utc_time_tm.tm_hour, - utc_time_tm.tm_min, - utc_time_tm.tm_sec, 0, Py_None, 0); - if (utc_time == NULL) { - Py_DECREF(local_time); - return NULL; - } - delta = datetime_subtract(local_time, utc_time); - Py_DECREF(local_time); - Py_DECREF(utc_time); - } -#endif /* HAVE_STRUCT_TM_TM_ZONE */ - if (delta == NULL) { - return NULL; - } - if (zone != NULL) { - nameo = PyUnicode_DecodeLocale(zone, "surrogateescape"); - if (nameo == NULL) - goto error; - } - result = new_timezone(delta, nameo); - Py_XDECREF(nameo); - error: - Py_DECREF(delta); - return result; -} - -static PyObject * -local_timezone(PyDateTime_DateTime *utc_time) -{ - time_t timestamp; - PyObject *delta; - PyObject *one_second; - PyObject *seconds; - - delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch); - if (delta == NULL) - return NULL; - one_second = new_delta(0, 1, 0, 0); - if (one_second == NULL) { - Py_DECREF(delta); - return NULL; - } - seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta, - (PyDateTime_Delta *)one_second); - Py_DECREF(one_second); - Py_DECREF(delta); - if (seconds == NULL) - return NULL; - timestamp = _PyLong_AsTime_t(seconds); - Py_DECREF(seconds); - if (timestamp == -1 && PyErr_Occurred()) - return NULL; - return local_timezone_from_timestamp(timestamp); -} - -static long long -local_to_seconds(int year, int month, int day, - int hour, int minute, int second, int fold); - -static PyObject * -local_timezone_from_local(PyDateTime_DateTime *local_dt) -{ - long long seconds; - time_t timestamp; - seconds = local_to_seconds(GET_YEAR(local_dt), - GET_MONTH(local_dt), - GET_DAY(local_dt), - DATE_GET_HOUR(local_dt), - DATE_GET_MINUTE(local_dt), - DATE_GET_SECOND(local_dt), - DATE_GET_FOLD(local_dt)); - if (seconds == -1) - return NULL; - /* XXX: add bounds check */ - timestamp = seconds - epoch; - return local_timezone_from_timestamp(timestamp); -} - -static PyDateTime_DateTime * -datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) -{ - PyDateTime_DateTime *result; - PyObject *offset; - PyObject *temp; - PyObject *self_tzinfo; - PyObject *tzinfo = Py_None; - static char *keywords[] = {"tz", NULL}; - - if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords, - &tzinfo)) - return NULL; - - if (check_tzinfo_subclass(tzinfo) == -1) - return NULL; - - if (!HASTZINFO(self) || self->tzinfo == Py_None) { - naive: - self_tzinfo = local_timezone_from_local(self); - if (self_tzinfo == NULL) - return NULL; - } else { - self_tzinfo = self->tzinfo; - Py_INCREF(self_tzinfo); - } - - /* Conversion to self's own time zone is a NOP. */ - if (self_tzinfo == tzinfo) { - Py_DECREF(self_tzinfo); - Py_INCREF(self); - return self; - } - - /* Convert self to UTC. */ - offset = call_utcoffset(self_tzinfo, (PyObject *)self); - Py_DECREF(self_tzinfo); - if (offset == NULL) - return NULL; - else if(offset == Py_None) { - Py_DECREF(offset); - goto naive; - } - else if (!PyDelta_Check(offset)) { - Py_DECREF(offset); - PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s," - " expected timedelta or None", Py_TYPE(offset)->tp_name); - return NULL; - } - /* result = self - offset */ - result = (PyDateTime_DateTime *)add_datetime_timedelta(self, - (PyDateTime_Delta *)offset, -1); - Py_DECREF(offset); - if (result == NULL) - return NULL; - - /* Make sure result is aware and UTC. */ - if (!HASTZINFO(result)) { - temp = (PyObject *)result; - result = (PyDateTime_DateTime *) - new_datetime_ex2(GET_YEAR(result), - GET_MONTH(result), - GET_DAY(result), - DATE_GET_HOUR(result), - DATE_GET_MINUTE(result), - DATE_GET_SECOND(result), - DATE_GET_MICROSECOND(result), - PyDateTime_TimeZone_UTC, - DATE_GET_FOLD(result), - Py_TYPE(result)); - Py_DECREF(temp); - if (result == NULL) - return NULL; - } - else { - /* Result is already aware - just replace tzinfo. */ - temp = result->tzinfo; - result->tzinfo = PyDateTime_TimeZone_UTC; - Py_INCREF(result->tzinfo); - Py_DECREF(temp); - } - - /* Attach new tzinfo and let fromutc() do the rest. */ - temp = result->tzinfo; - if (tzinfo == Py_None) { - tzinfo = local_timezone(result); - if (tzinfo == NULL) { - Py_DECREF(result); - return NULL; - } - } - else - Py_INCREF(tzinfo); - result->tzinfo = tzinfo; - Py_DECREF(temp); - - temp = (PyObject *)result; - result = (PyDateTime_DateTime *) - _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp); - Py_DECREF(temp); - - return result; -} - -static PyObject * -datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) -{ - int dstflag = -1; - - if (HASTZINFO(self) && self->tzinfo != Py_None) { - PyObject * dst; - - dst = call_dst(self->tzinfo, (PyObject *)self); - if (dst == NULL) - return NULL; - - if (dst != Py_None) - dstflag = delta_bool((PyDateTime_Delta *)dst); - Py_DECREF(dst); - } - return build_struct_time(GET_YEAR(self), - GET_MONTH(self), - GET_DAY(self), - DATE_GET_HOUR(self), - DATE_GET_MINUTE(self), - DATE_GET_SECOND(self), - dstflag); -} - -static long long -local_to_seconds(int year, int month, int day, - int hour, int minute, int second, int fold) -{ - long long t, a, b, u1, u2, t1, t2, lt; - t = utc_to_seconds(year, month, day, hour, minute, second); - /* Our goal is to solve t = local(u) for u. */ - lt = local(t); - if (lt == -1) - return -1; - a = lt - t; - u1 = t - a; - t1 = local(u1); - if (t1 == -1) - return -1; - if (t1 == t) { - /* We found one solution, but it may not be the one we need. - * Look for an earlier solution (if `fold` is 0), or a - * later one (if `fold` is 1). */ - if (fold) - u2 = u1 + max_fold_seconds; - else - u2 = u1 - max_fold_seconds; - lt = local(u2); - if (lt == -1) - return -1; - b = lt - u2; - if (a == b) - return u1; - } - else { - b = t1 - u1; - assert(a != b); - } - u2 = t - b; - t2 = local(u2); - if (t2 == -1) - return -1; - if (t2 == t) - return u2; - if (t1 == t) - return u1; - /* We have found both offsets a and b, but neither t - a nor t - b is - * a solution. This means t is in the gap. */ - return fold?Py_MIN(u1, u2):Py_MAX(u1, u2); -} - -/* date(1970,1,1).toordinal() == 719163 */ -#define EPOCH_SECONDS (719163LL * 24 * 60 * 60) - -static PyObject * -datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *result; +static PyGetSetDef iso_calendar_date_getset[] = { + {"year", (getter)iso_calendar_date_year}, + {"week", (getter)iso_calendar_date_week}, + {"weekday", (getter)iso_calendar_date_weekday}, + {NULL} +}; - if (HASTZINFO(self) && self->tzinfo != Py_None) { - PyObject *delta; - delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch); - if (delta == NULL) - return NULL; - result = delta_total_seconds(delta, NULL); - Py_DECREF(delta); - } - else { - long long seconds; - seconds = local_to_seconds(GET_YEAR(self), - GET_MONTH(self), - GET_DAY(self), - DATE_GET_HOUR(self), - DATE_GET_MINUTE(self), - DATE_GET_SECOND(self), - DATE_GET_FOLD(self)); - if (seconds == -1) - return NULL; - result = PyFloat_FromDouble(seconds - EPOCH_SECONDS + - DATE_GET_MICROSECOND(self) / 1e6); - } - return result; -} +static PyMethodDef iso_calendar_date_methods[] = { + {"__reduce__", (PyCFunction)iso_calendar_date_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + {NULL, NULL}, +}; -static PyObject * -datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) -{ - return new_date(GET_YEAR(self), - GET_MONTH(self), - GET_DAY(self)); -} +static PyTypeObject PyDateTime_IsoCalendarDateType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "datetime.IsoCalendarDate", + .tp_basicsize = sizeof(PyDateTime_IsoCalendarDate), + .tp_repr = (reprfunc) iso_calendar_date_repr, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = iso_calendar_date__doc__, + .tp_methods = iso_calendar_date_methods, + .tp_getset = iso_calendar_date_getset, + // .tp_base = &PyTuple_Type, // filled in PyInit__datetime + .tp_new = iso_calendar_date_new, +}; -static PyObject * -datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) -{ - return new_time(DATE_GET_HOUR(self), - DATE_GET_MINUTE(self), - DATE_GET_SECOND(self), - DATE_GET_MICROSECOND(self), - Py_None, - DATE_GET_FOLD(self)); -} +/*[clinic input] +@classmethod +datetime.IsoCalendarDate.__new__ as iso_calendar_date_new + year: int + week: int + weekday: int +[clinic start generated code]*/ static PyObject * -datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) -{ - return new_time(DATE_GET_HOUR(self), - DATE_GET_MINUTE(self), - DATE_GET_SECOND(self), - DATE_GET_MICROSECOND(self), - GET_DT_TZINFO(self), - DATE_GET_FOLD(self)); -} +iso_calendar_date_new_impl(PyTypeObject *type, int year, int week, + int weekday) +/*[clinic end generated code: output=383d33d8dc7183a2 input=4f2c663c9d19c4ee]*/ -static PyObject * -datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) { - int y, m, d, hh, mm, ss; - PyObject *tzinfo; - PyDateTime_DateTime *utcself; - - tzinfo = GET_DT_TZINFO(self); - if (tzinfo == Py_None) { - utcself = self; - Py_INCREF(utcself); - } - else { - PyObject *offset; - offset = call_utcoffset(tzinfo, (PyObject *)self); - if (offset == NULL) - return NULL; - if (offset == Py_None) { - Py_DECREF(offset); - utcself = self; - Py_INCREF(utcself); - } - else { - utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self, - (PyDateTime_Delta *)offset, -1); - Py_DECREF(offset); - if (utcself == NULL) - return NULL; - } + PyDateTime_IsoCalendarDate *self; + self = (PyDateTime_IsoCalendarDate *) type->tp_alloc(type, 3); + if (self == NULL) { + return NULL; } - y = GET_YEAR(utcself); - m = GET_MONTH(utcself); - d = GET_DAY(utcself); - hh = DATE_GET_HOUR(utcself); - mm = DATE_GET_MINUTE(utcself); - ss = DATE_GET_SECOND(utcself); - Py_DECREF(utcself); - return build_struct_time(y, m, d, hh, mm, ss, 0); -} + PyTuple_SET_ITEM(self, 0, PyLong_FromLong(year)); + PyTuple_SET_ITEM(self, 1, PyLong_FromLong(week)); + PyTuple_SET_ITEM(self, 2, PyLong_FromLong(weekday)); -/* Pickle support, a simple use of __reduce__. */ + return (PyObject *)self; +} -/* Let basestate be the non-tzinfo data string. - * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). - * So it's a tuple in any (non-error) case. - * __getstate__ isn't exposed. - */ static PyObject * -datetime_getstate(PyDateTime_DateTime *self, int proto) -{ - PyObject *basestate; - PyObject *result = NULL; +date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) +{ + int year = GET_YEAR(self); + int week1_monday = iso_week1_monday(year); + int today = ymd_to_ord(year, GET_MONTH(self), GET_DAY(self)); + int week; + int day; + + week = divmod(today - week1_monday, 7, &day); + if (week < 0) { + --year; + week1_monday = iso_week1_monday(year); + week = divmod(today - week1_monday, 7, &day); + } + else if (week >= 52 && today >= iso_week1_monday(year + 1)) { + ++year; + week = 0; + } - basestate = PyBytes_FromStringAndSize((char *)self->data, - _PyDateTime_DATETIME_DATASIZE); - if (basestate != NULL) { - if (proto > 3 && DATE_GET_FOLD(self)) - /* Set the first bit of the third byte */ - PyBytes_AS_STRING(basestate)[2] |= (1 << 7); - if (! HASTZINFO(self) || self->tzinfo == Py_None) - result = PyTuple_Pack(1, basestate); - else - result = PyTuple_Pack(2, basestate, self->tzinfo); - Py_DECREF(basestate); + PyObject* v = iso_calendar_date_new_impl(&PyDateTime_IsoCalendarDateType, + year, week + 1, day + 1); + if (v == NULL) { + return NULL; } - return result; -} + return v; +} + +/* Miscellaneous methods. */ + +static PyObject * +date_richcompare(PyObject *self, PyObject *other, int op) +{ + if (PyDate_Check(other)) { + int diff = memcmp(((PyDateTime_Date *)self)->data, + ((PyDateTime_Date *)other)->data, + _PyDateTime_DATE_DATASIZE); + return diff_to_bool(diff, op); + } + else + Py_RETURN_NOTIMPLEMENTED; +} + +static PyObject * +date_timetuple(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) +{ + return build_struct_time(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self), + 0, 0, 0, -1); +} + +static PyObject * +date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw) +{ + PyObject *clone; + PyObject *tuple; + int year = GET_YEAR(self); + int month = GET_MONTH(self); + int day = GET_DAY(self); + + if (! PyArg_ParseTupleAndKeywords(args, kw, "|iii:replace", date_kws, + &year, &month, &day)) + return NULL; + tuple = Py_BuildValue("iii", year, month, day); + if (tuple == NULL) + return NULL; + clone = date_new(Py_TYPE(self), tuple, NULL); + Py_DECREF(tuple); + return clone; +} + +static Py_hash_t +generic_hash(unsigned char *data, int len) +{ + return _Py_HashBytes(data, len); +} + + +static PyObject *date_getstate(PyDateTime_Date *self); + +static Py_hash_t +date_hash(PyDateTime_Date *self) +{ + if (self->hashcode == -1) { + self->hashcode = generic_hash( + (unsigned char *)self->data, _PyDateTime_DATE_DATASIZE); + } + + return self->hashcode; +} + +static PyObject * +date_toordinal(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) +{ + return PyLong_FromLong(ymd_to_ord(GET_YEAR(self), GET_MONTH(self), + GET_DAY(self))); +} + +static PyObject * +date_weekday(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) +{ + int dow = weekday(GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); + + return PyLong_FromLong(dow); +} + +/* Pickle support, a simple use of __reduce__. */ + +/* __getstate__ isn't exposed */ +static PyObject * +date_getstate(PyDateTime_Date *self) +{ + PyObject* field; + field = PyBytes_FromStringAndSize((char*)self->data, + _PyDateTime_DATE_DATASIZE); + return Py_BuildValue("(N)", field); +} + +static PyObject * +date_reduce(PyDateTime_Date *self, PyObject *arg) +{ + return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self)); +} + +static PyMethodDef date_methods[] = { + + /* Class methods: */ + DATETIME_DATE_FROMTIMESTAMP_METHODDEF + + {"fromordinal", (PyCFunction)date_fromordinal, METH_VARARGS | + METH_CLASS, + PyDoc_STR("int -> date corresponding to a proleptic Gregorian " + "ordinal.")}, + + {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O | + METH_CLASS, + PyDoc_STR("str -> Construct a date from the output of date.isoformat()")}, + + {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("int, int, int -> Construct a date from the ISO year, week " + "number and weekday.\n\n" + "This is the inverse of the date.isocalendar() function")}, -static PyObject * -datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args) -{ - int proto; - if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto)) + {"today", (PyCFunction)date_today, METH_NOARGS | METH_CLASS, + PyDoc_STR("Current date or datetime: same as " + "self.__class__.fromtimestamp(time.time()).")}, + + /* Instance methods: */ + + {"ctime", (PyCFunction)date_ctime, METH_NOARGS, + PyDoc_STR("Return ctime() style string.")}, + + {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("format -> strftime() style string.")}, + + {"__format__", (PyCFunction)date_format, METH_VARARGS, + PyDoc_STR("Formats self with strftime.")}, + + {"timetuple", (PyCFunction)date_timetuple, METH_NOARGS, + PyDoc_STR("Return time tuple, compatible with time.localtime().")}, + + {"isocalendar", (PyCFunction)date_isocalendar, METH_NOARGS, + PyDoc_STR("Return a named tuple containing ISO year, week number, and " + "weekday.")}, + + {"isoformat", (PyCFunction)date_isoformat, METH_NOARGS, + PyDoc_STR("Return string in ISO 8601 format, YYYY-MM-DD.")}, + + {"isoweekday", (PyCFunction)date_isoweekday, METH_NOARGS, + PyDoc_STR("Return the day of the week represented by the date.\n" + "Monday == 1 ... Sunday == 7")}, + + {"toordinal", (PyCFunction)date_toordinal, METH_NOARGS, + PyDoc_STR("Return proleptic Gregorian ordinal. January 1 of year " + "1 is day 1.")}, + + {"weekday", (PyCFunction)date_weekday, METH_NOARGS, + PyDoc_STR("Return the day of the week represented by the date.\n" + "Monday == 0 ... Sunday == 6")}, + + {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("Return date with new specified fields.")}, + + {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + + {NULL, NULL} +}; + +static const char date_doc[] = +PyDoc_STR("date(year, month, day) --> date object"); + +static PyNumberMethods date_as_number = { + date_add, /* nb_add */ + date_subtract, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_bool */ +}; + +static PyTypeObject PyDateTime_DateType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.date", /* tp_name */ + sizeof(PyDateTime_Date), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)date_repr, /* tp_repr */ + &date_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)date_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)date_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + date_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + date_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + date_methods, /* tp_methods */ + 0, /* tp_members */ + date_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + date_new, /* tp_new */ + 0, /* tp_free */ +}; + +/* + * PyDateTime_TZInfo implementation. + */ + +/* This is a pure abstract base class, so doesn't do anything beyond + * raising NotImplemented exceptions. Real tzinfo classes need + * to derive from this. This is mostly for clarity, and for efficiency in + * datetime and time constructors (their tzinfo arguments need to + * be subclasses of this tzinfo class, which is easy and quick to check). + * + * Note: For reasons having to do with pickling of subclasses, we have + * to allow tzinfo objects to be instantiated. This wasn't an issue + * in the Python implementation (__init__() could raise NotImplementedError + * there without ill effect), but doing so in the C implementation hit a + * brick wall. + */ + +static PyObject * +tzinfo_nogo(const char* methodname) +{ + PyErr_Format(PyExc_NotImplementedError, + "a tzinfo subclass must implement %s()", + methodname); + return NULL; +} + +/* Methods. A subclass must implement these. */ + +static PyObject * +tzinfo_tzname(PyDateTime_TZInfo *self, PyObject *dt) +{ + return tzinfo_nogo("tzname"); +} + +static PyObject * +tzinfo_utcoffset(PyDateTime_TZInfo *self, PyObject *dt) +{ + return tzinfo_nogo("utcoffset"); +} + +static PyObject * +tzinfo_dst(PyDateTime_TZInfo *self, PyObject *dt) +{ + return tzinfo_nogo("dst"); +} + + +static PyObject *add_datetime_timedelta(PyDateTime_DateTime *date, + PyDateTime_Delta *delta, + int factor); +static PyObject *datetime_utcoffset(PyObject *self, PyObject *); +static PyObject *datetime_dst(PyObject *self, PyObject *); + +static PyObject * +tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt) +{ + PyObject *result = NULL; + PyObject *off = NULL, *dst = NULL; + PyDateTime_Delta *delta = NULL; + + if (!PyDateTime_Check(dt)) { + PyErr_SetString(PyExc_TypeError, + "fromutc: argument must be a datetime"); + return NULL; + } + if (GET_DT_TZINFO(dt) != (PyObject *)self) { + PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " + "is not self"); + return NULL; + } + + off = datetime_utcoffset(dt, NULL); + if (off == NULL) + return NULL; + if (off == Py_None) { + PyErr_SetString(PyExc_ValueError, "fromutc: non-None " + "utcoffset() result required"); + goto Fail; + } + + dst = datetime_dst(dt, NULL); + if (dst == NULL) + goto Fail; + if (dst == Py_None) { + PyErr_SetString(PyExc_ValueError, "fromutc: non-None " + "dst() result required"); + goto Fail; + } + + delta = (PyDateTime_Delta *)delta_subtract(off, dst); + if (delta == NULL) + goto Fail; + result = add_datetime_timedelta((PyDateTime_DateTime *)dt, delta, 1); + if (result == NULL) + goto Fail; + + Py_DECREF(dst); + dst = call_dst(GET_DT_TZINFO(dt), result); + if (dst == NULL) + goto Fail; + if (dst == Py_None) + goto Inconsistent; + if (delta_bool((PyDateTime_Delta *)dst) != 0) { + Py_SETREF(result, add_datetime_timedelta((PyDateTime_DateTime *)result, + (PyDateTime_Delta *)dst, 1)); + if (result == NULL) + goto Fail; + } + Py_DECREF(delta); + Py_DECREF(dst); + Py_DECREF(off); + return result; + +Inconsistent: + PyErr_SetString(PyExc_ValueError, "fromutc: tz.dst() gave " + "inconsistent results; cannot convert"); + + /* fall through to failure */ +Fail: + Py_XDECREF(off); + Py_XDECREF(dst); + Py_XDECREF(delta); + Py_XDECREF(result); + return NULL; +} + +/* + * Pickle support. This is solely so that tzinfo subclasses can use + * pickling -- tzinfo itself is supposed to be uninstantiable. + */ + +static PyObject * +tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *args, *state; + PyObject *getinitargs, *getstate; + _Py_IDENTIFIER(__getinitargs__); + _Py_IDENTIFIER(__getstate__); + + if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) { return NULL; - - return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto)); -} - -static PyObject * -datetime_reduce(PyDateTime_DateTime *self, PyObject *arg) -{ - return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2)); -} - -static PyMethodDef datetime_methods[] = { - - /* Class methods: */ - - DATETIME_DATETIME_NOW_METHODDEF - - {"utcnow", (PyCFunction)datetime_utcnow, - METH_NOARGS | METH_CLASS, - PyDoc_STR("Return a new datetime representing UTC day and time.")}, - + } + if (getinitargs != NULL) { + args = PyObject_CallNoArgs(getinitargs); + Py_DECREF(getinitargs); + } + else { + args = PyTuple_New(0); + } + if (args == NULL) { + return NULL; + } + + if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) { + Py_DECREF(args); + return NULL; + } + if (getstate != NULL) { + state = PyObject_CallNoArgs(getstate); + Py_DECREF(getstate); + if (state == NULL) { + Py_DECREF(args); + return NULL; + } + } + else { + PyObject **dictptr; + state = Py_None; + dictptr = _PyObject_GetDictPtr(self); + if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) { + state = *dictptr; + } + Py_INCREF(state); + } + + if (state == Py_None) { + Py_DECREF(state); + return Py_BuildValue("(ON)", Py_TYPE(self), args); + } + else + return Py_BuildValue("(ONN)", Py_TYPE(self), args, state); +} + +static PyMethodDef tzinfo_methods[] = { + + {"tzname", (PyCFunction)tzinfo_tzname, METH_O, + PyDoc_STR("datetime -> string name of time zone.")}, + + {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O, + PyDoc_STR("datetime -> timedelta showing offset from UTC, negative " + "values indicating West of UTC")}, + + {"dst", (PyCFunction)tzinfo_dst, METH_O, + PyDoc_STR("datetime -> DST offset as timedelta positive east of UTC.")}, + + {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O, + PyDoc_STR("datetime in UTC -> datetime in local time.")}, + + {"__reduce__", tzinfo_reduce, METH_NOARGS, + PyDoc_STR("-> (cls, state)")}, + + {NULL, NULL} +}; + +static const char tzinfo_doc[] = +PyDoc_STR("Abstract base class for time zone info objects."); + +static PyTypeObject PyDateTime_TZInfoType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.tzinfo", /* tp_name */ + sizeof(PyDateTime_TZInfo), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + tzinfo_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + tzinfo_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ +}; + +static char *timezone_kws[] = {"offset", "name", NULL}; + +static PyObject * +timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *offset; + PyObject *name = NULL; + if (PyArg_ParseTupleAndKeywords(args, kw, "O!|U:timezone", timezone_kws, + &PyDateTime_DeltaType, &offset, &name)) + return new_timezone(offset, name); + + return NULL; +} + +static void +timezone_dealloc(PyDateTime_TimeZone *self) +{ + Py_CLEAR(self->offset); + Py_CLEAR(self->name); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject * +timezone_richcompare(PyDateTime_TimeZone *self, + PyDateTime_TimeZone *other, int op) +{ + if (op != Py_EQ && op != Py_NE) + Py_RETURN_NOTIMPLEMENTED; + if (!PyTimezone_Check(other)) { + Py_RETURN_NOTIMPLEMENTED; + } + return delta_richcompare(self->offset, other->offset, op); +} + +static Py_hash_t +timezone_hash(PyDateTime_TimeZone *self) +{ + return delta_hash((PyDateTime_Delta *)self->offset); +} + +/* Check argument type passed to tzname, utcoffset, or dst methods. + Returns 0 for good argument. Returns -1 and sets exception info + otherwise. + */ +static int +_timezone_check_argument(PyObject *dt, const char *meth) +{ + if (dt == Py_None || PyDateTime_Check(dt)) + return 0; + PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance" + " or None, not %.200s", meth, Py_TYPE(dt)->tp_name); + return -1; +} + +static PyObject * +timezone_repr(PyDateTime_TimeZone *self) +{ + /* Note that although timezone is not subclassable, it is convenient + to use Py_TYPE(self)->tp_name here. */ + const char *type_name = Py_TYPE(self)->tp_name; + + if (((PyObject *)self) == PyDateTime_TimeZone_UTC) + return PyUnicode_FromFormat("%s.utc", type_name); + + if (self->name == NULL) + return PyUnicode_FromFormat("%s(%R)", type_name, self->offset); + + return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset, + self->name); +} + + +static PyObject * +timezone_str(PyDateTime_TimeZone *self) +{ + int hours, minutes, seconds, microseconds; + PyObject *offset; + char sign; + + if (self->name != NULL) { + Py_INCREF(self->name); + return self->name; + } + if ((PyObject *)self == PyDateTime_TimeZone_UTC || + (GET_TD_DAYS(self->offset) == 0 && + GET_TD_SECONDS(self->offset) == 0 && + GET_TD_MICROSECONDS(self->offset) == 0)) + return PyUnicode_FromString("UTC"); + /* Offset is normalized, so it is negative if days < 0 */ + if (GET_TD_DAYS(self->offset) < 0) { + sign = '-'; + offset = delta_negative((PyDateTime_Delta *)self->offset); + if (offset == NULL) + return NULL; + } + else { + sign = '+'; + offset = self->offset; + Py_INCREF(offset); + } + /* Offset is not negative here. */ + microseconds = GET_TD_MICROSECONDS(offset); + seconds = GET_TD_SECONDS(offset); + Py_DECREF(offset); + minutes = divmod(seconds, 60, &seconds); + hours = divmod(minutes, 60, &minutes); + if (microseconds != 0) { + return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d.%06d", + sign, hours, minutes, + seconds, microseconds); + } + if (seconds != 0) { + return PyUnicode_FromFormat("UTC%c%02d:%02d:%02d", + sign, hours, minutes, seconds); + } + return PyUnicode_FromFormat("UTC%c%02d:%02d", sign, hours, minutes); +} + +static PyObject * +timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "tzname") == -1) + return NULL; + + return timezone_str(self); +} + +static PyObject * +timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "utcoffset") == -1) + return NULL; + + Py_INCREF(self->offset); + return self->offset; +} + +static PyObject * +timezone_dst(PyObject *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "dst") == -1) + return NULL; + + Py_RETURN_NONE; +} + +static PyObject * +timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt) +{ + if (!PyDateTime_Check(dt)) { + PyErr_SetString(PyExc_TypeError, + "fromutc: argument must be a datetime"); + return NULL; + } + if (!HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) { + PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " + "is not self"); + return NULL; + } + + return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1); +} + +static PyObject * +timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored)) +{ + if (self->name == NULL) + return Py_BuildValue("(O)", self->offset); + return Py_BuildValue("(OO)", self->offset, self->name); +} + +static PyMethodDef timezone_methods[] = { + {"tzname", (PyCFunction)timezone_tzname, METH_O, + PyDoc_STR("If name is specified when timezone is created, returns the name." + " Otherwise returns offset as 'UTC(+|-)HH:MM'.")}, + + {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O, + PyDoc_STR("Return fixed offset.")}, + + {"dst", (PyCFunction)timezone_dst, METH_O, + PyDoc_STR("Return None.")}, + + {"fromutc", (PyCFunction)timezone_fromutc, METH_O, + PyDoc_STR("datetime in UTC -> datetime in local time.")}, + + {"__getinitargs__", (PyCFunction)timezone_getinitargs, METH_NOARGS, + PyDoc_STR("pickle support")}, + + {NULL, NULL} +}; + +static const char timezone_doc[] = +PyDoc_STR("Fixed offset from UTC implementation of tzinfo."); + +static PyTypeObject PyDateTime_TimeZoneType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.timezone", /* tp_name */ + sizeof(PyDateTime_TimeZone), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)timezone_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)timezone_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)timezone_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)timezone_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + timezone_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)timezone_richcompare,/* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + timezone_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base; filled in PyInit__datetime */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + timezone_new, /* tp_new */ +}; + +/* + * PyDateTime_Time implementation. + */ + +/* Accessor properties. + */ + +static PyObject * +time_hour(PyDateTime_Time *self, void *unused) +{ + return PyLong_FromLong(TIME_GET_HOUR(self)); +} + +static PyObject * +time_minute(PyDateTime_Time *self, void *unused) +{ + return PyLong_FromLong(TIME_GET_MINUTE(self)); +} + +/* The name time_second conflicted with some platform header file. */ +static PyObject * +py_time_second(PyDateTime_Time *self, void *unused) +{ + return PyLong_FromLong(TIME_GET_SECOND(self)); +} + +static PyObject * +time_microsecond(PyDateTime_Time *self, void *unused) +{ + return PyLong_FromLong(TIME_GET_MICROSECOND(self)); +} + +static PyObject * +time_tzinfo(PyDateTime_Time *self, void *unused) +{ + PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; + Py_INCREF(result); + return result; +} + +static PyObject * +time_fold(PyDateTime_Time *self, void *unused) +{ + return PyLong_FromLong(TIME_GET_FOLD(self)); +} + +static PyGetSetDef time_getset[] = { + {"hour", (getter)time_hour}, + {"minute", (getter)time_minute}, + {"second", (getter)py_time_second}, + {"microsecond", (getter)time_microsecond}, + {"tzinfo", (getter)time_tzinfo}, + {"fold", (getter)time_fold}, + {NULL} +}; + +/* + * Constructors. + */ + +static char *time_kws[] = {"hour", "minute", "second", "microsecond", + "tzinfo", "fold", NULL}; + +static PyObject * +time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) +{ + PyDateTime_Time *me; + char aware = (char)(tzinfo != Py_None); + + if (aware && check_tzinfo_subclass(tzinfo) < 0) { + PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg"); + return NULL; + } + + me = (PyDateTime_Time *) (type->tp_alloc(type, aware)); + if (me != NULL) { + const char *pdata = PyBytes_AS_STRING(state); + + memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE); + me->hashcode = -1; + me->hastzinfo = aware; + if (aware) { + Py_INCREF(tzinfo); + me->tzinfo = tzinfo; + } + if (pdata[0] & (1 << 7)) { + me->data[0] -= 128; + me->fold = 1; + } + else { + me->fold = 0; + } + } + return (PyObject *)me; +} + +static PyObject * +time_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *self = NULL; + int hour = 0; + int minute = 0; + int second = 0; + int usecond = 0; + PyObject *tzinfo = Py_None; + int fold = 0; + + /* Check for invocation from pickle with __getstate__ state */ + if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) { + PyObject *state = PyTuple_GET_ITEM(args, 0); + if (PyTuple_GET_SIZE(args) == 2) { + tzinfo = PyTuple_GET_ITEM(args, 1); + } + if (PyBytes_Check(state)) { + if (PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && + (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24) + { + return time_from_pickle(type, state, tzinfo); + } + } + else if (PyUnicode_Check(state)) { + if (PyUnicode_READY(state)) { + return NULL; + } + if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE && + (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24) + { + state = PyUnicode_AsLatin1String(state); + if (state == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + /* More informative error message. */ + PyErr_SetString(PyExc_ValueError, + "Failed to encode latin1 string when unpickling " + "a time object. " + "pickle.load(data, encoding='latin1') is assumed."); + } + return NULL; + } + self = time_from_pickle(type, state, tzinfo); + Py_DECREF(state); + return self; + } + } + tzinfo = Py_None; + } + + if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws, + &hour, &minute, &second, &usecond, + &tzinfo, &fold)) { + self = new_time_ex2(hour, minute, second, usecond, tzinfo, fold, + type); + } + return self; +} + +/* + * Destructor. + */ + +static void +time_dealloc(PyDateTime_Time *self) +{ + if (HASTZINFO(self)) { + Py_XDECREF(self->tzinfo); + } + Py_TYPE(self)->tp_free((PyObject *)self); +} + +/* + * Indirect access to tzinfo methods. + */ + +/* These are all METH_NOARGS, so don't need to check the arglist. */ +static PyObject * +time_utcoffset(PyObject *self, PyObject *unused) { + return call_utcoffset(GET_TIME_TZINFO(self), Py_None); +} + +static PyObject * +time_dst(PyObject *self, PyObject *unused) { + return call_dst(GET_TIME_TZINFO(self), Py_None); +} + +static PyObject * +time_tzname(PyDateTime_Time *self, PyObject *unused) { + return call_tzname(GET_TIME_TZINFO(self), Py_None); +} + +/* + * Various ways to turn a time into a string. + */ + +static PyObject * +time_repr(PyDateTime_Time *self) +{ + const char *type_name = Py_TYPE(self)->tp_name; + int h = TIME_GET_HOUR(self); + int m = TIME_GET_MINUTE(self); + int s = TIME_GET_SECOND(self); + int us = TIME_GET_MICROSECOND(self); + int fold = TIME_GET_FOLD(self); + PyObject *result = NULL; + + if (us) + result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)", + type_name, h, m, s, us); + else if (s) + result = PyUnicode_FromFormat("%s(%d, %d, %d)", + type_name, h, m, s); + else + result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m); + if (result != NULL && HASTZINFO(self)) + result = append_keyword_tzinfo(result, self->tzinfo); + if (result != NULL && fold) + result = append_keyword_fold(result, fold); + return result; +} + +static PyObject * +time_str(PyDateTime_Time *self) +{ + return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); +} + +static PyObject * +time_isoformat(PyDateTime_Time *self, PyObject *args, PyObject *kw) +{ + char buf[100]; + const char *timespec = NULL; + static char *keywords[] = {"timespec", NULL}; + PyObject *result; + int us = TIME_GET_MICROSECOND(self); + static const char *specs[][2] = { + {"hours", "%02d"}, + {"minutes", "%02d:%02d"}, + {"seconds", "%02d:%02d:%02d"}, + {"milliseconds", "%02d:%02d:%02d.%03d"}, + {"microseconds", "%02d:%02d:%02d.%06d"}, + }; + size_t given_spec; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "|s:isoformat", keywords, ×pec)) + return NULL; + + if (timespec == NULL || strcmp(timespec, "auto") == 0) { + if (us == 0) { + /* seconds */ + given_spec = 2; + } + else { + /* microseconds */ + given_spec = 4; + } + } + else { + for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) { + if (strcmp(timespec, specs[given_spec][0]) == 0) { + if (given_spec == 3) { + /* milliseconds */ + us = us / 1000; + } + break; + } + } + } + + if (given_spec == Py_ARRAY_LENGTH(specs)) { + PyErr_Format(PyExc_ValueError, "Unknown timespec value"); + return NULL; + } + else { + result = PyUnicode_FromFormat(specs[given_spec][1], + TIME_GET_HOUR(self), TIME_GET_MINUTE(self), + TIME_GET_SECOND(self), us); + } + + if (result == NULL || !HASTZINFO(self) || self->tzinfo == Py_None) + return result; + + /* We need to append the UTC offset. */ + if (format_utcoffset(buf, sizeof(buf), ":", self->tzinfo, + Py_None) < 0) { + Py_DECREF(result); + return NULL; + } + PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buf)); + return result; +} + +static PyObject * +time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw) +{ + PyObject *result; + PyObject *tuple; + PyObject *format; + static char *keywords[] = {"format", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, + &format)) + return NULL; + + /* Python's strftime does insane things with the year part of the + * timetuple. The year is forced to (the otherwise nonsensical) + * 1900 to work around that. + */ + tuple = Py_BuildValue("iiiiiiiii", + 1900, 1, 1, /* year, month, day */ + TIME_GET_HOUR(self), + TIME_GET_MINUTE(self), + TIME_GET_SECOND(self), + 0, 1, -1); /* weekday, daynum, dst */ + if (tuple == NULL) + return NULL; + assert(PyTuple_Size(tuple) == 9); + result = wrap_strftime((PyObject *)self, format, tuple, + Py_None); + Py_DECREF(tuple); + return result; +} + +/* + * Miscellaneous methods. + */ + +static PyObject * +time_richcompare(PyObject *self, PyObject *other, int op) +{ + PyObject *result = NULL; + PyObject *offset1, *offset2; + int diff; + + if (! PyTime_Check(other)) + Py_RETURN_NOTIMPLEMENTED; + + if (GET_TIME_TZINFO(self) == GET_TIME_TZINFO(other)) { + diff = memcmp(((PyDateTime_Time *)self)->data, + ((PyDateTime_Time *)other)->data, + _PyDateTime_TIME_DATASIZE); + return diff_to_bool(diff, op); + } + offset1 = time_utcoffset(self, NULL); + if (offset1 == NULL) + return NULL; + offset2 = time_utcoffset(other, NULL); + if (offset2 == NULL) + goto done; + /* If they're both naive, or both aware and have the same offsets, + * we get off cheap. Note that if they're both naive, offset1 == + * offset2 == Py_None at this point. + */ + if ((offset1 == offset2) || + (PyDelta_Check(offset1) && PyDelta_Check(offset2) && + delta_cmp(offset1, offset2) == 0)) { + diff = memcmp(((PyDateTime_Time *)self)->data, + ((PyDateTime_Time *)other)->data, + _PyDateTime_TIME_DATASIZE); + result = diff_to_bool(diff, op); + } + /* The hard case: both aware with different UTC offsets */ + else if (offset1 != Py_None && offset2 != Py_None) { + int offsecs1, offsecs2; + assert(offset1 != offset2); /* else last "if" handled it */ + offsecs1 = TIME_GET_HOUR(self) * 3600 + + TIME_GET_MINUTE(self) * 60 + + TIME_GET_SECOND(self) - + GET_TD_DAYS(offset1) * 86400 - + GET_TD_SECONDS(offset1); + offsecs2 = TIME_GET_HOUR(other) * 3600 + + TIME_GET_MINUTE(other) * 60 + + TIME_GET_SECOND(other) - + GET_TD_DAYS(offset2) * 86400 - + GET_TD_SECONDS(offset2); + diff = offsecs1 - offsecs2; + if (diff == 0) + diff = TIME_GET_MICROSECOND(self) - + TIME_GET_MICROSECOND(other); + result = diff_to_bool(diff, op); + } + else if (op == Py_EQ) { + result = Py_False; + Py_INCREF(result); + } + else if (op == Py_NE) { + result = Py_True; + Py_INCREF(result); + } + else { + PyErr_SetString(PyExc_TypeError, + "can't compare offset-naive and " + "offset-aware times"); + } + done: + Py_DECREF(offset1); + Py_XDECREF(offset2); + return result; +} + +static Py_hash_t +time_hash(PyDateTime_Time *self) +{ + if (self->hashcode == -1) { + PyObject *offset, *self0; + if (TIME_GET_FOLD(self)) { + self0 = new_time_ex2(TIME_GET_HOUR(self), + TIME_GET_MINUTE(self), + TIME_GET_SECOND(self), + TIME_GET_MICROSECOND(self), + HASTZINFO(self) ? self->tzinfo : Py_None, + 0, Py_TYPE(self)); + if (self0 == NULL) + return -1; + } + else { + self0 = (PyObject *)self; + Py_INCREF(self0); + } + offset = time_utcoffset(self0, NULL); + Py_DECREF(self0); + + if (offset == NULL) + return -1; + + /* Reduce this to a hash of another object. */ + if (offset == Py_None) + self->hashcode = generic_hash( + (unsigned char *)self->data, _PyDateTime_TIME_DATASIZE); + else { + PyObject *temp1, *temp2; + int seconds, microseconds; + assert(HASTZINFO(self)); + seconds = TIME_GET_HOUR(self) * 3600 + + TIME_GET_MINUTE(self) * 60 + + TIME_GET_SECOND(self); + microseconds = TIME_GET_MICROSECOND(self); + temp1 = new_delta(0, seconds, microseconds, 1); + if (temp1 == NULL) { + Py_DECREF(offset); + return -1; + } + temp2 = delta_subtract(temp1, offset); + Py_DECREF(temp1); + if (temp2 == NULL) { + Py_DECREF(offset); + return -1; + } + self->hashcode = PyObject_Hash(temp2); + Py_DECREF(temp2); + } + Py_DECREF(offset); + } + return self->hashcode; +} + +static PyObject * +time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) +{ + PyObject *clone; + PyObject *tuple; + int hh = TIME_GET_HOUR(self); + int mm = TIME_GET_MINUTE(self); + int ss = TIME_GET_SECOND(self); + int us = TIME_GET_MICROSECOND(self); + PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; + int fold = TIME_GET_FOLD(self); + + if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:replace", + time_kws, + &hh, &mm, &ss, &us, &tzinfo, &fold)) + return NULL; + if (fold != 0 && fold != 1) { + PyErr_SetString(PyExc_ValueError, + "fold must be either 0 or 1"); + return NULL; + } + tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo); + if (tuple == NULL) + return NULL; + clone = time_new(Py_TYPE(self), tuple, NULL); + if (clone != NULL) { + TIME_SET_FOLD(clone, fold); + } + Py_DECREF(tuple); + return clone; +} + +static PyObject * +time_fromisoformat(PyObject *cls, PyObject *tstr) { + assert(tstr != NULL); + + if (!PyUnicode_Check(tstr)) { + PyErr_SetString(PyExc_TypeError, "fromisoformat: argument must be str"); + return NULL; + } + + Py_ssize_t len; + const char *p = PyUnicode_AsUTF8AndSize(tstr, &len); + + if (p == NULL) { + goto invalid_string_error; + } + + int hour = 0, minute = 0, second = 0, microsecond = 0; + int tzoffset, tzimicrosecond = 0; + int rv = parse_isoformat_time(p, len, + &hour, &minute, &second, µsecond, + &tzoffset, &tzimicrosecond); + + if (rv < 0) { + goto invalid_string_error; + } + + PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, + tzimicrosecond); + + if (tzinfo == NULL) { + return NULL; + } + + PyObject *t; + if ( (PyTypeObject *)cls == &PyDateTime_TimeType ) { + t = new_time(hour, minute, second, microsecond, tzinfo, 0); + } else { + t = PyObject_CallFunction(cls, "iiiiO", + hour, minute, second, microsecond, tzinfo); + } + + Py_DECREF(tzinfo); + return t; + +invalid_string_error: + PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr); + return NULL; +} + + +/* Pickle support, a simple use of __reduce__. */ + +/* Let basestate be the non-tzinfo data string. + * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). + * So it's a tuple in any (non-error) case. + * __getstate__ isn't exposed. + */ +static PyObject * +time_getstate(PyDateTime_Time *self, int proto) +{ + PyObject *basestate; + PyObject *result = NULL; + + basestate = PyBytes_FromStringAndSize((char *)self->data, + _PyDateTime_TIME_DATASIZE); + if (basestate != NULL) { + if (proto > 3 && TIME_GET_FOLD(self)) + /* Set the first bit of the first byte */ + PyBytes_AS_STRING(basestate)[0] |= (1 << 7); + if (! HASTZINFO(self) || self->tzinfo == Py_None) + result = PyTuple_Pack(1, basestate); + else + result = PyTuple_Pack(2, basestate, self->tzinfo); + Py_DECREF(basestate); + } + return result; +} + +static PyObject * +time_reduce_ex(PyDateTime_Time *self, PyObject *args) +{ + int proto; + if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto)) + return NULL; + + return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto)); +} + +static PyObject * +time_reduce(PyDateTime_Time *self, PyObject *arg) +{ + return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2)); +} + +static PyMethodDef time_methods[] = { + + {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]" + "[+HH:MM].\n\n" + "The optional argument timespec specifies the number " + "of additional terms\nof the time to include. Valid " + "options are 'auto', 'hours', 'minutes',\n'seconds', " + "'milliseconds' and 'microseconds'.\n")}, + + {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("format -> strftime() style string.")}, + + {"__format__", (PyCFunction)date_format, METH_VARARGS, + PyDoc_STR("Formats self with strftime.")}, + + {"utcoffset", (PyCFunction)time_utcoffset, METH_NOARGS, + PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, + + {"tzname", (PyCFunction)time_tzname, METH_NOARGS, + PyDoc_STR("Return self.tzinfo.tzname(self).")}, + + {"dst", (PyCFunction)time_dst, METH_NOARGS, + PyDoc_STR("Return self.tzinfo.dst(self).")}, + + {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS, + PyDoc_STR("Return time with new specified fields.")}, + + {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS, + PyDoc_STR("string -> time from time.isoformat() output")}, + + {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS, + PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, + + {"__reduce__", (PyCFunction)time_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + + {NULL, NULL} +}; + +static const char time_doc[] = +PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time object\n\ +\n\ +All arguments are optional. tzinfo may be None, or an instance of\n\ +a tzinfo subclass. The remaining arguments may be ints.\n"); + +static PyTypeObject PyDateTime_TimeType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.time", /* tp_name */ + sizeof(PyDateTime_Time), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)time_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)time_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)time_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)time_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + time_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + time_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + time_methods, /* tp_methods */ + 0, /* tp_members */ + time_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + time_alloc, /* tp_alloc */ + time_new, /* tp_new */ + 0, /* tp_free */ +}; + +/* + * PyDateTime_DateTime implementation. + */ + +/* Accessor properties. Properties for day, month, and year are inherited + * from date. + */ + +static PyObject * +datetime_hour(PyDateTime_DateTime *self, void *unused) +{ + return PyLong_FromLong(DATE_GET_HOUR(self)); +} + +static PyObject * +datetime_minute(PyDateTime_DateTime *self, void *unused) +{ + return PyLong_FromLong(DATE_GET_MINUTE(self)); +} + +static PyObject * +datetime_second(PyDateTime_DateTime *self, void *unused) +{ + return PyLong_FromLong(DATE_GET_SECOND(self)); +} + +static PyObject * +datetime_microsecond(PyDateTime_DateTime *self, void *unused) +{ + return PyLong_FromLong(DATE_GET_MICROSECOND(self)); +} + +static PyObject * +datetime_tzinfo(PyDateTime_DateTime *self, void *unused) +{ + PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; + Py_INCREF(result); + return result; +} + +static PyObject * +datetime_fold(PyDateTime_DateTime *self, void *unused) +{ + return PyLong_FromLong(DATE_GET_FOLD(self)); +} + +static PyGetSetDef datetime_getset[] = { + {"hour", (getter)datetime_hour}, + {"minute", (getter)datetime_minute}, + {"second", (getter)datetime_second}, + {"microsecond", (getter)datetime_microsecond}, + {"tzinfo", (getter)datetime_tzinfo}, + {"fold", (getter)datetime_fold}, + {NULL} +}; + +/* + * Constructors. + */ + +static char *datetime_kws[] = { + "year", "month", "day", "hour", "minute", "second", + "microsecond", "tzinfo", "fold", NULL +}; + +static PyObject * +datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) +{ + PyDateTime_DateTime *me; + char aware = (char)(tzinfo != Py_None); + + if (aware && check_tzinfo_subclass(tzinfo) < 0) { + PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg"); + return NULL; + } + + me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware)); + if (me != NULL) { + const char *pdata = PyBytes_AS_STRING(state); + + memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE); + me->hashcode = -1; + me->hastzinfo = aware; + if (aware) { + Py_INCREF(tzinfo); + me->tzinfo = tzinfo; + } + if (pdata[2] & (1 << 7)) { + me->data[2] -= 128; + me->fold = 1; + } + else { + me->fold = 0; + } + } + return (PyObject *)me; +} + +static PyObject * +datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *self = NULL; + int year; + int month; + int day; + int hour = 0; + int minute = 0; + int second = 0; + int usecond = 0; + int fold = 0; + PyObject *tzinfo = Py_None; + + /* Check for invocation from pickle with __getstate__ state */ + if (PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2) { + PyObject *state = PyTuple_GET_ITEM(args, 0); + if (PyTuple_GET_SIZE(args) == 2) { + tzinfo = PyTuple_GET_ITEM(args, 1); + } + if (PyBytes_Check(state)) { + if (PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && + MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F)) + { + return datetime_from_pickle(type, state, tzinfo); + } + } + else if (PyUnicode_Check(state)) { + if (PyUnicode_READY(state)) { + return NULL; + } + if (PyUnicode_GET_LENGTH(state) == _PyDateTime_DATETIME_DATASIZE && + MONTH_IS_SANE(PyUnicode_READ_CHAR(state, 2) & 0x7F)) + { + state = PyUnicode_AsLatin1String(state); + if (state == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + /* More informative error message. */ + PyErr_SetString(PyExc_ValueError, + "Failed to encode latin1 string when unpickling " + "a datetime object. " + "pickle.load(data, encoding='latin1') is assumed."); + } + return NULL; + } + self = datetime_from_pickle(type, state, tzinfo); + Py_DECREF(state); + return self; + } + } + tzinfo = Py_None; + } + + if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws, + &year, &month, &day, &hour, &minute, + &second, &usecond, &tzinfo, &fold)) { + self = new_datetime_ex2(year, month, day, + hour, minute, second, usecond, + tzinfo, fold, type); + } + return self; +} + +/* TM_FUNC is the shared type of _PyTime_localtime() and + * _PyTime_gmtime(). */ +typedef int (*TM_FUNC)(time_t timer, struct tm*); + +/* As of version 2015f max fold in IANA database is + * 23 hours at 1969-09-30 13:00:00 in Kwajalein. */ +static long long max_fold_seconds = 24 * 3600; +/* NB: date(1970,1,1).toordinal() == 719163 */ +static long long epoch = 719163LL * 24 * 60 * 60; + +static long long +utc_to_seconds(int year, int month, int day, + int hour, int minute, int second) +{ + long long ordinal; + + /* ymd_to_ord() doesn't support year <= 0 */ + if (year < MINYEAR || year > MAXYEAR) { + PyErr_Format(PyExc_ValueError, "year %i is out of range", year); + return -1; + } + + ordinal = ymd_to_ord(year, month, day); + return ((ordinal * 24 + hour) * 60 + minute) * 60 + second; +} + +static long long +local(long long u) +{ + struct tm local_time; + time_t t; + u -= epoch; + t = u; + if (t != u) { + PyErr_SetString(PyExc_OverflowError, + "timestamp out of range for platform time_t"); + return -1; + } + if (_PyTime_localtime(t, &local_time) != 0) + return -1; + return utc_to_seconds(local_time.tm_year + 1900, + local_time.tm_mon + 1, + local_time.tm_mday, + local_time.tm_hour, + local_time.tm_min, + local_time.tm_sec); +} + +/* Internal helper. + * Build datetime from a time_t and a distinct count of microseconds. + * Pass localtime or gmtime for f, to control the interpretation of timet. + */ +static PyObject * +datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, + PyObject *tzinfo) +{ + struct tm tm; + int year, month, day, hour, minute, second, fold = 0; + + if (f(timet, &tm) != 0) + return NULL; + + year = tm.tm_year + 1900; + month = tm.tm_mon + 1; + day = tm.tm_mday; + hour = tm.tm_hour; + minute = tm.tm_min; + /* The platform localtime/gmtime may insert leap seconds, + * indicated by tm.tm_sec > 59. We don't care about them, + * except to the extent that passing them on to the datetime + * constructor would raise ValueError for a reason that + * made no sense to the user. + */ + second = Py_MIN(59, tm.tm_sec); + + /* local timezone requires to compute fold */ + if (tzinfo == Py_None && f == _PyTime_localtime + /* On Windows, passing a negative value to local results + * in an OSError because localtime_s on Windows does + * not support negative timestamps. Unfortunately this + * means that fold detection for time values between + * 0 and max_fold_seconds will result in an identical + * error since we subtract max_fold_seconds to detect a + * fold. However, since we know there haven't been any + * folds in the interval [0, max_fold_seconds) in any + * timezone, we can hackily just forego fold detection + * for this time range. + */ +#ifdef MS_WINDOWS + && (timet - max_fold_seconds > 0) +#endif + ) { + long long probe_seconds, result_seconds, transition; + + result_seconds = utc_to_seconds(year, month, day, + hour, minute, second); + /* Probe max_fold_seconds to detect a fold. */ + probe_seconds = local(epoch + timet - max_fold_seconds); + if (probe_seconds == -1) + return NULL; + transition = result_seconds - probe_seconds - max_fold_seconds; + if (transition < 0) { + probe_seconds = local(epoch + timet + transition); + if (probe_seconds == -1) + return NULL; + if (probe_seconds == result_seconds) + fold = 1; + } + } + return new_datetime_subclass_fold_ex(year, month, day, hour, minute, + second, us, tzinfo, fold, cls); +} + +/* Internal helper. + * Build datetime from a Python timestamp. Pass localtime or gmtime for f, + * to control the interpretation of the timestamp. Since a double doesn't + * have enough bits to cover a datetime's full range of precision, it's + * better to call datetime_from_timet_and_us provided you have a way + * to get that much precision (e.g., C time() isn't good enough). + */ +static PyObject * +datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, + PyObject *tzinfo) +{ + time_t timet; + long us; + + if (_PyTime_ObjectToTimeval(timestamp, + &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1) + return NULL; + + return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); +} + +/* Internal helper. + * Build most accurate possible datetime for current time. Pass localtime or + * gmtime for f as appropriate. + */ +static PyObject * +datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo) +{ + _PyTime_t ts = _PyTime_GetSystemClock(); + time_t secs; + int us; + + if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0) + return NULL; + assert(0 <= us && us <= 999999); + + return datetime_from_timet_and_us(cls, f, secs, us, tzinfo); +} + +/*[clinic input] + +@classmethod +datetime.datetime.now + + tz: object = None + Timezone object. + +Returns new datetime object representing current time local to tz. + +If no tz is specified, uses local timezone. +[clinic start generated code]*/ + +static PyObject * +datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) +/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/ +{ + PyObject *self; + + /* Return best possible local time -- this isn't constrained by the + * precision of a timestamp. + */ + if (check_tzinfo_subclass(tz) < 0) + return NULL; + + self = datetime_best_possible((PyObject *)type, + tz == Py_None ? _PyTime_localtime : + _PyTime_gmtime, + tz); + if (self != NULL && tz != Py_None) { + /* Convert UTC to tzinfo's zone. */ + self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self); + } + return self; +} + +/* Return best possible UTC time -- this isn't constrained by the + * precision of a timestamp. + */ +static PyObject * +datetime_utcnow(PyObject *cls, PyObject *dummy) +{ + return datetime_best_possible(cls, _PyTime_gmtime, Py_None); +} + +/* Return new local datetime from timestamp (Python timestamp -- a double). */ +static PyObject * +datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) +{ + PyObject *self; + PyObject *timestamp; + PyObject *tzinfo = Py_None; + static char *keywords[] = {"timestamp", "tz", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp", + keywords, ×tamp, &tzinfo)) + return NULL; + if (check_tzinfo_subclass(tzinfo) < 0) + return NULL; + + self = datetime_from_timestamp(cls, + tzinfo == Py_None ? _PyTime_localtime : + _PyTime_gmtime, + timestamp, + tzinfo); + if (self != NULL && tzinfo != Py_None) { + /* Convert UTC to tzinfo's zone. */ + self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self); + } + return self; +} + +/* Return new UTC datetime from timestamp (Python timestamp -- a double). */ +static PyObject * +datetime_utcfromtimestamp(PyObject *cls, PyObject *args) +{ + PyObject *timestamp; + PyObject *result = NULL; + + if (PyArg_ParseTuple(args, "O:utcfromtimestamp", ×tamp)) + result = datetime_from_timestamp(cls, _PyTime_gmtime, timestamp, + Py_None); + return result; +} + +/* Return new datetime from _strptime.strptime_datetime(). */ +static PyObject * +datetime_strptime(PyObject *cls, PyObject *args) +{ + static PyObject *module = NULL; + PyObject *string, *format; + _Py_IDENTIFIER(_strptime_datetime); + + if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format)) + return NULL; + + if (module == NULL) { + module = PyImport_ImportModuleNoBlock("_strptime"); + if (module == NULL) + return NULL; + } + return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime, + cls, string, format, NULL); +} + +/* Return new datetime from date/datetime and time arguments. */ +static PyObject * +datetime_combine(PyObject *cls, PyObject *args, PyObject *kw) +{ + static char *keywords[] = {"date", "time", "tzinfo", NULL}; + PyObject *date; + PyObject *time; + PyObject *tzinfo = NULL; + PyObject *result = NULL; + + if (PyArg_ParseTupleAndKeywords(args, kw, "O!O!|O:combine", keywords, + &PyDateTime_DateType, &date, + &PyDateTime_TimeType, &time, &tzinfo)) { + if (tzinfo == NULL) { + if (HASTZINFO(time)) + tzinfo = ((PyDateTime_Time *)time)->tzinfo; + else + tzinfo = Py_None; + } + result = new_datetime_subclass_fold_ex(GET_YEAR(date), + GET_MONTH(date), + GET_DAY(date), + TIME_GET_HOUR(time), + TIME_GET_MINUTE(time), + TIME_GET_SECOND(time), + TIME_GET_MICROSECOND(time), + tzinfo, + TIME_GET_FOLD(time), + cls); + } + return result; +} + +static PyObject * +_sanitize_isoformat_str(PyObject *dtstr) +{ + // `fromisoformat` allows surrogate characters in exactly one position, + // the separator; to allow datetime_fromisoformat to make the simplifying + // assumption that all valid strings can be encoded in UTF-8, this function + // replaces any surrogate character separators with `T`. + // + // The result of this, if not NULL, returns a new reference + Py_ssize_t len = PyUnicode_GetLength(dtstr); + if (len < 0) { + return NULL; + } + + if (len <= 10 || + !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) { + Py_INCREF(dtstr); + return dtstr; + } + + PyObject *str_out = _PyUnicode_Copy(dtstr); + if (str_out == NULL) { + return NULL; + } + + if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) { + Py_DECREF(str_out); + return NULL; + } + + return str_out; +} + +static PyObject * +datetime_fromisoformat(PyObject *cls, PyObject *dtstr) +{ + assert(dtstr != NULL); + + if (!PyUnicode_Check(dtstr)) { + PyErr_SetString(PyExc_TypeError, + "fromisoformat: argument must be str"); + return NULL; + } + + PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr); + if (dtstr_clean == NULL) { + goto error; + } + + Py_ssize_t len; + const char *dt_ptr = PyUnicode_AsUTF8AndSize(dtstr_clean, &len); + + if (dt_ptr == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + // Encoding errors are invalid string errors at this point + goto invalid_string_error; + } + else { + goto error; + } + } + + const char *p = dt_ptr; + + int year = 0, month = 0, day = 0; + int hour = 0, minute = 0, second = 0, microsecond = 0; + int tzoffset = 0, tzusec = 0; + + // date has a fixed length of 10 + int rv = parse_isoformat_date(p, &year, &month, &day); + + if (!rv && len > 10) { + // In UTF-8, the length of multi-byte characters is encoded in the MSB + if ((p[10] & 0x80) == 0) { + p += 11; + } + else { + switch (p[10] & 0xf0) { + case 0xe0: + p += 13; + break; + case 0xf0: + p += 14; + break; + default: + p += 12; + break; + } + } + + len -= (p - dt_ptr); + rv = parse_isoformat_time(p, len, &hour, &minute, &second, + µsecond, &tzoffset, &tzusec); + } + if (rv < 0) { + goto invalid_string_error; + } + + PyObject *tzinfo = tzinfo_from_isoformat_results(rv, tzoffset, tzusec); + if (tzinfo == NULL) { + goto error; + } + + PyObject *dt = new_datetime_subclass_ex(year, month, day, hour, minute, + second, microsecond, tzinfo, cls); + + Py_DECREF(tzinfo); + Py_DECREF(dtstr_clean); + return dt; + +invalid_string_error: + PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", dtstr); + +error: + Py_XDECREF(dtstr_clean); + + return NULL; +} + +/* + * Destructor. + */ + +static void +datetime_dealloc(PyDateTime_DateTime *self) +{ + if (HASTZINFO(self)) { + Py_XDECREF(self->tzinfo); + } + Py_TYPE(self)->tp_free((PyObject *)self); +} + +/* + * Indirect access to tzinfo methods. + */ + +/* These are all METH_NOARGS, so don't need to check the arglist. */ +static PyObject * +datetime_utcoffset(PyObject *self, PyObject *unused) { + return call_utcoffset(GET_DT_TZINFO(self), self); +} + +static PyObject * +datetime_dst(PyObject *self, PyObject *unused) { + return call_dst(GET_DT_TZINFO(self), self); +} + +static PyObject * +datetime_tzname(PyObject *self, PyObject *unused) { + return call_tzname(GET_DT_TZINFO(self), self); +} + +/* + * datetime arithmetic. + */ + +/* factor must be 1 (to add) or -1 (to subtract). The result inherits + * the tzinfo state of date. + */ +static PyObject * +add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta, + int factor) +{ + /* Note that the C-level additions can't overflow, because of + * invariant bounds on the member values. + */ + int year = GET_YEAR(date); + int month = GET_MONTH(date); + int day = GET_DAY(date) + GET_TD_DAYS(delta) * factor; + int hour = DATE_GET_HOUR(date); + int minute = DATE_GET_MINUTE(date); + int second = DATE_GET_SECOND(date) + GET_TD_SECONDS(delta) * factor; + int microsecond = DATE_GET_MICROSECOND(date) + + GET_TD_MICROSECONDS(delta) * factor; + + assert(factor == 1 || factor == -1); + if (normalize_datetime(&year, &month, &day, + &hour, &minute, &second, µsecond) < 0) { + return NULL; + } + + return new_datetime_subclass_ex(year, month, day, + hour, minute, second, microsecond, + HASTZINFO(date) ? date->tzinfo : Py_None, + (PyObject *)Py_TYPE(date)); +} + +static PyObject * +datetime_add(PyObject *left, PyObject *right) +{ + if (PyDateTime_Check(left)) { + /* datetime + ??? */ + if (PyDelta_Check(right)) + /* datetime + delta */ + return add_datetime_timedelta( + (PyDateTime_DateTime *)left, + (PyDateTime_Delta *)right, + 1); + } + else if (PyDelta_Check(left)) { + /* delta + datetime */ + return add_datetime_timedelta((PyDateTime_DateTime *) right, + (PyDateTime_Delta *) left, + 1); + } + Py_RETURN_NOTIMPLEMENTED; +} + +static PyObject * +datetime_subtract(PyObject *left, PyObject *right) +{ + PyObject *result = Py_NotImplemented; + + if (PyDateTime_Check(left)) { + /* datetime - ??? */ + if (PyDateTime_Check(right)) { + /* datetime - datetime */ + PyObject *offset1, *offset2, *offdiff = NULL; + int delta_d, delta_s, delta_us; + + if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) { + offset2 = offset1 = Py_None; + Py_INCREF(offset1); + Py_INCREF(offset2); + } + else { + offset1 = datetime_utcoffset(left, NULL); + if (offset1 == NULL) + return NULL; + offset2 = datetime_utcoffset(right, NULL); + if (offset2 == NULL) { + Py_DECREF(offset1); + return NULL; + } + if ((offset1 != Py_None) != (offset2 != Py_None)) { + PyErr_SetString(PyExc_TypeError, + "can't subtract offset-naive and " + "offset-aware datetimes"); + Py_DECREF(offset1); + Py_DECREF(offset2); + return NULL; + } + } + if ((offset1 != offset2) && + delta_cmp(offset1, offset2) != 0) { + offdiff = delta_subtract(offset1, offset2); + if (offdiff == NULL) { + Py_DECREF(offset1); + Py_DECREF(offset2); + return NULL; + } + } + Py_DECREF(offset1); + Py_DECREF(offset2); + delta_d = ymd_to_ord(GET_YEAR(left), + GET_MONTH(left), + GET_DAY(left)) - + ymd_to_ord(GET_YEAR(right), + GET_MONTH(right), + GET_DAY(right)); + /* These can't overflow, since the values are + * normalized. At most this gives the number of + * seconds in one day. + */ + delta_s = (DATE_GET_HOUR(left) - + DATE_GET_HOUR(right)) * 3600 + + (DATE_GET_MINUTE(left) - + DATE_GET_MINUTE(right)) * 60 + + (DATE_GET_SECOND(left) - + DATE_GET_SECOND(right)); + delta_us = DATE_GET_MICROSECOND(left) - + DATE_GET_MICROSECOND(right); + result = new_delta(delta_d, delta_s, delta_us, 1); + if (result == NULL) + return NULL; + + if (offdiff != NULL) { + Py_SETREF(result, delta_subtract(result, offdiff)); + Py_DECREF(offdiff); + } + } + else if (PyDelta_Check(right)) { + /* datetime - delta */ + result = add_datetime_timedelta( + (PyDateTime_DateTime *)left, + (PyDateTime_Delta *)right, + -1); + } + } + + if (result == Py_NotImplemented) + Py_INCREF(result); + return result; +} + +/* Various ways to turn a datetime into a string. */ + +static PyObject * +datetime_repr(PyDateTime_DateTime *self) +{ + const char *type_name = Py_TYPE(self)->tp_name; + PyObject *baserepr; + + if (DATE_GET_MICROSECOND(self)) { + baserepr = PyUnicode_FromFormat( + "%s(%d, %d, %d, %d, %d, %d, %d)", + type_name, + GET_YEAR(self), GET_MONTH(self), GET_DAY(self), + DATE_GET_HOUR(self), DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + DATE_GET_MICROSECOND(self)); + } + else if (DATE_GET_SECOND(self)) { + baserepr = PyUnicode_FromFormat( + "%s(%d, %d, %d, %d, %d, %d)", + type_name, + GET_YEAR(self), GET_MONTH(self), GET_DAY(self), + DATE_GET_HOUR(self), DATE_GET_MINUTE(self), + DATE_GET_SECOND(self)); + } + else { + baserepr = PyUnicode_FromFormat( + "%s(%d, %d, %d, %d, %d)", + type_name, + GET_YEAR(self), GET_MONTH(self), GET_DAY(self), + DATE_GET_HOUR(self), DATE_GET_MINUTE(self)); + } + if (baserepr != NULL && DATE_GET_FOLD(self) != 0) + baserepr = append_keyword_fold(baserepr, DATE_GET_FOLD(self)); + if (baserepr == NULL || ! HASTZINFO(self)) + return baserepr; + return append_keyword_tzinfo(baserepr, self->tzinfo); +} + +static PyObject * +datetime_str(PyDateTime_DateTime *self) +{ + return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " "); +} + +static PyObject * +datetime_isoformat(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) +{ + int sep = 'T'; + char *timespec = NULL; + static char *keywords[] = {"sep", "timespec", NULL}; + char buffer[100]; + PyObject *result = NULL; + int us = DATE_GET_MICROSECOND(self); + static const char *specs[][2] = { + {"hours", "%04d-%02d-%02d%c%02d"}, + {"minutes", "%04d-%02d-%02d%c%02d:%02d"}, + {"seconds", "%04d-%02d-%02d%c%02d:%02d:%02d"}, + {"milliseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%03d"}, + {"microseconds", "%04d-%02d-%02d%c%02d:%02d:%02d.%06d"}, + }; + size_t given_spec; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Cs:isoformat", keywords, &sep, ×pec)) + return NULL; + + if (timespec == NULL || strcmp(timespec, "auto") == 0) { + if (us == 0) { + /* seconds */ + given_spec = 2; + } + else { + /* microseconds */ + given_spec = 4; + } + } + else { + for (given_spec = 0; given_spec < Py_ARRAY_LENGTH(specs); given_spec++) { + if (strcmp(timespec, specs[given_spec][0]) == 0) { + if (given_spec == 3) { + us = us / 1000; + } + break; + } + } + } + + if (given_spec == Py_ARRAY_LENGTH(specs)) { + PyErr_Format(PyExc_ValueError, "Unknown timespec value"); + return NULL; + } + else { + result = PyUnicode_FromFormat(specs[given_spec][1], + GET_YEAR(self), GET_MONTH(self), + GET_DAY(self), (int)sep, + DATE_GET_HOUR(self), DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), us); + } + + if (!result || !HASTZINFO(self)) + return result; + + /* We need to append the UTC offset. */ + if (format_utcoffset(buffer, sizeof(buffer), ":", self->tzinfo, + (PyObject *)self) < 0) { + Py_DECREF(result); + return NULL; + } + PyUnicode_AppendAndDel(&result, PyUnicode_FromString(buffer)); + return result; +} + +static PyObject * +datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) +{ + return format_ctime((PyDateTime_Date *)self, + DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self)); +} + +/* Miscellaneous methods. */ + +static PyObject * +flip_fold(PyObject *dt) +{ + return new_datetime_ex2(GET_YEAR(dt), + GET_MONTH(dt), + GET_DAY(dt), + DATE_GET_HOUR(dt), + DATE_GET_MINUTE(dt), + DATE_GET_SECOND(dt), + DATE_GET_MICROSECOND(dt), + HASTZINFO(dt) ? + ((PyDateTime_DateTime *)dt)->tzinfo : Py_None, + !DATE_GET_FOLD(dt), + Py_TYPE(dt)); +} + +static PyObject * +get_flip_fold_offset(PyObject *dt) +{ + PyObject *result, *flip_dt; + + flip_dt = flip_fold(dt); + if (flip_dt == NULL) + return NULL; + result = datetime_utcoffset(flip_dt, NULL); + Py_DECREF(flip_dt); + return result; +} + +/* PEP 495 exception: Whenever one or both of the operands in + * inter-zone comparison is such that its utcoffset() depends + * on the value of its fold attribute, the result is False. + * + * Return 1 if exception applies, 0 if not, and -1 on error. + */ +static int +pep495_eq_exception(PyObject *self, PyObject *other, + PyObject *offset_self, PyObject *offset_other) +{ + int result = 0; + PyObject *flip_offset; + + flip_offset = get_flip_fold_offset(self); + if (flip_offset == NULL) + return -1; + if (flip_offset != offset_self && + delta_cmp(flip_offset, offset_self)) + { + result = 1; + goto done; + } + Py_DECREF(flip_offset); + + flip_offset = get_flip_fold_offset(other); + if (flip_offset == NULL) + return -1; + if (flip_offset != offset_other && + delta_cmp(flip_offset, offset_other)) + result = 1; + done: + Py_DECREF(flip_offset); + return result; +} + +static PyObject * +datetime_richcompare(PyObject *self, PyObject *other, int op) +{ + PyObject *result = NULL; + PyObject *offset1, *offset2; + int diff; + + if (! PyDateTime_Check(other)) { + if (PyDate_Check(other)) { + /* Prevent invocation of date_richcompare. We want to + return NotImplemented here to give the other object + a chance. But since DateTime is a subclass of + Date, if the other object is a Date, it would + compute an ordering based on the date part alone, + and we don't want that. So force unequal or + uncomparable here in that case. */ + if (op == Py_EQ) + Py_RETURN_FALSE; + if (op == Py_NE) + Py_RETURN_TRUE; + return cmperror(self, other); + } + Py_RETURN_NOTIMPLEMENTED; + } + + if (GET_DT_TZINFO(self) == GET_DT_TZINFO(other)) { + diff = memcmp(((PyDateTime_DateTime *)self)->data, + ((PyDateTime_DateTime *)other)->data, + _PyDateTime_DATETIME_DATASIZE); + return diff_to_bool(diff, op); + } + offset1 = datetime_utcoffset(self, NULL); + if (offset1 == NULL) + return NULL; + offset2 = datetime_utcoffset(other, NULL); + if (offset2 == NULL) + goto done; + /* If they're both naive, or both aware and have the same offsets, + * we get off cheap. Note that if they're both naive, offset1 == + * offset2 == Py_None at this point. + */ + if ((offset1 == offset2) || + (PyDelta_Check(offset1) && PyDelta_Check(offset2) && + delta_cmp(offset1, offset2) == 0)) { + diff = memcmp(((PyDateTime_DateTime *)self)->data, + ((PyDateTime_DateTime *)other)->data, + _PyDateTime_DATETIME_DATASIZE); + if ((op == Py_EQ || op == Py_NE) && diff == 0) { + int ex = pep495_eq_exception(self, other, offset1, offset2); + if (ex == -1) + goto done; + if (ex) + diff = 1; + } + result = diff_to_bool(diff, op); + } + else if (offset1 != Py_None && offset2 != Py_None) { + PyDateTime_Delta *delta; + + assert(offset1 != offset2); /* else last "if" handled it */ + delta = (PyDateTime_Delta *)datetime_subtract((PyObject *)self, + other); + if (delta == NULL) + goto done; + diff = GET_TD_DAYS(delta); + if (diff == 0) + diff = GET_TD_SECONDS(delta) | + GET_TD_MICROSECONDS(delta); + Py_DECREF(delta); + if ((op == Py_EQ || op == Py_NE) && diff == 0) { + int ex = pep495_eq_exception(self, other, offset1, offset2); + if (ex == -1) + goto done; + if (ex) + diff = 1; + } + result = diff_to_bool(diff, op); + } + else if (op == Py_EQ) { + result = Py_False; + Py_INCREF(result); + } + else if (op == Py_NE) { + result = Py_True; + Py_INCREF(result); + } + else { + PyErr_SetString(PyExc_TypeError, + "can't compare offset-naive and " + "offset-aware datetimes"); + } + done: + Py_DECREF(offset1); + Py_XDECREF(offset2); + return result; +} + +static Py_hash_t +datetime_hash(PyDateTime_DateTime *self) +{ + if (self->hashcode == -1) { + PyObject *offset, *self0; + if (DATE_GET_FOLD(self)) { + self0 = new_datetime_ex2(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self), + DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + DATE_GET_MICROSECOND(self), + HASTZINFO(self) ? self->tzinfo : Py_None, + 0, Py_TYPE(self)); + if (self0 == NULL) + return -1; + } + else { + self0 = (PyObject *)self; + Py_INCREF(self0); + } + offset = datetime_utcoffset(self0, NULL); + Py_DECREF(self0); + + if (offset == NULL) + return -1; + + /* Reduce this to a hash of another object. */ + if (offset == Py_None) + self->hashcode = generic_hash( + (unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE); + else { + PyObject *temp1, *temp2; + int days, seconds; + + assert(HASTZINFO(self)); + days = ymd_to_ord(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self)); + seconds = DATE_GET_HOUR(self) * 3600 + + DATE_GET_MINUTE(self) * 60 + + DATE_GET_SECOND(self); + temp1 = new_delta(days, seconds, + DATE_GET_MICROSECOND(self), + 1); + if (temp1 == NULL) { + Py_DECREF(offset); + return -1; + } + temp2 = delta_subtract(temp1, offset); + Py_DECREF(temp1); + if (temp2 == NULL) { + Py_DECREF(offset); + return -1; + } + self->hashcode = PyObject_Hash(temp2); + Py_DECREF(temp2); + } + Py_DECREF(offset); + } + return self->hashcode; +} + +static PyObject * +datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) +{ + PyObject *clone; + PyObject *tuple; + int y = GET_YEAR(self); + int m = GET_MONTH(self); + int d = GET_DAY(self); + int hh = DATE_GET_HOUR(self); + int mm = DATE_GET_MINUTE(self); + int ss = DATE_GET_SECOND(self); + int us = DATE_GET_MICROSECOND(self); + PyObject *tzinfo = HASTZINFO(self) ? self->tzinfo : Py_None; + int fold = DATE_GET_FOLD(self); + + if (! PyArg_ParseTupleAndKeywords(args, kw, "|iiiiiiiO$i:replace", + datetime_kws, + &y, &m, &d, &hh, &mm, &ss, &us, + &tzinfo, &fold)) + return NULL; + if (fold != 0 && fold != 1) { + PyErr_SetString(PyExc_ValueError, + "fold must be either 0 or 1"); + return NULL; + } + tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo); + if (tuple == NULL) + return NULL; + clone = datetime_new(Py_TYPE(self), tuple, NULL); + if (clone != NULL) { + DATE_SET_FOLD(clone, fold); + } + Py_DECREF(tuple); + return clone; +} + +static PyObject * +local_timezone_from_timestamp(time_t timestamp) +{ + PyObject *result = NULL; + PyObject *delta; + struct tm local_time_tm; + PyObject *nameo = NULL; + const char *zone = NULL; + + if (_PyTime_localtime(timestamp, &local_time_tm) != 0) + return NULL; +#ifdef HAVE_STRUCT_TM_TM_ZONE + zone = local_time_tm.tm_zone; + delta = new_delta(0, local_time_tm.tm_gmtoff, 0, 1); +#else /* HAVE_STRUCT_TM_TM_ZONE */ + { + PyObject *local_time, *utc_time; + struct tm utc_time_tm; + char buf[100]; + strftime(buf, sizeof(buf), "%Z", &local_time_tm); + zone = buf; + local_time = new_datetime(local_time_tm.tm_year + 1900, + local_time_tm.tm_mon + 1, + local_time_tm.tm_mday, + local_time_tm.tm_hour, + local_time_tm.tm_min, + local_time_tm.tm_sec, 0, Py_None, 0); + if (local_time == NULL) { + return NULL; + } + if (_PyTime_gmtime(timestamp, &utc_time_tm) != 0) + return NULL; + utc_time = new_datetime(utc_time_tm.tm_year + 1900, + utc_time_tm.tm_mon + 1, + utc_time_tm.tm_mday, + utc_time_tm.tm_hour, + utc_time_tm.tm_min, + utc_time_tm.tm_sec, 0, Py_None, 0); + if (utc_time == NULL) { + Py_DECREF(local_time); + return NULL; + } + delta = datetime_subtract(local_time, utc_time); + Py_DECREF(local_time); + Py_DECREF(utc_time); + } +#endif /* HAVE_STRUCT_TM_TM_ZONE */ + if (delta == NULL) { + return NULL; + } + if (zone != NULL) { + nameo = PyUnicode_DecodeLocale(zone, "surrogateescape"); + if (nameo == NULL) + goto error; + } + result = new_timezone(delta, nameo); + Py_XDECREF(nameo); + error: + Py_DECREF(delta); + return result; +} + +static PyObject * +local_timezone(PyDateTime_DateTime *utc_time) +{ + time_t timestamp; + PyObject *delta; + PyObject *one_second; + PyObject *seconds; + + delta = datetime_subtract((PyObject *)utc_time, PyDateTime_Epoch); + if (delta == NULL) + return NULL; + one_second = new_delta(0, 1, 0, 0); + if (one_second == NULL) { + Py_DECREF(delta); + return NULL; + } + seconds = divide_timedelta_timedelta((PyDateTime_Delta *)delta, + (PyDateTime_Delta *)one_second); + Py_DECREF(one_second); + Py_DECREF(delta); + if (seconds == NULL) + return NULL; + timestamp = _PyLong_AsTime_t(seconds); + Py_DECREF(seconds); + if (timestamp == -1 && PyErr_Occurred()) + return NULL; + return local_timezone_from_timestamp(timestamp); +} + +static long long +local_to_seconds(int year, int month, int day, + int hour, int minute, int second, int fold); + +static PyObject * +local_timezone_from_local(PyDateTime_DateTime *local_dt) +{ + long long seconds; + time_t timestamp; + seconds = local_to_seconds(GET_YEAR(local_dt), + GET_MONTH(local_dt), + GET_DAY(local_dt), + DATE_GET_HOUR(local_dt), + DATE_GET_MINUTE(local_dt), + DATE_GET_SECOND(local_dt), + DATE_GET_FOLD(local_dt)); + if (seconds == -1) + return NULL; + /* XXX: add bounds check */ + timestamp = seconds - epoch; + return local_timezone_from_timestamp(timestamp); +} + +static PyDateTime_DateTime * +datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) +{ + PyDateTime_DateTime *result; + PyObject *offset; + PyObject *temp; + PyObject *self_tzinfo; + PyObject *tzinfo = Py_None; + static char *keywords[] = {"tz", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords, + &tzinfo)) + return NULL; + + if (check_tzinfo_subclass(tzinfo) == -1) + return NULL; + + if (!HASTZINFO(self) || self->tzinfo == Py_None) { + naive: + self_tzinfo = local_timezone_from_local(self); + if (self_tzinfo == NULL) + return NULL; + } else { + self_tzinfo = self->tzinfo; + Py_INCREF(self_tzinfo); + } + + /* Conversion to self's own time zone is a NOP. */ + if (self_tzinfo == tzinfo) { + Py_DECREF(self_tzinfo); + Py_INCREF(self); + return self; + } + + /* Convert self to UTC. */ + offset = call_utcoffset(self_tzinfo, (PyObject *)self); + Py_DECREF(self_tzinfo); + if (offset == NULL) + return NULL; + else if(offset == Py_None) { + Py_DECREF(offset); + goto naive; + } + else if (!PyDelta_Check(offset)) { + Py_DECREF(offset); + PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s," + " expected timedelta or None", Py_TYPE(offset)->tp_name); + return NULL; + } + /* result = self - offset */ + result = (PyDateTime_DateTime *)add_datetime_timedelta(self, + (PyDateTime_Delta *)offset, -1); + Py_DECREF(offset); + if (result == NULL) + return NULL; + + /* Make sure result is aware and UTC. */ + if (!HASTZINFO(result)) { + temp = (PyObject *)result; + result = (PyDateTime_DateTime *) + new_datetime_ex2(GET_YEAR(result), + GET_MONTH(result), + GET_DAY(result), + DATE_GET_HOUR(result), + DATE_GET_MINUTE(result), + DATE_GET_SECOND(result), + DATE_GET_MICROSECOND(result), + PyDateTime_TimeZone_UTC, + DATE_GET_FOLD(result), + Py_TYPE(result)); + Py_DECREF(temp); + if (result == NULL) + return NULL; + } + else { + /* Result is already aware - just replace tzinfo. */ + temp = result->tzinfo; + result->tzinfo = PyDateTime_TimeZone_UTC; + Py_INCREF(result->tzinfo); + Py_DECREF(temp); + } + + /* Attach new tzinfo and let fromutc() do the rest. */ + temp = result->tzinfo; + if (tzinfo == Py_None) { + tzinfo = local_timezone(result); + if (tzinfo == NULL) { + Py_DECREF(result); + return NULL; + } + } + else + Py_INCREF(tzinfo); + result->tzinfo = tzinfo; + Py_DECREF(temp); + + temp = (PyObject *)result; + result = (PyDateTime_DateTime *) + _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp); + Py_DECREF(temp); + + return result; +} + +static PyObject * +datetime_timetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) +{ + int dstflag = -1; + + if (HASTZINFO(self) && self->tzinfo != Py_None) { + PyObject * dst; + + dst = call_dst(self->tzinfo, (PyObject *)self); + if (dst == NULL) + return NULL; + + if (dst != Py_None) + dstflag = delta_bool((PyDateTime_Delta *)dst); + Py_DECREF(dst); + } + return build_struct_time(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self), + DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + dstflag); +} + +static long long +local_to_seconds(int year, int month, int day, + int hour, int minute, int second, int fold) +{ + long long t, a, b, u1, u2, t1, t2, lt; + t = utc_to_seconds(year, month, day, hour, minute, second); + /* Our goal is to solve t = local(u) for u. */ + lt = local(t); + if (lt == -1) + return -1; + a = lt - t; + u1 = t - a; + t1 = local(u1); + if (t1 == -1) + return -1; + if (t1 == t) { + /* We found one solution, but it may not be the one we need. + * Look for an earlier solution (if `fold` is 0), or a + * later one (if `fold` is 1). */ + if (fold) + u2 = u1 + max_fold_seconds; + else + u2 = u1 - max_fold_seconds; + lt = local(u2); + if (lt == -1) + return -1; + b = lt - u2; + if (a == b) + return u1; + } + else { + b = t1 - u1; + assert(a != b); + } + u2 = t - b; + t2 = local(u2); + if (t2 == -1) + return -1; + if (t2 == t) + return u2; + if (t1 == t) + return u1; + /* We have found both offsets a and b, but neither t - a nor t - b is + * a solution. This means t is in the gap. */ + return fold?Py_MIN(u1, u2):Py_MAX(u1, u2); +} + +/* date(1970,1,1).toordinal() == 719163 */ +#define EPOCH_SECONDS (719163LL * 24 * 60 * 60) + +static PyObject * +datetime_timestamp(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *result; + + if (HASTZINFO(self) && self->tzinfo != Py_None) { + PyObject *delta; + delta = datetime_subtract((PyObject *)self, PyDateTime_Epoch); + if (delta == NULL) + return NULL; + result = delta_total_seconds(delta, NULL); + Py_DECREF(delta); + } + else { + long long seconds; + seconds = local_to_seconds(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self), + DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + DATE_GET_FOLD(self)); + if (seconds == -1) + return NULL; + result = PyFloat_FromDouble(seconds - EPOCH_SECONDS + + DATE_GET_MICROSECOND(self) / 1e6); + } + return result; +} + +static PyObject * +datetime_getdate(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) +{ + return new_date(GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self)); +} + +static PyObject * +datetime_gettime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) +{ + return new_time(DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + DATE_GET_MICROSECOND(self), + Py_None, + DATE_GET_FOLD(self)); +} + +static PyObject * +datetime_gettimetz(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) +{ + return new_time(DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + DATE_GET_MICROSECOND(self), + GET_DT_TZINFO(self), + DATE_GET_FOLD(self)); +} + +static PyObject * +datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) +{ + int y, m, d, hh, mm, ss; + PyObject *tzinfo; + PyDateTime_DateTime *utcself; + + tzinfo = GET_DT_TZINFO(self); + if (tzinfo == Py_None) { + utcself = self; + Py_INCREF(utcself); + } + else { + PyObject *offset; + offset = call_utcoffset(tzinfo, (PyObject *)self); + if (offset == NULL) + return NULL; + if (offset == Py_None) { + Py_DECREF(offset); + utcself = self; + Py_INCREF(utcself); + } + else { + utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self, + (PyDateTime_Delta *)offset, -1); + Py_DECREF(offset); + if (utcself == NULL) + return NULL; + } + } + y = GET_YEAR(utcself); + m = GET_MONTH(utcself); + d = GET_DAY(utcself); + hh = DATE_GET_HOUR(utcself); + mm = DATE_GET_MINUTE(utcself); + ss = DATE_GET_SECOND(utcself); + + Py_DECREF(utcself); + return build_struct_time(y, m, d, hh, mm, ss, 0); +} + +/* Pickle support, a simple use of __reduce__. */ + +/* Let basestate be the non-tzinfo data string. + * If tzinfo is None, this returns (basestate,), else (basestate, tzinfo). + * So it's a tuple in any (non-error) case. + * __getstate__ isn't exposed. + */ +static PyObject * +datetime_getstate(PyDateTime_DateTime *self, int proto) +{ + PyObject *basestate; + PyObject *result = NULL; + + basestate = PyBytes_FromStringAndSize((char *)self->data, + _PyDateTime_DATETIME_DATASIZE); + if (basestate != NULL) { + if (proto > 3 && DATE_GET_FOLD(self)) + /* Set the first bit of the third byte */ + PyBytes_AS_STRING(basestate)[2] |= (1 << 7); + if (! HASTZINFO(self) || self->tzinfo == Py_None) + result = PyTuple_Pack(1, basestate); + else + result = PyTuple_Pack(2, basestate, self->tzinfo); + Py_DECREF(basestate); + } + return result; +} + +static PyObject * +datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args) +{ + int proto; + if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto)) + return NULL; + + return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto)); +} + +static PyObject * +datetime_reduce(PyDateTime_DateTime *self, PyObject *arg) +{ + return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2)); +} + +static PyMethodDef datetime_methods[] = { + + /* Class methods: */ + + DATETIME_DATETIME_NOW_METHODDEF + + {"utcnow", (PyCFunction)datetime_utcnow, + METH_NOARGS | METH_CLASS, + PyDoc_STR("Return a new datetime representing UTC day and time.")}, + {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")}, - - {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp, - METH_VARARGS | METH_CLASS, - PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")}, - - {"strptime", (PyCFunction)datetime_strptime, - METH_VARARGS | METH_CLASS, - PyDoc_STR("string, format -> new datetime parsed from a string " - "(like time.strptime()).")}, - + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")}, + + {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp, + METH_VARARGS | METH_CLASS, + PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")}, + + {"strptime", (PyCFunction)datetime_strptime, + METH_VARARGS | METH_CLASS, + PyDoc_STR("string, format -> new datetime parsed from a string " + "(like time.strptime()).")}, + {"combine", (PyCFunction)(void(*)(void))datetime_combine, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("date, time -> datetime with same date and time fields")}, - - {"fromisoformat", (PyCFunction)datetime_fromisoformat, - METH_O | METH_CLASS, - PyDoc_STR("string -> datetime from datetime.isoformat() output")}, - - /* Instance methods: */ - - {"date", (PyCFunction)datetime_getdate, METH_NOARGS, - PyDoc_STR("Return date object with same year, month and day.")}, - - {"time", (PyCFunction)datetime_gettime, METH_NOARGS, - PyDoc_STR("Return time object with same time but with tzinfo=None.")}, - - {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS, - PyDoc_STR("Return time object with same time and tzinfo.")}, - - {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS, - PyDoc_STR("Return ctime() style string.")}, - - {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS, - PyDoc_STR("Return time tuple, compatible with time.localtime().")}, - - {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS, - PyDoc_STR("Return POSIX timestamp as float.")}, - - {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS, - PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")}, - + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("date, time -> datetime with same date and time fields")}, + + {"fromisoformat", (PyCFunction)datetime_fromisoformat, + METH_O | METH_CLASS, + PyDoc_STR("string -> datetime from datetime.isoformat() output")}, + + /* Instance methods: */ + + {"date", (PyCFunction)datetime_getdate, METH_NOARGS, + PyDoc_STR("Return date object with same year, month and day.")}, + + {"time", (PyCFunction)datetime_gettime, METH_NOARGS, + PyDoc_STR("Return time object with same time but with tzinfo=None.")}, + + {"timetz", (PyCFunction)datetime_gettimetz, METH_NOARGS, + PyDoc_STR("Return time object with same time and tzinfo.")}, + + {"ctime", (PyCFunction)datetime_ctime, METH_NOARGS, + PyDoc_STR("Return ctime() style string.")}, + + {"timetuple", (PyCFunction)datetime_timetuple, METH_NOARGS, + PyDoc_STR("Return time tuple, compatible with time.localtime().")}, + + {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS, + PyDoc_STR("Return POSIX timestamp as float.")}, + + {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS, + PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")}, + {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("[sep] -> string in ISO 8601 format, " - "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n" - "sep is used to separate the year from the time, and " - "defaults to 'T'.\n" + PyDoc_STR("[sep] -> string in ISO 8601 format, " + "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n" + "sep is used to separate the year from the time, and " + "defaults to 'T'.\n" "The optional argument timespec specifies the number " "of additional terms\nof the time to include. Valid " "options are 'auto', 'hours', 'minutes',\n'seconds', " "'milliseconds' and 'microseconds'.\n")}, - - {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS, - PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, - - {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS, - PyDoc_STR("Return self.tzinfo.tzname(self).")}, - - {"dst", (PyCFunction)datetime_dst, METH_NOARGS, - PyDoc_STR("Return self.tzinfo.dst(self).")}, - + + {"utcoffset", (PyCFunction)datetime_utcoffset, METH_NOARGS, + PyDoc_STR("Return self.tzinfo.utcoffset(self).")}, + + {"tzname", (PyCFunction)datetime_tzname, METH_NOARGS, + PyDoc_STR("Return self.tzinfo.tzname(self).")}, + + {"dst", (PyCFunction)datetime_dst, METH_NOARGS, + PyDoc_STR("Return self.tzinfo.dst(self).")}, + {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Return datetime with new specified fields.")}, - + PyDoc_STR("Return datetime with new specified fields.")}, + {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, - - {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS, - PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, - - {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS, - PyDoc_STR("__reduce__() -> (cls, state)")}, - - {NULL, NULL} -}; - -static const char datetime_doc[] = -PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\ -\n\ -The year, month and day arguments are required. tzinfo may be None, or an\n\ -instance of a tzinfo subclass. The remaining arguments may be ints.\n"); - -static PyNumberMethods datetime_as_number = { - datetime_add, /* nb_add */ - datetime_subtract, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - 0, /* nb_bool */ -}; - -static PyTypeObject PyDateTime_DateTimeType = { - PyVarObject_HEAD_INIT(NULL, 0) - "datetime.datetime", /* tp_name */ - sizeof(PyDateTime_DateTime), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)datetime_dealloc, /* tp_dealloc */ + PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, + + {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS, + PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, + + {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS, + PyDoc_STR("__reduce__() -> (cls, state)")}, + + {NULL, NULL} +}; + +static const char datetime_doc[] = +PyDoc_STR("datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])\n\ +\n\ +The year, month and day arguments are required. tzinfo may be None, or an\n\ +instance of a tzinfo subclass. The remaining arguments may be ints.\n"); + +static PyNumberMethods datetime_as_number = { + datetime_add, /* nb_add */ + datetime_subtract, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_bool */ +}; + +static PyTypeObject PyDateTime_DateTimeType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.datetime", /* tp_name */ + sizeof(PyDateTime_DateTime), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)datetime_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)datetime_repr, /* tp_repr */ - &datetime_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)datetime_hash, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)datetime_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - datetime_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - datetime_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - datetime_methods, /* tp_methods */ - 0, /* tp_members */ - datetime_getset, /* tp_getset */ + (reprfunc)datetime_repr, /* tp_repr */ + &datetime_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)datetime_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)datetime_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + datetime_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + datetime_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + datetime_methods, /* tp_methods */ + 0, /* tp_members */ + datetime_getset, /* tp_getset */ 0, /* tp_base; filled in PyInit__datetime */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - datetime_alloc, /* tp_alloc */ - datetime_new, /* tp_new */ - 0, /* tp_free */ -}; - -/* --------------------------------------------------------------------------- - * Module methods and initialization. - */ - -static PyMethodDef module_methods[] = { - {NULL, NULL} -}; - -/* C API. Clients get at this via PyDateTime_IMPORT, defined in - * datetime.h. - */ -static PyDateTime_CAPI CAPI = { - &PyDateTime_DateType, - &PyDateTime_DateTimeType, - &PyDateTime_TimeType, - &PyDateTime_DeltaType, - &PyDateTime_TZInfoType, - NULL, // PyDatetime_TimeZone_UTC not initialized yet - new_date_ex, - new_datetime_ex, - new_time_ex, - new_delta_ex, - new_timezone, - datetime_fromtimestamp, + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + datetime_alloc, /* tp_alloc */ + datetime_new, /* tp_new */ + 0, /* tp_free */ +}; + +/* --------------------------------------------------------------------------- + * Module methods and initialization. + */ + +static PyMethodDef module_methods[] = { + {NULL, NULL} +}; + +/* C API. Clients get at this via PyDateTime_IMPORT, defined in + * datetime.h. + */ +static PyDateTime_CAPI CAPI = { + &PyDateTime_DateType, + &PyDateTime_DateTimeType, + &PyDateTime_TimeType, + &PyDateTime_DeltaType, + &PyDateTime_TZInfoType, + NULL, // PyDatetime_TimeZone_UTC not initialized yet + new_date_ex, + new_datetime_ex, + new_time_ex, + new_delta_ex, + new_timezone, + datetime_fromtimestamp, datetime_date_fromtimestamp_capi, - new_datetime_ex2, - new_time_ex2 -}; - - - -static struct PyModuleDef datetimemodule = { - PyModuleDef_HEAD_INIT, - "_datetime", - "Fast implementation of the datetime type.", - -1, - module_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__datetime(void) -{ - PyObject *m; /* a module object */ - PyObject *d; /* its dict */ - PyObject *x; - PyObject *delta; - - m = PyModule_Create(&datetimemodule); - if (m == NULL) - return NULL; - + new_datetime_ex2, + new_time_ex2 +}; + + + +static struct PyModuleDef datetimemodule = { + PyModuleDef_HEAD_INIT, + "_datetime", + "Fast implementation of the datetime type.", + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__datetime(void) +{ + PyObject *m; /* a module object */ + PyObject *d; /* its dict */ + PyObject *x; + PyObject *delta; + + m = PyModule_Create(&datetimemodule); + if (m == NULL) + return NULL; + // `&...` is not a constant expression according to a strict reading // of C standards. Fill tp_base at run-time rather than statically. // See https://bugs.python.org/issue40777 @@ -6552,362 +6552,362 @@ PyInit__datetime(void) } if (PyType_Ready(&PyDateTime_IsoCalendarDateType) < 0) { - return NULL; + return NULL; } Py_INCREF(&PyDateTime_IsoCalendarDateType); - - /* timedelta values */ - d = PyDateTime_DeltaType.tp_dict; - - x = new_delta(0, 0, 1, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); - - /* date values */ - d = PyDateTime_DateType.tp_dict; - - x = new_date(1, 1, 1); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_date(MAXYEAR, 12, 31); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(1, 0, 0, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return NULL; - Py_DECREF(x); - - /* time values */ - d = PyDateTime_TimeType.tp_dict; - - x = new_time(0, 0, 0, 0, Py_None, 0); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_time(23, 59, 59, 999999, Py_None, 0); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(0, 0, 1, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return NULL; - Py_DECREF(x); - - /* datetime values */ - d = PyDateTime_DateTimeType.tp_dict; - - x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); - - x = new_delta(0, 0, 1, 0); - if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) - return NULL; - Py_DECREF(x); - - /* timezone values */ - d = PyDateTime_TimeZoneType.tp_dict; - - delta = new_delta(0, 0, 0, 0); - if (delta == NULL) - return NULL; - x = create_timezone(delta, NULL); - Py_DECREF(delta); - if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0) - return NULL; - PyDateTime_TimeZone_UTC = x; - CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC; - + + /* timedelta values */ + d = PyDateTime_DeltaType.tp_dict; + + x = new_delta(0, 0, 1, 0); + if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) + return NULL; + Py_DECREF(x); + + x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0); + if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) + return NULL; + Py_DECREF(x); + + x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0); + if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) + return NULL; + Py_DECREF(x); + + /* date values */ + d = PyDateTime_DateType.tp_dict; + + x = new_date(1, 1, 1); + if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) + return NULL; + Py_DECREF(x); + + x = new_date(MAXYEAR, 12, 31); + if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) + return NULL; + Py_DECREF(x); + + x = new_delta(1, 0, 0, 0); + if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) + return NULL; + Py_DECREF(x); + + /* time values */ + d = PyDateTime_TimeType.tp_dict; + + x = new_time(0, 0, 0, 0, Py_None, 0); + if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) + return NULL; + Py_DECREF(x); + + x = new_time(23, 59, 59, 999999, Py_None, 0); + if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) + return NULL; + Py_DECREF(x); + + x = new_delta(0, 0, 1, 0); + if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) + return NULL; + Py_DECREF(x); + + /* datetime values */ + d = PyDateTime_DateTimeType.tp_dict; + + x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None, 0); + if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) + return NULL; + Py_DECREF(x); + + x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None, 0); + if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) + return NULL; + Py_DECREF(x); + + x = new_delta(0, 0, 1, 0); + if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0) + return NULL; + Py_DECREF(x); + + /* timezone values */ + d = PyDateTime_TimeZoneType.tp_dict; + + delta = new_delta(0, 0, 0, 0); + if (delta == NULL) + return NULL; + x = create_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0) + return NULL; + PyDateTime_TimeZone_UTC = x; + CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC; + /* bpo-37642: These attributes are rounded to the nearest minute for backwards * compatibility, even though the constructor will accept a wider range of * values. This may change in the future.*/ - delta = new_delta(-1, 60, 0, 1); /* -23:59 */ - if (delta == NULL) - return NULL; - x = create_timezone(delta, NULL); - Py_DECREF(delta); - if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) - return NULL; - Py_DECREF(x); - - delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */ - if (delta == NULL) - return NULL; - x = create_timezone(delta, NULL); - Py_DECREF(delta); - if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) - return NULL; - Py_DECREF(x); - - /* Epoch */ - PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0, - PyDateTime_TimeZone_UTC, 0); - if (PyDateTime_Epoch == NULL) - return NULL; - - /* module initialization */ - PyModule_AddIntMacro(m, MINYEAR); - PyModule_AddIntMacro(m, MAXYEAR); - - x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL); - if (x == NULL) - return NULL; - PyModule_AddObject(m, "datetime_CAPI", x); - - /* A 4-year cycle has an extra leap day over what we'd get from - * pasting together 4 single years. - */ - Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1); - assert(DI4Y == days_before_year(4+1)); - - /* Similarly, a 400-year cycle has an extra leap day over what we'd - * get from pasting together 4 100-year cycles. - */ - Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1); - assert(DI400Y == days_before_year(400+1)); - - /* OTOH, a 100-year cycle has one fewer leap day than we'd get from - * pasting together 25 4-year cycles. - */ - Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1); - assert(DI100Y == days_before_year(100+1)); - - us_per_ms = PyLong_FromLong(1000); - us_per_second = PyLong_FromLong(1000000); - us_per_minute = PyLong_FromLong(60000000); - seconds_per_day = PyLong_FromLong(24 * 3600); - if (us_per_ms == NULL || us_per_second == NULL || - us_per_minute == NULL || seconds_per_day == NULL) - return NULL; - - /* The rest are too big for 32-bit ints, but even - * us_per_week fits in 40 bits, so doubles should be exact. - */ - us_per_hour = PyLong_FromDouble(3600000000.0); - us_per_day = PyLong_FromDouble(86400000000.0); - us_per_week = PyLong_FromDouble(604800000000.0); - if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) - return NULL; - return m; -} - -/* --------------------------------------------------------------------------- -Some time zone algebra. For a datetime x, let - x.n = x stripped of its timezone -- its naive time. - x.o = x.utcoffset(), and assuming that doesn't raise an exception or - return None - x.d = x.dst(), and assuming that doesn't raise an exception or - return None - x.s = x's standard offset, x.o - x.d - -Now some derived rules, where k is a duration (timedelta). - -1. x.o = x.s + x.d - This follows from the definition of x.s. - -2. If x and y have the same tzinfo member, x.s = y.s. - This is actually a requirement, an assumption we need to make about - sane tzinfo classes. - -3. The naive UTC time corresponding to x is x.n - x.o. - This is again a requirement for a sane tzinfo class. - -4. (x+k).s = x.s - This follows from #2, and that datimetimetz+timedelta preserves tzinfo. - -5. (x+k).n = x.n + k - Again follows from how arithmetic is defined. - -Now we can explain tz.fromutc(x). Let's assume it's an interesting case -(meaning that the various tzinfo methods exist, and don't blow up or return -None when called). - -The function wants to return a datetime y with timezone tz, equivalent to x. -x is already in UTC. - -By #3, we want - - y.n - y.o = x.n [1] - -The algorithm starts by attaching tz to x.n, and calling that y. So -x.n = y.n at the start. Then it wants to add a duration k to y, so that [1] -becomes true; in effect, we want to solve [2] for k: - - (y+k).n - (y+k).o = x.n [2] - -By #1, this is the same as - - (y+k).n - ((y+k).s + (y+k).d) = x.n [3] - -By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. -Substituting that into [3], - - x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving - k - (y+k).s - (y+k).d = 0; rearranging, - k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so - k = y.s - (y+k).d - -On the RHS, (y+k).d can't be computed directly, but y.s can be, and we -approximate k by ignoring the (y+k).d term at first. Note that k can't be -very large, since all offset-returning methods return a duration of magnitude -less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must -be 0, so ignoring it has no consequence then. - -In any case, the new value is - - z = y + y.s [4] - -It's helpful to step back at look at [4] from a higher level: it's simply -mapping from UTC to tz's standard time. - -At this point, if - - z.n - z.o = x.n [5] - -we have an equivalent time, and are almost done. The insecurity here is -at the start of daylight time. Picture US Eastern for concreteness. The wall -time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good -sense then. The docs ask that an Eastern tzinfo class consider such a time to -be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST -on the day DST starts. We want to return the 1:MM EST spelling because that's -the only spelling that makes sense on the local wall clock. - -In fact, if [5] holds at this point, we do have the standard-time spelling, -but that takes a bit of proof. We first prove a stronger result. What's the -difference between the LHS and RHS of [5]? Let - - diff = x.n - (z.n - z.o) [6] - -Now - z.n = by [4] - (y + y.s).n = by #5 - y.n + y.s = since y.n = x.n - x.n + y.s = since z and y are have the same tzinfo member, - y.s = z.s by #2 - x.n + z.s - -Plugging that back into [6] gives - - diff = - x.n - ((x.n + z.s) - z.o) = expanding - x.n - x.n - z.s + z.o = cancelling - - z.s + z.o = by #2 - z.d - -So diff = z.d. - -If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time -spelling we wanted in the endcase described above. We're done. Contrarily, -if z.d = 0, then we have a UTC equivalent, and are also done. - -If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to -add to z (in effect, z is in tz's standard time, and we need to shift the -local clock into tz's daylight time). - -Let - - z' = z + z.d = z + diff [7] - -and we can again ask whether - - z'.n - z'.o = x.n [8] - -If so, we're done. If not, the tzinfo class is insane, according to the -assumptions we've made. This also requires a bit of proof. As before, let's -compute the difference between the LHS and RHS of [8] (and skipping some of -the justifications for the kinds of substitutions we've done several times -already): - - diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7] - x.n - (z.n + diff - z'.o) = replacing diff via [6] - x.n - (z.n + x.n - (z.n - z.o) - z'.o) = - x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n - - z.n + z.n - z.o + z'.o = cancel z.n - - z.o + z'.o = #1 twice - -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo - z'.d - z.d - -So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, -we've found the UTC-equivalent so are done. In fact, we stop with [7] and -return z', not bothering to compute z'.d. - -How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by -a dst() offset, and starting *from* a time already in DST (we know z.d != 0), -would have to change the result dst() returns: we start in DST, and moving -a little further into it takes us out of DST. - -There isn't a sane case where this can happen. The closest it gets is at -the end of DST, where there's an hour in UTC with no spelling in a hybrid -tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During -that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM -UTC) because the docs insist on that, but 0:MM is taken as being in daylight -time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local -clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in -standard time. Since that's what the local clock *does*, we want to map both -UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous -in local time, but so it goes -- it's the way the local clock works. - -When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, -so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. -z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] -(correctly) concludes that z' is not UTC-equivalent to x. - -Because we know z.d said z was in daylight time (else [5] would have held and -we would have stopped then), and we know z.d != z'.d (else [8] would have held -and we would have stopped then), and there are only 2 possible values dst() can -return in Eastern, it follows that z'.d must be 0 (which it is in the example, -but the reasoning doesn't depend on the example -- it depends on there being -two possible dst() outcomes, one zero and the other non-zero). Therefore -z' must be in standard time, and is the spelling we want in this case. - -Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is -concerned (because it takes z' as being in standard time rather than the -daylight time we intend here), but returning it gives the real-life "local -clock repeats an hour" behavior when mapping the "unspellable" UTC hour into -tz. - -When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with -the 1:MM standard time spelling we want. - -So how can this break? One of the assumptions must be violated. Two -possibilities: - -1) [2] effectively says that y.s is invariant across all y belong to a given - time zone. This isn't true if, for political reasons or continental drift, - a region decides to change its base offset from UTC. - -2) There may be versions of "double daylight" time where the tail end of - the analysis gives up a step too early. I haven't thought about that - enough to say. - -In any case, it's clear that the default fromutc() is strong enough to handle -"almost all" time zones: so long as the standard offset is invariant, it -doesn't matter if daylight time transition points change from year to year, or -if daylight time is skipped in some years; it doesn't matter how large or -small dst() may get within its bounds; and it doesn't even matter if some -perverse time zone returns a negative dst()). So a breaking case must be -pretty bizarre, and a tzinfo subclass can override fromutc() if it is. ---------------------------------------------------------------------------- */ + delta = new_delta(-1, 60, 0, 1); /* -23:59 */ + if (delta == NULL) + return NULL; + x = create_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) + return NULL; + Py_DECREF(x); + + delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */ + if (delta == NULL) + return NULL; + x = create_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) + return NULL; + Py_DECREF(x); + + /* Epoch */ + PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0, + PyDateTime_TimeZone_UTC, 0); + if (PyDateTime_Epoch == NULL) + return NULL; + + /* module initialization */ + PyModule_AddIntMacro(m, MINYEAR); + PyModule_AddIntMacro(m, MAXYEAR); + + x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL); + if (x == NULL) + return NULL; + PyModule_AddObject(m, "datetime_CAPI", x); + + /* A 4-year cycle has an extra leap day over what we'd get from + * pasting together 4 single years. + */ + Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1); + assert(DI4Y == days_before_year(4+1)); + + /* Similarly, a 400-year cycle has an extra leap day over what we'd + * get from pasting together 4 100-year cycles. + */ + Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1); + assert(DI400Y == days_before_year(400+1)); + + /* OTOH, a 100-year cycle has one fewer leap day than we'd get from + * pasting together 25 4-year cycles. + */ + Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1); + assert(DI100Y == days_before_year(100+1)); + + us_per_ms = PyLong_FromLong(1000); + us_per_second = PyLong_FromLong(1000000); + us_per_minute = PyLong_FromLong(60000000); + seconds_per_day = PyLong_FromLong(24 * 3600); + if (us_per_ms == NULL || us_per_second == NULL || + us_per_minute == NULL || seconds_per_day == NULL) + return NULL; + + /* The rest are too big for 32-bit ints, but even + * us_per_week fits in 40 bits, so doubles should be exact. + */ + us_per_hour = PyLong_FromDouble(3600000000.0); + us_per_day = PyLong_FromDouble(86400000000.0); + us_per_week = PyLong_FromDouble(604800000000.0); + if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) + return NULL; + return m; +} + +/* --------------------------------------------------------------------------- +Some time zone algebra. For a datetime x, let + x.n = x stripped of its timezone -- its naive time. + x.o = x.utcoffset(), and assuming that doesn't raise an exception or + return None + x.d = x.dst(), and assuming that doesn't raise an exception or + return None + x.s = x's standard offset, x.o - x.d + +Now some derived rules, where k is a duration (timedelta). + +1. x.o = x.s + x.d + This follows from the definition of x.s. + +2. If x and y have the same tzinfo member, x.s = y.s. + This is actually a requirement, an assumption we need to make about + sane tzinfo classes. + +3. The naive UTC time corresponding to x is x.n - x.o. + This is again a requirement for a sane tzinfo class. + +4. (x+k).s = x.s + This follows from #2, and that datimetimetz+timedelta preserves tzinfo. + +5. (x+k).n = x.n + k + Again follows from how arithmetic is defined. + +Now we can explain tz.fromutc(x). Let's assume it's an interesting case +(meaning that the various tzinfo methods exist, and don't blow up or return +None when called). + +The function wants to return a datetime y with timezone tz, equivalent to x. +x is already in UTC. + +By #3, we want + + y.n - y.o = x.n [1] + +The algorithm starts by attaching tz to x.n, and calling that y. So +x.n = y.n at the start. Then it wants to add a duration k to y, so that [1] +becomes true; in effect, we want to solve [2] for k: + + (y+k).n - (y+k).o = x.n [2] + +By #1, this is the same as + + (y+k).n - ((y+k).s + (y+k).d) = x.n [3] + +By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. +Substituting that into [3], + + x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving + k - (y+k).s - (y+k).d = 0; rearranging, + k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so + k = y.s - (y+k).d + +On the RHS, (y+k).d can't be computed directly, but y.s can be, and we +approximate k by ignoring the (y+k).d term at first. Note that k can't be +very large, since all offset-returning methods return a duration of magnitude +less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must +be 0, so ignoring it has no consequence then. + +In any case, the new value is + + z = y + y.s [4] + +It's helpful to step back at look at [4] from a higher level: it's simply +mapping from UTC to tz's standard time. + +At this point, if + + z.n - z.o = x.n [5] + +we have an equivalent time, and are almost done. The insecurity here is +at the start of daylight time. Picture US Eastern for concreteness. The wall +time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good +sense then. The docs ask that an Eastern tzinfo class consider such a time to +be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST +on the day DST starts. We want to return the 1:MM EST spelling because that's +the only spelling that makes sense on the local wall clock. + +In fact, if [5] holds at this point, we do have the standard-time spelling, +but that takes a bit of proof. We first prove a stronger result. What's the +difference between the LHS and RHS of [5]? Let + + diff = x.n - (z.n - z.o) [6] + +Now + z.n = by [4] + (y + y.s).n = by #5 + y.n + y.s = since y.n = x.n + x.n + y.s = since z and y are have the same tzinfo member, + y.s = z.s by #2 + x.n + z.s + +Plugging that back into [6] gives + + diff = + x.n - ((x.n + z.s) - z.o) = expanding + x.n - x.n - z.s + z.o = cancelling + - z.s + z.o = by #2 + z.d + +So diff = z.d. + +If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time +spelling we wanted in the endcase described above. We're done. Contrarily, +if z.d = 0, then we have a UTC equivalent, and are also done. + +If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to +add to z (in effect, z is in tz's standard time, and we need to shift the +local clock into tz's daylight time). + +Let + + z' = z + z.d = z + diff [7] + +and we can again ask whether + + z'.n - z'.o = x.n [8] + +If so, we're done. If not, the tzinfo class is insane, according to the +assumptions we've made. This also requires a bit of proof. As before, let's +compute the difference between the LHS and RHS of [8] (and skipping some of +the justifications for the kinds of substitutions we've done several times +already): + + diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7] + x.n - (z.n + diff - z'.o) = replacing diff via [6] + x.n - (z.n + x.n - (z.n - z.o) - z'.o) = + x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n + - z.n + z.n - z.o + z'.o = cancel z.n + - z.o + z'.o = #1 twice + -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo + z'.d - z.d + +So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, +we've found the UTC-equivalent so are done. In fact, we stop with [7] and +return z', not bothering to compute z'.d. + +How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by +a dst() offset, and starting *from* a time already in DST (we know z.d != 0), +would have to change the result dst() returns: we start in DST, and moving +a little further into it takes us out of DST. + +There isn't a sane case where this can happen. The closest it gets is at +the end of DST, where there's an hour in UTC with no spelling in a hybrid +tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During +that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM +UTC) because the docs insist on that, but 0:MM is taken as being in daylight +time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local +clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in +standard time. Since that's what the local clock *does*, we want to map both +UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous +in local time, but so it goes -- it's the way the local clock works. + +When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, +so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. +z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] +(correctly) concludes that z' is not UTC-equivalent to x. + +Because we know z.d said z was in daylight time (else [5] would have held and +we would have stopped then), and we know z.d != z'.d (else [8] would have held +and we would have stopped then), and there are only 2 possible values dst() can +return in Eastern, it follows that z'.d must be 0 (which it is in the example, +but the reasoning doesn't depend on the example -- it depends on there being +two possible dst() outcomes, one zero and the other non-zero). Therefore +z' must be in standard time, and is the spelling we want in this case. + +Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is +concerned (because it takes z' as being in standard time rather than the +daylight time we intend here), but returning it gives the real-life "local +clock repeats an hour" behavior when mapping the "unspellable" UTC hour into +tz. + +When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with +the 1:MM standard time spelling we want. + +So how can this break? One of the assumptions must be violated. Two +possibilities: + +1) [2] effectively says that y.s is invariant across all y belong to a given + time zone. This isn't true if, for political reasons or continental drift, + a region decides to change its base offset from UTC. + +2) There may be versions of "double daylight" time where the tail end of + the analysis gives up a step too early. I haven't thought about that + enough to say. + +In any case, it's clear that the default fromutc() is strong enough to handle +"almost all" time zones: so long as the standard offset is invariant, it +doesn't matter if daylight time transition points change from year to year, or +if daylight time is skipped in some years; it doesn't matter how large or +small dst() may get within its bounds; and it doesn't even matter if some +perverse time zone returns a negative dst()). So a breaking case must be +pretty bizarre, and a tzinfo subclass can override fromutc() if it is. +--------------------------------------------------------------------------- */ diff --git a/contrib/tools/python3/src/Modules/_decimal/_decimal.c b/contrib/tools/python3/src/Modules/_decimal/_decimal.c index d80d7915507..44dc4b1b6cd 100644 --- a/contrib/tools/python3/src/Modules/_decimal/_decimal.c +++ b/contrib/tools/python3/src/Modules/_decimal/_decimal.c @@ -1,130 +1,130 @@ -/* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include -#include "longintrepr.h" -#include "complexobject.h" -#include "mpdecimal.h" - -#include - -#include "docstrings.h" - - +/* + * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include +#include "longintrepr.h" +#include "complexobject.h" +#include "mpdecimal.h" + +#include + +#include "docstrings.h" + + #if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02050000 #error "libmpdec version >= 2.5.0 required" -#endif - - -/* - * Type sizes with assertions in mpdecimal.h and pyport.h: - * sizeof(size_t) == sizeof(Py_ssize_t) - * sizeof(size_t) == sizeof(mpd_uint_t) == sizeof(mpd_ssize_t) - */ - -#ifdef TEST_COVERAGE - #undef Py_LOCAL_INLINE - #define Py_LOCAL_INLINE Py_LOCAL -#endif - -#define MPD_Float_operation MPD_Not_implemented - -#define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x - +#endif + + +/* + * Type sizes with assertions in mpdecimal.h and pyport.h: + * sizeof(size_t) == sizeof(Py_ssize_t) + * sizeof(size_t) == sizeof(mpd_uint_t) == sizeof(mpd_ssize_t) + */ + +#ifdef TEST_COVERAGE + #undef Py_LOCAL_INLINE + #define Py_LOCAL_INLINE Py_LOCAL +#endif + +#define MPD_Float_operation MPD_Not_implemented + +#define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x + #if defined(__GNUC__) && !defined(__INTEL_COMPILER) #define UNUSED __attribute__((unused)) #else #define UNUSED #endif - -/* _Py_DEC_MINALLOC >= MPD_MINALLOC */ -#define _Py_DEC_MINALLOC 4 - -typedef struct { - PyObject_HEAD - Py_hash_t hash; - mpd_t dec; - mpd_uint_t data[_Py_DEC_MINALLOC]; -} PyDecObject; - -typedef struct { - PyObject_HEAD - uint32_t *flags; -} PyDecSignalDictObject; - -typedef struct { - PyObject_HEAD - mpd_context_t ctx; - PyObject *traps; - PyObject *flags; - int capitals; - PyThreadState *tstate; -} PyDecContextObject; - -typedef struct { - PyObject_HEAD - PyObject *local; - PyObject *global; -} PyDecContextManagerObject; - - -#undef MPD -#undef CTX -static PyTypeObject PyDec_Type; -static PyTypeObject *PyDecSignalDict_Type; -static PyTypeObject PyDecContext_Type; -static PyTypeObject PyDecContextManager_Type; + +/* _Py_DEC_MINALLOC >= MPD_MINALLOC */ +#define _Py_DEC_MINALLOC 4 + +typedef struct { + PyObject_HEAD + Py_hash_t hash; + mpd_t dec; + mpd_uint_t data[_Py_DEC_MINALLOC]; +} PyDecObject; + +typedef struct { + PyObject_HEAD + uint32_t *flags; +} PyDecSignalDictObject; + +typedef struct { + PyObject_HEAD + mpd_context_t ctx; + PyObject *traps; + PyObject *flags; + int capitals; + PyThreadState *tstate; +} PyDecContextObject; + +typedef struct { + PyObject_HEAD + PyObject *local; + PyObject *global; +} PyDecContextManagerObject; + + +#undef MPD +#undef CTX +static PyTypeObject PyDec_Type; +static PyTypeObject *PyDecSignalDict_Type; +static PyTypeObject PyDecContext_Type; +static PyTypeObject PyDecContextManager_Type; #define PyDec_CheckExact(v) Py_IS_TYPE(v, &PyDec_Type) -#define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type) +#define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type) #define PyDecSignalDict_Check(v) Py_IS_TYPE(v, PyDecSignalDict_Type) -#define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type) -#define MPD(v) (&((PyDecObject *)v)->dec) -#define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags) -#define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags) -#define CTX(v) (&((PyDecContextObject *)v)->ctx) -#define CtxCaps(v) (((PyDecContextObject *)v)->capitals) - - -Py_LOCAL_INLINE(PyObject *) -incr_true(void) -{ - Py_INCREF(Py_True); - return Py_True; -} - -Py_LOCAL_INLINE(PyObject *) -incr_false(void) -{ - Py_INCREF(Py_False); - return Py_False; -} - - +#define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type) +#define MPD(v) (&((PyDecObject *)v)->dec) +#define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags) +#define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags) +#define CTX(v) (&((PyDecContextObject *)v)->ctx) +#define CtxCaps(v) (((PyDecContextObject *)v)->capitals) + + +Py_LOCAL_INLINE(PyObject *) +incr_true(void) +{ + Py_INCREF(Py_True); + return Py_True; +} + +Py_LOCAL_INLINE(PyObject *) +incr_false(void) +{ + Py_INCREF(Py_False); + return Py_False; +} + + #ifndef WITH_DECIMAL_CONTEXTVAR /* Key for thread state dictionary */ static PyObject *tls_context_key = NULL; @@ -133,5797 +133,5797 @@ static PyDecContextObject *cached_context = NULL; #else static PyObject *current_context_var = NULL; #endif - -/* Template for creating new thread contexts, calling Context() without - * arguments and initializing the module_context on first access. */ -static PyObject *default_context_template = NULL; -/* Basic and extended context templates */ -static PyObject *basic_context_template = NULL; -static PyObject *extended_context_template = NULL; - - -/* Error codes for functions that return signals or conditions */ -#define DEC_INVALID_SIGNALS (MPD_Max_status+1U) -#define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1) -#define DEC_ERRORS (DEC_INVALID_SIGNALS|DEC_ERR_OCCURRED) - -typedef struct { - const char *name; /* condition or signal name */ - const char *fqname; /* fully qualified name */ - uint32_t flag; /* libmpdec flag */ - PyObject *ex; /* corresponding exception */ -} DecCondMap; - -/* Top level Exception; inherits from ArithmeticError */ -static PyObject *DecimalException = NULL; - -/* Exceptions that correspond to IEEE signals */ -#define SUBNORMAL 5 -#define INEXACT 6 -#define ROUNDED 7 -#define SIGNAL_MAP_LEN 9 -static DecCondMap signal_map[] = { - {"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL}, - {"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL}, - {"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL}, - {"Overflow", "decimal.Overflow", MPD_Overflow, NULL}, - {"Underflow", "decimal.Underflow", MPD_Underflow, NULL}, - {"Subnormal", "decimal.Subnormal", MPD_Subnormal, NULL}, - {"Inexact", "decimal.Inexact", MPD_Inexact, NULL}, - {"Rounded", "decimal.Rounded", MPD_Rounded, NULL}, - {"Clamped", "decimal.Clamped", MPD_Clamped, NULL}, - {NULL} -}; - -/* Exceptions that inherit from InvalidOperation */ -static DecCondMap cond_map[] = { - {"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL}, - {"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL}, - {"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL}, - {"DivisionUndefined", "decimal.DivisionUndefined", MPD_Division_undefined, NULL}, - {"InvalidContext", "decimal.InvalidContext", MPD_Invalid_context, NULL}, -#ifdef EXTRA_FUNCTIONALITY - {"MallocError", "decimal.MallocError", MPD_Malloc_error, NULL}, -#endif - {NULL} -}; - -static const char *dec_signal_string[MPD_NUM_FLAGS] = { - "Clamped", - "InvalidOperation", - "DivisionByZero", - "InvalidOperation", - "InvalidOperation", - "InvalidOperation", - "Inexact", - "InvalidOperation", - "InvalidOperation", - "InvalidOperation", - "FloatOperation", - "Overflow", - "Rounded", - "Subnormal", - "Underflow", -}; - -#ifdef EXTRA_FUNCTIONALITY - #define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD -#else - #define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1) -#endif -static PyObject *round_map[_PY_DEC_ROUND_GUARD]; - -static const char *invalid_rounding_err = -"valid values for rounding are:\n\ - [ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\ - ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,\n\ - ROUND_05UP]"; - -static const char *invalid_signals_err = -"valid values for signals are:\n\ - [InvalidOperation, FloatOperation, DivisionByZero,\n\ - Overflow, Underflow, Subnormal, Inexact, Rounded,\n\ - Clamped]"; - -#ifdef EXTRA_FUNCTIONALITY -static const char *invalid_flags_err = -"valid values for _flags or _traps are:\n\ - signals:\n\ - [DecIEEEInvalidOperation, DecFloatOperation, DecDivisionByZero,\n\ - DecOverflow, DecUnderflow, DecSubnormal, DecInexact, DecRounded,\n\ - DecClamped]\n\ - conditions which trigger DecIEEEInvalidOperation:\n\ - [DecInvalidOperation, DecConversionSyntax, DecDivisionImpossible,\n\ - DecDivisionUndefined, DecFpuError, DecInvalidContext, DecMallocError]"; -#endif - -static int -value_error_int(const char *mesg) -{ - PyErr_SetString(PyExc_ValueError, mesg); - return -1; -} - -#ifdef CONFIG_32 -static PyObject * -value_error_ptr(const char *mesg) -{ - PyErr_SetString(PyExc_ValueError, mesg); - return NULL; -} -#endif - -static int -type_error_int(const char *mesg) -{ - PyErr_SetString(PyExc_TypeError, mesg); - return -1; -} - -static int -runtime_error_int(const char *mesg) -{ - PyErr_SetString(PyExc_RuntimeError, mesg); - return -1; -} -#define INTERNAL_ERROR_INT(funcname) \ - return runtime_error_int("internal error in " funcname) - -static PyObject * -runtime_error_ptr(const char *mesg) -{ - PyErr_SetString(PyExc_RuntimeError, mesg); - return NULL; -} -#define INTERNAL_ERROR_PTR(funcname) \ - return runtime_error_ptr("internal error in " funcname) - -static void -dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */ -{ /* GCOV_NOT_REACHED */ - return; /* GCOV_NOT_REACHED */ -} - -static PyObject * -flags_as_exception(uint32_t flags) -{ - DecCondMap *cm; - - for (cm = signal_map; cm->name != NULL; cm++) { - if (flags&cm->flag) { - return cm->ex; - } - } - - INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */ -} - -Py_LOCAL_INLINE(uint32_t) -exception_as_flag(PyObject *ex) -{ - DecCondMap *cm; - - for (cm = signal_map; cm->name != NULL; cm++) { - if (cm->ex == ex) { - return cm->flag; - } + +/* Template for creating new thread contexts, calling Context() without + * arguments and initializing the module_context on first access. */ +static PyObject *default_context_template = NULL; +/* Basic and extended context templates */ +static PyObject *basic_context_template = NULL; +static PyObject *extended_context_template = NULL; + + +/* Error codes for functions that return signals or conditions */ +#define DEC_INVALID_SIGNALS (MPD_Max_status+1U) +#define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1) +#define DEC_ERRORS (DEC_INVALID_SIGNALS|DEC_ERR_OCCURRED) + +typedef struct { + const char *name; /* condition or signal name */ + const char *fqname; /* fully qualified name */ + uint32_t flag; /* libmpdec flag */ + PyObject *ex; /* corresponding exception */ +} DecCondMap; + +/* Top level Exception; inherits from ArithmeticError */ +static PyObject *DecimalException = NULL; + +/* Exceptions that correspond to IEEE signals */ +#define SUBNORMAL 5 +#define INEXACT 6 +#define ROUNDED 7 +#define SIGNAL_MAP_LEN 9 +static DecCondMap signal_map[] = { + {"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL}, + {"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL}, + {"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL}, + {"Overflow", "decimal.Overflow", MPD_Overflow, NULL}, + {"Underflow", "decimal.Underflow", MPD_Underflow, NULL}, + {"Subnormal", "decimal.Subnormal", MPD_Subnormal, NULL}, + {"Inexact", "decimal.Inexact", MPD_Inexact, NULL}, + {"Rounded", "decimal.Rounded", MPD_Rounded, NULL}, + {"Clamped", "decimal.Clamped", MPD_Clamped, NULL}, + {NULL} +}; + +/* Exceptions that inherit from InvalidOperation */ +static DecCondMap cond_map[] = { + {"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL}, + {"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL}, + {"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL}, + {"DivisionUndefined", "decimal.DivisionUndefined", MPD_Division_undefined, NULL}, + {"InvalidContext", "decimal.InvalidContext", MPD_Invalid_context, NULL}, +#ifdef EXTRA_FUNCTIONALITY + {"MallocError", "decimal.MallocError", MPD_Malloc_error, NULL}, +#endif + {NULL} +}; + +static const char *dec_signal_string[MPD_NUM_FLAGS] = { + "Clamped", + "InvalidOperation", + "DivisionByZero", + "InvalidOperation", + "InvalidOperation", + "InvalidOperation", + "Inexact", + "InvalidOperation", + "InvalidOperation", + "InvalidOperation", + "FloatOperation", + "Overflow", + "Rounded", + "Subnormal", + "Underflow", +}; + +#ifdef EXTRA_FUNCTIONALITY + #define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD +#else + #define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1) +#endif +static PyObject *round_map[_PY_DEC_ROUND_GUARD]; + +static const char *invalid_rounding_err = +"valid values for rounding are:\n\ + [ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\ + ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,\n\ + ROUND_05UP]"; + +static const char *invalid_signals_err = +"valid values for signals are:\n\ + [InvalidOperation, FloatOperation, DivisionByZero,\n\ + Overflow, Underflow, Subnormal, Inexact, Rounded,\n\ + Clamped]"; + +#ifdef EXTRA_FUNCTIONALITY +static const char *invalid_flags_err = +"valid values for _flags or _traps are:\n\ + signals:\n\ + [DecIEEEInvalidOperation, DecFloatOperation, DecDivisionByZero,\n\ + DecOverflow, DecUnderflow, DecSubnormal, DecInexact, DecRounded,\n\ + DecClamped]\n\ + conditions which trigger DecIEEEInvalidOperation:\n\ + [DecInvalidOperation, DecConversionSyntax, DecDivisionImpossible,\n\ + DecDivisionUndefined, DecFpuError, DecInvalidContext, DecMallocError]"; +#endif + +static int +value_error_int(const char *mesg) +{ + PyErr_SetString(PyExc_ValueError, mesg); + return -1; +} + +#ifdef CONFIG_32 +static PyObject * +value_error_ptr(const char *mesg) +{ + PyErr_SetString(PyExc_ValueError, mesg); + return NULL; +} +#endif + +static int +type_error_int(const char *mesg) +{ + PyErr_SetString(PyExc_TypeError, mesg); + return -1; +} + +static int +runtime_error_int(const char *mesg) +{ + PyErr_SetString(PyExc_RuntimeError, mesg); + return -1; +} +#define INTERNAL_ERROR_INT(funcname) \ + return runtime_error_int("internal error in " funcname) + +static PyObject * +runtime_error_ptr(const char *mesg) +{ + PyErr_SetString(PyExc_RuntimeError, mesg); + return NULL; +} +#define INTERNAL_ERROR_PTR(funcname) \ + return runtime_error_ptr("internal error in " funcname) + +static void +dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */ +{ /* GCOV_NOT_REACHED */ + return; /* GCOV_NOT_REACHED */ +} + +static PyObject * +flags_as_exception(uint32_t flags) +{ + DecCondMap *cm; + + for (cm = signal_map; cm->name != NULL; cm++) { + if (flags&cm->flag) { + return cm->ex; + } + } + + INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */ +} + +Py_LOCAL_INLINE(uint32_t) +exception_as_flag(PyObject *ex) +{ + DecCondMap *cm; + + for (cm = signal_map; cm->name != NULL; cm++) { + if (cm->ex == ex) { + return cm->flag; + } + } + + PyErr_SetString(PyExc_KeyError, invalid_signals_err); + return DEC_INVALID_SIGNALS; +} + +static PyObject * +flags_as_list(uint32_t flags) +{ + PyObject *list; + DecCondMap *cm; + + list = PyList_New(0); + if (list == NULL) { + return NULL; + } + + for (cm = cond_map; cm->name != NULL; cm++) { + if (flags&cm->flag) { + if (PyList_Append(list, cm->ex) < 0) { + goto error; + } + } + } + for (cm = signal_map+1; cm->name != NULL; cm++) { + if (flags&cm->flag) { + if (PyList_Append(list, cm->ex) < 0) { + goto error; + } + } + } + + return list; + +error: + Py_DECREF(list); + return NULL; +} + +static PyObject * +signals_as_list(uint32_t flags) +{ + PyObject *list; + DecCondMap *cm; + + list = PyList_New(0); + if (list == NULL) { + return NULL; + } + + for (cm = signal_map; cm->name != NULL; cm++) { + if (flags&cm->flag) { + if (PyList_Append(list, cm->ex) < 0) { + Py_DECREF(list); + return NULL; + } + } + } + + return list; +} + +static uint32_t +list_as_flags(PyObject *list) +{ + PyObject *item; + uint32_t flags, x; + Py_ssize_t n, j; + + assert(PyList_Check(list)); + + n = PyList_Size(list); + flags = 0; + for (j = 0; j < n; j++) { + item = PyList_GetItem(list, j); + x = exception_as_flag(item); + if (x & DEC_ERRORS) { + return x; + } + flags |= x; + } + + return flags; +} + +static PyObject * +flags_as_dict(uint32_t flags) +{ + DecCondMap *cm; + PyObject *dict; + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + + for (cm = signal_map; cm->name != NULL; cm++) { + PyObject *b = flags&cm->flag ? Py_True : Py_False; + if (PyDict_SetItem(dict, cm->ex, b) < 0) { + Py_DECREF(dict); + return NULL; + } + } + + return dict; +} + +static uint32_t +dict_as_flags(PyObject *val) +{ + PyObject *b; + DecCondMap *cm; + uint32_t flags = 0; + int x; + + if (!PyDict_Check(val)) { + PyErr_SetString(PyExc_TypeError, + "argument must be a signal dict"); + return DEC_INVALID_SIGNALS; + } + + if (PyDict_Size(val) != SIGNAL_MAP_LEN) { + PyErr_SetString(PyExc_KeyError, + "invalid signal dict"); + return DEC_INVALID_SIGNALS; + } + + for (cm = signal_map; cm->name != NULL; cm++) { + b = PyDict_GetItemWithError(val, cm->ex); + if (b == NULL) { + if (PyErr_Occurred()) { + return DEC_ERR_OCCURRED; + } + PyErr_SetString(PyExc_KeyError, + "invalid signal dict"); + return DEC_INVALID_SIGNALS; + } + + x = PyObject_IsTrue(b); + if (x < 0) { + return DEC_ERR_OCCURRED; + } + if (x == 1) { + flags |= cm->flag; + } + } + + return flags; +} + +#ifdef EXTRA_FUNCTIONALITY +static uint32_t +long_as_flags(PyObject *v) +{ + long x; + + x = PyLong_AsLong(v); + if (x == -1 && PyErr_Occurred()) { + return DEC_ERR_OCCURRED; + } + if (x < 0 || x > (long)MPD_Max_status) { + PyErr_SetString(PyExc_TypeError, invalid_flags_err); + return DEC_INVALID_SIGNALS; + } + + return x; +} +#endif + +static int +dec_addstatus(PyObject *context, uint32_t status) +{ + mpd_context_t *ctx = CTX(context); + + ctx->status |= status; + if (status & (ctx->traps|MPD_Malloc_error)) { + PyObject *ex, *siglist; + + if (status & MPD_Malloc_error) { + PyErr_NoMemory(); + return 1; + } + + ex = flags_as_exception(ctx->traps&status); + if (ex == NULL) { + return 1; /* GCOV_NOT_REACHED */ + } + siglist = flags_as_list(ctx->traps&status); + if (siglist == NULL) { + return 1; + } + + PyErr_SetObject(ex, siglist); + Py_DECREF(siglist); + return 1; + } + return 0; +} + +static int +getround(PyObject *v) +{ + int i; + + if (PyUnicode_Check(v)) { + for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { + if (v == round_map[i]) { + return i; + } + } + for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { + if (PyUnicode_Compare(v, round_map[i]) == 0) { + return i; + } + } + } + + return type_error_int(invalid_rounding_err); +} + + +/******************************************************************************/ +/* SignalDict Object */ +/******************************************************************************/ + +/* The SignalDict is a MutableMapping that provides access to the + mpd_context_t flags, which reside in the context object. When a + new context is created, context.traps and context.flags are + initialized to new SignalDicts. Once a SignalDict is tied to + a context, it cannot be deleted. */ + +static int +signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED) +{ + SdFlagAddr(self) = NULL; + return 0; +} + +static Py_ssize_t +signaldict_len(PyObject *self UNUSED) +{ + return SIGNAL_MAP_LEN; +} + +static PyObject *SignalTuple; +static PyObject * +signaldict_iter(PyObject *self UNUSED) +{ + return PyTuple_Type.tp_iter(SignalTuple); +} + +static PyObject * +signaldict_getitem(PyObject *self, PyObject *key) +{ + uint32_t flag; + + flag = exception_as_flag(key); + if (flag & DEC_ERRORS) { + return NULL; + } + + return SdFlags(self)&flag ? incr_true() : incr_false(); +} + +static int +signaldict_setitem(PyObject *self, PyObject *key, PyObject *value) +{ + uint32_t flag; + int x; + + if (value == NULL) { + return value_error_int("signal keys cannot be deleted"); + } + + flag = exception_as_flag(key); + if (flag & DEC_ERRORS) { + return -1; + } + + x = PyObject_IsTrue(value); + if (x < 0) { + return -1; + } + + if (x == 1) { + SdFlags(self) |= flag; + } + else { + SdFlags(self) &= ~flag; + } + + return 0; +} + +static PyObject * +signaldict_repr(PyObject *self) +{ + DecCondMap *cm; + const char *n[SIGNAL_MAP_LEN]; /* name */ + const char *b[SIGNAL_MAP_LEN]; /* bool */ + int i; + + assert(SIGNAL_MAP_LEN == 9); + + for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) { + n[i] = cm->fqname; + b[i] = SdFlags(self)&cm->flag ? "True" : "False"; + } + return PyUnicode_FromFormat( + "{:%s, :%s, :%s, " + ":%s, :%s, :%s, " + ":%s, :%s, :%s}", + n[0], b[0], n[1], b[1], n[2], b[2], + n[3], b[3], n[4], b[4], n[5], b[5], + n[6], b[6], n[7], b[7], n[8], b[8]); +} + +static PyObject * +signaldict_richcompare(PyObject *v, PyObject *w, int op) +{ + PyObject *res = Py_NotImplemented; + + assert(PyDecSignalDict_Check(v)); + + if (op == Py_EQ || op == Py_NE) { + if (PyDecSignalDict_Check(w)) { + res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False; + } + else if (PyDict_Check(w)) { + uint32_t flags = dict_as_flags(w); + if (flags & DEC_ERRORS) { + if (flags & DEC_INVALID_SIGNALS) { + /* non-comparable: Py_NotImplemented */ + PyErr_Clear(); + } + else { + return NULL; + } + } + else { + res = (SdFlags(v)==flags) ^ (op==Py_NE) ? Py_True : Py_False; + } + } + } + + Py_INCREF(res); + return res; +} + +static PyObject * +signaldict_copy(PyObject *self, PyObject *args UNUSED) +{ + return flags_as_dict(SdFlags(self)); +} + + +static PyMappingMethods signaldict_as_mapping = { + (lenfunc)signaldict_len, /* mp_length */ + (binaryfunc)signaldict_getitem, /* mp_subscript */ + (objobjargproc)signaldict_setitem /* mp_ass_subscript */ +}; + +static PyMethodDef signaldict_methods[] = { + { "copy", (PyCFunction)signaldict_copy, METH_NOARGS, NULL}, + {NULL, NULL} +}; + + +static PyTypeObject PyDecSignalDictMixin_Type = +{ + PyVarObject_HEAD_INIT(0, 0) + "decimal.SignalDictMixin", /* tp_name */ + sizeof(PyDecSignalDictObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + (getattrfunc) 0, /* tp_getattr */ + (setattrfunc) 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc) signaldict_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + &signaldict_as_mapping, /* tp_as_mapping */ + PyObject_HashNotImplemented, /* tp_hash */ + 0, /* tp_call */ + (reprfunc) 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + (setattrofunc) 0, /* tp_setattro */ + (PyBufferProcs *) 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + signaldict_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)signaldict_iter, /* tp_iter */ + 0, /* tp_iternext */ + signaldict_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)signaldict_init, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + + +/******************************************************************************/ +/* Context Object, Part 1 */ +/******************************************************************************/ + +#define Dec_CONTEXT_GET_SSIZE(mem) \ +static PyObject * \ +context_get##mem(PyObject *self, void *closure UNUSED) \ +{ \ + return PyLong_FromSsize_t(mpd_get##mem(CTX(self))); \ +} + +#define Dec_CONTEXT_GET_ULONG(mem) \ +static PyObject * \ +context_get##mem(PyObject *self, void *closure UNUSED) \ +{ \ + return PyLong_FromUnsignedLong(mpd_get##mem(CTX(self))); \ +} + +Dec_CONTEXT_GET_SSIZE(prec) +Dec_CONTEXT_GET_SSIZE(emax) +Dec_CONTEXT_GET_SSIZE(emin) +Dec_CONTEXT_GET_SSIZE(clamp) + +#ifdef EXTRA_FUNCTIONALITY +Dec_CONTEXT_GET_ULONG(traps) +Dec_CONTEXT_GET_ULONG(status) +#endif + +static PyObject * +context_getround(PyObject *self, void *closure UNUSED) +{ + int i = mpd_getround(CTX(self)); + + Py_INCREF(round_map[i]); + return round_map[i]; +} + +static PyObject * +context_getcapitals(PyObject *self, void *closure UNUSED) +{ + return PyLong_FromLong(CtxCaps(self)); +} + +#ifdef EXTRA_FUNCTIONALITY +static PyObject * +context_getallcr(PyObject *self, void *closure UNUSED) +{ + return PyLong_FromLong(mpd_getcr(CTX(self))); +} +#endif + +static PyObject * +context_getetiny(PyObject *self, PyObject *dummy UNUSED) +{ + return PyLong_FromSsize_t(mpd_etiny(CTX(self))); +} + +static PyObject * +context_getetop(PyObject *self, PyObject *dummy UNUSED) +{ + return PyLong_FromSsize_t(mpd_etop(CTX(self))); +} + +static int +context_setprec(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_context_t *ctx; + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return -1; + } + + ctx = CTX(self); + if (!mpd_qsetprec(ctx, x)) { + return value_error_int( + "valid range for prec is [1, MAX_PREC]"); + } + + return 0; +} + +static int +context_setemin(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_context_t *ctx; + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return -1; + } + + ctx = CTX(self); + if (!mpd_qsetemin(ctx, x)) { + return value_error_int( + "valid range for Emin is [MIN_EMIN, 0]"); + } + + return 0; +} + +static int +context_setemax(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_context_t *ctx; + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return -1; + } + + ctx = CTX(self); + if (!mpd_qsetemax(ctx, x)) { + return value_error_int( + "valid range for Emax is [0, MAX_EMAX]"); + } + + return 0; +} + +#ifdef CONFIG_32 +static PyObject * +context_unsafe_setprec(PyObject *self, PyObject *value) +{ + mpd_context_t *ctx = CTX(self); + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return NULL; + } + + if (x < 1 || x > 1070000000L) { + return value_error_ptr( + "valid range for unsafe prec is [1, 1070000000]"); + } + + ctx->prec = x; + Py_RETURN_NONE; +} + +static PyObject * +context_unsafe_setemin(PyObject *self, PyObject *value) +{ + mpd_context_t *ctx = CTX(self); + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return NULL; + } + + if (x < -1070000000L || x > 0) { + return value_error_ptr( + "valid range for unsafe emin is [-1070000000, 0]"); + } + + ctx->emin = x; + Py_RETURN_NONE; +} + +static PyObject * +context_unsafe_setemax(PyObject *self, PyObject *value) +{ + mpd_context_t *ctx = CTX(self); + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return NULL; + } + + if (x < 0 || x > 1070000000L) { + return value_error_ptr( + "valid range for unsafe emax is [0, 1070000000]"); + } + + ctx->emax = x; + Py_RETURN_NONE; +} +#endif + +static int +context_setround(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_context_t *ctx; + int x; + + x = getround(value); + if (x == -1) { + return -1; + } + + ctx = CTX(self); + if (!mpd_qsetround(ctx, x)) { + INTERNAL_ERROR_INT("context_setround"); /* GCOV_NOT_REACHED */ + } + + return 0; +} + +static int +context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return -1; + } + + if (x != 0 && x != 1) { + return value_error_int( + "valid values for capitals are 0 or 1"); + } + CtxCaps(self) = (int)x; + + return 0; +} + +#ifdef EXTRA_FUNCTIONALITY +static int +context_settraps(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_context_t *ctx; + uint32_t flags; + + flags = long_as_flags(value); + if (flags & DEC_ERRORS) { + return -1; + } + + ctx = CTX(self); + if (!mpd_qsettraps(ctx, flags)) { + INTERNAL_ERROR_INT("context_settraps"); + } + + return 0; +} +#endif + +static int +context_settraps_list(PyObject *self, PyObject *value) +{ + mpd_context_t *ctx; + uint32_t flags; + + flags = list_as_flags(value); + if (flags & DEC_ERRORS) { + return -1; + } + + ctx = CTX(self); + if (!mpd_qsettraps(ctx, flags)) { + INTERNAL_ERROR_INT("context_settraps_list"); + } + + return 0; +} + +static int +context_settraps_dict(PyObject *self, PyObject *value) +{ + mpd_context_t *ctx; + uint32_t flags; + + if (PyDecSignalDict_Check(value)) { + flags = SdFlags(value); + } + else { + flags = dict_as_flags(value); + if (flags & DEC_ERRORS) { + return -1; + } + } + + ctx = CTX(self); + if (!mpd_qsettraps(ctx, flags)) { + INTERNAL_ERROR_INT("context_settraps_dict"); + } + + return 0; +} + +#ifdef EXTRA_FUNCTIONALITY +static int +context_setstatus(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_context_t *ctx; + uint32_t flags; + + flags = long_as_flags(value); + if (flags & DEC_ERRORS) { + return -1; + } + + ctx = CTX(self); + if (!mpd_qsetstatus(ctx, flags)) { + INTERNAL_ERROR_INT("context_setstatus"); + } + + return 0; +} +#endif + +static int +context_setstatus_list(PyObject *self, PyObject *value) +{ + mpd_context_t *ctx; + uint32_t flags; + + flags = list_as_flags(value); + if (flags & DEC_ERRORS) { + return -1; + } + + ctx = CTX(self); + if (!mpd_qsetstatus(ctx, flags)) { + INTERNAL_ERROR_INT("context_setstatus_list"); + } + + return 0; +} + +static int +context_setstatus_dict(PyObject *self, PyObject *value) +{ + mpd_context_t *ctx; + uint32_t flags; + + if (PyDecSignalDict_Check(value)) { + flags = SdFlags(value); + } + else { + flags = dict_as_flags(value); + if (flags & DEC_ERRORS) { + return -1; + } + } + + ctx = CTX(self); + if (!mpd_qsetstatus(ctx, flags)) { + INTERNAL_ERROR_INT("context_setstatus_dict"); + } + + return 0; +} + +static int +context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_context_t *ctx; + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return -1; + } + BOUNDS_CHECK(x, INT_MIN, INT_MAX); + + ctx = CTX(self); + if (!mpd_qsetclamp(ctx, (int)x)) { + return value_error_int("valid values for clamp are 0 or 1"); + } + + return 0; +} + +#ifdef EXTRA_FUNCTIONALITY +static int +context_setallcr(PyObject *self, PyObject *value, void *closure UNUSED) +{ + mpd_context_t *ctx; + mpd_ssize_t x; + + x = PyLong_AsSsize_t(value); + if (x == -1 && PyErr_Occurred()) { + return -1; + } + BOUNDS_CHECK(x, INT_MIN, INT_MAX); + + ctx = CTX(self); + if (!mpd_qsetcr(ctx, (int)x)) { + return value_error_int("valid values for _allcr are 0 or 1"); + } + + return 0; +} +#endif + +static PyObject * +context_getattr(PyObject *self, PyObject *name) +{ + PyObject *retval; + + if (PyUnicode_Check(name)) { + if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { + retval = ((PyDecContextObject *)self)->traps; + Py_INCREF(retval); + return retval; + } + if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { + retval = ((PyDecContextObject *)self)->flags; + Py_INCREF(retval); + return retval; + } + } + + return PyObject_GenericGetAttr(self, name); +} + +static int +context_setattr(PyObject *self, PyObject *name, PyObject *value) +{ + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, + "context attributes cannot be deleted"); + return -1; + } + + if (PyUnicode_Check(name)) { + if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { + return context_settraps_dict(self, value); + } + if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { + return context_setstatus_dict(self, value); + } + } + + return PyObject_GenericSetAttr(self, name, value); +} + +static PyObject * +context_clear_traps(PyObject *self, PyObject *dummy UNUSED) +{ + CTX(self)->traps = 0; + Py_RETURN_NONE; +} + +static PyObject * +context_clear_flags(PyObject *self, PyObject *dummy UNUSED) +{ + CTX(self)->status = 0; + Py_RETURN_NONE; +} + +#define DEC_DFLT_EMAX 999999 +#define DEC_DFLT_EMIN -999999 + +static mpd_context_t dflt_ctx = { + 28, DEC_DFLT_EMAX, DEC_DFLT_EMIN, + MPD_IEEE_Invalid_operation|MPD_Division_by_zero|MPD_Overflow, + 0, 0, MPD_ROUND_HALF_EVEN, 0, 1 +}; + +static PyObject * +context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED) +{ + PyDecContextObject *self = NULL; + mpd_context_t *ctx; + + if (type == &PyDecContext_Type) { + self = PyObject_New(PyDecContextObject, &PyDecContext_Type); + } + else { + self = (PyDecContextObject *)type->tp_alloc(type, 0); + } + + if (self == NULL) { + return NULL; + } + + self->traps = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL); + if (self->traps == NULL) { + self->flags = NULL; + Py_DECREF(self); + return NULL; + } + self->flags = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL); + if (self->flags == NULL) { + Py_DECREF(self); + return NULL; + } + + ctx = CTX(self); + + if (default_context_template) { + *ctx = *CTX(default_context_template); + } + else { + *ctx = dflt_ctx; + } + + SdFlagAddr(self->traps) = &ctx->traps; + SdFlagAddr(self->flags) = &ctx->status; + + CtxCaps(self) = 1; + self->tstate = NULL; + + return (PyObject *)self; +} + +static void +context_dealloc(PyDecContextObject *self) +{ +#ifndef WITH_DECIMAL_CONTEXTVAR + if (self == cached_context) { + cached_context = NULL; } +#endif - PyErr_SetString(PyExc_KeyError, invalid_signals_err); - return DEC_INVALID_SIGNALS; -} - -static PyObject * -flags_as_list(uint32_t flags) + Py_XDECREF(self->traps); + Py_XDECREF(self->flags); + Py_TYPE(self)->tp_free(self); +} + +static int +context_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = { + "prec", "rounding", "Emin", "Emax", "capitals", "clamp", + "flags", "traps", NULL + }; + PyObject *prec = Py_None; + PyObject *rounding = Py_None; + PyObject *emin = Py_None; + PyObject *emax = Py_None; + PyObject *capitals = Py_None; + PyObject *clamp = Py_None; + PyObject *status = Py_None; + PyObject *traps = Py_None; + int ret; + + assert(PyTuple_Check(args)); + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, + "|OOOOOOOO", kwlist, + &prec, &rounding, &emin, &emax, &capitals, &clamp, &status, &traps + )) { + return -1; + } + + if (prec != Py_None && context_setprec(self, prec, NULL) < 0) { + return -1; + } + if (rounding != Py_None && context_setround(self, rounding, NULL) < 0) { + return -1; + } + if (emin != Py_None && context_setemin(self, emin, NULL) < 0) { + return -1; + } + if (emax != Py_None && context_setemax(self, emax, NULL) < 0) { + return -1; + } + if (capitals != Py_None && context_setcapitals(self, capitals, NULL) < 0) { + return -1; + } + if (clamp != Py_None && context_setclamp(self, clamp, NULL) < 0) { + return -1; + } + + if (traps != Py_None) { + if (PyList_Check(traps)) { + ret = context_settraps_list(self, traps); + } +#ifdef EXTRA_FUNCTIONALITY + else if (PyLong_Check(traps)) { + ret = context_settraps(self, traps, NULL); + } +#endif + else { + ret = context_settraps_dict(self, traps); + } + if (ret < 0) { + return ret; + } + } + if (status != Py_None) { + if (PyList_Check(status)) { + ret = context_setstatus_list(self, status); + } +#ifdef EXTRA_FUNCTIONALITY + else if (PyLong_Check(status)) { + ret = context_setstatus(self, status, NULL); + } +#endif + else { + ret = context_setstatus_dict(self, status); + } + if (ret < 0) { + return ret; + } + } + + return 0; +} + +static PyObject * +context_repr(PyDecContextObject *self) +{ + mpd_context_t *ctx; + char flags[MPD_MAX_SIGNAL_LIST]; + char traps[MPD_MAX_SIGNAL_LIST]; + int n, mem; + + assert(PyDecContext_Check(self)); + ctx = CTX(self); + + mem = MPD_MAX_SIGNAL_LIST; + n = mpd_lsnprint_signals(flags, mem, ctx->status, dec_signal_string); + if (n < 0 || n >= mem) { + INTERNAL_ERROR_PTR("context_repr"); + } + + n = mpd_lsnprint_signals(traps, mem, ctx->traps, dec_signal_string); + if (n < 0 || n >= mem) { + INTERNAL_ERROR_PTR("context_repr"); + } + + return PyUnicode_FromFormat( + "Context(prec=%zd, rounding=%s, Emin=%zd, Emax=%zd, " + "capitals=%d, clamp=%d, flags=%s, traps=%s)", + ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax, + self->capitals, ctx->clamp, flags, traps); +} + +static void +init_basic_context(PyObject *v) +{ + mpd_context_t ctx = dflt_ctx; + + ctx.prec = 9; + ctx.traps |= (MPD_Underflow|MPD_Clamped); + ctx.round = MPD_ROUND_HALF_UP; + + *CTX(v) = ctx; + CtxCaps(v) = 1; +} + +static void +init_extended_context(PyObject *v) +{ + mpd_context_t ctx = dflt_ctx; + + ctx.prec = 9; + ctx.traps = 0; + + *CTX(v) = ctx; + CtxCaps(v) = 1; +} + +#ifdef EXTRA_FUNCTIONALITY +/* Factory function for creating IEEE interchange format contexts */ +static PyObject * +ieee_context(PyObject *dummy UNUSED, PyObject *v) +{ + PyObject *context; + mpd_ssize_t bits; + mpd_context_t ctx; + + bits = PyLong_AsSsize_t(v); + if (bits == -1 && PyErr_Occurred()) { + return NULL; + } + if (bits <= 0 || bits > INT_MAX) { + goto error; + } + if (mpd_ieee_context(&ctx, (int)bits) < 0) { + goto error; + } + + context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); + if (context == NULL) { + return NULL; + } + *CTX(context) = ctx; + + return context; + +error: + PyErr_Format(PyExc_ValueError, + "argument must be a multiple of 32, with a maximum of %d", + MPD_IEEE_CONTEXT_MAX_BITS); + + return NULL; +} +#endif + +static PyObject * +context_copy(PyObject *self, PyObject *args UNUSED) +{ + PyObject *copy; + + copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); + if (copy == NULL) { + return NULL; + } + + *CTX(copy) = *CTX(self); + CTX(copy)->newtrap = 0; + CtxCaps(copy) = CtxCaps(self); + + return copy; +} + +static PyObject * +context_reduce(PyObject *self, PyObject *args UNUSED) +{ + PyObject *flags; + PyObject *traps; + PyObject *ret; + mpd_context_t *ctx; + + ctx = CTX(self); + + flags = signals_as_list(ctx->status); + if (flags == NULL) { + return NULL; + } + traps = signals_as_list(ctx->traps); + if (traps == NULL) { + Py_DECREF(flags); + return NULL; + } + + ret = Py_BuildValue( + "O(nsnniiOO)", + Py_TYPE(self), + ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax, + CtxCaps(self), ctx->clamp, flags, traps + ); + + Py_DECREF(flags); + Py_DECREF(traps); + return ret; +} + + +static PyGetSetDef context_getsets [] = +{ + { "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL}, + { "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL}, + { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL}, + { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL}, + { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL}, + { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL}, +#ifdef EXTRA_FUNCTIONALITY + { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL}, + { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL}, + { "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL}, +#endif + {NULL} +}; + + +#define CONTEXT_CHECK(obj) \ + if (!PyDecContext_Check(obj)) { \ + PyErr_SetString(PyExc_TypeError, \ + "argument must be a context"); \ + return NULL; \ + } + +#define CONTEXT_CHECK_VA(obj) \ + if (obj == Py_None) { \ + CURRENT_CONTEXT(obj); \ + } \ + else if (!PyDecContext_Check(obj)) { \ + PyErr_SetString(PyExc_TypeError, \ + "optional argument must be a context"); \ + return NULL; \ + } + + +/******************************************************************************/ +/* Global, thread local and temporary contexts */ +/******************************************************************************/ + +/* + * Thread local storage currently has a speed penalty of about 4%. + * All functions that map Python's arithmetic operators to mpdecimal + * functions have to look up the current context for each and every + * operation. + */ + +#ifndef WITH_DECIMAL_CONTEXTVAR +/* Get the context from the thread state dictionary. */ +static PyObject * +current_context_from_dict(void) { - PyObject *list; - DecCondMap *cm; + PyObject *dict; + PyObject *tl_context; + PyThreadState *tstate; - list = PyList_New(0); - if (list == NULL) { + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); return NULL; } - for (cm = cond_map; cm->name != NULL; cm++) { - if (flags&cm->flag) { - if (PyList_Append(list, cm->ex) < 0) { - goto error; - } - } - } - for (cm = signal_map+1; cm->name != NULL; cm++) { - if (flags&cm->flag) { - if (PyList_Append(list, cm->ex) < 0) { - goto error; - } - } - } - - return list; - -error: - Py_DECREF(list); - return NULL; -} - -static PyObject * -signals_as_list(uint32_t flags) -{ - PyObject *list; - DecCondMap *cm; - - list = PyList_New(0); - if (list == NULL) { - return NULL; + tl_context = PyDict_GetItemWithError(dict, tls_context_key); + if (tl_context != NULL) { + /* We already have a thread local context. */ + CONTEXT_CHECK(tl_context); } - - for (cm = signal_map; cm->name != NULL; cm++) { - if (flags&cm->flag) { - if (PyList_Append(list, cm->ex) < 0) { - Py_DECREF(list); - return NULL; - } + else { + if (PyErr_Occurred()) { + return NULL; } - } - - return list; -} -static uint32_t -list_as_flags(PyObject *list) -{ - PyObject *item; - uint32_t flags, x; - Py_ssize_t n, j; - - assert(PyList_Check(list)); - - n = PyList_Size(list); - flags = 0; - for (j = 0; j < n; j++) { - item = PyList_GetItem(list, j); - x = exception_as_flag(item); - if (x & DEC_ERRORS) { - return x; + /* Set up a new thread local context. */ + tl_context = context_copy(default_context_template, NULL); + if (tl_context == NULL) { + return NULL; } - flags |= x; - } - - return flags; -} - -static PyObject * -flags_as_dict(uint32_t flags) -{ - DecCondMap *cm; - PyObject *dict; - - dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } + CTX(tl_context)->status = 0; - for (cm = signal_map; cm->name != NULL; cm++) { - PyObject *b = flags&cm->flag ? Py_True : Py_False; - if (PyDict_SetItem(dict, cm->ex, b) < 0) { - Py_DECREF(dict); + if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) { + Py_DECREF(tl_context); return NULL; } + Py_DECREF(tl_context); } - return dict; -} - -static uint32_t -dict_as_flags(PyObject *val) -{ - PyObject *b; - DecCondMap *cm; - uint32_t flags = 0; - int x; - - if (!PyDict_Check(val)) { - PyErr_SetString(PyExc_TypeError, - "argument must be a signal dict"); - return DEC_INVALID_SIGNALS; - } - - if (PyDict_Size(val) != SIGNAL_MAP_LEN) { - PyErr_SetString(PyExc_KeyError, - "invalid signal dict"); - return DEC_INVALID_SIGNALS; - } - - for (cm = signal_map; cm->name != NULL; cm++) { - b = PyDict_GetItemWithError(val, cm->ex); - if (b == NULL) { - if (PyErr_Occurred()) { - return DEC_ERR_OCCURRED; - } - PyErr_SetString(PyExc_KeyError, - "invalid signal dict"); - return DEC_INVALID_SIGNALS; - } - - x = PyObject_IsTrue(b); - if (x < 0) { - return DEC_ERR_OCCURRED; - } - if (x == 1) { - flags |= cm->flag; - } + /* Cache the context of the current thread, assuming that it + * will be accessed several times before a thread switch. */ + tstate = PyThreadState_GET(); + if (tstate) { + cached_context = (PyDecContextObject *)tl_context; + cached_context->tstate = tstate; } - return flags; + /* Borrowed reference with refcount==1 */ + return tl_context; } -#ifdef EXTRA_FUNCTIONALITY -static uint32_t -long_as_flags(PyObject *v) +/* Return borrowed reference to thread local context. */ +static PyObject * +current_context(void) { - long x; + PyThreadState *tstate; - x = PyLong_AsLong(v); - if (x == -1 && PyErr_Occurred()) { - return DEC_ERR_OCCURRED; - } - if (x < 0 || x > (long)MPD_Max_status) { - PyErr_SetString(PyExc_TypeError, invalid_flags_err); - return DEC_INVALID_SIGNALS; + tstate = PyThreadState_GET(); + if (cached_context && cached_context->tstate == tstate) { + return (PyObject *)cached_context; } - return x; + return current_context_from_dict(); } -#endif -static int -dec_addstatus(PyObject *context, uint32_t status) -{ - mpd_context_t *ctx = CTX(context); - - ctx->status |= status; - if (status & (ctx->traps|MPD_Malloc_error)) { - PyObject *ex, *siglist; - - if (status & MPD_Malloc_error) { - PyErr_NoMemory(); - return 1; - } - - ex = flags_as_exception(ctx->traps&status); - if (ex == NULL) { - return 1; /* GCOV_NOT_REACHED */ - } - siglist = flags_as_list(ctx->traps&status); - if (siglist == NULL) { - return 1; - } - - PyErr_SetObject(ex, siglist); - Py_DECREF(siglist); - return 1; +/* ctxobj := borrowed reference to the current context */ +#define CURRENT_CONTEXT(ctxobj) \ + ctxobj = current_context(); \ + if (ctxobj == NULL) { \ + return NULL; \ } - return 0; -} -static int -getround(PyObject *v) +/* Return a new reference to the current context */ +static PyObject * +PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) { - int i; + PyObject *context; - if (PyUnicode_Check(v)) { - for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { - if (v == round_map[i]) { - return i; - } - } - for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { - if (PyUnicode_Compare(v, round_map[i]) == 0) { - return i; - } - } + context = current_context(); + if (context == NULL) { + return NULL; } - return type_error_int(invalid_rounding_err); -} - - -/******************************************************************************/ -/* SignalDict Object */ -/******************************************************************************/ - -/* The SignalDict is a MutableMapping that provides access to the - mpd_context_t flags, which reside in the context object. When a - new context is created, context.traps and context.flags are - initialized to new SignalDicts. Once a SignalDict is tied to - a context, it cannot be deleted. */ - -static int -signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED) -{ - SdFlagAddr(self) = NULL; - return 0; -} - -static Py_ssize_t -signaldict_len(PyObject *self UNUSED) -{ - return SIGNAL_MAP_LEN; + Py_INCREF(context); + return context; } -static PyObject *SignalTuple; +/* Set the thread local context to a new context, decrement old reference */ static PyObject * -signaldict_iter(PyObject *self UNUSED) +PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) { - return PyTuple_Type.tp_iter(SignalTuple); -} + PyObject *dict; -static PyObject * -signaldict_getitem(PyObject *self, PyObject *key) -{ - uint32_t flag; + CONTEXT_CHECK(v); - flag = exception_as_flag(key); - if (flag & DEC_ERRORS) { + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "cannot get thread state"); return NULL; } - return SdFlags(self)&flag ? incr_true() : incr_false(); -} - -static int -signaldict_setitem(PyObject *self, PyObject *key, PyObject *value) -{ - uint32_t flag; - int x; - - if (value == NULL) { - return value_error_int("signal keys cannot be deleted"); - } - - flag = exception_as_flag(key); - if (flag & DEC_ERRORS) { - return -1; + /* If the new context is one of the templates, make a copy. + * This is the current behavior of decimal.py. */ + if (v == default_context_template || + v == basic_context_template || + v == extended_context_template) { + v = context_copy(v, NULL); + if (v == NULL) { + return NULL; + } + CTX(v)->status = 0; } - - x = PyObject_IsTrue(value); - if (x < 0) { - return -1; + else { + Py_INCREF(v); } - if (x == 1) { - SdFlags(self) |= flag; - } - else { - SdFlags(self) &= ~flag; + cached_context = NULL; + if (PyDict_SetItem(dict, tls_context_key, v) < 0) { + Py_DECREF(v); + return NULL; } - return 0; + Py_DECREF(v); + Py_RETURN_NONE; } - +#else static PyObject * -signaldict_repr(PyObject *self) -{ - DecCondMap *cm; - const char *n[SIGNAL_MAP_LEN]; /* name */ - const char *b[SIGNAL_MAP_LEN]; /* bool */ - int i; - - assert(SIGNAL_MAP_LEN == 9); - - for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) { - n[i] = cm->fqname; - b[i] = SdFlags(self)&cm->flag ? "True" : "False"; - } - return PyUnicode_FromFormat( - "{:%s, :%s, :%s, " - ":%s, :%s, :%s, " - ":%s, :%s, :%s}", - n[0], b[0], n[1], b[1], n[2], b[2], - n[3], b[3], n[4], b[4], n[5], b[5], - n[6], b[6], n[7], b[7], n[8], b[8]); -} - -static PyObject * -signaldict_richcompare(PyObject *v, PyObject *w, int op) -{ - PyObject *res = Py_NotImplemented; - - assert(PyDecSignalDict_Check(v)); - - if (op == Py_EQ || op == Py_NE) { - if (PyDecSignalDict_Check(w)) { - res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False; - } - else if (PyDict_Check(w)) { - uint32_t flags = dict_as_flags(w); - if (flags & DEC_ERRORS) { - if (flags & DEC_INVALID_SIGNALS) { - /* non-comparable: Py_NotImplemented */ - PyErr_Clear(); - } - else { - return NULL; - } - } - else { - res = (SdFlags(v)==flags) ^ (op==Py_NE) ? Py_True : Py_False; - } - } - } - - Py_INCREF(res); - return res; -} - -static PyObject * -signaldict_copy(PyObject *self, PyObject *args UNUSED) -{ - return flags_as_dict(SdFlags(self)); -} - - -static PyMappingMethods signaldict_as_mapping = { - (lenfunc)signaldict_len, /* mp_length */ - (binaryfunc)signaldict_getitem, /* mp_subscript */ - (objobjargproc)signaldict_setitem /* mp_ass_subscript */ -}; - -static PyMethodDef signaldict_methods[] = { - { "copy", (PyCFunction)signaldict_copy, METH_NOARGS, NULL}, - {NULL, NULL} -}; - - -static PyTypeObject PyDecSignalDictMixin_Type = -{ - PyVarObject_HEAD_INIT(0, 0) - "decimal.SignalDictMixin", /* tp_name */ - sizeof(PyDecSignalDictObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - (getattrfunc) 0, /* tp_getattr */ - (setattrfunc) 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc) signaldict_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - &signaldict_as_mapping, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ - 0, /* tp_call */ - (reprfunc) 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - (setattrofunc) 0, /* tp_setattro */ - (PyBufferProcs *) 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - signaldict_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - (getiterfunc)signaldict_iter, /* tp_iter */ - 0, /* tp_iternext */ - signaldict_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)signaldict_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/******************************************************************************/ -/* Context Object, Part 1 */ -/******************************************************************************/ - -#define Dec_CONTEXT_GET_SSIZE(mem) \ -static PyObject * \ -context_get##mem(PyObject *self, void *closure UNUSED) \ -{ \ - return PyLong_FromSsize_t(mpd_get##mem(CTX(self))); \ -} - -#define Dec_CONTEXT_GET_ULONG(mem) \ -static PyObject * \ -context_get##mem(PyObject *self, void *closure UNUSED) \ -{ \ - return PyLong_FromUnsignedLong(mpd_get##mem(CTX(self))); \ -} - -Dec_CONTEXT_GET_SSIZE(prec) -Dec_CONTEXT_GET_SSIZE(emax) -Dec_CONTEXT_GET_SSIZE(emin) -Dec_CONTEXT_GET_SSIZE(clamp) - -#ifdef EXTRA_FUNCTIONALITY -Dec_CONTEXT_GET_ULONG(traps) -Dec_CONTEXT_GET_ULONG(status) -#endif - -static PyObject * -context_getround(PyObject *self, void *closure UNUSED) -{ - int i = mpd_getround(CTX(self)); - - Py_INCREF(round_map[i]); - return round_map[i]; -} - -static PyObject * -context_getcapitals(PyObject *self, void *closure UNUSED) -{ - return PyLong_FromLong(CtxCaps(self)); -} - -#ifdef EXTRA_FUNCTIONALITY -static PyObject * -context_getallcr(PyObject *self, void *closure UNUSED) -{ - return PyLong_FromLong(mpd_getcr(CTX(self))); -} -#endif - -static PyObject * -context_getetiny(PyObject *self, PyObject *dummy UNUSED) -{ - return PyLong_FromSsize_t(mpd_etiny(CTX(self))); -} - -static PyObject * -context_getetop(PyObject *self, PyObject *dummy UNUSED) -{ - return PyLong_FromSsize_t(mpd_etop(CTX(self))); -} - -static int -context_setprec(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_context_t *ctx; - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return -1; - } - - ctx = CTX(self); - if (!mpd_qsetprec(ctx, x)) { - return value_error_int( - "valid range for prec is [1, MAX_PREC]"); - } - - return 0; -} - -static int -context_setemin(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_context_t *ctx; - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return -1; - } - - ctx = CTX(self); - if (!mpd_qsetemin(ctx, x)) { - return value_error_int( - "valid range for Emin is [MIN_EMIN, 0]"); - } - - return 0; -} - -static int -context_setemax(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_context_t *ctx; - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return -1; - } - - ctx = CTX(self); - if (!mpd_qsetemax(ctx, x)) { - return value_error_int( - "valid range for Emax is [0, MAX_EMAX]"); - } - - return 0; -} - -#ifdef CONFIG_32 -static PyObject * -context_unsafe_setprec(PyObject *self, PyObject *value) -{ - mpd_context_t *ctx = CTX(self); - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return NULL; - } - - if (x < 1 || x > 1070000000L) { - return value_error_ptr( - "valid range for unsafe prec is [1, 1070000000]"); - } - - ctx->prec = x; - Py_RETURN_NONE; -} - -static PyObject * -context_unsafe_setemin(PyObject *self, PyObject *value) -{ - mpd_context_t *ctx = CTX(self); - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return NULL; - } - - if (x < -1070000000L || x > 0) { - return value_error_ptr( - "valid range for unsafe emin is [-1070000000, 0]"); - } - - ctx->emin = x; - Py_RETURN_NONE; -} - -static PyObject * -context_unsafe_setemax(PyObject *self, PyObject *value) -{ - mpd_context_t *ctx = CTX(self); - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return NULL; - } - - if (x < 0 || x > 1070000000L) { - return value_error_ptr( - "valid range for unsafe emax is [0, 1070000000]"); - } - - ctx->emax = x; - Py_RETURN_NONE; -} -#endif - -static int -context_setround(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_context_t *ctx; - int x; - - x = getround(value); - if (x == -1) { - return -1; - } - - ctx = CTX(self); - if (!mpd_qsetround(ctx, x)) { - INTERNAL_ERROR_INT("context_setround"); /* GCOV_NOT_REACHED */ - } - - return 0; -} - -static int -context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return -1; - } - - if (x != 0 && x != 1) { - return value_error_int( - "valid values for capitals are 0 or 1"); - } - CtxCaps(self) = (int)x; - - return 0; -} - -#ifdef EXTRA_FUNCTIONALITY -static int -context_settraps(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_context_t *ctx; - uint32_t flags; - - flags = long_as_flags(value); - if (flags & DEC_ERRORS) { - return -1; - } - - ctx = CTX(self); - if (!mpd_qsettraps(ctx, flags)) { - INTERNAL_ERROR_INT("context_settraps"); - } - - return 0; -} -#endif - -static int -context_settraps_list(PyObject *self, PyObject *value) -{ - mpd_context_t *ctx; - uint32_t flags; - - flags = list_as_flags(value); - if (flags & DEC_ERRORS) { - return -1; - } - - ctx = CTX(self); - if (!mpd_qsettraps(ctx, flags)) { - INTERNAL_ERROR_INT("context_settraps_list"); - } - - return 0; -} - -static int -context_settraps_dict(PyObject *self, PyObject *value) -{ - mpd_context_t *ctx; - uint32_t flags; - - if (PyDecSignalDict_Check(value)) { - flags = SdFlags(value); - } - else { - flags = dict_as_flags(value); - if (flags & DEC_ERRORS) { - return -1; - } - } - - ctx = CTX(self); - if (!mpd_qsettraps(ctx, flags)) { - INTERNAL_ERROR_INT("context_settraps_dict"); - } - - return 0; -} - -#ifdef EXTRA_FUNCTIONALITY -static int -context_setstatus(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_context_t *ctx; - uint32_t flags; - - flags = long_as_flags(value); - if (flags & DEC_ERRORS) { - return -1; - } - - ctx = CTX(self); - if (!mpd_qsetstatus(ctx, flags)) { - INTERNAL_ERROR_INT("context_setstatus"); - } - - return 0; -} -#endif - -static int -context_setstatus_list(PyObject *self, PyObject *value) -{ - mpd_context_t *ctx; - uint32_t flags; - - flags = list_as_flags(value); - if (flags & DEC_ERRORS) { - return -1; - } - - ctx = CTX(self); - if (!mpd_qsetstatus(ctx, flags)) { - INTERNAL_ERROR_INT("context_setstatus_list"); - } - - return 0; -} - -static int -context_setstatus_dict(PyObject *self, PyObject *value) -{ - mpd_context_t *ctx; - uint32_t flags; - - if (PyDecSignalDict_Check(value)) { - flags = SdFlags(value); - } - else { - flags = dict_as_flags(value); - if (flags & DEC_ERRORS) { - return -1; - } - } - - ctx = CTX(self); - if (!mpd_qsetstatus(ctx, flags)) { - INTERNAL_ERROR_INT("context_setstatus_dict"); - } - - return 0; -} - -static int -context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_context_t *ctx; - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return -1; - } - BOUNDS_CHECK(x, INT_MIN, INT_MAX); - - ctx = CTX(self); - if (!mpd_qsetclamp(ctx, (int)x)) { - return value_error_int("valid values for clamp are 0 or 1"); - } - - return 0; -} - -#ifdef EXTRA_FUNCTIONALITY -static int -context_setallcr(PyObject *self, PyObject *value, void *closure UNUSED) -{ - mpd_context_t *ctx; - mpd_ssize_t x; - - x = PyLong_AsSsize_t(value); - if (x == -1 && PyErr_Occurred()) { - return -1; - } - BOUNDS_CHECK(x, INT_MIN, INT_MAX); - - ctx = CTX(self); - if (!mpd_qsetcr(ctx, (int)x)) { - return value_error_int("valid values for _allcr are 0 or 1"); - } - - return 0; -} -#endif - -static PyObject * -context_getattr(PyObject *self, PyObject *name) -{ - PyObject *retval; - - if (PyUnicode_Check(name)) { - if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { - retval = ((PyDecContextObject *)self)->traps; - Py_INCREF(retval); - return retval; - } - if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { - retval = ((PyDecContextObject *)self)->flags; - Py_INCREF(retval); - return retval; - } - } - - return PyObject_GenericGetAttr(self, name); -} - -static int -context_setattr(PyObject *self, PyObject *name, PyObject *value) -{ - if (value == NULL) { - PyErr_SetString(PyExc_AttributeError, - "context attributes cannot be deleted"); - return -1; - } - - if (PyUnicode_Check(name)) { - if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { - return context_settraps_dict(self, value); - } - if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { - return context_setstatus_dict(self, value); - } - } - - return PyObject_GenericSetAttr(self, name, value); -} - -static PyObject * -context_clear_traps(PyObject *self, PyObject *dummy UNUSED) -{ - CTX(self)->traps = 0; - Py_RETURN_NONE; -} - -static PyObject * -context_clear_flags(PyObject *self, PyObject *dummy UNUSED) -{ - CTX(self)->status = 0; - Py_RETURN_NONE; -} - -#define DEC_DFLT_EMAX 999999 -#define DEC_DFLT_EMIN -999999 - -static mpd_context_t dflt_ctx = { - 28, DEC_DFLT_EMAX, DEC_DFLT_EMIN, - MPD_IEEE_Invalid_operation|MPD_Division_by_zero|MPD_Overflow, - 0, 0, MPD_ROUND_HALF_EVEN, 0, 1 -}; - -static PyObject * -context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED) -{ - PyDecContextObject *self = NULL; - mpd_context_t *ctx; - - if (type == &PyDecContext_Type) { - self = PyObject_New(PyDecContextObject, &PyDecContext_Type); - } - else { - self = (PyDecContextObject *)type->tp_alloc(type, 0); - } - - if (self == NULL) { - return NULL; - } - - self->traps = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL); - if (self->traps == NULL) { - self->flags = NULL; - Py_DECREF(self); - return NULL; - } - self->flags = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL); - if (self->flags == NULL) { - Py_DECREF(self); - return NULL; - } - - ctx = CTX(self); - - if (default_context_template) { - *ctx = *CTX(default_context_template); - } - else { - *ctx = dflt_ctx; - } - - SdFlagAddr(self->traps) = &ctx->traps; - SdFlagAddr(self->flags) = &ctx->status; - - CtxCaps(self) = 1; - self->tstate = NULL; - - return (PyObject *)self; -} - -static void -context_dealloc(PyDecContextObject *self) -{ -#ifndef WITH_DECIMAL_CONTEXTVAR - if (self == cached_context) { - cached_context = NULL; - } -#endif - - Py_XDECREF(self->traps); - Py_XDECREF(self->flags); - Py_TYPE(self)->tp_free(self); -} - -static int -context_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = { - "prec", "rounding", "Emin", "Emax", "capitals", "clamp", - "flags", "traps", NULL - }; - PyObject *prec = Py_None; - PyObject *rounding = Py_None; - PyObject *emin = Py_None; - PyObject *emax = Py_None; - PyObject *capitals = Py_None; - PyObject *clamp = Py_None; - PyObject *status = Py_None; - PyObject *traps = Py_None; - int ret; - - assert(PyTuple_Check(args)); - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, - "|OOOOOOOO", kwlist, - &prec, &rounding, &emin, &emax, &capitals, &clamp, &status, &traps - )) { - return -1; - } - - if (prec != Py_None && context_setprec(self, prec, NULL) < 0) { - return -1; - } - if (rounding != Py_None && context_setround(self, rounding, NULL) < 0) { - return -1; - } - if (emin != Py_None && context_setemin(self, emin, NULL) < 0) { - return -1; - } - if (emax != Py_None && context_setemax(self, emax, NULL) < 0) { - return -1; - } - if (capitals != Py_None && context_setcapitals(self, capitals, NULL) < 0) { - return -1; - } - if (clamp != Py_None && context_setclamp(self, clamp, NULL) < 0) { - return -1; - } - - if (traps != Py_None) { - if (PyList_Check(traps)) { - ret = context_settraps_list(self, traps); - } -#ifdef EXTRA_FUNCTIONALITY - else if (PyLong_Check(traps)) { - ret = context_settraps(self, traps, NULL); - } -#endif - else { - ret = context_settraps_dict(self, traps); - } - if (ret < 0) { - return ret; - } - } - if (status != Py_None) { - if (PyList_Check(status)) { - ret = context_setstatus_list(self, status); - } -#ifdef EXTRA_FUNCTIONALITY - else if (PyLong_Check(status)) { - ret = context_setstatus(self, status, NULL); - } -#endif - else { - ret = context_setstatus_dict(self, status); - } - if (ret < 0) { - return ret; - } - } - - return 0; -} - -static PyObject * -context_repr(PyDecContextObject *self) -{ - mpd_context_t *ctx; - char flags[MPD_MAX_SIGNAL_LIST]; - char traps[MPD_MAX_SIGNAL_LIST]; - int n, mem; - - assert(PyDecContext_Check(self)); - ctx = CTX(self); - - mem = MPD_MAX_SIGNAL_LIST; - n = mpd_lsnprint_signals(flags, mem, ctx->status, dec_signal_string); - if (n < 0 || n >= mem) { - INTERNAL_ERROR_PTR("context_repr"); - } - - n = mpd_lsnprint_signals(traps, mem, ctx->traps, dec_signal_string); - if (n < 0 || n >= mem) { - INTERNAL_ERROR_PTR("context_repr"); - } - - return PyUnicode_FromFormat( - "Context(prec=%zd, rounding=%s, Emin=%zd, Emax=%zd, " - "capitals=%d, clamp=%d, flags=%s, traps=%s)", - ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax, - self->capitals, ctx->clamp, flags, traps); -} - -static void -init_basic_context(PyObject *v) -{ - mpd_context_t ctx = dflt_ctx; - - ctx.prec = 9; - ctx.traps |= (MPD_Underflow|MPD_Clamped); - ctx.round = MPD_ROUND_HALF_UP; - - *CTX(v) = ctx; - CtxCaps(v) = 1; -} - -static void -init_extended_context(PyObject *v) -{ - mpd_context_t ctx = dflt_ctx; - - ctx.prec = 9; - ctx.traps = 0; - - *CTX(v) = ctx; - CtxCaps(v) = 1; -} - -#ifdef EXTRA_FUNCTIONALITY -/* Factory function for creating IEEE interchange format contexts */ -static PyObject * -ieee_context(PyObject *dummy UNUSED, PyObject *v) -{ - PyObject *context; - mpd_ssize_t bits; - mpd_context_t ctx; - - bits = PyLong_AsSsize_t(v); - if (bits == -1 && PyErr_Occurred()) { - return NULL; - } - if (bits <= 0 || bits > INT_MAX) { - goto error; - } - if (mpd_ieee_context(&ctx, (int)bits) < 0) { - goto error; - } - - context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); - if (context == NULL) { - return NULL; - } - *CTX(context) = ctx; - - return context; - -error: - PyErr_Format(PyExc_ValueError, - "argument must be a multiple of 32, with a maximum of %d", - MPD_IEEE_CONTEXT_MAX_BITS); - - return NULL; -} -#endif - -static PyObject * -context_copy(PyObject *self, PyObject *args UNUSED) -{ - PyObject *copy; - - copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); - if (copy == NULL) { - return NULL; - } - - *CTX(copy) = *CTX(self); - CTX(copy)->newtrap = 0; - CtxCaps(copy) = CtxCaps(self); - - return copy; -} - -static PyObject * -context_reduce(PyObject *self, PyObject *args UNUSED) -{ - PyObject *flags; - PyObject *traps; - PyObject *ret; - mpd_context_t *ctx; - - ctx = CTX(self); - - flags = signals_as_list(ctx->status); - if (flags == NULL) { - return NULL; - } - traps = signals_as_list(ctx->traps); - if (traps == NULL) { - Py_DECREF(flags); - return NULL; - } - - ret = Py_BuildValue( - "O(nsnniiOO)", - Py_TYPE(self), - ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax, - CtxCaps(self), ctx->clamp, flags, traps - ); - - Py_DECREF(flags); - Py_DECREF(traps); - return ret; -} - - -static PyGetSetDef context_getsets [] = -{ - { "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL}, - { "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL}, - { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL}, - { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL}, - { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL}, - { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL}, -#ifdef EXTRA_FUNCTIONALITY - { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL}, - { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL}, - { "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL}, -#endif - {NULL} -}; - - -#define CONTEXT_CHECK(obj) \ - if (!PyDecContext_Check(obj)) { \ - PyErr_SetString(PyExc_TypeError, \ - "argument must be a context"); \ - return NULL; \ - } - -#define CONTEXT_CHECK_VA(obj) \ - if (obj == Py_None) { \ - CURRENT_CONTEXT(obj); \ - } \ - else if (!PyDecContext_Check(obj)) { \ - PyErr_SetString(PyExc_TypeError, \ - "optional argument must be a context"); \ - return NULL; \ - } - - -/******************************************************************************/ -/* Global, thread local and temporary contexts */ -/******************************************************************************/ - -/* - * Thread local storage currently has a speed penalty of about 4%. - * All functions that map Python's arithmetic operators to mpdecimal - * functions have to look up the current context for each and every - * operation. - */ - -#ifndef WITH_DECIMAL_CONTEXTVAR -/* Get the context from the thread state dictionary. */ -static PyObject * -current_context_from_dict(void) -{ - PyObject *dict; - PyObject *tl_context; - PyThreadState *tstate; - - dict = PyThreadState_GetDict(); - if (dict == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "cannot get thread state"); - return NULL; - } - - tl_context = PyDict_GetItemWithError(dict, tls_context_key); - if (tl_context != NULL) { - /* We already have a thread local context. */ - CONTEXT_CHECK(tl_context); - } - else { - if (PyErr_Occurred()) { - return NULL; - } - - /* Set up a new thread local context. */ - tl_context = context_copy(default_context_template, NULL); - if (tl_context == NULL) { - return NULL; - } - CTX(tl_context)->status = 0; - - if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) { - Py_DECREF(tl_context); - return NULL; - } - Py_DECREF(tl_context); - } - - /* Cache the context of the current thread, assuming that it - * will be accessed several times before a thread switch. */ - tstate = PyThreadState_GET(); - if (tstate) { - cached_context = (PyDecContextObject *)tl_context; - cached_context->tstate = tstate; - } - - /* Borrowed reference with refcount==1 */ - return tl_context; -} - -/* Return borrowed reference to thread local context. */ -static PyObject * -current_context(void) -{ - PyThreadState *tstate; - - tstate = PyThreadState_GET(); - if (cached_context && cached_context->tstate == tstate) { - return (PyObject *)cached_context; - } - - return current_context_from_dict(); -} - -/* ctxobj := borrowed reference to the current context */ -#define CURRENT_CONTEXT(ctxobj) \ - ctxobj = current_context(); \ - if (ctxobj == NULL) { \ - return NULL; \ - } - -/* Return a new reference to the current context */ -static PyObject * -PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) -{ - PyObject *context; - - context = current_context(); - if (context == NULL) { - return NULL; - } - - Py_INCREF(context); - return context; -} - -/* Set the thread local context to a new context, decrement old reference */ -static PyObject * -PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) -{ - PyObject *dict; - - CONTEXT_CHECK(v); - - dict = PyThreadState_GetDict(); - if (dict == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "cannot get thread state"); - return NULL; - } - - /* If the new context is one of the templates, make a copy. - * This is the current behavior of decimal.py. */ - if (v == default_context_template || - v == basic_context_template || - v == extended_context_template) { - v = context_copy(v, NULL); - if (v == NULL) { - return NULL; - } - CTX(v)->status = 0; - } - else { - Py_INCREF(v); - } - - cached_context = NULL; - if (PyDict_SetItem(dict, tls_context_key, v) < 0) { - Py_DECREF(v); - return NULL; - } - - Py_DECREF(v); - Py_RETURN_NONE; -} -#else -static PyObject * -init_current_context(void) -{ - PyObject *tl_context = context_copy(default_context_template, NULL); - if (tl_context == NULL) { - return NULL; - } - CTX(tl_context)->status = 0; - - PyObject *tok = PyContextVar_Set(current_context_var, tl_context); - if (tok == NULL) { - Py_DECREF(tl_context); - return NULL; - } - Py_DECREF(tok); - - return tl_context; -} - -static inline PyObject * -current_context(void) -{ - PyObject *tl_context; - if (PyContextVar_Get(current_context_var, NULL, &tl_context) < 0) { - return NULL; - } - - if (tl_context != NULL) { - return tl_context; - } - - return init_current_context(); -} - -/* ctxobj := borrowed reference to the current context */ -#define CURRENT_CONTEXT(ctxobj) \ - ctxobj = current_context(); \ - if (ctxobj == NULL) { \ - return NULL; \ - } \ - Py_DECREF(ctxobj); - -/* Return a new reference to the current context */ -static PyObject * -PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) -{ - return current_context(); -} - -/* Set the thread local context to a new context, decrement old reference */ -static PyObject * -PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) -{ - CONTEXT_CHECK(v); - - /* If the new context is one of the templates, make a copy. - * This is the current behavior of decimal.py. */ - if (v == default_context_template || - v == basic_context_template || - v == extended_context_template) { - v = context_copy(v, NULL); - if (v == NULL) { - return NULL; - } - CTX(v)->status = 0; - } - else { - Py_INCREF(v); - } - - PyObject *tok = PyContextVar_Set(current_context_var, v); - Py_DECREF(v); - if (tok == NULL) { - return NULL; - } - Py_DECREF(tok); - - Py_RETURN_NONE; -} -#endif - -/* Context manager object for the 'with' statement. The manager - * owns one reference to the global (outer) context and one - * to the local (inner) context. */ -static PyObject * -ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"ctx", NULL}; - PyDecContextManagerObject *self; - PyObject *local = Py_None; - PyObject *global; - - CURRENT_CONTEXT(global); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &local)) { - return NULL; - } - if (local == Py_None) { - local = global; - } - else if (!PyDecContext_Check(local)) { - PyErr_SetString(PyExc_TypeError, - "optional argument must be a context"); - return NULL; - } - - self = PyObject_New(PyDecContextManagerObject, - &PyDecContextManager_Type); - if (self == NULL) { - return NULL; - } - - self->local = context_copy(local, NULL); - if (self->local == NULL) { - self->global = NULL; - Py_DECREF(self); - return NULL; - } - self->global = global; - Py_INCREF(self->global); - - return (PyObject *)self; -} - -static void -ctxmanager_dealloc(PyDecContextManagerObject *self) -{ - Py_XDECREF(self->local); - Py_XDECREF(self->global); - PyObject_Del(self); -} - -static PyObject * -ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED) -{ - PyObject *ret; - - ret = PyDec_SetCurrentContext(NULL, self->local); - if (ret == NULL) { - return NULL; - } - Py_DECREF(ret); - - Py_INCREF(self->local); - return self->local; -} - -static PyObject * -ctxmanager_restore_global(PyDecContextManagerObject *self, - PyObject *args UNUSED) -{ - PyObject *ret; - - ret = PyDec_SetCurrentContext(NULL, self->global); - if (ret == NULL) { - return NULL; - } - Py_DECREF(ret); - - Py_RETURN_NONE; -} - - -static PyMethodDef ctxmanager_methods[] = { - {"__enter__", (PyCFunction)ctxmanager_set_local, METH_NOARGS, NULL}, - {"__exit__", (PyCFunction)ctxmanager_restore_global, METH_VARARGS, NULL}, - {NULL, NULL} -}; - -static PyTypeObject PyDecContextManager_Type = -{ - PyVarObject_HEAD_INIT(NULL, 0) - "decimal.ContextManager", /* tp_name */ - sizeof(PyDecContextManagerObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor) ctxmanager_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - (getattrfunc) 0, /* tp_getattr */ - (setattrfunc) 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc) 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */ - (setattrofunc) 0, /* tp_setattro */ - (PyBufferProcs *) 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - ctxmanager_methods, /* tp_methods */ -}; - - -/******************************************************************************/ -/* New Decimal Object */ -/******************************************************************************/ - -static PyObject * -PyDecType_New(PyTypeObject *type) -{ - PyDecObject *dec; - - if (type == &PyDec_Type) { - dec = PyObject_New(PyDecObject, &PyDec_Type); - } - else { - dec = (PyDecObject *)type->tp_alloc(type, 0); - } - if (dec == NULL) { - return NULL; - } - - dec->hash = -1; - - MPD(dec)->flags = MPD_STATIC|MPD_STATIC_DATA; - MPD(dec)->exp = 0; - MPD(dec)->digits = 0; - MPD(dec)->len = 0; - MPD(dec)->alloc = _Py_DEC_MINALLOC; - MPD(dec)->data = dec->data; - - return (PyObject *)dec; -} -#define dec_alloc() PyDecType_New(&PyDec_Type) - -static void -dec_dealloc(PyObject *dec) -{ - mpd_del(MPD(dec)); - Py_TYPE(dec)->tp_free(dec); -} - - -/******************************************************************************/ -/* Conversions to Decimal */ -/******************************************************************************/ - -Py_LOCAL_INLINE(int) -is_space(enum PyUnicode_Kind kind, const void *data, Py_ssize_t pos) -{ - Py_UCS4 ch = PyUnicode_READ(kind, data, pos); - return Py_UNICODE_ISSPACE(ch); -} - -/* Return the ASCII representation of a numeric Unicode string. The numeric - string may contain ascii characters in the range [1, 127], any Unicode - space and any unicode digit. If strip_ws is true, leading and trailing - whitespace is stripped. If ignore_underscores is true, underscores are - ignored. - - Return NULL if malloc fails and an empty string if invalid characters - are found. */ -static char * -numeric_as_ascii(const PyObject *u, int strip_ws, int ignore_underscores) -{ - enum PyUnicode_Kind kind; - const void *data; - Py_UCS4 ch; - char *res, *cp; - Py_ssize_t j, len; - int d; - - if (PyUnicode_READY(u) == -1) { - return NULL; - } - - kind = PyUnicode_KIND(u); - data = PyUnicode_DATA(u); - len = PyUnicode_GET_LENGTH(u); - - cp = res = PyMem_Malloc(len+1); - if (res == NULL) { - PyErr_NoMemory(); - return NULL; - } - - j = 0; - if (strip_ws) { - while (len > 0 && is_space(kind, data, len-1)) { - len--; - } - while (j < len && is_space(kind, data, j)) { - j++; - } - } - - for (; j < len; j++) { - ch = PyUnicode_READ(kind, data, j); - if (ignore_underscores && ch == '_') { - continue; - } - if (0 < ch && ch <= 127) { - *cp++ = ch; - continue; - } - if (Py_UNICODE_ISSPACE(ch)) { - *cp++ = ' '; - continue; - } - d = Py_UNICODE_TODECIMAL(ch); - if (d < 0) { - /* empty string triggers ConversionSyntax */ - *res = '\0'; - return res; - } - *cp++ = '0' + d; - } - *cp = '\0'; - return res; -} - -/* Return a new PyDecObject or a subtype from a C string. Use the context - during conversion. */ -static PyObject * -PyDecType_FromCString(PyTypeObject *type, const char *s, - PyObject *context) -{ - PyObject *dec; - uint32_t status = 0; - - dec = PyDecType_New(type); - if (dec == NULL) { - return NULL; - } - - mpd_qset_string(MPD(dec), s, CTX(context), &status); - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - return dec; -} - -/* Return a new PyDecObject or a subtype from a C string. Attempt exact - conversion. If the operand cannot be converted exactly, set - InvalidOperation. */ -static PyObject * -PyDecType_FromCStringExact(PyTypeObject *type, const char *s, - PyObject *context) -{ - PyObject *dec; - uint32_t status = 0; - mpd_context_t maxctx; - - dec = PyDecType_New(type); - if (dec == NULL) { - return NULL; - } - - mpd_maxcontext(&maxctx); - - mpd_qset_string(MPD(dec), s, &maxctx, &status); - if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { - /* we want exact results */ - mpd_seterror(MPD(dec), MPD_Invalid_operation, &status); - } - status &= MPD_Errors; - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - - return dec; -} - -/* Return a new PyDecObject or a subtype from a PyUnicodeObject. */ -static PyObject * -PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u, - PyObject *context) -{ - PyObject *dec; - char *s; - - s = numeric_as_ascii(u, 0, 0); - if (s == NULL) { - return NULL; - } - - dec = PyDecType_FromCString(type, s, context); - PyMem_Free(s); - return dec; -} - -/* Return a new PyDecObject or a subtype from a PyUnicodeObject. Attempt exact - * conversion. If the conversion is not exact, fail with InvalidOperation. - * Allow leading and trailing whitespace in the input operand. */ -static PyObject * -PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u, - PyObject *context) -{ - PyObject *dec; - char *s; - - s = numeric_as_ascii(u, 1, 1); - if (s == NULL) { - return NULL; - } - - dec = PyDecType_FromCStringExact(type, s, context); - PyMem_Free(s); - return dec; -} - -/* Set PyDecObject from triple without any error checking. */ -Py_LOCAL_INLINE(void) -_dec_settriple(PyObject *dec, uint8_t sign, uint32_t v, mpd_ssize_t exp) -{ - -#ifdef CONFIG_64 - MPD(dec)->data[0] = v; - MPD(dec)->len = 1; -#else - uint32_t q, r; - q = v / MPD_RADIX; - r = v - q * MPD_RADIX; - MPD(dec)->data[1] = q; - MPD(dec)->data[0] = r; - MPD(dec)->len = q ? 2 : 1; -#endif - mpd_set_flags(MPD(dec), sign); - MPD(dec)->exp = exp; - mpd_setdigits(MPD(dec)); -} - -/* Return a new PyDecObject from an mpd_ssize_t. */ -static PyObject * -PyDecType_FromSsize(PyTypeObject *type, mpd_ssize_t v, PyObject *context) -{ - PyObject *dec; - uint32_t status = 0; - - dec = PyDecType_New(type); - if (dec == NULL) { - return NULL; - } - - mpd_qset_ssize(MPD(dec), v, CTX(context), &status); - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - return dec; -} - -/* Return a new PyDecObject from an mpd_ssize_t. Conversion is exact. */ -static PyObject * -PyDecType_FromSsizeExact(PyTypeObject *type, mpd_ssize_t v, PyObject *context) -{ - PyObject *dec; - uint32_t status = 0; - mpd_context_t maxctx; - - dec = PyDecType_New(type); - if (dec == NULL) { - return NULL; - } - - mpd_maxcontext(&maxctx); - - mpd_qset_ssize(MPD(dec), v, &maxctx, &status); - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - return dec; -} - -/* Convert from a PyLongObject. The context is not modified; flags set - during conversion are accumulated in the status parameter. */ -static PyObject * -dec_from_long(PyTypeObject *type, const PyObject *v, - const mpd_context_t *ctx, uint32_t *status) -{ - PyObject *dec; - PyLongObject *l = (PyLongObject *)v; - Py_ssize_t ob_size; - size_t len; - uint8_t sign; - - dec = PyDecType_New(type); - if (dec == NULL) { - return NULL; - } - - ob_size = Py_SIZE(l); - if (ob_size == 0) { - _dec_settriple(dec, MPD_POS, 0, 0); - return dec; - } - - if (ob_size < 0) { - len = -ob_size; - sign = MPD_NEG; - } - else { - len = ob_size; - sign = MPD_POS; - } - - if (len == 1) { - _dec_settriple(dec, sign, *l->ob_digit, 0); - mpd_qfinalize(MPD(dec), ctx, status); - return dec; - } - -#if PYLONG_BITS_IN_DIGIT == 30 - mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, - ctx, status); -#elif PYLONG_BITS_IN_DIGIT == 15 - mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, - ctx, status); -#else - #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" -#endif - - return dec; -} - -/* Return a new PyDecObject from a PyLongObject. Use the context for - conversion. */ -static PyObject * -PyDecType_FromLong(PyTypeObject *type, const PyObject *v, PyObject *context) -{ - PyObject *dec; - uint32_t status = 0; - - if (!PyLong_Check(v)) { - PyErr_SetString(PyExc_TypeError, "argument must be an integer"); - return NULL; - } - - dec = dec_from_long(type, v, CTX(context), &status); - if (dec == NULL) { - return NULL; - } - - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - - return dec; -} - -/* Return a new PyDecObject from a PyLongObject. Use a maximum context - for conversion. If the conversion is not exact, set InvalidOperation. */ -static PyObject * -PyDecType_FromLongExact(PyTypeObject *type, const PyObject *v, - PyObject *context) -{ - PyObject *dec; - uint32_t status = 0; - mpd_context_t maxctx; - - if (!PyLong_Check(v)) { - PyErr_SetString(PyExc_TypeError, "argument must be an integer"); - return NULL; - } - - mpd_maxcontext(&maxctx); - dec = dec_from_long(type, v, &maxctx, &status); - if (dec == NULL) { - return NULL; - } - - if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { - /* we want exact results */ - mpd_seterror(MPD(dec), MPD_Invalid_operation, &status); - } - status &= MPD_Errors; - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - - return dec; -} - -/* External C-API functions */ -static binaryfunc _py_long_multiply; -static binaryfunc _py_long_floor_divide; -static ternaryfunc _py_long_power; -static unaryfunc _py_float_abs; -static PyCFunction _py_long_bit_length; -static PyCFunction _py_float_as_integer_ratio; - -/* Return a PyDecObject or a subtype from a PyFloatObject. - Conversion is exact. */ -static PyObject * -PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v, - PyObject *context) -{ - PyObject *dec, *tmp; - PyObject *n, *d, *n_d; - mpd_ssize_t k; - double x; - int sign; - mpd_t *d1, *d2; - uint32_t status = 0; - mpd_context_t maxctx; - - - assert(PyType_IsSubtype(type, &PyDec_Type)); - - if (PyLong_Check(v)) { - return PyDecType_FromLongExact(type, v, context); - } - if (!PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "argument must be int or float"); - return NULL; - } - - x = PyFloat_AsDouble(v); - if (x == -1.0 && PyErr_Occurred()) { - return NULL; - } - sign = (copysign(1.0, x) == 1.0) ? 0 : 1; - - if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { - dec = PyDecType_New(type); - if (dec == NULL) { - return NULL; - } - if (Py_IS_NAN(x)) { - /* decimal.py calls repr(float(+-nan)), - * which always gives a positive result. */ - mpd_setspecial(MPD(dec), MPD_POS, MPD_NAN); - } - else { - mpd_setspecial(MPD(dec), sign, MPD_INF); - } - return dec; - } - - /* absolute value of the float */ - tmp = _py_float_abs(v); - if (tmp == NULL) { - return NULL; - } - - /* float as integer ratio: numerator/denominator */ - n_d = _py_float_as_integer_ratio(tmp, NULL); - Py_DECREF(tmp); - if (n_d == NULL) { - return NULL; - } - n = PyTuple_GET_ITEM(n_d, 0); - d = PyTuple_GET_ITEM(n_d, 1); - - tmp = _py_long_bit_length(d, NULL); - if (tmp == NULL) { - Py_DECREF(n_d); - return NULL; - } - k = PyLong_AsSsize_t(tmp); - Py_DECREF(tmp); - if (k == -1 && PyErr_Occurred()) { - Py_DECREF(n_d); - return NULL; - } - k--; - - dec = PyDecType_FromLongExact(type, n, context); - Py_DECREF(n_d); - if (dec == NULL) { - return NULL; - } - - d1 = mpd_qnew(); - if (d1 == NULL) { - Py_DECREF(dec); - PyErr_NoMemory(); - return NULL; - } - d2 = mpd_qnew(); - if (d2 == NULL) { - mpd_del(d1); - Py_DECREF(dec); - PyErr_NoMemory(); - return NULL; - } - - mpd_maxcontext(&maxctx); - mpd_qset_uint(d1, 5, &maxctx, &status); - mpd_qset_ssize(d2, k, &maxctx, &status); - mpd_qpow(d1, d1, d2, &maxctx, &status); - if (dec_addstatus(context, status)) { - mpd_del(d1); - mpd_del(d2); - Py_DECREF(dec); - return NULL; - } - - /* result = n * 5**k */ - mpd_qmul(MPD(dec), MPD(dec), d1, &maxctx, &status); - mpd_del(d1); - mpd_del(d2); - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - /* result = +- n * 5**k * 10**-k */ - mpd_set_sign(MPD(dec), sign); - MPD(dec)->exp = -k; - - return dec; -} - -static PyObject * -PyDecType_FromFloat(PyTypeObject *type, PyObject *v, - PyObject *context) -{ - PyObject *dec; - uint32_t status = 0; - - dec = PyDecType_FromFloatExact(type, v, context); - if (dec == NULL) { - return NULL; - } - - mpd_qfinalize(MPD(dec), CTX(context), &status); - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - - return dec; -} - -/* Return a new PyDecObject or a subtype from a Decimal. */ -static PyObject * -PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context) -{ - PyObject *dec; - uint32_t status = 0; - - if (type == &PyDec_Type && PyDec_CheckExact(v)) { - Py_INCREF(v); - return v; - } - - dec = PyDecType_New(type); - if (dec == NULL) { - return NULL; - } - - mpd_qcopy(MPD(dec), MPD(v), &status); - if (dec_addstatus(context, status)) { - Py_DECREF(dec); - return NULL; - } - - return dec; -} - -static PyObject * -sequence_as_tuple(PyObject *v, PyObject *ex, const char *mesg) -{ - if (PyTuple_Check(v)) { - Py_INCREF(v); - return v; - } - if (PyList_Check(v)) { - return PyList_AsTuple(v); - } - - PyErr_SetString(ex, mesg); - return NULL; -} - -/* Return a new C string representation of a DecimalTuple. */ -static char * -dectuple_as_str(PyObject *dectuple) -{ - PyObject *digits = NULL, *tmp; - char *decstring = NULL; - char sign_special[6]; - char *cp; - long sign, l; - mpd_ssize_t exp = 0; - Py_ssize_t i, mem, tsize; - int is_infinite = 0; - int n; - - assert(PyTuple_Check(dectuple)); - - if (PyTuple_Size(dectuple) != 3) { - PyErr_SetString(PyExc_ValueError, - "argument must be a sequence of length 3"); - goto error; - } - - /* sign */ - tmp = PyTuple_GET_ITEM(dectuple, 0); - if (!PyLong_Check(tmp)) { - PyErr_SetString(PyExc_ValueError, - "sign must be an integer with the value 0 or 1"); - goto error; - } - sign = PyLong_AsLong(tmp); - if (sign == -1 && PyErr_Occurred()) { - goto error; - } - if (sign != 0 && sign != 1) { - PyErr_SetString(PyExc_ValueError, - "sign must be an integer with the value 0 or 1"); - goto error; - } - sign_special[0] = sign ? '-' : '+'; - sign_special[1] = '\0'; - - /* exponent or encoding for a special number */ - tmp = PyTuple_GET_ITEM(dectuple, 2); - if (PyUnicode_Check(tmp)) { - /* special */ - if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) { - strcat(sign_special, "Inf"); - is_infinite = 1; - } - else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) { - strcat(sign_special, "NaN"); - } - else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) { - strcat(sign_special, "sNaN"); - } - else { - PyErr_SetString(PyExc_ValueError, - "string argument in the third position " - "must be 'F', 'n' or 'N'"); - goto error; - } - } - else { - /* exponent */ - if (!PyLong_Check(tmp)) { - PyErr_SetString(PyExc_ValueError, - "exponent must be an integer"); - goto error; - } - exp = PyLong_AsSsize_t(tmp); - if (exp == -1 && PyErr_Occurred()) { - goto error; - } - } - - /* coefficient */ - digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), PyExc_ValueError, - "coefficient must be a tuple of digits"); - if (digits == NULL) { - goto error; - } - - tsize = PyTuple_Size(digits); - /* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */ - mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2; - cp = decstring = PyMem_Malloc(mem); - if (decstring == NULL) { - PyErr_NoMemory(); - goto error; - } - - n = snprintf(cp, mem, "%s", sign_special); - if (n < 0 || n >= mem) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in dec_sequence_as_str"); - goto error; - } - cp += n; - - if (tsize == 0 && sign_special[1] == '\0') { - /* empty tuple: zero coefficient, except for special numbers */ - *cp++ = '0'; - } - for (i = 0; i < tsize; i++) { - tmp = PyTuple_GET_ITEM(digits, i); - if (!PyLong_Check(tmp)) { - PyErr_SetString(PyExc_ValueError, - "coefficient must be a tuple of digits"); - goto error; - } - l = PyLong_AsLong(tmp); - if (l == -1 && PyErr_Occurred()) { - goto error; - } - if (l < 0 || l > 9) { - PyErr_SetString(PyExc_ValueError, - "coefficient must be a tuple of digits"); - goto error; - } - if (is_infinite) { - /* accept but ignore any well-formed coefficient for compatibility - with decimal.py */ - continue; - } - *cp++ = (char)l + '0'; - } - *cp = '\0'; - - if (sign_special[1] == '\0') { - /* not a special number */ - *cp++ = 'E'; - n = snprintf(cp, MPD_EXPDIGITS+2, "%" PRI_mpd_ssize_t, exp); - if (n < 0 || n >= MPD_EXPDIGITS+2) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in dec_sequence_as_str"); - goto error; - } - } - - Py_XDECREF(digits); - return decstring; - - -error: - Py_XDECREF(digits); - if (decstring) PyMem_Free(decstring); - return NULL; -} - -/* Currently accepts tuples and lists. */ -static PyObject * -PyDecType_FromSequence(PyTypeObject *type, PyObject *v, - PyObject *context) -{ - PyObject *dectuple; - PyObject *dec; - char *s; - - dectuple = sequence_as_tuple(v, PyExc_TypeError, - "argument must be a tuple or list"); - if (dectuple == NULL) { - return NULL; - } - - s = dectuple_as_str(dectuple); - Py_DECREF(dectuple); - if (s == NULL) { - return NULL; - } - - dec = PyDecType_FromCString(type, s, context); - - PyMem_Free(s); - return dec; -} - -/* Currently accepts tuples and lists. */ -static PyObject * -PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v, - PyObject *context) -{ - PyObject *dectuple; - PyObject *dec; - char *s; - - dectuple = sequence_as_tuple(v, PyExc_TypeError, - "argument must be a tuple or list"); - if (dectuple == NULL) { - return NULL; - } - - s = dectuple_as_str(dectuple); - Py_DECREF(dectuple); - if (s == NULL) { - return NULL; - } - - dec = PyDecType_FromCStringExact(type, s, context); - - PyMem_Free(s); - return dec; -} - -#define PyDec_FromCString(str, context) \ - PyDecType_FromCString(&PyDec_Type, str, context) -#define PyDec_FromCStringExact(str, context) \ - PyDecType_FromCStringExact(&PyDec_Type, str, context) - -#define PyDec_FromUnicode(unicode, context) \ - PyDecType_FromUnicode(&PyDec_Type, unicode, context) -#define PyDec_FromUnicodeExact(unicode, context) \ - PyDecType_FromUnicodeExact(&PyDec_Type, unicode, context) -#define PyDec_FromUnicodeExactWS(unicode, context) \ - PyDecType_FromUnicodeExactWS(&PyDec_Type, unicode, context) - -#define PyDec_FromSsize(v, context) \ - PyDecType_FromSsize(&PyDec_Type, v, context) -#define PyDec_FromSsizeExact(v, context) \ - PyDecType_FromSsizeExact(&PyDec_Type, v, context) - -#define PyDec_FromLong(pylong, context) \ - PyDecType_FromLong(&PyDec_Type, pylong, context) -#define PyDec_FromLongExact(pylong, context) \ - PyDecType_FromLongExact(&PyDec_Type, pylong, context) - -#define PyDec_FromFloat(pyfloat, context) \ - PyDecType_FromFloat(&PyDec_Type, pyfloat, context) -#define PyDec_FromFloatExact(pyfloat, context) \ - PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context) - -#define PyDec_FromSequence(sequence, context) \ - PyDecType_FromSequence(&PyDec_Type, sequence, context) -#define PyDec_FromSequenceExact(sequence, context) \ - PyDecType_FromSequenceExact(&PyDec_Type, sequence, context) - -/* class method */ -static PyObject * -dec_from_float(PyObject *type, PyObject *pyfloat) -{ - PyObject *context; - PyObject *result; - - CURRENT_CONTEXT(context); - result = PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context); - if (type != (PyObject *)&PyDec_Type && result != NULL) { - Py_SETREF(result, PyObject_CallFunctionObjArgs(type, result, NULL)); - } - - return result; -} - -/* create_decimal_from_float */ -static PyObject * -ctx_from_float(PyObject *context, PyObject *v) -{ - return PyDec_FromFloat(v, context); -} - -/* Apply the context to the input operand. Return a new PyDecObject. */ -static PyObject * -dec_apply(PyObject *v, PyObject *context) -{ - PyObject *result; - uint32_t status = 0; - - result = dec_alloc(); - if (result == NULL) { - return NULL; - } - - mpd_qcopy(MPD(result), MPD(v), &status); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - mpd_qfinalize(MPD(result), CTX(context), &status); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -/* 'v' can have any type accepted by the Decimal constructor. Attempt - an exact conversion. If the result does not meet the restrictions - for an mpd_t, fail with InvalidOperation. */ -static PyObject * -PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context) -{ - if (v == NULL) { - return PyDecType_FromSsizeExact(type, 0, context); - } - else if (PyDec_Check(v)) { - return PyDecType_FromDecimalExact(type, v, context); - } - else if (PyUnicode_Check(v)) { - return PyDecType_FromUnicodeExactWS(type, v, context); - } - else if (PyLong_Check(v)) { - return PyDecType_FromLongExact(type, v, context); - } - else if (PyTuple_Check(v) || PyList_Check(v)) { - return PyDecType_FromSequenceExact(type, v, context); - } - else if (PyFloat_Check(v)) { - if (dec_addstatus(context, MPD_Float_operation)) { - return NULL; - } - return PyDecType_FromFloatExact(type, v, context); - } - else { - PyErr_Format(PyExc_TypeError, - "conversion from %s to Decimal is not supported", - Py_TYPE(v)->tp_name); - return NULL; - } -} - -/* The context is used during conversion. This function is the - equivalent of context.create_decimal(). */ -static PyObject * -PyDec_FromObject(PyObject *v, PyObject *context) -{ - if (v == NULL) { - return PyDec_FromSsize(0, context); - } - else if (PyDec_Check(v)) { - mpd_context_t *ctx = CTX(context); - if (mpd_isnan(MPD(v)) && - MPD(v)->digits > ctx->prec - ctx->clamp) { - /* Special case: too many NaN payload digits */ - PyObject *result; - if (dec_addstatus(context, MPD_Conversion_syntax)) { - return NULL; - } - result = dec_alloc(); - if (result == NULL) { - return NULL; - } - mpd_setspecial(MPD(result), MPD_POS, MPD_NAN); - return result; - } - return dec_apply(v, context); - } - else if (PyUnicode_Check(v)) { - return PyDec_FromUnicode(v, context); - } - else if (PyLong_Check(v)) { - return PyDec_FromLong(v, context); - } - else if (PyTuple_Check(v) || PyList_Check(v)) { - return PyDec_FromSequence(v, context); - } - else if (PyFloat_Check(v)) { - if (dec_addstatus(context, MPD_Float_operation)) { - return NULL; - } - return PyDec_FromFloat(v, context); - } - else { - PyErr_Format(PyExc_TypeError, - "conversion from %s to Decimal is not supported", - Py_TYPE(v)->tp_name); - return NULL; - } -} - -static PyObject * -dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"value", "context", NULL}; - PyObject *v = NULL; - PyObject *context = Py_None; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, - &v, &context)) { - return NULL; - } - CONTEXT_CHECK_VA(context); - - return PyDecType_FromObjectExact(type, v, context); -} - -static PyObject * -ctx_create_decimal(PyObject *context, PyObject *args) -{ - PyObject *v = NULL; - - if (!PyArg_ParseTuple(args, "|O", &v)) { - return NULL; - } - - return PyDec_FromObject(v, context); -} - - -/******************************************************************************/ -/* Implicit conversions to Decimal */ -/******************************************************************************/ - -/* Try to convert PyObject v to a new PyDecObject conv. If the conversion - fails, set conv to NULL (exception is set). If the conversion is not - implemented, set conv to Py_NotImplemented. */ -#define NOT_IMPL 0 -#define TYPE_ERR 1 -Py_LOCAL_INLINE(int) -convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) -{ - - if (PyDec_Check(v)) { - *conv = v; - Py_INCREF(v); - return 1; - } - if (PyLong_Check(v)) { - *conv = PyDec_FromLongExact(v, context); - if (*conv == NULL) { - return 0; - } - return 1; - } - - if (type_err) { - PyErr_Format(PyExc_TypeError, - "conversion from %s to Decimal is not supported", - Py_TYPE(v)->tp_name); - } - else { - Py_INCREF(Py_NotImplemented); - *conv = Py_NotImplemented; - } - return 0; -} - -/* Return NotImplemented for unsupported types. */ -#define CONVERT_OP(a, v, context) \ - if (!convert_op(NOT_IMPL, a, v, context)) { \ - return *(a); \ - } - -#define CONVERT_BINOP(a, b, v, w, context) \ - if (!convert_op(NOT_IMPL, a, v, context)) { \ - return *(a); \ - } \ - if (!convert_op(NOT_IMPL, b, w, context)) { \ - Py_DECREF(*(a)); \ - return *(b); \ - } - -#define CONVERT_TERNOP(a, b, c, v, w, x, context) \ - if (!convert_op(NOT_IMPL, a, v, context)) { \ - return *(a); \ - } \ - if (!convert_op(NOT_IMPL, b, w, context)) { \ - Py_DECREF(*(a)); \ - return *(b); \ - } \ - if (!convert_op(NOT_IMPL, c, x, context)) { \ - Py_DECREF(*(a)); \ - Py_DECREF(*(b)); \ - return *(c); \ - } - -/* Raise TypeError for unsupported types. */ -#define CONVERT_OP_RAISE(a, v, context) \ - if (!convert_op(TYPE_ERR, a, v, context)) { \ - return NULL; \ - } - -#define CONVERT_BINOP_RAISE(a, b, v, w, context) \ - if (!convert_op(TYPE_ERR, a, v, context)) { \ - return NULL; \ - } \ - if (!convert_op(TYPE_ERR, b, w, context)) { \ - Py_DECREF(*(a)); \ - return NULL; \ - } - -#define CONVERT_TERNOP_RAISE(a, b, c, v, w, x, context) \ - if (!convert_op(TYPE_ERR, a, v, context)) { \ - return NULL; \ - } \ - if (!convert_op(TYPE_ERR, b, w, context)) { \ - Py_DECREF(*(a)); \ - return NULL; \ - } \ - if (!convert_op(TYPE_ERR, c, x, context)) { \ - Py_DECREF(*(a)); \ - Py_DECREF(*(b)); \ - return NULL; \ - } - - -/******************************************************************************/ -/* Implicit conversions to Decimal for comparison */ -/******************************************************************************/ - -/* Convert rationals for comparison */ -static PyObject *Rational = NULL; -static PyObject * -multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context) -{ - PyObject *result; - PyObject *tmp = NULL; - PyObject *denom = NULL; - uint32_t status = 0; - mpd_context_t maxctx; - mpd_ssize_t exp; - mpd_t *vv; - - /* v is not special, r is a rational */ - tmp = PyObject_GetAttrString(r, "denominator"); - if (tmp == NULL) { - return NULL; - } - denom = PyDec_FromLongExact(tmp, context); - Py_DECREF(tmp); - if (denom == NULL) { - return NULL; - } - - vv = mpd_qncopy(MPD(v)); - if (vv == NULL) { - Py_DECREF(denom); - PyErr_NoMemory(); - return NULL; - } - result = dec_alloc(); - if (result == NULL) { - Py_DECREF(denom); - mpd_del(vv); - return NULL; - } - - mpd_maxcontext(&maxctx); - /* Prevent Overflow in the following multiplication. The result of - the multiplication is only used in mpd_qcmp, which can handle - values that are technically out of bounds, like (for 32-bit) - 99999999999999999999...99999999e+425000000. */ - exp = vv->exp; - vv->exp = 0; - mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status); - MPD(result)->exp = exp; - - Py_DECREF(denom); - mpd_del(vv); - /* If any status has been accumulated during the multiplication, - the result is invalid. This is very unlikely, since even the - 32-bit version supports 425000000 digits. */ - if (status) { - PyErr_SetString(PyExc_ValueError, - "exact conversion for comparison failed"); - Py_DECREF(result); - return NULL; - } - - return result; -} - -static PyObject * -numerator_as_decimal(PyObject *r, PyObject *context) -{ - PyObject *tmp, *num; - - tmp = PyObject_GetAttrString(r, "numerator"); - if (tmp == NULL) { - return NULL; - } - - num = PyDec_FromLongExact(tmp, context); - Py_DECREF(tmp); - return num; -} - -/* Convert v and w for comparison. v is a Decimal. If w is a Rational, both - v and w have to be transformed. Return 1 for success, with new references - to the converted objects in vcmp and wcmp. Return 0 for failure. In that - case wcmp is either NULL or Py_NotImplemented (new reference) and vcmp - is undefined. */ -static int -convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, - int op, PyObject *context) -{ - mpd_context_t *ctx = CTX(context); - - *vcmp = v; - - if (PyDec_Check(w)) { - Py_INCREF(w); - *wcmp = w; - } - else if (PyLong_Check(w)) { - *wcmp = PyDec_FromLongExact(w, context); - } - else if (PyFloat_Check(w)) { - if (op != Py_EQ && op != Py_NE && - dec_addstatus(context, MPD_Float_operation)) { - *wcmp = NULL; - } - else { - ctx->status |= MPD_Float_operation; - *wcmp = PyDec_FromFloatExact(w, context); - } - } - else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) { - Py_complex c = PyComplex_AsCComplex(w); - if (c.real == -1.0 && PyErr_Occurred()) { - *wcmp = NULL; - } - else if (c.imag == 0.0) { - PyObject *tmp = PyFloat_FromDouble(c.real); - if (tmp == NULL) { - *wcmp = NULL; - } - else { - ctx->status |= MPD_Float_operation; - *wcmp = PyDec_FromFloatExact(tmp, context); - Py_DECREF(tmp); - } - } - else { - Py_INCREF(Py_NotImplemented); - *wcmp = Py_NotImplemented; - } - } - else { - int is_rational = PyObject_IsInstance(w, Rational); - if (is_rational < 0) { - *wcmp = NULL; - } - else if (is_rational > 0) { - *wcmp = numerator_as_decimal(w, context); - if (*wcmp && !mpd_isspecial(MPD(v))) { - *vcmp = multiply_by_denominator(v, w, context); - if (*vcmp == NULL) { - Py_CLEAR(*wcmp); - } - } - } - else { - Py_INCREF(Py_NotImplemented); - *wcmp = Py_NotImplemented; - } - } - - if (*wcmp == NULL || *wcmp == Py_NotImplemented) { - return 0; - } - if (*vcmp == v) { - Py_INCREF(v); - } - return 1; -} - -#define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \ - if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) { \ - return *(wcmp); \ - } \ - - -/******************************************************************************/ -/* Conversions from decimal */ -/******************************************************************************/ - -static PyObject * -unicode_fromascii(const char *s, Py_ssize_t size) -{ - PyObject *res; - - res = PyUnicode_New(size, 127); - if (res == NULL) { - return NULL; - } - - memcpy(PyUnicode_1BYTE_DATA(res), s, size); - return res; -} - -/* PyDecObject as a string. The default module context is only used for - the value of 'capitals'. */ -static PyObject * -dec_str(PyObject *dec) -{ - PyObject *res, *context; - mpd_ssize_t size; - char *cp; - - CURRENT_CONTEXT(context); - size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context)); - if (size < 0) { - PyErr_NoMemory(); - return NULL; - } - - res = unicode_fromascii(cp, size); - mpd_free(cp); - return res; -} - -/* Representation of a PyDecObject. */ -static PyObject * -dec_repr(PyObject *dec) -{ - PyObject *res, *context; - char *cp; - - CURRENT_CONTEXT(context); - cp = mpd_to_sci(MPD(dec), CtxCaps(context)); - if (cp == NULL) { - PyErr_NoMemory(); - return NULL; - } - - res = PyUnicode_FromFormat("Decimal('%s')", cp); - mpd_free(cp); - return res; -} - -/* Return a duplicate of src, copy embedded null characters. */ -static char * -dec_strdup(const char *src, Py_ssize_t size) -{ - char *dest = PyMem_Malloc(size+1); - if (dest == NULL) { - PyErr_NoMemory(); - return NULL; - } - - memcpy(dest, src, size); - dest[size] = '\0'; - return dest; -} - -static void -dec_replace_fillchar(char *dest) -{ - while (*dest != '\0') { - if (*dest == '\xff') *dest = '\0'; - dest++; - } -} - -/* Convert decimal_point or thousands_sep, which may be multibyte or in - the range [128, 255], to a UTF8 string. */ -static PyObject * -dotsep_as_utf8(const char *s) -{ - PyObject *utf8; - PyObject *tmp; - wchar_t buf[2]; - size_t n; - - n = mbstowcs(buf, s, 2); - if (n != 1) { /* Issue #7442 */ - PyErr_SetString(PyExc_ValueError, - "invalid decimal point or unsupported " - "combination of LC_CTYPE and LC_NUMERIC"); - return NULL; - } - tmp = PyUnicode_FromWideChar(buf, n); - if (tmp == NULL) { - return NULL; - } - utf8 = PyUnicode_AsUTF8String(tmp); - Py_DECREF(tmp); - return utf8; -} - -/* Formatted representation of a PyDecObject. */ -static PyObject * -dec_format(PyObject *dec, PyObject *args) -{ - PyObject *result = NULL; - PyObject *override = NULL; - PyObject *dot = NULL; - PyObject *sep = NULL; - PyObject *grouping = NULL; - PyObject *fmtarg; - PyObject *context; - mpd_spec_t spec; - char *fmt; - char *decstring = NULL; - uint32_t status = 0; - int replace_fillchar = 0; - Py_ssize_t size; - - - CURRENT_CONTEXT(context); - if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) { - return NULL; - } - - if (PyUnicode_Check(fmtarg)) { - fmt = (char *)PyUnicode_AsUTF8AndSize(fmtarg, &size); - if (fmt == NULL) { - return NULL; - } - if (size > 0 && fmt[0] == '\0') { - /* NUL fill character: must be replaced with a valid UTF-8 char - before calling mpd_parse_fmt_str(). */ - replace_fillchar = 1; - fmt = dec_strdup(fmt, size); - if (fmt == NULL) { - return NULL; - } - fmt[0] = '_'; - } - } - else { - PyErr_SetString(PyExc_TypeError, - "format arg must be str"); - return NULL; - } - - if (!mpd_parse_fmt_str(&spec, fmt, CtxCaps(context))) { - PyErr_SetString(PyExc_ValueError, - "invalid format string"); - goto finish; - } - if (replace_fillchar) { - /* In order to avoid clobbering parts of UTF-8 thousands separators or - decimal points when the substitution is reversed later, the actual - placeholder must be an invalid UTF-8 byte. */ - spec.fill[0] = '\xff'; - spec.fill[1] = '\0'; - } - - if (override) { - /* Values for decimal_point, thousands_sep and grouping can - be explicitly specified in the override dict. These values - take precedence over the values obtained from localeconv() - in mpd_parse_fmt_str(). The feature is not documented and - is only used in test_decimal. */ - if (!PyDict_Check(override)) { - PyErr_SetString(PyExc_TypeError, - "optional argument must be a dict"); - goto finish; - } - if ((dot = PyDict_GetItemString(override, "decimal_point"))) { - if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) { - goto finish; - } - spec.dot = PyBytes_AS_STRING(dot); - } - if ((sep = PyDict_GetItemString(override, "thousands_sep"))) { - if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) { - goto finish; - } - spec.sep = PyBytes_AS_STRING(sep); - } - if ((grouping = PyDict_GetItemString(override, "grouping"))) { - if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) { - goto finish; - } - spec.grouping = PyBytes_AS_STRING(grouping); - } - if (mpd_validate_lconv(&spec) < 0) { - PyErr_SetString(PyExc_ValueError, - "invalid override dict"); - goto finish; - } - } - else { - size_t n = strlen(spec.dot); - if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) { - /* fix locale dependent non-ascii characters */ - dot = dotsep_as_utf8(spec.dot); - if (dot == NULL) { - goto finish; - } - spec.dot = PyBytes_AS_STRING(dot); - } - n = strlen(spec.sep); - if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) { - /* fix locale dependent non-ascii characters */ - sep = dotsep_as_utf8(spec.sep); - if (sep == NULL) { - goto finish; - } - spec.sep = PyBytes_AS_STRING(sep); - } - } - - - decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status); - if (decstring == NULL) { - if (status & MPD_Malloc_error) { - PyErr_NoMemory(); - } - else { - PyErr_SetString(PyExc_ValueError, - "format specification exceeds internal limits of _decimal"); - } - goto finish; - } - size = strlen(decstring); - if (replace_fillchar) { - dec_replace_fillchar(decstring); - } - - result = PyUnicode_DecodeUTF8(decstring, size, NULL); - - -finish: - Py_XDECREF(grouping); - Py_XDECREF(sep); - Py_XDECREF(dot); - if (replace_fillchar) PyMem_Free(fmt); - if (decstring) mpd_free(decstring); - return result; -} - -/* Return a PyLongObject from a PyDecObject, using the specified rounding - * mode. The context precision is not observed. */ -static PyObject * -dec_as_long(PyObject *dec, PyObject *context, int round) -{ - PyLongObject *pylong; - digit *ob_digit; - size_t n; - Py_ssize_t i; - mpd_t *x; - mpd_context_t workctx; - uint32_t status = 0; - - if (mpd_isspecial(MPD(dec))) { - if (mpd_isnan(MPD(dec))) { - PyErr_SetString(PyExc_ValueError, - "cannot convert NaN to integer"); - } - else { - PyErr_SetString(PyExc_OverflowError, - "cannot convert Infinity to integer"); - } - return NULL; - } - - x = mpd_qnew(); - if (x == NULL) { - PyErr_NoMemory(); - return NULL; - } - workctx = *CTX(context); - workctx.round = round; - mpd_qround_to_int(x, MPD(dec), &workctx, &status); - if (dec_addstatus(context, status)) { - mpd_del(x); - return NULL; - } - - status = 0; - ob_digit = NULL; -#if PYLONG_BITS_IN_DIGIT == 30 - n = mpd_qexport_u32(&ob_digit, 0, PyLong_BASE, x, &status); -#elif PYLONG_BITS_IN_DIGIT == 15 - n = mpd_qexport_u16(&ob_digit, 0, PyLong_BASE, x, &status); -#else - #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" -#endif - - if (n == SIZE_MAX) { - PyErr_NoMemory(); - mpd_del(x); - return NULL; - } - - assert(n > 0); - pylong = _PyLong_New(n); - if (pylong == NULL) { - mpd_free(ob_digit); - mpd_del(x); - return NULL; - } - - memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit)); - mpd_free(ob_digit); - - i = n; - while ((i > 0) && (pylong->ob_digit[i-1] == 0)) { - i--; - } - - Py_SET_SIZE(pylong, i); - if (mpd_isnegative(x) && !mpd_iszero(x)) { - Py_SET_SIZE(pylong, -i); - } - - mpd_del(x); - return (PyObject *) pylong; -} - -/* Convert a Decimal to its exact integer ratio representation. */ -static PyObject * -dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED) -{ - PyObject *numerator = NULL; - PyObject *denominator = NULL; - PyObject *exponent = NULL; - PyObject *result = NULL; - PyObject *tmp; - mpd_ssize_t exp; - PyObject *context; - uint32_t status = 0; - - if (mpd_isspecial(MPD(self))) { - if (mpd_isnan(MPD(self))) { - PyErr_SetString(PyExc_ValueError, - "cannot convert NaN to integer ratio"); - } - else { - PyErr_SetString(PyExc_OverflowError, - "cannot convert Infinity to integer ratio"); - } - return NULL; - } - - CURRENT_CONTEXT(context); - - tmp = dec_alloc(); - if (tmp == NULL) { - return NULL; - } - - if (!mpd_qcopy(MPD(tmp), MPD(self), &status)) { - Py_DECREF(tmp); - PyErr_NoMemory(); - return NULL; - } - - exp = mpd_iszero(MPD(tmp)) ? 0 : MPD(tmp)->exp; - MPD(tmp)->exp = 0; - - /* context and rounding are unused here: the conversion is exact */ - numerator = dec_as_long(tmp, context, MPD_ROUND_FLOOR); - Py_DECREF(tmp); - if (numerator == NULL) { - goto error; - } - - exponent = PyLong_FromSsize_t(exp < 0 ? -exp : exp); - if (exponent == NULL) { - goto error; - } - - tmp = PyLong_FromLong(10); - if (tmp == NULL) { - goto error; - } - - Py_SETREF(exponent, _py_long_power(tmp, exponent, Py_None)); - Py_DECREF(tmp); - if (exponent == NULL) { - goto error; - } - - if (exp >= 0) { - Py_SETREF(numerator, _py_long_multiply(numerator, exponent)); - if (numerator == NULL) { - goto error; - } - denominator = PyLong_FromLong(1); - if (denominator == NULL) { - goto error; - } - } - else { - denominator = exponent; - exponent = NULL; - tmp = _PyLong_GCD(numerator, denominator); - if (tmp == NULL) { - goto error; - } - Py_SETREF(numerator, _py_long_floor_divide(numerator, tmp)); - Py_SETREF(denominator, _py_long_floor_divide(denominator, tmp)); - Py_DECREF(tmp); - if (numerator == NULL || denominator == NULL) { - goto error; - } - } - - result = PyTuple_Pack(2, numerator, denominator); - - -error: - Py_XDECREF(exponent); - Py_XDECREF(denominator); - Py_XDECREF(numerator); - return result; -} - -static PyObject * -PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"rounding", "context", NULL}; - PyObject *result; - PyObject *rounding = Py_None; - PyObject *context = Py_None; - uint32_t status = 0; - mpd_context_t workctx; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, - &rounding, &context)) { - return NULL; - } - CONTEXT_CHECK_VA(context); - - workctx = *CTX(context); - if (rounding != Py_None) { - int round = getround(rounding); - if (round < 0) { - return NULL; - } - if (!mpd_qsetround(&workctx, round)) { - INTERNAL_ERROR_PTR("PyDec_ToIntegralValue"); /* GCOV_NOT_REACHED */ - } - } - - result = dec_alloc(); - if (result == NULL) { - return NULL; - } - - mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -static PyObject * -PyDec_ToIntegralExact(PyObject *dec, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"rounding", "context", NULL}; - PyObject *result; - PyObject *rounding = Py_None; - PyObject *context = Py_None; - uint32_t status = 0; - mpd_context_t workctx; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, - &rounding, &context)) { - return NULL; - } - CONTEXT_CHECK_VA(context); - - workctx = *CTX(context); - if (rounding != Py_None) { - int round = getround(rounding); - if (round < 0) { - return NULL; - } - if (!mpd_qsetround(&workctx, round)) { - INTERNAL_ERROR_PTR("PyDec_ToIntegralExact"); /* GCOV_NOT_REACHED */ - } - } - - result = dec_alloc(); - if (result == NULL) { - return NULL; - } - - mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -static PyObject * -PyDec_AsFloat(PyObject *dec) -{ - PyObject *f, *s; - - if (mpd_isnan(MPD(dec))) { - if (mpd_issnan(MPD(dec))) { - PyErr_SetString(PyExc_ValueError, - "cannot convert signaling NaN to float"); - return NULL; - } - if (mpd_isnegative(MPD(dec))) { - s = PyUnicode_FromString("-nan"); - } - else { - s = PyUnicode_FromString("nan"); - } - } - else { - s = dec_str(dec); - } - - if (s == NULL) { - return NULL; - } - - f = PyFloat_FromString(s); - Py_DECREF(s); - - return f; -} - -static PyObject * -PyDec_Round(PyObject *dec, PyObject *args) -{ - PyObject *result; - PyObject *x = NULL; - uint32_t status = 0; - PyObject *context; - - - CURRENT_CONTEXT(context); - if (!PyArg_ParseTuple(args, "|O", &x)) { - return NULL; - } - - if (x) { - mpd_uint_t dq[1] = {1}; - mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq}; - mpd_ssize_t y; - - if (!PyLong_Check(x)) { - PyErr_SetString(PyExc_TypeError, - "optional arg must be an integer"); - return NULL; - } - - y = PyLong_AsSsize_t(x); - if (y == -1 && PyErr_Occurred()) { - return NULL; - } - result = dec_alloc(); - if (result == NULL) { - return NULL; - } - - q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y; - mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; - } - else { - return dec_as_long(dec, context, MPD_ROUND_HALF_EVEN); - } -} - -static PyTypeObject *DecimalTuple = NULL; -/* Return the DecimalTuple representation of a PyDecObject. */ -static PyObject * -PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) -{ - PyObject *result = NULL; - PyObject *sign = NULL; - PyObject *coeff = NULL; - PyObject *expt = NULL; - PyObject *tmp = NULL; - mpd_t *x = NULL; - char *intstring = NULL; - Py_ssize_t intlen, i; - - - x = mpd_qncopy(MPD(dec)); - if (x == NULL) { - PyErr_NoMemory(); - goto out; - } - - sign = PyLong_FromUnsignedLong(mpd_sign(MPD(dec))); - if (sign == NULL) { - goto out; - } - - if (mpd_isinfinite(x)) { - expt = PyUnicode_FromString("F"); - if (expt == NULL) { - goto out; - } - /* decimal.py has non-compliant infinity payloads. */ - coeff = Py_BuildValue("(i)", 0); - if (coeff == NULL) { - goto out; - } - } - else { - if (mpd_isnan(x)) { - expt = PyUnicode_FromString(mpd_isqnan(x)?"n":"N"); - } - else { - expt = PyLong_FromSsize_t(MPD(dec)->exp); - } - if (expt == NULL) { - goto out; - } - - /* coefficient is defined */ - if (x->len > 0) { - - /* make an integer */ - x->exp = 0; - /* clear NaN and sign */ - mpd_clear_flags(x); - intstring = mpd_to_sci(x, 1); - if (intstring == NULL) { - PyErr_NoMemory(); - goto out; - } - - intlen = strlen(intstring); - coeff = PyTuple_New(intlen); - if (coeff == NULL) { - goto out; - } - - for (i = 0; i < intlen; i++) { - tmp = PyLong_FromLong(intstring[i]-'0'); - if (tmp == NULL) { - goto out; - } - PyTuple_SET_ITEM(coeff, i, tmp); - } - } - else { - coeff = PyTuple_New(0); - if (coeff == NULL) { - goto out; - } - } - } - - result = PyObject_CallFunctionObjArgs((PyObject *)DecimalTuple, - sign, coeff, expt, NULL); - -out: - if (x) mpd_del(x); - if (intstring) mpd_free(intstring); - Py_XDECREF(sign); - Py_XDECREF(coeff); - Py_XDECREF(expt); - return result; -} - - -/******************************************************************************/ -/* Macros for converting mpdecimal functions to Decimal methods */ -/******************************************************************************/ - -/* Unary number method that uses the default module context. */ -#define Dec_UnaryNumberMethod(MPDFUNC) \ -static PyObject * \ -nm_##MPDFUNC(PyObject *self) \ -{ \ - PyObject *result; \ - PyObject *context; \ - uint32_t status = 0; \ - \ - CURRENT_CONTEXT(context); \ - if ((result = dec_alloc()) == NULL) { \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \ - if (dec_addstatus(context, status)) { \ - Py_DECREF(result); \ - return NULL; \ - } \ - \ - return result; \ -} - -/* Binary number method that uses default module context. */ -#define Dec_BinaryNumberMethod(MPDFUNC) \ -static PyObject * \ -nm_##MPDFUNC(PyObject *self, PyObject *other) \ -{ \ - PyObject *a, *b; \ - PyObject *result; \ - PyObject *context; \ - uint32_t status = 0; \ - \ - CURRENT_CONTEXT(context) ; \ - CONVERT_BINOP(&a, &b, self, other, context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - Py_DECREF(a); \ - Py_DECREF(b); \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ - Py_DECREF(a); \ - Py_DECREF(b); \ - if (dec_addstatus(context, status)) { \ - Py_DECREF(result); \ - return NULL; \ - } \ - \ - return result; \ -} - -/* Boolean function without a context arg. */ -#define Dec_BoolFunc(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED) \ -{ \ - return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \ -} - -/* Boolean function with an optional context arg. */ -#define Dec_BoolFuncVA(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ -{ \ - static char *kwlist[] = {"context", NULL}; \ - PyObject *context = Py_None; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \ - &context)) { \ - return NULL; \ - } \ - CONTEXT_CHECK_VA(context); \ - \ - return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \ -} - -/* Unary function with an optional context arg. */ -#define Dec_UnaryFuncVA(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ -{ \ - static char *kwlist[] = {"context", NULL}; \ - PyObject *result; \ - PyObject *context = Py_None; \ - uint32_t status = 0; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \ - &context)) { \ - return NULL; \ - } \ - CONTEXT_CHECK_VA(context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \ - if (dec_addstatus(context, status)) { \ - Py_DECREF(result); \ - return NULL; \ - } \ - \ - return result; \ -} - -/* Binary function with an optional context arg. */ -#define Dec_BinaryFuncVA(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ -{ \ - static char *kwlist[] = {"other", "context", NULL}; \ - PyObject *other; \ - PyObject *a, *b; \ - PyObject *result; \ - PyObject *context = Py_None; \ - uint32_t status = 0; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \ - &other, &context)) { \ - return NULL; \ - } \ - CONTEXT_CHECK_VA(context); \ - CONVERT_BINOP_RAISE(&a, &b, self, other, context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - Py_DECREF(a); \ - Py_DECREF(b); \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ - Py_DECREF(a); \ - Py_DECREF(b); \ - if (dec_addstatus(context, status)) { \ - Py_DECREF(result); \ - return NULL; \ - } \ - \ - return result; \ -} - -/* Binary function with an optional context arg. Actual MPDFUNC does - NOT take a context. The context is used to record InvalidOperation - if the second operand cannot be converted exactly. */ -#define Dec_BinaryFuncVA_NO_CTX(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ -{ \ - static char *kwlist[] = {"other", "context", NULL}; \ - PyObject *context = Py_None; \ - PyObject *other; \ - PyObject *a, *b; \ - PyObject *result; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \ - &other, &context)) { \ - return NULL; \ - } \ - CONTEXT_CHECK_VA(context); \ - CONVERT_BINOP_RAISE(&a, &b, self, other, context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - Py_DECREF(a); \ - Py_DECREF(b); \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(a), MPD(b)); \ - Py_DECREF(a); \ - Py_DECREF(b); \ - \ - return result; \ -} - -/* Ternary function with an optional context arg. */ -#define Dec_TernaryFuncVA(MPDFUNC) \ -static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ -{ \ - static char *kwlist[] = {"other", "third", "context", NULL}; \ - PyObject *other, *third; \ - PyObject *a, *b, *c; \ - PyObject *result; \ - PyObject *context = Py_None; \ - uint32_t status = 0; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, \ - &other, &third, &context)) { \ - return NULL; \ - } \ - CONTEXT_CHECK_VA(context); \ - CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - Py_DECREF(a); \ - Py_DECREF(b); \ - Py_DECREF(c); \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \ - Py_DECREF(a); \ - Py_DECREF(b); \ - Py_DECREF(c); \ - if (dec_addstatus(context, status)) { \ - Py_DECREF(result); \ - return NULL; \ - } \ - \ - return result; \ -} - - -/**********************************************/ -/* Number methods */ -/**********************************************/ - -Dec_UnaryNumberMethod(mpd_qminus) -Dec_UnaryNumberMethod(mpd_qplus) -Dec_UnaryNumberMethod(mpd_qabs) - -Dec_BinaryNumberMethod(mpd_qadd) -Dec_BinaryNumberMethod(mpd_qsub) -Dec_BinaryNumberMethod(mpd_qmul) -Dec_BinaryNumberMethod(mpd_qdiv) -Dec_BinaryNumberMethod(mpd_qrem) -Dec_BinaryNumberMethod(mpd_qdivint) - -static PyObject * -nm_dec_as_long(PyObject *dec) -{ - PyObject *context; - - CURRENT_CONTEXT(context); - return dec_as_long(dec, context, MPD_ROUND_DOWN); -} - -static int -nm_nonzero(PyObject *v) -{ - return !mpd_iszero(MPD(v)); -} - -static PyObject * -nm_mpd_qdivmod(PyObject *v, PyObject *w) -{ - PyObject *a, *b; - PyObject *q, *r; - PyObject *context; - uint32_t status = 0; - PyObject *ret; - - CURRENT_CONTEXT(context); - CONVERT_BINOP(&a, &b, v, w, context); - - q = dec_alloc(); - if (q == NULL) { - Py_DECREF(a); - Py_DECREF(b); - return NULL; - } - r = dec_alloc(); - if (r == NULL) { - Py_DECREF(a); - Py_DECREF(b); - Py_DECREF(q); - return NULL; - } - - mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status); - Py_DECREF(a); - Py_DECREF(b); - if (dec_addstatus(context, status)) { - Py_DECREF(r); - Py_DECREF(q); - return NULL; - } - - ret = Py_BuildValue("(OO)", q, r); - Py_DECREF(r); - Py_DECREF(q); - return ret; -} - -static PyObject * -nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) -{ - PyObject *a, *b, *c = NULL; - PyObject *result; - PyObject *context; - uint32_t status = 0; - - CURRENT_CONTEXT(context); - CONVERT_BINOP(&a, &b, base, exp, context); - - if (mod != Py_None) { - if (!convert_op(NOT_IMPL, &c, mod, context)) { - Py_DECREF(a); - Py_DECREF(b); - return c; - } - } - - result = dec_alloc(); - if (result == NULL) { - Py_DECREF(a); - Py_DECREF(b); - Py_XDECREF(c); - return NULL; - } - - if (c == NULL) { - mpd_qpow(MPD(result), MPD(a), MPD(b), - CTX(context), &status); - } - else { - mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c), - CTX(context), &status); - Py_DECREF(c); - } - Py_DECREF(a); - Py_DECREF(b); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - - -/******************************************************************************/ -/* Decimal Methods */ -/******************************************************************************/ - -/* Unary arithmetic functions, optional context arg */ -Dec_UnaryFuncVA(mpd_qexp) -Dec_UnaryFuncVA(mpd_qln) -Dec_UnaryFuncVA(mpd_qlog10) -Dec_UnaryFuncVA(mpd_qnext_minus) -Dec_UnaryFuncVA(mpd_qnext_plus) -Dec_UnaryFuncVA(mpd_qreduce) -Dec_UnaryFuncVA(mpd_qsqrt) - -/* Binary arithmetic functions, optional context arg */ -Dec_BinaryFuncVA(mpd_qcompare) -Dec_BinaryFuncVA(mpd_qcompare_signal) -Dec_BinaryFuncVA(mpd_qmax) -Dec_BinaryFuncVA(mpd_qmax_mag) -Dec_BinaryFuncVA(mpd_qmin) -Dec_BinaryFuncVA(mpd_qmin_mag) -Dec_BinaryFuncVA(mpd_qnext_toward) -Dec_BinaryFuncVA(mpd_qrem_near) - -/* Ternary arithmetic functions, optional context arg */ -Dec_TernaryFuncVA(mpd_qfma) - -/* Boolean functions, no context arg */ -Dec_BoolFunc(mpd_iscanonical) -Dec_BoolFunc(mpd_isfinite) -Dec_BoolFunc(mpd_isinfinite) -Dec_BoolFunc(mpd_isnan) -Dec_BoolFunc(mpd_isqnan) -Dec_BoolFunc(mpd_issnan) -Dec_BoolFunc(mpd_issigned) -Dec_BoolFunc(mpd_iszero) - -/* Boolean functions, optional context arg */ -Dec_BoolFuncVA(mpd_isnormal) -Dec_BoolFuncVA(mpd_issubnormal) - -/* Unary functions, no context arg */ -static PyObject * -dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED) -{ - mpd_ssize_t retval; - - if (mpd_isspecial(MPD(self))) { - retval = 0; - } - else { - retval = mpd_adjexp(MPD(self)); - } - - return PyLong_FromSsize_t(retval); -} - -static PyObject * -dec_canonical(PyObject *self, PyObject *dummy UNUSED) -{ - Py_INCREF(self); - return self; -} - -static PyObject * -dec_conjugate(PyObject *self, PyObject *dummy UNUSED) -{ - Py_INCREF(self); - return self; -} - -static PyObject * -dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED) -{ - PyObject *result; - - result = dec_alloc(); - if (result == NULL) { - return NULL; - } - - _dec_settriple(result, MPD_POS, 10, 0); - return result; -} - -static PyObject * -dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED) -{ - PyObject *result; - uint32_t status = 0; - - if ((result = dec_alloc()) == NULL) { - return NULL; - } - - mpd_qcopy_abs(MPD(result), MPD(self), &status); - if (status & MPD_Malloc_error) { - Py_DECREF(result); - PyErr_NoMemory(); - return NULL; - } - - return result; -} - -static PyObject * -dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED) -{ - PyObject *result; - uint32_t status = 0; - - if ((result = dec_alloc()) == NULL) { - return NULL; - } - - mpd_qcopy_negate(MPD(result), MPD(self), &status); - if (status & MPD_Malloc_error) { - Py_DECREF(result); - PyErr_NoMemory(); - return NULL; - } - - return result; -} - -/* Unary functions, optional context arg */ -Dec_UnaryFuncVA(mpd_qinvert) -Dec_UnaryFuncVA(mpd_qlogb) - -static PyObject * -dec_mpd_class(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"context", NULL}; - PyObject *context = Py_None; - const char *cp; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, - &context)) { - return NULL; - } - CONTEXT_CHECK_VA(context); - - cp = mpd_class(MPD(self), CTX(context)); - return PyUnicode_FromString(cp); -} - -static PyObject * -dec_mpd_to_eng(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"context", NULL}; - PyObject *result; - PyObject *context = Py_None; - mpd_ssize_t size; - char *s; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, - &context)) { - return NULL; - } - CONTEXT_CHECK_VA(context); - - size = mpd_to_eng_size(&s, MPD(self), CtxCaps(context)); - if (size < 0) { - PyErr_NoMemory(); - return NULL; - } - - result = unicode_fromascii(s, size); - mpd_free(s); - - return result; -} - -/* Binary functions, optional context arg for conversion errors */ -Dec_BinaryFuncVA_NO_CTX(mpd_compare_total) -Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag) - -static PyObject * -dec_mpd_qcopy_sign(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"other", "context", NULL}; - PyObject *other; - PyObject *a, *b; - PyObject *result; - PyObject *context = Py_None; - uint32_t status = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, - &other, &context)) { - return NULL; - } - CONTEXT_CHECK_VA(context); - CONVERT_BINOP_RAISE(&a, &b, self, other, context); - - result = dec_alloc(); - if (result == NULL) { - Py_DECREF(a); - Py_DECREF(b); - return NULL; - } - - mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status); - Py_DECREF(a); - Py_DECREF(b); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -static PyObject * -dec_mpd_same_quantum(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"other", "context", NULL}; - PyObject *other; - PyObject *a, *b; - PyObject *result; - PyObject *context = Py_None; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, - &other, &context)) { - return NULL; - } - CONTEXT_CHECK_VA(context); - CONVERT_BINOP_RAISE(&a, &b, self, other, context); - - result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false(); - Py_DECREF(a); - Py_DECREF(b); - - return result; -} - -/* Binary functions, optional context arg */ -Dec_BinaryFuncVA(mpd_qand) -Dec_BinaryFuncVA(mpd_qor) -Dec_BinaryFuncVA(mpd_qxor) - -Dec_BinaryFuncVA(mpd_qrotate) -Dec_BinaryFuncVA(mpd_qscaleb) -Dec_BinaryFuncVA(mpd_qshift) - -static PyObject * -dec_mpd_qquantize(PyObject *v, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"exp", "rounding", "context", NULL}; - PyObject *rounding = Py_None; - PyObject *context = Py_None; - PyObject *w, *a, *b; - PyObject *result; - uint32_t status = 0; - mpd_context_t workctx; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist, - &w, &rounding, &context)) { - return NULL; - } - CONTEXT_CHECK_VA(context); - - workctx = *CTX(context); - if (rounding != Py_None) { - int round = getround(rounding); - if (round < 0) { - return NULL; - } - if (!mpd_qsetround(&workctx, round)) { - INTERNAL_ERROR_PTR("dec_mpd_qquantize"); /* GCOV_NOT_REACHED */ - } - } - - CONVERT_BINOP_RAISE(&a, &b, v, w, context); - - result = dec_alloc(); - if (result == NULL) { - Py_DECREF(a); - Py_DECREF(b); - return NULL; - } - - mpd_qquantize(MPD(result), MPD(a), MPD(b), &workctx, &status); - Py_DECREF(a); - Py_DECREF(b); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -/* Special methods */ -static PyObject * -dec_richcompare(PyObject *v, PyObject *w, int op) -{ - PyObject *a; - PyObject *b; - PyObject *context; - uint32_t status = 0; - int a_issnan, b_issnan; - int r; - - assert(PyDec_Check(v)); - - CURRENT_CONTEXT(context); - CONVERT_BINOP_CMP(&a, &b, v, w, op, context); - - a_issnan = mpd_issnan(MPD(a)); - b_issnan = mpd_issnan(MPD(b)); - - r = mpd_qcmp(MPD(a), MPD(b), &status); - Py_DECREF(a); - Py_DECREF(b); - if (r == INT_MAX) { - /* sNaNs or op={le,ge,lt,gt} always signal. */ - if (a_issnan || b_issnan || (op != Py_EQ && op != Py_NE)) { - if (dec_addstatus(context, status)) { - return NULL; - } - } - /* qNaN comparison with op={eq,ne} or comparison - * with InvalidOperation disabled. */ - return (op == Py_NE) ? incr_true() : incr_false(); - } - - switch (op) { - case Py_EQ: - r = (r == 0); - break; - case Py_NE: - r = (r != 0); - break; - case Py_LE: - r = (r <= 0); - break; - case Py_GE: - r = (r >= 0); - break; - case Py_LT: - r = (r == -1); - break; - case Py_GT: - r = (r == 1); - break; - } - - return PyBool_FromLong(r); -} - -/* __ceil__ */ -static PyObject * -dec_ceil(PyObject *self, PyObject *dummy UNUSED) -{ - PyObject *context; - - CURRENT_CONTEXT(context); - return dec_as_long(self, context, MPD_ROUND_CEILING); -} - -/* __complex__ */ -static PyObject * -dec_complex(PyObject *self, PyObject *dummy UNUSED) -{ - PyObject *f; - double x; - - f = PyDec_AsFloat(self); - if (f == NULL) { - return NULL; - } - - x = PyFloat_AsDouble(f); - Py_DECREF(f); - if (x == -1.0 && PyErr_Occurred()) { - return NULL; - } - - return PyComplex_FromDoubles(x, 0); -} - -/* __copy__ and __deepcopy__ */ -static PyObject * -dec_copy(PyObject *self, PyObject *dummy UNUSED) -{ - Py_INCREF(self); - return self; -} - -/* __floor__ */ -static PyObject * -dec_floor(PyObject *self, PyObject *dummy UNUSED) -{ - PyObject *context; - - CURRENT_CONTEXT(context); - return dec_as_long(self, context, MPD_ROUND_FLOOR); -} - -/* Always uses the module context */ -static Py_hash_t -_dec_hash(PyDecObject *v) -{ -#if defined(CONFIG_64) && _PyHASH_BITS == 61 - /* 2**61 - 1 */ - mpd_uint_t p_data[1] = {2305843009213693951ULL}; - mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data}; - /* Inverse of 10 modulo p */ - mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL}; - mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, - 0, 19, 1, 1, inv10_p_data}; -#elif defined(CONFIG_32) && _PyHASH_BITS == 31 - /* 2**31 - 1 */ - mpd_uint_t p_data[2] = {147483647UL, 2}; - mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data}; - /* Inverse of 10 modulo p */ - mpd_uint_t inv10_p_data[2] = {503238553UL, 1}; - mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, - 0, 10, 2, 2, inv10_p_data}; -#else - #error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS" -#endif - const Py_hash_t py_hash_inf = 314159; - const Py_hash_t py_hash_nan = 0; - mpd_uint_t ten_data[1] = {10}; - mpd_t ten = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, - 0, 2, 1, 1, ten_data}; - Py_hash_t result; - mpd_t *exp_hash = NULL; - mpd_t *tmp = NULL; - mpd_ssize_t exp; - uint32_t status = 0; - mpd_context_t maxctx; - - - if (mpd_isspecial(MPD(v))) { - if (mpd_issnan(MPD(v))) { - PyErr_SetString(PyExc_TypeError, - "Cannot hash a signaling NaN value"); - return -1; - } - else if (mpd_isnan(MPD(v))) { - return py_hash_nan; - } - else { - return py_hash_inf * mpd_arith_sign(MPD(v)); - } - } - - mpd_maxcontext(&maxctx); - exp_hash = mpd_qnew(); - if (exp_hash == NULL) { - goto malloc_error; - } - tmp = mpd_qnew(); - if (tmp == NULL) { - goto malloc_error; - } - - /* - * exp(v): exponent of v - * int(v): coefficient of v - */ - exp = MPD(v)->exp; - if (exp >= 0) { - /* 10**exp(v) % p */ - mpd_qsset_ssize(tmp, exp, &maxctx, &status); - mpd_qpowmod(exp_hash, &ten, tmp, &p, &maxctx, &status); - } - else { - /* inv10_p**(-exp(v)) % p */ - mpd_qsset_ssize(tmp, -exp, &maxctx, &status); - mpd_qpowmod(exp_hash, &inv10_p, tmp, &p, &maxctx, &status); - } - - /* hash = (int(v) * exp_hash) % p */ - if (!mpd_qcopy(tmp, MPD(v), &status)) { - goto malloc_error; - } - tmp->exp = 0; - mpd_set_positive(tmp); - - maxctx.prec = MPD_MAX_PREC + 21; - maxctx.emax = MPD_MAX_EMAX + 21; - maxctx.emin = MPD_MIN_EMIN - 21; - - mpd_qmul(tmp, tmp, exp_hash, &maxctx, &status); - mpd_qrem(tmp, tmp, &p, &maxctx, &status); - - result = mpd_qget_ssize(tmp, &status); - result = mpd_ispositive(MPD(v)) ? result : -result; - result = (result == -1) ? -2 : result; - - if (status != 0) { - if (status & MPD_Malloc_error) { - goto malloc_error; - } - else { - PyErr_SetString(PyExc_RuntimeError, /* GCOV_NOT_REACHED */ - "dec_hash: internal error: please report"); /* GCOV_NOT_REACHED */ - } - result = -1; /* GCOV_NOT_REACHED */ - } - - -finish: - if (exp_hash) mpd_del(exp_hash); - if (tmp) mpd_del(tmp); - return result; - -malloc_error: - PyErr_NoMemory(); - result = -1; - goto finish; -} - -static Py_hash_t -dec_hash(PyDecObject *self) -{ - if (self->hash == -1) { - self->hash = _dec_hash(self); - } - - return self->hash; -} - -/* __reduce__ */ -static PyObject * -dec_reduce(PyObject *self, PyObject *dummy UNUSED) -{ - PyObject *result, *str; - - str = dec_str(self); - if (str == NULL) { - return NULL; - } - - result = Py_BuildValue("O(O)", Py_TYPE(self), str); - Py_DECREF(str); - - return result; -} - -/* __sizeof__ */ -static PyObject * -dec_sizeof(PyObject *v, PyObject *dummy UNUSED) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(v)); - if (mpd_isdynamic_data(MPD(v))) { - res += MPD(v)->alloc * sizeof(mpd_uint_t); - } - return PyLong_FromSsize_t(res); -} - -/* __trunc__ */ -static PyObject * -dec_trunc(PyObject *self, PyObject *dummy UNUSED) -{ - PyObject *context; - - CURRENT_CONTEXT(context); - return dec_as_long(self, context, MPD_ROUND_DOWN); -} - -/* real and imag */ -static PyObject * -dec_real(PyObject *self, void *closure UNUSED) -{ - Py_INCREF(self); - return self; -} - -static PyObject * -dec_imag(PyObject *self UNUSED, void *closure UNUSED) -{ - PyObject *result; - - result = dec_alloc(); - if (result == NULL) { - return NULL; - } - - _dec_settriple(result, MPD_POS, 0, 0); - return result; -} - - -static PyGetSetDef dec_getsets [] = -{ - { "real", (getter)dec_real, NULL, NULL, NULL}, - { "imag", (getter)dec_imag, NULL, NULL, NULL}, - {NULL} -}; - -static PyNumberMethods dec_number_methods = -{ - (binaryfunc) nm_mpd_qadd, - (binaryfunc) nm_mpd_qsub, - (binaryfunc) nm_mpd_qmul, - (binaryfunc) nm_mpd_qrem, - (binaryfunc) nm_mpd_qdivmod, - (ternaryfunc) nm_mpd_qpow, - (unaryfunc) nm_mpd_qminus, - (unaryfunc) nm_mpd_qplus, - (unaryfunc) nm_mpd_qabs, - (inquiry) nm_nonzero, - (unaryfunc) 0, /* no bit-complement */ - (binaryfunc) 0, /* no shiftl */ - (binaryfunc) 0, /* no shiftr */ - (binaryfunc) 0, /* no bit-and */ - (binaryfunc) 0, /* no bit-xor */ - (binaryfunc) 0, /* no bit-ior */ - (unaryfunc) nm_dec_as_long, - 0, /* nb_reserved */ - (unaryfunc) PyDec_AsFloat, - 0, /* binaryfunc nb_inplace_add; */ - 0, /* binaryfunc nb_inplace_subtract; */ - 0, /* binaryfunc nb_inplace_multiply; */ - 0, /* binaryfunc nb_inplace_remainder; */ - 0, /* ternaryfunc nb_inplace_power; */ - 0, /* binaryfunc nb_inplace_lshift; */ - 0, /* binaryfunc nb_inplace_rshift; */ - 0, /* binaryfunc nb_inplace_and; */ - 0, /* binaryfunc nb_inplace_xor; */ - 0, /* binaryfunc nb_inplace_or; */ - (binaryfunc) nm_mpd_qdivint, /* binaryfunc nb_floor_divide; */ - (binaryfunc) nm_mpd_qdiv, /* binaryfunc nb_true_divide; */ - 0, /* binaryfunc nb_inplace_floor_divide; */ - 0, /* binaryfunc nb_inplace_true_divide; */ -}; - -static PyMethodDef dec_methods [] = -{ - /* Unary arithmetic functions, optional context arg */ - { "exp", (PyCFunction)(void(*)(void))dec_mpd_qexp, METH_VARARGS|METH_KEYWORDS, doc_exp }, - { "ln", (PyCFunction)(void(*)(void))dec_mpd_qln, METH_VARARGS|METH_KEYWORDS, doc_ln }, - { "log10", (PyCFunction)(void(*)(void))dec_mpd_qlog10, METH_VARARGS|METH_KEYWORDS, doc_log10 }, - { "next_minus", (PyCFunction)(void(*)(void))dec_mpd_qnext_minus, METH_VARARGS|METH_KEYWORDS, doc_next_minus }, - { "next_plus", (PyCFunction)(void(*)(void))dec_mpd_qnext_plus, METH_VARARGS|METH_KEYWORDS, doc_next_plus }, - { "normalize", (PyCFunction)(void(*)(void))dec_mpd_qreduce, METH_VARARGS|METH_KEYWORDS, doc_normalize }, - { "to_integral", (PyCFunction)(void(*)(void))PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral }, - { "to_integral_exact", (PyCFunction)(void(*)(void))PyDec_ToIntegralExact, METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact }, - { "to_integral_value", (PyCFunction)(void(*)(void))PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral_value }, - { "sqrt", (PyCFunction)(void(*)(void))dec_mpd_qsqrt, METH_VARARGS|METH_KEYWORDS, doc_sqrt }, - - /* Binary arithmetic functions, optional context arg */ - { "compare", (PyCFunction)(void(*)(void))dec_mpd_qcompare, METH_VARARGS|METH_KEYWORDS, doc_compare }, - { "compare_signal", (PyCFunction)(void(*)(void))dec_mpd_qcompare_signal, METH_VARARGS|METH_KEYWORDS, doc_compare_signal }, - { "max", (PyCFunction)(void(*)(void))dec_mpd_qmax, METH_VARARGS|METH_KEYWORDS, doc_max }, - { "max_mag", (PyCFunction)(void(*)(void))dec_mpd_qmax_mag, METH_VARARGS|METH_KEYWORDS, doc_max_mag }, - { "min", (PyCFunction)(void(*)(void))dec_mpd_qmin, METH_VARARGS|METH_KEYWORDS, doc_min }, - { "min_mag", (PyCFunction)(void(*)(void))dec_mpd_qmin_mag, METH_VARARGS|METH_KEYWORDS, doc_min_mag }, - { "next_toward", (PyCFunction)(void(*)(void))dec_mpd_qnext_toward, METH_VARARGS|METH_KEYWORDS, doc_next_toward }, - { "quantize", (PyCFunction)(void(*)(void))dec_mpd_qquantize, METH_VARARGS|METH_KEYWORDS, doc_quantize }, - { "remainder_near", (PyCFunction)(void(*)(void))dec_mpd_qrem_near, METH_VARARGS|METH_KEYWORDS, doc_remainder_near }, - - /* Ternary arithmetic functions, optional context arg */ - { "fma", (PyCFunction)(void(*)(void))dec_mpd_qfma, METH_VARARGS|METH_KEYWORDS, doc_fma }, - - /* Boolean functions, no context arg */ - { "is_canonical", dec_mpd_iscanonical, METH_NOARGS, doc_is_canonical }, - { "is_finite", dec_mpd_isfinite, METH_NOARGS, doc_is_finite }, - { "is_infinite", dec_mpd_isinfinite, METH_NOARGS, doc_is_infinite }, - { "is_nan", dec_mpd_isnan, METH_NOARGS, doc_is_nan }, - { "is_qnan", dec_mpd_isqnan, METH_NOARGS, doc_is_qnan }, - { "is_snan", dec_mpd_issnan, METH_NOARGS, doc_is_snan }, - { "is_signed", dec_mpd_issigned, METH_NOARGS, doc_is_signed }, - { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero }, - - /* Boolean functions, optional context arg */ - { "is_normal", (PyCFunction)(void(*)(void))dec_mpd_isnormal, METH_VARARGS|METH_KEYWORDS, doc_is_normal }, - { "is_subnormal", (PyCFunction)(void(*)(void))dec_mpd_issubnormal, METH_VARARGS|METH_KEYWORDS, doc_is_subnormal }, - - /* Unary functions, no context arg */ - { "adjusted", dec_mpd_adjexp, METH_NOARGS, doc_adjusted }, - { "canonical", dec_canonical, METH_NOARGS, doc_canonical }, - { "conjugate", dec_conjugate, METH_NOARGS, doc_conjugate }, - { "radix", dec_mpd_radix, METH_NOARGS, doc_radix }, - - /* Unary functions, optional context arg for conversion errors */ - { "copy_abs", dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs }, - { "copy_negate", dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate }, - - /* Unary functions, optional context arg */ - { "logb", (PyCFunction)(void(*)(void))dec_mpd_qlogb, METH_VARARGS|METH_KEYWORDS, doc_logb }, - { "logical_invert", (PyCFunction)(void(*)(void))dec_mpd_qinvert, METH_VARARGS|METH_KEYWORDS, doc_logical_invert }, - { "number_class", (PyCFunction)(void(*)(void))dec_mpd_class, METH_VARARGS|METH_KEYWORDS, doc_number_class }, - { "to_eng_string", (PyCFunction)(void(*)(void))dec_mpd_to_eng, METH_VARARGS|METH_KEYWORDS, doc_to_eng_string }, - - /* Binary functions, optional context arg for conversion errors */ - { "compare_total", (PyCFunction)(void(*)(void))dec_mpd_compare_total, METH_VARARGS|METH_KEYWORDS, doc_compare_total }, - { "compare_total_mag", (PyCFunction)(void(*)(void))dec_mpd_compare_total_mag, METH_VARARGS|METH_KEYWORDS, doc_compare_total_mag }, - { "copy_sign", (PyCFunction)(void(*)(void))dec_mpd_qcopy_sign, METH_VARARGS|METH_KEYWORDS, doc_copy_sign }, - { "same_quantum", (PyCFunction)(void(*)(void))dec_mpd_same_quantum, METH_VARARGS|METH_KEYWORDS, doc_same_quantum }, - - /* Binary functions, optional context arg */ - { "logical_and", (PyCFunction)(void(*)(void))dec_mpd_qand, METH_VARARGS|METH_KEYWORDS, doc_logical_and }, - { "logical_or", (PyCFunction)(void(*)(void))dec_mpd_qor, METH_VARARGS|METH_KEYWORDS, doc_logical_or }, - { "logical_xor", (PyCFunction)(void(*)(void))dec_mpd_qxor, METH_VARARGS|METH_KEYWORDS, doc_logical_xor }, - { "rotate", (PyCFunction)(void(*)(void))dec_mpd_qrotate, METH_VARARGS|METH_KEYWORDS, doc_rotate }, - { "scaleb", (PyCFunction)(void(*)(void))dec_mpd_qscaleb, METH_VARARGS|METH_KEYWORDS, doc_scaleb }, - { "shift", (PyCFunction)(void(*)(void))dec_mpd_qshift, METH_VARARGS|METH_KEYWORDS, doc_shift }, - - /* Miscellaneous */ - { "from_float", dec_from_float, METH_O|METH_CLASS, doc_from_float }, - { "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple }, - { "as_integer_ratio", dec_as_integer_ratio, METH_NOARGS, doc_as_integer_ratio }, - - /* Special methods */ - { "__copy__", dec_copy, METH_NOARGS, NULL }, - { "__deepcopy__", dec_copy, METH_O, NULL }, - { "__format__", dec_format, METH_VARARGS, NULL }, - { "__reduce__", dec_reduce, METH_NOARGS, NULL }, - { "__round__", PyDec_Round, METH_VARARGS, NULL }, - { "__ceil__", dec_ceil, METH_NOARGS, NULL }, - { "__floor__", dec_floor, METH_NOARGS, NULL }, - { "__trunc__", dec_trunc, METH_NOARGS, NULL }, - { "__complex__", dec_complex, METH_NOARGS, NULL }, - { "__sizeof__", dec_sizeof, METH_NOARGS, NULL }, - - { NULL, NULL, 1 } -}; - -static PyTypeObject PyDec_Type = -{ - PyVarObject_HEAD_INIT(NULL, 0) - "decimal.Decimal", /* tp_name */ - sizeof(PyDecObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor) dec_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - (getattrfunc) 0, /* tp_getattr */ - (setattrfunc) 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc) dec_repr, /* tp_repr */ - &dec_number_methods, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc) dec_hash, /* tp_hash */ - 0, /* tp_call */ - (reprfunc) dec_str, /* tp_str */ - (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */ - (setattrofunc) 0, /* tp_setattro */ - (PyBufferProcs *) 0, /* tp_as_buffer */ - (Py_TPFLAGS_DEFAULT| - Py_TPFLAGS_BASETYPE), /* tp_flags */ - doc_decimal, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - dec_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - dec_methods, /* tp_methods */ - 0, /* tp_members */ - dec_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - dec_new, /* tp_new */ - PyObject_Del, /* tp_free */ -}; - - -/******************************************************************************/ -/* Context Object, Part 2 */ -/******************************************************************************/ - - -/************************************************************************/ -/* Macros for converting mpdecimal functions to Context methods */ -/************************************************************************/ - -/* Boolean context method. */ -#define DecCtx_BoolFunc(MPDFUNC) \ -static PyObject * \ -ctx_##MPDFUNC(PyObject *context, PyObject *v) \ -{ \ - PyObject *ret; \ - PyObject *a; \ - \ - CONVERT_OP_RAISE(&a, v, context); \ - \ - ret = MPDFUNC(MPD(a), CTX(context)) ? incr_true() : incr_false(); \ - Py_DECREF(a); \ - return ret; \ -} - -/* Boolean context method. MPDFUNC does NOT use a context. */ -#define DecCtx_BoolFunc_NO_CTX(MPDFUNC) \ -static PyObject * \ -ctx_##MPDFUNC(PyObject *context, PyObject *v) \ -{ \ - PyObject *ret; \ - PyObject *a; \ - \ - CONVERT_OP_RAISE(&a, v, context); \ - \ - ret = MPDFUNC(MPD(a)) ? incr_true() : incr_false(); \ - Py_DECREF(a); \ - return ret; \ -} - -/* Unary context method. */ -#define DecCtx_UnaryFunc(MPDFUNC) \ -static PyObject * \ -ctx_##MPDFUNC(PyObject *context, PyObject *v) \ -{ \ - PyObject *result, *a; \ - uint32_t status = 0; \ - \ - CONVERT_OP_RAISE(&a, v, context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - Py_DECREF(a); \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(a), CTX(context), &status); \ - Py_DECREF(a); \ - if (dec_addstatus(context, status)) { \ - Py_DECREF(result); \ - return NULL; \ - } \ - \ - return result; \ -} - -/* Binary context method. */ -#define DecCtx_BinaryFunc(MPDFUNC) \ -static PyObject * \ -ctx_##MPDFUNC(PyObject *context, PyObject *args) \ -{ \ - PyObject *v, *w; \ - PyObject *a, *b; \ - PyObject *result; \ - uint32_t status = 0; \ - \ - if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \ - return NULL; \ - } \ - \ - CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - Py_DECREF(a); \ - Py_DECREF(b); \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ - Py_DECREF(a); \ - Py_DECREF(b); \ - if (dec_addstatus(context, status)) { \ - Py_DECREF(result); \ - return NULL; \ - } \ - \ - return result; \ -} - -/* - * Binary context method. The context is only used for conversion. - * The actual MPDFUNC does NOT take a context arg. - */ -#define DecCtx_BinaryFunc_NO_CTX(MPDFUNC) \ -static PyObject * \ -ctx_##MPDFUNC(PyObject *context, PyObject *args) \ -{ \ - PyObject *v, *w; \ - PyObject *a, *b; \ - PyObject *result; \ - \ - if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \ - return NULL; \ - } \ - \ - CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - Py_DECREF(a); \ - Py_DECREF(b); \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(a), MPD(b)); \ - Py_DECREF(a); \ - Py_DECREF(b); \ - \ - return result; \ -} - -/* Ternary context method. */ -#define DecCtx_TernaryFunc(MPDFUNC) \ -static PyObject * \ -ctx_##MPDFUNC(PyObject *context, PyObject *args) \ -{ \ - PyObject *v, *w, *x; \ - PyObject *a, *b, *c; \ - PyObject *result; \ - uint32_t status = 0; \ - \ - if (!PyArg_ParseTuple(args, "OOO", &v, &w, &x)) { \ - return NULL; \ - } \ - \ - CONVERT_TERNOP_RAISE(&a, &b, &c, v, w, x, context); \ - \ - if ((result = dec_alloc()) == NULL) { \ - Py_DECREF(a); \ - Py_DECREF(b); \ - Py_DECREF(c); \ - return NULL; \ - } \ - \ - MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \ - Py_DECREF(a); \ - Py_DECREF(b); \ - Py_DECREF(c); \ - if (dec_addstatus(context, status)) { \ - Py_DECREF(result); \ - return NULL; \ - } \ - \ - return result; \ -} - - -/* Unary arithmetic functions */ -DecCtx_UnaryFunc(mpd_qabs) -DecCtx_UnaryFunc(mpd_qexp) -DecCtx_UnaryFunc(mpd_qln) -DecCtx_UnaryFunc(mpd_qlog10) -DecCtx_UnaryFunc(mpd_qminus) -DecCtx_UnaryFunc(mpd_qnext_minus) -DecCtx_UnaryFunc(mpd_qnext_plus) -DecCtx_UnaryFunc(mpd_qplus) -DecCtx_UnaryFunc(mpd_qreduce) -DecCtx_UnaryFunc(mpd_qround_to_int) -DecCtx_UnaryFunc(mpd_qround_to_intx) -DecCtx_UnaryFunc(mpd_qsqrt) - -/* Binary arithmetic functions */ -DecCtx_BinaryFunc(mpd_qadd) -DecCtx_BinaryFunc(mpd_qcompare) -DecCtx_BinaryFunc(mpd_qcompare_signal) -DecCtx_BinaryFunc(mpd_qdiv) -DecCtx_BinaryFunc(mpd_qdivint) -DecCtx_BinaryFunc(mpd_qmax) -DecCtx_BinaryFunc(mpd_qmax_mag) -DecCtx_BinaryFunc(mpd_qmin) -DecCtx_BinaryFunc(mpd_qmin_mag) -DecCtx_BinaryFunc(mpd_qmul) -DecCtx_BinaryFunc(mpd_qnext_toward) -DecCtx_BinaryFunc(mpd_qquantize) -DecCtx_BinaryFunc(mpd_qrem) -DecCtx_BinaryFunc(mpd_qrem_near) -DecCtx_BinaryFunc(mpd_qsub) - -static PyObject * -ctx_mpd_qdivmod(PyObject *context, PyObject *args) -{ - PyObject *v, *w; - PyObject *a, *b; - PyObject *q, *r; - uint32_t status = 0; - PyObject *ret; - - if (!PyArg_ParseTuple(args, "OO", &v, &w)) { - return NULL; - } - - CONVERT_BINOP_RAISE(&a, &b, v, w, context); - - q = dec_alloc(); - if (q == NULL) { - Py_DECREF(a); - Py_DECREF(b); - return NULL; - } - r = dec_alloc(); - if (r == NULL) { - Py_DECREF(a); - Py_DECREF(b); - Py_DECREF(q); - return NULL; - } - - mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status); - Py_DECREF(a); - Py_DECREF(b); - if (dec_addstatus(context, status)) { - Py_DECREF(r); - Py_DECREF(q); - return NULL; - } - - ret = Py_BuildValue("(OO)", q, r); - Py_DECREF(r); - Py_DECREF(q); - return ret; -} - -/* Binary or ternary arithmetic functions */ -static PyObject * -ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"a", "b", "modulo", NULL}; - PyObject *base, *exp, *mod = Py_None; - PyObject *a, *b, *c = NULL; - PyObject *result; - uint32_t status = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, - &base, &exp, &mod)) { - return NULL; - } - - CONVERT_BINOP_RAISE(&a, &b, base, exp, context); - - if (mod != Py_None) { - if (!convert_op(TYPE_ERR, &c, mod, context)) { - Py_DECREF(a); - Py_DECREF(b); - return c; - } - } - - result = dec_alloc(); - if (result == NULL) { - Py_DECREF(a); - Py_DECREF(b); - Py_XDECREF(c); - return NULL; - } - - if (c == NULL) { - mpd_qpow(MPD(result), MPD(a), MPD(b), - CTX(context), &status); - } - else { - mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c), - CTX(context), &status); - Py_DECREF(c); - } - Py_DECREF(a); - Py_DECREF(b); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -/* Ternary arithmetic functions */ -DecCtx_TernaryFunc(mpd_qfma) - -/* No argument */ -static PyObject * -ctx_mpd_radix(PyObject *context, PyObject *dummy) -{ - return dec_mpd_radix(context, dummy); -} - -/* Boolean functions: single decimal argument */ -DecCtx_BoolFunc(mpd_isnormal) -DecCtx_BoolFunc(mpd_issubnormal) -DecCtx_BoolFunc_NO_CTX(mpd_isfinite) -DecCtx_BoolFunc_NO_CTX(mpd_isinfinite) -DecCtx_BoolFunc_NO_CTX(mpd_isnan) -DecCtx_BoolFunc_NO_CTX(mpd_isqnan) -DecCtx_BoolFunc_NO_CTX(mpd_issigned) -DecCtx_BoolFunc_NO_CTX(mpd_issnan) -DecCtx_BoolFunc_NO_CTX(mpd_iszero) - -static PyObject * -ctx_iscanonical(PyObject *context UNUSED, PyObject *v) -{ - if (!PyDec_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "argument must be a Decimal"); - return NULL; - } - - return mpd_iscanonical(MPD(v)) ? incr_true() : incr_false(); -} - -/* Functions with a single decimal argument */ -static PyObject * -PyDecContext_Apply(PyObject *context, PyObject *v) -{ - PyObject *result, *a; - - CONVERT_OP_RAISE(&a, v, context); - - result = dec_apply(a, context); - Py_DECREF(a); - return result; -} - -static PyObject * -ctx_canonical(PyObject *context UNUSED, PyObject *v) -{ - if (!PyDec_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "argument must be a Decimal"); - return NULL; - } - - Py_INCREF(v); - return v; -} - -static PyObject * -ctx_mpd_qcopy_abs(PyObject *context, PyObject *v) -{ - PyObject *result, *a; - uint32_t status = 0; - - CONVERT_OP_RAISE(&a, v, context); - - result = dec_alloc(); - if (result == NULL) { - Py_DECREF(a); - return NULL; - } - - mpd_qcopy_abs(MPD(result), MPD(a), &status); - Py_DECREF(a); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -static PyObject * -ctx_copy_decimal(PyObject *context, PyObject *v) -{ - PyObject *result; - - CONVERT_OP_RAISE(&result, v, context); - return result; -} - -static PyObject * -ctx_mpd_qcopy_negate(PyObject *context, PyObject *v) -{ - PyObject *result, *a; - uint32_t status = 0; - - CONVERT_OP_RAISE(&a, v, context); - - result = dec_alloc(); - if (result == NULL) { - Py_DECREF(a); - return NULL; - } - - mpd_qcopy_negate(MPD(result), MPD(a), &status); - Py_DECREF(a); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -DecCtx_UnaryFunc(mpd_qlogb) -DecCtx_UnaryFunc(mpd_qinvert) - -static PyObject * -ctx_mpd_class(PyObject *context, PyObject *v) -{ - PyObject *a; - const char *cp; - - CONVERT_OP_RAISE(&a, v, context); - - cp = mpd_class(MPD(a), CTX(context)); - Py_DECREF(a); - - return PyUnicode_FromString(cp); -} - -static PyObject * -ctx_mpd_to_sci(PyObject *context, PyObject *v) -{ - PyObject *result; - PyObject *a; - mpd_ssize_t size; - char *s; - - CONVERT_OP_RAISE(&a, v, context); - - size = mpd_to_sci_size(&s, MPD(a), CtxCaps(context)); - Py_DECREF(a); - if (size < 0) { - PyErr_NoMemory(); - return NULL; - } - - result = unicode_fromascii(s, size); - mpd_free(s); - - return result; -} - -static PyObject * -ctx_mpd_to_eng(PyObject *context, PyObject *v) -{ - PyObject *result; - PyObject *a; - mpd_ssize_t size; - char *s; - - CONVERT_OP_RAISE(&a, v, context); - - size = mpd_to_eng_size(&s, MPD(a), CtxCaps(context)); - Py_DECREF(a); - if (size < 0) { - PyErr_NoMemory(); - return NULL; - } - - result = unicode_fromascii(s, size); - mpd_free(s); - - return result; -} - -/* Functions with two decimal arguments */ -DecCtx_BinaryFunc_NO_CTX(mpd_compare_total) -DecCtx_BinaryFunc_NO_CTX(mpd_compare_total_mag) - -static PyObject * -ctx_mpd_qcopy_sign(PyObject *context, PyObject *args) -{ - PyObject *v, *w; - PyObject *a, *b; - PyObject *result; - uint32_t status = 0; - - if (!PyArg_ParseTuple(args, "OO", &v, &w)) { - return NULL; - } - - CONVERT_BINOP_RAISE(&a, &b, v, w, context); - - result = dec_alloc(); - if (result == NULL) { - Py_DECREF(a); - Py_DECREF(b); - return NULL; - } - - mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status); - Py_DECREF(a); - Py_DECREF(b); - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -DecCtx_BinaryFunc(mpd_qand) -DecCtx_BinaryFunc(mpd_qor) -DecCtx_BinaryFunc(mpd_qxor) - -DecCtx_BinaryFunc(mpd_qrotate) -DecCtx_BinaryFunc(mpd_qscaleb) -DecCtx_BinaryFunc(mpd_qshift) - -static PyObject * -ctx_mpd_same_quantum(PyObject *context, PyObject *args) -{ - PyObject *v, *w; - PyObject *a, *b; - PyObject *result; - - if (!PyArg_ParseTuple(args, "OO", &v, &w)) { - return NULL; - } - - CONVERT_BINOP_RAISE(&a, &b, v, w, context); - - result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false(); - Py_DECREF(a); - Py_DECREF(b); - - return result; -} - - -static PyMethodDef context_methods [] = -{ - /* Unary arithmetic functions */ - { "abs", ctx_mpd_qabs, METH_O, doc_ctx_abs }, - { "exp", ctx_mpd_qexp, METH_O, doc_ctx_exp }, - { "ln", ctx_mpd_qln, METH_O, doc_ctx_ln }, - { "log10", ctx_mpd_qlog10, METH_O, doc_ctx_log10 }, - { "minus", ctx_mpd_qminus, METH_O, doc_ctx_minus }, - { "next_minus", ctx_mpd_qnext_minus, METH_O, doc_ctx_next_minus }, - { "next_plus", ctx_mpd_qnext_plus, METH_O, doc_ctx_next_plus }, - { "normalize", ctx_mpd_qreduce, METH_O, doc_ctx_normalize }, - { "plus", ctx_mpd_qplus, METH_O, doc_ctx_plus }, - { "to_integral", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral }, - { "to_integral_exact", ctx_mpd_qround_to_intx, METH_O, doc_ctx_to_integral_exact }, - { "to_integral_value", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral_value }, - { "sqrt", ctx_mpd_qsqrt, METH_O, doc_ctx_sqrt }, - - /* Binary arithmetic functions */ - { "add", ctx_mpd_qadd, METH_VARARGS, doc_ctx_add }, - { "compare", ctx_mpd_qcompare, METH_VARARGS, doc_ctx_compare }, - { "compare_signal", ctx_mpd_qcompare_signal, METH_VARARGS, doc_ctx_compare_signal }, - { "divide", ctx_mpd_qdiv, METH_VARARGS, doc_ctx_divide }, - { "divide_int", ctx_mpd_qdivint, METH_VARARGS, doc_ctx_divide_int }, - { "divmod", ctx_mpd_qdivmod, METH_VARARGS, doc_ctx_divmod }, - { "max", ctx_mpd_qmax, METH_VARARGS, doc_ctx_max }, - { "max_mag", ctx_mpd_qmax_mag, METH_VARARGS, doc_ctx_max_mag }, - { "min", ctx_mpd_qmin, METH_VARARGS, doc_ctx_min }, - { "min_mag", ctx_mpd_qmin_mag, METH_VARARGS, doc_ctx_min_mag }, - { "multiply", ctx_mpd_qmul, METH_VARARGS, doc_ctx_multiply }, - { "next_toward", ctx_mpd_qnext_toward, METH_VARARGS, doc_ctx_next_toward }, - { "quantize", ctx_mpd_qquantize, METH_VARARGS, doc_ctx_quantize }, - { "remainder", ctx_mpd_qrem, METH_VARARGS, doc_ctx_remainder }, - { "remainder_near", ctx_mpd_qrem_near, METH_VARARGS, doc_ctx_remainder_near }, - { "subtract", ctx_mpd_qsub, METH_VARARGS, doc_ctx_subtract }, - - /* Binary or ternary arithmetic functions */ - { "power", (PyCFunction)(void(*)(void))ctx_mpd_qpow, METH_VARARGS|METH_KEYWORDS, doc_ctx_power }, - - /* Ternary arithmetic functions */ - { "fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma }, - - /* No argument */ - { "Etiny", context_getetiny, METH_NOARGS, doc_ctx_Etiny }, - { "Etop", context_getetop, METH_NOARGS, doc_ctx_Etop }, - { "radix", ctx_mpd_radix, METH_NOARGS, doc_ctx_radix }, - - /* Boolean functions */ - { "is_canonical", ctx_iscanonical, METH_O, doc_ctx_is_canonical }, - { "is_finite", ctx_mpd_isfinite, METH_O, doc_ctx_is_finite }, - { "is_infinite", ctx_mpd_isinfinite, METH_O, doc_ctx_is_infinite }, - { "is_nan", ctx_mpd_isnan, METH_O, doc_ctx_is_nan }, - { "is_normal", ctx_mpd_isnormal, METH_O, doc_ctx_is_normal }, - { "is_qnan", ctx_mpd_isqnan, METH_O, doc_ctx_is_qnan }, - { "is_signed", ctx_mpd_issigned, METH_O, doc_ctx_is_signed }, - { "is_snan", ctx_mpd_issnan, METH_O, doc_ctx_is_snan }, - { "is_subnormal", ctx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal }, - { "is_zero", ctx_mpd_iszero, METH_O, doc_ctx_is_zero }, - - /* Functions with a single decimal argument */ - { "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */ -#ifdef EXTRA_FUNCTIONALITY - { "apply", PyDecContext_Apply, METH_O, doc_ctx_apply }, -#endif - { "canonical", ctx_canonical, METH_O, doc_ctx_canonical }, - { "copy_abs", ctx_mpd_qcopy_abs, METH_O, doc_ctx_copy_abs }, - { "copy_decimal", ctx_copy_decimal, METH_O, doc_ctx_copy_decimal }, - { "copy_negate", ctx_mpd_qcopy_negate, METH_O, doc_ctx_copy_negate }, - { "logb", ctx_mpd_qlogb, METH_O, doc_ctx_logb }, - { "logical_invert", ctx_mpd_qinvert, METH_O, doc_ctx_logical_invert }, - { "number_class", ctx_mpd_class, METH_O, doc_ctx_number_class }, - { "to_sci_string", ctx_mpd_to_sci, METH_O, doc_ctx_to_sci_string }, - { "to_eng_string", ctx_mpd_to_eng, METH_O, doc_ctx_to_eng_string }, - - /* Functions with two decimal arguments */ - { "compare_total", ctx_mpd_compare_total, METH_VARARGS, doc_ctx_compare_total }, - { "compare_total_mag", ctx_mpd_compare_total_mag, METH_VARARGS, doc_ctx_compare_total_mag }, - { "copy_sign", ctx_mpd_qcopy_sign, METH_VARARGS, doc_ctx_copy_sign }, - { "logical_and", ctx_mpd_qand, METH_VARARGS, doc_ctx_logical_and }, - { "logical_or", ctx_mpd_qor, METH_VARARGS, doc_ctx_logical_or }, - { "logical_xor", ctx_mpd_qxor, METH_VARARGS, doc_ctx_logical_xor }, - { "rotate", ctx_mpd_qrotate, METH_VARARGS, doc_ctx_rotate }, - { "same_quantum", ctx_mpd_same_quantum, METH_VARARGS, doc_ctx_same_quantum }, - { "scaleb", ctx_mpd_qscaleb, METH_VARARGS, doc_ctx_scaleb }, - { "shift", ctx_mpd_qshift, METH_VARARGS, doc_ctx_shift }, - - /* Set context values */ - { "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags }, - { "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps }, - -#ifdef CONFIG_32 - /* Unsafe set functions with relaxed range checks */ - { "_unsafe_setprec", context_unsafe_setprec, METH_O, NULL }, - { "_unsafe_setemin", context_unsafe_setemin, METH_O, NULL }, - { "_unsafe_setemax", context_unsafe_setemax, METH_O, NULL }, +init_current_context(void) +{ + PyObject *tl_context = context_copy(default_context_template, NULL); + if (tl_context == NULL) { + return NULL; + } + CTX(tl_context)->status = 0; + + PyObject *tok = PyContextVar_Set(current_context_var, tl_context); + if (tok == NULL) { + Py_DECREF(tl_context); + return NULL; + } + Py_DECREF(tok); + + return tl_context; +} + +static inline PyObject * +current_context(void) +{ + PyObject *tl_context; + if (PyContextVar_Get(current_context_var, NULL, &tl_context) < 0) { + return NULL; + } + + if (tl_context != NULL) { + return tl_context; + } + + return init_current_context(); +} + +/* ctxobj := borrowed reference to the current context */ +#define CURRENT_CONTEXT(ctxobj) \ + ctxobj = current_context(); \ + if (ctxobj == NULL) { \ + return NULL; \ + } \ + Py_DECREF(ctxobj); + +/* Return a new reference to the current context */ +static PyObject * +PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) +{ + return current_context(); +} + +/* Set the thread local context to a new context, decrement old reference */ +static PyObject * +PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) +{ + CONTEXT_CHECK(v); + + /* If the new context is one of the templates, make a copy. + * This is the current behavior of decimal.py. */ + if (v == default_context_template || + v == basic_context_template || + v == extended_context_template) { + v = context_copy(v, NULL); + if (v == NULL) { + return NULL; + } + CTX(v)->status = 0; + } + else { + Py_INCREF(v); + } + + PyObject *tok = PyContextVar_Set(current_context_var, v); + Py_DECREF(v); + if (tok == NULL) { + return NULL; + } + Py_DECREF(tok); + + Py_RETURN_NONE; +} #endif - - /* Miscellaneous */ - { "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL }, - { "__reduce__", context_reduce, METH_NOARGS, NULL }, - { "copy", (PyCFunction)context_copy, METH_NOARGS, doc_ctx_copy }, - { "create_decimal", ctx_create_decimal, METH_VARARGS, doc_ctx_create_decimal }, - { "create_decimal_from_float", ctx_from_float, METH_O, doc_ctx_create_decimal_from_float }, - - { NULL, NULL, 1 } -}; - -static PyTypeObject PyDecContext_Type = -{ - PyVarObject_HEAD_INIT(NULL, 0) - "decimal.Context", /* tp_name */ - sizeof(PyDecContextObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor) context_dealloc, /* tp_dealloc */ + +/* Context manager object for the 'with' statement. The manager + * owns one reference to the global (outer) context and one + * to the local (inner) context. */ +static PyObject * +ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"ctx", NULL}; + PyDecContextManagerObject *self; + PyObject *local = Py_None; + PyObject *global; + + CURRENT_CONTEXT(global); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &local)) { + return NULL; + } + if (local == Py_None) { + local = global; + } + else if (!PyDecContext_Check(local)) { + PyErr_SetString(PyExc_TypeError, + "optional argument must be a context"); + return NULL; + } + + self = PyObject_New(PyDecContextManagerObject, + &PyDecContextManager_Type); + if (self == NULL) { + return NULL; + } + + self->local = context_copy(local, NULL); + if (self->local == NULL) { + self->global = NULL; + Py_DECREF(self); + return NULL; + } + self->global = global; + Py_INCREF(self->global); + + return (PyObject *)self; +} + +static void +ctxmanager_dealloc(PyDecContextManagerObject *self) +{ + Py_XDECREF(self->local); + Py_XDECREF(self->global); + PyObject_Del(self); +} + +static PyObject * +ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED) +{ + PyObject *ret; + + ret = PyDec_SetCurrentContext(NULL, self->local); + if (ret == NULL) { + return NULL; + } + Py_DECREF(ret); + + Py_INCREF(self->local); + return self->local; +} + +static PyObject * +ctxmanager_restore_global(PyDecContextManagerObject *self, + PyObject *args UNUSED) +{ + PyObject *ret; + + ret = PyDec_SetCurrentContext(NULL, self->global); + if (ret == NULL) { + return NULL; + } + Py_DECREF(ret); + + Py_RETURN_NONE; +} + + +static PyMethodDef ctxmanager_methods[] = { + {"__enter__", (PyCFunction)ctxmanager_set_local, METH_NOARGS, NULL}, + {"__exit__", (PyCFunction)ctxmanager_restore_global, METH_VARARGS, NULL}, + {NULL, NULL} +}; + +static PyTypeObject PyDecContextManager_Type = +{ + PyVarObject_HEAD_INIT(NULL, 0) + "decimal.ContextManager", /* tp_name */ + sizeof(PyDecContextManagerObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) ctxmanager_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + (getattrfunc) 0, /* tp_getattr */ + (setattrfunc) 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc) 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */ + (setattrofunc) 0, /* tp_setattro */ + (PyBufferProcs *) 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ctxmanager_methods, /* tp_methods */ +}; + + +/******************************************************************************/ +/* New Decimal Object */ +/******************************************************************************/ + +static PyObject * +PyDecType_New(PyTypeObject *type) +{ + PyDecObject *dec; + + if (type == &PyDec_Type) { + dec = PyObject_New(PyDecObject, &PyDec_Type); + } + else { + dec = (PyDecObject *)type->tp_alloc(type, 0); + } + if (dec == NULL) { + return NULL; + } + + dec->hash = -1; + + MPD(dec)->flags = MPD_STATIC|MPD_STATIC_DATA; + MPD(dec)->exp = 0; + MPD(dec)->digits = 0; + MPD(dec)->len = 0; + MPD(dec)->alloc = _Py_DEC_MINALLOC; + MPD(dec)->data = dec->data; + + return (PyObject *)dec; +} +#define dec_alloc() PyDecType_New(&PyDec_Type) + +static void +dec_dealloc(PyObject *dec) +{ + mpd_del(MPD(dec)); + Py_TYPE(dec)->tp_free(dec); +} + + +/******************************************************************************/ +/* Conversions to Decimal */ +/******************************************************************************/ + +Py_LOCAL_INLINE(int) +is_space(enum PyUnicode_Kind kind, const void *data, Py_ssize_t pos) +{ + Py_UCS4 ch = PyUnicode_READ(kind, data, pos); + return Py_UNICODE_ISSPACE(ch); +} + +/* Return the ASCII representation of a numeric Unicode string. The numeric + string may contain ascii characters in the range [1, 127], any Unicode + space and any unicode digit. If strip_ws is true, leading and trailing + whitespace is stripped. If ignore_underscores is true, underscores are + ignored. + + Return NULL if malloc fails and an empty string if invalid characters + are found. */ +static char * +numeric_as_ascii(const PyObject *u, int strip_ws, int ignore_underscores) +{ + enum PyUnicode_Kind kind; + const void *data; + Py_UCS4 ch; + char *res, *cp; + Py_ssize_t j, len; + int d; + + if (PyUnicode_READY(u) == -1) { + return NULL; + } + + kind = PyUnicode_KIND(u); + data = PyUnicode_DATA(u); + len = PyUnicode_GET_LENGTH(u); + + cp = res = PyMem_Malloc(len+1); + if (res == NULL) { + PyErr_NoMemory(); + return NULL; + } + + j = 0; + if (strip_ws) { + while (len > 0 && is_space(kind, data, len-1)) { + len--; + } + while (j < len && is_space(kind, data, j)) { + j++; + } + } + + for (; j < len; j++) { + ch = PyUnicode_READ(kind, data, j); + if (ignore_underscores && ch == '_') { + continue; + } + if (0 < ch && ch <= 127) { + *cp++ = ch; + continue; + } + if (Py_UNICODE_ISSPACE(ch)) { + *cp++ = ' '; + continue; + } + d = Py_UNICODE_TODECIMAL(ch); + if (d < 0) { + /* empty string triggers ConversionSyntax */ + *res = '\0'; + return res; + } + *cp++ = '0' + d; + } + *cp = '\0'; + return res; +} + +/* Return a new PyDecObject or a subtype from a C string. Use the context + during conversion. */ +static PyObject * +PyDecType_FromCString(PyTypeObject *type, const char *s, + PyObject *context) +{ + PyObject *dec; + uint32_t status = 0; + + dec = PyDecType_New(type); + if (dec == NULL) { + return NULL; + } + + mpd_qset_string(MPD(dec), s, CTX(context), &status); + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + return dec; +} + +/* Return a new PyDecObject or a subtype from a C string. Attempt exact + conversion. If the operand cannot be converted exactly, set + InvalidOperation. */ +static PyObject * +PyDecType_FromCStringExact(PyTypeObject *type, const char *s, + PyObject *context) +{ + PyObject *dec; + uint32_t status = 0; + mpd_context_t maxctx; + + dec = PyDecType_New(type); + if (dec == NULL) { + return NULL; + } + + mpd_maxcontext(&maxctx); + + mpd_qset_string(MPD(dec), s, &maxctx, &status); + if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + /* we want exact results */ + mpd_seterror(MPD(dec), MPD_Invalid_operation, &status); + } + status &= MPD_Errors; + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + + return dec; +} + +/* Return a new PyDecObject or a subtype from a PyUnicodeObject. */ +static PyObject * +PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u, + PyObject *context) +{ + PyObject *dec; + char *s; + + s = numeric_as_ascii(u, 0, 0); + if (s == NULL) { + return NULL; + } + + dec = PyDecType_FromCString(type, s, context); + PyMem_Free(s); + return dec; +} + +/* Return a new PyDecObject or a subtype from a PyUnicodeObject. Attempt exact + * conversion. If the conversion is not exact, fail with InvalidOperation. + * Allow leading and trailing whitespace in the input operand. */ +static PyObject * +PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u, + PyObject *context) +{ + PyObject *dec; + char *s; + + s = numeric_as_ascii(u, 1, 1); + if (s == NULL) { + return NULL; + } + + dec = PyDecType_FromCStringExact(type, s, context); + PyMem_Free(s); + return dec; +} + +/* Set PyDecObject from triple without any error checking. */ +Py_LOCAL_INLINE(void) +_dec_settriple(PyObject *dec, uint8_t sign, uint32_t v, mpd_ssize_t exp) +{ + +#ifdef CONFIG_64 + MPD(dec)->data[0] = v; + MPD(dec)->len = 1; +#else + uint32_t q, r; + q = v / MPD_RADIX; + r = v - q * MPD_RADIX; + MPD(dec)->data[1] = q; + MPD(dec)->data[0] = r; + MPD(dec)->len = q ? 2 : 1; +#endif + mpd_set_flags(MPD(dec), sign); + MPD(dec)->exp = exp; + mpd_setdigits(MPD(dec)); +} + +/* Return a new PyDecObject from an mpd_ssize_t. */ +static PyObject * +PyDecType_FromSsize(PyTypeObject *type, mpd_ssize_t v, PyObject *context) +{ + PyObject *dec; + uint32_t status = 0; + + dec = PyDecType_New(type); + if (dec == NULL) { + return NULL; + } + + mpd_qset_ssize(MPD(dec), v, CTX(context), &status); + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + return dec; +} + +/* Return a new PyDecObject from an mpd_ssize_t. Conversion is exact. */ +static PyObject * +PyDecType_FromSsizeExact(PyTypeObject *type, mpd_ssize_t v, PyObject *context) +{ + PyObject *dec; + uint32_t status = 0; + mpd_context_t maxctx; + + dec = PyDecType_New(type); + if (dec == NULL) { + return NULL; + } + + mpd_maxcontext(&maxctx); + + mpd_qset_ssize(MPD(dec), v, &maxctx, &status); + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + return dec; +} + +/* Convert from a PyLongObject. The context is not modified; flags set + during conversion are accumulated in the status parameter. */ +static PyObject * +dec_from_long(PyTypeObject *type, const PyObject *v, + const mpd_context_t *ctx, uint32_t *status) +{ + PyObject *dec; + PyLongObject *l = (PyLongObject *)v; + Py_ssize_t ob_size; + size_t len; + uint8_t sign; + + dec = PyDecType_New(type); + if (dec == NULL) { + return NULL; + } + + ob_size = Py_SIZE(l); + if (ob_size == 0) { + _dec_settriple(dec, MPD_POS, 0, 0); + return dec; + } + + if (ob_size < 0) { + len = -ob_size; + sign = MPD_NEG; + } + else { + len = ob_size; + sign = MPD_POS; + } + + if (len == 1) { + _dec_settriple(dec, sign, *l->ob_digit, 0); + mpd_qfinalize(MPD(dec), ctx, status); + return dec; + } + +#if PYLONG_BITS_IN_DIGIT == 30 + mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, + ctx, status); +#elif PYLONG_BITS_IN_DIGIT == 15 + mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, + ctx, status); +#else + #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" +#endif + + return dec; +} + +/* Return a new PyDecObject from a PyLongObject. Use the context for + conversion. */ +static PyObject * +PyDecType_FromLong(PyTypeObject *type, const PyObject *v, PyObject *context) +{ + PyObject *dec; + uint32_t status = 0; + + if (!PyLong_Check(v)) { + PyErr_SetString(PyExc_TypeError, "argument must be an integer"); + return NULL; + } + + dec = dec_from_long(type, v, CTX(context), &status); + if (dec == NULL) { + return NULL; + } + + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + + return dec; +} + +/* Return a new PyDecObject from a PyLongObject. Use a maximum context + for conversion. If the conversion is not exact, set InvalidOperation. */ +static PyObject * +PyDecType_FromLongExact(PyTypeObject *type, const PyObject *v, + PyObject *context) +{ + PyObject *dec; + uint32_t status = 0; + mpd_context_t maxctx; + + if (!PyLong_Check(v)) { + PyErr_SetString(PyExc_TypeError, "argument must be an integer"); + return NULL; + } + + mpd_maxcontext(&maxctx); + dec = dec_from_long(type, v, &maxctx, &status); + if (dec == NULL) { + return NULL; + } + + if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + /* we want exact results */ + mpd_seterror(MPD(dec), MPD_Invalid_operation, &status); + } + status &= MPD_Errors; + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + + return dec; +} + +/* External C-API functions */ +static binaryfunc _py_long_multiply; +static binaryfunc _py_long_floor_divide; +static ternaryfunc _py_long_power; +static unaryfunc _py_float_abs; +static PyCFunction _py_long_bit_length; +static PyCFunction _py_float_as_integer_ratio; + +/* Return a PyDecObject or a subtype from a PyFloatObject. + Conversion is exact. */ +static PyObject * +PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v, + PyObject *context) +{ + PyObject *dec, *tmp; + PyObject *n, *d, *n_d; + mpd_ssize_t k; + double x; + int sign; + mpd_t *d1, *d2; + uint32_t status = 0; + mpd_context_t maxctx; + + + assert(PyType_IsSubtype(type, &PyDec_Type)); + + if (PyLong_Check(v)) { + return PyDecType_FromLongExact(type, v, context); + } + if (!PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "argument must be int or float"); + return NULL; + } + + x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } + sign = (copysign(1.0, x) == 1.0) ? 0 : 1; + + if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { + dec = PyDecType_New(type); + if (dec == NULL) { + return NULL; + } + if (Py_IS_NAN(x)) { + /* decimal.py calls repr(float(+-nan)), + * which always gives a positive result. */ + mpd_setspecial(MPD(dec), MPD_POS, MPD_NAN); + } + else { + mpd_setspecial(MPD(dec), sign, MPD_INF); + } + return dec; + } + + /* absolute value of the float */ + tmp = _py_float_abs(v); + if (tmp == NULL) { + return NULL; + } + + /* float as integer ratio: numerator/denominator */ + n_d = _py_float_as_integer_ratio(tmp, NULL); + Py_DECREF(tmp); + if (n_d == NULL) { + return NULL; + } + n = PyTuple_GET_ITEM(n_d, 0); + d = PyTuple_GET_ITEM(n_d, 1); + + tmp = _py_long_bit_length(d, NULL); + if (tmp == NULL) { + Py_DECREF(n_d); + return NULL; + } + k = PyLong_AsSsize_t(tmp); + Py_DECREF(tmp); + if (k == -1 && PyErr_Occurred()) { + Py_DECREF(n_d); + return NULL; + } + k--; + + dec = PyDecType_FromLongExact(type, n, context); + Py_DECREF(n_d); + if (dec == NULL) { + return NULL; + } + + d1 = mpd_qnew(); + if (d1 == NULL) { + Py_DECREF(dec); + PyErr_NoMemory(); + return NULL; + } + d2 = mpd_qnew(); + if (d2 == NULL) { + mpd_del(d1); + Py_DECREF(dec); + PyErr_NoMemory(); + return NULL; + } + + mpd_maxcontext(&maxctx); + mpd_qset_uint(d1, 5, &maxctx, &status); + mpd_qset_ssize(d2, k, &maxctx, &status); + mpd_qpow(d1, d1, d2, &maxctx, &status); + if (dec_addstatus(context, status)) { + mpd_del(d1); + mpd_del(d2); + Py_DECREF(dec); + return NULL; + } + + /* result = n * 5**k */ + mpd_qmul(MPD(dec), MPD(dec), d1, &maxctx, &status); + mpd_del(d1); + mpd_del(d2); + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + /* result = +- n * 5**k * 10**-k */ + mpd_set_sign(MPD(dec), sign); + MPD(dec)->exp = -k; + + return dec; +} + +static PyObject * +PyDecType_FromFloat(PyTypeObject *type, PyObject *v, + PyObject *context) +{ + PyObject *dec; + uint32_t status = 0; + + dec = PyDecType_FromFloatExact(type, v, context); + if (dec == NULL) { + return NULL; + } + + mpd_qfinalize(MPD(dec), CTX(context), &status); + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + + return dec; +} + +/* Return a new PyDecObject or a subtype from a Decimal. */ +static PyObject * +PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context) +{ + PyObject *dec; + uint32_t status = 0; + + if (type == &PyDec_Type && PyDec_CheckExact(v)) { + Py_INCREF(v); + return v; + } + + dec = PyDecType_New(type); + if (dec == NULL) { + return NULL; + } + + mpd_qcopy(MPD(dec), MPD(v), &status); + if (dec_addstatus(context, status)) { + Py_DECREF(dec); + return NULL; + } + + return dec; +} + +static PyObject * +sequence_as_tuple(PyObject *v, PyObject *ex, const char *mesg) +{ + if (PyTuple_Check(v)) { + Py_INCREF(v); + return v; + } + if (PyList_Check(v)) { + return PyList_AsTuple(v); + } + + PyErr_SetString(ex, mesg); + return NULL; +} + +/* Return a new C string representation of a DecimalTuple. */ +static char * +dectuple_as_str(PyObject *dectuple) +{ + PyObject *digits = NULL, *tmp; + char *decstring = NULL; + char sign_special[6]; + char *cp; + long sign, l; + mpd_ssize_t exp = 0; + Py_ssize_t i, mem, tsize; + int is_infinite = 0; + int n; + + assert(PyTuple_Check(dectuple)); + + if (PyTuple_Size(dectuple) != 3) { + PyErr_SetString(PyExc_ValueError, + "argument must be a sequence of length 3"); + goto error; + } + + /* sign */ + tmp = PyTuple_GET_ITEM(dectuple, 0); + if (!PyLong_Check(tmp)) { + PyErr_SetString(PyExc_ValueError, + "sign must be an integer with the value 0 or 1"); + goto error; + } + sign = PyLong_AsLong(tmp); + if (sign == -1 && PyErr_Occurred()) { + goto error; + } + if (sign != 0 && sign != 1) { + PyErr_SetString(PyExc_ValueError, + "sign must be an integer with the value 0 or 1"); + goto error; + } + sign_special[0] = sign ? '-' : '+'; + sign_special[1] = '\0'; + + /* exponent or encoding for a special number */ + tmp = PyTuple_GET_ITEM(dectuple, 2); + if (PyUnicode_Check(tmp)) { + /* special */ + if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) { + strcat(sign_special, "Inf"); + is_infinite = 1; + } + else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) { + strcat(sign_special, "NaN"); + } + else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) { + strcat(sign_special, "sNaN"); + } + else { + PyErr_SetString(PyExc_ValueError, + "string argument in the third position " + "must be 'F', 'n' or 'N'"); + goto error; + } + } + else { + /* exponent */ + if (!PyLong_Check(tmp)) { + PyErr_SetString(PyExc_ValueError, + "exponent must be an integer"); + goto error; + } + exp = PyLong_AsSsize_t(tmp); + if (exp == -1 && PyErr_Occurred()) { + goto error; + } + } + + /* coefficient */ + digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), PyExc_ValueError, + "coefficient must be a tuple of digits"); + if (digits == NULL) { + goto error; + } + + tsize = PyTuple_Size(digits); + /* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */ + mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2; + cp = decstring = PyMem_Malloc(mem); + if (decstring == NULL) { + PyErr_NoMemory(); + goto error; + } + + n = snprintf(cp, mem, "%s", sign_special); + if (n < 0 || n >= mem) { + PyErr_SetString(PyExc_RuntimeError, + "internal error in dec_sequence_as_str"); + goto error; + } + cp += n; + + if (tsize == 0 && sign_special[1] == '\0') { + /* empty tuple: zero coefficient, except for special numbers */ + *cp++ = '0'; + } + for (i = 0; i < tsize; i++) { + tmp = PyTuple_GET_ITEM(digits, i); + if (!PyLong_Check(tmp)) { + PyErr_SetString(PyExc_ValueError, + "coefficient must be a tuple of digits"); + goto error; + } + l = PyLong_AsLong(tmp); + if (l == -1 && PyErr_Occurred()) { + goto error; + } + if (l < 0 || l > 9) { + PyErr_SetString(PyExc_ValueError, + "coefficient must be a tuple of digits"); + goto error; + } + if (is_infinite) { + /* accept but ignore any well-formed coefficient for compatibility + with decimal.py */ + continue; + } + *cp++ = (char)l + '0'; + } + *cp = '\0'; + + if (sign_special[1] == '\0') { + /* not a special number */ + *cp++ = 'E'; + n = snprintf(cp, MPD_EXPDIGITS+2, "%" PRI_mpd_ssize_t, exp); + if (n < 0 || n >= MPD_EXPDIGITS+2) { + PyErr_SetString(PyExc_RuntimeError, + "internal error in dec_sequence_as_str"); + goto error; + } + } + + Py_XDECREF(digits); + return decstring; + + +error: + Py_XDECREF(digits); + if (decstring) PyMem_Free(decstring); + return NULL; +} + +/* Currently accepts tuples and lists. */ +static PyObject * +PyDecType_FromSequence(PyTypeObject *type, PyObject *v, + PyObject *context) +{ + PyObject *dectuple; + PyObject *dec; + char *s; + + dectuple = sequence_as_tuple(v, PyExc_TypeError, + "argument must be a tuple or list"); + if (dectuple == NULL) { + return NULL; + } + + s = dectuple_as_str(dectuple); + Py_DECREF(dectuple); + if (s == NULL) { + return NULL; + } + + dec = PyDecType_FromCString(type, s, context); + + PyMem_Free(s); + return dec; +} + +/* Currently accepts tuples and lists. */ +static PyObject * +PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v, + PyObject *context) +{ + PyObject *dectuple; + PyObject *dec; + char *s; + + dectuple = sequence_as_tuple(v, PyExc_TypeError, + "argument must be a tuple or list"); + if (dectuple == NULL) { + return NULL; + } + + s = dectuple_as_str(dectuple); + Py_DECREF(dectuple); + if (s == NULL) { + return NULL; + } + + dec = PyDecType_FromCStringExact(type, s, context); + + PyMem_Free(s); + return dec; +} + +#define PyDec_FromCString(str, context) \ + PyDecType_FromCString(&PyDec_Type, str, context) +#define PyDec_FromCStringExact(str, context) \ + PyDecType_FromCStringExact(&PyDec_Type, str, context) + +#define PyDec_FromUnicode(unicode, context) \ + PyDecType_FromUnicode(&PyDec_Type, unicode, context) +#define PyDec_FromUnicodeExact(unicode, context) \ + PyDecType_FromUnicodeExact(&PyDec_Type, unicode, context) +#define PyDec_FromUnicodeExactWS(unicode, context) \ + PyDecType_FromUnicodeExactWS(&PyDec_Type, unicode, context) + +#define PyDec_FromSsize(v, context) \ + PyDecType_FromSsize(&PyDec_Type, v, context) +#define PyDec_FromSsizeExact(v, context) \ + PyDecType_FromSsizeExact(&PyDec_Type, v, context) + +#define PyDec_FromLong(pylong, context) \ + PyDecType_FromLong(&PyDec_Type, pylong, context) +#define PyDec_FromLongExact(pylong, context) \ + PyDecType_FromLongExact(&PyDec_Type, pylong, context) + +#define PyDec_FromFloat(pyfloat, context) \ + PyDecType_FromFloat(&PyDec_Type, pyfloat, context) +#define PyDec_FromFloatExact(pyfloat, context) \ + PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context) + +#define PyDec_FromSequence(sequence, context) \ + PyDecType_FromSequence(&PyDec_Type, sequence, context) +#define PyDec_FromSequenceExact(sequence, context) \ + PyDecType_FromSequenceExact(&PyDec_Type, sequence, context) + +/* class method */ +static PyObject * +dec_from_float(PyObject *type, PyObject *pyfloat) +{ + PyObject *context; + PyObject *result; + + CURRENT_CONTEXT(context); + result = PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context); + if (type != (PyObject *)&PyDec_Type && result != NULL) { + Py_SETREF(result, PyObject_CallFunctionObjArgs(type, result, NULL)); + } + + return result; +} + +/* create_decimal_from_float */ +static PyObject * +ctx_from_float(PyObject *context, PyObject *v) +{ + return PyDec_FromFloat(v, context); +} + +/* Apply the context to the input operand. Return a new PyDecObject. */ +static PyObject * +dec_apply(PyObject *v, PyObject *context) +{ + PyObject *result; + uint32_t status = 0; + + result = dec_alloc(); + if (result == NULL) { + return NULL; + } + + mpd_qcopy(MPD(result), MPD(v), &status); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + mpd_qfinalize(MPD(result), CTX(context), &status); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +/* 'v' can have any type accepted by the Decimal constructor. Attempt + an exact conversion. If the result does not meet the restrictions + for an mpd_t, fail with InvalidOperation. */ +static PyObject * +PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context) +{ + if (v == NULL) { + return PyDecType_FromSsizeExact(type, 0, context); + } + else if (PyDec_Check(v)) { + return PyDecType_FromDecimalExact(type, v, context); + } + else if (PyUnicode_Check(v)) { + return PyDecType_FromUnicodeExactWS(type, v, context); + } + else if (PyLong_Check(v)) { + return PyDecType_FromLongExact(type, v, context); + } + else if (PyTuple_Check(v) || PyList_Check(v)) { + return PyDecType_FromSequenceExact(type, v, context); + } + else if (PyFloat_Check(v)) { + if (dec_addstatus(context, MPD_Float_operation)) { + return NULL; + } + return PyDecType_FromFloatExact(type, v, context); + } + else { + PyErr_Format(PyExc_TypeError, + "conversion from %s to Decimal is not supported", + Py_TYPE(v)->tp_name); + return NULL; + } +} + +/* The context is used during conversion. This function is the + equivalent of context.create_decimal(). */ +static PyObject * +PyDec_FromObject(PyObject *v, PyObject *context) +{ + if (v == NULL) { + return PyDec_FromSsize(0, context); + } + else if (PyDec_Check(v)) { + mpd_context_t *ctx = CTX(context); + if (mpd_isnan(MPD(v)) && + MPD(v)->digits > ctx->prec - ctx->clamp) { + /* Special case: too many NaN payload digits */ + PyObject *result; + if (dec_addstatus(context, MPD_Conversion_syntax)) { + return NULL; + } + result = dec_alloc(); + if (result == NULL) { + return NULL; + } + mpd_setspecial(MPD(result), MPD_POS, MPD_NAN); + return result; + } + return dec_apply(v, context); + } + else if (PyUnicode_Check(v)) { + return PyDec_FromUnicode(v, context); + } + else if (PyLong_Check(v)) { + return PyDec_FromLong(v, context); + } + else if (PyTuple_Check(v) || PyList_Check(v)) { + return PyDec_FromSequence(v, context); + } + else if (PyFloat_Check(v)) { + if (dec_addstatus(context, MPD_Float_operation)) { + return NULL; + } + return PyDec_FromFloat(v, context); + } + else { + PyErr_Format(PyExc_TypeError, + "conversion from %s to Decimal is not supported", + Py_TYPE(v)->tp_name); + return NULL; + } +} + +static PyObject * +dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"value", "context", NULL}; + PyObject *v = NULL; + PyObject *context = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, + &v, &context)) { + return NULL; + } + CONTEXT_CHECK_VA(context); + + return PyDecType_FromObjectExact(type, v, context); +} + +static PyObject * +ctx_create_decimal(PyObject *context, PyObject *args) +{ + PyObject *v = NULL; + + if (!PyArg_ParseTuple(args, "|O", &v)) { + return NULL; + } + + return PyDec_FromObject(v, context); +} + + +/******************************************************************************/ +/* Implicit conversions to Decimal */ +/******************************************************************************/ + +/* Try to convert PyObject v to a new PyDecObject conv. If the conversion + fails, set conv to NULL (exception is set). If the conversion is not + implemented, set conv to Py_NotImplemented. */ +#define NOT_IMPL 0 +#define TYPE_ERR 1 +Py_LOCAL_INLINE(int) +convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) +{ + + if (PyDec_Check(v)) { + *conv = v; + Py_INCREF(v); + return 1; + } + if (PyLong_Check(v)) { + *conv = PyDec_FromLongExact(v, context); + if (*conv == NULL) { + return 0; + } + return 1; + } + + if (type_err) { + PyErr_Format(PyExc_TypeError, + "conversion from %s to Decimal is not supported", + Py_TYPE(v)->tp_name); + } + else { + Py_INCREF(Py_NotImplemented); + *conv = Py_NotImplemented; + } + return 0; +} + +/* Return NotImplemented for unsupported types. */ +#define CONVERT_OP(a, v, context) \ + if (!convert_op(NOT_IMPL, a, v, context)) { \ + return *(a); \ + } + +#define CONVERT_BINOP(a, b, v, w, context) \ + if (!convert_op(NOT_IMPL, a, v, context)) { \ + return *(a); \ + } \ + if (!convert_op(NOT_IMPL, b, w, context)) { \ + Py_DECREF(*(a)); \ + return *(b); \ + } + +#define CONVERT_TERNOP(a, b, c, v, w, x, context) \ + if (!convert_op(NOT_IMPL, a, v, context)) { \ + return *(a); \ + } \ + if (!convert_op(NOT_IMPL, b, w, context)) { \ + Py_DECREF(*(a)); \ + return *(b); \ + } \ + if (!convert_op(NOT_IMPL, c, x, context)) { \ + Py_DECREF(*(a)); \ + Py_DECREF(*(b)); \ + return *(c); \ + } + +/* Raise TypeError for unsupported types. */ +#define CONVERT_OP_RAISE(a, v, context) \ + if (!convert_op(TYPE_ERR, a, v, context)) { \ + return NULL; \ + } + +#define CONVERT_BINOP_RAISE(a, b, v, w, context) \ + if (!convert_op(TYPE_ERR, a, v, context)) { \ + return NULL; \ + } \ + if (!convert_op(TYPE_ERR, b, w, context)) { \ + Py_DECREF(*(a)); \ + return NULL; \ + } + +#define CONVERT_TERNOP_RAISE(a, b, c, v, w, x, context) \ + if (!convert_op(TYPE_ERR, a, v, context)) { \ + return NULL; \ + } \ + if (!convert_op(TYPE_ERR, b, w, context)) { \ + Py_DECREF(*(a)); \ + return NULL; \ + } \ + if (!convert_op(TYPE_ERR, c, x, context)) { \ + Py_DECREF(*(a)); \ + Py_DECREF(*(b)); \ + return NULL; \ + } + + +/******************************************************************************/ +/* Implicit conversions to Decimal for comparison */ +/******************************************************************************/ + +/* Convert rationals for comparison */ +static PyObject *Rational = NULL; +static PyObject * +multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context) +{ + PyObject *result; + PyObject *tmp = NULL; + PyObject *denom = NULL; + uint32_t status = 0; + mpd_context_t maxctx; + mpd_ssize_t exp; + mpd_t *vv; + + /* v is not special, r is a rational */ + tmp = PyObject_GetAttrString(r, "denominator"); + if (tmp == NULL) { + return NULL; + } + denom = PyDec_FromLongExact(tmp, context); + Py_DECREF(tmp); + if (denom == NULL) { + return NULL; + } + + vv = mpd_qncopy(MPD(v)); + if (vv == NULL) { + Py_DECREF(denom); + PyErr_NoMemory(); + return NULL; + } + result = dec_alloc(); + if (result == NULL) { + Py_DECREF(denom); + mpd_del(vv); + return NULL; + } + + mpd_maxcontext(&maxctx); + /* Prevent Overflow in the following multiplication. The result of + the multiplication is only used in mpd_qcmp, which can handle + values that are technically out of bounds, like (for 32-bit) + 99999999999999999999...99999999e+425000000. */ + exp = vv->exp; + vv->exp = 0; + mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status); + MPD(result)->exp = exp; + + Py_DECREF(denom); + mpd_del(vv); + /* If any status has been accumulated during the multiplication, + the result is invalid. This is very unlikely, since even the + 32-bit version supports 425000000 digits. */ + if (status) { + PyErr_SetString(PyExc_ValueError, + "exact conversion for comparison failed"); + Py_DECREF(result); + return NULL; + } + + return result; +} + +static PyObject * +numerator_as_decimal(PyObject *r, PyObject *context) +{ + PyObject *tmp, *num; + + tmp = PyObject_GetAttrString(r, "numerator"); + if (tmp == NULL) { + return NULL; + } + + num = PyDec_FromLongExact(tmp, context); + Py_DECREF(tmp); + return num; +} + +/* Convert v and w for comparison. v is a Decimal. If w is a Rational, both + v and w have to be transformed. Return 1 for success, with new references + to the converted objects in vcmp and wcmp. Return 0 for failure. In that + case wcmp is either NULL or Py_NotImplemented (new reference) and vcmp + is undefined. */ +static int +convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, + int op, PyObject *context) +{ + mpd_context_t *ctx = CTX(context); + + *vcmp = v; + + if (PyDec_Check(w)) { + Py_INCREF(w); + *wcmp = w; + } + else if (PyLong_Check(w)) { + *wcmp = PyDec_FromLongExact(w, context); + } + else if (PyFloat_Check(w)) { + if (op != Py_EQ && op != Py_NE && + dec_addstatus(context, MPD_Float_operation)) { + *wcmp = NULL; + } + else { + ctx->status |= MPD_Float_operation; + *wcmp = PyDec_FromFloatExact(w, context); + } + } + else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) { + Py_complex c = PyComplex_AsCComplex(w); + if (c.real == -1.0 && PyErr_Occurred()) { + *wcmp = NULL; + } + else if (c.imag == 0.0) { + PyObject *tmp = PyFloat_FromDouble(c.real); + if (tmp == NULL) { + *wcmp = NULL; + } + else { + ctx->status |= MPD_Float_operation; + *wcmp = PyDec_FromFloatExact(tmp, context); + Py_DECREF(tmp); + } + } + else { + Py_INCREF(Py_NotImplemented); + *wcmp = Py_NotImplemented; + } + } + else { + int is_rational = PyObject_IsInstance(w, Rational); + if (is_rational < 0) { + *wcmp = NULL; + } + else if (is_rational > 0) { + *wcmp = numerator_as_decimal(w, context); + if (*wcmp && !mpd_isspecial(MPD(v))) { + *vcmp = multiply_by_denominator(v, w, context); + if (*vcmp == NULL) { + Py_CLEAR(*wcmp); + } + } + } + else { + Py_INCREF(Py_NotImplemented); + *wcmp = Py_NotImplemented; + } + } + + if (*wcmp == NULL || *wcmp == Py_NotImplemented) { + return 0; + } + if (*vcmp == v) { + Py_INCREF(v); + } + return 1; +} + +#define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \ + if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) { \ + return *(wcmp); \ + } \ + + +/******************************************************************************/ +/* Conversions from decimal */ +/******************************************************************************/ + +static PyObject * +unicode_fromascii(const char *s, Py_ssize_t size) +{ + PyObject *res; + + res = PyUnicode_New(size, 127); + if (res == NULL) { + return NULL; + } + + memcpy(PyUnicode_1BYTE_DATA(res), s, size); + return res; +} + +/* PyDecObject as a string. The default module context is only used for + the value of 'capitals'. */ +static PyObject * +dec_str(PyObject *dec) +{ + PyObject *res, *context; + mpd_ssize_t size; + char *cp; + + CURRENT_CONTEXT(context); + size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context)); + if (size < 0) { + PyErr_NoMemory(); + return NULL; + } + + res = unicode_fromascii(cp, size); + mpd_free(cp); + return res; +} + +/* Representation of a PyDecObject. */ +static PyObject * +dec_repr(PyObject *dec) +{ + PyObject *res, *context; + char *cp; + + CURRENT_CONTEXT(context); + cp = mpd_to_sci(MPD(dec), CtxCaps(context)); + if (cp == NULL) { + PyErr_NoMemory(); + return NULL; + } + + res = PyUnicode_FromFormat("Decimal('%s')", cp); + mpd_free(cp); + return res; +} + +/* Return a duplicate of src, copy embedded null characters. */ +static char * +dec_strdup(const char *src, Py_ssize_t size) +{ + char *dest = PyMem_Malloc(size+1); + if (dest == NULL) { + PyErr_NoMemory(); + return NULL; + } + + memcpy(dest, src, size); + dest[size] = '\0'; + return dest; +} + +static void +dec_replace_fillchar(char *dest) +{ + while (*dest != '\0') { + if (*dest == '\xff') *dest = '\0'; + dest++; + } +} + +/* Convert decimal_point or thousands_sep, which may be multibyte or in + the range [128, 255], to a UTF8 string. */ +static PyObject * +dotsep_as_utf8(const char *s) +{ + PyObject *utf8; + PyObject *tmp; + wchar_t buf[2]; + size_t n; + + n = mbstowcs(buf, s, 2); + if (n != 1) { /* Issue #7442 */ + PyErr_SetString(PyExc_ValueError, + "invalid decimal point or unsupported " + "combination of LC_CTYPE and LC_NUMERIC"); + return NULL; + } + tmp = PyUnicode_FromWideChar(buf, n); + if (tmp == NULL) { + return NULL; + } + utf8 = PyUnicode_AsUTF8String(tmp); + Py_DECREF(tmp); + return utf8; +} + +/* Formatted representation of a PyDecObject. */ +static PyObject * +dec_format(PyObject *dec, PyObject *args) +{ + PyObject *result = NULL; + PyObject *override = NULL; + PyObject *dot = NULL; + PyObject *sep = NULL; + PyObject *grouping = NULL; + PyObject *fmtarg; + PyObject *context; + mpd_spec_t spec; + char *fmt; + char *decstring = NULL; + uint32_t status = 0; + int replace_fillchar = 0; + Py_ssize_t size; + + + CURRENT_CONTEXT(context); + if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) { + return NULL; + } + + if (PyUnicode_Check(fmtarg)) { + fmt = (char *)PyUnicode_AsUTF8AndSize(fmtarg, &size); + if (fmt == NULL) { + return NULL; + } + if (size > 0 && fmt[0] == '\0') { + /* NUL fill character: must be replaced with a valid UTF-8 char + before calling mpd_parse_fmt_str(). */ + replace_fillchar = 1; + fmt = dec_strdup(fmt, size); + if (fmt == NULL) { + return NULL; + } + fmt[0] = '_'; + } + } + else { + PyErr_SetString(PyExc_TypeError, + "format arg must be str"); + return NULL; + } + + if (!mpd_parse_fmt_str(&spec, fmt, CtxCaps(context))) { + PyErr_SetString(PyExc_ValueError, + "invalid format string"); + goto finish; + } + if (replace_fillchar) { + /* In order to avoid clobbering parts of UTF-8 thousands separators or + decimal points when the substitution is reversed later, the actual + placeholder must be an invalid UTF-8 byte. */ + spec.fill[0] = '\xff'; + spec.fill[1] = '\0'; + } + + if (override) { + /* Values for decimal_point, thousands_sep and grouping can + be explicitly specified in the override dict. These values + take precedence over the values obtained from localeconv() + in mpd_parse_fmt_str(). The feature is not documented and + is only used in test_decimal. */ + if (!PyDict_Check(override)) { + PyErr_SetString(PyExc_TypeError, + "optional argument must be a dict"); + goto finish; + } + if ((dot = PyDict_GetItemString(override, "decimal_point"))) { + if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) { + goto finish; + } + spec.dot = PyBytes_AS_STRING(dot); + } + if ((sep = PyDict_GetItemString(override, "thousands_sep"))) { + if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) { + goto finish; + } + spec.sep = PyBytes_AS_STRING(sep); + } + if ((grouping = PyDict_GetItemString(override, "grouping"))) { + if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) { + goto finish; + } + spec.grouping = PyBytes_AS_STRING(grouping); + } + if (mpd_validate_lconv(&spec) < 0) { + PyErr_SetString(PyExc_ValueError, + "invalid override dict"); + goto finish; + } + } + else { + size_t n = strlen(spec.dot); + if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) { + /* fix locale dependent non-ascii characters */ + dot = dotsep_as_utf8(spec.dot); + if (dot == NULL) { + goto finish; + } + spec.dot = PyBytes_AS_STRING(dot); + } + n = strlen(spec.sep); + if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) { + /* fix locale dependent non-ascii characters */ + sep = dotsep_as_utf8(spec.sep); + if (sep == NULL) { + goto finish; + } + spec.sep = PyBytes_AS_STRING(sep); + } + } + + + decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status); + if (decstring == NULL) { + if (status & MPD_Malloc_error) { + PyErr_NoMemory(); + } + else { + PyErr_SetString(PyExc_ValueError, + "format specification exceeds internal limits of _decimal"); + } + goto finish; + } + size = strlen(decstring); + if (replace_fillchar) { + dec_replace_fillchar(decstring); + } + + result = PyUnicode_DecodeUTF8(decstring, size, NULL); + + +finish: + Py_XDECREF(grouping); + Py_XDECREF(sep); + Py_XDECREF(dot); + if (replace_fillchar) PyMem_Free(fmt); + if (decstring) mpd_free(decstring); + return result; +} + +/* Return a PyLongObject from a PyDecObject, using the specified rounding + * mode. The context precision is not observed. */ +static PyObject * +dec_as_long(PyObject *dec, PyObject *context, int round) +{ + PyLongObject *pylong; + digit *ob_digit; + size_t n; + Py_ssize_t i; + mpd_t *x; + mpd_context_t workctx; + uint32_t status = 0; + + if (mpd_isspecial(MPD(dec))) { + if (mpd_isnan(MPD(dec))) { + PyErr_SetString(PyExc_ValueError, + "cannot convert NaN to integer"); + } + else { + PyErr_SetString(PyExc_OverflowError, + "cannot convert Infinity to integer"); + } + return NULL; + } + + x = mpd_qnew(); + if (x == NULL) { + PyErr_NoMemory(); + return NULL; + } + workctx = *CTX(context); + workctx.round = round; + mpd_qround_to_int(x, MPD(dec), &workctx, &status); + if (dec_addstatus(context, status)) { + mpd_del(x); + return NULL; + } + + status = 0; + ob_digit = NULL; +#if PYLONG_BITS_IN_DIGIT == 30 + n = mpd_qexport_u32(&ob_digit, 0, PyLong_BASE, x, &status); +#elif PYLONG_BITS_IN_DIGIT == 15 + n = mpd_qexport_u16(&ob_digit, 0, PyLong_BASE, x, &status); +#else + #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" +#endif + + if (n == SIZE_MAX) { + PyErr_NoMemory(); + mpd_del(x); + return NULL; + } + + assert(n > 0); + pylong = _PyLong_New(n); + if (pylong == NULL) { + mpd_free(ob_digit); + mpd_del(x); + return NULL; + } + + memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit)); + mpd_free(ob_digit); + + i = n; + while ((i > 0) && (pylong->ob_digit[i-1] == 0)) { + i--; + } + + Py_SET_SIZE(pylong, i); + if (mpd_isnegative(x) && !mpd_iszero(x)) { + Py_SET_SIZE(pylong, -i); + } + + mpd_del(x); + return (PyObject *) pylong; +} + +/* Convert a Decimal to its exact integer ratio representation. */ +static PyObject * +dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED) +{ + PyObject *numerator = NULL; + PyObject *denominator = NULL; + PyObject *exponent = NULL; + PyObject *result = NULL; + PyObject *tmp; + mpd_ssize_t exp; + PyObject *context; + uint32_t status = 0; + + if (mpd_isspecial(MPD(self))) { + if (mpd_isnan(MPD(self))) { + PyErr_SetString(PyExc_ValueError, + "cannot convert NaN to integer ratio"); + } + else { + PyErr_SetString(PyExc_OverflowError, + "cannot convert Infinity to integer ratio"); + } + return NULL; + } + + CURRENT_CONTEXT(context); + + tmp = dec_alloc(); + if (tmp == NULL) { + return NULL; + } + + if (!mpd_qcopy(MPD(tmp), MPD(self), &status)) { + Py_DECREF(tmp); + PyErr_NoMemory(); + return NULL; + } + + exp = mpd_iszero(MPD(tmp)) ? 0 : MPD(tmp)->exp; + MPD(tmp)->exp = 0; + + /* context and rounding are unused here: the conversion is exact */ + numerator = dec_as_long(tmp, context, MPD_ROUND_FLOOR); + Py_DECREF(tmp); + if (numerator == NULL) { + goto error; + } + + exponent = PyLong_FromSsize_t(exp < 0 ? -exp : exp); + if (exponent == NULL) { + goto error; + } + + tmp = PyLong_FromLong(10); + if (tmp == NULL) { + goto error; + } + + Py_SETREF(exponent, _py_long_power(tmp, exponent, Py_None)); + Py_DECREF(tmp); + if (exponent == NULL) { + goto error; + } + + if (exp >= 0) { + Py_SETREF(numerator, _py_long_multiply(numerator, exponent)); + if (numerator == NULL) { + goto error; + } + denominator = PyLong_FromLong(1); + if (denominator == NULL) { + goto error; + } + } + else { + denominator = exponent; + exponent = NULL; + tmp = _PyLong_GCD(numerator, denominator); + if (tmp == NULL) { + goto error; + } + Py_SETREF(numerator, _py_long_floor_divide(numerator, tmp)); + Py_SETREF(denominator, _py_long_floor_divide(denominator, tmp)); + Py_DECREF(tmp); + if (numerator == NULL || denominator == NULL) { + goto error; + } + } + + result = PyTuple_Pack(2, numerator, denominator); + + +error: + Py_XDECREF(exponent); + Py_XDECREF(denominator); + Py_XDECREF(numerator); + return result; +} + +static PyObject * +PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"rounding", "context", NULL}; + PyObject *result; + PyObject *rounding = Py_None; + PyObject *context = Py_None; + uint32_t status = 0; + mpd_context_t workctx; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, + &rounding, &context)) { + return NULL; + } + CONTEXT_CHECK_VA(context); + + workctx = *CTX(context); + if (rounding != Py_None) { + int round = getround(rounding); + if (round < 0) { + return NULL; + } + if (!mpd_qsetround(&workctx, round)) { + INTERNAL_ERROR_PTR("PyDec_ToIntegralValue"); /* GCOV_NOT_REACHED */ + } + } + + result = dec_alloc(); + if (result == NULL) { + return NULL; + } + + mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +static PyObject * +PyDec_ToIntegralExact(PyObject *dec, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"rounding", "context", NULL}; + PyObject *result; + PyObject *rounding = Py_None; + PyObject *context = Py_None; + uint32_t status = 0; + mpd_context_t workctx; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, + &rounding, &context)) { + return NULL; + } + CONTEXT_CHECK_VA(context); + + workctx = *CTX(context); + if (rounding != Py_None) { + int round = getround(rounding); + if (round < 0) { + return NULL; + } + if (!mpd_qsetround(&workctx, round)) { + INTERNAL_ERROR_PTR("PyDec_ToIntegralExact"); /* GCOV_NOT_REACHED */ + } + } + + result = dec_alloc(); + if (result == NULL) { + return NULL; + } + + mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +static PyObject * +PyDec_AsFloat(PyObject *dec) +{ + PyObject *f, *s; + + if (mpd_isnan(MPD(dec))) { + if (mpd_issnan(MPD(dec))) { + PyErr_SetString(PyExc_ValueError, + "cannot convert signaling NaN to float"); + return NULL; + } + if (mpd_isnegative(MPD(dec))) { + s = PyUnicode_FromString("-nan"); + } + else { + s = PyUnicode_FromString("nan"); + } + } + else { + s = dec_str(dec); + } + + if (s == NULL) { + return NULL; + } + + f = PyFloat_FromString(s); + Py_DECREF(s); + + return f; +} + +static PyObject * +PyDec_Round(PyObject *dec, PyObject *args) +{ + PyObject *result; + PyObject *x = NULL; + uint32_t status = 0; + PyObject *context; + + + CURRENT_CONTEXT(context); + if (!PyArg_ParseTuple(args, "|O", &x)) { + return NULL; + } + + if (x) { + mpd_uint_t dq[1] = {1}; + mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq}; + mpd_ssize_t y; + + if (!PyLong_Check(x)) { + PyErr_SetString(PyExc_TypeError, + "optional arg must be an integer"); + return NULL; + } + + y = PyLong_AsSsize_t(x); + if (y == -1 && PyErr_Occurred()) { + return NULL; + } + result = dec_alloc(); + if (result == NULL) { + return NULL; + } + + q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y; + mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; + } + else { + return dec_as_long(dec, context, MPD_ROUND_HALF_EVEN); + } +} + +static PyTypeObject *DecimalTuple = NULL; +/* Return the DecimalTuple representation of a PyDecObject. */ +static PyObject * +PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) +{ + PyObject *result = NULL; + PyObject *sign = NULL; + PyObject *coeff = NULL; + PyObject *expt = NULL; + PyObject *tmp = NULL; + mpd_t *x = NULL; + char *intstring = NULL; + Py_ssize_t intlen, i; + + + x = mpd_qncopy(MPD(dec)); + if (x == NULL) { + PyErr_NoMemory(); + goto out; + } + + sign = PyLong_FromUnsignedLong(mpd_sign(MPD(dec))); + if (sign == NULL) { + goto out; + } + + if (mpd_isinfinite(x)) { + expt = PyUnicode_FromString("F"); + if (expt == NULL) { + goto out; + } + /* decimal.py has non-compliant infinity payloads. */ + coeff = Py_BuildValue("(i)", 0); + if (coeff == NULL) { + goto out; + } + } + else { + if (mpd_isnan(x)) { + expt = PyUnicode_FromString(mpd_isqnan(x)?"n":"N"); + } + else { + expt = PyLong_FromSsize_t(MPD(dec)->exp); + } + if (expt == NULL) { + goto out; + } + + /* coefficient is defined */ + if (x->len > 0) { + + /* make an integer */ + x->exp = 0; + /* clear NaN and sign */ + mpd_clear_flags(x); + intstring = mpd_to_sci(x, 1); + if (intstring == NULL) { + PyErr_NoMemory(); + goto out; + } + + intlen = strlen(intstring); + coeff = PyTuple_New(intlen); + if (coeff == NULL) { + goto out; + } + + for (i = 0; i < intlen; i++) { + tmp = PyLong_FromLong(intstring[i]-'0'); + if (tmp == NULL) { + goto out; + } + PyTuple_SET_ITEM(coeff, i, tmp); + } + } + else { + coeff = PyTuple_New(0); + if (coeff == NULL) { + goto out; + } + } + } + + result = PyObject_CallFunctionObjArgs((PyObject *)DecimalTuple, + sign, coeff, expt, NULL); + +out: + if (x) mpd_del(x); + if (intstring) mpd_free(intstring); + Py_XDECREF(sign); + Py_XDECREF(coeff); + Py_XDECREF(expt); + return result; +} + + +/******************************************************************************/ +/* Macros for converting mpdecimal functions to Decimal methods */ +/******************************************************************************/ + +/* Unary number method that uses the default module context. */ +#define Dec_UnaryNumberMethod(MPDFUNC) \ +static PyObject * \ +nm_##MPDFUNC(PyObject *self) \ +{ \ + PyObject *result; \ + PyObject *context; \ + uint32_t status = 0; \ + \ + CURRENT_CONTEXT(context); \ + if ((result = dec_alloc()) == NULL) { \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \ + if (dec_addstatus(context, status)) { \ + Py_DECREF(result); \ + return NULL; \ + } \ + \ + return result; \ +} + +/* Binary number method that uses default module context. */ +#define Dec_BinaryNumberMethod(MPDFUNC) \ +static PyObject * \ +nm_##MPDFUNC(PyObject *self, PyObject *other) \ +{ \ + PyObject *a, *b; \ + PyObject *result; \ + PyObject *context; \ + uint32_t status = 0; \ + \ + CURRENT_CONTEXT(context) ; \ + CONVERT_BINOP(&a, &b, self, other, context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + Py_DECREF(a); \ + Py_DECREF(b); \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ + Py_DECREF(a); \ + Py_DECREF(b); \ + if (dec_addstatus(context, status)) { \ + Py_DECREF(result); \ + return NULL; \ + } \ + \ + return result; \ +} + +/* Boolean function without a context arg. */ +#define Dec_BoolFunc(MPDFUNC) \ +static PyObject * \ +dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED) \ +{ \ + return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \ +} + +/* Boolean function with an optional context arg. */ +#define Dec_BoolFuncVA(MPDFUNC) \ +static PyObject * \ +dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ +{ \ + static char *kwlist[] = {"context", NULL}; \ + PyObject *context = Py_None; \ + \ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \ + &context)) { \ + return NULL; \ + } \ + CONTEXT_CHECK_VA(context); \ + \ + return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \ +} + +/* Unary function with an optional context arg. */ +#define Dec_UnaryFuncVA(MPDFUNC) \ +static PyObject * \ +dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ +{ \ + static char *kwlist[] = {"context", NULL}; \ + PyObject *result; \ + PyObject *context = Py_None; \ + uint32_t status = 0; \ + \ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \ + &context)) { \ + return NULL; \ + } \ + CONTEXT_CHECK_VA(context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \ + if (dec_addstatus(context, status)) { \ + Py_DECREF(result); \ + return NULL; \ + } \ + \ + return result; \ +} + +/* Binary function with an optional context arg. */ +#define Dec_BinaryFuncVA(MPDFUNC) \ +static PyObject * \ +dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ +{ \ + static char *kwlist[] = {"other", "context", NULL}; \ + PyObject *other; \ + PyObject *a, *b; \ + PyObject *result; \ + PyObject *context = Py_None; \ + uint32_t status = 0; \ + \ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \ + &other, &context)) { \ + return NULL; \ + } \ + CONTEXT_CHECK_VA(context); \ + CONVERT_BINOP_RAISE(&a, &b, self, other, context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + Py_DECREF(a); \ + Py_DECREF(b); \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ + Py_DECREF(a); \ + Py_DECREF(b); \ + if (dec_addstatus(context, status)) { \ + Py_DECREF(result); \ + return NULL; \ + } \ + \ + return result; \ +} + +/* Binary function with an optional context arg. Actual MPDFUNC does + NOT take a context. The context is used to record InvalidOperation + if the second operand cannot be converted exactly. */ +#define Dec_BinaryFuncVA_NO_CTX(MPDFUNC) \ +static PyObject * \ +dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ +{ \ + static char *kwlist[] = {"other", "context", NULL}; \ + PyObject *context = Py_None; \ + PyObject *other; \ + PyObject *a, *b; \ + PyObject *result; \ + \ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \ + &other, &context)) { \ + return NULL; \ + } \ + CONTEXT_CHECK_VA(context); \ + CONVERT_BINOP_RAISE(&a, &b, self, other, context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + Py_DECREF(a); \ + Py_DECREF(b); \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(a), MPD(b)); \ + Py_DECREF(a); \ + Py_DECREF(b); \ + \ + return result; \ +} + +/* Ternary function with an optional context arg. */ +#define Dec_TernaryFuncVA(MPDFUNC) \ +static PyObject * \ +dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ +{ \ + static char *kwlist[] = {"other", "third", "context", NULL}; \ + PyObject *other, *third; \ + PyObject *a, *b, *c; \ + PyObject *result; \ + PyObject *context = Py_None; \ + uint32_t status = 0; \ + \ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, \ + &other, &third, &context)) { \ + return NULL; \ + } \ + CONTEXT_CHECK_VA(context); \ + CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + Py_DECREF(a); \ + Py_DECREF(b); \ + Py_DECREF(c); \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \ + Py_DECREF(a); \ + Py_DECREF(b); \ + Py_DECREF(c); \ + if (dec_addstatus(context, status)) { \ + Py_DECREF(result); \ + return NULL; \ + } \ + \ + return result; \ +} + + +/**********************************************/ +/* Number methods */ +/**********************************************/ + +Dec_UnaryNumberMethod(mpd_qminus) +Dec_UnaryNumberMethod(mpd_qplus) +Dec_UnaryNumberMethod(mpd_qabs) + +Dec_BinaryNumberMethod(mpd_qadd) +Dec_BinaryNumberMethod(mpd_qsub) +Dec_BinaryNumberMethod(mpd_qmul) +Dec_BinaryNumberMethod(mpd_qdiv) +Dec_BinaryNumberMethod(mpd_qrem) +Dec_BinaryNumberMethod(mpd_qdivint) + +static PyObject * +nm_dec_as_long(PyObject *dec) +{ + PyObject *context; + + CURRENT_CONTEXT(context); + return dec_as_long(dec, context, MPD_ROUND_DOWN); +} + +static int +nm_nonzero(PyObject *v) +{ + return !mpd_iszero(MPD(v)); +} + +static PyObject * +nm_mpd_qdivmod(PyObject *v, PyObject *w) +{ + PyObject *a, *b; + PyObject *q, *r; + PyObject *context; + uint32_t status = 0; + PyObject *ret; + + CURRENT_CONTEXT(context); + CONVERT_BINOP(&a, &b, v, w, context); + + q = dec_alloc(); + if (q == NULL) { + Py_DECREF(a); + Py_DECREF(b); + return NULL; + } + r = dec_alloc(); + if (r == NULL) { + Py_DECREF(a); + Py_DECREF(b); + Py_DECREF(q); + return NULL; + } + + mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status); + Py_DECREF(a); + Py_DECREF(b); + if (dec_addstatus(context, status)) { + Py_DECREF(r); + Py_DECREF(q); + return NULL; + } + + ret = Py_BuildValue("(OO)", q, r); + Py_DECREF(r); + Py_DECREF(q); + return ret; +} + +static PyObject * +nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) +{ + PyObject *a, *b, *c = NULL; + PyObject *result; + PyObject *context; + uint32_t status = 0; + + CURRENT_CONTEXT(context); + CONVERT_BINOP(&a, &b, base, exp, context); + + if (mod != Py_None) { + if (!convert_op(NOT_IMPL, &c, mod, context)) { + Py_DECREF(a); + Py_DECREF(b); + return c; + } + } + + result = dec_alloc(); + if (result == NULL) { + Py_DECREF(a); + Py_DECREF(b); + Py_XDECREF(c); + return NULL; + } + + if (c == NULL) { + mpd_qpow(MPD(result), MPD(a), MPD(b), + CTX(context), &status); + } + else { + mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c), + CTX(context), &status); + Py_DECREF(c); + } + Py_DECREF(a); + Py_DECREF(b); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + + +/******************************************************************************/ +/* Decimal Methods */ +/******************************************************************************/ + +/* Unary arithmetic functions, optional context arg */ +Dec_UnaryFuncVA(mpd_qexp) +Dec_UnaryFuncVA(mpd_qln) +Dec_UnaryFuncVA(mpd_qlog10) +Dec_UnaryFuncVA(mpd_qnext_minus) +Dec_UnaryFuncVA(mpd_qnext_plus) +Dec_UnaryFuncVA(mpd_qreduce) +Dec_UnaryFuncVA(mpd_qsqrt) + +/* Binary arithmetic functions, optional context arg */ +Dec_BinaryFuncVA(mpd_qcompare) +Dec_BinaryFuncVA(mpd_qcompare_signal) +Dec_BinaryFuncVA(mpd_qmax) +Dec_BinaryFuncVA(mpd_qmax_mag) +Dec_BinaryFuncVA(mpd_qmin) +Dec_BinaryFuncVA(mpd_qmin_mag) +Dec_BinaryFuncVA(mpd_qnext_toward) +Dec_BinaryFuncVA(mpd_qrem_near) + +/* Ternary arithmetic functions, optional context arg */ +Dec_TernaryFuncVA(mpd_qfma) + +/* Boolean functions, no context arg */ +Dec_BoolFunc(mpd_iscanonical) +Dec_BoolFunc(mpd_isfinite) +Dec_BoolFunc(mpd_isinfinite) +Dec_BoolFunc(mpd_isnan) +Dec_BoolFunc(mpd_isqnan) +Dec_BoolFunc(mpd_issnan) +Dec_BoolFunc(mpd_issigned) +Dec_BoolFunc(mpd_iszero) + +/* Boolean functions, optional context arg */ +Dec_BoolFuncVA(mpd_isnormal) +Dec_BoolFuncVA(mpd_issubnormal) + +/* Unary functions, no context arg */ +static PyObject * +dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED) +{ + mpd_ssize_t retval; + + if (mpd_isspecial(MPD(self))) { + retval = 0; + } + else { + retval = mpd_adjexp(MPD(self)); + } + + return PyLong_FromSsize_t(retval); +} + +static PyObject * +dec_canonical(PyObject *self, PyObject *dummy UNUSED) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +dec_conjugate(PyObject *self, PyObject *dummy UNUSED) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED) +{ + PyObject *result; + + result = dec_alloc(); + if (result == NULL) { + return NULL; + } + + _dec_settriple(result, MPD_POS, 10, 0); + return result; +} + +static PyObject * +dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED) +{ + PyObject *result; + uint32_t status = 0; + + if ((result = dec_alloc()) == NULL) { + return NULL; + } + + mpd_qcopy_abs(MPD(result), MPD(self), &status); + if (status & MPD_Malloc_error) { + Py_DECREF(result); + PyErr_NoMemory(); + return NULL; + } + + return result; +} + +static PyObject * +dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED) +{ + PyObject *result; + uint32_t status = 0; + + if ((result = dec_alloc()) == NULL) { + return NULL; + } + + mpd_qcopy_negate(MPD(result), MPD(self), &status); + if (status & MPD_Malloc_error) { + Py_DECREF(result); + PyErr_NoMemory(); + return NULL; + } + + return result; +} + +/* Unary functions, optional context arg */ +Dec_UnaryFuncVA(mpd_qinvert) +Dec_UnaryFuncVA(mpd_qlogb) + +static PyObject * +dec_mpd_class(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"context", NULL}; + PyObject *context = Py_None; + const char *cp; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, + &context)) { + return NULL; + } + CONTEXT_CHECK_VA(context); + + cp = mpd_class(MPD(self), CTX(context)); + return PyUnicode_FromString(cp); +} + +static PyObject * +dec_mpd_to_eng(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"context", NULL}; + PyObject *result; + PyObject *context = Py_None; + mpd_ssize_t size; + char *s; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, + &context)) { + return NULL; + } + CONTEXT_CHECK_VA(context); + + size = mpd_to_eng_size(&s, MPD(self), CtxCaps(context)); + if (size < 0) { + PyErr_NoMemory(); + return NULL; + } + + result = unicode_fromascii(s, size); + mpd_free(s); + + return result; +} + +/* Binary functions, optional context arg for conversion errors */ +Dec_BinaryFuncVA_NO_CTX(mpd_compare_total) +Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag) + +static PyObject * +dec_mpd_qcopy_sign(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"other", "context", NULL}; + PyObject *other; + PyObject *a, *b; + PyObject *result; + PyObject *context = Py_None; + uint32_t status = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, + &other, &context)) { + return NULL; + } + CONTEXT_CHECK_VA(context); + CONVERT_BINOP_RAISE(&a, &b, self, other, context); + + result = dec_alloc(); + if (result == NULL) { + Py_DECREF(a); + Py_DECREF(b); + return NULL; + } + + mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status); + Py_DECREF(a); + Py_DECREF(b); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +static PyObject * +dec_mpd_same_quantum(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"other", "context", NULL}; + PyObject *other; + PyObject *a, *b; + PyObject *result; + PyObject *context = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, + &other, &context)) { + return NULL; + } + CONTEXT_CHECK_VA(context); + CONVERT_BINOP_RAISE(&a, &b, self, other, context); + + result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false(); + Py_DECREF(a); + Py_DECREF(b); + + return result; +} + +/* Binary functions, optional context arg */ +Dec_BinaryFuncVA(mpd_qand) +Dec_BinaryFuncVA(mpd_qor) +Dec_BinaryFuncVA(mpd_qxor) + +Dec_BinaryFuncVA(mpd_qrotate) +Dec_BinaryFuncVA(mpd_qscaleb) +Dec_BinaryFuncVA(mpd_qshift) + +static PyObject * +dec_mpd_qquantize(PyObject *v, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"exp", "rounding", "context", NULL}; + PyObject *rounding = Py_None; + PyObject *context = Py_None; + PyObject *w, *a, *b; + PyObject *result; + uint32_t status = 0; + mpd_context_t workctx; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist, + &w, &rounding, &context)) { + return NULL; + } + CONTEXT_CHECK_VA(context); + + workctx = *CTX(context); + if (rounding != Py_None) { + int round = getround(rounding); + if (round < 0) { + return NULL; + } + if (!mpd_qsetround(&workctx, round)) { + INTERNAL_ERROR_PTR("dec_mpd_qquantize"); /* GCOV_NOT_REACHED */ + } + } + + CONVERT_BINOP_RAISE(&a, &b, v, w, context); + + result = dec_alloc(); + if (result == NULL) { + Py_DECREF(a); + Py_DECREF(b); + return NULL; + } + + mpd_qquantize(MPD(result), MPD(a), MPD(b), &workctx, &status); + Py_DECREF(a); + Py_DECREF(b); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +/* Special methods */ +static PyObject * +dec_richcompare(PyObject *v, PyObject *w, int op) +{ + PyObject *a; + PyObject *b; + PyObject *context; + uint32_t status = 0; + int a_issnan, b_issnan; + int r; + + assert(PyDec_Check(v)); + + CURRENT_CONTEXT(context); + CONVERT_BINOP_CMP(&a, &b, v, w, op, context); + + a_issnan = mpd_issnan(MPD(a)); + b_issnan = mpd_issnan(MPD(b)); + + r = mpd_qcmp(MPD(a), MPD(b), &status); + Py_DECREF(a); + Py_DECREF(b); + if (r == INT_MAX) { + /* sNaNs or op={le,ge,lt,gt} always signal. */ + if (a_issnan || b_issnan || (op != Py_EQ && op != Py_NE)) { + if (dec_addstatus(context, status)) { + return NULL; + } + } + /* qNaN comparison with op={eq,ne} or comparison + * with InvalidOperation disabled. */ + return (op == Py_NE) ? incr_true() : incr_false(); + } + + switch (op) { + case Py_EQ: + r = (r == 0); + break; + case Py_NE: + r = (r != 0); + break; + case Py_LE: + r = (r <= 0); + break; + case Py_GE: + r = (r >= 0); + break; + case Py_LT: + r = (r == -1); + break; + case Py_GT: + r = (r == 1); + break; + } + + return PyBool_FromLong(r); +} + +/* __ceil__ */ +static PyObject * +dec_ceil(PyObject *self, PyObject *dummy UNUSED) +{ + PyObject *context; + + CURRENT_CONTEXT(context); + return dec_as_long(self, context, MPD_ROUND_CEILING); +} + +/* __complex__ */ +static PyObject * +dec_complex(PyObject *self, PyObject *dummy UNUSED) +{ + PyObject *f; + double x; + + f = PyDec_AsFloat(self); + if (f == NULL) { + return NULL; + } + + x = PyFloat_AsDouble(f); + Py_DECREF(f); + if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } + + return PyComplex_FromDoubles(x, 0); +} + +/* __copy__ and __deepcopy__ */ +static PyObject * +dec_copy(PyObject *self, PyObject *dummy UNUSED) +{ + Py_INCREF(self); + return self; +} + +/* __floor__ */ +static PyObject * +dec_floor(PyObject *self, PyObject *dummy UNUSED) +{ + PyObject *context; + + CURRENT_CONTEXT(context); + return dec_as_long(self, context, MPD_ROUND_FLOOR); +} + +/* Always uses the module context */ +static Py_hash_t +_dec_hash(PyDecObject *v) +{ +#if defined(CONFIG_64) && _PyHASH_BITS == 61 + /* 2**61 - 1 */ + mpd_uint_t p_data[1] = {2305843009213693951ULL}; + mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data}; + /* Inverse of 10 modulo p */ + mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL}; + mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, + 0, 19, 1, 1, inv10_p_data}; +#elif defined(CONFIG_32) && _PyHASH_BITS == 31 + /* 2**31 - 1 */ + mpd_uint_t p_data[2] = {147483647UL, 2}; + mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data}; + /* Inverse of 10 modulo p */ + mpd_uint_t inv10_p_data[2] = {503238553UL, 1}; + mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, + 0, 10, 2, 2, inv10_p_data}; +#else + #error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS" +#endif + const Py_hash_t py_hash_inf = 314159; + const Py_hash_t py_hash_nan = 0; + mpd_uint_t ten_data[1] = {10}; + mpd_t ten = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, + 0, 2, 1, 1, ten_data}; + Py_hash_t result; + mpd_t *exp_hash = NULL; + mpd_t *tmp = NULL; + mpd_ssize_t exp; + uint32_t status = 0; + mpd_context_t maxctx; + + + if (mpd_isspecial(MPD(v))) { + if (mpd_issnan(MPD(v))) { + PyErr_SetString(PyExc_TypeError, + "Cannot hash a signaling NaN value"); + return -1; + } + else if (mpd_isnan(MPD(v))) { + return py_hash_nan; + } + else { + return py_hash_inf * mpd_arith_sign(MPD(v)); + } + } + + mpd_maxcontext(&maxctx); + exp_hash = mpd_qnew(); + if (exp_hash == NULL) { + goto malloc_error; + } + tmp = mpd_qnew(); + if (tmp == NULL) { + goto malloc_error; + } + + /* + * exp(v): exponent of v + * int(v): coefficient of v + */ + exp = MPD(v)->exp; + if (exp >= 0) { + /* 10**exp(v) % p */ + mpd_qsset_ssize(tmp, exp, &maxctx, &status); + mpd_qpowmod(exp_hash, &ten, tmp, &p, &maxctx, &status); + } + else { + /* inv10_p**(-exp(v)) % p */ + mpd_qsset_ssize(tmp, -exp, &maxctx, &status); + mpd_qpowmod(exp_hash, &inv10_p, tmp, &p, &maxctx, &status); + } + + /* hash = (int(v) * exp_hash) % p */ + if (!mpd_qcopy(tmp, MPD(v), &status)) { + goto malloc_error; + } + tmp->exp = 0; + mpd_set_positive(tmp); + + maxctx.prec = MPD_MAX_PREC + 21; + maxctx.emax = MPD_MAX_EMAX + 21; + maxctx.emin = MPD_MIN_EMIN - 21; + + mpd_qmul(tmp, tmp, exp_hash, &maxctx, &status); + mpd_qrem(tmp, tmp, &p, &maxctx, &status); + + result = mpd_qget_ssize(tmp, &status); + result = mpd_ispositive(MPD(v)) ? result : -result; + result = (result == -1) ? -2 : result; + + if (status != 0) { + if (status & MPD_Malloc_error) { + goto malloc_error; + } + else { + PyErr_SetString(PyExc_RuntimeError, /* GCOV_NOT_REACHED */ + "dec_hash: internal error: please report"); /* GCOV_NOT_REACHED */ + } + result = -1; /* GCOV_NOT_REACHED */ + } + + +finish: + if (exp_hash) mpd_del(exp_hash); + if (tmp) mpd_del(tmp); + return result; + +malloc_error: + PyErr_NoMemory(); + result = -1; + goto finish; +} + +static Py_hash_t +dec_hash(PyDecObject *self) +{ + if (self->hash == -1) { + self->hash = _dec_hash(self); + } + + return self->hash; +} + +/* __reduce__ */ +static PyObject * +dec_reduce(PyObject *self, PyObject *dummy UNUSED) +{ + PyObject *result, *str; + + str = dec_str(self); + if (str == NULL) { + return NULL; + } + + result = Py_BuildValue("O(O)", Py_TYPE(self), str); + Py_DECREF(str); + + return result; +} + +/* __sizeof__ */ +static PyObject * +dec_sizeof(PyObject *v, PyObject *dummy UNUSED) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(v)); + if (mpd_isdynamic_data(MPD(v))) { + res += MPD(v)->alloc * sizeof(mpd_uint_t); + } + return PyLong_FromSsize_t(res); +} + +/* __trunc__ */ +static PyObject * +dec_trunc(PyObject *self, PyObject *dummy UNUSED) +{ + PyObject *context; + + CURRENT_CONTEXT(context); + return dec_as_long(self, context, MPD_ROUND_DOWN); +} + +/* real and imag */ +static PyObject * +dec_real(PyObject *self, void *closure UNUSED) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +dec_imag(PyObject *self UNUSED, void *closure UNUSED) +{ + PyObject *result; + + result = dec_alloc(); + if (result == NULL) { + return NULL; + } + + _dec_settriple(result, MPD_POS, 0, 0); + return result; +} + + +static PyGetSetDef dec_getsets [] = +{ + { "real", (getter)dec_real, NULL, NULL, NULL}, + { "imag", (getter)dec_imag, NULL, NULL, NULL}, + {NULL} +}; + +static PyNumberMethods dec_number_methods = +{ + (binaryfunc) nm_mpd_qadd, + (binaryfunc) nm_mpd_qsub, + (binaryfunc) nm_mpd_qmul, + (binaryfunc) nm_mpd_qrem, + (binaryfunc) nm_mpd_qdivmod, + (ternaryfunc) nm_mpd_qpow, + (unaryfunc) nm_mpd_qminus, + (unaryfunc) nm_mpd_qplus, + (unaryfunc) nm_mpd_qabs, + (inquiry) nm_nonzero, + (unaryfunc) 0, /* no bit-complement */ + (binaryfunc) 0, /* no shiftl */ + (binaryfunc) 0, /* no shiftr */ + (binaryfunc) 0, /* no bit-and */ + (binaryfunc) 0, /* no bit-xor */ + (binaryfunc) 0, /* no bit-ior */ + (unaryfunc) nm_dec_as_long, + 0, /* nb_reserved */ + (unaryfunc) PyDec_AsFloat, + 0, /* binaryfunc nb_inplace_add; */ + 0, /* binaryfunc nb_inplace_subtract; */ + 0, /* binaryfunc nb_inplace_multiply; */ + 0, /* binaryfunc nb_inplace_remainder; */ + 0, /* ternaryfunc nb_inplace_power; */ + 0, /* binaryfunc nb_inplace_lshift; */ + 0, /* binaryfunc nb_inplace_rshift; */ + 0, /* binaryfunc nb_inplace_and; */ + 0, /* binaryfunc nb_inplace_xor; */ + 0, /* binaryfunc nb_inplace_or; */ + (binaryfunc) nm_mpd_qdivint, /* binaryfunc nb_floor_divide; */ + (binaryfunc) nm_mpd_qdiv, /* binaryfunc nb_true_divide; */ + 0, /* binaryfunc nb_inplace_floor_divide; */ + 0, /* binaryfunc nb_inplace_true_divide; */ +}; + +static PyMethodDef dec_methods [] = +{ + /* Unary arithmetic functions, optional context arg */ + { "exp", (PyCFunction)(void(*)(void))dec_mpd_qexp, METH_VARARGS|METH_KEYWORDS, doc_exp }, + { "ln", (PyCFunction)(void(*)(void))dec_mpd_qln, METH_VARARGS|METH_KEYWORDS, doc_ln }, + { "log10", (PyCFunction)(void(*)(void))dec_mpd_qlog10, METH_VARARGS|METH_KEYWORDS, doc_log10 }, + { "next_minus", (PyCFunction)(void(*)(void))dec_mpd_qnext_minus, METH_VARARGS|METH_KEYWORDS, doc_next_minus }, + { "next_plus", (PyCFunction)(void(*)(void))dec_mpd_qnext_plus, METH_VARARGS|METH_KEYWORDS, doc_next_plus }, + { "normalize", (PyCFunction)(void(*)(void))dec_mpd_qreduce, METH_VARARGS|METH_KEYWORDS, doc_normalize }, + { "to_integral", (PyCFunction)(void(*)(void))PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral }, + { "to_integral_exact", (PyCFunction)(void(*)(void))PyDec_ToIntegralExact, METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact }, + { "to_integral_value", (PyCFunction)(void(*)(void))PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral_value }, + { "sqrt", (PyCFunction)(void(*)(void))dec_mpd_qsqrt, METH_VARARGS|METH_KEYWORDS, doc_sqrt }, + + /* Binary arithmetic functions, optional context arg */ + { "compare", (PyCFunction)(void(*)(void))dec_mpd_qcompare, METH_VARARGS|METH_KEYWORDS, doc_compare }, + { "compare_signal", (PyCFunction)(void(*)(void))dec_mpd_qcompare_signal, METH_VARARGS|METH_KEYWORDS, doc_compare_signal }, + { "max", (PyCFunction)(void(*)(void))dec_mpd_qmax, METH_VARARGS|METH_KEYWORDS, doc_max }, + { "max_mag", (PyCFunction)(void(*)(void))dec_mpd_qmax_mag, METH_VARARGS|METH_KEYWORDS, doc_max_mag }, + { "min", (PyCFunction)(void(*)(void))dec_mpd_qmin, METH_VARARGS|METH_KEYWORDS, doc_min }, + { "min_mag", (PyCFunction)(void(*)(void))dec_mpd_qmin_mag, METH_VARARGS|METH_KEYWORDS, doc_min_mag }, + { "next_toward", (PyCFunction)(void(*)(void))dec_mpd_qnext_toward, METH_VARARGS|METH_KEYWORDS, doc_next_toward }, + { "quantize", (PyCFunction)(void(*)(void))dec_mpd_qquantize, METH_VARARGS|METH_KEYWORDS, doc_quantize }, + { "remainder_near", (PyCFunction)(void(*)(void))dec_mpd_qrem_near, METH_VARARGS|METH_KEYWORDS, doc_remainder_near }, + + /* Ternary arithmetic functions, optional context arg */ + { "fma", (PyCFunction)(void(*)(void))dec_mpd_qfma, METH_VARARGS|METH_KEYWORDS, doc_fma }, + + /* Boolean functions, no context arg */ + { "is_canonical", dec_mpd_iscanonical, METH_NOARGS, doc_is_canonical }, + { "is_finite", dec_mpd_isfinite, METH_NOARGS, doc_is_finite }, + { "is_infinite", dec_mpd_isinfinite, METH_NOARGS, doc_is_infinite }, + { "is_nan", dec_mpd_isnan, METH_NOARGS, doc_is_nan }, + { "is_qnan", dec_mpd_isqnan, METH_NOARGS, doc_is_qnan }, + { "is_snan", dec_mpd_issnan, METH_NOARGS, doc_is_snan }, + { "is_signed", dec_mpd_issigned, METH_NOARGS, doc_is_signed }, + { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero }, + + /* Boolean functions, optional context arg */ + { "is_normal", (PyCFunction)(void(*)(void))dec_mpd_isnormal, METH_VARARGS|METH_KEYWORDS, doc_is_normal }, + { "is_subnormal", (PyCFunction)(void(*)(void))dec_mpd_issubnormal, METH_VARARGS|METH_KEYWORDS, doc_is_subnormal }, + + /* Unary functions, no context arg */ + { "adjusted", dec_mpd_adjexp, METH_NOARGS, doc_adjusted }, + { "canonical", dec_canonical, METH_NOARGS, doc_canonical }, + { "conjugate", dec_conjugate, METH_NOARGS, doc_conjugate }, + { "radix", dec_mpd_radix, METH_NOARGS, doc_radix }, + + /* Unary functions, optional context arg for conversion errors */ + { "copy_abs", dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs }, + { "copy_negate", dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate }, + + /* Unary functions, optional context arg */ + { "logb", (PyCFunction)(void(*)(void))dec_mpd_qlogb, METH_VARARGS|METH_KEYWORDS, doc_logb }, + { "logical_invert", (PyCFunction)(void(*)(void))dec_mpd_qinvert, METH_VARARGS|METH_KEYWORDS, doc_logical_invert }, + { "number_class", (PyCFunction)(void(*)(void))dec_mpd_class, METH_VARARGS|METH_KEYWORDS, doc_number_class }, + { "to_eng_string", (PyCFunction)(void(*)(void))dec_mpd_to_eng, METH_VARARGS|METH_KEYWORDS, doc_to_eng_string }, + + /* Binary functions, optional context arg for conversion errors */ + { "compare_total", (PyCFunction)(void(*)(void))dec_mpd_compare_total, METH_VARARGS|METH_KEYWORDS, doc_compare_total }, + { "compare_total_mag", (PyCFunction)(void(*)(void))dec_mpd_compare_total_mag, METH_VARARGS|METH_KEYWORDS, doc_compare_total_mag }, + { "copy_sign", (PyCFunction)(void(*)(void))dec_mpd_qcopy_sign, METH_VARARGS|METH_KEYWORDS, doc_copy_sign }, + { "same_quantum", (PyCFunction)(void(*)(void))dec_mpd_same_quantum, METH_VARARGS|METH_KEYWORDS, doc_same_quantum }, + + /* Binary functions, optional context arg */ + { "logical_and", (PyCFunction)(void(*)(void))dec_mpd_qand, METH_VARARGS|METH_KEYWORDS, doc_logical_and }, + { "logical_or", (PyCFunction)(void(*)(void))dec_mpd_qor, METH_VARARGS|METH_KEYWORDS, doc_logical_or }, + { "logical_xor", (PyCFunction)(void(*)(void))dec_mpd_qxor, METH_VARARGS|METH_KEYWORDS, doc_logical_xor }, + { "rotate", (PyCFunction)(void(*)(void))dec_mpd_qrotate, METH_VARARGS|METH_KEYWORDS, doc_rotate }, + { "scaleb", (PyCFunction)(void(*)(void))dec_mpd_qscaleb, METH_VARARGS|METH_KEYWORDS, doc_scaleb }, + { "shift", (PyCFunction)(void(*)(void))dec_mpd_qshift, METH_VARARGS|METH_KEYWORDS, doc_shift }, + + /* Miscellaneous */ + { "from_float", dec_from_float, METH_O|METH_CLASS, doc_from_float }, + { "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple }, + { "as_integer_ratio", dec_as_integer_ratio, METH_NOARGS, doc_as_integer_ratio }, + + /* Special methods */ + { "__copy__", dec_copy, METH_NOARGS, NULL }, + { "__deepcopy__", dec_copy, METH_O, NULL }, + { "__format__", dec_format, METH_VARARGS, NULL }, + { "__reduce__", dec_reduce, METH_NOARGS, NULL }, + { "__round__", PyDec_Round, METH_VARARGS, NULL }, + { "__ceil__", dec_ceil, METH_NOARGS, NULL }, + { "__floor__", dec_floor, METH_NOARGS, NULL }, + { "__trunc__", dec_trunc, METH_NOARGS, NULL }, + { "__complex__", dec_complex, METH_NOARGS, NULL }, + { "__sizeof__", dec_sizeof, METH_NOARGS, NULL }, + + { NULL, NULL, 1 } +}; + +static PyTypeObject PyDec_Type = +{ + PyVarObject_HEAD_INIT(NULL, 0) + "decimal.Decimal", /* tp_name */ + sizeof(PyDecObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) dec_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + (getattrfunc) 0, /* tp_getattr */ + (setattrfunc) 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc) dec_repr, /* tp_repr */ + &dec_number_methods, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc) dec_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc) dec_str, /* tp_str */ + (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */ + (setattrofunc) 0, /* tp_setattro */ + (PyBufferProcs *) 0, /* tp_as_buffer */ + (Py_TPFLAGS_DEFAULT| + Py_TPFLAGS_BASETYPE), /* tp_flags */ + doc_decimal, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + dec_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + dec_methods, /* tp_methods */ + 0, /* tp_members */ + dec_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + dec_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + + +/******************************************************************************/ +/* Context Object, Part 2 */ +/******************************************************************************/ + + +/************************************************************************/ +/* Macros for converting mpdecimal functions to Context methods */ +/************************************************************************/ + +/* Boolean context method. */ +#define DecCtx_BoolFunc(MPDFUNC) \ +static PyObject * \ +ctx_##MPDFUNC(PyObject *context, PyObject *v) \ +{ \ + PyObject *ret; \ + PyObject *a; \ + \ + CONVERT_OP_RAISE(&a, v, context); \ + \ + ret = MPDFUNC(MPD(a), CTX(context)) ? incr_true() : incr_false(); \ + Py_DECREF(a); \ + return ret; \ +} + +/* Boolean context method. MPDFUNC does NOT use a context. */ +#define DecCtx_BoolFunc_NO_CTX(MPDFUNC) \ +static PyObject * \ +ctx_##MPDFUNC(PyObject *context, PyObject *v) \ +{ \ + PyObject *ret; \ + PyObject *a; \ + \ + CONVERT_OP_RAISE(&a, v, context); \ + \ + ret = MPDFUNC(MPD(a)) ? incr_true() : incr_false(); \ + Py_DECREF(a); \ + return ret; \ +} + +/* Unary context method. */ +#define DecCtx_UnaryFunc(MPDFUNC) \ +static PyObject * \ +ctx_##MPDFUNC(PyObject *context, PyObject *v) \ +{ \ + PyObject *result, *a; \ + uint32_t status = 0; \ + \ + CONVERT_OP_RAISE(&a, v, context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + Py_DECREF(a); \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(a), CTX(context), &status); \ + Py_DECREF(a); \ + if (dec_addstatus(context, status)) { \ + Py_DECREF(result); \ + return NULL; \ + } \ + \ + return result; \ +} + +/* Binary context method. */ +#define DecCtx_BinaryFunc(MPDFUNC) \ +static PyObject * \ +ctx_##MPDFUNC(PyObject *context, PyObject *args) \ +{ \ + PyObject *v, *w; \ + PyObject *a, *b; \ + PyObject *result; \ + uint32_t status = 0; \ + \ + if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \ + return NULL; \ + } \ + \ + CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + Py_DECREF(a); \ + Py_DECREF(b); \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \ + Py_DECREF(a); \ + Py_DECREF(b); \ + if (dec_addstatus(context, status)) { \ + Py_DECREF(result); \ + return NULL; \ + } \ + \ + return result; \ +} + +/* + * Binary context method. The context is only used for conversion. + * The actual MPDFUNC does NOT take a context arg. + */ +#define DecCtx_BinaryFunc_NO_CTX(MPDFUNC) \ +static PyObject * \ +ctx_##MPDFUNC(PyObject *context, PyObject *args) \ +{ \ + PyObject *v, *w; \ + PyObject *a, *b; \ + PyObject *result; \ + \ + if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \ + return NULL; \ + } \ + \ + CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + Py_DECREF(a); \ + Py_DECREF(b); \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(a), MPD(b)); \ + Py_DECREF(a); \ + Py_DECREF(b); \ + \ + return result; \ +} + +/* Ternary context method. */ +#define DecCtx_TernaryFunc(MPDFUNC) \ +static PyObject * \ +ctx_##MPDFUNC(PyObject *context, PyObject *args) \ +{ \ + PyObject *v, *w, *x; \ + PyObject *a, *b, *c; \ + PyObject *result; \ + uint32_t status = 0; \ + \ + if (!PyArg_ParseTuple(args, "OOO", &v, &w, &x)) { \ + return NULL; \ + } \ + \ + CONVERT_TERNOP_RAISE(&a, &b, &c, v, w, x, context); \ + \ + if ((result = dec_alloc()) == NULL) { \ + Py_DECREF(a); \ + Py_DECREF(b); \ + Py_DECREF(c); \ + return NULL; \ + } \ + \ + MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \ + Py_DECREF(a); \ + Py_DECREF(b); \ + Py_DECREF(c); \ + if (dec_addstatus(context, status)) { \ + Py_DECREF(result); \ + return NULL; \ + } \ + \ + return result; \ +} + + +/* Unary arithmetic functions */ +DecCtx_UnaryFunc(mpd_qabs) +DecCtx_UnaryFunc(mpd_qexp) +DecCtx_UnaryFunc(mpd_qln) +DecCtx_UnaryFunc(mpd_qlog10) +DecCtx_UnaryFunc(mpd_qminus) +DecCtx_UnaryFunc(mpd_qnext_minus) +DecCtx_UnaryFunc(mpd_qnext_plus) +DecCtx_UnaryFunc(mpd_qplus) +DecCtx_UnaryFunc(mpd_qreduce) +DecCtx_UnaryFunc(mpd_qround_to_int) +DecCtx_UnaryFunc(mpd_qround_to_intx) +DecCtx_UnaryFunc(mpd_qsqrt) + +/* Binary arithmetic functions */ +DecCtx_BinaryFunc(mpd_qadd) +DecCtx_BinaryFunc(mpd_qcompare) +DecCtx_BinaryFunc(mpd_qcompare_signal) +DecCtx_BinaryFunc(mpd_qdiv) +DecCtx_BinaryFunc(mpd_qdivint) +DecCtx_BinaryFunc(mpd_qmax) +DecCtx_BinaryFunc(mpd_qmax_mag) +DecCtx_BinaryFunc(mpd_qmin) +DecCtx_BinaryFunc(mpd_qmin_mag) +DecCtx_BinaryFunc(mpd_qmul) +DecCtx_BinaryFunc(mpd_qnext_toward) +DecCtx_BinaryFunc(mpd_qquantize) +DecCtx_BinaryFunc(mpd_qrem) +DecCtx_BinaryFunc(mpd_qrem_near) +DecCtx_BinaryFunc(mpd_qsub) + +static PyObject * +ctx_mpd_qdivmod(PyObject *context, PyObject *args) +{ + PyObject *v, *w; + PyObject *a, *b; + PyObject *q, *r; + uint32_t status = 0; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "OO", &v, &w)) { + return NULL; + } + + CONVERT_BINOP_RAISE(&a, &b, v, w, context); + + q = dec_alloc(); + if (q == NULL) { + Py_DECREF(a); + Py_DECREF(b); + return NULL; + } + r = dec_alloc(); + if (r == NULL) { + Py_DECREF(a); + Py_DECREF(b); + Py_DECREF(q); + return NULL; + } + + mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status); + Py_DECREF(a); + Py_DECREF(b); + if (dec_addstatus(context, status)) { + Py_DECREF(r); + Py_DECREF(q); + return NULL; + } + + ret = Py_BuildValue("(OO)", q, r); + Py_DECREF(r); + Py_DECREF(q); + return ret; +} + +/* Binary or ternary arithmetic functions */ +static PyObject * +ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"a", "b", "modulo", NULL}; + PyObject *base, *exp, *mod = Py_None; + PyObject *a, *b, *c = NULL; + PyObject *result; + uint32_t status = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, + &base, &exp, &mod)) { + return NULL; + } + + CONVERT_BINOP_RAISE(&a, &b, base, exp, context); + + if (mod != Py_None) { + if (!convert_op(TYPE_ERR, &c, mod, context)) { + Py_DECREF(a); + Py_DECREF(b); + return c; + } + } + + result = dec_alloc(); + if (result == NULL) { + Py_DECREF(a); + Py_DECREF(b); + Py_XDECREF(c); + return NULL; + } + + if (c == NULL) { + mpd_qpow(MPD(result), MPD(a), MPD(b), + CTX(context), &status); + } + else { + mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c), + CTX(context), &status); + Py_DECREF(c); + } + Py_DECREF(a); + Py_DECREF(b); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +/* Ternary arithmetic functions */ +DecCtx_TernaryFunc(mpd_qfma) + +/* No argument */ +static PyObject * +ctx_mpd_radix(PyObject *context, PyObject *dummy) +{ + return dec_mpd_radix(context, dummy); +} + +/* Boolean functions: single decimal argument */ +DecCtx_BoolFunc(mpd_isnormal) +DecCtx_BoolFunc(mpd_issubnormal) +DecCtx_BoolFunc_NO_CTX(mpd_isfinite) +DecCtx_BoolFunc_NO_CTX(mpd_isinfinite) +DecCtx_BoolFunc_NO_CTX(mpd_isnan) +DecCtx_BoolFunc_NO_CTX(mpd_isqnan) +DecCtx_BoolFunc_NO_CTX(mpd_issigned) +DecCtx_BoolFunc_NO_CTX(mpd_issnan) +DecCtx_BoolFunc_NO_CTX(mpd_iszero) + +static PyObject * +ctx_iscanonical(PyObject *context UNUSED, PyObject *v) +{ + if (!PyDec_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "argument must be a Decimal"); + return NULL; + } + + return mpd_iscanonical(MPD(v)) ? incr_true() : incr_false(); +} + +/* Functions with a single decimal argument */ +static PyObject * +PyDecContext_Apply(PyObject *context, PyObject *v) +{ + PyObject *result, *a; + + CONVERT_OP_RAISE(&a, v, context); + + result = dec_apply(a, context); + Py_DECREF(a); + return result; +} + +static PyObject * +ctx_canonical(PyObject *context UNUSED, PyObject *v) +{ + if (!PyDec_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "argument must be a Decimal"); + return NULL; + } + + Py_INCREF(v); + return v; +} + +static PyObject * +ctx_mpd_qcopy_abs(PyObject *context, PyObject *v) +{ + PyObject *result, *a; + uint32_t status = 0; + + CONVERT_OP_RAISE(&a, v, context); + + result = dec_alloc(); + if (result == NULL) { + Py_DECREF(a); + return NULL; + } + + mpd_qcopy_abs(MPD(result), MPD(a), &status); + Py_DECREF(a); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +static PyObject * +ctx_copy_decimal(PyObject *context, PyObject *v) +{ + PyObject *result; + + CONVERT_OP_RAISE(&result, v, context); + return result; +} + +static PyObject * +ctx_mpd_qcopy_negate(PyObject *context, PyObject *v) +{ + PyObject *result, *a; + uint32_t status = 0; + + CONVERT_OP_RAISE(&a, v, context); + + result = dec_alloc(); + if (result == NULL) { + Py_DECREF(a); + return NULL; + } + + mpd_qcopy_negate(MPD(result), MPD(a), &status); + Py_DECREF(a); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +DecCtx_UnaryFunc(mpd_qlogb) +DecCtx_UnaryFunc(mpd_qinvert) + +static PyObject * +ctx_mpd_class(PyObject *context, PyObject *v) +{ + PyObject *a; + const char *cp; + + CONVERT_OP_RAISE(&a, v, context); + + cp = mpd_class(MPD(a), CTX(context)); + Py_DECREF(a); + + return PyUnicode_FromString(cp); +} + +static PyObject * +ctx_mpd_to_sci(PyObject *context, PyObject *v) +{ + PyObject *result; + PyObject *a; + mpd_ssize_t size; + char *s; + + CONVERT_OP_RAISE(&a, v, context); + + size = mpd_to_sci_size(&s, MPD(a), CtxCaps(context)); + Py_DECREF(a); + if (size < 0) { + PyErr_NoMemory(); + return NULL; + } + + result = unicode_fromascii(s, size); + mpd_free(s); + + return result; +} + +static PyObject * +ctx_mpd_to_eng(PyObject *context, PyObject *v) +{ + PyObject *result; + PyObject *a; + mpd_ssize_t size; + char *s; + + CONVERT_OP_RAISE(&a, v, context); + + size = mpd_to_eng_size(&s, MPD(a), CtxCaps(context)); + Py_DECREF(a); + if (size < 0) { + PyErr_NoMemory(); + return NULL; + } + + result = unicode_fromascii(s, size); + mpd_free(s); + + return result; +} + +/* Functions with two decimal arguments */ +DecCtx_BinaryFunc_NO_CTX(mpd_compare_total) +DecCtx_BinaryFunc_NO_CTX(mpd_compare_total_mag) + +static PyObject * +ctx_mpd_qcopy_sign(PyObject *context, PyObject *args) +{ + PyObject *v, *w; + PyObject *a, *b; + PyObject *result; + uint32_t status = 0; + + if (!PyArg_ParseTuple(args, "OO", &v, &w)) { + return NULL; + } + + CONVERT_BINOP_RAISE(&a, &b, v, w, context); + + result = dec_alloc(); + if (result == NULL) { + Py_DECREF(a); + Py_DECREF(b); + return NULL; + } + + mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status); + Py_DECREF(a); + Py_DECREF(b); + if (dec_addstatus(context, status)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +DecCtx_BinaryFunc(mpd_qand) +DecCtx_BinaryFunc(mpd_qor) +DecCtx_BinaryFunc(mpd_qxor) + +DecCtx_BinaryFunc(mpd_qrotate) +DecCtx_BinaryFunc(mpd_qscaleb) +DecCtx_BinaryFunc(mpd_qshift) + +static PyObject * +ctx_mpd_same_quantum(PyObject *context, PyObject *args) +{ + PyObject *v, *w; + PyObject *a, *b; + PyObject *result; + + if (!PyArg_ParseTuple(args, "OO", &v, &w)) { + return NULL; + } + + CONVERT_BINOP_RAISE(&a, &b, v, w, context); + + result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false(); + Py_DECREF(a); + Py_DECREF(b); + + return result; +} + + +static PyMethodDef context_methods [] = +{ + /* Unary arithmetic functions */ + { "abs", ctx_mpd_qabs, METH_O, doc_ctx_abs }, + { "exp", ctx_mpd_qexp, METH_O, doc_ctx_exp }, + { "ln", ctx_mpd_qln, METH_O, doc_ctx_ln }, + { "log10", ctx_mpd_qlog10, METH_O, doc_ctx_log10 }, + { "minus", ctx_mpd_qminus, METH_O, doc_ctx_minus }, + { "next_minus", ctx_mpd_qnext_minus, METH_O, doc_ctx_next_minus }, + { "next_plus", ctx_mpd_qnext_plus, METH_O, doc_ctx_next_plus }, + { "normalize", ctx_mpd_qreduce, METH_O, doc_ctx_normalize }, + { "plus", ctx_mpd_qplus, METH_O, doc_ctx_plus }, + { "to_integral", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral }, + { "to_integral_exact", ctx_mpd_qround_to_intx, METH_O, doc_ctx_to_integral_exact }, + { "to_integral_value", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral_value }, + { "sqrt", ctx_mpd_qsqrt, METH_O, doc_ctx_sqrt }, + + /* Binary arithmetic functions */ + { "add", ctx_mpd_qadd, METH_VARARGS, doc_ctx_add }, + { "compare", ctx_mpd_qcompare, METH_VARARGS, doc_ctx_compare }, + { "compare_signal", ctx_mpd_qcompare_signal, METH_VARARGS, doc_ctx_compare_signal }, + { "divide", ctx_mpd_qdiv, METH_VARARGS, doc_ctx_divide }, + { "divide_int", ctx_mpd_qdivint, METH_VARARGS, doc_ctx_divide_int }, + { "divmod", ctx_mpd_qdivmod, METH_VARARGS, doc_ctx_divmod }, + { "max", ctx_mpd_qmax, METH_VARARGS, doc_ctx_max }, + { "max_mag", ctx_mpd_qmax_mag, METH_VARARGS, doc_ctx_max_mag }, + { "min", ctx_mpd_qmin, METH_VARARGS, doc_ctx_min }, + { "min_mag", ctx_mpd_qmin_mag, METH_VARARGS, doc_ctx_min_mag }, + { "multiply", ctx_mpd_qmul, METH_VARARGS, doc_ctx_multiply }, + { "next_toward", ctx_mpd_qnext_toward, METH_VARARGS, doc_ctx_next_toward }, + { "quantize", ctx_mpd_qquantize, METH_VARARGS, doc_ctx_quantize }, + { "remainder", ctx_mpd_qrem, METH_VARARGS, doc_ctx_remainder }, + { "remainder_near", ctx_mpd_qrem_near, METH_VARARGS, doc_ctx_remainder_near }, + { "subtract", ctx_mpd_qsub, METH_VARARGS, doc_ctx_subtract }, + + /* Binary or ternary arithmetic functions */ + { "power", (PyCFunction)(void(*)(void))ctx_mpd_qpow, METH_VARARGS|METH_KEYWORDS, doc_ctx_power }, + + /* Ternary arithmetic functions */ + { "fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma }, + + /* No argument */ + { "Etiny", context_getetiny, METH_NOARGS, doc_ctx_Etiny }, + { "Etop", context_getetop, METH_NOARGS, doc_ctx_Etop }, + { "radix", ctx_mpd_radix, METH_NOARGS, doc_ctx_radix }, + + /* Boolean functions */ + { "is_canonical", ctx_iscanonical, METH_O, doc_ctx_is_canonical }, + { "is_finite", ctx_mpd_isfinite, METH_O, doc_ctx_is_finite }, + { "is_infinite", ctx_mpd_isinfinite, METH_O, doc_ctx_is_infinite }, + { "is_nan", ctx_mpd_isnan, METH_O, doc_ctx_is_nan }, + { "is_normal", ctx_mpd_isnormal, METH_O, doc_ctx_is_normal }, + { "is_qnan", ctx_mpd_isqnan, METH_O, doc_ctx_is_qnan }, + { "is_signed", ctx_mpd_issigned, METH_O, doc_ctx_is_signed }, + { "is_snan", ctx_mpd_issnan, METH_O, doc_ctx_is_snan }, + { "is_subnormal", ctx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal }, + { "is_zero", ctx_mpd_iszero, METH_O, doc_ctx_is_zero }, + + /* Functions with a single decimal argument */ + { "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */ +#ifdef EXTRA_FUNCTIONALITY + { "apply", PyDecContext_Apply, METH_O, doc_ctx_apply }, +#endif + { "canonical", ctx_canonical, METH_O, doc_ctx_canonical }, + { "copy_abs", ctx_mpd_qcopy_abs, METH_O, doc_ctx_copy_abs }, + { "copy_decimal", ctx_copy_decimal, METH_O, doc_ctx_copy_decimal }, + { "copy_negate", ctx_mpd_qcopy_negate, METH_O, doc_ctx_copy_negate }, + { "logb", ctx_mpd_qlogb, METH_O, doc_ctx_logb }, + { "logical_invert", ctx_mpd_qinvert, METH_O, doc_ctx_logical_invert }, + { "number_class", ctx_mpd_class, METH_O, doc_ctx_number_class }, + { "to_sci_string", ctx_mpd_to_sci, METH_O, doc_ctx_to_sci_string }, + { "to_eng_string", ctx_mpd_to_eng, METH_O, doc_ctx_to_eng_string }, + + /* Functions with two decimal arguments */ + { "compare_total", ctx_mpd_compare_total, METH_VARARGS, doc_ctx_compare_total }, + { "compare_total_mag", ctx_mpd_compare_total_mag, METH_VARARGS, doc_ctx_compare_total_mag }, + { "copy_sign", ctx_mpd_qcopy_sign, METH_VARARGS, doc_ctx_copy_sign }, + { "logical_and", ctx_mpd_qand, METH_VARARGS, doc_ctx_logical_and }, + { "logical_or", ctx_mpd_qor, METH_VARARGS, doc_ctx_logical_or }, + { "logical_xor", ctx_mpd_qxor, METH_VARARGS, doc_ctx_logical_xor }, + { "rotate", ctx_mpd_qrotate, METH_VARARGS, doc_ctx_rotate }, + { "same_quantum", ctx_mpd_same_quantum, METH_VARARGS, doc_ctx_same_quantum }, + { "scaleb", ctx_mpd_qscaleb, METH_VARARGS, doc_ctx_scaleb }, + { "shift", ctx_mpd_qshift, METH_VARARGS, doc_ctx_shift }, + + /* Set context values */ + { "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags }, + { "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps }, + +#ifdef CONFIG_32 + /* Unsafe set functions with relaxed range checks */ + { "_unsafe_setprec", context_unsafe_setprec, METH_O, NULL }, + { "_unsafe_setemin", context_unsafe_setemin, METH_O, NULL }, + { "_unsafe_setemax", context_unsafe_setemax, METH_O, NULL }, +#endif + + /* Miscellaneous */ + { "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL }, + { "__reduce__", context_reduce, METH_NOARGS, NULL }, + { "copy", (PyCFunction)context_copy, METH_NOARGS, doc_ctx_copy }, + { "create_decimal", ctx_create_decimal, METH_VARARGS, doc_ctx_create_decimal }, + { "create_decimal_from_float", ctx_from_float, METH_O, doc_ctx_create_decimal_from_float }, + + { NULL, NULL, 1 } +}; + +static PyTypeObject PyDecContext_Type = +{ + PyVarObject_HEAD_INIT(NULL, 0) + "decimal.Context", /* tp_name */ + sizeof(PyDecContextObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) context_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - (getattrfunc) 0, /* tp_getattr */ - (setattrfunc) 0, /* tp_setattr */ + (getattrfunc) 0, /* tp_getattr */ + (setattrfunc) 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc) context_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc) 0, /* tp_hash */ - 0, /* tp_call */ + (reprfunc) context_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc) 0, /* tp_hash */ + 0, /* tp_call */ 0, /* tp_str */ - (getattrofunc) context_getattr, /* tp_getattro */ - (setattrofunc) context_setattr, /* tp_setattro */ - (PyBufferProcs *) 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - doc_context, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - context_methods, /* tp_methods */ - 0, /* tp_members */ - context_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - context_init, /* tp_init */ - 0, /* tp_alloc */ - context_new, /* tp_new */ - PyObject_Del, /* tp_free */ -}; - - -static PyMethodDef _decimal_methods [] = -{ - { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext}, - { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext}, + (getattrofunc) context_getattr, /* tp_getattro */ + (setattrofunc) context_setattr, /* tp_setattro */ + (PyBufferProcs *) 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ + doc_context, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + context_methods, /* tp_methods */ + 0, /* tp_members */ + context_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + context_init, /* tp_init */ + 0, /* tp_alloc */ + context_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + + +static PyMethodDef _decimal_methods [] = +{ + { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext}, + { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext}, { "localcontext", (PyCFunction)(void(*)(void))ctxmanager_new, METH_VARARGS|METH_KEYWORDS, doc_localcontext}, -#ifdef EXTRA_FUNCTIONALITY - { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context}, -#endif - { NULL, NULL, 1, NULL } -}; - -static struct PyModuleDef _decimal_module = { - PyModuleDef_HEAD_INIT, - "decimal", - doc__decimal, - -1, - _decimal_methods, - NULL, - NULL, - NULL, - NULL -}; - -struct ssize_constmap { const char *name; mpd_ssize_t val; }; -static struct ssize_constmap ssize_constants [] = { - {"MAX_PREC", MPD_MAX_PREC}, - {"MAX_EMAX", MPD_MAX_EMAX}, - {"MIN_EMIN", MPD_MIN_EMIN}, - {"MIN_ETINY", MPD_MIN_ETINY}, - {NULL} -}; - -struct int_constmap { const char *name; int val; }; -static struct int_constmap int_constants [] = { - /* int constants */ -#ifdef EXTRA_FUNCTIONALITY - {"DECIMAL32", MPD_DECIMAL32}, - {"DECIMAL64", MPD_DECIMAL64}, - {"DECIMAL128", MPD_DECIMAL128}, - {"IEEE_CONTEXT_MAX_BITS", MPD_IEEE_CONTEXT_MAX_BITS}, - /* int condition flags */ - {"DecClamped", MPD_Clamped}, - {"DecConversionSyntax", MPD_Conversion_syntax}, - {"DecDivisionByZero", MPD_Division_by_zero}, - {"DecDivisionImpossible", MPD_Division_impossible}, - {"DecDivisionUndefined", MPD_Division_undefined}, - {"DecFpuError", MPD_Fpu_error}, - {"DecInexact", MPD_Inexact}, - {"DecInvalidContext", MPD_Invalid_context}, - {"DecInvalidOperation", MPD_Invalid_operation}, - {"DecIEEEInvalidOperation", MPD_IEEE_Invalid_operation}, - {"DecMallocError", MPD_Malloc_error}, - {"DecFloatOperation", MPD_Float_operation}, - {"DecOverflow", MPD_Overflow}, - {"DecRounded", MPD_Rounded}, - {"DecSubnormal", MPD_Subnormal}, - {"DecUnderflow", MPD_Underflow}, - {"DecErrors", MPD_Errors}, - {"DecTraps", MPD_Traps}, -#endif - {NULL} -}; - - -#define CHECK_INT(expr) \ - do { if ((expr) < 0) goto error; } while (0) -#define ASSIGN_PTR(result, expr) \ - do { result = (expr); if (result == NULL) goto error; } while (0) -#define CHECK_PTR(expr) \ - do { if ((expr) == NULL) goto error; } while (0) - - -static PyCFunction -cfunc_noargs(PyTypeObject *t, const char *name) -{ - struct PyMethodDef *m; - - if (t->tp_methods == NULL) { - goto error; - } - - for (m = t->tp_methods; m->ml_name != NULL; m++) { - if (strcmp(name, m->ml_name) == 0) { - if (!(m->ml_flags & METH_NOARGS)) { - goto error; - } - return m->ml_meth; - } - } - -error: - PyErr_Format(PyExc_RuntimeError, - "internal error: could not find method %s", name); - return NULL; -} - - -PyMODINIT_FUNC -PyInit__decimal(void) -{ - PyObject *m = NULL; - PyObject *numbers = NULL; - PyObject *Number = NULL; - PyObject *collections = NULL; - PyObject *collections_abc = NULL; - PyObject *MutableMapping = NULL; - PyObject *obj = NULL; - DecCondMap *cm; - struct ssize_constmap *ssize_cm; - struct int_constmap *int_cm; - int i; - - - /* Init libmpdec */ - mpd_traphandler = dec_traphandler; - mpd_mallocfunc = PyMem_Malloc; - mpd_reallocfunc = PyMem_Realloc; - mpd_callocfunc = mpd_callocfunc_em; - mpd_free = PyMem_Free; - mpd_setminalloc(_Py_DEC_MINALLOC); - - - /* Init external C-API functions */ - _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; - _py_long_floor_divide = PyLong_Type.tp_as_number->nb_floor_divide; - _py_long_power = PyLong_Type.tp_as_number->nb_power; - _py_float_abs = PyFloat_Type.tp_as_number->nb_absolute; - ASSIGN_PTR(_py_float_as_integer_ratio, cfunc_noargs(&PyFloat_Type, - "as_integer_ratio")); - ASSIGN_PTR(_py_long_bit_length, cfunc_noargs(&PyLong_Type, "bit_length")); - - - /* Init types */ - PyDec_Type.tp_base = &PyBaseObject_Type; - PyDecContext_Type.tp_base = &PyBaseObject_Type; - PyDecContextManager_Type.tp_base = &PyBaseObject_Type; - PyDecSignalDictMixin_Type.tp_base = &PyBaseObject_Type; - - CHECK_INT(PyType_Ready(&PyDec_Type)); - CHECK_INT(PyType_Ready(&PyDecContext_Type)); - CHECK_INT(PyType_Ready(&PyDecSignalDictMixin_Type)); - CHECK_INT(PyType_Ready(&PyDecContextManager_Type)); - - ASSIGN_PTR(obj, PyUnicode_FromString("decimal")); - CHECK_INT(PyDict_SetItemString(PyDec_Type.tp_dict, "__module__", obj)); - CHECK_INT(PyDict_SetItemString(PyDecContext_Type.tp_dict, - "__module__", obj)); - Py_CLEAR(obj); - - - /* Numeric abstract base classes */ - ASSIGN_PTR(numbers, PyImport_ImportModule("numbers")); - ASSIGN_PTR(Number, PyObject_GetAttrString(numbers, "Number")); - /* Register Decimal with the Number abstract base class */ - ASSIGN_PTR(obj, PyObject_CallMethod(Number, "register", "(O)", - (PyObject *)&PyDec_Type)); - Py_CLEAR(obj); - /* Rational is a global variable used for fraction comparisons. */ - ASSIGN_PTR(Rational, PyObject_GetAttrString(numbers, "Rational")); - /* Done with numbers, Number */ - Py_CLEAR(numbers); - Py_CLEAR(Number); - - /* DecimalTuple */ - ASSIGN_PTR(collections, PyImport_ImportModule("collections")); - ASSIGN_PTR(DecimalTuple, (PyTypeObject *)PyObject_CallMethod(collections, - "namedtuple", "(ss)", "DecimalTuple", - "sign digits exponent")); - - ASSIGN_PTR(obj, PyUnicode_FromString("decimal")); - CHECK_INT(PyDict_SetItemString(DecimalTuple->tp_dict, "__module__", obj)); - Py_CLEAR(obj); - - /* MutableMapping */ - ASSIGN_PTR(collections_abc, PyImport_ImportModule("collections.abc")); - ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections_abc, - "MutableMapping")); - /* Create SignalDict type */ - ASSIGN_PTR(PyDecSignalDict_Type, - (PyTypeObject *)PyObject_CallFunction( - (PyObject *)&PyType_Type, "s(OO){}", - "SignalDict", &PyDecSignalDictMixin_Type, - MutableMapping)); - - /* Done with collections, MutableMapping */ - Py_CLEAR(collections); - Py_CLEAR(collections_abc); - Py_CLEAR(MutableMapping); - - - /* Create the module */ - ASSIGN_PTR(m, PyModule_Create(&_decimal_module)); - - - /* Add types to the module */ - Py_INCREF(&PyDec_Type); - CHECK_INT(PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type)); - Py_INCREF(&PyDecContext_Type); - CHECK_INT(PyModule_AddObject(m, "Context", - (PyObject *)&PyDecContext_Type)); - Py_INCREF(DecimalTuple); - CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple)); - - - /* Create top level exception */ - ASSIGN_PTR(DecimalException, PyErr_NewException( - "decimal.DecimalException", - PyExc_ArithmeticError, NULL)); - Py_INCREF(DecimalException); - CHECK_INT(PyModule_AddObject(m, "DecimalException", DecimalException)); - - /* Create signal tuple */ - ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN)); - - /* Add exceptions that correspond to IEEE signals */ - for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) { - PyObject *base; - - cm = signal_map + i; - - switch (cm->flag) { - case MPD_Float_operation: - base = PyTuple_Pack(2, DecimalException, PyExc_TypeError); - break; - case MPD_Division_by_zero: - base = PyTuple_Pack(2, DecimalException, PyExc_ZeroDivisionError); - break; - case MPD_Overflow: - base = PyTuple_Pack(2, signal_map[INEXACT].ex, - signal_map[ROUNDED].ex); - break; - case MPD_Underflow: - base = PyTuple_Pack(3, signal_map[INEXACT].ex, - signal_map[ROUNDED].ex, - signal_map[SUBNORMAL].ex); - break; - default: - base = PyTuple_Pack(1, DecimalException); - break; - } - - if (base == NULL) { - goto error; /* GCOV_NOT_REACHED */ - } - - ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); - Py_DECREF(base); - - /* add to module */ - Py_INCREF(cm->ex); - CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex)); - - /* add to signal tuple */ - Py_INCREF(cm->ex); - PyTuple_SET_ITEM(SignalTuple, i, cm->ex); - } - - /* - * Unfortunately, InvalidOperation is a signal that comprises - * several conditions, including InvalidOperation! Naming the - * signal IEEEInvalidOperation would prevent the confusion. - */ - cond_map[0].ex = signal_map[0].ex; - - /* Add remaining exceptions, inherit from InvalidOperation */ - for (cm = cond_map+1; cm->name != NULL; cm++) { - PyObject *base; - if (cm->flag == MPD_Division_undefined) { - base = PyTuple_Pack(2, signal_map[0].ex, PyExc_ZeroDivisionError); - } - else { - base = PyTuple_Pack(1, signal_map[0].ex); - } - if (base == NULL) { - goto error; /* GCOV_NOT_REACHED */ - } - - ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); - Py_DECREF(base); - - Py_INCREF(cm->ex); - CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex)); - } - - - /* Init default context template first */ - ASSIGN_PTR(default_context_template, - PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); - Py_INCREF(default_context_template); - CHECK_INT(PyModule_AddObject(m, "DefaultContext", - default_context_template)); - +#ifdef EXTRA_FUNCTIONALITY + { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context}, +#endif + { NULL, NULL, 1, NULL } +}; + +static struct PyModuleDef _decimal_module = { + PyModuleDef_HEAD_INIT, + "decimal", + doc__decimal, + -1, + _decimal_methods, + NULL, + NULL, + NULL, + NULL +}; + +struct ssize_constmap { const char *name; mpd_ssize_t val; }; +static struct ssize_constmap ssize_constants [] = { + {"MAX_PREC", MPD_MAX_PREC}, + {"MAX_EMAX", MPD_MAX_EMAX}, + {"MIN_EMIN", MPD_MIN_EMIN}, + {"MIN_ETINY", MPD_MIN_ETINY}, + {NULL} +}; + +struct int_constmap { const char *name; int val; }; +static struct int_constmap int_constants [] = { + /* int constants */ +#ifdef EXTRA_FUNCTIONALITY + {"DECIMAL32", MPD_DECIMAL32}, + {"DECIMAL64", MPD_DECIMAL64}, + {"DECIMAL128", MPD_DECIMAL128}, + {"IEEE_CONTEXT_MAX_BITS", MPD_IEEE_CONTEXT_MAX_BITS}, + /* int condition flags */ + {"DecClamped", MPD_Clamped}, + {"DecConversionSyntax", MPD_Conversion_syntax}, + {"DecDivisionByZero", MPD_Division_by_zero}, + {"DecDivisionImpossible", MPD_Division_impossible}, + {"DecDivisionUndefined", MPD_Division_undefined}, + {"DecFpuError", MPD_Fpu_error}, + {"DecInexact", MPD_Inexact}, + {"DecInvalidContext", MPD_Invalid_context}, + {"DecInvalidOperation", MPD_Invalid_operation}, + {"DecIEEEInvalidOperation", MPD_IEEE_Invalid_operation}, + {"DecMallocError", MPD_Malloc_error}, + {"DecFloatOperation", MPD_Float_operation}, + {"DecOverflow", MPD_Overflow}, + {"DecRounded", MPD_Rounded}, + {"DecSubnormal", MPD_Subnormal}, + {"DecUnderflow", MPD_Underflow}, + {"DecErrors", MPD_Errors}, + {"DecTraps", MPD_Traps}, +#endif + {NULL} +}; + + +#define CHECK_INT(expr) \ + do { if ((expr) < 0) goto error; } while (0) +#define ASSIGN_PTR(result, expr) \ + do { result = (expr); if (result == NULL) goto error; } while (0) +#define CHECK_PTR(expr) \ + do { if ((expr) == NULL) goto error; } while (0) + + +static PyCFunction +cfunc_noargs(PyTypeObject *t, const char *name) +{ + struct PyMethodDef *m; + + if (t->tp_methods == NULL) { + goto error; + } + + for (m = t->tp_methods; m->ml_name != NULL; m++) { + if (strcmp(name, m->ml_name) == 0) { + if (!(m->ml_flags & METH_NOARGS)) { + goto error; + } + return m->ml_meth; + } + } + +error: + PyErr_Format(PyExc_RuntimeError, + "internal error: could not find method %s", name); + return NULL; +} + + +PyMODINIT_FUNC +PyInit__decimal(void) +{ + PyObject *m = NULL; + PyObject *numbers = NULL; + PyObject *Number = NULL; + PyObject *collections = NULL; + PyObject *collections_abc = NULL; + PyObject *MutableMapping = NULL; + PyObject *obj = NULL; + DecCondMap *cm; + struct ssize_constmap *ssize_cm; + struct int_constmap *int_cm; + int i; + + + /* Init libmpdec */ + mpd_traphandler = dec_traphandler; + mpd_mallocfunc = PyMem_Malloc; + mpd_reallocfunc = PyMem_Realloc; + mpd_callocfunc = mpd_callocfunc_em; + mpd_free = PyMem_Free; + mpd_setminalloc(_Py_DEC_MINALLOC); + + + /* Init external C-API functions */ + _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; + _py_long_floor_divide = PyLong_Type.tp_as_number->nb_floor_divide; + _py_long_power = PyLong_Type.tp_as_number->nb_power; + _py_float_abs = PyFloat_Type.tp_as_number->nb_absolute; + ASSIGN_PTR(_py_float_as_integer_ratio, cfunc_noargs(&PyFloat_Type, + "as_integer_ratio")); + ASSIGN_PTR(_py_long_bit_length, cfunc_noargs(&PyLong_Type, "bit_length")); + + + /* Init types */ + PyDec_Type.tp_base = &PyBaseObject_Type; + PyDecContext_Type.tp_base = &PyBaseObject_Type; + PyDecContextManager_Type.tp_base = &PyBaseObject_Type; + PyDecSignalDictMixin_Type.tp_base = &PyBaseObject_Type; + + CHECK_INT(PyType_Ready(&PyDec_Type)); + CHECK_INT(PyType_Ready(&PyDecContext_Type)); + CHECK_INT(PyType_Ready(&PyDecSignalDictMixin_Type)); + CHECK_INT(PyType_Ready(&PyDecContextManager_Type)); + + ASSIGN_PTR(obj, PyUnicode_FromString("decimal")); + CHECK_INT(PyDict_SetItemString(PyDec_Type.tp_dict, "__module__", obj)); + CHECK_INT(PyDict_SetItemString(PyDecContext_Type.tp_dict, + "__module__", obj)); + Py_CLEAR(obj); + + + /* Numeric abstract base classes */ + ASSIGN_PTR(numbers, PyImport_ImportModule("numbers")); + ASSIGN_PTR(Number, PyObject_GetAttrString(numbers, "Number")); + /* Register Decimal with the Number abstract base class */ + ASSIGN_PTR(obj, PyObject_CallMethod(Number, "register", "(O)", + (PyObject *)&PyDec_Type)); + Py_CLEAR(obj); + /* Rational is a global variable used for fraction comparisons. */ + ASSIGN_PTR(Rational, PyObject_GetAttrString(numbers, "Rational")); + /* Done with numbers, Number */ + Py_CLEAR(numbers); + Py_CLEAR(Number); + + /* DecimalTuple */ + ASSIGN_PTR(collections, PyImport_ImportModule("collections")); + ASSIGN_PTR(DecimalTuple, (PyTypeObject *)PyObject_CallMethod(collections, + "namedtuple", "(ss)", "DecimalTuple", + "sign digits exponent")); + + ASSIGN_PTR(obj, PyUnicode_FromString("decimal")); + CHECK_INT(PyDict_SetItemString(DecimalTuple->tp_dict, "__module__", obj)); + Py_CLEAR(obj); + + /* MutableMapping */ + ASSIGN_PTR(collections_abc, PyImport_ImportModule("collections.abc")); + ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections_abc, + "MutableMapping")); + /* Create SignalDict type */ + ASSIGN_PTR(PyDecSignalDict_Type, + (PyTypeObject *)PyObject_CallFunction( + (PyObject *)&PyType_Type, "s(OO){}", + "SignalDict", &PyDecSignalDictMixin_Type, + MutableMapping)); + + /* Done with collections, MutableMapping */ + Py_CLEAR(collections); + Py_CLEAR(collections_abc); + Py_CLEAR(MutableMapping); + + + /* Create the module */ + ASSIGN_PTR(m, PyModule_Create(&_decimal_module)); + + + /* Add types to the module */ + Py_INCREF(&PyDec_Type); + CHECK_INT(PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type)); + Py_INCREF(&PyDecContext_Type); + CHECK_INT(PyModule_AddObject(m, "Context", + (PyObject *)&PyDecContext_Type)); + Py_INCREF(DecimalTuple); + CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple)); + + + /* Create top level exception */ + ASSIGN_PTR(DecimalException, PyErr_NewException( + "decimal.DecimalException", + PyExc_ArithmeticError, NULL)); + Py_INCREF(DecimalException); + CHECK_INT(PyModule_AddObject(m, "DecimalException", DecimalException)); + + /* Create signal tuple */ + ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN)); + + /* Add exceptions that correspond to IEEE signals */ + for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) { + PyObject *base; + + cm = signal_map + i; + + switch (cm->flag) { + case MPD_Float_operation: + base = PyTuple_Pack(2, DecimalException, PyExc_TypeError); + break; + case MPD_Division_by_zero: + base = PyTuple_Pack(2, DecimalException, PyExc_ZeroDivisionError); + break; + case MPD_Overflow: + base = PyTuple_Pack(2, signal_map[INEXACT].ex, + signal_map[ROUNDED].ex); + break; + case MPD_Underflow: + base = PyTuple_Pack(3, signal_map[INEXACT].ex, + signal_map[ROUNDED].ex, + signal_map[SUBNORMAL].ex); + break; + default: + base = PyTuple_Pack(1, DecimalException); + break; + } + + if (base == NULL) { + goto error; /* GCOV_NOT_REACHED */ + } + + ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); + Py_DECREF(base); + + /* add to module */ + Py_INCREF(cm->ex); + CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex)); + + /* add to signal tuple */ + Py_INCREF(cm->ex); + PyTuple_SET_ITEM(SignalTuple, i, cm->ex); + } + + /* + * Unfortunately, InvalidOperation is a signal that comprises + * several conditions, including InvalidOperation! Naming the + * signal IEEEInvalidOperation would prevent the confusion. + */ + cond_map[0].ex = signal_map[0].ex; + + /* Add remaining exceptions, inherit from InvalidOperation */ + for (cm = cond_map+1; cm->name != NULL; cm++) { + PyObject *base; + if (cm->flag == MPD_Division_undefined) { + base = PyTuple_Pack(2, signal_map[0].ex, PyExc_ZeroDivisionError); + } + else { + base = PyTuple_Pack(1, signal_map[0].ex); + } + if (base == NULL) { + goto error; /* GCOV_NOT_REACHED */ + } + + ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); + Py_DECREF(base); + + Py_INCREF(cm->ex); + CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex)); + } + + + /* Init default context template first */ + ASSIGN_PTR(default_context_template, + PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); + Py_INCREF(default_context_template); + CHECK_INT(PyModule_AddObject(m, "DefaultContext", + default_context_template)); + #ifndef WITH_DECIMAL_CONTEXTVAR ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__")); Py_INCREF(Py_False); CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_False)); #else ASSIGN_PTR(current_context_var, PyContextVar_New("decimal_context", NULL)); - Py_INCREF(Py_True); + Py_INCREF(Py_True); CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_True)); #endif Py_INCREF(Py_True); - CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True)); - - /* Init basic context template */ - ASSIGN_PTR(basic_context_template, - PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); - init_basic_context(basic_context_template); - Py_INCREF(basic_context_template); - CHECK_INT(PyModule_AddObject(m, "BasicContext", - basic_context_template)); - - /* Init extended context template */ - ASSIGN_PTR(extended_context_template, - PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); - init_extended_context(extended_context_template); - Py_INCREF(extended_context_template); - CHECK_INT(PyModule_AddObject(m, "ExtendedContext", - extended_context_template)); - - - /* Init mpd_ssize_t constants */ - for (ssize_cm = ssize_constants; ssize_cm->name != NULL; ssize_cm++) { - ASSIGN_PTR(obj, PyLong_FromSsize_t(ssize_cm->val)); - CHECK_INT(PyModule_AddObject(m, ssize_cm->name, obj)); - obj = NULL; - } - - /* Init int constants */ - for (int_cm = int_constants; int_cm->name != NULL; int_cm++) { - CHECK_INT(PyModule_AddIntConstant(m, int_cm->name, - int_cm->val)); - } - - /* Init string constants */ - for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { - ASSIGN_PTR(round_map[i], PyUnicode_InternFromString(mpd_round_string[i])); - Py_INCREF(round_map[i]); - CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], round_map[i])); - } - - /* Add specification version number */ - CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70")); - CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version())); - - - return m; - - -error: - Py_CLEAR(obj); /* GCOV_NOT_REACHED */ - Py_CLEAR(numbers); /* GCOV_NOT_REACHED */ - Py_CLEAR(Number); /* GCOV_NOT_REACHED */ - Py_CLEAR(Rational); /* GCOV_NOT_REACHED */ - Py_CLEAR(collections); /* GCOV_NOT_REACHED */ - Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */ - Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */ - Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */ - Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */ - Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */ + CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True)); + + /* Init basic context template */ + ASSIGN_PTR(basic_context_template, + PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); + init_basic_context(basic_context_template); + Py_INCREF(basic_context_template); + CHECK_INT(PyModule_AddObject(m, "BasicContext", + basic_context_template)); + + /* Init extended context template */ + ASSIGN_PTR(extended_context_template, + PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); + init_extended_context(extended_context_template); + Py_INCREF(extended_context_template); + CHECK_INT(PyModule_AddObject(m, "ExtendedContext", + extended_context_template)); + + + /* Init mpd_ssize_t constants */ + for (ssize_cm = ssize_constants; ssize_cm->name != NULL; ssize_cm++) { + ASSIGN_PTR(obj, PyLong_FromSsize_t(ssize_cm->val)); + CHECK_INT(PyModule_AddObject(m, ssize_cm->name, obj)); + obj = NULL; + } + + /* Init int constants */ + for (int_cm = int_constants; int_cm->name != NULL; int_cm++) { + CHECK_INT(PyModule_AddIntConstant(m, int_cm->name, + int_cm->val)); + } + + /* Init string constants */ + for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { + ASSIGN_PTR(round_map[i], PyUnicode_InternFromString(mpd_round_string[i])); + Py_INCREF(round_map[i]); + CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], round_map[i])); + } + + /* Add specification version number */ + CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70")); + CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version())); + + + return m; + + +error: + Py_CLEAR(obj); /* GCOV_NOT_REACHED */ + Py_CLEAR(numbers); /* GCOV_NOT_REACHED */ + Py_CLEAR(Number); /* GCOV_NOT_REACHED */ + Py_CLEAR(Rational); /* GCOV_NOT_REACHED */ + Py_CLEAR(collections); /* GCOV_NOT_REACHED */ + Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */ + Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */ + Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */ + Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */ + Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */ #ifndef WITH_DECIMAL_CONTEXTVAR Py_CLEAR(tls_context_key); /* GCOV_NOT_REACHED */ #else Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */ #endif - Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(m); /* GCOV_NOT_REACHED */ - - return NULL; /* GCOV_NOT_REACHED */ -} - - + Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */ + Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */ + Py_CLEAR(m); /* GCOV_NOT_REACHED */ + + return NULL; /* GCOV_NOT_REACHED */ +} + + diff --git a/contrib/tools/python3/src/Modules/_decimal/docstrings.h b/contrib/tools/python3/src/Modules/_decimal/docstrings.h index f7fd6e79529..1bb8e3f99e9 100644 --- a/contrib/tools/python3/src/Modules/_decimal/docstrings.h +++ b/contrib/tools/python3/src/Modules/_decimal/docstrings.h @@ -1,884 +1,884 @@ -/* - * Copyright (c) 2001-2012 Python Software Foundation. All Rights Reserved. - * Modified and extended by Stefan Krah. - */ - - -#ifndef DOCSTRINGS_H -#define DOCSTRINGS_H - - -#include "pymacro.h" - - -/******************************************************************************/ -/* Module */ -/******************************************************************************/ - - -PyDoc_STRVAR(doc__decimal, -"C decimal arithmetic module"); - -PyDoc_STRVAR(doc_getcontext, -"getcontext($module, /)\n--\n\n\ -Get the current default context.\n\ -\n"); - -PyDoc_STRVAR(doc_setcontext, -"setcontext($module, context, /)\n--\n\n\ -Set a new default context.\n\ -\n"); - -PyDoc_STRVAR(doc_localcontext, -"localcontext($module, /, ctx=None)\n--\n\n\ -Return a context manager that will set the default context to a copy of ctx\n\ -on entry to the with-statement and restore the previous default context when\n\ -exiting the with-statement. If no context is specified, a copy of the current\n\ -default context is used.\n\ -\n"); - -#ifdef EXTRA_FUNCTIONALITY -PyDoc_STRVAR(doc_ieee_context, -"IEEEContext($module, bits, /)\n--\n\n\ -Return a context object initialized to the proper values for one of the\n\ -IEEE interchange formats. The argument must be a multiple of 32 and less\n\ -than IEEE_CONTEXT_MAX_BITS. For the most common values, the constants\n\ -DECIMAL32, DECIMAL64 and DECIMAL128 are provided.\n\ -\n"); -#endif - - -/******************************************************************************/ -/* Decimal Object and Methods */ -/******************************************************************************/ - -PyDoc_STRVAR(doc_decimal, -"Decimal(value=\"0\", context=None)\n--\n\n\ -Construct a new Decimal object. 'value' can be an integer, string, tuple,\n\ -or another Decimal object. If no value is given, return Decimal('0'). The\n\ -context does not affect the conversion and is only passed to determine if\n\ -the InvalidOperation trap is active.\n\ -\n"); - -PyDoc_STRVAR(doc_adjusted, -"adjusted($self, /)\n--\n\n\ -Return the adjusted exponent of the number. Defined as exp + digits - 1.\n\ -\n"); - -PyDoc_STRVAR(doc_as_tuple, -"as_tuple($self, /)\n--\n\n\ -Return a tuple representation of the number.\n\ -\n"); - -PyDoc_STRVAR(doc_as_integer_ratio, -"as_integer_ratio($self, /)\n--\n\n\ -Decimal.as_integer_ratio() -> (int, int)\n\ -\n\ -Return a pair of integers, whose ratio is exactly equal to the original\n\ -Decimal and with a positive denominator. The ratio is in lowest terms.\n\ -Raise OverflowError on infinities and a ValueError on NaNs.\n\ -\n"); - -PyDoc_STRVAR(doc_canonical, -"canonical($self, /)\n--\n\n\ -Return the canonical encoding of the argument. Currently, the encoding\n\ -of a Decimal instance is always canonical, so this operation returns its\n\ -argument unchanged.\n\ -\n"); - -PyDoc_STRVAR(doc_compare, -"compare($self, /, other, context=None)\n--\n\n\ -Compare self to other. Return a decimal value:\n\ -\n\ - a or b is a NaN ==> Decimal('NaN')\n\ - a < b ==> Decimal('-1')\n\ - a == b ==> Decimal('0')\n\ - a > b ==> Decimal('1')\n\ -\n"); - -PyDoc_STRVAR(doc_compare_signal, -"compare_signal($self, /, other, context=None)\n--\n\n\ -Identical to compare, except that all NaNs signal.\n\ -\n"); - -PyDoc_STRVAR(doc_compare_total, -"compare_total($self, /, other, context=None)\n--\n\n\ -Compare two operands using their abstract representation rather than\n\ -their numerical value. Similar to the compare() method, but the result\n\ -gives a total ordering on Decimal instances. Two Decimal instances with\n\ -the same numeric value but different representations compare unequal\n\ -in this ordering:\n\ -\n\ - >>> Decimal('12.0').compare_total(Decimal('12'))\n\ - Decimal('-1')\n\ -\n\ -Quiet and signaling NaNs are also included in the total ordering. The result\n\ -of this function is Decimal('0') if both operands have the same representation,\n\ -Decimal('-1') if the first operand is lower in the total order than the second,\n\ -and Decimal('1') if the first operand is higher in the total order than the\n\ -second operand. See the specification for details of the total order.\n\ -\n\ -This operation is unaffected by context and is quiet: no flags are changed\n\ -and no rounding is performed. As an exception, the C version may raise\n\ -InvalidOperation if the second operand cannot be converted exactly.\n\ -\n"); - -PyDoc_STRVAR(doc_compare_total_mag, -"compare_total_mag($self, /, other, context=None)\n--\n\n\ -Compare two operands using their abstract representation rather than their\n\ -value as in compare_total(), but ignoring the sign of each operand.\n\ -\n\ -x.compare_total_mag(y) is equivalent to x.copy_abs().compare_total(y.copy_abs()).\n\ -\n\ -This operation is unaffected by context and is quiet: no flags are changed\n\ -and no rounding is performed. As an exception, the C version may raise\n\ -InvalidOperation if the second operand cannot be converted exactly.\n\ -\n"); - -PyDoc_STRVAR(doc_conjugate, -"conjugate($self, /)\n--\n\n\ -Return self.\n\ -\n"); - -PyDoc_STRVAR(doc_copy_abs, -"copy_abs($self, /)\n--\n\n\ -Return the absolute value of the argument. This operation is unaffected by\n\ -context and is quiet: no flags are changed and no rounding is performed.\n\ -\n"); - -PyDoc_STRVAR(doc_copy_negate, -"copy_negate($self, /)\n--\n\n\ -Return the negation of the argument. This operation is unaffected by context\n\ -and is quiet: no flags are changed and no rounding is performed.\n\ -\n"); - -PyDoc_STRVAR(doc_copy_sign, -"copy_sign($self, /, other, context=None)\n--\n\n\ -Return a copy of the first operand with the sign set to be the same as the\n\ -sign of the second operand. For example:\n\ -\n\ - >>> Decimal('2.3').copy_sign(Decimal('-1.5'))\n\ - Decimal('-2.3')\n\ -\n\ -This operation is unaffected by context and is quiet: no flags are changed\n\ -and no rounding is performed. As an exception, the C version may raise\n\ -InvalidOperation if the second operand cannot be converted exactly.\n\ -\n"); - -PyDoc_STRVAR(doc_exp, -"exp($self, /, context=None)\n--\n\n\ -Return the value of the (natural) exponential function e**x at the given\n\ -number. The function always uses the ROUND_HALF_EVEN mode and the result\n\ -is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_from_float, -"from_float($type, f, /)\n--\n\n\ -Class method that converts a float to a decimal number, exactly.\n\ -Since 0.1 is not exactly representable in binary floating point,\n\ -Decimal.from_float(0.1) is not the same as Decimal('0.1').\n\ -\n\ - >>> Decimal.from_float(0.1)\n\ - Decimal('0.1000000000000000055511151231257827021181583404541015625')\n\ - >>> Decimal.from_float(float('nan'))\n\ - Decimal('NaN')\n\ - >>> Decimal.from_float(float('inf'))\n\ - Decimal('Infinity')\n\ - >>> Decimal.from_float(float('-inf'))\n\ - Decimal('-Infinity')\n\ -\n\ -\n"); - -PyDoc_STRVAR(doc_fma, -"fma($self, /, other, third, context=None)\n--\n\n\ -Fused multiply-add. Return self*other+third with no rounding of the\n\ -intermediate product self*other.\n\ -\n\ - >>> Decimal(2).fma(3, 5)\n\ - Decimal('11')\n\ -\n\ -\n"); - -PyDoc_STRVAR(doc_is_canonical, -"is_canonical($self, /)\n--\n\n\ -Return True if the argument is canonical and False otherwise. Currently,\n\ -a Decimal instance is always canonical, so this operation always returns\n\ -True.\n\ -\n"); - -PyDoc_STRVAR(doc_is_finite, -"is_finite($self, /)\n--\n\n\ -Return True if the argument is a finite number, and False if the argument\n\ -is infinite or a NaN.\n\ -\n"); - -PyDoc_STRVAR(doc_is_infinite, -"is_infinite($self, /)\n--\n\n\ -Return True if the argument is either positive or negative infinity and\n\ -False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_is_nan, -"is_nan($self, /)\n--\n\n\ -Return True if the argument is a (quiet or signaling) NaN and False\n\ -otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_is_normal, -"is_normal($self, /, context=None)\n--\n\n\ -Return True if the argument is a normal finite non-zero number with an\n\ -adjusted exponent greater than or equal to Emin. Return False if the\n\ -argument is zero, subnormal, infinite or a NaN.\n\ -\n"); - -PyDoc_STRVAR(doc_is_qnan, -"is_qnan($self, /)\n--\n\n\ -Return True if the argument is a quiet NaN, and False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_is_signed, -"is_signed($self, /)\n--\n\n\ -Return True if the argument has a negative sign and False otherwise.\n\ -Note that both zeros and NaNs can carry signs.\n\ -\n"); - -PyDoc_STRVAR(doc_is_snan, -"is_snan($self, /)\n--\n\n\ -Return True if the argument is a signaling NaN and False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_is_subnormal, -"is_subnormal($self, /, context=None)\n--\n\n\ -Return True if the argument is subnormal, and False otherwise. A number is\n\ -subnormal if it is non-zero, finite, and has an adjusted exponent less\n\ -than Emin.\n\ -\n"); - -PyDoc_STRVAR(doc_is_zero, -"is_zero($self, /)\n--\n\n\ -Return True if the argument is a (positive or negative) zero and False\n\ -otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ln, -"ln($self, /, context=None)\n--\n\n\ -Return the natural (base e) logarithm of the operand. The function always\n\ -uses the ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_log10, -"log10($self, /, context=None)\n--\n\n\ -Return the base ten logarithm of the operand. The function always uses the\n\ -ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_logb, -"logb($self, /, context=None)\n--\n\n\ -For a non-zero number, return the adjusted exponent of the operand as a\n\ -Decimal instance. If the operand is a zero, then Decimal('-Infinity') is\n\ -returned and the DivisionByZero condition is raised. If the operand is\n\ -an infinity then Decimal('Infinity') is returned.\n\ -\n"); - -PyDoc_STRVAR(doc_logical_and, -"logical_and($self, /, other, context=None)\n--\n\n\ -Return the digit-wise 'and' of the two (logical) operands.\n\ -\n"); - -PyDoc_STRVAR(doc_logical_invert, -"logical_invert($self, /, context=None)\n--\n\n\ -Return the digit-wise inversion of the (logical) operand.\n\ -\n"); - -PyDoc_STRVAR(doc_logical_or, -"logical_or($self, /, other, context=None)\n--\n\n\ -Return the digit-wise 'or' of the two (logical) operands.\n\ -\n"); - -PyDoc_STRVAR(doc_logical_xor, -"logical_xor($self, /, other, context=None)\n--\n\n\ -Return the digit-wise 'exclusive or' of the two (logical) operands.\n\ -\n"); - -PyDoc_STRVAR(doc_max, -"max($self, /, other, context=None)\n--\n\n\ -Maximum of self and other. If one operand is a quiet NaN and the other is\n\ -numeric, the numeric operand is returned.\n\ -\n"); - -PyDoc_STRVAR(doc_max_mag, -"max_mag($self, /, other, context=None)\n--\n\n\ -Similar to the max() method, but the comparison is done using the absolute\n\ -values of the operands.\n\ -\n"); - -PyDoc_STRVAR(doc_min, -"min($self, /, other, context=None)\n--\n\n\ -Minimum of self and other. If one operand is a quiet NaN and the other is\n\ -numeric, the numeric operand is returned.\n\ -\n"); - -PyDoc_STRVAR(doc_min_mag, -"min_mag($self, /, other, context=None)\n--\n\n\ -Similar to the min() method, but the comparison is done using the absolute\n\ -values of the operands.\n\ -\n"); - -PyDoc_STRVAR(doc_next_minus, -"next_minus($self, /, context=None)\n--\n\n\ -Return the largest number representable in the given context (or in the\n\ -current default context if no context is given) that is smaller than the\n\ -given operand.\n\ -\n"); - -PyDoc_STRVAR(doc_next_plus, -"next_plus($self, /, context=None)\n--\n\n\ -Return the smallest number representable in the given context (or in the\n\ -current default context if no context is given) that is larger than the\n\ -given operand.\n\ -\n"); - -PyDoc_STRVAR(doc_next_toward, -"next_toward($self, /, other, context=None)\n--\n\n\ -If the two operands are unequal, return the number closest to the first\n\ -operand in the direction of the second operand. If both operands are\n\ -numerically equal, return a copy of the first operand with the sign set\n\ -to be the same as the sign of the second operand.\n\ -\n"); - -PyDoc_STRVAR(doc_normalize, -"normalize($self, /, context=None)\n--\n\n\ -Normalize the number by stripping the rightmost trailing zeros and\n\ -converting any result equal to Decimal('0') to Decimal('0e0'). Used\n\ -for producing canonical values for members of an equivalence class.\n\ -For example, Decimal('32.100') and Decimal('0.321000e+2') both normalize\n\ -to the equivalent value Decimal('32.1').\n\ -\n"); - -PyDoc_STRVAR(doc_number_class, -"number_class($self, /, context=None)\n--\n\n\ -Return a string describing the class of the operand. The returned value\n\ -is one of the following ten strings:\n\ -\n\ - * '-Infinity', indicating that the operand is negative infinity.\n\ - * '-Normal', indicating that the operand is a negative normal number.\n\ - * '-Subnormal', indicating that the operand is negative and subnormal.\n\ - * '-Zero', indicating that the operand is a negative zero.\n\ - * '+Zero', indicating that the operand is a positive zero.\n\ - * '+Subnormal', indicating that the operand is positive and subnormal.\n\ - * '+Normal', indicating that the operand is a positive normal number.\n\ - * '+Infinity', indicating that the operand is positive infinity.\n\ - * 'NaN', indicating that the operand is a quiet NaN (Not a Number).\n\ - * 'sNaN', indicating that the operand is a signaling NaN.\n\ -\n\ -\n"); - -PyDoc_STRVAR(doc_quantize, -"quantize($self, /, exp, rounding=None, context=None)\n--\n\n\ -Return a value equal to the first operand after rounding and having the\n\ -exponent of the second operand.\n\ -\n\ - >>> Decimal('1.41421356').quantize(Decimal('1.000'))\n\ - Decimal('1.414')\n\ -\n\ -Unlike other operations, if the length of the coefficient after the quantize\n\ -operation would be greater than precision, then an InvalidOperation is signaled.\n\ -This guarantees that, unless there is an error condition, the quantized exponent\n\ -is always equal to that of the right-hand operand.\n\ -\n\ -Also unlike other operations, quantize never signals Underflow, even if the\n\ -result is subnormal and inexact.\n\ -\n\ -If the exponent of the second operand is larger than that of the first, then\n\ -rounding may be necessary. In this case, the rounding mode is determined by the\n\ -rounding argument if given, else by the given context argument; if neither\n\ -argument is given, the rounding mode of the current thread's context is used.\n\ -\n"); - -PyDoc_STRVAR(doc_radix, -"radix($self, /)\n--\n\n\ -Return Decimal(10), the radix (base) in which the Decimal class does\n\ -all its arithmetic. Included for compatibility with the specification.\n\ -\n"); - -PyDoc_STRVAR(doc_remainder_near, -"remainder_near($self, /, other, context=None)\n--\n\n\ -Return the remainder from dividing self by other. This differs from\n\ -self % other in that the sign of the remainder is chosen so as to minimize\n\ -its absolute value. More precisely, the return value is self - n * other\n\ -where n is the integer nearest to the exact value of self / other, and\n\ -if two integers are equally near then the even one is chosen.\n\ -\n\ -If the result is zero then its sign will be the sign of self.\n\ -\n"); - -PyDoc_STRVAR(doc_rotate, -"rotate($self, /, other, context=None)\n--\n\n\ -Return the result of rotating the digits of the first operand by an amount\n\ -specified by the second operand. The second operand must be an integer in\n\ -the range -precision through precision. The absolute value of the second\n\ -operand gives the number of places to rotate. If the second operand is\n\ -positive then rotation is to the left; otherwise rotation is to the right.\n\ -The coefficient of the first operand is padded on the left with zeros to\n\ -length precision if necessary. The sign and exponent of the first operand are\n\ -unchanged.\n\ -\n"); - -PyDoc_STRVAR(doc_same_quantum, -"same_quantum($self, /, other, context=None)\n--\n\n\ -Test whether self and other have the same exponent or whether both are NaN.\n\ -\n\ -This operation is unaffected by context and is quiet: no flags are changed\n\ -and no rounding is performed. As an exception, the C version may raise\n\ -InvalidOperation if the second operand cannot be converted exactly.\n\ -\n"); - -PyDoc_STRVAR(doc_scaleb, -"scaleb($self, /, other, context=None)\n--\n\n\ -Return the first operand with the exponent adjusted the second. Equivalently,\n\ -return the first operand multiplied by 10**other. The second operand must be\n\ -an integer.\n\ -\n"); - -PyDoc_STRVAR(doc_shift, -"shift($self, /, other, context=None)\n--\n\n\ -Return the result of shifting the digits of the first operand by an amount\n\ -specified by the second operand. The second operand must be an integer in\n\ -the range -precision through precision. The absolute value of the second\n\ -operand gives the number of places to shift. If the second operand is\n\ -positive, then the shift is to the left; otherwise the shift is to the\n\ -right. Digits shifted into the coefficient are zeros. The sign and exponent\n\ -of the first operand are unchanged.\n\ -\n"); - -PyDoc_STRVAR(doc_sqrt, -"sqrt($self, /, context=None)\n--\n\n\ -Return the square root of the argument to full precision. The result is\n\ -correctly rounded using the ROUND_HALF_EVEN rounding mode.\n\ -\n"); - -PyDoc_STRVAR(doc_to_eng_string, -"to_eng_string($self, /, context=None)\n--\n\n\ -Convert to an engineering-type string. Engineering notation has an exponent\n\ -which is a multiple of 3, so there are up to 3 digits left of the decimal\n\ -place. For example, Decimal('123E+1') is converted to Decimal('1.23E+3').\n\ -\n\ -The value of context.capitals determines whether the exponent sign is lower\n\ -or upper case. Otherwise, the context does not affect the operation.\n\ -\n"); - -PyDoc_STRVAR(doc_to_integral, -"to_integral($self, /, rounding=None, context=None)\n--\n\n\ -Identical to the to_integral_value() method. The to_integral() name has been\n\ -kept for compatibility with older versions.\n\ -\n"); - -PyDoc_STRVAR(doc_to_integral_exact, -"to_integral_exact($self, /, rounding=None, context=None)\n--\n\n\ -Round to the nearest integer, signaling Inexact or Rounded as appropriate if\n\ -rounding occurs. The rounding mode is determined by the rounding parameter\n\ -if given, else by the given context. If neither parameter is given, then the\n\ -rounding mode of the current default context is used.\n\ -\n"); - -PyDoc_STRVAR(doc_to_integral_value, -"to_integral_value($self, /, rounding=None, context=None)\n--\n\n\ -Round to the nearest integer without signaling Inexact or Rounded. The\n\ -rounding mode is determined by the rounding parameter if given, else by\n\ -the given context. If neither parameter is given, then the rounding mode\n\ -of the current default context is used.\n\ -\n"); - - -/******************************************************************************/ -/* Context Object and Methods */ -/******************************************************************************/ - -PyDoc_STRVAR(doc_context, -"Context(prec=None, rounding=None, Emin=None, Emax=None, capitals=None, clamp=None, flags=None, traps=None)\n--\n\n\ -The context affects almost all operations and controls rounding,\n\ -Over/Underflow, raising of exceptions and much more. A new context\n\ -can be constructed as follows:\n\ -\n\ - >>> c = Context(prec=28, Emin=-425000000, Emax=425000000,\n\ - ... rounding=ROUND_HALF_EVEN, capitals=1, clamp=1,\n\ - ... traps=[InvalidOperation, DivisionByZero, Overflow],\n\ - ... flags=[])\n\ - >>>\n\ -\n\ -\n"); - -#ifdef EXTRA_FUNCTIONALITY -PyDoc_STRVAR(doc_ctx_apply, -"apply($self, x, /)\n--\n\n\ -Apply self to Decimal x.\n\ -\n"); -#endif - -PyDoc_STRVAR(doc_ctx_clear_flags, -"clear_flags($self, /)\n--\n\n\ -Reset all flags to False.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_clear_traps, -"clear_traps($self, /)\n--\n\n\ -Set all traps to False.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_copy, -"copy($self, /)\n--\n\n\ -Return a duplicate of the context with all flags cleared.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_copy_decimal, -"copy_decimal($self, x, /)\n--\n\n\ -Return a copy of Decimal x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_create_decimal, -"create_decimal($self, num=\"0\", /)\n--\n\n\ -Create a new Decimal instance from num, using self as the context. Unlike the\n\ -Decimal constructor, this function observes the context limits.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_create_decimal_from_float, -"create_decimal_from_float($self, f, /)\n--\n\n\ -Create a new Decimal instance from float f. Unlike the Decimal.from_float()\n\ -class method, this function observes the context limits.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_Etiny, -"Etiny($self, /)\n--\n\n\ -Return a value equal to Emin - prec + 1, which is the minimum exponent value\n\ -for subnormal results. When underflow occurs, the exponent is set to Etiny.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_Etop, -"Etop($self, /)\n--\n\n\ -Return a value equal to Emax - prec + 1. This is the maximum exponent\n\ -if the _clamp field of the context is set to 1 (IEEE clamp mode). Etop()\n\ -must not be negative.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_abs, -"abs($self, x, /)\n--\n\n\ -Return the absolute value of x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_add, -"add($self, x, y, /)\n--\n\n\ -Return the sum of x and y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_canonical, -"canonical($self, x, /)\n--\n\n\ -Return a new instance of x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_compare, -"compare($self, x, y, /)\n--\n\n\ -Compare x and y numerically.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_compare_signal, -"compare_signal($self, x, y, /)\n--\n\n\ -Compare x and y numerically. All NaNs signal.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_compare_total, -"compare_total($self, x, y, /)\n--\n\n\ -Compare x and y using their abstract representation.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_compare_total_mag, -"compare_total_mag($self, x, y, /)\n--\n\n\ -Compare x and y using their abstract representation, ignoring sign.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_copy_abs, -"copy_abs($self, x, /)\n--\n\n\ -Return a copy of x with the sign set to 0.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_copy_negate, -"copy_negate($self, x, /)\n--\n\n\ -Return a copy of x with the sign inverted.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_copy_sign, -"copy_sign($self, x, y, /)\n--\n\n\ -Copy the sign from y to x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_divide, -"divide($self, x, y, /)\n--\n\n\ -Return x divided by y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_divide_int, -"divide_int($self, x, y, /)\n--\n\n\ -Return x divided by y, truncated to an integer.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_divmod, -"divmod($self, x, y, /)\n--\n\n\ -Return quotient and remainder of the division x / y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_exp, -"exp($self, x, /)\n--\n\n\ -Return e ** x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_fma, -"fma($self, x, y, z, /)\n--\n\n\ -Return x multiplied by y, plus z.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_canonical, -"is_canonical($self, x, /)\n--\n\n\ -Return True if x is canonical, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_finite, -"is_finite($self, x, /)\n--\n\n\ -Return True if x is finite, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_infinite, -"is_infinite($self, x, /)\n--\n\n\ -Return True if x is infinite, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_nan, -"is_nan($self, x, /)\n--\n\n\ -Return True if x is a qNaN or sNaN, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_normal, -"is_normal($self, x, /)\n--\n\n\ -Return True if x is a normal number, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_qnan, -"is_qnan($self, x, /)\n--\n\n\ -Return True if x is a quiet NaN, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_signed, -"is_signed($self, x, /)\n--\n\n\ -Return True if x is negative, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_snan, -"is_snan($self, x, /)\n--\n\n\ -Return True if x is a signaling NaN, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_subnormal, -"is_subnormal($self, x, /)\n--\n\n\ -Return True if x is subnormal, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_is_zero, -"is_zero($self, x, /)\n--\n\n\ -Return True if x is a zero, False otherwise.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_ln, -"ln($self, x, /)\n--\n\n\ -Return the natural (base e) logarithm of x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_log10, -"log10($self, x, /)\n--\n\n\ -Return the base 10 logarithm of x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_logb, -"logb($self, x, /)\n--\n\n\ -Return the exponent of the magnitude of the operand's MSD.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_logical_and, -"logical_and($self, x, y, /)\n--\n\n\ -Digit-wise and of x and y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_logical_invert, -"logical_invert($self, x, /)\n--\n\n\ -Invert all digits of x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_logical_or, -"logical_or($self, x, y, /)\n--\n\n\ -Digit-wise or of x and y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_logical_xor, -"logical_xor($self, x, y, /)\n--\n\n\ -Digit-wise xor of x and y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_max, -"max($self, x, y, /)\n--\n\n\ -Compare the values numerically and return the maximum.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_max_mag, -"max_mag($self, x, y, /)\n--\n\n\ -Compare the values numerically with their sign ignored.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_min, -"min($self, x, y, /)\n--\n\n\ -Compare the values numerically and return the minimum.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_min_mag, -"min_mag($self, x, y, /)\n--\n\n\ -Compare the values numerically with their sign ignored.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_minus, -"minus($self, x, /)\n--\n\n\ -Minus corresponds to the unary prefix minus operator in Python, but applies\n\ -the context to the result.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_multiply, -"multiply($self, x, y, /)\n--\n\n\ -Return the product of x and y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_next_minus, -"next_minus($self, x, /)\n--\n\n\ -Return the largest representable number smaller than x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_next_plus, -"next_plus($self, x, /)\n--\n\n\ -Return the smallest representable number larger than x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_next_toward, -"next_toward($self, x, y, /)\n--\n\n\ -Return the number closest to x, in the direction towards y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_normalize, -"normalize($self, x, /)\n--\n\n\ -Reduce x to its simplest form. Alias for reduce(x).\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_number_class, -"number_class($self, x, /)\n--\n\n\ -Return an indication of the class of x.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_plus, -"plus($self, x, /)\n--\n\n\ -Plus corresponds to the unary prefix plus operator in Python, but applies\n\ -the context to the result.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_power, -"power($self, /, a, b, modulo=None)\n--\n\n\ -Compute a**b. If 'a' is negative, then 'b' must be integral. The result\n\ -will be inexact unless 'a' is integral and the result is finite and can\n\ -be expressed exactly in 'precision' digits. In the Python version the\n\ -result is always correctly rounded, in the C version the result is almost\n\ -always correctly rounded.\n\ -\n\ -If modulo is given, compute (a**b) % modulo. The following restrictions\n\ -hold:\n\ -\n\ - * all three arguments must be integral\n\ - * 'b' must be nonnegative\n\ - * at least one of 'a' or 'b' must be nonzero\n\ - * modulo must be nonzero and less than 10**prec in absolute value\n\ -\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_quantize, -"quantize($self, x, y, /)\n--\n\n\ -Return a value equal to x (rounded), having the exponent of y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_radix, -"radix($self, /)\n--\n\n\ -Return 10.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_remainder, -"remainder($self, x, y, /)\n--\n\n\ -Return the remainder from integer division. The sign of the result,\n\ -if non-zero, is the same as that of the original dividend.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_remainder_near, -"remainder_near($self, x, y, /)\n--\n\n\ -Return x - y * n, where n is the integer nearest the exact value of x / y\n\ -(if the result is 0 then its sign will be the sign of x).\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_rotate, -"rotate($self, x, y, /)\n--\n\n\ -Return a copy of x, rotated by y places.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_same_quantum, -"same_quantum($self, x, y, /)\n--\n\n\ -Return True if the two operands have the same exponent.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_scaleb, -"scaleb($self, x, y, /)\n--\n\n\ -Return the first operand after adding the second value to its exp.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_shift, -"shift($self, x, y, /)\n--\n\n\ -Return a copy of x, shifted by y places.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_sqrt, -"sqrt($self, x, /)\n--\n\n\ -Square root of a non-negative number to context precision.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_subtract, -"subtract($self, x, y, /)\n--\n\n\ -Return the difference between x and y.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_to_eng_string, -"to_eng_string($self, x, /)\n--\n\n\ -Convert a number to a string, using engineering notation.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_to_integral, -"to_integral($self, x, /)\n--\n\n\ -Identical to to_integral_value(x).\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_to_integral_exact, -"to_integral_exact($self, x, /)\n--\n\n\ -Round to an integer. Signal if the result is rounded or inexact.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_to_integral_value, -"to_integral_value($self, x, /)\n--\n\n\ -Round to an integer.\n\ -\n"); - -PyDoc_STRVAR(doc_ctx_to_sci_string, -"to_sci_string($self, x, /)\n--\n\n\ -Convert a number to a string using scientific notation.\n\ -\n"); - - -#endif /* DOCSTRINGS_H */ - - - +/* + * Copyright (c) 2001-2012 Python Software Foundation. All Rights Reserved. + * Modified and extended by Stefan Krah. + */ + + +#ifndef DOCSTRINGS_H +#define DOCSTRINGS_H + + +#include "pymacro.h" + + +/******************************************************************************/ +/* Module */ +/******************************************************************************/ + + +PyDoc_STRVAR(doc__decimal, +"C decimal arithmetic module"); + +PyDoc_STRVAR(doc_getcontext, +"getcontext($module, /)\n--\n\n\ +Get the current default context.\n\ +\n"); + +PyDoc_STRVAR(doc_setcontext, +"setcontext($module, context, /)\n--\n\n\ +Set a new default context.\n\ +\n"); + +PyDoc_STRVAR(doc_localcontext, +"localcontext($module, /, ctx=None)\n--\n\n\ +Return a context manager that will set the default context to a copy of ctx\n\ +on entry to the with-statement and restore the previous default context when\n\ +exiting the with-statement. If no context is specified, a copy of the current\n\ +default context is used.\n\ +\n"); + +#ifdef EXTRA_FUNCTIONALITY +PyDoc_STRVAR(doc_ieee_context, +"IEEEContext($module, bits, /)\n--\n\n\ +Return a context object initialized to the proper values for one of the\n\ +IEEE interchange formats. The argument must be a multiple of 32 and less\n\ +than IEEE_CONTEXT_MAX_BITS. For the most common values, the constants\n\ +DECIMAL32, DECIMAL64 and DECIMAL128 are provided.\n\ +\n"); +#endif + + +/******************************************************************************/ +/* Decimal Object and Methods */ +/******************************************************************************/ + +PyDoc_STRVAR(doc_decimal, +"Decimal(value=\"0\", context=None)\n--\n\n\ +Construct a new Decimal object. 'value' can be an integer, string, tuple,\n\ +or another Decimal object. If no value is given, return Decimal('0'). The\n\ +context does not affect the conversion and is only passed to determine if\n\ +the InvalidOperation trap is active.\n\ +\n"); + +PyDoc_STRVAR(doc_adjusted, +"adjusted($self, /)\n--\n\n\ +Return the adjusted exponent of the number. Defined as exp + digits - 1.\n\ +\n"); + +PyDoc_STRVAR(doc_as_tuple, +"as_tuple($self, /)\n--\n\n\ +Return a tuple representation of the number.\n\ +\n"); + +PyDoc_STRVAR(doc_as_integer_ratio, +"as_integer_ratio($self, /)\n--\n\n\ +Decimal.as_integer_ratio() -> (int, int)\n\ +\n\ +Return a pair of integers, whose ratio is exactly equal to the original\n\ +Decimal and with a positive denominator. The ratio is in lowest terms.\n\ +Raise OverflowError on infinities and a ValueError on NaNs.\n\ +\n"); + +PyDoc_STRVAR(doc_canonical, +"canonical($self, /)\n--\n\n\ +Return the canonical encoding of the argument. Currently, the encoding\n\ +of a Decimal instance is always canonical, so this operation returns its\n\ +argument unchanged.\n\ +\n"); + +PyDoc_STRVAR(doc_compare, +"compare($self, /, other, context=None)\n--\n\n\ +Compare self to other. Return a decimal value:\n\ +\n\ + a or b is a NaN ==> Decimal('NaN')\n\ + a < b ==> Decimal('-1')\n\ + a == b ==> Decimal('0')\n\ + a > b ==> Decimal('1')\n\ +\n"); + +PyDoc_STRVAR(doc_compare_signal, +"compare_signal($self, /, other, context=None)\n--\n\n\ +Identical to compare, except that all NaNs signal.\n\ +\n"); + +PyDoc_STRVAR(doc_compare_total, +"compare_total($self, /, other, context=None)\n--\n\n\ +Compare two operands using their abstract representation rather than\n\ +their numerical value. Similar to the compare() method, but the result\n\ +gives a total ordering on Decimal instances. Two Decimal instances with\n\ +the same numeric value but different representations compare unequal\n\ +in this ordering:\n\ +\n\ + >>> Decimal('12.0').compare_total(Decimal('12'))\n\ + Decimal('-1')\n\ +\n\ +Quiet and signaling NaNs are also included in the total ordering. The result\n\ +of this function is Decimal('0') if both operands have the same representation,\n\ +Decimal('-1') if the first operand is lower in the total order than the second,\n\ +and Decimal('1') if the first operand is higher in the total order than the\n\ +second operand. See the specification for details of the total order.\n\ +\n\ +This operation is unaffected by context and is quiet: no flags are changed\n\ +and no rounding is performed. As an exception, the C version may raise\n\ +InvalidOperation if the second operand cannot be converted exactly.\n\ +\n"); + +PyDoc_STRVAR(doc_compare_total_mag, +"compare_total_mag($self, /, other, context=None)\n--\n\n\ +Compare two operands using their abstract representation rather than their\n\ +value as in compare_total(), but ignoring the sign of each operand.\n\ +\n\ +x.compare_total_mag(y) is equivalent to x.copy_abs().compare_total(y.copy_abs()).\n\ +\n\ +This operation is unaffected by context and is quiet: no flags are changed\n\ +and no rounding is performed. As an exception, the C version may raise\n\ +InvalidOperation if the second operand cannot be converted exactly.\n\ +\n"); + +PyDoc_STRVAR(doc_conjugate, +"conjugate($self, /)\n--\n\n\ +Return self.\n\ +\n"); + +PyDoc_STRVAR(doc_copy_abs, +"copy_abs($self, /)\n--\n\n\ +Return the absolute value of the argument. This operation is unaffected by\n\ +context and is quiet: no flags are changed and no rounding is performed.\n\ +\n"); + +PyDoc_STRVAR(doc_copy_negate, +"copy_negate($self, /)\n--\n\n\ +Return the negation of the argument. This operation is unaffected by context\n\ +and is quiet: no flags are changed and no rounding is performed.\n\ +\n"); + +PyDoc_STRVAR(doc_copy_sign, +"copy_sign($self, /, other, context=None)\n--\n\n\ +Return a copy of the first operand with the sign set to be the same as the\n\ +sign of the second operand. For example:\n\ +\n\ + >>> Decimal('2.3').copy_sign(Decimal('-1.5'))\n\ + Decimal('-2.3')\n\ +\n\ +This operation is unaffected by context and is quiet: no flags are changed\n\ +and no rounding is performed. As an exception, the C version may raise\n\ +InvalidOperation if the second operand cannot be converted exactly.\n\ +\n"); + +PyDoc_STRVAR(doc_exp, +"exp($self, /, context=None)\n--\n\n\ +Return the value of the (natural) exponential function e**x at the given\n\ +number. The function always uses the ROUND_HALF_EVEN mode and the result\n\ +is correctly rounded.\n\ +\n"); + +PyDoc_STRVAR(doc_from_float, +"from_float($type, f, /)\n--\n\n\ +Class method that converts a float to a decimal number, exactly.\n\ +Since 0.1 is not exactly representable in binary floating point,\n\ +Decimal.from_float(0.1) is not the same as Decimal('0.1').\n\ +\n\ + >>> Decimal.from_float(0.1)\n\ + Decimal('0.1000000000000000055511151231257827021181583404541015625')\n\ + >>> Decimal.from_float(float('nan'))\n\ + Decimal('NaN')\n\ + >>> Decimal.from_float(float('inf'))\n\ + Decimal('Infinity')\n\ + >>> Decimal.from_float(float('-inf'))\n\ + Decimal('-Infinity')\n\ +\n\ +\n"); + +PyDoc_STRVAR(doc_fma, +"fma($self, /, other, third, context=None)\n--\n\n\ +Fused multiply-add. Return self*other+third with no rounding of the\n\ +intermediate product self*other.\n\ +\n\ + >>> Decimal(2).fma(3, 5)\n\ + Decimal('11')\n\ +\n\ +\n"); + +PyDoc_STRVAR(doc_is_canonical, +"is_canonical($self, /)\n--\n\n\ +Return True if the argument is canonical and False otherwise. Currently,\n\ +a Decimal instance is always canonical, so this operation always returns\n\ +True.\n\ +\n"); + +PyDoc_STRVAR(doc_is_finite, +"is_finite($self, /)\n--\n\n\ +Return True if the argument is a finite number, and False if the argument\n\ +is infinite or a NaN.\n\ +\n"); + +PyDoc_STRVAR(doc_is_infinite, +"is_infinite($self, /)\n--\n\n\ +Return True if the argument is either positive or negative infinity and\n\ +False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_is_nan, +"is_nan($self, /)\n--\n\n\ +Return True if the argument is a (quiet or signaling) NaN and False\n\ +otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_is_normal, +"is_normal($self, /, context=None)\n--\n\n\ +Return True if the argument is a normal finite non-zero number with an\n\ +adjusted exponent greater than or equal to Emin. Return False if the\n\ +argument is zero, subnormal, infinite or a NaN.\n\ +\n"); + +PyDoc_STRVAR(doc_is_qnan, +"is_qnan($self, /)\n--\n\n\ +Return True if the argument is a quiet NaN, and False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_is_signed, +"is_signed($self, /)\n--\n\n\ +Return True if the argument has a negative sign and False otherwise.\n\ +Note that both zeros and NaNs can carry signs.\n\ +\n"); + +PyDoc_STRVAR(doc_is_snan, +"is_snan($self, /)\n--\n\n\ +Return True if the argument is a signaling NaN and False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_is_subnormal, +"is_subnormal($self, /, context=None)\n--\n\n\ +Return True if the argument is subnormal, and False otherwise. A number is\n\ +subnormal if it is non-zero, finite, and has an adjusted exponent less\n\ +than Emin.\n\ +\n"); + +PyDoc_STRVAR(doc_is_zero, +"is_zero($self, /)\n--\n\n\ +Return True if the argument is a (positive or negative) zero and False\n\ +otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ln, +"ln($self, /, context=None)\n--\n\n\ +Return the natural (base e) logarithm of the operand. The function always\n\ +uses the ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ +\n"); + +PyDoc_STRVAR(doc_log10, +"log10($self, /, context=None)\n--\n\n\ +Return the base ten logarithm of the operand. The function always uses the\n\ +ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ +\n"); + +PyDoc_STRVAR(doc_logb, +"logb($self, /, context=None)\n--\n\n\ +For a non-zero number, return the adjusted exponent of the operand as a\n\ +Decimal instance. If the operand is a zero, then Decimal('-Infinity') is\n\ +returned and the DivisionByZero condition is raised. If the operand is\n\ +an infinity then Decimal('Infinity') is returned.\n\ +\n"); + +PyDoc_STRVAR(doc_logical_and, +"logical_and($self, /, other, context=None)\n--\n\n\ +Return the digit-wise 'and' of the two (logical) operands.\n\ +\n"); + +PyDoc_STRVAR(doc_logical_invert, +"logical_invert($self, /, context=None)\n--\n\n\ +Return the digit-wise inversion of the (logical) operand.\n\ +\n"); + +PyDoc_STRVAR(doc_logical_or, +"logical_or($self, /, other, context=None)\n--\n\n\ +Return the digit-wise 'or' of the two (logical) operands.\n\ +\n"); + +PyDoc_STRVAR(doc_logical_xor, +"logical_xor($self, /, other, context=None)\n--\n\n\ +Return the digit-wise 'exclusive or' of the two (logical) operands.\n\ +\n"); + +PyDoc_STRVAR(doc_max, +"max($self, /, other, context=None)\n--\n\n\ +Maximum of self and other. If one operand is a quiet NaN and the other is\n\ +numeric, the numeric operand is returned.\n\ +\n"); + +PyDoc_STRVAR(doc_max_mag, +"max_mag($self, /, other, context=None)\n--\n\n\ +Similar to the max() method, but the comparison is done using the absolute\n\ +values of the operands.\n\ +\n"); + +PyDoc_STRVAR(doc_min, +"min($self, /, other, context=None)\n--\n\n\ +Minimum of self and other. If one operand is a quiet NaN and the other is\n\ +numeric, the numeric operand is returned.\n\ +\n"); + +PyDoc_STRVAR(doc_min_mag, +"min_mag($self, /, other, context=None)\n--\n\n\ +Similar to the min() method, but the comparison is done using the absolute\n\ +values of the operands.\n\ +\n"); + +PyDoc_STRVAR(doc_next_minus, +"next_minus($self, /, context=None)\n--\n\n\ +Return the largest number representable in the given context (or in the\n\ +current default context if no context is given) that is smaller than the\n\ +given operand.\n\ +\n"); + +PyDoc_STRVAR(doc_next_plus, +"next_plus($self, /, context=None)\n--\n\n\ +Return the smallest number representable in the given context (or in the\n\ +current default context if no context is given) that is larger than the\n\ +given operand.\n\ +\n"); + +PyDoc_STRVAR(doc_next_toward, +"next_toward($self, /, other, context=None)\n--\n\n\ +If the two operands are unequal, return the number closest to the first\n\ +operand in the direction of the second operand. If both operands are\n\ +numerically equal, return a copy of the first operand with the sign set\n\ +to be the same as the sign of the second operand.\n\ +\n"); + +PyDoc_STRVAR(doc_normalize, +"normalize($self, /, context=None)\n--\n\n\ +Normalize the number by stripping the rightmost trailing zeros and\n\ +converting any result equal to Decimal('0') to Decimal('0e0'). Used\n\ +for producing canonical values for members of an equivalence class.\n\ +For example, Decimal('32.100') and Decimal('0.321000e+2') both normalize\n\ +to the equivalent value Decimal('32.1').\n\ +\n"); + +PyDoc_STRVAR(doc_number_class, +"number_class($self, /, context=None)\n--\n\n\ +Return a string describing the class of the operand. The returned value\n\ +is one of the following ten strings:\n\ +\n\ + * '-Infinity', indicating that the operand is negative infinity.\n\ + * '-Normal', indicating that the operand is a negative normal number.\n\ + * '-Subnormal', indicating that the operand is negative and subnormal.\n\ + * '-Zero', indicating that the operand is a negative zero.\n\ + * '+Zero', indicating that the operand is a positive zero.\n\ + * '+Subnormal', indicating that the operand is positive and subnormal.\n\ + * '+Normal', indicating that the operand is a positive normal number.\n\ + * '+Infinity', indicating that the operand is positive infinity.\n\ + * 'NaN', indicating that the operand is a quiet NaN (Not a Number).\n\ + * 'sNaN', indicating that the operand is a signaling NaN.\n\ +\n\ +\n"); + +PyDoc_STRVAR(doc_quantize, +"quantize($self, /, exp, rounding=None, context=None)\n--\n\n\ +Return a value equal to the first operand after rounding and having the\n\ +exponent of the second operand.\n\ +\n\ + >>> Decimal('1.41421356').quantize(Decimal('1.000'))\n\ + Decimal('1.414')\n\ +\n\ +Unlike other operations, if the length of the coefficient after the quantize\n\ +operation would be greater than precision, then an InvalidOperation is signaled.\n\ +This guarantees that, unless there is an error condition, the quantized exponent\n\ +is always equal to that of the right-hand operand.\n\ +\n\ +Also unlike other operations, quantize never signals Underflow, even if the\n\ +result is subnormal and inexact.\n\ +\n\ +If the exponent of the second operand is larger than that of the first, then\n\ +rounding may be necessary. In this case, the rounding mode is determined by the\n\ +rounding argument if given, else by the given context argument; if neither\n\ +argument is given, the rounding mode of the current thread's context is used.\n\ +\n"); + +PyDoc_STRVAR(doc_radix, +"radix($self, /)\n--\n\n\ +Return Decimal(10), the radix (base) in which the Decimal class does\n\ +all its arithmetic. Included for compatibility with the specification.\n\ +\n"); + +PyDoc_STRVAR(doc_remainder_near, +"remainder_near($self, /, other, context=None)\n--\n\n\ +Return the remainder from dividing self by other. This differs from\n\ +self % other in that the sign of the remainder is chosen so as to minimize\n\ +its absolute value. More precisely, the return value is self - n * other\n\ +where n is the integer nearest to the exact value of self / other, and\n\ +if two integers are equally near then the even one is chosen.\n\ +\n\ +If the result is zero then its sign will be the sign of self.\n\ +\n"); + +PyDoc_STRVAR(doc_rotate, +"rotate($self, /, other, context=None)\n--\n\n\ +Return the result of rotating the digits of the first operand by an amount\n\ +specified by the second operand. The second operand must be an integer in\n\ +the range -precision through precision. The absolute value of the second\n\ +operand gives the number of places to rotate. If the second operand is\n\ +positive then rotation is to the left; otherwise rotation is to the right.\n\ +The coefficient of the first operand is padded on the left with zeros to\n\ +length precision if necessary. The sign and exponent of the first operand are\n\ +unchanged.\n\ +\n"); + +PyDoc_STRVAR(doc_same_quantum, +"same_quantum($self, /, other, context=None)\n--\n\n\ +Test whether self and other have the same exponent or whether both are NaN.\n\ +\n\ +This operation is unaffected by context and is quiet: no flags are changed\n\ +and no rounding is performed. As an exception, the C version may raise\n\ +InvalidOperation if the second operand cannot be converted exactly.\n\ +\n"); + +PyDoc_STRVAR(doc_scaleb, +"scaleb($self, /, other, context=None)\n--\n\n\ +Return the first operand with the exponent adjusted the second. Equivalently,\n\ +return the first operand multiplied by 10**other. The second operand must be\n\ +an integer.\n\ +\n"); + +PyDoc_STRVAR(doc_shift, +"shift($self, /, other, context=None)\n--\n\n\ +Return the result of shifting the digits of the first operand by an amount\n\ +specified by the second operand. The second operand must be an integer in\n\ +the range -precision through precision. The absolute value of the second\n\ +operand gives the number of places to shift. If the second operand is\n\ +positive, then the shift is to the left; otherwise the shift is to the\n\ +right. Digits shifted into the coefficient are zeros. The sign and exponent\n\ +of the first operand are unchanged.\n\ +\n"); + +PyDoc_STRVAR(doc_sqrt, +"sqrt($self, /, context=None)\n--\n\n\ +Return the square root of the argument to full precision. The result is\n\ +correctly rounded using the ROUND_HALF_EVEN rounding mode.\n\ +\n"); + +PyDoc_STRVAR(doc_to_eng_string, +"to_eng_string($self, /, context=None)\n--\n\n\ +Convert to an engineering-type string. Engineering notation has an exponent\n\ +which is a multiple of 3, so there are up to 3 digits left of the decimal\n\ +place. For example, Decimal('123E+1') is converted to Decimal('1.23E+3').\n\ +\n\ +The value of context.capitals determines whether the exponent sign is lower\n\ +or upper case. Otherwise, the context does not affect the operation.\n\ +\n"); + +PyDoc_STRVAR(doc_to_integral, +"to_integral($self, /, rounding=None, context=None)\n--\n\n\ +Identical to the to_integral_value() method. The to_integral() name has been\n\ +kept for compatibility with older versions.\n\ +\n"); + +PyDoc_STRVAR(doc_to_integral_exact, +"to_integral_exact($self, /, rounding=None, context=None)\n--\n\n\ +Round to the nearest integer, signaling Inexact or Rounded as appropriate if\n\ +rounding occurs. The rounding mode is determined by the rounding parameter\n\ +if given, else by the given context. If neither parameter is given, then the\n\ +rounding mode of the current default context is used.\n\ +\n"); + +PyDoc_STRVAR(doc_to_integral_value, +"to_integral_value($self, /, rounding=None, context=None)\n--\n\n\ +Round to the nearest integer without signaling Inexact or Rounded. The\n\ +rounding mode is determined by the rounding parameter if given, else by\n\ +the given context. If neither parameter is given, then the rounding mode\n\ +of the current default context is used.\n\ +\n"); + + +/******************************************************************************/ +/* Context Object and Methods */ +/******************************************************************************/ + +PyDoc_STRVAR(doc_context, +"Context(prec=None, rounding=None, Emin=None, Emax=None, capitals=None, clamp=None, flags=None, traps=None)\n--\n\n\ +The context affects almost all operations and controls rounding,\n\ +Over/Underflow, raising of exceptions and much more. A new context\n\ +can be constructed as follows:\n\ +\n\ + >>> c = Context(prec=28, Emin=-425000000, Emax=425000000,\n\ + ... rounding=ROUND_HALF_EVEN, capitals=1, clamp=1,\n\ + ... traps=[InvalidOperation, DivisionByZero, Overflow],\n\ + ... flags=[])\n\ + >>>\n\ +\n\ +\n"); + +#ifdef EXTRA_FUNCTIONALITY +PyDoc_STRVAR(doc_ctx_apply, +"apply($self, x, /)\n--\n\n\ +Apply self to Decimal x.\n\ +\n"); +#endif + +PyDoc_STRVAR(doc_ctx_clear_flags, +"clear_flags($self, /)\n--\n\n\ +Reset all flags to False.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_clear_traps, +"clear_traps($self, /)\n--\n\n\ +Set all traps to False.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_copy, +"copy($self, /)\n--\n\n\ +Return a duplicate of the context with all flags cleared.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_copy_decimal, +"copy_decimal($self, x, /)\n--\n\n\ +Return a copy of Decimal x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_create_decimal, +"create_decimal($self, num=\"0\", /)\n--\n\n\ +Create a new Decimal instance from num, using self as the context. Unlike the\n\ +Decimal constructor, this function observes the context limits.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_create_decimal_from_float, +"create_decimal_from_float($self, f, /)\n--\n\n\ +Create a new Decimal instance from float f. Unlike the Decimal.from_float()\n\ +class method, this function observes the context limits.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_Etiny, +"Etiny($self, /)\n--\n\n\ +Return a value equal to Emin - prec + 1, which is the minimum exponent value\n\ +for subnormal results. When underflow occurs, the exponent is set to Etiny.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_Etop, +"Etop($self, /)\n--\n\n\ +Return a value equal to Emax - prec + 1. This is the maximum exponent\n\ +if the _clamp field of the context is set to 1 (IEEE clamp mode). Etop()\n\ +must not be negative.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_abs, +"abs($self, x, /)\n--\n\n\ +Return the absolute value of x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_add, +"add($self, x, y, /)\n--\n\n\ +Return the sum of x and y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_canonical, +"canonical($self, x, /)\n--\n\n\ +Return a new instance of x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_compare, +"compare($self, x, y, /)\n--\n\n\ +Compare x and y numerically.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_compare_signal, +"compare_signal($self, x, y, /)\n--\n\n\ +Compare x and y numerically. All NaNs signal.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_compare_total, +"compare_total($self, x, y, /)\n--\n\n\ +Compare x and y using their abstract representation.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_compare_total_mag, +"compare_total_mag($self, x, y, /)\n--\n\n\ +Compare x and y using their abstract representation, ignoring sign.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_copy_abs, +"copy_abs($self, x, /)\n--\n\n\ +Return a copy of x with the sign set to 0.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_copy_negate, +"copy_negate($self, x, /)\n--\n\n\ +Return a copy of x with the sign inverted.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_copy_sign, +"copy_sign($self, x, y, /)\n--\n\n\ +Copy the sign from y to x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_divide, +"divide($self, x, y, /)\n--\n\n\ +Return x divided by y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_divide_int, +"divide_int($self, x, y, /)\n--\n\n\ +Return x divided by y, truncated to an integer.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_divmod, +"divmod($self, x, y, /)\n--\n\n\ +Return quotient and remainder of the division x / y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_exp, +"exp($self, x, /)\n--\n\n\ +Return e ** x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_fma, +"fma($self, x, y, z, /)\n--\n\n\ +Return x multiplied by y, plus z.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_canonical, +"is_canonical($self, x, /)\n--\n\n\ +Return True if x is canonical, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_finite, +"is_finite($self, x, /)\n--\n\n\ +Return True if x is finite, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_infinite, +"is_infinite($self, x, /)\n--\n\n\ +Return True if x is infinite, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_nan, +"is_nan($self, x, /)\n--\n\n\ +Return True if x is a qNaN or sNaN, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_normal, +"is_normal($self, x, /)\n--\n\n\ +Return True if x is a normal number, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_qnan, +"is_qnan($self, x, /)\n--\n\n\ +Return True if x is a quiet NaN, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_signed, +"is_signed($self, x, /)\n--\n\n\ +Return True if x is negative, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_snan, +"is_snan($self, x, /)\n--\n\n\ +Return True if x is a signaling NaN, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_subnormal, +"is_subnormal($self, x, /)\n--\n\n\ +Return True if x is subnormal, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_is_zero, +"is_zero($self, x, /)\n--\n\n\ +Return True if x is a zero, False otherwise.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_ln, +"ln($self, x, /)\n--\n\n\ +Return the natural (base e) logarithm of x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_log10, +"log10($self, x, /)\n--\n\n\ +Return the base 10 logarithm of x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_logb, +"logb($self, x, /)\n--\n\n\ +Return the exponent of the magnitude of the operand's MSD.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_logical_and, +"logical_and($self, x, y, /)\n--\n\n\ +Digit-wise and of x and y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_logical_invert, +"logical_invert($self, x, /)\n--\n\n\ +Invert all digits of x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_logical_or, +"logical_or($self, x, y, /)\n--\n\n\ +Digit-wise or of x and y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_logical_xor, +"logical_xor($self, x, y, /)\n--\n\n\ +Digit-wise xor of x and y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_max, +"max($self, x, y, /)\n--\n\n\ +Compare the values numerically and return the maximum.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_max_mag, +"max_mag($self, x, y, /)\n--\n\n\ +Compare the values numerically with their sign ignored.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_min, +"min($self, x, y, /)\n--\n\n\ +Compare the values numerically and return the minimum.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_min_mag, +"min_mag($self, x, y, /)\n--\n\n\ +Compare the values numerically with their sign ignored.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_minus, +"minus($self, x, /)\n--\n\n\ +Minus corresponds to the unary prefix minus operator in Python, but applies\n\ +the context to the result.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_multiply, +"multiply($self, x, y, /)\n--\n\n\ +Return the product of x and y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_next_minus, +"next_minus($self, x, /)\n--\n\n\ +Return the largest representable number smaller than x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_next_plus, +"next_plus($self, x, /)\n--\n\n\ +Return the smallest representable number larger than x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_next_toward, +"next_toward($self, x, y, /)\n--\n\n\ +Return the number closest to x, in the direction towards y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_normalize, +"normalize($self, x, /)\n--\n\n\ +Reduce x to its simplest form. Alias for reduce(x).\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_number_class, +"number_class($self, x, /)\n--\n\n\ +Return an indication of the class of x.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_plus, +"plus($self, x, /)\n--\n\n\ +Plus corresponds to the unary prefix plus operator in Python, but applies\n\ +the context to the result.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_power, +"power($self, /, a, b, modulo=None)\n--\n\n\ +Compute a**b. If 'a' is negative, then 'b' must be integral. The result\n\ +will be inexact unless 'a' is integral and the result is finite and can\n\ +be expressed exactly in 'precision' digits. In the Python version the\n\ +result is always correctly rounded, in the C version the result is almost\n\ +always correctly rounded.\n\ +\n\ +If modulo is given, compute (a**b) % modulo. The following restrictions\n\ +hold:\n\ +\n\ + * all three arguments must be integral\n\ + * 'b' must be nonnegative\n\ + * at least one of 'a' or 'b' must be nonzero\n\ + * modulo must be nonzero and less than 10**prec in absolute value\n\ +\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_quantize, +"quantize($self, x, y, /)\n--\n\n\ +Return a value equal to x (rounded), having the exponent of y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_radix, +"radix($self, /)\n--\n\n\ +Return 10.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_remainder, +"remainder($self, x, y, /)\n--\n\n\ +Return the remainder from integer division. The sign of the result,\n\ +if non-zero, is the same as that of the original dividend.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_remainder_near, +"remainder_near($self, x, y, /)\n--\n\n\ +Return x - y * n, where n is the integer nearest the exact value of x / y\n\ +(if the result is 0 then its sign will be the sign of x).\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_rotate, +"rotate($self, x, y, /)\n--\n\n\ +Return a copy of x, rotated by y places.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_same_quantum, +"same_quantum($self, x, y, /)\n--\n\n\ +Return True if the two operands have the same exponent.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_scaleb, +"scaleb($self, x, y, /)\n--\n\n\ +Return the first operand after adding the second value to its exp.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_shift, +"shift($self, x, y, /)\n--\n\n\ +Return a copy of x, shifted by y places.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_sqrt, +"sqrt($self, x, /)\n--\n\n\ +Square root of a non-negative number to context precision.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_subtract, +"subtract($self, x, y, /)\n--\n\n\ +Return the difference between x and y.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_to_eng_string, +"to_eng_string($self, x, /)\n--\n\n\ +Convert a number to a string, using engineering notation.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_to_integral, +"to_integral($self, x, /)\n--\n\n\ +Identical to to_integral_value(x).\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_to_integral_exact, +"to_integral_exact($self, x, /)\n--\n\n\ +Round to an integer. Signal if the result is rounded or inexact.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_to_integral_value, +"to_integral_value($self, x, /)\n--\n\n\ +Round to an integer.\n\ +\n"); + +PyDoc_STRVAR(doc_ctx_to_sci_string, +"to_sci_string($self, x, /)\n--\n\n\ +Convert a number to a string using scientific notation.\n\ +\n"); + + +#endif /* DOCSTRINGS_H */ + + + diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/basearith.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/basearith.c index 85c608fadf5..ac0bfc113af 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/basearith.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/basearith.c @@ -1,655 +1,655 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" #include -#include +#include #include "basearith.h" -#include "constants.h" -#include "typearith.h" - - -/*********************************************************************/ -/* Calculations in base MPD_RADIX */ -/*********************************************************************/ - - -/* - * Knuth, TAOCP, Volume 2, 4.3.1: - * w := sum of u (len m) and v (len n) - * n > 0 and m >= n - * The calling function has to handle a possible final carry. - */ -mpd_uint_t -_mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t m, mpd_size_t n) -{ - mpd_uint_t s; - mpd_uint_t carry = 0; - mpd_size_t i; - - assert(n > 0 && m >= n); - - /* add n members of u and v */ - for (i = 0; i < n; i++) { - s = u[i] + (v[i] + carry); - carry = (s < u[i]) | (s >= MPD_RADIX); - w[i] = carry ? s-MPD_RADIX : s; - } - /* if there is a carry, propagate it */ - for (; carry && i < m; i++) { - s = u[i] + carry; - carry = (s == MPD_RADIX); - w[i] = carry ? 0 : s; - } - /* copy the rest of u */ - for (; i < m; i++) { - w[i] = u[i]; - } - - return carry; -} - -/* - * Add the contents of u to w. Carries are propagated further. The caller - * has to make sure that w is big enough. - */ -void -_mpd_baseaddto(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n) -{ - mpd_uint_t s; - mpd_uint_t carry = 0; - mpd_size_t i; - - if (n == 0) return; - - /* add n members of u to w */ - for (i = 0; i < n; i++) { - s = w[i] + (u[i] + carry); - carry = (s < w[i]) | (s >= MPD_RADIX); - w[i] = carry ? s-MPD_RADIX : s; - } - /* if there is a carry, propagate it */ - for (; carry; i++) { - s = w[i] + carry; - carry = (s == MPD_RADIX); - w[i] = carry ? 0 : s; - } -} - -/* - * Add v to w (len m). The calling function has to handle a possible - * final carry. Assumption: m > 0. - */ -mpd_uint_t -_mpd_shortadd(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v) -{ - mpd_uint_t s; - mpd_uint_t carry; - mpd_size_t i; - - assert(m > 0); - - /* add v to w */ - s = w[0] + v; - carry = (s < v) | (s >= MPD_RADIX); - w[0] = carry ? s-MPD_RADIX : s; - - /* if there is a carry, propagate it */ - for (i = 1; carry && i < m; i++) { - s = w[i] + carry; - carry = (s == MPD_RADIX); - w[i] = carry ? 0 : s; - } - - return carry; -} - -/* Increment u. The calling function has to handle a possible carry. */ -mpd_uint_t -_mpd_baseincr(mpd_uint_t *u, mpd_size_t n) -{ - mpd_uint_t s; - mpd_uint_t carry = 1; - mpd_size_t i; - - assert(n > 0); - - /* if there is a carry, propagate it */ - for (i = 0; carry && i < n; i++) { - s = u[i] + carry; - carry = (s == MPD_RADIX); - u[i] = carry ? 0 : s; - } - - return carry; -} - -/* - * Knuth, TAOCP, Volume 2, 4.3.1: - * w := difference of u (len m) and v (len n). - * number in u >= number in v; - */ -void -_mpd_basesub(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t m, mpd_size_t n) -{ - mpd_uint_t d; - mpd_uint_t borrow = 0; - mpd_size_t i; - - assert(m > 0 && n > 0); - - /* subtract n members of v from u */ - for (i = 0; i < n; i++) { - d = u[i] - (v[i] + borrow); - borrow = (u[i] < d); - w[i] = borrow ? d + MPD_RADIX : d; - } - /* if there is a borrow, propagate it */ - for (; borrow && i < m; i++) { - d = u[i] - borrow; - borrow = (u[i] == 0); - w[i] = borrow ? MPD_RADIX-1 : d; - } - /* copy the rest of u */ - for (; i < m; i++) { - w[i] = u[i]; - } -} - -/* - * Subtract the contents of u from w. w is larger than u. Borrows are - * propagated further, but eventually w can absorb the final borrow. - */ -void -_mpd_basesubfrom(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n) -{ - mpd_uint_t d; - mpd_uint_t borrow = 0; - mpd_size_t i; - - if (n == 0) return; - - /* subtract n members of u from w */ - for (i = 0; i < n; i++) { - d = w[i] - (u[i] + borrow); - borrow = (w[i] < d); - w[i] = borrow ? d + MPD_RADIX : d; - } - /* if there is a borrow, propagate it */ - for (; borrow; i++) { - d = w[i] - borrow; - borrow = (w[i] == 0); - w[i] = borrow ? MPD_RADIX-1 : d; - } -} - -/* w := product of u (len n) and v (single word) */ -void -_mpd_shortmul(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v) -{ - mpd_uint_t hi, lo; - mpd_uint_t carry = 0; - mpd_size_t i; - - assert(n > 0); - - for (i=0; i < n; i++) { - - _mpd_mul_words(&hi, &lo, u[i], v); - lo = carry + lo; - if (lo < carry) hi++; - - _mpd_div_words_r(&carry, &w[i], hi, lo); - } - w[i] = carry; -} - -/* - * Knuth, TAOCP, Volume 2, 4.3.1: - * w := product of u (len m) and v (len n) - * w must be initialized to zero - */ -void -_mpd_basemul(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t m, mpd_size_t n) -{ - mpd_uint_t hi, lo; - mpd_uint_t carry; - mpd_size_t i, j; - - assert(m > 0 && n > 0); - - for (j=0; j < n; j++) { - carry = 0; - for (i=0; i < m; i++) { - - _mpd_mul_words(&hi, &lo, u[i], v[j]); - lo = w[i+j] + lo; - if (lo < w[i+j]) hi++; - lo = carry + lo; - if (lo < carry) hi++; - - _mpd_div_words_r(&carry, &w[i+j], hi, lo); - } - w[j+m] = carry; - } -} - -/* - * Knuth, TAOCP Volume 2, 4.3.1, exercise 16: - * w := quotient of u (len n) divided by a single word v - */ -mpd_uint_t -_mpd_shortdiv(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v) -{ - mpd_uint_t hi, lo; - mpd_uint_t rem = 0; - mpd_size_t i; - - assert(n > 0); - - for (i=n-1; i != MPD_SIZE_MAX; i--) { - - _mpd_mul_words(&hi, &lo, rem, MPD_RADIX); - lo = u[i] + lo; - if (lo < u[i]) hi++; - - _mpd_div_words(&w[i], &rem, hi, lo, v); - } - - return rem; -} - -/* - * Knuth, TAOCP Volume 2, 4.3.1: - * q, r := quotient and remainder of uconst (len nplusm) - * divided by vconst (len n) - * nplusm >= n - * - * If r is not NULL, r will contain the remainder. If r is NULL, the - * return value indicates if there is a remainder: 1 for true, 0 for - * false. A return value of -1 indicates an error. - */ -int -_mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r, - const mpd_uint_t *uconst, const mpd_uint_t *vconst, - mpd_size_t nplusm, mpd_size_t n) -{ - mpd_uint_t ustatic[MPD_MINALLOC_MAX]; - mpd_uint_t vstatic[MPD_MINALLOC_MAX]; - mpd_uint_t *u = ustatic; - mpd_uint_t *v = vstatic; - mpd_uint_t d, qhat, rhat, w2[2]; - mpd_uint_t hi, lo, x; - mpd_uint_t carry; - mpd_size_t i, j, m; - int retval = 0; - - assert(n > 1 && nplusm >= n); - m = sub_size_t(nplusm, n); - - /* D1: normalize */ - d = MPD_RADIX / (vconst[n-1] + 1); - - if (nplusm >= MPD_MINALLOC_MAX) { - if ((u = mpd_alloc(nplusm+1, sizeof *u)) == NULL) { - return -1; - } - } - if (n >= MPD_MINALLOC_MAX) { - if ((v = mpd_alloc(n+1, sizeof *v)) == NULL) { - mpd_free(u); - return -1; - } - } - - _mpd_shortmul(u, uconst, nplusm, d); - _mpd_shortmul(v, vconst, n, d); - - /* D2: loop */ - for (j=m; j != MPD_SIZE_MAX; j--) { +#include "constants.h" +#include "typearith.h" + + +/*********************************************************************/ +/* Calculations in base MPD_RADIX */ +/*********************************************************************/ + + +/* + * Knuth, TAOCP, Volume 2, 4.3.1: + * w := sum of u (len m) and v (len n) + * n > 0 and m >= n + * The calling function has to handle a possible final carry. + */ +mpd_uint_t +_mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t m, mpd_size_t n) +{ + mpd_uint_t s; + mpd_uint_t carry = 0; + mpd_size_t i; + + assert(n > 0 && m >= n); + + /* add n members of u and v */ + for (i = 0; i < n; i++) { + s = u[i] + (v[i] + carry); + carry = (s < u[i]) | (s >= MPD_RADIX); + w[i] = carry ? s-MPD_RADIX : s; + } + /* if there is a carry, propagate it */ + for (; carry && i < m; i++) { + s = u[i] + carry; + carry = (s == MPD_RADIX); + w[i] = carry ? 0 : s; + } + /* copy the rest of u */ + for (; i < m; i++) { + w[i] = u[i]; + } + + return carry; +} + +/* + * Add the contents of u to w. Carries are propagated further. The caller + * has to make sure that w is big enough. + */ +void +_mpd_baseaddto(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n) +{ + mpd_uint_t s; + mpd_uint_t carry = 0; + mpd_size_t i; + + if (n == 0) return; + + /* add n members of u to w */ + for (i = 0; i < n; i++) { + s = w[i] + (u[i] + carry); + carry = (s < w[i]) | (s >= MPD_RADIX); + w[i] = carry ? s-MPD_RADIX : s; + } + /* if there is a carry, propagate it */ + for (; carry; i++) { + s = w[i] + carry; + carry = (s == MPD_RADIX); + w[i] = carry ? 0 : s; + } +} + +/* + * Add v to w (len m). The calling function has to handle a possible + * final carry. Assumption: m > 0. + */ +mpd_uint_t +_mpd_shortadd(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v) +{ + mpd_uint_t s; + mpd_uint_t carry; + mpd_size_t i; + + assert(m > 0); + + /* add v to w */ + s = w[0] + v; + carry = (s < v) | (s >= MPD_RADIX); + w[0] = carry ? s-MPD_RADIX : s; + + /* if there is a carry, propagate it */ + for (i = 1; carry && i < m; i++) { + s = w[i] + carry; + carry = (s == MPD_RADIX); + w[i] = carry ? 0 : s; + } + + return carry; +} + +/* Increment u. The calling function has to handle a possible carry. */ +mpd_uint_t +_mpd_baseincr(mpd_uint_t *u, mpd_size_t n) +{ + mpd_uint_t s; + mpd_uint_t carry = 1; + mpd_size_t i; + + assert(n > 0); + + /* if there is a carry, propagate it */ + for (i = 0; carry && i < n; i++) { + s = u[i] + carry; + carry = (s == MPD_RADIX); + u[i] = carry ? 0 : s; + } + + return carry; +} + +/* + * Knuth, TAOCP, Volume 2, 4.3.1: + * w := difference of u (len m) and v (len n). + * number in u >= number in v; + */ +void +_mpd_basesub(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t m, mpd_size_t n) +{ + mpd_uint_t d; + mpd_uint_t borrow = 0; + mpd_size_t i; + + assert(m > 0 && n > 0); + + /* subtract n members of v from u */ + for (i = 0; i < n; i++) { + d = u[i] - (v[i] + borrow); + borrow = (u[i] < d); + w[i] = borrow ? d + MPD_RADIX : d; + } + /* if there is a borrow, propagate it */ + for (; borrow && i < m; i++) { + d = u[i] - borrow; + borrow = (u[i] == 0); + w[i] = borrow ? MPD_RADIX-1 : d; + } + /* copy the rest of u */ + for (; i < m; i++) { + w[i] = u[i]; + } +} + +/* + * Subtract the contents of u from w. w is larger than u. Borrows are + * propagated further, but eventually w can absorb the final borrow. + */ +void +_mpd_basesubfrom(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n) +{ + mpd_uint_t d; + mpd_uint_t borrow = 0; + mpd_size_t i; + + if (n == 0) return; + + /* subtract n members of u from w */ + for (i = 0; i < n; i++) { + d = w[i] - (u[i] + borrow); + borrow = (w[i] < d); + w[i] = borrow ? d + MPD_RADIX : d; + } + /* if there is a borrow, propagate it */ + for (; borrow; i++) { + d = w[i] - borrow; + borrow = (w[i] == 0); + w[i] = borrow ? MPD_RADIX-1 : d; + } +} + +/* w := product of u (len n) and v (single word) */ +void +_mpd_shortmul(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v) +{ + mpd_uint_t hi, lo; + mpd_uint_t carry = 0; + mpd_size_t i; + + assert(n > 0); + + for (i=0; i < n; i++) { + + _mpd_mul_words(&hi, &lo, u[i], v); + lo = carry + lo; + if (lo < carry) hi++; + + _mpd_div_words_r(&carry, &w[i], hi, lo); + } + w[i] = carry; +} + +/* + * Knuth, TAOCP, Volume 2, 4.3.1: + * w := product of u (len m) and v (len n) + * w must be initialized to zero + */ +void +_mpd_basemul(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t m, mpd_size_t n) +{ + mpd_uint_t hi, lo; + mpd_uint_t carry; + mpd_size_t i, j; + + assert(m > 0 && n > 0); + + for (j=0; j < n; j++) { + carry = 0; + for (i=0; i < m; i++) { + + _mpd_mul_words(&hi, &lo, u[i], v[j]); + lo = w[i+j] + lo; + if (lo < w[i+j]) hi++; + lo = carry + lo; + if (lo < carry) hi++; + + _mpd_div_words_r(&carry, &w[i+j], hi, lo); + } + w[j+m] = carry; + } +} + +/* + * Knuth, TAOCP Volume 2, 4.3.1, exercise 16: + * w := quotient of u (len n) divided by a single word v + */ +mpd_uint_t +_mpd_shortdiv(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v) +{ + mpd_uint_t hi, lo; + mpd_uint_t rem = 0; + mpd_size_t i; + + assert(n > 0); + + for (i=n-1; i != MPD_SIZE_MAX; i--) { + + _mpd_mul_words(&hi, &lo, rem, MPD_RADIX); + lo = u[i] + lo; + if (lo < u[i]) hi++; + + _mpd_div_words(&w[i], &rem, hi, lo, v); + } + + return rem; +} + +/* + * Knuth, TAOCP Volume 2, 4.3.1: + * q, r := quotient and remainder of uconst (len nplusm) + * divided by vconst (len n) + * nplusm >= n + * + * If r is not NULL, r will contain the remainder. If r is NULL, the + * return value indicates if there is a remainder: 1 for true, 0 for + * false. A return value of -1 indicates an error. + */ +int +_mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r, + const mpd_uint_t *uconst, const mpd_uint_t *vconst, + mpd_size_t nplusm, mpd_size_t n) +{ + mpd_uint_t ustatic[MPD_MINALLOC_MAX]; + mpd_uint_t vstatic[MPD_MINALLOC_MAX]; + mpd_uint_t *u = ustatic; + mpd_uint_t *v = vstatic; + mpd_uint_t d, qhat, rhat, w2[2]; + mpd_uint_t hi, lo, x; + mpd_uint_t carry; + mpd_size_t i, j, m; + int retval = 0; + + assert(n > 1 && nplusm >= n); + m = sub_size_t(nplusm, n); + + /* D1: normalize */ + d = MPD_RADIX / (vconst[n-1] + 1); + + if (nplusm >= MPD_MINALLOC_MAX) { + if ((u = mpd_alloc(nplusm+1, sizeof *u)) == NULL) { + return -1; + } + } + if (n >= MPD_MINALLOC_MAX) { + if ((v = mpd_alloc(n+1, sizeof *v)) == NULL) { + mpd_free(u); + return -1; + } + } + + _mpd_shortmul(u, uconst, nplusm, d); + _mpd_shortmul(v, vconst, n, d); + + /* D2: loop */ + for (j=m; j != MPD_SIZE_MAX; j--) { assert(2 <= j+n && j+n <= nplusm); /* annotation for scan-build */ - - /* D3: calculate qhat and rhat */ - rhat = _mpd_shortdiv(w2, u+j+n-1, 2, v[n-1]); - qhat = w2[1] * MPD_RADIX + w2[0]; - - while (1) { - if (qhat < MPD_RADIX) { - _mpd_singlemul(w2, qhat, v[n-2]); - if (w2[1] <= rhat) { - if (w2[1] != rhat || w2[0] <= u[j+n-2]) { - break; - } - } - } - qhat -= 1; - rhat += v[n-1]; - if (rhat < v[n-1] || rhat >= MPD_RADIX) { - break; - } - } - /* D4: multiply and subtract */ - carry = 0; - for (i=0; i <= n; i++) { - - _mpd_mul_words(&hi, &lo, qhat, v[i]); - - lo = carry + lo; - if (lo < carry) hi++; - - _mpd_div_words_r(&hi, &lo, hi, lo); - - x = u[i+j] - lo; - carry = (u[i+j] < x); - u[i+j] = carry ? x+MPD_RADIX : x; - carry += hi; - } - q[j] = qhat; - /* D5: test remainder */ - if (carry) { - q[j] -= 1; - /* D6: add back */ - (void)_mpd_baseadd(u+j, u+j, v, n+1, n); - } - } - - /* D8: unnormalize */ - if (r != NULL) { - _mpd_shortdiv(r, u, n, d); - /* we are not interested in the return value here */ - retval = 0; - } - else { - retval = !_mpd_isallzero(u, n); - } - - -if (u != ustatic) mpd_free(u); -if (v != vstatic) mpd_free(v); -return retval; -} - -/* - * Left shift of src by 'shift' digits; src may equal dest. - * - * dest := area of n mpd_uint_t with space for srcdigits+shift digits. - * src := coefficient with length m. - * - * The case splits in the function are non-obvious. The following - * equations might help: - * - * Let msdigits denote the number of digits in the most significant - * word of src. Then 1 <= msdigits <= rdigits. - * - * 1) shift = q * rdigits + r - * 2) srcdigits = qsrc * rdigits + msdigits - * 3) destdigits = shift + srcdigits - * = q * rdigits + r + qsrc * rdigits + msdigits - * = q * rdigits + (qsrc * rdigits + (r + msdigits)) - * - * The result has q zero words, followed by the coefficient that - * is left-shifted by r. The case r == 0 is trivial. For r > 0, it - * is important to keep in mind that we always read m source words, - * but write m+1 destination words if r + msdigits > rdigits, m words - * otherwise. - */ -void -_mpd_baseshiftl(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t n, mpd_size_t m, - mpd_size_t shift) -{ -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) - /* spurious uninitialized warnings */ - mpd_uint_t l=l, lprev=lprev, h=h; -#else - mpd_uint_t l, lprev, h; -#endif - mpd_uint_t q, r; - mpd_uint_t ph; - - assert(m > 0 && n >= m); - - _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS); - - if (r != 0) { - - ph = mpd_pow10[r]; - - --m; --n; - _mpd_divmod_pow10(&h, &lprev, src[m--], MPD_RDIGITS-r); - if (h != 0) { /* r + msdigits > rdigits <==> h != 0 */ - dest[n--] = h; - } - /* write m-1 shifted words */ - for (; m != MPD_SIZE_MAX; m--,n--) { - _mpd_divmod_pow10(&h, &l, src[m], MPD_RDIGITS-r); - dest[n] = ph * lprev + h; - lprev = l; - } - /* write least significant word */ - dest[q] = ph * lprev; - } - else { - while (--m != MPD_SIZE_MAX) { - dest[m+q] = src[m]; - } - } - - mpd_uint_zero(dest, q); -} - -/* - * Right shift of src by 'shift' digits; src may equal dest. - * Assumption: srcdigits-shift > 0. - * - * dest := area with space for srcdigits-shift digits. - * src := coefficient with length 'slen'. - * - * The case splits in the function rely on the following equations: - * - * Let msdigits denote the number of digits in the most significant - * word of src. Then 1 <= msdigits <= rdigits. - * - * 1) shift = q * rdigits + r - * 2) srcdigits = qsrc * rdigits + msdigits - * 3) destdigits = srcdigits - shift - * = qsrc * rdigits + msdigits - (q * rdigits + r) - * = (qsrc - q) * rdigits + msdigits - r - * - * Since destdigits > 0 and 1 <= msdigits <= rdigits: - * - * 4) qsrc >= q - * 5) qsrc == q ==> msdigits > r - * - * The result has slen-q words if msdigits > r, slen-q-1 words otherwise. - */ -mpd_uint_t -_mpd_baseshiftr(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t slen, - mpd_size_t shift) -{ -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) - /* spurious uninitialized warnings */ - mpd_uint_t l=l, h=h, hprev=hprev; /* low, high, previous high */ -#else - mpd_uint_t l, h, hprev; /* low, high, previous high */ -#endif - mpd_uint_t rnd, rest; /* rounding digit, rest */ - mpd_uint_t q, r; - mpd_size_t i, j; - mpd_uint_t ph; - - assert(slen > 0); - - _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS); - - rnd = rest = 0; - if (r != 0) { - - ph = mpd_pow10[MPD_RDIGITS-r]; - - _mpd_divmod_pow10(&hprev, &rest, src[q], r); - _mpd_divmod_pow10(&rnd, &rest, rest, r-1); - - if (rest == 0 && q > 0) { - rest = !_mpd_isallzero(src, q); - } - /* write slen-q-1 words */ - for (j=0,i=q+1; i 0) { - _mpd_divmod_pow10(&rnd, &rest, src[q-1], MPD_RDIGITS-1); - /* is there any non-zero digit below rnd? */ - if (rest == 0) rest = !_mpd_isallzero(src, q-1); - } - for (j = 0; j < slen-q; j++) { - dest[j] = src[q+j]; - } - } - - /* 0-4 ==> rnd+rest < 0.5 */ - /* 5 ==> rnd+rest == 0.5 */ - /* 6-9 ==> rnd+rest > 0.5 */ - return (rnd == 0 || rnd == 5) ? rnd + !!rest : rnd; -} - - -/*********************************************************************/ -/* Calculations in base b */ -/*********************************************************************/ - -/* - * Add v to w (len m). The calling function has to handle a possible - * final carry. Assumption: m > 0. - */ -mpd_uint_t -_mpd_shortadd_b(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v, mpd_uint_t b) -{ - mpd_uint_t s; - mpd_uint_t carry; - mpd_size_t i; - - assert(m > 0); - - /* add v to w */ - s = w[0] + v; - carry = (s < v) | (s >= b); - w[0] = carry ? s-b : s; - - /* if there is a carry, propagate it */ - for (i = 1; carry && i < m; i++) { - s = w[i] + carry; - carry = (s == b); - w[i] = carry ? 0 : s; - } - - return carry; -} - -/* w := product of u (len n) and v (single word). Return carry. */ -mpd_uint_t -_mpd_shortmul_c(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v) -{ - mpd_uint_t hi, lo; - mpd_uint_t carry = 0; - mpd_size_t i; - - assert(n > 0); - - for (i=0; i < n; i++) { - - _mpd_mul_words(&hi, &lo, u[i], v); - lo = carry + lo; - if (lo < carry) hi++; - - _mpd_div_words_r(&carry, &w[i], hi, lo); - } - - return carry; -} - -/* w := product of u (len n) and v (single word) */ -mpd_uint_t -_mpd_shortmul_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, - mpd_uint_t v, mpd_uint_t b) -{ - mpd_uint_t hi, lo; - mpd_uint_t carry = 0; - mpd_size_t i; - - assert(n > 0); - - for (i=0; i < n; i++) { - - _mpd_mul_words(&hi, &lo, u[i], v); - lo = carry + lo; - if (lo < carry) hi++; - - _mpd_div_words(&carry, &w[i], hi, lo, b); - } - - return carry; -} - -/* - * Knuth, TAOCP Volume 2, 4.3.1, exercise 16: - * w := quotient of u (len n) divided by a single word v - */ -mpd_uint_t -_mpd_shortdiv_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, - mpd_uint_t v, mpd_uint_t b) -{ - mpd_uint_t hi, lo; - mpd_uint_t rem = 0; - mpd_size_t i; - - assert(n > 0); - - for (i=n-1; i != MPD_SIZE_MAX; i--) { - - _mpd_mul_words(&hi, &lo, rem, b); - lo = u[i] + lo; - if (lo < u[i]) hi++; - - _mpd_div_words(&w[i], &rem, hi, lo, v); - } - - return rem; -} + + /* D3: calculate qhat and rhat */ + rhat = _mpd_shortdiv(w2, u+j+n-1, 2, v[n-1]); + qhat = w2[1] * MPD_RADIX + w2[0]; + + while (1) { + if (qhat < MPD_RADIX) { + _mpd_singlemul(w2, qhat, v[n-2]); + if (w2[1] <= rhat) { + if (w2[1] != rhat || w2[0] <= u[j+n-2]) { + break; + } + } + } + qhat -= 1; + rhat += v[n-1]; + if (rhat < v[n-1] || rhat >= MPD_RADIX) { + break; + } + } + /* D4: multiply and subtract */ + carry = 0; + for (i=0; i <= n; i++) { + + _mpd_mul_words(&hi, &lo, qhat, v[i]); + + lo = carry + lo; + if (lo < carry) hi++; + + _mpd_div_words_r(&hi, &lo, hi, lo); + + x = u[i+j] - lo; + carry = (u[i+j] < x); + u[i+j] = carry ? x+MPD_RADIX : x; + carry += hi; + } + q[j] = qhat; + /* D5: test remainder */ + if (carry) { + q[j] -= 1; + /* D6: add back */ + (void)_mpd_baseadd(u+j, u+j, v, n+1, n); + } + } + + /* D8: unnormalize */ + if (r != NULL) { + _mpd_shortdiv(r, u, n, d); + /* we are not interested in the return value here */ + retval = 0; + } + else { + retval = !_mpd_isallzero(u, n); + } + + +if (u != ustatic) mpd_free(u); +if (v != vstatic) mpd_free(v); +return retval; +} + +/* + * Left shift of src by 'shift' digits; src may equal dest. + * + * dest := area of n mpd_uint_t with space for srcdigits+shift digits. + * src := coefficient with length m. + * + * The case splits in the function are non-obvious. The following + * equations might help: + * + * Let msdigits denote the number of digits in the most significant + * word of src. Then 1 <= msdigits <= rdigits. + * + * 1) shift = q * rdigits + r + * 2) srcdigits = qsrc * rdigits + msdigits + * 3) destdigits = shift + srcdigits + * = q * rdigits + r + qsrc * rdigits + msdigits + * = q * rdigits + (qsrc * rdigits + (r + msdigits)) + * + * The result has q zero words, followed by the coefficient that + * is left-shifted by r. The case r == 0 is trivial. For r > 0, it + * is important to keep in mind that we always read m source words, + * but write m+1 destination words if r + msdigits > rdigits, m words + * otherwise. + */ +void +_mpd_baseshiftl(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t n, mpd_size_t m, + mpd_size_t shift) +{ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) + /* spurious uninitialized warnings */ + mpd_uint_t l=l, lprev=lprev, h=h; +#else + mpd_uint_t l, lprev, h; +#endif + mpd_uint_t q, r; + mpd_uint_t ph; + + assert(m > 0 && n >= m); + + _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS); + + if (r != 0) { + + ph = mpd_pow10[r]; + + --m; --n; + _mpd_divmod_pow10(&h, &lprev, src[m--], MPD_RDIGITS-r); + if (h != 0) { /* r + msdigits > rdigits <==> h != 0 */ + dest[n--] = h; + } + /* write m-1 shifted words */ + for (; m != MPD_SIZE_MAX; m--,n--) { + _mpd_divmod_pow10(&h, &l, src[m], MPD_RDIGITS-r); + dest[n] = ph * lprev + h; + lprev = l; + } + /* write least significant word */ + dest[q] = ph * lprev; + } + else { + while (--m != MPD_SIZE_MAX) { + dest[m+q] = src[m]; + } + } + + mpd_uint_zero(dest, q); +} + +/* + * Right shift of src by 'shift' digits; src may equal dest. + * Assumption: srcdigits-shift > 0. + * + * dest := area with space for srcdigits-shift digits. + * src := coefficient with length 'slen'. + * + * The case splits in the function rely on the following equations: + * + * Let msdigits denote the number of digits in the most significant + * word of src. Then 1 <= msdigits <= rdigits. + * + * 1) shift = q * rdigits + r + * 2) srcdigits = qsrc * rdigits + msdigits + * 3) destdigits = srcdigits - shift + * = qsrc * rdigits + msdigits - (q * rdigits + r) + * = (qsrc - q) * rdigits + msdigits - r + * + * Since destdigits > 0 and 1 <= msdigits <= rdigits: + * + * 4) qsrc >= q + * 5) qsrc == q ==> msdigits > r + * + * The result has slen-q words if msdigits > r, slen-q-1 words otherwise. + */ +mpd_uint_t +_mpd_baseshiftr(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t slen, + mpd_size_t shift) +{ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) + /* spurious uninitialized warnings */ + mpd_uint_t l=l, h=h, hprev=hprev; /* low, high, previous high */ +#else + mpd_uint_t l, h, hprev; /* low, high, previous high */ +#endif + mpd_uint_t rnd, rest; /* rounding digit, rest */ + mpd_uint_t q, r; + mpd_size_t i, j; + mpd_uint_t ph; + + assert(slen > 0); + + _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS); + + rnd = rest = 0; + if (r != 0) { + + ph = mpd_pow10[MPD_RDIGITS-r]; + + _mpd_divmod_pow10(&hprev, &rest, src[q], r); + _mpd_divmod_pow10(&rnd, &rest, rest, r-1); + + if (rest == 0 && q > 0) { + rest = !_mpd_isallzero(src, q); + } + /* write slen-q-1 words */ + for (j=0,i=q+1; i 0) { + _mpd_divmod_pow10(&rnd, &rest, src[q-1], MPD_RDIGITS-1); + /* is there any non-zero digit below rnd? */ + if (rest == 0) rest = !_mpd_isallzero(src, q-1); + } + for (j = 0; j < slen-q; j++) { + dest[j] = src[q+j]; + } + } + + /* 0-4 ==> rnd+rest < 0.5 */ + /* 5 ==> rnd+rest == 0.5 */ + /* 6-9 ==> rnd+rest > 0.5 */ + return (rnd == 0 || rnd == 5) ? rnd + !!rest : rnd; +} + + +/*********************************************************************/ +/* Calculations in base b */ +/*********************************************************************/ + +/* + * Add v to w (len m). The calling function has to handle a possible + * final carry. Assumption: m > 0. + */ +mpd_uint_t +_mpd_shortadd_b(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v, mpd_uint_t b) +{ + mpd_uint_t s; + mpd_uint_t carry; + mpd_size_t i; + + assert(m > 0); + + /* add v to w */ + s = w[0] + v; + carry = (s < v) | (s >= b); + w[0] = carry ? s-b : s; + + /* if there is a carry, propagate it */ + for (i = 1; carry && i < m; i++) { + s = w[i] + carry; + carry = (s == b); + w[i] = carry ? 0 : s; + } + + return carry; +} + +/* w := product of u (len n) and v (single word). Return carry. */ +mpd_uint_t +_mpd_shortmul_c(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v) +{ + mpd_uint_t hi, lo; + mpd_uint_t carry = 0; + mpd_size_t i; + + assert(n > 0); + + for (i=0; i < n; i++) { + + _mpd_mul_words(&hi, &lo, u[i], v); + lo = carry + lo; + if (lo < carry) hi++; + + _mpd_div_words_r(&carry, &w[i], hi, lo); + } + + return carry; +} + +/* w := product of u (len n) and v (single word) */ +mpd_uint_t +_mpd_shortmul_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, + mpd_uint_t v, mpd_uint_t b) +{ + mpd_uint_t hi, lo; + mpd_uint_t carry = 0; + mpd_size_t i; + + assert(n > 0); + + for (i=0; i < n; i++) { + + _mpd_mul_words(&hi, &lo, u[i], v); + lo = carry + lo; + if (lo < carry) hi++; + + _mpd_div_words(&carry, &w[i], hi, lo, b); + } + + return carry; +} + +/* + * Knuth, TAOCP Volume 2, 4.3.1, exercise 16: + * w := quotient of u (len n) divided by a single word v + */ +mpd_uint_t +_mpd_shortdiv_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, + mpd_uint_t v, mpd_uint_t b) +{ + mpd_uint_t hi, lo; + mpd_uint_t rem = 0; + mpd_size_t i; + + assert(n > 0); + + for (i=n-1; i != MPD_SIZE_MAX; i--) { + + _mpd_mul_words(&hi, &lo, rem, b); + lo = u[i] + lo; + if (lo < u[i]) hi++; + + _mpd_div_words(&w[i], &rem, hi, lo, v); + } + + return rem; +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/basearith.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/basearith.h index d35925aaddb..651b0645691 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/basearith.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/basearith.h @@ -1,218 +1,218 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_BASEARITH_H_ #define LIBMPDEC_BASEARITH_H_ - - -#include "mpdecimal.h" -#include "typearith.h" - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -mpd_uint_t _mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t m, mpd_size_t n); -void _mpd_baseaddto(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n); -mpd_uint_t _mpd_shortadd(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v); -mpd_uint_t _mpd_shortadd_b(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v, - mpd_uint_t b); -mpd_uint_t _mpd_baseincr(mpd_uint_t *u, mpd_size_t n); -void _mpd_basesub(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t m, mpd_size_t n); -void _mpd_basesubfrom(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n); -void _mpd_basemul(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t m, mpd_size_t n); -void _mpd_shortmul(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, - mpd_uint_t v); -mpd_uint_t _mpd_shortmul_c(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, - mpd_uint_t v); -mpd_uint_t _mpd_shortmul_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, - mpd_uint_t v, mpd_uint_t b); -mpd_uint_t _mpd_shortdiv(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, - mpd_uint_t v); -mpd_uint_t _mpd_shortdiv_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, - mpd_uint_t v, mpd_uint_t b); -int _mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r, const mpd_uint_t *uconst, - const mpd_uint_t *vconst, mpd_size_t nplusm, mpd_size_t n); -void _mpd_baseshiftl(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t n, - mpd_size_t m, mpd_size_t shift); -mpd_uint_t _mpd_baseshiftr(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t slen, - mpd_size_t shift); - - - -#ifdef CONFIG_64 -extern const mpd_uint_t mprime_rdx; - -/* - * Algorithm from: Division by Invariant Integers using Multiplication, - * T. Granlund and P. L. Montgomery, Proceedings of the SIGPLAN '94 - * Conference on Programming Language Design and Implementation. - * - * http://gmplib.org/~tege/divcnst-pldi94.pdf - * - * Variables from the paper and their translations (See section 8): - * - * N := 64 - * d := MPD_RADIX - * l := 64 - * m' := floor((2**(64+64) - 1)/MPD_RADIX) - 2**64 - * - * Since N-l == 0: - * - * dnorm := d - * n2 := hi - * n10 := lo - * - * ACL2 proof: mpd-div-words-r-correct - */ -static inline void -_mpd_div_words_r(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo) -{ - mpd_uint_t n_adj, h, l, t; - mpd_uint_t n1_neg; - - /* n1_neg = if lo >= 2**63 then MPD_UINT_MAX else 0 */ - n1_neg = (lo & (1ULL<<63)) ? MPD_UINT_MAX : 0; - /* n_adj = if lo >= 2**63 then lo+MPD_RADIX else lo */ - n_adj = lo + (n1_neg & MPD_RADIX); - - /* (h, l) = if lo >= 2**63 then m'*(hi+1) else m'*hi */ - _mpd_mul_words(&h, &l, mprime_rdx, hi-n1_neg); - l = l + n_adj; - if (l < n_adj) h++; - t = h + hi; - /* At this point t == qest, with q == qest or q == qest+1: - * 1) 0 <= 2**64*hi + lo - qest*MPD_RADIX < 2*MPD_RADIX - */ - - /* t = 2**64-1 - qest = 2**64 - (qest+1) */ - t = MPD_UINT_MAX - t; - - /* (h, l) = 2**64*MPD_RADIX - (qest+1)*MPD_RADIX */ - _mpd_mul_words(&h, &l, t, MPD_RADIX); - l = l + lo; - if (l < lo) h++; - h += hi; - h -= MPD_RADIX; - /* (h, l) = 2**64*hi + lo - (qest+1)*MPD_RADIX (mod 2**128) - * Case q == qest+1: - * a) h == 0, l == r - * b) q := h - t == qest+1 - * c) r := l - * Case q == qest: - * a) h == MPD_UINT_MAX, l == 2**64-(MPD_RADIX-r) - * b) q := h - t == qest - * c) r := l + MPD_RADIX = r - */ - - *q = (h - t); - *r = l + (MPD_RADIX & h); -} -#else -static inline void -_mpd_div_words_r(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo) -{ - _mpd_div_words(q, r, hi, lo, MPD_RADIX); -} -#endif - - -/* Multiply two single base MPD_RADIX words, store result in array w[2]. */ -static inline void -_mpd_singlemul(mpd_uint_t w[2], mpd_uint_t u, mpd_uint_t v) -{ - mpd_uint_t hi, lo; - - _mpd_mul_words(&hi, &lo, u, v); - _mpd_div_words_r(&w[1], &w[0], hi, lo); -} - -/* Multiply u (len 2) and v (len m, 1 <= m <= 2). */ -static inline void -_mpd_mul_2_le2(mpd_uint_t w[4], mpd_uint_t u[2], mpd_uint_t v[2], mpd_ssize_t m) -{ - mpd_uint_t hi, lo; - - _mpd_mul_words(&hi, &lo, u[0], v[0]); - _mpd_div_words_r(&w[1], &w[0], hi, lo); - - _mpd_mul_words(&hi, &lo, u[1], v[0]); - lo = w[1] + lo; - if (lo < w[1]) hi++; - _mpd_div_words_r(&w[2], &w[1], hi, lo); - if (m == 1) return; - - _mpd_mul_words(&hi, &lo, u[0], v[1]); - lo = w[1] + lo; - if (lo < w[1]) hi++; - _mpd_div_words_r(&w[3], &w[1], hi, lo); - - _mpd_mul_words(&hi, &lo, u[1], v[1]); - lo = w[2] + lo; - if (lo < w[2]) hi++; - lo = w[3] + lo; - if (lo < w[3]) hi++; - _mpd_div_words_r(&w[3], &w[2], hi, lo); -} - - -/* - * Test if all words from data[len-1] to data[0] are zero. If len is 0, nothing - * is tested and the coefficient is regarded as "all zero". - */ -static inline int -_mpd_isallzero(const mpd_uint_t *data, mpd_ssize_t len) -{ - while (--len >= 0) { - if (data[len] != 0) return 0; - } - return 1; -} - -/* - * Test if all full words from data[len-1] to data[0] are MPD_RADIX-1 - * (all nines). Return true if len == 0. - */ -static inline int -_mpd_isallnine(const mpd_uint_t *data, mpd_ssize_t len) -{ - while (--len >= 0) { - if (data[len] != MPD_RADIX-1) return 0; - } - return 1; -} - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - + + +#include "mpdecimal.h" +#include "typearith.h" + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +mpd_uint_t _mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t m, mpd_size_t n); +void _mpd_baseaddto(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n); +mpd_uint_t _mpd_shortadd(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v); +mpd_uint_t _mpd_shortadd_b(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v, + mpd_uint_t b); +mpd_uint_t _mpd_baseincr(mpd_uint_t *u, mpd_size_t n); +void _mpd_basesub(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t m, mpd_size_t n); +void _mpd_basesubfrom(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n); +void _mpd_basemul(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t m, mpd_size_t n); +void _mpd_shortmul(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, + mpd_uint_t v); +mpd_uint_t _mpd_shortmul_c(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, + mpd_uint_t v); +mpd_uint_t _mpd_shortmul_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, + mpd_uint_t v, mpd_uint_t b); +mpd_uint_t _mpd_shortdiv(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, + mpd_uint_t v); +mpd_uint_t _mpd_shortdiv_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, + mpd_uint_t v, mpd_uint_t b); +int _mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r, const mpd_uint_t *uconst, + const mpd_uint_t *vconst, mpd_size_t nplusm, mpd_size_t n); +void _mpd_baseshiftl(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t n, + mpd_size_t m, mpd_size_t shift); +mpd_uint_t _mpd_baseshiftr(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t slen, + mpd_size_t shift); + + + +#ifdef CONFIG_64 +extern const mpd_uint_t mprime_rdx; + +/* + * Algorithm from: Division by Invariant Integers using Multiplication, + * T. Granlund and P. L. Montgomery, Proceedings of the SIGPLAN '94 + * Conference on Programming Language Design and Implementation. + * + * http://gmplib.org/~tege/divcnst-pldi94.pdf + * + * Variables from the paper and their translations (See section 8): + * + * N := 64 + * d := MPD_RADIX + * l := 64 + * m' := floor((2**(64+64) - 1)/MPD_RADIX) - 2**64 + * + * Since N-l == 0: + * + * dnorm := d + * n2 := hi + * n10 := lo + * + * ACL2 proof: mpd-div-words-r-correct + */ +static inline void +_mpd_div_words_r(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo) +{ + mpd_uint_t n_adj, h, l, t; + mpd_uint_t n1_neg; + + /* n1_neg = if lo >= 2**63 then MPD_UINT_MAX else 0 */ + n1_neg = (lo & (1ULL<<63)) ? MPD_UINT_MAX : 0; + /* n_adj = if lo >= 2**63 then lo+MPD_RADIX else lo */ + n_adj = lo + (n1_neg & MPD_RADIX); + + /* (h, l) = if lo >= 2**63 then m'*(hi+1) else m'*hi */ + _mpd_mul_words(&h, &l, mprime_rdx, hi-n1_neg); + l = l + n_adj; + if (l < n_adj) h++; + t = h + hi; + /* At this point t == qest, with q == qest or q == qest+1: + * 1) 0 <= 2**64*hi + lo - qest*MPD_RADIX < 2*MPD_RADIX + */ + + /* t = 2**64-1 - qest = 2**64 - (qest+1) */ + t = MPD_UINT_MAX - t; + + /* (h, l) = 2**64*MPD_RADIX - (qest+1)*MPD_RADIX */ + _mpd_mul_words(&h, &l, t, MPD_RADIX); + l = l + lo; + if (l < lo) h++; + h += hi; + h -= MPD_RADIX; + /* (h, l) = 2**64*hi + lo - (qest+1)*MPD_RADIX (mod 2**128) + * Case q == qest+1: + * a) h == 0, l == r + * b) q := h - t == qest+1 + * c) r := l + * Case q == qest: + * a) h == MPD_UINT_MAX, l == 2**64-(MPD_RADIX-r) + * b) q := h - t == qest + * c) r := l + MPD_RADIX = r + */ + + *q = (h - t); + *r = l + (MPD_RADIX & h); +} +#else +static inline void +_mpd_div_words_r(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo) +{ + _mpd_div_words(q, r, hi, lo, MPD_RADIX); +} +#endif + + +/* Multiply two single base MPD_RADIX words, store result in array w[2]. */ +static inline void +_mpd_singlemul(mpd_uint_t w[2], mpd_uint_t u, mpd_uint_t v) +{ + mpd_uint_t hi, lo; + + _mpd_mul_words(&hi, &lo, u, v); + _mpd_div_words_r(&w[1], &w[0], hi, lo); +} + +/* Multiply u (len 2) and v (len m, 1 <= m <= 2). */ +static inline void +_mpd_mul_2_le2(mpd_uint_t w[4], mpd_uint_t u[2], mpd_uint_t v[2], mpd_ssize_t m) +{ + mpd_uint_t hi, lo; + + _mpd_mul_words(&hi, &lo, u[0], v[0]); + _mpd_div_words_r(&w[1], &w[0], hi, lo); + + _mpd_mul_words(&hi, &lo, u[1], v[0]); + lo = w[1] + lo; + if (lo < w[1]) hi++; + _mpd_div_words_r(&w[2], &w[1], hi, lo); + if (m == 1) return; + + _mpd_mul_words(&hi, &lo, u[0], v[1]); + lo = w[1] + lo; + if (lo < w[1]) hi++; + _mpd_div_words_r(&w[3], &w[1], hi, lo); + + _mpd_mul_words(&hi, &lo, u[1], v[1]); + lo = w[2] + lo; + if (lo < w[2]) hi++; + lo = w[3] + lo; + if (lo < w[3]) hi++; + _mpd_div_words_r(&w[3], &w[2], hi, lo); +} + + +/* + * Test if all words from data[len-1] to data[0] are zero. If len is 0, nothing + * is tested and the coefficient is regarded as "all zero". + */ +static inline int +_mpd_isallzero(const mpd_uint_t *data, mpd_ssize_t len) +{ + while (--len >= 0) { + if (data[len] != 0) return 0; + } + return 1; +} + +/* + * Test if all full words from data[len-1] to data[0] are MPD_RADIX-1 + * (all nines). Return true if len == 0. + */ +static inline int +_mpd_isallnine(const mpd_uint_t *data, mpd_ssize_t len) +{ + while (--len >= 0) { + if (data[len] != MPD_RADIX-1) return 0; + } + return 1; +} + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_BASEARITH_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/bits.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/bits.h index aa9c3e77980..743b0e3b792 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/bits.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/bits.h @@ -1,188 +1,188 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_BITS_H_ #define LIBMPDEC_BITS_H_ - - -#include "mpdecimal.h" - - -/* Check if n is a power of 2. */ -static inline int -ispower2(mpd_size_t n) -{ - return n != 0 && (n & (n-1)) == 0; -} - -#if defined(ANSI) -/* - * Return the most significant bit position of n from 0 to 31 (63). - * Assumptions: n != 0. - */ -static inline int -mpd_bsr(mpd_size_t n) -{ - int pos = 0; - mpd_size_t tmp; - -#ifdef CONFIG_64 - tmp = n >> 32; - if (tmp != 0) { n = tmp; pos += 32; } -#endif - tmp = n >> 16; - if (tmp != 0) { n = tmp; pos += 16; } - tmp = n >> 8; - if (tmp != 0) { n = tmp; pos += 8; } - tmp = n >> 4; - if (tmp != 0) { n = tmp; pos += 4; } - tmp = n >> 2; - if (tmp != 0) { n = tmp; pos += 2; } - tmp = n >> 1; - if (tmp != 0) { n = tmp; pos += 1; } - - return pos + (int)n - 1; -} - -/* - * Return the least significant bit position of n from 0 to 31 (63). - * Assumptions: n != 0. - */ -static inline int -mpd_bsf(mpd_size_t n) -{ - int pos; - -#ifdef CONFIG_64 - pos = 63; - if (n & 0x00000000FFFFFFFFULL) { pos -= 32; } else { n >>= 32; } - if (n & 0x000000000000FFFFULL) { pos -= 16; } else { n >>= 16; } - if (n & 0x00000000000000FFULL) { pos -= 8; } else { n >>= 8; } - if (n & 0x000000000000000FULL) { pos -= 4; } else { n >>= 4; } - if (n & 0x0000000000000003ULL) { pos -= 2; } else { n >>= 2; } - if (n & 0x0000000000000001ULL) { pos -= 1; } -#else - pos = 31; - if (n & 0x000000000000FFFFUL) { pos -= 16; } else { n >>= 16; } - if (n & 0x00000000000000FFUL) { pos -= 8; } else { n >>= 8; } - if (n & 0x000000000000000FUL) { pos -= 4; } else { n >>= 4; } - if (n & 0x0000000000000003UL) { pos -= 2; } else { n >>= 2; } - if (n & 0x0000000000000001UL) { pos -= 1; } -#endif - return pos; -} -/* END ANSI */ - -#elif defined(ASM) -/* - * Bit scan reverse. Assumptions: a != 0. - */ -static inline int -mpd_bsr(mpd_size_t a) -{ - mpd_size_t retval; - - __asm__ ( -#ifdef CONFIG_64 - "bsrq %1, %0\n\t" -#else - "bsr %1, %0\n\t" -#endif - :"=r" (retval) - :"r" (a) - :"cc" - ); - - return (int)retval; -} - -/* - * Bit scan forward. Assumptions: a != 0. - */ -static inline int -mpd_bsf(mpd_size_t a) -{ - mpd_size_t retval; - - __asm__ ( -#ifdef CONFIG_64 - "bsfq %1, %0\n\t" -#else - "bsf %1, %0\n\t" -#endif - :"=r" (retval) - :"r" (a) - :"cc" - ); - - return (int)retval; -} -/* END ASM */ - -#elif defined(MASM) -#include -/* - * Bit scan reverse. Assumptions: a != 0. - */ -static inline int __cdecl -mpd_bsr(mpd_size_t a) -{ - unsigned long retval; - -#ifdef CONFIG_64 - _BitScanReverse64(&retval, a); -#else - _BitScanReverse(&retval, a); -#endif - - return (int)retval; -} - -/* - * Bit scan forward. Assumptions: a != 0. - */ -static inline int __cdecl -mpd_bsf(mpd_size_t a) -{ - unsigned long retval; - -#ifdef CONFIG_64 - _BitScanForward64(&retval, a); -#else - _BitScanForward(&retval, a); -#endif - - return (int)retval; -} -/* END MASM (_MSC_VER) */ -#else - #error "missing preprocessor definitions" -#endif /* BSR/BSF */ - - + + +#include "mpdecimal.h" + + +/* Check if n is a power of 2. */ +static inline int +ispower2(mpd_size_t n) +{ + return n != 0 && (n & (n-1)) == 0; +} + +#if defined(ANSI) +/* + * Return the most significant bit position of n from 0 to 31 (63). + * Assumptions: n != 0. + */ +static inline int +mpd_bsr(mpd_size_t n) +{ + int pos = 0; + mpd_size_t tmp; + +#ifdef CONFIG_64 + tmp = n >> 32; + if (tmp != 0) { n = tmp; pos += 32; } +#endif + tmp = n >> 16; + if (tmp != 0) { n = tmp; pos += 16; } + tmp = n >> 8; + if (tmp != 0) { n = tmp; pos += 8; } + tmp = n >> 4; + if (tmp != 0) { n = tmp; pos += 4; } + tmp = n >> 2; + if (tmp != 0) { n = tmp; pos += 2; } + tmp = n >> 1; + if (tmp != 0) { n = tmp; pos += 1; } + + return pos + (int)n - 1; +} + +/* + * Return the least significant bit position of n from 0 to 31 (63). + * Assumptions: n != 0. + */ +static inline int +mpd_bsf(mpd_size_t n) +{ + int pos; + +#ifdef CONFIG_64 + pos = 63; + if (n & 0x00000000FFFFFFFFULL) { pos -= 32; } else { n >>= 32; } + if (n & 0x000000000000FFFFULL) { pos -= 16; } else { n >>= 16; } + if (n & 0x00000000000000FFULL) { pos -= 8; } else { n >>= 8; } + if (n & 0x000000000000000FULL) { pos -= 4; } else { n >>= 4; } + if (n & 0x0000000000000003ULL) { pos -= 2; } else { n >>= 2; } + if (n & 0x0000000000000001ULL) { pos -= 1; } +#else + pos = 31; + if (n & 0x000000000000FFFFUL) { pos -= 16; } else { n >>= 16; } + if (n & 0x00000000000000FFUL) { pos -= 8; } else { n >>= 8; } + if (n & 0x000000000000000FUL) { pos -= 4; } else { n >>= 4; } + if (n & 0x0000000000000003UL) { pos -= 2; } else { n >>= 2; } + if (n & 0x0000000000000001UL) { pos -= 1; } +#endif + return pos; +} +/* END ANSI */ + +#elif defined(ASM) +/* + * Bit scan reverse. Assumptions: a != 0. + */ +static inline int +mpd_bsr(mpd_size_t a) +{ + mpd_size_t retval; + + __asm__ ( +#ifdef CONFIG_64 + "bsrq %1, %0\n\t" +#else + "bsr %1, %0\n\t" +#endif + :"=r" (retval) + :"r" (a) + :"cc" + ); + + return (int)retval; +} + +/* + * Bit scan forward. Assumptions: a != 0. + */ +static inline int +mpd_bsf(mpd_size_t a) +{ + mpd_size_t retval; + + __asm__ ( +#ifdef CONFIG_64 + "bsfq %1, %0\n\t" +#else + "bsf %1, %0\n\t" +#endif + :"=r" (retval) + :"r" (a) + :"cc" + ); + + return (int)retval; +} +/* END ASM */ + +#elif defined(MASM) +#include +/* + * Bit scan reverse. Assumptions: a != 0. + */ +static inline int __cdecl +mpd_bsr(mpd_size_t a) +{ + unsigned long retval; + +#ifdef CONFIG_64 + _BitScanReverse64(&retval, a); +#else + _BitScanReverse(&retval, a); +#endif + + return (int)retval; +} + +/* + * Bit scan forward. Assumptions: a != 0. + */ +static inline int __cdecl +mpd_bsf(mpd_size_t a) +{ + unsigned long retval; + +#ifdef CONFIG_64 + _BitScanForward64(&retval, a); +#else + _BitScanForward(&retval, a); +#endif + + return (int)retval; +} +/* END MASM (_MSC_VER) */ +#else + #error "missing preprocessor definitions" +#endif /* BSR/BSF */ + + #endif /* LIBMPDEC_BITS_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.c index 4c4de622bc6..3f6ca647055 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.c @@ -1,129 +1,129 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" -#include "constants.h" - - -#if defined(CONFIG_64) - - /* number-theory.c */ - const mpd_uint_t mpd_moduli[3] = { - 18446744069414584321ULL, 18446744056529682433ULL, 18446742974197923841ULL - }; - const mpd_uint_t mpd_roots[3] = {7ULL, 10ULL, 19ULL}; - - /* crt.c */ - const mpd_uint_t INV_P1_MOD_P2 = 18446744055098026669ULL; - const mpd_uint_t INV_P1P2_MOD_P3 = 287064143708160ULL; - const mpd_uint_t LH_P1P2 = 18446744052234715137ULL; /* (P1*P2) % 2^64 */ - const mpd_uint_t UH_P1P2 = 18446744052234715141ULL; /* (P1*P2) / 2^64 */ - - /* transpose.c */ - const mpd_size_t mpd_bits[64] = { - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, - 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, - 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, - 2147483648ULL, 4294967296ULL, 8589934592ULL, 17179869184ULL, 34359738368ULL, - 68719476736ULL, 137438953472ULL, 274877906944ULL, 549755813888ULL, - 1099511627776ULL, 2199023255552ULL, 4398046511104, 8796093022208ULL, - 17592186044416ULL, 35184372088832ULL, 70368744177664ULL, 140737488355328ULL, - 281474976710656ULL, 562949953421312ULL, 1125899906842624ULL, - 2251799813685248ULL, 4503599627370496ULL, 9007199254740992ULL, - 18014398509481984ULL, 36028797018963968ULL, 72057594037927936ULL, - 144115188075855872ULL, 288230376151711744ULL, 576460752303423488ULL, - 1152921504606846976ULL, 2305843009213693952ULL, 4611686018427387904ULL, - 9223372036854775808ULL - }; - - /* mpdecimal.c */ - const mpd_uint_t mpd_pow10[MPD_RDIGITS+1] = { - 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000, - 10000000000ULL,100000000000ULL,1000000000000ULL,10000000000000ULL, - 100000000000000ULL,1000000000000000ULL,10000000000000000ULL, - 100000000000000000ULL,1000000000000000000ULL,10000000000000000000ULL - }; - - /* magic number for constant division by MPD_RADIX */ - const mpd_uint_t mprime_rdx = 15581492618384294730ULL; - -#elif defined(CONFIG_32) - - /* number-theory.c */ - const mpd_uint_t mpd_moduli[3] = {2113929217UL, 2013265921UL, 1811939329UL}; - const mpd_uint_t mpd_roots[3] = {5UL, 31UL, 13UL}; - - /* PentiumPro modular multiplication: These constants have to be loaded as - * 80 bit long doubles, which are not supported by certain compilers. */ - const uint32_t mpd_invmoduli[3][3] = { - {4293885170U, 2181570688U, 16352U}, /* ((long double) 1 / 2113929217UL) */ - {1698898177U, 2290649223U, 16352U}, /* ((long double) 1 / 2013265921UL) */ - {2716021846U, 2545165803U, 16352U} /* ((long double) 1 / 1811939329UL) */ - }; - - const float MPD_TWO63 = 9223372036854775808.0; /* 2^63 */ - - /* crt.c */ - const mpd_uint_t INV_P1_MOD_P2 = 2013265901UL; - const mpd_uint_t INV_P1P2_MOD_P3 = 54UL; - const mpd_uint_t LH_P1P2 = 4127195137UL; /* (P1*P2) % 2^32 */ - const mpd_uint_t UH_P1P2 = 990904320UL; /* (P1*P2) / 2^32 */ - - /* transpose.c */ - const mpd_size_t mpd_bits[32] = { - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, - 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, - 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, - 2147483648UL - }; - - /* mpdecimal.c */ - const mpd_uint_t mpd_pow10[MPD_RDIGITS+1] = { - 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 - }; - -#else - #error "CONFIG_64 or CONFIG_32 must be defined." -#endif - -const char *mpd_round_string[MPD_ROUND_GUARD] = { - "ROUND_UP", /* round away from 0 */ - "ROUND_DOWN", /* round toward 0 (truncate) */ - "ROUND_CEILING", /* round toward +infinity */ - "ROUND_FLOOR", /* round toward -infinity */ - "ROUND_HALF_UP", /* 0.5 is rounded up */ - "ROUND_HALF_DOWN", /* 0.5 is rounded down */ - "ROUND_HALF_EVEN", /* 0.5 is rounded to even */ - "ROUND_05UP", /* round zero or five away from 0 */ - "ROUND_TRUNC", /* truncate, but set infinity */ -}; - -const char *mpd_clamp_string[MPD_CLAMP_GUARD] = { - "CLAMP_DEFAULT", - "CLAMP_IEEE_754" -}; + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" +#include "constants.h" + + +#if defined(CONFIG_64) + + /* number-theory.c */ + const mpd_uint_t mpd_moduli[3] = { + 18446744069414584321ULL, 18446744056529682433ULL, 18446742974197923841ULL + }; + const mpd_uint_t mpd_roots[3] = {7ULL, 10ULL, 19ULL}; + + /* crt.c */ + const mpd_uint_t INV_P1_MOD_P2 = 18446744055098026669ULL; + const mpd_uint_t INV_P1P2_MOD_P3 = 287064143708160ULL; + const mpd_uint_t LH_P1P2 = 18446744052234715137ULL; /* (P1*P2) % 2^64 */ + const mpd_uint_t UH_P1P2 = 18446744052234715141ULL; /* (P1*P2) / 2^64 */ + + /* transpose.c */ + const mpd_size_t mpd_bits[64] = { + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, + 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, + 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, + 2147483648ULL, 4294967296ULL, 8589934592ULL, 17179869184ULL, 34359738368ULL, + 68719476736ULL, 137438953472ULL, 274877906944ULL, 549755813888ULL, + 1099511627776ULL, 2199023255552ULL, 4398046511104, 8796093022208ULL, + 17592186044416ULL, 35184372088832ULL, 70368744177664ULL, 140737488355328ULL, + 281474976710656ULL, 562949953421312ULL, 1125899906842624ULL, + 2251799813685248ULL, 4503599627370496ULL, 9007199254740992ULL, + 18014398509481984ULL, 36028797018963968ULL, 72057594037927936ULL, + 144115188075855872ULL, 288230376151711744ULL, 576460752303423488ULL, + 1152921504606846976ULL, 2305843009213693952ULL, 4611686018427387904ULL, + 9223372036854775808ULL + }; + + /* mpdecimal.c */ + const mpd_uint_t mpd_pow10[MPD_RDIGITS+1] = { + 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000, + 10000000000ULL,100000000000ULL,1000000000000ULL,10000000000000ULL, + 100000000000000ULL,1000000000000000ULL,10000000000000000ULL, + 100000000000000000ULL,1000000000000000000ULL,10000000000000000000ULL + }; + + /* magic number for constant division by MPD_RADIX */ + const mpd_uint_t mprime_rdx = 15581492618384294730ULL; + +#elif defined(CONFIG_32) + + /* number-theory.c */ + const mpd_uint_t mpd_moduli[3] = {2113929217UL, 2013265921UL, 1811939329UL}; + const mpd_uint_t mpd_roots[3] = {5UL, 31UL, 13UL}; + + /* PentiumPro modular multiplication: These constants have to be loaded as + * 80 bit long doubles, which are not supported by certain compilers. */ + const uint32_t mpd_invmoduli[3][3] = { + {4293885170U, 2181570688U, 16352U}, /* ((long double) 1 / 2113929217UL) */ + {1698898177U, 2290649223U, 16352U}, /* ((long double) 1 / 2013265921UL) */ + {2716021846U, 2545165803U, 16352U} /* ((long double) 1 / 1811939329UL) */ + }; + + const float MPD_TWO63 = 9223372036854775808.0; /* 2^63 */ + + /* crt.c */ + const mpd_uint_t INV_P1_MOD_P2 = 2013265901UL; + const mpd_uint_t INV_P1P2_MOD_P3 = 54UL; + const mpd_uint_t LH_P1P2 = 4127195137UL; /* (P1*P2) % 2^32 */ + const mpd_uint_t UH_P1P2 = 990904320UL; /* (P1*P2) / 2^32 */ + + /* transpose.c */ + const mpd_size_t mpd_bits[32] = { + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, + 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, + 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, + 2147483648UL + }; + + /* mpdecimal.c */ + const mpd_uint_t mpd_pow10[MPD_RDIGITS+1] = { + 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 + }; + +#else + #error "CONFIG_64 or CONFIG_32 must be defined." +#endif + +const char *mpd_round_string[MPD_ROUND_GUARD] = { + "ROUND_UP", /* round away from 0 */ + "ROUND_DOWN", /* round toward 0 (truncate) */ + "ROUND_CEILING", /* round toward +infinity */ + "ROUND_FLOOR", /* round toward -infinity */ + "ROUND_HALF_UP", /* 0.5 is rounded up */ + "ROUND_HALF_DOWN", /* 0.5 is rounded down */ + "ROUND_HALF_EVEN", /* 0.5 is rounded to even */ + "ROUND_05UP", /* round zero or five away from 0 */ + "ROUND_TRUNC", /* truncate, but set infinity */ +}; + +const char *mpd_clamp_string[MPD_CLAMP_GUARD] = { + "CLAMP_DEFAULT", + "CLAMP_IEEE_754" +}; diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.h index 7c1db839c20..889d899b7a8 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/constants.h @@ -1,89 +1,89 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_CONSTANTS_H_ #define LIBMPDEC_CONSTANTS_H_ - - -#include "mpdecimal.h" - + + +#include "mpdecimal.h" + #include - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -/* choice of optimized functions */ -#if defined(CONFIG_64) -/* x64 */ - #define MULMOD(a, b) x64_mulmod(a, b, umod) - #define MULMOD2C(a0, a1, w) x64_mulmod2c(a0, a1, w, umod) - #define MULMOD2(a0, b0, a1, b1) x64_mulmod2(a0, b0, a1, b1, umod) - #define POWMOD(base, exp) x64_powmod(base, exp, umod) - #define SETMODULUS(modnum) std_setmodulus(modnum, &umod) - #define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod) -#elif defined(PPRO) -/* PentiumPro (or later) gcc inline asm */ - #define MULMOD(a, b) ppro_mulmod(a, b, &dmod, dinvmod) - #define MULMOD2C(a0, a1, w) ppro_mulmod2c(a0, a1, w, &dmod, dinvmod) - #define MULMOD2(a0, b0, a1, b1) ppro_mulmod2(a0, b0, a1, b1, &dmod, dinvmod) - #define POWMOD(base, exp) ppro_powmod(base, exp, &dmod, dinvmod) - #define SETMODULUS(modnum) ppro_setmodulus(modnum, &umod, &dmod, dinvmod) - #define SIZE3_NTT(x0, x1, x2, w3table) ppro_size3_ntt(x0, x1, x2, w3table, umod, &dmod, dinvmod) -#else - /* ANSI C99 */ - #define MULMOD(a, b) std_mulmod(a, b, umod) - #define MULMOD2C(a0, a1, w) std_mulmod2c(a0, a1, w, umod) - #define MULMOD2(a0, b0, a1, b1) std_mulmod2(a0, b0, a1, b1, umod) - #define POWMOD(base, exp) std_powmod(base, exp, umod) - #define SETMODULUS(modnum) std_setmodulus(modnum, &umod) - #define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod) -#endif - -/* PentiumPro (or later) gcc inline asm */ -extern const float MPD_TWO63; -extern const uint32_t mpd_invmoduli[3][3]; - -enum {P1, P2, P3}; - -extern const mpd_uint_t mpd_moduli[]; -extern const mpd_uint_t mpd_roots[]; -extern const mpd_size_t mpd_bits[]; -extern const mpd_uint_t mpd_pow10[]; - -extern const mpd_uint_t INV_P1_MOD_P2; -extern const mpd_uint_t INV_P1P2_MOD_P3; -extern const mpd_uint_t LH_P1P2; -extern const mpd_uint_t UH_P1P2; - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +/* choice of optimized functions */ +#if defined(CONFIG_64) +/* x64 */ + #define MULMOD(a, b) x64_mulmod(a, b, umod) + #define MULMOD2C(a0, a1, w) x64_mulmod2c(a0, a1, w, umod) + #define MULMOD2(a0, b0, a1, b1) x64_mulmod2(a0, b0, a1, b1, umod) + #define POWMOD(base, exp) x64_powmod(base, exp, umod) + #define SETMODULUS(modnum) std_setmodulus(modnum, &umod) + #define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod) +#elif defined(PPRO) +/* PentiumPro (or later) gcc inline asm */ + #define MULMOD(a, b) ppro_mulmod(a, b, &dmod, dinvmod) + #define MULMOD2C(a0, a1, w) ppro_mulmod2c(a0, a1, w, &dmod, dinvmod) + #define MULMOD2(a0, b0, a1, b1) ppro_mulmod2(a0, b0, a1, b1, &dmod, dinvmod) + #define POWMOD(base, exp) ppro_powmod(base, exp, &dmod, dinvmod) + #define SETMODULUS(modnum) ppro_setmodulus(modnum, &umod, &dmod, dinvmod) + #define SIZE3_NTT(x0, x1, x2, w3table) ppro_size3_ntt(x0, x1, x2, w3table, umod, &dmod, dinvmod) +#else + /* ANSI C99 */ + #define MULMOD(a, b) std_mulmod(a, b, umod) + #define MULMOD2C(a0, a1, w) std_mulmod2c(a0, a1, w, umod) + #define MULMOD2(a0, b0, a1, b1) std_mulmod2(a0, b0, a1, b1, umod) + #define POWMOD(base, exp) std_powmod(base, exp, umod) + #define SETMODULUS(modnum) std_setmodulus(modnum, &umod) + #define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod) +#endif + +/* PentiumPro (or later) gcc inline asm */ +extern const float MPD_TWO63; +extern const uint32_t mpd_invmoduli[3][3]; + +enum {P1, P2, P3}; + +extern const mpd_uint_t mpd_moduli[]; +extern const mpd_uint_t mpd_roots[]; +extern const mpd_size_t mpd_bits[]; +extern const mpd_uint_t mpd_pow10[]; + +extern const mpd_uint_t INV_P1_MOD_P2; +extern const mpd_uint_t INV_P1P2_MOD_P3; +extern const mpd_uint_t LH_P1P2; +extern const mpd_uint_t UH_P1P2; + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_CONSTANTS_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/context.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/context.c index 9cbc2050959..c711e0918f9 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/context.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/context.c @@ -1,286 +1,286 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" #include -#include -#include - - -void +#include +#include + + +void mpd_dflt_traphandler(mpd_context_t *ctx) -{ +{ (void)ctx; - raise(SIGFPE); -} - -void (* mpd_traphandler)(mpd_context_t *) = mpd_dflt_traphandler; - - -/* Set guaranteed minimum number of coefficient words. The function may - be used once at program start. Setting MPD_MINALLOC to out-of-bounds - values is a catastrophic error, so in that case the function exits rather - than relying on the user to check a return value. */ -void -mpd_setminalloc(mpd_ssize_t n) -{ - static int minalloc_is_set = 0; - - if (minalloc_is_set) { - mpd_err_warn("mpd_setminalloc: ignoring request to set " - "MPD_MINALLOC a second time\n"); - return; - } - if (n < MPD_MINALLOC_MIN || n > MPD_MINALLOC_MAX) { - mpd_err_fatal("illegal value for MPD_MINALLOC"); /* GCOV_NOT_REACHED */ - } - MPD_MINALLOC = n; - minalloc_is_set = 1; -} - -void -mpd_init(mpd_context_t *ctx, mpd_ssize_t prec) -{ - mpd_ssize_t ideal_minalloc; - - mpd_defaultcontext(ctx); - - if (!mpd_qsetprec(ctx, prec)) { - mpd_addstatus_raise(ctx, MPD_Invalid_context); - return; - } - - ideal_minalloc = 2 * ((prec+MPD_RDIGITS-1) / MPD_RDIGITS); - if (ideal_minalloc < MPD_MINALLOC_MIN) ideal_minalloc = MPD_MINALLOC_MIN; - if (ideal_minalloc > MPD_MINALLOC_MAX) ideal_minalloc = MPD_MINALLOC_MAX; - - mpd_setminalloc(ideal_minalloc); -} - -void -mpd_maxcontext(mpd_context_t *ctx) -{ - ctx->prec=MPD_MAX_PREC; - ctx->emax=MPD_MAX_EMAX; - ctx->emin=MPD_MIN_EMIN; - ctx->round=MPD_ROUND_HALF_EVEN; - ctx->traps=MPD_Traps; - ctx->status=0; - ctx->newtrap=0; - ctx->clamp=0; - ctx->allcr=1; -} - -void -mpd_defaultcontext(mpd_context_t *ctx) -{ - ctx->prec=2*MPD_RDIGITS; - ctx->emax=MPD_MAX_EMAX; - ctx->emin=MPD_MIN_EMIN; - ctx->round=MPD_ROUND_HALF_UP; - ctx->traps=MPD_Traps; - ctx->status=0; - ctx->newtrap=0; - ctx->clamp=0; - ctx->allcr=1; -} - -void -mpd_basiccontext(mpd_context_t *ctx) -{ - ctx->prec=9; - ctx->emax=MPD_MAX_EMAX; - ctx->emin=MPD_MIN_EMIN; - ctx->round=MPD_ROUND_HALF_UP; - ctx->traps=MPD_Traps|MPD_Clamped; - ctx->status=0; - ctx->newtrap=0; - ctx->clamp=0; - ctx->allcr=1; -} - -int -mpd_ieee_context(mpd_context_t *ctx, int bits) -{ - if (bits <= 0 || bits > MPD_IEEE_CONTEXT_MAX_BITS || bits % 32) { - return -1; - } - - ctx->prec = 9 * (bits/32) - 2; - ctx->emax = 3 * ((mpd_ssize_t)1<<(bits/16+3)); - ctx->emin = 1 - ctx->emax; - ctx->round=MPD_ROUND_HALF_EVEN; - ctx->traps=0; - ctx->status=0; - ctx->newtrap=0; - ctx->clamp=1; - ctx->allcr=1; - - return 0; -} - -mpd_ssize_t -mpd_getprec(const mpd_context_t *ctx) -{ - return ctx->prec; -} - -mpd_ssize_t -mpd_getemax(const mpd_context_t *ctx) -{ - return ctx->emax; -} - -mpd_ssize_t -mpd_getemin(const mpd_context_t *ctx) -{ - return ctx->emin; -} - -int -mpd_getround(const mpd_context_t *ctx) -{ - return ctx->round; -} - -uint32_t -mpd_gettraps(const mpd_context_t *ctx) -{ - return ctx->traps; -} - -uint32_t -mpd_getstatus(const mpd_context_t *ctx) -{ - return ctx->status; -} - -int -mpd_getclamp(const mpd_context_t *ctx) -{ - return ctx->clamp; -} - -int -mpd_getcr(const mpd_context_t *ctx) -{ - return ctx->allcr; -} - - -int -mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec) -{ - if (prec <= 0 || prec > MPD_MAX_PREC) { - return 0; - } - ctx->prec = prec; - return 1; -} - -int -mpd_qsetemax(mpd_context_t *ctx, mpd_ssize_t emax) -{ - if (emax < 0 || emax > MPD_MAX_EMAX) { - return 0; - } - ctx->emax = emax; - return 1; -} - -int -mpd_qsetemin(mpd_context_t *ctx, mpd_ssize_t emin) -{ - if (emin > 0 || emin < MPD_MIN_EMIN) { - return 0; - } - ctx->emin = emin; - return 1; -} - -int -mpd_qsetround(mpd_context_t *ctx, int round) -{ - if (!(0 <= round && round < MPD_ROUND_GUARD)) { - return 0; - } - ctx->round = round; - return 1; -} - -int -mpd_qsettraps(mpd_context_t *ctx, uint32_t traps) -{ - if (traps > MPD_Max_status) { - return 0; - } - ctx->traps = traps; - return 1; -} - -int -mpd_qsetstatus(mpd_context_t *ctx, uint32_t flags) -{ - if (flags > MPD_Max_status) { - return 0; - } - ctx->status = flags; - return 1; -} - -int -mpd_qsetclamp(mpd_context_t *ctx, int c) -{ - if (c != 0 && c != 1) { - return 0; - } - ctx->clamp = c; - return 1; -} - -int -mpd_qsetcr(mpd_context_t *ctx, int c) -{ - if (c != 0 && c != 1) { - return 0; - } - ctx->allcr = c; - return 1; -} - - -void -mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags) -{ - ctx->status |= flags; - if (flags&ctx->traps) { - ctx->newtrap = (flags&ctx->traps); - mpd_traphandler(ctx); - } -} + raise(SIGFPE); +} + +void (* mpd_traphandler)(mpd_context_t *) = mpd_dflt_traphandler; + + +/* Set guaranteed minimum number of coefficient words. The function may + be used once at program start. Setting MPD_MINALLOC to out-of-bounds + values is a catastrophic error, so in that case the function exits rather + than relying on the user to check a return value. */ +void +mpd_setminalloc(mpd_ssize_t n) +{ + static int minalloc_is_set = 0; + + if (minalloc_is_set) { + mpd_err_warn("mpd_setminalloc: ignoring request to set " + "MPD_MINALLOC a second time\n"); + return; + } + if (n < MPD_MINALLOC_MIN || n > MPD_MINALLOC_MAX) { + mpd_err_fatal("illegal value for MPD_MINALLOC"); /* GCOV_NOT_REACHED */ + } + MPD_MINALLOC = n; + minalloc_is_set = 1; +} + +void +mpd_init(mpd_context_t *ctx, mpd_ssize_t prec) +{ + mpd_ssize_t ideal_minalloc; + + mpd_defaultcontext(ctx); + + if (!mpd_qsetprec(ctx, prec)) { + mpd_addstatus_raise(ctx, MPD_Invalid_context); + return; + } + + ideal_minalloc = 2 * ((prec+MPD_RDIGITS-1) / MPD_RDIGITS); + if (ideal_minalloc < MPD_MINALLOC_MIN) ideal_minalloc = MPD_MINALLOC_MIN; + if (ideal_minalloc > MPD_MINALLOC_MAX) ideal_minalloc = MPD_MINALLOC_MAX; + + mpd_setminalloc(ideal_minalloc); +} + +void +mpd_maxcontext(mpd_context_t *ctx) +{ + ctx->prec=MPD_MAX_PREC; + ctx->emax=MPD_MAX_EMAX; + ctx->emin=MPD_MIN_EMIN; + ctx->round=MPD_ROUND_HALF_EVEN; + ctx->traps=MPD_Traps; + ctx->status=0; + ctx->newtrap=0; + ctx->clamp=0; + ctx->allcr=1; +} + +void +mpd_defaultcontext(mpd_context_t *ctx) +{ + ctx->prec=2*MPD_RDIGITS; + ctx->emax=MPD_MAX_EMAX; + ctx->emin=MPD_MIN_EMIN; + ctx->round=MPD_ROUND_HALF_UP; + ctx->traps=MPD_Traps; + ctx->status=0; + ctx->newtrap=0; + ctx->clamp=0; + ctx->allcr=1; +} + +void +mpd_basiccontext(mpd_context_t *ctx) +{ + ctx->prec=9; + ctx->emax=MPD_MAX_EMAX; + ctx->emin=MPD_MIN_EMIN; + ctx->round=MPD_ROUND_HALF_UP; + ctx->traps=MPD_Traps|MPD_Clamped; + ctx->status=0; + ctx->newtrap=0; + ctx->clamp=0; + ctx->allcr=1; +} + +int +mpd_ieee_context(mpd_context_t *ctx, int bits) +{ + if (bits <= 0 || bits > MPD_IEEE_CONTEXT_MAX_BITS || bits % 32) { + return -1; + } + + ctx->prec = 9 * (bits/32) - 2; + ctx->emax = 3 * ((mpd_ssize_t)1<<(bits/16+3)); + ctx->emin = 1 - ctx->emax; + ctx->round=MPD_ROUND_HALF_EVEN; + ctx->traps=0; + ctx->status=0; + ctx->newtrap=0; + ctx->clamp=1; + ctx->allcr=1; + + return 0; +} + +mpd_ssize_t +mpd_getprec(const mpd_context_t *ctx) +{ + return ctx->prec; +} + +mpd_ssize_t +mpd_getemax(const mpd_context_t *ctx) +{ + return ctx->emax; +} + +mpd_ssize_t +mpd_getemin(const mpd_context_t *ctx) +{ + return ctx->emin; +} + +int +mpd_getround(const mpd_context_t *ctx) +{ + return ctx->round; +} + +uint32_t +mpd_gettraps(const mpd_context_t *ctx) +{ + return ctx->traps; +} + +uint32_t +mpd_getstatus(const mpd_context_t *ctx) +{ + return ctx->status; +} + +int +mpd_getclamp(const mpd_context_t *ctx) +{ + return ctx->clamp; +} + +int +mpd_getcr(const mpd_context_t *ctx) +{ + return ctx->allcr; +} + + +int +mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec) +{ + if (prec <= 0 || prec > MPD_MAX_PREC) { + return 0; + } + ctx->prec = prec; + return 1; +} + +int +mpd_qsetemax(mpd_context_t *ctx, mpd_ssize_t emax) +{ + if (emax < 0 || emax > MPD_MAX_EMAX) { + return 0; + } + ctx->emax = emax; + return 1; +} + +int +mpd_qsetemin(mpd_context_t *ctx, mpd_ssize_t emin) +{ + if (emin > 0 || emin < MPD_MIN_EMIN) { + return 0; + } + ctx->emin = emin; + return 1; +} + +int +mpd_qsetround(mpd_context_t *ctx, int round) +{ + if (!(0 <= round && round < MPD_ROUND_GUARD)) { + return 0; + } + ctx->round = round; + return 1; +} + +int +mpd_qsettraps(mpd_context_t *ctx, uint32_t traps) +{ + if (traps > MPD_Max_status) { + return 0; + } + ctx->traps = traps; + return 1; +} + +int +mpd_qsetstatus(mpd_context_t *ctx, uint32_t flags) +{ + if (flags > MPD_Max_status) { + return 0; + } + ctx->status = flags; + return 1; +} + +int +mpd_qsetclamp(mpd_context_t *ctx, int c) +{ + if (c != 0 && c != 1) { + return 0; + } + ctx->clamp = c; + return 1; +} + +int +mpd_qsetcr(mpd_context_t *ctx, int c) +{ + if (c != 0 && c != 1) { + return 0; + } + ctx->allcr = c; + return 1; +} + + +void +mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags) +{ + ctx->status |= flags; + if (flags&ctx->traps) { + ctx->newtrap = (flags&ctx->traps); + mpd_traphandler(ctx); + } +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/convolute.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/convolute.c index 4bc8e8b5fd3..4323d3c6e1c 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/convolute.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/convolute.c @@ -1,171 +1,171 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" -#include "bits.h" -#include "constants.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" +#include "bits.h" +#include "constants.h" #include "convolute.h" -#include "fnt.h" -#include "fourstep.h" -#include "numbertheory.h" -#include "sixstep.h" -#include "umodarith.h" - - -/* Bignum: Fast convolution using the Number Theoretic Transform. Used for - the multiplication of very large coefficients. */ - - -/* Convolute the data in c1 and c2. Result is in c1. */ -int -fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum) -{ - int (*fnt)(mpd_uint_t *, mpd_size_t, int); - int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int); -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_uint_t n_inv, umod; - mpd_size_t i; - - - SETMODULUS(modnum); - n_inv = POWMOD(n, (umod-2)); - - if (ispower2(n)) { - if (n > SIX_STEP_THRESHOLD) { - fnt = six_step_fnt; - inv_fnt = inv_six_step_fnt; - } - else { - fnt = std_fnt; - inv_fnt = std_inv_fnt; - } - } - else { - fnt = four_step_fnt; - inv_fnt = inv_four_step_fnt; - } - - if (!fnt(c1, n, modnum)) { - return 0; - } - if (!fnt(c2, n, modnum)) { - return 0; - } - for (i = 0; i < n-1; i += 2) { - mpd_uint_t x0 = c1[i]; - mpd_uint_t y0 = c2[i]; - mpd_uint_t x1 = c1[i+1]; - mpd_uint_t y1 = c2[i+1]; - MULMOD2(&x0, y0, &x1, y1); - c1[i] = x0; - c1[i+1] = x1; - } - - if (!inv_fnt(c1, n, modnum)) { - return 0; - } - for (i = 0; i < n-3; i += 4) { - mpd_uint_t x0 = c1[i]; - mpd_uint_t x1 = c1[i+1]; - mpd_uint_t x2 = c1[i+2]; - mpd_uint_t x3 = c1[i+3]; - MULMOD2C(&x0, &x1, n_inv); - MULMOD2C(&x2, &x3, n_inv); - c1[i] = x0; - c1[i+1] = x1; - c1[i+2] = x2; - c1[i+3] = x3; - } - - return 1; -} - -/* Autoconvolute the data in c1. Result is in c1. */ -int -fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum) -{ - int (*fnt)(mpd_uint_t *, mpd_size_t, int); - int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int); -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_uint_t n_inv, umod; - mpd_size_t i; - - - SETMODULUS(modnum); - n_inv = POWMOD(n, (umod-2)); - - if (ispower2(n)) { - if (n > SIX_STEP_THRESHOLD) { - fnt = six_step_fnt; - inv_fnt = inv_six_step_fnt; - } - else { - fnt = std_fnt; - inv_fnt = std_inv_fnt; - } - } - else { - fnt = four_step_fnt; - inv_fnt = inv_four_step_fnt; - } - - if (!fnt(c1, n, modnum)) { - return 0; - } - for (i = 0; i < n-1; i += 2) { - mpd_uint_t x0 = c1[i]; - mpd_uint_t x1 = c1[i+1]; - MULMOD2(&x0, x0, &x1, x1); - c1[i] = x0; - c1[i+1] = x1; - } - - if (!inv_fnt(c1, n, modnum)) { - return 0; - } - for (i = 0; i < n-3; i += 4) { - mpd_uint_t x0 = c1[i]; - mpd_uint_t x1 = c1[i+1]; - mpd_uint_t x2 = c1[i+2]; - mpd_uint_t x3 = c1[i+3]; - MULMOD2C(&x0, &x1, n_inv); - MULMOD2C(&x2, &x3, n_inv); - c1[i] = x0; - c1[i+1] = x1; - c1[i+2] = x2; - c1[i+3] = x3; - } - - return 1; -} +#include "fnt.h" +#include "fourstep.h" +#include "numbertheory.h" +#include "sixstep.h" +#include "umodarith.h" + + +/* Bignum: Fast convolution using the Number Theoretic Transform. Used for + the multiplication of very large coefficients. */ + + +/* Convolute the data in c1 and c2. Result is in c1. */ +int +fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum) +{ + int (*fnt)(mpd_uint_t *, mpd_size_t, int); + int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int); +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_uint_t n_inv, umod; + mpd_size_t i; + + + SETMODULUS(modnum); + n_inv = POWMOD(n, (umod-2)); + + if (ispower2(n)) { + if (n > SIX_STEP_THRESHOLD) { + fnt = six_step_fnt; + inv_fnt = inv_six_step_fnt; + } + else { + fnt = std_fnt; + inv_fnt = std_inv_fnt; + } + } + else { + fnt = four_step_fnt; + inv_fnt = inv_four_step_fnt; + } + + if (!fnt(c1, n, modnum)) { + return 0; + } + if (!fnt(c2, n, modnum)) { + return 0; + } + for (i = 0; i < n-1; i += 2) { + mpd_uint_t x0 = c1[i]; + mpd_uint_t y0 = c2[i]; + mpd_uint_t x1 = c1[i+1]; + mpd_uint_t y1 = c2[i+1]; + MULMOD2(&x0, y0, &x1, y1); + c1[i] = x0; + c1[i+1] = x1; + } + + if (!inv_fnt(c1, n, modnum)) { + return 0; + } + for (i = 0; i < n-3; i += 4) { + mpd_uint_t x0 = c1[i]; + mpd_uint_t x1 = c1[i+1]; + mpd_uint_t x2 = c1[i+2]; + mpd_uint_t x3 = c1[i+3]; + MULMOD2C(&x0, &x1, n_inv); + MULMOD2C(&x2, &x3, n_inv); + c1[i] = x0; + c1[i+1] = x1; + c1[i+2] = x2; + c1[i+3] = x3; + } + + return 1; +} + +/* Autoconvolute the data in c1. Result is in c1. */ +int +fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum) +{ + int (*fnt)(mpd_uint_t *, mpd_size_t, int); + int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int); +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_uint_t n_inv, umod; + mpd_size_t i; + + + SETMODULUS(modnum); + n_inv = POWMOD(n, (umod-2)); + + if (ispower2(n)) { + if (n > SIX_STEP_THRESHOLD) { + fnt = six_step_fnt; + inv_fnt = inv_six_step_fnt; + } + else { + fnt = std_fnt; + inv_fnt = std_inv_fnt; + } + } + else { + fnt = four_step_fnt; + inv_fnt = inv_four_step_fnt; + } + + if (!fnt(c1, n, modnum)) { + return 0; + } + for (i = 0; i < n-1; i += 2) { + mpd_uint_t x0 = c1[i]; + mpd_uint_t x1 = c1[i+1]; + MULMOD2(&x0, x0, &x1, x1); + c1[i] = x0; + c1[i+1] = x1; + } + + if (!inv_fnt(c1, n, modnum)) { + return 0; + } + for (i = 0; i < n-3; i += 4) { + mpd_uint_t x0 = c1[i]; + mpd_uint_t x1 = c1[i+1]; + mpd_uint_t x2 = c1[i+2]; + mpd_uint_t x3 = c1[i+3]; + MULMOD2C(&x0, &x1, n_inv); + MULMOD2C(&x2, &x3, n_inv); + c1[i] = x0; + c1[i+1] = x1; + c1[i+2] = x2; + c1[i+3] = x3; + } + + return 1; +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/convolute.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/convolute.h index 62edb3e4573..85b6eb67785 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/convolute.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/convolute.h @@ -1,49 +1,49 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_CONVOLUTE_H_ #define LIBMPDEC_CONVOLUTE_H_ - - -#include "mpdecimal.h" - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -#define SIX_STEP_THRESHOLD 4096 - -int fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum); -int fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum); - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - + + +#include "mpdecimal.h" + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +#define SIX_STEP_THRESHOLD 4096 + +int fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum); +int fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum); + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_CONVOLUTE_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.c index 613274ee0c5..0a89d311123 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.c @@ -1,180 +1,180 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" - -#include + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" + +#include #include "constants.h" #include "crt.h" -#include "numbertheory.h" -#include "umodarith.h" +#include "numbertheory.h" +#include "umodarith.h" #include "typearith.h" - - -/* Bignum: Chinese Remainder Theorem, extends the maximum transform length. */ - - -/* Multiply P1P2 by v, store result in w. */ -static inline void -_crt_mulP1P2_3(mpd_uint_t w[3], mpd_uint_t v) -{ - mpd_uint_t hi1, hi2, lo; - - _mpd_mul_words(&hi1, &lo, LH_P1P2, v); - w[0] = lo; - - _mpd_mul_words(&hi2, &lo, UH_P1P2, v); - lo = hi1 + lo; - if (lo < hi1) hi2++; - - w[1] = lo; - w[2] = hi2; -} - -/* Add 3 words from v to w. The result is known to fit in w. */ -static inline void -_crt_add3(mpd_uint_t w[3], mpd_uint_t v[3]) -{ - mpd_uint_t carry; - mpd_uint_t s; - - s = w[0] + v[0]; - carry = (s < w[0]); - w[0] = s; - - s = w[1] + (v[1] + carry); - carry = (s < w[1]); - w[1] = s; - - w[2] = w[2] + (v[2] + carry); -} - -/* Divide 3 words in u by v, store result in w, return remainder. */ -static inline mpd_uint_t -_crt_div3(mpd_uint_t *w, const mpd_uint_t *u, mpd_uint_t v) -{ - mpd_uint_t r1 = u[2]; - mpd_uint_t r2; - - if (r1 < v) { - w[2] = 0; - } - else { - _mpd_div_word(&w[2], &r1, u[2], v); /* GCOV_NOT_REACHED */ - } - - _mpd_div_words(&w[1], &r2, r1, u[1], v); - _mpd_div_words(&w[0], &r1, r2, u[0], v); - - return r1; -} - - -/* - * Chinese Remainder Theorem: - * Algorithm from Joerg Arndt, "Matters Computational", - * Chapter 37.4.1 [http://www.jjj.de/fxt/] - * - * See also Knuth, TAOCP, Volume 2, 4.3.2, exercise 7. - */ - -/* - * CRT with carry: x1, x2, x3 contain numbers modulo p1, p2, p3. For each - * triple of members of the arrays, find the unique z modulo p1*p2*p3, with - * zmax = p1*p2*p3 - 1. - * - * In each iteration of the loop, split z into result[i] = z % MPD_RADIX - * and carry = z / MPD_RADIX. Let N be the size of carry[] and cmax the - * maximum carry. - * - * Limits for the 32-bit build: - * - * N = 2**96 - * cmax = 7711435591312380274 - * - * Limits for the 64 bit build: - * - * N = 2**192 - * cmax = 627710135393475385904124401220046371710 - * - * The following statements hold for both versions: - * - * 1) cmax + zmax < N, so the addition does not overflow. - * - * 2) (cmax + zmax) / MPD_RADIX == cmax. - * - * 3) If c <= cmax, then c_next = (c + zmax) / MPD_RADIX <= cmax. - */ -void -crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t rsize) -{ - mpd_uint_t p1 = mpd_moduli[P1]; - mpd_uint_t umod; -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_uint_t a1, a2, a3; - mpd_uint_t s; - mpd_uint_t z[3], t[3]; - mpd_uint_t carry[3] = {0,0,0}; - mpd_uint_t hi, lo; - mpd_size_t i; - - for (i = 0; i < rsize; i++) { - - a1 = x1[i]; - a2 = x2[i]; - a3 = x3[i]; - - SETMODULUS(P2); - s = ext_submod(a2, a1, umod); - s = MULMOD(s, INV_P1_MOD_P2); - - _mpd_mul_words(&hi, &lo, s, p1); - lo = lo + a1; - if (lo < a1) hi++; - - SETMODULUS(P3); - s = dw_submod(a3, hi, lo, umod); - s = MULMOD(s, INV_P1P2_MOD_P3); - - z[0] = lo; - z[1] = hi; - z[2] = 0; - - _crt_mulP1P2_3(t, s); - _crt_add3(z, t); - _crt_add3(carry, z); - - x1[i] = _crt_div3(carry, carry, MPD_RADIX); - } - - assert(carry[0] == 0 && carry[1] == 0 && carry[2] == 0); -} + + +/* Bignum: Chinese Remainder Theorem, extends the maximum transform length. */ + + +/* Multiply P1P2 by v, store result in w. */ +static inline void +_crt_mulP1P2_3(mpd_uint_t w[3], mpd_uint_t v) +{ + mpd_uint_t hi1, hi2, lo; + + _mpd_mul_words(&hi1, &lo, LH_P1P2, v); + w[0] = lo; + + _mpd_mul_words(&hi2, &lo, UH_P1P2, v); + lo = hi1 + lo; + if (lo < hi1) hi2++; + + w[1] = lo; + w[2] = hi2; +} + +/* Add 3 words from v to w. The result is known to fit in w. */ +static inline void +_crt_add3(mpd_uint_t w[3], mpd_uint_t v[3]) +{ + mpd_uint_t carry; + mpd_uint_t s; + + s = w[0] + v[0]; + carry = (s < w[0]); + w[0] = s; + + s = w[1] + (v[1] + carry); + carry = (s < w[1]); + w[1] = s; + + w[2] = w[2] + (v[2] + carry); +} + +/* Divide 3 words in u by v, store result in w, return remainder. */ +static inline mpd_uint_t +_crt_div3(mpd_uint_t *w, const mpd_uint_t *u, mpd_uint_t v) +{ + mpd_uint_t r1 = u[2]; + mpd_uint_t r2; + + if (r1 < v) { + w[2] = 0; + } + else { + _mpd_div_word(&w[2], &r1, u[2], v); /* GCOV_NOT_REACHED */ + } + + _mpd_div_words(&w[1], &r2, r1, u[1], v); + _mpd_div_words(&w[0], &r1, r2, u[0], v); + + return r1; +} + + +/* + * Chinese Remainder Theorem: + * Algorithm from Joerg Arndt, "Matters Computational", + * Chapter 37.4.1 [http://www.jjj.de/fxt/] + * + * See also Knuth, TAOCP, Volume 2, 4.3.2, exercise 7. + */ + +/* + * CRT with carry: x1, x2, x3 contain numbers modulo p1, p2, p3. For each + * triple of members of the arrays, find the unique z modulo p1*p2*p3, with + * zmax = p1*p2*p3 - 1. + * + * In each iteration of the loop, split z into result[i] = z % MPD_RADIX + * and carry = z / MPD_RADIX. Let N be the size of carry[] and cmax the + * maximum carry. + * + * Limits for the 32-bit build: + * + * N = 2**96 + * cmax = 7711435591312380274 + * + * Limits for the 64 bit build: + * + * N = 2**192 + * cmax = 627710135393475385904124401220046371710 + * + * The following statements hold for both versions: + * + * 1) cmax + zmax < N, so the addition does not overflow. + * + * 2) (cmax + zmax) / MPD_RADIX == cmax. + * + * 3) If c <= cmax, then c_next = (c + zmax) / MPD_RADIX <= cmax. + */ +void +crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t rsize) +{ + mpd_uint_t p1 = mpd_moduli[P1]; + mpd_uint_t umod; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_uint_t a1, a2, a3; + mpd_uint_t s; + mpd_uint_t z[3], t[3]; + mpd_uint_t carry[3] = {0,0,0}; + mpd_uint_t hi, lo; + mpd_size_t i; + + for (i = 0; i < rsize; i++) { + + a1 = x1[i]; + a2 = x2[i]; + a3 = x3[i]; + + SETMODULUS(P2); + s = ext_submod(a2, a1, umod); + s = MULMOD(s, INV_P1_MOD_P2); + + _mpd_mul_words(&hi, &lo, s, p1); + lo = lo + a1; + if (lo < a1) hi++; + + SETMODULUS(P3); + s = dw_submod(a3, hi, lo, umod); + s = MULMOD(s, INV_P1P2_MOD_P3); + + z[0] = lo; + z[1] = hi; + z[2] = 0; + + _crt_mulP1P2_3(t, s); + _crt_add3(z, t); + _crt_add3(carry, z); + + x1[i] = _crt_div3(carry, carry, MPD_RADIX); + } + + assert(carry[0] == 0 && carry[1] == 0 && carry[2] == 0); +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.h index 15a347d4cb3..0c4880a8a2d 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/crt.h @@ -1,46 +1,46 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_CRT_H_ #define LIBMPDEC_CRT_H_ - - -#include "mpdecimal.h" - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t nmemb); - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - + + +#include "mpdecimal.h" + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t nmemb); + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_CRT_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/difradix2.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/difradix2.c index 049ecff65b6..fb0657493cd 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/difradix2.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/difradix2.c @@ -1,173 +1,173 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" - -#include - -#include "bits.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" + +#include + +#include "bits.h" #include "constants.h" #include "difradix2.h" -#include "numbertheory.h" -#include "umodarith.h" - - -/* Bignum: The actual transform routine (decimation in frequency). */ - - -/* - * Generate index pairs (x, bitreverse(x)) and carry out the permutation. - * n must be a power of two. - * Algorithm due to Brent/Lehmann, see Joerg Arndt, "Matters Computational", - * Chapter 1.14.4. [http://www.jjj.de/fxt/] - */ -static inline void -bitreverse_permute(mpd_uint_t a[], mpd_size_t n) -{ - mpd_size_t x = 0; - mpd_size_t r = 0; - mpd_uint_t t; - - do { /* Invariant: r = bitreverse(x) */ - if (r > x) { - t = a[x]; - a[x] = a[r]; - a[r] = t; - } - /* Flip trailing consecutive 1 bits and the first zero bit - * that absorbs a possible carry. */ - x += 1; - /* Mirror the operation on r: Flip n_trailing_zeros(x)+1 - high bits of r. */ - r ^= (n - (n >> (mpd_bsf(x)+1))); - /* The loop invariant is preserved. */ - } while (x < n); -} - - -/* Fast Number Theoretic Transform, decimation in frequency. */ -void -fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams) -{ - mpd_uint_t *wtable = tparams->wtable; - mpd_uint_t umod; -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_uint_t u0, u1, v0, v1; - mpd_uint_t w, w0, w1, wstep; - mpd_size_t m, mhalf; - mpd_size_t j, r; - - - assert(ispower2(n)); - assert(n >= 4); - - SETMODULUS(tparams->modnum); - - /* m == n */ - mhalf = n / 2; - for (j = 0; j < mhalf; j += 2) { - - w0 = wtable[j]; - w1 = wtable[j+1]; - - u0 = a[j]; - v0 = a[j+mhalf]; - - u1 = a[j+1]; - v1 = a[j+1+mhalf]; - - a[j] = addmod(u0, v0, umod); - v0 = submod(u0, v0, umod); - - a[j+1] = addmod(u1, v1, umod); - v1 = submod(u1, v1, umod); - - MULMOD2(&v0, w0, &v1, w1); - - a[j+mhalf] = v0; - a[j+1+mhalf] = v1; - - } - - wstep = 2; - for (m = n/2; m >= 2; m>>=1, wstep<<=1) { - - mhalf = m / 2; - - /* j == 0 */ - for (r = 0; r < n; r += 2*m) { - - u0 = a[r]; - v0 = a[r+mhalf]; - - u1 = a[m+r]; - v1 = a[m+r+mhalf]; - - a[r] = addmod(u0, v0, umod); - v0 = submod(u0, v0, umod); - - a[m+r] = addmod(u1, v1, umod); - v1 = submod(u1, v1, umod); - - a[r+mhalf] = v0; - a[m+r+mhalf] = v1; - } - - for (j = 1; j < mhalf; j++) { - - w = wtable[j*wstep]; - - for (r = 0; r < n; r += 2*m) { - - u0 = a[r+j]; - v0 = a[r+j+mhalf]; - - u1 = a[m+r+j]; - v1 = a[m+r+j+mhalf]; - - a[r+j] = addmod(u0, v0, umod); - v0 = submod(u0, v0, umod); - - a[m+r+j] = addmod(u1, v1, umod); - v1 = submod(u1, v1, umod); - - MULMOD2C(&v0, &v1, w); - - a[r+j+mhalf] = v0; - a[m+r+j+mhalf] = v1; - } - - } - - } - - bitreverse_permute(a, n); -} +#include "numbertheory.h" +#include "umodarith.h" + + +/* Bignum: The actual transform routine (decimation in frequency). */ + + +/* + * Generate index pairs (x, bitreverse(x)) and carry out the permutation. + * n must be a power of two. + * Algorithm due to Brent/Lehmann, see Joerg Arndt, "Matters Computational", + * Chapter 1.14.4. [http://www.jjj.de/fxt/] + */ +static inline void +bitreverse_permute(mpd_uint_t a[], mpd_size_t n) +{ + mpd_size_t x = 0; + mpd_size_t r = 0; + mpd_uint_t t; + + do { /* Invariant: r = bitreverse(x) */ + if (r > x) { + t = a[x]; + a[x] = a[r]; + a[r] = t; + } + /* Flip trailing consecutive 1 bits and the first zero bit + * that absorbs a possible carry. */ + x += 1; + /* Mirror the operation on r: Flip n_trailing_zeros(x)+1 + high bits of r. */ + r ^= (n - (n >> (mpd_bsf(x)+1))); + /* The loop invariant is preserved. */ + } while (x < n); +} + + +/* Fast Number Theoretic Transform, decimation in frequency. */ +void +fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams) +{ + mpd_uint_t *wtable = tparams->wtable; + mpd_uint_t umod; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_uint_t u0, u1, v0, v1; + mpd_uint_t w, w0, w1, wstep; + mpd_size_t m, mhalf; + mpd_size_t j, r; + + + assert(ispower2(n)); + assert(n >= 4); + + SETMODULUS(tparams->modnum); + + /* m == n */ + mhalf = n / 2; + for (j = 0; j < mhalf; j += 2) { + + w0 = wtable[j]; + w1 = wtable[j+1]; + + u0 = a[j]; + v0 = a[j+mhalf]; + + u1 = a[j+1]; + v1 = a[j+1+mhalf]; + + a[j] = addmod(u0, v0, umod); + v0 = submod(u0, v0, umod); + + a[j+1] = addmod(u1, v1, umod); + v1 = submod(u1, v1, umod); + + MULMOD2(&v0, w0, &v1, w1); + + a[j+mhalf] = v0; + a[j+1+mhalf] = v1; + + } + + wstep = 2; + for (m = n/2; m >= 2; m>>=1, wstep<<=1) { + + mhalf = m / 2; + + /* j == 0 */ + for (r = 0; r < n; r += 2*m) { + + u0 = a[r]; + v0 = a[r+mhalf]; + + u1 = a[m+r]; + v1 = a[m+r+mhalf]; + + a[r] = addmod(u0, v0, umod); + v0 = submod(u0, v0, umod); + + a[m+r] = addmod(u1, v1, umod); + v1 = submod(u1, v1, umod); + + a[r+mhalf] = v0; + a[m+r+mhalf] = v1; + } + + for (j = 1; j < mhalf; j++) { + + w = wtable[j*wstep]; + + for (r = 0; r < n; r += 2*m) { + + u0 = a[r+j]; + v0 = a[r+j+mhalf]; + + u1 = a[m+r+j]; + v1 = a[m+r+j+mhalf]; + + a[r+j] = addmod(u0, v0, umod); + v0 = submod(u0, v0, umod); + + a[m+r+j] = addmod(u1, v1, umod); + v1 = submod(u1, v1, umod); + + MULMOD2C(&v0, &v1, w); + + a[r+j+mhalf] = v0; + a[m+r+j+mhalf] = v1; + } + + } + + } + + bitreverse_permute(a, n); +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/difradix2.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/difradix2.h index cdcbcf9a710..fb99acb7b6a 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/difradix2.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/difradix2.h @@ -1,47 +1,47 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_DIFRADIX2_H_ #define LIBMPDEC_DIFRADIX2_H_ - - -#include "mpdecimal.h" -#include "numbertheory.h" - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -void fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams); - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - + + +#include "mpdecimal.h" +#include "numbertheory.h" + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +void fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams); + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_DIFRADIX2_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/fnt.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/fnt.c index 0dbe98fc71c..2f69ba25573 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/fnt.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/fnt.c @@ -1,79 +1,79 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" #include -#include +#include -#include "bits.h" -#include "difradix2.h" +#include "bits.h" +#include "difradix2.h" #include "fnt.h" -#include "numbertheory.h" - - -/* Bignum: Fast transform for medium-sized coefficients. */ - - -/* forward transform, sign = -1 */ -int -std_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) -{ - struct fnt_params *tparams; - - assert(ispower2(n)); - assert(n >= 4); - assert(n <= 3*MPD_MAXTRANSFORM_2N); - - if ((tparams = _mpd_init_fnt_params(n, -1, modnum)) == NULL) { - return 0; - } - fnt_dif2(a, n, tparams); - - mpd_free(tparams); - return 1; -} - -/* reverse transform, sign = 1 */ -int -std_inv_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) -{ - struct fnt_params *tparams; - - assert(ispower2(n)); - assert(n >= 4); - assert(n <= 3*MPD_MAXTRANSFORM_2N); - - if ((tparams = _mpd_init_fnt_params(n, 1, modnum)) == NULL) { - return 0; - } - fnt_dif2(a, n, tparams); - - mpd_free(tparams); - return 1; -} +#include "numbertheory.h" + + +/* Bignum: Fast transform for medium-sized coefficients. */ + + +/* forward transform, sign = -1 */ +int +std_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) +{ + struct fnt_params *tparams; + + assert(ispower2(n)); + assert(n >= 4); + assert(n <= 3*MPD_MAXTRANSFORM_2N); + + if ((tparams = _mpd_init_fnt_params(n, -1, modnum)) == NULL) { + return 0; + } + fnt_dif2(a, n, tparams); + + mpd_free(tparams); + return 1; +} + +/* reverse transform, sign = 1 */ +int +std_inv_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) +{ + struct fnt_params *tparams; + + assert(ispower2(n)); + assert(n >= 4); + assert(n <= 3*MPD_MAXTRANSFORM_2N); + + if ((tparams = _mpd_init_fnt_params(n, 1, modnum)) == NULL) { + return 0; + } + fnt_dif2(a, n, tparams); + + mpd_free(tparams); + return 1; +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/fnt.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/fnt.h index 5222c476a3a..22e7b924dd1 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/fnt.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/fnt.h @@ -1,47 +1,47 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_FNT_H_ #define LIBMPDEC_FNT_H_ - - -#include "mpdecimal.h" - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -int std_fnt(mpd_uint_t a[], mpd_size_t n, int modnum); -int std_inv_fnt(mpd_uint_t a[], mpd_size_t n, int modnum); - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - + + +#include "mpdecimal.h" + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +int std_fnt(mpd_uint_t a[], mpd_size_t n, int modnum); +int std_inv_fnt(mpd_uint_t a[], mpd_size_t n, int modnum); + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_FNT_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/fourstep.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/fourstep.c index fb173ed5a52..ff7694ea6df 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/fourstep.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/fourstep.c @@ -1,259 +1,259 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" - -#include + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" + +#include #include "constants.h" #include "fourstep.h" -#include "numbertheory.h" -#include "sixstep.h" -#include "umodarith.h" - - -/* Bignum: Cache efficient Matrix Fourier Transform for arrays of the - form 3 * 2**n (See literature/matrix-transform.txt). */ - - -#ifndef PPRO -static inline void -std_size3_ntt(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, - mpd_uint_t w3table[3], mpd_uint_t umod) -{ - mpd_uint_t r1, r2; - mpd_uint_t w; - mpd_uint_t s, tmp; - - - /* k = 0 -> w = 1 */ - s = *x1; - s = addmod(s, *x2, umod); - s = addmod(s, *x3, umod); - - r1 = s; - - /* k = 1 */ - s = *x1; - - w = w3table[1]; - tmp = MULMOD(*x2, w); - s = addmod(s, tmp, umod); - - w = w3table[2]; - tmp = MULMOD(*x3, w); - s = addmod(s, tmp, umod); - - r2 = s; - - /* k = 2 */ - s = *x1; - - w = w3table[2]; - tmp = MULMOD(*x2, w); - s = addmod(s, tmp, umod); - - w = w3table[1]; - tmp = MULMOD(*x3, w); - s = addmod(s, tmp, umod); - - *x3 = s; - *x2 = r2; - *x1 = r1; -} -#else /* PPRO */ -static inline void -ppro_size3_ntt(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_uint_t w3table[3], - mpd_uint_t umod, double *dmod, uint32_t dinvmod[3]) -{ - mpd_uint_t r1, r2; - mpd_uint_t w; - mpd_uint_t s, tmp; - - - /* k = 0 -> w = 1 */ - s = *x1; - s = addmod(s, *x2, umod); - s = addmod(s, *x3, umod); - - r1 = s; - - /* k = 1 */ - s = *x1; - - w = w3table[1]; - tmp = ppro_mulmod(*x2, w, dmod, dinvmod); - s = addmod(s, tmp, umod); - - w = w3table[2]; - tmp = ppro_mulmod(*x3, w, dmod, dinvmod); - s = addmod(s, tmp, umod); - - r2 = s; - - /* k = 2 */ - s = *x1; - - w = w3table[2]; - tmp = ppro_mulmod(*x2, w, dmod, dinvmod); - s = addmod(s, tmp, umod); - - w = w3table[1]; - tmp = ppro_mulmod(*x3, w, dmod, dinvmod); - s = addmod(s, tmp, umod); - - *x3 = s; - *x2 = r2; - *x1 = r1; -} -#endif - - -/* forward transform, sign = -1; transform length = 3 * 2**n */ -int -four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) -{ - mpd_size_t R = 3; /* number of rows */ - mpd_size_t C = n / 3; /* number of columns */ - mpd_uint_t w3table[3]; - mpd_uint_t kernel, w0, w1, wstep; - mpd_uint_t *s, *p0, *p1, *p2; - mpd_uint_t umod; -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_size_t i, k; - - - assert(n >= 48); - assert(n <= 3*MPD_MAXTRANSFORM_2N); - - - /* Length R transform on the columns. */ - SETMODULUS(modnum); - _mpd_init_w3table(w3table, -1, modnum); - for (p0=a, p1=p0+C, p2=p0+2*C; p0 w = 1 */ + s = *x1; + s = addmod(s, *x2, umod); + s = addmod(s, *x3, umod); + + r1 = s; + + /* k = 1 */ + s = *x1; + + w = w3table[1]; + tmp = MULMOD(*x2, w); + s = addmod(s, tmp, umod); + + w = w3table[2]; + tmp = MULMOD(*x3, w); + s = addmod(s, tmp, umod); + + r2 = s; + + /* k = 2 */ + s = *x1; + + w = w3table[2]; + tmp = MULMOD(*x2, w); + s = addmod(s, tmp, umod); + + w = w3table[1]; + tmp = MULMOD(*x3, w); + s = addmod(s, tmp, umod); + + *x3 = s; + *x2 = r2; + *x1 = r1; +} +#else /* PPRO */ +static inline void +ppro_size3_ntt(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_uint_t w3table[3], + mpd_uint_t umod, double *dmod, uint32_t dinvmod[3]) +{ + mpd_uint_t r1, r2; + mpd_uint_t w; + mpd_uint_t s, tmp; + + + /* k = 0 -> w = 1 */ + s = *x1; + s = addmod(s, *x2, umod); + s = addmod(s, *x3, umod); + + r1 = s; + + /* k = 1 */ + s = *x1; + + w = w3table[1]; + tmp = ppro_mulmod(*x2, w, dmod, dinvmod); + s = addmod(s, tmp, umod); + + w = w3table[2]; + tmp = ppro_mulmod(*x3, w, dmod, dinvmod); + s = addmod(s, tmp, umod); + + r2 = s; + + /* k = 2 */ + s = *x1; + + w = w3table[2]; + tmp = ppro_mulmod(*x2, w, dmod, dinvmod); + s = addmod(s, tmp, umod); + + w = w3table[1]; + tmp = ppro_mulmod(*x3, w, dmod, dinvmod); + s = addmod(s, tmp, umod); + + *x3 = s; + *x2 = r2; + *x1 = r1; +} +#endif + + +/* forward transform, sign = -1; transform length = 3 * 2**n */ +int +four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) +{ + mpd_size_t R = 3; /* number of rows */ + mpd_size_t C = n / 3; /* number of columns */ + mpd_uint_t w3table[3]; + mpd_uint_t kernel, w0, w1, wstep; + mpd_uint_t *s, *p0, *p1, *p2; + mpd_uint_t umod; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_size_t i, k; + + + assert(n >= 48); + assert(n <= 3*MPD_MAXTRANSFORM_2N); + + + /* Length R transform on the columns. */ + SETMODULUS(modnum); + _mpd_init_w3table(w3table, -1, modnum); + for (p0=a, p1=p0+C, p2=p0+2*C; p0= 48); - assert(n <= 3*MPD_MAXTRANSFORM_2N); - - -#if 0 - /* An unordered transform is sufficient for convolution. */ - /* Transpose the matrix, producing an R*C matrix. */ + transpose_3xpow2(a, R, C); +#endif + + return 1; +} + +/* backward transform, sign = 1; transform length = 3 * 2**n */ +int +inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) +{ + mpd_size_t R = 3; /* number of rows */ + mpd_size_t C = n / 3; /* number of columns */ + mpd_uint_t w3table[3]; + mpd_uint_t kernel, w0, w1, wstep; + mpd_uint_t *s, *p0, *p1, *p2; + mpd_uint_t umod; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_size_t i, k; + + + assert(n >= 48); + assert(n <= 3*MPD_MAXTRANSFORM_2N); + + +#if 0 + /* An unordered transform is sufficient for convolution. */ + /* Transpose the matrix, producing an R*C matrix. */ #include "transpose.h" - transpose_3xpow2(a, C, R); -#endif - - /* Length C transform on the rows. */ - for (s = a; s < a+n; s += C) { - if (!inv_six_step_fnt(s, C, modnum)) { - return 0; - } - } - - /* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */ - SETMODULUS(modnum); - kernel = _mpd_getkernel(n, 1, modnum); - for (i = 1; i < R; i++) { - w0 = 1; - w1 = POWMOD(kernel, i); - wstep = MULMOD(w1, w1); - for (k = 0; k < C; k += 2) { - mpd_uint_t x0 = a[i*C+k]; - mpd_uint_t x1 = a[i*C+k+1]; - MULMOD2(&x0, w0, &x1, w1); - MULMOD2C(&w0, &w1, wstep); - a[i*C+k] = x0; - a[i*C+k+1] = x1; - } - } - - /* Length R transform on the columns. */ - _mpd_init_w3table(w3table, 1, modnum); - for (p0=a, p1=p0+C, p2=p0+2*C; p0 #include #include #include #include -#include -#include -#include - -#include "typearith.h" -#include "mpd_io.h" - - -/* This file contains functions for decimal <-> string conversions, including - PEP-3101 formatting for numeric types. */ - - -/* Disable warning that is part of -Wextra since gcc 7.0. */ -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && __GNUC__ >= 7 - #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#endif - - -/* - * Work around the behavior of tolower() and strcasecmp() in certain - * locales. For example, in tr_TR.utf8: - * - * tolower((unsigned char)'I') == 'I' - * - * u is the exact uppercase version of l; n is strlen(l) or strlen(l)+1 - */ -static inline int -_mpd_strneq(const char *s, const char *l, const char *u, size_t n) -{ - while (--n != SIZE_MAX) { - if (*s != *l && *s != *u) { - return 0; - } - s++; u++; l++; - } - - return 1; -} - -static mpd_ssize_t -strtoexp(const char *s) -{ - char *end; - mpd_ssize_t retval; - - errno = 0; - retval = mpd_strtossize(s, &end, 10); - if (errno == 0 && !(*s != '\0' && *end == '\0')) - errno = EINVAL; - - return retval; -} - -/* - * Scan 'len' words. The most significant word contains 'r' digits, - * the remaining words are full words. Skip dpoint. The string 's' must - * consist of digits and an optional single decimal point at 'dpoint'. - */ -static void -string_to_coeff(mpd_uint_t *data, const char *s, const char *dpoint, int r, - size_t len) -{ - int j; - - if (r > 0) { - data[--len] = 0; - for (j = 0; j < r; j++, s++) { - if (s == dpoint) s++; - data[len] = 10 * data[len] + (*s - '0'); - } - } - - while (--len != SIZE_MAX) { - data[len] = 0; - for (j = 0; j < MPD_RDIGITS; j++, s++) { - if (s == dpoint) s++; - data[len] = 10 * data[len] + (*s - '0'); - } - } -} - -/* - * Partially verify a numeric string of the form: - * - * [cdigits][.][cdigits][eE][+-][edigits] - * - * If successful, return a pointer to the location of the first - * relevant coefficient digit. This digit is either non-zero or - * part of one of the following patterns: - * - * ["0\x00", "0.\x00", "0.E", "0.e", "0E", "0e"] - * - * The locations of a single optional dot or indicator are stored - * in 'dpoint' and 'exp'. - * - * The end of the string is stored in 'end'. If an indicator [eE] - * occurs without trailing [edigits], the condition is caught - * later by strtoexp(). - */ -static const char * -scan_dpoint_exp(const char *s, const char **dpoint, const char **exp, - const char **end) -{ - const char *coeff = NULL; - - *dpoint = NULL; - *exp = NULL; - for (; *s != '\0'; s++) { - switch (*s) { - case '.': - if (*dpoint != NULL || *exp != NULL) - return NULL; - *dpoint = s; - break; - case 'E': case 'e': - if (*exp != NULL) - return NULL; - *exp = s; - if (*(s+1) == '+' || *(s+1) == '-') - s++; - break; - default: - if (!isdigit((uchar)*s)) - return NULL; - if (coeff == NULL && *exp == NULL) { - if (*s == '0') { - if (!isdigit((uchar)*(s+1))) - if (!(*(s+1) == '.' && - isdigit((uchar)*(s+2)))) - coeff = s; - } - else { - coeff = s; - } - } - break; - - } - } - - *end = s; - return coeff; -} - -/* scan the payload of a NaN */ -static const char * -scan_payload(const char *s, const char **end) -{ - const char *coeff; - - while (*s == '0') - s++; - coeff = s; - - while (isdigit((uchar)*s)) - s++; - *end = s; - - return (*s == '\0') ? coeff : NULL; -} - -/* convert a character string to a decimal */ -void -mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_ssize_t q, r, len; - const char *coeff, *end; - const char *dpoint = NULL, *exp = NULL; - size_t digits; - uint8_t sign = MPD_POS; - - mpd_set_flags(dec, 0); - dec->len = 0; - dec->exp = 0; - - /* sign */ - if (*s == '+') { - s++; - } - else if (*s == '-') { - mpd_set_negative(dec); - sign = MPD_NEG; - s++; - } - - if (_mpd_strneq(s, "nan", "NAN", 3)) { /* NaN */ - s += 3; - mpd_setspecial(dec, sign, MPD_NAN); - if (*s == '\0') - return; - /* validate payload: digits only */ - if ((coeff = scan_payload(s, &end)) == NULL) - goto conversion_error; - /* payload consists entirely of zeros */ - if (*coeff == '\0') - return; - digits = end - coeff; - /* prec >= 1, clamp is 0 or 1 */ - if (digits > (size_t)(ctx->prec-ctx->clamp)) - goto conversion_error; - } /* sNaN */ - else if (_mpd_strneq(s, "snan", "SNAN", 4)) { - s += 4; - mpd_setspecial(dec, sign, MPD_SNAN); - if (*s == '\0') - return; - /* validate payload: digits only */ - if ((coeff = scan_payload(s, &end)) == NULL) - goto conversion_error; - /* payload consists entirely of zeros */ - if (*coeff == '\0') - return; +#include +#include +#include + +#include "typearith.h" +#include "mpd_io.h" + + +/* This file contains functions for decimal <-> string conversions, including + PEP-3101 formatting for numeric types. */ + + +/* Disable warning that is part of -Wextra since gcc 7.0. */ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && __GNUC__ >= 7 + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif + + +/* + * Work around the behavior of tolower() and strcasecmp() in certain + * locales. For example, in tr_TR.utf8: + * + * tolower((unsigned char)'I') == 'I' + * + * u is the exact uppercase version of l; n is strlen(l) or strlen(l)+1 + */ +static inline int +_mpd_strneq(const char *s, const char *l, const char *u, size_t n) +{ + while (--n != SIZE_MAX) { + if (*s != *l && *s != *u) { + return 0; + } + s++; u++; l++; + } + + return 1; +} + +static mpd_ssize_t +strtoexp(const char *s) +{ + char *end; + mpd_ssize_t retval; + + errno = 0; + retval = mpd_strtossize(s, &end, 10); + if (errno == 0 && !(*s != '\0' && *end == '\0')) + errno = EINVAL; + + return retval; +} + +/* + * Scan 'len' words. The most significant word contains 'r' digits, + * the remaining words are full words. Skip dpoint. The string 's' must + * consist of digits and an optional single decimal point at 'dpoint'. + */ +static void +string_to_coeff(mpd_uint_t *data, const char *s, const char *dpoint, int r, + size_t len) +{ + int j; + + if (r > 0) { + data[--len] = 0; + for (j = 0; j < r; j++, s++) { + if (s == dpoint) s++; + data[len] = 10 * data[len] + (*s - '0'); + } + } + + while (--len != SIZE_MAX) { + data[len] = 0; + for (j = 0; j < MPD_RDIGITS; j++, s++) { + if (s == dpoint) s++; + data[len] = 10 * data[len] + (*s - '0'); + } + } +} + +/* + * Partially verify a numeric string of the form: + * + * [cdigits][.][cdigits][eE][+-][edigits] + * + * If successful, return a pointer to the location of the first + * relevant coefficient digit. This digit is either non-zero or + * part of one of the following patterns: + * + * ["0\x00", "0.\x00", "0.E", "0.e", "0E", "0e"] + * + * The locations of a single optional dot or indicator are stored + * in 'dpoint' and 'exp'. + * + * The end of the string is stored in 'end'. If an indicator [eE] + * occurs without trailing [edigits], the condition is caught + * later by strtoexp(). + */ +static const char * +scan_dpoint_exp(const char *s, const char **dpoint, const char **exp, + const char **end) +{ + const char *coeff = NULL; + + *dpoint = NULL; + *exp = NULL; + for (; *s != '\0'; s++) { + switch (*s) { + case '.': + if (*dpoint != NULL || *exp != NULL) + return NULL; + *dpoint = s; + break; + case 'E': case 'e': + if (*exp != NULL) + return NULL; + *exp = s; + if (*(s+1) == '+' || *(s+1) == '-') + s++; + break; + default: + if (!isdigit((uchar)*s)) + return NULL; + if (coeff == NULL && *exp == NULL) { + if (*s == '0') { + if (!isdigit((uchar)*(s+1))) + if (!(*(s+1) == '.' && + isdigit((uchar)*(s+2)))) + coeff = s; + } + else { + coeff = s; + } + } + break; + + } + } + + *end = s; + return coeff; +} + +/* scan the payload of a NaN */ +static const char * +scan_payload(const char *s, const char **end) +{ + const char *coeff; + + while (*s == '0') + s++; + coeff = s; + + while (isdigit((uchar)*s)) + s++; + *end = s; + + return (*s == '\0') ? coeff : NULL; +} + +/* convert a character string to a decimal */ +void +mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_ssize_t q, r, len; + const char *coeff, *end; + const char *dpoint = NULL, *exp = NULL; + size_t digits; + uint8_t sign = MPD_POS; + + mpd_set_flags(dec, 0); + dec->len = 0; + dec->exp = 0; + + /* sign */ + if (*s == '+') { + s++; + } + else if (*s == '-') { + mpd_set_negative(dec); + sign = MPD_NEG; + s++; + } + + if (_mpd_strneq(s, "nan", "NAN", 3)) { /* NaN */ + s += 3; + mpd_setspecial(dec, sign, MPD_NAN); + if (*s == '\0') + return; + /* validate payload: digits only */ + if ((coeff = scan_payload(s, &end)) == NULL) + goto conversion_error; + /* payload consists entirely of zeros */ + if (*coeff == '\0') + return; + digits = end - coeff; + /* prec >= 1, clamp is 0 or 1 */ + if (digits > (size_t)(ctx->prec-ctx->clamp)) + goto conversion_error; + } /* sNaN */ + else if (_mpd_strneq(s, "snan", "SNAN", 4)) { + s += 4; + mpd_setspecial(dec, sign, MPD_SNAN); + if (*s == '\0') + return; + /* validate payload: digits only */ + if ((coeff = scan_payload(s, &end)) == NULL) + goto conversion_error; + /* payload consists entirely of zeros */ + if (*coeff == '\0') + return; + digits = end - coeff; + if (digits > (size_t)(ctx->prec-ctx->clamp)) + goto conversion_error; + } + else if (_mpd_strneq(s, "inf", "INF", 3)) { + s += 3; + if (*s == '\0' || _mpd_strneq(s, "inity", "INITY", 6)) { + /* numeric-value: infinity */ + mpd_setspecial(dec, sign, MPD_INF); + return; + } + goto conversion_error; + } + else { + /* scan for start of coefficient, decimal point, indicator, end */ + if ((coeff = scan_dpoint_exp(s, &dpoint, &exp, &end)) == NULL) + goto conversion_error; + + /* numeric-value: [exponent-part] */ + if (exp) { + /* exponent-part */ + end = exp; exp++; + dec->exp = strtoexp(exp); + if (errno) { + if (!(errno == ERANGE && + (dec->exp == MPD_SSIZE_MAX || + dec->exp == MPD_SSIZE_MIN))) + goto conversion_error; + } + } + digits = end - coeff; - if (digits > (size_t)(ctx->prec-ctx->clamp)) - goto conversion_error; - } - else if (_mpd_strneq(s, "inf", "INF", 3)) { - s += 3; - if (*s == '\0' || _mpd_strneq(s, "inity", "INITY", 6)) { - /* numeric-value: infinity */ - mpd_setspecial(dec, sign, MPD_INF); - return; - } - goto conversion_error; - } - else { - /* scan for start of coefficient, decimal point, indicator, end */ - if ((coeff = scan_dpoint_exp(s, &dpoint, &exp, &end)) == NULL) - goto conversion_error; - - /* numeric-value: [exponent-part] */ - if (exp) { - /* exponent-part */ - end = exp; exp++; - dec->exp = strtoexp(exp); - if (errno) { - if (!(errno == ERANGE && - (dec->exp == MPD_SSIZE_MAX || - dec->exp == MPD_SSIZE_MIN))) - goto conversion_error; - } - } - - digits = end - coeff; - if (dpoint) { - size_t fracdigits = end-dpoint-1; - if (dpoint > coeff) digits--; - - if (fracdigits > MPD_MAX_PREC) { - goto conversion_error; - } - if (dec->exp < MPD_SSIZE_MIN+(mpd_ssize_t)fracdigits) { - dec->exp = MPD_SSIZE_MIN; - } - else { - dec->exp -= (mpd_ssize_t)fracdigits; - } - } - if (digits > MPD_MAX_PREC) { - goto conversion_error; - } - if (dec->exp > MPD_EXP_INF) { - dec->exp = MPD_EXP_INF; - } - if (dec->exp == MPD_SSIZE_MIN) { - dec->exp = MPD_SSIZE_MIN+1; - } - } - - _mpd_idiv_word(&q, &r, (mpd_ssize_t)digits, MPD_RDIGITS); - - len = (r == 0) ? q : q+1; - if (len == 0) { - goto conversion_error; /* GCOV_NOT_REACHED */ - } - if (!mpd_qresize(dec, len, status)) { - mpd_seterror(dec, MPD_Malloc_error, status); - return; - } - dec->len = len; - - string_to_coeff(dec->data, coeff, dpoint, (int)r, len); - - mpd_setdigits(dec); - mpd_qfinalize(dec, ctx, status); - return; - -conversion_error: - /* standard wants a positive NaN */ - mpd_seterror(dec, MPD_Conversion_syntax, status); -} - + if (dpoint) { + size_t fracdigits = end-dpoint-1; + if (dpoint > coeff) digits--; + + if (fracdigits > MPD_MAX_PREC) { + goto conversion_error; + } + if (dec->exp < MPD_SSIZE_MIN+(mpd_ssize_t)fracdigits) { + dec->exp = MPD_SSIZE_MIN; + } + else { + dec->exp -= (mpd_ssize_t)fracdigits; + } + } + if (digits > MPD_MAX_PREC) { + goto conversion_error; + } + if (dec->exp > MPD_EXP_INF) { + dec->exp = MPD_EXP_INF; + } + if (dec->exp == MPD_SSIZE_MIN) { + dec->exp = MPD_SSIZE_MIN+1; + } + } + + _mpd_idiv_word(&q, &r, (mpd_ssize_t)digits, MPD_RDIGITS); + + len = (r == 0) ? q : q+1; + if (len == 0) { + goto conversion_error; /* GCOV_NOT_REACHED */ + } + if (!mpd_qresize(dec, len, status)) { + mpd_seterror(dec, MPD_Malloc_error, status); + return; + } + dec->len = len; + + string_to_coeff(dec->data, coeff, dpoint, (int)r, len); + + mpd_setdigits(dec); + mpd_qfinalize(dec, ctx, status); + return; + +conversion_error: + /* standard wants a positive NaN */ + mpd_seterror(dec, MPD_Conversion_syntax, status); +} + /* convert a character string to a decimal, use a maxcontext for conversion */ void mpd_qset_string_exact(mpd_t *dec, const char *s, uint32_t *status) @@ -342,1257 +342,1257 @@ mpd_qset_string_exact(mpd_t *dec, const char *s, uint32_t *status) *status &= MPD_Errors; } -/* Print word x with n decimal digits to string s. dot is either NULL - or the location of a decimal point. */ -#define EXTRACT_DIGIT(s, x, d, dot) \ - if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d -static inline char * -word_to_string(char *s, mpd_uint_t x, int n, char *dot) -{ - switch(n) { -#ifdef CONFIG_64 - case 20: EXTRACT_DIGIT(s, x, 10000000000000000000ULL, dot); /* GCOV_NOT_REACHED */ - case 19: EXTRACT_DIGIT(s, x, 1000000000000000000ULL, dot); - case 18: EXTRACT_DIGIT(s, x, 100000000000000000ULL, dot); - case 17: EXTRACT_DIGIT(s, x, 10000000000000000ULL, dot); - case 16: EXTRACT_DIGIT(s, x, 1000000000000000ULL, dot); - case 15: EXTRACT_DIGIT(s, x, 100000000000000ULL, dot); - case 14: EXTRACT_DIGIT(s, x, 10000000000000ULL, dot); - case 13: EXTRACT_DIGIT(s, x, 1000000000000ULL, dot); - case 12: EXTRACT_DIGIT(s, x, 100000000000ULL, dot); - case 11: EXTRACT_DIGIT(s, x, 10000000000ULL, dot); -#endif - case 10: EXTRACT_DIGIT(s, x, 1000000000UL, dot); - case 9: EXTRACT_DIGIT(s, x, 100000000UL, dot); - case 8: EXTRACT_DIGIT(s, x, 10000000UL, dot); - case 7: EXTRACT_DIGIT(s, x, 1000000UL, dot); - case 6: EXTRACT_DIGIT(s, x, 100000UL, dot); - case 5: EXTRACT_DIGIT(s, x, 10000UL, dot); - case 4: EXTRACT_DIGIT(s, x, 1000UL, dot); - case 3: EXTRACT_DIGIT(s, x, 100UL, dot); - case 2: EXTRACT_DIGIT(s, x, 10UL, dot); - default: if (s == dot) *s++ = '.'; *s++ = '0' + (char)x; - } - - *s = '\0'; - return s; -} - -/* Print exponent x to string s. Undefined for MPD_SSIZE_MIN. */ -static inline char * -exp_to_string(char *s, mpd_ssize_t x) -{ - char sign = '+'; - - if (x < 0) { - sign = '-'; - x = -x; - } - *s++ = sign; - - return word_to_string(s, x, mpd_word_digits(x), NULL); -} - -/* Print the coefficient of dec to string s. len(dec) > 0. */ -static inline char * -coeff_to_string(char *s, const mpd_t *dec) -{ - mpd_uint_t x; - mpd_ssize_t i; - - /* most significant word */ - x = mpd_msword(dec); - s = word_to_string(s, x, mpd_word_digits(x), NULL); - - /* remaining full words */ - for (i=dec->len-2; i >= 0; --i) { - x = dec->data[i]; - s = word_to_string(s, x, MPD_RDIGITS, NULL); - } - - return s; -} - -/* Print the coefficient of dec to string s. len(dec) > 0. dot is either - NULL or a pointer to the location of a decimal point. */ -static inline char * -coeff_to_string_dot(char *s, char *dot, const mpd_t *dec) -{ - mpd_uint_t x; - mpd_ssize_t i; - - /* most significant word */ - x = mpd_msword(dec); - s = word_to_string(s, x, mpd_word_digits(x), dot); - - /* remaining full words */ - for (i=dec->len-2; i >= 0; --i) { - x = dec->data[i]; - s = word_to_string(s, x, MPD_RDIGITS, dot); - } - - return s; -} - -/* Format type */ -#define MPD_FMT_LOWER 0x00000000 -#define MPD_FMT_UPPER 0x00000001 -#define MPD_FMT_TOSCI 0x00000002 -#define MPD_FMT_TOENG 0x00000004 -#define MPD_FMT_EXP 0x00000008 -#define MPD_FMT_FIXED 0x00000010 -#define MPD_FMT_PERCENT 0x00000020 -#define MPD_FMT_SIGN_SPACE 0x00000040 -#define MPD_FMT_SIGN_PLUS 0x00000080 - -/* Default place of the decimal point for MPD_FMT_TOSCI, MPD_FMT_EXP */ -#define MPD_DEFAULT_DOTPLACE 1 - -/* - * Set *result to the string representation of a decimal. Return the length - * of *result, not including the terminating '\0' character. - * - * Formatting is done according to 'flags'. A return value of -1 with *result - * set to NULL indicates MPD_Malloc_error. - * - * 'dplace' is the default place of the decimal point. It is always set to - * MPD_DEFAULT_DOTPLACE except for zeros in combination with MPD_FMT_EXP. - */ -static mpd_ssize_t -_mpd_to_string(char **result, const mpd_t *dec, int flags, mpd_ssize_t dplace) -{ - char *decstring = NULL, *cp = NULL; - mpd_ssize_t ldigits; - mpd_ssize_t mem = 0, k; - - if (mpd_isspecial(dec)) { - - mem = sizeof "-Infinity%"; - if (mpd_isnan(dec) && dec->len > 0) { - /* diagnostic code */ - mem += dec->digits; - } - cp = decstring = mpd_alloc(mem, sizeof *decstring); - if (cp == NULL) { - *result = NULL; - return -1; - } - - if (mpd_isnegative(dec)) { - *cp++ = '-'; - } - else if (flags&MPD_FMT_SIGN_SPACE) { - *cp++ = ' '; - } - else if (flags&MPD_FMT_SIGN_PLUS) { - *cp++ = '+'; - } - - if (mpd_isnan(dec)) { - if (mpd_isqnan(dec)) { - strcpy(cp, "NaN"); - cp += 3; - } - else { - strcpy(cp, "sNaN"); - cp += 4; - } - if (dec->len > 0) { /* diagnostic code */ - cp = coeff_to_string(cp, dec); - } - } - else if (mpd_isinfinite(dec)) { - strcpy(cp, "Infinity"); - cp += 8; - } - else { /* debug */ - abort(); /* GCOV_NOT_REACHED */ - } - } - else { - assert(dec->len > 0); - - /* - * For easier manipulation of the decimal point's location - * and the exponent that is finally printed, the number is - * rescaled to a virtual representation with exp = 0. Here - * ldigits denotes the number of decimal digits to the left - * of the decimal point and remains constant once initialized. - * - * dplace is the location of the decimal point relative to - * the start of the coefficient. Note that 3) always holds - * when dplace is shifted. - * - * 1) ldigits := dec->digits - dec->exp - * 2) dplace := ldigits (initially) - * 3) exp := ldigits - dplace (initially exp = 0) - * - * 0.00000_.____._____000000. - * ^ ^ ^ ^ - * | | | | - * | | | `- dplace >= digits - * | | `- dplace in the middle of the coefficient - * | ` dplace = 1 (after the first coefficient digit) - * `- dplace <= 0 - */ - - ldigits = dec->digits + dec->exp; - - if (flags&MPD_FMT_EXP) { - ; - } - else if (flags&MPD_FMT_FIXED || (dec->exp <= 0 && ldigits > -6)) { - /* MPD_FMT_FIXED: always use fixed point notation. - * MPD_FMT_TOSCI, MPD_FMT_TOENG: for a certain range, - * override exponent notation. */ - dplace = ldigits; - } - else if (flags&MPD_FMT_TOENG) { - if (mpd_iszero(dec)) { - /* If the exponent is divisible by three, - * dplace = 1. Otherwise, move dplace one - * or two places to the left. */ - dplace = -1 + mod_mpd_ssize_t(dec->exp+2, 3); - } - else { /* ldigits-1 is the adjusted exponent, which +/* Print word x with n decimal digits to string s. dot is either NULL + or the location of a decimal point. */ +#define EXTRACT_DIGIT(s, x, d, dot) \ + if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d +static inline char * +word_to_string(char *s, mpd_uint_t x, int n, char *dot) +{ + switch(n) { +#ifdef CONFIG_64 + case 20: EXTRACT_DIGIT(s, x, 10000000000000000000ULL, dot); /* GCOV_NOT_REACHED */ + case 19: EXTRACT_DIGIT(s, x, 1000000000000000000ULL, dot); + case 18: EXTRACT_DIGIT(s, x, 100000000000000000ULL, dot); + case 17: EXTRACT_DIGIT(s, x, 10000000000000000ULL, dot); + case 16: EXTRACT_DIGIT(s, x, 1000000000000000ULL, dot); + case 15: EXTRACT_DIGIT(s, x, 100000000000000ULL, dot); + case 14: EXTRACT_DIGIT(s, x, 10000000000000ULL, dot); + case 13: EXTRACT_DIGIT(s, x, 1000000000000ULL, dot); + case 12: EXTRACT_DIGIT(s, x, 100000000000ULL, dot); + case 11: EXTRACT_DIGIT(s, x, 10000000000ULL, dot); +#endif + case 10: EXTRACT_DIGIT(s, x, 1000000000UL, dot); + case 9: EXTRACT_DIGIT(s, x, 100000000UL, dot); + case 8: EXTRACT_DIGIT(s, x, 10000000UL, dot); + case 7: EXTRACT_DIGIT(s, x, 1000000UL, dot); + case 6: EXTRACT_DIGIT(s, x, 100000UL, dot); + case 5: EXTRACT_DIGIT(s, x, 10000UL, dot); + case 4: EXTRACT_DIGIT(s, x, 1000UL, dot); + case 3: EXTRACT_DIGIT(s, x, 100UL, dot); + case 2: EXTRACT_DIGIT(s, x, 10UL, dot); + default: if (s == dot) *s++ = '.'; *s++ = '0' + (char)x; + } + + *s = '\0'; + return s; +} + +/* Print exponent x to string s. Undefined for MPD_SSIZE_MIN. */ +static inline char * +exp_to_string(char *s, mpd_ssize_t x) +{ + char sign = '+'; + + if (x < 0) { + sign = '-'; + x = -x; + } + *s++ = sign; + + return word_to_string(s, x, mpd_word_digits(x), NULL); +} + +/* Print the coefficient of dec to string s. len(dec) > 0. */ +static inline char * +coeff_to_string(char *s, const mpd_t *dec) +{ + mpd_uint_t x; + mpd_ssize_t i; + + /* most significant word */ + x = mpd_msword(dec); + s = word_to_string(s, x, mpd_word_digits(x), NULL); + + /* remaining full words */ + for (i=dec->len-2; i >= 0; --i) { + x = dec->data[i]; + s = word_to_string(s, x, MPD_RDIGITS, NULL); + } + + return s; +} + +/* Print the coefficient of dec to string s. len(dec) > 0. dot is either + NULL or a pointer to the location of a decimal point. */ +static inline char * +coeff_to_string_dot(char *s, char *dot, const mpd_t *dec) +{ + mpd_uint_t x; + mpd_ssize_t i; + + /* most significant word */ + x = mpd_msword(dec); + s = word_to_string(s, x, mpd_word_digits(x), dot); + + /* remaining full words */ + for (i=dec->len-2; i >= 0; --i) { + x = dec->data[i]; + s = word_to_string(s, x, MPD_RDIGITS, dot); + } + + return s; +} + +/* Format type */ +#define MPD_FMT_LOWER 0x00000000 +#define MPD_FMT_UPPER 0x00000001 +#define MPD_FMT_TOSCI 0x00000002 +#define MPD_FMT_TOENG 0x00000004 +#define MPD_FMT_EXP 0x00000008 +#define MPD_FMT_FIXED 0x00000010 +#define MPD_FMT_PERCENT 0x00000020 +#define MPD_FMT_SIGN_SPACE 0x00000040 +#define MPD_FMT_SIGN_PLUS 0x00000080 + +/* Default place of the decimal point for MPD_FMT_TOSCI, MPD_FMT_EXP */ +#define MPD_DEFAULT_DOTPLACE 1 + +/* + * Set *result to the string representation of a decimal. Return the length + * of *result, not including the terminating '\0' character. + * + * Formatting is done according to 'flags'. A return value of -1 with *result + * set to NULL indicates MPD_Malloc_error. + * + * 'dplace' is the default place of the decimal point. It is always set to + * MPD_DEFAULT_DOTPLACE except for zeros in combination with MPD_FMT_EXP. + */ +static mpd_ssize_t +_mpd_to_string(char **result, const mpd_t *dec, int flags, mpd_ssize_t dplace) +{ + char *decstring = NULL, *cp = NULL; + mpd_ssize_t ldigits; + mpd_ssize_t mem = 0, k; + + if (mpd_isspecial(dec)) { + + mem = sizeof "-Infinity%"; + if (mpd_isnan(dec) && dec->len > 0) { + /* diagnostic code */ + mem += dec->digits; + } + cp = decstring = mpd_alloc(mem, sizeof *decstring); + if (cp == NULL) { + *result = NULL; + return -1; + } + + if (mpd_isnegative(dec)) { + *cp++ = '-'; + } + else if (flags&MPD_FMT_SIGN_SPACE) { + *cp++ = ' '; + } + else if (flags&MPD_FMT_SIGN_PLUS) { + *cp++ = '+'; + } + + if (mpd_isnan(dec)) { + if (mpd_isqnan(dec)) { + strcpy(cp, "NaN"); + cp += 3; + } + else { + strcpy(cp, "sNaN"); + cp += 4; + } + if (dec->len > 0) { /* diagnostic code */ + cp = coeff_to_string(cp, dec); + } + } + else if (mpd_isinfinite(dec)) { + strcpy(cp, "Infinity"); + cp += 8; + } + else { /* debug */ + abort(); /* GCOV_NOT_REACHED */ + } + } + else { + assert(dec->len > 0); + + /* + * For easier manipulation of the decimal point's location + * and the exponent that is finally printed, the number is + * rescaled to a virtual representation with exp = 0. Here + * ldigits denotes the number of decimal digits to the left + * of the decimal point and remains constant once initialized. + * + * dplace is the location of the decimal point relative to + * the start of the coefficient. Note that 3) always holds + * when dplace is shifted. + * + * 1) ldigits := dec->digits - dec->exp + * 2) dplace := ldigits (initially) + * 3) exp := ldigits - dplace (initially exp = 0) + * + * 0.00000_.____._____000000. + * ^ ^ ^ ^ + * | | | | + * | | | `- dplace >= digits + * | | `- dplace in the middle of the coefficient + * | ` dplace = 1 (after the first coefficient digit) + * `- dplace <= 0 + */ + + ldigits = dec->digits + dec->exp; + + if (flags&MPD_FMT_EXP) { + ; + } + else if (flags&MPD_FMT_FIXED || (dec->exp <= 0 && ldigits > -6)) { + /* MPD_FMT_FIXED: always use fixed point notation. + * MPD_FMT_TOSCI, MPD_FMT_TOENG: for a certain range, + * override exponent notation. */ + dplace = ldigits; + } + else if (flags&MPD_FMT_TOENG) { + if (mpd_iszero(dec)) { + /* If the exponent is divisible by three, + * dplace = 1. Otherwise, move dplace one + * or two places to the left. */ + dplace = -1 + mod_mpd_ssize_t(dec->exp+2, 3); + } + else { /* ldigits-1 is the adjusted exponent, which * should be divisible by three. If not, move * dplace one or two places to the right. */ - dplace += mod_mpd_ssize_t(ldigits-1, 3); - } - } - - /* - * Basic space requirements: - * - * [-][.][coeffdigits][E][-][expdigits+1][%]['\0'] - * - * If the decimal point lies outside of the coefficient digits, - * space is adjusted accordingly. - */ - if (dplace <= 0) { - mem = -dplace + dec->digits + 2; - } - else if (dplace >= dec->digits) { - mem = dplace; - } - else { - mem = dec->digits; - } - mem += (MPD_EXPDIGITS+1+6); - - cp = decstring = mpd_alloc(mem, sizeof *decstring); - if (cp == NULL) { - *result = NULL; - return -1; - } - - - if (mpd_isnegative(dec)) { - *cp++ = '-'; - } - else if (flags&MPD_FMT_SIGN_SPACE) { - *cp++ = ' '; - } - else if (flags&MPD_FMT_SIGN_PLUS) { - *cp++ = '+'; - } - - if (dplace <= 0) { - /* space: -dplace+dec->digits+2 */ - *cp++ = '0'; - *cp++ = '.'; - for (k = 0; k < -dplace; k++) { - *cp++ = '0'; - } - cp = coeff_to_string(cp, dec); - } - else if (dplace >= dec->digits) { - /* space: dplace */ - cp = coeff_to_string(cp, dec); - for (k = 0; k < dplace-dec->digits; k++) { - *cp++ = '0'; - } - } - else { - /* space: dec->digits+1 */ - cp = coeff_to_string_dot(cp, cp+dplace, dec); - } - - /* - * Conditions for printing an exponent: - * - * MPD_FMT_TOSCI, MPD_FMT_TOENG: only if ldigits != dplace - * MPD_FMT_FIXED: never (ldigits == dplace) - * MPD_FMT_EXP: always - */ - if (ldigits != dplace || flags&MPD_FMT_EXP) { - /* space: expdigits+2 */ - *cp++ = (flags&MPD_FMT_UPPER) ? 'E' : 'e'; - cp = exp_to_string(cp, ldigits-dplace); - } - } - - if (flags&MPD_FMT_PERCENT) { - *cp++ = '%'; - } - - assert(cp < decstring+mem); - assert(cp-decstring < MPD_SSIZE_MAX); - - *cp = '\0'; - *result = decstring; - return (mpd_ssize_t)(cp-decstring); -} - -char * -mpd_to_sci(const mpd_t *dec, int fmt) -{ - char *res; - int flags = MPD_FMT_TOSCI; - - flags |= fmt ? MPD_FMT_UPPER : MPD_FMT_LOWER; - (void)_mpd_to_string(&res, dec, flags, MPD_DEFAULT_DOTPLACE); - return res; -} - -char * -mpd_to_eng(const mpd_t *dec, int fmt) -{ - char *res; - int flags = MPD_FMT_TOENG; - - flags |= fmt ? MPD_FMT_UPPER : MPD_FMT_LOWER; - (void)_mpd_to_string(&res, dec, flags, MPD_DEFAULT_DOTPLACE); - return res; -} - -mpd_ssize_t -mpd_to_sci_size(char **res, const mpd_t *dec, int fmt) -{ - int flags = MPD_FMT_TOSCI; - - flags |= fmt ? MPD_FMT_UPPER : MPD_FMT_LOWER; - return _mpd_to_string(res, dec, flags, MPD_DEFAULT_DOTPLACE); -} - -mpd_ssize_t -mpd_to_eng_size(char **res, const mpd_t *dec, int fmt) -{ - int flags = MPD_FMT_TOENG; - - flags |= fmt ? MPD_FMT_UPPER : MPD_FMT_LOWER; - return _mpd_to_string(res, dec, flags, MPD_DEFAULT_DOTPLACE); -} - -/* Copy a single UTF-8 char to dest. See: The Unicode Standard, version 5.2, - chapter 3.9: Well-formed UTF-8 byte sequences. */ -static int -_mpd_copy_utf8(char dest[5], const char *s) -{ - const uchar *cp = (const uchar *)s; - uchar lb, ub; - int count, i; - - - if (*cp == 0) { - /* empty string */ - dest[0] = '\0'; - return 0; - } - else if (*cp <= 0x7f) { - /* ascii */ - dest[0] = *cp; - dest[1] = '\0'; - return 1; - } - else if (0xc2 <= *cp && *cp <= 0xdf) { - lb = 0x80; ub = 0xbf; - count = 2; - } - else if (*cp == 0xe0) { - lb = 0xa0; ub = 0xbf; - count = 3; - } - else if (*cp <= 0xec) { - lb = 0x80; ub = 0xbf; - count = 3; - } - else if (*cp == 0xed) { - lb = 0x80; ub = 0x9f; - count = 3; - } - else if (*cp <= 0xef) { - lb = 0x80; ub = 0xbf; - count = 3; - } - else if (*cp == 0xf0) { - lb = 0x90; ub = 0xbf; - count = 4; - } - else if (*cp <= 0xf3) { - lb = 0x80; ub = 0xbf; - count = 4; - } - else if (*cp == 0xf4) { - lb = 0x80; ub = 0x8f; - count = 4; - } - else { - /* invalid */ - goto error; - } - - dest[0] = *cp++; - if (*cp < lb || ub < *cp) { - goto error; - } - dest[1] = *cp++; - for (i = 2; i < count; i++) { - if (*cp < 0x80 || 0xbf < *cp) { - goto error; - } - dest[i] = *cp++; - } - dest[i] = '\0'; - - return count; - -error: - dest[0] = '\0'; - return -1; -} - -int -mpd_validate_lconv(mpd_spec_t *spec) -{ - size_t n; -#if CHAR_MAX == SCHAR_MAX - const char *cp = spec->grouping; - while (*cp != '\0') { - if (*cp++ < 0) { - return -1; - } - } -#endif - n = strlen(spec->dot); - if (n == 0 || n > 4) { - return -1; - } - if (strlen(spec->sep) > 4) { - return -1; - } - - return 0; -} - -int -mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps) -{ - char *cp = (char *)fmt; - int have_align = 0, n; - - /* defaults */ - spec->min_width = 0; - spec->prec = -1; - spec->type = caps ? 'G' : 'g'; - spec->align = '>'; - spec->sign = '-'; - spec->dot = ""; - spec->sep = ""; - spec->grouping = ""; - - - /* presume that the first character is a UTF-8 fill character */ - if ((n = _mpd_copy_utf8(spec->fill, cp)) < 0) { - return 0; - } - - /* alignment directive, prefixed by a fill character */ - if (*cp && (*(cp+n) == '<' || *(cp+n) == '>' || - *(cp+n) == '=' || *(cp+n) == '^')) { - cp += n; - spec->align = *cp++; - have_align = 1; - } /* alignment directive */ - else { - /* default fill character */ - spec->fill[0] = ' '; - spec->fill[1] = '\0'; - if (*cp == '<' || *cp == '>' || - *cp == '=' || *cp == '^') { - spec->align = *cp++; - have_align = 1; - } - } - - /* sign formatting */ - if (*cp == '+' || *cp == '-' || *cp == ' ') { - spec->sign = *cp++; - } - - /* zero padding */ - if (*cp == '0') { - /* zero padding implies alignment, which should not be - * specified twice. */ - if (have_align) { - return 0; - } - spec->align = 'z'; - spec->fill[0] = *cp++; - spec->fill[1] = '\0'; - } - - /* minimum width */ - if (isdigit((uchar)*cp)) { - if (*cp == '0') { - return 0; - } - errno = 0; - spec->min_width = mpd_strtossize(cp, &cp, 10); - if (errno == ERANGE || errno == EINVAL) { - return 0; - } - } - - /* thousands separator */ - if (*cp == ',') { - spec->dot = "."; - spec->sep = ","; - spec->grouping = "\003\003"; - cp++; - } - - /* fraction digits or significant digits */ - if (*cp == '.') { - cp++; - if (!isdigit((uchar)*cp)) { - return 0; - } - errno = 0; - spec->prec = mpd_strtossize(cp, &cp, 10); - if (errno == ERANGE || errno == EINVAL) { - return 0; - } - } - - /* type */ - if (*cp == 'E' || *cp == 'e' || *cp == 'F' || *cp == 'f' || - *cp == 'G' || *cp == 'g' || *cp == '%') { - spec->type = *cp++; - } - else if (*cp == 'N' || *cp == 'n') { - /* locale specific conversion */ - struct lconv *lc; - /* separator has already been specified */ - if (*spec->sep) { - return 0; - } - spec->type = *cp++; - spec->type = (spec->type == 'N') ? 'G' : 'g'; - lc = localeconv(); - spec->dot = lc->decimal_point; - spec->sep = lc->thousands_sep; - spec->grouping = lc->grouping; - if (mpd_validate_lconv(spec) < 0) { - return 0; /* GCOV_NOT_REACHED */ - } - } - - /* check correctness */ - if (*cp != '\0') { - return 0; - } - - return 1; -} - -/* - * The following functions assume that spec->min_width <= MPD_MAX_PREC, which - * is made sure in mpd_qformat_spec. Then, even with a spec that inserts a - * four-byte separator after each digit, nbytes in the following struct - * cannot overflow. - */ - -/* Multibyte string */ -typedef struct { - mpd_ssize_t nbytes; /* length in bytes */ - mpd_ssize_t nchars; /* length in chars */ - mpd_ssize_t cur; /* current write index */ - char *data; -} mpd_mbstr_t; - -static inline void -_mpd_bcopy(char *dest, const char *src, mpd_ssize_t n) -{ - while (--n >= 0) { - dest[n] = src[n]; - } -} - -static inline void -_mbstr_copy_char(mpd_mbstr_t *dest, const char *src, mpd_ssize_t n) -{ - dest->nbytes += n; - dest->nchars += (n > 0 ? 1 : 0); - dest->cur -= n; - - if (dest->data != NULL) { - _mpd_bcopy(dest->data+dest->cur, src, n); - } -} - -static inline void -_mbstr_copy_ascii(mpd_mbstr_t *dest, const char *src, mpd_ssize_t n) -{ - dest->nbytes += n; - dest->nchars += n; - dest->cur -= n; - - if (dest->data != NULL) { - _mpd_bcopy(dest->data+dest->cur, src, n); - } -} - -static inline void -_mbstr_copy_pad(mpd_mbstr_t *dest, mpd_ssize_t n) -{ - dest->nbytes += n; - dest->nchars += n; - dest->cur -= n; - - if (dest->data != NULL) { - char *cp = dest->data + dest->cur; - while (--n >= 0) { - cp[n] = '0'; - } - } -} - -/* - * Copy a numeric string to dest->data, adding separators in the integer - * part according to spec->grouping. If leading zero padding is enabled - * and the result is smaller than spec->min_width, continue adding zeros - * and separators until the minimum width is reached. - * - * The final length of dest->data is stored in dest->nbytes. The number - * of UTF-8 characters is stored in dest->nchars. - * - * First run (dest->data == NULL): determine the length of the result - * string and store it in dest->nbytes. - * - * Second run (write to dest->data): data is written in chunks and in - * reverse order, starting with the rest of the numeric string. - */ -static void -_mpd_add_sep_dot(mpd_mbstr_t *dest, - const char *sign, /* location of optional sign */ - const char *src, mpd_ssize_t n_src, /* integer part and length */ - const char *dot, /* location of optional decimal point */ - const char *rest, mpd_ssize_t n_rest, /* remaining part and length */ - const mpd_spec_t *spec) -{ - mpd_ssize_t n_sep, n_sign, consume; - const char *g; - int pad = 0; - - n_sign = sign ? 1 : 0; - n_sep = (mpd_ssize_t)strlen(spec->sep); - /* Initial write index: set to location of '\0' in the output string. - * Irrelevant for the first run. */ - dest->cur = dest->nbytes; - dest->nbytes = dest->nchars = 0; - - _mbstr_copy_ascii(dest, rest, n_rest); - - if (dot) { - _mbstr_copy_char(dest, dot, (mpd_ssize_t)strlen(dot)); - } - - g = spec->grouping; - consume = *g; - while (1) { - /* If the group length is 0 or CHAR_MAX or greater than the - * number of source bytes, consume all remaining bytes. */ - if (*g == 0 || *g == CHAR_MAX || consume > n_src) { - consume = n_src; - } - n_src -= consume; - if (pad) { - _mbstr_copy_pad(dest, consume); - } - else { - _mbstr_copy_ascii(dest, src+n_src, consume); - } - - if (n_src == 0) { - /* Either the real source of intpart digits or the virtual - * source of padding zeros is exhausted. */ - if (spec->align == 'z' && - dest->nchars + n_sign < spec->min_width) { - /* Zero padding is set and length < min_width: - * Generate n_src additional characters. */ - n_src = spec->min_width - (dest->nchars + n_sign); - /* Next iteration: - * case *g == 0 || *g == CHAR_MAX: - * consume all padding characters - * case consume < g*: - * fill remainder of current group - * case consume == g* - * copying is a no-op */ - consume = *g - consume; - /* Switch on virtual source of zeros. */ - pad = 1; - continue; - } - break; - } - - if (n_sep > 0) { - /* If padding is switched on, separators are counted - * as padding characters. This rule does not apply if - * the separator would be the first character of the - * result string. */ - if (pad && n_src > 1) n_src -= 1; - _mbstr_copy_char(dest, spec->sep, n_sep); - } - - /* If non-NUL, use the next value for grouping. */ - if (*g && *(g+1)) g++; - consume = *g; - } - - if (sign) { - _mbstr_copy_ascii(dest, sign, 1); - } - - if (dest->data) { - dest->data[dest->nbytes] = '\0'; - } -} - -/* - * Convert a numeric-string to its locale-specific appearance. - * The string must have one of these forms: - * - * 1) [sign] digits [exponent-part] - * 2) [sign] digits '.' [digits] [exponent-part] - * - * Not allowed, since _mpd_to_string() never returns this form: - * - * 3) [sign] '.' digits [exponent-part] - * - * Input: result->data := original numeric string (ASCII) - * result->bytes := strlen(result->data) - * result->nchars := strlen(result->data) - * - * Output: result->data := modified or original string - * result->bytes := strlen(result->data) - * result->nchars := number of characters (possibly UTF-8) - */ -static int -_mpd_apply_lconv(mpd_mbstr_t *result, const mpd_spec_t *spec, uint32_t *status) -{ - const char *sign = NULL, *intpart = NULL, *dot = NULL; - const char *rest, *dp; - char *decstring; - mpd_ssize_t n_int, n_rest; - - /* original numeric string */ - dp = result->data; - - /* sign */ - if (*dp == '+' || *dp == '-' || *dp == ' ') { - sign = dp++; - } - /* integer part */ - assert(isdigit((uchar)*dp)); - intpart = dp++; - while (isdigit((uchar)*dp)) { - dp++; - } - n_int = (mpd_ssize_t)(dp-intpart); - /* decimal point */ - if (*dp == '.') { - dp++; dot = spec->dot; - } - /* rest */ - rest = dp; - n_rest = result->nbytes - (mpd_ssize_t)(dp-result->data); - - if (dot == NULL && (*spec->sep == '\0' || *spec->grouping == '\0')) { - /* _mpd_add_sep_dot() would not change anything */ - return 1; - } - - /* Determine the size of the new decimal string after inserting the - * decimal point, optional separators and optional padding. */ - decstring = result->data; - result->data = NULL; - _mpd_add_sep_dot(result, sign, intpart, n_int, dot, - rest, n_rest, spec); - - result->data = mpd_alloc(result->nbytes+1, 1); - if (result->data == NULL) { - *status |= MPD_Malloc_error; - mpd_free(decstring); - return 0; - } - - /* Perform actual writes. */ - _mpd_add_sep_dot(result, sign, intpart, n_int, dot, - rest, n_rest, spec); - - mpd_free(decstring); - return 1; -} - -/* Add padding to the formatted string if necessary. */ -static int -_mpd_add_pad(mpd_mbstr_t *result, const mpd_spec_t *spec, uint32_t *status) -{ - if (result->nchars < spec->min_width) { - mpd_ssize_t add_chars, add_bytes; - size_t lpad = 0, rpad = 0; - size_t n_fill, len, i, j; - char align = spec->align; - uint8_t err = 0; - char *cp; - - n_fill = strlen(spec->fill); - add_chars = (spec->min_width - result->nchars); - /* max value: MPD_MAX_PREC * 4 */ - add_bytes = add_chars * (mpd_ssize_t)n_fill; - - cp = result->data = mpd_realloc(result->data, - result->nbytes+add_bytes+1, - sizeof *result->data, &err); - if (err) { - *status |= MPD_Malloc_error; - mpd_free(result->data); - return 0; - } - - if (align == 'z') { - align = '='; - } - - if (align == '<') { - rpad = add_chars; - } - else if (align == '>' || align == '=') { - lpad = add_chars; - } - else { /* align == '^' */ - lpad = add_chars/2; - rpad = add_chars-lpad; - } - - len = result->nbytes; - if (align == '=' && (*cp == '-' || *cp == '+' || *cp == ' ')) { - /* leave sign in the leading position */ - cp++; len--; - } - - memmove(cp+n_fill*lpad, cp, len); - for (i = 0; i < lpad; i++) { - for (j = 0; j < n_fill; j++) { - cp[i*n_fill+j] = spec->fill[j]; - } - } - cp += (n_fill*lpad + len); - for (i = 0; i < rpad; i++) { - for (j = 0; j < n_fill; j++) { - cp[i*n_fill+j] = spec->fill[j]; - } - } - - result->nbytes += add_bytes; - result->nchars += add_chars; - result->data[result->nbytes] = '\0'; - } - - return 1; -} - -/* Round a number to prec digits. The adjusted exponent stays the same - or increases by one if rounding up crosses a power of ten boundary. - If result->digits would exceed MPD_MAX_PREC+1, MPD_Invalid_operation - is set and the result is NaN. */ -static inline void -_mpd_round(mpd_t *result, const mpd_t *a, mpd_ssize_t prec, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_ssize_t exp = a->exp + a->digits - prec; - - if (prec <= 0) { - mpd_seterror(result, MPD_Invalid_operation, status); /* GCOV_NOT_REACHED */ - return; /* GCOV_NOT_REACHED */ - } - if (mpd_isspecial(a) || mpd_iszero(a)) { - mpd_qcopy(result, a, status); /* GCOV_NOT_REACHED */ - return; /* GCOV_NOT_REACHED */ - } - - mpd_qrescale_fmt(result, a, exp, ctx, status); - if (result->digits > prec) { - mpd_qrescale_fmt(result, result, exp+1, ctx, status); - } -} - -/* - * Return the string representation of an mpd_t, formatted according to 'spec'. - * The format specification is assumed to be valid. Memory errors are indicated - * as usual. This function is quiet. - */ -char * -mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_uint_t dt[MPD_MINALLOC_MAX]; - mpd_t tmp = {MPD_STATIC|MPD_STATIC_DATA,0,0,0,MPD_MINALLOC_MAX,dt}; - mpd_ssize_t dplace = MPD_DEFAULT_DOTPLACE; - mpd_mbstr_t result; - mpd_spec_t stackspec; - char type = spec->type; - int flags = 0; - - - if (spec->min_width > MPD_MAX_PREC) { - *status |= MPD_Invalid_operation; - return NULL; - } - - if (isupper((uchar)type)) { + dplace += mod_mpd_ssize_t(ldigits-1, 3); + } + } + + /* + * Basic space requirements: + * + * [-][.][coeffdigits][E][-][expdigits+1][%]['\0'] + * + * If the decimal point lies outside of the coefficient digits, + * space is adjusted accordingly. + */ + if (dplace <= 0) { + mem = -dplace + dec->digits + 2; + } + else if (dplace >= dec->digits) { + mem = dplace; + } + else { + mem = dec->digits; + } + mem += (MPD_EXPDIGITS+1+6); + + cp = decstring = mpd_alloc(mem, sizeof *decstring); + if (cp == NULL) { + *result = NULL; + return -1; + } + + + if (mpd_isnegative(dec)) { + *cp++ = '-'; + } + else if (flags&MPD_FMT_SIGN_SPACE) { + *cp++ = ' '; + } + else if (flags&MPD_FMT_SIGN_PLUS) { + *cp++ = '+'; + } + + if (dplace <= 0) { + /* space: -dplace+dec->digits+2 */ + *cp++ = '0'; + *cp++ = '.'; + for (k = 0; k < -dplace; k++) { + *cp++ = '0'; + } + cp = coeff_to_string(cp, dec); + } + else if (dplace >= dec->digits) { + /* space: dplace */ + cp = coeff_to_string(cp, dec); + for (k = 0; k < dplace-dec->digits; k++) { + *cp++ = '0'; + } + } + else { + /* space: dec->digits+1 */ + cp = coeff_to_string_dot(cp, cp+dplace, dec); + } + + /* + * Conditions for printing an exponent: + * + * MPD_FMT_TOSCI, MPD_FMT_TOENG: only if ldigits != dplace + * MPD_FMT_FIXED: never (ldigits == dplace) + * MPD_FMT_EXP: always + */ + if (ldigits != dplace || flags&MPD_FMT_EXP) { + /* space: expdigits+2 */ + *cp++ = (flags&MPD_FMT_UPPER) ? 'E' : 'e'; + cp = exp_to_string(cp, ldigits-dplace); + } + } + + if (flags&MPD_FMT_PERCENT) { + *cp++ = '%'; + } + + assert(cp < decstring+mem); + assert(cp-decstring < MPD_SSIZE_MAX); + + *cp = '\0'; + *result = decstring; + return (mpd_ssize_t)(cp-decstring); +} + +char * +mpd_to_sci(const mpd_t *dec, int fmt) +{ + char *res; + int flags = MPD_FMT_TOSCI; + + flags |= fmt ? MPD_FMT_UPPER : MPD_FMT_LOWER; + (void)_mpd_to_string(&res, dec, flags, MPD_DEFAULT_DOTPLACE); + return res; +} + +char * +mpd_to_eng(const mpd_t *dec, int fmt) +{ + char *res; + int flags = MPD_FMT_TOENG; + + flags |= fmt ? MPD_FMT_UPPER : MPD_FMT_LOWER; + (void)_mpd_to_string(&res, dec, flags, MPD_DEFAULT_DOTPLACE); + return res; +} + +mpd_ssize_t +mpd_to_sci_size(char **res, const mpd_t *dec, int fmt) +{ + int flags = MPD_FMT_TOSCI; + + flags |= fmt ? MPD_FMT_UPPER : MPD_FMT_LOWER; + return _mpd_to_string(res, dec, flags, MPD_DEFAULT_DOTPLACE); +} + +mpd_ssize_t +mpd_to_eng_size(char **res, const mpd_t *dec, int fmt) +{ + int flags = MPD_FMT_TOENG; + + flags |= fmt ? MPD_FMT_UPPER : MPD_FMT_LOWER; + return _mpd_to_string(res, dec, flags, MPD_DEFAULT_DOTPLACE); +} + +/* Copy a single UTF-8 char to dest. See: The Unicode Standard, version 5.2, + chapter 3.9: Well-formed UTF-8 byte sequences. */ +static int +_mpd_copy_utf8(char dest[5], const char *s) +{ + const uchar *cp = (const uchar *)s; + uchar lb, ub; + int count, i; + + + if (*cp == 0) { + /* empty string */ + dest[0] = '\0'; + return 0; + } + else if (*cp <= 0x7f) { + /* ascii */ + dest[0] = *cp; + dest[1] = '\0'; + return 1; + } + else if (0xc2 <= *cp && *cp <= 0xdf) { + lb = 0x80; ub = 0xbf; + count = 2; + } + else if (*cp == 0xe0) { + lb = 0xa0; ub = 0xbf; + count = 3; + } + else if (*cp <= 0xec) { + lb = 0x80; ub = 0xbf; + count = 3; + } + else if (*cp == 0xed) { + lb = 0x80; ub = 0x9f; + count = 3; + } + else if (*cp <= 0xef) { + lb = 0x80; ub = 0xbf; + count = 3; + } + else if (*cp == 0xf0) { + lb = 0x90; ub = 0xbf; + count = 4; + } + else if (*cp <= 0xf3) { + lb = 0x80; ub = 0xbf; + count = 4; + } + else if (*cp == 0xf4) { + lb = 0x80; ub = 0x8f; + count = 4; + } + else { + /* invalid */ + goto error; + } + + dest[0] = *cp++; + if (*cp < lb || ub < *cp) { + goto error; + } + dest[1] = *cp++; + for (i = 2; i < count; i++) { + if (*cp < 0x80 || 0xbf < *cp) { + goto error; + } + dest[i] = *cp++; + } + dest[i] = '\0'; + + return count; + +error: + dest[0] = '\0'; + return -1; +} + +int +mpd_validate_lconv(mpd_spec_t *spec) +{ + size_t n; +#if CHAR_MAX == SCHAR_MAX + const char *cp = spec->grouping; + while (*cp != '\0') { + if (*cp++ < 0) { + return -1; + } + } +#endif + n = strlen(spec->dot); + if (n == 0 || n > 4) { + return -1; + } + if (strlen(spec->sep) > 4) { + return -1; + } + + return 0; +} + +int +mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps) +{ + char *cp = (char *)fmt; + int have_align = 0, n; + + /* defaults */ + spec->min_width = 0; + spec->prec = -1; + spec->type = caps ? 'G' : 'g'; + spec->align = '>'; + spec->sign = '-'; + spec->dot = ""; + spec->sep = ""; + spec->grouping = ""; + + + /* presume that the first character is a UTF-8 fill character */ + if ((n = _mpd_copy_utf8(spec->fill, cp)) < 0) { + return 0; + } + + /* alignment directive, prefixed by a fill character */ + if (*cp && (*(cp+n) == '<' || *(cp+n) == '>' || + *(cp+n) == '=' || *(cp+n) == '^')) { + cp += n; + spec->align = *cp++; + have_align = 1; + } /* alignment directive */ + else { + /* default fill character */ + spec->fill[0] = ' '; + spec->fill[1] = '\0'; + if (*cp == '<' || *cp == '>' || + *cp == '=' || *cp == '^') { + spec->align = *cp++; + have_align = 1; + } + } + + /* sign formatting */ + if (*cp == '+' || *cp == '-' || *cp == ' ') { + spec->sign = *cp++; + } + + /* zero padding */ + if (*cp == '0') { + /* zero padding implies alignment, which should not be + * specified twice. */ + if (have_align) { + return 0; + } + spec->align = 'z'; + spec->fill[0] = *cp++; + spec->fill[1] = '\0'; + } + + /* minimum width */ + if (isdigit((uchar)*cp)) { + if (*cp == '0') { + return 0; + } + errno = 0; + spec->min_width = mpd_strtossize(cp, &cp, 10); + if (errno == ERANGE || errno == EINVAL) { + return 0; + } + } + + /* thousands separator */ + if (*cp == ',') { + spec->dot = "."; + spec->sep = ","; + spec->grouping = "\003\003"; + cp++; + } + + /* fraction digits or significant digits */ + if (*cp == '.') { + cp++; + if (!isdigit((uchar)*cp)) { + return 0; + } + errno = 0; + spec->prec = mpd_strtossize(cp, &cp, 10); + if (errno == ERANGE || errno == EINVAL) { + return 0; + } + } + + /* type */ + if (*cp == 'E' || *cp == 'e' || *cp == 'F' || *cp == 'f' || + *cp == 'G' || *cp == 'g' || *cp == '%') { + spec->type = *cp++; + } + else if (*cp == 'N' || *cp == 'n') { + /* locale specific conversion */ + struct lconv *lc; + /* separator has already been specified */ + if (*spec->sep) { + return 0; + } + spec->type = *cp++; + spec->type = (spec->type == 'N') ? 'G' : 'g'; + lc = localeconv(); + spec->dot = lc->decimal_point; + spec->sep = lc->thousands_sep; + spec->grouping = lc->grouping; + if (mpd_validate_lconv(spec) < 0) { + return 0; /* GCOV_NOT_REACHED */ + } + } + + /* check correctness */ + if (*cp != '\0') { + return 0; + } + + return 1; +} + +/* + * The following functions assume that spec->min_width <= MPD_MAX_PREC, which + * is made sure in mpd_qformat_spec. Then, even with a spec that inserts a + * four-byte separator after each digit, nbytes in the following struct + * cannot overflow. + */ + +/* Multibyte string */ +typedef struct { + mpd_ssize_t nbytes; /* length in bytes */ + mpd_ssize_t nchars; /* length in chars */ + mpd_ssize_t cur; /* current write index */ + char *data; +} mpd_mbstr_t; + +static inline void +_mpd_bcopy(char *dest, const char *src, mpd_ssize_t n) +{ + while (--n >= 0) { + dest[n] = src[n]; + } +} + +static inline void +_mbstr_copy_char(mpd_mbstr_t *dest, const char *src, mpd_ssize_t n) +{ + dest->nbytes += n; + dest->nchars += (n > 0 ? 1 : 0); + dest->cur -= n; + + if (dest->data != NULL) { + _mpd_bcopy(dest->data+dest->cur, src, n); + } +} + +static inline void +_mbstr_copy_ascii(mpd_mbstr_t *dest, const char *src, mpd_ssize_t n) +{ + dest->nbytes += n; + dest->nchars += n; + dest->cur -= n; + + if (dest->data != NULL) { + _mpd_bcopy(dest->data+dest->cur, src, n); + } +} + +static inline void +_mbstr_copy_pad(mpd_mbstr_t *dest, mpd_ssize_t n) +{ + dest->nbytes += n; + dest->nchars += n; + dest->cur -= n; + + if (dest->data != NULL) { + char *cp = dest->data + dest->cur; + while (--n >= 0) { + cp[n] = '0'; + } + } +} + +/* + * Copy a numeric string to dest->data, adding separators in the integer + * part according to spec->grouping. If leading zero padding is enabled + * and the result is smaller than spec->min_width, continue adding zeros + * and separators until the minimum width is reached. + * + * The final length of dest->data is stored in dest->nbytes. The number + * of UTF-8 characters is stored in dest->nchars. + * + * First run (dest->data == NULL): determine the length of the result + * string and store it in dest->nbytes. + * + * Second run (write to dest->data): data is written in chunks and in + * reverse order, starting with the rest of the numeric string. + */ +static void +_mpd_add_sep_dot(mpd_mbstr_t *dest, + const char *sign, /* location of optional sign */ + const char *src, mpd_ssize_t n_src, /* integer part and length */ + const char *dot, /* location of optional decimal point */ + const char *rest, mpd_ssize_t n_rest, /* remaining part and length */ + const mpd_spec_t *spec) +{ + mpd_ssize_t n_sep, n_sign, consume; + const char *g; + int pad = 0; + + n_sign = sign ? 1 : 0; + n_sep = (mpd_ssize_t)strlen(spec->sep); + /* Initial write index: set to location of '\0' in the output string. + * Irrelevant for the first run. */ + dest->cur = dest->nbytes; + dest->nbytes = dest->nchars = 0; + + _mbstr_copy_ascii(dest, rest, n_rest); + + if (dot) { + _mbstr_copy_char(dest, dot, (mpd_ssize_t)strlen(dot)); + } + + g = spec->grouping; + consume = *g; + while (1) { + /* If the group length is 0 or CHAR_MAX or greater than the + * number of source bytes, consume all remaining bytes. */ + if (*g == 0 || *g == CHAR_MAX || consume > n_src) { + consume = n_src; + } + n_src -= consume; + if (pad) { + _mbstr_copy_pad(dest, consume); + } + else { + _mbstr_copy_ascii(dest, src+n_src, consume); + } + + if (n_src == 0) { + /* Either the real source of intpart digits or the virtual + * source of padding zeros is exhausted. */ + if (spec->align == 'z' && + dest->nchars + n_sign < spec->min_width) { + /* Zero padding is set and length < min_width: + * Generate n_src additional characters. */ + n_src = spec->min_width - (dest->nchars + n_sign); + /* Next iteration: + * case *g == 0 || *g == CHAR_MAX: + * consume all padding characters + * case consume < g*: + * fill remainder of current group + * case consume == g* + * copying is a no-op */ + consume = *g - consume; + /* Switch on virtual source of zeros. */ + pad = 1; + continue; + } + break; + } + + if (n_sep > 0) { + /* If padding is switched on, separators are counted + * as padding characters. This rule does not apply if + * the separator would be the first character of the + * result string. */ + if (pad && n_src > 1) n_src -= 1; + _mbstr_copy_char(dest, spec->sep, n_sep); + } + + /* If non-NUL, use the next value for grouping. */ + if (*g && *(g+1)) g++; + consume = *g; + } + + if (sign) { + _mbstr_copy_ascii(dest, sign, 1); + } + + if (dest->data) { + dest->data[dest->nbytes] = '\0'; + } +} + +/* + * Convert a numeric-string to its locale-specific appearance. + * The string must have one of these forms: + * + * 1) [sign] digits [exponent-part] + * 2) [sign] digits '.' [digits] [exponent-part] + * + * Not allowed, since _mpd_to_string() never returns this form: + * + * 3) [sign] '.' digits [exponent-part] + * + * Input: result->data := original numeric string (ASCII) + * result->bytes := strlen(result->data) + * result->nchars := strlen(result->data) + * + * Output: result->data := modified or original string + * result->bytes := strlen(result->data) + * result->nchars := number of characters (possibly UTF-8) + */ +static int +_mpd_apply_lconv(mpd_mbstr_t *result, const mpd_spec_t *spec, uint32_t *status) +{ + const char *sign = NULL, *intpart = NULL, *dot = NULL; + const char *rest, *dp; + char *decstring; + mpd_ssize_t n_int, n_rest; + + /* original numeric string */ + dp = result->data; + + /* sign */ + if (*dp == '+' || *dp == '-' || *dp == ' ') { + sign = dp++; + } + /* integer part */ + assert(isdigit((uchar)*dp)); + intpart = dp++; + while (isdigit((uchar)*dp)) { + dp++; + } + n_int = (mpd_ssize_t)(dp-intpart); + /* decimal point */ + if (*dp == '.') { + dp++; dot = spec->dot; + } + /* rest */ + rest = dp; + n_rest = result->nbytes - (mpd_ssize_t)(dp-result->data); + + if (dot == NULL && (*spec->sep == '\0' || *spec->grouping == '\0')) { + /* _mpd_add_sep_dot() would not change anything */ + return 1; + } + + /* Determine the size of the new decimal string after inserting the + * decimal point, optional separators and optional padding. */ + decstring = result->data; + result->data = NULL; + _mpd_add_sep_dot(result, sign, intpart, n_int, dot, + rest, n_rest, spec); + + result->data = mpd_alloc(result->nbytes+1, 1); + if (result->data == NULL) { + *status |= MPD_Malloc_error; + mpd_free(decstring); + return 0; + } + + /* Perform actual writes. */ + _mpd_add_sep_dot(result, sign, intpart, n_int, dot, + rest, n_rest, spec); + + mpd_free(decstring); + return 1; +} + +/* Add padding to the formatted string if necessary. */ +static int +_mpd_add_pad(mpd_mbstr_t *result, const mpd_spec_t *spec, uint32_t *status) +{ + if (result->nchars < spec->min_width) { + mpd_ssize_t add_chars, add_bytes; + size_t lpad = 0, rpad = 0; + size_t n_fill, len, i, j; + char align = spec->align; + uint8_t err = 0; + char *cp; + + n_fill = strlen(spec->fill); + add_chars = (spec->min_width - result->nchars); + /* max value: MPD_MAX_PREC * 4 */ + add_bytes = add_chars * (mpd_ssize_t)n_fill; + + cp = result->data = mpd_realloc(result->data, + result->nbytes+add_bytes+1, + sizeof *result->data, &err); + if (err) { + *status |= MPD_Malloc_error; + mpd_free(result->data); + return 0; + } + + if (align == 'z') { + align = '='; + } + + if (align == '<') { + rpad = add_chars; + } + else if (align == '>' || align == '=') { + lpad = add_chars; + } + else { /* align == '^' */ + lpad = add_chars/2; + rpad = add_chars-lpad; + } + + len = result->nbytes; + if (align == '=' && (*cp == '-' || *cp == '+' || *cp == ' ')) { + /* leave sign in the leading position */ + cp++; len--; + } + + memmove(cp+n_fill*lpad, cp, len); + for (i = 0; i < lpad; i++) { + for (j = 0; j < n_fill; j++) { + cp[i*n_fill+j] = spec->fill[j]; + } + } + cp += (n_fill*lpad + len); + for (i = 0; i < rpad; i++) { + for (j = 0; j < n_fill; j++) { + cp[i*n_fill+j] = spec->fill[j]; + } + } + + result->nbytes += add_bytes; + result->nchars += add_chars; + result->data[result->nbytes] = '\0'; + } + + return 1; +} + +/* Round a number to prec digits. The adjusted exponent stays the same + or increases by one if rounding up crosses a power of ten boundary. + If result->digits would exceed MPD_MAX_PREC+1, MPD_Invalid_operation + is set and the result is NaN. */ +static inline void +_mpd_round(mpd_t *result, const mpd_t *a, mpd_ssize_t prec, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_ssize_t exp = a->exp + a->digits - prec; + + if (prec <= 0) { + mpd_seterror(result, MPD_Invalid_operation, status); /* GCOV_NOT_REACHED */ + return; /* GCOV_NOT_REACHED */ + } + if (mpd_isspecial(a) || mpd_iszero(a)) { + mpd_qcopy(result, a, status); /* GCOV_NOT_REACHED */ + return; /* GCOV_NOT_REACHED */ + } + + mpd_qrescale_fmt(result, a, exp, ctx, status); + if (result->digits > prec) { + mpd_qrescale_fmt(result, result, exp+1, ctx, status); + } +} + +/* + * Return the string representation of an mpd_t, formatted according to 'spec'. + * The format specification is assumed to be valid. Memory errors are indicated + * as usual. This function is quiet. + */ +char * +mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_uint_t dt[MPD_MINALLOC_MAX]; + mpd_t tmp = {MPD_STATIC|MPD_STATIC_DATA,0,0,0,MPD_MINALLOC_MAX,dt}; + mpd_ssize_t dplace = MPD_DEFAULT_DOTPLACE; + mpd_mbstr_t result; + mpd_spec_t stackspec; + char type = spec->type; + int flags = 0; + + + if (spec->min_width > MPD_MAX_PREC) { + *status |= MPD_Invalid_operation; + return NULL; + } + + if (isupper((uchar)type)) { type = (char)tolower((uchar)type); - flags |= MPD_FMT_UPPER; - } - if (spec->sign == ' ') { - flags |= MPD_FMT_SIGN_SPACE; - } - else if (spec->sign == '+') { - flags |= MPD_FMT_SIGN_PLUS; - } - - if (mpd_isspecial(dec)) { - if (spec->align == 'z') { - stackspec = *spec; - stackspec.fill[0] = ' '; - stackspec.fill[1] = '\0'; - stackspec.align = '>'; - spec = &stackspec; - } + flags |= MPD_FMT_UPPER; + } + if (spec->sign == ' ') { + flags |= MPD_FMT_SIGN_SPACE; + } + else if (spec->sign == '+') { + flags |= MPD_FMT_SIGN_PLUS; + } + + if (mpd_isspecial(dec)) { + if (spec->align == 'z') { + stackspec = *spec; + stackspec.fill[0] = ' '; + stackspec.fill[1] = '\0'; + stackspec.align = '>'; + spec = &stackspec; + } assert(strlen(spec->fill) == 1); /* annotation for scan-build */ - if (type == '%') { - flags |= MPD_FMT_PERCENT; - } - } - else { - uint32_t workstatus = 0; - mpd_ssize_t prec; - - switch (type) { - case 'g': flags |= MPD_FMT_TOSCI; break; - case 'e': flags |= MPD_FMT_EXP; break; - case '%': flags |= MPD_FMT_PERCENT; - if (!mpd_qcopy(&tmp, dec, status)) { - return NULL; - } - tmp.exp += 2; - dec = &tmp; - type = 'f'; /* fall through */ - case 'f': flags |= MPD_FMT_FIXED; break; - default: abort(); /* debug: GCOV_NOT_REACHED */ - } - - if (spec->prec >= 0) { - if (spec->prec > MPD_MAX_PREC) { - *status |= MPD_Invalid_operation; - goto error; - } - - switch (type) { - case 'g': - prec = (spec->prec == 0) ? 1 : spec->prec; - if (dec->digits > prec) { - _mpd_round(&tmp, dec, prec, ctx, - &workstatus); - dec = &tmp; - } - break; - case 'e': - if (mpd_iszero(dec)) { - dplace = 1-spec->prec; - } - else { - _mpd_round(&tmp, dec, spec->prec+1, ctx, - &workstatus); - dec = &tmp; - } - break; - case 'f': - mpd_qrescale(&tmp, dec, -spec->prec, ctx, - &workstatus); - dec = &tmp; - break; - } - } - - if (type == 'f') { - if (mpd_iszero(dec) && dec->exp > 0) { - mpd_qrescale(&tmp, dec, 0, ctx, &workstatus); - dec = &tmp; - } - } - - if (workstatus&MPD_Errors) { - *status |= (workstatus&MPD_Errors); - goto error; - } - } - - /* - * At this point, for all scaled or non-scaled decimals: - * 1) 1 <= digits <= MAX_PREC+1 - * 2) adjexp(scaled) = adjexp(orig) [+1] - * 3) case 'g': MIN_ETINY <= exp <= MAX_EMAX+1 - * case 'e': MIN_ETINY-MAX_PREC <= exp <= MAX_EMAX+1 - * case 'f': MIN_ETINY <= exp <= MAX_EMAX+1 - * 4) max memory alloc in _mpd_to_string: - * case 'g': MAX_PREC+36 - * case 'e': MAX_PREC+36 - * case 'f': 2*MPD_MAX_PREC+30 - */ - result.nbytes = _mpd_to_string(&result.data, dec, flags, dplace); - result.nchars = result.nbytes; - if (result.nbytes < 0) { - *status |= MPD_Malloc_error; - goto error; - } - - if (*spec->dot != '\0' && !mpd_isspecial(dec)) { - if (result.nchars > MPD_MAX_PREC+36) { - /* Since a group length of one is not explicitly - * disallowed, ensure that it is always possible to - * insert a four byte separator after each digit. */ - *status |= MPD_Invalid_operation; - mpd_free(result.data); - goto error; - } - if (!_mpd_apply_lconv(&result, spec, status)) { - goto error; - } - } - - if (spec->min_width) { - if (!_mpd_add_pad(&result, spec, status)) { - goto error; - } - } - - mpd_del(&tmp); - return result.data; - -error: - mpd_del(&tmp); - return NULL; -} - -char * -mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_spec_t spec; - - if (!mpd_parse_fmt_str(&spec, fmt, 1)) { - *status |= MPD_Invalid_operation; - return NULL; - } - - return mpd_qformat_spec(dec, &spec, ctx, status); -} - -/* - * The specification has a *condition* called Invalid_operation and an - * IEEE *signal* called Invalid_operation. The former corresponds to - * MPD_Invalid_operation, the latter to MPD_IEEE_Invalid_operation. - * MPD_IEEE_Invalid_operation comprises the following conditions: - * - * [MPD_Conversion_syntax, MPD_Division_impossible, MPD_Division_undefined, - * MPD_Fpu_error, MPD_Invalid_context, MPD_Invalid_operation, - * MPD_Malloc_error] - * - * In the following functions, 'flag' denotes the condition, 'signal' - * denotes the IEEE signal. - */ - -static const char *mpd_flag_string[MPD_NUM_FLAGS] = { - "Clamped", - "Conversion_syntax", - "Division_by_zero", - "Division_impossible", - "Division_undefined", - "Fpu_error", - "Inexact", - "Invalid_context", - "Invalid_operation", - "Malloc_error", - "Not_implemented", - "Overflow", - "Rounded", - "Subnormal", - "Underflow", -}; - -static const char *mpd_signal_string[MPD_NUM_FLAGS] = { - "Clamped", - "IEEE_Invalid_operation", - "Division_by_zero", - "IEEE_Invalid_operation", - "IEEE_Invalid_operation", - "IEEE_Invalid_operation", - "Inexact", - "IEEE_Invalid_operation", - "IEEE_Invalid_operation", - "IEEE_Invalid_operation", - "Not_implemented", - "Overflow", - "Rounded", - "Subnormal", - "Underflow", -}; - -/* print conditions to buffer, separated by spaces */ -int -mpd_snprint_flags(char *dest, int nmemb, uint32_t flags) -{ - char *cp; - int n, j; - - assert(nmemb >= MPD_MAX_FLAG_STRING); - - *dest = '\0'; cp = dest; - for (j = 0; j < MPD_NUM_FLAGS; j++) { - if (flags & (1U<= nmemb) return -1; - cp += n; nmemb -= n; - } - } - - if (cp != dest) { - *(--cp) = '\0'; - } - - return (int)(cp-dest); -} - -/* print conditions to buffer, in list form */ -int -mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char *flag_string[]) -{ - char *cp; - int n, j; - - assert(nmemb >= MPD_MAX_FLAG_LIST); - if (flag_string == NULL) { - flag_string = mpd_flag_string; - } - - *dest = '['; - *(dest+1) = '\0'; - cp = dest+1; - --nmemb; - - for (j = 0; j < MPD_NUM_FLAGS; j++) { - if (flags & (1U<= nmemb) return -1; - cp += n; nmemb -= n; - } - } - - /* erase the last ", " */ - if (cp != dest+1) { - cp -= 2; - } - - *cp++ = ']'; - *cp = '\0'; - - return (int)(cp-dest); /* strlen, without NUL terminator */ -} - -/* print signals to buffer, in list form */ -int -mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_string[]) -{ - char *cp; - int n, j; - int ieee_invalid_done = 0; - - assert(nmemb >= MPD_MAX_SIGNAL_LIST); - if (signal_string == NULL) { - signal_string = mpd_signal_string; - } - - *dest = '['; - *(dest+1) = '\0'; - cp = dest+1; - --nmemb; - - for (j = 0; j < MPD_NUM_FLAGS; j++) { - uint32_t f = flags & (1U<= nmemb) return -1; - cp += n; nmemb -= n; - } - } - - /* erase the last ", " */ - if (cp != dest+1) { - cp -= 2; - } - - *cp++ = ']'; - *cp = '\0'; - - return (int)(cp-dest); /* strlen, without NUL terminator */ -} - -/* The following two functions are mainly intended for debugging. */ -void -mpd_fprint(FILE *file, const mpd_t *dec) -{ - char *decstring; - - decstring = mpd_to_sci(dec, 1); - if (decstring != NULL) { - fprintf(file, "%s\n", decstring); - mpd_free(decstring); - } - else { - fputs("mpd_fprint: output error\n", file); /* GCOV_NOT_REACHED */ - } -} - -void -mpd_print(const mpd_t *dec) -{ - char *decstring; - - decstring = mpd_to_sci(dec, 1); - if (decstring != NULL) { - printf("%s\n", decstring); - mpd_free(decstring); - } - else { - fputs("mpd_fprint: output error\n", stderr); /* GCOV_NOT_REACHED */ - } -} + if (type == '%') { + flags |= MPD_FMT_PERCENT; + } + } + else { + uint32_t workstatus = 0; + mpd_ssize_t prec; + + switch (type) { + case 'g': flags |= MPD_FMT_TOSCI; break; + case 'e': flags |= MPD_FMT_EXP; break; + case '%': flags |= MPD_FMT_PERCENT; + if (!mpd_qcopy(&tmp, dec, status)) { + return NULL; + } + tmp.exp += 2; + dec = &tmp; + type = 'f'; /* fall through */ + case 'f': flags |= MPD_FMT_FIXED; break; + default: abort(); /* debug: GCOV_NOT_REACHED */ + } + + if (spec->prec >= 0) { + if (spec->prec > MPD_MAX_PREC) { + *status |= MPD_Invalid_operation; + goto error; + } + + switch (type) { + case 'g': + prec = (spec->prec == 0) ? 1 : spec->prec; + if (dec->digits > prec) { + _mpd_round(&tmp, dec, prec, ctx, + &workstatus); + dec = &tmp; + } + break; + case 'e': + if (mpd_iszero(dec)) { + dplace = 1-spec->prec; + } + else { + _mpd_round(&tmp, dec, spec->prec+1, ctx, + &workstatus); + dec = &tmp; + } + break; + case 'f': + mpd_qrescale(&tmp, dec, -spec->prec, ctx, + &workstatus); + dec = &tmp; + break; + } + } + + if (type == 'f') { + if (mpd_iszero(dec) && dec->exp > 0) { + mpd_qrescale(&tmp, dec, 0, ctx, &workstatus); + dec = &tmp; + } + } + + if (workstatus&MPD_Errors) { + *status |= (workstatus&MPD_Errors); + goto error; + } + } + + /* + * At this point, for all scaled or non-scaled decimals: + * 1) 1 <= digits <= MAX_PREC+1 + * 2) adjexp(scaled) = adjexp(orig) [+1] + * 3) case 'g': MIN_ETINY <= exp <= MAX_EMAX+1 + * case 'e': MIN_ETINY-MAX_PREC <= exp <= MAX_EMAX+1 + * case 'f': MIN_ETINY <= exp <= MAX_EMAX+1 + * 4) max memory alloc in _mpd_to_string: + * case 'g': MAX_PREC+36 + * case 'e': MAX_PREC+36 + * case 'f': 2*MPD_MAX_PREC+30 + */ + result.nbytes = _mpd_to_string(&result.data, dec, flags, dplace); + result.nchars = result.nbytes; + if (result.nbytes < 0) { + *status |= MPD_Malloc_error; + goto error; + } + + if (*spec->dot != '\0' && !mpd_isspecial(dec)) { + if (result.nchars > MPD_MAX_PREC+36) { + /* Since a group length of one is not explicitly + * disallowed, ensure that it is always possible to + * insert a four byte separator after each digit. */ + *status |= MPD_Invalid_operation; + mpd_free(result.data); + goto error; + } + if (!_mpd_apply_lconv(&result, spec, status)) { + goto error; + } + } + + if (spec->min_width) { + if (!_mpd_add_pad(&result, spec, status)) { + goto error; + } + } + + mpd_del(&tmp); + return result.data; + +error: + mpd_del(&tmp); + return NULL; +} + +char * +mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_spec_t spec; + + if (!mpd_parse_fmt_str(&spec, fmt, 1)) { + *status |= MPD_Invalid_operation; + return NULL; + } + + return mpd_qformat_spec(dec, &spec, ctx, status); +} + +/* + * The specification has a *condition* called Invalid_operation and an + * IEEE *signal* called Invalid_operation. The former corresponds to + * MPD_Invalid_operation, the latter to MPD_IEEE_Invalid_operation. + * MPD_IEEE_Invalid_operation comprises the following conditions: + * + * [MPD_Conversion_syntax, MPD_Division_impossible, MPD_Division_undefined, + * MPD_Fpu_error, MPD_Invalid_context, MPD_Invalid_operation, + * MPD_Malloc_error] + * + * In the following functions, 'flag' denotes the condition, 'signal' + * denotes the IEEE signal. + */ + +static const char *mpd_flag_string[MPD_NUM_FLAGS] = { + "Clamped", + "Conversion_syntax", + "Division_by_zero", + "Division_impossible", + "Division_undefined", + "Fpu_error", + "Inexact", + "Invalid_context", + "Invalid_operation", + "Malloc_error", + "Not_implemented", + "Overflow", + "Rounded", + "Subnormal", + "Underflow", +}; + +static const char *mpd_signal_string[MPD_NUM_FLAGS] = { + "Clamped", + "IEEE_Invalid_operation", + "Division_by_zero", + "IEEE_Invalid_operation", + "IEEE_Invalid_operation", + "IEEE_Invalid_operation", + "Inexact", + "IEEE_Invalid_operation", + "IEEE_Invalid_operation", + "IEEE_Invalid_operation", + "Not_implemented", + "Overflow", + "Rounded", + "Subnormal", + "Underflow", +}; + +/* print conditions to buffer, separated by spaces */ +int +mpd_snprint_flags(char *dest, int nmemb, uint32_t flags) +{ + char *cp; + int n, j; + + assert(nmemb >= MPD_MAX_FLAG_STRING); + + *dest = '\0'; cp = dest; + for (j = 0; j < MPD_NUM_FLAGS; j++) { + if (flags & (1U<= nmemb) return -1; + cp += n; nmemb -= n; + } + } + + if (cp != dest) { + *(--cp) = '\0'; + } + + return (int)(cp-dest); +} + +/* print conditions to buffer, in list form */ +int +mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char *flag_string[]) +{ + char *cp; + int n, j; + + assert(nmemb >= MPD_MAX_FLAG_LIST); + if (flag_string == NULL) { + flag_string = mpd_flag_string; + } + + *dest = '['; + *(dest+1) = '\0'; + cp = dest+1; + --nmemb; + + for (j = 0; j < MPD_NUM_FLAGS; j++) { + if (flags & (1U<= nmemb) return -1; + cp += n; nmemb -= n; + } + } + + /* erase the last ", " */ + if (cp != dest+1) { + cp -= 2; + } + + *cp++ = ']'; + *cp = '\0'; + + return (int)(cp-dest); /* strlen, without NUL terminator */ +} + +/* print signals to buffer, in list form */ +int +mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_string[]) +{ + char *cp; + int n, j; + int ieee_invalid_done = 0; + + assert(nmemb >= MPD_MAX_SIGNAL_LIST); + if (signal_string == NULL) { + signal_string = mpd_signal_string; + } + + *dest = '['; + *(dest+1) = '\0'; + cp = dest+1; + --nmemb; + + for (j = 0; j < MPD_NUM_FLAGS; j++) { + uint32_t f = flags & (1U<= nmemb) return -1; + cp += n; nmemb -= n; + } + } + + /* erase the last ", " */ + if (cp != dest+1) { + cp -= 2; + } + + *cp++ = ']'; + *cp = '\0'; + + return (int)(cp-dest); /* strlen, without NUL terminator */ +} + +/* The following two functions are mainly intended for debugging. */ +void +mpd_fprint(FILE *file, const mpd_t *dec) +{ + char *decstring; + + decstring = mpd_to_sci(dec, 1); + if (decstring != NULL) { + fprintf(file, "%s\n", decstring); + mpd_free(decstring); + } + else { + fputs("mpd_fprint: output error\n", file); /* GCOV_NOT_REACHED */ + } +} + +void +mpd_print(const mpd_t *dec) +{ + char *decstring; + + decstring = mpd_to_sci(dec, 1); + if (decstring != NULL) { + printf("%s\n", decstring); + mpd_free(decstring); + } + else { + fputs("mpd_fprint: output error\n", stderr); /* GCOV_NOT_REACHED */ + } +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.h index 186808457b2..c8f7bbdf17a 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpalloc.h @@ -1,53 +1,53 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_MPALLOC_H_ #define LIBMPDEC_MPALLOC_H_ - - -#include "mpdecimal.h" - + + +#include "mpdecimal.h" + #include - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); -int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); -int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); - + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); +int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); +int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); + int mpd_switch_to_dyn_cxx(mpd_t *result, mpd_ssize_t size); int mpd_realloc_dyn_cxx(mpd_t *result, mpd_ssize_t size); + - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_MPALLOC_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpd_io.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpd_io.h index 79d7c05ce36..c1eb06918d6 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpd_io.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpd_io.h @@ -1,62 +1,62 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_IO_H_ #define LIBMPDEC_IO_H_ - - -#include "mpdecimal.h" - + + +#include "mpdecimal.h" + #include + - -#if SIZE_MAX == MPD_SIZE_MAX - #define mpd_strtossize _mpd_strtossize -#else +#if SIZE_MAX == MPD_SIZE_MAX + #define mpd_strtossize _mpd_strtossize +#else #include -static inline mpd_ssize_t -mpd_strtossize(const char *s, char **end, int base) -{ - int64_t retval; - - errno = 0; - retval = _mpd_strtossize(s, end, base); - if (errno == 0 && (retval > MPD_SSIZE_MAX || retval < MPD_SSIZE_MIN)) { - errno = ERANGE; - } - if (errno == ERANGE) { - return (retval < 0) ? MPD_SSIZE_MIN : MPD_SSIZE_MAX; - } - - return (mpd_ssize_t)retval; -} -#endif - - +static inline mpd_ssize_t +mpd_strtossize(const char *s, char **end, int base) +{ + int64_t retval; + + errno = 0; + retval = _mpd_strtossize(s, end, base); + if (errno == 0 && (retval > MPD_SSIZE_MAX || retval < MPD_SSIZE_MIN)) { + errno = ERANGE; + } + if (errno == ERANGE) { + return (retval < 0) ? MPD_SSIZE_MIN : MPD_SSIZE_MAX; + } + + return (mpd_ssize_t)retval; +} +#endif + + #endif /* LIBMPDEC_IO_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.c index 28b639ccb40..7bef29482de 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.c @@ -1,521 +1,521 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" #include #include #include -#include -#include -#include +#include +#include +#include -#include "basearith.h" -#include "bits.h" +#include "basearith.h" +#include "bits.h" #include "constants.h" -#include "convolute.h" -#include "crt.h" -#include "mpalloc.h" -#include "typearith.h" - -#ifdef PPRO - #if defined(_MSC_VER) - #include - #pragma float_control(precise, on) - #pragma fenv_access(on) - #elif !defined(__OpenBSD__) && !defined(__NetBSD__) - /* C99 */ - #include - #pragma STDC FENV_ACCESS ON - #endif -#endif - - -/* Disable warning that is part of -Wextra since gcc 7.0. */ -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && __GNUC__ >= 7 - #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#endif - - -#if defined(_MSC_VER) - #define ALWAYS_INLINE __forceinline +#include "convolute.h" +#include "crt.h" +#include "mpalloc.h" +#include "typearith.h" + +#ifdef PPRO + #if defined(_MSC_VER) + #include + #pragma float_control(precise, on) + #pragma fenv_access(on) + #elif !defined(__OpenBSD__) && !defined(__NetBSD__) + /* C99 */ + #include + #pragma STDC FENV_ACCESS ON + #endif +#endif + + +/* Disable warning that is part of -Wextra since gcc 7.0. */ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && __GNUC__ >= 7 + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif + + +#if defined(_MSC_VER) + #define ALWAYS_INLINE __forceinline #elif defined(__IBMC__) || defined(LEGACY_COMPILER) - #define ALWAYS_INLINE - #undef inline - #define inline -#else - #ifdef TEST_COVERAGE - #define ALWAYS_INLINE - #else - #define ALWAYS_INLINE inline __attribute__ ((always_inline)) - #endif -#endif - - -#define MPD_NEWTONDIV_CUTOFF 1024L - -#define MPD_NEW_STATIC(name, flags, exp, digits, len) \ - mpd_uint_t name##_data[MPD_MINALLOC_MAX]; \ - mpd_t name = {flags|MPD_STATIC|MPD_STATIC_DATA, exp, digits, \ - len, MPD_MINALLOC_MAX, name##_data} - -#define MPD_NEW_CONST(name, flags, exp, digits, len, alloc, initval) \ - mpd_uint_t name##_data[alloc] = {initval}; \ - mpd_t name = {flags|MPD_STATIC|MPD_CONST_DATA, exp, digits, \ - len, alloc, name##_data} - -#define MPD_NEW_SHARED(name, a) \ - mpd_t name = {(a->flags&~MPD_DATAFLAGS)|MPD_STATIC|MPD_SHARED_DATA, \ - a->exp, a->digits, a->len, a->alloc, a->data} - - -static mpd_uint_t data_one[1] = {1}; -static mpd_uint_t data_zero[1] = {0}; -static const mpd_t one = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_one}; -static const mpd_t minus_one = {MPD_NEG|MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, - data_one}; -static const mpd_t zero = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_zero}; - -static inline void _mpd_check_exp(mpd_t *dec, const mpd_context_t *ctx, - uint32_t *status); -static void _settriple(mpd_t *result, uint8_t sign, mpd_uint_t a, - mpd_ssize_t exp); -static inline mpd_ssize_t _mpd_real_size(mpd_uint_t *data, mpd_ssize_t size); - -static int _mpd_cmp_abs(const mpd_t *a, const mpd_t *b); - -static void _mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status); -static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status); -static void _mpd_base_ndivmod(mpd_t *q, mpd_t *r, const mpd_t *a, - const mpd_t *b, uint32_t *status); -static inline void _mpd_qpow_uint(mpd_t *result, const mpd_t *base, - mpd_uint_t exp, uint8_t resultsign, - const mpd_context_t *ctx, uint32_t *status); - -static mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n); - - -/******************************************************************************/ -/* Version */ -/******************************************************************************/ - -const char * -mpd_version(void) -{ - return MPD_VERSION; -} - - -/******************************************************************************/ -/* Performance critical inline functions */ -/******************************************************************************/ - -#ifdef CONFIG_64 -/* Digits in a word, primarily useful for the most significant word. */ -ALWAYS_INLINE int -mpd_word_digits(mpd_uint_t word) -{ - if (word < mpd_pow10[9]) { - if (word < mpd_pow10[4]) { - if (word < mpd_pow10[2]) { - return (word < mpd_pow10[1]) ? 1 : 2; - } - return (word < mpd_pow10[3]) ? 3 : 4; - } - if (word < mpd_pow10[6]) { - return (word < mpd_pow10[5]) ? 5 : 6; - } - if (word < mpd_pow10[8]) { - return (word < mpd_pow10[7]) ? 7 : 8; - } - return 9; - } - if (word < mpd_pow10[14]) { - if (word < mpd_pow10[11]) { - return (word < mpd_pow10[10]) ? 10 : 11; - } - if (word < mpd_pow10[13]) { - return (word < mpd_pow10[12]) ? 12 : 13; - } - return 14; - } - if (word < mpd_pow10[18]) { - if (word < mpd_pow10[16]) { - return (word < mpd_pow10[15]) ? 15 : 16; - } - return (word < mpd_pow10[17]) ? 17 : 18; - } - - return (word < mpd_pow10[19]) ? 19 : 20; -} -#else -ALWAYS_INLINE int -mpd_word_digits(mpd_uint_t word) -{ - if (word < mpd_pow10[4]) { - if (word < mpd_pow10[2]) { - return (word < mpd_pow10[1]) ? 1 : 2; - } - return (word < mpd_pow10[3]) ? 3 : 4; - } - if (word < mpd_pow10[6]) { - return (word < mpd_pow10[5]) ? 5 : 6; - } - if (word < mpd_pow10[8]) { - return (word < mpd_pow10[7]) ? 7 : 8; - } - - return (word < mpd_pow10[9]) ? 9 : 10; -} -#endif - - -/* Adjusted exponent */ -ALWAYS_INLINE mpd_ssize_t -mpd_adjexp(const mpd_t *dec) -{ - return (dec->exp + dec->digits) - 1; -} - -/* Etiny */ -ALWAYS_INLINE mpd_ssize_t -mpd_etiny(const mpd_context_t *ctx) -{ - return ctx->emin - (ctx->prec - 1); -} - -/* Etop: used for folding down in IEEE clamping */ -ALWAYS_INLINE mpd_ssize_t -mpd_etop(const mpd_context_t *ctx) -{ - return ctx->emax - (ctx->prec - 1); -} - -/* Most significant word */ -ALWAYS_INLINE mpd_uint_t -mpd_msword(const mpd_t *dec) -{ - assert(dec->len > 0); - return dec->data[dec->len-1]; -} - -/* Most significant digit of a word */ -inline mpd_uint_t -mpd_msd(mpd_uint_t word) -{ - int n; - - n = mpd_word_digits(word); - return word / mpd_pow10[n-1]; -} - -/* Least significant digit of a word */ -ALWAYS_INLINE mpd_uint_t -mpd_lsd(mpd_uint_t word) -{ - return word % 10; -} - -/* Coefficient size needed to store 'digits' */ + #define ALWAYS_INLINE + #undef inline + #define inline +#else + #ifdef TEST_COVERAGE + #define ALWAYS_INLINE + #else + #define ALWAYS_INLINE inline __attribute__ ((always_inline)) + #endif +#endif + + +#define MPD_NEWTONDIV_CUTOFF 1024L + +#define MPD_NEW_STATIC(name, flags, exp, digits, len) \ + mpd_uint_t name##_data[MPD_MINALLOC_MAX]; \ + mpd_t name = {flags|MPD_STATIC|MPD_STATIC_DATA, exp, digits, \ + len, MPD_MINALLOC_MAX, name##_data} + +#define MPD_NEW_CONST(name, flags, exp, digits, len, alloc, initval) \ + mpd_uint_t name##_data[alloc] = {initval}; \ + mpd_t name = {flags|MPD_STATIC|MPD_CONST_DATA, exp, digits, \ + len, alloc, name##_data} + +#define MPD_NEW_SHARED(name, a) \ + mpd_t name = {(a->flags&~MPD_DATAFLAGS)|MPD_STATIC|MPD_SHARED_DATA, \ + a->exp, a->digits, a->len, a->alloc, a->data} + + +static mpd_uint_t data_one[1] = {1}; +static mpd_uint_t data_zero[1] = {0}; +static const mpd_t one = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_one}; +static const mpd_t minus_one = {MPD_NEG|MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, + data_one}; +static const mpd_t zero = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_zero}; + +static inline void _mpd_check_exp(mpd_t *dec, const mpd_context_t *ctx, + uint32_t *status); +static void _settriple(mpd_t *result, uint8_t sign, mpd_uint_t a, + mpd_ssize_t exp); +static inline mpd_ssize_t _mpd_real_size(mpd_uint_t *data, mpd_ssize_t size); + +static int _mpd_cmp_abs(const mpd_t *a, const mpd_t *b); + +static void _mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status); +static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status); +static void _mpd_base_ndivmod(mpd_t *q, mpd_t *r, const mpd_t *a, + const mpd_t *b, uint32_t *status); +static inline void _mpd_qpow_uint(mpd_t *result, const mpd_t *base, + mpd_uint_t exp, uint8_t resultsign, + const mpd_context_t *ctx, uint32_t *status); + +static mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n); + + +/******************************************************************************/ +/* Version */ +/******************************************************************************/ + +const char * +mpd_version(void) +{ + return MPD_VERSION; +} + + +/******************************************************************************/ +/* Performance critical inline functions */ +/******************************************************************************/ + +#ifdef CONFIG_64 +/* Digits in a word, primarily useful for the most significant word. */ +ALWAYS_INLINE int +mpd_word_digits(mpd_uint_t word) +{ + if (word < mpd_pow10[9]) { + if (word < mpd_pow10[4]) { + if (word < mpd_pow10[2]) { + return (word < mpd_pow10[1]) ? 1 : 2; + } + return (word < mpd_pow10[3]) ? 3 : 4; + } + if (word < mpd_pow10[6]) { + return (word < mpd_pow10[5]) ? 5 : 6; + } + if (word < mpd_pow10[8]) { + return (word < mpd_pow10[7]) ? 7 : 8; + } + return 9; + } + if (word < mpd_pow10[14]) { + if (word < mpd_pow10[11]) { + return (word < mpd_pow10[10]) ? 10 : 11; + } + if (word < mpd_pow10[13]) { + return (word < mpd_pow10[12]) ? 12 : 13; + } + return 14; + } + if (word < mpd_pow10[18]) { + if (word < mpd_pow10[16]) { + return (word < mpd_pow10[15]) ? 15 : 16; + } + return (word < mpd_pow10[17]) ? 17 : 18; + } + + return (word < mpd_pow10[19]) ? 19 : 20; +} +#else +ALWAYS_INLINE int +mpd_word_digits(mpd_uint_t word) +{ + if (word < mpd_pow10[4]) { + if (word < mpd_pow10[2]) { + return (word < mpd_pow10[1]) ? 1 : 2; + } + return (word < mpd_pow10[3]) ? 3 : 4; + } + if (word < mpd_pow10[6]) { + return (word < mpd_pow10[5]) ? 5 : 6; + } + if (word < mpd_pow10[8]) { + return (word < mpd_pow10[7]) ? 7 : 8; + } + + return (word < mpd_pow10[9]) ? 9 : 10; +} +#endif + + +/* Adjusted exponent */ +ALWAYS_INLINE mpd_ssize_t +mpd_adjexp(const mpd_t *dec) +{ + return (dec->exp + dec->digits) - 1; +} + +/* Etiny */ +ALWAYS_INLINE mpd_ssize_t +mpd_etiny(const mpd_context_t *ctx) +{ + return ctx->emin - (ctx->prec - 1); +} + +/* Etop: used for folding down in IEEE clamping */ +ALWAYS_INLINE mpd_ssize_t +mpd_etop(const mpd_context_t *ctx) +{ + return ctx->emax - (ctx->prec - 1); +} + +/* Most significant word */ +ALWAYS_INLINE mpd_uint_t +mpd_msword(const mpd_t *dec) +{ + assert(dec->len > 0); + return dec->data[dec->len-1]; +} + +/* Most significant digit of a word */ +inline mpd_uint_t +mpd_msd(mpd_uint_t word) +{ + int n; + + n = mpd_word_digits(word); + return word / mpd_pow10[n-1]; +} + +/* Least significant digit of a word */ +ALWAYS_INLINE mpd_uint_t +mpd_lsd(mpd_uint_t word) +{ + return word % 10; +} + +/* Coefficient size needed to store 'digits' */ mpd_ssize_t -mpd_digits_to_size(mpd_ssize_t digits) -{ - mpd_ssize_t q, r; - - _mpd_idiv_word(&q, &r, digits, MPD_RDIGITS); - return (r == 0) ? q : q+1; -} - -/* Number of digits in the exponent. Not defined for MPD_SSIZE_MIN. */ -inline int -mpd_exp_digits(mpd_ssize_t exp) -{ - exp = (exp < 0) ? -exp : exp; - return mpd_word_digits(exp); -} - -/* Canonical */ -ALWAYS_INLINE int +mpd_digits_to_size(mpd_ssize_t digits) +{ + mpd_ssize_t q, r; + + _mpd_idiv_word(&q, &r, digits, MPD_RDIGITS); + return (r == 0) ? q : q+1; +} + +/* Number of digits in the exponent. Not defined for MPD_SSIZE_MIN. */ +inline int +mpd_exp_digits(mpd_ssize_t exp) +{ + exp = (exp < 0) ? -exp : exp; + return mpd_word_digits(exp); +} + +/* Canonical */ +ALWAYS_INLINE int mpd_iscanonical(const mpd_t *dec) -{ +{ (void)dec; - return 1; -} - -/* Finite */ -ALWAYS_INLINE int -mpd_isfinite(const mpd_t *dec) -{ - return !(dec->flags & MPD_SPECIAL); -} - -/* Infinite */ -ALWAYS_INLINE int -mpd_isinfinite(const mpd_t *dec) -{ - return dec->flags & MPD_INF; -} - -/* NaN */ -ALWAYS_INLINE int -mpd_isnan(const mpd_t *dec) -{ - return dec->flags & (MPD_NAN|MPD_SNAN); -} - -/* Negative */ -ALWAYS_INLINE int -mpd_isnegative(const mpd_t *dec) -{ - return dec->flags & MPD_NEG; -} - -/* Positive */ -ALWAYS_INLINE int -mpd_ispositive(const mpd_t *dec) -{ - return !(dec->flags & MPD_NEG); -} - -/* qNaN */ -ALWAYS_INLINE int -mpd_isqnan(const mpd_t *dec) -{ - return dec->flags & MPD_NAN; -} - -/* Signed */ -ALWAYS_INLINE int -mpd_issigned(const mpd_t *dec) -{ - return dec->flags & MPD_NEG; -} - -/* sNaN */ -ALWAYS_INLINE int -mpd_issnan(const mpd_t *dec) -{ - return dec->flags & MPD_SNAN; -} - -/* Special */ -ALWAYS_INLINE int -mpd_isspecial(const mpd_t *dec) -{ - return dec->flags & MPD_SPECIAL; -} - -/* Zero */ -ALWAYS_INLINE int -mpd_iszero(const mpd_t *dec) -{ - return !mpd_isspecial(dec) && mpd_msword(dec) == 0; -} - -/* Test for zero when specials have been ruled out already */ -ALWAYS_INLINE int -mpd_iszerocoeff(const mpd_t *dec) -{ - return mpd_msword(dec) == 0; -} - -/* Normal */ -inline int -mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx) -{ - if (mpd_isspecial(dec)) return 0; - if (mpd_iszerocoeff(dec)) return 0; - - return mpd_adjexp(dec) >= ctx->emin; -} - -/* Subnormal */ -inline int -mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx) -{ - if (mpd_isspecial(dec)) return 0; - if (mpd_iszerocoeff(dec)) return 0; - - return mpd_adjexp(dec) < ctx->emin; -} - -/* Odd word */ -ALWAYS_INLINE int -mpd_isoddword(mpd_uint_t word) -{ - return word & 1; -} - -/* Odd coefficient */ -ALWAYS_INLINE int -mpd_isoddcoeff(const mpd_t *dec) -{ - return mpd_isoddword(dec->data[0]); -} - -/* 0 if dec is positive, 1 if dec is negative */ -ALWAYS_INLINE uint8_t -mpd_sign(const mpd_t *dec) -{ - return dec->flags & MPD_NEG; -} - -/* 1 if dec is positive, -1 if dec is negative */ -ALWAYS_INLINE int -mpd_arith_sign(const mpd_t *dec) -{ - return 1 - 2 * mpd_isnegative(dec); -} - -/* Radix */ -ALWAYS_INLINE long -mpd_radix(void) -{ - return 10; -} - -/* Dynamic decimal */ -ALWAYS_INLINE int -mpd_isdynamic(const mpd_t *dec) -{ - return !(dec->flags & MPD_STATIC); -} - -/* Static decimal */ -ALWAYS_INLINE int -mpd_isstatic(const mpd_t *dec) -{ - return dec->flags & MPD_STATIC; -} - -/* Data of decimal is dynamic */ -ALWAYS_INLINE int -mpd_isdynamic_data(const mpd_t *dec) -{ - return !(dec->flags & MPD_DATAFLAGS); -} - -/* Data of decimal is static */ -ALWAYS_INLINE int -mpd_isstatic_data(const mpd_t *dec) -{ - return dec->flags & MPD_STATIC_DATA; -} - -/* Data of decimal is shared */ -ALWAYS_INLINE int -mpd_isshared_data(const mpd_t *dec) -{ - return dec->flags & MPD_SHARED_DATA; -} - -/* Data of decimal is const */ -ALWAYS_INLINE int -mpd_isconst_data(const mpd_t *dec) -{ - return dec->flags & MPD_CONST_DATA; -} - - -/******************************************************************************/ -/* Inline memory handling */ -/******************************************************************************/ - -/* Fill destination with zeros */ -ALWAYS_INLINE void -mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len) -{ - mpd_size_t i; - - for (i = 0; i < len; i++) { - dest[i] = 0; - } -} - -/* Free a decimal */ -ALWAYS_INLINE void -mpd_del(mpd_t *dec) -{ - if (mpd_isdynamic_data(dec)) { - mpd_free(dec->data); - } - if (mpd_isdynamic(dec)) { - mpd_free(dec); - } -} - -/* - * Resize the coefficient. Existing data up to 'nwords' is left untouched. - * Return 1 on success, 0 otherwise. - * - * Input invariant: MPD_MINALLOC <= result->alloc. - * - * Case nwords == result->alloc: - * 'result' is unchanged. Return 1. - * - * Case nwords > result->alloc: - * Case realloc success: - * The value of 'result' does not change. Return 1. - * Case realloc failure: - * 'result' is NaN, status is updated with MPD_Malloc_error. Return 0. - * - * Case nwords < result->alloc: - * Case is_static_data or realloc failure [1]: - * 'result' is unchanged. Return 1. - * Case realloc success: - * The value of result is undefined (expected). Return 1. - * - * - * [1] In that case the old (now oversized) area is still valid. - */ -ALWAYS_INLINE int -mpd_qresize(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) -{ - assert(!mpd_isconst_data(result)); /* illegal operation for a const */ - assert(!mpd_isshared_data(result)); /* illegal operation for a shared */ - assert(MPD_MINALLOC <= result->alloc); - - nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords; - if (nwords == result->alloc) { - return 1; - } - if (mpd_isstatic_data(result)) { - if (nwords > result->alloc) { - return mpd_switch_to_dyn(result, nwords, status); - } - return 1; - } - - return mpd_realloc_dyn(result, nwords, status); -} - + return 1; +} + +/* Finite */ +ALWAYS_INLINE int +mpd_isfinite(const mpd_t *dec) +{ + return !(dec->flags & MPD_SPECIAL); +} + +/* Infinite */ +ALWAYS_INLINE int +mpd_isinfinite(const mpd_t *dec) +{ + return dec->flags & MPD_INF; +} + +/* NaN */ +ALWAYS_INLINE int +mpd_isnan(const mpd_t *dec) +{ + return dec->flags & (MPD_NAN|MPD_SNAN); +} + +/* Negative */ +ALWAYS_INLINE int +mpd_isnegative(const mpd_t *dec) +{ + return dec->flags & MPD_NEG; +} + +/* Positive */ +ALWAYS_INLINE int +mpd_ispositive(const mpd_t *dec) +{ + return !(dec->flags & MPD_NEG); +} + +/* qNaN */ +ALWAYS_INLINE int +mpd_isqnan(const mpd_t *dec) +{ + return dec->flags & MPD_NAN; +} + +/* Signed */ +ALWAYS_INLINE int +mpd_issigned(const mpd_t *dec) +{ + return dec->flags & MPD_NEG; +} + +/* sNaN */ +ALWAYS_INLINE int +mpd_issnan(const mpd_t *dec) +{ + return dec->flags & MPD_SNAN; +} + +/* Special */ +ALWAYS_INLINE int +mpd_isspecial(const mpd_t *dec) +{ + return dec->flags & MPD_SPECIAL; +} + +/* Zero */ +ALWAYS_INLINE int +mpd_iszero(const mpd_t *dec) +{ + return !mpd_isspecial(dec) && mpd_msword(dec) == 0; +} + +/* Test for zero when specials have been ruled out already */ +ALWAYS_INLINE int +mpd_iszerocoeff(const mpd_t *dec) +{ + return mpd_msword(dec) == 0; +} + +/* Normal */ +inline int +mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx) +{ + if (mpd_isspecial(dec)) return 0; + if (mpd_iszerocoeff(dec)) return 0; + + return mpd_adjexp(dec) >= ctx->emin; +} + +/* Subnormal */ +inline int +mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx) +{ + if (mpd_isspecial(dec)) return 0; + if (mpd_iszerocoeff(dec)) return 0; + + return mpd_adjexp(dec) < ctx->emin; +} + +/* Odd word */ +ALWAYS_INLINE int +mpd_isoddword(mpd_uint_t word) +{ + return word & 1; +} + +/* Odd coefficient */ +ALWAYS_INLINE int +mpd_isoddcoeff(const mpd_t *dec) +{ + return mpd_isoddword(dec->data[0]); +} + +/* 0 if dec is positive, 1 if dec is negative */ +ALWAYS_INLINE uint8_t +mpd_sign(const mpd_t *dec) +{ + return dec->flags & MPD_NEG; +} + +/* 1 if dec is positive, -1 if dec is negative */ +ALWAYS_INLINE int +mpd_arith_sign(const mpd_t *dec) +{ + return 1 - 2 * mpd_isnegative(dec); +} + +/* Radix */ +ALWAYS_INLINE long +mpd_radix(void) +{ + return 10; +} + +/* Dynamic decimal */ +ALWAYS_INLINE int +mpd_isdynamic(const mpd_t *dec) +{ + return !(dec->flags & MPD_STATIC); +} + +/* Static decimal */ +ALWAYS_INLINE int +mpd_isstatic(const mpd_t *dec) +{ + return dec->flags & MPD_STATIC; +} + +/* Data of decimal is dynamic */ +ALWAYS_INLINE int +mpd_isdynamic_data(const mpd_t *dec) +{ + return !(dec->flags & MPD_DATAFLAGS); +} + +/* Data of decimal is static */ +ALWAYS_INLINE int +mpd_isstatic_data(const mpd_t *dec) +{ + return dec->flags & MPD_STATIC_DATA; +} + +/* Data of decimal is shared */ +ALWAYS_INLINE int +mpd_isshared_data(const mpd_t *dec) +{ + return dec->flags & MPD_SHARED_DATA; +} + +/* Data of decimal is const */ +ALWAYS_INLINE int +mpd_isconst_data(const mpd_t *dec) +{ + return dec->flags & MPD_CONST_DATA; +} + + +/******************************************************************************/ +/* Inline memory handling */ +/******************************************************************************/ + +/* Fill destination with zeros */ +ALWAYS_INLINE void +mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len) +{ + mpd_size_t i; + + for (i = 0; i < len; i++) { + dest[i] = 0; + } +} + +/* Free a decimal */ +ALWAYS_INLINE void +mpd_del(mpd_t *dec) +{ + if (mpd_isdynamic_data(dec)) { + mpd_free(dec->data); + } + if (mpd_isdynamic(dec)) { + mpd_free(dec); + } +} + +/* + * Resize the coefficient. Existing data up to 'nwords' is left untouched. + * Return 1 on success, 0 otherwise. + * + * Input invariant: MPD_MINALLOC <= result->alloc. + * + * Case nwords == result->alloc: + * 'result' is unchanged. Return 1. + * + * Case nwords > result->alloc: + * Case realloc success: + * The value of 'result' does not change. Return 1. + * Case realloc failure: + * 'result' is NaN, status is updated with MPD_Malloc_error. Return 0. + * + * Case nwords < result->alloc: + * Case is_static_data or realloc failure [1]: + * 'result' is unchanged. Return 1. + * Case realloc success: + * The value of result is undefined (expected). Return 1. + * + * + * [1] In that case the old (now oversized) area is still valid. + */ +ALWAYS_INLINE int +mpd_qresize(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) +{ + assert(!mpd_isconst_data(result)); /* illegal operation for a const */ + assert(!mpd_isshared_data(result)); /* illegal operation for a shared */ + assert(MPD_MINALLOC <= result->alloc); + + nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords; + if (nwords == result->alloc) { + return 1; + } + if (mpd_isstatic_data(result)) { + if (nwords > result->alloc) { + return mpd_switch_to_dyn(result, nwords, status); + } + return 1; + } + + return mpd_realloc_dyn(result, nwords, status); +} + /* Same as mpd_qresize, but do not set the result no NaN on failure. */ static ALWAYS_INLINE int mpd_qresize_cxx(mpd_t *result, mpd_ssize_t nwords) @@ -538,7494 +538,7494 @@ mpd_qresize_cxx(mpd_t *result, mpd_ssize_t nwords) return mpd_realloc_dyn_cxx(result, nwords); } -/* Same as mpd_qresize, but the complete coefficient (including the old - * memory area!) is initialized to zero. */ -ALWAYS_INLINE int -mpd_qresize_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) +/* Same as mpd_qresize, but the complete coefficient (including the old + * memory area!) is initialized to zero. */ +ALWAYS_INLINE int +mpd_qresize_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) +{ + assert(!mpd_isconst_data(result)); /* illegal operation for a const */ + assert(!mpd_isshared_data(result)); /* illegal operation for a shared */ + assert(MPD_MINALLOC <= result->alloc); + + nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords; + if (nwords != result->alloc) { + if (mpd_isstatic_data(result)) { + if (nwords > result->alloc) { + return mpd_switch_to_dyn_zero(result, nwords, status); + } + } + else if (!mpd_realloc_dyn(result, nwords, status)) { + return 0; + } + } + + mpd_uint_zero(result->data, nwords); + return 1; +} + +/* + * Reduce memory size for the coefficient to MPD_MINALLOC. In theory, + * realloc may fail even when reducing the memory size. But in that case + * the old memory area is always big enough, so checking for MPD_Malloc_error + * is not imperative. + */ +ALWAYS_INLINE void +mpd_minalloc(mpd_t *result) +{ + assert(!mpd_isconst_data(result)); /* illegal operation for a const */ + assert(!mpd_isshared_data(result)); /* illegal operation for a shared */ + + if (!mpd_isstatic_data(result) && result->alloc > MPD_MINALLOC) { + uint8_t err = 0; + result->data = mpd_realloc(result->data, MPD_MINALLOC, + sizeof *result->data, &err); + if (!err) { + result->alloc = MPD_MINALLOC; + } + } +} + +int +mpd_resize(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx) +{ + uint32_t status = 0; + if (!mpd_qresize(result, nwords, &status)) { + mpd_addstatus_raise(ctx, status); + return 0; + } + return 1; +} + +int +mpd_resize_zero(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx) +{ + uint32_t status = 0; + if (!mpd_qresize_zero(result, nwords, &status)) { + mpd_addstatus_raise(ctx, status); + return 0; + } + return 1; +} + + +/******************************************************************************/ +/* Set attributes of a decimal */ +/******************************************************************************/ + +/* Set digits. Assumption: result->len is initialized and > 0. */ +inline void +mpd_setdigits(mpd_t *result) +{ + mpd_ssize_t wdigits = mpd_word_digits(mpd_msword(result)); + result->digits = wdigits + (result->len-1) * MPD_RDIGITS; +} + +/* Set sign */ +ALWAYS_INLINE void +mpd_set_sign(mpd_t *result, uint8_t sign) +{ + result->flags &= ~MPD_NEG; + result->flags |= sign; +} + +/* Copy sign from another decimal */ +ALWAYS_INLINE void +mpd_signcpy(mpd_t *result, const mpd_t *a) +{ + uint8_t sign = a->flags&MPD_NEG; + + result->flags &= ~MPD_NEG; + result->flags |= sign; +} + +/* Set infinity */ +ALWAYS_INLINE void +mpd_set_infinity(mpd_t *result) +{ + result->flags &= ~MPD_SPECIAL; + result->flags |= MPD_INF; +} + +/* Set qNaN */ +ALWAYS_INLINE void +mpd_set_qnan(mpd_t *result) +{ + result->flags &= ~MPD_SPECIAL; + result->flags |= MPD_NAN; +} + +/* Set sNaN */ +ALWAYS_INLINE void +mpd_set_snan(mpd_t *result) +{ + result->flags &= ~MPD_SPECIAL; + result->flags |= MPD_SNAN; +} + +/* Set to negative */ +ALWAYS_INLINE void +mpd_set_negative(mpd_t *result) +{ + result->flags |= MPD_NEG; +} + +/* Set to positive */ +ALWAYS_INLINE void +mpd_set_positive(mpd_t *result) +{ + result->flags &= ~MPD_NEG; +} + +/* Set to dynamic */ +ALWAYS_INLINE void +mpd_set_dynamic(mpd_t *result) +{ + result->flags &= ~MPD_STATIC; +} + +/* Set to static */ +ALWAYS_INLINE void +mpd_set_static(mpd_t *result) +{ + result->flags |= MPD_STATIC; +} + +/* Set data to dynamic */ +ALWAYS_INLINE void +mpd_set_dynamic_data(mpd_t *result) +{ + result->flags &= ~MPD_DATAFLAGS; +} + +/* Set data to static */ +ALWAYS_INLINE void +mpd_set_static_data(mpd_t *result) +{ + result->flags &= ~MPD_DATAFLAGS; + result->flags |= MPD_STATIC_DATA; +} + +/* Set data to shared */ +ALWAYS_INLINE void +mpd_set_shared_data(mpd_t *result) +{ + result->flags &= ~MPD_DATAFLAGS; + result->flags |= MPD_SHARED_DATA; +} + +/* Set data to const */ +ALWAYS_INLINE void +mpd_set_const_data(mpd_t *result) +{ + result->flags &= ~MPD_DATAFLAGS; + result->flags |= MPD_CONST_DATA; +} + +/* Clear flags, preserving memory attributes. */ +ALWAYS_INLINE void +mpd_clear_flags(mpd_t *result) +{ + result->flags &= (MPD_STATIC|MPD_DATAFLAGS); +} + +/* Set flags, preserving memory attributes. */ +ALWAYS_INLINE void +mpd_set_flags(mpd_t *result, uint8_t flags) +{ + result->flags &= (MPD_STATIC|MPD_DATAFLAGS); + result->flags |= flags; +} + +/* Copy flags, preserving memory attributes of result. */ +ALWAYS_INLINE void +mpd_copy_flags(mpd_t *result, const mpd_t *a) +{ + uint8_t aflags = a->flags; + result->flags &= (MPD_STATIC|MPD_DATAFLAGS); + result->flags |= (aflags & ~(MPD_STATIC|MPD_DATAFLAGS)); +} + +/* Initialize a workcontext from ctx. Set traps, flags and newtrap to 0. */ +static inline void +mpd_workcontext(mpd_context_t *workctx, const mpd_context_t *ctx) +{ + workctx->prec = ctx->prec; + workctx->emax = ctx->emax; + workctx->emin = ctx->emin; + workctx->round = ctx->round; + workctx->traps = 0; + workctx->status = 0; + workctx->newtrap = 0; + workctx->clamp = ctx->clamp; + workctx->allcr = ctx->allcr; +} + + +/******************************************************************************/ +/* Getting and setting parts of decimals */ +/******************************************************************************/ + +/* Flip the sign of a decimal */ +static inline void +_mpd_negate(mpd_t *dec) +{ + dec->flags ^= MPD_NEG; +} + +/* Set coefficient to zero */ +void +mpd_zerocoeff(mpd_t *result) +{ + mpd_minalloc(result); + result->digits = 1; + result->len = 1; + result->data[0] = 0; +} + +/* Set the coefficient to all nines. */ +void +mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status) +{ + mpd_ssize_t len, r; + + _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS); + len = (r == 0) ? len : len+1; + + if (!mpd_qresize(result, len, status)) { + return; + } + + result->len = len; + result->digits = ctx->prec; + + --len; + if (r > 0) { + result->data[len--] = mpd_pow10[r]-1; + } + for (; len >= 0; --len) { + result->data[len] = MPD_RADIX-1; + } +} + +/* + * Cut off the most significant digits so that the rest fits in ctx->prec. + * Cannot fail. + */ +static void +_mpd_cap(mpd_t *result, const mpd_context_t *ctx) +{ + uint32_t dummy; + mpd_ssize_t len, r; + + if (result->len > 0 && result->digits > ctx->prec) { + _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS); + len = (r == 0) ? len : len+1; + + if (r != 0) { + result->data[len-1] %= mpd_pow10[r]; + } + + len = _mpd_real_size(result->data, len); + /* resize to fewer words cannot fail */ + mpd_qresize(result, len, &dummy); + result->len = len; + mpd_setdigits(result); + } + if (mpd_iszero(result)) { + _settriple(result, mpd_sign(result), 0, result->exp); + } +} + +/* + * Cut off the most significant digits of a NaN payload so that the rest + * fits in ctx->prec - ctx->clamp. Cannot fail. + */ +static void +_mpd_fix_nan(mpd_t *result, const mpd_context_t *ctx) +{ + uint32_t dummy; + mpd_ssize_t prec; + mpd_ssize_t len, r; + + prec = ctx->prec - ctx->clamp; + if (result->len > 0 && result->digits > prec) { + if (prec == 0) { + mpd_minalloc(result); + result->len = result->digits = 0; + } + else { + _mpd_idiv_word(&len, &r, prec, MPD_RDIGITS); + len = (r == 0) ? len : len+1; + + if (r != 0) { + result->data[len-1] %= mpd_pow10[r]; + } + + len = _mpd_real_size(result->data, len); + /* resize to fewer words cannot fail */ + mpd_qresize(result, len, &dummy); + result->len = len; + mpd_setdigits(result); + if (mpd_iszerocoeff(result)) { + /* NaN0 is not a valid representation */ + result->len = result->digits = 0; + } + } + } +} + +/* + * Get n most significant digits from a decimal, where 0 < n <= MPD_UINT_DIGITS. + * Assumes MPD_UINT_DIGITS == MPD_RDIGITS+1, which is true for 32 and 64 bit + * machines. + * + * The result of the operation will be in lo. If the operation is impossible, + * hi will be nonzero. This is used to indicate an error. + */ +static inline void +_mpd_get_msdigits(mpd_uint_t *hi, mpd_uint_t *lo, const mpd_t *dec, + unsigned int n) +{ + mpd_uint_t r, tmp; + + assert(0 < n && n <= MPD_RDIGITS+1); + + _mpd_div_word(&tmp, &r, dec->digits, MPD_RDIGITS); + r = (r == 0) ? MPD_RDIGITS : r; /* digits in the most significant word */ + + *hi = 0; + *lo = dec->data[dec->len-1]; + if (n <= r) { + *lo /= mpd_pow10[r-n]; + } + else if (dec->len > 1) { + /* at this point 1 <= r < n <= MPD_RDIGITS+1 */ + _mpd_mul_words(hi, lo, *lo, mpd_pow10[n-r]); + tmp = dec->data[dec->len-2] / mpd_pow10[MPD_RDIGITS-(n-r)]; + *lo = *lo + tmp; + if (*lo < tmp) (*hi)++; + } +} + + +/******************************************************************************/ +/* Gathering information about a decimal */ +/******************************************************************************/ + +/* The real size of the coefficient without leading zero words. */ +static inline mpd_ssize_t +_mpd_real_size(mpd_uint_t *data, mpd_ssize_t size) +{ + while (size > 1 && data[size-1] == 0) { + size--; + } + + return size; +} + +/* Return number of trailing zeros. No errors are possible. */ +mpd_ssize_t +mpd_trail_zeros(const mpd_t *dec) +{ + mpd_uint_t word; + mpd_ssize_t i, tz = 0; + + for (i=0; i < dec->len; ++i) { + if (dec->data[i] != 0) { + word = dec->data[i]; + tz = i * MPD_RDIGITS; + while (word % 10 == 0) { + word /= 10; + tz++; + } + break; + } + } + + return tz; +} + +/* Integer: Undefined for specials */ +static int +_mpd_isint(const mpd_t *dec) +{ + mpd_ssize_t tz; + + if (mpd_iszerocoeff(dec)) { + return 1; + } + + tz = mpd_trail_zeros(dec); + return (dec->exp + tz >= 0); +} + +/* Integer */ +int +mpd_isinteger(const mpd_t *dec) +{ + if (mpd_isspecial(dec)) { + return 0; + } + return _mpd_isint(dec); +} + +/* Word is a power of 10 */ +static int +mpd_word_ispow10(mpd_uint_t word) +{ + int n; + + n = mpd_word_digits(word); + if (word == mpd_pow10[n-1]) { + return 1; + } + + return 0; +} + +/* Coefficient is a power of 10 */ +static int +mpd_coeff_ispow10(const mpd_t *dec) +{ + if (mpd_word_ispow10(mpd_msword(dec))) { + if (_mpd_isallzero(dec->data, dec->len-1)) { + return 1; + } + } + + return 0; +} + +/* All digits of a word are nines */ +static int +mpd_word_isallnine(mpd_uint_t word) +{ + int n; + + n = mpd_word_digits(word); + if (word == mpd_pow10[n]-1) { + return 1; + } + + return 0; +} + +/* All digits of the coefficient are nines */ +static int +mpd_coeff_isallnine(const mpd_t *dec) +{ + if (mpd_word_isallnine(mpd_msword(dec))) { + if (_mpd_isallnine(dec->data, dec->len-1)) { + return 1; + } + } + + return 0; +} + +/* Odd decimal: Undefined for non-integers! */ +int +mpd_isodd(const mpd_t *dec) +{ + mpd_uint_t q, r; + assert(mpd_isinteger(dec)); + if (mpd_iszerocoeff(dec)) return 0; + if (dec->exp < 0) { + _mpd_div_word(&q, &r, -dec->exp, MPD_RDIGITS); + q = dec->data[q] / mpd_pow10[r]; + return mpd_isoddword(q); + } + return dec->exp == 0 && mpd_isoddword(dec->data[0]); +} + +/* Even: Undefined for non-integers! */ +int +mpd_iseven(const mpd_t *dec) +{ + return !mpd_isodd(dec); +} + +/******************************************************************************/ +/* Getting and setting decimals */ +/******************************************************************************/ + +/* Internal function: Set a static decimal from a triple, no error checking. */ +static void +_ssettriple(mpd_t *result, uint8_t sign, mpd_uint_t a, mpd_ssize_t exp) +{ + mpd_set_flags(result, sign); + result->exp = exp; + _mpd_div_word(&result->data[1], &result->data[0], a, MPD_RADIX); + result->len = (result->data[1] == 0) ? 1 : 2; + mpd_setdigits(result); +} + +/* Internal function: Set a decimal from a triple, no error checking. */ +static void +_settriple(mpd_t *result, uint8_t sign, mpd_uint_t a, mpd_ssize_t exp) +{ + mpd_minalloc(result); + mpd_set_flags(result, sign); + result->exp = exp; + _mpd_div_word(&result->data[1], &result->data[0], a, MPD_RADIX); + result->len = (result->data[1] == 0) ? 1 : 2; + mpd_setdigits(result); +} + +/* Set a special number from a triple */ +void +mpd_setspecial(mpd_t *result, uint8_t sign, uint8_t type) +{ + mpd_minalloc(result); + result->flags &= ~(MPD_NEG|MPD_SPECIAL); + result->flags |= (sign|type); + result->exp = result->digits = result->len = 0; +} + +/* Set result of NaN with an error status */ +void +mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status) +{ + mpd_minalloc(result); + mpd_set_qnan(result); + mpd_set_positive(result); + result->exp = result->digits = result->len = 0; + *status |= flags; +} + +/* quietly set a static decimal from an mpd_ssize_t */ +void +mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_uint_t u; + uint8_t sign = MPD_POS; + + if (a < 0) { + if (a == MPD_SSIZE_MIN) { + u = (mpd_uint_t)MPD_SSIZE_MAX + + (-(MPD_SSIZE_MIN+MPD_SSIZE_MAX)); + } + else { + u = -a; + } + sign = MPD_NEG; + } + else { + u = a; + } + _ssettriple(result, sign, u, 0); + mpd_qfinalize(result, ctx, status); +} + +/* quietly set a static decimal from an mpd_uint_t */ +void +mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + _ssettriple(result, MPD_POS, a, 0); + mpd_qfinalize(result, ctx, status); +} + +/* quietly set a static decimal from an int32_t */ +void +mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_qsset_ssize(result, a, ctx, status); +} + +/* quietly set a static decimal from a uint32_t */ +void +mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_qsset_uint(result, a, ctx, status); +} + +#ifdef CONFIG_64 +/* quietly set a static decimal from an int64_t */ +void +mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_qsset_ssize(result, a, ctx, status); +} + +/* quietly set a static decimal from a uint64_t */ +void +mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_qsset_uint(result, a, ctx, status); +} +#endif + +/* quietly set a decimal from an mpd_ssize_t */ +void +mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_minalloc(result); + mpd_qsset_ssize(result, a, ctx, status); +} + +/* quietly set a decimal from an mpd_uint_t */ +void +mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + _settriple(result, MPD_POS, a, 0); + mpd_qfinalize(result, ctx, status); +} + +/* quietly set a decimal from an int32_t */ +void +mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_qset_ssize(result, a, ctx, status); +} + +/* quietly set a decimal from a uint32_t */ +void +mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_qset_uint(result, a, ctx, status); +} + +#if defined(CONFIG_32) && !defined(LEGACY_COMPILER) +/* set a decimal from a uint64_t */ +static void +_c32setu64(mpd_t *result, uint64_t u, uint8_t sign, uint32_t *status) +{ + mpd_uint_t w[3]; + uint64_t q; + int i, len; + + len = 0; + do { + q = u / MPD_RADIX; + w[len] = (mpd_uint_t)(u - q * MPD_RADIX); + u = q; len++; + } while (u != 0); + + if (!mpd_qresize(result, len, status)) { + return; + } + for (i = 0; i < len; i++) { + result->data[i] = w[i]; + } + + mpd_set_flags(result, sign); + result->exp = 0; + result->len = len; + mpd_setdigits(result); +} + +static void +_c32_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + _c32setu64(result, a, MPD_POS, status); + mpd_qfinalize(result, ctx, status); +} + +/* set a decimal from an int64_t */ +static void +_c32_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, + uint32_t *status) +{ + uint64_t u; + uint8_t sign = MPD_POS; + + if (a < 0) { + if (a == INT64_MIN) { + u = (uint64_t)INT64_MAX + (-(INT64_MIN+INT64_MAX)); + } + else { + u = -a; + } + sign = MPD_NEG; + } + else { + u = a; + } + _c32setu64(result, u, sign, status); + mpd_qfinalize(result, ctx, status); +} +#endif /* CONFIG_32 && !LEGACY_COMPILER */ + +#ifndef LEGACY_COMPILER +/* quietly set a decimal from an int64_t */ +void +mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, + uint32_t *status) +{ +#ifdef CONFIG_64 + mpd_qset_ssize(result, a, ctx, status); +#else + _c32_qset_i64(result, a, ctx, status); +#endif +} + +/* quietly set a decimal from an int64_t, use a maxcontext for conversion */ +void +mpd_qset_i64_exact(mpd_t *result, int64_t a, uint32_t *status) { - assert(!mpd_isconst_data(result)); /* illegal operation for a const */ - assert(!mpd_isshared_data(result)); /* illegal operation for a shared */ - assert(MPD_MINALLOC <= result->alloc); + mpd_context_t maxcontext; - nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords; - if (nwords != result->alloc) { - if (mpd_isstatic_data(result)) { - if (nwords > result->alloc) { - return mpd_switch_to_dyn_zero(result, nwords, status); - } - } - else if (!mpd_realloc_dyn(result, nwords, status)) { - return 0; - } - } + mpd_maxcontext(&maxcontext); +#ifdef CONFIG_64 + mpd_qset_ssize(result, a, &maxcontext, status); +#else + _c32_qset_i64(result, a, &maxcontext, status); +#endif - mpd_uint_zero(result->data, nwords); - return 1; + if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + /* we want exact results */ + mpd_seterror(result, MPD_Invalid_operation, status); + } + *status &= MPD_Errors; } -/* - * Reduce memory size for the coefficient to MPD_MINALLOC. In theory, - * realloc may fail even when reducing the memory size. But in that case - * the old memory area is always big enough, so checking for MPD_Malloc_error - * is not imperative. - */ -ALWAYS_INLINE void -mpd_minalloc(mpd_t *result) +/* quietly set a decimal from a uint64_t */ +void +mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, + uint32_t *status) +{ +#ifdef CONFIG_64 + mpd_qset_uint(result, a, ctx, status); +#else + _c32_qset_u64(result, a, ctx, status); +#endif +} + +/* quietly set a decimal from a uint64_t, use a maxcontext for conversion */ +void +mpd_qset_u64_exact(mpd_t *result, uint64_t a, uint32_t *status) { - assert(!mpd_isconst_data(result)); /* illegal operation for a const */ - assert(!mpd_isshared_data(result)); /* illegal operation for a shared */ + mpd_context_t maxcontext; - if (!mpd_isstatic_data(result) && result->alloc > MPD_MINALLOC) { - uint8_t err = 0; - result->data = mpd_realloc(result->data, MPD_MINALLOC, - sizeof *result->data, &err); - if (!err) { - result->alloc = MPD_MINALLOC; - } + mpd_maxcontext(&maxcontext); +#ifdef CONFIG_64 + mpd_qset_uint(result, a, &maxcontext, status); +#else + _c32_qset_u64(result, a, &maxcontext, status); +#endif + + if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + /* we want exact results */ + mpd_seterror(result, MPD_Invalid_operation, status); } + *status &= MPD_Errors; } - +#endif /* !LEGACY_COMPILER */ + +/* + * Quietly get an mpd_uint_t from a decimal. Assumes + * MPD_UINT_DIGITS == MPD_RDIGITS+1, which is true for + * 32 and 64 bit machines. + * + * If the operation is impossible, MPD_Invalid_operation is set. + */ +static mpd_uint_t +_mpd_qget_uint(int use_sign, const mpd_t *a, uint32_t *status) +{ + mpd_t tmp; + mpd_uint_t tmp_data[2]; + mpd_uint_t lo, hi; + + if (mpd_isspecial(a)) { + *status |= MPD_Invalid_operation; + return MPD_UINT_MAX; + } + if (mpd_iszero(a)) { + return 0; + } + if (use_sign && mpd_isnegative(a)) { + *status |= MPD_Invalid_operation; + return MPD_UINT_MAX; + } + + if (a->digits+a->exp > MPD_RDIGITS+1) { + *status |= MPD_Invalid_operation; + return MPD_UINT_MAX; + } + + if (a->exp < 0) { + if (!_mpd_isint(a)) { + *status |= MPD_Invalid_operation; + return MPD_UINT_MAX; + } + /* At this point a->digits+a->exp <= MPD_RDIGITS+1, + * so the shift fits. */ + tmp.data = tmp_data; + tmp.flags = MPD_STATIC|MPD_STATIC_DATA; + tmp.alloc = 2; + mpd_qsshiftr(&tmp, a, -a->exp); + tmp.exp = 0; + a = &tmp; + } + + _mpd_get_msdigits(&hi, &lo, a, MPD_RDIGITS+1); + if (hi) { + *status |= MPD_Invalid_operation; + return MPD_UINT_MAX; + } + + if (a->exp > 0) { + _mpd_mul_words(&hi, &lo, lo, mpd_pow10[a->exp]); + if (hi) { + *status |= MPD_Invalid_operation; + return MPD_UINT_MAX; + } + } + + return lo; +} + +/* + * Sets Invalid_operation for: + * - specials + * - negative numbers (except negative zero) + * - non-integers + * - overflow + */ +mpd_uint_t +mpd_qget_uint(const mpd_t *a, uint32_t *status) +{ + return _mpd_qget_uint(1, a, status); +} + +/* Same as above, but gets the absolute value, i.e. the sign is ignored. */ +mpd_uint_t +mpd_qabs_uint(const mpd_t *a, uint32_t *status) +{ + return _mpd_qget_uint(0, a, status); +} + +/* quietly get an mpd_ssize_t from a decimal */ +mpd_ssize_t +mpd_qget_ssize(const mpd_t *a, uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_uint_t u; + int isneg; + + u = mpd_qabs_uint(a, &workstatus); + if (workstatus&MPD_Invalid_operation) { + *status |= workstatus; + return MPD_SSIZE_MAX; + } + + isneg = mpd_isnegative(a); + if (u <= MPD_SSIZE_MAX) { + return isneg ? -((mpd_ssize_t)u) : (mpd_ssize_t)u; + } + else if (isneg && u+(MPD_SSIZE_MIN+MPD_SSIZE_MAX) == MPD_SSIZE_MAX) { + return MPD_SSIZE_MIN; + } + + *status |= MPD_Invalid_operation; + return MPD_SSIZE_MAX; +} + +#if defined(CONFIG_32) && !defined(LEGACY_COMPILER) +/* + * Quietly get a uint64_t from a decimal. If the operation is impossible, + * MPD_Invalid_operation is set. + */ +static uint64_t +_c32_qget_u64(int use_sign, const mpd_t *a, uint32_t *status) +{ + MPD_NEW_STATIC(tmp,0,0,20,3); + mpd_context_t maxcontext; + uint64_t ret; + + tmp_data[0] = 709551615; + tmp_data[1] = 446744073; + tmp_data[2] = 18; + + if (mpd_isspecial(a)) { + *status |= MPD_Invalid_operation; + return UINT64_MAX; + } + if (mpd_iszero(a)) { + return 0; + } + if (use_sign && mpd_isnegative(a)) { + *status |= MPD_Invalid_operation; + return UINT64_MAX; + } + if (!_mpd_isint(a)) { + *status |= MPD_Invalid_operation; + return UINT64_MAX; + } + + if (_mpd_cmp_abs(a, &tmp) > 0) { + *status |= MPD_Invalid_operation; + return UINT64_MAX; + } + + mpd_maxcontext(&maxcontext); + mpd_qrescale(&tmp, a, 0, &maxcontext, &maxcontext.status); + maxcontext.status &= ~MPD_Rounded; + if (maxcontext.status != 0) { + *status |= (maxcontext.status|MPD_Invalid_operation); /* GCOV_NOT_REACHED */ + return UINT64_MAX; /* GCOV_NOT_REACHED */ + } + + ret = 0; + switch (tmp.len) { + case 3: + ret += (uint64_t)tmp_data[2] * 1000000000000000000ULL; + case 2: + ret += (uint64_t)tmp_data[1] * 1000000000ULL; + case 1: + ret += tmp_data[0]; + break; + default: + abort(); /* GCOV_NOT_REACHED */ + } + + return ret; +} + +static int64_t +_c32_qget_i64(const mpd_t *a, uint32_t *status) +{ + uint64_t u; + int isneg; + + u = _c32_qget_u64(0, a, status); + if (*status&MPD_Invalid_operation) { + return INT64_MAX; + } + + isneg = mpd_isnegative(a); + if (u <= INT64_MAX) { + return isneg ? -((int64_t)u) : (int64_t)u; + } + else if (isneg && u+(INT64_MIN+INT64_MAX) == INT64_MAX) { + return INT64_MIN; + } + + *status |= MPD_Invalid_operation; + return INT64_MAX; +} +#endif /* CONFIG_32 && !LEGACY_COMPILER */ + +#ifdef CONFIG_64 +/* quietly get a uint64_t from a decimal */ +uint64_t +mpd_qget_u64(const mpd_t *a, uint32_t *status) +{ + return mpd_qget_uint(a, status); +} + +/* quietly get an int64_t from a decimal */ +int64_t +mpd_qget_i64(const mpd_t *a, uint32_t *status) +{ + return mpd_qget_ssize(a, status); +} + +/* quietly get a uint32_t from a decimal */ +uint32_t +mpd_qget_u32(const mpd_t *a, uint32_t *status) +{ + uint32_t workstatus = 0; + uint64_t x = mpd_qget_uint(a, &workstatus); + + if (workstatus&MPD_Invalid_operation) { + *status |= workstatus; + return UINT32_MAX; + } + if (x > UINT32_MAX) { + *status |= MPD_Invalid_operation; + return UINT32_MAX; + } + + return (uint32_t)x; +} + +/* quietly get an int32_t from a decimal */ +int32_t +mpd_qget_i32(const mpd_t *a, uint32_t *status) +{ + uint32_t workstatus = 0; + int64_t x = mpd_qget_ssize(a, &workstatus); + + if (workstatus&MPD_Invalid_operation) { + *status |= workstatus; + return INT32_MAX; + } + if (x < INT32_MIN || x > INT32_MAX) { + *status |= MPD_Invalid_operation; + return INT32_MAX; + } + + return (int32_t)x; +} +#else +#ifndef LEGACY_COMPILER +/* quietly get a uint64_t from a decimal */ +uint64_t +mpd_qget_u64(const mpd_t *a, uint32_t *status) +{ + uint32_t workstatus = 0; + uint64_t x = _c32_qget_u64(1, a, &workstatus); + *status |= workstatus; + return x; +} + +/* quietly get an int64_t from a decimal */ +int64_t +mpd_qget_i64(const mpd_t *a, uint32_t *status) +{ + uint32_t workstatus = 0; + int64_t x = _c32_qget_i64(a, &workstatus); + *status |= workstatus; + return x; +} +#endif + +/* quietly get a uint32_t from a decimal */ +uint32_t +mpd_qget_u32(const mpd_t *a, uint32_t *status) +{ + return mpd_qget_uint(a, status); +} + +/* quietly get an int32_t from a decimal */ +int32_t +mpd_qget_i32(const mpd_t *a, uint32_t *status) +{ + return mpd_qget_ssize(a, status); +} +#endif + + +/******************************************************************************/ +/* Filtering input of functions, finalizing output of functions */ +/******************************************************************************/ + +/* + * Check if the operand is NaN, copy to result and return 1 if this is + * the case. Copying can fail since NaNs are allowed to have a payload that + * does not fit in MPD_MINALLOC. + */ +int +mpd_qcheck_nan(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + if (mpd_isnan(a)) { + *status |= mpd_issnan(a) ? MPD_Invalid_operation : 0; + mpd_qcopy(result, a, status); + mpd_set_qnan(result); + _mpd_fix_nan(result, ctx); + return 1; + } + return 0; +} + +/* + * Check if either operand is NaN, copy to result and return 1 if this + * is the case. Copying can fail since NaNs are allowed to have a payload + * that does not fit in MPD_MINALLOC. + */ +int +mpd_qcheck_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + if ((a->flags|b->flags)&(MPD_NAN|MPD_SNAN)) { + const mpd_t *choice = b; + if (mpd_issnan(a)) { + choice = a; + *status |= MPD_Invalid_operation; + } + else if (mpd_issnan(b)) { + *status |= MPD_Invalid_operation; + } + else if (mpd_isqnan(a)) { + choice = a; + } + mpd_qcopy(result, choice, status); + mpd_set_qnan(result); + _mpd_fix_nan(result, ctx); + return 1; + } + return 0; +} + +/* + * Check if one of the operands is NaN, copy to result and return 1 if this + * is the case. Copying can fail since NaNs are allowed to have a payload + * that does not fit in MPD_MINALLOC. + */ +static int +mpd_qcheck_3nans(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, + const mpd_context_t *ctx, uint32_t *status) +{ + if ((a->flags|b->flags|c->flags)&(MPD_NAN|MPD_SNAN)) { + const mpd_t *choice = c; + if (mpd_issnan(a)) { + choice = a; + *status |= MPD_Invalid_operation; + } + else if (mpd_issnan(b)) { + choice = b; + *status |= MPD_Invalid_operation; + } + else if (mpd_issnan(c)) { + *status |= MPD_Invalid_operation; + } + else if (mpd_isqnan(a)) { + choice = a; + } + else if (mpd_isqnan(b)) { + choice = b; + } + mpd_qcopy(result, choice, status); + mpd_set_qnan(result); + _mpd_fix_nan(result, ctx); + return 1; + } + return 0; +} + +/* Check if rounding digit 'rnd' leads to an increment. */ +static inline int +_mpd_rnd_incr(const mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx) +{ + int ld; + + switch (ctx->round) { + case MPD_ROUND_DOWN: case MPD_ROUND_TRUNC: + return 0; + case MPD_ROUND_HALF_UP: + return (rnd >= 5); + case MPD_ROUND_HALF_EVEN: + return (rnd > 5) || ((rnd == 5) && mpd_isoddcoeff(dec)); + case MPD_ROUND_CEILING: + return !(rnd == 0 || mpd_isnegative(dec)); + case MPD_ROUND_FLOOR: + return !(rnd == 0 || mpd_ispositive(dec)); + case MPD_ROUND_HALF_DOWN: + return (rnd > 5); + case MPD_ROUND_UP: + return !(rnd == 0); + case MPD_ROUND_05UP: + ld = (int)mpd_lsd(dec->data[0]); + return (!(rnd == 0) && (ld == 0 || ld == 5)); + default: + /* Without a valid context, further results will be undefined. */ + return 0; /* GCOV_NOT_REACHED */ + } +} + +/* + * Apply rounding to a decimal that has been right-shifted into a full + * precision decimal. If an increment leads to an overflow of the precision, + * adjust the coefficient and the exponent and check the new exponent for + * overflow. + */ +static inline void +_mpd_apply_round(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx, + uint32_t *status) +{ + if (_mpd_rnd_incr(dec, rnd, ctx)) { + /* We have a number with exactly ctx->prec digits. The increment + * can only lead to an overflow if the decimal is all nines. In + * that case, the result is a power of ten with prec+1 digits. + * + * If the precision is a multiple of MPD_RDIGITS, this situation is + * detected by _mpd_baseincr returning a carry. + * If the precision is not a multiple of MPD_RDIGITS, we have to + * check if the result has one digit too many. + */ + mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len); + if (carry) { + dec->data[dec->len-1] = mpd_pow10[MPD_RDIGITS-1]; + dec->exp += 1; + _mpd_check_exp(dec, ctx, status); + return; + } + mpd_setdigits(dec); + if (dec->digits > ctx->prec) { + mpd_qshiftr_inplace(dec, 1); + dec->exp += 1; + dec->digits = ctx->prec; + _mpd_check_exp(dec, ctx, status); + } + } +} + +/* + * Apply rounding to a decimal. Allow overflow of the precision. + */ +static inline void +_mpd_apply_round_excess(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx, + uint32_t *status) +{ + if (_mpd_rnd_incr(dec, rnd, ctx)) { + mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len); + if (carry) { + if (!mpd_qresize(dec, dec->len+1, status)) { + return; + } + dec->data[dec->len] = 1; + dec->len += 1; + } + mpd_setdigits(dec); + } +} + +/* + * Apply rounding to a decimal that has been right-shifted into a decimal + * with full precision or less. Return failure if an increment would + * overflow the precision. + */ +static inline int +_mpd_apply_round_fit(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx, + uint32_t *status) +{ + if (_mpd_rnd_incr(dec, rnd, ctx)) { + mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len); + if (carry) { + if (!mpd_qresize(dec, dec->len+1, status)) { + return 0; + } + dec->data[dec->len] = 1; + dec->len += 1; + } + mpd_setdigits(dec); + if (dec->digits > ctx->prec) { + mpd_seterror(dec, MPD_Invalid_operation, status); + return 0; + } + } + return 1; +} + +/* Check a normal number for overflow, underflow, clamping. If the operand + is modified, it will be zero, special or (sub)normal with a coefficient + that fits into the current context precision. */ +static inline void +_mpd_check_exp(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status) +{ + mpd_ssize_t adjexp, etiny, shift; + int rnd; + + adjexp = mpd_adjexp(dec); + if (adjexp > ctx->emax) { + + if (mpd_iszerocoeff(dec)) { + dec->exp = ctx->emax; + if (ctx->clamp) { + dec->exp -= (ctx->prec-1); + } + mpd_zerocoeff(dec); + *status |= MPD_Clamped; + return; + } + + switch (ctx->round) { + case MPD_ROUND_HALF_UP: case MPD_ROUND_HALF_EVEN: + case MPD_ROUND_HALF_DOWN: case MPD_ROUND_UP: + case MPD_ROUND_TRUNC: + mpd_setspecial(dec, mpd_sign(dec), MPD_INF); + break; + case MPD_ROUND_DOWN: case MPD_ROUND_05UP: + mpd_qmaxcoeff(dec, ctx, status); + dec->exp = ctx->emax - ctx->prec + 1; + break; + case MPD_ROUND_CEILING: + if (mpd_isnegative(dec)) { + mpd_qmaxcoeff(dec, ctx, status); + dec->exp = ctx->emax - ctx->prec + 1; + } + else { + mpd_setspecial(dec, MPD_POS, MPD_INF); + } + break; + case MPD_ROUND_FLOOR: + if (mpd_ispositive(dec)) { + mpd_qmaxcoeff(dec, ctx, status); + dec->exp = ctx->emax - ctx->prec + 1; + } + else { + mpd_setspecial(dec, MPD_NEG, MPD_INF); + } + break; + default: /* debug */ + abort(); /* GCOV_NOT_REACHED */ + } + + *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; + + } /* fold down */ + else if (ctx->clamp && dec->exp > mpd_etop(ctx)) { + /* At this point adjexp=exp+digits-1 <= emax and exp > etop=emax-prec+1: + * (1) shift = exp -emax+prec-1 > 0 + * (2) digits+shift = exp+digits-1 - emax + prec <= prec */ + shift = dec->exp - mpd_etop(ctx); + if (!mpd_qshiftl(dec, dec, shift, status)) { + return; + } + dec->exp -= shift; + *status |= MPD_Clamped; + if (!mpd_iszerocoeff(dec) && adjexp < ctx->emin) { + /* Underflow is impossible, since exp < etiny=emin-prec+1 + * and exp > etop=emax-prec+1 would imply emax < emin. */ + *status |= MPD_Subnormal; + } + } + else if (adjexp < ctx->emin) { + + etiny = mpd_etiny(ctx); + + if (mpd_iszerocoeff(dec)) { + if (dec->exp < etiny) { + dec->exp = etiny; + mpd_zerocoeff(dec); + *status |= MPD_Clamped; + } + return; + } + + *status |= MPD_Subnormal; + if (dec->exp < etiny) { + /* At this point adjexp=exp+digits-1 < emin and exp < etiny=emin-prec+1: + * (1) shift = emin-prec+1 - exp > 0 + * (2) digits-shift = exp+digits-1 - emin + prec < prec */ + shift = etiny - dec->exp; + rnd = (int)mpd_qshiftr_inplace(dec, shift); + dec->exp = etiny; + /* We always have a spare digit in case of an increment. */ + _mpd_apply_round_excess(dec, rnd, ctx, status); + *status |= MPD_Rounded; + if (rnd) { + *status |= (MPD_Inexact|MPD_Underflow); + if (mpd_iszerocoeff(dec)) { + mpd_zerocoeff(dec); + *status |= MPD_Clamped; + } + } + } + /* Case exp >= etiny=emin-prec+1: + * (1) adjexp=exp+digits-1 < emin + * (2) digits < emin-exp+1 <= prec */ + } +} + +/* Transcendental functions do not always set Underflow reliably, + * since they only use as much precision as is necessary for correct + * rounding. If a result like 1.0000000000e-101 is finalized, there + * is no rounding digit that would trigger Underflow. But we can + * assume Inexact, so a short check suffices. */ +static inline void +mpd_check_underflow(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status) +{ + if (mpd_adjexp(dec) < ctx->emin && !mpd_iszero(dec) && + dec->exp < mpd_etiny(ctx)) { + *status |= MPD_Underflow; + } +} + +/* Check if a normal number must be rounded after the exponent has been checked. */ +static inline void +_mpd_check_round(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status) +{ + mpd_uint_t rnd; + mpd_ssize_t shift; + + /* must handle specials: _mpd_check_exp() can produce infinities or NaNs */ + if (mpd_isspecial(dec)) { + return; + } + + if (dec->digits > ctx->prec) { + shift = dec->digits - ctx->prec; + rnd = mpd_qshiftr_inplace(dec, shift); + dec->exp += shift; + _mpd_apply_round(dec, rnd, ctx, status); + *status |= MPD_Rounded; + if (rnd) { + *status |= MPD_Inexact; + } + } +} + +/* Finalize all operations. */ +void +mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status) +{ + if (mpd_isspecial(result)) { + if (mpd_isnan(result)) { + _mpd_fix_nan(result, ctx); + } + return; + } + + _mpd_check_exp(result, ctx, status); + _mpd_check_round(result, ctx, status); +} + + +/******************************************************************************/ +/* Copying */ +/******************************************************************************/ + +/* Internal function: Copy a decimal, share data with src: USE WITH CARE! */ +static inline void +_mpd_copy_shared(mpd_t *dest, const mpd_t *src) +{ + dest->flags = src->flags; + dest->exp = src->exp; + dest->digits = src->digits; + dest->len = src->len; + dest->alloc = src->alloc; + dest->data = src->data; + + mpd_set_shared_data(dest); +} + +/* + * Copy a decimal. In case of an error, status is set to MPD_Malloc_error. + */ +int +mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status) +{ + if (result == a) return 1; + + if (!mpd_qresize(result, a->len, status)) { + return 0; + } + + mpd_copy_flags(result, a); + result->exp = a->exp; + result->digits = a->digits; + result->len = a->len; + memcpy(result->data, a->data, a->len * (sizeof *result->data)); + + return 1; +} + +/* Same as mpd_qcopy, but do not set the result to NaN on failure. */ int -mpd_resize(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx) +mpd_qcopy_cxx(mpd_t *result, const mpd_t *a) { - uint32_t status = 0; - if (!mpd_qresize(result, nwords, &status)) { - mpd_addstatus_raise(ctx, status); + if (result == a) return 1; + + if (!mpd_qresize_cxx(result, a->len)) { return 0; } - return 1; -} - -int -mpd_resize_zero(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx) -{ - uint32_t status = 0; - if (!mpd_qresize_zero(result, nwords, &status)) { - mpd_addstatus_raise(ctx, status); - return 0; - } - return 1; -} - - -/******************************************************************************/ -/* Set attributes of a decimal */ -/******************************************************************************/ - -/* Set digits. Assumption: result->len is initialized and > 0. */ -inline void -mpd_setdigits(mpd_t *result) -{ - mpd_ssize_t wdigits = mpd_word_digits(mpd_msword(result)); - result->digits = wdigits + (result->len-1) * MPD_RDIGITS; -} - -/* Set sign */ -ALWAYS_INLINE void -mpd_set_sign(mpd_t *result, uint8_t sign) -{ - result->flags &= ~MPD_NEG; - result->flags |= sign; -} - -/* Copy sign from another decimal */ -ALWAYS_INLINE void -mpd_signcpy(mpd_t *result, const mpd_t *a) -{ - uint8_t sign = a->flags&MPD_NEG; - - result->flags &= ~MPD_NEG; - result->flags |= sign; -} - -/* Set infinity */ -ALWAYS_INLINE void -mpd_set_infinity(mpd_t *result) -{ - result->flags &= ~MPD_SPECIAL; - result->flags |= MPD_INF; -} - -/* Set qNaN */ -ALWAYS_INLINE void -mpd_set_qnan(mpd_t *result) -{ - result->flags &= ~MPD_SPECIAL; - result->flags |= MPD_NAN; -} - -/* Set sNaN */ -ALWAYS_INLINE void -mpd_set_snan(mpd_t *result) -{ - result->flags &= ~MPD_SPECIAL; - result->flags |= MPD_SNAN; -} - -/* Set to negative */ -ALWAYS_INLINE void -mpd_set_negative(mpd_t *result) -{ - result->flags |= MPD_NEG; -} - -/* Set to positive */ -ALWAYS_INLINE void -mpd_set_positive(mpd_t *result) -{ - result->flags &= ~MPD_NEG; -} - -/* Set to dynamic */ -ALWAYS_INLINE void -mpd_set_dynamic(mpd_t *result) -{ - result->flags &= ~MPD_STATIC; -} - -/* Set to static */ -ALWAYS_INLINE void -mpd_set_static(mpd_t *result) -{ - result->flags |= MPD_STATIC; -} - -/* Set data to dynamic */ -ALWAYS_INLINE void -mpd_set_dynamic_data(mpd_t *result) -{ - result->flags &= ~MPD_DATAFLAGS; -} - -/* Set data to static */ -ALWAYS_INLINE void -mpd_set_static_data(mpd_t *result) -{ - result->flags &= ~MPD_DATAFLAGS; - result->flags |= MPD_STATIC_DATA; -} - -/* Set data to shared */ -ALWAYS_INLINE void -mpd_set_shared_data(mpd_t *result) -{ - result->flags &= ~MPD_DATAFLAGS; - result->flags |= MPD_SHARED_DATA; -} - -/* Set data to const */ -ALWAYS_INLINE void -mpd_set_const_data(mpd_t *result) -{ - result->flags &= ~MPD_DATAFLAGS; - result->flags |= MPD_CONST_DATA; -} - -/* Clear flags, preserving memory attributes. */ -ALWAYS_INLINE void -mpd_clear_flags(mpd_t *result) -{ - result->flags &= (MPD_STATIC|MPD_DATAFLAGS); -} - -/* Set flags, preserving memory attributes. */ -ALWAYS_INLINE void -mpd_set_flags(mpd_t *result, uint8_t flags) -{ - result->flags &= (MPD_STATIC|MPD_DATAFLAGS); - result->flags |= flags; -} - -/* Copy flags, preserving memory attributes of result. */ -ALWAYS_INLINE void -mpd_copy_flags(mpd_t *result, const mpd_t *a) -{ - uint8_t aflags = a->flags; - result->flags &= (MPD_STATIC|MPD_DATAFLAGS); - result->flags |= (aflags & ~(MPD_STATIC|MPD_DATAFLAGS)); -} - -/* Initialize a workcontext from ctx. Set traps, flags and newtrap to 0. */ -static inline void -mpd_workcontext(mpd_context_t *workctx, const mpd_context_t *ctx) -{ - workctx->prec = ctx->prec; - workctx->emax = ctx->emax; - workctx->emin = ctx->emin; - workctx->round = ctx->round; - workctx->traps = 0; - workctx->status = 0; - workctx->newtrap = 0; - workctx->clamp = ctx->clamp; - workctx->allcr = ctx->allcr; -} - - -/******************************************************************************/ -/* Getting and setting parts of decimals */ -/******************************************************************************/ - -/* Flip the sign of a decimal */ -static inline void -_mpd_negate(mpd_t *dec) -{ - dec->flags ^= MPD_NEG; -} - -/* Set coefficient to zero */ -void -mpd_zerocoeff(mpd_t *result) -{ - mpd_minalloc(result); - result->digits = 1; - result->len = 1; - result->data[0] = 0; -} - -/* Set the coefficient to all nines. */ -void -mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status) -{ - mpd_ssize_t len, r; - - _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS); - len = (r == 0) ? len : len+1; - - if (!mpd_qresize(result, len, status)) { - return; - } - - result->len = len; - result->digits = ctx->prec; - - --len; - if (r > 0) { - result->data[len--] = mpd_pow10[r]-1; - } - for (; len >= 0; --len) { - result->data[len] = MPD_RADIX-1; - } -} - -/* - * Cut off the most significant digits so that the rest fits in ctx->prec. - * Cannot fail. - */ -static void -_mpd_cap(mpd_t *result, const mpd_context_t *ctx) -{ - uint32_t dummy; - mpd_ssize_t len, r; - - if (result->len > 0 && result->digits > ctx->prec) { - _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS); - len = (r == 0) ? len : len+1; - - if (r != 0) { - result->data[len-1] %= mpd_pow10[r]; - } - - len = _mpd_real_size(result->data, len); - /* resize to fewer words cannot fail */ - mpd_qresize(result, len, &dummy); - result->len = len; - mpd_setdigits(result); - } - if (mpd_iszero(result)) { - _settriple(result, mpd_sign(result), 0, result->exp); - } -} - -/* - * Cut off the most significant digits of a NaN payload so that the rest - * fits in ctx->prec - ctx->clamp. Cannot fail. - */ -static void -_mpd_fix_nan(mpd_t *result, const mpd_context_t *ctx) -{ - uint32_t dummy; - mpd_ssize_t prec; - mpd_ssize_t len, r; - - prec = ctx->prec - ctx->clamp; - if (result->len > 0 && result->digits > prec) { - if (prec == 0) { - mpd_minalloc(result); - result->len = result->digits = 0; - } - else { - _mpd_idiv_word(&len, &r, prec, MPD_RDIGITS); - len = (r == 0) ? len : len+1; - - if (r != 0) { - result->data[len-1] %= mpd_pow10[r]; - } - - len = _mpd_real_size(result->data, len); - /* resize to fewer words cannot fail */ - mpd_qresize(result, len, &dummy); - result->len = len; - mpd_setdigits(result); - if (mpd_iszerocoeff(result)) { - /* NaN0 is not a valid representation */ - result->len = result->digits = 0; - } - } - } -} - -/* - * Get n most significant digits from a decimal, where 0 < n <= MPD_UINT_DIGITS. - * Assumes MPD_UINT_DIGITS == MPD_RDIGITS+1, which is true for 32 and 64 bit - * machines. - * - * The result of the operation will be in lo. If the operation is impossible, - * hi will be nonzero. This is used to indicate an error. - */ -static inline void -_mpd_get_msdigits(mpd_uint_t *hi, mpd_uint_t *lo, const mpd_t *dec, - unsigned int n) -{ - mpd_uint_t r, tmp; - - assert(0 < n && n <= MPD_RDIGITS+1); - - _mpd_div_word(&tmp, &r, dec->digits, MPD_RDIGITS); - r = (r == 0) ? MPD_RDIGITS : r; /* digits in the most significant word */ - - *hi = 0; - *lo = dec->data[dec->len-1]; - if (n <= r) { - *lo /= mpd_pow10[r-n]; - } - else if (dec->len > 1) { - /* at this point 1 <= r < n <= MPD_RDIGITS+1 */ - _mpd_mul_words(hi, lo, *lo, mpd_pow10[n-r]); - tmp = dec->data[dec->len-2] / mpd_pow10[MPD_RDIGITS-(n-r)]; - *lo = *lo + tmp; - if (*lo < tmp) (*hi)++; - } -} - - -/******************************************************************************/ -/* Gathering information about a decimal */ -/******************************************************************************/ - -/* The real size of the coefficient without leading zero words. */ -static inline mpd_ssize_t -_mpd_real_size(mpd_uint_t *data, mpd_ssize_t size) -{ - while (size > 1 && data[size-1] == 0) { - size--; - } - - return size; -} - -/* Return number of trailing zeros. No errors are possible. */ -mpd_ssize_t -mpd_trail_zeros(const mpd_t *dec) -{ - mpd_uint_t word; - mpd_ssize_t i, tz = 0; - - for (i=0; i < dec->len; ++i) { - if (dec->data[i] != 0) { - word = dec->data[i]; - tz = i * MPD_RDIGITS; - while (word % 10 == 0) { - word /= 10; - tz++; - } - break; - } - } - - return tz; -} - -/* Integer: Undefined for specials */ -static int -_mpd_isint(const mpd_t *dec) -{ - mpd_ssize_t tz; - - if (mpd_iszerocoeff(dec)) { - return 1; - } - - tz = mpd_trail_zeros(dec); - return (dec->exp + tz >= 0); -} - -/* Integer */ -int -mpd_isinteger(const mpd_t *dec) -{ - if (mpd_isspecial(dec)) { - return 0; - } - return _mpd_isint(dec); -} - -/* Word is a power of 10 */ -static int -mpd_word_ispow10(mpd_uint_t word) -{ - int n; - - n = mpd_word_digits(word); - if (word == mpd_pow10[n-1]) { - return 1; - } - - return 0; -} - -/* Coefficient is a power of 10 */ -static int -mpd_coeff_ispow10(const mpd_t *dec) -{ - if (mpd_word_ispow10(mpd_msword(dec))) { - if (_mpd_isallzero(dec->data, dec->len-1)) { - return 1; - } - } - - return 0; -} - -/* All digits of a word are nines */ -static int -mpd_word_isallnine(mpd_uint_t word) -{ - int n; - - n = mpd_word_digits(word); - if (word == mpd_pow10[n]-1) { - return 1; - } - - return 0; -} - -/* All digits of the coefficient are nines */ -static int -mpd_coeff_isallnine(const mpd_t *dec) -{ - if (mpd_word_isallnine(mpd_msword(dec))) { - if (_mpd_isallnine(dec->data, dec->len-1)) { - return 1; - } - } - - return 0; -} - -/* Odd decimal: Undefined for non-integers! */ -int -mpd_isodd(const mpd_t *dec) -{ - mpd_uint_t q, r; - assert(mpd_isinteger(dec)); - if (mpd_iszerocoeff(dec)) return 0; - if (dec->exp < 0) { - _mpd_div_word(&q, &r, -dec->exp, MPD_RDIGITS); - q = dec->data[q] / mpd_pow10[r]; - return mpd_isoddword(q); - } - return dec->exp == 0 && mpd_isoddword(dec->data[0]); -} - -/* Even: Undefined for non-integers! */ -int -mpd_iseven(const mpd_t *dec) -{ - return !mpd_isodd(dec); -} - -/******************************************************************************/ -/* Getting and setting decimals */ -/******************************************************************************/ - -/* Internal function: Set a static decimal from a triple, no error checking. */ -static void -_ssettriple(mpd_t *result, uint8_t sign, mpd_uint_t a, mpd_ssize_t exp) -{ - mpd_set_flags(result, sign); - result->exp = exp; - _mpd_div_word(&result->data[1], &result->data[0], a, MPD_RADIX); - result->len = (result->data[1] == 0) ? 1 : 2; - mpd_setdigits(result); -} - -/* Internal function: Set a decimal from a triple, no error checking. */ -static void -_settriple(mpd_t *result, uint8_t sign, mpd_uint_t a, mpd_ssize_t exp) -{ - mpd_minalloc(result); - mpd_set_flags(result, sign); - result->exp = exp; - _mpd_div_word(&result->data[1], &result->data[0], a, MPD_RADIX); - result->len = (result->data[1] == 0) ? 1 : 2; - mpd_setdigits(result); -} - -/* Set a special number from a triple */ -void -mpd_setspecial(mpd_t *result, uint8_t sign, uint8_t type) -{ - mpd_minalloc(result); - result->flags &= ~(MPD_NEG|MPD_SPECIAL); - result->flags |= (sign|type); - result->exp = result->digits = result->len = 0; -} - -/* Set result of NaN with an error status */ -void -mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status) -{ - mpd_minalloc(result); - mpd_set_qnan(result); - mpd_set_positive(result); - result->exp = result->digits = result->len = 0; - *status |= flags; -} - -/* quietly set a static decimal from an mpd_ssize_t */ -void -mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_uint_t u; - uint8_t sign = MPD_POS; - - if (a < 0) { - if (a == MPD_SSIZE_MIN) { - u = (mpd_uint_t)MPD_SSIZE_MAX + - (-(MPD_SSIZE_MIN+MPD_SSIZE_MAX)); - } - else { - u = -a; - } - sign = MPD_NEG; - } - else { - u = a; - } - _ssettriple(result, sign, u, 0); - mpd_qfinalize(result, ctx, status); -} - -/* quietly set a static decimal from an mpd_uint_t */ -void -mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - _ssettriple(result, MPD_POS, a, 0); - mpd_qfinalize(result, ctx, status); -} - -/* quietly set a static decimal from an int32_t */ -void -mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_qsset_ssize(result, a, ctx, status); -} - -/* quietly set a static decimal from a uint32_t */ -void -mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_qsset_uint(result, a, ctx, status); -} - -#ifdef CONFIG_64 -/* quietly set a static decimal from an int64_t */ -void -mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_qsset_ssize(result, a, ctx, status); -} - -/* quietly set a static decimal from a uint64_t */ -void -mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_qsset_uint(result, a, ctx, status); -} -#endif - -/* quietly set a decimal from an mpd_ssize_t */ -void -mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_minalloc(result); - mpd_qsset_ssize(result, a, ctx, status); -} - -/* quietly set a decimal from an mpd_uint_t */ -void -mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - _settriple(result, MPD_POS, a, 0); - mpd_qfinalize(result, ctx, status); -} - -/* quietly set a decimal from an int32_t */ -void -mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_qset_ssize(result, a, ctx, status); -} - -/* quietly set a decimal from a uint32_t */ -void -mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_qset_uint(result, a, ctx, status); -} - -#if defined(CONFIG_32) && !defined(LEGACY_COMPILER) -/* set a decimal from a uint64_t */ -static void -_c32setu64(mpd_t *result, uint64_t u, uint8_t sign, uint32_t *status) -{ - mpd_uint_t w[3]; - uint64_t q; - int i, len; - - len = 0; - do { - q = u / MPD_RADIX; - w[len] = (mpd_uint_t)(u - q * MPD_RADIX); - u = q; len++; - } while (u != 0); - - if (!mpd_qresize(result, len, status)) { - return; - } - for (i = 0; i < len; i++) { - result->data[i] = w[i]; - } - - mpd_set_flags(result, sign); - result->exp = 0; - result->len = len; - mpd_setdigits(result); -} - -static void -_c32_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - _c32setu64(result, a, MPD_POS, status); - mpd_qfinalize(result, ctx, status); -} - -/* set a decimal from an int64_t */ -static void -_c32_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, - uint32_t *status) -{ - uint64_t u; - uint8_t sign = MPD_POS; - - if (a < 0) { - if (a == INT64_MIN) { - u = (uint64_t)INT64_MAX + (-(INT64_MIN+INT64_MAX)); - } - else { - u = -a; - } - sign = MPD_NEG; - } - else { - u = a; - } - _c32setu64(result, u, sign, status); - mpd_qfinalize(result, ctx, status); -} -#endif /* CONFIG_32 && !LEGACY_COMPILER */ - -#ifndef LEGACY_COMPILER -/* quietly set a decimal from an int64_t */ -void -mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, - uint32_t *status) -{ -#ifdef CONFIG_64 - mpd_qset_ssize(result, a, ctx, status); -#else - _c32_qset_i64(result, a, ctx, status); -#endif -} - -/* quietly set a decimal from an int64_t, use a maxcontext for conversion */ -void -mpd_qset_i64_exact(mpd_t *result, int64_t a, uint32_t *status) -{ - mpd_context_t maxcontext; - - mpd_maxcontext(&maxcontext); -#ifdef CONFIG_64 - mpd_qset_ssize(result, a, &maxcontext, status); -#else - _c32_qset_i64(result, a, &maxcontext, status); -#endif - - if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { - /* we want exact results */ - mpd_seterror(result, MPD_Invalid_operation, status); - } - *status &= MPD_Errors; -} - -/* quietly set a decimal from a uint64_t */ -void -mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, - uint32_t *status) -{ -#ifdef CONFIG_64 - mpd_qset_uint(result, a, ctx, status); -#else - _c32_qset_u64(result, a, ctx, status); -#endif -} - -/* quietly set a decimal from a uint64_t, use a maxcontext for conversion */ -void -mpd_qset_u64_exact(mpd_t *result, uint64_t a, uint32_t *status) -{ - mpd_context_t maxcontext; - - mpd_maxcontext(&maxcontext); -#ifdef CONFIG_64 - mpd_qset_uint(result, a, &maxcontext, status); -#else - _c32_qset_u64(result, a, &maxcontext, status); -#endif - - if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { - /* we want exact results */ - mpd_seterror(result, MPD_Invalid_operation, status); - } - *status &= MPD_Errors; -} -#endif /* !LEGACY_COMPILER */ - -/* - * Quietly get an mpd_uint_t from a decimal. Assumes - * MPD_UINT_DIGITS == MPD_RDIGITS+1, which is true for - * 32 and 64 bit machines. - * - * If the operation is impossible, MPD_Invalid_operation is set. - */ -static mpd_uint_t -_mpd_qget_uint(int use_sign, const mpd_t *a, uint32_t *status) -{ - mpd_t tmp; - mpd_uint_t tmp_data[2]; - mpd_uint_t lo, hi; - - if (mpd_isspecial(a)) { - *status |= MPD_Invalid_operation; - return MPD_UINT_MAX; - } - if (mpd_iszero(a)) { - return 0; - } - if (use_sign && mpd_isnegative(a)) { - *status |= MPD_Invalid_operation; - return MPD_UINT_MAX; - } - - if (a->digits+a->exp > MPD_RDIGITS+1) { - *status |= MPD_Invalid_operation; - return MPD_UINT_MAX; - } - - if (a->exp < 0) { - if (!_mpd_isint(a)) { - *status |= MPD_Invalid_operation; - return MPD_UINT_MAX; - } - /* At this point a->digits+a->exp <= MPD_RDIGITS+1, - * so the shift fits. */ - tmp.data = tmp_data; - tmp.flags = MPD_STATIC|MPD_STATIC_DATA; - tmp.alloc = 2; - mpd_qsshiftr(&tmp, a, -a->exp); - tmp.exp = 0; - a = &tmp; - } - - _mpd_get_msdigits(&hi, &lo, a, MPD_RDIGITS+1); - if (hi) { - *status |= MPD_Invalid_operation; - return MPD_UINT_MAX; - } - - if (a->exp > 0) { - _mpd_mul_words(&hi, &lo, lo, mpd_pow10[a->exp]); - if (hi) { - *status |= MPD_Invalid_operation; - return MPD_UINT_MAX; - } - } - - return lo; -} - -/* - * Sets Invalid_operation for: - * - specials - * - negative numbers (except negative zero) - * - non-integers - * - overflow - */ -mpd_uint_t -mpd_qget_uint(const mpd_t *a, uint32_t *status) -{ - return _mpd_qget_uint(1, a, status); -} - -/* Same as above, but gets the absolute value, i.e. the sign is ignored. */ -mpd_uint_t -mpd_qabs_uint(const mpd_t *a, uint32_t *status) -{ - return _mpd_qget_uint(0, a, status); -} - -/* quietly get an mpd_ssize_t from a decimal */ -mpd_ssize_t -mpd_qget_ssize(const mpd_t *a, uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_uint_t u; - int isneg; - - u = mpd_qabs_uint(a, &workstatus); - if (workstatus&MPD_Invalid_operation) { - *status |= workstatus; - return MPD_SSIZE_MAX; - } - - isneg = mpd_isnegative(a); - if (u <= MPD_SSIZE_MAX) { - return isneg ? -((mpd_ssize_t)u) : (mpd_ssize_t)u; - } - else if (isneg && u+(MPD_SSIZE_MIN+MPD_SSIZE_MAX) == MPD_SSIZE_MAX) { - return MPD_SSIZE_MIN; - } - - *status |= MPD_Invalid_operation; - return MPD_SSIZE_MAX; -} - -#if defined(CONFIG_32) && !defined(LEGACY_COMPILER) -/* - * Quietly get a uint64_t from a decimal. If the operation is impossible, - * MPD_Invalid_operation is set. - */ -static uint64_t -_c32_qget_u64(int use_sign, const mpd_t *a, uint32_t *status) -{ - MPD_NEW_STATIC(tmp,0,0,20,3); - mpd_context_t maxcontext; - uint64_t ret; - - tmp_data[0] = 709551615; - tmp_data[1] = 446744073; - tmp_data[2] = 18; - - if (mpd_isspecial(a)) { - *status |= MPD_Invalid_operation; - return UINT64_MAX; - } - if (mpd_iszero(a)) { - return 0; - } - if (use_sign && mpd_isnegative(a)) { - *status |= MPD_Invalid_operation; - return UINT64_MAX; - } - if (!_mpd_isint(a)) { - *status |= MPD_Invalid_operation; - return UINT64_MAX; - } - - if (_mpd_cmp_abs(a, &tmp) > 0) { - *status |= MPD_Invalid_operation; - return UINT64_MAX; - } - - mpd_maxcontext(&maxcontext); - mpd_qrescale(&tmp, a, 0, &maxcontext, &maxcontext.status); - maxcontext.status &= ~MPD_Rounded; - if (maxcontext.status != 0) { - *status |= (maxcontext.status|MPD_Invalid_operation); /* GCOV_NOT_REACHED */ - return UINT64_MAX; /* GCOV_NOT_REACHED */ - } - - ret = 0; - switch (tmp.len) { - case 3: - ret += (uint64_t)tmp_data[2] * 1000000000000000000ULL; - case 2: - ret += (uint64_t)tmp_data[1] * 1000000000ULL; - case 1: - ret += tmp_data[0]; - break; - default: - abort(); /* GCOV_NOT_REACHED */ - } - - return ret; -} - -static int64_t -_c32_qget_i64(const mpd_t *a, uint32_t *status) -{ - uint64_t u; - int isneg; - - u = _c32_qget_u64(0, a, status); - if (*status&MPD_Invalid_operation) { - return INT64_MAX; - } - - isneg = mpd_isnegative(a); - if (u <= INT64_MAX) { - return isneg ? -((int64_t)u) : (int64_t)u; - } - else if (isneg && u+(INT64_MIN+INT64_MAX) == INT64_MAX) { - return INT64_MIN; - } - - *status |= MPD_Invalid_operation; - return INT64_MAX; -} -#endif /* CONFIG_32 && !LEGACY_COMPILER */ - -#ifdef CONFIG_64 -/* quietly get a uint64_t from a decimal */ -uint64_t -mpd_qget_u64(const mpd_t *a, uint32_t *status) -{ - return mpd_qget_uint(a, status); -} - -/* quietly get an int64_t from a decimal */ -int64_t -mpd_qget_i64(const mpd_t *a, uint32_t *status) -{ - return mpd_qget_ssize(a, status); -} - -/* quietly get a uint32_t from a decimal */ -uint32_t -mpd_qget_u32(const mpd_t *a, uint32_t *status) -{ - uint32_t workstatus = 0; - uint64_t x = mpd_qget_uint(a, &workstatus); - - if (workstatus&MPD_Invalid_operation) { - *status |= workstatus; - return UINT32_MAX; - } - if (x > UINT32_MAX) { - *status |= MPD_Invalid_operation; - return UINT32_MAX; - } - - return (uint32_t)x; -} - -/* quietly get an int32_t from a decimal */ -int32_t -mpd_qget_i32(const mpd_t *a, uint32_t *status) -{ - uint32_t workstatus = 0; - int64_t x = mpd_qget_ssize(a, &workstatus); - - if (workstatus&MPD_Invalid_operation) { - *status |= workstatus; - return INT32_MAX; - } - if (x < INT32_MIN || x > INT32_MAX) { - *status |= MPD_Invalid_operation; - return INT32_MAX; - } - - return (int32_t)x; -} -#else -#ifndef LEGACY_COMPILER -/* quietly get a uint64_t from a decimal */ -uint64_t -mpd_qget_u64(const mpd_t *a, uint32_t *status) -{ - uint32_t workstatus = 0; - uint64_t x = _c32_qget_u64(1, a, &workstatus); - *status |= workstatus; - return x; -} - -/* quietly get an int64_t from a decimal */ -int64_t -mpd_qget_i64(const mpd_t *a, uint32_t *status) -{ - uint32_t workstatus = 0; - int64_t x = _c32_qget_i64(a, &workstatus); - *status |= workstatus; - return x; -} -#endif - -/* quietly get a uint32_t from a decimal */ -uint32_t -mpd_qget_u32(const mpd_t *a, uint32_t *status) -{ - return mpd_qget_uint(a, status); -} - -/* quietly get an int32_t from a decimal */ -int32_t -mpd_qget_i32(const mpd_t *a, uint32_t *status) -{ - return mpd_qget_ssize(a, status); -} -#endif - - -/******************************************************************************/ -/* Filtering input of functions, finalizing output of functions */ -/******************************************************************************/ - -/* - * Check if the operand is NaN, copy to result and return 1 if this is - * the case. Copying can fail since NaNs are allowed to have a payload that - * does not fit in MPD_MINALLOC. - */ -int -mpd_qcheck_nan(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - if (mpd_isnan(a)) { - *status |= mpd_issnan(a) ? MPD_Invalid_operation : 0; - mpd_qcopy(result, a, status); - mpd_set_qnan(result); - _mpd_fix_nan(result, ctx); - return 1; - } - return 0; -} - -/* - * Check if either operand is NaN, copy to result and return 1 if this - * is the case. Copying can fail since NaNs are allowed to have a payload - * that does not fit in MPD_MINALLOC. - */ -int -mpd_qcheck_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - if ((a->flags|b->flags)&(MPD_NAN|MPD_SNAN)) { - const mpd_t *choice = b; - if (mpd_issnan(a)) { - choice = a; - *status |= MPD_Invalid_operation; - } - else if (mpd_issnan(b)) { - *status |= MPD_Invalid_operation; - } - else if (mpd_isqnan(a)) { - choice = a; - } - mpd_qcopy(result, choice, status); - mpd_set_qnan(result); - _mpd_fix_nan(result, ctx); - return 1; - } - return 0; -} - -/* - * Check if one of the operands is NaN, copy to result and return 1 if this - * is the case. Copying can fail since NaNs are allowed to have a payload - * that does not fit in MPD_MINALLOC. - */ -static int -mpd_qcheck_3nans(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, - const mpd_context_t *ctx, uint32_t *status) -{ - if ((a->flags|b->flags|c->flags)&(MPD_NAN|MPD_SNAN)) { - const mpd_t *choice = c; - if (mpd_issnan(a)) { - choice = a; - *status |= MPD_Invalid_operation; - } - else if (mpd_issnan(b)) { - choice = b; - *status |= MPD_Invalid_operation; - } - else if (mpd_issnan(c)) { - *status |= MPD_Invalid_operation; - } - else if (mpd_isqnan(a)) { - choice = a; - } - else if (mpd_isqnan(b)) { - choice = b; - } - mpd_qcopy(result, choice, status); - mpd_set_qnan(result); - _mpd_fix_nan(result, ctx); - return 1; - } - return 0; -} - -/* Check if rounding digit 'rnd' leads to an increment. */ -static inline int -_mpd_rnd_incr(const mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx) -{ - int ld; - - switch (ctx->round) { - case MPD_ROUND_DOWN: case MPD_ROUND_TRUNC: - return 0; - case MPD_ROUND_HALF_UP: - return (rnd >= 5); - case MPD_ROUND_HALF_EVEN: - return (rnd > 5) || ((rnd == 5) && mpd_isoddcoeff(dec)); - case MPD_ROUND_CEILING: - return !(rnd == 0 || mpd_isnegative(dec)); - case MPD_ROUND_FLOOR: - return !(rnd == 0 || mpd_ispositive(dec)); - case MPD_ROUND_HALF_DOWN: - return (rnd > 5); - case MPD_ROUND_UP: - return !(rnd == 0); - case MPD_ROUND_05UP: - ld = (int)mpd_lsd(dec->data[0]); - return (!(rnd == 0) && (ld == 0 || ld == 5)); - default: - /* Without a valid context, further results will be undefined. */ - return 0; /* GCOV_NOT_REACHED */ - } -} - -/* - * Apply rounding to a decimal that has been right-shifted into a full - * precision decimal. If an increment leads to an overflow of the precision, - * adjust the coefficient and the exponent and check the new exponent for - * overflow. - */ -static inline void -_mpd_apply_round(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx, - uint32_t *status) -{ - if (_mpd_rnd_incr(dec, rnd, ctx)) { - /* We have a number with exactly ctx->prec digits. The increment - * can only lead to an overflow if the decimal is all nines. In - * that case, the result is a power of ten with prec+1 digits. - * - * If the precision is a multiple of MPD_RDIGITS, this situation is - * detected by _mpd_baseincr returning a carry. - * If the precision is not a multiple of MPD_RDIGITS, we have to - * check if the result has one digit too many. - */ - mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len); - if (carry) { - dec->data[dec->len-1] = mpd_pow10[MPD_RDIGITS-1]; - dec->exp += 1; - _mpd_check_exp(dec, ctx, status); - return; - } - mpd_setdigits(dec); - if (dec->digits > ctx->prec) { - mpd_qshiftr_inplace(dec, 1); - dec->exp += 1; - dec->digits = ctx->prec; - _mpd_check_exp(dec, ctx, status); - } - } -} - -/* - * Apply rounding to a decimal. Allow overflow of the precision. - */ -static inline void -_mpd_apply_round_excess(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx, - uint32_t *status) -{ - if (_mpd_rnd_incr(dec, rnd, ctx)) { - mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len); - if (carry) { - if (!mpd_qresize(dec, dec->len+1, status)) { - return; - } - dec->data[dec->len] = 1; - dec->len += 1; - } - mpd_setdigits(dec); - } -} - -/* - * Apply rounding to a decimal that has been right-shifted into a decimal - * with full precision or less. Return failure if an increment would - * overflow the precision. - */ -static inline int -_mpd_apply_round_fit(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx, - uint32_t *status) -{ - if (_mpd_rnd_incr(dec, rnd, ctx)) { - mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len); - if (carry) { - if (!mpd_qresize(dec, dec->len+1, status)) { - return 0; - } - dec->data[dec->len] = 1; - dec->len += 1; - } - mpd_setdigits(dec); - if (dec->digits > ctx->prec) { - mpd_seterror(dec, MPD_Invalid_operation, status); - return 0; - } - } - return 1; -} - -/* Check a normal number for overflow, underflow, clamping. If the operand - is modified, it will be zero, special or (sub)normal with a coefficient - that fits into the current context precision. */ -static inline void -_mpd_check_exp(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status) -{ - mpd_ssize_t adjexp, etiny, shift; - int rnd; - - adjexp = mpd_adjexp(dec); - if (adjexp > ctx->emax) { - - if (mpd_iszerocoeff(dec)) { - dec->exp = ctx->emax; - if (ctx->clamp) { - dec->exp -= (ctx->prec-1); - } - mpd_zerocoeff(dec); - *status |= MPD_Clamped; - return; - } - - switch (ctx->round) { - case MPD_ROUND_HALF_UP: case MPD_ROUND_HALF_EVEN: - case MPD_ROUND_HALF_DOWN: case MPD_ROUND_UP: - case MPD_ROUND_TRUNC: - mpd_setspecial(dec, mpd_sign(dec), MPD_INF); - break; - case MPD_ROUND_DOWN: case MPD_ROUND_05UP: - mpd_qmaxcoeff(dec, ctx, status); - dec->exp = ctx->emax - ctx->prec + 1; - break; - case MPD_ROUND_CEILING: - if (mpd_isnegative(dec)) { - mpd_qmaxcoeff(dec, ctx, status); - dec->exp = ctx->emax - ctx->prec + 1; - } - else { - mpd_setspecial(dec, MPD_POS, MPD_INF); - } - break; - case MPD_ROUND_FLOOR: - if (mpd_ispositive(dec)) { - mpd_qmaxcoeff(dec, ctx, status); - dec->exp = ctx->emax - ctx->prec + 1; - } - else { - mpd_setspecial(dec, MPD_NEG, MPD_INF); - } - break; - default: /* debug */ - abort(); /* GCOV_NOT_REACHED */ - } - - *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; - - } /* fold down */ - else if (ctx->clamp && dec->exp > mpd_etop(ctx)) { - /* At this point adjexp=exp+digits-1 <= emax and exp > etop=emax-prec+1: - * (1) shift = exp -emax+prec-1 > 0 - * (2) digits+shift = exp+digits-1 - emax + prec <= prec */ - shift = dec->exp - mpd_etop(ctx); - if (!mpd_qshiftl(dec, dec, shift, status)) { - return; - } - dec->exp -= shift; - *status |= MPD_Clamped; - if (!mpd_iszerocoeff(dec) && adjexp < ctx->emin) { - /* Underflow is impossible, since exp < etiny=emin-prec+1 - * and exp > etop=emax-prec+1 would imply emax < emin. */ - *status |= MPD_Subnormal; - } - } - else if (adjexp < ctx->emin) { - - etiny = mpd_etiny(ctx); - - if (mpd_iszerocoeff(dec)) { - if (dec->exp < etiny) { - dec->exp = etiny; - mpd_zerocoeff(dec); - *status |= MPD_Clamped; - } - return; - } - - *status |= MPD_Subnormal; - if (dec->exp < etiny) { - /* At this point adjexp=exp+digits-1 < emin and exp < etiny=emin-prec+1: - * (1) shift = emin-prec+1 - exp > 0 - * (2) digits-shift = exp+digits-1 - emin + prec < prec */ - shift = etiny - dec->exp; - rnd = (int)mpd_qshiftr_inplace(dec, shift); - dec->exp = etiny; - /* We always have a spare digit in case of an increment. */ - _mpd_apply_round_excess(dec, rnd, ctx, status); - *status |= MPD_Rounded; - if (rnd) { - *status |= (MPD_Inexact|MPD_Underflow); - if (mpd_iszerocoeff(dec)) { - mpd_zerocoeff(dec); - *status |= MPD_Clamped; - } - } - } - /* Case exp >= etiny=emin-prec+1: - * (1) adjexp=exp+digits-1 < emin - * (2) digits < emin-exp+1 <= prec */ - } -} - -/* Transcendental functions do not always set Underflow reliably, - * since they only use as much precision as is necessary for correct - * rounding. If a result like 1.0000000000e-101 is finalized, there - * is no rounding digit that would trigger Underflow. But we can - * assume Inexact, so a short check suffices. */ -static inline void -mpd_check_underflow(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status) -{ - if (mpd_adjexp(dec) < ctx->emin && !mpd_iszero(dec) && - dec->exp < mpd_etiny(ctx)) { - *status |= MPD_Underflow; - } -} - -/* Check if a normal number must be rounded after the exponent has been checked. */ -static inline void -_mpd_check_round(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status) -{ - mpd_uint_t rnd; - mpd_ssize_t shift; - - /* must handle specials: _mpd_check_exp() can produce infinities or NaNs */ - if (mpd_isspecial(dec)) { - return; - } - - if (dec->digits > ctx->prec) { - shift = dec->digits - ctx->prec; - rnd = mpd_qshiftr_inplace(dec, shift); - dec->exp += shift; - _mpd_apply_round(dec, rnd, ctx, status); - *status |= MPD_Rounded; - if (rnd) { - *status |= MPD_Inexact; - } - } -} - -/* Finalize all operations. */ -void -mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status) -{ - if (mpd_isspecial(result)) { - if (mpd_isnan(result)) { - _mpd_fix_nan(result, ctx); - } - return; - } - - _mpd_check_exp(result, ctx, status); - _mpd_check_round(result, ctx, status); -} - - -/******************************************************************************/ -/* Copying */ -/******************************************************************************/ - -/* Internal function: Copy a decimal, share data with src: USE WITH CARE! */ -static inline void -_mpd_copy_shared(mpd_t *dest, const mpd_t *src) -{ - dest->flags = src->flags; - dest->exp = src->exp; - dest->digits = src->digits; - dest->len = src->len; - dest->alloc = src->alloc; - dest->data = src->data; - - mpd_set_shared_data(dest); -} - -/* - * Copy a decimal. In case of an error, status is set to MPD_Malloc_error. - */ -int -mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status) -{ - if (result == a) return 1; - - if (!mpd_qresize(result, a->len, status)) { - return 0; - } - - mpd_copy_flags(result, a); - result->exp = a->exp; - result->digits = a->digits; - result->len = a->len; - memcpy(result->data, a->data, a->len * (sizeof *result->data)); - - return 1; -} - -/* Same as mpd_qcopy, but do not set the result to NaN on failure. */ -int -mpd_qcopy_cxx(mpd_t *result, const mpd_t *a) -{ - if (result == a) return 1; - - if (!mpd_qresize_cxx(result, a->len)) { - return 0; - } - - mpd_copy_flags(result, a); - result->exp = a->exp; - result->digits = a->digits; - result->len = a->len; - memcpy(result->data, a->data, a->len * (sizeof *result->data)); - - return 1; -} - -/* - * Copy to a decimal with a static buffer. The caller has to make sure that - * the buffer is big enough. Cannot fail. - */ -static void -mpd_qcopy_static(mpd_t *result, const mpd_t *a) -{ - if (result == a) return; - - memcpy(result->data, a->data, a->len * (sizeof *result->data)); - - mpd_copy_flags(result, a); - result->exp = a->exp; - result->digits = a->digits; - result->len = a->len; -} - -/* - * Return a newly allocated copy of the operand. In case of an error, - * status is set to MPD_Malloc_error and the return value is NULL. - */ -mpd_t * -mpd_qncopy(const mpd_t *a) -{ - mpd_t *result; - - if ((result = mpd_qnew_size(a->len)) == NULL) { - return NULL; - } - memcpy(result->data, a->data, a->len * (sizeof *result->data)); - mpd_copy_flags(result, a); - result->exp = a->exp; - result->digits = a->digits; - result->len = a->len; - - return result; -} - -/* - * Copy a decimal and set the sign to positive. In case of an error, the - * status is set to MPD_Malloc_error. - */ -int -mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status) -{ - if (!mpd_qcopy(result, a, status)) { - return 0; - } - mpd_set_positive(result); - return 1; -} - -/* - * Copy a decimal and negate the sign. In case of an error, the - * status is set to MPD_Malloc_error. - */ -int -mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status) -{ - if (!mpd_qcopy(result, a, status)) { - return 0; - } - _mpd_negate(result); - return 1; -} - -/* - * Copy a decimal, setting the sign of the first operand to the sign of the - * second operand. In case of an error, the status is set to MPD_Malloc_error. - */ -int -mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status) -{ - uint8_t sign_b = mpd_sign(b); /* result may equal b! */ - - if (!mpd_qcopy(result, a, status)) { - return 0; - } - mpd_set_sign(result, sign_b); - return 1; -} - - -/******************************************************************************/ -/* Comparisons */ -/******************************************************************************/ - -/* - * For all functions that compare two operands and return an int the usual - * convention applies to the return value: - * - * -1 if op1 < op2 - * 0 if op1 == op2 - * 1 if op1 > op2 - * - * INT_MAX for error - */ - - -/* Convenience macro. If a and b are not equal, return from the calling - * function with the correct comparison value. */ -#define CMP_EQUAL_OR_RETURN(a, b) \ - if (a != b) { \ - if (a < b) { \ - return -1; \ - } \ - return 1; \ - } - -/* - * Compare the data of big and small. This function does the equivalent - * of first shifting small to the left and then comparing the data of - * big and small, except that no allocation for the left shift is needed. - */ -static int -_mpd_basecmp(mpd_uint_t *big, mpd_uint_t *small, mpd_size_t n, mpd_size_t m, - mpd_size_t shift) -{ -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) - /* spurious uninitialized warnings */ - mpd_uint_t l=l, lprev=lprev, h=h; -#else - mpd_uint_t l, lprev, h; -#endif - mpd_uint_t q, r; - mpd_uint_t ph, x; - - assert(m > 0 && n >= m && shift > 0); - - _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS); - - if (r != 0) { - - ph = mpd_pow10[r]; - - --m; --n; - _mpd_divmod_pow10(&h, &lprev, small[m--], MPD_RDIGITS-r); - if (h != 0) { - CMP_EQUAL_OR_RETURN(big[n], h) - --n; - } - for (; m != MPD_SIZE_MAX; m--,n--) { - _mpd_divmod_pow10(&h, &l, small[m], MPD_RDIGITS-r); - x = ph * lprev + h; - CMP_EQUAL_OR_RETURN(big[n], x) - lprev = l; - } - x = ph * lprev; - CMP_EQUAL_OR_RETURN(big[q], x) - } - else { - while (--m != MPD_SIZE_MAX) { - CMP_EQUAL_OR_RETURN(big[m+q], small[m]) - } - } - - return !_mpd_isallzero(big, q); -} - -/* Compare two decimals with the same adjusted exponent. */ -static int -_mpd_cmp_same_adjexp(const mpd_t *a, const mpd_t *b) -{ - mpd_ssize_t shift, i; - - if (a->exp != b->exp) { - /* Cannot wrap: a->exp + a->digits = b->exp + b->digits, so - * a->exp - b->exp = b->digits - a->digits. */ - shift = a->exp - b->exp; - if (shift > 0) { - return -1 * _mpd_basecmp(b->data, a->data, b->len, a->len, shift); - } - else { - return _mpd_basecmp(a->data, b->data, a->len, b->len, -shift); - } - } - - /* - * At this point adjexp(a) == adjexp(b) and a->exp == b->exp, - * so a->digits == b->digits, therefore a->len == b->len. - */ - for (i = a->len-1; i >= 0; --i) { - CMP_EQUAL_OR_RETURN(a->data[i], b->data[i]) - } - - return 0; -} - -/* Compare two numerical values. */ -static int -_mpd_cmp(const mpd_t *a, const mpd_t *b) -{ - mpd_ssize_t adjexp_a, adjexp_b; - - /* equal pointers */ - if (a == b) { - return 0; - } - - /* infinities */ - if (mpd_isinfinite(a)) { - if (mpd_isinfinite(b)) { - return mpd_isnegative(b) - mpd_isnegative(a); - } - return mpd_arith_sign(a); - } - if (mpd_isinfinite(b)) { - return -mpd_arith_sign(b); - } - - /* zeros */ - if (mpd_iszerocoeff(a)) { - if (mpd_iszerocoeff(b)) { - return 0; - } - return -mpd_arith_sign(b); - } - if (mpd_iszerocoeff(b)) { - return mpd_arith_sign(a); - } - - /* different signs */ - if (mpd_sign(a) != mpd_sign(b)) { - return mpd_sign(b) - mpd_sign(a); - } - - /* different adjusted exponents */ - adjexp_a = mpd_adjexp(a); - adjexp_b = mpd_adjexp(b); - if (adjexp_a != adjexp_b) { - if (adjexp_a < adjexp_b) { - return -1 * mpd_arith_sign(a); - } - return mpd_arith_sign(a); - } - - /* same adjusted exponents */ - return _mpd_cmp_same_adjexp(a, b) * mpd_arith_sign(a); -} - -/* Compare the absolutes of two numerical values. */ -static int -_mpd_cmp_abs(const mpd_t *a, const mpd_t *b) -{ - mpd_ssize_t adjexp_a, adjexp_b; - - /* equal pointers */ - if (a == b) { - return 0; - } - - /* infinities */ - if (mpd_isinfinite(a)) { - if (mpd_isinfinite(b)) { - return 0; - } - return 1; - } - if (mpd_isinfinite(b)) { - return -1; - } - - /* zeros */ - if (mpd_iszerocoeff(a)) { - if (mpd_iszerocoeff(b)) { - return 0; - } - return -1; - } - if (mpd_iszerocoeff(b)) { - return 1; - } - - /* different adjusted exponents */ - adjexp_a = mpd_adjexp(a); - adjexp_b = mpd_adjexp(b); - if (adjexp_a != adjexp_b) { - if (adjexp_a < adjexp_b) { - return -1; - } - return 1; - } - - /* same adjusted exponents */ - return _mpd_cmp_same_adjexp(a, b); -} - -/* Compare two values and return an integer result. */ -int -mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status) -{ - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_isnan(a) || mpd_isnan(b)) { - *status |= MPD_Invalid_operation; - return INT_MAX; - } - } - - return _mpd_cmp(a, b); -} - -/* - * Compare a and b, convert the usual integer result to a decimal and - * store it in 'result'. For convenience, the integer result of the comparison - * is returned. Comparisons involving NaNs return NaN/INT_MAX. - */ -int -mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - int c; - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return INT_MAX; - } - } - - c = _mpd_cmp(a, b); - _settriple(result, (c < 0), (c != 0), 0); - return c; -} - -/* Same as mpd_compare(), but signal for all NaNs, i.e. also for quiet NaNs. */ -int -mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - int c; - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - *status |= MPD_Invalid_operation; - return INT_MAX; - } - } - - c = _mpd_cmp(a, b); - _settriple(result, (c < 0), (c != 0), 0); - return c; -} - -/* Compare the operands using a total order. */ -int -mpd_cmp_total(const mpd_t *a, const mpd_t *b) -{ - mpd_t aa, bb; - int nan_a, nan_b; - int c; - - if (mpd_sign(a) != mpd_sign(b)) { - return mpd_sign(b) - mpd_sign(a); - } - - - if (mpd_isnan(a)) { - c = 1; - if (mpd_isnan(b)) { - nan_a = (mpd_isqnan(a)) ? 1 : 0; - nan_b = (mpd_isqnan(b)) ? 1 : 0; - if (nan_b == nan_a) { - if (a->len > 0 && b->len > 0) { - _mpd_copy_shared(&aa, a); - _mpd_copy_shared(&bb, b); - aa.exp = bb.exp = 0; - /* compare payload */ - c = _mpd_cmp_abs(&aa, &bb); - } - else { - c = (a->len > 0) - (b->len > 0); - } - } - else { - c = nan_a - nan_b; - } - } - } - else if (mpd_isnan(b)) { - c = -1; - } - else { - c = _mpd_cmp_abs(a, b); - if (c == 0 && a->exp != b->exp) { - c = (a->exp < b->exp) ? -1 : 1; - } - } - - return c * mpd_arith_sign(a); -} - -/* - * Compare a and b according to a total order, convert the usual integer result - * to a decimal and store it in 'result'. For convenience, the integer result - * of the comparison is returned. - */ -int -mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b) -{ - int c; - - c = mpd_cmp_total(a, b); - _settriple(result, (c < 0), (c != 0), 0); - return c; -} - -/* Compare the magnitude of the operands using a total order. */ -int -mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b) -{ - mpd_t aa, bb; - - _mpd_copy_shared(&aa, a); - _mpd_copy_shared(&bb, b); - - mpd_set_positive(&aa); - mpd_set_positive(&bb); - - return mpd_cmp_total(&aa, &bb); -} - -/* - * Compare the magnitude of a and b according to a total order, convert the - * the usual integer result to a decimal and store it in 'result'. - * For convenience, the integer result of the comparison is returned. - */ -int -mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b) -{ - int c; - - c = mpd_cmp_total_mag(a, b); - _settriple(result, (c < 0), (c != 0), 0); - return c; -} - -/* Determine an ordering for operands that are numerically equal. */ -static inline int -_mpd_cmp_numequal(const mpd_t *a, const mpd_t *b) -{ - int sign_a, sign_b; - int c; - - sign_a = mpd_sign(a); - sign_b = mpd_sign(b); - if (sign_a != sign_b) { - c = sign_b - sign_a; - } - else { - c = (a->exp < b->exp) ? -1 : 1; - c *= mpd_arith_sign(a); - } - - return c; -} - - -/******************************************************************************/ -/* Shifting the coefficient */ -/******************************************************************************/ - -/* - * Shift the coefficient of the operand to the left, no check for specials. - * Both operands may be the same pointer. If the result length has to be - * increased, mpd_qresize() might fail with MPD_Malloc_error. - */ -int -mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status) -{ - mpd_ssize_t size; - - assert(!mpd_isspecial(a)); - assert(n >= 0); - - if (mpd_iszerocoeff(a) || n == 0) { - return mpd_qcopy(result, a, status); - } - - size = mpd_digits_to_size(a->digits+n); - if (!mpd_qresize(result, size, status)) { - return 0; /* result is NaN */ - } - - _mpd_baseshiftl(result->data, a->data, size, a->len, n); - - mpd_copy_flags(result, a); - result->exp = a->exp; - result->digits = a->digits+n; - result->len = size; - - return 1; -} - -/* Determine the rounding indicator if all digits of the coefficient are shifted - * out of the picture. */ -static mpd_uint_t -_mpd_get_rnd(const mpd_uint_t *data, mpd_ssize_t len, int use_msd) -{ - mpd_uint_t rnd = 0, rest = 0, word; - - word = data[len-1]; - /* special treatment for the most significant digit if shift == digits */ - if (use_msd) { - _mpd_divmod_pow10(&rnd, &rest, word, mpd_word_digits(word)-1); - if (len > 1 && rest == 0) { - rest = !_mpd_isallzero(data, len-1); - } - } - else { - rest = !_mpd_isallzero(data, len); - } - - return (rnd == 0 || rnd == 5) ? rnd + !!rest : rnd; -} - -/* - * Same as mpd_qshiftr(), but 'result' is an mpd_t with a static coefficient. - * It is the caller's responsibility to ensure that the coefficient is big - * enough. The function cannot fail. - */ -static mpd_uint_t -mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n) -{ - mpd_uint_t rnd; - mpd_ssize_t size; - - assert(!mpd_isspecial(a)); - assert(n >= 0); - - if (mpd_iszerocoeff(a) || n == 0) { - mpd_qcopy_static(result, a); - return 0; - } - - if (n >= a->digits) { - rnd = _mpd_get_rnd(a->data, a->len, (n==a->digits)); - mpd_zerocoeff(result); - } - else { - result->digits = a->digits-n; - size = mpd_digits_to_size(result->digits); - rnd = _mpd_baseshiftr(result->data, a->data, a->len, n); - result->len = size; - } - - mpd_copy_flags(result, a); - result->exp = a->exp; - - return rnd; -} - -/* - * Inplace shift of the coefficient to the right, no check for specials. - * Returns the rounding indicator for mpd_rnd_incr(). - * The function cannot fail. - */ -mpd_uint_t -mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n) -{ - uint32_t dummy; - mpd_uint_t rnd; - mpd_ssize_t size; - - assert(!mpd_isspecial(result)); - assert(n >= 0); - - if (mpd_iszerocoeff(result) || n == 0) { - return 0; - } - - if (n >= result->digits) { - rnd = _mpd_get_rnd(result->data, result->len, (n==result->digits)); - mpd_zerocoeff(result); - } - else { - rnd = _mpd_baseshiftr(result->data, result->data, result->len, n); - result->digits -= n; - size = mpd_digits_to_size(result->digits); - /* reducing the size cannot fail */ - mpd_qresize(result, size, &dummy); - result->len = size; - } - - return rnd; -} - -/* - * Shift the coefficient of the operand to the right, no check for specials. - * Both operands may be the same pointer. Returns the rounding indicator to - * be used by mpd_rnd_incr(). If the result length has to be increased, - * mpd_qcopy() or mpd_qresize() might fail with MPD_Malloc_error. In those - * cases, MPD_UINT_MAX is returned. - */ -mpd_uint_t -mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status) -{ - mpd_uint_t rnd; - mpd_ssize_t size; - - assert(!mpd_isspecial(a)); - assert(n >= 0); - - if (mpd_iszerocoeff(a) || n == 0) { - if (!mpd_qcopy(result, a, status)) { - return MPD_UINT_MAX; - } - return 0; - } - - if (n >= a->digits) { - rnd = _mpd_get_rnd(a->data, a->len, (n==a->digits)); - mpd_zerocoeff(result); - } - else { - result->digits = a->digits-n; - size = mpd_digits_to_size(result->digits); - if (result == a) { - rnd = _mpd_baseshiftr(result->data, a->data, a->len, n); - /* reducing the size cannot fail */ - mpd_qresize(result, size, status); - } - else { - if (!mpd_qresize(result, size, status)) { - return MPD_UINT_MAX; - } - rnd = _mpd_baseshiftr(result->data, a->data, a->len, n); - } - result->len = size; - } - - mpd_copy_flags(result, a); - result->exp = a->exp; - - return rnd; -} - - -/******************************************************************************/ -/* Miscellaneous operations */ -/******************************************************************************/ - -/* Logical And */ -void -mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - const mpd_t *big = a, *small = b; - mpd_uint_t x, y, z, xbit, ybit; - int k, mswdigits; - mpd_ssize_t i; - - if (mpd_isspecial(a) || mpd_isspecial(b) || - mpd_isnegative(a) || mpd_isnegative(b) || - a->exp != 0 || b->exp != 0) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (b->digits > a->digits) { - big = b; - small = a; - } - if (!mpd_qresize(result, big->len, status)) { - return; - } - - - /* full words */ - for (i = 0; i < small->len-1; i++) { - x = small->data[i]; - y = big->data[i]; - z = 0; - for (k = 0; k < MPD_RDIGITS; k++) { - xbit = x % 10; - x /= 10; - ybit = y % 10; - y /= 10; - if (xbit > 1 || ybit > 1) { - goto invalid_operation; - } - z += (xbit&ybit) ? mpd_pow10[k] : 0; - } - result->data[i] = z; - } - /* most significant word of small */ - x = small->data[i]; - y = big->data[i]; - z = 0; - mswdigits = mpd_word_digits(x); - for (k = 0; k < mswdigits; k++) { - xbit = x % 10; - x /= 10; - ybit = y % 10; - y /= 10; - if (xbit > 1 || ybit > 1) { - goto invalid_operation; - } - z += (xbit&ybit) ? mpd_pow10[k] : 0; - } - result->data[i++] = z; - - /* scan the rest of y for digits > 1 */ - for (; k < MPD_RDIGITS; k++) { - ybit = y % 10; - y /= 10; - if (ybit > 1) { - goto invalid_operation; - } - } - /* scan the rest of big for digits > 1 */ - for (; i < big->len; i++) { - y = big->data[i]; - for (k = 0; k < MPD_RDIGITS; k++) { - ybit = y % 10; - y /= 10; - if (ybit > 1) { - goto invalid_operation; - } - } - } - - mpd_clear_flags(result); - result->exp = 0; - result->len = _mpd_real_size(result->data, small->len); - mpd_qresize(result, result->len, status); - mpd_setdigits(result); - _mpd_cap(result, ctx); - return; - -invalid_operation: - mpd_seterror(result, MPD_Invalid_operation, status); -} - -/* Class of an operand. Returns a pointer to the constant name. */ -const char * -mpd_class(const mpd_t *a, const mpd_context_t *ctx) -{ - if (mpd_isnan(a)) { - if (mpd_isqnan(a)) - return "NaN"; - else - return "sNaN"; - } - else if (mpd_ispositive(a)) { - if (mpd_isinfinite(a)) - return "+Infinity"; - else if (mpd_iszero(a)) - return "+Zero"; - else if (mpd_isnormal(a, ctx)) - return "+Normal"; - else - return "+Subnormal"; - } - else { - if (mpd_isinfinite(a)) - return "-Infinity"; - else if (mpd_iszero(a)) - return "-Zero"; - else if (mpd_isnormal(a, ctx)) - return "-Normal"; - else - return "-Subnormal"; - } -} - -/* Logical Xor */ -void -mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_uint_t x, z, xbit; - mpd_ssize_t i, digits, len; - mpd_ssize_t q, r; - int k; - - if (mpd_isspecial(a) || mpd_isnegative(a) || a->exp != 0) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - digits = (a->digits < ctx->prec) ? ctx->prec : a->digits; - _mpd_idiv_word(&q, &r, digits, MPD_RDIGITS); - len = (r == 0) ? q : q+1; - if (!mpd_qresize(result, len, status)) { - return; - } - - for (i = 0; i < len; i++) { - x = (i < a->len) ? a->data[i] : 0; - z = 0; - for (k = 0; k < MPD_RDIGITS; k++) { - xbit = x % 10; - x /= 10; - if (xbit > 1) { - goto invalid_operation; - } - z += !xbit ? mpd_pow10[k] : 0; - } - result->data[i] = z; - } - - mpd_clear_flags(result); - result->exp = 0; - result->len = _mpd_real_size(result->data, len); - mpd_qresize(result, result->len, status); - mpd_setdigits(result); - _mpd_cap(result, ctx); - return; - -invalid_operation: - mpd_seterror(result, MPD_Invalid_operation, status); -} - -/* Exponent of the magnitude of the most significant digit of the operand. */ -void -mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - mpd_setspecial(result, MPD_POS, MPD_INF); - } - else if (mpd_iszerocoeff(a)) { - mpd_setspecial(result, MPD_NEG, MPD_INF); - *status |= MPD_Division_by_zero; - } - else { - mpd_qset_ssize(result, mpd_adjexp(a), ctx, status); - } -} - -/* Logical Or */ -void -mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - const mpd_t *big = a, *small = b; - mpd_uint_t x, y, z, xbit, ybit; - int k, mswdigits; - mpd_ssize_t i; - - if (mpd_isspecial(a) || mpd_isspecial(b) || - mpd_isnegative(a) || mpd_isnegative(b) || - a->exp != 0 || b->exp != 0) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (b->digits > a->digits) { - big = b; - small = a; - } - if (!mpd_qresize(result, big->len, status)) { - return; - } - - - /* full words */ - for (i = 0; i < small->len-1; i++) { - x = small->data[i]; - y = big->data[i]; - z = 0; - for (k = 0; k < MPD_RDIGITS; k++) { - xbit = x % 10; - x /= 10; - ybit = y % 10; - y /= 10; - if (xbit > 1 || ybit > 1) { - goto invalid_operation; - } - z += (xbit|ybit) ? mpd_pow10[k] : 0; - } - result->data[i] = z; - } - /* most significant word of small */ - x = small->data[i]; - y = big->data[i]; - z = 0; - mswdigits = mpd_word_digits(x); - for (k = 0; k < mswdigits; k++) { - xbit = x % 10; - x /= 10; - ybit = y % 10; - y /= 10; - if (xbit > 1 || ybit > 1) { - goto invalid_operation; - } - z += (xbit|ybit) ? mpd_pow10[k] : 0; - } - - /* scan for digits > 1 and copy the rest of y */ - for (; k < MPD_RDIGITS; k++) { - ybit = y % 10; - y /= 10; - if (ybit > 1) { - goto invalid_operation; - } - z += ybit*mpd_pow10[k]; - } - result->data[i++] = z; - /* scan for digits > 1 and copy the rest of big */ - for (; i < big->len; i++) { - y = big->data[i]; - for (k = 0; k < MPD_RDIGITS; k++) { - ybit = y % 10; - y /= 10; - if (ybit > 1) { - goto invalid_operation; - } - } - result->data[i] = big->data[i]; - } - - mpd_clear_flags(result); - result->exp = 0; - result->len = _mpd_real_size(result->data, big->len); - mpd_qresize(result, result->len, status); - mpd_setdigits(result); - _mpd_cap(result, ctx); - return; - -invalid_operation: - mpd_seterror(result, MPD_Invalid_operation, status); -} - -/* - * Rotate the coefficient of 'a' by 'b' digits. 'b' must be an integer with - * exponent 0. - */ -void -mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - MPD_NEW_STATIC(tmp,0,0,0,0); - MPD_NEW_STATIC(big,0,0,0,0); - MPD_NEW_STATIC(small,0,0,0,0); - mpd_ssize_t n, lshift, rshift; - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - } - if (b->exp != 0 || mpd_isinfinite(b)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - n = mpd_qget_ssize(b, &workstatus); - if (workstatus&MPD_Invalid_operation) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (n > ctx->prec || n < -ctx->prec) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (mpd_isinfinite(a)) { - mpd_qcopy(result, a, status); - return; - } - - if (n >= 0) { - lshift = n; - rshift = ctx->prec-n; - } - else { - lshift = ctx->prec+n; - rshift = -n; - } - - if (a->digits > ctx->prec) { - if (!mpd_qcopy(&tmp, a, status)) { - mpd_seterror(result, MPD_Malloc_error, status); - goto finish; - } - _mpd_cap(&tmp, ctx); - a = &tmp; - } - - if (!mpd_qshiftl(&big, a, lshift, status)) { - mpd_seterror(result, MPD_Malloc_error, status); - goto finish; - } - _mpd_cap(&big, ctx); - - if (mpd_qshiftr(&small, a, rshift, status) == MPD_UINT_MAX) { - mpd_seterror(result, MPD_Malloc_error, status); - goto finish; - } - _mpd_qadd(result, &big, &small, ctx, status); - - -finish: - mpd_del(&tmp); - mpd_del(&big); - mpd_del(&small); -} - -/* - * b must be an integer with exponent 0 and in the range +-2*(emax + prec). - * XXX: In my opinion +-(2*emax + prec) would be more sensible. - * The result is a with the value of b added to its exponent. - */ -void -mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_uint_t n, maxjump; -#ifndef LEGACY_COMPILER - int64_t exp; -#else - mpd_uint_t x; - int x_sign, n_sign; - mpd_ssize_t exp; -#endif - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - } - if (b->exp != 0 || mpd_isinfinite(b)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - n = mpd_qabs_uint(b, &workstatus); - /* the spec demands this */ - maxjump = 2 * (mpd_uint_t)(ctx->emax + ctx->prec); - - if (n > maxjump || workstatus&MPD_Invalid_operation) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (mpd_isinfinite(a)) { - mpd_qcopy(result, a, status); - return; - } - -#ifndef LEGACY_COMPILER - exp = a->exp + (int64_t)n * mpd_arith_sign(b); - exp = (exp > MPD_EXP_INF) ? MPD_EXP_INF : exp; - exp = (exp < MPD_EXP_CLAMP) ? MPD_EXP_CLAMP : exp; -#else - x = (a->exp < 0) ? -a->exp : a->exp; - x_sign = (a->exp < 0) ? 1 : 0; - n_sign = mpd_isnegative(b) ? 1 : 0; - - if (x_sign == n_sign) { - x = x + n; - if (x < n) x = MPD_UINT_MAX; - } - else { - x_sign = (x >= n) ? x_sign : n_sign; - x = (x >= n) ? x - n : n - x; - } - if (!x_sign && x > MPD_EXP_INF) x = MPD_EXP_INF; - if (x_sign && x > -MPD_EXP_CLAMP) x = -MPD_EXP_CLAMP; - exp = x_sign ? -((mpd_ssize_t)x) : (mpd_ssize_t)x; -#endif - - mpd_qcopy(result, a, status); - result->exp = (mpd_ssize_t)exp; - - mpd_qfinalize(result, ctx, status); -} - -/* - * Shift the coefficient by n digits, positive n is a left shift. In the case - * of a left shift, the result is decapitated to fit the context precision. If - * you don't want that, use mpd_shiftl(). - */ -void -mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx, - uint32_t *status) -{ - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - mpd_qcopy(result, a, status); - return; - } - - if (n >= 0 && n <= ctx->prec) { - mpd_qshiftl(result, a, n, status); - _mpd_cap(result, ctx); - } - else if (n < 0 && n >= -ctx->prec) { - if (!mpd_qcopy(result, a, status)) { - return; - } - _mpd_cap(result, ctx); - mpd_qshiftr_inplace(result, -n); - } - else { - mpd_seterror(result, MPD_Invalid_operation, status); - } -} - -/* - * Same as mpd_shiftn(), but the shift is specified by the decimal b, which - * must be an integer with a zero exponent. Infinities remain infinities. - */ -void -mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, - uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_ssize_t n; - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - } - if (b->exp != 0 || mpd_isinfinite(b)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - n = mpd_qget_ssize(b, &workstatus); - if (workstatus&MPD_Invalid_operation) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (n > ctx->prec || n < -ctx->prec) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (mpd_isinfinite(a)) { - mpd_qcopy(result, a, status); - return; - } - - if (n >= 0) { - mpd_qshiftl(result, a, n, status); - _mpd_cap(result, ctx); - } - else { - if (!mpd_qcopy(result, a, status)) { - return; - } - _mpd_cap(result, ctx); - mpd_qshiftr_inplace(result, -n); - } -} - -/* Logical Xor */ -void -mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - const mpd_t *big = a, *small = b; - mpd_uint_t x, y, z, xbit, ybit; - int k, mswdigits; - mpd_ssize_t i; - - if (mpd_isspecial(a) || mpd_isspecial(b) || - mpd_isnegative(a) || mpd_isnegative(b) || - a->exp != 0 || b->exp != 0) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (b->digits > a->digits) { - big = b; - small = a; - } - if (!mpd_qresize(result, big->len, status)) { - return; - } - - - /* full words */ - for (i = 0; i < small->len-1; i++) { - x = small->data[i]; - y = big->data[i]; - z = 0; - for (k = 0; k < MPD_RDIGITS; k++) { - xbit = x % 10; - x /= 10; - ybit = y % 10; - y /= 10; - if (xbit > 1 || ybit > 1) { - goto invalid_operation; - } - z += (xbit^ybit) ? mpd_pow10[k] : 0; - } - result->data[i] = z; - } - /* most significant word of small */ - x = small->data[i]; - y = big->data[i]; - z = 0; - mswdigits = mpd_word_digits(x); - for (k = 0; k < mswdigits; k++) { - xbit = x % 10; - x /= 10; - ybit = y % 10; - y /= 10; - if (xbit > 1 || ybit > 1) { - goto invalid_operation; - } - z += (xbit^ybit) ? mpd_pow10[k] : 0; - } - - /* scan for digits > 1 and copy the rest of y */ - for (; k < MPD_RDIGITS; k++) { - ybit = y % 10; - y /= 10; - if (ybit > 1) { - goto invalid_operation; - } - z += ybit*mpd_pow10[k]; - } - result->data[i++] = z; - /* scan for digits > 1 and copy the rest of big */ - for (; i < big->len; i++) { - y = big->data[i]; - for (k = 0; k < MPD_RDIGITS; k++) { - ybit = y % 10; - y /= 10; - if (ybit > 1) { - goto invalid_operation; - } - } - result->data[i] = big->data[i]; - } - - mpd_clear_flags(result); - result->exp = 0; - result->len = _mpd_real_size(result->data, big->len); - mpd_qresize(result, result->len, status); - mpd_setdigits(result); - _mpd_cap(result, ctx); - return; - -invalid_operation: - mpd_seterror(result, MPD_Invalid_operation, status); -} - - -/******************************************************************************/ -/* Arithmetic operations */ -/******************************************************************************/ - -/* - * The absolute value of a. If a is negative, the result is the same - * as the result of the minus operation. Otherwise, the result is the - * result of the plus operation. - */ -void -mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - } - - if (mpd_isnegative(a)) { - mpd_qminus(result, a, ctx, status); - } - else { - mpd_qplus(result, a, ctx, status); - } -} - -static inline void -_mpd_ptrswap(const mpd_t **a, const mpd_t **b) -{ - const mpd_t *t = *a; - *a = *b; - *b = t; -} - -/* Add or subtract infinities. */ -static void -_mpd_qaddsub_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b, - uint32_t *status) -{ - if (mpd_isinfinite(a)) { - if (mpd_sign(a) != sign_b && mpd_isinfinite(b)) { - mpd_seterror(result, MPD_Invalid_operation, status); - } - else { - mpd_setspecial(result, mpd_sign(a), MPD_INF); - } - return; - } - assert(mpd_isinfinite(b)); - mpd_setspecial(result, sign_b, MPD_INF); -} - -/* Add or subtract non-special numbers. */ -static void -_mpd_qaddsub(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b, - const mpd_context_t *ctx, uint32_t *status) -{ - const mpd_t *big, *small; - MPD_NEW_STATIC(big_aligned,0,0,0,0); - MPD_NEW_CONST(tiny,0,0,1,1,1,1); - mpd_uint_t carry; - mpd_ssize_t newsize, shift; - mpd_ssize_t exp, i; - int swap = 0; - - - /* compare exponents */ - big = a; small = b; - if (big->exp != small->exp) { - if (small->exp > big->exp) { - _mpd_ptrswap(&big, &small); - swap++; - } - /* align the coefficients */ - if (!mpd_iszerocoeff(big)) { - exp = big->exp - 1; - exp += (big->digits > ctx->prec) ? 0 : big->digits-ctx->prec-1; - if (mpd_adjexp(small) < exp) { - /* - * Avoid huge shifts by substituting a value for small that is - * guaranteed to produce the same results. - * - * adjexp(small) < exp if and only if: - * - * bdigits <= prec AND - * bdigits+shift >= prec+2+sdigits AND - * exp = bexp+bdigits-prec-2 - * - * 1234567000000000 -> bdigits + shift - * ----------XX1234 -> sdigits - * ----------X1 -> tiny-digits - * |- prec -| - * - * OR - * - * bdigits > prec AND - * shift > sdigits AND - * exp = bexp-1 - * - * 1234567892100000 -> bdigits + shift - * ----------XX1234 -> sdigits - * ----------X1 -> tiny-digits - * |- prec -| - * - * If tiny is zero, adding or subtracting is a no-op. - * Otherwise, adding tiny generates a non-zero digit either - * below the rounding digit or the least significant digit - * of big. When subtracting, tiny is in the same position as - * the carry that would be generated by subtracting sdigits. - */ - mpd_copy_flags(&tiny, small); - tiny.exp = exp; - tiny.digits = 1; - tiny.len = 1; - tiny.data[0] = mpd_iszerocoeff(small) ? 0 : 1; - small = &tiny; - } - /* This cannot wrap: the difference is positive and <= maxprec */ - shift = big->exp - small->exp; - if (!mpd_qshiftl(&big_aligned, big, shift, status)) { - mpd_seterror(result, MPD_Malloc_error, status); - goto finish; - } - big = &big_aligned; - } - } - result->exp = small->exp; - - - /* compare length of coefficients */ - if (big->len < small->len) { - _mpd_ptrswap(&big, &small); - swap++; - } - - newsize = big->len; - if (!mpd_qresize(result, newsize, status)) { - goto finish; - } - - if (mpd_sign(a) == sign_b) { - - carry = _mpd_baseadd(result->data, big->data, small->data, - big->len, small->len); - - if (carry) { - newsize = big->len + 1; - if (!mpd_qresize(result, newsize, status)) { - goto finish; - } - result->data[newsize-1] = carry; - } - - result->len = newsize; - mpd_set_flags(result, sign_b); - } - else { - if (big->len == small->len) { - for (i=big->len-1; i >= 0; --i) { - if (big->data[i] != small->data[i]) { - if (big->data[i] < small->data[i]) { - _mpd_ptrswap(&big, &small); - swap++; - } - break; - } - } - } - - _mpd_basesub(result->data, big->data, small->data, - big->len, small->len); - newsize = _mpd_real_size(result->data, big->len); - /* resize to smaller cannot fail */ - (void)mpd_qresize(result, newsize, status); - - result->len = newsize; - sign_b = (swap & 1) ? sign_b : mpd_sign(a); - mpd_set_flags(result, sign_b); - - if (mpd_iszerocoeff(result)) { - mpd_set_positive(result); - if (ctx->round == MPD_ROUND_FLOOR) { - mpd_set_negative(result); - } - } - } - - mpd_setdigits(result); - -finish: - mpd_del(&big_aligned); -} - -/* Add a and b. No specials, no finalizing. */ -static void -_mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - _mpd_qaddsub(result, a, b, mpd_sign(b), ctx, status); -} - -/* Subtract b from a. No specials, no finalizing. */ -static void -_mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status); -} - -/* Add a and b. */ -void -mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - _mpd_qaddsub_inf(result, a, b, mpd_sign(b), status); - return; - } - - _mpd_qaddsub(result, a, b, mpd_sign(b), ctx, status); - mpd_qfinalize(result, ctx, status); -} - -/* Add a and b. Set NaN/Invalid_operation if the result is inexact. */ -static void -_mpd_qadd_exact(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - - mpd_qadd(result, a, b, ctx, &workstatus); - *status |= workstatus; - if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { - mpd_seterror(result, MPD_Invalid_operation, status); - } -} - -/* Subtract b from a. */ -void -mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - _mpd_qaddsub_inf(result, a, b, !mpd_sign(b), status); - return; - } - - _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status); - mpd_qfinalize(result, ctx, status); -} - -/* Subtract b from a. Set NaN/Invalid_operation if the result is inexact. */ -static void -_mpd_qsub_exact(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - - mpd_qsub(result, a, b, ctx, &workstatus); - *status |= workstatus; - if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { - mpd_seterror(result, MPD_Invalid_operation, status); - } -} - -/* Add decimal and mpd_ssize_t. */ -void -mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qsset_ssize(&bb, b, &maxcontext, status); - mpd_qadd(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Add decimal and mpd_uint_t. */ -void -mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qsset_uint(&bb, b, &maxcontext, status); - mpd_qadd(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Subtract mpd_ssize_t from decimal. */ -void -mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qsset_ssize(&bb, b, &maxcontext, status); - mpd_qsub(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Subtract mpd_uint_t from decimal. */ -void -mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qsset_uint(&bb, b, &maxcontext, status); - mpd_qsub(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Add decimal and int32_t. */ -void -mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qadd_ssize(result, a, b, ctx, status); -} - -/* Add decimal and uint32_t. */ -void -mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qadd_uint(result, a, b, ctx, status); -} - -#ifdef CONFIG_64 -/* Add decimal and int64_t. */ -void -mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qadd_ssize(result, a, b, ctx, status); -} - -/* Add decimal and uint64_t. */ -void -mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qadd_uint(result, a, b, ctx, status); -} -#elif !defined(LEGACY_COMPILER) -/* Add decimal and int64_t. */ -void -mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qset_i64(&bb, b, &maxcontext, status); - mpd_qadd(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Add decimal and uint64_t. */ -void -mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qset_u64(&bb, b, &maxcontext, status); - mpd_qadd(result, a, &bb, ctx, status); - mpd_del(&bb); -} -#endif - -/* Subtract int32_t from decimal. */ -void -mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qsub_ssize(result, a, b, ctx, status); -} - -/* Subtract uint32_t from decimal. */ -void -mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qsub_uint(result, a, b, ctx, status); -} - -#ifdef CONFIG_64 -/* Subtract int64_t from decimal. */ -void -mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qsub_ssize(result, a, b, ctx, status); -} - -/* Subtract uint64_t from decimal. */ -void -mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qsub_uint(result, a, b, ctx, status); -} -#elif !defined(LEGACY_COMPILER) -/* Subtract int64_t from decimal. */ -void -mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qset_i64(&bb, b, &maxcontext, status); - mpd_qsub(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Subtract uint64_t from decimal. */ -void -mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qset_u64(&bb, b, &maxcontext, status); - mpd_qsub(result, a, &bb, ctx, status); - mpd_del(&bb); -} -#endif - - -/* Divide infinities. */ -static void -_mpd_qdiv_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - if (mpd_isinfinite(a)) { - if (mpd_isinfinite(b)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF); - return; - } - assert(mpd_isinfinite(b)); - _settriple(result, mpd_sign(a)^mpd_sign(b), 0, mpd_etiny(ctx)); - *status |= MPD_Clamped; -} - -enum {NO_IDEAL_EXP, SET_IDEAL_EXP}; -/* Divide a by b. */ -static void -_mpd_qdiv(int action, mpd_t *q, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - MPD_NEW_STATIC(aligned,0,0,0,0); - mpd_uint_t ld; - mpd_ssize_t shift, exp, tz; - mpd_ssize_t newsize; - mpd_ssize_t ideal_exp; - mpd_uint_t rem; - uint8_t sign_a = mpd_sign(a); - uint8_t sign_b = mpd_sign(b); - - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(q, a, b, ctx, status)) { - return; - } - _mpd_qdiv_inf(q, a, b, ctx, status); - return; - } - if (mpd_iszerocoeff(b)) { - if (mpd_iszerocoeff(a)) { - mpd_seterror(q, MPD_Division_undefined, status); - } - else { - mpd_setspecial(q, sign_a^sign_b, MPD_INF); - *status |= MPD_Division_by_zero; - } - return; - } - if (mpd_iszerocoeff(a)) { - exp = a->exp - b->exp; - _settriple(q, sign_a^sign_b, 0, exp); - mpd_qfinalize(q, ctx, status); - return; - } - - shift = (b->digits - a->digits) + ctx->prec + 1; - ideal_exp = a->exp - b->exp; - exp = ideal_exp - shift; - if (shift > 0) { - if (!mpd_qshiftl(&aligned, a, shift, status)) { - mpd_seterror(q, MPD_Malloc_error, status); - goto finish; - } - a = &aligned; - } - else if (shift < 0) { - shift = -shift; - if (!mpd_qshiftl(&aligned, b, shift, status)) { - mpd_seterror(q, MPD_Malloc_error, status); - goto finish; - } - b = &aligned; - } - - - newsize = a->len - b->len + 1; - if ((q != b && q != a) || (q == b && newsize > b->len)) { - if (!mpd_qresize(q, newsize, status)) { - mpd_seterror(q, MPD_Malloc_error, status); - goto finish; - } - } - - - if (b->len == 1) { - rem = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]); - } - else if (b->len <= MPD_NEWTONDIV_CUTOFF) { - int ret = _mpd_basedivmod(q->data, NULL, a->data, b->data, - a->len, b->len); - if (ret < 0) { - mpd_seterror(q, MPD_Malloc_error, status); - goto finish; - } - rem = ret; - } - else { - MPD_NEW_STATIC(r,0,0,0,0); - _mpd_base_ndivmod(q, &r, a, b, status); - if (mpd_isspecial(q) || mpd_isspecial(&r)) { - mpd_setspecial(q, MPD_POS, MPD_NAN); - mpd_del(&r); - goto finish; - } - rem = !mpd_iszerocoeff(&r); - mpd_del(&r); - newsize = q->len; - } - - newsize = _mpd_real_size(q->data, newsize); - /* resize to smaller cannot fail */ - mpd_qresize(q, newsize, status); - mpd_set_flags(q, sign_a^sign_b); - q->len = newsize; - mpd_setdigits(q); - - shift = ideal_exp - exp; - if (rem) { - ld = mpd_lsd(q->data[0]); - if (ld == 0 || ld == 5) { - q->data[0] += 1; - } - } - else if (action == SET_IDEAL_EXP && shift > 0) { - tz = mpd_trail_zeros(q); - shift = (tz > shift) ? shift : tz; - mpd_qshiftr_inplace(q, shift); - exp += shift; - } - - q->exp = exp; - - -finish: - mpd_del(&aligned); - mpd_qfinalize(q, ctx, status); -} - -/* Divide a by b. */ -void -mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - MPD_NEW_STATIC(aa,0,0,0,0); - MPD_NEW_STATIC(bb,0,0,0,0); - uint32_t xstatus = 0; - - if (q == a) { - if (!mpd_qcopy(&aa, a, status)) { - mpd_seterror(q, MPD_Malloc_error, status); - goto out; - } - a = &aa; - } - - if (q == b) { - if (!mpd_qcopy(&bb, b, status)) { - mpd_seterror(q, MPD_Malloc_error, status); - goto out; - } - b = &bb; - } - - _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, &xstatus); - - if (xstatus & (MPD_Malloc_error|MPD_Division_impossible)) { - /* Inexact quotients (the usual case) fill the entire context precision, - * which can lead to the above errors for very high precisions. Retry - * the operation with a lower precision in case the result is exact. - * - * We need an upper bound for the number of digits of a_coeff / b_coeff - * when the result is exact. If a_coeff' * 1 / b_coeff' is in lowest - * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable - * bound. - * - * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5. - * The largest amount of digits is generated if b_coeff' is a power of 2 or - * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff'). - * - * We arrive at a total upper bound: - * - * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <= - * log10(a_coeff) + log2(b_coeff) = - * log10(a_coeff) + log10(b_coeff) / log10(2) <= - * a->digits + b->digits * 4; - */ - mpd_context_t workctx = *ctx; - uint32_t ystatus = 0; - - workctx.prec = a->digits + b->digits * 4; - if (workctx.prec >= ctx->prec) { - *status |= (xstatus&MPD_Errors); - goto out; /* No point in retrying, keep the original error. */ - } - - _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &ystatus); - if (ystatus != 0) { - ystatus = *status | ((ystatus|xstatus)&MPD_Errors); - mpd_seterror(q, ystatus, status); - } - } - else { - *status |= xstatus; - } - - -out: - mpd_del(&aa); - mpd_del(&bb); -} - -/* Internal function. */ -static void -_mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - MPD_NEW_STATIC(aligned,0,0,0,0); - mpd_ssize_t qsize, rsize; - mpd_ssize_t ideal_exp, expdiff, shift; - uint8_t sign_a = mpd_sign(a); - uint8_t sign_ab = mpd_sign(a)^mpd_sign(b); - - - ideal_exp = (a->exp > b->exp) ? b->exp : a->exp; - if (mpd_iszerocoeff(a)) { - if (!mpd_qcopy(r, a, status)) { - goto nanresult; /* GCOV_NOT_REACHED */ - } - r->exp = ideal_exp; - _settriple(q, sign_ab, 0, 0); - return; - } - - expdiff = mpd_adjexp(a) - mpd_adjexp(b); - if (expdiff < 0) { - if (a->exp > b->exp) { - /* positive and less than b->digits - a->digits */ - shift = a->exp - b->exp; - if (!mpd_qshiftl(r, a, shift, status)) { - goto nanresult; - } - r->exp = ideal_exp; - } - else { - if (!mpd_qcopy(r, a, status)) { - goto nanresult; - } - } - _settriple(q, sign_ab, 0, 0); - return; - } - if (expdiff > ctx->prec) { - *status |= MPD_Division_impossible; - goto nanresult; - } - - - /* - * At this point we have: - * (1) 0 <= a->exp + a->digits - b->exp - b->digits <= prec - * (2) a->exp - b->exp >= b->digits - a->digits - * (3) a->exp - b->exp <= prec + b->digits - a->digits - */ - if (a->exp != b->exp) { - shift = a->exp - b->exp; - if (shift > 0) { - /* by (3), after the shift a->digits <= prec + b->digits */ - if (!mpd_qshiftl(&aligned, a, shift, status)) { - goto nanresult; - } - a = &aligned; - } - else { - shift = -shift; - /* by (2), after the shift b->digits <= a->digits */ - if (!mpd_qshiftl(&aligned, b, shift, status)) { - goto nanresult; - } - b = &aligned; - } - } - - - qsize = a->len - b->len + 1; - if (!(q == a && qsize < a->len) && !(q == b && qsize < b->len)) { - if (!mpd_qresize(q, qsize, status)) { - goto nanresult; - } - } - - rsize = b->len; - if (!(r == a && rsize < a->len)) { - if (!mpd_qresize(r, rsize, status)) { - goto nanresult; - } - } - - if (b->len == 1) { - assert(b->data[0] != 0); /* annotation for scan-build */ - if (a->len == 1) { - _mpd_div_word(&q->data[0], &r->data[0], a->data[0], b->data[0]); - } - else { - r->data[0] = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]); - } - } - else if (b->len <= MPD_NEWTONDIV_CUTOFF) { - int ret; - ret = _mpd_basedivmod(q->data, r->data, a->data, b->data, - a->len, b->len); - if (ret == -1) { - *status |= MPD_Malloc_error; - goto nanresult; - } - } - else { - _mpd_base_ndivmod(q, r, a, b, status); - if (mpd_isspecial(q) || mpd_isspecial(r)) { - goto nanresult; - } - qsize = q->len; - rsize = r->len; - } - - qsize = _mpd_real_size(q->data, qsize); - /* resize to smaller cannot fail */ - mpd_qresize(q, qsize, status); - q->len = qsize; - mpd_setdigits(q); - mpd_set_flags(q, sign_ab); - q->exp = 0; - if (q->digits > ctx->prec) { - *status |= MPD_Division_impossible; - goto nanresult; - } - - rsize = _mpd_real_size(r->data, rsize); - /* resize to smaller cannot fail */ - mpd_qresize(r, rsize, status); - r->len = rsize; - mpd_setdigits(r); - mpd_set_flags(r, sign_a); - r->exp = ideal_exp; - -out: - mpd_del(&aligned); - return; - -nanresult: - mpd_setspecial(q, MPD_POS, MPD_NAN); - mpd_setspecial(r, MPD_POS, MPD_NAN); - goto out; -} - -/* Integer division with remainder. */ -void -mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - uint8_t sign = mpd_sign(a)^mpd_sign(b); - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(q, a, b, ctx, status)) { - mpd_qcopy(r, q, status); - return; - } - if (mpd_isinfinite(a)) { - if (mpd_isinfinite(b)) { - mpd_setspecial(q, MPD_POS, MPD_NAN); - } - else { - mpd_setspecial(q, sign, MPD_INF); - } - mpd_setspecial(r, MPD_POS, MPD_NAN); - *status |= MPD_Invalid_operation; - return; - } - if (mpd_isinfinite(b)) { - if (!mpd_qcopy(r, a, status)) { - mpd_seterror(q, MPD_Malloc_error, status); - return; - } - mpd_qfinalize(r, ctx, status); - _settriple(q, sign, 0, 0); - return; - } - /* debug */ - abort(); /* GCOV_NOT_REACHED */ - } - if (mpd_iszerocoeff(b)) { - if (mpd_iszerocoeff(a)) { - mpd_setspecial(q, MPD_POS, MPD_NAN); - mpd_setspecial(r, MPD_POS, MPD_NAN); - *status |= MPD_Division_undefined; - } - else { - mpd_setspecial(q, sign, MPD_INF); - mpd_setspecial(r, MPD_POS, MPD_NAN); - *status |= (MPD_Division_by_zero|MPD_Invalid_operation); - } - return; - } - - _mpd_qdivmod(q, r, a, b, ctx, status); - mpd_qfinalize(q, ctx, status); - mpd_qfinalize(r, ctx, status); -} - -void -mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - MPD_NEW_STATIC(r,0,0,0,0); - uint8_t sign = mpd_sign(a)^mpd_sign(b); - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(q, a, b, ctx, status)) { - return; - } - if (mpd_isinfinite(a) && mpd_isinfinite(b)) { - mpd_seterror(q, MPD_Invalid_operation, status); - return; - } - if (mpd_isinfinite(a)) { - mpd_setspecial(q, sign, MPD_INF); - return; - } - if (mpd_isinfinite(b)) { - _settriple(q, sign, 0, 0); - return; - } - /* debug */ - abort(); /* GCOV_NOT_REACHED */ - } - if (mpd_iszerocoeff(b)) { - if (mpd_iszerocoeff(a)) { - mpd_seterror(q, MPD_Division_undefined, status); - } - else { - mpd_setspecial(q, sign, MPD_INF); - *status |= MPD_Division_by_zero; - } - return; - } - - - _mpd_qdivmod(q, &r, a, b, ctx, status); - mpd_del(&r); - mpd_qfinalize(q, ctx, status); -} - -/* Divide decimal by mpd_ssize_t. */ -void -mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qsset_ssize(&bb, b, &maxcontext, status); - mpd_qdiv(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Divide decimal by mpd_uint_t. */ -void -mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qsset_uint(&bb, b, &maxcontext, status); - mpd_qdiv(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Divide decimal by int32_t. */ -void -mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qdiv_ssize(result, a, b, ctx, status); -} - -/* Divide decimal by uint32_t. */ -void -mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qdiv_uint(result, a, b, ctx, status); -} - -#ifdef CONFIG_64 -/* Divide decimal by int64_t. */ -void -mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qdiv_ssize(result, a, b, ctx, status); -} - -/* Divide decimal by uint64_t. */ -void -mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qdiv_uint(result, a, b, ctx, status); -} -#elif !defined(LEGACY_COMPILER) -/* Divide decimal by int64_t. */ -void -mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qset_i64(&bb, b, &maxcontext, status); - mpd_qdiv(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Divide decimal by uint64_t. */ -void -mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qset_u64(&bb, b, &maxcontext, status); - mpd_qdiv(result, a, &bb, ctx, status); - mpd_del(&bb); -} -#endif - -/* Pad the result with trailing zeros if it has fewer digits than prec. */ -static void -_mpd_zeropad(mpd_t *result, const mpd_context_t *ctx, uint32_t *status) -{ - if (!mpd_isspecial(result) && !mpd_iszero(result) && - result->digits < ctx->prec) { - mpd_ssize_t shift = ctx->prec - result->digits; - mpd_qshiftl(result, result, shift, status); - result->exp -= shift; - } -} - -/* Check if the result is guaranteed to be one. */ -static int -_mpd_qexp_check_one(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - MPD_NEW_CONST(lim,0,-(ctx->prec+1),1,1,1,9); - MPD_NEW_SHARED(aa, a); - - mpd_set_positive(&aa); - - /* abs(a) <= 9 * 10**(-prec-1) */ - if (_mpd_cmp(&aa, &lim) <= 0) { - _settriple(result, 0, 1, 0); - *status |= MPD_Rounded|MPD_Inexact; - return 1; - } - - return 0; -} - -/* - * Get the number of iterations for the Horner scheme in _mpd_qexp(). - */ -static inline mpd_ssize_t -_mpd_get_exp_iterations(const mpd_t *r, mpd_ssize_t p) -{ - mpd_ssize_t log10pbyr; /* lower bound for log10(p / abs(r)) */ - mpd_ssize_t n; - - assert(p >= 10); - assert(!mpd_iszero(r)); - assert(-p < mpd_adjexp(r) && mpd_adjexp(r) <= -1); - -#ifdef CONFIG_64 - if (p > (mpd_ssize_t)(1ULL<<52)) { - return MPD_SSIZE_MAX; - } -#endif - - /* - * Lower bound for log10(p / abs(r)): adjexp(p) - (adjexp(r) + 1) - * At this point (for CONFIG_64, CONFIG_32 is not problematic): - * 1) 10 <= p <= 2**52 - * 2) -p < adjexp(r) <= -1 - * 3) 1 <= log10pbyr <= 2**52 + 14 - */ - log10pbyr = (mpd_word_digits(p)-1) - (mpd_adjexp(r)+1); - - /* - * The numerator in the paper is 1.435 * p - 1.182, calculated - * exactly. We compensate for rounding errors by using 1.43503. - * ACL2 proofs: - * 1) exp-iter-approx-lower-bound: The term below evaluated - * in 53-bit floating point arithmetic is greater than or - * equal to the exact term used in the paper. - * 2) exp-iter-approx-upper-bound: The term below is less than - * or equal to 3/2 * p <= 3/2 * 2**52. - */ - n = (mpd_ssize_t)ceil((1.43503*(double)p - 1.182) / (double)log10pbyr); - return n >= 3 ? n : 3; -} - -/* - * Internal function, specials have been dealt with. Apart from Overflow - * and Underflow, two cases must be considered for the error of the result: - * - * 1) abs(a) <= 9 * 10**(-prec-1) ==> result == 1 - * - * Absolute error: abs(1 - e**x) < 10**(-prec) - * ------------------------------------------- - * - * 2) abs(a) > 9 * 10**(-prec-1) - * - * Relative error: abs(result - e**x) < 0.5 * 10**(-prec) * e**x - * ------------------------------------------------------------- - * - * The algorithm is from Hull&Abrham, Variable Precision Exponential Function, - * ACM Transactions on Mathematical Software, Vol. 12, No. 2, June 1986. - * - * Main differences: - * - * - The number of iterations for the Horner scheme is calculated using - * 53-bit floating point arithmetic. - * - * - In the error analysis for ER (relative error accumulated in the - * evaluation of the truncated series) the reduced operand r may - * have any number of digits. - * ACL2 proof: exponent-relative-error - * - * - The analysis for early abortion has been adapted for the mpd_t - * ranges. - */ -static void -_mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx; - MPD_NEW_STATIC(tmp,0,0,0,0); - MPD_NEW_STATIC(sum,0,0,0,0); - MPD_NEW_CONST(word,0,0,1,1,1,1); - mpd_ssize_t j, n, t; - - assert(!mpd_isspecial(a)); - - if (mpd_iszerocoeff(a)) { - _settriple(result, MPD_POS, 1, 0); - return; - } - - /* - * We are calculating e^x = e^(r*10^t) = (e^r)^(10^t), where abs(r) < 1 and t >= 0. - * - * If t > 0, we have: - * - * (1) 0.1 <= r < 1, so e^0.1 <= e^r. If t > MAX_T, overflow occurs: - * - * MAX-EMAX+1 < log10(e^(0.1*10*t)) <= log10(e^(r*10^t)) < adjexp(e^(r*10^t))+1 - * - * (2) -1 < r <= -0.1, so e^r <= e^-0.1. If t > MAX_T, underflow occurs: - * - * adjexp(e^(r*10^t)) <= log10(e^(r*10^t)) <= log10(e^(-0.1*10^t)) < MIN-ETINY - */ -#if defined(CONFIG_64) - #define MPD_EXP_MAX_T 19 -#elif defined(CONFIG_32) - #define MPD_EXP_MAX_T 10 -#endif - t = a->digits + a->exp; - t = (t > 0) ? t : 0; - if (t > MPD_EXP_MAX_T) { - if (mpd_ispositive(a)) { - mpd_setspecial(result, MPD_POS, MPD_INF); - *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; - } - else { - _settriple(result, MPD_POS, 0, mpd_etiny(ctx)); - *status |= (MPD_Inexact|MPD_Rounded|MPD_Subnormal| - MPD_Underflow|MPD_Clamped); - } - return; - } - - /* abs(a) <= 9 * 10**(-prec-1) */ - if (_mpd_qexp_check_one(result, a, ctx, status)) { - return; - } - - mpd_maxcontext(&workctx); - workctx.prec = ctx->prec + t + 2; - workctx.prec = (workctx.prec < 10) ? 10 : workctx.prec; - workctx.round = MPD_ROUND_HALF_EVEN; - - if (!mpd_qcopy(result, a, status)) { - return; - } - result->exp -= t; - - /* - * At this point: - * 1) 9 * 10**(-prec-1) < abs(a) - * 2) 9 * 10**(-prec-t-1) < abs(r) - * 3) log10(9) - prec - t - 1 < log10(abs(r)) < adjexp(abs(r)) + 1 - * 4) - prec - t - 2 < adjexp(abs(r)) <= -1 - */ - n = _mpd_get_exp_iterations(result, workctx.prec); - if (n == MPD_SSIZE_MAX) { - mpd_seterror(result, MPD_Invalid_operation, status); /* GCOV_UNLIKELY */ - return; /* GCOV_UNLIKELY */ - } - - _settriple(&sum, MPD_POS, 1, 0); - - for (j = n-1; j >= 1; j--) { - word.data[0] = j; - mpd_setdigits(&word); - mpd_qdiv(&tmp, result, &word, &workctx, &workctx.status); - mpd_qfma(&sum, &sum, &tmp, &one, &workctx, &workctx.status); - } - -#ifdef CONFIG_64 - _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status); -#else - if (t <= MPD_MAX_POW10) { - _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status); - } - else { - t -= MPD_MAX_POW10; - _mpd_qpow_uint(&tmp, &sum, mpd_pow10[MPD_MAX_POW10], MPD_POS, - &workctx, status); - _mpd_qpow_uint(result, &tmp, mpd_pow10[t], MPD_POS, &workctx, status); - } -#endif - - mpd_del(&tmp); - mpd_del(&sum); - *status |= (workctx.status&MPD_Errors); - *status |= (MPD_Inexact|MPD_Rounded); -} - -/* exp(a) */ -void -mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx; - - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - if (mpd_isnegative(a)) { - _settriple(result, MPD_POS, 0, 0); - } - else { - mpd_setspecial(result, MPD_POS, MPD_INF); - } - return; - } - if (mpd_iszerocoeff(a)) { - _settriple(result, MPD_POS, 1, 0); - return; - } - - workctx = *ctx; - workctx.round = MPD_ROUND_HALF_EVEN; - - if (ctx->allcr) { - MPD_NEW_STATIC(t1, 0,0,0,0); - MPD_NEW_STATIC(t2, 0,0,0,0); - MPD_NEW_STATIC(ulp, 0,0,0,0); - MPD_NEW_STATIC(aa, 0,0,0,0); - mpd_ssize_t prec; - mpd_ssize_t ulpexp; - uint32_t workstatus; - - if (result == a) { - if (!mpd_qcopy(&aa, a, status)) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - a = &aa; - } - - workctx.clamp = 0; - prec = ctx->prec + 3; - while (1) { - workctx.prec = prec; - workstatus = 0; - - _mpd_qexp(result, a, &workctx, &workstatus); - *status |= workstatus; - - ulpexp = result->exp + result->digits - workctx.prec; - if (workstatus & MPD_Underflow) { - /* The effective work precision is result->digits. */ - ulpexp = result->exp; - } - _ssettriple(&ulp, MPD_POS, 1, ulpexp); - - /* - * At this point [1]: - * 1) abs(result - e**x) < 0.5 * 10**(-prec) * e**x - * 2) result - ulp < e**x < result + ulp - * 3) result - ulp < result < result + ulp - * - * If round(result-ulp)==round(result+ulp), then - * round(result)==round(e**x). Therefore the result - * is correctly rounded. - * - * [1] If abs(a) <= 9 * 10**(-prec-1), use the absolute - * error for a similar argument. - */ - workctx.prec = ctx->prec; - mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); - mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); - if (mpd_isspecial(result) || mpd_iszerocoeff(result) || - mpd_qcmp(&t1, &t2, status) == 0) { - workctx.clamp = ctx->clamp; - _mpd_zeropad(result, &workctx, status); - mpd_check_underflow(result, &workctx, status); - mpd_qfinalize(result, &workctx, status); - break; - } - prec += MPD_RDIGITS; - } - mpd_del(&t1); - mpd_del(&t2); - mpd_del(&ulp); - mpd_del(&aa); - } - else { - _mpd_qexp(result, a, &workctx, status); - _mpd_zeropad(result, &workctx, status); - mpd_check_underflow(result, &workctx, status); - mpd_qfinalize(result, &workctx, status); - } -} - -/* Fused multiply-add: (a * b) + c, with a single final rounding. */ -void -mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_t *cc = NULL; - - if (result == c) { - if ((cc = mpd_qncopy(c)) == NULL) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - c = cc; - } - - _mpd_qmul(result, a, b, ctx, &workstatus); - if (!(workstatus&MPD_Invalid_operation)) { - mpd_qadd(result, result, c, ctx, &workstatus); - } - - if (cc) mpd_del(cc); - *status |= workstatus; -} - -/* - * Schedule the optimal precision increase for the Newton iteration. - * v := input operand - * z_0 := initial approximation - * initprec := natural number such that abs(log(v) - z_0) < 10**-initprec - * maxprec := target precision - * - * For convenience the output klist contains the elements in reverse order: - * klist := [k_n-1, ..., k_0], where - * 1) k_0 <= initprec and - * 2) abs(log(v) - result) < 10**(-2*k_n-1 + 1) <= 10**-maxprec. - */ -static inline int -ln_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], mpd_ssize_t maxprec, - mpd_ssize_t initprec) -{ - mpd_ssize_t k; - int i; - - assert(maxprec >= 2 && initprec >= 2); - if (maxprec <= initprec) return -1; - - i = 0; k = maxprec; - do { - k = (k+2) / 2; - klist[i++] = k; - } while (k > initprec); - - return i-1; -} - -/* The constants have been verified with both decimal.py and mpfr. */ -#ifdef CONFIG_64 -#if MPD_RDIGITS != 19 - #error "mpdecimal.c: MPD_RDIGITS must be 19." -#endif -static const mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = { - 6983716328982174407ULL, 9089704281976336583ULL, 1515961135648465461ULL, - 4416816335727555703ULL, 2900988039194170265ULL, 2307925037472986509ULL, - 107598438319191292ULL, 3466624107184669231ULL, 4450099781311469159ULL, - 9807828059751193854ULL, 7713456862091670584ULL, 1492198849978748873ULL, - 6528728696511086257ULL, 2385392051446341972ULL, 8692180205189339507ULL, - 6518769751037497088ULL, 2375253577097505395ULL, 9095610299291824318ULL, - 982748238504564801ULL, 5438635917781170543ULL, 7547331541421808427ULL, - 752371033310119785ULL, 3171643095059950878ULL, 9785265383207606726ULL, - 2932258279850258550ULL, 5497347726624257094ULL, 2976979522110718264ULL, - 9221477656763693866ULL, 1979650047149510504ULL, 6674183485704422507ULL, - 9702766860595249671ULL, 9278096762712757753ULL, 9314848524948644871ULL, - 6826928280848118428ULL, 754403708474699401ULL, 230105703089634572ULL, - 1929203337658714166ULL, 7589402567763113569ULL, 4208241314695689016ULL, - 2922455440575892572ULL, 9356734206705811364ULL, 2684916746550586856ULL, - 644507064800027750ULL, 9476834636167921018ULL, 5659121373450747856ULL, - 2835522011480466371ULL, 6470806855677432162ULL, 7141748003688084012ULL, - 9619404400222105101ULL, 5504893431493939147ULL, 6674744042432743651ULL, - 2287698219886746543ULL, 7773262884616336622ULL, 1985283935053089653ULL, - 4680843799894826233ULL, 8168948290720832555ULL, 8067566662873690987ULL, - 6248633409525465082ULL, 9829834196778404228ULL, 3524802359972050895ULL, - 3327900967572609677ULL, 110148862877297603ULL, 179914546843642076ULL, - 2302585092994045684ULL -}; -#else -#if MPD_RDIGITS != 9 - #error "mpdecimal.c: MPD_RDIGITS must be 9." -#endif -static const mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = { - 401682692UL, 708474699UL, 720754403UL, 30896345UL, 602301057UL, 765871416UL, - 192920333UL, 763113569UL, 589402567UL, 956890167UL, 82413146UL, 589257242UL, - 245544057UL, 811364292UL, 734206705UL, 868569356UL, 167465505UL, 775026849UL, - 706480002UL, 18064450UL, 636167921UL, 569476834UL, 734507478UL, 156591213UL, - 148046637UL, 283552201UL, 677432162UL, 470806855UL, 880840126UL, 417480036UL, - 210510171UL, 940440022UL, 939147961UL, 893431493UL, 436515504UL, 440424327UL, - 654366747UL, 821988674UL, 622228769UL, 884616336UL, 537773262UL, 350530896UL, - 319852839UL, 989482623UL, 468084379UL, 720832555UL, 168948290UL, 736909878UL, - 675666628UL, 546508280UL, 863340952UL, 404228624UL, 834196778UL, 508959829UL, - 23599720UL, 967735248UL, 96757260UL, 603332790UL, 862877297UL, 760110148UL, - 468436420UL, 401799145UL, 299404568UL, 230258509UL -}; -#endif -/* _mpd_ln10 is used directly for precisions smaller than MINALLOC_MAX*RDIGITS. - Otherwise, it serves as the initial approximation for calculating ln(10). */ -static const mpd_t _mpd_ln10 = { - MPD_STATIC|MPD_CONST_DATA, -(MPD_MINALLOC_MAX*MPD_RDIGITS-1), - MPD_MINALLOC_MAX*MPD_RDIGITS, MPD_MINALLOC_MAX, MPD_MINALLOC_MAX, - (mpd_uint_t *)mpd_ln10_data -}; - -/* - * Set 'result' to log(10). - * Ulp error: abs(result - log(10)) < ulp(log(10)) - * Relative error: abs(result - log(10)) < 5 * 10**-prec * log(10) - * - * NOTE: The relative error is not derived from the ulp error, but - * calculated separately using the fact that 23/10 < log(10) < 24/10. - */ -void -mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status) -{ - mpd_context_t varcontext, maxcontext; - MPD_NEW_STATIC(tmp, 0,0,0,0); - MPD_NEW_CONST(static10, 0,0,2,1,1,10); - mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; - mpd_uint_t rnd; - mpd_ssize_t shift; - int i; - - assert(prec >= 1); - - shift = MPD_MINALLOC_MAX*MPD_RDIGITS-prec; - shift = shift < 0 ? 0 : shift; - - rnd = mpd_qshiftr(result, &_mpd_ln10, shift, status); - if (rnd == MPD_UINT_MAX) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - result->exp = -(result->digits-1); - - mpd_maxcontext(&maxcontext); - if (prec < MPD_MINALLOC_MAX*MPD_RDIGITS) { - maxcontext.prec = prec; - _mpd_apply_round_excess(result, rnd, &maxcontext, status); - *status |= (MPD_Inexact|MPD_Rounded); - return; - } - - mpd_maxcontext(&varcontext); - varcontext.round = MPD_ROUND_TRUNC; - - i = ln_schedule_prec(klist, prec+2, -result->exp); - for (; i >= 0; i--) { - varcontext.prec = 2*klist[i]+3; - result->flags ^= MPD_NEG; - _mpd_qexp(&tmp, result, &varcontext, status); - result->flags ^= MPD_NEG; - mpd_qmul(&tmp, &static10, &tmp, &varcontext, status); - mpd_qsub(&tmp, &tmp, &one, &maxcontext, status); - mpd_qadd(result, result, &tmp, &maxcontext, status); - if (mpd_isspecial(result)) { - break; - } - } - - mpd_del(&tmp); - maxcontext.prec = prec; - mpd_qfinalize(result, &maxcontext, status); -} - -/* - * Initial approximations for the ln() iteration. The values have the - * following properties (established with both decimal.py and mpfr): - * - * Index 0 - 400, logarithms of x in [1.00, 5.00]: - * abs(lnapprox[i] * 10**-3 - log((i+100)/100)) < 10**-2 - * abs(lnapprox[i] * 10**-3 - log((i+1+100)/100)) < 10**-2 - * - * Index 401 - 899, logarithms of x in (0.500, 0.999]: - * abs(-lnapprox[i] * 10**-3 - log((i+100)/1000)) < 10**-2 - * abs(-lnapprox[i] * 10**-3 - log((i+1+100)/1000)) < 10**-2 - */ -static const uint16_t lnapprox[900] = { - /* index 0 - 400: log((i+100)/100) * 1000 */ - 0, 10, 20, 30, 39, 49, 58, 68, 77, 86, 95, 104, 113, 122, 131, 140, 148, 157, - 166, 174, 182, 191, 199, 207, 215, 223, 231, 239, 247, 255, 262, 270, 278, - 285, 293, 300, 308, 315, 322, 329, 336, 344, 351, 358, 365, 372, 378, 385, - 392, 399, 406, 412, 419, 425, 432, 438, 445, 451, 457, 464, 470, 476, 482, - 489, 495, 501, 507, 513, 519, 525, 531, 536, 542, 548, 554, 560, 565, 571, - 577, 582, 588, 593, 599, 604, 610, 615, 621, 626, 631, 637, 642, 647, 652, - 658, 663, 668, 673, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, - 732, 737, 742, 747, 751, 756, 761, 766, 770, 775, 779, 784, 788, 793, 798, - 802, 806, 811, 815, 820, 824, 829, 833, 837, 842, 846, 850, 854, 859, 863, - 867, 871, 876, 880, 884, 888, 892, 896, 900, 904, 908, 912, 916, 920, 924, - 928, 932, 936, 940, 944, 948, 952, 956, 959, 963, 967, 971, 975, 978, 982, - 986, 990, 993, 997, 1001, 1004, 1008, 1012, 1015, 1019, 1022, 1026, 1030, - 1033, 1037, 1040, 1044, 1047, 1051, 1054, 1058, 1061, 1065, 1068, 1072, 1075, - 1078, 1082, 1085, 1089, 1092, 1095, 1099, 1102, 1105, 1109, 1112, 1115, 1118, - 1122, 1125, 1128, 1131, 1135, 1138, 1141, 1144, 1147, 1151, 1154, 1157, 1160, - 1163, 1166, 1169, 1172, 1176, 1179, 1182, 1185, 1188, 1191, 1194, 1197, 1200, - 1203, 1206, 1209, 1212, 1215, 1218, 1221, 1224, 1227, 1230, 1233, 1235, 1238, - 1241, 1244, 1247, 1250, 1253, 1256, 1258, 1261, 1264, 1267, 1270, 1273, 1275, - 1278, 1281, 1284, 1286, 1289, 1292, 1295, 1297, 1300, 1303, 1306, 1308, 1311, - 1314, 1316, 1319, 1322, 1324, 1327, 1330, 1332, 1335, 1338, 1340, 1343, 1345, - 1348, 1351, 1353, 1356, 1358, 1361, 1364, 1366, 1369, 1371, 1374, 1376, 1379, - 1381, 1384, 1386, 1389, 1391, 1394, 1396, 1399, 1401, 1404, 1406, 1409, 1411, - 1413, 1416, 1418, 1421, 1423, 1426, 1428, 1430, 1433, 1435, 1437, 1440, 1442, - 1445, 1447, 1449, 1452, 1454, 1456, 1459, 1461, 1463, 1466, 1468, 1470, 1472, - 1475, 1477, 1479, 1482, 1484, 1486, 1488, 1491, 1493, 1495, 1497, 1500, 1502, - 1504, 1506, 1509, 1511, 1513, 1515, 1517, 1520, 1522, 1524, 1526, 1528, 1530, - 1533, 1535, 1537, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1556, 1558, - 1560, 1562, 1564, 1567, 1569, 1571, 1573, 1575, 1577, 1579, 1581, 1583, 1585, - 1587, 1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, 1605, 1607, 1609, - /* index 401 - 899: -log((i+100)/1000) * 1000 */ - 691, 689, 687, 685, 683, 681, 679, 677, 675, 673, 671, 669, 668, 666, 664, - 662, 660, 658, 656, 654, 652, 650, 648, 646, 644, 642, 641, 639, 637, 635, - 633, 631, 629, 627, 626, 624, 622, 620, 618, 616, 614, 612, 611, 609, 607, - 605, 603, 602, 600, 598, 596, 594, 592, 591, 589, 587, 585, 583, 582, 580, - 578, 576, 574, 573, 571, 569, 567, 566, 564, 562, 560, 559, 557, 555, 553, - 552, 550, 548, 546, 545, 543, 541, 540, 538, 536, 534, 533, 531, 529, 528, - 526, 524, 523, 521, 519, 518, 516, 514, 512, 511, 509, 508, 506, 504, 502, - 501, 499, 498, 496, 494, 493, 491, 489, 488, 486, 484, 483, 481, 480, 478, - 476, 475, 473, 472, 470, 468, 467, 465, 464, 462, 460, 459, 457, 456, 454, - 453, 451, 449, 448, 446, 445, 443, 442, 440, 438, 437, 435, 434, 432, 431, - 429, 428, 426, 425, 423, 422, 420, 419, 417, 416, 414, 412, 411, 410, 408, - 406, 405, 404, 402, 400, 399, 398, 396, 394, 393, 392, 390, 389, 387, 386, - 384, 383, 381, 380, 378, 377, 375, 374, 372, 371, 370, 368, 367, 365, 364, - 362, 361, 360, 358, 357, 355, 354, 352, 351, 350, 348, 347, 345, 344, 342, - 341, 340, 338, 337, 336, 334, 333, 331, 330, 328, 327, 326, 324, 323, 322, - 320, 319, 318, 316, 315, 313, 312, 311, 309, 308, 306, 305, 304, 302, 301, - 300, 298, 297, 296, 294, 293, 292, 290, 289, 288, 286, 285, 284, 282, 281, - 280, 278, 277, 276, 274, 273, 272, 270, 269, 268, 267, 265, 264, 263, 261, - 260, 259, 258, 256, 255, 254, 252, 251, 250, 248, 247, 246, 245, 243, 242, - 241, 240, 238, 237, 236, 234, 233, 232, 231, 229, 228, 227, 226, 224, 223, - 222, 221, 219, 218, 217, 216, 214, 213, 212, 211, 210, 208, 207, 206, 205, - 203, 202, 201, 200, 198, 197, 196, 195, 194, 192, 191, 190, 189, 188, 186, - 185, 184, 183, 182, 180, 179, 178, 177, 176, 174, 173, 172, 171, 170, 168, - 167, 166, 165, 164, 162, 161, 160, 159, 158, 157, 156, 154, 153, 152, 151, - 150, 148, 147, 146, 145, 144, 143, 142, 140, 139, 138, 137, 136, 135, 134, - 132, 131, 130, 129, 128, 127, 126, 124, 123, 122, 121, 120, 119, 118, 116, - 115, 114, 113, 112, 111, 110, 109, 108, 106, 105, 104, 103, 102, 101, 100, - 99, 98, 97, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 84, 83, 82, 81, 80, 79, - 78, 77, 76, 75, 74, 73, 72, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, - 58, 57, 56, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, - 38, 37, 36, 35, 34, 33, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, - 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 -}; - -/* - * Internal ln() function that does not check for specials, zero or one. - * Relative error: abs(result - log(a)) < 0.1 * 10**-prec * abs(log(a)) - */ -static void -_mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t varcontext, maxcontext; - mpd_t *z = (mpd_t *) result; - MPD_NEW_STATIC(v,0,0,0,0); - MPD_NEW_STATIC(vtmp,0,0,0,0); - MPD_NEW_STATIC(tmp,0,0,0,0); - mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; - mpd_ssize_t maxprec, shift, t; - mpd_ssize_t a_digits, a_exp; - mpd_uint_t dummy, x; - int i; - - assert(!mpd_isspecial(a) && !mpd_iszerocoeff(a)); - - /* - * We are calculating ln(a) = ln(v * 10^t) = ln(v) + t*ln(10), - * where 0.5 < v <= 5. - */ - if (!mpd_qcopy(&v, a, status)) { - mpd_seterror(result, MPD_Malloc_error, status); - goto finish; - } - - /* Initial approximation: we have at least one non-zero digit */ - _mpd_get_msdigits(&dummy, &x, &v, 3); - if (x < 10) x *= 10; - if (x < 100) x *= 10; - x -= 100; - - /* a may equal z */ - a_digits = a->digits; - a_exp = a->exp; - - mpd_minalloc(z); - mpd_clear_flags(z); - z->data[0] = lnapprox[x]; - z->len = 1; - z->exp = -3; - mpd_setdigits(z); - - if (x <= 400) { - /* Reduce the input operand to 1.00 <= v <= 5.00. Let y = x + 100, - * so 100 <= y <= 500. Since y contains the most significant digits - * of v, y/100 <= v < (y+1)/100 and abs(z - log(v)) < 10**-2. */ - v.exp = -(a_digits - 1); - t = a_exp + a_digits - 1; - } - else { - /* Reduce the input operand to 0.500 < v <= 0.999. Let y = x + 100, - * so 500 < y <= 999. Since y contains the most significant digits - * of v, y/1000 <= v < (y+1)/1000 and abs(z - log(v)) < 10**-2. */ - v.exp = -a_digits; - t = a_exp + a_digits; - mpd_set_negative(z); - } - - mpd_maxcontext(&maxcontext); - mpd_maxcontext(&varcontext); - varcontext.round = MPD_ROUND_TRUNC; - - maxprec = ctx->prec + 2; - if (t == 0 && (x <= 15 || x >= 800)) { - /* 0.900 <= v <= 1.15: Estimate the magnitude of the logarithm. - * If ln(v) will underflow, skip the loop. Otherwise, adjust the - * precision upwards in order to obtain a sufficient number of - * significant digits. - * - * Case v > 1: - * abs((v-1)/10) < abs((v-1)/v) < abs(ln(v)) < abs(v-1) - * Case v < 1: - * abs(v-1) < abs(ln(v)) < abs((v-1)/v) < abs((v-1)*10) - */ - int cmp = _mpd_cmp(&v, &one); - - /* Upper bound (assume v > 1): abs(v-1), unrounded */ - _mpd_qsub(&tmp, &v, &one, &maxcontext, &maxcontext.status); - if (maxcontext.status & MPD_Errors) { - mpd_seterror(result, MPD_Malloc_error, status); - goto finish; - } - - if (cmp < 0) { - /* v < 1: abs((v-1)*10) */ - tmp.exp += 1; - } - if (mpd_adjexp(&tmp) < mpd_etiny(ctx)) { - /* The upper bound is less than etiny: Underflow to zero */ - _settriple(result, (cmp<0), 1, mpd_etiny(ctx)-1); - goto finish; - } - /* Lower bound: abs((v-1)/10) or abs(v-1) */ - tmp.exp -= 1; - if (mpd_adjexp(&tmp) < 0) { - /* Absolute error of the loop: abs(z - log(v)) < 10**-p. If - * p = ctx->prec+2-adjexp(lower), then the relative error of - * the result is (using 10**adjexp(x) <= abs(x)): - * - * abs(z - log(v)) / abs(log(v)) < 10**-p / abs(log(v)) - * <= 10**(-ctx->prec-2) - */ - maxprec = maxprec - mpd_adjexp(&tmp); - } - } - - i = ln_schedule_prec(klist, maxprec, 2); - for (; i >= 0; i--) { - varcontext.prec = 2*klist[i]+3; - z->flags ^= MPD_NEG; - _mpd_qexp(&tmp, z, &varcontext, status); - z->flags ^= MPD_NEG; - - if (v.digits > varcontext.prec) { - shift = v.digits - varcontext.prec; - mpd_qshiftr(&vtmp, &v, shift, status); - vtmp.exp += shift; - mpd_qmul(&tmp, &vtmp, &tmp, &varcontext, status); - } - else { - mpd_qmul(&tmp, &v, &tmp, &varcontext, status); - } - - mpd_qsub(&tmp, &tmp, &one, &maxcontext, status); - mpd_qadd(z, z, &tmp, &maxcontext, status); - if (mpd_isspecial(z)) { - break; - } - } - - /* - * Case t == 0: - * t * log(10) == 0, the result does not change and the analysis - * above applies. If v < 0.900 or v > 1.15, the relative error is - * less than 10**(-ctx.prec-1). - * Case t != 0: - * z := approx(log(v)) - * y := approx(log(10)) - * p := maxprec = ctx->prec + 2 - * Absolute errors: - * 1) abs(z - log(v)) < 10**-p - * 2) abs(y - log(10)) < 10**-p - * The multiplication is exact, so: - * 3) abs(t*y - t*log(10)) < t*10**-p - * The sum is exact, so: - * 4) abs((z + t*y) - (log(v) + t*log(10))) < (abs(t) + 1) * 10**-p - * Bounds for log(v) and log(10): - * 5) -7/10 < log(v) < 17/10 - * 6) 23/10 < log(10) < 24/10 - * Using 4), 5), 6) and t != 0, the relative error is: - * - * 7) relerr < ((abs(t) + 1)*10**-p) / abs(log(v) + t*log(10)) - * < 0.5 * 10**(-p + 1) = 0.5 * 10**(-ctx->prec-1) - */ - mpd_qln10(&v, maxprec+1, status); - mpd_qmul_ssize(&tmp, &v, t, &maxcontext, status); - mpd_qadd(result, &tmp, z, &maxcontext, status); - - -finish: - *status |= (MPD_Inexact|MPD_Rounded); - mpd_del(&v); - mpd_del(&vtmp); - mpd_del(&tmp); -} - -/* ln(a) */ -void -mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx; - mpd_ssize_t adjexp, t; - - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - if (mpd_isnegative(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - mpd_setspecial(result, MPD_POS, MPD_INF); - return; - } - if (mpd_iszerocoeff(a)) { - mpd_setspecial(result, MPD_NEG, MPD_INF); - return; - } - if (mpd_isnegative(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (_mpd_cmp(a, &one) == 0) { - _settriple(result, MPD_POS, 0, 0); - return; - } - /* - * Check if the result will overflow (0 < x, x != 1): - * 1) log10(x) < 0 iff adjexp(x) < 0 - * 2) 0 < x /\ x <= y ==> adjexp(x) <= adjexp(y) - * 3) 0 < x /\ x != 1 ==> 2 * abs(log10(x)) < abs(log(x)) - * 4) adjexp(x) <= log10(x) < adjexp(x) + 1 - * - * Case adjexp(x) >= 0: - * 5) 2 * adjexp(x) < abs(log(x)) - * Case adjexp(x) > 0: - * 6) adjexp(2 * adjexp(x)) <= adjexp(abs(log(x))) - * Case adjexp(x) == 0: - * mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered) - * - * Case adjexp(x) < 0: - * 7) 2 * (-adjexp(x) - 1) < abs(log(x)) - * Case adjexp(x) < -1: - * 8) adjexp(2 * (-adjexp(x) - 1)) <= adjexp(abs(log(x))) - * Case adjexp(x) == -1: - * mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered) - */ - adjexp = mpd_adjexp(a); - t = (adjexp < 0) ? -adjexp-1 : adjexp; - t *= 2; - if (mpd_exp_digits(t)-1 > ctx->emax) { - *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; - mpd_setspecial(result, (adjexp<0), MPD_INF); - return; - } - - workctx = *ctx; - workctx.round = MPD_ROUND_HALF_EVEN; - - if (ctx->allcr) { - MPD_NEW_STATIC(t1, 0,0,0,0); - MPD_NEW_STATIC(t2, 0,0,0,0); - MPD_NEW_STATIC(ulp, 0,0,0,0); - MPD_NEW_STATIC(aa, 0,0,0,0); - mpd_ssize_t prec; - - if (result == a) { - if (!mpd_qcopy(&aa, a, status)) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - a = &aa; - } - - workctx.clamp = 0; - prec = ctx->prec + 3; - while (1) { - workctx.prec = prec; - _mpd_qln(result, a, &workctx, status); - _ssettriple(&ulp, MPD_POS, 1, - result->exp + result->digits-workctx.prec); - - workctx.prec = ctx->prec; - mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); - mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); - if (mpd_isspecial(result) || mpd_iszerocoeff(result) || - mpd_qcmp(&t1, &t2, status) == 0) { - workctx.clamp = ctx->clamp; - mpd_check_underflow(result, &workctx, status); - mpd_qfinalize(result, &workctx, status); - break; - } - prec += MPD_RDIGITS; - } - mpd_del(&t1); - mpd_del(&t2); - mpd_del(&ulp); - mpd_del(&aa); - } - else { - _mpd_qln(result, a, &workctx, status); - mpd_check_underflow(result, &workctx, status); - mpd_qfinalize(result, &workctx, status); - } -} - -/* - * Internal log10() function that does not check for specials, zero or one. - * Case SKIP_FINALIZE: - * Relative error: abs(result - log10(a)) < 0.1 * 10**-prec * abs(log10(a)) - * Case DO_FINALIZE: - * Ulp error: abs(result - log10(a)) < ulp(log10(a)) - */ -enum {SKIP_FINALIZE, DO_FINALIZE}; -static void -_mpd_qlog10(int action, mpd_t *result, const mpd_t *a, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t workctx; - MPD_NEW_STATIC(ln10,0,0,0,0); - - mpd_maxcontext(&workctx); - workctx.prec = ctx->prec + 3; - /* relative error: 0.1 * 10**(-p-3). The specific underflow shortcut - * in _mpd_qln() does not change the final result. */ - _mpd_qln(result, a, &workctx, status); - /* relative error: 5 * 10**(-p-3) */ - mpd_qln10(&ln10, workctx.prec, status); - - if (action == DO_FINALIZE) { - workctx = *ctx; - workctx.round = MPD_ROUND_HALF_EVEN; - } - /* SKIP_FINALIZE: relative error: 5 * 10**(-p-3) */ - _mpd_qdiv(NO_IDEAL_EXP, result, result, &ln10, &workctx, status); - - mpd_del(&ln10); -} - -/* log10(a) */ -void -mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx; - mpd_ssize_t adjexp, t; - - workctx = *ctx; - workctx.round = MPD_ROUND_HALF_EVEN; - - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - if (mpd_isnegative(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - mpd_setspecial(result, MPD_POS, MPD_INF); - return; - } - if (mpd_iszerocoeff(a)) { - mpd_setspecial(result, MPD_NEG, MPD_INF); - return; - } - if (mpd_isnegative(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (mpd_coeff_ispow10(a)) { - uint8_t sign = 0; - adjexp = mpd_adjexp(a); - if (adjexp < 0) { - sign = 1; - adjexp = -adjexp; - } - _settriple(result, sign, adjexp, 0); - mpd_qfinalize(result, &workctx, status); - return; - } - /* - * Check if the result will overflow (0 < x, x != 1): - * 1) log10(x) < 0 iff adjexp(x) < 0 - * 2) 0 < x /\ x <= y ==> adjexp(x) <= adjexp(y) - * 3) adjexp(x) <= log10(x) < adjexp(x) + 1 - * - * Case adjexp(x) >= 0: - * 4) adjexp(x) <= abs(log10(x)) - * Case adjexp(x) > 0: - * 5) adjexp(adjexp(x)) <= adjexp(abs(log10(x))) - * Case adjexp(x) == 0: - * mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered) - * - * Case adjexp(x) < 0: - * 6) -adjexp(x) - 1 < abs(log10(x)) - * Case adjexp(x) < -1: - * 7) adjexp(-adjexp(x) - 1) <= adjexp(abs(log(x))) - * Case adjexp(x) == -1: - * mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered) - */ - adjexp = mpd_adjexp(a); - t = (adjexp < 0) ? -adjexp-1 : adjexp; - if (mpd_exp_digits(t)-1 > ctx->emax) { - *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; - mpd_setspecial(result, (adjexp<0), MPD_INF); - return; - } - - if (ctx->allcr) { - MPD_NEW_STATIC(t1, 0,0,0,0); - MPD_NEW_STATIC(t2, 0,0,0,0); - MPD_NEW_STATIC(ulp, 0,0,0,0); - MPD_NEW_STATIC(aa, 0,0,0,0); - mpd_ssize_t prec; - - if (result == a) { - if (!mpd_qcopy(&aa, a, status)) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - a = &aa; - } - - workctx.clamp = 0; - prec = ctx->prec + 3; - while (1) { - workctx.prec = prec; - _mpd_qlog10(SKIP_FINALIZE, result, a, &workctx, status); - _ssettriple(&ulp, MPD_POS, 1, - result->exp + result->digits-workctx.prec); - - workctx.prec = ctx->prec; - mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); - mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); - if (mpd_isspecial(result) || mpd_iszerocoeff(result) || - mpd_qcmp(&t1, &t2, status) == 0) { - workctx.clamp = ctx->clamp; - mpd_check_underflow(result, &workctx, status); - mpd_qfinalize(result, &workctx, status); - break; - } - prec += MPD_RDIGITS; - } - mpd_del(&t1); - mpd_del(&t2); - mpd_del(&ulp); - mpd_del(&aa); - } - else { - _mpd_qlog10(DO_FINALIZE, result, a, &workctx, status); - mpd_check_underflow(result, &workctx, status); - } -} - -/* - * Maximum of the two operands. Attention: If one operand is a quiet NaN and the - * other is numeric, the numeric operand is returned. This may not be what one - * expects. - */ -void -mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - int c; - - if (mpd_isqnan(a) && !mpd_isnan(b)) { - mpd_qcopy(result, b, status); - } - else if (mpd_isqnan(b) && !mpd_isnan(a)) { - mpd_qcopy(result, a, status); - } - else if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - else { - c = _mpd_cmp(a, b); - if (c == 0) { - c = _mpd_cmp_numequal(a, b); - } - - if (c < 0) { - mpd_qcopy(result, b, status); - } - else { - mpd_qcopy(result, a, status); - } - } - - mpd_qfinalize(result, ctx, status); -} - -/* - * Maximum magnitude: Same as mpd_max(), but compares the operands with their - * sign ignored. - */ -void -mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - int c; - - if (mpd_isqnan(a) && !mpd_isnan(b)) { - mpd_qcopy(result, b, status); - } - else if (mpd_isqnan(b) && !mpd_isnan(a)) { - mpd_qcopy(result, a, status); - } - else if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - else { - c = _mpd_cmp_abs(a, b); - if (c == 0) { - c = _mpd_cmp_numequal(a, b); - } - - if (c < 0) { - mpd_qcopy(result, b, status); - } - else { - mpd_qcopy(result, a, status); - } - } - - mpd_qfinalize(result, ctx, status); -} - -/* - * Minimum of the two operands. Attention: If one operand is a quiet NaN and the - * other is numeric, the numeric operand is returned. This may not be what one - * expects. - */ -void -mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - int c; - - if (mpd_isqnan(a) && !mpd_isnan(b)) { - mpd_qcopy(result, b, status); - } - else if (mpd_isqnan(b) && !mpd_isnan(a)) { - mpd_qcopy(result, a, status); - } - else if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - else { - c = _mpd_cmp(a, b); - if (c == 0) { - c = _mpd_cmp_numequal(a, b); - } - - if (c < 0) { - mpd_qcopy(result, a, status); - } - else { - mpd_qcopy(result, b, status); - } - } - - mpd_qfinalize(result, ctx, status); -} - -/* - * Minimum magnitude: Same as mpd_min(), but compares the operands with their - * sign ignored. - */ -void -mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - int c; - - if (mpd_isqnan(a) && !mpd_isnan(b)) { - mpd_qcopy(result, b, status); - } - else if (mpd_isqnan(b) && !mpd_isnan(a)) { - mpd_qcopy(result, a, status); - } - else if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - else { - c = _mpd_cmp_abs(a, b); - if (c == 0) { - c = _mpd_cmp_numequal(a, b); - } - - if (c < 0) { - mpd_qcopy(result, a, status); - } - else { - mpd_qcopy(result, b, status); - } - } - - mpd_qfinalize(result, ctx, status); -} - -/* Minimum space needed for the result array in _karatsuba_rec(). */ -static inline mpd_size_t -_kmul_resultsize(mpd_size_t la, mpd_size_t lb) -{ - mpd_size_t n, m; - - n = add_size_t(la, lb); - n = add_size_t(n, 1); - - m = (la+1)/2 + 1; - m = mul_size_t(m, 3); - - return (m > n) ? m : n; -} - -/* Work space needed in _karatsuba_rec(). lim >= 4 */ -static inline mpd_size_t -_kmul_worksize(mpd_size_t n, mpd_size_t lim) -{ - mpd_size_t m; - - if (n <= lim) { - return 0; - } - - m = (n+1)/2 + 1; - - return add_size_t(mul_size_t(m, 2), _kmul_worksize(m, lim)); -} - - -#define MPD_KARATSUBA_BASECASE 16 /* must be >= 4 */ - -/* - * Add the product of a and b to c. - * c must be _kmul_resultsize(la, lb) in size. - * w is used as a work array and must be _kmul_worksize(a, lim) in size. - * Roman E. Maeder, Storage Allocation for the Karatsuba Integer Multiplication - * Algorithm. In "Design and implementation of symbolic computation systems", - * Springer, 1993, ISBN 354057235X, 9783540572350. - */ -static void -_karatsuba_rec(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b, - mpd_uint_t *w, mpd_size_t la, mpd_size_t lb) -{ - mpd_size_t m, lt; - - assert(la >= lb && lb > 0); - assert(la <= MPD_KARATSUBA_BASECASE || w != NULL); - - if (la <= MPD_KARATSUBA_BASECASE) { - _mpd_basemul(c, a, b, la, lb); - return; - } - - m = (la+1)/2; /* ceil(la/2) */ - - /* lb <= m < la */ - if (lb <= m) { - - /* lb can now be larger than la-m */ - if (lb > la-m) { - lt = lb + lb + 1; /* space needed for result array */ - mpd_uint_zero(w, lt); /* clear result array */ - _karatsuba_rec(w, b, a+m, w+lt, lb, la-m); /* b*ah */ - } - else { - lt = (la-m) + (la-m) + 1; /* space needed for result array */ - mpd_uint_zero(w, lt); /* clear result array */ - _karatsuba_rec(w, a+m, b, w+lt, la-m, lb); /* ah*b */ - } - _mpd_baseaddto(c+m, w, (la-m)+lb); /* add ah*b*B**m */ - - lt = m + m + 1; /* space needed for the result array */ - mpd_uint_zero(w, lt); /* clear result array */ - _karatsuba_rec(w, a, b, w+lt, m, lb); /* al*b */ - _mpd_baseaddto(c, w, m+lb); /* add al*b */ - - return; - } - - /* la >= lb > m */ - memcpy(w, a, m * sizeof *w); - w[m] = 0; - _mpd_baseaddto(w, a+m, la-m); - - memcpy(w+(m+1), b, m * sizeof *w); - w[m+1+m] = 0; - _mpd_baseaddto(w+(m+1), b+m, lb-m); - - _karatsuba_rec(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1); - - lt = (la-m) + (la-m) + 1; - mpd_uint_zero(w, lt); - - _karatsuba_rec(w, a+m, b+m, w+lt, la-m, lb-m); - - _mpd_baseaddto(c+2*m, w, (la-m) + (lb-m)); - _mpd_basesubfrom(c+m, w, (la-m) + (lb-m)); - - lt = m + m + 1; - mpd_uint_zero(w, lt); - - _karatsuba_rec(w, a, b, w+lt, m, m); - _mpd_baseaddto(c, w, m+m); - _mpd_basesubfrom(c+m, w, m+m); - - return; -} - -/* - * Multiply u and v, using Karatsuba multiplication. Returns a pointer - * to the result or NULL in case of failure (malloc error). - * Conditions: ulen >= vlen, ulen >= 4 - */ -static mpd_uint_t * -_mpd_kmul(const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t ulen, mpd_size_t vlen, - mpd_size_t *rsize) -{ - mpd_uint_t *result = NULL, *w = NULL; - mpd_size_t m; - - assert(ulen >= 4); - assert(ulen >= vlen); - - *rsize = _kmul_resultsize(ulen, vlen); - if ((result = mpd_calloc(*rsize, sizeof *result)) == NULL) { - return NULL; - } - - m = _kmul_worksize(ulen, MPD_KARATSUBA_BASECASE); - if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) { - mpd_free(result); - return NULL; - } - - _karatsuba_rec(result, u, v, w, ulen, vlen); - - - if (w) mpd_free(w); - return result; -} - - -/* - * Determine the minimum length for the number theoretic transform. Valid - * transform lengths are 2**n or 3*2**n, where 2**n <= MPD_MAXTRANSFORM_2N. - * The function finds the shortest length m such that rsize <= m. - */ -static inline mpd_size_t -_mpd_get_transform_len(mpd_size_t rsize) -{ - mpd_size_t log2rsize; - mpd_size_t x, step; - - assert(rsize >= 4); - log2rsize = mpd_bsr(rsize); - - if (rsize <= 1024) { - /* 2**n is faster in this range. */ - x = ((mpd_size_t)1)<>1; - x += step; - return (rsize <= x) ? x : x + step; - } - else if (rsize <= MPD_MAXTRANSFORM_2N+MPD_MAXTRANSFORM_2N/2) { - return MPD_MAXTRANSFORM_2N+MPD_MAXTRANSFORM_2N/2; - } - else if (rsize <= 3*MPD_MAXTRANSFORM_2N) { - return 3*MPD_MAXTRANSFORM_2N; - } - else { - return MPD_SIZE_MAX; - } -} - -#ifdef PPRO -#ifndef _MSC_VER -static inline unsigned short -_mpd_get_control87(void) -{ - unsigned short cw; - - __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); - return cw; -} - -static inline void -_mpd_set_control87(unsigned short cw) -{ - __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); -} -#endif - -static unsigned int -mpd_set_fenv(void) -{ - unsigned int cw; -#ifdef _MSC_VER - unsigned int flags = - _EM_INVALID|_EM_DENORMAL|_EM_ZERODIVIDE|_EM_OVERFLOW| - _EM_UNDERFLOW|_EM_INEXACT|_RC_CHOP|_PC_64; - unsigned int mask = _MCW_EM|_MCW_RC|_MCW_PC; - unsigned int dummy; - - __control87_2(0, 0, &cw, NULL); - __control87_2(flags, mask, &dummy, NULL); -#else - cw = _mpd_get_control87(); - _mpd_set_control87(cw|0xF3F); -#endif - return cw; -} - -static void -mpd_restore_fenv(unsigned int cw) -{ -#ifdef _MSC_VER - unsigned int mask = _MCW_EM|_MCW_RC|_MCW_PC; - unsigned int dummy; - - __control87_2(cw, mask, &dummy, NULL); -#else - _mpd_set_control87((unsigned short)cw); -#endif -} -#endif /* PPRO */ - -/* - * Multiply u and v, using the fast number theoretic transform. Returns - * a pointer to the result or NULL in case of failure (malloc error). - */ -static mpd_uint_t * -_mpd_fntmul(const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t ulen, mpd_size_t vlen, - mpd_size_t *rsize) -{ - mpd_uint_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *vtmp = NULL; - mpd_size_t n; - -#ifdef PPRO - unsigned int cw; - cw = mpd_set_fenv(); -#endif - - *rsize = add_size_t(ulen, vlen); - if ((n = _mpd_get_transform_len(*rsize)) == MPD_SIZE_MAX) { - goto malloc_error; - } - - if ((c1 = mpd_calloc(n, sizeof *c1)) == NULL) { - goto malloc_error; - } - if ((c2 = mpd_calloc(n, sizeof *c2)) == NULL) { - goto malloc_error; - } - if ((c3 = mpd_calloc(n, sizeof *c3)) == NULL) { - goto malloc_error; - } - - memcpy(c1, u, ulen * (sizeof *c1)); - memcpy(c2, u, ulen * (sizeof *c2)); - memcpy(c3, u, ulen * (sizeof *c3)); - - if (u == v) { - if (!fnt_autoconvolute(c1, n, P1) || - !fnt_autoconvolute(c2, n, P2) || - !fnt_autoconvolute(c3, n, P3)) { - goto malloc_error; - } - } - else { - if ((vtmp = mpd_calloc(n, sizeof *vtmp)) == NULL) { - goto malloc_error; - } - - memcpy(vtmp, v, vlen * (sizeof *vtmp)); - if (!fnt_convolute(c1, vtmp, n, P1)) { - mpd_free(vtmp); - goto malloc_error; - } - - memcpy(vtmp, v, vlen * (sizeof *vtmp)); - mpd_uint_zero(vtmp+vlen, n-vlen); - if (!fnt_convolute(c2, vtmp, n, P2)) { - mpd_free(vtmp); - goto malloc_error; - } - - memcpy(vtmp, v, vlen * (sizeof *vtmp)); - mpd_uint_zero(vtmp+vlen, n-vlen); - if (!fnt_convolute(c3, vtmp, n, P3)) { - mpd_free(vtmp); - goto malloc_error; - } - - mpd_free(vtmp); - } - - crt3(c1, c2, c3, *rsize); - -out: -#ifdef PPRO - mpd_restore_fenv(cw); -#endif - if (c2) mpd_free(c2); - if (c3) mpd_free(c3); - return c1; - -malloc_error: - if (c1) mpd_free(c1); - c1 = NULL; - goto out; -} - - -/* - * Karatsuba multiplication with FNT/basemul as the base case. - */ -static int -_karatsuba_rec_fnt(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b, - mpd_uint_t *w, mpd_size_t la, mpd_size_t lb) -{ - mpd_size_t m, lt; - - assert(la >= lb && lb > 0); - assert(la <= 3*(MPD_MAXTRANSFORM_2N/2) || w != NULL); - - if (la <= 3*(MPD_MAXTRANSFORM_2N/2)) { - - if (lb <= 192) { - _mpd_basemul(c, b, a, lb, la); - } - else { - mpd_uint_t *result; - mpd_size_t dummy; - - if ((result = _mpd_fntmul(a, b, la, lb, &dummy)) == NULL) { - return 0; - } - memcpy(c, result, (la+lb) * (sizeof *result)); - mpd_free(result); - } - return 1; - } - - m = (la+1)/2; /* ceil(la/2) */ - - /* lb <= m < la */ - if (lb <= m) { - - /* lb can now be larger than la-m */ - if (lb > la-m) { - lt = lb + lb + 1; /* space needed for result array */ - mpd_uint_zero(w, lt); /* clear result array */ - if (!_karatsuba_rec_fnt(w, b, a+m, w+lt, lb, la-m)) { /* b*ah */ - return 0; /* GCOV_UNLIKELY */ - } - } - else { - lt = (la-m) + (la-m) + 1; /* space needed for result array */ - mpd_uint_zero(w, lt); /* clear result array */ - if (!_karatsuba_rec_fnt(w, a+m, b, w+lt, la-m, lb)) { /* ah*b */ - return 0; /* GCOV_UNLIKELY */ - } - } - _mpd_baseaddto(c+m, w, (la-m)+lb); /* add ah*b*B**m */ - - lt = m + m + 1; /* space needed for the result array */ - mpd_uint_zero(w, lt); /* clear result array */ - if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, lb)) { /* al*b */ - return 0; /* GCOV_UNLIKELY */ - } - _mpd_baseaddto(c, w, m+lb); /* add al*b */ - - return 1; - } - - /* la >= lb > m */ - memcpy(w, a, m * sizeof *w); - w[m] = 0; - _mpd_baseaddto(w, a+m, la-m); - - memcpy(w+(m+1), b, m * sizeof *w); - w[m+1+m] = 0; - _mpd_baseaddto(w+(m+1), b+m, lb-m); - - if (!_karatsuba_rec_fnt(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1)) { - return 0; /* GCOV_UNLIKELY */ - } - - lt = (la-m) + (la-m) + 1; - mpd_uint_zero(w, lt); - - if (!_karatsuba_rec_fnt(w, a+m, b+m, w+lt, la-m, lb-m)) { - return 0; /* GCOV_UNLIKELY */ - } - - _mpd_baseaddto(c+2*m, w, (la-m) + (lb-m)); - _mpd_basesubfrom(c+m, w, (la-m) + (lb-m)); - - lt = m + m + 1; - mpd_uint_zero(w, lt); - - if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, m)) { - return 0; /* GCOV_UNLIKELY */ - } - _mpd_baseaddto(c, w, m+m); - _mpd_basesubfrom(c+m, w, m+m); - - return 1; -} - -/* - * Multiply u and v, using Karatsuba multiplication with the FNT as the - * base case. Returns a pointer to the result or NULL in case of failure - * (malloc error). Conditions: ulen >= vlen, ulen >= 4. - */ -static mpd_uint_t * -_mpd_kmul_fnt(const mpd_uint_t *u, const mpd_uint_t *v, - mpd_size_t ulen, mpd_size_t vlen, - mpd_size_t *rsize) -{ - mpd_uint_t *result = NULL, *w = NULL; - mpd_size_t m; - - assert(ulen >= 4); - assert(ulen >= vlen); - - *rsize = _kmul_resultsize(ulen, vlen); - if ((result = mpd_calloc(*rsize, sizeof *result)) == NULL) { - return NULL; - } - - m = _kmul_worksize(ulen, 3*(MPD_MAXTRANSFORM_2N/2)); - if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) { - mpd_free(result); /* GCOV_UNLIKELY */ - return NULL; /* GCOV_UNLIKELY */ - } - - if (!_karatsuba_rec_fnt(result, u, v, w, ulen, vlen)) { - mpd_free(result); - result = NULL; - } - - - if (w) mpd_free(w); - return result; -} - - -/* Deal with the special cases of multiplying infinities. */ -static void -_mpd_qmul_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status) -{ - if (mpd_isinfinite(a)) { - if (mpd_iszero(b)) { - mpd_seterror(result, MPD_Invalid_operation, status); - } - else { - mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF); - } - return; - } - assert(mpd_isinfinite(b)); - if (mpd_iszero(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - } - else { - mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF); - } -} - -/* - * Internal function: Multiply a and b. _mpd_qmul deals with specials but - * does NOT finalize the result. This is for use in mpd_fma(). - */ -static inline void -_mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - const mpd_t *big = a, *small = b; - mpd_uint_t *rdata = NULL; - mpd_uint_t rbuf[MPD_MINALLOC_MAX]; - mpd_size_t rsize, i; - - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - _mpd_qmul_inf(result, a, b, status); - return; - } - - if (small->len > big->len) { - _mpd_ptrswap(&big, &small); - } - - rsize = big->len + small->len; - - if (big->len == 1) { - _mpd_singlemul(result->data, big->data[0], small->data[0]); - goto finish; - } - if (rsize <= (mpd_size_t)MPD_MINALLOC_MAX) { - if (big->len == 2) { - _mpd_mul_2_le2(rbuf, big->data, small->data, small->len); - } - else { - mpd_uint_zero(rbuf, rsize); - if (small->len == 1) { - _mpd_shortmul(rbuf, big->data, big->len, small->data[0]); - } - else { - _mpd_basemul(rbuf, small->data, big->data, small->len, big->len); - } - } - if (!mpd_qresize(result, rsize, status)) { - return; - } - for(i = 0; i < rsize; i++) { - result->data[i] = rbuf[i]; - } - goto finish; - } - - - if (small->len <= 256) { - rdata = mpd_calloc(rsize, sizeof *rdata); - if (rdata != NULL) { - if (small->len == 1) { - _mpd_shortmul(rdata, big->data, big->len, small->data[0]); - } - else { - _mpd_basemul(rdata, small->data, big->data, small->len, big->len); - } - } - } - else if (rsize <= 1024) { - rdata = _mpd_kmul(big->data, small->data, big->len, small->len, &rsize); - } - else if (rsize <= 3*MPD_MAXTRANSFORM_2N) { - rdata = _mpd_fntmul(big->data, small->data, big->len, small->len, &rsize); - } - else { - rdata = _mpd_kmul_fnt(big->data, small->data, big->len, small->len, &rsize); - } - - if (rdata == NULL) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - - if (mpd_isdynamic_data(result)) { - mpd_free(result->data); - } - result->data = rdata; - result->alloc = rsize; - mpd_set_dynamic_data(result); - - -finish: - mpd_set_flags(result, mpd_sign(a)^mpd_sign(b)); - result->exp = big->exp + small->exp; - result->len = _mpd_real_size(result->data, rsize); - /* resize to smaller cannot fail */ - mpd_qresize(result, result->len, status); - mpd_setdigits(result); -} - -/* Multiply a and b. */ -void -mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - _mpd_qmul(result, a, b, ctx, status); - mpd_qfinalize(result, ctx, status); -} - -/* Multiply a and b. Set NaN/Invalid_operation if the result is inexact. */ -static void -_mpd_qmul_exact(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - - mpd_qmul(result, a, b, ctx, &workstatus); - *status |= workstatus; - if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { - mpd_seterror(result, MPD_Invalid_operation, status); - } -} - -/* Multiply decimal and mpd_ssize_t. */ -void -mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qsset_ssize(&bb, b, &maxcontext, status); - mpd_qmul(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Multiply decimal and mpd_uint_t. */ -void -mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qsset_uint(&bb, b, &maxcontext, status); - mpd_qmul(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -void -mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qmul_ssize(result, a, b, ctx, status); -} - -void -mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qmul_uint(result, a, b, ctx, status); -} - -#ifdef CONFIG_64 -void -mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qmul_ssize(result, a, b, ctx, status); -} - -void -mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_qmul_uint(result, a, b, ctx, status); -} -#elif !defined(LEGACY_COMPILER) -/* Multiply decimal and int64_t. */ -void -mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qset_i64(&bb, b, &maxcontext, status); - mpd_qmul(result, a, &bb, ctx, status); - mpd_del(&bb); -} - -/* Multiply decimal and uint64_t. */ -void -mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(bb,0,0,0,0); - - mpd_maxcontext(&maxcontext); - mpd_qset_u64(&bb, b, &maxcontext, status); - mpd_qmul(result, a, &bb, ctx, status); - mpd_del(&bb); -} -#endif - -/* Like the minus operator. */ -void -mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - } - - if (mpd_iszero(a) && ctx->round != MPD_ROUND_FLOOR) { - mpd_qcopy_abs(result, a, status); - } - else { - mpd_qcopy_negate(result, a, status); - } - - mpd_qfinalize(result, ctx, status); -} - -/* Like the plus operator. */ -void -mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - } - - if (mpd_iszero(a) && ctx->round != MPD_ROUND_FLOOR) { - mpd_qcopy_abs(result, a, status); - } - else { - mpd_qcopy(result, a, status); - } - - mpd_qfinalize(result, ctx, status); -} - -/* The largest representable number that is smaller than the operand. */ -void -mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx; - MPD_NEW_CONST(tiny,MPD_POS,mpd_etiny(ctx)-1,1,1,1,1); - - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - - assert(mpd_isinfinite(a)); - if (mpd_isnegative(a)) { - mpd_qcopy(result, a, status); - return; - } - else { - mpd_clear_flags(result); - mpd_qmaxcoeff(result, ctx, status); - if (mpd_isnan(result)) { - return; - } - result->exp = mpd_etop(ctx); - return; - } - } - - mpd_workcontext(&workctx, ctx); - workctx.round = MPD_ROUND_FLOOR; - - if (!mpd_qcopy(result, a, status)) { - return; - } - - mpd_qfinalize(result, &workctx, &workctx.status); - if (workctx.status&(MPD_Inexact|MPD_Errors)) { - *status |= (workctx.status&MPD_Errors); - return; - } - - workctx.status = 0; - mpd_qsub(result, a, &tiny, &workctx, &workctx.status); - *status |= (workctx.status&MPD_Errors); -} - -/* The smallest representable number that is larger than the operand. */ -void -mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx; - MPD_NEW_CONST(tiny,MPD_POS,mpd_etiny(ctx)-1,1,1,1,1); - - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - - assert(mpd_isinfinite(a)); - if (mpd_ispositive(a)) { - mpd_qcopy(result, a, status); - } - else { - mpd_clear_flags(result); - mpd_qmaxcoeff(result, ctx, status); - if (mpd_isnan(result)) { - return; - } - mpd_set_flags(result, MPD_NEG); - result->exp = mpd_etop(ctx); - } - return; - } - - mpd_workcontext(&workctx, ctx); - workctx.round = MPD_ROUND_CEILING; - - if (!mpd_qcopy(result, a, status)) { - return; - } - - mpd_qfinalize(result, &workctx, &workctx.status); - if (workctx.status & (MPD_Inexact|MPD_Errors)) { - *status |= (workctx.status&MPD_Errors); - return; - } - - workctx.status = 0; - mpd_qadd(result, a, &tiny, &workctx, &workctx.status); - *status |= (workctx.status&MPD_Errors); -} - -/* - * The number closest to the first operand that is in the direction towards - * the second operand. - */ -void -mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - int c; - - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - - c = _mpd_cmp(a, b); - if (c == 0) { - mpd_qcopy_sign(result, a, b, status); - return; - } - - if (c < 0) { - mpd_qnext_plus(result, a, ctx, status); - } - else { - mpd_qnext_minus(result, a, ctx, status); - } - - if (mpd_isinfinite(result)) { - *status |= (MPD_Overflow|MPD_Rounded|MPD_Inexact); - } - else if (mpd_adjexp(result) < ctx->emin) { - *status |= (MPD_Underflow|MPD_Subnormal|MPD_Rounded|MPD_Inexact); - if (mpd_iszero(result)) { - *status |= MPD_Clamped; - } - } -} - -/* - * Internal function: Integer power with mpd_uint_t exponent. The function - * can fail with MPD_Malloc_error. - * - * The error is equal to the error incurred in k-1 multiplications. Assuming - * the upper bound for the relative error in each operation: - * - * abs(err) = 5 * 10**-prec - * result = x**k * (1 + err)**(k-1) - */ -static inline void -_mpd_qpow_uint(mpd_t *result, const mpd_t *base, mpd_uint_t exp, - uint8_t resultsign, const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_uint_t n; - - if (exp == 0) { - _settriple(result, resultsign, 1, 0); /* GCOV_NOT_REACHED */ - return; /* GCOV_NOT_REACHED */ - } - - if (!mpd_qcopy(result, base, status)) { - return; - } - - n = mpd_bits[mpd_bsr(exp)]; - while (n >>= 1) { - mpd_qmul(result, result, result, ctx, &workstatus); - if (exp & n) { - mpd_qmul(result, result, base, ctx, &workstatus); - } - if (mpd_isspecial(result) || - (mpd_iszerocoeff(result) && (workstatus & MPD_Clamped))) { - break; - } - } - - *status |= workstatus; - mpd_set_sign(result, resultsign); -} - -/* - * Internal function: Integer power with mpd_t exponent, tbase and texp - * are modified!! Function can fail with MPD_Malloc_error. - * - * The error is equal to the error incurred in k multiplications. Assuming - * the upper bound for the relative error in each operation: - * - * abs(err) = 5 * 10**-prec - * result = x**k * (1 + err)**k - */ -static inline void -_mpd_qpow_mpd(mpd_t *result, mpd_t *tbase, mpd_t *texp, uint8_t resultsign, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_context_t maxctx; - MPD_NEW_CONST(two,0,0,1,1,1,2); - - - mpd_maxcontext(&maxctx); - - /* resize to smaller cannot fail */ - mpd_qcopy(result, &one, status); - - while (!mpd_iszero(texp)) { - if (mpd_isodd(texp)) { - mpd_qmul(result, result, tbase, ctx, &workstatus); - *status |= workstatus; - if (mpd_isspecial(result) || - (mpd_iszerocoeff(result) && (workstatus & MPD_Clamped))) { - break; - } - } - mpd_qmul(tbase, tbase, tbase, ctx, &workstatus); - mpd_qdivint(texp, texp, &two, &maxctx, &workstatus); - if (mpd_isnan(tbase) || mpd_isnan(texp)) { - mpd_seterror(result, workstatus&MPD_Errors, status); - return; - } - } - mpd_set_sign(result, resultsign); -} - -/* - * The power function for integer exponents. Relative error _before_ the - * final rounding to prec: - * abs(result - base**exp) < 0.1 * 10**-prec * abs(base**exp) - */ -static void -_mpd_qpow_int(mpd_t *result, const mpd_t *base, const mpd_t *exp, - uint8_t resultsign, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t workctx; - MPD_NEW_STATIC(tbase,0,0,0,0); - MPD_NEW_STATIC(texp,0,0,0,0); - mpd_ssize_t n; - - - mpd_workcontext(&workctx, ctx); - workctx.prec += (exp->digits + exp->exp + 2); - workctx.round = MPD_ROUND_HALF_EVEN; - workctx.clamp = 0; - if (mpd_isnegative(exp)) { - uint32_t workstatus = 0; - workctx.prec += 1; - mpd_qdiv(&tbase, &one, base, &workctx, &workstatus); - *status |= workstatus; - if (workstatus&MPD_Errors) { - mpd_setspecial(result, MPD_POS, MPD_NAN); - goto finish; - } - } - else { - if (!mpd_qcopy(&tbase, base, status)) { - mpd_setspecial(result, MPD_POS, MPD_NAN); - goto finish; - } - } - - n = mpd_qabs_uint(exp, &workctx.status); - if (workctx.status&MPD_Invalid_operation) { - if (!mpd_qcopy(&texp, exp, status)) { - mpd_setspecial(result, MPD_POS, MPD_NAN); /* GCOV_UNLIKELY */ - goto finish; /* GCOV_UNLIKELY */ - } - _mpd_qpow_mpd(result, &tbase, &texp, resultsign, &workctx, status); - } - else { - _mpd_qpow_uint(result, &tbase, n, resultsign, &workctx, status); - } - - if (mpd_isinfinite(result)) { - /* for ROUND_DOWN, ROUND_FLOOR, etc. */ - _settriple(result, resultsign, 1, MPD_EXP_INF); - } - -finish: - mpd_del(&tbase); - mpd_del(&texp); - mpd_qfinalize(result, ctx, status); -} - -/* - * If the exponent is infinite and base equals one, the result is one - * with a coefficient of length prec. Otherwise, result is undefined. - * Return the value of the comparison against one. - */ -static int -_qcheck_pow_one_inf(mpd_t *result, const mpd_t *base, uint8_t resultsign, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_ssize_t shift; - int cmp; - - if ((cmp = _mpd_cmp(base, &one)) == 0) { - shift = ctx->prec-1; - mpd_qshiftl(result, &one, shift, status); - result->exp = -shift; - mpd_set_flags(result, resultsign); - *status |= (MPD_Inexact|MPD_Rounded); - } - - return cmp; -} - -/* - * If abs(base) equals one, calculate the correct power of one result. - * Otherwise, result is undefined. Return the value of the comparison - * against 1. - * - * This is an internal function that does not check for specials. - */ -static int -_qcheck_pow_one(mpd_t *result, const mpd_t *base, const mpd_t *exp, - uint8_t resultsign, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_ssize_t shift; - int cmp; - - if ((cmp = _mpd_cmp_abs(base, &one)) == 0) { - if (_mpd_isint(exp)) { - if (mpd_isnegative(exp)) { - _settriple(result, resultsign, 1, 0); - return 0; - } - /* 1.000**3 = 1.000000000 */ - mpd_qmul_ssize(result, exp, -base->exp, ctx, &workstatus); - if (workstatus&MPD_Errors) { - *status |= (workstatus&MPD_Errors); - return 0; - } - /* digits-1 after exponentiation */ - shift = mpd_qget_ssize(result, &workstatus); - /* shift is MPD_SSIZE_MAX if result is too large */ - if (shift > ctx->prec-1) { - shift = ctx->prec-1; - *status |= MPD_Rounded; - } - } - else if (mpd_ispositive(base)) { - shift = ctx->prec-1; - *status |= (MPD_Inexact|MPD_Rounded); - } - else { - return -2; /* GCOV_NOT_REACHED */ - } - if (!mpd_qshiftl(result, &one, shift, status)) { - return 0; - } - result->exp = -shift; - mpd_set_flags(result, resultsign); - } - - return cmp; -} - -/* - * Detect certain over/underflow of x**y. - * ACL2 proof: pow-bounds.lisp. - * - * Symbols: - * - * e: EXP_INF or EXP_CLAMP - * x: base - * y: exponent - * - * omega(e) = log10(abs(e)) - * zeta(x) = log10(abs(log10(x))) - * theta(y) = log10(abs(y)) - * - * Upper and lower bounds: - * - * ub_omega(e) = ceil(log10(abs(e))) - * lb_theta(y) = floor(log10(abs(y))) - * - * | floor(log10(floor(abs(log10(x))))) if x < 1/10 or x >= 10 - * lb_zeta(x) = | floor(log10(abs(x-1)/10)) if 1/10 <= x < 1 - * | floor(log10(abs((x-1)/100))) if 1 < x < 10 - * - * ub_omega(e) and lb_theta(y) are obviously upper and lower bounds - * for omega(e) and theta(y). - * - * lb_zeta is a lower bound for zeta(x): - * - * x < 1/10 or x >= 10: - * - * abs(log10(x)) >= 1, so the outer log10 is well defined. Since log10 - * is strictly increasing, the end result is a lower bound. - * - * 1/10 <= x < 1: - * - * We use: log10(x) <= (x-1)/log(10) - * abs(log10(x)) >= abs(x-1)/log(10) - * abs(log10(x)) >= abs(x-1)/10 - * - * 1 < x < 10: - * - * We use: (x-1)/(x*log(10)) < log10(x) - * abs((x-1)/100) < abs(log10(x)) - * - * XXX: abs((x-1)/10) would work, need ACL2 proof. - * - * - * Let (0 < x < 1 and y < 0) or (x > 1 and y > 0). (H1) - * Let ub_omega(exp_inf) < lb_zeta(x) + lb_theta(y) (H2) - * - * Then: - * log10(abs(exp_inf)) < log10(abs(log10(x))) + log10(abs(y)). (1) - * exp_inf < log10(x) * y (2) - * 10**exp_inf < x**y (3) - * - * Let (0 < x < 1 and y > 0) or (x > 1 and y < 0). (H3) - * Let ub_omega(exp_clamp) < lb_zeta(x) + lb_theta(y) (H4) - * - * Then: - * log10(abs(exp_clamp)) < log10(abs(log10(x))) + log10(abs(y)). (4) - * log10(x) * y < exp_clamp (5) - * x**y < 10**exp_clamp (6) - * - */ -static mpd_ssize_t -_lower_bound_zeta(const mpd_t *x, uint32_t *status) -{ - mpd_context_t maxctx; - MPD_NEW_STATIC(scratch,0,0,0,0); - mpd_ssize_t t, u; - - t = mpd_adjexp(x); - if (t > 0) { - /* x >= 10 -> floor(log10(floor(abs(log10(x))))) */ - return mpd_exp_digits(t) - 1; - } - else if (t < -1) { - /* x < 1/10 -> floor(log10(floor(abs(log10(x))))) */ - return mpd_exp_digits(t+1) - 1; - } - else { - mpd_maxcontext(&maxctx); - mpd_qsub(&scratch, x, &one, &maxctx, status); - if (mpd_isspecial(&scratch)) { - mpd_del(&scratch); - return MPD_SSIZE_MAX; - } - u = mpd_adjexp(&scratch); - mpd_del(&scratch); - - /* t == -1, 1/10 <= x < 1 -> floor(log10(abs(x-1)/10)) - * t == 0, 1 < x < 10 -> floor(log10(abs(x-1)/100)) */ - return (t == 0) ? u-2 : u-1; - } -} - -/* - * Detect cases of certain overflow/underflow in the power function. - * Assumptions: x != 1, y != 0. The proof above is for positive x. - * If x is negative and y is an odd integer, x**y == -(abs(x)**y), - * so the analysis does not change. - */ -static int -_qcheck_pow_bounds(mpd_t *result, const mpd_t *x, const mpd_t *y, - uint8_t resultsign, - const mpd_context_t *ctx, uint32_t *status) -{ - MPD_NEW_SHARED(abs_x, x); - mpd_ssize_t ub_omega, lb_zeta, lb_theta; - uint8_t sign; - - mpd_set_positive(&abs_x); - - lb_theta = mpd_adjexp(y); - lb_zeta = _lower_bound_zeta(&abs_x, status); - if (lb_zeta == MPD_SSIZE_MAX) { - mpd_seterror(result, MPD_Malloc_error, status); - return 1; - } - - sign = (mpd_adjexp(&abs_x) < 0) ^ mpd_sign(y); - if (sign == 0) { - /* (0 < |x| < 1 and y < 0) or (|x| > 1 and y > 0) */ - ub_omega = mpd_exp_digits(ctx->emax); - if (ub_omega < lb_zeta + lb_theta) { - _settriple(result, resultsign, 1, MPD_EXP_INF); - mpd_qfinalize(result, ctx, status); - return 1; - } - } - else { - /* (0 < |x| < 1 and y > 0) or (|x| > 1 and y < 0). */ - ub_omega = mpd_exp_digits(mpd_etiny(ctx)); - if (ub_omega < lb_zeta + lb_theta) { - _settriple(result, resultsign, 1, mpd_etiny(ctx)-1); - mpd_qfinalize(result, ctx, status); - return 1; - } - } - - return 0; -} - -/* - * TODO: Implement algorithm for computing exact powers from decimal.py. - * In order to prevent infinite loops, this has to be called before - * using Ziv's strategy for correct rounding. - */ -/* -static int -_mpd_qpow_exact(mpd_t *result, const mpd_t *base, const mpd_t *exp, - const mpd_context_t *ctx, uint32_t *status) -{ - return 0; -} -*/ - -/* - * The power function for real exponents. - * Relative error: abs(result - e**y) < e**y * 1/5 * 10**(-prec - 1) - */ -static void -_mpd_qpow_real(mpd_t *result, const mpd_t *base, const mpd_t *exp, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t workctx; - MPD_NEW_STATIC(texp,0,0,0,0); - - if (!mpd_qcopy(&texp, exp, status)) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - - mpd_maxcontext(&workctx); - workctx.prec = (base->digits > ctx->prec) ? base->digits : ctx->prec; - workctx.prec += (4 + MPD_EXPDIGITS); - workctx.round = MPD_ROUND_HALF_EVEN; - workctx.allcr = ctx->allcr; - - /* - * extra := MPD_EXPDIGITS = MPD_EXP_MAX_T - * wp := prec + 4 + extra - * abs(err) < 5 * 10**-wp - * y := log(base) * exp - * Calculate: - * 1) e**(y * (1 + err)**2) * (1 + err) - * = e**y * e**(y * (2*err + err**2)) * (1 + err) - * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - * Relative error of the underlined term: - * 2) abs(e**(y * (2*err + err**2)) - 1) - * Case abs(y) >= 10**extra: - * 3) adjexp(y)+1 > log10(abs(y)) >= extra - * This triggers the Overflow/Underflow shortcut in _mpd_qexp(), - * so no further analysis is necessary. - * Case abs(y) < 10**extra: - * 4) abs(y * (2*err + err**2)) < 1/5 * 10**(-prec - 2) - * Use (see _mpd_qexp): - * 5) abs(x) <= 9/10 * 10**-p ==> abs(e**x - 1) < 10**-p - * With 2), 4) and 5): - * 6) abs(e**(y * (2*err + err**2)) - 1) < 10**(-prec - 2) - * The complete relative error of 1) is: - * 7) abs(result - e**y) < e**y * 1/5 * 10**(-prec - 1) - */ - mpd_qln(result, base, &workctx, &workctx.status); - mpd_qmul(result, result, &texp, &workctx, &workctx.status); - mpd_qexp(result, result, &workctx, status); - - mpd_del(&texp); - *status |= (workctx.status&MPD_Errors); - *status |= (MPD_Inexact|MPD_Rounded); -} - -/* The power function: base**exp */ -void -mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, - const mpd_context_t *ctx, uint32_t *status) -{ - uint8_t resultsign = 0; - int intexp = 0; - int cmp; - - if (mpd_isspecial(base) || mpd_isspecial(exp)) { - if (mpd_qcheck_nans(result, base, exp, ctx, status)) { - return; - } - } - if (mpd_isinteger(exp)) { - intexp = 1; - resultsign = mpd_isnegative(base) && mpd_isodd(exp); - } - - if (mpd_iszero(base)) { - if (mpd_iszero(exp)) { - mpd_seterror(result, MPD_Invalid_operation, status); - } - else if (mpd_isnegative(exp)) { - mpd_setspecial(result, resultsign, MPD_INF); - } - else { - _settriple(result, resultsign, 0, 0); - } - return; - } - if (mpd_isnegative(base)) { - if (!intexp || mpd_isinfinite(exp)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - } - if (mpd_isinfinite(exp)) { - /* power of one */ - cmp = _qcheck_pow_one_inf(result, base, resultsign, ctx, status); - if (cmp == 0) { - return; - } - else { - cmp *= mpd_arith_sign(exp); - if (cmp < 0) { - _settriple(result, resultsign, 0, 0); - } - else { - mpd_setspecial(result, resultsign, MPD_INF); - } - } - return; - } - if (mpd_isinfinite(base)) { - if (mpd_iszero(exp)) { - _settriple(result, resultsign, 1, 0); - } - else if (mpd_isnegative(exp)) { - _settriple(result, resultsign, 0, 0); - } - else { - mpd_setspecial(result, resultsign, MPD_INF); - } - return; - } - if (mpd_iszero(exp)) { - _settriple(result, resultsign, 1, 0); - return; - } - if (_qcheck_pow_one(result, base, exp, resultsign, ctx, status) == 0) { - return; - } - if (_qcheck_pow_bounds(result, base, exp, resultsign, ctx, status)) { - return; - } - - if (intexp) { - _mpd_qpow_int(result, base, exp, resultsign, ctx, status); - } - else { - _mpd_qpow_real(result, base, exp, ctx, status); - if (!mpd_isspecial(result) && _mpd_cmp(result, &one) == 0) { - mpd_ssize_t shift = ctx->prec-1; - mpd_qshiftl(result, &one, shift, status); - result->exp = -shift; - } - if (mpd_isinfinite(result)) { - /* for ROUND_DOWN, ROUND_FLOOR, etc. */ - _settriple(result, MPD_POS, 1, MPD_EXP_INF); - } - mpd_qfinalize(result, ctx, status); - } -} - -/* - * Internal function: Integer powmod with mpd_uint_t exponent, base is modified! - * Function can fail with MPD_Malloc_error. - */ -static inline void -_mpd_qpowmod_uint(mpd_t *result, mpd_t *base, mpd_uint_t exp, - const mpd_t *mod, uint32_t *status) -{ - mpd_context_t maxcontext; - - mpd_maxcontext(&maxcontext); - - /* resize to smaller cannot fail */ - mpd_qcopy(result, &one, status); - - while (exp > 0) { - if (exp & 1) { - _mpd_qmul_exact(result, result, base, &maxcontext, status); - mpd_qrem(result, result, mod, &maxcontext, status); - } - _mpd_qmul_exact(base, base, base, &maxcontext, status); - mpd_qrem(base, base, mod, &maxcontext, status); - exp >>= 1; - } -} - -/* The powmod function: (base**exp) % mod */ -void -mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, - const mpd_t *mod, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(tbase,0,0,0,0); - MPD_NEW_STATIC(texp,0,0,0,0); - MPD_NEW_STATIC(tmod,0,0,0,0); - MPD_NEW_STATIC(tmp,0,0,0,0); - MPD_NEW_CONST(two,0,0,1,1,1,2); - mpd_ssize_t tbase_exp, texp_exp; - mpd_ssize_t i; - mpd_t t; - mpd_uint_t r; - uint8_t sign; - - - if (mpd_isspecial(base) || mpd_isspecial(exp) || mpd_isspecial(mod)) { - if (mpd_qcheck_3nans(result, base, exp, mod, ctx, status)) { - return; - } - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - - if (!_mpd_isint(base) || !_mpd_isint(exp) || !_mpd_isint(mod)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (mpd_iszerocoeff(mod)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (mod->digits+mod->exp > ctx->prec) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - sign = (mpd_isnegative(base)) && (mpd_isodd(exp)); - if (mpd_iszerocoeff(exp)) { - if (mpd_iszerocoeff(base)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - r = (_mpd_cmp_abs(mod, &one)==0) ? 0 : 1; - _settriple(result, sign, r, 0); - return; - } - if (mpd_isnegative(exp)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (mpd_iszerocoeff(base)) { - _settriple(result, sign, 0, 0); - return; - } - - mpd_maxcontext(&maxcontext); - - mpd_qrescale(&tmod, mod, 0, &maxcontext, &maxcontext.status); - if (maxcontext.status&MPD_Errors) { - mpd_seterror(result, maxcontext.status&MPD_Errors, status); - goto out; - } - maxcontext.status = 0; - mpd_set_positive(&tmod); - - mpd_qround_to_int(&tbase, base, &maxcontext, status); - mpd_set_positive(&tbase); - tbase_exp = tbase.exp; - tbase.exp = 0; - - mpd_qround_to_int(&texp, exp, &maxcontext, status); - texp_exp = texp.exp; - texp.exp = 0; - - /* base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo */ - mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); - mpd_qshiftl(result, &one, tbase_exp, status); - mpd_qrem(result, result, &tmod, &maxcontext, status); - _mpd_qmul_exact(&tbase, &tbase, result, &maxcontext, status); - mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); - if (mpd_isspecial(&tbase) || - mpd_isspecial(&texp) || - mpd_isspecial(&tmod)) { - goto mpd_errors; - } - - for (i = 0; i < texp_exp; i++) { - _mpd_qpowmod_uint(&tmp, &tbase, 10, &tmod, status); - t = tmp; - tmp = tbase; - tbase = t; - } - if (mpd_isspecial(&tbase)) { - goto mpd_errors; /* GCOV_UNLIKELY */ - } - - /* resize to smaller cannot fail */ - mpd_qcopy(result, &one, status); - while (mpd_isfinite(&texp) && !mpd_iszero(&texp)) { - if (mpd_isodd(&texp)) { - _mpd_qmul_exact(result, result, &tbase, &maxcontext, status); - mpd_qrem(result, result, &tmod, &maxcontext, status); - } - _mpd_qmul_exact(&tbase, &tbase, &tbase, &maxcontext, status); - mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); - mpd_qdivint(&texp, &texp, &two, &maxcontext, status); - } - if (mpd_isspecial(&texp) || mpd_isspecial(&tbase) || - mpd_isspecial(&tmod) || mpd_isspecial(result)) { - /* MPD_Malloc_error */ - goto mpd_errors; - } - else { - mpd_set_sign(result, sign); - } - -out: - mpd_del(&tbase); - mpd_del(&texp); - mpd_del(&tmod); - mpd_del(&tmp); - return; - -mpd_errors: - mpd_setspecial(result, MPD_POS, MPD_NAN); - goto out; -} - -void -mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_ssize_t b_exp = b->exp; - mpd_ssize_t expdiff, shift; - mpd_uint_t rnd; - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(result, a, b, ctx, status)) { - return; - } - if (mpd_isinfinite(a) && mpd_isinfinite(b)) { - mpd_qcopy(result, a, status); - return; - } - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - if (b->exp > ctx->emax || b->exp < mpd_etiny(ctx)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - if (mpd_iszero(a)) { - _settriple(result, mpd_sign(a), 0, b->exp); - mpd_qfinalize(result, ctx, status); - return; - } - - - expdiff = a->exp - b->exp; - if (a->digits + expdiff > ctx->prec) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - if (expdiff >= 0) { - shift = expdiff; - if (!mpd_qshiftl(result, a, shift, status)) { - return; - } - result->exp = b_exp; - } - else { - /* At this point expdiff < 0 and a->digits+expdiff <= prec, - * so the shift before an increment will fit in prec. */ - shift = -expdiff; - rnd = mpd_qshiftr(result, a, shift, status); - if (rnd == MPD_UINT_MAX) { - return; - } - result->exp = b_exp; - if (!_mpd_apply_round_fit(result, rnd, ctx, status)) { - return; - } - workstatus |= MPD_Rounded; - if (rnd) { - workstatus |= MPD_Inexact; - } - } - - if (mpd_adjexp(result) > ctx->emax || - mpd_adjexp(result) < mpd_etiny(ctx)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - *status |= workstatus; - mpd_qfinalize(result, ctx, status); -} - -void -mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_ssize_t shift, maxexp, maxshift; - uint8_t sign_a = mpd_sign(a); - - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - mpd_qcopy(result, a, status); - return; - } - - if (!mpd_qcopy(result, a, status)) { - return; - } - mpd_qfinalize(result, ctx, status); - if (mpd_isspecial(result)) { - return; - } - if (mpd_iszero(result)) { - _settriple(result, sign_a, 0, 0); - return; - } - - shift = mpd_trail_zeros(result); - maxexp = (ctx->clamp) ? mpd_etop(ctx) : ctx->emax; - /* After the finalizing above result->exp <= maxexp. */ - maxshift = maxexp - result->exp; - shift = (shift > maxshift) ? maxshift : shift; - - mpd_qshiftr_inplace(result, shift); - result->exp += shift; -} - -void -mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, - uint32_t *status) -{ - MPD_NEW_STATIC(q,0,0,0,0); - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(r, a, b, ctx, status)) { - return; - } - if (mpd_isinfinite(a)) { - mpd_seterror(r, MPD_Invalid_operation, status); - return; - } - if (mpd_isinfinite(b)) { - mpd_qcopy(r, a, status); - mpd_qfinalize(r, ctx, status); - return; - } - /* debug */ - abort(); /* GCOV_NOT_REACHED */ - } - if (mpd_iszerocoeff(b)) { - if (mpd_iszerocoeff(a)) { - mpd_seterror(r, MPD_Division_undefined, status); - } - else { - mpd_seterror(r, MPD_Invalid_operation, status); - } - return; - } - - _mpd_qdivmod(&q, r, a, b, ctx, status); - mpd_del(&q); - mpd_qfinalize(r, ctx, status); -} - -void -mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_context_t workctx; - MPD_NEW_STATIC(btmp,0,0,0,0); - MPD_NEW_STATIC(q,0,0,0,0); - mpd_ssize_t expdiff, qdigits; - int cmp, isodd, allnine; - - assert(r != NULL); /* annotation for scan-build */ - - if (mpd_isspecial(a) || mpd_isspecial(b)) { - if (mpd_qcheck_nans(r, a, b, ctx, status)) { - return; - } - if (mpd_isinfinite(a)) { - mpd_seterror(r, MPD_Invalid_operation, status); - return; - } - if (mpd_isinfinite(b)) { - mpd_qcopy(r, a, status); - mpd_qfinalize(r, ctx, status); - return; - } - /* debug */ - abort(); /* GCOV_NOT_REACHED */ - } - if (mpd_iszerocoeff(b)) { - if (mpd_iszerocoeff(a)) { - mpd_seterror(r, MPD_Division_undefined, status); - } - else { - mpd_seterror(r, MPD_Invalid_operation, status); - } - return; - } - - if (r == b) { - if (!mpd_qcopy(&btmp, b, status)) { - mpd_seterror(r, MPD_Malloc_error, status); - return; - } - b = &btmp; - } - - _mpd_qdivmod(&q, r, a, b, ctx, status); - if (mpd_isnan(&q) || mpd_isnan(r)) { - goto finish; - } - if (mpd_iszerocoeff(r)) { - goto finish; - } - - expdiff = mpd_adjexp(b) - mpd_adjexp(r); - if (-1 <= expdiff && expdiff <= 1) { - - allnine = mpd_coeff_isallnine(&q); - qdigits = q.digits; - isodd = mpd_isodd(&q); - - mpd_maxcontext(&workctx); - if (mpd_sign(a) == mpd_sign(b)) { - /* sign(r) == sign(b) */ - _mpd_qsub(&q, r, b, &workctx, &workctx.status); - } - else { - /* sign(r) != sign(b) */ - _mpd_qadd(&q, r, b, &workctx, &workctx.status); - } - - if (workctx.status&MPD_Errors) { - mpd_seterror(r, workctx.status&MPD_Errors, status); - goto finish; - } - - cmp = _mpd_cmp_abs(&q, r); - if (cmp < 0 || (cmp == 0 && isodd)) { - /* abs(r) > abs(b)/2 or abs(r) == abs(b)/2 and isodd(quotient) */ - if (allnine && qdigits == ctx->prec) { - /* abs(quotient) + 1 == 10**prec */ - mpd_seterror(r, MPD_Division_impossible, status); - goto finish; - } - mpd_qcopy(r, &q, status); - } - } - - -finish: - mpd_del(&btmp); - mpd_del(&q); - mpd_qfinalize(r, ctx, status); -} - -static void -_mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_ssize_t expdiff, shift; - mpd_uint_t rnd; - - if (mpd_isspecial(a)) { - mpd_qcopy(result, a, status); - return; - } - - if (mpd_iszero(a)) { - _settriple(result, mpd_sign(a), 0, exp); - return; - } - - expdiff = a->exp - exp; - if (expdiff >= 0) { - shift = expdiff; - if (a->digits + shift > MPD_MAX_PREC+1) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - if (!mpd_qshiftl(result, a, shift, status)) { - return; - } - result->exp = exp; - } - else { - shift = -expdiff; - rnd = mpd_qshiftr(result, a, shift, status); - if (rnd == MPD_UINT_MAX) { - return; - } - result->exp = exp; - _mpd_apply_round_excess(result, rnd, ctx, status); - *status |= MPD_Rounded; - if (rnd) { - *status |= MPD_Inexact; - } - } - - if (mpd_issubnormal(result, ctx)) { - *status |= MPD_Subnormal; - } -} - -/* - * Rescale a number so that it has exponent 'exp'. Does not regard context - * precision, emax, emin, but uses the rounding mode. Special numbers are - * quietly copied. Restrictions: - * - * MPD_MIN_ETINY <= exp <= MPD_MAX_EMAX+1 - * result->digits <= MPD_MAX_PREC+1 - */ -void -mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, - const mpd_context_t *ctx, uint32_t *status) -{ - if (exp > MPD_MAX_EMAX+1 || exp < MPD_MIN_ETINY) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - _mpd_qrescale(result, a, exp, ctx, status); -} - -/* - * Same as mpd_qrescale, but with relaxed restrictions. The result of this - * function should only be used for formatting a number and never as input - * for other operations. - * - * MPD_MIN_ETINY-MPD_MAX_PREC <= exp <= MPD_MAX_EMAX+1 - * result->digits <= MPD_MAX_PREC+1 - */ -void -mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, - const mpd_context_t *ctx, uint32_t *status) -{ - if (exp > MPD_MAX_EMAX+1 || exp < MPD_MIN_ETINY-MPD_MAX_PREC) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - _mpd_qrescale(result, a, exp, ctx, status); -} - -/* Round to an integer according to 'action' and ctx->round. */ -enum {TO_INT_EXACT, TO_INT_SILENT, TO_INT_TRUNC}; -static void -_mpd_qround_to_integral(int action, mpd_t *result, const mpd_t *a, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_uint_t rnd; - - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - mpd_qcopy(result, a, status); - return; - } - if (a->exp >= 0) { - mpd_qcopy(result, a, status); - return; - } - if (mpd_iszerocoeff(a)) { - _settriple(result, mpd_sign(a), 0, 0); - return; - } - - rnd = mpd_qshiftr(result, a, -a->exp, status); - if (rnd == MPD_UINT_MAX) { - return; - } - result->exp = 0; - - if (action == TO_INT_EXACT || action == TO_INT_SILENT) { - _mpd_apply_round_excess(result, rnd, ctx, status); - if (action == TO_INT_EXACT) { - *status |= MPD_Rounded; - if (rnd) { - *status |= MPD_Inexact; - } - } - } -} - -void -mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - (void)_mpd_qround_to_integral(TO_INT_EXACT, result, a, ctx, status); -} - -void -mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, ctx, status); -} - -void -mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - if (mpd_isspecial(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - (void)_mpd_qround_to_integral(TO_INT_TRUNC, result, a, ctx, status); -} - -void -mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx = *ctx; - - if (mpd_isspecial(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - workctx.round = MPD_ROUND_FLOOR; - (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, - &workctx, status); -} - -void -mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx = *ctx; - - if (mpd_isspecial(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - workctx.round = MPD_ROUND_CEILING; - (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, - &workctx, status); -} - -int -mpd_same_quantum(const mpd_t *a, const mpd_t *b) -{ - if (mpd_isspecial(a) || mpd_isspecial(b)) { - return ((mpd_isnan(a) && mpd_isnan(b)) || - (mpd_isinfinite(a) && mpd_isinfinite(b))); - } - - return a->exp == b->exp; -} - -/* Schedule the increase in precision for the Newton iteration. */ -static inline int -recpr_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], - mpd_ssize_t maxprec, mpd_ssize_t initprec) -{ - mpd_ssize_t k; - int i; - - assert(maxprec > 0 && initprec > 0); - if (maxprec <= initprec) return -1; - - i = 0; k = maxprec; - do { - k = (k+1) / 2; - klist[i++] = k; - } while (k > initprec); - - return i-1; -} - -/* - * Initial approximation for the reciprocal: - * k_0 := MPD_RDIGITS-2 - * z_0 := 10**(-k_0) * floor(10**(2*k_0 + 2) / floor(v * 10**(k_0 + 2))) - * Absolute error: - * |1/v - z_0| < 10**(-k_0) - * ACL2 proof: maxerror-inverse-approx - */ -static void -_mpd_qreciprocal_approx(mpd_t *z, const mpd_t *v, uint32_t *status) -{ - mpd_uint_t p10data[2] = {0, mpd_pow10[MPD_RDIGITS-2]}; - mpd_uint_t dummy, word; - int n; - - assert(v->exp == -v->digits); - - _mpd_get_msdigits(&dummy, &word, v, MPD_RDIGITS); - n = mpd_word_digits(word); - word *= mpd_pow10[MPD_RDIGITS-n]; - - mpd_qresize(z, 2, status); - (void)_mpd_shortdiv(z->data, p10data, 2, word); - - mpd_clear_flags(z); - z->exp = -(MPD_RDIGITS-2); - z->len = (z->data[1] == 0) ? 1 : 2; - mpd_setdigits(z); -} - -/* - * Reciprocal, calculated with Newton's Method. Assumption: result != a. - * NOTE: The comments in the function show that certain operations are - * exact. The proof for the maximum error is too long to fit in here. - * ACL2 proof: maxerror-inverse-complete - */ -static void -_mpd_qreciprocal(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t varcontext, maxcontext; - mpd_t *z = result; /* current approximation */ - mpd_t *v; /* a, normalized to a number between 0.1 and 1 */ - MPD_NEW_SHARED(vtmp, a); /* v shares data with a */ - MPD_NEW_STATIC(s,0,0,0,0); /* temporary variable */ - MPD_NEW_STATIC(t,0,0,0,0); /* temporary variable */ - MPD_NEW_CONST(two,0,0,1,1,1,2); /* const 2 */ - mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; - mpd_ssize_t adj, maxprec, initprec; - uint8_t sign = mpd_sign(a); - int i; - - assert(result != a); - - v = &vtmp; - mpd_clear_flags(v); - adj = v->digits + v->exp; - v->exp = -v->digits; - - /* Initial approximation */ - _mpd_qreciprocal_approx(z, v, status); - - mpd_maxcontext(&varcontext); - mpd_maxcontext(&maxcontext); - varcontext.round = maxcontext.round = MPD_ROUND_TRUNC; - varcontext.emax = maxcontext.emax = MPD_MAX_EMAX + 100; - varcontext.emin = maxcontext.emin = MPD_MIN_EMIN - 100; - maxcontext.prec = MPD_MAX_PREC + 100; - - maxprec = ctx->prec; - maxprec += 2; - initprec = MPD_RDIGITS-3; - - i = recpr_schedule_prec(klist, maxprec, initprec); - for (; i >= 0; i--) { - /* Loop invariant: z->digits <= klist[i]+7 */ - /* Let s := z**2, exact result */ - _mpd_qmul_exact(&s, z, z, &maxcontext, status); - varcontext.prec = 2*klist[i] + 5; - if (v->digits > varcontext.prec) { - /* Let t := v, truncated to n >= 2*k+5 fraction digits */ - mpd_qshiftr(&t, v, v->digits-varcontext.prec, status); - t.exp = -varcontext.prec; - /* Let t := trunc(v)*s, truncated to n >= 2*k+1 fraction digits */ - mpd_qmul(&t, &t, &s, &varcontext, status); - } - else { /* v->digits <= 2*k+5 */ - /* Let t := v*s, truncated to n >= 2*k+1 fraction digits */ - mpd_qmul(&t, v, &s, &varcontext, status); - } - /* Let s := 2*z, exact result */ - _mpd_qmul_exact(&s, z, &two, &maxcontext, status); - /* s.digits < t.digits <= 2*k+5, |adjexp(s)-adjexp(t)| <= 1, - * so the subtraction generates at most 2*k+6 <= klist[i+1]+7 - * digits. The loop invariant is preserved. */ - _mpd_qsub_exact(z, &s, &t, &maxcontext, status); - } - - if (!mpd_isspecial(z)) { - z->exp -= adj; - mpd_set_flags(z, sign); - } - - mpd_del(&s); - mpd_del(&t); - mpd_qfinalize(z, ctx, status); -} - -/* - * Internal function for large numbers: - * - * q, r = divmod(coeff(a), coeff(b)) - * - * Strategy: Multiply the dividend by the reciprocal of the divisor. The - * inexact result is fixed by a small loop, using at most one iteration. - * - * ACL2 proofs: - * ------------ - * 1) q is a natural number. (ndivmod-quotient-natp) - * 2) r is a natural number. (ndivmod-remainder-natp) - * 3) a = q * b + r (ndivmod-q*b+r==a) - * 4) r < b (ndivmod-remainder-<-b) - */ -static void -_mpd_base_ndivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, - uint32_t *status) -{ - mpd_context_t workctx; - mpd_t *qq = q, *rr = r; - mpd_t aa, bb; - int k; - - _mpd_copy_shared(&aa, a); - _mpd_copy_shared(&bb, b); - - mpd_set_positive(&aa); - mpd_set_positive(&bb); - aa.exp = 0; - bb.exp = 0; - - if (q == a || q == b) { - if ((qq = mpd_qnew()) == NULL) { - *status |= MPD_Malloc_error; - goto nanresult; - } - } - if (r == a || r == b) { - if ((rr = mpd_qnew()) == NULL) { - *status |= MPD_Malloc_error; - goto nanresult; - } - } - - mpd_maxcontext(&workctx); - - /* Let prec := adigits - bdigits + 4 */ - workctx.prec = a->digits - b->digits + 1 + 3; - if (a->digits > MPD_MAX_PREC || workctx.prec > MPD_MAX_PREC) { - *status |= MPD_Division_impossible; - goto nanresult; - } - - /* Let x := _mpd_qreciprocal(b, prec) - * Then x is bounded by: - * 1) 1/b - 10**(-prec - bdigits) < x < 1/b + 10**(-prec - bdigits) - * 2) 1/b - 10**(-adigits - 4) < x < 1/b + 10**(-adigits - 4) - */ - _mpd_qreciprocal(rr, &bb, &workctx, &workctx.status); - - /* Get an estimate for the quotient. Let q := a * x - * Then q is bounded by: - * 3) a/b - 10**-4 < q < a/b + 10**-4 - */ - _mpd_qmul(qq, &aa, rr, &workctx, &workctx.status); - /* Truncate q to an integer: - * 4) a/b - 2 < trunc(q) < a/b + 1 - */ - mpd_qtrunc(qq, qq, &workctx, &workctx.status); - - workctx.prec = aa.digits + 3; - workctx.emax = MPD_MAX_EMAX + 3; - workctx.emin = MPD_MIN_EMIN - 3; - /* Multiply the estimate for q by b: - * 5) a - 2 * b < trunc(q) * b < a + b - */ - _mpd_qmul(rr, &bb, qq, &workctx, &workctx.status); - /* Get the estimate for r such that a = q * b + r. */ - _mpd_qsub_exact(rr, &aa, rr, &workctx, &workctx.status); - - /* Fix the result. At this point -b < r < 2*b, so the correction loop - takes at most one iteration. */ - for (k = 0;; k++) { - if (mpd_isspecial(qq) || mpd_isspecial(rr)) { - *status |= (workctx.status&MPD_Errors); - goto nanresult; - } - if (k > 2) { /* Allow two iterations despite the proof. */ - mpd_err_warn("libmpdec: internal error in " /* GCOV_NOT_REACHED */ - "_mpd_base_ndivmod: please report"); /* GCOV_NOT_REACHED */ - *status |= MPD_Invalid_operation; /* GCOV_NOT_REACHED */ - goto nanresult; /* GCOV_NOT_REACHED */ - } - /* r < 0 */ - else if (_mpd_cmp(&zero, rr) == 1) { - _mpd_qadd_exact(rr, rr, &bb, &workctx, &workctx.status); - _mpd_qadd_exact(qq, qq, &minus_one, &workctx, &workctx.status); - } - /* 0 <= r < b */ - else if (_mpd_cmp(rr, &bb) == -1) { - break; - } - /* r >= b */ - else { - _mpd_qsub_exact(rr, rr, &bb, &workctx, &workctx.status); - _mpd_qadd_exact(qq, qq, &one, &workctx, &workctx.status); - } - } - - if (qq != q) { - if (!mpd_qcopy(q, qq, status)) { - goto nanresult; /* GCOV_UNLIKELY */ - } - mpd_del(qq); - } - if (rr != r) { - if (!mpd_qcopy(r, rr, status)) { - goto nanresult; /* GCOV_UNLIKELY */ - } - mpd_del(rr); - } - - *status |= (workctx.status&MPD_Errors); - return; - - -nanresult: - if (qq && qq != q) mpd_del(qq); - if (rr && rr != r) mpd_del(rr); - mpd_setspecial(q, MPD_POS, MPD_NAN); - mpd_setspecial(r, MPD_POS, MPD_NAN); -} - -/* LIBMPDEC_ONLY */ -/* - * Schedule the optimal precision increase for the Newton iteration. - * v := input operand - * z_0 := initial approximation - * initprec := natural number such that abs(sqrt(v) - z_0) < 10**-initprec - * maxprec := target precision - * - * For convenience the output klist contains the elements in reverse order: - * klist := [k_n-1, ..., k_0], where - * 1) k_0 <= initprec and - * 2) abs(sqrt(v) - result) < 10**(-2*k_n-1 + 2) <= 10**-maxprec. - */ -static inline int -invroot_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], - mpd_ssize_t maxprec, mpd_ssize_t initprec) -{ - mpd_ssize_t k; - int i; - - assert(maxprec >= 3 && initprec >= 3); - if (maxprec <= initprec) return -1; - - i = 0; k = maxprec; - do { - k = (k+3) / 2; - klist[i++] = k; - } while (k > initprec); - - return i-1; -} - -/* - * Initial approximation for the inverse square root function. - * Input: - * v := rational number, with 1 <= v < 100 - * vhat := floor(v * 10**6) - * Output: - * z := approximation to 1/sqrt(v), such that abs(z - 1/sqrt(v)) < 10**-3. - */ -static inline void -_invroot_init_approx(mpd_t *z, mpd_uint_t vhat) -{ - mpd_uint_t lo = 1000; - mpd_uint_t hi = 10000; - mpd_uint_t a, sq; - - assert(lo*lo <= vhat && vhat < (hi+1)*(hi+1)); - - for(;;) { - a = (lo + hi) / 2; - sq = a * a; - if (vhat >= sq) { - if (vhat < sq + 2*a + 1) { - break; - } - lo = a + 1; - } - else { - hi = a - 1; - } - } - - /* - * After the binary search we have: - * 1) a**2 <= floor(v * 10**6) < (a + 1)**2 - * This implies: - * 2) a**2 <= v * 10**6 < (a + 1)**2 - * 3) a <= sqrt(v) * 10**3 < a + 1 - * Since 10**3 <= a: - * 4) 0 <= 10**prec/a - 1/sqrt(v) < 10**-prec - * We have: - * 5) 10**3/a - 10**-3 < floor(10**9/a) * 10**-6 <= 10**3/a - * Merging 4) and 5): - * 6) abs(floor(10**9/a) * 10**-6 - 1/sqrt(v)) < 10**-3 - */ - mpd_minalloc(z); - mpd_clear_flags(z); - z->data[0] = 1000000000UL / a; - z->len = 1; - z->exp = -6; - mpd_setdigits(z); -} - -/* - * Set 'result' to 1/sqrt(a). - * Relative error: abs(result - 1/sqrt(a)) < 10**-prec * 1/sqrt(a) - */ -static void -_mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - uint32_t workstatus = 0; - mpd_context_t varcontext, maxcontext; - mpd_t *z = result; /* current approximation */ - mpd_t *v; /* a, normalized to a number between 1 and 100 */ - MPD_NEW_SHARED(vtmp, a); /* by default v will share data with a */ - MPD_NEW_STATIC(s,0,0,0,0); /* temporary variable */ - MPD_NEW_STATIC(t,0,0,0,0); /* temporary variable */ - MPD_NEW_CONST(one_half,0,-1,1,1,1,5); - MPD_NEW_CONST(three,0,0,1,1,1,3); - mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; - mpd_ssize_t ideal_exp, shift; - mpd_ssize_t adj, tz; - mpd_ssize_t maxprec, fracdigits; - mpd_uint_t vhat, dummy; - int i, n; - - - ideal_exp = -(a->exp - (a->exp & 1)) / 2; - - v = &vtmp; - if (result == a) { - if ((v = mpd_qncopy(a)) == NULL) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - } - - /* normalize a to 1 <= v < 100 */ - if ((v->digits+v->exp) & 1) { - fracdigits = v->digits - 1; - v->exp = -fracdigits; - n = (v->digits > 7) ? 7 : (int)v->digits; - /* Let vhat := floor(v * 10**(2*initprec)) */ - _mpd_get_msdigits(&dummy, &vhat, v, n); - if (n < 7) { - vhat *= mpd_pow10[7-n]; - } - } - else { - fracdigits = v->digits - 2; - v->exp = -fracdigits; - n = (v->digits > 8) ? 8 : (int)v->digits; - /* Let vhat := floor(v * 10**(2*initprec)) */ - _mpd_get_msdigits(&dummy, &vhat, v, n); - if (n < 8) { - vhat *= mpd_pow10[8-n]; - } - } - adj = (a->exp-v->exp) / 2; - - /* initial approximation */ - _invroot_init_approx(z, vhat); - - mpd_maxcontext(&maxcontext); - mpd_maxcontext(&varcontext); - varcontext.round = MPD_ROUND_TRUNC; - maxprec = ctx->prec + 1; - - /* initprec == 3 */ - i = invroot_schedule_prec(klist, maxprec, 3); - for (; i >= 0; i--) { - varcontext.prec = 2*klist[i]+2; - mpd_qmul(&s, z, z, &maxcontext, &workstatus); - if (v->digits > varcontext.prec) { - shift = v->digits - varcontext.prec; - mpd_qshiftr(&t, v, shift, &workstatus); - t.exp += shift; - mpd_qmul(&t, &t, &s, &varcontext, &workstatus); - } - else { - mpd_qmul(&t, v, &s, &varcontext, &workstatus); - } - mpd_qsub(&t, &three, &t, &maxcontext, &workstatus); - mpd_qmul(z, z, &t, &varcontext, &workstatus); - mpd_qmul(z, z, &one_half, &maxcontext, &workstatus); - } - - z->exp -= adj; - - tz = mpd_trail_zeros(result); - shift = ideal_exp - result->exp; - shift = (tz > shift) ? shift : tz; - if (shift > 0) { - mpd_qshiftr_inplace(result, shift); - result->exp += shift; - } + mpd_copy_flags(result, a); + result->exp = a->exp; + result->digits = a->digits; + result->len = a->len; + memcpy(result->data, a->data, a->len * (sizeof *result->data)); - mpd_del(&s); - mpd_del(&t); - if (v != &vtmp) mpd_del(v); - *status |= (workstatus&MPD_Errors); - *status |= (MPD_Rounded|MPD_Inexact); + return 1; } -void -mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t workctx; +/* + * Copy to a decimal with a static buffer. The caller has to make sure that + * the buffer is big enough. Cannot fail. + */ +static void +mpd_qcopy_static(mpd_t *result, const mpd_t *a) +{ + if (result == a) return; + + memcpy(result->data, a->data, a->len * (sizeof *result->data)); + + mpd_copy_flags(result, a); + result->exp = a->exp; + result->digits = a->digits; + result->len = a->len; +} + +/* + * Return a newly allocated copy of the operand. In case of an error, + * status is set to MPD_Malloc_error and the return value is NULL. + */ +mpd_t * +mpd_qncopy(const mpd_t *a) +{ + mpd_t *result; + + if ((result = mpd_qnew_size(a->len)) == NULL) { + return NULL; + } + memcpy(result->data, a->data, a->len * (sizeof *result->data)); + mpd_copy_flags(result, a); + result->exp = a->exp; + result->digits = a->digits; + result->len = a->len; + + return result; +} + +/* + * Copy a decimal and set the sign to positive. In case of an error, the + * status is set to MPD_Malloc_error. + */ +int +mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status) +{ + if (!mpd_qcopy(result, a, status)) { + return 0; + } + mpd_set_positive(result); + return 1; +} + +/* + * Copy a decimal and negate the sign. In case of an error, the + * status is set to MPD_Malloc_error. + */ +int +mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status) +{ + if (!mpd_qcopy(result, a, status)) { + return 0; + } + _mpd_negate(result); + return 1; +} + +/* + * Copy a decimal, setting the sign of the first operand to the sign of the + * second operand. In case of an error, the status is set to MPD_Malloc_error. + */ +int +mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status) +{ + uint8_t sign_b = mpd_sign(b); /* result may equal b! */ + + if (!mpd_qcopy(result, a, status)) { + return 0; + } + mpd_set_sign(result, sign_b); + return 1; +} + + +/******************************************************************************/ +/* Comparisons */ +/******************************************************************************/ + +/* + * For all functions that compare two operands and return an int the usual + * convention applies to the return value: + * + * -1 if op1 < op2 + * 0 if op1 == op2 + * 1 if op1 > op2 + * + * INT_MAX for error + */ + + +/* Convenience macro. If a and b are not equal, return from the calling + * function with the correct comparison value. */ +#define CMP_EQUAL_OR_RETURN(a, b) \ + if (a != b) { \ + if (a < b) { \ + return -1; \ + } \ + return 1; \ + } + +/* + * Compare the data of big and small. This function does the equivalent + * of first shifting small to the left and then comparing the data of + * big and small, except that no allocation for the left shift is needed. + */ +static int +_mpd_basecmp(mpd_uint_t *big, mpd_uint_t *small, mpd_size_t n, mpd_size_t m, + mpd_size_t shift) +{ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) + /* spurious uninitialized warnings */ + mpd_uint_t l=l, lprev=lprev, h=h; +#else + mpd_uint_t l, lprev, h; +#endif + mpd_uint_t q, r; + mpd_uint_t ph, x; + + assert(m > 0 && n >= m && shift > 0); + + _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS); + + if (r != 0) { + + ph = mpd_pow10[r]; + + --m; --n; + _mpd_divmod_pow10(&h, &lprev, small[m--], MPD_RDIGITS-r); + if (h != 0) { + CMP_EQUAL_OR_RETURN(big[n], h) + --n; + } + for (; m != MPD_SIZE_MAX; m--,n--) { + _mpd_divmod_pow10(&h, &l, small[m], MPD_RDIGITS-r); + x = ph * lprev + h; + CMP_EQUAL_OR_RETURN(big[n], x) + lprev = l; + } + x = ph * lprev; + CMP_EQUAL_OR_RETURN(big[q], x) + } + else { + while (--m != MPD_SIZE_MAX) { + CMP_EQUAL_OR_RETURN(big[m+q], small[m]) + } + } + + return !_mpd_isallzero(big, q); +} + +/* Compare two decimals with the same adjusted exponent. */ +static int +_mpd_cmp_same_adjexp(const mpd_t *a, const mpd_t *b) +{ + mpd_ssize_t shift, i; + + if (a->exp != b->exp) { + /* Cannot wrap: a->exp + a->digits = b->exp + b->digits, so + * a->exp - b->exp = b->digits - a->digits. */ + shift = a->exp - b->exp; + if (shift > 0) { + return -1 * _mpd_basecmp(b->data, a->data, b->len, a->len, shift); + } + else { + return _mpd_basecmp(a->data, b->data, a->len, b->len, -shift); + } + } + + /* + * At this point adjexp(a) == adjexp(b) and a->exp == b->exp, + * so a->digits == b->digits, therefore a->len == b->len. + */ + for (i = a->len-1; i >= 0; --i) { + CMP_EQUAL_OR_RETURN(a->data[i], b->data[i]) + } + + return 0; +} + +/* Compare two numerical values. */ +static int +_mpd_cmp(const mpd_t *a, const mpd_t *b) +{ + mpd_ssize_t adjexp_a, adjexp_b; + + /* equal pointers */ + if (a == b) { + return 0; + } + + /* infinities */ + if (mpd_isinfinite(a)) { + if (mpd_isinfinite(b)) { + return mpd_isnegative(b) - mpd_isnegative(a); + } + return mpd_arith_sign(a); + } + if (mpd_isinfinite(b)) { + return -mpd_arith_sign(b); + } + + /* zeros */ + if (mpd_iszerocoeff(a)) { + if (mpd_iszerocoeff(b)) { + return 0; + } + return -mpd_arith_sign(b); + } + if (mpd_iszerocoeff(b)) { + return mpd_arith_sign(a); + } + + /* different signs */ + if (mpd_sign(a) != mpd_sign(b)) { + return mpd_sign(b) - mpd_sign(a); + } + + /* different adjusted exponents */ + adjexp_a = mpd_adjexp(a); + adjexp_b = mpd_adjexp(b); + if (adjexp_a != adjexp_b) { + if (adjexp_a < adjexp_b) { + return -1 * mpd_arith_sign(a); + } + return mpd_arith_sign(a); + } + + /* same adjusted exponents */ + return _mpd_cmp_same_adjexp(a, b) * mpd_arith_sign(a); +} + +/* Compare the absolutes of two numerical values. */ +static int +_mpd_cmp_abs(const mpd_t *a, const mpd_t *b) +{ + mpd_ssize_t adjexp_a, adjexp_b; + + /* equal pointers */ + if (a == b) { + return 0; + } + + /* infinities */ + if (mpd_isinfinite(a)) { + if (mpd_isinfinite(b)) { + return 0; + } + return 1; + } + if (mpd_isinfinite(b)) { + return -1; + } + + /* zeros */ + if (mpd_iszerocoeff(a)) { + if (mpd_iszerocoeff(b)) { + return 0; + } + return -1; + } + if (mpd_iszerocoeff(b)) { + return 1; + } + + /* different adjusted exponents */ + adjexp_a = mpd_adjexp(a); + adjexp_b = mpd_adjexp(b); + if (adjexp_a != adjexp_b) { + if (adjexp_a < adjexp_b) { + return -1; + } + return 1; + } + + /* same adjusted exponents */ + return _mpd_cmp_same_adjexp(a, b); +} + +/* Compare two values and return an integer result. */ +int +mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status) +{ + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_isnan(a) || mpd_isnan(b)) { + *status |= MPD_Invalid_operation; + return INT_MAX; + } + } + + return _mpd_cmp(a, b); +} + +/* + * Compare a and b, convert the usual integer result to a decimal and + * store it in 'result'. For convenience, the integer result of the comparison + * is returned. Comparisons involving NaNs return NaN/INT_MAX. + */ +int +mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + int c; + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return INT_MAX; + } + } + + c = _mpd_cmp(a, b); + _settriple(result, (c < 0), (c != 0), 0); + return c; +} + +/* Same as mpd_compare(), but signal for all NaNs, i.e. also for quiet NaNs. */ +int +mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + int c; + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + *status |= MPD_Invalid_operation; + return INT_MAX; + } + } + + c = _mpd_cmp(a, b); + _settriple(result, (c < 0), (c != 0), 0); + return c; +} + +/* Compare the operands using a total order. */ +int +mpd_cmp_total(const mpd_t *a, const mpd_t *b) +{ + mpd_t aa, bb; + int nan_a, nan_b; + int c; + + if (mpd_sign(a) != mpd_sign(b)) { + return mpd_sign(b) - mpd_sign(a); + } + + + if (mpd_isnan(a)) { + c = 1; + if (mpd_isnan(b)) { + nan_a = (mpd_isqnan(a)) ? 1 : 0; + nan_b = (mpd_isqnan(b)) ? 1 : 0; + if (nan_b == nan_a) { + if (a->len > 0 && b->len > 0) { + _mpd_copy_shared(&aa, a); + _mpd_copy_shared(&bb, b); + aa.exp = bb.exp = 0; + /* compare payload */ + c = _mpd_cmp_abs(&aa, &bb); + } + else { + c = (a->len > 0) - (b->len > 0); + } + } + else { + c = nan_a - nan_b; + } + } + } + else if (mpd_isnan(b)) { + c = -1; + } + else { + c = _mpd_cmp_abs(a, b); + if (c == 0 && a->exp != b->exp) { + c = (a->exp < b->exp) ? -1 : 1; + } + } + + return c * mpd_arith_sign(a); +} + +/* + * Compare a and b according to a total order, convert the usual integer result + * to a decimal and store it in 'result'. For convenience, the integer result + * of the comparison is returned. + */ +int +mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b) +{ + int c; + + c = mpd_cmp_total(a, b); + _settriple(result, (c < 0), (c != 0), 0); + return c; +} + +/* Compare the magnitude of the operands using a total order. */ +int +mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b) +{ + mpd_t aa, bb; + + _mpd_copy_shared(&aa, a); + _mpd_copy_shared(&bb, b); + + mpd_set_positive(&aa); + mpd_set_positive(&bb); + + return mpd_cmp_total(&aa, &bb); +} + +/* + * Compare the magnitude of a and b according to a total order, convert the + * the usual integer result to a decimal and store it in 'result'. + * For convenience, the integer result of the comparison is returned. + */ +int +mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b) +{ + int c; + + c = mpd_cmp_total_mag(a, b); + _settriple(result, (c < 0), (c != 0), 0); + return c; +} + +/* Determine an ordering for operands that are numerically equal. */ +static inline int +_mpd_cmp_numequal(const mpd_t *a, const mpd_t *b) +{ + int sign_a, sign_b; + int c; + + sign_a = mpd_sign(a); + sign_b = mpd_sign(b); + if (sign_a != sign_b) { + c = sign_b - sign_a; + } + else { + c = (a->exp < b->exp) ? -1 : 1; + c *= mpd_arith_sign(a); + } + + return c; +} + + +/******************************************************************************/ +/* Shifting the coefficient */ +/******************************************************************************/ + +/* + * Shift the coefficient of the operand to the left, no check for specials. + * Both operands may be the same pointer. If the result length has to be + * increased, mpd_qresize() might fail with MPD_Malloc_error. + */ +int +mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status) +{ + mpd_ssize_t size; + + assert(!mpd_isspecial(a)); + assert(n >= 0); + + if (mpd_iszerocoeff(a) || n == 0) { + return mpd_qcopy(result, a, status); + } + + size = mpd_digits_to_size(a->digits+n); + if (!mpd_qresize(result, size, status)) { + return 0; /* result is NaN */ + } + + _mpd_baseshiftl(result->data, a->data, size, a->len, n); + + mpd_copy_flags(result, a); + result->exp = a->exp; + result->digits = a->digits+n; + result->len = size; + + return 1; +} + +/* Determine the rounding indicator if all digits of the coefficient are shifted + * out of the picture. */ +static mpd_uint_t +_mpd_get_rnd(const mpd_uint_t *data, mpd_ssize_t len, int use_msd) +{ + mpd_uint_t rnd = 0, rest = 0, word; + + word = data[len-1]; + /* special treatment for the most significant digit if shift == digits */ + if (use_msd) { + _mpd_divmod_pow10(&rnd, &rest, word, mpd_word_digits(word)-1); + if (len > 1 && rest == 0) { + rest = !_mpd_isallzero(data, len-1); + } + } + else { + rest = !_mpd_isallzero(data, len); + } + + return (rnd == 0 || rnd == 5) ? rnd + !!rest : rnd; +} + +/* + * Same as mpd_qshiftr(), but 'result' is an mpd_t with a static coefficient. + * It is the caller's responsibility to ensure that the coefficient is big + * enough. The function cannot fail. + */ +static mpd_uint_t +mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n) +{ + mpd_uint_t rnd; + mpd_ssize_t size; + + assert(!mpd_isspecial(a)); + assert(n >= 0); + + if (mpd_iszerocoeff(a) || n == 0) { + mpd_qcopy_static(result, a); + return 0; + } + + if (n >= a->digits) { + rnd = _mpd_get_rnd(a->data, a->len, (n==a->digits)); + mpd_zerocoeff(result); + } + else { + result->digits = a->digits-n; + size = mpd_digits_to_size(result->digits); + rnd = _mpd_baseshiftr(result->data, a->data, a->len, n); + result->len = size; + } + + mpd_copy_flags(result, a); + result->exp = a->exp; + + return rnd; +} + +/* + * Inplace shift of the coefficient to the right, no check for specials. + * Returns the rounding indicator for mpd_rnd_incr(). + * The function cannot fail. + */ +mpd_uint_t +mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n) +{ + uint32_t dummy; + mpd_uint_t rnd; + mpd_ssize_t size; + + assert(!mpd_isspecial(result)); + assert(n >= 0); + + if (mpd_iszerocoeff(result) || n == 0) { + return 0; + } + + if (n >= result->digits) { + rnd = _mpd_get_rnd(result->data, result->len, (n==result->digits)); + mpd_zerocoeff(result); + } + else { + rnd = _mpd_baseshiftr(result->data, result->data, result->len, n); + result->digits -= n; + size = mpd_digits_to_size(result->digits); + /* reducing the size cannot fail */ + mpd_qresize(result, size, &dummy); + result->len = size; + } + + return rnd; +} + +/* + * Shift the coefficient of the operand to the right, no check for specials. + * Both operands may be the same pointer. Returns the rounding indicator to + * be used by mpd_rnd_incr(). If the result length has to be increased, + * mpd_qcopy() or mpd_qresize() might fail with MPD_Malloc_error. In those + * cases, MPD_UINT_MAX is returned. + */ +mpd_uint_t +mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status) +{ + mpd_uint_t rnd; + mpd_ssize_t size; + + assert(!mpd_isspecial(a)); + assert(n >= 0); + + if (mpd_iszerocoeff(a) || n == 0) { + if (!mpd_qcopy(result, a, status)) { + return MPD_UINT_MAX; + } + return 0; + } + + if (n >= a->digits) { + rnd = _mpd_get_rnd(a->data, a->len, (n==a->digits)); + mpd_zerocoeff(result); + } + else { + result->digits = a->digits-n; + size = mpd_digits_to_size(result->digits); + if (result == a) { + rnd = _mpd_baseshiftr(result->data, a->data, a->len, n); + /* reducing the size cannot fail */ + mpd_qresize(result, size, status); + } + else { + if (!mpd_qresize(result, size, status)) { + return MPD_UINT_MAX; + } + rnd = _mpd_baseshiftr(result->data, a->data, a->len, n); + } + result->len = size; + } + + mpd_copy_flags(result, a); + result->exp = a->exp; + + return rnd; +} + + +/******************************************************************************/ +/* Miscellaneous operations */ +/******************************************************************************/ + +/* Logical And */ +void +mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + const mpd_t *big = a, *small = b; + mpd_uint_t x, y, z, xbit, ybit; + int k, mswdigits; + mpd_ssize_t i; + + if (mpd_isspecial(a) || mpd_isspecial(b) || + mpd_isnegative(a) || mpd_isnegative(b) || + a->exp != 0 || b->exp != 0) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (b->digits > a->digits) { + big = b; + small = a; + } + if (!mpd_qresize(result, big->len, status)) { + return; + } + + + /* full words */ + for (i = 0; i < small->len-1; i++) { + x = small->data[i]; + y = big->data[i]; + z = 0; + for (k = 0; k < MPD_RDIGITS; k++) { + xbit = x % 10; + x /= 10; + ybit = y % 10; + y /= 10; + if (xbit > 1 || ybit > 1) { + goto invalid_operation; + } + z += (xbit&ybit) ? mpd_pow10[k] : 0; + } + result->data[i] = z; + } + /* most significant word of small */ + x = small->data[i]; + y = big->data[i]; + z = 0; + mswdigits = mpd_word_digits(x); + for (k = 0; k < mswdigits; k++) { + xbit = x % 10; + x /= 10; + ybit = y % 10; + y /= 10; + if (xbit > 1 || ybit > 1) { + goto invalid_operation; + } + z += (xbit&ybit) ? mpd_pow10[k] : 0; + } + result->data[i++] = z; + + /* scan the rest of y for digits > 1 */ + for (; k < MPD_RDIGITS; k++) { + ybit = y % 10; + y /= 10; + if (ybit > 1) { + goto invalid_operation; + } + } + /* scan the rest of big for digits > 1 */ + for (; i < big->len; i++) { + y = big->data[i]; + for (k = 0; k < MPD_RDIGITS; k++) { + ybit = y % 10; + y /= 10; + if (ybit > 1) { + goto invalid_operation; + } + } + } + + mpd_clear_flags(result); + result->exp = 0; + result->len = _mpd_real_size(result->data, small->len); + mpd_qresize(result, result->len, status); + mpd_setdigits(result); + _mpd_cap(result, ctx); + return; + +invalid_operation: + mpd_seterror(result, MPD_Invalid_operation, status); +} + +/* Class of an operand. Returns a pointer to the constant name. */ +const char * +mpd_class(const mpd_t *a, const mpd_context_t *ctx) +{ + if (mpd_isnan(a)) { + if (mpd_isqnan(a)) + return "NaN"; + else + return "sNaN"; + } + else if (mpd_ispositive(a)) { + if (mpd_isinfinite(a)) + return "+Infinity"; + else if (mpd_iszero(a)) + return "+Zero"; + else if (mpd_isnormal(a, ctx)) + return "+Normal"; + else + return "+Subnormal"; + } + else { + if (mpd_isinfinite(a)) + return "-Infinity"; + else if (mpd_iszero(a)) + return "-Zero"; + else if (mpd_isnormal(a, ctx)) + return "-Normal"; + else + return "-Subnormal"; + } +} + +/* Logical Xor */ +void +mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_uint_t x, z, xbit; + mpd_ssize_t i, digits, len; + mpd_ssize_t q, r; + int k; + + if (mpd_isspecial(a) || mpd_isnegative(a) || a->exp != 0) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + digits = (a->digits < ctx->prec) ? ctx->prec : a->digits; + _mpd_idiv_word(&q, &r, digits, MPD_RDIGITS); + len = (r == 0) ? q : q+1; + if (!mpd_qresize(result, len, status)) { + return; + } + + for (i = 0; i < len; i++) { + x = (i < a->len) ? a->data[i] : 0; + z = 0; + for (k = 0; k < MPD_RDIGITS; k++) { + xbit = x % 10; + x /= 10; + if (xbit > 1) { + goto invalid_operation; + } + z += !xbit ? mpd_pow10[k] : 0; + } + result->data[i] = z; + } + + mpd_clear_flags(result); + result->exp = 0; + result->len = _mpd_real_size(result->data, len); + mpd_qresize(result, result->len, status); + mpd_setdigits(result); + _mpd_cap(result, ctx); + return; + +invalid_operation: + mpd_seterror(result, MPD_Invalid_operation, status); +} + +/* Exponent of the magnitude of the most significant digit of the operand. */ +void +mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + mpd_setspecial(result, MPD_POS, MPD_INF); + } + else if (mpd_iszerocoeff(a)) { + mpd_setspecial(result, MPD_NEG, MPD_INF); + *status |= MPD_Division_by_zero; + } + else { + mpd_qset_ssize(result, mpd_adjexp(a), ctx, status); + } +} + +/* Logical Or */ +void +mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + const mpd_t *big = a, *small = b; + mpd_uint_t x, y, z, xbit, ybit; + int k, mswdigits; + mpd_ssize_t i; + + if (mpd_isspecial(a) || mpd_isspecial(b) || + mpd_isnegative(a) || mpd_isnegative(b) || + a->exp != 0 || b->exp != 0) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (b->digits > a->digits) { + big = b; + small = a; + } + if (!mpd_qresize(result, big->len, status)) { + return; + } + + + /* full words */ + for (i = 0; i < small->len-1; i++) { + x = small->data[i]; + y = big->data[i]; + z = 0; + for (k = 0; k < MPD_RDIGITS; k++) { + xbit = x % 10; + x /= 10; + ybit = y % 10; + y /= 10; + if (xbit > 1 || ybit > 1) { + goto invalid_operation; + } + z += (xbit|ybit) ? mpd_pow10[k] : 0; + } + result->data[i] = z; + } + /* most significant word of small */ + x = small->data[i]; + y = big->data[i]; + z = 0; + mswdigits = mpd_word_digits(x); + for (k = 0; k < mswdigits; k++) { + xbit = x % 10; + x /= 10; + ybit = y % 10; + y /= 10; + if (xbit > 1 || ybit > 1) { + goto invalid_operation; + } + z += (xbit|ybit) ? mpd_pow10[k] : 0; + } + + /* scan for digits > 1 and copy the rest of y */ + for (; k < MPD_RDIGITS; k++) { + ybit = y % 10; + y /= 10; + if (ybit > 1) { + goto invalid_operation; + } + z += ybit*mpd_pow10[k]; + } + result->data[i++] = z; + /* scan for digits > 1 and copy the rest of big */ + for (; i < big->len; i++) { + y = big->data[i]; + for (k = 0; k < MPD_RDIGITS; k++) { + ybit = y % 10; + y /= 10; + if (ybit > 1) { + goto invalid_operation; + } + } + result->data[i] = big->data[i]; + } + + mpd_clear_flags(result); + result->exp = 0; + result->len = _mpd_real_size(result->data, big->len); + mpd_qresize(result, result->len, status); + mpd_setdigits(result); + _mpd_cap(result, ctx); + return; + +invalid_operation: + mpd_seterror(result, MPD_Invalid_operation, status); +} + +/* + * Rotate the coefficient of 'a' by 'b' digits. 'b' must be an integer with + * exponent 0. + */ +void +mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + MPD_NEW_STATIC(tmp,0,0,0,0); + MPD_NEW_STATIC(big,0,0,0,0); + MPD_NEW_STATIC(small,0,0,0,0); + mpd_ssize_t n, lshift, rshift; + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + } + if (b->exp != 0 || mpd_isinfinite(b)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + n = mpd_qget_ssize(b, &workstatus); + if (workstatus&MPD_Invalid_operation) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (n > ctx->prec || n < -ctx->prec) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (mpd_isinfinite(a)) { + mpd_qcopy(result, a, status); + return; + } + + if (n >= 0) { + lshift = n; + rshift = ctx->prec-n; + } + else { + lshift = ctx->prec+n; + rshift = -n; + } + + if (a->digits > ctx->prec) { + if (!mpd_qcopy(&tmp, a, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + goto finish; + } + _mpd_cap(&tmp, ctx); + a = &tmp; + } + + if (!mpd_qshiftl(&big, a, lshift, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + goto finish; + } + _mpd_cap(&big, ctx); + + if (mpd_qshiftr(&small, a, rshift, status) == MPD_UINT_MAX) { + mpd_seterror(result, MPD_Malloc_error, status); + goto finish; + } + _mpd_qadd(result, &big, &small, ctx, status); + + +finish: + mpd_del(&tmp); + mpd_del(&big); + mpd_del(&small); +} + +/* + * b must be an integer with exponent 0 and in the range +-2*(emax + prec). + * XXX: In my opinion +-(2*emax + prec) would be more sensible. + * The result is a with the value of b added to its exponent. + */ +void +mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_uint_t n, maxjump; +#ifndef LEGACY_COMPILER + int64_t exp; +#else + mpd_uint_t x; + int x_sign, n_sign; + mpd_ssize_t exp; +#endif + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + } + if (b->exp != 0 || mpd_isinfinite(b)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + n = mpd_qabs_uint(b, &workstatus); + /* the spec demands this */ + maxjump = 2 * (mpd_uint_t)(ctx->emax + ctx->prec); + + if (n > maxjump || workstatus&MPD_Invalid_operation) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (mpd_isinfinite(a)) { + mpd_qcopy(result, a, status); + return; + } + +#ifndef LEGACY_COMPILER + exp = a->exp + (int64_t)n * mpd_arith_sign(b); + exp = (exp > MPD_EXP_INF) ? MPD_EXP_INF : exp; + exp = (exp < MPD_EXP_CLAMP) ? MPD_EXP_CLAMP : exp; +#else + x = (a->exp < 0) ? -a->exp : a->exp; + x_sign = (a->exp < 0) ? 1 : 0; + n_sign = mpd_isnegative(b) ? 1 : 0; + + if (x_sign == n_sign) { + x = x + n; + if (x < n) x = MPD_UINT_MAX; + } + else { + x_sign = (x >= n) ? x_sign : n_sign; + x = (x >= n) ? x - n : n - x; + } + if (!x_sign && x > MPD_EXP_INF) x = MPD_EXP_INF; + if (x_sign && x > -MPD_EXP_CLAMP) x = -MPD_EXP_CLAMP; + exp = x_sign ? -((mpd_ssize_t)x) : (mpd_ssize_t)x; +#endif + + mpd_qcopy(result, a, status); + result->exp = (mpd_ssize_t)exp; + + mpd_qfinalize(result, ctx, status); +} + +/* + * Shift the coefficient by n digits, positive n is a left shift. In the case + * of a left shift, the result is decapitated to fit the context precision. If + * you don't want that, use mpd_shiftl(). + */ +void +mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx, + uint32_t *status) +{ + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + mpd_qcopy(result, a, status); + return; + } + + if (n >= 0 && n <= ctx->prec) { + mpd_qshiftl(result, a, n, status); + _mpd_cap(result, ctx); + } + else if (n < 0 && n >= -ctx->prec) { + if (!mpd_qcopy(result, a, status)) { + return; + } + _mpd_cap(result, ctx); + mpd_qshiftr_inplace(result, -n); + } + else { + mpd_seterror(result, MPD_Invalid_operation, status); + } +} + +/* + * Same as mpd_shiftn(), but the shift is specified by the decimal b, which + * must be an integer with a zero exponent. Infinities remain infinities. + */ +void +mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, + uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_ssize_t n; + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + } + if (b->exp != 0 || mpd_isinfinite(b)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + n = mpd_qget_ssize(b, &workstatus); + if (workstatus&MPD_Invalid_operation) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (n > ctx->prec || n < -ctx->prec) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (mpd_isinfinite(a)) { + mpd_qcopy(result, a, status); + return; + } + + if (n >= 0) { + mpd_qshiftl(result, a, n, status); + _mpd_cap(result, ctx); + } + else { + if (!mpd_qcopy(result, a, status)) { + return; + } + _mpd_cap(result, ctx); + mpd_qshiftr_inplace(result, -n); + } +} + +/* Logical Xor */ +void +mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + const mpd_t *big = a, *small = b; + mpd_uint_t x, y, z, xbit, ybit; + int k, mswdigits; + mpd_ssize_t i; + + if (mpd_isspecial(a) || mpd_isspecial(b) || + mpd_isnegative(a) || mpd_isnegative(b) || + a->exp != 0 || b->exp != 0) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (b->digits > a->digits) { + big = b; + small = a; + } + if (!mpd_qresize(result, big->len, status)) { + return; + } + + + /* full words */ + for (i = 0; i < small->len-1; i++) { + x = small->data[i]; + y = big->data[i]; + z = 0; + for (k = 0; k < MPD_RDIGITS; k++) { + xbit = x % 10; + x /= 10; + ybit = y % 10; + y /= 10; + if (xbit > 1 || ybit > 1) { + goto invalid_operation; + } + z += (xbit^ybit) ? mpd_pow10[k] : 0; + } + result->data[i] = z; + } + /* most significant word of small */ + x = small->data[i]; + y = big->data[i]; + z = 0; + mswdigits = mpd_word_digits(x); + for (k = 0; k < mswdigits; k++) { + xbit = x % 10; + x /= 10; + ybit = y % 10; + y /= 10; + if (xbit > 1 || ybit > 1) { + goto invalid_operation; + } + z += (xbit^ybit) ? mpd_pow10[k] : 0; + } + + /* scan for digits > 1 and copy the rest of y */ + for (; k < MPD_RDIGITS; k++) { + ybit = y % 10; + y /= 10; + if (ybit > 1) { + goto invalid_operation; + } + z += ybit*mpd_pow10[k]; + } + result->data[i++] = z; + /* scan for digits > 1 and copy the rest of big */ + for (; i < big->len; i++) { + y = big->data[i]; + for (k = 0; k < MPD_RDIGITS; k++) { + ybit = y % 10; + y /= 10; + if (ybit > 1) { + goto invalid_operation; + } + } + result->data[i] = big->data[i]; + } + + mpd_clear_flags(result); + result->exp = 0; + result->len = _mpd_real_size(result->data, big->len); + mpd_qresize(result, result->len, status); + mpd_setdigits(result); + _mpd_cap(result, ctx); + return; + +invalid_operation: + mpd_seterror(result, MPD_Invalid_operation, status); +} + + +/******************************************************************************/ +/* Arithmetic operations */ +/******************************************************************************/ + +/* + * The absolute value of a. If a is negative, the result is the same + * as the result of the minus operation. Otherwise, the result is the + * result of the plus operation. + */ +void +mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + } + + if (mpd_isnegative(a)) { + mpd_qminus(result, a, ctx, status); + } + else { + mpd_qplus(result, a, ctx, status); + } +} + +static inline void +_mpd_ptrswap(const mpd_t **a, const mpd_t **b) +{ + const mpd_t *t = *a; + *a = *b; + *b = t; +} + +/* Add or subtract infinities. */ +static void +_mpd_qaddsub_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b, + uint32_t *status) +{ + if (mpd_isinfinite(a)) { + if (mpd_sign(a) != sign_b && mpd_isinfinite(b)) { + mpd_seterror(result, MPD_Invalid_operation, status); + } + else { + mpd_setspecial(result, mpd_sign(a), MPD_INF); + } + return; + } + assert(mpd_isinfinite(b)); + mpd_setspecial(result, sign_b, MPD_INF); +} + +/* Add or subtract non-special numbers. */ +static void +_mpd_qaddsub(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b, + const mpd_context_t *ctx, uint32_t *status) +{ + const mpd_t *big, *small; + MPD_NEW_STATIC(big_aligned,0,0,0,0); + MPD_NEW_CONST(tiny,0,0,1,1,1,1); + mpd_uint_t carry; + mpd_ssize_t newsize, shift; + mpd_ssize_t exp, i; + int swap = 0; + + + /* compare exponents */ + big = a; small = b; + if (big->exp != small->exp) { + if (small->exp > big->exp) { + _mpd_ptrswap(&big, &small); + swap++; + } + /* align the coefficients */ + if (!mpd_iszerocoeff(big)) { + exp = big->exp - 1; + exp += (big->digits > ctx->prec) ? 0 : big->digits-ctx->prec-1; + if (mpd_adjexp(small) < exp) { + /* + * Avoid huge shifts by substituting a value for small that is + * guaranteed to produce the same results. + * + * adjexp(small) < exp if and only if: + * + * bdigits <= prec AND + * bdigits+shift >= prec+2+sdigits AND + * exp = bexp+bdigits-prec-2 + * + * 1234567000000000 -> bdigits + shift + * ----------XX1234 -> sdigits + * ----------X1 -> tiny-digits + * |- prec -| + * + * OR + * + * bdigits > prec AND + * shift > sdigits AND + * exp = bexp-1 + * + * 1234567892100000 -> bdigits + shift + * ----------XX1234 -> sdigits + * ----------X1 -> tiny-digits + * |- prec -| + * + * If tiny is zero, adding or subtracting is a no-op. + * Otherwise, adding tiny generates a non-zero digit either + * below the rounding digit or the least significant digit + * of big. When subtracting, tiny is in the same position as + * the carry that would be generated by subtracting sdigits. + */ + mpd_copy_flags(&tiny, small); + tiny.exp = exp; + tiny.digits = 1; + tiny.len = 1; + tiny.data[0] = mpd_iszerocoeff(small) ? 0 : 1; + small = &tiny; + } + /* This cannot wrap: the difference is positive and <= maxprec */ + shift = big->exp - small->exp; + if (!mpd_qshiftl(&big_aligned, big, shift, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + goto finish; + } + big = &big_aligned; + } + } + result->exp = small->exp; + + + /* compare length of coefficients */ + if (big->len < small->len) { + _mpd_ptrswap(&big, &small); + swap++; + } + + newsize = big->len; + if (!mpd_qresize(result, newsize, status)) { + goto finish; + } + + if (mpd_sign(a) == sign_b) { + + carry = _mpd_baseadd(result->data, big->data, small->data, + big->len, small->len); + + if (carry) { + newsize = big->len + 1; + if (!mpd_qresize(result, newsize, status)) { + goto finish; + } + result->data[newsize-1] = carry; + } + + result->len = newsize; + mpd_set_flags(result, sign_b); + } + else { + if (big->len == small->len) { + for (i=big->len-1; i >= 0; --i) { + if (big->data[i] != small->data[i]) { + if (big->data[i] < small->data[i]) { + _mpd_ptrswap(&big, &small); + swap++; + } + break; + } + } + } + + _mpd_basesub(result->data, big->data, small->data, + big->len, small->len); + newsize = _mpd_real_size(result->data, big->len); + /* resize to smaller cannot fail */ + (void)mpd_qresize(result, newsize, status); + + result->len = newsize; + sign_b = (swap & 1) ? sign_b : mpd_sign(a); + mpd_set_flags(result, sign_b); + + if (mpd_iszerocoeff(result)) { + mpd_set_positive(result); + if (ctx->round == MPD_ROUND_FLOOR) { + mpd_set_negative(result); + } + } + } + + mpd_setdigits(result); + +finish: + mpd_del(&big_aligned); +} + +/* Add a and b. No specials, no finalizing. */ +static void +_mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + _mpd_qaddsub(result, a, b, mpd_sign(b), ctx, status); +} + +/* Subtract b from a. No specials, no finalizing. */ +static void +_mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status); +} + +/* Add a and b. */ +void +mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + _mpd_qaddsub_inf(result, a, b, mpd_sign(b), status); + return; + } + + _mpd_qaddsub(result, a, b, mpd_sign(b), ctx, status); + mpd_qfinalize(result, ctx, status); +} + +/* Add a and b. Set NaN/Invalid_operation if the result is inexact. */ +static void +_mpd_qadd_exact(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + + mpd_qadd(result, a, b, ctx, &workstatus); + *status |= workstatus; + if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + mpd_seterror(result, MPD_Invalid_operation, status); + } +} + +/* Subtract b from a. */ +void +mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + _mpd_qaddsub_inf(result, a, b, !mpd_sign(b), status); + return; + } + + _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status); + mpd_qfinalize(result, ctx, status); +} + +/* Subtract b from a. Set NaN/Invalid_operation if the result is inexact. */ +static void +_mpd_qsub_exact(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + + mpd_qsub(result, a, b, ctx, &workstatus); + *status |= workstatus; + if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + mpd_seterror(result, MPD_Invalid_operation, status); + } +} + +/* Add decimal and mpd_ssize_t. */ +void +mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qsset_ssize(&bb, b, &maxcontext, status); + mpd_qadd(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Add decimal and mpd_uint_t. */ +void +mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qsset_uint(&bb, b, &maxcontext, status); + mpd_qadd(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Subtract mpd_ssize_t from decimal. */ +void +mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qsset_ssize(&bb, b, &maxcontext, status); + mpd_qsub(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Subtract mpd_uint_t from decimal. */ +void +mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qsset_uint(&bb, b, &maxcontext, status); + mpd_qsub(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Add decimal and int32_t. */ +void +mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qadd_ssize(result, a, b, ctx, status); +} + +/* Add decimal and uint32_t. */ +void +mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qadd_uint(result, a, b, ctx, status); +} + +#ifdef CONFIG_64 +/* Add decimal and int64_t. */ +void +mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qadd_ssize(result, a, b, ctx, status); +} + +/* Add decimal and uint64_t. */ +void +mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qadd_uint(result, a, b, ctx, status); +} +#elif !defined(LEGACY_COMPILER) +/* Add decimal and int64_t. */ +void +mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qset_i64(&bb, b, &maxcontext, status); + mpd_qadd(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Add decimal and uint64_t. */ +void +mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qset_u64(&bb, b, &maxcontext, status); + mpd_qadd(result, a, &bb, ctx, status); + mpd_del(&bb); +} +#endif + +/* Subtract int32_t from decimal. */ +void +mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qsub_ssize(result, a, b, ctx, status); +} + +/* Subtract uint32_t from decimal. */ +void +mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qsub_uint(result, a, b, ctx, status); +} + +#ifdef CONFIG_64 +/* Subtract int64_t from decimal. */ +void +mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qsub_ssize(result, a, b, ctx, status); +} + +/* Subtract uint64_t from decimal. */ +void +mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qsub_uint(result, a, b, ctx, status); +} +#elif !defined(LEGACY_COMPILER) +/* Subtract int64_t from decimal. */ +void +mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qset_i64(&bb, b, &maxcontext, status); + mpd_qsub(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Subtract uint64_t from decimal. */ +void +mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qset_u64(&bb, b, &maxcontext, status); + mpd_qsub(result, a, &bb, ctx, status); + mpd_del(&bb); +} +#endif + + +/* Divide infinities. */ +static void +_mpd_qdiv_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + if (mpd_isinfinite(a)) { + if (mpd_isinfinite(b)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF); + return; + } + assert(mpd_isinfinite(b)); + _settriple(result, mpd_sign(a)^mpd_sign(b), 0, mpd_etiny(ctx)); + *status |= MPD_Clamped; +} + +enum {NO_IDEAL_EXP, SET_IDEAL_EXP}; +/* Divide a by b. */ +static void +_mpd_qdiv(int action, mpd_t *q, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + MPD_NEW_STATIC(aligned,0,0,0,0); + mpd_uint_t ld; + mpd_ssize_t shift, exp, tz; + mpd_ssize_t newsize; + mpd_ssize_t ideal_exp; + mpd_uint_t rem; + uint8_t sign_a = mpd_sign(a); + uint8_t sign_b = mpd_sign(b); + + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(q, a, b, ctx, status)) { + return; + } + _mpd_qdiv_inf(q, a, b, ctx, status); + return; + } + if (mpd_iszerocoeff(b)) { + if (mpd_iszerocoeff(a)) { + mpd_seterror(q, MPD_Division_undefined, status); + } + else { + mpd_setspecial(q, sign_a^sign_b, MPD_INF); + *status |= MPD_Division_by_zero; + } + return; + } + if (mpd_iszerocoeff(a)) { + exp = a->exp - b->exp; + _settriple(q, sign_a^sign_b, 0, exp); + mpd_qfinalize(q, ctx, status); + return; + } + + shift = (b->digits - a->digits) + ctx->prec + 1; + ideal_exp = a->exp - b->exp; + exp = ideal_exp - shift; + if (shift > 0) { + if (!mpd_qshiftl(&aligned, a, shift, status)) { + mpd_seterror(q, MPD_Malloc_error, status); + goto finish; + } + a = &aligned; + } + else if (shift < 0) { + shift = -shift; + if (!mpd_qshiftl(&aligned, b, shift, status)) { + mpd_seterror(q, MPD_Malloc_error, status); + goto finish; + } + b = &aligned; + } + + + newsize = a->len - b->len + 1; + if ((q != b && q != a) || (q == b && newsize > b->len)) { + if (!mpd_qresize(q, newsize, status)) { + mpd_seterror(q, MPD_Malloc_error, status); + goto finish; + } + } + + + if (b->len == 1) { + rem = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]); + } + else if (b->len <= MPD_NEWTONDIV_CUTOFF) { + int ret = _mpd_basedivmod(q->data, NULL, a->data, b->data, + a->len, b->len); + if (ret < 0) { + mpd_seterror(q, MPD_Malloc_error, status); + goto finish; + } + rem = ret; + } + else { + MPD_NEW_STATIC(r,0,0,0,0); + _mpd_base_ndivmod(q, &r, a, b, status); + if (mpd_isspecial(q) || mpd_isspecial(&r)) { + mpd_setspecial(q, MPD_POS, MPD_NAN); + mpd_del(&r); + goto finish; + } + rem = !mpd_iszerocoeff(&r); + mpd_del(&r); + newsize = q->len; + } + + newsize = _mpd_real_size(q->data, newsize); + /* resize to smaller cannot fail */ + mpd_qresize(q, newsize, status); + mpd_set_flags(q, sign_a^sign_b); + q->len = newsize; + mpd_setdigits(q); + + shift = ideal_exp - exp; + if (rem) { + ld = mpd_lsd(q->data[0]); + if (ld == 0 || ld == 5) { + q->data[0] += 1; + } + } + else if (action == SET_IDEAL_EXP && shift > 0) { + tz = mpd_trail_zeros(q); + shift = (tz > shift) ? shift : tz; + mpd_qshiftr_inplace(q, shift); + exp += shift; + } + + q->exp = exp; + + +finish: + mpd_del(&aligned); + mpd_qfinalize(q, ctx, status); +} + +/* Divide a by b. */ +void +mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + MPD_NEW_STATIC(aa,0,0,0,0); + MPD_NEW_STATIC(bb,0,0,0,0); + uint32_t xstatus = 0; - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - if (mpd_isnegative(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; + if (q == a) { + if (!mpd_qcopy(&aa, a, status)) { + mpd_seterror(q, MPD_Malloc_error, status); + goto out; } - /* positive infinity */ - _settriple(result, MPD_POS, 0, mpd_etiny(ctx)); - *status |= MPD_Clamped; - return; - } - if (mpd_iszero(a)) { - mpd_setspecial(result, mpd_sign(a), MPD_INF); - *status |= MPD_Division_by_zero; - return; - } - if (mpd_isnegative(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; + a = &aa; } - workctx = *ctx; - workctx.prec += 2; - workctx.round = MPD_ROUND_HALF_EVEN; - _mpd_qinvroot(result, a, &workctx, status); - mpd_qfinalize(result, ctx, status); -} -/* END LIBMPDEC_ONLY */ - -/* Algorithm from decimal.py */ -static void -_mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - mpd_context_t maxcontext; - MPD_NEW_STATIC(c,0,0,0,0); - MPD_NEW_STATIC(q,0,0,0,0); - MPD_NEW_STATIC(r,0,0,0,0); - MPD_NEW_CONST(two,0,0,1,1,1,2); - mpd_ssize_t prec, ideal_exp; - mpd_ssize_t l, shift; - int exact = 0; - - - ideal_exp = (a->exp - (a->exp & 1)) / 2; - - if (mpd_isspecial(a)) { - if (mpd_qcheck_nan(result, a, ctx, status)) { - return; - } - if (mpd_isnegative(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; + if (q == b) { + if (!mpd_qcopy(&bb, b, status)) { + mpd_seterror(q, MPD_Malloc_error, status); + goto out; } - mpd_setspecial(result, MPD_POS, MPD_INF); - return; - } - if (mpd_iszero(a)) { - _settriple(result, mpd_sign(a), 0, ideal_exp); - mpd_qfinalize(result, ctx, status); - return; - } - if (mpd_isnegative(a)) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; + b = &bb; } - mpd_maxcontext(&maxcontext); - prec = ctx->prec + 1; + _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, &xstatus); - if (!mpd_qcopy(&c, a, status)) { - goto malloc_error; - } - c.exp = 0; + if (xstatus & (MPD_Malloc_error|MPD_Division_impossible)) { + /* Inexact quotients (the usual case) fill the entire context precision, + * which can lead to the above errors for very high precisions. Retry + * the operation with a lower precision in case the result is exact. + * + * We need an upper bound for the number of digits of a_coeff / b_coeff + * when the result is exact. If a_coeff' * 1 / b_coeff' is in lowest + * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable + * bound. + * + * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5. + * The largest amount of digits is generated if b_coeff' is a power of 2 or + * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff'). + * + * We arrive at a total upper bound: + * + * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <= + * log10(a_coeff) + log2(b_coeff) = + * log10(a_coeff) + log10(b_coeff) / log10(2) <= + * a->digits + b->digits * 4; + */ + mpd_context_t workctx = *ctx; + uint32_t ystatus = 0; - if (a->exp & 1) { - if (!mpd_qshiftl(&c, &c, 1, status)) { - goto malloc_error; + workctx.prec = a->digits + b->digits * 4; + if (workctx.prec >= ctx->prec) { + *status |= (xstatus&MPD_Errors); + goto out; /* No point in retrying, keep the original error. */ } - l = (a->digits >> 1) + 1; - } - else { - l = (a->digits + 1) >> 1; - } - shift = prec - l; - if (shift >= 0) { - if (!mpd_qshiftl(&c, &c, 2*shift, status)) { - goto malloc_error; + _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &ystatus); + if (ystatus != 0) { + ystatus = *status | ((ystatus|xstatus)&MPD_Errors); + mpd_seterror(q, ystatus, status); } - exact = 1; } else { - exact = !mpd_qshiftr_inplace(&c, -2*shift); + *status |= xstatus; } - ideal_exp -= shift; - /* find result = floor(sqrt(c)) using Newton's method */ - if (!mpd_qshiftl(result, &one, prec, status)) { - goto malloc_error; - } +out: + mpd_del(&aa); + mpd_del(&bb); +} + +/* Internal function. */ +static void +_mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + MPD_NEW_STATIC(aligned,0,0,0,0); + mpd_ssize_t qsize, rsize; + mpd_ssize_t ideal_exp, expdiff, shift; + uint8_t sign_a = mpd_sign(a); + uint8_t sign_ab = mpd_sign(a)^mpd_sign(b); + + + ideal_exp = (a->exp > b->exp) ? b->exp : a->exp; + if (mpd_iszerocoeff(a)) { + if (!mpd_qcopy(r, a, status)) { + goto nanresult; /* GCOV_NOT_REACHED */ + } + r->exp = ideal_exp; + _settriple(q, sign_ab, 0, 0); + return; + } + + expdiff = mpd_adjexp(a) - mpd_adjexp(b); + if (expdiff < 0) { + if (a->exp > b->exp) { + /* positive and less than b->digits - a->digits */ + shift = a->exp - b->exp; + if (!mpd_qshiftl(r, a, shift, status)) { + goto nanresult; + } + r->exp = ideal_exp; + } + else { + if (!mpd_qcopy(r, a, status)) { + goto nanresult; + } + } + _settriple(q, sign_ab, 0, 0); + return; + } + if (expdiff > ctx->prec) { + *status |= MPD_Division_impossible; + goto nanresult; + } + + + /* + * At this point we have: + * (1) 0 <= a->exp + a->digits - b->exp - b->digits <= prec + * (2) a->exp - b->exp >= b->digits - a->digits + * (3) a->exp - b->exp <= prec + b->digits - a->digits + */ + if (a->exp != b->exp) { + shift = a->exp - b->exp; + if (shift > 0) { + /* by (3), after the shift a->digits <= prec + b->digits */ + if (!mpd_qshiftl(&aligned, a, shift, status)) { + goto nanresult; + } + a = &aligned; + } + else { + shift = -shift; + /* by (2), after the shift b->digits <= a->digits */ + if (!mpd_qshiftl(&aligned, b, shift, status)) { + goto nanresult; + } + b = &aligned; + } + } + + + qsize = a->len - b->len + 1; + if (!(q == a && qsize < a->len) && !(q == b && qsize < b->len)) { + if (!mpd_qresize(q, qsize, status)) { + goto nanresult; + } + } + + rsize = b->len; + if (!(r == a && rsize < a->len)) { + if (!mpd_qresize(r, rsize, status)) { + goto nanresult; + } + } + + if (b->len == 1) { + assert(b->data[0] != 0); /* annotation for scan-build */ + if (a->len == 1) { + _mpd_div_word(&q->data[0], &r->data[0], a->data[0], b->data[0]); + } + else { + r->data[0] = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]); + } + } + else if (b->len <= MPD_NEWTONDIV_CUTOFF) { + int ret; + ret = _mpd_basedivmod(q->data, r->data, a->data, b->data, + a->len, b->len); + if (ret == -1) { + *status |= MPD_Malloc_error; + goto nanresult; + } + } + else { + _mpd_base_ndivmod(q, r, a, b, status); + if (mpd_isspecial(q) || mpd_isspecial(r)) { + goto nanresult; + } + qsize = q->len; + rsize = r->len; + } + + qsize = _mpd_real_size(q->data, qsize); + /* resize to smaller cannot fail */ + mpd_qresize(q, qsize, status); + q->len = qsize; + mpd_setdigits(q); + mpd_set_flags(q, sign_ab); + q->exp = 0; + if (q->digits > ctx->prec) { + *status |= MPD_Division_impossible; + goto nanresult; + } + + rsize = _mpd_real_size(r->data, rsize); + /* resize to smaller cannot fail */ + mpd_qresize(r, rsize, status); + r->len = rsize; + mpd_setdigits(r); + mpd_set_flags(r, sign_a); + r->exp = ideal_exp; + +out: + mpd_del(&aligned); + return; + +nanresult: + mpd_setspecial(q, MPD_POS, MPD_NAN); + mpd_setspecial(r, MPD_POS, MPD_NAN); + goto out; +} + +/* Integer division with remainder. */ +void +mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + uint8_t sign = mpd_sign(a)^mpd_sign(b); + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(q, a, b, ctx, status)) { + mpd_qcopy(r, q, status); + return; + } + if (mpd_isinfinite(a)) { + if (mpd_isinfinite(b)) { + mpd_setspecial(q, MPD_POS, MPD_NAN); + } + else { + mpd_setspecial(q, sign, MPD_INF); + } + mpd_setspecial(r, MPD_POS, MPD_NAN); + *status |= MPD_Invalid_operation; + return; + } + if (mpd_isinfinite(b)) { + if (!mpd_qcopy(r, a, status)) { + mpd_seterror(q, MPD_Malloc_error, status); + return; + } + mpd_qfinalize(r, ctx, status); + _settriple(q, sign, 0, 0); + return; + } + /* debug */ + abort(); /* GCOV_NOT_REACHED */ + } + if (mpd_iszerocoeff(b)) { + if (mpd_iszerocoeff(a)) { + mpd_setspecial(q, MPD_POS, MPD_NAN); + mpd_setspecial(r, MPD_POS, MPD_NAN); + *status |= MPD_Division_undefined; + } + else { + mpd_setspecial(q, sign, MPD_INF); + mpd_setspecial(r, MPD_POS, MPD_NAN); + *status |= (MPD_Division_by_zero|MPD_Invalid_operation); + } + return; + } + + _mpd_qdivmod(q, r, a, b, ctx, status); + mpd_qfinalize(q, ctx, status); + mpd_qfinalize(r, ctx, status); +} + +void +mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + MPD_NEW_STATIC(r,0,0,0,0); + uint8_t sign = mpd_sign(a)^mpd_sign(b); + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(q, a, b, ctx, status)) { + return; + } + if (mpd_isinfinite(a) && mpd_isinfinite(b)) { + mpd_seterror(q, MPD_Invalid_operation, status); + return; + } + if (mpd_isinfinite(a)) { + mpd_setspecial(q, sign, MPD_INF); + return; + } + if (mpd_isinfinite(b)) { + _settriple(q, sign, 0, 0); + return; + } + /* debug */ + abort(); /* GCOV_NOT_REACHED */ + } + if (mpd_iszerocoeff(b)) { + if (mpd_iszerocoeff(a)) { + mpd_seterror(q, MPD_Division_undefined, status); + } + else { + mpd_setspecial(q, sign, MPD_INF); + *status |= MPD_Division_by_zero; + } + return; + } + + + _mpd_qdivmod(q, &r, a, b, ctx, status); + mpd_del(&r); + mpd_qfinalize(q, ctx, status); +} + +/* Divide decimal by mpd_ssize_t. */ +void +mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qsset_ssize(&bb, b, &maxcontext, status); + mpd_qdiv(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Divide decimal by mpd_uint_t. */ +void +mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qsset_uint(&bb, b, &maxcontext, status); + mpd_qdiv(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Divide decimal by int32_t. */ +void +mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qdiv_ssize(result, a, b, ctx, status); +} + +/* Divide decimal by uint32_t. */ +void +mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qdiv_uint(result, a, b, ctx, status); +} + +#ifdef CONFIG_64 +/* Divide decimal by int64_t. */ +void +mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qdiv_ssize(result, a, b, ctx, status); +} + +/* Divide decimal by uint64_t. */ +void +mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qdiv_uint(result, a, b, ctx, status); +} +#elif !defined(LEGACY_COMPILER) +/* Divide decimal by int64_t. */ +void +mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qset_i64(&bb, b, &maxcontext, status); + mpd_qdiv(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Divide decimal by uint64_t. */ +void +mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qset_u64(&bb, b, &maxcontext, status); + mpd_qdiv(result, a, &bb, ctx, status); + mpd_del(&bb); +} +#endif + +/* Pad the result with trailing zeros if it has fewer digits than prec. */ +static void +_mpd_zeropad(mpd_t *result, const mpd_context_t *ctx, uint32_t *status) +{ + if (!mpd_isspecial(result) && !mpd_iszero(result) && + result->digits < ctx->prec) { + mpd_ssize_t shift = ctx->prec - result->digits; + mpd_qshiftl(result, result, shift, status); + result->exp -= shift; + } +} + +/* Check if the result is guaranteed to be one. */ +static int +_mpd_qexp_check_one(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + MPD_NEW_CONST(lim,0,-(ctx->prec+1),1,1,1,9); + MPD_NEW_SHARED(aa, a); + + mpd_set_positive(&aa); + + /* abs(a) <= 9 * 10**(-prec-1) */ + if (_mpd_cmp(&aa, &lim) <= 0) { + _settriple(result, 0, 1, 0); + *status |= MPD_Rounded|MPD_Inexact; + return 1; + } + + return 0; +} + +/* + * Get the number of iterations for the Horner scheme in _mpd_qexp(). + */ +static inline mpd_ssize_t +_mpd_get_exp_iterations(const mpd_t *r, mpd_ssize_t p) +{ + mpd_ssize_t log10pbyr; /* lower bound for log10(p / abs(r)) */ + mpd_ssize_t n; + + assert(p >= 10); + assert(!mpd_iszero(r)); + assert(-p < mpd_adjexp(r) && mpd_adjexp(r) <= -1); + +#ifdef CONFIG_64 + if (p > (mpd_ssize_t)(1ULL<<52)) { + return MPD_SSIZE_MAX; + } +#endif + + /* + * Lower bound for log10(p / abs(r)): adjexp(p) - (adjexp(r) + 1) + * At this point (for CONFIG_64, CONFIG_32 is not problematic): + * 1) 10 <= p <= 2**52 + * 2) -p < adjexp(r) <= -1 + * 3) 1 <= log10pbyr <= 2**52 + 14 + */ + log10pbyr = (mpd_word_digits(p)-1) - (mpd_adjexp(r)+1); + + /* + * The numerator in the paper is 1.435 * p - 1.182, calculated + * exactly. We compensate for rounding errors by using 1.43503. + * ACL2 proofs: + * 1) exp-iter-approx-lower-bound: The term below evaluated + * in 53-bit floating point arithmetic is greater than or + * equal to the exact term used in the paper. + * 2) exp-iter-approx-upper-bound: The term below is less than + * or equal to 3/2 * p <= 3/2 * 2**52. + */ + n = (mpd_ssize_t)ceil((1.43503*(double)p - 1.182) / (double)log10pbyr); + return n >= 3 ? n : 3; +} + +/* + * Internal function, specials have been dealt with. Apart from Overflow + * and Underflow, two cases must be considered for the error of the result: + * + * 1) abs(a) <= 9 * 10**(-prec-1) ==> result == 1 + * + * Absolute error: abs(1 - e**x) < 10**(-prec) + * ------------------------------------------- + * + * 2) abs(a) > 9 * 10**(-prec-1) + * + * Relative error: abs(result - e**x) < 0.5 * 10**(-prec) * e**x + * ------------------------------------------------------------- + * + * The algorithm is from Hull&Abrham, Variable Precision Exponential Function, + * ACM Transactions on Mathematical Software, Vol. 12, No. 2, June 1986. + * + * Main differences: + * + * - The number of iterations for the Horner scheme is calculated using + * 53-bit floating point arithmetic. + * + * - In the error analysis for ER (relative error accumulated in the + * evaluation of the truncated series) the reduced operand r may + * have any number of digits. + * ACL2 proof: exponent-relative-error + * + * - The analysis for early abortion has been adapted for the mpd_t + * ranges. + */ +static void +_mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx; + MPD_NEW_STATIC(tmp,0,0,0,0); + MPD_NEW_STATIC(sum,0,0,0,0); + MPD_NEW_CONST(word,0,0,1,1,1,1); + mpd_ssize_t j, n, t; + + assert(!mpd_isspecial(a)); + + if (mpd_iszerocoeff(a)) { + _settriple(result, MPD_POS, 1, 0); + return; + } + + /* + * We are calculating e^x = e^(r*10^t) = (e^r)^(10^t), where abs(r) < 1 and t >= 0. + * + * If t > 0, we have: + * + * (1) 0.1 <= r < 1, so e^0.1 <= e^r. If t > MAX_T, overflow occurs: + * + * MAX-EMAX+1 < log10(e^(0.1*10*t)) <= log10(e^(r*10^t)) < adjexp(e^(r*10^t))+1 + * + * (2) -1 < r <= -0.1, so e^r <= e^-0.1. If t > MAX_T, underflow occurs: + * + * adjexp(e^(r*10^t)) <= log10(e^(r*10^t)) <= log10(e^(-0.1*10^t)) < MIN-ETINY + */ +#if defined(CONFIG_64) + #define MPD_EXP_MAX_T 19 +#elif defined(CONFIG_32) + #define MPD_EXP_MAX_T 10 +#endif + t = a->digits + a->exp; + t = (t > 0) ? t : 0; + if (t > MPD_EXP_MAX_T) { + if (mpd_ispositive(a)) { + mpd_setspecial(result, MPD_POS, MPD_INF); + *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; + } + else { + _settriple(result, MPD_POS, 0, mpd_etiny(ctx)); + *status |= (MPD_Inexact|MPD_Rounded|MPD_Subnormal| + MPD_Underflow|MPD_Clamped); + } + return; + } + + /* abs(a) <= 9 * 10**(-prec-1) */ + if (_mpd_qexp_check_one(result, a, ctx, status)) { + return; + } + + mpd_maxcontext(&workctx); + workctx.prec = ctx->prec + t + 2; + workctx.prec = (workctx.prec < 10) ? 10 : workctx.prec; + workctx.round = MPD_ROUND_HALF_EVEN; + + if (!mpd_qcopy(result, a, status)) { + return; + } + result->exp -= t; + + /* + * At this point: + * 1) 9 * 10**(-prec-1) < abs(a) + * 2) 9 * 10**(-prec-t-1) < abs(r) + * 3) log10(9) - prec - t - 1 < log10(abs(r)) < adjexp(abs(r)) + 1 + * 4) - prec - t - 2 < adjexp(abs(r)) <= -1 + */ + n = _mpd_get_exp_iterations(result, workctx.prec); + if (n == MPD_SSIZE_MAX) { + mpd_seterror(result, MPD_Invalid_operation, status); /* GCOV_UNLIKELY */ + return; /* GCOV_UNLIKELY */ + } + + _settriple(&sum, MPD_POS, 1, 0); + + for (j = n-1; j >= 1; j--) { + word.data[0] = j; + mpd_setdigits(&word); + mpd_qdiv(&tmp, result, &word, &workctx, &workctx.status); + mpd_qfma(&sum, &sum, &tmp, &one, &workctx, &workctx.status); + } + +#ifdef CONFIG_64 + _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status); +#else + if (t <= MPD_MAX_POW10) { + _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status); + } + else { + t -= MPD_MAX_POW10; + _mpd_qpow_uint(&tmp, &sum, mpd_pow10[MPD_MAX_POW10], MPD_POS, + &workctx, status); + _mpd_qpow_uint(result, &tmp, mpd_pow10[t], MPD_POS, &workctx, status); + } +#endif + + mpd_del(&tmp); + mpd_del(&sum); + *status |= (workctx.status&MPD_Errors); + *status |= (MPD_Inexact|MPD_Rounded); +} + +/* exp(a) */ +void +mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx; + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + if (mpd_isnegative(a)) { + _settriple(result, MPD_POS, 0, 0); + } + else { + mpd_setspecial(result, MPD_POS, MPD_INF); + } + return; + } + if (mpd_iszerocoeff(a)) { + _settriple(result, MPD_POS, 1, 0); + return; + } + + workctx = *ctx; + workctx.round = MPD_ROUND_HALF_EVEN; + + if (ctx->allcr) { + MPD_NEW_STATIC(t1, 0,0,0,0); + MPD_NEW_STATIC(t2, 0,0,0,0); + MPD_NEW_STATIC(ulp, 0,0,0,0); + MPD_NEW_STATIC(aa, 0,0,0,0); + mpd_ssize_t prec; + mpd_ssize_t ulpexp; + uint32_t workstatus; + + if (result == a) { + if (!mpd_qcopy(&aa, a, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + a = &aa; + } + + workctx.clamp = 0; + prec = ctx->prec + 3; + while (1) { + workctx.prec = prec; + workstatus = 0; + + _mpd_qexp(result, a, &workctx, &workstatus); + *status |= workstatus; + + ulpexp = result->exp + result->digits - workctx.prec; + if (workstatus & MPD_Underflow) { + /* The effective work precision is result->digits. */ + ulpexp = result->exp; + } + _ssettriple(&ulp, MPD_POS, 1, ulpexp); + + /* + * At this point [1]: + * 1) abs(result - e**x) < 0.5 * 10**(-prec) * e**x + * 2) result - ulp < e**x < result + ulp + * 3) result - ulp < result < result + ulp + * + * If round(result-ulp)==round(result+ulp), then + * round(result)==round(e**x). Therefore the result + * is correctly rounded. + * + * [1] If abs(a) <= 9 * 10**(-prec-1), use the absolute + * error for a similar argument. + */ + workctx.prec = ctx->prec; + mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); + mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); + if (mpd_isspecial(result) || mpd_iszerocoeff(result) || + mpd_qcmp(&t1, &t2, status) == 0) { + workctx.clamp = ctx->clamp; + _mpd_zeropad(result, &workctx, status); + mpd_check_underflow(result, &workctx, status); + mpd_qfinalize(result, &workctx, status); + break; + } + prec += MPD_RDIGITS; + } + mpd_del(&t1); + mpd_del(&t2); + mpd_del(&ulp); + mpd_del(&aa); + } + else { + _mpd_qexp(result, a, &workctx, status); + _mpd_zeropad(result, &workctx, status); + mpd_check_underflow(result, &workctx, status); + mpd_qfinalize(result, &workctx, status); + } +} + +/* Fused multiply-add: (a * b) + c, with a single final rounding. */ +void +mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_t *cc = NULL; + + if (result == c) { + if ((cc = mpd_qncopy(c)) == NULL) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + c = cc; + } + + _mpd_qmul(result, a, b, ctx, &workstatus); + if (!(workstatus&MPD_Invalid_operation)) { + mpd_qadd(result, result, c, ctx, &workstatus); + } + + if (cc) mpd_del(cc); + *status |= workstatus; +} + +/* + * Schedule the optimal precision increase for the Newton iteration. + * v := input operand + * z_0 := initial approximation + * initprec := natural number such that abs(log(v) - z_0) < 10**-initprec + * maxprec := target precision + * + * For convenience the output klist contains the elements in reverse order: + * klist := [k_n-1, ..., k_0], where + * 1) k_0 <= initprec and + * 2) abs(log(v) - result) < 10**(-2*k_n-1 + 1) <= 10**-maxprec. + */ +static inline int +ln_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], mpd_ssize_t maxprec, + mpd_ssize_t initprec) +{ + mpd_ssize_t k; + int i; + + assert(maxprec >= 2 && initprec >= 2); + if (maxprec <= initprec) return -1; + + i = 0; k = maxprec; + do { + k = (k+2) / 2; + klist[i++] = k; + } while (k > initprec); + + return i-1; +} + +/* The constants have been verified with both decimal.py and mpfr. */ +#ifdef CONFIG_64 +#if MPD_RDIGITS != 19 + #error "mpdecimal.c: MPD_RDIGITS must be 19." +#endif +static const mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = { + 6983716328982174407ULL, 9089704281976336583ULL, 1515961135648465461ULL, + 4416816335727555703ULL, 2900988039194170265ULL, 2307925037472986509ULL, + 107598438319191292ULL, 3466624107184669231ULL, 4450099781311469159ULL, + 9807828059751193854ULL, 7713456862091670584ULL, 1492198849978748873ULL, + 6528728696511086257ULL, 2385392051446341972ULL, 8692180205189339507ULL, + 6518769751037497088ULL, 2375253577097505395ULL, 9095610299291824318ULL, + 982748238504564801ULL, 5438635917781170543ULL, 7547331541421808427ULL, + 752371033310119785ULL, 3171643095059950878ULL, 9785265383207606726ULL, + 2932258279850258550ULL, 5497347726624257094ULL, 2976979522110718264ULL, + 9221477656763693866ULL, 1979650047149510504ULL, 6674183485704422507ULL, + 9702766860595249671ULL, 9278096762712757753ULL, 9314848524948644871ULL, + 6826928280848118428ULL, 754403708474699401ULL, 230105703089634572ULL, + 1929203337658714166ULL, 7589402567763113569ULL, 4208241314695689016ULL, + 2922455440575892572ULL, 9356734206705811364ULL, 2684916746550586856ULL, + 644507064800027750ULL, 9476834636167921018ULL, 5659121373450747856ULL, + 2835522011480466371ULL, 6470806855677432162ULL, 7141748003688084012ULL, + 9619404400222105101ULL, 5504893431493939147ULL, 6674744042432743651ULL, + 2287698219886746543ULL, 7773262884616336622ULL, 1985283935053089653ULL, + 4680843799894826233ULL, 8168948290720832555ULL, 8067566662873690987ULL, + 6248633409525465082ULL, 9829834196778404228ULL, 3524802359972050895ULL, + 3327900967572609677ULL, 110148862877297603ULL, 179914546843642076ULL, + 2302585092994045684ULL +}; +#else +#if MPD_RDIGITS != 9 + #error "mpdecimal.c: MPD_RDIGITS must be 9." +#endif +static const mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = { + 401682692UL, 708474699UL, 720754403UL, 30896345UL, 602301057UL, 765871416UL, + 192920333UL, 763113569UL, 589402567UL, 956890167UL, 82413146UL, 589257242UL, + 245544057UL, 811364292UL, 734206705UL, 868569356UL, 167465505UL, 775026849UL, + 706480002UL, 18064450UL, 636167921UL, 569476834UL, 734507478UL, 156591213UL, + 148046637UL, 283552201UL, 677432162UL, 470806855UL, 880840126UL, 417480036UL, + 210510171UL, 940440022UL, 939147961UL, 893431493UL, 436515504UL, 440424327UL, + 654366747UL, 821988674UL, 622228769UL, 884616336UL, 537773262UL, 350530896UL, + 319852839UL, 989482623UL, 468084379UL, 720832555UL, 168948290UL, 736909878UL, + 675666628UL, 546508280UL, 863340952UL, 404228624UL, 834196778UL, 508959829UL, + 23599720UL, 967735248UL, 96757260UL, 603332790UL, 862877297UL, 760110148UL, + 468436420UL, 401799145UL, 299404568UL, 230258509UL +}; +#endif +/* _mpd_ln10 is used directly for precisions smaller than MINALLOC_MAX*RDIGITS. + Otherwise, it serves as the initial approximation for calculating ln(10). */ +static const mpd_t _mpd_ln10 = { + MPD_STATIC|MPD_CONST_DATA, -(MPD_MINALLOC_MAX*MPD_RDIGITS-1), + MPD_MINALLOC_MAX*MPD_RDIGITS, MPD_MINALLOC_MAX, MPD_MINALLOC_MAX, + (mpd_uint_t *)mpd_ln10_data +}; + +/* + * Set 'result' to log(10). + * Ulp error: abs(result - log(10)) < ulp(log(10)) + * Relative error: abs(result - log(10)) < 5 * 10**-prec * log(10) + * + * NOTE: The relative error is not derived from the ulp error, but + * calculated separately using the fact that 23/10 < log(10) < 24/10. + */ +void +mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status) +{ + mpd_context_t varcontext, maxcontext; + MPD_NEW_STATIC(tmp, 0,0,0,0); + MPD_NEW_CONST(static10, 0,0,2,1,1,10); + mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; + mpd_uint_t rnd; + mpd_ssize_t shift; + int i; + + assert(prec >= 1); + + shift = MPD_MINALLOC_MAX*MPD_RDIGITS-prec; + shift = shift < 0 ? 0 : shift; + + rnd = mpd_qshiftr(result, &_mpd_ln10, shift, status); + if (rnd == MPD_UINT_MAX) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + result->exp = -(result->digits-1); + + mpd_maxcontext(&maxcontext); + if (prec < MPD_MINALLOC_MAX*MPD_RDIGITS) { + maxcontext.prec = prec; + _mpd_apply_round_excess(result, rnd, &maxcontext, status); + *status |= (MPD_Inexact|MPD_Rounded); + return; + } + + mpd_maxcontext(&varcontext); + varcontext.round = MPD_ROUND_TRUNC; + + i = ln_schedule_prec(klist, prec+2, -result->exp); + for (; i >= 0; i--) { + varcontext.prec = 2*klist[i]+3; + result->flags ^= MPD_NEG; + _mpd_qexp(&tmp, result, &varcontext, status); + result->flags ^= MPD_NEG; + mpd_qmul(&tmp, &static10, &tmp, &varcontext, status); + mpd_qsub(&tmp, &tmp, &one, &maxcontext, status); + mpd_qadd(result, result, &tmp, &maxcontext, status); + if (mpd_isspecial(result)) { + break; + } + } + + mpd_del(&tmp); + maxcontext.prec = prec; + mpd_qfinalize(result, &maxcontext, status); +} + +/* + * Initial approximations for the ln() iteration. The values have the + * following properties (established with both decimal.py and mpfr): + * + * Index 0 - 400, logarithms of x in [1.00, 5.00]: + * abs(lnapprox[i] * 10**-3 - log((i+100)/100)) < 10**-2 + * abs(lnapprox[i] * 10**-3 - log((i+1+100)/100)) < 10**-2 + * + * Index 401 - 899, logarithms of x in (0.500, 0.999]: + * abs(-lnapprox[i] * 10**-3 - log((i+100)/1000)) < 10**-2 + * abs(-lnapprox[i] * 10**-3 - log((i+1+100)/1000)) < 10**-2 + */ +static const uint16_t lnapprox[900] = { + /* index 0 - 400: log((i+100)/100) * 1000 */ + 0, 10, 20, 30, 39, 49, 58, 68, 77, 86, 95, 104, 113, 122, 131, 140, 148, 157, + 166, 174, 182, 191, 199, 207, 215, 223, 231, 239, 247, 255, 262, 270, 278, + 285, 293, 300, 308, 315, 322, 329, 336, 344, 351, 358, 365, 372, 378, 385, + 392, 399, 406, 412, 419, 425, 432, 438, 445, 451, 457, 464, 470, 476, 482, + 489, 495, 501, 507, 513, 519, 525, 531, 536, 542, 548, 554, 560, 565, 571, + 577, 582, 588, 593, 599, 604, 610, 615, 621, 626, 631, 637, 642, 647, 652, + 658, 663, 668, 673, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, + 732, 737, 742, 747, 751, 756, 761, 766, 770, 775, 779, 784, 788, 793, 798, + 802, 806, 811, 815, 820, 824, 829, 833, 837, 842, 846, 850, 854, 859, 863, + 867, 871, 876, 880, 884, 888, 892, 896, 900, 904, 908, 912, 916, 920, 924, + 928, 932, 936, 940, 944, 948, 952, 956, 959, 963, 967, 971, 975, 978, 982, + 986, 990, 993, 997, 1001, 1004, 1008, 1012, 1015, 1019, 1022, 1026, 1030, + 1033, 1037, 1040, 1044, 1047, 1051, 1054, 1058, 1061, 1065, 1068, 1072, 1075, + 1078, 1082, 1085, 1089, 1092, 1095, 1099, 1102, 1105, 1109, 1112, 1115, 1118, + 1122, 1125, 1128, 1131, 1135, 1138, 1141, 1144, 1147, 1151, 1154, 1157, 1160, + 1163, 1166, 1169, 1172, 1176, 1179, 1182, 1185, 1188, 1191, 1194, 1197, 1200, + 1203, 1206, 1209, 1212, 1215, 1218, 1221, 1224, 1227, 1230, 1233, 1235, 1238, + 1241, 1244, 1247, 1250, 1253, 1256, 1258, 1261, 1264, 1267, 1270, 1273, 1275, + 1278, 1281, 1284, 1286, 1289, 1292, 1295, 1297, 1300, 1303, 1306, 1308, 1311, + 1314, 1316, 1319, 1322, 1324, 1327, 1330, 1332, 1335, 1338, 1340, 1343, 1345, + 1348, 1351, 1353, 1356, 1358, 1361, 1364, 1366, 1369, 1371, 1374, 1376, 1379, + 1381, 1384, 1386, 1389, 1391, 1394, 1396, 1399, 1401, 1404, 1406, 1409, 1411, + 1413, 1416, 1418, 1421, 1423, 1426, 1428, 1430, 1433, 1435, 1437, 1440, 1442, + 1445, 1447, 1449, 1452, 1454, 1456, 1459, 1461, 1463, 1466, 1468, 1470, 1472, + 1475, 1477, 1479, 1482, 1484, 1486, 1488, 1491, 1493, 1495, 1497, 1500, 1502, + 1504, 1506, 1509, 1511, 1513, 1515, 1517, 1520, 1522, 1524, 1526, 1528, 1530, + 1533, 1535, 1537, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1556, 1558, + 1560, 1562, 1564, 1567, 1569, 1571, 1573, 1575, 1577, 1579, 1581, 1583, 1585, + 1587, 1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, 1605, 1607, 1609, + /* index 401 - 899: -log((i+100)/1000) * 1000 */ + 691, 689, 687, 685, 683, 681, 679, 677, 675, 673, 671, 669, 668, 666, 664, + 662, 660, 658, 656, 654, 652, 650, 648, 646, 644, 642, 641, 639, 637, 635, + 633, 631, 629, 627, 626, 624, 622, 620, 618, 616, 614, 612, 611, 609, 607, + 605, 603, 602, 600, 598, 596, 594, 592, 591, 589, 587, 585, 583, 582, 580, + 578, 576, 574, 573, 571, 569, 567, 566, 564, 562, 560, 559, 557, 555, 553, + 552, 550, 548, 546, 545, 543, 541, 540, 538, 536, 534, 533, 531, 529, 528, + 526, 524, 523, 521, 519, 518, 516, 514, 512, 511, 509, 508, 506, 504, 502, + 501, 499, 498, 496, 494, 493, 491, 489, 488, 486, 484, 483, 481, 480, 478, + 476, 475, 473, 472, 470, 468, 467, 465, 464, 462, 460, 459, 457, 456, 454, + 453, 451, 449, 448, 446, 445, 443, 442, 440, 438, 437, 435, 434, 432, 431, + 429, 428, 426, 425, 423, 422, 420, 419, 417, 416, 414, 412, 411, 410, 408, + 406, 405, 404, 402, 400, 399, 398, 396, 394, 393, 392, 390, 389, 387, 386, + 384, 383, 381, 380, 378, 377, 375, 374, 372, 371, 370, 368, 367, 365, 364, + 362, 361, 360, 358, 357, 355, 354, 352, 351, 350, 348, 347, 345, 344, 342, + 341, 340, 338, 337, 336, 334, 333, 331, 330, 328, 327, 326, 324, 323, 322, + 320, 319, 318, 316, 315, 313, 312, 311, 309, 308, 306, 305, 304, 302, 301, + 300, 298, 297, 296, 294, 293, 292, 290, 289, 288, 286, 285, 284, 282, 281, + 280, 278, 277, 276, 274, 273, 272, 270, 269, 268, 267, 265, 264, 263, 261, + 260, 259, 258, 256, 255, 254, 252, 251, 250, 248, 247, 246, 245, 243, 242, + 241, 240, 238, 237, 236, 234, 233, 232, 231, 229, 228, 227, 226, 224, 223, + 222, 221, 219, 218, 217, 216, 214, 213, 212, 211, 210, 208, 207, 206, 205, + 203, 202, 201, 200, 198, 197, 196, 195, 194, 192, 191, 190, 189, 188, 186, + 185, 184, 183, 182, 180, 179, 178, 177, 176, 174, 173, 172, 171, 170, 168, + 167, 166, 165, 164, 162, 161, 160, 159, 158, 157, 156, 154, 153, 152, 151, + 150, 148, 147, 146, 145, 144, 143, 142, 140, 139, 138, 137, 136, 135, 134, + 132, 131, 130, 129, 128, 127, 126, 124, 123, 122, 121, 120, 119, 118, 116, + 115, 114, 113, 112, 111, 110, 109, 108, 106, 105, 104, 103, 102, 101, 100, + 99, 98, 97, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 84, 83, 82, 81, 80, 79, + 78, 77, 76, 75, 74, 73, 72, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, + 58, 57, 56, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, + 38, 37, 36, 35, 34, 33, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, + 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 +}; + +/* + * Internal ln() function that does not check for specials, zero or one. + * Relative error: abs(result - log(a)) < 0.1 * 10**-prec * abs(log(a)) + */ +static void +_mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t varcontext, maxcontext; + mpd_t *z = (mpd_t *) result; + MPD_NEW_STATIC(v,0,0,0,0); + MPD_NEW_STATIC(vtmp,0,0,0,0); + MPD_NEW_STATIC(tmp,0,0,0,0); + mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; + mpd_ssize_t maxprec, shift, t; + mpd_ssize_t a_digits, a_exp; + mpd_uint_t dummy, x; + int i; + + assert(!mpd_isspecial(a) && !mpd_iszerocoeff(a)); + + /* + * We are calculating ln(a) = ln(v * 10^t) = ln(v) + t*ln(10), + * where 0.5 < v <= 5. + */ + if (!mpd_qcopy(&v, a, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + goto finish; + } + + /* Initial approximation: we have at least one non-zero digit */ + _mpd_get_msdigits(&dummy, &x, &v, 3); + if (x < 10) x *= 10; + if (x < 100) x *= 10; + x -= 100; + + /* a may equal z */ + a_digits = a->digits; + a_exp = a->exp; + + mpd_minalloc(z); + mpd_clear_flags(z); + z->data[0] = lnapprox[x]; + z->len = 1; + z->exp = -3; + mpd_setdigits(z); + + if (x <= 400) { + /* Reduce the input operand to 1.00 <= v <= 5.00. Let y = x + 100, + * so 100 <= y <= 500. Since y contains the most significant digits + * of v, y/100 <= v < (y+1)/100 and abs(z - log(v)) < 10**-2. */ + v.exp = -(a_digits - 1); + t = a_exp + a_digits - 1; + } + else { + /* Reduce the input operand to 0.500 < v <= 0.999. Let y = x + 100, + * so 500 < y <= 999. Since y contains the most significant digits + * of v, y/1000 <= v < (y+1)/1000 and abs(z - log(v)) < 10**-2. */ + v.exp = -a_digits; + t = a_exp + a_digits; + mpd_set_negative(z); + } + + mpd_maxcontext(&maxcontext); + mpd_maxcontext(&varcontext); + varcontext.round = MPD_ROUND_TRUNC; + + maxprec = ctx->prec + 2; + if (t == 0 && (x <= 15 || x >= 800)) { + /* 0.900 <= v <= 1.15: Estimate the magnitude of the logarithm. + * If ln(v) will underflow, skip the loop. Otherwise, adjust the + * precision upwards in order to obtain a sufficient number of + * significant digits. + * + * Case v > 1: + * abs((v-1)/10) < abs((v-1)/v) < abs(ln(v)) < abs(v-1) + * Case v < 1: + * abs(v-1) < abs(ln(v)) < abs((v-1)/v) < abs((v-1)*10) + */ + int cmp = _mpd_cmp(&v, &one); + + /* Upper bound (assume v > 1): abs(v-1), unrounded */ + _mpd_qsub(&tmp, &v, &one, &maxcontext, &maxcontext.status); + if (maxcontext.status & MPD_Errors) { + mpd_seterror(result, MPD_Malloc_error, status); + goto finish; + } + + if (cmp < 0) { + /* v < 1: abs((v-1)*10) */ + tmp.exp += 1; + } + if (mpd_adjexp(&tmp) < mpd_etiny(ctx)) { + /* The upper bound is less than etiny: Underflow to zero */ + _settriple(result, (cmp<0), 1, mpd_etiny(ctx)-1); + goto finish; + } + /* Lower bound: abs((v-1)/10) or abs(v-1) */ + tmp.exp -= 1; + if (mpd_adjexp(&tmp) < 0) { + /* Absolute error of the loop: abs(z - log(v)) < 10**-p. If + * p = ctx->prec+2-adjexp(lower), then the relative error of + * the result is (using 10**adjexp(x) <= abs(x)): + * + * abs(z - log(v)) / abs(log(v)) < 10**-p / abs(log(v)) + * <= 10**(-ctx->prec-2) + */ + maxprec = maxprec - mpd_adjexp(&tmp); + } + } + + i = ln_schedule_prec(klist, maxprec, 2); + for (; i >= 0; i--) { + varcontext.prec = 2*klist[i]+3; + z->flags ^= MPD_NEG; + _mpd_qexp(&tmp, z, &varcontext, status); + z->flags ^= MPD_NEG; + + if (v.digits > varcontext.prec) { + shift = v.digits - varcontext.prec; + mpd_qshiftr(&vtmp, &v, shift, status); + vtmp.exp += shift; + mpd_qmul(&tmp, &vtmp, &tmp, &varcontext, status); + } + else { + mpd_qmul(&tmp, &v, &tmp, &varcontext, status); + } + + mpd_qsub(&tmp, &tmp, &one, &maxcontext, status); + mpd_qadd(z, z, &tmp, &maxcontext, status); + if (mpd_isspecial(z)) { + break; + } + } + + /* + * Case t == 0: + * t * log(10) == 0, the result does not change and the analysis + * above applies. If v < 0.900 or v > 1.15, the relative error is + * less than 10**(-ctx.prec-1). + * Case t != 0: + * z := approx(log(v)) + * y := approx(log(10)) + * p := maxprec = ctx->prec + 2 + * Absolute errors: + * 1) abs(z - log(v)) < 10**-p + * 2) abs(y - log(10)) < 10**-p + * The multiplication is exact, so: + * 3) abs(t*y - t*log(10)) < t*10**-p + * The sum is exact, so: + * 4) abs((z + t*y) - (log(v) + t*log(10))) < (abs(t) + 1) * 10**-p + * Bounds for log(v) and log(10): + * 5) -7/10 < log(v) < 17/10 + * 6) 23/10 < log(10) < 24/10 + * Using 4), 5), 6) and t != 0, the relative error is: + * + * 7) relerr < ((abs(t) + 1)*10**-p) / abs(log(v) + t*log(10)) + * < 0.5 * 10**(-p + 1) = 0.5 * 10**(-ctx->prec-1) + */ + mpd_qln10(&v, maxprec+1, status); + mpd_qmul_ssize(&tmp, &v, t, &maxcontext, status); + mpd_qadd(result, &tmp, z, &maxcontext, status); + + +finish: + *status |= (MPD_Inexact|MPD_Rounded); + mpd_del(&v); + mpd_del(&vtmp); + mpd_del(&tmp); +} + +/* ln(a) */ +void +mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx; + mpd_ssize_t adjexp, t; + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + if (mpd_isnegative(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + mpd_setspecial(result, MPD_POS, MPD_INF); + return; + } + if (mpd_iszerocoeff(a)) { + mpd_setspecial(result, MPD_NEG, MPD_INF); + return; + } + if (mpd_isnegative(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (_mpd_cmp(a, &one) == 0) { + _settriple(result, MPD_POS, 0, 0); + return; + } + /* + * Check if the result will overflow (0 < x, x != 1): + * 1) log10(x) < 0 iff adjexp(x) < 0 + * 2) 0 < x /\ x <= y ==> adjexp(x) <= adjexp(y) + * 3) 0 < x /\ x != 1 ==> 2 * abs(log10(x)) < abs(log(x)) + * 4) adjexp(x) <= log10(x) < adjexp(x) + 1 + * + * Case adjexp(x) >= 0: + * 5) 2 * adjexp(x) < abs(log(x)) + * Case adjexp(x) > 0: + * 6) adjexp(2 * adjexp(x)) <= adjexp(abs(log(x))) + * Case adjexp(x) == 0: + * mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered) + * + * Case adjexp(x) < 0: + * 7) 2 * (-adjexp(x) - 1) < abs(log(x)) + * Case adjexp(x) < -1: + * 8) adjexp(2 * (-adjexp(x) - 1)) <= adjexp(abs(log(x))) + * Case adjexp(x) == -1: + * mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered) + */ + adjexp = mpd_adjexp(a); + t = (adjexp < 0) ? -adjexp-1 : adjexp; + t *= 2; + if (mpd_exp_digits(t)-1 > ctx->emax) { + *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; + mpd_setspecial(result, (adjexp<0), MPD_INF); + return; + } + + workctx = *ctx; + workctx.round = MPD_ROUND_HALF_EVEN; + + if (ctx->allcr) { + MPD_NEW_STATIC(t1, 0,0,0,0); + MPD_NEW_STATIC(t2, 0,0,0,0); + MPD_NEW_STATIC(ulp, 0,0,0,0); + MPD_NEW_STATIC(aa, 0,0,0,0); + mpd_ssize_t prec; + + if (result == a) { + if (!mpd_qcopy(&aa, a, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + a = &aa; + } + + workctx.clamp = 0; + prec = ctx->prec + 3; + while (1) { + workctx.prec = prec; + _mpd_qln(result, a, &workctx, status); + _ssettriple(&ulp, MPD_POS, 1, + result->exp + result->digits-workctx.prec); + + workctx.prec = ctx->prec; + mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); + mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); + if (mpd_isspecial(result) || mpd_iszerocoeff(result) || + mpd_qcmp(&t1, &t2, status) == 0) { + workctx.clamp = ctx->clamp; + mpd_check_underflow(result, &workctx, status); + mpd_qfinalize(result, &workctx, status); + break; + } + prec += MPD_RDIGITS; + } + mpd_del(&t1); + mpd_del(&t2); + mpd_del(&ulp); + mpd_del(&aa); + } + else { + _mpd_qln(result, a, &workctx, status); + mpd_check_underflow(result, &workctx, status); + mpd_qfinalize(result, &workctx, status); + } +} + +/* + * Internal log10() function that does not check for specials, zero or one. + * Case SKIP_FINALIZE: + * Relative error: abs(result - log10(a)) < 0.1 * 10**-prec * abs(log10(a)) + * Case DO_FINALIZE: + * Ulp error: abs(result - log10(a)) < ulp(log10(a)) + */ +enum {SKIP_FINALIZE, DO_FINALIZE}; +static void +_mpd_qlog10(int action, mpd_t *result, const mpd_t *a, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t workctx; + MPD_NEW_STATIC(ln10,0,0,0,0); + + mpd_maxcontext(&workctx); + workctx.prec = ctx->prec + 3; + /* relative error: 0.1 * 10**(-p-3). The specific underflow shortcut + * in _mpd_qln() does not change the final result. */ + _mpd_qln(result, a, &workctx, status); + /* relative error: 5 * 10**(-p-3) */ + mpd_qln10(&ln10, workctx.prec, status); + + if (action == DO_FINALIZE) { + workctx = *ctx; + workctx.round = MPD_ROUND_HALF_EVEN; + } + /* SKIP_FINALIZE: relative error: 5 * 10**(-p-3) */ + _mpd_qdiv(NO_IDEAL_EXP, result, result, &ln10, &workctx, status); + + mpd_del(&ln10); +} + +/* log10(a) */ +void +mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx; + mpd_ssize_t adjexp, t; + + workctx = *ctx; + workctx.round = MPD_ROUND_HALF_EVEN; + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + if (mpd_isnegative(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + mpd_setspecial(result, MPD_POS, MPD_INF); + return; + } + if (mpd_iszerocoeff(a)) { + mpd_setspecial(result, MPD_NEG, MPD_INF); + return; + } + if (mpd_isnegative(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (mpd_coeff_ispow10(a)) { + uint8_t sign = 0; + adjexp = mpd_adjexp(a); + if (adjexp < 0) { + sign = 1; + adjexp = -adjexp; + } + _settriple(result, sign, adjexp, 0); + mpd_qfinalize(result, &workctx, status); + return; + } + /* + * Check if the result will overflow (0 < x, x != 1): + * 1) log10(x) < 0 iff adjexp(x) < 0 + * 2) 0 < x /\ x <= y ==> adjexp(x) <= adjexp(y) + * 3) adjexp(x) <= log10(x) < adjexp(x) + 1 + * + * Case adjexp(x) >= 0: + * 4) adjexp(x) <= abs(log10(x)) + * Case adjexp(x) > 0: + * 5) adjexp(adjexp(x)) <= adjexp(abs(log10(x))) + * Case adjexp(x) == 0: + * mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered) + * + * Case adjexp(x) < 0: + * 6) -adjexp(x) - 1 < abs(log10(x)) + * Case adjexp(x) < -1: + * 7) adjexp(-adjexp(x) - 1) <= adjexp(abs(log(x))) + * Case adjexp(x) == -1: + * mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered) + */ + adjexp = mpd_adjexp(a); + t = (adjexp < 0) ? -adjexp-1 : adjexp; + if (mpd_exp_digits(t)-1 > ctx->emax) { + *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; + mpd_setspecial(result, (adjexp<0), MPD_INF); + return; + } + + if (ctx->allcr) { + MPD_NEW_STATIC(t1, 0,0,0,0); + MPD_NEW_STATIC(t2, 0,0,0,0); + MPD_NEW_STATIC(ulp, 0,0,0,0); + MPD_NEW_STATIC(aa, 0,0,0,0); + mpd_ssize_t prec; + + if (result == a) { + if (!mpd_qcopy(&aa, a, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + a = &aa; + } + + workctx.clamp = 0; + prec = ctx->prec + 3; + while (1) { + workctx.prec = prec; + _mpd_qlog10(SKIP_FINALIZE, result, a, &workctx, status); + _ssettriple(&ulp, MPD_POS, 1, + result->exp + result->digits-workctx.prec); + + workctx.prec = ctx->prec; + mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); + mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); + if (mpd_isspecial(result) || mpd_iszerocoeff(result) || + mpd_qcmp(&t1, &t2, status) == 0) { + workctx.clamp = ctx->clamp; + mpd_check_underflow(result, &workctx, status); + mpd_qfinalize(result, &workctx, status); + break; + } + prec += MPD_RDIGITS; + } + mpd_del(&t1); + mpd_del(&t2); + mpd_del(&ulp); + mpd_del(&aa); + } + else { + _mpd_qlog10(DO_FINALIZE, result, a, &workctx, status); + mpd_check_underflow(result, &workctx, status); + } +} + +/* + * Maximum of the two operands. Attention: If one operand is a quiet NaN and the + * other is numeric, the numeric operand is returned. This may not be what one + * expects. + */ +void +mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + int c; + + if (mpd_isqnan(a) && !mpd_isnan(b)) { + mpd_qcopy(result, b, status); + } + else if (mpd_isqnan(b) && !mpd_isnan(a)) { + mpd_qcopy(result, a, status); + } + else if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + else { + c = _mpd_cmp(a, b); + if (c == 0) { + c = _mpd_cmp_numequal(a, b); + } + + if (c < 0) { + mpd_qcopy(result, b, status); + } + else { + mpd_qcopy(result, a, status); + } + } + + mpd_qfinalize(result, ctx, status); +} + +/* + * Maximum magnitude: Same as mpd_max(), but compares the operands with their + * sign ignored. + */ +void +mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + int c; + + if (mpd_isqnan(a) && !mpd_isnan(b)) { + mpd_qcopy(result, b, status); + } + else if (mpd_isqnan(b) && !mpd_isnan(a)) { + mpd_qcopy(result, a, status); + } + else if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + else { + c = _mpd_cmp_abs(a, b); + if (c == 0) { + c = _mpd_cmp_numequal(a, b); + } + + if (c < 0) { + mpd_qcopy(result, b, status); + } + else { + mpd_qcopy(result, a, status); + } + } + + mpd_qfinalize(result, ctx, status); +} + +/* + * Minimum of the two operands. Attention: If one operand is a quiet NaN and the + * other is numeric, the numeric operand is returned. This may not be what one + * expects. + */ +void +mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + int c; + + if (mpd_isqnan(a) && !mpd_isnan(b)) { + mpd_qcopy(result, b, status); + } + else if (mpd_isqnan(b) && !mpd_isnan(a)) { + mpd_qcopy(result, a, status); + } + else if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + else { + c = _mpd_cmp(a, b); + if (c == 0) { + c = _mpd_cmp_numequal(a, b); + } + + if (c < 0) { + mpd_qcopy(result, a, status); + } + else { + mpd_qcopy(result, b, status); + } + } + + mpd_qfinalize(result, ctx, status); +} + +/* + * Minimum magnitude: Same as mpd_min(), but compares the operands with their + * sign ignored. + */ +void +mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + int c; + + if (mpd_isqnan(a) && !mpd_isnan(b)) { + mpd_qcopy(result, b, status); + } + else if (mpd_isqnan(b) && !mpd_isnan(a)) { + mpd_qcopy(result, a, status); + } + else if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + else { + c = _mpd_cmp_abs(a, b); + if (c == 0) { + c = _mpd_cmp_numequal(a, b); + } + + if (c < 0) { + mpd_qcopy(result, a, status); + } + else { + mpd_qcopy(result, b, status); + } + } + + mpd_qfinalize(result, ctx, status); +} + +/* Minimum space needed for the result array in _karatsuba_rec(). */ +static inline mpd_size_t +_kmul_resultsize(mpd_size_t la, mpd_size_t lb) +{ + mpd_size_t n, m; + + n = add_size_t(la, lb); + n = add_size_t(n, 1); + + m = (la+1)/2 + 1; + m = mul_size_t(m, 3); + + return (m > n) ? m : n; +} + +/* Work space needed in _karatsuba_rec(). lim >= 4 */ +static inline mpd_size_t +_kmul_worksize(mpd_size_t n, mpd_size_t lim) +{ + mpd_size_t m; + + if (n <= lim) { + return 0; + } + + m = (n+1)/2 + 1; + + return add_size_t(mul_size_t(m, 2), _kmul_worksize(m, lim)); +} + + +#define MPD_KARATSUBA_BASECASE 16 /* must be >= 4 */ + +/* + * Add the product of a and b to c. + * c must be _kmul_resultsize(la, lb) in size. + * w is used as a work array and must be _kmul_worksize(a, lim) in size. + * Roman E. Maeder, Storage Allocation for the Karatsuba Integer Multiplication + * Algorithm. In "Design and implementation of symbolic computation systems", + * Springer, 1993, ISBN 354057235X, 9783540572350. + */ +static void +_karatsuba_rec(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b, + mpd_uint_t *w, mpd_size_t la, mpd_size_t lb) +{ + mpd_size_t m, lt; + + assert(la >= lb && lb > 0); + assert(la <= MPD_KARATSUBA_BASECASE || w != NULL); + + if (la <= MPD_KARATSUBA_BASECASE) { + _mpd_basemul(c, a, b, la, lb); + return; + } + + m = (la+1)/2; /* ceil(la/2) */ + + /* lb <= m < la */ + if (lb <= m) { + + /* lb can now be larger than la-m */ + if (lb > la-m) { + lt = lb + lb + 1; /* space needed for result array */ + mpd_uint_zero(w, lt); /* clear result array */ + _karatsuba_rec(w, b, a+m, w+lt, lb, la-m); /* b*ah */ + } + else { + lt = (la-m) + (la-m) + 1; /* space needed for result array */ + mpd_uint_zero(w, lt); /* clear result array */ + _karatsuba_rec(w, a+m, b, w+lt, la-m, lb); /* ah*b */ + } + _mpd_baseaddto(c+m, w, (la-m)+lb); /* add ah*b*B**m */ + + lt = m + m + 1; /* space needed for the result array */ + mpd_uint_zero(w, lt); /* clear result array */ + _karatsuba_rec(w, a, b, w+lt, m, lb); /* al*b */ + _mpd_baseaddto(c, w, m+lb); /* add al*b */ + + return; + } + + /* la >= lb > m */ + memcpy(w, a, m * sizeof *w); + w[m] = 0; + _mpd_baseaddto(w, a+m, la-m); + + memcpy(w+(m+1), b, m * sizeof *w); + w[m+1+m] = 0; + _mpd_baseaddto(w+(m+1), b+m, lb-m); + + _karatsuba_rec(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1); + + lt = (la-m) + (la-m) + 1; + mpd_uint_zero(w, lt); + + _karatsuba_rec(w, a+m, b+m, w+lt, la-m, lb-m); + + _mpd_baseaddto(c+2*m, w, (la-m) + (lb-m)); + _mpd_basesubfrom(c+m, w, (la-m) + (lb-m)); + + lt = m + m + 1; + mpd_uint_zero(w, lt); + + _karatsuba_rec(w, a, b, w+lt, m, m); + _mpd_baseaddto(c, w, m+m); + _mpd_basesubfrom(c+m, w, m+m); + + return; +} + +/* + * Multiply u and v, using Karatsuba multiplication. Returns a pointer + * to the result or NULL in case of failure (malloc error). + * Conditions: ulen >= vlen, ulen >= 4 + */ +static mpd_uint_t * +_mpd_kmul(const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t ulen, mpd_size_t vlen, + mpd_size_t *rsize) +{ + mpd_uint_t *result = NULL, *w = NULL; + mpd_size_t m; + + assert(ulen >= 4); + assert(ulen >= vlen); + + *rsize = _kmul_resultsize(ulen, vlen); + if ((result = mpd_calloc(*rsize, sizeof *result)) == NULL) { + return NULL; + } + + m = _kmul_worksize(ulen, MPD_KARATSUBA_BASECASE); + if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) { + mpd_free(result); + return NULL; + } + + _karatsuba_rec(result, u, v, w, ulen, vlen); + + + if (w) mpd_free(w); + return result; +} + + +/* + * Determine the minimum length for the number theoretic transform. Valid + * transform lengths are 2**n or 3*2**n, where 2**n <= MPD_MAXTRANSFORM_2N. + * The function finds the shortest length m such that rsize <= m. + */ +static inline mpd_size_t +_mpd_get_transform_len(mpd_size_t rsize) +{ + mpd_size_t log2rsize; + mpd_size_t x, step; + + assert(rsize >= 4); + log2rsize = mpd_bsr(rsize); + + if (rsize <= 1024) { + /* 2**n is faster in this range. */ + x = ((mpd_size_t)1)<>1; + x += step; + return (rsize <= x) ? x : x + step; + } + else if (rsize <= MPD_MAXTRANSFORM_2N+MPD_MAXTRANSFORM_2N/2) { + return MPD_MAXTRANSFORM_2N+MPD_MAXTRANSFORM_2N/2; + } + else if (rsize <= 3*MPD_MAXTRANSFORM_2N) { + return 3*MPD_MAXTRANSFORM_2N; + } + else { + return MPD_SIZE_MAX; + } +} + +#ifdef PPRO +#ifndef _MSC_VER +static inline unsigned short +_mpd_get_control87(void) +{ + unsigned short cw; + + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + return cw; +} + +static inline void +_mpd_set_control87(unsigned short cw) +{ + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); +} +#endif + +static unsigned int +mpd_set_fenv(void) +{ + unsigned int cw; +#ifdef _MSC_VER + unsigned int flags = + _EM_INVALID|_EM_DENORMAL|_EM_ZERODIVIDE|_EM_OVERFLOW| + _EM_UNDERFLOW|_EM_INEXACT|_RC_CHOP|_PC_64; + unsigned int mask = _MCW_EM|_MCW_RC|_MCW_PC; + unsigned int dummy; + + __control87_2(0, 0, &cw, NULL); + __control87_2(flags, mask, &dummy, NULL); +#else + cw = _mpd_get_control87(); + _mpd_set_control87(cw|0xF3F); +#endif + return cw; +} + +static void +mpd_restore_fenv(unsigned int cw) +{ +#ifdef _MSC_VER + unsigned int mask = _MCW_EM|_MCW_RC|_MCW_PC; + unsigned int dummy; + + __control87_2(cw, mask, &dummy, NULL); +#else + _mpd_set_control87((unsigned short)cw); +#endif +} +#endif /* PPRO */ + +/* + * Multiply u and v, using the fast number theoretic transform. Returns + * a pointer to the result or NULL in case of failure (malloc error). + */ +static mpd_uint_t * +_mpd_fntmul(const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t ulen, mpd_size_t vlen, + mpd_size_t *rsize) +{ + mpd_uint_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *vtmp = NULL; + mpd_size_t n; + +#ifdef PPRO + unsigned int cw; + cw = mpd_set_fenv(); +#endif + + *rsize = add_size_t(ulen, vlen); + if ((n = _mpd_get_transform_len(*rsize)) == MPD_SIZE_MAX) { + goto malloc_error; + } + + if ((c1 = mpd_calloc(n, sizeof *c1)) == NULL) { + goto malloc_error; + } + if ((c2 = mpd_calloc(n, sizeof *c2)) == NULL) { + goto malloc_error; + } + if ((c3 = mpd_calloc(n, sizeof *c3)) == NULL) { + goto malloc_error; + } + + memcpy(c1, u, ulen * (sizeof *c1)); + memcpy(c2, u, ulen * (sizeof *c2)); + memcpy(c3, u, ulen * (sizeof *c3)); + + if (u == v) { + if (!fnt_autoconvolute(c1, n, P1) || + !fnt_autoconvolute(c2, n, P2) || + !fnt_autoconvolute(c3, n, P3)) { + goto malloc_error; + } + } + else { + if ((vtmp = mpd_calloc(n, sizeof *vtmp)) == NULL) { + goto malloc_error; + } + + memcpy(vtmp, v, vlen * (sizeof *vtmp)); + if (!fnt_convolute(c1, vtmp, n, P1)) { + mpd_free(vtmp); + goto malloc_error; + } + + memcpy(vtmp, v, vlen * (sizeof *vtmp)); + mpd_uint_zero(vtmp+vlen, n-vlen); + if (!fnt_convolute(c2, vtmp, n, P2)) { + mpd_free(vtmp); + goto malloc_error; + } + + memcpy(vtmp, v, vlen * (sizeof *vtmp)); + mpd_uint_zero(vtmp+vlen, n-vlen); + if (!fnt_convolute(c3, vtmp, n, P3)) { + mpd_free(vtmp); + goto malloc_error; + } + + mpd_free(vtmp); + } + + crt3(c1, c2, c3, *rsize); + +out: +#ifdef PPRO + mpd_restore_fenv(cw); +#endif + if (c2) mpd_free(c2); + if (c3) mpd_free(c3); + return c1; + +malloc_error: + if (c1) mpd_free(c1); + c1 = NULL; + goto out; +} + + +/* + * Karatsuba multiplication with FNT/basemul as the base case. + */ +static int +_karatsuba_rec_fnt(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b, + mpd_uint_t *w, mpd_size_t la, mpd_size_t lb) +{ + mpd_size_t m, lt; + + assert(la >= lb && lb > 0); + assert(la <= 3*(MPD_MAXTRANSFORM_2N/2) || w != NULL); + + if (la <= 3*(MPD_MAXTRANSFORM_2N/2)) { + + if (lb <= 192) { + _mpd_basemul(c, b, a, lb, la); + } + else { + mpd_uint_t *result; + mpd_size_t dummy; + + if ((result = _mpd_fntmul(a, b, la, lb, &dummy)) == NULL) { + return 0; + } + memcpy(c, result, (la+lb) * (sizeof *result)); + mpd_free(result); + } + return 1; + } + + m = (la+1)/2; /* ceil(la/2) */ + + /* lb <= m < la */ + if (lb <= m) { + + /* lb can now be larger than la-m */ + if (lb > la-m) { + lt = lb + lb + 1; /* space needed for result array */ + mpd_uint_zero(w, lt); /* clear result array */ + if (!_karatsuba_rec_fnt(w, b, a+m, w+lt, lb, la-m)) { /* b*ah */ + return 0; /* GCOV_UNLIKELY */ + } + } + else { + lt = (la-m) + (la-m) + 1; /* space needed for result array */ + mpd_uint_zero(w, lt); /* clear result array */ + if (!_karatsuba_rec_fnt(w, a+m, b, w+lt, la-m, lb)) { /* ah*b */ + return 0; /* GCOV_UNLIKELY */ + } + } + _mpd_baseaddto(c+m, w, (la-m)+lb); /* add ah*b*B**m */ + + lt = m + m + 1; /* space needed for the result array */ + mpd_uint_zero(w, lt); /* clear result array */ + if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, lb)) { /* al*b */ + return 0; /* GCOV_UNLIKELY */ + } + _mpd_baseaddto(c, w, m+lb); /* add al*b */ + + return 1; + } + + /* la >= lb > m */ + memcpy(w, a, m * sizeof *w); + w[m] = 0; + _mpd_baseaddto(w, a+m, la-m); + + memcpy(w+(m+1), b, m * sizeof *w); + w[m+1+m] = 0; + _mpd_baseaddto(w+(m+1), b+m, lb-m); + + if (!_karatsuba_rec_fnt(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1)) { + return 0; /* GCOV_UNLIKELY */ + } + + lt = (la-m) + (la-m) + 1; + mpd_uint_zero(w, lt); + + if (!_karatsuba_rec_fnt(w, a+m, b+m, w+lt, la-m, lb-m)) { + return 0; /* GCOV_UNLIKELY */ + } + + _mpd_baseaddto(c+2*m, w, (la-m) + (lb-m)); + _mpd_basesubfrom(c+m, w, (la-m) + (lb-m)); + + lt = m + m + 1; + mpd_uint_zero(w, lt); + + if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, m)) { + return 0; /* GCOV_UNLIKELY */ + } + _mpd_baseaddto(c, w, m+m); + _mpd_basesubfrom(c+m, w, m+m); + + return 1; +} + +/* + * Multiply u and v, using Karatsuba multiplication with the FNT as the + * base case. Returns a pointer to the result or NULL in case of failure + * (malloc error). Conditions: ulen >= vlen, ulen >= 4. + */ +static mpd_uint_t * +_mpd_kmul_fnt(const mpd_uint_t *u, const mpd_uint_t *v, + mpd_size_t ulen, mpd_size_t vlen, + mpd_size_t *rsize) +{ + mpd_uint_t *result = NULL, *w = NULL; + mpd_size_t m; + + assert(ulen >= 4); + assert(ulen >= vlen); + + *rsize = _kmul_resultsize(ulen, vlen); + if ((result = mpd_calloc(*rsize, sizeof *result)) == NULL) { + return NULL; + } + + m = _kmul_worksize(ulen, 3*(MPD_MAXTRANSFORM_2N/2)); + if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) { + mpd_free(result); /* GCOV_UNLIKELY */ + return NULL; /* GCOV_UNLIKELY */ + } + + if (!_karatsuba_rec_fnt(result, u, v, w, ulen, vlen)) { + mpd_free(result); + result = NULL; + } + + + if (w) mpd_free(w); + return result; +} + + +/* Deal with the special cases of multiplying infinities. */ +static void +_mpd_qmul_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status) +{ + if (mpd_isinfinite(a)) { + if (mpd_iszero(b)) { + mpd_seterror(result, MPD_Invalid_operation, status); + } + else { + mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF); + } + return; + } + assert(mpd_isinfinite(b)); + if (mpd_iszero(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + } + else { + mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF); + } +} + +/* + * Internal function: Multiply a and b. _mpd_qmul deals with specials but + * does NOT finalize the result. This is for use in mpd_fma(). + */ +static inline void +_mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + const mpd_t *big = a, *small = b; + mpd_uint_t *rdata = NULL; + mpd_uint_t rbuf[MPD_MINALLOC_MAX]; + mpd_size_t rsize, i; + + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + _mpd_qmul_inf(result, a, b, status); + return; + } + + if (small->len > big->len) { + _mpd_ptrswap(&big, &small); + } + + rsize = big->len + small->len; + + if (big->len == 1) { + _mpd_singlemul(result->data, big->data[0], small->data[0]); + goto finish; + } + if (rsize <= (mpd_size_t)MPD_MINALLOC_MAX) { + if (big->len == 2) { + _mpd_mul_2_le2(rbuf, big->data, small->data, small->len); + } + else { + mpd_uint_zero(rbuf, rsize); + if (small->len == 1) { + _mpd_shortmul(rbuf, big->data, big->len, small->data[0]); + } + else { + _mpd_basemul(rbuf, small->data, big->data, small->len, big->len); + } + } + if (!mpd_qresize(result, rsize, status)) { + return; + } + for(i = 0; i < rsize; i++) { + result->data[i] = rbuf[i]; + } + goto finish; + } + + + if (small->len <= 256) { + rdata = mpd_calloc(rsize, sizeof *rdata); + if (rdata != NULL) { + if (small->len == 1) { + _mpd_shortmul(rdata, big->data, big->len, small->data[0]); + } + else { + _mpd_basemul(rdata, small->data, big->data, small->len, big->len); + } + } + } + else if (rsize <= 1024) { + rdata = _mpd_kmul(big->data, small->data, big->len, small->len, &rsize); + } + else if (rsize <= 3*MPD_MAXTRANSFORM_2N) { + rdata = _mpd_fntmul(big->data, small->data, big->len, small->len, &rsize); + } + else { + rdata = _mpd_kmul_fnt(big->data, small->data, big->len, small->len, &rsize); + } + + if (rdata == NULL) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + + if (mpd_isdynamic_data(result)) { + mpd_free(result->data); + } + result->data = rdata; + result->alloc = rsize; + mpd_set_dynamic_data(result); + + +finish: + mpd_set_flags(result, mpd_sign(a)^mpd_sign(b)); + result->exp = big->exp + small->exp; + result->len = _mpd_real_size(result->data, rsize); + /* resize to smaller cannot fail */ + mpd_qresize(result, result->len, status); + mpd_setdigits(result); +} + +/* Multiply a and b. */ +void +mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + _mpd_qmul(result, a, b, ctx, status); + mpd_qfinalize(result, ctx, status); +} + +/* Multiply a and b. Set NaN/Invalid_operation if the result is inexact. */ +static void +_mpd_qmul_exact(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + + mpd_qmul(result, a, b, ctx, &workstatus); + *status |= workstatus; + if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + mpd_seterror(result, MPD_Invalid_operation, status); + } +} + +/* Multiply decimal and mpd_ssize_t. */ +void +mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qsset_ssize(&bb, b, &maxcontext, status); + mpd_qmul(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Multiply decimal and mpd_uint_t. */ +void +mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qsset_uint(&bb, b, &maxcontext, status); + mpd_qmul(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +void +mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qmul_ssize(result, a, b, ctx, status); +} + +void +mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qmul_uint(result, a, b, ctx, status); +} + +#ifdef CONFIG_64 +void +mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qmul_ssize(result, a, b, ctx, status); +} + +void +mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_qmul_uint(result, a, b, ctx, status); +} +#elif !defined(LEGACY_COMPILER) +/* Multiply decimal and int64_t. */ +void +mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qset_i64(&bb, b, &maxcontext, status); + mpd_qmul(result, a, &bb, ctx, status); + mpd_del(&bb); +} + +/* Multiply decimal and uint64_t. */ +void +mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(bb,0,0,0,0); + + mpd_maxcontext(&maxcontext); + mpd_qset_u64(&bb, b, &maxcontext, status); + mpd_qmul(result, a, &bb, ctx, status); + mpd_del(&bb); +} +#endif + +/* Like the minus operator. */ +void +mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + } + + if (mpd_iszero(a) && ctx->round != MPD_ROUND_FLOOR) { + mpd_qcopy_abs(result, a, status); + } + else { + mpd_qcopy_negate(result, a, status); + } + + mpd_qfinalize(result, ctx, status); +} + +/* Like the plus operator. */ +void +mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + } + + if (mpd_iszero(a) && ctx->round != MPD_ROUND_FLOOR) { + mpd_qcopy_abs(result, a, status); + } + else { + mpd_qcopy(result, a, status); + } + + mpd_qfinalize(result, ctx, status); +} + +/* The largest representable number that is smaller than the operand. */ +void +mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx; + MPD_NEW_CONST(tiny,MPD_POS,mpd_etiny(ctx)-1,1,1,1,1); + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + + assert(mpd_isinfinite(a)); + if (mpd_isnegative(a)) { + mpd_qcopy(result, a, status); + return; + } + else { + mpd_clear_flags(result); + mpd_qmaxcoeff(result, ctx, status); + if (mpd_isnan(result)) { + return; + } + result->exp = mpd_etop(ctx); + return; + } + } + + mpd_workcontext(&workctx, ctx); + workctx.round = MPD_ROUND_FLOOR; + + if (!mpd_qcopy(result, a, status)) { + return; + } + + mpd_qfinalize(result, &workctx, &workctx.status); + if (workctx.status&(MPD_Inexact|MPD_Errors)) { + *status |= (workctx.status&MPD_Errors); + return; + } + + workctx.status = 0; + mpd_qsub(result, a, &tiny, &workctx, &workctx.status); + *status |= (workctx.status&MPD_Errors); +} + +/* The smallest representable number that is larger than the operand. */ +void +mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx; + MPD_NEW_CONST(tiny,MPD_POS,mpd_etiny(ctx)-1,1,1,1,1); + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + + assert(mpd_isinfinite(a)); + if (mpd_ispositive(a)) { + mpd_qcopy(result, a, status); + } + else { + mpd_clear_flags(result); + mpd_qmaxcoeff(result, ctx, status); + if (mpd_isnan(result)) { + return; + } + mpd_set_flags(result, MPD_NEG); + result->exp = mpd_etop(ctx); + } + return; + } + + mpd_workcontext(&workctx, ctx); + workctx.round = MPD_ROUND_CEILING; + + if (!mpd_qcopy(result, a, status)) { + return; + } + + mpd_qfinalize(result, &workctx, &workctx.status); + if (workctx.status & (MPD_Inexact|MPD_Errors)) { + *status |= (workctx.status&MPD_Errors); + return; + } + + workctx.status = 0; + mpd_qadd(result, a, &tiny, &workctx, &workctx.status); + *status |= (workctx.status&MPD_Errors); +} + +/* + * The number closest to the first operand that is in the direction towards + * the second operand. + */ +void +mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + int c; + + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + + c = _mpd_cmp(a, b); + if (c == 0) { + mpd_qcopy_sign(result, a, b, status); + return; + } + + if (c < 0) { + mpd_qnext_plus(result, a, ctx, status); + } + else { + mpd_qnext_minus(result, a, ctx, status); + } + + if (mpd_isinfinite(result)) { + *status |= (MPD_Overflow|MPD_Rounded|MPD_Inexact); + } + else if (mpd_adjexp(result) < ctx->emin) { + *status |= (MPD_Underflow|MPD_Subnormal|MPD_Rounded|MPD_Inexact); + if (mpd_iszero(result)) { + *status |= MPD_Clamped; + } + } +} + +/* + * Internal function: Integer power with mpd_uint_t exponent. The function + * can fail with MPD_Malloc_error. + * + * The error is equal to the error incurred in k-1 multiplications. Assuming + * the upper bound for the relative error in each operation: + * + * abs(err) = 5 * 10**-prec + * result = x**k * (1 + err)**(k-1) + */ +static inline void +_mpd_qpow_uint(mpd_t *result, const mpd_t *base, mpd_uint_t exp, + uint8_t resultsign, const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_uint_t n; + + if (exp == 0) { + _settriple(result, resultsign, 1, 0); /* GCOV_NOT_REACHED */ + return; /* GCOV_NOT_REACHED */ + } + + if (!mpd_qcopy(result, base, status)) { + return; + } + + n = mpd_bits[mpd_bsr(exp)]; + while (n >>= 1) { + mpd_qmul(result, result, result, ctx, &workstatus); + if (exp & n) { + mpd_qmul(result, result, base, ctx, &workstatus); + } + if (mpd_isspecial(result) || + (mpd_iszerocoeff(result) && (workstatus & MPD_Clamped))) { + break; + } + } + + *status |= workstatus; + mpd_set_sign(result, resultsign); +} + +/* + * Internal function: Integer power with mpd_t exponent, tbase and texp + * are modified!! Function can fail with MPD_Malloc_error. + * + * The error is equal to the error incurred in k multiplications. Assuming + * the upper bound for the relative error in each operation: + * + * abs(err) = 5 * 10**-prec + * result = x**k * (1 + err)**k + */ +static inline void +_mpd_qpow_mpd(mpd_t *result, mpd_t *tbase, mpd_t *texp, uint8_t resultsign, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_context_t maxctx; + MPD_NEW_CONST(two,0,0,1,1,1,2); + + + mpd_maxcontext(&maxctx); + + /* resize to smaller cannot fail */ + mpd_qcopy(result, &one, status); + + while (!mpd_iszero(texp)) { + if (mpd_isodd(texp)) { + mpd_qmul(result, result, tbase, ctx, &workstatus); + *status |= workstatus; + if (mpd_isspecial(result) || + (mpd_iszerocoeff(result) && (workstatus & MPD_Clamped))) { + break; + } + } + mpd_qmul(tbase, tbase, tbase, ctx, &workstatus); + mpd_qdivint(texp, texp, &two, &maxctx, &workstatus); + if (mpd_isnan(tbase) || mpd_isnan(texp)) { + mpd_seterror(result, workstatus&MPD_Errors, status); + return; + } + } + mpd_set_sign(result, resultsign); +} + +/* + * The power function for integer exponents. Relative error _before_ the + * final rounding to prec: + * abs(result - base**exp) < 0.1 * 10**-prec * abs(base**exp) + */ +static void +_mpd_qpow_int(mpd_t *result, const mpd_t *base, const mpd_t *exp, + uint8_t resultsign, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t workctx; + MPD_NEW_STATIC(tbase,0,0,0,0); + MPD_NEW_STATIC(texp,0,0,0,0); + mpd_ssize_t n; + + + mpd_workcontext(&workctx, ctx); + workctx.prec += (exp->digits + exp->exp + 2); + workctx.round = MPD_ROUND_HALF_EVEN; + workctx.clamp = 0; + if (mpd_isnegative(exp)) { + uint32_t workstatus = 0; + workctx.prec += 1; + mpd_qdiv(&tbase, &one, base, &workctx, &workstatus); + *status |= workstatus; + if (workstatus&MPD_Errors) { + mpd_setspecial(result, MPD_POS, MPD_NAN); + goto finish; + } + } + else { + if (!mpd_qcopy(&tbase, base, status)) { + mpd_setspecial(result, MPD_POS, MPD_NAN); + goto finish; + } + } + + n = mpd_qabs_uint(exp, &workctx.status); + if (workctx.status&MPD_Invalid_operation) { + if (!mpd_qcopy(&texp, exp, status)) { + mpd_setspecial(result, MPD_POS, MPD_NAN); /* GCOV_UNLIKELY */ + goto finish; /* GCOV_UNLIKELY */ + } + _mpd_qpow_mpd(result, &tbase, &texp, resultsign, &workctx, status); + } + else { + _mpd_qpow_uint(result, &tbase, n, resultsign, &workctx, status); + } + + if (mpd_isinfinite(result)) { + /* for ROUND_DOWN, ROUND_FLOOR, etc. */ + _settriple(result, resultsign, 1, MPD_EXP_INF); + } + +finish: + mpd_del(&tbase); + mpd_del(&texp); + mpd_qfinalize(result, ctx, status); +} + +/* + * If the exponent is infinite and base equals one, the result is one + * with a coefficient of length prec. Otherwise, result is undefined. + * Return the value of the comparison against one. + */ +static int +_qcheck_pow_one_inf(mpd_t *result, const mpd_t *base, uint8_t resultsign, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_ssize_t shift; + int cmp; + + if ((cmp = _mpd_cmp(base, &one)) == 0) { + shift = ctx->prec-1; + mpd_qshiftl(result, &one, shift, status); + result->exp = -shift; + mpd_set_flags(result, resultsign); + *status |= (MPD_Inexact|MPD_Rounded); + } + + return cmp; +} + +/* + * If abs(base) equals one, calculate the correct power of one result. + * Otherwise, result is undefined. Return the value of the comparison + * against 1. + * + * This is an internal function that does not check for specials. + */ +static int +_qcheck_pow_one(mpd_t *result, const mpd_t *base, const mpd_t *exp, + uint8_t resultsign, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_ssize_t shift; + int cmp; + + if ((cmp = _mpd_cmp_abs(base, &one)) == 0) { + if (_mpd_isint(exp)) { + if (mpd_isnegative(exp)) { + _settriple(result, resultsign, 1, 0); + return 0; + } + /* 1.000**3 = 1.000000000 */ + mpd_qmul_ssize(result, exp, -base->exp, ctx, &workstatus); + if (workstatus&MPD_Errors) { + *status |= (workstatus&MPD_Errors); + return 0; + } + /* digits-1 after exponentiation */ + shift = mpd_qget_ssize(result, &workstatus); + /* shift is MPD_SSIZE_MAX if result is too large */ + if (shift > ctx->prec-1) { + shift = ctx->prec-1; + *status |= MPD_Rounded; + } + } + else if (mpd_ispositive(base)) { + shift = ctx->prec-1; + *status |= (MPD_Inexact|MPD_Rounded); + } + else { + return -2; /* GCOV_NOT_REACHED */ + } + if (!mpd_qshiftl(result, &one, shift, status)) { + return 0; + } + result->exp = -shift; + mpd_set_flags(result, resultsign); + } + + return cmp; +} + +/* + * Detect certain over/underflow of x**y. + * ACL2 proof: pow-bounds.lisp. + * + * Symbols: + * + * e: EXP_INF or EXP_CLAMP + * x: base + * y: exponent + * + * omega(e) = log10(abs(e)) + * zeta(x) = log10(abs(log10(x))) + * theta(y) = log10(abs(y)) + * + * Upper and lower bounds: + * + * ub_omega(e) = ceil(log10(abs(e))) + * lb_theta(y) = floor(log10(abs(y))) + * + * | floor(log10(floor(abs(log10(x))))) if x < 1/10 or x >= 10 + * lb_zeta(x) = | floor(log10(abs(x-1)/10)) if 1/10 <= x < 1 + * | floor(log10(abs((x-1)/100))) if 1 < x < 10 + * + * ub_omega(e) and lb_theta(y) are obviously upper and lower bounds + * for omega(e) and theta(y). + * + * lb_zeta is a lower bound for zeta(x): + * + * x < 1/10 or x >= 10: + * + * abs(log10(x)) >= 1, so the outer log10 is well defined. Since log10 + * is strictly increasing, the end result is a lower bound. + * + * 1/10 <= x < 1: + * + * We use: log10(x) <= (x-1)/log(10) + * abs(log10(x)) >= abs(x-1)/log(10) + * abs(log10(x)) >= abs(x-1)/10 + * + * 1 < x < 10: + * + * We use: (x-1)/(x*log(10)) < log10(x) + * abs((x-1)/100) < abs(log10(x)) + * + * XXX: abs((x-1)/10) would work, need ACL2 proof. + * + * + * Let (0 < x < 1 and y < 0) or (x > 1 and y > 0). (H1) + * Let ub_omega(exp_inf) < lb_zeta(x) + lb_theta(y) (H2) + * + * Then: + * log10(abs(exp_inf)) < log10(abs(log10(x))) + log10(abs(y)). (1) + * exp_inf < log10(x) * y (2) + * 10**exp_inf < x**y (3) + * + * Let (0 < x < 1 and y > 0) or (x > 1 and y < 0). (H3) + * Let ub_omega(exp_clamp) < lb_zeta(x) + lb_theta(y) (H4) + * + * Then: + * log10(abs(exp_clamp)) < log10(abs(log10(x))) + log10(abs(y)). (4) + * log10(x) * y < exp_clamp (5) + * x**y < 10**exp_clamp (6) + * + */ +static mpd_ssize_t +_lower_bound_zeta(const mpd_t *x, uint32_t *status) +{ + mpd_context_t maxctx; + MPD_NEW_STATIC(scratch,0,0,0,0); + mpd_ssize_t t, u; + + t = mpd_adjexp(x); + if (t > 0) { + /* x >= 10 -> floor(log10(floor(abs(log10(x))))) */ + return mpd_exp_digits(t) - 1; + } + else if (t < -1) { + /* x < 1/10 -> floor(log10(floor(abs(log10(x))))) */ + return mpd_exp_digits(t+1) - 1; + } + else { + mpd_maxcontext(&maxctx); + mpd_qsub(&scratch, x, &one, &maxctx, status); + if (mpd_isspecial(&scratch)) { + mpd_del(&scratch); + return MPD_SSIZE_MAX; + } + u = mpd_adjexp(&scratch); + mpd_del(&scratch); + + /* t == -1, 1/10 <= x < 1 -> floor(log10(abs(x-1)/10)) + * t == 0, 1 < x < 10 -> floor(log10(abs(x-1)/100)) */ + return (t == 0) ? u-2 : u-1; + } +} + +/* + * Detect cases of certain overflow/underflow in the power function. + * Assumptions: x != 1, y != 0. The proof above is for positive x. + * If x is negative and y is an odd integer, x**y == -(abs(x)**y), + * so the analysis does not change. + */ +static int +_qcheck_pow_bounds(mpd_t *result, const mpd_t *x, const mpd_t *y, + uint8_t resultsign, + const mpd_context_t *ctx, uint32_t *status) +{ + MPD_NEW_SHARED(abs_x, x); + mpd_ssize_t ub_omega, lb_zeta, lb_theta; + uint8_t sign; + + mpd_set_positive(&abs_x); + + lb_theta = mpd_adjexp(y); + lb_zeta = _lower_bound_zeta(&abs_x, status); + if (lb_zeta == MPD_SSIZE_MAX) { + mpd_seterror(result, MPD_Malloc_error, status); + return 1; + } + + sign = (mpd_adjexp(&abs_x) < 0) ^ mpd_sign(y); + if (sign == 0) { + /* (0 < |x| < 1 and y < 0) or (|x| > 1 and y > 0) */ + ub_omega = mpd_exp_digits(ctx->emax); + if (ub_omega < lb_zeta + lb_theta) { + _settriple(result, resultsign, 1, MPD_EXP_INF); + mpd_qfinalize(result, ctx, status); + return 1; + } + } + else { + /* (0 < |x| < 1 and y > 0) or (|x| > 1 and y < 0). */ + ub_omega = mpd_exp_digits(mpd_etiny(ctx)); + if (ub_omega < lb_zeta + lb_theta) { + _settriple(result, resultsign, 1, mpd_etiny(ctx)-1); + mpd_qfinalize(result, ctx, status); + return 1; + } + } + + return 0; +} + +/* + * TODO: Implement algorithm for computing exact powers from decimal.py. + * In order to prevent infinite loops, this has to be called before + * using Ziv's strategy for correct rounding. + */ +/* +static int +_mpd_qpow_exact(mpd_t *result, const mpd_t *base, const mpd_t *exp, + const mpd_context_t *ctx, uint32_t *status) +{ + return 0; +} +*/ + +/* + * The power function for real exponents. + * Relative error: abs(result - e**y) < e**y * 1/5 * 10**(-prec - 1) + */ +static void +_mpd_qpow_real(mpd_t *result, const mpd_t *base, const mpd_t *exp, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t workctx; + MPD_NEW_STATIC(texp,0,0,0,0); + + if (!mpd_qcopy(&texp, exp, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + + mpd_maxcontext(&workctx); + workctx.prec = (base->digits > ctx->prec) ? base->digits : ctx->prec; + workctx.prec += (4 + MPD_EXPDIGITS); + workctx.round = MPD_ROUND_HALF_EVEN; + workctx.allcr = ctx->allcr; + + /* + * extra := MPD_EXPDIGITS = MPD_EXP_MAX_T + * wp := prec + 4 + extra + * abs(err) < 5 * 10**-wp + * y := log(base) * exp + * Calculate: + * 1) e**(y * (1 + err)**2) * (1 + err) + * = e**y * e**(y * (2*err + err**2)) * (1 + err) + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * Relative error of the underlined term: + * 2) abs(e**(y * (2*err + err**2)) - 1) + * Case abs(y) >= 10**extra: + * 3) adjexp(y)+1 > log10(abs(y)) >= extra + * This triggers the Overflow/Underflow shortcut in _mpd_qexp(), + * so no further analysis is necessary. + * Case abs(y) < 10**extra: + * 4) abs(y * (2*err + err**2)) < 1/5 * 10**(-prec - 2) + * Use (see _mpd_qexp): + * 5) abs(x) <= 9/10 * 10**-p ==> abs(e**x - 1) < 10**-p + * With 2), 4) and 5): + * 6) abs(e**(y * (2*err + err**2)) - 1) < 10**(-prec - 2) + * The complete relative error of 1) is: + * 7) abs(result - e**y) < e**y * 1/5 * 10**(-prec - 1) + */ + mpd_qln(result, base, &workctx, &workctx.status); + mpd_qmul(result, result, &texp, &workctx, &workctx.status); + mpd_qexp(result, result, &workctx, status); + + mpd_del(&texp); + *status |= (workctx.status&MPD_Errors); + *status |= (MPD_Inexact|MPD_Rounded); +} + +/* The power function: base**exp */ +void +mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, + const mpd_context_t *ctx, uint32_t *status) +{ + uint8_t resultsign = 0; + int intexp = 0; + int cmp; + + if (mpd_isspecial(base) || mpd_isspecial(exp)) { + if (mpd_qcheck_nans(result, base, exp, ctx, status)) { + return; + } + } + if (mpd_isinteger(exp)) { + intexp = 1; + resultsign = mpd_isnegative(base) && mpd_isodd(exp); + } + + if (mpd_iszero(base)) { + if (mpd_iszero(exp)) { + mpd_seterror(result, MPD_Invalid_operation, status); + } + else if (mpd_isnegative(exp)) { + mpd_setspecial(result, resultsign, MPD_INF); + } + else { + _settriple(result, resultsign, 0, 0); + } + return; + } + if (mpd_isnegative(base)) { + if (!intexp || mpd_isinfinite(exp)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + } + if (mpd_isinfinite(exp)) { + /* power of one */ + cmp = _qcheck_pow_one_inf(result, base, resultsign, ctx, status); + if (cmp == 0) { + return; + } + else { + cmp *= mpd_arith_sign(exp); + if (cmp < 0) { + _settriple(result, resultsign, 0, 0); + } + else { + mpd_setspecial(result, resultsign, MPD_INF); + } + } + return; + } + if (mpd_isinfinite(base)) { + if (mpd_iszero(exp)) { + _settriple(result, resultsign, 1, 0); + } + else if (mpd_isnegative(exp)) { + _settriple(result, resultsign, 0, 0); + } + else { + mpd_setspecial(result, resultsign, MPD_INF); + } + return; + } + if (mpd_iszero(exp)) { + _settriple(result, resultsign, 1, 0); + return; + } + if (_qcheck_pow_one(result, base, exp, resultsign, ctx, status) == 0) { + return; + } + if (_qcheck_pow_bounds(result, base, exp, resultsign, ctx, status)) { + return; + } + + if (intexp) { + _mpd_qpow_int(result, base, exp, resultsign, ctx, status); + } + else { + _mpd_qpow_real(result, base, exp, ctx, status); + if (!mpd_isspecial(result) && _mpd_cmp(result, &one) == 0) { + mpd_ssize_t shift = ctx->prec-1; + mpd_qshiftl(result, &one, shift, status); + result->exp = -shift; + } + if (mpd_isinfinite(result)) { + /* for ROUND_DOWN, ROUND_FLOOR, etc. */ + _settriple(result, MPD_POS, 1, MPD_EXP_INF); + } + mpd_qfinalize(result, ctx, status); + } +} + +/* + * Internal function: Integer powmod with mpd_uint_t exponent, base is modified! + * Function can fail with MPD_Malloc_error. + */ +static inline void +_mpd_qpowmod_uint(mpd_t *result, mpd_t *base, mpd_uint_t exp, + const mpd_t *mod, uint32_t *status) +{ + mpd_context_t maxcontext; + + mpd_maxcontext(&maxcontext); + + /* resize to smaller cannot fail */ + mpd_qcopy(result, &one, status); + + while (exp > 0) { + if (exp & 1) { + _mpd_qmul_exact(result, result, base, &maxcontext, status); + mpd_qrem(result, result, mod, &maxcontext, status); + } + _mpd_qmul_exact(base, base, base, &maxcontext, status); + mpd_qrem(base, base, mod, &maxcontext, status); + exp >>= 1; + } +} + +/* The powmod function: (base**exp) % mod */ +void +mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, + const mpd_t *mod, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(tbase,0,0,0,0); + MPD_NEW_STATIC(texp,0,0,0,0); + MPD_NEW_STATIC(tmod,0,0,0,0); + MPD_NEW_STATIC(tmp,0,0,0,0); + MPD_NEW_CONST(two,0,0,1,1,1,2); + mpd_ssize_t tbase_exp, texp_exp; + mpd_ssize_t i; + mpd_t t; + mpd_uint_t r; + uint8_t sign; + + + if (mpd_isspecial(base) || mpd_isspecial(exp) || mpd_isspecial(mod)) { + if (mpd_qcheck_3nans(result, base, exp, mod, ctx, status)) { + return; + } + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + + if (!_mpd_isint(base) || !_mpd_isint(exp) || !_mpd_isint(mod)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (mpd_iszerocoeff(mod)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (mod->digits+mod->exp > ctx->prec) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + sign = (mpd_isnegative(base)) && (mpd_isodd(exp)); + if (mpd_iszerocoeff(exp)) { + if (mpd_iszerocoeff(base)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + r = (_mpd_cmp_abs(mod, &one)==0) ? 0 : 1; + _settriple(result, sign, r, 0); + return; + } + if (mpd_isnegative(exp)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (mpd_iszerocoeff(base)) { + _settriple(result, sign, 0, 0); + return; + } + + mpd_maxcontext(&maxcontext); + + mpd_qrescale(&tmod, mod, 0, &maxcontext, &maxcontext.status); + if (maxcontext.status&MPD_Errors) { + mpd_seterror(result, maxcontext.status&MPD_Errors, status); + goto out; + } + maxcontext.status = 0; + mpd_set_positive(&tmod); + + mpd_qround_to_int(&tbase, base, &maxcontext, status); + mpd_set_positive(&tbase); + tbase_exp = tbase.exp; + tbase.exp = 0; + + mpd_qround_to_int(&texp, exp, &maxcontext, status); + texp_exp = texp.exp; + texp.exp = 0; + + /* base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo */ + mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); + mpd_qshiftl(result, &one, tbase_exp, status); + mpd_qrem(result, result, &tmod, &maxcontext, status); + _mpd_qmul_exact(&tbase, &tbase, result, &maxcontext, status); + mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); + if (mpd_isspecial(&tbase) || + mpd_isspecial(&texp) || + mpd_isspecial(&tmod)) { + goto mpd_errors; + } + + for (i = 0; i < texp_exp; i++) { + _mpd_qpowmod_uint(&tmp, &tbase, 10, &tmod, status); + t = tmp; + tmp = tbase; + tbase = t; + } + if (mpd_isspecial(&tbase)) { + goto mpd_errors; /* GCOV_UNLIKELY */ + } + + /* resize to smaller cannot fail */ + mpd_qcopy(result, &one, status); + while (mpd_isfinite(&texp) && !mpd_iszero(&texp)) { + if (mpd_isodd(&texp)) { + _mpd_qmul_exact(result, result, &tbase, &maxcontext, status); + mpd_qrem(result, result, &tmod, &maxcontext, status); + } + _mpd_qmul_exact(&tbase, &tbase, &tbase, &maxcontext, status); + mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); + mpd_qdivint(&texp, &texp, &two, &maxcontext, status); + } + if (mpd_isspecial(&texp) || mpd_isspecial(&tbase) || + mpd_isspecial(&tmod) || mpd_isspecial(result)) { + /* MPD_Malloc_error */ + goto mpd_errors; + } + else { + mpd_set_sign(result, sign); + } + +out: + mpd_del(&tbase); + mpd_del(&texp); + mpd_del(&tmod); + mpd_del(&tmp); + return; + +mpd_errors: + mpd_setspecial(result, MPD_POS, MPD_NAN); + goto out; +} + +void +mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_ssize_t b_exp = b->exp; + mpd_ssize_t expdiff, shift; + mpd_uint_t rnd; + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(result, a, b, ctx, status)) { + return; + } + if (mpd_isinfinite(a) && mpd_isinfinite(b)) { + mpd_qcopy(result, a, status); + return; + } + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + if (b->exp > ctx->emax || b->exp < mpd_etiny(ctx)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + if (mpd_iszero(a)) { + _settriple(result, mpd_sign(a), 0, b->exp); + mpd_qfinalize(result, ctx, status); + return; + } + + + expdiff = a->exp - b->exp; + if (a->digits + expdiff > ctx->prec) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + if (expdiff >= 0) { + shift = expdiff; + if (!mpd_qshiftl(result, a, shift, status)) { + return; + } + result->exp = b_exp; + } + else { + /* At this point expdiff < 0 and a->digits+expdiff <= prec, + * so the shift before an increment will fit in prec. */ + shift = -expdiff; + rnd = mpd_qshiftr(result, a, shift, status); + if (rnd == MPD_UINT_MAX) { + return; + } + result->exp = b_exp; + if (!_mpd_apply_round_fit(result, rnd, ctx, status)) { + return; + } + workstatus |= MPD_Rounded; + if (rnd) { + workstatus |= MPD_Inexact; + } + } + + if (mpd_adjexp(result) > ctx->emax || + mpd_adjexp(result) < mpd_etiny(ctx)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + *status |= workstatus; + mpd_qfinalize(result, ctx, status); +} + +void +mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_ssize_t shift, maxexp, maxshift; + uint8_t sign_a = mpd_sign(a); + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + mpd_qcopy(result, a, status); + return; + } + + if (!mpd_qcopy(result, a, status)) { + return; + } + mpd_qfinalize(result, ctx, status); + if (mpd_isspecial(result)) { + return; + } + if (mpd_iszero(result)) { + _settriple(result, sign_a, 0, 0); + return; + } + + shift = mpd_trail_zeros(result); + maxexp = (ctx->clamp) ? mpd_etop(ctx) : ctx->emax; + /* After the finalizing above result->exp <= maxexp. */ + maxshift = maxexp - result->exp; + shift = (shift > maxshift) ? maxshift : shift; + + mpd_qshiftr_inplace(result, shift); + result->exp += shift; +} + +void +mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, + uint32_t *status) +{ + MPD_NEW_STATIC(q,0,0,0,0); + + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(r, a, b, ctx, status)) { + return; + } + if (mpd_isinfinite(a)) { + mpd_seterror(r, MPD_Invalid_operation, status); + return; + } + if (mpd_isinfinite(b)) { + mpd_qcopy(r, a, status); + mpd_qfinalize(r, ctx, status); + return; + } + /* debug */ + abort(); /* GCOV_NOT_REACHED */ + } + if (mpd_iszerocoeff(b)) { + if (mpd_iszerocoeff(a)) { + mpd_seterror(r, MPD_Division_undefined, status); + } + else { + mpd_seterror(r, MPD_Invalid_operation, status); + } + return; + } + + _mpd_qdivmod(&q, r, a, b, ctx, status); + mpd_del(&q); + mpd_qfinalize(r, ctx, status); +} + +void +mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_context_t workctx; + MPD_NEW_STATIC(btmp,0,0,0,0); + MPD_NEW_STATIC(q,0,0,0,0); + mpd_ssize_t expdiff, qdigits; + int cmp, isodd, allnine; + + assert(r != NULL); /* annotation for scan-build */ - while (1) { - _mpd_qdivmod(&q, &r, &c, result, &maxcontext, &maxcontext.status); - if (mpd_isspecial(result) || mpd_isspecial(&q)) { - mpd_seterror(result, maxcontext.status&MPD_Errors, status); - goto out; - } - if (_mpd_cmp(result, &q) <= 0) { - break; - } - _mpd_qadd_exact(result, result, &q, &maxcontext, &maxcontext.status); - if (mpd_isspecial(result)) { - mpd_seterror(result, maxcontext.status&MPD_Errors, status); - goto out; - } - _mpd_qdivmod(result, &r, result, &two, &maxcontext, &maxcontext.status); + if (mpd_isspecial(a) || mpd_isspecial(b)) { + if (mpd_qcheck_nans(r, a, b, ctx, status)) { + return; + } + if (mpd_isinfinite(a)) { + mpd_seterror(r, MPD_Invalid_operation, status); + return; + } + if (mpd_isinfinite(b)) { + mpd_qcopy(r, a, status); + mpd_qfinalize(r, ctx, status); + return; + } + /* debug */ + abort(); /* GCOV_NOT_REACHED */ + } + if (mpd_iszerocoeff(b)) { + if (mpd_iszerocoeff(a)) { + mpd_seterror(r, MPD_Division_undefined, status); + } + else { + mpd_seterror(r, MPD_Invalid_operation, status); + } + return; + } + + if (r == b) { + if (!mpd_qcopy(&btmp, b, status)) { + mpd_seterror(r, MPD_Malloc_error, status); + return; + } + b = &btmp; + } + + _mpd_qdivmod(&q, r, a, b, ctx, status); + if (mpd_isnan(&q) || mpd_isnan(r)) { + goto finish; + } + if (mpd_iszerocoeff(r)) { + goto finish; + } + + expdiff = mpd_adjexp(b) - mpd_adjexp(r); + if (-1 <= expdiff && expdiff <= 1) { + + allnine = mpd_coeff_isallnine(&q); + qdigits = q.digits; + isodd = mpd_isodd(&q); + + mpd_maxcontext(&workctx); + if (mpd_sign(a) == mpd_sign(b)) { + /* sign(r) == sign(b) */ + _mpd_qsub(&q, r, b, &workctx, &workctx.status); + } + else { + /* sign(r) != sign(b) */ + _mpd_qadd(&q, r, b, &workctx, &workctx.status); + } + + if (workctx.status&MPD_Errors) { + mpd_seterror(r, workctx.status&MPD_Errors, status); + goto finish; + } + + cmp = _mpd_cmp_abs(&q, r); + if (cmp < 0 || (cmp == 0 && isodd)) { + /* abs(r) > abs(b)/2 or abs(r) == abs(b)/2 and isodd(quotient) */ + if (allnine && qdigits == ctx->prec) { + /* abs(quotient) + 1 == 10**prec */ + mpd_seterror(r, MPD_Division_impossible, status); + goto finish; + } + mpd_qcopy(r, &q, status); + } + } + + +finish: + mpd_del(&btmp); + mpd_del(&q); + mpd_qfinalize(r, ctx, status); +} + +static void +_mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_ssize_t expdiff, shift; + mpd_uint_t rnd; + + if (mpd_isspecial(a)) { + mpd_qcopy(result, a, status); + return; + } + + if (mpd_iszero(a)) { + _settriple(result, mpd_sign(a), 0, exp); + return; + } + + expdiff = a->exp - exp; + if (expdiff >= 0) { + shift = expdiff; + if (a->digits + shift > MPD_MAX_PREC+1) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (!mpd_qshiftl(result, a, shift, status)) { + return; + } + result->exp = exp; + } + else { + shift = -expdiff; + rnd = mpd_qshiftr(result, a, shift, status); + if (rnd == MPD_UINT_MAX) { + return; + } + result->exp = exp; + _mpd_apply_round_excess(result, rnd, ctx, status); + *status |= MPD_Rounded; + if (rnd) { + *status |= MPD_Inexact; + } + } + + if (mpd_issubnormal(result, ctx)) { + *status |= MPD_Subnormal; + } +} + +/* + * Rescale a number so that it has exponent 'exp'. Does not regard context + * precision, emax, emin, but uses the rounding mode. Special numbers are + * quietly copied. Restrictions: + * + * MPD_MIN_ETINY <= exp <= MPD_MAX_EMAX+1 + * result->digits <= MPD_MAX_PREC+1 + */ +void +mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, + const mpd_context_t *ctx, uint32_t *status) +{ + if (exp > MPD_MAX_EMAX+1 || exp < MPD_MIN_ETINY) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + _mpd_qrescale(result, a, exp, ctx, status); +} + +/* + * Same as mpd_qrescale, but with relaxed restrictions. The result of this + * function should only be used for formatting a number and never as input + * for other operations. + * + * MPD_MIN_ETINY-MPD_MAX_PREC <= exp <= MPD_MAX_EMAX+1 + * result->digits <= MPD_MAX_PREC+1 + */ +void +mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, + const mpd_context_t *ctx, uint32_t *status) +{ + if (exp > MPD_MAX_EMAX+1 || exp < MPD_MIN_ETINY-MPD_MAX_PREC) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + _mpd_qrescale(result, a, exp, ctx, status); +} + +/* Round to an integer according to 'action' and ctx->round. */ +enum {TO_INT_EXACT, TO_INT_SILENT, TO_INT_TRUNC}; +static void +_mpd_qround_to_integral(int action, mpd_t *result, const mpd_t *a, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_uint_t rnd; + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + mpd_qcopy(result, a, status); + return; + } + if (a->exp >= 0) { + mpd_qcopy(result, a, status); + return; + } + if (mpd_iszerocoeff(a)) { + _settriple(result, mpd_sign(a), 0, 0); + return; + } + + rnd = mpd_qshiftr(result, a, -a->exp, status); + if (rnd == MPD_UINT_MAX) { + return; + } + result->exp = 0; + + if (action == TO_INT_EXACT || action == TO_INT_SILENT) { + _mpd_apply_round_excess(result, rnd, ctx, status); + if (action == TO_INT_EXACT) { + *status |= MPD_Rounded; + if (rnd) { + *status |= MPD_Inexact; + } + } + } +} + +void +mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + (void)_mpd_qround_to_integral(TO_INT_EXACT, result, a, ctx, status); +} + +void +mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, ctx, status); +} + +void +mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + if (mpd_isspecial(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; } - if (exact) { - _mpd_qmul_exact(&r, result, result, &maxcontext, &maxcontext.status); - if (mpd_isspecial(&r)) { - mpd_seterror(result, maxcontext.status&MPD_Errors, status); - goto out; - } - exact = (_mpd_cmp(&r, &c) == 0); - } + (void)_mpd_qround_to_integral(TO_INT_TRUNC, result, a, ctx, status); +} + +void +mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx = *ctx; - if (exact) { - if (shift >= 0) { - mpd_qshiftr_inplace(result, shift); - } - else { - if (!mpd_qshiftl(result, result, -shift, status)) { - goto malloc_error; - } - } - ideal_exp += shift; - } - else { - int lsd = (int)mpd_lsd(result->data[0]); - if (lsd == 0 || lsd == 5) { - result->data[0] += 1; - } + if (mpd_isspecial(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; } - result->exp = ideal_exp; + workctx.round = MPD_ROUND_FLOOR; + (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, + &workctx, status); +} + +void +mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx = *ctx; + if (mpd_isspecial(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } -out: - mpd_del(&c); - mpd_del(&q); - mpd_del(&r); - maxcontext = *ctx; - maxcontext.round = MPD_ROUND_HALF_EVEN; - mpd_qfinalize(result, &maxcontext, status); - return; - -malloc_error: - mpd_seterror(result, MPD_Malloc_error, status); - goto out; -} - + workctx.round = MPD_ROUND_CEILING; + (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, + &workctx, status); +} + +int +mpd_same_quantum(const mpd_t *a, const mpd_t *b) +{ + if (mpd_isspecial(a) || mpd_isspecial(b)) { + return ((mpd_isnan(a) && mpd_isnan(b)) || + (mpd_isinfinite(a) && mpd_isinfinite(b))); + } + + return a->exp == b->exp; +} + +/* Schedule the increase in precision for the Newton iteration. */ +static inline int +recpr_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], + mpd_ssize_t maxprec, mpd_ssize_t initprec) +{ + mpd_ssize_t k; + int i; + + assert(maxprec > 0 && initprec > 0); + if (maxprec <= initprec) return -1; + + i = 0; k = maxprec; + do { + k = (k+1) / 2; + klist[i++] = k; + } while (k > initprec); + + return i-1; +} + +/* + * Initial approximation for the reciprocal: + * k_0 := MPD_RDIGITS-2 + * z_0 := 10**(-k_0) * floor(10**(2*k_0 + 2) / floor(v * 10**(k_0 + 2))) + * Absolute error: + * |1/v - z_0| < 10**(-k_0) + * ACL2 proof: maxerror-inverse-approx + */ +static void +_mpd_qreciprocal_approx(mpd_t *z, const mpd_t *v, uint32_t *status) +{ + mpd_uint_t p10data[2] = {0, mpd_pow10[MPD_RDIGITS-2]}; + mpd_uint_t dummy, word; + int n; + + assert(v->exp == -v->digits); + + _mpd_get_msdigits(&dummy, &word, v, MPD_RDIGITS); + n = mpd_word_digits(word); + word *= mpd_pow10[MPD_RDIGITS-n]; + + mpd_qresize(z, 2, status); + (void)_mpd_shortdiv(z->data, p10data, 2, word); + + mpd_clear_flags(z); + z->exp = -(MPD_RDIGITS-2); + z->len = (z->data[1] == 0) ? 1 : 2; + mpd_setdigits(z); +} + +/* + * Reciprocal, calculated with Newton's Method. Assumption: result != a. + * NOTE: The comments in the function show that certain operations are + * exact. The proof for the maximum error is too long to fit in here. + * ACL2 proof: maxerror-inverse-complete + */ +static void +_mpd_qreciprocal(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t varcontext, maxcontext; + mpd_t *z = result; /* current approximation */ + mpd_t *v; /* a, normalized to a number between 0.1 and 1 */ + MPD_NEW_SHARED(vtmp, a); /* v shares data with a */ + MPD_NEW_STATIC(s,0,0,0,0); /* temporary variable */ + MPD_NEW_STATIC(t,0,0,0,0); /* temporary variable */ + MPD_NEW_CONST(two,0,0,1,1,1,2); /* const 2 */ + mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; + mpd_ssize_t adj, maxprec, initprec; + uint8_t sign = mpd_sign(a); + int i; + + assert(result != a); + + v = &vtmp; + mpd_clear_flags(v); + adj = v->digits + v->exp; + v->exp = -v->digits; + + /* Initial approximation */ + _mpd_qreciprocal_approx(z, v, status); + + mpd_maxcontext(&varcontext); + mpd_maxcontext(&maxcontext); + varcontext.round = maxcontext.round = MPD_ROUND_TRUNC; + varcontext.emax = maxcontext.emax = MPD_MAX_EMAX + 100; + varcontext.emin = maxcontext.emin = MPD_MIN_EMIN - 100; + maxcontext.prec = MPD_MAX_PREC + 100; + + maxprec = ctx->prec; + maxprec += 2; + initprec = MPD_RDIGITS-3; + + i = recpr_schedule_prec(klist, maxprec, initprec); + for (; i >= 0; i--) { + /* Loop invariant: z->digits <= klist[i]+7 */ + /* Let s := z**2, exact result */ + _mpd_qmul_exact(&s, z, z, &maxcontext, status); + varcontext.prec = 2*klist[i] + 5; + if (v->digits > varcontext.prec) { + /* Let t := v, truncated to n >= 2*k+5 fraction digits */ + mpd_qshiftr(&t, v, v->digits-varcontext.prec, status); + t.exp = -varcontext.prec; + /* Let t := trunc(v)*s, truncated to n >= 2*k+1 fraction digits */ + mpd_qmul(&t, &t, &s, &varcontext, status); + } + else { /* v->digits <= 2*k+5 */ + /* Let t := v*s, truncated to n >= 2*k+1 fraction digits */ + mpd_qmul(&t, v, &s, &varcontext, status); + } + /* Let s := 2*z, exact result */ + _mpd_qmul_exact(&s, z, &two, &maxcontext, status); + /* s.digits < t.digits <= 2*k+5, |adjexp(s)-adjexp(t)| <= 1, + * so the subtraction generates at most 2*k+6 <= klist[i+1]+7 + * digits. The loop invariant is preserved. */ + _mpd_qsub_exact(z, &s, &t, &maxcontext, status); + } + + if (!mpd_isspecial(z)) { + z->exp -= adj; + mpd_set_flags(z, sign); + } + + mpd_del(&s); + mpd_del(&t); + mpd_qfinalize(z, ctx, status); +} + +/* + * Internal function for large numbers: + * + * q, r = divmod(coeff(a), coeff(b)) + * + * Strategy: Multiply the dividend by the reciprocal of the divisor. The + * inexact result is fixed by a small loop, using at most one iteration. + * + * ACL2 proofs: + * ------------ + * 1) q is a natural number. (ndivmod-quotient-natp) + * 2) r is a natural number. (ndivmod-remainder-natp) + * 3) a = q * b + r (ndivmod-q*b+r==a) + * 4) r < b (ndivmod-remainder-<-b) + */ +static void +_mpd_base_ndivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, + uint32_t *status) +{ + mpd_context_t workctx; + mpd_t *qq = q, *rr = r; + mpd_t aa, bb; + int k; + + _mpd_copy_shared(&aa, a); + _mpd_copy_shared(&bb, b); + + mpd_set_positive(&aa); + mpd_set_positive(&bb); + aa.exp = 0; + bb.exp = 0; + + if (q == a || q == b) { + if ((qq = mpd_qnew()) == NULL) { + *status |= MPD_Malloc_error; + goto nanresult; + } + } + if (r == a || r == b) { + if ((rr = mpd_qnew()) == NULL) { + *status |= MPD_Malloc_error; + goto nanresult; + } + } + + mpd_maxcontext(&workctx); + + /* Let prec := adigits - bdigits + 4 */ + workctx.prec = a->digits - b->digits + 1 + 3; + if (a->digits > MPD_MAX_PREC || workctx.prec > MPD_MAX_PREC) { + *status |= MPD_Division_impossible; + goto nanresult; + } + + /* Let x := _mpd_qreciprocal(b, prec) + * Then x is bounded by: + * 1) 1/b - 10**(-prec - bdigits) < x < 1/b + 10**(-prec - bdigits) + * 2) 1/b - 10**(-adigits - 4) < x < 1/b + 10**(-adigits - 4) + */ + _mpd_qreciprocal(rr, &bb, &workctx, &workctx.status); + + /* Get an estimate for the quotient. Let q := a * x + * Then q is bounded by: + * 3) a/b - 10**-4 < q < a/b + 10**-4 + */ + _mpd_qmul(qq, &aa, rr, &workctx, &workctx.status); + /* Truncate q to an integer: + * 4) a/b - 2 < trunc(q) < a/b + 1 + */ + mpd_qtrunc(qq, qq, &workctx, &workctx.status); + + workctx.prec = aa.digits + 3; + workctx.emax = MPD_MAX_EMAX + 3; + workctx.emin = MPD_MIN_EMIN - 3; + /* Multiply the estimate for q by b: + * 5) a - 2 * b < trunc(q) * b < a + b + */ + _mpd_qmul(rr, &bb, qq, &workctx, &workctx.status); + /* Get the estimate for r such that a = q * b + r. */ + _mpd_qsub_exact(rr, &aa, rr, &workctx, &workctx.status); + + /* Fix the result. At this point -b < r < 2*b, so the correction loop + takes at most one iteration. */ + for (k = 0;; k++) { + if (mpd_isspecial(qq) || mpd_isspecial(rr)) { + *status |= (workctx.status&MPD_Errors); + goto nanresult; + } + if (k > 2) { /* Allow two iterations despite the proof. */ + mpd_err_warn("libmpdec: internal error in " /* GCOV_NOT_REACHED */ + "_mpd_base_ndivmod: please report"); /* GCOV_NOT_REACHED */ + *status |= MPD_Invalid_operation; /* GCOV_NOT_REACHED */ + goto nanresult; /* GCOV_NOT_REACHED */ + } + /* r < 0 */ + else if (_mpd_cmp(&zero, rr) == 1) { + _mpd_qadd_exact(rr, rr, &bb, &workctx, &workctx.status); + _mpd_qadd_exact(qq, qq, &minus_one, &workctx, &workctx.status); + } + /* 0 <= r < b */ + else if (_mpd_cmp(rr, &bb) == -1) { + break; + } + /* r >= b */ + else { + _mpd_qsub_exact(rr, rr, &bb, &workctx, &workctx.status); + _mpd_qadd_exact(qq, qq, &one, &workctx, &workctx.status); + } + } + + if (qq != q) { + if (!mpd_qcopy(q, qq, status)) { + goto nanresult; /* GCOV_UNLIKELY */ + } + mpd_del(qq); + } + if (rr != r) { + if (!mpd_qcopy(r, rr, status)) { + goto nanresult; /* GCOV_UNLIKELY */ + } + mpd_del(rr); + } + + *status |= (workctx.status&MPD_Errors); + return; + + +nanresult: + if (qq && qq != q) mpd_del(qq); + if (rr && rr != r) mpd_del(rr); + mpd_setspecial(q, MPD_POS, MPD_NAN); + mpd_setspecial(r, MPD_POS, MPD_NAN); +} + +/* LIBMPDEC_ONLY */ +/* + * Schedule the optimal precision increase for the Newton iteration. + * v := input operand + * z_0 := initial approximation + * initprec := natural number such that abs(sqrt(v) - z_0) < 10**-initprec + * maxprec := target precision + * + * For convenience the output klist contains the elements in reverse order: + * klist := [k_n-1, ..., k_0], where + * 1) k_0 <= initprec and + * 2) abs(sqrt(v) - result) < 10**(-2*k_n-1 + 2) <= 10**-maxprec. + */ +static inline int +invroot_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], + mpd_ssize_t maxprec, mpd_ssize_t initprec) +{ + mpd_ssize_t k; + int i; + + assert(maxprec >= 3 && initprec >= 3); + if (maxprec <= initprec) return -1; + + i = 0; k = maxprec; + do { + k = (k+3) / 2; + klist[i++] = k; + } while (k > initprec); + + return i-1; +} + +/* + * Initial approximation for the inverse square root function. + * Input: + * v := rational number, with 1 <= v < 100 + * vhat := floor(v * 10**6) + * Output: + * z := approximation to 1/sqrt(v), such that abs(z - 1/sqrt(v)) < 10**-3. + */ +static inline void +_invroot_init_approx(mpd_t *z, mpd_uint_t vhat) +{ + mpd_uint_t lo = 1000; + mpd_uint_t hi = 10000; + mpd_uint_t a, sq; + + assert(lo*lo <= vhat && vhat < (hi+1)*(hi+1)); + + for(;;) { + a = (lo + hi) / 2; + sq = a * a; + if (vhat >= sq) { + if (vhat < sq + 2*a + 1) { + break; + } + lo = a + 1; + } + else { + hi = a - 1; + } + } + + /* + * After the binary search we have: + * 1) a**2 <= floor(v * 10**6) < (a + 1)**2 + * This implies: + * 2) a**2 <= v * 10**6 < (a + 1)**2 + * 3) a <= sqrt(v) * 10**3 < a + 1 + * Since 10**3 <= a: + * 4) 0 <= 10**prec/a - 1/sqrt(v) < 10**-prec + * We have: + * 5) 10**3/a - 10**-3 < floor(10**9/a) * 10**-6 <= 10**3/a + * Merging 4) and 5): + * 6) abs(floor(10**9/a) * 10**-6 - 1/sqrt(v)) < 10**-3 + */ + mpd_minalloc(z); + mpd_clear_flags(z); + z->data[0] = 1000000000UL / a; + z->len = 1; + z->exp = -6; + mpd_setdigits(z); +} + +/* + * Set 'result' to 1/sqrt(a). + * Relative error: abs(result - 1/sqrt(a)) < 10**-prec * 1/sqrt(a) + */ +static void +_mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + uint32_t workstatus = 0; + mpd_context_t varcontext, maxcontext; + mpd_t *z = result; /* current approximation */ + mpd_t *v; /* a, normalized to a number between 1 and 100 */ + MPD_NEW_SHARED(vtmp, a); /* by default v will share data with a */ + MPD_NEW_STATIC(s,0,0,0,0); /* temporary variable */ + MPD_NEW_STATIC(t,0,0,0,0); /* temporary variable */ + MPD_NEW_CONST(one_half,0,-1,1,1,1,5); + MPD_NEW_CONST(three,0,0,1,1,1,3); + mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; + mpd_ssize_t ideal_exp, shift; + mpd_ssize_t adj, tz; + mpd_ssize_t maxprec, fracdigits; + mpd_uint_t vhat, dummy; + int i, n; + + + ideal_exp = -(a->exp - (a->exp & 1)) / 2; + + v = &vtmp; + if (result == a) { + if ((v = mpd_qncopy(a)) == NULL) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + } + + /* normalize a to 1 <= v < 100 */ + if ((v->digits+v->exp) & 1) { + fracdigits = v->digits - 1; + v->exp = -fracdigits; + n = (v->digits > 7) ? 7 : (int)v->digits; + /* Let vhat := floor(v * 10**(2*initprec)) */ + _mpd_get_msdigits(&dummy, &vhat, v, n); + if (n < 7) { + vhat *= mpd_pow10[7-n]; + } + } + else { + fracdigits = v->digits - 2; + v->exp = -fracdigits; + n = (v->digits > 8) ? 8 : (int)v->digits; + /* Let vhat := floor(v * 10**(2*initprec)) */ + _mpd_get_msdigits(&dummy, &vhat, v, n); + if (n < 8) { + vhat *= mpd_pow10[8-n]; + } + } + adj = (a->exp-v->exp) / 2; + + /* initial approximation */ + _invroot_init_approx(z, vhat); + + mpd_maxcontext(&maxcontext); + mpd_maxcontext(&varcontext); + varcontext.round = MPD_ROUND_TRUNC; + maxprec = ctx->prec + 1; + + /* initprec == 3 */ + i = invroot_schedule_prec(klist, maxprec, 3); + for (; i >= 0; i--) { + varcontext.prec = 2*klist[i]+2; + mpd_qmul(&s, z, z, &maxcontext, &workstatus); + if (v->digits > varcontext.prec) { + shift = v->digits - varcontext.prec; + mpd_qshiftr(&t, v, shift, &workstatus); + t.exp += shift; + mpd_qmul(&t, &t, &s, &varcontext, &workstatus); + } + else { + mpd_qmul(&t, v, &s, &varcontext, &workstatus); + } + mpd_qsub(&t, &three, &t, &maxcontext, &workstatus); + mpd_qmul(z, z, &t, &varcontext, &workstatus); + mpd_qmul(z, z, &one_half, &maxcontext, &workstatus); + } + + z->exp -= adj; + + tz = mpd_trail_zeros(result); + shift = ideal_exp - result->exp; + shift = (tz > shift) ? shift : tz; + if (shift > 0) { + mpd_qshiftr_inplace(result, shift); + result->exp += shift; + } + + + mpd_del(&s); + mpd_del(&t); + if (v != &vtmp) mpd_del(v); + *status |= (workstatus&MPD_Errors); + *status |= (MPD_Rounded|MPD_Inexact); +} + +void +mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t workctx; + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + if (mpd_isnegative(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + /* positive infinity */ + _settriple(result, MPD_POS, 0, mpd_etiny(ctx)); + *status |= MPD_Clamped; + return; + } + if (mpd_iszero(a)) { + mpd_setspecial(result, mpd_sign(a), MPD_INF); + *status |= MPD_Division_by_zero; + return; + } + if (mpd_isnegative(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + workctx = *ctx; + workctx.prec += 2; + workctx.round = MPD_ROUND_HALF_EVEN; + _mpd_qinvroot(result, a, &workctx, status); + mpd_qfinalize(result, ctx, status); +} +/* END LIBMPDEC_ONLY */ + +/* Algorithm from decimal.py */ +static void +_mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) +{ + mpd_context_t maxcontext; + MPD_NEW_STATIC(c,0,0,0,0); + MPD_NEW_STATIC(q,0,0,0,0); + MPD_NEW_STATIC(r,0,0,0,0); + MPD_NEW_CONST(two,0,0,1,1,1,2); + mpd_ssize_t prec, ideal_exp; + mpd_ssize_t l, shift; + int exact = 0; + + + ideal_exp = (a->exp - (a->exp & 1)) / 2; + + if (mpd_isspecial(a)) { + if (mpd_qcheck_nan(result, a, ctx, status)) { + return; + } + if (mpd_isnegative(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + mpd_setspecial(result, MPD_POS, MPD_INF); + return; + } + if (mpd_iszero(a)) { + _settriple(result, mpd_sign(a), 0, ideal_exp); + mpd_qfinalize(result, ctx, status); + return; + } + if (mpd_isnegative(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + mpd_maxcontext(&maxcontext); + prec = ctx->prec + 1; + + if (!mpd_qcopy(&c, a, status)) { + goto malloc_error; + } + c.exp = 0; + + if (a->exp & 1) { + if (!mpd_qshiftl(&c, &c, 1, status)) { + goto malloc_error; + } + l = (a->digits >> 1) + 1; + } + else { + l = (a->digits + 1) >> 1; + } + + shift = prec - l; + if (shift >= 0) { + if (!mpd_qshiftl(&c, &c, 2*shift, status)) { + goto malloc_error; + } + exact = 1; + } + else { + exact = !mpd_qshiftr_inplace(&c, -2*shift); + } + + ideal_exp -= shift; + + /* find result = floor(sqrt(c)) using Newton's method */ + if (!mpd_qshiftl(result, &one, prec, status)) { + goto malloc_error; + } + + while (1) { + _mpd_qdivmod(&q, &r, &c, result, &maxcontext, &maxcontext.status); + if (mpd_isspecial(result) || mpd_isspecial(&q)) { + mpd_seterror(result, maxcontext.status&MPD_Errors, status); + goto out; + } + if (_mpd_cmp(result, &q) <= 0) { + break; + } + _mpd_qadd_exact(result, result, &q, &maxcontext, &maxcontext.status); + if (mpd_isspecial(result)) { + mpd_seterror(result, maxcontext.status&MPD_Errors, status); + goto out; + } + _mpd_qdivmod(result, &r, result, &two, &maxcontext, &maxcontext.status); + } + + if (exact) { + _mpd_qmul_exact(&r, result, result, &maxcontext, &maxcontext.status); + if (mpd_isspecial(&r)) { + mpd_seterror(result, maxcontext.status&MPD_Errors, status); + goto out; + } + exact = (_mpd_cmp(&r, &c) == 0); + } + + if (exact) { + if (shift >= 0) { + mpd_qshiftr_inplace(result, shift); + } + else { + if (!mpd_qshiftl(result, result, -shift, status)) { + goto malloc_error; + } + } + ideal_exp += shift; + } + else { + int lsd = (int)mpd_lsd(result->data[0]); + if (lsd == 0 || lsd == 5) { + result->data[0] += 1; + } + } + + result->exp = ideal_exp; + + +out: + mpd_del(&c); + mpd_del(&q); + mpd_del(&r); + maxcontext = *ctx; + maxcontext.round = MPD_ROUND_HALF_EVEN; + mpd_qfinalize(result, &maxcontext, status); + return; + +malloc_error: + mpd_seterror(result, MPD_Malloc_error, status); + goto out; +} + void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status) { MPD_NEW_STATIC(aa,0,0,0,0); uint32_t xstatus = 0; - + if (result == a) { if (!mpd_qcopy(&aa, a, status)) { mpd_seterror(result, MPD_Malloc_error, status); @@ -8070,589 +8070,589 @@ out: } -/******************************************************************************/ -/* Base conversions */ -/******************************************************************************/ - -/* Space needed to represent an integer mpd_t in base 'base'. */ -size_t -mpd_sizeinbase(const mpd_t *a, uint32_t base) -{ - double x; - size_t digits; +/******************************************************************************/ +/* Base conversions */ +/******************************************************************************/ + +/* Space needed to represent an integer mpd_t in base 'base'. */ +size_t +mpd_sizeinbase(const mpd_t *a, uint32_t base) +{ + double x; + size_t digits; double upper_bound; - - assert(mpd_isinteger(a)); - assert(base >= 2); - - if (mpd_iszero(a)) { - return 1; - } - - digits = a->digits+a->exp; - assert(digits > 0); - -#ifdef CONFIG_64 - /* ceil(2711437152599294 / log10(2)) + 4 == 2**53 */ - if (digits > 2711437152599294ULL) { - return SIZE_MAX; - } + + assert(mpd_isinteger(a)); + assert(base >= 2); + + if (mpd_iszero(a)) { + return 1; + } + + digits = a->digits+a->exp; + assert(digits > 0); + +#ifdef CONFIG_64 + /* ceil(2711437152599294 / log10(2)) + 4 == 2**53 */ + if (digits > 2711437152599294ULL) { + return SIZE_MAX; + } upper_bound = (double)((1ULL<<53)-1); #else upper_bound = (double)(SIZE_MAX-1); -#endif - - x = (double)digits / log10(base); +#endif + + x = (double)digits / log10(base); return (x > upper_bound) ? SIZE_MAX : (size_t)x + 1; -} - -/* Space needed to import a base 'base' integer of length 'srclen'. */ -static mpd_ssize_t -_mpd_importsize(size_t srclen, uint32_t base) -{ - double x; +} + +/* Space needed to import a base 'base' integer of length 'srclen'. */ +static mpd_ssize_t +_mpd_importsize(size_t srclen, uint32_t base) +{ + double x; double upper_bound; - - assert(srclen > 0); - assert(base >= 2); - -#if SIZE_MAX == UINT64_MAX - if (srclen > (1ULL<<53)) { - return MPD_SSIZE_MAX; - } + + assert(srclen > 0); + assert(base >= 2); + +#if SIZE_MAX == UINT64_MAX + if (srclen > (1ULL<<53)) { + return MPD_SSIZE_MAX; + } assert((1ULL<<53) <= MPD_MAXIMPORT); upper_bound = (double)((1ULL<<53)-1); #else upper_bound = MPD_MAXIMPORT-1; -#endif - - x = (double)srclen * (log10(base)/MPD_RDIGITS); +#endif + + x = (double)srclen * (log10(base)/MPD_RDIGITS); return (x > upper_bound) ? MPD_SSIZE_MAX : (mpd_ssize_t)x + 1; -} - -static uint8_t -mpd_resize_u16(uint16_t **w, size_t nmemb) -{ - uint8_t err = 0; - *w = mpd_realloc(*w, nmemb, sizeof **w, &err); - return !err; -} - -static uint8_t -mpd_resize_u32(uint32_t **w, size_t nmemb) -{ - uint8_t err = 0; - *w = mpd_realloc(*w, nmemb, sizeof **w, &err); - return !err; -} - -static size_t -_baseconv_to_u16(uint16_t **w, size_t wlen, mpd_uint_t wbase, - mpd_uint_t *u, mpd_ssize_t ulen) -{ - size_t n = 0; - - assert(wlen > 0 && ulen > 0); - assert(wbase <= (1U<<16)); - - do { - if (n >= wlen) { - if (!mpd_resize_u16(w, n+1)) { - return SIZE_MAX; - } - wlen = n+1; - } - (*w)[n++] = (uint16_t)_mpd_shortdiv(u, u, ulen, wbase); - /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */ - ulen = _mpd_real_size(u, ulen); - - } while (u[ulen-1] != 0); - - return n; -} - -static size_t -_coeff_from_u16(mpd_t *w, mpd_ssize_t wlen, - const mpd_uint_t *u, size_t ulen, uint32_t ubase, - uint32_t *status) -{ - mpd_ssize_t n = 0; - mpd_uint_t carry; - - assert(wlen > 0 && ulen > 0); - assert(ubase <= (1U<<16)); - - w->data[n++] = u[--ulen]; - while (--ulen != SIZE_MAX) { - carry = _mpd_shortmul_c(w->data, w->data, n, ubase); - if (carry) { - if (n >= wlen) { - if (!mpd_qresize(w, n+1, status)) { - return SIZE_MAX; - } - wlen = n+1; - } - w->data[n++] = carry; - } - carry = _mpd_shortadd(w->data, n, u[ulen]); - if (carry) { - if (n >= wlen) { - if (!mpd_qresize(w, n+1, status)) { - return SIZE_MAX; - } - wlen = n+1; - } - w->data[n++] = carry; - } - } - - return n; -} - -/* target base wbase < source base ubase */ -static size_t -_baseconv_to_smaller(uint32_t **w, size_t wlen, uint32_t wbase, - mpd_uint_t *u, mpd_ssize_t ulen, mpd_uint_t ubase) -{ - size_t n = 0; - - assert(wlen > 0 && ulen > 0); - assert(wbase < ubase); - - do { - if (n >= wlen) { - if (!mpd_resize_u32(w, n+1)) { - return SIZE_MAX; - } - wlen = n+1; - } - (*w)[n++] = (uint32_t)_mpd_shortdiv_b(u, u, ulen, wbase, ubase); - /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */ - ulen = _mpd_real_size(u, ulen); - - } while (u[ulen-1] != 0); - - return n; -} - -#ifdef CONFIG_32 -/* target base 'wbase' == source base 'ubase' */ -static size_t -_copy_equal_base(uint32_t **w, size_t wlen, - const uint32_t *u, size_t ulen) -{ - if (wlen < ulen) { - if (!mpd_resize_u32(w, ulen)) { - return SIZE_MAX; - } - } - - memcpy(*w, u, ulen * (sizeof **w)); - return ulen; -} - -/* target base 'wbase' > source base 'ubase' */ -static size_t -_baseconv_to_larger(uint32_t **w, size_t wlen, mpd_uint_t wbase, - const mpd_uint_t *u, size_t ulen, mpd_uint_t ubase) -{ - size_t n = 0; - mpd_uint_t carry; - - assert(wlen > 0 && ulen > 0); - assert(ubase < wbase); - - (*w)[n++] = u[--ulen]; - while (--ulen != SIZE_MAX) { - carry = _mpd_shortmul_b(*w, *w, n, ubase, wbase); - if (carry) { - if (n >= wlen) { - if (!mpd_resize_u32(w, n+1)) { - return SIZE_MAX; - } - wlen = n+1; - } - (*w)[n++] = carry; - } - carry = _mpd_shortadd_b(*w, n, u[ulen], wbase); - if (carry) { - if (n >= wlen) { - if (!mpd_resize_u32(w, n+1)) { - return SIZE_MAX; - } - wlen = n+1; - } - (*w)[n++] = carry; - } - } - - return n; -} - -/* target base wbase < source base ubase */ -static size_t -_coeff_from_larger_base(mpd_t *w, size_t wlen, mpd_uint_t wbase, - mpd_uint_t *u, mpd_ssize_t ulen, mpd_uint_t ubase, - uint32_t *status) -{ - size_t n = 0; - - assert(wlen > 0 && ulen > 0); - assert(wbase < ubase); - - do { - if (n >= wlen) { - if (!mpd_qresize(w, n+1, status)) { - return SIZE_MAX; - } - wlen = n+1; - } - w->data[n++] = (uint32_t)_mpd_shortdiv_b(u, u, ulen, wbase, ubase); - /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */ - ulen = _mpd_real_size(u, ulen); - - } while (u[ulen-1] != 0); - - return n; -} -#endif - -/* target base 'wbase' > source base 'ubase' */ -static size_t -_coeff_from_smaller_base(mpd_t *w, mpd_ssize_t wlen, mpd_uint_t wbase, - const uint32_t *u, size_t ulen, mpd_uint_t ubase, - uint32_t *status) -{ - mpd_ssize_t n = 0; - mpd_uint_t carry; - - assert(wlen > 0 && ulen > 0); - assert(wbase > ubase); - - w->data[n++] = u[--ulen]; - while (--ulen != SIZE_MAX) { - carry = _mpd_shortmul_b(w->data, w->data, n, ubase, wbase); - if (carry) { - if (n >= wlen) { - if (!mpd_qresize(w, n+1, status)) { - return SIZE_MAX; - } - wlen = n+1; - } - w->data[n++] = carry; - } - carry = _mpd_shortadd_b(w->data, n, u[ulen], wbase); - if (carry) { - if (n >= wlen) { - if (!mpd_qresize(w, n+1, status)) { - return SIZE_MAX; - } - wlen = n+1; - } - w->data[n++] = carry; - } - } - - return n; -} - -/* - * Convert an integer mpd_t to a multiprecision integer with base <= 2**16. - * The least significant word of the result is (*rdata)[0]. - * - * If rdata is NULL, space is allocated by the function and rlen is irrelevant. - * In case of an error any allocated storage is freed and rdata is set back to - * NULL. - * - * If rdata is non-NULL, it MUST be allocated by one of libmpdec's allocation - * functions and rlen MUST be correct. If necessary, the function will resize - * rdata. In case of an error the caller must free rdata. - * - * Return value: In case of success, the exact length of rdata, SIZE_MAX - * otherwise. - */ -size_t -mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t rbase, - const mpd_t *src, uint32_t *status) -{ - MPD_NEW_STATIC(tsrc,0,0,0,0); - int alloc = 0; /* rdata == NULL */ - size_t n; - - assert(rbase <= (1U<<16)); - - if (mpd_isspecial(src) || !_mpd_isint(src)) { - *status |= MPD_Invalid_operation; - return SIZE_MAX; - } - - if (*rdata == NULL) { - rlen = mpd_sizeinbase(src, rbase); - if (rlen == SIZE_MAX) { - *status |= MPD_Invalid_operation; - return SIZE_MAX; - } - *rdata = mpd_alloc(rlen, sizeof **rdata); - if (*rdata == NULL) { - goto malloc_error; - } - alloc = 1; - } - - if (mpd_iszero(src)) { - **rdata = 0; - return 1; - } - - if (src->exp >= 0) { - if (!mpd_qshiftl(&tsrc, src, src->exp, status)) { - goto malloc_error; - } - } - else { - if (mpd_qshiftr(&tsrc, src, -src->exp, status) == MPD_UINT_MAX) { - goto malloc_error; - } - } - - n = _baseconv_to_u16(rdata, rlen, rbase, tsrc.data, tsrc.len); - if (n == SIZE_MAX) { - goto malloc_error; - } - - -out: - mpd_del(&tsrc); - return n; - -malloc_error: - if (alloc) { - mpd_free(*rdata); - *rdata = NULL; - } - n = SIZE_MAX; - *status |= MPD_Malloc_error; - goto out; -} - -/* - * Convert an integer mpd_t to a multiprecision integer with base<=UINT32_MAX. - * The least significant word of the result is (*rdata)[0]. - * - * If rdata is NULL, space is allocated by the function and rlen is irrelevant. - * In case of an error any allocated storage is freed and rdata is set back to - * NULL. - * - * If rdata is non-NULL, it MUST be allocated by one of libmpdec's allocation - * functions and rlen MUST be correct. If necessary, the function will resize - * rdata. In case of an error the caller must free rdata. - * - * Return value: In case of success, the exact length of rdata, SIZE_MAX - * otherwise. - */ -size_t -mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t rbase, - const mpd_t *src, uint32_t *status) -{ - MPD_NEW_STATIC(tsrc,0,0,0,0); - int alloc = 0; /* rdata == NULL */ - size_t n; - - if (mpd_isspecial(src) || !_mpd_isint(src)) { - *status |= MPD_Invalid_operation; - return SIZE_MAX; - } - - if (*rdata == NULL) { - rlen = mpd_sizeinbase(src, rbase); - if (rlen == SIZE_MAX) { - *status |= MPD_Invalid_operation; - return SIZE_MAX; - } - *rdata = mpd_alloc(rlen, sizeof **rdata); - if (*rdata == NULL) { - goto malloc_error; - } - alloc = 1; - } - - if (mpd_iszero(src)) { - **rdata = 0; - return 1; - } - - if (src->exp >= 0) { - if (!mpd_qshiftl(&tsrc, src, src->exp, status)) { - goto malloc_error; - } - } - else { - if (mpd_qshiftr(&tsrc, src, -src->exp, status) == MPD_UINT_MAX) { - goto malloc_error; - } - } - -#ifdef CONFIG_64 - n = _baseconv_to_smaller(rdata, rlen, rbase, - tsrc.data, tsrc.len, MPD_RADIX); -#else - if (rbase == MPD_RADIX) { - n = _copy_equal_base(rdata, rlen, tsrc.data, tsrc.len); - } - else if (rbase < MPD_RADIX) { - n = _baseconv_to_smaller(rdata, rlen, rbase, - tsrc.data, tsrc.len, MPD_RADIX); - } - else { - n = _baseconv_to_larger(rdata, rlen, rbase, - tsrc.data, tsrc.len, MPD_RADIX); - } -#endif - - if (n == SIZE_MAX) { - goto malloc_error; - } - - -out: - mpd_del(&tsrc); - return n; - -malloc_error: - if (alloc) { - mpd_free(*rdata); - *rdata = NULL; - } - n = SIZE_MAX; - *status |= MPD_Malloc_error; - goto out; -} - - -/* - * Converts a multiprecision integer with base <= UINT16_MAX+1 to an mpd_t. - * The least significant word of the source is srcdata[0]. - */ -void -mpd_qimport_u16(mpd_t *result, - const uint16_t *srcdata, size_t srclen, - uint8_t srcsign, uint32_t srcbase, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_uint_t *usrc; /* uint16_t src copied to an mpd_uint_t array */ - mpd_ssize_t rlen; /* length of the result */ - size_t n; - - assert(srclen > 0); - assert(srcbase <= (1U<<16)); - - rlen = _mpd_importsize(srclen, srcbase); - if (rlen == MPD_SSIZE_MAX) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - usrc = mpd_alloc((mpd_size_t)srclen, sizeof *usrc); - if (usrc == NULL) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - for (n = 0; n < srclen; n++) { - usrc[n] = srcdata[n]; - } - - if (!mpd_qresize(result, rlen, status)) { - goto finish; - } - - n = _coeff_from_u16(result, rlen, usrc, srclen, srcbase, status); - if (n == SIZE_MAX) { - goto finish; - } - - mpd_set_flags(result, srcsign); - result->exp = 0; - result->len = n; - mpd_setdigits(result); - - mpd_qresize(result, result->len, status); - mpd_qfinalize(result, ctx, status); - - -finish: - mpd_free(usrc); -} - -/* - * Converts a multiprecision integer with base <= UINT32_MAX to an mpd_t. - * The least significant word of the source is srcdata[0]. - */ -void -mpd_qimport_u32(mpd_t *result, - const uint32_t *srcdata, size_t srclen, - uint8_t srcsign, uint32_t srcbase, - const mpd_context_t *ctx, uint32_t *status) -{ - mpd_ssize_t rlen; /* length of the result */ - size_t n; - - assert(srclen > 0); - - rlen = _mpd_importsize(srclen, srcbase); - if (rlen == MPD_SSIZE_MAX) { - mpd_seterror(result, MPD_Invalid_operation, status); - return; - } - - if (!mpd_qresize(result, rlen, status)) { - return; - } - -#ifdef CONFIG_64 - n = _coeff_from_smaller_base(result, rlen, MPD_RADIX, - srcdata, srclen, srcbase, - status); -#else - if (srcbase == MPD_RADIX) { - if (!mpd_qresize(result, srclen, status)) { - return; - } - memcpy(result->data, srcdata, srclen * (sizeof *srcdata)); - n = srclen; - } - else if (srcbase < MPD_RADIX) { - n = _coeff_from_smaller_base(result, rlen, MPD_RADIX, - srcdata, srclen, srcbase, - status); - } - else { - mpd_uint_t *usrc = mpd_alloc((mpd_size_t)srclen, sizeof *usrc); - if (usrc == NULL) { - mpd_seterror(result, MPD_Malloc_error, status); - return; - } - for (n = 0; n < srclen; n++) { - usrc[n] = srcdata[n]; - } - - n = _coeff_from_larger_base(result, rlen, MPD_RADIX, - usrc, (mpd_ssize_t)srclen, srcbase, - status); - mpd_free(usrc); - } -#endif - - if (n == SIZE_MAX) { - return; - } - - mpd_set_flags(result, srcsign); - result->exp = 0; - result->len = n; - mpd_setdigits(result); - - mpd_qresize(result, result->len, status); - mpd_qfinalize(result, ctx, status); -} +} + +static uint8_t +mpd_resize_u16(uint16_t **w, size_t nmemb) +{ + uint8_t err = 0; + *w = mpd_realloc(*w, nmemb, sizeof **w, &err); + return !err; +} + +static uint8_t +mpd_resize_u32(uint32_t **w, size_t nmemb) +{ + uint8_t err = 0; + *w = mpd_realloc(*w, nmemb, sizeof **w, &err); + return !err; +} + +static size_t +_baseconv_to_u16(uint16_t **w, size_t wlen, mpd_uint_t wbase, + mpd_uint_t *u, mpd_ssize_t ulen) +{ + size_t n = 0; + + assert(wlen > 0 && ulen > 0); + assert(wbase <= (1U<<16)); + + do { + if (n >= wlen) { + if (!mpd_resize_u16(w, n+1)) { + return SIZE_MAX; + } + wlen = n+1; + } + (*w)[n++] = (uint16_t)_mpd_shortdiv(u, u, ulen, wbase); + /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */ + ulen = _mpd_real_size(u, ulen); + + } while (u[ulen-1] != 0); + + return n; +} + +static size_t +_coeff_from_u16(mpd_t *w, mpd_ssize_t wlen, + const mpd_uint_t *u, size_t ulen, uint32_t ubase, + uint32_t *status) +{ + mpd_ssize_t n = 0; + mpd_uint_t carry; + + assert(wlen > 0 && ulen > 0); + assert(ubase <= (1U<<16)); + + w->data[n++] = u[--ulen]; + while (--ulen != SIZE_MAX) { + carry = _mpd_shortmul_c(w->data, w->data, n, ubase); + if (carry) { + if (n >= wlen) { + if (!mpd_qresize(w, n+1, status)) { + return SIZE_MAX; + } + wlen = n+1; + } + w->data[n++] = carry; + } + carry = _mpd_shortadd(w->data, n, u[ulen]); + if (carry) { + if (n >= wlen) { + if (!mpd_qresize(w, n+1, status)) { + return SIZE_MAX; + } + wlen = n+1; + } + w->data[n++] = carry; + } + } + + return n; +} + +/* target base wbase < source base ubase */ +static size_t +_baseconv_to_smaller(uint32_t **w, size_t wlen, uint32_t wbase, + mpd_uint_t *u, mpd_ssize_t ulen, mpd_uint_t ubase) +{ + size_t n = 0; + + assert(wlen > 0 && ulen > 0); + assert(wbase < ubase); + + do { + if (n >= wlen) { + if (!mpd_resize_u32(w, n+1)) { + return SIZE_MAX; + } + wlen = n+1; + } + (*w)[n++] = (uint32_t)_mpd_shortdiv_b(u, u, ulen, wbase, ubase); + /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */ + ulen = _mpd_real_size(u, ulen); + + } while (u[ulen-1] != 0); + + return n; +} + +#ifdef CONFIG_32 +/* target base 'wbase' == source base 'ubase' */ +static size_t +_copy_equal_base(uint32_t **w, size_t wlen, + const uint32_t *u, size_t ulen) +{ + if (wlen < ulen) { + if (!mpd_resize_u32(w, ulen)) { + return SIZE_MAX; + } + } + + memcpy(*w, u, ulen * (sizeof **w)); + return ulen; +} + +/* target base 'wbase' > source base 'ubase' */ +static size_t +_baseconv_to_larger(uint32_t **w, size_t wlen, mpd_uint_t wbase, + const mpd_uint_t *u, size_t ulen, mpd_uint_t ubase) +{ + size_t n = 0; + mpd_uint_t carry; + + assert(wlen > 0 && ulen > 0); + assert(ubase < wbase); + + (*w)[n++] = u[--ulen]; + while (--ulen != SIZE_MAX) { + carry = _mpd_shortmul_b(*w, *w, n, ubase, wbase); + if (carry) { + if (n >= wlen) { + if (!mpd_resize_u32(w, n+1)) { + return SIZE_MAX; + } + wlen = n+1; + } + (*w)[n++] = carry; + } + carry = _mpd_shortadd_b(*w, n, u[ulen], wbase); + if (carry) { + if (n >= wlen) { + if (!mpd_resize_u32(w, n+1)) { + return SIZE_MAX; + } + wlen = n+1; + } + (*w)[n++] = carry; + } + } + + return n; +} + +/* target base wbase < source base ubase */ +static size_t +_coeff_from_larger_base(mpd_t *w, size_t wlen, mpd_uint_t wbase, + mpd_uint_t *u, mpd_ssize_t ulen, mpd_uint_t ubase, + uint32_t *status) +{ + size_t n = 0; + + assert(wlen > 0 && ulen > 0); + assert(wbase < ubase); + + do { + if (n >= wlen) { + if (!mpd_qresize(w, n+1, status)) { + return SIZE_MAX; + } + wlen = n+1; + } + w->data[n++] = (uint32_t)_mpd_shortdiv_b(u, u, ulen, wbase, ubase); + /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */ + ulen = _mpd_real_size(u, ulen); + + } while (u[ulen-1] != 0); + + return n; +} +#endif + +/* target base 'wbase' > source base 'ubase' */ +static size_t +_coeff_from_smaller_base(mpd_t *w, mpd_ssize_t wlen, mpd_uint_t wbase, + const uint32_t *u, size_t ulen, mpd_uint_t ubase, + uint32_t *status) +{ + mpd_ssize_t n = 0; + mpd_uint_t carry; + + assert(wlen > 0 && ulen > 0); + assert(wbase > ubase); + + w->data[n++] = u[--ulen]; + while (--ulen != SIZE_MAX) { + carry = _mpd_shortmul_b(w->data, w->data, n, ubase, wbase); + if (carry) { + if (n >= wlen) { + if (!mpd_qresize(w, n+1, status)) { + return SIZE_MAX; + } + wlen = n+1; + } + w->data[n++] = carry; + } + carry = _mpd_shortadd_b(w->data, n, u[ulen], wbase); + if (carry) { + if (n >= wlen) { + if (!mpd_qresize(w, n+1, status)) { + return SIZE_MAX; + } + wlen = n+1; + } + w->data[n++] = carry; + } + } + + return n; +} + +/* + * Convert an integer mpd_t to a multiprecision integer with base <= 2**16. + * The least significant word of the result is (*rdata)[0]. + * + * If rdata is NULL, space is allocated by the function and rlen is irrelevant. + * In case of an error any allocated storage is freed and rdata is set back to + * NULL. + * + * If rdata is non-NULL, it MUST be allocated by one of libmpdec's allocation + * functions and rlen MUST be correct. If necessary, the function will resize + * rdata. In case of an error the caller must free rdata. + * + * Return value: In case of success, the exact length of rdata, SIZE_MAX + * otherwise. + */ +size_t +mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t rbase, + const mpd_t *src, uint32_t *status) +{ + MPD_NEW_STATIC(tsrc,0,0,0,0); + int alloc = 0; /* rdata == NULL */ + size_t n; + + assert(rbase <= (1U<<16)); + + if (mpd_isspecial(src) || !_mpd_isint(src)) { + *status |= MPD_Invalid_operation; + return SIZE_MAX; + } + + if (*rdata == NULL) { + rlen = mpd_sizeinbase(src, rbase); + if (rlen == SIZE_MAX) { + *status |= MPD_Invalid_operation; + return SIZE_MAX; + } + *rdata = mpd_alloc(rlen, sizeof **rdata); + if (*rdata == NULL) { + goto malloc_error; + } + alloc = 1; + } + + if (mpd_iszero(src)) { + **rdata = 0; + return 1; + } + + if (src->exp >= 0) { + if (!mpd_qshiftl(&tsrc, src, src->exp, status)) { + goto malloc_error; + } + } + else { + if (mpd_qshiftr(&tsrc, src, -src->exp, status) == MPD_UINT_MAX) { + goto malloc_error; + } + } + + n = _baseconv_to_u16(rdata, rlen, rbase, tsrc.data, tsrc.len); + if (n == SIZE_MAX) { + goto malloc_error; + } + + +out: + mpd_del(&tsrc); + return n; + +malloc_error: + if (alloc) { + mpd_free(*rdata); + *rdata = NULL; + } + n = SIZE_MAX; + *status |= MPD_Malloc_error; + goto out; +} + +/* + * Convert an integer mpd_t to a multiprecision integer with base<=UINT32_MAX. + * The least significant word of the result is (*rdata)[0]. + * + * If rdata is NULL, space is allocated by the function and rlen is irrelevant. + * In case of an error any allocated storage is freed and rdata is set back to + * NULL. + * + * If rdata is non-NULL, it MUST be allocated by one of libmpdec's allocation + * functions and rlen MUST be correct. If necessary, the function will resize + * rdata. In case of an error the caller must free rdata. + * + * Return value: In case of success, the exact length of rdata, SIZE_MAX + * otherwise. + */ +size_t +mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t rbase, + const mpd_t *src, uint32_t *status) +{ + MPD_NEW_STATIC(tsrc,0,0,0,0); + int alloc = 0; /* rdata == NULL */ + size_t n; + + if (mpd_isspecial(src) || !_mpd_isint(src)) { + *status |= MPD_Invalid_operation; + return SIZE_MAX; + } + + if (*rdata == NULL) { + rlen = mpd_sizeinbase(src, rbase); + if (rlen == SIZE_MAX) { + *status |= MPD_Invalid_operation; + return SIZE_MAX; + } + *rdata = mpd_alloc(rlen, sizeof **rdata); + if (*rdata == NULL) { + goto malloc_error; + } + alloc = 1; + } + + if (mpd_iszero(src)) { + **rdata = 0; + return 1; + } + + if (src->exp >= 0) { + if (!mpd_qshiftl(&tsrc, src, src->exp, status)) { + goto malloc_error; + } + } + else { + if (mpd_qshiftr(&tsrc, src, -src->exp, status) == MPD_UINT_MAX) { + goto malloc_error; + } + } + +#ifdef CONFIG_64 + n = _baseconv_to_smaller(rdata, rlen, rbase, + tsrc.data, tsrc.len, MPD_RADIX); +#else + if (rbase == MPD_RADIX) { + n = _copy_equal_base(rdata, rlen, tsrc.data, tsrc.len); + } + else if (rbase < MPD_RADIX) { + n = _baseconv_to_smaller(rdata, rlen, rbase, + tsrc.data, tsrc.len, MPD_RADIX); + } + else { + n = _baseconv_to_larger(rdata, rlen, rbase, + tsrc.data, tsrc.len, MPD_RADIX); + } +#endif + + if (n == SIZE_MAX) { + goto malloc_error; + } + + +out: + mpd_del(&tsrc); + return n; + +malloc_error: + if (alloc) { + mpd_free(*rdata); + *rdata = NULL; + } + n = SIZE_MAX; + *status |= MPD_Malloc_error; + goto out; +} + + +/* + * Converts a multiprecision integer with base <= UINT16_MAX+1 to an mpd_t. + * The least significant word of the source is srcdata[0]. + */ +void +mpd_qimport_u16(mpd_t *result, + const uint16_t *srcdata, size_t srclen, + uint8_t srcsign, uint32_t srcbase, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_uint_t *usrc; /* uint16_t src copied to an mpd_uint_t array */ + mpd_ssize_t rlen; /* length of the result */ + size_t n; + + assert(srclen > 0); + assert(srcbase <= (1U<<16)); + + rlen = _mpd_importsize(srclen, srcbase); + if (rlen == MPD_SSIZE_MAX) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + usrc = mpd_alloc((mpd_size_t)srclen, sizeof *usrc); + if (usrc == NULL) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + for (n = 0; n < srclen; n++) { + usrc[n] = srcdata[n]; + } + + if (!mpd_qresize(result, rlen, status)) { + goto finish; + } + + n = _coeff_from_u16(result, rlen, usrc, srclen, srcbase, status); + if (n == SIZE_MAX) { + goto finish; + } + + mpd_set_flags(result, srcsign); + result->exp = 0; + result->len = n; + mpd_setdigits(result); + + mpd_qresize(result, result->len, status); + mpd_qfinalize(result, ctx, status); + + +finish: + mpd_free(usrc); +} + +/* + * Converts a multiprecision integer with base <= UINT32_MAX to an mpd_t. + * The least significant word of the source is srcdata[0]. + */ +void +mpd_qimport_u32(mpd_t *result, + const uint32_t *srcdata, size_t srclen, + uint8_t srcsign, uint32_t srcbase, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_ssize_t rlen; /* length of the result */ + size_t n; + + assert(srclen > 0); + + rlen = _mpd_importsize(srclen, srcbase); + if (rlen == MPD_SSIZE_MAX) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + + if (!mpd_qresize(result, rlen, status)) { + return; + } + +#ifdef CONFIG_64 + n = _coeff_from_smaller_base(result, rlen, MPD_RADIX, + srcdata, srclen, srcbase, + status); +#else + if (srcbase == MPD_RADIX) { + if (!mpd_qresize(result, srclen, status)) { + return; + } + memcpy(result->data, srcdata, srclen * (sizeof *srcdata)); + n = srclen; + } + else if (srcbase < MPD_RADIX) { + n = _coeff_from_smaller_base(result, rlen, MPD_RADIX, + srcdata, srclen, srcbase, + status); + } + else { + mpd_uint_t *usrc = mpd_alloc((mpd_size_t)srclen, sizeof *usrc); + if (usrc == NULL) { + mpd_seterror(result, MPD_Malloc_error, status); + return; + } + for (n = 0; n < srclen; n++) { + usrc[n] = srcdata[n]; + } + + n = _coeff_from_larger_base(result, rlen, MPD_RADIX, + usrc, (mpd_ssize_t)srclen, srcbase, + status); + mpd_free(usrc); + } +#endif + + if (n == SIZE_MAX) { + return; + } + + mpd_set_flags(result, srcsign); + result->exp = 0; + result->len = n; + mpd_setdigits(result); + + mpd_qresize(result, result->len, status); + mpd_qfinalize(result, ctx, status); +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h index f66f6e59207..547d32bec48 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/mpdecimal.h @@ -1,55 +1,55 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_MPDECIMAL_H_ #define LIBMPDEC_MPDECIMAL_H_ - - + + #ifndef _MSC_VER #include "pyconfig.h" #endif -#ifdef __cplusplus +#ifdef __cplusplus #include #include #include #include #include -extern "C" { +extern "C" { #else #include #include #include #include #include -#endif - - +#endif + + #if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) && \ defined(__GNUC__) && __GNUC__ >= 4 && !defined(__INTEL_COMPILER) #define MPD_PRAGMA(x) _Pragma(x) @@ -59,775 +59,775 @@ extern "C" { #define MPD_PRAGMA(x) #define MPD_HIDE_SYMBOLS_START #define MPD_HIDE_SYMBOLS_END -#endif - +#endif + #if defined(_MSC_VER) - #include "vccompat.h" - #define EXTINLINE extern inline -#else - #define EXTINLINE -#endif - - -/* This header file is internal for the purpose of building _decimal.so. - * All symbols should have local scope in the DSO. */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -#if !defined(LEGACY_COMPILER) - #if !defined(UINT64_MAX) - /* The following #error is just a warning. If the compiler indeed does - * not have uint64_t, it is perfectly safe to comment out the #error. */ - #error "Warning: Compiler without uint64_t. Comment out this line." - #define LEGACY_COMPILER - #endif -#endif - - -/******************************************************************************/ -/* Version */ -/******************************************************************************/ - -#define MPD_MAJOR_VERSION 2 + #include "vccompat.h" + #define EXTINLINE extern inline +#else + #define EXTINLINE +#endif + + +/* This header file is internal for the purpose of building _decimal.so. + * All symbols should have local scope in the DSO. */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +#if !defined(LEGACY_COMPILER) + #if !defined(UINT64_MAX) + /* The following #error is just a warning. If the compiler indeed does + * not have uint64_t, it is perfectly safe to comment out the #error. */ + #error "Warning: Compiler without uint64_t. Comment out this line." + #define LEGACY_COMPILER + #endif +#endif + + +/******************************************************************************/ +/* Version */ +/******************************************************************************/ + +#define MPD_MAJOR_VERSION 2 #define MPD_MINOR_VERSION 5 #define MPD_MICRO_VERSION 0 - + #define MPD_VERSION "2.5.0" - -#define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \ - (MPD_MINOR_VERSION << 16) | \ - (MPD_MICRO_VERSION << 8)) - -const char *mpd_version(void); - - -/******************************************************************************/ -/* Configuration */ -/******************************************************************************/ - -#if 1 - #if defined(CONFIG_64) || defined(CONFIG_32) - #error "cannot use CONFIG_64 or CONFIG_32 with UNIVERSAL." - #endif + +#define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \ + (MPD_MINOR_VERSION << 16) | \ + (MPD_MICRO_VERSION << 8)) + +const char *mpd_version(void); + + +/******************************************************************************/ +/* Configuration */ +/******************************************************************************/ + +#if 1 + #if defined(CONFIG_64) || defined(CONFIG_32) + #error "cannot use CONFIG_64 or CONFIG_32 with UNIVERSAL." + #endif #if defined(__powerpc64__) || defined(_M_AMD64) || defined(__aarch64__) #define CONFIG_64 #define ANSI #elif defined(__powerpc__) - #define CONFIG_32 - #define ANSI - #elif defined(__i386__) || defined(_M_IX86) - #define CONFIG_32 - #define ANSI - #elif defined(__x86_64__) - #define CONFIG_64 - #define ASM + #define CONFIG_32 + #define ANSI + #elif defined(__i386__) || defined(_M_IX86) + #define CONFIG_32 + #define ANSI + #elif defined(__x86_64__) + #define CONFIG_64 + #define ASM #elif defined(__arm64__) #define CONFIG_64 #define ANSI - #else - #error "unknown architecture for universal build." - #endif -#endif - - -/* BEGIN CONFIG_64 */ -#if defined(CONFIG_64) -/* types for modular and base arithmetic */ -#define MPD_UINT_MAX UINT64_MAX -#define MPD_BITS_PER_UINT 64 -typedef uint64_t mpd_uint_t; /* unsigned mod type */ - -#define MPD_SIZE_MAX SIZE_MAX -typedef size_t mpd_size_t; /* unsigned size type */ - -/* type for exp, digits, len, prec */ -#define MPD_SSIZE_MAX INT64_MAX -#define MPD_SSIZE_MIN INT64_MIN -typedef int64_t mpd_ssize_t; -#define _mpd_strtossize strtoll - -/* decimal arithmetic */ -#define MPD_RADIX 10000000000000000000ULL /* 10**19 */ -#define MPD_RDIGITS 19 -#define MPD_MAX_POW10 19 -#define MPD_EXPDIGITS 19 /* MPD_EXPDIGITS <= MPD_RDIGITS+1 */ - -#define MPD_MAXTRANSFORM_2N 4294967296ULL /* 2**32 */ -#define MPD_MAX_PREC 999999999999999999LL -#define MPD_MAX_PREC_LOG2 64 -#define MPD_ELIMIT 1000000000000000000LL -#define MPD_MAX_EMAX 999999999999999999LL /* ELIMIT-1 */ -#define MPD_MIN_EMIN (-999999999999999999LL) /* -EMAX */ -#define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1)) -#define MPD_EXP_INF 2000000000000000001LL -#define MPD_EXP_CLAMP (-4000000000000000001LL) -#define MPD_MAXIMPORT 105263157894736842L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */ - -/* conversion specifiers */ -#define PRI_mpd_uint_t PRIu64 -#define PRI_mpd_ssize_t PRIi64 -/* END CONFIG_64 */ - - -/* BEGIN CONFIG_32 */ -#elif defined(CONFIG_32) -/* types for modular and base arithmetic */ -#define MPD_UINT_MAX UINT32_MAX -#define MPD_BITS_PER_UINT 32 -typedef uint32_t mpd_uint_t; /* unsigned mod type */ - -#ifndef LEGACY_COMPILER -#define MPD_UUINT_MAX UINT64_MAX -typedef uint64_t mpd_uuint_t; /* double width unsigned mod type */ -#endif - -#define MPD_SIZE_MAX SIZE_MAX -typedef size_t mpd_size_t; /* unsigned size type */ - -/* type for dec->len, dec->exp, ctx->prec */ -#define MPD_SSIZE_MAX INT32_MAX -#define MPD_SSIZE_MIN INT32_MIN -typedef int32_t mpd_ssize_t; -#define _mpd_strtossize strtol - -/* decimal arithmetic */ -#define MPD_RADIX 1000000000UL /* 10**9 */ -#define MPD_RDIGITS 9 -#define MPD_MAX_POW10 9 -#define MPD_EXPDIGITS 10 /* MPD_EXPDIGITS <= MPD_RDIGITS+1 */ - -#define MPD_MAXTRANSFORM_2N 33554432UL /* 2**25 */ -#define MPD_MAX_PREC 425000000L -#define MPD_MAX_PREC_LOG2 32 -#define MPD_ELIMIT 425000001L -#define MPD_MAX_EMAX 425000000L /* ELIMIT-1 */ -#define MPD_MIN_EMIN (-425000000L) /* -EMAX */ -#define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1)) -#define MPD_EXP_INF 1000000001L /* allows for emax=999999999 in the tests */ -#define MPD_EXP_CLAMP (-2000000001L) /* allows for emin=-999999999 in the tests */ -#define MPD_MAXIMPORT 94444445L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */ - -/* conversion specifiers */ -#define PRI_mpd_uint_t PRIu32 -#define PRI_mpd_ssize_t PRIi32 -/* END CONFIG_32 */ - -#else - #error "define CONFIG_64 or CONFIG_32" -#endif -/* END CONFIG */ - - -#if MPD_SIZE_MAX != MPD_UINT_MAX - #error "unsupported platform: need mpd_size_t == mpd_uint_t" -#endif - - -/******************************************************************************/ -/* Context */ -/******************************************************************************/ - -enum { - MPD_ROUND_UP, /* round away from 0 */ - MPD_ROUND_DOWN, /* round toward 0 (truncate) */ - MPD_ROUND_CEILING, /* round toward +infinity */ - MPD_ROUND_FLOOR, /* round toward -infinity */ - MPD_ROUND_HALF_UP, /* 0.5 is rounded up */ - MPD_ROUND_HALF_DOWN, /* 0.5 is rounded down */ - MPD_ROUND_HALF_EVEN, /* 0.5 is rounded to even */ - MPD_ROUND_05UP, /* round zero or five away from 0 */ - MPD_ROUND_TRUNC, /* truncate, but set infinity */ - MPD_ROUND_GUARD -}; - -enum { MPD_CLAMP_DEFAULT, MPD_CLAMP_IEEE_754, MPD_CLAMP_GUARD }; - -extern const char *mpd_round_string[MPD_ROUND_GUARD]; -extern const char *mpd_clamp_string[MPD_CLAMP_GUARD]; - - -typedef struct mpd_context_t { - mpd_ssize_t prec; /* precision */ - mpd_ssize_t emax; /* max positive exp */ - mpd_ssize_t emin; /* min negative exp */ - uint32_t traps; /* status events that should be trapped */ - uint32_t status; /* status flags */ - uint32_t newtrap; /* set by mpd_addstatus_raise() */ - int round; /* rounding mode */ - int clamp; /* clamp mode */ - int allcr; /* all functions correctly rounded */ -} mpd_context_t; - - -/* Status flags */ -#define MPD_Clamped 0x00000001U -#define MPD_Conversion_syntax 0x00000002U -#define MPD_Division_by_zero 0x00000004U -#define MPD_Division_impossible 0x00000008U -#define MPD_Division_undefined 0x00000010U -#define MPD_Fpu_error 0x00000020U -#define MPD_Inexact 0x00000040U -#define MPD_Invalid_context 0x00000080U -#define MPD_Invalid_operation 0x00000100U -#define MPD_Malloc_error 0x00000200U -#define MPD_Not_implemented 0x00000400U -#define MPD_Overflow 0x00000800U -#define MPD_Rounded 0x00001000U -#define MPD_Subnormal 0x00002000U -#define MPD_Underflow 0x00004000U -#define MPD_Max_status (0x00008000U-1U) - -/* Conditions that result in an IEEE 754 exception */ -#define MPD_IEEE_Invalid_operation (MPD_Conversion_syntax | \ - MPD_Division_impossible | \ - MPD_Division_undefined | \ - MPD_Fpu_error | \ - MPD_Invalid_context | \ - MPD_Invalid_operation | \ - MPD_Malloc_error) \ - -/* Errors that require the result of an operation to be set to NaN */ -#define MPD_Errors (MPD_IEEE_Invalid_operation | \ - MPD_Division_by_zero) - -/* Default traps */ -#define MPD_Traps (MPD_IEEE_Invalid_operation | \ - MPD_Division_by_zero | \ - MPD_Overflow | \ - MPD_Underflow) - -/* Official name */ -#define MPD_Insufficient_storage MPD_Malloc_error - -/* IEEE 754 interchange format contexts */ -#define MPD_IEEE_CONTEXT_MAX_BITS 512 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */ -#define MPD_DECIMAL32 32 -#define MPD_DECIMAL64 64 -#define MPD_DECIMAL128 128 - - -#define MPD_MINALLOC_MIN 2 -#define MPD_MINALLOC_MAX 64 -extern mpd_ssize_t MPD_MINALLOC; -extern void (* mpd_traphandler)(mpd_context_t *); -void mpd_dflt_traphandler(mpd_context_t *); - -void mpd_setminalloc(mpd_ssize_t n); -void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec); - -void mpd_maxcontext(mpd_context_t *ctx); -void mpd_defaultcontext(mpd_context_t *ctx); -void mpd_basiccontext(mpd_context_t *ctx); -int mpd_ieee_context(mpd_context_t *ctx, int bits); - -mpd_ssize_t mpd_getprec(const mpd_context_t *ctx); -mpd_ssize_t mpd_getemax(const mpd_context_t *ctx); -mpd_ssize_t mpd_getemin(const mpd_context_t *ctx); -int mpd_getround(const mpd_context_t *ctx); -uint32_t mpd_gettraps(const mpd_context_t *ctx); -uint32_t mpd_getstatus(const mpd_context_t *ctx); -int mpd_getclamp(const mpd_context_t *ctx); -int mpd_getcr(const mpd_context_t *ctx); - -int mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec); -int mpd_qsetemax(mpd_context_t *ctx, mpd_ssize_t emax); -int mpd_qsetemin(mpd_context_t *ctx, mpd_ssize_t emin); -int mpd_qsetround(mpd_context_t *ctx, int newround); -int mpd_qsettraps(mpd_context_t *ctx, uint32_t flags); -int mpd_qsetstatus(mpd_context_t *ctx, uint32_t flags); -int mpd_qsetclamp(mpd_context_t *ctx, int c); -int mpd_qsetcr(mpd_context_t *ctx, int c); -void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags); - - -/******************************************************************************/ -/* Decimal Arithmetic */ -/******************************************************************************/ - -/* mpd_t flags */ -#define MPD_POS ((uint8_t)0) -#define MPD_NEG ((uint8_t)1) -#define MPD_INF ((uint8_t)2) -#define MPD_NAN ((uint8_t)4) -#define MPD_SNAN ((uint8_t)8) -#define MPD_SPECIAL (MPD_INF|MPD_NAN|MPD_SNAN) -#define MPD_STATIC ((uint8_t)16) -#define MPD_STATIC_DATA ((uint8_t)32) -#define MPD_SHARED_DATA ((uint8_t)64) -#define MPD_CONST_DATA ((uint8_t)128) -#define MPD_DATAFLAGS (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA) - -/* mpd_t */ -typedef struct mpd_t { - uint8_t flags; - mpd_ssize_t exp; - mpd_ssize_t digits; - mpd_ssize_t len; - mpd_ssize_t alloc; - mpd_uint_t *data; -} mpd_t; - - -typedef unsigned char uchar; - - -/******************************************************************************/ -/* Quiet, thread-safe functions */ -/******************************************************************************/ - -/* format specification */ -typedef struct mpd_spec_t { - mpd_ssize_t min_width; /* minimum field width */ - mpd_ssize_t prec; /* fraction digits or significant digits */ - char type; /* conversion specifier */ - char align; /* alignment */ - char sign; /* sign printing/alignment */ - char fill[5]; /* fill character */ - const char *dot; /* decimal point */ - const char *sep; /* thousands separator */ - const char *grouping; /* grouping of digits */ -} mpd_spec_t; - -/* output to a string */ -char *mpd_to_sci(const mpd_t *dec, int fmt); -char *mpd_to_eng(const mpd_t *dec, int fmt); -mpd_ssize_t mpd_to_sci_size(char **res, const mpd_t *dec, int fmt); -mpd_ssize_t mpd_to_eng_size(char **res, const mpd_t *dec, int fmt); -int mpd_validate_lconv(mpd_spec_t *spec); -int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps); -char *mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status); -char *mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, uint32_t *status); - -#define MPD_NUM_FLAGS 15 -#define MPD_MAX_FLAG_STRING 208 -#define MPD_MAX_FLAG_LIST (MPD_MAX_FLAG_STRING+18) -#define MPD_MAX_SIGNAL_LIST 121 -int mpd_snprint_flags(char *dest, int nmemb, uint32_t flags); -int mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char *flag_string[]); -int mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_string[]); - -/* output to a file */ -void mpd_fprint(FILE *file, const mpd_t *dec); -void mpd_print(const mpd_t *dec); - -/* assignment from a string */ -void mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, uint32_t *status); + #else + #error "unknown architecture for universal build." + #endif +#endif + + +/* BEGIN CONFIG_64 */ +#if defined(CONFIG_64) +/* types for modular and base arithmetic */ +#define MPD_UINT_MAX UINT64_MAX +#define MPD_BITS_PER_UINT 64 +typedef uint64_t mpd_uint_t; /* unsigned mod type */ + +#define MPD_SIZE_MAX SIZE_MAX +typedef size_t mpd_size_t; /* unsigned size type */ + +/* type for exp, digits, len, prec */ +#define MPD_SSIZE_MAX INT64_MAX +#define MPD_SSIZE_MIN INT64_MIN +typedef int64_t mpd_ssize_t; +#define _mpd_strtossize strtoll + +/* decimal arithmetic */ +#define MPD_RADIX 10000000000000000000ULL /* 10**19 */ +#define MPD_RDIGITS 19 +#define MPD_MAX_POW10 19 +#define MPD_EXPDIGITS 19 /* MPD_EXPDIGITS <= MPD_RDIGITS+1 */ + +#define MPD_MAXTRANSFORM_2N 4294967296ULL /* 2**32 */ +#define MPD_MAX_PREC 999999999999999999LL +#define MPD_MAX_PREC_LOG2 64 +#define MPD_ELIMIT 1000000000000000000LL +#define MPD_MAX_EMAX 999999999999999999LL /* ELIMIT-1 */ +#define MPD_MIN_EMIN (-999999999999999999LL) /* -EMAX */ +#define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1)) +#define MPD_EXP_INF 2000000000000000001LL +#define MPD_EXP_CLAMP (-4000000000000000001LL) +#define MPD_MAXIMPORT 105263157894736842L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */ + +/* conversion specifiers */ +#define PRI_mpd_uint_t PRIu64 +#define PRI_mpd_ssize_t PRIi64 +/* END CONFIG_64 */ + + +/* BEGIN CONFIG_32 */ +#elif defined(CONFIG_32) +/* types for modular and base arithmetic */ +#define MPD_UINT_MAX UINT32_MAX +#define MPD_BITS_PER_UINT 32 +typedef uint32_t mpd_uint_t; /* unsigned mod type */ + +#ifndef LEGACY_COMPILER +#define MPD_UUINT_MAX UINT64_MAX +typedef uint64_t mpd_uuint_t; /* double width unsigned mod type */ +#endif + +#define MPD_SIZE_MAX SIZE_MAX +typedef size_t mpd_size_t; /* unsigned size type */ + +/* type for dec->len, dec->exp, ctx->prec */ +#define MPD_SSIZE_MAX INT32_MAX +#define MPD_SSIZE_MIN INT32_MIN +typedef int32_t mpd_ssize_t; +#define _mpd_strtossize strtol + +/* decimal arithmetic */ +#define MPD_RADIX 1000000000UL /* 10**9 */ +#define MPD_RDIGITS 9 +#define MPD_MAX_POW10 9 +#define MPD_EXPDIGITS 10 /* MPD_EXPDIGITS <= MPD_RDIGITS+1 */ + +#define MPD_MAXTRANSFORM_2N 33554432UL /* 2**25 */ +#define MPD_MAX_PREC 425000000L +#define MPD_MAX_PREC_LOG2 32 +#define MPD_ELIMIT 425000001L +#define MPD_MAX_EMAX 425000000L /* ELIMIT-1 */ +#define MPD_MIN_EMIN (-425000000L) /* -EMAX */ +#define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1)) +#define MPD_EXP_INF 1000000001L /* allows for emax=999999999 in the tests */ +#define MPD_EXP_CLAMP (-2000000001L) /* allows for emin=-999999999 in the tests */ +#define MPD_MAXIMPORT 94444445L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */ + +/* conversion specifiers */ +#define PRI_mpd_uint_t PRIu32 +#define PRI_mpd_ssize_t PRIi32 +/* END CONFIG_32 */ + +#else + #error "define CONFIG_64 or CONFIG_32" +#endif +/* END CONFIG */ + + +#if MPD_SIZE_MAX != MPD_UINT_MAX + #error "unsupported platform: need mpd_size_t == mpd_uint_t" +#endif + + +/******************************************************************************/ +/* Context */ +/******************************************************************************/ + +enum { + MPD_ROUND_UP, /* round away from 0 */ + MPD_ROUND_DOWN, /* round toward 0 (truncate) */ + MPD_ROUND_CEILING, /* round toward +infinity */ + MPD_ROUND_FLOOR, /* round toward -infinity */ + MPD_ROUND_HALF_UP, /* 0.5 is rounded up */ + MPD_ROUND_HALF_DOWN, /* 0.5 is rounded down */ + MPD_ROUND_HALF_EVEN, /* 0.5 is rounded to even */ + MPD_ROUND_05UP, /* round zero or five away from 0 */ + MPD_ROUND_TRUNC, /* truncate, but set infinity */ + MPD_ROUND_GUARD +}; + +enum { MPD_CLAMP_DEFAULT, MPD_CLAMP_IEEE_754, MPD_CLAMP_GUARD }; + +extern const char *mpd_round_string[MPD_ROUND_GUARD]; +extern const char *mpd_clamp_string[MPD_CLAMP_GUARD]; + + +typedef struct mpd_context_t { + mpd_ssize_t prec; /* precision */ + mpd_ssize_t emax; /* max positive exp */ + mpd_ssize_t emin; /* min negative exp */ + uint32_t traps; /* status events that should be trapped */ + uint32_t status; /* status flags */ + uint32_t newtrap; /* set by mpd_addstatus_raise() */ + int round; /* rounding mode */ + int clamp; /* clamp mode */ + int allcr; /* all functions correctly rounded */ +} mpd_context_t; + + +/* Status flags */ +#define MPD_Clamped 0x00000001U +#define MPD_Conversion_syntax 0x00000002U +#define MPD_Division_by_zero 0x00000004U +#define MPD_Division_impossible 0x00000008U +#define MPD_Division_undefined 0x00000010U +#define MPD_Fpu_error 0x00000020U +#define MPD_Inexact 0x00000040U +#define MPD_Invalid_context 0x00000080U +#define MPD_Invalid_operation 0x00000100U +#define MPD_Malloc_error 0x00000200U +#define MPD_Not_implemented 0x00000400U +#define MPD_Overflow 0x00000800U +#define MPD_Rounded 0x00001000U +#define MPD_Subnormal 0x00002000U +#define MPD_Underflow 0x00004000U +#define MPD_Max_status (0x00008000U-1U) + +/* Conditions that result in an IEEE 754 exception */ +#define MPD_IEEE_Invalid_operation (MPD_Conversion_syntax | \ + MPD_Division_impossible | \ + MPD_Division_undefined | \ + MPD_Fpu_error | \ + MPD_Invalid_context | \ + MPD_Invalid_operation | \ + MPD_Malloc_error) \ + +/* Errors that require the result of an operation to be set to NaN */ +#define MPD_Errors (MPD_IEEE_Invalid_operation | \ + MPD_Division_by_zero) + +/* Default traps */ +#define MPD_Traps (MPD_IEEE_Invalid_operation | \ + MPD_Division_by_zero | \ + MPD_Overflow | \ + MPD_Underflow) + +/* Official name */ +#define MPD_Insufficient_storage MPD_Malloc_error + +/* IEEE 754 interchange format contexts */ +#define MPD_IEEE_CONTEXT_MAX_BITS 512 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */ +#define MPD_DECIMAL32 32 +#define MPD_DECIMAL64 64 +#define MPD_DECIMAL128 128 + + +#define MPD_MINALLOC_MIN 2 +#define MPD_MINALLOC_MAX 64 +extern mpd_ssize_t MPD_MINALLOC; +extern void (* mpd_traphandler)(mpd_context_t *); +void mpd_dflt_traphandler(mpd_context_t *); + +void mpd_setminalloc(mpd_ssize_t n); +void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec); + +void mpd_maxcontext(mpd_context_t *ctx); +void mpd_defaultcontext(mpd_context_t *ctx); +void mpd_basiccontext(mpd_context_t *ctx); +int mpd_ieee_context(mpd_context_t *ctx, int bits); + +mpd_ssize_t mpd_getprec(const mpd_context_t *ctx); +mpd_ssize_t mpd_getemax(const mpd_context_t *ctx); +mpd_ssize_t mpd_getemin(const mpd_context_t *ctx); +int mpd_getround(const mpd_context_t *ctx); +uint32_t mpd_gettraps(const mpd_context_t *ctx); +uint32_t mpd_getstatus(const mpd_context_t *ctx); +int mpd_getclamp(const mpd_context_t *ctx); +int mpd_getcr(const mpd_context_t *ctx); + +int mpd_qsetprec(mpd_context_t *ctx, mpd_ssize_t prec); +int mpd_qsetemax(mpd_context_t *ctx, mpd_ssize_t emax); +int mpd_qsetemin(mpd_context_t *ctx, mpd_ssize_t emin); +int mpd_qsetround(mpd_context_t *ctx, int newround); +int mpd_qsettraps(mpd_context_t *ctx, uint32_t flags); +int mpd_qsetstatus(mpd_context_t *ctx, uint32_t flags); +int mpd_qsetclamp(mpd_context_t *ctx, int c); +int mpd_qsetcr(mpd_context_t *ctx, int c); +void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags); + + +/******************************************************************************/ +/* Decimal Arithmetic */ +/******************************************************************************/ + +/* mpd_t flags */ +#define MPD_POS ((uint8_t)0) +#define MPD_NEG ((uint8_t)1) +#define MPD_INF ((uint8_t)2) +#define MPD_NAN ((uint8_t)4) +#define MPD_SNAN ((uint8_t)8) +#define MPD_SPECIAL (MPD_INF|MPD_NAN|MPD_SNAN) +#define MPD_STATIC ((uint8_t)16) +#define MPD_STATIC_DATA ((uint8_t)32) +#define MPD_SHARED_DATA ((uint8_t)64) +#define MPD_CONST_DATA ((uint8_t)128) +#define MPD_DATAFLAGS (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA) + +/* mpd_t */ +typedef struct mpd_t { + uint8_t flags; + mpd_ssize_t exp; + mpd_ssize_t digits; + mpd_ssize_t len; + mpd_ssize_t alloc; + mpd_uint_t *data; +} mpd_t; + + +typedef unsigned char uchar; + + +/******************************************************************************/ +/* Quiet, thread-safe functions */ +/******************************************************************************/ + +/* format specification */ +typedef struct mpd_spec_t { + mpd_ssize_t min_width; /* minimum field width */ + mpd_ssize_t prec; /* fraction digits or significant digits */ + char type; /* conversion specifier */ + char align; /* alignment */ + char sign; /* sign printing/alignment */ + char fill[5]; /* fill character */ + const char *dot; /* decimal point */ + const char *sep; /* thousands separator */ + const char *grouping; /* grouping of digits */ +} mpd_spec_t; + +/* output to a string */ +char *mpd_to_sci(const mpd_t *dec, int fmt); +char *mpd_to_eng(const mpd_t *dec, int fmt); +mpd_ssize_t mpd_to_sci_size(char **res, const mpd_t *dec, int fmt); +mpd_ssize_t mpd_to_eng_size(char **res, const mpd_t *dec, int fmt); +int mpd_validate_lconv(mpd_spec_t *spec); +int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps); +char *mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status); +char *mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, uint32_t *status); + +#define MPD_NUM_FLAGS 15 +#define MPD_MAX_FLAG_STRING 208 +#define MPD_MAX_FLAG_LIST (MPD_MAX_FLAG_STRING+18) +#define MPD_MAX_SIGNAL_LIST 121 +int mpd_snprint_flags(char *dest, int nmemb, uint32_t flags); +int mpd_lsnprint_flags(char *dest, int nmemb, uint32_t flags, const char *flag_string[]); +int mpd_lsnprint_signals(char *dest, int nmemb, uint32_t flags, const char *signal_string[]); + +/* output to a file */ +void mpd_fprint(FILE *file, const mpd_t *dec); +void mpd_print(const mpd_t *dec); + +/* assignment from a string */ +void mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, uint32_t *status); void mpd_qset_string_exact(mpd_t *dec, const char *s, uint32_t *status); - -/* set to NaN with error flags */ -void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status); -/* set a special with sign and type */ -void mpd_setspecial(mpd_t *dec, uint8_t sign, uint8_t type); -/* set coefficient to zero or all nines */ -void mpd_zerocoeff(mpd_t *result); -void mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status); - -/* quietly assign a C integer type to an mpd_t */ -void mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status); -#ifndef LEGACY_COMPILER -void mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status); + +/* set to NaN with error flags */ +void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status); +/* set a special with sign and type */ +void mpd_setspecial(mpd_t *dec, uint8_t sign, uint8_t type); +/* set coefficient to zero or all nines */ +void mpd_zerocoeff(mpd_t *result); +void mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status); + +/* quietly assign a C integer type to an mpd_t */ +void mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status); +#ifndef LEGACY_COMPILER +void mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status); void mpd_qset_i64_exact(mpd_t *result, int64_t a, uint32_t *status); void mpd_qset_u64_exact(mpd_t *result, uint64_t a, uint32_t *status); -#endif - -/* quietly assign a C integer type to an mpd_t with a static coefficient */ -void mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status); - -/* quietly get a C integer type from an mpd_t */ -mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status); -mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status); -mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status); - -int32_t mpd_qget_i32(const mpd_t *dec, uint32_t *status); -uint32_t mpd_qget_u32(const mpd_t *dec, uint32_t *status); -#ifndef LEGACY_COMPILER -int64_t mpd_qget_i64(const mpd_t *dec, uint32_t *status); -uint64_t mpd_qget_u64(const mpd_t *dec, uint32_t *status); -#endif - -/* quiet functions */ -int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -int mpd_qcheck_nans(mpd_t *nanresult, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status); - -const char *mpd_class(const mpd_t *a, const mpd_context_t *ctx); - +#endif + +/* quietly assign a C integer type to an mpd_t with a static coefficient */ +void mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status); + +/* quietly get a C integer type from an mpd_t */ +mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status); +mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status); +mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status); + +int32_t mpd_qget_i32(const mpd_t *dec, uint32_t *status); +uint32_t mpd_qget_u32(const mpd_t *dec, uint32_t *status); +#ifndef LEGACY_COMPILER +int64_t mpd_qget_i64(const mpd_t *dec, uint32_t *status); +uint64_t mpd_qget_u64(const mpd_t *dec, uint32_t *status); +#endif + +/* quiet functions */ +int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +int mpd_qcheck_nans(mpd_t *nanresult, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status); + +const char *mpd_class(const mpd_t *a, const mpd_context_t *ctx); + int mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status); int mpd_qcopy_cxx(mpd_t *result, const mpd_t *a); -mpd_t *mpd_qncopy(const mpd_t *a); -int mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status); -int mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status); -int mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status); - -void mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -int mpd_same_quantum(const mpd_t *a, const mpd_t *b); - -void mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -int mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status); -mpd_uint_t mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status); -mpd_uint_t mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n); -void mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx, uint32_t *status); - -int mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status); -int mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -int mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -int mpd_cmp_total(const mpd_t *a, const mpd_t *b); -int mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b); -int mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b); -int mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b); - -void mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); - -void mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status); -void mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status); -void mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_context_t *ctx, uint32_t *status); -void mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, const mpd_context_t *ctx, uint32_t *status); -void mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status); -void mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); - -#ifndef LEGACY_COMPILER -void mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status); -void mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status); -#endif - - -size_t mpd_sizeinbase(const mpd_t *a, uint32_t base); -void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, - uint8_t srcsign, uint32_t srcbase, - const mpd_context_t *ctx, uint32_t *status); -void mpd_qimport_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, - uint8_t srcsign, uint32_t srcbase, - const mpd_context_t *ctx, uint32_t *status); -size_t mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t base, - const mpd_t *src, uint32_t *status); -size_t mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t base, - const mpd_t *src, uint32_t *status); - - -/******************************************************************************/ -/* Signalling functions */ -/******************************************************************************/ - -char *mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx); -void mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx); -void mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx); -size_t mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx); -size_t mpd_export_u32(uint32_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx); -void mpd_finalize(mpd_t *result, mpd_context_t *ctx); -int mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -int mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx); -void mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx); -void mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx); -void mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx); -void mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx); -void mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx); -void mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx); -void mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx); -void mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx); -void mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx); -#ifndef LEGACY_COMPILER -void mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx); -void mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx); -#endif -mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx); -mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx); -mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx); -int32_t mpd_get_i32(const mpd_t *a, mpd_context_t *ctx); -uint32_t mpd_get_u32(const mpd_t *a, mpd_context_t *ctx); -#ifndef LEGACY_COMPILER -int64_t mpd_get_i64(const mpd_t *a, mpd_context_t *ctx); -uint64_t mpd_get_u64(const mpd_t *a, mpd_context_t *ctx); -#endif -void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx); -mpd_uint_t mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx); -void mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx); -void mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -int mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -int mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -int mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx); -void mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx); -void mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx); -void mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx); -void mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx); -void mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx); -void mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx); -void mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx); -void mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx); -void mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx); -void mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx); -void mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx); -void mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, mpd_context_t *ctx); -void mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx); -void mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx); -void mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx); -void mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx); -void mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx); -void mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, mpd_context_t *ctx); -void mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx); -void mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); -void mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); -void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); - -#ifndef LEGACY_COMPILER -void mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); -void mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); -void mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); -void mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); -void mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); -void mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); -void mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); -void mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); -#endif - - -/******************************************************************************/ -/* Configuration specific */ -/******************************************************************************/ - -#ifdef CONFIG_64 -void mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status); -void mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx); -void mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx); -#endif - - -/******************************************************************************/ -/* Get attributes of a decimal */ -/******************************************************************************/ - -EXTINLINE mpd_ssize_t mpd_adjexp(const mpd_t *dec); -EXTINLINE mpd_ssize_t mpd_etiny(const mpd_context_t *ctx); -EXTINLINE mpd_ssize_t mpd_etop(const mpd_context_t *ctx); -EXTINLINE mpd_uint_t mpd_msword(const mpd_t *dec); -EXTINLINE int mpd_word_digits(mpd_uint_t word); -/* most significant digit of a word */ -EXTINLINE mpd_uint_t mpd_msd(mpd_uint_t word); -/* least significant digit of a word */ -EXTINLINE mpd_uint_t mpd_lsd(mpd_uint_t word); -/* coefficient size needed to store 'digits' */ -EXTINLINE mpd_ssize_t mpd_digits_to_size(mpd_ssize_t digits); -/* number of digits in the exponent, undefined for MPD_SSIZE_MIN */ -EXTINLINE int mpd_exp_digits(mpd_ssize_t exp); +mpd_t *mpd_qncopy(const mpd_t *a); +int mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status); +int mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status); +int mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status); + +void mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +int mpd_same_quantum(const mpd_t *a, const mpd_t *b); + +void mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +int mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status); +mpd_uint_t mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status); +mpd_uint_t mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n); +void mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx, uint32_t *status); + +int mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status); +int mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +int mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +int mpd_cmp_total(const mpd_t *a, const mpd_t *b); +int mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b); +int mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b); +int mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b); + +void mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); + +void mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status); +void mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, const mpd_context_t *ctx, uint32_t *status); +void mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_context_t *ctx, uint32_t *status); +void mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, const mpd_context_t *ctx, uint32_t *status); +void mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status); +void mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status); + +#ifndef LEGACY_COMPILER +void mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b, const mpd_context_t *ctx, uint32_t *status); +void mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b, const mpd_context_t *ctx, uint32_t *status); +#endif + + +size_t mpd_sizeinbase(const mpd_t *a, uint32_t base); +void mpd_qimport_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, + uint8_t srcsign, uint32_t srcbase, + const mpd_context_t *ctx, uint32_t *status); +void mpd_qimport_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, + uint8_t srcsign, uint32_t srcbase, + const mpd_context_t *ctx, uint32_t *status); +size_t mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t base, + const mpd_t *src, uint32_t *status); +size_t mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t base, + const mpd_t *src, uint32_t *status); + + +/******************************************************************************/ +/* Signalling functions */ +/******************************************************************************/ + +char *mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx); +void mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx); +void mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx); +size_t mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx); +size_t mpd_export_u32(uint32_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx); +void mpd_finalize(mpd_t *result, mpd_context_t *ctx); +int mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +int mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx); +void mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx); +void mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx); +void mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx); +void mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx); +void mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx); +void mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx); +void mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx); +void mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx); +void mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx); +#ifndef LEGACY_COMPILER +void mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx); +void mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx); +#endif +mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx); +mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx); +mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx); +int32_t mpd_get_i32(const mpd_t *a, mpd_context_t *ctx); +uint32_t mpd_get_u32(const mpd_t *a, mpd_context_t *ctx); +#ifndef LEGACY_COMPILER +int64_t mpd_get_i64(const mpd_t *a, mpd_context_t *ctx); +uint64_t mpd_get_u64(const mpd_t *a, mpd_context_t *ctx); +#endif +void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx); +mpd_uint_t mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx); +void mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx); +void mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +int mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +int mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +int mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx); +void mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx); +void mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx); +void mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx); +void mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx); +void mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx); +void mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx); +void mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx); +void mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx); +void mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx); +void mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx); +void mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx); +void mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, mpd_context_t *ctx); +void mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx); +void mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx); +void mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx); +void mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx); +void mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx); +void mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, mpd_context_t *ctx); +void mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx); +void mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx); +void mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); +void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx); + +#ifndef LEGACY_COMPILER +void mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); +void mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); +void mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); +void mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); +void mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); +void mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); +void mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx); +void mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx); +#endif + + +/******************************************************************************/ +/* Configuration specific */ +/******************************************************************************/ + +#ifdef CONFIG_64 +void mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx); +void mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx); +#endif + + +/******************************************************************************/ +/* Get attributes of a decimal */ +/******************************************************************************/ + +EXTINLINE mpd_ssize_t mpd_adjexp(const mpd_t *dec); +EXTINLINE mpd_ssize_t mpd_etiny(const mpd_context_t *ctx); +EXTINLINE mpd_ssize_t mpd_etop(const mpd_context_t *ctx); +EXTINLINE mpd_uint_t mpd_msword(const mpd_t *dec); +EXTINLINE int mpd_word_digits(mpd_uint_t word); +/* most significant digit of a word */ +EXTINLINE mpd_uint_t mpd_msd(mpd_uint_t word); +/* least significant digit of a word */ +EXTINLINE mpd_uint_t mpd_lsd(mpd_uint_t word); +/* coefficient size needed to store 'digits' */ +EXTINLINE mpd_ssize_t mpd_digits_to_size(mpd_ssize_t digits); +/* number of digits in the exponent, undefined for MPD_SSIZE_MIN */ +EXTINLINE int mpd_exp_digits(mpd_ssize_t exp); EXTINLINE int mpd_iscanonical(const mpd_t *dec); -EXTINLINE int mpd_isfinite(const mpd_t *dec); -EXTINLINE int mpd_isinfinite(const mpd_t *dec); -EXTINLINE int mpd_isinteger(const mpd_t *dec); -EXTINLINE int mpd_isnan(const mpd_t *dec); -EXTINLINE int mpd_isnegative(const mpd_t *dec); -EXTINLINE int mpd_ispositive(const mpd_t *dec); -EXTINLINE int mpd_isqnan(const mpd_t *dec); -EXTINLINE int mpd_issigned(const mpd_t *dec); -EXTINLINE int mpd_issnan(const mpd_t *dec); -EXTINLINE int mpd_isspecial(const mpd_t *dec); -EXTINLINE int mpd_iszero(const mpd_t *dec); -/* undefined for special numbers */ -EXTINLINE int mpd_iszerocoeff(const mpd_t *dec); -EXTINLINE int mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx); -EXTINLINE int mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx); -/* odd word */ -EXTINLINE int mpd_isoddword(mpd_uint_t word); -/* odd coefficient */ -EXTINLINE int mpd_isoddcoeff(const mpd_t *dec); -/* odd decimal, only defined for integers */ -int mpd_isodd(const mpd_t *dec); -/* even decimal, only defined for integers */ -int mpd_iseven(const mpd_t *dec); -/* 0 if dec is positive, 1 if dec is negative */ -EXTINLINE uint8_t mpd_sign(const mpd_t *dec); -/* 1 if dec is positive, -1 if dec is negative */ -EXTINLINE int mpd_arith_sign(const mpd_t *dec); -EXTINLINE long mpd_radix(void); -EXTINLINE int mpd_isdynamic(const mpd_t *dec); -EXTINLINE int mpd_isstatic(const mpd_t *dec); -EXTINLINE int mpd_isdynamic_data(const mpd_t *dec); -EXTINLINE int mpd_isstatic_data(const mpd_t *dec); -EXTINLINE int mpd_isshared_data(const mpd_t *dec); -EXTINLINE int mpd_isconst_data(const mpd_t *dec); -EXTINLINE mpd_ssize_t mpd_trail_zeros(const mpd_t *dec); - - -/******************************************************************************/ -/* Set attributes of a decimal */ -/******************************************************************************/ - -/* set number of decimal digits in the coefficient */ -EXTINLINE void mpd_setdigits(mpd_t *result); -EXTINLINE void mpd_set_sign(mpd_t *result, uint8_t sign); -/* copy sign from another decimal */ -EXTINLINE void mpd_signcpy(mpd_t *result, const mpd_t *a); -EXTINLINE void mpd_set_infinity(mpd_t *result); -EXTINLINE void mpd_set_qnan(mpd_t *result); -EXTINLINE void mpd_set_snan(mpd_t *result); -EXTINLINE void mpd_set_negative(mpd_t *result); -EXTINLINE void mpd_set_positive(mpd_t *result); -EXTINLINE void mpd_set_dynamic(mpd_t *result); -EXTINLINE void mpd_set_static(mpd_t *result); -EXTINLINE void mpd_set_dynamic_data(mpd_t *result); -EXTINLINE void mpd_set_static_data(mpd_t *result); -EXTINLINE void mpd_set_shared_data(mpd_t *result); -EXTINLINE void mpd_set_const_data(mpd_t *result); -EXTINLINE void mpd_clear_flags(mpd_t *result); -EXTINLINE void mpd_set_flags(mpd_t *result, uint8_t flags); -EXTINLINE void mpd_copy_flags(mpd_t *result, const mpd_t *a); - - -/******************************************************************************/ -/* Error Macros */ -/******************************************************************************/ - -#define mpd_err_fatal(...) \ - do {fprintf(stderr, "%s:%d: error: ", __FILE__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); fputc('\n', stderr); \ - abort(); \ - } while (0) -#define mpd_err_warn(...) \ - do {fprintf(stderr, "%s:%d: warning: ", __FILE__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); fputc('\n', stderr); \ - } while (0) - - -/******************************************************************************/ -/* Memory handling */ -/******************************************************************************/ - -extern void *(* mpd_mallocfunc)(size_t size); -extern void *(* mpd_callocfunc)(size_t nmemb, size_t size); -extern void *(* mpd_reallocfunc)(void *ptr, size_t size); -extern void (* mpd_free)(void *ptr); - -void *mpd_callocfunc_em(size_t nmemb, size_t size); - -void *mpd_alloc(mpd_size_t nmemb, mpd_size_t size); -void *mpd_calloc(mpd_size_t nmemb, mpd_size_t size); -void *mpd_realloc(void *ptr, mpd_size_t nmemb, mpd_size_t size, uint8_t *err); -void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size); - -mpd_t *mpd_qnew(void); -mpd_t *mpd_new(mpd_context_t *ctx); -mpd_t *mpd_qnew_size(mpd_ssize_t size); -EXTINLINE void mpd_del(mpd_t *dec); - -EXTINLINE void mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len); -EXTINLINE int mpd_qresize(mpd_t *result, mpd_ssize_t size, uint32_t *status); -EXTINLINE int mpd_qresize_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); -EXTINLINE void mpd_minalloc(mpd_t *result); - -int mpd_resize(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx); -int mpd_resize_zero(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx); - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - -#ifdef __cplusplus -} /* END extern "C" */ -#endif - - +EXTINLINE int mpd_isfinite(const mpd_t *dec); +EXTINLINE int mpd_isinfinite(const mpd_t *dec); +EXTINLINE int mpd_isinteger(const mpd_t *dec); +EXTINLINE int mpd_isnan(const mpd_t *dec); +EXTINLINE int mpd_isnegative(const mpd_t *dec); +EXTINLINE int mpd_ispositive(const mpd_t *dec); +EXTINLINE int mpd_isqnan(const mpd_t *dec); +EXTINLINE int mpd_issigned(const mpd_t *dec); +EXTINLINE int mpd_issnan(const mpd_t *dec); +EXTINLINE int mpd_isspecial(const mpd_t *dec); +EXTINLINE int mpd_iszero(const mpd_t *dec); +/* undefined for special numbers */ +EXTINLINE int mpd_iszerocoeff(const mpd_t *dec); +EXTINLINE int mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx); +EXTINLINE int mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx); +/* odd word */ +EXTINLINE int mpd_isoddword(mpd_uint_t word); +/* odd coefficient */ +EXTINLINE int mpd_isoddcoeff(const mpd_t *dec); +/* odd decimal, only defined for integers */ +int mpd_isodd(const mpd_t *dec); +/* even decimal, only defined for integers */ +int mpd_iseven(const mpd_t *dec); +/* 0 if dec is positive, 1 if dec is negative */ +EXTINLINE uint8_t mpd_sign(const mpd_t *dec); +/* 1 if dec is positive, -1 if dec is negative */ +EXTINLINE int mpd_arith_sign(const mpd_t *dec); +EXTINLINE long mpd_radix(void); +EXTINLINE int mpd_isdynamic(const mpd_t *dec); +EXTINLINE int mpd_isstatic(const mpd_t *dec); +EXTINLINE int mpd_isdynamic_data(const mpd_t *dec); +EXTINLINE int mpd_isstatic_data(const mpd_t *dec); +EXTINLINE int mpd_isshared_data(const mpd_t *dec); +EXTINLINE int mpd_isconst_data(const mpd_t *dec); +EXTINLINE mpd_ssize_t mpd_trail_zeros(const mpd_t *dec); + + +/******************************************************************************/ +/* Set attributes of a decimal */ +/******************************************************************************/ + +/* set number of decimal digits in the coefficient */ +EXTINLINE void mpd_setdigits(mpd_t *result); +EXTINLINE void mpd_set_sign(mpd_t *result, uint8_t sign); +/* copy sign from another decimal */ +EXTINLINE void mpd_signcpy(mpd_t *result, const mpd_t *a); +EXTINLINE void mpd_set_infinity(mpd_t *result); +EXTINLINE void mpd_set_qnan(mpd_t *result); +EXTINLINE void mpd_set_snan(mpd_t *result); +EXTINLINE void mpd_set_negative(mpd_t *result); +EXTINLINE void mpd_set_positive(mpd_t *result); +EXTINLINE void mpd_set_dynamic(mpd_t *result); +EXTINLINE void mpd_set_static(mpd_t *result); +EXTINLINE void mpd_set_dynamic_data(mpd_t *result); +EXTINLINE void mpd_set_static_data(mpd_t *result); +EXTINLINE void mpd_set_shared_data(mpd_t *result); +EXTINLINE void mpd_set_const_data(mpd_t *result); +EXTINLINE void mpd_clear_flags(mpd_t *result); +EXTINLINE void mpd_set_flags(mpd_t *result, uint8_t flags); +EXTINLINE void mpd_copy_flags(mpd_t *result, const mpd_t *a); + + +/******************************************************************************/ +/* Error Macros */ +/******************************************************************************/ + +#define mpd_err_fatal(...) \ + do {fprintf(stderr, "%s:%d: error: ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); fputc('\n', stderr); \ + abort(); \ + } while (0) +#define mpd_err_warn(...) \ + do {fprintf(stderr, "%s:%d: warning: ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); fputc('\n', stderr); \ + } while (0) + + +/******************************************************************************/ +/* Memory handling */ +/******************************************************************************/ + +extern void *(* mpd_mallocfunc)(size_t size); +extern void *(* mpd_callocfunc)(size_t nmemb, size_t size); +extern void *(* mpd_reallocfunc)(void *ptr, size_t size); +extern void (* mpd_free)(void *ptr); + +void *mpd_callocfunc_em(size_t nmemb, size_t size); + +void *mpd_alloc(mpd_size_t nmemb, mpd_size_t size); +void *mpd_calloc(mpd_size_t nmemb, mpd_size_t size); +void *mpd_realloc(void *ptr, mpd_size_t nmemb, mpd_size_t size, uint8_t *err); +void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size); + +mpd_t *mpd_qnew(void); +mpd_t *mpd_new(mpd_context_t *ctx); +mpd_t *mpd_qnew_size(mpd_ssize_t size); +EXTINLINE void mpd_del(mpd_t *dec); + +EXTINLINE void mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len); +EXTINLINE int mpd_qresize(mpd_t *result, mpd_ssize_t size, uint32_t *status); +EXTINLINE int mpd_qresize_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); +EXTINLINE void mpd_minalloc(mpd_t *result); + +int mpd_resize(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx); +int mpd_resize_zero(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx); + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + +#ifdef __cplusplus +} /* END extern "C" */ +#endif + + #endif /* LIBMPDEC_MPDECIMAL_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/numbertheory.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/numbertheory.c index 210e0deb371..8778fbb8f72 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/numbertheory.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/numbertheory.c @@ -1,132 +1,132 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" #include -#include +#include -#include "bits.h" +#include "bits.h" #include "numbertheory.h" -#include "umodarith.h" - - -/* Bignum: Initialize the Number Theoretic Transform. */ - - -/* - * Return the nth root of unity in F(p). This corresponds to e**((2*pi*i)/n) - * in the Fourier transform. We have w**n == 1 (mod p). - * n := transform length. - * sign := -1 for forward transform, 1 for backward transform. - * modnum := one of {P1, P2, P3}. - */ -mpd_uint_t -_mpd_getkernel(mpd_uint_t n, int sign, int modnum) -{ - mpd_uint_t umod, p, r, xi; -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - - SETMODULUS(modnum); - r = mpd_roots[modnum]; /* primitive root of F(p) */ - p = umod; - xi = (p-1) / n; - - if (sign == -1) - return POWMOD(r, (p-1-xi)); - else - return POWMOD(r, xi); -} - -/* - * Initialize and return transform parameters. - * n := transform length. - * sign := -1 for forward transform, 1 for backward transform. - * modnum := one of {P1, P2, P3}. - */ -struct fnt_params * -_mpd_init_fnt_params(mpd_size_t n, int sign, int modnum) -{ - struct fnt_params *tparams; - mpd_uint_t umod; -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_uint_t kernel, w; - mpd_uint_t i; - mpd_size_t nhalf; - - assert(ispower2(n)); - assert(sign == -1 || sign == 1); - assert(P1 <= modnum && modnum <= P3); - - nhalf = n/2; - tparams = mpd_sh_alloc(sizeof *tparams, nhalf, sizeof (mpd_uint_t)); - if (tparams == NULL) { - return NULL; - } - - SETMODULUS(modnum); - kernel = _mpd_getkernel(n, sign, modnum); - - tparams->modnum = modnum; - tparams->modulus = umod; - tparams->kernel = kernel; - - /* wtable[] := w**0, w**1, ..., w**(nhalf-1) */ - w = 1; - for (i = 0; i < nhalf; i++) { - tparams->wtable[i] = w; - w = MULMOD(w, kernel); - } - - return tparams; -} - -/* Initialize wtable of size three. */ -void -_mpd_init_w3table(mpd_uint_t w3table[3], int sign, int modnum) -{ - mpd_uint_t umod; -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_uint_t kernel; - - SETMODULUS(modnum); - kernel = _mpd_getkernel(3, sign, modnum); - - w3table[0] = 1; - w3table[1] = kernel; - w3table[2] = POWMOD(kernel, 2); -} +#include "umodarith.h" + + +/* Bignum: Initialize the Number Theoretic Transform. */ + + +/* + * Return the nth root of unity in F(p). This corresponds to e**((2*pi*i)/n) + * in the Fourier transform. We have w**n == 1 (mod p). + * n := transform length. + * sign := -1 for forward transform, 1 for backward transform. + * modnum := one of {P1, P2, P3}. + */ +mpd_uint_t +_mpd_getkernel(mpd_uint_t n, int sign, int modnum) +{ + mpd_uint_t umod, p, r, xi; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + + SETMODULUS(modnum); + r = mpd_roots[modnum]; /* primitive root of F(p) */ + p = umod; + xi = (p-1) / n; + + if (sign == -1) + return POWMOD(r, (p-1-xi)); + else + return POWMOD(r, xi); +} + +/* + * Initialize and return transform parameters. + * n := transform length. + * sign := -1 for forward transform, 1 for backward transform. + * modnum := one of {P1, P2, P3}. + */ +struct fnt_params * +_mpd_init_fnt_params(mpd_size_t n, int sign, int modnum) +{ + struct fnt_params *tparams; + mpd_uint_t umod; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_uint_t kernel, w; + mpd_uint_t i; + mpd_size_t nhalf; + + assert(ispower2(n)); + assert(sign == -1 || sign == 1); + assert(P1 <= modnum && modnum <= P3); + + nhalf = n/2; + tparams = mpd_sh_alloc(sizeof *tparams, nhalf, sizeof (mpd_uint_t)); + if (tparams == NULL) { + return NULL; + } + + SETMODULUS(modnum); + kernel = _mpd_getkernel(n, sign, modnum); + + tparams->modnum = modnum; + tparams->modulus = umod; + tparams->kernel = kernel; + + /* wtable[] := w**0, w**1, ..., w**(nhalf-1) */ + w = 1; + for (i = 0; i < nhalf; i++) { + tparams->wtable[i] = w; + w = MULMOD(w, kernel); + } + + return tparams; +} + +/* Initialize wtable of size three. */ +void +_mpd_init_w3table(mpd_uint_t w3table[3], int sign, int modnum) +{ + mpd_uint_t umod; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_uint_t kernel; + + SETMODULUS(modnum); + kernel = _mpd_getkernel(3, sign, modnum); + + w3table[0] = 1; + w3table[1] = kernel; + w3table[2] = POWMOD(kernel, 2); +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/numbertheory.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/numbertheory.h index 47b7753b831..280dcb8c727 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/numbertheory.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/numbertheory.h @@ -1,76 +1,76 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_NUMBERTHEORY_H_ #define LIBMPDEC_NUMBERTHEORY_H_ - - + + #include "mpdecimal.h" -#include "constants.h" - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -/* transform parameters */ -struct fnt_params { - int modnum; - mpd_uint_t modulus; - mpd_uint_t kernel; - mpd_uint_t wtable[]; -}; - - -mpd_uint_t _mpd_getkernel(mpd_uint_t n, int sign, int modnum); -struct fnt_params *_mpd_init_fnt_params(mpd_size_t n, int sign, int modnum); -void _mpd_init_w3table(mpd_uint_t w3table[3], int sign, int modnum); - - -#ifdef PPRO -static inline void -ppro_setmodulus(int modnum, mpd_uint_t *umod, double *dmod, uint32_t dinvmod[3]) -{ - *dmod = *umod = mpd_moduli[modnum]; - dinvmod[0] = mpd_invmoduli[modnum][0]; - dinvmod[1] = mpd_invmoduli[modnum][1]; - dinvmod[2] = mpd_invmoduli[modnum][2]; -} -#else -static inline void -std_setmodulus(int modnum, mpd_uint_t *umod) -{ - *umod = mpd_moduli[modnum]; -} -#endif - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - +#include "constants.h" + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +/* transform parameters */ +struct fnt_params { + int modnum; + mpd_uint_t modulus; + mpd_uint_t kernel; + mpd_uint_t wtable[]; +}; + + +mpd_uint_t _mpd_getkernel(mpd_uint_t n, int sign, int modnum); +struct fnt_params *_mpd_init_fnt_params(mpd_size_t n, int sign, int modnum); +void _mpd_init_w3table(mpd_uint_t w3table[3], int sign, int modnum); + + +#ifdef PPRO +static inline void +ppro_setmodulus(int modnum, mpd_uint_t *umod, double *dmod, uint32_t dinvmod[3]) +{ + *dmod = *umod = mpd_moduli[modnum]; + dinvmod[0] = mpd_invmoduli[modnum][0]; + dinvmod[1] = mpd_invmoduli[modnum][1]; + dinvmod[2] = mpd_invmoduli[modnum][2]; +} +#else +static inline void +std_setmodulus(int modnum, mpd_uint_t *umod) +{ + *umod = mpd_moduli[modnum]; +} +#endif + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_NUMBERTHEORY_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/sixstep.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/sixstep.c index a4d1dbed781..5dab2a5c0ca 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/sixstep.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/sixstep.c @@ -1,214 +1,214 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" #include -#include +#include -#include "bits.h" +#include "bits.h" #include "constants.h" -#include "difradix2.h" -#include "numbertheory.h" +#include "difradix2.h" +#include "numbertheory.h" #include "sixstep.h" -#include "transpose.h" -#include "umodarith.h" - - -/* Bignum: Cache efficient Matrix Fourier Transform for arrays of the - form 2**n (See literature/six-step.txt). */ - - -/* forward transform with sign = -1 */ -int -six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) -{ - struct fnt_params *tparams; - mpd_size_t log2n, C, R; - mpd_uint_t kernel; - mpd_uint_t umod; -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_uint_t *x, w0, w1, wstep; - mpd_size_t i, k; - - - assert(ispower2(n)); - assert(n >= 16); - assert(n <= MPD_MAXTRANSFORM_2N); - - log2n = mpd_bsr(n); - C = ((mpd_size_t)1) << (log2n / 2); /* number of columns */ - R = ((mpd_size_t)1) << (log2n - (log2n / 2)); /* number of rows */ - - - /* Transpose the matrix. */ - if (!transpose_pow2(a, R, C)) { - return 0; - } - - /* Length R transform on the rows. */ - if ((tparams = _mpd_init_fnt_params(R, -1, modnum)) == NULL) { - return 0; - } - for (x = a; x < a+n; x += R) { - fnt_dif2(x, R, tparams); - } - - /* Transpose the matrix. */ - if (!transpose_pow2(a, C, R)) { - mpd_free(tparams); - return 0; - } - - /* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */ - SETMODULUS(modnum); - kernel = _mpd_getkernel(n, -1, modnum); - for (i = 1; i < R; i++) { - w0 = 1; /* r**(i*0): initial value for k=0 */ - w1 = POWMOD(kernel, i); /* r**(i*1): initial value for k=1 */ - wstep = MULMOD(w1, w1); /* r**(2*i) */ - for (k = 0; k < C; k += 2) { - mpd_uint_t x0 = a[i*C+k]; - mpd_uint_t x1 = a[i*C+k+1]; - MULMOD2(&x0, w0, &x1, w1); - MULMOD2C(&w0, &w1, wstep); /* r**(i*(k+2)) = r**(i*k) * r**(2*i) */ - a[i*C+k] = x0; - a[i*C+k+1] = x1; - } - } - - /* Length C transform on the rows. */ - if (C != R) { - mpd_free(tparams); - if ((tparams = _mpd_init_fnt_params(C, -1, modnum)) == NULL) { - return 0; - } - } - for (x = a; x < a+n; x += C) { - fnt_dif2(x, C, tparams); - } - mpd_free(tparams); - -#if 0 - /* An unordered transform is sufficient for convolution. */ - /* Transpose the matrix. */ - if (!transpose_pow2(a, R, C)) { - return 0; - } -#endif - - return 1; -} - - -/* reverse transform, sign = 1 */ -int -inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) -{ - struct fnt_params *tparams; - mpd_size_t log2n, C, R; - mpd_uint_t kernel; - mpd_uint_t umod; -#ifdef PPRO - double dmod; - uint32_t dinvmod[3]; -#endif - mpd_uint_t *x, w0, w1, wstep; - mpd_size_t i, k; - - - assert(ispower2(n)); - assert(n >= 16); - assert(n <= MPD_MAXTRANSFORM_2N); - - log2n = mpd_bsr(n); - C = ((mpd_size_t)1) << (log2n / 2); /* number of columns */ - R = ((mpd_size_t)1) << (log2n - (log2n / 2)); /* number of rows */ - - -#if 0 - /* An unordered transform is sufficient for convolution. */ - /* Transpose the matrix, producing an R*C matrix. */ - if (!transpose_pow2(a, C, R)) { - return 0; - } -#endif - - /* Length C transform on the rows. */ - if ((tparams = _mpd_init_fnt_params(C, 1, modnum)) == NULL) { - return 0; - } - for (x = a; x < a+n; x += C) { - fnt_dif2(x, C, tparams); - } - - /* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */ - SETMODULUS(modnum); - kernel = _mpd_getkernel(n, 1, modnum); - for (i = 1; i < R; i++) { - w0 = 1; - w1 = POWMOD(kernel, i); - wstep = MULMOD(w1, w1); - for (k = 0; k < C; k += 2) { - mpd_uint_t x0 = a[i*C+k]; - mpd_uint_t x1 = a[i*C+k+1]; - MULMOD2(&x0, w0, &x1, w1); - MULMOD2C(&w0, &w1, wstep); - a[i*C+k] = x0; - a[i*C+k+1] = x1; - } - } - - /* Transpose the matrix. */ - if (!transpose_pow2(a, R, C)) { - mpd_free(tparams); - return 0; - } - - /* Length R transform on the rows. */ - if (R != C) { - mpd_free(tparams); - if ((tparams = _mpd_init_fnt_params(R, 1, modnum)) == NULL) { - return 0; - } - } - for (x = a; x < a+n; x += R) { - fnt_dif2(x, R, tparams); - } - mpd_free(tparams); - - /* Transpose the matrix. */ - if (!transpose_pow2(a, C, R)) { - return 0; - } - - return 1; -} +#include "transpose.h" +#include "umodarith.h" + + +/* Bignum: Cache efficient Matrix Fourier Transform for arrays of the + form 2**n (See literature/six-step.txt). */ + + +/* forward transform with sign = -1 */ +int +six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) +{ + struct fnt_params *tparams; + mpd_size_t log2n, C, R; + mpd_uint_t kernel; + mpd_uint_t umod; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_uint_t *x, w0, w1, wstep; + mpd_size_t i, k; + + + assert(ispower2(n)); + assert(n >= 16); + assert(n <= MPD_MAXTRANSFORM_2N); + + log2n = mpd_bsr(n); + C = ((mpd_size_t)1) << (log2n / 2); /* number of columns */ + R = ((mpd_size_t)1) << (log2n - (log2n / 2)); /* number of rows */ + + + /* Transpose the matrix. */ + if (!transpose_pow2(a, R, C)) { + return 0; + } + + /* Length R transform on the rows. */ + if ((tparams = _mpd_init_fnt_params(R, -1, modnum)) == NULL) { + return 0; + } + for (x = a; x < a+n; x += R) { + fnt_dif2(x, R, tparams); + } + + /* Transpose the matrix. */ + if (!transpose_pow2(a, C, R)) { + mpd_free(tparams); + return 0; + } + + /* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */ + SETMODULUS(modnum); + kernel = _mpd_getkernel(n, -1, modnum); + for (i = 1; i < R; i++) { + w0 = 1; /* r**(i*0): initial value for k=0 */ + w1 = POWMOD(kernel, i); /* r**(i*1): initial value for k=1 */ + wstep = MULMOD(w1, w1); /* r**(2*i) */ + for (k = 0; k < C; k += 2) { + mpd_uint_t x0 = a[i*C+k]; + mpd_uint_t x1 = a[i*C+k+1]; + MULMOD2(&x0, w0, &x1, w1); + MULMOD2C(&w0, &w1, wstep); /* r**(i*(k+2)) = r**(i*k) * r**(2*i) */ + a[i*C+k] = x0; + a[i*C+k+1] = x1; + } + } + + /* Length C transform on the rows. */ + if (C != R) { + mpd_free(tparams); + if ((tparams = _mpd_init_fnt_params(C, -1, modnum)) == NULL) { + return 0; + } + } + for (x = a; x < a+n; x += C) { + fnt_dif2(x, C, tparams); + } + mpd_free(tparams); + +#if 0 + /* An unordered transform is sufficient for convolution. */ + /* Transpose the matrix. */ + if (!transpose_pow2(a, R, C)) { + return 0; + } +#endif + + return 1; +} + + +/* reverse transform, sign = 1 */ +int +inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) +{ + struct fnt_params *tparams; + mpd_size_t log2n, C, R; + mpd_uint_t kernel; + mpd_uint_t umod; +#ifdef PPRO + double dmod; + uint32_t dinvmod[3]; +#endif + mpd_uint_t *x, w0, w1, wstep; + mpd_size_t i, k; + + + assert(ispower2(n)); + assert(n >= 16); + assert(n <= MPD_MAXTRANSFORM_2N); + + log2n = mpd_bsr(n); + C = ((mpd_size_t)1) << (log2n / 2); /* number of columns */ + R = ((mpd_size_t)1) << (log2n - (log2n / 2)); /* number of rows */ + + +#if 0 + /* An unordered transform is sufficient for convolution. */ + /* Transpose the matrix, producing an R*C matrix. */ + if (!transpose_pow2(a, C, R)) { + return 0; + } +#endif + + /* Length C transform on the rows. */ + if ((tparams = _mpd_init_fnt_params(C, 1, modnum)) == NULL) { + return 0; + } + for (x = a; x < a+n; x += C) { + fnt_dif2(x, C, tparams); + } + + /* Multiply each matrix element (addressed by i*C+k) by r**(i*k). */ + SETMODULUS(modnum); + kernel = _mpd_getkernel(n, 1, modnum); + for (i = 1; i < R; i++) { + w0 = 1; + w1 = POWMOD(kernel, i); + wstep = MULMOD(w1, w1); + for (k = 0; k < C; k += 2) { + mpd_uint_t x0 = a[i*C+k]; + mpd_uint_t x1 = a[i*C+k+1]; + MULMOD2(&x0, w0, &x1, w1); + MULMOD2C(&w0, &w1, wstep); + a[i*C+k] = x0; + a[i*C+k+1] = x1; + } + } + + /* Transpose the matrix. */ + if (!transpose_pow2(a, R, C)) { + mpd_free(tparams); + return 0; + } + + /* Length R transform on the rows. */ + if (R != C) { + mpd_free(tparams); + if ((tparams = _mpd_init_fnt_params(R, 1, modnum)) == NULL) { + return 0; + } + } + for (x = a; x < a+n; x += R) { + fnt_dif2(x, R, tparams); + } + mpd_free(tparams); + + /* Transpose the matrix. */ + if (!transpose_pow2(a, C, R)) { + return 0; + } + + return 1; +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/sixstep.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/sixstep.h index 89b4a33afc7..0e72f3b5207 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/sixstep.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/sixstep.h @@ -1,47 +1,47 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_SIXSTEP_H_ #define LIBMPDEC_SIXSTEP_H_ - - -#include "mpdecimal.h" - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -int six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum); -int inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum); - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - + + +#include "mpdecimal.h" + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +int six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum); +int inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum); + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_SIXSTEP_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/transpose.c b/contrib/tools/python3/src/Modules/_decimal/libmpdec/transpose.c index 56321b5f39a..c79c34948a2 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/transpose.c +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/transpose.c @@ -1,276 +1,276 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include "mpdecimal.h" + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "mpdecimal.h" #include #include -#include -#include -#include +#include +#include +#include -#include "bits.h" -#include "constants.h" +#include "bits.h" +#include "constants.h" #include "transpose.h" -#include "typearith.h" - - -#define BUFSIZE 4096 -#define SIDE 128 - - -/* Bignum: The transpose functions are used for very large transforms - in sixstep.c and fourstep.c. */ - - -/* Definition of the matrix transpose */ -void -std_trans(mpd_uint_t dest[], mpd_uint_t src[], mpd_size_t rows, mpd_size_t cols) -{ - mpd_size_t idest, isrc; - mpd_size_t r, c; - - for (r = 0; r < rows; r++) { - isrc = r * cols; - idest = r; - for (c = 0; c < cols; c++) { - dest[idest] = src[isrc]; - isrc += 1; - idest += rows; - } - } -} - -/* - * Swap half-rows of 2^n * (2*2^n) matrix. - * FORWARD_CYCLE: even/odd permutation of the halfrows. - * BACKWARD_CYCLE: reverse the even/odd permutation. - */ -static int -swap_halfrows_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols, int dir) -{ - mpd_uint_t buf1[BUFSIZE]; - mpd_uint_t buf2[BUFSIZE]; - mpd_uint_t *readbuf, *writebuf, *hp; - mpd_size_t *done, dbits; - mpd_size_t b = BUFSIZE, stride; - mpd_size_t hn, hmax; /* halfrow number */ - mpd_size_t m, r=0; - mpd_size_t offset; - mpd_size_t next; - - - assert(cols == mul_size_t(2, rows)); - - if (dir == FORWARD_CYCLE) { - r = rows; - } - else if (dir == BACKWARD_CYCLE) { - r = 2; - } - else { - abort(); /* GCOV_NOT_REACHED */ - } - - m = cols - 1; - hmax = rows; /* cycles start at odd halfrows */ - dbits = 8 * sizeof *done; - if ((done = mpd_calloc(hmax/(sizeof *done) + 1, sizeof *done)) == NULL) { - return 0; - } - - for (hn = 1; hn <= hmax; hn += 2) { - - if (done[hn/dbits] & mpd_bits[hn%dbits]) { - continue; - } - - readbuf = buf1; writebuf = buf2; - - for (offset = 0; offset < cols/2; offset += b) { - - stride = (offset + b < cols/2) ? b : cols/2-offset; - - hp = matrix + hn*cols/2; - memcpy(readbuf, hp+offset, stride*(sizeof *readbuf)); - pointerswap(&readbuf, &writebuf); - - next = mulmod_size_t(hn, r, m); - hp = matrix + next*cols/2; - - while (next != hn) { - - memcpy(readbuf, hp+offset, stride*(sizeof *readbuf)); - memcpy(hp+offset, writebuf, stride*(sizeof *writebuf)); - pointerswap(&readbuf, &writebuf); - - done[next/dbits] |= mpd_bits[next%dbits]; - - next = mulmod_size_t(next, r, m); - hp = matrix + next*cols/2; - - } - - memcpy(hp+offset, writebuf, stride*(sizeof *writebuf)); - - done[hn/dbits] |= mpd_bits[hn%dbits]; - } - } - - mpd_free(done); - return 1; -} - -/* In-place transpose of a square matrix */ -static inline void -squaretrans(mpd_uint_t *buf, mpd_size_t cols) -{ - mpd_uint_t tmp; - mpd_size_t idest, isrc; - mpd_size_t r, c; - - for (r = 0; r < cols; r++) { - c = r+1; - isrc = r*cols + c; - idest = c*cols + r; - for (c = r+1; c < cols; c++) { - tmp = buf[isrc]; - buf[isrc] = buf[idest]; - buf[idest] = tmp; - isrc += 1; - idest += cols; - } - } -} - -/* - * Transpose 2^n * 2^n matrix. For cache efficiency, the matrix is split into - * square blocks with side length 'SIDE'. First, the blocks are transposed, - * then a square transposition is done on each individual block. - */ -static void -squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size) -{ - mpd_uint_t buf1[SIDE*SIDE]; - mpd_uint_t buf2[SIDE*SIDE]; - mpd_uint_t *to, *from; - mpd_size_t b = size; - mpd_size_t r, c; - mpd_size_t i; - - while (b > SIDE) b >>= 1; - - for (r = 0; r < size; r += b) { - - for (c = r; c < size; c += b) { - - from = matrix + r*size + c; - to = buf1; - for (i = 0; i < b; i++) { - memcpy(to, from, b*(sizeof *to)); - from += size; - to += b; - } - squaretrans(buf1, b); - - if (r == c) { - to = matrix + r*size + c; - from = buf1; - for (i = 0; i < b; i++) { - memcpy(to, from, b*(sizeof *to)); - from += b; - to += size; - } - continue; - } - else { - from = matrix + c*size + r; - to = buf2; - for (i = 0; i < b; i++) { - memcpy(to, from, b*(sizeof *to)); - from += size; - to += b; - } - squaretrans(buf2, b); - - to = matrix + c*size + r; - from = buf1; - for (i = 0; i < b; i++) { - memcpy(to, from, b*(sizeof *to)); - from += b; - to += size; - } - - to = matrix + r*size + c; - from = buf2; - for (i = 0; i < b; i++) { - memcpy(to, from, b*(sizeof *to)); - from += b; - to += size; - } - } - } - } - -} - -/* - * In-place transposition of a 2^n x 2^n or a 2^n x (2*2^n) - * or a (2*2^n) x 2^n matrix. - */ -int -transpose_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols) -{ - mpd_size_t size = mul_size_t(rows, cols); - - assert(ispower2(rows)); - assert(ispower2(cols)); - - if (cols == rows) { - squaretrans_pow2(matrix, rows); - } - else if (cols == mul_size_t(2, rows)) { - if (!swap_halfrows_pow2(matrix, rows, cols, FORWARD_CYCLE)) { - return 0; - } - squaretrans_pow2(matrix, rows); - squaretrans_pow2(matrix+(size/2), rows); - } - else if (rows == mul_size_t(2, cols)) { - squaretrans_pow2(matrix, cols); - squaretrans_pow2(matrix+(size/2), cols); - if (!swap_halfrows_pow2(matrix, cols, rows, BACKWARD_CYCLE)) { - return 0; - } - } - else { - abort(); /* GCOV_NOT_REACHED */ - } - - return 1; -} +#include "typearith.h" + + +#define BUFSIZE 4096 +#define SIDE 128 + + +/* Bignum: The transpose functions are used for very large transforms + in sixstep.c and fourstep.c. */ + + +/* Definition of the matrix transpose */ +void +std_trans(mpd_uint_t dest[], mpd_uint_t src[], mpd_size_t rows, mpd_size_t cols) +{ + mpd_size_t idest, isrc; + mpd_size_t r, c; + + for (r = 0; r < rows; r++) { + isrc = r * cols; + idest = r; + for (c = 0; c < cols; c++) { + dest[idest] = src[isrc]; + isrc += 1; + idest += rows; + } + } +} + +/* + * Swap half-rows of 2^n * (2*2^n) matrix. + * FORWARD_CYCLE: even/odd permutation of the halfrows. + * BACKWARD_CYCLE: reverse the even/odd permutation. + */ +static int +swap_halfrows_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols, int dir) +{ + mpd_uint_t buf1[BUFSIZE]; + mpd_uint_t buf2[BUFSIZE]; + mpd_uint_t *readbuf, *writebuf, *hp; + mpd_size_t *done, dbits; + mpd_size_t b = BUFSIZE, stride; + mpd_size_t hn, hmax; /* halfrow number */ + mpd_size_t m, r=0; + mpd_size_t offset; + mpd_size_t next; + + + assert(cols == mul_size_t(2, rows)); + + if (dir == FORWARD_CYCLE) { + r = rows; + } + else if (dir == BACKWARD_CYCLE) { + r = 2; + } + else { + abort(); /* GCOV_NOT_REACHED */ + } + + m = cols - 1; + hmax = rows; /* cycles start at odd halfrows */ + dbits = 8 * sizeof *done; + if ((done = mpd_calloc(hmax/(sizeof *done) + 1, sizeof *done)) == NULL) { + return 0; + } + + for (hn = 1; hn <= hmax; hn += 2) { + + if (done[hn/dbits] & mpd_bits[hn%dbits]) { + continue; + } + + readbuf = buf1; writebuf = buf2; + + for (offset = 0; offset < cols/2; offset += b) { + + stride = (offset + b < cols/2) ? b : cols/2-offset; + + hp = matrix + hn*cols/2; + memcpy(readbuf, hp+offset, stride*(sizeof *readbuf)); + pointerswap(&readbuf, &writebuf); + + next = mulmod_size_t(hn, r, m); + hp = matrix + next*cols/2; + + while (next != hn) { + + memcpy(readbuf, hp+offset, stride*(sizeof *readbuf)); + memcpy(hp+offset, writebuf, stride*(sizeof *writebuf)); + pointerswap(&readbuf, &writebuf); + + done[next/dbits] |= mpd_bits[next%dbits]; + + next = mulmod_size_t(next, r, m); + hp = matrix + next*cols/2; + + } + + memcpy(hp+offset, writebuf, stride*(sizeof *writebuf)); + + done[hn/dbits] |= mpd_bits[hn%dbits]; + } + } + + mpd_free(done); + return 1; +} + +/* In-place transpose of a square matrix */ +static inline void +squaretrans(mpd_uint_t *buf, mpd_size_t cols) +{ + mpd_uint_t tmp; + mpd_size_t idest, isrc; + mpd_size_t r, c; + + for (r = 0; r < cols; r++) { + c = r+1; + isrc = r*cols + c; + idest = c*cols + r; + for (c = r+1; c < cols; c++) { + tmp = buf[isrc]; + buf[isrc] = buf[idest]; + buf[idest] = tmp; + isrc += 1; + idest += cols; + } + } +} + +/* + * Transpose 2^n * 2^n matrix. For cache efficiency, the matrix is split into + * square blocks with side length 'SIDE'. First, the blocks are transposed, + * then a square transposition is done on each individual block. + */ +static void +squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size) +{ + mpd_uint_t buf1[SIDE*SIDE]; + mpd_uint_t buf2[SIDE*SIDE]; + mpd_uint_t *to, *from; + mpd_size_t b = size; + mpd_size_t r, c; + mpd_size_t i; + + while (b > SIDE) b >>= 1; + + for (r = 0; r < size; r += b) { + + for (c = r; c < size; c += b) { + + from = matrix + r*size + c; + to = buf1; + for (i = 0; i < b; i++) { + memcpy(to, from, b*(sizeof *to)); + from += size; + to += b; + } + squaretrans(buf1, b); + + if (r == c) { + to = matrix + r*size + c; + from = buf1; + for (i = 0; i < b; i++) { + memcpy(to, from, b*(sizeof *to)); + from += b; + to += size; + } + continue; + } + else { + from = matrix + c*size + r; + to = buf2; + for (i = 0; i < b; i++) { + memcpy(to, from, b*(sizeof *to)); + from += size; + to += b; + } + squaretrans(buf2, b); + + to = matrix + c*size + r; + from = buf1; + for (i = 0; i < b; i++) { + memcpy(to, from, b*(sizeof *to)); + from += b; + to += size; + } + + to = matrix + r*size + c; + from = buf2; + for (i = 0; i < b; i++) { + memcpy(to, from, b*(sizeof *to)); + from += b; + to += size; + } + } + } + } + +} + +/* + * In-place transposition of a 2^n x 2^n or a 2^n x (2*2^n) + * or a (2*2^n) x 2^n matrix. + */ +int +transpose_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols) +{ + mpd_size_t size = mul_size_t(rows, cols); + + assert(ispower2(rows)); + assert(ispower2(cols)); + + if (cols == rows) { + squaretrans_pow2(matrix, rows); + } + else if (cols == mul_size_t(2, rows)) { + if (!swap_halfrows_pow2(matrix, rows, cols, FORWARD_CYCLE)) { + return 0; + } + squaretrans_pow2(matrix, rows); + squaretrans_pow2(matrix+(size/2), rows); + } + else if (rows == mul_size_t(2, cols)) { + squaretrans_pow2(matrix, cols); + squaretrans_pow2(matrix+(size/2), cols); + if (!swap_halfrows_pow2(matrix, cols, rows, BACKWARD_CYCLE)) { + return 0; + } + } + else { + abort(); /* GCOV_NOT_REACHED */ + } + + return 1; +} diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/transpose.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/transpose.h index e91c18d7435..8e6ec56a282 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/transpose.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/transpose.h @@ -1,61 +1,61 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_TRANSPOSE_H_ #define LIBMPDEC_TRANSPOSE_H_ - - -#include "mpdecimal.h" - - -/* Internal header file: all symbols have local scope in the DSO */ -MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) - - -enum {FORWARD_CYCLE, BACKWARD_CYCLE}; - - -void std_trans(mpd_uint_t dest[], mpd_uint_t src[], mpd_size_t rows, mpd_size_t cols); -int transpose_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols); -void transpose_3xpow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols); - - -static inline void pointerswap(mpd_uint_t **a, mpd_uint_t **b) -{ - mpd_uint_t *tmp; - - tmp = *b; - *b = *a; - *a = tmp; -} - - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ - - + + +#include "mpdecimal.h" + + +/* Internal header file: all symbols have local scope in the DSO */ +MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) + + +enum {FORWARD_CYCLE, BACKWARD_CYCLE}; + + +void std_trans(mpd_uint_t dest[], mpd_uint_t src[], mpd_size_t rows, mpd_size_t cols); +int transpose_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols); +void transpose_3xpow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols); + + +static inline void pointerswap(mpd_uint_t **a, mpd_uint_t **b) +{ + mpd_uint_t *tmp; + + tmp = *b; + *b = *a; + *a = tmp; +} + + +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ + + #endif /* LIBMPDEC_TRANSPOSE_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/typearith.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/typearith.h index 47961788d76..5c00d1e6b18 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/typearith.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/typearith.h @@ -1,668 +1,668 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_TYPEARITH_H_ #define LIBMPDEC_TYPEARITH_H_ - - -#include "mpdecimal.h" - + + +#include "mpdecimal.h" + #include - - -/*****************************************************************************/ -/* Low level native arithmetic on basic types */ -/*****************************************************************************/ - - -/** ------------------------------------------------------------ - ** Double width multiplication and division - ** ------------------------------------------------------------ - */ - -#if defined(CONFIG_64) -#if defined(ANSI) -#if defined(HAVE_UINT128_T) -static inline void -_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) -{ - __uint128_t hl; - - hl = (__uint128_t)a * b; - - *hi = hl >> 64; - *lo = (mpd_uint_t)hl; -} - -static inline void -_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, - mpd_uint_t d) -{ - __uint128_t hl; - - hl = ((__uint128_t)hi<<64) + lo; - *q = (mpd_uint_t)(hl / d); /* quotient is known to fit */ - *r = (mpd_uint_t)(hl - (__uint128_t)(*q) * d); -} -#else -static inline void -_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) -{ - uint32_t w[4], carry; - uint32_t ah, al, bh, bl; - uint64_t hl; - - ah = (uint32_t)(a>>32); al = (uint32_t)a; - bh = (uint32_t)(b>>32); bl = (uint32_t)b; - - hl = (uint64_t)al * bl; - w[0] = (uint32_t)hl; - carry = (uint32_t)(hl>>32); - - hl = (uint64_t)ah * bl + carry; - w[1] = (uint32_t)hl; - w[2] = (uint32_t)(hl>>32); - - hl = (uint64_t)al * bh + w[1]; - w[1] = (uint32_t)hl; - carry = (uint32_t)(hl>>32); - - hl = ((uint64_t)ah * bh + w[2]) + carry; - w[2] = (uint32_t)hl; - w[3] = (uint32_t)(hl>>32); - - *hi = ((uint64_t)w[3]<<32) + w[2]; - *lo = ((uint64_t)w[1]<<32) + w[0]; -} - -/* - * By Henry S. Warren: http://www.hackersdelight.org/HDcode/divlu.c.txt - * http://www.hackersdelight.org/permissions.htm: - * "You are free to use, copy, and distribute any of the code on this web - * site, whether modified by you or not. You need not give attribution." - * - * Slightly modified, comments are mine. - */ -static inline int -nlz(uint64_t x) -{ - int n; - - if (x == 0) return(64); - - n = 0; - if (x <= 0x00000000FFFFFFFF) {n = n +32; x = x <<32;} - if (x <= 0x0000FFFFFFFFFFFF) {n = n +16; x = x <<16;} - if (x <= 0x00FFFFFFFFFFFFFF) {n = n + 8; x = x << 8;} - if (x <= 0x0FFFFFFFFFFFFFFF) {n = n + 4; x = x << 4;} - if (x <= 0x3FFFFFFFFFFFFFFF) {n = n + 2; x = x << 2;} - if (x <= 0x7FFFFFFFFFFFFFFF) {n = n + 1;} - - return n; -} - -static inline void -_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t u1, mpd_uint_t u0, - mpd_uint_t v) -{ - const mpd_uint_t b = 4294967296; - mpd_uint_t un1, un0, - vn1, vn0, - q1, q0, - un32, un21, un10, - rhat, t; - int s; - - assert(u1 < v); - - s = nlz(v); - v = v << s; - vn1 = v >> 32; - vn0 = v & 0xFFFFFFFF; - - t = (s == 0) ? 0 : u0 >> (64 - s); - un32 = (u1 << s) | t; - un10 = u0 << s; - - un1 = un10 >> 32; - un0 = un10 & 0xFFFFFFFF; - - q1 = un32 / vn1; - rhat = un32 - q1*vn1; -again1: - if (q1 >= b || q1*vn0 > b*rhat + un1) { - q1 = q1 - 1; - rhat = rhat + vn1; - if (rhat < b) goto again1; - } - - /* - * Before again1 we had: - * (1) q1*vn1 + rhat = un32 - * (2) q1*vn1*b + rhat*b + un1 = un32*b + un1 - * - * The statements inside the if-clause do not change the value - * of the left-hand side of (2), and the loop is only exited - * if q1*vn0 <= rhat*b + un1, so: - * - * (3) q1*vn1*b + q1*vn0 <= un32*b + un1 - * (4) q1*v <= un32*b + un1 - * (5) 0 <= un32*b + un1 - q1*v - * - * By (5) we are certain that the possible add-back step from - * Knuth's algorithm D is never required. - * - * Since the final quotient is less than 2**64, the following - * must be true: - * - * (6) un32*b + un1 - q1*v <= UINT64_MAX - * - * This means that in the following line, the high words - * of un32*b and q1*v can be discarded without any effect - * on the result. - */ - un21 = un32*b + un1 - q1*v; - - q0 = un21 / vn1; - rhat = un21 - q0*vn1; -again2: - if (q0 >= b || q0*vn0 > b*rhat + un0) { - q0 = q0 - 1; - rhat = rhat + vn1; - if (rhat < b) goto again2; - } - - *q = q1*b + q0; - *r = (un21*b + un0 - q0*v) >> s; -} -#endif - -/* END ANSI */ -#elif defined(ASM) -static inline void -_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) -{ - mpd_uint_t h, l; - - __asm__ ( "mulq %3\n\t" - : "=d" (h), "=a" (l) - : "%a" (a), "rm" (b) - : "cc" - ); - - *hi = h; - *lo = l; -} - -static inline void -_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, - mpd_uint_t d) -{ - mpd_uint_t qq, rr; - - __asm__ ( "divq %4\n\t" - : "=a" (qq), "=d" (rr) - : "a" (lo), "d" (hi), "rm" (d) - : "cc" - ); - - *q = qq; - *r = rr; -} -/* END GCC ASM */ -#elif defined(MASM) -#include -#pragma intrinsic(_umul128) - -static inline void -_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) -{ - *lo = _umul128(a, b, hi); -} - -void _mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, - mpd_uint_t d); - -/* END MASM (_MSC_VER) */ -#else - #error "need platform specific 128 bit multiplication and division" -#endif - -#define DIVMOD(q, r, v, d) *q = v / d; *r = v - *q * d -static inline void -_mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp) -{ - assert(exp <= 19); - - if (exp <= 9) { - if (exp <= 4) { - switch (exp) { - case 0: *q = v; *r = 0; break; - case 1: DIVMOD(q, r, v, 10UL); break; - case 2: DIVMOD(q, r, v, 100UL); break; - case 3: DIVMOD(q, r, v, 1000UL); break; - case 4: DIVMOD(q, r, v, 10000UL); break; - } - } - else { - switch (exp) { - case 5: DIVMOD(q, r, v, 100000UL); break; - case 6: DIVMOD(q, r, v, 1000000UL); break; - case 7: DIVMOD(q, r, v, 10000000UL); break; - case 8: DIVMOD(q, r, v, 100000000UL); break; - case 9: DIVMOD(q, r, v, 1000000000UL); break; - } - } - } - else { - if (exp <= 14) { - switch (exp) { - case 10: DIVMOD(q, r, v, 10000000000ULL); break; - case 11: DIVMOD(q, r, v, 100000000000ULL); break; - case 12: DIVMOD(q, r, v, 1000000000000ULL); break; - case 13: DIVMOD(q, r, v, 10000000000000ULL); break; - case 14: DIVMOD(q, r, v, 100000000000000ULL); break; - } - } - else { - switch (exp) { - case 15: DIVMOD(q, r, v, 1000000000000000ULL); break; - case 16: DIVMOD(q, r, v, 10000000000000000ULL); break; - case 17: DIVMOD(q, r, v, 100000000000000000ULL); break; - case 18: DIVMOD(q, r, v, 1000000000000000000ULL); break; - case 19: DIVMOD(q, r, v, 10000000000000000000ULL); break; /* GCOV_NOT_REACHED */ - } - } - } -} - -/* END CONFIG_64 */ -#elif defined(CONFIG_32) -#if defined(ANSI) -#if !defined(LEGACY_COMPILER) -static inline void -_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) -{ - mpd_uuint_t hl; - - hl = (mpd_uuint_t)a * b; - - *hi = hl >> 32; - *lo = (mpd_uint_t)hl; -} - -static inline void -_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, - mpd_uint_t d) -{ - mpd_uuint_t hl; - - hl = ((mpd_uuint_t)hi<<32) + lo; - *q = (mpd_uint_t)(hl / d); /* quotient is known to fit */ - *r = (mpd_uint_t)(hl - (mpd_uuint_t)(*q) * d); -} -/* END ANSI + uint64_t */ -#else -static inline void -_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) -{ - uint16_t w[4], carry; - uint16_t ah, al, bh, bl; - uint32_t hl; - - ah = (uint16_t)(a>>16); al = (uint16_t)a; - bh = (uint16_t)(b>>16); bl = (uint16_t)b; - - hl = (uint32_t)al * bl; - w[0] = (uint16_t)hl; - carry = (uint16_t)(hl>>16); - - hl = (uint32_t)ah * bl + carry; - w[1] = (uint16_t)hl; - w[2] = (uint16_t)(hl>>16); - - hl = (uint32_t)al * bh + w[1]; - w[1] = (uint16_t)hl; - carry = (uint16_t)(hl>>16); - - hl = ((uint32_t)ah * bh + w[2]) + carry; - w[2] = (uint16_t)hl; - w[3] = (uint16_t)(hl>>16); - - *hi = ((uint32_t)w[3]<<16) + w[2]; - *lo = ((uint32_t)w[1]<<16) + w[0]; -} - -/* - * By Henry S. Warren: http://www.hackersdelight.org/HDcode/divlu.c.txt - * http://www.hackersdelight.org/permissions.htm: - * "You are free to use, copy, and distribute any of the code on this web - * site, whether modified by you or not. You need not give attribution." - * - * Slightly modified, comments are mine. - */ -static inline int -nlz(uint32_t x) -{ - int n; - - if (x == 0) return(32); - - n = 0; - if (x <= 0x0000FFFF) {n = n +16; x = x <<16;} - if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;} - if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;} - if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;} - if (x <= 0x7FFFFFFF) {n = n + 1;} - - return n; -} - -static inline void -_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t u1, mpd_uint_t u0, - mpd_uint_t v) -{ - const mpd_uint_t b = 65536; - mpd_uint_t un1, un0, - vn1, vn0, - q1, q0, - un32, un21, un10, - rhat, t; - int s; - - assert(u1 < v); - - s = nlz(v); - v = v << s; - vn1 = v >> 16; - vn0 = v & 0xFFFF; - - t = (s == 0) ? 0 : u0 >> (32 - s); - un32 = (u1 << s) | t; - un10 = u0 << s; - - un1 = un10 >> 16; - un0 = un10 & 0xFFFF; - - q1 = un32 / vn1; - rhat = un32 - q1*vn1; -again1: - if (q1 >= b || q1*vn0 > b*rhat + un1) { - q1 = q1 - 1; - rhat = rhat + vn1; - if (rhat < b) goto again1; - } - - /* - * Before again1 we had: - * (1) q1*vn1 + rhat = un32 - * (2) q1*vn1*b + rhat*b + un1 = un32*b + un1 - * - * The statements inside the if-clause do not change the value - * of the left-hand side of (2), and the loop is only exited - * if q1*vn0 <= rhat*b + un1, so: - * - * (3) q1*vn1*b + q1*vn0 <= un32*b + un1 - * (4) q1*v <= un32*b + un1 - * (5) 0 <= un32*b + un1 - q1*v - * - * By (5) we are certain that the possible add-back step from - * Knuth's algorithm D is never required. - * - * Since the final quotient is less than 2**32, the following - * must be true: - * - * (6) un32*b + un1 - q1*v <= UINT32_MAX - * - * This means that in the following line, the high words - * of un32*b and q1*v can be discarded without any effect - * on the result. - */ - un21 = un32*b + un1 - q1*v; - - q0 = un21 / vn1; - rhat = un21 - q0*vn1; -again2: - if (q0 >= b || q0*vn0 > b*rhat + un0) { - q0 = q0 - 1; - rhat = rhat + vn1; - if (rhat < b) goto again2; - } - - *q = q1*b + q0; - *r = (un21*b + un0 - q0*v) >> s; -} -#endif /* END ANSI + LEGACY_COMPILER */ - -/* END ANSI */ -#elif defined(ASM) -static inline void -_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) -{ - mpd_uint_t h, l; - - __asm__ ( "mull %3\n\t" - : "=d" (h), "=a" (l) - : "%a" (a), "rm" (b) - : "cc" - ); - - *hi = h; - *lo = l; -} - -static inline void -_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, - mpd_uint_t d) -{ - mpd_uint_t qq, rr; - - __asm__ ( "divl %4\n\t" - : "=a" (qq), "=d" (rr) - : "a" (lo), "d" (hi), "rm" (d) - : "cc" - ); - - *q = qq; - *r = rr; -} -/* END GCC ASM */ -#elif defined(MASM) -static inline void __cdecl -_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) -{ - mpd_uint_t h, l; - - __asm { - mov eax, a - mul b - mov h, edx - mov l, eax - } - - *hi = h; - *lo = l; -} - -static inline void __cdecl -_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, - mpd_uint_t d) -{ - mpd_uint_t qq, rr; - - __asm { - mov eax, lo - mov edx, hi - div d - mov qq, eax - mov rr, edx - } - - *q = qq; - *r = rr; -} -/* END MASM (_MSC_VER) */ -#else - #error "need platform specific 64 bit multiplication and division" -#endif - -#define DIVMOD(q, r, v, d) *q = v / d; *r = v - *q * d -static inline void -_mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp) -{ - assert(exp <= 9); - - if (exp <= 4) { - switch (exp) { - case 0: *q = v; *r = 0; break; - case 1: DIVMOD(q, r, v, 10UL); break; - case 2: DIVMOD(q, r, v, 100UL); break; - case 3: DIVMOD(q, r, v, 1000UL); break; - case 4: DIVMOD(q, r, v, 10000UL); break; - } - } - else { - switch (exp) { - case 5: DIVMOD(q, r, v, 100000UL); break; - case 6: DIVMOD(q, r, v, 1000000UL); break; - case 7: DIVMOD(q, r, v, 10000000UL); break; - case 8: DIVMOD(q, r, v, 100000000UL); break; - case 9: DIVMOD(q, r, v, 1000000000UL); break; /* GCOV_NOT_REACHED */ - } - } -} -/* END CONFIG_32 */ - -/* NO CONFIG */ -#else - #error "define CONFIG_64 or CONFIG_32" -#endif /* CONFIG */ - - -static inline void -_mpd_div_word(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t d) -{ - *q = v / d; - *r = v - *q * d; -} - -static inline void -_mpd_idiv_word(mpd_ssize_t *q, mpd_ssize_t *r, mpd_ssize_t v, mpd_ssize_t d) -{ - *q = v / d; - *r = v - *q * d; -} - - -/** ------------------------------------------------------------ - ** Arithmetic with overflow checking - ** ------------------------------------------------------------ - */ - -/* The following macros do call exit() in case of an overflow. - If the library is used correctly (i.e. with valid context - parameters), such overflows cannot occur. The macros are used - as sanity checks in a couple of strategic places and should - be viewed as a handwritten version of gcc's -ftrapv option. */ - -static inline mpd_size_t -add_size_t(mpd_size_t a, mpd_size_t b) -{ - if (a > MPD_SIZE_MAX - b) { - mpd_err_fatal("add_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */ - } - return a + b; -} - -static inline mpd_size_t -sub_size_t(mpd_size_t a, mpd_size_t b) -{ - if (b > a) { - mpd_err_fatal("sub_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */ - } - return a - b; -} - -#if MPD_SIZE_MAX != MPD_UINT_MAX - #error "adapt mul_size_t() and mulmod_size_t()" -#endif - -static inline mpd_size_t -mul_size_t(mpd_size_t a, mpd_size_t b) -{ - mpd_uint_t hi, lo; - - _mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b); - if (hi) { - mpd_err_fatal("mul_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */ - } - return lo; -} - -static inline mpd_size_t -add_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow) -{ - mpd_size_t ret; - - *overflow = 0; - ret = a + b; - if (ret < a) *overflow = 1; - return ret; -} - -static inline mpd_size_t -mul_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow) -{ - mpd_uint_t lo; - - _mpd_mul_words((mpd_uint_t *)overflow, &lo, (mpd_uint_t)a, - (mpd_uint_t)b); - return lo; -} - -static inline mpd_ssize_t -mod_mpd_ssize_t(mpd_ssize_t a, mpd_ssize_t m) -{ - mpd_ssize_t r = a % m; - return (r < 0) ? r + m : r; -} - -static inline mpd_size_t -mulmod_size_t(mpd_size_t a, mpd_size_t b, mpd_size_t m) -{ - mpd_uint_t hi, lo; - mpd_uint_t q, r; - - _mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b); - _mpd_div_words(&q, &r, hi, lo, (mpd_uint_t)m); - - return r; -} - - + + +/*****************************************************************************/ +/* Low level native arithmetic on basic types */ +/*****************************************************************************/ + + +/** ------------------------------------------------------------ + ** Double width multiplication and division + ** ------------------------------------------------------------ + */ + +#if defined(CONFIG_64) +#if defined(ANSI) +#if defined(HAVE_UINT128_T) +static inline void +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + __uint128_t hl; + + hl = (__uint128_t)a * b; + + *hi = hl >> 64; + *lo = (mpd_uint_t)hl; +} + +static inline void +_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, + mpd_uint_t d) +{ + __uint128_t hl; + + hl = ((__uint128_t)hi<<64) + lo; + *q = (mpd_uint_t)(hl / d); /* quotient is known to fit */ + *r = (mpd_uint_t)(hl - (__uint128_t)(*q) * d); +} +#else +static inline void +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + uint32_t w[4], carry; + uint32_t ah, al, bh, bl; + uint64_t hl; + + ah = (uint32_t)(a>>32); al = (uint32_t)a; + bh = (uint32_t)(b>>32); bl = (uint32_t)b; + + hl = (uint64_t)al * bl; + w[0] = (uint32_t)hl; + carry = (uint32_t)(hl>>32); + + hl = (uint64_t)ah * bl + carry; + w[1] = (uint32_t)hl; + w[2] = (uint32_t)(hl>>32); + + hl = (uint64_t)al * bh + w[1]; + w[1] = (uint32_t)hl; + carry = (uint32_t)(hl>>32); + + hl = ((uint64_t)ah * bh + w[2]) + carry; + w[2] = (uint32_t)hl; + w[3] = (uint32_t)(hl>>32); + + *hi = ((uint64_t)w[3]<<32) + w[2]; + *lo = ((uint64_t)w[1]<<32) + w[0]; +} + +/* + * By Henry S. Warren: http://www.hackersdelight.org/HDcode/divlu.c.txt + * http://www.hackersdelight.org/permissions.htm: + * "You are free to use, copy, and distribute any of the code on this web + * site, whether modified by you or not. You need not give attribution." + * + * Slightly modified, comments are mine. + */ +static inline int +nlz(uint64_t x) +{ + int n; + + if (x == 0) return(64); + + n = 0; + if (x <= 0x00000000FFFFFFFF) {n = n +32; x = x <<32;} + if (x <= 0x0000FFFFFFFFFFFF) {n = n +16; x = x <<16;} + if (x <= 0x00FFFFFFFFFFFFFF) {n = n + 8; x = x << 8;} + if (x <= 0x0FFFFFFFFFFFFFFF) {n = n + 4; x = x << 4;} + if (x <= 0x3FFFFFFFFFFFFFFF) {n = n + 2; x = x << 2;} + if (x <= 0x7FFFFFFFFFFFFFFF) {n = n + 1;} + + return n; +} + +static inline void +_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t u1, mpd_uint_t u0, + mpd_uint_t v) +{ + const mpd_uint_t b = 4294967296; + mpd_uint_t un1, un0, + vn1, vn0, + q1, q0, + un32, un21, un10, + rhat, t; + int s; + + assert(u1 < v); + + s = nlz(v); + v = v << s; + vn1 = v >> 32; + vn0 = v & 0xFFFFFFFF; + + t = (s == 0) ? 0 : u0 >> (64 - s); + un32 = (u1 << s) | t; + un10 = u0 << s; + + un1 = un10 >> 32; + un0 = un10 & 0xFFFFFFFF; + + q1 = un32 / vn1; + rhat = un32 - q1*vn1; +again1: + if (q1 >= b || q1*vn0 > b*rhat + un1) { + q1 = q1 - 1; + rhat = rhat + vn1; + if (rhat < b) goto again1; + } + + /* + * Before again1 we had: + * (1) q1*vn1 + rhat = un32 + * (2) q1*vn1*b + rhat*b + un1 = un32*b + un1 + * + * The statements inside the if-clause do not change the value + * of the left-hand side of (2), and the loop is only exited + * if q1*vn0 <= rhat*b + un1, so: + * + * (3) q1*vn1*b + q1*vn0 <= un32*b + un1 + * (4) q1*v <= un32*b + un1 + * (5) 0 <= un32*b + un1 - q1*v + * + * By (5) we are certain that the possible add-back step from + * Knuth's algorithm D is never required. + * + * Since the final quotient is less than 2**64, the following + * must be true: + * + * (6) un32*b + un1 - q1*v <= UINT64_MAX + * + * This means that in the following line, the high words + * of un32*b and q1*v can be discarded without any effect + * on the result. + */ + un21 = un32*b + un1 - q1*v; + + q0 = un21 / vn1; + rhat = un21 - q0*vn1; +again2: + if (q0 >= b || q0*vn0 > b*rhat + un0) { + q0 = q0 - 1; + rhat = rhat + vn1; + if (rhat < b) goto again2; + } + + *q = q1*b + q0; + *r = (un21*b + un0 - q0*v) >> s; +} +#endif + +/* END ANSI */ +#elif defined(ASM) +static inline void +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + mpd_uint_t h, l; + + __asm__ ( "mulq %3\n\t" + : "=d" (h), "=a" (l) + : "%a" (a), "rm" (b) + : "cc" + ); + + *hi = h; + *lo = l; +} + +static inline void +_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, + mpd_uint_t d) +{ + mpd_uint_t qq, rr; + + __asm__ ( "divq %4\n\t" + : "=a" (qq), "=d" (rr) + : "a" (lo), "d" (hi), "rm" (d) + : "cc" + ); + + *q = qq; + *r = rr; +} +/* END GCC ASM */ +#elif defined(MASM) +#include +#pragma intrinsic(_umul128) + +static inline void +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + *lo = _umul128(a, b, hi); +} + +void _mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, + mpd_uint_t d); + +/* END MASM (_MSC_VER) */ +#else + #error "need platform specific 128 bit multiplication and division" +#endif + +#define DIVMOD(q, r, v, d) *q = v / d; *r = v - *q * d +static inline void +_mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp) +{ + assert(exp <= 19); + + if (exp <= 9) { + if (exp <= 4) { + switch (exp) { + case 0: *q = v; *r = 0; break; + case 1: DIVMOD(q, r, v, 10UL); break; + case 2: DIVMOD(q, r, v, 100UL); break; + case 3: DIVMOD(q, r, v, 1000UL); break; + case 4: DIVMOD(q, r, v, 10000UL); break; + } + } + else { + switch (exp) { + case 5: DIVMOD(q, r, v, 100000UL); break; + case 6: DIVMOD(q, r, v, 1000000UL); break; + case 7: DIVMOD(q, r, v, 10000000UL); break; + case 8: DIVMOD(q, r, v, 100000000UL); break; + case 9: DIVMOD(q, r, v, 1000000000UL); break; + } + } + } + else { + if (exp <= 14) { + switch (exp) { + case 10: DIVMOD(q, r, v, 10000000000ULL); break; + case 11: DIVMOD(q, r, v, 100000000000ULL); break; + case 12: DIVMOD(q, r, v, 1000000000000ULL); break; + case 13: DIVMOD(q, r, v, 10000000000000ULL); break; + case 14: DIVMOD(q, r, v, 100000000000000ULL); break; + } + } + else { + switch (exp) { + case 15: DIVMOD(q, r, v, 1000000000000000ULL); break; + case 16: DIVMOD(q, r, v, 10000000000000000ULL); break; + case 17: DIVMOD(q, r, v, 100000000000000000ULL); break; + case 18: DIVMOD(q, r, v, 1000000000000000000ULL); break; + case 19: DIVMOD(q, r, v, 10000000000000000000ULL); break; /* GCOV_NOT_REACHED */ + } + } + } +} + +/* END CONFIG_64 */ +#elif defined(CONFIG_32) +#if defined(ANSI) +#if !defined(LEGACY_COMPILER) +static inline void +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + mpd_uuint_t hl; + + hl = (mpd_uuint_t)a * b; + + *hi = hl >> 32; + *lo = (mpd_uint_t)hl; +} + +static inline void +_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, + mpd_uint_t d) +{ + mpd_uuint_t hl; + + hl = ((mpd_uuint_t)hi<<32) + lo; + *q = (mpd_uint_t)(hl / d); /* quotient is known to fit */ + *r = (mpd_uint_t)(hl - (mpd_uuint_t)(*q) * d); +} +/* END ANSI + uint64_t */ +#else +static inline void +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + uint16_t w[4], carry; + uint16_t ah, al, bh, bl; + uint32_t hl; + + ah = (uint16_t)(a>>16); al = (uint16_t)a; + bh = (uint16_t)(b>>16); bl = (uint16_t)b; + + hl = (uint32_t)al * bl; + w[0] = (uint16_t)hl; + carry = (uint16_t)(hl>>16); + + hl = (uint32_t)ah * bl + carry; + w[1] = (uint16_t)hl; + w[2] = (uint16_t)(hl>>16); + + hl = (uint32_t)al * bh + w[1]; + w[1] = (uint16_t)hl; + carry = (uint16_t)(hl>>16); + + hl = ((uint32_t)ah * bh + w[2]) + carry; + w[2] = (uint16_t)hl; + w[3] = (uint16_t)(hl>>16); + + *hi = ((uint32_t)w[3]<<16) + w[2]; + *lo = ((uint32_t)w[1]<<16) + w[0]; +} + +/* + * By Henry S. Warren: http://www.hackersdelight.org/HDcode/divlu.c.txt + * http://www.hackersdelight.org/permissions.htm: + * "You are free to use, copy, and distribute any of the code on this web + * site, whether modified by you or not. You need not give attribution." + * + * Slightly modified, comments are mine. + */ +static inline int +nlz(uint32_t x) +{ + int n; + + if (x == 0) return(32); + + n = 0; + if (x <= 0x0000FFFF) {n = n +16; x = x <<16;} + if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;} + if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;} + if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;} + if (x <= 0x7FFFFFFF) {n = n + 1;} + + return n; +} + +static inline void +_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t u1, mpd_uint_t u0, + mpd_uint_t v) +{ + const mpd_uint_t b = 65536; + mpd_uint_t un1, un0, + vn1, vn0, + q1, q0, + un32, un21, un10, + rhat, t; + int s; + + assert(u1 < v); + + s = nlz(v); + v = v << s; + vn1 = v >> 16; + vn0 = v & 0xFFFF; + + t = (s == 0) ? 0 : u0 >> (32 - s); + un32 = (u1 << s) | t; + un10 = u0 << s; + + un1 = un10 >> 16; + un0 = un10 & 0xFFFF; + + q1 = un32 / vn1; + rhat = un32 - q1*vn1; +again1: + if (q1 >= b || q1*vn0 > b*rhat + un1) { + q1 = q1 - 1; + rhat = rhat + vn1; + if (rhat < b) goto again1; + } + + /* + * Before again1 we had: + * (1) q1*vn1 + rhat = un32 + * (2) q1*vn1*b + rhat*b + un1 = un32*b + un1 + * + * The statements inside the if-clause do not change the value + * of the left-hand side of (2), and the loop is only exited + * if q1*vn0 <= rhat*b + un1, so: + * + * (3) q1*vn1*b + q1*vn0 <= un32*b + un1 + * (4) q1*v <= un32*b + un1 + * (5) 0 <= un32*b + un1 - q1*v + * + * By (5) we are certain that the possible add-back step from + * Knuth's algorithm D is never required. + * + * Since the final quotient is less than 2**32, the following + * must be true: + * + * (6) un32*b + un1 - q1*v <= UINT32_MAX + * + * This means that in the following line, the high words + * of un32*b and q1*v can be discarded without any effect + * on the result. + */ + un21 = un32*b + un1 - q1*v; + + q0 = un21 / vn1; + rhat = un21 - q0*vn1; +again2: + if (q0 >= b || q0*vn0 > b*rhat + un0) { + q0 = q0 - 1; + rhat = rhat + vn1; + if (rhat < b) goto again2; + } + + *q = q1*b + q0; + *r = (un21*b + un0 - q0*v) >> s; +} +#endif /* END ANSI + LEGACY_COMPILER */ + +/* END ANSI */ +#elif defined(ASM) +static inline void +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + mpd_uint_t h, l; + + __asm__ ( "mull %3\n\t" + : "=d" (h), "=a" (l) + : "%a" (a), "rm" (b) + : "cc" + ); + + *hi = h; + *lo = l; +} + +static inline void +_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, + mpd_uint_t d) +{ + mpd_uint_t qq, rr; + + __asm__ ( "divl %4\n\t" + : "=a" (qq), "=d" (rr) + : "a" (lo), "d" (hi), "rm" (d) + : "cc" + ); + + *q = qq; + *r = rr; +} +/* END GCC ASM */ +#elif defined(MASM) +static inline void __cdecl +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + mpd_uint_t h, l; + + __asm { + mov eax, a + mul b + mov h, edx + mov l, eax + } + + *hi = h; + *lo = l; +} + +static inline void __cdecl +_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, + mpd_uint_t d) +{ + mpd_uint_t qq, rr; + + __asm { + mov eax, lo + mov edx, hi + div d + mov qq, eax + mov rr, edx + } + + *q = qq; + *r = rr; +} +/* END MASM (_MSC_VER) */ +#else + #error "need platform specific 64 bit multiplication and division" +#endif + +#define DIVMOD(q, r, v, d) *q = v / d; *r = v - *q * d +static inline void +_mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp) +{ + assert(exp <= 9); + + if (exp <= 4) { + switch (exp) { + case 0: *q = v; *r = 0; break; + case 1: DIVMOD(q, r, v, 10UL); break; + case 2: DIVMOD(q, r, v, 100UL); break; + case 3: DIVMOD(q, r, v, 1000UL); break; + case 4: DIVMOD(q, r, v, 10000UL); break; + } + } + else { + switch (exp) { + case 5: DIVMOD(q, r, v, 100000UL); break; + case 6: DIVMOD(q, r, v, 1000000UL); break; + case 7: DIVMOD(q, r, v, 10000000UL); break; + case 8: DIVMOD(q, r, v, 100000000UL); break; + case 9: DIVMOD(q, r, v, 1000000000UL); break; /* GCOV_NOT_REACHED */ + } + } +} +/* END CONFIG_32 */ + +/* NO CONFIG */ +#else + #error "define CONFIG_64 or CONFIG_32" +#endif /* CONFIG */ + + +static inline void +_mpd_div_word(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t d) +{ + *q = v / d; + *r = v - *q * d; +} + +static inline void +_mpd_idiv_word(mpd_ssize_t *q, mpd_ssize_t *r, mpd_ssize_t v, mpd_ssize_t d) +{ + *q = v / d; + *r = v - *q * d; +} + + +/** ------------------------------------------------------------ + ** Arithmetic with overflow checking + ** ------------------------------------------------------------ + */ + +/* The following macros do call exit() in case of an overflow. + If the library is used correctly (i.e. with valid context + parameters), such overflows cannot occur. The macros are used + as sanity checks in a couple of strategic places and should + be viewed as a handwritten version of gcc's -ftrapv option. */ + +static inline mpd_size_t +add_size_t(mpd_size_t a, mpd_size_t b) +{ + if (a > MPD_SIZE_MAX - b) { + mpd_err_fatal("add_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */ + } + return a + b; +} + +static inline mpd_size_t +sub_size_t(mpd_size_t a, mpd_size_t b) +{ + if (b > a) { + mpd_err_fatal("sub_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */ + } + return a - b; +} + +#if MPD_SIZE_MAX != MPD_UINT_MAX + #error "adapt mul_size_t() and mulmod_size_t()" +#endif + +static inline mpd_size_t +mul_size_t(mpd_size_t a, mpd_size_t b) +{ + mpd_uint_t hi, lo; + + _mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b); + if (hi) { + mpd_err_fatal("mul_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */ + } + return lo; +} + +static inline mpd_size_t +add_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow) +{ + mpd_size_t ret; + + *overflow = 0; + ret = a + b; + if (ret < a) *overflow = 1; + return ret; +} + +static inline mpd_size_t +mul_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow) +{ + mpd_uint_t lo; + + _mpd_mul_words((mpd_uint_t *)overflow, &lo, (mpd_uint_t)a, + (mpd_uint_t)b); + return lo; +} + +static inline mpd_ssize_t +mod_mpd_ssize_t(mpd_ssize_t a, mpd_ssize_t m) +{ + mpd_ssize_t r = a % m; + return (r < 0) ? r + m : r; +} + +static inline mpd_size_t +mulmod_size_t(mpd_size_t a, mpd_size_t b, mpd_size_t m) +{ + mpd_uint_t hi, lo; + mpd_uint_t q, r; + + _mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b); + _mpd_div_words(&q, &r, hi, lo, (mpd_uint_t)m); + + return r; +} + + #endif /* LIBMPDEC_TYPEARITH_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/umodarith.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/umodarith.h index d7dbbbe6a73..20748b6b914 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/umodarith.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/umodarith.h @@ -1,648 +1,648 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_UMODARITH_H_ #define LIBMPDEC_UMODARITH_H_ - - + + #include "mpdecimal.h" -#include "constants.h" -#include "typearith.h" - - -/* Bignum: Low level routines for unsigned modular arithmetic. These are - used in the fast convolution functions for very large coefficients. */ - - -/**************************************************************************/ -/* ANSI modular arithmetic */ -/**************************************************************************/ - - -/* - * Restrictions: a < m and b < m - * ACL2 proof: umodarith.lisp: addmod-correct - */ -static inline mpd_uint_t -addmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) -{ - mpd_uint_t s; - - s = a + b; - s = (s < a) ? s - m : s; - s = (s >= m) ? s - m : s; - - return s; -} - -/* - * Restrictions: a < m and b < m - * ACL2 proof: umodarith.lisp: submod-2-correct - */ -static inline mpd_uint_t -submod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) -{ - mpd_uint_t d; - - d = a - b; - d = (a < b) ? d + m : d; - - return d; -} - -/* - * Restrictions: a < 2m and b < 2m - * ACL2 proof: umodarith.lisp: section ext-submod - */ -static inline mpd_uint_t -ext_submod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) -{ - mpd_uint_t d; - - a = (a >= m) ? a - m : a; - b = (b >= m) ? b - m : b; - - d = a - b; - d = (a < b) ? d + m : d; - - return d; -} - -/* - * Reduce double word modulo m. - * Restrictions: m != 0 - * ACL2 proof: umodarith.lisp: section dw-reduce - */ -static inline mpd_uint_t -dw_reduce(mpd_uint_t hi, mpd_uint_t lo, mpd_uint_t m) -{ - mpd_uint_t r1, r2, w; - - _mpd_div_word(&w, &r1, hi, m); - _mpd_div_words(&w, &r2, r1, lo, m); - - return r2; -} - -/* - * Subtract double word from a. - * Restrictions: a < m - * ACL2 proof: umodarith.lisp: section dw-submod - */ -static inline mpd_uint_t -dw_submod(mpd_uint_t a, mpd_uint_t hi, mpd_uint_t lo, mpd_uint_t m) -{ - mpd_uint_t d, r; - - r = dw_reduce(hi, lo, m); - d = a - r; - d = (a < r) ? d + m : d; - - return d; -} - -#ifdef CONFIG_64 - -/**************************************************************************/ -/* 64-bit modular arithmetic */ -/**************************************************************************/ - -/* - * A proof of the algorithm is in literature/mulmod-64.txt. An ACL2 - * proof is in umodarith.lisp: section "Fast modular reduction". - * - * Algorithm: calculate (a * b) % p: - * - * a) hi, lo <- a * b # Calculate a * b. - * - * b) hi, lo <- R(hi, lo) # Reduce modulo p. - * - * c) Repeat step b) until 0 <= hi * 2**64 + lo < 2*p. - * - * d) If the result is less than p, return lo. Otherwise return lo - p. - */ - -static inline mpd_uint_t -x64_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) -{ - mpd_uint_t hi, lo, x, y; - - - _mpd_mul_words(&hi, &lo, a, b); - - if (m & (1ULL<<32)) { /* P1 */ - - /* first reduction */ - x = y = hi; - hi >>= 32; - - x = lo - x; - if (x > lo) hi--; - - y <<= 32; - lo = y + x; - if (lo < y) hi++; - - /* second reduction */ - x = y = hi; - hi >>= 32; - - x = lo - x; - if (x > lo) hi--; - - y <<= 32; - lo = y + x; - if (lo < y) hi++; - - return (hi || lo >= m ? lo - m : lo); - } - else if (m & (1ULL<<34)) { /* P2 */ - - /* first reduction */ - x = y = hi; - hi >>= 30; - - x = lo - x; - if (x > lo) hi--; - - y <<= 34; - lo = y + x; - if (lo < y) hi++; - - /* second reduction */ - x = y = hi; - hi >>= 30; - - x = lo - x; - if (x > lo) hi--; - - y <<= 34; - lo = y + x; - if (lo < y) hi++; - - /* third reduction */ - x = y = hi; - hi >>= 30; - - x = lo - x; - if (x > lo) hi--; - - y <<= 34; - lo = y + x; - if (lo < y) hi++; - - return (hi || lo >= m ? lo - m : lo); - } - else { /* P3 */ - - /* first reduction */ - x = y = hi; - hi >>= 24; - - x = lo - x; - if (x > lo) hi--; - - y <<= 40; - lo = y + x; - if (lo < y) hi++; - - /* second reduction */ - x = y = hi; - hi >>= 24; - - x = lo - x; - if (x > lo) hi--; - - y <<= 40; - lo = y + x; - if (lo < y) hi++; - - /* third reduction */ - x = y = hi; - hi >>= 24; - - x = lo - x; - if (x > lo) hi--; - - y <<= 40; - lo = y + x; - if (lo < y) hi++; - - return (hi || lo >= m ? lo - m : lo); - } -} - -static inline void -x64_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m) -{ - *a = x64_mulmod(*a, w, m); - *b = x64_mulmod(*b, w, m); -} - -static inline void -x64_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, - mpd_uint_t m) -{ - *a0 = x64_mulmod(*a0, b0, m); - *a1 = x64_mulmod(*a1, b1, m); -} - -static inline mpd_uint_t -x64_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod) -{ - mpd_uint_t r = 1; - - while (exp > 0) { - if (exp & 1) - r = x64_mulmod(r, base, umod); - base = x64_mulmod(base, base, umod); - exp >>= 1; - } - - return r; -} - -/* END CONFIG_64 */ -#else /* CONFIG_32 */ - - -/**************************************************************************/ -/* 32-bit modular arithmetic */ -/**************************************************************************/ - -#if defined(ANSI) -#if !defined(LEGACY_COMPILER) -/* HAVE_UINT64_T */ -static inline mpd_uint_t -std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) -{ - return ((mpd_uuint_t) a * b) % m; -} - -static inline void -std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m) -{ - *a = ((mpd_uuint_t) *a * w) % m; - *b = ((mpd_uuint_t) *b * w) % m; -} - -static inline void -std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, - mpd_uint_t m) -{ - *a0 = ((mpd_uuint_t) *a0 * b0) % m; - *a1 = ((mpd_uuint_t) *a1 * b1) % m; -} -/* END HAVE_UINT64_T */ -#else -/* LEGACY_COMPILER */ -static inline mpd_uint_t -std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) -{ - mpd_uint_t hi, lo, q, r; - _mpd_mul_words(&hi, &lo, a, b); - _mpd_div_words(&q, &r, hi, lo, m); - return r; -} - -static inline void -std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m) -{ - *a = std_mulmod(*a, w, m); - *b = std_mulmod(*b, w, m); -} - -static inline void -std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, - mpd_uint_t m) -{ - *a0 = std_mulmod(*a0, b0, m); - *a1 = std_mulmod(*a1, b1, m); -} -/* END LEGACY_COMPILER */ -#endif - -static inline mpd_uint_t -std_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod) -{ - mpd_uint_t r = 1; - - while (exp > 0) { - if (exp & 1) - r = std_mulmod(r, base, umod); - base = std_mulmod(base, base, umod); - exp >>= 1; - } - - return r; -} -#endif /* ANSI CONFIG_32 */ - - -/**************************************************************************/ -/* Pentium Pro modular arithmetic */ -/**************************************************************************/ - -/* - * A proof of the algorithm is in literature/mulmod-ppro.txt. The FPU - * control word must be set to 64-bit precision and truncation mode - * prior to using these functions. - * - * Algorithm: calculate (a * b) % p: - * - * p := prime < 2**31 - * pinv := (long double)1.0 / p (precalculated) - * - * a) n = a * b # Calculate exact product. - * b) qest = n * pinv # Calculate estimate for q = n / p. - * c) q = (qest+2**63)-2**63 # Truncate qest to the exact quotient. - * d) r = n - q * p # Calculate remainder. - * - * Remarks: - * - * - p = dmod and pinv = dinvmod. - * - dinvmod points to an array of three uint32_t, which is interpreted - * as an 80 bit long double by fldt. - * - Intel compilers prior to version 11 do not seem to handle the - * __GNUC__ inline assembly correctly. - * - random tests are provided in tests/extended/ppro_mulmod.c - */ - -#if defined(PPRO) -#if defined(ASM) - -/* Return (a * b) % dmod */ -static inline mpd_uint_t -ppro_mulmod(mpd_uint_t a, mpd_uint_t b, double *dmod, uint32_t *dinvmod) -{ - mpd_uint_t retval; - - __asm__ ( - "fildl %2\n\t" - "fildl %1\n\t" - "fmulp %%st, %%st(1)\n\t" - "fldt (%4)\n\t" - "fmul %%st(1), %%st\n\t" - "flds %5\n\t" - "fadd %%st, %%st(1)\n\t" - "fsubrp %%st, %%st(1)\n\t" - "fldl (%3)\n\t" - "fmulp %%st, %%st(1)\n\t" - "fsubrp %%st, %%st(1)\n\t" - "fistpl %0\n\t" - : "=m" (retval) - : "m" (a), "m" (b), "r" (dmod), "r" (dinvmod), "m" (MPD_TWO63) - : "st", "memory" - ); - - return retval; -} - -/* - * Two modular multiplications in parallel: - * *a0 = (*a0 * w) % dmod - * *a1 = (*a1 * w) % dmod - */ -static inline void -ppro_mulmod2c(mpd_uint_t *a0, mpd_uint_t *a1, mpd_uint_t w, - double *dmod, uint32_t *dinvmod) -{ - __asm__ ( - "fildl %2\n\t" - "fildl (%1)\n\t" - "fmul %%st(1), %%st\n\t" - "fxch %%st(1)\n\t" - "fildl (%0)\n\t" - "fmulp %%st, %%st(1) \n\t" - "fldt (%4)\n\t" - "flds %5\n\t" - "fld %%st(2)\n\t" - "fmul %%st(2)\n\t" - "fadd %%st(1)\n\t" - "fsub %%st(1)\n\t" - "fmull (%3)\n\t" - "fsubrp %%st, %%st(3)\n\t" - "fxch %%st(2)\n\t" - "fistpl (%0)\n\t" - "fmul %%st(2)\n\t" - "fadd %%st(1)\n\t" - "fsubp %%st, %%st(1)\n\t" - "fmull (%3)\n\t" - "fsubrp %%st, %%st(1)\n\t" - "fistpl (%1)\n\t" - : : "r" (a0), "r" (a1), "m" (w), - "r" (dmod), "r" (dinvmod), - "m" (MPD_TWO63) - : "st", "memory" - ); -} - -/* - * Two modular multiplications in parallel: - * *a0 = (*a0 * b0) % dmod - * *a1 = (*a1 * b1) % dmod - */ -static inline void -ppro_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, - double *dmod, uint32_t *dinvmod) -{ - __asm__ ( - "fildl %3\n\t" - "fildl (%2)\n\t" - "fmulp %%st, %%st(1)\n\t" - "fildl %1\n\t" - "fildl (%0)\n\t" - "fmulp %%st, %%st(1)\n\t" - "fldt (%5)\n\t" - "fld %%st(2)\n\t" - "fmul %%st(1), %%st\n\t" - "fxch %%st(1)\n\t" - "fmul %%st(2), %%st\n\t" - "flds %6\n\t" - "fldl (%4)\n\t" - "fxch %%st(3)\n\t" - "fadd %%st(1), %%st\n\t" - "fxch %%st(2)\n\t" - "fadd %%st(1), %%st\n\t" - "fxch %%st(2)\n\t" - "fsub %%st(1), %%st\n\t" - "fxch %%st(2)\n\t" - "fsubp %%st, %%st(1)\n\t" - "fxch %%st(1)\n\t" - "fmul %%st(2), %%st\n\t" - "fxch %%st(1)\n\t" - "fmulp %%st, %%st(2)\n\t" - "fsubrp %%st, %%st(3)\n\t" - "fsubrp %%st, %%st(1)\n\t" - "fxch %%st(1)\n\t" - "fistpl (%2)\n\t" - "fistpl (%0)\n\t" - : : "r" (a0), "m" (b0), "r" (a1), "m" (b1), - "r" (dmod), "r" (dinvmod), - "m" (MPD_TWO63) - : "st", "memory" - ); -} -/* END PPRO GCC ASM */ -#elif defined(MASM) - -/* Return (a * b) % dmod */ -static inline mpd_uint_t __cdecl -ppro_mulmod(mpd_uint_t a, mpd_uint_t b, double *dmod, uint32_t *dinvmod) -{ - mpd_uint_t retval; - - __asm { - mov eax, dinvmod - mov edx, dmod - fild b - fild a - fmulp st(1), st - fld TBYTE PTR [eax] - fmul st, st(1) - fld MPD_TWO63 - fadd st(1), st - fsubp st(1), st - fld QWORD PTR [edx] - fmulp st(1), st - fsubp st(1), st - fistp retval - } - - return retval; -} - -/* - * Two modular multiplications in parallel: - * *a0 = (*a0 * w) % dmod - * *a1 = (*a1 * w) % dmod - */ -static inline mpd_uint_t __cdecl -ppro_mulmod2c(mpd_uint_t *a0, mpd_uint_t *a1, mpd_uint_t w, - double *dmod, uint32_t *dinvmod) -{ - __asm { - mov ecx, dmod - mov edx, a1 - mov ebx, dinvmod - mov eax, a0 - fild w - fild DWORD PTR [edx] - fmul st, st(1) - fxch st(1) - fild DWORD PTR [eax] - fmulp st(1), st - fld TBYTE PTR [ebx] - fld MPD_TWO63 - fld st(2) - fmul st, st(2) - fadd st, st(1) - fsub st, st(1) - fmul QWORD PTR [ecx] - fsubp st(3), st - fxch st(2) - fistp DWORD PTR [eax] - fmul st, st(2) - fadd st, st(1) - fsubrp st(1), st - fmul QWORD PTR [ecx] - fsubp st(1), st - fistp DWORD PTR [edx] - } -} - -/* - * Two modular multiplications in parallel: - * *a0 = (*a0 * b0) % dmod - * *a1 = (*a1 * b1) % dmod - */ -static inline void __cdecl -ppro_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, - double *dmod, uint32_t *dinvmod) -{ - __asm { - mov ecx, dmod - mov edx, a1 - mov ebx, dinvmod - mov eax, a0 - fild b1 - fild DWORD PTR [edx] - fmulp st(1), st - fild b0 - fild DWORD PTR [eax] - fmulp st(1), st - fld TBYTE PTR [ebx] - fld st(2) - fmul st, st(1) - fxch st(1) - fmul st, st(2) - fld DWORD PTR MPD_TWO63 - fld QWORD PTR [ecx] - fxch st(3) - fadd st, st(1) - fxch st(2) - fadd st, st(1) - fxch st(2) - fsub st, st(1) - fxch st(2) - fsubrp st(1), st - fxch st(1) - fmul st, st(2) - fxch st(1) - fmulp st(2), st - fsubp st(3), st - fsubp st(1), st - fxch st(1) - fistp DWORD PTR [edx] - fistp DWORD PTR [eax] - } -} -#endif /* PPRO MASM (_MSC_VER) */ - - -/* Return (base ** exp) % dmod */ -static inline mpd_uint_t -ppro_powmod(mpd_uint_t base, mpd_uint_t exp, double *dmod, uint32_t *dinvmod) -{ - mpd_uint_t r = 1; - - while (exp > 0) { - if (exp & 1) - r = ppro_mulmod(r, base, dmod, dinvmod); - base = ppro_mulmod(base, base, dmod, dinvmod); - exp >>= 1; - } - - return r; -} -#endif /* PPRO */ -#endif /* CONFIG_32 */ - - +#include "constants.h" +#include "typearith.h" + + +/* Bignum: Low level routines for unsigned modular arithmetic. These are + used in the fast convolution functions for very large coefficients. */ + + +/**************************************************************************/ +/* ANSI modular arithmetic */ +/**************************************************************************/ + + +/* + * Restrictions: a < m and b < m + * ACL2 proof: umodarith.lisp: addmod-correct + */ +static inline mpd_uint_t +addmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) +{ + mpd_uint_t s; + + s = a + b; + s = (s < a) ? s - m : s; + s = (s >= m) ? s - m : s; + + return s; +} + +/* + * Restrictions: a < m and b < m + * ACL2 proof: umodarith.lisp: submod-2-correct + */ +static inline mpd_uint_t +submod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) +{ + mpd_uint_t d; + + d = a - b; + d = (a < b) ? d + m : d; + + return d; +} + +/* + * Restrictions: a < 2m and b < 2m + * ACL2 proof: umodarith.lisp: section ext-submod + */ +static inline mpd_uint_t +ext_submod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) +{ + mpd_uint_t d; + + a = (a >= m) ? a - m : a; + b = (b >= m) ? b - m : b; + + d = a - b; + d = (a < b) ? d + m : d; + + return d; +} + +/* + * Reduce double word modulo m. + * Restrictions: m != 0 + * ACL2 proof: umodarith.lisp: section dw-reduce + */ +static inline mpd_uint_t +dw_reduce(mpd_uint_t hi, mpd_uint_t lo, mpd_uint_t m) +{ + mpd_uint_t r1, r2, w; + + _mpd_div_word(&w, &r1, hi, m); + _mpd_div_words(&w, &r2, r1, lo, m); + + return r2; +} + +/* + * Subtract double word from a. + * Restrictions: a < m + * ACL2 proof: umodarith.lisp: section dw-submod + */ +static inline mpd_uint_t +dw_submod(mpd_uint_t a, mpd_uint_t hi, mpd_uint_t lo, mpd_uint_t m) +{ + mpd_uint_t d, r; + + r = dw_reduce(hi, lo, m); + d = a - r; + d = (a < r) ? d + m : d; + + return d; +} + +#ifdef CONFIG_64 + +/**************************************************************************/ +/* 64-bit modular arithmetic */ +/**************************************************************************/ + +/* + * A proof of the algorithm is in literature/mulmod-64.txt. An ACL2 + * proof is in umodarith.lisp: section "Fast modular reduction". + * + * Algorithm: calculate (a * b) % p: + * + * a) hi, lo <- a * b # Calculate a * b. + * + * b) hi, lo <- R(hi, lo) # Reduce modulo p. + * + * c) Repeat step b) until 0 <= hi * 2**64 + lo < 2*p. + * + * d) If the result is less than p, return lo. Otherwise return lo - p. + */ + +static inline mpd_uint_t +x64_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) +{ + mpd_uint_t hi, lo, x, y; + + + _mpd_mul_words(&hi, &lo, a, b); + + if (m & (1ULL<<32)) { /* P1 */ + + /* first reduction */ + x = y = hi; + hi >>= 32; + + x = lo - x; + if (x > lo) hi--; + + y <<= 32; + lo = y + x; + if (lo < y) hi++; + + /* second reduction */ + x = y = hi; + hi >>= 32; + + x = lo - x; + if (x > lo) hi--; + + y <<= 32; + lo = y + x; + if (lo < y) hi++; + + return (hi || lo >= m ? lo - m : lo); + } + else if (m & (1ULL<<34)) { /* P2 */ + + /* first reduction */ + x = y = hi; + hi >>= 30; + + x = lo - x; + if (x > lo) hi--; + + y <<= 34; + lo = y + x; + if (lo < y) hi++; + + /* second reduction */ + x = y = hi; + hi >>= 30; + + x = lo - x; + if (x > lo) hi--; + + y <<= 34; + lo = y + x; + if (lo < y) hi++; + + /* third reduction */ + x = y = hi; + hi >>= 30; + + x = lo - x; + if (x > lo) hi--; + + y <<= 34; + lo = y + x; + if (lo < y) hi++; + + return (hi || lo >= m ? lo - m : lo); + } + else { /* P3 */ + + /* first reduction */ + x = y = hi; + hi >>= 24; + + x = lo - x; + if (x > lo) hi--; + + y <<= 40; + lo = y + x; + if (lo < y) hi++; + + /* second reduction */ + x = y = hi; + hi >>= 24; + + x = lo - x; + if (x > lo) hi--; + + y <<= 40; + lo = y + x; + if (lo < y) hi++; + + /* third reduction */ + x = y = hi; + hi >>= 24; + + x = lo - x; + if (x > lo) hi--; + + y <<= 40; + lo = y + x; + if (lo < y) hi++; + + return (hi || lo >= m ? lo - m : lo); + } +} + +static inline void +x64_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m) +{ + *a = x64_mulmod(*a, w, m); + *b = x64_mulmod(*b, w, m); +} + +static inline void +x64_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, + mpd_uint_t m) +{ + *a0 = x64_mulmod(*a0, b0, m); + *a1 = x64_mulmod(*a1, b1, m); +} + +static inline mpd_uint_t +x64_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod) +{ + mpd_uint_t r = 1; + + while (exp > 0) { + if (exp & 1) + r = x64_mulmod(r, base, umod); + base = x64_mulmod(base, base, umod); + exp >>= 1; + } + + return r; +} + +/* END CONFIG_64 */ +#else /* CONFIG_32 */ + + +/**************************************************************************/ +/* 32-bit modular arithmetic */ +/**************************************************************************/ + +#if defined(ANSI) +#if !defined(LEGACY_COMPILER) +/* HAVE_UINT64_T */ +static inline mpd_uint_t +std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) +{ + return ((mpd_uuint_t) a * b) % m; +} + +static inline void +std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m) +{ + *a = ((mpd_uuint_t) *a * w) % m; + *b = ((mpd_uuint_t) *b * w) % m; +} + +static inline void +std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, + mpd_uint_t m) +{ + *a0 = ((mpd_uuint_t) *a0 * b0) % m; + *a1 = ((mpd_uuint_t) *a1 * b1) % m; +} +/* END HAVE_UINT64_T */ +#else +/* LEGACY_COMPILER */ +static inline mpd_uint_t +std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m) +{ + mpd_uint_t hi, lo, q, r; + _mpd_mul_words(&hi, &lo, a, b); + _mpd_div_words(&q, &r, hi, lo, m); + return r; +} + +static inline void +std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m) +{ + *a = std_mulmod(*a, w, m); + *b = std_mulmod(*b, w, m); +} + +static inline void +std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, + mpd_uint_t m) +{ + *a0 = std_mulmod(*a0, b0, m); + *a1 = std_mulmod(*a1, b1, m); +} +/* END LEGACY_COMPILER */ +#endif + +static inline mpd_uint_t +std_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod) +{ + mpd_uint_t r = 1; + + while (exp > 0) { + if (exp & 1) + r = std_mulmod(r, base, umod); + base = std_mulmod(base, base, umod); + exp >>= 1; + } + + return r; +} +#endif /* ANSI CONFIG_32 */ + + +/**************************************************************************/ +/* Pentium Pro modular arithmetic */ +/**************************************************************************/ + +/* + * A proof of the algorithm is in literature/mulmod-ppro.txt. The FPU + * control word must be set to 64-bit precision and truncation mode + * prior to using these functions. + * + * Algorithm: calculate (a * b) % p: + * + * p := prime < 2**31 + * pinv := (long double)1.0 / p (precalculated) + * + * a) n = a * b # Calculate exact product. + * b) qest = n * pinv # Calculate estimate for q = n / p. + * c) q = (qest+2**63)-2**63 # Truncate qest to the exact quotient. + * d) r = n - q * p # Calculate remainder. + * + * Remarks: + * + * - p = dmod and pinv = dinvmod. + * - dinvmod points to an array of three uint32_t, which is interpreted + * as an 80 bit long double by fldt. + * - Intel compilers prior to version 11 do not seem to handle the + * __GNUC__ inline assembly correctly. + * - random tests are provided in tests/extended/ppro_mulmod.c + */ + +#if defined(PPRO) +#if defined(ASM) + +/* Return (a * b) % dmod */ +static inline mpd_uint_t +ppro_mulmod(mpd_uint_t a, mpd_uint_t b, double *dmod, uint32_t *dinvmod) +{ + mpd_uint_t retval; + + __asm__ ( + "fildl %2\n\t" + "fildl %1\n\t" + "fmulp %%st, %%st(1)\n\t" + "fldt (%4)\n\t" + "fmul %%st(1), %%st\n\t" + "flds %5\n\t" + "fadd %%st, %%st(1)\n\t" + "fsubrp %%st, %%st(1)\n\t" + "fldl (%3)\n\t" + "fmulp %%st, %%st(1)\n\t" + "fsubrp %%st, %%st(1)\n\t" + "fistpl %0\n\t" + : "=m" (retval) + : "m" (a), "m" (b), "r" (dmod), "r" (dinvmod), "m" (MPD_TWO63) + : "st", "memory" + ); + + return retval; +} + +/* + * Two modular multiplications in parallel: + * *a0 = (*a0 * w) % dmod + * *a1 = (*a1 * w) % dmod + */ +static inline void +ppro_mulmod2c(mpd_uint_t *a0, mpd_uint_t *a1, mpd_uint_t w, + double *dmod, uint32_t *dinvmod) +{ + __asm__ ( + "fildl %2\n\t" + "fildl (%1)\n\t" + "fmul %%st(1), %%st\n\t" + "fxch %%st(1)\n\t" + "fildl (%0)\n\t" + "fmulp %%st, %%st(1) \n\t" + "fldt (%4)\n\t" + "flds %5\n\t" + "fld %%st(2)\n\t" + "fmul %%st(2)\n\t" + "fadd %%st(1)\n\t" + "fsub %%st(1)\n\t" + "fmull (%3)\n\t" + "fsubrp %%st, %%st(3)\n\t" + "fxch %%st(2)\n\t" + "fistpl (%0)\n\t" + "fmul %%st(2)\n\t" + "fadd %%st(1)\n\t" + "fsubp %%st, %%st(1)\n\t" + "fmull (%3)\n\t" + "fsubrp %%st, %%st(1)\n\t" + "fistpl (%1)\n\t" + : : "r" (a0), "r" (a1), "m" (w), + "r" (dmod), "r" (dinvmod), + "m" (MPD_TWO63) + : "st", "memory" + ); +} + +/* + * Two modular multiplications in parallel: + * *a0 = (*a0 * b0) % dmod + * *a1 = (*a1 * b1) % dmod + */ +static inline void +ppro_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, + double *dmod, uint32_t *dinvmod) +{ + __asm__ ( + "fildl %3\n\t" + "fildl (%2)\n\t" + "fmulp %%st, %%st(1)\n\t" + "fildl %1\n\t" + "fildl (%0)\n\t" + "fmulp %%st, %%st(1)\n\t" + "fldt (%5)\n\t" + "fld %%st(2)\n\t" + "fmul %%st(1), %%st\n\t" + "fxch %%st(1)\n\t" + "fmul %%st(2), %%st\n\t" + "flds %6\n\t" + "fldl (%4)\n\t" + "fxch %%st(3)\n\t" + "fadd %%st(1), %%st\n\t" + "fxch %%st(2)\n\t" + "fadd %%st(1), %%st\n\t" + "fxch %%st(2)\n\t" + "fsub %%st(1), %%st\n\t" + "fxch %%st(2)\n\t" + "fsubp %%st, %%st(1)\n\t" + "fxch %%st(1)\n\t" + "fmul %%st(2), %%st\n\t" + "fxch %%st(1)\n\t" + "fmulp %%st, %%st(2)\n\t" + "fsubrp %%st, %%st(3)\n\t" + "fsubrp %%st, %%st(1)\n\t" + "fxch %%st(1)\n\t" + "fistpl (%2)\n\t" + "fistpl (%0)\n\t" + : : "r" (a0), "m" (b0), "r" (a1), "m" (b1), + "r" (dmod), "r" (dinvmod), + "m" (MPD_TWO63) + : "st", "memory" + ); +} +/* END PPRO GCC ASM */ +#elif defined(MASM) + +/* Return (a * b) % dmod */ +static inline mpd_uint_t __cdecl +ppro_mulmod(mpd_uint_t a, mpd_uint_t b, double *dmod, uint32_t *dinvmod) +{ + mpd_uint_t retval; + + __asm { + mov eax, dinvmod + mov edx, dmod + fild b + fild a + fmulp st(1), st + fld TBYTE PTR [eax] + fmul st, st(1) + fld MPD_TWO63 + fadd st(1), st + fsubp st(1), st + fld QWORD PTR [edx] + fmulp st(1), st + fsubp st(1), st + fistp retval + } + + return retval; +} + +/* + * Two modular multiplications in parallel: + * *a0 = (*a0 * w) % dmod + * *a1 = (*a1 * w) % dmod + */ +static inline mpd_uint_t __cdecl +ppro_mulmod2c(mpd_uint_t *a0, mpd_uint_t *a1, mpd_uint_t w, + double *dmod, uint32_t *dinvmod) +{ + __asm { + mov ecx, dmod + mov edx, a1 + mov ebx, dinvmod + mov eax, a0 + fild w + fild DWORD PTR [edx] + fmul st, st(1) + fxch st(1) + fild DWORD PTR [eax] + fmulp st(1), st + fld TBYTE PTR [ebx] + fld MPD_TWO63 + fld st(2) + fmul st, st(2) + fadd st, st(1) + fsub st, st(1) + fmul QWORD PTR [ecx] + fsubp st(3), st + fxch st(2) + fistp DWORD PTR [eax] + fmul st, st(2) + fadd st, st(1) + fsubrp st(1), st + fmul QWORD PTR [ecx] + fsubp st(1), st + fistp DWORD PTR [edx] + } +} + +/* + * Two modular multiplications in parallel: + * *a0 = (*a0 * b0) % dmod + * *a1 = (*a1 * b1) % dmod + */ +static inline void __cdecl +ppro_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1, + double *dmod, uint32_t *dinvmod) +{ + __asm { + mov ecx, dmod + mov edx, a1 + mov ebx, dinvmod + mov eax, a0 + fild b1 + fild DWORD PTR [edx] + fmulp st(1), st + fild b0 + fild DWORD PTR [eax] + fmulp st(1), st + fld TBYTE PTR [ebx] + fld st(2) + fmul st, st(1) + fxch st(1) + fmul st, st(2) + fld DWORD PTR MPD_TWO63 + fld QWORD PTR [ecx] + fxch st(3) + fadd st, st(1) + fxch st(2) + fadd st, st(1) + fxch st(2) + fsub st, st(1) + fxch st(2) + fsubrp st(1), st + fxch st(1) + fmul st, st(2) + fxch st(1) + fmulp st(2), st + fsubp st(3), st + fsubp st(1), st + fxch st(1) + fistp DWORD PTR [edx] + fistp DWORD PTR [eax] + } +} +#endif /* PPRO MASM (_MSC_VER) */ + + +/* Return (base ** exp) % dmod */ +static inline mpd_uint_t +ppro_powmod(mpd_uint_t base, mpd_uint_t exp, double *dmod, uint32_t *dinvmod) +{ + mpd_uint_t r = 1; + + while (exp > 0) { + if (exp & 1) + r = ppro_mulmod(r, base, dmod, dinvmod); + base = ppro_mulmod(base, base, dmod, dinvmod); + exp >>= 1; + } + + return r; +} +#endif /* PPRO */ +#endif /* CONFIG_32 */ + + #endif /* LIBMPDEC_UMODARITH_H_ */ diff --git a/contrib/tools/python3/src/Modules/_decimal/libmpdec/vccompat.h b/contrib/tools/python3/src/Modules/_decimal/libmpdec/vccompat.h index e2e1c42cc02..e473ac370bf 100644 --- a/contrib/tools/python3/src/Modules/_decimal/libmpdec/vccompat.h +++ b/contrib/tools/python3/src/Modules/_decimal/libmpdec/vccompat.h @@ -1,56 +1,56 @@ -/* +/* * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + #ifndef LIBMPDEC_VCCOMPAT_H_ #define LIBMPDEC_VCCOMPAT_H_ - - + + /* Visual C fixes: no snprintf ... */ -#ifdef _MSC_VER +#ifdef _MSC_VER #ifndef __cplusplus #undef inline #define inline __inline #endif - #undef random - #define random rand - #undef srandom - #define srandom srand - #undef snprintf - #define snprintf sprintf_s - #define HAVE_SNPRINTF - #undef strncasecmp - #define strncasecmp _strnicmp - #undef strcasecmp - #define strcasecmp _stricmp - #undef strtoll - #define strtoll _strtoi64 - #define strdup _strdup -#endif - - + #undef random + #define random rand + #undef srandom + #define srandom srand + #undef snprintf + #define snprintf sprintf_s + #define HAVE_SNPRINTF + #undef strncasecmp + #define strncasecmp _strnicmp + #undef strcasecmp + #define strcasecmp _stricmp + #undef strtoll + #define strtoll _strtoi64 + #define strdup _strdup +#endif + + #endif /* LIBMPDEC_VCCOMPAT_H_ */ diff --git a/contrib/tools/python3/src/Modules/_elementtree.c b/contrib/tools/python3/src/Modules/_elementtree.c index d9c2a23ccb8..d7d81e86796 100644 --- a/contrib/tools/python3/src/Modules/_elementtree.c +++ b/contrib/tools/python3/src/Modules/_elementtree.c @@ -1,106 +1,106 @@ -/*-------------------------------------------------------------------- - * Licensed to PSF under a Contributor Agreement. +/*-------------------------------------------------------------------- + * Licensed to PSF under a Contributor Agreement. * See https://www.python.org/psf/license for licensing details. - * - * _elementtree - C accelerator for xml.etree.ElementTree - * Copyright (c) 1999-2009 by Secret Labs AB. All rights reserved. - * Copyright (c) 1999-2009 by Fredrik Lundh. - * - * info@pythonware.com - * http://www.pythonware.com - *-------------------------------------------------------------------- - */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" + * + * _elementtree - C accelerator for xml.etree.ElementTree + * Copyright (c) 1999-2009 by Secret Labs AB. All rights reserved. + * Copyright (c) 1999-2009 by Fredrik Lundh. + * + * info@pythonware.com + * http://www.pythonware.com + *-------------------------------------------------------------------- + */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" #include "structmember.h" // PyMemberDef - -/* -------------------------------------------------------------------- */ -/* configuration */ - -/* An element can hold this many children without extra memory - allocations. */ -#define STATIC_CHILDREN 4 - -/* For best performance, chose a value so that 80-90% of all nodes - have no more than the given number of children. Set this to zero - to minimize the size of the element structure itself (this only - helps if you have lots of leaf nodes with attributes). */ - -/* Also note that pymalloc always allocates blocks in multiples of - eight bytes. For the current C version of ElementTree, this means - that the number of children should be an even number, at least on - 32-bit platforms. */ - -/* -------------------------------------------------------------------- */ - -#if 0 -static int memory = 0; -#define ALLOC(size, comment)\ -do { memory += size; printf("%8d - %s\n", memory, comment); } while (0) -#define RELEASE(size, comment)\ -do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0) -#else -#define ALLOC(size, comment) -#define RELEASE(size, comment) -#endif - -/* compiler tweaks */ -#if defined(_MSC_VER) -#define LOCAL(type) static __inline type __fastcall -#else -#define LOCAL(type) static type -#endif - -/* macros used to store 'join' flags in string object pointers. note - that all use of text and tail as object pointers must be wrapped in - JOIN_OBJ. see comments in the ElementObject definition for more - info. */ -#define JOIN_GET(p) ((uintptr_t) (p) & 1) -#define JOIN_SET(p, flag) ((void*) ((uintptr_t) (JOIN_OBJ(p)) | (flag))) -#define JOIN_OBJ(p) ((PyObject*) ((uintptr_t) (p) & ~(uintptr_t)1)) - -/* Py_SETREF for a PyObject* that uses a join flag. */ -Py_LOCAL_INLINE(void) -_set_joined_ptr(PyObject **p, PyObject *new_joined_ptr) -{ - PyObject *tmp = JOIN_OBJ(*p); - *p = new_joined_ptr; - Py_DECREF(tmp); -} - -/* Py_CLEAR for a PyObject* that uses a join flag. Pass the pointer by - * reference since this function sets it to NULL. -*/ -static void _clear_joined_ptr(PyObject **p) -{ - if (*p) { - _set_joined_ptr(p, NULL); - } -} - -/* Types defined by this extension */ -static PyTypeObject Element_Type; -static PyTypeObject ElementIter_Type; -static PyTypeObject TreeBuilder_Type; -static PyTypeObject XMLParser_Type; - - -/* Per-module state; PEP 3121 */ -typedef struct { - PyObject *parseerror_obj; - PyObject *deepcopy_obj; - PyObject *elementpath_obj; + +/* -------------------------------------------------------------------- */ +/* configuration */ + +/* An element can hold this many children without extra memory + allocations. */ +#define STATIC_CHILDREN 4 + +/* For best performance, chose a value so that 80-90% of all nodes + have no more than the given number of children. Set this to zero + to minimize the size of the element structure itself (this only + helps if you have lots of leaf nodes with attributes). */ + +/* Also note that pymalloc always allocates blocks in multiples of + eight bytes. For the current C version of ElementTree, this means + that the number of children should be an even number, at least on + 32-bit platforms. */ + +/* -------------------------------------------------------------------- */ + +#if 0 +static int memory = 0; +#define ALLOC(size, comment)\ +do { memory += size; printf("%8d - %s\n", memory, comment); } while (0) +#define RELEASE(size, comment)\ +do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0) +#else +#define ALLOC(size, comment) +#define RELEASE(size, comment) +#endif + +/* compiler tweaks */ +#if defined(_MSC_VER) +#define LOCAL(type) static __inline type __fastcall +#else +#define LOCAL(type) static type +#endif + +/* macros used to store 'join' flags in string object pointers. note + that all use of text and tail as object pointers must be wrapped in + JOIN_OBJ. see comments in the ElementObject definition for more + info. */ +#define JOIN_GET(p) ((uintptr_t) (p) & 1) +#define JOIN_SET(p, flag) ((void*) ((uintptr_t) (JOIN_OBJ(p)) | (flag))) +#define JOIN_OBJ(p) ((PyObject*) ((uintptr_t) (p) & ~(uintptr_t)1)) + +/* Py_SETREF for a PyObject* that uses a join flag. */ +Py_LOCAL_INLINE(void) +_set_joined_ptr(PyObject **p, PyObject *new_joined_ptr) +{ + PyObject *tmp = JOIN_OBJ(*p); + *p = new_joined_ptr; + Py_DECREF(tmp); +} + +/* Py_CLEAR for a PyObject* that uses a join flag. Pass the pointer by + * reference since this function sets it to NULL. +*/ +static void _clear_joined_ptr(PyObject **p) +{ + if (*p) { + _set_joined_ptr(p, NULL); + } +} + +/* Types defined by this extension */ +static PyTypeObject Element_Type; +static PyTypeObject ElementIter_Type; +static PyTypeObject TreeBuilder_Type; +static PyTypeObject XMLParser_Type; + + +/* Per-module state; PEP 3121 */ +typedef struct { + PyObject *parseerror_obj; + PyObject *deepcopy_obj; + PyObject *elementpath_obj; PyObject *comment_factory; PyObject *pi_factory; -} elementtreestate; - -static struct PyModuleDef elementtreemodule; - -/* Given a module object (assumed to be _elementtree), get its per-module - * state. - */ +} elementtreestate; + +static struct PyModuleDef elementtreemodule; + +/* Given a module object (assumed to be _elementtree), get its per-module + * state. + */ static inline elementtreestate* get_elementtree_state(PyObject *module) { @@ -108,394 +108,394 @@ get_elementtree_state(PyObject *module) assert(state != NULL); return (elementtreestate *)state; } - -/* Find the module instance imported in the currently running sub-interpreter - * and get its state. - */ -#define ET_STATE_GLOBAL \ - ((elementtreestate *) PyModule_GetState(PyState_FindModule(&elementtreemodule))) - -static int -elementtree_clear(PyObject *m) -{ + +/* Find the module instance imported in the currently running sub-interpreter + * and get its state. + */ +#define ET_STATE_GLOBAL \ + ((elementtreestate *) PyModule_GetState(PyState_FindModule(&elementtreemodule))) + +static int +elementtree_clear(PyObject *m) +{ elementtreestate *st = get_elementtree_state(m); - Py_CLEAR(st->parseerror_obj); - Py_CLEAR(st->deepcopy_obj); - Py_CLEAR(st->elementpath_obj); + Py_CLEAR(st->parseerror_obj); + Py_CLEAR(st->deepcopy_obj); + Py_CLEAR(st->elementpath_obj); Py_CLEAR(st->comment_factory); Py_CLEAR(st->pi_factory); - return 0; -} - -static int -elementtree_traverse(PyObject *m, visitproc visit, void *arg) -{ + return 0; +} + +static int +elementtree_traverse(PyObject *m, visitproc visit, void *arg) +{ elementtreestate *st = get_elementtree_state(m); - Py_VISIT(st->parseerror_obj); - Py_VISIT(st->deepcopy_obj); - Py_VISIT(st->elementpath_obj); + Py_VISIT(st->parseerror_obj); + Py_VISIT(st->deepcopy_obj); + Py_VISIT(st->elementpath_obj); Py_VISIT(st->comment_factory); Py_VISIT(st->pi_factory); - return 0; -} - -static void -elementtree_free(void *m) -{ - elementtree_clear((PyObject *)m); -} - -/* helpers */ - -LOCAL(PyObject*) -list_join(PyObject* list) -{ - /* join list elements */ - PyObject* joiner; - PyObject* result; - - joiner = PyUnicode_FromStringAndSize("", 0); - if (!joiner) - return NULL; - result = PyUnicode_Join(joiner, list); - Py_DECREF(joiner); - return result; -} - -/* Is the given object an empty dictionary? -*/ -static int -is_empty_dict(PyObject *obj) -{ - return PyDict_CheckExact(obj) && PyDict_GET_SIZE(obj) == 0; -} - - -/* -------------------------------------------------------------------- */ -/* the Element type */ - -typedef struct { - + return 0; +} + +static void +elementtree_free(void *m) +{ + elementtree_clear((PyObject *)m); +} + +/* helpers */ + +LOCAL(PyObject*) +list_join(PyObject* list) +{ + /* join list elements */ + PyObject* joiner; + PyObject* result; + + joiner = PyUnicode_FromStringAndSize("", 0); + if (!joiner) + return NULL; + result = PyUnicode_Join(joiner, list); + Py_DECREF(joiner); + return result; +} + +/* Is the given object an empty dictionary? +*/ +static int +is_empty_dict(PyObject *obj) +{ + return PyDict_CheckExact(obj) && PyDict_GET_SIZE(obj) == 0; +} + + +/* -------------------------------------------------------------------- */ +/* the Element type */ + +typedef struct { + /* attributes (a dictionary object), or NULL if no attributes */ - PyObject* attrib; - - /* child elements */ - Py_ssize_t length; /* actual number of items */ - Py_ssize_t allocated; /* allocated items */ - - /* this either points to _children or to a malloced buffer */ - PyObject* *children; - - PyObject* _children[STATIC_CHILDREN]; - -} ElementObjectExtra; - -typedef struct { - PyObject_HEAD - - /* element tag (a string). */ - PyObject* tag; - - /* text before first child. note that this is a tagged pointer; - use JOIN_OBJ to get the object pointer. the join flag is used - to distinguish lists created by the tree builder from lists - assigned to the attribute by application code; the former - should be joined before being returned to the user, the latter - should be left intact. */ - PyObject* text; - - /* text after this element, in parent. note that this is a tagged - pointer; use JOIN_OBJ to get the object pointer. */ - PyObject* tail; - - ElementObjectExtra* extra; - - PyObject *weakreflist; /* For tp_weaklistoffset */ - -} ElementObject; - - + PyObject* attrib; + + /* child elements */ + Py_ssize_t length; /* actual number of items */ + Py_ssize_t allocated; /* allocated items */ + + /* this either points to _children or to a malloced buffer */ + PyObject* *children; + + PyObject* _children[STATIC_CHILDREN]; + +} ElementObjectExtra; + +typedef struct { + PyObject_HEAD + + /* element tag (a string). */ + PyObject* tag; + + /* text before first child. note that this is a tagged pointer; + use JOIN_OBJ to get the object pointer. the join flag is used + to distinguish lists created by the tree builder from lists + assigned to the attribute by application code; the former + should be joined before being returned to the user, the latter + should be left intact. */ + PyObject* text; + + /* text after this element, in parent. note that this is a tagged + pointer; use JOIN_OBJ to get the object pointer. */ + PyObject* tail; + + ElementObjectExtra* extra; + + PyObject *weakreflist; /* For tp_weaklistoffset */ + +} ElementObject; + + #define Element_CheckExact(op) Py_IS_TYPE(op, &Element_Type) -#define Element_Check(op) PyObject_TypeCheck(op, &Element_Type) - - -/* -------------------------------------------------------------------- */ -/* Element constructors and destructor */ - -LOCAL(int) -create_extra(ElementObject* self, PyObject* attrib) -{ - self->extra = PyObject_Malloc(sizeof(ElementObjectExtra)); - if (!self->extra) { - PyErr_NoMemory(); - return -1; - } - +#define Element_Check(op) PyObject_TypeCheck(op, &Element_Type) + + +/* -------------------------------------------------------------------- */ +/* Element constructors and destructor */ + +LOCAL(int) +create_extra(ElementObject* self, PyObject* attrib) +{ + self->extra = PyObject_Malloc(sizeof(ElementObjectExtra)); + if (!self->extra) { + PyErr_NoMemory(); + return -1; + } + Py_XINCREF(attrib); - self->extra->attrib = attrib; - - self->extra->length = 0; - self->extra->allocated = STATIC_CHILDREN; - self->extra->children = self->extra->_children; - - return 0; -} - -LOCAL(void) -dealloc_extra(ElementObjectExtra *extra) -{ - Py_ssize_t i; - - if (!extra) - return; - + self->extra->attrib = attrib; + + self->extra->length = 0; + self->extra->allocated = STATIC_CHILDREN; + self->extra->children = self->extra->_children; + + return 0; +} + +LOCAL(void) +dealloc_extra(ElementObjectExtra *extra) +{ + Py_ssize_t i; + + if (!extra) + return; + Py_XDECREF(extra->attrib); - - for (i = 0; i < extra->length; i++) - Py_DECREF(extra->children[i]); - - if (extra->children != extra->_children) - PyObject_Free(extra->children); - - PyObject_Free(extra); -} - -LOCAL(void) -clear_extra(ElementObject* self) -{ - ElementObjectExtra *myextra; - - if (!self->extra) - return; - - /* Avoid DECREFs calling into this code again (cycles, etc.) - */ - myextra = self->extra; - self->extra = NULL; - - dealloc_extra(myextra); -} - -/* Convenience internal function to create new Element objects with the given - * tag and attributes. -*/ -LOCAL(PyObject*) -create_new_element(PyObject* tag, PyObject* attrib) -{ - ElementObject* self; - - self = PyObject_GC_New(ElementObject, &Element_Type); - if (self == NULL) - return NULL; - self->extra = NULL; - - Py_INCREF(tag); - self->tag = tag; - - Py_INCREF(Py_None); - self->text = Py_None; - - Py_INCREF(Py_None); - self->tail = Py_None; - - self->weakreflist = NULL; - - ALLOC(sizeof(ElementObject), "create element"); - PyObject_GC_Track(self); - + + for (i = 0; i < extra->length; i++) + Py_DECREF(extra->children[i]); + + if (extra->children != extra->_children) + PyObject_Free(extra->children); + + PyObject_Free(extra); +} + +LOCAL(void) +clear_extra(ElementObject* self) +{ + ElementObjectExtra *myextra; + + if (!self->extra) + return; + + /* Avoid DECREFs calling into this code again (cycles, etc.) + */ + myextra = self->extra; + self->extra = NULL; + + dealloc_extra(myextra); +} + +/* Convenience internal function to create new Element objects with the given + * tag and attributes. +*/ +LOCAL(PyObject*) +create_new_element(PyObject* tag, PyObject* attrib) +{ + ElementObject* self; + + self = PyObject_GC_New(ElementObject, &Element_Type); + if (self == NULL) + return NULL; + self->extra = NULL; + + Py_INCREF(tag); + self->tag = tag; + + Py_INCREF(Py_None); + self->text = Py_None; + + Py_INCREF(Py_None); + self->tail = Py_None; + + self->weakreflist = NULL; + + ALLOC(sizeof(ElementObject), "create element"); + PyObject_GC_Track(self); + if (attrib != NULL && !is_empty_dict(attrib)) { - if (create_extra(self, attrib) < 0) { - Py_DECREF(self); - return NULL; - } - } - - return (PyObject*) self; -} - -static PyObject * -element_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - ElementObject *e = (ElementObject *)type->tp_alloc(type, 0); - if (e != NULL) { - Py_INCREF(Py_None); - e->tag = Py_None; - - Py_INCREF(Py_None); - e->text = Py_None; - - Py_INCREF(Py_None); - e->tail = Py_None; - - e->extra = NULL; - e->weakreflist = NULL; - } - return (PyObject *)e; -} - -/* Helper function for extracting the attrib dictionary from a keywords dict. - * This is required by some constructors/functions in this module that can - * either accept attrib as a keyword argument or all attributes splashed - * directly into *kwds. - * - * Return a dictionary with the content of kwds merged into the content of - * attrib. If there is no attrib keyword, return a copy of kwds. - */ -static PyObject* -get_attrib_from_keywords(PyObject *kwds) -{ - PyObject *attrib_str = PyUnicode_FromString("attrib"); - if (attrib_str == NULL) { - return NULL; - } + if (create_extra(self, attrib) < 0) { + Py_DECREF(self); + return NULL; + } + } + + return (PyObject*) self; +} + +static PyObject * +element_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + ElementObject *e = (ElementObject *)type->tp_alloc(type, 0); + if (e != NULL) { + Py_INCREF(Py_None); + e->tag = Py_None; + + Py_INCREF(Py_None); + e->text = Py_None; + + Py_INCREF(Py_None); + e->tail = Py_None; + + e->extra = NULL; + e->weakreflist = NULL; + } + return (PyObject *)e; +} + +/* Helper function for extracting the attrib dictionary from a keywords dict. + * This is required by some constructors/functions in this module that can + * either accept attrib as a keyword argument or all attributes splashed + * directly into *kwds. + * + * Return a dictionary with the content of kwds merged into the content of + * attrib. If there is no attrib keyword, return a copy of kwds. + */ +static PyObject* +get_attrib_from_keywords(PyObject *kwds) +{ + PyObject *attrib_str = PyUnicode_FromString("attrib"); + if (attrib_str == NULL) { + return NULL; + } PyObject *attrib = PyDict_GetItemWithError(kwds, attrib_str); - - if (attrib) { - /* If attrib was found in kwds, copy its value and remove it from - * kwds - */ - if (!PyDict_Check(attrib)) { - Py_DECREF(attrib_str); - PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.100s", - Py_TYPE(attrib)->tp_name); - return NULL; - } - attrib = PyDict_Copy(attrib); - if (attrib && PyDict_DelItem(kwds, attrib_str) < 0) { - Py_DECREF(attrib); - attrib = NULL; - } + + if (attrib) { + /* If attrib was found in kwds, copy its value and remove it from + * kwds + */ + if (!PyDict_Check(attrib)) { + Py_DECREF(attrib_str); + PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.100s", + Py_TYPE(attrib)->tp_name); + return NULL; + } + attrib = PyDict_Copy(attrib); + if (attrib && PyDict_DelItem(kwds, attrib_str) < 0) { + Py_DECREF(attrib); + attrib = NULL; + } } else if (!PyErr_Occurred()) { - attrib = PyDict_New(); - } - - Py_DECREF(attrib_str); - - if (attrib != NULL && PyDict_Update(attrib, kwds) < 0) { - Py_DECREF(attrib); - return NULL; - } - return attrib; -} - -/*[clinic input] -module _elementtree -class _elementtree.Element "ElementObject *" "&Element_Type" -class _elementtree.TreeBuilder "TreeBuilderObject *" "&TreeBuilder_Type" -class _elementtree.XMLParser "XMLParserObject *" "&XMLParser_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=159aa50a54061c22]*/ - -static int -element_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - PyObject *tag; - PyObject *attrib = NULL; - ElementObject *self_elem; - - if (!PyArg_ParseTuple(args, "O|O!:Element", &tag, &PyDict_Type, &attrib)) - return -1; - - if (attrib) { - /* attrib passed as positional arg */ - attrib = PyDict_Copy(attrib); - if (!attrib) - return -1; - if (kwds) { - if (PyDict_Update(attrib, kwds) < 0) { - Py_DECREF(attrib); - return -1; - } - } - } else if (kwds) { - /* have keywords args */ - attrib = get_attrib_from_keywords(kwds); - if (!attrib) - return -1; - } - - self_elem = (ElementObject *)self; - - if (attrib != NULL && !is_empty_dict(attrib)) { - if (create_extra(self_elem, attrib) < 0) { - Py_DECREF(attrib); - return -1; - } - } - - /* We own a reference to attrib here and it's no longer needed. */ - Py_XDECREF(attrib); - - /* Replace the objects already pointed to by tag, text and tail. */ - Py_INCREF(tag); - Py_XSETREF(self_elem->tag, tag); - - Py_INCREF(Py_None); - _set_joined_ptr(&self_elem->text, Py_None); - - Py_INCREF(Py_None); - _set_joined_ptr(&self_elem->tail, Py_None); - - return 0; -} - -LOCAL(int) -element_resize(ElementObject* self, Py_ssize_t extra) -{ - Py_ssize_t size; - PyObject* *children; - - assert(extra >= 0); - /* make sure self->children can hold the given number of extra - elements. set an exception and return -1 if allocation failed */ - - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return -1; - } - - size = self->extra->length + extra; /* never overflows */ - - if (size > self->extra->allocated) { - /* use Python 2.4's list growth strategy */ - size = (size >> 3) + (size < 9 ? 3 : 6) + size; - /* Coverity CID #182 size_error: Allocating 1 bytes to pointer "children" - * which needs at least 4 bytes. - * Although it's a false alarm always assume at least one child to - * be safe. - */ - size = size ? size : 1; - if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*)) - goto nomemory; - if (self->extra->children != self->extra->_children) { - /* Coverity CID #182 size_error: Allocating 1 bytes to pointer - * "children", which needs at least 4 bytes. Although it's a - * false alarm always assume at least one child to be safe. - */ - children = PyObject_Realloc(self->extra->children, - size * sizeof(PyObject*)); - if (!children) - goto nomemory; - } else { - children = PyObject_Malloc(size * sizeof(PyObject*)); - if (!children) - goto nomemory; - /* copy existing children from static area to malloc buffer */ - memcpy(children, self->extra->children, - self->extra->length * sizeof(PyObject*)); - } - self->extra->children = children; - self->extra->allocated = size; - } - - return 0; - - nomemory: - PyErr_NoMemory(); - return -1; -} - + attrib = PyDict_New(); + } + + Py_DECREF(attrib_str); + + if (attrib != NULL && PyDict_Update(attrib, kwds) < 0) { + Py_DECREF(attrib); + return NULL; + } + return attrib; +} + +/*[clinic input] +module _elementtree +class _elementtree.Element "ElementObject *" "&Element_Type" +class _elementtree.TreeBuilder "TreeBuilderObject *" "&TreeBuilder_Type" +class _elementtree.XMLParser "XMLParserObject *" "&XMLParser_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=159aa50a54061c22]*/ + +static int +element_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *tag; + PyObject *attrib = NULL; + ElementObject *self_elem; + + if (!PyArg_ParseTuple(args, "O|O!:Element", &tag, &PyDict_Type, &attrib)) + return -1; + + if (attrib) { + /* attrib passed as positional arg */ + attrib = PyDict_Copy(attrib); + if (!attrib) + return -1; + if (kwds) { + if (PyDict_Update(attrib, kwds) < 0) { + Py_DECREF(attrib); + return -1; + } + } + } else if (kwds) { + /* have keywords args */ + attrib = get_attrib_from_keywords(kwds); + if (!attrib) + return -1; + } + + self_elem = (ElementObject *)self; + + if (attrib != NULL && !is_empty_dict(attrib)) { + if (create_extra(self_elem, attrib) < 0) { + Py_DECREF(attrib); + return -1; + } + } + + /* We own a reference to attrib here and it's no longer needed. */ + Py_XDECREF(attrib); + + /* Replace the objects already pointed to by tag, text and tail. */ + Py_INCREF(tag); + Py_XSETREF(self_elem->tag, tag); + + Py_INCREF(Py_None); + _set_joined_ptr(&self_elem->text, Py_None); + + Py_INCREF(Py_None); + _set_joined_ptr(&self_elem->tail, Py_None); + + return 0; +} + +LOCAL(int) +element_resize(ElementObject* self, Py_ssize_t extra) +{ + Py_ssize_t size; + PyObject* *children; + + assert(extra >= 0); + /* make sure self->children can hold the given number of extra + elements. set an exception and return -1 if allocation failed */ + + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return -1; + } + + size = self->extra->length + extra; /* never overflows */ + + if (size > self->extra->allocated) { + /* use Python 2.4's list growth strategy */ + size = (size >> 3) + (size < 9 ? 3 : 6) + size; + /* Coverity CID #182 size_error: Allocating 1 bytes to pointer "children" + * which needs at least 4 bytes. + * Although it's a false alarm always assume at least one child to + * be safe. + */ + size = size ? size : 1; + if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*)) + goto nomemory; + if (self->extra->children != self->extra->_children) { + /* Coverity CID #182 size_error: Allocating 1 bytes to pointer + * "children", which needs at least 4 bytes. Although it's a + * false alarm always assume at least one child to be safe. + */ + children = PyObject_Realloc(self->extra->children, + size * sizeof(PyObject*)); + if (!children) + goto nomemory; + } else { + children = PyObject_Malloc(size * sizeof(PyObject*)); + if (!children) + goto nomemory; + /* copy existing children from static area to malloc buffer */ + memcpy(children, self->extra->children, + self->extra->length * sizeof(PyObject*)); + } + self->extra->children = children; + self->extra->allocated = size; + } + + return 0; + + nomemory: + PyErr_NoMemory(); + return -1; +} + LOCAL(void) raise_type_error(PyObject *element) { @@ -504,655 +504,655 @@ raise_type_error(PyObject *element) Py_TYPE(element)->tp_name); } -LOCAL(int) -element_add_subelement(ElementObject* self, PyObject* element) -{ - /* add a child element to a parent */ - +LOCAL(int) +element_add_subelement(ElementObject* self, PyObject* element) +{ + /* add a child element to a parent */ + if (!Element_Check(element)) { raise_type_error(element); return -1; } - if (element_resize(self, 1) < 0) - return -1; - - Py_INCREF(element); - self->extra->children[self->extra->length] = element; - - self->extra->length++; - - return 0; -} - -LOCAL(PyObject*) -element_get_attrib(ElementObject* self) -{ - /* return borrowed reference to attrib dictionary */ - /* note: this function assumes that the extra section exists */ - - PyObject* res = self->extra->attrib; - + if (element_resize(self, 1) < 0) + return -1; + + Py_INCREF(element); + self->extra->children[self->extra->length] = element; + + self->extra->length++; + + return 0; +} + +LOCAL(PyObject*) +element_get_attrib(ElementObject* self) +{ + /* return borrowed reference to attrib dictionary */ + /* note: this function assumes that the extra section exists */ + + PyObject* res = self->extra->attrib; + if (!res) { - /* create missing dictionary */ + /* create missing dictionary */ res = self->extra->attrib = PyDict_New(); - } - - return res; -} - -LOCAL(PyObject*) -element_get_text(ElementObject* self) -{ - /* return borrowed reference to text attribute */ - - PyObject *res = self->text; - - if (JOIN_GET(res)) { - res = JOIN_OBJ(res); - if (PyList_CheckExact(res)) { - PyObject *tmp = list_join(res); - if (!tmp) - return NULL; - self->text = tmp; - Py_DECREF(res); - res = tmp; + } + + return res; +} + +LOCAL(PyObject*) +element_get_text(ElementObject* self) +{ + /* return borrowed reference to text attribute */ + + PyObject *res = self->text; + + if (JOIN_GET(res)) { + res = JOIN_OBJ(res); + if (PyList_CheckExact(res)) { + PyObject *tmp = list_join(res); + if (!tmp) + return NULL; + self->text = tmp; + Py_DECREF(res); + res = tmp; + } + } + + return res; +} + +LOCAL(PyObject*) +element_get_tail(ElementObject* self) +{ + /* return borrowed reference to text attribute */ + + PyObject *res = self->tail; + + if (JOIN_GET(res)) { + res = JOIN_OBJ(res); + if (PyList_CheckExact(res)) { + PyObject *tmp = list_join(res); + if (!tmp) + return NULL; + self->tail = tmp; + Py_DECREF(res); + res = tmp; + } + } + + return res; +} + +static PyObject* +subelement(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject* elem; + + ElementObject* parent; + PyObject* tag; + PyObject* attrib = NULL; + if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", + &Element_Type, &parent, &tag, + &PyDict_Type, &attrib)) { + return NULL; + } + + if (attrib) { + /* attrib passed as positional arg */ + attrib = PyDict_Copy(attrib); + if (!attrib) + return NULL; + if (kwds != NULL && PyDict_Update(attrib, kwds) < 0) { + Py_DECREF(attrib); + return NULL; + } + } else if (kwds) { + /* have keyword args */ + attrib = get_attrib_from_keywords(kwds); + if (!attrib) + return NULL; + } else { + /* no attrib arg, no kwds, so no attribute */ + } + + elem = create_new_element(tag, attrib); + Py_XDECREF(attrib); + if (elem == NULL) + return NULL; + + if (element_add_subelement(parent, elem) < 0) { + Py_DECREF(elem); + return NULL; + } + + return elem; +} + +static int +element_gc_traverse(ElementObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->tag); + Py_VISIT(JOIN_OBJ(self->text)); + Py_VISIT(JOIN_OBJ(self->tail)); + + if (self->extra) { + Py_ssize_t i; + Py_VISIT(self->extra->attrib); + + for (i = 0; i < self->extra->length; ++i) + Py_VISIT(self->extra->children[i]); + } + return 0; +} + +static int +element_gc_clear(ElementObject *self) +{ + Py_CLEAR(self->tag); + _clear_joined_ptr(&self->text); + _clear_joined_ptr(&self->tail); + + /* After dropping all references from extra, it's no longer valid anyway, + * so fully deallocate it. + */ + clear_extra(self); + return 0; +} + +static void +element_dealloc(ElementObject* self) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(self); + Py_TRASHCAN_BEGIN(self, element_dealloc) + + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + + /* element_gc_clear clears all references and deallocates extra + */ + element_gc_clear(self); + + RELEASE(sizeof(ElementObject), "destroy element"); + Py_TYPE(self)->tp_free((PyObject *)self); + Py_TRASHCAN_END +} + +/* -------------------------------------------------------------------- */ + +/*[clinic input] +_elementtree.Element.append + + subelement: object(subclass_of='&Element_Type') + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement) +/*[clinic end generated code: output=54a884b7cf2295f4 input=3ed648beb5bfa22a]*/ +{ + if (element_add_subelement(self, subelement) < 0) + return NULL; + + Py_RETURN_NONE; +} + +/*[clinic input] +_elementtree.Element.clear + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_clear_impl(ElementObject *self) +/*[clinic end generated code: output=8bcd7a51f94cfff6 input=3c719ff94bf45dd6]*/ +{ + clear_extra(self); + + Py_INCREF(Py_None); + _set_joined_ptr(&self->text, Py_None); + + Py_INCREF(Py_None); + _set_joined_ptr(&self->tail, Py_None); + + Py_RETURN_NONE; +} + +/*[clinic input] +_elementtree.Element.__copy__ + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element___copy___impl(ElementObject *self) +/*[clinic end generated code: output=2c701ebff7247781 input=ad87aaebe95675bf]*/ +{ + Py_ssize_t i; + ElementObject* element; + + element = (ElementObject*) create_new_element( + self->tag, self->extra ? self->extra->attrib : NULL); + if (!element) + return NULL; + + Py_INCREF(JOIN_OBJ(self->text)); + _set_joined_ptr(&element->text, self->text); + + Py_INCREF(JOIN_OBJ(self->tail)); + _set_joined_ptr(&element->tail, self->tail); + + assert(!element->extra || !element->extra->length); + if (self->extra) { + if (element_resize(element, self->extra->length) < 0) { + Py_DECREF(element); + return NULL; + } + + for (i = 0; i < self->extra->length; i++) { + Py_INCREF(self->extra->children[i]); + element->extra->children[i] = self->extra->children[i]; + } + + assert(!element->extra->length); + element->extra->length = self->extra->length; + } + + return (PyObject*) element; +} + +/* Helper for a deep copy. */ +LOCAL(PyObject *) deepcopy(PyObject *, PyObject *); + +/*[clinic input] +_elementtree.Element.__deepcopy__ + + memo: object(subclass_of="&PyDict_Type") + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) +/*[clinic end generated code: output=eefc3df50465b642 input=a2d40348c0aade10]*/ +{ + Py_ssize_t i; + ElementObject* element; + PyObject* tag; + PyObject* attrib; + PyObject* text; + PyObject* tail; + PyObject* id; + + tag = deepcopy(self->tag, memo); + if (!tag) + return NULL; + + if (self->extra && self->extra->attrib) { + attrib = deepcopy(self->extra->attrib, memo); + if (!attrib) { + Py_DECREF(tag); + return NULL; + } + } else { + attrib = NULL; + } + + element = (ElementObject*) create_new_element(tag, attrib); + + Py_DECREF(tag); + Py_XDECREF(attrib); + + if (!element) + return NULL; + + text = deepcopy(JOIN_OBJ(self->text), memo); + if (!text) + goto error; + _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text))); + + tail = deepcopy(JOIN_OBJ(self->tail), memo); + if (!tail) + goto error; + _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail))); + + assert(!element->extra || !element->extra->length); + if (self->extra) { + if (element_resize(element, self->extra->length) < 0) + goto error; + + for (i = 0; i < self->extra->length; i++) { + PyObject* child = deepcopy(self->extra->children[i], memo); + if (!child || !Element_Check(child)) { + if (child) { + raise_type_error(child); + Py_DECREF(child); + } + element->extra->length = i; + goto error; + } + element->extra->children[i] = child; + } + + assert(!element->extra->length); + element->extra->length = self->extra->length; + } + + /* add object to memo dictionary (so deepcopy won't visit it again) */ + id = PyLong_FromSsize_t((uintptr_t) self); + if (!id) + goto error; + + i = PyDict_SetItem(memo, id, (PyObject*) element); + + Py_DECREF(id); + + if (i < 0) + goto error; + + return (PyObject*) element; + + error: + Py_DECREF(element); + return NULL; +} + +LOCAL(PyObject *) +deepcopy(PyObject *object, PyObject *memo) +{ + /* do a deep copy of the given object */ + elementtreestate *st; + PyObject *stack[2]; + + /* Fast paths */ + if (object == Py_None || PyUnicode_CheckExact(object)) { + Py_INCREF(object); + return object; + } + + if (Py_REFCNT(object) == 1) { + if (PyDict_CheckExact(object)) { + PyObject *key, *value; + Py_ssize_t pos = 0; + int simple = 1; + while (PyDict_Next(object, &pos, &key, &value)) { + if (!PyUnicode_CheckExact(key) || !PyUnicode_CheckExact(value)) { + simple = 0; + break; + } + } + if (simple) + return PyDict_Copy(object); + /* Fall through to general case */ + } + else if (Element_CheckExact(object)) { + return _elementtree_Element___deepcopy___impl( + (ElementObject *)object, memo); + } + } + + /* General case */ + st = ET_STATE_GLOBAL; + if (!st->deepcopy_obj) { + PyErr_SetString(PyExc_RuntimeError, + "deepcopy helper not found"); + return NULL; + } + + stack[0] = object; + stack[1] = memo; + return _PyObject_FastCall(st->deepcopy_obj, stack, 2); +} + + +/*[clinic input] +_elementtree.Element.__sizeof__ -> Py_ssize_t + +[clinic start generated code]*/ + +static Py_ssize_t +_elementtree_Element___sizeof___impl(ElementObject *self) +/*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/ +{ + Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self)); + if (self->extra) { + result += sizeof(ElementObjectExtra); + if (self->extra->children != self->extra->_children) + result += sizeof(PyObject*) * self->extra->allocated; + } + return result; +} + +/* dict keys for getstate/setstate. */ +#define PICKLED_TAG "tag" +#define PICKLED_CHILDREN "_children" +#define PICKLED_ATTRIB "attrib" +#define PICKLED_TAIL "tail" +#define PICKLED_TEXT "text" + +/* __getstate__ returns a fabricated instance dict as in the pure-Python + * Element implementation, for interoperability/interchangeability. This + * makes the pure-Python implementation details an API, but (a) there aren't + * any unnecessary structures there; and (b) it buys compatibility with 3.2 + * pickles. See issue #16076. + */ +/*[clinic input] +_elementtree.Element.__getstate__ + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element___getstate___impl(ElementObject *self) +/*[clinic end generated code: output=37279aeeb6bb5b04 input=f0d16d7ec2f7adc1]*/ +{ + Py_ssize_t i; + PyObject *children, *attrib; + + /* Build a list of children. */ + children = PyList_New(self->extra ? self->extra->length : 0); + if (!children) + return NULL; + for (i = 0; i < PyList_GET_SIZE(children); i++) { + PyObject *child = self->extra->children[i]; + Py_INCREF(child); + PyList_SET_ITEM(children, i, child); + } + + if (self->extra && self->extra->attrib) { + attrib = self->extra->attrib; + Py_INCREF(attrib); + } + else { + attrib = PyDict_New(); + if (!attrib) { + Py_DECREF(children); + return NULL; } } - - return res; -} - -LOCAL(PyObject*) -element_get_tail(ElementObject* self) -{ - /* return borrowed reference to text attribute */ - - PyObject *res = self->tail; - - if (JOIN_GET(res)) { - res = JOIN_OBJ(res); - if (PyList_CheckExact(res)) { - PyObject *tmp = list_join(res); - if (!tmp) + + return Py_BuildValue("{sOsNsNsOsO}", + PICKLED_TAG, self->tag, + PICKLED_CHILDREN, children, + PICKLED_ATTRIB, attrib, + PICKLED_TEXT, JOIN_OBJ(self->text), + PICKLED_TAIL, JOIN_OBJ(self->tail)); +} + +static PyObject * +element_setstate_from_attributes(ElementObject *self, + PyObject *tag, + PyObject *attrib, + PyObject *text, + PyObject *tail, + PyObject *children) +{ + Py_ssize_t i, nchildren; + ElementObjectExtra *oldextra = NULL; + + if (!tag) { + PyErr_SetString(PyExc_TypeError, "tag may not be NULL"); + return NULL; + } + + Py_INCREF(tag); + Py_XSETREF(self->tag, tag); + + text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None; + Py_INCREF(JOIN_OBJ(text)); + _set_joined_ptr(&self->text, text); + + tail = tail ? JOIN_SET(tail, PyList_CheckExact(tail)) : Py_None; + Py_INCREF(JOIN_OBJ(tail)); + _set_joined_ptr(&self->tail, tail); + + /* Handle ATTRIB and CHILDREN. */ + if (!children && !attrib) { + Py_RETURN_NONE; + } + + /* Compute 'nchildren'. */ + if (children) { + if (!PyList_Check(children)) { + PyErr_SetString(PyExc_TypeError, "'_children' is not a list"); + return NULL; + } + nchildren = PyList_GET_SIZE(children); + + /* (Re-)allocate 'extra'. + Avoid DECREFs calling into this code again (cycles, etc.) + */ + oldextra = self->extra; + self->extra = NULL; + if (element_resize(self, nchildren)) { + assert(!self->extra || !self->extra->length); + clear_extra(self); + self->extra = oldextra; + return NULL; + } + assert(self->extra); + assert(self->extra->allocated >= nchildren); + if (oldextra) { + assert(self->extra->attrib == NULL); + self->extra->attrib = oldextra->attrib; + oldextra->attrib = NULL; + } + + /* Copy children */ + for (i = 0; i < nchildren; i++) { + PyObject *child = PyList_GET_ITEM(children, i); + if (!Element_Check(child)) { + raise_type_error(child); + self->extra->length = i; + dealloc_extra(oldextra); return NULL; - self->tail = tmp; - Py_DECREF(res); - res = tmp; - } - } - - return res; -} - -static PyObject* -subelement(PyObject *self, PyObject *args, PyObject *kwds) -{ - PyObject* elem; - - ElementObject* parent; - PyObject* tag; - PyObject* attrib = NULL; - if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", - &Element_Type, &parent, &tag, - &PyDict_Type, &attrib)) { - return NULL; - } - - if (attrib) { - /* attrib passed as positional arg */ - attrib = PyDict_Copy(attrib); - if (!attrib) - return NULL; - if (kwds != NULL && PyDict_Update(attrib, kwds) < 0) { - Py_DECREF(attrib); - return NULL; + } + Py_INCREF(child); + self->extra->children[i] = child; + } + + assert(!self->extra->length); + self->extra->length = nchildren; + } + else { + if (element_resize(self, 0)) { + return NULL; + } + } + + /* Stash attrib. */ + Py_XINCREF(attrib); + Py_XSETREF(self->extra->attrib, attrib); + dealloc_extra(oldextra); + + Py_RETURN_NONE; +} + +/* __setstate__ for Element instance from the Python implementation. + * 'state' should be the instance dict. + */ + +static PyObject * +element_setstate_from_Python(ElementObject *self, PyObject *state) +{ + static char *kwlist[] = {PICKLED_TAG, PICKLED_ATTRIB, PICKLED_TEXT, + PICKLED_TAIL, PICKLED_CHILDREN, 0}; + PyObject *args; + PyObject *tag, *attrib, *text, *tail, *children; + PyObject *retval; + + tag = attrib = text = tail = children = NULL; + args = PyTuple_New(0); + if (!args) + return NULL; + + if (PyArg_ParseTupleAndKeywords(args, state, "|$OOOOO", kwlist, &tag, + &attrib, &text, &tail, &children)) + retval = element_setstate_from_attributes(self, tag, attrib, text, + tail, children); + else + retval = NULL; + + Py_DECREF(args); + return retval; +} + +/*[clinic input] +_elementtree.Element.__setstate__ + + state: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element___setstate__(ElementObject *self, PyObject *state) +/*[clinic end generated code: output=ea28bf3491b1f75e input=aaf80abea7c1e3b9]*/ +{ + if (!PyDict_CheckExact(state)) { + PyErr_Format(PyExc_TypeError, + "Don't know how to unpickle \"%.200R\" as an Element", + state); + return NULL; + } + else + return element_setstate_from_Python(self, state); +} + +LOCAL(int) +checkpath(PyObject* tag) +{ + Py_ssize_t i; + int check = 1; + + /* check if a tag contains an xpath character */ + +#define PATHCHAR(ch) \ + (ch == '/' || ch == '*' || ch == '[' || ch == '@' || ch == '.') + + if (PyUnicode_Check(tag)) { + const Py_ssize_t len = PyUnicode_GET_LENGTH(tag); + const void *data = PyUnicode_DATA(tag); + unsigned int kind = PyUnicode_KIND(tag); + if (len >= 3 && PyUnicode_READ(kind, data, 0) == '{' && ( + PyUnicode_READ(kind, data, 1) == '}' || ( + PyUnicode_READ(kind, data, 1) == '*' && + PyUnicode_READ(kind, data, 2) == '}'))) { + /* wildcard: '{}tag' or '{*}tag' */ + return 1; } - } else if (kwds) { - /* have keyword args */ - attrib = get_attrib_from_keywords(kwds); - if (!attrib) - return NULL; - } else { - /* no attrib arg, no kwds, so no attribute */ - } - - elem = create_new_element(tag, attrib); - Py_XDECREF(attrib); - if (elem == NULL) - return NULL; - - if (element_add_subelement(parent, elem) < 0) { - Py_DECREF(elem); - return NULL; - } - - return elem; -} - -static int -element_gc_traverse(ElementObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->tag); - Py_VISIT(JOIN_OBJ(self->text)); - Py_VISIT(JOIN_OBJ(self->tail)); - - if (self->extra) { - Py_ssize_t i; - Py_VISIT(self->extra->attrib); - - for (i = 0; i < self->extra->length; ++i) - Py_VISIT(self->extra->children[i]); - } - return 0; -} - -static int -element_gc_clear(ElementObject *self) -{ - Py_CLEAR(self->tag); - _clear_joined_ptr(&self->text); - _clear_joined_ptr(&self->tail); - - /* After dropping all references from extra, it's no longer valid anyway, - * so fully deallocate it. - */ - clear_extra(self); - return 0; -} - -static void -element_dealloc(ElementObject* self) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(self); - Py_TRASHCAN_BEGIN(self, element_dealloc) - - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - - /* element_gc_clear clears all references and deallocates extra - */ - element_gc_clear(self); - - RELEASE(sizeof(ElementObject), "destroy element"); - Py_TYPE(self)->tp_free((PyObject *)self); - Py_TRASHCAN_END -} - -/* -------------------------------------------------------------------- */ - -/*[clinic input] -_elementtree.Element.append - - subelement: object(subclass_of='&Element_Type') - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=54a884b7cf2295f4 input=3ed648beb5bfa22a]*/ -{ - if (element_add_subelement(self, subelement) < 0) - return NULL; - - Py_RETURN_NONE; -} - -/*[clinic input] -_elementtree.Element.clear - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_clear_impl(ElementObject *self) -/*[clinic end generated code: output=8bcd7a51f94cfff6 input=3c719ff94bf45dd6]*/ -{ - clear_extra(self); - - Py_INCREF(Py_None); - _set_joined_ptr(&self->text, Py_None); - - Py_INCREF(Py_None); - _set_joined_ptr(&self->tail, Py_None); - - Py_RETURN_NONE; -} - -/*[clinic input] -_elementtree.Element.__copy__ - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element___copy___impl(ElementObject *self) -/*[clinic end generated code: output=2c701ebff7247781 input=ad87aaebe95675bf]*/ -{ - Py_ssize_t i; - ElementObject* element; - - element = (ElementObject*) create_new_element( - self->tag, self->extra ? self->extra->attrib : NULL); - if (!element) - return NULL; - - Py_INCREF(JOIN_OBJ(self->text)); - _set_joined_ptr(&element->text, self->text); - - Py_INCREF(JOIN_OBJ(self->tail)); - _set_joined_ptr(&element->tail, self->tail); - - assert(!element->extra || !element->extra->length); - if (self->extra) { - if (element_resize(element, self->extra->length) < 0) { - Py_DECREF(element); - return NULL; - } - - for (i = 0; i < self->extra->length; i++) { - Py_INCREF(self->extra->children[i]); - element->extra->children[i] = self->extra->children[i]; - } - - assert(!element->extra->length); - element->extra->length = self->extra->length; - } - - return (PyObject*) element; -} - -/* Helper for a deep copy. */ -LOCAL(PyObject *) deepcopy(PyObject *, PyObject *); - -/*[clinic input] -_elementtree.Element.__deepcopy__ - - memo: object(subclass_of="&PyDict_Type") - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) -/*[clinic end generated code: output=eefc3df50465b642 input=a2d40348c0aade10]*/ -{ - Py_ssize_t i; - ElementObject* element; - PyObject* tag; - PyObject* attrib; - PyObject* text; - PyObject* tail; - PyObject* id; - - tag = deepcopy(self->tag, memo); - if (!tag) - return NULL; - - if (self->extra && self->extra->attrib) { - attrib = deepcopy(self->extra->attrib, memo); - if (!attrib) { - Py_DECREF(tag); - return NULL; - } - } else { - attrib = NULL; - } - - element = (ElementObject*) create_new_element(tag, attrib); - - Py_DECREF(tag); - Py_XDECREF(attrib); - - if (!element) - return NULL; - - text = deepcopy(JOIN_OBJ(self->text), memo); - if (!text) - goto error; - _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text))); - - tail = deepcopy(JOIN_OBJ(self->tail), memo); - if (!tail) - goto error; - _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail))); - - assert(!element->extra || !element->extra->length); - if (self->extra) { - if (element_resize(element, self->extra->length) < 0) - goto error; - - for (i = 0; i < self->extra->length; i++) { - PyObject* child = deepcopy(self->extra->children[i], memo); - if (!child || !Element_Check(child)) { - if (child) { - raise_type_error(child); - Py_DECREF(child); - } - element->extra->length = i; - goto error; - } - element->extra->children[i] = child; - } - - assert(!element->extra->length); - element->extra->length = self->extra->length; - } - - /* add object to memo dictionary (so deepcopy won't visit it again) */ - id = PyLong_FromSsize_t((uintptr_t) self); - if (!id) - goto error; - - i = PyDict_SetItem(memo, id, (PyObject*) element); - - Py_DECREF(id); - - if (i < 0) - goto error; - - return (PyObject*) element; - - error: - Py_DECREF(element); - return NULL; -} - -LOCAL(PyObject *) -deepcopy(PyObject *object, PyObject *memo) -{ - /* do a deep copy of the given object */ - elementtreestate *st; - PyObject *stack[2]; - - /* Fast paths */ - if (object == Py_None || PyUnicode_CheckExact(object)) { - Py_INCREF(object); - return object; - } - - if (Py_REFCNT(object) == 1) { - if (PyDict_CheckExact(object)) { - PyObject *key, *value; - Py_ssize_t pos = 0; - int simple = 1; - while (PyDict_Next(object, &pos, &key, &value)) { - if (!PyUnicode_CheckExact(key) || !PyUnicode_CheckExact(value)) { - simple = 0; - break; - } - } - if (simple) - return PyDict_Copy(object); - /* Fall through to general case */ - } - else if (Element_CheckExact(object)) { - return _elementtree_Element___deepcopy___impl( - (ElementObject *)object, memo); - } - } - - /* General case */ - st = ET_STATE_GLOBAL; - if (!st->deepcopy_obj) { - PyErr_SetString(PyExc_RuntimeError, - "deepcopy helper not found"); - return NULL; - } - - stack[0] = object; - stack[1] = memo; - return _PyObject_FastCall(st->deepcopy_obj, stack, 2); -} - - -/*[clinic input] -_elementtree.Element.__sizeof__ -> Py_ssize_t - -[clinic start generated code]*/ - -static Py_ssize_t -_elementtree_Element___sizeof___impl(ElementObject *self) -/*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/ -{ - Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self)); - if (self->extra) { - result += sizeof(ElementObjectExtra); - if (self->extra->children != self->extra->_children) - result += sizeof(PyObject*) * self->extra->allocated; - } - return result; -} - -/* dict keys for getstate/setstate. */ -#define PICKLED_TAG "tag" -#define PICKLED_CHILDREN "_children" -#define PICKLED_ATTRIB "attrib" -#define PICKLED_TAIL "tail" -#define PICKLED_TEXT "text" - -/* __getstate__ returns a fabricated instance dict as in the pure-Python - * Element implementation, for interoperability/interchangeability. This - * makes the pure-Python implementation details an API, but (a) there aren't - * any unnecessary structures there; and (b) it buys compatibility with 3.2 - * pickles. See issue #16076. - */ -/*[clinic input] -_elementtree.Element.__getstate__ - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element___getstate___impl(ElementObject *self) -/*[clinic end generated code: output=37279aeeb6bb5b04 input=f0d16d7ec2f7adc1]*/ -{ - Py_ssize_t i; - PyObject *children, *attrib; - - /* Build a list of children. */ - children = PyList_New(self->extra ? self->extra->length : 0); - if (!children) - return NULL; - for (i = 0; i < PyList_GET_SIZE(children); i++) { - PyObject *child = self->extra->children[i]; - Py_INCREF(child); - PyList_SET_ITEM(children, i, child); - } - - if (self->extra && self->extra->attrib) { - attrib = self->extra->attrib; - Py_INCREF(attrib); - } - else { - attrib = PyDict_New(); - if (!attrib) { - Py_DECREF(children); - return NULL; - } - } - - return Py_BuildValue("{sOsNsNsOsO}", - PICKLED_TAG, self->tag, - PICKLED_CHILDREN, children, - PICKLED_ATTRIB, attrib, - PICKLED_TEXT, JOIN_OBJ(self->text), - PICKLED_TAIL, JOIN_OBJ(self->tail)); -} - -static PyObject * -element_setstate_from_attributes(ElementObject *self, - PyObject *tag, - PyObject *attrib, - PyObject *text, - PyObject *tail, - PyObject *children) -{ - Py_ssize_t i, nchildren; - ElementObjectExtra *oldextra = NULL; - - if (!tag) { - PyErr_SetString(PyExc_TypeError, "tag may not be NULL"); - return NULL; - } - - Py_INCREF(tag); - Py_XSETREF(self->tag, tag); - - text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None; - Py_INCREF(JOIN_OBJ(text)); - _set_joined_ptr(&self->text, text); - - tail = tail ? JOIN_SET(tail, PyList_CheckExact(tail)) : Py_None; - Py_INCREF(JOIN_OBJ(tail)); - _set_joined_ptr(&self->tail, tail); - - /* Handle ATTRIB and CHILDREN. */ - if (!children && !attrib) { - Py_RETURN_NONE; - } - - /* Compute 'nchildren'. */ - if (children) { - if (!PyList_Check(children)) { - PyErr_SetString(PyExc_TypeError, "'_children' is not a list"); - return NULL; - } - nchildren = PyList_GET_SIZE(children); - - /* (Re-)allocate 'extra'. - Avoid DECREFs calling into this code again (cycles, etc.) - */ - oldextra = self->extra; - self->extra = NULL; - if (element_resize(self, nchildren)) { - assert(!self->extra || !self->extra->length); - clear_extra(self); - self->extra = oldextra; - return NULL; - } - assert(self->extra); - assert(self->extra->allocated >= nchildren); - if (oldextra) { - assert(self->extra->attrib == NULL); - self->extra->attrib = oldextra->attrib; - oldextra->attrib = NULL; - } - - /* Copy children */ - for (i = 0; i < nchildren; i++) { - PyObject *child = PyList_GET_ITEM(children, i); - if (!Element_Check(child)) { - raise_type_error(child); - self->extra->length = i; - dealloc_extra(oldextra); - return NULL; - } - Py_INCREF(child); - self->extra->children[i] = child; - } - - assert(!self->extra->length); - self->extra->length = nchildren; - } - else { - if (element_resize(self, 0)) { - return NULL; - } - } - - /* Stash attrib. */ - Py_XINCREF(attrib); - Py_XSETREF(self->extra->attrib, attrib); - dealloc_extra(oldextra); - - Py_RETURN_NONE; -} - -/* __setstate__ for Element instance from the Python implementation. - * 'state' should be the instance dict. - */ - -static PyObject * -element_setstate_from_Python(ElementObject *self, PyObject *state) -{ - static char *kwlist[] = {PICKLED_TAG, PICKLED_ATTRIB, PICKLED_TEXT, - PICKLED_TAIL, PICKLED_CHILDREN, 0}; - PyObject *args; - PyObject *tag, *attrib, *text, *tail, *children; - PyObject *retval; - - tag = attrib = text = tail = children = NULL; - args = PyTuple_New(0); - if (!args) - return NULL; - - if (PyArg_ParseTupleAndKeywords(args, state, "|$OOOOO", kwlist, &tag, - &attrib, &text, &tail, &children)) - retval = element_setstate_from_attributes(self, tag, attrib, text, - tail, children); - else - retval = NULL; - - Py_DECREF(args); - return retval; -} - -/*[clinic input] -_elementtree.Element.__setstate__ - - state: object - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element___setstate__(ElementObject *self, PyObject *state) -/*[clinic end generated code: output=ea28bf3491b1f75e input=aaf80abea7c1e3b9]*/ -{ - if (!PyDict_CheckExact(state)) { - PyErr_Format(PyExc_TypeError, - "Don't know how to unpickle \"%.200R\" as an Element", - state); - return NULL; - } - else - return element_setstate_from_Python(self, state); -} - -LOCAL(int) -checkpath(PyObject* tag) -{ - Py_ssize_t i; - int check = 1; - - /* check if a tag contains an xpath character */ - -#define PATHCHAR(ch) \ - (ch == '/' || ch == '*' || ch == '[' || ch == '@' || ch == '.') - - if (PyUnicode_Check(tag)) { - const Py_ssize_t len = PyUnicode_GET_LENGTH(tag); - const void *data = PyUnicode_DATA(tag); - unsigned int kind = PyUnicode_KIND(tag); - if (len >= 3 && PyUnicode_READ(kind, data, 0) == '{' && ( - PyUnicode_READ(kind, data, 1) == '}' || ( - PyUnicode_READ(kind, data, 1) == '*' && - PyUnicode_READ(kind, data, 2) == '}'))) { - /* wildcard: '{}tag' or '{*}tag' */ - return 1; - } - for (i = 0; i < len; i++) { - Py_UCS4 ch = PyUnicode_READ(kind, data, i); - if (ch == '{') - check = 0; - else if (ch == '}') - check = 1; - else if (check && PATHCHAR(ch)) - return 1; - } - return 0; - } - if (PyBytes_Check(tag)) { + for (i = 0; i < len; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (ch == '{') + check = 0; + else if (ch == '}') + check = 1; + else if (check && PATHCHAR(ch)) + return 1; + } + return 0; + } + if (PyBytes_Check(tag)) { const char *p = PyBytes_AS_STRING(tag); const Py_ssize_t len = PyBytes_GET_SIZE(tag); if (len >= 3 && p[0] == '{' && ( @@ -1160,239 +1160,239 @@ checkpath(PyObject* tag) /* wildcard: '{}tag' or '{*}tag' */ return 1; } - for (i = 0; i < len; i++) { - if (p[i] == '{') - check = 0; - else if (p[i] == '}') - check = 1; - else if (check && PATHCHAR(p[i])) - return 1; - } - return 0; - } - - return 1; /* unknown type; might be path expression */ -} - -/*[clinic input] -_elementtree.Element.extend - - elements: object - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_extend(ElementObject *self, PyObject *elements) -/*[clinic end generated code: output=f6e67fc2ff529191 input=807bc4f31c69f7c0]*/ -{ - PyObject* seq; - Py_ssize_t i; - - seq = PySequence_Fast(elements, ""); - if (!seq) { - PyErr_Format( - PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name - ); - return NULL; - } - - for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) { - PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(element); - if (element_add_subelement(self, element) < 0) { - Py_DECREF(seq); - Py_DECREF(element); - return NULL; - } - Py_DECREF(element); - } - - Py_DECREF(seq); - - Py_RETURN_NONE; -} - -/*[clinic input] -_elementtree.Element.find - - path: object - namespaces: object = None - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_find_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=41b43f0f0becafae input=359b6985f6489d2e]*/ -{ - Py_ssize_t i; - elementtreestate *st = ET_STATE_GLOBAL; - - if (checkpath(path) || namespaces != Py_None) { - _Py_IDENTIFIER(find); - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_find, self, path, namespaces, NULL - ); - } - - if (!self->extra) - Py_RETURN_NONE; - - for (i = 0; i < self->extra->length; i++) { - PyObject* item = self->extra->children[i]; - int rc; - assert(Element_Check(item)); - Py_INCREF(item); - rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); - if (rc > 0) - return item; - Py_DECREF(item); - if (rc < 0) - return NULL; - } - - Py_RETURN_NONE; -} - -/*[clinic input] -_elementtree.Element.findtext - - path: object - default: object = None - namespaces: object = None - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, - PyObject *default_value, - PyObject *namespaces) -/*[clinic end generated code: output=83b3ba4535d308d2 input=b53a85aa5aa2a916]*/ -{ - Py_ssize_t i; - _Py_IDENTIFIER(findtext); - elementtreestate *st = ET_STATE_GLOBAL; - - if (checkpath(path) || namespaces != Py_None) - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_findtext, - self, path, default_value, namespaces, NULL - ); - - if (!self->extra) { - Py_INCREF(default_value); - return default_value; - } - - for (i = 0; i < self->extra->length; i++) { - PyObject *item = self->extra->children[i]; - int rc; - assert(Element_Check(item)); - Py_INCREF(item); - rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); - if (rc > 0) { - PyObject* text = element_get_text((ElementObject*)item); - if (text == Py_None) { - Py_DECREF(item); - return PyUnicode_New(0, 0); - } - Py_XINCREF(text); - Py_DECREF(item); - return text; - } - Py_DECREF(item); - if (rc < 0) - return NULL; - } - - Py_INCREF(default_value); - return default_value; -} - -/*[clinic input] -_elementtree.Element.findall - - path: object - namespaces: object = None - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=1a0bd9f5541b711d input=4d9e6505a638550c]*/ -{ - Py_ssize_t i; - PyObject* out; - elementtreestate *st = ET_STATE_GLOBAL; - - if (checkpath(path) || namespaces != Py_None) { - _Py_IDENTIFIER(findall); - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_findall, self, path, namespaces, NULL - ); - } - - out = PyList_New(0); - if (!out) - return NULL; - - if (!self->extra) - return out; - - for (i = 0; i < self->extra->length; i++) { - PyObject* item = self->extra->children[i]; - int rc; - assert(Element_Check(item)); - Py_INCREF(item); - rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); - if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) { - Py_DECREF(item); - Py_DECREF(out); - return NULL; - } - Py_DECREF(item); - } - - return out; -} - -/*[clinic input] -_elementtree.Element.iterfind - - path: object - namespaces: object = None - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=ecdd56d63b19d40f input=abb974e350fb65c7]*/ -{ - PyObject* tag = path; - _Py_IDENTIFIER(iterfind); - elementtreestate *st = ET_STATE_GLOBAL; - - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_iterfind, self, tag, namespaces, NULL); -} - -/*[clinic input] -_elementtree.Element.get - - key: object - default: object = None - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_get_impl(ElementObject *self, PyObject *key, - PyObject *default_value) -/*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/ -{ + for (i = 0; i < len; i++) { + if (p[i] == '{') + check = 0; + else if (p[i] == '}') + check = 1; + else if (check && PATHCHAR(p[i])) + return 1; + } + return 0; + } + + return 1; /* unknown type; might be path expression */ +} + +/*[clinic input] +_elementtree.Element.extend + + elements: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_extend(ElementObject *self, PyObject *elements) +/*[clinic end generated code: output=f6e67fc2ff529191 input=807bc4f31c69f7c0]*/ +{ + PyObject* seq; + Py_ssize_t i; + + seq = PySequence_Fast(elements, ""); + if (!seq) { + PyErr_Format( + PyExc_TypeError, + "expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name + ); + return NULL; + } + + for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) { + PyObject* element = PySequence_Fast_GET_ITEM(seq, i); + Py_INCREF(element); + if (element_add_subelement(self, element) < 0) { + Py_DECREF(seq); + Py_DECREF(element); + return NULL; + } + Py_DECREF(element); + } + + Py_DECREF(seq); + + Py_RETURN_NONE; +} + +/*[clinic input] +_elementtree.Element.find + + path: object + namespaces: object = None + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_find_impl(ElementObject *self, PyObject *path, + PyObject *namespaces) +/*[clinic end generated code: output=41b43f0f0becafae input=359b6985f6489d2e]*/ +{ + Py_ssize_t i; + elementtreestate *st = ET_STATE_GLOBAL; + + if (checkpath(path) || namespaces != Py_None) { + _Py_IDENTIFIER(find); + return _PyObject_CallMethodIdObjArgs( + st->elementpath_obj, &PyId_find, self, path, namespaces, NULL + ); + } + + if (!self->extra) + Py_RETURN_NONE; + + for (i = 0; i < self->extra->length; i++) { + PyObject* item = self->extra->children[i]; + int rc; + assert(Element_Check(item)); + Py_INCREF(item); + rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); + if (rc > 0) + return item; + Py_DECREF(item); + if (rc < 0) + return NULL; + } + + Py_RETURN_NONE; +} + +/*[clinic input] +_elementtree.Element.findtext + + path: object + default: object = None + namespaces: object = None + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, + PyObject *default_value, + PyObject *namespaces) +/*[clinic end generated code: output=83b3ba4535d308d2 input=b53a85aa5aa2a916]*/ +{ + Py_ssize_t i; + _Py_IDENTIFIER(findtext); + elementtreestate *st = ET_STATE_GLOBAL; + + if (checkpath(path) || namespaces != Py_None) + return _PyObject_CallMethodIdObjArgs( + st->elementpath_obj, &PyId_findtext, + self, path, default_value, namespaces, NULL + ); + + if (!self->extra) { + Py_INCREF(default_value); + return default_value; + } + + for (i = 0; i < self->extra->length; i++) { + PyObject *item = self->extra->children[i]; + int rc; + assert(Element_Check(item)); + Py_INCREF(item); + rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); + if (rc > 0) { + PyObject* text = element_get_text((ElementObject*)item); + if (text == Py_None) { + Py_DECREF(item); + return PyUnicode_New(0, 0); + } + Py_XINCREF(text); + Py_DECREF(item); + return text; + } + Py_DECREF(item); + if (rc < 0) + return NULL; + } + + Py_INCREF(default_value); + return default_value; +} + +/*[clinic input] +_elementtree.Element.findall + + path: object + namespaces: object = None + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, + PyObject *namespaces) +/*[clinic end generated code: output=1a0bd9f5541b711d input=4d9e6505a638550c]*/ +{ + Py_ssize_t i; + PyObject* out; + elementtreestate *st = ET_STATE_GLOBAL; + + if (checkpath(path) || namespaces != Py_None) { + _Py_IDENTIFIER(findall); + return _PyObject_CallMethodIdObjArgs( + st->elementpath_obj, &PyId_findall, self, path, namespaces, NULL + ); + } + + out = PyList_New(0); + if (!out) + return NULL; + + if (!self->extra) + return out; + + for (i = 0; i < self->extra->length; i++) { + PyObject* item = self->extra->children[i]; + int rc; + assert(Element_Check(item)); + Py_INCREF(item); + rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); + if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) { + Py_DECREF(item); + Py_DECREF(out); + return NULL; + } + Py_DECREF(item); + } + + return out; +} + +/*[clinic input] +_elementtree.Element.iterfind + + path: object + namespaces: object = None + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, + PyObject *namespaces) +/*[clinic end generated code: output=ecdd56d63b19d40f input=abb974e350fb65c7]*/ +{ + PyObject* tag = path; + _Py_IDENTIFIER(iterfind); + elementtreestate *st = ET_STATE_GLOBAL; + + return _PyObject_CallMethodIdObjArgs( + st->elementpath_obj, &PyId_iterfind, self, tag, namespaces, NULL); +} + +/*[clinic input] +_elementtree.Element.get + + key: object + default: object = None + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_get_impl(ElementObject *self, PyObject *key, + PyObject *default_value) +/*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/ +{ if (self->extra && self->extra->attrib) { PyObject *attrib = self->extra->attrib; Py_INCREF(attrib); @@ -1402,504 +1402,504 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key, if (value != NULL || PyErr_Occurred()) { return value; } - } - + } + Py_INCREF(default_value); return default_value; -} - -static PyObject * -create_elementiter(ElementObject *self, PyObject *tag, int gettext); - - -/*[clinic input] -_elementtree.Element.iter - - tag: object = None - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag) -/*[clinic end generated code: output=3f49f9a862941cc5 input=774d5b12e573aedd]*/ -{ - if (PyUnicode_Check(tag)) { - if (PyUnicode_READY(tag) < 0) - return NULL; - if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*') - tag = Py_None; - } - else if (PyBytes_Check(tag)) { - if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*') - tag = Py_None; - } - - return create_elementiter(self, tag, 0); -} - - -/*[clinic input] -_elementtree.Element.itertext - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_itertext_impl(ElementObject *self) -/*[clinic end generated code: output=5fa34b2fbcb65df6 input=af8f0e42cb239c89]*/ -{ - return create_elementiter(self, Py_None, 1); -} - - -static PyObject* -element_getitem(PyObject* self_, Py_ssize_t index) -{ - ElementObject* self = (ElementObject*) self_; - - if (!self->extra || index < 0 || index >= self->extra->length) { - PyErr_SetString( - PyExc_IndexError, - "child index out of range" - ); - return NULL; - } - - Py_INCREF(self->extra->children[index]); - return self->extra->children[index]; -} - -/*[clinic input] -_elementtree.Element.insert - - index: Py_ssize_t - subelement: object(subclass_of='&Element_Type') - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, - PyObject *subelement) -/*[clinic end generated code: output=990adfef4d424c0b input=cd6fbfcdab52d7a8]*/ -{ - Py_ssize_t i; - - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return NULL; - } - - if (index < 0) { - index += self->extra->length; - if (index < 0) - index = 0; - } - if (index > self->extra->length) - index = self->extra->length; - - if (element_resize(self, 1) < 0) - return NULL; - - for (i = self->extra->length; i > index; i--) - self->extra->children[i] = self->extra->children[i-1]; - - Py_INCREF(subelement); - self->extra->children[index] = subelement; - - self->extra->length++; - - Py_RETURN_NONE; -} - -/*[clinic input] -_elementtree.Element.items - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_items_impl(ElementObject *self) -/*[clinic end generated code: output=6db2c778ce3f5a4d input=adbe09aaea474447]*/ -{ +} + +static PyObject * +create_elementiter(ElementObject *self, PyObject *tag, int gettext); + + +/*[clinic input] +_elementtree.Element.iter + + tag: object = None + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag) +/*[clinic end generated code: output=3f49f9a862941cc5 input=774d5b12e573aedd]*/ +{ + if (PyUnicode_Check(tag)) { + if (PyUnicode_READY(tag) < 0) + return NULL; + if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*') + tag = Py_None; + } + else if (PyBytes_Check(tag)) { + if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*') + tag = Py_None; + } + + return create_elementiter(self, tag, 0); +} + + +/*[clinic input] +_elementtree.Element.itertext + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_itertext_impl(ElementObject *self) +/*[clinic end generated code: output=5fa34b2fbcb65df6 input=af8f0e42cb239c89]*/ +{ + return create_elementiter(self, Py_None, 1); +} + + +static PyObject* +element_getitem(PyObject* self_, Py_ssize_t index) +{ + ElementObject* self = (ElementObject*) self_; + + if (!self->extra || index < 0 || index >= self->extra->length) { + PyErr_SetString( + PyExc_IndexError, + "child index out of range" + ); + return NULL; + } + + Py_INCREF(self->extra->children[index]); + return self->extra->children[index]; +} + +/*[clinic input] +_elementtree.Element.insert + + index: Py_ssize_t + subelement: object(subclass_of='&Element_Type') + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, + PyObject *subelement) +/*[clinic end generated code: output=990adfef4d424c0b input=cd6fbfcdab52d7a8]*/ +{ + Py_ssize_t i; + + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return NULL; + } + + if (index < 0) { + index += self->extra->length; + if (index < 0) + index = 0; + } + if (index > self->extra->length) + index = self->extra->length; + + if (element_resize(self, 1) < 0) + return NULL; + + for (i = self->extra->length; i > index; i--) + self->extra->children[i] = self->extra->children[i-1]; + + Py_INCREF(subelement); + self->extra->children[index] = subelement; + + self->extra->length++; + + Py_RETURN_NONE; +} + +/*[clinic input] +_elementtree.Element.items + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_items_impl(ElementObject *self) +/*[clinic end generated code: output=6db2c778ce3f5a4d input=adbe09aaea474447]*/ +{ if (!self->extra || !self->extra->attrib) - return PyList_New(0); - - return PyDict_Items(self->extra->attrib); -} - -/*[clinic input] -_elementtree.Element.keys - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_keys_impl(ElementObject *self) -/*[clinic end generated code: output=bc5bfabbf20eeb3c input=f02caf5b496b5b0b]*/ -{ + return PyList_New(0); + + return PyDict_Items(self->extra->attrib); +} + +/*[clinic input] +_elementtree.Element.keys + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_keys_impl(ElementObject *self) +/*[clinic end generated code: output=bc5bfabbf20eeb3c input=f02caf5b496b5b0b]*/ +{ if (!self->extra || !self->extra->attrib) - return PyList_New(0); - - return PyDict_Keys(self->extra->attrib); -} - -static Py_ssize_t -element_length(ElementObject* self) -{ - if (!self->extra) - return 0; - - return self->extra->length; -} - -/*[clinic input] -_elementtree.Element.makeelement - - tag: object + return PyList_New(0); + + return PyDict_Keys(self->extra->attrib); +} + +static Py_ssize_t +element_length(ElementObject* self) +{ + if (!self->extra) + return 0; + + return self->extra->length; +} + +/*[clinic input] +_elementtree.Element.makeelement + + tag: object attrib: object(subclass_of='&PyDict_Type') - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, - PyObject *attrib) + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, + PyObject *attrib) /*[clinic end generated code: output=4109832d5bb789ef input=2279d974529c3861]*/ -{ - PyObject* elem; - - attrib = PyDict_Copy(attrib); - if (!attrib) - return NULL; - - elem = create_new_element(tag, attrib); - - Py_DECREF(attrib); - - return elem; -} - -/*[clinic input] -_elementtree.Element.remove - - subelement: object(subclass_of='&Element_Type') - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=38fe6c07d6d87d1f input=d52fc28ededc0bd8]*/ -{ - Py_ssize_t i; - int rc; - PyObject *found; - - if (!self->extra) { - /* element has no children, so raise exception */ - PyErr_SetString( - PyExc_ValueError, - "list.remove(x): x not in list" - ); - return NULL; - } - - for (i = 0; i < self->extra->length; i++) { - if (self->extra->children[i] == subelement) - break; - rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ); - if (rc > 0) - break; - if (rc < 0) - return NULL; - } - - if (i >= self->extra->length) { - /* subelement is not in children, so raise exception */ - PyErr_SetString( - PyExc_ValueError, - "list.remove(x): x not in list" - ); - return NULL; - } - - found = self->extra->children[i]; - - self->extra->length--; - for (; i < self->extra->length; i++) - self->extra->children[i] = self->extra->children[i+1]; - - Py_DECREF(found); - Py_RETURN_NONE; -} - -static PyObject* -element_repr(ElementObject* self) -{ - int status; - - if (self->tag == NULL) - return PyUnicode_FromFormat("", self); - - status = Py_ReprEnter((PyObject *)self); - if (status == 0) { - PyObject *res; - res = PyUnicode_FromFormat("", self->tag, self); - Py_ReprLeave((PyObject *)self); - return res; - } - if (status > 0) - PyErr_Format(PyExc_RuntimeError, - "reentrant call inside %s.__repr__", - Py_TYPE(self)->tp_name); - return NULL; -} - -/*[clinic input] -_elementtree.Element.set - - key: object - value: object - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_Element_set_impl(ElementObject *self, PyObject *key, - PyObject *value) -/*[clinic end generated code: output=fb938806be3c5656 input=1efe90f7d82b3fe9]*/ -{ - PyObject* attrib; - - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return NULL; - } - - attrib = element_get_attrib(self); - if (!attrib) - return NULL; - - if (PyDict_SetItem(attrib, key, value) < 0) - return NULL; - - Py_RETURN_NONE; -} - -static int -element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) -{ - ElementObject* self = (ElementObject*) self_; - Py_ssize_t i; - PyObject* old; - - if (!self->extra || index < 0 || index >= self->extra->length) { - PyErr_SetString( - PyExc_IndexError, - "child assignment index out of range"); - return -1; - } - - old = self->extra->children[index]; - - if (item) { +{ + PyObject* elem; + + attrib = PyDict_Copy(attrib); + if (!attrib) + return NULL; + + elem = create_new_element(tag, attrib); + + Py_DECREF(attrib); + + return elem; +} + +/*[clinic input] +_elementtree.Element.remove + + subelement: object(subclass_of='&Element_Type') + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement) +/*[clinic end generated code: output=38fe6c07d6d87d1f input=d52fc28ededc0bd8]*/ +{ + Py_ssize_t i; + int rc; + PyObject *found; + + if (!self->extra) { + /* element has no children, so raise exception */ + PyErr_SetString( + PyExc_ValueError, + "list.remove(x): x not in list" + ); + return NULL; + } + + for (i = 0; i < self->extra->length; i++) { + if (self->extra->children[i] == subelement) + break; + rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ); + if (rc > 0) + break; + if (rc < 0) + return NULL; + } + + if (i >= self->extra->length) { + /* subelement is not in children, so raise exception */ + PyErr_SetString( + PyExc_ValueError, + "list.remove(x): x not in list" + ); + return NULL; + } + + found = self->extra->children[i]; + + self->extra->length--; + for (; i < self->extra->length; i++) + self->extra->children[i] = self->extra->children[i+1]; + + Py_DECREF(found); + Py_RETURN_NONE; +} + +static PyObject* +element_repr(ElementObject* self) +{ + int status; + + if (self->tag == NULL) + return PyUnicode_FromFormat("", self); + + status = Py_ReprEnter((PyObject *)self); + if (status == 0) { + PyObject *res; + res = PyUnicode_FromFormat("", self->tag, self); + Py_ReprLeave((PyObject *)self); + return res; + } + if (status > 0) + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s.__repr__", + Py_TYPE(self)->tp_name); + return NULL; +} + +/*[clinic input] +_elementtree.Element.set + + key: object + value: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element_set_impl(ElementObject *self, PyObject *key, + PyObject *value) +/*[clinic end generated code: output=fb938806be3c5656 input=1efe90f7d82b3fe9]*/ +{ + PyObject* attrib; + + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return NULL; + } + + attrib = element_get_attrib(self); + if (!attrib) + return NULL; + + if (PyDict_SetItem(attrib, key, value) < 0) + return NULL; + + Py_RETURN_NONE; +} + +static int +element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) +{ + ElementObject* self = (ElementObject*) self_; + Py_ssize_t i; + PyObject* old; + + if (!self->extra || index < 0 || index >= self->extra->length) { + PyErr_SetString( + PyExc_IndexError, + "child assignment index out of range"); + return -1; + } + + old = self->extra->children[index]; + + if (item) { if (!Element_Check(item)) { - raise_type_error(item); - return -1; - } - Py_INCREF(item); - self->extra->children[index] = item; - } else { - self->extra->length--; - for (i = index; i < self->extra->length; i++) - self->extra->children[i] = self->extra->children[i+1]; - } - - Py_DECREF(old); - - return 0; -} - -static PyObject* -element_subscr(PyObject* self_, PyObject* item) -{ - ElementObject* self = (ElementObject*) self_; - - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - - if (i == -1 && PyErr_Occurred()) { - return NULL; - } - if (i < 0 && self->extra) - i += self->extra->length; - return element_getitem(self_, i); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelen, i; - size_t cur; - PyObject* list; - - if (!self->extra) - return PyList_New(0); - - if (PySlice_Unpack(item, &start, &stop, &step) < 0) { - return NULL; - } - slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop, - step); - - if (slicelen <= 0) - return PyList_New(0); - else { - list = PyList_New(slicelen); - if (!list) - return NULL; - - for (cur = start, i = 0; i < slicelen; - cur += step, i++) { - PyObject* item = self->extra->children[cur]; - Py_INCREF(item); - PyList_SET_ITEM(list, i, item); - } - - return list; - } - } - else { - PyErr_SetString(PyExc_TypeError, - "element indices must be integers"); - return NULL; - } -} - -static int -element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) -{ - ElementObject* self = (ElementObject*) self_; - - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - - if (i == -1 && PyErr_Occurred()) { - return -1; - } - if (i < 0 && self->extra) - i += self->extra->length; - return element_setitem(self_, i, value); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelen, newlen, i; - size_t cur; - - PyObject* recycle = NULL; - PyObject* seq; - - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return -1; - } - - if (PySlice_Unpack(item, &start, &stop, &step) < 0) { - return -1; - } - slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop, - step); - - if (value == NULL) { - /* Delete slice */ - size_t cur; - Py_ssize_t i; - - if (slicelen <= 0) - return 0; - - /* Since we're deleting, the direction of the range doesn't matter, - * so for simplicity make it always ascending. - */ - if (step < 0) { - stop = start + 1; - start = stop + step * (slicelen - 1) - 1; - step = -step; - } - - assert((size_t)slicelen <= SIZE_MAX / sizeof(PyObject *)); - - /* recycle is a list that will contain all the children - * scheduled for removal. - */ - if (!(recycle = PyList_New(slicelen))) { - return -1; - } - - /* This loop walks over all the children that have to be deleted, - * with cur pointing at them. num_moved is the amount of children - * until the next deleted child that have to be "shifted down" to - * occupy the deleted's places. - * Note that in the ith iteration, shifting is done i+i places down - * because i children were already removed. - */ - for (cur = start, i = 0; cur < (size_t)stop; cur += step, ++i) { - /* Compute how many children have to be moved, clipping at the - * list end. - */ - Py_ssize_t num_moved = step - 1; - if (cur + step >= (size_t)self->extra->length) { - num_moved = self->extra->length - cur - 1; - } - - PyList_SET_ITEM(recycle, i, self->extra->children[cur]); - - memmove( - self->extra->children + cur - i, - self->extra->children + cur + 1, - num_moved * sizeof(PyObject *)); - } - - /* Leftover "tail" after the last removed child */ - cur = start + (size_t)slicelen * step; - if (cur < (size_t)self->extra->length) { - memmove( - self->extra->children + cur - slicelen, - self->extra->children + cur, - (self->extra->length - cur) * sizeof(PyObject *)); - } - - self->extra->length -= slicelen; - - /* Discard the recycle list with all the deleted sub-elements */ - Py_DECREF(recycle); - return 0; - } - - /* A new slice is actually being assigned */ - seq = PySequence_Fast(value, ""); - if (!seq) { - PyErr_Format( - PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name - ); - return -1; - } - newlen = PySequence_Fast_GET_SIZE(seq); - - if (step != 1 && newlen != slicelen) - { - Py_DECREF(seq); - PyErr_Format(PyExc_ValueError, - "attempt to assign sequence of size %zd " - "to extended slice of size %zd", - newlen, slicelen - ); + raise_type_error(item); return -1; } - - /* Resize before creating the recycle bin, to prevent refleaks. */ - if (newlen > slicelen) { - if (element_resize(self, newlen - slicelen) < 0) { - Py_DECREF(seq); - return -1; - } - } - + Py_INCREF(item); + self->extra->children[index] = item; + } else { + self->extra->length--; + for (i = index; i < self->extra->length; i++) + self->extra->children[i] = self->extra->children[i+1]; + } + + Py_DECREF(old); + + return 0; +} + +static PyObject* +element_subscr(PyObject* self_, PyObject* item) +{ + ElementObject* self = (ElementObject*) self_; + + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + + if (i == -1 && PyErr_Occurred()) { + return NULL; + } + if (i < 0 && self->extra) + i += self->extra->length; + return element_getitem(self_, i); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelen, i; + size_t cur; + PyObject* list; + + if (!self->extra) + return PyList_New(0); + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return NULL; + } + slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop, + step); + + if (slicelen <= 0) + return PyList_New(0); + else { + list = PyList_New(slicelen); + if (!list) + return NULL; + + for (cur = start, i = 0; i < slicelen; + cur += step, i++) { + PyObject* item = self->extra->children[cur]; + Py_INCREF(item); + PyList_SET_ITEM(list, i, item); + } + + return list; + } + } + else { + PyErr_SetString(PyExc_TypeError, + "element indices must be integers"); + return NULL; + } +} + +static int +element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) +{ + ElementObject* self = (ElementObject*) self_; + + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + + if (i == -1 && PyErr_Occurred()) { + return -1; + } + if (i < 0 && self->extra) + i += self->extra->length; + return element_setitem(self_, i, value); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelen, newlen, i; + size_t cur; + + PyObject* recycle = NULL; + PyObject* seq; + + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return -1; + } + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return -1; + } + slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop, + step); + + if (value == NULL) { + /* Delete slice */ + size_t cur; + Py_ssize_t i; + + if (slicelen <= 0) + return 0; + + /* Since we're deleting, the direction of the range doesn't matter, + * so for simplicity make it always ascending. + */ + if (step < 0) { + stop = start + 1; + start = stop + step * (slicelen - 1) - 1; + step = -step; + } + + assert((size_t)slicelen <= SIZE_MAX / sizeof(PyObject *)); + + /* recycle is a list that will contain all the children + * scheduled for removal. + */ + if (!(recycle = PyList_New(slicelen))) { + return -1; + } + + /* This loop walks over all the children that have to be deleted, + * with cur pointing at them. num_moved is the amount of children + * until the next deleted child that have to be "shifted down" to + * occupy the deleted's places. + * Note that in the ith iteration, shifting is done i+i places down + * because i children were already removed. + */ + for (cur = start, i = 0; cur < (size_t)stop; cur += step, ++i) { + /* Compute how many children have to be moved, clipping at the + * list end. + */ + Py_ssize_t num_moved = step - 1; + if (cur + step >= (size_t)self->extra->length) { + num_moved = self->extra->length - cur - 1; + } + + PyList_SET_ITEM(recycle, i, self->extra->children[cur]); + + memmove( + self->extra->children + cur - i, + self->extra->children + cur + 1, + num_moved * sizeof(PyObject *)); + } + + /* Leftover "tail" after the last removed child */ + cur = start + (size_t)slicelen * step; + if (cur < (size_t)self->extra->length) { + memmove( + self->extra->children + cur - slicelen, + self->extra->children + cur, + (self->extra->length - cur) * sizeof(PyObject *)); + } + + self->extra->length -= slicelen; + + /* Discard the recycle list with all the deleted sub-elements */ + Py_DECREF(recycle); + return 0; + } + + /* A new slice is actually being assigned */ + seq = PySequence_Fast(value, ""); + if (!seq) { + PyErr_Format( + PyExc_TypeError, + "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name + ); + return -1; + } + newlen = PySequence_Fast_GET_SIZE(seq); + + if (step != 1 && newlen != slicelen) + { + Py_DECREF(seq); + PyErr_Format(PyExc_ValueError, + "attempt to assign sequence of size %zd " + "to extended slice of size %zd", + newlen, slicelen + ); + return -1; + } + + /* Resize before creating the recycle bin, to prevent refleaks. */ + if (newlen > slicelen) { + if (element_resize(self, newlen - slicelen) < 0) { + Py_DECREF(seq); + return -1; + } + } + for (i = 0; i < newlen; i++) { PyObject *element = PySequence_Fast_GET_ITEM(seq, i); if (!Element_Check(element)) { @@ -1909,517 +1909,517 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) } } - if (slicelen > 0) { - /* to avoid recursive calls to this method (via decref), move - old items to the recycle bin here, and get rid of them when - we're done modifying the element */ - recycle = PyList_New(slicelen); - if (!recycle) { - Py_DECREF(seq); - return -1; - } - for (cur = start, i = 0; i < slicelen; - cur += step, i++) - PyList_SET_ITEM(recycle, i, self->extra->children[cur]); - } - - if (newlen < slicelen) { - /* delete slice */ - for (i = stop; i < self->extra->length; i++) - self->extra->children[i + newlen - slicelen] = self->extra->children[i]; - } else if (newlen > slicelen) { - /* insert slice */ - for (i = self->extra->length-1; i >= stop; i--) - self->extra->children[i + newlen - slicelen] = self->extra->children[i]; - } - - /* replace the slice */ - for (cur = start, i = 0; i < newlen; - cur += step, i++) { - PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(element); - self->extra->children[cur] = element; - } - - self->extra->length += newlen - slicelen; - - Py_DECREF(seq); - - /* discard the recycle bin, and everything in it */ - Py_XDECREF(recycle); - - return 0; - } - else { - PyErr_SetString(PyExc_TypeError, - "element indices must be integers"); - return -1; - } -} - -static PyObject* -element_tag_getter(ElementObject *self, void *closure) -{ - PyObject *res = self->tag; - Py_INCREF(res); - return res; -} - -static PyObject* -element_text_getter(ElementObject *self, void *closure) -{ - PyObject *res = element_get_text(self); - Py_XINCREF(res); - return res; -} - -static PyObject* -element_tail_getter(ElementObject *self, void *closure) -{ - PyObject *res = element_get_tail(self); - Py_XINCREF(res); - return res; -} - -static PyObject* -element_attrib_getter(ElementObject *self, void *closure) -{ - PyObject *res; - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return NULL; - } - res = element_get_attrib(self); - Py_XINCREF(res); - return res; -} - -/* macro for setter validation */ -#define _VALIDATE_ATTR_VALUE(V) \ - if ((V) == NULL) { \ - PyErr_SetString( \ - PyExc_AttributeError, \ - "can't delete element attribute"); \ - return -1; \ - } - -static int -element_tag_setter(ElementObject *self, PyObject *value, void *closure) -{ - _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - Py_SETREF(self->tag, value); - return 0; -} - -static int -element_text_setter(ElementObject *self, PyObject *value, void *closure) -{ - _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - _set_joined_ptr(&self->text, value); - return 0; -} - -static int -element_tail_setter(ElementObject *self, PyObject *value, void *closure) -{ - _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - _set_joined_ptr(&self->tail, value); - return 0; -} - -static int -element_attrib_setter(ElementObject *self, PyObject *value, void *closure) -{ - _VALIDATE_ATTR_VALUE(value); + if (slicelen > 0) { + /* to avoid recursive calls to this method (via decref), move + old items to the recycle bin here, and get rid of them when + we're done modifying the element */ + recycle = PyList_New(slicelen); + if (!recycle) { + Py_DECREF(seq); + return -1; + } + for (cur = start, i = 0; i < slicelen; + cur += step, i++) + PyList_SET_ITEM(recycle, i, self->extra->children[cur]); + } + + if (newlen < slicelen) { + /* delete slice */ + for (i = stop; i < self->extra->length; i++) + self->extra->children[i + newlen - slicelen] = self->extra->children[i]; + } else if (newlen > slicelen) { + /* insert slice */ + for (i = self->extra->length-1; i >= stop; i--) + self->extra->children[i + newlen - slicelen] = self->extra->children[i]; + } + + /* replace the slice */ + for (cur = start, i = 0; i < newlen; + cur += step, i++) { + PyObject* element = PySequence_Fast_GET_ITEM(seq, i); + Py_INCREF(element); + self->extra->children[cur] = element; + } + + self->extra->length += newlen - slicelen; + + Py_DECREF(seq); + + /* discard the recycle bin, and everything in it */ + Py_XDECREF(recycle); + + return 0; + } + else { + PyErr_SetString(PyExc_TypeError, + "element indices must be integers"); + return -1; + } +} + +static PyObject* +element_tag_getter(ElementObject *self, void *closure) +{ + PyObject *res = self->tag; + Py_INCREF(res); + return res; +} + +static PyObject* +element_text_getter(ElementObject *self, void *closure) +{ + PyObject *res = element_get_text(self); + Py_XINCREF(res); + return res; +} + +static PyObject* +element_tail_getter(ElementObject *self, void *closure) +{ + PyObject *res = element_get_tail(self); + Py_XINCREF(res); + return res; +} + +static PyObject* +element_attrib_getter(ElementObject *self, void *closure) +{ + PyObject *res; + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return NULL; + } + res = element_get_attrib(self); + Py_XINCREF(res); + return res; +} + +/* macro for setter validation */ +#define _VALIDATE_ATTR_VALUE(V) \ + if ((V) == NULL) { \ + PyErr_SetString( \ + PyExc_AttributeError, \ + "can't delete element attribute"); \ + return -1; \ + } + +static int +element_tag_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + Py_SETREF(self->tag, value); + return 0; +} + +static int +element_text_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + _set_joined_ptr(&self->text, value); + return 0; +} + +static int +element_tail_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + _set_joined_ptr(&self->tail, value); + return 0; +} + +static int +element_attrib_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); if (!PyDict_Check(value)) { PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.200s", value->ob_type->tp_name); return -1; } - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return -1; - } - Py_INCREF(value); + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return -1; + } + Py_INCREF(value); Py_XSETREF(self->extra->attrib, value); - return 0; -} - -static PySequenceMethods element_as_sequence = { - (lenfunc) element_length, - 0, /* sq_concat */ - 0, /* sq_repeat */ - element_getitem, - 0, - element_setitem, - 0, -}; - -/******************************* Element iterator ****************************/ - -/* ElementIterObject represents the iteration state over an XML element in - * pre-order traversal. To keep track of which sub-element should be returned - * next, a stack of parents is maintained. This is a standard stack-based - * iterative pre-order traversal of a tree. - * The stack is managed using a continuous array. - * Each stack item contains the saved parent to which we should return after - * the current one is exhausted, and the next child to examine in that parent. - */ -typedef struct ParentLocator_t { - ElementObject *parent; - Py_ssize_t child_index; -} ParentLocator; - -typedef struct { - PyObject_HEAD - ParentLocator *parent_stack; - Py_ssize_t parent_stack_used; - Py_ssize_t parent_stack_size; - ElementObject *root_element; - PyObject *sought_tag; - int gettext; -} ElementIterObject; - - -static void -elementiter_dealloc(ElementIterObject *it) -{ - Py_ssize_t i = it->parent_stack_used; - it->parent_stack_used = 0; - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(it); - while (i--) - Py_XDECREF(it->parent_stack[i].parent); - PyMem_Free(it->parent_stack); - - Py_XDECREF(it->sought_tag); - Py_XDECREF(it->root_element); - - PyObject_GC_Del(it); -} - -static int -elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg) -{ - Py_ssize_t i = it->parent_stack_used; - while (i--) - Py_VISIT(it->parent_stack[i].parent); - - Py_VISIT(it->root_element); - Py_VISIT(it->sought_tag); - return 0; -} - -/* Helper function for elementiter_next. Add a new parent to the parent stack. - */ -static int -parent_stack_push_new(ElementIterObject *it, ElementObject *parent) -{ - ParentLocator *item; - - if (it->parent_stack_used >= it->parent_stack_size) { - Py_ssize_t new_size = it->parent_stack_size * 2; /* never overflow */ - ParentLocator *parent_stack = it->parent_stack; - PyMem_Resize(parent_stack, ParentLocator, new_size); - if (parent_stack == NULL) - return -1; - it->parent_stack = parent_stack; - it->parent_stack_size = new_size; - } - item = it->parent_stack + it->parent_stack_used++; - Py_INCREF(parent); - item->parent = parent; - item->child_index = 0; - return 0; -} - -static PyObject * -elementiter_next(ElementIterObject *it) -{ - /* Sub-element iterator. - * - * A short note on gettext: this function serves both the iter() and - * itertext() methods to avoid code duplication. However, there are a few - * small differences in the way these iterations work. Namely: - * - itertext() only yields text from nodes that have it, and continues - * iterating when a node doesn't have text (so it doesn't return any - * node like iter()) - * - itertext() also has to handle tail, after finishing with all the - * children of a node. - */ - int rc; - ElementObject *elem; - PyObject *text; - - while (1) { - /* Handle the case reached in the beginning and end of iteration, where - * the parent stack is empty. If root_element is NULL and we're here, the - * iterator is exhausted. - */ - if (!it->parent_stack_used) { - if (!it->root_element) { - PyErr_SetNone(PyExc_StopIteration); - return NULL; - } - - elem = it->root_element; /* steals a reference */ - it->root_element = NULL; - } - else { - /* See if there are children left to traverse in the current parent. If - * yes, visit the next child. If not, pop the stack and try again. - */ - ParentLocator *item = &it->parent_stack[it->parent_stack_used - 1]; - Py_ssize_t child_index = item->child_index; - ElementObjectExtra *extra; - elem = item->parent; - extra = elem->extra; - if (!extra || child_index >= extra->length) { - it->parent_stack_used--; - /* Note that extra condition on it->parent_stack_used here; - * this is because itertext() is supposed to only return *inner* - * text, not text following the element it began iteration with. - */ - if (it->gettext && it->parent_stack_used) { - text = element_get_tail(elem); - goto gettext; - } - Py_DECREF(elem); - continue; - } - + return 0; +} + +static PySequenceMethods element_as_sequence = { + (lenfunc) element_length, + 0, /* sq_concat */ + 0, /* sq_repeat */ + element_getitem, + 0, + element_setitem, + 0, +}; + +/******************************* Element iterator ****************************/ + +/* ElementIterObject represents the iteration state over an XML element in + * pre-order traversal. To keep track of which sub-element should be returned + * next, a stack of parents is maintained. This is a standard stack-based + * iterative pre-order traversal of a tree. + * The stack is managed using a continuous array. + * Each stack item contains the saved parent to which we should return after + * the current one is exhausted, and the next child to examine in that parent. + */ +typedef struct ParentLocator_t { + ElementObject *parent; + Py_ssize_t child_index; +} ParentLocator; + +typedef struct { + PyObject_HEAD + ParentLocator *parent_stack; + Py_ssize_t parent_stack_used; + Py_ssize_t parent_stack_size; + ElementObject *root_element; + PyObject *sought_tag; + int gettext; +} ElementIterObject; + + +static void +elementiter_dealloc(ElementIterObject *it) +{ + Py_ssize_t i = it->parent_stack_used; + it->parent_stack_used = 0; + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(it); + while (i--) + Py_XDECREF(it->parent_stack[i].parent); + PyMem_Free(it->parent_stack); + + Py_XDECREF(it->sought_tag); + Py_XDECREF(it->root_element); + + PyObject_GC_Del(it); +} + +static int +elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg) +{ + Py_ssize_t i = it->parent_stack_used; + while (i--) + Py_VISIT(it->parent_stack[i].parent); + + Py_VISIT(it->root_element); + Py_VISIT(it->sought_tag); + return 0; +} + +/* Helper function for elementiter_next. Add a new parent to the parent stack. + */ +static int +parent_stack_push_new(ElementIterObject *it, ElementObject *parent) +{ + ParentLocator *item; + + if (it->parent_stack_used >= it->parent_stack_size) { + Py_ssize_t new_size = it->parent_stack_size * 2; /* never overflow */ + ParentLocator *parent_stack = it->parent_stack; + PyMem_Resize(parent_stack, ParentLocator, new_size); + if (parent_stack == NULL) + return -1; + it->parent_stack = parent_stack; + it->parent_stack_size = new_size; + } + item = it->parent_stack + it->parent_stack_used++; + Py_INCREF(parent); + item->parent = parent; + item->child_index = 0; + return 0; +} + +static PyObject * +elementiter_next(ElementIterObject *it) +{ + /* Sub-element iterator. + * + * A short note on gettext: this function serves both the iter() and + * itertext() methods to avoid code duplication. However, there are a few + * small differences in the way these iterations work. Namely: + * - itertext() only yields text from nodes that have it, and continues + * iterating when a node doesn't have text (so it doesn't return any + * node like iter()) + * - itertext() also has to handle tail, after finishing with all the + * children of a node. + */ + int rc; + ElementObject *elem; + PyObject *text; + + while (1) { + /* Handle the case reached in the beginning and end of iteration, where + * the parent stack is empty. If root_element is NULL and we're here, the + * iterator is exhausted. + */ + if (!it->parent_stack_used) { + if (!it->root_element) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + + elem = it->root_element; /* steals a reference */ + it->root_element = NULL; + } + else { + /* See if there are children left to traverse in the current parent. If + * yes, visit the next child. If not, pop the stack and try again. + */ + ParentLocator *item = &it->parent_stack[it->parent_stack_used - 1]; + Py_ssize_t child_index = item->child_index; + ElementObjectExtra *extra; + elem = item->parent; + extra = elem->extra; + if (!extra || child_index >= extra->length) { + it->parent_stack_used--; + /* Note that extra condition on it->parent_stack_used here; + * this is because itertext() is supposed to only return *inner* + * text, not text following the element it began iteration with. + */ + if (it->gettext && it->parent_stack_used) { + text = element_get_tail(elem); + goto gettext; + } + Py_DECREF(elem); + continue; + } + assert(Element_Check(extra->children[child_index])); - elem = (ElementObject *)extra->children[child_index]; - item->child_index++; - Py_INCREF(elem); - } - - if (parent_stack_push_new(it, elem) < 0) { - Py_DECREF(elem); - PyErr_NoMemory(); - return NULL; - } - if (it->gettext) { - text = element_get_text(elem); - goto gettext; - } - - if (it->sought_tag == Py_None) - return (PyObject *)elem; - - rc = PyObject_RichCompareBool(elem->tag, it->sought_tag, Py_EQ); - if (rc > 0) - return (PyObject *)elem; - - Py_DECREF(elem); - if (rc < 0) - return NULL; - continue; - -gettext: - if (!text) { - Py_DECREF(elem); - return NULL; - } - if (text == Py_None) { - Py_DECREF(elem); - } - else { - Py_INCREF(text); - Py_DECREF(elem); - rc = PyObject_IsTrue(text); - if (rc > 0) - return text; - Py_DECREF(text); - if (rc < 0) - return NULL; - } - } - - return NULL; -} - - -static PyTypeObject ElementIter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - /* Using the module's name since the pure-Python implementation does not - have such a type. */ - "_elementtree._element_iterator", /* tp_name */ - sizeof(ElementIterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)elementiter_dealloc, /* tp_dealloc */ + elem = (ElementObject *)extra->children[child_index]; + item->child_index++; + Py_INCREF(elem); + } + + if (parent_stack_push_new(it, elem) < 0) { + Py_DECREF(elem); + PyErr_NoMemory(); + return NULL; + } + if (it->gettext) { + text = element_get_text(elem); + goto gettext; + } + + if (it->sought_tag == Py_None) + return (PyObject *)elem; + + rc = PyObject_RichCompareBool(elem->tag, it->sought_tag, Py_EQ); + if (rc > 0) + return (PyObject *)elem; + + Py_DECREF(elem); + if (rc < 0) + return NULL; + continue; + +gettext: + if (!text) { + Py_DECREF(elem); + return NULL; + } + if (text == Py_None) { + Py_DECREF(elem); + } + else { + Py_INCREF(text); + Py_DECREF(elem); + rc = PyObject_IsTrue(text); + if (rc > 0) + return text; + Py_DECREF(text); + if (rc < 0) + return NULL; + } + } + + return NULL; +} + + +static PyTypeObject ElementIter_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + /* Using the module's name since the pure-Python implementation does not + have such a type. */ + "_elementtree._element_iterator", /* tp_name */ + sizeof(ElementIterObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)elementiter_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)elementiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)elementiter_next, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - -#define INIT_PARENT_STACK_SIZE 8 - -static PyObject * -create_elementiter(ElementObject *self, PyObject *tag, int gettext) -{ - ElementIterObject *it; - - it = PyObject_GC_New(ElementIterObject, &ElementIter_Type); - if (!it) - return NULL; - - Py_INCREF(tag); - it->sought_tag = tag; - it->gettext = gettext; - Py_INCREF(self); - it->root_element = self; - - it->parent_stack = PyMem_New(ParentLocator, INIT_PARENT_STACK_SIZE); - if (it->parent_stack == NULL) { - Py_DECREF(it); - PyErr_NoMemory(); - return NULL; - } - it->parent_stack_used = 0; - it->parent_stack_size = INIT_PARENT_STACK_SIZE; - + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)elementiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)elementiter_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +#define INIT_PARENT_STACK_SIZE 8 + +static PyObject * +create_elementiter(ElementObject *self, PyObject *tag, int gettext) +{ + ElementIterObject *it; + + it = PyObject_GC_New(ElementIterObject, &ElementIter_Type); + if (!it) + return NULL; + + Py_INCREF(tag); + it->sought_tag = tag; + it->gettext = gettext; + Py_INCREF(self); + it->root_element = self; + + it->parent_stack = PyMem_New(ParentLocator, INIT_PARENT_STACK_SIZE); + if (it->parent_stack == NULL) { + Py_DECREF(it); + PyErr_NoMemory(); + return NULL; + } + it->parent_stack_used = 0; + it->parent_stack_size = INIT_PARENT_STACK_SIZE; + PyObject_GC_Track(it); - return (PyObject *)it; -} - - -/* ==================================================================== */ -/* the tree builder type */ - -typedef struct { - PyObject_HEAD - - PyObject *root; /* root node (first created node) */ - - PyObject *this; /* current node */ - PyObject *last; /* most recently created node */ + return (PyObject *)it; +} + + +/* ==================================================================== */ +/* the tree builder type */ + +typedef struct { + PyObject_HEAD + + PyObject *root; /* root node (first created node) */ + + PyObject *this; /* current node */ + PyObject *last; /* most recently created node */ PyObject *last_for_tail; /* most recently created node that takes a tail */ - - PyObject *data; /* data collector (string or list), or NULL */ - - PyObject *stack; /* element stack */ - Py_ssize_t index; /* current stack size (0 means empty) */ - - PyObject *element_factory; + + PyObject *data; /* data collector (string or list), or NULL */ + + PyObject *stack; /* element stack */ + Py_ssize_t index; /* current stack size (0 means empty) */ + + PyObject *element_factory; PyObject *comment_factory; PyObject *pi_factory; - - /* element tracing */ - PyObject *events_append; /* the append method of the list of events, or NULL */ - PyObject *start_event_obj; /* event objects (NULL to ignore) */ - PyObject *end_event_obj; - PyObject *start_ns_event_obj; - PyObject *end_ns_event_obj; + + /* element tracing */ + PyObject *events_append; /* the append method of the list of events, or NULL */ + PyObject *start_event_obj; /* event objects (NULL to ignore) */ + PyObject *end_event_obj; + PyObject *start_ns_event_obj; + PyObject *end_ns_event_obj; PyObject *comment_event_obj; PyObject *pi_event_obj; char insert_comments; char insert_pis; -} TreeBuilderObject; - +} TreeBuilderObject; + #define TreeBuilder_CheckExact(op) Py_IS_TYPE((op), &TreeBuilder_Type) - -/* -------------------------------------------------------------------- */ -/* constructor and destructor */ - -static PyObject * -treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - TreeBuilderObject *t = (TreeBuilderObject *)type->tp_alloc(type, 0); - if (t != NULL) { - t->root = NULL; - - Py_INCREF(Py_None); - t->this = Py_None; - Py_INCREF(Py_None); - t->last = Py_None; - - t->data = NULL; - t->element_factory = NULL; + +/* -------------------------------------------------------------------- */ +/* constructor and destructor */ + +static PyObject * +treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + TreeBuilderObject *t = (TreeBuilderObject *)type->tp_alloc(type, 0); + if (t != NULL) { + t->root = NULL; + + Py_INCREF(Py_None); + t->this = Py_None; + Py_INCREF(Py_None); + t->last = Py_None; + + t->data = NULL; + t->element_factory = NULL; t->comment_factory = NULL; t->pi_factory = NULL; - t->stack = PyList_New(20); - if (!t->stack) { - Py_DECREF(t->this); - Py_DECREF(t->last); - Py_DECREF((PyObject *) t); - return NULL; - } - t->index = 0; - - t->events_append = NULL; - t->start_event_obj = t->end_event_obj = NULL; - t->start_ns_event_obj = t->end_ns_event_obj = NULL; + t->stack = PyList_New(20); + if (!t->stack) { + Py_DECREF(t->this); + Py_DECREF(t->last); + Py_DECREF((PyObject *) t); + return NULL; + } + t->index = 0; + + t->events_append = NULL; + t->start_event_obj = t->end_event_obj = NULL; + t->start_ns_event_obj = t->end_ns_event_obj = NULL; t->comment_event_obj = t->pi_event_obj = NULL; t->insert_comments = t->insert_pis = 0; - } - return (PyObject *)t; -} - -/*[clinic input] -_elementtree.TreeBuilder.__init__ - + } + return (PyObject *)t; +} + +/*[clinic input] +_elementtree.TreeBuilder.__init__ + element_factory: object = None * comment_factory: object = None pi_factory: object = None insert_comments: bool = False insert_pis: bool = False - -[clinic start generated code]*/ - -static int -_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, + +[clinic start generated code]*/ + +static int +_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, PyObject *element_factory, PyObject *comment_factory, PyObject *pi_factory, int insert_comments, int insert_pis) /*[clinic end generated code: output=8571d4dcadfdf952 input=ae98a94df20b5cc3]*/ -{ +{ if (element_factory != Py_None) { - Py_INCREF(element_factory); - Py_XSETREF(self->element_factory, element_factory); + Py_INCREF(element_factory); + Py_XSETREF(self->element_factory, element_factory); } else { Py_CLEAR(self->element_factory); - } - + } + if (comment_factory == Py_None) { elementtreestate *st = ET_STATE_GLOBAL; comment_factory = st->comment_factory; @@ -2446,64 +2446,64 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, self->insert_pis = 0; } - return 0; -} - -static int -treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) -{ + return 0; +} + +static int +treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) +{ Py_VISIT(self->pi_event_obj); Py_VISIT(self->comment_event_obj); - Py_VISIT(self->end_ns_event_obj); - Py_VISIT(self->start_ns_event_obj); - Py_VISIT(self->end_event_obj); - Py_VISIT(self->start_event_obj); - Py_VISIT(self->events_append); - Py_VISIT(self->root); - Py_VISIT(self->this); - Py_VISIT(self->last); + Py_VISIT(self->end_ns_event_obj); + Py_VISIT(self->start_ns_event_obj); + Py_VISIT(self->end_event_obj); + Py_VISIT(self->start_event_obj); + Py_VISIT(self->events_append); + Py_VISIT(self->root); + Py_VISIT(self->this); + Py_VISIT(self->last); Py_VISIT(self->last_for_tail); - Py_VISIT(self->data); - Py_VISIT(self->stack); + Py_VISIT(self->data); + Py_VISIT(self->stack); Py_VISIT(self->pi_factory); Py_VISIT(self->comment_factory); - Py_VISIT(self->element_factory); - return 0; -} - -static int -treebuilder_gc_clear(TreeBuilderObject *self) -{ + Py_VISIT(self->element_factory); + return 0; +} + +static int +treebuilder_gc_clear(TreeBuilderObject *self) +{ Py_CLEAR(self->pi_event_obj); Py_CLEAR(self->comment_event_obj); - Py_CLEAR(self->end_ns_event_obj); - Py_CLEAR(self->start_ns_event_obj); - Py_CLEAR(self->end_event_obj); - Py_CLEAR(self->start_event_obj); - Py_CLEAR(self->events_append); - Py_CLEAR(self->stack); - Py_CLEAR(self->data); - Py_CLEAR(self->last); + Py_CLEAR(self->end_ns_event_obj); + Py_CLEAR(self->start_ns_event_obj); + Py_CLEAR(self->end_event_obj); + Py_CLEAR(self->start_event_obj); + Py_CLEAR(self->events_append); + Py_CLEAR(self->stack); + Py_CLEAR(self->data); + Py_CLEAR(self->last); Py_CLEAR(self->last_for_tail); - Py_CLEAR(self->this); + Py_CLEAR(self->this); Py_CLEAR(self->pi_factory); Py_CLEAR(self->comment_factory); - Py_CLEAR(self->element_factory); - Py_CLEAR(self->root); - return 0; -} - -static void -treebuilder_dealloc(TreeBuilderObject *self) -{ - PyObject_GC_UnTrack(self); - treebuilder_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -/* -------------------------------------------------------------------- */ -/* helpers for handling of arbitrary element-like objects */ - + Py_CLEAR(self->element_factory); + Py_CLEAR(self->root); + return 0; +} + +static void +treebuilder_dealloc(TreeBuilderObject *self) +{ + PyObject_GC_UnTrack(self); + treebuilder_gc_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +/* -------------------------------------------------------------------- */ +/* helpers for handling of arbitrary element-like objects */ + /*[clinic input] _elementtree._set_factories @@ -2555,12 +2555,12 @@ _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, return old; } -static int +static int treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, PyObject **dest, _Py_Identifier *name) -{ +{ /* Fast paths for the "almost always" cases. */ - if (Element_CheckExact(element)) { + if (Element_CheckExact(element)) { PyObject *dest_obj = JOIN_OBJ(*dest); if (dest_obj == Py_None) { *dest = JOIN_SET(*data, PyList_CheckExact(*data)); @@ -2575,15 +2575,15 @@ treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, Py_CLEAR(*data); return 0; } - } + } /* Fallback for the non-Element / non-trivial cases. */ { - int r; + int r; PyObject* joined; PyObject* previous = _PyObject_GetAttrId(element, name); if (!previous) - return -1; + return -1; joined = list_join(*data); if (!joined) { Py_DECREF(previous); @@ -2600,220 +2600,220 @@ treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, Py_DECREF(previous); } - r = _PyObject_SetAttrId(element, name, joined); - Py_DECREF(joined); - if (r < 0) - return -1; - Py_CLEAR(*data); - return 0; - } -} - -LOCAL(int) -treebuilder_flush_data(TreeBuilderObject* self) -{ - if (!self->data) { - return 0; - } - - if (!self->last_for_tail) { - PyObject *element = self->last; - _Py_IDENTIFIER(text); - return treebuilder_extend_element_text_or_tail( - element, &self->data, - &((ElementObject *) element)->text, &PyId_text); - } - else { - PyObject *element = self->last_for_tail; - _Py_IDENTIFIER(tail); - return treebuilder_extend_element_text_or_tail( - element, &self->data, - &((ElementObject *) element)->tail, &PyId_tail); - } -} - -static int -treebuilder_add_subelement(PyObject *element, PyObject *child) -{ - _Py_IDENTIFIER(append); - if (Element_CheckExact(element)) { - ElementObject *elem = (ElementObject *) element; - return element_add_subelement(elem, child); - } - else { - PyObject *res; - res = _PyObject_CallMethodIdOneArg(element, &PyId_append, child); - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; - } -} - -LOCAL(int) -treebuilder_append_event(TreeBuilderObject *self, PyObject *action, - PyObject *node) -{ - if (action != NULL) { - PyObject *res; - PyObject *event = PyTuple_Pack(2, action, node); - if (event == NULL) - return -1; - res = PyObject_CallOneArg(self->events_append, event); - Py_DECREF(event); - if (res == NULL) - return -1; - Py_DECREF(res); - } - return 0; -} - -/* -------------------------------------------------------------------- */ -/* handlers */ - -LOCAL(PyObject*) -treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, - PyObject* attrib) -{ - PyObject* node; - PyObject* this; - elementtreestate *st = ET_STATE_GLOBAL; - - if (treebuilder_flush_data(self) < 0) { - return NULL; - } - - if (!self->element_factory) { - node = create_new_element(tag, attrib); - } else if (attrib == NULL) { - attrib = PyDict_New(); - if (!attrib) - return NULL; - node = PyObject_CallFunctionObjArgs(self->element_factory, - tag, attrib, NULL); - Py_DECREF(attrib); - } - else { - node = PyObject_CallFunctionObjArgs(self->element_factory, - tag, attrib, NULL); - } - if (!node) { - return NULL; - } - - this = self->this; - Py_CLEAR(self->last_for_tail); - - if (this != Py_None) { - if (treebuilder_add_subelement(this, node) < 0) - goto error; - } else { - if (self->root) { - PyErr_SetString( - st->parseerror_obj, - "multiple elements on top level" - ); - goto error; - } - Py_INCREF(node); - self->root = node; - } - - if (self->index < PyList_GET_SIZE(self->stack)) { - if (PyList_SetItem(self->stack, self->index, this) < 0) - goto error; - Py_INCREF(this); - } else { - if (PyList_Append(self->stack, this) < 0) - goto error; - } - self->index++; - - Py_INCREF(node); - Py_SETREF(self->this, node); - Py_INCREF(node); - Py_SETREF(self->last, node); - - if (treebuilder_append_event(self, self->start_event_obj, node) < 0) - goto error; - - return node; - - error: - Py_DECREF(node); - return NULL; -} - -LOCAL(PyObject*) -treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) -{ - if (!self->data) { - if (self->last == Py_None) { - /* ignore calls to data before the first call to start */ - Py_RETURN_NONE; - } - /* store the first item as is */ - Py_INCREF(data); self->data = data; - } else { - /* more than one item; use a list to collect items */ - if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 && - PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) { - /* XXX this code path unused in Python 3? */ - /* expat often generates single character data sections; handle - the most common case by resizing the existing string... */ - Py_ssize_t size = PyBytes_GET_SIZE(self->data); - if (_PyBytes_Resize(&self->data, size + 1) < 0) - return NULL; - PyBytes_AS_STRING(self->data)[size] = PyBytes_AS_STRING(data)[0]; - } else if (PyList_CheckExact(self->data)) { - if (PyList_Append(self->data, data) < 0) - return NULL; - } else { - PyObject* list = PyList_New(2); - if (!list) - return NULL; - PyList_SET_ITEM(list, 0, self->data); - Py_INCREF(data); PyList_SET_ITEM(list, 1, data); - self->data = list; - } - } - - Py_RETURN_NONE; -} - -LOCAL(PyObject*) -treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) -{ - PyObject* item; - - if (treebuilder_flush_data(self) < 0) { - return NULL; - } - - if (self->index == 0) { - PyErr_SetString( - PyExc_IndexError, - "pop from empty stack" - ); - return NULL; - } - - item = self->last; - self->last = self->this; + r = _PyObject_SetAttrId(element, name, joined); + Py_DECREF(joined); + if (r < 0) + return -1; + Py_CLEAR(*data); + return 0; + } +} + +LOCAL(int) +treebuilder_flush_data(TreeBuilderObject* self) +{ + if (!self->data) { + return 0; + } + + if (!self->last_for_tail) { + PyObject *element = self->last; + _Py_IDENTIFIER(text); + return treebuilder_extend_element_text_or_tail( + element, &self->data, + &((ElementObject *) element)->text, &PyId_text); + } + else { + PyObject *element = self->last_for_tail; + _Py_IDENTIFIER(tail); + return treebuilder_extend_element_text_or_tail( + element, &self->data, + &((ElementObject *) element)->tail, &PyId_tail); + } +} + +static int +treebuilder_add_subelement(PyObject *element, PyObject *child) +{ + _Py_IDENTIFIER(append); + if (Element_CheckExact(element)) { + ElementObject *elem = (ElementObject *) element; + return element_add_subelement(elem, child); + } + else { + PyObject *res; + res = _PyObject_CallMethodIdOneArg(element, &PyId_append, child); + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; + } +} + +LOCAL(int) +treebuilder_append_event(TreeBuilderObject *self, PyObject *action, + PyObject *node) +{ + if (action != NULL) { + PyObject *res; + PyObject *event = PyTuple_Pack(2, action, node); + if (event == NULL) + return -1; + res = PyObject_CallOneArg(self->events_append, event); + Py_DECREF(event); + if (res == NULL) + return -1; + Py_DECREF(res); + } + return 0; +} + +/* -------------------------------------------------------------------- */ +/* handlers */ + +LOCAL(PyObject*) +treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, + PyObject* attrib) +{ + PyObject* node; + PyObject* this; + elementtreestate *st = ET_STATE_GLOBAL; + + if (treebuilder_flush_data(self) < 0) { + return NULL; + } + + if (!self->element_factory) { + node = create_new_element(tag, attrib); + } else if (attrib == NULL) { + attrib = PyDict_New(); + if (!attrib) + return NULL; + node = PyObject_CallFunctionObjArgs(self->element_factory, + tag, attrib, NULL); + Py_DECREF(attrib); + } + else { + node = PyObject_CallFunctionObjArgs(self->element_factory, + tag, attrib, NULL); + } + if (!node) { + return NULL; + } + + this = self->this; + Py_CLEAR(self->last_for_tail); + + if (this != Py_None) { + if (treebuilder_add_subelement(this, node) < 0) + goto error; + } else { + if (self->root) { + PyErr_SetString( + st->parseerror_obj, + "multiple elements on top level" + ); + goto error; + } + Py_INCREF(node); + self->root = node; + } + + if (self->index < PyList_GET_SIZE(self->stack)) { + if (PyList_SetItem(self->stack, self->index, this) < 0) + goto error; + Py_INCREF(this); + } else { + if (PyList_Append(self->stack, this) < 0) + goto error; + } + self->index++; + + Py_INCREF(node); + Py_SETREF(self->this, node); + Py_INCREF(node); + Py_SETREF(self->last, node); + + if (treebuilder_append_event(self, self->start_event_obj, node) < 0) + goto error; + + return node; + + error: + Py_DECREF(node); + return NULL; +} + +LOCAL(PyObject*) +treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) +{ + if (!self->data) { + if (self->last == Py_None) { + /* ignore calls to data before the first call to start */ + Py_RETURN_NONE; + } + /* store the first item as is */ + Py_INCREF(data); self->data = data; + } else { + /* more than one item; use a list to collect items */ + if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 && + PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) { + /* XXX this code path unused in Python 3? */ + /* expat often generates single character data sections; handle + the most common case by resizing the existing string... */ + Py_ssize_t size = PyBytes_GET_SIZE(self->data); + if (_PyBytes_Resize(&self->data, size + 1) < 0) + return NULL; + PyBytes_AS_STRING(self->data)[size] = PyBytes_AS_STRING(data)[0]; + } else if (PyList_CheckExact(self->data)) { + if (PyList_Append(self->data, data) < 0) + return NULL; + } else { + PyObject* list = PyList_New(2); + if (!list) + return NULL; + PyList_SET_ITEM(list, 0, self->data); + Py_INCREF(data); PyList_SET_ITEM(list, 1, data); + self->data = list; + } + } + + Py_RETURN_NONE; +} + +LOCAL(PyObject*) +treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) +{ + PyObject* item; + + if (treebuilder_flush_data(self) < 0) { + return NULL; + } + + if (self->index == 0) { + PyErr_SetString( + PyExc_IndexError, + "pop from empty stack" + ); + return NULL; + } + + item = self->last; + self->last = self->this; Py_INCREF(self->last); Py_XSETREF(self->last_for_tail, self->last); - self->index--; - self->this = PyList_GET_ITEM(self->stack, self->index); - Py_INCREF(self->this); - Py_DECREF(item); - - if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0) - return NULL; - - Py_INCREF(self->last); - return (PyObject*) self->last; -} - + self->index--; + self->this = PyList_GET_ITEM(self->stack, self->index); + Py_INCREF(self->this); + Py_DECREF(item); + + if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0) + return NULL; + + Py_INCREF(self->last); + return (PyObject*) self->last; +} + LOCAL(PyObject*) treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) { @@ -2929,39 +2929,39 @@ treebuilder_handle_end_ns(TreeBuilderObject* self, PyObject* prefix) Py_RETURN_NONE; } -/* -------------------------------------------------------------------- */ -/* methods (in alphabetical order) */ - -/*[clinic input] -_elementtree.TreeBuilder.data - - data: object - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_TreeBuilder_data(TreeBuilderObject *self, PyObject *data) -/*[clinic end generated code: output=69144c7100795bb2 input=a0540c532b284d29]*/ -{ - return treebuilder_handle_data(self, data); -} - -/*[clinic input] -_elementtree.TreeBuilder.end - - tag: object - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_TreeBuilder_end(TreeBuilderObject *self, PyObject *tag) -/*[clinic end generated code: output=9a98727cc691cd9d input=22dc3674236f5745]*/ -{ - return treebuilder_handle_end(self, tag); -} - +/* -------------------------------------------------------------------- */ +/* methods (in alphabetical order) */ + +/*[clinic input] +_elementtree.TreeBuilder.data + + data: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_data(TreeBuilderObject *self, PyObject *data) +/*[clinic end generated code: output=69144c7100795bb2 input=a0540c532b284d29]*/ +{ + return treebuilder_handle_data(self, data); +} + +/*[clinic input] +_elementtree.TreeBuilder.end + + tag: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_end(TreeBuilderObject *self, PyObject *tag) +/*[clinic end generated code: output=9a98727cc691cd9d input=22dc3674236f5745]*/ +{ + return treebuilder_handle_end(self, tag); +} + /*[clinic input] _elementtree.TreeBuilder.comment @@ -2994,407 +2994,407 @@ _elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target, return treebuilder_handle_pi(self, target, text); } -LOCAL(PyObject*) -treebuilder_done(TreeBuilderObject* self) -{ - PyObject* res; - - /* FIXME: check stack size? */ - - if (self->root) - res = self->root; - else - res = Py_None; - - Py_INCREF(res); - return res; -} - -/*[clinic input] -_elementtree.TreeBuilder.close - -[clinic start generated code]*/ - -static PyObject * -_elementtree_TreeBuilder_close_impl(TreeBuilderObject *self) -/*[clinic end generated code: output=b441fee3202f61ee input=f7c9c65dc718de14]*/ -{ - return treebuilder_done(self); -} - -/*[clinic input] -_elementtree.TreeBuilder.start - - tag: object +LOCAL(PyObject*) +treebuilder_done(TreeBuilderObject* self) +{ + PyObject* res; + + /* FIXME: check stack size? */ + + if (self->root) + res = self->root; + else + res = Py_None; + + Py_INCREF(res); + return res; +} + +/*[clinic input] +_elementtree.TreeBuilder.close + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_close_impl(TreeBuilderObject *self) +/*[clinic end generated code: output=b441fee3202f61ee input=f7c9c65dc718de14]*/ +{ + return treebuilder_done(self); +} + +/*[clinic input] +_elementtree.TreeBuilder.start + + tag: object attrs: object(subclass_of='&PyDict_Type') - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, - PyObject *attrs) + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, + PyObject *attrs) /*[clinic end generated code: output=e7e9dc2861349411 input=7288e9e38e63b2b6]*/ -{ - return treebuilder_handle_start(self, tag, attrs); -} - -/* ==================================================================== */ -/* the expat interface */ - -#include "expat.h" -#include "pyexpat.h" - -/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be - * cached globally without being in per-module state. - */ -static struct PyExpat_CAPI *expat_capi; -#define EXPAT(func) (expat_capi->func) - -static XML_Memory_Handling_Suite ExpatMemoryHandler = { - PyObject_Malloc, PyObject_Realloc, PyObject_Free}; - -typedef struct { - PyObject_HEAD - - XML_Parser parser; - - PyObject *target; - PyObject *entity; - - PyObject *names; - +{ + return treebuilder_handle_start(self, tag, attrs); +} + +/* ==================================================================== */ +/* the expat interface */ + +#include "expat.h" +#include "pyexpat.h" + +/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be + * cached globally without being in per-module state. + */ +static struct PyExpat_CAPI *expat_capi; +#define EXPAT(func) (expat_capi->func) + +static XML_Memory_Handling_Suite ExpatMemoryHandler = { + PyObject_Malloc, PyObject_Realloc, PyObject_Free}; + +typedef struct { + PyObject_HEAD + + XML_Parser parser; + + PyObject *target; + PyObject *entity; + + PyObject *names; + PyObject *handle_start_ns; PyObject *handle_end_ns; - PyObject *handle_start; - PyObject *handle_data; - PyObject *handle_end; - - PyObject *handle_comment; - PyObject *handle_pi; - PyObject *handle_doctype; - - PyObject *handle_close; - -} XMLParserObject; - -/* helpers */ - -LOCAL(PyObject*) -makeuniversal(XMLParserObject* self, const char* string) -{ - /* convert a UTF-8 tag/attribute name from the expat parser - to a universal name string */ - - Py_ssize_t size = (Py_ssize_t) strlen(string); - PyObject* key; - PyObject* value; - - /* look the 'raw' name up in the names dictionary */ - key = PyBytes_FromStringAndSize(string, size); - if (!key) - return NULL; - + PyObject *handle_start; + PyObject *handle_data; + PyObject *handle_end; + + PyObject *handle_comment; + PyObject *handle_pi; + PyObject *handle_doctype; + + PyObject *handle_close; + +} XMLParserObject; + +/* helpers */ + +LOCAL(PyObject*) +makeuniversal(XMLParserObject* self, const char* string) +{ + /* convert a UTF-8 tag/attribute name from the expat parser + to a universal name string */ + + Py_ssize_t size = (Py_ssize_t) strlen(string); + PyObject* key; + PyObject* value; + + /* look the 'raw' name up in the names dictionary */ + key = PyBytes_FromStringAndSize(string, size); + if (!key) + return NULL; + value = PyDict_GetItemWithError(self->names, key); - - if (value) { - Py_INCREF(value); + + if (value) { + Py_INCREF(value); } else if (!PyErr_Occurred()) { - /* new name. convert to universal name, and decode as - necessary */ - - PyObject* tag; - char* p; - Py_ssize_t i; - - /* look for namespace separator */ - for (i = 0; i < size; i++) - if (string[i] == '}') - break; - if (i != size) { - /* convert to universal name */ - tag = PyBytes_FromStringAndSize(NULL, size+1); - if (tag == NULL) { - Py_DECREF(key); - return NULL; - } - p = PyBytes_AS_STRING(tag); - p[0] = '{'; - memcpy(p+1, string, size); - size++; - } else { - /* plain name; use key as tag */ - Py_INCREF(key); - tag = key; - } - - /* decode universal name */ - p = PyBytes_AS_STRING(tag); - value = PyUnicode_DecodeUTF8(p, size, "strict"); - Py_DECREF(tag); - if (!value) { - Py_DECREF(key); - return NULL; - } - - /* add to names dictionary */ - if (PyDict_SetItem(self->names, key, value) < 0) { - Py_DECREF(key); - Py_DECREF(value); - return NULL; - } - } - - Py_DECREF(key); - return value; -} - -/* Set the ParseError exception with the given parameters. - * If message is not NULL, it's used as the error string. Otherwise, the - * message string is the default for the given error_code. -*/ -static void -expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, - const char *message) -{ - PyObject *errmsg, *error, *position, *code; - elementtreestate *st = ET_STATE_GLOBAL; - - errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd", - message ? message : EXPAT(ErrorString)(error_code), - line, column); - if (errmsg == NULL) - return; - + /* new name. convert to universal name, and decode as + necessary */ + + PyObject* tag; + char* p; + Py_ssize_t i; + + /* look for namespace separator */ + for (i = 0; i < size; i++) + if (string[i] == '}') + break; + if (i != size) { + /* convert to universal name */ + tag = PyBytes_FromStringAndSize(NULL, size+1); + if (tag == NULL) { + Py_DECREF(key); + return NULL; + } + p = PyBytes_AS_STRING(tag); + p[0] = '{'; + memcpy(p+1, string, size); + size++; + } else { + /* plain name; use key as tag */ + Py_INCREF(key); + tag = key; + } + + /* decode universal name */ + p = PyBytes_AS_STRING(tag); + value = PyUnicode_DecodeUTF8(p, size, "strict"); + Py_DECREF(tag); + if (!value) { + Py_DECREF(key); + return NULL; + } + + /* add to names dictionary */ + if (PyDict_SetItem(self->names, key, value) < 0) { + Py_DECREF(key); + Py_DECREF(value); + return NULL; + } + } + + Py_DECREF(key); + return value; +} + +/* Set the ParseError exception with the given parameters. + * If message is not NULL, it's used as the error string. Otherwise, the + * message string is the default for the given error_code. +*/ +static void +expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, + const char *message) +{ + PyObject *errmsg, *error, *position, *code; + elementtreestate *st = ET_STATE_GLOBAL; + + errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd", + message ? message : EXPAT(ErrorString)(error_code), + line, column); + if (errmsg == NULL) + return; + error = PyObject_CallOneArg(st->parseerror_obj, errmsg); - Py_DECREF(errmsg); - if (!error) - return; - - /* Add code and position attributes */ - code = PyLong_FromLong((long)error_code); - if (!code) { - Py_DECREF(error); - return; - } - if (PyObject_SetAttrString(error, "code", code) == -1) { - Py_DECREF(error); - Py_DECREF(code); - return; - } - Py_DECREF(code); - - position = Py_BuildValue("(nn)", line, column); - if (!position) { - Py_DECREF(error); - return; - } - if (PyObject_SetAttrString(error, "position", position) == -1) { - Py_DECREF(error); - Py_DECREF(position); - return; - } - Py_DECREF(position); - - PyErr_SetObject(st->parseerror_obj, error); - Py_DECREF(error); -} - -/* -------------------------------------------------------------------- */ -/* handlers */ - -static void -expat_default_handler(XMLParserObject* self, const XML_Char* data_in, - int data_len) -{ - PyObject* key; - PyObject* value; - PyObject* res; - - if (data_len < 2 || data_in[0] != '&') - return; - - if (PyErr_Occurred()) - return; - - key = PyUnicode_DecodeUTF8(data_in + 1, data_len - 2, "strict"); - if (!key) - return; - + Py_DECREF(errmsg); + if (!error) + return; + + /* Add code and position attributes */ + code = PyLong_FromLong((long)error_code); + if (!code) { + Py_DECREF(error); + return; + } + if (PyObject_SetAttrString(error, "code", code) == -1) { + Py_DECREF(error); + Py_DECREF(code); + return; + } + Py_DECREF(code); + + position = Py_BuildValue("(nn)", line, column); + if (!position) { + Py_DECREF(error); + return; + } + if (PyObject_SetAttrString(error, "position", position) == -1) { + Py_DECREF(error); + Py_DECREF(position); + return; + } + Py_DECREF(position); + + PyErr_SetObject(st->parseerror_obj, error); + Py_DECREF(error); +} + +/* -------------------------------------------------------------------- */ +/* handlers */ + +static void +expat_default_handler(XMLParserObject* self, const XML_Char* data_in, + int data_len) +{ + PyObject* key; + PyObject* value; + PyObject* res; + + if (data_len < 2 || data_in[0] != '&') + return; + + if (PyErr_Occurred()) + return; + + key = PyUnicode_DecodeUTF8(data_in + 1, data_len - 2, "strict"); + if (!key) + return; + value = PyDict_GetItemWithError(self->entity, key); - - if (value) { - if (TreeBuilder_CheckExact(self->target)) - res = treebuilder_handle_data( - (TreeBuilderObject*) self->target, value - ); - else if (self->handle_data) + + if (value) { + if (TreeBuilder_CheckExact(self->target)) + res = treebuilder_handle_data( + (TreeBuilderObject*) self->target, value + ); + else if (self->handle_data) res = PyObject_CallOneArg(self->handle_data, value); - else - res = NULL; - Py_XDECREF(res); - } else if (!PyErr_Occurred()) { - /* Report the first error, not the last */ - char message[128] = "undefined entity "; - strncat(message, data_in, data_len < 100?data_len:100); - expat_set_error( - XML_ERROR_UNDEFINED_ENTITY, - EXPAT(GetErrorLineNumber)(self->parser), - EXPAT(GetErrorColumnNumber)(self->parser), - message - ); - } - - Py_DECREF(key); -} - -static void -expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, - const XML_Char **attrib_in) -{ - PyObject* res; - PyObject* tag; - PyObject* attrib; - int ok; - - if (PyErr_Occurred()) - return; - - /* tag name */ - tag = makeuniversal(self, tag_in); - if (!tag) - return; /* parser will look for errors */ - - /* attributes */ - if (attrib_in[0]) { - attrib = PyDict_New(); - if (!attrib) { - Py_DECREF(tag); - return; - } - while (attrib_in[0] && attrib_in[1]) { - PyObject* key = makeuniversal(self, attrib_in[0]); - PyObject* value = PyUnicode_DecodeUTF8(attrib_in[1], strlen(attrib_in[1]), "strict"); - if (!key || !value) { - Py_XDECREF(value); - Py_XDECREF(key); - Py_DECREF(attrib); - Py_DECREF(tag); - return; - } - ok = PyDict_SetItem(attrib, key, value); - Py_DECREF(value); - Py_DECREF(key); - if (ok < 0) { - Py_DECREF(attrib); - Py_DECREF(tag); - return; - } - attrib_in += 2; - } - } else { + else + res = NULL; + Py_XDECREF(res); + } else if (!PyErr_Occurred()) { + /* Report the first error, not the last */ + char message[128] = "undefined entity "; + strncat(message, data_in, data_len < 100?data_len:100); + expat_set_error( + XML_ERROR_UNDEFINED_ENTITY, + EXPAT(GetErrorLineNumber)(self->parser), + EXPAT(GetErrorColumnNumber)(self->parser), + message + ); + } + + Py_DECREF(key); +} + +static void +expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, + const XML_Char **attrib_in) +{ + PyObject* res; + PyObject* tag; + PyObject* attrib; + int ok; + + if (PyErr_Occurred()) + return; + + /* tag name */ + tag = makeuniversal(self, tag_in); + if (!tag) + return; /* parser will look for errors */ + + /* attributes */ + if (attrib_in[0]) { + attrib = PyDict_New(); + if (!attrib) { + Py_DECREF(tag); + return; + } + while (attrib_in[0] && attrib_in[1]) { + PyObject* key = makeuniversal(self, attrib_in[0]); + PyObject* value = PyUnicode_DecodeUTF8(attrib_in[1], strlen(attrib_in[1]), "strict"); + if (!key || !value) { + Py_XDECREF(value); + Py_XDECREF(key); + Py_DECREF(attrib); + Py_DECREF(tag); + return; + } + ok = PyDict_SetItem(attrib, key, value); + Py_DECREF(value); + Py_DECREF(key); + if (ok < 0) { + Py_DECREF(attrib); + Py_DECREF(tag); + return; + } + attrib_in += 2; + } + } else { attrib = NULL; - } - - if (TreeBuilder_CheckExact(self->target)) { - /* shortcut */ - res = treebuilder_handle_start((TreeBuilderObject*) self->target, - tag, attrib); - } - else if (self->handle_start) { + } + + if (TreeBuilder_CheckExact(self->target)) { + /* shortcut */ + res = treebuilder_handle_start((TreeBuilderObject*) self->target, + tag, attrib); + } + else if (self->handle_start) { if (attrib == NULL) { - attrib = PyDict_New(); - if (!attrib) { - Py_DECREF(tag); - return; - } - } - res = PyObject_CallFunctionObjArgs(self->handle_start, - tag, attrib, NULL); - } else - res = NULL; - - Py_DECREF(tag); + attrib = PyDict_New(); + if (!attrib) { + Py_DECREF(tag); + return; + } + } + res = PyObject_CallFunctionObjArgs(self->handle_start, + tag, attrib, NULL); + } else + res = NULL; + + Py_DECREF(tag); Py_XDECREF(attrib); - - Py_XDECREF(res); -} - -static void -expat_data_handler(XMLParserObject* self, const XML_Char* data_in, - int data_len) -{ - PyObject* data; - PyObject* res; - - if (PyErr_Occurred()) - return; - - data = PyUnicode_DecodeUTF8(data_in, data_len, "strict"); - if (!data) - return; /* parser will look for errors */ - - if (TreeBuilder_CheckExact(self->target)) - /* shortcut */ - res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); - else if (self->handle_data) + + Py_XDECREF(res); +} + +static void +expat_data_handler(XMLParserObject* self, const XML_Char* data_in, + int data_len) +{ + PyObject* data; + PyObject* res; + + if (PyErr_Occurred()) + return; + + data = PyUnicode_DecodeUTF8(data_in, data_len, "strict"); + if (!data) + return; /* parser will look for errors */ + + if (TreeBuilder_CheckExact(self->target)) + /* shortcut */ + res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); + else if (self->handle_data) res = PyObject_CallOneArg(self->handle_data, data); - else - res = NULL; - - Py_DECREF(data); - - Py_XDECREF(res); -} - -static void -expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) -{ - PyObject* tag; - PyObject* res = NULL; - - if (PyErr_Occurred()) - return; - - if (TreeBuilder_CheckExact(self->target)) - /* shortcut */ - /* the standard tree builder doesn't look at the end tag */ - res = treebuilder_handle_end( - (TreeBuilderObject*) self->target, Py_None - ); - else if (self->handle_end) { - tag = makeuniversal(self, tag_in); - if (tag) { + else + res = NULL; + + Py_DECREF(data); + + Py_XDECREF(res); +} + +static void +expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) +{ + PyObject* tag; + PyObject* res = NULL; + + if (PyErr_Occurred()) + return; + + if (TreeBuilder_CheckExact(self->target)) + /* shortcut */ + /* the standard tree builder doesn't look at the end tag */ + res = treebuilder_handle_end( + (TreeBuilderObject*) self->target, Py_None + ); + else if (self->handle_end) { + tag = makeuniversal(self, tag_in); + if (tag) { res = PyObject_CallOneArg(self->handle_end, tag); - Py_DECREF(tag); - } - } - - Py_XDECREF(res); -} - -static void + Py_DECREF(tag); + } + } + + Py_XDECREF(res); +} + +static void expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in, const XML_Char *uri_in) -{ +{ PyObject* res = NULL; PyObject* uri; PyObject* prefix; PyObject* stack[2]; - - if (PyErr_Occurred()) - return; - + + if (PyErr_Occurred()) + return; + if (!uri_in) uri_in = ""; if (!prefix_in) prefix_in = ""; - + if (TreeBuilder_CheckExact(self->target)) { /* shortcut - TreeBuilder does not actually implement .start_ns() */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; - + if (target->events_append && target->start_ns_event_obj) { prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); if (!prefix) @@ -3427,20 +3427,20 @@ expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in, } Py_XDECREF(res); -} - -static void -expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) -{ +} + +static void +expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) +{ PyObject *res = NULL; PyObject* prefix; - - if (PyErr_Occurred()) - return; - + + if (PyErr_Occurred()) + return; + if (!prefix_in) prefix_in = ""; - + if (TreeBuilder_CheckExact(self->target)) { /* shortcut - TreeBuilder does not actually implement .end_ns() */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3458,22 +3458,22 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) } Py_XDECREF(res); -} - -static void -expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) -{ - PyObject* comment; - PyObject* res; - - if (PyErr_Occurred()) - return; - +} + +static void +expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) +{ + PyObject* comment; + PyObject* res; + + if (PyErr_Occurred()) + return; + if (TreeBuilder_CheckExact(self->target)) { /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; - comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); + comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); if (!comment) return; /* parser will look for errors */ @@ -3488,82 +3488,82 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) res = PyObject_CallOneArg(self->handle_comment, comment); Py_XDECREF(res); Py_DECREF(comment); - } -} - -static void -expat_start_doctype_handler(XMLParserObject *self, - const XML_Char *doctype_name, - const XML_Char *sysid, - const XML_Char *pubid, - int has_internal_subset) -{ + } +} + +static void +expat_start_doctype_handler(XMLParserObject *self, + const XML_Char *doctype_name, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset) +{ _Py_IDENTIFIER(doctype); - PyObject *doctype_name_obj, *sysid_obj, *pubid_obj; + PyObject *doctype_name_obj, *sysid_obj, *pubid_obj; PyObject *res; - - if (PyErr_Occurred()) - return; - - doctype_name_obj = makeuniversal(self, doctype_name); - if (!doctype_name_obj) - return; - - if (sysid) { - sysid_obj = makeuniversal(self, sysid); - if (!sysid_obj) { - Py_DECREF(doctype_name_obj); - return; - } - } else { - Py_INCREF(Py_None); - sysid_obj = Py_None; - } - - if (pubid) { - pubid_obj = makeuniversal(self, pubid); - if (!pubid_obj) { - Py_DECREF(doctype_name_obj); - Py_DECREF(sysid_obj); - return; - } - } else { - Py_INCREF(Py_None); - pubid_obj = Py_None; - } - - /* If the target has a handler for doctype, call it. */ - if (self->handle_doctype) { - res = PyObject_CallFunctionObjArgs(self->handle_doctype, - doctype_name_obj, pubid_obj, - sysid_obj, NULL); + + if (PyErr_Occurred()) + return; + + doctype_name_obj = makeuniversal(self, doctype_name); + if (!doctype_name_obj) + return; + + if (sysid) { + sysid_obj = makeuniversal(self, sysid); + if (!sysid_obj) { + Py_DECREF(doctype_name_obj); + return; + } + } else { + Py_INCREF(Py_None); + sysid_obj = Py_None; + } + + if (pubid) { + pubid_obj = makeuniversal(self, pubid); + if (!pubid_obj) { + Py_DECREF(doctype_name_obj); + Py_DECREF(sysid_obj); + return; + } + } else { + Py_INCREF(Py_None); + pubid_obj = Py_None; + } + + /* If the target has a handler for doctype, call it. */ + if (self->handle_doctype) { + res = PyObject_CallFunctionObjArgs(self->handle_doctype, + doctype_name_obj, pubid_obj, + sysid_obj, NULL); Py_XDECREF(res); - } + } else if (_PyObject_LookupAttrId((PyObject *)self, &PyId_doctype, &res) > 0) { (void)PyErr_WarnEx(PyExc_RuntimeWarning, "The doctype() method of XMLParser is ignored. " "Define doctype() method on the TreeBuilder target.", 1); Py_DECREF(res); - } - - Py_DECREF(doctype_name_obj); - Py_DECREF(pubid_obj); - Py_DECREF(sysid_obj); -} - -static void -expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, - const XML_Char* data_in) -{ + } + + Py_DECREF(doctype_name_obj); + Py_DECREF(pubid_obj); + Py_DECREF(sysid_obj); +} + +static void +expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, + const XML_Char* data_in) +{ PyObject* pi_target; - PyObject* data; - PyObject* res; + PyObject* data; + PyObject* res; PyObject* stack[2]; - - if (PyErr_Occurred()) - return; - + + if (PyErr_Occurred()) + return; + if (TreeBuilder_CheckExact(self->target)) { /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3576,10 +3576,10 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, if (!data) goto error; res = treebuilder_handle_pi(target, pi_target, data); - Py_XDECREF(res); - Py_DECREF(data); + Py_XDECREF(res); + Py_DECREF(data); Py_DECREF(pi_target); - } + } } else if (self->handle_pi) { pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); if (!pi_target) @@ -3592,95 +3592,95 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, stack[1] = data; res = _PyObject_FastCall(self->handle_pi, stack, 2); Py_XDECREF(res); - Py_DECREF(data); - Py_DECREF(pi_target); - } - - return; - - error: - Py_XDECREF(pi_target); - return; -} - -/* -------------------------------------------------------------------- */ - -static PyObject * -xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - XMLParserObject *self = (XMLParserObject *)type->tp_alloc(type, 0); - if (self) { - self->parser = NULL; - self->target = self->entity = self->names = NULL; - self->handle_start_ns = self->handle_end_ns = NULL; - self->handle_start = self->handle_data = self->handle_end = NULL; - self->handle_comment = self->handle_pi = self->handle_close = NULL; - self->handle_doctype = NULL; - } - return (PyObject *)self; -} - -static int -ignore_attribute_error(PyObject *value) -{ - if (value == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return -1; - } - PyErr_Clear(); - } - return 0; -} + Py_DECREF(data); + Py_DECREF(pi_target); + } -/*[clinic input] -_elementtree.XMLParser.__init__ + return; + error: + Py_XDECREF(pi_target); + return; +} + +/* -------------------------------------------------------------------- */ + +static PyObject * +xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + XMLParserObject *self = (XMLParserObject *)type->tp_alloc(type, 0); + if (self) { + self->parser = NULL; + self->target = self->entity = self->names = NULL; + self->handle_start_ns = self->handle_end_ns = NULL; + self->handle_start = self->handle_data = self->handle_end = NULL; + self->handle_comment = self->handle_pi = self->handle_close = NULL; + self->handle_doctype = NULL; + } + return (PyObject *)self; +} + +static int +ignore_attribute_error(PyObject *value) +{ + if (value == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + return -1; + } + PyErr_Clear(); + } + return 0; +} + +/*[clinic input] +_elementtree.XMLParser.__init__ + * - target: object = NULL + target: object = NULL encoding: str(accept={str, NoneType}) = None - -[clinic start generated code]*/ - -static int + +[clinic start generated code]*/ + +static int _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, const char *encoding) /*[clinic end generated code: output=3ae45ec6cdf344e4 input=53e35a829ae043e8]*/ -{ - self->entity = PyDict_New(); - if (!self->entity) - return -1; - - self->names = PyDict_New(); - if (!self->names) { - Py_CLEAR(self->entity); - return -1; - } - - self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); - if (!self->parser) { - Py_CLEAR(self->entity); - Py_CLEAR(self->names); - PyErr_NoMemory(); - return -1; - } - /* expat < 2.1.0 has no XML_SetHashSalt() */ - if (EXPAT(SetHashSalt) != NULL) { - EXPAT(SetHashSalt)(self->parser, - (unsigned long)_Py_HashSecret.expat.hashsalt); - } - - if (target) { - Py_INCREF(target); - } else { - target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); - if (!target) { - Py_CLEAR(self->entity); - Py_CLEAR(self->names); - return -1; - } - } - self->target = target; - +{ + self->entity = PyDict_New(); + if (!self->entity) + return -1; + + self->names = PyDict_New(); + if (!self->names) { + Py_CLEAR(self->entity); + return -1; + } + + self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); + if (!self->parser) { + Py_CLEAR(self->entity); + Py_CLEAR(self->names); + PyErr_NoMemory(); + return -1; + } + /* expat < 2.1.0 has no XML_SetHashSalt() */ + if (EXPAT(SetHashSalt) != NULL) { + EXPAT(SetHashSalt)(self->parser, + (unsigned long)_Py_HashSecret.expat.hashsalt); + } + + if (target) { + Py_INCREF(target); + } else { + target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); + if (!target) { + Py_CLEAR(self->entity); + Py_CLEAR(self->names); + return -1; + } + } + self->target = target; + self->handle_start_ns = PyObject_GetAttrString(target, "start_ns"); if (ignore_attribute_error(self->handle_start_ns)) { return -1; @@ -3689,132 +3689,132 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, if (ignore_attribute_error(self->handle_end_ns)) { return -1; } - self->handle_start = PyObject_GetAttrString(target, "start"); - if (ignore_attribute_error(self->handle_start)) { - return -1; - } - self->handle_data = PyObject_GetAttrString(target, "data"); - if (ignore_attribute_error(self->handle_data)) { - return -1; - } - self->handle_end = PyObject_GetAttrString(target, "end"); - if (ignore_attribute_error(self->handle_end)) { - return -1; - } - self->handle_comment = PyObject_GetAttrString(target, "comment"); - if (ignore_attribute_error(self->handle_comment)) { - return -1; - } - self->handle_pi = PyObject_GetAttrString(target, "pi"); - if (ignore_attribute_error(self->handle_pi)) { - return -1; - } - self->handle_close = PyObject_GetAttrString(target, "close"); - if (ignore_attribute_error(self->handle_close)) { - return -1; - } - self->handle_doctype = PyObject_GetAttrString(target, "doctype"); - if (ignore_attribute_error(self->handle_doctype)) { - return -1; - } - - /* configure parser */ - EXPAT(SetUserData)(self->parser, self); + self->handle_start = PyObject_GetAttrString(target, "start"); + if (ignore_attribute_error(self->handle_start)) { + return -1; + } + self->handle_data = PyObject_GetAttrString(target, "data"); + if (ignore_attribute_error(self->handle_data)) { + return -1; + } + self->handle_end = PyObject_GetAttrString(target, "end"); + if (ignore_attribute_error(self->handle_end)) { + return -1; + } + self->handle_comment = PyObject_GetAttrString(target, "comment"); + if (ignore_attribute_error(self->handle_comment)) { + return -1; + } + self->handle_pi = PyObject_GetAttrString(target, "pi"); + if (ignore_attribute_error(self->handle_pi)) { + return -1; + } + self->handle_close = PyObject_GetAttrString(target, "close"); + if (ignore_attribute_error(self->handle_close)) { + return -1; + } + self->handle_doctype = PyObject_GetAttrString(target, "doctype"); + if (ignore_attribute_error(self->handle_doctype)) { + return -1; + } + + /* configure parser */ + EXPAT(SetUserData)(self->parser, self); if (self->handle_start_ns || self->handle_end_ns) EXPAT(SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); - EXPAT(SetElementHandler)( - self->parser, - (XML_StartElementHandler) expat_start_handler, - (XML_EndElementHandler) expat_end_handler - ); - EXPAT(SetDefaultHandlerExpand)( - self->parser, - (XML_DefaultHandler) expat_default_handler - ); - EXPAT(SetCharacterDataHandler)( - self->parser, - (XML_CharacterDataHandler) expat_data_handler - ); - if (self->handle_comment) - EXPAT(SetCommentHandler)( - self->parser, - (XML_CommentHandler) expat_comment_handler - ); - if (self->handle_pi) - EXPAT(SetProcessingInstructionHandler)( - self->parser, - (XML_ProcessingInstructionHandler) expat_pi_handler - ); - EXPAT(SetStartDoctypeDeclHandler)( - self->parser, - (XML_StartDoctypeDeclHandler) expat_start_doctype_handler - ); - EXPAT(SetUnknownEncodingHandler)( - self->parser, - EXPAT(DefaultUnknownEncodingHandler), NULL - ); - - return 0; -} - -static int -xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->handle_close); - Py_VISIT(self->handle_pi); - Py_VISIT(self->handle_comment); - Py_VISIT(self->handle_end); - Py_VISIT(self->handle_data); - Py_VISIT(self->handle_start); + EXPAT(SetElementHandler)( + self->parser, + (XML_StartElementHandler) expat_start_handler, + (XML_EndElementHandler) expat_end_handler + ); + EXPAT(SetDefaultHandlerExpand)( + self->parser, + (XML_DefaultHandler) expat_default_handler + ); + EXPAT(SetCharacterDataHandler)( + self->parser, + (XML_CharacterDataHandler) expat_data_handler + ); + if (self->handle_comment) + EXPAT(SetCommentHandler)( + self->parser, + (XML_CommentHandler) expat_comment_handler + ); + if (self->handle_pi) + EXPAT(SetProcessingInstructionHandler)( + self->parser, + (XML_ProcessingInstructionHandler) expat_pi_handler + ); + EXPAT(SetStartDoctypeDeclHandler)( + self->parser, + (XML_StartDoctypeDeclHandler) expat_start_doctype_handler + ); + EXPAT(SetUnknownEncodingHandler)( + self->parser, + EXPAT(DefaultUnknownEncodingHandler), NULL + ); + + return 0; +} + +static int +xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->handle_close); + Py_VISIT(self->handle_pi); + Py_VISIT(self->handle_comment); + Py_VISIT(self->handle_end); + Py_VISIT(self->handle_data); + Py_VISIT(self->handle_start); Py_VISIT(self->handle_start_ns); Py_VISIT(self->handle_end_ns); Py_VISIT(self->handle_doctype); - - Py_VISIT(self->target); - Py_VISIT(self->entity); - Py_VISIT(self->names); - - return 0; -} - -static int -xmlparser_gc_clear(XMLParserObject *self) -{ - if (self->parser != NULL) { - XML_Parser parser = self->parser; - self->parser = NULL; - EXPAT(ParserFree)(parser); - } - - Py_CLEAR(self->handle_close); - Py_CLEAR(self->handle_pi); - Py_CLEAR(self->handle_comment); - Py_CLEAR(self->handle_end); - Py_CLEAR(self->handle_data); - Py_CLEAR(self->handle_start); + + Py_VISIT(self->target); + Py_VISIT(self->entity); + Py_VISIT(self->names); + + return 0; +} + +static int +xmlparser_gc_clear(XMLParserObject *self) +{ + if (self->parser != NULL) { + XML_Parser parser = self->parser; + self->parser = NULL; + EXPAT(ParserFree)(parser); + } + + Py_CLEAR(self->handle_close); + Py_CLEAR(self->handle_pi); + Py_CLEAR(self->handle_comment); + Py_CLEAR(self->handle_end); + Py_CLEAR(self->handle_data); + Py_CLEAR(self->handle_start); Py_CLEAR(self->handle_start_ns); Py_CLEAR(self->handle_end_ns); - Py_CLEAR(self->handle_doctype); - - Py_CLEAR(self->target); - Py_CLEAR(self->entity); - Py_CLEAR(self->names); - - return 0; -} - -static void -xmlparser_dealloc(XMLParserObject* self) -{ - PyObject_GC_UnTrack(self); - xmlparser_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); -} - + Py_CLEAR(self->handle_doctype); + + Py_CLEAR(self->target); + Py_CLEAR(self->entity); + Py_CLEAR(self->names); + + return 0; +} + +static void +xmlparser_dealloc(XMLParserObject* self) +{ + PyObject_GC_UnTrack(self); + xmlparser_gc_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + Py_LOCAL_INLINE(int) _check_xmlparser(XMLParserObject* self) { @@ -3826,288 +3826,288 @@ _check_xmlparser(XMLParserObject* self) return 1; } -LOCAL(PyObject*) -expat_parse(XMLParserObject* self, const char* data, int data_len, int final) -{ - int ok; - - assert(!PyErr_Occurred()); - ok = EXPAT(Parse)(self->parser, data, data_len, final); - - if (PyErr_Occurred()) - return NULL; - - if (!ok) { - expat_set_error( - EXPAT(GetErrorCode)(self->parser), - EXPAT(GetErrorLineNumber)(self->parser), - EXPAT(GetErrorColumnNumber)(self->parser), - NULL - ); - return NULL; - } - - Py_RETURN_NONE; -} - -/*[clinic input] -_elementtree.XMLParser.close - -[clinic start generated code]*/ - -static PyObject * -_elementtree_XMLParser_close_impl(XMLParserObject *self) -/*[clinic end generated code: output=d68d375dd23bc7fb input=ca7909ca78c3abfe]*/ -{ - /* end feeding data to parser */ - - PyObject* res; +LOCAL(PyObject*) +expat_parse(XMLParserObject* self, const char* data, int data_len, int final) +{ + int ok; + + assert(!PyErr_Occurred()); + ok = EXPAT(Parse)(self->parser, data, data_len, final); + + if (PyErr_Occurred()) + return NULL; + + if (!ok) { + expat_set_error( + EXPAT(GetErrorCode)(self->parser), + EXPAT(GetErrorLineNumber)(self->parser), + EXPAT(GetErrorColumnNumber)(self->parser), + NULL + ); + return NULL; + } + + Py_RETURN_NONE; +} + +/*[clinic input] +_elementtree.XMLParser.close + +[clinic start generated code]*/ + +static PyObject * +_elementtree_XMLParser_close_impl(XMLParserObject *self) +/*[clinic end generated code: output=d68d375dd23bc7fb input=ca7909ca78c3abfe]*/ +{ + /* end feeding data to parser */ + + PyObject* res; if (!_check_xmlparser(self)) { return NULL; } - res = expat_parse(self, "", 0, 1); - if (!res) - return NULL; - - if (TreeBuilder_CheckExact(self->target)) { - Py_DECREF(res); - return treebuilder_done((TreeBuilderObject*) self->target); - } - else if (self->handle_close) { - Py_DECREF(res); + res = expat_parse(self, "", 0, 1); + if (!res) + return NULL; + + if (TreeBuilder_CheckExact(self->target)) { + Py_DECREF(res); + return treebuilder_done((TreeBuilderObject*) self->target); + } + else if (self->handle_close) { + Py_DECREF(res); return PyObject_CallNoArgs(self->handle_close); - } - else { - return res; - } -} - -/*[clinic input] -_elementtree.XMLParser.feed - - data: object - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) -/*[clinic end generated code: output=e42b6a78eec7446d input=fe231b6b8de3ce1f]*/ -{ - /* feed data to parser */ - + } + else { + return res; + } +} + +/*[clinic input] +_elementtree.XMLParser.feed + + data: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) +/*[clinic end generated code: output=e42b6a78eec7446d input=fe231b6b8de3ce1f]*/ +{ + /* feed data to parser */ + if (!_check_xmlparser(self)) { return NULL; } - if (PyUnicode_Check(data)) { - Py_ssize_t data_len; - const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len); - if (data_ptr == NULL) - return NULL; - if (data_len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); - return NULL; - } - /* Explicitly set UTF-8 encoding. Return code ignored. */ - (void)EXPAT(SetEncoding)(self->parser, "utf-8"); - return expat_parse(self, data_ptr, (int)data_len, 0); - } - else { - Py_buffer view; - PyObject *res; - if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0) - return NULL; - if (view.len > INT_MAX) { - PyBuffer_Release(&view); - PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); - return NULL; - } - res = expat_parse(self, view.buf, (int)view.len, 0); - PyBuffer_Release(&view); - return res; - } -} - -/*[clinic input] -_elementtree.XMLParser._parse_whole - - file: object - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) -/*[clinic end generated code: output=f797197bb818dda3 input=19ecc893b6f3e752]*/ -{ - /* (internal) parse the whole input, until end of stream */ - PyObject* reader; - PyObject* buffer; - PyObject* temp; - PyObject* res; - + if (PyUnicode_Check(data)) { + Py_ssize_t data_len; + const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len); + if (data_ptr == NULL) + return NULL; + if (data_len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); + return NULL; + } + /* Explicitly set UTF-8 encoding. Return code ignored. */ + (void)EXPAT(SetEncoding)(self->parser, "utf-8"); + return expat_parse(self, data_ptr, (int)data_len, 0); + } + else { + Py_buffer view; + PyObject *res; + if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0) + return NULL; + if (view.len > INT_MAX) { + PyBuffer_Release(&view); + PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); + return NULL; + } + res = expat_parse(self, view.buf, (int)view.len, 0); + PyBuffer_Release(&view); + return res; + } +} + +/*[clinic input] +_elementtree.XMLParser._parse_whole + + file: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) +/*[clinic end generated code: output=f797197bb818dda3 input=19ecc893b6f3e752]*/ +{ + /* (internal) parse the whole input, until end of stream */ + PyObject* reader; + PyObject* buffer; + PyObject* temp; + PyObject* res; + if (!_check_xmlparser(self)) { return NULL; } - reader = PyObject_GetAttrString(file, "read"); - if (!reader) - return NULL; - - /* read from open file object */ - for (;;) { - - buffer = PyObject_CallFunction(reader, "i", 64*1024); - - if (!buffer) { - /* read failed (e.g. due to KeyboardInterrupt) */ - Py_DECREF(reader); - return NULL; - } - - if (PyUnicode_CheckExact(buffer)) { - /* A unicode object is encoded into bytes using UTF-8 */ - if (PyUnicode_GET_LENGTH(buffer) == 0) { - Py_DECREF(buffer); - break; - } - temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass"); - Py_DECREF(buffer); - if (!temp) { - /* Propagate exception from PyUnicode_AsEncodedString */ - Py_DECREF(reader); - return NULL; - } - buffer = temp; - } - else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) { - Py_DECREF(buffer); - break; - } - - if (PyBytes_GET_SIZE(buffer) > INT_MAX) { - Py_DECREF(buffer); - Py_DECREF(reader); - PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); - return NULL; - } - res = expat_parse( - self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 - ); - - Py_DECREF(buffer); - - if (!res) { - Py_DECREF(reader); - return NULL; - } - Py_DECREF(res); - - } - - Py_DECREF(reader); - - res = expat_parse(self, "", 0, 1); - - if (res && TreeBuilder_CheckExact(self->target)) { - Py_DECREF(res); - return treebuilder_done((TreeBuilderObject*) self->target); - } - - return res; -} - -/*[clinic input] -_elementtree.XMLParser._setevents - - events_queue: object - events_to_report: object = None - / - -[clinic start generated code]*/ - -static PyObject * -_elementtree_XMLParser__setevents_impl(XMLParserObject *self, - PyObject *events_queue, - PyObject *events_to_report) -/*[clinic end generated code: output=1440092922b13ed1 input=abf90830a1c3b0fc]*/ -{ - /* activate element event reporting */ - Py_ssize_t i; - TreeBuilderObject *target; - PyObject *events_append, *events_seq; - + reader = PyObject_GetAttrString(file, "read"); + if (!reader) + return NULL; + + /* read from open file object */ + for (;;) { + + buffer = PyObject_CallFunction(reader, "i", 64*1024); + + if (!buffer) { + /* read failed (e.g. due to KeyboardInterrupt) */ + Py_DECREF(reader); + return NULL; + } + + if (PyUnicode_CheckExact(buffer)) { + /* A unicode object is encoded into bytes using UTF-8 */ + if (PyUnicode_GET_LENGTH(buffer) == 0) { + Py_DECREF(buffer); + break; + } + temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass"); + Py_DECREF(buffer); + if (!temp) { + /* Propagate exception from PyUnicode_AsEncodedString */ + Py_DECREF(reader); + return NULL; + } + buffer = temp; + } + else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) { + Py_DECREF(buffer); + break; + } + + if (PyBytes_GET_SIZE(buffer) > INT_MAX) { + Py_DECREF(buffer); + Py_DECREF(reader); + PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); + return NULL; + } + res = expat_parse( + self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 + ); + + Py_DECREF(buffer); + + if (!res) { + Py_DECREF(reader); + return NULL; + } + Py_DECREF(res); + + } + + Py_DECREF(reader); + + res = expat_parse(self, "", 0, 1); + + if (res && TreeBuilder_CheckExact(self->target)) { + Py_DECREF(res); + return treebuilder_done((TreeBuilderObject*) self->target); + } + + return res; +} + +/*[clinic input] +_elementtree.XMLParser._setevents + + events_queue: object + events_to_report: object = None + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_XMLParser__setevents_impl(XMLParserObject *self, + PyObject *events_queue, + PyObject *events_to_report) +/*[clinic end generated code: output=1440092922b13ed1 input=abf90830a1c3b0fc]*/ +{ + /* activate element event reporting */ + Py_ssize_t i; + TreeBuilderObject *target; + PyObject *events_append, *events_seq; + if (!_check_xmlparser(self)) { return NULL; } - if (!TreeBuilder_CheckExact(self->target)) { - PyErr_SetString( - PyExc_TypeError, - "event handling only supported for ElementTree.TreeBuilder " - "targets" - ); - return NULL; - } - - target = (TreeBuilderObject*) self->target; - - events_append = PyObject_GetAttrString(events_queue, "append"); - if (events_append == NULL) - return NULL; - Py_XSETREF(target->events_append, events_append); - - /* clear out existing events */ - Py_CLEAR(target->start_event_obj); - Py_CLEAR(target->end_event_obj); - Py_CLEAR(target->start_ns_event_obj); - Py_CLEAR(target->end_ns_event_obj); + if (!TreeBuilder_CheckExact(self->target)) { + PyErr_SetString( + PyExc_TypeError, + "event handling only supported for ElementTree.TreeBuilder " + "targets" + ); + return NULL; + } + + target = (TreeBuilderObject*) self->target; + + events_append = PyObject_GetAttrString(events_queue, "append"); + if (events_append == NULL) + return NULL; + Py_XSETREF(target->events_append, events_append); + + /* clear out existing events */ + Py_CLEAR(target->start_event_obj); + Py_CLEAR(target->end_event_obj); + Py_CLEAR(target->start_ns_event_obj); + Py_CLEAR(target->end_ns_event_obj); Py_CLEAR(target->comment_event_obj); Py_CLEAR(target->pi_event_obj); - - if (events_to_report == Py_None) { - /* default is "end" only */ - target->end_event_obj = PyUnicode_FromString("end"); - Py_RETURN_NONE; - } - - if (!(events_seq = PySequence_Fast(events_to_report, - "events must be a sequence"))) { - return NULL; - } - - for (i = 0; i < PySequence_Fast_GET_SIZE(events_seq); ++i) { - PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i); - const char *event_name = NULL; - if (PyUnicode_Check(event_name_obj)) { - event_name = PyUnicode_AsUTF8(event_name_obj); - } else if (PyBytes_Check(event_name_obj)) { - event_name = PyBytes_AS_STRING(event_name_obj); - } - if (event_name == NULL) { - Py_DECREF(events_seq); - PyErr_Format(PyExc_ValueError, "invalid events sequence"); - return NULL; - } - - Py_INCREF(event_name_obj); - if (strcmp(event_name, "start") == 0) { - Py_XSETREF(target->start_event_obj, event_name_obj); - } else if (strcmp(event_name, "end") == 0) { - Py_XSETREF(target->end_event_obj, event_name_obj); - } else if (strcmp(event_name, "start-ns") == 0) { - Py_XSETREF(target->start_ns_event_obj, event_name_obj); - EXPAT(SetNamespaceDeclHandler)( - self->parser, - (XML_StartNamespaceDeclHandler) expat_start_ns_handler, - (XML_EndNamespaceDeclHandler) expat_end_ns_handler - ); - } else if (strcmp(event_name, "end-ns") == 0) { - Py_XSETREF(target->end_ns_event_obj, event_name_obj); - EXPAT(SetNamespaceDeclHandler)( - self->parser, - (XML_StartNamespaceDeclHandler) expat_start_ns_handler, - (XML_EndNamespaceDeclHandler) expat_end_ns_handler - ); + + if (events_to_report == Py_None) { + /* default is "end" only */ + target->end_event_obj = PyUnicode_FromString("end"); + Py_RETURN_NONE; + } + + if (!(events_seq = PySequence_Fast(events_to_report, + "events must be a sequence"))) { + return NULL; + } + + for (i = 0; i < PySequence_Fast_GET_SIZE(events_seq); ++i) { + PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i); + const char *event_name = NULL; + if (PyUnicode_Check(event_name_obj)) { + event_name = PyUnicode_AsUTF8(event_name_obj); + } else if (PyBytes_Check(event_name_obj)) { + event_name = PyBytes_AS_STRING(event_name_obj); + } + if (event_name == NULL) { + Py_DECREF(events_seq); + PyErr_Format(PyExc_ValueError, "invalid events sequence"); + return NULL; + } + + Py_INCREF(event_name_obj); + if (strcmp(event_name, "start") == 0) { + Py_XSETREF(target->start_event_obj, event_name_obj); + } else if (strcmp(event_name, "end") == 0) { + Py_XSETREF(target->end_event_obj, event_name_obj); + } else if (strcmp(event_name, "start-ns") == 0) { + Py_XSETREF(target->start_ns_event_obj, event_name_obj); + EXPAT(SetNamespaceDeclHandler)( + self->parser, + (XML_StartNamespaceDeclHandler) expat_start_ns_handler, + (XML_EndNamespaceDeclHandler) expat_end_ns_handler + ); + } else if (strcmp(event_name, "end-ns") == 0) { + Py_XSETREF(target->end_ns_event_obj, event_name_obj); + EXPAT(SetNamespaceDeclHandler)( + self->parser, + (XML_StartNamespaceDeclHandler) expat_start_ns_handler, + (XML_EndNamespaceDeclHandler) expat_end_ns_handler + ); } else if (strcmp(event_name, "comment") == 0) { Py_XSETREF(target->comment_event_obj, event_name_obj); EXPAT(SetCommentHandler)( @@ -4120,342 +4120,342 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, self->parser, (XML_ProcessingInstructionHandler) expat_pi_handler ); - } else { - Py_DECREF(event_name_obj); - Py_DECREF(events_seq); - PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name); - return NULL; - } - } - - Py_DECREF(events_seq); - Py_RETURN_NONE; -} - + } else { + Py_DECREF(event_name_obj); + Py_DECREF(events_seq); + PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name); + return NULL; + } + } + + Py_DECREF(events_seq); + Py_RETURN_NONE; +} + static PyMemberDef xmlparser_members[] = { {"entity", T_OBJECT, offsetof(XMLParserObject, entity), READONLY, NULL}, {"target", T_OBJECT, offsetof(XMLParserObject, target), READONLY, NULL}, {NULL} }; -static PyObject* +static PyObject* xmlparser_version_getter(XMLParserObject *self, void *closure) -{ +{ return PyUnicode_FromFormat( "Expat %d.%d.%d", XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); -} - +} + static PyGetSetDef xmlparser_getsetlist[] = { {"version", (getter)xmlparser_version_getter, NULL, NULL}, {NULL}, }; -#include "clinic/_elementtree.c.h" - -static PyMethodDef element_methods[] = { - - _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF - - _ELEMENTTREE_ELEMENT_GET_METHODDEF - _ELEMENTTREE_ELEMENT_SET_METHODDEF - - _ELEMENTTREE_ELEMENT_FIND_METHODDEF - _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF - _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF - - _ELEMENTTREE_ELEMENT_APPEND_METHODDEF - _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF - _ELEMENTTREE_ELEMENT_INSERT_METHODDEF - _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF - - _ELEMENTTREE_ELEMENT_ITER_METHODDEF - _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF - _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF - - _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF - _ELEMENTTREE_ELEMENT_KEYS_METHODDEF - - _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF - - _ELEMENTTREE_ELEMENT___COPY___METHODDEF - _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF - _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF - _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF - _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF - - {NULL, NULL} -}; - -static PyMappingMethods element_as_mapping = { - (lenfunc) element_length, - (binaryfunc) element_subscr, - (objobjargproc) element_ass_subscr, -}; - -static PyGetSetDef element_getsetlist[] = { - {"tag", - (getter)element_tag_getter, - (setter)element_tag_setter, - "A string identifying what kind of data this element represents"}, - {"text", - (getter)element_text_getter, - (setter)element_text_setter, - "A string of text directly after the start tag, or None"}, - {"tail", - (getter)element_tail_getter, - (setter)element_tail_setter, - "A string of text directly after the end tag, or None"}, - {"attrib", - (getter)element_attrib_getter, - (setter)element_attrib_setter, - "A dictionary containing the element's attributes"}, - {NULL}, -}; - -static PyTypeObject Element_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, - /* methods */ - (destructor)element_dealloc, /* tp_dealloc */ +#include "clinic/_elementtree.c.h" + +static PyMethodDef element_methods[] = { + + _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF + + _ELEMENTTREE_ELEMENT_GET_METHODDEF + _ELEMENTTREE_ELEMENT_SET_METHODDEF + + _ELEMENTTREE_ELEMENT_FIND_METHODDEF + _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF + _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF + + _ELEMENTTREE_ELEMENT_APPEND_METHODDEF + _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF + _ELEMENTTREE_ELEMENT_INSERT_METHODDEF + _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF + + _ELEMENTTREE_ELEMENT_ITER_METHODDEF + _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF + _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF + + _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF + _ELEMENTTREE_ELEMENT_KEYS_METHODDEF + + _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF + + _ELEMENTTREE_ELEMENT___COPY___METHODDEF + _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF + _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF + _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF + _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF + + {NULL, NULL} +}; + +static PyMappingMethods element_as_mapping = { + (lenfunc) element_length, + (binaryfunc) element_subscr, + (objobjargproc) element_ass_subscr, +}; + +static PyGetSetDef element_getsetlist[] = { + {"tag", + (getter)element_tag_getter, + (setter)element_tag_setter, + "A string identifying what kind of data this element represents"}, + {"text", + (getter)element_text_getter, + (setter)element_text_setter, + "A string of text directly after the start tag, or None"}, + {"tail", + (getter)element_tail_getter, + (setter)element_tail_setter, + "A string of text directly after the end tag, or None"}, + {"attrib", + (getter)element_attrib_getter, + (setter)element_attrib_setter, + "A dictionary containing the element's attributes"}, + {NULL}, +}; + +static PyTypeObject Element_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, + /* methods */ + (destructor)element_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)element_repr, /* tp_repr */ - 0, /* tp_as_number */ - &element_as_sequence, /* tp_as_sequence */ - &element_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)element_gc_traverse, /* tp_traverse */ - (inquiry)element_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(ElementObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - element_methods, /* tp_methods */ - 0, /* tp_members */ - element_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)element_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - element_new, /* tp_new */ - 0, /* tp_free */ -}; - -static PyMethodDef treebuilder_methods[] = { - _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF - _ELEMENTTREE_TREEBUILDER_START_METHODDEF - _ELEMENTTREE_TREEBUILDER_END_METHODDEF + (reprfunc)element_repr, /* tp_repr */ + 0, /* tp_as_number */ + &element_as_sequence, /* tp_as_sequence */ + &element_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)element_gc_traverse, /* tp_traverse */ + (inquiry)element_gc_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(ElementObject, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + element_methods, /* tp_methods */ + 0, /* tp_members */ + element_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)element_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + element_new, /* tp_new */ + 0, /* tp_free */ +}; + +static PyMethodDef treebuilder_methods[] = { + _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF + _ELEMENTTREE_TREEBUILDER_START_METHODDEF + _ELEMENTTREE_TREEBUILDER_END_METHODDEF _ELEMENTTREE_TREEBUILDER_COMMENT_METHODDEF _ELEMENTTREE_TREEBUILDER_PI_METHODDEF - _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF - {NULL, NULL} -}; - -static PyTypeObject TreeBuilder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0, - /* methods */ - (destructor)treebuilder_dealloc, /* tp_dealloc */ + _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF + {NULL, NULL} +}; + +static PyTypeObject TreeBuilder_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0, + /* methods */ + (destructor)treebuilder_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)treebuilder_gc_traverse, /* tp_traverse */ - (inquiry)treebuilder_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - treebuilder_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _elementtree_TreeBuilder___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - treebuilder_new, /* tp_new */ - 0, /* tp_free */ -}; - -static PyMethodDef xmlparser_methods[] = { - _ELEMENTTREE_XMLPARSER_FEED_METHODDEF - _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF - _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF - _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF - {NULL, NULL} -}; - -static PyTypeObject XMLParser_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, - /* methods */ - (destructor)xmlparser_dealloc, /* tp_dealloc */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)treebuilder_gc_traverse, /* tp_traverse */ + (inquiry)treebuilder_gc_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + treebuilder_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + _elementtree_TreeBuilder___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + treebuilder_new, /* tp_new */ + 0, /* tp_free */ +}; + +static PyMethodDef xmlparser_methods[] = { + _ELEMENTTREE_XMLPARSER_FEED_METHODDEF + _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF + _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF + _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF + {NULL, NULL} +}; + +static PyTypeObject XMLParser_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, + /* methods */ + (destructor)xmlparser_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 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_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)xmlparser_gc_traverse, /* tp_traverse */ - (inquiry)xmlparser_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - xmlparser_methods, /* tp_methods */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)xmlparser_gc_traverse, /* tp_traverse */ + (inquiry)xmlparser_gc_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + xmlparser_methods, /* tp_methods */ xmlparser_members, /* tp_members */ xmlparser_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _elementtree_XMLParser___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - xmlparser_new, /* tp_new */ - 0, /* tp_free */ -}; - -/* ==================================================================== */ -/* python module interface */ - -static PyMethodDef _functions[] = { + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + _elementtree_XMLParser___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + xmlparser_new, /* tp_new */ + 0, /* tp_free */ +}; + +/* ==================================================================== */ +/* python module interface */ + +static PyMethodDef _functions[] = { {"SubElement", (PyCFunction)(void(*)(void)) subelement, METH_VARARGS | METH_KEYWORDS}, _ELEMENTTREE__SET_FACTORIES_METHODDEF - {NULL, NULL} -}; - - -static struct PyModuleDef elementtreemodule = { - PyModuleDef_HEAD_INIT, - "_elementtree", - NULL, - sizeof(elementtreestate), - _functions, - NULL, - elementtree_traverse, - elementtree_clear, - elementtree_free -}; - -PyMODINIT_FUNC -PyInit__elementtree(void) -{ - PyObject *m, *temp; - elementtreestate *st; - - m = PyState_FindModule(&elementtreemodule); - if (m) { - Py_INCREF(m); - return m; - } - - /* Initialize object types */ - if (PyType_Ready(&ElementIter_Type) < 0) - return NULL; - if (PyType_Ready(&TreeBuilder_Type) < 0) - return NULL; - if (PyType_Ready(&Element_Type) < 0) - return NULL; - if (PyType_Ready(&XMLParser_Type) < 0) - return NULL; - - m = PyModule_Create(&elementtreemodule); - if (!m) - return NULL; + {NULL, NULL} +}; + + +static struct PyModuleDef elementtreemodule = { + PyModuleDef_HEAD_INIT, + "_elementtree", + NULL, + sizeof(elementtreestate), + _functions, + NULL, + elementtree_traverse, + elementtree_clear, + elementtree_free +}; + +PyMODINIT_FUNC +PyInit__elementtree(void) +{ + PyObject *m, *temp; + elementtreestate *st; + + m = PyState_FindModule(&elementtreemodule); + if (m) { + Py_INCREF(m); + return m; + } + + /* Initialize object types */ + if (PyType_Ready(&ElementIter_Type) < 0) + return NULL; + if (PyType_Ready(&TreeBuilder_Type) < 0) + return NULL; + if (PyType_Ready(&Element_Type) < 0) + return NULL; + if (PyType_Ready(&XMLParser_Type) < 0) + return NULL; + + m = PyModule_Create(&elementtreemodule); + if (!m) + return NULL; st = get_elementtree_state(m); - - if (!(temp = PyImport_ImportModule("copy"))) - return NULL; - st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); - Py_XDECREF(temp); - - if (st->deepcopy_obj == NULL) { - return NULL; - } - - assert(!PyErr_Occurred()); - if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) - return NULL; - - /* link against pyexpat */ - expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); - if (expat_capi) { - /* check that it's usable */ - if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || - (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) || - expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION || - expat_capi->MINOR_VERSION != XML_MINOR_VERSION || - expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { - PyErr_SetString(PyExc_ImportError, - "pyexpat version is incompatible"); - return NULL; - } - } else { - return NULL; - } - - st->parseerror_obj = PyErr_NewException( - "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL - ); - Py_INCREF(st->parseerror_obj); + + if (!(temp = PyImport_ImportModule("copy"))) + return NULL; + st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); + Py_XDECREF(temp); + + if (st->deepcopy_obj == NULL) { + return NULL; + } + + assert(!PyErr_Occurred()); + if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) + return NULL; + + /* link against pyexpat */ + expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); + if (expat_capi) { + /* check that it's usable */ + if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || + (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) || + expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION || + expat_capi->MINOR_VERSION != XML_MINOR_VERSION || + expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { + PyErr_SetString(PyExc_ImportError, + "pyexpat version is incompatible"); + return NULL; + } + } else { + return NULL; + } + + st->parseerror_obj = PyErr_NewException( + "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL + ); + Py_INCREF(st->parseerror_obj); if (PyModule_AddObject(m, "ParseError", st->parseerror_obj) < 0) { Py_DECREF(st->parseerror_obj); return NULL; } - + PyTypeObject *types[] = { &Element_Type, &TreeBuilder_Type, &XMLParser_Type }; - + for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { if (PyModule_AddType(m, types[i]) < 0) { return NULL; } } - - return m; -} + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_functoolsmodule.c b/contrib/tools/python3/src/Modules/_functoolsmodule.c index 42764a181d2..097bee53c6d 100644 --- a/contrib/tools/python3/src/Modules/_functoolsmodule.c +++ b/contrib/tools/python3/src/Modules/_functoolsmodule.c @@ -1,132 +1,132 @@ -#include "Python.h" +#include "Python.h" #include "pycore_object.h" // _PyObject_GC_TRACK #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tupleobject.h" #include "structmember.h" // PyMemberDef - -/* _functools module written and maintained - by Hye-Shik Chang - with adaptations by Raymond Hettinger - Copyright (c) 2004, 2005, 2006 Python Software Foundation. - All rights reserved. -*/ - -/* partial object **********************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *fn; - PyObject *args; - PyObject *kw; + +/* _functools module written and maintained + by Hye-Shik Chang + with adaptations by Raymond Hettinger + Copyright (c) 2004, 2005, 2006 Python Software Foundation. + All rights reserved. +*/ + +/* partial object **********************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *fn; + PyObject *args; + PyObject *kw; PyObject *dict; /* __dict__ */ - PyObject *weakreflist; /* List of weak references */ + PyObject *weakreflist; /* List of weak references */ vectorcallfunc vectorcall; -} partialobject; - -static PyTypeObject partial_type; - +} partialobject; + +static PyTypeObject partial_type; + static void partial_setvectorcall(partialobject *pto); -static PyObject * -partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - PyObject *func, *pargs, *nargs, *pkw; - partialobject *pto; - - if (PyTuple_GET_SIZE(args) < 1) { - PyErr_SetString(PyExc_TypeError, - "type 'partial' takes at least one argument"); - return NULL; - } - - pargs = pkw = NULL; - func = PyTuple_GET_ITEM(args, 0); +static PyObject * +partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *func, *pargs, *nargs, *pkw; + partialobject *pto; + + if (PyTuple_GET_SIZE(args) < 1) { + PyErr_SetString(PyExc_TypeError, + "type 'partial' takes at least one argument"); + return NULL; + } + + pargs = pkw = NULL; + func = PyTuple_GET_ITEM(args, 0); if (Py_IS_TYPE(func, &partial_type) && type == &partial_type) { - partialobject *part = (partialobject *)func; - if (part->dict == NULL) { - pargs = part->args; - pkw = part->kw; - func = part->fn; - assert(PyTuple_Check(pargs)); - assert(PyDict_Check(pkw)); - } - } - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_TypeError, - "the first argument must be callable"); - return NULL; - } - - /* create partialobject structure */ - pto = (partialobject *)type->tp_alloc(type, 0); - if (pto == NULL) - return NULL; - - pto->fn = func; - Py_INCREF(func); - - nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX); - if (nargs == NULL) { - Py_DECREF(pto); - return NULL; - } - if (pargs == NULL) { - pto->args = nargs; - } - else { - pto->args = PySequence_Concat(pargs, nargs); - Py_DECREF(nargs); - if (pto->args == NULL) { - Py_DECREF(pto); - return NULL; - } - assert(PyTuple_Check(pto->args)); - } - - if (pkw == NULL || PyDict_GET_SIZE(pkw) == 0) { - if (kw == NULL) { - pto->kw = PyDict_New(); - } - else if (Py_REFCNT(kw) == 1) { - Py_INCREF(kw); - pto->kw = kw; - } - else { - pto->kw = PyDict_Copy(kw); - } - } - else { - pto->kw = PyDict_Copy(pkw); - if (kw != NULL && pto->kw != NULL) { - if (PyDict_Merge(pto->kw, kw, 1) != 0) { - Py_DECREF(pto); - return NULL; - } - } - } - if (pto->kw == NULL) { - Py_DECREF(pto); - return NULL; - } - + partialobject *part = (partialobject *)func; + if (part->dict == NULL) { + pargs = part->args; + pkw = part->kw; + func = part->fn; + assert(PyTuple_Check(pargs)); + assert(PyDict_Check(pkw)); + } + } + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "the first argument must be callable"); + return NULL; + } + + /* create partialobject structure */ + pto = (partialobject *)type->tp_alloc(type, 0); + if (pto == NULL) + return NULL; + + pto->fn = func; + Py_INCREF(func); + + nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX); + if (nargs == NULL) { + Py_DECREF(pto); + return NULL; + } + if (pargs == NULL) { + pto->args = nargs; + } + else { + pto->args = PySequence_Concat(pargs, nargs); + Py_DECREF(nargs); + if (pto->args == NULL) { + Py_DECREF(pto); + return NULL; + } + assert(PyTuple_Check(pto->args)); + } + + if (pkw == NULL || PyDict_GET_SIZE(pkw) == 0) { + if (kw == NULL) { + pto->kw = PyDict_New(); + } + else if (Py_REFCNT(kw) == 1) { + Py_INCREF(kw); + pto->kw = kw; + } + else { + pto->kw = PyDict_Copy(kw); + } + } + else { + pto->kw = PyDict_Copy(pkw); + if (kw != NULL && pto->kw != NULL) { + if (PyDict_Merge(pto->kw, kw, 1) != 0) { + Py_DECREF(pto); + return NULL; + } + } + } + if (pto->kw == NULL) { + Py_DECREF(pto); + return NULL; + } + partial_setvectorcall(pto); - return (PyObject *)pto; -} - -static void -partial_dealloc(partialobject *pto) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(pto); - if (pto->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) pto); - Py_XDECREF(pto->fn); - Py_XDECREF(pto->args); - Py_XDECREF(pto->kw); - Py_XDECREF(pto->dict); - Py_TYPE(pto)->tp_free(pto); -} - + return (PyObject *)pto; +} + +static void +partial_dealloc(partialobject *pto) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(pto); + if (pto->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) pto); + Py_XDECREF(pto->fn); + Py_XDECREF(pto->args); + Py_XDECREF(pto->kw); + Py_XDECREF(pto->dict); + Py_TYPE(pto)->tp_free(pto); +} + /* Merging keyword arguments using the vectorcall convention is messy, so * if we would need to do that, we stop using vectorcall and fall back @@ -142,10 +142,10 @@ partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto, args, nargs, kwnames); } -static PyObject * +static PyObject * partial_vectorcall(partialobject *pto, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ +{ PyThreadState *tstate = _PyThreadState_GET(); /* pto->kw is mutable, so need to check every time */ @@ -182,21 +182,21 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, Py_ssize_t newnargs_total = pto_nargs + nargs_total; - PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; - PyObject *ret; + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; + PyObject *ret; PyObject **stack; - + if (newnargs_total <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { stack = small_stack; - } - else { + } + else { stack = PyMem_Malloc(newnargs_total * sizeof(PyObject *)); if (stack == NULL) { PyErr_NoMemory(); return NULL; - } + } } - + /* Copy to new stack, using borrowed references */ memcpy(stack, pto_args, pto_nargs * sizeof(PyObject*)); memcpy(stack + pto_nargs, args, nargs_total * sizeof(PyObject*)); @@ -205,58 +205,58 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, stack, pto_nargs + nargs, kwnames); if (stack != small_stack) { PyMem_Free(stack); - } - return ret; -} - + } + return ret; +} + /* Set pto->vectorcall depending on the parameters of the partial object */ static void partial_setvectorcall(partialobject *pto) -{ +{ if (PyVectorcall_Function(pto->fn) == NULL) { /* Don't use vectorcall if the underlying function doesn't support it */ pto->vectorcall = NULL; - } + } /* We could have a special case if there are no arguments, * but that is unlikely (why use partial without arguments?), * so we don't optimize that */ else { pto->vectorcall = (vectorcallfunc)partial_vectorcall; } -} - +} + -static PyObject * -partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) -{ +static PyObject * +partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) +{ assert(PyCallable_Check(pto->fn)); assert(PyTuple_Check(pto->args)); assert(PyDict_Check(pto->kw)); - + /* Merge keywords */ PyObject *kwargs2; - if (PyDict_GET_SIZE(pto->kw) == 0) { - /* kwargs can be NULL */ - kwargs2 = kwargs; - Py_XINCREF(kwargs2); - } - else { - /* bpo-27840, bpo-29318: dictionary of keyword parameters must be - copied, because a function using "**kwargs" can modify the - dictionary. */ - kwargs2 = PyDict_Copy(pto->kw); - if (kwargs2 == NULL) { - return NULL; - } - - if (kwargs != NULL) { - if (PyDict_Merge(kwargs2, kwargs, 1) != 0) { - Py_DECREF(kwargs2); - return NULL; - } - } - } - + if (PyDict_GET_SIZE(pto->kw) == 0) { + /* kwargs can be NULL */ + kwargs2 = kwargs; + Py_XINCREF(kwargs2); + } + else { + /* bpo-27840, bpo-29318: dictionary of keyword parameters must be + copied, because a function using "**kwargs" can modify the + dictionary. */ + kwargs2 = PyDict_Copy(pto->kw); + if (kwargs2 == NULL) { + return NULL; + } + + if (kwargs != NULL) { + if (PyDict_Merge(kwargs2, kwargs, 1) != 0) { + Py_DECREF(kwargs2); + return NULL; + } + } + } + /* Merge positional arguments */ /* Note: tupleconcat() is optimized for empty tuples */ PyObject *args2 = PySequence_Concat(pto->args, args); @@ -264,1196 +264,1196 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) Py_XDECREF(kwargs2); return NULL; } - + PyObject *res = PyObject_Call(pto->fn, args2, kwargs2); Py_DECREF(args2); - Py_XDECREF(kwargs2); - return res; -} - -static int -partial_traverse(partialobject *pto, visitproc visit, void *arg) -{ - Py_VISIT(pto->fn); - Py_VISIT(pto->args); - Py_VISIT(pto->kw); - Py_VISIT(pto->dict); - return 0; -} - -PyDoc_STRVAR(partial_doc, -"partial(func, *args, **keywords) - new function with partial application\n\ - of the given arguments and keywords.\n"); - -#define OFF(x) offsetof(partialobject, x) -static PyMemberDef partial_memberlist[] = { - {"func", T_OBJECT, OFF(fn), READONLY, - "function object to use in future partial calls"}, - {"args", T_OBJECT, OFF(args), READONLY, - "tuple of arguments to future partial calls"}, - {"keywords", T_OBJECT, OFF(kw), READONLY, - "dictionary of keyword arguments to future partial calls"}, - {NULL} /* Sentinel */ -}; - -static PyGetSetDef partial_getsetlist[] = { - {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, - {NULL} /* Sentinel */ -}; - -static PyObject * -partial_repr(partialobject *pto) -{ - PyObject *result = NULL; - PyObject *arglist; - Py_ssize_t i, n; - PyObject *key, *value; - int status; - - status = Py_ReprEnter((PyObject *)pto); - if (status != 0) { - if (status < 0) - return NULL; - return PyUnicode_FromString("..."); - } - - arglist = PyUnicode_FromString(""); - if (arglist == NULL) - goto done; - /* Pack positional arguments */ - assert (PyTuple_Check(pto->args)); - n = PyTuple_GET_SIZE(pto->args); - for (i = 0; i < n; i++) { - Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist, - PyTuple_GET_ITEM(pto->args, i))); - if (arglist == NULL) - goto done; - } - /* Pack keyword arguments */ - assert (PyDict_Check(pto->kw)); - for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) { - /* Prevent key.__str__ from deleting the value. */ - Py_INCREF(value); - Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist, - key, value)); - Py_DECREF(value); - if (arglist == NULL) - goto done; - } - result = PyUnicode_FromFormat("%s(%R%U)", Py_TYPE(pto)->tp_name, - pto->fn, arglist); - Py_DECREF(arglist); - - done: - Py_ReprLeave((PyObject *)pto); - return result; -} - -/* Pickle strategy: - __reduce__ by itself doesn't support getting kwargs in the unpickle - operation so we define a __setstate__ that replaces all the information - about the partial. If we only replaced part of it someone would use - it as a hook to do strange things. - */ - -static PyObject * -partial_reduce(partialobject *pto, PyObject *unused) -{ - return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn, - pto->args, pto->kw, - pto->dict ? pto->dict : Py_None); -} - -static PyObject * -partial_setstate(partialobject *pto, PyObject *state) -{ - PyObject *fn, *fnargs, *kw, *dict; - - if (!PyTuple_Check(state) || - !PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) || - !PyCallable_Check(fn) || - !PyTuple_Check(fnargs) || - (kw != Py_None && !PyDict_Check(kw))) - { - PyErr_SetString(PyExc_TypeError, "invalid partial state"); - return NULL; - } - - if(!PyTuple_CheckExact(fnargs)) - fnargs = PySequence_Tuple(fnargs); - else - Py_INCREF(fnargs); - if (fnargs == NULL) - return NULL; - - if (kw == Py_None) - kw = PyDict_New(); - else if(!PyDict_CheckExact(kw)) - kw = PyDict_Copy(kw); - else - Py_INCREF(kw); - if (kw == NULL) { - Py_DECREF(fnargs); - return NULL; - } - - if (dict == Py_None) - dict = NULL; - else - Py_INCREF(dict); - - Py_INCREF(fn); - Py_SETREF(pto->fn, fn); - Py_SETREF(pto->args, fnargs); - Py_SETREF(pto->kw, kw); - Py_XSETREF(pto->dict, dict); + Py_XDECREF(kwargs2); + return res; +} + +static int +partial_traverse(partialobject *pto, visitproc visit, void *arg) +{ + Py_VISIT(pto->fn); + Py_VISIT(pto->args); + Py_VISIT(pto->kw); + Py_VISIT(pto->dict); + return 0; +} + +PyDoc_STRVAR(partial_doc, +"partial(func, *args, **keywords) - new function with partial application\n\ + of the given arguments and keywords.\n"); + +#define OFF(x) offsetof(partialobject, x) +static PyMemberDef partial_memberlist[] = { + {"func", T_OBJECT, OFF(fn), READONLY, + "function object to use in future partial calls"}, + {"args", T_OBJECT, OFF(args), READONLY, + "tuple of arguments to future partial calls"}, + {"keywords", T_OBJECT, OFF(kw), READONLY, + "dictionary of keyword arguments to future partial calls"}, + {NULL} /* Sentinel */ +}; + +static PyGetSetDef partial_getsetlist[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} /* Sentinel */ +}; + +static PyObject * +partial_repr(partialobject *pto) +{ + PyObject *result = NULL; + PyObject *arglist; + Py_ssize_t i, n; + PyObject *key, *value; + int status; + + status = Py_ReprEnter((PyObject *)pto); + if (status != 0) { + if (status < 0) + return NULL; + return PyUnicode_FromString("..."); + } + + arglist = PyUnicode_FromString(""); + if (arglist == NULL) + goto done; + /* Pack positional arguments */ + assert (PyTuple_Check(pto->args)); + n = PyTuple_GET_SIZE(pto->args); + for (i = 0; i < n; i++) { + Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist, + PyTuple_GET_ITEM(pto->args, i))); + if (arglist == NULL) + goto done; + } + /* Pack keyword arguments */ + assert (PyDict_Check(pto->kw)); + for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) { + /* Prevent key.__str__ from deleting the value. */ + Py_INCREF(value); + Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist, + key, value)); + Py_DECREF(value); + if (arglist == NULL) + goto done; + } + result = PyUnicode_FromFormat("%s(%R%U)", Py_TYPE(pto)->tp_name, + pto->fn, arglist); + Py_DECREF(arglist); + + done: + Py_ReprLeave((PyObject *)pto); + return result; +} + +/* Pickle strategy: + __reduce__ by itself doesn't support getting kwargs in the unpickle + operation so we define a __setstate__ that replaces all the information + about the partial. If we only replaced part of it someone would use + it as a hook to do strange things. + */ + +static PyObject * +partial_reduce(partialobject *pto, PyObject *unused) +{ + return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn, + pto->args, pto->kw, + pto->dict ? pto->dict : Py_None); +} + +static PyObject * +partial_setstate(partialobject *pto, PyObject *state) +{ + PyObject *fn, *fnargs, *kw, *dict; + + if (!PyTuple_Check(state) || + !PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) || + !PyCallable_Check(fn) || + !PyTuple_Check(fnargs) || + (kw != Py_None && !PyDict_Check(kw))) + { + PyErr_SetString(PyExc_TypeError, "invalid partial state"); + return NULL; + } + + if(!PyTuple_CheckExact(fnargs)) + fnargs = PySequence_Tuple(fnargs); + else + Py_INCREF(fnargs); + if (fnargs == NULL) + return NULL; + + if (kw == Py_None) + kw = PyDict_New(); + else if(!PyDict_CheckExact(kw)) + kw = PyDict_Copy(kw); + else + Py_INCREF(kw); + if (kw == NULL) { + Py_DECREF(fnargs); + return NULL; + } + + if (dict == Py_None) + dict = NULL; + else + Py_INCREF(dict); + + Py_INCREF(fn); + Py_SETREF(pto->fn, fn); + Py_SETREF(pto->args, fnargs); + Py_SETREF(pto->kw, kw); + Py_XSETREF(pto->dict, dict); partial_setvectorcall(pto); - Py_RETURN_NONE; -} - -static PyMethodDef partial_methods[] = { - {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS}, - {"__setstate__", (PyCFunction)partial_setstate, METH_O}, + Py_RETURN_NONE; +} + +static PyMethodDef partial_methods[] = { + {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS}, + {"__setstate__", (PyCFunction)partial_setstate, METH_O}, {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject partial_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "functools.partial", /* tp_name */ - sizeof(partialobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)partial_dealloc, /* tp_dealloc */ + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject partial_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "functools.partial", /* tp_name */ + sizeof(partialobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)partial_dealloc, /* tp_dealloc */ offsetof(partialobject, vectorcall),/* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)partial_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)partial_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + (reprfunc)partial_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)partial_call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ - partial_doc, /* tp_doc */ - (traverseproc)partial_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(partialobject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - partial_methods, /* tp_methods */ - partial_memberlist, /* tp_members */ - partial_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(partialobject, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - partial_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* cmp_to_key ***************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *cmp; - PyObject *object; -} keyobject; - -static void -keyobject_dealloc(keyobject *ko) -{ - Py_DECREF(ko->cmp); - Py_XDECREF(ko->object); - PyObject_FREE(ko); -} - -static int -keyobject_traverse(keyobject *ko, visitproc visit, void *arg) -{ - Py_VISIT(ko->cmp); - if (ko->object) - Py_VISIT(ko->object); - return 0; -} - -static int -keyobject_clear(keyobject *ko) -{ - Py_CLEAR(ko->cmp); - if (ko->object) - Py_CLEAR(ko->object); - return 0; -} - -static PyMemberDef keyobject_members[] = { - {"obj", T_OBJECT, - offsetof(keyobject, object), 0, - PyDoc_STR("Value wrapped by a key function.")}, - {NULL} -}; - -static PyObject * -keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds); - -static PyObject * -keyobject_richcompare(PyObject *ko, PyObject *other, int op); - -static PyTypeObject keyobject_type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "functools.KeyWrapper", /* tp_name */ - sizeof(keyobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)keyobject_dealloc, /* tp_dealloc */ + partial_doc, /* tp_doc */ + (traverseproc)partial_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(partialobject, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + partial_methods, /* tp_methods */ + partial_memberlist, /* tp_members */ + partial_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(partialobject, dict), /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + partial_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* cmp_to_key ***************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *cmp; + PyObject *object; +} keyobject; + +static void +keyobject_dealloc(keyobject *ko) +{ + Py_DECREF(ko->cmp); + Py_XDECREF(ko->object); + PyObject_FREE(ko); +} + +static int +keyobject_traverse(keyobject *ko, visitproc visit, void *arg) +{ + Py_VISIT(ko->cmp); + if (ko->object) + Py_VISIT(ko->object); + return 0; +} + +static int +keyobject_clear(keyobject *ko) +{ + Py_CLEAR(ko->cmp); + if (ko->object) + Py_CLEAR(ko->object); + return 0; +} + +static PyMemberDef keyobject_members[] = { + {"obj", T_OBJECT, + offsetof(keyobject, object), 0, + PyDoc_STR("Value wrapped by a key function.")}, + {NULL} +}; + +static PyObject * +keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds); + +static PyObject * +keyobject_richcompare(PyObject *ko, PyObject *other, int op); + +static PyTypeObject keyobject_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "functools.KeyWrapper", /* tp_name */ + sizeof(keyobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)keyobject_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)keyobject_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)keyobject_traverse, /* tp_traverse */ - (inquiry)keyobject_clear, /* tp_clear */ - keyobject_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - keyobject_members, /* tp_members */ - 0, /* tp_getset */ -}; - -static PyObject * -keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds) -{ - PyObject *object; - keyobject *result; - static char *kwargs[] = {"obj", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:K", kwargs, &object)) - return NULL; - result = PyObject_New(keyobject, &keyobject_type); - if (!result) - return NULL; - Py_INCREF(ko->cmp); - result->cmp = ko->cmp; - Py_INCREF(object); - result->object = object; - return (PyObject *)result; -} - -static PyObject * -keyobject_richcompare(PyObject *ko, PyObject *other, int op) -{ - PyObject *res; - PyObject *x; - PyObject *y; - PyObject *compare; - PyObject *answer; - PyObject* stack[2]; - + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)keyobject_call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)keyobject_traverse, /* tp_traverse */ + (inquiry)keyobject_clear, /* tp_clear */ + keyobject_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + keyobject_members, /* tp_members */ + 0, /* tp_getset */ +}; + +static PyObject * +keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds) +{ + PyObject *object; + keyobject *result; + static char *kwargs[] = {"obj", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:K", kwargs, &object)) + return NULL; + result = PyObject_New(keyobject, &keyobject_type); + if (!result) + return NULL; + Py_INCREF(ko->cmp); + result->cmp = ko->cmp; + Py_INCREF(object); + result->object = object; + return (PyObject *)result; +} + +static PyObject * +keyobject_richcompare(PyObject *ko, PyObject *other, int op) +{ + PyObject *res; + PyObject *x; + PyObject *y; + PyObject *compare; + PyObject *answer; + PyObject* stack[2]; + if (!Py_IS_TYPE(other, &keyobject_type)) { - PyErr_Format(PyExc_TypeError, "other argument must be K instance"); - return NULL; - } - compare = ((keyobject *) ko)->cmp; - assert(compare != NULL); - x = ((keyobject *) ko)->object; - y = ((keyobject *) other)->object; - if (!x || !y){ - PyErr_Format(PyExc_AttributeError, "object"); - return NULL; - } - - /* Call the user's comparison function and translate the 3-way - * result into true or false (or error). - */ - stack[0] = x; - stack[1] = y; - res = _PyObject_FastCall(compare, stack, 2); - if (res == NULL) { - return NULL; - } - - answer = PyObject_RichCompare(res, _PyLong_Zero, op); - Py_DECREF(res); - return answer; -} - -static PyObject * -functools_cmp_to_key(PyObject *self, PyObject *args, PyObject *kwds) -{ - PyObject *cmp; - static char *kwargs[] = {"mycmp", NULL}; - keyobject *object; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:cmp_to_key", kwargs, &cmp)) - return NULL; - object = PyObject_New(keyobject, &keyobject_type); - if (!object) - return NULL; - Py_INCREF(cmp); - object->cmp = cmp; - object->object = NULL; - return (PyObject *)object; -} - -PyDoc_STRVAR(functools_cmp_to_key_doc, -"Convert a cmp= function into a key= function."); - -/* reduce (used to be a builtin) ********************************************/ - -static PyObject * -functools_reduce(PyObject *self, PyObject *args) -{ - PyObject *seq, *func, *result = NULL, *it; - - if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result)) - return NULL; - if (result != NULL) - Py_INCREF(result); - - it = PyObject_GetIter(seq); - if (it == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_SetString(PyExc_TypeError, - "reduce() arg 2 must support iteration"); - Py_XDECREF(result); - return NULL; - } - - if ((args = PyTuple_New(2)) == NULL) - goto Fail; - - for (;;) { - PyObject *op2; - + PyErr_Format(PyExc_TypeError, "other argument must be K instance"); + return NULL; + } + compare = ((keyobject *) ko)->cmp; + assert(compare != NULL); + x = ((keyobject *) ko)->object; + y = ((keyobject *) other)->object; + if (!x || !y){ + PyErr_Format(PyExc_AttributeError, "object"); + return NULL; + } + + /* Call the user's comparison function and translate the 3-way + * result into true or false (or error). + */ + stack[0] = x; + stack[1] = y; + res = _PyObject_FastCall(compare, stack, 2); + if (res == NULL) { + return NULL; + } + + answer = PyObject_RichCompare(res, _PyLong_Zero, op); + Py_DECREF(res); + return answer; +} + +static PyObject * +functools_cmp_to_key(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *cmp; + static char *kwargs[] = {"mycmp", NULL}; + keyobject *object; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:cmp_to_key", kwargs, &cmp)) + return NULL; + object = PyObject_New(keyobject, &keyobject_type); + if (!object) + return NULL; + Py_INCREF(cmp); + object->cmp = cmp; + object->object = NULL; + return (PyObject *)object; +} + +PyDoc_STRVAR(functools_cmp_to_key_doc, +"Convert a cmp= function into a key= function."); + +/* reduce (used to be a builtin) ********************************************/ + +static PyObject * +functools_reduce(PyObject *self, PyObject *args) +{ + PyObject *seq, *func, *result = NULL, *it; + + if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result)) + return NULL; + if (result != NULL) + Py_INCREF(result); + + it = PyObject_GetIter(seq); + if (it == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_SetString(PyExc_TypeError, + "reduce() arg 2 must support iteration"); + Py_XDECREF(result); + return NULL; + } + + if ((args = PyTuple_New(2)) == NULL) + goto Fail; + + for (;;) { + PyObject *op2; + if (Py_REFCNT(args) > 1) { - Py_DECREF(args); - if ((args = PyTuple_New(2)) == NULL) - goto Fail; - } - - op2 = PyIter_Next(it); - if (op2 == NULL) { - if (PyErr_Occurred()) - goto Fail; - break; - } - - if (result == NULL) - result = op2; - else { + Py_DECREF(args); + if ((args = PyTuple_New(2)) == NULL) + goto Fail; + } + + op2 = PyIter_Next(it); + if (op2 == NULL) { + if (PyErr_Occurred()) + goto Fail; + break; + } + + if (result == NULL) + result = op2; + else { /* Update the args tuple in-place */ assert(Py_REFCNT(args) == 1); Py_XSETREF(_PyTuple_ITEMS(args)[0], result); Py_XSETREF(_PyTuple_ITEMS(args)[1], op2); if ((result = PyObject_Call(func, args, NULL)) == NULL) { - goto Fail; + goto Fail; } // bpo-42536: The GC may have untracked this args tuple. Since we're // recycling it, make sure it's tracked again: if (!_PyObject_GC_IS_TRACKED(args)) { _PyObject_GC_TRACK(args); } - } - } - - Py_DECREF(args); - - if (result == NULL) - PyErr_SetString(PyExc_TypeError, - "reduce() of empty sequence with no initial value"); - - Py_DECREF(it); - return result; - -Fail: - Py_XDECREF(args); - Py_XDECREF(result); - Py_DECREF(it); - return NULL; -} - -PyDoc_STRVAR(functools_reduce_doc, -"reduce(function, sequence[, initial]) -> value\n\ -\n\ -Apply a function of two arguments cumulatively to the items of a sequence,\n\ -from left to right, so as to reduce the sequence to a single value.\n\ -For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\ -((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\ -of the sequence in the calculation, and serves as a default when the\n\ -sequence is empty."); - -/* lru_cache object **********************************************************/ - -/* There are four principal algorithmic differences from the pure python version: - - 1). The C version relies on the GIL instead of having its own reentrant lock. - - 2). The prev/next link fields use borrowed references. - - 3). For a full cache, the pure python version rotates the location of the - root entry so that it never has to move individual links and it can - limit updates to just the key and result fields. However, in the C - version, links are temporarily removed while the cache dict updates are - occurring. Afterwards, they are appended or prepended back into the - doubly-linked lists. - - 4) In the Python version, the _HashSeq class is used to prevent __hash__ - from being called more than once. In the C version, the "known hash" - variants of dictionary calls as used to the same effect. - -*/ - - -/* this object is used delimit args and keywords in the cache keys */ -static PyObject *kwd_mark = NULL; - -struct lru_list_elem; -struct lru_cache_object; - -typedef struct lru_list_elem { - PyObject_HEAD - struct lru_list_elem *prev, *next; /* borrowed links */ - Py_hash_t hash; - PyObject *key, *result; -} lru_list_elem; - -static void -lru_list_elem_dealloc(lru_list_elem *link) -{ - Py_XDECREF(link->key); - Py_XDECREF(link->result); - PyObject_Del(link); -} - -static PyTypeObject lru_list_elem_type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "functools._lru_list_elem", /* tp_name */ - sizeof(lru_list_elem), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)lru_list_elem_dealloc, /* tp_dealloc */ + } + } + + Py_DECREF(args); + + if (result == NULL) + PyErr_SetString(PyExc_TypeError, + "reduce() of empty sequence with no initial value"); + + Py_DECREF(it); + return result; + +Fail: + Py_XDECREF(args); + Py_XDECREF(result); + Py_DECREF(it); + return NULL; +} + +PyDoc_STRVAR(functools_reduce_doc, +"reduce(function, sequence[, initial]) -> value\n\ +\n\ +Apply a function of two arguments cumulatively to the items of a sequence,\n\ +from left to right, so as to reduce the sequence to a single value.\n\ +For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\ +((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\ +of the sequence in the calculation, and serves as a default when the\n\ +sequence is empty."); + +/* lru_cache object **********************************************************/ + +/* There are four principal algorithmic differences from the pure python version: + + 1). The C version relies on the GIL instead of having its own reentrant lock. + + 2). The prev/next link fields use borrowed references. + + 3). For a full cache, the pure python version rotates the location of the + root entry so that it never has to move individual links and it can + limit updates to just the key and result fields. However, in the C + version, links are temporarily removed while the cache dict updates are + occurring. Afterwards, they are appended or prepended back into the + doubly-linked lists. + + 4) In the Python version, the _HashSeq class is used to prevent __hash__ + from being called more than once. In the C version, the "known hash" + variants of dictionary calls as used to the same effect. + +*/ + + +/* this object is used delimit args and keywords in the cache keys */ +static PyObject *kwd_mark = NULL; + +struct lru_list_elem; +struct lru_cache_object; + +typedef struct lru_list_elem { + PyObject_HEAD + struct lru_list_elem *prev, *next; /* borrowed links */ + Py_hash_t hash; + PyObject *key, *result; +} lru_list_elem; + +static void +lru_list_elem_dealloc(lru_list_elem *link) +{ + Py_XDECREF(link->key); + Py_XDECREF(link->result); + PyObject_Del(link); +} + +static PyTypeObject lru_list_elem_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "functools._lru_list_elem", /* tp_name */ + sizeof(lru_list_elem), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)lru_list_elem_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ -}; - - -typedef PyObject *(*lru_cache_ternaryfunc)(struct lru_cache_object *, PyObject *, PyObject *); - -typedef struct lru_cache_object { - lru_list_elem root; /* includes PyObject_HEAD */ - lru_cache_ternaryfunc wrapper; - int typed; - PyObject *cache; - Py_ssize_t hits; - PyObject *func; - Py_ssize_t maxsize; - Py_ssize_t misses; - PyObject *cache_info_type; - PyObject *dict; + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ +}; + + +typedef PyObject *(*lru_cache_ternaryfunc)(struct lru_cache_object *, PyObject *, PyObject *); + +typedef struct lru_cache_object { + lru_list_elem root; /* includes PyObject_HEAD */ + lru_cache_ternaryfunc wrapper; + int typed; + PyObject *cache; + Py_ssize_t hits; + PyObject *func; + Py_ssize_t maxsize; + Py_ssize_t misses; + PyObject *cache_info_type; + PyObject *dict; PyObject *weakreflist; -} lru_cache_object; - -static PyTypeObject lru_cache_type; - -static PyObject * -lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) -{ - PyObject *key, *keyword, *value; - Py_ssize_t key_size, pos, key_pos, kwds_size; - +} lru_cache_object; + +static PyTypeObject lru_cache_type; + +static PyObject * +lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) +{ + PyObject *key, *keyword, *value; + Py_ssize_t key_size, pos, key_pos, kwds_size; + kwds_size = kwds ? PyDict_GET_SIZE(kwds) : 0; - /* short path, key will match args anyway, which is a tuple */ + /* short path, key will match args anyway, which is a tuple */ if (!typed && !kwds_size) { - if (PyTuple_GET_SIZE(args) == 1) { - key = PyTuple_GET_ITEM(args, 0); - if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) { - /* For common scalar keys, save space by - dropping the enclosing args tuple */ - Py_INCREF(key); - return key; - } - } - Py_INCREF(args); - return args; - } - - key_size = PyTuple_GET_SIZE(args); - if (kwds_size) - key_size += kwds_size * 2 + 1; - if (typed) - key_size += PyTuple_GET_SIZE(args) + kwds_size; - - key = PyTuple_New(key_size); - if (key == NULL) - return NULL; - - key_pos = 0; - for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { - PyObject *item = PyTuple_GET_ITEM(args, pos); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); - } - if (kwds_size) { - Py_INCREF(kwd_mark); - PyTuple_SET_ITEM(key, key_pos++, kwd_mark); - for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { - Py_INCREF(keyword); - PyTuple_SET_ITEM(key, key_pos++, keyword); - Py_INCREF(value); - PyTuple_SET_ITEM(key, key_pos++, value); - } - assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1); - } - if (typed) { - for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { - PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos)); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); - } - if (kwds_size) { - for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { - PyObject *item = (PyObject *)Py_TYPE(value); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); - } - } - } - assert(key_pos == key_size); - return key; -} - -static PyObject * -uncached_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds) -{ - PyObject *result; - - self->misses++; - result = PyObject_Call(self->func, args, kwds); - if (!result) - return NULL; - return result; -} - -static PyObject * -infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds) -{ - PyObject *result; - Py_hash_t hash; - PyObject *key = lru_cache_make_key(args, kwds, self->typed); - if (!key) - return NULL; - hash = PyObject_Hash(key); - if (hash == -1) { - Py_DECREF(key); - return NULL; - } - result = _PyDict_GetItem_KnownHash(self->cache, key, hash); - if (result) { - Py_INCREF(result); - self->hits++; - Py_DECREF(key); - return result; - } - if (PyErr_Occurred()) { - Py_DECREF(key); - return NULL; - } - self->misses++; - result = PyObject_Call(self->func, args, kwds); - if (!result) { - Py_DECREF(key); - return NULL; - } - if (_PyDict_SetItem_KnownHash(self->cache, key, result, hash) < 0) { - Py_DECREF(result); - Py_DECREF(key); - return NULL; - } - Py_DECREF(key); - return result; -} - -static void -lru_cache_extract_link(lru_list_elem *link) -{ - lru_list_elem *link_prev = link->prev; - lru_list_elem *link_next = link->next; - link_prev->next = link->next; - link_next->prev = link->prev; -} - -static void -lru_cache_append_link(lru_cache_object *self, lru_list_elem *link) -{ - lru_list_elem *root = &self->root; - lru_list_elem *last = root->prev; - last->next = root->prev = link; - link->prev = last; - link->next = root; -} - -static void -lru_cache_prepend_link(lru_cache_object *self, lru_list_elem *link) -{ - lru_list_elem *root = &self->root; - lru_list_elem *first = root->next; - first->prev = root->next = link; - link->prev = root; - link->next = first; -} - -/* General note on reentrancy: - - There are four dictionary calls in the bounded_lru_cache_wrapper(): - 1) The initial check for a cache match. 2) The post user-function - check for a cache match. 3) The deletion of the oldest entry. - 4) The addition of the newest entry. - - In all four calls, we have a known hash which lets use avoid a call - to __hash__(). That leaves only __eq__ as a possible source of a - reentrant call. - - The __eq__ method call is always made for a cache hit (dict access #1). - Accordingly, we have make sure not modify the cache state prior to - this call. - - The __eq__ method call is never made for the deletion (dict access #3) - because it is an identity match. - - For the other two accesses (#2 and #4), calls to __eq__ only occur - when some other entry happens to have an exactly matching hash (all - 64-bits). Though rare, this can happen, so we have to make sure to - either call it at the top of its code path before any cache - state modifications (dict access #2) or be prepared to restore - invariants at the end of the code path (dict access #4). - - Another possible source of reentrancy is a decref which can trigger - arbitrary code execution. To make the code easier to reason about, - the decrefs are deferred to the end of the each possible code path - so that we know the cache is a consistent state. - */ - -static PyObject * -bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds) -{ - lru_list_elem *link; - PyObject *key, *result, *testresult; - Py_hash_t hash; - - key = lru_cache_make_key(args, kwds, self->typed); - if (!key) - return NULL; - hash = PyObject_Hash(key); - if (hash == -1) { - Py_DECREF(key); - return NULL; - } - link = (lru_list_elem *)_PyDict_GetItem_KnownHash(self->cache, key, hash); - if (link != NULL) { - lru_cache_extract_link(link); - lru_cache_append_link(self, link); - result = link->result; - self->hits++; - Py_INCREF(result); - Py_DECREF(key); - return result; - } - if (PyErr_Occurred()) { - Py_DECREF(key); - return NULL; - } - self->misses++; - result = PyObject_Call(self->func, args, kwds); - if (!result) { - Py_DECREF(key); - return NULL; - } - testresult = _PyDict_GetItem_KnownHash(self->cache, key, hash); - if (testresult != NULL) { - /* Getting here means that this same key was added to the cache - during the PyObject_Call(). Since the link update is already - done, we need only return the computed result. */ - Py_DECREF(key); - return result; - } - if (PyErr_Occurred()) { - /* This is an unusual case since this same lookup - did not previously trigger an error during lookup. - Treat it the same as an error in user function - and return with the error set. */ - Py_DECREF(key); - Py_DECREF(result); - return NULL; - } - /* This is the normal case. The new key wasn't found before - user function call and it is still not there. So we - proceed normally and update the cache with the new result. */ - - assert(self->maxsize > 0); - if (PyDict_GET_SIZE(self->cache) < self->maxsize || - self->root.next == &self->root) - { - /* Cache is not full, so put the result in a new link */ - link = (lru_list_elem *)PyObject_New(lru_list_elem, - &lru_list_elem_type); - if (link == NULL) { - Py_DECREF(key); - Py_DECREF(result); - return NULL; - } - - link->hash = hash; - link->key = key; - link->result = result; - /* What is really needed here is a SetItem variant with a "no clobber" - option. If the __eq__ call triggers a reentrant call that adds - this same key, then this setitem call will update the cache dict - with this new link, leaving the old link as an orphan (i.e. not - having a cache dict entry that refers to it). */ - if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, - hash) < 0) { - Py_DECREF(link); - return NULL; - } - lru_cache_append_link(self, link); - Py_INCREF(result); /* for return */ - return result; - } - /* Since the cache is full, we need to evict an old key and add - a new key. Rather than free the old link and allocate a new - one, we reuse the link for the new key and result and move it - to front of the cache to mark it as recently used. - - We try to assure all code paths (including errors) leave all - of the links in place. Either the link is successfully - updated and moved or it is restored to its old position. - However if an unrecoverable error is found, it doesn't - make sense to reinsert the link, so we leave it out - and the cache will no longer register as full. - */ - PyObject *oldkey, *oldresult, *popresult; - - /* Extract the oldest item. */ - assert(self->root.next != &self->root); - link = self->root.next; - lru_cache_extract_link(link); - /* Remove it from the cache. - The cache dict holds one reference to the link. - We created one other reference when the link was created. - The linked list only has borrowed references. */ - popresult = _PyDict_Pop_KnownHash(self->cache, link->key, - link->hash, Py_None); - if (popresult == Py_None) { - /* Getting here means that the user function call or another - thread has already removed the old key from the dictionary. - This link is now an orphan. Since we don't want to leave the - cache in an inconsistent state, we don't restore the link. */ - Py_DECREF(popresult); - Py_DECREF(link); - Py_DECREF(key); - return result; - } - if (popresult == NULL) { - /* An error arose while trying to remove the oldest key (the one - being evicted) from the cache. We restore the link to its - original position as the oldest link. Then we allow the - error propagate upward; treating it the same as an error - arising in the user function. */ - lru_cache_prepend_link(self, link); - Py_DECREF(key); - Py_DECREF(result); - return NULL; - } - /* Keep a reference to the old key and old result to prevent their - ref counts from going to zero during the update. That will - prevent potentially arbitrary object clean-up code (i.e. __del__) - from running while we're still adjusting the links. */ - oldkey = link->key; - oldresult = link->result; - - link->hash = hash; - link->key = key; - link->result = result; - /* Note: The link is being added to the cache dict without the - prev and next fields set to valid values. We have to wait - for successful insertion in the cache dict before adding the - link to the linked list. Otherwise, the potentially reentrant - __eq__ call could cause the then orphan link to be visited. */ - if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, - hash) < 0) { - /* Somehow the cache dict update failed. We no longer can - restore the old link. Let the error propagate upward and - leave the cache short one link. */ - Py_DECREF(popresult); - Py_DECREF(link); - Py_DECREF(oldkey); - Py_DECREF(oldresult); - return NULL; - } - lru_cache_append_link(self, link); - Py_INCREF(result); /* for return */ - Py_DECREF(popresult); - Py_DECREF(oldkey); - Py_DECREF(oldresult); - return result; -} - -static PyObject * -lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - PyObject *func, *maxsize_O, *cache_info_type, *cachedict; - int typed; - lru_cache_object *obj; - Py_ssize_t maxsize; - PyObject *(*wrapper)(lru_cache_object *, PyObject *, PyObject *); - static char *keywords[] = {"user_function", "maxsize", "typed", - "cache_info_type", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "OOpO:lru_cache", keywords, - &func, &maxsize_O, &typed, - &cache_info_type)) { - return NULL; - } - - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_TypeError, - "the first argument must be callable"); - return NULL; - } - - /* select the caching function, and make/inc maxsize_O */ - if (maxsize_O == Py_None) { - wrapper = infinite_lru_cache_wrapper; - /* use this only to initialize lru_cache_object attribute maxsize */ - maxsize = -1; - } else if (PyIndex_Check(maxsize_O)) { - maxsize = PyNumber_AsSsize_t(maxsize_O, PyExc_OverflowError); - if (maxsize == -1 && PyErr_Occurred()) - return NULL; - if (maxsize < 0) { - maxsize = 0; - } - if (maxsize == 0) - wrapper = uncached_lru_cache_wrapper; - else - wrapper = bounded_lru_cache_wrapper; - } else { - PyErr_SetString(PyExc_TypeError, "maxsize should be integer or None"); - return NULL; - } - - if (!(cachedict = PyDict_New())) - return NULL; - - obj = (lru_cache_object *)type->tp_alloc(type, 0); - if (obj == NULL) { - Py_DECREF(cachedict); - return NULL; - } - - obj->root.prev = &obj->root; - obj->root.next = &obj->root; - obj->wrapper = wrapper; - obj->typed = typed; - obj->cache = cachedict; - Py_INCREF(func); - obj->func = func; - obj->misses = obj->hits = 0; - obj->maxsize = maxsize; - Py_INCREF(cache_info_type); - obj->cache_info_type = cache_info_type; + if (PyTuple_GET_SIZE(args) == 1) { + key = PyTuple_GET_ITEM(args, 0); + if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) { + /* For common scalar keys, save space by + dropping the enclosing args tuple */ + Py_INCREF(key); + return key; + } + } + Py_INCREF(args); + return args; + } + + key_size = PyTuple_GET_SIZE(args); + if (kwds_size) + key_size += kwds_size * 2 + 1; + if (typed) + key_size += PyTuple_GET_SIZE(args) + kwds_size; + + key = PyTuple_New(key_size); + if (key == NULL) + return NULL; + + key_pos = 0; + for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { + PyObject *item = PyTuple_GET_ITEM(args, pos); + Py_INCREF(item); + PyTuple_SET_ITEM(key, key_pos++, item); + } + if (kwds_size) { + Py_INCREF(kwd_mark); + PyTuple_SET_ITEM(key, key_pos++, kwd_mark); + for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { + Py_INCREF(keyword); + PyTuple_SET_ITEM(key, key_pos++, keyword); + Py_INCREF(value); + PyTuple_SET_ITEM(key, key_pos++, value); + } + assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1); + } + if (typed) { + for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { + PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos)); + Py_INCREF(item); + PyTuple_SET_ITEM(key, key_pos++, item); + } + if (kwds_size) { + for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { + PyObject *item = (PyObject *)Py_TYPE(value); + Py_INCREF(item); + PyTuple_SET_ITEM(key, key_pos++, item); + } + } + } + assert(key_pos == key_size); + return key; +} + +static PyObject * +uncached_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds) +{ + PyObject *result; + + self->misses++; + result = PyObject_Call(self->func, args, kwds); + if (!result) + return NULL; + return result; +} + +static PyObject * +infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds) +{ + PyObject *result; + Py_hash_t hash; + PyObject *key = lru_cache_make_key(args, kwds, self->typed); + if (!key) + return NULL; + hash = PyObject_Hash(key); + if (hash == -1) { + Py_DECREF(key); + return NULL; + } + result = _PyDict_GetItem_KnownHash(self->cache, key, hash); + if (result) { + Py_INCREF(result); + self->hits++; + Py_DECREF(key); + return result; + } + if (PyErr_Occurred()) { + Py_DECREF(key); + return NULL; + } + self->misses++; + result = PyObject_Call(self->func, args, kwds); + if (!result) { + Py_DECREF(key); + return NULL; + } + if (_PyDict_SetItem_KnownHash(self->cache, key, result, hash) < 0) { + Py_DECREF(result); + Py_DECREF(key); + return NULL; + } + Py_DECREF(key); + return result; +} + +static void +lru_cache_extract_link(lru_list_elem *link) +{ + lru_list_elem *link_prev = link->prev; + lru_list_elem *link_next = link->next; + link_prev->next = link->next; + link_next->prev = link->prev; +} + +static void +lru_cache_append_link(lru_cache_object *self, lru_list_elem *link) +{ + lru_list_elem *root = &self->root; + lru_list_elem *last = root->prev; + last->next = root->prev = link; + link->prev = last; + link->next = root; +} + +static void +lru_cache_prepend_link(lru_cache_object *self, lru_list_elem *link) +{ + lru_list_elem *root = &self->root; + lru_list_elem *first = root->next; + first->prev = root->next = link; + link->prev = root; + link->next = first; +} + +/* General note on reentrancy: + + There are four dictionary calls in the bounded_lru_cache_wrapper(): + 1) The initial check for a cache match. 2) The post user-function + check for a cache match. 3) The deletion of the oldest entry. + 4) The addition of the newest entry. + + In all four calls, we have a known hash which lets use avoid a call + to __hash__(). That leaves only __eq__ as a possible source of a + reentrant call. + + The __eq__ method call is always made for a cache hit (dict access #1). + Accordingly, we have make sure not modify the cache state prior to + this call. + + The __eq__ method call is never made for the deletion (dict access #3) + because it is an identity match. + + For the other two accesses (#2 and #4), calls to __eq__ only occur + when some other entry happens to have an exactly matching hash (all + 64-bits). Though rare, this can happen, so we have to make sure to + either call it at the top of its code path before any cache + state modifications (dict access #2) or be prepared to restore + invariants at the end of the code path (dict access #4). + + Another possible source of reentrancy is a decref which can trigger + arbitrary code execution. To make the code easier to reason about, + the decrefs are deferred to the end of the each possible code path + so that we know the cache is a consistent state. + */ + +static PyObject * +bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds) +{ + lru_list_elem *link; + PyObject *key, *result, *testresult; + Py_hash_t hash; + + key = lru_cache_make_key(args, kwds, self->typed); + if (!key) + return NULL; + hash = PyObject_Hash(key); + if (hash == -1) { + Py_DECREF(key); + return NULL; + } + link = (lru_list_elem *)_PyDict_GetItem_KnownHash(self->cache, key, hash); + if (link != NULL) { + lru_cache_extract_link(link); + lru_cache_append_link(self, link); + result = link->result; + self->hits++; + Py_INCREF(result); + Py_DECREF(key); + return result; + } + if (PyErr_Occurred()) { + Py_DECREF(key); + return NULL; + } + self->misses++; + result = PyObject_Call(self->func, args, kwds); + if (!result) { + Py_DECREF(key); + return NULL; + } + testresult = _PyDict_GetItem_KnownHash(self->cache, key, hash); + if (testresult != NULL) { + /* Getting here means that this same key was added to the cache + during the PyObject_Call(). Since the link update is already + done, we need only return the computed result. */ + Py_DECREF(key); + return result; + } + if (PyErr_Occurred()) { + /* This is an unusual case since this same lookup + did not previously trigger an error during lookup. + Treat it the same as an error in user function + and return with the error set. */ + Py_DECREF(key); + Py_DECREF(result); + return NULL; + } + /* This is the normal case. The new key wasn't found before + user function call and it is still not there. So we + proceed normally and update the cache with the new result. */ + + assert(self->maxsize > 0); + if (PyDict_GET_SIZE(self->cache) < self->maxsize || + self->root.next == &self->root) + { + /* Cache is not full, so put the result in a new link */ + link = (lru_list_elem *)PyObject_New(lru_list_elem, + &lru_list_elem_type); + if (link == NULL) { + Py_DECREF(key); + Py_DECREF(result); + return NULL; + } + + link->hash = hash; + link->key = key; + link->result = result; + /* What is really needed here is a SetItem variant with a "no clobber" + option. If the __eq__ call triggers a reentrant call that adds + this same key, then this setitem call will update the cache dict + with this new link, leaving the old link as an orphan (i.e. not + having a cache dict entry that refers to it). */ + if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, + hash) < 0) { + Py_DECREF(link); + return NULL; + } + lru_cache_append_link(self, link); + Py_INCREF(result); /* for return */ + return result; + } + /* Since the cache is full, we need to evict an old key and add + a new key. Rather than free the old link and allocate a new + one, we reuse the link for the new key and result and move it + to front of the cache to mark it as recently used. + + We try to assure all code paths (including errors) leave all + of the links in place. Either the link is successfully + updated and moved or it is restored to its old position. + However if an unrecoverable error is found, it doesn't + make sense to reinsert the link, so we leave it out + and the cache will no longer register as full. + */ + PyObject *oldkey, *oldresult, *popresult; + + /* Extract the oldest item. */ + assert(self->root.next != &self->root); + link = self->root.next; + lru_cache_extract_link(link); + /* Remove it from the cache. + The cache dict holds one reference to the link. + We created one other reference when the link was created. + The linked list only has borrowed references. */ + popresult = _PyDict_Pop_KnownHash(self->cache, link->key, + link->hash, Py_None); + if (popresult == Py_None) { + /* Getting here means that the user function call or another + thread has already removed the old key from the dictionary. + This link is now an orphan. Since we don't want to leave the + cache in an inconsistent state, we don't restore the link. */ + Py_DECREF(popresult); + Py_DECREF(link); + Py_DECREF(key); + return result; + } + if (popresult == NULL) { + /* An error arose while trying to remove the oldest key (the one + being evicted) from the cache. We restore the link to its + original position as the oldest link. Then we allow the + error propagate upward; treating it the same as an error + arising in the user function. */ + lru_cache_prepend_link(self, link); + Py_DECREF(key); + Py_DECREF(result); + return NULL; + } + /* Keep a reference to the old key and old result to prevent their + ref counts from going to zero during the update. That will + prevent potentially arbitrary object clean-up code (i.e. __del__) + from running while we're still adjusting the links. */ + oldkey = link->key; + oldresult = link->result; + + link->hash = hash; + link->key = key; + link->result = result; + /* Note: The link is being added to the cache dict without the + prev and next fields set to valid values. We have to wait + for successful insertion in the cache dict before adding the + link to the linked list. Otherwise, the potentially reentrant + __eq__ call could cause the then orphan link to be visited. */ + if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, + hash) < 0) { + /* Somehow the cache dict update failed. We no longer can + restore the old link. Let the error propagate upward and + leave the cache short one link. */ + Py_DECREF(popresult); + Py_DECREF(link); + Py_DECREF(oldkey); + Py_DECREF(oldresult); + return NULL; + } + lru_cache_append_link(self, link); + Py_INCREF(result); /* for return */ + Py_DECREF(popresult); + Py_DECREF(oldkey); + Py_DECREF(oldresult); + return result; +} + +static PyObject * +lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *func, *maxsize_O, *cache_info_type, *cachedict; + int typed; + lru_cache_object *obj; + Py_ssize_t maxsize; + PyObject *(*wrapper)(lru_cache_object *, PyObject *, PyObject *); + static char *keywords[] = {"user_function", "maxsize", "typed", + "cache_info_type", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "OOpO:lru_cache", keywords, + &func, &maxsize_O, &typed, + &cache_info_type)) { + return NULL; + } + + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "the first argument must be callable"); + return NULL; + } + + /* select the caching function, and make/inc maxsize_O */ + if (maxsize_O == Py_None) { + wrapper = infinite_lru_cache_wrapper; + /* use this only to initialize lru_cache_object attribute maxsize */ + maxsize = -1; + } else if (PyIndex_Check(maxsize_O)) { + maxsize = PyNumber_AsSsize_t(maxsize_O, PyExc_OverflowError); + if (maxsize == -1 && PyErr_Occurred()) + return NULL; + if (maxsize < 0) { + maxsize = 0; + } + if (maxsize == 0) + wrapper = uncached_lru_cache_wrapper; + else + wrapper = bounded_lru_cache_wrapper; + } else { + PyErr_SetString(PyExc_TypeError, "maxsize should be integer or None"); + return NULL; + } + + if (!(cachedict = PyDict_New())) + return NULL; + + obj = (lru_cache_object *)type->tp_alloc(type, 0); + if (obj == NULL) { + Py_DECREF(cachedict); + return NULL; + } + + obj->root.prev = &obj->root; + obj->root.next = &obj->root; + obj->wrapper = wrapper; + obj->typed = typed; + obj->cache = cachedict; + Py_INCREF(func); + obj->func = func; + obj->misses = obj->hits = 0; + obj->maxsize = maxsize; + Py_INCREF(cache_info_type); + obj->cache_info_type = cache_info_type; obj->dict = NULL; obj->weakreflist = NULL; - return (PyObject *)obj; -} - -static lru_list_elem * -lru_cache_unlink_list(lru_cache_object *self) -{ - lru_list_elem *root = &self->root; - lru_list_elem *link = root->next; - if (link == root) - return NULL; - root->prev->next = NULL; - root->next = root->prev = root; - return link; -} - -static void -lru_cache_clear_list(lru_list_elem *link) -{ - while (link != NULL) { - lru_list_elem *next = link->next; - Py_DECREF(link); - link = next; - } -} - -static void -lru_cache_dealloc(lru_cache_object *obj) -{ - lru_list_elem *list; - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(obj); + return (PyObject *)obj; +} + +static lru_list_elem * +lru_cache_unlink_list(lru_cache_object *self) +{ + lru_list_elem *root = &self->root; + lru_list_elem *link = root->next; + if (link == root) + return NULL; + root->prev->next = NULL; + root->next = root->prev = root; + return link; +} + +static void +lru_cache_clear_list(lru_list_elem *link) +{ + while (link != NULL) { + lru_list_elem *next = link->next; + Py_DECREF(link); + link = next; + } +} + +static void +lru_cache_dealloc(lru_cache_object *obj) +{ + lru_list_elem *list; + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(obj); if (obj->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject*)obj); - - list = lru_cache_unlink_list(obj); - Py_XDECREF(obj->cache); - Py_XDECREF(obj->func); - Py_XDECREF(obj->cache_info_type); - Py_XDECREF(obj->dict); - lru_cache_clear_list(list); - Py_TYPE(obj)->tp_free(obj); -} - -static PyObject * -lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds) -{ - return self->wrapper(self, args, kwds); -} - -static PyObject * -lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type) -{ - if (obj == Py_None || obj == NULL) { - Py_INCREF(self); - return self; - } - return PyMethod_New(self, obj); -} - -static PyObject * -lru_cache_cache_info(lru_cache_object *self, PyObject *unused) -{ - if (self->maxsize == -1) { - return PyObject_CallFunction(self->cache_info_type, "nnOn", - self->hits, self->misses, Py_None, - PyDict_GET_SIZE(self->cache)); - } - return PyObject_CallFunction(self->cache_info_type, "nnnn", - self->hits, self->misses, self->maxsize, - PyDict_GET_SIZE(self->cache)); -} - -static PyObject * -lru_cache_cache_clear(lru_cache_object *self, PyObject *unused) -{ - lru_list_elem *list = lru_cache_unlink_list(self); - self->hits = self->misses = 0; - PyDict_Clear(self->cache); - lru_cache_clear_list(list); - Py_RETURN_NONE; -} - -static PyObject * -lru_cache_reduce(PyObject *self, PyObject *unused) -{ - return PyObject_GetAttrString(self, "__qualname__"); -} - -static PyObject * -lru_cache_copy(PyObject *self, PyObject *unused) -{ - Py_INCREF(self); - return self; -} - -static PyObject * -lru_cache_deepcopy(PyObject *self, PyObject *unused) -{ - Py_INCREF(self); - return self; -} - -static int -lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg) -{ - lru_list_elem *link = self->root.next; - while (link != &self->root) { - lru_list_elem *next = link->next; - Py_VISIT(link->key); - Py_VISIT(link->result); - link = next; - } - Py_VISIT(self->func); - Py_VISIT(self->cache); - Py_VISIT(self->cache_info_type); - Py_VISIT(self->dict); - return 0; -} - -static int -lru_cache_tp_clear(lru_cache_object *self) -{ - lru_list_elem *list = lru_cache_unlink_list(self); - Py_CLEAR(self->func); - Py_CLEAR(self->cache); - Py_CLEAR(self->cache_info_type); - Py_CLEAR(self->dict); - lru_cache_clear_list(list); - return 0; -} - - -PyDoc_STRVAR(lru_cache_doc, -"Create a cached callable that wraps another function.\n\ -\n\ -user_function: the function being cached\n\ -\n\ -maxsize: 0 for no caching\n\ - None for unlimited cache size\n\ - n for a bounded cache\n\ -\n\ -typed: False cache f(3) and f(3.0) as identical calls\n\ - True cache f(3) and f(3.0) as distinct calls\n\ -\n\ -cache_info_type: namedtuple class with the fields:\n\ - hits misses currsize maxsize\n" -); - -static PyMethodDef lru_cache_methods[] = { - {"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS}, - {"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS}, - {"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS}, - {"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS}, - {"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS}, - {NULL} -}; - -static PyGetSetDef lru_cache_getsetlist[] = { - {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, - {NULL} -}; - -static PyTypeObject lru_cache_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "functools._lru_cache_wrapper", /* tp_name */ - sizeof(lru_cache_object), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)lru_cache_dealloc, /* tp_dealloc */ + + list = lru_cache_unlink_list(obj); + Py_XDECREF(obj->cache); + Py_XDECREF(obj->func); + Py_XDECREF(obj->cache_info_type); + Py_XDECREF(obj->dict); + lru_cache_clear_list(list); + Py_TYPE(obj)->tp_free(obj); +} + +static PyObject * +lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds) +{ + return self->wrapper(self, args, kwds); +} + +static PyObject * +lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type) +{ + if (obj == Py_None || obj == NULL) { + Py_INCREF(self); + return self; + } + return PyMethod_New(self, obj); +} + +static PyObject * +lru_cache_cache_info(lru_cache_object *self, PyObject *unused) +{ + if (self->maxsize == -1) { + return PyObject_CallFunction(self->cache_info_type, "nnOn", + self->hits, self->misses, Py_None, + PyDict_GET_SIZE(self->cache)); + } + return PyObject_CallFunction(self->cache_info_type, "nnnn", + self->hits, self->misses, self->maxsize, + PyDict_GET_SIZE(self->cache)); +} + +static PyObject * +lru_cache_cache_clear(lru_cache_object *self, PyObject *unused) +{ + lru_list_elem *list = lru_cache_unlink_list(self); + self->hits = self->misses = 0; + PyDict_Clear(self->cache); + lru_cache_clear_list(list); + Py_RETURN_NONE; +} + +static PyObject * +lru_cache_reduce(PyObject *self, PyObject *unused) +{ + return PyObject_GetAttrString(self, "__qualname__"); +} + +static PyObject * +lru_cache_copy(PyObject *self, PyObject *unused) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +lru_cache_deepcopy(PyObject *self, PyObject *unused) +{ + Py_INCREF(self); + return self; +} + +static int +lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg) +{ + lru_list_elem *link = self->root.next; + while (link != &self->root) { + lru_list_elem *next = link->next; + Py_VISIT(link->key); + Py_VISIT(link->result); + link = next; + } + Py_VISIT(self->func); + Py_VISIT(self->cache); + Py_VISIT(self->cache_info_type); + Py_VISIT(self->dict); + return 0; +} + +static int +lru_cache_tp_clear(lru_cache_object *self) +{ + lru_list_elem *list = lru_cache_unlink_list(self); + Py_CLEAR(self->func); + Py_CLEAR(self->cache); + Py_CLEAR(self->cache_info_type); + Py_CLEAR(self->dict); + lru_cache_clear_list(list); + return 0; +} + + +PyDoc_STRVAR(lru_cache_doc, +"Create a cached callable that wraps another function.\n\ +\n\ +user_function: the function being cached\n\ +\n\ +maxsize: 0 for no caching\n\ + None for unlimited cache size\n\ + n for a bounded cache\n\ +\n\ +typed: False cache f(3) and f(3.0) as identical calls\n\ + True cache f(3) and f(3.0) as distinct calls\n\ +\n\ +cache_info_type: namedtuple class with the fields:\n\ + hits misses currsize maxsize\n" +); + +static PyMethodDef lru_cache_methods[] = { + {"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS}, + {"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS}, + {"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS}, + {"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS}, + {"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS}, + {NULL} +}; + +static PyGetSetDef lru_cache_getsetlist[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} +}; + +static PyTypeObject lru_cache_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "functools._lru_cache_wrapper", /* tp_name */ + sizeof(lru_cache_object), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)lru_cache_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)lru_cache_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)lru_cache_call, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_METHOD_DESCRIPTOR, - /* tp_flags */ - lru_cache_doc, /* tp_doc */ - (traverseproc)lru_cache_tp_traverse,/* tp_traverse */ - (inquiry)lru_cache_tp_clear, /* tp_clear */ - 0, /* tp_richcompare */ + /* tp_flags */ + lru_cache_doc, /* tp_doc */ + (traverseproc)lru_cache_tp_traverse,/* tp_traverse */ + (inquiry)lru_cache_tp_clear, /* tp_clear */ + 0, /* tp_richcompare */ offsetof(lru_cache_object, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - lru_cache_methods, /* tp_methods */ - 0, /* tp_members */ - lru_cache_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - lru_cache_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(lru_cache_object, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - lru_cache_new, /* tp_new */ -}; - -/* module level code ********************************************************/ - + 0, /* tp_iter */ + 0, /* tp_iternext */ + lru_cache_methods, /* tp_methods */ + 0, /* tp_members */ + lru_cache_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + lru_cache_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(lru_cache_object, dict), /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + lru_cache_new, /* tp_new */ +}; + +/* module level code ********************************************************/ + PyDoc_STRVAR(_functools_doc, -"Tools that operate on functions."); - +"Tools that operate on functions."); + static PyMethodDef _functools_methods[] = { - {"reduce", functools_reduce, METH_VARARGS, functools_reduce_doc}, + {"reduce", functools_reduce, METH_VARARGS, functools_reduce_doc}, {"cmp_to_key", (PyCFunction)(void(*)(void))functools_cmp_to_key, - METH_VARARGS | METH_KEYWORDS, functools_cmp_to_key_doc}, - {NULL, NULL} /* sentinel */ -}; - -static void + METH_VARARGS | METH_KEYWORDS, functools_cmp_to_key_doc}, + {NULL, NULL} /* sentinel */ +}; + +static void _functools_free(void *m) -{ +{ // FIXME: Do not clear kwd_mark to avoid NULL pointer dereferencing if we have // other modules instances that could use it. Will fix when PEP-573 land // and we could move kwd_mark to a per-module state. // Py_CLEAR(kwd_mark); -} - +} + static int _functools_exec(PyObject *module) -{ - PyTypeObject *typelist[] = { - &partial_type, +{ + PyTypeObject *typelist[] = { + &partial_type, &lru_cache_type - }; - - if (!kwd_mark) { + }; + + if (!kwd_mark) { kwd_mark = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); if (!kwd_mark) { return -1; } - } - + } + for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { if (PyModule_AddType(module, typelist[i]) < 0) { return -1; - } - } + } + } return 0; -} +} static struct PyModuleDef_Slot _functools_slots[] = { {Py_mod_exec, _functools_exec}, diff --git a/contrib/tools/python3/src/Modules/_hashopenssl.c b/contrib/tools/python3/src/Modules/_hashopenssl.c index a4889450821..32a86a00be4 100644 --- a/contrib/tools/python3/src/Modules/_hashopenssl.c +++ b/contrib/tools/python3/src/Modules/_hashopenssl.c @@ -1,16 +1,16 @@ -/* Module that wraps all OpenSSL hash algorithms */ - -/* - * Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org) - * Licensed to PSF under a Contributor Agreement. - * - * Derived from a skeleton of shamodule.c containing work performed by: - * - * Andrew Kuchling (amk@amk.ca) - * Greg Stein (gstein@lyra.org) - * - */ - +/* Module that wraps all OpenSSL hash algorithms */ + +/* + * Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org) + * Licensed to PSF under a Contributor Agreement. + * + * Derived from a skeleton of shamodule.c containing work performed by: + * + * Andrew Kuchling (amk@amk.ca) + * Greg Stein (gstein@lyra.org) + * + */ + /* Don't warn about deprecated functions, */ #ifndef OPENSSL_API_COMPAT // 0x10101000L == 1.1.1, 30000 == 3.0.0 @@ -22,31 +22,31 @@ # define Py_BUILD_CORE_MODULE 1 #endif -#define PY_SSIZE_T_CLEAN - -#include "Python.h" +#define PY_SSIZE_T_CLEAN + +#include "Python.h" #include "pycore_hashtable.h" -#include "hashlib.h" -#include "pystrhex.h" - -/* EVP is the preferred interface to hashing in OpenSSL */ -#include -#include +#include "hashlib.h" +#include "pystrhex.h" + +/* EVP is the preferred interface to hashing in OpenSSL */ +#include +#include #include -/* We use the object interface to discover what hashes OpenSSL supports. */ -#include +/* We use the object interface to discover what hashes OpenSSL supports. */ +#include #include - + #include // FIPS_mode() #ifndef OPENSSL_THREADS # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" -#endif - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) -/* OpenSSL < 1.1.0 */ -#define EVP_MD_CTX_new EVP_MD_CTX_create -#define EVP_MD_CTX_free EVP_MD_CTX_destroy +#endif + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +/* OpenSSL < 1.1.0 */ +#define EVP_MD_CTX_new EVP_MD_CTX_create +#define EVP_MD_CTX_free EVP_MD_CTX_destroy HMAC_CTX * HMAC_CTX_new(void) @@ -73,10 +73,10 @@ HMAC_CTX_get_md(const HMAC_CTX *ctx) { return ctx->md; } -#endif - +#endif + #define MUNCH_SIZE INT_MAX - + #ifdef NID_sha3_224 #define PY_OPENSSL_HAS_SHA3 1 #endif @@ -253,7 +253,7 @@ py_hashentry_table_new(void) { /* Module state */ static PyModuleDef _hashlibmodule; -typedef struct { +typedef struct { PyTypeObject *EVPtype; PyTypeObject *HMACtype; #ifdef PY_OPENSSL_HAS_SHAKE @@ -271,17 +271,17 @@ get_hashlib_state(PyObject *module) } typedef struct { - PyObject_HEAD - EVP_MD_CTX *ctx; /* OpenSSL message digest context */ - PyThread_type_lock lock; /* OpenSSL context lock */ -} EVPobject; - + PyObject_HEAD + EVP_MD_CTX *ctx; /* OpenSSL message digest context */ + PyThread_type_lock lock; /* OpenSSL context lock */ +} EVPobject; + typedef struct { PyObject_HEAD HMAC_CTX *ctx; /* OpenSSL hmac context */ PyThread_type_lock lock; /* HMAC context lock */ } HMACobject; - + #include "clinic/_hashopenssl.c.h" /*[clinic input] module _hashlib @@ -290,49 +290,49 @@ class _hashlib.HASHXOF "EVPobject *" "((_hashlibstate *)PyModule_GetState(module class _hashlib.HMAC "HMACobject *" "((_hashlibstate *)PyModule_GetState(module))->HMACtype" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=7df1bcf6f75cb8ef]*/ - - -/* LCOV_EXCL_START */ -static PyObject * + + +/* LCOV_EXCL_START */ +static PyObject * _setException(PyObject *exc, const char* altmsg, ...) -{ +{ unsigned long errcode = ERR_peek_last_error(); - const char *lib, *func, *reason; + const char *lib, *func, *reason; va_list vargs; - + #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, altmsg); #else va_start(vargs); #endif - if (!errcode) { + if (!errcode) { if (altmsg == NULL) { PyErr_SetString(exc, "no reason supplied"); } else { PyErr_FormatV(exc, altmsg, vargs); } - return NULL; - } + return NULL; + } va_end(vargs); - ERR_clear_error(); - - lib = ERR_lib_error_string(errcode); - func = ERR_func_error_string(errcode); - reason = ERR_reason_error_string(errcode); - - if (lib && func) { - PyErr_Format(exc, "[%s: %s] %s", lib, func, reason); - } - else if (lib) { - PyErr_Format(exc, "[%s] %s", lib, reason); - } - else { - PyErr_SetString(exc, reason); - } - return NULL; -} -/* LCOV_EXCL_STOP */ - + ERR_clear_error(); + + lib = ERR_lib_error_string(errcode); + func = ERR_func_error_string(errcode); + reason = ERR_reason_error_string(errcode); + + if (lib && func) { + PyErr_Format(exc, "[%s: %s] %s", lib, func, reason); + } + else if (lib) { + PyErr_Format(exc, "[%s] %s", lib, reason); + } + else { + PyErr_SetString(exc, reason); + } + return NULL; +} +/* LCOV_EXCL_STOP */ + /* {Py_tp_new, NULL} doesn't block __new__ */ static PyObject * _disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) @@ -419,265 +419,265 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) return digest; } -static EVPobject * +static EVPobject * newEVPobject(PyTypeObject *type) -{ +{ EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, type); - if (retval == NULL) { - return NULL; - } - - retval->lock = NULL; - - retval->ctx = EVP_MD_CTX_new(); - if (retval->ctx == NULL) { - Py_DECREF(retval); - PyErr_NoMemory(); - return NULL; - } - - return retval; -} - + if (retval == NULL) { + return NULL; + } + + retval->lock = NULL; + + retval->ctx = EVP_MD_CTX_new(); + if (retval->ctx == NULL) { + Py_DECREF(retval); + PyErr_NoMemory(); + return NULL; + } + + return retval; +} + static int -EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) -{ - unsigned int process; - const unsigned char *cp = (const unsigned char *)vp; - while (0 < len) { - if (len > (Py_ssize_t)MUNCH_SIZE) - process = MUNCH_SIZE; - else - process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); - if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) { +EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) +{ + unsigned int process; + const unsigned char *cp = (const unsigned char *)vp; + while (0 < len) { + if (len > (Py_ssize_t)MUNCH_SIZE) + process = MUNCH_SIZE; + else + process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); + if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) { _setException(PyExc_ValueError, NULL); return -1; - } - len -= process; - cp += process; - } + } + len -= process; + cp += process; + } return 0; -} - -/* Internal methods for a hash object */ - -static void -EVP_dealloc(EVPobject *self) -{ +} + +/* Internal methods for a hash object */ + +static void +EVP_dealloc(EVPobject *self) +{ PyTypeObject *tp = Py_TYPE(self); - if (self->lock != NULL) - PyThread_free_lock(self->lock); - EVP_MD_CTX_free(self->ctx); - PyObject_Del(self); + if (self->lock != NULL) + PyThread_free_lock(self->lock); + EVP_MD_CTX_free(self->ctx); + PyObject_Del(self); Py_DECREF(tp); -} - -static int -locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) -{ - int result; - ENTER_HASHLIB(self); - result = EVP_MD_CTX_copy(new_ctx_p, self->ctx); - LEAVE_HASHLIB(self); - return result; -} - -/* External methods for a hash object */ - +} + +static int +locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) +{ + int result; + ENTER_HASHLIB(self); + result = EVP_MD_CTX_copy(new_ctx_p, self->ctx); + LEAVE_HASHLIB(self); + return result; +} + +/* External methods for a hash object */ + /*[clinic input] _hashlib.HASH.copy as EVP_copy - + Return a copy of the hash object. [clinic start generated code]*/ - -static PyObject * + +static PyObject * EVP_copy_impl(EVPobject *self) /*[clinic end generated code: output=b370c21cdb8ca0b4 input=31455b6a3e638069]*/ -{ - EVPobject *newobj; - +{ + EVPobject *newobj; + if ((newobj = newEVPobject(Py_TYPE(self))) == NULL) - return NULL; - - if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) { - Py_DECREF(newobj); + return NULL; + + if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) { + Py_DECREF(newobj); return _setException(PyExc_ValueError, NULL); - } - return (PyObject *)newobj; -} - + } + return (PyObject *)newobj; +} + /*[clinic input] _hashlib.HASH.digest as EVP_digest - + Return the digest value as a bytes object. [clinic start generated code]*/ -static PyObject * +static PyObject * EVP_digest_impl(EVPobject *self) /*[clinic end generated code: output=0f6a3a0da46dc12d input=03561809a419bf00]*/ -{ - unsigned char digest[EVP_MAX_MD_SIZE]; - EVP_MD_CTX *temp_ctx; - PyObject *retval; - unsigned int digest_size; - - temp_ctx = EVP_MD_CTX_new(); - if (temp_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { +{ + unsigned char digest[EVP_MAX_MD_SIZE]; + EVP_MD_CTX *temp_ctx; + PyObject *retval; + unsigned int digest_size; + + temp_ctx = EVP_MD_CTX_new(); + if (temp_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { return _setException(PyExc_ValueError, NULL); - } - digest_size = EVP_MD_CTX_size(temp_ctx); - if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { + } + digest_size = EVP_MD_CTX_size(temp_ctx); + if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { _setException(PyExc_ValueError, NULL); - return NULL; - } - - retval = PyBytes_FromStringAndSize((const char *)digest, digest_size); - EVP_MD_CTX_free(temp_ctx); - return retval; -} - + return NULL; + } + + retval = PyBytes_FromStringAndSize((const char *)digest, digest_size); + EVP_MD_CTX_free(temp_ctx); + return retval; +} + /*[clinic input] _hashlib.HASH.hexdigest as EVP_hexdigest - + Return the digest value as a string of hexadecimal digits. [clinic start generated code]*/ -static PyObject * +static PyObject * EVP_hexdigest_impl(EVPobject *self) /*[clinic end generated code: output=18e6decbaf197296 input=aff9cf0e4c741a9a]*/ -{ - unsigned char digest[EVP_MAX_MD_SIZE]; - EVP_MD_CTX *temp_ctx; - unsigned int digest_size; - - temp_ctx = EVP_MD_CTX_new(); - if (temp_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - /* Get the raw (binary) digest value */ - if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { +{ + unsigned char digest[EVP_MAX_MD_SIZE]; + EVP_MD_CTX *temp_ctx; + unsigned int digest_size; + + temp_ctx = EVP_MD_CTX_new(); + if (temp_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + /* Get the raw (binary) digest value */ + if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { return _setException(PyExc_ValueError, NULL); - } - digest_size = EVP_MD_CTX_size(temp_ctx); - if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { + } + digest_size = EVP_MD_CTX_size(temp_ctx); + if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { _setException(PyExc_ValueError, NULL); - return NULL; - } - - EVP_MD_CTX_free(temp_ctx); - + return NULL; + } + + EVP_MD_CTX_free(temp_ctx); + return _Py_strhex((const char *)digest, (Py_ssize_t)digest_size); -} - +} + /*[clinic input] _hashlib.HASH.update as EVP_update - + obj: object / Update this hash object's state with the provided string. [clinic start generated code]*/ -static PyObject * +static PyObject * EVP_update(EVPobject *self, PyObject *obj) /*[clinic end generated code: output=ec1d55ed2432e966 input=9b30ec848f015501]*/ -{ +{ int result; - Py_buffer view; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &view); - - if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); - /* fail? lock = NULL and we fail over to non-threaded code. */ - } - - if (self->lock != NULL) { - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + Py_buffer view; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &view); + + if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) { + self->lock = PyThread_allocate_lock(); + /* fail? lock = NULL and we fail over to non-threaded code. */ + } + + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); result = EVP_hash(self, view.buf, view.len); - PyThread_release_lock(self->lock); - Py_END_ALLOW_THREADS - } else { + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { result = EVP_hash(self, view.buf, view.len); - } - - PyBuffer_Release(&view); + } + + PyBuffer_Release(&view); if (result == -1) return NULL; - Py_RETURN_NONE; -} - -static PyMethodDef EVP_methods[] = { + Py_RETURN_NONE; +} + +static PyMethodDef EVP_methods[] = { EVP_UPDATE_METHODDEF EVP_DIGEST_METHODDEF EVP_HEXDIGEST_METHODDEF EVP_COPY_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -EVP_get_block_size(EVPobject *self, void *closure) -{ - long block_size; - block_size = EVP_MD_CTX_block_size(self->ctx); - return PyLong_FromLong(block_size); -} - -static PyObject * -EVP_get_digest_size(EVPobject *self, void *closure) -{ - long size; - size = EVP_MD_CTX_size(self->ctx); - return PyLong_FromLong(size); -} - + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +EVP_get_block_size(EVPobject *self, void *closure) +{ + long block_size; + block_size = EVP_MD_CTX_block_size(self->ctx); + return PyLong_FromLong(block_size); +} + +static PyObject * +EVP_get_digest_size(EVPobject *self, void *closure) +{ + long size; + size = EVP_MD_CTX_size(self->ctx); + return PyLong_FromLong(size); +} + static PyObject * EVP_get_name(EVPobject *self, void *closure) { return py_digest_name(EVP_MD_CTX_md(self->ctx)); } - -static PyGetSetDef EVP_getseters[] = { - {"digest_size", - (getter)EVP_get_digest_size, NULL, - NULL, - NULL}, - {"block_size", - (getter)EVP_get_block_size, NULL, - NULL, - NULL}, + +static PyGetSetDef EVP_getseters[] = { + {"digest_size", + (getter)EVP_get_digest_size, NULL, + NULL, + NULL}, + {"block_size", + (getter)EVP_get_block_size, NULL, + NULL, + NULL}, {"name", (getter)EVP_get_name, NULL, NULL, PyDoc_STR("algorithm name.")}, - {NULL} /* Sentinel */ -}; - - -static PyObject * -EVP_repr(EVPobject *self) -{ + {NULL} /* Sentinel */ +}; + + +static PyObject * +EVP_repr(EVPobject *self) +{ PyObject *name_obj, *repr; name_obj = py_digest_name(EVP_MD_CTX_md(self->ctx)); if (!name_obj) { return NULL; - } + } repr = PyUnicode_FromFormat("<%U %s object @ %p>", name_obj, Py_TYPE(self)->tp_name, self); Py_DECREF(name_obj); return repr; -} - -PyDoc_STRVAR(hashtype_doc, +} + +PyDoc_STRVAR(hashtype_doc, "HASH(name, string=b\'\')\n" "--\n" "\n" @@ -694,7 +694,7 @@ PyDoc_STRVAR(hashtype_doc, "\n" "name -- the hash algorithm being used by this object\n" "digest_size -- number of bytes in this hashes output"); - + static PyType_Slot EVPtype_slots[] = { {Py_tp_dealloc, EVP_dealloc}, {Py_tp_repr, EVP_repr}, @@ -706,13 +706,13 @@ static PyType_Slot EVPtype_slots[] = { }; static PyType_Spec EVPtype_spec = { - "_hashlib.HASH", /*tp_name*/ - sizeof(EVPobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ + "_hashlib.HASH", /*tp_name*/ + sizeof(EVPobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, EVPtype_slots -}; - +}; + #ifdef PY_OPENSSL_HAS_SHAKE /*[clinic input] @@ -723,10 +723,10 @@ _hashlib.HASHXOF.digest as EVPXOF_digest Return the digest value as a bytes object. [clinic start generated code]*/ -static PyObject * +static PyObject * EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length) /*[clinic end generated code: output=ef9320c23280efad input=816a6537cea3d1db]*/ -{ +{ EVP_MD_CTX *temp_ctx; PyObject *retval = PyBytes_FromStringAndSize(NULL, length); @@ -874,11 +874,11 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, PY_EVP_MD *digest = NULL; PyTypeObject *type; EVPobject *self = NULL; - + if (data_obj != NULL) { GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); - } - + } + digest = py_digest_by_name( module, digestname, usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity ); @@ -899,7 +899,7 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, if (self == NULL) { goto exit; } - + #if defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) && OPENSSL_VERSION_NUMBER < 0x30000000L // In OpenSSL 1.1.1 the non FIPS allowed flag is context specific while // in 3.0.0 it is a different EVP_MD provider. @@ -913,22 +913,22 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, _setException(PyExc_ValueError, NULL); Py_CLEAR(self); goto exit; - } - + } + if (view.buf && view.len) { if (view.len >= HASHLIB_GIL_MINSIZE) { - Py_BEGIN_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS result = EVP_hash(self, view.buf, view.len); - Py_END_ALLOW_THREADS - } else { + Py_END_ALLOW_THREADS + } else { result = EVP_hash(self, view.buf, view.len); - } + } if (result == -1) { Py_CLEAR(self); goto exit; } - } - + } + exit: if (data_obj != NULL) { PyBuffer_Release(&view); @@ -937,15 +937,15 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, PY_EVP_MD_free(digest); } - return (PyObject *)self; -} - - -/* The module-level function: new() */ - + return (PyObject *)self; +} + + +/* The module-level function: new() */ + /*[clinic input] _hashlib.new as EVP_new - + name as name_obj: object string as data_obj: object(c_default="NULL") = b'' * @@ -959,20 +959,20 @@ automatically hashed. The MD5 and SHA1 algorithms are always supported. [clinic start generated code]*/ -static PyObject * +static PyObject * EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=ddd5053f92dffe90 input=c24554d0337be1b0]*/ -{ - char *name; - if (!PyArg_Parse(name_obj, "s", &name)) { - PyErr_SetString(PyExc_TypeError, "name must be a string"); - return NULL; - } +{ + char *name; + if (!PyArg_Parse(name_obj, "s", &name)) { + PyErr_SetString(PyExc_TypeError, "name must be a string"); + return NULL; + } return py_evp_fromname(module, name, data_obj, usedforsecurity); -} - - +} + + /*[clinic input] _hashlib.openssl_md5 @@ -988,11 +988,11 @@ static PyObject * _hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=87b0186440a44f8c input=990e36d5e689b16e]*/ -{ +{ return py_evp_fromname(module, Py_hash_md5, data_obj, usedforsecurity); } - - + + /*[clinic input] _hashlib.openssl_sha1 @@ -1010,12 +1010,12 @@ _hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj, /*[clinic end generated code: output=6813024cf690670d input=948f2f4b6deabc10]*/ { return py_evp_fromname(module, Py_hash_sha1, data_obj, usedforsecurity); -} - - +} + + /*[clinic input] _hashlib.openssl_sha224 - + string as data_obj: object(py_default="b''") = NULL * usedforsecurity: bool = True @@ -1024,11 +1024,11 @@ Returns a sha224 hash object; optionally initialized with a string [clinic start generated code]*/ -static PyObject * +static PyObject * _hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=a2dfe7cc4eb14ebb input=f9272821fadca505]*/ -{ +{ return py_evp_fromname(module, Py_hash_sha224, data_obj, usedforsecurity); } @@ -1233,267 +1233,267 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, PyObject *key_obj = NULL; char *key; long dklen; - int retval; - + int retval; + PY_EVP_MD *digest = py_digest_by_name(module, hash_name, Py_ht_pbkdf2); - if (digest == NULL) { - PyErr_SetString(PyExc_ValueError, "unsupported hash type"); - goto end; - } - + if (digest == NULL) { + PyErr_SetString(PyExc_ValueError, "unsupported hash type"); + goto end; + } + if (password->len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "password is too long."); - goto end; - } - + PyErr_SetString(PyExc_OverflowError, + "password is too long."); + goto end; + } + if (salt->len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "salt is too long."); - goto end; - } - - if (iterations < 1) { - PyErr_SetString(PyExc_ValueError, - "iteration value must be greater than 0."); - goto end; - } - if (iterations > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "iteration value is too great."); - goto end; - } - - if (dklen_obj == Py_None) { - dklen = EVP_MD_size(digest); - } else { - dklen = PyLong_AsLong(dklen_obj); - if ((dklen == -1) && PyErr_Occurred()) { - goto end; - } - } - if (dklen < 1) { - PyErr_SetString(PyExc_ValueError, - "key length must be greater than 0."); - goto end; - } - if (dklen > INT_MAX) { - /* INT_MAX is always smaller than dkLen max (2^32 - 1) * hLen */ - PyErr_SetString(PyExc_OverflowError, - "key length is too great."); - goto end; - } - - key_obj = PyBytes_FromStringAndSize(NULL, dklen); - if (key_obj == NULL) { - goto end; - } - key = PyBytes_AS_STRING(key_obj); - - Py_BEGIN_ALLOW_THREADS + PyErr_SetString(PyExc_OverflowError, + "salt is too long."); + goto end; + } + + if (iterations < 1) { + PyErr_SetString(PyExc_ValueError, + "iteration value must be greater than 0."); + goto end; + } + if (iterations > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "iteration value is too great."); + goto end; + } + + if (dklen_obj == Py_None) { + dklen = EVP_MD_size(digest); + } else { + dklen = PyLong_AsLong(dklen_obj); + if ((dklen == -1) && PyErr_Occurred()) { + goto end; + } + } + if (dklen < 1) { + PyErr_SetString(PyExc_ValueError, + "key length must be greater than 0."); + goto end; + } + if (dklen > INT_MAX) { + /* INT_MAX is always smaller than dkLen max (2^32 - 1) * hLen */ + PyErr_SetString(PyExc_OverflowError, + "key length is too great."); + goto end; + } + + key_obj = PyBytes_FromStringAndSize(NULL, dklen); + if (key_obj == NULL) { + goto end; + } + key = PyBytes_AS_STRING(key_obj); + + Py_BEGIN_ALLOW_THREADS retval = PKCS5_PBKDF2_HMAC((char*)password->buf, (int)password->len, (unsigned char *)salt->buf, (int)salt->len, - iterations, digest, dklen, - (unsigned char *)key); - Py_END_ALLOW_THREADS - - if (!retval) { - Py_CLEAR(key_obj); + iterations, digest, dklen, + (unsigned char *)key); + Py_END_ALLOW_THREADS + + if (!retval) { + Py_CLEAR(key_obj); _setException(PyExc_ValueError, NULL); - goto end; - } - - end: + goto end; + } + + end: if (digest != NULL) { PY_EVP_MD_free(digest); } - return key_obj; -} - -#if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER) -#define PY_SCRYPT 1 - -/* XXX: Parameters salt, n, r and p should be required keyword-only parameters. - They are optional in the Argument Clinic declaration only due to a - limitation of PyArg_ParseTupleAndKeywords. */ - -/*[clinic input] -_hashlib.scrypt - - password: Py_buffer - * - salt: Py_buffer = None - n as n_obj: object(subclass_of='&PyLong_Type') = None - r as r_obj: object(subclass_of='&PyLong_Type') = None - p as p_obj: object(subclass_of='&PyLong_Type') = None - maxmem: long = 0 - dklen: long = 64 - - -scrypt password-based key derivation function. -[clinic start generated code]*/ - -static PyObject * -_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, - PyObject *n_obj, PyObject *r_obj, PyObject *p_obj, - long maxmem, long dklen) -/*[clinic end generated code: output=14849e2aa2b7b46c input=48a7d63bf3f75c42]*/ -{ - PyObject *key_obj = NULL; - char *key; - int retval; - unsigned long n, r, p; - - if (password->len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "password is too long."); - return NULL; - } - - if (salt->buf == NULL) { - PyErr_SetString(PyExc_TypeError, - "salt is required"); - return NULL; - } - if (salt->len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "salt is too long."); - return NULL; - } - - n = PyLong_AsUnsignedLong(n_obj); - if (n == (unsigned long) -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "n is required and must be an unsigned int"); - return NULL; - } - if (n < 2 || n & (n - 1)) { - PyErr_SetString(PyExc_ValueError, - "n must be a power of 2."); - return NULL; - } - - r = PyLong_AsUnsignedLong(r_obj); - if (r == (unsigned long) -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "r is required and must be an unsigned int"); - return NULL; - } - - p = PyLong_AsUnsignedLong(p_obj); - if (p == (unsigned long) -1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "p is required and must be an unsigned int"); - return NULL; - } - - if (maxmem < 0 || maxmem > INT_MAX) { - /* OpenSSL 1.1.0 restricts maxmem to 32 MiB. It may change in the - future. The maxmem constant is private to OpenSSL. */ - PyErr_Format(PyExc_ValueError, - "maxmem must be positive and smaller than %d", - INT_MAX); - return NULL; - } - - if (dklen < 1 || dklen > INT_MAX) { - PyErr_Format(PyExc_ValueError, - "dklen must be greater than 0 and smaller than %d", - INT_MAX); - return NULL; - } - - /* let OpenSSL validate the rest */ - retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0); - if (!retval) { + return key_obj; +} + +#if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER) +#define PY_SCRYPT 1 + +/* XXX: Parameters salt, n, r and p should be required keyword-only parameters. + They are optional in the Argument Clinic declaration only due to a + limitation of PyArg_ParseTupleAndKeywords. */ + +/*[clinic input] +_hashlib.scrypt + + password: Py_buffer + * + salt: Py_buffer = None + n as n_obj: object(subclass_of='&PyLong_Type') = None + r as r_obj: object(subclass_of='&PyLong_Type') = None + p as p_obj: object(subclass_of='&PyLong_Type') = None + maxmem: long = 0 + dklen: long = 64 + + +scrypt password-based key derivation function. +[clinic start generated code]*/ + +static PyObject * +_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, + PyObject *n_obj, PyObject *r_obj, PyObject *p_obj, + long maxmem, long dklen) +/*[clinic end generated code: output=14849e2aa2b7b46c input=48a7d63bf3f75c42]*/ +{ + PyObject *key_obj = NULL; + char *key; + int retval; + unsigned long n, r, p; + + if (password->len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "password is too long."); + return NULL; + } + + if (salt->buf == NULL) { + PyErr_SetString(PyExc_TypeError, + "salt is required"); + return NULL; + } + if (salt->len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "salt is too long."); + return NULL; + } + + n = PyLong_AsUnsignedLong(n_obj); + if (n == (unsigned long) -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "n is required and must be an unsigned int"); + return NULL; + } + if (n < 2 || n & (n - 1)) { + PyErr_SetString(PyExc_ValueError, + "n must be a power of 2."); + return NULL; + } + + r = PyLong_AsUnsignedLong(r_obj); + if (r == (unsigned long) -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "r is required and must be an unsigned int"); + return NULL; + } + + p = PyLong_AsUnsignedLong(p_obj); + if (p == (unsigned long) -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "p is required and must be an unsigned int"); + return NULL; + } + + if (maxmem < 0 || maxmem > INT_MAX) { + /* OpenSSL 1.1.0 restricts maxmem to 32 MiB. It may change in the + future. The maxmem constant is private to OpenSSL. */ + PyErr_Format(PyExc_ValueError, + "maxmem must be positive and smaller than %d", + INT_MAX); + return NULL; + } + + if (dklen < 1 || dklen > INT_MAX) { + PyErr_Format(PyExc_ValueError, + "dklen must be greater than 0 and smaller than %d", + INT_MAX); + return NULL; + } + + /* let OpenSSL validate the rest */ + retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0); + if (!retval) { _setException(PyExc_ValueError, "Invalid parameter combination for n, r, p, maxmem."); - return NULL; - } - - key_obj = PyBytes_FromStringAndSize(NULL, dklen); - if (key_obj == NULL) { - return NULL; - } - key = PyBytes_AS_STRING(key_obj); - - Py_BEGIN_ALLOW_THREADS - retval = EVP_PBE_scrypt( - (const char*)password->buf, (size_t)password->len, - (const unsigned char *)salt->buf, (size_t)salt->len, - n, r, p, maxmem, - (unsigned char *)key, (size_t)dklen - ); - Py_END_ALLOW_THREADS - - if (!retval) { - Py_CLEAR(key_obj); + return NULL; + } + + key_obj = PyBytes_FromStringAndSize(NULL, dklen); + if (key_obj == NULL) { + return NULL; + } + key = PyBytes_AS_STRING(key_obj); + + Py_BEGIN_ALLOW_THREADS + retval = EVP_PBE_scrypt( + (const char*)password->buf, (size_t)password->len, + (const unsigned char *)salt->buf, (size_t)salt->len, + n, r, p, maxmem, + (unsigned char *)key, (size_t)dklen + ); + Py_END_ALLOW_THREADS + + if (!retval) { + Py_CLEAR(key_obj); _setException(PyExc_ValueError, NULL); - return NULL; - } - return key_obj; -} -#endif - -/* Fast HMAC for hmac.digest() - */ - -/*[clinic input] + return NULL; + } + return key_obj; +} +#endif + +/* Fast HMAC for hmac.digest() + */ + +/*[clinic input] _hashlib.hmac_digest as _hashlib_hmac_singleshot - - key: Py_buffer - msg: Py_buffer - digest: str - -Single-shot HMAC. -[clinic start generated code]*/ - -static PyObject * + + key: Py_buffer + msg: Py_buffer + digest: str + +Single-shot HMAC. +[clinic start generated code]*/ + +static PyObject * _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, Py_buffer *msg, const char *digest) /*[clinic end generated code: output=15658ede5ab98185 input=019dffc571909a46]*/ -{ - unsigned char md[EVP_MAX_MD_SIZE] = {0}; - unsigned int md_len = 0; - unsigned char *result; +{ + unsigned char md[EVP_MAX_MD_SIZE] = {0}; + unsigned int md_len = 0; + unsigned char *result; PY_EVP_MD *evp; - + evp = py_digest_by_name(module, digest, Py_ht_mac); - if (evp == NULL) { - return NULL; - } - if (key->len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "key is too long."); - return NULL; - } - if (msg->len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "msg is too long."); - return NULL; - } - + if (evp == NULL) { + return NULL; + } + if (key->len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "key is too long."); + return NULL; + } + if (msg->len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "msg is too long."); + return NULL; + } + evp = py_digest_by_name(module, digest, Py_ht_mac); if (evp == NULL) { return NULL; } - Py_BEGIN_ALLOW_THREADS - result = HMAC( - evp, - (const void*)key->buf, (int)key->len, - (const unsigned char*)msg->buf, (int)msg->len, - md, &md_len - ); - Py_END_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + result = HMAC( + evp, + (const void*)key->buf, (int)key->len, + (const unsigned char*)msg->buf, (int)msg->len, + md, &md_len + ); + Py_END_ALLOW_THREADS PY_EVP_MD_free(evp); - - if (result == NULL) { + + if (result == NULL) { _setException(PyExc_ValueError, NULL); - return NULL; - } - return PyBytes_FromStringAndSize((const char*)md, md_len); -} - + return NULL; + } + return PyBytes_FromStringAndSize((const char*)md, md_len); +} + /* OpenSSL-based HMAC implementation */ @@ -1850,41 +1850,41 @@ PyType_Spec HMACtype_spec = { }; -/* State for our callback function so that it can accumulate a result. */ -typedef struct _internal_name_mapper_state { - PyObject *set; - int error; -} _InternalNameMapperState; - - -/* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ -static void +/* State for our callback function so that it can accumulate a result. */ +typedef struct _internal_name_mapper_state { + PyObject *set; + int error; +} _InternalNameMapperState; + + +/* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ +static void _openssl_hash_name_mapper(const EVP_MD *md, const char *from, const char *to, void *arg) -{ - _InternalNameMapperState *state = (_InternalNameMapperState *)arg; - PyObject *py_name; - - assert(state != NULL); +{ + _InternalNameMapperState *state = (_InternalNameMapperState *)arg; + PyObject *py_name; + + assert(state != NULL); if (md == NULL) - return; - + return; + py_name = py_digest_name(md); - if (py_name == NULL) { - state->error = 1; - } else { - if (PySet_Add(state->set, py_name) != 0) { - state->error = 1; - } - Py_DECREF(py_name); - } -} - - -/* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */ + if (py_name == NULL) { + state->error = 1; + } else { + if (PySet_Add(state->set, py_name) != 0) { + state->error = 1; + } + Py_DECREF(py_name); + } +} + + +/* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */ static int hashlib_md_meth_names(PyObject *module) -{ +{ _InternalNameMapperState state = { .set = PyFrozenSet_New(NULL), .error = 0 @@ -1892,13 +1892,13 @@ hashlib_md_meth_names(PyObject *module) if (state.set == NULL) { return -1; } - + EVP_MD_do_all(&_openssl_hash_name_mapper, &state); - - if (state.error) { - Py_DECREF(state.set); + + if (state.error) { + Py_DECREF(state.set); return -1; - } + } if (PyModule_AddObject(module, "openssl_md_meth_names", state.set) < 0) { Py_DECREF(state.set); @@ -1906,8 +1906,8 @@ hashlib_md_meth_names(PyObject *module) } return 0; -} - +} + /* LibreSSL doesn't support FIPS: https://marc.info/?l=openbsd-misc&m=139819485423701&w=2 @@ -2068,12 +2068,12 @@ _hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) return PyBool_FromLong(rc); } -/* List of functions exported by this module */ - -static struct PyMethodDef EVP_functions[] = { +/* List of functions exported by this module */ + +static struct PyMethodDef EVP_functions[] = { EVP_NEW_METHODDEF PBKDF2_HMAC_METHODDEF - _HASHLIB_SCRYPT_METHODDEF + _HASHLIB_SCRYPT_METHODDEF _HASHLIB_GET_FIPS_MODE_METHODDEF _HASHLIB_COMPARE_DIGEST_METHODDEF _HASHLIB_HMAC_SINGLESHOT_METHODDEF @@ -2090,12 +2090,12 @@ static struct PyMethodDef EVP_functions[] = { _HASHLIB_OPENSSL_SHA3_512_METHODDEF _HASHLIB_OPENSSL_SHAKE_128_METHODDEF _HASHLIB_OPENSSL_SHAKE_256_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ - + {NULL, NULL} /* Sentinel */ +}; + + +/* Initialize this module. */ + static int hashlib_traverse(PyObject *m, visitproc visit, void *arg) { @@ -2107,7 +2107,7 @@ hashlib_traverse(PyObject *m, visitproc visit, void *arg) #endif return 0; } - + static int hashlib_clear(PyObject *m) { @@ -2123,25 +2123,25 @@ hashlib_clear(PyObject *m) } return 0; } - + static void hashlib_free(void *m) -{ +{ hashlib_clear((PyObject *)m); } - + /* Py_mod_exec functions */ static int hashlib_openssl_legacy_init(PyObject *module) { #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) - /* Load all digest algorithms and initialize cpuid */ - OPENSSL_add_all_algorithms_noconf(); - ERR_load_crypto_strings(); -#endif + /* Load all digest algorithms and initialize cpuid */ + OPENSSL_add_all_algorithms_noconf(); + ERR_load_crypto_strings(); +#endif return 0; } - + static int hashlib_init_hashtable(PyObject *module) { @@ -2159,7 +2159,7 @@ static int hashlib_init_evptype(PyObject *module) { _hashlibstate *state = get_hashlib_state(module); - + state->EVPtype = (PyTypeObject *)PyType_FromSpec(&EVPtype_spec); if (state->EVPtype == NULL) { return -1; @@ -2169,7 +2169,7 @@ hashlib_init_evptype(PyObject *module) } return 0; } - + static int hashlib_init_evpxoftype(PyObject *module) { @@ -2249,23 +2249,23 @@ PyInit__hashlib(void) return m; } - m = PyModule_Create(&_hashlibmodule); + m = PyModule_Create(&_hashlibmodule); if (m == NULL) { - return NULL; + return NULL; } - + if (hashlib_openssl_legacy_init(m) < 0) { - Py_DECREF(m); - return NULL; - } + Py_DECREF(m); + return NULL; + } if (hashlib_init_hashtable(m) < 0) { Py_DECREF(m); return NULL; } if (hashlib_init_evptype(m) < 0) { - Py_DECREF(m); - return NULL; - } + Py_DECREF(m); + return NULL; + } if (hashlib_init_evpxoftype(m) < 0) { Py_DECREF(m); return NULL; @@ -2278,6 +2278,6 @@ PyInit__hashlib(void) Py_DECREF(m); return NULL; } - - return m; -} + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_heapqmodule.c b/contrib/tools/python3/src/Modules/_heapqmodule.c index 4e85e046d38..5ba0f556b4a 100644 --- a/contrib/tools/python3/src/Modules/_heapqmodule.c +++ b/contrib/tools/python3/src/Modules/_heapqmodule.c @@ -1,13 +1,13 @@ -/* Drop in replacement for heapq.py - -C implementation derived directly from heapq.py in Py2.3 -which was written by Kevin O'Connor, augmented by Tim Peters, -annotated by François Pinard, and converted to C by Raymond Hettinger. - -*/ - -#include "Python.h" - +/* Drop in replacement for heapq.py + +C implementation derived directly from heapq.py in Py2.3 +which was written by Kevin O'Connor, augmented by Tim Peters, +annotated by François Pinard, and converted to C by Raymond Hettinger. + +*/ + +#include "Python.h" + #include "clinic/_heapqmodule.c.h" /*[clinic input] @@ -15,73 +15,73 @@ module _heapq [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=d7cca0a2e4c0ceb3]*/ -static int -siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) -{ - PyObject *newitem, *parent, **arr; - Py_ssize_t parentpos, size; - int cmp; - - assert(PyList_Check(heap)); - size = PyList_GET_SIZE(heap); - if (pos >= size) { - PyErr_SetString(PyExc_IndexError, "index out of range"); - return -1; - } - - /* Follow the path to the root, moving parents down until finding - a place newitem fits. */ - arr = _PyList_ITEMS(heap); - newitem = arr[pos]; - while (pos > startpos) { - parentpos = (pos - 1) >> 1; - parent = arr[parentpos]; +static int +siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) +{ + PyObject *newitem, *parent, **arr; + Py_ssize_t parentpos, size; + int cmp; + + assert(PyList_Check(heap)); + size = PyList_GET_SIZE(heap); + if (pos >= size) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + /* Follow the path to the root, moving parents down until finding + a place newitem fits. */ + arr = _PyList_ITEMS(heap); + newitem = arr[pos]; + while (pos > startpos) { + parentpos = (pos - 1) >> 1; + parent = arr[parentpos]; Py_INCREF(newitem); Py_INCREF(parent); - cmp = PyObject_RichCompareBool(newitem, parent, Py_LT); + cmp = PyObject_RichCompareBool(newitem, parent, Py_LT); Py_DECREF(parent); Py_DECREF(newitem); - if (cmp < 0) - return -1; - if (size != PyList_GET_SIZE(heap)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; - } - if (cmp == 0) - break; - arr = _PyList_ITEMS(heap); - parent = arr[parentpos]; - newitem = arr[pos]; - arr[parentpos] = newitem; - arr[pos] = parent; - pos = parentpos; - } - return 0; -} - -static int -siftup(PyListObject *heap, Py_ssize_t pos) -{ - Py_ssize_t startpos, endpos, childpos, limit; - PyObject *tmp1, *tmp2, **arr; - int cmp; - - assert(PyList_Check(heap)); - endpos = PyList_GET_SIZE(heap); - startpos = pos; - if (pos >= endpos) { - PyErr_SetString(PyExc_IndexError, "index out of range"); - return -1; - } - - /* Bubble up the smaller child until hitting a leaf. */ - arr = _PyList_ITEMS(heap); - limit = endpos >> 1; /* smallest pos that has no child */ - while (pos < limit) { - /* Set childpos to index of smaller child. */ - childpos = 2*pos + 1; /* leftmost child position */ - if (childpos + 1 < endpos) { + if (cmp < 0) + return -1; + if (size != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); + return -1; + } + if (cmp == 0) + break; + arr = _PyList_ITEMS(heap); + parent = arr[parentpos]; + newitem = arr[pos]; + arr[parentpos] = newitem; + arr[pos] = parent; + pos = parentpos; + } + return 0; +} + +static int +siftup(PyListObject *heap, Py_ssize_t pos) +{ + Py_ssize_t startpos, endpos, childpos, limit; + PyObject *tmp1, *tmp2, **arr; + int cmp; + + assert(PyList_Check(heap)); + endpos = PyList_GET_SIZE(heap); + startpos = pos; + if (pos >= endpos) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + /* Bubble up the smaller child until hitting a leaf. */ + arr = _PyList_ITEMS(heap); + limit = endpos >> 1; /* smallest pos that has no child */ + while (pos < limit) { + /* Set childpos to index of smaller child. */ + childpos = 2*pos + 1; /* leftmost child position */ + if (childpos + 1 < endpos) { PyObject* a = arr[childpos]; PyObject* b = arr[childpos + 1]; Py_INCREF(a); @@ -89,27 +89,27 @@ siftup(PyListObject *heap, Py_ssize_t pos) cmp = PyObject_RichCompareBool(a, b, Py_LT); Py_DECREF(a); Py_DECREF(b); - if (cmp < 0) - return -1; - childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ - arr = _PyList_ITEMS(heap); /* arr may have changed */ - if (endpos != PyList_GET_SIZE(heap)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; - } - } - /* Move the smaller child up. */ - tmp1 = arr[childpos]; - tmp2 = arr[pos]; - arr[childpos] = tmp2; - arr[pos] = tmp1; - pos = childpos; - } - /* Bubble it up to its final resting place (by sifting its parents down). */ - return siftdown(heap, startpos, pos); -} - + if (cmp < 0) + return -1; + childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ + arr = _PyList_ITEMS(heap); /* arr may have changed */ + if (endpos != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); + return -1; + } + } + /* Move the smaller child up. */ + tmp1 = arr[childpos]; + tmp2 = arr[pos]; + arr[childpos] = tmp2; + arr[pos] = tmp1; + pos = childpos; + } + /* Bubble it up to its final resting place (by sifting its parents down). */ + return siftdown(heap, startpos, pos); +} + /*[clinic input] _heapq.heappush @@ -120,60 +120,60 @@ _heapq.heappush Push item onto heap, maintaining the heap invariant. [clinic start generated code]*/ -static PyObject * +static PyObject * _heapq_heappush_impl(PyObject *module, PyObject *heap, PyObject *item) /*[clinic end generated code: output=912c094f47663935 input=7913545cb5118842]*/ -{ - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - - if (PyList_Append(heap, item)) - return NULL; - - if (siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1)) - return NULL; - Py_RETURN_NONE; -} - -static PyObject * -heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) -{ - PyObject *lastelt, *returnitem; - Py_ssize_t n; - - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - - /* raises IndexError if the heap is empty */ - n = PyList_GET_SIZE(heap); - if (n == 0) { - PyErr_SetString(PyExc_IndexError, "index out of range"); - return NULL; - } - - lastelt = PyList_GET_ITEM(heap, n-1) ; - Py_INCREF(lastelt); - if (PyList_SetSlice(heap, n-1, n, NULL)) { - Py_DECREF(lastelt); - return NULL; - } - n--; - - if (!n) - return lastelt; - returnitem = PyList_GET_ITEM(heap, 0); - PyList_SET_ITEM(heap, 0, lastelt); - if (siftup_func((PyListObject *)heap, 0)) { - Py_DECREF(returnitem); - return NULL; - } - return returnitem; -} - +{ + if (!PyList_Check(heap)) { + PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); + return NULL; + } + + if (PyList_Append(heap, item)) + return NULL; + + if (siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1)) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) +{ + PyObject *lastelt, *returnitem; + Py_ssize_t n; + + if (!PyList_Check(heap)) { + PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); + return NULL; + } + + /* raises IndexError if the heap is empty */ + n = PyList_GET_SIZE(heap); + if (n == 0) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + lastelt = PyList_GET_ITEM(heap, n-1) ; + Py_INCREF(lastelt); + if (PyList_SetSlice(heap, n-1, n, NULL)) { + Py_DECREF(lastelt); + return NULL; + } + n--; + + if (!n) + return lastelt; + returnitem = PyList_GET_ITEM(heap, 0); + PyList_SET_ITEM(heap, 0, lastelt); + if (siftup_func((PyListObject *)heap, 0)) { + Py_DECREF(returnitem); + return NULL; + } + return returnitem; +} + /*[clinic input] _heapq.heappop @@ -183,38 +183,38 @@ _heapq.heappop Pop the smallest item off the heap, maintaining the heap invariant. [clinic start generated code]*/ -static PyObject * +static PyObject * _heapq_heappop(PyObject *module, PyObject *heap) /*[clinic end generated code: output=e1bbbc9866bce179 input=9bd36317b806033d]*/ -{ - return heappop_internal(heap, siftup); -} - -static PyObject * +{ + return heappop_internal(heap, siftup); +} + +static PyObject * heapreplace_internal(PyObject *heap, PyObject *item, int siftup_func(PyListObject *, Py_ssize_t)) -{ +{ PyObject *returnitem; - - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - - if (PyList_GET_SIZE(heap) == 0) { - PyErr_SetString(PyExc_IndexError, "index out of range"); - return NULL; - } - - returnitem = PyList_GET_ITEM(heap, 0); - Py_INCREF(item); - PyList_SET_ITEM(heap, 0, item); - if (siftup_func((PyListObject *)heap, 0)) { - Py_DECREF(returnitem); - return NULL; - } - return returnitem; -} - + + if (!PyList_Check(heap)) { + PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); + return NULL; + } + + if (PyList_GET_SIZE(heap) == 0) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + returnitem = PyList_GET_ITEM(heap, 0); + Py_INCREF(item); + PyList_SET_ITEM(heap, 0, item); + if (siftup_func((PyListObject *)heap, 0)) { + Py_DECREF(returnitem); + return NULL; + } + return returnitem; +} + /*[clinic input] _heapq.heapreplace @@ -234,16 +234,16 @@ this routine unless written as part of a conditional replacement: item = heapreplace(heap, item) [clinic start generated code]*/ -static PyObject * +static PyObject * _heapq_heapreplace_impl(PyObject *module, PyObject *heap, PyObject *item) /*[clinic end generated code: output=82ea55be8fbe24b4 input=e57ae8f4ecfc88e3]*/ -{ +{ return heapreplace_internal(heap, item, siftup); -} - +} + /*[clinic input] _heapq.heappushpop - + heap: object item: object / @@ -254,145 +254,145 @@ The combined action runs more efficiently than heappush() followed by a separate call to heappop(). [clinic start generated code]*/ -static PyObject * +static PyObject * _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) /*[clinic end generated code: output=67231dc98ed5774f input=eb48c90ba77b2214]*/ -{ +{ PyObject *returnitem; - int cmp; - - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - - if (PyList_GET_SIZE(heap) == 0) { - Py_INCREF(item); - return item; - } - + int cmp; + + if (!PyList_Check(heap)) { + PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); + return NULL; + } + + if (PyList_GET_SIZE(heap) == 0) { + Py_INCREF(item); + return item; + } + PyObject* top = PyList_GET_ITEM(heap, 0); Py_INCREF(top); cmp = PyObject_RichCompareBool(top, item, Py_LT); Py_DECREF(top); - if (cmp < 0) - return NULL; - if (cmp == 0) { - Py_INCREF(item); - return item; - } - - if (PyList_GET_SIZE(heap) == 0) { - PyErr_SetString(PyExc_IndexError, "index out of range"); - return NULL; - } - - returnitem = PyList_GET_ITEM(heap, 0); - Py_INCREF(item); - PyList_SET_ITEM(heap, 0, item); - if (siftup((PyListObject *)heap, 0)) { - Py_DECREF(returnitem); - return NULL; - } - return returnitem; -} - -static Py_ssize_t -keep_top_bit(Py_ssize_t n) -{ - int i = 0; - - while (n > 1) { - n >>= 1; - i++; - } - return n << i; -} - -/* Cache friendly version of heapify() - ----------------------------------- - - Build-up a heap in O(n) time by performing siftup() operations - on nodes whose children are already heaps. - - The simplest way is to sift the nodes in reverse order from - n//2-1 to 0 inclusive. The downside is that children may be - out of cache by the time their parent is reached. - - A better way is to not wait for the children to go out of cache. - Once a sibling pair of child nodes have been sifted, immediately - sift their parent node (while the children are still in cache). - - Both ways build child heaps before their parents, so both ways - do the exact same number of comparisons and produce exactly - the same heap. The only difference is that the traversal - order is optimized for cache efficiency. -*/ - -static PyObject * -cache_friendly_heapify(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) -{ - Py_ssize_t i, j, m, mhalf, leftmost; - - m = PyList_GET_SIZE(heap) >> 1; /* index of first childless node */ - leftmost = keep_top_bit(m + 1) - 1; /* leftmost node in row of m */ - mhalf = m >> 1; /* parent of first childless node */ - - for (i = leftmost - 1 ; i >= mhalf ; i--) { - j = i; - while (1) { - if (siftup_func((PyListObject *)heap, j)) - return NULL; - if (!(j & 1)) - break; - j >>= 1; - } - } - - for (i = m - 1 ; i >= leftmost ; i--) { - j = i; - while (1) { - if (siftup_func((PyListObject *)heap, j)) - return NULL; - if (!(j & 1)) - break; - j >>= 1; - } - } - Py_RETURN_NONE; -} - -static PyObject * -heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) -{ - Py_ssize_t i, n; - - if (!PyList_Check(heap)) { - PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); - return NULL; - } - - /* For heaps likely to be bigger than L1 cache, we use the cache - friendly heapify function. For smaller heaps that fit entirely - in cache, we prefer the simpler algorithm with less branching. - */ - n = PyList_GET_SIZE(heap); - if (n > 2500) - return cache_friendly_heapify(heap, siftup_func); - - /* Transform bottom-up. The largest index there's any point to - looking at is the largest with a child index in-range, so must - have 2*i + 1 < n, or i < (n-1)/2. If n is even = 2*j, this is - (2*j-1)/2 = j-1/2 so j-1 is the largest, which is n//2 - 1. If - n is odd = 2*j+1, this is (2*j+1-1)/2 = j so j-1 is the largest, - and that's again n//2-1. - */ - for (i = (n >> 1) - 1 ; i >= 0 ; i--) - if (siftup_func((PyListObject *)heap, i)) - return NULL; - Py_RETURN_NONE; -} - + if (cmp < 0) + return NULL; + if (cmp == 0) { + Py_INCREF(item); + return item; + } + + if (PyList_GET_SIZE(heap) == 0) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + + returnitem = PyList_GET_ITEM(heap, 0); + Py_INCREF(item); + PyList_SET_ITEM(heap, 0, item); + if (siftup((PyListObject *)heap, 0)) { + Py_DECREF(returnitem); + return NULL; + } + return returnitem; +} + +static Py_ssize_t +keep_top_bit(Py_ssize_t n) +{ + int i = 0; + + while (n > 1) { + n >>= 1; + i++; + } + return n << i; +} + +/* Cache friendly version of heapify() + ----------------------------------- + + Build-up a heap in O(n) time by performing siftup() operations + on nodes whose children are already heaps. + + The simplest way is to sift the nodes in reverse order from + n//2-1 to 0 inclusive. The downside is that children may be + out of cache by the time their parent is reached. + + A better way is to not wait for the children to go out of cache. + Once a sibling pair of child nodes have been sifted, immediately + sift their parent node (while the children are still in cache). + + Both ways build child heaps before their parents, so both ways + do the exact same number of comparisons and produce exactly + the same heap. The only difference is that the traversal + order is optimized for cache efficiency. +*/ + +static PyObject * +cache_friendly_heapify(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) +{ + Py_ssize_t i, j, m, mhalf, leftmost; + + m = PyList_GET_SIZE(heap) >> 1; /* index of first childless node */ + leftmost = keep_top_bit(m + 1) - 1; /* leftmost node in row of m */ + mhalf = m >> 1; /* parent of first childless node */ + + for (i = leftmost - 1 ; i >= mhalf ; i--) { + j = i; + while (1) { + if (siftup_func((PyListObject *)heap, j)) + return NULL; + if (!(j & 1)) + break; + j >>= 1; + } + } + + for (i = m - 1 ; i >= leftmost ; i--) { + j = i; + while (1) { + if (siftup_func((PyListObject *)heap, j)) + return NULL; + if (!(j & 1)) + break; + j >>= 1; + } + } + Py_RETURN_NONE; +} + +static PyObject * +heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) +{ + Py_ssize_t i, n; + + if (!PyList_Check(heap)) { + PyErr_SetString(PyExc_TypeError, "heap argument must be a list"); + return NULL; + } + + /* For heaps likely to be bigger than L1 cache, we use the cache + friendly heapify function. For smaller heaps that fit entirely + in cache, we prefer the simpler algorithm with less branching. + */ + n = PyList_GET_SIZE(heap); + if (n > 2500) + return cache_friendly_heapify(heap, siftup_func); + + /* Transform bottom-up. The largest index there's any point to + looking at is the largest with a child index in-range, so must + have 2*i + 1 < n, or i < (n-1)/2. If n is even = 2*j, this is + (2*j-1)/2 = j-1/2 so j-1 is the largest, which is n//2 - 1. If + n is odd = 2*j+1, this is (2*j+1-1)/2 = j so j-1 is the largest, + and that's again n//2-1. + */ + for (i = (n >> 1) - 1 ; i >= 0 ; i--) + if (siftup_func((PyListObject *)heap, i)) + return NULL; + Py_RETURN_NONE; +} + /*[clinic input] _heapq.heapify @@ -402,80 +402,80 @@ _heapq.heapify Transform list into a heap, in-place, in O(len(heap)) time. [clinic start generated code]*/ -static PyObject * +static PyObject * _heapq_heapify(PyObject *module, PyObject *heap) /*[clinic end generated code: output=11483f23627c4616 input=872c87504b8de970]*/ -{ - return heapify_internal(heap, siftup); -} - -static int -siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) -{ - PyObject *newitem, *parent, **arr; - Py_ssize_t parentpos, size; - int cmp; - - assert(PyList_Check(heap)); - size = PyList_GET_SIZE(heap); - if (pos >= size) { - PyErr_SetString(PyExc_IndexError, "index out of range"); - return -1; - } - - /* Follow the path to the root, moving parents down until finding - a place newitem fits. */ - arr = _PyList_ITEMS(heap); - newitem = arr[pos]; - while (pos > startpos) { - parentpos = (pos - 1) >> 1; - parent = arr[parentpos]; +{ + return heapify_internal(heap, siftup); +} + +static int +siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) +{ + PyObject *newitem, *parent, **arr; + Py_ssize_t parentpos, size; + int cmp; + + assert(PyList_Check(heap)); + size = PyList_GET_SIZE(heap); + if (pos >= size) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + /* Follow the path to the root, moving parents down until finding + a place newitem fits. */ + arr = _PyList_ITEMS(heap); + newitem = arr[pos]; + while (pos > startpos) { + parentpos = (pos - 1) >> 1; + parent = arr[parentpos]; Py_INCREF(parent); Py_INCREF(newitem); - cmp = PyObject_RichCompareBool(parent, newitem, Py_LT); + cmp = PyObject_RichCompareBool(parent, newitem, Py_LT); Py_DECREF(parent); Py_DECREF(newitem); - if (cmp < 0) - return -1; - if (size != PyList_GET_SIZE(heap)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; - } - if (cmp == 0) - break; - arr = _PyList_ITEMS(heap); - parent = arr[parentpos]; - newitem = arr[pos]; - arr[parentpos] = newitem; - arr[pos] = parent; - pos = parentpos; - } - return 0; -} - -static int -siftup_max(PyListObject *heap, Py_ssize_t pos) -{ - Py_ssize_t startpos, endpos, childpos, limit; - PyObject *tmp1, *tmp2, **arr; - int cmp; - - assert(PyList_Check(heap)); - endpos = PyList_GET_SIZE(heap); - startpos = pos; - if (pos >= endpos) { - PyErr_SetString(PyExc_IndexError, "index out of range"); - return -1; - } - - /* Bubble up the smaller child until hitting a leaf. */ - arr = _PyList_ITEMS(heap); - limit = endpos >> 1; /* smallest pos that has no child */ - while (pos < limit) { - /* Set childpos to index of smaller child. */ - childpos = 2*pos + 1; /* leftmost child position */ - if (childpos + 1 < endpos) { + if (cmp < 0) + return -1; + if (size != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); + return -1; + } + if (cmp == 0) + break; + arr = _PyList_ITEMS(heap); + parent = arr[parentpos]; + newitem = arr[pos]; + arr[parentpos] = newitem; + arr[pos] = parent; + pos = parentpos; + } + return 0; +} + +static int +siftup_max(PyListObject *heap, Py_ssize_t pos) +{ + Py_ssize_t startpos, endpos, childpos, limit; + PyObject *tmp1, *tmp2, **arr; + int cmp; + + assert(PyList_Check(heap)); + endpos = PyList_GET_SIZE(heap); + startpos = pos; + if (pos >= endpos) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return -1; + } + + /* Bubble up the smaller child until hitting a leaf. */ + arr = _PyList_ITEMS(heap); + limit = endpos >> 1; /* smallest pos that has no child */ + while (pos < limit) { + /* Set childpos to index of smaller child. */ + childpos = 2*pos + 1; /* leftmost child position */ + if (childpos + 1 < endpos) { PyObject* a = arr[childpos + 1]; PyObject* b = arr[childpos]; Py_INCREF(a); @@ -483,27 +483,27 @@ siftup_max(PyListObject *heap, Py_ssize_t pos) cmp = PyObject_RichCompareBool(a, b, Py_LT); Py_DECREF(a); Py_DECREF(b); - if (cmp < 0) - return -1; - childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ - arr = _PyList_ITEMS(heap); /* arr may have changed */ - if (endpos != PyList_GET_SIZE(heap)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; - } - } - /* Move the smaller child up. */ - tmp1 = arr[childpos]; - tmp2 = arr[pos]; - arr[childpos] = tmp2; - arr[pos] = tmp1; - pos = childpos; - } - /* Bubble it up to its final resting place (by sifting its parents down). */ - return siftdown_max(heap, startpos, pos); -} - + if (cmp < 0) + return -1; + childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ + arr = _PyList_ITEMS(heap); /* arr may have changed */ + if (endpos != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); + return -1; + } + } + /* Move the smaller child up. */ + tmp1 = arr[childpos]; + tmp2 = arr[pos]; + arr[childpos] = tmp2; + arr[pos] = tmp1; + pos = childpos; + } + /* Bubble it up to its final resting place (by sifting its parents down). */ + return siftdown_max(heap, startpos, pos); +} + /*[clinic input] _heapq._heappop_max @@ -514,16 +514,16 @@ _heapq._heappop_max Maxheap variant of heappop. [clinic start generated code]*/ -static PyObject * +static PyObject * _heapq__heappop_max(PyObject *module, PyObject *heap) /*[clinic end generated code: output=acd30acf6384b13c input=62ede3ba9117f541]*/ -{ - return heappop_internal(heap, siftup_max); -} - +{ + return heappop_internal(heap, siftup_max); +} + /*[clinic input] _heapq._heapreplace_max - + heap: object item: object / @@ -531,31 +531,31 @@ _heapq._heapreplace_max Maxheap variant of heapreplace. [clinic start generated code]*/ -static PyObject * +static PyObject * _heapq__heapreplace_max_impl(PyObject *module, PyObject *heap, PyObject *item) /*[clinic end generated code: output=8ad7545e4a5e8adb input=6d8f25131e0f0e5f]*/ -{ +{ return heapreplace_internal(heap, item, siftup_max); -} - +} + /*[clinic input] _heapq._heapify_max - + heap: object / Maxheap variant of heapify. [clinic start generated code]*/ -static PyObject * +static PyObject * _heapq__heapify_max(PyObject *module, PyObject *heap) /*[clinic end generated code: output=1c6bb6b60d6a2133 input=cdfcc6835b14110d]*/ -{ - return heapify_internal(heap, siftup_max); -} - -static PyMethodDef heapq_methods[] = { +{ + return heapify_internal(heap, siftup_max); +} + +static PyMethodDef heapq_methods[] = { _HEAPQ_HEAPPUSH_METHODDEF _HEAPQ_HEAPPUSHPOP_METHODDEF _HEAPQ_HEAPPOP_METHODDEF @@ -565,134 +565,134 @@ static PyMethodDef heapq_methods[] = { _HEAPQ__HEAPIFY_MAX_METHODDEF _HEAPQ__HEAPREPLACE_MAX_METHODDEF {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(module_doc, -"Heap queue algorithm (a.k.a. priority queue).\n\ -\n\ -Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for\n\ -all k, counting elements from 0. For the sake of comparison,\n\ -non-existing elements are considered to be infinite. The interesting\n\ -property of a heap is that a[0] is always its smallest element.\n\ -\n\ -Usage:\n\ -\n\ -heap = [] # creates an empty heap\n\ -heappush(heap, item) # pushes a new item on the heap\n\ -item = heappop(heap) # pops the smallest item from the heap\n\ -item = heap[0] # smallest item on the heap without popping it\n\ -heapify(x) # transforms list into a heap, in-place, in linear time\n\ -item = heapreplace(heap, item) # pops and returns smallest item, and adds\n\ - # new item; the heap size is unchanged\n\ -\n\ -Our API differs from textbook heap algorithms as follows:\n\ -\n\ -- We use 0-based indexing. This makes the relationship between the\n\ - index for a node and the indexes for its children slightly less\n\ - obvious, but is more suitable since Python uses 0-based indexing.\n\ -\n\ -- Our heappop() method returns the smallest item, not the largest.\n\ -\n\ -These two make it possible to view the heap as a regular Python list\n\ -without surprises: heap[0] is the smallest item, and heap.sort()\n\ -maintains the heap invariant!\n"); - - -PyDoc_STRVAR(__about__, -"Heap queues\n\ -\n\ -[explanation by Fran\xc3\xa7ois Pinard]\n\ -\n\ -Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for\n\ -all k, counting elements from 0. For the sake of comparison,\n\ -non-existing elements are considered to be infinite. The interesting\n\ -property of a heap is that a[0] is always its smallest element.\n" -"\n\ -The strange invariant above is meant to be an efficient memory\n\ -representation for a tournament. The numbers below are `k', not a[k]:\n\ -\n\ - 0\n\ -\n\ - 1 2\n\ -\n\ - 3 4 5 6\n\ -\n\ - 7 8 9 10 11 12 13 14\n\ -\n\ - 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30\n\ -\n\ -\n\ -In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'. In\n\ -a usual binary tournament we see in sports, each cell is the winner\n\ -over the two cells it tops, and we can trace the winner down the tree\n\ -to see all opponents s/he had. However, in many computer applications\n\ -of such tournaments, we do not need to trace the history of a winner.\n\ -To be more memory efficient, when a winner is promoted, we try to\n\ -replace it by something else at a lower level, and the rule becomes\n\ -that a cell and the two cells it tops contain three different items,\n\ -but the top cell \"wins\" over the two topped cells.\n" -"\n\ -If this heap invariant is protected at all time, index 0 is clearly\n\ -the overall winner. The simplest algorithmic way to remove it and\n\ -find the \"next\" winner is to move some loser (let's say cell 30 in the\n\ -diagram above) into the 0 position, and then percolate this new 0 down\n\ -the tree, exchanging values, until the invariant is re-established.\n\ -This is clearly logarithmic on the total number of items in the tree.\n\ -By iterating over all items, you get an O(n ln n) sort.\n" -"\n\ -A nice feature of this sort is that you can efficiently insert new\n\ -items while the sort is going on, provided that the inserted items are\n\ -not \"better\" than the last 0'th element you extracted. This is\n\ -especially useful in simulation contexts, where the tree holds all\n\ -incoming events, and the \"win\" condition means the smallest scheduled\n\ -time. When an event schedule other events for execution, they are\n\ -scheduled into the future, so they can easily go into the heap. So, a\n\ -heap is a good structure for implementing schedulers (this is what I\n\ -used for my MIDI sequencer :-).\n" -"\n\ -Various structures for implementing schedulers have been extensively\n\ -studied, and heaps are good for this, as they are reasonably speedy,\n\ -the speed is almost constant, and the worst case is not much different\n\ -than the average case. However, there are other representations which\n\ -are more efficient overall, yet the worst cases might be terrible.\n" -"\n\ -Heaps are also very useful in big disk sorts. You most probably all\n\ -know that a big sort implies producing \"runs\" (which are pre-sorted\n\ -sequences, which size is usually related to the amount of CPU memory),\n\ -followed by a merging passes for these runs, which merging is often\n\ -very cleverly organised[1]. It is very important that the initial\n\ -sort produces the longest runs possible. Tournaments are a good way\n\ -to that. If, using all the memory available to hold a tournament, you\n\ -replace and percolate items that happen to fit the current run, you'll\n\ -produce runs which are twice the size of the memory for random input,\n\ -and much better for input fuzzily ordered.\n" -"\n\ -Moreover, if you output the 0'th item on disk and get an input which\n\ -may not fit in the current tournament (because the value \"wins\" over\n\ -the last output value), it cannot fit in the heap, so the size of the\n\ -heap decreases. The freed memory could be cleverly reused immediately\n\ -for progressively building a second heap, which grows at exactly the\n\ -same rate the first heap is melting. When the first heap completely\n\ -vanishes, you switch heaps and start a new run. Clever and quite\n\ -effective!\n\ -\n\ -In a word, heaps are useful memory structures to know. I use them in\n\ -a few applications, and I think it is good to keep a `heap' module\n\ -around. :-)\n" -"\n\ ---------------------\n\ -[1] The disk balancing algorithms which are current, nowadays, are\n\ -more annoying than clever, and this is a consequence of the seeking\n\ -capabilities of the disks. On devices which cannot seek, like big\n\ -tape drives, the story was quite different, and one had to be very\n\ -clever to ensure (far in advance) that each tape movement will be the\n\ -most effective possible (that is, will best participate at\n\ -\"progressing\" the merge). Some tapes were even able to read\n\ -backwards, and this was also used to avoid the rewinding time.\n\ -Believe me, real good tape sorts were quite spectacular to watch!\n\ -From all times, sorting has always been a Great Art! :-)\n"); - - +}; + +PyDoc_STRVAR(module_doc, +"Heap queue algorithm (a.k.a. priority queue).\n\ +\n\ +Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for\n\ +all k, counting elements from 0. For the sake of comparison,\n\ +non-existing elements are considered to be infinite. The interesting\n\ +property of a heap is that a[0] is always its smallest element.\n\ +\n\ +Usage:\n\ +\n\ +heap = [] # creates an empty heap\n\ +heappush(heap, item) # pushes a new item on the heap\n\ +item = heappop(heap) # pops the smallest item from the heap\n\ +item = heap[0] # smallest item on the heap without popping it\n\ +heapify(x) # transforms list into a heap, in-place, in linear time\n\ +item = heapreplace(heap, item) # pops and returns smallest item, and adds\n\ + # new item; the heap size is unchanged\n\ +\n\ +Our API differs from textbook heap algorithms as follows:\n\ +\n\ +- We use 0-based indexing. This makes the relationship between the\n\ + index for a node and the indexes for its children slightly less\n\ + obvious, but is more suitable since Python uses 0-based indexing.\n\ +\n\ +- Our heappop() method returns the smallest item, not the largest.\n\ +\n\ +These two make it possible to view the heap as a regular Python list\n\ +without surprises: heap[0] is the smallest item, and heap.sort()\n\ +maintains the heap invariant!\n"); + + +PyDoc_STRVAR(__about__, +"Heap queues\n\ +\n\ +[explanation by Fran\xc3\xa7ois Pinard]\n\ +\n\ +Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for\n\ +all k, counting elements from 0. For the sake of comparison,\n\ +non-existing elements are considered to be infinite. The interesting\n\ +property of a heap is that a[0] is always its smallest element.\n" +"\n\ +The strange invariant above is meant to be an efficient memory\n\ +representation for a tournament. The numbers below are `k', not a[k]:\n\ +\n\ + 0\n\ +\n\ + 1 2\n\ +\n\ + 3 4 5 6\n\ +\n\ + 7 8 9 10 11 12 13 14\n\ +\n\ + 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30\n\ +\n\ +\n\ +In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'. In\n\ +a usual binary tournament we see in sports, each cell is the winner\n\ +over the two cells it tops, and we can trace the winner down the tree\n\ +to see all opponents s/he had. However, in many computer applications\n\ +of such tournaments, we do not need to trace the history of a winner.\n\ +To be more memory efficient, when a winner is promoted, we try to\n\ +replace it by something else at a lower level, and the rule becomes\n\ +that a cell and the two cells it tops contain three different items,\n\ +but the top cell \"wins\" over the two topped cells.\n" +"\n\ +If this heap invariant is protected at all time, index 0 is clearly\n\ +the overall winner. The simplest algorithmic way to remove it and\n\ +find the \"next\" winner is to move some loser (let's say cell 30 in the\n\ +diagram above) into the 0 position, and then percolate this new 0 down\n\ +the tree, exchanging values, until the invariant is re-established.\n\ +This is clearly logarithmic on the total number of items in the tree.\n\ +By iterating over all items, you get an O(n ln n) sort.\n" +"\n\ +A nice feature of this sort is that you can efficiently insert new\n\ +items while the sort is going on, provided that the inserted items are\n\ +not \"better\" than the last 0'th element you extracted. This is\n\ +especially useful in simulation contexts, where the tree holds all\n\ +incoming events, and the \"win\" condition means the smallest scheduled\n\ +time. When an event schedule other events for execution, they are\n\ +scheduled into the future, so they can easily go into the heap. So, a\n\ +heap is a good structure for implementing schedulers (this is what I\n\ +used for my MIDI sequencer :-).\n" +"\n\ +Various structures for implementing schedulers have been extensively\n\ +studied, and heaps are good for this, as they are reasonably speedy,\n\ +the speed is almost constant, and the worst case is not much different\n\ +than the average case. However, there are other representations which\n\ +are more efficient overall, yet the worst cases might be terrible.\n" +"\n\ +Heaps are also very useful in big disk sorts. You most probably all\n\ +know that a big sort implies producing \"runs\" (which are pre-sorted\n\ +sequences, which size is usually related to the amount of CPU memory),\n\ +followed by a merging passes for these runs, which merging is often\n\ +very cleverly organised[1]. It is very important that the initial\n\ +sort produces the longest runs possible. Tournaments are a good way\n\ +to that. If, using all the memory available to hold a tournament, you\n\ +replace and percolate items that happen to fit the current run, you'll\n\ +produce runs which are twice the size of the memory for random input,\n\ +and much better for input fuzzily ordered.\n" +"\n\ +Moreover, if you output the 0'th item on disk and get an input which\n\ +may not fit in the current tournament (because the value \"wins\" over\n\ +the last output value), it cannot fit in the heap, so the size of the\n\ +heap decreases. The freed memory could be cleverly reused immediately\n\ +for progressively building a second heap, which grows at exactly the\n\ +same rate the first heap is melting. When the first heap completely\n\ +vanishes, you switch heaps and start a new run. Clever and quite\n\ +effective!\n\ +\n\ +In a word, heaps are useful memory structures to know. I use them in\n\ +a few applications, and I think it is good to keep a `heap' module\n\ +around. :-)\n" +"\n\ +--------------------\n\ +[1] The disk balancing algorithms which are current, nowadays, are\n\ +more annoying than clever, and this is a consequence of the seeking\n\ +capabilities of the disks. On devices which cannot seek, like big\n\ +tape drives, the story was quite different, and one had to be very\n\ +clever to ensure (far in advance) that each tape movement will be the\n\ +most effective possible (that is, will best participate at\n\ +\"progressing\" the merge). Some tapes were even able to read\n\ +backwards, and this was also used to avoid the rewinding time.\n\ +Believe me, real good tape sorts were quite spectacular to watch!\n\ +From all times, sorting has always been a Great Art! :-)\n"); + + static int heapq_exec(PyObject *m) { @@ -709,20 +709,20 @@ static struct PyModuleDef_Slot heapq_slots[] = { {0, NULL} }; -static struct PyModuleDef _heapqmodule = { - PyModuleDef_HEAD_INIT, - "_heapq", - module_doc, +static struct PyModuleDef _heapqmodule = { + PyModuleDef_HEAD_INIT, + "_heapq", + module_doc, 0, - heapq_methods, + heapq_methods, heapq_slots, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__heapq(void) -{ + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__heapq(void) +{ return PyModuleDef_Init(&_heapqmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/_io/_iomodule.c b/contrib/tools/python3/src/Modules/_io/_iomodule.c index d7cadacea1b..f81f7a8f78f 100644 --- a/contrib/tools/python3/src/Modules/_io/_iomodule.c +++ b/contrib/tools/python3/src/Modules/_io/_iomodule.c @@ -1,367 +1,367 @@ -/* - An implementation of the new I/O lib as defined by PEP 3116 - "New I/O" - - Classes defined here: UnsupportedOperation, BlockingIOError. - Functions defined here: open(). - - Mostly written by Amaury Forgeot d'Arc -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "_iomodule.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_SYS_STAT_H -#include -#endif /* HAVE_SYS_STAT_H */ - -#ifdef MS_WINDOWS -#include -#endif - -/* Various interned strings */ - -PyObject *_PyIO_str_close = NULL; -PyObject *_PyIO_str_closed = NULL; -PyObject *_PyIO_str_decode = NULL; -PyObject *_PyIO_str_encode = NULL; -PyObject *_PyIO_str_fileno = NULL; -PyObject *_PyIO_str_flush = NULL; -PyObject *_PyIO_str_getstate = NULL; -PyObject *_PyIO_str_isatty = NULL; -PyObject *_PyIO_str_newlines = NULL; -PyObject *_PyIO_str_nl = NULL; -PyObject *_PyIO_str_peek = NULL; -PyObject *_PyIO_str_read = NULL; -PyObject *_PyIO_str_read1 = NULL; -PyObject *_PyIO_str_readable = NULL; -PyObject *_PyIO_str_readall = NULL; -PyObject *_PyIO_str_readinto = NULL; -PyObject *_PyIO_str_readline = NULL; -PyObject *_PyIO_str_reset = NULL; -PyObject *_PyIO_str_seek = NULL; -PyObject *_PyIO_str_seekable = NULL; -PyObject *_PyIO_str_setstate = NULL; -PyObject *_PyIO_str_tell = NULL; -PyObject *_PyIO_str_truncate = NULL; -PyObject *_PyIO_str_writable = NULL; -PyObject *_PyIO_str_write = NULL; - -PyObject *_PyIO_empty_str = NULL; -PyObject *_PyIO_empty_bytes = NULL; - -PyDoc_STRVAR(module_doc, -"The io module provides the Python interfaces to stream handling. The\n" -"builtin open function is defined in this module.\n" -"\n" -"At the top of the I/O hierarchy is the abstract base class IOBase. It\n" -"defines the basic interface to a stream. Note, however, that there is no\n" -"separation between reading and writing to streams; implementations are\n" -"allowed to raise an OSError if they do not support a given operation.\n" -"\n" -"Extending IOBase is RawIOBase which deals simply with the reading and\n" -"writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide\n" -"an interface to OS files.\n" -"\n" -"BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n" -"subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer\n" -"streams that are readable, writable, and both respectively.\n" -"BufferedRandom provides a buffered interface to random access\n" -"streams. BytesIO is a simple stream of in-memory bytes.\n" -"\n" -"Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n" -"of streams into text. TextIOWrapper, which extends it, is a buffered text\n" -"interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n" -"is an in-memory stream for text.\n" -"\n" -"Argument names are not part of the specification, and only the arguments\n" -"of open() are intended to be used as keyword arguments.\n" -"\n" -"data:\n" -"\n" -"DEFAULT_BUFFER_SIZE\n" -"\n" -" An int containing the default buffer size used by the module's buffered\n" -" I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n" -" possible.\n" - ); - - -/* - * The main open() function - */ -/*[clinic input] -module _io - -_io.open - file: object - mode: str = "r" - buffering: int = -1 +/* + An implementation of the new I/O lib as defined by PEP 3116 - "New I/O" + + Classes defined here: UnsupportedOperation, BlockingIOError. + Functions defined here: open(). + + Mostly written by Amaury Forgeot d'Arc +*/ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "_iomodule.h" + +#ifdef HAVE_SYS_TYPES_H +#include +#endif /* HAVE_SYS_TYPES_H */ + +#ifdef HAVE_SYS_STAT_H +#include +#endif /* HAVE_SYS_STAT_H */ + +#ifdef MS_WINDOWS +#include +#endif + +/* Various interned strings */ + +PyObject *_PyIO_str_close = NULL; +PyObject *_PyIO_str_closed = NULL; +PyObject *_PyIO_str_decode = NULL; +PyObject *_PyIO_str_encode = NULL; +PyObject *_PyIO_str_fileno = NULL; +PyObject *_PyIO_str_flush = NULL; +PyObject *_PyIO_str_getstate = NULL; +PyObject *_PyIO_str_isatty = NULL; +PyObject *_PyIO_str_newlines = NULL; +PyObject *_PyIO_str_nl = NULL; +PyObject *_PyIO_str_peek = NULL; +PyObject *_PyIO_str_read = NULL; +PyObject *_PyIO_str_read1 = NULL; +PyObject *_PyIO_str_readable = NULL; +PyObject *_PyIO_str_readall = NULL; +PyObject *_PyIO_str_readinto = NULL; +PyObject *_PyIO_str_readline = NULL; +PyObject *_PyIO_str_reset = NULL; +PyObject *_PyIO_str_seek = NULL; +PyObject *_PyIO_str_seekable = NULL; +PyObject *_PyIO_str_setstate = NULL; +PyObject *_PyIO_str_tell = NULL; +PyObject *_PyIO_str_truncate = NULL; +PyObject *_PyIO_str_writable = NULL; +PyObject *_PyIO_str_write = NULL; + +PyObject *_PyIO_empty_str = NULL; +PyObject *_PyIO_empty_bytes = NULL; + +PyDoc_STRVAR(module_doc, +"The io module provides the Python interfaces to stream handling. The\n" +"builtin open function is defined in this module.\n" +"\n" +"At the top of the I/O hierarchy is the abstract base class IOBase. It\n" +"defines the basic interface to a stream. Note, however, that there is no\n" +"separation between reading and writing to streams; implementations are\n" +"allowed to raise an OSError if they do not support a given operation.\n" +"\n" +"Extending IOBase is RawIOBase which deals simply with the reading and\n" +"writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide\n" +"an interface to OS files.\n" +"\n" +"BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n" +"subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer\n" +"streams that are readable, writable, and both respectively.\n" +"BufferedRandom provides a buffered interface to random access\n" +"streams. BytesIO is a simple stream of in-memory bytes.\n" +"\n" +"Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n" +"of streams into text. TextIOWrapper, which extends it, is a buffered text\n" +"interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n" +"is an in-memory stream for text.\n" +"\n" +"Argument names are not part of the specification, and only the arguments\n" +"of open() are intended to be used as keyword arguments.\n" +"\n" +"data:\n" +"\n" +"DEFAULT_BUFFER_SIZE\n" +"\n" +" An int containing the default buffer size used by the module's buffered\n" +" I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n" +" possible.\n" + ); + + +/* + * The main open() function + */ +/*[clinic input] +module _io + +_io.open + file: object + mode: str = "r" + buffering: int = -1 encoding: str(accept={str, NoneType}) = None errors: str(accept={str, NoneType}) = None newline: str(accept={str, NoneType}) = None - closefd: bool(accept={int}) = True - opener: object = None - -Open file and return a stream. Raise OSError upon failure. - -file is either a text or byte string giving the name (and the path -if the file isn't in the current working directory) of the file to -be opened or an integer file descriptor of the file to be -wrapped. (If a file descriptor is given, it is closed when the -returned I/O object is closed, unless closefd is set to False.) - -mode is an optional string that specifies the mode in which the file -is opened. It defaults to 'r' which means open for reading in text -mode. Other common values are 'w' for writing (truncating the file if -it already exists), 'x' for creating and writing to a new file, and -'a' for appending (which on some Unix systems, means that all writes -append to the end of the file regardless of the current seek position). -In text mode, if encoding is not specified the encoding used is platform -dependent: locale.getpreferredencoding(False) is called to get the -current locale encoding. (For reading and writing raw bytes use binary -mode and leave encoding unspecified.) The available modes are: - -========= =============================================================== -Character Meaning ---------- --------------------------------------------------------------- -'r' open for reading (default) -'w' open for writing, truncating the file first -'x' create a new file and open it for writing -'a' open for writing, appending to the end of the file if it exists -'b' binary mode -'t' text mode (default) -'+' open a disk file for updating (reading and writing) -'U' universal newline mode (deprecated) -========= =============================================================== - -The default mode is 'rt' (open for reading text). For binary random -access, the mode 'w+b' opens and truncates the file to 0 bytes, while -'r+b' opens the file without truncation. The 'x' mode implies 'w' and -raises an `FileExistsError` if the file already exists. - -Python distinguishes between files opened in binary and text modes, -even when the underlying operating system doesn't. Files opened in -binary mode (appending 'b' to the mode argument) return contents as -bytes objects without any decoding. In text mode (the default, or when -'t' is appended to the mode argument), the contents of the file are -returned as strings, the bytes having been first decoded using a -platform-dependent encoding or using the specified encoding if given. - -'U' mode is deprecated and will raise an exception in future versions -of Python. It has no effect in Python 3. Use newline to control -universal newlines mode. - -buffering is an optional integer used to set the buffering policy. -Pass 0 to switch buffering off (only allowed in binary mode), 1 to select -line buffering (only usable in text mode), and an integer > 1 to indicate -the size of a fixed-size chunk buffer. When no buffering argument is -given, the default buffering policy works as follows: - -* Binary files are buffered in fixed-size chunks; the size of the buffer - is chosen using a heuristic trying to determine the underlying device's - "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`. - On many systems, the buffer will typically be 4096 or 8192 bytes long. - -* "Interactive" text files (files for which isatty() returns True) - use line buffering. Other text files use the policy described above - for binary files. - -encoding is the name of the encoding used to decode or encode the -file. This should only be used in text mode. The default encoding is -platform dependent, but any encoding supported by Python can be -passed. See the codecs module for the list of supported encodings. - -errors is an optional string that specifies how encoding errors are to -be handled---this argument should not be used in binary mode. Pass -'strict' to raise a ValueError exception if there is an encoding error -(the default of None has the same effect), or pass 'ignore' to ignore -errors. (Note that ignoring encoding errors can lead to data loss.) -See the documentation for codecs.register or run 'help(codecs.Codec)' -for a list of the permitted encoding error strings. - -newline controls how universal newlines works (it only applies to text -mode). It can be None, '', '\n', '\r', and '\r\n'. It works as -follows: - -* On input, if newline is None, universal newlines mode is - enabled. Lines in the input can end in '\n', '\r', or '\r\n', and - these are translated into '\n' before being returned to the - caller. If it is '', universal newline mode is enabled, but line - endings are returned to the caller untranslated. If it has any of - the other legal values, input lines are only terminated by the given - string, and the line ending is returned to the caller untranslated. - -* On output, if newline is None, any '\n' characters written are - translated to the system default line separator, os.linesep. If - newline is '' or '\n', no translation takes place. If newline is any - of the other legal values, any '\n' characters written are translated - to the given string. - -If closefd is False, the underlying file descriptor will be kept open -when the file is closed. This does not work when a file name is given -and must be True in that case. - -A custom opener can be used by passing a callable as *opener*. The -underlying file descriptor for the file object is then obtained by -calling *opener* with (*file*, *flags*). *opener* must return an open -file descriptor (passing os.open as *opener* results in functionality -similar to passing None). - -open() returns a file object whose type depends on the mode, and -through which the standard file operations such as reading and writing -are performed. When open() is used to open a file in a text mode ('w', -'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open -a file in a binary mode, the returned class varies: in read binary -mode, it returns a BufferedReader; in write binary and append binary -modes, it returns a BufferedWriter, and in read/write mode, it returns -a BufferedRandom. - -It is also possible to use a string or bytearray as a file for both -reading and writing. For strings StringIO can be used like a file -opened in a text mode, and for bytes a BytesIO can be used like a file -opened in a binary mode. -[clinic start generated code]*/ - -static PyObject * -_io_open_impl(PyObject *module, PyObject *file, const char *mode, - int buffering, const char *encoding, const char *errors, - const char *newline, int closefd, PyObject *opener) + closefd: bool(accept={int}) = True + opener: object = None + +Open file and return a stream. Raise OSError upon failure. + +file is either a text or byte string giving the name (and the path +if the file isn't in the current working directory) of the file to +be opened or an integer file descriptor of the file to be +wrapped. (If a file descriptor is given, it is closed when the +returned I/O object is closed, unless closefd is set to False.) + +mode is an optional string that specifies the mode in which the file +is opened. It defaults to 'r' which means open for reading in text +mode. Other common values are 'w' for writing (truncating the file if +it already exists), 'x' for creating and writing to a new file, and +'a' for appending (which on some Unix systems, means that all writes +append to the end of the file regardless of the current seek position). +In text mode, if encoding is not specified the encoding used is platform +dependent: locale.getpreferredencoding(False) is called to get the +current locale encoding. (For reading and writing raw bytes use binary +mode and leave encoding unspecified.) The available modes are: + +========= =============================================================== +Character Meaning +--------- --------------------------------------------------------------- +'r' open for reading (default) +'w' open for writing, truncating the file first +'x' create a new file and open it for writing +'a' open for writing, appending to the end of the file if it exists +'b' binary mode +'t' text mode (default) +'+' open a disk file for updating (reading and writing) +'U' universal newline mode (deprecated) +========= =============================================================== + +The default mode is 'rt' (open for reading text). For binary random +access, the mode 'w+b' opens and truncates the file to 0 bytes, while +'r+b' opens the file without truncation. The 'x' mode implies 'w' and +raises an `FileExistsError` if the file already exists. + +Python distinguishes between files opened in binary and text modes, +even when the underlying operating system doesn't. Files opened in +binary mode (appending 'b' to the mode argument) return contents as +bytes objects without any decoding. In text mode (the default, or when +'t' is appended to the mode argument), the contents of the file are +returned as strings, the bytes having been first decoded using a +platform-dependent encoding or using the specified encoding if given. + +'U' mode is deprecated and will raise an exception in future versions +of Python. It has no effect in Python 3. Use newline to control +universal newlines mode. + +buffering is an optional integer used to set the buffering policy. +Pass 0 to switch buffering off (only allowed in binary mode), 1 to select +line buffering (only usable in text mode), and an integer > 1 to indicate +the size of a fixed-size chunk buffer. When no buffering argument is +given, the default buffering policy works as follows: + +* Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + +* "Interactive" text files (files for which isatty() returns True) + use line buffering. Other text files use the policy described above + for binary files. + +encoding is the name of the encoding used to decode or encode the +file. This should only be used in text mode. The default encoding is +platform dependent, but any encoding supported by Python can be +passed. See the codecs module for the list of supported encodings. + +errors is an optional string that specifies how encoding errors are to +be handled---this argument should not be used in binary mode. Pass +'strict' to raise a ValueError exception if there is an encoding error +(the default of None has the same effect), or pass 'ignore' to ignore +errors. (Note that ignoring encoding errors can lead to data loss.) +See the documentation for codecs.register or run 'help(codecs.Codec)' +for a list of the permitted encoding error strings. + +newline controls how universal newlines works (it only applies to text +mode). It can be None, '', '\n', '\r', and '\r\n'. It works as +follows: + +* On input, if newline is None, universal newlines mode is + enabled. Lines in the input can end in '\n', '\r', or '\r\n', and + these are translated into '\n' before being returned to the + caller. If it is '', universal newline mode is enabled, but line + endings are returned to the caller untranslated. If it has any of + the other legal values, input lines are only terminated by the given + string, and the line ending is returned to the caller untranslated. + +* On output, if newline is None, any '\n' characters written are + translated to the system default line separator, os.linesep. If + newline is '' or '\n', no translation takes place. If newline is any + of the other legal values, any '\n' characters written are translated + to the given string. + +If closefd is False, the underlying file descriptor will be kept open +when the file is closed. This does not work when a file name is given +and must be True in that case. + +A custom opener can be used by passing a callable as *opener*. The +underlying file descriptor for the file object is then obtained by +calling *opener* with (*file*, *flags*). *opener* must return an open +file descriptor (passing os.open as *opener* results in functionality +similar to passing None). + +open() returns a file object whose type depends on the mode, and +through which the standard file operations such as reading and writing +are performed. When open() is used to open a file in a text mode ('w', +'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open +a file in a binary mode, the returned class varies: in read binary +mode, it returns a BufferedReader; in write binary and append binary +modes, it returns a BufferedWriter, and in read/write mode, it returns +a BufferedRandom. + +It is also possible to use a string or bytearray as a file for both +reading and writing. For strings StringIO can be used like a file +opened in a text mode, and for bytes a BytesIO can be used like a file +opened in a binary mode. +[clinic start generated code]*/ + +static PyObject * +_io_open_impl(PyObject *module, PyObject *file, const char *mode, + int buffering, const char *encoding, const char *errors, + const char *newline, int closefd, PyObject *opener) /*[clinic end generated code: output=aefafc4ce2b46dc0 input=7295902222e6b311]*/ -{ - unsigned i; - - int creating = 0, reading = 0, writing = 0, appending = 0, updating = 0; - int text = 0, binary = 0, universal = 0; - - char rawmode[6], *m; - int line_buffering, is_number; +{ + unsigned i; + + int creating = 0, reading = 0, writing = 0, appending = 0, updating = 0; + int text = 0, binary = 0, universal = 0; + + char rawmode[6], *m; + int line_buffering, is_number; long isatty = 0; - - PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL; - - _Py_IDENTIFIER(_blksize); - _Py_IDENTIFIER(isatty); - _Py_IDENTIFIER(mode); - _Py_IDENTIFIER(close); - - is_number = PyNumber_Check(file); - - if (is_number) { - path_or_fd = file; - Py_INCREF(path_or_fd); - } else { - path_or_fd = PyOS_FSPath(file); - if (path_or_fd == NULL) { - return NULL; - } - } - - if (!is_number && - !PyUnicode_Check(path_or_fd) && - !PyBytes_Check(path_or_fd)) { - PyErr_Format(PyExc_TypeError, "invalid file: %R", file); - goto error; - } - - /* Decode mode */ - for (i = 0; i < strlen(mode); i++) { - char c = mode[i]; - - switch (c) { - case 'x': - creating = 1; - break; - case 'r': - reading = 1; - break; - case 'w': - writing = 1; - break; - case 'a': - appending = 1; - break; - case '+': - updating = 1; - break; - case 't': - text = 1; - break; - case 'b': - binary = 1; - break; - case 'U': - universal = 1; - reading = 1; - break; - default: - goto invalid_mode; - } - - /* c must not be duplicated */ - if (strchr(mode+i+1, c)) { - invalid_mode: - PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode); - goto error; - } - - } - - m = rawmode; - if (creating) *(m++) = 'x'; - if (reading) *(m++) = 'r'; - if (writing) *(m++) = 'w'; - if (appending) *(m++) = 'a'; - if (updating) *(m++) = '+'; - *m = '\0'; - - /* Parameters validation */ - if (universal) { - if (creating || writing || appending || updating) { - PyErr_SetString(PyExc_ValueError, + + PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL; + + _Py_IDENTIFIER(_blksize); + _Py_IDENTIFIER(isatty); + _Py_IDENTIFIER(mode); + _Py_IDENTIFIER(close); + + is_number = PyNumber_Check(file); + + if (is_number) { + path_or_fd = file; + Py_INCREF(path_or_fd); + } else { + path_or_fd = PyOS_FSPath(file); + if (path_or_fd == NULL) { + return NULL; + } + } + + if (!is_number && + !PyUnicode_Check(path_or_fd) && + !PyBytes_Check(path_or_fd)) { + PyErr_Format(PyExc_TypeError, "invalid file: %R", file); + goto error; + } + + /* Decode mode */ + for (i = 0; i < strlen(mode); i++) { + char c = mode[i]; + + switch (c) { + case 'x': + creating = 1; + break; + case 'r': + reading = 1; + break; + case 'w': + writing = 1; + break; + case 'a': + appending = 1; + break; + case '+': + updating = 1; + break; + case 't': + text = 1; + break; + case 'b': + binary = 1; + break; + case 'U': + universal = 1; + reading = 1; + break; + default: + goto invalid_mode; + } + + /* c must not be duplicated */ + if (strchr(mode+i+1, c)) { + invalid_mode: + PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode); + goto error; + } + + } + + m = rawmode; + if (creating) *(m++) = 'x'; + if (reading) *(m++) = 'r'; + if (writing) *(m++) = 'w'; + if (appending) *(m++) = 'a'; + if (updating) *(m++) = '+'; + *m = '\0'; + + /* Parameters validation */ + if (universal) { + if (creating || writing || appending || updating) { + PyErr_SetString(PyExc_ValueError, "mode U cannot be combined with 'x', 'w', 'a', or '+'"); - goto error; - } - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "'U' mode is deprecated", 1) < 0) - goto error; - reading = 1; - } - - if (text && binary) { - PyErr_SetString(PyExc_ValueError, - "can't have text and binary mode at once"); - goto error; - } - - if (creating + reading + writing + appending > 1) { - PyErr_SetString(PyExc_ValueError, - "must have exactly one of create/read/write/append mode"); - goto error; - } - - if (binary && encoding != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take an encoding argument"); - goto error; - } - - if (binary && errors != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take an errors argument"); - goto error; - } - - if (binary && newline != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take a newline argument"); - goto error; - } - + goto error; + } + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "'U' mode is deprecated", 1) < 0) + goto error; + reading = 1; + } + + if (text && binary) { + PyErr_SetString(PyExc_ValueError, + "can't have text and binary mode at once"); + goto error; + } + + if (creating + reading + writing + appending > 1) { + PyErr_SetString(PyExc_ValueError, + "must have exactly one of create/read/write/append mode"); + goto error; + } + + if (binary && encoding != NULL) { + PyErr_SetString(PyExc_ValueError, + "binary mode doesn't take an encoding argument"); + goto error; + } + + if (binary && errors != NULL) { + PyErr_SetString(PyExc_ValueError, + "binary mode doesn't take an errors argument"); + goto error; + } + + if (binary && newline != NULL) { + PyErr_SetString(PyExc_ValueError, + "binary mode doesn't take a newline argument"); + goto error; + } + if (binary && buffering == 1) { if (PyErr_WarnEx(PyExc_RuntimeWarning, "line buffering (buffering=1) isn't supported in " @@ -371,138 +371,138 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, } } - /* Create the Raw file stream */ - { - PyObject *RawIO_class = (PyObject *)&PyFileIO_Type; -#ifdef MS_WINDOWS + /* Create the Raw file stream */ + { + PyObject *RawIO_class = (PyObject *)&PyFileIO_Type; +#ifdef MS_WINDOWS const PyConfig *config = _Py_GetConfig(); if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') { - RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type; - encoding = "utf-8"; - } -#endif + RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type; + encoding = "utf-8"; + } +#endif raw = PyObject_CallFunction(RawIO_class, "OsOO", path_or_fd, rawmode, closefd ? Py_True : Py_False, opener); - } - - if (raw == NULL) - goto error; - result = raw; - - Py_DECREF(path_or_fd); - path_or_fd = NULL; - - modeobj = PyUnicode_FromString(mode); - if (modeobj == NULL) - goto error; - - /* buffering */ + } + + if (raw == NULL) + goto error; + result = raw; + + Py_DECREF(path_or_fd); + path_or_fd = NULL; + + modeobj = PyUnicode_FromString(mode); + if (modeobj == NULL) + goto error; + + /* buffering */ if (buffering < 0) { PyObject *res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty); - if (res == NULL) - goto error; - isatty = PyLong_AsLong(res); - Py_DECREF(res); - if (isatty == -1 && PyErr_Occurred()) - goto error; - } - + if (res == NULL) + goto error; + isatty = PyLong_AsLong(res); + Py_DECREF(res); + if (isatty == -1 && PyErr_Occurred()) + goto error; + } + if (buffering == 1 || isatty) { - buffering = -1; - line_buffering = 1; - } - else - line_buffering = 0; - - if (buffering < 0) { - PyObject *blksize_obj; - blksize_obj = _PyObject_GetAttrId(raw, &PyId__blksize); - if (blksize_obj == NULL) - goto error; - buffering = PyLong_AsLong(blksize_obj); - Py_DECREF(blksize_obj); - if (buffering == -1 && PyErr_Occurred()) - goto error; - } - if (buffering < 0) { - PyErr_SetString(PyExc_ValueError, - "invalid buffering size"); - goto error; - } - - /* if not buffering, returns the raw file object */ - if (buffering == 0) { - if (!binary) { - PyErr_SetString(PyExc_ValueError, - "can't have unbuffered text I/O"); - goto error; - } - - Py_DECREF(modeobj); - return result; - } - - /* wraps into a buffered file */ - { - PyObject *Buffered_class; - - if (updating) - Buffered_class = (PyObject *)&PyBufferedRandom_Type; - else if (creating || writing || appending) - Buffered_class = (PyObject *)&PyBufferedWriter_Type; - else if (reading) - Buffered_class = (PyObject *)&PyBufferedReader_Type; - else { - PyErr_Format(PyExc_ValueError, - "unknown mode: '%s'", mode); - goto error; - } - - buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering); - } - if (buffer == NULL) - goto error; - result = buffer; - Py_DECREF(raw); - - - /* if binary, returns the buffered file */ - if (binary) { - Py_DECREF(modeobj); - return result; - } - - /* wraps into a TextIOWrapper */ - wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type, + buffering = -1; + line_buffering = 1; + } + else + line_buffering = 0; + + if (buffering < 0) { + PyObject *blksize_obj; + blksize_obj = _PyObject_GetAttrId(raw, &PyId__blksize); + if (blksize_obj == NULL) + goto error; + buffering = PyLong_AsLong(blksize_obj); + Py_DECREF(blksize_obj); + if (buffering == -1 && PyErr_Occurred()) + goto error; + } + if (buffering < 0) { + PyErr_SetString(PyExc_ValueError, + "invalid buffering size"); + goto error; + } + + /* if not buffering, returns the raw file object */ + if (buffering == 0) { + if (!binary) { + PyErr_SetString(PyExc_ValueError, + "can't have unbuffered text I/O"); + goto error; + } + + Py_DECREF(modeobj); + return result; + } + + /* wraps into a buffered file */ + { + PyObject *Buffered_class; + + if (updating) + Buffered_class = (PyObject *)&PyBufferedRandom_Type; + else if (creating || writing || appending) + Buffered_class = (PyObject *)&PyBufferedWriter_Type; + else if (reading) + Buffered_class = (PyObject *)&PyBufferedReader_Type; + else { + PyErr_Format(PyExc_ValueError, + "unknown mode: '%s'", mode); + goto error; + } + + buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering); + } + if (buffer == NULL) + goto error; + result = buffer; + Py_DECREF(raw); + + + /* if binary, returns the buffered file */ + if (binary) { + Py_DECREF(modeobj); + return result; + } + + /* wraps into a TextIOWrapper */ + wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type, "OsssO", - buffer, - encoding, errors, newline, + buffer, + encoding, errors, newline, line_buffering ? Py_True : Py_False); - if (wrapper == NULL) - goto error; - result = wrapper; - Py_DECREF(buffer); - - if (_PyObject_SetAttrId(wrapper, &PyId_mode, modeobj) < 0) - goto error; - Py_DECREF(modeobj); - return result; - - error: - if (result != NULL) { - PyObject *exc, *val, *tb, *close_result; - PyErr_Fetch(&exc, &val, &tb); + if (wrapper == NULL) + goto error; + result = wrapper; + Py_DECREF(buffer); + + if (_PyObject_SetAttrId(wrapper, &PyId_mode, modeobj) < 0) + goto error; + Py_DECREF(modeobj); + return result; + + error: + if (result != NULL) { + PyObject *exc, *val, *tb, *close_result; + PyErr_Fetch(&exc, &val, &tb); close_result = _PyObject_CallMethodIdNoArgs(result, &PyId_close); - _PyErr_ChainExceptions(exc, val, tb); - Py_XDECREF(close_result); - Py_DECREF(result); - } - Py_XDECREF(path_or_fd); - Py_XDECREF(modeobj); - return NULL; -} + _PyErr_ChainExceptions(exc, val, tb); + Py_XDECREF(close_result); + Py_DECREF(result); + } + Py_XDECREF(path_or_fd); + Py_XDECREF(modeobj); + return NULL; +} /*[clinic input] _io.open_code @@ -522,55 +522,55 @@ _io_open_code_impl(PyObject *module, PyObject *path) { return PyFile_OpenCodeObject(path); } - -/* - * Private helpers for the io module. - */ - -Py_off_t -PyNumber_AsOff_t(PyObject *item, PyObject *err) -{ - Py_off_t result; - PyObject *runerr; - PyObject *value = PyNumber_Index(item); - if (value == NULL) - return -1; - - /* We're done if PyLong_AsSsize_t() returns without error. */ - result = PyLong_AsOff_t(value); - if (result != -1 || !(runerr = PyErr_Occurred())) - goto finish; - - /* Error handling code -- only manage OverflowError differently */ - if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) - goto finish; - - PyErr_Clear(); - /* If no error-handling desired then the default clipping - is sufficient. - */ - if (!err) { - assert(PyLong_Check(value)); - /* Whether or not it is less than or equal to - zero is determined by the sign of ob_size - */ - if (_PyLong_Sign(value) < 0) - result = PY_OFF_T_MIN; - else - result = PY_OFF_T_MAX; - } - else { - /* Otherwise replace the error with caller's error object. */ - PyErr_Format(err, - "cannot fit '%.200s' into an offset-sized integer", + +/* + * Private helpers for the io module. + */ + +Py_off_t +PyNumber_AsOff_t(PyObject *item, PyObject *err) +{ + Py_off_t result; + PyObject *runerr; + PyObject *value = PyNumber_Index(item); + if (value == NULL) + return -1; + + /* We're done if PyLong_AsSsize_t() returns without error. */ + result = PyLong_AsOff_t(value); + if (result != -1 || !(runerr = PyErr_Occurred())) + goto finish; + + /* Error handling code -- only manage OverflowError differently */ + if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) + goto finish; + + PyErr_Clear(); + /* If no error-handling desired then the default clipping + is sufficient. + */ + if (!err) { + assert(PyLong_Check(value)); + /* Whether or not it is less than or equal to + zero is determined by the sign of ob_size + */ + if (_PyLong_Sign(value) < 0) + result = PY_OFF_T_MIN; + else + result = PY_OFF_T_MAX; + } + else { + /* Otherwise replace the error with caller's error object. */ + PyErr_Format(err, + "cannot fit '%.200s' into an offset-sized integer", Py_TYPE(item)->tp_name); - } - - finish: - Py_DECREF(value); - return result; -} - + } + + finish: + Py_DECREF(value); + return result; +} + static inline _PyIO_State* get_io_state(PyObject *module) { @@ -578,236 +578,236 @@ get_io_state(PyObject *module) assert(state != NULL); return (_PyIO_State *)state; } - -_PyIO_State * -_PyIO_get_module_state(void) -{ - PyObject *mod = PyState_FindModule(&_PyIO_Module); - _PyIO_State *state; + +_PyIO_State * +_PyIO_get_module_state(void) +{ + PyObject *mod = PyState_FindModule(&_PyIO_Module); + _PyIO_State *state; if (mod == NULL || (state = get_io_state(mod)) == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "could not find io module state " - "(interpreter shutdown?)"); - return NULL; - } - return state; -} - -PyObject * -_PyIO_get_locale_module(_PyIO_State *state) -{ - PyObject *mod; - if (state->locale_module != NULL) { - assert(PyWeakref_CheckRef(state->locale_module)); - mod = PyWeakref_GET_OBJECT(state->locale_module); - if (mod != Py_None) { - Py_INCREF(mod); - return mod; - } - Py_CLEAR(state->locale_module); - } - mod = PyImport_ImportModule("_bootlocale"); - if (mod == NULL) - return NULL; - state->locale_module = PyWeakref_NewRef(mod, NULL); - if (state->locale_module == NULL) { - Py_DECREF(mod); - return NULL; - } - return mod; -} - - -static int -iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { + PyErr_SetString(PyExc_RuntimeError, + "could not find io module state " + "(interpreter shutdown?)"); + return NULL; + } + return state; +} + +PyObject * +_PyIO_get_locale_module(_PyIO_State *state) +{ + PyObject *mod; + if (state->locale_module != NULL) { + assert(PyWeakref_CheckRef(state->locale_module)); + mod = PyWeakref_GET_OBJECT(state->locale_module); + if (mod != Py_None) { + Py_INCREF(mod); + return mod; + } + Py_CLEAR(state->locale_module); + } + mod = PyImport_ImportModule("_bootlocale"); + if (mod == NULL) + return NULL; + state->locale_module = PyWeakref_NewRef(mod, NULL); + if (state->locale_module == NULL) { + Py_DECREF(mod); + return NULL; + } + return mod; +} + + +static int +iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { _PyIO_State *state = get_io_state(mod); - if (!state->initialized) - return 0; - if (state->locale_module != NULL) { - Py_VISIT(state->locale_module); - } - Py_VISIT(state->unsupported_operation); - return 0; -} - - -static int -iomodule_clear(PyObject *mod) { + if (!state->initialized) + return 0; + if (state->locale_module != NULL) { + Py_VISIT(state->locale_module); + } + Py_VISIT(state->unsupported_operation); + return 0; +} + + +static int +iomodule_clear(PyObject *mod) { _PyIO_State *state = get_io_state(mod); - if (!state->initialized) - return 0; - if (state->locale_module != NULL) - Py_CLEAR(state->locale_module); - Py_CLEAR(state->unsupported_operation); - return 0; -} - -static void -iomodule_free(PyObject *mod) { - iomodule_clear(mod); -} - - -/* - * Module definition - */ - -#include "clinic/_iomodule.c.h" - -static PyMethodDef module_methods[] = { - _IO_OPEN_METHODDEF + if (!state->initialized) + return 0; + if (state->locale_module != NULL) + Py_CLEAR(state->locale_module); + Py_CLEAR(state->unsupported_operation); + return 0; +} + +static void +iomodule_free(PyObject *mod) { + iomodule_clear(mod); +} + + +/* + * Module definition + */ + +#include "clinic/_iomodule.c.h" + +static PyMethodDef module_methods[] = { + _IO_OPEN_METHODDEF _IO_OPEN_CODE_METHODDEF - {NULL, NULL} -}; - -struct PyModuleDef _PyIO_Module = { - PyModuleDef_HEAD_INIT, - "io", - module_doc, - sizeof(_PyIO_State), - module_methods, - NULL, - iomodule_traverse, - iomodule_clear, - (freefunc)iomodule_free, -}; - -PyMODINIT_FUNC -PyInit__io(void) -{ - PyObject *m = PyModule_Create(&_PyIO_Module); - _PyIO_State *state = NULL; - if (m == NULL) - return NULL; + {NULL, NULL} +}; + +struct PyModuleDef _PyIO_Module = { + PyModuleDef_HEAD_INIT, + "io", + module_doc, + sizeof(_PyIO_State), + module_methods, + NULL, + iomodule_traverse, + iomodule_clear, + (freefunc)iomodule_free, +}; + +PyMODINIT_FUNC +PyInit__io(void) +{ + PyObject *m = PyModule_Create(&_PyIO_Module); + _PyIO_State *state = NULL; + if (m == NULL) + return NULL; state = get_io_state(m); - state->initialized = 0; - + state->initialized = 0; + #define ADD_TYPE(type) \ if (PyModule_AddType(m, type) < 0) { \ - goto fail; \ - } - - /* DEFAULT_BUFFER_SIZE */ - if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0) - goto fail; - - /* UnsupportedOperation inherits from ValueError and OSError */ - state->unsupported_operation = PyObject_CallFunction( - (PyObject *)&PyType_Type, "s(OO){}", - "UnsupportedOperation", PyExc_OSError, PyExc_ValueError); - if (state->unsupported_operation == NULL) - goto fail; - Py_INCREF(state->unsupported_operation); - if (PyModule_AddObject(m, "UnsupportedOperation", - state->unsupported_operation) < 0) - goto fail; - - /* BlockingIOError, for compatibility */ - Py_INCREF(PyExc_BlockingIOError); - if (PyModule_AddObject(m, "BlockingIOError", - (PyObject *) PyExc_BlockingIOError) < 0) - goto fail; - - /* Concrete base types of the IO ABCs. - (the ABCs themselves are declared through inheritance in io.py) - */ + goto fail; \ + } + + /* DEFAULT_BUFFER_SIZE */ + if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0) + goto fail; + + /* UnsupportedOperation inherits from ValueError and OSError */ + state->unsupported_operation = PyObject_CallFunction( + (PyObject *)&PyType_Type, "s(OO){}", + "UnsupportedOperation", PyExc_OSError, PyExc_ValueError); + if (state->unsupported_operation == NULL) + goto fail; + Py_INCREF(state->unsupported_operation); + if (PyModule_AddObject(m, "UnsupportedOperation", + state->unsupported_operation) < 0) + goto fail; + + /* BlockingIOError, for compatibility */ + Py_INCREF(PyExc_BlockingIOError); + if (PyModule_AddObject(m, "BlockingIOError", + (PyObject *) PyExc_BlockingIOError) < 0) + goto fail; + + /* Concrete base types of the IO ABCs. + (the ABCs themselves are declared through inheritance in io.py) + */ ADD_TYPE(&PyIOBase_Type); ADD_TYPE(&PyRawIOBase_Type); ADD_TYPE(&PyBufferedIOBase_Type); ADD_TYPE(&PyTextIOBase_Type); - - /* Implementation of concrete IO objects. */ - /* FileIO */ - PyFileIO_Type.tp_base = &PyRawIOBase_Type; + + /* Implementation of concrete IO objects. */ + /* FileIO */ + PyFileIO_Type.tp_base = &PyRawIOBase_Type; ADD_TYPE(&PyFileIO_Type); - - /* BytesIO */ - PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; + + /* BytesIO */ + PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBytesIO_Type); - if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0) - goto fail; - - /* StringIO */ - PyStringIO_Type.tp_base = &PyTextIOBase_Type; + if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0) + goto fail; + + /* StringIO */ + PyStringIO_Type.tp_base = &PyTextIOBase_Type; ADD_TYPE(&PyStringIO_Type); - -#ifdef MS_WINDOWS - /* WindowsConsoleIO */ - PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type; + +#ifdef MS_WINDOWS + /* WindowsConsoleIO */ + PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type; ADD_TYPE(&PyWindowsConsoleIO_Type); -#endif - - /* BufferedReader */ - PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; +#endif + + /* BufferedReader */ + PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBufferedReader_Type); - - /* BufferedWriter */ - PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type; + + /* BufferedWriter */ + PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBufferedWriter_Type); - - /* BufferedRWPair */ - PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type; + + /* BufferedRWPair */ + PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBufferedRWPair_Type); - - /* BufferedRandom */ - PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type; + + /* BufferedRandom */ + PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBufferedRandom_Type); - - /* TextIOWrapper */ - PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type; + + /* TextIOWrapper */ + PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type; ADD_TYPE(&PyTextIOWrapper_Type); - - /* IncrementalNewlineDecoder */ + + /* IncrementalNewlineDecoder */ ADD_TYPE(&PyIncrementalNewlineDecoder_Type); - - /* Interned strings */ -#define ADD_INTERNED(name) \ - if (!_PyIO_str_ ## name && \ - !(_PyIO_str_ ## name = PyUnicode_InternFromString(# name))) \ - goto fail; - - ADD_INTERNED(close) - ADD_INTERNED(closed) - ADD_INTERNED(decode) - ADD_INTERNED(encode) - ADD_INTERNED(fileno) - ADD_INTERNED(flush) - ADD_INTERNED(getstate) - ADD_INTERNED(isatty) - ADD_INTERNED(newlines) - ADD_INTERNED(peek) - ADD_INTERNED(read) - ADD_INTERNED(read1) - ADD_INTERNED(readable) - ADD_INTERNED(readall) - ADD_INTERNED(readinto) - ADD_INTERNED(readline) - ADD_INTERNED(reset) - ADD_INTERNED(seek) - ADD_INTERNED(seekable) - ADD_INTERNED(setstate) - ADD_INTERNED(tell) - ADD_INTERNED(truncate) - ADD_INTERNED(write) - ADD_INTERNED(writable) - - if (!_PyIO_str_nl && - !(_PyIO_str_nl = PyUnicode_InternFromString("\n"))) - goto fail; - - if (!_PyIO_empty_str && - !(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) - goto fail; - if (!_PyIO_empty_bytes && - !(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) - goto fail; - - state->initialized = 1; - - return m; - - fail: - Py_XDECREF(state->unsupported_operation); - Py_DECREF(m); - return NULL; -} + + /* Interned strings */ +#define ADD_INTERNED(name) \ + if (!_PyIO_str_ ## name && \ + !(_PyIO_str_ ## name = PyUnicode_InternFromString(# name))) \ + goto fail; + + ADD_INTERNED(close) + ADD_INTERNED(closed) + ADD_INTERNED(decode) + ADD_INTERNED(encode) + ADD_INTERNED(fileno) + ADD_INTERNED(flush) + ADD_INTERNED(getstate) + ADD_INTERNED(isatty) + ADD_INTERNED(newlines) + ADD_INTERNED(peek) + ADD_INTERNED(read) + ADD_INTERNED(read1) + ADD_INTERNED(readable) + ADD_INTERNED(readall) + ADD_INTERNED(readinto) + ADD_INTERNED(readline) + ADD_INTERNED(reset) + ADD_INTERNED(seek) + ADD_INTERNED(seekable) + ADD_INTERNED(setstate) + ADD_INTERNED(tell) + ADD_INTERNED(truncate) + ADD_INTERNED(write) + ADD_INTERNED(writable) + + if (!_PyIO_str_nl && + !(_PyIO_str_nl = PyUnicode_InternFromString("\n"))) + goto fail; + + if (!_PyIO_empty_str && + !(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) + goto fail; + if (!_PyIO_empty_bytes && + !(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) + goto fail; + + state->initialized = 1; + + return m; + + fail: + Py_XDECREF(state->unsupported_operation); + Py_DECREF(m); + return NULL; +} diff --git a/contrib/tools/python3/src/Modules/_io/_iomodule.h b/contrib/tools/python3/src/Modules/_io/_iomodule.h index a8f3951e57f..947fbf5ac32 100644 --- a/contrib/tools/python3/src/Modules/_io/_iomodule.h +++ b/contrib/tools/python3/src/Modules/_io/_iomodule.h @@ -1,188 +1,188 @@ -/* - * Declarations shared between the different parts of the io module - */ - +/* + * Declarations shared between the different parts of the io module + */ + #include "exports.h" -/* ABCs */ -extern PyTypeObject PyIOBase_Type; -extern PyTypeObject PyRawIOBase_Type; -extern PyTypeObject PyBufferedIOBase_Type; -extern PyTypeObject PyTextIOBase_Type; - -/* Concrete classes */ -extern PyTypeObject PyFileIO_Type; -extern PyTypeObject PyBytesIO_Type; -extern PyTypeObject PyStringIO_Type; -extern PyTypeObject PyBufferedReader_Type; -extern PyTypeObject PyBufferedWriter_Type; -extern PyTypeObject PyBufferedRWPair_Type; -extern PyTypeObject PyBufferedRandom_Type; -extern PyTypeObject PyTextIOWrapper_Type; -extern PyTypeObject PyIncrementalNewlineDecoder_Type; - -#ifndef Py_LIMITED_API -#ifdef MS_WINDOWS -extern PyTypeObject PyWindowsConsoleIO_Type; -PyAPI_DATA(PyObject *) _PyWindowsConsoleIO_Type; -#define PyWindowsConsoleIO_Check(op) (PyObject_TypeCheck((op), (PyTypeObject*)_PyWindowsConsoleIO_Type)) -#endif /* MS_WINDOWS */ -#endif /* Py_LIMITED_API */ - -/* These functions are used as METH_NOARGS methods, are normally called - * with args=NULL, and return a new reference. - * BUT when args=Py_True is passed, they return a borrowed reference. - */ -extern PyObject* _PyIOBase_check_readable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_writable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_seekable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args); - -/* Helper for finalization. - This function will revive an object ready to be deallocated and try to - close() it. It returns 0 if the object can be destroyed, or -1 if it - is alive again. */ -extern int _PyIOBase_finalize(PyObject *self); - -/* Returns true if the given FileIO object is closed. - Doesn't check the argument type, so be careful! */ -extern int _PyFileIO_closed(PyObject *self); - -/* Shortcut to the core of the IncrementalNewlineDecoder.decode method */ -extern PyObject *_PyIncrementalNewlineDecoder_decode( - PyObject *self, PyObject *input, int final); - -/* Finds the first line ending between `start` and `end`. - If found, returns the index after the line ending and doesn't touch - `*consumed`. - If not found, returns -1 and sets `*consumed` to the number of characters - which can be safely put aside until another search. - - NOTE: for performance reasons, `end` must point to a NUL character ('\0'). - Otherwise, the function will scan further and return garbage. - - There are three modes, in order of priority: - * translated: Only find \n (assume newlines already translated) - * universal: Use universal newlines algorithm - * Otherwise, the line ending is specified by readnl, a str object */ -extern Py_ssize_t _PyIO_find_line_ending( - int translated, int universal, PyObject *readnl, - int kind, const char *start, const char *end, Py_ssize_t *consumed); - -/* Return 1 if an OSError with errno == EINTR is set (and then - clears the error indicator), 0 otherwise. - Should only be called when PyErr_Occurred() is true. -*/ -extern int _PyIO_trap_eintr(void); - -#define DEFAULT_BUFFER_SIZE (8 * 1024) /* bytes */ - -/* - * Offset type for positioning. - */ - -/* Printing a variable of type off_t (with e.g., PyUnicode_FromFormat) - correctly and without producing compiler warnings is surprisingly painful. - We identify an integer type whose size matches off_t and then: (1) cast the - off_t to that integer type and (2) use the appropriate conversion - specification. The cast is necessary: gcc complains about formatting a - long with "%lld" even when both long and long long have the same - precision. */ - -#ifdef MS_WINDOWS - -/* Windows uses long long for offsets */ -typedef long long Py_off_t; -# define PyLong_AsOff_t PyLong_AsLongLong -# define PyLong_FromOff_t PyLong_FromLongLong -# define PY_OFF_T_MAX LLONG_MAX -# define PY_OFF_T_MIN LLONG_MIN -# define PY_OFF_T_COMPAT long long /* type compatible with off_t */ -# define PY_PRIdOFF "lld" /* format to use for that type */ - -#else - -/* Other platforms use off_t */ -typedef off_t Py_off_t; -#if (SIZEOF_OFF_T == SIZEOF_SIZE_T) -# define PyLong_AsOff_t PyLong_AsSsize_t -# define PyLong_FromOff_t PyLong_FromSsize_t -# define PY_OFF_T_MAX PY_SSIZE_T_MAX -# define PY_OFF_T_MIN PY_SSIZE_T_MIN -# define PY_OFF_T_COMPAT Py_ssize_t -# define PY_PRIdOFF "zd" -#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG) -# define PyLong_AsOff_t PyLong_AsLongLong -# define PyLong_FromOff_t PyLong_FromLongLong -# define PY_OFF_T_MAX LLONG_MAX -# define PY_OFF_T_MIN LLONG_MIN -# define PY_OFF_T_COMPAT long long -# define PY_PRIdOFF "lld" -#elif (SIZEOF_OFF_T == SIZEOF_LONG) -# define PyLong_AsOff_t PyLong_AsLong -# define PyLong_FromOff_t PyLong_FromLong -# define PY_OFF_T_MAX LONG_MAX -# define PY_OFF_T_MIN LONG_MIN -# define PY_OFF_T_COMPAT long -# define PY_PRIdOFF "ld" -#else -# error off_t does not match either size_t, long, or long long! -#endif - -#endif - -extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err); - -/* Implementation details */ - -/* IO module structure */ - -extern PyModuleDef _PyIO_Module; - -typedef struct { - int initialized; - PyObject *locale_module; - - PyObject *unsupported_operation; -} _PyIO_State; - -#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) -#define IO_STATE() _PyIO_get_module_state() - -extern _PyIO_State *_PyIO_get_module_state(void); -extern PyObject *_PyIO_get_locale_module(_PyIO_State *); - -#ifdef MS_WINDOWS -extern char _PyIO_get_console_type(PyObject *); -#endif - -extern PyObject *_PyIO_str_close; -extern PyObject *_PyIO_str_closed; -extern PyObject *_PyIO_str_decode; -extern PyObject *_PyIO_str_encode; -extern PyObject *_PyIO_str_fileno; -extern PyObject *_PyIO_str_flush; -extern PyObject *_PyIO_str_getstate; -extern PyObject *_PyIO_str_isatty; -extern PyObject *_PyIO_str_newlines; -extern PyObject *_PyIO_str_nl; -extern PyObject *_PyIO_str_peek; -extern PyObject *_PyIO_str_read; -extern PyObject *_PyIO_str_read1; -extern PyObject *_PyIO_str_readable; -extern PyObject *_PyIO_str_readall; -extern PyObject *_PyIO_str_readinto; -extern PyObject *_PyIO_str_readline; -extern PyObject *_PyIO_str_reset; -extern PyObject *_PyIO_str_seek; -extern PyObject *_PyIO_str_seekable; -extern PyObject *_PyIO_str_setstate; -extern PyObject *_PyIO_str_tell; -extern PyObject *_PyIO_str_truncate; -extern PyObject *_PyIO_str_writable; -extern PyObject *_PyIO_str_write; - -extern PyObject *_PyIO_empty_str; -extern PyObject *_PyIO_empty_bytes; - +/* ABCs */ +extern PyTypeObject PyIOBase_Type; +extern PyTypeObject PyRawIOBase_Type; +extern PyTypeObject PyBufferedIOBase_Type; +extern PyTypeObject PyTextIOBase_Type; + +/* Concrete classes */ +extern PyTypeObject PyFileIO_Type; +extern PyTypeObject PyBytesIO_Type; +extern PyTypeObject PyStringIO_Type; +extern PyTypeObject PyBufferedReader_Type; +extern PyTypeObject PyBufferedWriter_Type; +extern PyTypeObject PyBufferedRWPair_Type; +extern PyTypeObject PyBufferedRandom_Type; +extern PyTypeObject PyTextIOWrapper_Type; +extern PyTypeObject PyIncrementalNewlineDecoder_Type; + +#ifndef Py_LIMITED_API +#ifdef MS_WINDOWS +extern PyTypeObject PyWindowsConsoleIO_Type; +PyAPI_DATA(PyObject *) _PyWindowsConsoleIO_Type; +#define PyWindowsConsoleIO_Check(op) (PyObject_TypeCheck((op), (PyTypeObject*)_PyWindowsConsoleIO_Type)) +#endif /* MS_WINDOWS */ +#endif /* Py_LIMITED_API */ + +/* These functions are used as METH_NOARGS methods, are normally called + * with args=NULL, and return a new reference. + * BUT when args=Py_True is passed, they return a borrowed reference. + */ +extern PyObject* _PyIOBase_check_readable(PyObject *self, PyObject *args); +extern PyObject* _PyIOBase_check_writable(PyObject *self, PyObject *args); +extern PyObject* _PyIOBase_check_seekable(PyObject *self, PyObject *args); +extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args); + +/* Helper for finalization. + This function will revive an object ready to be deallocated and try to + close() it. It returns 0 if the object can be destroyed, or -1 if it + is alive again. */ +extern int _PyIOBase_finalize(PyObject *self); + +/* Returns true if the given FileIO object is closed. + Doesn't check the argument type, so be careful! */ +extern int _PyFileIO_closed(PyObject *self); + +/* Shortcut to the core of the IncrementalNewlineDecoder.decode method */ +extern PyObject *_PyIncrementalNewlineDecoder_decode( + PyObject *self, PyObject *input, int final); + +/* Finds the first line ending between `start` and `end`. + If found, returns the index after the line ending and doesn't touch + `*consumed`. + If not found, returns -1 and sets `*consumed` to the number of characters + which can be safely put aside until another search. + + NOTE: for performance reasons, `end` must point to a NUL character ('\0'). + Otherwise, the function will scan further and return garbage. + + There are three modes, in order of priority: + * translated: Only find \n (assume newlines already translated) + * universal: Use universal newlines algorithm + * Otherwise, the line ending is specified by readnl, a str object */ +extern Py_ssize_t _PyIO_find_line_ending( + int translated, int universal, PyObject *readnl, + int kind, const char *start, const char *end, Py_ssize_t *consumed); + +/* Return 1 if an OSError with errno == EINTR is set (and then + clears the error indicator), 0 otherwise. + Should only be called when PyErr_Occurred() is true. +*/ +extern int _PyIO_trap_eintr(void); + +#define DEFAULT_BUFFER_SIZE (8 * 1024) /* bytes */ + +/* + * Offset type for positioning. + */ + +/* Printing a variable of type off_t (with e.g., PyUnicode_FromFormat) + correctly and without producing compiler warnings is surprisingly painful. + We identify an integer type whose size matches off_t and then: (1) cast the + off_t to that integer type and (2) use the appropriate conversion + specification. The cast is necessary: gcc complains about formatting a + long with "%lld" even when both long and long long have the same + precision. */ + +#ifdef MS_WINDOWS + +/* Windows uses long long for offsets */ +typedef long long Py_off_t; +# define PyLong_AsOff_t PyLong_AsLongLong +# define PyLong_FromOff_t PyLong_FromLongLong +# define PY_OFF_T_MAX LLONG_MAX +# define PY_OFF_T_MIN LLONG_MIN +# define PY_OFF_T_COMPAT long long /* type compatible with off_t */ +# define PY_PRIdOFF "lld" /* format to use for that type */ + +#else + +/* Other platforms use off_t */ +typedef off_t Py_off_t; +#if (SIZEOF_OFF_T == SIZEOF_SIZE_T) +# define PyLong_AsOff_t PyLong_AsSsize_t +# define PyLong_FromOff_t PyLong_FromSsize_t +# define PY_OFF_T_MAX PY_SSIZE_T_MAX +# define PY_OFF_T_MIN PY_SSIZE_T_MIN +# define PY_OFF_T_COMPAT Py_ssize_t +# define PY_PRIdOFF "zd" +#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG) +# define PyLong_AsOff_t PyLong_AsLongLong +# define PyLong_FromOff_t PyLong_FromLongLong +# define PY_OFF_T_MAX LLONG_MAX +# define PY_OFF_T_MIN LLONG_MIN +# define PY_OFF_T_COMPAT long long +# define PY_PRIdOFF "lld" +#elif (SIZEOF_OFF_T == SIZEOF_LONG) +# define PyLong_AsOff_t PyLong_AsLong +# define PyLong_FromOff_t PyLong_FromLong +# define PY_OFF_T_MAX LONG_MAX +# define PY_OFF_T_MIN LONG_MIN +# define PY_OFF_T_COMPAT long +# define PY_PRIdOFF "ld" +#else +# error off_t does not match either size_t, long, or long long! +#endif + +#endif + +extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err); + +/* Implementation details */ + +/* IO module structure */ + +extern PyModuleDef _PyIO_Module; + +typedef struct { + int initialized; + PyObject *locale_module; + + PyObject *unsupported_operation; +} _PyIO_State; + +#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) +#define IO_STATE() _PyIO_get_module_state() + +extern _PyIO_State *_PyIO_get_module_state(void); +extern PyObject *_PyIO_get_locale_module(_PyIO_State *); + +#ifdef MS_WINDOWS +extern char _PyIO_get_console_type(PyObject *); +#endif + +extern PyObject *_PyIO_str_close; +extern PyObject *_PyIO_str_closed; +extern PyObject *_PyIO_str_decode; +extern PyObject *_PyIO_str_encode; +extern PyObject *_PyIO_str_fileno; +extern PyObject *_PyIO_str_flush; +extern PyObject *_PyIO_str_getstate; +extern PyObject *_PyIO_str_isatty; +extern PyObject *_PyIO_str_newlines; +extern PyObject *_PyIO_str_nl; +extern PyObject *_PyIO_str_peek; +extern PyObject *_PyIO_str_read; +extern PyObject *_PyIO_str_read1; +extern PyObject *_PyIO_str_readable; +extern PyObject *_PyIO_str_readall; +extern PyObject *_PyIO_str_readinto; +extern PyObject *_PyIO_str_readline; +extern PyObject *_PyIO_str_reset; +extern PyObject *_PyIO_str_seek; +extern PyObject *_PyIO_str_seekable; +extern PyObject *_PyIO_str_setstate; +extern PyObject *_PyIO_str_tell; +extern PyObject *_PyIO_str_truncate; +extern PyObject *_PyIO_str_writable; +extern PyObject *_PyIO_str_write; + +extern PyObject *_PyIO_empty_str; +extern PyObject *_PyIO_empty_bytes; + extern Py_EXPORTED_SYMBOL PyTypeObject _PyBytesIOBuffer_Type; diff --git a/contrib/tools/python3/src/Modules/_io/bufferedio.c b/contrib/tools/python3/src/Modules/_io/bufferedio.c index b0fe9e45891..46da7b74c9a 100644 --- a/contrib/tools/python3/src/Modules/_io/bufferedio.c +++ b/contrib/tools/python3/src/Modules/_io/bufferedio.c @@ -1,1387 +1,1387 @@ -/* - An implementation of Buffered I/O as defined by PEP 3116 - "New I/O" - - Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter, - BufferedRandom. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" +/* + An implementation of Buffered I/O as defined by PEP 3116 - "New I/O" + + Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter, + BufferedRandom. + + Written by Amaury Forgeot d'Arc and Antoine Pitrou +*/ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include "pycore_object.h" #include "structmember.h" // PyMemberDef -#include "_iomodule.h" - -/*[clinic input] -module _io -class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type" -class _io._Buffered "buffered *" "&PyBufferedIOBase_Type" -class _io.BufferedReader "buffered *" "&PyBufferedReader_Type" -class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type" -class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type" -class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/ - -_Py_IDENTIFIER(close); -_Py_IDENTIFIER(_dealloc_warn); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(isatty); -_Py_IDENTIFIER(mode); -_Py_IDENTIFIER(name); -_Py_IDENTIFIER(peek); -_Py_IDENTIFIER(read); -_Py_IDENTIFIER(read1); -_Py_IDENTIFIER(readable); -_Py_IDENTIFIER(readinto); -_Py_IDENTIFIER(readinto1); -_Py_IDENTIFIER(writable); -_Py_IDENTIFIER(write); - -/* - * BufferedIOBase class, inherits from IOBase. - */ -PyDoc_STRVAR(bufferediobase_doc, - "Base class for buffered IO objects.\n" - "\n" - "The main difference with RawIOBase is that the read() method\n" - "supports omitting the size argument, and does not have a default\n" - "implementation that defers to readinto().\n" - "\n" - "In addition, read(), readinto() and write() may raise\n" - "BlockingIOError if the underlying raw stream is in non-blocking\n" - "mode and not ready; unlike their raw counterparts, they will never\n" - "return None.\n" - "\n" - "A typical implementation should not inherit from a RawIOBase\n" - "implementation, but wrap one.\n" - ); - -static PyObject * -_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1) -{ - Py_ssize_t len; - PyObject *data; - - data = _PyObject_CallMethodId(self, - readinto1 ? &PyId_read1 : &PyId_read, - "n", buffer->len); - if (data == NULL) - return NULL; - - if (!PyBytes_Check(data)) { - Py_DECREF(data); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - return NULL; - } - - len = PyBytes_GET_SIZE(data); - if (len > buffer->len) { - PyErr_Format(PyExc_ValueError, - "read() returned too much data: " - "%zd bytes requested, %zd returned", - buffer->len, len); - Py_DECREF(data); - return NULL; - } - memcpy(buffer->buf, PyBytes_AS_STRING(data), len); - - Py_DECREF(data); - - return PyLong_FromSsize_t(len); -} - -/*[clinic input] -_io._BufferedIOBase.readinto - buffer: Py_buffer(accept={rwbuffer}) - / -[clinic start generated code]*/ - -static PyObject * -_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer) -/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/ -{ - return _bufferediobase_readinto_generic(self, buffer, 0); -} - -/*[clinic input] -_io._BufferedIOBase.readinto1 - buffer: Py_buffer(accept={rwbuffer}) - / -[clinic start generated code]*/ - -static PyObject * -_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer) -/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/ -{ - return _bufferediobase_readinto_generic(self, buffer, 1); -} - -static PyObject * -bufferediobase_unsupported(const char *message) -{ - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_SetString(state->unsupported_operation, message); - return NULL; -} - -/*[clinic input] -_io._BufferedIOBase.detach - -Disconnect this buffer from its underlying raw stream and return it. - -After the raw stream has been detached, the buffer is in an unusable -state. -[clinic start generated code]*/ - -static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self) -/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/ -{ - return bufferediobase_unsupported("detach"); -} - -PyDoc_STRVAR(bufferediobase_read_doc, - "Read and return up to n bytes.\n" - "\n" - "If the argument is omitted, None, or negative, reads and\n" - "returns all data until EOF.\n" - "\n" - "If the argument is positive, and the underlying raw stream is\n" - "not 'interactive', multiple raw reads may be issued to satisfy\n" - "the byte count (unless EOF is reached first). But for\n" - "interactive raw streams (as well as sockets and pipes), at most\n" - "one raw read will be issued, and a short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n" - "\n" - "Returns None if the underlying raw stream was open in non-blocking\n" - "mode and no data is available at the moment.\n"); - -static PyObject * -bufferediobase_read(PyObject *self, PyObject *args) -{ - return bufferediobase_unsupported("read"); -} - -PyDoc_STRVAR(bufferediobase_read1_doc, - "Read and return up to n bytes, with at most one read() call\n" - "to the underlying raw stream. A short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n"); - -static PyObject * -bufferediobase_read1(PyObject *self, PyObject *args) -{ - return bufferediobase_unsupported("read1"); -} - -PyDoc_STRVAR(bufferediobase_write_doc, - "Write the given buffer to the IO stream.\n" - "\n" - "Returns the number of bytes written, which is always the length of b\n" - "in bytes.\n" - "\n" - "Raises BlockingIOError if the buffer is full and the\n" - "underlying raw stream cannot accept more data at the moment.\n"); - -static PyObject * -bufferediobase_write(PyObject *self, PyObject *args) -{ - return bufferediobase_unsupported("write"); -} - - -typedef struct { - PyObject_HEAD - - PyObject *raw; - int ok; /* Initialized? */ - int detached; - int readable; - int writable; - char finalizing; - - /* True if this is a vanilla Buffered object (rather than a user derived - class) *and* the raw stream is a vanilla FileIO object. */ - int fast_closed_checks; - - /* Absolute position inside the raw stream (-1 if unknown). */ - Py_off_t abs_pos; - - /* A static buffer of size `buffer_size` */ - char *buffer; - /* Current logical position in the buffer. */ - Py_off_t pos; - /* Position of the raw stream in the buffer. */ - Py_off_t raw_pos; - - /* Just after the last buffered byte in the buffer, or -1 if the buffer - isn't ready for reading. */ - Py_off_t read_end; - - /* Just after the last byte actually written */ - Py_off_t write_pos; - /* Just after the last byte waiting to be written, or -1 if the buffer - isn't ready for writing. */ - Py_off_t write_end; - - PyThread_type_lock lock; - volatile unsigned long owner; - - Py_ssize_t buffer_size; - Py_ssize_t buffer_mask; - - PyObject *dict; - PyObject *weakreflist; -} buffered; - -/* - Implementation notes: - - * BufferedReader, BufferedWriter and BufferedRandom try to share most - methods (this is helped by the members `readable` and `writable`, which - are initialized in the respective constructors) - * They also share a single buffer for reading and writing. This enables - interleaved reads and writes without flushing. It also makes the logic - a bit trickier to get right. - * The absolute position of the raw stream is cached, if possible, in the - `abs_pos` member. It must be updated every time an operation is done - on the raw stream. If not sure, it can be reinitialized by calling - _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek() - also does it). To read it, use RAW_TELL(). - * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and - _bufferedwriter_flush_unlocked do a lot of useful housekeeping. - - NOTE: we should try to maintain block alignment of reads and writes to the - raw stream (according to the buffer size), but for now it is only done - in read() and friends. - -*/ - -/* These macros protect the buffered object against concurrent operations. */ - -static int -_enter_buffered_busy(buffered *self) -{ - int relax_locking; - PyLockStatus st; - if (self->owner == PyThread_get_thread_ident()) { - PyErr_Format(PyExc_RuntimeError, - "reentrant call inside %R", self); - return 0; - } - relax_locking = _Py_IsFinalizing(); - Py_BEGIN_ALLOW_THREADS - if (!relax_locking) - st = PyThread_acquire_lock(self->lock, 1); - else { - /* When finalizing, we don't want a deadlock to happen with daemon - * threads abruptly shut down while they owned the lock. - * Therefore, only wait for a grace period (1 s.). - * Note that non-daemon threads have already exited here, so this - * shouldn't affect carefully written threaded I/O code. - */ - st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0); - } - Py_END_ALLOW_THREADS - if (relax_locking && st != PY_LOCK_ACQUIRED) { +#include "_iomodule.h" + +/*[clinic input] +module _io +class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type" +class _io._Buffered "buffered *" "&PyBufferedIOBase_Type" +class _io.BufferedReader "buffered *" "&PyBufferedReader_Type" +class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type" +class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type" +class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/ + +_Py_IDENTIFIER(close); +_Py_IDENTIFIER(_dealloc_warn); +_Py_IDENTIFIER(flush); +_Py_IDENTIFIER(isatty); +_Py_IDENTIFIER(mode); +_Py_IDENTIFIER(name); +_Py_IDENTIFIER(peek); +_Py_IDENTIFIER(read); +_Py_IDENTIFIER(read1); +_Py_IDENTIFIER(readable); +_Py_IDENTIFIER(readinto); +_Py_IDENTIFIER(readinto1); +_Py_IDENTIFIER(writable); +_Py_IDENTIFIER(write); + +/* + * BufferedIOBase class, inherits from IOBase. + */ +PyDoc_STRVAR(bufferediobase_doc, + "Base class for buffered IO objects.\n" + "\n" + "The main difference with RawIOBase is that the read() method\n" + "supports omitting the size argument, and does not have a default\n" + "implementation that defers to readinto().\n" + "\n" + "In addition, read(), readinto() and write() may raise\n" + "BlockingIOError if the underlying raw stream is in non-blocking\n" + "mode and not ready; unlike their raw counterparts, they will never\n" + "return None.\n" + "\n" + "A typical implementation should not inherit from a RawIOBase\n" + "implementation, but wrap one.\n" + ); + +static PyObject * +_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1) +{ + Py_ssize_t len; + PyObject *data; + + data = _PyObject_CallMethodId(self, + readinto1 ? &PyId_read1 : &PyId_read, + "n", buffer->len); + if (data == NULL) + return NULL; + + if (!PyBytes_Check(data)) { + Py_DECREF(data); + PyErr_SetString(PyExc_TypeError, "read() should return bytes"); + return NULL; + } + + len = PyBytes_GET_SIZE(data); + if (len > buffer->len) { + PyErr_Format(PyExc_ValueError, + "read() returned too much data: " + "%zd bytes requested, %zd returned", + buffer->len, len); + Py_DECREF(data); + return NULL; + } + memcpy(buffer->buf, PyBytes_AS_STRING(data), len); + + Py_DECREF(data); + + return PyLong_FromSsize_t(len); +} + +/*[clinic input] +_io._BufferedIOBase.readinto + buffer: Py_buffer(accept={rwbuffer}) + / +[clinic start generated code]*/ + +static PyObject * +_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer) +/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/ +{ + return _bufferediobase_readinto_generic(self, buffer, 0); +} + +/*[clinic input] +_io._BufferedIOBase.readinto1 + buffer: Py_buffer(accept={rwbuffer}) + / +[clinic start generated code]*/ + +static PyObject * +_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer) +/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/ +{ + return _bufferediobase_readinto_generic(self, buffer, 1); +} + +static PyObject * +bufferediobase_unsupported(const char *message) +{ + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); + return NULL; +} + +/*[clinic input] +_io._BufferedIOBase.detach + +Disconnect this buffer from its underlying raw stream and return it. + +After the raw stream has been detached, the buffer is in an unusable +state. +[clinic start generated code]*/ + +static PyObject * +_io__BufferedIOBase_detach_impl(PyObject *self) +/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/ +{ + return bufferediobase_unsupported("detach"); +} + +PyDoc_STRVAR(bufferediobase_read_doc, + "Read and return up to n bytes.\n" + "\n" + "If the argument is omitted, None, or negative, reads and\n" + "returns all data until EOF.\n" + "\n" + "If the argument is positive, and the underlying raw stream is\n" + "not 'interactive', multiple raw reads may be issued to satisfy\n" + "the byte count (unless EOF is reached first). But for\n" + "interactive raw streams (as well as sockets and pipes), at most\n" + "one raw read will be issued, and a short result does not imply\n" + "that EOF is imminent.\n" + "\n" + "Returns an empty bytes object on EOF.\n" + "\n" + "Returns None if the underlying raw stream was open in non-blocking\n" + "mode and no data is available at the moment.\n"); + +static PyObject * +bufferediobase_read(PyObject *self, PyObject *args) +{ + return bufferediobase_unsupported("read"); +} + +PyDoc_STRVAR(bufferediobase_read1_doc, + "Read and return up to n bytes, with at most one read() call\n" + "to the underlying raw stream. A short result does not imply\n" + "that EOF is imminent.\n" + "\n" + "Returns an empty bytes object on EOF.\n"); + +static PyObject * +bufferediobase_read1(PyObject *self, PyObject *args) +{ + return bufferediobase_unsupported("read1"); +} + +PyDoc_STRVAR(bufferediobase_write_doc, + "Write the given buffer to the IO stream.\n" + "\n" + "Returns the number of bytes written, which is always the length of b\n" + "in bytes.\n" + "\n" + "Raises BlockingIOError if the buffer is full and the\n" + "underlying raw stream cannot accept more data at the moment.\n"); + +static PyObject * +bufferediobase_write(PyObject *self, PyObject *args) +{ + return bufferediobase_unsupported("write"); +} + + +typedef struct { + PyObject_HEAD + + PyObject *raw; + int ok; /* Initialized? */ + int detached; + int readable; + int writable; + char finalizing; + + /* True if this is a vanilla Buffered object (rather than a user derived + class) *and* the raw stream is a vanilla FileIO object. */ + int fast_closed_checks; + + /* Absolute position inside the raw stream (-1 if unknown). */ + Py_off_t abs_pos; + + /* A static buffer of size `buffer_size` */ + char *buffer; + /* Current logical position in the buffer. */ + Py_off_t pos; + /* Position of the raw stream in the buffer. */ + Py_off_t raw_pos; + + /* Just after the last buffered byte in the buffer, or -1 if the buffer + isn't ready for reading. */ + Py_off_t read_end; + + /* Just after the last byte actually written */ + Py_off_t write_pos; + /* Just after the last byte waiting to be written, or -1 if the buffer + isn't ready for writing. */ + Py_off_t write_end; + + PyThread_type_lock lock; + volatile unsigned long owner; + + Py_ssize_t buffer_size; + Py_ssize_t buffer_mask; + + PyObject *dict; + PyObject *weakreflist; +} buffered; + +/* + Implementation notes: + + * BufferedReader, BufferedWriter and BufferedRandom try to share most + methods (this is helped by the members `readable` and `writable`, which + are initialized in the respective constructors) + * They also share a single buffer for reading and writing. This enables + interleaved reads and writes without flushing. It also makes the logic + a bit trickier to get right. + * The absolute position of the raw stream is cached, if possible, in the + `abs_pos` member. It must be updated every time an operation is done + on the raw stream. If not sure, it can be reinitialized by calling + _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek() + also does it). To read it, use RAW_TELL(). + * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and + _bufferedwriter_flush_unlocked do a lot of useful housekeeping. + + NOTE: we should try to maintain block alignment of reads and writes to the + raw stream (according to the buffer size), but for now it is only done + in read() and friends. + +*/ + +/* These macros protect the buffered object against concurrent operations. */ + +static int +_enter_buffered_busy(buffered *self) +{ + int relax_locking; + PyLockStatus st; + if (self->owner == PyThread_get_thread_ident()) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %R", self); + return 0; + } + relax_locking = _Py_IsFinalizing(); + Py_BEGIN_ALLOW_THREADS + if (!relax_locking) + st = PyThread_acquire_lock(self->lock, 1); + else { + /* When finalizing, we don't want a deadlock to happen with daemon + * threads abruptly shut down while they owned the lock. + * Therefore, only wait for a grace period (1 s.). + * Note that non-daemon threads have already exited here, so this + * shouldn't affect carefully written threaded I/O code. + */ + st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0); + } + Py_END_ALLOW_THREADS + if (relax_locking && st != PY_LOCK_ACQUIRED) { PyObject *ascii = PyObject_ASCII((PyObject*)self); _Py_FatalErrorFormat(__func__, "could not acquire lock for %s at interpreter " - "shutdown, possibly due to daemon threads", + "shutdown, possibly due to daemon threads", ascii ? PyUnicode_AsUTF8(ascii) : ""); - } - return 1; -} - -#define ENTER_BUFFERED(self) \ - ( (PyThread_acquire_lock(self->lock, 0) ? \ - 1 : _enter_buffered_busy(self)) \ - && (self->owner = PyThread_get_thread_ident(), 1) ) - -#define LEAVE_BUFFERED(self) \ - do { \ - self->owner = 0; \ - PyThread_release_lock(self->lock); \ - } while(0); - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "raw stream has been detached"); \ - } else { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - } \ - return NULL; \ - } - -#define CHECK_INITIALIZED_INT(self) \ - if (self->ok <= 0) { \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "raw stream has been detached"); \ - } else { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - } \ - return -1; \ - } - -#define IS_CLOSED(self) \ - (!self->buffer || \ - (self->fast_closed_checks \ - ? _PyFileIO_closed(self->raw) \ - : buffered_closed(self))) - -#define CHECK_CLOSED(self, error_msg) \ + } + return 1; +} + +#define ENTER_BUFFERED(self) \ + ( (PyThread_acquire_lock(self->lock, 0) ? \ + 1 : _enter_buffered_busy(self)) \ + && (self->owner = PyThread_get_thread_ident(), 1) ) + +#define LEAVE_BUFFERED(self) \ + do { \ + self->owner = 0; \ + PyThread_release_lock(self->lock); \ + } while(0); + +#define CHECK_INITIALIZED(self) \ + if (self->ok <= 0) { \ + if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "raw stream has been detached"); \ + } else { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + } \ + return NULL; \ + } + +#define CHECK_INITIALIZED_INT(self) \ + if (self->ok <= 0) { \ + if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "raw stream has been detached"); \ + } else { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + } \ + return -1; \ + } + +#define IS_CLOSED(self) \ + (!self->buffer || \ + (self->fast_closed_checks \ + ? _PyFileIO_closed(self->raw) \ + : buffered_closed(self))) + +#define CHECK_CLOSED(self, error_msg) \ if (IS_CLOSED(self) & (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) { \ - PyErr_SetString(PyExc_ValueError, error_msg); \ - return NULL; \ + PyErr_SetString(PyExc_ValueError, error_msg); \ + return NULL; \ } \ - -#define VALID_READ_BUFFER(self) \ - (self->readable && self->read_end != -1) - -#define VALID_WRITE_BUFFER(self) \ - (self->writable && self->write_end != -1) - -#define ADJUST_POSITION(self, _new_pos) \ - do { \ - self->pos = _new_pos; \ - if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \ - self->read_end = self->pos; \ - } while(0) - -#define READAHEAD(self) \ - ((self->readable && VALID_READ_BUFFER(self)) \ - ? (self->read_end - self->pos) : 0) - -#define RAW_OFFSET(self) \ - (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \ - && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0) - -#define RAW_TELL(self) \ - (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self)) - -#define MINUS_LAST_BLOCK(self, size) \ - (self->buffer_mask ? \ - (size & ~self->buffer_mask) : \ - (self->buffer_size * (size / self->buffer_size))) - - -static void -buffered_dealloc(buffered *self) -{ - self->finalizing = 1; - if (_PyIOBase_finalize((PyObject *) self) < 0) - return; - _PyObject_GC_UNTRACK(self); - self->ok = 0; - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->raw); - if (self->buffer) { - PyMem_Free(self->buffer); - self->buffer = NULL; - } - if (self->lock) { - PyThread_free_lock(self->lock); - self->lock = NULL; - } - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * + +#define VALID_READ_BUFFER(self) \ + (self->readable && self->read_end != -1) + +#define VALID_WRITE_BUFFER(self) \ + (self->writable && self->write_end != -1) + +#define ADJUST_POSITION(self, _new_pos) \ + do { \ + self->pos = _new_pos; \ + if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \ + self->read_end = self->pos; \ + } while(0) + +#define READAHEAD(self) \ + ((self->readable && VALID_READ_BUFFER(self)) \ + ? (self->read_end - self->pos) : 0) + +#define RAW_OFFSET(self) \ + (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \ + && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0) + +#define RAW_TELL(self) \ + (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self)) + +#define MINUS_LAST_BLOCK(self, size) \ + (self->buffer_mask ? \ + (size & ~self->buffer_mask) : \ + (self->buffer_size * (size / self->buffer_size))) + + +static void +buffered_dealloc(buffered *self) +{ + self->finalizing = 1; + if (_PyIOBase_finalize((PyObject *) self) < 0) + return; + _PyObject_GC_UNTRACK(self); + self->ok = 0; + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)self); + Py_CLEAR(self->raw); + if (self->buffer) { + PyMem_Free(self->buffer); + self->buffer = NULL; + } + if (self->lock) { + PyThread_free_lock(self->lock); + self->lock = NULL; + } + Py_CLEAR(self->dict); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject * buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored)) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); - if (self->buffer) - res += self->buffer_size; - return PyLong_FromSsize_t(res); -} - -static int -buffered_traverse(buffered *self, visitproc visit, void *arg) -{ - Py_VISIT(self->raw); - Py_VISIT(self->dict); - return 0; -} - -static int -buffered_clear(buffered *self) -{ - self->ok = 0; - Py_CLEAR(self->raw); - Py_CLEAR(self->dict); - return 0; -} - -/* Because this can call arbitrary code, it shouldn't be called when - the refcount is 0 (that is, not directly from tp_dealloc unless - the refcount has been temporarily re-incremented). */ -static PyObject * -buffered_dealloc_warn(buffered *self, PyObject *source) -{ - if (self->ok && self->raw) { - PyObject *r; +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(self)); + if (self->buffer) + res += self->buffer_size; + return PyLong_FromSsize_t(res); +} + +static int +buffered_traverse(buffered *self, visitproc visit, void *arg) +{ + Py_VISIT(self->raw); + Py_VISIT(self->dict); + return 0; +} + +static int +buffered_clear(buffered *self) +{ + self->ok = 0; + Py_CLEAR(self->raw); + Py_CLEAR(self->dict); + return 0; +} + +/* Because this can call arbitrary code, it shouldn't be called when + the refcount is 0 (that is, not directly from tp_dealloc unless + the refcount has been temporarily re-incremented). */ +static PyObject * +buffered_dealloc_warn(buffered *self, PyObject *source) +{ + if (self->ok && self->raw) { + PyObject *r; r = _PyObject_CallMethodIdOneArg(self->raw, &PyId__dealloc_warn, source); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } - Py_RETURN_NONE; -} - -/* - * _BufferedIOMixin methods - * This is not a class, just a collection of methods that will be reused - * by BufferedReader and BufferedWriter - */ - -/* Flush and close */ - -static PyObject * -buffered_simple_flush(buffered *self, PyObject *args) -{ - CHECK_INITIALIZED(self) + if (r) + Py_DECREF(r); + else + PyErr_Clear(); + } + Py_RETURN_NONE; +} + +/* + * _BufferedIOMixin methods + * This is not a class, just a collection of methods that will be reused + * by BufferedReader and BufferedWriter + */ + +/* Flush and close */ + +static PyObject * +buffered_simple_flush(buffered *self, PyObject *args) +{ + CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush); -} - -static int -buffered_closed(buffered *self) -{ - int closed; - PyObject *res; - CHECK_INITIALIZED_INT(self) - res = PyObject_GetAttr(self->raw, _PyIO_str_closed); - if (res == NULL) - return -1; - closed = PyObject_IsTrue(res); - Py_DECREF(res); - return closed; -} - -static PyObject * -buffered_closed_get(buffered *self, void *context) -{ - CHECK_INITIALIZED(self) - return PyObject_GetAttr(self->raw, _PyIO_str_closed); -} - -static PyObject * -buffered_close(buffered *self, PyObject *args) -{ - PyObject *res = NULL, *exc = NULL, *val, *tb; - int r; - - CHECK_INITIALIZED(self) - if (!ENTER_BUFFERED(self)) - return NULL; - - r = buffered_closed(self); - if (r < 0) - goto end; - if (r > 0) { - res = Py_None; - Py_INCREF(res); - goto end; - } - - if (self->finalizing) { - PyObject *r = buffered_dealloc_warn(self, (PyObject *) self); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } - /* flush() will most probably re-take the lock, so drop it first */ - LEAVE_BUFFERED(self) +} + +static int +buffered_closed(buffered *self) +{ + int closed; + PyObject *res; + CHECK_INITIALIZED_INT(self) + res = PyObject_GetAttr(self->raw, _PyIO_str_closed); + if (res == NULL) + return -1; + closed = PyObject_IsTrue(res); + Py_DECREF(res); + return closed; +} + +static PyObject * +buffered_closed_get(buffered *self, void *context) +{ + CHECK_INITIALIZED(self) + return PyObject_GetAttr(self->raw, _PyIO_str_closed); +} + +static PyObject * +buffered_close(buffered *self, PyObject *args) +{ + PyObject *res = NULL, *exc = NULL, *val, *tb; + int r; + + CHECK_INITIALIZED(self) + if (!ENTER_BUFFERED(self)) + return NULL; + + r = buffered_closed(self); + if (r < 0) + goto end; + if (r > 0) { + res = Py_None; + Py_INCREF(res); + goto end; + } + + if (self->finalizing) { + PyObject *r = buffered_dealloc_warn(self, (PyObject *) self); + if (r) + Py_DECREF(r); + else + PyErr_Clear(); + } + /* flush() will most probably re-take the lock, so drop it first */ + LEAVE_BUFFERED(self) res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); - if (!ENTER_BUFFERED(self)) - return NULL; - if (res == NULL) - PyErr_Fetch(&exc, &val, &tb); - else - Py_DECREF(res); - + if (!ENTER_BUFFERED(self)) + return NULL; + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); + else + Py_DECREF(res); + res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close); - - if (self->buffer) { - PyMem_Free(self->buffer); - self->buffer = NULL; - } - - if (exc != NULL) { - _PyErr_ChainExceptions(exc, val, tb); - Py_CLEAR(res); - } - + + if (self->buffer) { + PyMem_Free(self->buffer); + self->buffer = NULL; + } + + if (exc != NULL) { + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(res); + } + self->read_end = 0; self->pos = 0; -end: - LEAVE_BUFFERED(self) - return res; -} - -/* detach */ - -static PyObject * +end: + LEAVE_BUFFERED(self) + return res; +} + +/* detach */ + +static PyObject * buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *raw, *res; - CHECK_INITIALIZED(self) +{ + PyObject *raw, *res; + CHECK_INITIALIZED(self) res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); - if (res == NULL) - return NULL; - Py_DECREF(res); - raw = self->raw; - self->raw = NULL; - self->detached = 1; - self->ok = 0; - return raw; -} - -/* Inquiries */ - -static PyObject * + if (res == NULL) + return NULL; + Py_DECREF(res); + raw = self->raw; + self->raw = NULL; + self->detached = 1; + self->ok = 0; + return raw; +} + +/* Inquiries */ + +static PyObject * buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored)) -{ - CHECK_INITIALIZED(self) +{ + CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable); -} - -static PyObject * +} + +static PyObject * buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored)) -{ - CHECK_INITIALIZED(self) +{ + CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable); -} - -static PyObject * +} + +static PyObject * buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored)) -{ - CHECK_INITIALIZED(self) +{ + CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable); -} - -static PyObject * -buffered_name_get(buffered *self, void *context) -{ - CHECK_INITIALIZED(self) - return _PyObject_GetAttrId(self->raw, &PyId_name); -} - -static PyObject * -buffered_mode_get(buffered *self, void *context) -{ - CHECK_INITIALIZED(self) - return _PyObject_GetAttrId(self->raw, &PyId_mode); -} - -/* Lower-level APIs */ - -static PyObject * +} + +static PyObject * +buffered_name_get(buffered *self, void *context) +{ + CHECK_INITIALIZED(self) + return _PyObject_GetAttrId(self->raw, &PyId_name); +} + +static PyObject * +buffered_mode_get(buffered *self, void *context) +{ + CHECK_INITIALIZED(self) + return _PyObject_GetAttrId(self->raw, &PyId_mode); +} + +/* Lower-level APIs */ + +static PyObject * buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored)) -{ - CHECK_INITIALIZED(self) +{ + CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno); -} - -static PyObject * +} + +static PyObject * buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored)) -{ - CHECK_INITIALIZED(self) +{ + CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty); -} - -/* Forward decls */ -static PyObject * -_bufferedwriter_flush_unlocked(buffered *); -static Py_ssize_t -_bufferedreader_fill_buffer(buffered *self); -static void -_bufferedreader_reset_buf(buffered *self); -static void -_bufferedwriter_reset_buf(buffered *self); -static PyObject * -_bufferedreader_peek_unlocked(buffered *self); -static PyObject * -_bufferedreader_read_all(buffered *self); -static PyObject * -_bufferedreader_read_fast(buffered *self, Py_ssize_t); -static PyObject * -_bufferedreader_read_generic(buffered *self, Py_ssize_t); -static Py_ssize_t -_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len); - -/* - * Helpers - */ - -/* Sets the current error to BlockingIOError */ -static void -_set_BlockingIOError(const char *msg, Py_ssize_t written) -{ - PyObject *err; - PyErr_Clear(); - err = PyObject_CallFunction(PyExc_BlockingIOError, "isn", - errno, msg, written); - if (err) - PyErr_SetObject(PyExc_BlockingIOError, err); - Py_XDECREF(err); -} - -/* Returns the address of the `written` member if a BlockingIOError was - raised, NULL otherwise. The error is always re-raised. */ -static Py_ssize_t * -_buffered_check_blocking_error(void) -{ - PyObject *t, *v, *tb; - PyOSErrorObject *err; - - PyErr_Fetch(&t, &v, &tb); - if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) { - PyErr_Restore(t, v, tb); - return NULL; - } - err = (PyOSErrorObject *) v; - /* TODO: sanity check (err->written >= 0) */ - PyErr_Restore(t, v, tb); - return &err->written; -} - -static Py_off_t -_buffered_raw_tell(buffered *self) -{ - Py_off_t n; - PyObject *res; +} + +/* Forward decls */ +static PyObject * +_bufferedwriter_flush_unlocked(buffered *); +static Py_ssize_t +_bufferedreader_fill_buffer(buffered *self); +static void +_bufferedreader_reset_buf(buffered *self); +static void +_bufferedwriter_reset_buf(buffered *self); +static PyObject * +_bufferedreader_peek_unlocked(buffered *self); +static PyObject * +_bufferedreader_read_all(buffered *self); +static PyObject * +_bufferedreader_read_fast(buffered *self, Py_ssize_t); +static PyObject * +_bufferedreader_read_generic(buffered *self, Py_ssize_t); +static Py_ssize_t +_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len); + +/* + * Helpers + */ + +/* Sets the current error to BlockingIOError */ +static void +_set_BlockingIOError(const char *msg, Py_ssize_t written) +{ + PyObject *err; + PyErr_Clear(); + err = PyObject_CallFunction(PyExc_BlockingIOError, "isn", + errno, msg, written); + if (err) + PyErr_SetObject(PyExc_BlockingIOError, err); + Py_XDECREF(err); +} + +/* Returns the address of the `written` member if a BlockingIOError was + raised, NULL otherwise. The error is always re-raised. */ +static Py_ssize_t * +_buffered_check_blocking_error(void) +{ + PyObject *t, *v, *tb; + PyOSErrorObject *err; + + PyErr_Fetch(&t, &v, &tb); + if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) { + PyErr_Restore(t, v, tb); + return NULL; + } + err = (PyOSErrorObject *) v; + /* TODO: sanity check (err->written >= 0) */ + PyErr_Restore(t, v, tb); + return &err->written; +} + +static Py_off_t +_buffered_raw_tell(buffered *self) +{ + Py_off_t n; + PyObject *res; res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell); - if (res == NULL) - return -1; - n = PyNumber_AsOff_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_OSError, - "Raw stream returned invalid position %" PY_PRIdOFF, - (PY_OFF_T_COMPAT)n); - return -1; - } - self->abs_pos = n; - return n; -} - -static Py_off_t -_buffered_raw_seek(buffered *self, Py_off_t target, int whence) -{ - PyObject *res, *posobj, *whenceobj; - Py_off_t n; - - posobj = PyLong_FromOff_t(target); - if (posobj == NULL) - return -1; - whenceobj = PyLong_FromLong(whence); - if (whenceobj == NULL) { - Py_DECREF(posobj); - return -1; - } - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek, - posobj, whenceobj, NULL); - Py_DECREF(posobj); - Py_DECREF(whenceobj); - if (res == NULL) - return -1; - n = PyNumber_AsOff_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_OSError, - "Raw stream returned invalid position %" PY_PRIdOFF, - (PY_OFF_T_COMPAT)n); - return -1; - } - self->abs_pos = n; - return n; -} - -static int -_buffered_init(buffered *self) -{ - Py_ssize_t n; - if (self->buffer_size <= 0) { - PyErr_SetString(PyExc_ValueError, - "buffer size must be strictly positive"); - return -1; - } - if (self->buffer) - PyMem_Free(self->buffer); - self->buffer = PyMem_Malloc(self->buffer_size); - if (self->buffer == NULL) { - PyErr_NoMemory(); - return -1; - } - if (self->lock) - PyThread_free_lock(self->lock); - self->lock = PyThread_allocate_lock(); - if (self->lock == NULL) { - PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); - return -1; - } - self->owner = 0; - /* Find out whether buffer_size is a power of 2 */ - /* XXX is this optimization useful? */ - for (n = self->buffer_size - 1; n & 1; n >>= 1) - ; - if (n == 0) - self->buffer_mask = self->buffer_size - 1; - else - self->buffer_mask = 0; - if (_buffered_raw_tell(self) == -1) - PyErr_Clear(); - return 0; -} - -/* Return 1 if an OSError with errno == EINTR is set (and then - clears the error indicator), 0 otherwise. - Should only be called when PyErr_Occurred() is true. -*/ -int -_PyIO_trap_eintr(void) -{ - static PyObject *eintr_int = NULL; - PyObject *typ, *val, *tb; - PyOSErrorObject *env_err; - - if (eintr_int == NULL) { - eintr_int = PyLong_FromLong(EINTR); - assert(eintr_int != NULL); - } - if (!PyErr_ExceptionMatches(PyExc_OSError)) - return 0; - PyErr_Fetch(&typ, &val, &tb); - PyErr_NormalizeException(&typ, &val, &tb); - env_err = (PyOSErrorObject *) val; - assert(env_err != NULL); - if (env_err->myerrno != NULL && - PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) { - Py_DECREF(typ); - Py_DECREF(val); - Py_XDECREF(tb); - return 1; - } - /* This silences any error set by PyObject_RichCompareBool() */ - PyErr_Restore(typ, val, tb); - return 0; -} - -/* - * Shared methods and wrappers - */ - -static PyObject * -buffered_flush_and_rewind_unlocked(buffered *self) -{ - PyObject *res; - - res = _bufferedwriter_flush_unlocked(self); - if (res == NULL) - return NULL; - Py_DECREF(res); - - if (self->readable) { - /* Rewind the raw stream so that its position corresponds to - the current logical position. */ - Py_off_t n; - n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1); - _bufferedreader_reset_buf(self); - if (n == -1) - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject * -buffered_flush(buffered *self, PyObject *args) -{ - PyObject *res; - - CHECK_INITIALIZED(self) - CHECK_CLOSED(self, "flush of closed file") - - if (!ENTER_BUFFERED(self)) - return NULL; - res = buffered_flush_and_rewind_unlocked(self); - LEAVE_BUFFERED(self) - - return res; -} - -/*[clinic input] -_io._Buffered.peek - size: Py_ssize_t = 0 - / - -[clinic start generated code]*/ - -static PyObject * -_io__Buffered_peek_impl(buffered *self, Py_ssize_t size) -/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/ -{ - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - CHECK_CLOSED(self, "peek of closed file") - - if (!ENTER_BUFFERED(self)) - return NULL; - - if (self->writable) { - res = buffered_flush_and_rewind_unlocked(self); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - res = _bufferedreader_peek_unlocked(self); - -end: - LEAVE_BUFFERED(self) - return res; -} - -/*[clinic input] -_io._Buffered.read - size as n: Py_ssize_t(accept={int, NoneType}) = -1 - / -[clinic start generated code]*/ - -static PyObject * -_io__Buffered_read_impl(buffered *self, Py_ssize_t n) -/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/ -{ - PyObject *res; - - CHECK_INITIALIZED(self) - if (n < -1) { - PyErr_SetString(PyExc_ValueError, - "read length must be non-negative or -1"); - return NULL; - } - - CHECK_CLOSED(self, "read of closed file") - - if (n == -1) { - /* The number of bytes is unspecified, read until the end of stream */ - if (!ENTER_BUFFERED(self)) - return NULL; - res = _bufferedreader_read_all(self); - } - else { - res = _bufferedreader_read_fast(self, n); - if (res != Py_None) - return res; - Py_DECREF(res); - if (!ENTER_BUFFERED(self)) - return NULL; - res = _bufferedreader_read_generic(self, n); - } - - LEAVE_BUFFERED(self) - return res; -} - -/*[clinic input] -_io._Buffered.read1 - size as n: Py_ssize_t = -1 - / -[clinic start generated code]*/ - -static PyObject * -_io__Buffered_read1_impl(buffered *self, Py_ssize_t n) -/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/ -{ - Py_ssize_t have, r; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - if (n < 0) { - n = self->buffer_size; - } - - CHECK_CLOSED(self, "read of closed file") - - if (n == 0) - return PyBytes_FromStringAndSize(NULL, 0); - - /* Return up to n bytes. If at least one byte is buffered, we - only return buffered bytes. Otherwise, we do one raw read. */ - - have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (have > 0) { - n = Py_MIN(have, n); - res = _bufferedreader_read_fast(self, n); - assert(res != Py_None); - return res; - } - res = PyBytes_FromStringAndSize(NULL, n); - if (res == NULL) - return NULL; - if (!ENTER_BUFFERED(self)) { - Py_DECREF(res); - return NULL; - } - _bufferedreader_reset_buf(self); - r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n); - LEAVE_BUFFERED(self) - if (r == -1) { - Py_DECREF(res); - return NULL; - } - if (r == -2) - r = 0; - if (n > r) - _PyBytes_Resize(&res, r); - return res; -} - -static PyObject * -_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) -{ - Py_ssize_t n, written = 0, remaining; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) + if (res == NULL) + return -1; + n = PyNumber_AsOff_t(res, PyExc_ValueError); + Py_DECREF(res); + if (n < 0) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_OSError, + "Raw stream returned invalid position %" PY_PRIdOFF, + (PY_OFF_T_COMPAT)n); + return -1; + } + self->abs_pos = n; + return n; +} + +static Py_off_t +_buffered_raw_seek(buffered *self, Py_off_t target, int whence) +{ + PyObject *res, *posobj, *whenceobj; + Py_off_t n; + + posobj = PyLong_FromOff_t(target); + if (posobj == NULL) + return -1; + whenceobj = PyLong_FromLong(whence); + if (whenceobj == NULL) { + Py_DECREF(posobj); + return -1; + } + res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek, + posobj, whenceobj, NULL); + Py_DECREF(posobj); + Py_DECREF(whenceobj); + if (res == NULL) + return -1; + n = PyNumber_AsOff_t(res, PyExc_ValueError); + Py_DECREF(res); + if (n < 0) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_OSError, + "Raw stream returned invalid position %" PY_PRIdOFF, + (PY_OFF_T_COMPAT)n); + return -1; + } + self->abs_pos = n; + return n; +} + +static int +_buffered_init(buffered *self) +{ + Py_ssize_t n; + if (self->buffer_size <= 0) { + PyErr_SetString(PyExc_ValueError, + "buffer size must be strictly positive"); + return -1; + } + if (self->buffer) + PyMem_Free(self->buffer); + self->buffer = PyMem_Malloc(self->buffer_size); + if (self->buffer == NULL) { + PyErr_NoMemory(); + return -1; + } + if (self->lock) + PyThread_free_lock(self->lock); + self->lock = PyThread_allocate_lock(); + if (self->lock == NULL) { + PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); + return -1; + } + self->owner = 0; + /* Find out whether buffer_size is a power of 2 */ + /* XXX is this optimization useful? */ + for (n = self->buffer_size - 1; n & 1; n >>= 1) + ; + if (n == 0) + self->buffer_mask = self->buffer_size - 1; + else + self->buffer_mask = 0; + if (_buffered_raw_tell(self) == -1) + PyErr_Clear(); + return 0; +} + +/* Return 1 if an OSError with errno == EINTR is set (and then + clears the error indicator), 0 otherwise. + Should only be called when PyErr_Occurred() is true. +*/ +int +_PyIO_trap_eintr(void) +{ + static PyObject *eintr_int = NULL; + PyObject *typ, *val, *tb; + PyOSErrorObject *env_err; + + if (eintr_int == NULL) { + eintr_int = PyLong_FromLong(EINTR); + assert(eintr_int != NULL); + } + if (!PyErr_ExceptionMatches(PyExc_OSError)) + return 0; + PyErr_Fetch(&typ, &val, &tb); + PyErr_NormalizeException(&typ, &val, &tb); + env_err = (PyOSErrorObject *) val; + assert(env_err != NULL); + if (env_err->myerrno != NULL && + PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) { + Py_DECREF(typ); + Py_DECREF(val); + Py_XDECREF(tb); + return 1; + } + /* This silences any error set by PyObject_RichCompareBool() */ + PyErr_Restore(typ, val, tb); + return 0; +} + +/* + * Shared methods and wrappers + */ + +static PyObject * +buffered_flush_and_rewind_unlocked(buffered *self) +{ + PyObject *res; + + res = _bufferedwriter_flush_unlocked(self); + if (res == NULL) + return NULL; + Py_DECREF(res); + + if (self->readable) { + /* Rewind the raw stream so that its position corresponds to + the current logical position. */ + Py_off_t n; + n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1); + _bufferedreader_reset_buf(self); + if (n == -1) + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +buffered_flush(buffered *self, PyObject *args) +{ + PyObject *res; + + CHECK_INITIALIZED(self) + CHECK_CLOSED(self, "flush of closed file") + + if (!ENTER_BUFFERED(self)) + return NULL; + res = buffered_flush_and_rewind_unlocked(self); + LEAVE_BUFFERED(self) + + return res; +} + +/*[clinic input] +_io._Buffered.peek + size: Py_ssize_t = 0 + / + +[clinic start generated code]*/ + +static PyObject * +_io__Buffered_peek_impl(buffered *self, Py_ssize_t size) +/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/ +{ + PyObject *res = NULL; + + CHECK_INITIALIZED(self) + CHECK_CLOSED(self, "peek of closed file") + + if (!ENTER_BUFFERED(self)) + return NULL; + + if (self->writable) { + res = buffered_flush_and_rewind_unlocked(self); + if (res == NULL) + goto end; + Py_CLEAR(res); + } + res = _bufferedreader_peek_unlocked(self); + +end: + LEAVE_BUFFERED(self) + return res; +} + +/*[clinic input] +_io._Buffered.read + size as n: Py_ssize_t(accept={int, NoneType}) = -1 + / +[clinic start generated code]*/ + +static PyObject * +_io__Buffered_read_impl(buffered *self, Py_ssize_t n) +/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/ +{ + PyObject *res; + + CHECK_INITIALIZED(self) + if (n < -1) { + PyErr_SetString(PyExc_ValueError, + "read length must be non-negative or -1"); + return NULL; + } + + CHECK_CLOSED(self, "read of closed file") + + if (n == -1) { + /* The number of bytes is unspecified, read until the end of stream */ + if (!ENTER_BUFFERED(self)) + return NULL; + res = _bufferedreader_read_all(self); + } + else { + res = _bufferedreader_read_fast(self, n); + if (res != Py_None) + return res; + Py_DECREF(res); + if (!ENTER_BUFFERED(self)) + return NULL; + res = _bufferedreader_read_generic(self, n); + } + + LEAVE_BUFFERED(self) + return res; +} + +/*[clinic input] +_io._Buffered.read1 + size as n: Py_ssize_t = -1 + / +[clinic start generated code]*/ + +static PyObject * +_io__Buffered_read1_impl(buffered *self, Py_ssize_t n) +/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/ +{ + Py_ssize_t have, r; + PyObject *res = NULL; + + CHECK_INITIALIZED(self) + if (n < 0) { + n = self->buffer_size; + } + + CHECK_CLOSED(self, "read of closed file") + + if (n == 0) + return PyBytes_FromStringAndSize(NULL, 0); + + /* Return up to n bytes. If at least one byte is buffered, we + only return buffered bytes. Otherwise, we do one raw read. */ + + have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (have > 0) { + n = Py_MIN(have, n); + res = _bufferedreader_read_fast(self, n); + assert(res != Py_None); + return res; + } + res = PyBytes_FromStringAndSize(NULL, n); + if (res == NULL) + return NULL; + if (!ENTER_BUFFERED(self)) { + Py_DECREF(res); + return NULL; + } + _bufferedreader_reset_buf(self); + r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n); + LEAVE_BUFFERED(self) + if (r == -1) { + Py_DECREF(res); + return NULL; + } + if (r == -2) + r = 0; + if (n > r) + _PyBytes_Resize(&res, r); + return res; +} + +static PyObject * +_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) +{ + Py_ssize_t n, written = 0, remaining; + PyObject *res = NULL; + + CHECK_INITIALIZED(self) CHECK_CLOSED(self, "readinto of closed file") - - n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (n > 0) { - if (n >= buffer->len) { - memcpy(buffer->buf, self->buffer + self->pos, buffer->len); - self->pos += buffer->len; - return PyLong_FromSsize_t(buffer->len); - } - memcpy(buffer->buf, self->buffer + self->pos, n); - self->pos += n; - written = n; - } - - if (!ENTER_BUFFERED(self)) - return NULL; - - if (self->writable) { - res = buffered_flush_and_rewind_unlocked(self); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - - _bufferedreader_reset_buf(self); - self->pos = 0; - - for (remaining = buffer->len - written; - remaining > 0; - written += n, remaining -= n) { - /* If remaining bytes is larger than internal buffer size, copy - * directly into caller's buffer. */ - if (remaining > self->buffer_size) { - n = _bufferedreader_raw_read(self, (char *) buffer->buf + written, - remaining); - } - - /* In readinto1 mode, we do not want to fill the internal - buffer if we already have some data to return */ - else if (!(readinto1 && written)) { - n = _bufferedreader_fill_buffer(self); - if (n > 0) { - if (n > remaining) - n = remaining; - memcpy((char *) buffer->buf + written, - self->buffer + self->pos, n); - self->pos += n; - continue; /* short circuit */ - } - } - else - n = 0; - - if (n == 0 || (n == -2 && written > 0)) - break; - if (n < 0) { - if (n == -2) { - Py_INCREF(Py_None); - res = Py_None; - } - goto end; - } - - /* At most one read in readinto1 mode */ - if (readinto1) { - written += n; - break; - } - } - res = PyLong_FromSsize_t(written); - -end: - LEAVE_BUFFERED(self); - return res; -} - -/*[clinic input] -_io._Buffered.readinto - buffer: Py_buffer(accept={rwbuffer}) - / -[clinic start generated code]*/ - -static PyObject * -_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer) -/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/ -{ - return _buffered_readinto_generic(self, buffer, 0); -} - -/*[clinic input] -_io._Buffered.readinto1 - buffer: Py_buffer(accept={rwbuffer}) - / -[clinic start generated code]*/ - -static PyObject * -_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer) -/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/ -{ - return _buffered_readinto_generic(self, buffer, 1); -} - - -static PyObject * -_buffered_readline(buffered *self, Py_ssize_t limit) -{ - PyObject *res = NULL; - PyObject *chunks = NULL; - Py_ssize_t n, written = 0; - const char *start, *s, *end; - - CHECK_CLOSED(self, "readline of closed file") - - /* First, try to find a line in the buffer. This can run unlocked because - the calls to the C API are simple enough that they can't trigger - any thread switch. */ - n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (limit >= 0 && n > limit) - n = limit; - start = self->buffer + self->pos; - s = memchr(start, '\n', n); - if (s != NULL) { - res = PyBytes_FromStringAndSize(start, s - start + 1); - if (res != NULL) - self->pos += s - start + 1; - goto end_unlocked; - } - if (n == limit) { - res = PyBytes_FromStringAndSize(start, n); - if (res != NULL) - self->pos += n; - goto end_unlocked; - } - - if (!ENTER_BUFFERED(self)) - goto end_unlocked; - - /* Now we try to get some more from the raw stream */ - chunks = PyList_New(0); - if (chunks == NULL) - goto end; - if (n > 0) { - res = PyBytes_FromStringAndSize(start, n); - if (res == NULL) - goto end; - if (PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_CLEAR(res); - written += n; - self->pos += n; - if (limit >= 0) - limit -= n; - } - if (self->writable) { - PyObject *r = buffered_flush_and_rewind_unlocked(self); - if (r == NULL) - goto end; - Py_DECREF(r); - } - - for (;;) { - _bufferedreader_reset_buf(self); - n = _bufferedreader_fill_buffer(self); - if (n == -1) - goto end; - if (n <= 0) - break; - if (limit >= 0 && n > limit) - n = limit; - start = self->buffer; - end = start + n; - s = start; - while (s < end) { - if (*s++ == '\n') { - res = PyBytes_FromStringAndSize(start, s - start); - if (res == NULL) - goto end; - self->pos = s - start; - goto found; - } - } - res = PyBytes_FromStringAndSize(start, n); - if (res == NULL) - goto end; - if (n == limit) { - self->pos = n; - break; - } - if (PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_CLEAR(res); - written += n; - if (limit >= 0) - limit -= n; - } -found: - if (res != NULL && PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks)); - -end: - LEAVE_BUFFERED(self) -end_unlocked: - Py_XDECREF(chunks); - return res; -} - -/*[clinic input] -_io._Buffered.readline - size: Py_ssize_t(accept={int, NoneType}) = -1 - / -[clinic start generated code]*/ - -static PyObject * -_io__Buffered_readline_impl(buffered *self, Py_ssize_t size) -/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/ -{ - CHECK_INITIALIZED(self) - return _buffered_readline(self, size); -} - - -static PyObject * + + n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (n > 0) { + if (n >= buffer->len) { + memcpy(buffer->buf, self->buffer + self->pos, buffer->len); + self->pos += buffer->len; + return PyLong_FromSsize_t(buffer->len); + } + memcpy(buffer->buf, self->buffer + self->pos, n); + self->pos += n; + written = n; + } + + if (!ENTER_BUFFERED(self)) + return NULL; + + if (self->writable) { + res = buffered_flush_and_rewind_unlocked(self); + if (res == NULL) + goto end; + Py_CLEAR(res); + } + + _bufferedreader_reset_buf(self); + self->pos = 0; + + for (remaining = buffer->len - written; + remaining > 0; + written += n, remaining -= n) { + /* If remaining bytes is larger than internal buffer size, copy + * directly into caller's buffer. */ + if (remaining > self->buffer_size) { + n = _bufferedreader_raw_read(self, (char *) buffer->buf + written, + remaining); + } + + /* In readinto1 mode, we do not want to fill the internal + buffer if we already have some data to return */ + else if (!(readinto1 && written)) { + n = _bufferedreader_fill_buffer(self); + if (n > 0) { + if (n > remaining) + n = remaining; + memcpy((char *) buffer->buf + written, + self->buffer + self->pos, n); + self->pos += n; + continue; /* short circuit */ + } + } + else + n = 0; + + if (n == 0 || (n == -2 && written > 0)) + break; + if (n < 0) { + if (n == -2) { + Py_INCREF(Py_None); + res = Py_None; + } + goto end; + } + + /* At most one read in readinto1 mode */ + if (readinto1) { + written += n; + break; + } + } + res = PyLong_FromSsize_t(written); + +end: + LEAVE_BUFFERED(self); + return res; +} + +/*[clinic input] +_io._Buffered.readinto + buffer: Py_buffer(accept={rwbuffer}) + / +[clinic start generated code]*/ + +static PyObject * +_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer) +/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/ +{ + return _buffered_readinto_generic(self, buffer, 0); +} + +/*[clinic input] +_io._Buffered.readinto1 + buffer: Py_buffer(accept={rwbuffer}) + / +[clinic start generated code]*/ + +static PyObject * +_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer) +/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/ +{ + return _buffered_readinto_generic(self, buffer, 1); +} + + +static PyObject * +_buffered_readline(buffered *self, Py_ssize_t limit) +{ + PyObject *res = NULL; + PyObject *chunks = NULL; + Py_ssize_t n, written = 0; + const char *start, *s, *end; + + CHECK_CLOSED(self, "readline of closed file") + + /* First, try to find a line in the buffer. This can run unlocked because + the calls to the C API are simple enough that they can't trigger + any thread switch. */ + n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (limit >= 0 && n > limit) + n = limit; + start = self->buffer + self->pos; + s = memchr(start, '\n', n); + if (s != NULL) { + res = PyBytes_FromStringAndSize(start, s - start + 1); + if (res != NULL) + self->pos += s - start + 1; + goto end_unlocked; + } + if (n == limit) { + res = PyBytes_FromStringAndSize(start, n); + if (res != NULL) + self->pos += n; + goto end_unlocked; + } + + if (!ENTER_BUFFERED(self)) + goto end_unlocked; + + /* Now we try to get some more from the raw stream */ + chunks = PyList_New(0); + if (chunks == NULL) + goto end; + if (n > 0) { + res = PyBytes_FromStringAndSize(start, n); + if (res == NULL) + goto end; + if (PyList_Append(chunks, res) < 0) { + Py_CLEAR(res); + goto end; + } + Py_CLEAR(res); + written += n; + self->pos += n; + if (limit >= 0) + limit -= n; + } + if (self->writable) { + PyObject *r = buffered_flush_and_rewind_unlocked(self); + if (r == NULL) + goto end; + Py_DECREF(r); + } + + for (;;) { + _bufferedreader_reset_buf(self); + n = _bufferedreader_fill_buffer(self); + if (n == -1) + goto end; + if (n <= 0) + break; + if (limit >= 0 && n > limit) + n = limit; + start = self->buffer; + end = start + n; + s = start; + while (s < end) { + if (*s++ == '\n') { + res = PyBytes_FromStringAndSize(start, s - start); + if (res == NULL) + goto end; + self->pos = s - start; + goto found; + } + } + res = PyBytes_FromStringAndSize(start, n); + if (res == NULL) + goto end; + if (n == limit) { + self->pos = n; + break; + } + if (PyList_Append(chunks, res) < 0) { + Py_CLEAR(res); + goto end; + } + Py_CLEAR(res); + written += n; + if (limit >= 0) + limit -= n; + } +found: + if (res != NULL && PyList_Append(chunks, res) < 0) { + Py_CLEAR(res); + goto end; + } + Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks)); + +end: + LEAVE_BUFFERED(self) +end_unlocked: + Py_XDECREF(chunks); + return res; +} + +/*[clinic input] +_io._Buffered.readline + size: Py_ssize_t(accept={int, NoneType}) = -1 + / +[clinic start generated code]*/ + +static PyObject * +_io__Buffered_readline_impl(buffered *self, Py_ssize_t size) +/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/ +{ + CHECK_INITIALIZED(self) + return _buffered_readline(self, size); +} + + +static PyObject * buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored)) -{ - Py_off_t pos; - - CHECK_INITIALIZED(self) - pos = _buffered_raw_tell(self); - if (pos == -1) - return NULL; - pos -= RAW_OFFSET(self); - /* TODO: sanity check (pos >= 0) */ - return PyLong_FromOff_t(pos); -} - -/*[clinic input] -_io._Buffered.seek - target as targetobj: object - whence: int = 0 - / -[clinic start generated code]*/ - -static PyObject * -_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) -/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/ -{ - Py_off_t target, n; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - - /* Do some error checking instead of trusting OS 'seek()' - ** error detection, just in case. - */ - if ((whence < 0 || whence >2) -#ifdef SEEK_HOLE - && (whence != SEEK_HOLE) -#endif -#ifdef SEEK_DATA - && (whence != SEEK_DATA) -#endif - ) { - PyErr_Format(PyExc_ValueError, - "whence value %d unsupported", whence); - return NULL; - } - - CHECK_CLOSED(self, "seek of closed file") - - if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL) - return NULL; - - target = PyNumber_AsOff_t(targetobj, PyExc_ValueError); - if (target == -1 && PyErr_Occurred()) - return NULL; - - /* SEEK_SET and SEEK_CUR are special because we could seek inside the - buffer. Other whence values must be managed without this optimization. - Some Operating Systems can provide additional values, like - SEEK_HOLE/SEEK_DATA. */ - if (((whence == 0) || (whence == 1)) && self->readable) { - Py_off_t current, avail; - /* Check if seeking leaves us inside the current buffer, - so as to return quickly if possible. Also, we needn't take the - lock in this fast path. - Don't know how to do that when whence == 2, though. */ - /* NOTE: RAW_TELL() can release the GIL but the object is in a stable - state at this point. */ - current = RAW_TELL(self); - avail = READAHEAD(self); - if (avail > 0) { - Py_off_t offset; - if (whence == 0) - offset = target - (current - RAW_OFFSET(self)); - else - offset = target; - if (offset >= -self->pos && offset <= avail) { - self->pos += offset; - return PyLong_FromOff_t(current - avail + offset); - } - } - } - - if (!ENTER_BUFFERED(self)) - return NULL; - - /* Fallback: invoke raw seek() method and clear buffer */ - if (self->writable) { - res = _bufferedwriter_flush_unlocked(self); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - - /* TODO: align on block boundary and read buffer if needed? */ - if (whence == 1) - target -= RAW_OFFSET(self); - n = _buffered_raw_seek(self, target, whence); - if (n == -1) - goto end; - self->raw_pos = -1; - res = PyLong_FromOff_t(n); - if (res != NULL && self->readable) - _bufferedreader_reset_buf(self); - -end: - LEAVE_BUFFERED(self) - return res; -} - -/*[clinic input] -_io._Buffered.truncate - pos: object = None - / -[clinic start generated code]*/ - -static PyObject * -_io__Buffered_truncate_impl(buffered *self, PyObject *pos) -/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/ -{ - PyObject *res = NULL; - - CHECK_INITIALIZED(self) +{ + Py_off_t pos; + + CHECK_INITIALIZED(self) + pos = _buffered_raw_tell(self); + if (pos == -1) + return NULL; + pos -= RAW_OFFSET(self); + /* TODO: sanity check (pos >= 0) */ + return PyLong_FromOff_t(pos); +} + +/*[clinic input] +_io._Buffered.seek + target as targetobj: object + whence: int = 0 + / +[clinic start generated code]*/ + +static PyObject * +_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) +/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/ +{ + Py_off_t target, n; + PyObject *res = NULL; + + CHECK_INITIALIZED(self) + + /* Do some error checking instead of trusting OS 'seek()' + ** error detection, just in case. + */ + if ((whence < 0 || whence >2) +#ifdef SEEK_HOLE + && (whence != SEEK_HOLE) +#endif +#ifdef SEEK_DATA + && (whence != SEEK_DATA) +#endif + ) { + PyErr_Format(PyExc_ValueError, + "whence value %d unsupported", whence); + return NULL; + } + + CHECK_CLOSED(self, "seek of closed file") + + if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL) + return NULL; + + target = PyNumber_AsOff_t(targetobj, PyExc_ValueError); + if (target == -1 && PyErr_Occurred()) + return NULL; + + /* SEEK_SET and SEEK_CUR are special because we could seek inside the + buffer. Other whence values must be managed without this optimization. + Some Operating Systems can provide additional values, like + SEEK_HOLE/SEEK_DATA. */ + if (((whence == 0) || (whence == 1)) && self->readable) { + Py_off_t current, avail; + /* Check if seeking leaves us inside the current buffer, + so as to return quickly if possible. Also, we needn't take the + lock in this fast path. + Don't know how to do that when whence == 2, though. */ + /* NOTE: RAW_TELL() can release the GIL but the object is in a stable + state at this point. */ + current = RAW_TELL(self); + avail = READAHEAD(self); + if (avail > 0) { + Py_off_t offset; + if (whence == 0) + offset = target - (current - RAW_OFFSET(self)); + else + offset = target; + if (offset >= -self->pos && offset <= avail) { + self->pos += offset; + return PyLong_FromOff_t(current - avail + offset); + } + } + } + + if (!ENTER_BUFFERED(self)) + return NULL; + + /* Fallback: invoke raw seek() method and clear buffer */ + if (self->writable) { + res = _bufferedwriter_flush_unlocked(self); + if (res == NULL) + goto end; + Py_CLEAR(res); + } + + /* TODO: align on block boundary and read buffer if needed? */ + if (whence == 1) + target -= RAW_OFFSET(self); + n = _buffered_raw_seek(self, target, whence); + if (n == -1) + goto end; + self->raw_pos = -1; + res = PyLong_FromOff_t(n); + if (res != NULL && self->readable) + _bufferedreader_reset_buf(self); + +end: + LEAVE_BUFFERED(self) + return res; +} + +/*[clinic input] +_io._Buffered.truncate + pos: object = None + / +[clinic start generated code]*/ + +static PyObject * +_io__Buffered_truncate_impl(buffered *self, PyObject *pos) +/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/ +{ + PyObject *res = NULL; + + CHECK_INITIALIZED(self) CHECK_CLOSED(self, "truncate of closed file") if (!self->writable) { return bufferediobase_unsupported("truncate"); } - if (!ENTER_BUFFERED(self)) - return NULL; - + if (!ENTER_BUFFERED(self)) + return NULL; + res = buffered_flush_and_rewind_unlocked(self); if (res == NULL) { goto end; - } + } Py_CLEAR(res); res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos); - if (res == NULL) - goto end; - /* Reset cached position */ - if (_buffered_raw_tell(self) == -1) - PyErr_Clear(); - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -buffered_iternext(buffered *self) -{ - PyObject *line; - PyTypeObject *tp; - - CHECK_INITIALIZED(self); - - tp = Py_TYPE(self); - if (tp == &PyBufferedReader_Type || - tp == &PyBufferedRandom_Type) { - /* Skip method call overhead for speed */ - line = _buffered_readline(self, -1); - } - else { + if (res == NULL) + goto end; + /* Reset cached position */ + if (_buffered_raw_tell(self) == -1) + PyErr_Clear(); + +end: + LEAVE_BUFFERED(self) + return res; +} + +static PyObject * +buffered_iternext(buffered *self) +{ + PyObject *line; + PyTypeObject *tp; + + CHECK_INITIALIZED(self); + + tp = Py_TYPE(self); + if (tp == &PyBufferedReader_Type || + tp == &PyBufferedRandom_Type) { + /* Skip method call overhead for speed */ + line = _buffered_readline(self, -1); + } + else { line = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_readline); - if (line && !PyBytes_Check(line)) { - PyErr_Format(PyExc_OSError, - "readline() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL) - return NULL; - - if (PyBytes_GET_SIZE(line) == 0) { - /* Reached EOF or would have blocked */ - Py_DECREF(line); - return NULL; - } - - return line; -} - -static PyObject * -buffered_repr(buffered *self) -{ - PyObject *nameobj, *res; - + if (line && !PyBytes_Check(line)) { + PyErr_Format(PyExc_OSError, + "readline() should have returned a bytes object, " + "not '%.200s'", Py_TYPE(line)->tp_name); + Py_DECREF(line); + return NULL; + } + } + + if (line == NULL) + return NULL; + + if (PyBytes_GET_SIZE(line) == 0) { + /* Reached EOF or would have blocked */ + Py_DECREF(line); + return NULL; + } + + return line; +} + +static PyObject * +buffered_repr(buffered *self) +{ + PyObject *nameobj, *res; + if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { if (!PyErr_ExceptionMatches(PyExc_ValueError)) { return NULL; @@ -1389,1340 +1389,1340 @@ buffered_repr(buffered *self) /* Ignore ValueError raised if the underlying stream was detached */ PyErr_Clear(); } - if (nameobj == NULL) { - res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name); - } - else { - int status = Py_ReprEnter((PyObject *)self); - res = NULL; - if (status == 0) { - res = PyUnicode_FromFormat("<%s name=%R>", - Py_TYPE(self)->tp_name, nameobj); - Py_ReprLeave((PyObject *)self); - } - else if (status > 0) { - PyErr_Format(PyExc_RuntimeError, - "reentrant call inside %s.__repr__", - Py_TYPE(self)->tp_name); - } - Py_DECREF(nameobj); - } - return res; -} - -/* - * class BufferedReader - */ - -static void _bufferedreader_reset_buf(buffered *self) -{ - self->read_end = -1; -} - -/*[clinic input] -_io.BufferedReader.__init__ - raw: object - buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE - -Create a new buffered reader using the given readable raw IO object. -[clinic start generated code]*/ - -static int -_io_BufferedReader___init___impl(buffered *self, PyObject *raw, - Py_ssize_t buffer_size) -/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/ -{ - self->ok = 0; - self->detached = 0; - - if (_PyIOBase_check_readable(raw, Py_True) == NULL) - return -1; - - Py_INCREF(raw); - Py_XSETREF(self->raw, raw); - self->buffer_size = buffer_size; - self->readable = 1; - self->writable = 0; - - if (_buffered_init(self) < 0) - return -1; - _bufferedreader_reset_buf(self); - + if (nameobj == NULL) { + res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name); + } + else { + int status = Py_ReprEnter((PyObject *)self); + res = NULL; + if (status == 0) { + res = PyUnicode_FromFormat("<%s name=%R>", + Py_TYPE(self)->tp_name, nameobj); + Py_ReprLeave((PyObject *)self); + } + else if (status > 0) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s.__repr__", + Py_TYPE(self)->tp_name); + } + Py_DECREF(nameobj); + } + return res; +} + +/* + * class BufferedReader + */ + +static void _bufferedreader_reset_buf(buffered *self) +{ + self->read_end = -1; +} + +/*[clinic input] +_io.BufferedReader.__init__ + raw: object + buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE + +Create a new buffered reader using the given readable raw IO object. +[clinic start generated code]*/ + +static int +_io_BufferedReader___init___impl(buffered *self, PyObject *raw, + Py_ssize_t buffer_size) +/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/ +{ + self->ok = 0; + self->detached = 0; + + if (_PyIOBase_check_readable(raw, Py_True) == NULL) + return -1; + + Py_INCREF(raw); + Py_XSETREF(self->raw, raw); + self->buffer_size = buffer_size; + self->readable = 1; + self->writable = 0; + + if (_buffered_init(self) < 0) + return -1; + _bufferedreader_reset_buf(self); + self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) && Py_IS_TYPE(raw, &PyFileIO_Type)); - - self->ok = 1; - return 0; -} - -static Py_ssize_t -_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len) -{ - Py_buffer buf; - PyObject *memobj, *res; - Py_ssize_t n; - /* NOTE: the buffer needn't be released as its object is NULL. */ - if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1) - return -1; - memobj = PyMemoryView_FromBuffer(&buf); - if (memobj == NULL) - return -1; - /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR - occurs so we needn't do it ourselves. - We then retry reading, ignoring the signal if no handler has - raised (see issue #10956). - */ - do { + + self->ok = 1; + return 0; +} + +static Py_ssize_t +_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len) +{ + Py_buffer buf; + PyObject *memobj, *res; + Py_ssize_t n; + /* NOTE: the buffer needn't be released as its object is NULL. */ + if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1) + return -1; + memobj = PyMemoryView_FromBuffer(&buf); + if (memobj == NULL) + return -1; + /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR + occurs so we needn't do it ourselves. + We then retry reading, ignoring the signal if no handler has + raised (see issue #10956). + */ + do { res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj); - } while (res == NULL && _PyIO_trap_eintr()); - Py_DECREF(memobj); - if (res == NULL) - return -1; - if (res == Py_None) { - /* Non-blocking stream would have blocked. Special return code! */ - Py_DECREF(res); - return -2; - } - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0 || n > len) { - PyErr_Format(PyExc_OSError, - "raw readinto() returned invalid length %zd " - "(should have been between 0 and %zd)", n, len); - return -1; - } - if (n > 0 && self->abs_pos != -1) - self->abs_pos += n; - return n; -} - -static Py_ssize_t -_bufferedreader_fill_buffer(buffered *self) -{ - Py_ssize_t start, len, n; - if (VALID_READ_BUFFER(self)) - start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t); - else - start = 0; - len = self->buffer_size - start; - n = _bufferedreader_raw_read(self, self->buffer + start, len); - if (n <= 0) - return n; - self->read_end = start + n; - self->raw_pos = start + n; - return n; -} - -static PyObject * -_bufferedreader_read_all(buffered *self) -{ - Py_ssize_t current_size; - PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall; - - /* First copy what we have in the current buffer. */ - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (current_size) { - data = PyBytes_FromStringAndSize( - self->buffer + self->pos, current_size); - if (data == NULL) - return NULL; - self->pos += current_size; - } - /* We're going past the buffer's bounds, flush it */ - if (self->writable) { - tmp = buffered_flush_and_rewind_unlocked(self); - if (tmp == NULL) - goto cleanup; - Py_CLEAR(tmp); - } - _bufferedreader_reset_buf(self); - - if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) { - goto cleanup; - } - if (readall) { - tmp = _PyObject_CallNoArg(readall); - Py_DECREF(readall); - if (tmp == NULL) - goto cleanup; - if (tmp != Py_None && !PyBytes_Check(tmp)) { - PyErr_SetString(PyExc_TypeError, "readall() should return bytes"); - goto cleanup; - } - if (current_size == 0) { - res = tmp; - } else { - if (tmp != Py_None) { - PyBytes_Concat(&data, tmp); - } - res = data; - } - goto cleanup; - } - - chunks = PyList_New(0); - if (chunks == NULL) - goto cleanup; - - while (1) { - if (data) { - if (PyList_Append(chunks, data) < 0) - goto cleanup; - Py_CLEAR(data); - } - - /* Read until EOF or until read() would block. */ + } while (res == NULL && _PyIO_trap_eintr()); + Py_DECREF(memobj); + if (res == NULL) + return -1; + if (res == Py_None) { + /* Non-blocking stream would have blocked. Special return code! */ + Py_DECREF(res); + return -2; + } + n = PyNumber_AsSsize_t(res, PyExc_ValueError); + Py_DECREF(res); + if (n < 0 || n > len) { + PyErr_Format(PyExc_OSError, + "raw readinto() returned invalid length %zd " + "(should have been between 0 and %zd)", n, len); + return -1; + } + if (n > 0 && self->abs_pos != -1) + self->abs_pos += n; + return n; +} + +static Py_ssize_t +_bufferedreader_fill_buffer(buffered *self) +{ + Py_ssize_t start, len, n; + if (VALID_READ_BUFFER(self)) + start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t); + else + start = 0; + len = self->buffer_size - start; + n = _bufferedreader_raw_read(self, self->buffer + start, len); + if (n <= 0) + return n; + self->read_end = start + n; + self->raw_pos = start + n; + return n; +} + +static PyObject * +_bufferedreader_read_all(buffered *self) +{ + Py_ssize_t current_size; + PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall; + + /* First copy what we have in the current buffer. */ + current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (current_size) { + data = PyBytes_FromStringAndSize( + self->buffer + self->pos, current_size); + if (data == NULL) + return NULL; + self->pos += current_size; + } + /* We're going past the buffer's bounds, flush it */ + if (self->writable) { + tmp = buffered_flush_and_rewind_unlocked(self); + if (tmp == NULL) + goto cleanup; + Py_CLEAR(tmp); + } + _bufferedreader_reset_buf(self); + + if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) { + goto cleanup; + } + if (readall) { + tmp = _PyObject_CallNoArg(readall); + Py_DECREF(readall); + if (tmp == NULL) + goto cleanup; + if (tmp != Py_None && !PyBytes_Check(tmp)) { + PyErr_SetString(PyExc_TypeError, "readall() should return bytes"); + goto cleanup; + } + if (current_size == 0) { + res = tmp; + } else { + if (tmp != Py_None) { + PyBytes_Concat(&data, tmp); + } + res = data; + } + goto cleanup; + } + + chunks = PyList_New(0); + if (chunks == NULL) + goto cleanup; + + while (1) { + if (data) { + if (PyList_Append(chunks, data) < 0) + goto cleanup; + Py_CLEAR(data); + } + + /* Read until EOF or until read() would block. */ data = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read); - if (data == NULL) - goto cleanup; - if (data != Py_None && !PyBytes_Check(data)) { - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - goto cleanup; - } - if (data == Py_None || PyBytes_GET_SIZE(data) == 0) { - if (current_size == 0) { - res = data; - goto cleanup; - } - else { - tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks); - res = tmp; - goto cleanup; - } - } - current_size += PyBytes_GET_SIZE(data); - if (self->abs_pos != -1) - self->abs_pos += PyBytes_GET_SIZE(data); - } -cleanup: - /* res is either NULL or a borrowed ref */ - Py_XINCREF(res); - Py_XDECREF(data); - Py_XDECREF(tmp); - Py_XDECREF(chunks); - return res; -} - -/* Read n bytes from the buffer if it can, otherwise return None. - This function is simple enough that it can run unlocked. */ -static PyObject * -_bufferedreader_read_fast(buffered *self, Py_ssize_t n) -{ - Py_ssize_t current_size; - - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (n <= current_size) { - /* Fast path: the data to read is fully buffered. */ - PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); - if (res != NULL) - self->pos += n; - return res; - } - Py_RETURN_NONE; -} - -/* Generic read function: read from the stream until enough bytes are read, - * or until an EOF occurs or until read() would block. - */ -static PyObject * -_bufferedreader_read_generic(buffered *self, Py_ssize_t n) -{ - PyObject *res = NULL; - Py_ssize_t current_size, remaining, written; - char *out; - - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (n <= current_size) - return _bufferedreader_read_fast(self, n); - - res = PyBytes_FromStringAndSize(NULL, n); - if (res == NULL) - goto error; - out = PyBytes_AS_STRING(res); - remaining = n; - written = 0; - if (current_size > 0) { - memcpy(out, self->buffer + self->pos, current_size); - remaining -= current_size; - written += current_size; - self->pos += current_size; - } - /* Flush the write buffer if necessary */ - if (self->writable) { - PyObject *r = buffered_flush_and_rewind_unlocked(self); - if (r == NULL) - goto error; - Py_DECREF(r); - } - _bufferedreader_reset_buf(self); - while (remaining > 0) { - /* We want to read a whole block at the end into buffer. - If we had readv() we could do this in one pass. */ - Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining); - if (r == 0) - break; - r = _bufferedreader_raw_read(self, out + written, r); - if (r == -1) - goto error; - if (r == 0 || r == -2) { - /* EOF occurred or read() would block. */ - if (r == 0 || written > 0) { - if (_PyBytes_Resize(&res, written)) - goto error; - return res; - } - Py_DECREF(res); - Py_RETURN_NONE; - } - remaining -= r; - written += r; - } - assert(remaining <= self->buffer_size); - self->pos = 0; - self->raw_pos = 0; - self->read_end = 0; - /* NOTE: when the read is satisfied, we avoid issuing any additional - reads, which could block indefinitely (e.g. on a socket). - See issue #9550. */ - while (remaining > 0 && self->read_end < self->buffer_size) { - Py_ssize_t r = _bufferedreader_fill_buffer(self); - if (r == -1) - goto error; - if (r == 0 || r == -2) { - /* EOF occurred or read() would block. */ - if (r == 0 || written > 0) { - if (_PyBytes_Resize(&res, written)) - goto error; - return res; - } - Py_DECREF(res); - Py_RETURN_NONE; - } - if (remaining > r) { - memcpy(out + written, self->buffer + self->pos, r); - written += r; - self->pos += r; - remaining -= r; - } - else if (remaining > 0) { - memcpy(out + written, self->buffer + self->pos, remaining); - written += remaining; - self->pos += remaining; - remaining = 0; - } - if (remaining == 0) - break; - } - - return res; - -error: - Py_XDECREF(res); - return NULL; -} - -static PyObject * -_bufferedreader_peek_unlocked(buffered *self) -{ - Py_ssize_t have, r; - - have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - /* Constraints: - 1. we don't want to advance the file position. - 2. we don't want to lose block alignment, so we can't shift the buffer - to make some place. - Therefore, we either return `have` bytes (if > 0), or a full buffer. - */ - if (have > 0) { - return PyBytes_FromStringAndSize(self->buffer + self->pos, have); - } - - /* Fill the buffer from the raw stream, and copy it to the result. */ - _bufferedreader_reset_buf(self); - r = _bufferedreader_fill_buffer(self); - if (r == -1) - return NULL; - if (r == -2) - r = 0; - self->pos = 0; - return PyBytes_FromStringAndSize(self->buffer, r); -} - - - -/* - * class BufferedWriter - */ -static void -_bufferedwriter_reset_buf(buffered *self) -{ - self->write_pos = 0; - self->write_end = -1; -} - -/*[clinic input] -_io.BufferedWriter.__init__ - raw: object - buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE - -A buffer for a writeable sequential RawIO object. - -The constructor creates a BufferedWriter for the given writeable raw -stream. If the buffer_size is not given, it defaults to -DEFAULT_BUFFER_SIZE. -[clinic start generated code]*/ - -static int -_io_BufferedWriter___init___impl(buffered *self, PyObject *raw, - Py_ssize_t buffer_size) -/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/ -{ - self->ok = 0; - self->detached = 0; - - if (_PyIOBase_check_writable(raw, Py_True) == NULL) - return -1; - - Py_INCREF(raw); - Py_XSETREF(self->raw, raw); - self->readable = 0; - self->writable = 1; - - self->buffer_size = buffer_size; - if (_buffered_init(self) < 0) - return -1; - _bufferedwriter_reset_buf(self); - self->pos = 0; - + if (data == NULL) + goto cleanup; + if (data != Py_None && !PyBytes_Check(data)) { + PyErr_SetString(PyExc_TypeError, "read() should return bytes"); + goto cleanup; + } + if (data == Py_None || PyBytes_GET_SIZE(data) == 0) { + if (current_size == 0) { + res = data; + goto cleanup; + } + else { + tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks); + res = tmp; + goto cleanup; + } + } + current_size += PyBytes_GET_SIZE(data); + if (self->abs_pos != -1) + self->abs_pos += PyBytes_GET_SIZE(data); + } +cleanup: + /* res is either NULL or a borrowed ref */ + Py_XINCREF(res); + Py_XDECREF(data); + Py_XDECREF(tmp); + Py_XDECREF(chunks); + return res; +} + +/* Read n bytes from the buffer if it can, otherwise return None. + This function is simple enough that it can run unlocked. */ +static PyObject * +_bufferedreader_read_fast(buffered *self, Py_ssize_t n) +{ + Py_ssize_t current_size; + + current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (n <= current_size) { + /* Fast path: the data to read is fully buffered. */ + PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); + if (res != NULL) + self->pos += n; + return res; + } + Py_RETURN_NONE; +} + +/* Generic read function: read from the stream until enough bytes are read, + * or until an EOF occurs or until read() would block. + */ +static PyObject * +_bufferedreader_read_generic(buffered *self, Py_ssize_t n) +{ + PyObject *res = NULL; + Py_ssize_t current_size, remaining, written; + char *out; + + current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (n <= current_size) + return _bufferedreader_read_fast(self, n); + + res = PyBytes_FromStringAndSize(NULL, n); + if (res == NULL) + goto error; + out = PyBytes_AS_STRING(res); + remaining = n; + written = 0; + if (current_size > 0) { + memcpy(out, self->buffer + self->pos, current_size); + remaining -= current_size; + written += current_size; + self->pos += current_size; + } + /* Flush the write buffer if necessary */ + if (self->writable) { + PyObject *r = buffered_flush_and_rewind_unlocked(self); + if (r == NULL) + goto error; + Py_DECREF(r); + } + _bufferedreader_reset_buf(self); + while (remaining > 0) { + /* We want to read a whole block at the end into buffer. + If we had readv() we could do this in one pass. */ + Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining); + if (r == 0) + break; + r = _bufferedreader_raw_read(self, out + written, r); + if (r == -1) + goto error; + if (r == 0 || r == -2) { + /* EOF occurred or read() would block. */ + if (r == 0 || written > 0) { + if (_PyBytes_Resize(&res, written)) + goto error; + return res; + } + Py_DECREF(res); + Py_RETURN_NONE; + } + remaining -= r; + written += r; + } + assert(remaining <= self->buffer_size); + self->pos = 0; + self->raw_pos = 0; + self->read_end = 0; + /* NOTE: when the read is satisfied, we avoid issuing any additional + reads, which could block indefinitely (e.g. on a socket). + See issue #9550. */ + while (remaining > 0 && self->read_end < self->buffer_size) { + Py_ssize_t r = _bufferedreader_fill_buffer(self); + if (r == -1) + goto error; + if (r == 0 || r == -2) { + /* EOF occurred or read() would block. */ + if (r == 0 || written > 0) { + if (_PyBytes_Resize(&res, written)) + goto error; + return res; + } + Py_DECREF(res); + Py_RETURN_NONE; + } + if (remaining > r) { + memcpy(out + written, self->buffer + self->pos, r); + written += r; + self->pos += r; + remaining -= r; + } + else if (remaining > 0) { + memcpy(out + written, self->buffer + self->pos, remaining); + written += remaining; + self->pos += remaining; + remaining = 0; + } + if (remaining == 0) + break; + } + + return res; + +error: + Py_XDECREF(res); + return NULL; +} + +static PyObject * +_bufferedreader_peek_unlocked(buffered *self) +{ + Py_ssize_t have, r; + + have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + /* Constraints: + 1. we don't want to advance the file position. + 2. we don't want to lose block alignment, so we can't shift the buffer + to make some place. + Therefore, we either return `have` bytes (if > 0), or a full buffer. + */ + if (have > 0) { + return PyBytes_FromStringAndSize(self->buffer + self->pos, have); + } + + /* Fill the buffer from the raw stream, and copy it to the result. */ + _bufferedreader_reset_buf(self); + r = _bufferedreader_fill_buffer(self); + if (r == -1) + return NULL; + if (r == -2) + r = 0; + self->pos = 0; + return PyBytes_FromStringAndSize(self->buffer, r); +} + + + +/* + * class BufferedWriter + */ +static void +_bufferedwriter_reset_buf(buffered *self) +{ + self->write_pos = 0; + self->write_end = -1; +} + +/*[clinic input] +_io.BufferedWriter.__init__ + raw: object + buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE + +A buffer for a writeable sequential RawIO object. + +The constructor creates a BufferedWriter for the given writeable raw +stream. If the buffer_size is not given, it defaults to +DEFAULT_BUFFER_SIZE. +[clinic start generated code]*/ + +static int +_io_BufferedWriter___init___impl(buffered *self, PyObject *raw, + Py_ssize_t buffer_size) +/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/ +{ + self->ok = 0; + self->detached = 0; + + if (_PyIOBase_check_writable(raw, Py_True) == NULL) + return -1; + + Py_INCREF(raw); + Py_XSETREF(self->raw, raw); + self->readable = 0; + self->writable = 1; + + self->buffer_size = buffer_size; + if (_buffered_init(self) < 0) + return -1; + _bufferedwriter_reset_buf(self); + self->pos = 0; + self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) && Py_IS_TYPE(raw, &PyFileIO_Type)); - - self->ok = 1; - return 0; -} - -static Py_ssize_t -_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len) -{ - Py_buffer buf; - PyObject *memobj, *res; - Py_ssize_t n; - int errnum; - /* NOTE: the buffer needn't be released as its object is NULL. */ - if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1) - return -1; - memobj = PyMemoryView_FromBuffer(&buf); - if (memobj == NULL) - return -1; - /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR - occurs so we needn't do it ourselves. - We then retry writing, ignoring the signal if no handler has - raised (see issue #10956). - */ - do { - errno = 0; + + self->ok = 1; + return 0; +} + +static Py_ssize_t +_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len) +{ + Py_buffer buf; + PyObject *memobj, *res; + Py_ssize_t n; + int errnum; + /* NOTE: the buffer needn't be released as its object is NULL. */ + if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1) + return -1; + memobj = PyMemoryView_FromBuffer(&buf); + if (memobj == NULL) + return -1; + /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR + occurs so we needn't do it ourselves. + We then retry writing, ignoring the signal if no handler has + raised (see issue #10956). + */ + do { + errno = 0; res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj); - errnum = errno; - } while (res == NULL && _PyIO_trap_eintr()); - Py_DECREF(memobj); - if (res == NULL) - return -1; - if (res == Py_None) { - /* Non-blocking stream would have blocked. Special return code! - Being paranoid we reset errno in case it is changed by code - triggered by a decref. errno is used by _set_BlockingIOError(). */ - Py_DECREF(res); - errno = errnum; - return -2; - } - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0 || n > len) { - PyErr_Format(PyExc_OSError, - "raw write() returned invalid length %zd " - "(should have been between 0 and %zd)", n, len); - return -1; - } - if (n > 0 && self->abs_pos != -1) - self->abs_pos += n; - return n; -} - -static PyObject * -_bufferedwriter_flush_unlocked(buffered *self) -{ - Py_ssize_t written = 0; - Py_off_t n, rewind; - - if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end) - goto end; - /* First, rewind */ - rewind = RAW_OFFSET(self) + (self->pos - self->write_pos); - if (rewind != 0) { - n = _buffered_raw_seek(self, -rewind, 1); - if (n < 0) { - goto error; - } - self->raw_pos -= rewind; - } - while (self->write_pos < self->write_end) { - n = _bufferedwriter_raw_write(self, - self->buffer + self->write_pos, - Py_SAFE_DOWNCAST(self->write_end - self->write_pos, - Py_off_t, Py_ssize_t)); - if (n == -1) { - goto error; - } - else if (n == -2) { - _set_BlockingIOError("write could not complete without blocking", - 0); - goto error; - } - self->write_pos += n; - self->raw_pos = self->write_pos; - written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t); - /* Partial writes can return successfully when interrupted by a - signal (see write(2)). We must run signal handlers before - blocking another time, possibly indefinitely. */ - if (PyErr_CheckSignals() < 0) - goto error; - } - - -end: - /* This ensures that after return from this function, - VALID_WRITE_BUFFER(self) returns false. - - This is a required condition because when a tell() is called - after flushing and if VALID_READ_BUFFER(self) is false, we need - VALID_WRITE_BUFFER(self) to be false to have - RAW_OFFSET(self) == 0. - - Issue: https://bugs.python.org/issue32228 */ - _bufferedwriter_reset_buf(self); - Py_RETURN_NONE; - -error: - return NULL; -} - -/*[clinic input] -_io.BufferedWriter.write - buffer: Py_buffer - / -[clinic start generated code]*/ - -static PyObject * -_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer) -/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/ -{ - PyObject *res = NULL; - Py_ssize_t written, avail, remaining; - Py_off_t offset; - - CHECK_INITIALIZED(self) - - if (!ENTER_BUFFERED(self)) - return NULL; - - /* Issue #31976: Check for closed file after acquiring the lock. Another - thread could be holding the lock while closing the file. */ - if (IS_CLOSED(self)) { - PyErr_SetString(PyExc_ValueError, "write to closed file"); - goto error; - } - - /* Fast path: the data to write can be fully buffered. */ - if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { - self->pos = 0; - self->raw_pos = 0; - } - avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t); - if (buffer->len <= avail) { - memcpy(self->buffer + self->pos, buffer->buf, buffer->len); - if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) { - self->write_pos = self->pos; - } - ADJUST_POSITION(self, self->pos + buffer->len); - if (self->pos > self->write_end) - self->write_end = self->pos; - written = buffer->len; - goto end; - } - - /* First write the current buffer */ - res = _bufferedwriter_flush_unlocked(self); - if (res == NULL) { - Py_ssize_t *w = _buffered_check_blocking_error(); - if (w == NULL) - goto error; - if (self->readable) - _bufferedreader_reset_buf(self); - /* Make some place by shifting the buffer. */ - assert(VALID_WRITE_BUFFER(self)); - memmove(self->buffer, self->buffer + self->write_pos, - Py_SAFE_DOWNCAST(self->write_end - self->write_pos, - Py_off_t, Py_ssize_t)); - self->write_end -= self->write_pos; - self->raw_pos -= self->write_pos; - self->pos -= self->write_pos; - self->write_pos = 0; - avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end, - Py_off_t, Py_ssize_t); - if (buffer->len <= avail) { - /* Everything can be buffered */ - PyErr_Clear(); - memcpy(self->buffer + self->write_end, buffer->buf, buffer->len); - self->write_end += buffer->len; - self->pos += buffer->len; - written = buffer->len; - goto end; - } - /* Buffer as much as possible. */ - memcpy(self->buffer + self->write_end, buffer->buf, avail); - self->write_end += avail; - self->pos += avail; - /* XXX Modifying the existing exception e using the pointer w - will change e.characters_written but not e.args[2]. - Therefore we just replace with a new error. */ - _set_BlockingIOError("write could not complete without blocking", - avail); - goto error; - } - Py_CLEAR(res); - - /* Adjust the raw stream position if it is away from the logical stream - position. This happens if the read buffer has been filled but not - modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind - the raw stream by itself). - Fixes issue #6629. - */ - offset = RAW_OFFSET(self); - if (offset != 0) { - if (_buffered_raw_seek(self, -offset, 1) < 0) - goto error; - self->raw_pos -= offset; - } - - /* Then write buf itself. At this point the buffer has been emptied. */ - remaining = buffer->len; - written = 0; - while (remaining > self->buffer_size) { - Py_ssize_t n = _bufferedwriter_raw_write( - self, (char *) buffer->buf + written, buffer->len - written); - if (n == -1) { - goto error; - } else if (n == -2) { - /* Write failed because raw file is non-blocking */ - if (remaining > self->buffer_size) { - /* Can't buffer everything, still buffer as much as possible */ - memcpy(self->buffer, - (char *) buffer->buf + written, self->buffer_size); - self->raw_pos = 0; - ADJUST_POSITION(self, self->buffer_size); - self->write_end = self->buffer_size; - written += self->buffer_size; - _set_BlockingIOError("write could not complete without " - "blocking", written); - goto error; - } - PyErr_Clear(); - break; - } - written += n; - remaining -= n; - /* Partial writes can return successfully when interrupted by a - signal (see write(2)). We must run signal handlers before - blocking another time, possibly indefinitely. */ - if (PyErr_CheckSignals() < 0) - goto error; - } - if (self->readable) - _bufferedreader_reset_buf(self); - if (remaining > 0) { - memcpy(self->buffer, (char *) buffer->buf + written, remaining); - written += remaining; - } - self->write_pos = 0; - /* TODO: sanity check (remaining >= 0) */ - self->write_end = remaining; - ADJUST_POSITION(self, remaining); - self->raw_pos = 0; - -end: - res = PyLong_FromSsize_t(written); - -error: - LEAVE_BUFFERED(self) - return res; -} - - - -/* - * BufferedRWPair - */ - -/* XXX The usefulness of this (compared to having two separate IO objects) is - * questionable. - */ - -typedef struct { - PyObject_HEAD - buffered *reader; - buffered *writer; - PyObject *dict; - PyObject *weakreflist; -} rwpair; - -/*[clinic input] -_io.BufferedRWPair.__init__ - reader: object - writer: object - buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE - / - -A buffered reader and writer object together. - -A buffered reader object and buffered writer object put together to -form a sequential IO object that can read and write. This is typically -used with a socket or two-way pipe. - -reader and writer are RawIOBase objects that are readable and -writeable respectively. If the buffer_size is omitted it defaults to -DEFAULT_BUFFER_SIZE. -[clinic start generated code]*/ - -static int -_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader, - PyObject *writer, Py_ssize_t buffer_size) -/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/ -{ - if (_PyIOBase_check_readable(reader, Py_True) == NULL) - return -1; - if (_PyIOBase_check_writable(writer, Py_True) == NULL) - return -1; - - self->reader = (buffered *) PyObject_CallFunction( - (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size); - if (self->reader == NULL) - return -1; - - self->writer = (buffered *) PyObject_CallFunction( - (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size); - if (self->writer == NULL) { - Py_CLEAR(self->reader); - return -1; - } - - return 0; -} - -static int -bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -bufferedrwpair_clear(rwpair *self) -{ - Py_CLEAR(self->reader); - Py_CLEAR(self->writer); - Py_CLEAR(self->dict); - return 0; -} - -static void -bufferedrwpair_dealloc(rwpair *self) -{ - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->reader); - Py_CLEAR(self->writer); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -_forward_call(buffered *self, _Py_Identifier *name, PyObject *args) -{ - PyObject *func, *ret; - if (self == NULL) { - PyErr_SetString(PyExc_ValueError, - "I/O operation on uninitialized object"); - return NULL; - } - - func = _PyObject_GetAttrId((PyObject *)self, name); - if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, name->string); - return NULL; - } - - ret = PyObject_CallObject(func, args); - Py_DECREF(func); - return ret; -} - -static PyObject * -bufferedrwpair_read(rwpair *self, PyObject *args) -{ - return _forward_call(self->reader, &PyId_read, args); -} - -static PyObject * -bufferedrwpair_peek(rwpair *self, PyObject *args) -{ - return _forward_call(self->reader, &PyId_peek, args); -} - -static PyObject * -bufferedrwpair_read1(rwpair *self, PyObject *args) -{ - return _forward_call(self->reader, &PyId_read1, args); -} - -static PyObject * -bufferedrwpair_readinto(rwpair *self, PyObject *args) -{ - return _forward_call(self->reader, &PyId_readinto, args); -} - -static PyObject * -bufferedrwpair_readinto1(rwpair *self, PyObject *args) -{ - return _forward_call(self->reader, &PyId_readinto1, args); -} - -static PyObject * -bufferedrwpair_write(rwpair *self, PyObject *args) -{ - return _forward_call(self->writer, &PyId_write, args); -} - -static PyObject * + errnum = errno; + } while (res == NULL && _PyIO_trap_eintr()); + Py_DECREF(memobj); + if (res == NULL) + return -1; + if (res == Py_None) { + /* Non-blocking stream would have blocked. Special return code! + Being paranoid we reset errno in case it is changed by code + triggered by a decref. errno is used by _set_BlockingIOError(). */ + Py_DECREF(res); + errno = errnum; + return -2; + } + n = PyNumber_AsSsize_t(res, PyExc_ValueError); + Py_DECREF(res); + if (n < 0 || n > len) { + PyErr_Format(PyExc_OSError, + "raw write() returned invalid length %zd " + "(should have been between 0 and %zd)", n, len); + return -1; + } + if (n > 0 && self->abs_pos != -1) + self->abs_pos += n; + return n; +} + +static PyObject * +_bufferedwriter_flush_unlocked(buffered *self) +{ + Py_ssize_t written = 0; + Py_off_t n, rewind; + + if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end) + goto end; + /* First, rewind */ + rewind = RAW_OFFSET(self) + (self->pos - self->write_pos); + if (rewind != 0) { + n = _buffered_raw_seek(self, -rewind, 1); + if (n < 0) { + goto error; + } + self->raw_pos -= rewind; + } + while (self->write_pos < self->write_end) { + n = _bufferedwriter_raw_write(self, + self->buffer + self->write_pos, + Py_SAFE_DOWNCAST(self->write_end - self->write_pos, + Py_off_t, Py_ssize_t)); + if (n == -1) { + goto error; + } + else if (n == -2) { + _set_BlockingIOError("write could not complete without blocking", + 0); + goto error; + } + self->write_pos += n; + self->raw_pos = self->write_pos; + written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t); + /* Partial writes can return successfully when interrupted by a + signal (see write(2)). We must run signal handlers before + blocking another time, possibly indefinitely. */ + if (PyErr_CheckSignals() < 0) + goto error; + } + + +end: + /* This ensures that after return from this function, + VALID_WRITE_BUFFER(self) returns false. + + This is a required condition because when a tell() is called + after flushing and if VALID_READ_BUFFER(self) is false, we need + VALID_WRITE_BUFFER(self) to be false to have + RAW_OFFSET(self) == 0. + + Issue: https://bugs.python.org/issue32228 */ + _bufferedwriter_reset_buf(self); + Py_RETURN_NONE; + +error: + return NULL; +} + +/*[clinic input] +_io.BufferedWriter.write + buffer: Py_buffer + / +[clinic start generated code]*/ + +static PyObject * +_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer) +/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/ +{ + PyObject *res = NULL; + Py_ssize_t written, avail, remaining; + Py_off_t offset; + + CHECK_INITIALIZED(self) + + if (!ENTER_BUFFERED(self)) + return NULL; + + /* Issue #31976: Check for closed file after acquiring the lock. Another + thread could be holding the lock while closing the file. */ + if (IS_CLOSED(self)) { + PyErr_SetString(PyExc_ValueError, "write to closed file"); + goto error; + } + + /* Fast path: the data to write can be fully buffered. */ + if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { + self->pos = 0; + self->raw_pos = 0; + } + avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t); + if (buffer->len <= avail) { + memcpy(self->buffer + self->pos, buffer->buf, buffer->len); + if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) { + self->write_pos = self->pos; + } + ADJUST_POSITION(self, self->pos + buffer->len); + if (self->pos > self->write_end) + self->write_end = self->pos; + written = buffer->len; + goto end; + } + + /* First write the current buffer */ + res = _bufferedwriter_flush_unlocked(self); + if (res == NULL) { + Py_ssize_t *w = _buffered_check_blocking_error(); + if (w == NULL) + goto error; + if (self->readable) + _bufferedreader_reset_buf(self); + /* Make some place by shifting the buffer. */ + assert(VALID_WRITE_BUFFER(self)); + memmove(self->buffer, self->buffer + self->write_pos, + Py_SAFE_DOWNCAST(self->write_end - self->write_pos, + Py_off_t, Py_ssize_t)); + self->write_end -= self->write_pos; + self->raw_pos -= self->write_pos; + self->pos -= self->write_pos; + self->write_pos = 0; + avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end, + Py_off_t, Py_ssize_t); + if (buffer->len <= avail) { + /* Everything can be buffered */ + PyErr_Clear(); + memcpy(self->buffer + self->write_end, buffer->buf, buffer->len); + self->write_end += buffer->len; + self->pos += buffer->len; + written = buffer->len; + goto end; + } + /* Buffer as much as possible. */ + memcpy(self->buffer + self->write_end, buffer->buf, avail); + self->write_end += avail; + self->pos += avail; + /* XXX Modifying the existing exception e using the pointer w + will change e.characters_written but not e.args[2]. + Therefore we just replace with a new error. */ + _set_BlockingIOError("write could not complete without blocking", + avail); + goto error; + } + Py_CLEAR(res); + + /* Adjust the raw stream position if it is away from the logical stream + position. This happens if the read buffer has been filled but not + modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind + the raw stream by itself). + Fixes issue #6629. + */ + offset = RAW_OFFSET(self); + if (offset != 0) { + if (_buffered_raw_seek(self, -offset, 1) < 0) + goto error; + self->raw_pos -= offset; + } + + /* Then write buf itself. At this point the buffer has been emptied. */ + remaining = buffer->len; + written = 0; + while (remaining > self->buffer_size) { + Py_ssize_t n = _bufferedwriter_raw_write( + self, (char *) buffer->buf + written, buffer->len - written); + if (n == -1) { + goto error; + } else if (n == -2) { + /* Write failed because raw file is non-blocking */ + if (remaining > self->buffer_size) { + /* Can't buffer everything, still buffer as much as possible */ + memcpy(self->buffer, + (char *) buffer->buf + written, self->buffer_size); + self->raw_pos = 0; + ADJUST_POSITION(self, self->buffer_size); + self->write_end = self->buffer_size; + written += self->buffer_size; + _set_BlockingIOError("write could not complete without " + "blocking", written); + goto error; + } + PyErr_Clear(); + break; + } + written += n; + remaining -= n; + /* Partial writes can return successfully when interrupted by a + signal (see write(2)). We must run signal handlers before + blocking another time, possibly indefinitely. */ + if (PyErr_CheckSignals() < 0) + goto error; + } + if (self->readable) + _bufferedreader_reset_buf(self); + if (remaining > 0) { + memcpy(self->buffer, (char *) buffer->buf + written, remaining); + written += remaining; + } + self->write_pos = 0; + /* TODO: sanity check (remaining >= 0) */ + self->write_end = remaining; + ADJUST_POSITION(self, remaining); + self->raw_pos = 0; + +end: + res = PyLong_FromSsize_t(written); + +error: + LEAVE_BUFFERED(self) + return res; +} + + + +/* + * BufferedRWPair + */ + +/* XXX The usefulness of this (compared to having two separate IO objects) is + * questionable. + */ + +typedef struct { + PyObject_HEAD + buffered *reader; + buffered *writer; + PyObject *dict; + PyObject *weakreflist; +} rwpair; + +/*[clinic input] +_io.BufferedRWPair.__init__ + reader: object + writer: object + buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE + / + +A buffered reader and writer object together. + +A buffered reader object and buffered writer object put together to +form a sequential IO object that can read and write. This is typically +used with a socket or two-way pipe. + +reader and writer are RawIOBase objects that are readable and +writeable respectively. If the buffer_size is omitted it defaults to +DEFAULT_BUFFER_SIZE. +[clinic start generated code]*/ + +static int +_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader, + PyObject *writer, Py_ssize_t buffer_size) +/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/ +{ + if (_PyIOBase_check_readable(reader, Py_True) == NULL) + return -1; + if (_PyIOBase_check_writable(writer, Py_True) == NULL) + return -1; + + self->reader = (buffered *) PyObject_CallFunction( + (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size); + if (self->reader == NULL) + return -1; + + self->writer = (buffered *) PyObject_CallFunction( + (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size); + if (self->writer == NULL) { + Py_CLEAR(self->reader); + return -1; + } + + return 0; +} + +static int +bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +bufferedrwpair_clear(rwpair *self) +{ + Py_CLEAR(self->reader); + Py_CLEAR(self->writer); + Py_CLEAR(self->dict); + return 0; +} + +static void +bufferedrwpair_dealloc(rwpair *self) +{ + _PyObject_GC_UNTRACK(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)self); + Py_CLEAR(self->reader); + Py_CLEAR(self->writer); + Py_CLEAR(self->dict); + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static PyObject * +_forward_call(buffered *self, _Py_Identifier *name, PyObject *args) +{ + PyObject *func, *ret; + if (self == NULL) { + PyErr_SetString(PyExc_ValueError, + "I/O operation on uninitialized object"); + return NULL; + } + + func = _PyObject_GetAttrId((PyObject *)self, name); + if (func == NULL) { + PyErr_SetString(PyExc_AttributeError, name->string); + return NULL; + } + + ret = PyObject_CallObject(func, args); + Py_DECREF(func); + return ret; +} + +static PyObject * +bufferedrwpair_read(rwpair *self, PyObject *args) +{ + return _forward_call(self->reader, &PyId_read, args); +} + +static PyObject * +bufferedrwpair_peek(rwpair *self, PyObject *args) +{ + return _forward_call(self->reader, &PyId_peek, args); +} + +static PyObject * +bufferedrwpair_read1(rwpair *self, PyObject *args) +{ + return _forward_call(self->reader, &PyId_read1, args); +} + +static PyObject * +bufferedrwpair_readinto(rwpair *self, PyObject *args) +{ + return _forward_call(self->reader, &PyId_readinto, args); +} + +static PyObject * +bufferedrwpair_readinto1(rwpair *self, PyObject *args) +{ + return _forward_call(self->reader, &PyId_readinto1, args); +} + +static PyObject * +bufferedrwpair_write(rwpair *self, PyObject *args) +{ + return _forward_call(self->writer, &PyId_write, args); +} + +static PyObject * bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored)) -{ +{ return _forward_call(self->writer, &PyId_flush, NULL); -} - -static PyObject * +} + +static PyObject * bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored)) -{ +{ return _forward_call(self->reader, &PyId_readable, NULL); -} - -static PyObject * +} + +static PyObject * bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored)) -{ +{ return _forward_call(self->writer, &PyId_writable, NULL); -} - -static PyObject * +} + +static PyObject * bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *exc = NULL, *val, *tb; +{ + PyObject *exc = NULL, *val, *tb; PyObject *ret = _forward_call(self->writer, &PyId_close, NULL); - if (ret == NULL) - PyErr_Fetch(&exc, &val, &tb); - else - Py_DECREF(ret); + if (ret == NULL) + PyErr_Fetch(&exc, &val, &tb); + else + Py_DECREF(ret); ret = _forward_call(self->reader, &PyId_close, NULL); - if (exc != NULL) { - _PyErr_ChainExceptions(exc, val, tb); - Py_CLEAR(ret); - } - return ret; -} - -static PyObject * + if (exc != NULL) { + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(ret); + } + return ret; +} + +static PyObject * bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored)) -{ +{ PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL); - - if (ret != Py_False) { - /* either True or exception */ - return ret; - } - Py_DECREF(ret); - + + if (ret != Py_False) { + /* either True or exception */ + return ret; + } + Py_DECREF(ret); + return _forward_call(self->reader, &PyId_isatty, NULL); -} - -static PyObject * -bufferedrwpair_closed_get(rwpair *self, void *context) -{ - if (self->writer == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "the BufferedRWPair object is being garbage-collected"); - return NULL; - } - return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed); -} - - - -/* - * BufferedRandom - */ - -/*[clinic input] -_io.BufferedRandom.__init__ - raw: object - buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE - -A buffered interface to random access streams. - -The constructor creates a reader and writer for a seekable stream, -raw, given in the first argument. If the buffer_size is omitted it -defaults to DEFAULT_BUFFER_SIZE. -[clinic start generated code]*/ - -static int -_io_BufferedRandom___init___impl(buffered *self, PyObject *raw, - Py_ssize_t buffer_size) -/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/ -{ - self->ok = 0; - self->detached = 0; - - if (_PyIOBase_check_seekable(raw, Py_True) == NULL) - return -1; - if (_PyIOBase_check_readable(raw, Py_True) == NULL) - return -1; - if (_PyIOBase_check_writable(raw, Py_True) == NULL) - return -1; - - Py_INCREF(raw); - Py_XSETREF(self->raw, raw); - self->buffer_size = buffer_size; - self->readable = 1; - self->writable = 1; - - if (_buffered_init(self) < 0) - return -1; - _bufferedreader_reset_buf(self); - _bufferedwriter_reset_buf(self); - self->pos = 0; - +} + +static PyObject * +bufferedrwpair_closed_get(rwpair *self, void *context) +{ + if (self->writer == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "the BufferedRWPair object is being garbage-collected"); + return NULL; + } + return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed); +} + + + +/* + * BufferedRandom + */ + +/*[clinic input] +_io.BufferedRandom.__init__ + raw: object + buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE + +A buffered interface to random access streams. + +The constructor creates a reader and writer for a seekable stream, +raw, given in the first argument. If the buffer_size is omitted it +defaults to DEFAULT_BUFFER_SIZE. +[clinic start generated code]*/ + +static int +_io_BufferedRandom___init___impl(buffered *self, PyObject *raw, + Py_ssize_t buffer_size) +/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/ +{ + self->ok = 0; + self->detached = 0; + + if (_PyIOBase_check_seekable(raw, Py_True) == NULL) + return -1; + if (_PyIOBase_check_readable(raw, Py_True) == NULL) + return -1; + if (_PyIOBase_check_writable(raw, Py_True) == NULL) + return -1; + + Py_INCREF(raw); + Py_XSETREF(self->raw, raw); + self->buffer_size = buffer_size; + self->readable = 1; + self->writable = 1; + + if (_buffered_init(self) < 0) + return -1; + _bufferedreader_reset_buf(self); + _bufferedwriter_reset_buf(self); + self->pos = 0; + self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) && Py_IS_TYPE(raw, &PyFileIO_Type)); - - self->ok = 1; - return 0; -} - -#include "clinic/bufferedio.c.h" - - -static PyMethodDef bufferediobase_methods[] = { - _IO__BUFFEREDIOBASE_DETACH_METHODDEF - {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc}, - {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc}, - _IO__BUFFEREDIOBASE_READINTO_METHODDEF - _IO__BUFFEREDIOBASE_READINTO1_METHODDEF - {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc}, - {NULL, NULL} -}; - -PyTypeObject PyBufferedIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._BufferedIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ + + self->ok = 1; + return 0; +} + +#include "clinic/bufferedio.c.h" + + +static PyMethodDef bufferediobase_methods[] = { + _IO__BUFFEREDIOBASE_DETACH_METHODDEF + {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc}, + {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc}, + _IO__BUFFEREDIOBASE_READINTO_METHODDEF + _IO__BUFFEREDIOBASE_READINTO1_METHODDEF + {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc}, + {NULL, NULL} +}; + +PyTypeObject PyBufferedIOBase_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io._BufferedIOBase", /*tp_name*/ + 0, /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 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_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - bufferediobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - bufferediobase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; - - -static PyMethodDef bufferedreader_methods[] = { - /* BufferedIOMixin methods */ - {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, - {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS}, - {"close", (PyCFunction)buffered_close, METH_NOARGS}, - {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, - {"readable", (PyCFunction)buffered_readable, METH_NOARGS}, - {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, - {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, - - _IO__BUFFERED_READ_METHODDEF - _IO__BUFFERED_PEEK_METHODDEF - _IO__BUFFERED_READ1_METHODDEF - _IO__BUFFERED_READINTO_METHODDEF - _IO__BUFFERED_READINTO1_METHODDEF - _IO__BUFFERED_READLINE_METHODDEF - _IO__BUFFERED_SEEK_METHODDEF - {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, - _IO__BUFFERED_TRUNCATE_METHODDEF - {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, - {NULL, NULL} -}; - -static PyMemberDef bufferedreader_members[] = { - {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, - {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, - {NULL} -}; - -static PyGetSetDef bufferedreader_getset[] = { - {"closed", (getter)buffered_closed_get, NULL, NULL}, - {"name", (getter)buffered_name_get, NULL, NULL}, - {"mode", (getter)buffered_mode_get, NULL, NULL}, - {NULL} -}; - - -PyTypeObject PyBufferedReader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedReader", /*tp_name*/ - sizeof(buffered), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)buffered_dealloc, /*tp_dealloc*/ + bufferediobase_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + bufferediobase_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyIOBase_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; + + +static PyMethodDef bufferedreader_methods[] = { + /* BufferedIOMixin methods */ + {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, + {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS}, + {"close", (PyCFunction)buffered_close, METH_NOARGS}, + {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, + {"readable", (PyCFunction)buffered_readable, METH_NOARGS}, + {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, + {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, + {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, + + _IO__BUFFERED_READ_METHODDEF + _IO__BUFFERED_PEEK_METHODDEF + _IO__BUFFERED_READ1_METHODDEF + _IO__BUFFERED_READINTO_METHODDEF + _IO__BUFFERED_READINTO1_METHODDEF + _IO__BUFFERED_READLINE_METHODDEF + _IO__BUFFERED_SEEK_METHODDEF + {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, + _IO__BUFFERED_TRUNCATE_METHODDEF + {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, + {NULL, NULL} +}; + +static PyMemberDef bufferedreader_members[] = { + {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, + {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, + {NULL} +}; + +static PyGetSetDef bufferedreader_getset[] = { + {"closed", (getter)buffered_closed_get, NULL, NULL}, + {"name", (getter)buffered_name_get, NULL, NULL}, + {"mode", (getter)buffered_mode_get, NULL, NULL}, + {NULL} +}; + + +PyTypeObject PyBufferedReader_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.BufferedReader", /*tp_name*/ + sizeof(buffered), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)buffered_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - (reprfunc)buffered_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*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + (reprfunc)buffered_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*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_BufferedReader___init____doc__, /* tp_doc */ - (traverseproc)buffered_traverse, /* tp_traverse */ - (inquiry)buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)buffered_iternext, /* tp_iternext */ - bufferedreader_methods, /* tp_methods */ - bufferedreader_members, /* tp_members */ - bufferedreader_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(buffered, dict), /* tp_dictoffset */ - _io_BufferedReader___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; - - -static PyMethodDef bufferedwriter_methods[] = { - /* BufferedIOMixin methods */ - {"close", (PyCFunction)buffered_close, METH_NOARGS}, - {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, - {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, - {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, - {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, - {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, - - _IO_BUFFEREDWRITER_WRITE_METHODDEF - _IO__BUFFERED_TRUNCATE_METHODDEF - {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, - _IO__BUFFERED_SEEK_METHODDEF - {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, - {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, - {NULL, NULL} -}; - -static PyMemberDef bufferedwriter_members[] = { - {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, - {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, - {NULL} -}; - -static PyGetSetDef bufferedwriter_getset[] = { - {"closed", (getter)buffered_closed_get, NULL, NULL}, - {"name", (getter)buffered_name_get, NULL, NULL}, - {"mode", (getter)buffered_mode_get, NULL, NULL}, - {NULL} -}; - - -PyTypeObject PyBufferedWriter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedWriter", /*tp_name*/ - sizeof(buffered), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)buffered_dealloc, /*tp_dealloc*/ + _io_BufferedReader___init____doc__, /* tp_doc */ + (traverseproc)buffered_traverse, /* tp_traverse */ + (inquiry)buffered_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ + 0, /* tp_iter */ + (iternextfunc)buffered_iternext, /* tp_iternext */ + bufferedreader_methods, /* tp_methods */ + bufferedreader_members, /* tp_members */ + bufferedreader_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(buffered, dict), /* tp_dictoffset */ + _io_BufferedReader___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; + + +static PyMethodDef bufferedwriter_methods[] = { + /* BufferedIOMixin methods */ + {"close", (PyCFunction)buffered_close, METH_NOARGS}, + {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, + {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, + {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, + {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, + {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, + {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, + + _IO_BUFFEREDWRITER_WRITE_METHODDEF + _IO__BUFFERED_TRUNCATE_METHODDEF + {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, + _IO__BUFFERED_SEEK_METHODDEF + {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, + {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, + {NULL, NULL} +}; + +static PyMemberDef bufferedwriter_members[] = { + {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, + {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, + {NULL} +}; + +static PyGetSetDef bufferedwriter_getset[] = { + {"closed", (getter)buffered_closed_get, NULL, NULL}, + {"name", (getter)buffered_name_get, NULL, NULL}, + {"mode", (getter)buffered_mode_get, NULL, NULL}, + {NULL} +}; + + +PyTypeObject PyBufferedWriter_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.BufferedWriter", /*tp_name*/ + sizeof(buffered), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)buffered_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - (reprfunc)buffered_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*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + (reprfunc)buffered_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*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_BufferedWriter___init____doc__, /* tp_doc */ - (traverseproc)buffered_traverse, /* tp_traverse */ - (inquiry)buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - bufferedwriter_methods, /* tp_methods */ - bufferedwriter_members, /* tp_members */ - bufferedwriter_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(buffered, dict), /* tp_dictoffset */ - _io_BufferedWriter___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; - - -static PyMethodDef bufferedrwpair_methods[] = { - {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS}, - {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS}, - {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS}, - {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS}, - {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS}, - - {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS}, - {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS}, - - {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS}, - {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS}, - - {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS}, - {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS}, - - {NULL, NULL} -}; - -static PyGetSetDef bufferedrwpair_getset[] = { - {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL}, - {NULL} -}; - -PyTypeObject PyBufferedRWPair_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedRWPair", /*tp_name*/ - sizeof(rwpair), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/ + _io_BufferedWriter___init____doc__, /* tp_doc */ + (traverseproc)buffered_traverse, /* tp_traverse */ + (inquiry)buffered_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ + 0, /* tp_iter */ + 0, /* tp_iternext */ + bufferedwriter_methods, /* tp_methods */ + bufferedwriter_members, /* tp_members */ + bufferedwriter_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(buffered, dict), /* tp_dictoffset */ + _io_BufferedWriter___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; + + +static PyMethodDef bufferedrwpair_methods[] = { + {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS}, + {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS}, + {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS}, + {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS}, + {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS}, + + {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS}, + {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS}, + + {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS}, + {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS}, + + {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS}, + {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS}, + + {NULL, NULL} +}; + +static PyGetSetDef bufferedrwpair_getset[] = { + {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL}, + {NULL} +}; + +PyTypeObject PyBufferedRWPair_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.BufferedRWPair", /*tp_name*/ + sizeof(rwpair), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - _io_BufferedRWPair___init____doc__, /* tp_doc */ - (traverseproc)bufferedrwpair_traverse, /* tp_traverse */ - (inquiry)bufferedrwpair_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - bufferedrwpair_methods, /* tp_methods */ - 0, /* tp_members */ - bufferedrwpair_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(rwpair, dict), /* tp_dictoffset */ - _io_BufferedRWPair___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; - - -static PyMethodDef bufferedrandom_methods[] = { - /* BufferedIOMixin methods */ - {"close", (PyCFunction)buffered_close, METH_NOARGS}, - {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, - {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, - {"readable", (PyCFunction)buffered_readable, METH_NOARGS}, - {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, - {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, - {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, - - {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, - - _IO__BUFFERED_SEEK_METHODDEF - {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, - _IO__BUFFERED_TRUNCATE_METHODDEF - _IO__BUFFERED_READ_METHODDEF - _IO__BUFFERED_READ1_METHODDEF - _IO__BUFFERED_READINTO_METHODDEF - _IO__BUFFERED_READINTO1_METHODDEF - _IO__BUFFERED_READLINE_METHODDEF - _IO__BUFFERED_PEEK_METHODDEF - _IO_BUFFEREDWRITER_WRITE_METHODDEF - {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, - {NULL, NULL} -}; - -static PyMemberDef bufferedrandom_members[] = { - {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, - {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, - {NULL} -}; - -static PyGetSetDef bufferedrandom_getset[] = { - {"closed", (getter)buffered_closed_get, NULL, NULL}, - {"name", (getter)buffered_name_get, NULL, NULL}, - {"mode", (getter)buffered_mode_get, NULL, NULL}, - {NULL} -}; - - -PyTypeObject PyBufferedRandom_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedRandom", /*tp_name*/ - sizeof(buffered), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)buffered_dealloc, /*tp_dealloc*/ + _io_BufferedRWPair___init____doc__, /* tp_doc */ + (traverseproc)bufferedrwpair_traverse, /* tp_traverse */ + (inquiry)bufferedrwpair_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/ + 0, /* tp_iter */ + 0, /* tp_iternext */ + bufferedrwpair_methods, /* tp_methods */ + 0, /* tp_members */ + bufferedrwpair_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(rwpair, dict), /* tp_dictoffset */ + _io_BufferedRWPair___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; + + +static PyMethodDef bufferedrandom_methods[] = { + /* BufferedIOMixin methods */ + {"close", (PyCFunction)buffered_close, METH_NOARGS}, + {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, + {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, + {"readable", (PyCFunction)buffered_readable, METH_NOARGS}, + {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, + {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, + {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, + {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, + + {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, + + _IO__BUFFERED_SEEK_METHODDEF + {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, + _IO__BUFFERED_TRUNCATE_METHODDEF + _IO__BUFFERED_READ_METHODDEF + _IO__BUFFERED_READ1_METHODDEF + _IO__BUFFERED_READINTO_METHODDEF + _IO__BUFFERED_READINTO1_METHODDEF + _IO__BUFFERED_READLINE_METHODDEF + _IO__BUFFERED_PEEK_METHODDEF + _IO_BUFFEREDWRITER_WRITE_METHODDEF + {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, + {NULL, NULL} +}; + +static PyMemberDef bufferedrandom_members[] = { + {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, + {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, + {NULL} +}; + +static PyGetSetDef bufferedrandom_getset[] = { + {"closed", (getter)buffered_closed_get, NULL, NULL}, + {"name", (getter)buffered_name_get, NULL, NULL}, + {"mode", (getter)buffered_mode_get, NULL, NULL}, + {NULL} +}; + + +PyTypeObject PyBufferedRandom_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.BufferedRandom", /*tp_name*/ + sizeof(buffered), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)buffered_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - (reprfunc)buffered_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*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + (reprfunc)buffered_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*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_BufferedRandom___init____doc__, /* tp_doc */ - (traverseproc)buffered_traverse, /* tp_traverse */ - (inquiry)buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)buffered_iternext, /* tp_iternext */ - bufferedrandom_methods, /* tp_methods */ - bufferedrandom_members, /* tp_members */ - bufferedrandom_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /*tp_dict*/ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(buffered, dict), /*tp_dictoffset*/ - _io_BufferedRandom___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; + _io_BufferedRandom___init____doc__, /* tp_doc */ + (traverseproc)buffered_traverse, /* tp_traverse */ + (inquiry)buffered_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ + 0, /* tp_iter */ + (iternextfunc)buffered_iternext, /* tp_iternext */ + bufferedrandom_methods, /* tp_methods */ + bufferedrandom_members, /* tp_members */ + bufferedrandom_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /*tp_dict*/ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(buffered, dict), /*tp_dictoffset*/ + _io_BufferedRandom___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; diff --git a/contrib/tools/python3/src/Modules/_io/bytesio.c b/contrib/tools/python3/src/Modules/_io/bytesio.c index 2468f45f941..47471efd436 100644 --- a/contrib/tools/python3/src/Modules/_io/bytesio.c +++ b/contrib/tools/python3/src/Modules/_io/bytesio.c @@ -1,36 +1,36 @@ -#include "Python.h" +#include "Python.h" #include "pycore_object.h" #include // offsetof() -#include "_iomodule.h" - -/*[clinic input] -module _io -class _io.BytesIO "bytesio *" "&PyBytesIO_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/ - -typedef struct { - PyObject_HEAD - PyObject *buf; - Py_ssize_t pos; - Py_ssize_t string_size; - PyObject *dict; - PyObject *weakreflist; - Py_ssize_t exports; -} bytesio; - -typedef struct { - PyObject_HEAD - bytesio *source; -} bytesiobuf; - -/* The bytesio object can be in three states: - * Py_REFCNT(buf) == 1, exports == 0. - * Py_REFCNT(buf) > 1. exports == 0, - first modification or export causes the internal buffer copying. - * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden. -*/ - +#include "_iomodule.h" + +/*[clinic input] +module _io +class _io.BytesIO "bytesio *" "&PyBytesIO_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/ + +typedef struct { + PyObject_HEAD + PyObject *buf; + Py_ssize_t pos; + Py_ssize_t string_size; + PyObject *dict; + PyObject *weakreflist; + Py_ssize_t exports; +} bytesio; + +typedef struct { + PyObject_HEAD + bytesio *source; +} bytesiobuf; + +/* The bytesio object can be in three states: + * Py_REFCNT(buf) == 1, exports == 0. + * Py_REFCNT(buf) > 1. exports == 0, + first modification or export causes the internal buffer copying. + * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden. +*/ + static int check_closed(bytesio *self) { @@ -52,133 +52,133 @@ check_exports(bytesio *self) return 0; } -#define CHECK_CLOSED(self) \ +#define CHECK_CLOSED(self) \ if (check_closed(self)) { \ - return NULL; \ - } - -#define CHECK_EXPORTS(self) \ + return NULL; \ + } + +#define CHECK_EXPORTS(self) \ if (check_exports(self)) { \ - return NULL; \ - } - -#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1) - - -/* Internal routine to get a line from the buffer of a BytesIO - object. Returns the length between the current position to the - next newline character. */ -static Py_ssize_t -scan_eol(bytesio *self, Py_ssize_t len) -{ - const char *start, *n; - Py_ssize_t maxlen; - - assert(self->buf != NULL); - assert(self->pos >= 0); - - if (self->pos >= self->string_size) - return 0; - - /* Move to the end of the line, up to the end of the string, s. */ - maxlen = self->string_size - self->pos; - if (len < 0 || len > maxlen) - len = maxlen; - - if (len) { - start = PyBytes_AS_STRING(self->buf) + self->pos; - n = memchr(start, '\n', len); - if (n) - /* Get the length from the current position to the end of - the line. */ - len = n - start + 1; - } - assert(len >= 0); - assert(self->pos < PY_SSIZE_T_MAX - len); - - return len; -} - -/* Internal routine for detaching the shared buffer of BytesIO objects. - The caller should ensure that the 'size' argument is non-negative and - not lesser than self->string_size. Returns 0 on success, -1 otherwise. */ -static int -unshare_buffer(bytesio *self, size_t size) -{ - PyObject *new_buf; - assert(SHARED_BUF(self)); - assert(self->exports == 0); - assert(size >= (size_t)self->string_size); - new_buf = PyBytes_FromStringAndSize(NULL, size); - if (new_buf == NULL) - return -1; - memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf), - self->string_size); - Py_SETREF(self->buf, new_buf); - return 0; -} - -/* Internal routine for changing the size of the buffer of BytesIO objects. - The caller should ensure that the 'size' argument is non-negative. Returns - 0 on success, -1 otherwise. */ -static int -resize_buffer(bytesio *self, size_t size) -{ - /* Here, unsigned types are used to avoid dealing with signed integer - overflow, which is undefined in C. */ - size_t alloc = PyBytes_GET_SIZE(self->buf); - - assert(self->buf != NULL); - - /* For simplicity, stay in the range of the signed type. Anyway, Python - doesn't allow strings to be longer than this. */ - if (size > PY_SSIZE_T_MAX) - goto overflow; - - if (size < alloc / 2) { - /* Major downsize; resize down to exact size. */ - alloc = size + 1; - } - else if (size < alloc) { - /* Within allocated size; quick exit */ - return 0; - } - else if (size <= alloc * 1.125) { - /* Moderate upsize; overallocate similar to list_resize() */ - alloc = size + (size >> 3) + (size < 9 ? 3 : 6); - } - else { - /* Major upsize; resize up to exact size */ - alloc = size + 1; - } - - if (alloc > ((size_t)-1) / sizeof(char)) - goto overflow; - - if (SHARED_BUF(self)) { - if (unshare_buffer(self, alloc) < 0) - return -1; - } - else { - if (_PyBytes_Resize(&self->buf, alloc) < 0) - return -1; - } - - return 0; - - overflow: - PyErr_SetString(PyExc_OverflowError, - "new buffer size too large"); - return -1; -} - -/* Internal routine for writing a string of bytes to the buffer of a BytesIO + return NULL; \ + } + +#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1) + + +/* Internal routine to get a line from the buffer of a BytesIO + object. Returns the length between the current position to the + next newline character. */ +static Py_ssize_t +scan_eol(bytesio *self, Py_ssize_t len) +{ + const char *start, *n; + Py_ssize_t maxlen; + + assert(self->buf != NULL); + assert(self->pos >= 0); + + if (self->pos >= self->string_size) + return 0; + + /* Move to the end of the line, up to the end of the string, s. */ + maxlen = self->string_size - self->pos; + if (len < 0 || len > maxlen) + len = maxlen; + + if (len) { + start = PyBytes_AS_STRING(self->buf) + self->pos; + n = memchr(start, '\n', len); + if (n) + /* Get the length from the current position to the end of + the line. */ + len = n - start + 1; + } + assert(len >= 0); + assert(self->pos < PY_SSIZE_T_MAX - len); + + return len; +} + +/* Internal routine for detaching the shared buffer of BytesIO objects. + The caller should ensure that the 'size' argument is non-negative and + not lesser than self->string_size. Returns 0 on success, -1 otherwise. */ +static int +unshare_buffer(bytesio *self, size_t size) +{ + PyObject *new_buf; + assert(SHARED_BUF(self)); + assert(self->exports == 0); + assert(size >= (size_t)self->string_size); + new_buf = PyBytes_FromStringAndSize(NULL, size); + if (new_buf == NULL) + return -1; + memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf), + self->string_size); + Py_SETREF(self->buf, new_buf); + return 0; +} + +/* Internal routine for changing the size of the buffer of BytesIO objects. + The caller should ensure that the 'size' argument is non-negative. Returns + 0 on success, -1 otherwise. */ +static int +resize_buffer(bytesio *self, size_t size) +{ + /* Here, unsigned types are used to avoid dealing with signed integer + overflow, which is undefined in C. */ + size_t alloc = PyBytes_GET_SIZE(self->buf); + + assert(self->buf != NULL); + + /* For simplicity, stay in the range of the signed type. Anyway, Python + doesn't allow strings to be longer than this. */ + if (size > PY_SSIZE_T_MAX) + goto overflow; + + if (size < alloc / 2) { + /* Major downsize; resize down to exact size. */ + alloc = size + 1; + } + else if (size < alloc) { + /* Within allocated size; quick exit */ + return 0; + } + else if (size <= alloc * 1.125) { + /* Moderate upsize; overallocate similar to list_resize() */ + alloc = size + (size >> 3) + (size < 9 ? 3 : 6); + } + else { + /* Major upsize; resize up to exact size */ + alloc = size + 1; + } + + if (alloc > ((size_t)-1) / sizeof(char)) + goto overflow; + + if (SHARED_BUF(self)) { + if (unshare_buffer(self, alloc) < 0) + return -1; + } + else { + if (_PyBytes_Resize(&self->buf, alloc) < 0) + return -1; + } + + return 0; + + overflow: + PyErr_SetString(PyExc_OverflowError, + "new buffer size too large"); + return -1; +} + +/* Internal routine for writing a string of bytes to the buffer of a BytesIO object. Returns the number of bytes written, or -1 on error. Inlining is disabled because it's significantly decreases performance of writelines() in PGO build. */ _Py_NO_INLINE static Py_ssize_t write_bytes(bytesio *self, PyObject *b) -{ +{ if (check_closed(self)) { return -1; } @@ -195,777 +195,777 @@ write_bytes(bytesio *self, PyObject *b) goto done; } - assert(self->pos >= 0); + assert(self->pos >= 0); size_t endpos = (size_t)self->pos + len; - if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) { + if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) { if (resize_buffer(self, endpos) < 0) { len = -1; goto done; } - } - else if (SHARED_BUF(self)) { + } + else if (SHARED_BUF(self)) { if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0) { len = -1; goto done; } - } - - if (self->pos > self->string_size) { - /* In case of overseek, pad with null bytes the buffer region between - the end of stream and the current position. - - 0 lo string_size hi - | |<---used--->|<----------available----------->| - | | <--to pad-->|<---to write---> | - 0 buf position - */ - memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0', - (self->pos - self->string_size) * sizeof(char)); - } - - /* Copy the data to the internal buffer, overwriting some of the existing - data if self->pos < self->string_size. */ + } + + if (self->pos > self->string_size) { + /* In case of overseek, pad with null bytes the buffer region between + the end of stream and the current position. + + 0 lo string_size hi + | |<---used--->|<----------available----------->| + | | <--to pad-->|<---to write---> | + 0 buf position + */ + memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0', + (self->pos - self->string_size) * sizeof(char)); + } + + /* Copy the data to the internal buffer, overwriting some of the existing + data if self->pos < self->string_size. */ memcpy(PyBytes_AS_STRING(self->buf) + self->pos, buf.buf, len); - self->pos = endpos; - - /* Set the new length of the internal string if it has changed. */ - if ((size_t)self->string_size < endpos) { - self->string_size = endpos; - } - + self->pos = endpos; + + /* Set the new length of the internal string if it has changed. */ + if ((size_t)self->string_size < endpos) { + self->string_size = endpos; + } + done: PyBuffer_Release(&buf); - return len; -} - -static PyObject * -bytesio_get_closed(bytesio *self, void *Py_UNUSED(ignored)) -{ - if (self->buf == NULL) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -/*[clinic input] -_io.BytesIO.readable - -Returns True if the IO object can be read. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_readable_impl(bytesio *self) -/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/ -{ - CHECK_CLOSED(self); - Py_RETURN_TRUE; -} - -/*[clinic input] -_io.BytesIO.writable - -Returns True if the IO object can be written. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_writable_impl(bytesio *self) -/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/ -{ - CHECK_CLOSED(self); - Py_RETURN_TRUE; -} - -/*[clinic input] -_io.BytesIO.seekable - -Returns True if the IO object can be seeked. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_seekable_impl(bytesio *self) -/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/ -{ - CHECK_CLOSED(self); - Py_RETURN_TRUE; -} - -/*[clinic input] -_io.BytesIO.flush - -Does nothing. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_flush_impl(bytesio *self) -/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/ -{ - CHECK_CLOSED(self); - Py_RETURN_NONE; -} - -/*[clinic input] -_io.BytesIO.getbuffer - -Get a read-write view over the contents of the BytesIO object. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_getbuffer_impl(bytesio *self) -/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/ -{ - PyTypeObject *type = &_PyBytesIOBuffer_Type; - bytesiobuf *buf; - PyObject *view; - - CHECK_CLOSED(self); - - buf = (bytesiobuf *) type->tp_alloc(type, 0); - if (buf == NULL) - return NULL; - Py_INCREF(self); - buf->source = self; - view = PyMemoryView_FromObject((PyObject *) buf); - Py_DECREF(buf); - return view; -} - -/*[clinic input] -_io.BytesIO.getvalue - -Retrieve the entire contents of the BytesIO object. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_getvalue_impl(bytesio *self) -/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/ -{ - CHECK_CLOSED(self); - if (self->string_size <= 1 || self->exports > 0) - return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf), - self->string_size); - - if (self->string_size != PyBytes_GET_SIZE(self->buf)) { - if (SHARED_BUF(self)) { - if (unshare_buffer(self, self->string_size) < 0) - return NULL; - } - else { - if (_PyBytes_Resize(&self->buf, self->string_size) < 0) - return NULL; - } - } - Py_INCREF(self->buf); - return self->buf; -} - -/*[clinic input] -_io.BytesIO.isatty - -Always returns False. - -BytesIO objects are not connected to a TTY-like device. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_isatty_impl(bytesio *self) -/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/ -{ - CHECK_CLOSED(self); - Py_RETURN_FALSE; -} - -/*[clinic input] -_io.BytesIO.tell - -Current file position, an integer. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_tell_impl(bytesio *self) -/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/ -{ - CHECK_CLOSED(self); - return PyLong_FromSsize_t(self->pos); -} - -static PyObject * -read_bytes(bytesio *self, Py_ssize_t size) -{ + return len; +} + +static PyObject * +bytesio_get_closed(bytesio *self, void *Py_UNUSED(ignored)) +{ + if (self->buf == NULL) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +/*[clinic input] +_io.BytesIO.readable + +Returns True if the IO object can be read. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_readable_impl(bytesio *self) +/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/ +{ + CHECK_CLOSED(self); + Py_RETURN_TRUE; +} + +/*[clinic input] +_io.BytesIO.writable + +Returns True if the IO object can be written. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_writable_impl(bytesio *self) +/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/ +{ + CHECK_CLOSED(self); + Py_RETURN_TRUE; +} + +/*[clinic input] +_io.BytesIO.seekable + +Returns True if the IO object can be seeked. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_seekable_impl(bytesio *self) +/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/ +{ + CHECK_CLOSED(self); + Py_RETURN_TRUE; +} + +/*[clinic input] +_io.BytesIO.flush + +Does nothing. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_flush_impl(bytesio *self) +/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/ +{ + CHECK_CLOSED(self); + Py_RETURN_NONE; +} + +/*[clinic input] +_io.BytesIO.getbuffer + +Get a read-write view over the contents of the BytesIO object. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_getbuffer_impl(bytesio *self) +/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/ +{ + PyTypeObject *type = &_PyBytesIOBuffer_Type; + bytesiobuf *buf; + PyObject *view; + + CHECK_CLOSED(self); + + buf = (bytesiobuf *) type->tp_alloc(type, 0); + if (buf == NULL) + return NULL; + Py_INCREF(self); + buf->source = self; + view = PyMemoryView_FromObject((PyObject *) buf); + Py_DECREF(buf); + return view; +} + +/*[clinic input] +_io.BytesIO.getvalue + +Retrieve the entire contents of the BytesIO object. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_getvalue_impl(bytesio *self) +/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/ +{ + CHECK_CLOSED(self); + if (self->string_size <= 1 || self->exports > 0) + return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf), + self->string_size); + + if (self->string_size != PyBytes_GET_SIZE(self->buf)) { + if (SHARED_BUF(self)) { + if (unshare_buffer(self, self->string_size) < 0) + return NULL; + } + else { + if (_PyBytes_Resize(&self->buf, self->string_size) < 0) + return NULL; + } + } + Py_INCREF(self->buf); + return self->buf; +} + +/*[clinic input] +_io.BytesIO.isatty + +Always returns False. + +BytesIO objects are not connected to a TTY-like device. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_isatty_impl(bytesio *self) +/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/ +{ + CHECK_CLOSED(self); + Py_RETURN_FALSE; +} + +/*[clinic input] +_io.BytesIO.tell + +Current file position, an integer. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_tell_impl(bytesio *self) +/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/ +{ + CHECK_CLOSED(self); + return PyLong_FromSsize_t(self->pos); +} + +static PyObject * +read_bytes(bytesio *self, Py_ssize_t size) +{ const char *output; - - assert(self->buf != NULL); - assert(size <= self->string_size); - if (size > 1 && - self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) && - self->exports == 0) { - self->pos += size; - Py_INCREF(self->buf); - return self->buf; - } - - output = PyBytes_AS_STRING(self->buf) + self->pos; - self->pos += size; - return PyBytes_FromStringAndSize(output, size); -} - -/*[clinic input] -_io.BytesIO.read - size: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Read at most size bytes, returned as a bytes object. - -If the size argument is negative, read until EOF is reached. -Return an empty bytes object at EOF. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size) -/*[clinic end generated code: output=9cc025f21c75bdd2 input=74344a39f431c3d7]*/ -{ - Py_ssize_t n; - - CHECK_CLOSED(self); - - /* adjust invalid sizes */ - n = self->string_size - self->pos; - if (size < 0 || size > n) { - size = n; - if (size < 0) - size = 0; - } - - return read_bytes(self, size); -} - - -/*[clinic input] -_io.BytesIO.read1 - size: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Read at most size bytes, returned as a bytes object. - -If the size argument is negative or omitted, read until EOF is reached. -Return an empty bytes object at EOF. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size) -/*[clinic end generated code: output=d0f843285aa95f1c input=440a395bf9129ef5]*/ -{ - return _io_BytesIO_read_impl(self, size); -} - -/*[clinic input] -_io.BytesIO.readline - size: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Next line from the file, as a bytes object. - -Retain newline. A non-negative size argument limits the maximum -number of bytes to return (an incomplete line may be returned then). -Return an empty bytes object at EOF. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size) -/*[clinic end generated code: output=4bff3c251df8ffcd input=e7c3fbd1744e2783]*/ -{ - Py_ssize_t n; - - CHECK_CLOSED(self); - - n = scan_eol(self, size); - - return read_bytes(self, n); -} - -/*[clinic input] -_io.BytesIO.readlines - size as arg: object = None - / - -List of bytes objects, each a line from the file. - -Call readline() repeatedly and return a list of the lines so read. -The optional size argument, if given, is an approximate bound on the -total number of bytes in the lines returned. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg) -/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/ -{ - Py_ssize_t maxsize, size, n; - PyObject *result, *line; + + assert(self->buf != NULL); + assert(size <= self->string_size); + if (size > 1 && + self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) && + self->exports == 0) { + self->pos += size; + Py_INCREF(self->buf); + return self->buf; + } + + output = PyBytes_AS_STRING(self->buf) + self->pos; + self->pos += size; + return PyBytes_FromStringAndSize(output, size); +} + +/*[clinic input] +_io.BytesIO.read + size: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Read at most size bytes, returned as a bytes object. + +If the size argument is negative, read until EOF is reached. +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size) +/*[clinic end generated code: output=9cc025f21c75bdd2 input=74344a39f431c3d7]*/ +{ + Py_ssize_t n; + + CHECK_CLOSED(self); + + /* adjust invalid sizes */ + n = self->string_size - self->pos; + if (size < 0 || size > n) { + size = n; + if (size < 0) + size = 0; + } + + return read_bytes(self, size); +} + + +/*[clinic input] +_io.BytesIO.read1 + size: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Read at most size bytes, returned as a bytes object. + +If the size argument is negative or omitted, read until EOF is reached. +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size) +/*[clinic end generated code: output=d0f843285aa95f1c input=440a395bf9129ef5]*/ +{ + return _io_BytesIO_read_impl(self, size); +} + +/*[clinic input] +_io.BytesIO.readline + size: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Next line from the file, as a bytes object. + +Retain newline. A non-negative size argument limits the maximum +number of bytes to return (an incomplete line may be returned then). +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size) +/*[clinic end generated code: output=4bff3c251df8ffcd input=e7c3fbd1744e2783]*/ +{ + Py_ssize_t n; + + CHECK_CLOSED(self); + + n = scan_eol(self, size); + + return read_bytes(self, n); +} + +/*[clinic input] +_io.BytesIO.readlines + size as arg: object = None + / + +List of bytes objects, each a line from the file. + +Call readline() repeatedly and return a list of the lines so read. +The optional size argument, if given, is an approximate bound on the +total number of bytes in the lines returned. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg) +/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/ +{ + Py_ssize_t maxsize, size, n; + PyObject *result, *line; const char *output; - - CHECK_CLOSED(self); - - if (PyLong_Check(arg)) { - maxsize = PyLong_AsSsize_t(arg); - if (maxsize == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* No size limit, by default. */ - maxsize = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - size = 0; - result = PyList_New(0); - if (!result) - return NULL; - - output = PyBytes_AS_STRING(self->buf) + self->pos; - while ((n = scan_eol(self, -1)) != 0) { - self->pos += n; - line = PyBytes_FromStringAndSize(output, n); - if (!line) - goto on_error; - if (PyList_Append(result, line) == -1) { - Py_DECREF(line); - goto on_error; - } - Py_DECREF(line); - size += n; - if (maxsize > 0 && size >= maxsize) - break; - output += n; - } - return result; - - on_error: - Py_DECREF(result); - return NULL; -} - -/*[clinic input] -_io.BytesIO.readinto - buffer: Py_buffer(accept={rwbuffer}) - / - -Read bytes into buffer. - -Returns number of bytes read (0 for EOF), or None if the object -is set not to block and has no data to read. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer) -/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/ -{ - Py_ssize_t len, n; - - CHECK_CLOSED(self); - - /* adjust invalid sizes */ - len = buffer->len; - n = self->string_size - self->pos; - if (len > n) { - len = n; - if (len < 0) - len = 0; - } - - memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len); - assert(self->pos + len < PY_SSIZE_T_MAX); - assert(len >= 0); - self->pos += len; - - return PyLong_FromSsize_t(len); -} - -/*[clinic input] -_io.BytesIO.truncate - size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None - / - -Truncate the file to at most size bytes. - -Size defaults to the current file position, as returned by tell(). -The current file position is unchanged. Returns the new size. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size) -/*[clinic end generated code: output=9ad17650c15fa09b input=423759dd42d2f7c1]*/ -{ - CHECK_CLOSED(self); - CHECK_EXPORTS(self); - - if (size < 0) { - PyErr_Format(PyExc_ValueError, - "negative size value %zd", size); - return NULL; - } - - if (size < self->string_size) { - self->string_size = size; - if (resize_buffer(self, size) < 0) - return NULL; - } - - return PyLong_FromSsize_t(size); -} - -static PyObject * -bytesio_iternext(bytesio *self) -{ - Py_ssize_t n; - - CHECK_CLOSED(self); - - n = scan_eol(self, -1); - - if (n == 0) - return NULL; - - return read_bytes(self, n); -} - -/*[clinic input] -_io.BytesIO.seek - pos: Py_ssize_t - whence: int = 0 - / - -Change stream position. - -Seek to byte offset pos relative to position indicated by whence: - 0 Start of stream (the default). pos should be >= 0; - 1 Current position - pos may be negative; - 2 End of stream - pos usually negative. -Returns the new absolute position. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence) -/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/ -{ - CHECK_CLOSED(self); - - if (pos < 0 && whence == 0) { - PyErr_Format(PyExc_ValueError, - "negative seek value %zd", pos); - return NULL; - } - - /* whence = 0: offset relative to beginning of the string. - whence = 1: offset relative to current position. - whence = 2: offset relative the end of the string. */ - if (whence == 1) { - if (pos > PY_SSIZE_T_MAX - self->pos) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - return NULL; - } - pos += self->pos; - } - else if (whence == 2) { - if (pos > PY_SSIZE_T_MAX - self->string_size) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - return NULL; - } - pos += self->string_size; - } - else if (whence != 0) { - PyErr_Format(PyExc_ValueError, - "invalid whence (%i, should be 0, 1 or 2)", whence); - return NULL; - } - - if (pos < 0) - pos = 0; - self->pos = pos; - - return PyLong_FromSsize_t(self->pos); -} - -/*[clinic input] -_io.BytesIO.write - b: object - / - -Write bytes to file. - -Return the number of bytes written. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_write(bytesio *self, PyObject *b) -/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/ -{ + + CHECK_CLOSED(self); + + if (PyLong_Check(arg)) { + maxsize = PyLong_AsSsize_t(arg); + if (maxsize == -1 && PyErr_Occurred()) + return NULL; + } + else if (arg == Py_None) { + /* No size limit, by default. */ + maxsize = -1; + } + else { + PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", + Py_TYPE(arg)->tp_name); + return NULL; + } + + size = 0; + result = PyList_New(0); + if (!result) + return NULL; + + output = PyBytes_AS_STRING(self->buf) + self->pos; + while ((n = scan_eol(self, -1)) != 0) { + self->pos += n; + line = PyBytes_FromStringAndSize(output, n); + if (!line) + goto on_error; + if (PyList_Append(result, line) == -1) { + Py_DECREF(line); + goto on_error; + } + Py_DECREF(line); + size += n; + if (maxsize > 0 && size >= maxsize) + break; + output += n; + } + return result; + + on_error: + Py_DECREF(result); + return NULL; +} + +/*[clinic input] +_io.BytesIO.readinto + buffer: Py_buffer(accept={rwbuffer}) + / + +Read bytes into buffer. + +Returns number of bytes read (0 for EOF), or None if the object +is set not to block and has no data to read. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer) +/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/ +{ + Py_ssize_t len, n; + + CHECK_CLOSED(self); + + /* adjust invalid sizes */ + len = buffer->len; + n = self->string_size - self->pos; + if (len > n) { + len = n; + if (len < 0) + len = 0; + } + + memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len); + assert(self->pos + len < PY_SSIZE_T_MAX); + assert(len >= 0); + self->pos += len; + + return PyLong_FromSsize_t(len); +} + +/*[clinic input] +_io.BytesIO.truncate + size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None + / + +Truncate the file to at most size bytes. + +Size defaults to the current file position, as returned by tell(). +The current file position is unchanged. Returns the new size. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size) +/*[clinic end generated code: output=9ad17650c15fa09b input=423759dd42d2f7c1]*/ +{ + CHECK_CLOSED(self); + CHECK_EXPORTS(self); + + if (size < 0) { + PyErr_Format(PyExc_ValueError, + "negative size value %zd", size); + return NULL; + } + + if (size < self->string_size) { + self->string_size = size; + if (resize_buffer(self, size) < 0) + return NULL; + } + + return PyLong_FromSsize_t(size); +} + +static PyObject * +bytesio_iternext(bytesio *self) +{ + Py_ssize_t n; + + CHECK_CLOSED(self); + + n = scan_eol(self, -1); + + if (n == 0) + return NULL; + + return read_bytes(self, n); +} + +/*[clinic input] +_io.BytesIO.seek + pos: Py_ssize_t + whence: int = 0 + / + +Change stream position. + +Seek to byte offset pos relative to position indicated by whence: + 0 Start of stream (the default). pos should be >= 0; + 1 Current position - pos may be negative; + 2 End of stream - pos usually negative. +Returns the new absolute position. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence) +/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/ +{ + CHECK_CLOSED(self); + + if (pos < 0 && whence == 0) { + PyErr_Format(PyExc_ValueError, + "negative seek value %zd", pos); + return NULL; + } + + /* whence = 0: offset relative to beginning of the string. + whence = 1: offset relative to current position. + whence = 2: offset relative the end of the string. */ + if (whence == 1) { + if (pos > PY_SSIZE_T_MAX - self->pos) { + PyErr_SetString(PyExc_OverflowError, + "new position too large"); + return NULL; + } + pos += self->pos; + } + else if (whence == 2) { + if (pos > PY_SSIZE_T_MAX - self->string_size) { + PyErr_SetString(PyExc_OverflowError, + "new position too large"); + return NULL; + } + pos += self->string_size; + } + else if (whence != 0) { + PyErr_Format(PyExc_ValueError, + "invalid whence (%i, should be 0, 1 or 2)", whence); + return NULL; + } + + if (pos < 0) + pos = 0; + self->pos = pos; + + return PyLong_FromSsize_t(self->pos); +} + +/*[clinic input] +_io.BytesIO.write + b: object + / + +Write bytes to file. + +Return the number of bytes written. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_write(bytesio *self, PyObject *b) +/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/ +{ Py_ssize_t n = write_bytes(self, b); - return n >= 0 ? PyLong_FromSsize_t(n) : NULL; -} - -/*[clinic input] -_io.BytesIO.writelines - lines: object - / - -Write lines to the file. - -Note that newlines are not added. lines can be any iterable object -producing bytes-like objects. This is equivalent to calling write() for -each element. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_writelines(bytesio *self, PyObject *lines) -/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/ -{ - PyObject *it, *item; - - CHECK_CLOSED(self); - - it = PyObject_GetIter(lines); - if (it == NULL) - return NULL; - - while ((item = PyIter_Next(it)) != NULL) { + return n >= 0 ? PyLong_FromSsize_t(n) : NULL; +} + +/*[clinic input] +_io.BytesIO.writelines + lines: object + / + +Write lines to the file. + +Note that newlines are not added. lines can be any iterable object +producing bytes-like objects. This is equivalent to calling write() for +each element. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_writelines(bytesio *self, PyObject *lines) +/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/ +{ + PyObject *it, *item; + + CHECK_CLOSED(self); + + it = PyObject_GetIter(lines); + if (it == NULL) + return NULL; + + while ((item = PyIter_Next(it)) != NULL) { Py_ssize_t ret = write_bytes(self, item); - Py_DECREF(item); + Py_DECREF(item); if (ret < 0) { - Py_DECREF(it); - return NULL; - } - } - Py_DECREF(it); - - /* See if PyIter_Next failed */ - if (PyErr_Occurred()) - return NULL; - - Py_RETURN_NONE; -} - -/*[clinic input] -_io.BytesIO.close - -Disable all I/O operations. -[clinic start generated code]*/ - -static PyObject * -_io_BytesIO_close_impl(bytesio *self) -/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/ -{ - CHECK_EXPORTS(self); - Py_CLEAR(self->buf); - Py_RETURN_NONE; -} - -/* Pickling support. - - Note that only pickle protocol 2 and onward are supported since we use - extended __reduce__ API of PEP 307 to make BytesIO instances picklable. - - Providing support for protocol < 2 would require the __reduce_ex__ method - which is notably long-winded when defined properly. - - For BytesIO, the implementation would similar to one coded for - object.__reduce_ex__, but slightly less general. To be more specific, we - could call bytesio_getstate directly and avoid checking for the presence of - a fallback __reduce__ method. However, we would still need a __newobj__ - function to use the efficient instance representation of PEP 307. - */ - -static PyObject * + Py_DECREF(it); + return NULL; + } + } + Py_DECREF(it); + + /* See if PyIter_Next failed */ + if (PyErr_Occurred()) + return NULL; + + Py_RETURN_NONE; +} + +/*[clinic input] +_io.BytesIO.close + +Disable all I/O operations. +[clinic start generated code]*/ + +static PyObject * +_io_BytesIO_close_impl(bytesio *self) +/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/ +{ + CHECK_EXPORTS(self); + Py_CLEAR(self->buf); + Py_RETURN_NONE; +} + +/* Pickling support. + + Note that only pickle protocol 2 and onward are supported since we use + extended __reduce__ API of PEP 307 to make BytesIO instances picklable. + + Providing support for protocol < 2 would require the __reduce_ex__ method + which is notably long-winded when defined properly. + + For BytesIO, the implementation would similar to one coded for + object.__reduce_ex__, but slightly less general. To be more specific, we + could call bytesio_getstate directly and avoid checking for the presence of + a fallback __reduce__ method. However, we would still need a __newobj__ + function to use the efficient instance representation of PEP 307. + */ + +static PyObject * bytesio_getstate(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *initvalue = _io_BytesIO_getvalue_impl(self); - PyObject *dict; - PyObject *state; - - if (initvalue == NULL) - return NULL; - if (self->dict == NULL) { - Py_INCREF(Py_None); - dict = Py_None; - } - else { - dict = PyDict_Copy(self->dict); - if (dict == NULL) { - Py_DECREF(initvalue); - return NULL; - } - } - - state = Py_BuildValue("(OnN)", initvalue, self->pos, dict); - Py_DECREF(initvalue); - return state; -} - -static PyObject * -bytesio_setstate(bytesio *self, PyObject *state) -{ - PyObject *result; - PyObject *position_obj; - PyObject *dict; - Py_ssize_t pos; - - assert(state != NULL); - - /* We allow the state tuple to be longer than 3, because we may need - someday to extend the object's state without breaking - backward-compatibility. */ - if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 3) { - PyErr_Format(PyExc_TypeError, - "%.200s.__setstate__ argument should be 3-tuple, got %.200s", - Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name); - return NULL; - } - CHECK_EXPORTS(self); - /* Reset the object to its default state. This is only needed to handle - the case of repeated calls to __setstate__. */ - self->string_size = 0; - self->pos = 0; - - /* Set the value of the internal buffer. If state[0] does not support the - buffer protocol, bytesio_write will raise the appropriate TypeError. */ - result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0)); - if (result == NULL) - return NULL; - Py_DECREF(result); - - /* Set carefully the position value. Alternatively, we could use the seek - method instead of modifying self->pos directly to better protect the +{ + PyObject *initvalue = _io_BytesIO_getvalue_impl(self); + PyObject *dict; + PyObject *state; + + if (initvalue == NULL) + return NULL; + if (self->dict == NULL) { + Py_INCREF(Py_None); + dict = Py_None; + } + else { + dict = PyDict_Copy(self->dict); + if (dict == NULL) { + Py_DECREF(initvalue); + return NULL; + } + } + + state = Py_BuildValue("(OnN)", initvalue, self->pos, dict); + Py_DECREF(initvalue); + return state; +} + +static PyObject * +bytesio_setstate(bytesio *self, PyObject *state) +{ + PyObject *result; + PyObject *position_obj; + PyObject *dict; + Py_ssize_t pos; + + assert(state != NULL); + + /* We allow the state tuple to be longer than 3, because we may need + someday to extend the object's state without breaking + backward-compatibility. */ + if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 3) { + PyErr_Format(PyExc_TypeError, + "%.200s.__setstate__ argument should be 3-tuple, got %.200s", + Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name); + return NULL; + } + CHECK_EXPORTS(self); + /* Reset the object to its default state. This is only needed to handle + the case of repeated calls to __setstate__. */ + self->string_size = 0; + self->pos = 0; + + /* Set the value of the internal buffer. If state[0] does not support the + buffer protocol, bytesio_write will raise the appropriate TypeError. */ + result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0)); + if (result == NULL) + return NULL; + Py_DECREF(result); + + /* Set carefully the position value. Alternatively, we could use the seek + method instead of modifying self->pos directly to better protect the object internal state against erroneous (or malicious) inputs. */ - position_obj = PyTuple_GET_ITEM(state, 1); - if (!PyLong_Check(position_obj)) { - PyErr_Format(PyExc_TypeError, - "second item of state must be an integer, not %.200s", - Py_TYPE(position_obj)->tp_name); - return NULL; - } - pos = PyLong_AsSsize_t(position_obj); - if (pos == -1 && PyErr_Occurred()) - return NULL; - if (pos < 0) { - PyErr_SetString(PyExc_ValueError, - "position value cannot be negative"); - return NULL; - } - self->pos = pos; - - /* Set the dictionary of the instance variables. */ - dict = PyTuple_GET_ITEM(state, 2); - if (dict != Py_None) { - if (!PyDict_Check(dict)) { - PyErr_Format(PyExc_TypeError, - "third item of state should be a dict, got a %.200s", - Py_TYPE(dict)->tp_name); - return NULL; - } - if (self->dict) { - /* Alternatively, we could replace the internal dictionary - completely. However, it seems more practical to just update it. */ - if (PyDict_Update(self->dict, dict) < 0) - return NULL; - } - else { - Py_INCREF(dict); - self->dict = dict; - } - } - - Py_RETURN_NONE; -} - -static void -bytesio_dealloc(bytesio *self) -{ - _PyObject_GC_UNTRACK(self); - if (self->exports > 0) { - PyErr_SetString(PyExc_SystemError, - "deallocated BytesIO object has exported buffers"); - PyErr_Print(); - } - Py_CLEAR(self->buf); - Py_CLEAR(self->dict); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - bytesio *self; - - assert(type != NULL && type->tp_alloc != NULL); - self = (bytesio *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - /* tp_alloc initializes all the fields to zero. So we don't have to - initialize them here. */ - - self->buf = PyBytes_FromStringAndSize(NULL, 0); - if (self->buf == NULL) { - Py_DECREF(self); - return PyErr_NoMemory(); - } - - return (PyObject *)self; -} - -/*[clinic input] -_io.BytesIO.__init__ - initial_bytes as initvalue: object(c_default="NULL") = b'' - -Buffered I/O implementation using an in-memory bytes buffer. -[clinic start generated code]*/ - -static int -_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue) -/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/ -{ - /* In case, __init__ is called multiple times. */ - self->string_size = 0; - self->pos = 0; - - if (self->exports > 0) { - PyErr_SetString(PyExc_BufferError, - "Existing exports of data: object cannot be re-sized"); - return -1; - } - if (initvalue && initvalue != Py_None) { - if (PyBytes_CheckExact(initvalue)) { - Py_INCREF(initvalue); - Py_XSETREF(self->buf, initvalue); - self->string_size = PyBytes_GET_SIZE(initvalue); - } - else { - PyObject *res; - res = _io_BytesIO_write(self, initvalue); - if (res == NULL) - return -1; - Py_DECREF(res); - self->pos = 0; - } - } - - return 0; -} - -static PyObject * -bytesio_sizeof(bytesio *self, void *unused) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); + position_obj = PyTuple_GET_ITEM(state, 1); + if (!PyLong_Check(position_obj)) { + PyErr_Format(PyExc_TypeError, + "second item of state must be an integer, not %.200s", + Py_TYPE(position_obj)->tp_name); + return NULL; + } + pos = PyLong_AsSsize_t(position_obj); + if (pos == -1 && PyErr_Occurred()) + return NULL; + if (pos < 0) { + PyErr_SetString(PyExc_ValueError, + "position value cannot be negative"); + return NULL; + } + self->pos = pos; + + /* Set the dictionary of the instance variables. */ + dict = PyTuple_GET_ITEM(state, 2); + if (dict != Py_None) { + if (!PyDict_Check(dict)) { + PyErr_Format(PyExc_TypeError, + "third item of state should be a dict, got a %.200s", + Py_TYPE(dict)->tp_name); + return NULL; + } + if (self->dict) { + /* Alternatively, we could replace the internal dictionary + completely. However, it seems more practical to just update it. */ + if (PyDict_Update(self->dict, dict) < 0) + return NULL; + } + else { + Py_INCREF(dict); + self->dict = dict; + } + } + + Py_RETURN_NONE; +} + +static void +bytesio_dealloc(bytesio *self) +{ + _PyObject_GC_UNTRACK(self); + if (self->exports > 0) { + PyErr_SetString(PyExc_SystemError, + "deallocated BytesIO object has exported buffers"); + PyErr_Print(); + } + Py_CLEAR(self->buf); + Py_CLEAR(self->dict); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + bytesio *self; + + assert(type != NULL && type->tp_alloc != NULL); + self = (bytesio *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + /* tp_alloc initializes all the fields to zero. So we don't have to + initialize them here. */ + + self->buf = PyBytes_FromStringAndSize(NULL, 0); + if (self->buf == NULL) { + Py_DECREF(self); + return PyErr_NoMemory(); + } + + return (PyObject *)self; +} + +/*[clinic input] +_io.BytesIO.__init__ + initial_bytes as initvalue: object(c_default="NULL") = b'' + +Buffered I/O implementation using an in-memory bytes buffer. +[clinic start generated code]*/ + +static int +_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue) +/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/ +{ + /* In case, __init__ is called multiple times. */ + self->string_size = 0; + self->pos = 0; + + if (self->exports > 0) { + PyErr_SetString(PyExc_BufferError, + "Existing exports of data: object cannot be re-sized"); + return -1; + } + if (initvalue && initvalue != Py_None) { + if (PyBytes_CheckExact(initvalue)) { + Py_INCREF(initvalue); + Py_XSETREF(self->buf, initvalue); + self->string_size = PyBytes_GET_SIZE(initvalue); + } + else { + PyObject *res; + res = _io_BytesIO_write(self, initvalue); + if (res == NULL) + return -1; + Py_DECREF(res); + self->pos = 0; + } + } + + return 0; +} + +static PyObject * +bytesio_sizeof(bytesio *self, void *unused) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(self)); if (self->buf && !SHARED_BUF(self)) { Py_ssize_t s = _PySys_GetSizeOf(self->buf); if (s == -1) { @@ -973,194 +973,194 @@ bytesio_sizeof(bytesio *self, void *unused) } res += s; } - return PyLong_FromSsize_t(res); -} - -static int -bytesio_traverse(bytesio *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -bytesio_clear(bytesio *self) -{ - Py_CLEAR(self->dict); - return 0; -} - - -#include "clinic/bytesio.c.h" - -static PyGetSetDef bytesio_getsetlist[] = { - {"closed", (getter)bytesio_get_closed, NULL, - "True if the file is closed."}, - {NULL}, /* sentinel */ -}; - -static struct PyMethodDef bytesio_methods[] = { - _IO_BYTESIO_READABLE_METHODDEF - _IO_BYTESIO_SEEKABLE_METHODDEF - _IO_BYTESIO_WRITABLE_METHODDEF - _IO_BYTESIO_CLOSE_METHODDEF - _IO_BYTESIO_FLUSH_METHODDEF - _IO_BYTESIO_ISATTY_METHODDEF - _IO_BYTESIO_TELL_METHODDEF - _IO_BYTESIO_WRITE_METHODDEF - _IO_BYTESIO_WRITELINES_METHODDEF - _IO_BYTESIO_READ1_METHODDEF - _IO_BYTESIO_READINTO_METHODDEF - _IO_BYTESIO_READLINE_METHODDEF - _IO_BYTESIO_READLINES_METHODDEF - _IO_BYTESIO_READ_METHODDEF - _IO_BYTESIO_GETBUFFER_METHODDEF - _IO_BYTESIO_GETVALUE_METHODDEF - _IO_BYTESIO_SEEK_METHODDEF - _IO_BYTESIO_TRUNCATE_METHODDEF - {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL}, - {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL}, - {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL}, - {NULL, NULL} /* sentinel */ -}; - -PyTypeObject PyBytesIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BytesIO", /*tp_name*/ - sizeof(bytesio), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)bytesio_dealloc, /*tp_dealloc*/ + return PyLong_FromSsize_t(res); +} + +static int +bytesio_traverse(bytesio *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +bytesio_clear(bytesio *self) +{ + Py_CLEAR(self->dict); + return 0; +} + + +#include "clinic/bytesio.c.h" + +static PyGetSetDef bytesio_getsetlist[] = { + {"closed", (getter)bytesio_get_closed, NULL, + "True if the file is closed."}, + {NULL}, /* sentinel */ +}; + +static struct PyMethodDef bytesio_methods[] = { + _IO_BYTESIO_READABLE_METHODDEF + _IO_BYTESIO_SEEKABLE_METHODDEF + _IO_BYTESIO_WRITABLE_METHODDEF + _IO_BYTESIO_CLOSE_METHODDEF + _IO_BYTESIO_FLUSH_METHODDEF + _IO_BYTESIO_ISATTY_METHODDEF + _IO_BYTESIO_TELL_METHODDEF + _IO_BYTESIO_WRITE_METHODDEF + _IO_BYTESIO_WRITELINES_METHODDEF + _IO_BYTESIO_READ1_METHODDEF + _IO_BYTESIO_READINTO_METHODDEF + _IO_BYTESIO_READLINE_METHODDEF + _IO_BYTESIO_READLINES_METHODDEF + _IO_BYTESIO_READ_METHODDEF + _IO_BYTESIO_GETBUFFER_METHODDEF + _IO_BYTESIO_GETVALUE_METHODDEF + _IO_BYTESIO_SEEK_METHODDEF + _IO_BYTESIO_TRUNCATE_METHODDEF + {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL}, + {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL}, + {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyBytesIO_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.BytesIO", /*tp_name*/ + sizeof(bytesio), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)bytesio_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_BytesIO___init____doc__, /*tp_doc*/ - (traverseproc)bytesio_traverse, /*tp_traverse*/ - (inquiry)bytesio_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/ - PyObject_SelfIter, /*tp_iter*/ - (iternextfunc)bytesio_iternext, /*tp_iternext*/ - bytesio_methods, /*tp_methods*/ - 0, /*tp_members*/ - bytesio_getsetlist, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - offsetof(bytesio, dict), /*tp_dictoffset*/ - _io_BytesIO___init__, /*tp_init*/ - 0, /*tp_alloc*/ - bytesio_new, /*tp_new*/ -}; - - -/* - * Implementation of the small intermediate object used by getbuffer(). - * getbuffer() returns a memoryview over this object, which should make it - * invisible from Python code. - */ - -static int -bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags) -{ - bytesio *b = (bytesio *) obj->source; - - if (view == NULL) { - PyErr_SetString(PyExc_BufferError, - "bytesiobuf_getbuffer: view==NULL argument is obsolete"); - return -1; - } - if (SHARED_BUF(b)) { - if (unshare_buffer(b, b->string_size) < 0) - return -1; - } - - /* cannot fail if view != NULL and readonly == 0 */ - (void)PyBuffer_FillInfo(view, (PyObject*)obj, - PyBytes_AS_STRING(b->buf), b->string_size, - 0, flags); - b->exports++; - return 0; -} - -static void -bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view) -{ - bytesio *b = (bytesio *) obj->source; - b->exports--; -} - -static int -bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg) -{ - Py_VISIT(self->source); - return 0; -} - -static void -bytesiobuf_dealloc(bytesiobuf *self) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(self); - Py_CLEAR(self->source); - Py_TYPE(self)->tp_free(self); -} - -static PyBufferProcs bytesiobuf_as_buffer = { - (getbufferproc) bytesiobuf_getbuffer, - (releasebufferproc) bytesiobuf_releasebuffer, -}; - + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + _io_BytesIO___init____doc__, /*tp_doc*/ + (traverseproc)bytesio_traverse, /*tp_traverse*/ + (inquiry)bytesio_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/ + PyObject_SelfIter, /*tp_iter*/ + (iternextfunc)bytesio_iternext, /*tp_iternext*/ + bytesio_methods, /*tp_methods*/ + 0, /*tp_members*/ + bytesio_getsetlist, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + offsetof(bytesio, dict), /*tp_dictoffset*/ + _io_BytesIO___init__, /*tp_init*/ + 0, /*tp_alloc*/ + bytesio_new, /*tp_new*/ +}; + + +/* + * Implementation of the small intermediate object used by getbuffer(). + * getbuffer() returns a memoryview over this object, which should make it + * invisible from Python code. + */ + +static int +bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags) +{ + bytesio *b = (bytesio *) obj->source; + + if (view == NULL) { + PyErr_SetString(PyExc_BufferError, + "bytesiobuf_getbuffer: view==NULL argument is obsolete"); + return -1; + } + if (SHARED_BUF(b)) { + if (unshare_buffer(b, b->string_size) < 0) + return -1; + } + + /* cannot fail if view != NULL and readonly == 0 */ + (void)PyBuffer_FillInfo(view, (PyObject*)obj, + PyBytes_AS_STRING(b->buf), b->string_size, + 0, flags); + b->exports++; + return 0; +} + +static void +bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view) +{ + bytesio *b = (bytesio *) obj->source; + b->exports--; +} + +static int +bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg) +{ + Py_VISIT(self->source); + return 0; +} + +static void +bytesiobuf_dealloc(bytesiobuf *self) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(self); + Py_CLEAR(self->source); + Py_TYPE(self)->tp_free(self); +} + +static PyBufferProcs bytesiobuf_as_buffer = { + (getbufferproc) bytesiobuf_getbuffer, + (releasebufferproc) bytesiobuf_releasebuffer, +}; + Py_EXPORTED_SYMBOL PyTypeObject _PyBytesIOBuffer_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._BytesIOBuffer", /*tp_name*/ - sizeof(bytesiobuf), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)bytesiobuf_dealloc, /*tp_dealloc*/ + PyVarObject_HEAD_INIT(NULL, 0) + "_io._BytesIOBuffer", /*tp_name*/ + sizeof(bytesiobuf), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)bytesiobuf_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 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*/ - &bytesiobuf_as_buffer, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc)bytesiobuf_traverse, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - 0, /*tp_new*/ -}; + 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*/ + &bytesiobuf_as_buffer, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + (traverseproc)bytesiobuf_traverse, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ +}; diff --git a/contrib/tools/python3/src/Modules/_io/clinic/_iomodule.c.h b/contrib/tools/python3/src/Modules/_io/clinic/_iomodule.c.h index 1a9651d3408..3cab3356809 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/_iomodule.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/_iomodule.c.h @@ -1,160 +1,160 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_io_open__doc__, -"open($module, /, file, mode=\'r\', buffering=-1, encoding=None,\n" -" errors=None, newline=None, closefd=True, opener=None)\n" -"--\n" -"\n" -"Open file and return a stream. Raise OSError upon failure.\n" -"\n" -"file is either a text or byte string giving the name (and the path\n" -"if the file isn\'t in the current working directory) of the file to\n" -"be opened or an integer file descriptor of the file to be\n" -"wrapped. (If a file descriptor is given, it is closed when the\n" -"returned I/O object is closed, unless closefd is set to False.)\n" -"\n" -"mode is an optional string that specifies the mode in which the file\n" -"is opened. It defaults to \'r\' which means open for reading in text\n" -"mode. Other common values are \'w\' for writing (truncating the file if\n" -"it already exists), \'x\' for creating and writing to a new file, and\n" -"\'a\' for appending (which on some Unix systems, means that all writes\n" -"append to the end of the file regardless of the current seek position).\n" -"In text mode, if encoding is not specified the encoding used is platform\n" -"dependent: locale.getpreferredencoding(False) is called to get the\n" -"current locale encoding. (For reading and writing raw bytes use binary\n" -"mode and leave encoding unspecified.) The available modes are:\n" -"\n" -"========= ===============================================================\n" -"Character Meaning\n" -"--------- ---------------------------------------------------------------\n" -"\'r\' open for reading (default)\n" -"\'w\' open for writing, truncating the file first\n" -"\'x\' create a new file and open it for writing\n" -"\'a\' open for writing, appending to the end of the file if it exists\n" -"\'b\' binary mode\n" -"\'t\' text mode (default)\n" -"\'+\' open a disk file for updating (reading and writing)\n" -"\'U\' universal newline mode (deprecated)\n" -"========= ===============================================================\n" -"\n" -"The default mode is \'rt\' (open for reading text). For binary random\n" -"access, the mode \'w+b\' opens and truncates the file to 0 bytes, while\n" -"\'r+b\' opens the file without truncation. The \'x\' mode implies \'w\' and\n" -"raises an `FileExistsError` if the file already exists.\n" -"\n" -"Python distinguishes between files opened in binary and text modes,\n" -"even when the underlying operating system doesn\'t. Files opened in\n" -"binary mode (appending \'b\' to the mode argument) return contents as\n" -"bytes objects without any decoding. In text mode (the default, or when\n" -"\'t\' is appended to the mode argument), the contents of the file are\n" -"returned as strings, the bytes having been first decoded using a\n" -"platform-dependent encoding or using the specified encoding if given.\n" -"\n" -"\'U\' mode is deprecated and will raise an exception in future versions\n" -"of Python. It has no effect in Python 3. Use newline to control\n" -"universal newlines mode.\n" -"\n" -"buffering is an optional integer used to set the buffering policy.\n" -"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n" -"line buffering (only usable in text mode), and an integer > 1 to indicate\n" -"the size of a fixed-size chunk buffer. When no buffering argument is\n" -"given, the default buffering policy works as follows:\n" -"\n" -"* Binary files are buffered in fixed-size chunks; the size of the buffer\n" -" is chosen using a heuristic trying to determine the underlying device\'s\n" -" \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n" -" On many systems, the buffer will typically be 4096 or 8192 bytes long.\n" -"\n" -"* \"Interactive\" text files (files for which isatty() returns True)\n" -" use line buffering. Other text files use the policy described above\n" -" for binary files.\n" -"\n" -"encoding is the name of the encoding used to decode or encode the\n" -"file. This should only be used in text mode. The default encoding is\n" -"platform dependent, but any encoding supported by Python can be\n" -"passed. See the codecs module for the list of supported encodings.\n" -"\n" -"errors is an optional string that specifies how encoding errors are to\n" -"be handled---this argument should not be used in binary mode. Pass\n" -"\'strict\' to raise a ValueError exception if there is an encoding error\n" -"(the default of None has the same effect), or pass \'ignore\' to ignore\n" -"errors. (Note that ignoring encoding errors can lead to data loss.)\n" -"See the documentation for codecs.register or run \'help(codecs.Codec)\'\n" -"for a list of the permitted encoding error strings.\n" -"\n" -"newline controls how universal newlines works (it only applies to text\n" -"mode). It can be None, \'\', \'\\n\', \'\\r\', and \'\\r\\n\'. It works as\n" -"follows:\n" -"\n" -"* On input, if newline is None, universal newlines mode is\n" -" enabled. Lines in the input can end in \'\\n\', \'\\r\', or \'\\r\\n\', and\n" -" these are translated into \'\\n\' before being returned to the\n" -" caller. If it is \'\', universal newline mode is enabled, but line\n" -" endings are returned to the caller untranslated. If it has any of\n" -" the other legal values, input lines are only terminated by the given\n" -" string, and the line ending is returned to the caller untranslated.\n" -"\n" -"* On output, if newline is None, any \'\\n\' characters written are\n" -" translated to the system default line separator, os.linesep. If\n" -" newline is \'\' or \'\\n\', no translation takes place. If newline is any\n" -" of the other legal values, any \'\\n\' characters written are translated\n" -" to the given string.\n" -"\n" -"If closefd is False, the underlying file descriptor will be kept open\n" -"when the file is closed. This does not work when a file name is given\n" -"and must be True in that case.\n" -"\n" -"A custom opener can be used by passing a callable as *opener*. The\n" -"underlying file descriptor for the file object is then obtained by\n" -"calling *opener* with (*file*, *flags*). *opener* must return an open\n" -"file descriptor (passing os.open as *opener* results in functionality\n" -"similar to passing None).\n" -"\n" -"open() returns a file object whose type depends on the mode, and\n" -"through which the standard file operations such as reading and writing\n" -"are performed. When open() is used to open a file in a text mode (\'w\',\n" -"\'r\', \'wt\', \'rt\', etc.), it returns a TextIOWrapper. When used to open\n" -"a file in a binary mode, the returned class varies: in read binary\n" -"mode, it returns a BufferedReader; in write binary and append binary\n" -"modes, it returns a BufferedWriter, and in read/write mode, it returns\n" -"a BufferedRandom.\n" -"\n" -"It is also possible to use a string or bytearray as a file for both\n" -"reading and writing. For strings StringIO can be used like a file\n" -"opened in a text mode, and for bytes a BytesIO can be used like a file\n" -"opened in a binary mode."); - -#define _IO_OPEN_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_io_open__doc__, +"open($module, /, file, mode=\'r\', buffering=-1, encoding=None,\n" +" errors=None, newline=None, closefd=True, opener=None)\n" +"--\n" +"\n" +"Open file and return a stream. Raise OSError upon failure.\n" +"\n" +"file is either a text or byte string giving the name (and the path\n" +"if the file isn\'t in the current working directory) of the file to\n" +"be opened or an integer file descriptor of the file to be\n" +"wrapped. (If a file descriptor is given, it is closed when the\n" +"returned I/O object is closed, unless closefd is set to False.)\n" +"\n" +"mode is an optional string that specifies the mode in which the file\n" +"is opened. It defaults to \'r\' which means open for reading in text\n" +"mode. Other common values are \'w\' for writing (truncating the file if\n" +"it already exists), \'x\' for creating and writing to a new file, and\n" +"\'a\' for appending (which on some Unix systems, means that all writes\n" +"append to the end of the file regardless of the current seek position).\n" +"In text mode, if encoding is not specified the encoding used is platform\n" +"dependent: locale.getpreferredencoding(False) is called to get the\n" +"current locale encoding. (For reading and writing raw bytes use binary\n" +"mode and leave encoding unspecified.) The available modes are:\n" +"\n" +"========= ===============================================================\n" +"Character Meaning\n" +"--------- ---------------------------------------------------------------\n" +"\'r\' open for reading (default)\n" +"\'w\' open for writing, truncating the file first\n" +"\'x\' create a new file and open it for writing\n" +"\'a\' open for writing, appending to the end of the file if it exists\n" +"\'b\' binary mode\n" +"\'t\' text mode (default)\n" +"\'+\' open a disk file for updating (reading and writing)\n" +"\'U\' universal newline mode (deprecated)\n" +"========= ===============================================================\n" +"\n" +"The default mode is \'rt\' (open for reading text). For binary random\n" +"access, the mode \'w+b\' opens and truncates the file to 0 bytes, while\n" +"\'r+b\' opens the file without truncation. The \'x\' mode implies \'w\' and\n" +"raises an `FileExistsError` if the file already exists.\n" +"\n" +"Python distinguishes between files opened in binary and text modes,\n" +"even when the underlying operating system doesn\'t. Files opened in\n" +"binary mode (appending \'b\' to the mode argument) return contents as\n" +"bytes objects without any decoding. In text mode (the default, or when\n" +"\'t\' is appended to the mode argument), the contents of the file are\n" +"returned as strings, the bytes having been first decoded using a\n" +"platform-dependent encoding or using the specified encoding if given.\n" +"\n" +"\'U\' mode is deprecated and will raise an exception in future versions\n" +"of Python. It has no effect in Python 3. Use newline to control\n" +"universal newlines mode.\n" +"\n" +"buffering is an optional integer used to set the buffering policy.\n" +"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n" +"line buffering (only usable in text mode), and an integer > 1 to indicate\n" +"the size of a fixed-size chunk buffer. When no buffering argument is\n" +"given, the default buffering policy works as follows:\n" +"\n" +"* Binary files are buffered in fixed-size chunks; the size of the buffer\n" +" is chosen using a heuristic trying to determine the underlying device\'s\n" +" \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n" +" On many systems, the buffer will typically be 4096 or 8192 bytes long.\n" +"\n" +"* \"Interactive\" text files (files for which isatty() returns True)\n" +" use line buffering. Other text files use the policy described above\n" +" for binary files.\n" +"\n" +"encoding is the name of the encoding used to decode or encode the\n" +"file. This should only be used in text mode. The default encoding is\n" +"platform dependent, but any encoding supported by Python can be\n" +"passed. See the codecs module for the list of supported encodings.\n" +"\n" +"errors is an optional string that specifies how encoding errors are to\n" +"be handled---this argument should not be used in binary mode. Pass\n" +"\'strict\' to raise a ValueError exception if there is an encoding error\n" +"(the default of None has the same effect), or pass \'ignore\' to ignore\n" +"errors. (Note that ignoring encoding errors can lead to data loss.)\n" +"See the documentation for codecs.register or run \'help(codecs.Codec)\'\n" +"for a list of the permitted encoding error strings.\n" +"\n" +"newline controls how universal newlines works (it only applies to text\n" +"mode). It can be None, \'\', \'\\n\', \'\\r\', and \'\\r\\n\'. It works as\n" +"follows:\n" +"\n" +"* On input, if newline is None, universal newlines mode is\n" +" enabled. Lines in the input can end in \'\\n\', \'\\r\', or \'\\r\\n\', and\n" +" these are translated into \'\\n\' before being returned to the\n" +" caller. If it is \'\', universal newline mode is enabled, but line\n" +" endings are returned to the caller untranslated. If it has any of\n" +" the other legal values, input lines are only terminated by the given\n" +" string, and the line ending is returned to the caller untranslated.\n" +"\n" +"* On output, if newline is None, any \'\\n\' characters written are\n" +" translated to the system default line separator, os.linesep. If\n" +" newline is \'\' or \'\\n\', no translation takes place. If newline is any\n" +" of the other legal values, any \'\\n\' characters written are translated\n" +" to the given string.\n" +"\n" +"If closefd is False, the underlying file descriptor will be kept open\n" +"when the file is closed. This does not work when a file name is given\n" +"and must be True in that case.\n" +"\n" +"A custom opener can be used by passing a callable as *opener*. The\n" +"underlying file descriptor for the file object is then obtained by\n" +"calling *opener* with (*file*, *flags*). *opener* must return an open\n" +"file descriptor (passing os.open as *opener* results in functionality\n" +"similar to passing None).\n" +"\n" +"open() returns a file object whose type depends on the mode, and\n" +"through which the standard file operations such as reading and writing\n" +"are performed. When open() is used to open a file in a text mode (\'w\',\n" +"\'r\', \'wt\', \'rt\', etc.), it returns a TextIOWrapper. When used to open\n" +"a file in a binary mode, the returned class varies: in read binary\n" +"mode, it returns a BufferedReader; in write binary and append binary\n" +"modes, it returns a BufferedWriter, and in read/write mode, it returns\n" +"a BufferedRandom.\n" +"\n" +"It is also possible to use a string or bytearray as a file for both\n" +"reading and writing. For strings StringIO can be used like a file\n" +"opened in a text mode, and for bytes a BytesIO can be used like a file\n" +"opened in a binary mode."); + +#define _IO_OPEN_METHODDEF \ {"open", (PyCFunction)(void(*)(void))_io_open, METH_FASTCALL|METH_KEYWORDS, _io_open__doc__}, - -static PyObject * -_io_open_impl(PyObject *module, PyObject *file, const char *mode, - int buffering, const char *encoding, const char *errors, - const char *newline, int closefd, PyObject *opener); - -static PyObject * -_io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; + +static PyObject * +_io_open_impl(PyObject *module, PyObject *file, const char *mode, + int buffering, const char *encoding, const char *errors, + const char *newline, int closefd, PyObject *opener); + +static PyObject * +_io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; PyObject *argsbuf[8]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *file; - const char *mode = "r"; - int buffering = -1; - const char *encoding = NULL; - const char *errors = NULL; - const char *newline = NULL; - int closefd = 1; - PyObject *opener = Py_None; - + PyObject *file; + const char *mode = "r"; + int buffering = -1; + const char *encoding = NULL; + const char *errors = NULL; + const char *newline = NULL; + int closefd = 1; + PyObject *opener = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 8, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } file = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -276,11 +276,11 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } opener = args[7]; skip_optional_pos: - return_value = _io_open_impl(module, file, mode, buffering, encoding, errors, newline, closefd, opener); - -exit: - return return_value; -} + return_value = _io_open_impl(module, file, mode, buffering, encoding, errors, newline, closefd, opener); + +exit: + return return_value; +} PyDoc_STRVAR(_io_open_code__doc__, "open_code($module, /, path)\n" diff --git a/contrib/tools/python3/src/Modules/_io/clinic/bufferedio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/bufferedio.c.h index 56d6332a250..b5e677812f5 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/bufferedio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/bufferedio.c.h @@ -1,122 +1,122 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_io__BufferedIOBase_readinto__doc__, -"readinto($self, buffer, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFEREDIOBASE_READINTO_METHODDEF \ - {"readinto", (PyCFunction)_io__BufferedIOBase_readinto, METH_O, _io__BufferedIOBase_readinto__doc__}, - -static PyObject * -_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer); - -static PyObject * -_io__BufferedIOBase_readinto(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_io__BufferedIOBase_readinto__doc__, +"readinto($self, buffer, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFEREDIOBASE_READINTO_METHODDEF \ + {"readinto", (PyCFunction)_io__BufferedIOBase_readinto, METH_O, _io__BufferedIOBase_readinto__doc__}, + +static PyObject * +_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer); + +static PyObject * +_io__BufferedIOBase_readinto(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io__BufferedIOBase_readinto_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(_io__BufferedIOBase_readinto1__doc__, -"readinto1($self, buffer, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFEREDIOBASE_READINTO1_METHODDEF \ - {"readinto1", (PyCFunction)_io__BufferedIOBase_readinto1, METH_O, _io__BufferedIOBase_readinto1__doc__}, - -static PyObject * -_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer); - -static PyObject * -_io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + return_value = _io__BufferedIOBase_readinto_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(_io__BufferedIOBase_readinto1__doc__, +"readinto1($self, buffer, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFEREDIOBASE_READINTO1_METHODDEF \ + {"readinto1", (PyCFunction)_io__BufferedIOBase_readinto1, METH_O, _io__BufferedIOBase_readinto1__doc__}, + +static PyObject * +_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer); + +static PyObject * +_io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("readinto1", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io__BufferedIOBase_readinto1_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(_io__BufferedIOBase_detach__doc__, -"detach($self, /)\n" -"--\n" -"\n" -"Disconnect this buffer from its underlying raw stream and return it.\n" -"\n" -"After the raw stream has been detached, the buffer is in an unusable\n" -"state."); - -#define _IO__BUFFEREDIOBASE_DETACH_METHODDEF \ - {"detach", (PyCFunction)_io__BufferedIOBase_detach, METH_NOARGS, _io__BufferedIOBase_detach__doc__}, - -static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self); - -static PyObject * -_io__BufferedIOBase_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__BufferedIOBase_detach_impl(self); -} - -PyDoc_STRVAR(_io__Buffered_peek__doc__, -"peek($self, size=0, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFERED_PEEK_METHODDEF \ + return_value = _io__BufferedIOBase_readinto1_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(_io__BufferedIOBase_detach__doc__, +"detach($self, /)\n" +"--\n" +"\n" +"Disconnect this buffer from its underlying raw stream and return it.\n" +"\n" +"After the raw stream has been detached, the buffer is in an unusable\n" +"state."); + +#define _IO__BUFFEREDIOBASE_DETACH_METHODDEF \ + {"detach", (PyCFunction)_io__BufferedIOBase_detach, METH_NOARGS, _io__BufferedIOBase_detach__doc__}, + +static PyObject * +_io__BufferedIOBase_detach_impl(PyObject *self); + +static PyObject * +_io__BufferedIOBase_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__BufferedIOBase_detach_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_peek__doc__, +"peek($self, size=0, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_PEEK_METHODDEF \ {"peek", (PyCFunction)(void(*)(void))_io__Buffered_peek, METH_FASTCALL, _io__Buffered_peek__doc__}, - -static PyObject * -_io__Buffered_peek_impl(buffered *self, Py_ssize_t size); - -static PyObject * -_io__Buffered_peek(buffered *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = 0; - + +static PyObject * +_io__Buffered_peek_impl(buffered *self, Py_ssize_t size); + +static PyObject * +_io__Buffered_peek(buffered *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = 0; + if (!_PyArg_CheckPositional("peek", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -138,32 +138,32 @@ _io__Buffered_peek(buffered *self, PyObject *const *args, Py_ssize_t nargs) size = ival; } skip_optional: - return_value = _io__Buffered_peek_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io__Buffered_read__doc__, -"read($self, size=-1, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFERED_READ_METHODDEF \ + return_value = _io__Buffered_peek_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__Buffered_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_io__Buffered_read, METH_FASTCALL, _io__Buffered_read__doc__}, - -static PyObject * -_io__Buffered_read_impl(buffered *self, Py_ssize_t n); - -static PyObject * -_io__Buffered_read(buffered *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t n = -1; - + +static PyObject * +_io__Buffered_read_impl(buffered *self, Py_ssize_t n); + +static PyObject * +_io__Buffered_read(buffered *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t n = -1; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -171,32 +171,32 @@ _io__Buffered_read(buffered *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io__Buffered_read_impl(self, n); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io__Buffered_read1__doc__, -"read1($self, size=-1, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFERED_READ1_METHODDEF \ + return_value = _io__Buffered_read_impl(self, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__Buffered_read1__doc__, +"read1($self, size=-1, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_READ1_METHODDEF \ {"read1", (PyCFunction)(void(*)(void))_io__Buffered_read1, METH_FASTCALL, _io__Buffered_read1__doc__}, - -static PyObject * -_io__Buffered_read1_impl(buffered *self, Py_ssize_t n); - -static PyObject * -_io__Buffered_read1(buffered *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t n = -1; - + +static PyObject * +_io__Buffered_read1_impl(buffered *self, Py_ssize_t n); + +static PyObject * +_io__Buffered_read1(buffered *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t n = -1; + if (!_PyArg_CheckPositional("read1", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -218,106 +218,106 @@ _io__Buffered_read1(buffered *self, PyObject *const *args, Py_ssize_t nargs) n = ival; } skip_optional: - return_value = _io__Buffered_read1_impl(self, n); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io__Buffered_readinto__doc__, -"readinto($self, buffer, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFERED_READINTO_METHODDEF \ - {"readinto", (PyCFunction)_io__Buffered_readinto, METH_O, _io__Buffered_readinto__doc__}, - -static PyObject * -_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer); - -static PyObject * -_io__Buffered_readinto(buffered *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + return_value = _io__Buffered_read1_impl(self, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__Buffered_readinto__doc__, +"readinto($self, buffer, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_READINTO_METHODDEF \ + {"readinto", (PyCFunction)_io__Buffered_readinto, METH_O, _io__Buffered_readinto__doc__}, + +static PyObject * +_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer); + +static PyObject * +_io__Buffered_readinto(buffered *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io__Buffered_readinto_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(_io__Buffered_readinto1__doc__, -"readinto1($self, buffer, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFERED_READINTO1_METHODDEF \ - {"readinto1", (PyCFunction)_io__Buffered_readinto1, METH_O, _io__Buffered_readinto1__doc__}, - -static PyObject * -_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer); - -static PyObject * -_io__Buffered_readinto1(buffered *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + return_value = _io__Buffered_readinto_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(_io__Buffered_readinto1__doc__, +"readinto1($self, buffer, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_READINTO1_METHODDEF \ + {"readinto1", (PyCFunction)_io__Buffered_readinto1, METH_O, _io__Buffered_readinto1__doc__}, + +static PyObject * +_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer); + +static PyObject * +_io__Buffered_readinto1(buffered *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("readinto1", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io__Buffered_readinto1_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(_io__Buffered_readline__doc__, -"readline($self, size=-1, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFERED_READLINE_METHODDEF \ + return_value = _io__Buffered_readinto1_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(_io__Buffered_readline__doc__, +"readline($self, size=-1, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_READLINE_METHODDEF \ {"readline", (PyCFunction)(void(*)(void))_io__Buffered_readline, METH_FASTCALL, _io__Buffered_readline__doc__}, - -static PyObject * -_io__Buffered_readline_impl(buffered *self, Py_ssize_t size); - -static PyObject * -_io__Buffered_readline(buffered *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io__Buffered_readline_impl(buffered *self, Py_ssize_t size); + +static PyObject * +_io__Buffered_readline(buffered *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -325,33 +325,33 @@ _io__Buffered_readline(buffered *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io__Buffered_readline_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io__Buffered_seek__doc__, -"seek($self, target, whence=0, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFERED_SEEK_METHODDEF \ + return_value = _io__Buffered_readline_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__Buffered_seek__doc__, +"seek($self, target, whence=0, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_SEEK_METHODDEF \ {"seek", (PyCFunction)(void(*)(void))_io__Buffered_seek, METH_FASTCALL, _io__Buffered_seek__doc__}, - -static PyObject * -_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence); - -static PyObject * -_io__Buffered_seek(buffered *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *targetobj; - int whence = 0; - + +static PyObject * +_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence); + +static PyObject * +_io__Buffered_seek(buffered *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *targetobj; + int whence = 0; + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { - goto exit; - } + goto exit; + } targetobj = args[0]; if (nargs < 2) { goto skip_optional; @@ -366,70 +366,70 @@ _io__Buffered_seek(buffered *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io__Buffered_seek_impl(self, targetobj, whence); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io__Buffered_truncate__doc__, -"truncate($self, pos=None, /)\n" -"--\n" -"\n"); - -#define _IO__BUFFERED_TRUNCATE_METHODDEF \ + return_value = _io__Buffered_seek_impl(self, targetobj, whence); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__Buffered_truncate__doc__, +"truncate($self, pos=None, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_TRUNCATE_METHODDEF \ {"truncate", (PyCFunction)(void(*)(void))_io__Buffered_truncate, METH_FASTCALL, _io__Buffered_truncate__doc__}, - -static PyObject * -_io__Buffered_truncate_impl(buffered *self, PyObject *pos); - -static PyObject * -_io__Buffered_truncate(buffered *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *pos = Py_None; - + +static PyObject * +_io__Buffered_truncate_impl(buffered *self, PyObject *pos); + +static PyObject * +_io__Buffered_truncate(buffered *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *pos = Py_None; + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } pos = args[0]; skip_optional: - return_value = _io__Buffered_truncate_impl(self, pos); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BufferedReader___init____doc__, -"BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)\n" -"--\n" -"\n" -"Create a new buffered reader using the given readable raw IO object."); - -static int -_io_BufferedReader___init___impl(buffered *self, PyObject *raw, - Py_ssize_t buffer_size); - -static int -_io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"raw", "buffer_size", NULL}; + return_value = _io__Buffered_truncate_impl(self, pos); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BufferedReader___init____doc__, +"BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)\n" +"--\n" +"\n" +"Create a new buffered reader using the given readable raw IO object."); + +static int +_io_BufferedReader___init___impl(buffered *self, PyObject *raw, + Py_ssize_t buffer_size); + +static int +_io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "BufferedReader", 0}; PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *raw; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - + PyObject *raw; + Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } raw = fastargs[0]; if (!noptargs) { goto skip_optional_pos; @@ -452,43 +452,43 @@ _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) buffer_size = ival; } skip_optional_pos: - return_value = _io_BufferedReader___init___impl((buffered *)self, raw, buffer_size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BufferedWriter___init____doc__, -"BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)\n" -"--\n" -"\n" -"A buffer for a writeable sequential RawIO object.\n" -"\n" -"The constructor creates a BufferedWriter for the given writeable raw\n" -"stream. If the buffer_size is not given, it defaults to\n" -"DEFAULT_BUFFER_SIZE."); - -static int -_io_BufferedWriter___init___impl(buffered *self, PyObject *raw, - Py_ssize_t buffer_size); - -static int -_io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"raw", "buffer_size", NULL}; + return_value = _io_BufferedReader___init___impl((buffered *)self, raw, buffer_size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BufferedWriter___init____doc__, +"BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)\n" +"--\n" +"\n" +"A buffer for a writeable sequential RawIO object.\n" +"\n" +"The constructor creates a BufferedWriter for the given writeable raw\n" +"stream. If the buffer_size is not given, it defaults to\n" +"DEFAULT_BUFFER_SIZE."); + +static int +_io_BufferedWriter___init___impl(buffered *self, PyObject *raw, + Py_ssize_t buffer_size); + +static int +_io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "BufferedWriter", 0}; PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *raw; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - + PyObject *raw; + Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } raw = fastargs[0]; if (!noptargs) { goto skip_optional_pos; @@ -511,80 +511,80 @@ _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) buffer_size = ival; } skip_optional_pos: - return_value = _io_BufferedWriter___init___impl((buffered *)self, raw, buffer_size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BufferedWriter_write__doc__, -"write($self, buffer, /)\n" -"--\n" -"\n"); - -#define _IO_BUFFEREDWRITER_WRITE_METHODDEF \ - {"write", (PyCFunction)_io_BufferedWriter_write, METH_O, _io_BufferedWriter_write__doc__}, - -static PyObject * -_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer); - -static PyObject * -_io_BufferedWriter_write(buffered *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + return_value = _io_BufferedWriter___init___impl((buffered *)self, raw, buffer_size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BufferedWriter_write__doc__, +"write($self, buffer, /)\n" +"--\n" +"\n"); + +#define _IO_BUFFEREDWRITER_WRITE_METHODDEF \ + {"write", (PyCFunction)_io_BufferedWriter_write, METH_O, _io_BufferedWriter_write__doc__}, + +static PyObject * +_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer); + +static PyObject * +_io_BufferedWriter_write(buffered *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io_BufferedWriter_write_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(_io_BufferedRWPair___init____doc__, -"BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /)\n" -"--\n" -"\n" -"A buffered reader and writer object together.\n" -"\n" -"A buffered reader object and buffered writer object put together to\n" -"form a sequential IO object that can read and write. This is typically\n" -"used with a socket or two-way pipe.\n" -"\n" -"reader and writer are RawIOBase objects that are readable and\n" -"writeable respectively. If the buffer_size is omitted it defaults to\n" -"DEFAULT_BUFFER_SIZE."); - -static int -_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader, - PyObject *writer, Py_ssize_t buffer_size); - -static int -_io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - PyObject *reader; - PyObject *writer; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - + return_value = _io_BufferedWriter_write_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(_io_BufferedRWPair___init____doc__, +"BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /)\n" +"--\n" +"\n" +"A buffered reader and writer object together.\n" +"\n" +"A buffered reader object and buffered writer object put together to\n" +"form a sequential IO object that can read and write. This is typically\n" +"used with a socket or two-way pipe.\n" +"\n" +"reader and writer are RawIOBase objects that are readable and\n" +"writeable respectively. If the buffer_size is omitted it defaults to\n" +"DEFAULT_BUFFER_SIZE."); + +static int +_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader, + PyObject *writer, Py_ssize_t buffer_size); + +static int +_io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + PyObject *reader; + PyObject *writer; + Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; + if (Py_IS_TYPE(self, &PyBufferedRWPair_Type) && - !_PyArg_NoKeywords("BufferedRWPair", kwargs)) { - goto exit; - } + !_PyArg_NoKeywords("BufferedRWPair", kwargs)) { + goto exit; + } if (!_PyArg_CheckPositional("BufferedRWPair", PyTuple_GET_SIZE(args), 2, 3)) { - goto exit; - } + goto exit; + } reader = PyTuple_GET_ITEM(args, 0); writer = PyTuple_GET_ITEM(args, 1); if (PyTuple_GET_SIZE(args) < 3) { @@ -608,43 +608,43 @@ _io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs) buffer_size = ival; } skip_optional: - return_value = _io_BufferedRWPair___init___impl((rwpair *)self, reader, writer, buffer_size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BufferedRandom___init____doc__, -"BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)\n" -"--\n" -"\n" -"A buffered interface to random access streams.\n" -"\n" -"The constructor creates a reader and writer for a seekable stream,\n" -"raw, given in the first argument. If the buffer_size is omitted it\n" -"defaults to DEFAULT_BUFFER_SIZE."); - -static int -_io_BufferedRandom___init___impl(buffered *self, PyObject *raw, - Py_ssize_t buffer_size); - -static int -_io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"raw", "buffer_size", NULL}; + return_value = _io_BufferedRWPair___init___impl((rwpair *)self, reader, writer, buffer_size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BufferedRandom___init____doc__, +"BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)\n" +"--\n" +"\n" +"A buffered interface to random access streams.\n" +"\n" +"The constructor creates a reader and writer for a seekable stream,\n" +"raw, given in the first argument. If the buffer_size is omitted it\n" +"defaults to DEFAULT_BUFFER_SIZE."); + +static int +_io_BufferedRandom___init___impl(buffered *self, PyObject *raw, + Py_ssize_t buffer_size); + +static int +_io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "BufferedRandom", 0}; PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *raw; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - + PyObject *raw; + Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 2, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } raw = fastargs[0]; if (!noptargs) { goto skip_optional_pos; @@ -667,9 +667,9 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) buffer_size = ival; } skip_optional_pos: - return_value = _io_BufferedRandom___init___impl((buffered *)self, raw, buffer_size); - -exit: - return return_value; -} + return_value = _io_BufferedRandom___init___impl((buffered *)self, raw, buffer_size); + +exit: + return return_value; +} /*[clinic end generated code: output=7d9ad40c95bdd808 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/bytesio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/bytesio.c.h index 83cd490dc59..af84feb8daa 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/bytesio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/bytesio.c.h @@ -1,177 +1,177 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_io_BytesIO_readable__doc__, -"readable($self, /)\n" -"--\n" -"\n" -"Returns True if the IO object can be read."); - -#define _IO_BYTESIO_READABLE_METHODDEF \ - {"readable", (PyCFunction)_io_BytesIO_readable, METH_NOARGS, _io_BytesIO_readable__doc__}, - -static PyObject * -_io_BytesIO_readable_impl(bytesio *self); - -static PyObject * -_io_BytesIO_readable(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_readable_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO_writable__doc__, -"writable($self, /)\n" -"--\n" -"\n" -"Returns True if the IO object can be written."); - -#define _IO_BYTESIO_WRITABLE_METHODDEF \ - {"writable", (PyCFunction)_io_BytesIO_writable, METH_NOARGS, _io_BytesIO_writable__doc__}, - -static PyObject * -_io_BytesIO_writable_impl(bytesio *self); - -static PyObject * -_io_BytesIO_writable(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_writable_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO_seekable__doc__, -"seekable($self, /)\n" -"--\n" -"\n" -"Returns True if the IO object can be seeked."); - -#define _IO_BYTESIO_SEEKABLE_METHODDEF \ - {"seekable", (PyCFunction)_io_BytesIO_seekable, METH_NOARGS, _io_BytesIO_seekable__doc__}, - -static PyObject * -_io_BytesIO_seekable_impl(bytesio *self); - -static PyObject * -_io_BytesIO_seekable(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_seekable_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO_flush__doc__, -"flush($self, /)\n" -"--\n" -"\n" -"Does nothing."); - -#define _IO_BYTESIO_FLUSH_METHODDEF \ - {"flush", (PyCFunction)_io_BytesIO_flush, METH_NOARGS, _io_BytesIO_flush__doc__}, - -static PyObject * -_io_BytesIO_flush_impl(bytesio *self); - -static PyObject * -_io_BytesIO_flush(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_flush_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO_getbuffer__doc__, -"getbuffer($self, /)\n" -"--\n" -"\n" -"Get a read-write view over the contents of the BytesIO object."); - -#define _IO_BYTESIO_GETBUFFER_METHODDEF \ - {"getbuffer", (PyCFunction)_io_BytesIO_getbuffer, METH_NOARGS, _io_BytesIO_getbuffer__doc__}, - -static PyObject * -_io_BytesIO_getbuffer_impl(bytesio *self); - -static PyObject * -_io_BytesIO_getbuffer(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_getbuffer_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO_getvalue__doc__, -"getvalue($self, /)\n" -"--\n" -"\n" -"Retrieve the entire contents of the BytesIO object."); - -#define _IO_BYTESIO_GETVALUE_METHODDEF \ - {"getvalue", (PyCFunction)_io_BytesIO_getvalue, METH_NOARGS, _io_BytesIO_getvalue__doc__}, - -static PyObject * -_io_BytesIO_getvalue_impl(bytesio *self); - -static PyObject * -_io_BytesIO_getvalue(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_getvalue_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO_isatty__doc__, -"isatty($self, /)\n" -"--\n" -"\n" -"Always returns False.\n" -"\n" -"BytesIO objects are not connected to a TTY-like device."); - -#define _IO_BYTESIO_ISATTY_METHODDEF \ - {"isatty", (PyCFunction)_io_BytesIO_isatty, METH_NOARGS, _io_BytesIO_isatty__doc__}, - -static PyObject * -_io_BytesIO_isatty_impl(bytesio *self); - -static PyObject * -_io_BytesIO_isatty(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_isatty_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO_tell__doc__, -"tell($self, /)\n" -"--\n" -"\n" -"Current file position, an integer."); - -#define _IO_BYTESIO_TELL_METHODDEF \ - {"tell", (PyCFunction)_io_BytesIO_tell, METH_NOARGS, _io_BytesIO_tell__doc__}, - -static PyObject * -_io_BytesIO_tell_impl(bytesio *self); - -static PyObject * -_io_BytesIO_tell(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_tell_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO_read__doc__, -"read($self, size=-1, /)\n" -"--\n" -"\n" -"Read at most size bytes, returned as a bytes object.\n" -"\n" -"If the size argument is negative, read until EOF is reached.\n" -"Return an empty bytes object at EOF."); - -#define _IO_BYTESIO_READ_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_io_BytesIO_readable__doc__, +"readable($self, /)\n" +"--\n" +"\n" +"Returns True if the IO object can be read."); + +#define _IO_BYTESIO_READABLE_METHODDEF \ + {"readable", (PyCFunction)_io_BytesIO_readable, METH_NOARGS, _io_BytesIO_readable__doc__}, + +static PyObject * +_io_BytesIO_readable_impl(bytesio *self); + +static PyObject * +_io_BytesIO_readable(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_readable_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO_writable__doc__, +"writable($self, /)\n" +"--\n" +"\n" +"Returns True if the IO object can be written."); + +#define _IO_BYTESIO_WRITABLE_METHODDEF \ + {"writable", (PyCFunction)_io_BytesIO_writable, METH_NOARGS, _io_BytesIO_writable__doc__}, + +static PyObject * +_io_BytesIO_writable_impl(bytesio *self); + +static PyObject * +_io_BytesIO_writable(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_writable_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO_seekable__doc__, +"seekable($self, /)\n" +"--\n" +"\n" +"Returns True if the IO object can be seeked."); + +#define _IO_BYTESIO_SEEKABLE_METHODDEF \ + {"seekable", (PyCFunction)_io_BytesIO_seekable, METH_NOARGS, _io_BytesIO_seekable__doc__}, + +static PyObject * +_io_BytesIO_seekable_impl(bytesio *self); + +static PyObject * +_io_BytesIO_seekable(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_seekable_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n" +"Does nothing."); + +#define _IO_BYTESIO_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_io_BytesIO_flush, METH_NOARGS, _io_BytesIO_flush__doc__}, + +static PyObject * +_io_BytesIO_flush_impl(bytesio *self); + +static PyObject * +_io_BytesIO_flush(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_flush_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO_getbuffer__doc__, +"getbuffer($self, /)\n" +"--\n" +"\n" +"Get a read-write view over the contents of the BytesIO object."); + +#define _IO_BYTESIO_GETBUFFER_METHODDEF \ + {"getbuffer", (PyCFunction)_io_BytesIO_getbuffer, METH_NOARGS, _io_BytesIO_getbuffer__doc__}, + +static PyObject * +_io_BytesIO_getbuffer_impl(bytesio *self); + +static PyObject * +_io_BytesIO_getbuffer(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_getbuffer_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO_getvalue__doc__, +"getvalue($self, /)\n" +"--\n" +"\n" +"Retrieve the entire contents of the BytesIO object."); + +#define _IO_BYTESIO_GETVALUE_METHODDEF \ + {"getvalue", (PyCFunction)_io_BytesIO_getvalue, METH_NOARGS, _io_BytesIO_getvalue__doc__}, + +static PyObject * +_io_BytesIO_getvalue_impl(bytesio *self); + +static PyObject * +_io_BytesIO_getvalue(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_getvalue_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO_isatty__doc__, +"isatty($self, /)\n" +"--\n" +"\n" +"Always returns False.\n" +"\n" +"BytesIO objects are not connected to a TTY-like device."); + +#define _IO_BYTESIO_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)_io_BytesIO_isatty, METH_NOARGS, _io_BytesIO_isatty__doc__}, + +static PyObject * +_io_BytesIO_isatty_impl(bytesio *self); + +static PyObject * +_io_BytesIO_isatty(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_isatty_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO_tell__doc__, +"tell($self, /)\n" +"--\n" +"\n" +"Current file position, an integer."); + +#define _IO_BYTESIO_TELL_METHODDEF \ + {"tell", (PyCFunction)_io_BytesIO_tell, METH_NOARGS, _io_BytesIO_tell__doc__}, + +static PyObject * +_io_BytesIO_tell_impl(bytesio *self); + +static PyObject * +_io_BytesIO_tell(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_tell_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n" +"Read at most size bytes, returned as a bytes object.\n" +"\n" +"If the size argument is negative, read until EOF is reached.\n" +"Return an empty bytes object at EOF."); + +#define _IO_BYTESIO_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_io_BytesIO_read, METH_FASTCALL, _io_BytesIO_read__doc__}, - -static PyObject * -_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size); - -static PyObject * -_io_BytesIO_read(bytesio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size); + +static PyObject * +_io_BytesIO_read(bytesio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -179,36 +179,36 @@ _io_BytesIO_read(bytesio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_BytesIO_read_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BytesIO_read1__doc__, -"read1($self, size=-1, /)\n" -"--\n" -"\n" -"Read at most size bytes, returned as a bytes object.\n" -"\n" -"If the size argument is negative or omitted, read until EOF is reached.\n" -"Return an empty bytes object at EOF."); - -#define _IO_BYTESIO_READ1_METHODDEF \ + return_value = _io_BytesIO_read_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BytesIO_read1__doc__, +"read1($self, size=-1, /)\n" +"--\n" +"\n" +"Read at most size bytes, returned as a bytes object.\n" +"\n" +"If the size argument is negative or omitted, read until EOF is reached.\n" +"Return an empty bytes object at EOF."); + +#define _IO_BYTESIO_READ1_METHODDEF \ {"read1", (PyCFunction)(void(*)(void))_io_BytesIO_read1, METH_FASTCALL, _io_BytesIO_read1__doc__}, - -static PyObject * -_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size); - -static PyObject * -_io_BytesIO_read1(bytesio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size); + +static PyObject * +_io_BytesIO_read1(bytesio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("read1", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -216,37 +216,37 @@ _io_BytesIO_read1(bytesio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_BytesIO_read1_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BytesIO_readline__doc__, -"readline($self, size=-1, /)\n" -"--\n" -"\n" -"Next line from the file, as a bytes object.\n" -"\n" -"Retain newline. A non-negative size argument limits the maximum\n" -"number of bytes to return (an incomplete line may be returned then).\n" -"Return an empty bytes object at EOF."); - -#define _IO_BYTESIO_READLINE_METHODDEF \ + return_value = _io_BytesIO_read1_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BytesIO_readline__doc__, +"readline($self, size=-1, /)\n" +"--\n" +"\n" +"Next line from the file, as a bytes object.\n" +"\n" +"Retain newline. A non-negative size argument limits the maximum\n" +"number of bytes to return (an incomplete line may be returned then).\n" +"Return an empty bytes object at EOF."); + +#define _IO_BYTESIO_READLINE_METHODDEF \ {"readline", (PyCFunction)(void(*)(void))_io_BytesIO_readline, METH_FASTCALL, _io_BytesIO_readline__doc__}, - -static PyObject * -_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size); - -static PyObject * -_io_BytesIO_readline(bytesio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size); + +static PyObject * +_io_BytesIO_readline(bytesio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -254,113 +254,113 @@ _io_BytesIO_readline(bytesio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_BytesIO_readline_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BytesIO_readlines__doc__, -"readlines($self, size=None, /)\n" -"--\n" -"\n" -"List of bytes objects, each a line from the file.\n" -"\n" -"Call readline() repeatedly and return a list of the lines so read.\n" -"The optional size argument, if given, is an approximate bound on the\n" -"total number of bytes in the lines returned."); - -#define _IO_BYTESIO_READLINES_METHODDEF \ + return_value = _io_BytesIO_readline_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BytesIO_readlines__doc__, +"readlines($self, size=None, /)\n" +"--\n" +"\n" +"List of bytes objects, each a line from the file.\n" +"\n" +"Call readline() repeatedly and return a list of the lines so read.\n" +"The optional size argument, if given, is an approximate bound on the\n" +"total number of bytes in the lines returned."); + +#define _IO_BYTESIO_READLINES_METHODDEF \ {"readlines", (PyCFunction)(void(*)(void))_io_BytesIO_readlines, METH_FASTCALL, _io_BytesIO_readlines__doc__}, - -static PyObject * -_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg); - -static PyObject * -_io_BytesIO_readlines(bytesio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *arg = Py_None; - + +static PyObject * +_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg); + +static PyObject * +_io_BytesIO_readlines(bytesio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *arg = Py_None; + if (!_PyArg_CheckPositional("readlines", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } arg = args[0]; skip_optional: - return_value = _io_BytesIO_readlines_impl(self, arg); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BytesIO_readinto__doc__, -"readinto($self, buffer, /)\n" -"--\n" -"\n" -"Read bytes into buffer.\n" -"\n" -"Returns number of bytes read (0 for EOF), or None if the object\n" -"is set not to block and has no data to read."); - -#define _IO_BYTESIO_READINTO_METHODDEF \ - {"readinto", (PyCFunction)_io_BytesIO_readinto, METH_O, _io_BytesIO_readinto__doc__}, - -static PyObject * -_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer); - -static PyObject * -_io_BytesIO_readinto(bytesio *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + return_value = _io_BytesIO_readlines_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BytesIO_readinto__doc__, +"readinto($self, buffer, /)\n" +"--\n" +"\n" +"Read bytes into buffer.\n" +"\n" +"Returns number of bytes read (0 for EOF), or None if the object\n" +"is set not to block and has no data to read."); + +#define _IO_BYTESIO_READINTO_METHODDEF \ + {"readinto", (PyCFunction)_io_BytesIO_readinto, METH_O, _io_BytesIO_readinto__doc__}, + +static PyObject * +_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer); + +static PyObject * +_io_BytesIO_readinto(bytesio *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io_BytesIO_readinto_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(_io_BytesIO_truncate__doc__, -"truncate($self, size=None, /)\n" -"--\n" -"\n" -"Truncate the file to at most size bytes.\n" -"\n" -"Size defaults to the current file position, as returned by tell().\n" -"The current file position is unchanged. Returns the new size."); - -#define _IO_BYTESIO_TRUNCATE_METHODDEF \ + return_value = _io_BytesIO_readinto_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(_io_BytesIO_truncate__doc__, +"truncate($self, size=None, /)\n" +"--\n" +"\n" +"Truncate the file to at most size bytes.\n" +"\n" +"Size defaults to the current file position, as returned by tell().\n" +"The current file position is unchanged. Returns the new size."); + +#define _IO_BYTESIO_TRUNCATE_METHODDEF \ {"truncate", (PyCFunction)(void(*)(void))_io_BytesIO_truncate, METH_FASTCALL, _io_BytesIO_truncate__doc__}, - -static PyObject * -_io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size); - -static PyObject * -_io_BytesIO_truncate(bytesio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = self->pos; - + +static PyObject * +_io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size); + +static PyObject * +_io_BytesIO_truncate(bytesio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = self->pos; + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -368,40 +368,40 @@ _io_BytesIO_truncate(bytesio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_BytesIO_truncate_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BytesIO_seek__doc__, -"seek($self, pos, whence=0, /)\n" -"--\n" -"\n" -"Change stream position.\n" -"\n" -"Seek to byte offset pos relative to position indicated by whence:\n" -" 0 Start of stream (the default). pos should be >= 0;\n" -" 1 Current position - pos may be negative;\n" -" 2 End of stream - pos usually negative.\n" -"Returns the new absolute position."); - -#define _IO_BYTESIO_SEEK_METHODDEF \ + return_value = _io_BytesIO_truncate_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BytesIO_seek__doc__, +"seek($self, pos, whence=0, /)\n" +"--\n" +"\n" +"Change stream position.\n" +"\n" +"Seek to byte offset pos relative to position indicated by whence:\n" +" 0 Start of stream (the default). pos should be >= 0;\n" +" 1 Current position - pos may be negative;\n" +" 2 End of stream - pos usually negative.\n" +"Returns the new absolute position."); + +#define _IO_BYTESIO_SEEK_METHODDEF \ {"seek", (PyCFunction)(void(*)(void))_io_BytesIO_seek, METH_FASTCALL, _io_BytesIO_seek__doc__}, - -static PyObject * -_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence); - -static PyObject * -_io_BytesIO_seek(bytesio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t pos; - int whence = 0; - + +static PyObject * +_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence); + +static PyObject * +_io_BytesIO_seek(bytesio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t pos; + int whence = 0; + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -432,87 +432,87 @@ _io_BytesIO_seek(bytesio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_BytesIO_seek_impl(self, pos, whence); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_BytesIO_write__doc__, -"write($self, b, /)\n" -"--\n" -"\n" -"Write bytes to file.\n" -"\n" -"Return the number of bytes written."); - -#define _IO_BYTESIO_WRITE_METHODDEF \ - {"write", (PyCFunction)_io_BytesIO_write, METH_O, _io_BytesIO_write__doc__}, - -PyDoc_STRVAR(_io_BytesIO_writelines__doc__, -"writelines($self, lines, /)\n" -"--\n" -"\n" -"Write lines to the file.\n" -"\n" -"Note that newlines are not added. lines can be any iterable object\n" -"producing bytes-like objects. This is equivalent to calling write() for\n" -"each element."); - -#define _IO_BYTESIO_WRITELINES_METHODDEF \ - {"writelines", (PyCFunction)_io_BytesIO_writelines, METH_O, _io_BytesIO_writelines__doc__}, - -PyDoc_STRVAR(_io_BytesIO_close__doc__, -"close($self, /)\n" -"--\n" -"\n" -"Disable all I/O operations."); - -#define _IO_BYTESIO_CLOSE_METHODDEF \ - {"close", (PyCFunction)_io_BytesIO_close, METH_NOARGS, _io_BytesIO_close__doc__}, - -static PyObject * -_io_BytesIO_close_impl(bytesio *self); - -static PyObject * -_io_BytesIO_close(bytesio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_BytesIO_close_impl(self); -} - -PyDoc_STRVAR(_io_BytesIO___init____doc__, -"BytesIO(initial_bytes=b\'\')\n" -"--\n" -"\n" -"Buffered I/O implementation using an in-memory bytes buffer."); - -static int -_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue); - -static int -_io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"initial_bytes", NULL}; + return_value = _io_BytesIO_seek_impl(self, pos, whence); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BytesIO_write__doc__, +"write($self, b, /)\n" +"--\n" +"\n" +"Write bytes to file.\n" +"\n" +"Return the number of bytes written."); + +#define _IO_BYTESIO_WRITE_METHODDEF \ + {"write", (PyCFunction)_io_BytesIO_write, METH_O, _io_BytesIO_write__doc__}, + +PyDoc_STRVAR(_io_BytesIO_writelines__doc__, +"writelines($self, lines, /)\n" +"--\n" +"\n" +"Write lines to the file.\n" +"\n" +"Note that newlines are not added. lines can be any iterable object\n" +"producing bytes-like objects. This is equivalent to calling write() for\n" +"each element."); + +#define _IO_BYTESIO_WRITELINES_METHODDEF \ + {"writelines", (PyCFunction)_io_BytesIO_writelines, METH_O, _io_BytesIO_writelines__doc__}, + +PyDoc_STRVAR(_io_BytesIO_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Disable all I/O operations."); + +#define _IO_BYTESIO_CLOSE_METHODDEF \ + {"close", (PyCFunction)_io_BytesIO_close, METH_NOARGS, _io_BytesIO_close__doc__}, + +static PyObject * +_io_BytesIO_close_impl(bytesio *self); + +static PyObject * +_io_BytesIO_close(bytesio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_BytesIO_close_impl(self); +} + +PyDoc_STRVAR(_io_BytesIO___init____doc__, +"BytesIO(initial_bytes=b\'\')\n" +"--\n" +"\n" +"Buffered I/O implementation using an in-memory bytes buffer."); + +static int +_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue); + +static int +_io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"initial_bytes", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "BytesIO", 0}; PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *initvalue = NULL; - + PyObject *initvalue = NULL; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } initvalue = fastargs[0]; skip_optional_pos: - return_value = _io_BytesIO___init___impl((bytesio *)self, initvalue); - -exit: - return return_value; -} + return_value = _io_BytesIO___init___impl((bytesio *)self, initvalue); + +exit: + return return_value; +} /*[clinic end generated code: output=4ec2506def9c8eb9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/fileio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/fileio.c.h index 53e7067cf7a..2b8819bc882 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/fileio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/fileio.c.h @@ -1,69 +1,69 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_io_FileIO_close__doc__, -"close($self, /)\n" -"--\n" -"\n" -"Close the file.\n" -"\n" -"A closed file cannot be used for further I/O operations. close() may be\n" -"called more than once without error."); - -#define _IO_FILEIO_CLOSE_METHODDEF \ - {"close", (PyCFunction)_io_FileIO_close, METH_NOARGS, _io_FileIO_close__doc__}, - -static PyObject * -_io_FileIO_close_impl(fileio *self); - -static PyObject * -_io_FileIO_close(fileio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_FileIO_close_impl(self); -} - -PyDoc_STRVAR(_io_FileIO___init____doc__, -"FileIO(file, mode=\'r\', closefd=True, opener=None)\n" -"--\n" -"\n" -"Open a file.\n" -"\n" -"The mode can be \'r\' (default), \'w\', \'x\' or \'a\' for reading,\n" -"writing, exclusive creation or appending. The file will be created if it\n" -"doesn\'t exist when opened for writing or appending; it will be truncated\n" -"when opened for writing. A FileExistsError will be raised if it already\n" -"exists when opened for creating. Opening a file for creating implies\n" -"writing so this mode behaves in a similar way to \'w\'.Add a \'+\' to the mode\n" -"to allow simultaneous reading and writing. A custom opener can be used by\n" -"passing a callable as *opener*. The underlying file descriptor for the file\n" -"object is then obtained by calling opener with (*name*, *flags*).\n" -"*opener* must return an open file descriptor (passing os.open as *opener*\n" -"results in functionality similar to passing None)."); - -static int -_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, - int closefd, PyObject *opener); - -static int -_io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_io_FileIO_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the file.\n" +"\n" +"A closed file cannot be used for further I/O operations. close() may be\n" +"called more than once without error."); + +#define _IO_FILEIO_CLOSE_METHODDEF \ + {"close", (PyCFunction)_io_FileIO_close, METH_NOARGS, _io_FileIO_close__doc__}, + +static PyObject * +_io_FileIO_close_impl(fileio *self); + +static PyObject * +_io_FileIO_close(fileio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_FileIO_close_impl(self); +} + +PyDoc_STRVAR(_io_FileIO___init____doc__, +"FileIO(file, mode=\'r\', closefd=True, opener=None)\n" +"--\n" +"\n" +"Open a file.\n" +"\n" +"The mode can be \'r\' (default), \'w\', \'x\' or \'a\' for reading,\n" +"writing, exclusive creation or appending. The file will be created if it\n" +"doesn\'t exist when opened for writing or appending; it will be truncated\n" +"when opened for writing. A FileExistsError will be raised if it already\n" +"exists when opened for creating. Opening a file for creating implies\n" +"writing so this mode behaves in a similar way to \'w\'.Add a \'+\' to the mode\n" +"to allow simultaneous reading and writing. A custom opener can be used by\n" +"passing a callable as *opener*. The underlying file descriptor for the file\n" +"object is then obtained by calling opener with (*name*, *flags*).\n" +"*opener* must return an open file descriptor (passing os.open as *opener*\n" +"results in functionality similar to passing None)."); + +static int +_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, + int closefd, PyObject *opener); + +static int +_io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "FileIO", 0}; PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *nameobj; - const char *mode = "r"; - int closefd = 1; - PyObject *opener = Py_None; - + PyObject *nameobj; + const char *mode = "r"; + int closefd = 1; + PyObject *opener = Py_None; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 4, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } nameobj = fastargs[0]; if (!noptargs) { goto skip_optional_pos; @@ -102,168 +102,168 @@ _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } opener = fastargs[3]; skip_optional_pos: - return_value = _io_FileIO___init___impl((fileio *)self, nameobj, mode, closefd, opener); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_FileIO_fileno__doc__, -"fileno($self, /)\n" -"--\n" -"\n" -"Return the underlying file descriptor (an integer)."); - -#define _IO_FILEIO_FILENO_METHODDEF \ - {"fileno", (PyCFunction)_io_FileIO_fileno, METH_NOARGS, _io_FileIO_fileno__doc__}, - -static PyObject * -_io_FileIO_fileno_impl(fileio *self); - -static PyObject * -_io_FileIO_fileno(fileio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_FileIO_fileno_impl(self); -} - -PyDoc_STRVAR(_io_FileIO_readable__doc__, -"readable($self, /)\n" -"--\n" -"\n" -"True if file was opened in a read mode."); - -#define _IO_FILEIO_READABLE_METHODDEF \ - {"readable", (PyCFunction)_io_FileIO_readable, METH_NOARGS, _io_FileIO_readable__doc__}, - -static PyObject * -_io_FileIO_readable_impl(fileio *self); - -static PyObject * -_io_FileIO_readable(fileio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_FileIO_readable_impl(self); -} - -PyDoc_STRVAR(_io_FileIO_writable__doc__, -"writable($self, /)\n" -"--\n" -"\n" -"True if file was opened in a write mode."); - -#define _IO_FILEIO_WRITABLE_METHODDEF \ - {"writable", (PyCFunction)_io_FileIO_writable, METH_NOARGS, _io_FileIO_writable__doc__}, - -static PyObject * -_io_FileIO_writable_impl(fileio *self); - -static PyObject * -_io_FileIO_writable(fileio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_FileIO_writable_impl(self); -} - -PyDoc_STRVAR(_io_FileIO_seekable__doc__, -"seekable($self, /)\n" -"--\n" -"\n" -"True if file supports random-access."); - -#define _IO_FILEIO_SEEKABLE_METHODDEF \ - {"seekable", (PyCFunction)_io_FileIO_seekable, METH_NOARGS, _io_FileIO_seekable__doc__}, - -static PyObject * -_io_FileIO_seekable_impl(fileio *self); - -static PyObject * -_io_FileIO_seekable(fileio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_FileIO_seekable_impl(self); -} - -PyDoc_STRVAR(_io_FileIO_readinto__doc__, -"readinto($self, buffer, /)\n" -"--\n" -"\n" -"Same as RawIOBase.readinto()."); - -#define _IO_FILEIO_READINTO_METHODDEF \ - {"readinto", (PyCFunction)_io_FileIO_readinto, METH_O, _io_FileIO_readinto__doc__}, - -static PyObject * -_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer); - -static PyObject * -_io_FileIO_readinto(fileio *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + return_value = _io_FileIO___init___impl((fileio *)self, nameobj, mode, closefd, opener); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_FileIO_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the underlying file descriptor (an integer)."); + +#define _IO_FILEIO_FILENO_METHODDEF \ + {"fileno", (PyCFunction)_io_FileIO_fileno, METH_NOARGS, _io_FileIO_fileno__doc__}, + +static PyObject * +_io_FileIO_fileno_impl(fileio *self); + +static PyObject * +_io_FileIO_fileno(fileio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_FileIO_fileno_impl(self); +} + +PyDoc_STRVAR(_io_FileIO_readable__doc__, +"readable($self, /)\n" +"--\n" +"\n" +"True if file was opened in a read mode."); + +#define _IO_FILEIO_READABLE_METHODDEF \ + {"readable", (PyCFunction)_io_FileIO_readable, METH_NOARGS, _io_FileIO_readable__doc__}, + +static PyObject * +_io_FileIO_readable_impl(fileio *self); + +static PyObject * +_io_FileIO_readable(fileio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_FileIO_readable_impl(self); +} + +PyDoc_STRVAR(_io_FileIO_writable__doc__, +"writable($self, /)\n" +"--\n" +"\n" +"True if file was opened in a write mode."); + +#define _IO_FILEIO_WRITABLE_METHODDEF \ + {"writable", (PyCFunction)_io_FileIO_writable, METH_NOARGS, _io_FileIO_writable__doc__}, + +static PyObject * +_io_FileIO_writable_impl(fileio *self); + +static PyObject * +_io_FileIO_writable(fileio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_FileIO_writable_impl(self); +} + +PyDoc_STRVAR(_io_FileIO_seekable__doc__, +"seekable($self, /)\n" +"--\n" +"\n" +"True if file supports random-access."); + +#define _IO_FILEIO_SEEKABLE_METHODDEF \ + {"seekable", (PyCFunction)_io_FileIO_seekable, METH_NOARGS, _io_FileIO_seekable__doc__}, + +static PyObject * +_io_FileIO_seekable_impl(fileio *self); + +static PyObject * +_io_FileIO_seekable(fileio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_FileIO_seekable_impl(self); +} + +PyDoc_STRVAR(_io_FileIO_readinto__doc__, +"readinto($self, buffer, /)\n" +"--\n" +"\n" +"Same as RawIOBase.readinto()."); + +#define _IO_FILEIO_READINTO_METHODDEF \ + {"readinto", (PyCFunction)_io_FileIO_readinto, METH_O, _io_FileIO_readinto__doc__}, + +static PyObject * +_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer); + +static PyObject * +_io_FileIO_readinto(fileio *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io_FileIO_readinto_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(_io_FileIO_readall__doc__, -"readall($self, /)\n" -"--\n" -"\n" -"Read all data from the file, returned as bytes.\n" -"\n" -"In non-blocking mode, returns as much as is immediately available,\n" -"or None if no data is available. Return an empty bytes object at EOF."); - -#define _IO_FILEIO_READALL_METHODDEF \ - {"readall", (PyCFunction)_io_FileIO_readall, METH_NOARGS, _io_FileIO_readall__doc__}, - -static PyObject * -_io_FileIO_readall_impl(fileio *self); - -static PyObject * -_io_FileIO_readall(fileio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_FileIO_readall_impl(self); -} - -PyDoc_STRVAR(_io_FileIO_read__doc__, -"read($self, size=-1, /)\n" -"--\n" -"\n" -"Read at most size bytes, returned as bytes.\n" -"\n" -"Only makes one system call, so less data may be returned than requested.\n" -"In non-blocking mode, returns None if no data is available.\n" -"Return an empty bytes object at EOF."); - -#define _IO_FILEIO_READ_METHODDEF \ + return_value = _io_FileIO_readinto_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(_io_FileIO_readall__doc__, +"readall($self, /)\n" +"--\n" +"\n" +"Read all data from the file, returned as bytes.\n" +"\n" +"In non-blocking mode, returns as much as is immediately available,\n" +"or None if no data is available. Return an empty bytes object at EOF."); + +#define _IO_FILEIO_READALL_METHODDEF \ + {"readall", (PyCFunction)_io_FileIO_readall, METH_NOARGS, _io_FileIO_readall__doc__}, + +static PyObject * +_io_FileIO_readall_impl(fileio *self); + +static PyObject * +_io_FileIO_readall(fileio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_FileIO_readall_impl(self); +} + +PyDoc_STRVAR(_io_FileIO_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n" +"Read at most size bytes, returned as bytes.\n" +"\n" +"Only makes one system call, so less data may be returned than requested.\n" +"In non-blocking mode, returns None if no data is available.\n" +"Return an empty bytes object at EOF."); + +#define _IO_FILEIO_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_io_FileIO_read, METH_FASTCALL, _io_FileIO_read__doc__}, - -static PyObject * -_io_FileIO_read_impl(fileio *self, Py_ssize_t size); - -static PyObject * -_io_FileIO_read(fileio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io_FileIO_read_impl(fileio *self, Py_ssize_t size); + +static PyObject * +_io_FileIO_read(fileio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -271,82 +271,82 @@ _io_FileIO_read(fileio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_FileIO_read_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_FileIO_write__doc__, -"write($self, b, /)\n" -"--\n" -"\n" -"Write buffer b to file, return number of bytes written.\n" -"\n" -"Only makes one system call, so not all of the data may be written.\n" -"The number of bytes actually written is returned. In non-blocking mode,\n" -"returns None if the write would block."); - -#define _IO_FILEIO_WRITE_METHODDEF \ - {"write", (PyCFunction)_io_FileIO_write, METH_O, _io_FileIO_write__doc__}, - -static PyObject * -_io_FileIO_write_impl(fileio *self, Py_buffer *b); - -static PyObject * -_io_FileIO_write(fileio *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer b = {NULL, NULL}; - + return_value = _io_FileIO_read_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_FileIO_write__doc__, +"write($self, b, /)\n" +"--\n" +"\n" +"Write buffer b to file, return number of bytes written.\n" +"\n" +"Only makes one system call, so not all of the data may be written.\n" +"The number of bytes actually written is returned. In non-blocking mode,\n" +"returns None if the write would block."); + +#define _IO_FILEIO_WRITE_METHODDEF \ + {"write", (PyCFunction)_io_FileIO_write, METH_O, _io_FileIO_write__doc__}, + +static PyObject * +_io_FileIO_write_impl(fileio *self, Py_buffer *b); + +static PyObject * +_io_FileIO_write(fileio *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer b = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&b, 'C')) { _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io_FileIO_write_impl(self, &b); - -exit: - /* Cleanup for b */ - if (b.obj) { - PyBuffer_Release(&b); - } - - return return_value; -} - -PyDoc_STRVAR(_io_FileIO_seek__doc__, -"seek($self, pos, whence=0, /)\n" -"--\n" -"\n" -"Move to new file position and return the file position.\n" -"\n" -"Argument offset is a byte count. Optional argument whence defaults to\n" -"SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values\n" -"are SEEK_CUR or 1 (move relative to current position, positive or negative),\n" -"and SEEK_END or 2 (move relative to end of file, usually negative, although\n" -"many platforms allow seeking beyond the end of a file).\n" -"\n" -"Note that not all file objects are seekable."); - -#define _IO_FILEIO_SEEK_METHODDEF \ + return_value = _io_FileIO_write_impl(self, &b); + +exit: + /* Cleanup for b */ + if (b.obj) { + PyBuffer_Release(&b); + } + + return return_value; +} + +PyDoc_STRVAR(_io_FileIO_seek__doc__, +"seek($self, pos, whence=0, /)\n" +"--\n" +"\n" +"Move to new file position and return the file position.\n" +"\n" +"Argument offset is a byte count. Optional argument whence defaults to\n" +"SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values\n" +"are SEEK_CUR or 1 (move relative to current position, positive or negative),\n" +"and SEEK_END or 2 (move relative to end of file, usually negative, although\n" +"many platforms allow seeking beyond the end of a file).\n" +"\n" +"Note that not all file objects are seekable."); + +#define _IO_FILEIO_SEEK_METHODDEF \ {"seek", (PyCFunction)(void(*)(void))_io_FileIO_seek, METH_FASTCALL, _io_FileIO_seek__doc__}, - -static PyObject * -_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence); - -static PyObject * -_io_FileIO_seek(fileio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *pos; - int whence = 0; - + +static PyObject * +_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence); + +static PyObject * +_io_FileIO_seek(fileio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *pos; + int whence = 0; + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { - goto exit; - } + goto exit; + } pos = args[0]; if (nargs < 2) { goto skip_optional; @@ -361,90 +361,90 @@ _io_FileIO_seek(fileio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_FileIO_seek_impl(self, pos, whence); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_FileIO_tell__doc__, -"tell($self, /)\n" -"--\n" -"\n" -"Current file position.\n" -"\n" -"Can raise OSError for non seekable files."); - -#define _IO_FILEIO_TELL_METHODDEF \ - {"tell", (PyCFunction)_io_FileIO_tell, METH_NOARGS, _io_FileIO_tell__doc__}, - -static PyObject * -_io_FileIO_tell_impl(fileio *self); - -static PyObject * -_io_FileIO_tell(fileio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_FileIO_tell_impl(self); -} - -#if defined(HAVE_FTRUNCATE) - -PyDoc_STRVAR(_io_FileIO_truncate__doc__, -"truncate($self, size=None, /)\n" -"--\n" -"\n" -"Truncate the file to at most size bytes and return the truncated size.\n" -"\n" -"Size defaults to the current file position, as returned by tell().\n" -"The current file position is changed to the value of size."); - -#define _IO_FILEIO_TRUNCATE_METHODDEF \ + return_value = _io_FileIO_seek_impl(self, pos, whence); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_FileIO_tell__doc__, +"tell($self, /)\n" +"--\n" +"\n" +"Current file position.\n" +"\n" +"Can raise OSError for non seekable files."); + +#define _IO_FILEIO_TELL_METHODDEF \ + {"tell", (PyCFunction)_io_FileIO_tell, METH_NOARGS, _io_FileIO_tell__doc__}, + +static PyObject * +_io_FileIO_tell_impl(fileio *self); + +static PyObject * +_io_FileIO_tell(fileio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_FileIO_tell_impl(self); +} + +#if defined(HAVE_FTRUNCATE) + +PyDoc_STRVAR(_io_FileIO_truncate__doc__, +"truncate($self, size=None, /)\n" +"--\n" +"\n" +"Truncate the file to at most size bytes and return the truncated size.\n" +"\n" +"Size defaults to the current file position, as returned by tell().\n" +"The current file position is changed to the value of size."); + +#define _IO_FILEIO_TRUNCATE_METHODDEF \ {"truncate", (PyCFunction)(void(*)(void))_io_FileIO_truncate, METH_FASTCALL, _io_FileIO_truncate__doc__}, - -static PyObject * -_io_FileIO_truncate_impl(fileio *self, PyObject *posobj); - -static PyObject * -_io_FileIO_truncate(fileio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; + +static PyObject * +_io_FileIO_truncate_impl(fileio *self, PyObject *posobj); + +static PyObject * +_io_FileIO_truncate(fileio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; PyObject *posobj = Py_None; - + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } posobj = args[0]; skip_optional: - return_value = _io_FileIO_truncate_impl(self, posobj); - -exit: - return return_value; -} - -#endif /* defined(HAVE_FTRUNCATE) */ - -PyDoc_STRVAR(_io_FileIO_isatty__doc__, -"isatty($self, /)\n" -"--\n" -"\n" -"True if the file is connected to a TTY device."); - -#define _IO_FILEIO_ISATTY_METHODDEF \ - {"isatty", (PyCFunction)_io_FileIO_isatty, METH_NOARGS, _io_FileIO_isatty__doc__}, - -static PyObject * -_io_FileIO_isatty_impl(fileio *self); - -static PyObject * -_io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_FileIO_isatty_impl(self); -} - -#ifndef _IO_FILEIO_TRUNCATE_METHODDEF - #define _IO_FILEIO_TRUNCATE_METHODDEF -#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ + return_value = _io_FileIO_truncate_impl(self, posobj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_FTRUNCATE) */ + +PyDoc_STRVAR(_io_FileIO_isatty__doc__, +"isatty($self, /)\n" +"--\n" +"\n" +"True if the file is connected to a TTY device."); + +#define _IO_FILEIO_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)_io_FileIO_isatty, METH_NOARGS, _io_FileIO_isatty__doc__}, + +static PyObject * +_io_FileIO_isatty_impl(fileio *self); + +static PyObject * +_io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_FileIO_isatty_impl(self); +} + +#ifndef _IO_FILEIO_TRUNCATE_METHODDEF + #define _IO_FILEIO_TRUNCATE_METHODDEF +#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ /*[clinic end generated code: output=e7682d0a3264d284 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/iobase.c.h b/contrib/tools/python3/src/Modules/_io/clinic/iobase.c.h index ddaff7b5d13..65c92043cfa 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/iobase.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/iobase.c.h @@ -1,193 +1,193 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_io__IOBase_tell__doc__, -"tell($self, /)\n" -"--\n" -"\n" -"Return current stream position."); - -#define _IO__IOBASE_TELL_METHODDEF \ - {"tell", (PyCFunction)_io__IOBase_tell, METH_NOARGS, _io__IOBase_tell__doc__}, - -static PyObject * -_io__IOBase_tell_impl(PyObject *self); - -static PyObject * -_io__IOBase_tell(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__IOBase_tell_impl(self); -} - -PyDoc_STRVAR(_io__IOBase_flush__doc__, -"flush($self, /)\n" -"--\n" -"\n" -"Flush write buffers, if applicable.\n" -"\n" -"This is not implemented for read-only and non-blocking streams."); - -#define _IO__IOBASE_FLUSH_METHODDEF \ - {"flush", (PyCFunction)_io__IOBase_flush, METH_NOARGS, _io__IOBase_flush__doc__}, - -static PyObject * -_io__IOBase_flush_impl(PyObject *self); - -static PyObject * -_io__IOBase_flush(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__IOBase_flush_impl(self); -} - -PyDoc_STRVAR(_io__IOBase_close__doc__, -"close($self, /)\n" -"--\n" -"\n" -"Flush and close the IO object.\n" -"\n" -"This method has no effect if the file is already closed."); - -#define _IO__IOBASE_CLOSE_METHODDEF \ - {"close", (PyCFunction)_io__IOBase_close, METH_NOARGS, _io__IOBase_close__doc__}, - -static PyObject * -_io__IOBase_close_impl(PyObject *self); - -static PyObject * -_io__IOBase_close(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__IOBase_close_impl(self); -} - -PyDoc_STRVAR(_io__IOBase_seekable__doc__, -"seekable($self, /)\n" -"--\n" -"\n" -"Return whether object supports random access.\n" -"\n" -"If False, seek(), tell() and truncate() will raise OSError.\n" -"This method may need to do a test seek()."); - -#define _IO__IOBASE_SEEKABLE_METHODDEF \ - {"seekable", (PyCFunction)_io__IOBase_seekable, METH_NOARGS, _io__IOBase_seekable__doc__}, - -static PyObject * -_io__IOBase_seekable_impl(PyObject *self); - -static PyObject * -_io__IOBase_seekable(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__IOBase_seekable_impl(self); -} - -PyDoc_STRVAR(_io__IOBase_readable__doc__, -"readable($self, /)\n" -"--\n" -"\n" -"Return whether object was opened for reading.\n" -"\n" -"If False, read() will raise OSError."); - -#define _IO__IOBASE_READABLE_METHODDEF \ - {"readable", (PyCFunction)_io__IOBase_readable, METH_NOARGS, _io__IOBase_readable__doc__}, - -static PyObject * -_io__IOBase_readable_impl(PyObject *self); - -static PyObject * -_io__IOBase_readable(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__IOBase_readable_impl(self); -} - -PyDoc_STRVAR(_io__IOBase_writable__doc__, -"writable($self, /)\n" -"--\n" -"\n" -"Return whether object was opened for writing.\n" -"\n" -"If False, write() will raise OSError."); - -#define _IO__IOBASE_WRITABLE_METHODDEF \ - {"writable", (PyCFunction)_io__IOBase_writable, METH_NOARGS, _io__IOBase_writable__doc__}, - -static PyObject * -_io__IOBase_writable_impl(PyObject *self); - -static PyObject * -_io__IOBase_writable(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__IOBase_writable_impl(self); -} - -PyDoc_STRVAR(_io__IOBase_fileno__doc__, -"fileno($self, /)\n" -"--\n" -"\n" -"Returns underlying file descriptor if one exists.\n" -"\n" -"OSError is raised if the IO object does not use a file descriptor."); - -#define _IO__IOBASE_FILENO_METHODDEF \ - {"fileno", (PyCFunction)_io__IOBase_fileno, METH_NOARGS, _io__IOBase_fileno__doc__}, - -static PyObject * -_io__IOBase_fileno_impl(PyObject *self); - -static PyObject * -_io__IOBase_fileno(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__IOBase_fileno_impl(self); -} - -PyDoc_STRVAR(_io__IOBase_isatty__doc__, -"isatty($self, /)\n" -"--\n" -"\n" -"Return whether this is an \'interactive\' stream.\n" -"\n" -"Return False if it can\'t be determined."); - -#define _IO__IOBASE_ISATTY_METHODDEF \ - {"isatty", (PyCFunction)_io__IOBase_isatty, METH_NOARGS, _io__IOBase_isatty__doc__}, - -static PyObject * -_io__IOBase_isatty_impl(PyObject *self); - -static PyObject * -_io__IOBase_isatty(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__IOBase_isatty_impl(self); -} - -PyDoc_STRVAR(_io__IOBase_readline__doc__, -"readline($self, size=-1, /)\n" -"--\n" -"\n" -"Read and return a line from the stream.\n" -"\n" -"If size is specified, at most size bytes will be read.\n" -"\n" -"The line terminator is always b\'\\n\' for binary files; for text\n" -"files, the newlines argument to open can be used to select the line\n" -"terminator(s) recognized."); - -#define _IO__IOBASE_READLINE_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_io__IOBase_tell__doc__, +"tell($self, /)\n" +"--\n" +"\n" +"Return current stream position."); + +#define _IO__IOBASE_TELL_METHODDEF \ + {"tell", (PyCFunction)_io__IOBase_tell, METH_NOARGS, _io__IOBase_tell__doc__}, + +static PyObject * +_io__IOBase_tell_impl(PyObject *self); + +static PyObject * +_io__IOBase_tell(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__IOBase_tell_impl(self); +} + +PyDoc_STRVAR(_io__IOBase_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n" +"Flush write buffers, if applicable.\n" +"\n" +"This is not implemented for read-only and non-blocking streams."); + +#define _IO__IOBASE_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_io__IOBase_flush, METH_NOARGS, _io__IOBase_flush__doc__}, + +static PyObject * +_io__IOBase_flush_impl(PyObject *self); + +static PyObject * +_io__IOBase_flush(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__IOBase_flush_impl(self); +} + +PyDoc_STRVAR(_io__IOBase_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Flush and close the IO object.\n" +"\n" +"This method has no effect if the file is already closed."); + +#define _IO__IOBASE_CLOSE_METHODDEF \ + {"close", (PyCFunction)_io__IOBase_close, METH_NOARGS, _io__IOBase_close__doc__}, + +static PyObject * +_io__IOBase_close_impl(PyObject *self); + +static PyObject * +_io__IOBase_close(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__IOBase_close_impl(self); +} + +PyDoc_STRVAR(_io__IOBase_seekable__doc__, +"seekable($self, /)\n" +"--\n" +"\n" +"Return whether object supports random access.\n" +"\n" +"If False, seek(), tell() and truncate() will raise OSError.\n" +"This method may need to do a test seek()."); + +#define _IO__IOBASE_SEEKABLE_METHODDEF \ + {"seekable", (PyCFunction)_io__IOBase_seekable, METH_NOARGS, _io__IOBase_seekable__doc__}, + +static PyObject * +_io__IOBase_seekable_impl(PyObject *self); + +static PyObject * +_io__IOBase_seekable(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__IOBase_seekable_impl(self); +} + +PyDoc_STRVAR(_io__IOBase_readable__doc__, +"readable($self, /)\n" +"--\n" +"\n" +"Return whether object was opened for reading.\n" +"\n" +"If False, read() will raise OSError."); + +#define _IO__IOBASE_READABLE_METHODDEF \ + {"readable", (PyCFunction)_io__IOBase_readable, METH_NOARGS, _io__IOBase_readable__doc__}, + +static PyObject * +_io__IOBase_readable_impl(PyObject *self); + +static PyObject * +_io__IOBase_readable(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__IOBase_readable_impl(self); +} + +PyDoc_STRVAR(_io__IOBase_writable__doc__, +"writable($self, /)\n" +"--\n" +"\n" +"Return whether object was opened for writing.\n" +"\n" +"If False, write() will raise OSError."); + +#define _IO__IOBASE_WRITABLE_METHODDEF \ + {"writable", (PyCFunction)_io__IOBase_writable, METH_NOARGS, _io__IOBase_writable__doc__}, + +static PyObject * +_io__IOBase_writable_impl(PyObject *self); + +static PyObject * +_io__IOBase_writable(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__IOBase_writable_impl(self); +} + +PyDoc_STRVAR(_io__IOBase_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Returns underlying file descriptor if one exists.\n" +"\n" +"OSError is raised if the IO object does not use a file descriptor."); + +#define _IO__IOBASE_FILENO_METHODDEF \ + {"fileno", (PyCFunction)_io__IOBase_fileno, METH_NOARGS, _io__IOBase_fileno__doc__}, + +static PyObject * +_io__IOBase_fileno_impl(PyObject *self); + +static PyObject * +_io__IOBase_fileno(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__IOBase_fileno_impl(self); +} + +PyDoc_STRVAR(_io__IOBase_isatty__doc__, +"isatty($self, /)\n" +"--\n" +"\n" +"Return whether this is an \'interactive\' stream.\n" +"\n" +"Return False if it can\'t be determined."); + +#define _IO__IOBASE_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)_io__IOBase_isatty, METH_NOARGS, _io__IOBase_isatty__doc__}, + +static PyObject * +_io__IOBase_isatty_impl(PyObject *self); + +static PyObject * +_io__IOBase_isatty(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__IOBase_isatty_impl(self); +} + +PyDoc_STRVAR(_io__IOBase_readline__doc__, +"readline($self, size=-1, /)\n" +"--\n" +"\n" +"Read and return a line from the stream.\n" +"\n" +"If size is specified, at most size bytes will be read.\n" +"\n" +"The line terminator is always b\'\\n\' for binary files; for text\n" +"files, the newlines argument to open can be used to select the line\n" +"terminator(s) recognized."); + +#define _IO__IOBASE_READLINE_METHODDEF \ {"readline", (PyCFunction)(void(*)(void))_io__IOBase_readline, METH_FASTCALL, _io__IOBase_readline__doc__}, - -static PyObject * -_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit); - -static PyObject * -_io__IOBase_readline(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t limit = -1; - + +static PyObject * +_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit); + +static PyObject * +_io__IOBase_readline(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t limit = -1; + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -195,37 +195,37 @@ _io__IOBase_readline(PyObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io__IOBase_readline_impl(self, limit); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io__IOBase_readlines__doc__, -"readlines($self, hint=-1, /)\n" -"--\n" -"\n" -"Return a list of lines from the stream.\n" -"\n" -"hint can be specified to control the number of lines read: no more\n" -"lines will be read if the total size (in bytes/characters) of all\n" -"lines so far exceeds hint."); - -#define _IO__IOBASE_READLINES_METHODDEF \ + return_value = _io__IOBase_readline_impl(self, limit); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__IOBase_readlines__doc__, +"readlines($self, hint=-1, /)\n" +"--\n" +"\n" +"Return a list of lines from the stream.\n" +"\n" +"hint can be specified to control the number of lines read: no more\n" +"lines will be read if the total size (in bytes/characters) of all\n" +"lines so far exceeds hint."); + +#define _IO__IOBASE_READLINES_METHODDEF \ {"readlines", (PyCFunction)(void(*)(void))_io__IOBase_readlines, METH_FASTCALL, _io__IOBase_readlines__doc__}, - -static PyObject * -_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint); - -static PyObject * -_io__IOBase_readlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t hint = -1; - + +static PyObject * +_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint); + +static PyObject * +_io__IOBase_readlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t hint = -1; + if (!_PyArg_CheckPositional("readlines", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -233,44 +233,44 @@ _io__IOBase_readlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io__IOBase_readlines_impl(self, hint); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io__IOBase_writelines__doc__, -"writelines($self, lines, /)\n" -"--\n" + return_value = _io__IOBase_readlines_impl(self, hint); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__IOBase_writelines__doc__, +"writelines($self, lines, /)\n" +"--\n" "\n" "Write a list of lines to stream.\n" "\n" "Line separators are not added, so it is usual for each of the\n" "lines provided to have a line separator at the end."); - -#define _IO__IOBASE_WRITELINES_METHODDEF \ - {"writelines", (PyCFunction)_io__IOBase_writelines, METH_O, _io__IOBase_writelines__doc__}, - -PyDoc_STRVAR(_io__RawIOBase_read__doc__, -"read($self, size=-1, /)\n" -"--\n" -"\n"); - -#define _IO__RAWIOBASE_READ_METHODDEF \ + +#define _IO__IOBASE_WRITELINES_METHODDEF \ + {"writelines", (PyCFunction)_io__IOBase_writelines, METH_O, _io__IOBase_writelines__doc__}, + +PyDoc_STRVAR(_io__RawIOBase_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n"); + +#define _IO__RAWIOBASE_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_io__RawIOBase_read, METH_FASTCALL, _io__RawIOBase_read__doc__}, - -static PyObject * -_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n); - -static PyObject * -_io__RawIOBase_read(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t n = -1; - + +static PyObject * +_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n); + +static PyObject * +_io__RawIOBase_read(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t n = -1; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -292,27 +292,27 @@ _io__RawIOBase_read(PyObject *self, PyObject *const *args, Py_ssize_t nargs) n = ival; } skip_optional: - return_value = _io__RawIOBase_read_impl(self, n); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io__RawIOBase_readall__doc__, -"readall($self, /)\n" -"--\n" -"\n" -"Read until EOF, using multiple read() call."); - -#define _IO__RAWIOBASE_READALL_METHODDEF \ - {"readall", (PyCFunction)_io__RawIOBase_readall, METH_NOARGS, _io__RawIOBase_readall__doc__}, - -static PyObject * -_io__RawIOBase_readall_impl(PyObject *self); - -static PyObject * -_io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__RawIOBase_readall_impl(self); -} + return_value = _io__RawIOBase_read_impl(self, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__RawIOBase_readall__doc__, +"readall($self, /)\n" +"--\n" +"\n" +"Read until EOF, using multiple read() call."); + +#define _IO__RAWIOBASE_READALL_METHODDEF \ + {"readall", (PyCFunction)_io__RawIOBase_readall, METH_NOARGS, _io__RawIOBase_readall__doc__}, + +static PyObject * +_io__RawIOBase_readall_impl(PyObject *self); + +static PyObject * +_io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__RawIOBase_readall_impl(self); +} /*[clinic end generated code: output=61b6ea7153ef9940 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/stringio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/stringio.c.h index 77a720c2a6f..14d6cd6423c 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/stringio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/stringio.c.h @@ -1,67 +1,67 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_io_StringIO_getvalue__doc__, -"getvalue($self, /)\n" -"--\n" -"\n" -"Retrieve the entire contents of the object."); - -#define _IO_STRINGIO_GETVALUE_METHODDEF \ - {"getvalue", (PyCFunction)_io_StringIO_getvalue, METH_NOARGS, _io_StringIO_getvalue__doc__}, - -static PyObject * -_io_StringIO_getvalue_impl(stringio *self); - -static PyObject * -_io_StringIO_getvalue(stringio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_StringIO_getvalue_impl(self); -} - -PyDoc_STRVAR(_io_StringIO_tell__doc__, -"tell($self, /)\n" -"--\n" -"\n" -"Tell the current file position."); - -#define _IO_STRINGIO_TELL_METHODDEF \ - {"tell", (PyCFunction)_io_StringIO_tell, METH_NOARGS, _io_StringIO_tell__doc__}, - -static PyObject * -_io_StringIO_tell_impl(stringio *self); - -static PyObject * -_io_StringIO_tell(stringio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_StringIO_tell_impl(self); -} - -PyDoc_STRVAR(_io_StringIO_read__doc__, -"read($self, size=-1, /)\n" -"--\n" -"\n" -"Read at most size characters, returned as a string.\n" -"\n" -"If the argument is negative or omitted, read until EOF\n" -"is reached. Return an empty string at EOF."); - -#define _IO_STRINGIO_READ_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_io_StringIO_getvalue__doc__, +"getvalue($self, /)\n" +"--\n" +"\n" +"Retrieve the entire contents of the object."); + +#define _IO_STRINGIO_GETVALUE_METHODDEF \ + {"getvalue", (PyCFunction)_io_StringIO_getvalue, METH_NOARGS, _io_StringIO_getvalue__doc__}, + +static PyObject * +_io_StringIO_getvalue_impl(stringio *self); + +static PyObject * +_io_StringIO_getvalue(stringio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_StringIO_getvalue_impl(self); +} + +PyDoc_STRVAR(_io_StringIO_tell__doc__, +"tell($self, /)\n" +"--\n" +"\n" +"Tell the current file position."); + +#define _IO_STRINGIO_TELL_METHODDEF \ + {"tell", (PyCFunction)_io_StringIO_tell, METH_NOARGS, _io_StringIO_tell__doc__}, + +static PyObject * +_io_StringIO_tell_impl(stringio *self); + +static PyObject * +_io_StringIO_tell(stringio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_StringIO_tell_impl(self); +} + +PyDoc_STRVAR(_io_StringIO_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n" +"Read at most size characters, returned as a string.\n" +"\n" +"If the argument is negative or omitted, read until EOF\n" +"is reached. Return an empty string at EOF."); + +#define _IO_STRINGIO_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_io_StringIO_read, METH_FASTCALL, _io_StringIO_read__doc__}, - -static PyObject * -_io_StringIO_read_impl(stringio *self, Py_ssize_t size); - -static PyObject * -_io_StringIO_read(stringio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io_StringIO_read_impl(stringio *self, Py_ssize_t size); + +static PyObject * +_io_StringIO_read(stringio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -69,35 +69,35 @@ _io_StringIO_read(stringio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_StringIO_read_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_StringIO_readline__doc__, -"readline($self, size=-1, /)\n" -"--\n" -"\n" -"Read until newline or EOF.\n" -"\n" -"Returns an empty string if EOF is hit immediately."); - -#define _IO_STRINGIO_READLINE_METHODDEF \ + return_value = _io_StringIO_read_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_StringIO_readline__doc__, +"readline($self, size=-1, /)\n" +"--\n" +"\n" +"Read until newline or EOF.\n" +"\n" +"Returns an empty string if EOF is hit immediately."); + +#define _IO_STRINGIO_READLINE_METHODDEF \ {"readline", (PyCFunction)(void(*)(void))_io_StringIO_readline, METH_FASTCALL, _io_StringIO_readline__doc__}, - -static PyObject * -_io_StringIO_readline_impl(stringio *self, Py_ssize_t size); - -static PyObject * -_io_StringIO_readline(stringio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io_StringIO_readline_impl(stringio *self, Py_ssize_t size); + +static PyObject * +_io_StringIO_readline(stringio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -105,37 +105,37 @@ _io_StringIO_readline(stringio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_StringIO_readline_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_StringIO_truncate__doc__, -"truncate($self, pos=None, /)\n" -"--\n" -"\n" -"Truncate size to pos.\n" -"\n" -"The pos argument defaults to the current file position, as\n" -"returned by tell(). The current file position is unchanged.\n" -"Returns the new absolute position."); - -#define _IO_STRINGIO_TRUNCATE_METHODDEF \ + return_value = _io_StringIO_readline_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_StringIO_truncate__doc__, +"truncate($self, pos=None, /)\n" +"--\n" +"\n" +"Truncate size to pos.\n" +"\n" +"The pos argument defaults to the current file position, as\n" +"returned by tell(). The current file position is unchanged.\n" +"Returns the new absolute position."); + +#define _IO_STRINGIO_TRUNCATE_METHODDEF \ {"truncate", (PyCFunction)(void(*)(void))_io_StringIO_truncate, METH_FASTCALL, _io_StringIO_truncate__doc__}, - -static PyObject * -_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size); - -static PyObject * -_io_StringIO_truncate(stringio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = self->pos; - + +static PyObject * +_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size); + +static PyObject * +_io_StringIO_truncate(stringio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = self->pos; + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -143,40 +143,40 @@ _io_StringIO_truncate(stringio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_StringIO_truncate_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_StringIO_seek__doc__, -"seek($self, pos, whence=0, /)\n" -"--\n" -"\n" -"Change stream position.\n" -"\n" -"Seek to character offset pos relative to position indicated by whence:\n" -" 0 Start of stream (the default). pos should be >= 0;\n" -" 1 Current position - pos must be 0;\n" -" 2 End of stream - pos must be 0.\n" -"Returns the new absolute position."); - -#define _IO_STRINGIO_SEEK_METHODDEF \ + return_value = _io_StringIO_truncate_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_StringIO_seek__doc__, +"seek($self, pos, whence=0, /)\n" +"--\n" +"\n" +"Change stream position.\n" +"\n" +"Seek to character offset pos relative to position indicated by whence:\n" +" 0 Start of stream (the default). pos should be >= 0;\n" +" 1 Current position - pos must be 0;\n" +" 2 End of stream - pos must be 0.\n" +"Returns the new absolute position."); + +#define _IO_STRINGIO_SEEK_METHODDEF \ {"seek", (PyCFunction)(void(*)(void))_io_StringIO_seek, METH_FASTCALL, _io_StringIO_seek__doc__}, - -static PyObject * -_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence); - -static PyObject * -_io_StringIO_seek(stringio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t pos; - int whence = 0; - + +static PyObject * +_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence); + +static PyObject * +_io_StringIO_seek(stringio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t pos; + int whence = 0; + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -207,77 +207,77 @@ _io_StringIO_seek(stringio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_StringIO_seek_impl(self, pos, whence); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_StringIO_write__doc__, -"write($self, s, /)\n" -"--\n" -"\n" -"Write string to file.\n" -"\n" -"Returns the number of characters written, which is always equal to\n" -"the length of the string."); - -#define _IO_STRINGIO_WRITE_METHODDEF \ - {"write", (PyCFunction)_io_StringIO_write, METH_O, _io_StringIO_write__doc__}, - -PyDoc_STRVAR(_io_StringIO_close__doc__, -"close($self, /)\n" -"--\n" -"\n" -"Close the IO object.\n" -"\n" -"Attempting any further operation after the object is closed\n" -"will raise a ValueError.\n" -"\n" -"This method has no effect if the file is already closed."); - -#define _IO_STRINGIO_CLOSE_METHODDEF \ - {"close", (PyCFunction)_io_StringIO_close, METH_NOARGS, _io_StringIO_close__doc__}, - -static PyObject * -_io_StringIO_close_impl(stringio *self); - -static PyObject * -_io_StringIO_close(stringio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_StringIO_close_impl(self); -} - -PyDoc_STRVAR(_io_StringIO___init____doc__, -"StringIO(initial_value=\'\', newline=\'\\n\')\n" -"--\n" -"\n" -"Text I/O implementation using an in-memory buffer.\n" -"\n" -"The initial_value argument sets the value of object. The newline\n" -"argument is like the one of TextIOWrapper\'s constructor."); - -static int -_io_StringIO___init___impl(stringio *self, PyObject *value, - PyObject *newline_obj); - -static int -_io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"initial_value", "newline", NULL}; + return_value = _io_StringIO_seek_impl(self, pos, whence); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_StringIO_write__doc__, +"write($self, s, /)\n" +"--\n" +"\n" +"Write string to file.\n" +"\n" +"Returns the number of characters written, which is always equal to\n" +"the length of the string."); + +#define _IO_STRINGIO_WRITE_METHODDEF \ + {"write", (PyCFunction)_io_StringIO_write, METH_O, _io_StringIO_write__doc__}, + +PyDoc_STRVAR(_io_StringIO_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the IO object.\n" +"\n" +"Attempting any further operation after the object is closed\n" +"will raise a ValueError.\n" +"\n" +"This method has no effect if the file is already closed."); + +#define _IO_STRINGIO_CLOSE_METHODDEF \ + {"close", (PyCFunction)_io_StringIO_close, METH_NOARGS, _io_StringIO_close__doc__}, + +static PyObject * +_io_StringIO_close_impl(stringio *self); + +static PyObject * +_io_StringIO_close(stringio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_StringIO_close_impl(self); +} + +PyDoc_STRVAR(_io_StringIO___init____doc__, +"StringIO(initial_value=\'\', newline=\'\\n\')\n" +"--\n" +"\n" +"Text I/O implementation using an in-memory buffer.\n" +"\n" +"The initial_value argument sets the value of object. The newline\n" +"argument is like the one of TextIOWrapper\'s constructor."); + +static int +_io_StringIO___init___impl(stringio *self, PyObject *value, + PyObject *newline_obj); + +static int +_io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"initial_value", "newline", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "StringIO", 0}; PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *value = NULL; - PyObject *newline_obj = NULL; - + PyObject *value = NULL; + PyObject *newline_obj = NULL; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 2, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -289,63 +289,63 @@ _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } newline_obj = fastargs[1]; skip_optional_pos: - return_value = _io_StringIO___init___impl((stringio *)self, value, newline_obj); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_StringIO_readable__doc__, -"readable($self, /)\n" -"--\n" -"\n" -"Returns True if the IO object can be read."); - -#define _IO_STRINGIO_READABLE_METHODDEF \ - {"readable", (PyCFunction)_io_StringIO_readable, METH_NOARGS, _io_StringIO_readable__doc__}, - -static PyObject * -_io_StringIO_readable_impl(stringio *self); - -static PyObject * -_io_StringIO_readable(stringio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_StringIO_readable_impl(self); -} - -PyDoc_STRVAR(_io_StringIO_writable__doc__, -"writable($self, /)\n" -"--\n" -"\n" -"Returns True if the IO object can be written."); - -#define _IO_STRINGIO_WRITABLE_METHODDEF \ - {"writable", (PyCFunction)_io_StringIO_writable, METH_NOARGS, _io_StringIO_writable__doc__}, - -static PyObject * -_io_StringIO_writable_impl(stringio *self); - -static PyObject * -_io_StringIO_writable(stringio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_StringIO_writable_impl(self); -} - -PyDoc_STRVAR(_io_StringIO_seekable__doc__, -"seekable($self, /)\n" -"--\n" -"\n" -"Returns True if the IO object can be seeked."); - -#define _IO_STRINGIO_SEEKABLE_METHODDEF \ - {"seekable", (PyCFunction)_io_StringIO_seekable, METH_NOARGS, _io_StringIO_seekable__doc__}, - -static PyObject * -_io_StringIO_seekable_impl(stringio *self); - -static PyObject * -_io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_StringIO_seekable_impl(self); -} + return_value = _io_StringIO___init___impl((stringio *)self, value, newline_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_StringIO_readable__doc__, +"readable($self, /)\n" +"--\n" +"\n" +"Returns True if the IO object can be read."); + +#define _IO_STRINGIO_READABLE_METHODDEF \ + {"readable", (PyCFunction)_io_StringIO_readable, METH_NOARGS, _io_StringIO_readable__doc__}, + +static PyObject * +_io_StringIO_readable_impl(stringio *self); + +static PyObject * +_io_StringIO_readable(stringio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_StringIO_readable_impl(self); +} + +PyDoc_STRVAR(_io_StringIO_writable__doc__, +"writable($self, /)\n" +"--\n" +"\n" +"Returns True if the IO object can be written."); + +#define _IO_STRINGIO_WRITABLE_METHODDEF \ + {"writable", (PyCFunction)_io_StringIO_writable, METH_NOARGS, _io_StringIO_writable__doc__}, + +static PyObject * +_io_StringIO_writable_impl(stringio *self); + +static PyObject * +_io_StringIO_writable(stringio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_StringIO_writable_impl(self); +} + +PyDoc_STRVAR(_io_StringIO_seekable__doc__, +"seekable($self, /)\n" +"--\n" +"\n" +"Returns True if the IO object can be seeked."); + +#define _IO_STRINGIO_SEEKABLE_METHODDEF \ + {"seekable", (PyCFunction)_io_StringIO_seekable, METH_NOARGS, _io_StringIO_seekable__doc__}, + +static PyObject * +_io_StringIO_seekable_impl(stringio *self); + +static PyObject * +_io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_StringIO_seekable_impl(self); +} /*[clinic end generated code: output=7aad5ab2e64a25b8 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/textio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/textio.c.h index b8b507543ea..72aea83dcc9 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/textio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/textio.c.h @@ -1,43 +1,43 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_io_IncrementalNewlineDecoder___init____doc__, -"IncrementalNewlineDecoder(decoder, translate, errors=\'strict\')\n" -"--\n" -"\n" -"Codec used when reading a file in universal newlines mode.\n" -"\n" -"It wraps another incremental decoder, translating \\r\\n and \\r into \\n.\n" -"It also records the types of newlines encountered. When used with\n" -"translate=False, it ensures that the newline sequence is returned in\n" -"one piece. When used with decoder=None, it expects unicode strings as\n" -"decode input and translates newlines without first invoking an external\n" -"decoder."); - -static int -_io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, - PyObject *decoder, int translate, - PyObject *errors); - -static int -_io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"decoder", "translate", "errors", NULL}; +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_io_IncrementalNewlineDecoder___init____doc__, +"IncrementalNewlineDecoder(decoder, translate, errors=\'strict\')\n" +"--\n" +"\n" +"Codec used when reading a file in universal newlines mode.\n" +"\n" +"It wraps another incremental decoder, translating \\r\\n and \\r into \\n.\n" +"It also records the types of newlines encountered. When used with\n" +"translate=False, it ensures that the newline sequence is returned in\n" +"one piece. When used with decoder=None, it expects unicode strings as\n" +"decode input and translates newlines without first invoking an external\n" +"decoder."); + +static int +_io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, + PyObject *decoder, int translate, + PyObject *errors); + +static int +_io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"decoder", "translate", "errors", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "IncrementalNewlineDecoder", 0}; PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 2; - PyObject *decoder; - int translate; - PyObject *errors = NULL; - + PyObject *decoder; + int translate; + PyObject *errors = NULL; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 3, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } decoder = fastargs[0]; if (PyFloat_Check(fastargs[1])) { PyErr_SetString(PyExc_TypeError, @@ -53,39 +53,39 @@ _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject } errors = fastargs[2]; skip_optional_pos: - return_value = _io_IncrementalNewlineDecoder___init___impl((nldecoder_object *)self, decoder, translate, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_IncrementalNewlineDecoder_decode__doc__, -"decode($self, /, input, final=False)\n" -"--\n" -"\n"); - -#define _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF \ + return_value = _io_IncrementalNewlineDecoder___init___impl((nldecoder_object *)self, decoder, translate, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_IncrementalNewlineDecoder_decode__doc__, +"decode($self, /, input, final=False)\n" +"--\n" +"\n"); + +#define _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF \ {"decode", (PyCFunction)(void(*)(void))_io_IncrementalNewlineDecoder_decode, METH_FASTCALL|METH_KEYWORDS, _io_IncrementalNewlineDecoder_decode__doc__}, - -static PyObject * -_io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, - PyObject *input, int final); - -static PyObject * -_io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"input", "final", NULL}; + +static PyObject * +_io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, + PyObject *input, int final); + +static PyObject * +_io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"input", "final", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *input; - int final = 0; - + PyObject *input; + int final = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } input = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -100,115 +100,115 @@ _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *ar goto exit; } skip_optional_pos: - return_value = _io_IncrementalNewlineDecoder_decode_impl(self, input, final); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_IncrementalNewlineDecoder_getstate__doc__, -"getstate($self, /)\n" -"--\n" -"\n"); - -#define _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF \ - {"getstate", (PyCFunction)_io_IncrementalNewlineDecoder_getstate, METH_NOARGS, _io_IncrementalNewlineDecoder_getstate__doc__}, - -static PyObject * -_io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self); - -static PyObject * -_io_IncrementalNewlineDecoder_getstate(nldecoder_object *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_IncrementalNewlineDecoder_getstate_impl(self); -} - -PyDoc_STRVAR(_io_IncrementalNewlineDecoder_setstate__doc__, -"setstate($self, state, /)\n" -"--\n" -"\n"); - -#define _IO_INCREMENTALNEWLINEDECODER_SETSTATE_METHODDEF \ - {"setstate", (PyCFunction)_io_IncrementalNewlineDecoder_setstate, METH_O, _io_IncrementalNewlineDecoder_setstate__doc__}, - -PyDoc_STRVAR(_io_IncrementalNewlineDecoder_reset__doc__, -"reset($self, /)\n" -"--\n" -"\n"); - -#define _IO_INCREMENTALNEWLINEDECODER_RESET_METHODDEF \ - {"reset", (PyCFunction)_io_IncrementalNewlineDecoder_reset, METH_NOARGS, _io_IncrementalNewlineDecoder_reset__doc__}, - -static PyObject * -_io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self); - -static PyObject * -_io_IncrementalNewlineDecoder_reset(nldecoder_object *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_IncrementalNewlineDecoder_reset_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper___init____doc__, -"TextIOWrapper(buffer, encoding=None, errors=None, newline=None,\n" -" line_buffering=False, write_through=False)\n" -"--\n" -"\n" -"Character and line based layer over a BufferedIOBase object, buffer.\n" -"\n" -"encoding gives the name of the encoding that the stream will be\n" -"decoded or encoded with. It defaults to locale.getpreferredencoding(False).\n" -"\n" -"errors determines the strictness of encoding and decoding (see\n" -"help(codecs.Codec) or the documentation for codecs.register) and\n" -"defaults to \"strict\".\n" -"\n" -"newline controls how line endings are handled. It can be None, \'\',\n" -"\'\\n\', \'\\r\', and \'\\r\\n\'. It works as follows:\n" -"\n" -"* On input, if newline is None, universal newlines mode is\n" -" enabled. Lines in the input can end in \'\\n\', \'\\r\', or \'\\r\\n\', and\n" -" these are translated into \'\\n\' before being returned to the\n" -" caller. If it is \'\', universal newline mode is enabled, but line\n" -" endings are returned to the caller untranslated. If it has any of\n" -" the other legal values, input lines are only terminated by the given\n" -" string, and the line ending is returned to the caller untranslated.\n" -"\n" -"* On output, if newline is None, any \'\\n\' characters written are\n" -" translated to the system default line separator, os.linesep. If\n" -" newline is \'\' or \'\\n\', no translation takes place. If newline is any\n" -" of the other legal values, any \'\\n\' characters written are translated\n" -" to the given string.\n" -"\n" -"If line_buffering is True, a call to flush is implied when a call to\n" -"write contains a newline character."); - -static int -_io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, - const char *encoding, PyObject *errors, - const char *newline, int line_buffering, - int write_through); - -static int -_io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; + return_value = _io_IncrementalNewlineDecoder_decode_impl(self, input, final); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_IncrementalNewlineDecoder_getstate__doc__, +"getstate($self, /)\n" +"--\n" +"\n"); + +#define _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF \ + {"getstate", (PyCFunction)_io_IncrementalNewlineDecoder_getstate, METH_NOARGS, _io_IncrementalNewlineDecoder_getstate__doc__}, + +static PyObject * +_io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self); + +static PyObject * +_io_IncrementalNewlineDecoder_getstate(nldecoder_object *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_IncrementalNewlineDecoder_getstate_impl(self); +} + +PyDoc_STRVAR(_io_IncrementalNewlineDecoder_setstate__doc__, +"setstate($self, state, /)\n" +"--\n" +"\n"); + +#define _IO_INCREMENTALNEWLINEDECODER_SETSTATE_METHODDEF \ + {"setstate", (PyCFunction)_io_IncrementalNewlineDecoder_setstate, METH_O, _io_IncrementalNewlineDecoder_setstate__doc__}, + +PyDoc_STRVAR(_io_IncrementalNewlineDecoder_reset__doc__, +"reset($self, /)\n" +"--\n" +"\n"); + +#define _IO_INCREMENTALNEWLINEDECODER_RESET_METHODDEF \ + {"reset", (PyCFunction)_io_IncrementalNewlineDecoder_reset, METH_NOARGS, _io_IncrementalNewlineDecoder_reset__doc__}, + +static PyObject * +_io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self); + +static PyObject * +_io_IncrementalNewlineDecoder_reset(nldecoder_object *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_IncrementalNewlineDecoder_reset_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper___init____doc__, +"TextIOWrapper(buffer, encoding=None, errors=None, newline=None,\n" +" line_buffering=False, write_through=False)\n" +"--\n" +"\n" +"Character and line based layer over a BufferedIOBase object, buffer.\n" +"\n" +"encoding gives the name of the encoding that the stream will be\n" +"decoded or encoded with. It defaults to locale.getpreferredencoding(False).\n" +"\n" +"errors determines the strictness of encoding and decoding (see\n" +"help(codecs.Codec) or the documentation for codecs.register) and\n" +"defaults to \"strict\".\n" +"\n" +"newline controls how line endings are handled. It can be None, \'\',\n" +"\'\\n\', \'\\r\', and \'\\r\\n\'. It works as follows:\n" +"\n" +"* On input, if newline is None, universal newlines mode is\n" +" enabled. Lines in the input can end in \'\\n\', \'\\r\', or \'\\r\\n\', and\n" +" these are translated into \'\\n\' before being returned to the\n" +" caller. If it is \'\', universal newline mode is enabled, but line\n" +" endings are returned to the caller untranslated. If it has any of\n" +" the other legal values, input lines are only terminated by the given\n" +" string, and the line ending is returned to the caller untranslated.\n" +"\n" +"* On output, if newline is None, any \'\\n\' characters written are\n" +" translated to the system default line separator, os.linesep. If\n" +" newline is \'\' or \'\\n\', no translation takes place. If newline is any\n" +" of the other legal values, any \'\\n\' characters written are translated\n" +" to the given string.\n" +"\n" +"If line_buffering is True, a call to flush is implied when a call to\n" +"write contains a newline character."); + +static int +_io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, + const char *encoding, PyObject *errors, + const char *newline, int line_buffering, + int write_through); + +static int +_io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "TextIOWrapper", 0}; PyObject *argsbuf[6]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *buffer; - const char *encoding = NULL; - PyObject *errors = Py_None; - const char *newline = NULL; - int line_buffering = 0; - int write_through = 0; - + PyObject *buffer; + const char *encoding = NULL; + PyObject *errors = Py_None; + const char *newline = NULL; + int line_buffering = 0; + int write_through = 0; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 6, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } buffer = fastargs[0]; if (!noptargs) { goto skip_optional_pos; @@ -289,48 +289,48 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto exit; } skip_optional_pos: - return_value = _io_TextIOWrapper___init___impl((textio *)self, buffer, encoding, errors, newline, line_buffering, write_through); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_TextIOWrapper_reconfigure__doc__, -"reconfigure($self, /, *, encoding=None, errors=None, newline=None,\n" -" line_buffering=None, write_through=None)\n" -"--\n" -"\n" -"Reconfigure the text stream with new parameters.\n" -"\n" -"This also does an implicit stream flush."); - -#define _IO_TEXTIOWRAPPER_RECONFIGURE_METHODDEF \ + return_value = _io_TextIOWrapper___init___impl((textio *)self, buffer, encoding, errors, newline, line_buffering, write_through); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_TextIOWrapper_reconfigure__doc__, +"reconfigure($self, /, *, encoding=None, errors=None, newline=None,\n" +" line_buffering=None, write_through=None)\n" +"--\n" +"\n" +"Reconfigure the text stream with new parameters.\n" +"\n" +"This also does an implicit stream flush."); + +#define _IO_TEXTIOWRAPPER_RECONFIGURE_METHODDEF \ {"reconfigure", (PyCFunction)(void(*)(void))_io_TextIOWrapper_reconfigure, METH_FASTCALL|METH_KEYWORDS, _io_TextIOWrapper_reconfigure__doc__}, - -static PyObject * -_io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, - PyObject *errors, PyObject *newline_obj, - PyObject *line_buffering_obj, - PyObject *write_through_obj); - -static PyObject * -_io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"encoding", "errors", "newline", "line_buffering", "write_through", NULL}; + +static PyObject * +_io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, + PyObject *errors, PyObject *newline_obj, + PyObject *line_buffering_obj, + PyObject *write_through_obj); + +static PyObject * +_io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"encoding", "errors", "newline", "line_buffering", "write_through", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "reconfigure", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *encoding = Py_None; - PyObject *errors = Py_None; - PyObject *newline_obj = NULL; - PyObject *line_buffering_obj = Py_None; - PyObject *write_through_obj = Py_None; - + PyObject *encoding = Py_None; + PyObject *errors = Py_None; + PyObject *newline_obj = NULL; + PyObject *line_buffering_obj = Py_None; + PyObject *write_through_obj = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_kwonly; } @@ -360,80 +360,80 @@ _io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t na } write_through_obj = args[4]; skip_optional_kwonly: - return_value = _io_TextIOWrapper_reconfigure_impl(self, encoding, errors, newline_obj, line_buffering_obj, write_through_obj); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_TextIOWrapper_detach__doc__, -"detach($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_DETACH_METHODDEF \ - {"detach", (PyCFunction)_io_TextIOWrapper_detach, METH_NOARGS, _io_TextIOWrapper_detach__doc__}, - -static PyObject * -_io_TextIOWrapper_detach_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_detach(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_detach_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper_write__doc__, -"write($self, text, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_WRITE_METHODDEF \ - {"write", (PyCFunction)_io_TextIOWrapper_write, METH_O, _io_TextIOWrapper_write__doc__}, - -static PyObject * -_io_TextIOWrapper_write_impl(textio *self, PyObject *text); - -static PyObject * -_io_TextIOWrapper_write(textio *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *text; - + return_value = _io_TextIOWrapper_reconfigure_impl(self, encoding, errors, newline_obj, line_buffering_obj, write_through_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_TextIOWrapper_detach__doc__, +"detach($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_DETACH_METHODDEF \ + {"detach", (PyCFunction)_io_TextIOWrapper_detach, METH_NOARGS, _io_TextIOWrapper_detach__doc__}, + +static PyObject * +_io_TextIOWrapper_detach_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_detach(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_detach_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper_write__doc__, +"write($self, text, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_WRITE_METHODDEF \ + {"write", (PyCFunction)_io_TextIOWrapper_write, METH_O, _io_TextIOWrapper_write__doc__}, + +static PyObject * +_io_TextIOWrapper_write_impl(textio *self, PyObject *text); + +static PyObject * +_io_TextIOWrapper_write(textio *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *text; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("write", "argument", "str", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg) == -1) { goto exit; } text = arg; - return_value = _io_TextIOWrapper_write_impl(self, text); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_TextIOWrapper_read__doc__, -"read($self, size=-1, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_READ_METHODDEF \ + return_value = _io_TextIOWrapper_write_impl(self, text); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_TextIOWrapper_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_io_TextIOWrapper_read, METH_FASTCALL, _io_TextIOWrapper_read__doc__}, - -static PyObject * -_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n); - -static PyObject * -_io_TextIOWrapper_read(textio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t n = -1; - + +static PyObject * +_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n); + +static PyObject * +_io_TextIOWrapper_read(textio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t n = -1; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -441,32 +441,32 @@ _io_TextIOWrapper_read(textio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_TextIOWrapper_read_impl(self, n); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_TextIOWrapper_readline__doc__, -"readline($self, size=-1, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_READLINE_METHODDEF \ + return_value = _io_TextIOWrapper_read_impl(self, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_TextIOWrapper_readline__doc__, +"readline($self, size=-1, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_READLINE_METHODDEF \ {"readline", (PyCFunction)(void(*)(void))_io_TextIOWrapper_readline, METH_FASTCALL, _io_TextIOWrapper_readline__doc__}, - -static PyObject * -_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size); - -static PyObject * -_io_TextIOWrapper_readline(textio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size); + +static PyObject * +_io_TextIOWrapper_readline(textio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -488,33 +488,33 @@ _io_TextIOWrapper_readline(textio *self, PyObject *const *args, Py_ssize_t nargs size = ival; } skip_optional: - return_value = _io_TextIOWrapper_readline_impl(self, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_TextIOWrapper_seek__doc__, -"seek($self, cookie, whence=0, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_SEEK_METHODDEF \ + return_value = _io_TextIOWrapper_readline_impl(self, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_TextIOWrapper_seek__doc__, +"seek($self, cookie, whence=0, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_SEEK_METHODDEF \ {"seek", (PyCFunction)(void(*)(void))_io_TextIOWrapper_seek, METH_FASTCALL, _io_TextIOWrapper_seek__doc__}, - -static PyObject * -_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence); - -static PyObject * -_io_TextIOWrapper_seek(textio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *cookieObj; - int whence = 0; - + +static PyObject * +_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence); + +static PyObject * +_io_TextIOWrapper_seek(textio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *cookieObj; + int whence = 0; + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { - goto exit; - } + goto exit; + } cookieObj = args[0]; if (nargs < 2) { goto skip_optional; @@ -529,176 +529,176 @@ _io_TextIOWrapper_seek(textio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _io_TextIOWrapper_seek_impl(self, cookieObj, whence); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_TextIOWrapper_tell__doc__, -"tell($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_TELL_METHODDEF \ - {"tell", (PyCFunction)_io_TextIOWrapper_tell, METH_NOARGS, _io_TextIOWrapper_tell__doc__}, - -static PyObject * -_io_TextIOWrapper_tell_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_tell(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_tell_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper_truncate__doc__, -"truncate($self, pos=None, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF \ + return_value = _io_TextIOWrapper_seek_impl(self, cookieObj, whence); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_TextIOWrapper_tell__doc__, +"tell($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_TELL_METHODDEF \ + {"tell", (PyCFunction)_io_TextIOWrapper_tell, METH_NOARGS, _io_TextIOWrapper_tell__doc__}, + +static PyObject * +_io_TextIOWrapper_tell_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_tell(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_tell_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper_truncate__doc__, +"truncate($self, pos=None, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF \ {"truncate", (PyCFunction)(void(*)(void))_io_TextIOWrapper_truncate, METH_FASTCALL, _io_TextIOWrapper_truncate__doc__}, - -static PyObject * -_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos); - -static PyObject * -_io_TextIOWrapper_truncate(textio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *pos = Py_None; - + +static PyObject * +_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos); + +static PyObject * +_io_TextIOWrapper_truncate(textio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *pos = Py_None; + if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } pos = args[0]; skip_optional: - return_value = _io_TextIOWrapper_truncate_impl(self, pos); - -exit: - return return_value; -} - -PyDoc_STRVAR(_io_TextIOWrapper_fileno__doc__, -"fileno($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_FILENO_METHODDEF \ - {"fileno", (PyCFunction)_io_TextIOWrapper_fileno, METH_NOARGS, _io_TextIOWrapper_fileno__doc__}, - -static PyObject * -_io_TextIOWrapper_fileno_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_fileno(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_fileno_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper_seekable__doc__, -"seekable($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_SEEKABLE_METHODDEF \ - {"seekable", (PyCFunction)_io_TextIOWrapper_seekable, METH_NOARGS, _io_TextIOWrapper_seekable__doc__}, - -static PyObject * -_io_TextIOWrapper_seekable_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_seekable(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_seekable_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper_readable__doc__, -"readable($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_READABLE_METHODDEF \ - {"readable", (PyCFunction)_io_TextIOWrapper_readable, METH_NOARGS, _io_TextIOWrapper_readable__doc__}, - -static PyObject * -_io_TextIOWrapper_readable_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_readable(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_readable_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper_writable__doc__, -"writable($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_WRITABLE_METHODDEF \ - {"writable", (PyCFunction)_io_TextIOWrapper_writable, METH_NOARGS, _io_TextIOWrapper_writable__doc__}, - -static PyObject * -_io_TextIOWrapper_writable_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_writable(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_writable_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper_isatty__doc__, -"isatty($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_ISATTY_METHODDEF \ - {"isatty", (PyCFunction)_io_TextIOWrapper_isatty, METH_NOARGS, _io_TextIOWrapper_isatty__doc__}, - -static PyObject * -_io_TextIOWrapper_isatty_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_isatty(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_isatty_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper_flush__doc__, -"flush($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_FLUSH_METHODDEF \ - {"flush", (PyCFunction)_io_TextIOWrapper_flush, METH_NOARGS, _io_TextIOWrapper_flush__doc__}, - -static PyObject * -_io_TextIOWrapper_flush_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_flush(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_flush_impl(self); -} - -PyDoc_STRVAR(_io_TextIOWrapper_close__doc__, -"close($self, /)\n" -"--\n" -"\n"); - -#define _IO_TEXTIOWRAPPER_CLOSE_METHODDEF \ - {"close", (PyCFunction)_io_TextIOWrapper_close, METH_NOARGS, _io_TextIOWrapper_close__doc__}, - -static PyObject * -_io_TextIOWrapper_close_impl(textio *self); - -static PyObject * -_io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io_TextIOWrapper_close_impl(self); -} + return_value = _io_TextIOWrapper_truncate_impl(self, pos); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_TextIOWrapper_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_FILENO_METHODDEF \ + {"fileno", (PyCFunction)_io_TextIOWrapper_fileno, METH_NOARGS, _io_TextIOWrapper_fileno__doc__}, + +static PyObject * +_io_TextIOWrapper_fileno_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_fileno(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_fileno_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper_seekable__doc__, +"seekable($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_SEEKABLE_METHODDEF \ + {"seekable", (PyCFunction)_io_TextIOWrapper_seekable, METH_NOARGS, _io_TextIOWrapper_seekable__doc__}, + +static PyObject * +_io_TextIOWrapper_seekable_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_seekable(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_seekable_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper_readable__doc__, +"readable($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_READABLE_METHODDEF \ + {"readable", (PyCFunction)_io_TextIOWrapper_readable, METH_NOARGS, _io_TextIOWrapper_readable__doc__}, + +static PyObject * +_io_TextIOWrapper_readable_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_readable(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_readable_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper_writable__doc__, +"writable($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_WRITABLE_METHODDEF \ + {"writable", (PyCFunction)_io_TextIOWrapper_writable, METH_NOARGS, _io_TextIOWrapper_writable__doc__}, + +static PyObject * +_io_TextIOWrapper_writable_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_writable(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_writable_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper_isatty__doc__, +"isatty($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)_io_TextIOWrapper_isatty, METH_NOARGS, _io_TextIOWrapper_isatty__doc__}, + +static PyObject * +_io_TextIOWrapper_isatty_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_isatty(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_isatty_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_io_TextIOWrapper_flush, METH_NOARGS, _io_TextIOWrapper_flush__doc__}, + +static PyObject * +_io_TextIOWrapper_flush_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_flush(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_flush_impl(self); +} + +PyDoc_STRVAR(_io_TextIOWrapper_close__doc__, +"close($self, /)\n" +"--\n" +"\n"); + +#define _IO_TEXTIOWRAPPER_CLOSE_METHODDEF \ + {"close", (PyCFunction)_io_TextIOWrapper_close, METH_NOARGS, _io_TextIOWrapper_close__doc__}, + +static PyObject * +_io_TextIOWrapper_close_impl(textio *self); + +static PyObject * +_io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io_TextIOWrapper_close_impl(self); +} /*[clinic end generated code: output=b1bae4f4cdf6019e input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/clinic/winconsoleio.c.h b/contrib/tools/python3/src/Modules/_io/clinic/winconsoleio.c.h index 3e501a58537..9be1d5a0ace 100644 --- a/contrib/tools/python3/src/Modules/_io/clinic/winconsoleio.c.h +++ b/contrib/tools/python3/src/Modules/_io/clinic/winconsoleio.c.h @@ -1,68 +1,68 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_close__doc__, -"close($self, /)\n" -"--\n" -"\n" -"Close the handle.\n" -"\n" -"A closed handle cannot be used for further I/O operations. close() may be\n" -"called more than once without error."); - -#define _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF \ - {"close", (PyCFunction)_io__WindowsConsoleIO_close, METH_NOARGS, _io__WindowsConsoleIO_close__doc__}, - -static PyObject * -_io__WindowsConsoleIO_close_impl(winconsoleio *self); - -static PyObject * -_io__WindowsConsoleIO_close(winconsoleio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__WindowsConsoleIO_close_impl(self); -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO___init____doc__, -"_WindowsConsoleIO(file, mode=\'r\', closefd=True, opener=None)\n" -"--\n" -"\n" -"Open a console buffer by file descriptor.\n" -"\n" -"The mode can be \'rb\' (default), or \'wb\' for reading or writing bytes. All\n" -"other mode characters will be ignored. Mode \'b\' will be assumed if it is\n" -"omitted. The *opener* parameter is always ignored."); - -static int -_io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, - const char *mode, int closefd, - PyObject *opener); - -static int -_io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the handle.\n" +"\n" +"A closed handle cannot be used for further I/O operations. close() may be\n" +"called more than once without error."); + +#define _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF \ + {"close", (PyCFunction)_io__WindowsConsoleIO_close, METH_NOARGS, _io__WindowsConsoleIO_close__doc__}, + +static PyObject * +_io__WindowsConsoleIO_close_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_close(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_close_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO___init____doc__, +"_WindowsConsoleIO(file, mode=\'r\', closefd=True, opener=None)\n" +"--\n" +"\n" +"Open a console buffer by file descriptor.\n" +"\n" +"The mode can be \'rb\' (default), or \'wb\' for reading or writing bytes. All\n" +"other mode characters will be ignored. Mode \'b\' will be assumed if it is\n" +"omitted. The *opener* parameter is always ignored."); + +static int +_io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, + const char *mode, int closefd, + PyObject *opener); + +static int +_io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "_WindowsConsoleIO", 0}; PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *nameobj; - const char *mode = "r"; - int closefd = 1; - PyObject *opener = Py_None; - + PyObject *nameobj; + const char *mode = "r"; + int closefd = 1; + PyObject *opener = Py_None; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 4, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } nameobj = fastargs[0]; if (!noptargs) { goto skip_optional_pos; @@ -101,176 +101,176 @@ _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } opener = fastargs[3]; skip_optional_pos: - return_value = _io__WindowsConsoleIO___init___impl((winconsoleio *)self, nameobj, mode, closefd, opener); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_fileno__doc__, -"fileno($self, /)\n" -"--\n" -"\n" -"Return the underlying file descriptor (an integer).\n" -"\n" -"fileno is only set when a file descriptor is used to open\n" -"one of the standard streams."); - -#define _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF \ - {"fileno", (PyCFunction)_io__WindowsConsoleIO_fileno, METH_NOARGS, _io__WindowsConsoleIO_fileno__doc__}, - -static PyObject * -_io__WindowsConsoleIO_fileno_impl(winconsoleio *self); - -static PyObject * -_io__WindowsConsoleIO_fileno(winconsoleio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__WindowsConsoleIO_fileno_impl(self); -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_readable__doc__, -"readable($self, /)\n" -"--\n" -"\n" -"True if console is an input buffer."); - -#define _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF \ - {"readable", (PyCFunction)_io__WindowsConsoleIO_readable, METH_NOARGS, _io__WindowsConsoleIO_readable__doc__}, - -static PyObject * -_io__WindowsConsoleIO_readable_impl(winconsoleio *self); - -static PyObject * -_io__WindowsConsoleIO_readable(winconsoleio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__WindowsConsoleIO_readable_impl(self); -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_writable__doc__, -"writable($self, /)\n" -"--\n" -"\n" -"True if console is an output buffer."); - -#define _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF \ - {"writable", (PyCFunction)_io__WindowsConsoleIO_writable, METH_NOARGS, _io__WindowsConsoleIO_writable__doc__}, - -static PyObject * -_io__WindowsConsoleIO_writable_impl(winconsoleio *self); - -static PyObject * -_io__WindowsConsoleIO_writable(winconsoleio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__WindowsConsoleIO_writable_impl(self); -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_readinto__doc__, -"readinto($self, buffer, /)\n" -"--\n" -"\n" -"Same as RawIOBase.readinto()."); - -#define _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF \ - {"readinto", (PyCFunction)_io__WindowsConsoleIO_readinto, METH_O, _io__WindowsConsoleIO_readinto__doc__}, - -static PyObject * -_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, Py_buffer *buffer); - -static PyObject * -_io__WindowsConsoleIO_readinto(winconsoleio *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + return_value = _io__WindowsConsoleIO___init___impl((winconsoleio *)self, nameobj, mode, closefd, opener); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n" +"Return the underlying file descriptor (an integer).\n" +"\n" +"fileno is only set when a file descriptor is used to open\n" +"one of the standard streams."); + +#define _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF \ + {"fileno", (PyCFunction)_io__WindowsConsoleIO_fileno, METH_NOARGS, _io__WindowsConsoleIO_fileno__doc__}, + +static PyObject * +_io__WindowsConsoleIO_fileno_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_fileno(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_fileno_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_readable__doc__, +"readable($self, /)\n" +"--\n" +"\n" +"True if console is an input buffer."); + +#define _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF \ + {"readable", (PyCFunction)_io__WindowsConsoleIO_readable, METH_NOARGS, _io__WindowsConsoleIO_readable__doc__}, + +static PyObject * +_io__WindowsConsoleIO_readable_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_readable(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_readable_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_writable__doc__, +"writable($self, /)\n" +"--\n" +"\n" +"True if console is an output buffer."); + +#define _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF \ + {"writable", (PyCFunction)_io__WindowsConsoleIO_writable, METH_NOARGS, _io__WindowsConsoleIO_writable__doc__}, + +static PyObject * +_io__WindowsConsoleIO_writable_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_writable(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_writable_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_readinto__doc__, +"readinto($self, buffer, /)\n" +"--\n" +"\n" +"Same as RawIOBase.readinto()."); + +#define _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF \ + {"readinto", (PyCFunction)_io__WindowsConsoleIO_readinto, METH_O, _io__WindowsConsoleIO_readinto__doc__}, + +static PyObject * +_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, Py_buffer *buffer); + +static PyObject * +_io__WindowsConsoleIO_readinto(winconsoleio *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io__WindowsConsoleIO_readinto_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_readall__doc__, -"readall($self, /)\n" -"--\n" -"\n" -"Read all data from the console, returned as bytes.\n" -"\n" -"Return an empty bytes object at EOF."); - -#define _IO__WINDOWSCONSOLEIO_READALL_METHODDEF \ - {"readall", (PyCFunction)_io__WindowsConsoleIO_readall, METH_NOARGS, _io__WindowsConsoleIO_readall__doc__}, - -static PyObject * -_io__WindowsConsoleIO_readall_impl(winconsoleio *self); - -static PyObject * -_io__WindowsConsoleIO_readall(winconsoleio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__WindowsConsoleIO_readall_impl(self); -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_read__doc__, -"read($self, size=-1, /)\n" -"--\n" -"\n" -"Read at most size bytes, returned as bytes.\n" -"\n" -"Only makes one system call when size is a positive integer,\n" -"so less data may be returned than requested.\n" -"Return an empty bytes object at EOF."); - -#define _IO__WINDOWSCONSOLEIO_READ_METHODDEF \ + return_value = _io__WindowsConsoleIO_readinto_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_readall__doc__, +"readall($self, /)\n" +"--\n" +"\n" +"Read all data from the console, returned as bytes.\n" +"\n" +"Return an empty bytes object at EOF."); + +#define _IO__WINDOWSCONSOLEIO_READALL_METHODDEF \ + {"readall", (PyCFunction)_io__WindowsConsoleIO_readall, METH_NOARGS, _io__WindowsConsoleIO_readall__doc__}, + +static PyObject * +_io__WindowsConsoleIO_readall_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_readall(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_readall_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n" +"Read at most size bytes, returned as bytes.\n" +"\n" +"Only makes one system call when size is a positive integer,\n" +"so less data may be returned than requested.\n" +"Return an empty bytes object at EOF."); + +#define _IO__WINDOWSCONSOLEIO_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_io__WindowsConsoleIO_read, METH_FASTCALL, _io__WindowsConsoleIO_read__doc__}, - -static PyObject * -_io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size); - -static PyObject * -_io__WindowsConsoleIO_read(winconsoleio *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t size = -1; - + +static PyObject * +_io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size); + +static PyObject * +_io__WindowsConsoleIO_read(winconsoleio *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -278,112 +278,112 @@ _io__WindowsConsoleIO_read(winconsoleio *self, PyObject *const *args, Py_ssize_t goto exit; } skip_optional: - return_value = _io__WindowsConsoleIO_read_impl(self, size); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_write__doc__, -"write($self, b, /)\n" -"--\n" -"\n" -"Write buffer b to file, return number of bytes written.\n" -"\n" -"Only makes one system call, so not all of the data may be written.\n" -"The number of bytes actually written is returned."); - -#define _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF \ - {"write", (PyCFunction)_io__WindowsConsoleIO_write, METH_O, _io__WindowsConsoleIO_write__doc__}, - -static PyObject * -_io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b); - -static PyObject * -_io__WindowsConsoleIO_write(winconsoleio *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer b = {NULL, NULL}; - + return_value = _io__WindowsConsoleIO_read_impl(self, size); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_write__doc__, +"write($self, b, /)\n" +"--\n" +"\n" +"Write buffer b to file, return number of bytes written.\n" +"\n" +"Only makes one system call, so not all of the data may be written.\n" +"The number of bytes actually written is returned."); + +#define _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF \ + {"write", (PyCFunction)_io__WindowsConsoleIO_write, METH_O, _io__WindowsConsoleIO_write__doc__}, + +static PyObject * +_io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b); + +static PyObject * +_io__WindowsConsoleIO_write(winconsoleio *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer b = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&b, 'C')) { _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } - return_value = _io__WindowsConsoleIO_write_impl(self, &b); - -exit: - /* Cleanup for b */ - if (b.obj) { - PyBuffer_Release(&b); - } - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_io__WindowsConsoleIO_isatty__doc__, -"isatty($self, /)\n" -"--\n" -"\n" -"Always True."); - -#define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF \ - {"isatty", (PyCFunction)_io__WindowsConsoleIO_isatty, METH_NOARGS, _io__WindowsConsoleIO_isatty__doc__}, - -static PyObject * -_io__WindowsConsoleIO_isatty_impl(winconsoleio *self); - -static PyObject * -_io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) -{ - return _io__WindowsConsoleIO_isatty_impl(self); -} - -#endif /* defined(MS_WINDOWS) */ - -#ifndef _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF - #define _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF) */ - -#ifndef _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF - #define _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_FILENO_METHODDEF) */ - -#ifndef _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF - #define _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_READABLE_METHODDEF) */ - -#ifndef _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF - #define _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF) */ - -#ifndef _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF - #define _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_READINTO_METHODDEF) */ - -#ifndef _IO__WINDOWSCONSOLEIO_READALL_METHODDEF - #define _IO__WINDOWSCONSOLEIO_READALL_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_READALL_METHODDEF) */ - -#ifndef _IO__WINDOWSCONSOLEIO_READ_METHODDEF - #define _IO__WINDOWSCONSOLEIO_READ_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_READ_METHODDEF) */ - -#ifndef _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF - #define _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_WRITE_METHODDEF) */ - -#ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF - #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF -#endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ + return_value = _io__WindowsConsoleIO_write_impl(self, &b); + +exit: + /* Cleanup for b */ + if (b.obj) { + PyBuffer_Release(&b); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_io__WindowsConsoleIO_isatty__doc__, +"isatty($self, /)\n" +"--\n" +"\n" +"Always True."); + +#define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)_io__WindowsConsoleIO_isatty, METH_NOARGS, _io__WindowsConsoleIO_isatty__doc__}, + +static PyObject * +_io__WindowsConsoleIO_isatty_impl(winconsoleio *self); + +static PyObject * +_io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__WindowsConsoleIO_isatty_impl(self); +} + +#endif /* defined(MS_WINDOWS) */ + +#ifndef _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF + #define _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF + #define _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_FILENO_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF + #define _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_READABLE_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF + #define _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF + #define _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_READINTO_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_READALL_METHODDEF + #define _IO__WINDOWSCONSOLEIO_READALL_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_READALL_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_READ_METHODDEF + #define _IO__WINDOWSCONSOLEIO_READ_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_READ_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF + #define _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_WRITE_METHODDEF) */ + +#ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF + #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF +#endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ /*[clinic end generated code: output=f5b8860a658a001a input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/_io/fileio.c b/contrib/tools/python3/src/Modules/_io/fileio.c index 048484bde54..6f9d32c334c 100644 --- a/contrib/tools/python3/src/Modules/_io/fileio.c +++ b/contrib/tools/python3/src/Modules/_io/fileio.c @@ -1,930 +1,930 @@ -/* Author: Daniel Stutzbach */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" +/* Author: Daniel Stutzbach */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include "pycore_object.h" #include "structmember.h" // PyMemberDef #include -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#include /* For offsetof */ -#include "_iomodule.h" - -/* - * Known likely problems: - * - * - Files larger then 2**32-1 - * - Files with unicode filenames - * - Passing numbers greater than 2**32-1 when an integer is expected - * - Making it work on Windows and other oddball platforms - * - * To Do: - * - * - autoconfify header file inclusion - */ - -#ifdef MS_WINDOWS -/* can simulate truncate with Win32 API functions; see file_truncate */ -#define HAVE_FTRUNCATE -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#if BUFSIZ < (8*1024) -#define SMALLCHUNK (8*1024) -#elif (BUFSIZ >= (2 << 25)) -#error "unreasonable BUFSIZ > 64 MiB defined" -#else -#define SMALLCHUNK BUFSIZ -#endif - -/*[clinic input] -module _io -class _io.FileIO "fileio *" "&PyFileIO_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/ - -typedef struct { - PyObject_HEAD - int fd; - unsigned int created : 1; - unsigned int readable : 1; - unsigned int writable : 1; - unsigned int appending : 1; - signed int seekable : 2; /* -1 means unknown */ - unsigned int closefd : 1; - char finalizing; - unsigned int blksize; - PyObject *weakreflist; - PyObject *dict; -} fileio; - -PyTypeObject PyFileIO_Type; - -_Py_IDENTIFIER(name); - -#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) - -/* Forward declarations */ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_IO_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#include /* For offsetof */ +#include "_iomodule.h" + +/* + * Known likely problems: + * + * - Files larger then 2**32-1 + * - Files with unicode filenames + * - Passing numbers greater than 2**32-1 when an integer is expected + * - Making it work on Windows and other oddball platforms + * + * To Do: + * + * - autoconfify header file inclusion + */ + +#ifdef MS_WINDOWS +/* can simulate truncate with Win32 API functions; see file_truncate */ +#define HAVE_FTRUNCATE +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#if BUFSIZ < (8*1024) +#define SMALLCHUNK (8*1024) +#elif (BUFSIZ >= (2 << 25)) +#error "unreasonable BUFSIZ > 64 MiB defined" +#else +#define SMALLCHUNK BUFSIZ +#endif + +/*[clinic input] +module _io +class _io.FileIO "fileio *" "&PyFileIO_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/ + +typedef struct { + PyObject_HEAD + int fd; + unsigned int created : 1; + unsigned int readable : 1; + unsigned int writable : 1; + unsigned int appending : 1; + signed int seekable : 2; /* -1 means unknown */ + unsigned int closefd : 1; + char finalizing; + unsigned int blksize; + PyObject *weakreflist; + PyObject *dict; +} fileio; + +PyTypeObject PyFileIO_Type; + +_Py_IDENTIFIER(name); + +#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) + +/* Forward declarations */ static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error); - -int -_PyFileIO_closed(PyObject *self) -{ - return ((fileio *)self)->fd < 0; -} - -/* Because this can call arbitrary code, it shouldn't be called when - the refcount is 0 (that is, not directly from tp_dealloc unless - the refcount has been temporarily re-incremented). */ -static PyObject * -fileio_dealloc_warn(fileio *self, PyObject *source) -{ - if (self->fd >= 0 && self->closefd) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); - if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) { - /* Spurious errors can appear at shutdown */ - if (PyErr_ExceptionMatches(PyExc_Warning)) - PyErr_WriteUnraisable((PyObject *) self); - } - PyErr_Restore(exc, val, tb); - } - Py_RETURN_NONE; -} - -/* Returns 0 on success, -1 with exception set on failure. */ -static int -internal_close(fileio *self) -{ - int err = 0; - int save_errno = 0; - if (self->fd >= 0) { - int fd = self->fd; - self->fd = -1; - /* fd is accessible and someone else may have closed it */ - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - err = close(fd); - if (err < 0) - save_errno = errno; - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } - if (err < 0) { - errno = save_errno; - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - return 0; -} - -/*[clinic input] -_io.FileIO.close - -Close the file. - -A closed file cannot be used for further I/O operations. close() may be -called more than once without error. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_close_impl(fileio *self) -/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/ -{ - PyObject *res; - PyObject *exc, *val, *tb; - int rc; - _Py_IDENTIFIER(close); + +int +_PyFileIO_closed(PyObject *self) +{ + return ((fileio *)self)->fd < 0; +} + +/* Because this can call arbitrary code, it shouldn't be called when + the refcount is 0 (that is, not directly from tp_dealloc unless + the refcount has been temporarily re-incremented). */ +static PyObject * +fileio_dealloc_warn(fileio *self, PyObject *source) +{ + if (self->fd >= 0 && self->closefd) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) { + /* Spurious errors can appear at shutdown */ + if (PyErr_ExceptionMatches(PyExc_Warning)) + PyErr_WriteUnraisable((PyObject *) self); + } + PyErr_Restore(exc, val, tb); + } + Py_RETURN_NONE; +} + +/* Returns 0 on success, -1 with exception set on failure. */ +static int +internal_close(fileio *self) +{ + int err = 0; + int save_errno = 0; + if (self->fd >= 0) { + int fd = self->fd; + self->fd = -1; + /* fd is accessible and someone else may have closed it */ + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + err = close(fd); + if (err < 0) + save_errno = errno; + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } + if (err < 0) { + errno = save_errno; + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + return 0; +} + +/*[clinic input] +_io.FileIO.close + +Close the file. + +A closed file cannot be used for further I/O operations. close() may be +called more than once without error. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_close_impl(fileio *self) +/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/ +{ + PyObject *res; + PyObject *exc, *val, *tb; + int rc; + _Py_IDENTIFIER(close); res = _PyObject_CallMethodIdOneArg((PyObject*)&PyRawIOBase_Type, &PyId_close, (PyObject *)self); - if (!self->closefd) { - self->fd = -1; - return res; - } - if (res == NULL) - PyErr_Fetch(&exc, &val, &tb); - if (self->finalizing) { - PyObject *r = fileio_dealloc_warn(self, (PyObject *) self); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } - rc = internal_close(self); - if (res == NULL) - _PyErr_ChainExceptions(exc, val, tb); - if (rc < 0) - Py_CLEAR(res); - return res; -} - -static PyObject * -fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - fileio *self; - - assert(type != NULL && type->tp_alloc != NULL); - - self = (fileio *) type->tp_alloc(type, 0); - if (self != NULL) { - self->fd = -1; - self->created = 0; - self->readable = 0; - self->writable = 0; - self->appending = 0; - self->seekable = -1; - self->blksize = 0; - self->closefd = 1; - self->weakreflist = NULL; - } - - return (PyObject *) self; -} - -#ifdef O_CLOEXEC -extern int _Py_open_cloexec_works; -#endif - -/*[clinic input] -_io.FileIO.__init__ - file as nameobj: object - mode: str = "r" - closefd: bool(accept={int}) = True - opener: object = None - -Open a file. - -The mode can be 'r' (default), 'w', 'x' or 'a' for reading, -writing, exclusive creation or appending. The file will be created if it -doesn't exist when opened for writing or appending; it will be truncated -when opened for writing. A FileExistsError will be raised if it already -exists when opened for creating. Opening a file for creating implies -writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode -to allow simultaneous reading and writing. A custom opener can be used by -passing a callable as *opener*. The underlying file descriptor for the file -object is then obtained by calling opener with (*name*, *flags*). -*opener* must return an open file descriptor (passing os.open as *opener* -results in functionality similar to passing None). -[clinic start generated code]*/ - -static int -_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, - int closefd, PyObject *opener) -/*[clinic end generated code: output=23413f68e6484bbd input=1596c9157a042a39]*/ -{ -#ifdef MS_WINDOWS - Py_UNICODE *widename = NULL; -#else - const char *name = NULL; -#endif - PyObject *stringobj = NULL; - const char *s; - int ret = 0; - int rwa = 0, plus = 0; - int flags = 0; - int fd = -1; - int fd_is_own = 0; -#ifdef O_CLOEXEC - int *atomic_flag_works = &_Py_open_cloexec_works; -#elif !defined(MS_WINDOWS) - int *atomic_flag_works = NULL; -#endif - struct _Py_stat_struct fdfstat; - int fstat_result; - int async_err = 0; - - assert(PyFileIO_Check(self)); - if (self->fd >= 0) { - if (self->closefd) { - /* Have to close the existing file first. */ - if (internal_close(self) < 0) - return -1; - } - else - self->fd = -1; - } - - if (PyFloat_Check(nameobj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); - return -1; - } - - fd = _PyLong_AsInt(nameobj); - if (fd < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "negative file descriptor"); - return -1; - } - PyErr_Clear(); - } - - if (fd < 0) { -#ifdef MS_WINDOWS - if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { - return -1; - } + if (!self->closefd) { + self->fd = -1; + return res; + } + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); + if (self->finalizing) { + PyObject *r = fileio_dealloc_warn(self, (PyObject *) self); + if (r) + Py_DECREF(r); + else + PyErr_Clear(); + } + rc = internal_close(self); + if (res == NULL) + _PyErr_ChainExceptions(exc, val, tb); + if (rc < 0) + Py_CLEAR(res); + return res; +} + +static PyObject * +fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + fileio *self; + + assert(type != NULL && type->tp_alloc != NULL); + + self = (fileio *) type->tp_alloc(type, 0); + if (self != NULL) { + self->fd = -1; + self->created = 0; + self->readable = 0; + self->writable = 0; + self->appending = 0; + self->seekable = -1; + self->blksize = 0; + self->closefd = 1; + self->weakreflist = NULL; + } + + return (PyObject *) self; +} + +#ifdef O_CLOEXEC +extern int _Py_open_cloexec_works; +#endif + +/*[clinic input] +_io.FileIO.__init__ + file as nameobj: object + mode: str = "r" + closefd: bool(accept={int}) = True + opener: object = None + +Open a file. + +The mode can be 'r' (default), 'w', 'x' or 'a' for reading, +writing, exclusive creation or appending. The file will be created if it +doesn't exist when opened for writing or appending; it will be truncated +when opened for writing. A FileExistsError will be raised if it already +exists when opened for creating. Opening a file for creating implies +writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode +to allow simultaneous reading and writing. A custom opener can be used by +passing a callable as *opener*. The underlying file descriptor for the file +object is then obtained by calling opener with (*name*, *flags*). +*opener* must return an open file descriptor (passing os.open as *opener* +results in functionality similar to passing None). +[clinic start generated code]*/ + +static int +_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, + int closefd, PyObject *opener) +/*[clinic end generated code: output=23413f68e6484bbd input=1596c9157a042a39]*/ +{ +#ifdef MS_WINDOWS + Py_UNICODE *widename = NULL; +#else + const char *name = NULL; +#endif + PyObject *stringobj = NULL; + const char *s; + int ret = 0; + int rwa = 0, plus = 0; + int flags = 0; + int fd = -1; + int fd_is_own = 0; +#ifdef O_CLOEXEC + int *atomic_flag_works = &_Py_open_cloexec_works; +#elif !defined(MS_WINDOWS) + int *atomic_flag_works = NULL; +#endif + struct _Py_stat_struct fdfstat; + int fstat_result; + int async_err = 0; + + assert(PyFileIO_Check(self)); + if (self->fd >= 0) { + if (self->closefd) { + /* Have to close the existing file first. */ + if (internal_close(self) < 0) + return -1; + } + else + self->fd = -1; + } + + if (PyFloat_Check(nameobj)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float"); + return -1; + } + + fd = _PyLong_AsInt(nameobj); + if (fd < 0) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "negative file descriptor"); + return -1; + } + PyErr_Clear(); + } + + if (fd < 0) { +#ifdef MS_WINDOWS + if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { + return -1; + } _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS - widename = PyUnicode_AsUnicode(stringobj); + widename = PyUnicode_AsUnicode(stringobj); _Py_COMP_DIAG_POP - if (widename == NULL) - return -1; -#else - if (!PyUnicode_FSConverter(nameobj, &stringobj)) { - return -1; - } - name = PyBytes_AS_STRING(stringobj); -#endif - } - - s = mode; - while (*s) { - switch (*s++) { - case 'x': - if (rwa) { - bad_mode: - PyErr_SetString(PyExc_ValueError, - "Must have exactly one of create/read/write/append " - "mode and at most one plus"); - goto error; - } - rwa = 1; - self->created = 1; - self->writable = 1; - flags |= O_EXCL | O_CREAT; - break; - case 'r': - if (rwa) - goto bad_mode; - rwa = 1; - self->readable = 1; - break; - case 'w': - if (rwa) - goto bad_mode; - rwa = 1; - self->writable = 1; - flags |= O_CREAT | O_TRUNC; - break; - case 'a': - if (rwa) - goto bad_mode; - rwa = 1; - self->writable = 1; - self->appending = 1; - flags |= O_APPEND | O_CREAT; - break; - case 'b': - break; - case '+': - if (plus) - goto bad_mode; - self->readable = self->writable = 1; - plus = 1; - break; - default: - PyErr_Format(PyExc_ValueError, - "invalid mode: %.200s", mode); - goto error; - } - } - - if (!rwa) - goto bad_mode; - - if (self->readable && self->writable) - flags |= O_RDWR; - else if (self->readable) - flags |= O_RDONLY; - else - flags |= O_WRONLY; - -#ifdef O_BINARY - flags |= O_BINARY; -#endif - -#ifdef MS_WINDOWS - flags |= O_NOINHERIT; -#elif defined(O_CLOEXEC) - flags |= O_CLOEXEC; -#endif - + if (widename == NULL) + return -1; +#else + if (!PyUnicode_FSConverter(nameobj, &stringobj)) { + return -1; + } + name = PyBytes_AS_STRING(stringobj); +#endif + } + + s = mode; + while (*s) { + switch (*s++) { + case 'x': + if (rwa) { + bad_mode: + PyErr_SetString(PyExc_ValueError, + "Must have exactly one of create/read/write/append " + "mode and at most one plus"); + goto error; + } + rwa = 1; + self->created = 1; + self->writable = 1; + flags |= O_EXCL | O_CREAT; + break; + case 'r': + if (rwa) + goto bad_mode; + rwa = 1; + self->readable = 1; + break; + case 'w': + if (rwa) + goto bad_mode; + rwa = 1; + self->writable = 1; + flags |= O_CREAT | O_TRUNC; + break; + case 'a': + if (rwa) + goto bad_mode; + rwa = 1; + self->writable = 1; + self->appending = 1; + flags |= O_APPEND | O_CREAT; + break; + case 'b': + break; + case '+': + if (plus) + goto bad_mode; + self->readable = self->writable = 1; + plus = 1; + break; + default: + PyErr_Format(PyExc_ValueError, + "invalid mode: %.200s", mode); + goto error; + } + } + + if (!rwa) + goto bad_mode; + + if (self->readable && self->writable) + flags |= O_RDWR; + else if (self->readable) + flags |= O_RDONLY; + else + flags |= O_WRONLY; + +#ifdef O_BINARY + flags |= O_BINARY; +#endif + +#ifdef MS_WINDOWS + flags |= O_NOINHERIT; +#elif defined(O_CLOEXEC) + flags |= O_CLOEXEC; +#endif + if (PySys_Audit("open", "Osi", nameobj, mode, flags) < 0) { goto error; } - if (fd >= 0) { - self->fd = fd; - self->closefd = closefd; - } - else { - self->closefd = 1; - if (!closefd) { - PyErr_SetString(PyExc_ValueError, - "Cannot use closefd=False with file name"); - goto error; - } - - errno = 0; - if (opener == Py_None) { - do { - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - self->fd = _wopen(widename, flags, 0666); -#else - self->fd = open(name, flags, 0666); -#endif - Py_END_ALLOW_THREADS - } while (self->fd < 0 && errno == EINTR && - !(async_err = PyErr_CheckSignals())); - - if (async_err) - goto error; - } - else { - PyObject *fdobj; - -#ifndef MS_WINDOWS - /* the opener may clear the atomic flag */ - atomic_flag_works = NULL; -#endif - - fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags); - if (fdobj == NULL) - goto error; - if (!PyLong_Check(fdobj)) { - Py_DECREF(fdobj); - PyErr_SetString(PyExc_TypeError, - "expected integer from opener"); - goto error; - } - - self->fd = _PyLong_AsInt(fdobj); - Py_DECREF(fdobj); - if (self->fd < 0) { - if (!PyErr_Occurred()) { - /* The opener returned a negative but didn't set an - exception. See issue #27066 */ - PyErr_Format(PyExc_ValueError, - "opener returned %d", self->fd); - } - goto error; - } - } - - fd_is_own = 1; - if (self->fd < 0) { - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); - goto error; - } - -#ifndef MS_WINDOWS - if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0) - goto error; -#endif - } - - self->blksize = DEFAULT_BUFFER_SIZE; - Py_BEGIN_ALLOW_THREADS - fstat_result = _Py_fstat_noraise(self->fd, &fdfstat); - Py_END_ALLOW_THREADS - if (fstat_result < 0) { - /* Tolerate fstat() errors other than EBADF. See Issue #25717, where - an anonymous file on a Virtual Box shared folder filesystem would - raise ENOENT. */ -#ifdef MS_WINDOWS - if (GetLastError() == ERROR_INVALID_HANDLE) { - PyErr_SetFromWindowsErr(0); -#else - if (errno == EBADF) { - PyErr_SetFromErrno(PyExc_OSError); -#endif - goto error; - } - } - else { -#if defined(S_ISDIR) && defined(EISDIR) - /* On Unix, open will succeed for directories. - In Python, there should be no file objects referring to - directories, so we need a check. */ - if (S_ISDIR(fdfstat.st_mode)) { - errno = EISDIR; - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); - goto error; - } -#endif /* defined(S_ISDIR) */ -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - if (fdfstat.st_blksize > 1) - self->blksize = fdfstat.st_blksize; -#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ - } - -#if defined(MS_WINDOWS) || defined(__CYGWIN__) - /* don't translate newlines (\r\n <=> \n) */ - _setmode(self->fd, O_BINARY); -#endif - - if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0) - goto error; - - if (self->appending) { - /* For consistent behaviour, we explicitly seek to the - end of file (otherwise, it might be done only on the - first write()). */ + if (fd >= 0) { + self->fd = fd; + self->closefd = closefd; + } + else { + self->closefd = 1; + if (!closefd) { + PyErr_SetString(PyExc_ValueError, + "Cannot use closefd=False with file name"); + goto error; + } + + errno = 0; + if (opener == Py_None) { + do { + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + self->fd = _wopen(widename, flags, 0666); +#else + self->fd = open(name, flags, 0666); +#endif + Py_END_ALLOW_THREADS + } while (self->fd < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + + if (async_err) + goto error; + } + else { + PyObject *fdobj; + +#ifndef MS_WINDOWS + /* the opener may clear the atomic flag */ + atomic_flag_works = NULL; +#endif + + fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags); + if (fdobj == NULL) + goto error; + if (!PyLong_Check(fdobj)) { + Py_DECREF(fdobj); + PyErr_SetString(PyExc_TypeError, + "expected integer from opener"); + goto error; + } + + self->fd = _PyLong_AsInt(fdobj); + Py_DECREF(fdobj); + if (self->fd < 0) { + if (!PyErr_Occurred()) { + /* The opener returned a negative but didn't set an + exception. See issue #27066 */ + PyErr_Format(PyExc_ValueError, + "opener returned %d", self->fd); + } + goto error; + } + } + + fd_is_own = 1; + if (self->fd < 0) { + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); + goto error; + } + +#ifndef MS_WINDOWS + if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0) + goto error; +#endif + } + + self->blksize = DEFAULT_BUFFER_SIZE; + Py_BEGIN_ALLOW_THREADS + fstat_result = _Py_fstat_noraise(self->fd, &fdfstat); + Py_END_ALLOW_THREADS + if (fstat_result < 0) { + /* Tolerate fstat() errors other than EBADF. See Issue #25717, where + an anonymous file on a Virtual Box shared folder filesystem would + raise ENOENT. */ +#ifdef MS_WINDOWS + if (GetLastError() == ERROR_INVALID_HANDLE) { + PyErr_SetFromWindowsErr(0); +#else + if (errno == EBADF) { + PyErr_SetFromErrno(PyExc_OSError); +#endif + goto error; + } + } + else { +#if defined(S_ISDIR) && defined(EISDIR) + /* On Unix, open will succeed for directories. + In Python, there should be no file objects referring to + directories, so we need a check. */ + if (S_ISDIR(fdfstat.st_mode)) { + errno = EISDIR; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); + goto error; + } +#endif /* defined(S_ISDIR) */ +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE + if (fdfstat.st_blksize > 1) + self->blksize = fdfstat.st_blksize; +#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ + } + +#if defined(MS_WINDOWS) || defined(__CYGWIN__) + /* don't translate newlines (\r\n <=> \n) */ + _setmode(self->fd, O_BINARY); +#endif + + if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0) + goto error; + + if (self->appending) { + /* For consistent behaviour, we explicitly seek to the + end of file (otherwise, it might be done only on the + first write()). */ PyObject *pos = portable_lseek(self, NULL, 2, true); - if (pos == NULL) - goto error; - Py_DECREF(pos); - } - - goto done; - - error: - ret = -1; - if (!fd_is_own) - self->fd = -1; - if (self->fd >= 0) - internal_close(self); - - done: - Py_CLEAR(stringobj); - return ret; -} - -static int -fileio_traverse(fileio *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -fileio_clear(fileio *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -static void -fileio_dealloc(fileio *self) -{ - self->finalizing = 1; - if (_PyIOBase_finalize((PyObject *) self) < 0) - return; - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -err_closed(void) -{ - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); - return NULL; -} - -static PyObject * -err_mode(const char *action) -{ - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_Format(state->unsupported_operation, - "File not open for %s", action); - return NULL; -} - -/*[clinic input] -_io.FileIO.fileno - -Return the underlying file descriptor (an integer). -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_fileno_impl(fileio *self) -/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/ -{ - if (self->fd < 0) - return err_closed(); - return PyLong_FromLong((long) self->fd); -} - -/*[clinic input] -_io.FileIO.readable - -True if file was opened in a read mode. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_readable_impl(fileio *self) -/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/ -{ - if (self->fd < 0) - return err_closed(); - return PyBool_FromLong((long) self->readable); -} - -/*[clinic input] -_io.FileIO.writable - -True if file was opened in a write mode. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_writable_impl(fileio *self) -/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/ -{ - if (self->fd < 0) - return err_closed(); - return PyBool_FromLong((long) self->writable); -} - -/*[clinic input] -_io.FileIO.seekable - -True if file supports random-access. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_seekable_impl(fileio *self) -/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/ -{ - if (self->fd < 0) - return err_closed(); - if (self->seekable < 0) { - /* portable_lseek() sets the seekable attribute */ + if (pos == NULL) + goto error; + Py_DECREF(pos); + } + + goto done; + + error: + ret = -1; + if (!fd_is_own) + self->fd = -1; + if (self->fd >= 0) + internal_close(self); + + done: + Py_CLEAR(stringobj); + return ret; +} + +static int +fileio_traverse(fileio *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +fileio_clear(fileio *self) +{ + Py_CLEAR(self->dict); + return 0; +} + +static void +fileio_dealloc(fileio *self) +{ + self->finalizing = 1; + if (_PyIOBase_finalize((PyObject *) self) < 0) + return; + _PyObject_GC_UNTRACK(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_CLEAR(self->dict); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject * +err_closed(void) +{ + PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); + return NULL; +} + +static PyObject * +err_mode(const char *action) +{ + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_Format(state->unsupported_operation, + "File not open for %s", action); + return NULL; +} + +/*[clinic input] +_io.FileIO.fileno + +Return the underlying file descriptor (an integer). +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_fileno_impl(fileio *self) +/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/ +{ + if (self->fd < 0) + return err_closed(); + return PyLong_FromLong((long) self->fd); +} + +/*[clinic input] +_io.FileIO.readable + +True if file was opened in a read mode. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_readable_impl(fileio *self) +/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/ +{ + if (self->fd < 0) + return err_closed(); + return PyBool_FromLong((long) self->readable); +} + +/*[clinic input] +_io.FileIO.writable + +True if file was opened in a write mode. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_writable_impl(fileio *self) +/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/ +{ + if (self->fd < 0) + return err_closed(); + return PyBool_FromLong((long) self->writable); +} + +/*[clinic input] +_io.FileIO.seekable + +True if file supports random-access. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_seekable_impl(fileio *self) +/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/ +{ + if (self->fd < 0) + return err_closed(); + if (self->seekable < 0) { + /* portable_lseek() sets the seekable attribute */ PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false); - assert(self->seekable >= 0); - if (pos == NULL) { - PyErr_Clear(); - } - else { - Py_DECREF(pos); - } - } - return PyBool_FromLong((long) self->seekable); -} - -/*[clinic input] -_io.FileIO.readinto - buffer: Py_buffer(accept={rwbuffer}) - / - -Same as RawIOBase.readinto(). -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer) -/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/ -{ - Py_ssize_t n; - int err; - - if (self->fd < 0) - return err_closed(); - if (!self->readable) - return err_mode("reading"); - - n = _Py_read(self->fd, buffer->buf, buffer->len); - /* copy errno because PyBuffer_Release() can indirectly modify it */ - err = errno; - - if (n == -1) { - if (err == EAGAIN) { - PyErr_Clear(); - Py_RETURN_NONE; - } - return NULL; - } - - return PyLong_FromSsize_t(n); -} - -static size_t -new_buffersize(fileio *self, size_t currentsize) -{ - size_t addend; - - /* Expand the buffer by an amount proportional to the current size, - giving us amortized linear-time behavior. For bigger sizes, use a - less-than-double growth factor to avoid excessive allocation. */ - assert(currentsize <= PY_SSIZE_T_MAX); - if (currentsize > 65536) - addend = currentsize >> 3; - else - addend = 256 + currentsize; - if (addend < SMALLCHUNK) - /* Avoid tiny read() calls. */ - addend = SMALLCHUNK; - return addend + currentsize; -} - -/*[clinic input] -_io.FileIO.readall - -Read all data from the file, returned as bytes. - -In non-blocking mode, returns as much as is immediately available, -or None if no data is available. Return an empty bytes object at EOF. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_readall_impl(fileio *self) -/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/ -{ - struct _Py_stat_struct status; - Py_off_t pos, end; - PyObject *result; - Py_ssize_t bytes_read = 0; - Py_ssize_t n; - size_t bufsize; - int fstat_result; - - if (self->fd < 0) - return err_closed(); - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef MS_WINDOWS - pos = _lseeki64(self->fd, 0L, SEEK_CUR); -#else - pos = lseek(self->fd, 0L, SEEK_CUR); -#endif - _Py_END_SUPPRESS_IPH - fstat_result = _Py_fstat_noraise(self->fd, &status); - Py_END_ALLOW_THREADS - - if (fstat_result == 0) - end = status.st_size; - else - end = (Py_off_t)-1; - - if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) { - /* This is probably a real file, so we try to allocate a - buffer one byte larger than the rest of the file. If the - calculation is right then we should get EOF without having - to enlarge the buffer. */ - bufsize = (size_t)(end - pos + 1); - } else { - bufsize = SMALLCHUNK; - } - - result = PyBytes_FromStringAndSize(NULL, bufsize); - if (result == NULL) - return NULL; - - while (1) { - if (bytes_read >= (Py_ssize_t)bufsize) { - bufsize = new_buffersize(self, bytes_read); - if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) { - PyErr_SetString(PyExc_OverflowError, - "unbounded read returned more bytes " - "than a Python bytes object can hold"); - Py_DECREF(result); - return NULL; - } - - if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) { - if (_PyBytes_Resize(&result, bufsize) < 0) - return NULL; - } - } - - n = _Py_read(self->fd, - PyBytes_AS_STRING(result) + bytes_read, - bufsize - bytes_read); - - if (n == 0) - break; - if (n == -1) { - if (errno == EAGAIN) { - PyErr_Clear(); - if (bytes_read > 0) - break; - Py_DECREF(result); - Py_RETURN_NONE; - } - Py_DECREF(result); - return NULL; - } - bytes_read += n; - pos += n; - } - - if (PyBytes_GET_SIZE(result) > bytes_read) { - if (_PyBytes_Resize(&result, bytes_read) < 0) - return NULL; - } - return result; -} - -/*[clinic input] -_io.FileIO.read - size: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Read at most size bytes, returned as bytes. - -Only makes one system call, so less data may be returned than requested. -In non-blocking mode, returns None if no data is available. -Return an empty bytes object at EOF. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_read_impl(fileio *self, Py_ssize_t size) -/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/ -{ - char *ptr; - Py_ssize_t n; - PyObject *bytes; - - if (self->fd < 0) - return err_closed(); - if (!self->readable) - return err_mode("reading"); - - if (size < 0) - return _io_FileIO_readall_impl(self); - - if (size > _PY_READ_MAX) { - size = _PY_READ_MAX; - } - - bytes = PyBytes_FromStringAndSize(NULL, size); - if (bytes == NULL) - return NULL; - ptr = PyBytes_AS_STRING(bytes); - - n = _Py_read(self->fd, ptr, size); - if (n == -1) { - /* copy errno because Py_DECREF() can indirectly modify it */ - int err = errno; - Py_DECREF(bytes); - if (err == EAGAIN) { - PyErr_Clear(); - Py_RETURN_NONE; - } - return NULL; - } - - if (n != size) { - if (_PyBytes_Resize(&bytes, n) < 0) { - Py_CLEAR(bytes); - return NULL; - } - } - - return (PyObject *) bytes; -} - -/*[clinic input] -_io.FileIO.write - b: Py_buffer - / - -Write buffer b to file, return number of bytes written. - -Only makes one system call, so not all of the data may be written. -The number of bytes actually written is returned. In non-blocking mode, -returns None if the write would block. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_write_impl(fileio *self, Py_buffer *b) -/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/ -{ - Py_ssize_t n; - int err; - - if (self->fd < 0) - return err_closed(); - if (!self->writable) - return err_mode("writing"); - - n = _Py_write(self->fd, b->buf, b->len); - /* copy errno because PyBuffer_Release() can indirectly modify it */ - err = errno; - - if (n < 0) { - if (err == EAGAIN) { - PyErr_Clear(); - Py_RETURN_NONE; - } - return NULL; - } - - return PyLong_FromSsize_t(n); -} - -/* XXX Windows support below is likely incomplete */ - -/* Cribbed from posix_lseek() */ -static PyObject * + assert(self->seekable >= 0); + if (pos == NULL) { + PyErr_Clear(); + } + else { + Py_DECREF(pos); + } + } + return PyBool_FromLong((long) self->seekable); +} + +/*[clinic input] +_io.FileIO.readinto + buffer: Py_buffer(accept={rwbuffer}) + / + +Same as RawIOBase.readinto(). +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer) +/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/ +{ + Py_ssize_t n; + int err; + + if (self->fd < 0) + return err_closed(); + if (!self->readable) + return err_mode("reading"); + + n = _Py_read(self->fd, buffer->buf, buffer->len); + /* copy errno because PyBuffer_Release() can indirectly modify it */ + err = errno; + + if (n == -1) { + if (err == EAGAIN) { + PyErr_Clear(); + Py_RETURN_NONE; + } + return NULL; + } + + return PyLong_FromSsize_t(n); +} + +static size_t +new_buffersize(fileio *self, size_t currentsize) +{ + size_t addend; + + /* Expand the buffer by an amount proportional to the current size, + giving us amortized linear-time behavior. For bigger sizes, use a + less-than-double growth factor to avoid excessive allocation. */ + assert(currentsize <= PY_SSIZE_T_MAX); + if (currentsize > 65536) + addend = currentsize >> 3; + else + addend = 256 + currentsize; + if (addend < SMALLCHUNK) + /* Avoid tiny read() calls. */ + addend = SMALLCHUNK; + return addend + currentsize; +} + +/*[clinic input] +_io.FileIO.readall + +Read all data from the file, returned as bytes. + +In non-blocking mode, returns as much as is immediately available, +or None if no data is available. Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_readall_impl(fileio *self) +/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/ +{ + struct _Py_stat_struct status; + Py_off_t pos, end; + PyObject *result; + Py_ssize_t bytes_read = 0; + Py_ssize_t n; + size_t bufsize; + int fstat_result; + + if (self->fd < 0) + return err_closed(); + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef MS_WINDOWS + pos = _lseeki64(self->fd, 0L, SEEK_CUR); +#else + pos = lseek(self->fd, 0L, SEEK_CUR); +#endif + _Py_END_SUPPRESS_IPH + fstat_result = _Py_fstat_noraise(self->fd, &status); + Py_END_ALLOW_THREADS + + if (fstat_result == 0) + end = status.st_size; + else + end = (Py_off_t)-1; + + if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) { + /* This is probably a real file, so we try to allocate a + buffer one byte larger than the rest of the file. If the + calculation is right then we should get EOF without having + to enlarge the buffer. */ + bufsize = (size_t)(end - pos + 1); + } else { + bufsize = SMALLCHUNK; + } + + result = PyBytes_FromStringAndSize(NULL, bufsize); + if (result == NULL) + return NULL; + + while (1) { + if (bytes_read >= (Py_ssize_t)bufsize) { + bufsize = new_buffersize(self, bytes_read); + if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) { + PyErr_SetString(PyExc_OverflowError, + "unbounded read returned more bytes " + "than a Python bytes object can hold"); + Py_DECREF(result); + return NULL; + } + + if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) { + if (_PyBytes_Resize(&result, bufsize) < 0) + return NULL; + } + } + + n = _Py_read(self->fd, + PyBytes_AS_STRING(result) + bytes_read, + bufsize - bytes_read); + + if (n == 0) + break; + if (n == -1) { + if (errno == EAGAIN) { + PyErr_Clear(); + if (bytes_read > 0) + break; + Py_DECREF(result); + Py_RETURN_NONE; + } + Py_DECREF(result); + return NULL; + } + bytes_read += n; + pos += n; + } + + if (PyBytes_GET_SIZE(result) > bytes_read) { + if (_PyBytes_Resize(&result, bytes_read) < 0) + return NULL; + } + return result; +} + +/*[clinic input] +_io.FileIO.read + size: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Read at most size bytes, returned as bytes. + +Only makes one system call, so less data may be returned than requested. +In non-blocking mode, returns None if no data is available. +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_read_impl(fileio *self, Py_ssize_t size) +/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/ +{ + char *ptr; + Py_ssize_t n; + PyObject *bytes; + + if (self->fd < 0) + return err_closed(); + if (!self->readable) + return err_mode("reading"); + + if (size < 0) + return _io_FileIO_readall_impl(self); + + if (size > _PY_READ_MAX) { + size = _PY_READ_MAX; + } + + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) + return NULL; + ptr = PyBytes_AS_STRING(bytes); + + n = _Py_read(self->fd, ptr, size); + if (n == -1) { + /* copy errno because Py_DECREF() can indirectly modify it */ + int err = errno; + Py_DECREF(bytes); + if (err == EAGAIN) { + PyErr_Clear(); + Py_RETURN_NONE; + } + return NULL; + } + + if (n != size) { + if (_PyBytes_Resize(&bytes, n) < 0) { + Py_CLEAR(bytes); + return NULL; + } + } + + return (PyObject *) bytes; +} + +/*[clinic input] +_io.FileIO.write + b: Py_buffer + / + +Write buffer b to file, return number of bytes written. + +Only makes one system call, so not all of the data may be written. +The number of bytes actually written is returned. In non-blocking mode, +returns None if the write would block. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_write_impl(fileio *self, Py_buffer *b) +/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/ +{ + Py_ssize_t n; + int err; + + if (self->fd < 0) + return err_closed(); + if (!self->writable) + return err_mode("writing"); + + n = _Py_write(self->fd, b->buf, b->len); + /* copy errno because PyBuffer_Release() can indirectly modify it */ + err = errno; + + if (n < 0) { + if (err == EAGAIN) { + PyErr_Clear(); + Py_RETURN_NONE; + } + return NULL; + } + + return PyLong_FromSsize_t(n); +} + +/* XXX Windows support below is likely incomplete */ + +/* Cribbed from posix_lseek() */ +static PyObject * portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error) -{ - Py_off_t pos, res; - int fd = self->fd; - -#ifdef SEEK_SET - /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ - switch (whence) { -#if SEEK_SET != 0 - case 0: whence = SEEK_SET; break; -#endif -#if SEEK_CUR != 1 - case 1: whence = SEEK_CUR; break; -#endif -#if SEEK_END != 2 - case 2: whence = SEEK_END; break; -#endif - } -#endif /* SEEK_SET */ - - if (posobj == NULL) { - pos = 0; - } - else { - if(PyFloat_Check(posobj)) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return NULL; - } -#if defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLongLong(posobj); -#else - pos = PyLong_AsLong(posobj); -#endif - if (PyErr_Occurred()) - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef MS_WINDOWS - res = _lseeki64(fd, pos, whence); -#else - res = lseek(fd, pos, whence); -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - - if (self->seekable < 0) { - self->seekable = (res >= 0); - } - +{ + Py_off_t pos, res; + int fd = self->fd; + +#ifdef SEEK_SET + /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ + switch (whence) { +#if SEEK_SET != 0 + case 0: whence = SEEK_SET; break; +#endif +#if SEEK_CUR != 1 + case 1: whence = SEEK_CUR; break; +#endif +#if SEEK_END != 2 + case 2: whence = SEEK_END; break; +#endif + } +#endif /* SEEK_SET */ + + if (posobj == NULL) { + pos = 0; + } + else { + if(PyFloat_Check(posobj)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return NULL; + } +#if defined(HAVE_LARGEFILE_SUPPORT) + pos = PyLong_AsLongLong(posobj); +#else + pos = PyLong_AsLong(posobj); +#endif + if (PyErr_Occurred()) + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef MS_WINDOWS + res = _lseeki64(fd, pos, whence); +#else + res = lseek(fd, pos, whence); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + if (self->seekable < 0) { + self->seekable = (res >= 0); + } + if (res < 0) { if (suppress_pipe_error && errno == ESPIPE) { res = 0; @@ -932,310 +932,310 @@ portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_er return PyErr_SetFromErrno(PyExc_OSError); } } - -#if defined(HAVE_LARGEFILE_SUPPORT) - return PyLong_FromLongLong(res); -#else - return PyLong_FromLong(res); -#endif -} - -/*[clinic input] -_io.FileIO.seek - pos: object - whence: int = 0 - / - -Move to new file position and return the file position. - -Argument offset is a byte count. Optional argument whence defaults to -SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values -are SEEK_CUR or 1 (move relative to current position, positive or negative), -and SEEK_END or 2 (move relative to end of file, usually negative, although -many platforms allow seeking beyond the end of a file). - -Note that not all file objects are seekable. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) -/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/ -{ - if (self->fd < 0) - return err_closed(); - + +#if defined(HAVE_LARGEFILE_SUPPORT) + return PyLong_FromLongLong(res); +#else + return PyLong_FromLong(res); +#endif +} + +/*[clinic input] +_io.FileIO.seek + pos: object + whence: int = 0 + / + +Move to new file position and return the file position. + +Argument offset is a byte count. Optional argument whence defaults to +SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values +are SEEK_CUR or 1 (move relative to current position, positive or negative), +and SEEK_END or 2 (move relative to end of file, usually negative, although +many platforms allow seeking beyond the end of a file). + +Note that not all file objects are seekable. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) +/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/ +{ + if (self->fd < 0) + return err_closed(); + return portable_lseek(self, pos, whence, false); -} - -/*[clinic input] -_io.FileIO.tell - -Current file position. - -Can raise OSError for non seekable files. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_tell_impl(fileio *self) -/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/ -{ - if (self->fd < 0) - return err_closed(); - +} + +/*[clinic input] +_io.FileIO.tell + +Current file position. + +Can raise OSError for non seekable files. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_tell_impl(fileio *self) +/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/ +{ + if (self->fd < 0) + return err_closed(); + return portable_lseek(self, NULL, 1, false); -} - -#ifdef HAVE_FTRUNCATE -/*[clinic input] -_io.FileIO.truncate +} + +#ifdef HAVE_FTRUNCATE +/*[clinic input] +_io.FileIO.truncate size as posobj: object = None - / - -Truncate the file to at most size bytes and return the truncated size. - -Size defaults to the current file position, as returned by tell(). -The current file position is changed to the value of size. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_truncate_impl(fileio *self, PyObject *posobj) + / + +Truncate the file to at most size bytes and return the truncated size. + +Size defaults to the current file position, as returned by tell(). +The current file position is changed to the value of size. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_truncate_impl(fileio *self, PyObject *posobj) /*[clinic end generated code: output=e49ca7a916c176fa input=b0ac133939823875]*/ -{ - Py_off_t pos; - int ret; - int fd; - - fd = self->fd; - if (fd < 0) - return err_closed(); - if (!self->writable) - return err_mode("writing"); - +{ + Py_off_t pos; + int ret; + int fd; + + fd = self->fd; + if (fd < 0) + return err_closed(); + if (!self->writable) + return err_mode("writing"); + if (posobj == Py_None) { - /* Get the current position. */ + /* Get the current position. */ posobj = portable_lseek(self, NULL, 1, false); - if (posobj == NULL) - return NULL; - } - else { - Py_INCREF(posobj); - } - -#if defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLongLong(posobj); -#else - pos = PyLong_AsLong(posobj); -#endif - if (PyErr_Occurred()){ - Py_DECREF(posobj); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - errno = 0; -#ifdef MS_WINDOWS - ret = _chsize_s(fd, pos); -#else - ret = ftruncate(fd, pos); -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - - if (ret != 0) { - Py_DECREF(posobj); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - return posobj; -} -#endif /* HAVE_FTRUNCATE */ - -static const char * -mode_string(fileio *self) -{ - if (self->created) { - if (self->readable) - return "xb+"; - else - return "xb"; - } - if (self->appending) { - if (self->readable) - return "ab+"; - else - return "ab"; - } - else if (self->readable) { - if (self->writable) - return "rb+"; - else - return "rb"; - } - else - return "wb"; -} - -static PyObject * -fileio_repr(fileio *self) -{ - PyObject *nameobj, *res; - - if (self->fd < 0) - return PyUnicode_FromFormat("<_io.FileIO [closed]>"); - - if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { - return NULL; - } - if (nameobj == NULL) { - res = PyUnicode_FromFormat( - "<_io.FileIO fd=%d mode='%s' closefd=%s>", - self->fd, mode_string(self), self->closefd ? "True" : "False"); - } - else { - int status = Py_ReprEnter((PyObject *)self); - res = NULL; - if (status == 0) { - res = PyUnicode_FromFormat( - "<_io.FileIO name=%R mode='%s' closefd=%s>", - nameobj, mode_string(self), self->closefd ? "True" : "False"); - Py_ReprLeave((PyObject *)self); - } - else if (status > 0) { - PyErr_Format(PyExc_RuntimeError, - "reentrant call inside %s.__repr__", - Py_TYPE(self)->tp_name); - } - Py_DECREF(nameobj); - } - return res; -} - -/*[clinic input] -_io.FileIO.isatty - -True if the file is connected to a TTY device. -[clinic start generated code]*/ - -static PyObject * -_io_FileIO_isatty_impl(fileio *self) -/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/ -{ - long res; - - if (self->fd < 0) - return err_closed(); - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - res = isatty(self->fd); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - return PyBool_FromLong(res); -} - -#include "clinic/fileio.c.h" - -static PyMethodDef fileio_methods[] = { - _IO_FILEIO_READ_METHODDEF - _IO_FILEIO_READALL_METHODDEF - _IO_FILEIO_READINTO_METHODDEF - _IO_FILEIO_WRITE_METHODDEF - _IO_FILEIO_SEEK_METHODDEF - _IO_FILEIO_TELL_METHODDEF - _IO_FILEIO_TRUNCATE_METHODDEF - _IO_FILEIO_CLOSE_METHODDEF - _IO_FILEIO_SEEKABLE_METHODDEF - _IO_FILEIO_READABLE_METHODDEF - _IO_FILEIO_WRITABLE_METHODDEF - _IO_FILEIO_FILENO_METHODDEF - _IO_FILEIO_ISATTY_METHODDEF - {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL}, - {NULL, NULL} /* sentinel */ -}; - -/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */ - -static PyObject * -get_closed(fileio *self, void *closure) -{ - return PyBool_FromLong((long)(self->fd < 0)); -} - -static PyObject * -get_closefd(fileio *self, void *closure) -{ - return PyBool_FromLong((long)(self->closefd)); -} - -static PyObject * -get_mode(fileio *self, void *closure) -{ - return PyUnicode_FromString(mode_string(self)); -} - -static PyGetSetDef fileio_getsetlist[] = { - {"closed", (getter)get_closed, NULL, "True if the file is closed"}, - {"closefd", (getter)get_closefd, NULL, - "True if the file descriptor will be closed by close()."}, - {"mode", (getter)get_mode, NULL, "String giving the file mode"}, - {NULL}, -}; - -static PyMemberDef fileio_members[] = { - {"_blksize", T_UINT, offsetof(fileio, blksize), 0}, - {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0}, - {NULL} -}; - -PyTypeObject PyFileIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.FileIO", - sizeof(fileio), - 0, - (destructor)fileio_dealloc, /* tp_dealloc */ + if (posobj == NULL) + return NULL; + } + else { + Py_INCREF(posobj); + } + +#if defined(HAVE_LARGEFILE_SUPPORT) + pos = PyLong_AsLongLong(posobj); +#else + pos = PyLong_AsLong(posobj); +#endif + if (PyErr_Occurred()){ + Py_DECREF(posobj); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + errno = 0; +#ifdef MS_WINDOWS + ret = _chsize_s(fd, pos); +#else + ret = ftruncate(fd, pos); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + if (ret != 0) { + Py_DECREF(posobj); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + return posobj; +} +#endif /* HAVE_FTRUNCATE */ + +static const char * +mode_string(fileio *self) +{ + if (self->created) { + if (self->readable) + return "xb+"; + else + return "xb"; + } + if (self->appending) { + if (self->readable) + return "ab+"; + else + return "ab"; + } + else if (self->readable) { + if (self->writable) + return "rb+"; + else + return "rb"; + } + else + return "wb"; +} + +static PyObject * +fileio_repr(fileio *self) +{ + PyObject *nameobj, *res; + + if (self->fd < 0) + return PyUnicode_FromFormat("<_io.FileIO [closed]>"); + + if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { + return NULL; + } + if (nameobj == NULL) { + res = PyUnicode_FromFormat( + "<_io.FileIO fd=%d mode='%s' closefd=%s>", + self->fd, mode_string(self), self->closefd ? "True" : "False"); + } + else { + int status = Py_ReprEnter((PyObject *)self); + res = NULL; + if (status == 0) { + res = PyUnicode_FromFormat( + "<_io.FileIO name=%R mode='%s' closefd=%s>", + nameobj, mode_string(self), self->closefd ? "True" : "False"); + Py_ReprLeave((PyObject *)self); + } + else if (status > 0) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s.__repr__", + Py_TYPE(self)->tp_name); + } + Py_DECREF(nameobj); + } + return res; +} + +/*[clinic input] +_io.FileIO.isatty + +True if the file is connected to a TTY device. +[clinic start generated code]*/ + +static PyObject * +_io_FileIO_isatty_impl(fileio *self) +/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/ +{ + long res; + + if (self->fd < 0) + return err_closed(); + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + res = isatty(self->fd); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + return PyBool_FromLong(res); +} + +#include "clinic/fileio.c.h" + +static PyMethodDef fileio_methods[] = { + _IO_FILEIO_READ_METHODDEF + _IO_FILEIO_READALL_METHODDEF + _IO_FILEIO_READINTO_METHODDEF + _IO_FILEIO_WRITE_METHODDEF + _IO_FILEIO_SEEK_METHODDEF + _IO_FILEIO_TELL_METHODDEF + _IO_FILEIO_TRUNCATE_METHODDEF + _IO_FILEIO_CLOSE_METHODDEF + _IO_FILEIO_SEEKABLE_METHODDEF + _IO_FILEIO_READABLE_METHODDEF + _IO_FILEIO_WRITABLE_METHODDEF + _IO_FILEIO_FILENO_METHODDEF + _IO_FILEIO_ISATTY_METHODDEF + {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL}, + {NULL, NULL} /* sentinel */ +}; + +/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */ + +static PyObject * +get_closed(fileio *self, void *closure) +{ + return PyBool_FromLong((long)(self->fd < 0)); +} + +static PyObject * +get_closefd(fileio *self, void *closure) +{ + return PyBool_FromLong((long)(self->closefd)); +} + +static PyObject * +get_mode(fileio *self, void *closure) +{ + return PyUnicode_FromString(mode_string(self)); +} + +static PyGetSetDef fileio_getsetlist[] = { + {"closed", (getter)get_closed, NULL, "True if the file is closed"}, + {"closefd", (getter)get_closefd, NULL, + "True if the file descriptor will be closed by close()."}, + {"mode", (getter)get_mode, NULL, "String giving the file mode"}, + {NULL}, +}; + +static PyMemberDef fileio_members[] = { + {"_blksize", T_UINT, offsetof(fileio, blksize), 0}, + {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0}, + {NULL} +}; + +PyTypeObject PyFileIO_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.FileIO", + sizeof(fileio), + 0, + (destructor)fileio_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)fileio_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + (reprfunc)fileio_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - _io_FileIO___init____doc__, /* tp_doc */ - (traverseproc)fileio_traverse, /* tp_traverse */ - (inquiry)fileio_clear, /* tp_clear */ - 0, /* tp_richcompare */ + _io_FileIO___init____doc__, /* tp_doc */ + (traverseproc)fileio_traverse, /* tp_traverse */ + (inquiry)fileio_clear, /* tp_clear */ + 0, /* tp_richcompare */ offsetof(fileio, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - fileio_methods, /* tp_methods */ - fileio_members, /* tp_members */ - fileio_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + fileio_methods, /* tp_methods */ + fileio_members, /* tp_members */ + fileio_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ offsetof(fileio, dict), /* tp_dictoffset */ - _io_FileIO___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - fileio_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; + _io_FileIO___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + fileio_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; diff --git a/contrib/tools/python3/src/Modules/_io/iobase.c b/contrib/tools/python3/src/Modules/_io/iobase.c index a8e55c34799..dab8eda4f10 100644 --- a/contrib/tools/python3/src/Modules/_io/iobase.c +++ b/contrib/tools/python3/src/Modules/_io/iobase.c @@ -1,290 +1,290 @@ -/* - An implementation of the I/O abstract base classes hierarchy - as defined by PEP 3116 - "New I/O" - - Classes defined here: IOBase, RawIOBase. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - - -#define PY_SSIZE_T_CLEAN -#include "Python.h" +/* + An implementation of the I/O abstract base classes hierarchy + as defined by PEP 3116 - "New I/O" + + Classes defined here: IOBase, RawIOBase. + + Written by Amaury Forgeot d'Arc and Antoine Pitrou +*/ + + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include "pycore_object.h" #include // offsetof() -#include "_iomodule.h" - -/*[clinic input] -module _io -class _io._IOBase "PyObject *" "&PyIOBase_Type" -class _io._RawIOBase "PyObject *" "&PyRawIOBase_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d29a4d076c2b211c]*/ - -/* - * IOBase class, an abstract class - */ - -typedef struct { - PyObject_HEAD - - PyObject *dict; - PyObject *weakreflist; -} iobase; - -PyDoc_STRVAR(iobase_doc, - "The abstract base class for all I/O classes, acting on streams of\n" - "bytes. There is no public constructor.\n" - "\n" - "This class provides dummy implementations for many methods that\n" - "derived classes can override selectively; the default implementations\n" - "represent a file that cannot be read, written or seeked.\n" - "\n" - "Even though IOBase does not declare read, readinto, or write because\n" - "their signatures will vary, implementations and clients should\n" - "consider those methods part of the interface. Also, implementations\n" - "may raise UnsupportedOperation when operations they do not support are\n" - "called.\n" - "\n" - "The basic type used for binary data read from or written to a file is\n" - "bytes. Other bytes-like objects are accepted as method arguments too.\n" - "In some cases (such as readinto), a writable object is required. Text\n" - "I/O classes work with str data.\n" - "\n" - "Note that calling any method (except additional calls to close(),\n" - "which are ignored) on a closed stream should raise a ValueError.\n" - "\n" - "IOBase (and its subclasses) support the iterator protocol, meaning\n" - "that an IOBase object can be iterated over yielding the lines in a\n" - "stream.\n" - "\n" - "IOBase also supports the :keyword:`with` statement. In this example,\n" - "fp is closed after the suite of the with statement is complete:\n" - "\n" - "with open('spam.txt', 'r') as fp:\n" - " fp.write('Spam and eggs!')\n"); - -/* Use this macro whenever you want to check the internal `closed` status - of the IOBase object rather than the virtual `closed` attribute as returned - by whatever subclass. */ - -_Py_IDENTIFIER(__IOBase_closed); -_Py_IDENTIFIER(read); - - -/* Internal methods */ -static PyObject * -iobase_unsupported(const char *message) -{ - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_SetString(state->unsupported_operation, message); - return NULL; -} - -/* Positioning */ - -PyDoc_STRVAR(iobase_seek_doc, - "Change stream position.\n" - "\n" - "Change the stream position to the given byte offset. The offset is\n" - "interpreted relative to the position indicated by whence. Values\n" - "for whence are:\n" - "\n" - "* 0 -- start of stream (the default); offset should be zero or positive\n" - "* 1 -- current stream position; offset may be negative\n" - "* 2 -- end of stream; offset is usually negative\n" - "\n" - "Return the new absolute position."); - -static PyObject * -iobase_seek(PyObject *self, PyObject *args) -{ - return iobase_unsupported("seek"); -} - -/*[clinic input] -_io._IOBase.tell - -Return current stream position. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_tell_impl(PyObject *self) -/*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/ -{ - _Py_IDENTIFIER(seek); - - return _PyObject_CallMethodId(self, &PyId_seek, "ii", 0, 1); -} - -PyDoc_STRVAR(iobase_truncate_doc, - "Truncate file to size bytes.\n" - "\n" - "File pointer is left unchanged. Size defaults to the current IO\n" - "position as reported by tell(). Returns the new size."); - -static PyObject * -iobase_truncate(PyObject *self, PyObject *args) -{ - return iobase_unsupported("truncate"); -} - -static int -iobase_is_closed(PyObject *self) -{ - PyObject *res; - int ret; - /* This gets the derived attribute, which is *not* __IOBase_closed - in most cases! */ - ret = _PyObject_LookupAttrId(self, &PyId___IOBase_closed, &res); - Py_XDECREF(res); - return ret; -} - -/* Flush and close methods */ - -/*[clinic input] -_io._IOBase.flush - -Flush write buffers, if applicable. - -This is not implemented for read-only and non-blocking streams. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_flush_impl(PyObject *self) -/*[clinic end generated code: output=7cef4b4d54656a3b input=773be121abe270aa]*/ -{ - /* XXX Should this return the number of bytes written??? */ - int closed = iobase_is_closed(self); - - if (!closed) { - Py_RETURN_NONE; - } - if (closed > 0) { - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); - } - return NULL; -} - -static PyObject * -iobase_closed_get(PyObject *self, void *context) -{ - int closed = iobase_is_closed(self); - if (closed < 0) { - return NULL; - } - return PyBool_FromLong(closed); -} - -static int -iobase_check_closed(PyObject *self) -{ - PyObject *res; - int closed; - /* This gets the derived attribute, which is *not* __IOBase_closed - in most cases! */ - closed = _PyObject_LookupAttr(self, _PyIO_str_closed, &res); - if (closed > 0) { - closed = PyObject_IsTrue(res); - Py_DECREF(res); - if (closed > 0) { - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); - return -1; - } - } - return closed; -} - -PyObject * -_PyIOBase_check_closed(PyObject *self, PyObject *args) -{ - if (iobase_check_closed(self)) { - return NULL; - } - if (args == Py_True) { - return Py_None; - } - Py_RETURN_NONE; -} - -/* XXX: IOBase thinks it has to maintain its own internal state in - `__IOBase_closed` and call flush() by itself, but it is redundant with - whatever behaviour a non-trivial derived class will implement. */ - -/*[clinic input] -_io._IOBase.close - -Flush and close the IO object. - -This method has no effect if the file is already closed. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_close_impl(PyObject *self) -/*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/ -{ - PyObject *res, *exc, *val, *tb; - int rc, closed = iobase_is_closed(self); - - if (closed < 0) { - return NULL; - } - if (closed) { - Py_RETURN_NONE; - } - +#include "_iomodule.h" + +/*[clinic input] +module _io +class _io._IOBase "PyObject *" "&PyIOBase_Type" +class _io._RawIOBase "PyObject *" "&PyRawIOBase_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d29a4d076c2b211c]*/ + +/* + * IOBase class, an abstract class + */ + +typedef struct { + PyObject_HEAD + + PyObject *dict; + PyObject *weakreflist; +} iobase; + +PyDoc_STRVAR(iobase_doc, + "The abstract base class for all I/O classes, acting on streams of\n" + "bytes. There is no public constructor.\n" + "\n" + "This class provides dummy implementations for many methods that\n" + "derived classes can override selectively; the default implementations\n" + "represent a file that cannot be read, written or seeked.\n" + "\n" + "Even though IOBase does not declare read, readinto, or write because\n" + "their signatures will vary, implementations and clients should\n" + "consider those methods part of the interface. Also, implementations\n" + "may raise UnsupportedOperation when operations they do not support are\n" + "called.\n" + "\n" + "The basic type used for binary data read from or written to a file is\n" + "bytes. Other bytes-like objects are accepted as method arguments too.\n" + "In some cases (such as readinto), a writable object is required. Text\n" + "I/O classes work with str data.\n" + "\n" + "Note that calling any method (except additional calls to close(),\n" + "which are ignored) on a closed stream should raise a ValueError.\n" + "\n" + "IOBase (and its subclasses) support the iterator protocol, meaning\n" + "that an IOBase object can be iterated over yielding the lines in a\n" + "stream.\n" + "\n" + "IOBase also supports the :keyword:`with` statement. In this example,\n" + "fp is closed after the suite of the with statement is complete:\n" + "\n" + "with open('spam.txt', 'r') as fp:\n" + " fp.write('Spam and eggs!')\n"); + +/* Use this macro whenever you want to check the internal `closed` status + of the IOBase object rather than the virtual `closed` attribute as returned + by whatever subclass. */ + +_Py_IDENTIFIER(__IOBase_closed); +_Py_IDENTIFIER(read); + + +/* Internal methods */ +static PyObject * +iobase_unsupported(const char *message) +{ + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); + return NULL; +} + +/* Positioning */ + +PyDoc_STRVAR(iobase_seek_doc, + "Change stream position.\n" + "\n" + "Change the stream position to the given byte offset. The offset is\n" + "interpreted relative to the position indicated by whence. Values\n" + "for whence are:\n" + "\n" + "* 0 -- start of stream (the default); offset should be zero or positive\n" + "* 1 -- current stream position; offset may be negative\n" + "* 2 -- end of stream; offset is usually negative\n" + "\n" + "Return the new absolute position."); + +static PyObject * +iobase_seek(PyObject *self, PyObject *args) +{ + return iobase_unsupported("seek"); +} + +/*[clinic input] +_io._IOBase.tell + +Return current stream position. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_tell_impl(PyObject *self) +/*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/ +{ + _Py_IDENTIFIER(seek); + + return _PyObject_CallMethodId(self, &PyId_seek, "ii", 0, 1); +} + +PyDoc_STRVAR(iobase_truncate_doc, + "Truncate file to size bytes.\n" + "\n" + "File pointer is left unchanged. Size defaults to the current IO\n" + "position as reported by tell(). Returns the new size."); + +static PyObject * +iobase_truncate(PyObject *self, PyObject *args) +{ + return iobase_unsupported("truncate"); +} + +static int +iobase_is_closed(PyObject *self) +{ + PyObject *res; + int ret; + /* This gets the derived attribute, which is *not* __IOBase_closed + in most cases! */ + ret = _PyObject_LookupAttrId(self, &PyId___IOBase_closed, &res); + Py_XDECREF(res); + return ret; +} + +/* Flush and close methods */ + +/*[clinic input] +_io._IOBase.flush + +Flush write buffers, if applicable. + +This is not implemented for read-only and non-blocking streams. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_flush_impl(PyObject *self) +/*[clinic end generated code: output=7cef4b4d54656a3b input=773be121abe270aa]*/ +{ + /* XXX Should this return the number of bytes written??? */ + int closed = iobase_is_closed(self); + + if (!closed) { + Py_RETURN_NONE; + } + if (closed > 0) { + PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); + } + return NULL; +} + +static PyObject * +iobase_closed_get(PyObject *self, void *context) +{ + int closed = iobase_is_closed(self); + if (closed < 0) { + return NULL; + } + return PyBool_FromLong(closed); +} + +static int +iobase_check_closed(PyObject *self) +{ + PyObject *res; + int closed; + /* This gets the derived attribute, which is *not* __IOBase_closed + in most cases! */ + closed = _PyObject_LookupAttr(self, _PyIO_str_closed, &res); + if (closed > 0) { + closed = PyObject_IsTrue(res); + Py_DECREF(res); + if (closed > 0) { + PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); + return -1; + } + } + return closed; +} + +PyObject * +_PyIOBase_check_closed(PyObject *self, PyObject *args) +{ + if (iobase_check_closed(self)) { + return NULL; + } + if (args == Py_True) { + return Py_None; + } + Py_RETURN_NONE; +} + +/* XXX: IOBase thinks it has to maintain its own internal state in + `__IOBase_closed` and call flush() by itself, but it is redundant with + whatever behaviour a non-trivial derived class will implement. */ + +/*[clinic input] +_io._IOBase.close + +Flush and close the IO object. + +This method has no effect if the file is already closed. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_close_impl(PyObject *self) +/*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/ +{ + PyObject *res, *exc, *val, *tb; + int rc, closed = iobase_is_closed(self); + + if (closed < 0) { + return NULL; + } + if (closed) { + Py_RETURN_NONE; + } + res = PyObject_CallMethodNoArgs(self, _PyIO_str_flush); - - PyErr_Fetch(&exc, &val, &tb); - rc = _PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True); - _PyErr_ChainExceptions(exc, val, tb); - if (rc < 0) { - Py_CLEAR(res); - } - - if (res == NULL) - return NULL; - - Py_DECREF(res); - Py_RETURN_NONE; -} - -/* Finalization and garbage collection support */ - -static void -iobase_finalize(PyObject *self) -{ - PyObject *res; - PyObject *error_type, *error_value, *error_traceback; - int closed; - _Py_IDENTIFIER(_finalizing); - - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - /* If `closed` doesn't exist or can't be evaluated as bool, then the - object is probably in an unusable state, so ignore. */ - if (_PyObject_LookupAttr(self, _PyIO_str_closed, &res) <= 0) { - PyErr_Clear(); - closed = -1; - } - else { - closed = PyObject_IsTrue(res); - Py_DECREF(res); - if (closed == -1) - PyErr_Clear(); - } - if (closed == 0) { - /* Signal close() that it was called as part of the object - finalization process. */ - if (_PyObject_SetAttrId(self, &PyId__finalizing, Py_True)) - PyErr_Clear(); + + PyErr_Fetch(&exc, &val, &tb); + rc = _PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True); + _PyErr_ChainExceptions(exc, val, tb); + if (rc < 0) { + Py_CLEAR(res); + } + + if (res == NULL) + return NULL; + + Py_DECREF(res); + Py_RETURN_NONE; +} + +/* Finalization and garbage collection support */ + +static void +iobase_finalize(PyObject *self) +{ + PyObject *res; + PyObject *error_type, *error_value, *error_traceback; + int closed; + _Py_IDENTIFIER(_finalizing); + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + /* If `closed` doesn't exist or can't be evaluated as bool, then the + object is probably in an unusable state, so ignore. */ + if (_PyObject_LookupAttr(self, _PyIO_str_closed, &res) <= 0) { + PyErr_Clear(); + closed = -1; + } + else { + closed = PyObject_IsTrue(res); + Py_DECREF(res); + if (closed == -1) + PyErr_Clear(); + } + if (closed == 0) { + /* Signal close() that it was called as part of the object + finalization process. */ + if (_PyObject_SetAttrId(self, &PyId__finalizing, Py_True)) + PyErr_Clear(); res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_close); - /* Silencing I/O errors is bad, but printing spurious tracebacks is - equally as bad, and potentially more frequent (because of - shutdown issues). */ + /* Silencing I/O errors is bad, but printing spurious tracebacks is + equally as bad, and potentially more frequent (because of + shutdown issues). */ if (res == NULL) { #ifndef Py_DEBUG if (_Py_GetConfig()->dev_mode) { @@ -298,784 +298,784 @@ iobase_finalize(PyObject *self) #endif } else { - Py_DECREF(res); + Py_DECREF(res); } - } - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); -} - -int -_PyIOBase_finalize(PyObject *self) -{ - int is_zombie; - - /* If _PyIOBase_finalize() is called from a destructor, we need to - resurrect the object as calling close() can invoke arbitrary code. */ - is_zombie = (Py_REFCNT(self) == 0); - if (is_zombie) - return PyObject_CallFinalizerFromDealloc(self); - else { - PyObject_CallFinalizer(self); - return 0; - } -} - -static int -iobase_traverse(iobase *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -iobase_clear(iobase *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -/* Destructor */ - -static void -iobase_dealloc(iobase *self) -{ - /* NOTE: since IOBaseObject has its own dict, Python-defined attributes - are still available here for close() to use. - However, if the derived class declares a __slots__, those slots are - already gone. - */ - if (_PyIOBase_finalize((PyObject *) self) < 0) { - /* When called from a heap type's dealloc, the type will be - decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */ - if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) - Py_INCREF(Py_TYPE(self)); - return; - } - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); -} - -/* Inquiry methods */ - -/*[clinic input] -_io._IOBase.seekable - -Return whether object supports random access. - -If False, seek(), tell() and truncate() will raise OSError. -This method may need to do a test seek(). -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_seekable_impl(PyObject *self) -/*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/ -{ - Py_RETURN_FALSE; -} - -PyObject * -_PyIOBase_check_seekable(PyObject *self, PyObject *args) -{ + } + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +int +_PyIOBase_finalize(PyObject *self) +{ + int is_zombie; + + /* If _PyIOBase_finalize() is called from a destructor, we need to + resurrect the object as calling close() can invoke arbitrary code. */ + is_zombie = (Py_REFCNT(self) == 0); + if (is_zombie) + return PyObject_CallFinalizerFromDealloc(self); + else { + PyObject_CallFinalizer(self); + return 0; + } +} + +static int +iobase_traverse(iobase *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +iobase_clear(iobase *self) +{ + Py_CLEAR(self->dict); + return 0; +} + +/* Destructor */ + +static void +iobase_dealloc(iobase *self) +{ + /* NOTE: since IOBaseObject has its own dict, Python-defined attributes + are still available here for close() to use. + However, if the derived class declares a __slots__, those slots are + already gone. + */ + if (_PyIOBase_finalize((PyObject *) self) < 0) { + /* When called from a heap type's dealloc, the type will be + decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */ + if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) + Py_INCREF(Py_TYPE(self)); + return; + } + _PyObject_GC_UNTRACK(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_CLEAR(self->dict); + Py_TYPE(self)->tp_free((PyObject *) self); +} + +/* Inquiry methods */ + +/*[clinic input] +_io._IOBase.seekable + +Return whether object supports random access. + +If False, seek(), tell() and truncate() will raise OSError. +This method may need to do a test seek(). +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_seekable_impl(PyObject *self) +/*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/ +{ + Py_RETURN_FALSE; +} + +PyObject * +_PyIOBase_check_seekable(PyObject *self, PyObject *args) +{ PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_seekable); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - iobase_unsupported("File or stream is not seekable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -/*[clinic input] -_io._IOBase.readable - -Return whether object was opened for reading. - -If False, read() will raise OSError. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_readable_impl(PyObject *self) -/*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/ -{ - Py_RETURN_FALSE; -} - -/* May be called with any object */ -PyObject * -_PyIOBase_check_readable(PyObject *self, PyObject *args) -{ + if (res == NULL) + return NULL; + if (res != Py_True) { + Py_CLEAR(res); + iobase_unsupported("File or stream is not seekable."); + return NULL; + } + if (args == Py_True) { + Py_DECREF(res); + } + return res; +} + +/*[clinic input] +_io._IOBase.readable + +Return whether object was opened for reading. + +If False, read() will raise OSError. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_readable_impl(PyObject *self) +/*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/ +{ + Py_RETURN_FALSE; +} + +/* May be called with any object */ +PyObject * +_PyIOBase_check_readable(PyObject *self, PyObject *args) +{ PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_readable); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - iobase_unsupported("File or stream is not readable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -/*[clinic input] -_io._IOBase.writable - -Return whether object was opened for writing. - -If False, write() will raise OSError. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_writable_impl(PyObject *self) -/*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/ -{ - Py_RETURN_FALSE; -} - -/* May be called with any object */ -PyObject * -_PyIOBase_check_writable(PyObject *self, PyObject *args) -{ + if (res == NULL) + return NULL; + if (res != Py_True) { + Py_CLEAR(res); + iobase_unsupported("File or stream is not readable."); + return NULL; + } + if (args == Py_True) { + Py_DECREF(res); + } + return res; +} + +/*[clinic input] +_io._IOBase.writable + +Return whether object was opened for writing. + +If False, write() will raise OSError. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_writable_impl(PyObject *self) +/*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/ +{ + Py_RETURN_FALSE; +} + +/* May be called with any object */ +PyObject * +_PyIOBase_check_writable(PyObject *self, PyObject *args) +{ PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_writable); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - iobase_unsupported("File or stream is not writable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -/* Context manager */ - -static PyObject * -iobase_enter(PyObject *self, PyObject *args) -{ - if (iobase_check_closed(self)) - return NULL; - - Py_INCREF(self); - return self; -} - -static PyObject * -iobase_exit(PyObject *self, PyObject *args) -{ + if (res == NULL) + return NULL; + if (res != Py_True) { + Py_CLEAR(res); + iobase_unsupported("File or stream is not writable."); + return NULL; + } + if (args == Py_True) { + Py_DECREF(res); + } + return res; +} + +/* Context manager */ + +static PyObject * +iobase_enter(PyObject *self, PyObject *args) +{ + if (iobase_check_closed(self)) + return NULL; + + Py_INCREF(self); + return self; +} + +static PyObject * +iobase_exit(PyObject *self, PyObject *args) +{ return PyObject_CallMethodNoArgs(self, _PyIO_str_close); -} - -/* Lower-level APIs */ - -/* XXX Should these be present even if unimplemented? */ - -/*[clinic input] -_io._IOBase.fileno - -Returns underlying file descriptor if one exists. - -OSError is raised if the IO object does not use a file descriptor. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_fileno_impl(PyObject *self) -/*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/ -{ - return iobase_unsupported("fileno"); -} - -/*[clinic input] -_io._IOBase.isatty - -Return whether this is an 'interactive' stream. - -Return False if it can't be determined. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_isatty_impl(PyObject *self) -/*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/ -{ - if (iobase_check_closed(self)) - return NULL; - Py_RETURN_FALSE; -} - -/* Readline(s) and writelines */ - -/*[clinic input] -_io._IOBase.readline - size as limit: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Read and return a line from the stream. - -If size is specified, at most size bytes will be read. - -The line terminator is always b'\n' for binary files; for text -files, the newlines argument to open can be used to select the line -terminator(s) recognized. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) -/*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/ -{ - /* For backwards compatibility, a (slowish) readline(). */ - - PyObject *peek, *buffer, *result; - Py_ssize_t old_size = -1; - - if (_PyObject_LookupAttr(self, _PyIO_str_peek, &peek) < 0) { - return NULL; - } - - buffer = PyByteArray_FromStringAndSize(NULL, 0); - if (buffer == NULL) { - Py_XDECREF(peek); - return NULL; - } - - while (limit < 0 || PyByteArray_GET_SIZE(buffer) < limit) { - Py_ssize_t nreadahead = 1; - PyObject *b; - - if (peek != NULL) { +} + +/* Lower-level APIs */ + +/* XXX Should these be present even if unimplemented? */ + +/*[clinic input] +_io._IOBase.fileno + +Returns underlying file descriptor if one exists. + +OSError is raised if the IO object does not use a file descriptor. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_fileno_impl(PyObject *self) +/*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/ +{ + return iobase_unsupported("fileno"); +} + +/*[clinic input] +_io._IOBase.isatty + +Return whether this is an 'interactive' stream. + +Return False if it can't be determined. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_isatty_impl(PyObject *self) +/*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/ +{ + if (iobase_check_closed(self)) + return NULL; + Py_RETURN_FALSE; +} + +/* Readline(s) and writelines */ + +/*[clinic input] +_io._IOBase.readline + size as limit: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Read and return a line from the stream. + +If size is specified, at most size bytes will be read. + +The line terminator is always b'\n' for binary files; for text +files, the newlines argument to open can be used to select the line +terminator(s) recognized. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) +/*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/ +{ + /* For backwards compatibility, a (slowish) readline(). */ + + PyObject *peek, *buffer, *result; + Py_ssize_t old_size = -1; + + if (_PyObject_LookupAttr(self, _PyIO_str_peek, &peek) < 0) { + return NULL; + } + + buffer = PyByteArray_FromStringAndSize(NULL, 0); + if (buffer == NULL) { + Py_XDECREF(peek); + return NULL; + } + + while (limit < 0 || PyByteArray_GET_SIZE(buffer) < limit) { + Py_ssize_t nreadahead = 1; + PyObject *b; + + if (peek != NULL) { PyObject *readahead = PyObject_CallOneArg(peek, _PyLong_One); - if (readahead == NULL) { - /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() - when EINTR occurs so we needn't do it ourselves. */ - if (_PyIO_trap_eintr()) { - continue; - } - goto fail; - } - if (!PyBytes_Check(readahead)) { - PyErr_Format(PyExc_OSError, - "peek() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(readahead)->tp_name); - Py_DECREF(readahead); - goto fail; - } - if (PyBytes_GET_SIZE(readahead) > 0) { - Py_ssize_t n = 0; - const char *buf = PyBytes_AS_STRING(readahead); - if (limit >= 0) { - do { - if (n >= PyBytes_GET_SIZE(readahead) || n >= limit) - break; - if (buf[n++] == '\n') - break; - } while (1); - } - else { - do { - if (n >= PyBytes_GET_SIZE(readahead)) - break; - if (buf[n++] == '\n') - break; - } while (1); - } - nreadahead = n; - } - Py_DECREF(readahead); - } - - b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead); - if (b == NULL) { - /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() - when EINTR occurs so we needn't do it ourselves. */ - if (_PyIO_trap_eintr()) { - continue; - } - goto fail; - } - if (!PyBytes_Check(b)) { - PyErr_Format(PyExc_OSError, - "read() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(b)->tp_name); - Py_DECREF(b); - goto fail; - } - if (PyBytes_GET_SIZE(b) == 0) { - Py_DECREF(b); - break; - } - - old_size = PyByteArray_GET_SIZE(buffer); - if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) { - Py_DECREF(b); - goto fail; - } - memcpy(PyByteArray_AS_STRING(buffer) + old_size, - PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b)); - - Py_DECREF(b); - - if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n') - break; - } - - result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer), - PyByteArray_GET_SIZE(buffer)); - Py_XDECREF(peek); - Py_DECREF(buffer); - return result; - fail: - Py_XDECREF(peek); - Py_DECREF(buffer); - return NULL; -} - -static PyObject * -iobase_iter(PyObject *self) -{ - if (iobase_check_closed(self)) - return NULL; - - Py_INCREF(self); - return self; -} - -static PyObject * -iobase_iternext(PyObject *self) -{ + if (readahead == NULL) { + /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() + when EINTR occurs so we needn't do it ourselves. */ + if (_PyIO_trap_eintr()) { + continue; + } + goto fail; + } + if (!PyBytes_Check(readahead)) { + PyErr_Format(PyExc_OSError, + "peek() should have returned a bytes object, " + "not '%.200s'", Py_TYPE(readahead)->tp_name); + Py_DECREF(readahead); + goto fail; + } + if (PyBytes_GET_SIZE(readahead) > 0) { + Py_ssize_t n = 0; + const char *buf = PyBytes_AS_STRING(readahead); + if (limit >= 0) { + do { + if (n >= PyBytes_GET_SIZE(readahead) || n >= limit) + break; + if (buf[n++] == '\n') + break; + } while (1); + } + else { + do { + if (n >= PyBytes_GET_SIZE(readahead)) + break; + if (buf[n++] == '\n') + break; + } while (1); + } + nreadahead = n; + } + Py_DECREF(readahead); + } + + b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead); + if (b == NULL) { + /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() + when EINTR occurs so we needn't do it ourselves. */ + if (_PyIO_trap_eintr()) { + continue; + } + goto fail; + } + if (!PyBytes_Check(b)) { + PyErr_Format(PyExc_OSError, + "read() should have returned a bytes object, " + "not '%.200s'", Py_TYPE(b)->tp_name); + Py_DECREF(b); + goto fail; + } + if (PyBytes_GET_SIZE(b) == 0) { + Py_DECREF(b); + break; + } + + old_size = PyByteArray_GET_SIZE(buffer); + if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) { + Py_DECREF(b); + goto fail; + } + memcpy(PyByteArray_AS_STRING(buffer) + old_size, + PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b)); + + Py_DECREF(b); + + if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n') + break; + } + + result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer), + PyByteArray_GET_SIZE(buffer)); + Py_XDECREF(peek); + Py_DECREF(buffer); + return result; + fail: + Py_XDECREF(peek); + Py_DECREF(buffer); + return NULL; +} + +static PyObject * +iobase_iter(PyObject *self) +{ + if (iobase_check_closed(self)) + return NULL; + + Py_INCREF(self); + return self; +} + +static PyObject * +iobase_iternext(PyObject *self) +{ PyObject *line = PyObject_CallMethodNoArgs(self, _PyIO_str_readline); - - if (line == NULL) - return NULL; - - if (PyObject_Size(line) <= 0) { - /* Error or empty */ - Py_DECREF(line); - return NULL; - } - - return line; -} - -/*[clinic input] -_io._IOBase.readlines - hint: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Return a list of lines from the stream. - -hint can be specified to control the number of lines read: no more -lines will be read if the total size (in bytes/characters) of all -lines so far exceeds hint. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) -/*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/ -{ - Py_ssize_t length = 0; - PyObject *result, *it = NULL; - - result = PyList_New(0); - if (result == NULL) - return NULL; - - if (hint <= 0) { - /* XXX special-casing this made sense in the Python version in order - to remove the bytecode interpretation overhead, but it could - probably be removed here. */ - _Py_IDENTIFIER(extend); - PyObject *ret = _PyObject_CallMethodIdObjArgs(result, &PyId_extend, - self, NULL); - - if (ret == NULL) { - goto error; - } - Py_DECREF(ret); - return result; - } - - it = PyObject_GetIter(self); - if (it == NULL) { - goto error; - } - - while (1) { - Py_ssize_t line_length; - PyObject *line = PyIter_Next(it); - if (line == NULL) { - if (PyErr_Occurred()) { - goto error; - } - else - break; /* StopIteration raised */ - } - - if (PyList_Append(result, line) < 0) { - Py_DECREF(line); - goto error; - } - line_length = PyObject_Size(line); - Py_DECREF(line); - if (line_length < 0) { - goto error; - } - if (line_length > hint - length) - break; - length += line_length; - } - - Py_DECREF(it); - return result; - - error: - Py_XDECREF(it); - Py_DECREF(result); - return NULL; -} - -/*[clinic input] -_io._IOBase.writelines - lines: object - / + + if (line == NULL) + return NULL; + + if (PyObject_Size(line) <= 0) { + /* Error or empty */ + Py_DECREF(line); + return NULL; + } + + return line; +} + +/*[clinic input] +_io._IOBase.readlines + hint: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Return a list of lines from the stream. + +hint can be specified to control the number of lines read: no more +lines will be read if the total size (in bytes/characters) of all +lines so far exceeds hint. +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) +/*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/ +{ + Py_ssize_t length = 0; + PyObject *result, *it = NULL; + + result = PyList_New(0); + if (result == NULL) + return NULL; + + if (hint <= 0) { + /* XXX special-casing this made sense in the Python version in order + to remove the bytecode interpretation overhead, but it could + probably be removed here. */ + _Py_IDENTIFIER(extend); + PyObject *ret = _PyObject_CallMethodIdObjArgs(result, &PyId_extend, + self, NULL); + + if (ret == NULL) { + goto error; + } + Py_DECREF(ret); + return result; + } + + it = PyObject_GetIter(self); + if (it == NULL) { + goto error; + } + + while (1) { + Py_ssize_t line_length; + PyObject *line = PyIter_Next(it); + if (line == NULL) { + if (PyErr_Occurred()) { + goto error; + } + else + break; /* StopIteration raised */ + } + + if (PyList_Append(result, line) < 0) { + Py_DECREF(line); + goto error; + } + line_length = PyObject_Size(line); + Py_DECREF(line); + if (line_length < 0) { + goto error; + } + if (line_length > hint - length) + break; + length += line_length; + } + + Py_DECREF(it); + return result; + + error: + Py_XDECREF(it); + Py_DECREF(result); + return NULL; +} + +/*[clinic input] +_io._IOBase.writelines + lines: object + / Write a list of lines to stream. Line separators are not added, so it is usual for each of the lines provided to have a line separator at the end. -[clinic start generated code]*/ - -static PyObject * -_io__IOBase_writelines(PyObject *self, PyObject *lines) +[clinic start generated code]*/ + +static PyObject * +_io__IOBase_writelines(PyObject *self, PyObject *lines) /*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/ -{ - PyObject *iter, *res; - - if (iobase_check_closed(self)) - return NULL; - - iter = PyObject_GetIter(lines); - if (iter == NULL) - return NULL; - - while (1) { - PyObject *line = PyIter_Next(iter); - if (line == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(iter); - return NULL; - } - else - break; /* Stop Iteration */ - } - - res = NULL; - do { - res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL); - } while (res == NULL && _PyIO_trap_eintr()); - Py_DECREF(line); - if (res == NULL) { - Py_DECREF(iter); - return NULL; - } - Py_DECREF(res); - } - Py_DECREF(iter); - Py_RETURN_NONE; -} - -#include "clinic/iobase.c.h" - -static PyMethodDef iobase_methods[] = { - {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc}, - _IO__IOBASE_TELL_METHODDEF - {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc}, - _IO__IOBASE_FLUSH_METHODDEF - _IO__IOBASE_CLOSE_METHODDEF - - _IO__IOBASE_SEEKABLE_METHODDEF - _IO__IOBASE_READABLE_METHODDEF - _IO__IOBASE_WRITABLE_METHODDEF - - {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS}, - {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS}, - {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS}, - {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS}, - - _IO__IOBASE_FILENO_METHODDEF - _IO__IOBASE_ISATTY_METHODDEF - - {"__enter__", iobase_enter, METH_NOARGS}, - {"__exit__", iobase_exit, METH_VARARGS}, - - _IO__IOBASE_READLINE_METHODDEF - _IO__IOBASE_READLINES_METHODDEF - _IO__IOBASE_WRITELINES_METHODDEF - - {NULL, NULL} -}; - -static PyGetSetDef iobase_getset[] = { - {"__dict__", PyObject_GenericGetDict, NULL, NULL}, - {"closed", (getter)iobase_closed_get, NULL, NULL}, - {NULL} -}; - - -PyTypeObject PyIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._IOBase", /*tp_name*/ - sizeof(iobase), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)iobase_dealloc, /*tp_dealloc*/ +{ + PyObject *iter, *res; + + if (iobase_check_closed(self)) + return NULL; + + iter = PyObject_GetIter(lines); + if (iter == NULL) + return NULL; + + while (1) { + PyObject *line = PyIter_Next(iter); + if (line == NULL) { + if (PyErr_Occurred()) { + Py_DECREF(iter); + return NULL; + } + else + break; /* Stop Iteration */ + } + + res = NULL; + do { + res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL); + } while (res == NULL && _PyIO_trap_eintr()); + Py_DECREF(line); + if (res == NULL) { + Py_DECREF(iter); + return NULL; + } + Py_DECREF(res); + } + Py_DECREF(iter); + Py_RETURN_NONE; +} + +#include "clinic/iobase.c.h" + +static PyMethodDef iobase_methods[] = { + {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc}, + _IO__IOBASE_TELL_METHODDEF + {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc}, + _IO__IOBASE_FLUSH_METHODDEF + _IO__IOBASE_CLOSE_METHODDEF + + _IO__IOBASE_SEEKABLE_METHODDEF + _IO__IOBASE_READABLE_METHODDEF + _IO__IOBASE_WRITABLE_METHODDEF + + {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS}, + {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS}, + {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS}, + {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS}, + + _IO__IOBASE_FILENO_METHODDEF + _IO__IOBASE_ISATTY_METHODDEF + + {"__enter__", iobase_enter, METH_NOARGS}, + {"__exit__", iobase_exit, METH_VARARGS}, + + _IO__IOBASE_READLINE_METHODDEF + _IO__IOBASE_READLINES_METHODDEF + _IO__IOBASE_WRITELINES_METHODDEF + + {NULL, NULL} +}; + +static PyGetSetDef iobase_getset[] = { + {"__dict__", PyObject_GenericGetDict, NULL, NULL}, + {"closed", (getter)iobase_closed_get, NULL, NULL}, + {NULL} +}; + + +PyTypeObject PyIOBase_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io._IOBase", /*tp_name*/ + sizeof(iobase), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)iobase_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - iobase_doc, /* tp_doc */ - (traverseproc)iobase_traverse, /* tp_traverse */ - (inquiry)iobase_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(iobase, weakreflist), /* tp_weaklistoffset */ - iobase_iter, /* tp_iter */ - iobase_iternext, /* tp_iternext */ - iobase_methods, /* tp_methods */ - 0, /* tp_members */ - iobase_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(iobase, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - iobase_finalize, /* tp_finalize */ -}; - - -/* - * RawIOBase class, Inherits from IOBase. - */ -PyDoc_STRVAR(rawiobase_doc, - "Base class for raw binary I/O."); - -/* - * The read() method is implemented by calling readinto(); derived classes - * that want to support read() only need to implement readinto() as a - * primitive operation. In general, readinto() can be more efficient than - * read(). - * - * (It would be tempting to also provide an implementation of readinto() in - * terms of read(), in case the latter is a more suitable primitive operation, - * but that would lead to nasty recursion in case a subclass doesn't implement - * either.) -*/ - -/*[clinic input] -_io._RawIOBase.read - size as n: Py_ssize_t = -1 - / -[clinic start generated code]*/ - -static PyObject * -_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) -/*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/ -{ - PyObject *b, *res; - - if (n < 0) { - _Py_IDENTIFIER(readall); - + iobase_doc, /* tp_doc */ + (traverseproc)iobase_traverse, /* tp_traverse */ + (inquiry)iobase_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(iobase, weakreflist), /* tp_weaklistoffset */ + iobase_iter, /* tp_iter */ + iobase_iternext, /* tp_iternext */ + iobase_methods, /* tp_methods */ + 0, /* tp_members */ + iobase_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(iobase, dict), /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + iobase_finalize, /* tp_finalize */ +}; + + +/* + * RawIOBase class, Inherits from IOBase. + */ +PyDoc_STRVAR(rawiobase_doc, + "Base class for raw binary I/O."); + +/* + * The read() method is implemented by calling readinto(); derived classes + * that want to support read() only need to implement readinto() as a + * primitive operation. In general, readinto() can be more efficient than + * read(). + * + * (It would be tempting to also provide an implementation of readinto() in + * terms of read(), in case the latter is a more suitable primitive operation, + * but that would lead to nasty recursion in case a subclass doesn't implement + * either.) +*/ + +/*[clinic input] +_io._RawIOBase.read + size as n: Py_ssize_t = -1 + / +[clinic start generated code]*/ + +static PyObject * +_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) +/*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/ +{ + PyObject *b, *res; + + if (n < 0) { + _Py_IDENTIFIER(readall); + return _PyObject_CallMethodIdNoArgs(self, &PyId_readall); - } - - /* TODO: allocate a bytes object directly instead and manually construct - a writable memoryview pointing to it. */ - b = PyByteArray_FromStringAndSize(NULL, n); - if (b == NULL) - return NULL; - - res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL); - if (res == NULL || res == Py_None) { - Py_DECREF(b); - return res; - } - - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n == -1 && PyErr_Occurred()) { - Py_DECREF(b); - return NULL; - } - - res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n); - Py_DECREF(b); - return res; -} - - -/*[clinic input] -_io._RawIOBase.readall - -Read until EOF, using multiple read() call. -[clinic start generated code]*/ - -static PyObject * -_io__RawIOBase_readall_impl(PyObject *self) -/*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/ -{ - int r; - PyObject *chunks = PyList_New(0); - PyObject *result; - - if (chunks == NULL) - return NULL; - - while (1) { - PyObject *data = _PyObject_CallMethodId(self, &PyId_read, - "i", DEFAULT_BUFFER_SIZE); - if (!data) { - /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() - when EINTR occurs so we needn't do it ourselves. */ - if (_PyIO_trap_eintr()) { - continue; - } - Py_DECREF(chunks); - return NULL; - } - if (data == Py_None) { - if (PyList_GET_SIZE(chunks) == 0) { - Py_DECREF(chunks); - return data; - } - Py_DECREF(data); - break; - } - if (!PyBytes_Check(data)) { - Py_DECREF(chunks); - Py_DECREF(data); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - return NULL; - } - if (PyBytes_GET_SIZE(data) == 0) { - /* EOF */ - Py_DECREF(data); - break; - } - r = PyList_Append(chunks, data); - Py_DECREF(data); - if (r < 0) { - Py_DECREF(chunks); - return NULL; - } - } - result = _PyBytes_Join(_PyIO_empty_bytes, chunks); - Py_DECREF(chunks); - return result; -} - -static PyObject * -rawiobase_readinto(PyObject *self, PyObject *args) -{ - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; -} - -static PyObject * -rawiobase_write(PyObject *self, PyObject *args) -{ - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; -} - -static PyMethodDef rawiobase_methods[] = { - _IO__RAWIOBASE_READ_METHODDEF - _IO__RAWIOBASE_READALL_METHODDEF - {"readinto", rawiobase_readinto, METH_VARARGS}, - {"write", rawiobase_write, METH_VARARGS}, - {NULL, NULL} -}; - -PyTypeObject PyRawIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._RawIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ + } + + /* TODO: allocate a bytes object directly instead and manually construct + a writable memoryview pointing to it. */ + b = PyByteArray_FromStringAndSize(NULL, n); + if (b == NULL) + return NULL; + + res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL); + if (res == NULL || res == Py_None) { + Py_DECREF(b); + return res; + } + + n = PyNumber_AsSsize_t(res, PyExc_ValueError); + Py_DECREF(res); + if (n == -1 && PyErr_Occurred()) { + Py_DECREF(b); + return NULL; + } + + res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n); + Py_DECREF(b); + return res; +} + + +/*[clinic input] +_io._RawIOBase.readall + +Read until EOF, using multiple read() call. +[clinic start generated code]*/ + +static PyObject * +_io__RawIOBase_readall_impl(PyObject *self) +/*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/ +{ + int r; + PyObject *chunks = PyList_New(0); + PyObject *result; + + if (chunks == NULL) + return NULL; + + while (1) { + PyObject *data = _PyObject_CallMethodId(self, &PyId_read, + "i", DEFAULT_BUFFER_SIZE); + if (!data) { + /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() + when EINTR occurs so we needn't do it ourselves. */ + if (_PyIO_trap_eintr()) { + continue; + } + Py_DECREF(chunks); + return NULL; + } + if (data == Py_None) { + if (PyList_GET_SIZE(chunks) == 0) { + Py_DECREF(chunks); + return data; + } + Py_DECREF(data); + break; + } + if (!PyBytes_Check(data)) { + Py_DECREF(chunks); + Py_DECREF(data); + PyErr_SetString(PyExc_TypeError, "read() should return bytes"); + return NULL; + } + if (PyBytes_GET_SIZE(data) == 0) { + /* EOF */ + Py_DECREF(data); + break; + } + r = PyList_Append(chunks, data); + Py_DECREF(data); + if (r < 0) { + Py_DECREF(chunks); + return NULL; + } + } + result = _PyBytes_Join(_PyIO_empty_bytes, chunks); + Py_DECREF(chunks); + return result; +} + +static PyObject * +rawiobase_readinto(PyObject *self, PyObject *args) +{ + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +} + +static PyObject * +rawiobase_write(PyObject *self, PyObject *args) +{ + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +} + +static PyMethodDef rawiobase_methods[] = { + _IO__RAWIOBASE_READ_METHODDEF + _IO__RAWIOBASE_READALL_METHODDEF + {"readinto", rawiobase_readinto, METH_VARARGS}, + {"write", rawiobase_write, METH_VARARGS}, + {NULL, NULL} +}; + +PyTypeObject PyRawIOBase_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io._RawIOBase", /*tp_name*/ + 0, /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 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_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - rawiobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - rawiobase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; + rawiobase_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + rawiobase_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyIOBase_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; diff --git a/contrib/tools/python3/src/Modules/_io/stringio.c b/contrib/tools/python3/src/Modules/_io/stringio.c index e76152e617b..dedbc18bcca 100644 --- a/contrib/tools/python3/src/Modules/_io/stringio.c +++ b/contrib/tools/python3/src/Modules/_io/stringio.c @@ -1,1044 +1,1044 @@ -#define PY_SSIZE_T_CLEAN -#include "Python.h" +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include // offsetof() #include "pycore_accu.h" #include "pycore_object.h" -#include "_iomodule.h" - -/* Implementation note: the buffer is always at least one character longer - than the enclosed string, for proper functioning of _PyIO_find_line_ending. -*/ - -#define STATE_REALIZED 1 -#define STATE_ACCUMULATING 2 - -/*[clinic input] -module _io -class _io.StringIO "stringio *" "&PyStringIO_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c17bc0f42165cd7d]*/ - -typedef struct { - PyObject_HEAD - Py_UCS4 *buf; - Py_ssize_t pos; - Py_ssize_t string_size; - size_t buf_size; - - /* The stringio object can be in two states: accumulating or realized. - In accumulating state, the internal buffer contains nothing and - the contents are given by the embedded _PyAccu structure. - In realized state, the internal buffer is meaningful and the - _PyAccu is destroyed. - */ - int state; - _PyAccu accu; - - char ok; /* initialized? */ - char closed; - char readuniversal; - char readtranslate; - PyObject *decoder; - PyObject *readnl; - PyObject *writenl; - - PyObject *dict; - PyObject *weakreflist; -} stringio; - -static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs); - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_CLOSED(self) \ - if (self->closed) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file"); \ - return NULL; \ - } - -#define ENSURE_REALIZED(self) \ - if (realize(self) < 0) { \ - return NULL; \ - } - - -/* Internal routine for changing the size, in terms of characters, of the - buffer of StringIO objects. The caller should ensure that the 'size' - argument is non-negative. Returns 0 on success, -1 otherwise. */ -static int -resize_buffer(stringio *self, size_t size) -{ - /* Here, unsigned types are used to avoid dealing with signed integer - overflow, which is undefined in C. */ - size_t alloc = self->buf_size; - Py_UCS4 *new_buf = NULL; - - assert(self->buf != NULL); - - /* Reserve one more char for line ending detection. */ - size = size + 1; - /* For simplicity, stay in the range of the signed type. Anyway, Python - doesn't allow strings to be longer than this. */ - if (size > PY_SSIZE_T_MAX) - goto overflow; - - if (size < alloc / 2) { - /* Major downsize; resize down to exact size. */ - alloc = size + 1; - } - else if (size < alloc) { - /* Within allocated size; quick exit */ - return 0; - } - else if (size <= alloc * 1.125) { - /* Moderate upsize; overallocate similar to list_resize() */ - alloc = size + (size >> 3) + (size < 9 ? 3 : 6); - } - else { - /* Major upsize; resize up to exact size */ - alloc = size + 1; - } - - if (alloc > PY_SIZE_MAX / sizeof(Py_UCS4)) - goto overflow; - new_buf = (Py_UCS4 *)PyMem_Realloc(self->buf, alloc * sizeof(Py_UCS4)); - if (new_buf == NULL) { - PyErr_NoMemory(); - return -1; - } - self->buf_size = alloc; - self->buf = new_buf; - - return 0; - - overflow: - PyErr_SetString(PyExc_OverflowError, - "new buffer size too large"); - return -1; -} - -static PyObject * -make_intermediate(stringio *self) -{ - PyObject *intermediate = _PyAccu_Finish(&self->accu); - self->state = STATE_REALIZED; - if (intermediate == NULL) - return NULL; - if (_PyAccu_Init(&self->accu) || - _PyAccu_Accumulate(&self->accu, intermediate)) { - Py_DECREF(intermediate); - return NULL; - } - self->state = STATE_ACCUMULATING; - return intermediate; -} - -static int -realize(stringio *self) -{ - Py_ssize_t len; - PyObject *intermediate; - - if (self->state == STATE_REALIZED) - return 0; - assert(self->state == STATE_ACCUMULATING); - self->state = STATE_REALIZED; - - intermediate = _PyAccu_Finish(&self->accu); - if (intermediate == NULL) - return -1; - - /* Append the intermediate string to the internal buffer. - The length should be equal to the current cursor position. - */ - len = PyUnicode_GET_LENGTH(intermediate); - if (resize_buffer(self, len) < 0) { - Py_DECREF(intermediate); - return -1; - } - if (!PyUnicode_AsUCS4(intermediate, self->buf, len, 0)) { - Py_DECREF(intermediate); - return -1; - } - - Py_DECREF(intermediate); - return 0; -} - -/* Internal routine for writing a whole PyUnicode object to the buffer of a - StringIO object. Returns 0 on success, or -1 on error. */ -static Py_ssize_t -write_str(stringio *self, PyObject *obj) -{ - Py_ssize_t len; - PyObject *decoded = NULL; - - assert(self->buf != NULL); - assert(self->pos >= 0); - - if (self->decoder != NULL) { - decoded = _PyIncrementalNewlineDecoder_decode( - self->decoder, obj, 1 /* always final */); - } - else { - decoded = obj; - Py_INCREF(decoded); - } - if (self->writenl) { - PyObject *translated = PyUnicode_Replace( - decoded, _PyIO_str_nl, self->writenl, -1); - Py_DECREF(decoded); - decoded = translated; - } - if (decoded == NULL) - return -1; - - assert(PyUnicode_Check(decoded)); - if (PyUnicode_READY(decoded)) { - Py_DECREF(decoded); - return -1; - } - len = PyUnicode_GET_LENGTH(decoded); - assert(len >= 0); - - /* This overflow check is not strictly necessary. However, it avoids us to - deal with funky things like comparing an unsigned and a signed - integer. */ - if (self->pos > PY_SSIZE_T_MAX - len) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - goto fail; - } - - if (self->state == STATE_ACCUMULATING) { - if (self->string_size == self->pos) { - if (_PyAccu_Accumulate(&self->accu, decoded)) - goto fail; - goto success; - } - if (realize(self)) - goto fail; - } - - if (self->pos + len > self->string_size) { - if (resize_buffer(self, self->pos + len) < 0) - goto fail; - } - - if (self->pos > self->string_size) { - /* In case of overseek, pad with null bytes the buffer region between - the end of stream and the current position. - - 0 lo string_size hi - | |<---used--->|<----------available----------->| - | | <--to pad-->|<---to write---> | - 0 buf position - - */ - memset(self->buf + self->string_size, '\0', - (self->pos - self->string_size) * sizeof(Py_UCS4)); - } - - /* Copy the data to the internal buffer, overwriting some of the - existing data if self->pos < self->string_size. */ - if (!PyUnicode_AsUCS4(decoded, - self->buf + self->pos, - self->buf_size - self->pos, - 0)) - goto fail; - -success: - /* Set the new length of the internal string if it has changed. */ - self->pos += len; - if (self->string_size < self->pos) - self->string_size = self->pos; - - Py_DECREF(decoded); - return 0; - -fail: - Py_XDECREF(decoded); - return -1; -} - -/*[clinic input] -_io.StringIO.getvalue - -Retrieve the entire contents of the object. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_getvalue_impl(stringio *self) -/*[clinic end generated code: output=27b6a7bfeaebce01 input=d23cb81d6791cf88]*/ -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - if (self->state == STATE_ACCUMULATING) - return make_intermediate(self); - return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, self->buf, - self->string_size); -} - -/*[clinic input] -_io.StringIO.tell - -Tell the current file position. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_tell_impl(stringio *self) -/*[clinic end generated code: output=2e87ac67b116c77b input=ec866ebaff02f405]*/ -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - return PyLong_FromSsize_t(self->pos); -} - -/*[clinic input] -_io.StringIO.read - size: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Read at most size characters, returned as a string. - -If the argument is negative or omitted, read until EOF -is reached. Return an empty string at EOF. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_read_impl(stringio *self, Py_ssize_t size) -/*[clinic end generated code: output=ae8cf6002f71626c input=0921093383dfb92d]*/ -{ - Py_ssize_t n; - Py_UCS4 *output; - - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - - /* adjust invalid sizes */ - n = self->string_size - self->pos; - if (size < 0 || size > n) { - size = n; - if (size < 0) - size = 0; - } - - /* Optimization for seek(0); read() */ - if (self->state == STATE_ACCUMULATING && self->pos == 0 && size == n) { - PyObject *result = make_intermediate(self); - self->pos = self->string_size; - return result; - } - - ENSURE_REALIZED(self); - output = self->buf + self->pos; - self->pos += size; - return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, size); -} - -/* Internal helper, used by stringio_readline and stringio_iternext */ -static PyObject * -_stringio_readline(stringio *self, Py_ssize_t limit) -{ - Py_UCS4 *start, *end, old_char; - Py_ssize_t len, consumed; - - /* In case of overseek, return the empty string */ - if (self->pos >= self->string_size) - return PyUnicode_New(0, 0); - - start = self->buf + self->pos; - if (limit < 0 || limit > self->string_size - self->pos) - limit = self->string_size - self->pos; - - end = start + limit; - old_char = *end; - *end = '\0'; - len = _PyIO_find_line_ending( - self->readtranslate, self->readuniversal, self->readnl, - PyUnicode_4BYTE_KIND, (char*)start, (char*)end, &consumed); - *end = old_char; - /* If we haven't found any line ending, we just return everything - (`consumed` is ignored). */ - if (len < 0) - len = limit; - self->pos += len; - return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, start, len); -} - -/*[clinic input] -_io.StringIO.readline - size: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Read until newline or EOF. - -Returns an empty string if EOF is hit immediately. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_readline_impl(stringio *self, Py_ssize_t size) -/*[clinic end generated code: output=cabd6452f1b7e85d input=a5bd70bf682aa276]*/ -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - ENSURE_REALIZED(self); - - return _stringio_readline(self, size); -} - -static PyObject * -stringio_iternext(stringio *self) -{ - PyObject *line; - - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - ENSURE_REALIZED(self); - +#include "_iomodule.h" + +/* Implementation note: the buffer is always at least one character longer + than the enclosed string, for proper functioning of _PyIO_find_line_ending. +*/ + +#define STATE_REALIZED 1 +#define STATE_ACCUMULATING 2 + +/*[clinic input] +module _io +class _io.StringIO "stringio *" "&PyStringIO_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c17bc0f42165cd7d]*/ + +typedef struct { + PyObject_HEAD + Py_UCS4 *buf; + Py_ssize_t pos; + Py_ssize_t string_size; + size_t buf_size; + + /* The stringio object can be in two states: accumulating or realized. + In accumulating state, the internal buffer contains nothing and + the contents are given by the embedded _PyAccu structure. + In realized state, the internal buffer is meaningful and the + _PyAccu is destroyed. + */ + int state; + _PyAccu accu; + + char ok; /* initialized? */ + char closed; + char readuniversal; + char readtranslate; + PyObject *decoder; + PyObject *readnl; + PyObject *writenl; + + PyObject *dict; + PyObject *weakreflist; +} stringio; + +static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs); + +#define CHECK_INITIALIZED(self) \ + if (self->ok <= 0) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + return NULL; \ + } + +#define CHECK_CLOSED(self) \ + if (self->closed) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on closed file"); \ + return NULL; \ + } + +#define ENSURE_REALIZED(self) \ + if (realize(self) < 0) { \ + return NULL; \ + } + + +/* Internal routine for changing the size, in terms of characters, of the + buffer of StringIO objects. The caller should ensure that the 'size' + argument is non-negative. Returns 0 on success, -1 otherwise. */ +static int +resize_buffer(stringio *self, size_t size) +{ + /* Here, unsigned types are used to avoid dealing with signed integer + overflow, which is undefined in C. */ + size_t alloc = self->buf_size; + Py_UCS4 *new_buf = NULL; + + assert(self->buf != NULL); + + /* Reserve one more char for line ending detection. */ + size = size + 1; + /* For simplicity, stay in the range of the signed type. Anyway, Python + doesn't allow strings to be longer than this. */ + if (size > PY_SSIZE_T_MAX) + goto overflow; + + if (size < alloc / 2) { + /* Major downsize; resize down to exact size. */ + alloc = size + 1; + } + else if (size < alloc) { + /* Within allocated size; quick exit */ + return 0; + } + else if (size <= alloc * 1.125) { + /* Moderate upsize; overallocate similar to list_resize() */ + alloc = size + (size >> 3) + (size < 9 ? 3 : 6); + } + else { + /* Major upsize; resize up to exact size */ + alloc = size + 1; + } + + if (alloc > PY_SIZE_MAX / sizeof(Py_UCS4)) + goto overflow; + new_buf = (Py_UCS4 *)PyMem_Realloc(self->buf, alloc * sizeof(Py_UCS4)); + if (new_buf == NULL) { + PyErr_NoMemory(); + return -1; + } + self->buf_size = alloc; + self->buf = new_buf; + + return 0; + + overflow: + PyErr_SetString(PyExc_OverflowError, + "new buffer size too large"); + return -1; +} + +static PyObject * +make_intermediate(stringio *self) +{ + PyObject *intermediate = _PyAccu_Finish(&self->accu); + self->state = STATE_REALIZED; + if (intermediate == NULL) + return NULL; + if (_PyAccu_Init(&self->accu) || + _PyAccu_Accumulate(&self->accu, intermediate)) { + Py_DECREF(intermediate); + return NULL; + } + self->state = STATE_ACCUMULATING; + return intermediate; +} + +static int +realize(stringio *self) +{ + Py_ssize_t len; + PyObject *intermediate; + + if (self->state == STATE_REALIZED) + return 0; + assert(self->state == STATE_ACCUMULATING); + self->state = STATE_REALIZED; + + intermediate = _PyAccu_Finish(&self->accu); + if (intermediate == NULL) + return -1; + + /* Append the intermediate string to the internal buffer. + The length should be equal to the current cursor position. + */ + len = PyUnicode_GET_LENGTH(intermediate); + if (resize_buffer(self, len) < 0) { + Py_DECREF(intermediate); + return -1; + } + if (!PyUnicode_AsUCS4(intermediate, self->buf, len, 0)) { + Py_DECREF(intermediate); + return -1; + } + + Py_DECREF(intermediate); + return 0; +} + +/* Internal routine for writing a whole PyUnicode object to the buffer of a + StringIO object. Returns 0 on success, or -1 on error. */ +static Py_ssize_t +write_str(stringio *self, PyObject *obj) +{ + Py_ssize_t len; + PyObject *decoded = NULL; + + assert(self->buf != NULL); + assert(self->pos >= 0); + + if (self->decoder != NULL) { + decoded = _PyIncrementalNewlineDecoder_decode( + self->decoder, obj, 1 /* always final */); + } + else { + decoded = obj; + Py_INCREF(decoded); + } + if (self->writenl) { + PyObject *translated = PyUnicode_Replace( + decoded, _PyIO_str_nl, self->writenl, -1); + Py_DECREF(decoded); + decoded = translated; + } + if (decoded == NULL) + return -1; + + assert(PyUnicode_Check(decoded)); + if (PyUnicode_READY(decoded)) { + Py_DECREF(decoded); + return -1; + } + len = PyUnicode_GET_LENGTH(decoded); + assert(len >= 0); + + /* This overflow check is not strictly necessary. However, it avoids us to + deal with funky things like comparing an unsigned and a signed + integer. */ + if (self->pos > PY_SSIZE_T_MAX - len) { + PyErr_SetString(PyExc_OverflowError, + "new position too large"); + goto fail; + } + + if (self->state == STATE_ACCUMULATING) { + if (self->string_size == self->pos) { + if (_PyAccu_Accumulate(&self->accu, decoded)) + goto fail; + goto success; + } + if (realize(self)) + goto fail; + } + + if (self->pos + len > self->string_size) { + if (resize_buffer(self, self->pos + len) < 0) + goto fail; + } + + if (self->pos > self->string_size) { + /* In case of overseek, pad with null bytes the buffer region between + the end of stream and the current position. + + 0 lo string_size hi + | |<---used--->|<----------available----------->| + | | <--to pad-->|<---to write---> | + 0 buf position + + */ + memset(self->buf + self->string_size, '\0', + (self->pos - self->string_size) * sizeof(Py_UCS4)); + } + + /* Copy the data to the internal buffer, overwriting some of the + existing data if self->pos < self->string_size. */ + if (!PyUnicode_AsUCS4(decoded, + self->buf + self->pos, + self->buf_size - self->pos, + 0)) + goto fail; + +success: + /* Set the new length of the internal string if it has changed. */ + self->pos += len; + if (self->string_size < self->pos) + self->string_size = self->pos; + + Py_DECREF(decoded); + return 0; + +fail: + Py_XDECREF(decoded); + return -1; +} + +/*[clinic input] +_io.StringIO.getvalue + +Retrieve the entire contents of the object. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_getvalue_impl(stringio *self) +/*[clinic end generated code: output=27b6a7bfeaebce01 input=d23cb81d6791cf88]*/ +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + if (self->state == STATE_ACCUMULATING) + return make_intermediate(self); + return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, self->buf, + self->string_size); +} + +/*[clinic input] +_io.StringIO.tell + +Tell the current file position. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_tell_impl(stringio *self) +/*[clinic end generated code: output=2e87ac67b116c77b input=ec866ebaff02f405]*/ +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + return PyLong_FromSsize_t(self->pos); +} + +/*[clinic input] +_io.StringIO.read + size: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Read at most size characters, returned as a string. + +If the argument is negative or omitted, read until EOF +is reached. Return an empty string at EOF. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_read_impl(stringio *self, Py_ssize_t size) +/*[clinic end generated code: output=ae8cf6002f71626c input=0921093383dfb92d]*/ +{ + Py_ssize_t n; + Py_UCS4 *output; + + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + + /* adjust invalid sizes */ + n = self->string_size - self->pos; + if (size < 0 || size > n) { + size = n; + if (size < 0) + size = 0; + } + + /* Optimization for seek(0); read() */ + if (self->state == STATE_ACCUMULATING && self->pos == 0 && size == n) { + PyObject *result = make_intermediate(self); + self->pos = self->string_size; + return result; + } + + ENSURE_REALIZED(self); + output = self->buf + self->pos; + self->pos += size; + return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, size); +} + +/* Internal helper, used by stringio_readline and stringio_iternext */ +static PyObject * +_stringio_readline(stringio *self, Py_ssize_t limit) +{ + Py_UCS4 *start, *end, old_char; + Py_ssize_t len, consumed; + + /* In case of overseek, return the empty string */ + if (self->pos >= self->string_size) + return PyUnicode_New(0, 0); + + start = self->buf + self->pos; + if (limit < 0 || limit > self->string_size - self->pos) + limit = self->string_size - self->pos; + + end = start + limit; + old_char = *end; + *end = '\0'; + len = _PyIO_find_line_ending( + self->readtranslate, self->readuniversal, self->readnl, + PyUnicode_4BYTE_KIND, (char*)start, (char*)end, &consumed); + *end = old_char; + /* If we haven't found any line ending, we just return everything + (`consumed` is ignored). */ + if (len < 0) + len = limit; + self->pos += len; + return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, start, len); +} + +/*[clinic input] +_io.StringIO.readline + size: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Read until newline or EOF. + +Returns an empty string if EOF is hit immediately. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_readline_impl(stringio *self, Py_ssize_t size) +/*[clinic end generated code: output=cabd6452f1b7e85d input=a5bd70bf682aa276]*/ +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + ENSURE_REALIZED(self); + + return _stringio_readline(self, size); +} + +static PyObject * +stringio_iternext(stringio *self) +{ + PyObject *line; + + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + ENSURE_REALIZED(self); + if (Py_IS_TYPE(self, &PyStringIO_Type)) { - /* Skip method call overhead for speed */ - line = _stringio_readline(self, -1); - } - else { - /* XXX is subclassing StringIO really supported? */ + /* Skip method call overhead for speed */ + line = _stringio_readline(self, -1); + } + else { + /* XXX is subclassing StringIO really supported? */ line = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_readline); - if (line && !PyUnicode_Check(line)) { - PyErr_Format(PyExc_OSError, - "readline() should have returned a str object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL) - return NULL; - - if (PyUnicode_GET_LENGTH(line) == 0) { - /* Reached EOF */ - Py_DECREF(line); - return NULL; - } - - return line; -} - -/*[clinic input] -_io.StringIO.truncate - pos as size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None - / - -Truncate size to pos. - -The pos argument defaults to the current file position, as -returned by tell(). The current file position is unchanged. -Returns the new absolute position. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size) -/*[clinic end generated code: output=eb3aef8e06701365 input=5505cff90ca48b96]*/ -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - - if (size < 0) { - PyErr_Format(PyExc_ValueError, - "Negative size value %zd", size); - return NULL; - } - - if (size < self->string_size) { - ENSURE_REALIZED(self); - if (resize_buffer(self, size) < 0) - return NULL; - self->string_size = size; - } - - return PyLong_FromSsize_t(size); -} - -/*[clinic input] -_io.StringIO.seek - pos: Py_ssize_t - whence: int = 0 - / - -Change stream position. - -Seek to character offset pos relative to position indicated by whence: - 0 Start of stream (the default). pos should be >= 0; - 1 Current position - pos must be 0; - 2 End of stream - pos must be 0. -Returns the new absolute position. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence) -/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=e3855b24e7cae06a]*/ -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - - if (whence != 0 && whence != 1 && whence != 2) { - PyErr_Format(PyExc_ValueError, - "Invalid whence (%i, should be 0, 1 or 2)", whence); - return NULL; - } - else if (pos < 0 && whence == 0) { - PyErr_Format(PyExc_ValueError, - "Negative seek position %zd", pos); - return NULL; - } - else if (whence != 0 && pos != 0) { - PyErr_SetString(PyExc_OSError, - "Can't do nonzero cur-relative seeks"); - return NULL; - } - - /* whence = 0: offset relative to beginning of the string. - whence = 1: no change to current position. - whence = 2: change position to end of file. */ - if (whence == 1) { - pos = self->pos; - } - else if (whence == 2) { - pos = self->string_size; - } - - self->pos = pos; - - return PyLong_FromSsize_t(self->pos); -} - -/*[clinic input] -_io.StringIO.write - s as obj: object - / - -Write string to file. - -Returns the number of characters written, which is always equal to -the length of the string. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_write(stringio *self, PyObject *obj) -/*[clinic end generated code: output=0deaba91a15b94da input=cf96f3b16586e669]*/ -{ - Py_ssize_t size; - - CHECK_INITIALIZED(self); - if (!PyUnicode_Check(obj)) { - PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'", - Py_TYPE(obj)->tp_name); - return NULL; - } - if (PyUnicode_READY(obj)) - return NULL; - CHECK_CLOSED(self); - size = PyUnicode_GET_LENGTH(obj); - - if (size > 0 && write_str(self, obj) < 0) - return NULL; - - return PyLong_FromSsize_t(size); -} - -/*[clinic input] -_io.StringIO.close - -Close the IO object. - -Attempting any further operation after the object is closed -will raise a ValueError. - -This method has no effect if the file is already closed. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_close_impl(stringio *self) -/*[clinic end generated code: output=04399355cbe518f1 input=cbc10b45f35d6d46]*/ -{ - self->closed = 1; - /* Free up some memory */ - if (resize_buffer(self, 0) < 0) - return NULL; - _PyAccu_Destroy(&self->accu); - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - Py_RETURN_NONE; -} - -static int -stringio_traverse(stringio *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -stringio_clear(stringio *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -static void -stringio_dealloc(stringio *self) -{ - _PyObject_GC_UNTRACK(self); - self->ok = 0; - if (self->buf) { - PyMem_Free(self->buf); - self->buf = NULL; - } - _PyAccu_Destroy(&self->accu); - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - Py_CLEAR(self->dict); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - stringio *self; - - assert(type != NULL && type->tp_alloc != NULL); - self = (stringio *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - /* tp_alloc initializes all the fields to zero. So we don't have to - initialize them here. */ - - self->buf = (Py_UCS4 *)PyMem_Malloc(0); - if (self->buf == NULL) { - Py_DECREF(self); - return PyErr_NoMemory(); - } - - return (PyObject *)self; -} - -/*[clinic input] -_io.StringIO.__init__ - initial_value as value: object(c_default="NULL") = '' - newline as newline_obj: object(c_default="NULL") = '\n' - -Text I/O implementation using an in-memory buffer. - -The initial_value argument sets the value of object. The newline -argument is like the one of TextIOWrapper's constructor. -[clinic start generated code]*/ - -static int -_io_StringIO___init___impl(stringio *self, PyObject *value, - PyObject *newline_obj) -/*[clinic end generated code: output=a421ea023b22ef4e input=cee2d9181b2577a3]*/ -{ - const char *newline = "\n"; - Py_ssize_t value_len; - - /* Parse the newline argument. We only want to allow unicode objects or - None. */ - if (newline_obj == Py_None) { - newline = NULL; - } - else if (newline_obj) { - if (!PyUnicode_Check(newline_obj)) { - PyErr_Format(PyExc_TypeError, - "newline must be str or None, not %.200s", - Py_TYPE(newline_obj)->tp_name); - return -1; - } - newline = PyUnicode_AsUTF8(newline_obj); - if (newline == NULL) - return -1; - } - - if (newline && newline[0] != '\0' - && !(newline[0] == '\n' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { - PyErr_Format(PyExc_ValueError, - "illegal newline value: %R", newline_obj); - return -1; - } - if (value && value != Py_None && !PyUnicode_Check(value)) { - PyErr_Format(PyExc_TypeError, - "initial_value must be str or None, not %.200s", - Py_TYPE(value)->tp_name); - return -1; - } - - self->ok = 0; - - _PyAccu_Destroy(&self->accu); - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - - assert((newline != NULL && newline_obj != Py_None) || - (newline == NULL && newline_obj == Py_None)); - - if (newline) { - self->readnl = PyUnicode_FromString(newline); - if (self->readnl == NULL) - return -1; - } - self->readuniversal = (newline == NULL || newline[0] == '\0'); - self->readtranslate = (newline == NULL); - /* If newline == "", we don't translate anything. - If newline == "\n" or newline == None, we translate to "\n", which is - a no-op. - (for newline == None, TextIOWrapper translates to os.linesep, but it - is pointless for StringIO) - */ - if (newline != NULL && newline[0] == '\r') { - self->writenl = self->readnl; - Py_INCREF(self->writenl); - } - - if (self->readuniversal) { + if (line && !PyUnicode_Check(line)) { + PyErr_Format(PyExc_OSError, + "readline() should have returned a str object, " + "not '%.200s'", Py_TYPE(line)->tp_name); + Py_DECREF(line); + return NULL; + } + } + + if (line == NULL) + return NULL; + + if (PyUnicode_GET_LENGTH(line) == 0) { + /* Reached EOF */ + Py_DECREF(line); + return NULL; + } + + return line; +} + +/*[clinic input] +_io.StringIO.truncate + pos as size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None + / + +Truncate size to pos. + +The pos argument defaults to the current file position, as +returned by tell(). The current file position is unchanged. +Returns the new absolute position. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size) +/*[clinic end generated code: output=eb3aef8e06701365 input=5505cff90ca48b96]*/ +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + + if (size < 0) { + PyErr_Format(PyExc_ValueError, + "Negative size value %zd", size); + return NULL; + } + + if (size < self->string_size) { + ENSURE_REALIZED(self); + if (resize_buffer(self, size) < 0) + return NULL; + self->string_size = size; + } + + return PyLong_FromSsize_t(size); +} + +/*[clinic input] +_io.StringIO.seek + pos: Py_ssize_t + whence: int = 0 + / + +Change stream position. + +Seek to character offset pos relative to position indicated by whence: + 0 Start of stream (the default). pos should be >= 0; + 1 Current position - pos must be 0; + 2 End of stream - pos must be 0. +Returns the new absolute position. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence) +/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=e3855b24e7cae06a]*/ +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + + if (whence != 0 && whence != 1 && whence != 2) { + PyErr_Format(PyExc_ValueError, + "Invalid whence (%i, should be 0, 1 or 2)", whence); + return NULL; + } + else if (pos < 0 && whence == 0) { + PyErr_Format(PyExc_ValueError, + "Negative seek position %zd", pos); + return NULL; + } + else if (whence != 0 && pos != 0) { + PyErr_SetString(PyExc_OSError, + "Can't do nonzero cur-relative seeks"); + return NULL; + } + + /* whence = 0: offset relative to beginning of the string. + whence = 1: no change to current position. + whence = 2: change position to end of file. */ + if (whence == 1) { + pos = self->pos; + } + else if (whence == 2) { + pos = self->string_size; + } + + self->pos = pos; + + return PyLong_FromSsize_t(self->pos); +} + +/*[clinic input] +_io.StringIO.write + s as obj: object + / + +Write string to file. + +Returns the number of characters written, which is always equal to +the length of the string. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_write(stringio *self, PyObject *obj) +/*[clinic end generated code: output=0deaba91a15b94da input=cf96f3b16586e669]*/ +{ + Py_ssize_t size; + + CHECK_INITIALIZED(self); + if (!PyUnicode_Check(obj)) { + PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'", + Py_TYPE(obj)->tp_name); + return NULL; + } + if (PyUnicode_READY(obj)) + return NULL; + CHECK_CLOSED(self); + size = PyUnicode_GET_LENGTH(obj); + + if (size > 0 && write_str(self, obj) < 0) + return NULL; + + return PyLong_FromSsize_t(size); +} + +/*[clinic input] +_io.StringIO.close + +Close the IO object. + +Attempting any further operation after the object is closed +will raise a ValueError. + +This method has no effect if the file is already closed. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_close_impl(stringio *self) +/*[clinic end generated code: output=04399355cbe518f1 input=cbc10b45f35d6d46]*/ +{ + self->closed = 1; + /* Free up some memory */ + if (resize_buffer(self, 0) < 0) + return NULL; + _PyAccu_Destroy(&self->accu); + Py_CLEAR(self->readnl); + Py_CLEAR(self->writenl); + Py_CLEAR(self->decoder); + Py_RETURN_NONE; +} + +static int +stringio_traverse(stringio *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +stringio_clear(stringio *self) +{ + Py_CLEAR(self->dict); + return 0; +} + +static void +stringio_dealloc(stringio *self) +{ + _PyObject_GC_UNTRACK(self); + self->ok = 0; + if (self->buf) { + PyMem_Free(self->buf); + self->buf = NULL; + } + _PyAccu_Destroy(&self->accu); + Py_CLEAR(self->readnl); + Py_CLEAR(self->writenl); + Py_CLEAR(self->decoder); + Py_CLEAR(self->dict); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + stringio *self; + + assert(type != NULL && type->tp_alloc != NULL); + self = (stringio *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + /* tp_alloc initializes all the fields to zero. So we don't have to + initialize them here. */ + + self->buf = (Py_UCS4 *)PyMem_Malloc(0); + if (self->buf == NULL) { + Py_DECREF(self); + return PyErr_NoMemory(); + } + + return (PyObject *)self; +} + +/*[clinic input] +_io.StringIO.__init__ + initial_value as value: object(c_default="NULL") = '' + newline as newline_obj: object(c_default="NULL") = '\n' + +Text I/O implementation using an in-memory buffer. + +The initial_value argument sets the value of object. The newline +argument is like the one of TextIOWrapper's constructor. +[clinic start generated code]*/ + +static int +_io_StringIO___init___impl(stringio *self, PyObject *value, + PyObject *newline_obj) +/*[clinic end generated code: output=a421ea023b22ef4e input=cee2d9181b2577a3]*/ +{ + const char *newline = "\n"; + Py_ssize_t value_len; + + /* Parse the newline argument. We only want to allow unicode objects or + None. */ + if (newline_obj == Py_None) { + newline = NULL; + } + else if (newline_obj) { + if (!PyUnicode_Check(newline_obj)) { + PyErr_Format(PyExc_TypeError, + "newline must be str or None, not %.200s", + Py_TYPE(newline_obj)->tp_name); + return -1; + } + newline = PyUnicode_AsUTF8(newline_obj); + if (newline == NULL) + return -1; + } + + if (newline && newline[0] != '\0' + && !(newline[0] == '\n' && newline[1] == '\0') + && !(newline[0] == '\r' && newline[1] == '\0') + && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { + PyErr_Format(PyExc_ValueError, + "illegal newline value: %R", newline_obj); + return -1; + } + if (value && value != Py_None && !PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "initial_value must be str or None, not %.200s", + Py_TYPE(value)->tp_name); + return -1; + } + + self->ok = 0; + + _PyAccu_Destroy(&self->accu); + Py_CLEAR(self->readnl); + Py_CLEAR(self->writenl); + Py_CLEAR(self->decoder); + + assert((newline != NULL && newline_obj != Py_None) || + (newline == NULL && newline_obj == Py_None)); + + if (newline) { + self->readnl = PyUnicode_FromString(newline); + if (self->readnl == NULL) + return -1; + } + self->readuniversal = (newline == NULL || newline[0] == '\0'); + self->readtranslate = (newline == NULL); + /* If newline == "", we don't translate anything. + If newline == "\n" or newline == None, we translate to "\n", which is + a no-op. + (for newline == None, TextIOWrapper translates to os.linesep, but it + is pointless for StringIO) + */ + if (newline != NULL && newline[0] == '\r') { + self->writenl = self->readnl; + Py_INCREF(self->writenl); + } + + if (self->readuniversal) { self->decoder = PyObject_CallFunctionObjArgs( - (PyObject *)&PyIncrementalNewlineDecoder_Type, + (PyObject *)&PyIncrementalNewlineDecoder_Type, Py_None, self->readtranslate ? Py_True : Py_False, NULL); - if (self->decoder == NULL) - return -1; - } - - /* Now everything is set up, resize buffer to size of initial value, - and copy it */ - self->string_size = 0; - if (value && value != Py_None) - value_len = PyUnicode_GetLength(value); - else - value_len = 0; - if (value_len > 0) { - /* This is a heuristic, for newline translation might change - the string length. */ - if (resize_buffer(self, 0) < 0) - return -1; - self->state = STATE_REALIZED; - self->pos = 0; - if (write_str(self, value) < 0) - return -1; - } - else { - /* Empty stringio object, we can start by accumulating */ - if (resize_buffer(self, 0) < 0) - return -1; - if (_PyAccu_Init(&self->accu)) - return -1; - self->state = STATE_ACCUMULATING; - } - self->pos = 0; - - self->closed = 0; - self->ok = 1; - return 0; -} - -/* Properties and pseudo-properties */ - -/*[clinic input] -_io.StringIO.readable - -Returns True if the IO object can be read. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_readable_impl(stringio *self) -/*[clinic end generated code: output=b19d44dd8b1ceb99 input=39ce068b224c21ad]*/ -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - Py_RETURN_TRUE; -} - -/*[clinic input] -_io.StringIO.writable - -Returns True if the IO object can be written. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_writable_impl(stringio *self) -/*[clinic end generated code: output=13e4dd77187074ca input=7a691353aac38835]*/ -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - Py_RETURN_TRUE; -} - -/*[clinic input] -_io.StringIO.seekable - -Returns True if the IO object can be seeked. -[clinic start generated code]*/ - -static PyObject * -_io_StringIO_seekable_impl(stringio *self) -/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/ -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - Py_RETURN_TRUE; -} - -/* Pickling support. - - The implementation of __getstate__ is similar to the one for BytesIO, - except that we also save the newline parameter. For __setstate__ and unlike - BytesIO, we call __init__ to restore the object's state. Doing so allows us - to avoid decoding the complex newline state while keeping the object - representation compact. - - See comment in bytesio.c regarding why only pickle protocols and onward are - supported. -*/ - -static PyObject * + if (self->decoder == NULL) + return -1; + } + + /* Now everything is set up, resize buffer to size of initial value, + and copy it */ + self->string_size = 0; + if (value && value != Py_None) + value_len = PyUnicode_GetLength(value); + else + value_len = 0; + if (value_len > 0) { + /* This is a heuristic, for newline translation might change + the string length. */ + if (resize_buffer(self, 0) < 0) + return -1; + self->state = STATE_REALIZED; + self->pos = 0; + if (write_str(self, value) < 0) + return -1; + } + else { + /* Empty stringio object, we can start by accumulating */ + if (resize_buffer(self, 0) < 0) + return -1; + if (_PyAccu_Init(&self->accu)) + return -1; + self->state = STATE_ACCUMULATING; + } + self->pos = 0; + + self->closed = 0; + self->ok = 1; + return 0; +} + +/* Properties and pseudo-properties */ + +/*[clinic input] +_io.StringIO.readable + +Returns True if the IO object can be read. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_readable_impl(stringio *self) +/*[clinic end generated code: output=b19d44dd8b1ceb99 input=39ce068b224c21ad]*/ +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + Py_RETURN_TRUE; +} + +/*[clinic input] +_io.StringIO.writable + +Returns True if the IO object can be written. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_writable_impl(stringio *self) +/*[clinic end generated code: output=13e4dd77187074ca input=7a691353aac38835]*/ +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + Py_RETURN_TRUE; +} + +/*[clinic input] +_io.StringIO.seekable + +Returns True if the IO object can be seeked. +[clinic start generated code]*/ + +static PyObject * +_io_StringIO_seekable_impl(stringio *self) +/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/ +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + Py_RETURN_TRUE; +} + +/* Pickling support. + + The implementation of __getstate__ is similar to the one for BytesIO, + except that we also save the newline parameter. For __setstate__ and unlike + BytesIO, we call __init__ to restore the object's state. Doing so allows us + to avoid decoding the complex newline state while keeping the object + representation compact. + + See comment in bytesio.c regarding why only pickle protocols and onward are + supported. +*/ + +static PyObject * stringio_getstate(stringio *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *initvalue = _io_StringIO_getvalue_impl(self); - PyObject *dict; - PyObject *state; - - if (initvalue == NULL) - return NULL; - if (self->dict == NULL) { - Py_INCREF(Py_None); - dict = Py_None; - } - else { - dict = PyDict_Copy(self->dict); - if (dict == NULL) { - Py_DECREF(initvalue); - return NULL; - } - } - - state = Py_BuildValue("(OOnN)", initvalue, - self->readnl ? self->readnl : Py_None, - self->pos, dict); - Py_DECREF(initvalue); - return state; -} - -static PyObject * -stringio_setstate(stringio *self, PyObject *state) -{ - PyObject *initarg; - PyObject *position_obj; - PyObject *dict; - Py_ssize_t pos; - - assert(state != NULL); - CHECK_CLOSED(self); - - /* We allow the state tuple to be longer than 4, because we may need - someday to extend the object's state without breaking - backward-compatibility. */ - if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 4) { - PyErr_Format(PyExc_TypeError, - "%.200s.__setstate__ argument should be 4-tuple, got %.200s", - Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name); - return NULL; - } - - /* Initialize the object's state. */ - initarg = PyTuple_GetSlice(state, 0, 2); - if (initarg == NULL) - return NULL; - if (_io_StringIO___init__((PyObject *)self, initarg, NULL) < 0) { - Py_DECREF(initarg); - return NULL; - } - Py_DECREF(initarg); - - /* Restore the buffer state. Even if __init__ did initialize the buffer, - we have to initialize it again since __init__ may translate the - newlines in the initial_value string. We clearly do not want that - because the string value in the state tuple has already been translated - once by __init__. So we do not take any chance and replace object's - buffer completely. */ - { - PyObject *item; - Py_UCS4 *buf; - Py_ssize_t bufsize; - - item = PyTuple_GET_ITEM(state, 0); - buf = PyUnicode_AsUCS4Copy(item); - if (buf == NULL) - return NULL; - bufsize = PyUnicode_GET_LENGTH(item); - - if (resize_buffer(self, bufsize) < 0) { - PyMem_Free(buf); - return NULL; - } - memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4)); - PyMem_Free(buf); - self->string_size = bufsize; - } - - /* Set carefully the position value. Alternatively, we could use the seek - method instead of modifying self->pos directly to better protect the +{ + PyObject *initvalue = _io_StringIO_getvalue_impl(self); + PyObject *dict; + PyObject *state; + + if (initvalue == NULL) + return NULL; + if (self->dict == NULL) { + Py_INCREF(Py_None); + dict = Py_None; + } + else { + dict = PyDict_Copy(self->dict); + if (dict == NULL) { + Py_DECREF(initvalue); + return NULL; + } + } + + state = Py_BuildValue("(OOnN)", initvalue, + self->readnl ? self->readnl : Py_None, + self->pos, dict); + Py_DECREF(initvalue); + return state; +} + +static PyObject * +stringio_setstate(stringio *self, PyObject *state) +{ + PyObject *initarg; + PyObject *position_obj; + PyObject *dict; + Py_ssize_t pos; + + assert(state != NULL); + CHECK_CLOSED(self); + + /* We allow the state tuple to be longer than 4, because we may need + someday to extend the object's state without breaking + backward-compatibility. */ + if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 4) { + PyErr_Format(PyExc_TypeError, + "%.200s.__setstate__ argument should be 4-tuple, got %.200s", + Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name); + return NULL; + } + + /* Initialize the object's state. */ + initarg = PyTuple_GetSlice(state, 0, 2); + if (initarg == NULL) + return NULL; + if (_io_StringIO___init__((PyObject *)self, initarg, NULL) < 0) { + Py_DECREF(initarg); + return NULL; + } + Py_DECREF(initarg); + + /* Restore the buffer state. Even if __init__ did initialize the buffer, + we have to initialize it again since __init__ may translate the + newlines in the initial_value string. We clearly do not want that + because the string value in the state tuple has already been translated + once by __init__. So we do not take any chance and replace object's + buffer completely. */ + { + PyObject *item; + Py_UCS4 *buf; + Py_ssize_t bufsize; + + item = PyTuple_GET_ITEM(state, 0); + buf = PyUnicode_AsUCS4Copy(item); + if (buf == NULL) + return NULL; + bufsize = PyUnicode_GET_LENGTH(item); + + if (resize_buffer(self, bufsize) < 0) { + PyMem_Free(buf); + return NULL; + } + memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4)); + PyMem_Free(buf); + self->string_size = bufsize; + } + + /* Set carefully the position value. Alternatively, we could use the seek + method instead of modifying self->pos directly to better protect the object internal state against erroneous (or malicious) inputs. */ - position_obj = PyTuple_GET_ITEM(state, 2); - if (!PyLong_Check(position_obj)) { - PyErr_Format(PyExc_TypeError, - "third item of state must be an integer, got %.200s", - Py_TYPE(position_obj)->tp_name); - return NULL; - } - pos = PyLong_AsSsize_t(position_obj); - if (pos == -1 && PyErr_Occurred()) - return NULL; - if (pos < 0) { - PyErr_SetString(PyExc_ValueError, - "position value cannot be negative"); - return NULL; - } - self->pos = pos; - - /* Set the dictionary of the instance variables. */ - dict = PyTuple_GET_ITEM(state, 3); - if (dict != Py_None) { - if (!PyDict_Check(dict)) { - PyErr_Format(PyExc_TypeError, - "fourth item of state should be a dict, got a %.200s", - Py_TYPE(dict)->tp_name); - return NULL; - } - if (self->dict) { - /* Alternatively, we could replace the internal dictionary - completely. However, it seems more practical to just update it. */ - if (PyDict_Update(self->dict, dict) < 0) - return NULL; - } - else { - Py_INCREF(dict); - self->dict = dict; - } - } - - Py_RETURN_NONE; -} - - -static PyObject * -stringio_closed(stringio *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyBool_FromLong(self->closed); -} - -static PyObject * -stringio_line_buffering(stringio *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - Py_RETURN_FALSE; -} - -static PyObject * -stringio_newlines(stringio *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - if (self->decoder == NULL) - Py_RETURN_NONE; - return PyObject_GetAttr(self->decoder, _PyIO_str_newlines); -} - -#include "clinic/stringio.c.h" - -static struct PyMethodDef stringio_methods[] = { - _IO_STRINGIO_CLOSE_METHODDEF - _IO_STRINGIO_GETVALUE_METHODDEF - _IO_STRINGIO_READ_METHODDEF - _IO_STRINGIO_READLINE_METHODDEF - _IO_STRINGIO_TELL_METHODDEF - _IO_STRINGIO_TRUNCATE_METHODDEF - _IO_STRINGIO_SEEK_METHODDEF - _IO_STRINGIO_WRITE_METHODDEF - - _IO_STRINGIO_SEEKABLE_METHODDEF - _IO_STRINGIO_READABLE_METHODDEF - _IO_STRINGIO_WRITABLE_METHODDEF - - {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS}, - {"__setstate__", (PyCFunction)stringio_setstate, METH_O}, - {NULL, NULL} /* sentinel */ -}; - -static PyGetSetDef stringio_getset[] = { - {"closed", (getter)stringio_closed, NULL, NULL}, - {"newlines", (getter)stringio_newlines, NULL, NULL}, - /* (following comments straight off of the original Python wrapper:) - XXX Cruft to support the TextIOWrapper API. This would only - be meaningful if StringIO supported the buffer attribute. - Hopefully, a better solution, than adding these pseudo-attributes, - will be found. - */ - {"line_buffering", (getter)stringio_line_buffering, NULL, NULL}, - {NULL} -}; - -PyTypeObject PyStringIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.StringIO", /*tp_name*/ - sizeof(stringio), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)stringio_dealloc, /*tp_dealloc*/ + position_obj = PyTuple_GET_ITEM(state, 2); + if (!PyLong_Check(position_obj)) { + PyErr_Format(PyExc_TypeError, + "third item of state must be an integer, got %.200s", + Py_TYPE(position_obj)->tp_name); + return NULL; + } + pos = PyLong_AsSsize_t(position_obj); + if (pos == -1 && PyErr_Occurred()) + return NULL; + if (pos < 0) { + PyErr_SetString(PyExc_ValueError, + "position value cannot be negative"); + return NULL; + } + self->pos = pos; + + /* Set the dictionary of the instance variables. */ + dict = PyTuple_GET_ITEM(state, 3); + if (dict != Py_None) { + if (!PyDict_Check(dict)) { + PyErr_Format(PyExc_TypeError, + "fourth item of state should be a dict, got a %.200s", + Py_TYPE(dict)->tp_name); + return NULL; + } + if (self->dict) { + /* Alternatively, we could replace the internal dictionary + completely. However, it seems more practical to just update it. */ + if (PyDict_Update(self->dict, dict) < 0) + return NULL; + } + else { + Py_INCREF(dict); + self->dict = dict; + } + } + + Py_RETURN_NONE; +} + + +static PyObject * +stringio_closed(stringio *self, void *context) +{ + CHECK_INITIALIZED(self); + return PyBool_FromLong(self->closed); +} + +static PyObject * +stringio_line_buffering(stringio *self, void *context) +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + Py_RETURN_FALSE; +} + +static PyObject * +stringio_newlines(stringio *self, void *context) +{ + CHECK_INITIALIZED(self); + CHECK_CLOSED(self); + if (self->decoder == NULL) + Py_RETURN_NONE; + return PyObject_GetAttr(self->decoder, _PyIO_str_newlines); +} + +#include "clinic/stringio.c.h" + +static struct PyMethodDef stringio_methods[] = { + _IO_STRINGIO_CLOSE_METHODDEF + _IO_STRINGIO_GETVALUE_METHODDEF + _IO_STRINGIO_READ_METHODDEF + _IO_STRINGIO_READLINE_METHODDEF + _IO_STRINGIO_TELL_METHODDEF + _IO_STRINGIO_TRUNCATE_METHODDEF + _IO_STRINGIO_SEEK_METHODDEF + _IO_STRINGIO_WRITE_METHODDEF + + _IO_STRINGIO_SEEKABLE_METHODDEF + _IO_STRINGIO_READABLE_METHODDEF + _IO_STRINGIO_WRITABLE_METHODDEF + + {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS}, + {"__setstate__", (PyCFunction)stringio_setstate, METH_O}, + {NULL, NULL} /* sentinel */ +}; + +static PyGetSetDef stringio_getset[] = { + {"closed", (getter)stringio_closed, NULL, NULL}, + {"newlines", (getter)stringio_newlines, NULL, NULL}, + /* (following comments straight off of the original Python wrapper:) + XXX Cruft to support the TextIOWrapper API. This would only + be meaningful if StringIO supported the buffer attribute. + Hopefully, a better solution, than adding these pseudo-attributes, + will be found. + */ + {"line_buffering", (getter)stringio_line_buffering, NULL, NULL}, + {NULL} +}; + +PyTypeObject PyStringIO_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.StringIO", /*tp_name*/ + sizeof(stringio), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)stringio_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_StringIO___init____doc__, /*tp_doc*/ - (traverseproc)stringio_traverse, /*tp_traverse*/ - (inquiry)stringio_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(stringio, weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - (iternextfunc)stringio_iternext, /*tp_iternext*/ - stringio_methods, /*tp_methods*/ - 0, /*tp_members*/ - stringio_getset, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - offsetof(stringio, dict), /*tp_dictoffset*/ - _io_StringIO___init__, /*tp_init*/ - 0, /*tp_alloc*/ - stringio_new, /*tp_new*/ -}; + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + _io_StringIO___init____doc__, /*tp_doc*/ + (traverseproc)stringio_traverse, /*tp_traverse*/ + (inquiry)stringio_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + offsetof(stringio, weakreflist), /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + (iternextfunc)stringio_iternext, /*tp_iternext*/ + stringio_methods, /*tp_methods*/ + 0, /*tp_members*/ + stringio_getset, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + offsetof(stringio, dict), /*tp_dictoffset*/ + _io_StringIO___init__, /*tp_init*/ + 0, /*tp_alloc*/ + stringio_new, /*tp_new*/ +}; diff --git a/contrib/tools/python3/src/Modules/_io/textio.c b/contrib/tools/python3/src/Modules/_io/textio.c index 966c532a0e3..57d669e9ff5 100644 --- a/contrib/tools/python3/src/Modules/_io/textio.c +++ b/contrib/tools/python3/src/Modules/_io/textio.c @@ -1,783 +1,783 @@ -/* - An implementation of Text I/O as defined by PEP 3116 - "New I/O" - - Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" +/* + An implementation of Text I/O as defined by PEP 3116 - "New I/O" + + Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper. + + Written by Amaury Forgeot d'Arc and Antoine Pitrou +*/ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include "pycore_interp.h" // PyInterpreterState.fs_codec #include "pycore_object.h" #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "structmember.h" // PyMemberDef -#include "_iomodule.h" - -/*[clinic input] -module _io -class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type" -class _io.TextIOWrapper "textio *" "&TextIOWrapper_TYpe" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2097a4fc85670c26]*/ - -_Py_IDENTIFIER(close); -_Py_IDENTIFIER(_dealloc_warn); -_Py_IDENTIFIER(decode); -_Py_IDENTIFIER(fileno); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(getpreferredencoding); -_Py_IDENTIFIER(isatty); -_Py_IDENTIFIER(mode); -_Py_IDENTIFIER(name); -_Py_IDENTIFIER(raw); -_Py_IDENTIFIER(read); -_Py_IDENTIFIER(readable); -_Py_IDENTIFIER(replace); -_Py_IDENTIFIER(reset); -_Py_IDENTIFIER(seek); -_Py_IDENTIFIER(seekable); -_Py_IDENTIFIER(setstate); -_Py_IDENTIFIER(strict); -_Py_IDENTIFIER(tell); -_Py_IDENTIFIER(writable); - -/* TextIOBase */ - -PyDoc_STRVAR(textiobase_doc, - "Base class for text I/O.\n" - "\n" - "This class provides a character and line based interface to stream\n" - "I/O. There is no readinto method because Python's character strings\n" - "are immutable. There is no public constructor.\n" - ); - -static PyObject * -_unsupported(const char *message) -{ - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_SetString(state->unsupported_operation, message); - return NULL; -} - -PyDoc_STRVAR(textiobase_detach_doc, - "Separate the underlying buffer from the TextIOBase and return it.\n" - "\n" - "After the underlying buffer has been detached, the TextIO is in an\n" - "unusable state.\n" - ); - -static PyObject * +#include "_iomodule.h" + +/*[clinic input] +module _io +class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type" +class _io.TextIOWrapper "textio *" "&TextIOWrapper_TYpe" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2097a4fc85670c26]*/ + +_Py_IDENTIFIER(close); +_Py_IDENTIFIER(_dealloc_warn); +_Py_IDENTIFIER(decode); +_Py_IDENTIFIER(fileno); +_Py_IDENTIFIER(flush); +_Py_IDENTIFIER(getpreferredencoding); +_Py_IDENTIFIER(isatty); +_Py_IDENTIFIER(mode); +_Py_IDENTIFIER(name); +_Py_IDENTIFIER(raw); +_Py_IDENTIFIER(read); +_Py_IDENTIFIER(readable); +_Py_IDENTIFIER(replace); +_Py_IDENTIFIER(reset); +_Py_IDENTIFIER(seek); +_Py_IDENTIFIER(seekable); +_Py_IDENTIFIER(setstate); +_Py_IDENTIFIER(strict); +_Py_IDENTIFIER(tell); +_Py_IDENTIFIER(writable); + +/* TextIOBase */ + +PyDoc_STRVAR(textiobase_doc, + "Base class for text I/O.\n" + "\n" + "This class provides a character and line based interface to stream\n" + "I/O. There is no readinto method because Python's character strings\n" + "are immutable. There is no public constructor.\n" + ); + +static PyObject * +_unsupported(const char *message) +{ + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); + return NULL; +} + +PyDoc_STRVAR(textiobase_detach_doc, + "Separate the underlying buffer from the TextIOBase and return it.\n" + "\n" + "After the underlying buffer has been detached, the TextIO is in an\n" + "unusable state.\n" + ); + +static PyObject * textiobase_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _unsupported("detach"); -} - -PyDoc_STRVAR(textiobase_read_doc, - "Read at most n characters from stream.\n" - "\n" - "Read from underlying buffer until we have n characters or we hit EOF.\n" - "If n is negative or omitted, read until EOF.\n" - ); - -static PyObject * -textiobase_read(PyObject *self, PyObject *args) -{ - return _unsupported("read"); -} - -PyDoc_STRVAR(textiobase_readline_doc, - "Read until newline or EOF.\n" - "\n" - "Returns an empty string if EOF is hit immediately.\n" - ); - -static PyObject * -textiobase_readline(PyObject *self, PyObject *args) -{ - return _unsupported("readline"); -} - -PyDoc_STRVAR(textiobase_write_doc, - "Write string to stream.\n" - "Returns the number of characters written (which is always equal to\n" - "the length of the string).\n" - ); - -static PyObject * -textiobase_write(PyObject *self, PyObject *args) -{ - return _unsupported("write"); -} - -PyDoc_STRVAR(textiobase_encoding_doc, - "Encoding of the text stream.\n" - "\n" - "Subclasses should override.\n" - ); - -static PyObject * -textiobase_encoding_get(PyObject *self, void *context) -{ - Py_RETURN_NONE; -} - -PyDoc_STRVAR(textiobase_newlines_doc, - "Line endings translated so far.\n" - "\n" - "Only line endings translated during reading are considered.\n" - "\n" - "Subclasses should override.\n" - ); - -static PyObject * -textiobase_newlines_get(PyObject *self, void *context) -{ - Py_RETURN_NONE; -} - -PyDoc_STRVAR(textiobase_errors_doc, - "The error setting of the decoder or encoder.\n" - "\n" - "Subclasses should override.\n" - ); - -static PyObject * -textiobase_errors_get(PyObject *self, void *context) -{ - Py_RETURN_NONE; -} - - -static PyMethodDef textiobase_methods[] = { +{ + return _unsupported("detach"); +} + +PyDoc_STRVAR(textiobase_read_doc, + "Read at most n characters from stream.\n" + "\n" + "Read from underlying buffer until we have n characters or we hit EOF.\n" + "If n is negative or omitted, read until EOF.\n" + ); + +static PyObject * +textiobase_read(PyObject *self, PyObject *args) +{ + return _unsupported("read"); +} + +PyDoc_STRVAR(textiobase_readline_doc, + "Read until newline or EOF.\n" + "\n" + "Returns an empty string if EOF is hit immediately.\n" + ); + +static PyObject * +textiobase_readline(PyObject *self, PyObject *args) +{ + return _unsupported("readline"); +} + +PyDoc_STRVAR(textiobase_write_doc, + "Write string to stream.\n" + "Returns the number of characters written (which is always equal to\n" + "the length of the string).\n" + ); + +static PyObject * +textiobase_write(PyObject *self, PyObject *args) +{ + return _unsupported("write"); +} + +PyDoc_STRVAR(textiobase_encoding_doc, + "Encoding of the text stream.\n" + "\n" + "Subclasses should override.\n" + ); + +static PyObject * +textiobase_encoding_get(PyObject *self, void *context) +{ + Py_RETURN_NONE; +} + +PyDoc_STRVAR(textiobase_newlines_doc, + "Line endings translated so far.\n" + "\n" + "Only line endings translated during reading are considered.\n" + "\n" + "Subclasses should override.\n" + ); + +static PyObject * +textiobase_newlines_get(PyObject *self, void *context) +{ + Py_RETURN_NONE; +} + +PyDoc_STRVAR(textiobase_errors_doc, + "The error setting of the decoder or encoder.\n" + "\n" + "Subclasses should override.\n" + ); + +static PyObject * +textiobase_errors_get(PyObject *self, void *context) +{ + Py_RETURN_NONE; +} + + +static PyMethodDef textiobase_methods[] = { {"detach", textiobase_detach, METH_NOARGS, textiobase_detach_doc}, - {"read", textiobase_read, METH_VARARGS, textiobase_read_doc}, - {"readline", textiobase_readline, METH_VARARGS, textiobase_readline_doc}, - {"write", textiobase_write, METH_VARARGS, textiobase_write_doc}, - {NULL, NULL} -}; - -static PyGetSetDef textiobase_getset[] = { - {"encoding", (getter)textiobase_encoding_get, NULL, textiobase_encoding_doc}, - {"newlines", (getter)textiobase_newlines_get, NULL, textiobase_newlines_doc}, - {"errors", (getter)textiobase_errors_get, NULL, textiobase_errors_doc}, - {NULL} -}; - -PyTypeObject PyTextIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._TextIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ + {"read", textiobase_read, METH_VARARGS, textiobase_read_doc}, + {"readline", textiobase_readline, METH_VARARGS, textiobase_readline_doc}, + {"write", textiobase_write, METH_VARARGS, textiobase_write_doc}, + {NULL, NULL} +}; + +static PyGetSetDef textiobase_getset[] = { + {"encoding", (getter)textiobase_encoding_get, NULL, textiobase_encoding_doc}, + {"newlines", (getter)textiobase_newlines_get, NULL, textiobase_newlines_doc}, + {"errors", (getter)textiobase_errors_get, NULL, textiobase_errors_doc}, + {NULL} +}; + +PyTypeObject PyTextIOBase_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io._TextIOBase", /*tp_name*/ + 0, /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 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_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - textiobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - textiobase_methods, /* tp_methods */ - 0, /* tp_members */ - textiobase_getset, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; - - -/* IncrementalNewlineDecoder */ - -typedef struct { - PyObject_HEAD - PyObject *decoder; - PyObject *errors; - unsigned int pendingcr: 1; - unsigned int translate: 1; - unsigned int seennl: 3; -} nldecoder_object; - -/*[clinic input] -_io.IncrementalNewlineDecoder.__init__ - decoder: object - translate: int - errors: object(c_default="NULL") = "strict" - -Codec used when reading a file in universal newlines mode. - -It wraps another incremental decoder, translating \r\n and \r into \n. -It also records the types of newlines encountered. When used with -translate=False, it ensures that the newline sequence is returned in -one piece. When used with decoder=None, it expects unicode strings as -decode input and translates newlines without first invoking an external -decoder. -[clinic start generated code]*/ - -static int -_io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, - PyObject *decoder, int translate, - PyObject *errors) -/*[clinic end generated code: output=fbd04d443e764ec2 input=89db6b19c6b126bf]*/ -{ - self->decoder = decoder; - Py_INCREF(decoder); - - if (errors == NULL) { - self->errors = _PyUnicode_FromId(&PyId_strict); - if (self->errors == NULL) - return -1; - } - else { - self->errors = errors; - } - Py_INCREF(self->errors); - - self->translate = translate ? 1 : 0; - self->seennl = 0; - self->pendingcr = 0; - - return 0; -} - -static void -incrementalnewlinedecoder_dealloc(nldecoder_object *self) -{ - Py_CLEAR(self->decoder); - Py_CLEAR(self->errors); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -check_decoded(PyObject *decoded) -{ - if (decoded == NULL) - return -1; - if (!PyUnicode_Check(decoded)) { - PyErr_Format(PyExc_TypeError, - "decoder should return a string result, not '%.200s'", - Py_TYPE(decoded)->tp_name); - Py_DECREF(decoded); - return -1; - } - if (PyUnicode_READY(decoded) < 0) { - Py_DECREF(decoded); - return -1; - } - return 0; -} - -#define SEEN_CR 1 -#define SEEN_LF 2 -#define SEEN_CRLF 4 -#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF) - -PyObject * -_PyIncrementalNewlineDecoder_decode(PyObject *myself, - PyObject *input, int final) -{ - PyObject *output; - Py_ssize_t output_len; - nldecoder_object *self = (nldecoder_object *) myself; - - if (self->decoder == NULL) { - PyErr_SetString(PyExc_ValueError, - "IncrementalNewlineDecoder.__init__ not called"); - return NULL; - } - - /* decode input (with the eventual \r from a previous pass) */ - if (self->decoder != Py_None) { - output = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_decode, input, final ? Py_True : Py_False, NULL); - } - else { - output = input; - Py_INCREF(output); - } - - if (check_decoded(output) < 0) - return NULL; - - output_len = PyUnicode_GET_LENGTH(output); - if (self->pendingcr && (final || output_len > 0)) { - /* Prefix output with CR */ - int kind; - PyObject *modified; - char *out; - - modified = PyUnicode_New(output_len + 1, - PyUnicode_MAX_CHAR_VALUE(output)); - if (modified == NULL) - goto error; - kind = PyUnicode_KIND(modified); - out = PyUnicode_DATA(modified); + textiobase_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + textiobase_methods, /* tp_methods */ + 0, /* tp_members */ + textiobase_getset, /* tp_getset */ + &PyIOBase_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; + + +/* IncrementalNewlineDecoder */ + +typedef struct { + PyObject_HEAD + PyObject *decoder; + PyObject *errors; + unsigned int pendingcr: 1; + unsigned int translate: 1; + unsigned int seennl: 3; +} nldecoder_object; + +/*[clinic input] +_io.IncrementalNewlineDecoder.__init__ + decoder: object + translate: int + errors: object(c_default="NULL") = "strict" + +Codec used when reading a file in universal newlines mode. + +It wraps another incremental decoder, translating \r\n and \r into \n. +It also records the types of newlines encountered. When used with +translate=False, it ensures that the newline sequence is returned in +one piece. When used with decoder=None, it expects unicode strings as +decode input and translates newlines without first invoking an external +decoder. +[clinic start generated code]*/ + +static int +_io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, + PyObject *decoder, int translate, + PyObject *errors) +/*[clinic end generated code: output=fbd04d443e764ec2 input=89db6b19c6b126bf]*/ +{ + self->decoder = decoder; + Py_INCREF(decoder); + + if (errors == NULL) { + self->errors = _PyUnicode_FromId(&PyId_strict); + if (self->errors == NULL) + return -1; + } + else { + self->errors = errors; + } + Py_INCREF(self->errors); + + self->translate = translate ? 1 : 0; + self->seennl = 0; + self->pendingcr = 0; + + return 0; +} + +static void +incrementalnewlinedecoder_dealloc(nldecoder_object *self) +{ + Py_CLEAR(self->decoder); + Py_CLEAR(self->errors); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +check_decoded(PyObject *decoded) +{ + if (decoded == NULL) + return -1; + if (!PyUnicode_Check(decoded)) { + PyErr_Format(PyExc_TypeError, + "decoder should return a string result, not '%.200s'", + Py_TYPE(decoded)->tp_name); + Py_DECREF(decoded); + return -1; + } + if (PyUnicode_READY(decoded) < 0) { + Py_DECREF(decoded); + return -1; + } + return 0; +} + +#define SEEN_CR 1 +#define SEEN_LF 2 +#define SEEN_CRLF 4 +#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF) + +PyObject * +_PyIncrementalNewlineDecoder_decode(PyObject *myself, + PyObject *input, int final) +{ + PyObject *output; + Py_ssize_t output_len; + nldecoder_object *self = (nldecoder_object *) myself; + + if (self->decoder == NULL) { + PyErr_SetString(PyExc_ValueError, + "IncrementalNewlineDecoder.__init__ not called"); + return NULL; + } + + /* decode input (with the eventual \r from a previous pass) */ + if (self->decoder != Py_None) { + output = PyObject_CallMethodObjArgs(self->decoder, + _PyIO_str_decode, input, final ? Py_True : Py_False, NULL); + } + else { + output = input; + Py_INCREF(output); + } + + if (check_decoded(output) < 0) + return NULL; + + output_len = PyUnicode_GET_LENGTH(output); + if (self->pendingcr && (final || output_len > 0)) { + /* Prefix output with CR */ + int kind; + PyObject *modified; + char *out; + + modified = PyUnicode_New(output_len + 1, + PyUnicode_MAX_CHAR_VALUE(output)); + if (modified == NULL) + goto error; + kind = PyUnicode_KIND(modified); + out = PyUnicode_DATA(modified); PyUnicode_WRITE(kind, out, 0, '\r'); - memcpy(out + kind, PyUnicode_DATA(output), kind * output_len); - Py_DECREF(output); - output = modified; /* output remains ready */ - self->pendingcr = 0; - output_len++; - } - - /* retain last \r even when not translating data: - * then readline() is sure to get \r\n in one pass - */ - if (!final) { - if (output_len > 0 - && PyUnicode_READ_CHAR(output, output_len - 1) == '\r') - { - PyObject *modified = PyUnicode_Substring(output, 0, output_len -1); - if (modified == NULL) - goto error; - Py_DECREF(output); - output = modified; - self->pendingcr = 1; - } - } - - /* Record which newlines are read and do newline translation if desired, - all in one pass. */ - { + memcpy(out + kind, PyUnicode_DATA(output), kind * output_len); + Py_DECREF(output); + output = modified; /* output remains ready */ + self->pendingcr = 0; + output_len++; + } + + /* retain last \r even when not translating data: + * then readline() is sure to get \r\n in one pass + */ + if (!final) { + if (output_len > 0 + && PyUnicode_READ_CHAR(output, output_len - 1) == '\r') + { + PyObject *modified = PyUnicode_Substring(output, 0, output_len -1); + if (modified == NULL) + goto error; + Py_DECREF(output); + output = modified; + self->pendingcr = 1; + } + } + + /* Record which newlines are read and do newline translation if desired, + all in one pass. */ + { const void *in_str; - Py_ssize_t len; - int seennl = self->seennl; - int only_lf = 0; - int kind; - - in_str = PyUnicode_DATA(output); - len = PyUnicode_GET_LENGTH(output); - kind = PyUnicode_KIND(output); - - if (len == 0) - return output; - - /* If, up to now, newlines are consistently \n, do a quick check - for the \r *byte* with the libc's optimized memchr. - */ - if (seennl == SEEN_LF || seennl == 0) { - only_lf = (memchr(in_str, '\r', kind * len) == NULL); - } - - if (only_lf) { - /* If not already seen, quick scan for a possible "\n" character. - (there's nothing else to be done, even when in translation mode) - */ - if (seennl == 0 && - memchr(in_str, '\n', kind * len) != NULL) { - if (kind == PyUnicode_1BYTE_KIND) - seennl |= SEEN_LF; - else { - Py_ssize_t i = 0; - for (;;) { - Py_UCS4 c; - /* Fast loop for non-control characters */ - while (PyUnicode_READ(kind, in_str, i) > '\n') - i++; - c = PyUnicode_READ(kind, in_str, i++); - if (c == '\n') { - seennl |= SEEN_LF; - break; - } - if (i >= len) - break; - } - } - } - /* Finished: we have scanned for newlines, and none of them - need translating */ - } - else if (!self->translate) { - Py_ssize_t i = 0; - /* We have already seen all newline types, no need to scan again */ - if (seennl == SEEN_ALL) - goto endscan; - for (;;) { - Py_UCS4 c; - /* Fast loop for non-control characters */ - while (PyUnicode_READ(kind, in_str, i) > '\r') - i++; - c = PyUnicode_READ(kind, in_str, i++); - if (c == '\n') - seennl |= SEEN_LF; - else if (c == '\r') { - if (PyUnicode_READ(kind, in_str, i) == '\n') { - seennl |= SEEN_CRLF; - i++; - } - else - seennl |= SEEN_CR; - } - if (i >= len) - break; - if (seennl == SEEN_ALL) - break; - } - endscan: - ; - } - else { - void *translated; - int kind = PyUnicode_KIND(output); + Py_ssize_t len; + int seennl = self->seennl; + int only_lf = 0; + int kind; + + in_str = PyUnicode_DATA(output); + len = PyUnicode_GET_LENGTH(output); + kind = PyUnicode_KIND(output); + + if (len == 0) + return output; + + /* If, up to now, newlines are consistently \n, do a quick check + for the \r *byte* with the libc's optimized memchr. + */ + if (seennl == SEEN_LF || seennl == 0) { + only_lf = (memchr(in_str, '\r', kind * len) == NULL); + } + + if (only_lf) { + /* If not already seen, quick scan for a possible "\n" character. + (there's nothing else to be done, even when in translation mode) + */ + if (seennl == 0 && + memchr(in_str, '\n', kind * len) != NULL) { + if (kind == PyUnicode_1BYTE_KIND) + seennl |= SEEN_LF; + else { + Py_ssize_t i = 0; + for (;;) { + Py_UCS4 c; + /* Fast loop for non-control characters */ + while (PyUnicode_READ(kind, in_str, i) > '\n') + i++; + c = PyUnicode_READ(kind, in_str, i++); + if (c == '\n') { + seennl |= SEEN_LF; + break; + } + if (i >= len) + break; + } + } + } + /* Finished: we have scanned for newlines, and none of them + need translating */ + } + else if (!self->translate) { + Py_ssize_t i = 0; + /* We have already seen all newline types, no need to scan again */ + if (seennl == SEEN_ALL) + goto endscan; + for (;;) { + Py_UCS4 c; + /* Fast loop for non-control characters */ + while (PyUnicode_READ(kind, in_str, i) > '\r') + i++; + c = PyUnicode_READ(kind, in_str, i++); + if (c == '\n') + seennl |= SEEN_LF; + else if (c == '\r') { + if (PyUnicode_READ(kind, in_str, i) == '\n') { + seennl |= SEEN_CRLF; + i++; + } + else + seennl |= SEEN_CR; + } + if (i >= len) + break; + if (seennl == SEEN_ALL) + break; + } + endscan: + ; + } + else { + void *translated; + int kind = PyUnicode_KIND(output); const void *in_str = PyUnicode_DATA(output); - Py_ssize_t in, out; - /* XXX: Previous in-place translation here is disabled as - resizing is not possible anymore */ - /* We could try to optimize this so that we only do a copy - when there is something to translate. On the other hand, - we already know there is a \r byte, so chances are high - that something needs to be done. */ - translated = PyMem_Malloc(kind * len); - if (translated == NULL) { - PyErr_NoMemory(); - goto error; - } - in = out = 0; - for (;;) { - Py_UCS4 c; - /* Fast loop for non-control characters */ - while ((c = PyUnicode_READ(kind, in_str, in++)) > '\r') - PyUnicode_WRITE(kind, translated, out++, c); - if (c == '\n') { - PyUnicode_WRITE(kind, translated, out++, c); - seennl |= SEEN_LF; - continue; - } - if (c == '\r') { - if (PyUnicode_READ(kind, in_str, in) == '\n') { - in++; - seennl |= SEEN_CRLF; - } - else - seennl |= SEEN_CR; - PyUnicode_WRITE(kind, translated, out++, '\n'); - continue; - } - if (in > len) - break; - PyUnicode_WRITE(kind, translated, out++, c); - } - Py_DECREF(output); - output = PyUnicode_FromKindAndData(kind, translated, out); - PyMem_Free(translated); - if (!output) - return NULL; - } - self->seennl |= seennl; - } - - return output; - - error: - Py_DECREF(output); - return NULL; -} - -/*[clinic input] -_io.IncrementalNewlineDecoder.decode - input: object - final: bool(accept={int}) = False -[clinic start generated code]*/ - -static PyObject * -_io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, - PyObject *input, int final) -/*[clinic end generated code: output=0d486755bb37a66e input=a4ea97f26372d866]*/ -{ - return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); -} - -/*[clinic input] -_io.IncrementalNewlineDecoder.getstate -[clinic start generated code]*/ - -static PyObject * -_io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) -/*[clinic end generated code: output=f0d2c9c136f4e0d0 input=f8ff101825e32e7f]*/ -{ - PyObject *buffer; - unsigned long long flag; - - if (self->decoder != Py_None) { + Py_ssize_t in, out; + /* XXX: Previous in-place translation here is disabled as + resizing is not possible anymore */ + /* We could try to optimize this so that we only do a copy + when there is something to translate. On the other hand, + we already know there is a \r byte, so chances are high + that something needs to be done. */ + translated = PyMem_Malloc(kind * len); + if (translated == NULL) { + PyErr_NoMemory(); + goto error; + } + in = out = 0; + for (;;) { + Py_UCS4 c; + /* Fast loop for non-control characters */ + while ((c = PyUnicode_READ(kind, in_str, in++)) > '\r') + PyUnicode_WRITE(kind, translated, out++, c); + if (c == '\n') { + PyUnicode_WRITE(kind, translated, out++, c); + seennl |= SEEN_LF; + continue; + } + if (c == '\r') { + if (PyUnicode_READ(kind, in_str, in) == '\n') { + in++; + seennl |= SEEN_CRLF; + } + else + seennl |= SEEN_CR; + PyUnicode_WRITE(kind, translated, out++, '\n'); + continue; + } + if (in > len) + break; + PyUnicode_WRITE(kind, translated, out++, c); + } + Py_DECREF(output); + output = PyUnicode_FromKindAndData(kind, translated, out); + PyMem_Free(translated); + if (!output) + return NULL; + } + self->seennl |= seennl; + } + + return output; + + error: + Py_DECREF(output); + return NULL; +} + +/*[clinic input] +_io.IncrementalNewlineDecoder.decode + input: object + final: bool(accept={int}) = False +[clinic start generated code]*/ + +static PyObject * +_io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, + PyObject *input, int final) +/*[clinic end generated code: output=0d486755bb37a66e input=a4ea97f26372d866]*/ +{ + return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); +} + +/*[clinic input] +_io.IncrementalNewlineDecoder.getstate +[clinic start generated code]*/ + +static PyObject * +_io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) +/*[clinic end generated code: output=f0d2c9c136f4e0d0 input=f8ff101825e32e7f]*/ +{ + PyObject *buffer; + unsigned long long flag; + + if (self->decoder != Py_None) { PyObject *state = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_getstate); - if (state == NULL) - return NULL; - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, - "illegal decoder state"); - Py_DECREF(state); - return NULL; - } - if (!PyArg_ParseTuple(state, "OK;illegal decoder state", - &buffer, &flag)) - { - Py_DECREF(state); - return NULL; - } - Py_INCREF(buffer); - Py_DECREF(state); - } - else { - buffer = PyBytes_FromString(""); - flag = 0; - } - flag <<= 1; - if (self->pendingcr) - flag |= 1; - return Py_BuildValue("NK", buffer, flag); -} - -/*[clinic input] -_io.IncrementalNewlineDecoder.setstate - state: object - / -[clinic start generated code]*/ - -static PyObject * -_io_IncrementalNewlineDecoder_setstate(nldecoder_object *self, - PyObject *state) -/*[clinic end generated code: output=c10c622508b576cb input=c53fb505a76dbbe2]*/ -{ - PyObject *buffer; - unsigned long long flag; - - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state argument must be a tuple"); - return NULL; - } - if (!PyArg_ParseTuple(state, "OK;setstate(): illegal state argument", - &buffer, &flag)) - { - return NULL; - } - - self->pendingcr = (int) (flag & 1); - flag >>= 1; - - if (self->decoder != Py_None) - return _PyObject_CallMethodId(self->decoder, - &PyId_setstate, "((OK))", buffer, flag); - else - Py_RETURN_NONE; -} - -/*[clinic input] -_io.IncrementalNewlineDecoder.reset -[clinic start generated code]*/ - -static PyObject * -_io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) -/*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/ -{ - self->seennl = 0; - self->pendingcr = 0; - if (self->decoder != Py_None) + if (state == NULL) + return NULL; + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, + "illegal decoder state"); + Py_DECREF(state); + return NULL; + } + if (!PyArg_ParseTuple(state, "OK;illegal decoder state", + &buffer, &flag)) + { + Py_DECREF(state); + return NULL; + } + Py_INCREF(buffer); + Py_DECREF(state); + } + else { + buffer = PyBytes_FromString(""); + flag = 0; + } + flag <<= 1; + if (self->pendingcr) + flag |= 1; + return Py_BuildValue("NK", buffer, flag); +} + +/*[clinic input] +_io.IncrementalNewlineDecoder.setstate + state: object + / +[clinic start generated code]*/ + +static PyObject * +_io_IncrementalNewlineDecoder_setstate(nldecoder_object *self, + PyObject *state) +/*[clinic end generated code: output=c10c622508b576cb input=c53fb505a76dbbe2]*/ +{ + PyObject *buffer; + unsigned long long flag; + + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state argument must be a tuple"); + return NULL; + } + if (!PyArg_ParseTuple(state, "OK;setstate(): illegal state argument", + &buffer, &flag)) + { + return NULL; + } + + self->pendingcr = (int) (flag & 1); + flag >>= 1; + + if (self->decoder != Py_None) + return _PyObject_CallMethodId(self->decoder, + &PyId_setstate, "((OK))", buffer, flag); + else + Py_RETURN_NONE; +} + +/*[clinic input] +_io.IncrementalNewlineDecoder.reset +[clinic start generated code]*/ + +static PyObject * +_io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) +/*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/ +{ + self->seennl = 0; + self->pendingcr = 0; + if (self->decoder != Py_None) return PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); - else - Py_RETURN_NONE; -} - -static PyObject * -incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context) -{ - switch (self->seennl) { - case SEEN_CR: - return PyUnicode_FromString("\r"); - case SEEN_LF: - return PyUnicode_FromString("\n"); - case SEEN_CRLF: - return PyUnicode_FromString("\r\n"); - case SEEN_CR | SEEN_LF: - return Py_BuildValue("ss", "\r", "\n"); - case SEEN_CR | SEEN_CRLF: - return Py_BuildValue("ss", "\r", "\r\n"); - case SEEN_LF | SEEN_CRLF: - return Py_BuildValue("ss", "\n", "\r\n"); - case SEEN_CR | SEEN_LF | SEEN_CRLF: - return Py_BuildValue("sss", "\r", "\n", "\r\n"); - default: - Py_RETURN_NONE; - } - -} - -/* TextIOWrapper */ - -typedef PyObject * - (*encodefunc_t)(PyObject *, PyObject *); - -typedef struct -{ - PyObject_HEAD - int ok; /* initialized? */ - int detached; - Py_ssize_t chunk_size; - PyObject *buffer; - PyObject *encoding; - PyObject *encoder; - PyObject *decoder; - PyObject *readnl; - PyObject *errors; - const char *writenl; /* ASCII-encoded; NULL stands for \n */ - char line_buffering; - char write_through; - char readuniversal; - char readtranslate; - char writetranslate; - char seekable; - char has_read1; - char telling; - char finalizing; - /* Specialized encoding func (see below) */ - encodefunc_t encodefunc; - /* Whether or not it's the start of the stream */ - char encoding_start_of_stream; - - /* Reads and writes are internally buffered in order to speed things up. - However, any read will first flush the write buffer if itsn't empty. - - Please also note that text to be written is first encoded before being - buffered. This is necessary so that encoding errors are immediately - reported to the caller, but it unfortunately means that the - IncrementalEncoder (whose encode() method is always written in Python) - becomes a bottleneck for small writes. - */ - PyObject *decoded_chars; /* buffer for text returned from decoder */ - Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */ + else + Py_RETURN_NONE; +} + +static PyObject * +incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context) +{ + switch (self->seennl) { + case SEEN_CR: + return PyUnicode_FromString("\r"); + case SEEN_LF: + return PyUnicode_FromString("\n"); + case SEEN_CRLF: + return PyUnicode_FromString("\r\n"); + case SEEN_CR | SEEN_LF: + return Py_BuildValue("ss", "\r", "\n"); + case SEEN_CR | SEEN_CRLF: + return Py_BuildValue("ss", "\r", "\r\n"); + case SEEN_LF | SEEN_CRLF: + return Py_BuildValue("ss", "\n", "\r\n"); + case SEEN_CR | SEEN_LF | SEEN_CRLF: + return Py_BuildValue("sss", "\r", "\n", "\r\n"); + default: + Py_RETURN_NONE; + } + +} + +/* TextIOWrapper */ + +typedef PyObject * + (*encodefunc_t)(PyObject *, PyObject *); + +typedef struct +{ + PyObject_HEAD + int ok; /* initialized? */ + int detached; + Py_ssize_t chunk_size; + PyObject *buffer; + PyObject *encoding; + PyObject *encoder; + PyObject *decoder; + PyObject *readnl; + PyObject *errors; + const char *writenl; /* ASCII-encoded; NULL stands for \n */ + char line_buffering; + char write_through; + char readuniversal; + char readtranslate; + char writetranslate; + char seekable; + char has_read1; + char telling; + char finalizing; + /* Specialized encoding func (see below) */ + encodefunc_t encodefunc; + /* Whether or not it's the start of the stream */ + char encoding_start_of_stream; + + /* Reads and writes are internally buffered in order to speed things up. + However, any read will first flush the write buffer if itsn't empty. + + Please also note that text to be written is first encoded before being + buffered. This is necessary so that encoding errors are immediately + reported to the caller, but it unfortunately means that the + IncrementalEncoder (whose encode() method is always written in Python) + becomes a bottleneck for small writes. + */ + PyObject *decoded_chars; /* buffer for text returned from decoder */ + Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */ PyObject *pending_bytes; // data waiting to be written. // ascii unicode, bytes, or list of them. - Py_ssize_t pending_bytes_count; - - /* snapshot is either NULL, or a tuple (dec_flags, next_input) where - * dec_flags is the second (integer) item of the decoder state and - * next_input is the chunk of input bytes that comes next after the - * snapshot point. We use this to reconstruct decoder states in tell(). - */ - PyObject *snapshot; - /* Bytes-to-characters ratio for the current chunk. Serves as input for - the heuristic in tell(). */ - double b2cratio; - - /* Cache raw object if it's a FileIO object */ - PyObject *raw; - - PyObject *weakreflist; - PyObject *dict; -} textio; - -static void -textiowrapper_set_decoded_chars(textio *self, PyObject *chars); - -/* A couple of specialized cases in order to bypass the slow incremental - encoding methods for the most popular encodings. */ - -static PyObject * -ascii_encode(textio *self, PyObject *text) -{ - return _PyUnicode_AsASCIIString(text, PyUnicode_AsUTF8(self->errors)); -} - -static PyObject * -utf16be_encode(textio *self, PyObject *text) -{ - return _PyUnicode_EncodeUTF16(text, - PyUnicode_AsUTF8(self->errors), 1); -} - -static PyObject * -utf16le_encode(textio *self, PyObject *text) -{ - return _PyUnicode_EncodeUTF16(text, - PyUnicode_AsUTF8(self->errors), -1); -} - -static PyObject * -utf16_encode(textio *self, PyObject *text) -{ - if (!self->encoding_start_of_stream) { - /* Skip the BOM and use native byte ordering */ -#if PY_BIG_ENDIAN - return utf16be_encode(self, text); -#else - return utf16le_encode(self, text); -#endif - } - return _PyUnicode_EncodeUTF16(text, - PyUnicode_AsUTF8(self->errors), 0); -} - -static PyObject * -utf32be_encode(textio *self, PyObject *text) -{ - return _PyUnicode_EncodeUTF32(text, - PyUnicode_AsUTF8(self->errors), 1); -} - -static PyObject * -utf32le_encode(textio *self, PyObject *text) -{ - return _PyUnicode_EncodeUTF32(text, - PyUnicode_AsUTF8(self->errors), -1); -} - -static PyObject * -utf32_encode(textio *self, PyObject *text) -{ - if (!self->encoding_start_of_stream) { - /* Skip the BOM and use native byte ordering */ -#if PY_BIG_ENDIAN - return utf32be_encode(self, text); -#else - return utf32le_encode(self, text); -#endif - } - return _PyUnicode_EncodeUTF32(text, - PyUnicode_AsUTF8(self->errors), 0); -} - -static PyObject * -utf8_encode(textio *self, PyObject *text) -{ - return _PyUnicode_AsUTF8String(text, PyUnicode_AsUTF8(self->errors)); -} - -static PyObject * -latin1_encode(textio *self, PyObject *text) -{ - return _PyUnicode_AsLatin1String(text, PyUnicode_AsUTF8(self->errors)); -} - + Py_ssize_t pending_bytes_count; + + /* snapshot is either NULL, or a tuple (dec_flags, next_input) where + * dec_flags is the second (integer) item of the decoder state and + * next_input is the chunk of input bytes that comes next after the + * snapshot point. We use this to reconstruct decoder states in tell(). + */ + PyObject *snapshot; + /* Bytes-to-characters ratio for the current chunk. Serves as input for + the heuristic in tell(). */ + double b2cratio; + + /* Cache raw object if it's a FileIO object */ + PyObject *raw; + + PyObject *weakreflist; + PyObject *dict; +} textio; + +static void +textiowrapper_set_decoded_chars(textio *self, PyObject *chars); + +/* A couple of specialized cases in order to bypass the slow incremental + encoding methods for the most popular encodings. */ + +static PyObject * +ascii_encode(textio *self, PyObject *text) +{ + return _PyUnicode_AsASCIIString(text, PyUnicode_AsUTF8(self->errors)); +} + +static PyObject * +utf16be_encode(textio *self, PyObject *text) +{ + return _PyUnicode_EncodeUTF16(text, + PyUnicode_AsUTF8(self->errors), 1); +} + +static PyObject * +utf16le_encode(textio *self, PyObject *text) +{ + return _PyUnicode_EncodeUTF16(text, + PyUnicode_AsUTF8(self->errors), -1); +} + +static PyObject * +utf16_encode(textio *self, PyObject *text) +{ + if (!self->encoding_start_of_stream) { + /* Skip the BOM and use native byte ordering */ +#if PY_BIG_ENDIAN + return utf16be_encode(self, text); +#else + return utf16le_encode(self, text); +#endif + } + return _PyUnicode_EncodeUTF16(text, + PyUnicode_AsUTF8(self->errors), 0); +} + +static PyObject * +utf32be_encode(textio *self, PyObject *text) +{ + return _PyUnicode_EncodeUTF32(text, + PyUnicode_AsUTF8(self->errors), 1); +} + +static PyObject * +utf32le_encode(textio *self, PyObject *text) +{ + return _PyUnicode_EncodeUTF32(text, + PyUnicode_AsUTF8(self->errors), -1); +} + +static PyObject * +utf32_encode(textio *self, PyObject *text) +{ + if (!self->encoding_start_of_stream) { + /* Skip the BOM and use native byte ordering */ +#if PY_BIG_ENDIAN + return utf32be_encode(self, text); +#else + return utf32le_encode(self, text); +#endif + } + return _PyUnicode_EncodeUTF32(text, + PyUnicode_AsUTF8(self->errors), 0); +} + +static PyObject * +utf8_encode(textio *self, PyObject *text) +{ + return _PyUnicode_AsUTF8String(text, PyUnicode_AsUTF8(self->errors)); +} + +static PyObject * +latin1_encode(textio *self, PyObject *text) +{ + return _PyUnicode_AsLatin1String(text, PyUnicode_AsUTF8(self->errors)); +} + // Return true when encoding can be skipped when text is ascii. static inline int is_asciicompat_encoding(encodefunc_t f) @@ -787,764 +787,764 @@ is_asciicompat_encoding(encodefunc_t f) || f == (encodefunc_t) utf8_encode; } -/* Map normalized encoding names onto the specialized encoding funcs */ - -typedef struct { - const char *name; - encodefunc_t encodefunc; -} encodefuncentry; - -static const encodefuncentry encodefuncs[] = { - {"ascii", (encodefunc_t) ascii_encode}, - {"iso8859-1", (encodefunc_t) latin1_encode}, - {"utf-8", (encodefunc_t) utf8_encode}, - {"utf-16-be", (encodefunc_t) utf16be_encode}, - {"utf-16-le", (encodefunc_t) utf16le_encode}, - {"utf-16", (encodefunc_t) utf16_encode}, - {"utf-32-be", (encodefunc_t) utf32be_encode}, - {"utf-32-le", (encodefunc_t) utf32le_encode}, - {"utf-32", (encodefunc_t) utf32_encode}, - {NULL, NULL} -}; - +/* Map normalized encoding names onto the specialized encoding funcs */ + +typedef struct { + const char *name; + encodefunc_t encodefunc; +} encodefuncentry; + +static const encodefuncentry encodefuncs[] = { + {"ascii", (encodefunc_t) ascii_encode}, + {"iso8859-1", (encodefunc_t) latin1_encode}, + {"utf-8", (encodefunc_t) utf8_encode}, + {"utf-16-be", (encodefunc_t) utf16be_encode}, + {"utf-16-le", (encodefunc_t) utf16le_encode}, + {"utf-16", (encodefunc_t) utf16_encode}, + {"utf-32-be", (encodefunc_t) utf32be_encode}, + {"utf-32-le", (encodefunc_t) utf32le_encode}, + {"utf-32", (encodefunc_t) utf32_encode}, + {NULL, NULL} +}; + +static int +validate_newline(const char *newline) +{ + if (newline && newline[0] != '\0' + && !(newline[0] == '\n' && newline[1] == '\0') + && !(newline[0] == '\r' && newline[1] == '\0') + && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { + PyErr_Format(PyExc_ValueError, + "illegal newline value: %s", newline); + return -1; + } + return 0; +} + +static int +set_newline(textio *self, const char *newline) +{ + PyObject *old = self->readnl; + if (newline == NULL) { + self->readnl = NULL; + } + else { + self->readnl = PyUnicode_FromString(newline); + if (self->readnl == NULL) { + self->readnl = old; + return -1; + } + } + self->readuniversal = (newline == NULL || newline[0] == '\0'); + self->readtranslate = (newline == NULL); + self->writetranslate = (newline == NULL || newline[0] != '\0'); + if (!self->readuniversal && self->readnl != NULL) { + // validate_newline() accepts only ASCII newlines. + assert(PyUnicode_KIND(self->readnl) == PyUnicode_1BYTE_KIND); + self->writenl = (const char *)PyUnicode_1BYTE_DATA(self->readnl); + if (strcmp(self->writenl, "\n") == 0) { + self->writenl = NULL; + } + } + else { +#ifdef MS_WINDOWS + self->writenl = "\r\n"; +#else + self->writenl = NULL; +#endif + } + Py_XDECREF(old); + return 0; +} + +static int +_textiowrapper_set_decoder(textio *self, PyObject *codec_info, + const char *errors) +{ + PyObject *res; + int r; + + res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_readable); + if (res == NULL) + return -1; + + r = PyObject_IsTrue(res); + Py_DECREF(res); + if (r == -1) + return -1; + + if (r != 1) + return 0; + + Py_CLEAR(self->decoder); + self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info, errors); + if (self->decoder == NULL) + return -1; + + if (self->readuniversal) { + PyObject *incrementalDecoder = PyObject_CallFunctionObjArgs( + (PyObject *)&PyIncrementalNewlineDecoder_Type, + self->decoder, self->readtranslate ? Py_True : Py_False, NULL); + if (incrementalDecoder == NULL) + return -1; + Py_CLEAR(self->decoder); + self->decoder = incrementalDecoder; + } + + return 0; +} + +static PyObject* +_textiowrapper_decode(PyObject *decoder, PyObject *bytes, int eof) +{ + PyObject *chars; + + if (Py_IS_TYPE(decoder, &PyIncrementalNewlineDecoder_Type)) + chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof); + else + chars = PyObject_CallMethodObjArgs(decoder, _PyIO_str_decode, bytes, + eof ? Py_True : Py_False, NULL); + + if (check_decoded(chars) < 0) + // check_decoded already decreases refcount + return NULL; + + return chars; +} + +static int +_textiowrapper_set_encoder(textio *self, PyObject *codec_info, + const char *errors) +{ + PyObject *res; + int r; + + res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_writable); + if (res == NULL) + return -1; + + r = PyObject_IsTrue(res); + Py_DECREF(res); + if (r == -1) + return -1; + + if (r != 1) + return 0; + + Py_CLEAR(self->encoder); + self->encodefunc = NULL; + self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info, errors); + if (self->encoder == NULL) + return -1; + + /* Get the normalized named of the codec */ + if (_PyObject_LookupAttrId(codec_info, &PyId_name, &res) < 0) { + return -1; + } + if (res != NULL && PyUnicode_Check(res)) { + const encodefuncentry *e = encodefuncs; + while (e->name != NULL) { + if (_PyUnicode_EqualToASCIIString(res, e->name)) { + self->encodefunc = e->encodefunc; + break; + } + e++; + } + } + Py_XDECREF(res); + + return 0; +} + +static int +_textiowrapper_fix_encoder_state(textio *self) +{ + if (!self->seekable || !self->encoder) { + return 0; + } + + self->encoding_start_of_stream = 1; + + PyObject *cookieObj = PyObject_CallMethodNoArgs( + self->buffer, _PyIO_str_tell); + if (cookieObj == NULL) { + return -1; + } + + int cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); + Py_DECREF(cookieObj); + if (cmp < 0) { + return -1; + } + + if (cmp == 0) { + self->encoding_start_of_stream = 0; + PyObject *res = PyObject_CallMethodOneArg( + self->encoder, _PyIO_str_setstate, _PyLong_Zero); + if (res == NULL) { + return -1; + } + Py_DECREF(res); + } + + return 0; +} + static int -validate_newline(const char *newline) +io_check_errors(PyObject *errors) { - if (newline && newline[0] != '\0' - && !(newline[0] == '\n' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { - PyErr_Format(PyExc_ValueError, - "illegal newline value: %s", newline); - return -1; - } - return 0; -} + assert(errors != NULL && errors != Py_None); -static int -set_newline(textio *self, const char *newline) -{ - PyObject *old = self->readnl; - if (newline == NULL) { - self->readnl = NULL; - } - else { - self->readnl = PyUnicode_FromString(newline); - if (self->readnl == NULL) { - self->readnl = old; - return -1; - } - } - self->readuniversal = (newline == NULL || newline[0] == '\0'); - self->readtranslate = (newline == NULL); - self->writetranslate = (newline == NULL || newline[0] != '\0'); - if (!self->readuniversal && self->readnl != NULL) { - // validate_newline() accepts only ASCII newlines. - assert(PyUnicode_KIND(self->readnl) == PyUnicode_1BYTE_KIND); - self->writenl = (const char *)PyUnicode_1BYTE_DATA(self->readnl); - if (strcmp(self->writenl, "\n") == 0) { - self->writenl = NULL; - } + PyInterpreterState *interp = _PyInterpreterState_GET(); +#ifndef Py_DEBUG + /* In release mode, only check in development mode (-X dev) */ + if (!_PyInterpreterState_GetConfig(interp)->dev_mode) { + return 0; } - else { -#ifdef MS_WINDOWS - self->writenl = "\r\n"; #else - self->writenl = NULL; + /* Always check in debug mode */ #endif - } - Py_XDECREF(old); - return 0; -} -static int -_textiowrapper_set_decoder(textio *self, PyObject *codec_info, - const char *errors) -{ - PyObject *res; - int r; + /* Avoid calling PyCodec_LookupError() before the codec registry is ready: + before_PyUnicode_InitEncodings() is called. */ + if (!interp->unicode.fs_codec.encoding) { + return 0; + } - res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_readable); - if (res == NULL) + Py_ssize_t name_length; + const char *name = PyUnicode_AsUTF8AndSize(errors, &name_length); + if (name == NULL) { return -1; - - r = PyObject_IsTrue(res); - Py_DECREF(res); - if (r == -1) + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character in errors"); return -1; - - if (r != 1) + } + PyObject *handler = PyCodec_LookupError(name); + if (handler != NULL) { + Py_DECREF(handler); return 0; - - Py_CLEAR(self->decoder); - self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info, errors); - if (self->decoder == NULL) - return -1; - - if (self->readuniversal) { - PyObject *incrementalDecoder = PyObject_CallFunctionObjArgs( - (PyObject *)&PyIncrementalNewlineDecoder_Type, - self->decoder, self->readtranslate ? Py_True : Py_False, NULL); - if (incrementalDecoder == NULL) - return -1; - Py_CLEAR(self->decoder); - self->decoder = incrementalDecoder; } - - return 0; + return -1; } -static PyObject* -_textiowrapper_decode(PyObject *decoder, PyObject *bytes, int eof) -{ - PyObject *chars; - - if (Py_IS_TYPE(decoder, &PyIncrementalNewlineDecoder_Type)) - chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof); - else - chars = PyObject_CallMethodObjArgs(decoder, _PyIO_str_decode, bytes, - eof ? Py_True : Py_False, NULL); - - if (check_decoded(chars) < 0) - // check_decoded already decreases refcount - return NULL; - return chars; -} -static int -_textiowrapper_set_encoder(textio *self, PyObject *codec_info, - const char *errors) -{ - PyObject *res; - int r; - - res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_writable); - if (res == NULL) - return -1; - - r = PyObject_IsTrue(res); - Py_DECREF(res); - if (r == -1) - return -1; - - if (r != 1) - return 0; - - Py_CLEAR(self->encoder); - self->encodefunc = NULL; - self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info, errors); - if (self->encoder == NULL) - return -1; - - /* Get the normalized named of the codec */ - if (_PyObject_LookupAttrId(codec_info, &PyId_name, &res) < 0) { - return -1; - } - if (res != NULL && PyUnicode_Check(res)) { - const encodefuncentry *e = encodefuncs; - while (e->name != NULL) { - if (_PyUnicode_EqualToASCIIString(res, e->name)) { - self->encodefunc = e->encodefunc; - break; - } - e++; - } - } - Py_XDECREF(res); - - return 0; -} - -static int -_textiowrapper_fix_encoder_state(textio *self) -{ - if (!self->seekable || !self->encoder) { - return 0; - } - - self->encoding_start_of_stream = 1; - - PyObject *cookieObj = PyObject_CallMethodNoArgs( - self->buffer, _PyIO_str_tell); - if (cookieObj == NULL) { - return -1; - } - - int cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); - Py_DECREF(cookieObj); - if (cmp < 0) { - return -1; - } - - if (cmp == 0) { - self->encoding_start_of_stream = 0; - PyObject *res = PyObject_CallMethodOneArg( - self->encoder, _PyIO_str_setstate, _PyLong_Zero); - if (res == NULL) { - return -1; - } - Py_DECREF(res); - } - - return 0; -} - -static int -io_check_errors(PyObject *errors) -{ - assert(errors != NULL && errors != Py_None); - - PyInterpreterState *interp = _PyInterpreterState_GET(); -#ifndef Py_DEBUG - /* In release mode, only check in development mode (-X dev) */ - if (!_PyInterpreterState_GetConfig(interp)->dev_mode) { - return 0; - } -#else - /* Always check in debug mode */ -#endif - - /* Avoid calling PyCodec_LookupError() before the codec registry is ready: - before_PyUnicode_InitEncodings() is called. */ - if (!interp->unicode.fs_codec.encoding) { - return 0; - } - - Py_ssize_t name_length; - const char *name = PyUnicode_AsUTF8AndSize(errors, &name_length); - if (name == NULL) { - return -1; - } - if (strlen(name) != (size_t)name_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character in errors"); - return -1; - } - PyObject *handler = PyCodec_LookupError(name); - if (handler != NULL) { - Py_DECREF(handler); - return 0; - } - return -1; -} - - - -/*[clinic input] -_io.TextIOWrapper.__init__ - buffer: object +/*[clinic input] +_io.TextIOWrapper.__init__ + buffer: object encoding: str(accept={str, NoneType}) = None - errors: object = None + errors: object = None newline: str(accept={str, NoneType}) = None - line_buffering: bool(accept={int}) = False - write_through: bool(accept={int}) = False - -Character and line based layer over a BufferedIOBase object, buffer. - -encoding gives the name of the encoding that the stream will be -decoded or encoded with. It defaults to locale.getpreferredencoding(False). - -errors determines the strictness of encoding and decoding (see -help(codecs.Codec) or the documentation for codecs.register) and -defaults to "strict". - -newline controls how line endings are handled. It can be None, '', -'\n', '\r', and '\r\n'. It works as follows: - -* On input, if newline is None, universal newlines mode is - enabled. Lines in the input can end in '\n', '\r', or '\r\n', and - these are translated into '\n' before being returned to the - caller. If it is '', universal newline mode is enabled, but line - endings are returned to the caller untranslated. If it has any of - the other legal values, input lines are only terminated by the given - string, and the line ending is returned to the caller untranslated. - -* On output, if newline is None, any '\n' characters written are - translated to the system default line separator, os.linesep. If - newline is '' or '\n', no translation takes place. If newline is any - of the other legal values, any '\n' characters written are translated - to the given string. - -If line_buffering is True, a call to flush is implied when a call to -write contains a newline character. -[clinic start generated code]*/ - -static int -_io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, - const char *encoding, PyObject *errors, - const char *newline, int line_buffering, - int write_through) + line_buffering: bool(accept={int}) = False + write_through: bool(accept={int}) = False + +Character and line based layer over a BufferedIOBase object, buffer. + +encoding gives the name of the encoding that the stream will be +decoded or encoded with. It defaults to locale.getpreferredencoding(False). + +errors determines the strictness of encoding and decoding (see +help(codecs.Codec) or the documentation for codecs.register) and +defaults to "strict". + +newline controls how line endings are handled. It can be None, '', +'\n', '\r', and '\r\n'. It works as follows: + +* On input, if newline is None, universal newlines mode is + enabled. Lines in the input can end in '\n', '\r', or '\r\n', and + these are translated into '\n' before being returned to the + caller. If it is '', universal newline mode is enabled, but line + endings are returned to the caller untranslated. If it has any of + the other legal values, input lines are only terminated by the given + string, and the line ending is returned to the caller untranslated. + +* On output, if newline is None, any '\n' characters written are + translated to the system default line separator, os.linesep. If + newline is '' or '\n', no translation takes place. If newline is any + of the other legal values, any '\n' characters written are translated + to the given string. + +If line_buffering is True, a call to flush is implied when a call to +write contains a newline character. +[clinic start generated code]*/ + +static int +_io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, + const char *encoding, PyObject *errors, + const char *newline, int line_buffering, + int write_through) /*[clinic end generated code: output=72267c0c01032ed2 input=77d8696d1a1f460b]*/ -{ - PyObject *raw, *codec_info = NULL; - _PyIO_State *state = NULL; - PyObject *res; - int r; - - self->ok = 0; - self->detached = 0; - - if (errors == Py_None) { - errors = _PyUnicode_FromId(&PyId_strict); /* borrowed */ - if (errors == NULL) { - return -1; - } - } - else if (!PyUnicode_Check(errors)) { - // Check 'errors' argument here because Argument Clinic doesn't support - // 'str(accept={str, NoneType})' converter. - PyErr_Format( - PyExc_TypeError, - "TextIOWrapper() argument 'errors' must be str or None, not %.50s", +{ + PyObject *raw, *codec_info = NULL; + _PyIO_State *state = NULL; + PyObject *res; + int r; + + self->ok = 0; + self->detached = 0; + + if (errors == Py_None) { + errors = _PyUnicode_FromId(&PyId_strict); /* borrowed */ + if (errors == NULL) { + return -1; + } + } + else if (!PyUnicode_Check(errors)) { + // Check 'errors' argument here because Argument Clinic doesn't support + // 'str(accept={str, NoneType})' converter. + PyErr_Format( + PyExc_TypeError, + "TextIOWrapper() argument 'errors' must be str or None, not %.50s", Py_TYPE(errors)->tp_name); - return -1; - } + return -1; + } else if (io_check_errors(errors)) { return -1; } - - if (validate_newline(newline) < 0) { - return -1; - } - - Py_CLEAR(self->buffer); - Py_CLEAR(self->encoding); - Py_CLEAR(self->encoder); - Py_CLEAR(self->decoder); - Py_CLEAR(self->readnl); - Py_CLEAR(self->decoded_chars); - Py_CLEAR(self->pending_bytes); - Py_CLEAR(self->snapshot); - Py_CLEAR(self->errors); - Py_CLEAR(self->raw); - self->decoded_chars_used = 0; - self->pending_bytes_count = 0; - self->encodefunc = NULL; - self->b2cratio = 0.0; - - if (encoding == NULL) { - /* Try os.device_encoding(fileno) */ - PyObject *fileno; - state = IO_STATE(); - if (state == NULL) - goto error; + + if (validate_newline(newline) < 0) { + return -1; + } + + Py_CLEAR(self->buffer); + Py_CLEAR(self->encoding); + Py_CLEAR(self->encoder); + Py_CLEAR(self->decoder); + Py_CLEAR(self->readnl); + Py_CLEAR(self->decoded_chars); + Py_CLEAR(self->pending_bytes); + Py_CLEAR(self->snapshot); + Py_CLEAR(self->errors); + Py_CLEAR(self->raw); + self->decoded_chars_used = 0; + self->pending_bytes_count = 0; + self->encodefunc = NULL; + self->b2cratio = 0.0; + + if (encoding == NULL) { + /* Try os.device_encoding(fileno) */ + PyObject *fileno; + state = IO_STATE(); + if (state == NULL) + goto error; fileno = _PyObject_CallMethodIdNoArgs(buffer, &PyId_fileno); - /* Ignore only AttributeError and UnsupportedOperation */ - if (fileno == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError) || - PyErr_ExceptionMatches(state->unsupported_operation)) { - PyErr_Clear(); - } - else { - goto error; - } - } - else { - int fd = _PyLong_AsInt(fileno); - Py_DECREF(fileno); - if (fd == -1 && PyErr_Occurred()) { - goto error; - } - - self->encoding = _Py_device_encoding(fd); - if (self->encoding == NULL) - goto error; - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); - } - } - if (encoding == NULL && self->encoding == NULL) { - PyObject *locale_module = _PyIO_get_locale_module(state); - if (locale_module == NULL) - goto catch_ImportError; + /* Ignore only AttributeError and UnsupportedOperation */ + if (fileno == NULL) { + if (PyErr_ExceptionMatches(PyExc_AttributeError) || + PyErr_ExceptionMatches(state->unsupported_operation)) { + PyErr_Clear(); + } + else { + goto error; + } + } + else { + int fd = _PyLong_AsInt(fileno); + Py_DECREF(fileno); + if (fd == -1 && PyErr_Occurred()) { + goto error; + } + + self->encoding = _Py_device_encoding(fd); + if (self->encoding == NULL) + goto error; + else if (!PyUnicode_Check(self->encoding)) + Py_CLEAR(self->encoding); + } + } + if (encoding == NULL && self->encoding == NULL) { + PyObject *locale_module = _PyIO_get_locale_module(state); + if (locale_module == NULL) + goto catch_ImportError; self->encoding = _PyObject_CallMethodIdOneArg( locale_module, &PyId_getpreferredencoding, Py_False); - Py_DECREF(locale_module); - if (self->encoding == NULL) { - catch_ImportError: - /* - Importing locale can raise an ImportError because of - _functools, and locale.getpreferredencoding can raise an - ImportError if _locale is not available. These will happen - during module building. - */ - if (PyErr_ExceptionMatches(PyExc_ImportError)) { - PyErr_Clear(); - self->encoding = PyUnicode_FromString("ascii"); - } - else - goto error; - } - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); - } - if (self->encoding != NULL) { - encoding = PyUnicode_AsUTF8(self->encoding); - if (encoding == NULL) - goto error; - } - else if (encoding != NULL) { - self->encoding = PyUnicode_FromString(encoding); - if (self->encoding == NULL) - goto error; - } - else { - PyErr_SetString(PyExc_OSError, - "could not determine default encoding"); - goto error; - } - - /* Check we have been asked for a real text encoding */ - codec_info = _PyCodec_LookupTextEncoding(encoding, "codecs.open()"); - if (codec_info == NULL) { - Py_CLEAR(self->encoding); - goto error; - } - - /* XXX: Failures beyond this point have the potential to leak elements - * of the partially constructed object (like self->encoding) - */ - - Py_INCREF(errors); - self->errors = errors; - self->chunk_size = 8192; - self->line_buffering = line_buffering; - self->write_through = write_through; - if (set_newline(self, newline) < 0) { - goto error; - } - - self->buffer = buffer; - Py_INCREF(buffer); - - /* Build the decoder object */ - if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0) - goto error; - - /* Build the encoder object */ - if (_textiowrapper_set_encoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0) - goto error; - - /* Finished sorting out the codec details */ - Py_CLEAR(codec_info); - + Py_DECREF(locale_module); + if (self->encoding == NULL) { + catch_ImportError: + /* + Importing locale can raise an ImportError because of + _functools, and locale.getpreferredencoding can raise an + ImportError if _locale is not available. These will happen + during module building. + */ + if (PyErr_ExceptionMatches(PyExc_ImportError)) { + PyErr_Clear(); + self->encoding = PyUnicode_FromString("ascii"); + } + else + goto error; + } + else if (!PyUnicode_Check(self->encoding)) + Py_CLEAR(self->encoding); + } + if (self->encoding != NULL) { + encoding = PyUnicode_AsUTF8(self->encoding); + if (encoding == NULL) + goto error; + } + else if (encoding != NULL) { + self->encoding = PyUnicode_FromString(encoding); + if (self->encoding == NULL) + goto error; + } + else { + PyErr_SetString(PyExc_OSError, + "could not determine default encoding"); + goto error; + } + + /* Check we have been asked for a real text encoding */ + codec_info = _PyCodec_LookupTextEncoding(encoding, "codecs.open()"); + if (codec_info == NULL) { + Py_CLEAR(self->encoding); + goto error; + } + + /* XXX: Failures beyond this point have the potential to leak elements + * of the partially constructed object (like self->encoding) + */ + + Py_INCREF(errors); + self->errors = errors; + self->chunk_size = 8192; + self->line_buffering = line_buffering; + self->write_through = write_through; + if (set_newline(self, newline) < 0) { + goto error; + } + + self->buffer = buffer; + Py_INCREF(buffer); + + /* Build the decoder object */ + if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0) + goto error; + + /* Build the encoder object */ + if (_textiowrapper_set_encoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0) + goto error; + + /* Finished sorting out the codec details */ + Py_CLEAR(codec_info); + if (Py_IS_TYPE(buffer, &PyBufferedReader_Type) || Py_IS_TYPE(buffer, &PyBufferedWriter_Type) || Py_IS_TYPE(buffer, &PyBufferedRandom_Type)) - { - if (_PyObject_LookupAttrId(buffer, &PyId_raw, &raw) < 0) - goto error; - /* Cache the raw FileIO object to speed up 'closed' checks */ - if (raw != NULL) { + { + if (_PyObject_LookupAttrId(buffer, &PyId_raw, &raw) < 0) + goto error; + /* Cache the raw FileIO object to speed up 'closed' checks */ + if (raw != NULL) { if (Py_IS_TYPE(raw, &PyFileIO_Type)) - self->raw = raw; - else - Py_DECREF(raw); - } - } - + self->raw = raw; + else + Py_DECREF(raw); + } + } + res = _PyObject_CallMethodIdNoArgs(buffer, &PyId_seekable); - if (res == NULL) - goto error; - r = PyObject_IsTrue(res); - Py_DECREF(res); - if (r < 0) - goto error; - self->seekable = self->telling = r; - - r = _PyObject_LookupAttr(buffer, _PyIO_str_read1, &res); - if (r < 0) { - goto error; - } - Py_XDECREF(res); - self->has_read1 = r; - - self->encoding_start_of_stream = 0; - if (_textiowrapper_fix_encoder_state(self) < 0) { - goto error; - } - - self->ok = 1; - return 0; - - error: - Py_XDECREF(codec_info); - return -1; -} - -/* Return *default_value* if ob is None, 0 if ob is false, 1 if ob is true, - * -1 on error. - */ -static int -convert_optional_bool(PyObject *obj, int default_value) -{ - long v; - if (obj == Py_None) { - v = default_value; - } - else { - v = PyLong_AsLong(obj); - if (v == -1 && PyErr_Occurred()) - return -1; - } - return v != 0; -} - -static int -textiowrapper_change_encoding(textio *self, PyObject *encoding, - PyObject *errors, int newline_changed) -{ - /* Use existing settings where new settings are not specified */ - if (encoding == Py_None && errors == Py_None && !newline_changed) { - return 0; // no change - } - - if (encoding == Py_None) { - encoding = self->encoding; - if (errors == Py_None) { - errors = self->errors; - } - } - else if (errors == Py_None) { - errors = _PyUnicode_FromId(&PyId_strict); - if (errors == NULL) { - return -1; - } - } - - const char *c_errors = PyUnicode_AsUTF8(errors); - if (c_errors == NULL) { - return -1; - } - - // Create new encoder & decoder - PyObject *codec_info = _PyCodec_LookupTextEncoding( - PyUnicode_AsUTF8(encoding), "codecs.open()"); - if (codec_info == NULL) { - return -1; - } - if (_textiowrapper_set_decoder(self, codec_info, c_errors) != 0 || - _textiowrapper_set_encoder(self, codec_info, c_errors) != 0) { - Py_DECREF(codec_info); - return -1; - } - Py_DECREF(codec_info); - - Py_INCREF(encoding); - Py_INCREF(errors); - Py_SETREF(self->encoding, encoding); - Py_SETREF(self->errors, errors); - - return _textiowrapper_fix_encoder_state(self); -} - -/*[clinic input] -_io.TextIOWrapper.reconfigure - * - encoding: object = None - errors: object = None - newline as newline_obj: object(c_default="NULL") = None - line_buffering as line_buffering_obj: object = None - write_through as write_through_obj: object = None - -Reconfigure the text stream with new parameters. - -This also does an implicit stream flush. - -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, - PyObject *errors, PyObject *newline_obj, - PyObject *line_buffering_obj, - PyObject *write_through_obj) -/*[clinic end generated code: output=52b812ff4b3d4b0f input=671e82136e0f5822]*/ -{ - int line_buffering; - int write_through; - const char *newline = NULL; - - /* Check if something is in the read buffer */ - if (self->decoded_chars != NULL) { - if (encoding != Py_None || errors != Py_None || newline_obj != NULL) { - _unsupported("It is not possible to set the encoding or newline " - "of stream after the first read"); - return NULL; - } - } - - if (newline_obj != NULL && newline_obj != Py_None) { - newline = PyUnicode_AsUTF8(newline_obj); - if (newline == NULL || validate_newline(newline) < 0) { - return NULL; - } - } - - line_buffering = convert_optional_bool(line_buffering_obj, - self->line_buffering); - write_through = convert_optional_bool(write_through_obj, - self->write_through); - if (line_buffering < 0 || write_through < 0) { - return NULL; - } - + if (res == NULL) + goto error; + r = PyObject_IsTrue(res); + Py_DECREF(res); + if (r < 0) + goto error; + self->seekable = self->telling = r; + + r = _PyObject_LookupAttr(buffer, _PyIO_str_read1, &res); + if (r < 0) { + goto error; + } + Py_XDECREF(res); + self->has_read1 = r; + + self->encoding_start_of_stream = 0; + if (_textiowrapper_fix_encoder_state(self) < 0) { + goto error; + } + + self->ok = 1; + return 0; + + error: + Py_XDECREF(codec_info); + return -1; +} + +/* Return *default_value* if ob is None, 0 if ob is false, 1 if ob is true, + * -1 on error. + */ +static int +convert_optional_bool(PyObject *obj, int default_value) +{ + long v; + if (obj == Py_None) { + v = default_value; + } + else { + v = PyLong_AsLong(obj); + if (v == -1 && PyErr_Occurred()) + return -1; + } + return v != 0; +} + +static int +textiowrapper_change_encoding(textio *self, PyObject *encoding, + PyObject *errors, int newline_changed) +{ + /* Use existing settings where new settings are not specified */ + if (encoding == Py_None && errors == Py_None && !newline_changed) { + return 0; // no change + } + + if (encoding == Py_None) { + encoding = self->encoding; + if (errors == Py_None) { + errors = self->errors; + } + } + else if (errors == Py_None) { + errors = _PyUnicode_FromId(&PyId_strict); + if (errors == NULL) { + return -1; + } + } + + const char *c_errors = PyUnicode_AsUTF8(errors); + if (c_errors == NULL) { + return -1; + } + + // Create new encoder & decoder + PyObject *codec_info = _PyCodec_LookupTextEncoding( + PyUnicode_AsUTF8(encoding), "codecs.open()"); + if (codec_info == NULL) { + return -1; + } + if (_textiowrapper_set_decoder(self, codec_info, c_errors) != 0 || + _textiowrapper_set_encoder(self, codec_info, c_errors) != 0) { + Py_DECREF(codec_info); + return -1; + } + Py_DECREF(codec_info); + + Py_INCREF(encoding); + Py_INCREF(errors); + Py_SETREF(self->encoding, encoding); + Py_SETREF(self->errors, errors); + + return _textiowrapper_fix_encoder_state(self); +} + +/*[clinic input] +_io.TextIOWrapper.reconfigure + * + encoding: object = None + errors: object = None + newline as newline_obj: object(c_default="NULL") = None + line_buffering as line_buffering_obj: object = None + write_through as write_through_obj: object = None + +Reconfigure the text stream with new parameters. + +This also does an implicit stream flush. + +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, + PyObject *errors, PyObject *newline_obj, + PyObject *line_buffering_obj, + PyObject *write_through_obj) +/*[clinic end generated code: output=52b812ff4b3d4b0f input=671e82136e0f5822]*/ +{ + int line_buffering; + int write_through; + const char *newline = NULL; + + /* Check if something is in the read buffer */ + if (self->decoded_chars != NULL) { + if (encoding != Py_None || errors != Py_None || newline_obj != NULL) { + _unsupported("It is not possible to set the encoding or newline " + "of stream after the first read"); + return NULL; + } + } + + if (newline_obj != NULL && newline_obj != Py_None) { + newline = PyUnicode_AsUTF8(newline_obj); + if (newline == NULL || validate_newline(newline) < 0) { + return NULL; + } + } + + line_buffering = convert_optional_bool(line_buffering_obj, + self->line_buffering); + write_through = convert_optional_bool(write_through_obj, + self->write_through); + if (line_buffering < 0 || write_through < 0) { + return NULL; + } + PyObject *res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); - if (res == NULL) { - return NULL; - } - Py_DECREF(res); - self->b2cratio = 0; - - if (newline_obj != NULL && set_newline(self, newline) < 0) { - return NULL; - } - - if (textiowrapper_change_encoding( - self, encoding, errors, newline_obj != NULL) < 0) { - return NULL; - } - - self->line_buffering = line_buffering; - self->write_through = write_through; - Py_RETURN_NONE; -} - -static int -textiowrapper_clear(textio *self) -{ - self->ok = 0; - Py_CLEAR(self->buffer); - Py_CLEAR(self->encoding); - Py_CLEAR(self->encoder); - Py_CLEAR(self->decoder); - Py_CLEAR(self->readnl); - Py_CLEAR(self->decoded_chars); - Py_CLEAR(self->pending_bytes); - Py_CLEAR(self->snapshot); - Py_CLEAR(self->errors); - Py_CLEAR(self->raw); - - Py_CLEAR(self->dict); - return 0; -} - -static void -textiowrapper_dealloc(textio *self) -{ - self->finalizing = 1; - if (_PyIOBase_finalize((PyObject *) self) < 0) - return; - self->ok = 0; - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - textiowrapper_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -textiowrapper_traverse(textio *self, visitproc visit, void *arg) -{ - Py_VISIT(self->buffer); - Py_VISIT(self->encoding); - Py_VISIT(self->encoder); - Py_VISIT(self->decoder); - Py_VISIT(self->readnl); - Py_VISIT(self->decoded_chars); - Py_VISIT(self->pending_bytes); - Py_VISIT(self->snapshot); - Py_VISIT(self->errors); - Py_VISIT(self->raw); - - Py_VISIT(self->dict); - return 0; -} - -static PyObject * -textiowrapper_closed_get(textio *self, void *context); - -/* This macro takes some shortcuts to make the common case faster. */ -#define CHECK_CLOSED(self) \ - do { \ - int r; \ - PyObject *_res; \ + if (res == NULL) { + return NULL; + } + Py_DECREF(res); + self->b2cratio = 0; + + if (newline_obj != NULL && set_newline(self, newline) < 0) { + return NULL; + } + + if (textiowrapper_change_encoding( + self, encoding, errors, newline_obj != NULL) < 0) { + return NULL; + } + + self->line_buffering = line_buffering; + self->write_through = write_through; + Py_RETURN_NONE; +} + +static int +textiowrapper_clear(textio *self) +{ + self->ok = 0; + Py_CLEAR(self->buffer); + Py_CLEAR(self->encoding); + Py_CLEAR(self->encoder); + Py_CLEAR(self->decoder); + Py_CLEAR(self->readnl); + Py_CLEAR(self->decoded_chars); + Py_CLEAR(self->pending_bytes); + Py_CLEAR(self->snapshot); + Py_CLEAR(self->errors); + Py_CLEAR(self->raw); + + Py_CLEAR(self->dict); + return 0; +} + +static void +textiowrapper_dealloc(textio *self) +{ + self->finalizing = 1; + if (_PyIOBase_finalize((PyObject *) self) < 0) + return; + self->ok = 0; + _PyObject_GC_UNTRACK(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)self); + textiowrapper_clear(self); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +textiowrapper_traverse(textio *self, visitproc visit, void *arg) +{ + Py_VISIT(self->buffer); + Py_VISIT(self->encoding); + Py_VISIT(self->encoder); + Py_VISIT(self->decoder); + Py_VISIT(self->readnl); + Py_VISIT(self->decoded_chars); + Py_VISIT(self->pending_bytes); + Py_VISIT(self->snapshot); + Py_VISIT(self->errors); + Py_VISIT(self->raw); + + Py_VISIT(self->dict); + return 0; +} + +static PyObject * +textiowrapper_closed_get(textio *self, void *context); + +/* This macro takes some shortcuts to make the common case faster. */ +#define CHECK_CLOSED(self) \ + do { \ + int r; \ + PyObject *_res; \ if (Py_IS_TYPE(self, &PyTextIOWrapper_Type)) { \ - if (self->raw != NULL) \ - r = _PyFileIO_closed(self->raw); \ - else { \ - _res = textiowrapper_closed_get(self, NULL); \ - if (_res == NULL) \ - return NULL; \ - r = PyObject_IsTrue(_res); \ - Py_DECREF(_res); \ - if (r < 0) \ - return NULL; \ - } \ - if (r > 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file."); \ - return NULL; \ - } \ - } \ - else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \ - return NULL; \ - } while (0) - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_ATTACHED(self) \ - CHECK_INITIALIZED(self); \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "underlying buffer has been detached"); \ - return NULL; \ - } - -#define CHECK_ATTACHED_INT(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return -1; \ - } else if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "underlying buffer has been detached"); \ - return -1; \ - } - - -/*[clinic input] -_io.TextIOWrapper.detach -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_detach_impl(textio *self) -/*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/ -{ - PyObject *buffer, *res; - CHECK_ATTACHED(self); + if (self->raw != NULL) \ + r = _PyFileIO_closed(self->raw); \ + else { \ + _res = textiowrapper_closed_get(self, NULL); \ + if (_res == NULL) \ + return NULL; \ + r = PyObject_IsTrue(_res); \ + Py_DECREF(_res); \ + if (r < 0) \ + return NULL; \ + } \ + if (r > 0) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on closed file."); \ + return NULL; \ + } \ + } \ + else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \ + return NULL; \ + } while (0) + +#define CHECK_INITIALIZED(self) \ + if (self->ok <= 0) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + return NULL; \ + } + +#define CHECK_ATTACHED(self) \ + CHECK_INITIALIZED(self); \ + if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "underlying buffer has been detached"); \ + return NULL; \ + } + +#define CHECK_ATTACHED_INT(self) \ + if (self->ok <= 0) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + return -1; \ + } else if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "underlying buffer has been detached"); \ + return -1; \ + } + + +/*[clinic input] +_io.TextIOWrapper.detach +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_detach_impl(textio *self) +/*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/ +{ + PyObject *buffer, *res; + CHECK_ATTACHED(self); res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); - if (res == NULL) - return NULL; - Py_DECREF(res); - buffer = self->buffer; - self->buffer = NULL; - self->detached = 1; - return buffer; -} - -/* Flush the internal write buffer. This doesn't explicitly flush the - underlying buffered object, though. */ -static int -_textiowrapper_writeflush(textio *self) -{ - if (self->pending_bytes == NULL) - return 0; - + if (res == NULL) + return NULL; + Py_DECREF(res); + buffer = self->buffer; + self->buffer = NULL; + self->detached = 1; + return buffer; +} + +/* Flush the internal write buffer. This doesn't explicitly flush the + underlying buffered object, though. */ +static int +_textiowrapper_writeflush(textio *self) +{ + if (self->pending_bytes == NULL) + return 0; + PyObject *pending = self->pending_bytes; PyObject *b; @@ -1593,74 +1593,74 @@ _textiowrapper_writeflush(textio *self) assert(pos == self->pending_bytes_count); } - self->pending_bytes_count = 0; + self->pending_bytes_count = 0; self->pending_bytes = NULL; Py_DECREF(pending); - + PyObject *ret; - do { + do { ret = PyObject_CallMethodOneArg(self->buffer, _PyIO_str_write, b); - } while (ret == NULL && _PyIO_trap_eintr()); - Py_DECREF(b); + } while (ret == NULL && _PyIO_trap_eintr()); + Py_DECREF(b); // NOTE: We cleared buffer but we don't know how many bytes are actually written // when an error occurred. - if (ret == NULL) - return -1; - Py_DECREF(ret); - return 0; -} - -/*[clinic input] -_io.TextIOWrapper.write - text: unicode - / -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_write_impl(textio *self, PyObject *text) -/*[clinic end generated code: output=d2deb0d50771fcec input=fdf19153584a0e44]*/ -{ - PyObject *ret; - PyObject *b; - Py_ssize_t textlen; - int haslf = 0; - int needflush = 0, text_needflush = 0; - - if (PyUnicode_READY(text) == -1) - return NULL; - - CHECK_ATTACHED(self); - CHECK_CLOSED(self); - - if (self->encoder == NULL) - return _unsupported("not writable"); - - Py_INCREF(text); - - textlen = PyUnicode_GET_LENGTH(text); - - if ((self->writetranslate && self->writenl != NULL) || self->line_buffering) - if (PyUnicode_FindChar(text, '\n', 0, PyUnicode_GET_LENGTH(text), 1) != -1) - haslf = 1; - - if (haslf && self->writetranslate && self->writenl != NULL) { - PyObject *newtext = _PyObject_CallMethodId( - text, &PyId_replace, "ss", "\n", self->writenl); - Py_DECREF(text); - if (newtext == NULL) - return NULL; - text = newtext; - } - - if (self->write_through) - text_needflush = 1; - if (self->line_buffering && - (haslf || - PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1)) - needflush = 1; - - /* XXX What if we were just reading? */ - if (self->encodefunc != NULL) { + if (ret == NULL) + return -1; + Py_DECREF(ret); + return 0; +} + +/*[clinic input] +_io.TextIOWrapper.write + text: unicode + / +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_write_impl(textio *self, PyObject *text) +/*[clinic end generated code: output=d2deb0d50771fcec input=fdf19153584a0e44]*/ +{ + PyObject *ret; + PyObject *b; + Py_ssize_t textlen; + int haslf = 0; + int needflush = 0, text_needflush = 0; + + if (PyUnicode_READY(text) == -1) + return NULL; + + CHECK_ATTACHED(self); + CHECK_CLOSED(self); + + if (self->encoder == NULL) + return _unsupported("not writable"); + + Py_INCREF(text); + + textlen = PyUnicode_GET_LENGTH(text); + + if ((self->writetranslate && self->writenl != NULL) || self->line_buffering) + if (PyUnicode_FindChar(text, '\n', 0, PyUnicode_GET_LENGTH(text), 1) != -1) + haslf = 1; + + if (haslf && self->writetranslate && self->writenl != NULL) { + PyObject *newtext = _PyObject_CallMethodId( + text, &PyId_replace, "ss", "\n", self->writenl); + Py_DECREF(text); + if (newtext == NULL) + return NULL; + text = newtext; + } + + if (self->write_through) + text_needflush = 1; + if (self->line_buffering && + (haslf || + PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1)) + needflush = 1; + + /* XXX What if we were just reading? */ + if (self->encodefunc != NULL) { if (PyUnicode_IS_ASCII(text) && // See bpo-43260 PyUnicode_GET_LENGTH(text) <= self->chunk_size && @@ -1671,1670 +1671,1670 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) else { b = (*self->encodefunc)((PyObject *) self, text); } - self->encoding_start_of_stream = 0; - } + self->encoding_start_of_stream = 0; + } else { b = PyObject_CallMethodOneArg(self->encoder, _PyIO_str_encode, text); - } - - Py_DECREF(text); - if (b == NULL) - return NULL; - if (b != text && !PyBytes_Check(b)) { - PyErr_Format(PyExc_TypeError, - "encoder should return a bytes object, not '%.200s'", - Py_TYPE(b)->tp_name); - Py_DECREF(b); - return NULL; - } - - Py_ssize_t bytes_len; - if (b == text) { - bytes_len = PyUnicode_GET_LENGTH(b); - } - else { - bytes_len = PyBytes_GET_SIZE(b); - } - - if (self->pending_bytes == NULL) { - self->pending_bytes_count = 0; - self->pending_bytes = b; - } - else if (self->pending_bytes_count + bytes_len > self->chunk_size) { - // Prevent to concatenate more than chunk_size data. - if (_textiowrapper_writeflush(self) < 0) { - Py_DECREF(b); - return NULL; - } - self->pending_bytes = b; - } - else if (!PyList_CheckExact(self->pending_bytes)) { - PyObject *list = PyList_New(2); - if (list == NULL) { - Py_DECREF(b); - return NULL; - } - PyList_SET_ITEM(list, 0, self->pending_bytes); - PyList_SET_ITEM(list, 1, b); - self->pending_bytes = list; - } - else { - if (PyList_Append(self->pending_bytes, b) < 0) { - Py_DECREF(b); - return NULL; - } - Py_DECREF(b); - } - - self->pending_bytes_count += bytes_len; - if (self->pending_bytes_count >= self->chunk_size || needflush || - text_needflush) { - if (_textiowrapper_writeflush(self) < 0) - return NULL; - } - - if (needflush) { - ret = PyObject_CallMethodNoArgs(self->buffer, _PyIO_str_flush); - if (ret == NULL) - return NULL; - Py_DECREF(ret); - } - - textiowrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - - if (self->decoder) { - ret = _PyObject_CallMethodIdNoArgs(self->decoder, &PyId_reset); - if (ret == NULL) - return NULL; - Py_DECREF(ret); - } - - return PyLong_FromSsize_t(textlen); -} - -/* Steal a reference to chars and store it in the decoded_char buffer; - */ -static void -textiowrapper_set_decoded_chars(textio *self, PyObject *chars) -{ - Py_XSETREF(self->decoded_chars, chars); - self->decoded_chars_used = 0; -} - -static PyObject * -textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n) -{ - PyObject *chars; - Py_ssize_t avail; - - if (self->decoded_chars == NULL) - return PyUnicode_FromStringAndSize(NULL, 0); - - /* decoded_chars is guaranteed to be "ready". */ - avail = (PyUnicode_GET_LENGTH(self->decoded_chars) - - self->decoded_chars_used); - - assert(avail >= 0); - - if (n < 0 || n > avail) - n = avail; - - if (self->decoded_chars_used > 0 || n < avail) { - chars = PyUnicode_Substring(self->decoded_chars, - self->decoded_chars_used, - self->decoded_chars_used + n); - if (chars == NULL) - return NULL; - } - else { - chars = self->decoded_chars; - Py_INCREF(chars); - } - - self->decoded_chars_used += n; - return chars; -} - -/* Read and decode the next chunk of data from the BufferedReader. - */ -static int -textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) -{ - PyObject *dec_buffer = NULL; - PyObject *dec_flags = NULL; - PyObject *input_chunk = NULL; - Py_buffer input_chunk_buf; - PyObject *decoded_chars, *chunk_size; - Py_ssize_t nbytes, nchars; - int eof; - - /* The return value is True unless EOF was reached. The decoded string is - * placed in self._decoded_chars (replacing its previous value). The - * entire input chunk is sent to the decoder, though some of it may remain - * buffered in the decoder, yet to be converted. - */ - - if (self->decoder == NULL) { - _unsupported("not readable"); - return -1; - } - - if (self->telling) { - /* To prepare for tell(), we need to snapshot a point in the file - * where the decoder's input buffer is empty. - */ - PyObject *state = PyObject_CallMethodNoArgs(self->decoder, - _PyIO_str_getstate); - if (state == NULL) - return -1; - /* Given this, we know there was a valid snapshot point - * len(dec_buffer) bytes ago with decoder state (b'', dec_flags). - */ - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, - "illegal decoder state"); - Py_DECREF(state); - return -1; - } - if (!PyArg_ParseTuple(state, - "OO;illegal decoder state", &dec_buffer, &dec_flags)) - { - Py_DECREF(state); - return -1; - } - - if (!PyBytes_Check(dec_buffer)) { - PyErr_Format(PyExc_TypeError, - "illegal decoder state: the first item should be a " - "bytes object, not '%.200s'", - Py_TYPE(dec_buffer)->tp_name); - Py_DECREF(state); - return -1; - } - Py_INCREF(dec_buffer); - Py_INCREF(dec_flags); - Py_DECREF(state); - } - - /* Read a chunk, decode it, and put the result in self._decoded_chars. */ - if (size_hint > 0) { - size_hint = (Py_ssize_t)(Py_MAX(self->b2cratio, 1.0) * size_hint); - } - chunk_size = PyLong_FromSsize_t(Py_MAX(self->chunk_size, size_hint)); - if (chunk_size == NULL) - goto fail; - - input_chunk = PyObject_CallMethodOneArg(self->buffer, - (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read), - chunk_size); - Py_DECREF(chunk_size); - if (input_chunk == NULL) - goto fail; - - if (PyObject_GetBuffer(input_chunk, &input_chunk_buf, 0) != 0) { - PyErr_Format(PyExc_TypeError, - "underlying %s() should have returned a bytes-like object, " - "not '%.200s'", (self->has_read1 ? "read1": "read"), - Py_TYPE(input_chunk)->tp_name); - goto fail; - } - - nbytes = input_chunk_buf.len; - eof = (nbytes == 0); - - decoded_chars = _textiowrapper_decode(self->decoder, input_chunk, eof); - PyBuffer_Release(&input_chunk_buf); - if (decoded_chars == NULL) - goto fail; - - textiowrapper_set_decoded_chars(self, decoded_chars); - nchars = PyUnicode_GET_LENGTH(decoded_chars); - if (nchars > 0) - self->b2cratio = (double) nbytes / nchars; - else - self->b2cratio = 0.0; - if (nchars > 0) - eof = 0; - - if (self->telling) { - /* At the snapshot point, len(dec_buffer) bytes before the read, the - * next input to be decoded is dec_buffer + input_chunk. - */ - PyObject *next_input = dec_buffer; - PyBytes_Concat(&next_input, input_chunk); - dec_buffer = NULL; /* Reference lost to PyBytes_Concat */ - if (next_input == NULL) { - goto fail; - } - PyObject *snapshot = Py_BuildValue("NN", dec_flags, next_input); - if (snapshot == NULL) { - dec_flags = NULL; - goto fail; - } - Py_XSETREF(self->snapshot, snapshot); - } - Py_DECREF(input_chunk); - - return (eof == 0); - - fail: - Py_XDECREF(dec_buffer); - Py_XDECREF(dec_flags); - Py_XDECREF(input_chunk); - return -1; -} - -/*[clinic input] -_io.TextIOWrapper.read - size as n: Py_ssize_t(accept={int, NoneType}) = -1 - / -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) -/*[clinic end generated code: output=7e651ce6cc6a25a6 input=123eecbfe214aeb8]*/ -{ - PyObject *result = NULL, *chunks = NULL; - - CHECK_ATTACHED(self); - CHECK_CLOSED(self); - - if (self->decoder == NULL) - return _unsupported("not readable"); - - if (_textiowrapper_writeflush(self) < 0) - return NULL; - - if (n < 0) { - /* Read everything */ - PyObject *bytes = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_read); - PyObject *decoded; - if (bytes == NULL) - goto fail; - - if (Py_IS_TYPE(self->decoder, &PyIncrementalNewlineDecoder_Type)) - decoded = _PyIncrementalNewlineDecoder_decode(self->decoder, - bytes, 1); - else - decoded = PyObject_CallMethodObjArgs( - self->decoder, _PyIO_str_decode, bytes, Py_True, NULL); - Py_DECREF(bytes); - if (check_decoded(decoded) < 0) - goto fail; - - result = textiowrapper_get_decoded_chars(self, -1); - - if (result == NULL) { - Py_DECREF(decoded); - return NULL; - } - - PyUnicode_AppendAndDel(&result, decoded); - if (result == NULL) - goto fail; - - textiowrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - return result; - } - else { - int res = 1; - Py_ssize_t remaining = n; - - result = textiowrapper_get_decoded_chars(self, n); - if (result == NULL) - goto fail; - if (PyUnicode_READY(result) == -1) - goto fail; - remaining -= PyUnicode_GET_LENGTH(result); - - /* Keep reading chunks until we have n characters to return */ - while (remaining > 0) { - res = textiowrapper_read_chunk(self, remaining); - if (res < 0) { - /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() - when EINTR occurs so we needn't do it ourselves. */ - if (_PyIO_trap_eintr()) { - continue; - } - goto fail; - } - if (res == 0) /* EOF */ - break; - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto fail; - } - if (PyUnicode_GET_LENGTH(result) > 0 && - PyList_Append(chunks, result) < 0) - goto fail; - Py_DECREF(result); - result = textiowrapper_get_decoded_chars(self, remaining); - if (result == NULL) - goto fail; - remaining -= PyUnicode_GET_LENGTH(result); - } - if (chunks != NULL) { - if (result != NULL && PyList_Append(chunks, result) < 0) - goto fail; - Py_XSETREF(result, PyUnicode_Join(_PyIO_empty_str, chunks)); - if (result == NULL) - goto fail; - Py_CLEAR(chunks); - } - return result; - } - fail: - Py_XDECREF(result); - Py_XDECREF(chunks); - return NULL; -} - - -/* NOTE: `end` must point to the real end of the Py_UCS4 storage, - that is to the NUL character. Otherwise the function will produce - incorrect results. */ -static const char * -find_control_char(int kind, const char *s, const char *end, Py_UCS4 ch) -{ - if (kind == PyUnicode_1BYTE_KIND) { - assert(ch < 256); - return (char *) memchr((const void *) s, (char) ch, end - s); - } - for (;;) { - while (PyUnicode_READ(kind, s, 0) > ch) - s += kind; - if (PyUnicode_READ(kind, s, 0) == ch) - return s; - if (s == end) - return NULL; - s += kind; - } -} - -Py_ssize_t -_PyIO_find_line_ending( - int translated, int universal, PyObject *readnl, - int kind, const char *start, const char *end, Py_ssize_t *consumed) -{ - Py_ssize_t len = (end - start)/kind; - - if (translated) { - /* Newlines are already translated, only search for \n */ - const char *pos = find_control_char(kind, start, end, '\n'); - if (pos != NULL) - return (pos - start)/kind + 1; - else { - *consumed = len; - return -1; - } - } - else if (universal) { - /* Universal newline search. Find any of \r, \r\n, \n - * The decoder ensures that \r\n are not split in two pieces - */ - const char *s = start; - for (;;) { - Py_UCS4 ch; - /* Fast path for non-control chars. The loop always ends - since the Unicode string is NUL-terminated. */ - while (PyUnicode_READ(kind, s, 0) > '\r') - s += kind; - if (s >= end) { - *consumed = len; - return -1; - } - ch = PyUnicode_READ(kind, s, 0); - s += kind; - if (ch == '\n') - return (s - start)/kind; - if (ch == '\r') { - if (PyUnicode_READ(kind, s, 0) == '\n') - return (s - start)/kind + 1; - else - return (s - start)/kind; - } - } - } - else { - /* Non-universal mode. */ - Py_ssize_t readnl_len = PyUnicode_GET_LENGTH(readnl); - const Py_UCS1 *nl = PyUnicode_1BYTE_DATA(readnl); - /* Assume that readnl is an ASCII character. */ - assert(PyUnicode_KIND(readnl) == PyUnicode_1BYTE_KIND); - if (readnl_len == 1) { - const char *pos = find_control_char(kind, start, end, nl[0]); - if (pos != NULL) - return (pos - start)/kind + 1; - *consumed = len; - return -1; - } - else { - const char *s = start; - const char *e = end - (readnl_len - 1)*kind; - const char *pos; - if (e < s) - e = s; - while (s < e) { - Py_ssize_t i; - const char *pos = find_control_char(kind, s, end, nl[0]); - if (pos == NULL || pos >= e) - break; - for (i = 1; i < readnl_len; i++) { - if (PyUnicode_READ(kind, pos, i) != nl[i]) - break; - } - if (i == readnl_len) - return (pos - start)/kind + readnl_len; - s = pos + kind; - } - pos = find_control_char(kind, e, end, nl[0]); - if (pos == NULL) - *consumed = len; - else - *consumed = (pos - start)/kind; - return -1; - } - } -} - -static PyObject * -_textiowrapper_readline(textio *self, Py_ssize_t limit) -{ - PyObject *line = NULL, *chunks = NULL, *remaining = NULL; - Py_ssize_t start, endpos, chunked, offset_to_buffer; - int res; - - CHECK_CLOSED(self); - - if (_textiowrapper_writeflush(self) < 0) - return NULL; - - chunked = 0; - - while (1) { - const char *ptr; - Py_ssize_t line_len; - int kind; - Py_ssize_t consumed = 0; - - /* First, get some data if necessary */ - res = 1; - while (!self->decoded_chars || - !PyUnicode_GET_LENGTH(self->decoded_chars)) { - res = textiowrapper_read_chunk(self, 0); - if (res < 0) { - /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() - when EINTR occurs so we needn't do it ourselves. */ - if (_PyIO_trap_eintr()) { - continue; - } - goto error; - } - if (res == 0) - break; - } - if (res == 0) { - /* end of file */ - textiowrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - start = endpos = offset_to_buffer = 0; - break; - } - - if (remaining == NULL) { - line = self->decoded_chars; - start = self->decoded_chars_used; - offset_to_buffer = 0; - Py_INCREF(line); - } - else { - assert(self->decoded_chars_used == 0); - line = PyUnicode_Concat(remaining, self->decoded_chars); - start = 0; - offset_to_buffer = PyUnicode_GET_LENGTH(remaining); - Py_CLEAR(remaining); - if (line == NULL) - goto error; - if (PyUnicode_READY(line) == -1) - goto error; - } - - ptr = PyUnicode_DATA(line); - line_len = PyUnicode_GET_LENGTH(line); - kind = PyUnicode_KIND(line); - - endpos = _PyIO_find_line_ending( - self->readtranslate, self->readuniversal, self->readnl, - kind, - ptr + kind * start, - ptr + kind * line_len, - &consumed); - if (endpos >= 0) { - endpos += start; - if (limit >= 0 && (endpos - start) + chunked >= limit) - endpos = start + limit - chunked; - break; - } - - /* We can put aside up to `endpos` */ - endpos = consumed + start; - if (limit >= 0 && (endpos - start) + chunked >= limit) { - /* Didn't find line ending, but reached length limit */ - endpos = start + limit - chunked; - break; - } - - if (endpos > start) { - /* No line ending seen yet - put aside current data */ - PyObject *s; - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto error; - } - s = PyUnicode_Substring(line, start, endpos); - if (s == NULL) - goto error; - if (PyList_Append(chunks, s) < 0) { - Py_DECREF(s); - goto error; - } - chunked += PyUnicode_GET_LENGTH(s); - Py_DECREF(s); - } - /* There may be some remaining bytes we'll have to prepend to the - next chunk of data */ - if (endpos < line_len) { - remaining = PyUnicode_Substring(line, endpos, line_len); - if (remaining == NULL) - goto error; - } - Py_CLEAR(line); - /* We have consumed the buffer */ - textiowrapper_set_decoded_chars(self, NULL); - } - - if (line != NULL) { - /* Our line ends in the current buffer */ - self->decoded_chars_used = endpos - offset_to_buffer; - if (start > 0 || endpos < PyUnicode_GET_LENGTH(line)) { - PyObject *s = PyUnicode_Substring(line, start, endpos); - Py_CLEAR(line); - if (s == NULL) - goto error; - line = s; - } - } - if (remaining != NULL) { - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto error; - } - if (PyList_Append(chunks, remaining) < 0) - goto error; - Py_CLEAR(remaining); - } - if (chunks != NULL) { - if (line != NULL) { - if (PyList_Append(chunks, line) < 0) - goto error; - Py_DECREF(line); - } - line = PyUnicode_Join(_PyIO_empty_str, chunks); - if (line == NULL) - goto error; - Py_CLEAR(chunks); - } - if (line == NULL) { - Py_INCREF(_PyIO_empty_str); - line = _PyIO_empty_str; - } - - return line; - - error: - Py_XDECREF(chunks); - Py_XDECREF(remaining); - Py_XDECREF(line); - return NULL; -} - -/*[clinic input] -_io.TextIOWrapper.readline - size: Py_ssize_t = -1 - / -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size) -/*[clinic end generated code: output=344afa98804e8b25 input=56c7172483b36db6]*/ -{ - CHECK_ATTACHED(self); - return _textiowrapper_readline(self, size); -} - -/* Seek and Tell */ - -typedef struct { - Py_off_t start_pos; - int dec_flags; - int bytes_to_feed; - int chars_to_skip; - char need_eof; -} cookie_type; - -/* - To speed up cookie packing/unpacking, we store the fields in a temporary - string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.). - The following macros define at which offsets in the intermediary byte - string the various CookieStruct fields will be stored. - */ - -#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char)) - -#if PY_BIG_ENDIAN -/* We want the least significant byte of start_pos to also be the least - significant byte of the cookie, which means that in big-endian mode we - must copy the fields in reverse order. */ - -# define OFF_START_POS (sizeof(char) + 3 * sizeof(int)) -# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int)) -# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int)) -# define OFF_CHARS_TO_SKIP (sizeof(char)) -# define OFF_NEED_EOF 0 - -#else -/* Little-endian mode: the least significant byte of start_pos will - naturally end up the least significant byte of the cookie. */ - -# define OFF_START_POS 0 -# define OFF_DEC_FLAGS (sizeof(Py_off_t)) -# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int)) -# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int)) -# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int)) - -#endif - -static int -textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj) -{ - unsigned char buffer[COOKIE_BUF_LEN]; - PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj); - if (cookieLong == NULL) - return -1; - - if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer), - PY_LITTLE_ENDIAN, 0) < 0) { - Py_DECREF(cookieLong); - return -1; - } - Py_DECREF(cookieLong); - - memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos)); - memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags)); - memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed)); - memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip)); - memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof)); - - return 0; -} - -static PyObject * -textiowrapper_build_cookie(cookie_type *cookie) -{ - unsigned char buffer[COOKIE_BUF_LEN]; - - memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos)); - memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags)); - memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed)); - memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip)); - memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof)); - - return _PyLong_FromByteArray(buffer, sizeof(buffer), - PY_LITTLE_ENDIAN, 0); -} - -static int -_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) -{ - PyObject *res; - /* When seeking to the start of the stream, we call decoder.reset() - rather than decoder.getstate(). - This is for a few decoders such as utf-16 for which the state value - at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of - utf-16, that we are expecting a BOM). - */ - if (cookie->start_pos == 0 && cookie->dec_flags == 0) - res = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); - else - res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, - "((yi))", "", cookie->dec_flags); - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; -} + } -static int -_textiowrapper_encoder_reset(textio *self, int start_of_stream) -{ - PyObject *res; - if (start_of_stream) { - res = PyObject_CallMethodNoArgs(self->encoder, _PyIO_str_reset); - self->encoding_start_of_stream = 1; + Py_DECREF(text); + if (b == NULL) + return NULL; + if (b != text && !PyBytes_Check(b)) { + PyErr_Format(PyExc_TypeError, + "encoder should return a bytes object, not '%.200s'", + Py_TYPE(b)->tp_name); + Py_DECREF(b); + return NULL; + } + + Py_ssize_t bytes_len; + if (b == text) { + bytes_len = PyUnicode_GET_LENGTH(b); } else { - res = PyObject_CallMethodOneArg(self->encoder, _PyIO_str_setstate, - _PyLong_Zero); - self->encoding_start_of_stream = 0; + bytes_len = PyBytes_GET_SIZE(b); } - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; -} - -static int -_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) -{ - /* Same as _textiowrapper_decoder_setstate() above. */ - return _textiowrapper_encoder_reset( - self, cookie->start_pos == 0 && cookie->dec_flags == 0); -} - -/*[clinic input] -_io.TextIOWrapper.seek - cookie as cookieObj: object - whence: int = 0 - / -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) -/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/ -{ - PyObject *posobj; - cookie_type cookie; - PyObject *res; - int cmp; - PyObject *snapshot; - CHECK_ATTACHED(self); - CHECK_CLOSED(self); - - Py_INCREF(cookieObj); - - if (!self->seekable) { - _unsupported("underlying stream is not seekable"); - goto fail; + if (self->pending_bytes == NULL) { + self->pending_bytes_count = 0; + self->pending_bytes = b; + } + else if (self->pending_bytes_count + bytes_len > self->chunk_size) { + // Prevent to concatenate more than chunk_size data. + if (_textiowrapper_writeflush(self) < 0) { + Py_DECREF(b); + return NULL; + } + self->pending_bytes = b; } + else if (!PyList_CheckExact(self->pending_bytes)) { + PyObject *list = PyList_New(2); + if (list == NULL) { + Py_DECREF(b); + return NULL; + } + PyList_SET_ITEM(list, 0, self->pending_bytes); + PyList_SET_ITEM(list, 1, b); + self->pending_bytes = list; + } + else { + if (PyList_Append(self->pending_bytes, b) < 0) { + Py_DECREF(b); + return NULL; + } + Py_DECREF(b); + } + self->pending_bytes_count += bytes_len; + if (self->pending_bytes_count >= self->chunk_size || needflush || + text_needflush) { + if (_textiowrapper_writeflush(self) < 0) + return NULL; + } + + if (needflush) { + ret = PyObject_CallMethodNoArgs(self->buffer, _PyIO_str_flush); + if (ret == NULL) + return NULL; + Py_DECREF(ret); + } + + textiowrapper_set_decoded_chars(self, NULL); + Py_CLEAR(self->snapshot); + + if (self->decoder) { + ret = _PyObject_CallMethodIdNoArgs(self->decoder, &PyId_reset); + if (ret == NULL) + return NULL; + Py_DECREF(ret); + } + + return PyLong_FromSsize_t(textlen); +} + +/* Steal a reference to chars and store it in the decoded_char buffer; + */ +static void +textiowrapper_set_decoded_chars(textio *self, PyObject *chars) +{ + Py_XSETREF(self->decoded_chars, chars); + self->decoded_chars_used = 0; +} + +static PyObject * +textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n) +{ + PyObject *chars; + Py_ssize_t avail; + + if (self->decoded_chars == NULL) + return PyUnicode_FromStringAndSize(NULL, 0); + + /* decoded_chars is guaranteed to be "ready". */ + avail = (PyUnicode_GET_LENGTH(self->decoded_chars) + - self->decoded_chars_used); + + assert(avail >= 0); + + if (n < 0 || n > avail) + n = avail; + + if (self->decoded_chars_used > 0 || n < avail) { + chars = PyUnicode_Substring(self->decoded_chars, + self->decoded_chars_used, + self->decoded_chars_used + n); + if (chars == NULL) + return NULL; + } + else { + chars = self->decoded_chars; + Py_INCREF(chars); + } + + self->decoded_chars_used += n; + return chars; +} + +/* Read and decode the next chunk of data from the BufferedReader. + */ +static int +textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) +{ + PyObject *dec_buffer = NULL; + PyObject *dec_flags = NULL; + PyObject *input_chunk = NULL; + Py_buffer input_chunk_buf; + PyObject *decoded_chars, *chunk_size; + Py_ssize_t nbytes, nchars; + int eof; + + /* The return value is True unless EOF was reached. The decoded string is + * placed in self._decoded_chars (replacing its previous value). The + * entire input chunk is sent to the decoder, though some of it may remain + * buffered in the decoder, yet to be converted. + */ + + if (self->decoder == NULL) { + _unsupported("not readable"); + return -1; + } + + if (self->telling) { + /* To prepare for tell(), we need to snapshot a point in the file + * where the decoder's input buffer is empty. + */ + PyObject *state = PyObject_CallMethodNoArgs(self->decoder, + _PyIO_str_getstate); + if (state == NULL) + return -1; + /* Given this, we know there was a valid snapshot point + * len(dec_buffer) bytes ago with decoder state (b'', dec_flags). + */ + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, + "illegal decoder state"); + Py_DECREF(state); + return -1; + } + if (!PyArg_ParseTuple(state, + "OO;illegal decoder state", &dec_buffer, &dec_flags)) + { + Py_DECREF(state); + return -1; + } + + if (!PyBytes_Check(dec_buffer)) { + PyErr_Format(PyExc_TypeError, + "illegal decoder state: the first item should be a " + "bytes object, not '%.200s'", + Py_TYPE(dec_buffer)->tp_name); + Py_DECREF(state); + return -1; + } + Py_INCREF(dec_buffer); + Py_INCREF(dec_flags); + Py_DECREF(state); + } + + /* Read a chunk, decode it, and put the result in self._decoded_chars. */ + if (size_hint > 0) { + size_hint = (Py_ssize_t)(Py_MAX(self->b2cratio, 1.0) * size_hint); + } + chunk_size = PyLong_FromSsize_t(Py_MAX(self->chunk_size, size_hint)); + if (chunk_size == NULL) + goto fail; + + input_chunk = PyObject_CallMethodOneArg(self->buffer, + (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read), + chunk_size); + Py_DECREF(chunk_size); + if (input_chunk == NULL) + goto fail; + + if (PyObject_GetBuffer(input_chunk, &input_chunk_buf, 0) != 0) { + PyErr_Format(PyExc_TypeError, + "underlying %s() should have returned a bytes-like object, " + "not '%.200s'", (self->has_read1 ? "read1": "read"), + Py_TYPE(input_chunk)->tp_name); + goto fail; + } + + nbytes = input_chunk_buf.len; + eof = (nbytes == 0); + + decoded_chars = _textiowrapper_decode(self->decoder, input_chunk, eof); + PyBuffer_Release(&input_chunk_buf); + if (decoded_chars == NULL) + goto fail; + + textiowrapper_set_decoded_chars(self, decoded_chars); + nchars = PyUnicode_GET_LENGTH(decoded_chars); + if (nchars > 0) + self->b2cratio = (double) nbytes / nchars; + else + self->b2cratio = 0.0; + if (nchars > 0) + eof = 0; + + if (self->telling) { + /* At the snapshot point, len(dec_buffer) bytes before the read, the + * next input to be decoded is dec_buffer + input_chunk. + */ + PyObject *next_input = dec_buffer; + PyBytes_Concat(&next_input, input_chunk); + dec_buffer = NULL; /* Reference lost to PyBytes_Concat */ + if (next_input == NULL) { + goto fail; + } + PyObject *snapshot = Py_BuildValue("NN", dec_flags, next_input); + if (snapshot == NULL) { + dec_flags = NULL; + goto fail; + } + Py_XSETREF(self->snapshot, snapshot); + } + Py_DECREF(input_chunk); + + return (eof == 0); + + fail: + Py_XDECREF(dec_buffer); + Py_XDECREF(dec_flags); + Py_XDECREF(input_chunk); + return -1; +} + +/*[clinic input] +_io.TextIOWrapper.read + size as n: Py_ssize_t(accept={int, NoneType}) = -1 + / +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) +/*[clinic end generated code: output=7e651ce6cc6a25a6 input=123eecbfe214aeb8]*/ +{ + PyObject *result = NULL, *chunks = NULL; + + CHECK_ATTACHED(self); + CHECK_CLOSED(self); + + if (self->decoder == NULL) + return _unsupported("not readable"); + + if (_textiowrapper_writeflush(self) < 0) + return NULL; + + if (n < 0) { + /* Read everything */ + PyObject *bytes = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_read); + PyObject *decoded; + if (bytes == NULL) + goto fail; + + if (Py_IS_TYPE(self->decoder, &PyIncrementalNewlineDecoder_Type)) + decoded = _PyIncrementalNewlineDecoder_decode(self->decoder, + bytes, 1); + else + decoded = PyObject_CallMethodObjArgs( + self->decoder, _PyIO_str_decode, bytes, Py_True, NULL); + Py_DECREF(bytes); + if (check_decoded(decoded) < 0) + goto fail; + + result = textiowrapper_get_decoded_chars(self, -1); + + if (result == NULL) { + Py_DECREF(decoded); + return NULL; + } + + PyUnicode_AppendAndDel(&result, decoded); + if (result == NULL) + goto fail; + + textiowrapper_set_decoded_chars(self, NULL); + Py_CLEAR(self->snapshot); + return result; + } + else { + int res = 1; + Py_ssize_t remaining = n; + + result = textiowrapper_get_decoded_chars(self, n); + if (result == NULL) + goto fail; + if (PyUnicode_READY(result) == -1) + goto fail; + remaining -= PyUnicode_GET_LENGTH(result); + + /* Keep reading chunks until we have n characters to return */ + while (remaining > 0) { + res = textiowrapper_read_chunk(self, remaining); + if (res < 0) { + /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() + when EINTR occurs so we needn't do it ourselves. */ + if (_PyIO_trap_eintr()) { + continue; + } + goto fail; + } + if (res == 0) /* EOF */ + break; + if (chunks == NULL) { + chunks = PyList_New(0); + if (chunks == NULL) + goto fail; + } + if (PyUnicode_GET_LENGTH(result) > 0 && + PyList_Append(chunks, result) < 0) + goto fail; + Py_DECREF(result); + result = textiowrapper_get_decoded_chars(self, remaining); + if (result == NULL) + goto fail; + remaining -= PyUnicode_GET_LENGTH(result); + } + if (chunks != NULL) { + if (result != NULL && PyList_Append(chunks, result) < 0) + goto fail; + Py_XSETREF(result, PyUnicode_Join(_PyIO_empty_str, chunks)); + if (result == NULL) + goto fail; + Py_CLEAR(chunks); + } + return result; + } + fail: + Py_XDECREF(result); + Py_XDECREF(chunks); + return NULL; +} + + +/* NOTE: `end` must point to the real end of the Py_UCS4 storage, + that is to the NUL character. Otherwise the function will produce + incorrect results. */ +static const char * +find_control_char(int kind, const char *s, const char *end, Py_UCS4 ch) +{ + if (kind == PyUnicode_1BYTE_KIND) { + assert(ch < 256); + return (char *) memchr((const void *) s, (char) ch, end - s); + } + for (;;) { + while (PyUnicode_READ(kind, s, 0) > ch) + s += kind; + if (PyUnicode_READ(kind, s, 0) == ch) + return s; + if (s == end) + return NULL; + s += kind; + } +} + +Py_ssize_t +_PyIO_find_line_ending( + int translated, int universal, PyObject *readnl, + int kind, const char *start, const char *end, Py_ssize_t *consumed) +{ + Py_ssize_t len = (end - start)/kind; + + if (translated) { + /* Newlines are already translated, only search for \n */ + const char *pos = find_control_char(kind, start, end, '\n'); + if (pos != NULL) + return (pos - start)/kind + 1; + else { + *consumed = len; + return -1; + } + } + else if (universal) { + /* Universal newline search. Find any of \r, \r\n, \n + * The decoder ensures that \r\n are not split in two pieces + */ + const char *s = start; + for (;;) { + Py_UCS4 ch; + /* Fast path for non-control chars. The loop always ends + since the Unicode string is NUL-terminated. */ + while (PyUnicode_READ(kind, s, 0) > '\r') + s += kind; + if (s >= end) { + *consumed = len; + return -1; + } + ch = PyUnicode_READ(kind, s, 0); + s += kind; + if (ch == '\n') + return (s - start)/kind; + if (ch == '\r') { + if (PyUnicode_READ(kind, s, 0) == '\n') + return (s - start)/kind + 1; + else + return (s - start)/kind; + } + } + } + else { + /* Non-universal mode. */ + Py_ssize_t readnl_len = PyUnicode_GET_LENGTH(readnl); + const Py_UCS1 *nl = PyUnicode_1BYTE_DATA(readnl); + /* Assume that readnl is an ASCII character. */ + assert(PyUnicode_KIND(readnl) == PyUnicode_1BYTE_KIND); + if (readnl_len == 1) { + const char *pos = find_control_char(kind, start, end, nl[0]); + if (pos != NULL) + return (pos - start)/kind + 1; + *consumed = len; + return -1; + } + else { + const char *s = start; + const char *e = end - (readnl_len - 1)*kind; + const char *pos; + if (e < s) + e = s; + while (s < e) { + Py_ssize_t i; + const char *pos = find_control_char(kind, s, end, nl[0]); + if (pos == NULL || pos >= e) + break; + for (i = 1; i < readnl_len; i++) { + if (PyUnicode_READ(kind, pos, i) != nl[i]) + break; + } + if (i == readnl_len) + return (pos - start)/kind + readnl_len; + s = pos + kind; + } + pos = find_control_char(kind, e, end, nl[0]); + if (pos == NULL) + *consumed = len; + else + *consumed = (pos - start)/kind; + return -1; + } + } +} + +static PyObject * +_textiowrapper_readline(textio *self, Py_ssize_t limit) +{ + PyObject *line = NULL, *chunks = NULL, *remaining = NULL; + Py_ssize_t start, endpos, chunked, offset_to_buffer; + int res; + + CHECK_CLOSED(self); + + if (_textiowrapper_writeflush(self) < 0) + return NULL; + + chunked = 0; + + while (1) { + const char *ptr; + Py_ssize_t line_len; + int kind; + Py_ssize_t consumed = 0; + + /* First, get some data if necessary */ + res = 1; + while (!self->decoded_chars || + !PyUnicode_GET_LENGTH(self->decoded_chars)) { + res = textiowrapper_read_chunk(self, 0); + if (res < 0) { + /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() + when EINTR occurs so we needn't do it ourselves. */ + if (_PyIO_trap_eintr()) { + continue; + } + goto error; + } + if (res == 0) + break; + } + if (res == 0) { + /* end of file */ + textiowrapper_set_decoded_chars(self, NULL); + Py_CLEAR(self->snapshot); + start = endpos = offset_to_buffer = 0; + break; + } + + if (remaining == NULL) { + line = self->decoded_chars; + start = self->decoded_chars_used; + offset_to_buffer = 0; + Py_INCREF(line); + } + else { + assert(self->decoded_chars_used == 0); + line = PyUnicode_Concat(remaining, self->decoded_chars); + start = 0; + offset_to_buffer = PyUnicode_GET_LENGTH(remaining); + Py_CLEAR(remaining); + if (line == NULL) + goto error; + if (PyUnicode_READY(line) == -1) + goto error; + } + + ptr = PyUnicode_DATA(line); + line_len = PyUnicode_GET_LENGTH(line); + kind = PyUnicode_KIND(line); + + endpos = _PyIO_find_line_ending( + self->readtranslate, self->readuniversal, self->readnl, + kind, + ptr + kind * start, + ptr + kind * line_len, + &consumed); + if (endpos >= 0) { + endpos += start; + if (limit >= 0 && (endpos - start) + chunked >= limit) + endpos = start + limit - chunked; + break; + } + + /* We can put aside up to `endpos` */ + endpos = consumed + start; + if (limit >= 0 && (endpos - start) + chunked >= limit) { + /* Didn't find line ending, but reached length limit */ + endpos = start + limit - chunked; + break; + } + + if (endpos > start) { + /* No line ending seen yet - put aside current data */ + PyObject *s; + if (chunks == NULL) { + chunks = PyList_New(0); + if (chunks == NULL) + goto error; + } + s = PyUnicode_Substring(line, start, endpos); + if (s == NULL) + goto error; + if (PyList_Append(chunks, s) < 0) { + Py_DECREF(s); + goto error; + } + chunked += PyUnicode_GET_LENGTH(s); + Py_DECREF(s); + } + /* There may be some remaining bytes we'll have to prepend to the + next chunk of data */ + if (endpos < line_len) { + remaining = PyUnicode_Substring(line, endpos, line_len); + if (remaining == NULL) + goto error; + } + Py_CLEAR(line); + /* We have consumed the buffer */ + textiowrapper_set_decoded_chars(self, NULL); + } + + if (line != NULL) { + /* Our line ends in the current buffer */ + self->decoded_chars_used = endpos - offset_to_buffer; + if (start > 0 || endpos < PyUnicode_GET_LENGTH(line)) { + PyObject *s = PyUnicode_Substring(line, start, endpos); + Py_CLEAR(line); + if (s == NULL) + goto error; + line = s; + } + } + if (remaining != NULL) { + if (chunks == NULL) { + chunks = PyList_New(0); + if (chunks == NULL) + goto error; + } + if (PyList_Append(chunks, remaining) < 0) + goto error; + Py_CLEAR(remaining); + } + if (chunks != NULL) { + if (line != NULL) { + if (PyList_Append(chunks, line) < 0) + goto error; + Py_DECREF(line); + } + line = PyUnicode_Join(_PyIO_empty_str, chunks); + if (line == NULL) + goto error; + Py_CLEAR(chunks); + } + if (line == NULL) { + Py_INCREF(_PyIO_empty_str); + line = _PyIO_empty_str; + } + + return line; + + error: + Py_XDECREF(chunks); + Py_XDECREF(remaining); + Py_XDECREF(line); + return NULL; +} + +/*[clinic input] +_io.TextIOWrapper.readline + size: Py_ssize_t = -1 + / +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size) +/*[clinic end generated code: output=344afa98804e8b25 input=56c7172483b36db6]*/ +{ + CHECK_ATTACHED(self); + return _textiowrapper_readline(self, size); +} + +/* Seek and Tell */ + +typedef struct { + Py_off_t start_pos; + int dec_flags; + int bytes_to_feed; + int chars_to_skip; + char need_eof; +} cookie_type; + +/* + To speed up cookie packing/unpacking, we store the fields in a temporary + string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.). + The following macros define at which offsets in the intermediary byte + string the various CookieStruct fields will be stored. + */ + +#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char)) + +#if PY_BIG_ENDIAN +/* We want the least significant byte of start_pos to also be the least + significant byte of the cookie, which means that in big-endian mode we + must copy the fields in reverse order. */ + +# define OFF_START_POS (sizeof(char) + 3 * sizeof(int)) +# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int)) +# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int)) +# define OFF_CHARS_TO_SKIP (sizeof(char)) +# define OFF_NEED_EOF 0 + +#else +/* Little-endian mode: the least significant byte of start_pos will + naturally end up the least significant byte of the cookie. */ + +# define OFF_START_POS 0 +# define OFF_DEC_FLAGS (sizeof(Py_off_t)) +# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int)) +# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int)) +# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int)) + +#endif + +static int +textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj) +{ + unsigned char buffer[COOKIE_BUF_LEN]; + PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj); + if (cookieLong == NULL) + return -1; + + if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer), + PY_LITTLE_ENDIAN, 0) < 0) { + Py_DECREF(cookieLong); + return -1; + } + Py_DECREF(cookieLong); + + memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos)); + memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags)); + memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed)); + memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip)); + memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof)); + + return 0; +} + +static PyObject * +textiowrapper_build_cookie(cookie_type *cookie) +{ + unsigned char buffer[COOKIE_BUF_LEN]; + + memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos)); + memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags)); + memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed)); + memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip)); + memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof)); + + return _PyLong_FromByteArray(buffer, sizeof(buffer), + PY_LITTLE_ENDIAN, 0); +} + +static int +_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) +{ + PyObject *res; + /* When seeking to the start of the stream, we call decoder.reset() + rather than decoder.getstate(). + This is for a few decoders such as utf-16 for which the state value + at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of + utf-16, that we are expecting a BOM). + */ + if (cookie->start_pos == 0 && cookie->dec_flags == 0) + res = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); + else + res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, + "((yi))", "", cookie->dec_flags); + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + +static int +_textiowrapper_encoder_reset(textio *self, int start_of_stream) +{ + PyObject *res; + if (start_of_stream) { + res = PyObject_CallMethodNoArgs(self->encoder, _PyIO_str_reset); + self->encoding_start_of_stream = 1; + } + else { + res = PyObject_CallMethodOneArg(self->encoder, _PyIO_str_setstate, + _PyLong_Zero); + self->encoding_start_of_stream = 0; + } + if (res == NULL) + return -1; + Py_DECREF(res); + return 0; +} + +static int +_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) +{ + /* Same as _textiowrapper_decoder_setstate() above. */ + return _textiowrapper_encoder_reset( + self, cookie->start_pos == 0 && cookie->dec_flags == 0); +} + +/*[clinic input] +_io.TextIOWrapper.seek + cookie as cookieObj: object + whence: int = 0 + / +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) +/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/ +{ + PyObject *posobj; + cookie_type cookie; + PyObject *res; + int cmp; + PyObject *snapshot; + + CHECK_ATTACHED(self); + CHECK_CLOSED(self); + + Py_INCREF(cookieObj); + + if (!self->seekable) { + _unsupported("underlying stream is not seekable"); + goto fail; + } + switch (whence) { case SEEK_CUR: - /* seek relative to current position */ - cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); - if (cmp < 0) - goto fail; - - if (cmp == 0) { - _unsupported("can't do nonzero cur-relative seeks"); - goto fail; - } - - /* Seeking to the current position should attempt to - * sync the underlying buffer with the current position. - */ - Py_DECREF(cookieObj); + /* seek relative to current position */ + cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); + if (cmp < 0) + goto fail; + + if (cmp == 0) { + _unsupported("can't do nonzero cur-relative seeks"); + goto fail; + } + + /* Seeking to the current position should attempt to + * sync the underlying buffer with the current position. + */ + Py_DECREF(cookieObj); cookieObj = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_tell); - if (cookieObj == NULL) - goto fail; + if (cookieObj == NULL) + goto fail; break; case SEEK_END: - /* seek relative to end of file */ - cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); - if (cmp < 0) - goto fail; - - if (cmp == 0) { - _unsupported("can't do nonzero end-relative seeks"); - goto fail; - } - + /* seek relative to end of file */ + cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ); + if (cmp < 0) + goto fail; + + if (cmp == 0) { + _unsupported("can't do nonzero end-relative seeks"); + goto fail; + } + res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); - if (res == NULL) - goto fail; - Py_DECREF(res); - - textiowrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - if (self->decoder) { + if (res == NULL) + goto fail; + Py_DECREF(res); + + textiowrapper_set_decoded_chars(self, NULL); + Py_CLEAR(self->snapshot); + if (self->decoder) { res = _PyObject_CallMethodIdNoArgs(self->decoder, &PyId_reset); - if (res == NULL) - goto fail; - Py_DECREF(res); - } - - res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2); - Py_CLEAR(cookieObj); - if (res == NULL) - goto fail; - if (self->encoder) { - /* If seek() == 0, we are at the start of stream, otherwise not */ - cmp = PyObject_RichCompareBool(res, _PyLong_Zero, Py_EQ); - if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) { - Py_DECREF(res); - goto fail; - } - } - return res; + if (res == NULL) + goto fail; + Py_DECREF(res); + } + + res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2); + Py_CLEAR(cookieObj); + if (res == NULL) + goto fail; + if (self->encoder) { + /* If seek() == 0, we are at the start of stream, otherwise not */ + cmp = PyObject_RichCompareBool(res, _PyLong_Zero, Py_EQ); + if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) { + Py_DECREF(res); + goto fail; + } + } + return res; case SEEK_SET: break; default: - PyErr_Format(PyExc_ValueError, + PyErr_Format(PyExc_ValueError, "invalid whence (%d, should be %d, %d or %d)", whence, SEEK_SET, SEEK_CUR, SEEK_END); - goto fail; - } - - cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_LT); - if (cmp < 0) - goto fail; - - if (cmp == 1) { - PyErr_Format(PyExc_ValueError, - "negative seek position %R", cookieObj); - goto fail; - } - + goto fail; + } + + cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_LT); + if (cmp < 0) + goto fail; + + if (cmp == 1) { + PyErr_Format(PyExc_ValueError, + "negative seek position %R", cookieObj); + goto fail; + } + res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); - if (res == NULL) - goto fail; - Py_DECREF(res); - - /* The strategy of seek() is to go back to the safe start point - * and replay the effect of read(chars_to_skip) from there. - */ - if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0) - goto fail; - - /* Seek back to the safe start point. */ - posobj = PyLong_FromOff_t(cookie.start_pos); - if (posobj == NULL) - goto fail; + if (res == NULL) + goto fail; + Py_DECREF(res); + + /* The strategy of seek() is to go back to the safe start point + * and replay the effect of read(chars_to_skip) from there. + */ + if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0) + goto fail; + + /* Seek back to the safe start point. */ + posobj = PyLong_FromOff_t(cookie.start_pos); + if (posobj == NULL) + goto fail; res = PyObject_CallMethodOneArg(self->buffer, _PyIO_str_seek, posobj); - Py_DECREF(posobj); - if (res == NULL) - goto fail; - Py_DECREF(res); - - textiowrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - - /* Restore the decoder to its state from the safe start point. */ - if (self->decoder) { - if (_textiowrapper_decoder_setstate(self, &cookie) < 0) - goto fail; - } - - if (cookie.chars_to_skip) { - /* Just like _read_chunk, feed the decoder and save a snapshot. */ - PyObject *input_chunk = _PyObject_CallMethodId( - self->buffer, &PyId_read, "i", cookie.bytes_to_feed); - PyObject *decoded; - - if (input_chunk == NULL) - goto fail; - - if (!PyBytes_Check(input_chunk)) { - PyErr_Format(PyExc_TypeError, - "underlying read() should have returned a bytes " - "object, not '%.200s'", - Py_TYPE(input_chunk)->tp_name); - Py_DECREF(input_chunk); - goto fail; - } - - snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); - if (snapshot == NULL) { - goto fail; - } - Py_XSETREF(self->snapshot, snapshot); - + Py_DECREF(posobj); + if (res == NULL) + goto fail; + Py_DECREF(res); + + textiowrapper_set_decoded_chars(self, NULL); + Py_CLEAR(self->snapshot); + + /* Restore the decoder to its state from the safe start point. */ + if (self->decoder) { + if (_textiowrapper_decoder_setstate(self, &cookie) < 0) + goto fail; + } + + if (cookie.chars_to_skip) { + /* Just like _read_chunk, feed the decoder and save a snapshot. */ + PyObject *input_chunk = _PyObject_CallMethodId( + self->buffer, &PyId_read, "i", cookie.bytes_to_feed); + PyObject *decoded; + + if (input_chunk == NULL) + goto fail; + + if (!PyBytes_Check(input_chunk)) { + PyErr_Format(PyExc_TypeError, + "underlying read() should have returned a bytes " + "object, not '%.200s'", + Py_TYPE(input_chunk)->tp_name); + Py_DECREF(input_chunk); + goto fail; + } + + snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); + if (snapshot == NULL) { + goto fail; + } + Py_XSETREF(self->snapshot, snapshot); + decoded = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_decode, input_chunk, cookie.need_eof ? Py_True : Py_False, NULL); - - if (check_decoded(decoded) < 0) - goto fail; - - textiowrapper_set_decoded_chars(self, decoded); - - /* Skip chars_to_skip of the decoded characters. */ - if (PyUnicode_GetLength(self->decoded_chars) < cookie.chars_to_skip) { - PyErr_SetString(PyExc_OSError, "can't restore logical file position"); - goto fail; - } - self->decoded_chars_used = cookie.chars_to_skip; - } - else { - snapshot = Py_BuildValue("iy", cookie.dec_flags, ""); - if (snapshot == NULL) - goto fail; - Py_XSETREF(self->snapshot, snapshot); - } - - /* Finally, reset the encoder (merely useful for proper BOM handling) */ - if (self->encoder) { - if (_textiowrapper_encoder_setstate(self, &cookie) < 0) - goto fail; - } - return cookieObj; - fail: - Py_XDECREF(cookieObj); - return NULL; - -} - -/*[clinic input] -_io.TextIOWrapper.tell -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_tell_impl(textio *self) -/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/ -{ - PyObject *res; - PyObject *posobj = NULL; - cookie_type cookie = {0,0,0,0,0}; - PyObject *next_input; - Py_ssize_t chars_to_skip, chars_decoded; - Py_ssize_t skip_bytes, skip_back; - PyObject *saved_state = NULL; + + if (check_decoded(decoded) < 0) + goto fail; + + textiowrapper_set_decoded_chars(self, decoded); + + /* Skip chars_to_skip of the decoded characters. */ + if (PyUnicode_GetLength(self->decoded_chars) < cookie.chars_to_skip) { + PyErr_SetString(PyExc_OSError, "can't restore logical file position"); + goto fail; + } + self->decoded_chars_used = cookie.chars_to_skip; + } + else { + snapshot = Py_BuildValue("iy", cookie.dec_flags, ""); + if (snapshot == NULL) + goto fail; + Py_XSETREF(self->snapshot, snapshot); + } + + /* Finally, reset the encoder (merely useful for proper BOM handling) */ + if (self->encoder) { + if (_textiowrapper_encoder_setstate(self, &cookie) < 0) + goto fail; + } + return cookieObj; + fail: + Py_XDECREF(cookieObj); + return NULL; + +} + +/*[clinic input] +_io.TextIOWrapper.tell +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_tell_impl(textio *self) +/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/ +{ + PyObject *res; + PyObject *posobj = NULL; + cookie_type cookie = {0,0,0,0,0}; + PyObject *next_input; + Py_ssize_t chars_to_skip, chars_decoded; + Py_ssize_t skip_bytes, skip_back; + PyObject *saved_state = NULL; const char *input, *input_end; - Py_ssize_t dec_buffer_len; - int dec_flags; - - CHECK_ATTACHED(self); - CHECK_CLOSED(self); - - if (!self->seekable) { - _unsupported("underlying stream is not seekable"); - goto fail; - } - if (!self->telling) { - PyErr_SetString(PyExc_OSError, - "telling position disabled by next() call"); - goto fail; - } - - if (_textiowrapper_writeflush(self) < 0) - return NULL; + Py_ssize_t dec_buffer_len; + int dec_flags; + + CHECK_ATTACHED(self); + CHECK_CLOSED(self); + + if (!self->seekable) { + _unsupported("underlying stream is not seekable"); + goto fail; + } + if (!self->telling) { + PyErr_SetString(PyExc_OSError, + "telling position disabled by next() call"); + goto fail; + } + + if (_textiowrapper_writeflush(self) < 0) + return NULL; res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); - if (res == NULL) - goto fail; - Py_DECREF(res); - + if (res == NULL) + goto fail; + Py_DECREF(res); + posobj = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_tell); - if (posobj == NULL) - goto fail; - - if (self->decoder == NULL || self->snapshot == NULL) { - assert (self->decoded_chars == NULL || PyUnicode_GetLength(self->decoded_chars) == 0); - return posobj; - } - -#if defined(HAVE_LARGEFILE_SUPPORT) - cookie.start_pos = PyLong_AsLongLong(posobj); -#else - cookie.start_pos = PyLong_AsLong(posobj); -#endif - Py_DECREF(posobj); - if (PyErr_Occurred()) - goto fail; - - /* Skip backward to the snapshot point (see _read_chunk). */ - assert(PyTuple_Check(self->snapshot)); - if (!PyArg_ParseTuple(self->snapshot, "iO", &cookie.dec_flags, &next_input)) - goto fail; - - assert (PyBytes_Check(next_input)); - - cookie.start_pos -= PyBytes_GET_SIZE(next_input); - - /* How many decoded characters have been used up since the snapshot? */ - if (self->decoded_chars_used == 0) { - /* We haven't moved from the snapshot point. */ - return textiowrapper_build_cookie(&cookie); - } - - chars_to_skip = self->decoded_chars_used; - - /* Decoder state will be restored at the end */ + if (posobj == NULL) + goto fail; + + if (self->decoder == NULL || self->snapshot == NULL) { + assert (self->decoded_chars == NULL || PyUnicode_GetLength(self->decoded_chars) == 0); + return posobj; + } + +#if defined(HAVE_LARGEFILE_SUPPORT) + cookie.start_pos = PyLong_AsLongLong(posobj); +#else + cookie.start_pos = PyLong_AsLong(posobj); +#endif + Py_DECREF(posobj); + if (PyErr_Occurred()) + goto fail; + + /* Skip backward to the snapshot point (see _read_chunk). */ + assert(PyTuple_Check(self->snapshot)); + if (!PyArg_ParseTuple(self->snapshot, "iO", &cookie.dec_flags, &next_input)) + goto fail; + + assert (PyBytes_Check(next_input)); + + cookie.start_pos -= PyBytes_GET_SIZE(next_input); + + /* How many decoded characters have been used up since the snapshot? */ + if (self->decoded_chars_used == 0) { + /* We haven't moved from the snapshot point. */ + return textiowrapper_build_cookie(&cookie); + } + + chars_to_skip = self->decoded_chars_used; + + /* Decoder state will be restored at the end */ saved_state = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_getstate); - if (saved_state == NULL) - goto fail; - -#define DECODER_GETSTATE() do { \ - PyObject *dec_buffer; \ + if (saved_state == NULL) + goto fail; + +#define DECODER_GETSTATE() do { \ + PyObject *dec_buffer; \ PyObject *_state = PyObject_CallMethodNoArgs(self->decoder, \ _PyIO_str_getstate); \ - if (_state == NULL) \ - goto fail; \ - if (!PyTuple_Check(_state)) { \ - PyErr_SetString(PyExc_TypeError, \ - "illegal decoder state"); \ - Py_DECREF(_state); \ - goto fail; \ - } \ - if (!PyArg_ParseTuple(_state, "Oi;illegal decoder state", \ - &dec_buffer, &dec_flags)) \ - { \ - Py_DECREF(_state); \ - goto fail; \ - } \ - if (!PyBytes_Check(dec_buffer)) { \ - PyErr_Format(PyExc_TypeError, \ - "illegal decoder state: the first item should be a " \ - "bytes object, not '%.200s'", \ - Py_TYPE(dec_buffer)->tp_name); \ - Py_DECREF(_state); \ - goto fail; \ - } \ - dec_buffer_len = PyBytes_GET_SIZE(dec_buffer); \ - Py_DECREF(_state); \ - } while (0) - -#define DECODER_DECODE(start, len, res) do { \ - PyObject *_decoded = _PyObject_CallMethodId( \ - self->decoder, &PyId_decode, "y#", start, len); \ - if (check_decoded(_decoded) < 0) \ - goto fail; \ - res = PyUnicode_GET_LENGTH(_decoded); \ - Py_DECREF(_decoded); \ - } while (0) - - /* Fast search for an acceptable start point, close to our - current pos */ - skip_bytes = (Py_ssize_t) (self->b2cratio * chars_to_skip); - skip_back = 1; - assert(skip_back <= PyBytes_GET_SIZE(next_input)); - input = PyBytes_AS_STRING(next_input); - while (skip_bytes > 0) { - /* Decode up to temptative start point */ - if (_textiowrapper_decoder_setstate(self, &cookie) < 0) - goto fail; - DECODER_DECODE(input, skip_bytes, chars_decoded); - if (chars_decoded <= chars_to_skip) { - DECODER_GETSTATE(); - if (dec_buffer_len == 0) { - /* Before pos and no bytes buffered in decoder => OK */ - cookie.dec_flags = dec_flags; - chars_to_skip -= chars_decoded; - break; - } - /* Skip back by buffered amount and reset heuristic */ - skip_bytes -= dec_buffer_len; - skip_back = 1; - } - else { - /* We're too far ahead, skip back a bit */ - skip_bytes -= skip_back; - skip_back *= 2; - } - } - if (skip_bytes <= 0) { - skip_bytes = 0; - if (_textiowrapper_decoder_setstate(self, &cookie) < 0) - goto fail; - } - - /* Note our initial start point. */ - cookie.start_pos += skip_bytes; - cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int); - if (chars_to_skip == 0) - goto finally; - - /* We should be close to the desired position. Now feed the decoder one - * byte at a time until we reach the `chars_to_skip` target. - * As we go, note the nearest "safe start point" before the current - * location (a point where the decoder has nothing buffered, so seek() - * can safely start from there and advance to this location). - */ - chars_decoded = 0; - input = PyBytes_AS_STRING(next_input); - input_end = input + PyBytes_GET_SIZE(next_input); - input += skip_bytes; - while (input < input_end) { - Py_ssize_t n; - - DECODER_DECODE(input, (Py_ssize_t)1, n); - /* We got n chars for 1 byte */ - chars_decoded += n; - cookie.bytes_to_feed += 1; - DECODER_GETSTATE(); - - if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) { - /* Decoder buffer is empty, so this is a safe start point. */ - cookie.start_pos += cookie.bytes_to_feed; - chars_to_skip -= chars_decoded; - cookie.dec_flags = dec_flags; - cookie.bytes_to_feed = 0; - chars_decoded = 0; - } - if (chars_decoded >= chars_to_skip) - break; - input++; - } - if (input == input_end) { - /* We didn't get enough decoded data; signal EOF to get more. */ - PyObject *decoded = _PyObject_CallMethodId( + if (_state == NULL) \ + goto fail; \ + if (!PyTuple_Check(_state)) { \ + PyErr_SetString(PyExc_TypeError, \ + "illegal decoder state"); \ + Py_DECREF(_state); \ + goto fail; \ + } \ + if (!PyArg_ParseTuple(_state, "Oi;illegal decoder state", \ + &dec_buffer, &dec_flags)) \ + { \ + Py_DECREF(_state); \ + goto fail; \ + } \ + if (!PyBytes_Check(dec_buffer)) { \ + PyErr_Format(PyExc_TypeError, \ + "illegal decoder state: the first item should be a " \ + "bytes object, not '%.200s'", \ + Py_TYPE(dec_buffer)->tp_name); \ + Py_DECREF(_state); \ + goto fail; \ + } \ + dec_buffer_len = PyBytes_GET_SIZE(dec_buffer); \ + Py_DECREF(_state); \ + } while (0) + +#define DECODER_DECODE(start, len, res) do { \ + PyObject *_decoded = _PyObject_CallMethodId( \ + self->decoder, &PyId_decode, "y#", start, len); \ + if (check_decoded(_decoded) < 0) \ + goto fail; \ + res = PyUnicode_GET_LENGTH(_decoded); \ + Py_DECREF(_decoded); \ + } while (0) + + /* Fast search for an acceptable start point, close to our + current pos */ + skip_bytes = (Py_ssize_t) (self->b2cratio * chars_to_skip); + skip_back = 1; + assert(skip_back <= PyBytes_GET_SIZE(next_input)); + input = PyBytes_AS_STRING(next_input); + while (skip_bytes > 0) { + /* Decode up to temptative start point */ + if (_textiowrapper_decoder_setstate(self, &cookie) < 0) + goto fail; + DECODER_DECODE(input, skip_bytes, chars_decoded); + if (chars_decoded <= chars_to_skip) { + DECODER_GETSTATE(); + if (dec_buffer_len == 0) { + /* Before pos and no bytes buffered in decoder => OK */ + cookie.dec_flags = dec_flags; + chars_to_skip -= chars_decoded; + break; + } + /* Skip back by buffered amount and reset heuristic */ + skip_bytes -= dec_buffer_len; + skip_back = 1; + } + else { + /* We're too far ahead, skip back a bit */ + skip_bytes -= skip_back; + skip_back *= 2; + } + } + if (skip_bytes <= 0) { + skip_bytes = 0; + if (_textiowrapper_decoder_setstate(self, &cookie) < 0) + goto fail; + } + + /* Note our initial start point. */ + cookie.start_pos += skip_bytes; + cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int); + if (chars_to_skip == 0) + goto finally; + + /* We should be close to the desired position. Now feed the decoder one + * byte at a time until we reach the `chars_to_skip` target. + * As we go, note the nearest "safe start point" before the current + * location (a point where the decoder has nothing buffered, so seek() + * can safely start from there and advance to this location). + */ + chars_decoded = 0; + input = PyBytes_AS_STRING(next_input); + input_end = input + PyBytes_GET_SIZE(next_input); + input += skip_bytes; + while (input < input_end) { + Py_ssize_t n; + + DECODER_DECODE(input, (Py_ssize_t)1, n); + /* We got n chars for 1 byte */ + chars_decoded += n; + cookie.bytes_to_feed += 1; + DECODER_GETSTATE(); + + if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) { + /* Decoder buffer is empty, so this is a safe start point. */ + cookie.start_pos += cookie.bytes_to_feed; + chars_to_skip -= chars_decoded; + cookie.dec_flags = dec_flags; + cookie.bytes_to_feed = 0; + chars_decoded = 0; + } + if (chars_decoded >= chars_to_skip) + break; + input++; + } + if (input == input_end) { + /* We didn't get enough decoded data; signal EOF to get more. */ + PyObject *decoded = _PyObject_CallMethodId( self->decoder, &PyId_decode, "yO", "", /* final = */ Py_True); - if (check_decoded(decoded) < 0) - goto fail; - chars_decoded += PyUnicode_GET_LENGTH(decoded); - Py_DECREF(decoded); - cookie.need_eof = 1; - - if (chars_decoded < chars_to_skip) { - PyErr_SetString(PyExc_OSError, - "can't reconstruct logical file position"); - goto fail; - } - } - -finally: + if (check_decoded(decoded) < 0) + goto fail; + chars_decoded += PyUnicode_GET_LENGTH(decoded); + Py_DECREF(decoded); + cookie.need_eof = 1; + + if (chars_decoded < chars_to_skip) { + PyErr_SetString(PyExc_OSError, + "can't reconstruct logical file position"); + goto fail; + } + } + +finally: res = _PyObject_CallMethodIdOneArg(self->decoder, &PyId_setstate, saved_state); - Py_DECREF(saved_state); - if (res == NULL) - return NULL; - Py_DECREF(res); - - /* The returned cookie corresponds to the last safe start point. */ - cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int); - return textiowrapper_build_cookie(&cookie); - -fail: - if (saved_state) { - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); + Py_DECREF(saved_state); + if (res == NULL) + return NULL; + Py_DECREF(res); + + /* The returned cookie corresponds to the last safe start point. */ + cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int); + return textiowrapper_build_cookie(&cookie); + +fail: + if (saved_state) { + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); res = _PyObject_CallMethodIdOneArg(self->decoder, &PyId_setstate, saved_state); - _PyErr_ChainExceptions(type, value, traceback); - Py_DECREF(saved_state); - Py_XDECREF(res); - } - return NULL; -} - -/*[clinic input] -_io.TextIOWrapper.truncate - pos: object = None - / -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) -/*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/ -{ - PyObject *res; - - CHECK_ATTACHED(self) - + _PyErr_ChainExceptions(type, value, traceback); + Py_DECREF(saved_state); + Py_XDECREF(res); + } + return NULL; +} + +/*[clinic input] +_io.TextIOWrapper.truncate + pos: object = None + / +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) +/*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/ +{ + PyObject *res; + + CHECK_ATTACHED(self) + res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); - if (res == NULL) - return NULL; - Py_DECREF(res); - + if (res == NULL) + return NULL; + Py_DECREF(res); + return PyObject_CallMethodOneArg(self->buffer, _PyIO_str_truncate, pos); -} - -static PyObject * -textiowrapper_repr(textio *self) -{ - PyObject *nameobj, *modeobj, *res, *s; - int status; - - CHECK_INITIALIZED(self); - - res = PyUnicode_FromString("<_io.TextIOWrapper"); - if (res == NULL) - return NULL; - - status = Py_ReprEnter((PyObject *)self); - if (status != 0) { - if (status > 0) { - PyErr_Format(PyExc_RuntimeError, - "reentrant call inside %s.__repr__", - Py_TYPE(self)->tp_name); - } - goto error; - } +} + +static PyObject * +textiowrapper_repr(textio *self) +{ + PyObject *nameobj, *modeobj, *res, *s; + int status; + + CHECK_INITIALIZED(self); + + res = PyUnicode_FromString("<_io.TextIOWrapper"); + if (res == NULL) + return NULL; + + status = Py_ReprEnter((PyObject *)self); + if (status != 0) { + if (status > 0) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s.__repr__", + Py_TYPE(self)->tp_name); + } + goto error; + } if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { if (!PyErr_ExceptionMatches(PyExc_ValueError)) { - goto error; + goto error; } /* Ignore ValueError raised if the underlying stream was detached */ PyErr_Clear(); - } + } if (nameobj != NULL) { - s = PyUnicode_FromFormat(" name=%R", nameobj); - Py_DECREF(nameobj); - if (s == NULL) - goto error; - PyUnicode_AppendAndDel(&res, s); - if (res == NULL) - goto error; - } + s = PyUnicode_FromFormat(" name=%R", nameobj); + Py_DECREF(nameobj); + if (s == NULL) + goto error; + PyUnicode_AppendAndDel(&res, s); + if (res == NULL) + goto error; + } if (_PyObject_LookupAttrId((PyObject *) self, &PyId_mode, &modeobj) < 0) { goto error; - } + } if (modeobj != NULL) { - s = PyUnicode_FromFormat(" mode=%R", modeobj); - Py_DECREF(modeobj); - if (s == NULL) - goto error; - PyUnicode_AppendAndDel(&res, s); - if (res == NULL) - goto error; - } - s = PyUnicode_FromFormat("%U encoding=%R>", - res, self->encoding); - Py_DECREF(res); - if (status == 0) { - Py_ReprLeave((PyObject *)self); - } - return s; - - error: - Py_XDECREF(res); - if (status == 0) { - Py_ReprLeave((PyObject *)self); - } - return NULL; -} - - -/* Inquiries */ - -/*[clinic input] -_io.TextIOWrapper.fileno -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_fileno_impl(textio *self) -/*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/ -{ - CHECK_ATTACHED(self); + s = PyUnicode_FromFormat(" mode=%R", modeobj); + Py_DECREF(modeobj); + if (s == NULL) + goto error; + PyUnicode_AppendAndDel(&res, s); + if (res == NULL) + goto error; + } + s = PyUnicode_FromFormat("%U encoding=%R>", + res, self->encoding); + Py_DECREF(res); + if (status == 0) { + Py_ReprLeave((PyObject *)self); + } + return s; + + error: + Py_XDECREF(res); + if (status == 0) { + Py_ReprLeave((PyObject *)self); + } + return NULL; +} + + +/* Inquiries */ + +/*[clinic input] +_io.TextIOWrapper.fileno +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_fileno_impl(textio *self) +/*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/ +{ + CHECK_ATTACHED(self); return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_fileno); -} - -/*[clinic input] -_io.TextIOWrapper.seekable -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_seekable_impl(textio *self) -/*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/ -{ - CHECK_ATTACHED(self); +} + +/*[clinic input] +_io.TextIOWrapper.seekable +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_seekable_impl(textio *self) +/*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/ +{ + CHECK_ATTACHED(self); return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_seekable); -} - -/*[clinic input] -_io.TextIOWrapper.readable -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_readable_impl(textio *self) -/*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/ -{ - CHECK_ATTACHED(self); +} + +/*[clinic input] +_io.TextIOWrapper.readable +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_readable_impl(textio *self) +/*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/ +{ + CHECK_ATTACHED(self); return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_readable); -} - -/*[clinic input] -_io.TextIOWrapper.writable -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_writable_impl(textio *self) -/*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/ -{ - CHECK_ATTACHED(self); +} + +/*[clinic input] +_io.TextIOWrapper.writable +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_writable_impl(textio *self) +/*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/ +{ + CHECK_ATTACHED(self); return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_writable); -} - -/*[clinic input] -_io.TextIOWrapper.isatty -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_isatty_impl(textio *self) -/*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/ -{ - CHECK_ATTACHED(self); +} + +/*[clinic input] +_io.TextIOWrapper.isatty +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_isatty_impl(textio *self) +/*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/ +{ + CHECK_ATTACHED(self); return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_isatty); -} - -/*[clinic input] -_io.TextIOWrapper.flush -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_flush_impl(textio *self) -/*[clinic end generated code: output=59de9165f9c2e4d2 input=928c60590694ab85]*/ -{ - CHECK_ATTACHED(self); - CHECK_CLOSED(self); - self->telling = self->seekable; - if (_textiowrapper_writeflush(self) < 0) - return NULL; +} + +/*[clinic input] +_io.TextIOWrapper.flush +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_flush_impl(textio *self) +/*[clinic end generated code: output=59de9165f9c2e4d2 input=928c60590694ab85]*/ +{ + CHECK_ATTACHED(self); + CHECK_CLOSED(self); + self->telling = self->seekable; + if (_textiowrapper_writeflush(self) < 0) + return NULL; return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_flush); -} - -/*[clinic input] -_io.TextIOWrapper.close -[clinic start generated code]*/ - -static PyObject * -_io_TextIOWrapper_close_impl(textio *self) -/*[clinic end generated code: output=056ccf8b4876e4f4 input=9c2114315eae1948]*/ -{ - PyObject *res; - int r; - CHECK_ATTACHED(self); - - res = textiowrapper_closed_get(self, NULL); - if (res == NULL) - return NULL; - r = PyObject_IsTrue(res); - Py_DECREF(res); - if (r < 0) - return NULL; - - if (r > 0) { - Py_RETURN_NONE; /* stream already closed */ - } - else { - PyObject *exc = NULL, *val, *tb; - if (self->finalizing) { +} + +/*[clinic input] +_io.TextIOWrapper.close +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper_close_impl(textio *self) +/*[clinic end generated code: output=056ccf8b4876e4f4 input=9c2114315eae1948]*/ +{ + PyObject *res; + int r; + CHECK_ATTACHED(self); + + res = textiowrapper_closed_get(self, NULL); + if (res == NULL) + return NULL; + r = PyObject_IsTrue(res); + Py_DECREF(res); + if (r < 0) + return NULL; + + if (r > 0) { + Py_RETURN_NONE; /* stream already closed */ + } + else { + PyObject *exc = NULL, *val, *tb; + if (self->finalizing) { res = _PyObject_CallMethodIdOneArg(self->buffer, &PyId__dealloc_warn, (PyObject *)self); - if (res) - Py_DECREF(res); - else - PyErr_Clear(); - } + if (res) + Py_DECREF(res); + else + PyErr_Clear(); + } res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); - if (res == NULL) - PyErr_Fetch(&exc, &val, &tb); - else - Py_DECREF(res); - + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); + else + Py_DECREF(res); + res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_close); - if (exc != NULL) { - _PyErr_ChainExceptions(exc, val, tb); - Py_CLEAR(res); - } - return res; - } -} - -static PyObject * -textiowrapper_iternext(textio *self) -{ - PyObject *line; - - CHECK_ATTACHED(self); - - self->telling = 0; + if (exc != NULL) { + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(res); + } + return res; + } +} + +static PyObject * +textiowrapper_iternext(textio *self) +{ + PyObject *line; + + CHECK_ATTACHED(self); + + self->telling = 0; if (Py_IS_TYPE(self, &PyTextIOWrapper_Type)) { - /* Skip method call overhead for speed */ - line = _textiowrapper_readline(self, -1); - } - else { + /* Skip method call overhead for speed */ + line = _textiowrapper_readline(self, -1); + } + else { line = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_readline); - if (line && !PyUnicode_Check(line)) { - PyErr_Format(PyExc_OSError, - "readline() should have returned a str object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL || PyUnicode_READY(line) == -1) - return NULL; - - if (PyUnicode_GET_LENGTH(line) == 0) { - /* Reached EOF or would have blocked */ - Py_DECREF(line); - Py_CLEAR(self->snapshot); - self->telling = self->seekable; - return NULL; - } - - return line; -} - -static PyObject * -textiowrapper_name_get(textio *self, void *context) -{ - CHECK_ATTACHED(self); - return _PyObject_GetAttrId(self->buffer, &PyId_name); -} - -static PyObject * -textiowrapper_closed_get(textio *self, void *context) -{ - CHECK_ATTACHED(self); - return PyObject_GetAttr(self->buffer, _PyIO_str_closed); -} - -static PyObject * -textiowrapper_newlines_get(textio *self, void *context) -{ - PyObject *res; - CHECK_ATTACHED(self); - if (self->decoder == NULL || - _PyObject_LookupAttr(self->decoder, _PyIO_str_newlines, &res) == 0) - { - Py_RETURN_NONE; - } - return res; -} - -static PyObject * -textiowrapper_errors_get(textio *self, void *context) -{ - CHECK_INITIALIZED(self); - Py_INCREF(self->errors); - return self->errors; -} - -static PyObject * -textiowrapper_chunk_size_get(textio *self, void *context) -{ - CHECK_ATTACHED(self); - return PyLong_FromSsize_t(self->chunk_size); -} - -static int -textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context) -{ - Py_ssize_t n; - CHECK_ATTACHED_INT(self); - if (arg == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - n = PyNumber_AsSsize_t(arg, PyExc_ValueError); - if (n == -1 && PyErr_Occurred()) - return -1; - if (n <= 0) { - PyErr_SetString(PyExc_ValueError, - "a strictly positive integer is required"); - return -1; - } - self->chunk_size = n; - return 0; -} - -#include "clinic/textio.c.h" - -static PyMethodDef incrementalnewlinedecoder_methods[] = { - _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF - _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF - _IO_INCREMENTALNEWLINEDECODER_SETSTATE_METHODDEF - _IO_INCREMENTALNEWLINEDECODER_RESET_METHODDEF - {NULL} -}; - -static PyGetSetDef incrementalnewlinedecoder_getset[] = { - {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL}, - {NULL} -}; - -PyTypeObject PyIncrementalNewlineDecoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.IncrementalNewlineDecoder", /*tp_name*/ - sizeof(nldecoder_object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/ + if (line && !PyUnicode_Check(line)) { + PyErr_Format(PyExc_OSError, + "readline() should have returned a str object, " + "not '%.200s'", Py_TYPE(line)->tp_name); + Py_DECREF(line); + return NULL; + } + } + + if (line == NULL || PyUnicode_READY(line) == -1) + return NULL; + + if (PyUnicode_GET_LENGTH(line) == 0) { + /* Reached EOF or would have blocked */ + Py_DECREF(line); + Py_CLEAR(self->snapshot); + self->telling = self->seekable; + return NULL; + } + + return line; +} + +static PyObject * +textiowrapper_name_get(textio *self, void *context) +{ + CHECK_ATTACHED(self); + return _PyObject_GetAttrId(self->buffer, &PyId_name); +} + +static PyObject * +textiowrapper_closed_get(textio *self, void *context) +{ + CHECK_ATTACHED(self); + return PyObject_GetAttr(self->buffer, _PyIO_str_closed); +} + +static PyObject * +textiowrapper_newlines_get(textio *self, void *context) +{ + PyObject *res; + CHECK_ATTACHED(self); + if (self->decoder == NULL || + _PyObject_LookupAttr(self->decoder, _PyIO_str_newlines, &res) == 0) + { + Py_RETURN_NONE; + } + return res; +} + +static PyObject * +textiowrapper_errors_get(textio *self, void *context) +{ + CHECK_INITIALIZED(self); + Py_INCREF(self->errors); + return self->errors; +} + +static PyObject * +textiowrapper_chunk_size_get(textio *self, void *context) +{ + CHECK_ATTACHED(self); + return PyLong_FromSsize_t(self->chunk_size); +} + +static int +textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context) +{ + Py_ssize_t n; + CHECK_ATTACHED_INT(self); + if (arg == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + n = PyNumber_AsSsize_t(arg, PyExc_ValueError); + if (n == -1 && PyErr_Occurred()) + return -1; + if (n <= 0) { + PyErr_SetString(PyExc_ValueError, + "a strictly positive integer is required"); + return -1; + } + self->chunk_size = n; + return 0; +} + +#include "clinic/textio.c.h" + +static PyMethodDef incrementalnewlinedecoder_methods[] = { + _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF + _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF + _IO_INCREMENTALNEWLINEDECODER_SETSTATE_METHODDEF + _IO_INCREMENTALNEWLINEDECODER_RESET_METHODDEF + {NULL} +}; + +static PyGetSetDef incrementalnewlinedecoder_getset[] = { + {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL}, + {NULL} +}; + +PyTypeObject PyIncrementalNewlineDecoder_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.IncrementalNewlineDecoder", /*tp_name*/ + sizeof(nldecoder_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - _io_IncrementalNewlineDecoder___init____doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - incrementalnewlinedecoder_methods, /* tp_methods */ - 0, /* tp_members */ - incrementalnewlinedecoder_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _io_IncrementalNewlineDecoder___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -static PyMethodDef textiowrapper_methods[] = { - _IO_TEXTIOWRAPPER_DETACH_METHODDEF - _IO_TEXTIOWRAPPER_RECONFIGURE_METHODDEF - _IO_TEXTIOWRAPPER_WRITE_METHODDEF - _IO_TEXTIOWRAPPER_READ_METHODDEF - _IO_TEXTIOWRAPPER_READLINE_METHODDEF - _IO_TEXTIOWRAPPER_FLUSH_METHODDEF - _IO_TEXTIOWRAPPER_CLOSE_METHODDEF - - _IO_TEXTIOWRAPPER_FILENO_METHODDEF - _IO_TEXTIOWRAPPER_SEEKABLE_METHODDEF - _IO_TEXTIOWRAPPER_READABLE_METHODDEF - _IO_TEXTIOWRAPPER_WRITABLE_METHODDEF - _IO_TEXTIOWRAPPER_ISATTY_METHODDEF - - _IO_TEXTIOWRAPPER_SEEK_METHODDEF - _IO_TEXTIOWRAPPER_TELL_METHODDEF - _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF - {NULL, NULL} -}; - -static PyMemberDef textiowrapper_members[] = { - {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY}, - {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY}, - {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY}, - {"write_through", T_BOOL, offsetof(textio, write_through), READONLY}, - {"_finalizing", T_BOOL, offsetof(textio, finalizing), 0}, - {NULL} -}; - -static PyGetSetDef textiowrapper_getset[] = { - {"name", (getter)textiowrapper_name_get, NULL, NULL}, - {"closed", (getter)textiowrapper_closed_get, NULL, NULL}, -/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL}, -*/ - {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL}, - {"errors", (getter)textiowrapper_errors_get, NULL, NULL}, - {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get, - (setter)textiowrapper_chunk_size_set, NULL}, - {NULL} -}; - -PyTypeObject PyTextIOWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.TextIOWrapper", /*tp_name*/ - sizeof(textio), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)textiowrapper_dealloc, /*tp_dealloc*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + _io_IncrementalNewlineDecoder___init____doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /*tp_weaklistoffset*/ + 0, /* tp_iter */ + 0, /* tp_iternext */ + incrementalnewlinedecoder_methods, /* tp_methods */ + 0, /* tp_members */ + incrementalnewlinedecoder_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + _io_IncrementalNewlineDecoder___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + + +static PyMethodDef textiowrapper_methods[] = { + _IO_TEXTIOWRAPPER_DETACH_METHODDEF + _IO_TEXTIOWRAPPER_RECONFIGURE_METHODDEF + _IO_TEXTIOWRAPPER_WRITE_METHODDEF + _IO_TEXTIOWRAPPER_READ_METHODDEF + _IO_TEXTIOWRAPPER_READLINE_METHODDEF + _IO_TEXTIOWRAPPER_FLUSH_METHODDEF + _IO_TEXTIOWRAPPER_CLOSE_METHODDEF + + _IO_TEXTIOWRAPPER_FILENO_METHODDEF + _IO_TEXTIOWRAPPER_SEEKABLE_METHODDEF + _IO_TEXTIOWRAPPER_READABLE_METHODDEF + _IO_TEXTIOWRAPPER_WRITABLE_METHODDEF + _IO_TEXTIOWRAPPER_ISATTY_METHODDEF + + _IO_TEXTIOWRAPPER_SEEK_METHODDEF + _IO_TEXTIOWRAPPER_TELL_METHODDEF + _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF + {NULL, NULL} +}; + +static PyMemberDef textiowrapper_members[] = { + {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY}, + {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY}, + {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY}, + {"write_through", T_BOOL, offsetof(textio, write_through), READONLY}, + {"_finalizing", T_BOOL, offsetof(textio, finalizing), 0}, + {NULL} +}; + +static PyGetSetDef textiowrapper_getset[] = { + {"name", (getter)textiowrapper_name_get, NULL, NULL}, + {"closed", (getter)textiowrapper_closed_get, NULL, NULL}, +/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL}, +*/ + {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL}, + {"errors", (getter)textiowrapper_errors_get, NULL, NULL}, + {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get, + (setter)textiowrapper_chunk_size_set, NULL}, + {NULL} +}; + +PyTypeObject PyTextIOWrapper_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io.TextIOWrapper", /*tp_name*/ + sizeof(textio), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)textiowrapper_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tps_etattr*/ + 0, /*tp_getattr*/ + 0, /*tps_etattr*/ 0, /*tp_as_async*/ - (reprfunc)textiowrapper_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*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + (reprfunc)textiowrapper_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*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_TextIOWrapper___init____doc__, /* tp_doc */ - (traverseproc)textiowrapper_traverse, /* tp_traverse */ - (inquiry)textiowrapper_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(textio, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)textiowrapper_iternext, /* tp_iternext */ - textiowrapper_methods, /* tp_methods */ - textiowrapper_members, /* tp_members */ - textiowrapper_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(textio, dict), /*tp_dictoffset*/ - _io_TextIOWrapper___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; + _io_TextIOWrapper___init____doc__, /* tp_doc */ + (traverseproc)textiowrapper_traverse, /* tp_traverse */ + (inquiry)textiowrapper_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(textio, weakreflist), /*tp_weaklistoffset*/ + 0, /* tp_iter */ + (iternextfunc)textiowrapper_iternext, /* tp_iternext */ + textiowrapper_methods, /* tp_methods */ + textiowrapper_members, /* tp_members */ + textiowrapper_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(textio, dict), /*tp_dictoffset*/ + _io_TextIOWrapper___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; diff --git a/contrib/tools/python3/src/Modules/_io/winconsoleio.c b/contrib/tools/python3/src/Modules/_io/winconsoleio.c index a83ef37a1fc..0e223cd8724 100644 --- a/contrib/tools/python3/src/Modules/_io/winconsoleio.c +++ b/contrib/tools/python3/src/Modules/_io/winconsoleio.c @@ -1,1169 +1,1169 @@ -/* - An implementation of Windows console I/O - - Classes defined here: _WindowsConsoleIO - - Written by Steve Dower -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" +/* + An implementation of Windows console I/O + + Classes defined here: _WindowsConsoleIO + + Written by Steve Dower +*/ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include "pycore_object.h" - -#ifdef MS_WINDOWS - + +#ifdef MS_WINDOWS + #include "structmember.h" // PyMemberDef -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#include /* For offsetof */ - -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include "_iomodule.h" - -/* BUFSIZ determines how many characters can be typed at the console - before it starts blocking. */ -#if BUFSIZ < (16*1024) -#define SMALLCHUNK (2*1024) -#elif (BUFSIZ >= (2 << 25)) -#error "unreasonable BUFSIZ > 64 MiB defined" -#else -#define SMALLCHUNK BUFSIZ -#endif - -/* BUFMAX determines how many bytes can be read in one go. */ -#define BUFMAX (32*1024*1024) - -/* SMALLBUF determines how many utf-8 characters will be - buffered within the stream, in order to support reads - of less than one character */ -#define SMALLBUF 4 - -char _get_console_type(HANDLE handle) { - DWORD mode, peek_count; - - if (handle == INVALID_HANDLE_VALUE) - return '\0'; - - if (!GetConsoleMode(handle, &mode)) - return '\0'; - - /* Peek at the handle to see whether it is an input or output handle */ - if (GetNumberOfConsoleInputEvents(handle, &peek_count)) - return 'r'; - return 'w'; -} - -char _PyIO_get_console_type(PyObject *path_or_fd) { - int fd = PyLong_AsLong(path_or_fd); - PyErr_Clear(); - if (fd >= 0) { - HANDLE handle; - _Py_BEGIN_SUPPRESS_IPH - handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH - if (handle == INVALID_HANDLE_VALUE) - return '\0'; - return _get_console_type(handle); - } - - PyObject *decoded; - wchar_t *decoded_wstr; - - if (!PyUnicode_FSDecoder(path_or_fd, &decoded)) { - PyErr_Clear(); - return '\0'; - } - decoded_wstr = PyUnicode_AsWideCharString(decoded, NULL); - Py_CLEAR(decoded); - if (!decoded_wstr) { - PyErr_Clear(); - return '\0'; - } - - char m = '\0'; - if (!_wcsicmp(decoded_wstr, L"CONIN$")) { - m = 'r'; - } else if (!_wcsicmp(decoded_wstr, L"CONOUT$")) { - m = 'w'; - } else if (!_wcsicmp(decoded_wstr, L"CON")) { - m = 'x'; - } - if (m) { - PyMem_Free(decoded_wstr); - return m; - } - - DWORD length; - wchar_t name_buf[MAX_PATH], *pname_buf = name_buf; - - length = GetFullPathNameW(decoded_wstr, MAX_PATH, pname_buf, NULL); - if (length > MAX_PATH) { - pname_buf = PyMem_New(wchar_t, length); - if (pname_buf) - length = GetFullPathNameW(decoded_wstr, length, pname_buf, NULL); - else - length = 0; - } - PyMem_Free(decoded_wstr); - - if (length) { - wchar_t *name = pname_buf; - if (length >= 4 && name[3] == L'\\' && - (name[2] == L'.' || name[2] == L'?') && - name[1] == L'\\' && name[0] == L'\\') { - name += 4; - } - if (!_wcsicmp(name, L"CONIN$")) { - m = 'r'; - } else if (!_wcsicmp(name, L"CONOUT$")) { - m = 'w'; - } else if (!_wcsicmp(name, L"CON")) { - m = 'x'; - } - } - - if (pname_buf != name_buf) - PyMem_Free(pname_buf); - return m; -} - - -/*[clinic input] -module _io -class _io._WindowsConsoleIO "winconsoleio *" "&PyWindowsConsoleIO_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e897fdc1fba4e131]*/ - -typedef struct { - PyObject_HEAD - HANDLE handle; - int fd; - unsigned int created : 1; - unsigned int readable : 1; - unsigned int writable : 1; - unsigned int closehandle : 1; - char finalizing; - unsigned int blksize; - PyObject *weakreflist; - PyObject *dict; - char buf[SMALLBUF]; - wchar_t wbuf; -} winconsoleio; - -PyTypeObject PyWindowsConsoleIO_Type; - -_Py_IDENTIFIER(name); - -int -_PyWindowsConsoleIO_closed(PyObject *self) -{ - return ((winconsoleio *)self)->handle == INVALID_HANDLE_VALUE; -} - - -/* Returns 0 on success, -1 with exception set on failure. */ -static int -internal_close(winconsoleio *self) -{ - if (self->handle != INVALID_HANDLE_VALUE) { - if (self->closehandle) { - if (self->fd >= 0) { - _Py_BEGIN_SUPPRESS_IPH - close(self->fd); - _Py_END_SUPPRESS_IPH - } - CloseHandle(self->handle); - } - self->handle = INVALID_HANDLE_VALUE; - self->fd = -1; - } - return 0; -} - -/*[clinic input] -_io._WindowsConsoleIO.close - -Close the handle. - -A closed handle cannot be used for further I/O operations. close() may be -called more than once without error. -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_close_impl(winconsoleio *self) -/*[clinic end generated code: output=27ef95b66c29057b input=185617e349ae4c7b]*/ -{ - PyObject *res; - PyObject *exc, *val, *tb; - int rc; - _Py_IDENTIFIER(close); +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#include /* For offsetof */ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "_iomodule.h" + +/* BUFSIZ determines how many characters can be typed at the console + before it starts blocking. */ +#if BUFSIZ < (16*1024) +#define SMALLCHUNK (2*1024) +#elif (BUFSIZ >= (2 << 25)) +#error "unreasonable BUFSIZ > 64 MiB defined" +#else +#define SMALLCHUNK BUFSIZ +#endif + +/* BUFMAX determines how many bytes can be read in one go. */ +#define BUFMAX (32*1024*1024) + +/* SMALLBUF determines how many utf-8 characters will be + buffered within the stream, in order to support reads + of less than one character */ +#define SMALLBUF 4 + +char _get_console_type(HANDLE handle) { + DWORD mode, peek_count; + + if (handle == INVALID_HANDLE_VALUE) + return '\0'; + + if (!GetConsoleMode(handle, &mode)) + return '\0'; + + /* Peek at the handle to see whether it is an input or output handle */ + if (GetNumberOfConsoleInputEvents(handle, &peek_count)) + return 'r'; + return 'w'; +} + +char _PyIO_get_console_type(PyObject *path_or_fd) { + int fd = PyLong_AsLong(path_or_fd); + PyErr_Clear(); + if (fd >= 0) { + HANDLE handle; + _Py_BEGIN_SUPPRESS_IPH + handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + if (handle == INVALID_HANDLE_VALUE) + return '\0'; + return _get_console_type(handle); + } + + PyObject *decoded; + wchar_t *decoded_wstr; + + if (!PyUnicode_FSDecoder(path_or_fd, &decoded)) { + PyErr_Clear(); + return '\0'; + } + decoded_wstr = PyUnicode_AsWideCharString(decoded, NULL); + Py_CLEAR(decoded); + if (!decoded_wstr) { + PyErr_Clear(); + return '\0'; + } + + char m = '\0'; + if (!_wcsicmp(decoded_wstr, L"CONIN$")) { + m = 'r'; + } else if (!_wcsicmp(decoded_wstr, L"CONOUT$")) { + m = 'w'; + } else if (!_wcsicmp(decoded_wstr, L"CON")) { + m = 'x'; + } + if (m) { + PyMem_Free(decoded_wstr); + return m; + } + + DWORD length; + wchar_t name_buf[MAX_PATH], *pname_buf = name_buf; + + length = GetFullPathNameW(decoded_wstr, MAX_PATH, pname_buf, NULL); + if (length > MAX_PATH) { + pname_buf = PyMem_New(wchar_t, length); + if (pname_buf) + length = GetFullPathNameW(decoded_wstr, length, pname_buf, NULL); + else + length = 0; + } + PyMem_Free(decoded_wstr); + + if (length) { + wchar_t *name = pname_buf; + if (length >= 4 && name[3] == L'\\' && + (name[2] == L'.' || name[2] == L'?') && + name[1] == L'\\' && name[0] == L'\\') { + name += 4; + } + if (!_wcsicmp(name, L"CONIN$")) { + m = 'r'; + } else if (!_wcsicmp(name, L"CONOUT$")) { + m = 'w'; + } else if (!_wcsicmp(name, L"CON")) { + m = 'x'; + } + } + + if (pname_buf != name_buf) + PyMem_Free(pname_buf); + return m; +} + + +/*[clinic input] +module _io +class _io._WindowsConsoleIO "winconsoleio *" "&PyWindowsConsoleIO_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e897fdc1fba4e131]*/ + +typedef struct { + PyObject_HEAD + HANDLE handle; + int fd; + unsigned int created : 1; + unsigned int readable : 1; + unsigned int writable : 1; + unsigned int closehandle : 1; + char finalizing; + unsigned int blksize; + PyObject *weakreflist; + PyObject *dict; + char buf[SMALLBUF]; + wchar_t wbuf; +} winconsoleio; + +PyTypeObject PyWindowsConsoleIO_Type; + +_Py_IDENTIFIER(name); + +int +_PyWindowsConsoleIO_closed(PyObject *self) +{ + return ((winconsoleio *)self)->handle == INVALID_HANDLE_VALUE; +} + + +/* Returns 0 on success, -1 with exception set on failure. */ +static int +internal_close(winconsoleio *self) +{ + if (self->handle != INVALID_HANDLE_VALUE) { + if (self->closehandle) { + if (self->fd >= 0) { + _Py_BEGIN_SUPPRESS_IPH + close(self->fd); + _Py_END_SUPPRESS_IPH + } + CloseHandle(self->handle); + } + self->handle = INVALID_HANDLE_VALUE; + self->fd = -1; + } + return 0; +} + +/*[clinic input] +_io._WindowsConsoleIO.close + +Close the handle. + +A closed handle cannot be used for further I/O operations. close() may be +called more than once without error. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_close_impl(winconsoleio *self) +/*[clinic end generated code: output=27ef95b66c29057b input=185617e349ae4c7b]*/ +{ + PyObject *res; + PyObject *exc, *val, *tb; + int rc; + _Py_IDENTIFIER(close); res = _PyObject_CallMethodIdOneArg((PyObject*)&PyRawIOBase_Type, &PyId_close, (PyObject*)self); - if (!self->closehandle) { - self->handle = INVALID_HANDLE_VALUE; - return res; - } - if (res == NULL) - PyErr_Fetch(&exc, &val, &tb); - rc = internal_close(self); - if (res == NULL) - _PyErr_ChainExceptions(exc, val, tb); - if (rc < 0) - Py_CLEAR(res); - return res; -} - -static PyObject * -winconsoleio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - winconsoleio *self; - - assert(type != NULL && type->tp_alloc != NULL); - - self = (winconsoleio *) type->tp_alloc(type, 0); - if (self != NULL) { - self->handle = INVALID_HANDLE_VALUE; - self->fd = -1; - self->created = 0; - self->readable = 0; - self->writable = 0; - self->closehandle = 0; - self->blksize = 0; - self->weakreflist = NULL; - } - - return (PyObject *) self; -} - -/*[clinic input] -_io._WindowsConsoleIO.__init__ - file as nameobj: object - mode: str = "r" - closefd: bool(accept={int}) = True - opener: object = None - -Open a console buffer by file descriptor. - -The mode can be 'rb' (default), or 'wb' for reading or writing bytes. All -other mode characters will be ignored. Mode 'b' will be assumed if it is -omitted. The *opener* parameter is always ignored. -[clinic start generated code]*/ - -static int -_io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, - const char *mode, int closefd, - PyObject *opener) -/*[clinic end generated code: output=3fd9cbcdd8d95429 input=06ae4b863c63244b]*/ -{ - const char *s; - wchar_t *name = NULL; - char console_type = '\0'; - int ret = 0; - int rwa = 0; - int fd = -1; - int fd_is_own = 0; - - assert(PyWindowsConsoleIO_Check(self)); - if (self->handle >= 0) { - if (self->closehandle) { - /* Have to close the existing file first. */ - if (internal_close(self) < 0) - return -1; - } - else - self->handle = INVALID_HANDLE_VALUE; - } - - if (PyFloat_Check(nameobj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); - return -1; - } - - fd = _PyLong_AsInt(nameobj); - if (fd < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "negative file descriptor"); - return -1; - } - PyErr_Clear(); - } - self->fd = fd; - - if (fd < 0) { - PyObject *decodedname; - - int d = PyUnicode_FSDecoder(nameobj, (void*)&decodedname); - if (!d) - return -1; - - name = PyUnicode_AsWideCharString(decodedname, NULL); - console_type = _PyIO_get_console_type(decodedname); - Py_CLEAR(decodedname); - if (name == NULL) - return -1; - } - - s = mode; - while (*s) { - switch (*s++) { - case '+': - case 'a': - case 'b': - case 'x': - break; - case 'r': - if (rwa) - goto bad_mode; - rwa = 1; - self->readable = 1; - if (console_type == 'x') - console_type = 'r'; - break; - case 'w': - if (rwa) - goto bad_mode; - rwa = 1; - self->writable = 1; - if (console_type == 'x') - console_type = 'w'; - break; - default: - PyErr_Format(PyExc_ValueError, - "invalid mode: %.200s", mode); - goto error; - } - } - - if (!rwa) - goto bad_mode; - - if (fd >= 0) { - _Py_BEGIN_SUPPRESS_IPH - self->handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH - self->closehandle = 0; - } else { - DWORD access = GENERIC_READ; - - self->closehandle = 1; - if (!closefd) { - PyErr_SetString(PyExc_ValueError, - "Cannot use closefd=False with file name"); - goto error; - } - - if (self->writable) - access = GENERIC_WRITE; - - Py_BEGIN_ALLOW_THREADS - /* Attempt to open for read/write initially, then fall back - on the specific access. This is required for modern names - CONIN$ and CONOUT$, which allow reading/writing state as - well as reading/writing content. */ - self->handle = CreateFileW(name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (self->handle == INVALID_HANDLE_VALUE) - self->handle = CreateFileW(name, access, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - Py_END_ALLOW_THREADS - - if (self->handle == INVALID_HANDLE_VALUE) { - PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, GetLastError(), nameobj); - goto error; - } - } - - if (console_type == '\0') - console_type = _get_console_type(self->handle); - - if (self->writable && console_type != 'w') { - PyErr_SetString(PyExc_ValueError, - "Cannot open console input buffer for writing"); - goto error; - } - if (self->readable && console_type != 'r') { - PyErr_SetString(PyExc_ValueError, - "Cannot open console output buffer for reading"); - goto error; - } - - self->blksize = DEFAULT_BUFFER_SIZE; - memset(self->buf, 0, 4); - - if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0) - goto error; - - goto done; - -bad_mode: - PyErr_SetString(PyExc_ValueError, - "Must have exactly one of read or write mode"); -error: - ret = -1; - internal_close(self); - -done: - if (name) - PyMem_Free(name); - return ret; -} - -static int -winconsoleio_traverse(winconsoleio *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -winconsoleio_clear(winconsoleio *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -static void -winconsoleio_dealloc(winconsoleio *self) -{ - self->finalizing = 1; - if (_PyIOBase_finalize((PyObject *) self) < 0) - return; - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -err_closed(void) -{ - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); - return NULL; -} - -static PyObject * -err_mode(const char *action) -{ - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_Format(state->unsupported_operation, - "Console buffer does not support %s", action); - return NULL; -} - -/*[clinic input] -_io._WindowsConsoleIO.fileno - -Return the underlying file descriptor (an integer). - -fileno is only set when a file descriptor is used to open -one of the standard streams. - -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_fileno_impl(winconsoleio *self) -/*[clinic end generated code: output=006fa74ce3b5cfbf input=079adc330ddaabe6]*/ -{ - if (self->fd < 0 && self->handle != INVALID_HANDLE_VALUE) { - _Py_BEGIN_SUPPRESS_IPH - if (self->writable) - self->fd = _open_osfhandle((intptr_t)self->handle, _O_WRONLY | _O_BINARY); - else - self->fd = _open_osfhandle((intptr_t)self->handle, _O_RDONLY | _O_BINARY); - _Py_END_SUPPRESS_IPH - } - if (self->fd < 0) - return err_mode("fileno"); - return PyLong_FromLong(self->fd); -} - -/*[clinic input] -_io._WindowsConsoleIO.readable - -True if console is an input buffer. -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_readable_impl(winconsoleio *self) -/*[clinic end generated code: output=daf9cef2743becf0 input=6be9defb5302daae]*/ -{ - if (self->handle == INVALID_HANDLE_VALUE) - return err_closed(); - return PyBool_FromLong((long) self->readable); -} - -/*[clinic input] -_io._WindowsConsoleIO.writable - -True if console is an output buffer. -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_writable_impl(winconsoleio *self) -/*[clinic end generated code: output=e0a2ad7eae5abf67 input=cefbd8abc24df6a0]*/ -{ - if (self->handle == INVALID_HANDLE_VALUE) - return err_closed(); - return PyBool_FromLong((long) self->writable); -} - -static DWORD -_buflen(winconsoleio *self) -{ - for (DWORD i = 0; i < SMALLBUF; ++i) { - if (!self->buf[i]) - return i; - } - return SMALLBUF; -} - -static DWORD -_copyfrombuf(winconsoleio *self, char *buf, DWORD len) -{ - DWORD n = 0; - - while (self->buf[0] && len--) { - buf[n++] = self->buf[0]; - for (int i = 1; i < SMALLBUF; ++i) - self->buf[i - 1] = self->buf[i]; - self->buf[SMALLBUF - 1] = 0; - } - - return n; -} - -static wchar_t * -read_console_w(HANDLE handle, DWORD maxlen, DWORD *readlen) { - int err = 0, sig = 0; - - wchar_t *buf = (wchar_t*)PyMem_Malloc(maxlen * sizeof(wchar_t)); - if (!buf) - goto error; - - *readlen = 0; - - //DebugBreak(); - Py_BEGIN_ALLOW_THREADS - DWORD off = 0; - while (off < maxlen) { + if (!self->closehandle) { + self->handle = INVALID_HANDLE_VALUE; + return res; + } + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); + rc = internal_close(self); + if (res == NULL) + _PyErr_ChainExceptions(exc, val, tb); + if (rc < 0) + Py_CLEAR(res); + return res; +} + +static PyObject * +winconsoleio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + winconsoleio *self; + + assert(type != NULL && type->tp_alloc != NULL); + + self = (winconsoleio *) type->tp_alloc(type, 0); + if (self != NULL) { + self->handle = INVALID_HANDLE_VALUE; + self->fd = -1; + self->created = 0; + self->readable = 0; + self->writable = 0; + self->closehandle = 0; + self->blksize = 0; + self->weakreflist = NULL; + } + + return (PyObject *) self; +} + +/*[clinic input] +_io._WindowsConsoleIO.__init__ + file as nameobj: object + mode: str = "r" + closefd: bool(accept={int}) = True + opener: object = None + +Open a console buffer by file descriptor. + +The mode can be 'rb' (default), or 'wb' for reading or writing bytes. All +other mode characters will be ignored. Mode 'b' will be assumed if it is +omitted. The *opener* parameter is always ignored. +[clinic start generated code]*/ + +static int +_io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, + const char *mode, int closefd, + PyObject *opener) +/*[clinic end generated code: output=3fd9cbcdd8d95429 input=06ae4b863c63244b]*/ +{ + const char *s; + wchar_t *name = NULL; + char console_type = '\0'; + int ret = 0; + int rwa = 0; + int fd = -1; + int fd_is_own = 0; + + assert(PyWindowsConsoleIO_Check(self)); + if (self->handle >= 0) { + if (self->closehandle) { + /* Have to close the existing file first. */ + if (internal_close(self) < 0) + return -1; + } + else + self->handle = INVALID_HANDLE_VALUE; + } + + if (PyFloat_Check(nameobj)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float"); + return -1; + } + + fd = _PyLong_AsInt(nameobj); + if (fd < 0) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "negative file descriptor"); + return -1; + } + PyErr_Clear(); + } + self->fd = fd; + + if (fd < 0) { + PyObject *decodedname; + + int d = PyUnicode_FSDecoder(nameobj, (void*)&decodedname); + if (!d) + return -1; + + name = PyUnicode_AsWideCharString(decodedname, NULL); + console_type = _PyIO_get_console_type(decodedname); + Py_CLEAR(decodedname); + if (name == NULL) + return -1; + } + + s = mode; + while (*s) { + switch (*s++) { + case '+': + case 'a': + case 'b': + case 'x': + break; + case 'r': + if (rwa) + goto bad_mode; + rwa = 1; + self->readable = 1; + if (console_type == 'x') + console_type = 'r'; + break; + case 'w': + if (rwa) + goto bad_mode; + rwa = 1; + self->writable = 1; + if (console_type == 'x') + console_type = 'w'; + break; + default: + PyErr_Format(PyExc_ValueError, + "invalid mode: %.200s", mode); + goto error; + } + } + + if (!rwa) + goto bad_mode; + + if (fd >= 0) { + _Py_BEGIN_SUPPRESS_IPH + self->handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + self->closehandle = 0; + } else { + DWORD access = GENERIC_READ; + + self->closehandle = 1; + if (!closefd) { + PyErr_SetString(PyExc_ValueError, + "Cannot use closefd=False with file name"); + goto error; + } + + if (self->writable) + access = GENERIC_WRITE; + + Py_BEGIN_ALLOW_THREADS + /* Attempt to open for read/write initially, then fall back + on the specific access. This is required for modern names + CONIN$ and CONOUT$, which allow reading/writing state as + well as reading/writing content. */ + self->handle = CreateFileW(name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (self->handle == INVALID_HANDLE_VALUE) + self->handle = CreateFileW(name, access, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + Py_END_ALLOW_THREADS + + if (self->handle == INVALID_HANDLE_VALUE) { + PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, GetLastError(), nameobj); + goto error; + } + } + + if (console_type == '\0') + console_type = _get_console_type(self->handle); + + if (self->writable && console_type != 'w') { + PyErr_SetString(PyExc_ValueError, + "Cannot open console input buffer for writing"); + goto error; + } + if (self->readable && console_type != 'r') { + PyErr_SetString(PyExc_ValueError, + "Cannot open console output buffer for reading"); + goto error; + } + + self->blksize = DEFAULT_BUFFER_SIZE; + memset(self->buf, 0, 4); + + if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0) + goto error; + + goto done; + +bad_mode: + PyErr_SetString(PyExc_ValueError, + "Must have exactly one of read or write mode"); +error: + ret = -1; + internal_close(self); + +done: + if (name) + PyMem_Free(name); + return ret; +} + +static int +winconsoleio_traverse(winconsoleio *self, visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + return 0; +} + +static int +winconsoleio_clear(winconsoleio *self) +{ + Py_CLEAR(self->dict); + return 0; +} + +static void +winconsoleio_dealloc(winconsoleio *self) +{ + self->finalizing = 1; + if (_PyIOBase_finalize((PyObject *) self) < 0) + return; + _PyObject_GC_UNTRACK(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_CLEAR(self->dict); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject * +err_closed(void) +{ + PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); + return NULL; +} + +static PyObject * +err_mode(const char *action) +{ + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_Format(state->unsupported_operation, + "Console buffer does not support %s", action); + return NULL; +} + +/*[clinic input] +_io._WindowsConsoleIO.fileno + +Return the underlying file descriptor (an integer). + +fileno is only set when a file descriptor is used to open +one of the standard streams. + +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_fileno_impl(winconsoleio *self) +/*[clinic end generated code: output=006fa74ce3b5cfbf input=079adc330ddaabe6]*/ +{ + if (self->fd < 0 && self->handle != INVALID_HANDLE_VALUE) { + _Py_BEGIN_SUPPRESS_IPH + if (self->writable) + self->fd = _open_osfhandle((intptr_t)self->handle, _O_WRONLY | _O_BINARY); + else + self->fd = _open_osfhandle((intptr_t)self->handle, _O_RDONLY | _O_BINARY); + _Py_END_SUPPRESS_IPH + } + if (self->fd < 0) + return err_mode("fileno"); + return PyLong_FromLong(self->fd); +} + +/*[clinic input] +_io._WindowsConsoleIO.readable + +True if console is an input buffer. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_readable_impl(winconsoleio *self) +/*[clinic end generated code: output=daf9cef2743becf0 input=6be9defb5302daae]*/ +{ + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + return PyBool_FromLong((long) self->readable); +} + +/*[clinic input] +_io._WindowsConsoleIO.writable + +True if console is an output buffer. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_writable_impl(winconsoleio *self) +/*[clinic end generated code: output=e0a2ad7eae5abf67 input=cefbd8abc24df6a0]*/ +{ + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + return PyBool_FromLong((long) self->writable); +} + +static DWORD +_buflen(winconsoleio *self) +{ + for (DWORD i = 0; i < SMALLBUF; ++i) { + if (!self->buf[i]) + return i; + } + return SMALLBUF; +} + +static DWORD +_copyfrombuf(winconsoleio *self, char *buf, DWORD len) +{ + DWORD n = 0; + + while (self->buf[0] && len--) { + buf[n++] = self->buf[0]; + for (int i = 1; i < SMALLBUF; ++i) + self->buf[i - 1] = self->buf[i]; + self->buf[SMALLBUF - 1] = 0; + } + + return n; +} + +static wchar_t * +read_console_w(HANDLE handle, DWORD maxlen, DWORD *readlen) { + int err = 0, sig = 0; + + wchar_t *buf = (wchar_t*)PyMem_Malloc(maxlen * sizeof(wchar_t)); + if (!buf) + goto error; + + *readlen = 0; + + //DebugBreak(); + Py_BEGIN_ALLOW_THREADS + DWORD off = 0; + while (off < maxlen) { DWORD n = (DWORD)-1; - DWORD len = min(maxlen - off, BUFSIZ); - SetLastError(0); - BOOL res = ReadConsoleW(handle, &buf[off], len, &n, NULL); - - if (!res) { - err = GetLastError(); - break; - } - if (n == (DWORD)-1 && (err = GetLastError()) == ERROR_OPERATION_ABORTED) { - break; - } - if (n == 0) { - err = GetLastError(); - if (err != ERROR_OPERATION_ABORTED) - break; - err = 0; - HANDLE hInterruptEvent = _PyOS_SigintEvent(); - if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE) - == WAIT_OBJECT_0) { - ResetEvent(hInterruptEvent); - Py_BLOCK_THREADS - sig = PyErr_CheckSignals(); - Py_UNBLOCK_THREADS - if (sig < 0) - break; - } - } - *readlen += n; - - /* If we didn't read a full buffer that time, don't try - again or we will block a second time. */ - if (n < len) - break; - /* If the buffer ended with a newline, break out */ - if (buf[*readlen - 1] == '\n') - break; - /* If the buffer ends with a high surrogate, expand the - buffer and read an extra character. */ - WORD char_type; - if (off + BUFSIZ >= maxlen && - GetStringTypeW(CT_CTYPE3, &buf[*readlen - 1], 1, &char_type) && - char_type == C3_HIGHSURROGATE) { - wchar_t *newbuf; - maxlen += 1; - Py_BLOCK_THREADS - newbuf = (wchar_t*)PyMem_Realloc(buf, maxlen * sizeof(wchar_t)); - Py_UNBLOCK_THREADS - if (!newbuf) { - sig = -1; - break; - } - buf = newbuf; - /* Only advance by n and not BUFSIZ in this case */ - off += n; - continue; - } - - off += BUFSIZ; - } - - Py_END_ALLOW_THREADS - - if (sig) - goto error; - if (err) { - PyErr_SetFromWindowsErr(err); - goto error; - } - - if (*readlen > 0 && buf[0] == L'\x1a') { - PyMem_Free(buf); - buf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t)); - if (!buf) - goto error; - buf[0] = L'\0'; - *readlen = 0; - } - - return buf; - -error: - if (buf) - PyMem_Free(buf); - return NULL; -} - - -static Py_ssize_t -readinto(winconsoleio *self, char *buf, Py_ssize_t len) -{ - if (self->handle == INVALID_HANDLE_VALUE) { - err_closed(); - return -1; - } - if (!self->readable) { - err_mode("reading"); - return -1; - } - if (len == 0) - return 0; - if (len > BUFMAX) { - PyErr_Format(PyExc_ValueError, "cannot read more than %d bytes", BUFMAX); - return -1; - } - - /* Each character may take up to 4 bytes in the final buffer. - This is highly conservative, but necessary to avoid - failure for any given Unicode input (e.g. \U0010ffff). - If the caller requests fewer than 4 bytes, we buffer one - character. - */ - DWORD wlen = (DWORD)(len / 4); - if (wlen == 0) { - wlen = 1; - } - - DWORD read_len = _copyfrombuf(self, buf, (DWORD)len); - if (read_len) { - buf = &buf[read_len]; - len -= read_len; - wlen -= 1; - } - if (len == read_len || wlen == 0) - return read_len; - - DWORD n; - wchar_t *wbuf = read_console_w(self->handle, wlen, &n); - if (wbuf == NULL) - return -1; - if (n == 0) { - PyMem_Free(wbuf); - return read_len; - } - - int err = 0; - DWORD u8n = 0; - - Py_BEGIN_ALLOW_THREADS - if (len < 4) { - if (WideCharToMultiByte(CP_UTF8, 0, wbuf, n, - self->buf, sizeof(self->buf) / sizeof(self->buf[0]), - NULL, NULL)) - u8n = _copyfrombuf(self, buf, (DWORD)len); - } else { - u8n = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, - buf, (DWORD)len, NULL, NULL); - } - - if (u8n) { - read_len += u8n; - u8n = 0; - } else { - err = GetLastError(); - if (err == ERROR_INSUFFICIENT_BUFFER) { - /* Calculate the needed buffer for a more useful error, as this - means our "/ 4" logic above is insufficient for some input. - */ - u8n = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, - NULL, 0, NULL, NULL); - } - } - Py_END_ALLOW_THREADS - - PyMem_Free(wbuf); - - if (u8n) { - PyErr_Format(PyExc_SystemError, + DWORD len = min(maxlen - off, BUFSIZ); + SetLastError(0); + BOOL res = ReadConsoleW(handle, &buf[off], len, &n, NULL); + + if (!res) { + err = GetLastError(); + break; + } + if (n == (DWORD)-1 && (err = GetLastError()) == ERROR_OPERATION_ABORTED) { + break; + } + if (n == 0) { + err = GetLastError(); + if (err != ERROR_OPERATION_ABORTED) + break; + err = 0; + HANDLE hInterruptEvent = _PyOS_SigintEvent(); + if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE) + == WAIT_OBJECT_0) { + ResetEvent(hInterruptEvent); + Py_BLOCK_THREADS + sig = PyErr_CheckSignals(); + Py_UNBLOCK_THREADS + if (sig < 0) + break; + } + } + *readlen += n; + + /* If we didn't read a full buffer that time, don't try + again or we will block a second time. */ + if (n < len) + break; + /* If the buffer ended with a newline, break out */ + if (buf[*readlen - 1] == '\n') + break; + /* If the buffer ends with a high surrogate, expand the + buffer and read an extra character. */ + WORD char_type; + if (off + BUFSIZ >= maxlen && + GetStringTypeW(CT_CTYPE3, &buf[*readlen - 1], 1, &char_type) && + char_type == C3_HIGHSURROGATE) { + wchar_t *newbuf; + maxlen += 1; + Py_BLOCK_THREADS + newbuf = (wchar_t*)PyMem_Realloc(buf, maxlen * sizeof(wchar_t)); + Py_UNBLOCK_THREADS + if (!newbuf) { + sig = -1; + break; + } + buf = newbuf; + /* Only advance by n and not BUFSIZ in this case */ + off += n; + continue; + } + + off += BUFSIZ; + } + + Py_END_ALLOW_THREADS + + if (sig) + goto error; + if (err) { + PyErr_SetFromWindowsErr(err); + goto error; + } + + if (*readlen > 0 && buf[0] == L'\x1a') { + PyMem_Free(buf); + buf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t)); + if (!buf) + goto error; + buf[0] = L'\0'; + *readlen = 0; + } + + return buf; + +error: + if (buf) + PyMem_Free(buf); + return NULL; +} + + +static Py_ssize_t +readinto(winconsoleio *self, char *buf, Py_ssize_t len) +{ + if (self->handle == INVALID_HANDLE_VALUE) { + err_closed(); + return -1; + } + if (!self->readable) { + err_mode("reading"); + return -1; + } + if (len == 0) + return 0; + if (len > BUFMAX) { + PyErr_Format(PyExc_ValueError, "cannot read more than %d bytes", BUFMAX); + return -1; + } + + /* Each character may take up to 4 bytes in the final buffer. + This is highly conservative, but necessary to avoid + failure for any given Unicode input (e.g. \U0010ffff). + If the caller requests fewer than 4 bytes, we buffer one + character. + */ + DWORD wlen = (DWORD)(len / 4); + if (wlen == 0) { + wlen = 1; + } + + DWORD read_len = _copyfrombuf(self, buf, (DWORD)len); + if (read_len) { + buf = &buf[read_len]; + len -= read_len; + wlen -= 1; + } + if (len == read_len || wlen == 0) + return read_len; + + DWORD n; + wchar_t *wbuf = read_console_w(self->handle, wlen, &n); + if (wbuf == NULL) + return -1; + if (n == 0) { + PyMem_Free(wbuf); + return read_len; + } + + int err = 0; + DWORD u8n = 0; + + Py_BEGIN_ALLOW_THREADS + if (len < 4) { + if (WideCharToMultiByte(CP_UTF8, 0, wbuf, n, + self->buf, sizeof(self->buf) / sizeof(self->buf[0]), + NULL, NULL)) + u8n = _copyfrombuf(self, buf, (DWORD)len); + } else { + u8n = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, + buf, (DWORD)len, NULL, NULL); + } + + if (u8n) { + read_len += u8n; + u8n = 0; + } else { + err = GetLastError(); + if (err == ERROR_INSUFFICIENT_BUFFER) { + /* Calculate the needed buffer for a more useful error, as this + means our "/ 4" logic above is insufficient for some input. + */ + u8n = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, + NULL, 0, NULL, NULL); + } + } + Py_END_ALLOW_THREADS + + PyMem_Free(wbuf); + + if (u8n) { + PyErr_Format(PyExc_SystemError, "Buffer had room for %zd bytes but %u bytes required", - len, u8n); - return -1; - } - if (err) { - PyErr_SetFromWindowsErr(err); - return -1; - } - - return read_len; -} - -/*[clinic input] -_io._WindowsConsoleIO.readinto - buffer: Py_buffer(accept={rwbuffer}) - / - -Same as RawIOBase.readinto(). -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, Py_buffer *buffer) -/*[clinic end generated code: output=66d1bdfa3f20af39 input=4ed68da48a6baffe]*/ -{ - Py_ssize_t len = readinto(self, buffer->buf, buffer->len); - if (len < 0) - return NULL; - - return PyLong_FromSsize_t(len); -} - -static DWORD -new_buffersize(winconsoleio *self, DWORD currentsize) -{ - DWORD addend; - - /* Expand the buffer by an amount proportional to the current size, - giving us amortized linear-time behavior. For bigger sizes, use a - less-than-double growth factor to avoid excessive allocation. */ - if (currentsize > 65536) - addend = currentsize >> 3; - else - addend = 256 + currentsize; - if (addend < SMALLCHUNK) - /* Avoid tiny read() calls. */ - addend = SMALLCHUNK; - return addend + currentsize; -} - -/*[clinic input] -_io._WindowsConsoleIO.readall - -Read all data from the console, returned as bytes. - -Return an empty bytes object at EOF. -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_readall_impl(winconsoleio *self) -/*[clinic end generated code: output=e6d312c684f6e23b input=4024d649a1006e69]*/ -{ - wchar_t *buf; - DWORD bufsize, n, len = 0; - PyObject *bytes; - DWORD bytes_size, rn; - - if (self->handle == INVALID_HANDLE_VALUE) - return err_closed(); - - bufsize = BUFSIZ; - - buf = (wchar_t*)PyMem_Malloc((bufsize + 1) * sizeof(wchar_t)); - if (buf == NULL) - return NULL; - - while (1) { - wchar_t *subbuf; - - if (len >= (Py_ssize_t)bufsize) { - DWORD newsize = new_buffersize(self, len); - if (newsize > BUFMAX) - break; - if (newsize < bufsize) { - PyErr_SetString(PyExc_OverflowError, - "unbounded read returned more bytes " - "than a Python bytes object can hold"); - PyMem_Free(buf); - return NULL; - } - bufsize = newsize; - - wchar_t *tmp = PyMem_Realloc(buf, - (bufsize + 1) * sizeof(wchar_t)); - if (tmp == NULL) { - PyMem_Free(buf); - return NULL; - } - buf = tmp; - } - - subbuf = read_console_w(self->handle, bufsize - len, &n); - - if (subbuf == NULL) { - PyMem_Free(buf); - return NULL; - } - - if (n > 0) - wcsncpy_s(&buf[len], bufsize - len + 1, subbuf, n); - - PyMem_Free(subbuf); - - /* when the read is empty we break */ - if (n == 0) - break; - - len += n; - } - - if (len == 0 && _buflen(self) == 0) { - /* when the result starts with ^Z we return an empty buffer */ - PyMem_Free(buf); - return PyBytes_FromStringAndSize(NULL, 0); - } - - if (len) { - Py_BEGIN_ALLOW_THREADS - bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, - NULL, 0, NULL, NULL); - Py_END_ALLOW_THREADS - - if (!bytes_size) { - DWORD err = GetLastError(); - PyMem_Free(buf); - return PyErr_SetFromWindowsErr(err); - } - } else { - bytes_size = 0; - } - - bytes_size += _buflen(self); - bytes = PyBytes_FromStringAndSize(NULL, bytes_size); - rn = _copyfrombuf(self, PyBytes_AS_STRING(bytes), bytes_size); - - if (len) { - Py_BEGIN_ALLOW_THREADS - bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, - &PyBytes_AS_STRING(bytes)[rn], bytes_size - rn, NULL, NULL); - Py_END_ALLOW_THREADS - - if (!bytes_size) { - DWORD err = GetLastError(); - PyMem_Free(buf); - Py_CLEAR(bytes); - return PyErr_SetFromWindowsErr(err); - } - - /* add back the number of preserved bytes */ - bytes_size += rn; - } - - PyMem_Free(buf); - if (bytes_size < (size_t)PyBytes_GET_SIZE(bytes)) { - if (_PyBytes_Resize(&bytes, n * sizeof(wchar_t)) < 0) { - Py_CLEAR(bytes); - return NULL; - } - } - return bytes; -} - -/*[clinic input] -_io._WindowsConsoleIO.read - size: Py_ssize_t(accept={int, NoneType}) = -1 - / - -Read at most size bytes, returned as bytes. - -Only makes one system call when size is a positive integer, -so less data may be returned than requested. -Return an empty bytes object at EOF. -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size) -/*[clinic end generated code: output=57df68af9f4b22d0 input=8bc73bc15d0fa072]*/ -{ - PyObject *bytes; - Py_ssize_t bytes_size; - - if (self->handle == INVALID_HANDLE_VALUE) - return err_closed(); - if (!self->readable) - return err_mode("reading"); - - if (size < 0) - return _io__WindowsConsoleIO_readall_impl(self); - if (size > BUFMAX) { - PyErr_Format(PyExc_ValueError, "cannot read more than %d bytes", BUFMAX); - return NULL; - } - - bytes = PyBytes_FromStringAndSize(NULL, size); - if (bytes == NULL) - return NULL; - - bytes_size = readinto(self, PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); - if (bytes_size < 0) { - Py_CLEAR(bytes); - return NULL; - } - - if (bytes_size < PyBytes_GET_SIZE(bytes)) { - if (_PyBytes_Resize(&bytes, bytes_size) < 0) { - Py_CLEAR(bytes); - return NULL; - } - } - - return bytes; -} - -/*[clinic input] -_io._WindowsConsoleIO.write - b: Py_buffer - / - -Write buffer b to file, return number of bytes written. - -Only makes one system call, so not all of the data may be written. -The number of bytes actually written is returned. -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) -/*[clinic end generated code: output=775bdb16fbf9137b input=be35fb624f97c941]*/ -{ - BOOL res = TRUE; - wchar_t *wbuf; - DWORD len, wlen, n = 0; - - if (self->handle == INVALID_HANDLE_VALUE) - return err_closed(); - if (!self->writable) - return err_mode("writing"); - - if (!b->len) { - return PyLong_FromLong(0); - } - if (b->len > BUFMAX) - len = BUFMAX; - else - len = (DWORD)b->len; - - Py_BEGIN_ALLOW_THREADS - wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0); - - /* issue11395 there is an unspecified upper bound on how many bytes - can be written at once. We cap at 32k - the caller will have to - handle partial writes. - Since we don't know how many input bytes are being ignored, we - have to reduce and recalculate. */ - while (wlen > 32766 / sizeof(wchar_t)) { - len /= 2; - wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0); - } - Py_END_ALLOW_THREADS - - if (!wlen) - return PyErr_SetFromWindowsErr(0); - - wbuf = (wchar_t*)PyMem_Malloc(wlen * sizeof(wchar_t)); - - Py_BEGIN_ALLOW_THREADS - wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, wbuf, wlen); - if (wlen) { - res = WriteConsoleW(self->handle, wbuf, wlen, &n, NULL); - if (res && n < wlen) { - /* Wrote fewer characters than expected, which means our - * len value may be wrong. So recalculate it from the - * characters that were written. As this could potentially - * result in a different value, we also validate that value. - */ - len = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, - NULL, 0, NULL, NULL); - if (len) { - wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, - NULL, 0); - assert(wlen == len); - } - } - } else - res = 0; - Py_END_ALLOW_THREADS - - if (!res) { - DWORD err = GetLastError(); - PyMem_Free(wbuf); - return PyErr_SetFromWindowsErr(err); - } - - PyMem_Free(wbuf); - return PyLong_FromSsize_t(len); -} - -static PyObject * -winconsoleio_repr(winconsoleio *self) -{ - if (self->handle == INVALID_HANDLE_VALUE) - return PyUnicode_FromFormat("<_io._WindowsConsoleIO [closed]>"); - - if (self->readable) - return PyUnicode_FromFormat("<_io._WindowsConsoleIO mode='rb' closefd=%s>", - self->closehandle ? "True" : "False"); - if (self->writable) - return PyUnicode_FromFormat("<_io._WindowsConsoleIO mode='wb' closefd=%s>", - self->closehandle ? "True" : "False"); - - PyErr_SetString(PyExc_SystemError, "_WindowsConsoleIO has invalid mode"); - return NULL; -} - -/*[clinic input] -_io._WindowsConsoleIO.isatty - -Always True. -[clinic start generated code]*/ - -static PyObject * -_io__WindowsConsoleIO_isatty_impl(winconsoleio *self) -/*[clinic end generated code: output=9eac09d287c11bd7 input=9b91591dbe356f86]*/ -{ - if (self->handle == INVALID_HANDLE_VALUE) - return err_closed(); - - Py_RETURN_TRUE; -} - -#include "clinic/winconsoleio.c.h" - -static PyMethodDef winconsoleio_methods[] = { - _IO__WINDOWSCONSOLEIO_READ_METHODDEF - _IO__WINDOWSCONSOLEIO_READALL_METHODDEF - _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF - _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF - _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF - _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF - _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF - _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF - _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -/* 'closed' and 'mode' are attributes for compatibility with FileIO. */ - -static PyObject * -get_closed(winconsoleio *self, void *closure) -{ - return PyBool_FromLong((long)(self->handle == INVALID_HANDLE_VALUE)); -} - -static PyObject * -get_closefd(winconsoleio *self, void *closure) -{ - return PyBool_FromLong((long)(self->closehandle)); -} - -static PyObject * -get_mode(winconsoleio *self, void *closure) -{ - return PyUnicode_FromString(self->readable ? "rb" : "wb"); -} - -static PyGetSetDef winconsoleio_getsetlist[] = { - {"closed", (getter)get_closed, NULL, "True if the file is closed"}, - {"closefd", (getter)get_closefd, NULL, - "True if the file descriptor will be closed by close()."}, - {"mode", (getter)get_mode, NULL, "String giving the file mode"}, - {NULL}, -}; - -static PyMemberDef winconsoleio_members[] = { - {"_blksize", T_UINT, offsetof(winconsoleio, blksize), 0}, - {"_finalizing", T_BOOL, offsetof(winconsoleio, finalizing), 0}, - {NULL} -}; - -PyTypeObject PyWindowsConsoleIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._WindowsConsoleIO", - sizeof(winconsoleio), - 0, - (destructor)winconsoleio_dealloc, /* tp_dealloc */ + len, u8n); + return -1; + } + if (err) { + PyErr_SetFromWindowsErr(err); + return -1; + } + + return read_len; +} + +/*[clinic input] +_io._WindowsConsoleIO.readinto + buffer: Py_buffer(accept={rwbuffer}) + / + +Same as RawIOBase.readinto(). +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, Py_buffer *buffer) +/*[clinic end generated code: output=66d1bdfa3f20af39 input=4ed68da48a6baffe]*/ +{ + Py_ssize_t len = readinto(self, buffer->buf, buffer->len); + if (len < 0) + return NULL; + + return PyLong_FromSsize_t(len); +} + +static DWORD +new_buffersize(winconsoleio *self, DWORD currentsize) +{ + DWORD addend; + + /* Expand the buffer by an amount proportional to the current size, + giving us amortized linear-time behavior. For bigger sizes, use a + less-than-double growth factor to avoid excessive allocation. */ + if (currentsize > 65536) + addend = currentsize >> 3; + else + addend = 256 + currentsize; + if (addend < SMALLCHUNK) + /* Avoid tiny read() calls. */ + addend = SMALLCHUNK; + return addend + currentsize; +} + +/*[clinic input] +_io._WindowsConsoleIO.readall + +Read all data from the console, returned as bytes. + +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_readall_impl(winconsoleio *self) +/*[clinic end generated code: output=e6d312c684f6e23b input=4024d649a1006e69]*/ +{ + wchar_t *buf; + DWORD bufsize, n, len = 0; + PyObject *bytes; + DWORD bytes_size, rn; + + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + + bufsize = BUFSIZ; + + buf = (wchar_t*)PyMem_Malloc((bufsize + 1) * sizeof(wchar_t)); + if (buf == NULL) + return NULL; + + while (1) { + wchar_t *subbuf; + + if (len >= (Py_ssize_t)bufsize) { + DWORD newsize = new_buffersize(self, len); + if (newsize > BUFMAX) + break; + if (newsize < bufsize) { + PyErr_SetString(PyExc_OverflowError, + "unbounded read returned more bytes " + "than a Python bytes object can hold"); + PyMem_Free(buf); + return NULL; + } + bufsize = newsize; + + wchar_t *tmp = PyMem_Realloc(buf, + (bufsize + 1) * sizeof(wchar_t)); + if (tmp == NULL) { + PyMem_Free(buf); + return NULL; + } + buf = tmp; + } + + subbuf = read_console_w(self->handle, bufsize - len, &n); + + if (subbuf == NULL) { + PyMem_Free(buf); + return NULL; + } + + if (n > 0) + wcsncpy_s(&buf[len], bufsize - len + 1, subbuf, n); + + PyMem_Free(subbuf); + + /* when the read is empty we break */ + if (n == 0) + break; + + len += n; + } + + if (len == 0 && _buflen(self) == 0) { + /* when the result starts with ^Z we return an empty buffer */ + PyMem_Free(buf); + return PyBytes_FromStringAndSize(NULL, 0); + } + + if (len) { + Py_BEGIN_ALLOW_THREADS + bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, + NULL, 0, NULL, NULL); + Py_END_ALLOW_THREADS + + if (!bytes_size) { + DWORD err = GetLastError(); + PyMem_Free(buf); + return PyErr_SetFromWindowsErr(err); + } + } else { + bytes_size = 0; + } + + bytes_size += _buflen(self); + bytes = PyBytes_FromStringAndSize(NULL, bytes_size); + rn = _copyfrombuf(self, PyBytes_AS_STRING(bytes), bytes_size); + + if (len) { + Py_BEGIN_ALLOW_THREADS + bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, + &PyBytes_AS_STRING(bytes)[rn], bytes_size - rn, NULL, NULL); + Py_END_ALLOW_THREADS + + if (!bytes_size) { + DWORD err = GetLastError(); + PyMem_Free(buf); + Py_CLEAR(bytes); + return PyErr_SetFromWindowsErr(err); + } + + /* add back the number of preserved bytes */ + bytes_size += rn; + } + + PyMem_Free(buf); + if (bytes_size < (size_t)PyBytes_GET_SIZE(bytes)) { + if (_PyBytes_Resize(&bytes, n * sizeof(wchar_t)) < 0) { + Py_CLEAR(bytes); + return NULL; + } + } + return bytes; +} + +/*[clinic input] +_io._WindowsConsoleIO.read + size: Py_ssize_t(accept={int, NoneType}) = -1 + / + +Read at most size bytes, returned as bytes. + +Only makes one system call when size is a positive integer, +so less data may be returned than requested. +Return an empty bytes object at EOF. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size) +/*[clinic end generated code: output=57df68af9f4b22d0 input=8bc73bc15d0fa072]*/ +{ + PyObject *bytes; + Py_ssize_t bytes_size; + + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + if (!self->readable) + return err_mode("reading"); + + if (size < 0) + return _io__WindowsConsoleIO_readall_impl(self); + if (size > BUFMAX) { + PyErr_Format(PyExc_ValueError, "cannot read more than %d bytes", BUFMAX); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) + return NULL; + + bytes_size = readinto(self, PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); + if (bytes_size < 0) { + Py_CLEAR(bytes); + return NULL; + } + + if (bytes_size < PyBytes_GET_SIZE(bytes)) { + if (_PyBytes_Resize(&bytes, bytes_size) < 0) { + Py_CLEAR(bytes); + return NULL; + } + } + + return bytes; +} + +/*[clinic input] +_io._WindowsConsoleIO.write + b: Py_buffer + / + +Write buffer b to file, return number of bytes written. + +Only makes one system call, so not all of the data may be written. +The number of bytes actually written is returned. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) +/*[clinic end generated code: output=775bdb16fbf9137b input=be35fb624f97c941]*/ +{ + BOOL res = TRUE; + wchar_t *wbuf; + DWORD len, wlen, n = 0; + + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + if (!self->writable) + return err_mode("writing"); + + if (!b->len) { + return PyLong_FromLong(0); + } + if (b->len > BUFMAX) + len = BUFMAX; + else + len = (DWORD)b->len; + + Py_BEGIN_ALLOW_THREADS + wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0); + + /* issue11395 there is an unspecified upper bound on how many bytes + can be written at once. We cap at 32k - the caller will have to + handle partial writes. + Since we don't know how many input bytes are being ignored, we + have to reduce and recalculate. */ + while (wlen > 32766 / sizeof(wchar_t)) { + len /= 2; + wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0); + } + Py_END_ALLOW_THREADS + + if (!wlen) + return PyErr_SetFromWindowsErr(0); + + wbuf = (wchar_t*)PyMem_Malloc(wlen * sizeof(wchar_t)); + + Py_BEGIN_ALLOW_THREADS + wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, wbuf, wlen); + if (wlen) { + res = WriteConsoleW(self->handle, wbuf, wlen, &n, NULL); + if (res && n < wlen) { + /* Wrote fewer characters than expected, which means our + * len value may be wrong. So recalculate it from the + * characters that were written. As this could potentially + * result in a different value, we also validate that value. + */ + len = WideCharToMultiByte(CP_UTF8, 0, wbuf, n, + NULL, 0, NULL, NULL); + if (len) { + wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, + NULL, 0); + assert(wlen == len); + } + } + } else + res = 0; + Py_END_ALLOW_THREADS + + if (!res) { + DWORD err = GetLastError(); + PyMem_Free(wbuf); + return PyErr_SetFromWindowsErr(err); + } + + PyMem_Free(wbuf); + return PyLong_FromSsize_t(len); +} + +static PyObject * +winconsoleio_repr(winconsoleio *self) +{ + if (self->handle == INVALID_HANDLE_VALUE) + return PyUnicode_FromFormat("<_io._WindowsConsoleIO [closed]>"); + + if (self->readable) + return PyUnicode_FromFormat("<_io._WindowsConsoleIO mode='rb' closefd=%s>", + self->closehandle ? "True" : "False"); + if (self->writable) + return PyUnicode_FromFormat("<_io._WindowsConsoleIO mode='wb' closefd=%s>", + self->closehandle ? "True" : "False"); + + PyErr_SetString(PyExc_SystemError, "_WindowsConsoleIO has invalid mode"); + return NULL; +} + +/*[clinic input] +_io._WindowsConsoleIO.isatty + +Always True. +[clinic start generated code]*/ + +static PyObject * +_io__WindowsConsoleIO_isatty_impl(winconsoleio *self) +/*[clinic end generated code: output=9eac09d287c11bd7 input=9b91591dbe356f86]*/ +{ + if (self->handle == INVALID_HANDLE_VALUE) + return err_closed(); + + Py_RETURN_TRUE; +} + +#include "clinic/winconsoleio.c.h" + +static PyMethodDef winconsoleio_methods[] = { + _IO__WINDOWSCONSOLEIO_READ_METHODDEF + _IO__WINDOWSCONSOLEIO_READALL_METHODDEF + _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF + _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF + _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF + _IO__WINDOWSCONSOLEIO_READABLE_METHODDEF + _IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF + _IO__WINDOWSCONSOLEIO_FILENO_METHODDEF + _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +/* 'closed' and 'mode' are attributes for compatibility with FileIO. */ + +static PyObject * +get_closed(winconsoleio *self, void *closure) +{ + return PyBool_FromLong((long)(self->handle == INVALID_HANDLE_VALUE)); +} + +static PyObject * +get_closefd(winconsoleio *self, void *closure) +{ + return PyBool_FromLong((long)(self->closehandle)); +} + +static PyObject * +get_mode(winconsoleio *self, void *closure) +{ + return PyUnicode_FromString(self->readable ? "rb" : "wb"); +} + +static PyGetSetDef winconsoleio_getsetlist[] = { + {"closed", (getter)get_closed, NULL, "True if the file is closed"}, + {"closefd", (getter)get_closefd, NULL, + "True if the file descriptor will be closed by close()."}, + {"mode", (getter)get_mode, NULL, "String giving the file mode"}, + {NULL}, +}; + +static PyMemberDef winconsoleio_members[] = { + {"_blksize", T_UINT, offsetof(winconsoleio, blksize), 0}, + {"_finalizing", T_BOOL, offsetof(winconsoleio, finalizing), 0}, + {NULL} +}; + +PyTypeObject PyWindowsConsoleIO_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_io._WindowsConsoleIO", + sizeof(winconsoleio), + 0, + (destructor)winconsoleio_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)winconsoleio_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + (reprfunc)winconsoleio_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - _io__WindowsConsoleIO___init____doc__, /* tp_doc */ - (traverseproc)winconsoleio_traverse, /* tp_traverse */ - (inquiry)winconsoleio_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(winconsoleio, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - winconsoleio_methods, /* tp_methods */ - winconsoleio_members, /* tp_members */ - winconsoleio_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(winconsoleio, dict), /* tp_dictoffset */ - _io__WindowsConsoleIO___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - winconsoleio_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ -}; - + _io__WindowsConsoleIO___init____doc__, /* tp_doc */ + (traverseproc)winconsoleio_traverse, /* tp_traverse */ + (inquiry)winconsoleio_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(winconsoleio, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + winconsoleio_methods, /* tp_methods */ + winconsoleio_members, /* tp_members */ + winconsoleio_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(winconsoleio, dict), /* tp_dictoffset */ + _io__WindowsConsoleIO___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + winconsoleio_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + 0, /* tp_finalize */ +}; + PyObject * _PyWindowsConsoleIO_Type = (PyObject*)&PyWindowsConsoleIO_Type; - -#endif /* MS_WINDOWS */ + +#endif /* MS_WINDOWS */ diff --git a/contrib/tools/python3/src/Modules/_json.c b/contrib/tools/python3/src/Modules/_json.c index faa3944eedd..51daa71ebcd 100644 --- a/contrib/tools/python3/src/Modules/_json.c +++ b/contrib/tools/python3/src/Modules/_json.c @@ -3,20 +3,20 @@ * It is built as a built-in module (Py_BUILD_CORE_BUILTIN define) on Windows * and as an extension module (Py_BUILD_CORE_MODULE define) on other * platforms. */ - + #if !defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE_MODULE) # error "Py_BUILD_CORE_BUILTIN or Py_BUILD_CORE_MODULE must be defined" -#endif - -#include "Python.h" +#endif + +#include "Python.h" #include "structmember.h" // PyMemberDef #include "pycore_accu.h" - + typedef struct { PyObject *PyScannerType; PyObject *PyEncoderType; } _jsonmodulestate; - + static inline _jsonmodulestate* get_json_state(PyObject *module) { @@ -24,389 +24,389 @@ get_json_state(PyObject *module) assert(state != NULL); return (_jsonmodulestate *)state; } - - -typedef struct _PyScannerObject { - PyObject_HEAD - signed char strict; - PyObject *object_hook; - PyObject *object_pairs_hook; - PyObject *parse_float; - PyObject *parse_int; - PyObject *parse_constant; - PyObject *memo; -} PyScannerObject; - -static PyMemberDef scanner_members[] = { - {"strict", T_BOOL, offsetof(PyScannerObject, strict), READONLY, "strict"}, - {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"}, - {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, object_pairs_hook), READONLY}, - {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"}, - {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"}, - {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"}, - {NULL} -}; - -typedef struct _PyEncoderObject { - PyObject_HEAD - PyObject *markers; - PyObject *defaultfn; - PyObject *encoder; - PyObject *indent; - PyObject *key_separator; - PyObject *item_separator; - char sort_keys; - char skipkeys; - int allow_nan; - PyCFunction fast_encode; -} PyEncoderObject; - -static PyMemberDef encoder_members[] = { - {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"}, - {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"}, - {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"}, - {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"}, - {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"}, - {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"}, - {"sort_keys", T_BOOL, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"}, - {"skipkeys", T_BOOL, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"}, - {NULL} -}; - -/* Forward decls */ - -static PyObject * -ascii_escape_unicode(PyObject *pystr); -static PyObject * + + +typedef struct _PyScannerObject { + PyObject_HEAD + signed char strict; + PyObject *object_hook; + PyObject *object_pairs_hook; + PyObject *parse_float; + PyObject *parse_int; + PyObject *parse_constant; + PyObject *memo; +} PyScannerObject; + +static PyMemberDef scanner_members[] = { + {"strict", T_BOOL, offsetof(PyScannerObject, strict), READONLY, "strict"}, + {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"}, + {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, object_pairs_hook), READONLY}, + {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"}, + {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"}, + {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"}, + {NULL} +}; + +typedef struct _PyEncoderObject { + PyObject_HEAD + PyObject *markers; + PyObject *defaultfn; + PyObject *encoder; + PyObject *indent; + PyObject *key_separator; + PyObject *item_separator; + char sort_keys; + char skipkeys; + int allow_nan; + PyCFunction fast_encode; +} PyEncoderObject; + +static PyMemberDef encoder_members[] = { + {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"}, + {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"}, + {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"}, + {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"}, + {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"}, + {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"}, + {"sort_keys", T_BOOL, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"}, + {"skipkeys", T_BOOL, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"}, + {NULL} +}; + +/* Forward decls */ + +static PyObject * +ascii_escape_unicode(PyObject *pystr); +static PyObject * py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr); -void init_json(void); -static PyObject * -scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); -static PyObject * -_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx); -static PyObject * -scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -static void -scanner_dealloc(PyObject *self); -static int +void init_json(void); +static PyObject * +scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); +static PyObject * +_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx); +static PyObject * +scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static void +scanner_dealloc(PyObject *self); +static int scanner_clear(PyScannerObject *self); -static PyObject * -encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -static void -encoder_dealloc(PyObject *self); -static int +static PyObject * +encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static void +encoder_dealloc(PyObject *self); +static int encoder_clear(PyEncoderObject *self); -static int -encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level); -static int -encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, PyObject *obj, Py_ssize_t indent_level); -static int -encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssize_t indent_level); -static PyObject * -_encoded_const(PyObject *obj); -static void -raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end); -static PyObject * -encoder_encode_string(PyEncoderObject *s, PyObject *obj); -static PyObject * -encoder_encode_float(PyEncoderObject *s, PyObject *obj); - -#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"') -#define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r')) - -static Py_ssize_t -ascii_escape_unichar(Py_UCS4 c, unsigned char *output, Py_ssize_t chars) -{ - /* Escape unicode code point c to ASCII escape sequences - in char *output. output must have at least 12 bytes unused to - accommodate an escaped surrogate pair "\uXXXX\uXXXX" */ - output[chars++] = '\\'; - switch (c) { - case '\\': output[chars++] = c; break; - case '"': output[chars++] = c; break; - case '\b': output[chars++] = 'b'; break; - case '\f': output[chars++] = 'f'; break; - case '\n': output[chars++] = 'n'; break; - case '\r': output[chars++] = 'r'; break; - case '\t': output[chars++] = 't'; break; - default: - if (c >= 0x10000) { - /* UTF-16 surrogate pair */ - Py_UCS4 v = Py_UNICODE_HIGH_SURROGATE(c); - output[chars++] = 'u'; - output[chars++] = Py_hexdigits[(v >> 12) & 0xf]; - output[chars++] = Py_hexdigits[(v >> 8) & 0xf]; - output[chars++] = Py_hexdigits[(v >> 4) & 0xf]; - output[chars++] = Py_hexdigits[(v ) & 0xf]; - c = Py_UNICODE_LOW_SURROGATE(c); - output[chars++] = '\\'; - } - output[chars++] = 'u'; - output[chars++] = Py_hexdigits[(c >> 12) & 0xf]; - output[chars++] = Py_hexdigits[(c >> 8) & 0xf]; - output[chars++] = Py_hexdigits[(c >> 4) & 0xf]; - output[chars++] = Py_hexdigits[(c ) & 0xf]; - } - return chars; -} - -static PyObject * -ascii_escape_unicode(PyObject *pystr) -{ - /* Take a PyUnicode pystr and return a new ASCII-only escaped PyUnicode */ - Py_ssize_t i; - Py_ssize_t input_chars; - Py_ssize_t output_size; - Py_ssize_t chars; - PyObject *rval; +static int +encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level); +static int +encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, PyObject *obj, Py_ssize_t indent_level); +static int +encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssize_t indent_level); +static PyObject * +_encoded_const(PyObject *obj); +static void +raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end); +static PyObject * +encoder_encode_string(PyEncoderObject *s, PyObject *obj); +static PyObject * +encoder_encode_float(PyEncoderObject *s, PyObject *obj); + +#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"') +#define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r')) + +static Py_ssize_t +ascii_escape_unichar(Py_UCS4 c, unsigned char *output, Py_ssize_t chars) +{ + /* Escape unicode code point c to ASCII escape sequences + in char *output. output must have at least 12 bytes unused to + accommodate an escaped surrogate pair "\uXXXX\uXXXX" */ + output[chars++] = '\\'; + switch (c) { + case '\\': output[chars++] = c; break; + case '"': output[chars++] = c; break; + case '\b': output[chars++] = 'b'; break; + case '\f': output[chars++] = 'f'; break; + case '\n': output[chars++] = 'n'; break; + case '\r': output[chars++] = 'r'; break; + case '\t': output[chars++] = 't'; break; + default: + if (c >= 0x10000) { + /* UTF-16 surrogate pair */ + Py_UCS4 v = Py_UNICODE_HIGH_SURROGATE(c); + output[chars++] = 'u'; + output[chars++] = Py_hexdigits[(v >> 12) & 0xf]; + output[chars++] = Py_hexdigits[(v >> 8) & 0xf]; + output[chars++] = Py_hexdigits[(v >> 4) & 0xf]; + output[chars++] = Py_hexdigits[(v ) & 0xf]; + c = Py_UNICODE_LOW_SURROGATE(c); + output[chars++] = '\\'; + } + output[chars++] = 'u'; + output[chars++] = Py_hexdigits[(c >> 12) & 0xf]; + output[chars++] = Py_hexdigits[(c >> 8) & 0xf]; + output[chars++] = Py_hexdigits[(c >> 4) & 0xf]; + output[chars++] = Py_hexdigits[(c ) & 0xf]; + } + return chars; +} + +static PyObject * +ascii_escape_unicode(PyObject *pystr) +{ + /* Take a PyUnicode pystr and return a new ASCII-only escaped PyUnicode */ + Py_ssize_t i; + Py_ssize_t input_chars; + Py_ssize_t output_size; + Py_ssize_t chars; + PyObject *rval; const void *input; Py_UCS1 *output; - int kind; - - if (PyUnicode_READY(pystr) == -1) - return NULL; - - input_chars = PyUnicode_GET_LENGTH(pystr); - input = PyUnicode_DATA(pystr); - kind = PyUnicode_KIND(pystr); - - /* Compute the output size */ - for (i = 0, output_size = 2; i < input_chars; i++) { - Py_UCS4 c = PyUnicode_READ(kind, input, i); - Py_ssize_t d; - if (S_CHAR(c)) { - d = 1; - } - else { - switch(c) { - case '\\': case '"': case '\b': case '\f': - case '\n': case '\r': case '\t': - d = 2; break; - default: - d = c >= 0x10000 ? 12 : 6; - } - } - if (output_size > PY_SSIZE_T_MAX - d) { - PyErr_SetString(PyExc_OverflowError, "string is too long to escape"); - return NULL; - } - output_size += d; - } - - rval = PyUnicode_New(output_size, 127); - if (rval == NULL) { - return NULL; - } - output = PyUnicode_1BYTE_DATA(rval); - chars = 0; - output[chars++] = '"'; - for (i = 0; i < input_chars; i++) { - Py_UCS4 c = PyUnicode_READ(kind, input, i); - if (S_CHAR(c)) { - output[chars++] = c; - } - else { - chars = ascii_escape_unichar(c, output, chars); - } - } - output[chars++] = '"'; -#ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(rval, 1)); -#endif - return rval; -} - -static PyObject * -escape_unicode(PyObject *pystr) -{ - /* Take a PyUnicode pystr and return a new escaped PyUnicode */ - Py_ssize_t i; - Py_ssize_t input_chars; - Py_ssize_t output_size; - Py_ssize_t chars; - PyObject *rval; + int kind; + + if (PyUnicode_READY(pystr) == -1) + return NULL; + + input_chars = PyUnicode_GET_LENGTH(pystr); + input = PyUnicode_DATA(pystr); + kind = PyUnicode_KIND(pystr); + + /* Compute the output size */ + for (i = 0, output_size = 2; i < input_chars; i++) { + Py_UCS4 c = PyUnicode_READ(kind, input, i); + Py_ssize_t d; + if (S_CHAR(c)) { + d = 1; + } + else { + switch(c) { + case '\\': case '"': case '\b': case '\f': + case '\n': case '\r': case '\t': + d = 2; break; + default: + d = c >= 0x10000 ? 12 : 6; + } + } + if (output_size > PY_SSIZE_T_MAX - d) { + PyErr_SetString(PyExc_OverflowError, "string is too long to escape"); + return NULL; + } + output_size += d; + } + + rval = PyUnicode_New(output_size, 127); + if (rval == NULL) { + return NULL; + } + output = PyUnicode_1BYTE_DATA(rval); + chars = 0; + output[chars++] = '"'; + for (i = 0; i < input_chars; i++) { + Py_UCS4 c = PyUnicode_READ(kind, input, i); + if (S_CHAR(c)) { + output[chars++] = c; + } + else { + chars = ascii_escape_unichar(c, output, chars); + } + } + output[chars++] = '"'; +#ifdef Py_DEBUG + assert(_PyUnicode_CheckConsistency(rval, 1)); +#endif + return rval; +} + +static PyObject * +escape_unicode(PyObject *pystr) +{ + /* Take a PyUnicode pystr and return a new escaped PyUnicode */ + Py_ssize_t i; + Py_ssize_t input_chars; + Py_ssize_t output_size; + Py_ssize_t chars; + PyObject *rval; const void *input; - int kind; - Py_UCS4 maxchar; - - if (PyUnicode_READY(pystr) == -1) - return NULL; - - maxchar = PyUnicode_MAX_CHAR_VALUE(pystr); - input_chars = PyUnicode_GET_LENGTH(pystr); - input = PyUnicode_DATA(pystr); - kind = PyUnicode_KIND(pystr); - - /* Compute the output size */ - for (i = 0, output_size = 2; i < input_chars; i++) { - Py_UCS4 c = PyUnicode_READ(kind, input, i); - Py_ssize_t d; - switch (c) { - case '\\': case '"': case '\b': case '\f': - case '\n': case '\r': case '\t': - d = 2; - break; - default: - if (c <= 0x1f) - d = 6; - else - d = 1; - } - if (output_size > PY_SSIZE_T_MAX - d) { - PyErr_SetString(PyExc_OverflowError, "string is too long to escape"); - return NULL; - } - output_size += d; - } - - rval = PyUnicode_New(output_size, maxchar); - if (rval == NULL) - return NULL; - - kind = PyUnicode_KIND(rval); - -#define ENCODE_OUTPUT do { \ - chars = 0; \ - output[chars++] = '"'; \ - for (i = 0; i < input_chars; i++) { \ - Py_UCS4 c = PyUnicode_READ(kind, input, i); \ - switch (c) { \ - case '\\': output[chars++] = '\\'; output[chars++] = c; break; \ - case '"': output[chars++] = '\\'; output[chars++] = c; break; \ - case '\b': output[chars++] = '\\'; output[chars++] = 'b'; break; \ - case '\f': output[chars++] = '\\'; output[chars++] = 'f'; break; \ - case '\n': output[chars++] = '\\'; output[chars++] = 'n'; break; \ - case '\r': output[chars++] = '\\'; output[chars++] = 'r'; break; \ - case '\t': output[chars++] = '\\'; output[chars++] = 't'; break; \ - default: \ - if (c <= 0x1f) { \ - output[chars++] = '\\'; \ - output[chars++] = 'u'; \ - output[chars++] = '0'; \ - output[chars++] = '0'; \ - output[chars++] = Py_hexdigits[(c >> 4) & 0xf]; \ - output[chars++] = Py_hexdigits[(c ) & 0xf]; \ - } else { \ - output[chars++] = c; \ - } \ - } \ - } \ - output[chars++] = '"'; \ - } while (0) - - if (kind == PyUnicode_1BYTE_KIND) { - Py_UCS1 *output = PyUnicode_1BYTE_DATA(rval); - ENCODE_OUTPUT; - } else if (kind == PyUnicode_2BYTE_KIND) { - Py_UCS2 *output = PyUnicode_2BYTE_DATA(rval); - ENCODE_OUTPUT; - } else { - Py_UCS4 *output = PyUnicode_4BYTE_DATA(rval); - assert(kind == PyUnicode_4BYTE_KIND); - ENCODE_OUTPUT; - } -#undef ENCODE_OUTPUT - -#ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(rval, 1)); -#endif - return rval; -} - -static void -raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end) -{ - /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ - static PyObject *JSONDecodeError = NULL; - PyObject *exc; - if (JSONDecodeError == NULL) { - PyObject *decoder = PyImport_ImportModule("json.decoder"); - if (decoder == NULL) - return; - JSONDecodeError = PyObject_GetAttrString(decoder, "JSONDecodeError"); - Py_DECREF(decoder); - if (JSONDecodeError == NULL) - return; - } - exc = PyObject_CallFunction(JSONDecodeError, "zOn", msg, s, end); - if (exc) { - PyErr_SetObject(JSONDecodeError, exc); - Py_DECREF(exc); - } -} - -static void -raise_stop_iteration(Py_ssize_t idx) -{ - PyObject *value = PyLong_FromSsize_t(idx); - if (value != NULL) { - PyErr_SetObject(PyExc_StopIteration, value); - Py_DECREF(value); - } -} - -static PyObject * -_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) { - /* return (rval, idx) tuple, stealing reference to rval */ - PyObject *tpl; - PyObject *pyidx; - /* - steal a reference to rval, returns (rval, idx) - */ - if (rval == NULL) { - return NULL; - } - pyidx = PyLong_FromSsize_t(idx); - if (pyidx == NULL) { - Py_DECREF(rval); - return NULL; - } - tpl = PyTuple_New(2); - if (tpl == NULL) { - Py_DECREF(pyidx); - Py_DECREF(rval); - return NULL; - } - PyTuple_SET_ITEM(tpl, 0, rval); - PyTuple_SET_ITEM(tpl, 1, pyidx); - return tpl; -} - -static PyObject * -scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr) -{ - /* Read the JSON string from PyUnicode pystr. - end is the index of the first character after the quote. - if strict is zero then literal control characters are allowed - *next_end_ptr is a return-by-reference index of the character - after the end quote - - Return value is a new PyUnicode - */ - PyObject *rval = NULL; - Py_ssize_t len; - Py_ssize_t begin = end - 1; - Py_ssize_t next /* = begin */; - const void *buf; - int kind; - - if (PyUnicode_READY(pystr) == -1) - return 0; - + int kind; + Py_UCS4 maxchar; + + if (PyUnicode_READY(pystr) == -1) + return NULL; + + maxchar = PyUnicode_MAX_CHAR_VALUE(pystr); + input_chars = PyUnicode_GET_LENGTH(pystr); + input = PyUnicode_DATA(pystr); + kind = PyUnicode_KIND(pystr); + + /* Compute the output size */ + for (i = 0, output_size = 2; i < input_chars; i++) { + Py_UCS4 c = PyUnicode_READ(kind, input, i); + Py_ssize_t d; + switch (c) { + case '\\': case '"': case '\b': case '\f': + case '\n': case '\r': case '\t': + d = 2; + break; + default: + if (c <= 0x1f) + d = 6; + else + d = 1; + } + if (output_size > PY_SSIZE_T_MAX - d) { + PyErr_SetString(PyExc_OverflowError, "string is too long to escape"); + return NULL; + } + output_size += d; + } + + rval = PyUnicode_New(output_size, maxchar); + if (rval == NULL) + return NULL; + + kind = PyUnicode_KIND(rval); + +#define ENCODE_OUTPUT do { \ + chars = 0; \ + output[chars++] = '"'; \ + for (i = 0; i < input_chars; i++) { \ + Py_UCS4 c = PyUnicode_READ(kind, input, i); \ + switch (c) { \ + case '\\': output[chars++] = '\\'; output[chars++] = c; break; \ + case '"': output[chars++] = '\\'; output[chars++] = c; break; \ + case '\b': output[chars++] = '\\'; output[chars++] = 'b'; break; \ + case '\f': output[chars++] = '\\'; output[chars++] = 'f'; break; \ + case '\n': output[chars++] = '\\'; output[chars++] = 'n'; break; \ + case '\r': output[chars++] = '\\'; output[chars++] = 'r'; break; \ + case '\t': output[chars++] = '\\'; output[chars++] = 't'; break; \ + default: \ + if (c <= 0x1f) { \ + output[chars++] = '\\'; \ + output[chars++] = 'u'; \ + output[chars++] = '0'; \ + output[chars++] = '0'; \ + output[chars++] = Py_hexdigits[(c >> 4) & 0xf]; \ + output[chars++] = Py_hexdigits[(c ) & 0xf]; \ + } else { \ + output[chars++] = c; \ + } \ + } \ + } \ + output[chars++] = '"'; \ + } while (0) + + if (kind == PyUnicode_1BYTE_KIND) { + Py_UCS1 *output = PyUnicode_1BYTE_DATA(rval); + ENCODE_OUTPUT; + } else if (kind == PyUnicode_2BYTE_KIND) { + Py_UCS2 *output = PyUnicode_2BYTE_DATA(rval); + ENCODE_OUTPUT; + } else { + Py_UCS4 *output = PyUnicode_4BYTE_DATA(rval); + assert(kind == PyUnicode_4BYTE_KIND); + ENCODE_OUTPUT; + } +#undef ENCODE_OUTPUT + +#ifdef Py_DEBUG + assert(_PyUnicode_CheckConsistency(rval, 1)); +#endif + return rval; +} + +static void +raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end) +{ + /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ + static PyObject *JSONDecodeError = NULL; + PyObject *exc; + if (JSONDecodeError == NULL) { + PyObject *decoder = PyImport_ImportModule("json.decoder"); + if (decoder == NULL) + return; + JSONDecodeError = PyObject_GetAttrString(decoder, "JSONDecodeError"); + Py_DECREF(decoder); + if (JSONDecodeError == NULL) + return; + } + exc = PyObject_CallFunction(JSONDecodeError, "zOn", msg, s, end); + if (exc) { + PyErr_SetObject(JSONDecodeError, exc); + Py_DECREF(exc); + } +} + +static void +raise_stop_iteration(Py_ssize_t idx) +{ + PyObject *value = PyLong_FromSsize_t(idx); + if (value != NULL) { + PyErr_SetObject(PyExc_StopIteration, value); + Py_DECREF(value); + } +} + +static PyObject * +_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) { + /* return (rval, idx) tuple, stealing reference to rval */ + PyObject *tpl; + PyObject *pyidx; + /* + steal a reference to rval, returns (rval, idx) + */ + if (rval == NULL) { + return NULL; + } + pyidx = PyLong_FromSsize_t(idx); + if (pyidx == NULL) { + Py_DECREF(rval); + return NULL; + } + tpl = PyTuple_New(2); + if (tpl == NULL) { + Py_DECREF(pyidx); + Py_DECREF(rval); + return NULL; + } + PyTuple_SET_ITEM(tpl, 0, rval); + PyTuple_SET_ITEM(tpl, 1, pyidx); + return tpl; +} + +static PyObject * +scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr) +{ + /* Read the JSON string from PyUnicode pystr. + end is the index of the first character after the quote. + if strict is zero then literal control characters are allowed + *next_end_ptr is a return-by-reference index of the character + after the end quote + + Return value is a new PyUnicode + */ + PyObject *rval = NULL; + Py_ssize_t len; + Py_ssize_t begin = end - 1; + Py_ssize_t next /* = begin */; + const void *buf; + int kind; + + if (PyUnicode_READY(pystr) == -1) + return 0; + _PyUnicodeWriter writer; _PyUnicodeWriter_Init(&writer); writer.overallocate = 1; - len = PyUnicode_GET_LENGTH(pystr); - buf = PyUnicode_DATA(pystr); - kind = PyUnicode_KIND(pystr); - - if (end < 0 || len < end) { - PyErr_SetString(PyExc_ValueError, "end is out of bounds"); - goto bail; - } - while (1) { - /* Find the end of the string or the next escape */ + len = PyUnicode_GET_LENGTH(pystr); + buf = PyUnicode_DATA(pystr); + kind = PyUnicode_KIND(pystr); + + if (end < 0 || len < end) { + PyErr_SetString(PyExc_ValueError, "end is out of bounds"); + goto bail; + } + while (1) { + /* Find the end of the string or the next escape */ Py_UCS4 c; { // Use tight scope variable to help register allocation. @@ -420,7 +420,7 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next raise_errmsg("Invalid control character at", pystr, next); goto bail; } - } + } c = d; } @@ -433,220 +433,220 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next } *next_end_ptr = next + 1;; return ret; - } - } + } + } else if (c != '\\') { - raise_errmsg("Unterminated string starting at", pystr, begin); - goto bail; - } + raise_errmsg("Unterminated string starting at", pystr, begin); + goto bail; + } - /* Pick up this chunk if it's not zero length */ - if (next != end) { + /* Pick up this chunk if it's not zero length */ + if (next != end) { if (_PyUnicodeWriter_WriteSubstring(&writer, pystr, end, next) < 0) { - goto bail; - } - } - next++; - if (c == '"') { - end = next; - break; - } - if (next == len) { - raise_errmsg("Unterminated string starting at", pystr, begin); - goto bail; - } - c = PyUnicode_READ(kind, buf, next); - if (c != 'u') { - /* Non-unicode backslash escapes */ - end = next + 1; - switch (c) { - case '"': break; - case '\\': break; - case '/': break; - case 'b': c = '\b'; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - default: c = 0; - } - if (c == 0) { - raise_errmsg("Invalid \\escape", pystr, end - 2); - goto bail; - } - } - else { - c = 0; - next++; - end = next + 4; - if (end >= len) { - raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1); - goto bail; - } - /* Decode 4 hex digits */ - for (; next < end; next++) { - Py_UCS4 digit = PyUnicode_READ(kind, buf, next); - c <<= 4; - switch (digit) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - c |= (digit - '0'); break; - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': - c |= (digit - 'a' + 10); break; - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': - c |= (digit - 'A' + 10); break; - default: - raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); - goto bail; - } - } - /* Surrogate pair */ - if (Py_UNICODE_IS_HIGH_SURROGATE(c) && end + 6 < len && - PyUnicode_READ(kind, buf, next++) == '\\' && - PyUnicode_READ(kind, buf, next++) == 'u') { - Py_UCS4 c2 = 0; - end += 6; - /* Decode 4 hex digits */ - for (; next < end; next++) { - Py_UCS4 digit = PyUnicode_READ(kind, buf, next); - c2 <<= 4; - switch (digit) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - c2 |= (digit - '0'); break; - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': - c2 |= (digit - 'a' + 10); break; - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': - c2 |= (digit - 'A' + 10); break; - default: - raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); - goto bail; - } - } - if (Py_UNICODE_IS_LOW_SURROGATE(c2)) - c = Py_UNICODE_JOIN_SURROGATES(c, c2); - else - end -= 6; - } - } + goto bail; + } + } + next++; + if (c == '"') { + end = next; + break; + } + if (next == len) { + raise_errmsg("Unterminated string starting at", pystr, begin); + goto bail; + } + c = PyUnicode_READ(kind, buf, next); + if (c != 'u') { + /* Non-unicode backslash escapes */ + end = next + 1; + switch (c) { + case '"': break; + case '\\': break; + case '/': break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + default: c = 0; + } + if (c == 0) { + raise_errmsg("Invalid \\escape", pystr, end - 2); + goto bail; + } + } + else { + c = 0; + next++; + end = next + 4; + if (end >= len) { + raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1); + goto bail; + } + /* Decode 4 hex digits */ + for (; next < end; next++) { + Py_UCS4 digit = PyUnicode_READ(kind, buf, next); + c <<= 4; + switch (digit) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + c |= (digit - '0'); break; + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': + c |= (digit - 'a' + 10); break; + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': + c |= (digit - 'A' + 10); break; + default: + raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); + goto bail; + } + } + /* Surrogate pair */ + if (Py_UNICODE_IS_HIGH_SURROGATE(c) && end + 6 < len && + PyUnicode_READ(kind, buf, next++) == '\\' && + PyUnicode_READ(kind, buf, next++) == 'u') { + Py_UCS4 c2 = 0; + end += 6; + /* Decode 4 hex digits */ + for (; next < end; next++) { + Py_UCS4 digit = PyUnicode_READ(kind, buf, next); + c2 <<= 4; + switch (digit) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + c2 |= (digit - '0'); break; + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': + c2 |= (digit - 'a' + 10); break; + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': + c2 |= (digit - 'A' + 10); break; + default: + raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); + goto bail; + } + } + if (Py_UNICODE_IS_LOW_SURROGATE(c2)) + c = Py_UNICODE_JOIN_SURROGATES(c, c2); + else + end -= 6; + } + } if (_PyUnicodeWriter_WriteChar(&writer, c) < 0) { - goto bail; - } - } - + goto bail; + } + } + rval = _PyUnicodeWriter_Finish(&writer); - *next_end_ptr = end; - return rval; + *next_end_ptr = end; + return rval; -bail: - *next_end_ptr = -1; +bail: + *next_end_ptr = -1; _PyUnicodeWriter_Dealloc(&writer); - return NULL; -} - -PyDoc_STRVAR(pydoc_scanstring, - "scanstring(string, end, strict=True) -> (string, end)\n" - "\n" - "Scan the string s for a JSON string. End is the index of the\n" - "character in s after the quote that started the JSON string.\n" - "Unescapes all valid JSON string escape sequences and raises ValueError\n" - "on attempt to decode an invalid string. If strict is False then literal\n" - "control characters are allowed in the string.\n" - "\n" - "Returns a tuple of the decoded string and the index of the character in s\n" - "after the end quote." -); - -static PyObject * + return NULL; +} + +PyDoc_STRVAR(pydoc_scanstring, + "scanstring(string, end, strict=True) -> (string, end)\n" + "\n" + "Scan the string s for a JSON string. End is the index of the\n" + "character in s after the quote that started the JSON string.\n" + "Unescapes all valid JSON string escape sequences and raises ValueError\n" + "on attempt to decode an invalid string. If strict is False then literal\n" + "control characters are allowed in the string.\n" + "\n" + "Returns a tuple of the decoded string and the index of the character in s\n" + "after the end quote." +); + +static PyObject * py_scanstring(PyObject* Py_UNUSED(self), PyObject *args) -{ - PyObject *pystr; - PyObject *rval; - Py_ssize_t end; - Py_ssize_t next_end = -1; - int strict = 1; - if (!PyArg_ParseTuple(args, "On|i:scanstring", &pystr, &end, &strict)) { - return NULL; - } - if (PyUnicode_Check(pystr)) { - rval = scanstring_unicode(pystr, end, strict, &next_end); - } - else { - PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); - return NULL; - } - return _build_rval_index_tuple(rval, next_end); -} - -PyDoc_STRVAR(pydoc_encode_basestring_ascii, - "encode_basestring_ascii(string) -> string\n" - "\n" - "Return an ASCII-only JSON representation of a Python string" -); - -static PyObject * +{ + PyObject *pystr; + PyObject *rval; + Py_ssize_t end; + Py_ssize_t next_end = -1; + int strict = 1; + if (!PyArg_ParseTuple(args, "On|i:scanstring", &pystr, &end, &strict)) { + return NULL; + } + if (PyUnicode_Check(pystr)) { + rval = scanstring_unicode(pystr, end, strict, &next_end); + } + else { + PyErr_Format(PyExc_TypeError, + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); + return NULL; + } + return _build_rval_index_tuple(rval, next_end); +} + +PyDoc_STRVAR(pydoc_encode_basestring_ascii, + "encode_basestring_ascii(string) -> string\n" + "\n" + "Return an ASCII-only JSON representation of a Python string" +); + +static PyObject * py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr) -{ - PyObject *rval; - /* Return an ASCII-only JSON representation of a Python string */ - /* METH_O */ - if (PyUnicode_Check(pystr)) { - rval = ascii_escape_unicode(pystr); - } - else { - PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); - return NULL; - } - return rval; -} - - -PyDoc_STRVAR(pydoc_encode_basestring, - "encode_basestring(string) -> string\n" - "\n" - "Return a JSON representation of a Python string" -); - -static PyObject * +{ + PyObject *rval; + /* Return an ASCII-only JSON representation of a Python string */ + /* METH_O */ + if (PyUnicode_Check(pystr)) { + rval = ascii_escape_unicode(pystr); + } + else { + PyErr_Format(PyExc_TypeError, + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); + return NULL; + } + return rval; +} + + +PyDoc_STRVAR(pydoc_encode_basestring, + "encode_basestring(string) -> string\n" + "\n" + "Return a JSON representation of a Python string" +); + +static PyObject * py_encode_basestring(PyObject* Py_UNUSED(self), PyObject *pystr) -{ - PyObject *rval; - /* Return a JSON representation of a Python string */ - /* METH_O */ - if (PyUnicode_Check(pystr)) { - rval = escape_unicode(pystr); - } - else { - PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); - return NULL; - } - return rval; -} - -static void -scanner_dealloc(PyObject *self) -{ +{ + PyObject *rval; + /* Return a JSON representation of a Python string */ + /* METH_O */ + if (PyUnicode_Check(pystr)) { + rval = escape_unicode(pystr); + } + else { + PyErr_Format(PyExc_TypeError, + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); + return NULL; + } + return rval; +} + +static void +scanner_dealloc(PyObject *self) +{ PyTypeObject *tp = Py_TYPE(self); - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(self); + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(self); scanner_clear((PyScannerObject *)self); tp->tp_free(self); Py_DECREF(tp); -} - -static int +} + +static int scanner_traverse(PyScannerObject *self, visitproc visit, void *arg) -{ +{ Py_VISIT(Py_TYPE(self)); Py_VISIT(self->object_hook); Py_VISIT(self->object_pairs_hook); @@ -654,70 +654,70 @@ scanner_traverse(PyScannerObject *self, visitproc visit, void *arg) Py_VISIT(self->parse_int); Py_VISIT(self->parse_constant); Py_VISIT(self->memo); - return 0; -} - -static int + return 0; +} + +static int scanner_clear(PyScannerObject *self) -{ +{ Py_CLEAR(self->object_hook); Py_CLEAR(self->object_pairs_hook); Py_CLEAR(self->parse_float); Py_CLEAR(self->parse_int); Py_CLEAR(self->parse_constant); Py_CLEAR(self->memo); - return 0; -} - -static PyObject * -_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) -{ - /* Read a JSON object from PyUnicode pystr. - idx is the index of the first character after the opening curly brace. - *next_idx_ptr is a return-by-reference index to the first character after - the closing curly brace. - - Returns a new PyObject (usually a dict, but object_hook can change that) - */ + return 0; +} + +static PyObject * +_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) +{ + /* Read a JSON object from PyUnicode pystr. + idx is the index of the first character after the opening curly brace. + *next_idx_ptr is a return-by-reference index to the first character after + the closing curly brace. + + Returns a new PyObject (usually a dict, but object_hook can change that) + */ const void *str; - int kind; - Py_ssize_t end_idx; - PyObject *val = NULL; - PyObject *rval = NULL; - PyObject *key = NULL; - int has_pairs_hook = (s->object_pairs_hook != Py_None); - Py_ssize_t next_idx; - - if (PyUnicode_READY(pystr) == -1) - return NULL; - - str = PyUnicode_DATA(pystr); - kind = PyUnicode_KIND(pystr); - end_idx = PyUnicode_GET_LENGTH(pystr) - 1; - - if (has_pairs_hook) - rval = PyList_New(0); - else - rval = PyDict_New(); - if (rval == NULL) - return NULL; - - /* skip whitespace after { */ - while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind,str, idx))) idx++; - - /* only loop if the object is non-empty */ - if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '}') { - while (1) { - PyObject *memokey; - - /* read key */ - if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '"') { - raise_errmsg("Expecting property name enclosed in double quotes", pystr, idx); - goto bail; - } - key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx); - if (key == NULL) - goto bail; + int kind; + Py_ssize_t end_idx; + PyObject *val = NULL; + PyObject *rval = NULL; + PyObject *key = NULL; + int has_pairs_hook = (s->object_pairs_hook != Py_None); + Py_ssize_t next_idx; + + if (PyUnicode_READY(pystr) == -1) + return NULL; + + str = PyUnicode_DATA(pystr); + kind = PyUnicode_KIND(pystr); + end_idx = PyUnicode_GET_LENGTH(pystr) - 1; + + if (has_pairs_hook) + rval = PyList_New(0); + else + rval = PyDict_New(); + if (rval == NULL) + return NULL; + + /* skip whitespace after { */ + while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind,str, idx))) idx++; + + /* only loop if the object is non-empty */ + if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '}') { + while (1) { + PyObject *memokey; + + /* read key */ + if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '"') { + raise_errmsg("Expecting property name enclosed in double quotes", pystr, idx); + goto bail; + } + key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx); + if (key == NULL) + goto bail; memokey = PyDict_SetDefault(s->memo, key, key); if (memokey == NULL) { goto bail; @@ -725,491 +725,491 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss Py_INCREF(memokey); Py_DECREF(key); key = memokey; - idx = next_idx; - - /* skip whitespace between key and : delimiter, read :, skip whitespace */ - while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; - if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ':') { - raise_errmsg("Expecting ':' delimiter", pystr, idx); - goto bail; - } - idx++; - while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; - - /* read any JSON term */ - val = scan_once_unicode(s, pystr, idx, &next_idx); - if (val == NULL) - goto bail; - - if (has_pairs_hook) { - PyObject *item = PyTuple_Pack(2, key, val); - if (item == NULL) - goto bail; - Py_CLEAR(key); - Py_CLEAR(val); - if (PyList_Append(rval, item) == -1) { - Py_DECREF(item); - goto bail; - } - Py_DECREF(item); - } - else { - if (PyDict_SetItem(rval, key, val) < 0) - goto bail; - Py_CLEAR(key); - Py_CLEAR(val); - } - idx = next_idx; - - /* skip whitespace before } or , */ - while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; - - /* bail if the object is closed or we didn't get the , delimiter */ - if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == '}') - break; - if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') { - raise_errmsg("Expecting ',' delimiter", pystr, idx); - goto bail; - } - idx++; - - /* skip whitespace after , delimiter */ - while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; - } - } - - *next_idx_ptr = idx + 1; - - if (has_pairs_hook) { + idx = next_idx; + + /* skip whitespace between key and : delimiter, read :, skip whitespace */ + while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; + if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ':') { + raise_errmsg("Expecting ':' delimiter", pystr, idx); + goto bail; + } + idx++; + while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; + + /* read any JSON term */ + val = scan_once_unicode(s, pystr, idx, &next_idx); + if (val == NULL) + goto bail; + + if (has_pairs_hook) { + PyObject *item = PyTuple_Pack(2, key, val); + if (item == NULL) + goto bail; + Py_CLEAR(key); + Py_CLEAR(val); + if (PyList_Append(rval, item) == -1) { + Py_DECREF(item); + goto bail; + } + Py_DECREF(item); + } + else { + if (PyDict_SetItem(rval, key, val) < 0) + goto bail; + Py_CLEAR(key); + Py_CLEAR(val); + } + idx = next_idx; + + /* skip whitespace before } or , */ + while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; + + /* bail if the object is closed or we didn't get the , delimiter */ + if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == '}') + break; + if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') { + raise_errmsg("Expecting ',' delimiter", pystr, idx); + goto bail; + } + idx++; + + /* skip whitespace after , delimiter */ + while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; + } + } + + *next_idx_ptr = idx + 1; + + if (has_pairs_hook) { val = PyObject_CallOneArg(s->object_pairs_hook, rval); - Py_DECREF(rval); - return val; - } - - /* if object_hook is not None: rval = object_hook(rval) */ - if (s->object_hook != Py_None) { + Py_DECREF(rval); + return val; + } + + /* if object_hook is not None: rval = object_hook(rval) */ + if (s->object_hook != Py_None) { val = PyObject_CallOneArg(s->object_hook, rval); - Py_DECREF(rval); - return val; - } - return rval; -bail: - Py_XDECREF(key); - Py_XDECREF(val); - Py_XDECREF(rval); - return NULL; -} - -static PyObject * -_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { - /* Read a JSON array from PyUnicode pystr. - idx is the index of the first character after the opening brace. - *next_idx_ptr is a return-by-reference index to the first character after - the closing brace. - - Returns a new PyList - */ + Py_DECREF(rval); + return val; + } + return rval; +bail: + Py_XDECREF(key); + Py_XDECREF(val); + Py_XDECREF(rval); + return NULL; +} + +static PyObject * +_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { + /* Read a JSON array from PyUnicode pystr. + idx is the index of the first character after the opening brace. + *next_idx_ptr is a return-by-reference index to the first character after + the closing brace. + + Returns a new PyList + */ const void *str; - int kind; - Py_ssize_t end_idx; - PyObject *val = NULL; - PyObject *rval; - Py_ssize_t next_idx; - - if (PyUnicode_READY(pystr) == -1) - return NULL; - - rval = PyList_New(0); - if (rval == NULL) - return NULL; - - str = PyUnicode_DATA(pystr); - kind = PyUnicode_KIND(pystr); - end_idx = PyUnicode_GET_LENGTH(pystr) - 1; - - /* skip whitespace after [ */ - while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; - - /* only loop if the array is non-empty */ - if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') { - while (1) { - - /* read any JSON term */ - val = scan_once_unicode(s, pystr, idx, &next_idx); - if (val == NULL) - goto bail; - - if (PyList_Append(rval, val) == -1) - goto bail; - - Py_CLEAR(val); - idx = next_idx; - - /* skip whitespace between term and , */ - while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; - - /* bail if the array is closed or we didn't get the , delimiter */ - if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == ']') - break; - if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') { - raise_errmsg("Expecting ',' delimiter", pystr, idx); - goto bail; - } - idx++; - - /* skip whitespace after , */ - while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; - } - } - - /* verify that idx < end_idx, PyUnicode_READ(kind, str, idx) should be ']' */ - if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') { - raise_errmsg("Expecting value", pystr, end_idx); - goto bail; - } - *next_idx_ptr = idx + 1; - return rval; -bail: - Py_XDECREF(val); - Py_DECREF(rval); - return NULL; -} - -static PyObject * -_parse_constant(PyScannerObject *s, const char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { - /* Read a JSON constant. - constant is the constant string that was found - ("NaN", "Infinity", "-Infinity"). - idx is the index of the first character of the constant - *next_idx_ptr is a return-by-reference index to the first character after - the constant. - - Returns the result of parse_constant - */ - PyObject *cstr; - PyObject *rval; - /* constant is "NaN", "Infinity", or "-Infinity" */ - cstr = PyUnicode_InternFromString(constant); - if (cstr == NULL) - return NULL; - - /* rval = parse_constant(constant) */ + int kind; + Py_ssize_t end_idx; + PyObject *val = NULL; + PyObject *rval; + Py_ssize_t next_idx; + + if (PyUnicode_READY(pystr) == -1) + return NULL; + + rval = PyList_New(0); + if (rval == NULL) + return NULL; + + str = PyUnicode_DATA(pystr); + kind = PyUnicode_KIND(pystr); + end_idx = PyUnicode_GET_LENGTH(pystr) - 1; + + /* skip whitespace after [ */ + while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; + + /* only loop if the array is non-empty */ + if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') { + while (1) { + + /* read any JSON term */ + val = scan_once_unicode(s, pystr, idx, &next_idx); + if (val == NULL) + goto bail; + + if (PyList_Append(rval, val) == -1) + goto bail; + + Py_CLEAR(val); + idx = next_idx; + + /* skip whitespace between term and , */ + while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; + + /* bail if the array is closed or we didn't get the , delimiter */ + if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == ']') + break; + if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') { + raise_errmsg("Expecting ',' delimiter", pystr, idx); + goto bail; + } + idx++; + + /* skip whitespace after , */ + while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; + } + } + + /* verify that idx < end_idx, PyUnicode_READ(kind, str, idx) should be ']' */ + if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') { + raise_errmsg("Expecting value", pystr, end_idx); + goto bail; + } + *next_idx_ptr = idx + 1; + return rval; +bail: + Py_XDECREF(val); + Py_DECREF(rval); + return NULL; +} + +static PyObject * +_parse_constant(PyScannerObject *s, const char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { + /* Read a JSON constant. + constant is the constant string that was found + ("NaN", "Infinity", "-Infinity"). + idx is the index of the first character of the constant + *next_idx_ptr is a return-by-reference index to the first character after + the constant. + + Returns the result of parse_constant + */ + PyObject *cstr; + PyObject *rval; + /* constant is "NaN", "Infinity", or "-Infinity" */ + cstr = PyUnicode_InternFromString(constant); + if (cstr == NULL) + return NULL; + + /* rval = parse_constant(constant) */ rval = PyObject_CallOneArg(s->parse_constant, cstr); - idx += PyUnicode_GET_LENGTH(cstr); - Py_DECREF(cstr); - *next_idx_ptr = idx; - return rval; -} - -static PyObject * -_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) { - /* Read a JSON number from PyUnicode pystr. - idx is the index of the first character of the number - *next_idx_ptr is a return-by-reference index to the first character after - the number. - - Returns a new PyObject representation of that number: - PyLong, or PyFloat. - May return other types if parse_int or parse_float are set - */ + idx += PyUnicode_GET_LENGTH(cstr); + Py_DECREF(cstr); + *next_idx_ptr = idx; + return rval; +} + +static PyObject * +_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) { + /* Read a JSON number from PyUnicode pystr. + idx is the index of the first character of the number + *next_idx_ptr is a return-by-reference index to the first character after + the number. + + Returns a new PyObject representation of that number: + PyLong, or PyFloat. + May return other types if parse_int or parse_float are set + */ const void *str; - int kind; - Py_ssize_t end_idx; - Py_ssize_t idx = start; - int is_float = 0; - PyObject *rval; - PyObject *numstr = NULL; - PyObject *custom_func; - - if (PyUnicode_READY(pystr) == -1) - return NULL; - - str = PyUnicode_DATA(pystr); - kind = PyUnicode_KIND(pystr); - end_idx = PyUnicode_GET_LENGTH(pystr) - 1; - - /* read a sign if it's there, make sure it's not the end of the string */ - if (PyUnicode_READ(kind, str, idx) == '-') { - idx++; - if (idx > end_idx) { - raise_stop_iteration(start); - return NULL; - } - } - - /* read as many integer digits as we find as long as it doesn't start with 0 */ - if (PyUnicode_READ(kind, str, idx) >= '1' && PyUnicode_READ(kind, str, idx) <= '9') { - idx++; - while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++; - } - /* if it starts with 0 we only expect one integer digit */ - else if (PyUnicode_READ(kind, str, idx) == '0') { - idx++; - } - /* no integer digits, error */ - else { - raise_stop_iteration(start); - return NULL; - } - - /* if the next char is '.' followed by a digit then read all float digits */ - if (idx < end_idx && PyUnicode_READ(kind, str, idx) == '.' && PyUnicode_READ(kind, str, idx + 1) >= '0' && PyUnicode_READ(kind, str, idx + 1) <= '9') { - is_float = 1; - idx += 2; - while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++; - } - - /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */ - if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == 'e' || PyUnicode_READ(kind, str, idx) == 'E')) { - Py_ssize_t e_start = idx; - idx++; - - /* read an exponent sign if present */ - if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == '-' || PyUnicode_READ(kind, str, idx) == '+')) idx++; - - /* read all digits */ - while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++; - - /* if we got a digit, then parse as float. if not, backtrack */ - if (PyUnicode_READ(kind, str, idx - 1) >= '0' && PyUnicode_READ(kind, str, idx - 1) <= '9') { - is_float = 1; - } - else { - idx = e_start; - } - } - - if (is_float && s->parse_float != (PyObject *)&PyFloat_Type) - custom_func = s->parse_float; - else if (!is_float && s->parse_int != (PyObject *) &PyLong_Type) - custom_func = s->parse_int; - else - custom_func = NULL; - - if (custom_func) { - /* copy the section we determined to be a number */ - numstr = PyUnicode_FromKindAndData(kind, - (char*)str + kind * start, - idx - start); - if (numstr == NULL) - return NULL; + int kind; + Py_ssize_t end_idx; + Py_ssize_t idx = start; + int is_float = 0; + PyObject *rval; + PyObject *numstr = NULL; + PyObject *custom_func; + + if (PyUnicode_READY(pystr) == -1) + return NULL; + + str = PyUnicode_DATA(pystr); + kind = PyUnicode_KIND(pystr); + end_idx = PyUnicode_GET_LENGTH(pystr) - 1; + + /* read a sign if it's there, make sure it's not the end of the string */ + if (PyUnicode_READ(kind, str, idx) == '-') { + idx++; + if (idx > end_idx) { + raise_stop_iteration(start); + return NULL; + } + } + + /* read as many integer digits as we find as long as it doesn't start with 0 */ + if (PyUnicode_READ(kind, str, idx) >= '1' && PyUnicode_READ(kind, str, idx) <= '9') { + idx++; + while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++; + } + /* if it starts with 0 we only expect one integer digit */ + else if (PyUnicode_READ(kind, str, idx) == '0') { + idx++; + } + /* no integer digits, error */ + else { + raise_stop_iteration(start); + return NULL; + } + + /* if the next char is '.' followed by a digit then read all float digits */ + if (idx < end_idx && PyUnicode_READ(kind, str, idx) == '.' && PyUnicode_READ(kind, str, idx + 1) >= '0' && PyUnicode_READ(kind, str, idx + 1) <= '9') { + is_float = 1; + idx += 2; + while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++; + } + + /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */ + if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == 'e' || PyUnicode_READ(kind, str, idx) == 'E')) { + Py_ssize_t e_start = idx; + idx++; + + /* read an exponent sign if present */ + if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == '-' || PyUnicode_READ(kind, str, idx) == '+')) idx++; + + /* read all digits */ + while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++; + + /* if we got a digit, then parse as float. if not, backtrack */ + if (PyUnicode_READ(kind, str, idx - 1) >= '0' && PyUnicode_READ(kind, str, idx - 1) <= '9') { + is_float = 1; + } + else { + idx = e_start; + } + } + + if (is_float && s->parse_float != (PyObject *)&PyFloat_Type) + custom_func = s->parse_float; + else if (!is_float && s->parse_int != (PyObject *) &PyLong_Type) + custom_func = s->parse_int; + else + custom_func = NULL; + + if (custom_func) { + /* copy the section we determined to be a number */ + numstr = PyUnicode_FromKindAndData(kind, + (char*)str + kind * start, + idx - start); + if (numstr == NULL) + return NULL; rval = PyObject_CallOneArg(custom_func, numstr); - } - else { - Py_ssize_t i, n; - char *buf; - /* Straight conversion to ASCII, to avoid costly conversion of - decimal unicode digits (which cannot appear here) */ - n = idx - start; - numstr = PyBytes_FromStringAndSize(NULL, n); - if (numstr == NULL) - return NULL; - buf = PyBytes_AS_STRING(numstr); - for (i = 0; i < n; i++) { - buf[i] = (char) PyUnicode_READ(kind, str, i + start); - } - if (is_float) - rval = PyFloat_FromString(numstr); - else - rval = PyLong_FromString(buf, NULL, 10); - } - Py_DECREF(numstr); - *next_idx_ptr = idx; - return rval; -} - -static PyObject * -scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) -{ - /* Read one JSON term (of any kind) from PyUnicode pystr. - idx is the index of the first character of the term - *next_idx_ptr is a return-by-reference index to the first character after - the number. - - Returns a new PyObject representation of the term. - */ - PyObject *res; + } + else { + Py_ssize_t i, n; + char *buf; + /* Straight conversion to ASCII, to avoid costly conversion of + decimal unicode digits (which cannot appear here) */ + n = idx - start; + numstr = PyBytes_FromStringAndSize(NULL, n); + if (numstr == NULL) + return NULL; + buf = PyBytes_AS_STRING(numstr); + for (i = 0; i < n; i++) { + buf[i] = (char) PyUnicode_READ(kind, str, i + start); + } + if (is_float) + rval = PyFloat_FromString(numstr); + else + rval = PyLong_FromString(buf, NULL, 10); + } + Py_DECREF(numstr); + *next_idx_ptr = idx; + return rval; +} + +static PyObject * +scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) +{ + /* Read one JSON term (of any kind) from PyUnicode pystr. + idx is the index of the first character of the term + *next_idx_ptr is a return-by-reference index to the first character after + the number. + + Returns a new PyObject representation of the term. + */ + PyObject *res; const void *str; - int kind; - Py_ssize_t length; - - if (PyUnicode_READY(pystr) == -1) - return NULL; - - str = PyUnicode_DATA(pystr); - kind = PyUnicode_KIND(pystr); - length = PyUnicode_GET_LENGTH(pystr); - - if (idx < 0) { - PyErr_SetString(PyExc_ValueError, "idx cannot be negative"); - return NULL; - } - if (idx >= length) { - raise_stop_iteration(idx); - return NULL; - } - - switch (PyUnicode_READ(kind, str, idx)) { - case '"': - /* string */ - return scanstring_unicode(pystr, idx + 1, s->strict, next_idx_ptr); - case '{': - /* object */ - if (Py_EnterRecursiveCall(" while decoding a JSON object " - "from a unicode string")) - return NULL; - res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr); - Py_LeaveRecursiveCall(); - return res; - case '[': - /* array */ - if (Py_EnterRecursiveCall(" while decoding a JSON array " - "from a unicode string")) - return NULL; - res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr); - Py_LeaveRecursiveCall(); - return res; - case 'n': - /* null */ - if ((idx + 3 < length) && PyUnicode_READ(kind, str, idx + 1) == 'u' && PyUnicode_READ(kind, str, idx + 2) == 'l' && PyUnicode_READ(kind, str, idx + 3) == 'l') { - *next_idx_ptr = idx + 4; - Py_RETURN_NONE; - } - break; - case 't': - /* true */ - if ((idx + 3 < length) && PyUnicode_READ(kind, str, idx + 1) == 'r' && PyUnicode_READ(kind, str, idx + 2) == 'u' && PyUnicode_READ(kind, str, idx + 3) == 'e') { - *next_idx_ptr = idx + 4; - Py_RETURN_TRUE; - } - break; - case 'f': - /* false */ - if ((idx + 4 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' && - PyUnicode_READ(kind, str, idx + 2) == 'l' && - PyUnicode_READ(kind, str, idx + 3) == 's' && - PyUnicode_READ(kind, str, idx + 4) == 'e') { - *next_idx_ptr = idx + 5; - Py_RETURN_FALSE; - } - break; - case 'N': - /* NaN */ - if ((idx + 2 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' && - PyUnicode_READ(kind, str, idx + 2) == 'N') { - return _parse_constant(s, "NaN", idx, next_idx_ptr); - } - break; - case 'I': - /* Infinity */ - if ((idx + 7 < length) && PyUnicode_READ(kind, str, idx + 1) == 'n' && - PyUnicode_READ(kind, str, idx + 2) == 'f' && - PyUnicode_READ(kind, str, idx + 3) == 'i' && - PyUnicode_READ(kind, str, idx + 4) == 'n' && - PyUnicode_READ(kind, str, idx + 5) == 'i' && - PyUnicode_READ(kind, str, idx + 6) == 't' && - PyUnicode_READ(kind, str, idx + 7) == 'y') { - return _parse_constant(s, "Infinity", idx, next_idx_ptr); - } - break; - case '-': - /* -Infinity */ - if ((idx + 8 < length) && PyUnicode_READ(kind, str, idx + 1) == 'I' && - PyUnicode_READ(kind, str, idx + 2) == 'n' && - PyUnicode_READ(kind, str, idx + 3) == 'f' && - PyUnicode_READ(kind, str, idx + 4) == 'i' && - PyUnicode_READ(kind, str, idx + 5) == 'n' && - PyUnicode_READ(kind, str, idx + 6) == 'i' && - PyUnicode_READ(kind, str, idx + 7) == 't' && - PyUnicode_READ(kind, str, idx + 8) == 'y') { - return _parse_constant(s, "-Infinity", idx, next_idx_ptr); - } - break; - } - /* Didn't find a string, object, array, or named constant. Look for a number. */ - return _match_number_unicode(s, pystr, idx, next_idx_ptr); -} - -static PyObject * + int kind; + Py_ssize_t length; + + if (PyUnicode_READY(pystr) == -1) + return NULL; + + str = PyUnicode_DATA(pystr); + kind = PyUnicode_KIND(pystr); + length = PyUnicode_GET_LENGTH(pystr); + + if (idx < 0) { + PyErr_SetString(PyExc_ValueError, "idx cannot be negative"); + return NULL; + } + if (idx >= length) { + raise_stop_iteration(idx); + return NULL; + } + + switch (PyUnicode_READ(kind, str, idx)) { + case '"': + /* string */ + return scanstring_unicode(pystr, idx + 1, s->strict, next_idx_ptr); + case '{': + /* object */ + if (Py_EnterRecursiveCall(" while decoding a JSON object " + "from a unicode string")) + return NULL; + res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr); + Py_LeaveRecursiveCall(); + return res; + case '[': + /* array */ + if (Py_EnterRecursiveCall(" while decoding a JSON array " + "from a unicode string")) + return NULL; + res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr); + Py_LeaveRecursiveCall(); + return res; + case 'n': + /* null */ + if ((idx + 3 < length) && PyUnicode_READ(kind, str, idx + 1) == 'u' && PyUnicode_READ(kind, str, idx + 2) == 'l' && PyUnicode_READ(kind, str, idx + 3) == 'l') { + *next_idx_ptr = idx + 4; + Py_RETURN_NONE; + } + break; + case 't': + /* true */ + if ((idx + 3 < length) && PyUnicode_READ(kind, str, idx + 1) == 'r' && PyUnicode_READ(kind, str, idx + 2) == 'u' && PyUnicode_READ(kind, str, idx + 3) == 'e') { + *next_idx_ptr = idx + 4; + Py_RETURN_TRUE; + } + break; + case 'f': + /* false */ + if ((idx + 4 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' && + PyUnicode_READ(kind, str, idx + 2) == 'l' && + PyUnicode_READ(kind, str, idx + 3) == 's' && + PyUnicode_READ(kind, str, idx + 4) == 'e') { + *next_idx_ptr = idx + 5; + Py_RETURN_FALSE; + } + break; + case 'N': + /* NaN */ + if ((idx + 2 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' && + PyUnicode_READ(kind, str, idx + 2) == 'N') { + return _parse_constant(s, "NaN", idx, next_idx_ptr); + } + break; + case 'I': + /* Infinity */ + if ((idx + 7 < length) && PyUnicode_READ(kind, str, idx + 1) == 'n' && + PyUnicode_READ(kind, str, idx + 2) == 'f' && + PyUnicode_READ(kind, str, idx + 3) == 'i' && + PyUnicode_READ(kind, str, idx + 4) == 'n' && + PyUnicode_READ(kind, str, idx + 5) == 'i' && + PyUnicode_READ(kind, str, idx + 6) == 't' && + PyUnicode_READ(kind, str, idx + 7) == 'y') { + return _parse_constant(s, "Infinity", idx, next_idx_ptr); + } + break; + case '-': + /* -Infinity */ + if ((idx + 8 < length) && PyUnicode_READ(kind, str, idx + 1) == 'I' && + PyUnicode_READ(kind, str, idx + 2) == 'n' && + PyUnicode_READ(kind, str, idx + 3) == 'f' && + PyUnicode_READ(kind, str, idx + 4) == 'i' && + PyUnicode_READ(kind, str, idx + 5) == 'n' && + PyUnicode_READ(kind, str, idx + 6) == 'i' && + PyUnicode_READ(kind, str, idx + 7) == 't' && + PyUnicode_READ(kind, str, idx + 8) == 'y') { + return _parse_constant(s, "-Infinity", idx, next_idx_ptr); + } + break; + } + /* Didn't find a string, object, array, or named constant. Look for a number. */ + return _match_number_unicode(s, pystr, idx, next_idx_ptr); +} + +static PyObject * scanner_call(PyScannerObject *self, PyObject *args, PyObject *kwds) -{ - /* Python callable interface to scan_once_{str,unicode} */ - PyObject *pystr; - PyObject *rval; - Py_ssize_t idx; - Py_ssize_t next_idx = -1; - static char *kwlist[] = {"string", "idx", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx)) - return NULL; - - if (PyUnicode_Check(pystr)) { +{ + /* Python callable interface to scan_once_{str,unicode} */ + PyObject *pystr; + PyObject *rval; + Py_ssize_t idx; + Py_ssize_t next_idx = -1; + static char *kwlist[] = {"string", "idx", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx)) + return NULL; + + if (PyUnicode_Check(pystr)) { rval = scan_once_unicode(self, pystr, idx, &next_idx); - } - else { - PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); - return NULL; - } + } + else { + PyErr_Format(PyExc_TypeError, + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); + return NULL; + } PyDict_Clear(self->memo); - if (rval == NULL) - return NULL; - return _build_rval_index_tuple(rval, next_idx); -} - -static PyObject * -scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyScannerObject *s; - PyObject *ctx; - PyObject *strict; - static char *kwlist[] = {"context", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx)) - return NULL; - - s = (PyScannerObject *)type->tp_alloc(type, 0); - if (s == NULL) { - return NULL; - } - - s->memo = PyDict_New(); - if (s->memo == NULL) - goto bail; - - /* All of these will fail "gracefully" so we don't need to verify them */ - strict = PyObject_GetAttrString(ctx, "strict"); - if (strict == NULL) - goto bail; - s->strict = PyObject_IsTrue(strict); - Py_DECREF(strict); - if (s->strict < 0) - goto bail; - s->object_hook = PyObject_GetAttrString(ctx, "object_hook"); - if (s->object_hook == NULL) - goto bail; - s->object_pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook"); - if (s->object_pairs_hook == NULL) - goto bail; - s->parse_float = PyObject_GetAttrString(ctx, "parse_float"); - if (s->parse_float == NULL) - goto bail; - s->parse_int = PyObject_GetAttrString(ctx, "parse_int"); - if (s->parse_int == NULL) - goto bail; - s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant"); - if (s->parse_constant == NULL) - goto bail; - - return (PyObject *)s; - -bail: - Py_DECREF(s); - return NULL; -} - -PyDoc_STRVAR(scanner_doc, "JSON scanner object"); - + if (rval == NULL) + return NULL; + return _build_rval_index_tuple(rval, next_idx); +} + +static PyObject * +scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyScannerObject *s; + PyObject *ctx; + PyObject *strict; + static char *kwlist[] = {"context", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx)) + return NULL; + + s = (PyScannerObject *)type->tp_alloc(type, 0); + if (s == NULL) { + return NULL; + } + + s->memo = PyDict_New(); + if (s->memo == NULL) + goto bail; + + /* All of these will fail "gracefully" so we don't need to verify them */ + strict = PyObject_GetAttrString(ctx, "strict"); + if (strict == NULL) + goto bail; + s->strict = PyObject_IsTrue(strict); + Py_DECREF(strict); + if (s->strict < 0) + goto bail; + s->object_hook = PyObject_GetAttrString(ctx, "object_hook"); + if (s->object_hook == NULL) + goto bail; + s->object_pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook"); + if (s->object_pairs_hook == NULL) + goto bail; + s->parse_float = PyObject_GetAttrString(ctx, "parse_float"); + if (s->parse_float == NULL) + goto bail; + s->parse_int = PyObject_GetAttrString(ctx, "parse_int"); + if (s->parse_int == NULL) + goto bail; + s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant"); + if (s->parse_constant == NULL) + goto bail; + + return (PyObject *)s; + +bail: + Py_DECREF(s); + return NULL; +} + +PyDoc_STRVAR(scanner_doc, "JSON scanner object"); + static PyType_Slot PyScannerType_slots[] = { {Py_tp_doc, (void *)scanner_doc}, {Py_tp_dealloc, scanner_dealloc}, @@ -1219,8 +1219,8 @@ static PyType_Slot PyScannerType_slots[] = { {Py_tp_members, scanner_members}, {Py_tp_new, scanner_new}, {0, 0} -}; - +}; + static PyType_Spec PyScannerType_spec = { .name = "_json.Scanner", .basicsize = sizeof(PyScannerObject), @@ -1229,523 +1229,523 @@ static PyType_Spec PyScannerType_spec = { .slots = PyScannerType_slots, }; -static PyObject * -encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL}; - - PyEncoderObject *s; - PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; - PyObject *item_separator; - int sort_keys, skipkeys, allow_nan; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUppp:make_encoder", kwlist, - &markers, &defaultfn, &encoder, &indent, - &key_separator, &item_separator, - &sort_keys, &skipkeys, &allow_nan)) - return NULL; - - if (markers != Py_None && !PyDict_Check(markers)) { - PyErr_Format(PyExc_TypeError, - "make_encoder() argument 1 must be dict or None, " - "not %.200s", Py_TYPE(markers)->tp_name); - return NULL; - } - - s = (PyEncoderObject *)type->tp_alloc(type, 0); - if (s == NULL) - return NULL; - - s->markers = markers; - s->defaultfn = defaultfn; - s->encoder = encoder; - s->indent = indent; - s->key_separator = key_separator; - s->item_separator = item_separator; - s->sort_keys = sort_keys; - s->skipkeys = skipkeys; - s->allow_nan = allow_nan; - s->fast_encode = NULL; - if (PyCFunction_Check(s->encoder)) { - PyCFunction f = PyCFunction_GetFunction(s->encoder); - if (f == (PyCFunction)py_encode_basestring_ascii || - f == (PyCFunction)py_encode_basestring) { - s->fast_encode = f; - } - } - - Py_INCREF(s->markers); - Py_INCREF(s->defaultfn); - Py_INCREF(s->encoder); - Py_INCREF(s->indent); - Py_INCREF(s->key_separator); - Py_INCREF(s->item_separator); - return (PyObject *)s; -} - -static PyObject * +static PyObject * +encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL}; + + PyEncoderObject *s; + PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; + PyObject *item_separator; + int sort_keys, skipkeys, allow_nan; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUppp:make_encoder", kwlist, + &markers, &defaultfn, &encoder, &indent, + &key_separator, &item_separator, + &sort_keys, &skipkeys, &allow_nan)) + return NULL; + + if (markers != Py_None && !PyDict_Check(markers)) { + PyErr_Format(PyExc_TypeError, + "make_encoder() argument 1 must be dict or None, " + "not %.200s", Py_TYPE(markers)->tp_name); + return NULL; + } + + s = (PyEncoderObject *)type->tp_alloc(type, 0); + if (s == NULL) + return NULL; + + s->markers = markers; + s->defaultfn = defaultfn; + s->encoder = encoder; + s->indent = indent; + s->key_separator = key_separator; + s->item_separator = item_separator; + s->sort_keys = sort_keys; + s->skipkeys = skipkeys; + s->allow_nan = allow_nan; + s->fast_encode = NULL; + if (PyCFunction_Check(s->encoder)) { + PyCFunction f = PyCFunction_GetFunction(s->encoder); + if (f == (PyCFunction)py_encode_basestring_ascii || + f == (PyCFunction)py_encode_basestring) { + s->fast_encode = f; + } + } + + Py_INCREF(s->markers); + Py_INCREF(s->defaultfn); + Py_INCREF(s->encoder); + Py_INCREF(s->indent); + Py_INCREF(s->key_separator); + Py_INCREF(s->item_separator); + return (PyObject *)s; +} + +static PyObject * encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds) -{ - /* Python callable interface to encode_listencode_obj */ - static char *kwlist[] = {"obj", "_current_indent_level", NULL}; - PyObject *obj; - Py_ssize_t indent_level; - _PyAccu acc; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist, - &obj, &indent_level)) - return NULL; - if (_PyAccu_Init(&acc)) - return NULL; +{ + /* Python callable interface to encode_listencode_obj */ + static char *kwlist[] = {"obj", "_current_indent_level", NULL}; + PyObject *obj; + Py_ssize_t indent_level; + _PyAccu acc; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist, + &obj, &indent_level)) + return NULL; + if (_PyAccu_Init(&acc)) + return NULL; if (encoder_listencode_obj(self, &acc, obj, indent_level)) { - _PyAccu_Destroy(&acc); - return NULL; - } - return _PyAccu_FinishAsList(&acc); -} - -static PyObject * -_encoded_const(PyObject *obj) -{ - /* Return the JSON string representation of None, True, False */ - if (obj == Py_None) { - static PyObject *s_null = NULL; - if (s_null == NULL) { - s_null = PyUnicode_InternFromString("null"); - } - Py_XINCREF(s_null); - return s_null; - } - else if (obj == Py_True) { - static PyObject *s_true = NULL; - if (s_true == NULL) { - s_true = PyUnicode_InternFromString("true"); - } - Py_XINCREF(s_true); - return s_true; - } - else if (obj == Py_False) { - static PyObject *s_false = NULL; - if (s_false == NULL) { - s_false = PyUnicode_InternFromString("false"); - } - Py_XINCREF(s_false); - return s_false; - } - else { - PyErr_SetString(PyExc_ValueError, "not a const"); - return NULL; - } -} - -static PyObject * -encoder_encode_float(PyEncoderObject *s, PyObject *obj) -{ - /* Return the JSON representation of a PyFloat. */ - double i = PyFloat_AS_DOUBLE(obj); - if (!Py_IS_FINITE(i)) { - if (!s->allow_nan) { - PyErr_SetString( - PyExc_ValueError, - "Out of range float values are not JSON compliant" - ); - return NULL; - } - if (i > 0) { - return PyUnicode_FromString("Infinity"); - } - else if (i < 0) { - return PyUnicode_FromString("-Infinity"); - } - else { - return PyUnicode_FromString("NaN"); - } - } - return PyFloat_Type.tp_repr(obj); -} - -static PyObject * -encoder_encode_string(PyEncoderObject *s, PyObject *obj) -{ - /* Return the JSON representation of a string */ - PyObject *encoded; - - if (s->fast_encode) { - return s->fast_encode(NULL, obj); - } + _PyAccu_Destroy(&acc); + return NULL; + } + return _PyAccu_FinishAsList(&acc); +} + +static PyObject * +_encoded_const(PyObject *obj) +{ + /* Return the JSON string representation of None, True, False */ + if (obj == Py_None) { + static PyObject *s_null = NULL; + if (s_null == NULL) { + s_null = PyUnicode_InternFromString("null"); + } + Py_XINCREF(s_null); + return s_null; + } + else if (obj == Py_True) { + static PyObject *s_true = NULL; + if (s_true == NULL) { + s_true = PyUnicode_InternFromString("true"); + } + Py_XINCREF(s_true); + return s_true; + } + else if (obj == Py_False) { + static PyObject *s_false = NULL; + if (s_false == NULL) { + s_false = PyUnicode_InternFromString("false"); + } + Py_XINCREF(s_false); + return s_false; + } + else { + PyErr_SetString(PyExc_ValueError, "not a const"); + return NULL; + } +} + +static PyObject * +encoder_encode_float(PyEncoderObject *s, PyObject *obj) +{ + /* Return the JSON representation of a PyFloat. */ + double i = PyFloat_AS_DOUBLE(obj); + if (!Py_IS_FINITE(i)) { + if (!s->allow_nan) { + PyErr_SetString( + PyExc_ValueError, + "Out of range float values are not JSON compliant" + ); + return NULL; + } + if (i > 0) { + return PyUnicode_FromString("Infinity"); + } + else if (i < 0) { + return PyUnicode_FromString("-Infinity"); + } + else { + return PyUnicode_FromString("NaN"); + } + } + return PyFloat_Type.tp_repr(obj); +} + +static PyObject * +encoder_encode_string(PyEncoderObject *s, PyObject *obj) +{ + /* Return the JSON representation of a string */ + PyObject *encoded; + + if (s->fast_encode) { + return s->fast_encode(NULL, obj); + } encoded = PyObject_CallOneArg(s->encoder, obj); - if (encoded != NULL && !PyUnicode_Check(encoded)) { - PyErr_Format(PyExc_TypeError, - "encoder() must return a string, not %.80s", - Py_TYPE(encoded)->tp_name); - Py_DECREF(encoded); - return NULL; - } - return encoded; -} - -static int -_steal_accumulate(_PyAccu *acc, PyObject *stolen) -{ - /* Append stolen and then decrement its reference count */ - int rval = _PyAccu_Accumulate(acc, stolen); - Py_DECREF(stolen); - return rval; -} - -static int -encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, - PyObject *obj, Py_ssize_t indent_level) -{ - /* Encode Python object obj to a JSON term */ - PyObject *newobj; - int rv; - - if (obj == Py_None || obj == Py_True || obj == Py_False) { - PyObject *cstr = _encoded_const(obj); - if (cstr == NULL) - return -1; - return _steal_accumulate(acc, cstr); - } - else if (PyUnicode_Check(obj)) - { - PyObject *encoded = encoder_encode_string(s, obj); - if (encoded == NULL) - return -1; - return _steal_accumulate(acc, encoded); - } - else if (PyLong_Check(obj)) { + if (encoded != NULL && !PyUnicode_Check(encoded)) { + PyErr_Format(PyExc_TypeError, + "encoder() must return a string, not %.80s", + Py_TYPE(encoded)->tp_name); + Py_DECREF(encoded); + return NULL; + } + return encoded; +} + +static int +_steal_accumulate(_PyAccu *acc, PyObject *stolen) +{ + /* Append stolen and then decrement its reference count */ + int rval = _PyAccu_Accumulate(acc, stolen); + Py_DECREF(stolen); + return rval; +} + +static int +encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, + PyObject *obj, Py_ssize_t indent_level) +{ + /* Encode Python object obj to a JSON term */ + PyObject *newobj; + int rv; + + if (obj == Py_None || obj == Py_True || obj == Py_False) { + PyObject *cstr = _encoded_const(obj); + if (cstr == NULL) + return -1; + return _steal_accumulate(acc, cstr); + } + else if (PyUnicode_Check(obj)) + { + PyObject *encoded = encoder_encode_string(s, obj); + if (encoded == NULL) + return -1; + return _steal_accumulate(acc, encoded); + } + else if (PyLong_Check(obj)) { PyObject *encoded = PyLong_Type.tp_repr(obj); - if (encoded == NULL) - return -1; - return _steal_accumulate(acc, encoded); - } - else if (PyFloat_Check(obj)) { - PyObject *encoded = encoder_encode_float(s, obj); - if (encoded == NULL) - return -1; - return _steal_accumulate(acc, encoded); - } - else if (PyList_Check(obj) || PyTuple_Check(obj)) { - if (Py_EnterRecursiveCall(" while encoding a JSON object")) - return -1; - rv = encoder_listencode_list(s, acc, obj, indent_level); - Py_LeaveRecursiveCall(); - return rv; - } - else if (PyDict_Check(obj)) { - if (Py_EnterRecursiveCall(" while encoding a JSON object")) - return -1; - rv = encoder_listencode_dict(s, acc, obj, indent_level); - Py_LeaveRecursiveCall(); - return rv; - } - else { - PyObject *ident = NULL; - if (s->markers != Py_None) { - int has_key; - ident = PyLong_FromVoidPtr(obj); - if (ident == NULL) - return -1; - has_key = PyDict_Contains(s->markers, ident); - if (has_key) { - if (has_key != -1) - PyErr_SetString(PyExc_ValueError, "Circular reference detected"); - Py_DECREF(ident); - return -1; - } - if (PyDict_SetItem(s->markers, ident, obj)) { - Py_DECREF(ident); - return -1; - } - } + if (encoded == NULL) + return -1; + return _steal_accumulate(acc, encoded); + } + else if (PyFloat_Check(obj)) { + PyObject *encoded = encoder_encode_float(s, obj); + if (encoded == NULL) + return -1; + return _steal_accumulate(acc, encoded); + } + else if (PyList_Check(obj) || PyTuple_Check(obj)) { + if (Py_EnterRecursiveCall(" while encoding a JSON object")) + return -1; + rv = encoder_listencode_list(s, acc, obj, indent_level); + Py_LeaveRecursiveCall(); + return rv; + } + else if (PyDict_Check(obj)) { + if (Py_EnterRecursiveCall(" while encoding a JSON object")) + return -1; + rv = encoder_listencode_dict(s, acc, obj, indent_level); + Py_LeaveRecursiveCall(); + return rv; + } + else { + PyObject *ident = NULL; + if (s->markers != Py_None) { + int has_key; + ident = PyLong_FromVoidPtr(obj); + if (ident == NULL) + return -1; + has_key = PyDict_Contains(s->markers, ident); + if (has_key) { + if (has_key != -1) + PyErr_SetString(PyExc_ValueError, "Circular reference detected"); + Py_DECREF(ident); + return -1; + } + if (PyDict_SetItem(s->markers, ident, obj)) { + Py_DECREF(ident); + return -1; + } + } newobj = PyObject_CallOneArg(s->defaultfn, obj); - if (newobj == NULL) { - Py_XDECREF(ident); - return -1; - } - - if (Py_EnterRecursiveCall(" while encoding a JSON object")) { - Py_DECREF(newobj); - Py_XDECREF(ident); - return -1; - } - rv = encoder_listencode_obj(s, acc, newobj, indent_level); - Py_LeaveRecursiveCall(); - - Py_DECREF(newobj); - if (rv) { - Py_XDECREF(ident); - return -1; - } - if (ident != NULL) { - if (PyDict_DelItem(s->markers, ident)) { - Py_XDECREF(ident); - return -1; - } - Py_XDECREF(ident); - } - return rv; - } -} - -static int -encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, - PyObject *dct, Py_ssize_t indent_level) -{ - /* Encode Python dict dct a JSON term */ - static PyObject *open_dict = NULL; - static PyObject *close_dict = NULL; - static PyObject *empty_dict = NULL; - PyObject *kstr = NULL; - PyObject *ident = NULL; - PyObject *it = NULL; - PyObject *items; - PyObject *item = NULL; - Py_ssize_t idx; - - if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { - open_dict = PyUnicode_InternFromString("{"); - close_dict = PyUnicode_InternFromString("}"); - empty_dict = PyUnicode_InternFromString("{}"); - if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) - return -1; - } - if (PyDict_GET_SIZE(dct) == 0) /* Fast path */ - return _PyAccu_Accumulate(acc, empty_dict); - - if (s->markers != Py_None) { - int has_key; - ident = PyLong_FromVoidPtr(dct); - if (ident == NULL) - goto bail; - has_key = PyDict_Contains(s->markers, ident); - if (has_key) { - if (has_key != -1) - PyErr_SetString(PyExc_ValueError, "Circular reference detected"); - goto bail; - } - if (PyDict_SetItem(s->markers, ident, dct)) { - goto bail; - } - } - - if (_PyAccu_Accumulate(acc, open_dict)) - goto bail; - - if (s->indent != Py_None) { - /* TODO: DOES NOT RUN */ - indent_level += 1; - /* - newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) - separator = _item_separator + newline_indent - buf += newline_indent - */ - } - - items = PyMapping_Items(dct); - if (items == NULL) - goto bail; - if (s->sort_keys && PyList_Sort(items) < 0) { - Py_DECREF(items); - goto bail; - } - it = PyObject_GetIter(items); - Py_DECREF(items); - if (it == NULL) - goto bail; - idx = 0; - while ((item = PyIter_Next(it)) != NULL) { - PyObject *encoded, *key, *value; - if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { - PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); - goto bail; - } - key = PyTuple_GET_ITEM(item, 0); - if (PyUnicode_Check(key)) { - Py_INCREF(key); - kstr = key; - } - else if (PyFloat_Check(key)) { - kstr = encoder_encode_float(s, key); - if (kstr == NULL) - goto bail; - } - else if (key == Py_True || key == Py_False || key == Py_None) { - /* This must come before the PyLong_Check because - True and False are also 1 and 0.*/ - kstr = _encoded_const(key); - if (kstr == NULL) - goto bail; - } - else if (PyLong_Check(key)) { + if (newobj == NULL) { + Py_XDECREF(ident); + return -1; + } + + if (Py_EnterRecursiveCall(" while encoding a JSON object")) { + Py_DECREF(newobj); + Py_XDECREF(ident); + return -1; + } + rv = encoder_listencode_obj(s, acc, newobj, indent_level); + Py_LeaveRecursiveCall(); + + Py_DECREF(newobj); + if (rv) { + Py_XDECREF(ident); + return -1; + } + if (ident != NULL) { + if (PyDict_DelItem(s->markers, ident)) { + Py_XDECREF(ident); + return -1; + } + Py_XDECREF(ident); + } + return rv; + } +} + +static int +encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, + PyObject *dct, Py_ssize_t indent_level) +{ + /* Encode Python dict dct a JSON term */ + static PyObject *open_dict = NULL; + static PyObject *close_dict = NULL; + static PyObject *empty_dict = NULL; + PyObject *kstr = NULL; + PyObject *ident = NULL; + PyObject *it = NULL; + PyObject *items; + PyObject *item = NULL; + Py_ssize_t idx; + + if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { + open_dict = PyUnicode_InternFromString("{"); + close_dict = PyUnicode_InternFromString("}"); + empty_dict = PyUnicode_InternFromString("{}"); + if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) + return -1; + } + if (PyDict_GET_SIZE(dct) == 0) /* Fast path */ + return _PyAccu_Accumulate(acc, empty_dict); + + if (s->markers != Py_None) { + int has_key; + ident = PyLong_FromVoidPtr(dct); + if (ident == NULL) + goto bail; + has_key = PyDict_Contains(s->markers, ident); + if (has_key) { + if (has_key != -1) + PyErr_SetString(PyExc_ValueError, "Circular reference detected"); + goto bail; + } + if (PyDict_SetItem(s->markers, ident, dct)) { + goto bail; + } + } + + if (_PyAccu_Accumulate(acc, open_dict)) + goto bail; + + if (s->indent != Py_None) { + /* TODO: DOES NOT RUN */ + indent_level += 1; + /* + newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) + separator = _item_separator + newline_indent + buf += newline_indent + */ + } + + items = PyMapping_Items(dct); + if (items == NULL) + goto bail; + if (s->sort_keys && PyList_Sort(items) < 0) { + Py_DECREF(items); + goto bail; + } + it = PyObject_GetIter(items); + Py_DECREF(items); + if (it == NULL) + goto bail; + idx = 0; + while ((item = PyIter_Next(it)) != NULL) { + PyObject *encoded, *key, *value; + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { + PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); + goto bail; + } + key = PyTuple_GET_ITEM(item, 0); + if (PyUnicode_Check(key)) { + Py_INCREF(key); + kstr = key; + } + else if (PyFloat_Check(key)) { + kstr = encoder_encode_float(s, key); + if (kstr == NULL) + goto bail; + } + else if (key == Py_True || key == Py_False || key == Py_None) { + /* This must come before the PyLong_Check because + True and False are also 1 and 0.*/ + kstr = _encoded_const(key); + if (kstr == NULL) + goto bail; + } + else if (PyLong_Check(key)) { kstr = PyLong_Type.tp_repr(key); - if (kstr == NULL) { - goto bail; - } - } - else if (s->skipkeys) { - Py_DECREF(item); - continue; - } - else { - PyErr_Format(PyExc_TypeError, - "keys must be str, int, float, bool or None, " + if (kstr == NULL) { + goto bail; + } + } + else if (s->skipkeys) { + Py_DECREF(item); + continue; + } + else { + PyErr_Format(PyExc_TypeError, + "keys must be str, int, float, bool or None, " "not %.100s", Py_TYPE(key)->tp_name); - goto bail; - } - - if (idx) { - if (_PyAccu_Accumulate(acc, s->item_separator)) - goto bail; - } - - encoded = encoder_encode_string(s, kstr); - Py_CLEAR(kstr); - if (encoded == NULL) - goto bail; - if (_PyAccu_Accumulate(acc, encoded)) { - Py_DECREF(encoded); - goto bail; - } - Py_DECREF(encoded); - if (_PyAccu_Accumulate(acc, s->key_separator)) - goto bail; - - value = PyTuple_GET_ITEM(item, 1); - if (encoder_listencode_obj(s, acc, value, indent_level)) - goto bail; - idx += 1; - Py_DECREF(item); - } - if (PyErr_Occurred()) - goto bail; - Py_CLEAR(it); - - if (ident != NULL) { - if (PyDict_DelItem(s->markers, ident)) - goto bail; - Py_CLEAR(ident); - } - /* TODO DOES NOT RUN; dead code - if (s->indent != Py_None) { - indent_level -= 1; - - yield '\n' + (' ' * (_indent * _current_indent_level)) - }*/ - if (_PyAccu_Accumulate(acc, close_dict)) - goto bail; - return 0; - -bail: - Py_XDECREF(it); - Py_XDECREF(item); - Py_XDECREF(kstr); - Py_XDECREF(ident); - return -1; -} - - -static int -encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, - PyObject *seq, Py_ssize_t indent_level) -{ - /* Encode Python list seq to a JSON term */ - static PyObject *open_array = NULL; - static PyObject *close_array = NULL; - static PyObject *empty_array = NULL; - PyObject *ident = NULL; - PyObject *s_fast = NULL; - Py_ssize_t i; - - if (open_array == NULL || close_array == NULL || empty_array == NULL) { - open_array = PyUnicode_InternFromString("["); - close_array = PyUnicode_InternFromString("]"); - empty_array = PyUnicode_InternFromString("[]"); - if (open_array == NULL || close_array == NULL || empty_array == NULL) - return -1; - } - ident = NULL; - s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence"); - if (s_fast == NULL) - return -1; - if (PySequence_Fast_GET_SIZE(s_fast) == 0) { - Py_DECREF(s_fast); - return _PyAccu_Accumulate(acc, empty_array); - } - - if (s->markers != Py_None) { - int has_key; - ident = PyLong_FromVoidPtr(seq); - if (ident == NULL) - goto bail; - has_key = PyDict_Contains(s->markers, ident); - if (has_key) { - if (has_key != -1) - PyErr_SetString(PyExc_ValueError, "Circular reference detected"); - goto bail; - } - if (PyDict_SetItem(s->markers, ident, seq)) { - goto bail; - } - } - - if (_PyAccu_Accumulate(acc, open_array)) - goto bail; - if (s->indent != Py_None) { - /* TODO: DOES NOT RUN */ - indent_level += 1; - /* - newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) - separator = _item_separator + newline_indent - buf += newline_indent - */ - } - for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) { - PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i); - if (i) { - if (_PyAccu_Accumulate(acc, s->item_separator)) - goto bail; - } - if (encoder_listencode_obj(s, acc, obj, indent_level)) - goto bail; - } - if (ident != NULL) { - if (PyDict_DelItem(s->markers, ident)) - goto bail; - Py_CLEAR(ident); - } - - /* TODO: DOES NOT RUN - if (s->indent != Py_None) { - indent_level -= 1; - - yield '\n' + (' ' * (_indent * _current_indent_level)) - }*/ - if (_PyAccu_Accumulate(acc, close_array)) - goto bail; - Py_DECREF(s_fast); - return 0; - -bail: - Py_XDECREF(ident); - Py_DECREF(s_fast); - return -1; -} - -static void -encoder_dealloc(PyObject *self) -{ + goto bail; + } + + if (idx) { + if (_PyAccu_Accumulate(acc, s->item_separator)) + goto bail; + } + + encoded = encoder_encode_string(s, kstr); + Py_CLEAR(kstr); + if (encoded == NULL) + goto bail; + if (_PyAccu_Accumulate(acc, encoded)) { + Py_DECREF(encoded); + goto bail; + } + Py_DECREF(encoded); + if (_PyAccu_Accumulate(acc, s->key_separator)) + goto bail; + + value = PyTuple_GET_ITEM(item, 1); + if (encoder_listencode_obj(s, acc, value, indent_level)) + goto bail; + idx += 1; + Py_DECREF(item); + } + if (PyErr_Occurred()) + goto bail; + Py_CLEAR(it); + + if (ident != NULL) { + if (PyDict_DelItem(s->markers, ident)) + goto bail; + Py_CLEAR(ident); + } + /* TODO DOES NOT RUN; dead code + if (s->indent != Py_None) { + indent_level -= 1; + + yield '\n' + (' ' * (_indent * _current_indent_level)) + }*/ + if (_PyAccu_Accumulate(acc, close_dict)) + goto bail; + return 0; + +bail: + Py_XDECREF(it); + Py_XDECREF(item); + Py_XDECREF(kstr); + Py_XDECREF(ident); + return -1; +} + + +static int +encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, + PyObject *seq, Py_ssize_t indent_level) +{ + /* Encode Python list seq to a JSON term */ + static PyObject *open_array = NULL; + static PyObject *close_array = NULL; + static PyObject *empty_array = NULL; + PyObject *ident = NULL; + PyObject *s_fast = NULL; + Py_ssize_t i; + + if (open_array == NULL || close_array == NULL || empty_array == NULL) { + open_array = PyUnicode_InternFromString("["); + close_array = PyUnicode_InternFromString("]"); + empty_array = PyUnicode_InternFromString("[]"); + if (open_array == NULL || close_array == NULL || empty_array == NULL) + return -1; + } + ident = NULL; + s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence"); + if (s_fast == NULL) + return -1; + if (PySequence_Fast_GET_SIZE(s_fast) == 0) { + Py_DECREF(s_fast); + return _PyAccu_Accumulate(acc, empty_array); + } + + if (s->markers != Py_None) { + int has_key; + ident = PyLong_FromVoidPtr(seq); + if (ident == NULL) + goto bail; + has_key = PyDict_Contains(s->markers, ident); + if (has_key) { + if (has_key != -1) + PyErr_SetString(PyExc_ValueError, "Circular reference detected"); + goto bail; + } + if (PyDict_SetItem(s->markers, ident, seq)) { + goto bail; + } + } + + if (_PyAccu_Accumulate(acc, open_array)) + goto bail; + if (s->indent != Py_None) { + /* TODO: DOES NOT RUN */ + indent_level += 1; + /* + newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) + separator = _item_separator + newline_indent + buf += newline_indent + */ + } + for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) { + PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i); + if (i) { + if (_PyAccu_Accumulate(acc, s->item_separator)) + goto bail; + } + if (encoder_listencode_obj(s, acc, obj, indent_level)) + goto bail; + } + if (ident != NULL) { + if (PyDict_DelItem(s->markers, ident)) + goto bail; + Py_CLEAR(ident); + } + + /* TODO: DOES NOT RUN + if (s->indent != Py_None) { + indent_level -= 1; + + yield '\n' + (' ' * (_indent * _current_indent_level)) + }*/ + if (_PyAccu_Accumulate(acc, close_array)) + goto bail; + Py_DECREF(s_fast); + return 0; + +bail: + Py_XDECREF(ident); + Py_DECREF(s_fast); + return -1; +} + +static void +encoder_dealloc(PyObject *self) +{ PyTypeObject *tp = Py_TYPE(self); - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(self); + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(self); encoder_clear((PyEncoderObject *)self); tp->tp_free(self); Py_DECREF(tp); -} - -static int +} + +static int encoder_traverse(PyEncoderObject *self, visitproc visit, void *arg) -{ +{ Py_VISIT(Py_TYPE(self)); Py_VISIT(self->markers); Py_VISIT(self->defaultfn); @@ -1753,24 +1753,24 @@ encoder_traverse(PyEncoderObject *self, visitproc visit, void *arg) Py_VISIT(self->indent); Py_VISIT(self->key_separator); Py_VISIT(self->item_separator); - return 0; -} - -static int + return 0; +} + +static int encoder_clear(PyEncoderObject *self) -{ - /* Deallocate Encoder */ +{ + /* Deallocate Encoder */ Py_CLEAR(self->markers); Py_CLEAR(self->defaultfn); Py_CLEAR(self->encoder); Py_CLEAR(self->indent); Py_CLEAR(self->key_separator); Py_CLEAR(self->item_separator); - return 0; -} - -PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable"); - + return 0; +} + +PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable"); + static PyType_Slot PyEncoderType_slots[] = { {Py_tp_doc, (void *)encoder_doc}, {Py_tp_dealloc, encoder_dealloc}, @@ -1780,8 +1780,8 @@ static PyType_Slot PyEncoderType_slots[] = { {Py_tp_members, encoder_members}, {Py_tp_new, encoder_new}, {0, 0} -}; - +}; + static PyType_Spec PyEncoderType_spec = { .name = "_json.Encoder", .basicsize = sizeof(PyEncoderObject), @@ -1790,25 +1790,25 @@ static PyType_Spec PyEncoderType_spec = { .slots = PyEncoderType_slots }; -static PyMethodDef speedups_methods[] = { - {"encode_basestring_ascii", - (PyCFunction)py_encode_basestring_ascii, - METH_O, - pydoc_encode_basestring_ascii}, - {"encode_basestring", - (PyCFunction)py_encode_basestring, - METH_O, - pydoc_encode_basestring}, - {"scanstring", - (PyCFunction)py_scanstring, - METH_VARARGS, - pydoc_scanstring}, - {NULL, NULL, 0, NULL} -}; - -PyDoc_STRVAR(module_doc, -"json speedups\n"); - +static PyMethodDef speedups_methods[] = { + {"encode_basestring_ascii", + (PyCFunction)py_encode_basestring_ascii, + METH_O, + pydoc_encode_basestring_ascii}, + {"encode_basestring", + (PyCFunction)py_encode_basestring, + METH_O, + pydoc_encode_basestring}, + {"scanstring", + (PyCFunction)py_scanstring, + METH_VARARGS, + pydoc_scanstring}, + {NULL, NULL, 0, NULL} +}; + +PyDoc_STRVAR(module_doc, +"json speedups\n"); + static int _json_exec(PyObject *module) { @@ -1866,20 +1866,20 @@ static PyModuleDef_Slot _json_slots[] = { {0, NULL} }; -static struct PyModuleDef jsonmodule = { - PyModuleDef_HEAD_INIT, - "_json", - module_doc, +static struct PyModuleDef jsonmodule = { + PyModuleDef_HEAD_INIT, + "_json", + module_doc, sizeof(_jsonmodulestate), - speedups_methods, + speedups_methods, _json_slots, _jsonmodule_traverse, _jsonmodule_clear, _jsonmodule_free, -}; - -PyMODINIT_FUNC -PyInit__json(void) -{ +}; + +PyMODINIT_FUNC +PyInit__json(void) +{ return PyModuleDef_Init(&jsonmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/_localemodule.c b/contrib/tools/python3/src/Modules/_localemodule.c index 2e353bba00b..1b933069da8 100644 --- a/contrib/tools/python3/src/Modules/_localemodule.c +++ b/contrib/tools/python3/src/Modules/_localemodule.c @@ -1,50 +1,50 @@ -/*********************************************************** -Copyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies. - -This software comes with no warranty. Use at your own risk. - -******************************************************************/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" +/*********************************************************** +Copyright (C) 1997, 2002, 2003, 2007, 2008 Martin von Loewis + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies. + +This software comes with no warranty. Use at your own risk. + +******************************************************************/ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include "pycore_fileutils.h" - -#include -#include -#include -#include - -#ifdef HAVE_ERRNO_H -#include -#endif - -#ifdef HAVE_LANGINFO_H -#include -#endif - -#ifdef HAVE_LIBINTL_H -#include -#endif - -#ifdef HAVE_WCHAR_H -#include -#endif - -#if defined(MS_WINDOWS) -#define WIN32_LEAN_AND_MEAN -#include -#endif - -PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); - + +#include +#include +#include +#include + +#ifdef HAVE_ERRNO_H +#include +#endif + +#ifdef HAVE_LANGINFO_H +#include +#endif + +#ifdef HAVE_LIBINTL_H +#include +#endif + +#ifdef HAVE_WCHAR_H +#include +#endif + +#if defined(MS_WINDOWS) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); + typedef struct _locale_state { PyObject *Error; } _locale_state; - + static inline _locale_state* get_locale_state(PyObject *m) { @@ -53,752 +53,752 @@ get_locale_state(PyObject *m) return (_locale_state *)state; } -/* support functions for formatting floating point numbers */ - -PyDoc_STRVAR(setlocale__doc__, -"(integer,string=None) -> string. Activates/queries locale processing."); - -/* the grouping is terminated by either 0 or CHAR_MAX */ -static PyObject* -copy_grouping(const char* s) -{ - int i; - PyObject *result, *val = NULL; - - if (s[0] == '\0') { - /* empty string: no grouping at all */ - return PyList_New(0); - } - - for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++) - ; /* nothing */ - - result = PyList_New(i+1); - if (!result) - return NULL; - - i = -1; - do { - i++; - val = PyLong_FromLong(s[i]); - if (val == NULL) { - Py_DECREF(result); - return NULL; - } - PyList_SET_ITEM(result, i, val); - } while (s[i] != '\0' && s[i] != CHAR_MAX); - - return result; -} - -static PyObject* -PyLocale_setlocale(PyObject* self, PyObject* args) -{ - int category; - char *locale = NULL, *result; - PyObject *result_object; - - if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale)) - return NULL; - -#if defined(MS_WINDOWS) - if (category < LC_MIN || category > LC_MAX) - { +/* support functions for formatting floating point numbers */ + +PyDoc_STRVAR(setlocale__doc__, +"(integer,string=None) -> string. Activates/queries locale processing."); + +/* the grouping is terminated by either 0 or CHAR_MAX */ +static PyObject* +copy_grouping(const char* s) +{ + int i; + PyObject *result, *val = NULL; + + if (s[0] == '\0') { + /* empty string: no grouping at all */ + return PyList_New(0); + } + + for (i = 0; s[i] != '\0' && s[i] != CHAR_MAX; i++) + ; /* nothing */ + + result = PyList_New(i+1); + if (!result) + return NULL; + + i = -1; + do { + i++; + val = PyLong_FromLong(s[i]); + if (val == NULL) { + Py_DECREF(result); + return NULL; + } + PyList_SET_ITEM(result, i, val); + } while (s[i] != '\0' && s[i] != CHAR_MAX); + + return result; +} + +static PyObject* +PyLocale_setlocale(PyObject* self, PyObject* args) +{ + int category; + char *locale = NULL, *result; + PyObject *result_object; + + if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale)) + return NULL; + +#if defined(MS_WINDOWS) + if (category < LC_MIN || category > LC_MAX) + { PyErr_SetString(get_locale_state(self)->Error, "invalid locale category"); - return NULL; - } -#endif - - if (locale) { - /* set locale */ - result = setlocale(category, locale); - if (!result) { - /* operation failed, no setting was changed */ + return NULL; + } +#endif + + if (locale) { + /* set locale */ + result = setlocale(category, locale); + if (!result) { + /* operation failed, no setting was changed */ PyErr_SetString(get_locale_state(self)->Error, "unsupported locale setting"); - return NULL; - } - result_object = PyUnicode_DecodeLocale(result, NULL); - if (!result_object) - return NULL; - } else { - /* get locale */ - result = setlocale(category, NULL); - if (!result) { + return NULL; + } + result_object = PyUnicode_DecodeLocale(result, NULL); + if (!result_object) + return NULL; + } else { + /* get locale */ + result = setlocale(category, NULL); + if (!result) { PyErr_SetString(get_locale_state(self)->Error, "locale query failed"); - return NULL; - } - result_object = PyUnicode_DecodeLocale(result, NULL); - } - return result_object; -} - -static int -locale_is_ascii(const char *str) -{ - return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127); -} - -static int -locale_decode_monetary(PyObject *dict, struct lconv *lc) -{ + return NULL; + } + result_object = PyUnicode_DecodeLocale(result, NULL); + } + return result_object; +} + +static int +locale_is_ascii(const char *str) +{ + return (strlen(str) == 1 && ((unsigned char)str[0]) <= 127); +} + +static int +locale_decode_monetary(PyObject *dict, struct lconv *lc) +{ #ifndef MS_WINDOWS - int change_locale; - change_locale = (!locale_is_ascii(lc->int_curr_symbol) - || !locale_is_ascii(lc->currency_symbol) - || !locale_is_ascii(lc->mon_decimal_point) - || !locale_is_ascii(lc->mon_thousands_sep)); - - /* Keep a copy of the LC_CTYPE locale */ - char *oldloc = NULL, *loc = NULL; - if (change_locale) { - oldloc = setlocale(LC_CTYPE, NULL); - if (!oldloc) { - PyErr_SetString(PyExc_RuntimeWarning, - "failed to get LC_CTYPE locale"); - return -1; - } - - oldloc = _PyMem_Strdup(oldloc); - if (!oldloc) { - PyErr_NoMemory(); - return -1; - } - - loc = setlocale(LC_MONETARY, NULL); - if (loc != NULL && strcmp(loc, oldloc) == 0) { - loc = NULL; - } - - if (loc != NULL) { - /* Only set the locale temporarily the LC_CTYPE locale - to the LC_MONETARY locale if the two locales are different and - at least one string is non-ASCII. */ - setlocale(LC_CTYPE, loc); - } - } - + int change_locale; + change_locale = (!locale_is_ascii(lc->int_curr_symbol) + || !locale_is_ascii(lc->currency_symbol) + || !locale_is_ascii(lc->mon_decimal_point) + || !locale_is_ascii(lc->mon_thousands_sep)); + + /* Keep a copy of the LC_CTYPE locale */ + char *oldloc = NULL, *loc = NULL; + if (change_locale) { + oldloc = setlocale(LC_CTYPE, NULL); + if (!oldloc) { + PyErr_SetString(PyExc_RuntimeWarning, + "failed to get LC_CTYPE locale"); + return -1; + } + + oldloc = _PyMem_Strdup(oldloc); + if (!oldloc) { + PyErr_NoMemory(); + return -1; + } + + loc = setlocale(LC_MONETARY, NULL); + if (loc != NULL && strcmp(loc, oldloc) == 0) { + loc = NULL; + } + + if (loc != NULL) { + /* Only set the locale temporarily the LC_CTYPE locale + to the LC_MONETARY locale if the two locales are different and + at least one string is non-ASCII. */ + setlocale(LC_CTYPE, loc); + } + } + #define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) #else /* MS_WINDOWS */ /* Use _W_* fields of Windows struct lconv */ #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1) #endif /* MS_WINDOWS */ - int res = -1; - -#define RESULT_STRING(ATTR) \ - do { \ - PyObject *obj; \ + int res = -1; + +#define RESULT_STRING(ATTR) \ + do { \ + PyObject *obj; \ obj = GET_LOCALE_STRING(ATTR); \ - if (obj == NULL) { \ - goto done; \ - } \ - if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \ - Py_DECREF(obj); \ - goto done; \ - } \ - Py_DECREF(obj); \ - } while (0) - - RESULT_STRING(int_curr_symbol); - RESULT_STRING(currency_symbol); - RESULT_STRING(mon_decimal_point); - RESULT_STRING(mon_thousands_sep); -#undef RESULT_STRING + if (obj == NULL) { \ + goto done; \ + } \ + if (PyDict_SetItemString(dict, Py_STRINGIFY(ATTR), obj) < 0) { \ + Py_DECREF(obj); \ + goto done; \ + } \ + Py_DECREF(obj); \ + } while (0) + + RESULT_STRING(int_curr_symbol); + RESULT_STRING(currency_symbol); + RESULT_STRING(mon_decimal_point); + RESULT_STRING(mon_thousands_sep); +#undef RESULT_STRING #undef GET_LOCALE_STRING - - res = 0; - -done: + + res = 0; + +done: #ifndef MS_WINDOWS - if (loc != NULL) { - setlocale(LC_CTYPE, oldloc); - } - PyMem_Free(oldloc); -#endif - return res; -} - -PyDoc_STRVAR(localeconv__doc__, -"() -> dict. Returns numeric and monetary locale-specific parameters."); - -static PyObject* + if (loc != NULL) { + setlocale(LC_CTYPE, oldloc); + } + PyMem_Free(oldloc); +#endif + return res; +} + +PyDoc_STRVAR(localeconv__doc__, +"() -> dict. Returns numeric and monetary locale-specific parameters."); + +static PyObject* PyLocale_localeconv(PyObject* self, PyObject *Py_UNUSED(ignored)) -{ - PyObject* result; +{ + PyObject* result; struct lconv *lc; - PyObject *x; - - result = PyDict_New(); - if (!result) { - return NULL; - } - - /* if LC_NUMERIC is different in the C library, use saved value */ + PyObject *x; + + result = PyDict_New(); + if (!result) { + return NULL; + } + + /* if LC_NUMERIC is different in the C library, use saved value */ lc = localeconv(); - - /* hopefully, the localeconv result survives the C library calls - involved herein */ - -#define RESULT(key, obj)\ - do { \ - if (obj == NULL) \ - goto failed; \ - if (PyDict_SetItemString(result, key, obj) < 0) { \ - Py_DECREF(obj); \ - goto failed; \ - } \ - Py_DECREF(obj); \ - } while (0) - + + /* hopefully, the localeconv result survives the C library calls + involved herein */ + +#define RESULT(key, obj)\ + do { \ + if (obj == NULL) \ + goto failed; \ + if (PyDict_SetItemString(result, key, obj) < 0) { \ + Py_DECREF(obj); \ + goto failed; \ + } \ + Py_DECREF(obj); \ + } while (0) + #ifdef MS_WINDOWS /* Use _W_* fields of Windows struct lconv */ #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1) #else #define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL) #endif -#define RESULT_STRING(s)\ - do { \ +#define RESULT_STRING(s)\ + do { \ x = GET_LOCALE_STRING(s); \ - RESULT(#s, x); \ - } while (0) - -#define RESULT_INT(i)\ - do { \ + RESULT(#s, x); \ + } while (0) + +#define RESULT_INT(i)\ + do { \ x = PyLong_FromLong(lc->i); \ - RESULT(#i, x); \ - } while (0) - - /* Monetary information: LC_MONETARY encoding */ + RESULT(#i, x); \ + } while (0) + + /* Monetary information: LC_MONETARY encoding */ if (locale_decode_monetary(result, lc) < 0) { - goto failed; - } + goto failed; + } x = copy_grouping(lc->mon_grouping); - RESULT("mon_grouping", x); - - RESULT_STRING(positive_sign); - RESULT_STRING(negative_sign); - RESULT_INT(int_frac_digits); - RESULT_INT(frac_digits); - RESULT_INT(p_cs_precedes); - RESULT_INT(p_sep_by_space); - RESULT_INT(n_cs_precedes); - RESULT_INT(n_sep_by_space); - RESULT_INT(p_sign_posn); - RESULT_INT(n_sign_posn); - - /* Numeric information: LC_NUMERIC encoding */ + RESULT("mon_grouping", x); + + RESULT_STRING(positive_sign); + RESULT_STRING(negative_sign); + RESULT_INT(int_frac_digits); + RESULT_INT(frac_digits); + RESULT_INT(p_cs_precedes); + RESULT_INT(p_sep_by_space); + RESULT_INT(n_cs_precedes); + RESULT_INT(n_sep_by_space); + RESULT_INT(p_sign_posn); + RESULT_INT(n_sign_posn); + + /* Numeric information: LC_NUMERIC encoding */ PyObject *decimal_point = NULL, *thousands_sep = NULL; if (_Py_GetLocaleconvNumeric(lc, &decimal_point, &thousands_sep) < 0) { Py_XDECREF(decimal_point); Py_XDECREF(thousands_sep); - goto failed; - } - - if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) { - Py_DECREF(decimal_point); - Py_DECREF(thousands_sep); - goto failed; - } - Py_DECREF(decimal_point); - - if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) { - Py_DECREF(thousands_sep); - goto failed; - } - Py_DECREF(thousands_sep); - + goto failed; + } + + if (PyDict_SetItemString(result, "decimal_point", decimal_point) < 0) { + Py_DECREF(decimal_point); + Py_DECREF(thousands_sep); + goto failed; + } + Py_DECREF(decimal_point); + + if (PyDict_SetItemString(result, "thousands_sep", thousands_sep) < 0) { + Py_DECREF(thousands_sep); + goto failed; + } + Py_DECREF(thousands_sep); + x = copy_grouping(lc->grouping); - RESULT("grouping", x); - - return result; - - failed: - Py_DECREF(result); - return NULL; - -#undef RESULT -#undef RESULT_STRING -#undef RESULT_INT + RESULT("grouping", x); + + return result; + + failed: + Py_DECREF(result); + return NULL; + +#undef RESULT +#undef RESULT_STRING +#undef RESULT_INT #undef GET_LOCALE_STRING -} - -#if defined(HAVE_WCSCOLL) -PyDoc_STRVAR(strcoll__doc__, -"string,string -> int. Compares two strings according to the locale."); - -static PyObject* -PyLocale_strcoll(PyObject* self, PyObject* args) -{ - PyObject *os1, *os2, *result = NULL; - wchar_t *ws1 = NULL, *ws2 = NULL; - - if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2)) - return NULL; - /* Convert the unicode strings to wchar[]. */ - ws1 = PyUnicode_AsWideCharString(os1, NULL); - if (ws1 == NULL) - goto done; - ws2 = PyUnicode_AsWideCharString(os2, NULL); - if (ws2 == NULL) - goto done; - /* Collate the strings. */ - result = PyLong_FromLong(wcscoll(ws1, ws2)); - done: - /* Deallocate everything. */ - if (ws1) PyMem_FREE(ws1); - if (ws2) PyMem_FREE(ws2); - return result; -} -#endif - -#ifdef HAVE_WCSXFRM -PyDoc_STRVAR(strxfrm__doc__, -"strxfrm(string) -> string.\n\ -\n\ -Return a string that can be used as a key for locale-aware comparisons."); - -static PyObject* -PyLocale_strxfrm(PyObject* self, PyObject* args) -{ - PyObject *str; - Py_ssize_t n1; - wchar_t *s = NULL, *buf = NULL; - size_t n2; - PyObject *result = NULL; - - if (!PyArg_ParseTuple(args, "U:strxfrm", &str)) - return NULL; - - s = PyUnicode_AsWideCharString(str, &n1); - if (s == NULL) - goto exit; - if (wcslen(s) != (size_t)n1) { - PyErr_SetString(PyExc_ValueError, - "embedded null character"); - goto exit; - } - - /* assume no change in size, first */ - n1 = n1 + 1; - buf = PyMem_New(wchar_t, n1); - if (!buf) { - PyErr_NoMemory(); - goto exit; - } - errno = 0; - n2 = wcsxfrm(buf, s, n1); - if (errno && errno != ERANGE) { - PyErr_SetFromErrno(PyExc_OSError); - goto exit; - } - if (n2 >= (size_t)n1) { - /* more space needed */ - wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t)); - if (!new_buf) { - PyErr_NoMemory(); - goto exit; - } - buf = new_buf; - errno = 0; - n2 = wcsxfrm(buf, s, n2+1); - if (errno) { - PyErr_SetFromErrno(PyExc_OSError); - goto exit; - } - } - result = PyUnicode_FromWideChar(buf, n2); -exit: - PyMem_Free(buf); - PyMem_Free(s); - return result; -} -#endif - -#if defined(MS_WINDOWS) -static PyObject* +} + +#if defined(HAVE_WCSCOLL) +PyDoc_STRVAR(strcoll__doc__, +"string,string -> int. Compares two strings according to the locale."); + +static PyObject* +PyLocale_strcoll(PyObject* self, PyObject* args) +{ + PyObject *os1, *os2, *result = NULL; + wchar_t *ws1 = NULL, *ws2 = NULL; + + if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2)) + return NULL; + /* Convert the unicode strings to wchar[]. */ + ws1 = PyUnicode_AsWideCharString(os1, NULL); + if (ws1 == NULL) + goto done; + ws2 = PyUnicode_AsWideCharString(os2, NULL); + if (ws2 == NULL) + goto done; + /* Collate the strings. */ + result = PyLong_FromLong(wcscoll(ws1, ws2)); + done: + /* Deallocate everything. */ + if (ws1) PyMem_FREE(ws1); + if (ws2) PyMem_FREE(ws2); + return result; +} +#endif + +#ifdef HAVE_WCSXFRM +PyDoc_STRVAR(strxfrm__doc__, +"strxfrm(string) -> string.\n\ +\n\ +Return a string that can be used as a key for locale-aware comparisons."); + +static PyObject* +PyLocale_strxfrm(PyObject* self, PyObject* args) +{ + PyObject *str; + Py_ssize_t n1; + wchar_t *s = NULL, *buf = NULL; + size_t n2; + PyObject *result = NULL; + + if (!PyArg_ParseTuple(args, "U:strxfrm", &str)) + return NULL; + + s = PyUnicode_AsWideCharString(str, &n1); + if (s == NULL) + goto exit; + if (wcslen(s) != (size_t)n1) { + PyErr_SetString(PyExc_ValueError, + "embedded null character"); + goto exit; + } + + /* assume no change in size, first */ + n1 = n1 + 1; + buf = PyMem_New(wchar_t, n1); + if (!buf) { + PyErr_NoMemory(); + goto exit; + } + errno = 0; + n2 = wcsxfrm(buf, s, n1); + if (errno && errno != ERANGE) { + PyErr_SetFromErrno(PyExc_OSError); + goto exit; + } + if (n2 >= (size_t)n1) { + /* more space needed */ + wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t)); + if (!new_buf) { + PyErr_NoMemory(); + goto exit; + } + buf = new_buf; + errno = 0; + n2 = wcsxfrm(buf, s, n2+1); + if (errno) { + PyErr_SetFromErrno(PyExc_OSError); + goto exit; + } + } + result = PyUnicode_FromWideChar(buf, n2); +exit: + PyMem_Free(buf); + PyMem_Free(s); + return result; +} +#endif + +#if defined(MS_WINDOWS) +static PyObject* PyLocale_getdefaultlocale(PyObject* self, PyObject *Py_UNUSED(ignored)) -{ +{ char encoding[20]; - char locale[100]; - + char locale[100]; + PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP()); - - if (GetLocaleInfo(LOCALE_USER_DEFAULT, - LOCALE_SISO639LANGNAME, - locale, sizeof(locale))) { - Py_ssize_t i = strlen(locale); - locale[i++] = '_'; - if (GetLocaleInfo(LOCALE_USER_DEFAULT, - LOCALE_SISO3166CTRYNAME, - locale+i, (int)(sizeof(locale)-i))) - return Py_BuildValue("ss", locale, encoding); - } - - /* If we end up here, this windows version didn't know about - ISO639/ISO3166 names (it's probably Windows 95). Return the - Windows language identifier instead (a hexadecimal number) */ - - locale[0] = '0'; - locale[1] = 'x'; - if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE, - locale+2, sizeof(locale)-2)) { - return Py_BuildValue("ss", locale, encoding); - } - - /* cannot determine the language code (very unlikely) */ - Py_INCREF(Py_None); - return Py_BuildValue("Os", Py_None, encoding); -} -#endif - -#ifdef HAVE_LANGINFO_H -#define LANGINFO(X) {#X, X} -static struct langinfo_constant{ - char* name; - int value; -} langinfo_constants[] = -{ - /* These constants should exist on any langinfo implementation */ - LANGINFO(DAY_1), - LANGINFO(DAY_2), - LANGINFO(DAY_3), - LANGINFO(DAY_4), - LANGINFO(DAY_5), - LANGINFO(DAY_6), - LANGINFO(DAY_7), - - LANGINFO(ABDAY_1), - LANGINFO(ABDAY_2), - LANGINFO(ABDAY_3), - LANGINFO(ABDAY_4), - LANGINFO(ABDAY_5), - LANGINFO(ABDAY_6), - LANGINFO(ABDAY_7), - - LANGINFO(MON_1), - LANGINFO(MON_2), - LANGINFO(MON_3), - LANGINFO(MON_4), - LANGINFO(MON_5), - LANGINFO(MON_6), - LANGINFO(MON_7), - LANGINFO(MON_8), - LANGINFO(MON_9), - LANGINFO(MON_10), - LANGINFO(MON_11), - LANGINFO(MON_12), - - LANGINFO(ABMON_1), - LANGINFO(ABMON_2), - LANGINFO(ABMON_3), - LANGINFO(ABMON_4), - LANGINFO(ABMON_5), - LANGINFO(ABMON_6), - LANGINFO(ABMON_7), - LANGINFO(ABMON_8), - LANGINFO(ABMON_9), - LANGINFO(ABMON_10), - LANGINFO(ABMON_11), - LANGINFO(ABMON_12), - -#ifdef RADIXCHAR - /* The following are not available with glibc 2.0 */ - LANGINFO(RADIXCHAR), - LANGINFO(THOUSEP), - /* YESSTR and NOSTR are deprecated in glibc, since they are - a special case of message translation, which should be rather - done using gettext. So we don't expose it to Python in the - first place. - LANGINFO(YESSTR), - LANGINFO(NOSTR), - */ - LANGINFO(CRNCYSTR), -#endif - - LANGINFO(D_T_FMT), - LANGINFO(D_FMT), - LANGINFO(T_FMT), - LANGINFO(AM_STR), - LANGINFO(PM_STR), - - /* The following constants are available only with XPG4, but... - AIX 3.2. only has CODESET. - OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have - a few of the others. - Solution: ifdef-test them all. */ -#ifdef CODESET - LANGINFO(CODESET), -#endif -#ifdef T_FMT_AMPM - LANGINFO(T_FMT_AMPM), -#endif -#ifdef ERA - LANGINFO(ERA), -#endif -#ifdef ERA_D_FMT - LANGINFO(ERA_D_FMT), -#endif -#ifdef ERA_D_T_FMT - LANGINFO(ERA_D_T_FMT), -#endif -#ifdef ERA_T_FMT - LANGINFO(ERA_T_FMT), -#endif -#ifdef ALT_DIGITS - LANGINFO(ALT_DIGITS), -#endif -#ifdef YESEXPR - LANGINFO(YESEXPR), -#endif -#ifdef NOEXPR - LANGINFO(NOEXPR), -#endif -#ifdef _DATE_FMT - /* This is not available in all glibc versions that have CODESET. */ - LANGINFO(_DATE_FMT), -#endif - {0, 0} -}; - -PyDoc_STRVAR(nl_langinfo__doc__, -"nl_langinfo(key) -> string\n" -"Return the value for the locale information associated with key."); - -static PyObject* -PyLocale_nl_langinfo(PyObject* self, PyObject* args) -{ - int item, i; - if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item)) - return NULL; - /* Check whether this is a supported constant. GNU libc sometimes - returns numeric values in the char* return value, which would - crash PyUnicode_FromString. */ - for (i = 0; langinfo_constants[i].name; i++) - if (langinfo_constants[i].value == item) { - /* Check NULL as a workaround for GNU libc's returning NULL - instead of an empty string for nl_langinfo(ERA). */ - const char *result = nl_langinfo(item); - result = result != NULL ? result : ""; - return PyUnicode_DecodeLocale(result, NULL); - } - PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant"); - return NULL; -} -#endif /* HAVE_LANGINFO_H */ - -#ifdef HAVE_LIBINTL_H - -PyDoc_STRVAR(gettext__doc__, -"gettext(msg) -> string\n" -"Return translation of msg."); - -static PyObject* -PyIntl_gettext(PyObject* self, PyObject *args) -{ - char *in; - if (!PyArg_ParseTuple(args, "s", &in)) - return 0; - return PyUnicode_DecodeLocale(gettext(in), NULL); -} - -PyDoc_STRVAR(dgettext__doc__, -"dgettext(domain, msg) -> string\n" -"Return translation of msg in domain."); - -static PyObject* -PyIntl_dgettext(PyObject* self, PyObject *args) -{ - char *domain, *in; - if (!PyArg_ParseTuple(args, "zs", &domain, &in)) - return 0; - return PyUnicode_DecodeLocale(dgettext(domain, in), NULL); -} - -PyDoc_STRVAR(dcgettext__doc__, -"dcgettext(domain, msg, category) -> string\n" -"Return translation of msg in domain and category."); - -static PyObject* -PyIntl_dcgettext(PyObject *self, PyObject *args) -{ - char *domain, *msgid; - int category; - if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category)) - return 0; - return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL); -} - -PyDoc_STRVAR(textdomain__doc__, -"textdomain(domain) -> string\n" -"Set the C library's textdmain to domain, returning the new domain."); - -static PyObject* -PyIntl_textdomain(PyObject* self, PyObject* args) -{ - char *domain; - if (!PyArg_ParseTuple(args, "z", &domain)) - return 0; - domain = textdomain(domain); - if (!domain) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return PyUnicode_DecodeLocale(domain, NULL); -} - -PyDoc_STRVAR(bindtextdomain__doc__, -"bindtextdomain(domain, dir) -> string\n" -"Bind the C library's domain to dir."); - -static PyObject* + + if (GetLocaleInfo(LOCALE_USER_DEFAULT, + LOCALE_SISO639LANGNAME, + locale, sizeof(locale))) { + Py_ssize_t i = strlen(locale); + locale[i++] = '_'; + if (GetLocaleInfo(LOCALE_USER_DEFAULT, + LOCALE_SISO3166CTRYNAME, + locale+i, (int)(sizeof(locale)-i))) + return Py_BuildValue("ss", locale, encoding); + } + + /* If we end up here, this windows version didn't know about + ISO639/ISO3166 names (it's probably Windows 95). Return the + Windows language identifier instead (a hexadecimal number) */ + + locale[0] = '0'; + locale[1] = 'x'; + if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE, + locale+2, sizeof(locale)-2)) { + return Py_BuildValue("ss", locale, encoding); + } + + /* cannot determine the language code (very unlikely) */ + Py_INCREF(Py_None); + return Py_BuildValue("Os", Py_None, encoding); +} +#endif + +#ifdef HAVE_LANGINFO_H +#define LANGINFO(X) {#X, X} +static struct langinfo_constant{ + char* name; + int value; +} langinfo_constants[] = +{ + /* These constants should exist on any langinfo implementation */ + LANGINFO(DAY_1), + LANGINFO(DAY_2), + LANGINFO(DAY_3), + LANGINFO(DAY_4), + LANGINFO(DAY_5), + LANGINFO(DAY_6), + LANGINFO(DAY_7), + + LANGINFO(ABDAY_1), + LANGINFO(ABDAY_2), + LANGINFO(ABDAY_3), + LANGINFO(ABDAY_4), + LANGINFO(ABDAY_5), + LANGINFO(ABDAY_6), + LANGINFO(ABDAY_7), + + LANGINFO(MON_1), + LANGINFO(MON_2), + LANGINFO(MON_3), + LANGINFO(MON_4), + LANGINFO(MON_5), + LANGINFO(MON_6), + LANGINFO(MON_7), + LANGINFO(MON_8), + LANGINFO(MON_9), + LANGINFO(MON_10), + LANGINFO(MON_11), + LANGINFO(MON_12), + + LANGINFO(ABMON_1), + LANGINFO(ABMON_2), + LANGINFO(ABMON_3), + LANGINFO(ABMON_4), + LANGINFO(ABMON_5), + LANGINFO(ABMON_6), + LANGINFO(ABMON_7), + LANGINFO(ABMON_8), + LANGINFO(ABMON_9), + LANGINFO(ABMON_10), + LANGINFO(ABMON_11), + LANGINFO(ABMON_12), + +#ifdef RADIXCHAR + /* The following are not available with glibc 2.0 */ + LANGINFO(RADIXCHAR), + LANGINFO(THOUSEP), + /* YESSTR and NOSTR are deprecated in glibc, since they are + a special case of message translation, which should be rather + done using gettext. So we don't expose it to Python in the + first place. + LANGINFO(YESSTR), + LANGINFO(NOSTR), + */ + LANGINFO(CRNCYSTR), +#endif + + LANGINFO(D_T_FMT), + LANGINFO(D_FMT), + LANGINFO(T_FMT), + LANGINFO(AM_STR), + LANGINFO(PM_STR), + + /* The following constants are available only with XPG4, but... + AIX 3.2. only has CODESET. + OpenBSD doesn't have CODESET but has T_FMT_AMPM, and doesn't have + a few of the others. + Solution: ifdef-test them all. */ +#ifdef CODESET + LANGINFO(CODESET), +#endif +#ifdef T_FMT_AMPM + LANGINFO(T_FMT_AMPM), +#endif +#ifdef ERA + LANGINFO(ERA), +#endif +#ifdef ERA_D_FMT + LANGINFO(ERA_D_FMT), +#endif +#ifdef ERA_D_T_FMT + LANGINFO(ERA_D_T_FMT), +#endif +#ifdef ERA_T_FMT + LANGINFO(ERA_T_FMT), +#endif +#ifdef ALT_DIGITS + LANGINFO(ALT_DIGITS), +#endif +#ifdef YESEXPR + LANGINFO(YESEXPR), +#endif +#ifdef NOEXPR + LANGINFO(NOEXPR), +#endif +#ifdef _DATE_FMT + /* This is not available in all glibc versions that have CODESET. */ + LANGINFO(_DATE_FMT), +#endif + {0, 0} +}; + +PyDoc_STRVAR(nl_langinfo__doc__, +"nl_langinfo(key) -> string\n" +"Return the value for the locale information associated with key."); + +static PyObject* +PyLocale_nl_langinfo(PyObject* self, PyObject* args) +{ + int item, i; + if (!PyArg_ParseTuple(args, "i:nl_langinfo", &item)) + return NULL; + /* Check whether this is a supported constant. GNU libc sometimes + returns numeric values in the char* return value, which would + crash PyUnicode_FromString. */ + for (i = 0; langinfo_constants[i].name; i++) + if (langinfo_constants[i].value == item) { + /* Check NULL as a workaround for GNU libc's returning NULL + instead of an empty string for nl_langinfo(ERA). */ + const char *result = nl_langinfo(item); + result = result != NULL ? result : ""; + return PyUnicode_DecodeLocale(result, NULL); + } + PyErr_SetString(PyExc_ValueError, "unsupported langinfo constant"); + return NULL; +} +#endif /* HAVE_LANGINFO_H */ + +#ifdef HAVE_LIBINTL_H + +PyDoc_STRVAR(gettext__doc__, +"gettext(msg) -> string\n" +"Return translation of msg."); + +static PyObject* +PyIntl_gettext(PyObject* self, PyObject *args) +{ + char *in; + if (!PyArg_ParseTuple(args, "s", &in)) + return 0; + return PyUnicode_DecodeLocale(gettext(in), NULL); +} + +PyDoc_STRVAR(dgettext__doc__, +"dgettext(domain, msg) -> string\n" +"Return translation of msg in domain."); + +static PyObject* +PyIntl_dgettext(PyObject* self, PyObject *args) +{ + char *domain, *in; + if (!PyArg_ParseTuple(args, "zs", &domain, &in)) + return 0; + return PyUnicode_DecodeLocale(dgettext(domain, in), NULL); +} + +PyDoc_STRVAR(dcgettext__doc__, +"dcgettext(domain, msg, category) -> string\n" +"Return translation of msg in domain and category."); + +static PyObject* +PyIntl_dcgettext(PyObject *self, PyObject *args) +{ + char *domain, *msgid; + int category; + if (!PyArg_ParseTuple(args, "zsi", &domain, &msgid, &category)) + return 0; + return PyUnicode_DecodeLocale(dcgettext(domain,msgid,category), NULL); +} + +PyDoc_STRVAR(textdomain__doc__, +"textdomain(domain) -> string\n" +"Set the C library's textdmain to domain, returning the new domain."); + +static PyObject* +PyIntl_textdomain(PyObject* self, PyObject* args) +{ + char *domain; + if (!PyArg_ParseTuple(args, "z", &domain)) + return 0; + domain = textdomain(domain); + if (!domain) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyUnicode_DecodeLocale(domain, NULL); +} + +PyDoc_STRVAR(bindtextdomain__doc__, +"bindtextdomain(domain, dir) -> string\n" +"Bind the C library's domain to dir."); + +static PyObject* PyIntl_bindtextdomain(PyObject* self, PyObject*args) -{ +{ const char *domain, *dirname, *current_dirname; - PyObject *dirname_obj, *dirname_bytes = NULL, *result; + PyObject *dirname_obj, *dirname_bytes = NULL, *result; - if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj)) - return 0; - if (!strlen(domain)) { + if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj)) + return 0; + if (!strlen(domain)) { PyErr_SetString(get_locale_state(self)->Error, "domain must be a non-empty string"); - return 0; - } - if (dirname_obj != Py_None) { - if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes)) - return NULL; - dirname = PyBytes_AsString(dirname_bytes); - } else { - dirname_bytes = NULL; - dirname = NULL; - } - current_dirname = bindtextdomain(domain, dirname); - if (current_dirname == NULL) { - Py_XDECREF(dirname_bytes); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - result = PyUnicode_DecodeLocale(current_dirname, NULL); - Py_XDECREF(dirname_bytes); - return result; -} - -#ifdef HAVE_BIND_TEXTDOMAIN_CODESET -PyDoc_STRVAR(bind_textdomain_codeset__doc__, -"bind_textdomain_codeset(domain, codeset) -> string\n" -"Bind the C library's domain to codeset."); - -static PyObject* -PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args) -{ - char *domain,*codeset; - if (!PyArg_ParseTuple(args, "sz", &domain, &codeset)) - return NULL; - codeset = bind_textdomain_codeset(domain, codeset); - if (codeset) { - return PyUnicode_DecodeLocale(codeset, NULL); - } - Py_RETURN_NONE; -} -#endif - -#endif - -static struct PyMethodDef PyLocale_Methods[] = { - {"setlocale", (PyCFunction) PyLocale_setlocale, - METH_VARARGS, setlocale__doc__}, + return 0; + } + if (dirname_obj != Py_None) { + if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes)) + return NULL; + dirname = PyBytes_AsString(dirname_bytes); + } else { + dirname_bytes = NULL; + dirname = NULL; + } + current_dirname = bindtextdomain(domain, dirname); + if (current_dirname == NULL) { + Py_XDECREF(dirname_bytes); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + result = PyUnicode_DecodeLocale(current_dirname, NULL); + Py_XDECREF(dirname_bytes); + return result; +} + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET +PyDoc_STRVAR(bind_textdomain_codeset__doc__, +"bind_textdomain_codeset(domain, codeset) -> string\n" +"Bind the C library's domain to codeset."); + +static PyObject* +PyIntl_bind_textdomain_codeset(PyObject* self,PyObject*args) +{ + char *domain,*codeset; + if (!PyArg_ParseTuple(args, "sz", &domain, &codeset)) + return NULL; + codeset = bind_textdomain_codeset(domain, codeset); + if (codeset) { + return PyUnicode_DecodeLocale(codeset, NULL); + } + Py_RETURN_NONE; +} +#endif + +#endif + +static struct PyMethodDef PyLocale_Methods[] = { + {"setlocale", (PyCFunction) PyLocale_setlocale, + METH_VARARGS, setlocale__doc__}, {"localeconv", PyLocale_localeconv, METH_NOARGS, localeconv__doc__}, -#ifdef HAVE_WCSCOLL - {"strcoll", (PyCFunction) PyLocale_strcoll, - METH_VARARGS, strcoll__doc__}, -#endif -#ifdef HAVE_WCSXFRM - {"strxfrm", (PyCFunction) PyLocale_strxfrm, - METH_VARARGS, strxfrm__doc__}, -#endif -#if defined(MS_WINDOWS) +#ifdef HAVE_WCSCOLL + {"strcoll", (PyCFunction) PyLocale_strcoll, + METH_VARARGS, strcoll__doc__}, +#endif +#ifdef HAVE_WCSXFRM + {"strxfrm", (PyCFunction) PyLocale_strxfrm, + METH_VARARGS, strxfrm__doc__}, +#endif +#if defined(MS_WINDOWS) {"_getdefaultlocale", PyLocale_getdefaultlocale, METH_NOARGS}, -#endif -#ifdef HAVE_LANGINFO_H - {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo, - METH_VARARGS, nl_langinfo__doc__}, -#endif -#ifdef HAVE_LIBINTL_H - {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS, - gettext__doc__}, - {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS, - dgettext__doc__}, - {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS, - dcgettext__doc__}, - {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS, - textdomain__doc__}, - {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS, - bindtextdomain__doc__}, -#ifdef HAVE_BIND_TEXTDOMAIN_CODESET - {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset, - METH_VARARGS, bind_textdomain_codeset__doc__}, -#endif -#endif - {NULL, NULL} -}; - +#endif +#ifdef HAVE_LANGINFO_H + {"nl_langinfo", (PyCFunction) PyLocale_nl_langinfo, + METH_VARARGS, nl_langinfo__doc__}, +#endif +#ifdef HAVE_LIBINTL_H + {"gettext",(PyCFunction)PyIntl_gettext,METH_VARARGS, + gettext__doc__}, + {"dgettext",(PyCFunction)PyIntl_dgettext,METH_VARARGS, + dgettext__doc__}, + {"dcgettext",(PyCFunction)PyIntl_dcgettext,METH_VARARGS, + dcgettext__doc__}, + {"textdomain",(PyCFunction)PyIntl_textdomain,METH_VARARGS, + textdomain__doc__}, + {"bindtextdomain",(PyCFunction)PyIntl_bindtextdomain,METH_VARARGS, + bindtextdomain__doc__}, +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + {"bind_textdomain_codeset",(PyCFunction)PyIntl_bind_textdomain_codeset, + METH_VARARGS, bind_textdomain_codeset__doc__}, +#endif +#endif + {NULL, NULL} +}; + static int _locale_exec(PyObject *module) -{ -#ifdef HAVE_LANGINFO_H - int i; -#endif +{ +#ifdef HAVE_LANGINFO_H + int i; +#endif #define ADD_INT(module, value) \ do { \ if (PyModule_AddIntConstant(module, #value, value) < 0) { \ return -1; \ } \ } while (0) - + ADD_INT(module, LC_CTYPE); ADD_INT(module, LC_TIME); ADD_INT(module, LC_COLLATE); ADD_INT(module, LC_MONETARY); - -#ifdef LC_MESSAGES + +#ifdef LC_MESSAGES ADD_INT(module, LC_MESSAGES); -#endif /* LC_MESSAGES */ - +#endif /* LC_MESSAGES */ + ADD_INT(module, LC_NUMERIC); ADD_INT(module, LC_ALL); ADD_INT(module, CHAR_MAX); - + _locale_state *state = get_locale_state(module); state->Error = PyErr_NewException("locale.Error", NULL, NULL); if (state->Error == NULL) { return -1; - } + } Py_INCREF(get_locale_state(module)->Error); if (PyModule_AddObject(module, "Error", get_locale_state(module)->Error) < 0) { Py_DECREF(get_locale_state(module)->Error); return -1; } - -#ifdef HAVE_LANGINFO_H - for (i = 0; langinfo_constants[i].name; i++) { + +#ifdef HAVE_LANGINFO_H + for (i = 0; langinfo_constants[i].name; i++) { if (PyModule_AddIntConstant(module, langinfo_constants[i].name, langinfo_constants[i].value) < 0) { return -1; } - } -#endif - - if (PyErr_Occurred()) { + } +#endif + + if (PyErr_Occurred()) { return -1; - } + } return 0; #undef ADD_INT -} - +} + static struct PyModuleDef_Slot _locale_slots[] = { {Py_mod_exec, _locale_exec}, {0, NULL} @@ -844,9 +844,9 @@ PyInit__locale(void) return PyModuleDef_Init(&_localemodule); } -/* -Local variables: -c-basic-offset: 4 -indent-tabs-mode: nil -End: -*/ +/* +Local variables: +c-basic-offset: 4 +indent-tabs-mode: nil +End: +*/ diff --git a/contrib/tools/python3/src/Modules/_lsprof.c b/contrib/tools/python3/src/Modules/_lsprof.c index 5e53d839640..a5e18bae107 100644 --- a/contrib/tools/python3/src/Modules/_lsprof.c +++ b/contrib/tools/python3/src/Modules/_lsprof.c @@ -1,91 +1,91 @@ -#include "Python.h" -#include "rotatingtree.h" - -/************************************************************/ -/* Written by Brett Rosen and Ted Czotter */ - -struct _ProfilerEntry; - -/* represents a function called from another function */ -typedef struct _ProfilerSubEntry { - rotating_node_t header; +#include "Python.h" +#include "rotatingtree.h" + +/************************************************************/ +/* Written by Brett Rosen and Ted Czotter */ + +struct _ProfilerEntry; + +/* represents a function called from another function */ +typedef struct _ProfilerSubEntry { + rotating_node_t header; _PyTime_t tt; _PyTime_t it; - long callcount; - long recursivecallcount; - long recursionLevel; -} ProfilerSubEntry; - -/* represents a function or user defined block */ -typedef struct _ProfilerEntry { - rotating_node_t header; - PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */ + long callcount; + long recursivecallcount; + long recursionLevel; +} ProfilerSubEntry; + +/* represents a function or user defined block */ +typedef struct _ProfilerEntry { + rotating_node_t header; + PyObject *userObj; /* PyCodeObject, or a descriptive str for builtins */ _PyTime_t tt; /* total time in this entry */ _PyTime_t it; /* inline time in this entry (not in subcalls) */ - long callcount; /* how many times this was called */ - long recursivecallcount; /* how many times called recursively */ - long recursionLevel; - rotating_node_t *calls; -} ProfilerEntry; - -typedef struct _ProfilerContext { + long callcount; /* how many times this was called */ + long recursivecallcount; /* how many times called recursively */ + long recursionLevel; + rotating_node_t *calls; +} ProfilerEntry; + +typedef struct _ProfilerContext { _PyTime_t t0; _PyTime_t subt; - struct _ProfilerContext *previous; - ProfilerEntry *ctxEntry; -} ProfilerContext; - -typedef struct { - PyObject_HEAD - rotating_node_t *profilerEntries; - ProfilerContext *currentProfilerContext; - ProfilerContext *freelistProfilerContext; - int flags; - PyObject *externalTimer; - double externalTimerUnit; -} ProfilerObject; - -#define POF_ENABLED 0x001 -#define POF_SUBCALLS 0x002 -#define POF_BUILTINS 0x004 -#define POF_NOMEMORY 0x100 - -static PyTypeObject PyProfiler_Type; - -#define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type) + struct _ProfilerContext *previous; + ProfilerEntry *ctxEntry; +} ProfilerContext; + +typedef struct { + PyObject_HEAD + rotating_node_t *profilerEntries; + ProfilerContext *currentProfilerContext; + ProfilerContext *freelistProfilerContext; + int flags; + PyObject *externalTimer; + double externalTimerUnit; +} ProfilerObject; + +#define POF_ENABLED 0x001 +#define POF_SUBCALLS 0x002 +#define POF_BUILTINS 0x004 +#define POF_NOMEMORY 0x100 + +static PyTypeObject PyProfiler_Type; + +#define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type) #define PyProfiler_CheckExact(op) Py_IS_TYPE(op, &PyProfiler_Type) - -/*** External Timers ***/ - + +/*** External Timers ***/ + static _PyTime_t CallExternalTimer(ProfilerObject *pObj) -{ +{ PyObject *o = _PyObject_CallNoArg(pObj->externalTimer); - if (o == NULL) { - PyErr_WriteUnraisable(pObj->externalTimer); - return 0; - } + if (o == NULL) { + PyErr_WriteUnraisable(pObj->externalTimer); + return 0; + } _PyTime_t result; int err; - if (pObj->externalTimerUnit > 0.0) { - /* interpret the result as an integer that will be scaled - in profiler_getstats() */ + if (pObj->externalTimerUnit > 0.0) { + /* interpret the result as an integer that will be scaled + in profiler_getstats() */ err = _PyTime_FromNanosecondsObject(&result, o); - } - else { - /* interpret the result as a double measured in seconds. + } + else { + /* interpret the result as a double measured in seconds. As the profiler works with _PyTime_t internally - we convert it to a large integer */ + we convert it to a large integer */ err = _PyTime_FromSecondsObject(&result, o, _PyTime_ROUND_FLOOR); - } - Py_DECREF(o); + } + Py_DECREF(o); if (err < 0) { - PyErr_WriteUnraisable(pObj->externalTimer); - return 0; - } - return result; -} - + PyErr_WriteUnraisable(pObj->externalTimer); + return 0; + } + return result; +} + static inline _PyTime_t call_timer(ProfilerObject *pObj) { @@ -96,558 +96,558 @@ call_timer(ProfilerObject *pObj) return _PyTime_GetPerfCounter(); } } - - -/*** ProfilerObject ***/ - -static PyObject * -normalizeUserObj(PyObject *obj) -{ - PyCFunctionObject *fn; - if (!PyCFunction_Check(obj)) { - Py_INCREF(obj); - return obj; - } - /* Replace built-in function objects with a descriptive string - because of built-in methods -- keeping a reference to - __self__ is probably not a good idea. */ - fn = (PyCFunctionObject *)obj; - - if (fn->m_self == NULL) { - /* built-in function: look up the module name */ - PyObject *mod = fn->m_module; - PyObject *modname = NULL; - if (mod != NULL) { - if (PyUnicode_Check(mod)) { - modname = mod; - Py_INCREF(modname); - } - else if (PyModule_Check(mod)) { - modname = PyModule_GetNameObject(mod); - if (modname == NULL) - PyErr_Clear(); - } - } - if (modname != NULL) { - if (!_PyUnicode_EqualToASCIIString(modname, "builtins")) { - PyObject *result; - result = PyUnicode_FromFormat("<%U.%s>", modname, - fn->m_ml->ml_name); - Py_DECREF(modname); - return result; - } - Py_DECREF(modname); - } - return PyUnicode_FromFormat("<%s>", fn->m_ml->ml_name); - } - else { - /* built-in method: try to return - repr(getattr(type(__self__), __name__)) - */ - PyObject *self = fn->m_self; - PyObject *name = PyUnicode_FromString(fn->m_ml->ml_name); - PyObject *modname = fn->m_module; - - if (name != NULL) { - PyObject *mo = _PyType_Lookup(Py_TYPE(self), name); - Py_XINCREF(mo); - Py_DECREF(name); - if (mo != NULL) { - PyObject *res = PyObject_Repr(mo); - Py_DECREF(mo); - if (res != NULL) - return res; - } - } - /* Otherwise, use __module__ */ - PyErr_Clear(); - if (modname != NULL && PyUnicode_Check(modname)) - return PyUnicode_FromFormat("", - modname, fn->m_ml->ml_name); - else - return PyUnicode_FromFormat("", - fn->m_ml->ml_name); - } -} - -static ProfilerEntry* -newProfilerEntry(ProfilerObject *pObj, void *key, PyObject *userObj) -{ - ProfilerEntry *self; - self = (ProfilerEntry*) PyMem_Malloc(sizeof(ProfilerEntry)); - if (self == NULL) { - pObj->flags |= POF_NOMEMORY; - return NULL; - } - userObj = normalizeUserObj(userObj); - if (userObj == NULL) { - PyErr_Clear(); - PyMem_Free(self); - pObj->flags |= POF_NOMEMORY; - return NULL; - } - self->header.key = key; - self->userObj = userObj; - self->tt = 0; - self->it = 0; - self->callcount = 0; - self->recursivecallcount = 0; - self->recursionLevel = 0; - self->calls = EMPTY_ROTATING_TREE; - RotatingTree_Add(&pObj->profilerEntries, &self->header); - return self; -} - -static ProfilerEntry* -getEntry(ProfilerObject *pObj, void *key) -{ - return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key); -} - -static ProfilerSubEntry * -getSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry) -{ - return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls, - (void *)entry); -} - -static ProfilerSubEntry * -newSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry) -{ - ProfilerSubEntry *self; - self = (ProfilerSubEntry*) PyMem_Malloc(sizeof(ProfilerSubEntry)); - if (self == NULL) { - pObj->flags |= POF_NOMEMORY; - return NULL; - } - self->header.key = (void *)entry; - self->tt = 0; - self->it = 0; - self->callcount = 0; - self->recursivecallcount = 0; - self->recursionLevel = 0; - RotatingTree_Add(&caller->calls, &self->header); - return self; -} - -static int freeSubEntry(rotating_node_t *header, void *arg) -{ - ProfilerSubEntry *subentry = (ProfilerSubEntry*) header; - PyMem_Free(subentry); - return 0; -} - -static int freeEntry(rotating_node_t *header, void *arg) -{ - ProfilerEntry *entry = (ProfilerEntry*) header; - RotatingTree_Enum(entry->calls, freeSubEntry, NULL); - Py_DECREF(entry->userObj); - PyMem_Free(entry); - return 0; -} - -static void clearEntries(ProfilerObject *pObj) -{ - RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL); - pObj->profilerEntries = EMPTY_ROTATING_TREE; - /* release the memory hold by the ProfilerContexts */ - if (pObj->currentProfilerContext) { - PyMem_Free(pObj->currentProfilerContext); - pObj->currentProfilerContext = NULL; - } - while (pObj->freelistProfilerContext) { - ProfilerContext *c = pObj->freelistProfilerContext; - pObj->freelistProfilerContext = c->previous; - PyMem_Free(c); - } - pObj->freelistProfilerContext = NULL; -} - -static void -initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) -{ - self->ctxEntry = entry; - self->subt = 0; - self->previous = pObj->currentProfilerContext; - pObj->currentProfilerContext = self; - ++entry->recursionLevel; - if ((pObj->flags & POF_SUBCALLS) && self->previous) { - /* find or create an entry for me in my caller's entry */ - ProfilerEntry *caller = self->previous->ctxEntry; - ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry); - if (subentry == NULL) - subentry = newSubEntry(pObj, caller, entry); - if (subentry) - ++subentry->recursionLevel; - } + + +/*** ProfilerObject ***/ + +static PyObject * +normalizeUserObj(PyObject *obj) +{ + PyCFunctionObject *fn; + if (!PyCFunction_Check(obj)) { + Py_INCREF(obj); + return obj; + } + /* Replace built-in function objects with a descriptive string + because of built-in methods -- keeping a reference to + __self__ is probably not a good idea. */ + fn = (PyCFunctionObject *)obj; + + if (fn->m_self == NULL) { + /* built-in function: look up the module name */ + PyObject *mod = fn->m_module; + PyObject *modname = NULL; + if (mod != NULL) { + if (PyUnicode_Check(mod)) { + modname = mod; + Py_INCREF(modname); + } + else if (PyModule_Check(mod)) { + modname = PyModule_GetNameObject(mod); + if (modname == NULL) + PyErr_Clear(); + } + } + if (modname != NULL) { + if (!_PyUnicode_EqualToASCIIString(modname, "builtins")) { + PyObject *result; + result = PyUnicode_FromFormat("<%U.%s>", modname, + fn->m_ml->ml_name); + Py_DECREF(modname); + return result; + } + Py_DECREF(modname); + } + return PyUnicode_FromFormat("<%s>", fn->m_ml->ml_name); + } + else { + /* built-in method: try to return + repr(getattr(type(__self__), __name__)) + */ + PyObject *self = fn->m_self; + PyObject *name = PyUnicode_FromString(fn->m_ml->ml_name); + PyObject *modname = fn->m_module; + + if (name != NULL) { + PyObject *mo = _PyType_Lookup(Py_TYPE(self), name); + Py_XINCREF(mo); + Py_DECREF(name); + if (mo != NULL) { + PyObject *res = PyObject_Repr(mo); + Py_DECREF(mo); + if (res != NULL) + return res; + } + } + /* Otherwise, use __module__ */ + PyErr_Clear(); + if (modname != NULL && PyUnicode_Check(modname)) + return PyUnicode_FromFormat("", + modname, fn->m_ml->ml_name); + else + return PyUnicode_FromFormat("", + fn->m_ml->ml_name); + } +} + +static ProfilerEntry* +newProfilerEntry(ProfilerObject *pObj, void *key, PyObject *userObj) +{ + ProfilerEntry *self; + self = (ProfilerEntry*) PyMem_Malloc(sizeof(ProfilerEntry)); + if (self == NULL) { + pObj->flags |= POF_NOMEMORY; + return NULL; + } + userObj = normalizeUserObj(userObj); + if (userObj == NULL) { + PyErr_Clear(); + PyMem_Free(self); + pObj->flags |= POF_NOMEMORY; + return NULL; + } + self->header.key = key; + self->userObj = userObj; + self->tt = 0; + self->it = 0; + self->callcount = 0; + self->recursivecallcount = 0; + self->recursionLevel = 0; + self->calls = EMPTY_ROTATING_TREE; + RotatingTree_Add(&pObj->profilerEntries, &self->header); + return self; +} + +static ProfilerEntry* +getEntry(ProfilerObject *pObj, void *key) +{ + return (ProfilerEntry*) RotatingTree_Get(&pObj->profilerEntries, key); +} + +static ProfilerSubEntry * +getSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry) +{ + return (ProfilerSubEntry*) RotatingTree_Get(&caller->calls, + (void *)entry); +} + +static ProfilerSubEntry * +newSubEntry(ProfilerObject *pObj, ProfilerEntry *caller, ProfilerEntry* entry) +{ + ProfilerSubEntry *self; + self = (ProfilerSubEntry*) PyMem_Malloc(sizeof(ProfilerSubEntry)); + if (self == NULL) { + pObj->flags |= POF_NOMEMORY; + return NULL; + } + self->header.key = (void *)entry; + self->tt = 0; + self->it = 0; + self->callcount = 0; + self->recursivecallcount = 0; + self->recursionLevel = 0; + RotatingTree_Add(&caller->calls, &self->header); + return self; +} + +static int freeSubEntry(rotating_node_t *header, void *arg) +{ + ProfilerSubEntry *subentry = (ProfilerSubEntry*) header; + PyMem_Free(subentry); + return 0; +} + +static int freeEntry(rotating_node_t *header, void *arg) +{ + ProfilerEntry *entry = (ProfilerEntry*) header; + RotatingTree_Enum(entry->calls, freeSubEntry, NULL); + Py_DECREF(entry->userObj); + PyMem_Free(entry); + return 0; +} + +static void clearEntries(ProfilerObject *pObj) +{ + RotatingTree_Enum(pObj->profilerEntries, freeEntry, NULL); + pObj->profilerEntries = EMPTY_ROTATING_TREE; + /* release the memory hold by the ProfilerContexts */ + if (pObj->currentProfilerContext) { + PyMem_Free(pObj->currentProfilerContext); + pObj->currentProfilerContext = NULL; + } + while (pObj->freelistProfilerContext) { + ProfilerContext *c = pObj->freelistProfilerContext; + pObj->freelistProfilerContext = c->previous; + PyMem_Free(c); + } + pObj->freelistProfilerContext = NULL; +} + +static void +initContext(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) +{ + self->ctxEntry = entry; + self->subt = 0; + self->previous = pObj->currentProfilerContext; + pObj->currentProfilerContext = self; + ++entry->recursionLevel; + if ((pObj->flags & POF_SUBCALLS) && self->previous) { + /* find or create an entry for me in my caller's entry */ + ProfilerEntry *caller = self->previous->ctxEntry; + ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry); + if (subentry == NULL) + subentry = newSubEntry(pObj, caller, entry); + if (subentry) + ++subentry->recursionLevel; + } self->t0 = call_timer(pObj); -} - -static void -Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) -{ +} + +static void +Stop(ProfilerObject *pObj, ProfilerContext *self, ProfilerEntry *entry) +{ _PyTime_t tt = call_timer(pObj) - self->t0; _PyTime_t it = tt - self->subt; - if (self->previous) - self->previous->subt += tt; - pObj->currentProfilerContext = self->previous; - if (--entry->recursionLevel == 0) - entry->tt += tt; - else - ++entry->recursivecallcount; - entry->it += it; - entry->callcount++; - if ((pObj->flags & POF_SUBCALLS) && self->previous) { - /* find or create an entry for me in my caller's entry */ - ProfilerEntry *caller = self->previous->ctxEntry; - ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry); - if (subentry) { - if (--subentry->recursionLevel == 0) - subentry->tt += tt; - else - ++subentry->recursivecallcount; - subentry->it += it; - ++subentry->callcount; - } - } -} - -static void -ptrace_enter_call(PyObject *self, void *key, PyObject *userObj) -{ - /* entering a call to the function identified by 'key' - (which can be a PyCodeObject or a PyMethodDef pointer) */ - ProfilerObject *pObj = (ProfilerObject*)self; - ProfilerEntry *profEntry; - ProfilerContext *pContext; - - /* In the case of entering a generator expression frame via a - * throw (gen_send_ex(.., 1)), we may already have an - * Exception set here. We must not mess around with this - * exception, and some of the code under here assumes that - * PyErr_* is its own to mess around with, so we have to - * save and restore any current exception. */ - PyObject *last_type, *last_value, *last_tb; - PyErr_Fetch(&last_type, &last_value, &last_tb); - - profEntry = getEntry(pObj, key); - if (profEntry == NULL) { - profEntry = newProfilerEntry(pObj, key, userObj); - if (profEntry == NULL) - goto restorePyerr; - } - /* grab a ProfilerContext out of the free list */ - pContext = pObj->freelistProfilerContext; - if (pContext) { - pObj->freelistProfilerContext = pContext->previous; - } - else { - /* free list exhausted, allocate a new one */ - pContext = (ProfilerContext*) - PyMem_Malloc(sizeof(ProfilerContext)); - if (pContext == NULL) { - pObj->flags |= POF_NOMEMORY; - goto restorePyerr; - } - } - initContext(pObj, pContext, profEntry); - -restorePyerr: - PyErr_Restore(last_type, last_value, last_tb); -} - -static void -ptrace_leave_call(PyObject *self, void *key) -{ - /* leaving a call to the function identified by 'key' */ - ProfilerObject *pObj = (ProfilerObject*)self; - ProfilerEntry *profEntry; - ProfilerContext *pContext; - - pContext = pObj->currentProfilerContext; - if (pContext == NULL) - return; - profEntry = getEntry(pObj, key); - if (profEntry) { - Stop(pObj, pContext, profEntry); - } - else { - pObj->currentProfilerContext = pContext->previous; - } - /* put pContext into the free list */ - pContext->previous = pObj->freelistProfilerContext; - pObj->freelistProfilerContext = pContext; -} - -static int -profiler_callback(PyObject *self, PyFrameObject *frame, int what, - PyObject *arg) -{ - switch (what) { - - /* the 'frame' of a called function is about to start its execution */ - case PyTrace_CALL: + if (self->previous) + self->previous->subt += tt; + pObj->currentProfilerContext = self->previous; + if (--entry->recursionLevel == 0) + entry->tt += tt; + else + ++entry->recursivecallcount; + entry->it += it; + entry->callcount++; + if ((pObj->flags & POF_SUBCALLS) && self->previous) { + /* find or create an entry for me in my caller's entry */ + ProfilerEntry *caller = self->previous->ctxEntry; + ProfilerSubEntry *subentry = getSubEntry(pObj, caller, entry); + if (subentry) { + if (--subentry->recursionLevel == 0) + subentry->tt += tt; + else + ++subentry->recursivecallcount; + subentry->it += it; + ++subentry->callcount; + } + } +} + +static void +ptrace_enter_call(PyObject *self, void *key, PyObject *userObj) +{ + /* entering a call to the function identified by 'key' + (which can be a PyCodeObject or a PyMethodDef pointer) */ + ProfilerObject *pObj = (ProfilerObject*)self; + ProfilerEntry *profEntry; + ProfilerContext *pContext; + + /* In the case of entering a generator expression frame via a + * throw (gen_send_ex(.., 1)), we may already have an + * Exception set here. We must not mess around with this + * exception, and some of the code under here assumes that + * PyErr_* is its own to mess around with, so we have to + * save and restore any current exception. */ + PyObject *last_type, *last_value, *last_tb; + PyErr_Fetch(&last_type, &last_value, &last_tb); + + profEntry = getEntry(pObj, key); + if (profEntry == NULL) { + profEntry = newProfilerEntry(pObj, key, userObj); + if (profEntry == NULL) + goto restorePyerr; + } + /* grab a ProfilerContext out of the free list */ + pContext = pObj->freelistProfilerContext; + if (pContext) { + pObj->freelistProfilerContext = pContext->previous; + } + else { + /* free list exhausted, allocate a new one */ + pContext = (ProfilerContext*) + PyMem_Malloc(sizeof(ProfilerContext)); + if (pContext == NULL) { + pObj->flags |= POF_NOMEMORY; + goto restorePyerr; + } + } + initContext(pObj, pContext, profEntry); + +restorePyerr: + PyErr_Restore(last_type, last_value, last_tb); +} + +static void +ptrace_leave_call(PyObject *self, void *key) +{ + /* leaving a call to the function identified by 'key' */ + ProfilerObject *pObj = (ProfilerObject*)self; + ProfilerEntry *profEntry; + ProfilerContext *pContext; + + pContext = pObj->currentProfilerContext; + if (pContext == NULL) + return; + profEntry = getEntry(pObj, key); + if (profEntry) { + Stop(pObj, pContext, profEntry); + } + else { + pObj->currentProfilerContext = pContext->previous; + } + /* put pContext into the free list */ + pContext->previous = pObj->freelistProfilerContext; + pObj->freelistProfilerContext = pContext; +} + +static int +profiler_callback(PyObject *self, PyFrameObject *frame, int what, + PyObject *arg) +{ + switch (what) { + + /* the 'frame' of a called function is about to start its execution */ + case PyTrace_CALL: { PyCodeObject *code = PyFrame_GetCode(frame); ptrace_enter_call(self, (void *)code, (PyObject *)code); Py_DECREF(code); - break; + break; } - - /* the 'frame' of a called function is about to finish - (either normally or with an exception) */ - case PyTrace_RETURN: + + /* the 'frame' of a called function is about to finish + (either normally or with an exception) */ + case PyTrace_RETURN: { PyCodeObject *code = PyFrame_GetCode(frame); ptrace_leave_call(self, (void *)code); Py_DECREF(code); - break; - } - - /* case PyTrace_EXCEPTION: - If the exception results in the function exiting, a - PyTrace_RETURN event will be generated, so we don't need to - handle it. */ - - /* the Python function 'frame' is issuing a call to the built-in - function 'arg' */ - case PyTrace_C_CALL: - if ((((ProfilerObject *)self)->flags & POF_BUILTINS) - && PyCFunction_Check(arg)) { - ptrace_enter_call(self, - ((PyCFunctionObject *)arg)->m_ml, - arg); - } - break; - - /* the call to the built-in function 'arg' is returning into its - caller 'frame' */ - case PyTrace_C_RETURN: /* ...normally */ - case PyTrace_C_EXCEPTION: /* ...with an exception set */ - if ((((ProfilerObject *)self)->flags & POF_BUILTINS) - && PyCFunction_Check(arg)) { - ptrace_leave_call(self, - ((PyCFunctionObject *)arg)->m_ml); - } - break; - - default: - break; - } - return 0; -} - -static int -pending_exception(ProfilerObject *pObj) -{ - if (pObj->flags & POF_NOMEMORY) { - pObj->flags -= POF_NOMEMORY; - PyErr_SetString(PyExc_MemoryError, - "memory was exhausted while profiling"); - return -1; - } - return 0; -} - -/************************************************************/ - -static PyStructSequence_Field profiler_entry_fields[] = { - {"code", "code object or built-in function name"}, - {"callcount", "how many times this was called"}, - {"reccallcount", "how many times called recursively"}, - {"totaltime", "total time in this entry"}, - {"inlinetime", "inline time in this entry (not in subcalls)"}, - {"calls", "details of the calls"}, - {0} -}; - -static PyStructSequence_Field profiler_subentry_fields[] = { - {"code", "called code object or built-in function name"}, - {"callcount", "how many times this is called"}, - {"reccallcount", "how many times this is called recursively"}, - {"totaltime", "total time spent in this call"}, - {"inlinetime", "inline time (not in further subcalls)"}, - {0} -}; - -static PyStructSequence_Desc profiler_entry_desc = { - "_lsprof.profiler_entry", /* name */ - NULL, /* doc */ - profiler_entry_fields, - 6 -}; - -static PyStructSequence_Desc profiler_subentry_desc = { - "_lsprof.profiler_subentry", /* name */ - NULL, /* doc */ - profiler_subentry_fields, - 5 -}; - -static int initialized; -static PyTypeObject StatsEntryType; -static PyTypeObject StatsSubEntryType; - - -typedef struct { - PyObject *list; - PyObject *sublist; - double factor; -} statscollector_t; - -static int statsForSubEntry(rotating_node_t *node, void *arg) -{ - ProfilerSubEntry *sentry = (ProfilerSubEntry*) node; - statscollector_t *collect = (statscollector_t*) arg; - ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key; - int err; - PyObject *sinfo; - sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType, - "((Olldd))", - entry->userObj, - sentry->callcount, - sentry->recursivecallcount, - collect->factor * sentry->tt, - collect->factor * sentry->it); - if (sinfo == NULL) - return -1; - err = PyList_Append(collect->sublist, sinfo); - Py_DECREF(sinfo); - return err; -} - -static int statsForEntry(rotating_node_t *node, void *arg) -{ - ProfilerEntry *entry = (ProfilerEntry*) node; - statscollector_t *collect = (statscollector_t*) arg; - PyObject *info; - int err; - if (entry->callcount == 0) - return 0; /* skip */ - - if (entry->calls != EMPTY_ROTATING_TREE) { - collect->sublist = PyList_New(0); - if (collect->sublist == NULL) - return -1; - if (RotatingTree_Enum(entry->calls, - statsForSubEntry, collect) != 0) { - Py_DECREF(collect->sublist); - return -1; - } - } - else { - Py_INCREF(Py_None); - collect->sublist = Py_None; - } - - info = PyObject_CallFunction((PyObject*) &StatsEntryType, - "((OllddO))", - entry->userObj, - entry->callcount, - entry->recursivecallcount, - collect->factor * entry->tt, - collect->factor * entry->it, - collect->sublist); - Py_DECREF(collect->sublist); - if (info == NULL) - return -1; - err = PyList_Append(collect->list, info); - Py_DECREF(info); - return err; -} - -PyDoc_STRVAR(getstats_doc, "\ -getstats() -> list of profiler_entry objects\n\ -\n\ -Return all information collected by the profiler.\n\ -Each profiler_entry is a tuple-like object with the\n\ -following attributes:\n\ -\n\ - code code object\n\ - callcount how many times this was called\n\ - reccallcount how many times called recursively\n\ - totaltime total time in this entry\n\ - inlinetime inline time in this entry (not in subcalls)\n\ - calls details of the calls\n\ -\n\ -The calls attribute is either None or a list of\n\ -profiler_subentry objects:\n\ -\n\ - code called code object\n\ - callcount how many times this is called\n\ - reccallcount how many times this is called recursively\n\ - totaltime total time spent in this call\n\ - inlinetime inline time (not in further subcalls)\n\ -"); - -static PyObject* -profiler_getstats(ProfilerObject *pObj, PyObject* noarg) -{ - statscollector_t collect; + break; + } + + /* case PyTrace_EXCEPTION: + If the exception results in the function exiting, a + PyTrace_RETURN event will be generated, so we don't need to + handle it. */ + + /* the Python function 'frame' is issuing a call to the built-in + function 'arg' */ + case PyTrace_C_CALL: + if ((((ProfilerObject *)self)->flags & POF_BUILTINS) + && PyCFunction_Check(arg)) { + ptrace_enter_call(self, + ((PyCFunctionObject *)arg)->m_ml, + arg); + } + break; + + /* the call to the built-in function 'arg' is returning into its + caller 'frame' */ + case PyTrace_C_RETURN: /* ...normally */ + case PyTrace_C_EXCEPTION: /* ...with an exception set */ + if ((((ProfilerObject *)self)->flags & POF_BUILTINS) + && PyCFunction_Check(arg)) { + ptrace_leave_call(self, + ((PyCFunctionObject *)arg)->m_ml); + } + break; + + default: + break; + } + return 0; +} + +static int +pending_exception(ProfilerObject *pObj) +{ + if (pObj->flags & POF_NOMEMORY) { + pObj->flags -= POF_NOMEMORY; + PyErr_SetString(PyExc_MemoryError, + "memory was exhausted while profiling"); + return -1; + } + return 0; +} + +/************************************************************/ + +static PyStructSequence_Field profiler_entry_fields[] = { + {"code", "code object or built-in function name"}, + {"callcount", "how many times this was called"}, + {"reccallcount", "how many times called recursively"}, + {"totaltime", "total time in this entry"}, + {"inlinetime", "inline time in this entry (not in subcalls)"}, + {"calls", "details of the calls"}, + {0} +}; + +static PyStructSequence_Field profiler_subentry_fields[] = { + {"code", "called code object or built-in function name"}, + {"callcount", "how many times this is called"}, + {"reccallcount", "how many times this is called recursively"}, + {"totaltime", "total time spent in this call"}, + {"inlinetime", "inline time (not in further subcalls)"}, + {0} +}; + +static PyStructSequence_Desc profiler_entry_desc = { + "_lsprof.profiler_entry", /* name */ + NULL, /* doc */ + profiler_entry_fields, + 6 +}; + +static PyStructSequence_Desc profiler_subentry_desc = { + "_lsprof.profiler_subentry", /* name */ + NULL, /* doc */ + profiler_subentry_fields, + 5 +}; + +static int initialized; +static PyTypeObject StatsEntryType; +static PyTypeObject StatsSubEntryType; + + +typedef struct { + PyObject *list; + PyObject *sublist; + double factor; +} statscollector_t; + +static int statsForSubEntry(rotating_node_t *node, void *arg) +{ + ProfilerSubEntry *sentry = (ProfilerSubEntry*) node; + statscollector_t *collect = (statscollector_t*) arg; + ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key; + int err; + PyObject *sinfo; + sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType, + "((Olldd))", + entry->userObj, + sentry->callcount, + sentry->recursivecallcount, + collect->factor * sentry->tt, + collect->factor * sentry->it); + if (sinfo == NULL) + return -1; + err = PyList_Append(collect->sublist, sinfo); + Py_DECREF(sinfo); + return err; +} + +static int statsForEntry(rotating_node_t *node, void *arg) +{ + ProfilerEntry *entry = (ProfilerEntry*) node; + statscollector_t *collect = (statscollector_t*) arg; + PyObject *info; + int err; + if (entry->callcount == 0) + return 0; /* skip */ + + if (entry->calls != EMPTY_ROTATING_TREE) { + collect->sublist = PyList_New(0); + if (collect->sublist == NULL) + return -1; + if (RotatingTree_Enum(entry->calls, + statsForSubEntry, collect) != 0) { + Py_DECREF(collect->sublist); + return -1; + } + } + else { + Py_INCREF(Py_None); + collect->sublist = Py_None; + } + + info = PyObject_CallFunction((PyObject*) &StatsEntryType, + "((OllddO))", + entry->userObj, + entry->callcount, + entry->recursivecallcount, + collect->factor * entry->tt, + collect->factor * entry->it, + collect->sublist); + Py_DECREF(collect->sublist); + if (info == NULL) + return -1; + err = PyList_Append(collect->list, info); + Py_DECREF(info); + return err; +} + +PyDoc_STRVAR(getstats_doc, "\ +getstats() -> list of profiler_entry objects\n\ +\n\ +Return all information collected by the profiler.\n\ +Each profiler_entry is a tuple-like object with the\n\ +following attributes:\n\ +\n\ + code code object\n\ + callcount how many times this was called\n\ + reccallcount how many times called recursively\n\ + totaltime total time in this entry\n\ + inlinetime inline time in this entry (not in subcalls)\n\ + calls details of the calls\n\ +\n\ +The calls attribute is either None or a list of\n\ +profiler_subentry objects:\n\ +\n\ + code called code object\n\ + callcount how many times this is called\n\ + reccallcount how many times this is called recursively\n\ + totaltime total time spent in this call\n\ + inlinetime inline time (not in further subcalls)\n\ +"); + +static PyObject* +profiler_getstats(ProfilerObject *pObj, PyObject* noarg) +{ + statscollector_t collect; if (pending_exception(pObj)) { - return NULL; + return NULL; } if (!pObj->externalTimer || pObj->externalTimerUnit == 0.0) { _PyTime_t onesec = _PyTime_FromSeconds(1); collect.factor = (double)1 / onesec; } else { - collect.factor = pObj->externalTimerUnit; - } - - collect.list = PyList_New(0); - if (collect.list == NULL) - return NULL; - if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect) - != 0) { - Py_DECREF(collect.list); - return NULL; - } - return collect.list; -} - -static int -setSubcalls(ProfilerObject *pObj, int nvalue) -{ - if (nvalue == 0) - pObj->flags &= ~POF_SUBCALLS; - else if (nvalue > 0) - pObj->flags |= POF_SUBCALLS; - return 0; -} - -static int -setBuiltins(ProfilerObject *pObj, int nvalue) -{ - if (nvalue == 0) - pObj->flags &= ~POF_BUILTINS; - else if (nvalue > 0) { - pObj->flags |= POF_BUILTINS; - } - return 0; -} - -PyDoc_STRVAR(enable_doc, "\ -enable(subcalls=True, builtins=True)\n\ -\n\ -Start collecting profiling information.\n\ -If 'subcalls' is True, also records for each function\n\ -statistics separated according to its current caller.\n\ -If 'builtins' is True, records the time spent in\n\ -built-in functions separately from their caller.\n\ -"); - -static PyObject* -profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) -{ - int subcalls = -1; - int builtins = -1; - static char *kwlist[] = {"subcalls", "builtins", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", - kwlist, &subcalls, &builtins)) - return NULL; + collect.factor = pObj->externalTimerUnit; + } + + collect.list = PyList_New(0); + if (collect.list == NULL) + return NULL; + if (RotatingTree_Enum(pObj->profilerEntries, statsForEntry, &collect) + != 0) { + Py_DECREF(collect.list); + return NULL; + } + return collect.list; +} + +static int +setSubcalls(ProfilerObject *pObj, int nvalue) +{ + if (nvalue == 0) + pObj->flags &= ~POF_SUBCALLS; + else if (nvalue > 0) + pObj->flags |= POF_SUBCALLS; + return 0; +} + +static int +setBuiltins(ProfilerObject *pObj, int nvalue) +{ + if (nvalue == 0) + pObj->flags &= ~POF_BUILTINS; + else if (nvalue > 0) { + pObj->flags |= POF_BUILTINS; + } + return 0; +} + +PyDoc_STRVAR(enable_doc, "\ +enable(subcalls=True, builtins=True)\n\ +\n\ +Start collecting profiling information.\n\ +If 'subcalls' is True, also records for each function\n\ +statistics separated according to its current caller.\n\ +If 'builtins' is True, records the time spent in\n\ +built-in functions separately from their caller.\n\ +"); + +static PyObject* +profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) +{ + int subcalls = -1; + int builtins = -1; + static char *kwlist[] = {"subcalls", "builtins", 0}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", + kwlist, &subcalls, &builtins)) + return NULL; if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) { - return NULL; + return NULL; } PyThreadState *tstate = PyThreadState_GET(); @@ -655,64 +655,64 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) return NULL; } - self->flags |= POF_ENABLED; - Py_RETURN_NONE; -} - -static void -flush_unmatched(ProfilerObject *pObj) -{ - while (pObj->currentProfilerContext) { - ProfilerContext *pContext = pObj->currentProfilerContext; - ProfilerEntry *profEntry= pContext->ctxEntry; - if (profEntry) - Stop(pObj, pContext, profEntry); - else - pObj->currentProfilerContext = pContext->previous; - if (pContext) - PyMem_Free(pContext); - } - -} - -PyDoc_STRVAR(disable_doc, "\ -disable()\n\ -\n\ -Stop collecting profiling information.\n\ -"); - -static PyObject* -profiler_disable(ProfilerObject *self, PyObject* noarg) -{ + self->flags |= POF_ENABLED; + Py_RETURN_NONE; +} + +static void +flush_unmatched(ProfilerObject *pObj) +{ + while (pObj->currentProfilerContext) { + ProfilerContext *pContext = pObj->currentProfilerContext; + ProfilerEntry *profEntry= pContext->ctxEntry; + if (profEntry) + Stop(pObj, pContext, profEntry); + else + pObj->currentProfilerContext = pContext->previous; + if (pContext) + PyMem_Free(pContext); + } + +} + +PyDoc_STRVAR(disable_doc, "\ +disable()\n\ +\n\ +Stop collecting profiling information.\n\ +"); + +static PyObject* +profiler_disable(ProfilerObject *self, PyObject* noarg) +{ PyThreadState *tstate = PyThreadState_GET(); if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { return NULL; } - self->flags &= ~POF_ENABLED; + self->flags &= ~POF_ENABLED; - flush_unmatched(self); + flush_unmatched(self); if (pending_exception(self)) { - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(clear_doc, "\ -clear()\n\ -\n\ -Clear all profiling information collected so far.\n\ -"); - -static PyObject* -profiler_clear(ProfilerObject *pObj, PyObject* noarg) -{ - clearEntries(pObj); - Py_RETURN_NONE; -} - -static void -profiler_dealloc(ProfilerObject *op) -{ + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(clear_doc, "\ +clear()\n\ +\n\ +Clear all profiling information collected so far.\n\ +"); + +static PyObject* +profiler_clear(ProfilerObject *pObj, PyObject* noarg) +{ + clearEntries(pObj); + Py_RETURN_NONE; +} + +static void +profiler_dealloc(ProfilerObject *op) +{ if (op->flags & POF_ENABLED) { PyThreadState *tstate = PyThreadState_GET(); if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { @@ -720,142 +720,142 @@ profiler_dealloc(ProfilerObject *op) } } - flush_unmatched(op); - clearEntries(op); - Py_XDECREF(op->externalTimer); - Py_TYPE(op)->tp_free(op); -} - -static int -profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) -{ - PyObject *timer = NULL; - double timeunit = 0.0; - int subcalls = 1; - int builtins = 1; - static char *kwlist[] = {"timer", "timeunit", - "subcalls", "builtins", 0}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist, - &timer, &timeunit, - &subcalls, &builtins)) - return -1; - - if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) - return -1; - pObj->externalTimerUnit = timeunit; - Py_XINCREF(timer); - Py_XSETREF(pObj->externalTimer, timer); - return 0; -} - -static PyMethodDef profiler_methods[] = { - {"getstats", (PyCFunction)profiler_getstats, - METH_NOARGS, getstats_doc}, + flush_unmatched(op); + clearEntries(op); + Py_XDECREF(op->externalTimer); + Py_TYPE(op)->tp_free(op); +} + +static int +profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) +{ + PyObject *timer = NULL; + double timeunit = 0.0; + int subcalls = 1; + int builtins = 1; + static char *kwlist[] = {"timer", "timeunit", + "subcalls", "builtins", 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist, + &timer, &timeunit, + &subcalls, &builtins)) + return -1; + + if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) + return -1; + pObj->externalTimerUnit = timeunit; + Py_XINCREF(timer); + Py_XSETREF(pObj->externalTimer, timer); + return 0; +} + +static PyMethodDef profiler_methods[] = { + {"getstats", (PyCFunction)profiler_getstats, + METH_NOARGS, getstats_doc}, {"enable", (PyCFunction)(void(*)(void))profiler_enable, - METH_VARARGS | METH_KEYWORDS, enable_doc}, - {"disable", (PyCFunction)profiler_disable, - METH_NOARGS, disable_doc}, - {"clear", (PyCFunction)profiler_clear, - METH_NOARGS, clear_doc}, - {NULL, NULL} -}; - -PyDoc_STRVAR(profiler_doc, "\ -Profiler(timer=None, timeunit=None, subcalls=True, builtins=True)\n\ -\n\ - Builds a profiler object using the specified timer function.\n\ - The default timer is a fast built-in one based on real time.\n\ - For custom timer functions returning integers, timeunit can\n\ - be a float specifying a scale (i.e. how long each integer unit\n\ - is, in seconds).\n\ -"); - -static PyTypeObject PyProfiler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_lsprof.Profiler", /* tp_name */ - sizeof(ProfilerObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)profiler_dealloc, /* tp_dealloc */ + METH_VARARGS | METH_KEYWORDS, enable_doc}, + {"disable", (PyCFunction)profiler_disable, + METH_NOARGS, disable_doc}, + {"clear", (PyCFunction)profiler_clear, + METH_NOARGS, clear_doc}, + {NULL, NULL} +}; + +PyDoc_STRVAR(profiler_doc, "\ +Profiler(timer=None, timeunit=None, subcalls=True, builtins=True)\n\ +\n\ + Builds a profiler object using the specified timer function.\n\ + The default timer is a fast built-in one based on real time.\n\ + For custom timer functions returning integers, timeunit can\n\ + be a float specifying a scale (i.e. how long each integer unit\n\ + is, in seconds).\n\ +"); + +static PyTypeObject PyProfiler_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_lsprof.Profiler", /* tp_name */ + sizeof(ProfilerObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)profiler_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - profiler_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - profiler_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)profiler_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - PyObject_Del, /* tp_free */ -}; - -static PyMethodDef moduleMethods[] = { - {NULL, NULL} -}; - - -static struct PyModuleDef _lsprofmodule = { - PyModuleDef_HEAD_INIT, - "_lsprof", - "Fast profiler", - -1, - moduleMethods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__lsprof(void) -{ - PyObject *module, *d; - module = PyModule_Create(&_lsprofmodule); - if (module == NULL) - return NULL; - d = PyModule_GetDict(module); - if (PyType_Ready(&PyProfiler_Type) < 0) - return NULL; - PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); - - if (!initialized) { - if (PyStructSequence_InitType2(&StatsEntryType, - &profiler_entry_desc) < 0) - return NULL; - if (PyStructSequence_InitType2(&StatsSubEntryType, - &profiler_subentry_desc) < 0) - return NULL; - } - Py_INCREF((PyObject*) &StatsEntryType); - Py_INCREF((PyObject*) &StatsSubEntryType); - PyModule_AddObject(module, "profiler_entry", - (PyObject*) &StatsEntryType); - PyModule_AddObject(module, "profiler_subentry", - (PyObject*) &StatsSubEntryType); - initialized = 1; - return module; -} + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + profiler_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + profiler_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)profiler_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + +static PyMethodDef moduleMethods[] = { + {NULL, NULL} +}; + + +static struct PyModuleDef _lsprofmodule = { + PyModuleDef_HEAD_INIT, + "_lsprof", + "Fast profiler", + -1, + moduleMethods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__lsprof(void) +{ + PyObject *module, *d; + module = PyModule_Create(&_lsprofmodule); + if (module == NULL) + return NULL; + d = PyModule_GetDict(module); + if (PyType_Ready(&PyProfiler_Type) < 0) + return NULL; + PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); + + if (!initialized) { + if (PyStructSequence_InitType2(&StatsEntryType, + &profiler_entry_desc) < 0) + return NULL; + if (PyStructSequence_InitType2(&StatsSubEntryType, + &profiler_subentry_desc) < 0) + return NULL; + } + Py_INCREF((PyObject*) &StatsEntryType); + Py_INCREF((PyObject*) &StatsSubEntryType); + PyModule_AddObject(module, "profiler_entry", + (PyObject*) &StatsEntryType); + PyModule_AddObject(module, "profiler_subentry", + (PyObject*) &StatsSubEntryType); + initialized = 1; + return module; +} diff --git a/contrib/tools/python3/src/Modules/_lzmamodule.c b/contrib/tools/python3/src/Modules/_lzmamodule.c index 2a62a683568..24ffe50c7fc 100644 --- a/contrib/tools/python3/src/Modules/_lzmamodule.c +++ b/contrib/tools/python3/src/Modules/_lzmamodule.c @@ -1,1494 +1,1494 @@ -/* _lzma - Low-level Python interface to liblzma. - - Initial implementation by Per Øyvind Karlsen. - Rewritten by Nadeem Vawda. - -*/ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" -#include "structmember.h" // PyMemberDef - -#include -#include - -#include - -#define ACQUIRE_LOCK(obj) do { \ - if (!PyThread_acquire_lock((obj)->lock, 0)) { \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock((obj)->lock, 1); \ - Py_END_ALLOW_THREADS \ - } } while (0) -#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock) - - -/* Container formats: */ -enum { - FORMAT_AUTO, - FORMAT_XZ, - FORMAT_ALONE, - FORMAT_RAW, -}; - -#define LZMA_CHECK_UNKNOWN (LZMA_CHECK_ID_MAX + 1) - - -typedef struct { - PyObject_HEAD - lzma_allocator alloc; - lzma_stream lzs; - int flushed; - PyThread_type_lock lock; -} Compressor; - -typedef struct { - PyObject_HEAD - lzma_allocator alloc; - lzma_stream lzs; - int check; - char eof; - PyObject *unused_data; - char needs_input; - uint8_t *input_buffer; - size_t input_buffer_size; - PyThread_type_lock lock; -} Decompressor; - -/* LZMAError class object. */ -static PyObject *Error; - -/* An empty tuple, used by the filter specifier parsing code. */ -static PyObject *empty_tuple; - - -/* Helper functions. */ - -static int -catch_lzma_error(lzma_ret lzret) -{ - switch (lzret) { - case LZMA_OK: - case LZMA_GET_CHECK: - case LZMA_NO_CHECK: - case LZMA_STREAM_END: - return 0; - case LZMA_UNSUPPORTED_CHECK: - PyErr_SetString(Error, "Unsupported integrity check"); - return 1; - case LZMA_MEM_ERROR: - PyErr_NoMemory(); - return 1; - case LZMA_MEMLIMIT_ERROR: - PyErr_SetString(Error, "Memory usage limit exceeded"); - return 1; - case LZMA_FORMAT_ERROR: - PyErr_SetString(Error, "Input format not supported by decoder"); - return 1; - case LZMA_OPTIONS_ERROR: - PyErr_SetString(Error, "Invalid or unsupported options"); - return 1; - case LZMA_DATA_ERROR: - PyErr_SetString(Error, "Corrupt input data"); - return 1; - case LZMA_BUF_ERROR: - PyErr_SetString(Error, "Insufficient buffer space"); - return 1; - case LZMA_PROG_ERROR: - PyErr_SetString(Error, "Internal error"); - return 1; - default: - PyErr_Format(Error, "Unrecognized error from liblzma: %d", lzret); - return 1; - } -} - -static void* -PyLzma_Malloc(void *opaque, size_t items, size_t size) -{ - if (size != 0 && items > (size_t)PY_SSIZE_T_MAX / size) - return NULL; - /* PyMem_Malloc() cannot be used: - the GIL is not held when lzma_code() is called */ - return PyMem_RawMalloc(items * size); -} - -static void -PyLzma_Free(void *opaque, void *ptr) -{ - PyMem_RawFree(ptr); -} - -#if BUFSIZ < 8192 -#define INITIAL_BUFFER_SIZE 8192 -#else -#define INITIAL_BUFFER_SIZE BUFSIZ -#endif - -static int -grow_buffer(PyObject **buf, Py_ssize_t max_length) -{ - Py_ssize_t size = PyBytes_GET_SIZE(*buf); - Py_ssize_t newsize = size + (size >> 3) + 6; - - if (max_length > 0 && newsize > max_length) - newsize = max_length; - - return _PyBytes_Resize(buf, newsize); -} - - -/* Some custom type conversions for PyArg_ParseTupleAndKeywords(), - since the predefined conversion specifiers do not suit our needs: - - uint32_t - the "I" (unsigned int) specifier is the right size, but - silently ignores overflows on conversion. - - lzma_vli - the "K" (unsigned long long) specifier is the right - size, but like "I" it silently ignores overflows on conversion. - - lzma_mode and lzma_match_finder - these are enumeration types, and - so the size of each is implementation-defined. Worse, different - enum types can be of different sizes within the same program, so - to be strictly correct, we need to define two separate converters. - */ - -#define INT_TYPE_CONVERTER_FUNC(TYPE, FUNCNAME) \ - static int \ - FUNCNAME(PyObject *obj, void *ptr) \ - { \ - unsigned long long val; \ - \ - val = PyLong_AsUnsignedLongLong(obj); \ - if (PyErr_Occurred()) \ - return 0; \ - if ((unsigned long long)(TYPE)val != val) { \ - PyErr_SetString(PyExc_OverflowError, \ - "Value too large for " #TYPE " type"); \ - return 0; \ - } \ - *(TYPE *)ptr = (TYPE)val; \ - return 1; \ - } - -INT_TYPE_CONVERTER_FUNC(uint32_t, uint32_converter) -INT_TYPE_CONVERTER_FUNC(lzma_vli, lzma_vli_converter) -INT_TYPE_CONVERTER_FUNC(lzma_mode, lzma_mode_converter) -INT_TYPE_CONVERTER_FUNC(lzma_match_finder, lzma_mf_converter) - -#undef INT_TYPE_CONVERTER_FUNC - - -/* Filter specifier parsing. - - This code handles converting filter specifiers (Python dicts) into - the C lzma_filter structs expected by liblzma. */ - -static void * -parse_filter_spec_lzma(PyObject *spec) -{ - static char *optnames[] = {"id", "preset", "dict_size", "lc", "lp", - "pb", "mode", "nice_len", "mf", "depth", NULL}; - PyObject *id; - PyObject *preset_obj; - uint32_t preset = LZMA_PRESET_DEFAULT; - lzma_options_lzma *options; - - /* First, fill in default values for all the options using a preset. - Then, override the defaults with any values given by the caller. */ - - preset_obj = PyMapping_GetItemString(spec, "preset"); - if (preset_obj == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_Clear(); - else - return NULL; - } else { - int ok = uint32_converter(preset_obj, &preset); - Py_DECREF(preset_obj); - if (!ok) - return NULL; - } - - options = (lzma_options_lzma *)PyMem_Calloc(1, sizeof *options); - if (options == NULL) - return PyErr_NoMemory(); - - if (lzma_lzma_preset(options, preset)) { - PyMem_Free(options); - PyErr_Format(Error, "Invalid compression preset: %u", preset); - return NULL; - } - - if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, - "|OOO&O&O&O&O&O&O&O&", optnames, - &id, &preset_obj, - uint32_converter, &options->dict_size, - uint32_converter, &options->lc, - uint32_converter, &options->lp, - uint32_converter, &options->pb, - lzma_mode_converter, &options->mode, - uint32_converter, &options->nice_len, - lzma_mf_converter, &options->mf, - uint32_converter, &options->depth)) { - PyErr_SetString(PyExc_ValueError, - "Invalid filter specifier for LZMA filter"); - PyMem_Free(options); - options = NULL; - } - return options; -} - -static void * -parse_filter_spec_delta(PyObject *spec) -{ - static char *optnames[] = {"id", "dist", NULL}; - PyObject *id; - uint32_t dist = 1; - lzma_options_delta *options; - - if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, "|OO&", optnames, - &id, uint32_converter, &dist)) { - PyErr_SetString(PyExc_ValueError, - "Invalid filter specifier for delta filter"); - return NULL; - } - - options = (lzma_options_delta *)PyMem_Calloc(1, sizeof *options); - if (options == NULL) - return PyErr_NoMemory(); - options->type = LZMA_DELTA_TYPE_BYTE; - options->dist = dist; - return options; -} - -static void * -parse_filter_spec_bcj(PyObject *spec) -{ - static char *optnames[] = {"id", "start_offset", NULL}; - PyObject *id; - uint32_t start_offset = 0; - lzma_options_bcj *options; - - if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, "|OO&", optnames, - &id, uint32_converter, &start_offset)) { - PyErr_SetString(PyExc_ValueError, - "Invalid filter specifier for BCJ filter"); - return NULL; - } - - options = (lzma_options_bcj *)PyMem_Calloc(1, sizeof *options); - if (options == NULL) - return PyErr_NoMemory(); - options->start_offset = start_offset; - return options; -} - -static int -lzma_filter_converter(PyObject *spec, void *ptr) -{ - lzma_filter *f = (lzma_filter *)ptr; - PyObject *id_obj; - - if (!PyMapping_Check(spec)) { - PyErr_SetString(PyExc_TypeError, - "Filter specifier must be a dict or dict-like object"); - return 0; - } - id_obj = PyMapping_GetItemString(spec, "id"); - if (id_obj == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_SetString(PyExc_ValueError, - "Filter specifier must have an \"id\" entry"); - return 0; - } - f->id = PyLong_AsUnsignedLongLong(id_obj); - Py_DECREF(id_obj); - if (PyErr_Occurred()) - return 0; - - switch (f->id) { - case LZMA_FILTER_LZMA1: - case LZMA_FILTER_LZMA2: - f->options = parse_filter_spec_lzma(spec); - return f->options != NULL; - case LZMA_FILTER_DELTA: - f->options = parse_filter_spec_delta(spec); - return f->options != NULL; - case LZMA_FILTER_X86: - case LZMA_FILTER_POWERPC: - case LZMA_FILTER_IA64: - case LZMA_FILTER_ARM: - case LZMA_FILTER_ARMTHUMB: - case LZMA_FILTER_SPARC: - f->options = parse_filter_spec_bcj(spec); - return f->options != NULL; - default: - PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id); - return 0; - } -} - -static void -free_filter_chain(lzma_filter filters[]) -{ - int i; - - for (i = 0; filters[i].id != LZMA_VLI_UNKNOWN; i++) - PyMem_Free(filters[i].options); -} - -static int -parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs) -{ - Py_ssize_t i, num_filters; - - num_filters = PySequence_Length(filterspecs); - if (num_filters == -1) - return -1; - if (num_filters > LZMA_FILTERS_MAX) { - PyErr_Format(PyExc_ValueError, - "Too many filters - liblzma supports a maximum of %d", - LZMA_FILTERS_MAX); - return -1; - } - - for (i = 0; i < num_filters; i++) { - int ok = 1; - PyObject *spec = PySequence_GetItem(filterspecs, i); - if (spec == NULL || !lzma_filter_converter(spec, &filters[i])) - ok = 0; - Py_XDECREF(spec); - if (!ok) { - filters[i].id = LZMA_VLI_UNKNOWN; - free_filter_chain(filters); - return -1; - } - } - filters[num_filters].id = LZMA_VLI_UNKNOWN; - return 0; -} - - -/* Filter specifier construction. - - This code handles converting C lzma_filter structs into - Python-level filter specifiers (represented as dicts). */ - -static int -spec_add_field(PyObject *spec, _Py_Identifier *key, unsigned long long value) -{ - int status; - PyObject *value_object; - - value_object = PyLong_FromUnsignedLongLong(value); - if (value_object == NULL) - return -1; - - status = _PyDict_SetItemId(spec, key, value_object); - Py_DECREF(value_object); - return status; -} - -static PyObject * -build_filter_spec(const lzma_filter *f) -{ - PyObject *spec; - - spec = PyDict_New(); - if (spec == NULL) - return NULL; - -#define ADD_FIELD(SOURCE, FIELD) \ - do { \ - _Py_IDENTIFIER(FIELD); \ - if (spec_add_field(spec, &PyId_##FIELD, SOURCE->FIELD) == -1) \ - goto error;\ - } while (0) - - ADD_FIELD(f, id); - - switch (f->id) { - /* For LZMA1 filters, lzma_properties_{encode,decode}() only look at the - lc, lp, pb, and dict_size fields. For LZMA2 filters, only the - dict_size field is used. */ - case LZMA_FILTER_LZMA1: { - lzma_options_lzma *options = f->options; - ADD_FIELD(options, lc); - ADD_FIELD(options, lp); - ADD_FIELD(options, pb); - ADD_FIELD(options, dict_size); - break; - } - case LZMA_FILTER_LZMA2: { - lzma_options_lzma *options = f->options; - ADD_FIELD(options, dict_size); - break; - } - case LZMA_FILTER_DELTA: { - lzma_options_delta *options = f->options; - ADD_FIELD(options, dist); - break; - } - case LZMA_FILTER_X86: - case LZMA_FILTER_POWERPC: - case LZMA_FILTER_IA64: - case LZMA_FILTER_ARM: - case LZMA_FILTER_ARMTHUMB: - case LZMA_FILTER_SPARC: { - lzma_options_bcj *options = f->options; - ADD_FIELD(options, start_offset); - break; - } - default: - PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id); - goto error; - } - -#undef ADD_FIELD - - return spec; - -error: - Py_DECREF(spec); - return NULL; -} - - -/*[clinic input] -module _lzma -class _lzma.LZMACompressor "Compressor *" "&Compressor_type" -class _lzma.LZMADecompressor "Decompressor *" "&Decompressor_type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2c14bbe05ff0c147]*/ - -#include "clinic/_lzmamodule.c.h" - -/*[python input] - -class lzma_vli_converter(CConverter): - type = 'lzma_vli' - converter = 'lzma_vli_converter' - -class lzma_filter_converter(CConverter): - type = 'lzma_filter' - converter = 'lzma_filter_converter' - c_default = c_ignored_default = "{LZMA_VLI_UNKNOWN, NULL}" - - def cleanup(self): - name = ensure_legal_c_identifier(self.name) - return ('if (%(name)s.id != LZMA_VLI_UNKNOWN)\n' - ' PyMem_Free(%(name)s.options);\n') % {'name': name} - -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=74fe7631ce377a94]*/ - - -/* LZMACompressor class. */ - -static PyObject * -compress(Compressor *c, uint8_t *data, size_t len, lzma_action action) -{ - Py_ssize_t data_size = 0; - PyObject *result; - - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); - if (result == NULL) - return NULL; - c->lzs.next_in = data; - c->lzs.avail_in = len; - c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result); - c->lzs.avail_out = PyBytes_GET_SIZE(result); - for (;;) { - lzma_ret lzret; - - Py_BEGIN_ALLOW_THREADS - lzret = lzma_code(&c->lzs, action); - data_size = (char *)c->lzs.next_out - PyBytes_AS_STRING(result); - if (lzret == LZMA_BUF_ERROR && len == 0 && c->lzs.avail_out > 0) - lzret = LZMA_OK; /* That wasn't a real error */ - Py_END_ALLOW_THREADS - if (catch_lzma_error(lzret)) - goto error; - if ((action == LZMA_RUN && c->lzs.avail_in == 0) || - (action == LZMA_FINISH && lzret == LZMA_STREAM_END)) { - break; - } else if (c->lzs.avail_out == 0) { - if (grow_buffer(&result, -1) == -1) - goto error; - c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; - c->lzs.avail_out = PyBytes_GET_SIZE(result) - data_size; - } - } - if (data_size != PyBytes_GET_SIZE(result)) - if (_PyBytes_Resize(&result, data_size) == -1) - goto error; - return result; - -error: - Py_XDECREF(result); - return NULL; -} - -/*[clinic input] -_lzma.LZMACompressor.compress - - data: Py_buffer - / - -Provide data to the compressor object. - -Returns a chunk of compressed data if possible, or b'' otherwise. - -When you have finished providing data to the compressor, call the -flush() method to finish the compression process. -[clinic start generated code]*/ - -static PyObject * -_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data) -/*[clinic end generated code: output=31f615136963e00f input=64019eac7f2cc8d0]*/ -{ - PyObject *result = NULL; - - ACQUIRE_LOCK(self); - if (self->flushed) - PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); - else - result = compress(self, data->buf, data->len, LZMA_RUN); - RELEASE_LOCK(self); - return result; -} - -/*[clinic input] -_lzma.LZMACompressor.flush - -Finish the compression process. - -Returns the compressed data left in internal buffers. - -The compressor object may not be used after this method is called. -[clinic start generated code]*/ - -static PyObject * -_lzma_LZMACompressor_flush_impl(Compressor *self) -/*[clinic end generated code: output=fec21f3e22504f50 input=6b369303f67ad0a8]*/ -{ - PyObject *result = NULL; - - ACQUIRE_LOCK(self); - if (self->flushed) { - PyErr_SetString(PyExc_ValueError, "Repeated call to flush()"); - } else { - self->flushed = 1; - result = compress(self, NULL, 0, LZMA_FINISH); - } - RELEASE_LOCK(self); - return result; -} - -static int -Compressor_init_xz(lzma_stream *lzs, int check, uint32_t preset, - PyObject *filterspecs) -{ - lzma_ret lzret; - - if (filterspecs == Py_None) { - lzret = lzma_easy_encoder(lzs, preset, check); - } else { - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - - if (parse_filter_chain_spec(filters, filterspecs) == -1) - return -1; - lzret = lzma_stream_encoder(lzs, filters, check); - free_filter_chain(filters); - } - if (catch_lzma_error(lzret)) - return -1; - else - return 0; -} - -static int -Compressor_init_alone(lzma_stream *lzs, uint32_t preset, PyObject *filterspecs) -{ - lzma_ret lzret; - - if (filterspecs == Py_None) { - lzma_options_lzma options; - - if (lzma_lzma_preset(&options, preset)) { - PyErr_Format(Error, "Invalid compression preset: %u", preset); - return -1; - } - lzret = lzma_alone_encoder(lzs, &options); - } else { - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - - if (parse_filter_chain_spec(filters, filterspecs) == -1) - return -1; - if (filters[0].id == LZMA_FILTER_LZMA1 && - filters[1].id == LZMA_VLI_UNKNOWN) { - lzret = lzma_alone_encoder(lzs, filters[0].options); - } else { - PyErr_SetString(PyExc_ValueError, - "Invalid filter chain for FORMAT_ALONE - " - "must be a single LZMA1 filter"); - lzret = LZMA_PROG_ERROR; - } - free_filter_chain(filters); - } - if (PyErr_Occurred() || catch_lzma_error(lzret)) - return -1; - else - return 0; -} - -static int -Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) -{ - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - lzma_ret lzret; - - if (filterspecs == Py_None) { - PyErr_SetString(PyExc_ValueError, - "Must specify filters for FORMAT_RAW"); - return -1; - } - if (parse_filter_chain_spec(filters, filterspecs) == -1) - return -1; - lzret = lzma_raw_encoder(lzs, filters); - free_filter_chain(filters); - if (catch_lzma_error(lzret)) - return -1; - else - return 0; -} - -/*[-clinic input] -_lzma.LZMACompressor.__init__ - - format: int(c_default="FORMAT_XZ") = FORMAT_XZ - The container format to use for the output. This can - be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW. - - check: int(c_default="-1") = unspecified - The integrity check to use. For FORMAT_XZ, the default - is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not support integrity - checks; for these formats, check must be omitted, or be CHECK_NONE. - - preset: object = None - If provided should be an integer in the range 0-9, optionally - OR-ed with the constant PRESET_EXTREME. - - filters: object = None - If provided should be a sequence of dicts. Each dict should - have an entry for "id" indicating the ID of the filter, plus - additional entries for options to the filter. - -Create a compressor object for compressing data incrementally. - -The settings used by the compressor can be specified either as a -preset compression level (with the 'preset' argument), or in detail -as a custom filter chain (with the 'filters' argument). For FORMAT_XZ -and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset -level. For FORMAT_RAW, the caller must always specify a filter chain; -the raw compressor does not support preset compression levels. - -For one-shot compression, use the compress() function instead. -[-clinic start generated code]*/ -static int -Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) -{ - static char *arg_names[] = {"format", "check", "preset", "filters", NULL}; - int format = FORMAT_XZ; - int check = -1; - uint32_t preset = LZMA_PRESET_DEFAULT; - PyObject *preset_obj = Py_None; - PyObject *filterspecs = Py_None; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|iiOO:LZMACompressor", arg_names, - &format, &check, &preset_obj, - &filterspecs)) - return -1; - - if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) { - PyErr_SetString(PyExc_ValueError, - "Integrity checks are only supported by FORMAT_XZ"); - return -1; - } - - if (preset_obj != Py_None && filterspecs != Py_None) { - PyErr_SetString(PyExc_ValueError, - "Cannot specify both preset and filter chain"); - return -1; - } - - if (preset_obj != Py_None) - if (!uint32_converter(preset_obj, &preset)) - return -1; - - self->alloc.opaque = NULL; - self->alloc.alloc = PyLzma_Malloc; - self->alloc.free = PyLzma_Free; - self->lzs.allocator = &self->alloc; - - self->lock = PyThread_allocate_lock(); - if (self->lock == NULL) { - PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return -1; - } - - self->flushed = 0; - switch (format) { - case FORMAT_XZ: - if (check == -1) - check = LZMA_CHECK_CRC64; - if (Compressor_init_xz(&self->lzs, check, preset, filterspecs) != 0) - break; - return 0; - - case FORMAT_ALONE: - if (Compressor_init_alone(&self->lzs, preset, filterspecs) != 0) - break; - return 0; - - case FORMAT_RAW: - if (Compressor_init_raw(&self->lzs, filterspecs) != 0) - break; - return 0; - - default: - PyErr_Format(PyExc_ValueError, - "Invalid container format: %d", format); - break; - } - - PyThread_free_lock(self->lock); - self->lock = NULL; - return -1; -} - -static void -Compressor_dealloc(Compressor *self) -{ - lzma_end(&self->lzs); - if (self->lock != NULL) - PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyMethodDef Compressor_methods[] = { - _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF - _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF - {NULL} -}; - -PyDoc_STRVAR(Compressor_doc, -"LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)\n" -"\n" -"Create a compressor object for compressing data incrementally.\n" -"\n" -"format specifies the container format to use for the output. This can\n" -"be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.\n" -"\n" -"check specifies the integrity check to use. For FORMAT_XZ, the default\n" -"is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not support integrity\n" -"checks; for these formats, check must be omitted, or be CHECK_NONE.\n" -"\n" -"The settings used by the compressor can be specified either as a\n" -"preset compression level (with the 'preset' argument), or in detail\n" -"as a custom filter chain (with the 'filters' argument). For FORMAT_XZ\n" -"and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset\n" -"level. For FORMAT_RAW, the caller must always specify a filter chain;\n" -"the raw compressor does not support preset compression levels.\n" -"\n" -"preset (if provided) should be an integer in the range 0-9, optionally\n" -"OR-ed with the constant PRESET_EXTREME.\n" -"\n" -"filters (if provided) should be a sequence of dicts. Each dict should\n" -"have an entry for \"id\" indicating the ID of the filter, plus\n" -"additional entries for options to the filter.\n" -"\n" -"For one-shot compression, use the compress() function instead.\n"); - -static PyTypeObject Compressor_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_lzma.LZMACompressor", /* tp_name */ - sizeof(Compressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)Compressor_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - Compressor_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Compressor_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)Compressor_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/* LZMADecompressor class. */ - -/* Decompress data of length d->lzs.avail_in in d->lzs.next_in. The output - buffer is allocated dynamically and returned. At most max_length bytes are - returned, so some of the input may not be consumed. d->lzs.next_in and - d->lzs.avail_in are updated to reflect the consumed input. */ -static PyObject* -decompress_buf(Decompressor *d, Py_ssize_t max_length) -{ - Py_ssize_t data_size = 0; - PyObject *result; - lzma_stream *lzs = &d->lzs; - - if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE) - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); - else - result = PyBytes_FromStringAndSize(NULL, max_length); - if (result == NULL) - return NULL; - - lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result); - lzs->avail_out = PyBytes_GET_SIZE(result); - - for (;;) { - lzma_ret lzret; - - Py_BEGIN_ALLOW_THREADS - lzret = lzma_code(lzs, LZMA_RUN); - data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result); - if (lzret == LZMA_BUF_ERROR && lzs->avail_in == 0 && lzs->avail_out > 0) - lzret = LZMA_OK; /* That wasn't a real error */ - Py_END_ALLOW_THREADS - - if (catch_lzma_error(lzret)) - goto error; - if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK) - d->check = lzma_get_check(&d->lzs); - if (lzret == LZMA_STREAM_END) { - d->eof = 1; - break; - } else if (lzs->avail_out == 0) { - /* Need to check lzs->avail_out before lzs->avail_in. - Maybe lzs's internal state still have a few bytes - can be output, grow the output buffer and continue - if max_lengh < 0. */ - if (data_size == max_length) - break; - if (grow_buffer(&result, max_length) == -1) - goto error; - lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; - lzs->avail_out = PyBytes_GET_SIZE(result) - data_size; - } else if (lzs->avail_in == 0) { - break; - } - } - if (data_size != PyBytes_GET_SIZE(result)) - if (_PyBytes_Resize(&result, data_size) == -1) - goto error; - - return result; - -error: - Py_XDECREF(result); - return NULL; -} - -static PyObject * -decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) -{ - char input_buffer_in_use; - PyObject *result; - lzma_stream *lzs = &d->lzs; - - /* Prepend unconsumed input if necessary */ - if (lzs->next_in != NULL) { - size_t avail_now, avail_total; - - /* Number of bytes we can append to input buffer */ - avail_now = (d->input_buffer + d->input_buffer_size) - - (lzs->next_in + lzs->avail_in); - - /* Number of bytes we can append if we move existing - contents to beginning of buffer (overwriting - consumed input) */ - avail_total = d->input_buffer_size - lzs->avail_in; - - if (avail_total < len) { - size_t offset = lzs->next_in - d->input_buffer; - uint8_t *tmp; - size_t new_size = d->input_buffer_size + len - avail_now; - - /* Assign to temporary variable first, so we don't - lose address of allocated buffer if realloc fails */ - tmp = PyMem_Realloc(d->input_buffer, new_size); - if (tmp == NULL) { - PyErr_SetNone(PyExc_MemoryError); - return NULL; - } - d->input_buffer = tmp; - d->input_buffer_size = new_size; - - lzs->next_in = d->input_buffer + offset; - } - else if (avail_now < len) { - memmove(d->input_buffer, lzs->next_in, - lzs->avail_in); - lzs->next_in = d->input_buffer; - } - memcpy((void*)(lzs->next_in + lzs->avail_in), data, len); - lzs->avail_in += len; - input_buffer_in_use = 1; - } - else { - lzs->next_in = data; - lzs->avail_in = len; - input_buffer_in_use = 0; - } - - result = decompress_buf(d, max_length); - if (result == NULL) { - lzs->next_in = NULL; - return NULL; - } - - if (d->eof) { - d->needs_input = 0; - if (lzs->avail_in > 0) { - Py_XSETREF(d->unused_data, - PyBytes_FromStringAndSize((char *)lzs->next_in, lzs->avail_in)); - if (d->unused_data == NULL) - goto error; - } - } - else if (lzs->avail_in == 0) { - lzs->next_in = NULL; - - if (lzs->avail_out == 0) { - /* (avail_in==0 && avail_out==0) - Maybe lzs's internal state still have a few bytes can - be output, try to output them next time. */ - d->needs_input = 0; - - /* if max_length < 0, lzs->avail_out always > 0 */ - assert(max_length >= 0); - } else { - /* Input buffer exhausted, output buffer has space. */ - d->needs_input = 1; - } - } - else { - d->needs_input = 0; - - /* If we did not use the input buffer, we now have - to copy the tail from the caller's buffer into the - input buffer */ - if (!input_buffer_in_use) { - - /* Discard buffer if it's too small - (resizing it may needlessly copy the current contents) */ - if (d->input_buffer != NULL && - d->input_buffer_size < lzs->avail_in) { - PyMem_Free(d->input_buffer); - d->input_buffer = NULL; - } - - /* Allocate if necessary */ - if (d->input_buffer == NULL) { - d->input_buffer = PyMem_Malloc(lzs->avail_in); - if (d->input_buffer == NULL) { - PyErr_SetNone(PyExc_MemoryError); - goto error; - } - d->input_buffer_size = lzs->avail_in; - } - - /* Copy tail */ - memcpy(d->input_buffer, lzs->next_in, lzs->avail_in); - lzs->next_in = d->input_buffer; - } - } - - return result; - -error: - Py_XDECREF(result); - return NULL; -} - -/*[clinic input] -_lzma.LZMADecompressor.decompress - - data: Py_buffer - max_length: Py_ssize_t=-1 - -Decompress *data*, returning uncompressed data as bytes. - -If *max_length* is nonnegative, returns at most *max_length* bytes of -decompressed data. If this limit is reached and further output can be -produced, *self.needs_input* will be set to ``False``. In this case, the next -call to *decompress()* may provide *data* as b'' to obtain more of the output. - -If all of the input data was decompressed and returned (either because this -was less than *max_length* bytes, or because *max_length* was negative), -*self.needs_input* will be set to True. - -Attempting to decompress data after the end of stream is reached raises an -EOFError. Any data found after the end of the stream is ignored and saved in -the unused_data attribute. -[clinic start generated code]*/ - -static PyObject * -_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, - Py_ssize_t max_length) -/*[clinic end generated code: output=ef4e20ec7122241d input=60c1f135820e309d]*/ -{ - PyObject *result = NULL; - - ACQUIRE_LOCK(self); - if (self->eof) - PyErr_SetString(PyExc_EOFError, "Already at end of stream"); - else - result = decompress(self, data->buf, data->len, max_length); - RELEASE_LOCK(self); - return result; -} - -static int -Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) -{ - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - lzma_ret lzret; - - if (parse_filter_chain_spec(filters, filterspecs) == -1) - return -1; - lzret = lzma_raw_decoder(lzs, filters); - free_filter_chain(filters); - if (catch_lzma_error(lzret)) - return -1; - else - return 0; -} - -/*[clinic input] -_lzma.LZMADecompressor.__init__ - - format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO - Specifies the container format of the input stream. If this is - FORMAT_AUTO (the default), the decompressor will automatically detect - whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with - FORMAT_RAW cannot be autodetected. - - memlimit: object = None - Limit the amount of memory used by the decompressor. This will cause - decompression to fail if the input cannot be decompressed within the - given limit. - - filters: object = None - A custom filter chain. This argument is required for FORMAT_RAW, and - not accepted with any other format. When provided, this should be a - sequence of dicts, each indicating the ID and options for a single - filter. - -Create a decompressor object for decompressing data incrementally. - -For one-shot decompression, use the decompress() function instead. -[clinic start generated code]*/ - -static int -_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, - PyObject *memlimit, PyObject *filters) -/*[clinic end generated code: output=3e1821f8aa36564c input=81fe684a6c2f8a27]*/ -{ - const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK; - uint64_t memlimit_ = UINT64_MAX; - lzma_ret lzret; - - if (memlimit != Py_None) { - if (format == FORMAT_RAW) { - PyErr_SetString(PyExc_ValueError, - "Cannot specify memory limit with FORMAT_RAW"); - return -1; - } - memlimit_ = PyLong_AsUnsignedLongLong(memlimit); - if (PyErr_Occurred()) - return -1; - } - - if (format == FORMAT_RAW && filters == Py_None) { - PyErr_SetString(PyExc_ValueError, - "Must specify filters for FORMAT_RAW"); - return -1; - } else if (format != FORMAT_RAW && filters != Py_None) { - PyErr_SetString(PyExc_ValueError, - "Cannot specify filters except with FORMAT_RAW"); - return -1; - } - - self->alloc.opaque = NULL; - self->alloc.alloc = PyLzma_Malloc; - self->alloc.free = PyLzma_Free; - self->lzs.allocator = &self->alloc; - self->lzs.next_in = NULL; - - PyThread_type_lock lock = PyThread_allocate_lock(); - if (lock == NULL) { - PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return -1; - } - if (self->lock != NULL) { - PyThread_free_lock(self->lock); - } - self->lock = lock; - - self->check = LZMA_CHECK_UNKNOWN; - self->needs_input = 1; - self->input_buffer = NULL; - self->input_buffer_size = 0; - Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0)); - if (self->unused_data == NULL) - goto error; - - switch (format) { - case FORMAT_AUTO: - lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags); - if (catch_lzma_error(lzret)) - break; - return 0; - - case FORMAT_XZ: - lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags); - if (catch_lzma_error(lzret)) - break; - return 0; - - case FORMAT_ALONE: - self->check = LZMA_CHECK_NONE; - lzret = lzma_alone_decoder(&self->lzs, memlimit_); - if (catch_lzma_error(lzret)) - break; - return 0; - - case FORMAT_RAW: - self->check = LZMA_CHECK_NONE; - if (Decompressor_init_raw(&self->lzs, filters) == -1) - break; - return 0; - - default: - PyErr_Format(PyExc_ValueError, - "Invalid container format: %d", format); - break; - } - -error: - Py_CLEAR(self->unused_data); - PyThread_free_lock(self->lock); - self->lock = NULL; - return -1; -} - -static void -Decompressor_dealloc(Decompressor *self) -{ - if(self->input_buffer != NULL) - PyMem_Free(self->input_buffer); - - lzma_end(&self->lzs); - Py_CLEAR(self->unused_data); - if (self->lock != NULL) - PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyMethodDef Decompressor_methods[] = { - _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF - {NULL} -}; - -PyDoc_STRVAR(Decompressor_check_doc, -"ID of the integrity check used by the input stream."); - -PyDoc_STRVAR(Decompressor_eof_doc, -"True if the end-of-stream marker has been reached."); - -PyDoc_STRVAR(Decompressor_needs_input_doc, -"True if more input is needed before more decompressed data can be produced."); - -PyDoc_STRVAR(Decompressor_unused_data_doc, -"Data found after the end of the compressed stream."); - -static PyMemberDef Decompressor_members[] = { - {"check", T_INT, offsetof(Decompressor, check), READONLY, - Decompressor_check_doc}, - {"eof", T_BOOL, offsetof(Decompressor, eof), READONLY, - Decompressor_eof_doc}, - {"needs_input", T_BOOL, offsetof(Decompressor, needs_input), READONLY, - Decompressor_needs_input_doc}, - {"unused_data", T_OBJECT_EX, offsetof(Decompressor, unused_data), READONLY, - Decompressor_unused_data_doc}, - {NULL} -}; - -static PyTypeObject Decompressor_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_lzma.LZMADecompressor", /* tp_name */ - sizeof(Decompressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)Decompressor_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - _lzma_LZMADecompressor___init____doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - Decompressor_methods, /* tp_methods */ - Decompressor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _lzma_LZMADecompressor___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/* Module-level functions. */ - -/*[clinic input] -_lzma.is_check_supported - check_id: int - / - -Test whether the given integrity check is supported. - -Always returns True for CHECK_NONE and CHECK_CRC32. -[clinic start generated code]*/ - -static PyObject * -_lzma_is_check_supported_impl(PyObject *module, int check_id) -/*[clinic end generated code: output=e4f14ba3ce2ad0a5 input=5518297b97b2318f]*/ -{ - return PyBool_FromLong(lzma_check_is_supported(check_id)); -} - - -/*[clinic input] -_lzma._encode_filter_properties - filter: lzma_filter(c_default="{LZMA_VLI_UNKNOWN, NULL}") - / - -Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict). - -The result does not include the filter ID itself, only the options. -[clinic start generated code]*/ - -static PyObject * -_lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter) -/*[clinic end generated code: output=5c93c8e14e7be5a8 input=d4c64f1b557c77d4]*/ -{ - lzma_ret lzret; - uint32_t encoded_size; - PyObject *result = NULL; - - lzret = lzma_properties_size(&encoded_size, &filter); - if (catch_lzma_error(lzret)) - goto error; - - result = PyBytes_FromStringAndSize(NULL, encoded_size); - if (result == NULL) - goto error; - - lzret = lzma_properties_encode( - &filter, (uint8_t *)PyBytes_AS_STRING(result)); - if (catch_lzma_error(lzret)) - goto error; - - return result; - -error: - Py_XDECREF(result); - return NULL; -} - - -/*[clinic input] -_lzma._decode_filter_properties - filter_id: lzma_vli - encoded_props: Py_buffer - / - -Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict). - -The result does not include the filter ID itself, only the options. -[clinic start generated code]*/ - -static PyObject * -_lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id, - Py_buffer *encoded_props) -/*[clinic end generated code: output=714fd2ef565d5c60 input=246410800782160c]*/ -{ - lzma_filter filter; - lzma_ret lzret; - PyObject *result = NULL; - filter.id = filter_id; - - lzret = lzma_properties_decode( - &filter, NULL, encoded_props->buf, encoded_props->len); - if (catch_lzma_error(lzret)) - return NULL; - - result = build_filter_spec(&filter); - - /* We use vanilla free() here instead of PyMem_Free() - filter.options was - allocated by lzma_properties_decode() using the default allocator. */ - free(filter.options); - return result; -} - - -/* Module initialization. */ - -static PyMethodDef module_methods[] = { - _LZMA_IS_CHECK_SUPPORTED_METHODDEF - _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF - _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF - {NULL} -}; - -static PyModuleDef _lzmamodule = { - PyModuleDef_HEAD_INIT, - "_lzma", - NULL, - -1, - module_methods, - NULL, - NULL, - NULL, - NULL, -}; - -/* Some of our constants are more than 32 bits wide, so PyModule_AddIntConstant - would not work correctly on platforms with 32-bit longs. */ -static int -module_add_int_constant(PyObject *m, const char *name, long long value) -{ - PyObject *o = PyLong_FromLongLong(value); - if (o == NULL) - return -1; - if (PyModule_AddObject(m, name, o) == 0) - return 0; - Py_DECREF(o); - return -1; -} - -#define ADD_INT_PREFIX_MACRO(m, macro) \ - module_add_int_constant(m, #macro, LZMA_ ## macro) - -PyMODINIT_FUNC -PyInit__lzma(void) -{ - PyObject *m; - - empty_tuple = PyTuple_New(0); - if (empty_tuple == NULL) - return NULL; - - m = PyModule_Create(&_lzmamodule); - if (m == NULL) - return NULL; - - if (PyModule_AddIntMacro(m, FORMAT_AUTO) == -1 || - PyModule_AddIntMacro(m, FORMAT_XZ) == -1 || - PyModule_AddIntMacro(m, FORMAT_ALONE) == -1 || - PyModule_AddIntMacro(m, FORMAT_RAW) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_NONE) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_CRC32) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_CRC64) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_SHA256) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_ID_MAX) == -1 || - ADD_INT_PREFIX_MACRO(m, CHECK_UNKNOWN) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_LZMA1) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_LZMA2) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_DELTA) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_X86) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_IA64) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_ARM) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_ARMTHUMB) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_SPARC) == -1 || - ADD_INT_PREFIX_MACRO(m, FILTER_POWERPC) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_HC3) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_HC4) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_BT2) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_BT3) == -1 || - ADD_INT_PREFIX_MACRO(m, MF_BT4) == -1 || - ADD_INT_PREFIX_MACRO(m, MODE_FAST) == -1 || - ADD_INT_PREFIX_MACRO(m, MODE_NORMAL) == -1 || - ADD_INT_PREFIX_MACRO(m, PRESET_DEFAULT) == -1 || - ADD_INT_PREFIX_MACRO(m, PRESET_EXTREME) == -1) - return NULL; - - Error = PyErr_NewExceptionWithDoc( - "_lzma.LZMAError", "Call to liblzma failed.", NULL, NULL); - if (Error == NULL) - return NULL; - Py_INCREF(Error); - if (PyModule_AddObject(m, "LZMAError", Error) == -1) - return NULL; - - if (PyModule_AddType(m, &Compressor_type) < 0) { - return NULL; - } - - if (PyModule_AddType(m, &Decompressor_type) < 0) { - return NULL; - } - - return m; -} +/* _lzma - Low-level Python interface to liblzma. + + Initial implementation by Per Øyvind Karlsen. + Rewritten by Nadeem Vawda. + +*/ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "structmember.h" // PyMemberDef + +#include +#include + +#include + +#define ACQUIRE_LOCK(obj) do { \ + if (!PyThread_acquire_lock((obj)->lock, 0)) { \ + Py_BEGIN_ALLOW_THREADS \ + PyThread_acquire_lock((obj)->lock, 1); \ + Py_END_ALLOW_THREADS \ + } } while (0) +#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock) + + +/* Container formats: */ +enum { + FORMAT_AUTO, + FORMAT_XZ, + FORMAT_ALONE, + FORMAT_RAW, +}; + +#define LZMA_CHECK_UNKNOWN (LZMA_CHECK_ID_MAX + 1) + + +typedef struct { + PyObject_HEAD + lzma_allocator alloc; + lzma_stream lzs; + int flushed; + PyThread_type_lock lock; +} Compressor; + +typedef struct { + PyObject_HEAD + lzma_allocator alloc; + lzma_stream lzs; + int check; + char eof; + PyObject *unused_data; + char needs_input; + uint8_t *input_buffer; + size_t input_buffer_size; + PyThread_type_lock lock; +} Decompressor; + +/* LZMAError class object. */ +static PyObject *Error; + +/* An empty tuple, used by the filter specifier parsing code. */ +static PyObject *empty_tuple; + + +/* Helper functions. */ + +static int +catch_lzma_error(lzma_ret lzret) +{ + switch (lzret) { + case LZMA_OK: + case LZMA_GET_CHECK: + case LZMA_NO_CHECK: + case LZMA_STREAM_END: + return 0; + case LZMA_UNSUPPORTED_CHECK: + PyErr_SetString(Error, "Unsupported integrity check"); + return 1; + case LZMA_MEM_ERROR: + PyErr_NoMemory(); + return 1; + case LZMA_MEMLIMIT_ERROR: + PyErr_SetString(Error, "Memory usage limit exceeded"); + return 1; + case LZMA_FORMAT_ERROR: + PyErr_SetString(Error, "Input format not supported by decoder"); + return 1; + case LZMA_OPTIONS_ERROR: + PyErr_SetString(Error, "Invalid or unsupported options"); + return 1; + case LZMA_DATA_ERROR: + PyErr_SetString(Error, "Corrupt input data"); + return 1; + case LZMA_BUF_ERROR: + PyErr_SetString(Error, "Insufficient buffer space"); + return 1; + case LZMA_PROG_ERROR: + PyErr_SetString(Error, "Internal error"); + return 1; + default: + PyErr_Format(Error, "Unrecognized error from liblzma: %d", lzret); + return 1; + } +} + +static void* +PyLzma_Malloc(void *opaque, size_t items, size_t size) +{ + if (size != 0 && items > (size_t)PY_SSIZE_T_MAX / size) + return NULL; + /* PyMem_Malloc() cannot be used: + the GIL is not held when lzma_code() is called */ + return PyMem_RawMalloc(items * size); +} + +static void +PyLzma_Free(void *opaque, void *ptr) +{ + PyMem_RawFree(ptr); +} + +#if BUFSIZ < 8192 +#define INITIAL_BUFFER_SIZE 8192 +#else +#define INITIAL_BUFFER_SIZE BUFSIZ +#endif + +static int +grow_buffer(PyObject **buf, Py_ssize_t max_length) +{ + Py_ssize_t size = PyBytes_GET_SIZE(*buf); + Py_ssize_t newsize = size + (size >> 3) + 6; + + if (max_length > 0 && newsize > max_length) + newsize = max_length; + + return _PyBytes_Resize(buf, newsize); +} + + +/* Some custom type conversions for PyArg_ParseTupleAndKeywords(), + since the predefined conversion specifiers do not suit our needs: + + uint32_t - the "I" (unsigned int) specifier is the right size, but + silently ignores overflows on conversion. + + lzma_vli - the "K" (unsigned long long) specifier is the right + size, but like "I" it silently ignores overflows on conversion. + + lzma_mode and lzma_match_finder - these are enumeration types, and + so the size of each is implementation-defined. Worse, different + enum types can be of different sizes within the same program, so + to be strictly correct, we need to define two separate converters. + */ + +#define INT_TYPE_CONVERTER_FUNC(TYPE, FUNCNAME) \ + static int \ + FUNCNAME(PyObject *obj, void *ptr) \ + { \ + unsigned long long val; \ + \ + val = PyLong_AsUnsignedLongLong(obj); \ + if (PyErr_Occurred()) \ + return 0; \ + if ((unsigned long long)(TYPE)val != val) { \ + PyErr_SetString(PyExc_OverflowError, \ + "Value too large for " #TYPE " type"); \ + return 0; \ + } \ + *(TYPE *)ptr = (TYPE)val; \ + return 1; \ + } + +INT_TYPE_CONVERTER_FUNC(uint32_t, uint32_converter) +INT_TYPE_CONVERTER_FUNC(lzma_vli, lzma_vli_converter) +INT_TYPE_CONVERTER_FUNC(lzma_mode, lzma_mode_converter) +INT_TYPE_CONVERTER_FUNC(lzma_match_finder, lzma_mf_converter) + +#undef INT_TYPE_CONVERTER_FUNC + + +/* Filter specifier parsing. + + This code handles converting filter specifiers (Python dicts) into + the C lzma_filter structs expected by liblzma. */ + +static void * +parse_filter_spec_lzma(PyObject *spec) +{ + static char *optnames[] = {"id", "preset", "dict_size", "lc", "lp", + "pb", "mode", "nice_len", "mf", "depth", NULL}; + PyObject *id; + PyObject *preset_obj; + uint32_t preset = LZMA_PRESET_DEFAULT; + lzma_options_lzma *options; + + /* First, fill in default values for all the options using a preset. + Then, override the defaults with any values given by the caller. */ + + preset_obj = PyMapping_GetItemString(spec, "preset"); + if (preset_obj == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_Clear(); + else + return NULL; + } else { + int ok = uint32_converter(preset_obj, &preset); + Py_DECREF(preset_obj); + if (!ok) + return NULL; + } + + options = (lzma_options_lzma *)PyMem_Calloc(1, sizeof *options); + if (options == NULL) + return PyErr_NoMemory(); + + if (lzma_lzma_preset(options, preset)) { + PyMem_Free(options); + PyErr_Format(Error, "Invalid compression preset: %u", preset); + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, + "|OOO&O&O&O&O&O&O&O&", optnames, + &id, &preset_obj, + uint32_converter, &options->dict_size, + uint32_converter, &options->lc, + uint32_converter, &options->lp, + uint32_converter, &options->pb, + lzma_mode_converter, &options->mode, + uint32_converter, &options->nice_len, + lzma_mf_converter, &options->mf, + uint32_converter, &options->depth)) { + PyErr_SetString(PyExc_ValueError, + "Invalid filter specifier for LZMA filter"); + PyMem_Free(options); + options = NULL; + } + return options; +} + +static void * +parse_filter_spec_delta(PyObject *spec) +{ + static char *optnames[] = {"id", "dist", NULL}; + PyObject *id; + uint32_t dist = 1; + lzma_options_delta *options; + + if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, "|OO&", optnames, + &id, uint32_converter, &dist)) { + PyErr_SetString(PyExc_ValueError, + "Invalid filter specifier for delta filter"); + return NULL; + } + + options = (lzma_options_delta *)PyMem_Calloc(1, sizeof *options); + if (options == NULL) + return PyErr_NoMemory(); + options->type = LZMA_DELTA_TYPE_BYTE; + options->dist = dist; + return options; +} + +static void * +parse_filter_spec_bcj(PyObject *spec) +{ + static char *optnames[] = {"id", "start_offset", NULL}; + PyObject *id; + uint32_t start_offset = 0; + lzma_options_bcj *options; + + if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, "|OO&", optnames, + &id, uint32_converter, &start_offset)) { + PyErr_SetString(PyExc_ValueError, + "Invalid filter specifier for BCJ filter"); + return NULL; + } + + options = (lzma_options_bcj *)PyMem_Calloc(1, sizeof *options); + if (options == NULL) + return PyErr_NoMemory(); + options->start_offset = start_offset; + return options; +} + +static int +lzma_filter_converter(PyObject *spec, void *ptr) +{ + lzma_filter *f = (lzma_filter *)ptr; + PyObject *id_obj; + + if (!PyMapping_Check(spec)) { + PyErr_SetString(PyExc_TypeError, + "Filter specifier must be a dict or dict-like object"); + return 0; + } + id_obj = PyMapping_GetItemString(spec, "id"); + if (id_obj == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_SetString(PyExc_ValueError, + "Filter specifier must have an \"id\" entry"); + return 0; + } + f->id = PyLong_AsUnsignedLongLong(id_obj); + Py_DECREF(id_obj); + if (PyErr_Occurred()) + return 0; + + switch (f->id) { + case LZMA_FILTER_LZMA1: + case LZMA_FILTER_LZMA2: + f->options = parse_filter_spec_lzma(spec); + return f->options != NULL; + case LZMA_FILTER_DELTA: + f->options = parse_filter_spec_delta(spec); + return f->options != NULL; + case LZMA_FILTER_X86: + case LZMA_FILTER_POWERPC: + case LZMA_FILTER_IA64: + case LZMA_FILTER_ARM: + case LZMA_FILTER_ARMTHUMB: + case LZMA_FILTER_SPARC: + f->options = parse_filter_spec_bcj(spec); + return f->options != NULL; + default: + PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id); + return 0; + } +} + +static void +free_filter_chain(lzma_filter filters[]) +{ + int i; + + for (i = 0; filters[i].id != LZMA_VLI_UNKNOWN; i++) + PyMem_Free(filters[i].options); +} + +static int +parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs) +{ + Py_ssize_t i, num_filters; + + num_filters = PySequence_Length(filterspecs); + if (num_filters == -1) + return -1; + if (num_filters > LZMA_FILTERS_MAX) { + PyErr_Format(PyExc_ValueError, + "Too many filters - liblzma supports a maximum of %d", + LZMA_FILTERS_MAX); + return -1; + } + + for (i = 0; i < num_filters; i++) { + int ok = 1; + PyObject *spec = PySequence_GetItem(filterspecs, i); + if (spec == NULL || !lzma_filter_converter(spec, &filters[i])) + ok = 0; + Py_XDECREF(spec); + if (!ok) { + filters[i].id = LZMA_VLI_UNKNOWN; + free_filter_chain(filters); + return -1; + } + } + filters[num_filters].id = LZMA_VLI_UNKNOWN; + return 0; +} + + +/* Filter specifier construction. + + This code handles converting C lzma_filter structs into + Python-level filter specifiers (represented as dicts). */ + +static int +spec_add_field(PyObject *spec, _Py_Identifier *key, unsigned long long value) +{ + int status; + PyObject *value_object; + + value_object = PyLong_FromUnsignedLongLong(value); + if (value_object == NULL) + return -1; + + status = _PyDict_SetItemId(spec, key, value_object); + Py_DECREF(value_object); + return status; +} + +static PyObject * +build_filter_spec(const lzma_filter *f) +{ + PyObject *spec; + + spec = PyDict_New(); + if (spec == NULL) + return NULL; + +#define ADD_FIELD(SOURCE, FIELD) \ + do { \ + _Py_IDENTIFIER(FIELD); \ + if (spec_add_field(spec, &PyId_##FIELD, SOURCE->FIELD) == -1) \ + goto error;\ + } while (0) + + ADD_FIELD(f, id); + + switch (f->id) { + /* For LZMA1 filters, lzma_properties_{encode,decode}() only look at the + lc, lp, pb, and dict_size fields. For LZMA2 filters, only the + dict_size field is used. */ + case LZMA_FILTER_LZMA1: { + lzma_options_lzma *options = f->options; + ADD_FIELD(options, lc); + ADD_FIELD(options, lp); + ADD_FIELD(options, pb); + ADD_FIELD(options, dict_size); + break; + } + case LZMA_FILTER_LZMA2: { + lzma_options_lzma *options = f->options; + ADD_FIELD(options, dict_size); + break; + } + case LZMA_FILTER_DELTA: { + lzma_options_delta *options = f->options; + ADD_FIELD(options, dist); + break; + } + case LZMA_FILTER_X86: + case LZMA_FILTER_POWERPC: + case LZMA_FILTER_IA64: + case LZMA_FILTER_ARM: + case LZMA_FILTER_ARMTHUMB: + case LZMA_FILTER_SPARC: { + lzma_options_bcj *options = f->options; + ADD_FIELD(options, start_offset); + break; + } + default: + PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id); + goto error; + } + +#undef ADD_FIELD + + return spec; + +error: + Py_DECREF(spec); + return NULL; +} + + +/*[clinic input] +module _lzma +class _lzma.LZMACompressor "Compressor *" "&Compressor_type" +class _lzma.LZMADecompressor "Decompressor *" "&Decompressor_type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2c14bbe05ff0c147]*/ + +#include "clinic/_lzmamodule.c.h" + +/*[python input] + +class lzma_vli_converter(CConverter): + type = 'lzma_vli' + converter = 'lzma_vli_converter' + +class lzma_filter_converter(CConverter): + type = 'lzma_filter' + converter = 'lzma_filter_converter' + c_default = c_ignored_default = "{LZMA_VLI_UNKNOWN, NULL}" + + def cleanup(self): + name = ensure_legal_c_identifier(self.name) + return ('if (%(name)s.id != LZMA_VLI_UNKNOWN)\n' + ' PyMem_Free(%(name)s.options);\n') % {'name': name} + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=74fe7631ce377a94]*/ + + +/* LZMACompressor class. */ + +static PyObject * +compress(Compressor *c, uint8_t *data, size_t len, lzma_action action) +{ + Py_ssize_t data_size = 0; + PyObject *result; + + result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); + if (result == NULL) + return NULL; + c->lzs.next_in = data; + c->lzs.avail_in = len; + c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result); + c->lzs.avail_out = PyBytes_GET_SIZE(result); + for (;;) { + lzma_ret lzret; + + Py_BEGIN_ALLOW_THREADS + lzret = lzma_code(&c->lzs, action); + data_size = (char *)c->lzs.next_out - PyBytes_AS_STRING(result); + if (lzret == LZMA_BUF_ERROR && len == 0 && c->lzs.avail_out > 0) + lzret = LZMA_OK; /* That wasn't a real error */ + Py_END_ALLOW_THREADS + if (catch_lzma_error(lzret)) + goto error; + if ((action == LZMA_RUN && c->lzs.avail_in == 0) || + (action == LZMA_FINISH && lzret == LZMA_STREAM_END)) { + break; + } else if (c->lzs.avail_out == 0) { + if (grow_buffer(&result, -1) == -1) + goto error; + c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; + c->lzs.avail_out = PyBytes_GET_SIZE(result) - data_size; + } + } + if (data_size != PyBytes_GET_SIZE(result)) + if (_PyBytes_Resize(&result, data_size) == -1) + goto error; + return result; + +error: + Py_XDECREF(result); + return NULL; +} + +/*[clinic input] +_lzma.LZMACompressor.compress + + data: Py_buffer + / + +Provide data to the compressor object. + +Returns a chunk of compressed data if possible, or b'' otherwise. + +When you have finished providing data to the compressor, call the +flush() method to finish the compression process. +[clinic start generated code]*/ + +static PyObject * +_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data) +/*[clinic end generated code: output=31f615136963e00f input=64019eac7f2cc8d0]*/ +{ + PyObject *result = NULL; + + ACQUIRE_LOCK(self); + if (self->flushed) + PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); + else + result = compress(self, data->buf, data->len, LZMA_RUN); + RELEASE_LOCK(self); + return result; +} + +/*[clinic input] +_lzma.LZMACompressor.flush + +Finish the compression process. + +Returns the compressed data left in internal buffers. + +The compressor object may not be used after this method is called. +[clinic start generated code]*/ + +static PyObject * +_lzma_LZMACompressor_flush_impl(Compressor *self) +/*[clinic end generated code: output=fec21f3e22504f50 input=6b369303f67ad0a8]*/ +{ + PyObject *result = NULL; + + ACQUIRE_LOCK(self); + if (self->flushed) { + PyErr_SetString(PyExc_ValueError, "Repeated call to flush()"); + } else { + self->flushed = 1; + result = compress(self, NULL, 0, LZMA_FINISH); + } + RELEASE_LOCK(self); + return result; +} + +static int +Compressor_init_xz(lzma_stream *lzs, int check, uint32_t preset, + PyObject *filterspecs) +{ + lzma_ret lzret; + + if (filterspecs == Py_None) { + lzret = lzma_easy_encoder(lzs, preset, check); + } else { + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + + if (parse_filter_chain_spec(filters, filterspecs) == -1) + return -1; + lzret = lzma_stream_encoder(lzs, filters, check); + free_filter_chain(filters); + } + if (catch_lzma_error(lzret)) + return -1; + else + return 0; +} + +static int +Compressor_init_alone(lzma_stream *lzs, uint32_t preset, PyObject *filterspecs) +{ + lzma_ret lzret; + + if (filterspecs == Py_None) { + lzma_options_lzma options; + + if (lzma_lzma_preset(&options, preset)) { + PyErr_Format(Error, "Invalid compression preset: %u", preset); + return -1; + } + lzret = lzma_alone_encoder(lzs, &options); + } else { + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + + if (parse_filter_chain_spec(filters, filterspecs) == -1) + return -1; + if (filters[0].id == LZMA_FILTER_LZMA1 && + filters[1].id == LZMA_VLI_UNKNOWN) { + lzret = lzma_alone_encoder(lzs, filters[0].options); + } else { + PyErr_SetString(PyExc_ValueError, + "Invalid filter chain for FORMAT_ALONE - " + "must be a single LZMA1 filter"); + lzret = LZMA_PROG_ERROR; + } + free_filter_chain(filters); + } + if (PyErr_Occurred() || catch_lzma_error(lzret)) + return -1; + else + return 0; +} + +static int +Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) +{ + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + lzma_ret lzret; + + if (filterspecs == Py_None) { + PyErr_SetString(PyExc_ValueError, + "Must specify filters for FORMAT_RAW"); + return -1; + } + if (parse_filter_chain_spec(filters, filterspecs) == -1) + return -1; + lzret = lzma_raw_encoder(lzs, filters); + free_filter_chain(filters); + if (catch_lzma_error(lzret)) + return -1; + else + return 0; +} + +/*[-clinic input] +_lzma.LZMACompressor.__init__ + + format: int(c_default="FORMAT_XZ") = FORMAT_XZ + The container format to use for the output. This can + be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW. + + check: int(c_default="-1") = unspecified + The integrity check to use. For FORMAT_XZ, the default + is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not support integrity + checks; for these formats, check must be omitted, or be CHECK_NONE. + + preset: object = None + If provided should be an integer in the range 0-9, optionally + OR-ed with the constant PRESET_EXTREME. + + filters: object = None + If provided should be a sequence of dicts. Each dict should + have an entry for "id" indicating the ID of the filter, plus + additional entries for options to the filter. + +Create a compressor object for compressing data incrementally. + +The settings used by the compressor can be specified either as a +preset compression level (with the 'preset' argument), or in detail +as a custom filter chain (with the 'filters' argument). For FORMAT_XZ +and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset +level. For FORMAT_RAW, the caller must always specify a filter chain; +the raw compressor does not support preset compression levels. + +For one-shot compression, use the compress() function instead. +[-clinic start generated code]*/ +static int +Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) +{ + static char *arg_names[] = {"format", "check", "preset", "filters", NULL}; + int format = FORMAT_XZ; + int check = -1; + uint32_t preset = LZMA_PRESET_DEFAULT; + PyObject *preset_obj = Py_None; + PyObject *filterspecs = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|iiOO:LZMACompressor", arg_names, + &format, &check, &preset_obj, + &filterspecs)) + return -1; + + if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) { + PyErr_SetString(PyExc_ValueError, + "Integrity checks are only supported by FORMAT_XZ"); + return -1; + } + + if (preset_obj != Py_None && filterspecs != Py_None) { + PyErr_SetString(PyExc_ValueError, + "Cannot specify both preset and filter chain"); + return -1; + } + + if (preset_obj != Py_None) + if (!uint32_converter(preset_obj, &preset)) + return -1; + + self->alloc.opaque = NULL; + self->alloc.alloc = PyLzma_Malloc; + self->alloc.free = PyLzma_Free; + self->lzs.allocator = &self->alloc; + + self->lock = PyThread_allocate_lock(); + if (self->lock == NULL) { + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + return -1; + } + + self->flushed = 0; + switch (format) { + case FORMAT_XZ: + if (check == -1) + check = LZMA_CHECK_CRC64; + if (Compressor_init_xz(&self->lzs, check, preset, filterspecs) != 0) + break; + return 0; + + case FORMAT_ALONE: + if (Compressor_init_alone(&self->lzs, preset, filterspecs) != 0) + break; + return 0; + + case FORMAT_RAW: + if (Compressor_init_raw(&self->lzs, filterspecs) != 0) + break; + return 0; + + default: + PyErr_Format(PyExc_ValueError, + "Invalid container format: %d", format); + break; + } + + PyThread_free_lock(self->lock); + self->lock = NULL; + return -1; +} + +static void +Compressor_dealloc(Compressor *self) +{ + lzma_end(&self->lzs); + if (self->lock != NULL) + PyThread_free_lock(self->lock); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyMethodDef Compressor_methods[] = { + _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF + _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF + {NULL} +}; + +PyDoc_STRVAR(Compressor_doc, +"LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)\n" +"\n" +"Create a compressor object for compressing data incrementally.\n" +"\n" +"format specifies the container format to use for the output. This can\n" +"be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.\n" +"\n" +"check specifies the integrity check to use. For FORMAT_XZ, the default\n" +"is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not support integrity\n" +"checks; for these formats, check must be omitted, or be CHECK_NONE.\n" +"\n" +"The settings used by the compressor can be specified either as a\n" +"preset compression level (with the 'preset' argument), or in detail\n" +"as a custom filter chain (with the 'filters' argument). For FORMAT_XZ\n" +"and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset\n" +"level. For FORMAT_RAW, the caller must always specify a filter chain;\n" +"the raw compressor does not support preset compression levels.\n" +"\n" +"preset (if provided) should be an integer in the range 0-9, optionally\n" +"OR-ed with the constant PRESET_EXTREME.\n" +"\n" +"filters (if provided) should be a sequence of dicts. Each dict should\n" +"have an entry for \"id\" indicating the ID of the filter, plus\n" +"additional entries for options to the filter.\n" +"\n" +"For one-shot compression, use the compress() function instead.\n"); + +static PyTypeObject Compressor_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_lzma.LZMACompressor", /* tp_name */ + sizeof(Compressor), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)Compressor_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + Compressor_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Compressor_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Compressor_init, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + + +/* LZMADecompressor class. */ + +/* Decompress data of length d->lzs.avail_in in d->lzs.next_in. The output + buffer is allocated dynamically and returned. At most max_length bytes are + returned, so some of the input may not be consumed. d->lzs.next_in and + d->lzs.avail_in are updated to reflect the consumed input. */ +static PyObject* +decompress_buf(Decompressor *d, Py_ssize_t max_length) +{ + Py_ssize_t data_size = 0; + PyObject *result; + lzma_stream *lzs = &d->lzs; + + if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE) + result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); + else + result = PyBytes_FromStringAndSize(NULL, max_length); + if (result == NULL) + return NULL; + + lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result); + lzs->avail_out = PyBytes_GET_SIZE(result); + + for (;;) { + lzma_ret lzret; + + Py_BEGIN_ALLOW_THREADS + lzret = lzma_code(lzs, LZMA_RUN); + data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result); + if (lzret == LZMA_BUF_ERROR && lzs->avail_in == 0 && lzs->avail_out > 0) + lzret = LZMA_OK; /* That wasn't a real error */ + Py_END_ALLOW_THREADS + + if (catch_lzma_error(lzret)) + goto error; + if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK) + d->check = lzma_get_check(&d->lzs); + if (lzret == LZMA_STREAM_END) { + d->eof = 1; + break; + } else if (lzs->avail_out == 0) { + /* Need to check lzs->avail_out before lzs->avail_in. + Maybe lzs's internal state still have a few bytes + can be output, grow the output buffer and continue + if max_lengh < 0. */ + if (data_size == max_length) + break; + if (grow_buffer(&result, max_length) == -1) + goto error; + lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; + lzs->avail_out = PyBytes_GET_SIZE(result) - data_size; + } else if (lzs->avail_in == 0) { + break; + } + } + if (data_size != PyBytes_GET_SIZE(result)) + if (_PyBytes_Resize(&result, data_size) == -1) + goto error; + + return result; + +error: + Py_XDECREF(result); + return NULL; +} + +static PyObject * +decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) +{ + char input_buffer_in_use; + PyObject *result; + lzma_stream *lzs = &d->lzs; + + /* Prepend unconsumed input if necessary */ + if (lzs->next_in != NULL) { + size_t avail_now, avail_total; + + /* Number of bytes we can append to input buffer */ + avail_now = (d->input_buffer + d->input_buffer_size) + - (lzs->next_in + lzs->avail_in); + + /* Number of bytes we can append if we move existing + contents to beginning of buffer (overwriting + consumed input) */ + avail_total = d->input_buffer_size - lzs->avail_in; + + if (avail_total < len) { + size_t offset = lzs->next_in - d->input_buffer; + uint8_t *tmp; + size_t new_size = d->input_buffer_size + len - avail_now; + + /* Assign to temporary variable first, so we don't + lose address of allocated buffer if realloc fails */ + tmp = PyMem_Realloc(d->input_buffer, new_size); + if (tmp == NULL) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } + d->input_buffer = tmp; + d->input_buffer_size = new_size; + + lzs->next_in = d->input_buffer + offset; + } + else if (avail_now < len) { + memmove(d->input_buffer, lzs->next_in, + lzs->avail_in); + lzs->next_in = d->input_buffer; + } + memcpy((void*)(lzs->next_in + lzs->avail_in), data, len); + lzs->avail_in += len; + input_buffer_in_use = 1; + } + else { + lzs->next_in = data; + lzs->avail_in = len; + input_buffer_in_use = 0; + } + + result = decompress_buf(d, max_length); + if (result == NULL) { + lzs->next_in = NULL; + return NULL; + } + + if (d->eof) { + d->needs_input = 0; + if (lzs->avail_in > 0) { + Py_XSETREF(d->unused_data, + PyBytes_FromStringAndSize((char *)lzs->next_in, lzs->avail_in)); + if (d->unused_data == NULL) + goto error; + } + } + else if (lzs->avail_in == 0) { + lzs->next_in = NULL; + + if (lzs->avail_out == 0) { + /* (avail_in==0 && avail_out==0) + Maybe lzs's internal state still have a few bytes can + be output, try to output them next time. */ + d->needs_input = 0; + + /* if max_length < 0, lzs->avail_out always > 0 */ + assert(max_length >= 0); + } else { + /* Input buffer exhausted, output buffer has space. */ + d->needs_input = 1; + } + } + else { + d->needs_input = 0; + + /* If we did not use the input buffer, we now have + to copy the tail from the caller's buffer into the + input buffer */ + if (!input_buffer_in_use) { + + /* Discard buffer if it's too small + (resizing it may needlessly copy the current contents) */ + if (d->input_buffer != NULL && + d->input_buffer_size < lzs->avail_in) { + PyMem_Free(d->input_buffer); + d->input_buffer = NULL; + } + + /* Allocate if necessary */ + if (d->input_buffer == NULL) { + d->input_buffer = PyMem_Malloc(lzs->avail_in); + if (d->input_buffer == NULL) { + PyErr_SetNone(PyExc_MemoryError); + goto error; + } + d->input_buffer_size = lzs->avail_in; + } + + /* Copy tail */ + memcpy(d->input_buffer, lzs->next_in, lzs->avail_in); + lzs->next_in = d->input_buffer; + } + } + + return result; + +error: + Py_XDECREF(result); + return NULL; +} + +/*[clinic input] +_lzma.LZMADecompressor.decompress + + data: Py_buffer + max_length: Py_ssize_t=-1 + +Decompress *data*, returning uncompressed data as bytes. + +If *max_length* is nonnegative, returns at most *max_length* bytes of +decompressed data. If this limit is reached and further output can be +produced, *self.needs_input* will be set to ``False``. In this case, the next +call to *decompress()* may provide *data* as b'' to obtain more of the output. + +If all of the input data was decompressed and returned (either because this +was less than *max_length* bytes, or because *max_length* was negative), +*self.needs_input* will be set to True. + +Attempting to decompress data after the end of stream is reached raises an +EOFError. Any data found after the end of the stream is ignored and saved in +the unused_data attribute. +[clinic start generated code]*/ + +static PyObject * +_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, + Py_ssize_t max_length) +/*[clinic end generated code: output=ef4e20ec7122241d input=60c1f135820e309d]*/ +{ + PyObject *result = NULL; + + ACQUIRE_LOCK(self); + if (self->eof) + PyErr_SetString(PyExc_EOFError, "Already at end of stream"); + else + result = decompress(self, data->buf, data->len, max_length); + RELEASE_LOCK(self); + return result; +} + +static int +Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) +{ + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + lzma_ret lzret; + + if (parse_filter_chain_spec(filters, filterspecs) == -1) + return -1; + lzret = lzma_raw_decoder(lzs, filters); + free_filter_chain(filters); + if (catch_lzma_error(lzret)) + return -1; + else + return 0; +} + +/*[clinic input] +_lzma.LZMADecompressor.__init__ + + format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO + Specifies the container format of the input stream. If this is + FORMAT_AUTO (the default), the decompressor will automatically detect + whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with + FORMAT_RAW cannot be autodetected. + + memlimit: object = None + Limit the amount of memory used by the decompressor. This will cause + decompression to fail if the input cannot be decompressed within the + given limit. + + filters: object = None + A custom filter chain. This argument is required for FORMAT_RAW, and + not accepted with any other format. When provided, this should be a + sequence of dicts, each indicating the ID and options for a single + filter. + +Create a decompressor object for decompressing data incrementally. + +For one-shot decompression, use the decompress() function instead. +[clinic start generated code]*/ + +static int +_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, + PyObject *memlimit, PyObject *filters) +/*[clinic end generated code: output=3e1821f8aa36564c input=81fe684a6c2f8a27]*/ +{ + const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK; + uint64_t memlimit_ = UINT64_MAX; + lzma_ret lzret; + + if (memlimit != Py_None) { + if (format == FORMAT_RAW) { + PyErr_SetString(PyExc_ValueError, + "Cannot specify memory limit with FORMAT_RAW"); + return -1; + } + memlimit_ = PyLong_AsUnsignedLongLong(memlimit); + if (PyErr_Occurred()) + return -1; + } + + if (format == FORMAT_RAW && filters == Py_None) { + PyErr_SetString(PyExc_ValueError, + "Must specify filters for FORMAT_RAW"); + return -1; + } else if (format != FORMAT_RAW && filters != Py_None) { + PyErr_SetString(PyExc_ValueError, + "Cannot specify filters except with FORMAT_RAW"); + return -1; + } + + self->alloc.opaque = NULL; + self->alloc.alloc = PyLzma_Malloc; + self->alloc.free = PyLzma_Free; + self->lzs.allocator = &self->alloc; + self->lzs.next_in = NULL; + + PyThread_type_lock lock = PyThread_allocate_lock(); + if (lock == NULL) { + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + return -1; + } + if (self->lock != NULL) { + PyThread_free_lock(self->lock); + } + self->lock = lock; + + self->check = LZMA_CHECK_UNKNOWN; + self->needs_input = 1; + self->input_buffer = NULL; + self->input_buffer_size = 0; + Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0)); + if (self->unused_data == NULL) + goto error; + + switch (format) { + case FORMAT_AUTO: + lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags); + if (catch_lzma_error(lzret)) + break; + return 0; + + case FORMAT_XZ: + lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags); + if (catch_lzma_error(lzret)) + break; + return 0; + + case FORMAT_ALONE: + self->check = LZMA_CHECK_NONE; + lzret = lzma_alone_decoder(&self->lzs, memlimit_); + if (catch_lzma_error(lzret)) + break; + return 0; + + case FORMAT_RAW: + self->check = LZMA_CHECK_NONE; + if (Decompressor_init_raw(&self->lzs, filters) == -1) + break; + return 0; + + default: + PyErr_Format(PyExc_ValueError, + "Invalid container format: %d", format); + break; + } + +error: + Py_CLEAR(self->unused_data); + PyThread_free_lock(self->lock); + self->lock = NULL; + return -1; +} + +static void +Decompressor_dealloc(Decompressor *self) +{ + if(self->input_buffer != NULL) + PyMem_Free(self->input_buffer); + + lzma_end(&self->lzs); + Py_CLEAR(self->unused_data); + if (self->lock != NULL) + PyThread_free_lock(self->lock); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyMethodDef Decompressor_methods[] = { + _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF + {NULL} +}; + +PyDoc_STRVAR(Decompressor_check_doc, +"ID of the integrity check used by the input stream."); + +PyDoc_STRVAR(Decompressor_eof_doc, +"True if the end-of-stream marker has been reached."); + +PyDoc_STRVAR(Decompressor_needs_input_doc, +"True if more input is needed before more decompressed data can be produced."); + +PyDoc_STRVAR(Decompressor_unused_data_doc, +"Data found after the end of the compressed stream."); + +static PyMemberDef Decompressor_members[] = { + {"check", T_INT, offsetof(Decompressor, check), READONLY, + Decompressor_check_doc}, + {"eof", T_BOOL, offsetof(Decompressor, eof), READONLY, + Decompressor_eof_doc}, + {"needs_input", T_BOOL, offsetof(Decompressor, needs_input), READONLY, + Decompressor_needs_input_doc}, + {"unused_data", T_OBJECT_EX, offsetof(Decompressor, unused_data), READONLY, + Decompressor_unused_data_doc}, + {NULL} +}; + +static PyTypeObject Decompressor_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_lzma.LZMADecompressor", /* tp_name */ + sizeof(Decompressor), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)Decompressor_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + _lzma_LZMADecompressor___init____doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Decompressor_methods, /* tp_methods */ + Decompressor_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + _lzma_LZMADecompressor___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + + +/* Module-level functions. */ + +/*[clinic input] +_lzma.is_check_supported + check_id: int + / + +Test whether the given integrity check is supported. + +Always returns True for CHECK_NONE and CHECK_CRC32. +[clinic start generated code]*/ + +static PyObject * +_lzma_is_check_supported_impl(PyObject *module, int check_id) +/*[clinic end generated code: output=e4f14ba3ce2ad0a5 input=5518297b97b2318f]*/ +{ + return PyBool_FromLong(lzma_check_is_supported(check_id)); +} + + +/*[clinic input] +_lzma._encode_filter_properties + filter: lzma_filter(c_default="{LZMA_VLI_UNKNOWN, NULL}") + / + +Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict). + +The result does not include the filter ID itself, only the options. +[clinic start generated code]*/ + +static PyObject * +_lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter) +/*[clinic end generated code: output=5c93c8e14e7be5a8 input=d4c64f1b557c77d4]*/ +{ + lzma_ret lzret; + uint32_t encoded_size; + PyObject *result = NULL; + + lzret = lzma_properties_size(&encoded_size, &filter); + if (catch_lzma_error(lzret)) + goto error; + + result = PyBytes_FromStringAndSize(NULL, encoded_size); + if (result == NULL) + goto error; + + lzret = lzma_properties_encode( + &filter, (uint8_t *)PyBytes_AS_STRING(result)); + if (catch_lzma_error(lzret)) + goto error; + + return result; + +error: + Py_XDECREF(result); + return NULL; +} + + +/*[clinic input] +_lzma._decode_filter_properties + filter_id: lzma_vli + encoded_props: Py_buffer + / + +Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict). + +The result does not include the filter ID itself, only the options. +[clinic start generated code]*/ + +static PyObject * +_lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id, + Py_buffer *encoded_props) +/*[clinic end generated code: output=714fd2ef565d5c60 input=246410800782160c]*/ +{ + lzma_filter filter; + lzma_ret lzret; + PyObject *result = NULL; + filter.id = filter_id; + + lzret = lzma_properties_decode( + &filter, NULL, encoded_props->buf, encoded_props->len); + if (catch_lzma_error(lzret)) + return NULL; + + result = build_filter_spec(&filter); + + /* We use vanilla free() here instead of PyMem_Free() - filter.options was + allocated by lzma_properties_decode() using the default allocator. */ + free(filter.options); + return result; +} + + +/* Module initialization. */ + +static PyMethodDef module_methods[] = { + _LZMA_IS_CHECK_SUPPORTED_METHODDEF + _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF + _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF + {NULL} +}; + +static PyModuleDef _lzmamodule = { + PyModuleDef_HEAD_INIT, + "_lzma", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL, +}; + +/* Some of our constants are more than 32 bits wide, so PyModule_AddIntConstant + would not work correctly on platforms with 32-bit longs. */ +static int +module_add_int_constant(PyObject *m, const char *name, long long value) +{ + PyObject *o = PyLong_FromLongLong(value); + if (o == NULL) + return -1; + if (PyModule_AddObject(m, name, o) == 0) + return 0; + Py_DECREF(o); + return -1; +} + +#define ADD_INT_PREFIX_MACRO(m, macro) \ + module_add_int_constant(m, #macro, LZMA_ ## macro) + +PyMODINIT_FUNC +PyInit__lzma(void) +{ + PyObject *m; + + empty_tuple = PyTuple_New(0); + if (empty_tuple == NULL) + return NULL; + + m = PyModule_Create(&_lzmamodule); + if (m == NULL) + return NULL; + + if (PyModule_AddIntMacro(m, FORMAT_AUTO) == -1 || + PyModule_AddIntMacro(m, FORMAT_XZ) == -1 || + PyModule_AddIntMacro(m, FORMAT_ALONE) == -1 || + PyModule_AddIntMacro(m, FORMAT_RAW) == -1 || + ADD_INT_PREFIX_MACRO(m, CHECK_NONE) == -1 || + ADD_INT_PREFIX_MACRO(m, CHECK_CRC32) == -1 || + ADD_INT_PREFIX_MACRO(m, CHECK_CRC64) == -1 || + ADD_INT_PREFIX_MACRO(m, CHECK_SHA256) == -1 || + ADD_INT_PREFIX_MACRO(m, CHECK_ID_MAX) == -1 || + ADD_INT_PREFIX_MACRO(m, CHECK_UNKNOWN) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_LZMA1) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_LZMA2) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_DELTA) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_X86) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_IA64) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_ARM) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_ARMTHUMB) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_SPARC) == -1 || + ADD_INT_PREFIX_MACRO(m, FILTER_POWERPC) == -1 || + ADD_INT_PREFIX_MACRO(m, MF_HC3) == -1 || + ADD_INT_PREFIX_MACRO(m, MF_HC4) == -1 || + ADD_INT_PREFIX_MACRO(m, MF_BT2) == -1 || + ADD_INT_PREFIX_MACRO(m, MF_BT3) == -1 || + ADD_INT_PREFIX_MACRO(m, MF_BT4) == -1 || + ADD_INT_PREFIX_MACRO(m, MODE_FAST) == -1 || + ADD_INT_PREFIX_MACRO(m, MODE_NORMAL) == -1 || + ADD_INT_PREFIX_MACRO(m, PRESET_DEFAULT) == -1 || + ADD_INT_PREFIX_MACRO(m, PRESET_EXTREME) == -1) + return NULL; + + Error = PyErr_NewExceptionWithDoc( + "_lzma.LZMAError", "Call to liblzma failed.", NULL, NULL); + if (Error == NULL) + return NULL; + Py_INCREF(Error); + if (PyModule_AddObject(m, "LZMAError", Error) == -1) + return NULL; + + if (PyModule_AddType(m, &Compressor_type) < 0) { + return NULL; + } + + if (PyModule_AddType(m, &Decompressor_type) < 0) { + return NULL; + } + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_math.c b/contrib/tools/python3/src/Modules/_math.c index 68e3a234692..2ab022c0933 100644 --- a/contrib/tools/python3/src/Modules/_math.c +++ b/contrib/tools/python3/src/Modules/_math.c @@ -1,266 +1,266 @@ -/* Definitions of some C99 math library functions, for those platforms - that don't implement these functions already. */ - -#include "Python.h" -#include -#include "_math.h" - -/* The following copyright notice applies to the original - implementations of acosh, asinh and atanh. */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if !defined(HAVE_ACOSH) || !defined(HAVE_ASINH) -static const double ln2 = 6.93147180559945286227E-01; -static const double two_pow_p28 = 268435456.0; /* 2**28 */ -#endif -#if !defined(HAVE_ASINH) || !defined(HAVE_ATANH) -static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ -#endif -#if !defined(HAVE_ATANH) && !defined(Py_NAN) -static const double zero = 0.0; -#endif - - -#ifndef HAVE_ACOSH -/* acosh(x) - * Method : - * Based on - * acosh(x) = log [ x + sqrt(x*x-1) ] - * we have - * acosh(x) := log(x)+ln2, if x is large; else - * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else - * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. - * - * Special cases: - * acosh(x) is NaN with signal if x<1. - * acosh(NaN) is NaN without signal. - */ - -double -_Py_acosh(double x) -{ - if (Py_IS_NAN(x)) { - return x+x; - } - if (x < 1.) { /* x < 1; return a signaling NaN */ - errno = EDOM; -#ifdef Py_NAN - return Py_NAN; -#else - return (x-x)/(x-x); -#endif - } - else if (x >= two_pow_p28) { /* x > 2**28 */ - if (Py_IS_INFINITY(x)) { - return x+x; - } - else { - return log(x) + ln2; /* acosh(huge)=log(2x) */ - } - } - else if (x == 1.) { - return 0.0; /* acosh(1) = 0 */ - } - else if (x > 2.) { /* 2 < x < 2**28 */ - double t = x * x; - return log(2.0 * x - 1.0 / (x + sqrt(t - 1.0))); - } - else { /* 1 < x <= 2 */ - double t = x - 1.0; - return m_log1p(t + sqrt(2.0 * t + t * t)); - } -} -#endif /* HAVE_ACOSH */ - - -#ifndef HAVE_ASINH -/* asinh(x) - * Method : - * Based on - * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] - * we have - * asinh(x) := x if 1+x*x=1, +/* Definitions of some C99 math library functions, for those platforms + that don't implement these functions already. */ + +#include "Python.h" +#include +#include "_math.h" + +/* The following copyright notice applies to the original + implementations of acosh, asinh and atanh. */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if !defined(HAVE_ACOSH) || !defined(HAVE_ASINH) +static const double ln2 = 6.93147180559945286227E-01; +static const double two_pow_p28 = 268435456.0; /* 2**28 */ +#endif +#if !defined(HAVE_ASINH) || !defined(HAVE_ATANH) +static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ +#endif +#if !defined(HAVE_ATANH) && !defined(Py_NAN) +static const double zero = 0.0; +#endif + + +#ifndef HAVE_ACOSH +/* acosh(x) + * Method : + * Based on + * acosh(x) = log [ x + sqrt(x*x-1) ] + * we have + * acosh(x) := log(x)+ln2, if x is large; else + * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else + * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. + * + * Special cases: + * acosh(x) is NaN with signal if x<1. + * acosh(NaN) is NaN without signal. + */ + +double +_Py_acosh(double x) +{ + if (Py_IS_NAN(x)) { + return x+x; + } + if (x < 1.) { /* x < 1; return a signaling NaN */ + errno = EDOM; +#ifdef Py_NAN + return Py_NAN; +#else + return (x-x)/(x-x); +#endif + } + else if (x >= two_pow_p28) { /* x > 2**28 */ + if (Py_IS_INFINITY(x)) { + return x+x; + } + else { + return log(x) + ln2; /* acosh(huge)=log(2x) */ + } + } + else if (x == 1.) { + return 0.0; /* acosh(1) = 0 */ + } + else if (x > 2.) { /* 2 < x < 2**28 */ + double t = x * x; + return log(2.0 * x - 1.0 / (x + sqrt(t - 1.0))); + } + else { /* 1 < x <= 2 */ + double t = x - 1.0; + return m_log1p(t + sqrt(2.0 * t + t * t)); + } +} +#endif /* HAVE_ACOSH */ + + +#ifndef HAVE_ASINH +/* asinh(x) + * Method : + * Based on + * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] + * we have + * asinh(x) := x if 1+x*x=1, * := sign(x)*(log(x)+ln2) for large |x|, else - * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else - * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) - */ - -double -_Py_asinh(double x) -{ - double w; - double absx = fabs(x); - - if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { - return x+x; - } - if (absx < two_pow_m28) { /* |x| < 2**-28 */ - return x; /* return x inexact except 0 */ - } - if (absx > two_pow_p28) { /* |x| > 2**28 */ - w = log(absx) + ln2; - } - else if (absx > 2.0) { /* 2 < |x| < 2**28 */ - w = log(2.0 * absx + 1.0 / (sqrt(x * x + 1.0) + absx)); - } - else { /* 2**-28 <= |x| < 2= */ - double t = x*x; - w = m_log1p(absx + t / (1.0 + sqrt(1.0 + t))); - } - return copysign(w, x); - -} -#endif /* HAVE_ASINH */ - - -#ifndef HAVE_ATANH -/* atanh(x) - * Method : - * 1.Reduced x to positive by atanh(-x) = -atanh(x) - * 2.For x>=0.5 - * 1 2x x - * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * -------) - * 2 1 - x 1 - x - * - * For x<0.5 - * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) - * - * Special cases: - * atanh(x) is NaN if |x| >= 1 with signal; - * atanh(NaN) is that NaN with no signal; - * - */ - -double -_Py_atanh(double x) -{ - double absx; - double t; - - if (Py_IS_NAN(x)) { - return x+x; - } - absx = fabs(x); - if (absx >= 1.) { /* |x| >= 1 */ - errno = EDOM; -#ifdef Py_NAN - return Py_NAN; -#else - return x / zero; -#endif - } - if (absx < two_pow_m28) { /* |x| < 2**-28 */ - return x; - } - if (absx < 0.5) { /* |x| < 0.5 */ - t = absx+absx; - t = 0.5 * m_log1p(t + t*absx / (1.0 - absx)); - } - else { /* 0.5 <= |x| <= 1.0 */ - t = 0.5 * m_log1p((absx + absx) / (1.0 - absx)); - } - return copysign(t, x); -} -#endif /* HAVE_ATANH */ - - -#ifndef HAVE_EXPM1 -/* Mathematically, expm1(x) = exp(x) - 1. The expm1 function is designed - to avoid the significant loss of precision that arises from direct - evaluation of the expression exp(x) - 1, for x near 0. */ - -double -_Py_expm1(double x) -{ - /* For abs(x) >= log(2), it's safe to evaluate exp(x) - 1 directly; this - also works fine for infinities and nans. - - For smaller x, we can use a method due to Kahan that achieves close to - full accuracy. - */ - - if (fabs(x) < 0.7) { - double u; - u = exp(x); - if (u == 1.0) - return x; - else - return (u - 1.0) * x / log(u); - } - else - return exp(x) - 1.0; -} -#endif /* HAVE_EXPM1 */ - - -/* log1p(x) = log(1+x). The log1p function is designed to avoid the - significant loss of precision that arises from direct evaluation when x is - small. */ - -double -_Py_log1p(double x) -{ -#ifdef HAVE_LOG1P - /* Some platforms supply a log1p function but don't respect the sign of - zero: log1p(-0.0) gives 0.0 instead of the correct result of -0.0. - - To save fiddling with configure tests and platform checks, we handle the - special case of zero input directly on all platforms. - */ - if (x == 0.0) { - return x; - } - else { - return log1p(x); - } -#else - /* For x small, we use the following approach. Let y be the nearest float - to 1+x, then - - 1+x = y * (1 - (y-1-x)/y) - - so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny, the - second term is well approximated by (y-1-x)/y. If abs(x) >= - DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest - then y-1-x will be exactly representable, and is computed exactly by - (y-1)-x. - - If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be - round-to-nearest then this method is slightly dangerous: 1+x could be - rounded up to 1+DBL_EPSILON instead of down to 1, and in that case - y-1-x will not be exactly representable any more and the result can be - off by many ulps. But this is easily fixed: for a floating-point - number |x| < DBL_EPSILON/2., the closest floating-point number to - log(1+x) is exactly x. - */ - - double y; - if (fabs(x) < DBL_EPSILON / 2.) { - return x; - } - else if (-0.5 <= x && x <= 1.) { - /* WARNING: it's possible that an overeager compiler - will incorrectly optimize the following two lines - to the equivalent of "return log(1.+x)". If this - happens, then results from log1p will be inaccurate - for small x. */ - y = 1.+x; - return log(y) - ((y - 1.) - x) / y; - } - else { - /* NaNs and infinities should end up here */ - return log(1.+x); - } -#endif /* ifdef HAVE_LOG1P */ -} - + * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else + * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) + */ + +double +_Py_asinh(double x) +{ + double w; + double absx = fabs(x); + + if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { + return x+x; + } + if (absx < two_pow_m28) { /* |x| < 2**-28 */ + return x; /* return x inexact except 0 */ + } + if (absx > two_pow_p28) { /* |x| > 2**28 */ + w = log(absx) + ln2; + } + else if (absx > 2.0) { /* 2 < |x| < 2**28 */ + w = log(2.0 * absx + 1.0 / (sqrt(x * x + 1.0) + absx)); + } + else { /* 2**-28 <= |x| < 2= */ + double t = x*x; + w = m_log1p(absx + t / (1.0 + sqrt(1.0 + t))); + } + return copysign(w, x); + +} +#endif /* HAVE_ASINH */ + + +#ifndef HAVE_ATANH +/* atanh(x) + * Method : + * 1.Reduced x to positive by atanh(-x) = -atanh(x) + * 2.For x>=0.5 + * 1 2x x + * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * -------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) + * + * Special cases: + * atanh(x) is NaN if |x| >= 1 with signal; + * atanh(NaN) is that NaN with no signal; + * + */ + +double +_Py_atanh(double x) +{ + double absx; + double t; + + if (Py_IS_NAN(x)) { + return x+x; + } + absx = fabs(x); + if (absx >= 1.) { /* |x| >= 1 */ + errno = EDOM; +#ifdef Py_NAN + return Py_NAN; +#else + return x / zero; +#endif + } + if (absx < two_pow_m28) { /* |x| < 2**-28 */ + return x; + } + if (absx < 0.5) { /* |x| < 0.5 */ + t = absx+absx; + t = 0.5 * m_log1p(t + t*absx / (1.0 - absx)); + } + else { /* 0.5 <= |x| <= 1.0 */ + t = 0.5 * m_log1p((absx + absx) / (1.0 - absx)); + } + return copysign(t, x); +} +#endif /* HAVE_ATANH */ + + +#ifndef HAVE_EXPM1 +/* Mathematically, expm1(x) = exp(x) - 1. The expm1 function is designed + to avoid the significant loss of precision that arises from direct + evaluation of the expression exp(x) - 1, for x near 0. */ + +double +_Py_expm1(double x) +{ + /* For abs(x) >= log(2), it's safe to evaluate exp(x) - 1 directly; this + also works fine for infinities and nans. + + For smaller x, we can use a method due to Kahan that achieves close to + full accuracy. + */ + + if (fabs(x) < 0.7) { + double u; + u = exp(x); + if (u == 1.0) + return x; + else + return (u - 1.0) * x / log(u); + } + else + return exp(x) - 1.0; +} +#endif /* HAVE_EXPM1 */ + + +/* log1p(x) = log(1+x). The log1p function is designed to avoid the + significant loss of precision that arises from direct evaluation when x is + small. */ + +double +_Py_log1p(double x) +{ +#ifdef HAVE_LOG1P + /* Some platforms supply a log1p function but don't respect the sign of + zero: log1p(-0.0) gives 0.0 instead of the correct result of -0.0. + + To save fiddling with configure tests and platform checks, we handle the + special case of zero input directly on all platforms. + */ + if (x == 0.0) { + return x; + } + else { + return log1p(x); + } +#else + /* For x small, we use the following approach. Let y be the nearest float + to 1+x, then + + 1+x = y * (1 - (y-1-x)/y) + + so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny, the + second term is well approximated by (y-1-x)/y. If abs(x) >= + DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest + then y-1-x will be exactly representable, and is computed exactly by + (y-1)-x. + + If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be + round-to-nearest then this method is slightly dangerous: 1+x could be + rounded up to 1+DBL_EPSILON instead of down to 1, and in that case + y-1-x will not be exactly representable any more and the result can be + off by many ulps. But this is easily fixed: for a floating-point + number |x| < DBL_EPSILON/2., the closest floating-point number to + log(1+x) is exactly x. + */ + + double y; + if (fabs(x) < DBL_EPSILON / 2.) { + return x; + } + else if (-0.5 <= x && x <= 1.) { + /* WARNING: it's possible that an overeager compiler + will incorrectly optimize the following two lines + to the equivalent of "return log(1.+x)". If this + happens, then results from log1p will be inaccurate + for small x. */ + y = 1.+x; + return log(y) - ((y - 1.) - x) / y; + } + else { + /* NaNs and infinities should end up here */ + return log(1.+x); + } +#endif /* ifdef HAVE_LOG1P */ +} + diff --git a/contrib/tools/python3/src/Modules/_math.h b/contrib/tools/python3/src/Modules/_math.h index 398b7e8874a..574a27974cb 100644 --- a/contrib/tools/python3/src/Modules/_math.h +++ b/contrib/tools/python3/src/Modules/_math.h @@ -1,41 +1,41 @@ -#ifdef HAVE_ACOSH -# define m_acosh acosh -#else -/* if the system doesn't have acosh, use the substitute - function defined in Modules/_math.c. */ -double _Py_acosh(double x); -# define m_acosh _Py_acosh -#endif - -#ifdef HAVE_ASINH -# define m_asinh asinh -#else -/* if the system doesn't have asinh, use the substitute - function defined in Modules/_math.c. */ -double _Py_asinh(double x); -# define m_asinh _Py_asinh -#endif - -#ifdef HAVE_ATANH -# define m_atanh atanh -#else -/* if the system doesn't have atanh, use the substitute - function defined in Modules/_math.c. */ -double _Py_atanh(double x); -#define m_atanh _Py_atanh -#endif - -#ifdef HAVE_EXPM1 -# define m_expm1 expm1 -#else -/* if the system doesn't have expm1, use the substitute - function defined in Modules/_math.c. */ -double _Py_expm1(double x); -#define m_expm1 _Py_expm1 -#endif - -double _Py_log1p(double x); - -/* Use the substitute from _math.c on all platforms: - it includes workarounds for buggy handling of zeros. */ -#define m_log1p _Py_log1p +#ifdef HAVE_ACOSH +# define m_acosh acosh +#else +/* if the system doesn't have acosh, use the substitute + function defined in Modules/_math.c. */ +double _Py_acosh(double x); +# define m_acosh _Py_acosh +#endif + +#ifdef HAVE_ASINH +# define m_asinh asinh +#else +/* if the system doesn't have asinh, use the substitute + function defined in Modules/_math.c. */ +double _Py_asinh(double x); +# define m_asinh _Py_asinh +#endif + +#ifdef HAVE_ATANH +# define m_atanh atanh +#else +/* if the system doesn't have atanh, use the substitute + function defined in Modules/_math.c. */ +double _Py_atanh(double x); +#define m_atanh _Py_atanh +#endif + +#ifdef HAVE_EXPM1 +# define m_expm1 expm1 +#else +/* if the system doesn't have expm1, use the substitute + function defined in Modules/_math.c. */ +double _Py_expm1(double x); +#define m_expm1 _Py_expm1 +#endif + +double _Py_log1p(double x); + +/* Use the substitute from _math.c on all platforms: + it includes workarounds for buggy handling of zeros. */ +#define m_log1p _Py_log1p diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.c b/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.c index 806e638340f..77fe4a07616 100644 --- a/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.c +++ b/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.c @@ -1,219 +1,219 @@ -/* - * Extension module used by multiprocessing package - * - * multiprocessing.c - * - * Copyright (c) 2006-2008, R Oudkerk - * Licensed to PSF under a Contributor Agreement. - */ - -#include "multiprocessing.h" - - -/* - * Function which raises exceptions based on error codes - */ - -PyObject * -_PyMp_SetError(PyObject *Type, int num) -{ - switch (num) { -#ifdef MS_WINDOWS - case MP_STANDARD_ERROR: - if (Type == NULL) - Type = PyExc_OSError; - PyErr_SetExcFromWindowsErr(Type, 0); - break; - case MP_SOCKET_ERROR: - if (Type == NULL) - Type = PyExc_OSError; - PyErr_SetExcFromWindowsErr(Type, WSAGetLastError()); - break; -#else /* !MS_WINDOWS */ - case MP_STANDARD_ERROR: - case MP_SOCKET_ERROR: - if (Type == NULL) - Type = PyExc_OSError; - PyErr_SetFromErrno(Type); - break; -#endif /* !MS_WINDOWS */ - case MP_MEMORY_ERROR: - PyErr_NoMemory(); - break; - case MP_EXCEPTION_HAS_BEEN_SET: - break; - default: - PyErr_Format(PyExc_RuntimeError, - "unknown error number %d", num); - } - return NULL; -} - -#ifdef MS_WINDOWS -static PyObject * -multiprocessing_closesocket(PyObject *self, PyObject *args) -{ - HANDLE handle; - int ret; - - if (!PyArg_ParseTuple(args, F_HANDLE ":closesocket" , &handle)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - ret = closesocket((SOCKET) handle); - Py_END_ALLOW_THREADS - - if (ret) - return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); - Py_RETURN_NONE; -} - -static PyObject * -multiprocessing_recv(PyObject *self, PyObject *args) -{ - HANDLE handle; - int size, nread; - PyObject *buf; - - if (!PyArg_ParseTuple(args, F_HANDLE "i:recv" , &handle, &size)) - return NULL; - - buf = PyBytes_FromStringAndSize(NULL, size); - if (!buf) - return NULL; - - Py_BEGIN_ALLOW_THREADS - nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0); - Py_END_ALLOW_THREADS - - if (nread < 0) { - Py_DECREF(buf); - return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); - } - _PyBytes_Resize(&buf, nread); - return buf; -} - -static PyObject * -multiprocessing_send(PyObject *self, PyObject *args) -{ - HANDLE handle; - Py_buffer buf; - int ret, length; - - if (!PyArg_ParseTuple(args, F_HANDLE "y*:send" , &handle, &buf)) - return NULL; - - length = (int)Py_MIN(buf.len, INT_MAX); - - Py_BEGIN_ALLOW_THREADS - ret = send((SOCKET) handle, buf.buf, length, 0); - Py_END_ALLOW_THREADS - - PyBuffer_Release(&buf); - if (ret < 0) - return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); - return PyLong_FromLong(ret); -} - -#endif - -/* - * Function table - */ - -static PyMethodDef module_methods[] = { -#ifdef MS_WINDOWS - {"closesocket", multiprocessing_closesocket, METH_VARARGS, ""}, - {"recv", multiprocessing_recv, METH_VARARGS, ""}, - {"send", multiprocessing_send, METH_VARARGS, ""}, -#endif -#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) - {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""}, -#endif - {NULL} -}; - - -/* - * Initialize - */ - -static struct PyModuleDef multiprocessing_module = { - PyModuleDef_HEAD_INIT, - "_multiprocessing", - NULL, - -1, - module_methods, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit__multiprocessing(void) -{ - PyObject *module, *temp, *value = NULL; - - /* Initialize module */ - module = PyModule_Create(&multiprocessing_module); - if (!module) - return NULL; - -#if defined(MS_WINDOWS) || \ - (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) - /* Add _PyMp_SemLock type to module */ - if (PyType_Ready(&_PyMp_SemLockType) < 0) - return NULL; - Py_INCREF(&_PyMp_SemLockType); - { - PyObject *py_sem_value_max; - /* Some systems define SEM_VALUE_MAX as an unsigned value that - * causes it to be negative when used as an int (NetBSD). - * - * Issue #28152: Use (0) instead of 0 to fix a warning on dead code - * when using clang -Wunreachable-code. */ - if ((int)(SEM_VALUE_MAX) < (0)) - py_sem_value_max = PyLong_FromLong(INT_MAX); - else - py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); - if (py_sem_value_max == NULL) - return NULL; - PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX", - py_sem_value_max); - } - PyModule_AddObject(module, "SemLock", (PyObject*)&_PyMp_SemLockType); -#endif - - /* Add configuration macros */ - temp = PyDict_New(); - if (!temp) - return NULL; - -#define ADD_FLAG(name) \ - value = Py_BuildValue("i", name); \ - if (value == NULL) { Py_DECREF(temp); return NULL; } \ - if (PyDict_SetItemString(temp, #name, value) < 0) { \ - Py_DECREF(temp); Py_DECREF(value); return NULL; } \ - Py_DECREF(value) - -#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) - ADD_FLAG(HAVE_SEM_OPEN); -#endif -#ifdef HAVE_SEM_TIMEDWAIT - ADD_FLAG(HAVE_SEM_TIMEDWAIT); -#endif -#ifdef HAVE_BROKEN_SEM_GETVALUE - ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE); -#endif -#ifdef HAVE_BROKEN_SEM_UNLINK - ADD_FLAG(HAVE_BROKEN_SEM_UNLINK); -#endif - - if (PyModule_AddObject(module, "flags", temp) < 0) - return NULL; - - return module; -} +/* + * Extension module used by multiprocessing package + * + * multiprocessing.c + * + * Copyright (c) 2006-2008, R Oudkerk + * Licensed to PSF under a Contributor Agreement. + */ + +#include "multiprocessing.h" + + +/* + * Function which raises exceptions based on error codes + */ + +PyObject * +_PyMp_SetError(PyObject *Type, int num) +{ + switch (num) { +#ifdef MS_WINDOWS + case MP_STANDARD_ERROR: + if (Type == NULL) + Type = PyExc_OSError; + PyErr_SetExcFromWindowsErr(Type, 0); + break; + case MP_SOCKET_ERROR: + if (Type == NULL) + Type = PyExc_OSError; + PyErr_SetExcFromWindowsErr(Type, WSAGetLastError()); + break; +#else /* !MS_WINDOWS */ + case MP_STANDARD_ERROR: + case MP_SOCKET_ERROR: + if (Type == NULL) + Type = PyExc_OSError; + PyErr_SetFromErrno(Type); + break; +#endif /* !MS_WINDOWS */ + case MP_MEMORY_ERROR: + PyErr_NoMemory(); + break; + case MP_EXCEPTION_HAS_BEEN_SET: + break; + default: + PyErr_Format(PyExc_RuntimeError, + "unknown error number %d", num); + } + return NULL; +} + +#ifdef MS_WINDOWS +static PyObject * +multiprocessing_closesocket(PyObject *self, PyObject *args) +{ + HANDLE handle; + int ret; + + if (!PyArg_ParseTuple(args, F_HANDLE ":closesocket" , &handle)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = closesocket((SOCKET) handle); + Py_END_ALLOW_THREADS + + if (ret) + return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + Py_RETURN_NONE; +} + +static PyObject * +multiprocessing_recv(PyObject *self, PyObject *args) +{ + HANDLE handle; + int size, nread; + PyObject *buf; + + if (!PyArg_ParseTuple(args, F_HANDLE "i:recv" , &handle, &size)) + return NULL; + + buf = PyBytes_FromStringAndSize(NULL, size); + if (!buf) + return NULL; + + Py_BEGIN_ALLOW_THREADS + nread = recv((SOCKET) handle, PyBytes_AS_STRING(buf), size, 0); + Py_END_ALLOW_THREADS + + if (nread < 0) { + Py_DECREF(buf); + return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + } + _PyBytes_Resize(&buf, nread); + return buf; +} + +static PyObject * +multiprocessing_send(PyObject *self, PyObject *args) +{ + HANDLE handle; + Py_buffer buf; + int ret, length; + + if (!PyArg_ParseTuple(args, F_HANDLE "y*:send" , &handle, &buf)) + return NULL; + + length = (int)Py_MIN(buf.len, INT_MAX); + + Py_BEGIN_ALLOW_THREADS + ret = send((SOCKET) handle, buf.buf, length, 0); + Py_END_ALLOW_THREADS + + PyBuffer_Release(&buf); + if (ret < 0) + return PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + return PyLong_FromLong(ret); +} + +#endif + +/* + * Function table + */ + +static PyMethodDef module_methods[] = { +#ifdef MS_WINDOWS + {"closesocket", multiprocessing_closesocket, METH_VARARGS, ""}, + {"recv", multiprocessing_recv, METH_VARARGS, ""}, + {"send", multiprocessing_send, METH_VARARGS, ""}, +#endif +#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) + {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""}, +#endif + {NULL} +}; + + +/* + * Initialize + */ + +static struct PyModuleDef multiprocessing_module = { + PyModuleDef_HEAD_INIT, + "_multiprocessing", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__multiprocessing(void) +{ + PyObject *module, *temp, *value = NULL; + + /* Initialize module */ + module = PyModule_Create(&multiprocessing_module); + if (!module) + return NULL; + +#if defined(MS_WINDOWS) || \ + (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) + /* Add _PyMp_SemLock type to module */ + if (PyType_Ready(&_PyMp_SemLockType) < 0) + return NULL; + Py_INCREF(&_PyMp_SemLockType); + { + PyObject *py_sem_value_max; + /* Some systems define SEM_VALUE_MAX as an unsigned value that + * causes it to be negative when used as an int (NetBSD). + * + * Issue #28152: Use (0) instead of 0 to fix a warning on dead code + * when using clang -Wunreachable-code. */ + if ((int)(SEM_VALUE_MAX) < (0)) + py_sem_value_max = PyLong_FromLong(INT_MAX); + else + py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); + if (py_sem_value_max == NULL) + return NULL; + PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX", + py_sem_value_max); + } + PyModule_AddObject(module, "SemLock", (PyObject*)&_PyMp_SemLockType); +#endif + + /* Add configuration macros */ + temp = PyDict_New(); + if (!temp) + return NULL; + +#define ADD_FLAG(name) \ + value = Py_BuildValue("i", name); \ + if (value == NULL) { Py_DECREF(temp); return NULL; } \ + if (PyDict_SetItemString(temp, #name, value) < 0) { \ + Py_DECREF(temp); Py_DECREF(value); return NULL; } \ + Py_DECREF(value) + +#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) + ADD_FLAG(HAVE_SEM_OPEN); +#endif +#ifdef HAVE_SEM_TIMEDWAIT + ADD_FLAG(HAVE_SEM_TIMEDWAIT); +#endif +#ifdef HAVE_BROKEN_SEM_GETVALUE + ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE); +#endif +#ifdef HAVE_BROKEN_SEM_UNLINK + ADD_FLAG(HAVE_BROKEN_SEM_UNLINK); +#endif + + if (PyModule_AddObject(module, "flags", temp) < 0) + return NULL; + + return module; +} diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.h b/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.h index fe78135d466..474c0c04080 100644 --- a/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.h +++ b/contrib/tools/python3/src/Modules/_multiprocessing/multiprocessing.h @@ -1,93 +1,93 @@ -#ifndef MULTIPROCESSING_H -#define MULTIPROCESSING_H - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" -#include "structmember.h" -#include "pythread.h" - -/* - * Platform includes and definitions - */ - -#ifdef MS_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include -# include -# include /* getpid() */ -# ifdef Py_DEBUG -# include -# endif -# define SEM_HANDLE HANDLE -# define SEM_VALUE_MAX LONG_MAX -#else -# include /* O_CREAT and O_EXCL */ -# if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) -# include - typedef sem_t *SEM_HANDLE; -# endif -#endif - -/* - * Issue 3110 - Solaris does not define SEM_VALUE_MAX - */ -#ifndef SEM_VALUE_MAX - #if defined(HAVE_SYSCONF) && defined(_SC_SEM_VALUE_MAX) - # define SEM_VALUE_MAX sysconf(_SC_SEM_VALUE_MAX) - #elif defined(_SEM_VALUE_MAX) - # define SEM_VALUE_MAX _SEM_VALUE_MAX - #elif defined(_POSIX_SEM_VALUE_MAX) - # define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX - #else - # define SEM_VALUE_MAX INT_MAX - #endif -#endif - - -/* - * Format codes - */ - -#if SIZEOF_VOID_P == SIZEOF_LONG -# define F_POINTER "k" -# define T_POINTER T_ULONG -#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG -# define F_POINTER "K" -# define T_POINTER T_ULONGLONG -#else -# error "can't find format code for unsigned integer of same size as void*" -#endif - -#ifdef MS_WINDOWS -# define F_HANDLE F_POINTER -# define T_HANDLE T_POINTER -# define F_SEM_HANDLE F_HANDLE -# define T_SEM_HANDLE T_HANDLE -#else -# define F_HANDLE "i" -# define T_HANDLE T_INT -# define F_SEM_HANDLE F_POINTER -# define T_SEM_HANDLE T_POINTER -#endif - -/* - * Error codes which can be returned by functions called without GIL - */ - -#define MP_SUCCESS (0) -#define MP_STANDARD_ERROR (-1) -#define MP_MEMORY_ERROR (-1001) -#define MP_SOCKET_ERROR (-1002) -#define MP_EXCEPTION_HAS_BEEN_SET (-1003) - -PyObject *_PyMp_SetError(PyObject *Type, int num); - -/* - * Externs - not all will really exist on all platforms - */ - -extern PyTypeObject _PyMp_SemLockType; -extern PyObject *_PyMp_sem_unlink(PyObject *ignore, PyObject *args); - -#endif /* MULTIPROCESSING_H */ +#ifndef MULTIPROCESSING_H +#define MULTIPROCESSING_H + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "structmember.h" +#include "pythread.h" + +/* + * Platform includes and definitions + */ + +#ifdef MS_WINDOWS +# define WIN32_LEAN_AND_MEAN +# include +# include +# include /* getpid() */ +# ifdef Py_DEBUG +# include +# endif +# define SEM_HANDLE HANDLE +# define SEM_VALUE_MAX LONG_MAX +#else +# include /* O_CREAT and O_EXCL */ +# if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) +# include + typedef sem_t *SEM_HANDLE; +# endif +#endif + +/* + * Issue 3110 - Solaris does not define SEM_VALUE_MAX + */ +#ifndef SEM_VALUE_MAX + #if defined(HAVE_SYSCONF) && defined(_SC_SEM_VALUE_MAX) + # define SEM_VALUE_MAX sysconf(_SC_SEM_VALUE_MAX) + #elif defined(_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _SEM_VALUE_MAX + #elif defined(_POSIX_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX + #else + # define SEM_VALUE_MAX INT_MAX + #endif +#endif + + +/* + * Format codes + */ + +#if SIZEOF_VOID_P == SIZEOF_LONG +# define F_POINTER "k" +# define T_POINTER T_ULONG +#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG +# define F_POINTER "K" +# define T_POINTER T_ULONGLONG +#else +# error "can't find format code for unsigned integer of same size as void*" +#endif + +#ifdef MS_WINDOWS +# define F_HANDLE F_POINTER +# define T_HANDLE T_POINTER +# define F_SEM_HANDLE F_HANDLE +# define T_SEM_HANDLE T_HANDLE +#else +# define F_HANDLE "i" +# define T_HANDLE T_INT +# define F_SEM_HANDLE F_POINTER +# define T_SEM_HANDLE T_POINTER +#endif + +/* + * Error codes which can be returned by functions called without GIL + */ + +#define MP_SUCCESS (0) +#define MP_STANDARD_ERROR (-1) +#define MP_MEMORY_ERROR (-1001) +#define MP_SOCKET_ERROR (-1002) +#define MP_EXCEPTION_HAS_BEEN_SET (-1003) + +PyObject *_PyMp_SetError(PyObject *Type, int num); + +/* + * Externs - not all will really exist on all platforms + */ + +extern PyTypeObject _PyMp_SemLockType; +extern PyObject *_PyMp_sem_unlink(PyObject *ignore, PyObject *args); + +#endif /* MULTIPROCESSING_H */ diff --git a/contrib/tools/python3/src/Modules/_multiprocessing/semaphore.c b/contrib/tools/python3/src/Modules/_multiprocessing/semaphore.c index ee490256d2a..b792e275cfc 100644 --- a/contrib/tools/python3/src/Modules/_multiprocessing/semaphore.c +++ b/contrib/tools/python3/src/Modules/_multiprocessing/semaphore.c @@ -1,690 +1,690 @@ -/* - * A type which wraps a semaphore - * - * semaphore.c - * - * Copyright (c) 2006-2008, R Oudkerk - * Licensed to PSF under a Contributor Agreement. - */ - -#include "multiprocessing.h" - -enum { RECURSIVE_MUTEX, SEMAPHORE }; - -typedef struct { - PyObject_HEAD - SEM_HANDLE handle; - unsigned long last_tid; - int count; - int maxvalue; - int kind; - char *name; -} SemLockObject; - -#define ISMINE(o) (o->count > 0 && PyThread_get_thread_ident() == o->last_tid) - - -#ifdef MS_WINDOWS - -/* - * Windows definitions - */ - -#define SEM_FAILED NULL - -#define SEM_CLEAR_ERROR() SetLastError(0) -#define SEM_GET_LAST_ERROR() GetLastError() -#define SEM_CREATE(name, val, max) CreateSemaphore(NULL, val, max, NULL) -#define SEM_CLOSE(sem) (CloseHandle(sem) ? 0 : -1) -#define SEM_GETVALUE(sem, pval) _GetSemaphoreValue(sem, pval) -#define SEM_UNLINK(name) 0 - -static int -_GetSemaphoreValue(HANDLE handle, long *value) -{ - long previous; - - switch (WaitForSingleObjectEx(handle, 0, FALSE)) { - case WAIT_OBJECT_0: - if (!ReleaseSemaphore(handle, 1, &previous)) - return MP_STANDARD_ERROR; - *value = previous + 1; - return 0; - case WAIT_TIMEOUT: - *value = 0; - return 0; - default: - return MP_STANDARD_ERROR; - } -} - -static PyObject * -semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) -{ - int blocking = 1; - double timeout; - PyObject *timeout_obj = Py_None; - DWORD res, full_msecs, nhandles; - HANDLE handles[2], sigint_event; - - static char *kwlist[] = {"block", "timeout", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist, - &blocking, &timeout_obj)) - return NULL; - - /* calculate timeout */ - if (!blocking) { - full_msecs = 0; - } else if (timeout_obj == Py_None) { - full_msecs = INFINITE; - } else { - timeout = PyFloat_AsDouble(timeout_obj); - if (PyErr_Occurred()) - return NULL; - timeout *= 1000.0; /* convert to millisecs */ - if (timeout < 0.0) { - timeout = 0.0; - } else if (timeout >= 0.5 * INFINITE) { /* 25 days */ - PyErr_SetString(PyExc_OverflowError, - "timeout is too large"); - return NULL; - } - full_msecs = (DWORD)(timeout + 0.5); - } - - /* check whether we already own the lock */ - if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { - ++self->count; - Py_RETURN_TRUE; - } - - /* check whether we can acquire without releasing the GIL and blocking */ - if (WaitForSingleObjectEx(self->handle, 0, FALSE) == WAIT_OBJECT_0) { - self->last_tid = GetCurrentThreadId(); - ++self->count; - Py_RETURN_TRUE; - } - - /* prepare list of handles */ - nhandles = 0; - handles[nhandles++] = self->handle; - if (_PyOS_IsMainThread()) { - sigint_event = _PyOS_SigintEvent(); - assert(sigint_event != NULL); - handles[nhandles++] = sigint_event; - } - else { - sigint_event = NULL; - } - - /* do the wait */ - Py_BEGIN_ALLOW_THREADS - if (sigint_event != NULL) - ResetEvent(sigint_event); - res = WaitForMultipleObjectsEx(nhandles, handles, FALSE, full_msecs, FALSE); - Py_END_ALLOW_THREADS - - /* handle result */ - switch (res) { - case WAIT_TIMEOUT: - Py_RETURN_FALSE; - case WAIT_OBJECT_0 + 0: - self->last_tid = GetCurrentThreadId(); - ++self->count; - Py_RETURN_TRUE; - case WAIT_OBJECT_0 + 1: - errno = EINTR; - return PyErr_SetFromErrno(PyExc_OSError); - case WAIT_FAILED: - return PyErr_SetFromWindowsErr(0); - default: - PyErr_Format(PyExc_RuntimeError, "WaitForSingleObject() or " - "WaitForMultipleObjects() gave unrecognized " +/* + * A type which wraps a semaphore + * + * semaphore.c + * + * Copyright (c) 2006-2008, R Oudkerk + * Licensed to PSF under a Contributor Agreement. + */ + +#include "multiprocessing.h" + +enum { RECURSIVE_MUTEX, SEMAPHORE }; + +typedef struct { + PyObject_HEAD + SEM_HANDLE handle; + unsigned long last_tid; + int count; + int maxvalue; + int kind; + char *name; +} SemLockObject; + +#define ISMINE(o) (o->count > 0 && PyThread_get_thread_ident() == o->last_tid) + + +#ifdef MS_WINDOWS + +/* + * Windows definitions + */ + +#define SEM_FAILED NULL + +#define SEM_CLEAR_ERROR() SetLastError(0) +#define SEM_GET_LAST_ERROR() GetLastError() +#define SEM_CREATE(name, val, max) CreateSemaphore(NULL, val, max, NULL) +#define SEM_CLOSE(sem) (CloseHandle(sem) ? 0 : -1) +#define SEM_GETVALUE(sem, pval) _GetSemaphoreValue(sem, pval) +#define SEM_UNLINK(name) 0 + +static int +_GetSemaphoreValue(HANDLE handle, long *value) +{ + long previous; + + switch (WaitForSingleObjectEx(handle, 0, FALSE)) { + case WAIT_OBJECT_0: + if (!ReleaseSemaphore(handle, 1, &previous)) + return MP_STANDARD_ERROR; + *value = previous + 1; + return 0; + case WAIT_TIMEOUT: + *value = 0; + return 0; + default: + return MP_STANDARD_ERROR; + } +} + +static PyObject * +semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) +{ + int blocking = 1; + double timeout; + PyObject *timeout_obj = Py_None; + DWORD res, full_msecs, nhandles; + HANDLE handles[2], sigint_event; + + static char *kwlist[] = {"block", "timeout", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist, + &blocking, &timeout_obj)) + return NULL; + + /* calculate timeout */ + if (!blocking) { + full_msecs = 0; + } else if (timeout_obj == Py_None) { + full_msecs = INFINITE; + } else { + timeout = PyFloat_AsDouble(timeout_obj); + if (PyErr_Occurred()) + return NULL; + timeout *= 1000.0; /* convert to millisecs */ + if (timeout < 0.0) { + timeout = 0.0; + } else if (timeout >= 0.5 * INFINITE) { /* 25 days */ + PyErr_SetString(PyExc_OverflowError, + "timeout is too large"); + return NULL; + } + full_msecs = (DWORD)(timeout + 0.5); + } + + /* check whether we already own the lock */ + if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { + ++self->count; + Py_RETURN_TRUE; + } + + /* check whether we can acquire without releasing the GIL and blocking */ + if (WaitForSingleObjectEx(self->handle, 0, FALSE) == WAIT_OBJECT_0) { + self->last_tid = GetCurrentThreadId(); + ++self->count; + Py_RETURN_TRUE; + } + + /* prepare list of handles */ + nhandles = 0; + handles[nhandles++] = self->handle; + if (_PyOS_IsMainThread()) { + sigint_event = _PyOS_SigintEvent(); + assert(sigint_event != NULL); + handles[nhandles++] = sigint_event; + } + else { + sigint_event = NULL; + } + + /* do the wait */ + Py_BEGIN_ALLOW_THREADS + if (sigint_event != NULL) + ResetEvent(sigint_event); + res = WaitForMultipleObjectsEx(nhandles, handles, FALSE, full_msecs, FALSE); + Py_END_ALLOW_THREADS + + /* handle result */ + switch (res) { + case WAIT_TIMEOUT: + Py_RETURN_FALSE; + case WAIT_OBJECT_0 + 0: + self->last_tid = GetCurrentThreadId(); + ++self->count; + Py_RETURN_TRUE; + case WAIT_OBJECT_0 + 1: + errno = EINTR; + return PyErr_SetFromErrno(PyExc_OSError); + case WAIT_FAILED: + return PyErr_SetFromWindowsErr(0); + default: + PyErr_Format(PyExc_RuntimeError, "WaitForSingleObject() or " + "WaitForMultipleObjects() gave unrecognized " "value %u", res); - return NULL; - } -} - -static PyObject * -semlock_release(SemLockObject *self, PyObject *args) -{ - if (self->kind == RECURSIVE_MUTEX) { - if (!ISMINE(self)) { - PyErr_SetString(PyExc_AssertionError, "attempt to " - "release recursive lock not owned " - "by thread"); - return NULL; - } - if (self->count > 1) { - --self->count; - Py_RETURN_NONE; - } - assert(self->count == 1); - } - - if (!ReleaseSemaphore(self->handle, 1, NULL)) { - if (GetLastError() == ERROR_TOO_MANY_POSTS) { - PyErr_SetString(PyExc_ValueError, "semaphore or lock " - "released too many times"); - return NULL; - } else { - return PyErr_SetFromWindowsErr(0); - } - } - - --self->count; - Py_RETURN_NONE; -} - -#else /* !MS_WINDOWS */ - -/* - * Unix definitions - */ - -#define SEM_CLEAR_ERROR() -#define SEM_GET_LAST_ERROR() 0 -#define SEM_CREATE(name, val, max) sem_open(name, O_CREAT | O_EXCL, 0600, val) -#define SEM_CLOSE(sem) sem_close(sem) -#define SEM_GETVALUE(sem, pval) sem_getvalue(sem, pval) -#define SEM_UNLINK(name) sem_unlink(name) - -/* OS X 10.4 defines SEM_FAILED as -1 instead of (sem_t *)-1; this gives - compiler warnings, and (potentially) undefined behaviour. */ -#ifdef __APPLE__ -# undef SEM_FAILED -# define SEM_FAILED ((sem_t *)-1) -#endif - -#ifndef HAVE_SEM_UNLINK -# define sem_unlink(name) 0 -#endif - -#ifndef HAVE_SEM_TIMEDWAIT -# define sem_timedwait(sem,deadline) sem_timedwait_save(sem,deadline,_save) - -static int -sem_timedwait_save(sem_t *sem, struct timespec *deadline, PyThreadState *_save) -{ - int res; - unsigned long delay, difference; - struct timeval now, tvdeadline, tvdelay; - - errno = 0; - tvdeadline.tv_sec = deadline->tv_sec; - tvdeadline.tv_usec = deadline->tv_nsec / 1000; - - for (delay = 0 ; ; delay += 1000) { - /* poll */ - if (sem_trywait(sem) == 0) - return 0; - else if (errno != EAGAIN) - return MP_STANDARD_ERROR; - - /* get current time */ - if (gettimeofday(&now, NULL) < 0) - return MP_STANDARD_ERROR; - - /* check for timeout */ - if (tvdeadline.tv_sec < now.tv_sec || - (tvdeadline.tv_sec == now.tv_sec && - tvdeadline.tv_usec <= now.tv_usec)) { - errno = ETIMEDOUT; - return MP_STANDARD_ERROR; - } - - /* calculate how much time is left */ - difference = (tvdeadline.tv_sec - now.tv_sec) * 1000000 + - (tvdeadline.tv_usec - now.tv_usec); - - /* check delay not too long -- maximum is 20 msecs */ - if (delay > 20000) - delay = 20000; - if (delay > difference) - delay = difference; - - /* sleep */ - tvdelay.tv_sec = delay / 1000000; - tvdelay.tv_usec = delay % 1000000; - if (select(0, NULL, NULL, NULL, &tvdelay) < 0) - return MP_STANDARD_ERROR; - - /* check for signals */ - Py_BLOCK_THREADS - res = PyErr_CheckSignals(); - Py_UNBLOCK_THREADS - - if (res) { - errno = EINTR; - return MP_EXCEPTION_HAS_BEEN_SET; - } - } -} - -#endif /* !HAVE_SEM_TIMEDWAIT */ - -static PyObject * -semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) -{ - int blocking = 1, res, err = 0; - PyObject *timeout_obj = Py_None; - struct timespec deadline = {0}; - - static char *kwlist[] = {"block", "timeout", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist, - &blocking, &timeout_obj)) - return NULL; - - if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { - ++self->count; - Py_RETURN_TRUE; - } - + return NULL; + } +} + +static PyObject * +semlock_release(SemLockObject *self, PyObject *args) +{ + if (self->kind == RECURSIVE_MUTEX) { + if (!ISMINE(self)) { + PyErr_SetString(PyExc_AssertionError, "attempt to " + "release recursive lock not owned " + "by thread"); + return NULL; + } + if (self->count > 1) { + --self->count; + Py_RETURN_NONE; + } + assert(self->count == 1); + } + + if (!ReleaseSemaphore(self->handle, 1, NULL)) { + if (GetLastError() == ERROR_TOO_MANY_POSTS) { + PyErr_SetString(PyExc_ValueError, "semaphore or lock " + "released too many times"); + return NULL; + } else { + return PyErr_SetFromWindowsErr(0); + } + } + + --self->count; + Py_RETURN_NONE; +} + +#else /* !MS_WINDOWS */ + +/* + * Unix definitions + */ + +#define SEM_CLEAR_ERROR() +#define SEM_GET_LAST_ERROR() 0 +#define SEM_CREATE(name, val, max) sem_open(name, O_CREAT | O_EXCL, 0600, val) +#define SEM_CLOSE(sem) sem_close(sem) +#define SEM_GETVALUE(sem, pval) sem_getvalue(sem, pval) +#define SEM_UNLINK(name) sem_unlink(name) + +/* OS X 10.4 defines SEM_FAILED as -1 instead of (sem_t *)-1; this gives + compiler warnings, and (potentially) undefined behaviour. */ +#ifdef __APPLE__ +# undef SEM_FAILED +# define SEM_FAILED ((sem_t *)-1) +#endif + +#ifndef HAVE_SEM_UNLINK +# define sem_unlink(name) 0 +#endif + +#ifndef HAVE_SEM_TIMEDWAIT +# define sem_timedwait(sem,deadline) sem_timedwait_save(sem,deadline,_save) + +static int +sem_timedwait_save(sem_t *sem, struct timespec *deadline, PyThreadState *_save) +{ + int res; + unsigned long delay, difference; + struct timeval now, tvdeadline, tvdelay; + + errno = 0; + tvdeadline.tv_sec = deadline->tv_sec; + tvdeadline.tv_usec = deadline->tv_nsec / 1000; + + for (delay = 0 ; ; delay += 1000) { + /* poll */ + if (sem_trywait(sem) == 0) + return 0; + else if (errno != EAGAIN) + return MP_STANDARD_ERROR; + + /* get current time */ + if (gettimeofday(&now, NULL) < 0) + return MP_STANDARD_ERROR; + + /* check for timeout */ + if (tvdeadline.tv_sec < now.tv_sec || + (tvdeadline.tv_sec == now.tv_sec && + tvdeadline.tv_usec <= now.tv_usec)) { + errno = ETIMEDOUT; + return MP_STANDARD_ERROR; + } + + /* calculate how much time is left */ + difference = (tvdeadline.tv_sec - now.tv_sec) * 1000000 + + (tvdeadline.tv_usec - now.tv_usec); + + /* check delay not too long -- maximum is 20 msecs */ + if (delay > 20000) + delay = 20000; + if (delay > difference) + delay = difference; + + /* sleep */ + tvdelay.tv_sec = delay / 1000000; + tvdelay.tv_usec = delay % 1000000; + if (select(0, NULL, NULL, NULL, &tvdelay) < 0) + return MP_STANDARD_ERROR; + + /* check for signals */ + Py_BLOCK_THREADS + res = PyErr_CheckSignals(); + Py_UNBLOCK_THREADS + + if (res) { + errno = EINTR; + return MP_EXCEPTION_HAS_BEEN_SET; + } + } +} + +#endif /* !HAVE_SEM_TIMEDWAIT */ + +static PyObject * +semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds) +{ + int blocking = 1, res, err = 0; + PyObject *timeout_obj = Py_None; + struct timespec deadline = {0}; + + static char *kwlist[] = {"block", "timeout", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist, + &blocking, &timeout_obj)) + return NULL; + + if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { + ++self->count; + Py_RETURN_TRUE; + } + int use_deadline = (timeout_obj != Py_None); if (use_deadline) { double timeout = PyFloat_AsDouble(timeout_obj); if (PyErr_Occurred()) { - return NULL; + return NULL; } if (timeout < 0.0) { - timeout = 0.0; + timeout = 0.0; } - + struct timeval now; - if (gettimeofday(&now, NULL) < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } + if (gettimeofday(&now, NULL) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } long sec = (long) timeout; long nsec = (long) (1e9 * (timeout - sec) + 0.5); - deadline.tv_sec = now.tv_sec + sec; - deadline.tv_nsec = now.tv_usec * 1000 + nsec; - deadline.tv_sec += (deadline.tv_nsec / 1000000000); - deadline.tv_nsec %= 1000000000; - } - - /* Check whether we can acquire without releasing the GIL and blocking */ - do { - res = sem_trywait(self->handle); - err = errno; - } while (res < 0 && errno == EINTR && !PyErr_CheckSignals()); - errno = err; - - if (res < 0 && errno == EAGAIN && blocking) { - /* Couldn't acquire immediately, need to block */ - do { - Py_BEGIN_ALLOW_THREADS + deadline.tv_sec = now.tv_sec + sec; + deadline.tv_nsec = now.tv_usec * 1000 + nsec; + deadline.tv_sec += (deadline.tv_nsec / 1000000000); + deadline.tv_nsec %= 1000000000; + } + + /* Check whether we can acquire without releasing the GIL and blocking */ + do { + res = sem_trywait(self->handle); + err = errno; + } while (res < 0 && errno == EINTR && !PyErr_CheckSignals()); + errno = err; + + if (res < 0 && errno == EAGAIN && blocking) { + /* Couldn't acquire immediately, need to block */ + do { + Py_BEGIN_ALLOW_THREADS if (!use_deadline) { - res = sem_wait(self->handle); - } - else { - res = sem_timedwait(self->handle, &deadline); - } - Py_END_ALLOW_THREADS - err = errno; - if (res == MP_EXCEPTION_HAS_BEEN_SET) - break; - } while (res < 0 && errno == EINTR && !PyErr_CheckSignals()); - } - - if (res < 0) { - errno = err; - if (errno == EAGAIN || errno == ETIMEDOUT) - Py_RETURN_FALSE; - else if (errno == EINTR) - return NULL; - else - return PyErr_SetFromErrno(PyExc_OSError); - } - - ++self->count; - self->last_tid = PyThread_get_thread_ident(); - - Py_RETURN_TRUE; -} - -static PyObject * -semlock_release(SemLockObject *self, PyObject *args) -{ - if (self->kind == RECURSIVE_MUTEX) { - if (!ISMINE(self)) { - PyErr_SetString(PyExc_AssertionError, "attempt to " - "release recursive lock not owned " - "by thread"); - return NULL; - } - if (self->count > 1) { - --self->count; - Py_RETURN_NONE; - } - assert(self->count == 1); - } else { -#ifdef HAVE_BROKEN_SEM_GETVALUE - /* We will only check properly the maxvalue == 1 case */ - if (self->maxvalue == 1) { - /* make sure that already locked */ - if (sem_trywait(self->handle) < 0) { - if (errno != EAGAIN) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - /* it is already locked as expected */ - } else { - /* it was not locked so undo wait and raise */ - if (sem_post(self->handle) < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - PyErr_SetString(PyExc_ValueError, "semaphore " - "or lock released too many " - "times"); - return NULL; - } - } -#else - int sval; - - /* This check is not an absolute guarantee that the semaphore - does not rise above maxvalue. */ - if (sem_getvalue(self->handle, &sval) < 0) { - return PyErr_SetFromErrno(PyExc_OSError); - } else if (sval >= self->maxvalue) { - PyErr_SetString(PyExc_ValueError, "semaphore or lock " - "released too many times"); - return NULL; - } -#endif - } - - if (sem_post(self->handle) < 0) - return PyErr_SetFromErrno(PyExc_OSError); - - --self->count; - Py_RETURN_NONE; -} - -#endif /* !MS_WINDOWS */ - -/* - * All platforms - */ - -static PyObject * -newsemlockobject(PyTypeObject *type, SEM_HANDLE handle, int kind, int maxvalue, - char *name) -{ - SemLockObject *self; - - self = PyObject_New(SemLockObject, type); - if (!self) - return NULL; - self->handle = handle; - self->kind = kind; - self->count = 0; - self->last_tid = 0; - self->maxvalue = maxvalue; - self->name = name; - return (PyObject*)self; -} - -static PyObject * -semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - SEM_HANDLE handle = SEM_FAILED; - int kind, maxvalue, value, unlink; - PyObject *result; - char *name, *name_copy = NULL; - static char *kwlist[] = {"kind", "value", "maxvalue", "name", "unlink", - NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiisi", kwlist, - &kind, &value, &maxvalue, &name, &unlink)) - return NULL; - - if (kind != RECURSIVE_MUTEX && kind != SEMAPHORE) { - PyErr_SetString(PyExc_ValueError, "unrecognized kind"); - return NULL; - } - - if (!unlink) { - name_copy = PyMem_Malloc(strlen(name) + 1); - if (name_copy == NULL) { - return PyErr_NoMemory(); - } - strcpy(name_copy, name); - } - - SEM_CLEAR_ERROR(); - handle = SEM_CREATE(name, value, maxvalue); - /* On Windows we should fail if GetLastError()==ERROR_ALREADY_EXISTS */ - if (handle == SEM_FAILED || SEM_GET_LAST_ERROR() != 0) - goto failure; - - if (unlink && SEM_UNLINK(name) < 0) - goto failure; - - result = newsemlockobject(type, handle, kind, maxvalue, name_copy); - if (!result) - goto failure; - - return result; - - failure: - if (handle != SEM_FAILED) - SEM_CLOSE(handle); - PyMem_Free(name_copy); - if (!PyErr_Occurred()) { - _PyMp_SetError(NULL, MP_STANDARD_ERROR); - } - return NULL; -} - -static PyObject * -semlock_rebuild(PyTypeObject *type, PyObject *args) -{ - SEM_HANDLE handle; - int kind, maxvalue; - char *name, *name_copy = NULL; - - if (!PyArg_ParseTuple(args, F_SEM_HANDLE "iiz", - &handle, &kind, &maxvalue, &name)) - return NULL; - - if (name != NULL) { - name_copy = PyMem_Malloc(strlen(name) + 1); - if (name_copy == NULL) - return PyErr_NoMemory(); - strcpy(name_copy, name); - } - -#ifndef MS_WINDOWS - if (name != NULL) { - handle = sem_open(name, 0); - if (handle == SEM_FAILED) { - PyMem_Free(name_copy); - return PyErr_SetFromErrno(PyExc_OSError); - } - } -#endif - - return newsemlockobject(type, handle, kind, maxvalue, name_copy); -} - -static void -semlock_dealloc(SemLockObject* self) -{ - if (self->handle != SEM_FAILED) - SEM_CLOSE(self->handle); - PyMem_Free(self->name); - PyObject_Del(self); -} - -static PyObject * + res = sem_wait(self->handle); + } + else { + res = sem_timedwait(self->handle, &deadline); + } + Py_END_ALLOW_THREADS + err = errno; + if (res == MP_EXCEPTION_HAS_BEEN_SET) + break; + } while (res < 0 && errno == EINTR && !PyErr_CheckSignals()); + } + + if (res < 0) { + errno = err; + if (errno == EAGAIN || errno == ETIMEDOUT) + Py_RETURN_FALSE; + else if (errno == EINTR) + return NULL; + else + return PyErr_SetFromErrno(PyExc_OSError); + } + + ++self->count; + self->last_tid = PyThread_get_thread_ident(); + + Py_RETURN_TRUE; +} + +static PyObject * +semlock_release(SemLockObject *self, PyObject *args) +{ + if (self->kind == RECURSIVE_MUTEX) { + if (!ISMINE(self)) { + PyErr_SetString(PyExc_AssertionError, "attempt to " + "release recursive lock not owned " + "by thread"); + return NULL; + } + if (self->count > 1) { + --self->count; + Py_RETURN_NONE; + } + assert(self->count == 1); + } else { +#ifdef HAVE_BROKEN_SEM_GETVALUE + /* We will only check properly the maxvalue == 1 case */ + if (self->maxvalue == 1) { + /* make sure that already locked */ + if (sem_trywait(self->handle) < 0) { + if (errno != EAGAIN) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + /* it is already locked as expected */ + } else { + /* it was not locked so undo wait and raise */ + if (sem_post(self->handle) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + PyErr_SetString(PyExc_ValueError, "semaphore " + "or lock released too many " + "times"); + return NULL; + } + } +#else + int sval; + + /* This check is not an absolute guarantee that the semaphore + does not rise above maxvalue. */ + if (sem_getvalue(self->handle, &sval) < 0) { + return PyErr_SetFromErrno(PyExc_OSError); + } else if (sval >= self->maxvalue) { + PyErr_SetString(PyExc_ValueError, "semaphore or lock " + "released too many times"); + return NULL; + } +#endif + } + + if (sem_post(self->handle) < 0) + return PyErr_SetFromErrno(PyExc_OSError); + + --self->count; + Py_RETURN_NONE; +} + +#endif /* !MS_WINDOWS */ + +/* + * All platforms + */ + +static PyObject * +newsemlockobject(PyTypeObject *type, SEM_HANDLE handle, int kind, int maxvalue, + char *name) +{ + SemLockObject *self; + + self = PyObject_New(SemLockObject, type); + if (!self) + return NULL; + self->handle = handle; + self->kind = kind; + self->count = 0; + self->last_tid = 0; + self->maxvalue = maxvalue; + self->name = name; + return (PyObject*)self; +} + +static PyObject * +semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + SEM_HANDLE handle = SEM_FAILED; + int kind, maxvalue, value, unlink; + PyObject *result; + char *name, *name_copy = NULL; + static char *kwlist[] = {"kind", "value", "maxvalue", "name", "unlink", + NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "iiisi", kwlist, + &kind, &value, &maxvalue, &name, &unlink)) + return NULL; + + if (kind != RECURSIVE_MUTEX && kind != SEMAPHORE) { + PyErr_SetString(PyExc_ValueError, "unrecognized kind"); + return NULL; + } + + if (!unlink) { + name_copy = PyMem_Malloc(strlen(name) + 1); + if (name_copy == NULL) { + return PyErr_NoMemory(); + } + strcpy(name_copy, name); + } + + SEM_CLEAR_ERROR(); + handle = SEM_CREATE(name, value, maxvalue); + /* On Windows we should fail if GetLastError()==ERROR_ALREADY_EXISTS */ + if (handle == SEM_FAILED || SEM_GET_LAST_ERROR() != 0) + goto failure; + + if (unlink && SEM_UNLINK(name) < 0) + goto failure; + + result = newsemlockobject(type, handle, kind, maxvalue, name_copy); + if (!result) + goto failure; + + return result; + + failure: + if (handle != SEM_FAILED) + SEM_CLOSE(handle); + PyMem_Free(name_copy); + if (!PyErr_Occurred()) { + _PyMp_SetError(NULL, MP_STANDARD_ERROR); + } + return NULL; +} + +static PyObject * +semlock_rebuild(PyTypeObject *type, PyObject *args) +{ + SEM_HANDLE handle; + int kind, maxvalue; + char *name, *name_copy = NULL; + + if (!PyArg_ParseTuple(args, F_SEM_HANDLE "iiz", + &handle, &kind, &maxvalue, &name)) + return NULL; + + if (name != NULL) { + name_copy = PyMem_Malloc(strlen(name) + 1); + if (name_copy == NULL) + return PyErr_NoMemory(); + strcpy(name_copy, name); + } + +#ifndef MS_WINDOWS + if (name != NULL) { + handle = sem_open(name, 0); + if (handle == SEM_FAILED) { + PyMem_Free(name_copy); + return PyErr_SetFromErrno(PyExc_OSError); + } + } +#endif + + return newsemlockobject(type, handle, kind, maxvalue, name_copy); +} + +static void +semlock_dealloc(SemLockObject* self) +{ + if (self->handle != SEM_FAILED) + SEM_CLOSE(self->handle); + PyMem_Free(self->name); + PyObject_Del(self); +} + +static PyObject * semlock_count(SemLockObject *self, PyObject *Py_UNUSED(ignored)) -{ - return PyLong_FromLong((long)self->count); -} - -static PyObject * +{ + return PyLong_FromLong((long)self->count); +} + +static PyObject * semlock_ismine(SemLockObject *self, PyObject *Py_UNUSED(ignored)) -{ - /* only makes sense for a lock */ - return PyBool_FromLong(ISMINE(self)); -} - -static PyObject * +{ + /* only makes sense for a lock */ + return PyBool_FromLong(ISMINE(self)); +} + +static PyObject * semlock_getvalue(SemLockObject *self, PyObject *Py_UNUSED(ignored)) -{ -#ifdef HAVE_BROKEN_SEM_GETVALUE - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; -#else - int sval; - if (SEM_GETVALUE(self->handle, &sval) < 0) - return _PyMp_SetError(NULL, MP_STANDARD_ERROR); - /* some posix implementations use negative numbers to indicate - the number of waiting threads */ - if (sval < 0) - sval = 0; - return PyLong_FromLong((long)sval); -#endif -} - -static PyObject * +{ +#ifdef HAVE_BROKEN_SEM_GETVALUE + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +#else + int sval; + if (SEM_GETVALUE(self->handle, &sval) < 0) + return _PyMp_SetError(NULL, MP_STANDARD_ERROR); + /* some posix implementations use negative numbers to indicate + the number of waiting threads */ + if (sval < 0) + sval = 0; + return PyLong_FromLong((long)sval); +#endif +} + +static PyObject * semlock_iszero(SemLockObject *self, PyObject *Py_UNUSED(ignored)) -{ -#ifdef HAVE_BROKEN_SEM_GETVALUE - if (sem_trywait(self->handle) < 0) { - if (errno == EAGAIN) - Py_RETURN_TRUE; - return _PyMp_SetError(NULL, MP_STANDARD_ERROR); - } else { - if (sem_post(self->handle) < 0) - return _PyMp_SetError(NULL, MP_STANDARD_ERROR); - Py_RETURN_FALSE; - } -#else - int sval; - if (SEM_GETVALUE(self->handle, &sval) < 0) - return _PyMp_SetError(NULL, MP_STANDARD_ERROR); - return PyBool_FromLong((long)sval == 0); -#endif -} - -static PyObject * +{ +#ifdef HAVE_BROKEN_SEM_GETVALUE + if (sem_trywait(self->handle) < 0) { + if (errno == EAGAIN) + Py_RETURN_TRUE; + return _PyMp_SetError(NULL, MP_STANDARD_ERROR); + } else { + if (sem_post(self->handle) < 0) + return _PyMp_SetError(NULL, MP_STANDARD_ERROR); + Py_RETURN_FALSE; + } +#else + int sval; + if (SEM_GETVALUE(self->handle, &sval) < 0) + return _PyMp_SetError(NULL, MP_STANDARD_ERROR); + return PyBool_FromLong((long)sval == 0); +#endif +} + +static PyObject * semlock_afterfork(SemLockObject *self, PyObject *Py_UNUSED(ignored)) -{ - self->count = 0; - Py_RETURN_NONE; -} - -/* - * Semaphore methods - */ - -static PyMethodDef semlock_methods[] = { +{ + self->count = 0; + Py_RETURN_NONE; +} + +/* + * Semaphore methods + */ + +static PyMethodDef semlock_methods[] = { {"acquire", (PyCFunction)(void(*)(void))semlock_acquire, METH_VARARGS | METH_KEYWORDS, - "acquire the semaphore/lock"}, - {"release", (PyCFunction)semlock_release, METH_NOARGS, - "release the semaphore/lock"}, + "acquire the semaphore/lock"}, + {"release", (PyCFunction)semlock_release, METH_NOARGS, + "release the semaphore/lock"}, {"__enter__", (PyCFunction)(void(*)(void))semlock_acquire, METH_VARARGS | METH_KEYWORDS, - "enter the semaphore/lock"}, - {"__exit__", (PyCFunction)semlock_release, METH_VARARGS, - "exit the semaphore/lock"}, - {"_count", (PyCFunction)semlock_count, METH_NOARGS, - "num of `acquire()`s minus num of `release()`s for this process"}, - {"_is_mine", (PyCFunction)semlock_ismine, METH_NOARGS, - "whether the lock is owned by this thread"}, - {"_get_value", (PyCFunction)semlock_getvalue, METH_NOARGS, - "get the value of the semaphore"}, - {"_is_zero", (PyCFunction)semlock_iszero, METH_NOARGS, - "returns whether semaphore has value zero"}, - {"_rebuild", (PyCFunction)semlock_rebuild, METH_VARARGS | METH_CLASS, - ""}, - {"_after_fork", (PyCFunction)semlock_afterfork, METH_NOARGS, - "rezero the net acquisition count after fork()"}, - {NULL} -}; - -/* - * Member table - */ - -static PyMemberDef semlock_members[] = { - {"handle", T_SEM_HANDLE, offsetof(SemLockObject, handle), READONLY, - ""}, - {"kind", T_INT, offsetof(SemLockObject, kind), READONLY, - ""}, - {"maxvalue", T_INT, offsetof(SemLockObject, maxvalue), READONLY, - ""}, - {"name", T_STRING, offsetof(SemLockObject, name), READONLY, - ""}, - {NULL} -}; - -/* - * Semaphore type - */ - -PyTypeObject _PyMp_SemLockType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_multiprocessing.SemLock", - /* tp_basicsize */ sizeof(SemLockObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor)semlock_dealloc, + "enter the semaphore/lock"}, + {"__exit__", (PyCFunction)semlock_release, METH_VARARGS, + "exit the semaphore/lock"}, + {"_count", (PyCFunction)semlock_count, METH_NOARGS, + "num of `acquire()`s minus num of `release()`s for this process"}, + {"_is_mine", (PyCFunction)semlock_ismine, METH_NOARGS, + "whether the lock is owned by this thread"}, + {"_get_value", (PyCFunction)semlock_getvalue, METH_NOARGS, + "get the value of the semaphore"}, + {"_is_zero", (PyCFunction)semlock_iszero, METH_NOARGS, + "returns whether semaphore has value zero"}, + {"_rebuild", (PyCFunction)semlock_rebuild, METH_VARARGS | METH_CLASS, + ""}, + {"_after_fork", (PyCFunction)semlock_afterfork, METH_NOARGS, + "rezero the net acquisition count after fork()"}, + {NULL} +}; + +/* + * Member table + */ + +static PyMemberDef semlock_members[] = { + {"handle", T_SEM_HANDLE, offsetof(SemLockObject, handle), READONLY, + ""}, + {"kind", T_INT, offsetof(SemLockObject, kind), READONLY, + ""}, + {"maxvalue", T_INT, offsetof(SemLockObject, maxvalue), READONLY, + ""}, + {"name", T_STRING, offsetof(SemLockObject, name), READONLY, + ""}, + {NULL} +}; + +/* + * Semaphore type + */ + +PyTypeObject _PyMp_SemLockType = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_multiprocessing.SemLock", + /* tp_basicsize */ sizeof(SemLockObject), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)semlock_dealloc, /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, + /* tp_getattr */ 0, + /* tp_setattr */ 0, /* tp_as_async */ 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 */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - /* tp_doc */ "Semaphore/Mutex type", - /* tp_traverse */ 0, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ semlock_methods, - /* tp_members */ semlock_members, - /* tp_getset */ 0, - /* tp_base */ 0, - /* tp_dict */ 0, - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ semlock_new, -}; - -/* - * Function to unlink semaphore names - */ - -PyObject * -_PyMp_sem_unlink(PyObject *ignore, PyObject *args) -{ - char *name; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - if (SEM_UNLINK(name) < 0) { - _PyMp_SetError(NULL, MP_STANDARD_ERROR); - return NULL; - } - - Py_RETURN_NONE; -} + /* 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 */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + /* tp_doc */ "Semaphore/Mutex type", + /* tp_traverse */ 0, + /* tp_clear */ 0, + /* tp_richcompare */ 0, + /* tp_weaklistoffset */ 0, + /* tp_iter */ 0, + /* tp_iternext */ 0, + /* tp_methods */ semlock_methods, + /* tp_members */ semlock_members, + /* tp_getset */ 0, + /* tp_base */ 0, + /* tp_dict */ 0, + /* tp_descr_get */ 0, + /* tp_descr_set */ 0, + /* tp_dictoffset */ 0, + /* tp_init */ 0, + /* tp_alloc */ 0, + /* tp_new */ semlock_new, +}; + +/* + * Function to unlink semaphore names + */ + +PyObject * +_PyMp_sem_unlink(PyObject *ignore, PyObject *args) +{ + char *name; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + if (SEM_UNLINK(name) < 0) { + _PyMp_SetError(NULL, MP_STANDARD_ERROR); + return NULL; + } + + Py_RETURN_NONE; +} diff --git a/contrib/tools/python3/src/Modules/_opcode.c b/contrib/tools/python3/src/Modules/_opcode.c index 42a8732694a..ec7e05a965d 100644 --- a/contrib/tools/python3/src/Modules/_opcode.c +++ b/contrib/tools/python3/src/Modules/_opcode.c @@ -1,49 +1,49 @@ -#include "Python.h" -#include "opcode.h" - -/*[clinic input] -module _opcode -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=117442e66eb376e6]*/ - -#include "clinic/_opcode.c.h" - -/*[clinic input] - -_opcode.stack_effect -> int - - opcode: int - oparg: object = None - / +#include "Python.h" +#include "opcode.h" + +/*[clinic input] +module _opcode +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=117442e66eb376e6]*/ + +#include "clinic/_opcode.c.h" + +/*[clinic input] + +_opcode.stack_effect -> int + + opcode: int + oparg: object = None + / * jump: object = None - -Compute the stack effect of the opcode. -[clinic start generated code]*/ - -static int + +Compute the stack effect of the opcode. +[clinic start generated code]*/ + +static int _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, PyObject *jump) /*[clinic end generated code: output=64a18f2ead954dbb input=461c9d4a44851898]*/ -{ - int effect; - int oparg_int = 0; +{ + int effect; + int oparg_int = 0; int jump_int; - if (HAS_ARG(opcode)) { - if (oparg == Py_None) { - PyErr_SetString(PyExc_ValueError, - "stack_effect: opcode requires oparg but oparg was not specified"); - return -1; - } - oparg_int = (int)PyLong_AsLong(oparg); - if ((oparg_int == -1) && PyErr_Occurred()) - return -1; - } - else if (oparg != Py_None) { - PyErr_SetString(PyExc_ValueError, - "stack_effect: opcode does not permit oparg but oparg was specified"); - return -1; - } + if (HAS_ARG(opcode)) { + if (oparg == Py_None) { + PyErr_SetString(PyExc_ValueError, + "stack_effect: opcode requires oparg but oparg was not specified"); + return -1; + } + oparg_int = (int)PyLong_AsLong(oparg); + if ((oparg_int == -1) && PyErr_Occurred()) + return -1; + } + else if (oparg != Py_None) { + PyErr_SetString(PyExc_ValueError, + "stack_effect: opcode does not permit oparg but oparg was specified"); + return -1; + } if (jump == Py_None) { jump_int = -1; } @@ -59,38 +59,38 @@ _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, return -1; } effect = PyCompile_OpcodeStackEffectWithJump(opcode, oparg_int, jump_int); - if (effect == PY_INVALID_STACK_EFFECT) { - PyErr_SetString(PyExc_ValueError, - "invalid opcode or oparg"); - return -1; - } - return effect; -} - - - - -static PyMethodDef -opcode_functions[] = { - _OPCODE_STACK_EFFECT_METHODDEF - {NULL, NULL, 0, NULL} -}; - - -static struct PyModuleDef opcodemodule = { - PyModuleDef_HEAD_INIT, - "_opcode", - "Opcode support module.", - -1, - opcode_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__opcode(void) -{ - return PyModule_Create(&opcodemodule); -} + if (effect == PY_INVALID_STACK_EFFECT) { + PyErr_SetString(PyExc_ValueError, + "invalid opcode or oparg"); + return -1; + } + return effect; +} + + + + +static PyMethodDef +opcode_functions[] = { + _OPCODE_STACK_EFFECT_METHODDEF + {NULL, NULL, 0, NULL} +}; + + +static struct PyModuleDef opcodemodule = { + PyModuleDef_HEAD_INIT, + "_opcode", + "Opcode support module.", + -1, + opcode_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__opcode(void) +{ + return PyModule_Create(&opcodemodule); +} diff --git a/contrib/tools/python3/src/Modules/_operator.c b/contrib/tools/python3/src/Modules/_operator.c index 0136e380d2a..8589334bca3 100644 --- a/contrib/tools/python3/src/Modules/_operator.c +++ b/contrib/tools/python3/src/Modules/_operator.c @@ -1,976 +1,976 @@ - -#include "Python.h" - -#include "clinic/_operator.c.h" - -/*[clinic input] -module _operator -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/ - -PyDoc_STRVAR(operator_doc, -"Operator interface.\n\ -\n\ -This module exports a set of functions implemented in C corresponding\n\ -to the intrinsic operators of Python. For example, operator.add(x, y)\n\ -is equivalent to the expression x+y. The function names are those\n\ -used for special methods; variants without leading and trailing\n\ -'__' are also provided for convenience."); - - -/*[clinic input] -_operator.truth -> bool - - a: object - / - -Return True if a is true, False otherwise. -[clinic start generated code]*/ - -static int -_operator_truth_impl(PyObject *module, PyObject *a) -/*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/ -{ - return PyObject_IsTrue(a); -} - -/*[clinic input] -_operator.add - - a: object - b: object - / - -Same as a + b. -[clinic start generated code]*/ - -static PyObject * -_operator_add_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=8292984204f45164 input=5efe3bff856ac215]*/ -{ - return PyNumber_Add(a, b); -} - -/*[clinic input] -_operator.sub = _operator.add - -Same as a - b. -[clinic start generated code]*/ - -static PyObject * -_operator_sub_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=4adfc3b888c1ee2e input=6494c6b100b8e795]*/ -{ - return PyNumber_Subtract(a, b); -} - -/*[clinic input] -_operator.mul = _operator.add - -Same as a * b. -[clinic start generated code]*/ - -static PyObject * -_operator_mul_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=d24d66f55a01944c input=2368615b4358b70d]*/ -{ - return PyNumber_Multiply(a, b); -} - -/*[clinic input] -_operator.matmul = _operator.add - -Same as a @ b. -[clinic start generated code]*/ - -static PyObject * -_operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=a20d917eb35d0101 input=9ab304e37fb42dd4]*/ -{ - return PyNumber_MatrixMultiply(a, b); -} - -/*[clinic input] -_operator.floordiv = _operator.add - -Same as a // b. -[clinic start generated code]*/ - -static PyObject * -_operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=df26b71a60589f99 input=bb2e88ba446c612c]*/ -{ - return PyNumber_FloorDivide(a, b); -} - -/*[clinic input] -_operator.truediv = _operator.add - -Same as a / b. -[clinic start generated code]*/ - -static PyObject * -_operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=0e6a959944d77719 input=ecbb947673f4eb1f]*/ -{ - return PyNumber_TrueDivide(a, b); -} - -/*[clinic input] -_operator.mod = _operator.add - -Same as a % b. -[clinic start generated code]*/ - -static PyObject * -_operator_mod_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=9519822f0bbec166 input=102e19b422342ac1]*/ -{ - return PyNumber_Remainder(a, b); -} - -/*[clinic input] -_operator.neg - - a: object - / - -Same as -a. -[clinic start generated code]*/ - -static PyObject * -_operator_neg(PyObject *module, PyObject *a) -/*[clinic end generated code: output=36e08ecfc6a1c08c input=84f09bdcf27c96ec]*/ -{ - return PyNumber_Negative(a); -} - -/*[clinic input] -_operator.pos = _operator.neg - -Same as +a. -[clinic start generated code]*/ - -static PyObject * -_operator_pos(PyObject *module, PyObject *a) -/*[clinic end generated code: output=dad7a126221dd091 input=b6445b63fddb8772]*/ -{ - return PyNumber_Positive(a); -} - -/*[clinic input] -_operator.abs = _operator.neg - -Same as abs(a). -[clinic start generated code]*/ - -static PyObject * -_operator_abs(PyObject *module, PyObject *a) -/*[clinic end generated code: output=1389a93ba053ea3e input=341d07ba86f58039]*/ -{ - return PyNumber_Absolute(a); -} - -/*[clinic input] -_operator.inv = _operator.neg - -Same as ~a. -[clinic start generated code]*/ - -static PyObject * -_operator_inv(PyObject *module, PyObject *a) -/*[clinic end generated code: output=a56875ba075ee06d input=b01a4677739f6eb2]*/ -{ - return PyNumber_Invert(a); -} - -/*[clinic input] -_operator.invert = _operator.neg - -Same as ~a. -[clinic start generated code]*/ - -static PyObject * -_operator_invert(PyObject *module, PyObject *a) -/*[clinic end generated code: output=406b5aa030545fcc input=7f2d607176672e55]*/ -{ - return PyNumber_Invert(a); -} - -/*[clinic input] -_operator.lshift = _operator.add - -Same as a << b. -[clinic start generated code]*/ - -static PyObject * -_operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=37f7e52c41435bd8 input=746e8a160cbbc9eb]*/ -{ - return PyNumber_Lshift(a, b); -} - -/*[clinic input] -_operator.rshift = _operator.add - -Same as a >> b. -[clinic start generated code]*/ - -static PyObject * -_operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=4593c7ef30ec2ee3 input=d2c85bb5a64504c2]*/ -{ - return PyNumber_Rshift(a, b); -} - -/*[clinic input] -_operator.not_ = _operator.truth - -Same as not a. -[clinic start generated code]*/ - -static int -_operator_not__impl(PyObject *module, PyObject *a) -/*[clinic end generated code: output=743f9c24a09759ef input=854156d50804d9b8]*/ -{ - return PyObject_Not(a); -} - -/*[clinic input] -_operator.and_ = _operator.add - -Same as a & b. -[clinic start generated code]*/ - -static PyObject * -_operator_and__impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=93c4fe88f7b76d9e input=4f3057c90ec4c99f]*/ -{ - return PyNumber_And(a, b); -} - -/*[clinic input] -_operator.xor = _operator.add - -Same as a ^ b. -[clinic start generated code]*/ - -static PyObject * -_operator_xor_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=b24cd8b79fde0004 input=3c5cfa7253d808dd]*/ -{ - return PyNumber_Xor(a, b); -} - -/*[clinic input] -_operator.or_ = _operator.add - -Same as a | b. -[clinic start generated code]*/ - -static PyObject * -_operator_or__impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=58024867b8d90461 input=b40c6c44f7c79c09]*/ -{ - return PyNumber_Or(a, b); -} - -/*[clinic input] -_operator.iadd = _operator.add - -Same as a += b. -[clinic start generated code]*/ - -static PyObject * -_operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=07dc627832526eb5 input=d22a91c07ac69227]*/ -{ - return PyNumber_InPlaceAdd(a, b); -} - -/*[clinic input] -_operator.isub = _operator.add - -Same as a -= b. -[clinic start generated code]*/ - -static PyObject * -_operator_isub_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=4513467d23b5e0b1 input=4591b00d0a0ccafd]*/ -{ - return PyNumber_InPlaceSubtract(a, b); -} - -/*[clinic input] -_operator.imul = _operator.add - -Same as a *= b. -[clinic start generated code]*/ - -static PyObject * -_operator_imul_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=5e87dacd19a71eab input=0e01fb8631e1b76f]*/ -{ - return PyNumber_InPlaceMultiply(a, b); -} - -/*[clinic input] -_operator.imatmul = _operator.add - -Same as a @= b. -[clinic start generated code]*/ - -static PyObject * -_operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=d603cbdf716ce519 input=bb614026372cd542]*/ -{ - return PyNumber_InPlaceMatrixMultiply(a, b); -} - -/*[clinic input] -_operator.ifloordiv = _operator.add - -Same as a //= b. -[clinic start generated code]*/ - -static PyObject * -_operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=535336048c681794 input=9df3b5021cff4ca1]*/ -{ - return PyNumber_InPlaceFloorDivide(a, b); -} - -/*[clinic input] -_operator.itruediv = _operator.add - -Same as a /= b. -[clinic start generated code]*/ - -static PyObject * -_operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=28017fbd3563952f input=9a1ee01608f5f590]*/ -{ - return PyNumber_InPlaceTrueDivide(a, b); -} - -/*[clinic input] -_operator.imod = _operator.add - -Same as a %= b. -[clinic start generated code]*/ - -static PyObject * -_operator_imod_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=f7c540ae0fc70904 input=d0c384a3ce38e1dd]*/ -{ - return PyNumber_InPlaceRemainder(a, b); -} - -/*[clinic input] -_operator.ilshift = _operator.add - -Same as a <<= b. -[clinic start generated code]*/ - -static PyObject * -_operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=e73a8fee1ac18749 input=e21b6b310f54572e]*/ -{ - return PyNumber_InPlaceLshift(a, b); -} - -/*[clinic input] -_operator.irshift = _operator.add - -Same as a >>= b. -[clinic start generated code]*/ - -static PyObject * -_operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=97f2af6b5ff2ed81 input=6778dbd0f6e1ec16]*/ -{ - return PyNumber_InPlaceRshift(a, b); -} - -/*[clinic input] -_operator.iand = _operator.add - -Same as a &= b. -[clinic start generated code]*/ - -static PyObject * -_operator_iand_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=4599e9d40cbf7d00 input=71dfd8e70c156a7b]*/ -{ - return PyNumber_InPlaceAnd(a, b); -} - -/*[clinic input] -_operator.ixor = _operator.add - -Same as a ^= b. -[clinic start generated code]*/ - -static PyObject * -_operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=5ff881766872be03 input=695c32bec0604d86]*/ -{ - return PyNumber_InPlaceXor(a, b); -} - -/*[clinic input] -_operator.ior = _operator.add - -Same as a |= b. -[clinic start generated code]*/ - -static PyObject * -_operator_ior_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=48aac319445bf759 input=8f01d03eda9920cf]*/ -{ - return PyNumber_InPlaceOr(a, b); -} - -/*[clinic input] -_operator.concat = _operator.add - -Same as a + b, for a and b sequences. -[clinic start generated code]*/ - -static PyObject * -_operator_concat_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=80028390942c5f11 input=8544ccd5341a3658]*/ -{ - return PySequence_Concat(a, b); -} - -/*[clinic input] -_operator.iconcat = _operator.add - -Same as a += b, for a and b sequences. -[clinic start generated code]*/ - -static PyObject * -_operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=3ea0a162ebb2e26d input=8f5fe5722fcd837e]*/ -{ - return PySequence_InPlaceConcat(a, b); -} - -/*[clinic input] -_operator.contains -> bool - - a: object - b: object - / - -Same as b in a (note reversed operands). -[clinic start generated code]*/ - -static int -_operator_contains_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=413b4dbe82b6ffc1 input=9122a69b505fde13]*/ -{ - return PySequence_Contains(a, b); -} - -/*[clinic input] -_operator.indexOf -> Py_ssize_t - - a: object - b: object - / - -Return the first index of b in a. -[clinic start generated code]*/ - -static Py_ssize_t -_operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=c6226d8e0fb60fa6 input=8be2e43b6a6fffe3]*/ -{ - return PySequence_Index(a, b); -} - -/*[clinic input] -_operator.countOf = _operator.indexOf - + +#include "Python.h" + +#include "clinic/_operator.c.h" + +/*[clinic input] +module _operator +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/ + +PyDoc_STRVAR(operator_doc, +"Operator interface.\n\ +\n\ +This module exports a set of functions implemented in C corresponding\n\ +to the intrinsic operators of Python. For example, operator.add(x, y)\n\ +is equivalent to the expression x+y. The function names are those\n\ +used for special methods; variants without leading and trailing\n\ +'__' are also provided for convenience."); + + +/*[clinic input] +_operator.truth -> bool + + a: object + / + +Return True if a is true, False otherwise. +[clinic start generated code]*/ + +static int +_operator_truth_impl(PyObject *module, PyObject *a) +/*[clinic end generated code: output=eaf87767234fa5d7 input=bc74a4cd90235875]*/ +{ + return PyObject_IsTrue(a); +} + +/*[clinic input] +_operator.add + + a: object + b: object + / + +Same as a + b. +[clinic start generated code]*/ + +static PyObject * +_operator_add_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=8292984204f45164 input=5efe3bff856ac215]*/ +{ + return PyNumber_Add(a, b); +} + +/*[clinic input] +_operator.sub = _operator.add + +Same as a - b. +[clinic start generated code]*/ + +static PyObject * +_operator_sub_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=4adfc3b888c1ee2e input=6494c6b100b8e795]*/ +{ + return PyNumber_Subtract(a, b); +} + +/*[clinic input] +_operator.mul = _operator.add + +Same as a * b. +[clinic start generated code]*/ + +static PyObject * +_operator_mul_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=d24d66f55a01944c input=2368615b4358b70d]*/ +{ + return PyNumber_Multiply(a, b); +} + +/*[clinic input] +_operator.matmul = _operator.add + +Same as a @ b. +[clinic start generated code]*/ + +static PyObject * +_operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=a20d917eb35d0101 input=9ab304e37fb42dd4]*/ +{ + return PyNumber_MatrixMultiply(a, b); +} + +/*[clinic input] +_operator.floordiv = _operator.add + +Same as a // b. +[clinic start generated code]*/ + +static PyObject * +_operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=df26b71a60589f99 input=bb2e88ba446c612c]*/ +{ + return PyNumber_FloorDivide(a, b); +} + +/*[clinic input] +_operator.truediv = _operator.add + +Same as a / b. +[clinic start generated code]*/ + +static PyObject * +_operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=0e6a959944d77719 input=ecbb947673f4eb1f]*/ +{ + return PyNumber_TrueDivide(a, b); +} + +/*[clinic input] +_operator.mod = _operator.add + +Same as a % b. +[clinic start generated code]*/ + +static PyObject * +_operator_mod_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=9519822f0bbec166 input=102e19b422342ac1]*/ +{ + return PyNumber_Remainder(a, b); +} + +/*[clinic input] +_operator.neg + + a: object + / + +Same as -a. +[clinic start generated code]*/ + +static PyObject * +_operator_neg(PyObject *module, PyObject *a) +/*[clinic end generated code: output=36e08ecfc6a1c08c input=84f09bdcf27c96ec]*/ +{ + return PyNumber_Negative(a); +} + +/*[clinic input] +_operator.pos = _operator.neg + +Same as +a. +[clinic start generated code]*/ + +static PyObject * +_operator_pos(PyObject *module, PyObject *a) +/*[clinic end generated code: output=dad7a126221dd091 input=b6445b63fddb8772]*/ +{ + return PyNumber_Positive(a); +} + +/*[clinic input] +_operator.abs = _operator.neg + +Same as abs(a). +[clinic start generated code]*/ + +static PyObject * +_operator_abs(PyObject *module, PyObject *a) +/*[clinic end generated code: output=1389a93ba053ea3e input=341d07ba86f58039]*/ +{ + return PyNumber_Absolute(a); +} + +/*[clinic input] +_operator.inv = _operator.neg + +Same as ~a. +[clinic start generated code]*/ + +static PyObject * +_operator_inv(PyObject *module, PyObject *a) +/*[clinic end generated code: output=a56875ba075ee06d input=b01a4677739f6eb2]*/ +{ + return PyNumber_Invert(a); +} + +/*[clinic input] +_operator.invert = _operator.neg + +Same as ~a. +[clinic start generated code]*/ + +static PyObject * +_operator_invert(PyObject *module, PyObject *a) +/*[clinic end generated code: output=406b5aa030545fcc input=7f2d607176672e55]*/ +{ + return PyNumber_Invert(a); +} + +/*[clinic input] +_operator.lshift = _operator.add + +Same as a << b. +[clinic start generated code]*/ + +static PyObject * +_operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=37f7e52c41435bd8 input=746e8a160cbbc9eb]*/ +{ + return PyNumber_Lshift(a, b); +} + +/*[clinic input] +_operator.rshift = _operator.add + +Same as a >> b. +[clinic start generated code]*/ + +static PyObject * +_operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=4593c7ef30ec2ee3 input=d2c85bb5a64504c2]*/ +{ + return PyNumber_Rshift(a, b); +} + +/*[clinic input] +_operator.not_ = _operator.truth + +Same as not a. +[clinic start generated code]*/ + +static int +_operator_not__impl(PyObject *module, PyObject *a) +/*[clinic end generated code: output=743f9c24a09759ef input=854156d50804d9b8]*/ +{ + return PyObject_Not(a); +} + +/*[clinic input] +_operator.and_ = _operator.add + +Same as a & b. +[clinic start generated code]*/ + +static PyObject * +_operator_and__impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=93c4fe88f7b76d9e input=4f3057c90ec4c99f]*/ +{ + return PyNumber_And(a, b); +} + +/*[clinic input] +_operator.xor = _operator.add + +Same as a ^ b. +[clinic start generated code]*/ + +static PyObject * +_operator_xor_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=b24cd8b79fde0004 input=3c5cfa7253d808dd]*/ +{ + return PyNumber_Xor(a, b); +} + +/*[clinic input] +_operator.or_ = _operator.add + +Same as a | b. +[clinic start generated code]*/ + +static PyObject * +_operator_or__impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=58024867b8d90461 input=b40c6c44f7c79c09]*/ +{ + return PyNumber_Or(a, b); +} + +/*[clinic input] +_operator.iadd = _operator.add + +Same as a += b. +[clinic start generated code]*/ + +static PyObject * +_operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=07dc627832526eb5 input=d22a91c07ac69227]*/ +{ + return PyNumber_InPlaceAdd(a, b); +} + +/*[clinic input] +_operator.isub = _operator.add + +Same as a -= b. +[clinic start generated code]*/ + +static PyObject * +_operator_isub_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=4513467d23b5e0b1 input=4591b00d0a0ccafd]*/ +{ + return PyNumber_InPlaceSubtract(a, b); +} + +/*[clinic input] +_operator.imul = _operator.add + +Same as a *= b. +[clinic start generated code]*/ + +static PyObject * +_operator_imul_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=5e87dacd19a71eab input=0e01fb8631e1b76f]*/ +{ + return PyNumber_InPlaceMultiply(a, b); +} + +/*[clinic input] +_operator.imatmul = _operator.add + +Same as a @= b. +[clinic start generated code]*/ + +static PyObject * +_operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=d603cbdf716ce519 input=bb614026372cd542]*/ +{ + return PyNumber_InPlaceMatrixMultiply(a, b); +} + +/*[clinic input] +_operator.ifloordiv = _operator.add + +Same as a //= b. +[clinic start generated code]*/ + +static PyObject * +_operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=535336048c681794 input=9df3b5021cff4ca1]*/ +{ + return PyNumber_InPlaceFloorDivide(a, b); +} + +/*[clinic input] +_operator.itruediv = _operator.add + +Same as a /= b. +[clinic start generated code]*/ + +static PyObject * +_operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=28017fbd3563952f input=9a1ee01608f5f590]*/ +{ + return PyNumber_InPlaceTrueDivide(a, b); +} + +/*[clinic input] +_operator.imod = _operator.add + +Same as a %= b. +[clinic start generated code]*/ + +static PyObject * +_operator_imod_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=f7c540ae0fc70904 input=d0c384a3ce38e1dd]*/ +{ + return PyNumber_InPlaceRemainder(a, b); +} + +/*[clinic input] +_operator.ilshift = _operator.add + +Same as a <<= b. +[clinic start generated code]*/ + +static PyObject * +_operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=e73a8fee1ac18749 input=e21b6b310f54572e]*/ +{ + return PyNumber_InPlaceLshift(a, b); +} + +/*[clinic input] +_operator.irshift = _operator.add + +Same as a >>= b. +[clinic start generated code]*/ + +static PyObject * +_operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=97f2af6b5ff2ed81 input=6778dbd0f6e1ec16]*/ +{ + return PyNumber_InPlaceRshift(a, b); +} + +/*[clinic input] +_operator.iand = _operator.add + +Same as a &= b. +[clinic start generated code]*/ + +static PyObject * +_operator_iand_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=4599e9d40cbf7d00 input=71dfd8e70c156a7b]*/ +{ + return PyNumber_InPlaceAnd(a, b); +} + +/*[clinic input] +_operator.ixor = _operator.add + +Same as a ^= b. +[clinic start generated code]*/ + +static PyObject * +_operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=5ff881766872be03 input=695c32bec0604d86]*/ +{ + return PyNumber_InPlaceXor(a, b); +} + +/*[clinic input] +_operator.ior = _operator.add + +Same as a |= b. +[clinic start generated code]*/ + +static PyObject * +_operator_ior_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=48aac319445bf759 input=8f01d03eda9920cf]*/ +{ + return PyNumber_InPlaceOr(a, b); +} + +/*[clinic input] +_operator.concat = _operator.add + +Same as a + b, for a and b sequences. +[clinic start generated code]*/ + +static PyObject * +_operator_concat_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=80028390942c5f11 input=8544ccd5341a3658]*/ +{ + return PySequence_Concat(a, b); +} + +/*[clinic input] +_operator.iconcat = _operator.add + +Same as a += b, for a and b sequences. +[clinic start generated code]*/ + +static PyObject * +_operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=3ea0a162ebb2e26d input=8f5fe5722fcd837e]*/ +{ + return PySequence_InPlaceConcat(a, b); +} + +/*[clinic input] +_operator.contains -> bool + + a: object + b: object + / + +Same as b in a (note reversed operands). +[clinic start generated code]*/ + +static int +_operator_contains_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=413b4dbe82b6ffc1 input=9122a69b505fde13]*/ +{ + return PySequence_Contains(a, b); +} + +/*[clinic input] +_operator.indexOf -> Py_ssize_t + + a: object + b: object + / + +Return the first index of b in a. +[clinic start generated code]*/ + +static Py_ssize_t +_operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=c6226d8e0fb60fa6 input=8be2e43b6a6fffe3]*/ +{ + return PySequence_Index(a, b); +} + +/*[clinic input] +_operator.countOf = _operator.indexOf + Return the number of items in a which are, or which equal, b. -[clinic start generated code]*/ - -static Py_ssize_t -_operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b) +[clinic start generated code]*/ + +static Py_ssize_t +_operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b) /*[clinic end generated code: output=9e1623197daf3382 input=93ea57f170f3f0bb]*/ -{ - return PySequence_Count(a, b); -} - -/*[clinic input] -_operator.getitem - - a: object - b: object - / - -Same as a[b]. -[clinic start generated code]*/ - -static PyObject * -_operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=6c8d8101a676e594 input=6682797320e48845]*/ -{ - return PyObject_GetItem(a, b); -} - -/*[clinic input] -_operator.setitem - - a: object - b: object - c: object - / - -Same as a[b] = c. -[clinic start generated code]*/ - -static PyObject * -_operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *c) -/*[clinic end generated code: output=1324f9061ae99e25 input=ceaf453c4d3a58df]*/ -{ - if (-1 == PyObject_SetItem(a, b, c)) - return NULL; - Py_RETURN_NONE; -} - -/*[clinic input] -_operator.delitem = _operator.getitem - -Same as del a[b]. -[clinic start generated code]*/ - -static PyObject * -_operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=db18f61506295799 input=991bec56a0d3ec7f]*/ -{ - if (-1 == PyObject_DelItem(a, b)) - return NULL; - Py_RETURN_NONE; -} - -/*[clinic input] -_operator.eq - - a: object - b: object - / - -Same as a == b. -[clinic start generated code]*/ - -static PyObject * -_operator_eq_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=8d7d46ed4135677c input=586fca687a95a83f]*/ -{ - return PyObject_RichCompare(a, b, Py_EQ); -} - -/*[clinic input] -_operator.ne = _operator.eq - -Same as a != b. -[clinic start generated code]*/ - -static PyObject * -_operator_ne_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=c99bd0c3a4c01297 input=5d88f23d35e9abac]*/ -{ - return PyObject_RichCompare(a, b, Py_NE); -} - -/*[clinic input] -_operator.lt = _operator.eq - -Same as a < b. -[clinic start generated code]*/ - -static PyObject * -_operator_lt_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=082d7c45c440e535 input=34a59ad6d39d3a2b]*/ -{ - return PyObject_RichCompare(a, b, Py_LT); -} - -/*[clinic input] -_operator.le = _operator.eq - -Same as a <= b. -[clinic start generated code]*/ - -static PyObject * -_operator_le_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=00970a2923d0ae17 input=b812a7860a0bef44]*/ -{ - return PyObject_RichCompare(a, b, Py_LE); -} - -/*[clinic input] -_operator.gt = _operator.eq - -Same as a > b. -[clinic start generated code]*/ - -static PyObject * -_operator_gt_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=8d373349ecf25641 input=9bdb45b995ada35b]*/ -{ - return PyObject_RichCompare(a, b, Py_GT); -} - -/*[clinic input] -_operator.ge = _operator.eq - -Same as a >= b. -[clinic start generated code]*/ - -static PyObject * -_operator_ge_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=7ce3882256d4b137 input=cf1dc4a5ca9c35f5]*/ -{ - return PyObject_RichCompare(a, b, Py_GE); -} - -/*[clinic input] -_operator.pow = _operator.add - -Same as a ** b. -[clinic start generated code]*/ - -static PyObject * -_operator_pow_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=09e668ad50036120 input=690b40f097ab1637]*/ -{ - return PyNumber_Power(a, b, Py_None); -} - -/*[clinic input] -_operator.ipow = _operator.add - -Same as a **= b. -[clinic start generated code]*/ - -static PyObject * -_operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=7189ff4d4367c808 input=f00623899d07499a]*/ -{ - return PyNumber_InPlacePower(a, b, Py_None); -} - -/*[clinic input] -_operator.index - - a: object - / - -Same as a.__index__() -[clinic start generated code]*/ - -static PyObject * -_operator_index(PyObject *module, PyObject *a) -/*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/ -{ - return PyNumber_Index(a); -} - -/*[clinic input] -_operator.is_ = _operator.add - -Same as a is b. -[clinic start generated code]*/ - -static PyObject * -_operator_is__impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/ -{ - PyObject *result; - result = (a == b) ? Py_True : Py_False; - Py_INCREF(result); - return result; -} - -/*[clinic input] -_operator.is_not = _operator.add - -Same as a is not b. -[clinic start generated code]*/ - -static PyObject * -_operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/ -{ - PyObject *result; - result = (a != b) ? Py_True : Py_False; - Py_INCREF(result); - return result; -} - -/* compare_digest **********************************************************/ - -/* - * timing safe compare - * - * Returns 1 of the strings are equal. - * In case of len(a) != len(b) the function tries to keep the timing - * dependent on the length of b. CPU cache locally may still alter timing - * a bit. - */ -static int -_tscmp(const unsigned char *a, const unsigned char *b, - Py_ssize_t len_a, Py_ssize_t len_b) -{ - /* The volatile type declarations make sure that the compiler has no - * chance to optimize and fold the code in any way that may change - * the timing. - */ - volatile Py_ssize_t length; - volatile const unsigned char *left; - volatile const unsigned char *right; - Py_ssize_t i; +{ + return PySequence_Count(a, b); +} + +/*[clinic input] +_operator.getitem + + a: object + b: object + / + +Same as a[b]. +[clinic start generated code]*/ + +static PyObject * +_operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=6c8d8101a676e594 input=6682797320e48845]*/ +{ + return PyObject_GetItem(a, b); +} + +/*[clinic input] +_operator.setitem + + a: object + b: object + c: object + / + +Same as a[b] = c. +[clinic start generated code]*/ + +static PyObject * +_operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=1324f9061ae99e25 input=ceaf453c4d3a58df]*/ +{ + if (-1 == PyObject_SetItem(a, b, c)) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +_operator.delitem = _operator.getitem + +Same as del a[b]. +[clinic start generated code]*/ + +static PyObject * +_operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=db18f61506295799 input=991bec56a0d3ec7f]*/ +{ + if (-1 == PyObject_DelItem(a, b)) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +_operator.eq + + a: object + b: object + / + +Same as a == b. +[clinic start generated code]*/ + +static PyObject * +_operator_eq_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=8d7d46ed4135677c input=586fca687a95a83f]*/ +{ + return PyObject_RichCompare(a, b, Py_EQ); +} + +/*[clinic input] +_operator.ne = _operator.eq + +Same as a != b. +[clinic start generated code]*/ + +static PyObject * +_operator_ne_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=c99bd0c3a4c01297 input=5d88f23d35e9abac]*/ +{ + return PyObject_RichCompare(a, b, Py_NE); +} + +/*[clinic input] +_operator.lt = _operator.eq + +Same as a < b. +[clinic start generated code]*/ + +static PyObject * +_operator_lt_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=082d7c45c440e535 input=34a59ad6d39d3a2b]*/ +{ + return PyObject_RichCompare(a, b, Py_LT); +} + +/*[clinic input] +_operator.le = _operator.eq + +Same as a <= b. +[clinic start generated code]*/ + +static PyObject * +_operator_le_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=00970a2923d0ae17 input=b812a7860a0bef44]*/ +{ + return PyObject_RichCompare(a, b, Py_LE); +} + +/*[clinic input] +_operator.gt = _operator.eq + +Same as a > b. +[clinic start generated code]*/ + +static PyObject * +_operator_gt_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=8d373349ecf25641 input=9bdb45b995ada35b]*/ +{ + return PyObject_RichCompare(a, b, Py_GT); +} + +/*[clinic input] +_operator.ge = _operator.eq + +Same as a >= b. +[clinic start generated code]*/ + +static PyObject * +_operator_ge_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=7ce3882256d4b137 input=cf1dc4a5ca9c35f5]*/ +{ + return PyObject_RichCompare(a, b, Py_GE); +} + +/*[clinic input] +_operator.pow = _operator.add + +Same as a ** b. +[clinic start generated code]*/ + +static PyObject * +_operator_pow_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=09e668ad50036120 input=690b40f097ab1637]*/ +{ + return PyNumber_Power(a, b, Py_None); +} + +/*[clinic input] +_operator.ipow = _operator.add + +Same as a **= b. +[clinic start generated code]*/ + +static PyObject * +_operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=7189ff4d4367c808 input=f00623899d07499a]*/ +{ + return PyNumber_InPlacePower(a, b, Py_None); +} + +/*[clinic input] +_operator.index + + a: object + / + +Same as a.__index__() +[clinic start generated code]*/ + +static PyObject * +_operator_index(PyObject *module, PyObject *a) +/*[clinic end generated code: output=d972b0764ac305fc input=6f54d50ea64a579c]*/ +{ + return PyNumber_Index(a); +} + +/*[clinic input] +_operator.is_ = _operator.add + +Same as a is b. +[clinic start generated code]*/ + +static PyObject * +_operator_is__impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=bcd47a402e482e1d input=5fa9b97df03c427f]*/ +{ + PyObject *result; + result = (a == b) ? Py_True : Py_False; + Py_INCREF(result); + return result; +} + +/*[clinic input] +_operator.is_not = _operator.add + +Same as a is not b. +[clinic start generated code]*/ + +static PyObject * +_operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=491a1f2f81f6c7f9 input=5a93f7e1a93535f1]*/ +{ + PyObject *result; + result = (a != b) ? Py_True : Py_False; + Py_INCREF(result); + return result; +} + +/* compare_digest **********************************************************/ + +/* + * timing safe compare + * + * Returns 1 of the strings are equal. + * In case of len(a) != len(b) the function tries to keep the timing + * dependent on the length of b. CPU cache locally may still alter timing + * a bit. + */ +static int +_tscmp(const unsigned char *a, const unsigned char *b, + Py_ssize_t len_a, Py_ssize_t len_b) +{ + /* The volatile type declarations make sure that the compiler has no + * chance to optimize and fold the code in any way that may change + * the timing. + */ + volatile Py_ssize_t length; + volatile const unsigned char *left; + volatile const unsigned char *right; + Py_ssize_t i; volatile unsigned char result; - - /* loop count depends on length of b */ - length = len_b; - left = NULL; - right = b; - - /* don't use else here to keep the amount of CPU instructions constant, - * volatile forces re-evaluation - * */ - if (len_a == length) { - left = *((volatile const unsigned char**)&a); - result = 0; - } - if (len_a != length) { - left = b; - result = 1; - } - - for (i=0; i < length; i++) { - result |= *left++ ^ *right++; - } - - return (result == 0); -} - -/*[clinic input] -_operator.length_hint -> Py_ssize_t - - obj: object - default: Py_ssize_t = 0 - / - -Return an estimate of the number of items in obj. - -This is useful for presizing containers when building from an iterable. - -If the object supports len(), the result will be exact. -Otherwise, it may over- or under-estimate by an arbitrary amount. -The result will be an integer >= 0. -[clinic start generated code]*/ - -static Py_ssize_t -_operator_length_hint_impl(PyObject *module, PyObject *obj, - Py_ssize_t default_value) -/*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/ -{ - return PyObject_LengthHint(obj, default_value); -} - + + /* loop count depends on length of b */ + length = len_b; + left = NULL; + right = b; + + /* don't use else here to keep the amount of CPU instructions constant, + * volatile forces re-evaluation + * */ + if (len_a == length) { + left = *((volatile const unsigned char**)&a); + result = 0; + } + if (len_a != length) { + left = b; + result = 1; + } + + for (i=0; i < length; i++) { + result |= *left++ ^ *right++; + } + + return (result == 0); +} + +/*[clinic input] +_operator.length_hint -> Py_ssize_t + + obj: object + default: Py_ssize_t = 0 + / + +Return an estimate of the number of items in obj. + +This is useful for presizing containers when building from an iterable. + +If the object supports len(), the result will be exact. +Otherwise, it may over- or under-estimate by an arbitrary amount. +The result will be an integer >= 0. +[clinic start generated code]*/ + +static Py_ssize_t +_operator_length_hint_impl(PyObject *module, PyObject *obj, + Py_ssize_t default_value) +/*[clinic end generated code: output=01d469edc1d612ad input=65ed29f04401e96a]*/ +{ + return PyObject_LengthHint(obj, default_value); +} + /* NOTE: Keep in sync with _hashopenssl.c implementation. */ -/*[clinic input] -_operator._compare_digest = _operator.eq - -Return 'a == b'. - -This function uses an approach designed to prevent -timing analysis, making it appropriate for cryptography. - -a and b must both be of the same type: either str (ASCII only), -or any bytes-like object. - -Note: If a and b are of different lengths, or if an error occurs, -a timing attack could theoretically reveal information about the -types and lengths of a and b--but not their values. -[clinic start generated code]*/ - -static PyObject * -_operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/ -{ - int rc; - - /* ASCII unicode string */ - if(PyUnicode_Check(a) && PyUnicode_Check(b)) { - if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) { - return NULL; - } - if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) { - PyErr_SetString(PyExc_TypeError, - "comparing strings with non-ASCII characters is " - "not supported"); - return NULL; - } - - rc = _tscmp(PyUnicode_DATA(a), - PyUnicode_DATA(b), - PyUnicode_GET_LENGTH(a), - PyUnicode_GET_LENGTH(b)); - } - /* fallback to buffer interface for bytes, bytesarray and other */ - else { - Py_buffer view_a; - Py_buffer view_b; - - if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) { - PyErr_Format(PyExc_TypeError, - "unsupported operand types(s) or combination of types: " - "'%.100s' and '%.100s'", - Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); - return NULL; - } - - if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) { - return NULL; - } - if (view_a.ndim > 1) { - PyErr_SetString(PyExc_BufferError, - "Buffer must be single dimension"); - PyBuffer_Release(&view_a); - return NULL; - } - - if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) { - PyBuffer_Release(&view_a); - return NULL; - } - if (view_b.ndim > 1) { - PyErr_SetString(PyExc_BufferError, - "Buffer must be single dimension"); - PyBuffer_Release(&view_a); - PyBuffer_Release(&view_b); - return NULL; - } - - rc = _tscmp((const unsigned char*)view_a.buf, - (const unsigned char*)view_b.buf, - view_a.len, - view_b.len); - - PyBuffer_Release(&view_a); - PyBuffer_Release(&view_b); - } - - return PyBool_FromLong(rc); -} - -/* operator methods **********************************************************/ - -static struct PyMethodDef operator_methods[] = { - - _OPERATOR_TRUTH_METHODDEF - _OPERATOR_CONTAINS_METHODDEF - _OPERATOR_INDEXOF_METHODDEF - _OPERATOR_COUNTOF_METHODDEF - _OPERATOR_IS__METHODDEF - _OPERATOR_IS_NOT_METHODDEF - _OPERATOR_INDEX_METHODDEF - _OPERATOR_ADD_METHODDEF - _OPERATOR_SUB_METHODDEF - _OPERATOR_MUL_METHODDEF - _OPERATOR_MATMUL_METHODDEF - _OPERATOR_FLOORDIV_METHODDEF - _OPERATOR_TRUEDIV_METHODDEF - _OPERATOR_MOD_METHODDEF - _OPERATOR_NEG_METHODDEF - _OPERATOR_POS_METHODDEF - _OPERATOR_ABS_METHODDEF - _OPERATOR_INV_METHODDEF - _OPERATOR_INVERT_METHODDEF - _OPERATOR_LSHIFT_METHODDEF - _OPERATOR_RSHIFT_METHODDEF - _OPERATOR_NOT__METHODDEF - _OPERATOR_AND__METHODDEF - _OPERATOR_XOR_METHODDEF - _OPERATOR_OR__METHODDEF - _OPERATOR_IADD_METHODDEF - _OPERATOR_ISUB_METHODDEF - _OPERATOR_IMUL_METHODDEF - _OPERATOR_IMATMUL_METHODDEF - _OPERATOR_IFLOORDIV_METHODDEF - _OPERATOR_ITRUEDIV_METHODDEF - _OPERATOR_IMOD_METHODDEF - _OPERATOR_ILSHIFT_METHODDEF - _OPERATOR_IRSHIFT_METHODDEF - _OPERATOR_IAND_METHODDEF - _OPERATOR_IXOR_METHODDEF - _OPERATOR_IOR_METHODDEF - _OPERATOR_CONCAT_METHODDEF - _OPERATOR_ICONCAT_METHODDEF - _OPERATOR_GETITEM_METHODDEF - _OPERATOR_SETITEM_METHODDEF - _OPERATOR_DELITEM_METHODDEF - _OPERATOR_POW_METHODDEF - _OPERATOR_IPOW_METHODDEF - _OPERATOR_EQ_METHODDEF - _OPERATOR_NE_METHODDEF - _OPERATOR_LT_METHODDEF - _OPERATOR_LE_METHODDEF - _OPERATOR_GT_METHODDEF - _OPERATOR_GE_METHODDEF - _OPERATOR__COMPARE_DIGEST_METHODDEF - _OPERATOR_LENGTH_HINT_METHODDEF - {NULL, NULL} /* sentinel */ - -}; - -/* itemgetter object **********************************************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t nitems; - PyObject *item; +/*[clinic input] +_operator._compare_digest = _operator.eq + +Return 'a == b'. + +This function uses an approach designed to prevent +timing analysis, making it appropriate for cryptography. + +a and b must both be of the same type: either str (ASCII only), +or any bytes-like object. + +Note: If a and b are of different lengths, or if an error occurs, +a timing attack could theoretically reveal information about the +types and lengths of a and b--but not their values. +[clinic start generated code]*/ + +static PyObject * +_operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=11d452bdd3a23cbc input=9ac7e2c4e30bc356]*/ +{ + int rc; + + /* ASCII unicode string */ + if(PyUnicode_Check(a) && PyUnicode_Check(b)) { + if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) { + return NULL; + } + if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) { + PyErr_SetString(PyExc_TypeError, + "comparing strings with non-ASCII characters is " + "not supported"); + return NULL; + } + + rc = _tscmp(PyUnicode_DATA(a), + PyUnicode_DATA(b), + PyUnicode_GET_LENGTH(a), + PyUnicode_GET_LENGTH(b)); + } + /* fallback to buffer interface for bytes, bytesarray and other */ + else { + Py_buffer view_a; + Py_buffer view_b; + + if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) { + PyErr_Format(PyExc_TypeError, + "unsupported operand types(s) or combination of types: " + "'%.100s' and '%.100s'", + Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); + return NULL; + } + + if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) { + return NULL; + } + if (view_a.ndim > 1) { + PyErr_SetString(PyExc_BufferError, + "Buffer must be single dimension"); + PyBuffer_Release(&view_a); + return NULL; + } + + if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) { + PyBuffer_Release(&view_a); + return NULL; + } + if (view_b.ndim > 1) { + PyErr_SetString(PyExc_BufferError, + "Buffer must be single dimension"); + PyBuffer_Release(&view_a); + PyBuffer_Release(&view_b); + return NULL; + } + + rc = _tscmp((const unsigned char*)view_a.buf, + (const unsigned char*)view_b.buf, + view_a.len, + view_b.len); + + PyBuffer_Release(&view_a); + PyBuffer_Release(&view_b); + } + + return PyBool_FromLong(rc); +} + +/* operator methods **********************************************************/ + +static struct PyMethodDef operator_methods[] = { + + _OPERATOR_TRUTH_METHODDEF + _OPERATOR_CONTAINS_METHODDEF + _OPERATOR_INDEXOF_METHODDEF + _OPERATOR_COUNTOF_METHODDEF + _OPERATOR_IS__METHODDEF + _OPERATOR_IS_NOT_METHODDEF + _OPERATOR_INDEX_METHODDEF + _OPERATOR_ADD_METHODDEF + _OPERATOR_SUB_METHODDEF + _OPERATOR_MUL_METHODDEF + _OPERATOR_MATMUL_METHODDEF + _OPERATOR_FLOORDIV_METHODDEF + _OPERATOR_TRUEDIV_METHODDEF + _OPERATOR_MOD_METHODDEF + _OPERATOR_NEG_METHODDEF + _OPERATOR_POS_METHODDEF + _OPERATOR_ABS_METHODDEF + _OPERATOR_INV_METHODDEF + _OPERATOR_INVERT_METHODDEF + _OPERATOR_LSHIFT_METHODDEF + _OPERATOR_RSHIFT_METHODDEF + _OPERATOR_NOT__METHODDEF + _OPERATOR_AND__METHODDEF + _OPERATOR_XOR_METHODDEF + _OPERATOR_OR__METHODDEF + _OPERATOR_IADD_METHODDEF + _OPERATOR_ISUB_METHODDEF + _OPERATOR_IMUL_METHODDEF + _OPERATOR_IMATMUL_METHODDEF + _OPERATOR_IFLOORDIV_METHODDEF + _OPERATOR_ITRUEDIV_METHODDEF + _OPERATOR_IMOD_METHODDEF + _OPERATOR_ILSHIFT_METHODDEF + _OPERATOR_IRSHIFT_METHODDEF + _OPERATOR_IAND_METHODDEF + _OPERATOR_IXOR_METHODDEF + _OPERATOR_IOR_METHODDEF + _OPERATOR_CONCAT_METHODDEF + _OPERATOR_ICONCAT_METHODDEF + _OPERATOR_GETITEM_METHODDEF + _OPERATOR_SETITEM_METHODDEF + _OPERATOR_DELITEM_METHODDEF + _OPERATOR_POW_METHODDEF + _OPERATOR_IPOW_METHODDEF + _OPERATOR_EQ_METHODDEF + _OPERATOR_NE_METHODDEF + _OPERATOR_LT_METHODDEF + _OPERATOR_LE_METHODDEF + _OPERATOR_GT_METHODDEF + _OPERATOR_GE_METHODDEF + _OPERATOR__COMPARE_DIGEST_METHODDEF + _OPERATOR_LENGTH_HINT_METHODDEF + {NULL, NULL} /* sentinel */ + +}; + +/* itemgetter object **********************************************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t nitems; + PyObject *item; Py_ssize_t index; // -1 unless *item* is a single non-negative integer index -} itemgetterobject; - -static PyTypeObject itemgetter_type; - -/* AC 3.5: treats first argument as an iterable, otherwise uses *args */ -static PyObject * -itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - itemgetterobject *ig; - PyObject *item; - Py_ssize_t nitems; +} itemgetterobject; + +static PyTypeObject itemgetter_type; + +/* AC 3.5: treats first argument as an iterable, otherwise uses *args */ +static PyObject * +itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + itemgetterobject *ig; + PyObject *item; + Py_ssize_t nitems; Py_ssize_t index; - - if (!_PyArg_NoKeywords("itemgetter", kwds)) - return NULL; - - nitems = PyTuple_GET_SIZE(args); - if (nitems <= 1) { - if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item)) - return NULL; - } else - item = args; - - /* create itemgetterobject structure */ - ig = PyObject_GC_New(itemgetterobject, &itemgetter_type); - if (ig == NULL) - return NULL; - - Py_INCREF(item); - ig->item = item; - ig->nitems = nitems; + + if (!_PyArg_NoKeywords("itemgetter", kwds)) + return NULL; + + nitems = PyTuple_GET_SIZE(args); + if (nitems <= 1) { + if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item)) + return NULL; + } else + item = args; + + /* create itemgetterobject structure */ + ig = PyObject_GC_New(itemgetterobject, &itemgetter_type); + if (ig == NULL) + return NULL; + + Py_INCREF(item); + ig->item = item; + ig->nitems = nitems; ig->index = -1; if (PyLong_CheckExact(item)) { index = PyLong_AsSsize_t(item); @@ -986,37 +986,37 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ig->index = index; } } - - PyObject_GC_Track(ig); - return (PyObject *)ig; -} - -static void -itemgetter_dealloc(itemgetterobject *ig) -{ - PyObject_GC_UnTrack(ig); - Py_XDECREF(ig->item); - PyObject_GC_Del(ig); -} - -static int -itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg) -{ - Py_VISIT(ig->item); - return 0; -} - -static PyObject * -itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw) -{ - PyObject *obj, *result; - Py_ssize_t i, nitems=ig->nitems; - + + PyObject_GC_Track(ig); + return (PyObject *)ig; +} + +static void +itemgetter_dealloc(itemgetterobject *ig) +{ + PyObject_GC_UnTrack(ig); + Py_XDECREF(ig->item); + PyObject_GC_Del(ig); +} + +static int +itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg) +{ + Py_VISIT(ig->item); + return 0; +} + +static PyObject * +itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw) +{ + PyObject *obj, *result; + Py_ssize_t i, nitems=ig->nitems; + assert(PyTuple_CheckExact(args)); - if (!_PyArg_NoKeywords("itemgetter", kw)) - return NULL; + if (!_PyArg_NoKeywords("itemgetter", kw)) + return NULL; if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1)) - return NULL; + return NULL; obj = PyTuple_GET_ITEM(args, 0); if (nitems == 1) { @@ -1028,726 +1028,726 @@ itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw) Py_INCREF(result); return result; } - return PyObject_GetItem(obj, ig->item); - } - - assert(PyTuple_Check(ig->item)); - assert(PyTuple_GET_SIZE(ig->item) == nitems); - - result = PyTuple_New(nitems); - if (result == NULL) - return NULL; - - for (i=0 ; i < nitems ; i++) { - PyObject *item, *val; - item = PyTuple_GET_ITEM(ig->item, i); - val = PyObject_GetItem(obj, item); - if (val == NULL) { - Py_DECREF(result); - return NULL; - } - PyTuple_SET_ITEM(result, i, val); + return PyObject_GetItem(obj, ig->item); } - return result; -} - -static PyObject * -itemgetter_repr(itemgetterobject *ig) -{ - PyObject *repr; - const char *reprfmt; - - int status = Py_ReprEnter((PyObject *)ig); - if (status != 0) { - if (status < 0) - return NULL; - return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name); - } - - reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R"; - repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item); - Py_ReprLeave((PyObject *)ig); - return repr; -} - -static PyObject * + + assert(PyTuple_Check(ig->item)); + assert(PyTuple_GET_SIZE(ig->item) == nitems); + + result = PyTuple_New(nitems); + if (result == NULL) + return NULL; + + for (i=0 ; i < nitems ; i++) { + PyObject *item, *val; + item = PyTuple_GET_ITEM(ig->item, i); + val = PyObject_GetItem(obj, item); + if (val == NULL) { + Py_DECREF(result); + return NULL; + } + PyTuple_SET_ITEM(result, i, val); + } + return result; +} + +static PyObject * +itemgetter_repr(itemgetterobject *ig) +{ + PyObject *repr; + const char *reprfmt; + + int status = Py_ReprEnter((PyObject *)ig); + if (status != 0) { + if (status < 0) + return NULL; + return PyUnicode_FromFormat("%s(...)", Py_TYPE(ig)->tp_name); + } + + reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R"; + repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item); + Py_ReprLeave((PyObject *)ig); + return repr; +} + +static PyObject * itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored)) -{ - if (ig->nitems == 1) - return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item); - return PyTuple_Pack(2, Py_TYPE(ig), ig->item); -} - -PyDoc_STRVAR(reduce_doc, "Return state information for pickling"); - -static PyMethodDef itemgetter_methods[] = { - {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS, - reduce_doc}, - {NULL} -}; - -PyDoc_STRVAR(itemgetter_doc, -"itemgetter(item, ...) --> itemgetter object\n\ -\n\ -Return a callable object that fetches the given item(s) from its operand.\n\ -After f = itemgetter(2), the call f(r) returns r[2].\n\ -After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])"); - -static PyTypeObject itemgetter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.itemgetter", /* tp_name */ - sizeof(itemgetterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)itemgetter_dealloc, /* tp_dealloc */ +{ + if (ig->nitems == 1) + return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item); + return PyTuple_Pack(2, Py_TYPE(ig), ig->item); +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling"); + +static PyMethodDef itemgetter_methods[] = { + {"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS, + reduce_doc}, + {NULL} +}; + +PyDoc_STRVAR(itemgetter_doc, +"itemgetter(item, ...) --> itemgetter object\n\ +\n\ +Return a callable object that fetches the given item(s) from its operand.\n\ +After f = itemgetter(2), the call f(r) returns r[2].\n\ +After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])"); + +static PyTypeObject itemgetter_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "operator.itemgetter", /* tp_name */ + sizeof(itemgetterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)itemgetter_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)itemgetter_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)itemgetter_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - itemgetter_doc, /* tp_doc */ - (traverseproc)itemgetter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - itemgetter_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itemgetter_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/* attrgetter object **********************************************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t nattrs; - PyObject *attr; -} attrgetterobject; - -static PyTypeObject attrgetter_type; - -/* AC 3.5: treats first argument as an iterable, otherwise uses *args */ -static PyObject * -attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - attrgetterobject *ag; - PyObject *attr; - Py_ssize_t nattrs, idx, char_idx; - - if (!_PyArg_NoKeywords("attrgetter", kwds)) - return NULL; - - nattrs = PyTuple_GET_SIZE(args); - if (nattrs <= 1) { - if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr)) - return NULL; - } - - attr = PyTuple_New(nattrs); - if (attr == NULL) - return NULL; - - /* prepare attr while checking args */ - for (idx = 0; idx < nattrs; ++idx) { - PyObject *item = PyTuple_GET_ITEM(args, idx); - Py_ssize_t item_len; + (reprfunc)itemgetter_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)itemgetter_call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + itemgetter_doc, /* tp_doc */ + (traverseproc)itemgetter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + itemgetter_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + itemgetter_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/* attrgetter object **********************************************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t nattrs; + PyObject *attr; +} attrgetterobject; + +static PyTypeObject attrgetter_type; + +/* AC 3.5: treats first argument as an iterable, otherwise uses *args */ +static PyObject * +attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + attrgetterobject *ag; + PyObject *attr; + Py_ssize_t nattrs, idx, char_idx; + + if (!_PyArg_NoKeywords("attrgetter", kwds)) + return NULL; + + nattrs = PyTuple_GET_SIZE(args); + if (nattrs <= 1) { + if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr)) + return NULL; + } + + attr = PyTuple_New(nattrs); + if (attr == NULL) + return NULL; + + /* prepare attr while checking args */ + for (idx = 0; idx < nattrs; ++idx) { + PyObject *item = PyTuple_GET_ITEM(args, idx); + Py_ssize_t item_len; const void *data; - unsigned int kind; - int dot_count; - - if (!PyUnicode_Check(item)) { - PyErr_SetString(PyExc_TypeError, - "attribute name must be a string"); - Py_DECREF(attr); - return NULL; - } - if (PyUnicode_READY(item)) { - Py_DECREF(attr); - return NULL; - } - item_len = PyUnicode_GET_LENGTH(item); - kind = PyUnicode_KIND(item); - data = PyUnicode_DATA(item); - - /* check whethere the string is dotted */ - dot_count = 0; - for (char_idx = 0; char_idx < item_len; ++char_idx) { - if (PyUnicode_READ(kind, data, char_idx) == '.') - ++dot_count; - } - - if (dot_count == 0) { - Py_INCREF(item); - PyUnicode_InternInPlace(&item); - PyTuple_SET_ITEM(attr, idx, item); - } else { /* make it a tuple of non-dotted attrnames */ - PyObject *attr_chain = PyTuple_New(dot_count + 1); - PyObject *attr_chain_item; - Py_ssize_t unibuff_from = 0; - Py_ssize_t unibuff_till = 0; - Py_ssize_t attr_chain_idx = 0; - - if (attr_chain == NULL) { - Py_DECREF(attr); - return NULL; - } - - for (; dot_count > 0; --dot_count) { - while (PyUnicode_READ(kind, data, unibuff_till) != '.') { - ++unibuff_till; - } - attr_chain_item = PyUnicode_Substring(item, - unibuff_from, - unibuff_till); - if (attr_chain_item == NULL) { - Py_DECREF(attr_chain); - Py_DECREF(attr); - return NULL; - } - PyUnicode_InternInPlace(&attr_chain_item); - PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item); - ++attr_chain_idx; - unibuff_till = unibuff_from = unibuff_till + 1; - } - - /* now add the last dotless name */ - attr_chain_item = PyUnicode_Substring(item, - unibuff_from, item_len); - if (attr_chain_item == NULL) { - Py_DECREF(attr_chain); - Py_DECREF(attr); - return NULL; - } - PyUnicode_InternInPlace(&attr_chain_item); - PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item); - - PyTuple_SET_ITEM(attr, idx, attr_chain); - } - } - - /* create attrgetterobject structure */ - ag = PyObject_GC_New(attrgetterobject, &attrgetter_type); - if (ag == NULL) { - Py_DECREF(attr); - return NULL; - } - - ag->attr = attr; - ag->nattrs = nattrs; - - PyObject_GC_Track(ag); - return (PyObject *)ag; -} - -static void -attrgetter_dealloc(attrgetterobject *ag) -{ - PyObject_GC_UnTrack(ag); - Py_XDECREF(ag->attr); - PyObject_GC_Del(ag); -} - -static int -attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg) -{ - Py_VISIT(ag->attr); - return 0; -} - -static PyObject * -dotted_getattr(PyObject *obj, PyObject *attr) -{ - PyObject *newobj; - - /* attr is either a tuple or instance of str. - Ensured by the setup code of attrgetter_new */ - if (PyTuple_CheckExact(attr)) { /* chained getattr */ - Py_ssize_t name_idx = 0, name_count; - PyObject *attr_name; - - name_count = PyTuple_GET_SIZE(attr); - Py_INCREF(obj); - for (name_idx = 0; name_idx < name_count; ++name_idx) { - attr_name = PyTuple_GET_ITEM(attr, name_idx); - newobj = PyObject_GetAttr(obj, attr_name); - Py_DECREF(obj); - if (newobj == NULL) { - return NULL; - } - /* here */ - obj = newobj; - } - } else { /* single getattr */ - newobj = PyObject_GetAttr(obj, attr); - if (newobj == NULL) - return NULL; - obj = newobj; - } - - return obj; -} - -static PyObject * -attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw) -{ - PyObject *obj, *result; - Py_ssize_t i, nattrs=ag->nattrs; - - if (!_PyArg_NoKeywords("attrgetter", kw)) - return NULL; + unsigned int kind; + int dot_count; + + if (!PyUnicode_Check(item)) { + PyErr_SetString(PyExc_TypeError, + "attribute name must be a string"); + Py_DECREF(attr); + return NULL; + } + if (PyUnicode_READY(item)) { + Py_DECREF(attr); + return NULL; + } + item_len = PyUnicode_GET_LENGTH(item); + kind = PyUnicode_KIND(item); + data = PyUnicode_DATA(item); + + /* check whethere the string is dotted */ + dot_count = 0; + for (char_idx = 0; char_idx < item_len; ++char_idx) { + if (PyUnicode_READ(kind, data, char_idx) == '.') + ++dot_count; + } + + if (dot_count == 0) { + Py_INCREF(item); + PyUnicode_InternInPlace(&item); + PyTuple_SET_ITEM(attr, idx, item); + } else { /* make it a tuple of non-dotted attrnames */ + PyObject *attr_chain = PyTuple_New(dot_count + 1); + PyObject *attr_chain_item; + Py_ssize_t unibuff_from = 0; + Py_ssize_t unibuff_till = 0; + Py_ssize_t attr_chain_idx = 0; + + if (attr_chain == NULL) { + Py_DECREF(attr); + return NULL; + } + + for (; dot_count > 0; --dot_count) { + while (PyUnicode_READ(kind, data, unibuff_till) != '.') { + ++unibuff_till; + } + attr_chain_item = PyUnicode_Substring(item, + unibuff_from, + unibuff_till); + if (attr_chain_item == NULL) { + Py_DECREF(attr_chain); + Py_DECREF(attr); + return NULL; + } + PyUnicode_InternInPlace(&attr_chain_item); + PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item); + ++attr_chain_idx; + unibuff_till = unibuff_from = unibuff_till + 1; + } + + /* now add the last dotless name */ + attr_chain_item = PyUnicode_Substring(item, + unibuff_from, item_len); + if (attr_chain_item == NULL) { + Py_DECREF(attr_chain); + Py_DECREF(attr); + return NULL; + } + PyUnicode_InternInPlace(&attr_chain_item); + PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item); + + PyTuple_SET_ITEM(attr, idx, attr_chain); + } + } + + /* create attrgetterobject structure */ + ag = PyObject_GC_New(attrgetterobject, &attrgetter_type); + if (ag == NULL) { + Py_DECREF(attr); + return NULL; + } + + ag->attr = attr; + ag->nattrs = nattrs; + + PyObject_GC_Track(ag); + return (PyObject *)ag; +} + +static void +attrgetter_dealloc(attrgetterobject *ag) +{ + PyObject_GC_UnTrack(ag); + Py_XDECREF(ag->attr); + PyObject_GC_Del(ag); +} + +static int +attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg) +{ + Py_VISIT(ag->attr); + return 0; +} + +static PyObject * +dotted_getattr(PyObject *obj, PyObject *attr) +{ + PyObject *newobj; + + /* attr is either a tuple or instance of str. + Ensured by the setup code of attrgetter_new */ + if (PyTuple_CheckExact(attr)) { /* chained getattr */ + Py_ssize_t name_idx = 0, name_count; + PyObject *attr_name; + + name_count = PyTuple_GET_SIZE(attr); + Py_INCREF(obj); + for (name_idx = 0; name_idx < name_count; ++name_idx) { + attr_name = PyTuple_GET_ITEM(attr, name_idx); + newobj = PyObject_GetAttr(obj, attr_name); + Py_DECREF(obj); + if (newobj == NULL) { + return NULL; + } + /* here */ + obj = newobj; + } + } else { /* single getattr */ + newobj = PyObject_GetAttr(obj, attr); + if (newobj == NULL) + return NULL; + obj = newobj; + } + + return obj; +} + +static PyObject * +attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw) +{ + PyObject *obj, *result; + Py_ssize_t i, nattrs=ag->nattrs; + + if (!_PyArg_NoKeywords("attrgetter", kw)) + return NULL; if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1)) - return NULL; + return NULL; obj = PyTuple_GET_ITEM(args, 0); - if (ag->nattrs == 1) /* ag->attr is always a tuple */ - return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0)); - - assert(PyTuple_Check(ag->attr)); - assert(PyTuple_GET_SIZE(ag->attr) == nattrs); - - result = PyTuple_New(nattrs); - if (result == NULL) - return NULL; - - for (i=0 ; i < nattrs ; i++) { - PyObject *attr, *val; - attr = PyTuple_GET_ITEM(ag->attr, i); - val = dotted_getattr(obj, attr); - if (val == NULL) { - Py_DECREF(result); - return NULL; - } - PyTuple_SET_ITEM(result, i, val); - } - return result; -} - -static PyObject * -dotjoinattr(PyObject *attr, PyObject **attrsep) -{ - if (PyTuple_CheckExact(attr)) { - if (*attrsep == NULL) { - *attrsep = PyUnicode_FromString("."); - if (*attrsep == NULL) - return NULL; - } - return PyUnicode_Join(*attrsep, attr); - } else { - Py_INCREF(attr); - return attr; - } -} - -static PyObject * -attrgetter_args(attrgetterobject *ag) -{ - Py_ssize_t i; - PyObject *attrsep = NULL; - PyObject *attrstrings = PyTuple_New(ag->nattrs); - if (attrstrings == NULL) - return NULL; - - for (i = 0; i < ag->nattrs; ++i) { - PyObject *attr = PyTuple_GET_ITEM(ag->attr, i); - PyObject *attrstr = dotjoinattr(attr, &attrsep); - if (attrstr == NULL) { - Py_XDECREF(attrsep); - Py_DECREF(attrstrings); - return NULL; - } - PyTuple_SET_ITEM(attrstrings, i, attrstr); - } - Py_XDECREF(attrsep); - return attrstrings; -} - -static PyObject * -attrgetter_repr(attrgetterobject *ag) -{ - PyObject *repr = NULL; - int status = Py_ReprEnter((PyObject *)ag); - if (status != 0) { - if (status < 0) - return NULL; - return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name); - } - - if (ag->nattrs == 1) { - PyObject *attrsep = NULL; - PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep); - if (attr != NULL) { - repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr); - Py_DECREF(attr); - } - Py_XDECREF(attrsep); - } - else { - PyObject *attrstrings = attrgetter_args(ag); - if (attrstrings != NULL) { - repr = PyUnicode_FromFormat("%s%R", - Py_TYPE(ag)->tp_name, attrstrings); - Py_DECREF(attrstrings); - } - } - Py_ReprLeave((PyObject *)ag); - return repr; -} - -static PyObject * + if (ag->nattrs == 1) /* ag->attr is always a tuple */ + return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0)); + + assert(PyTuple_Check(ag->attr)); + assert(PyTuple_GET_SIZE(ag->attr) == nattrs); + + result = PyTuple_New(nattrs); + if (result == NULL) + return NULL; + + for (i=0 ; i < nattrs ; i++) { + PyObject *attr, *val; + attr = PyTuple_GET_ITEM(ag->attr, i); + val = dotted_getattr(obj, attr); + if (val == NULL) { + Py_DECREF(result); + return NULL; + } + PyTuple_SET_ITEM(result, i, val); + } + return result; +} + +static PyObject * +dotjoinattr(PyObject *attr, PyObject **attrsep) +{ + if (PyTuple_CheckExact(attr)) { + if (*attrsep == NULL) { + *attrsep = PyUnicode_FromString("."); + if (*attrsep == NULL) + return NULL; + } + return PyUnicode_Join(*attrsep, attr); + } else { + Py_INCREF(attr); + return attr; + } +} + +static PyObject * +attrgetter_args(attrgetterobject *ag) +{ + Py_ssize_t i; + PyObject *attrsep = NULL; + PyObject *attrstrings = PyTuple_New(ag->nattrs); + if (attrstrings == NULL) + return NULL; + + for (i = 0; i < ag->nattrs; ++i) { + PyObject *attr = PyTuple_GET_ITEM(ag->attr, i); + PyObject *attrstr = dotjoinattr(attr, &attrsep); + if (attrstr == NULL) { + Py_XDECREF(attrsep); + Py_DECREF(attrstrings); + return NULL; + } + PyTuple_SET_ITEM(attrstrings, i, attrstr); + } + Py_XDECREF(attrsep); + return attrstrings; +} + +static PyObject * +attrgetter_repr(attrgetterobject *ag) +{ + PyObject *repr = NULL; + int status = Py_ReprEnter((PyObject *)ag); + if (status != 0) { + if (status < 0) + return NULL; + return PyUnicode_FromFormat("%s(...)", Py_TYPE(ag)->tp_name); + } + + if (ag->nattrs == 1) { + PyObject *attrsep = NULL; + PyObject *attr = dotjoinattr(PyTuple_GET_ITEM(ag->attr, 0), &attrsep); + if (attr != NULL) { + repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(ag)->tp_name, attr); + Py_DECREF(attr); + } + Py_XDECREF(attrsep); + } + else { + PyObject *attrstrings = attrgetter_args(ag); + if (attrstrings != NULL) { + repr = PyUnicode_FromFormat("%s%R", + Py_TYPE(ag)->tp_name, attrstrings); + Py_DECREF(attrstrings); + } + } + Py_ReprLeave((PyObject *)ag); + return repr; +} + +static PyObject * attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored)) -{ - PyObject *attrstrings = attrgetter_args(ag); - if (attrstrings == NULL) - return NULL; - - return Py_BuildValue("ON", Py_TYPE(ag), attrstrings); -} - -static PyMethodDef attrgetter_methods[] = { - {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS, - reduce_doc}, - {NULL} -}; - -PyDoc_STRVAR(attrgetter_doc, -"attrgetter(attr, ...) --> attrgetter object\n\ -\n\ -Return a callable object that fetches the given attribute(s) from its operand.\n\ -After f = attrgetter('name'), the call f(r) returns r.name.\n\ -After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\ -After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\ -(r.name.first, r.name.last)."); - -static PyTypeObject attrgetter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.attrgetter", /* tp_name */ - sizeof(attrgetterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)attrgetter_dealloc, /* tp_dealloc */ +{ + PyObject *attrstrings = attrgetter_args(ag); + if (attrstrings == NULL) + return NULL; + + return Py_BuildValue("ON", Py_TYPE(ag), attrstrings); +} + +static PyMethodDef attrgetter_methods[] = { + {"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS, + reduce_doc}, + {NULL} +}; + +PyDoc_STRVAR(attrgetter_doc, +"attrgetter(attr, ...) --> attrgetter object\n\ +\n\ +Return a callable object that fetches the given attribute(s) from its operand.\n\ +After f = attrgetter('name'), the call f(r) returns r.name.\n\ +After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\ +After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\ +(r.name.first, r.name.last)."); + +static PyTypeObject attrgetter_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "operator.attrgetter", /* tp_name */ + sizeof(attrgetterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)attrgetter_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)attrgetter_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)attrgetter_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - attrgetter_doc, /* tp_doc */ - (traverseproc)attrgetter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - attrgetter_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - attrgetter_new, /* tp_new */ - 0, /* tp_free */ -}; - - -/* methodcaller object **********************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *name; - PyObject *args; - PyObject *kwds; -} methodcallerobject; - -static PyTypeObject methodcaller_type; - -/* AC 3.5: variable number of arguments, not currently support by AC */ -static PyObject * -methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - methodcallerobject *mc; - PyObject *name; - - if (PyTuple_GET_SIZE(args) < 1) { - PyErr_SetString(PyExc_TypeError, "methodcaller needs at least " - "one argument, the method name"); - return NULL; - } - - name = PyTuple_GET_ITEM(args, 0); - if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, - "method name must be a string"); - return NULL; - } - - /* create methodcallerobject structure */ - mc = PyObject_GC_New(methodcallerobject, &methodcaller_type); - if (mc == NULL) - return NULL; - - name = PyTuple_GET_ITEM(args, 0); - Py_INCREF(name); - PyUnicode_InternInPlace(&name); - mc->name = name; - - Py_XINCREF(kwds); - mc->kwds = kwds; - - mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); - if (mc->args == NULL) { - Py_DECREF(mc); - return NULL; - } - - PyObject_GC_Track(mc); - return (PyObject *)mc; -} - -static void -methodcaller_dealloc(methodcallerobject *mc) -{ - PyObject_GC_UnTrack(mc); - Py_XDECREF(mc->name); - Py_XDECREF(mc->args); - Py_XDECREF(mc->kwds); - PyObject_GC_Del(mc); -} - -static int -methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg) -{ - Py_VISIT(mc->args); - Py_VISIT(mc->kwds); - return 0; -} - -static PyObject * -methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw) -{ - PyObject *method, *obj, *result; - - if (!_PyArg_NoKeywords("methodcaller", kw)) - return NULL; + (reprfunc)attrgetter_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)attrgetter_call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + attrgetter_doc, /* tp_doc */ + (traverseproc)attrgetter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + attrgetter_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + attrgetter_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/* methodcaller object **********************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *args; + PyObject *kwds; +} methodcallerobject; + +static PyTypeObject methodcaller_type; + +/* AC 3.5: variable number of arguments, not currently support by AC */ +static PyObject * +methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + methodcallerobject *mc; + PyObject *name; + + if (PyTuple_GET_SIZE(args) < 1) { + PyErr_SetString(PyExc_TypeError, "methodcaller needs at least " + "one argument, the method name"); + return NULL; + } + + name = PyTuple_GET_ITEM(args, 0); + if (!PyUnicode_Check(name)) { + PyErr_SetString(PyExc_TypeError, + "method name must be a string"); + return NULL; + } + + /* create methodcallerobject structure */ + mc = PyObject_GC_New(methodcallerobject, &methodcaller_type); + if (mc == NULL) + return NULL; + + name = PyTuple_GET_ITEM(args, 0); + Py_INCREF(name); + PyUnicode_InternInPlace(&name); + mc->name = name; + + Py_XINCREF(kwds); + mc->kwds = kwds; + + mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + if (mc->args == NULL) { + Py_DECREF(mc); + return NULL; + } + + PyObject_GC_Track(mc); + return (PyObject *)mc; +} + +static void +methodcaller_dealloc(methodcallerobject *mc) +{ + PyObject_GC_UnTrack(mc); + Py_XDECREF(mc->name); + Py_XDECREF(mc->args); + Py_XDECREF(mc->kwds); + PyObject_GC_Del(mc); +} + +static int +methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg) +{ + Py_VISIT(mc->args); + Py_VISIT(mc->kwds); + return 0; +} + +static PyObject * +methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw) +{ + PyObject *method, *obj, *result; + + if (!_PyArg_NoKeywords("methodcaller", kw)) + return NULL; if (!_PyArg_CheckPositional("methodcaller", PyTuple_GET_SIZE(args), 1, 1)) - return NULL; + return NULL; obj = PyTuple_GET_ITEM(args, 0); - method = PyObject_GetAttr(obj, mc->name); - if (method == NULL) - return NULL; - result = PyObject_Call(method, mc->args, mc->kwds); - Py_DECREF(method); - return result; -} - -static PyObject * -methodcaller_repr(methodcallerobject *mc) -{ - PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs; - Py_ssize_t numtotalargs, numposargs, numkwdargs, i; - int status = Py_ReprEnter((PyObject *)mc); - if (status != 0) { - if (status < 0) - return NULL; - return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name); - } - - numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0; - numposargs = PyTuple_GET_SIZE(mc->args); - numtotalargs = numposargs + numkwdargs; - - if (numtotalargs == 0) { - repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name); - Py_ReprLeave((PyObject *)mc); - return repr; - } - - argreprs = PyTuple_New(numtotalargs); - if (argreprs == NULL) { - Py_ReprLeave((PyObject *)mc); - return NULL; - } - - for (i = 0; i < numposargs; ++i) { - PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i)); - if (onerepr == NULL) - goto done; - PyTuple_SET_ITEM(argreprs, i, onerepr); - } - - if (numkwdargs != 0) { - PyObject *key, *value; - Py_ssize_t pos = 0; - while (PyDict_Next(mc->kwds, &pos, &key, &value)) { - PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value); - if (onerepr == NULL) - goto done; - if (i >= numtotalargs) { - i = -1; - Py_DECREF(onerepr); - break; - } - PyTuple_SET_ITEM(argreprs, i, onerepr); - ++i; - } - if (i != numtotalargs) { - PyErr_SetString(PyExc_RuntimeError, - "keywords dict changed size during iteration"); - goto done; - } - } - - sep = PyUnicode_FromString(", "); - if (sep == NULL) - goto done; - - joinedargreprs = PyUnicode_Join(sep, argreprs); - Py_DECREF(sep); - if (joinedargreprs == NULL) - goto done; - - repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name, - mc->name, joinedargreprs); - Py_DECREF(joinedargreprs); - -done: - Py_DECREF(argreprs); - Py_ReprLeave((PyObject *)mc); - return repr; -} - -static PyObject * + method = PyObject_GetAttr(obj, mc->name); + if (method == NULL) + return NULL; + result = PyObject_Call(method, mc->args, mc->kwds); + Py_DECREF(method); + return result; +} + +static PyObject * +methodcaller_repr(methodcallerobject *mc) +{ + PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs; + Py_ssize_t numtotalargs, numposargs, numkwdargs, i; + int status = Py_ReprEnter((PyObject *)mc); + if (status != 0) { + if (status < 0) + return NULL; + return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name); + } + + numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0; + numposargs = PyTuple_GET_SIZE(mc->args); + numtotalargs = numposargs + numkwdargs; + + if (numtotalargs == 0) { + repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name); + Py_ReprLeave((PyObject *)mc); + return repr; + } + + argreprs = PyTuple_New(numtotalargs); + if (argreprs == NULL) { + Py_ReprLeave((PyObject *)mc); + return NULL; + } + + for (i = 0; i < numposargs; ++i) { + PyObject *onerepr = PyObject_Repr(PyTuple_GET_ITEM(mc->args, i)); + if (onerepr == NULL) + goto done; + PyTuple_SET_ITEM(argreprs, i, onerepr); + } + + if (numkwdargs != 0) { + PyObject *key, *value; + Py_ssize_t pos = 0; + while (PyDict_Next(mc->kwds, &pos, &key, &value)) { + PyObject *onerepr = PyUnicode_FromFormat("%U=%R", key, value); + if (onerepr == NULL) + goto done; + if (i >= numtotalargs) { + i = -1; + Py_DECREF(onerepr); + break; + } + PyTuple_SET_ITEM(argreprs, i, onerepr); + ++i; + } + if (i != numtotalargs) { + PyErr_SetString(PyExc_RuntimeError, + "keywords dict changed size during iteration"); + goto done; + } + } + + sep = PyUnicode_FromString(", "); + if (sep == NULL) + goto done; + + joinedargreprs = PyUnicode_Join(sep, argreprs); + Py_DECREF(sep); + if (joinedargreprs == NULL) + goto done; + + repr = PyUnicode_FromFormat("%s(%R, %U)", Py_TYPE(mc)->tp_name, + mc->name, joinedargreprs); + Py_DECREF(joinedargreprs); + +done: + Py_DECREF(argreprs); + Py_ReprLeave((PyObject *)mc); + return repr; +} + +static PyObject * methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored)) -{ - PyObject *newargs; - if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) { - Py_ssize_t i; - Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args); - newargs = PyTuple_New(1 + callargcount); - if (newargs == NULL) - return NULL; - Py_INCREF(mc->name); - PyTuple_SET_ITEM(newargs, 0, mc->name); - for (i = 0; i < callargcount; ++i) { - PyObject *arg = PyTuple_GET_ITEM(mc->args, i); - Py_INCREF(arg); - PyTuple_SET_ITEM(newargs, i + 1, arg); - } - return Py_BuildValue("ON", Py_TYPE(mc), newargs); - } - else { - PyObject *functools; - PyObject *partial; - PyObject *constructor; - PyObject *newargs[2]; - - _Py_IDENTIFIER(partial); - functools = PyImport_ImportModule("functools"); - if (!functools) - return NULL; - partial = _PyObject_GetAttrId(functools, &PyId_partial); - Py_DECREF(functools); - if (!partial) - return NULL; - - newargs[0] = (PyObject *)Py_TYPE(mc); - newargs[1] = mc->name; +{ + PyObject *newargs; + if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) { + Py_ssize_t i; + Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args); + newargs = PyTuple_New(1 + callargcount); + if (newargs == NULL) + return NULL; + Py_INCREF(mc->name); + PyTuple_SET_ITEM(newargs, 0, mc->name); + for (i = 0; i < callargcount; ++i) { + PyObject *arg = PyTuple_GET_ITEM(mc->args, i); + Py_INCREF(arg); + PyTuple_SET_ITEM(newargs, i + 1, arg); + } + return Py_BuildValue("ON", Py_TYPE(mc), newargs); + } + else { + PyObject *functools; + PyObject *partial; + PyObject *constructor; + PyObject *newargs[2]; + + _Py_IDENTIFIER(partial); + functools = PyImport_ImportModule("functools"); + if (!functools) + return NULL; + partial = _PyObject_GetAttrId(functools, &PyId_partial); + Py_DECREF(functools); + if (!partial) + return NULL; + + newargs[0] = (PyObject *)Py_TYPE(mc); + newargs[1] = mc->name; constructor = PyObject_VectorcallDict(partial, newargs, 2, mc->kwds); - - Py_DECREF(partial); - return Py_BuildValue("NO", constructor, mc->args); - } -} - -static PyMethodDef methodcaller_methods[] = { - {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS, - reduce_doc}, - {NULL} -}; -PyDoc_STRVAR(methodcaller_doc, -"methodcaller(name, ...) --> methodcaller object\n\ -\n\ -Return a callable object that calls the given method on its operand.\n\ -After f = methodcaller('name'), the call f(r) returns r.name().\n\ -After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\ -r.name('date', foo=1)."); - -static PyTypeObject methodcaller_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "operator.methodcaller", /* tp_name */ - sizeof(methodcallerobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)methodcaller_dealloc, /* tp_dealloc */ + + Py_DECREF(partial); + return Py_BuildValue("NO", constructor, mc->args); + } +} + +static PyMethodDef methodcaller_methods[] = { + {"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS, + reduce_doc}, + {NULL} +}; +PyDoc_STRVAR(methodcaller_doc, +"methodcaller(name, ...) --> methodcaller object\n\ +\n\ +Return a callable object that calls the given method on its operand.\n\ +After f = methodcaller('name'), the call f(r) returns r.name().\n\ +After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\ +r.name('date', foo=1)."); + +static PyTypeObject methodcaller_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "operator.methodcaller", /* tp_name */ + sizeof(methodcallerobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)methodcaller_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)methodcaller_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)methodcaller_call, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - methodcaller_doc, /* tp_doc */ - (traverseproc)methodcaller_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - methodcaller_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - methodcaller_new, /* tp_new */ - 0, /* tp_free */ -}; - - + (reprfunc)methodcaller_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)methodcaller_call, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + methodcaller_doc, /* tp_doc */ + (traverseproc)methodcaller_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + methodcaller_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + methodcaller_new, /* tp_new */ + 0, /* tp_free */ +}; + + static int operator_exec(PyObject *module) { @@ -1756,13 +1756,13 @@ operator_exec(PyObject *module) &attrgetter_type, &methodcaller_type }; - + for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { if (PyModule_AddType(module, types[i]) < 0) { return -1; } } - + return 0; } @@ -1773,20 +1773,20 @@ static struct PyModuleDef_Slot operator_slots[] = { }; -static struct PyModuleDef operatormodule = { - PyModuleDef_HEAD_INIT, - "_operator", - operator_doc, +static struct PyModuleDef operatormodule = { + PyModuleDef_HEAD_INIT, + "_operator", + operator_doc, 0, - operator_methods, + operator_methods, operator_slots, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__operator(void) -{ + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__operator(void) +{ return PyModuleDef_Init(&operatormodule); -} +} diff --git a/contrib/tools/python3/src/Modules/_pickle.c b/contrib/tools/python3/src/Modules/_pickle.c index 30bb5c0d75c..a9332342526 100644 --- a/contrib/tools/python3/src/Modules/_pickle.c +++ b/contrib/tools/python3/src/Modules/_pickle.c @@ -3,8060 +3,8060 @@ * It is built as a built-in module (Py_BUILD_CORE_BUILTIN define) on Windows * and as an extension module (Py_BUILD_CORE_MODULE define) on other * platforms. */ - + #if !defined(Py_BUILD_CORE_BUILTIN) && !defined(Py_BUILD_CORE_MODULE) # error "Py_BUILD_CORE_BUILTIN or Py_BUILD_CORE_MODULE must be defined" -#endif - -#include "Python.h" +#endif + +#include "Python.h" #include "structmember.h" // PyMemberDef - -PyDoc_STRVAR(pickle_module_doc, -"Optimized C implementation for the Python pickle module."); - -/*[clinic input] -module _pickle -class _pickle.Pickler "PicklerObject *" "&Pickler_Type" -class _pickle.PicklerMemoProxy "PicklerMemoProxyObject *" "&PicklerMemoProxyType" -class _pickle.Unpickler "UnpicklerObject *" "&Unpickler_Type" -class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "&UnpicklerMemoProxyType" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b3e113468a58e6c]*/ - + +PyDoc_STRVAR(pickle_module_doc, +"Optimized C implementation for the Python pickle module."); + +/*[clinic input] +module _pickle +class _pickle.Pickler "PicklerObject *" "&Pickler_Type" +class _pickle.PicklerMemoProxy "PicklerMemoProxyObject *" "&PicklerMemoProxyType" +class _pickle.Unpickler "UnpicklerObject *" "&Unpickler_Type" +class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "&UnpicklerMemoProxyType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b3e113468a58e6c]*/ + /* Bump HIGHEST_PROTOCOL when new opcodes are added to the pickle protocol. Bump DEFAULT_PROTOCOL only when the oldest still supported version of Python already includes it. */ -enum { +enum { HIGHEST_PROTOCOL = 5, DEFAULT_PROTOCOL = 4 -}; - -/* Pickle opcodes. These must be kept updated with pickle.py. - Extensive docs are in pickletools.py. */ -enum opcode { - MARK = '(', - STOP = '.', - POP = '0', - POP_MARK = '1', - DUP = '2', +}; + +/* Pickle opcodes. These must be kept updated with pickle.py. + Extensive docs are in pickletools.py. */ +enum opcode { + MARK = '(', + STOP = '.', + POP = '0', + POP_MARK = '1', + DUP = '2', FLOAT_ = 'F', INT_ = 'I', - BININT = 'J', - BININT1 = 'K', + BININT = 'J', + BININT1 = 'K', LONG_ = 'L', - BININT2 = 'M', - NONE = 'N', - PERSID = 'P', - BINPERSID = 'Q', - REDUCE = 'R', - STRING = 'S', - BINSTRING = 'T', - SHORT_BINSTRING = 'U', - UNICODE = 'V', - BINUNICODE = 'X', - APPEND = 'a', - BUILD = 'b', - GLOBAL = 'c', - DICT = 'd', - EMPTY_DICT = '}', - APPENDS = 'e', - GET = 'g', - BINGET = 'h', - INST = 'i', - LONG_BINGET = 'j', - LIST = 'l', - EMPTY_LIST = ']', - OBJ = 'o', - PUT = 'p', - BINPUT = 'q', - LONG_BINPUT = 'r', - SETITEM = 's', - TUPLE = 't', - EMPTY_TUPLE = ')', - SETITEMS = 'u', - BINFLOAT = 'G', - - /* Protocol 2. */ - PROTO = '\x80', - NEWOBJ = '\x81', - EXT1 = '\x82', - EXT2 = '\x83', - EXT4 = '\x84', - TUPLE1 = '\x85', - TUPLE2 = '\x86', - TUPLE3 = '\x87', - NEWTRUE = '\x88', - NEWFALSE = '\x89', - LONG1 = '\x8a', - LONG4 = '\x8b', - - /* Protocol 3 (Python 3.x) */ - BINBYTES = 'B', - SHORT_BINBYTES = 'C', - - /* Protocol 4 */ - SHORT_BINUNICODE = '\x8c', - BINUNICODE8 = '\x8d', - BINBYTES8 = '\x8e', - EMPTY_SET = '\x8f', - ADDITEMS = '\x90', - FROZENSET = '\x91', - NEWOBJ_EX = '\x92', - STACK_GLOBAL = '\x93', - MEMOIZE = '\x94', + BININT2 = 'M', + NONE = 'N', + PERSID = 'P', + BINPERSID = 'Q', + REDUCE = 'R', + STRING = 'S', + BINSTRING = 'T', + SHORT_BINSTRING = 'U', + UNICODE = 'V', + BINUNICODE = 'X', + APPEND = 'a', + BUILD = 'b', + GLOBAL = 'c', + DICT = 'd', + EMPTY_DICT = '}', + APPENDS = 'e', + GET = 'g', + BINGET = 'h', + INST = 'i', + LONG_BINGET = 'j', + LIST = 'l', + EMPTY_LIST = ']', + OBJ = 'o', + PUT = 'p', + BINPUT = 'q', + LONG_BINPUT = 'r', + SETITEM = 's', + TUPLE = 't', + EMPTY_TUPLE = ')', + SETITEMS = 'u', + BINFLOAT = 'G', + + /* Protocol 2. */ + PROTO = '\x80', + NEWOBJ = '\x81', + EXT1 = '\x82', + EXT2 = '\x83', + EXT4 = '\x84', + TUPLE1 = '\x85', + TUPLE2 = '\x86', + TUPLE3 = '\x87', + NEWTRUE = '\x88', + NEWFALSE = '\x89', + LONG1 = '\x8a', + LONG4 = '\x8b', + + /* Protocol 3 (Python 3.x) */ + BINBYTES = 'B', + SHORT_BINBYTES = 'C', + + /* Protocol 4 */ + SHORT_BINUNICODE = '\x8c', + BINUNICODE8 = '\x8d', + BINBYTES8 = '\x8e', + EMPTY_SET = '\x8f', + ADDITEMS = '\x90', + FROZENSET = '\x91', + NEWOBJ_EX = '\x92', + STACK_GLOBAL = '\x93', + MEMOIZE = '\x94', FRAME = '\x95', /* Protocol 5 */ BYTEARRAY8 = '\x96', NEXT_BUFFER = '\x97', READONLY_BUFFER = '\x98' -}; - -enum { - /* Keep in synch with pickle.Pickler._BATCHSIZE. This is how many elements - batch_list/dict() pumps out before doing APPENDS/SETITEMS. Nothing will - break if this gets out of synch with pickle.py, but it's unclear that would - help anything either. */ - BATCHSIZE = 1000, - - /* Nesting limit until Pickler, when running in "fast mode", starts - checking for self-referential data-structures. */ - FAST_NESTING_LIMIT = 50, - - /* Initial size of the write buffer of Pickler. */ - WRITE_BUF_SIZE = 4096, - - /* Prefetch size when unpickling (disabled on unpeekable streams) */ - PREFETCH = 8192 * 16, - - FRAME_SIZE_MIN = 4, - FRAME_SIZE_TARGET = 64 * 1024, - FRAME_HEADER_SIZE = 9 -}; - -/*************************************************************************/ - -/* State of the pickle module, per PEP 3121. */ -typedef struct { - /* Exception classes for pickle. */ - PyObject *PickleError; - PyObject *PicklingError; - PyObject *UnpicklingError; - - /* copyreg.dispatch_table, {type_object: pickling_function} */ - PyObject *dispatch_table; - - /* For the extension opcodes EXT1, EXT2 and EXT4. */ - - /* copyreg._extension_registry, {(module_name, function_name): code} */ - PyObject *extension_registry; - /* copyreg._extension_cache, {code: object} */ - PyObject *extension_cache; - /* copyreg._inverted_registry, {code: (module_name, function_name)} */ - PyObject *inverted_registry; - - /* Import mappings for compatibility with Python 2.x */ - - /* _compat_pickle.NAME_MAPPING, - {(oldmodule, oldname): (newmodule, newname)} */ - PyObject *name_mapping_2to3; - /* _compat_pickle.IMPORT_MAPPING, {oldmodule: newmodule} */ - PyObject *import_mapping_2to3; - /* Same, but with REVERSE_NAME_MAPPING / REVERSE_IMPORT_MAPPING */ - PyObject *name_mapping_3to2; - PyObject *import_mapping_3to2; - - /* codecs.encode, used for saving bytes in older protocols */ - PyObject *codecs_encode; - /* builtins.getattr, used for saving nested names with protocol < 4 */ - PyObject *getattr; - /* functools.partial, used for implementing __newobj_ex__ with protocols - 2 and 3 */ - PyObject *partial; -} PickleState; - -/* Forward declaration of the _pickle module definition. */ -static struct PyModuleDef _picklemodule; - -/* Given a module object, get its per-module state. */ -static PickleState * -_Pickle_GetState(PyObject *module) -{ - return (PickleState *)PyModule_GetState(module); -} +}; + +enum { + /* Keep in synch with pickle.Pickler._BATCHSIZE. This is how many elements + batch_list/dict() pumps out before doing APPENDS/SETITEMS. Nothing will + break if this gets out of synch with pickle.py, but it's unclear that would + help anything either. */ + BATCHSIZE = 1000, + + /* Nesting limit until Pickler, when running in "fast mode", starts + checking for self-referential data-structures. */ + FAST_NESTING_LIMIT = 50, + + /* Initial size of the write buffer of Pickler. */ + WRITE_BUF_SIZE = 4096, + + /* Prefetch size when unpickling (disabled on unpeekable streams) */ + PREFETCH = 8192 * 16, + + FRAME_SIZE_MIN = 4, + FRAME_SIZE_TARGET = 64 * 1024, + FRAME_HEADER_SIZE = 9 +}; + +/*************************************************************************/ + +/* State of the pickle module, per PEP 3121. */ +typedef struct { + /* Exception classes for pickle. */ + PyObject *PickleError; + PyObject *PicklingError; + PyObject *UnpicklingError; + + /* copyreg.dispatch_table, {type_object: pickling_function} */ + PyObject *dispatch_table; + + /* For the extension opcodes EXT1, EXT2 and EXT4. */ + + /* copyreg._extension_registry, {(module_name, function_name): code} */ + PyObject *extension_registry; + /* copyreg._extension_cache, {code: object} */ + PyObject *extension_cache; + /* copyreg._inverted_registry, {code: (module_name, function_name)} */ + PyObject *inverted_registry; + + /* Import mappings for compatibility with Python 2.x */ + + /* _compat_pickle.NAME_MAPPING, + {(oldmodule, oldname): (newmodule, newname)} */ + PyObject *name_mapping_2to3; + /* _compat_pickle.IMPORT_MAPPING, {oldmodule: newmodule} */ + PyObject *import_mapping_2to3; + /* Same, but with REVERSE_NAME_MAPPING / REVERSE_IMPORT_MAPPING */ + PyObject *name_mapping_3to2; + PyObject *import_mapping_3to2; + + /* codecs.encode, used for saving bytes in older protocols */ + PyObject *codecs_encode; + /* builtins.getattr, used for saving nested names with protocol < 4 */ + PyObject *getattr; + /* functools.partial, used for implementing __newobj_ex__ with protocols + 2 and 3 */ + PyObject *partial; +} PickleState; + +/* Forward declaration of the _pickle module definition. */ +static struct PyModuleDef _picklemodule; + +/* Given a module object, get its per-module state. */ +static PickleState * +_Pickle_GetState(PyObject *module) +{ + return (PickleState *)PyModule_GetState(module); +} + +/* Find the module instance imported in the currently running sub-interpreter + and get its state. */ +static PickleState * +_Pickle_GetGlobalState(void) +{ + return _Pickle_GetState(PyState_FindModule(&_picklemodule)); +} + +/* Clear the given pickle module state. */ +static void +_Pickle_ClearState(PickleState *st) +{ + Py_CLEAR(st->PickleError); + Py_CLEAR(st->PicklingError); + Py_CLEAR(st->UnpicklingError); + Py_CLEAR(st->dispatch_table); + Py_CLEAR(st->extension_registry); + Py_CLEAR(st->extension_cache); + Py_CLEAR(st->inverted_registry); + Py_CLEAR(st->name_mapping_2to3); + Py_CLEAR(st->import_mapping_2to3); + Py_CLEAR(st->name_mapping_3to2); + Py_CLEAR(st->import_mapping_3to2); + Py_CLEAR(st->codecs_encode); + Py_CLEAR(st->getattr); + Py_CLEAR(st->partial); +} + +/* Initialize the given pickle module state. */ +static int +_Pickle_InitState(PickleState *st) +{ + PyObject *copyreg = NULL; + PyObject *compat_pickle = NULL; + PyObject *codecs = NULL; + PyObject *functools = NULL; + _Py_IDENTIFIER(getattr); + + st->getattr = _PyEval_GetBuiltinId(&PyId_getattr); + if (st->getattr == NULL) + goto error; + + copyreg = PyImport_ImportModule("copyreg"); + if (!copyreg) + goto error; + st->dispatch_table = PyObject_GetAttrString(copyreg, "dispatch_table"); + if (!st->dispatch_table) + goto error; + if (!PyDict_CheckExact(st->dispatch_table)) { + PyErr_Format(PyExc_RuntimeError, + "copyreg.dispatch_table should be a dict, not %.200s", + Py_TYPE(st->dispatch_table)->tp_name); + goto error; + } + st->extension_registry = \ + PyObject_GetAttrString(copyreg, "_extension_registry"); + if (!st->extension_registry) + goto error; + if (!PyDict_CheckExact(st->extension_registry)) { + PyErr_Format(PyExc_RuntimeError, + "copyreg._extension_registry should be a dict, " + "not %.200s", Py_TYPE(st->extension_registry)->tp_name); + goto error; + } + st->inverted_registry = \ + PyObject_GetAttrString(copyreg, "_inverted_registry"); + if (!st->inverted_registry) + goto error; + if (!PyDict_CheckExact(st->inverted_registry)) { + PyErr_Format(PyExc_RuntimeError, + "copyreg._inverted_registry should be a dict, " + "not %.200s", Py_TYPE(st->inverted_registry)->tp_name); + goto error; + } + st->extension_cache = PyObject_GetAttrString(copyreg, "_extension_cache"); + if (!st->extension_cache) + goto error; + if (!PyDict_CheckExact(st->extension_cache)) { + PyErr_Format(PyExc_RuntimeError, + "copyreg._extension_cache should be a dict, " + "not %.200s", Py_TYPE(st->extension_cache)->tp_name); + goto error; + } + Py_CLEAR(copyreg); + + /* Load the 2.x -> 3.x stdlib module mapping tables */ + compat_pickle = PyImport_ImportModule("_compat_pickle"); + if (!compat_pickle) + goto error; + st->name_mapping_2to3 = \ + PyObject_GetAttrString(compat_pickle, "NAME_MAPPING"); + if (!st->name_mapping_2to3) + goto error; + if (!PyDict_CheckExact(st->name_mapping_2to3)) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.NAME_MAPPING should be a dict, not %.200s", + Py_TYPE(st->name_mapping_2to3)->tp_name); + goto error; + } + st->import_mapping_2to3 = \ + PyObject_GetAttrString(compat_pickle, "IMPORT_MAPPING"); + if (!st->import_mapping_2to3) + goto error; + if (!PyDict_CheckExact(st->import_mapping_2to3)) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.IMPORT_MAPPING should be a dict, " + "not %.200s", Py_TYPE(st->import_mapping_2to3)->tp_name); + goto error; + } + /* ... and the 3.x -> 2.x mapping tables */ + st->name_mapping_3to2 = \ + PyObject_GetAttrString(compat_pickle, "REVERSE_NAME_MAPPING"); + if (!st->name_mapping_3to2) + goto error; + if (!PyDict_CheckExact(st->name_mapping_3to2)) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.REVERSE_NAME_MAPPING should be a dict, " + "not %.200s", Py_TYPE(st->name_mapping_3to2)->tp_name); + goto error; + } + st->import_mapping_3to2 = \ + PyObject_GetAttrString(compat_pickle, "REVERSE_IMPORT_MAPPING"); + if (!st->import_mapping_3to2) + goto error; + if (!PyDict_CheckExact(st->import_mapping_3to2)) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.REVERSE_IMPORT_MAPPING should be a dict, " + "not %.200s", Py_TYPE(st->import_mapping_3to2)->tp_name); + goto error; + } + Py_CLEAR(compat_pickle); + + codecs = PyImport_ImportModule("codecs"); + if (codecs == NULL) + goto error; + st->codecs_encode = PyObject_GetAttrString(codecs, "encode"); + if (st->codecs_encode == NULL) { + goto error; + } + if (!PyCallable_Check(st->codecs_encode)) { + PyErr_Format(PyExc_RuntimeError, + "codecs.encode should be a callable, not %.200s", + Py_TYPE(st->codecs_encode)->tp_name); + goto error; + } + Py_CLEAR(codecs); + + functools = PyImport_ImportModule("functools"); + if (!functools) + goto error; + st->partial = PyObject_GetAttrString(functools, "partial"); + if (!st->partial) + goto error; + Py_CLEAR(functools); + + return 0; + + error: + Py_CLEAR(copyreg); + Py_CLEAR(compat_pickle); + Py_CLEAR(codecs); + Py_CLEAR(functools); + _Pickle_ClearState(st); + return -1; +} + +/* Helper for calling a function with a single argument quickly. + + This function steals the reference of the given argument. */ +static PyObject * +_Pickle_FastCall(PyObject *func, PyObject *obj) +{ + PyObject *result; + + result = PyObject_CallOneArg(func, obj); + Py_DECREF(obj); + return result; +} + +/*************************************************************************/ + +/* Retrieve and deconstruct a method for avoiding a reference cycle + (pickler -> bound method of pickler -> pickler) */ +static int +init_method_ref(PyObject *self, _Py_Identifier *name, + PyObject **method_func, PyObject **method_self) +{ + PyObject *func, *func2; + int ret; + + /* *method_func and *method_self should be consistent. All refcount decrements + should be occurred after setting *method_self and *method_func. */ + ret = _PyObject_LookupAttrId(self, name, &func); + if (func == NULL) { + *method_self = NULL; + Py_CLEAR(*method_func); + return ret; + } + + if (PyMethod_Check(func) && PyMethod_GET_SELF(func) == self) { + /* Deconstruct a bound Python method */ + func2 = PyMethod_GET_FUNCTION(func); + Py_INCREF(func2); + *method_self = self; /* borrowed */ + Py_XSETREF(*method_func, func2); + Py_DECREF(func); + return 0; + } + else { + *method_self = NULL; + Py_XSETREF(*method_func, func); + return 0; + } +} + +/* Bind a method if it was deconstructed */ +static PyObject * +reconstruct_method(PyObject *func, PyObject *self) +{ + if (self) { + return PyMethod_New(func, self); + } + else { + Py_INCREF(func); + return func; + } +} + +static PyObject * +call_method(PyObject *func, PyObject *self, PyObject *obj) +{ + if (self) { + return PyObject_CallFunctionObjArgs(func, self, obj, NULL); + } + else { + return PyObject_CallOneArg(func, obj); + } +} + +/*************************************************************************/ + +/* Internal data type used as the unpickling stack. */ +typedef struct { + PyObject_VAR_HEAD + PyObject **data; + int mark_set; /* is MARK set? */ + Py_ssize_t fence; /* position of top MARK or 0 */ + Py_ssize_t allocated; /* number of slots in data allocated */ +} Pdata; + +static void +Pdata_dealloc(Pdata *self) +{ + Py_ssize_t i = Py_SIZE(self); + while (--i >= 0) { + Py_DECREF(self->data[i]); + } + PyMem_FREE(self->data); + PyObject_Del(self); +} + +static PyTypeObject Pdata_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_pickle.Pdata", /*tp_name*/ + sizeof(Pdata), /*tp_basicsize*/ + sizeof(PyObject *), /*tp_itemsize*/ + (destructor)Pdata_dealloc, /*tp_dealloc*/ +}; + +static PyObject * +Pdata_New(void) +{ + Pdata *self; + + if (!(self = PyObject_New(Pdata, &Pdata_Type))) + return NULL; + Py_SET_SIZE(self, 0); + self->mark_set = 0; + self->fence = 0; + self->allocated = 8; + self->data = PyMem_MALLOC(self->allocated * sizeof(PyObject *)); + if (self->data) + return (PyObject *)self; + Py_DECREF(self); + return PyErr_NoMemory(); +} + + +/* Retain only the initial clearto items. If clearto >= the current + * number of items, this is a (non-erroneous) NOP. + */ +static int +Pdata_clear(Pdata *self, Py_ssize_t clearto) +{ + Py_ssize_t i = Py_SIZE(self); + + assert(clearto >= self->fence); + if (clearto >= i) + return 0; + + while (--i >= clearto) { + Py_CLEAR(self->data[i]); + } + Py_SET_SIZE(self, clearto); + return 0; +} + +static int +Pdata_grow(Pdata *self) +{ + PyObject **data = self->data; + size_t allocated = (size_t)self->allocated; + size_t new_allocated; + + new_allocated = (allocated >> 3) + 6; + /* check for integer overflow */ + if (new_allocated > (size_t)PY_SSIZE_T_MAX - allocated) + goto nomemory; + new_allocated += allocated; + PyMem_RESIZE(data, PyObject *, new_allocated); + if (data == NULL) + goto nomemory; + + self->data = data; + self->allocated = (Py_ssize_t)new_allocated; + return 0; + + nomemory: + PyErr_NoMemory(); + return -1; +} + +static int +Pdata_stack_underflow(Pdata *self) +{ + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + self->mark_set ? + "unexpected MARK found" : + "unpickling stack underflow"); + return -1; +} + +/* D is a Pdata*. Pop the topmost element and store it into V, which + * must be an lvalue holding PyObject*. On stack underflow, UnpicklingError + * is raised and V is set to NULL. + */ +static PyObject * +Pdata_pop(Pdata *self) +{ + if (Py_SIZE(self) <= self->fence) { + Pdata_stack_underflow(self); + return NULL; + } + Py_SET_SIZE(self, Py_SIZE(self) - 1); + return self->data[Py_SIZE(self)]; +} +#define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0) + +static int +Pdata_push(Pdata *self, PyObject *obj) +{ + if (Py_SIZE(self) == self->allocated && Pdata_grow(self) < 0) { + return -1; + } + self->data[Py_SIZE(self)] = obj; + Py_SET_SIZE(self, Py_SIZE(self) + 1); + return 0; +} + +/* Push an object on stack, transferring its ownership to the stack. */ +#define PDATA_PUSH(D, O, ER) do { \ + if (Pdata_push((D), (O)) < 0) return (ER); } while(0) + +/* Push an object on stack, adding a new reference to the object. */ +#define PDATA_APPEND(D, O, ER) do { \ + Py_INCREF((O)); \ + if (Pdata_push((D), (O)) < 0) return (ER); } while(0) + +static PyObject * +Pdata_poptuple(Pdata *self, Py_ssize_t start) +{ + PyObject *tuple; + Py_ssize_t len, i, j; + + if (start < self->fence) { + Pdata_stack_underflow(self); + return NULL; + } + len = Py_SIZE(self) - start; + tuple = PyTuple_New(len); + if (tuple == NULL) + return NULL; + for (i = start, j = 0; j < len; i++, j++) + PyTuple_SET_ITEM(tuple, j, self->data[i]); + + Py_SET_SIZE(self, start); + return tuple; +} + +static PyObject * +Pdata_poplist(Pdata *self, Py_ssize_t start) +{ + PyObject *list; + Py_ssize_t len, i, j; + + len = Py_SIZE(self) - start; + list = PyList_New(len); + if (list == NULL) + return NULL; + for (i = start, j = 0; j < len; i++, j++) + PyList_SET_ITEM(list, j, self->data[i]); + + Py_SET_SIZE(self, start); + return list; +} + +typedef struct { + PyObject *me_key; + Py_ssize_t me_value; +} PyMemoEntry; + +typedef struct { + size_t mt_mask; + size_t mt_used; + size_t mt_allocated; + PyMemoEntry *mt_table; +} PyMemoTable; + +typedef struct PicklerObject { + PyObject_HEAD + PyMemoTable *memo; /* Memo table, keep track of the seen + objects to support self-referential objects + pickling. */ + PyObject *pers_func; /* persistent_id() method, can be NULL */ + PyObject *pers_func_self; /* borrowed reference to self if pers_func + is an unbound method, NULL otherwise */ + PyObject *dispatch_table; /* private dispatch_table, can be NULL */ + PyObject *reducer_override; /* hook for invoking user-defined callbacks + instead of save_global when pickling + functions and classes*/ + + PyObject *write; /* write() method of the output stream. */ + PyObject *output_buffer; /* Write into a local bytearray buffer before + flushing to the stream. */ + Py_ssize_t output_len; /* Length of output_buffer. */ + Py_ssize_t max_output_len; /* Allocation size of output_buffer. */ + int proto; /* Pickle protocol number, >= 0 */ + int bin; /* Boolean, true if proto > 0 */ + int framing; /* True when framing is enabled, proto >= 4 */ + Py_ssize_t frame_start; /* Position in output_buffer where the + current frame begins. -1 if there + is no frame currently open. */ + + Py_ssize_t buf_size; /* Size of the current buffered pickle data */ + int fast; /* Enable fast mode if set to a true value. + The fast mode disable the usage of memo, + therefore speeding the pickling process by + not generating superfluous PUT opcodes. It + should not be used if with self-referential + objects. */ + int fast_nesting; + int fix_imports; /* Indicate whether Pickler should fix + the name of globals for Python 2.x. */ + PyObject *fast_memo; + PyObject *buffer_callback; /* Callback for out-of-band buffers, or NULL */ +} PicklerObject; + +typedef struct UnpicklerObject { + PyObject_HEAD + Pdata *stack; /* Pickle data stack, store unpickled objects. */ + + /* The unpickler memo is just an array of PyObject *s. Using a dict + is unnecessary, since the keys are contiguous ints. */ + PyObject **memo; + size_t memo_size; /* Capacity of the memo array */ + size_t memo_len; /* Number of objects in the memo */ + + PyObject *pers_func; /* persistent_load() method, can be NULL. */ + PyObject *pers_func_self; /* borrowed reference to self if pers_func + is an unbound method, NULL otherwise */ + + Py_buffer buffer; + char *input_buffer; + char *input_line; + Py_ssize_t input_len; + Py_ssize_t next_read_idx; + Py_ssize_t prefetched_idx; /* index of first prefetched byte */ + + PyObject *read; /* read() method of the input stream. */ + PyObject *readinto; /* readinto() method of the input stream. */ + PyObject *readline; /* readline() method of the input stream. */ + PyObject *peek; /* peek() method of the input stream, or NULL */ + PyObject *buffers; /* iterable of out-of-band buffers, or NULL */ + + char *encoding; /* Name of the encoding to be used for + decoding strings pickled using Python + 2.x. The default value is "ASCII" */ + char *errors; /* Name of errors handling scheme to used when + decoding strings. The default value is + "strict". */ + Py_ssize_t *marks; /* Mark stack, used for unpickling container + objects. */ + Py_ssize_t num_marks; /* Number of marks in the mark stack. */ + Py_ssize_t marks_size; /* Current allocated size of the mark stack. */ + int proto; /* Protocol of the pickle loaded. */ + int fix_imports; /* Indicate whether Unpickler should fix + the name of globals pickled by Python 2.x. */ +} UnpicklerObject; + +typedef struct { + PyObject_HEAD + PicklerObject *pickler; /* Pickler whose memo table we're proxying. */ +} PicklerMemoProxyObject; + +typedef struct { + PyObject_HEAD + UnpicklerObject *unpickler; +} UnpicklerMemoProxyObject; + +/* Forward declarations */ +static int save(PicklerObject *, PyObject *, int); +static int save_reduce(PicklerObject *, PyObject *, PyObject *); +static PyTypeObject Pickler_Type; +static PyTypeObject Unpickler_Type; + +#include "clinic/_pickle.c.h" + +/************************************************************************* + A custom hashtable mapping void* to Python ints. This is used by the pickler + for memoization. Using a custom hashtable rather than PyDict allows us to skip + a bunch of unnecessary object creation. This makes a huge performance + difference. */ + +#define MT_MINSIZE 8 +#define PERTURB_SHIFT 5 + + +static PyMemoTable * +PyMemoTable_New(void) +{ + PyMemoTable *memo = PyMem_MALLOC(sizeof(PyMemoTable)); + if (memo == NULL) { + PyErr_NoMemory(); + return NULL; + } + + memo->mt_used = 0; + memo->mt_allocated = MT_MINSIZE; + memo->mt_mask = MT_MINSIZE - 1; + memo->mt_table = PyMem_MALLOC(MT_MINSIZE * sizeof(PyMemoEntry)); + if (memo->mt_table == NULL) { + PyMem_FREE(memo); + PyErr_NoMemory(); + return NULL; + } + memset(memo->mt_table, 0, MT_MINSIZE * sizeof(PyMemoEntry)); + + return memo; +} + +static PyMemoTable * +PyMemoTable_Copy(PyMemoTable *self) +{ + PyMemoTable *new = PyMemoTable_New(); + if (new == NULL) + return NULL; + + new->mt_used = self->mt_used; + new->mt_allocated = self->mt_allocated; + new->mt_mask = self->mt_mask; + /* The table we get from _New() is probably smaller than we wanted. + Free it and allocate one that's the right size. */ + PyMem_FREE(new->mt_table); + new->mt_table = PyMem_NEW(PyMemoEntry, self->mt_allocated); + if (new->mt_table == NULL) { + PyMem_FREE(new); + PyErr_NoMemory(); + return NULL; + } + for (size_t i = 0; i < self->mt_allocated; i++) { + Py_XINCREF(self->mt_table[i].me_key); + } + memcpy(new->mt_table, self->mt_table, + sizeof(PyMemoEntry) * self->mt_allocated); + + return new; +} + +static Py_ssize_t +PyMemoTable_Size(PyMemoTable *self) +{ + return self->mt_used; +} + +static int +PyMemoTable_Clear(PyMemoTable *self) +{ + Py_ssize_t i = self->mt_allocated; + + while (--i >= 0) { + Py_XDECREF(self->mt_table[i].me_key); + } + self->mt_used = 0; + memset(self->mt_table, 0, self->mt_allocated * sizeof(PyMemoEntry)); + return 0; +} + +static void +PyMemoTable_Del(PyMemoTable *self) +{ + if (self == NULL) + return; + PyMemoTable_Clear(self); + + PyMem_FREE(self->mt_table); + PyMem_FREE(self); +} + +/* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup() + can be considerably simpler than dictobject.c's lookdict(). */ +static PyMemoEntry * +_PyMemoTable_Lookup(PyMemoTable *self, PyObject *key) +{ + size_t i; + size_t perturb; + size_t mask = self->mt_mask; + PyMemoEntry *table = self->mt_table; + PyMemoEntry *entry; + Py_hash_t hash = (Py_hash_t)key >> 3; + + i = hash & mask; + entry = &table[i]; + if (entry->me_key == NULL || entry->me_key == key) + return entry; + + for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { + i = (i << 2) + i + perturb + 1; + entry = &table[i & mask]; + if (entry->me_key == NULL || entry->me_key == key) + return entry; + } + Py_UNREACHABLE(); +} + +/* Returns -1 on failure, 0 on success. */ +static int +_PyMemoTable_ResizeTable(PyMemoTable *self, size_t min_size) +{ + PyMemoEntry *oldtable = NULL; + PyMemoEntry *oldentry, *newentry; + size_t new_size = MT_MINSIZE; + size_t to_process; + + assert(min_size > 0); + + if (min_size > PY_SSIZE_T_MAX) { + PyErr_NoMemory(); + return -1; + } + + /* Find the smallest valid table size >= min_size. */ + while (new_size < min_size) { + new_size <<= 1; + } + /* new_size needs to be a power of two. */ + assert((new_size & (new_size - 1)) == 0); + + /* Allocate new table. */ + oldtable = self->mt_table; + self->mt_table = PyMem_NEW(PyMemoEntry, new_size); + if (self->mt_table == NULL) { + self->mt_table = oldtable; + PyErr_NoMemory(); + return -1; + } + self->mt_allocated = new_size; + self->mt_mask = new_size - 1; + memset(self->mt_table, 0, sizeof(PyMemoEntry) * new_size); + + /* Copy entries from the old table. */ + to_process = self->mt_used; + for (oldentry = oldtable; to_process > 0; oldentry++) { + if (oldentry->me_key != NULL) { + to_process--; + /* newentry is a pointer to a chunk of the new + mt_table, so we're setting the key:value pair + in-place. */ + newentry = _PyMemoTable_Lookup(self, oldentry->me_key); + newentry->me_key = oldentry->me_key; + newentry->me_value = oldentry->me_value; + } + } + + /* Deallocate the old table. */ + PyMem_FREE(oldtable); + return 0; +} + +/* Returns NULL on failure, a pointer to the value otherwise. */ +static Py_ssize_t * +PyMemoTable_Get(PyMemoTable *self, PyObject *key) +{ + PyMemoEntry *entry = _PyMemoTable_Lookup(self, key); + if (entry->me_key == NULL) + return NULL; + return &entry->me_value; +} + +/* Returns -1 on failure, 0 on success. */ +static int +PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value) +{ + PyMemoEntry *entry; + + assert(key != NULL); + + entry = _PyMemoTable_Lookup(self, key); + if (entry->me_key != NULL) { + entry->me_value = value; + return 0; + } + Py_INCREF(key); + entry->me_key = key; + entry->me_value = value; + self->mt_used++; + + /* If we added a key, we can safely resize. Otherwise just return! + * If used >= 2/3 size, adjust size. Normally, this quaduples the size. + * + * Quadrupling the size improves average table sparseness + * (reducing collisions) at the cost of some memory. It also halves + * the number of expensive resize operations in a growing memo table. + * + * Very large memo tables (over 50K items) use doubling instead. + * This may help applications with severe memory constraints. + */ + if (SIZE_MAX / 3 >= self->mt_used && self->mt_used * 3 < self->mt_allocated * 2) { + return 0; + } + // self->mt_used is always < PY_SSIZE_T_MAX, so this can't overflow. + size_t desired_size = (self->mt_used > 50000 ? 2 : 4) * self->mt_used; + return _PyMemoTable_ResizeTable(self, desired_size); +} + +#undef MT_MINSIZE +#undef PERTURB_SHIFT + +/*************************************************************************/ + + +static int +_Pickler_ClearBuffer(PicklerObject *self) +{ + Py_XSETREF(self->output_buffer, + PyBytes_FromStringAndSize(NULL, self->max_output_len)); + if (self->output_buffer == NULL) + return -1; + self->output_len = 0; + self->frame_start = -1; + return 0; +} + +static void +_write_size64(char *out, size_t value) +{ + size_t i; + + Py_BUILD_ASSERT(sizeof(size_t) <= 8); + + for (i = 0; i < sizeof(size_t); i++) { + out[i] = (unsigned char)((value >> (8 * i)) & 0xff); + } + for (i = sizeof(size_t); i < 8; i++) { + out[i] = 0; + } +} + +static int +_Pickler_CommitFrame(PicklerObject *self) +{ + size_t frame_len; + char *qdata; + + if (!self->framing || self->frame_start == -1) + return 0; + frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE; + qdata = PyBytes_AS_STRING(self->output_buffer) + self->frame_start; + if (frame_len >= FRAME_SIZE_MIN) { + qdata[0] = FRAME; + _write_size64(qdata + 1, frame_len); + } + else { + memmove(qdata, qdata + FRAME_HEADER_SIZE, frame_len); + self->output_len -= FRAME_HEADER_SIZE; + } + self->frame_start = -1; + return 0; +} + +static PyObject * +_Pickler_GetString(PicklerObject *self) +{ + PyObject *output_buffer = self->output_buffer; + + assert(self->output_buffer != NULL); + + if (_Pickler_CommitFrame(self)) + return NULL; + + self->output_buffer = NULL; + /* Resize down to exact size */ + if (_PyBytes_Resize(&output_buffer, self->output_len) < 0) + return NULL; + return output_buffer; +} + +static int +_Pickler_FlushToFile(PicklerObject *self) +{ + PyObject *output, *result; + + assert(self->write != NULL); + + /* This will commit the frame first */ + output = _Pickler_GetString(self); + if (output == NULL) + return -1; + + result = _Pickle_FastCall(self->write, output); + Py_XDECREF(result); + return (result == NULL) ? -1 : 0; +} + +static int +_Pickler_OpcodeBoundary(PicklerObject *self) +{ + Py_ssize_t frame_len; + + if (!self->framing || self->frame_start == -1) { + return 0; + } + frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE; + if (frame_len >= FRAME_SIZE_TARGET) { + if(_Pickler_CommitFrame(self)) { + return -1; + } + /* Flush the content of the committed frame to the underlying + * file and reuse the pickler buffer for the next frame so as + * to limit memory usage when dumping large complex objects to + * a file. + * + * self->write is NULL when called via dumps. + */ + if (self->write != NULL) { + if (_Pickler_FlushToFile(self) < 0) { + return -1; + } + if (_Pickler_ClearBuffer(self) < 0) { + return -1; + } + } + } + return 0; +} + +static Py_ssize_t +_Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len) +{ + Py_ssize_t i, n, required; + char *buffer; + int need_new_frame; + + assert(s != NULL); + need_new_frame = (self->framing && self->frame_start == -1); + + if (need_new_frame) + n = data_len + FRAME_HEADER_SIZE; + else + n = data_len; + + required = self->output_len + n; + if (required > self->max_output_len) { + /* Make place in buffer for the pickle chunk */ + if (self->output_len >= PY_SSIZE_T_MAX / 2 - n) { + PyErr_NoMemory(); + return -1; + } + self->max_output_len = (self->output_len + n) / 2 * 3; + if (_PyBytes_Resize(&self->output_buffer, self->max_output_len) < 0) + return -1; + } + buffer = PyBytes_AS_STRING(self->output_buffer); + if (need_new_frame) { + /* Setup new frame */ + Py_ssize_t frame_start = self->output_len; + self->frame_start = frame_start; + for (i = 0; i < FRAME_HEADER_SIZE; i++) { + /* Write an invalid value, for debugging */ + buffer[frame_start + i] = 0xFE; + } + self->output_len += FRAME_HEADER_SIZE; + } + if (data_len < 8) { + /* This is faster than memcpy when the string is short. */ + for (i = 0; i < data_len; i++) { + buffer[self->output_len + i] = s[i]; + } + } + else { + memcpy(buffer + self->output_len, s, data_len); + } + self->output_len += data_len; + return data_len; +} + +static PicklerObject * +_Pickler_New(void) +{ + PicklerObject *self; + + self = PyObject_GC_New(PicklerObject, &Pickler_Type); + if (self == NULL) + return NULL; + + self->pers_func = NULL; + self->dispatch_table = NULL; + self->buffer_callback = NULL; + self->write = NULL; + self->proto = 0; + self->bin = 0; + self->framing = 0; + self->frame_start = -1; + self->fast = 0; + self->fast_nesting = 0; + self->fix_imports = 0; + self->fast_memo = NULL; + self->max_output_len = WRITE_BUF_SIZE; + self->output_len = 0; + self->reducer_override = NULL; + + self->memo = PyMemoTable_New(); + self->output_buffer = PyBytes_FromStringAndSize(NULL, + self->max_output_len); + + if (self->memo == NULL || self->output_buffer == NULL) { + Py_DECREF(self); + return NULL; + } -/* Find the module instance imported in the currently running sub-interpreter - and get its state. */ -static PickleState * -_Pickle_GetGlobalState(void) + PyObject_GC_Track(self); + return self; +} + +static int +_Pickler_SetProtocol(PicklerObject *self, PyObject *protocol, int fix_imports) +{ + long proto; + + if (protocol == Py_None) { + proto = DEFAULT_PROTOCOL; + } + else { + proto = PyLong_AsLong(protocol); + if (proto < 0) { + if (proto == -1 && PyErr_Occurred()) + return -1; + proto = HIGHEST_PROTOCOL; + } + else if (proto > HIGHEST_PROTOCOL) { + PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d", + HIGHEST_PROTOCOL); + return -1; + } + } + self->proto = (int)proto; + self->bin = proto > 0; + self->fix_imports = fix_imports && proto < 3; + return 0; +} + +/* Returns -1 (with an exception set) on failure, 0 on success. This may + be called once on a freshly created Pickler. */ +static int +_Pickler_SetOutputStream(PicklerObject *self, PyObject *file) +{ + _Py_IDENTIFIER(write); + assert(file != NULL); + if (_PyObject_LookupAttrId(file, &PyId_write, &self->write) < 0) { + return -1; + } + if (self->write == NULL) { + PyErr_SetString(PyExc_TypeError, + "file must have a 'write' attribute"); + return -1; + } + + return 0; +} + +static int +_Pickler_SetBufferCallback(PicklerObject *self, PyObject *buffer_callback) { - return _Pickle_GetState(PyState_FindModule(&_picklemodule)); -} + if (buffer_callback == Py_None) { + buffer_callback = NULL; + } + if (buffer_callback != NULL && self->proto < 5) { + PyErr_SetString(PyExc_ValueError, + "buffer_callback needs protocol >= 5"); + return -1; + } -/* Clear the given pickle module state. */ -static void -_Pickle_ClearState(PickleState *st) -{ - Py_CLEAR(st->PickleError); - Py_CLEAR(st->PicklingError); - Py_CLEAR(st->UnpicklingError); - Py_CLEAR(st->dispatch_table); - Py_CLEAR(st->extension_registry); - Py_CLEAR(st->extension_cache); - Py_CLEAR(st->inverted_registry); - Py_CLEAR(st->name_mapping_2to3); - Py_CLEAR(st->import_mapping_2to3); - Py_CLEAR(st->name_mapping_3to2); - Py_CLEAR(st->import_mapping_3to2); - Py_CLEAR(st->codecs_encode); - Py_CLEAR(st->getattr); - Py_CLEAR(st->partial); + Py_XINCREF(buffer_callback); + self->buffer_callback = buffer_callback; + return 0; } -/* Initialize the given pickle module state. */ -static int -_Pickle_InitState(PickleState *st) +/* Returns the size of the input on success, -1 on failure. This takes its + own reference to `input`. */ +static Py_ssize_t +_Unpickler_SetStringInput(UnpicklerObject *self, PyObject *input) +{ + if (self->buffer.buf != NULL) + PyBuffer_Release(&self->buffer); + if (PyObject_GetBuffer(input, &self->buffer, PyBUF_CONTIG_RO) < 0) + return -1; + self->input_buffer = self->buffer.buf; + self->input_len = self->buffer.len; + self->next_read_idx = 0; + self->prefetched_idx = self->input_len; + return self->input_len; +} + +static int +bad_readline(void) +{ + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, "pickle data was truncated"); + return -1; +} + +/* Skip any consumed data that was only prefetched using peek() */ +static int +_Unpickler_SkipConsumed(UnpicklerObject *self) +{ + Py_ssize_t consumed; + PyObject *r; + + consumed = self->next_read_idx - self->prefetched_idx; + if (consumed <= 0) + return 0; + + assert(self->peek); /* otherwise we did something wrong */ + /* This makes a useless copy... */ + r = PyObject_CallFunction(self->read, "n", consumed); + if (r == NULL) + return -1; + Py_DECREF(r); + + self->prefetched_idx = self->next_read_idx; + return 0; +} + +static const Py_ssize_t READ_WHOLE_LINE = -1; + +/* If reading from a file, we need to only pull the bytes we need, since there + may be multiple pickle objects arranged contiguously in the same input + buffer. + + If `n` is READ_WHOLE_LINE, read a whole line. Otherwise, read up to `n` + bytes from the input stream/buffer. + + Update the unpickler's input buffer with the newly-read data. Returns -1 on + failure; on success, returns the number of bytes read from the file. + + On success, self->input_len will be 0; this is intentional so that when + unpickling from a file, the "we've run out of data" code paths will trigger, + causing the Unpickler to go back to the file for more data. Use the returned + size to tell you how much data you can process. */ +static Py_ssize_t +_Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n) +{ + PyObject *data; + Py_ssize_t read_size; + + assert(self->read != NULL); + + if (_Unpickler_SkipConsumed(self) < 0) + return -1; + + if (n == READ_WHOLE_LINE) { + data = PyObject_CallNoArgs(self->readline); + } + else { + PyObject *len; + /* Prefetch some data without advancing the file pointer, if possible */ + if (self->peek && n < PREFETCH) { + len = PyLong_FromSsize_t(PREFETCH); + if (len == NULL) + return -1; + data = _Pickle_FastCall(self->peek, len); + if (data == NULL) { + if (!PyErr_ExceptionMatches(PyExc_NotImplementedError)) + return -1; + /* peek() is probably not supported by the given file object */ + PyErr_Clear(); + Py_CLEAR(self->peek); + } + else { + read_size = _Unpickler_SetStringInput(self, data); + Py_DECREF(data); + self->prefetched_idx = 0; + if (n <= read_size) + return n; + } + } + len = PyLong_FromSsize_t(n); + if (len == NULL) + return -1; + data = _Pickle_FastCall(self->read, len); + } + if (data == NULL) + return -1; + + read_size = _Unpickler_SetStringInput(self, data); + Py_DECREF(data); + return read_size; +} + +/* Don't call it directly: use _Unpickler_Read() */ +static Py_ssize_t +_Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) +{ + Py_ssize_t num_read; + + *s = NULL; + if (self->next_read_idx > PY_SSIZE_T_MAX - n) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "read would overflow (invalid bytecode)"); + return -1; + } + + /* This case is handled by the _Unpickler_Read() macro for efficiency */ + assert(self->next_read_idx + n > self->input_len); + + if (!self->read) + return bad_readline(); + + /* Extend the buffer to satisfy desired size */ + num_read = _Unpickler_ReadFromFile(self, n); + if (num_read < 0) + return -1; + if (num_read < n) + return bad_readline(); + *s = self->input_buffer; + self->next_read_idx = n; + return n; +} + +/* Read `n` bytes from the unpickler's data source, storing the result in `buf`. + * + * This should only be used for non-small data reads where potentially + * avoiding a copy is beneficial. This method does not try to prefetch + * more data into the input buffer. + * + * _Unpickler_Read() is recommended in most cases. + */ +static Py_ssize_t +_Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) { - PyObject *copyreg = NULL; - PyObject *compat_pickle = NULL; - PyObject *codecs = NULL; - PyObject *functools = NULL; - _Py_IDENTIFIER(getattr); - - st->getattr = _PyEval_GetBuiltinId(&PyId_getattr); - if (st->getattr == NULL) - goto error; + assert(n != READ_WHOLE_LINE); - copyreg = PyImport_ImportModule("copyreg"); - if (!copyreg) - goto error; - st->dispatch_table = PyObject_GetAttrString(copyreg, "dispatch_table"); - if (!st->dispatch_table) - goto error; - if (!PyDict_CheckExact(st->dispatch_table)) { - PyErr_Format(PyExc_RuntimeError, - "copyreg.dispatch_table should be a dict, not %.200s", - Py_TYPE(st->dispatch_table)->tp_name); - goto error; - } - st->extension_registry = \ - PyObject_GetAttrString(copyreg, "_extension_registry"); - if (!st->extension_registry) - goto error; - if (!PyDict_CheckExact(st->extension_registry)) { - PyErr_Format(PyExc_RuntimeError, - "copyreg._extension_registry should be a dict, " - "not %.200s", Py_TYPE(st->extension_registry)->tp_name); - goto error; + /* Read from available buffer data, if any */ + Py_ssize_t in_buffer = self->input_len - self->next_read_idx; + if (in_buffer > 0) { + Py_ssize_t to_read = Py_MIN(in_buffer, n); + memcpy(buf, self->input_buffer + self->next_read_idx, to_read); + self->next_read_idx += to_read; + buf += to_read; + n -= to_read; + if (n == 0) { + /* Entire read was satisfied from buffer */ + return n; + } } - st->inverted_registry = \ - PyObject_GetAttrString(copyreg, "_inverted_registry"); - if (!st->inverted_registry) - goto error; - if (!PyDict_CheckExact(st->inverted_registry)) { - PyErr_Format(PyExc_RuntimeError, - "copyreg._inverted_registry should be a dict, " - "not %.200s", Py_TYPE(st->inverted_registry)->tp_name); - goto error; + + /* Read from file */ + if (!self->read) { + /* We're unpickling memory, this means the input is truncated */ + return bad_readline(); } - st->extension_cache = PyObject_GetAttrString(copyreg, "_extension_cache"); - if (!st->extension_cache) - goto error; - if (!PyDict_CheckExact(st->extension_cache)) { - PyErr_Format(PyExc_RuntimeError, - "copyreg._extension_cache should be a dict, " - "not %.200s", Py_TYPE(st->extension_cache)->tp_name); - goto error; + if (_Unpickler_SkipConsumed(self) < 0) { + return -1; } - Py_CLEAR(copyreg); - /* Load the 2.x -> 3.x stdlib module mapping tables */ - compat_pickle = PyImport_ImportModule("_compat_pickle"); - if (!compat_pickle) - goto error; - st->name_mapping_2to3 = \ - PyObject_GetAttrString(compat_pickle, "NAME_MAPPING"); - if (!st->name_mapping_2to3) - goto error; - if (!PyDict_CheckExact(st->name_mapping_2to3)) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.NAME_MAPPING should be a dict, not %.200s", - Py_TYPE(st->name_mapping_2to3)->tp_name); - goto error; - } - st->import_mapping_2to3 = \ - PyObject_GetAttrString(compat_pickle, "IMPORT_MAPPING"); - if (!st->import_mapping_2to3) - goto error; - if (!PyDict_CheckExact(st->import_mapping_2to3)) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.IMPORT_MAPPING should be a dict, " - "not %.200s", Py_TYPE(st->import_mapping_2to3)->tp_name); - goto error; + if (!self->readinto) { + /* readinto() not supported on file-like object, fall back to read() + * and copy into destination buffer (bpo-39681) */ + PyObject* len = PyLong_FromSsize_t(n); + if (len == NULL) { + return -1; + } + PyObject* data = _Pickle_FastCall(self->read, len); + if (data == NULL) { + return -1; + } + if (!PyBytes_Check(data)) { + PyErr_Format(PyExc_ValueError, + "read() returned non-bytes object (%R)", + Py_TYPE(data)); + Py_DECREF(data); + return -1; + } + Py_ssize_t read_size = PyBytes_GET_SIZE(data); + if (read_size < n) { + Py_DECREF(data); + return bad_readline(); + } + memcpy(buf, PyBytes_AS_STRING(data), n); + Py_DECREF(data); + return n; } - /* ... and the 3.x -> 2.x mapping tables */ - st->name_mapping_3to2 = \ - PyObject_GetAttrString(compat_pickle, "REVERSE_NAME_MAPPING"); - if (!st->name_mapping_3to2) - goto error; - if (!PyDict_CheckExact(st->name_mapping_3to2)) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.REVERSE_NAME_MAPPING should be a dict, " - "not %.200s", Py_TYPE(st->name_mapping_3to2)->tp_name); - goto error; + + /* Call readinto() into user buffer */ + PyObject *buf_obj = PyMemoryView_FromMemory(buf, n, PyBUF_WRITE); + if (buf_obj == NULL) { + return -1; } - st->import_mapping_3to2 = \ - PyObject_GetAttrString(compat_pickle, "REVERSE_IMPORT_MAPPING"); - if (!st->import_mapping_3to2) - goto error; - if (!PyDict_CheckExact(st->import_mapping_3to2)) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.REVERSE_IMPORT_MAPPING should be a dict, " - "not %.200s", Py_TYPE(st->import_mapping_3to2)->tp_name); - goto error; + PyObject *read_size_obj = _Pickle_FastCall(self->readinto, buf_obj); + if (read_size_obj == NULL) { + return -1; } - Py_CLEAR(compat_pickle); + Py_ssize_t read_size = PyLong_AsSsize_t(read_size_obj); + Py_DECREF(read_size_obj); - codecs = PyImport_ImportModule("codecs"); - if (codecs == NULL) - goto error; - st->codecs_encode = PyObject_GetAttrString(codecs, "encode"); - if (st->codecs_encode == NULL) { - goto error; + if (read_size < 0) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "readinto() returned negative size"); + } + return -1; } - if (!PyCallable_Check(st->codecs_encode)) { - PyErr_Format(PyExc_RuntimeError, - "codecs.encode should be a callable, not %.200s", - Py_TYPE(st->codecs_encode)->tp_name); - goto error; + if (read_size < n) { + return bad_readline(); } - Py_CLEAR(codecs); - - functools = PyImport_ImportModule("functools"); - if (!functools) - goto error; - st->partial = PyObject_GetAttrString(functools, "partial"); - if (!st->partial) - goto error; - Py_CLEAR(functools); - - return 0; - - error: - Py_CLEAR(copyreg); - Py_CLEAR(compat_pickle); - Py_CLEAR(codecs); - Py_CLEAR(functools); - _Pickle_ClearState(st); - return -1; -} - -/* Helper for calling a function with a single argument quickly. - - This function steals the reference of the given argument. */ -static PyObject * -_Pickle_FastCall(PyObject *func, PyObject *obj) -{ - PyObject *result; - - result = PyObject_CallOneArg(func, obj); - Py_DECREF(obj); - return result; + return n; } -/*************************************************************************/ - -/* Retrieve and deconstruct a method for avoiding a reference cycle - (pickler -> bound method of pickler -> pickler) */ +/* Read `n` bytes from the unpickler's data source, storing the result in `*s`. + + This should be used for all data reads, rather than accessing the unpickler's + input buffer directly. This method deals correctly with reading from input + streams, which the input buffer doesn't deal with. + + Note that when reading from a file-like object, self->next_read_idx won't + be updated (it should remain at 0 for the entire unpickling process). You + should use this function's return value to know how many bytes you can + consume. + + Returns -1 (with an exception set) on failure. On success, return the + number of chars read. */ +#define _Unpickler_Read(self, s, n) \ + (((n) <= (self)->input_len - (self)->next_read_idx) \ + ? (*(s) = (self)->input_buffer + (self)->next_read_idx, \ + (self)->next_read_idx += (n), \ + (n)) \ + : _Unpickler_ReadImpl(self, (s), (n))) + +static Py_ssize_t +_Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len, + char **result) +{ + char *input_line = PyMem_Realloc(self->input_line, len + 1); + if (input_line == NULL) { + PyErr_NoMemory(); + return -1; + } + + memcpy(input_line, line, len); + input_line[len] = '\0'; + self->input_line = input_line; + *result = self->input_line; + return len; +} + +/* Read a line from the input stream/buffer. If we run off the end of the input + before hitting \n, raise an error. + + Returns the number of chars read, or -1 on failure. */ +static Py_ssize_t +_Unpickler_Readline(UnpicklerObject *self, char **result) +{ + Py_ssize_t i, num_read; + + for (i = self->next_read_idx; i < self->input_len; i++) { + if (self->input_buffer[i] == '\n') { + char *line_start = self->input_buffer + self->next_read_idx; + num_read = i - self->next_read_idx + 1; + self->next_read_idx = i + 1; + return _Unpickler_CopyLine(self, line_start, num_read, result); + } + } + if (!self->read) + return bad_readline(); + + num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE); + if (num_read < 0) + return -1; + if (num_read == 0 || self->input_buffer[num_read - 1] != '\n') + return bad_readline(); + self->next_read_idx = num_read; + return _Unpickler_CopyLine(self, self->input_buffer, num_read, result); +} + +/* Returns -1 (with an exception set) on failure, 0 on success. The memo array + will be modified in place. */ +static int +_Unpickler_ResizeMemoList(UnpicklerObject *self, size_t new_size) +{ + size_t i; + + assert(new_size > self->memo_size); + + PyObject **memo_new = self->memo; + PyMem_RESIZE(memo_new, PyObject *, new_size); + if (memo_new == NULL) { + PyErr_NoMemory(); + return -1; + } + self->memo = memo_new; + for (i = self->memo_size; i < new_size; i++) + self->memo[i] = NULL; + self->memo_size = new_size; + return 0; +} + +/* Returns NULL if idx is out of bounds. */ +static PyObject * +_Unpickler_MemoGet(UnpicklerObject *self, size_t idx) +{ + if (idx >= self->memo_size) + return NULL; + + return self->memo[idx]; +} + +/* Returns -1 (with an exception set) on failure, 0 on success. + This takes its own reference to `value`. */ +static int +_Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value) +{ + PyObject *old_item; + + if (idx >= self->memo_size) { + if (_Unpickler_ResizeMemoList(self, idx * 2) < 0) + return -1; + assert(idx < self->memo_size); + } + Py_INCREF(value); + old_item = self->memo[idx]; + self->memo[idx] = value; + if (old_item != NULL) { + Py_DECREF(old_item); + } + else { + self->memo_len++; + } + return 0; +} + +static PyObject ** +_Unpickler_NewMemo(Py_ssize_t new_size) +{ + PyObject **memo = PyMem_NEW(PyObject *, new_size); + if (memo == NULL) { + PyErr_NoMemory(); + return NULL; + } + memset(memo, 0, new_size * sizeof(PyObject *)); + return memo; +} + +/* Free the unpickler's memo, taking care to decref any items left in it. */ +static void +_Unpickler_MemoCleanup(UnpicklerObject *self) +{ + Py_ssize_t i; + PyObject **memo = self->memo; + + if (self->memo == NULL) + return; + self->memo = NULL; + i = self->memo_size; + while (--i >= 0) { + Py_XDECREF(memo[i]); + } + PyMem_FREE(memo); +} + +static UnpicklerObject * +_Unpickler_New(void) +{ + UnpicklerObject *self; + + self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type); + if (self == NULL) + return NULL; + + self->pers_func = NULL; + self->input_buffer = NULL; + self->input_line = NULL; + self->input_len = 0; + self->next_read_idx = 0; + self->prefetched_idx = 0; + self->read = NULL; + self->readinto = NULL; + self->readline = NULL; + self->peek = NULL; + self->buffers = NULL; + self->encoding = NULL; + self->errors = NULL; + self->marks = NULL; + self->num_marks = 0; + self->marks_size = 0; + self->proto = 0; + self->fix_imports = 0; + memset(&self->buffer, 0, sizeof(Py_buffer)); + self->memo_size = 32; + self->memo_len = 0; + self->memo = _Unpickler_NewMemo(self->memo_size); + self->stack = (Pdata *)Pdata_New(); + + if (self->memo == NULL || self->stack == NULL) { + Py_DECREF(self); + return NULL; + } + + PyObject_GC_Track(self); + return self; +} + +/* Returns -1 (with an exception set) on failure, 0 on success. This may + be called once on a freshly created Unpickler. */ +static int +_Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) +{ + _Py_IDENTIFIER(peek); + _Py_IDENTIFIER(read); + _Py_IDENTIFIER(readinto); + _Py_IDENTIFIER(readline); + + /* Optional file methods */ + if (_PyObject_LookupAttrId(file, &PyId_peek, &self->peek) < 0) { + return -1; + } + if (_PyObject_LookupAttrId(file, &PyId_readinto, &self->readinto) < 0) { + return -1; + } + (void)_PyObject_LookupAttrId(file, &PyId_read, &self->read); + (void)_PyObject_LookupAttrId(file, &PyId_readline, &self->readline); + if (!self->readline || !self->read) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "file must have 'read' and 'readline' attributes"); + } + Py_CLEAR(self->read); + Py_CLEAR(self->readinto); + Py_CLEAR(self->readline); + Py_CLEAR(self->peek); + return -1; + } + return 0; +} + +/* Returns -1 (with an exception set) on failure, 0 on success. This may + be called once on a freshly created Unpickler. */ +static int +_Unpickler_SetInputEncoding(UnpicklerObject *self, + const char *encoding, + const char *errors) +{ + if (encoding == NULL) + encoding = "ASCII"; + if (errors == NULL) + errors = "strict"; + + self->encoding = _PyMem_Strdup(encoding); + self->errors = _PyMem_Strdup(errors); + if (self->encoding == NULL || self->errors == NULL) { + PyErr_NoMemory(); + return -1; + } + return 0; +} + +/* Returns -1 (with an exception set) on failure, 0 on success. This may + be called once on a freshly created Unpickler. */ static int -init_method_ref(PyObject *self, _Py_Identifier *name, - PyObject **method_func, PyObject **method_self) +_Unpickler_SetBuffers(UnpicklerObject *self, PyObject *buffers) { - PyObject *func, *func2; - int ret; - - /* *method_func and *method_self should be consistent. All refcount decrements - should be occurred after setting *method_self and *method_func. */ - ret = _PyObject_LookupAttrId(self, name, &func); - if (func == NULL) { - *method_self = NULL; - Py_CLEAR(*method_func); - return ret; - } - - if (PyMethod_Check(func) && PyMethod_GET_SELF(func) == self) { - /* Deconstruct a bound Python method */ - func2 = PyMethod_GET_FUNCTION(func); - Py_INCREF(func2); - *method_self = self; /* borrowed */ - Py_XSETREF(*method_func, func2); - Py_DECREF(func); - return 0; + if (buffers == NULL || buffers == Py_None) { + self->buffers = NULL; } else { - *method_self = NULL; - Py_XSETREF(*method_func, func); - return 0; + self->buffers = PyObject_GetIter(buffers); + if (self->buffers == NULL) { + return -1; + } } + return 0; } -/* Bind a method if it was deconstructed */ -static PyObject * -reconstruct_method(PyObject *func, PyObject *self) +/* Generate a GET opcode for an object stored in the memo. */ +static int +memo_get(PicklerObject *self, PyObject *key) +{ + Py_ssize_t *value; + char pdata[30]; + Py_ssize_t len; + + value = PyMemoTable_Get(self->memo, key); + if (value == NULL) { + PyErr_SetObject(PyExc_KeyError, key); + return -1; + } + + if (!self->bin) { + pdata[0] = GET; + PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, + "%" PY_FORMAT_SIZE_T "d\n", *value); + len = strlen(pdata); + } + else { + if (*value < 256) { + pdata[0] = BINGET; + pdata[1] = (unsigned char)(*value & 0xff); + len = 2; + } + else if ((size_t)*value <= 0xffffffffUL) { + pdata[0] = LONG_BINGET; + pdata[1] = (unsigned char)(*value & 0xff); + pdata[2] = (unsigned char)((*value >> 8) & 0xff); + pdata[3] = (unsigned char)((*value >> 16) & 0xff); + pdata[4] = (unsigned char)((*value >> 24) & 0xff); + len = 5; + } + else { /* unlikely */ + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->PicklingError, + "memo id too large for LONG_BINGET"); + return -1; + } + } + + if (_Pickler_Write(self, pdata, len) < 0) + return -1; + + return 0; +} + +/* Store an object in the memo, assign it a new unique ID based on the number + of objects currently stored in the memo and generate a PUT opcode. */ +static int +memo_put(PicklerObject *self, PyObject *obj) +{ + char pdata[30]; + Py_ssize_t len; + Py_ssize_t idx; + + const char memoize_op = MEMOIZE; + + if (self->fast) + return 0; + + idx = PyMemoTable_Size(self->memo); + if (PyMemoTable_Set(self->memo, obj, idx) < 0) + return -1; + + if (self->proto >= 4) { + if (_Pickler_Write(self, &memoize_op, 1) < 0) + return -1; + return 0; + } + else if (!self->bin) { + pdata[0] = PUT; + PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, + "%" PY_FORMAT_SIZE_T "d\n", idx); + len = strlen(pdata); + } + else { + if (idx < 256) { + pdata[0] = BINPUT; + pdata[1] = (unsigned char)idx; + len = 2; + } + else if ((size_t)idx <= 0xffffffffUL) { + pdata[0] = LONG_BINPUT; + pdata[1] = (unsigned char)(idx & 0xff); + pdata[2] = (unsigned char)((idx >> 8) & 0xff); + pdata[3] = (unsigned char)((idx >> 16) & 0xff); + pdata[4] = (unsigned char)((idx >> 24) & 0xff); + len = 5; + } + else { /* unlikely */ + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->PicklingError, + "memo id too large for LONG_BINPUT"); + return -1; + } + } + if (_Pickler_Write(self, pdata, len) < 0) + return -1; + + return 0; +} + +static PyObject * +get_dotted_path(PyObject *obj, PyObject *name) +{ + _Py_static_string(PyId_dot, "."); + PyObject *dotted_path; + Py_ssize_t i, n; + + dotted_path = PyUnicode_Split(name, _PyUnicode_FromId(&PyId_dot), -1); + if (dotted_path == NULL) + return NULL; + n = PyList_GET_SIZE(dotted_path); + assert(n >= 1); + for (i = 0; i < n; i++) { + PyObject *subpath = PyList_GET_ITEM(dotted_path, i); + if (_PyUnicode_EqualToASCIIString(subpath, "")) { + if (obj == NULL) + PyErr_Format(PyExc_AttributeError, + "Can't pickle local object %R", name); + else + PyErr_Format(PyExc_AttributeError, + "Can't pickle local attribute %R on %R", name, obj); + Py_DECREF(dotted_path); + return NULL; + } + } + return dotted_path; +} + +static PyObject * +get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent) +{ + Py_ssize_t i, n; + PyObject *parent = NULL; + + assert(PyList_CheckExact(names)); + Py_INCREF(obj); + n = PyList_GET_SIZE(names); + for (i = 0; i < n; i++) { + PyObject *name = PyList_GET_ITEM(names, i); + Py_XDECREF(parent); + parent = obj; + (void)_PyObject_LookupAttr(parent, name, &obj); + if (obj == NULL) { + Py_DECREF(parent); + return NULL; + } + } + if (pparent != NULL) + *pparent = parent; + else + Py_XDECREF(parent); + return obj; +} + + +static PyObject * +getattribute(PyObject *obj, PyObject *name, int allow_qualname) +{ + PyObject *dotted_path, *attr; + + if (allow_qualname) { + dotted_path = get_dotted_path(obj, name); + if (dotted_path == NULL) + return NULL; + attr = get_deep_attribute(obj, dotted_path, NULL); + Py_DECREF(dotted_path); + } + else { + (void)_PyObject_LookupAttr(obj, name, &attr); + } + if (attr == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_AttributeError, + "Can't get attribute %R on %R", name, obj); + } + return attr; +} + +static int +_checkmodule(PyObject *module_name, PyObject *module, + PyObject *global, PyObject *dotted_path) +{ + if (module == Py_None) { + return -1; + } + if (PyUnicode_Check(module_name) && + _PyUnicode_EqualToASCIIString(module_name, "__main__")) { + return -1; + } + + PyObject *candidate = get_deep_attribute(module, dotted_path, NULL); + if (candidate == NULL) { + return -1; + } + if (candidate != global) { + Py_DECREF(candidate); + return -1; + } + Py_DECREF(candidate); + return 0; +} + +static PyObject * +whichmodule(PyObject *global, PyObject *dotted_path) +{ + PyObject *module_name; + PyObject *module = NULL; + Py_ssize_t i; + PyObject *modules; + _Py_IDENTIFIER(__module__); + _Py_IDENTIFIER(modules); + _Py_IDENTIFIER(__main__); + + if (_PyObject_LookupAttrId(global, &PyId___module__, &module_name) < 0) { + return NULL; + } + if (module_name) { + /* In some rare cases (e.g., bound methods of extension types), + __module__ can be None. If it is so, then search sys.modules for + the module of global. */ + if (module_name != Py_None) + return module_name; + Py_CLEAR(module_name); + } + assert(module_name == NULL); + + /* Fallback on walking sys.modules */ + modules = _PySys_GetObjectId(&PyId_modules); + if (modules == NULL) { + PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); + return NULL; + } + if (PyDict_CheckExact(modules)) { + i = 0; + while (PyDict_Next(modules, &i, &module_name, &module)) { + if (_checkmodule(module_name, module, global, dotted_path) == 0) { + Py_INCREF(module_name); + return module_name; + } + if (PyErr_Occurred()) { + return NULL; + } + } + } + else { + PyObject *iterator = PyObject_GetIter(modules); + if (iterator == NULL) { + return NULL; + } + while ((module_name = PyIter_Next(iterator))) { + module = PyObject_GetItem(modules, module_name); + if (module == NULL) { + Py_DECREF(module_name); + Py_DECREF(iterator); + return NULL; + } + if (_checkmodule(module_name, module, global, dotted_path) == 0) { + Py_DECREF(module); + Py_DECREF(iterator); + return module_name; + } + Py_DECREF(module); + Py_DECREF(module_name); + if (PyErr_Occurred()) { + Py_DECREF(iterator); + return NULL; + } + } + Py_DECREF(iterator); + } + + /* If no module is found, use __main__. */ + module_name = _PyUnicode_FromId(&PyId___main__); + Py_XINCREF(module_name); + return module_name; +} + +/* fast_save_enter() and fast_save_leave() are guards against recursive + objects when Pickler is used with the "fast mode" (i.e., with object + memoization disabled). If the nesting of a list or dict object exceed + FAST_NESTING_LIMIT, these guards will start keeping an internal + reference to the seen list or dict objects and check whether these objects + are recursive. These are not strictly necessary, since save() has a + hard-coded recursion limit, but they give a nicer error message than the + typical RuntimeError. */ +static int +fast_save_enter(PicklerObject *self, PyObject *obj) +{ + /* if fast_nesting < 0, we're doing an error exit. */ + if (++self->fast_nesting >= FAST_NESTING_LIMIT) { + PyObject *key = NULL; + if (self->fast_memo == NULL) { + self->fast_memo = PyDict_New(); + if (self->fast_memo == NULL) { + self->fast_nesting = -1; + return 0; + } + } + key = PyLong_FromVoidPtr(obj); + if (key == NULL) { + self->fast_nesting = -1; + return 0; + } + if (PyDict_GetItemWithError(self->fast_memo, key)) { + Py_DECREF(key); + PyErr_Format(PyExc_ValueError, + "fast mode: can't pickle cyclic objects " + "including object type %.200s at %p", + Py_TYPE(obj)->tp_name, obj); + self->fast_nesting = -1; + return 0; + } + if (PyErr_Occurred()) { + Py_DECREF(key); + self->fast_nesting = -1; + return 0; + } + if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) { + Py_DECREF(key); + self->fast_nesting = -1; + return 0; + } + Py_DECREF(key); + } + return 1; +} + +static int +fast_save_leave(PicklerObject *self, PyObject *obj) +{ + if (self->fast_nesting-- >= FAST_NESTING_LIMIT) { + PyObject *key = PyLong_FromVoidPtr(obj); + if (key == NULL) + return 0; + if (PyDict_DelItem(self->fast_memo, key) < 0) { + Py_DECREF(key); + return 0; + } + Py_DECREF(key); + } + return 1; +} + +static int +save_none(PicklerObject *self, PyObject *obj) +{ + const char none_op = NONE; + if (_Pickler_Write(self, &none_op, 1) < 0) + return -1; + + return 0; +} + +static int +save_bool(PicklerObject *self, PyObject *obj) +{ + if (self->proto >= 2) { + const char bool_op = (obj == Py_True) ? NEWTRUE : NEWFALSE; + if (_Pickler_Write(self, &bool_op, 1) < 0) + return -1; + } + else { + /* These aren't opcodes -- they're ways to pickle bools before protocol 2 + * so that unpicklers written before bools were introduced unpickle them + * as ints, but unpicklers after can recognize that bools were intended. + * Note that protocol 2 added direct ways to pickle bools. + */ + const char *bool_str = (obj == Py_True) ? "I01\n" : "I00\n"; + if (_Pickler_Write(self, bool_str, strlen(bool_str)) < 0) + return -1; + } + return 0; +} + +static int +save_long(PicklerObject *self, PyObject *obj) +{ + PyObject *repr = NULL; + Py_ssize_t size; + long val; + int overflow; + int status = 0; + + val= PyLong_AsLongAndOverflow(obj, &overflow); + if (!overflow && (sizeof(long) <= 4 || + (val <= 0x7fffffffL && val >= (-0x7fffffffL - 1)))) + { + /* result fits in a signed 4-byte integer. + + Note: we can't use -0x80000000L in the above condition because some + compilers (e.g., MSVC) will promote 0x80000000L to an unsigned type + before applying the unary minus when sizeof(long) <= 4. The + resulting value stays unsigned which is commonly not what we want, + so MSVC happily warns us about it. However, that result would have + been fine because we guard for sizeof(long) <= 4 which turns the + condition true in that particular case. */ + char pdata[32]; + Py_ssize_t len = 0; + + if (self->bin) { + pdata[1] = (unsigned char)(val & 0xff); + pdata[2] = (unsigned char)((val >> 8) & 0xff); + pdata[3] = (unsigned char)((val >> 16) & 0xff); + pdata[4] = (unsigned char)((val >> 24) & 0xff); + + if ((pdata[4] != 0) || (pdata[3] != 0)) { + pdata[0] = BININT; + len = 5; + } + else if (pdata[2] != 0) { + pdata[0] = BININT2; + len = 3; + } + else { + pdata[0] = BININT1; + len = 2; + } + } + else { + sprintf(pdata, "%c%ld\n", INT_, val); + len = strlen(pdata); + } + if (_Pickler_Write(self, pdata, len) < 0) + return -1; + + return 0; + } + assert(!PyErr_Occurred()); + + if (self->proto >= 2) { + /* Linear-time pickling. */ + size_t nbits; + size_t nbytes; + unsigned char *pdata; + char header[5]; + int i; + int sign = _PyLong_Sign(obj); + + if (sign == 0) { + header[0] = LONG1; + header[1] = 0; /* It's 0 -- an empty bytestring. */ + if (_Pickler_Write(self, header, 2) < 0) + goto error; + return 0; + } + nbits = _PyLong_NumBits(obj); + if (nbits == (size_t)-1 && PyErr_Occurred()) + goto error; + /* How many bytes do we need? There are nbits >> 3 full + * bytes of data, and nbits & 7 leftover bits. If there + * are any leftover bits, then we clearly need another + * byte. What's not so obvious is that we *probably* + * need another byte even if there aren't any leftovers: + * the most-significant bit of the most-significant byte + * acts like a sign bit, and it's usually got a sense + * opposite of the one we need. The exception is ints + * of the form -(2**(8*j-1)) for j > 0. Such an int is + * its own 256's-complement, so has the right sign bit + * even without the extra byte. That's a pain to check + * for in advance, though, so we always grab an extra + * byte at the start, and cut it back later if possible. + */ + nbytes = (nbits >> 3) + 1; + if (nbytes > 0x7fffffffL) { + PyErr_SetString(PyExc_OverflowError, + "int too large to pickle"); + goto error; + } + repr = PyBytes_FromStringAndSize(NULL, (Py_ssize_t)nbytes); + if (repr == NULL) + goto error; + pdata = (unsigned char *)PyBytes_AS_STRING(repr); + i = _PyLong_AsByteArray((PyLongObject *)obj, + pdata, nbytes, + 1 /* little endian */ , 1 /* signed */ ); + if (i < 0) + goto error; + /* If the int is negative, this may be a byte more than + * needed. This is so iff the MSB is all redundant sign + * bits. + */ + if (sign < 0 && + nbytes > 1 && + pdata[nbytes - 1] == 0xff && + (pdata[nbytes - 2] & 0x80) != 0) { + nbytes--; + } + + if (nbytes < 256) { + header[0] = LONG1; + header[1] = (unsigned char)nbytes; + size = 2; + } + else { + header[0] = LONG4; + size = (Py_ssize_t) nbytes; + for (i = 1; i < 5; i++) { + header[i] = (unsigned char)(size & 0xff); + size >>= 8; + } + size = 5; + } + if (_Pickler_Write(self, header, size) < 0 || + _Pickler_Write(self, (char *)pdata, (int)nbytes) < 0) + goto error; + } + else { + const char long_op = LONG_; + const char *string; + + /* proto < 2: write the repr and newline. This is quadratic-time (in + the number of digits), in both directions. We add a trailing 'L' + to the repr, for compatibility with Python 2.x. */ + + repr = PyObject_Repr(obj); + if (repr == NULL) + goto error; + + string = PyUnicode_AsUTF8AndSize(repr, &size); + if (string == NULL) + goto error; + + if (_Pickler_Write(self, &long_op, 1) < 0 || + _Pickler_Write(self, string, size) < 0 || + _Pickler_Write(self, "L\n", 2) < 0) + goto error; + } + + if (0) { + error: + status = -1; + } + Py_XDECREF(repr); + + return status; +} + +static int +save_float(PicklerObject *self, PyObject *obj) +{ + double x = PyFloat_AS_DOUBLE((PyFloatObject *)obj); + + if (self->bin) { + char pdata[9]; + pdata[0] = BINFLOAT; + if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0) + return -1; + if (_Pickler_Write(self, pdata, 9) < 0) + return -1; + } + else { + int result = -1; + char *buf = NULL; + char op = FLOAT_; + + if (_Pickler_Write(self, &op, 1) < 0) + goto done; + + buf = PyOS_double_to_string(x, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!buf) { + PyErr_NoMemory(); + goto done; + } + + if (_Pickler_Write(self, buf, strlen(buf)) < 0) + goto done; + + if (_Pickler_Write(self, "\n", 1) < 0) + goto done; + + result = 0; +done: + PyMem_Free(buf); + return result; + } + + return 0; +} + +/* Perform direct write of the header and payload of the binary object. + + The large contiguous data is written directly into the underlying file + object, bypassing the output_buffer of the Pickler. We intentionally + do not insert a protocol 4 frame opcode to make it possible to optimize + file.read calls in the loader. + */ +static int +_Pickler_write_bytes(PicklerObject *self, + const char *header, Py_ssize_t header_size, + const char *data, Py_ssize_t data_size, + PyObject *payload) +{ + int bypass_buffer = (data_size >= FRAME_SIZE_TARGET); + int framing = self->framing; + + if (bypass_buffer) { + assert(self->output_buffer != NULL); + /* Commit the previous frame. */ + if (_Pickler_CommitFrame(self)) { + return -1; + } + /* Disable framing temporarily */ + self->framing = 0; + } + + if (_Pickler_Write(self, header, header_size) < 0) { + return -1; + } + + if (bypass_buffer && self->write != NULL) { + /* Bypass the in-memory buffer to directly stream large data + into the underlying file object. */ + PyObject *result, *mem = NULL; + /* Dump the output buffer to the file. */ + if (_Pickler_FlushToFile(self) < 0) { + return -1; + } + + /* Stream write the payload into the file without going through the + output buffer. */ + if (payload == NULL) { + /* TODO: It would be better to use a memoryview with a linked + original string if this is possible. */ + payload = mem = PyBytes_FromStringAndSize(data, data_size); + if (payload == NULL) { + return -1; + } + } + result = PyObject_CallOneArg(self->write, payload); + Py_XDECREF(mem); + if (result == NULL) { + return -1; + } + Py_DECREF(result); + + /* Reinitialize the buffer for subsequent calls to _Pickler_Write. */ + if (_Pickler_ClearBuffer(self) < 0) { + return -1; + } + } + else { + if (_Pickler_Write(self, data, data_size) < 0) { + return -1; + } + } + + /* Re-enable framing for subsequent calls to _Pickler_Write. */ + self->framing = framing; + + return 0; +} + +static int +_save_bytes_data(PicklerObject *self, PyObject *obj, const char *data, + Py_ssize_t size) { - if (self) { - return PyMethod_New(func, self); + assert(self->proto >= 3); + + char header[9]; + Py_ssize_t len; + + if (size < 0) + return -1; + + if (size <= 0xff) { + header[0] = SHORT_BINBYTES; + header[1] = (unsigned char)size; + len = 2; } - else { - Py_INCREF(func); - return func; + else if ((size_t)size <= 0xffffffffUL) { + header[0] = BINBYTES; + header[1] = (unsigned char)(size & 0xff); + header[2] = (unsigned char)((size >> 8) & 0xff); + header[3] = (unsigned char)((size >> 16) & 0xff); + header[4] = (unsigned char)((size >> 24) & 0xff); + len = 5; } -} - -static PyObject * -call_method(PyObject *func, PyObject *self, PyObject *obj) -{ - if (self) { - return PyObject_CallFunctionObjArgs(func, self, obj, NULL); + else if (self->proto >= 4) { + header[0] = BINBYTES8; + _write_size64(header + 1, size); + len = 9; } else { - return PyObject_CallOneArg(func, obj); + PyErr_SetString(PyExc_OverflowError, + "serializing a bytes object larger than 4 GiB " + "requires pickle protocol 4 or higher"); + return -1; } -} -/*************************************************************************/ - -/* Internal data type used as the unpickling stack. */ -typedef struct { - PyObject_VAR_HEAD - PyObject **data; - int mark_set; /* is MARK set? */ - Py_ssize_t fence; /* position of top MARK or 0 */ - Py_ssize_t allocated; /* number of slots in data allocated */ -} Pdata; + if (_Pickler_write_bytes(self, header, len, data, size, obj) < 0) { + return -1; + } -static void -Pdata_dealloc(Pdata *self) -{ - Py_ssize_t i = Py_SIZE(self); - while (--i >= 0) { - Py_DECREF(self->data[i]); + if (memo_put(self, obj) < 0) { + return -1; } - PyMem_FREE(self->data); - PyObject_Del(self); -} -static PyTypeObject Pdata_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.Pdata", /*tp_name*/ - sizeof(Pdata), /*tp_basicsize*/ - sizeof(PyObject *), /*tp_itemsize*/ - (destructor)Pdata_dealloc, /*tp_dealloc*/ -}; - -static PyObject * -Pdata_New(void) -{ - Pdata *self; - - if (!(self = PyObject_New(Pdata, &Pdata_Type))) - return NULL; - Py_SET_SIZE(self, 0); - self->mark_set = 0; - self->fence = 0; - self->allocated = 8; - self->data = PyMem_MALLOC(self->allocated * sizeof(PyObject *)); - if (self->data) - return (PyObject *)self; - Py_DECREF(self); - return PyErr_NoMemory(); -} - - -/* Retain only the initial clearto items. If clearto >= the current - * number of items, this is a (non-erroneous) NOP. - */ -static int -Pdata_clear(Pdata *self, Py_ssize_t clearto) -{ - Py_ssize_t i = Py_SIZE(self); - - assert(clearto >= self->fence); - if (clearto >= i) - return 0; - - while (--i >= clearto) { - Py_CLEAR(self->data[i]); - } - Py_SET_SIZE(self, clearto); - return 0; -} - -static int -Pdata_grow(Pdata *self) -{ - PyObject **data = self->data; - size_t allocated = (size_t)self->allocated; - size_t new_allocated; - - new_allocated = (allocated >> 3) + 6; - /* check for integer overflow */ - if (new_allocated > (size_t)PY_SSIZE_T_MAX - allocated) - goto nomemory; - new_allocated += allocated; - PyMem_RESIZE(data, PyObject *, new_allocated); - if (data == NULL) - goto nomemory; - - self->data = data; - self->allocated = (Py_ssize_t)new_allocated; - return 0; - - nomemory: - PyErr_NoMemory(); - return -1; -} - -static int -Pdata_stack_underflow(Pdata *self) -{ - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, - self->mark_set ? - "unexpected MARK found" : - "unpickling stack underflow"); - return -1; -} - -/* D is a Pdata*. Pop the topmost element and store it into V, which - * must be an lvalue holding PyObject*. On stack underflow, UnpicklingError - * is raised and V is set to NULL. - */ -static PyObject * -Pdata_pop(Pdata *self) -{ - if (Py_SIZE(self) <= self->fence) { - Pdata_stack_underflow(self); - return NULL; - } - Py_SET_SIZE(self, Py_SIZE(self) - 1); - return self->data[Py_SIZE(self)]; -} -#define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0) - -static int -Pdata_push(Pdata *self, PyObject *obj) -{ - if (Py_SIZE(self) == self->allocated && Pdata_grow(self) < 0) { - return -1; - } - self->data[Py_SIZE(self)] = obj; - Py_SET_SIZE(self, Py_SIZE(self) + 1); - return 0; -} - -/* Push an object on stack, transferring its ownership to the stack. */ -#define PDATA_PUSH(D, O, ER) do { \ - if (Pdata_push((D), (O)) < 0) return (ER); } while(0) - -/* Push an object on stack, adding a new reference to the object. */ -#define PDATA_APPEND(D, O, ER) do { \ - Py_INCREF((O)); \ - if (Pdata_push((D), (O)) < 0) return (ER); } while(0) - -static PyObject * -Pdata_poptuple(Pdata *self, Py_ssize_t start) -{ - PyObject *tuple; - Py_ssize_t len, i, j; - - if (start < self->fence) { - Pdata_stack_underflow(self); - return NULL; - } - len = Py_SIZE(self) - start; - tuple = PyTuple_New(len); - if (tuple == NULL) - return NULL; - for (i = start, j = 0; j < len; i++, j++) - PyTuple_SET_ITEM(tuple, j, self->data[i]); - - Py_SET_SIZE(self, start); - return tuple; -} - -static PyObject * -Pdata_poplist(Pdata *self, Py_ssize_t start) -{ - PyObject *list; - Py_ssize_t len, i, j; - - len = Py_SIZE(self) - start; - list = PyList_New(len); - if (list == NULL) - return NULL; - for (i = start, j = 0; j < len; i++, j++) - PyList_SET_ITEM(list, j, self->data[i]); - - Py_SET_SIZE(self, start); - return list; -} - -typedef struct { - PyObject *me_key; - Py_ssize_t me_value; -} PyMemoEntry; - -typedef struct { - size_t mt_mask; - size_t mt_used; - size_t mt_allocated; - PyMemoEntry *mt_table; -} PyMemoTable; - -typedef struct PicklerObject { - PyObject_HEAD - PyMemoTable *memo; /* Memo table, keep track of the seen - objects to support self-referential objects - pickling. */ - PyObject *pers_func; /* persistent_id() method, can be NULL */ - PyObject *pers_func_self; /* borrowed reference to self if pers_func - is an unbound method, NULL otherwise */ - PyObject *dispatch_table; /* private dispatch_table, can be NULL */ - PyObject *reducer_override; /* hook for invoking user-defined callbacks - instead of save_global when pickling - functions and classes*/ - - PyObject *write; /* write() method of the output stream. */ - PyObject *output_buffer; /* Write into a local bytearray buffer before - flushing to the stream. */ - Py_ssize_t output_len; /* Length of output_buffer. */ - Py_ssize_t max_output_len; /* Allocation size of output_buffer. */ - int proto; /* Pickle protocol number, >= 0 */ - int bin; /* Boolean, true if proto > 0 */ - int framing; /* True when framing is enabled, proto >= 4 */ - Py_ssize_t frame_start; /* Position in output_buffer where the - current frame begins. -1 if there - is no frame currently open. */ - - Py_ssize_t buf_size; /* Size of the current buffered pickle data */ - int fast; /* Enable fast mode if set to a true value. - The fast mode disable the usage of memo, - therefore speeding the pickling process by - not generating superfluous PUT opcodes. It - should not be used if with self-referential - objects. */ - int fast_nesting; - int fix_imports; /* Indicate whether Pickler should fix - the name of globals for Python 2.x. */ - PyObject *fast_memo; - PyObject *buffer_callback; /* Callback for out-of-band buffers, or NULL */ -} PicklerObject; - -typedef struct UnpicklerObject { - PyObject_HEAD - Pdata *stack; /* Pickle data stack, store unpickled objects. */ - - /* The unpickler memo is just an array of PyObject *s. Using a dict - is unnecessary, since the keys are contiguous ints. */ - PyObject **memo; - size_t memo_size; /* Capacity of the memo array */ - size_t memo_len; /* Number of objects in the memo */ - - PyObject *pers_func; /* persistent_load() method, can be NULL. */ - PyObject *pers_func_self; /* borrowed reference to self if pers_func - is an unbound method, NULL otherwise */ - - Py_buffer buffer; - char *input_buffer; - char *input_line; - Py_ssize_t input_len; - Py_ssize_t next_read_idx; - Py_ssize_t prefetched_idx; /* index of first prefetched byte */ - - PyObject *read; /* read() method of the input stream. */ - PyObject *readinto; /* readinto() method of the input stream. */ - PyObject *readline; /* readline() method of the input stream. */ - PyObject *peek; /* peek() method of the input stream, or NULL */ - PyObject *buffers; /* iterable of out-of-band buffers, or NULL */ - - char *encoding; /* Name of the encoding to be used for - decoding strings pickled using Python - 2.x. The default value is "ASCII" */ - char *errors; /* Name of errors handling scheme to used when - decoding strings. The default value is - "strict". */ - Py_ssize_t *marks; /* Mark stack, used for unpickling container - objects. */ - Py_ssize_t num_marks; /* Number of marks in the mark stack. */ - Py_ssize_t marks_size; /* Current allocated size of the mark stack. */ - int proto; /* Protocol of the pickle loaded. */ - int fix_imports; /* Indicate whether Unpickler should fix - the name of globals pickled by Python 2.x. */ -} UnpicklerObject; - -typedef struct { - PyObject_HEAD - PicklerObject *pickler; /* Pickler whose memo table we're proxying. */ -} PicklerMemoProxyObject; - -typedef struct { - PyObject_HEAD - UnpicklerObject *unpickler; -} UnpicklerMemoProxyObject; - -/* Forward declarations */ -static int save(PicklerObject *, PyObject *, int); -static int save_reduce(PicklerObject *, PyObject *, PyObject *); -static PyTypeObject Pickler_Type; -static PyTypeObject Unpickler_Type; - -#include "clinic/_pickle.c.h" - -/************************************************************************* - A custom hashtable mapping void* to Python ints. This is used by the pickler - for memoization. Using a custom hashtable rather than PyDict allows us to skip - a bunch of unnecessary object creation. This makes a huge performance - difference. */ - -#define MT_MINSIZE 8 -#define PERTURB_SHIFT 5 - - -static PyMemoTable * -PyMemoTable_New(void) -{ - PyMemoTable *memo = PyMem_MALLOC(sizeof(PyMemoTable)); - if (memo == NULL) { - PyErr_NoMemory(); - return NULL; - } - - memo->mt_used = 0; - memo->mt_allocated = MT_MINSIZE; - memo->mt_mask = MT_MINSIZE - 1; - memo->mt_table = PyMem_MALLOC(MT_MINSIZE * sizeof(PyMemoEntry)); - if (memo->mt_table == NULL) { - PyMem_FREE(memo); - PyErr_NoMemory(); - return NULL; - } - memset(memo->mt_table, 0, MT_MINSIZE * sizeof(PyMemoEntry)); - - return memo; -} - -static PyMemoTable * -PyMemoTable_Copy(PyMemoTable *self) -{ - PyMemoTable *new = PyMemoTable_New(); - if (new == NULL) - return NULL; - - new->mt_used = self->mt_used; - new->mt_allocated = self->mt_allocated; - new->mt_mask = self->mt_mask; - /* The table we get from _New() is probably smaller than we wanted. - Free it and allocate one that's the right size. */ - PyMem_FREE(new->mt_table); - new->mt_table = PyMem_NEW(PyMemoEntry, self->mt_allocated); - if (new->mt_table == NULL) { - PyMem_FREE(new); - PyErr_NoMemory(); - return NULL; - } - for (size_t i = 0; i < self->mt_allocated; i++) { - Py_XINCREF(self->mt_table[i].me_key); - } - memcpy(new->mt_table, self->mt_table, - sizeof(PyMemoEntry) * self->mt_allocated); - - return new; -} - -static Py_ssize_t -PyMemoTable_Size(PyMemoTable *self) -{ - return self->mt_used; -} - -static int -PyMemoTable_Clear(PyMemoTable *self) -{ - Py_ssize_t i = self->mt_allocated; - - while (--i >= 0) { - Py_XDECREF(self->mt_table[i].me_key); - } - self->mt_used = 0; - memset(self->mt_table, 0, self->mt_allocated * sizeof(PyMemoEntry)); - return 0; -} - -static void -PyMemoTable_Del(PyMemoTable *self) -{ - if (self == NULL) - return; - PyMemoTable_Clear(self); - - PyMem_FREE(self->mt_table); - PyMem_FREE(self); -} - -/* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup() - can be considerably simpler than dictobject.c's lookdict(). */ -static PyMemoEntry * -_PyMemoTable_Lookup(PyMemoTable *self, PyObject *key) -{ - size_t i; - size_t perturb; - size_t mask = self->mt_mask; - PyMemoEntry *table = self->mt_table; - PyMemoEntry *entry; - Py_hash_t hash = (Py_hash_t)key >> 3; - - i = hash & mask; - entry = &table[i]; - if (entry->me_key == NULL || entry->me_key == key) - return entry; - - for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { - i = (i << 2) + i + perturb + 1; - entry = &table[i & mask]; - if (entry->me_key == NULL || entry->me_key == key) - return entry; - } - Py_UNREACHABLE(); -} - -/* Returns -1 on failure, 0 on success. */ -static int -_PyMemoTable_ResizeTable(PyMemoTable *self, size_t min_size) -{ - PyMemoEntry *oldtable = NULL; - PyMemoEntry *oldentry, *newentry; - size_t new_size = MT_MINSIZE; - size_t to_process; - - assert(min_size > 0); - - if (min_size > PY_SSIZE_T_MAX) { - PyErr_NoMemory(); - return -1; - } - - /* Find the smallest valid table size >= min_size. */ - while (new_size < min_size) { - new_size <<= 1; - } - /* new_size needs to be a power of two. */ - assert((new_size & (new_size - 1)) == 0); - - /* Allocate new table. */ - oldtable = self->mt_table; - self->mt_table = PyMem_NEW(PyMemoEntry, new_size); - if (self->mt_table == NULL) { - self->mt_table = oldtable; - PyErr_NoMemory(); - return -1; - } - self->mt_allocated = new_size; - self->mt_mask = new_size - 1; - memset(self->mt_table, 0, sizeof(PyMemoEntry) * new_size); - - /* Copy entries from the old table. */ - to_process = self->mt_used; - for (oldentry = oldtable; to_process > 0; oldentry++) { - if (oldentry->me_key != NULL) { - to_process--; - /* newentry is a pointer to a chunk of the new - mt_table, so we're setting the key:value pair - in-place. */ - newentry = _PyMemoTable_Lookup(self, oldentry->me_key); - newentry->me_key = oldentry->me_key; - newentry->me_value = oldentry->me_value; - } - } - - /* Deallocate the old table. */ - PyMem_FREE(oldtable); - return 0; -} - -/* Returns NULL on failure, a pointer to the value otherwise. */ -static Py_ssize_t * -PyMemoTable_Get(PyMemoTable *self, PyObject *key) -{ - PyMemoEntry *entry = _PyMemoTable_Lookup(self, key); - if (entry->me_key == NULL) - return NULL; - return &entry->me_value; -} - -/* Returns -1 on failure, 0 on success. */ -static int -PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value) -{ - PyMemoEntry *entry; - - assert(key != NULL); - - entry = _PyMemoTable_Lookup(self, key); - if (entry->me_key != NULL) { - entry->me_value = value; - return 0; - } - Py_INCREF(key); - entry->me_key = key; - entry->me_value = value; - self->mt_used++; - - /* If we added a key, we can safely resize. Otherwise just return! - * If used >= 2/3 size, adjust size. Normally, this quaduples the size. - * - * Quadrupling the size improves average table sparseness - * (reducing collisions) at the cost of some memory. It also halves - * the number of expensive resize operations in a growing memo table. - * - * Very large memo tables (over 50K items) use doubling instead. - * This may help applications with severe memory constraints. - */ - if (SIZE_MAX / 3 >= self->mt_used && self->mt_used * 3 < self->mt_allocated * 2) { - return 0; - } - // self->mt_used is always < PY_SSIZE_T_MAX, so this can't overflow. - size_t desired_size = (self->mt_used > 50000 ? 2 : 4) * self->mt_used; - return _PyMemoTable_ResizeTable(self, desired_size); -} - -#undef MT_MINSIZE -#undef PERTURB_SHIFT - -/*************************************************************************/ - - -static int -_Pickler_ClearBuffer(PicklerObject *self) -{ - Py_XSETREF(self->output_buffer, - PyBytes_FromStringAndSize(NULL, self->max_output_len)); - if (self->output_buffer == NULL) - return -1; - self->output_len = 0; - self->frame_start = -1; - return 0; -} - -static void -_write_size64(char *out, size_t value) -{ - size_t i; - - Py_BUILD_ASSERT(sizeof(size_t) <= 8); - - for (i = 0; i < sizeof(size_t); i++) { - out[i] = (unsigned char)((value >> (8 * i)) & 0xff); - } - for (i = sizeof(size_t); i < 8; i++) { - out[i] = 0; - } -} - -static int -_Pickler_CommitFrame(PicklerObject *self) -{ - size_t frame_len; - char *qdata; - - if (!self->framing || self->frame_start == -1) - return 0; - frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE; - qdata = PyBytes_AS_STRING(self->output_buffer) + self->frame_start; - if (frame_len >= FRAME_SIZE_MIN) { - qdata[0] = FRAME; - _write_size64(qdata + 1, frame_len); - } - else { - memmove(qdata, qdata + FRAME_HEADER_SIZE, frame_len); - self->output_len -= FRAME_HEADER_SIZE; - } - self->frame_start = -1; - return 0; -} - -static PyObject * -_Pickler_GetString(PicklerObject *self) -{ - PyObject *output_buffer = self->output_buffer; - - assert(self->output_buffer != NULL); - - if (_Pickler_CommitFrame(self)) - return NULL; - - self->output_buffer = NULL; - /* Resize down to exact size */ - if (_PyBytes_Resize(&output_buffer, self->output_len) < 0) - return NULL; - return output_buffer; -} - -static int -_Pickler_FlushToFile(PicklerObject *self) -{ - PyObject *output, *result; - - assert(self->write != NULL); - - /* This will commit the frame first */ - output = _Pickler_GetString(self); - if (output == NULL) - return -1; - - result = _Pickle_FastCall(self->write, output); - Py_XDECREF(result); - return (result == NULL) ? -1 : 0; -} - -static int -_Pickler_OpcodeBoundary(PicklerObject *self) -{ - Py_ssize_t frame_len; - - if (!self->framing || self->frame_start == -1) { - return 0; - } - frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE; - if (frame_len >= FRAME_SIZE_TARGET) { - if(_Pickler_CommitFrame(self)) { - return -1; - } - /* Flush the content of the committed frame to the underlying - * file and reuse the pickler buffer for the next frame so as - * to limit memory usage when dumping large complex objects to - * a file. - * - * self->write is NULL when called via dumps. - */ - if (self->write != NULL) { - if (_Pickler_FlushToFile(self) < 0) { - return -1; - } - if (_Pickler_ClearBuffer(self) < 0) { - return -1; - } - } - } - return 0; -} - -static Py_ssize_t -_Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len) -{ - Py_ssize_t i, n, required; - char *buffer; - int need_new_frame; - - assert(s != NULL); - need_new_frame = (self->framing && self->frame_start == -1); - - if (need_new_frame) - n = data_len + FRAME_HEADER_SIZE; - else - n = data_len; - - required = self->output_len + n; - if (required > self->max_output_len) { - /* Make place in buffer for the pickle chunk */ - if (self->output_len >= PY_SSIZE_T_MAX / 2 - n) { - PyErr_NoMemory(); - return -1; - } - self->max_output_len = (self->output_len + n) / 2 * 3; - if (_PyBytes_Resize(&self->output_buffer, self->max_output_len) < 0) - return -1; - } - buffer = PyBytes_AS_STRING(self->output_buffer); - if (need_new_frame) { - /* Setup new frame */ - Py_ssize_t frame_start = self->output_len; - self->frame_start = frame_start; - for (i = 0; i < FRAME_HEADER_SIZE; i++) { - /* Write an invalid value, for debugging */ - buffer[frame_start + i] = 0xFE; - } - self->output_len += FRAME_HEADER_SIZE; - } - if (data_len < 8) { - /* This is faster than memcpy when the string is short. */ - for (i = 0; i < data_len; i++) { - buffer[self->output_len + i] = s[i]; - } - } - else { - memcpy(buffer + self->output_len, s, data_len); - } - self->output_len += data_len; - return data_len; -} - -static PicklerObject * -_Pickler_New(void) -{ - PicklerObject *self; - - self = PyObject_GC_New(PicklerObject, &Pickler_Type); - if (self == NULL) - return NULL; - - self->pers_func = NULL; - self->dispatch_table = NULL; - self->buffer_callback = NULL; - self->write = NULL; - self->proto = 0; - self->bin = 0; - self->framing = 0; - self->frame_start = -1; - self->fast = 0; - self->fast_nesting = 0; - self->fix_imports = 0; - self->fast_memo = NULL; - self->max_output_len = WRITE_BUF_SIZE; - self->output_len = 0; - self->reducer_override = NULL; - - self->memo = PyMemoTable_New(); - self->output_buffer = PyBytes_FromStringAndSize(NULL, - self->max_output_len); - - if (self->memo == NULL || self->output_buffer == NULL) { - Py_DECREF(self); - return NULL; - } - - PyObject_GC_Track(self); - return self; -} - -static int -_Pickler_SetProtocol(PicklerObject *self, PyObject *protocol, int fix_imports) -{ - long proto; - - if (protocol == Py_None) { - proto = DEFAULT_PROTOCOL; - } - else { - proto = PyLong_AsLong(protocol); - if (proto < 0) { - if (proto == -1 && PyErr_Occurred()) - return -1; - proto = HIGHEST_PROTOCOL; - } - else if (proto > HIGHEST_PROTOCOL) { - PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d", - HIGHEST_PROTOCOL); - return -1; - } - } - self->proto = (int)proto; - self->bin = proto > 0; - self->fix_imports = fix_imports && proto < 3; - return 0; -} - -/* Returns -1 (with an exception set) on failure, 0 on success. This may - be called once on a freshly created Pickler. */ -static int -_Pickler_SetOutputStream(PicklerObject *self, PyObject *file) -{ - _Py_IDENTIFIER(write); - assert(file != NULL); - if (_PyObject_LookupAttrId(file, &PyId_write, &self->write) < 0) { - return -1; - } - if (self->write == NULL) { - PyErr_SetString(PyExc_TypeError, - "file must have a 'write' attribute"); - return -1; - } - - return 0; -} - -static int -_Pickler_SetBufferCallback(PicklerObject *self, PyObject *buffer_callback) -{ - if (buffer_callback == Py_None) { - buffer_callback = NULL; - } - if (buffer_callback != NULL && self->proto < 5) { - PyErr_SetString(PyExc_ValueError, - "buffer_callback needs protocol >= 5"); - return -1; - } - - Py_XINCREF(buffer_callback); - self->buffer_callback = buffer_callback; - return 0; -} - -/* Returns the size of the input on success, -1 on failure. This takes its - own reference to `input`. */ -static Py_ssize_t -_Unpickler_SetStringInput(UnpicklerObject *self, PyObject *input) -{ - if (self->buffer.buf != NULL) - PyBuffer_Release(&self->buffer); - if (PyObject_GetBuffer(input, &self->buffer, PyBUF_CONTIG_RO) < 0) - return -1; - self->input_buffer = self->buffer.buf; - self->input_len = self->buffer.len; - self->next_read_idx = 0; - self->prefetched_idx = self->input_len; - return self->input_len; -} - -static int -bad_readline(void) -{ - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, "pickle data was truncated"); - return -1; -} - -/* Skip any consumed data that was only prefetched using peek() */ -static int -_Unpickler_SkipConsumed(UnpicklerObject *self) -{ - Py_ssize_t consumed; - PyObject *r; - - consumed = self->next_read_idx - self->prefetched_idx; - if (consumed <= 0) - return 0; - - assert(self->peek); /* otherwise we did something wrong */ - /* This makes a useless copy... */ - r = PyObject_CallFunction(self->read, "n", consumed); - if (r == NULL) - return -1; - Py_DECREF(r); - - self->prefetched_idx = self->next_read_idx; - return 0; -} - -static const Py_ssize_t READ_WHOLE_LINE = -1; - -/* If reading from a file, we need to only pull the bytes we need, since there - may be multiple pickle objects arranged contiguously in the same input - buffer. - - If `n` is READ_WHOLE_LINE, read a whole line. Otherwise, read up to `n` - bytes from the input stream/buffer. - - Update the unpickler's input buffer with the newly-read data. Returns -1 on - failure; on success, returns the number of bytes read from the file. - - On success, self->input_len will be 0; this is intentional so that when - unpickling from a file, the "we've run out of data" code paths will trigger, - causing the Unpickler to go back to the file for more data. Use the returned - size to tell you how much data you can process. */ -static Py_ssize_t -_Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n) -{ - PyObject *data; - Py_ssize_t read_size; - - assert(self->read != NULL); - - if (_Unpickler_SkipConsumed(self) < 0) - return -1; - - if (n == READ_WHOLE_LINE) { - data = PyObject_CallNoArgs(self->readline); - } - else { - PyObject *len; - /* Prefetch some data without advancing the file pointer, if possible */ - if (self->peek && n < PREFETCH) { - len = PyLong_FromSsize_t(PREFETCH); - if (len == NULL) - return -1; - data = _Pickle_FastCall(self->peek, len); - if (data == NULL) { - if (!PyErr_ExceptionMatches(PyExc_NotImplementedError)) - return -1; - /* peek() is probably not supported by the given file object */ - PyErr_Clear(); - Py_CLEAR(self->peek); - } - else { - read_size = _Unpickler_SetStringInput(self, data); - Py_DECREF(data); - self->prefetched_idx = 0; - if (n <= read_size) - return n; - } - } - len = PyLong_FromSsize_t(n); - if (len == NULL) - return -1; - data = _Pickle_FastCall(self->read, len); - } - if (data == NULL) - return -1; - - read_size = _Unpickler_SetStringInput(self, data); - Py_DECREF(data); - return read_size; -} - -/* Don't call it directly: use _Unpickler_Read() */ -static Py_ssize_t -_Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) -{ - Py_ssize_t num_read; - - *s = NULL; - if (self->next_read_idx > PY_SSIZE_T_MAX - n) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, - "read would overflow (invalid bytecode)"); - return -1; - } - - /* This case is handled by the _Unpickler_Read() macro for efficiency */ - assert(self->next_read_idx + n > self->input_len); - - if (!self->read) - return bad_readline(); - - /* Extend the buffer to satisfy desired size */ - num_read = _Unpickler_ReadFromFile(self, n); - if (num_read < 0) - return -1; - if (num_read < n) - return bad_readline(); - *s = self->input_buffer; - self->next_read_idx = n; - return n; -} - -/* Read `n` bytes from the unpickler's data source, storing the result in `buf`. - * - * This should only be used for non-small data reads where potentially - * avoiding a copy is beneficial. This method does not try to prefetch - * more data into the input buffer. - * - * _Unpickler_Read() is recommended in most cases. - */ -static Py_ssize_t -_Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) -{ - assert(n != READ_WHOLE_LINE); - - /* Read from available buffer data, if any */ - Py_ssize_t in_buffer = self->input_len - self->next_read_idx; - if (in_buffer > 0) { - Py_ssize_t to_read = Py_MIN(in_buffer, n); - memcpy(buf, self->input_buffer + self->next_read_idx, to_read); - self->next_read_idx += to_read; - buf += to_read; - n -= to_read; - if (n == 0) { - /* Entire read was satisfied from buffer */ - return n; - } - } - - /* Read from file */ - if (!self->read) { - /* We're unpickling memory, this means the input is truncated */ - return bad_readline(); - } - if (_Unpickler_SkipConsumed(self) < 0) { - return -1; - } - - if (!self->readinto) { - /* readinto() not supported on file-like object, fall back to read() - * and copy into destination buffer (bpo-39681) */ - PyObject* len = PyLong_FromSsize_t(n); - if (len == NULL) { - return -1; - } - PyObject* data = _Pickle_FastCall(self->read, len); - if (data == NULL) { - return -1; - } - if (!PyBytes_Check(data)) { - PyErr_Format(PyExc_ValueError, - "read() returned non-bytes object (%R)", - Py_TYPE(data)); - Py_DECREF(data); - return -1; - } - Py_ssize_t read_size = PyBytes_GET_SIZE(data); - if (read_size < n) { - Py_DECREF(data); - return bad_readline(); - } - memcpy(buf, PyBytes_AS_STRING(data), n); - Py_DECREF(data); - return n; - } - - /* Call readinto() into user buffer */ - PyObject *buf_obj = PyMemoryView_FromMemory(buf, n, PyBUF_WRITE); - if (buf_obj == NULL) { - return -1; - } - PyObject *read_size_obj = _Pickle_FastCall(self->readinto, buf_obj); - if (read_size_obj == NULL) { - return -1; - } - Py_ssize_t read_size = PyLong_AsSsize_t(read_size_obj); - Py_DECREF(read_size_obj); - - if (read_size < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "readinto() returned negative size"); - } - return -1; - } - if (read_size < n) { - return bad_readline(); - } - return n; -} - -/* Read `n` bytes from the unpickler's data source, storing the result in `*s`. - - This should be used for all data reads, rather than accessing the unpickler's - input buffer directly. This method deals correctly with reading from input - streams, which the input buffer doesn't deal with. - - Note that when reading from a file-like object, self->next_read_idx won't - be updated (it should remain at 0 for the entire unpickling process). You - should use this function's return value to know how many bytes you can - consume. - - Returns -1 (with an exception set) on failure. On success, return the - number of chars read. */ -#define _Unpickler_Read(self, s, n) \ - (((n) <= (self)->input_len - (self)->next_read_idx) \ - ? (*(s) = (self)->input_buffer + (self)->next_read_idx, \ - (self)->next_read_idx += (n), \ - (n)) \ - : _Unpickler_ReadImpl(self, (s), (n))) - -static Py_ssize_t -_Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len, - char **result) -{ - char *input_line = PyMem_Realloc(self->input_line, len + 1); - if (input_line == NULL) { - PyErr_NoMemory(); - return -1; - } - - memcpy(input_line, line, len); - input_line[len] = '\0'; - self->input_line = input_line; - *result = self->input_line; - return len; -} - -/* Read a line from the input stream/buffer. If we run off the end of the input - before hitting \n, raise an error. - - Returns the number of chars read, or -1 on failure. */ -static Py_ssize_t -_Unpickler_Readline(UnpicklerObject *self, char **result) -{ - Py_ssize_t i, num_read; - - for (i = self->next_read_idx; i < self->input_len; i++) { - if (self->input_buffer[i] == '\n') { - char *line_start = self->input_buffer + self->next_read_idx; - num_read = i - self->next_read_idx + 1; - self->next_read_idx = i + 1; - return _Unpickler_CopyLine(self, line_start, num_read, result); - } - } - if (!self->read) - return bad_readline(); - - num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE); - if (num_read < 0) - return -1; - if (num_read == 0 || self->input_buffer[num_read - 1] != '\n') - return bad_readline(); - self->next_read_idx = num_read; - return _Unpickler_CopyLine(self, self->input_buffer, num_read, result); -} - -/* Returns -1 (with an exception set) on failure, 0 on success. The memo array - will be modified in place. */ -static int -_Unpickler_ResizeMemoList(UnpicklerObject *self, size_t new_size) -{ - size_t i; - - assert(new_size > self->memo_size); - - PyObject **memo_new = self->memo; - PyMem_RESIZE(memo_new, PyObject *, new_size); - if (memo_new == NULL) { - PyErr_NoMemory(); - return -1; - } - self->memo = memo_new; - for (i = self->memo_size; i < new_size; i++) - self->memo[i] = NULL; - self->memo_size = new_size; - return 0; -} - -/* Returns NULL if idx is out of bounds. */ -static PyObject * -_Unpickler_MemoGet(UnpicklerObject *self, size_t idx) -{ - if (idx >= self->memo_size) - return NULL; - - return self->memo[idx]; -} - -/* Returns -1 (with an exception set) on failure, 0 on success. - This takes its own reference to `value`. */ -static int -_Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value) -{ - PyObject *old_item; - - if (idx >= self->memo_size) { - if (_Unpickler_ResizeMemoList(self, idx * 2) < 0) - return -1; - assert(idx < self->memo_size); - } - Py_INCREF(value); - old_item = self->memo[idx]; - self->memo[idx] = value; - if (old_item != NULL) { - Py_DECREF(old_item); - } - else { - self->memo_len++; - } - return 0; -} - -static PyObject ** -_Unpickler_NewMemo(Py_ssize_t new_size) -{ - PyObject **memo = PyMem_NEW(PyObject *, new_size); - if (memo == NULL) { - PyErr_NoMemory(); - return NULL; - } - memset(memo, 0, new_size * sizeof(PyObject *)); - return memo; -} - -/* Free the unpickler's memo, taking care to decref any items left in it. */ -static void -_Unpickler_MemoCleanup(UnpicklerObject *self) -{ - Py_ssize_t i; - PyObject **memo = self->memo; - - if (self->memo == NULL) - return; - self->memo = NULL; - i = self->memo_size; - while (--i >= 0) { - Py_XDECREF(memo[i]); - } - PyMem_FREE(memo); -} - -static UnpicklerObject * -_Unpickler_New(void) -{ - UnpicklerObject *self; - - self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type); - if (self == NULL) - return NULL; - - self->pers_func = NULL; - self->input_buffer = NULL; - self->input_line = NULL; - self->input_len = 0; - self->next_read_idx = 0; - self->prefetched_idx = 0; - self->read = NULL; - self->readinto = NULL; - self->readline = NULL; - self->peek = NULL; - self->buffers = NULL; - self->encoding = NULL; - self->errors = NULL; - self->marks = NULL; - self->num_marks = 0; - self->marks_size = 0; - self->proto = 0; - self->fix_imports = 0; - memset(&self->buffer, 0, sizeof(Py_buffer)); - self->memo_size = 32; - self->memo_len = 0; - self->memo = _Unpickler_NewMemo(self->memo_size); - self->stack = (Pdata *)Pdata_New(); - - if (self->memo == NULL || self->stack == NULL) { - Py_DECREF(self); - return NULL; - } - - PyObject_GC_Track(self); - return self; -} - -/* Returns -1 (with an exception set) on failure, 0 on success. This may - be called once on a freshly created Unpickler. */ -static int -_Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) -{ - _Py_IDENTIFIER(peek); - _Py_IDENTIFIER(read); - _Py_IDENTIFIER(readinto); - _Py_IDENTIFIER(readline); - - /* Optional file methods */ - if (_PyObject_LookupAttrId(file, &PyId_peek, &self->peek) < 0) { - return -1; - } - if (_PyObject_LookupAttrId(file, &PyId_readinto, &self->readinto) < 0) { - return -1; - } - (void)_PyObject_LookupAttrId(file, &PyId_read, &self->read); - (void)_PyObject_LookupAttrId(file, &PyId_readline, &self->readline); - if (!self->readline || !self->read) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "file must have 'read' and 'readline' attributes"); - } - Py_CLEAR(self->read); - Py_CLEAR(self->readinto); - Py_CLEAR(self->readline); - Py_CLEAR(self->peek); - return -1; - } - return 0; -} - -/* Returns -1 (with an exception set) on failure, 0 on success. This may - be called once on a freshly created Unpickler. */ -static int -_Unpickler_SetInputEncoding(UnpicklerObject *self, - const char *encoding, - const char *errors) -{ - if (encoding == NULL) - encoding = "ASCII"; - if (errors == NULL) - errors = "strict"; - - self->encoding = _PyMem_Strdup(encoding); - self->errors = _PyMem_Strdup(errors); - if (self->encoding == NULL || self->errors == NULL) { - PyErr_NoMemory(); - return -1; - } - return 0; -} - -/* Returns -1 (with an exception set) on failure, 0 on success. This may - be called once on a freshly created Unpickler. */ -static int -_Unpickler_SetBuffers(UnpicklerObject *self, PyObject *buffers) -{ - if (buffers == NULL || buffers == Py_None) { - self->buffers = NULL; - } - else { - self->buffers = PyObject_GetIter(buffers); - if (self->buffers == NULL) { - return -1; - } - } - return 0; -} - -/* Generate a GET opcode for an object stored in the memo. */ -static int -memo_get(PicklerObject *self, PyObject *key) -{ - Py_ssize_t *value; - char pdata[30]; - Py_ssize_t len; - - value = PyMemoTable_Get(self->memo, key); - if (value == NULL) { - PyErr_SetObject(PyExc_KeyError, key); - return -1; - } - - if (!self->bin) { - pdata[0] = GET; - PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, - "%" PY_FORMAT_SIZE_T "d\n", *value); - len = strlen(pdata); - } - else { - if (*value < 256) { - pdata[0] = BINGET; - pdata[1] = (unsigned char)(*value & 0xff); - len = 2; - } - else if ((size_t)*value <= 0xffffffffUL) { - pdata[0] = LONG_BINGET; - pdata[1] = (unsigned char)(*value & 0xff); - pdata[2] = (unsigned char)((*value >> 8) & 0xff); - pdata[3] = (unsigned char)((*value >> 16) & 0xff); - pdata[4] = (unsigned char)((*value >> 24) & 0xff); - len = 5; - } - else { /* unlikely */ - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->PicklingError, - "memo id too large for LONG_BINGET"); - return -1; - } - } - - if (_Pickler_Write(self, pdata, len) < 0) - return -1; - - return 0; -} - -/* Store an object in the memo, assign it a new unique ID based on the number - of objects currently stored in the memo and generate a PUT opcode. */ -static int -memo_put(PicklerObject *self, PyObject *obj) -{ - char pdata[30]; - Py_ssize_t len; - Py_ssize_t idx; - - const char memoize_op = MEMOIZE; - - if (self->fast) - return 0; - - idx = PyMemoTable_Size(self->memo); - if (PyMemoTable_Set(self->memo, obj, idx) < 0) - return -1; - - if (self->proto >= 4) { - if (_Pickler_Write(self, &memoize_op, 1) < 0) - return -1; - return 0; - } - else if (!self->bin) { - pdata[0] = PUT; - PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, - "%" PY_FORMAT_SIZE_T "d\n", idx); - len = strlen(pdata); - } - else { - if (idx < 256) { - pdata[0] = BINPUT; - pdata[1] = (unsigned char)idx; - len = 2; - } - else if ((size_t)idx <= 0xffffffffUL) { - pdata[0] = LONG_BINPUT; - pdata[1] = (unsigned char)(idx & 0xff); - pdata[2] = (unsigned char)((idx >> 8) & 0xff); - pdata[3] = (unsigned char)((idx >> 16) & 0xff); - pdata[4] = (unsigned char)((idx >> 24) & 0xff); - len = 5; - } - else { /* unlikely */ - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->PicklingError, - "memo id too large for LONG_BINPUT"); - return -1; - } - } - if (_Pickler_Write(self, pdata, len) < 0) - return -1; - - return 0; -} - -static PyObject * -get_dotted_path(PyObject *obj, PyObject *name) -{ - _Py_static_string(PyId_dot, "."); - PyObject *dotted_path; - Py_ssize_t i, n; - - dotted_path = PyUnicode_Split(name, _PyUnicode_FromId(&PyId_dot), -1); - if (dotted_path == NULL) - return NULL; - n = PyList_GET_SIZE(dotted_path); - assert(n >= 1); - for (i = 0; i < n; i++) { - PyObject *subpath = PyList_GET_ITEM(dotted_path, i); - if (_PyUnicode_EqualToASCIIString(subpath, "")) { - if (obj == NULL) - PyErr_Format(PyExc_AttributeError, - "Can't pickle local object %R", name); - else - PyErr_Format(PyExc_AttributeError, - "Can't pickle local attribute %R on %R", name, obj); - Py_DECREF(dotted_path); - return NULL; - } - } - return dotted_path; -} - -static PyObject * -get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent) -{ - Py_ssize_t i, n; - PyObject *parent = NULL; - - assert(PyList_CheckExact(names)); - Py_INCREF(obj); - n = PyList_GET_SIZE(names); - for (i = 0; i < n; i++) { - PyObject *name = PyList_GET_ITEM(names, i); - Py_XDECREF(parent); - parent = obj; - (void)_PyObject_LookupAttr(parent, name, &obj); - if (obj == NULL) { - Py_DECREF(parent); - return NULL; - } - } - if (pparent != NULL) - *pparent = parent; - else - Py_XDECREF(parent); - return obj; -} - - -static PyObject * -getattribute(PyObject *obj, PyObject *name, int allow_qualname) -{ - PyObject *dotted_path, *attr; - - if (allow_qualname) { - dotted_path = get_dotted_path(obj, name); - if (dotted_path == NULL) - return NULL; - attr = get_deep_attribute(obj, dotted_path, NULL); - Py_DECREF(dotted_path); - } - else { - (void)_PyObject_LookupAttr(obj, name, &attr); - } - if (attr == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_AttributeError, - "Can't get attribute %R on %R", name, obj); - } - return attr; -} - -static int -_checkmodule(PyObject *module_name, PyObject *module, - PyObject *global, PyObject *dotted_path) -{ - if (module == Py_None) { - return -1; - } - if (PyUnicode_Check(module_name) && - _PyUnicode_EqualToASCIIString(module_name, "__main__")) { - return -1; - } - - PyObject *candidate = get_deep_attribute(module, dotted_path, NULL); - if (candidate == NULL) { - return -1; - } - if (candidate != global) { - Py_DECREF(candidate); - return -1; - } - Py_DECREF(candidate); - return 0; -} - -static PyObject * -whichmodule(PyObject *global, PyObject *dotted_path) -{ - PyObject *module_name; - PyObject *module = NULL; - Py_ssize_t i; - PyObject *modules; - _Py_IDENTIFIER(__module__); - _Py_IDENTIFIER(modules); - _Py_IDENTIFIER(__main__); - - if (_PyObject_LookupAttrId(global, &PyId___module__, &module_name) < 0) { - return NULL; - } - if (module_name) { - /* In some rare cases (e.g., bound methods of extension types), - __module__ can be None. If it is so, then search sys.modules for - the module of global. */ - if (module_name != Py_None) - return module_name; - Py_CLEAR(module_name); - } - assert(module_name == NULL); - - /* Fallback on walking sys.modules */ - modules = _PySys_GetObjectId(&PyId_modules); - if (modules == NULL) { - PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); - return NULL; - } - if (PyDict_CheckExact(modules)) { - i = 0; - while (PyDict_Next(modules, &i, &module_name, &module)) { - if (_checkmodule(module_name, module, global, dotted_path) == 0) { - Py_INCREF(module_name); - return module_name; - } - if (PyErr_Occurred()) { - return NULL; - } - } - } - else { - PyObject *iterator = PyObject_GetIter(modules); - if (iterator == NULL) { - return NULL; - } - while ((module_name = PyIter_Next(iterator))) { - module = PyObject_GetItem(modules, module_name); - if (module == NULL) { - Py_DECREF(module_name); - Py_DECREF(iterator); - return NULL; - } - if (_checkmodule(module_name, module, global, dotted_path) == 0) { - Py_DECREF(module); - Py_DECREF(iterator); - return module_name; - } - Py_DECREF(module); - Py_DECREF(module_name); - if (PyErr_Occurred()) { - Py_DECREF(iterator); - return NULL; - } - } - Py_DECREF(iterator); - } - - /* If no module is found, use __main__. */ - module_name = _PyUnicode_FromId(&PyId___main__); - Py_XINCREF(module_name); - return module_name; -} - -/* fast_save_enter() and fast_save_leave() are guards against recursive - objects when Pickler is used with the "fast mode" (i.e., with object - memoization disabled). If the nesting of a list or dict object exceed - FAST_NESTING_LIMIT, these guards will start keeping an internal - reference to the seen list or dict objects and check whether these objects - are recursive. These are not strictly necessary, since save() has a - hard-coded recursion limit, but they give a nicer error message than the - typical RuntimeError. */ -static int -fast_save_enter(PicklerObject *self, PyObject *obj) -{ - /* if fast_nesting < 0, we're doing an error exit. */ - if (++self->fast_nesting >= FAST_NESTING_LIMIT) { - PyObject *key = NULL; - if (self->fast_memo == NULL) { - self->fast_memo = PyDict_New(); - if (self->fast_memo == NULL) { - self->fast_nesting = -1; - return 0; - } - } - key = PyLong_FromVoidPtr(obj); - if (key == NULL) { - self->fast_nesting = -1; - return 0; - } - if (PyDict_GetItemWithError(self->fast_memo, key)) { - Py_DECREF(key); - PyErr_Format(PyExc_ValueError, - "fast mode: can't pickle cyclic objects " - "including object type %.200s at %p", - Py_TYPE(obj)->tp_name, obj); - self->fast_nesting = -1; - return 0; - } - if (PyErr_Occurred()) { - Py_DECREF(key); - self->fast_nesting = -1; - return 0; - } - if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) { - Py_DECREF(key); - self->fast_nesting = -1; - return 0; - } - Py_DECREF(key); - } - return 1; -} - -static int -fast_save_leave(PicklerObject *self, PyObject *obj) -{ - if (self->fast_nesting-- >= FAST_NESTING_LIMIT) { - PyObject *key = PyLong_FromVoidPtr(obj); - if (key == NULL) - return 0; - if (PyDict_DelItem(self->fast_memo, key) < 0) { - Py_DECREF(key); - return 0; - } - Py_DECREF(key); - } - return 1; -} - -static int -save_none(PicklerObject *self, PyObject *obj) -{ - const char none_op = NONE; - if (_Pickler_Write(self, &none_op, 1) < 0) - return -1; - - return 0; -} - -static int -save_bool(PicklerObject *self, PyObject *obj) -{ - if (self->proto >= 2) { - const char bool_op = (obj == Py_True) ? NEWTRUE : NEWFALSE; - if (_Pickler_Write(self, &bool_op, 1) < 0) - return -1; - } - else { - /* These aren't opcodes -- they're ways to pickle bools before protocol 2 - * so that unpicklers written before bools were introduced unpickle them - * as ints, but unpicklers after can recognize that bools were intended. - * Note that protocol 2 added direct ways to pickle bools. - */ - const char *bool_str = (obj == Py_True) ? "I01\n" : "I00\n"; - if (_Pickler_Write(self, bool_str, strlen(bool_str)) < 0) - return -1; - } - return 0; -} - -static int -save_long(PicklerObject *self, PyObject *obj) -{ - PyObject *repr = NULL; - Py_ssize_t size; - long val; - int overflow; - int status = 0; - - val= PyLong_AsLongAndOverflow(obj, &overflow); - if (!overflow && (sizeof(long) <= 4 || - (val <= 0x7fffffffL && val >= (-0x7fffffffL - 1)))) - { - /* result fits in a signed 4-byte integer. - - Note: we can't use -0x80000000L in the above condition because some - compilers (e.g., MSVC) will promote 0x80000000L to an unsigned type - before applying the unary minus when sizeof(long) <= 4. The - resulting value stays unsigned which is commonly not what we want, - so MSVC happily warns us about it. However, that result would have - been fine because we guard for sizeof(long) <= 4 which turns the - condition true in that particular case. */ - char pdata[32]; - Py_ssize_t len = 0; - - if (self->bin) { - pdata[1] = (unsigned char)(val & 0xff); - pdata[2] = (unsigned char)((val >> 8) & 0xff); - pdata[3] = (unsigned char)((val >> 16) & 0xff); - pdata[4] = (unsigned char)((val >> 24) & 0xff); - - if ((pdata[4] != 0) || (pdata[3] != 0)) { - pdata[0] = BININT; - len = 5; - } - else if (pdata[2] != 0) { - pdata[0] = BININT2; - len = 3; - } - else { - pdata[0] = BININT1; - len = 2; - } - } - else { - sprintf(pdata, "%c%ld\n", INT_, val); - len = strlen(pdata); - } - if (_Pickler_Write(self, pdata, len) < 0) - return -1; - - return 0; - } - assert(!PyErr_Occurred()); - - if (self->proto >= 2) { - /* Linear-time pickling. */ - size_t nbits; - size_t nbytes; - unsigned char *pdata; - char header[5]; - int i; - int sign = _PyLong_Sign(obj); - - if (sign == 0) { - header[0] = LONG1; - header[1] = 0; /* It's 0 -- an empty bytestring. */ - if (_Pickler_Write(self, header, 2) < 0) - goto error; - return 0; - } - nbits = _PyLong_NumBits(obj); - if (nbits == (size_t)-1 && PyErr_Occurred()) - goto error; - /* How many bytes do we need? There are nbits >> 3 full - * bytes of data, and nbits & 7 leftover bits. If there - * are any leftover bits, then we clearly need another - * byte. What's not so obvious is that we *probably* - * need another byte even if there aren't any leftovers: - * the most-significant bit of the most-significant byte - * acts like a sign bit, and it's usually got a sense - * opposite of the one we need. The exception is ints - * of the form -(2**(8*j-1)) for j > 0. Such an int is - * its own 256's-complement, so has the right sign bit - * even without the extra byte. That's a pain to check - * for in advance, though, so we always grab an extra - * byte at the start, and cut it back later if possible. - */ - nbytes = (nbits >> 3) + 1; - if (nbytes > 0x7fffffffL) { - PyErr_SetString(PyExc_OverflowError, - "int too large to pickle"); - goto error; - } - repr = PyBytes_FromStringAndSize(NULL, (Py_ssize_t)nbytes); - if (repr == NULL) - goto error; - pdata = (unsigned char *)PyBytes_AS_STRING(repr); - i = _PyLong_AsByteArray((PyLongObject *)obj, - pdata, nbytes, - 1 /* little endian */ , 1 /* signed */ ); - if (i < 0) - goto error; - /* If the int is negative, this may be a byte more than - * needed. This is so iff the MSB is all redundant sign - * bits. - */ - if (sign < 0 && - nbytes > 1 && - pdata[nbytes - 1] == 0xff && - (pdata[nbytes - 2] & 0x80) != 0) { - nbytes--; - } - - if (nbytes < 256) { - header[0] = LONG1; - header[1] = (unsigned char)nbytes; - size = 2; - } - else { - header[0] = LONG4; - size = (Py_ssize_t) nbytes; - for (i = 1; i < 5; i++) { - header[i] = (unsigned char)(size & 0xff); - size >>= 8; - } - size = 5; - } - if (_Pickler_Write(self, header, size) < 0 || - _Pickler_Write(self, (char *)pdata, (int)nbytes) < 0) - goto error; - } - else { - const char long_op = LONG_; - const char *string; - - /* proto < 2: write the repr and newline. This is quadratic-time (in - the number of digits), in both directions. We add a trailing 'L' - to the repr, for compatibility with Python 2.x. */ - - repr = PyObject_Repr(obj); - if (repr == NULL) - goto error; - - string = PyUnicode_AsUTF8AndSize(repr, &size); - if (string == NULL) - goto error; - - if (_Pickler_Write(self, &long_op, 1) < 0 || - _Pickler_Write(self, string, size) < 0 || - _Pickler_Write(self, "L\n", 2) < 0) - goto error; - } - - if (0) { - error: - status = -1; - } - Py_XDECREF(repr); - - return status; -} - -static int -save_float(PicklerObject *self, PyObject *obj) -{ - double x = PyFloat_AS_DOUBLE((PyFloatObject *)obj); - - if (self->bin) { - char pdata[9]; - pdata[0] = BINFLOAT; - if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0) - return -1; - if (_Pickler_Write(self, pdata, 9) < 0) - return -1; - } - else { - int result = -1; - char *buf = NULL; - char op = FLOAT_; - - if (_Pickler_Write(self, &op, 1) < 0) - goto done; - - buf = PyOS_double_to_string(x, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); - if (!buf) { - PyErr_NoMemory(); - goto done; - } - - if (_Pickler_Write(self, buf, strlen(buf)) < 0) - goto done; - - if (_Pickler_Write(self, "\n", 1) < 0) - goto done; - - result = 0; -done: - PyMem_Free(buf); - return result; - } - - return 0; -} - -/* Perform direct write of the header and payload of the binary object. - - The large contiguous data is written directly into the underlying file - object, bypassing the output_buffer of the Pickler. We intentionally - do not insert a protocol 4 frame opcode to make it possible to optimize - file.read calls in the loader. - */ -static int -_Pickler_write_bytes(PicklerObject *self, - const char *header, Py_ssize_t header_size, - const char *data, Py_ssize_t data_size, - PyObject *payload) -{ - int bypass_buffer = (data_size >= FRAME_SIZE_TARGET); - int framing = self->framing; - - if (bypass_buffer) { - assert(self->output_buffer != NULL); - /* Commit the previous frame. */ - if (_Pickler_CommitFrame(self)) { - return -1; - } - /* Disable framing temporarily */ - self->framing = 0; - } - - if (_Pickler_Write(self, header, header_size) < 0) { - return -1; - } - - if (bypass_buffer && self->write != NULL) { - /* Bypass the in-memory buffer to directly stream large data - into the underlying file object. */ - PyObject *result, *mem = NULL; - /* Dump the output buffer to the file. */ - if (_Pickler_FlushToFile(self) < 0) { - return -1; - } - - /* Stream write the payload into the file without going through the - output buffer. */ - if (payload == NULL) { - /* TODO: It would be better to use a memoryview with a linked - original string if this is possible. */ - payload = mem = PyBytes_FromStringAndSize(data, data_size); - if (payload == NULL) { - return -1; - } - } - result = PyObject_CallOneArg(self->write, payload); - Py_XDECREF(mem); - if (result == NULL) { - return -1; - } - Py_DECREF(result); - - /* Reinitialize the buffer for subsequent calls to _Pickler_Write. */ - if (_Pickler_ClearBuffer(self) < 0) { - return -1; - } - } - else { - if (_Pickler_Write(self, data, data_size) < 0) { - return -1; - } - } - - /* Re-enable framing for subsequent calls to _Pickler_Write. */ - self->framing = framing; - - return 0; -} - -static int -_save_bytes_data(PicklerObject *self, PyObject *obj, const char *data, - Py_ssize_t size) -{ - assert(self->proto >= 3); - - char header[9]; - Py_ssize_t len; - - if (size < 0) - return -1; - - if (size <= 0xff) { - header[0] = SHORT_BINBYTES; - header[1] = (unsigned char)size; - len = 2; - } - else if ((size_t)size <= 0xffffffffUL) { - header[0] = BINBYTES; - header[1] = (unsigned char)(size & 0xff); - header[2] = (unsigned char)((size >> 8) & 0xff); - header[3] = (unsigned char)((size >> 16) & 0xff); - header[4] = (unsigned char)((size >> 24) & 0xff); - len = 5; - } - else if (self->proto >= 4) { - header[0] = BINBYTES8; - _write_size64(header + 1, size); - len = 9; - } - else { - PyErr_SetString(PyExc_OverflowError, - "serializing a bytes object larger than 4 GiB " - "requires pickle protocol 4 or higher"); - return -1; - } - - if (_Pickler_write_bytes(self, header, len, data, size, obj) < 0) { - return -1; - } - - if (memo_put(self, obj) < 0) { - return -1; - } - - return 0; -} - -static int -save_bytes(PicklerObject *self, PyObject *obj) -{ - if (self->proto < 3) { - /* Older pickle protocols do not have an opcode for pickling bytes - objects. Therefore, we need to fake the copy protocol (i.e., - the __reduce__ method) to permit bytes object unpickling. - - Here we use a hack to be compatible with Python 2. Since in Python - 2 'bytes' is just an alias for 'str' (which has different - parameters than the actual bytes object), we use codecs.encode - to create the appropriate 'str' object when unpickled using - Python 2 *and* the appropriate 'bytes' object when unpickled - using Python 3. Again this is a hack and we don't need to do this - with newer protocols. */ - PyObject *reduce_value; - int status; - - if (PyBytes_GET_SIZE(obj) == 0) { - reduce_value = Py_BuildValue("(O())", (PyObject*)&PyBytes_Type); - } - else { - PickleState *st = _Pickle_GetGlobalState(); - PyObject *unicode_str = - PyUnicode_DecodeLatin1(PyBytes_AS_STRING(obj), - PyBytes_GET_SIZE(obj), - "strict"); - _Py_IDENTIFIER(latin1); - - if (unicode_str == NULL) - return -1; - reduce_value = Py_BuildValue("(O(OO))", - st->codecs_encode, unicode_str, - _PyUnicode_FromId(&PyId_latin1)); - Py_DECREF(unicode_str); - } - - if (reduce_value == NULL) - return -1; - - /* save_reduce() will memoize the object automatically. */ - status = save_reduce(self, reduce_value, obj); - Py_DECREF(reduce_value); - return status; - } - else { - return _save_bytes_data(self, obj, PyBytes_AS_STRING(obj), - PyBytes_GET_SIZE(obj)); - } -} - -static int -_save_bytearray_data(PicklerObject *self, PyObject *obj, const char *data, - Py_ssize_t size) -{ - assert(self->proto >= 5); - - char header[9]; - Py_ssize_t len; - - if (size < 0) - return -1; - - header[0] = BYTEARRAY8; - _write_size64(header + 1, size); - len = 9; - - if (_Pickler_write_bytes(self, header, len, data, size, obj) < 0) { - return -1; - } - - if (memo_put(self, obj) < 0) { - return -1; - } - - return 0; -} - -static int -save_bytearray(PicklerObject *self, PyObject *obj) -{ - if (self->proto < 5) { - /* Older pickle protocols do not have an opcode for pickling - * bytearrays. */ - PyObject *reduce_value = NULL; - int status; - - if (PyByteArray_GET_SIZE(obj) == 0) { - reduce_value = Py_BuildValue("(O())", - (PyObject *) &PyByteArray_Type); - } - else { - PyObject *bytes_obj = PyBytes_FromObject(obj); - if (bytes_obj != NULL) { - reduce_value = Py_BuildValue("(O(O))", - (PyObject *) &PyByteArray_Type, - bytes_obj); - Py_DECREF(bytes_obj); - } - } - if (reduce_value == NULL) - return -1; - - /* save_reduce() will memoize the object automatically. */ - status = save_reduce(self, reduce_value, obj); - Py_DECREF(reduce_value); - return status; - } - else { - return _save_bytearray_data(self, obj, PyByteArray_AS_STRING(obj), - PyByteArray_GET_SIZE(obj)); - } -} - -static int -save_picklebuffer(PicklerObject *self, PyObject *obj) -{ - if (self->proto < 5) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->PicklingError, - "PickleBuffer can only pickled with protocol >= 5"); - return -1; - } - const Py_buffer* view = PyPickleBuffer_GetBuffer(obj); - if (view == NULL) { - return -1; - } - if (view->suboffsets != NULL || !PyBuffer_IsContiguous(view, 'A')) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->PicklingError, - "PickleBuffer can not be pickled when " - "pointing to a non-contiguous buffer"); - return -1; - } - int in_band = 1; - if (self->buffer_callback != NULL) { - PyObject *ret = PyObject_CallOneArg(self->buffer_callback, obj); - if (ret == NULL) { - return -1; - } - in_band = PyObject_IsTrue(ret); - Py_DECREF(ret); - if (in_band == -1) { - return -1; - } - } - if (in_band) { - /* Write data in-band */ - if (view->readonly) { - return _save_bytes_data(self, obj, (const char*) view->buf, - view->len); - } - else { - return _save_bytearray_data(self, obj, (const char*) view->buf, - view->len); - } - } - else { - /* Write data out-of-band */ - const char next_buffer_op = NEXT_BUFFER; - if (_Pickler_Write(self, &next_buffer_op, 1) < 0) { - return -1; - } - if (view->readonly) { - const char readonly_buffer_op = READONLY_BUFFER; - if (_Pickler_Write(self, &readonly_buffer_op, 1) < 0) { - return -1; - } - } - } - return 0; -} - -/* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates - backslash and newline characters to \uXXXX escapes. */ -static PyObject * -raw_unicode_escape(PyObject *obj) -{ - char *p; - Py_ssize_t i, size; - const void *data; - unsigned int kind; - _PyBytesWriter writer; - - if (PyUnicode_READY(obj)) - return NULL; - - _PyBytesWriter_Init(&writer); - - size = PyUnicode_GET_LENGTH(obj); - data = PyUnicode_DATA(obj); - kind = PyUnicode_KIND(obj); - - p = _PyBytesWriter_Alloc(&writer, size); - if (p == NULL) - goto error; - writer.overallocate = 1; - - for (i=0; i < size; i++) { - Py_UCS4 ch = PyUnicode_READ(kind, data, i); - /* Map 32-bit characters to '\Uxxxxxxxx' */ - if (ch >= 0x10000) { - /* -1: subtract 1 preallocated byte */ - p = _PyBytesWriter_Prepare(&writer, p, 10-1); - if (p == NULL) - goto error; - - *p++ = '\\'; - *p++ = 'U'; - *p++ = Py_hexdigits[(ch >> 28) & 0xf]; - *p++ = Py_hexdigits[(ch >> 24) & 0xf]; - *p++ = Py_hexdigits[(ch >> 20) & 0xf]; - *p++ = Py_hexdigits[(ch >> 16) & 0xf]; - *p++ = Py_hexdigits[(ch >> 12) & 0xf]; - *p++ = Py_hexdigits[(ch >> 8) & 0xf]; - *p++ = Py_hexdigits[(ch >> 4) & 0xf]; - *p++ = Py_hexdigits[ch & 15]; - } - /* Map 16-bit characters, '\\' and '\n' to '\uxxxx' */ - else if (ch >= 256 || - ch == '\\' || ch == 0 || ch == '\n' || ch == '\r' || - ch == 0x1a) - { - /* -1: subtract 1 preallocated byte */ - p = _PyBytesWriter_Prepare(&writer, p, 6-1); - if (p == NULL) - goto error; - - *p++ = '\\'; - *p++ = 'u'; - *p++ = Py_hexdigits[(ch >> 12) & 0xf]; - *p++ = Py_hexdigits[(ch >> 8) & 0xf]; - *p++ = Py_hexdigits[(ch >> 4) & 0xf]; - *p++ = Py_hexdigits[ch & 15]; - } - /* Copy everything else as-is */ - else - *p++ = (char) ch; - } - - return _PyBytesWriter_Finish(&writer, p); - -error: - _PyBytesWriter_Dealloc(&writer); - return NULL; -} - -static int -write_unicode_binary(PicklerObject *self, PyObject *obj) -{ - char header[9]; - Py_ssize_t len; - PyObject *encoded = NULL; - Py_ssize_t size; - const char *data; - - if (PyUnicode_READY(obj)) - return -1; - - data = PyUnicode_AsUTF8AndSize(obj, &size); - if (data == NULL) { - /* Issue #8383: for strings with lone surrogates, fallback on the - "surrogatepass" error handler. */ - PyErr_Clear(); - encoded = PyUnicode_AsEncodedString(obj, "utf-8", "surrogatepass"); - if (encoded == NULL) - return -1; - - data = PyBytes_AS_STRING(encoded); - size = PyBytes_GET_SIZE(encoded); - } - - assert(size >= 0); - if (size <= 0xff && self->proto >= 4) { - header[0] = SHORT_BINUNICODE; - header[1] = (unsigned char)(size & 0xff); - len = 2; - } - else if ((size_t)size <= 0xffffffffUL) { - header[0] = BINUNICODE; - header[1] = (unsigned char)(size & 0xff); - header[2] = (unsigned char)((size >> 8) & 0xff); - header[3] = (unsigned char)((size >> 16) & 0xff); - header[4] = (unsigned char)((size >> 24) & 0xff); - len = 5; - } - else if (self->proto >= 4) { - header[0] = BINUNICODE8; - _write_size64(header + 1, size); - len = 9; - } - else { - PyErr_SetString(PyExc_OverflowError, - "serializing a string larger than 4 GiB " - "requires pickle protocol 4 or higher"); - Py_XDECREF(encoded); - return -1; - } - - if (_Pickler_write_bytes(self, header, len, data, size, encoded) < 0) { - Py_XDECREF(encoded); - return -1; - } - Py_XDECREF(encoded); - return 0; -} - -static int -save_unicode(PicklerObject *self, PyObject *obj) -{ - if (self->bin) { - if (write_unicode_binary(self, obj) < 0) - return -1; - } - else { - PyObject *encoded; - Py_ssize_t size; - const char unicode_op = UNICODE; - - encoded = raw_unicode_escape(obj); - if (encoded == NULL) - return -1; - - if (_Pickler_Write(self, &unicode_op, 1) < 0) { - Py_DECREF(encoded); - return -1; - } - - size = PyBytes_GET_SIZE(encoded); - if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), size) < 0) { - Py_DECREF(encoded); - return -1; - } - Py_DECREF(encoded); - - if (_Pickler_Write(self, "\n", 1) < 0) - return -1; - } - if (memo_put(self, obj) < 0) - return -1; - - return 0; -} - -/* A helper for save_tuple. Push the len elements in tuple t on the stack. */ -static int -store_tuple_elements(PicklerObject *self, PyObject *t, Py_ssize_t len) -{ - Py_ssize_t i; - - assert(PyTuple_Size(t) == len); - - for (i = 0; i < len; i++) { - PyObject *element = PyTuple_GET_ITEM(t, i); - - if (element == NULL) - return -1; - if (save(self, element, 0) < 0) - return -1; - } - - return 0; -} - -/* Tuples are ubiquitous in the pickle protocols, so many techniques are - * used across protocols to minimize the space needed to pickle them. - * Tuples are also the only builtin immutable type that can be recursive - * (a tuple can be reached from itself), and that requires some subtle - * magic so that it works in all cases. IOW, this is a long routine. - */ -static int -save_tuple(PicklerObject *self, PyObject *obj) -{ - Py_ssize_t len, i; - - const char mark_op = MARK; - const char tuple_op = TUPLE; - const char pop_op = POP; - const char pop_mark_op = POP_MARK; - const char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3}; - - if ((len = PyTuple_Size(obj)) < 0) - return -1; - - if (len == 0) { - char pdata[2]; - - if (self->proto) { - pdata[0] = EMPTY_TUPLE; - len = 1; - } - else { - pdata[0] = MARK; - pdata[1] = TUPLE; - len = 2; - } - if (_Pickler_Write(self, pdata, len) < 0) - return -1; - return 0; - } - - /* The tuple isn't in the memo now. If it shows up there after - * saving the tuple elements, the tuple must be recursive, in - * which case we'll pop everything we put on the stack, and fetch - * its value from the memo. - */ - if (len <= 3 && self->proto >= 2) { - /* Use TUPLE{1,2,3} opcodes. */ - if (store_tuple_elements(self, obj, len) < 0) - return -1; - - if (PyMemoTable_Get(self->memo, obj)) { - /* pop the len elements */ - for (i = 0; i < len; i++) - if (_Pickler_Write(self, &pop_op, 1) < 0) - return -1; - /* fetch from memo */ - if (memo_get(self, obj) < 0) - return -1; - - return 0; - } - else { /* Not recursive. */ - if (_Pickler_Write(self, len2opcode + len, 1) < 0) - return -1; - } - goto memoize; - } - - /* proto < 2 and len > 0, or proto >= 2 and len > 3. - * Generate MARK e1 e2 ... TUPLE - */ - if (_Pickler_Write(self, &mark_op, 1) < 0) - return -1; - - if (store_tuple_elements(self, obj, len) < 0) - return -1; - - if (PyMemoTable_Get(self->memo, obj)) { - /* pop the stack stuff we pushed */ - if (self->bin) { - if (_Pickler_Write(self, &pop_mark_op, 1) < 0) - return -1; - } - else { - /* Note that we pop one more than len, to remove - * the MARK too. - */ - for (i = 0; i <= len; i++) - if (_Pickler_Write(self, &pop_op, 1) < 0) - return -1; - } - /* fetch from memo */ - if (memo_get(self, obj) < 0) - return -1; - - return 0; - } - else { /* Not recursive. */ - if (_Pickler_Write(self, &tuple_op, 1) < 0) - return -1; - } - - memoize: - if (memo_put(self, obj) < 0) - return -1; - - return 0; -} - -/* iter is an iterator giving items, and we batch up chunks of - * MARK item item ... item APPENDS - * opcode sequences. Calling code should have arranged to first create an - * empty list, or list-like object, for the APPENDS to operate on. - * Returns 0 on success, <0 on error. - */ -static int -batch_list(PicklerObject *self, PyObject *iter) -{ - PyObject *obj = NULL; - PyObject *firstitem = NULL; - int i, n; - - const char mark_op = MARK; - const char append_op = APPEND; - const char appends_op = APPENDS; - - assert(iter != NULL); - - /* XXX: I think this function could be made faster by avoiding the - iterator interface and fetching objects directly from list using - PyList_GET_ITEM. - */ - - if (self->proto == 0) { - /* APPENDS isn't available; do one at a time. */ - for (;;) { - obj = PyIter_Next(iter); - if (obj == NULL) { - if (PyErr_Occurred()) - return -1; - break; - } - i = save(self, obj, 0); - Py_DECREF(obj); - if (i < 0) - return -1; - if (_Pickler_Write(self, &append_op, 1) < 0) - return -1; - } - return 0; - } - - /* proto > 0: write in batches of BATCHSIZE. */ - do { - /* Get first item */ - firstitem = PyIter_Next(iter); - if (firstitem == NULL) { - if (PyErr_Occurred()) - goto error; - - /* nothing more to add */ - break; - } - - /* Try to get a second item */ - obj = PyIter_Next(iter); - if (obj == NULL) { - if (PyErr_Occurred()) - goto error; - - /* Only one item to write */ - if (save(self, firstitem, 0) < 0) - goto error; - if (_Pickler_Write(self, &append_op, 1) < 0) - goto error; - Py_CLEAR(firstitem); - break; - } - - /* More than one item to write */ - - /* Pump out MARK, items, APPENDS. */ - if (_Pickler_Write(self, &mark_op, 1) < 0) - goto error; - - if (save(self, firstitem, 0) < 0) - goto error; - Py_CLEAR(firstitem); - n = 1; - - /* Fetch and save up to BATCHSIZE items */ - while (obj) { - if (save(self, obj, 0) < 0) - goto error; - Py_CLEAR(obj); - n += 1; - - if (n == BATCHSIZE) - break; - - obj = PyIter_Next(iter); - if (obj == NULL) { - if (PyErr_Occurred()) - goto error; - break; - } - } - - if (_Pickler_Write(self, &appends_op, 1) < 0) - goto error; - - } while (n == BATCHSIZE); - return 0; - - error: - Py_XDECREF(firstitem); - Py_XDECREF(obj); - return -1; -} - -/* This is a variant of batch_list() above, specialized for lists (with no - * support for list subclasses). Like batch_list(), we batch up chunks of - * MARK item item ... item APPENDS - * opcode sequences. Calling code should have arranged to first create an - * empty list, or list-like object, for the APPENDS to operate on. - * Returns 0 on success, -1 on error. - * - * This version is considerably faster than batch_list(), if less general. - * - * Note that this only works for protocols > 0. - */ -static int -batch_list_exact(PicklerObject *self, PyObject *obj) -{ - PyObject *item = NULL; - Py_ssize_t this_batch, total; - - const char append_op = APPEND; - const char appends_op = APPENDS; - const char mark_op = MARK; - - assert(obj != NULL); - assert(self->proto > 0); - assert(PyList_CheckExact(obj)); - - if (PyList_GET_SIZE(obj) == 1) { - item = PyList_GET_ITEM(obj, 0); - if (save(self, item, 0) < 0) - return -1; - if (_Pickler_Write(self, &append_op, 1) < 0) - return -1; - return 0; - } - - /* Write in batches of BATCHSIZE. */ - total = 0; - do { - this_batch = 0; - if (_Pickler_Write(self, &mark_op, 1) < 0) - return -1; - while (total < PyList_GET_SIZE(obj)) { - item = PyList_GET_ITEM(obj, total); - if (save(self, item, 0) < 0) - return -1; - total++; - if (++this_batch == BATCHSIZE) - break; - } - if (_Pickler_Write(self, &appends_op, 1) < 0) - return -1; - - } while (total < PyList_GET_SIZE(obj)); - - return 0; -} - -static int -save_list(PicklerObject *self, PyObject *obj) -{ - char header[3]; - Py_ssize_t len; - int status = 0; - - if (self->fast && !fast_save_enter(self, obj)) - goto error; - - /* Create an empty list. */ - if (self->bin) { - header[0] = EMPTY_LIST; - len = 1; - } - else { - header[0] = MARK; - header[1] = LIST; - len = 2; - } - - if (_Pickler_Write(self, header, len) < 0) - goto error; - - /* Get list length, and bow out early if empty. */ - if ((len = PyList_Size(obj)) < 0) - goto error; - - if (memo_put(self, obj) < 0) - goto error; - - if (len != 0) { - /* Materialize the list elements. */ - if (PyList_CheckExact(obj) && self->proto > 0) { - if (Py_EnterRecursiveCall(" while pickling an object")) - goto error; - status = batch_list_exact(self, obj); - Py_LeaveRecursiveCall(); - } else { - PyObject *iter = PyObject_GetIter(obj); - if (iter == NULL) - goto error; - - if (Py_EnterRecursiveCall(" while pickling an object")) { - Py_DECREF(iter); - goto error; - } - status = batch_list(self, iter); - Py_LeaveRecursiveCall(); - Py_DECREF(iter); - } - } - if (0) { - error: - status = -1; - } - - if (self->fast && !fast_save_leave(self, obj)) - status = -1; - - return status; -} - -/* iter is an iterator giving (key, value) pairs, and we batch up chunks of - * MARK key value ... key value SETITEMS - * opcode sequences. Calling code should have arranged to first create an - * empty dict, or dict-like object, for the SETITEMS to operate on. - * Returns 0 on success, <0 on error. - * - * This is very much like batch_list(). The difference between saving - * elements directly, and picking apart two-tuples, is so long-winded at - * the C level, though, that attempts to combine these routines were too - * ugly to bear. - */ -static int -batch_dict(PicklerObject *self, PyObject *iter) -{ - PyObject *obj = NULL; - PyObject *firstitem = NULL; - int i, n; - - const char mark_op = MARK; - const char setitem_op = SETITEM; - const char setitems_op = SETITEMS; - - assert(iter != NULL); - - if (self->proto == 0) { - /* SETITEMS isn't available; do one at a time. */ - for (;;) { - obj = PyIter_Next(iter); - if (obj == NULL) { - if (PyErr_Occurred()) - return -1; - break; - } - if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) { - PyErr_SetString(PyExc_TypeError, "dict items " - "iterator must return 2-tuples"); - return -1; - } - i = save(self, PyTuple_GET_ITEM(obj, 0), 0); - if (i >= 0) - i = save(self, PyTuple_GET_ITEM(obj, 1), 0); - Py_DECREF(obj); - if (i < 0) - return -1; - if (_Pickler_Write(self, &setitem_op, 1) < 0) - return -1; - } - return 0; - } - - /* proto > 0: write in batches of BATCHSIZE. */ - do { - /* Get first item */ - firstitem = PyIter_Next(iter); - if (firstitem == NULL) { - if (PyErr_Occurred()) - goto error; - - /* nothing more to add */ - break; - } - if (!PyTuple_Check(firstitem) || PyTuple_Size(firstitem) != 2) { - PyErr_SetString(PyExc_TypeError, "dict items " - "iterator must return 2-tuples"); - goto error; - } - - /* Try to get a second item */ - obj = PyIter_Next(iter); - if (obj == NULL) { - if (PyErr_Occurred()) - goto error; - - /* Only one item to write */ - if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) - goto error; - if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) - goto error; - if (_Pickler_Write(self, &setitem_op, 1) < 0) - goto error; - Py_CLEAR(firstitem); - break; - } - - /* More than one item to write */ - - /* Pump out MARK, items, SETITEMS. */ - if (_Pickler_Write(self, &mark_op, 1) < 0) - goto error; - - if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) - goto error; - if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) - goto error; - Py_CLEAR(firstitem); - n = 1; - - /* Fetch and save up to BATCHSIZE items */ - while (obj) { - if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) { - PyErr_SetString(PyExc_TypeError, "dict items " - "iterator must return 2-tuples"); - goto error; - } - if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 || - save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0) - goto error; - Py_CLEAR(obj); - n += 1; - - if (n == BATCHSIZE) - break; - - obj = PyIter_Next(iter); - if (obj == NULL) { - if (PyErr_Occurred()) - goto error; - break; - } - } - - if (_Pickler_Write(self, &setitems_op, 1) < 0) - goto error; - - } while (n == BATCHSIZE); - return 0; - - error: - Py_XDECREF(firstitem); - Py_XDECREF(obj); - return -1; -} - -/* This is a variant of batch_dict() above that specializes for dicts, with no - * support for dict subclasses. Like batch_dict(), we batch up chunks of - * MARK key value ... key value SETITEMS - * opcode sequences. Calling code should have arranged to first create an - * empty dict, or dict-like object, for the SETITEMS to operate on. - * Returns 0 on success, -1 on error. - * - * Note that this currently doesn't work for protocol 0. - */ -static int -batch_dict_exact(PicklerObject *self, PyObject *obj) -{ - PyObject *key = NULL, *value = NULL; - int i; - Py_ssize_t dict_size, ppos = 0; - - const char mark_op = MARK; - const char setitem_op = SETITEM; - const char setitems_op = SETITEMS; - - assert(obj != NULL && PyDict_CheckExact(obj)); - assert(self->proto > 0); - - dict_size = PyDict_GET_SIZE(obj); - - /* Special-case len(d) == 1 to save space. */ - if (dict_size == 1) { - PyDict_Next(obj, &ppos, &key, &value); - if (save(self, key, 0) < 0) - return -1; - if (save(self, value, 0) < 0) - return -1; - if (_Pickler_Write(self, &setitem_op, 1) < 0) - return -1; - return 0; - } - - /* Write in batches of BATCHSIZE. */ - do { - i = 0; - if (_Pickler_Write(self, &mark_op, 1) < 0) - return -1; - while (PyDict_Next(obj, &ppos, &key, &value)) { - if (save(self, key, 0) < 0) - return -1; - if (save(self, value, 0) < 0) - return -1; - if (++i == BATCHSIZE) - break; - } - if (_Pickler_Write(self, &setitems_op, 1) < 0) - return -1; - if (PyDict_GET_SIZE(obj) != dict_size) { - PyErr_Format( - PyExc_RuntimeError, - "dictionary changed size during iteration"); - return -1; - } - - } while (i == BATCHSIZE); - return 0; -} - -static int -save_dict(PicklerObject *self, PyObject *obj) -{ - PyObject *items, *iter; - char header[3]; - Py_ssize_t len; - int status = 0; - assert(PyDict_Check(obj)); - - if (self->fast && !fast_save_enter(self, obj)) - goto error; - - /* Create an empty dict. */ - if (self->bin) { - header[0] = EMPTY_DICT; - len = 1; - } - else { - header[0] = MARK; - header[1] = DICT; - len = 2; - } - - if (_Pickler_Write(self, header, len) < 0) - goto error; - - if (memo_put(self, obj) < 0) - goto error; - - if (PyDict_GET_SIZE(obj)) { - /* Save the dict items. */ - if (PyDict_CheckExact(obj) && self->proto > 0) { - /* We can take certain shortcuts if we know this is a dict and - not a dict subclass. */ - if (Py_EnterRecursiveCall(" while pickling an object")) - goto error; - status = batch_dict_exact(self, obj); - Py_LeaveRecursiveCall(); - } else { - _Py_IDENTIFIER(items); - - items = _PyObject_CallMethodIdNoArgs(obj, &PyId_items); - if (items == NULL) - goto error; - iter = PyObject_GetIter(items); - Py_DECREF(items); - if (iter == NULL) - goto error; - if (Py_EnterRecursiveCall(" while pickling an object")) { - Py_DECREF(iter); - goto error; - } - status = batch_dict(self, iter); - Py_LeaveRecursiveCall(); - Py_DECREF(iter); - } - } - - if (0) { - error: - status = -1; - } - - if (self->fast && !fast_save_leave(self, obj)) - status = -1; - - return status; -} - -static int -save_set(PicklerObject *self, PyObject *obj) -{ - PyObject *item; - int i; - Py_ssize_t set_size, ppos = 0; - Py_hash_t hash; - - const char empty_set_op = EMPTY_SET; - const char mark_op = MARK; - const char additems_op = ADDITEMS; - - if (self->proto < 4) { - PyObject *items; - PyObject *reduce_value; - int status; - - items = PySequence_List(obj); - if (items == NULL) { - return -1; - } - reduce_value = Py_BuildValue("(O(O))", (PyObject*)&PySet_Type, items); - Py_DECREF(items); - if (reduce_value == NULL) { - return -1; - } - /* save_reduce() will memoize the object automatically. */ - status = save_reduce(self, reduce_value, obj); - Py_DECREF(reduce_value); - return status; - } - - if (_Pickler_Write(self, &empty_set_op, 1) < 0) - return -1; - - if (memo_put(self, obj) < 0) - return -1; - - set_size = PySet_GET_SIZE(obj); - if (set_size == 0) - return 0; /* nothing to do */ - - /* Write in batches of BATCHSIZE. */ - do { - i = 0; - if (_Pickler_Write(self, &mark_op, 1) < 0) - return -1; - while (_PySet_NextEntry(obj, &ppos, &item, &hash)) { - if (save(self, item, 0) < 0) - return -1; - if (++i == BATCHSIZE) - break; - } - if (_Pickler_Write(self, &additems_op, 1) < 0) - return -1; - if (PySet_GET_SIZE(obj) != set_size) { - PyErr_Format( - PyExc_RuntimeError, - "set changed size during iteration"); - return -1; - } - } while (i == BATCHSIZE); - - return 0; -} - -static int -save_frozenset(PicklerObject *self, PyObject *obj) -{ - PyObject *iter; - - const char mark_op = MARK; - const char frozenset_op = FROZENSET; - - if (self->fast && !fast_save_enter(self, obj)) - return -1; - - if (self->proto < 4) { - PyObject *items; - PyObject *reduce_value; - int status; - - items = PySequence_List(obj); - if (items == NULL) { - return -1; - } - reduce_value = Py_BuildValue("(O(O))", (PyObject*)&PyFrozenSet_Type, - items); - Py_DECREF(items); - if (reduce_value == NULL) { - return -1; - } - /* save_reduce() will memoize the object automatically. */ - status = save_reduce(self, reduce_value, obj); - Py_DECREF(reduce_value); - return status; - } - - if (_Pickler_Write(self, &mark_op, 1) < 0) - return -1; - - iter = PyObject_GetIter(obj); - if (iter == NULL) { - return -1; - } - for (;;) { - PyObject *item; - - item = PyIter_Next(iter); - if (item == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(iter); - return -1; - } - break; - } - if (save(self, item, 0) < 0) { - Py_DECREF(item); - Py_DECREF(iter); - return -1; - } - Py_DECREF(item); - } - Py_DECREF(iter); - - /* If the object is already in the memo, this means it is - recursive. In this case, throw away everything we put on the - stack, and fetch the object back from the memo. */ - if (PyMemoTable_Get(self->memo, obj)) { - const char pop_mark_op = POP_MARK; - - if (_Pickler_Write(self, &pop_mark_op, 1) < 0) - return -1; - if (memo_get(self, obj) < 0) - return -1; - return 0; - } - - if (_Pickler_Write(self, &frozenset_op, 1) < 0) - return -1; - if (memo_put(self, obj) < 0) - return -1; - - return 0; -} - -static int -fix_imports(PyObject **module_name, PyObject **global_name) -{ - PyObject *key; - PyObject *item; - PickleState *st = _Pickle_GetGlobalState(); - - key = PyTuple_Pack(2, *module_name, *global_name); - if (key == NULL) - return -1; - item = PyDict_GetItemWithError(st->name_mapping_3to2, key); - Py_DECREF(key); - if (item) { - PyObject *fixed_module_name; - PyObject *fixed_global_name; - - if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.REVERSE_NAME_MAPPING values " - "should be 2-tuples, not %.200s", - Py_TYPE(item)->tp_name); - return -1; - } - fixed_module_name = PyTuple_GET_ITEM(item, 0); - fixed_global_name = PyTuple_GET_ITEM(item, 1); - if (!PyUnicode_Check(fixed_module_name) || - !PyUnicode_Check(fixed_global_name)) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.REVERSE_NAME_MAPPING values " - "should be pairs of str, not (%.200s, %.200s)", - Py_TYPE(fixed_module_name)->tp_name, - Py_TYPE(fixed_global_name)->tp_name); - return -1; - } - - Py_CLEAR(*module_name); - Py_CLEAR(*global_name); - Py_INCREF(fixed_module_name); - Py_INCREF(fixed_global_name); - *module_name = fixed_module_name; - *global_name = fixed_global_name; - return 0; - } - else if (PyErr_Occurred()) { - return -1; - } - - item = PyDict_GetItemWithError(st->import_mapping_3to2, *module_name); - if (item) { - if (!PyUnicode_Check(item)) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.REVERSE_IMPORT_MAPPING values " - "should be strings, not %.200s", - Py_TYPE(item)->tp_name); - return -1; - } - Py_INCREF(item); - Py_XSETREF(*module_name, item); - } - else if (PyErr_Occurred()) { - return -1; - } - - return 0; -} - -static int -save_global(PicklerObject *self, PyObject *obj, PyObject *name) -{ - PyObject *global_name = NULL; - PyObject *module_name = NULL; - PyObject *module = NULL; - PyObject *parent = NULL; - PyObject *dotted_path = NULL; - PyObject *lastname = NULL; - PyObject *cls; - PickleState *st = _Pickle_GetGlobalState(); - int status = 0; - _Py_IDENTIFIER(__name__); - _Py_IDENTIFIER(__qualname__); - - const char global_op = GLOBAL; - - if (name) { - Py_INCREF(name); - global_name = name; - } - else { - if (_PyObject_LookupAttrId(obj, &PyId___qualname__, &global_name) < 0) - goto error; - if (global_name == NULL) { - global_name = _PyObject_GetAttrId(obj, &PyId___name__); - if (global_name == NULL) - goto error; - } - } - - dotted_path = get_dotted_path(module, global_name); - if (dotted_path == NULL) - goto error; - module_name = whichmodule(obj, dotted_path); - if (module_name == NULL) - goto error; - - /* XXX: Change to use the import C API directly with level=0 to disallow - relative imports. - - XXX: PyImport_ImportModuleLevel could be used. However, this bypasses - builtins.__import__. Therefore, _pickle, unlike pickle.py, will ignore - custom import functions (IMHO, this would be a nice security - feature). The import C API would need to be extended to support the - extra parameters of __import__ to fix that. */ - module = PyImport_Import(module_name); - if (module == NULL) { - PyErr_Format(st->PicklingError, - "Can't pickle %R: import of module %R failed", - obj, module_name); - goto error; - } - lastname = PyList_GET_ITEM(dotted_path, PyList_GET_SIZE(dotted_path)-1); - Py_INCREF(lastname); - cls = get_deep_attribute(module, dotted_path, &parent); - Py_CLEAR(dotted_path); - if (cls == NULL) { - PyErr_Format(st->PicklingError, - "Can't pickle %R: attribute lookup %S on %S failed", - obj, global_name, module_name); - goto error; - } - if (cls != obj) { - Py_DECREF(cls); - PyErr_Format(st->PicklingError, - "Can't pickle %R: it's not the same object as %S.%S", - obj, module_name, global_name); - goto error; - } - Py_DECREF(cls); - - if (self->proto >= 2) { - /* See whether this is in the extension registry, and if - * so generate an EXT opcode. - */ - PyObject *extension_key; - PyObject *code_obj; /* extension code as Python object */ - long code; /* extension code as C value */ - char pdata[5]; - Py_ssize_t n; - - extension_key = PyTuple_Pack(2, module_name, global_name); - if (extension_key == NULL) { - goto error; - } - code_obj = PyDict_GetItemWithError(st->extension_registry, - extension_key); - Py_DECREF(extension_key); - /* The object is not registered in the extension registry. - This is the most likely code path. */ - if (code_obj == NULL) { - if (PyErr_Occurred()) { - goto error; - } - goto gen_global; - } - - /* XXX: pickle.py doesn't check neither the type, nor the range - of the value returned by the extension_registry. It should for - consistency. */ - - /* Verify code_obj has the right type and value. */ - if (!PyLong_Check(code_obj)) { - PyErr_Format(st->PicklingError, - "Can't pickle %R: extension code %R isn't an integer", - obj, code_obj); - goto error; - } - code = PyLong_AS_LONG(code_obj); - if (code <= 0 || code > 0x7fffffffL) { - if (!PyErr_Occurred()) - PyErr_Format(st->PicklingError, "Can't pickle %R: extension " - "code %ld is out of range", obj, code); - goto error; - } - - /* Generate an EXT opcode. */ - if (code <= 0xff) { - pdata[0] = EXT1; - pdata[1] = (unsigned char)code; - n = 2; - } - else if (code <= 0xffff) { - pdata[0] = EXT2; - pdata[1] = (unsigned char)(code & 0xff); - pdata[2] = (unsigned char)((code >> 8) & 0xff); - n = 3; - } - else { - pdata[0] = EXT4; - pdata[1] = (unsigned char)(code & 0xff); - pdata[2] = (unsigned char)((code >> 8) & 0xff); - pdata[3] = (unsigned char)((code >> 16) & 0xff); - pdata[4] = (unsigned char)((code >> 24) & 0xff); - n = 5; - } - - if (_Pickler_Write(self, pdata, n) < 0) - goto error; - } - else { - gen_global: - if (parent == module) { - Py_INCREF(lastname); - Py_DECREF(global_name); - global_name = lastname; - } - if (self->proto >= 4) { - const char stack_global_op = STACK_GLOBAL; - - if (save(self, module_name, 0) < 0) - goto error; - if (save(self, global_name, 0) < 0) - goto error; - - if (_Pickler_Write(self, &stack_global_op, 1) < 0) - goto error; - } - else if (parent != module) { - PickleState *st = _Pickle_GetGlobalState(); - PyObject *reduce_value = Py_BuildValue("(O(OO))", - st->getattr, parent, lastname); - if (reduce_value == NULL) - goto error; - status = save_reduce(self, reduce_value, NULL); - Py_DECREF(reduce_value); - if (status < 0) - goto error; - } - else { - /* Generate a normal global opcode if we are using a pickle - protocol < 4, or if the object is not registered in the - extension registry. */ - PyObject *encoded; - PyObject *(*unicode_encoder)(PyObject *); - - if (_Pickler_Write(self, &global_op, 1) < 0) - goto error; - - /* For protocol < 3 and if the user didn't request against doing - so, we convert module names to the old 2.x module names. */ - if (self->proto < 3 && self->fix_imports) { - if (fix_imports(&module_name, &global_name) < 0) { - goto error; - } - } - - /* Since Python 3.0 now supports non-ASCII identifiers, we encode - both the module name and the global name using UTF-8. We do so - only when we are using the pickle protocol newer than version - 3. This is to ensure compatibility with older Unpickler running - on Python 2.x. */ - if (self->proto == 3) { - unicode_encoder = PyUnicode_AsUTF8String; - } - else { - unicode_encoder = PyUnicode_AsASCIIString; - } - encoded = unicode_encoder(module_name); - if (encoded == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) - PyErr_Format(st->PicklingError, - "can't pickle module identifier '%S' using " - "pickle protocol %i", - module_name, self->proto); - goto error; - } - if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), - PyBytes_GET_SIZE(encoded)) < 0) { - Py_DECREF(encoded); - goto error; - } - Py_DECREF(encoded); - if(_Pickler_Write(self, "\n", 1) < 0) - goto error; - - /* Save the name of the module. */ - encoded = unicode_encoder(global_name); - if (encoded == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) - PyErr_Format(st->PicklingError, - "can't pickle global identifier '%S' using " - "pickle protocol %i", - global_name, self->proto); - goto error; - } - if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), - PyBytes_GET_SIZE(encoded)) < 0) { - Py_DECREF(encoded); - goto error; - } - Py_DECREF(encoded); - if (_Pickler_Write(self, "\n", 1) < 0) - goto error; - } - /* Memoize the object. */ - if (memo_put(self, obj) < 0) - goto error; - } - - if (0) { - error: - status = -1; - } - Py_XDECREF(module_name); - Py_XDECREF(global_name); - Py_XDECREF(module); - Py_XDECREF(parent); - Py_XDECREF(dotted_path); - Py_XDECREF(lastname); - - return status; -} - -static int -save_singleton_type(PicklerObject *self, PyObject *obj, PyObject *singleton) -{ - PyObject *reduce_value; - int status; - - reduce_value = Py_BuildValue("O(O)", &PyType_Type, singleton); - if (reduce_value == NULL) { - return -1; - } - status = save_reduce(self, reduce_value, obj); - Py_DECREF(reduce_value); - return status; -} - -static int -save_type(PicklerObject *self, PyObject *obj) -{ - if (obj == (PyObject *)&_PyNone_Type) { - return save_singleton_type(self, obj, Py_None); - } - else if (obj == (PyObject *)&PyEllipsis_Type) { - return save_singleton_type(self, obj, Py_Ellipsis); - } - else if (obj == (PyObject *)&_PyNotImplemented_Type) { - return save_singleton_type(self, obj, Py_NotImplemented); - } - return save_global(self, obj, NULL); -} - -static int -save_pers(PicklerObject *self, PyObject *obj) -{ - PyObject *pid = NULL; - int status = 0; - - const char persid_op = PERSID; - const char binpersid_op = BINPERSID; - - pid = call_method(self->pers_func, self->pers_func_self, obj); - if (pid == NULL) - return -1; - - if (pid != Py_None) { - if (self->bin) { - if (save(self, pid, 1) < 0 || - _Pickler_Write(self, &binpersid_op, 1) < 0) - goto error; - } - else { - PyObject *pid_str; - - pid_str = PyObject_Str(pid); - if (pid_str == NULL) - goto error; - - /* XXX: Should it check whether the pid contains embedded - newlines? */ - if (!PyUnicode_IS_ASCII(pid_str)) { - PyErr_SetString(_Pickle_GetGlobalState()->PicklingError, - "persistent IDs in protocol 0 must be " - "ASCII strings"); - Py_DECREF(pid_str); - goto error; - } - - if (_Pickler_Write(self, &persid_op, 1) < 0 || - _Pickler_Write(self, PyUnicode_DATA(pid_str), - PyUnicode_GET_LENGTH(pid_str)) < 0 || - _Pickler_Write(self, "\n", 1) < 0) { - Py_DECREF(pid_str); - goto error; - } - Py_DECREF(pid_str); - } - status = 1; - } - - if (0) { - error: - status = -1; - } - Py_XDECREF(pid); - - return status; -} - -static PyObject * -get_class(PyObject *obj) -{ - PyObject *cls; - _Py_IDENTIFIER(__class__); - - if (_PyObject_LookupAttrId(obj, &PyId___class__, &cls) == 0) { - cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); - } - return cls; -} - -/* We're saving obj, and args is the 2-thru-5 tuple returned by the - * appropriate __reduce__ method for obj. - */ -static int -save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) -{ - PyObject *callable; - PyObject *argtup; - PyObject *state = NULL; - PyObject *listitems = Py_None; - PyObject *dictitems = Py_None; - PyObject *state_setter = Py_None; - PickleState *st = _Pickle_GetGlobalState(); - Py_ssize_t size; - int use_newobj = 0, use_newobj_ex = 0; - - const char reduce_op = REDUCE; - const char build_op = BUILD; - const char newobj_op = NEWOBJ; - const char newobj_ex_op = NEWOBJ_EX; - - size = PyTuple_Size(args); - if (size < 2 || size > 6) { - PyErr_SetString(st->PicklingError, "tuple returned by " - "__reduce__ must contain 2 through 6 elements"); - return -1; - } - - if (!PyArg_UnpackTuple(args, "save_reduce", 2, 6, - &callable, &argtup, &state, &listitems, &dictitems, - &state_setter)) - return -1; - - if (!PyCallable_Check(callable)) { - PyErr_SetString(st->PicklingError, "first item of the tuple " - "returned by __reduce__ must be callable"); - return -1; - } - if (!PyTuple_Check(argtup)) { - PyErr_SetString(st->PicklingError, "second item of the tuple " - "returned by __reduce__ must be a tuple"); - return -1; - } - - if (state == Py_None) - state = NULL; - - if (listitems == Py_None) - listitems = NULL; - else if (!PyIter_Check(listitems)) { - PyErr_Format(st->PicklingError, "fourth element of the tuple " - "returned by __reduce__ must be an iterator, not %s", - Py_TYPE(listitems)->tp_name); - return -1; - } - - if (dictitems == Py_None) - dictitems = NULL; - else if (!PyIter_Check(dictitems)) { - PyErr_Format(st->PicklingError, "fifth element of the tuple " - "returned by __reduce__ must be an iterator, not %s", - Py_TYPE(dictitems)->tp_name); - return -1; - } - - if (state_setter == Py_None) - state_setter = NULL; - else if (!PyCallable_Check(state_setter)) { - PyErr_Format(st->PicklingError, "sixth element of the tuple " - "returned by __reduce__ must be a function, not %s", - Py_TYPE(state_setter)->tp_name); - return -1; - } - - if (self->proto >= 2) { - PyObject *name; - _Py_IDENTIFIER(__name__); - - if (_PyObject_LookupAttrId(callable, &PyId___name__, &name) < 0) { - return -1; - } - if (name != NULL && PyUnicode_Check(name)) { - _Py_IDENTIFIER(__newobj_ex__); - use_newobj_ex = _PyUnicode_EqualToASCIIId( - name, &PyId___newobj_ex__); - if (!use_newobj_ex) { - _Py_IDENTIFIER(__newobj__); - use_newobj = _PyUnicode_EqualToASCIIId(name, &PyId___newobj__); - } - } - Py_XDECREF(name); - } - - if (use_newobj_ex) { - PyObject *cls; - PyObject *args; - PyObject *kwargs; - - if (PyTuple_GET_SIZE(argtup) != 3) { - PyErr_Format(st->PicklingError, - "length of the NEWOBJ_EX argument tuple must be " - "exactly 3, not %zd", PyTuple_GET_SIZE(argtup)); - return -1; - } - - cls = PyTuple_GET_ITEM(argtup, 0); - if (!PyType_Check(cls)) { - PyErr_Format(st->PicklingError, - "first item from NEWOBJ_EX argument tuple must " - "be a class, not %.200s", Py_TYPE(cls)->tp_name); - return -1; - } - args = PyTuple_GET_ITEM(argtup, 1); - if (!PyTuple_Check(args)) { - PyErr_Format(st->PicklingError, - "second item from NEWOBJ_EX argument tuple must " - "be a tuple, not %.200s", Py_TYPE(args)->tp_name); - return -1; - } - kwargs = PyTuple_GET_ITEM(argtup, 2); - if (!PyDict_Check(kwargs)) { - PyErr_Format(st->PicklingError, - "third item from NEWOBJ_EX argument tuple must " - "be a dict, not %.200s", Py_TYPE(kwargs)->tp_name); - return -1; - } - - if (self->proto >= 4) { - if (save(self, cls, 0) < 0 || - save(self, args, 0) < 0 || - save(self, kwargs, 0) < 0 || - _Pickler_Write(self, &newobj_ex_op, 1) < 0) { - return -1; - } - } - else { - PyObject *newargs; - PyObject *cls_new; - Py_ssize_t i; - _Py_IDENTIFIER(__new__); - - newargs = PyTuple_New(PyTuple_GET_SIZE(args) + 2); - if (newargs == NULL) - return -1; - - cls_new = _PyObject_GetAttrId(cls, &PyId___new__); - if (cls_new == NULL) { - Py_DECREF(newargs); - return -1; - } - PyTuple_SET_ITEM(newargs, 0, cls_new); - Py_INCREF(cls); - PyTuple_SET_ITEM(newargs, 1, cls); - for (i = 0; i < PyTuple_GET_SIZE(args); i++) { - PyObject *item = PyTuple_GET_ITEM(args, i); - Py_INCREF(item); - PyTuple_SET_ITEM(newargs, i + 2, item); - } - - callable = PyObject_Call(st->partial, newargs, kwargs); - Py_DECREF(newargs); - if (callable == NULL) - return -1; - - newargs = PyTuple_New(0); - if (newargs == NULL) { - Py_DECREF(callable); - return -1; - } - - if (save(self, callable, 0) < 0 || - save(self, newargs, 0) < 0 || - _Pickler_Write(self, &reduce_op, 1) < 0) { - Py_DECREF(newargs); - Py_DECREF(callable); - return -1; - } - Py_DECREF(newargs); - Py_DECREF(callable); - } - } - else if (use_newobj) { - PyObject *cls; - PyObject *newargtup; - PyObject *obj_class; - int p; - - /* Sanity checks. */ - if (PyTuple_GET_SIZE(argtup) < 1) { - PyErr_SetString(st->PicklingError, "__newobj__ arglist is empty"); - return -1; - } - - cls = PyTuple_GET_ITEM(argtup, 0); - if (!PyType_Check(cls)) { - PyErr_SetString(st->PicklingError, "args[0] from " - "__newobj__ args is not a type"); - return -1; - } - - if (obj != NULL) { - obj_class = get_class(obj); - if (obj_class == NULL) { - return -1; - } - p = obj_class != cls; - Py_DECREF(obj_class); - if (p) { - PyErr_SetString(st->PicklingError, "args[0] from " - "__newobj__ args has the wrong class"); - return -1; - } - } - /* XXX: These calls save() are prone to infinite recursion. Imagine - what happen if the value returned by the __reduce__() method of - some extension type contains another object of the same type. Ouch! - - Here is a quick example, that I ran into, to illustrate what I - mean: - - >>> import pickle, copyreg - >>> copyreg.dispatch_table.pop(complex) - >>> pickle.dumps(1+2j) - Traceback (most recent call last): - ... - RecursionError: maximum recursion depth exceeded - - Removing the complex class from copyreg.dispatch_table made the - __reduce_ex__() method emit another complex object: - - >>> (1+1j).__reduce_ex__(2) - (, - (, (1+1j)), None, None, None) - - Thus when save() was called on newargstup (the 2nd item) recursion - ensued. Of course, the bug was in the complex class which had a - broken __getnewargs__() that emitted another complex object. But, - the point, here, is it is quite easy to end up with a broken reduce - function. */ - - /* Save the class and its __new__ arguments. */ - if (save(self, cls, 0) < 0) - return -1; - - newargtup = PyTuple_GetSlice(argtup, 1, PyTuple_GET_SIZE(argtup)); - if (newargtup == NULL) - return -1; - - p = save(self, newargtup, 0); - Py_DECREF(newargtup); - if (p < 0) - return -1; - - /* Add NEWOBJ opcode. */ - if (_Pickler_Write(self, &newobj_op, 1) < 0) - return -1; - } - else { /* Not using NEWOBJ. */ - if (save(self, callable, 0) < 0 || - save(self, argtup, 0) < 0 || - _Pickler_Write(self, &reduce_op, 1) < 0) - return -1; - } - - /* obj can be NULL when save_reduce() is used directly. A NULL obj means - the caller do not want to memoize the object. Not particularly useful, - but that is to mimic the behavior save_reduce() in pickle.py when - obj is None. */ - if (obj != NULL) { - /* If the object is already in the memo, this means it is - recursive. In this case, throw away everything we put on the - stack, and fetch the object back from the memo. */ - if (PyMemoTable_Get(self->memo, obj)) { - const char pop_op = POP; - - if (_Pickler_Write(self, &pop_op, 1) < 0) - return -1; - if (memo_get(self, obj) < 0) - return -1; - - return 0; - } - else if (memo_put(self, obj) < 0) - return -1; - } - - if (listitems && batch_list(self, listitems) < 0) - return -1; - - if (dictitems && batch_dict(self, dictitems) < 0) - return -1; - - if (state) { - if (state_setter == NULL) { - if (save(self, state, 0) < 0 || - _Pickler_Write(self, &build_op, 1) < 0) - return -1; - } - else { - - /* If a state_setter is specified, call it instead of load_build to - * update obj's with its previous state. - * The first 4 save/write instructions push state_setter and its - * tuple of expected arguments (obj, state) onto the stack. The - * REDUCE opcode triggers the state_setter(obj, state) function - * call. Finally, because state-updating routines only do in-place - * modification, the whole operation has to be stack-transparent. - * Thus, we finally pop the call's output from the stack.*/ - - const char tupletwo_op = TUPLE2; - const char pop_op = POP; - if (save(self, state_setter, 0) < 0 || - save(self, obj, 0) < 0 || save(self, state, 0) < 0 || - _Pickler_Write(self, &tupletwo_op, 1) < 0 || - _Pickler_Write(self, &reduce_op, 1) < 0 || - _Pickler_Write(self, &pop_op, 1) < 0) - return -1; - } - } - return 0; -} - -static int -save(PicklerObject *self, PyObject *obj, int pers_save) -{ - PyTypeObject *type; - PyObject *reduce_func = NULL; - PyObject *reduce_value = NULL; - int status = 0; - - if (_Pickler_OpcodeBoundary(self) < 0) - return -1; - - /* The extra pers_save argument is necessary to avoid calling save_pers() - on its returned object. */ - if (!pers_save && self->pers_func) { - /* save_pers() returns: - -1 to signal an error; - 0 if it did nothing successfully; - 1 if a persistent id was saved. - */ - if ((status = save_pers(self, obj)) != 0) - return status; - } - - type = Py_TYPE(obj); - - /* The old cPickle had an optimization that used switch-case statement - dispatching on the first letter of the type name. This has was removed - since benchmarks shown that this optimization was actually slowing - things down. */ - - /* Atom types; these aren't memoized, so don't check the memo. */ - - if (obj == Py_None) { - return save_none(self, obj); - } - else if (obj == Py_False || obj == Py_True) { - return save_bool(self, obj); - } - else if (type == &PyLong_Type) { - return save_long(self, obj); - } - else if (type == &PyFloat_Type) { - return save_float(self, obj); - } - - /* Check the memo to see if it has the object. If so, generate - a GET (or BINGET) opcode, instead of pickling the object - once again. */ - if (PyMemoTable_Get(self->memo, obj)) { - return memo_get(self, obj); - } - - if (type == &PyBytes_Type) { - return save_bytes(self, obj); - } - else if (type == &PyUnicode_Type) { - return save_unicode(self, obj); - } - - /* We're only calling Py_EnterRecursiveCall here so that atomic - types above are pickled faster. */ - if (Py_EnterRecursiveCall(" while pickling an object")) { - return -1; - } - - if (type == &PyDict_Type) { - status = save_dict(self, obj); - goto done; - } - else if (type == &PySet_Type) { - status = save_set(self, obj); - goto done; - } - else if (type == &PyFrozenSet_Type) { - status = save_frozenset(self, obj); - goto done; - } - else if (type == &PyList_Type) { - status = save_list(self, obj); - goto done; - } - else if (type == &PyTuple_Type) { - status = save_tuple(self, obj); - goto done; - } - else if (type == &PyByteArray_Type) { - status = save_bytearray(self, obj); - goto done; - } - else if (type == &PyPickleBuffer_Type) { - status = save_picklebuffer(self, obj); - goto done; - } - - /* Now, check reducer_override. If it returns NotImplemented, - * fallback to save_type or save_global, and then perhaps to the - * regular reduction mechanism. - */ - if (self->reducer_override != NULL) { - reduce_value = PyObject_CallOneArg(self->reducer_override, obj); - if (reduce_value == NULL) { - goto error; - } - if (reduce_value != Py_NotImplemented) { - goto reduce; - } - Py_DECREF(reduce_value); - reduce_value = NULL; - } - - if (type == &PyType_Type) { - status = save_type(self, obj); - goto done; - } - else if (type == &PyFunction_Type) { - status = save_global(self, obj, NULL); - goto done; - } - - /* XXX: This part needs some unit tests. */ - - /* Get a reduction callable, and call it. This may come from - * self.dispatch_table, copyreg.dispatch_table, the object's - * __reduce_ex__ method, or the object's __reduce__ method. - */ - if (self->dispatch_table == NULL) { - PickleState *st = _Pickle_GetGlobalState(); - reduce_func = PyDict_GetItemWithError(st->dispatch_table, - (PyObject *)type); - if (reduce_func == NULL) { - if (PyErr_Occurred()) { - goto error; - } - } else { - /* PyDict_GetItemWithError() returns a borrowed reference. - Increase the reference count to be consistent with - PyObject_GetItem and _PyObject_GetAttrId used below. */ - Py_INCREF(reduce_func); - } - } else { - reduce_func = PyObject_GetItem(self->dispatch_table, - (PyObject *)type); - if (reduce_func == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_Clear(); - else - goto error; - } - } - if (reduce_func != NULL) { - Py_INCREF(obj); - reduce_value = _Pickle_FastCall(reduce_func, obj); - } - else if (PyType_IsSubtype(type, &PyType_Type)) { - status = save_global(self, obj, NULL); - goto done; - } - else { - _Py_IDENTIFIER(__reduce__); - _Py_IDENTIFIER(__reduce_ex__); - - /* XXX: If the __reduce__ method is defined, __reduce_ex__ is - automatically defined as __reduce__. While this is convenient, this - make it impossible to know which method was actually called. Of - course, this is not a big deal. But still, it would be nice to let - the user know which method was called when something go - wrong. Incidentally, this means if __reduce_ex__ is not defined, we - don't actually have to check for a __reduce__ method. */ - - /* Check for a __reduce_ex__ method. */ - if (_PyObject_LookupAttrId(obj, &PyId___reduce_ex__, &reduce_func) < 0) { - goto error; - } - if (reduce_func != NULL) { - PyObject *proto; - proto = PyLong_FromLong(self->proto); - if (proto != NULL) { - reduce_value = _Pickle_FastCall(reduce_func, proto); - } - } - else { - /* Check for a __reduce__ method. */ - if (_PyObject_LookupAttrId(obj, &PyId___reduce__, &reduce_func) < 0) { - goto error; - } - if (reduce_func != NULL) { - reduce_value = PyObject_CallNoArgs(reduce_func); - } - else { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->PicklingError, - "can't pickle '%.200s' object: %R", - type->tp_name, obj); - goto error; - } - } - } - - if (reduce_value == NULL) - goto error; - - reduce: - if (PyUnicode_Check(reduce_value)) { - status = save_global(self, obj, reduce_value); - goto done; - } - - if (!PyTuple_Check(reduce_value)) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->PicklingError, - "__reduce__ must return a string or tuple"); - goto error; - } - - status = save_reduce(self, reduce_value, obj); - - if (0) { - error: - status = -1; - } - done: - - Py_LeaveRecursiveCall(); - Py_XDECREF(reduce_func); - Py_XDECREF(reduce_value); - - return status; -} - -static int -dump(PicklerObject *self, PyObject *obj) -{ - const char stop_op = STOP; - int status = -1; - PyObject *tmp; - _Py_IDENTIFIER(reducer_override); - - if (_PyObject_LookupAttrId((PyObject *)self, &PyId_reducer_override, - &tmp) < 0) { - goto error; - } - /* Cache the reducer_override method, if it exists. */ - if (tmp != NULL) { - Py_XSETREF(self->reducer_override, tmp); - } - else { - Py_CLEAR(self->reducer_override); - } - - if (self->proto >= 2) { - char header[2]; - - header[0] = PROTO; - assert(self->proto >= 0 && self->proto < 256); - header[1] = (unsigned char)self->proto; - if (_Pickler_Write(self, header, 2) < 0) - goto error; - if (self->proto >= 4) - self->framing = 1; - } - - if (save(self, obj, 0) < 0 || - _Pickler_Write(self, &stop_op, 1) < 0 || - _Pickler_CommitFrame(self) < 0) - goto error; - - // Success - status = 0; - - error: - self->framing = 0; - - /* Break the reference cycle we generated at the beginning this function - * call when setting the reducer_override attribute of the Pickler instance - * to a bound method of the same instance. This is important as the Pickler - * instance holds a reference to each object it has pickled (through its - * memo): thus, these objects won't be garbage-collected as long as the - * Pickler itself is not collected. */ - Py_CLEAR(self->reducer_override); - return status; -} - -/*[clinic input] - -_pickle.Pickler.clear_memo - -Clears the pickler's "memo". - -The memo is the data structure that remembers which objects the -pickler has already seen, so that shared or recursive objects are -pickled by reference and not by value. This method is useful when -re-using picklers. -[clinic start generated code]*/ - -static PyObject * -_pickle_Pickler_clear_memo_impl(PicklerObject *self) -/*[clinic end generated code: output=8665c8658aaa094b input=01bdad52f3d93e56]*/ -{ - if (self->memo) - PyMemoTable_Clear(self->memo); - - Py_RETURN_NONE; -} - -/*[clinic input] - -_pickle.Pickler.dump - - obj: object - / - -Write a pickled representation of the given object to the open file. -[clinic start generated code]*/ - -static PyObject * -_pickle_Pickler_dump(PicklerObject *self, PyObject *obj) -/*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ -{ - /* Check whether the Pickler was initialized correctly (issue3664). - Developers often forget to call __init__() in their subclasses, which - would trigger a segfault without this check. */ - if (self->write == NULL) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->PicklingError, - "Pickler.__init__() was not called by %s.__init__()", - Py_TYPE(self)->tp_name); - return NULL; - } - - if (_Pickler_ClearBuffer(self) < 0) - return NULL; - - if (dump(self, obj) < 0) - return NULL; - - if (_Pickler_FlushToFile(self) < 0) - return NULL; - - Py_RETURN_NONE; -} - -/*[clinic input] - -_pickle.Pickler.__sizeof__ -> Py_ssize_t - -Returns size in memory, in bytes. -[clinic start generated code]*/ - -static Py_ssize_t -_pickle_Pickler___sizeof___impl(PicklerObject *self) -/*[clinic end generated code: output=106edb3123f332e1 input=8cbbec9bd5540d42]*/ -{ - Py_ssize_t res, s; - - res = _PyObject_SIZE(Py_TYPE(self)); - if (self->memo != NULL) { - res += sizeof(PyMemoTable); - res += self->memo->mt_allocated * sizeof(PyMemoEntry); - } - if (self->output_buffer != NULL) { - s = _PySys_GetSizeOf(self->output_buffer); - if (s == -1) - return -1; - res += s; - } - return res; -} - -static struct PyMethodDef Pickler_methods[] = { - _PICKLE_PICKLER_DUMP_METHODDEF - _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF - _PICKLE_PICKLER___SIZEOF___METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static void -Pickler_dealloc(PicklerObject *self) -{ - PyObject_GC_UnTrack(self); - - Py_XDECREF(self->output_buffer); - Py_XDECREF(self->write); - Py_XDECREF(self->pers_func); - Py_XDECREF(self->dispatch_table); - Py_XDECREF(self->fast_memo); - Py_XDECREF(self->reducer_override); - Py_XDECREF(self->buffer_callback); - - PyMemoTable_Del(self->memo); - - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -Pickler_traverse(PicklerObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->write); - Py_VISIT(self->pers_func); - Py_VISIT(self->dispatch_table); - Py_VISIT(self->fast_memo); - Py_VISIT(self->reducer_override); - Py_VISIT(self->buffer_callback); - return 0; -} - -static int -Pickler_clear(PicklerObject *self) -{ - Py_CLEAR(self->output_buffer); - Py_CLEAR(self->write); - Py_CLEAR(self->pers_func); - Py_CLEAR(self->dispatch_table); - Py_CLEAR(self->fast_memo); - Py_CLEAR(self->reducer_override); - Py_CLEAR(self->buffer_callback); - - if (self->memo != NULL) { - PyMemoTable *memo = self->memo; - self->memo = NULL; - PyMemoTable_Del(memo); - } - return 0; -} - - -/*[clinic input] - -_pickle.Pickler.__init__ - - file: object - protocol: object = None - fix_imports: bool = True - buffer_callback: object = None - -This takes a binary file for writing a pickle data stream. - -The optional *protocol* argument tells the pickler to use the given -protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default -protocol is 4. It was introduced in Python 3.4, and is incompatible -with previous versions. - -Specifying a negative protocol version selects the highest protocol -version supported. The higher the protocol used, the more recent the -version of Python needed to read the pickle produced. - -The *file* argument must have a write() method that accepts a single -bytes argument. It can thus be a file object opened for binary -writing, an io.BytesIO instance, or any other custom object that meets -this interface. - -If *fix_imports* is True and protocol is less than 3, pickle will try -to map the new Python 3 names to the old module names used in Python -2, so that the pickle data stream is readable with Python 2. - -If *buffer_callback* is None (the default), buffer views are -serialized into *file* as part of the pickle stream. - -If *buffer_callback* is not None, then it can be called any number -of times with a buffer view. If the callback returns a false value -(such as None), the given buffer is out-of-band; otherwise the -buffer is serialized in-band, i.e. inside the pickle stream. - -It is an error if *buffer_callback* is not None and *protocol* -is None or smaller than 5. - -[clinic start generated code]*/ - -static int -_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, - PyObject *protocol, int fix_imports, - PyObject *buffer_callback) -/*[clinic end generated code: output=0abedc50590d259b input=a7c969699bf5dad3]*/ -{ - _Py_IDENTIFIER(persistent_id); - _Py_IDENTIFIER(dispatch_table); - - /* In case of multiple __init__() calls, clear previous content. */ - if (self->write != NULL) - (void)Pickler_clear(self); - - if (_Pickler_SetProtocol(self, protocol, fix_imports) < 0) - return -1; - - if (_Pickler_SetOutputStream(self, file) < 0) - return -1; - - if (_Pickler_SetBufferCallback(self, buffer_callback) < 0) - return -1; - - /* memo and output_buffer may have already been created in _Pickler_New */ - if (self->memo == NULL) { - self->memo = PyMemoTable_New(); - if (self->memo == NULL) - return -1; - } - self->output_len = 0; - if (self->output_buffer == NULL) { - self->max_output_len = WRITE_BUF_SIZE; - self->output_buffer = PyBytes_FromStringAndSize(NULL, - self->max_output_len); - if (self->output_buffer == NULL) - return -1; - } - - self->fast = 0; - self->fast_nesting = 0; - self->fast_memo = NULL; - - if (init_method_ref((PyObject *)self, &PyId_persistent_id, - &self->pers_func, &self->pers_func_self) < 0) - { - return -1; - } - - if (_PyObject_LookupAttrId((PyObject *)self, - &PyId_dispatch_table, &self->dispatch_table) < 0) { - return -1; - } - - return 0; -} - - -/* Define a proxy object for the Pickler's internal memo object. This is to - * avoid breaking code like: - * pickler.memo.clear() - * and - * pickler.memo = saved_memo - * Is this a good idea? Not really, but we don't want to break code that uses - * it. Note that we don't implement the entire mapping API here. This is - * intentional, as these should be treated as black-box implementation details. - */ - -/*[clinic input] -_pickle.PicklerMemoProxy.clear - -Remove all items from memo. -[clinic start generated code]*/ - -static PyObject * -_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self) -/*[clinic end generated code: output=5fb9370d48ae8b05 input=ccc186dacd0f1405]*/ -{ - if (self->pickler->memo) - PyMemoTable_Clear(self->pickler->memo); - Py_RETURN_NONE; -} - -/*[clinic input] -_pickle.PicklerMemoProxy.copy - -Copy the memo to a new object. -[clinic start generated code]*/ - -static PyObject * -_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self) -/*[clinic end generated code: output=bb83a919d29225ef input=b73043485ac30b36]*/ -{ - PyMemoTable *memo; - PyObject *new_memo = PyDict_New(); - if (new_memo == NULL) - return NULL; - - memo = self->pickler->memo; - for (size_t i = 0; i < memo->mt_allocated; ++i) { - PyMemoEntry entry = memo->mt_table[i]; - if (entry.me_key != NULL) { - int status; - PyObject *key, *value; - - key = PyLong_FromVoidPtr(entry.me_key); - value = Py_BuildValue("nO", entry.me_value, entry.me_key); - - if (key == NULL || value == NULL) { - Py_XDECREF(key); - Py_XDECREF(value); - goto error; - } - status = PyDict_SetItem(new_memo, key, value); - Py_DECREF(key); - Py_DECREF(value); - if (status < 0) - goto error; - } - } - return new_memo; - - error: - Py_XDECREF(new_memo); - return NULL; -} - -/*[clinic input] -_pickle.PicklerMemoProxy.__reduce__ - -Implement pickle support. -[clinic start generated code]*/ - -static PyObject * -_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) -/*[clinic end generated code: output=bebba1168863ab1d input=2f7c540e24b7aae4]*/ -{ - PyObject *reduce_value, *dict_args; - PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self); - if (contents == NULL) - return NULL; - - reduce_value = PyTuple_New(2); - if (reduce_value == NULL) { - Py_DECREF(contents); - return NULL; - } - dict_args = PyTuple_New(1); - if (dict_args == NULL) { - Py_DECREF(contents); - Py_DECREF(reduce_value); - return NULL; - } - PyTuple_SET_ITEM(dict_args, 0, contents); - Py_INCREF((PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 1, dict_args); - return reduce_value; -} - -static PyMethodDef picklerproxy_methods[] = { - _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF - _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF - _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static void -PicklerMemoProxy_dealloc(PicklerMemoProxyObject *self) -{ - PyObject_GC_UnTrack(self); - Py_XDECREF(self->pickler); - PyObject_GC_Del((PyObject *)self); -} - -static int -PicklerMemoProxy_traverse(PicklerMemoProxyObject *self, - visitproc visit, void *arg) -{ - Py_VISIT(self->pickler); - return 0; -} - -static int -PicklerMemoProxy_clear(PicklerMemoProxyObject *self) -{ - Py_CLEAR(self->pickler); - return 0; -} - -static PyTypeObject PicklerMemoProxyType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.PicklerMemoProxy", /*tp_name*/ - sizeof(PicklerMemoProxyObject), /*tp_basicsize*/ - 0, - (destructor)PicklerMemoProxy_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - 0, /* tp_doc */ - (traverseproc)PicklerMemoProxy_traverse, /* tp_traverse */ - (inquiry)PicklerMemoProxy_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - picklerproxy_methods, /* tp_methods */ -}; - -static PyObject * -PicklerMemoProxy_New(PicklerObject *pickler) -{ - PicklerMemoProxyObject *self; - - self = PyObject_GC_New(PicklerMemoProxyObject, &PicklerMemoProxyType); - if (self == NULL) - return NULL; - Py_INCREF(pickler); - self->pickler = pickler; - PyObject_GC_Track(self); - return (PyObject *)self; -} - -/*****************************************************************************/ - -static PyObject * -Pickler_get_memo(PicklerObject *self, void *Py_UNUSED(ignored)) -{ - return PicklerMemoProxy_New(self); -} - -static int -Pickler_set_memo(PicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored)) -{ - PyMemoTable *new_memo = NULL; - - if (obj == NULL) { - PyErr_SetString(PyExc_TypeError, - "attribute deletion is not supported"); - return -1; - } - - if (Py_IS_TYPE(obj, &PicklerMemoProxyType)) { - PicklerObject *pickler = - ((PicklerMemoProxyObject *)obj)->pickler; - - new_memo = PyMemoTable_Copy(pickler->memo); - if (new_memo == NULL) - return -1; - } - else if (PyDict_Check(obj)) { - Py_ssize_t i = 0; - PyObject *key, *value; - - new_memo = PyMemoTable_New(); - if (new_memo == NULL) - return -1; - - while (PyDict_Next(obj, &i, &key, &value)) { - Py_ssize_t memo_id; - PyObject *memo_obj; - - if (!PyTuple_Check(value) || PyTuple_GET_SIZE(value) != 2) { - PyErr_SetString(PyExc_TypeError, - "'memo' values must be 2-item tuples"); - goto error; - } - memo_id = PyLong_AsSsize_t(PyTuple_GET_ITEM(value, 0)); - if (memo_id == -1 && PyErr_Occurred()) - goto error; - memo_obj = PyTuple_GET_ITEM(value, 1); - if (PyMemoTable_Set(new_memo, memo_obj, memo_id) < 0) - goto error; - } - } - else { - PyErr_Format(PyExc_TypeError, - "'memo' attribute must be a PicklerMemoProxy object " - "or dict, not %.200s", Py_TYPE(obj)->tp_name); - return -1; - } - - PyMemoTable_Del(self->memo); - self->memo = new_memo; - - return 0; - - error: - if (new_memo) - PyMemoTable_Del(new_memo); - return -1; -} - -static PyObject * -Pickler_get_persid(PicklerObject *self, void *Py_UNUSED(ignored)) -{ - if (self->pers_func == NULL) { - PyErr_SetString(PyExc_AttributeError, "persistent_id"); - return NULL; - } - return reconstruct_method(self->pers_func, self->pers_func_self); -} - -static int -Pickler_set_persid(PicklerObject *self, PyObject *value, void *Py_UNUSED(ignored)) -{ - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "attribute deletion is not supported"); - return -1; - } - if (!PyCallable_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "persistent_id must be a callable taking one argument"); - return -1; - } - - self->pers_func_self = NULL; - Py_INCREF(value); - Py_XSETREF(self->pers_func, value); - - return 0; -} - -static PyMemberDef Pickler_members[] = { - {"bin", T_INT, offsetof(PicklerObject, bin)}, - {"fast", T_INT, offsetof(PicklerObject, fast)}, - {"dispatch_table", T_OBJECT_EX, offsetof(PicklerObject, dispatch_table)}, - {NULL} -}; - -static PyGetSetDef Pickler_getsets[] = { - {"memo", (getter)Pickler_get_memo, - (setter)Pickler_set_memo}, - {"persistent_id", (getter)Pickler_get_persid, - (setter)Pickler_set_persid}, - {NULL} -}; - -static PyTypeObject Pickler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.Pickler" , /*tp_name*/ - sizeof(PicklerObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)Pickler_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - _pickle_Pickler___init____doc__, /*tp_doc*/ - (traverseproc)Pickler_traverse, /*tp_traverse*/ - (inquiry)Pickler_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - Pickler_methods, /*tp_methods*/ - Pickler_members, /*tp_members*/ - Pickler_getsets, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - _pickle_Pickler___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - PyType_GenericNew, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ - 0, /*tp_is_gc*/ -}; - -/* Temporary helper for calling self.find_class(). - - XXX: It would be nice to able to avoid Python function call overhead, by - using directly the C version of find_class(), when find_class() is not - overridden by a subclass. Although, this could become rather hackish. A - simpler optimization would be to call the C function when self is not a - subclass instance. */ -static PyObject * -find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) -{ - _Py_IDENTIFIER(find_class); - - return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_find_class, - module_name, global_name, NULL); -} - -static Py_ssize_t -marker(UnpicklerObject *self) -{ - Py_ssize_t mark; - - if (self->num_marks < 1) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, "could not find MARK"); - return -1; - } - - mark = self->marks[--self->num_marks]; - self->stack->mark_set = self->num_marks != 0; - self->stack->fence = self->num_marks ? - self->marks[self->num_marks - 1] : 0; - return mark; -} - -static int -load_none(UnpicklerObject *self) -{ - PDATA_APPEND(self->stack, Py_None, -1); - return 0; -} - -static int -load_int(UnpicklerObject *self) -{ - PyObject *value; - char *endptr, *s; - Py_ssize_t len; - long x; - - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 2) - return bad_readline(); - - errno = 0; - /* XXX: Should the base argument of strtol() be explicitly set to 10? - XXX(avassalotti): Should this uses PyOS_strtol()? */ - x = strtol(s, &endptr, 0); - - if (errno || (*endptr != '\n' && *endptr != '\0')) { - /* Hm, maybe we've got something long. Let's try reading - * it as a Python int object. */ - errno = 0; - /* XXX: Same thing about the base here. */ - value = PyLong_FromString(s, NULL, 0); - if (value == NULL) { - PyErr_SetString(PyExc_ValueError, - "could not convert string to int"); - return -1; - } - } - else { - if (len == 3 && (x == 0 || x == 1)) { - if ((value = PyBool_FromLong(x)) == NULL) - return -1; - } - else { - if ((value = PyLong_FromLong(x)) == NULL) - return -1; - } - } - - PDATA_PUSH(self->stack, value, -1); - return 0; -} - -static int -load_bool(UnpicklerObject *self, PyObject *boolean) -{ - assert(boolean == Py_True || boolean == Py_False); - PDATA_APPEND(self->stack, boolean, -1); - return 0; -} - -/* s contains x bytes of an unsigned little-endian integer. Return its value - * as a C Py_ssize_t, or -1 if it's higher than PY_SSIZE_T_MAX. - */ -static Py_ssize_t -calc_binsize(char *bytes, int nbytes) -{ - unsigned char *s = (unsigned char *)bytes; - int i; - size_t x = 0; - - if (nbytes > (int)sizeof(size_t)) { - /* Check for integer overflow. BINBYTES8 and BINUNICODE8 opcodes - * have 64-bit size that can't be represented on 32-bit platform. - */ - for (i = (int)sizeof(size_t); i < nbytes; i++) { - if (s[i]) - return -1; - } - nbytes = (int)sizeof(size_t); - } - for (i = 0; i < nbytes; i++) { - x |= (size_t) s[i] << (8 * i); - } - - if (x > PY_SSIZE_T_MAX) - return -1; - else - return (Py_ssize_t) x; -} - -/* s contains x bytes of a little-endian integer. Return its value as a - * C int. Obscure: when x is 1 or 2, this is an unsigned little-endian - * int, but when x is 4 it's a signed one. This is a historical source - * of x-platform bugs. - */ -static long -calc_binint(char *bytes, int nbytes) -{ - unsigned char *s = (unsigned char *)bytes; - Py_ssize_t i; - long x = 0; - - for (i = 0; i < nbytes; i++) { - x |= (long)s[i] << (8 * i); - } - - /* Unlike BININT1 and BININT2, BININT (more accurately BININT4) - * is signed, so on a box with longs bigger than 4 bytes we need - * to extend a BININT's sign bit to the full width. - */ - if (SIZEOF_LONG > 4 && nbytes == 4) { - x |= -(x & (1L << 31)); - } - - return x; -} - -static int -load_binintx(UnpicklerObject *self, char *s, int size) -{ - PyObject *value; - long x; - - x = calc_binint(s, size); - - if ((value = PyLong_FromLong(x)) == NULL) - return -1; - - PDATA_PUSH(self->stack, value, -1); - return 0; -} - -static int -load_binint(UnpicklerObject *self) -{ - char *s; - - if (_Unpickler_Read(self, &s, 4) < 0) - return -1; - - return load_binintx(self, s, 4); -} - -static int -load_binint1(UnpicklerObject *self) -{ - char *s; - - if (_Unpickler_Read(self, &s, 1) < 0) - return -1; - - return load_binintx(self, s, 1); -} - -static int -load_binint2(UnpicklerObject *self) -{ - char *s; - - if (_Unpickler_Read(self, &s, 2) < 0) - return -1; - - return load_binintx(self, s, 2); -} - -static int -load_long(UnpicklerObject *self) -{ - PyObject *value; - char *s = NULL; - Py_ssize_t len; - - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 2) - return bad_readline(); - - /* s[len-2] will usually be 'L' (and s[len-1] is '\n'); we need to remove - the 'L' before calling PyLong_FromString. In order to maintain - compatibility with Python 3.0.0, we don't actually *require* - the 'L' to be present. */ - if (s[len-2] == 'L') - s[len-2] = '\0'; - /* XXX: Should the base argument explicitly set to 10? */ - value = PyLong_FromString(s, NULL, 0); - if (value == NULL) - return -1; - - PDATA_PUSH(self->stack, value, -1); - return 0; -} - -/* 'size' bytes contain the # of bytes of little-endian 256's-complement - * data following. - */ -static int -load_counted_long(UnpicklerObject *self, int size) -{ - PyObject *value; - char *nbytes; - char *pdata; - - assert(size == 1 || size == 4); - if (_Unpickler_Read(self, &nbytes, size) < 0) - return -1; - - size = calc_binint(nbytes, size); - if (size < 0) { - PickleState *st = _Pickle_GetGlobalState(); - /* Corrupt or hostile pickle -- we never write one like this */ - PyErr_SetString(st->UnpicklingError, - "LONG pickle has negative byte count"); - return -1; - } - - if (size == 0) - value = PyLong_FromLong(0L); - else { - /* Read the raw little-endian bytes and convert. */ - if (_Unpickler_Read(self, &pdata, size) < 0) - return -1; - value = _PyLong_FromByteArray((unsigned char *)pdata, (size_t)size, - 1 /* little endian */ , 1 /* signed */ ); - } - if (value == NULL) - return -1; - PDATA_PUSH(self->stack, value, -1); - return 0; -} - -static int -load_float(UnpicklerObject *self) -{ - PyObject *value; - char *endptr, *s; - Py_ssize_t len; - double d; - - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 2) - return bad_readline(); - - errno = 0; - d = PyOS_string_to_double(s, &endptr, PyExc_OverflowError); - if (d == -1.0 && PyErr_Occurred()) - return -1; - if ((endptr[0] != '\n') && (endptr[0] != '\0')) { - PyErr_SetString(PyExc_ValueError, "could not convert string to float"); - return -1; - } - value = PyFloat_FromDouble(d); - if (value == NULL) - return -1; - - PDATA_PUSH(self->stack, value, -1); - return 0; -} - -static int -load_binfloat(UnpicklerObject *self) -{ - PyObject *value; - double x; - char *s; - - if (_Unpickler_Read(self, &s, 8) < 0) - return -1; - - x = _PyFloat_Unpack8((unsigned char *)s, 0); - if (x == -1.0 && PyErr_Occurred()) - return -1; - - if ((value = PyFloat_FromDouble(x)) == NULL) - return -1; - - PDATA_PUSH(self->stack, value, -1); - return 0; -} - -static int -load_string(UnpicklerObject *self) -{ - PyObject *bytes; - PyObject *obj; - Py_ssize_t len; - char *s, *p; - - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - /* Strip the newline */ - len--; - /* Strip outermost quotes */ - if (len >= 2 && s[0] == s[len - 1] && (s[0] == '\'' || s[0] == '"')) { - p = s + 1; - len -= 2; - } - else { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, - "the STRING opcode argument must be quoted"); - return -1; - } - assert(len >= 0); - - /* Use the PyBytes API to decode the string, since that is what is used - to encode, and then coerce the result to Unicode. */ - bytes = PyBytes_DecodeEscape(p, len, NULL, 0, NULL); - if (bytes == NULL) - return -1; - - /* Leave the Python 2.x strings as bytes if the *encoding* given to the - Unpickler was 'bytes'. Otherwise, convert them to unicode. */ - if (strcmp(self->encoding, "bytes") == 0) { - obj = bytes; - } - else { - obj = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors); - Py_DECREF(bytes); - if (obj == NULL) { - return -1; - } - } - - PDATA_PUSH(self->stack, obj, -1); - return 0; -} - -static int -load_counted_binstring(UnpicklerObject *self, int nbytes) -{ - PyObject *obj; - Py_ssize_t size; - char *s; - - if (_Unpickler_Read(self, &s, nbytes) < 0) - return -1; - - size = calc_binsize(s, nbytes); - if (size < 0) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->UnpicklingError, - "BINSTRING exceeds system's maximum size of %zd bytes", - PY_SSIZE_T_MAX); - return -1; - } - - if (_Unpickler_Read(self, &s, size) < 0) - return -1; - - /* Convert Python 2.x strings to bytes if the *encoding* given to the - Unpickler was 'bytes'. Otherwise, convert them to unicode. */ - if (strcmp(self->encoding, "bytes") == 0) { - obj = PyBytes_FromStringAndSize(s, size); - } - else { - obj = PyUnicode_Decode(s, size, self->encoding, self->errors); - } - if (obj == NULL) { - return -1; - } - - PDATA_PUSH(self->stack, obj, -1); - return 0; -} - -static int -load_counted_binbytes(UnpicklerObject *self, int nbytes) -{ - PyObject *bytes; - Py_ssize_t size; - char *s; - - if (_Unpickler_Read(self, &s, nbytes) < 0) - return -1; - - size = calc_binsize(s, nbytes); - if (size < 0) { - PyErr_Format(PyExc_OverflowError, - "BINBYTES exceeds system's maximum size of %zd bytes", - PY_SSIZE_T_MAX); - return -1; - } - - bytes = PyBytes_FromStringAndSize(NULL, size); - if (bytes == NULL) - return -1; - if (_Unpickler_ReadInto(self, PyBytes_AS_STRING(bytes), size) < 0) { - Py_DECREF(bytes); - return -1; - } - - PDATA_PUSH(self->stack, bytes, -1); - return 0; -} - -static int -load_counted_bytearray(UnpicklerObject *self) -{ - PyObject *bytearray; - Py_ssize_t size; - char *s; - - if (_Unpickler_Read(self, &s, 8) < 0) { - return -1; - } - - size = calc_binsize(s, 8); - if (size < 0) { - PyErr_Format(PyExc_OverflowError, - "BYTEARRAY8 exceeds system's maximum size of %zd bytes", - PY_SSIZE_T_MAX); - return -1; - } - - bytearray = PyByteArray_FromStringAndSize(NULL, size); - if (bytearray == NULL) { - return -1; - } - if (_Unpickler_ReadInto(self, PyByteArray_AS_STRING(bytearray), size) < 0) { - Py_DECREF(bytearray); - return -1; - } - - PDATA_PUSH(self->stack, bytearray, -1); - return 0; -} - -static int -load_next_buffer(UnpicklerObject *self) -{ - if (self->buffers == NULL) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, - "pickle stream refers to out-of-band data " - "but no *buffers* argument was given"); - return -1; - } - PyObject *buf = PyIter_Next(self->buffers); - if (buf == NULL) { - if (!PyErr_Occurred()) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, - "not enough out-of-band buffers"); - } - return -1; - } - - PDATA_PUSH(self->stack, buf, -1); - return 0; -} - -static int -load_readonly_buffer(UnpicklerObject *self) -{ - Py_ssize_t len = Py_SIZE(self->stack); - if (len <= self->stack->fence) { - return Pdata_stack_underflow(self->stack); - } - - PyObject *obj = self->stack->data[len - 1]; - PyObject *view = PyMemoryView_FromObject(obj); - if (view == NULL) { - return -1; - } - if (!PyMemoryView_GET_BUFFER(view)->readonly) { - /* Original object is writable */ - PyMemoryView_GET_BUFFER(view)->readonly = 1; - self->stack->data[len - 1] = view; - Py_DECREF(obj); - } - else { - /* Original object is read-only, no need to replace it */ - Py_DECREF(view); - } - return 0; -} - -static int -load_unicode(UnpicklerObject *self) -{ - PyObject *str; - Py_ssize_t len; - char *s = NULL; - - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 1) - return bad_readline(); - - str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL); - if (str == NULL) - return -1; - - PDATA_PUSH(self->stack, str, -1); - return 0; -} - -static int -load_counted_binunicode(UnpicklerObject *self, int nbytes) -{ - PyObject *str; - Py_ssize_t size; - char *s; - - if (_Unpickler_Read(self, &s, nbytes) < 0) - return -1; - - size = calc_binsize(s, nbytes); - if (size < 0) { - PyErr_Format(PyExc_OverflowError, - "BINUNICODE exceeds system's maximum size of %zd bytes", - PY_SSIZE_T_MAX); - return -1; - } - - if (_Unpickler_Read(self, &s, size) < 0) - return -1; - - str = PyUnicode_DecodeUTF8(s, size, "surrogatepass"); - if (str == NULL) - return -1; - - PDATA_PUSH(self->stack, str, -1); - return 0; -} - -static int -load_counted_tuple(UnpicklerObject *self, Py_ssize_t len) -{ - PyObject *tuple; - - if (Py_SIZE(self->stack) < len) - return Pdata_stack_underflow(self->stack); - - tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len); - if (tuple == NULL) - return -1; - PDATA_PUSH(self->stack, tuple, -1); - return 0; -} - -static int -load_tuple(UnpicklerObject *self) -{ - Py_ssize_t i; - - if ((i = marker(self)) < 0) - return -1; - - return load_counted_tuple(self, Py_SIZE(self->stack) - i); -} - -static int -load_empty_list(UnpicklerObject *self) -{ - PyObject *list; - - if ((list = PyList_New(0)) == NULL) - return -1; - PDATA_PUSH(self->stack, list, -1); - return 0; -} - -static int -load_empty_dict(UnpicklerObject *self) -{ - PyObject *dict; - - if ((dict = PyDict_New()) == NULL) - return -1; - PDATA_PUSH(self->stack, dict, -1); - return 0; -} - -static int -load_empty_set(UnpicklerObject *self) -{ - PyObject *set; - - if ((set = PySet_New(NULL)) == NULL) - return -1; - PDATA_PUSH(self->stack, set, -1); - return 0; -} - -static int -load_list(UnpicklerObject *self) -{ - PyObject *list; - Py_ssize_t i; - - if ((i = marker(self)) < 0) - return -1; - - list = Pdata_poplist(self->stack, i); - if (list == NULL) - return -1; - PDATA_PUSH(self->stack, list, -1); - return 0; -} - -static int -load_dict(UnpicklerObject *self) -{ - PyObject *dict, *key, *value; - Py_ssize_t i, j, k; - - if ((i = marker(self)) < 0) - return -1; - j = Py_SIZE(self->stack); - - if ((dict = PyDict_New()) == NULL) - return -1; - - if ((j - i) % 2 != 0) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, "odd number of items for DICT"); - Py_DECREF(dict); - return -1; - } - - for (k = i + 1; k < j; k += 2) { - key = self->stack->data[k - 1]; - value = self->stack->data[k]; - if (PyDict_SetItem(dict, key, value) < 0) { - Py_DECREF(dict); - return -1; - } - } - Pdata_clear(self->stack, i); - PDATA_PUSH(self->stack, dict, -1); - return 0; -} - -static int -load_frozenset(UnpicklerObject *self) -{ - PyObject *items; - PyObject *frozenset; - Py_ssize_t i; - - if ((i = marker(self)) < 0) - return -1; - - items = Pdata_poptuple(self->stack, i); - if (items == NULL) - return -1; - - frozenset = PyFrozenSet_New(items); - Py_DECREF(items); - if (frozenset == NULL) - return -1; - - PDATA_PUSH(self->stack, frozenset, -1); - return 0; -} - -static PyObject * -instantiate(PyObject *cls, PyObject *args) -{ - /* Caller must assure args are a tuple. Normally, args come from - Pdata_poptuple which packs objects from the top of the stack - into a newly created tuple. */ - assert(PyTuple_Check(args)); - if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) { - _Py_IDENTIFIER(__getinitargs__); - _Py_IDENTIFIER(__new__); - PyObject *func; - if (_PyObject_LookupAttrId(cls, &PyId___getinitargs__, &func) < 0) { - return NULL; - } - if (func == NULL) { - return _PyObject_CallMethodIdOneArg(cls, &PyId___new__, cls); - } - Py_DECREF(func); - } - return PyObject_CallObject(cls, args); -} - -static int -load_obj(UnpicklerObject *self) -{ - PyObject *cls, *args, *obj = NULL; - Py_ssize_t i; - - if ((i = marker(self)) < 0) - return -1; - - if (Py_SIZE(self->stack) - i < 1) - return Pdata_stack_underflow(self->stack); - - args = Pdata_poptuple(self->stack, i + 1); - if (args == NULL) - return -1; - - PDATA_POP(self->stack, cls); - if (cls) { - obj = instantiate(cls, args); - Py_DECREF(cls); - } - Py_DECREF(args); - if (obj == NULL) - return -1; - - PDATA_PUSH(self->stack, obj, -1); - return 0; -} - -static int -load_inst(UnpicklerObject *self) -{ - PyObject *cls = NULL; - PyObject *args = NULL; - PyObject *obj = NULL; - PyObject *module_name; - PyObject *class_name; - Py_ssize_t len; - Py_ssize_t i; - char *s; - - if ((i = marker(self)) < 0) - return -1; - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 2) - return bad_readline(); - - /* Here it is safe to use PyUnicode_DecodeASCII(), even though non-ASCII - identifiers are permitted in Python 3.0, since the INST opcode is only - supported by older protocols on Python 2.x. */ - module_name = PyUnicode_DecodeASCII(s, len - 1, "strict"); - if (module_name == NULL) - return -1; - - if ((len = _Unpickler_Readline(self, &s)) >= 0) { - if (len < 2) { - Py_DECREF(module_name); - return bad_readline(); - } - class_name = PyUnicode_DecodeASCII(s, len - 1, "strict"); - if (class_name != NULL) { - cls = find_class(self, module_name, class_name); - Py_DECREF(class_name); - } - } - Py_DECREF(module_name); - - if (cls == NULL) - return -1; - - if ((args = Pdata_poptuple(self->stack, i)) != NULL) { - obj = instantiate(cls, args); - Py_DECREF(args); - } - Py_DECREF(cls); - - if (obj == NULL) - return -1; - - PDATA_PUSH(self->stack, obj, -1); - return 0; -} - -static int -load_newobj(UnpicklerObject *self) -{ - PyObject *args = NULL; - PyObject *clsraw = NULL; - PyTypeObject *cls; /* clsraw cast to its true type */ - PyObject *obj; - PickleState *st = _Pickle_GetGlobalState(); - - /* Stack is ... cls argtuple, and we want to call - * cls.__new__(cls, *argtuple). - */ - PDATA_POP(self->stack, args); - if (args == NULL) - goto error; - if (!PyTuple_Check(args)) { - PyErr_SetString(st->UnpicklingError, - "NEWOBJ expected an arg " "tuple."); - goto error; - } - - PDATA_POP(self->stack, clsraw); - cls = (PyTypeObject *)clsraw; - if (cls == NULL) - goto error; - if (!PyType_Check(cls)) { - PyErr_SetString(st->UnpicklingError, "NEWOBJ class argument " - "isn't a type object"); - goto error; - } - if (cls->tp_new == NULL) { - PyErr_SetString(st->UnpicklingError, "NEWOBJ class argument " - "has NULL tp_new"); - goto error; - } - - /* Call __new__. */ - obj = cls->tp_new(cls, args, NULL); - if (obj == NULL) - goto error; - - Py_DECREF(args); - Py_DECREF(clsraw); - PDATA_PUSH(self->stack, obj, -1); - return 0; - - error: - Py_XDECREF(args); - Py_XDECREF(clsraw); - return -1; -} - -static int -load_newobj_ex(UnpicklerObject *self) -{ - PyObject *cls, *args, *kwargs; - PyObject *obj; - PickleState *st = _Pickle_GetGlobalState(); - - PDATA_POP(self->stack, kwargs); - if (kwargs == NULL) { - return -1; - } - PDATA_POP(self->stack, args); - if (args == NULL) { - Py_DECREF(kwargs); - return -1; - } - PDATA_POP(self->stack, cls); - if (cls == NULL) { - Py_DECREF(kwargs); - Py_DECREF(args); - return -1; - } - - if (!PyType_Check(cls)) { - PyErr_Format(st->UnpicklingError, - "NEWOBJ_EX class argument must be a type, not %.200s", - Py_TYPE(cls)->tp_name); - goto error; - } - - if (((PyTypeObject *)cls)->tp_new == NULL) { - PyErr_SetString(st->UnpicklingError, - "NEWOBJ_EX class argument doesn't have __new__"); - goto error; - } - if (!PyTuple_Check(args)) { - PyErr_Format(st->UnpicklingError, - "NEWOBJ_EX args argument must be a tuple, not %.200s", - Py_TYPE(args)->tp_name); - goto error; - } - if (!PyDict_Check(kwargs)) { - PyErr_Format(st->UnpicklingError, - "NEWOBJ_EX kwargs argument must be a dict, not %.200s", - Py_TYPE(kwargs)->tp_name); - goto error; - } - - obj = ((PyTypeObject *)cls)->tp_new((PyTypeObject *)cls, args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(args); - Py_DECREF(cls); - if (obj == NULL) { - return -1; - } - PDATA_PUSH(self->stack, obj, -1); - return 0; - -error: - Py_DECREF(kwargs); - Py_DECREF(args); - Py_DECREF(cls); - return -1; -} - -static int -load_global(UnpicklerObject *self) -{ - PyObject *global = NULL; - PyObject *module_name; - PyObject *global_name; - Py_ssize_t len; - char *s; - - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 2) - return bad_readline(); - module_name = PyUnicode_DecodeUTF8(s, len - 1, "strict"); - if (!module_name) - return -1; - - if ((len = _Unpickler_Readline(self, &s)) >= 0) { - if (len < 2) { - Py_DECREF(module_name); - return bad_readline(); - } - global_name = PyUnicode_DecodeUTF8(s, len - 1, "strict"); - if (global_name) { - global = find_class(self, module_name, global_name); - Py_DECREF(global_name); - } - } - Py_DECREF(module_name); - - if (global == NULL) - return -1; - PDATA_PUSH(self->stack, global, -1); - return 0; -} - -static int -load_stack_global(UnpicklerObject *self) -{ - PyObject *global; - PyObject *module_name; - PyObject *global_name; - - PDATA_POP(self->stack, global_name); - PDATA_POP(self->stack, module_name); - if (module_name == NULL || !PyUnicode_CheckExact(module_name) || - global_name == NULL || !PyUnicode_CheckExact(global_name)) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, "STACK_GLOBAL requires str"); - Py_XDECREF(global_name); - Py_XDECREF(module_name); - return -1; - } - global = find_class(self, module_name, global_name); - Py_DECREF(global_name); - Py_DECREF(module_name); - if (global == NULL) - return -1; - PDATA_PUSH(self->stack, global, -1); - return 0; -} - -static int -load_persid(UnpicklerObject *self) -{ - PyObject *pid, *obj; - Py_ssize_t len; - char *s; - - if (self->pers_func) { - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 1) - return bad_readline(); - - pid = PyUnicode_DecodeASCII(s, len - 1, "strict"); - if (pid == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { - PyErr_SetString(_Pickle_GetGlobalState()->UnpicklingError, - "persistent IDs in protocol 0 must be " - "ASCII strings"); - } - return -1; - } - - obj = call_method(self->pers_func, self->pers_func_self, pid); - Py_DECREF(pid); - if (obj == NULL) - return -1; - - PDATA_PUSH(self->stack, obj, -1); - return 0; - } - else { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, - "A load persistent id instruction was encountered,\n" - "but no persistent_load function was specified."); - return -1; - } -} - -static int -load_binpersid(UnpicklerObject *self) -{ - PyObject *pid, *obj; - - if (self->pers_func) { - PDATA_POP(self->stack, pid); - if (pid == NULL) - return -1; - - obj = call_method(self->pers_func, self->pers_func_self, pid); - Py_DECREF(pid); - if (obj == NULL) - return -1; - - PDATA_PUSH(self->stack, obj, -1); - return 0; - } - else { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, - "A load persistent id instruction was encountered,\n" - "but no persistent_load function was specified."); - return -1; - } -} - -static int -load_pop(UnpicklerObject *self) -{ - Py_ssize_t len = Py_SIZE(self->stack); - - /* Note that we split the (pickle.py) stack into two stacks, - * an object stack and a mark stack. We have to be clever and - * pop the right one. We do this by looking at the top of the - * mark stack first, and only signalling a stack underflow if - * the object stack is empty and the mark stack doesn't match - * our expectations. - */ - if (self->num_marks > 0 && self->marks[self->num_marks - 1] == len) { - self->num_marks--; - self->stack->mark_set = self->num_marks != 0; - self->stack->fence = self->num_marks ? - self->marks[self->num_marks - 1] : 0; - } else if (len <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - else { - len--; - Py_DECREF(self->stack->data[len]); - Py_SET_SIZE(self->stack, len); - } - return 0; -} - -static int -load_pop_mark(UnpicklerObject *self) -{ - Py_ssize_t i; - - if ((i = marker(self)) < 0) - return -1; - - Pdata_clear(self->stack, i); - - return 0; -} - -static int -load_dup(UnpicklerObject *self) -{ - PyObject *last; - Py_ssize_t len = Py_SIZE(self->stack); - - if (len <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - last = self->stack->data[len - 1]; - PDATA_APPEND(self->stack, last, -1); - return 0; -} - -static int -load_get(UnpicklerObject *self) -{ - PyObject *key, *value; - Py_ssize_t idx; - Py_ssize_t len; - char *s; - - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 2) - return bad_readline(); - - key = PyLong_FromString(s, NULL, 10); - if (key == NULL) - return -1; - idx = PyLong_AsSsize_t(key); - if (idx == -1 && PyErr_Occurred()) { - Py_DECREF(key); - return -1; - } - - value = _Unpickler_MemoGet(self, idx); - if (value == NULL) { - if (!PyErr_Occurred()) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); - } - Py_DECREF(key); - return -1; - } - Py_DECREF(key); - - PDATA_APPEND(self->stack, value, -1); - return 0; -} - -static int -load_binget(UnpicklerObject *self) -{ - PyObject *value; - Py_ssize_t idx; - char *s; - - if (_Unpickler_Read(self, &s, 1) < 0) - return -1; - - idx = Py_CHARMASK(s[0]); - - value = _Unpickler_MemoGet(self, idx); - if (value == NULL) { - PyObject *key = PyLong_FromSsize_t(idx); - if (key != NULL) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); - Py_DECREF(key); - } - return -1; - } - - PDATA_APPEND(self->stack, value, -1); - return 0; -} - -static int -load_long_binget(UnpicklerObject *self) -{ - PyObject *value; - Py_ssize_t idx; - char *s; - - if (_Unpickler_Read(self, &s, 4) < 0) - return -1; - - idx = calc_binsize(s, 4); - - value = _Unpickler_MemoGet(self, idx); - if (value == NULL) { - PyObject *key = PyLong_FromSsize_t(idx); - if (key != NULL) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); - Py_DECREF(key); - } - return -1; - } - - PDATA_APPEND(self->stack, value, -1); - return 0; -} - -/* Push an object from the extension registry (EXT[124]). nbytes is - * the number of bytes following the opcode, holding the index (code) value. - */ -static int -load_extension(UnpicklerObject *self, int nbytes) -{ - char *codebytes; /* the nbytes bytes after the opcode */ - long code; /* calc_binint returns long */ - PyObject *py_code; /* code as a Python int */ - PyObject *obj; /* the object to push */ - PyObject *pair; /* (module_name, class_name) */ - PyObject *module_name, *class_name; - PickleState *st = _Pickle_GetGlobalState(); - - assert(nbytes == 1 || nbytes == 2 || nbytes == 4); - if (_Unpickler_Read(self, &codebytes, nbytes) < 0) - return -1; - code = calc_binint(codebytes, nbytes); - if (code <= 0) { /* note that 0 is forbidden */ - /* Corrupt or hostile pickle. */ - PyErr_SetString(st->UnpicklingError, "EXT specifies code <= 0"); - return -1; - } - - /* Look for the code in the cache. */ - py_code = PyLong_FromLong(code); - if (py_code == NULL) - return -1; - obj = PyDict_GetItemWithError(st->extension_cache, py_code); - if (obj != NULL) { - /* Bingo. */ - Py_DECREF(py_code); - PDATA_APPEND(self->stack, obj, -1); - return 0; - } - if (PyErr_Occurred()) { - Py_DECREF(py_code); - return -1; - } - - /* Look up the (module_name, class_name) pair. */ - pair = PyDict_GetItemWithError(st->inverted_registry, py_code); - if (pair == NULL) { - Py_DECREF(py_code); - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_ValueError, "unregistered extension " - "code %ld", code); - } - return -1; - } - /* Since the extension registry is manipulable via Python code, - * confirm that pair is really a 2-tuple of strings. - */ - if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2) { - goto error; - } - - module_name = PyTuple_GET_ITEM(pair, 0); - if (!PyUnicode_Check(module_name)) { - goto error; - } - - class_name = PyTuple_GET_ITEM(pair, 1); - if (!PyUnicode_Check(class_name)) { - goto error; - } - - /* Load the object. */ - obj = find_class(self, module_name, class_name); - if (obj == NULL) { - Py_DECREF(py_code); - return -1; - } - /* Cache code -> obj. */ - code = PyDict_SetItem(st->extension_cache, py_code, obj); - Py_DECREF(py_code); - if (code < 0) { - Py_DECREF(obj); - return -1; - } - PDATA_PUSH(self->stack, obj, -1); - return 0; - -error: - Py_DECREF(py_code); - PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] " - "isn't a 2-tuple of strings", code); - return -1; -} - -static int -load_put(UnpicklerObject *self) -{ - PyObject *key, *value; - Py_ssize_t idx; - Py_ssize_t len; - char *s = NULL; - - if ((len = _Unpickler_Readline(self, &s)) < 0) - return -1; - if (len < 2) - return bad_readline(); - if (Py_SIZE(self->stack) <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - value = self->stack->data[Py_SIZE(self->stack) - 1]; - - key = PyLong_FromString(s, NULL, 10); - if (key == NULL) - return -1; - idx = PyLong_AsSsize_t(key); - Py_DECREF(key); - if (idx < 0) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_ValueError, - "negative PUT argument"); - return -1; - } - - return _Unpickler_MemoPut(self, idx, value); -} - -static int -load_binput(UnpicklerObject *self) -{ - PyObject *value; - Py_ssize_t idx; - char *s; - - if (_Unpickler_Read(self, &s, 1) < 0) - return -1; - - if (Py_SIZE(self->stack) <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - value = self->stack->data[Py_SIZE(self->stack) - 1]; - - idx = Py_CHARMASK(s[0]); - - return _Unpickler_MemoPut(self, idx, value); -} - -static int -load_long_binput(UnpicklerObject *self) -{ - PyObject *value; - Py_ssize_t idx; - char *s; - - if (_Unpickler_Read(self, &s, 4) < 0) - return -1; - - if (Py_SIZE(self->stack) <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - value = self->stack->data[Py_SIZE(self->stack) - 1]; - - idx = calc_binsize(s, 4); - if (idx < 0) { - PyErr_SetString(PyExc_ValueError, - "negative LONG_BINPUT argument"); - return -1; - } - - return _Unpickler_MemoPut(self, idx, value); -} - -static int -load_memoize(UnpicklerObject *self) -{ - PyObject *value; - - if (Py_SIZE(self->stack) <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - value = self->stack->data[Py_SIZE(self->stack) - 1]; - - return _Unpickler_MemoPut(self, self->memo_len, value); -} - -static int -do_append(UnpicklerObject *self, Py_ssize_t x) -{ - PyObject *value; - PyObject *slice; - PyObject *list; - PyObject *result; - Py_ssize_t len, i; - - len = Py_SIZE(self->stack); - if (x > len || x <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - if (len == x) /* nothing to do */ - return 0; - - list = self->stack->data[x - 1]; - - if (PyList_CheckExact(list)) { - Py_ssize_t list_len; - int ret; - - slice = Pdata_poplist(self->stack, x); - if (!slice) - return -1; - list_len = PyList_GET_SIZE(list); - ret = PyList_SetSlice(list, list_len, list_len, slice); - Py_DECREF(slice); - return ret; - } - else { - PyObject *extend_func; - _Py_IDENTIFIER(extend); - - if (_PyObject_LookupAttrId(list, &PyId_extend, &extend_func) < 0) { - return -1; - } - if (extend_func != NULL) { - slice = Pdata_poplist(self->stack, x); - if (!slice) { - Py_DECREF(extend_func); - return -1; - } - result = _Pickle_FastCall(extend_func, slice); - Py_DECREF(extend_func); - if (result == NULL) - return -1; - Py_DECREF(result); - } - else { - PyObject *append_func; - _Py_IDENTIFIER(append); - - /* Even if the PEP 307 requires extend() and append() methods, - fall back on append() if the object has no extend() method - for backward compatibility. */ - append_func = _PyObject_GetAttrId(list, &PyId_append); - if (append_func == NULL) - return -1; - for (i = x; i < len; i++) { - value = self->stack->data[i]; - result = _Pickle_FastCall(append_func, value); - if (result == NULL) { - Pdata_clear(self->stack, i + 1); - Py_SET_SIZE(self->stack, x); - Py_DECREF(append_func); - return -1; - } - Py_DECREF(result); - } - Py_SET_SIZE(self->stack, x); - Py_DECREF(append_func); - } - } - - return 0; -} - -static int -load_append(UnpicklerObject *self) -{ - if (Py_SIZE(self->stack) - 1 <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - return do_append(self, Py_SIZE(self->stack) - 1); -} - -static int -load_appends(UnpicklerObject *self) -{ - Py_ssize_t i = marker(self); - if (i < 0) - return -1; - return do_append(self, i); -} + return 0; +} static int -do_setitems(UnpicklerObject *self, Py_ssize_t x) -{ - PyObject *value, *key; - PyObject *dict; - Py_ssize_t len, i; - int status = 0; - - len = Py_SIZE(self->stack); - if (x > len || x <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - if (len == x) /* nothing to do */ - return 0; - if ((len - x) % 2 != 0) { - PickleState *st = _Pickle_GetGlobalState(); - /* Corrupt or hostile pickle -- we never write one like this. */ - PyErr_SetString(st->UnpicklingError, - "odd number of items for SETITEMS"); - return -1; - } - - /* Here, dict does not actually need to be a PyDict; it could be anything - that supports the __setitem__ attribute. */ - dict = self->stack->data[x - 1]; - - for (i = x + 1; i < len; i += 2) { - key = self->stack->data[i - 1]; - value = self->stack->data[i]; - if (PyObject_SetItem(dict, key, value) < 0) { - status = -1; - break; - } +save_bytes(PicklerObject *self, PyObject *obj) +{ + if (self->proto < 3) { + /* Older pickle protocols do not have an opcode for pickling bytes + objects. Therefore, we need to fake the copy protocol (i.e., + the __reduce__ method) to permit bytes object unpickling. + + Here we use a hack to be compatible with Python 2. Since in Python + 2 'bytes' is just an alias for 'str' (which has different + parameters than the actual bytes object), we use codecs.encode + to create the appropriate 'str' object when unpickled using + Python 2 *and* the appropriate 'bytes' object when unpickled + using Python 3. Again this is a hack and we don't need to do this + with newer protocols. */ + PyObject *reduce_value; + int status; + + if (PyBytes_GET_SIZE(obj) == 0) { + reduce_value = Py_BuildValue("(O())", (PyObject*)&PyBytes_Type); + } + else { + PickleState *st = _Pickle_GetGlobalState(); + PyObject *unicode_str = + PyUnicode_DecodeLatin1(PyBytes_AS_STRING(obj), + PyBytes_GET_SIZE(obj), + "strict"); + _Py_IDENTIFIER(latin1); + + if (unicode_str == NULL) + return -1; + reduce_value = Py_BuildValue("(O(OO))", + st->codecs_encode, unicode_str, + _PyUnicode_FromId(&PyId_latin1)); + Py_DECREF(unicode_str); + } + + if (reduce_value == NULL) + return -1; + + /* save_reduce() will memoize the object automatically. */ + status = save_reduce(self, reduce_value, obj); + Py_DECREF(reduce_value); + return status; + } + else { + return _save_bytes_data(self, obj, PyBytes_AS_STRING(obj), + PyBytes_GET_SIZE(obj)); } - - Pdata_clear(self->stack, x); - return status; -} - -static int -load_setitem(UnpicklerObject *self) -{ - return do_setitems(self, Py_SIZE(self->stack) - 2); -} - -static int -load_setitems(UnpicklerObject *self) -{ - Py_ssize_t i = marker(self); - if (i < 0) - return -1; - return do_setitems(self, i); } - + static int -load_additems(UnpicklerObject *self) +_save_bytearray_data(PicklerObject *self, PyObject *obj, const char *data, + Py_ssize_t size) { - PyObject *set; - Py_ssize_t mark, len, i; - - mark = marker(self); - if (mark < 0) - return -1; - len = Py_SIZE(self->stack); - if (mark > len || mark <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - if (len == mark) /* nothing to do */ - return 0; + assert(self->proto >= 5); - set = self->stack->data[mark - 1]; + char header[9]; + Py_ssize_t len; - if (PySet_Check(set)) { - PyObject *items; - int status; + if (size < 0) + return -1; - items = Pdata_poptuple(self->stack, mark); - if (items == NULL) - return -1; + header[0] = BYTEARRAY8; + _write_size64(header + 1, size); + len = 9; - status = _PySet_Update(set, items); - Py_DECREF(items); - return status; + if (_Pickler_write_bytes(self, header, len, data, size, obj) < 0) { + return -1; } - else { - PyObject *add_func; - _Py_IDENTIFIER(add); - add_func = _PyObject_GetAttrId(set, &PyId_add); - if (add_func == NULL) - return -1; - for (i = mark; i < len; i++) { - PyObject *result; - PyObject *item; - - item = self->stack->data[i]; - result = _Pickle_FastCall(add_func, item); - if (result == NULL) { - Pdata_clear(self->stack, i + 1); - Py_SET_SIZE(self->stack, mark); - return -1; - } - Py_DECREF(result); - } - Py_SET_SIZE(self->stack, mark); + if (memo_put(self, obj) < 0) { + return -1; } return 0; } static int -load_build(UnpicklerObject *self) +save_bytearray(PicklerObject *self, PyObject *obj) { - PyObject *state, *inst, *slotstate; - PyObject *setstate; - int status = 0; - _Py_IDENTIFIER(__setstate__); - - /* Stack is ... instance, state. We want to leave instance at - * the stack top, possibly mutated via instance.__setstate__(state). - */ - if (Py_SIZE(self->stack) - 2 < self->stack->fence) - return Pdata_stack_underflow(self->stack); - - PDATA_POP(self->stack, state); - if (state == NULL) - return -1; - - inst = self->stack->data[Py_SIZE(self->stack) - 1]; - - if (_PyObject_LookupAttrId(inst, &PyId___setstate__, &setstate) < 0) { - Py_DECREF(state); - return -1; - } - if (setstate != NULL) { - PyObject *result; - - /* The explicit __setstate__ is responsible for everything. */ - result = _Pickle_FastCall(setstate, state); - Py_DECREF(setstate); - if (result == NULL) - return -1; - Py_DECREF(result); - return 0; - } - - /* A default __setstate__. First see whether state embeds a - * slot state dict too (a proto 2 addition). - */ - if (PyTuple_Check(state) && PyTuple_GET_SIZE(state) == 2) { - PyObject *tmp = state; - - state = PyTuple_GET_ITEM(tmp, 0); - slotstate = PyTuple_GET_ITEM(tmp, 1); - Py_INCREF(state); - Py_INCREF(slotstate); - Py_DECREF(tmp); - } - else - slotstate = NULL; - - /* Set inst.__dict__ from the state dict (if any). */ - if (state != Py_None) { - PyObject *dict; - PyObject *d_key, *d_value; - Py_ssize_t i; - _Py_IDENTIFIER(__dict__); + if (self->proto < 5) { + /* Older pickle protocols do not have an opcode for pickling + * bytearrays. */ + PyObject *reduce_value = NULL; + int status; - if (!PyDict_Check(state)) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, "state is not a dictionary"); - goto error; + if (PyByteArray_GET_SIZE(obj) == 0) { + reduce_value = Py_BuildValue("(O())", + (PyObject *) &PyByteArray_Type); } - dict = _PyObject_GetAttrId(inst, &PyId___dict__); - if (dict == NULL) - goto error; - - i = 0; - while (PyDict_Next(state, &i, &d_key, &d_value)) { - /* normally the keys for instance attributes are - interned. we should try to do that here. */ - Py_INCREF(d_key); - if (PyUnicode_CheckExact(d_key)) - PyUnicode_InternInPlace(&d_key); - if (PyObject_SetItem(dict, d_key, d_value) < 0) { - Py_DECREF(d_key); - goto error; + else { + PyObject *bytes_obj = PyBytes_FromObject(obj); + if (bytes_obj != NULL) { + reduce_value = Py_BuildValue("(O(O))", + (PyObject *) &PyByteArray_Type, + bytes_obj); + Py_DECREF(bytes_obj); } - Py_DECREF(d_key); - } - Py_DECREF(dict); - } - - /* Also set instance attributes from the slotstate dict (if any). */ - if (slotstate != NULL) { - PyObject *d_key, *d_value; - Py_ssize_t i; - - if (!PyDict_Check(slotstate)) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_SetString(st->UnpicklingError, - "slot state is not a dictionary"); - goto error; - } - i = 0; - while (PyDict_Next(slotstate, &i, &d_key, &d_value)) { - if (PyObject_SetAttr(inst, d_key, d_value) < 0) - goto error; } + if (reduce_value == NULL) + return -1; + + /* save_reduce() will memoize the object automatically. */ + status = save_reduce(self, reduce_value, obj); + Py_DECREF(reduce_value); + return status; } - - if (0) { - error: - status = -1; - } - - Py_DECREF(state); - Py_XDECREF(slotstate); - return status; -} - -static int -load_mark(UnpicklerObject *self) -{ - - /* Note that we split the (pickle.py) stack into two stacks, an - * object stack and a mark stack. Here we push a mark onto the - * mark stack. - */ - - if (self->num_marks >= self->marks_size) { - size_t alloc = ((size_t)self->num_marks << 1) + 20; - Py_ssize_t *marks_new = self->marks; - PyMem_RESIZE(marks_new, Py_ssize_t, alloc); - if (marks_new == NULL) { - PyErr_NoMemory(); - return -1; - } - self->marks = marks_new; - self->marks_size = (Py_ssize_t)alloc; + else { + return _save_bytearray_data(self, obj, PyByteArray_AS_STRING(obj), + PyByteArray_GET_SIZE(obj)); } - - self->stack->mark_set = 1; - self->marks[self->num_marks++] = self->stack->fence = Py_SIZE(self->stack); - - return 0; } static int -load_reduce(UnpicklerObject *self) +save_picklebuffer(PicklerObject *self, PyObject *obj) { - PyObject *callable = NULL; - PyObject *argtup = NULL; - PyObject *obj = NULL; - - PDATA_POP(self->stack, argtup); - if (argtup == NULL) + if (self->proto < 5) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->PicklingError, + "PickleBuffer can only pickled with protocol >= 5"); return -1; - PDATA_POP(self->stack, callable); - if (callable) { - obj = PyObject_CallObject(callable, argtup); - Py_DECREF(callable); } - Py_DECREF(argtup); - - if (obj == NULL) - return -1; - - PDATA_PUSH(self->stack, obj, -1); - return 0; -} - -/* Just raises an error if we don't know the protocol specified. PROTO - * is the first opcode for protocols >= 2. - */ -static int -load_proto(UnpicklerObject *self) -{ - char *s; - int i; - - if (_Unpickler_Read(self, &s, 1) < 0) + const Py_buffer* view = PyPickleBuffer_GetBuffer(obj); + if (view == NULL) { return -1; - - i = (unsigned char)s[0]; - if (i <= HIGHEST_PROTOCOL) { - self->proto = i; - return 0; } - - PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i); - return -1; -} - -static int -load_frame(UnpicklerObject *self) -{ - char *s; - Py_ssize_t frame_len; - - if (_Unpickler_Read(self, &s, 8) < 0) - return -1; - - frame_len = calc_binsize(s, 8); - if (frame_len < 0) { - PyErr_Format(PyExc_OverflowError, - "FRAME length exceeds system's maximum of %zd bytes", - PY_SSIZE_T_MAX); + if (view->suboffsets != NULL || !PyBuffer_IsContiguous(view, 'A')) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->PicklingError, + "PickleBuffer can not be pickled when " + "pointing to a non-contiguous buffer"); return -1; } - - if (_Unpickler_Read(self, &s, frame_len) < 0) - return -1; - - /* Rewind to start of frame */ - self->next_read_idx -= frame_len; - return 0; -} - -static PyObject * -load(UnpicklerObject *self) -{ - PyObject *value = NULL; - char *s = NULL; - - self->num_marks = 0; - self->stack->mark_set = 0; - self->stack->fence = 0; - self->proto = 0; - if (Py_SIZE(self->stack)) - Pdata_clear(self->stack, 0); - - /* Convenient macros for the dispatch while-switch loop just below. */ -#define OP(opcode, load_func) \ - case opcode: if (load_func(self) < 0) break; continue; - -#define OP_ARG(opcode, load_func, arg) \ - case opcode: if (load_func(self, (arg)) < 0) break; continue; - - while (1) { - if (_Unpickler_Read(self, &s, 1) < 0) { - PickleState *st = _Pickle_GetGlobalState(); - if (PyErr_ExceptionMatches(st->UnpicklingError)) { - PyErr_Format(PyExc_EOFError, "Ran out of input"); - } - return NULL; - } - - switch ((enum opcode)s[0]) { - OP(NONE, load_none) - OP(BININT, load_binint) - OP(BININT1, load_binint1) - OP(BININT2, load_binint2) - OP(INT_, load_int) - OP(LONG_, load_long) - OP_ARG(LONG1, load_counted_long, 1) - OP_ARG(LONG4, load_counted_long, 4) - OP(FLOAT_, load_float) - OP(BINFLOAT, load_binfloat) - OP_ARG(SHORT_BINBYTES, load_counted_binbytes, 1) - OP_ARG(BINBYTES, load_counted_binbytes, 4) - OP_ARG(BINBYTES8, load_counted_binbytes, 8) - OP(BYTEARRAY8, load_counted_bytearray) - OP(NEXT_BUFFER, load_next_buffer) - OP(READONLY_BUFFER, load_readonly_buffer) - OP_ARG(SHORT_BINSTRING, load_counted_binstring, 1) - OP_ARG(BINSTRING, load_counted_binstring, 4) - OP(STRING, load_string) - OP(UNICODE, load_unicode) - OP_ARG(SHORT_BINUNICODE, load_counted_binunicode, 1) - OP_ARG(BINUNICODE, load_counted_binunicode, 4) - OP_ARG(BINUNICODE8, load_counted_binunicode, 8) - OP_ARG(EMPTY_TUPLE, load_counted_tuple, 0) - OP_ARG(TUPLE1, load_counted_tuple, 1) - OP_ARG(TUPLE2, load_counted_tuple, 2) - OP_ARG(TUPLE3, load_counted_tuple, 3) - OP(TUPLE, load_tuple) - OP(EMPTY_LIST, load_empty_list) - OP(LIST, load_list) - OP(EMPTY_DICT, load_empty_dict) - OP(DICT, load_dict) - OP(EMPTY_SET, load_empty_set) - OP(ADDITEMS, load_additems) - OP(FROZENSET, load_frozenset) - OP(OBJ, load_obj) - OP(INST, load_inst) - OP(NEWOBJ, load_newobj) - OP(NEWOBJ_EX, load_newobj_ex) - OP(GLOBAL, load_global) - OP(STACK_GLOBAL, load_stack_global) - OP(APPEND, load_append) - OP(APPENDS, load_appends) - OP(BUILD, load_build) - OP(DUP, load_dup) - OP(BINGET, load_binget) - OP(LONG_BINGET, load_long_binget) - OP(GET, load_get) - OP(MARK, load_mark) - OP(BINPUT, load_binput) - OP(LONG_BINPUT, load_long_binput) - OP(PUT, load_put) - OP(MEMOIZE, load_memoize) - OP(POP, load_pop) - OP(POP_MARK, load_pop_mark) - OP(SETITEM, load_setitem) - OP(SETITEMS, load_setitems) - OP(PERSID, load_persid) - OP(BINPERSID, load_binpersid) - OP(REDUCE, load_reduce) - OP(PROTO, load_proto) - OP(FRAME, load_frame) - OP_ARG(EXT1, load_extension, 1) - OP_ARG(EXT2, load_extension, 2) - OP_ARG(EXT4, load_extension, 4) - OP_ARG(NEWTRUE, load_bool, Py_True) - OP_ARG(NEWFALSE, load_bool, Py_False) - - case STOP: - break; - - default: - { - PickleState *st = _Pickle_GetGlobalState(); - unsigned char c = (unsigned char) *s; - if (0x20 <= c && c <= 0x7e && c != '\'' && c != '\\') { - PyErr_Format(st->UnpicklingError, - "invalid load key, '%c'.", c); - } - else { - PyErr_Format(st->UnpicklingError, - "invalid load key, '\\x%02x'.", c); - } - return NULL; + int in_band = 1; + if (self->buffer_callback != NULL) { + PyObject *ret = PyObject_CallOneArg(self->buffer_callback, obj); + if (ret == NULL) { + return -1; + } + in_band = PyObject_IsTrue(ret); + Py_DECREF(ret); + if (in_band == -1) { + return -1; + } + } + if (in_band) { + /* Write data in-band */ + if (view->readonly) { + return _save_bytes_data(self, obj, (const char*) view->buf, + view->len); + } + else { + return _save_bytearray_data(self, obj, (const char*) view->buf, + view->len); + } + } + else { + /* Write data out-of-band */ + const char next_buffer_op = NEXT_BUFFER; + if (_Pickler_Write(self, &next_buffer_op, 1) < 0) { + return -1; + } + if (view->readonly) { + const char readonly_buffer_op = READONLY_BUFFER; + if (_Pickler_Write(self, &readonly_buffer_op, 1) < 0) { + return -1; } } - - break; /* and we are done! */ - } - - if (PyErr_Occurred()) { - return NULL; + } + return 0; +} + +/* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates + backslash and newline characters to \uXXXX escapes. */ +static PyObject * +raw_unicode_escape(PyObject *obj) +{ + char *p; + Py_ssize_t i, size; + const void *data; + unsigned int kind; + _PyBytesWriter writer; + + if (PyUnicode_READY(obj)) + return NULL; + + _PyBytesWriter_Init(&writer); + + size = PyUnicode_GET_LENGTH(obj); + data = PyUnicode_DATA(obj); + kind = PyUnicode_KIND(obj); + + p = _PyBytesWriter_Alloc(&writer, size); + if (p == NULL) + goto error; + writer.overallocate = 1; + + for (i=0; i < size; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + /* Map 32-bit characters to '\Uxxxxxxxx' */ + if (ch >= 0x10000) { + /* -1: subtract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 10-1); + if (p == NULL) + goto error; + + *p++ = '\\'; + *p++ = 'U'; + *p++ = Py_hexdigits[(ch >> 28) & 0xf]; + *p++ = Py_hexdigits[(ch >> 24) & 0xf]; + *p++ = Py_hexdigits[(ch >> 20) & 0xf]; + *p++ = Py_hexdigits[(ch >> 16) & 0xf]; + *p++ = Py_hexdigits[(ch >> 12) & 0xf]; + *p++ = Py_hexdigits[(ch >> 8) & 0xf]; + *p++ = Py_hexdigits[(ch >> 4) & 0xf]; + *p++ = Py_hexdigits[ch & 15]; + } + /* Map 16-bit characters, '\\' and '\n' to '\uxxxx' */ + else if (ch >= 256 || + ch == '\\' || ch == 0 || ch == '\n' || ch == '\r' || + ch == 0x1a) + { + /* -1: subtract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 6-1); + if (p == NULL) + goto error; + + *p++ = '\\'; + *p++ = 'u'; + *p++ = Py_hexdigits[(ch >> 12) & 0xf]; + *p++ = Py_hexdigits[(ch >> 8) & 0xf]; + *p++ = Py_hexdigits[(ch >> 4) & 0xf]; + *p++ = Py_hexdigits[ch & 15]; + } + /* Copy everything else as-is */ + else + *p++ = (char) ch; + } + + return _PyBytesWriter_Finish(&writer, p); + +error: + _PyBytesWriter_Dealloc(&writer); + return NULL; +} + +static int +write_unicode_binary(PicklerObject *self, PyObject *obj) +{ + char header[9]; + Py_ssize_t len; + PyObject *encoded = NULL; + Py_ssize_t size; + const char *data; + + if (PyUnicode_READY(obj)) + return -1; + + data = PyUnicode_AsUTF8AndSize(obj, &size); + if (data == NULL) { + /* Issue #8383: for strings with lone surrogates, fallback on the + "surrogatepass" error handler. */ + PyErr_Clear(); + encoded = PyUnicode_AsEncodedString(obj, "utf-8", "surrogatepass"); + if (encoded == NULL) + return -1; + + data = PyBytes_AS_STRING(encoded); + size = PyBytes_GET_SIZE(encoded); + } + + assert(size >= 0); + if (size <= 0xff && self->proto >= 4) { + header[0] = SHORT_BINUNICODE; + header[1] = (unsigned char)(size & 0xff); + len = 2; + } + else if ((size_t)size <= 0xffffffffUL) { + header[0] = BINUNICODE; + header[1] = (unsigned char)(size & 0xff); + header[2] = (unsigned char)((size >> 8) & 0xff); + header[3] = (unsigned char)((size >> 16) & 0xff); + header[4] = (unsigned char)((size >> 24) & 0xff); + len = 5; + } + else if (self->proto >= 4) { + header[0] = BINUNICODE8; + _write_size64(header + 1, size); + len = 9; + } + else { + PyErr_SetString(PyExc_OverflowError, + "serializing a string larger than 4 GiB " + "requires pickle protocol 4 or higher"); + Py_XDECREF(encoded); + return -1; + } + + if (_Pickler_write_bytes(self, header, len, data, size, encoded) < 0) { + Py_XDECREF(encoded); + return -1; + } + Py_XDECREF(encoded); + return 0; +} + +static int +save_unicode(PicklerObject *self, PyObject *obj) +{ + if (self->bin) { + if (write_unicode_binary(self, obj) < 0) + return -1; + } + else { + PyObject *encoded; + Py_ssize_t size; + const char unicode_op = UNICODE; + + encoded = raw_unicode_escape(obj); + if (encoded == NULL) + return -1; + + if (_Pickler_Write(self, &unicode_op, 1) < 0) { + Py_DECREF(encoded); + return -1; + } + + size = PyBytes_GET_SIZE(encoded); + if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), size) < 0) { + Py_DECREF(encoded); + return -1; + } + Py_DECREF(encoded); + + if (_Pickler_Write(self, "\n", 1) < 0) + return -1; + } + if (memo_put(self, obj) < 0) + return -1; + + return 0; +} + +/* A helper for save_tuple. Push the len elements in tuple t on the stack. */ +static int +store_tuple_elements(PicklerObject *self, PyObject *t, Py_ssize_t len) +{ + Py_ssize_t i; + + assert(PyTuple_Size(t) == len); + + for (i = 0; i < len; i++) { + PyObject *element = PyTuple_GET_ITEM(t, i); + + if (element == NULL) + return -1; + if (save(self, element, 0) < 0) + return -1; + } + + return 0; +} + +/* Tuples are ubiquitous in the pickle protocols, so many techniques are + * used across protocols to minimize the space needed to pickle them. + * Tuples are also the only builtin immutable type that can be recursive + * (a tuple can be reached from itself), and that requires some subtle + * magic so that it works in all cases. IOW, this is a long routine. + */ +static int +save_tuple(PicklerObject *self, PyObject *obj) +{ + Py_ssize_t len, i; + + const char mark_op = MARK; + const char tuple_op = TUPLE; + const char pop_op = POP; + const char pop_mark_op = POP_MARK; + const char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3}; + + if ((len = PyTuple_Size(obj)) < 0) + return -1; + + if (len == 0) { + char pdata[2]; + + if (self->proto) { + pdata[0] = EMPTY_TUPLE; + len = 1; + } + else { + pdata[0] = MARK; + pdata[1] = TUPLE; + len = 2; + } + if (_Pickler_Write(self, pdata, len) < 0) + return -1; + return 0; + } + + /* The tuple isn't in the memo now. If it shows up there after + * saving the tuple elements, the tuple must be recursive, in + * which case we'll pop everything we put on the stack, and fetch + * its value from the memo. + */ + if (len <= 3 && self->proto >= 2) { + /* Use TUPLE{1,2,3} opcodes. */ + if (store_tuple_elements(self, obj, len) < 0) + return -1; + + if (PyMemoTable_Get(self->memo, obj)) { + /* pop the len elements */ + for (i = 0; i < len; i++) + if (_Pickler_Write(self, &pop_op, 1) < 0) + return -1; + /* fetch from memo */ + if (memo_get(self, obj) < 0) + return -1; + + return 0; + } + else { /* Not recursive. */ + if (_Pickler_Write(self, len2opcode + len, 1) < 0) + return -1; + } + goto memoize; + } + + /* proto < 2 and len > 0, or proto >= 2 and len > 3. + * Generate MARK e1 e2 ... TUPLE + */ + if (_Pickler_Write(self, &mark_op, 1) < 0) + return -1; + + if (store_tuple_elements(self, obj, len) < 0) + return -1; + + if (PyMemoTable_Get(self->memo, obj)) { + /* pop the stack stuff we pushed */ + if (self->bin) { + if (_Pickler_Write(self, &pop_mark_op, 1) < 0) + return -1; + } + else { + /* Note that we pop one more than len, to remove + * the MARK too. + */ + for (i = 0; i <= len; i++) + if (_Pickler_Write(self, &pop_op, 1) < 0) + return -1; + } + /* fetch from memo */ + if (memo_get(self, obj) < 0) + return -1; + + return 0; + } + else { /* Not recursive. */ + if (_Pickler_Write(self, &tuple_op, 1) < 0) + return -1; + } + + memoize: + if (memo_put(self, obj) < 0) + return -1; + + return 0; +} + +/* iter is an iterator giving items, and we batch up chunks of + * MARK item item ... item APPENDS + * opcode sequences. Calling code should have arranged to first create an + * empty list, or list-like object, for the APPENDS to operate on. + * Returns 0 on success, <0 on error. + */ +static int +batch_list(PicklerObject *self, PyObject *iter) +{ + PyObject *obj = NULL; + PyObject *firstitem = NULL; + int i, n; + + const char mark_op = MARK; + const char append_op = APPEND; + const char appends_op = APPENDS; + + assert(iter != NULL); + + /* XXX: I think this function could be made faster by avoiding the + iterator interface and fetching objects directly from list using + PyList_GET_ITEM. + */ + + if (self->proto == 0) { + /* APPENDS isn't available; do one at a time. */ + for (;;) { + obj = PyIter_Next(iter); + if (obj == NULL) { + if (PyErr_Occurred()) + return -1; + break; + } + i = save(self, obj, 0); + Py_DECREF(obj); + if (i < 0) + return -1; + if (_Pickler_Write(self, &append_op, 1) < 0) + return -1; + } + return 0; + } + + /* proto > 0: write in batches of BATCHSIZE. */ + do { + /* Get first item */ + firstitem = PyIter_Next(iter); + if (firstitem == NULL) { + if (PyErr_Occurred()) + goto error; + + /* nothing more to add */ + break; + } + + /* Try to get a second item */ + obj = PyIter_Next(iter); + if (obj == NULL) { + if (PyErr_Occurred()) + goto error; + + /* Only one item to write */ + if (save(self, firstitem, 0) < 0) + goto error; + if (_Pickler_Write(self, &append_op, 1) < 0) + goto error; + Py_CLEAR(firstitem); + break; + } + + /* More than one item to write */ + + /* Pump out MARK, items, APPENDS. */ + if (_Pickler_Write(self, &mark_op, 1) < 0) + goto error; + + if (save(self, firstitem, 0) < 0) + goto error; + Py_CLEAR(firstitem); + n = 1; + + /* Fetch and save up to BATCHSIZE items */ + while (obj) { + if (save(self, obj, 0) < 0) + goto error; + Py_CLEAR(obj); + n += 1; + + if (n == BATCHSIZE) + break; + + obj = PyIter_Next(iter); + if (obj == NULL) { + if (PyErr_Occurred()) + goto error; + break; + } + } + + if (_Pickler_Write(self, &appends_op, 1) < 0) + goto error; + + } while (n == BATCHSIZE); + return 0; + + error: + Py_XDECREF(firstitem); + Py_XDECREF(obj); + return -1; +} + +/* This is a variant of batch_list() above, specialized for lists (with no + * support for list subclasses). Like batch_list(), we batch up chunks of + * MARK item item ... item APPENDS + * opcode sequences. Calling code should have arranged to first create an + * empty list, or list-like object, for the APPENDS to operate on. + * Returns 0 on success, -1 on error. + * + * This version is considerably faster than batch_list(), if less general. + * + * Note that this only works for protocols > 0. + */ +static int +batch_list_exact(PicklerObject *self, PyObject *obj) +{ + PyObject *item = NULL; + Py_ssize_t this_batch, total; + + const char append_op = APPEND; + const char appends_op = APPENDS; + const char mark_op = MARK; + + assert(obj != NULL); + assert(self->proto > 0); + assert(PyList_CheckExact(obj)); + + if (PyList_GET_SIZE(obj) == 1) { + item = PyList_GET_ITEM(obj, 0); + if (save(self, item, 0) < 0) + return -1; + if (_Pickler_Write(self, &append_op, 1) < 0) + return -1; + return 0; + } + + /* Write in batches of BATCHSIZE. */ + total = 0; + do { + this_batch = 0; + if (_Pickler_Write(self, &mark_op, 1) < 0) + return -1; + while (total < PyList_GET_SIZE(obj)) { + item = PyList_GET_ITEM(obj, total); + if (save(self, item, 0) < 0) + return -1; + total++; + if (++this_batch == BATCHSIZE) + break; + } + if (_Pickler_Write(self, &appends_op, 1) < 0) + return -1; + + } while (total < PyList_GET_SIZE(obj)); + + return 0; +} + +static int +save_list(PicklerObject *self, PyObject *obj) +{ + char header[3]; + Py_ssize_t len; + int status = 0; + + if (self->fast && !fast_save_enter(self, obj)) + goto error; + + /* Create an empty list. */ + if (self->bin) { + header[0] = EMPTY_LIST; + len = 1; + } + else { + header[0] = MARK; + header[1] = LIST; + len = 2; + } + + if (_Pickler_Write(self, header, len) < 0) + goto error; + + /* Get list length, and bow out early if empty. */ + if ((len = PyList_Size(obj)) < 0) + goto error; + + if (memo_put(self, obj) < 0) + goto error; + + if (len != 0) { + /* Materialize the list elements. */ + if (PyList_CheckExact(obj) && self->proto > 0) { + if (Py_EnterRecursiveCall(" while pickling an object")) + goto error; + status = batch_list_exact(self, obj); + Py_LeaveRecursiveCall(); + } else { + PyObject *iter = PyObject_GetIter(obj); + if (iter == NULL) + goto error; + + if (Py_EnterRecursiveCall(" while pickling an object")) { + Py_DECREF(iter); + goto error; + } + status = batch_list(self, iter); + Py_LeaveRecursiveCall(); + Py_DECREF(iter); + } + } + if (0) { + error: + status = -1; + } + + if (self->fast && !fast_save_leave(self, obj)) + status = -1; + + return status; +} + +/* iter is an iterator giving (key, value) pairs, and we batch up chunks of + * MARK key value ... key value SETITEMS + * opcode sequences. Calling code should have arranged to first create an + * empty dict, or dict-like object, for the SETITEMS to operate on. + * Returns 0 on success, <0 on error. + * + * This is very much like batch_list(). The difference between saving + * elements directly, and picking apart two-tuples, is so long-winded at + * the C level, though, that attempts to combine these routines were too + * ugly to bear. + */ +static int +batch_dict(PicklerObject *self, PyObject *iter) +{ + PyObject *obj = NULL; + PyObject *firstitem = NULL; + int i, n; + + const char mark_op = MARK; + const char setitem_op = SETITEM; + const char setitems_op = SETITEMS; + + assert(iter != NULL); + + if (self->proto == 0) { + /* SETITEMS isn't available; do one at a time. */ + for (;;) { + obj = PyIter_Next(iter); + if (obj == NULL) { + if (PyErr_Occurred()) + return -1; + break; + } + if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) { + PyErr_SetString(PyExc_TypeError, "dict items " + "iterator must return 2-tuples"); + return -1; + } + i = save(self, PyTuple_GET_ITEM(obj, 0), 0); + if (i >= 0) + i = save(self, PyTuple_GET_ITEM(obj, 1), 0); + Py_DECREF(obj); + if (i < 0) + return -1; + if (_Pickler_Write(self, &setitem_op, 1) < 0) + return -1; + } + return 0; + } + + /* proto > 0: write in batches of BATCHSIZE. */ + do { + /* Get first item */ + firstitem = PyIter_Next(iter); + if (firstitem == NULL) { + if (PyErr_Occurred()) + goto error; + + /* nothing more to add */ + break; + } + if (!PyTuple_Check(firstitem) || PyTuple_Size(firstitem) != 2) { + PyErr_SetString(PyExc_TypeError, "dict items " + "iterator must return 2-tuples"); + goto error; + } + + /* Try to get a second item */ + obj = PyIter_Next(iter); + if (obj == NULL) { + if (PyErr_Occurred()) + goto error; + + /* Only one item to write */ + if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) + goto error; + if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) + goto error; + if (_Pickler_Write(self, &setitem_op, 1) < 0) + goto error; + Py_CLEAR(firstitem); + break; + } + + /* More than one item to write */ + + /* Pump out MARK, items, SETITEMS. */ + if (_Pickler_Write(self, &mark_op, 1) < 0) + goto error; + + if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) + goto error; + if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) + goto error; + Py_CLEAR(firstitem); + n = 1; + + /* Fetch and save up to BATCHSIZE items */ + while (obj) { + if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) { + PyErr_SetString(PyExc_TypeError, "dict items " + "iterator must return 2-tuples"); + goto error; + } + if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 || + save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0) + goto error; + Py_CLEAR(obj); + n += 1; + + if (n == BATCHSIZE) + break; + + obj = PyIter_Next(iter); + if (obj == NULL) { + if (PyErr_Occurred()) + goto error; + break; + } + } + + if (_Pickler_Write(self, &setitems_op, 1) < 0) + goto error; + + } while (n == BATCHSIZE); + return 0; + + error: + Py_XDECREF(firstitem); + Py_XDECREF(obj); + return -1; +} + +/* This is a variant of batch_dict() above that specializes for dicts, with no + * support for dict subclasses. Like batch_dict(), we batch up chunks of + * MARK key value ... key value SETITEMS + * opcode sequences. Calling code should have arranged to first create an + * empty dict, or dict-like object, for the SETITEMS to operate on. + * Returns 0 on success, -1 on error. + * + * Note that this currently doesn't work for protocol 0. + */ +static int +batch_dict_exact(PicklerObject *self, PyObject *obj) +{ + PyObject *key = NULL, *value = NULL; + int i; + Py_ssize_t dict_size, ppos = 0; + + const char mark_op = MARK; + const char setitem_op = SETITEM; + const char setitems_op = SETITEMS; + + assert(obj != NULL && PyDict_CheckExact(obj)); + assert(self->proto > 0); + + dict_size = PyDict_GET_SIZE(obj); + + /* Special-case len(d) == 1 to save space. */ + if (dict_size == 1) { + PyDict_Next(obj, &ppos, &key, &value); + if (save(self, key, 0) < 0) + return -1; + if (save(self, value, 0) < 0) + return -1; + if (_Pickler_Write(self, &setitem_op, 1) < 0) + return -1; + return 0; + } + + /* Write in batches of BATCHSIZE. */ + do { + i = 0; + if (_Pickler_Write(self, &mark_op, 1) < 0) + return -1; + while (PyDict_Next(obj, &ppos, &key, &value)) { + if (save(self, key, 0) < 0) + return -1; + if (save(self, value, 0) < 0) + return -1; + if (++i == BATCHSIZE) + break; + } + if (_Pickler_Write(self, &setitems_op, 1) < 0) + return -1; + if (PyDict_GET_SIZE(obj) != dict_size) { + PyErr_Format( + PyExc_RuntimeError, + "dictionary changed size during iteration"); + return -1; + } + + } while (i == BATCHSIZE); + return 0; +} + +static int +save_dict(PicklerObject *self, PyObject *obj) +{ + PyObject *items, *iter; + char header[3]; + Py_ssize_t len; + int status = 0; + assert(PyDict_Check(obj)); + + if (self->fast && !fast_save_enter(self, obj)) + goto error; + + /* Create an empty dict. */ + if (self->bin) { + header[0] = EMPTY_DICT; + len = 1; + } + else { + header[0] = MARK; + header[1] = DICT; + len = 2; + } + + if (_Pickler_Write(self, header, len) < 0) + goto error; + + if (memo_put(self, obj) < 0) + goto error; + + if (PyDict_GET_SIZE(obj)) { + /* Save the dict items. */ + if (PyDict_CheckExact(obj) && self->proto > 0) { + /* We can take certain shortcuts if we know this is a dict and + not a dict subclass. */ + if (Py_EnterRecursiveCall(" while pickling an object")) + goto error; + status = batch_dict_exact(self, obj); + Py_LeaveRecursiveCall(); + } else { + _Py_IDENTIFIER(items); + + items = _PyObject_CallMethodIdNoArgs(obj, &PyId_items); + if (items == NULL) + goto error; + iter = PyObject_GetIter(items); + Py_DECREF(items); + if (iter == NULL) + goto error; + if (Py_EnterRecursiveCall(" while pickling an object")) { + Py_DECREF(iter); + goto error; + } + status = batch_dict(self, iter); + Py_LeaveRecursiveCall(); + Py_DECREF(iter); + } + } + + if (0) { + error: + status = -1; + } + + if (self->fast && !fast_save_leave(self, obj)) + status = -1; + + return status; +} + +static int +save_set(PicklerObject *self, PyObject *obj) +{ + PyObject *item; + int i; + Py_ssize_t set_size, ppos = 0; + Py_hash_t hash; + + const char empty_set_op = EMPTY_SET; + const char mark_op = MARK; + const char additems_op = ADDITEMS; + + if (self->proto < 4) { + PyObject *items; + PyObject *reduce_value; + int status; + + items = PySequence_List(obj); + if (items == NULL) { + return -1; + } + reduce_value = Py_BuildValue("(O(O))", (PyObject*)&PySet_Type, items); + Py_DECREF(items); + if (reduce_value == NULL) { + return -1; + } + /* save_reduce() will memoize the object automatically. */ + status = save_reduce(self, reduce_value, obj); + Py_DECREF(reduce_value); + return status; + } + + if (_Pickler_Write(self, &empty_set_op, 1) < 0) + return -1; + + if (memo_put(self, obj) < 0) + return -1; + + set_size = PySet_GET_SIZE(obj); + if (set_size == 0) + return 0; /* nothing to do */ + + /* Write in batches of BATCHSIZE. */ + do { + i = 0; + if (_Pickler_Write(self, &mark_op, 1) < 0) + return -1; + while (_PySet_NextEntry(obj, &ppos, &item, &hash)) { + if (save(self, item, 0) < 0) + return -1; + if (++i == BATCHSIZE) + break; + } + if (_Pickler_Write(self, &additems_op, 1) < 0) + return -1; + if (PySet_GET_SIZE(obj) != set_size) { + PyErr_Format( + PyExc_RuntimeError, + "set changed size during iteration"); + return -1; + } + } while (i == BATCHSIZE); + + return 0; +} + +static int +save_frozenset(PicklerObject *self, PyObject *obj) +{ + PyObject *iter; + + const char mark_op = MARK; + const char frozenset_op = FROZENSET; + + if (self->fast && !fast_save_enter(self, obj)) + return -1; + + if (self->proto < 4) { + PyObject *items; + PyObject *reduce_value; + int status; + + items = PySequence_List(obj); + if (items == NULL) { + return -1; + } + reduce_value = Py_BuildValue("(O(O))", (PyObject*)&PyFrozenSet_Type, + items); + Py_DECREF(items); + if (reduce_value == NULL) { + return -1; + } + /* save_reduce() will memoize the object automatically. */ + status = save_reduce(self, reduce_value, obj); + Py_DECREF(reduce_value); + return status; + } + + if (_Pickler_Write(self, &mark_op, 1) < 0) + return -1; + + iter = PyObject_GetIter(obj); + if (iter == NULL) { + return -1; + } + for (;;) { + PyObject *item; + + item = PyIter_Next(iter); + if (item == NULL) { + if (PyErr_Occurred()) { + Py_DECREF(iter); + return -1; + } + break; + } + if (save(self, item, 0) < 0) { + Py_DECREF(item); + Py_DECREF(iter); + return -1; + } + Py_DECREF(item); + } + Py_DECREF(iter); + + /* If the object is already in the memo, this means it is + recursive. In this case, throw away everything we put on the + stack, and fetch the object back from the memo. */ + if (PyMemoTable_Get(self->memo, obj)) { + const char pop_mark_op = POP_MARK; + + if (_Pickler_Write(self, &pop_mark_op, 1) < 0) + return -1; + if (memo_get(self, obj) < 0) + return -1; + return 0; + } + + if (_Pickler_Write(self, &frozenset_op, 1) < 0) + return -1; + if (memo_put(self, obj) < 0) + return -1; + + return 0; +} + +static int +fix_imports(PyObject **module_name, PyObject **global_name) +{ + PyObject *key; + PyObject *item; + PickleState *st = _Pickle_GetGlobalState(); + + key = PyTuple_Pack(2, *module_name, *global_name); + if (key == NULL) + return -1; + item = PyDict_GetItemWithError(st->name_mapping_3to2, key); + Py_DECREF(key); + if (item) { + PyObject *fixed_module_name; + PyObject *fixed_global_name; + + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.REVERSE_NAME_MAPPING values " + "should be 2-tuples, not %.200s", + Py_TYPE(item)->tp_name); + return -1; + } + fixed_module_name = PyTuple_GET_ITEM(item, 0); + fixed_global_name = PyTuple_GET_ITEM(item, 1); + if (!PyUnicode_Check(fixed_module_name) || + !PyUnicode_Check(fixed_global_name)) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.REVERSE_NAME_MAPPING values " + "should be pairs of str, not (%.200s, %.200s)", + Py_TYPE(fixed_module_name)->tp_name, + Py_TYPE(fixed_global_name)->tp_name); + return -1; + } + + Py_CLEAR(*module_name); + Py_CLEAR(*global_name); + Py_INCREF(fixed_module_name); + Py_INCREF(fixed_global_name); + *module_name = fixed_module_name; + *global_name = fixed_global_name; + return 0; + } + else if (PyErr_Occurred()) { + return -1; + } + + item = PyDict_GetItemWithError(st->import_mapping_3to2, *module_name); + if (item) { + if (!PyUnicode_Check(item)) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.REVERSE_IMPORT_MAPPING values " + "should be strings, not %.200s", + Py_TYPE(item)->tp_name); + return -1; + } + Py_INCREF(item); + Py_XSETREF(*module_name, item); + } + else if (PyErr_Occurred()) { + return -1; + } + + return 0; +} + +static int +save_global(PicklerObject *self, PyObject *obj, PyObject *name) +{ + PyObject *global_name = NULL; + PyObject *module_name = NULL; + PyObject *module = NULL; + PyObject *parent = NULL; + PyObject *dotted_path = NULL; + PyObject *lastname = NULL; + PyObject *cls; + PickleState *st = _Pickle_GetGlobalState(); + int status = 0; + _Py_IDENTIFIER(__name__); + _Py_IDENTIFIER(__qualname__); + + const char global_op = GLOBAL; + + if (name) { + Py_INCREF(name); + global_name = name; + } + else { + if (_PyObject_LookupAttrId(obj, &PyId___qualname__, &global_name) < 0) + goto error; + if (global_name == NULL) { + global_name = _PyObject_GetAttrId(obj, &PyId___name__); + if (global_name == NULL) + goto error; + } + } + + dotted_path = get_dotted_path(module, global_name); + if (dotted_path == NULL) + goto error; + module_name = whichmodule(obj, dotted_path); + if (module_name == NULL) + goto error; + + /* XXX: Change to use the import C API directly with level=0 to disallow + relative imports. + + XXX: PyImport_ImportModuleLevel could be used. However, this bypasses + builtins.__import__. Therefore, _pickle, unlike pickle.py, will ignore + custom import functions (IMHO, this would be a nice security + feature). The import C API would need to be extended to support the + extra parameters of __import__ to fix that. */ + module = PyImport_Import(module_name); + if (module == NULL) { + PyErr_Format(st->PicklingError, + "Can't pickle %R: import of module %R failed", + obj, module_name); + goto error; + } + lastname = PyList_GET_ITEM(dotted_path, PyList_GET_SIZE(dotted_path)-1); + Py_INCREF(lastname); + cls = get_deep_attribute(module, dotted_path, &parent); + Py_CLEAR(dotted_path); + if (cls == NULL) { + PyErr_Format(st->PicklingError, + "Can't pickle %R: attribute lookup %S on %S failed", + obj, global_name, module_name); + goto error; + } + if (cls != obj) { + Py_DECREF(cls); + PyErr_Format(st->PicklingError, + "Can't pickle %R: it's not the same object as %S.%S", + obj, module_name, global_name); + goto error; + } + Py_DECREF(cls); + + if (self->proto >= 2) { + /* See whether this is in the extension registry, and if + * so generate an EXT opcode. + */ + PyObject *extension_key; + PyObject *code_obj; /* extension code as Python object */ + long code; /* extension code as C value */ + char pdata[5]; + Py_ssize_t n; + + extension_key = PyTuple_Pack(2, module_name, global_name); + if (extension_key == NULL) { + goto error; + } + code_obj = PyDict_GetItemWithError(st->extension_registry, + extension_key); + Py_DECREF(extension_key); + /* The object is not registered in the extension registry. + This is the most likely code path. */ + if (code_obj == NULL) { + if (PyErr_Occurred()) { + goto error; + } + goto gen_global; + } + + /* XXX: pickle.py doesn't check neither the type, nor the range + of the value returned by the extension_registry. It should for + consistency. */ + + /* Verify code_obj has the right type and value. */ + if (!PyLong_Check(code_obj)) { + PyErr_Format(st->PicklingError, + "Can't pickle %R: extension code %R isn't an integer", + obj, code_obj); + goto error; + } + code = PyLong_AS_LONG(code_obj); + if (code <= 0 || code > 0x7fffffffL) { + if (!PyErr_Occurred()) + PyErr_Format(st->PicklingError, "Can't pickle %R: extension " + "code %ld is out of range", obj, code); + goto error; + } + + /* Generate an EXT opcode. */ + if (code <= 0xff) { + pdata[0] = EXT1; + pdata[1] = (unsigned char)code; + n = 2; + } + else if (code <= 0xffff) { + pdata[0] = EXT2; + pdata[1] = (unsigned char)(code & 0xff); + pdata[2] = (unsigned char)((code >> 8) & 0xff); + n = 3; + } + else { + pdata[0] = EXT4; + pdata[1] = (unsigned char)(code & 0xff); + pdata[2] = (unsigned char)((code >> 8) & 0xff); + pdata[3] = (unsigned char)((code >> 16) & 0xff); + pdata[4] = (unsigned char)((code >> 24) & 0xff); + n = 5; + } + + if (_Pickler_Write(self, pdata, n) < 0) + goto error; + } + else { + gen_global: + if (parent == module) { + Py_INCREF(lastname); + Py_DECREF(global_name); + global_name = lastname; + } + if (self->proto >= 4) { + const char stack_global_op = STACK_GLOBAL; + + if (save(self, module_name, 0) < 0) + goto error; + if (save(self, global_name, 0) < 0) + goto error; + + if (_Pickler_Write(self, &stack_global_op, 1) < 0) + goto error; + } + else if (parent != module) { + PickleState *st = _Pickle_GetGlobalState(); + PyObject *reduce_value = Py_BuildValue("(O(OO))", + st->getattr, parent, lastname); + if (reduce_value == NULL) + goto error; + status = save_reduce(self, reduce_value, NULL); + Py_DECREF(reduce_value); + if (status < 0) + goto error; + } + else { + /* Generate a normal global opcode if we are using a pickle + protocol < 4, or if the object is not registered in the + extension registry. */ + PyObject *encoded; + PyObject *(*unicode_encoder)(PyObject *); + + if (_Pickler_Write(self, &global_op, 1) < 0) + goto error; + + /* For protocol < 3 and if the user didn't request against doing + so, we convert module names to the old 2.x module names. */ + if (self->proto < 3 && self->fix_imports) { + if (fix_imports(&module_name, &global_name) < 0) { + goto error; + } + } + + /* Since Python 3.0 now supports non-ASCII identifiers, we encode + both the module name and the global name using UTF-8. We do so + only when we are using the pickle protocol newer than version + 3. This is to ensure compatibility with older Unpickler running + on Python 2.x. */ + if (self->proto == 3) { + unicode_encoder = PyUnicode_AsUTF8String; + } + else { + unicode_encoder = PyUnicode_AsASCIIString; + } + encoded = unicode_encoder(module_name); + if (encoded == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) + PyErr_Format(st->PicklingError, + "can't pickle module identifier '%S' using " + "pickle protocol %i", + module_name, self->proto); + goto error; + } + if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), + PyBytes_GET_SIZE(encoded)) < 0) { + Py_DECREF(encoded); + goto error; + } + Py_DECREF(encoded); + if(_Pickler_Write(self, "\n", 1) < 0) + goto error; + + /* Save the name of the module. */ + encoded = unicode_encoder(global_name); + if (encoded == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) + PyErr_Format(st->PicklingError, + "can't pickle global identifier '%S' using " + "pickle protocol %i", + global_name, self->proto); + goto error; + } + if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), + PyBytes_GET_SIZE(encoded)) < 0) { + Py_DECREF(encoded); + goto error; + } + Py_DECREF(encoded); + if (_Pickler_Write(self, "\n", 1) < 0) + goto error; + } + /* Memoize the object. */ + if (memo_put(self, obj) < 0) + goto error; + } + + if (0) { + error: + status = -1; + } + Py_XDECREF(module_name); + Py_XDECREF(global_name); + Py_XDECREF(module); + Py_XDECREF(parent); + Py_XDECREF(dotted_path); + Py_XDECREF(lastname); + + return status; +} + +static int +save_singleton_type(PicklerObject *self, PyObject *obj, PyObject *singleton) +{ + PyObject *reduce_value; + int status; + + reduce_value = Py_BuildValue("O(O)", &PyType_Type, singleton); + if (reduce_value == NULL) { + return -1; + } + status = save_reduce(self, reduce_value, obj); + Py_DECREF(reduce_value); + return status; +} + +static int +save_type(PicklerObject *self, PyObject *obj) +{ + if (obj == (PyObject *)&_PyNone_Type) { + return save_singleton_type(self, obj, Py_None); + } + else if (obj == (PyObject *)&PyEllipsis_Type) { + return save_singleton_type(self, obj, Py_Ellipsis); + } + else if (obj == (PyObject *)&_PyNotImplemented_Type) { + return save_singleton_type(self, obj, Py_NotImplemented); + } + return save_global(self, obj, NULL); +} + +static int +save_pers(PicklerObject *self, PyObject *obj) +{ + PyObject *pid = NULL; + int status = 0; + + const char persid_op = PERSID; + const char binpersid_op = BINPERSID; + + pid = call_method(self->pers_func, self->pers_func_self, obj); + if (pid == NULL) + return -1; + + if (pid != Py_None) { + if (self->bin) { + if (save(self, pid, 1) < 0 || + _Pickler_Write(self, &binpersid_op, 1) < 0) + goto error; + } + else { + PyObject *pid_str; + + pid_str = PyObject_Str(pid); + if (pid_str == NULL) + goto error; + + /* XXX: Should it check whether the pid contains embedded + newlines? */ + if (!PyUnicode_IS_ASCII(pid_str)) { + PyErr_SetString(_Pickle_GetGlobalState()->PicklingError, + "persistent IDs in protocol 0 must be " + "ASCII strings"); + Py_DECREF(pid_str); + goto error; + } + + if (_Pickler_Write(self, &persid_op, 1) < 0 || + _Pickler_Write(self, PyUnicode_DATA(pid_str), + PyUnicode_GET_LENGTH(pid_str)) < 0 || + _Pickler_Write(self, "\n", 1) < 0) { + Py_DECREF(pid_str); + goto error; + } + Py_DECREF(pid_str); + } + status = 1; + } + + if (0) { + error: + status = -1; + } + Py_XDECREF(pid); + + return status; +} + +static PyObject * +get_class(PyObject *obj) +{ + PyObject *cls; + _Py_IDENTIFIER(__class__); + + if (_PyObject_LookupAttrId(obj, &PyId___class__, &cls) == 0) { + cls = (PyObject *) Py_TYPE(obj); + Py_INCREF(cls); + } + return cls; +} + +/* We're saving obj, and args is the 2-thru-5 tuple returned by the + * appropriate __reduce__ method for obj. + */ +static int +save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) +{ + PyObject *callable; + PyObject *argtup; + PyObject *state = NULL; + PyObject *listitems = Py_None; + PyObject *dictitems = Py_None; + PyObject *state_setter = Py_None; + PickleState *st = _Pickle_GetGlobalState(); + Py_ssize_t size; + int use_newobj = 0, use_newobj_ex = 0; + + const char reduce_op = REDUCE; + const char build_op = BUILD; + const char newobj_op = NEWOBJ; + const char newobj_ex_op = NEWOBJ_EX; + + size = PyTuple_Size(args); + if (size < 2 || size > 6) { + PyErr_SetString(st->PicklingError, "tuple returned by " + "__reduce__ must contain 2 through 6 elements"); + return -1; + } + + if (!PyArg_UnpackTuple(args, "save_reduce", 2, 6, + &callable, &argtup, &state, &listitems, &dictitems, + &state_setter)) + return -1; + + if (!PyCallable_Check(callable)) { + PyErr_SetString(st->PicklingError, "first item of the tuple " + "returned by __reduce__ must be callable"); + return -1; + } + if (!PyTuple_Check(argtup)) { + PyErr_SetString(st->PicklingError, "second item of the tuple " + "returned by __reduce__ must be a tuple"); + return -1; + } + + if (state == Py_None) + state = NULL; + + if (listitems == Py_None) + listitems = NULL; + else if (!PyIter_Check(listitems)) { + PyErr_Format(st->PicklingError, "fourth element of the tuple " + "returned by __reduce__ must be an iterator, not %s", + Py_TYPE(listitems)->tp_name); + return -1; + } + + if (dictitems == Py_None) + dictitems = NULL; + else if (!PyIter_Check(dictitems)) { + PyErr_Format(st->PicklingError, "fifth element of the tuple " + "returned by __reduce__ must be an iterator, not %s", + Py_TYPE(dictitems)->tp_name); + return -1; + } + + if (state_setter == Py_None) + state_setter = NULL; + else if (!PyCallable_Check(state_setter)) { + PyErr_Format(st->PicklingError, "sixth element of the tuple " + "returned by __reduce__ must be a function, not %s", + Py_TYPE(state_setter)->tp_name); + return -1; } - if (_Unpickler_SkipConsumed(self) < 0) - return NULL; - - PDATA_POP(self->stack, value); - return value; -} - -/*[clinic input] - -_pickle.Unpickler.load - -Load a pickle. + if (self->proto >= 2) { + PyObject *name; + _Py_IDENTIFIER(__name__); + + if (_PyObject_LookupAttrId(callable, &PyId___name__, &name) < 0) { + return -1; + } + if (name != NULL && PyUnicode_Check(name)) { + _Py_IDENTIFIER(__newobj_ex__); + use_newobj_ex = _PyUnicode_EqualToASCIIId( + name, &PyId___newobj_ex__); + if (!use_newobj_ex) { + _Py_IDENTIFIER(__newobj__); + use_newobj = _PyUnicode_EqualToASCIIId(name, &PyId___newobj__); + } + } + Py_XDECREF(name); + } + + if (use_newobj_ex) { + PyObject *cls; + PyObject *args; + PyObject *kwargs; + + if (PyTuple_GET_SIZE(argtup) != 3) { + PyErr_Format(st->PicklingError, + "length of the NEWOBJ_EX argument tuple must be " + "exactly 3, not %zd", PyTuple_GET_SIZE(argtup)); + return -1; + } + + cls = PyTuple_GET_ITEM(argtup, 0); + if (!PyType_Check(cls)) { + PyErr_Format(st->PicklingError, + "first item from NEWOBJ_EX argument tuple must " + "be a class, not %.200s", Py_TYPE(cls)->tp_name); + return -1; + } + args = PyTuple_GET_ITEM(argtup, 1); + if (!PyTuple_Check(args)) { + PyErr_Format(st->PicklingError, + "second item from NEWOBJ_EX argument tuple must " + "be a tuple, not %.200s", Py_TYPE(args)->tp_name); + return -1; + } + kwargs = PyTuple_GET_ITEM(argtup, 2); + if (!PyDict_Check(kwargs)) { + PyErr_Format(st->PicklingError, + "third item from NEWOBJ_EX argument tuple must " + "be a dict, not %.200s", Py_TYPE(kwargs)->tp_name); + return -1; + } + + if (self->proto >= 4) { + if (save(self, cls, 0) < 0 || + save(self, args, 0) < 0 || + save(self, kwargs, 0) < 0 || + _Pickler_Write(self, &newobj_ex_op, 1) < 0) { + return -1; + } + } + else { + PyObject *newargs; + PyObject *cls_new; + Py_ssize_t i; + _Py_IDENTIFIER(__new__); + + newargs = PyTuple_New(PyTuple_GET_SIZE(args) + 2); + if (newargs == NULL) + return -1; + + cls_new = _PyObject_GetAttrId(cls, &PyId___new__); + if (cls_new == NULL) { + Py_DECREF(newargs); + return -1; + } + PyTuple_SET_ITEM(newargs, 0, cls_new); + Py_INCREF(cls); + PyTuple_SET_ITEM(newargs, 1, cls); + for (i = 0; i < PyTuple_GET_SIZE(args); i++) { + PyObject *item = PyTuple_GET_ITEM(args, i); + Py_INCREF(item); + PyTuple_SET_ITEM(newargs, i + 2, item); + } + + callable = PyObject_Call(st->partial, newargs, kwargs); + Py_DECREF(newargs); + if (callable == NULL) + return -1; + + newargs = PyTuple_New(0); + if (newargs == NULL) { + Py_DECREF(callable); + return -1; + } + + if (save(self, callable, 0) < 0 || + save(self, newargs, 0) < 0 || + _Pickler_Write(self, &reduce_op, 1) < 0) { + Py_DECREF(newargs); + Py_DECREF(callable); + return -1; + } + Py_DECREF(newargs); + Py_DECREF(callable); + } + } + else if (use_newobj) { + PyObject *cls; + PyObject *newargtup; + PyObject *obj_class; + int p; + + /* Sanity checks. */ + if (PyTuple_GET_SIZE(argtup) < 1) { + PyErr_SetString(st->PicklingError, "__newobj__ arglist is empty"); + return -1; + } + + cls = PyTuple_GET_ITEM(argtup, 0); + if (!PyType_Check(cls)) { + PyErr_SetString(st->PicklingError, "args[0] from " + "__newobj__ args is not a type"); + return -1; + } + + if (obj != NULL) { + obj_class = get_class(obj); + if (obj_class == NULL) { + return -1; + } + p = obj_class != cls; + Py_DECREF(obj_class); + if (p) { + PyErr_SetString(st->PicklingError, "args[0] from " + "__newobj__ args has the wrong class"); + return -1; + } + } + /* XXX: These calls save() are prone to infinite recursion. Imagine + what happen if the value returned by the __reduce__() method of + some extension type contains another object of the same type. Ouch! + + Here is a quick example, that I ran into, to illustrate what I + mean: + + >>> import pickle, copyreg + >>> copyreg.dispatch_table.pop(complex) + >>> pickle.dumps(1+2j) + Traceback (most recent call last): + ... + RecursionError: maximum recursion depth exceeded + + Removing the complex class from copyreg.dispatch_table made the + __reduce_ex__() method emit another complex object: + + >>> (1+1j).__reduce_ex__(2) + (, + (, (1+1j)), None, None, None) + + Thus when save() was called on newargstup (the 2nd item) recursion + ensued. Of course, the bug was in the complex class which had a + broken __getnewargs__() that emitted another complex object. But, + the point, here, is it is quite easy to end up with a broken reduce + function. */ + + /* Save the class and its __new__ arguments. */ + if (save(self, cls, 0) < 0) + return -1; + + newargtup = PyTuple_GetSlice(argtup, 1, PyTuple_GET_SIZE(argtup)); + if (newargtup == NULL) + return -1; + + p = save(self, newargtup, 0); + Py_DECREF(newargtup); + if (p < 0) + return -1; + + /* Add NEWOBJ opcode. */ + if (_Pickler_Write(self, &newobj_op, 1) < 0) + return -1; + } + else { /* Not using NEWOBJ. */ + if (save(self, callable, 0) < 0 || + save(self, argtup, 0) < 0 || + _Pickler_Write(self, &reduce_op, 1) < 0) + return -1; + } + + /* obj can be NULL when save_reduce() is used directly. A NULL obj means + the caller do not want to memoize the object. Not particularly useful, + but that is to mimic the behavior save_reduce() in pickle.py when + obj is None. */ + if (obj != NULL) { + /* If the object is already in the memo, this means it is + recursive. In this case, throw away everything we put on the + stack, and fetch the object back from the memo. */ + if (PyMemoTable_Get(self->memo, obj)) { + const char pop_op = POP; + + if (_Pickler_Write(self, &pop_op, 1) < 0) + return -1; + if (memo_get(self, obj) < 0) + return -1; + + return 0; + } + else if (memo_put(self, obj) < 0) + return -1; + } + + if (listitems && batch_list(self, listitems) < 0) + return -1; + + if (dictitems && batch_dict(self, dictitems) < 0) + return -1; + + if (state) { + if (state_setter == NULL) { + if (save(self, state, 0) < 0 || + _Pickler_Write(self, &build_op, 1) < 0) + return -1; + } + else { -Read a pickled object representation from the open file object given -in the constructor, and return the reconstituted object hierarchy -specified therein. -[clinic start generated code]*/ + /* If a state_setter is specified, call it instead of load_build to + * update obj's with its previous state. + * The first 4 save/write instructions push state_setter and its + * tuple of expected arguments (obj, state) onto the stack. The + * REDUCE opcode triggers the state_setter(obj, state) function + * call. Finally, because state-updating routines only do in-place + * modification, the whole operation has to be stack-transparent. + * Thus, we finally pop the call's output from the stack.*/ -static PyObject * -_pickle_Unpickler_load_impl(UnpicklerObject *self) -/*[clinic end generated code: output=fdcc488aad675b14 input=acbb91a42fa9b7b9]*/ -{ - UnpicklerObject *unpickler = (UnpicklerObject*)self; + const char tupletwo_op = TUPLE2; + const char pop_op = POP; + if (save(self, state_setter, 0) < 0 || + save(self, obj, 0) < 0 || save(self, state, 0) < 0 || + _Pickler_Write(self, &tupletwo_op, 1) < 0 || + _Pickler_Write(self, &reduce_op, 1) < 0 || + _Pickler_Write(self, &pop_op, 1) < 0) + return -1; + } + } + return 0; +} + +static int +save(PicklerObject *self, PyObject *obj, int pers_save) +{ + PyTypeObject *type; + PyObject *reduce_func = NULL; + PyObject *reduce_value = NULL; + int status = 0; + + if (_Pickler_OpcodeBoundary(self) < 0) + return -1; + + /* The extra pers_save argument is necessary to avoid calling save_pers() + on its returned object. */ + if (!pers_save && self->pers_func) { + /* save_pers() returns: + -1 to signal an error; + 0 if it did nothing successfully; + 1 if a persistent id was saved. + */ + if ((status = save_pers(self, obj)) != 0) + return status; + } + + type = Py_TYPE(obj); + + /* The old cPickle had an optimization that used switch-case statement + dispatching on the first letter of the type name. This has was removed + since benchmarks shown that this optimization was actually slowing + things down. */ + + /* Atom types; these aren't memoized, so don't check the memo. */ + + if (obj == Py_None) { + return save_none(self, obj); + } + else if (obj == Py_False || obj == Py_True) { + return save_bool(self, obj); + } + else if (type == &PyLong_Type) { + return save_long(self, obj); + } + else if (type == &PyFloat_Type) { + return save_float(self, obj); + } + + /* Check the memo to see if it has the object. If so, generate + a GET (or BINGET) opcode, instead of pickling the object + once again. */ + if (PyMemoTable_Get(self->memo, obj)) { + return memo_get(self, obj); + } + + if (type == &PyBytes_Type) { + return save_bytes(self, obj); + } + else if (type == &PyUnicode_Type) { + return save_unicode(self, obj); + } - /* Check whether the Unpickler was initialized correctly. This prevents - segfaulting if a subclass overridden __init__ with a function that does - not call Unpickler.__init__(). Here, we simply ensure that self->read - is not NULL. */ - if (unpickler->read == NULL) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->UnpicklingError, - "Unpickler.__init__() was not called by %s.__init__()", - Py_TYPE(unpickler)->tp_name); - return NULL; + /* We're only calling Py_EnterRecursiveCall here so that atomic + types above are pickled faster. */ + if (Py_EnterRecursiveCall(" while pickling an object")) { + return -1; } - return load(unpickler); -} - -/* The name of find_class() is misleading. In newer pickle protocols, this - function is used for loading any global (i.e., functions), not just - classes. The name is kept only for backward compatibility. */ - -/*[clinic input] - -_pickle.Unpickler.find_class - - module_name: object - global_name: object - / - -Return an object from a specified module. - -If necessary, the module will be imported. Subclasses may override -this method (e.g. to restrict unpickling of arbitrary classes and -functions). - -This method is called whenever a class or a function object is -needed. Both arguments passed are str objects. -[clinic start generated code]*/ - -static PyObject * -_pickle_Unpickler_find_class_impl(UnpicklerObject *self, - PyObject *module_name, - PyObject *global_name) -/*[clinic end generated code: output=becc08d7f9ed41e3 input=e2e6a865de093ef4]*/ -{ - PyObject *global; - PyObject *module; - - if (PySys_Audit("pickle.find_class", "OO", - module_name, global_name) < 0) { - return NULL; + if (type == &PyDict_Type) { + status = save_dict(self, obj); + goto done; + } + else if (type == &PySet_Type) { + status = save_set(self, obj); + goto done; + } + else if (type == &PyFrozenSet_Type) { + status = save_frozenset(self, obj); + goto done; + } + else if (type == &PyList_Type) { + status = save_list(self, obj); + goto done; + } + else if (type == &PyTuple_Type) { + status = save_tuple(self, obj); + goto done; + } + else if (type == &PyByteArray_Type) { + status = save_bytearray(self, obj); + goto done; + } + else if (type == &PyPickleBuffer_Type) { + status = save_picklebuffer(self, obj); + goto done; } - /* Try to map the old names used in Python 2.x to the new ones used in - Python 3.x. We do this only with old pickle protocols and when the - user has not disabled the feature. */ - if (self->proto < 3 && self->fix_imports) { - PyObject *key; - PyObject *item; - PickleState *st = _Pickle_GetGlobalState(); - - /* Check if the global (i.e., a function or a class) was renamed - or moved to another module. */ - key = PyTuple_Pack(2, module_name, global_name); - if (key == NULL) - return NULL; - item = PyDict_GetItemWithError(st->name_mapping_2to3, key); - Py_DECREF(key); - if (item) { - if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.NAME_MAPPING values should be " - "2-tuples, not %.200s", Py_TYPE(item)->tp_name); - return NULL; - } - module_name = PyTuple_GET_ITEM(item, 0); - global_name = PyTuple_GET_ITEM(item, 1); - if (!PyUnicode_Check(module_name) || - !PyUnicode_Check(global_name)) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.NAME_MAPPING values should be " - "pairs of str, not (%.200s, %.200s)", - Py_TYPE(module_name)->tp_name, - Py_TYPE(global_name)->tp_name); - return NULL; - } - } - else if (PyErr_Occurred()) { - return NULL; + /* Now, check reducer_override. If it returns NotImplemented, + * fallback to save_type or save_global, and then perhaps to the + * regular reduction mechanism. + */ + if (self->reducer_override != NULL) { + reduce_value = PyObject_CallOneArg(self->reducer_override, obj); + if (reduce_value == NULL) { + goto error; } - else { - /* Check if the module was renamed. */ - item = PyDict_GetItemWithError(st->import_mapping_2to3, module_name); - if (item) { - if (!PyUnicode_Check(item)) { - PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.IMPORT_MAPPING values should be " - "strings, not %.200s", Py_TYPE(item)->tp_name); - return NULL; - } - module_name = item; - } - else if (PyErr_Occurred()) { - return NULL; - } + if (reduce_value != Py_NotImplemented) { + goto reduce; } + Py_DECREF(reduce_value); + reduce_value = NULL; } - /* - * we don't use PyImport_GetModule here, because it can return partially- - * initialised modules, which then cause the getattribute to fail. - */ - module = PyImport_Import(module_name); - if (module == NULL) { - return NULL; + if (type == &PyType_Type) { + status = save_type(self, obj); + goto done; + } + else if (type == &PyFunction_Type) { + status = save_global(self, obj, NULL); + goto done; + } + + /* XXX: This part needs some unit tests. */ + + /* Get a reduction callable, and call it. This may come from + * self.dispatch_table, copyreg.dispatch_table, the object's + * __reduce_ex__ method, or the object's __reduce__ method. + */ + if (self->dispatch_table == NULL) { + PickleState *st = _Pickle_GetGlobalState(); + reduce_func = PyDict_GetItemWithError(st->dispatch_table, + (PyObject *)type); + if (reduce_func == NULL) { + if (PyErr_Occurred()) { + goto error; + } + } else { + /* PyDict_GetItemWithError() returns a borrowed reference. + Increase the reference count to be consistent with + PyObject_GetItem and _PyObject_GetAttrId used below. */ + Py_INCREF(reduce_func); + } + } else { + reduce_func = PyObject_GetItem(self->dispatch_table, + (PyObject *)type); + if (reduce_func == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_Clear(); + else + goto error; + } + } + if (reduce_func != NULL) { + Py_INCREF(obj); + reduce_value = _Pickle_FastCall(reduce_func, obj); + } + else if (PyType_IsSubtype(type, &PyType_Type)) { + status = save_global(self, obj, NULL); + goto done; + } + else { + _Py_IDENTIFIER(__reduce__); + _Py_IDENTIFIER(__reduce_ex__); + + /* XXX: If the __reduce__ method is defined, __reduce_ex__ is + automatically defined as __reduce__. While this is convenient, this + make it impossible to know which method was actually called. Of + course, this is not a big deal. But still, it would be nice to let + the user know which method was called when something go + wrong. Incidentally, this means if __reduce_ex__ is not defined, we + don't actually have to check for a __reduce__ method. */ + + /* Check for a __reduce_ex__ method. */ + if (_PyObject_LookupAttrId(obj, &PyId___reduce_ex__, &reduce_func) < 0) { + goto error; + } + if (reduce_func != NULL) { + PyObject *proto; + proto = PyLong_FromLong(self->proto); + if (proto != NULL) { + reduce_value = _Pickle_FastCall(reduce_func, proto); + } + } + else { + /* Check for a __reduce__ method. */ + if (_PyObject_LookupAttrId(obj, &PyId___reduce__, &reduce_func) < 0) { + goto error; + } + if (reduce_func != NULL) { + reduce_value = PyObject_CallNoArgs(reduce_func); + } + else { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->PicklingError, + "can't pickle '%.200s' object: %R", + type->tp_name, obj); + goto error; + } + } + } + + if (reduce_value == NULL) + goto error; + + reduce: + if (PyUnicode_Check(reduce_value)) { + status = save_global(self, obj, reduce_value); + goto done; + } + + if (!PyTuple_Check(reduce_value)) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->PicklingError, + "__reduce__ must return a string or tuple"); + goto error; + } + + status = save_reduce(self, reduce_value, obj); + + if (0) { + error: + status = -1; + } + done: + + Py_LeaveRecursiveCall(); + Py_XDECREF(reduce_func); + Py_XDECREF(reduce_value); + + return status; +} + +static int +dump(PicklerObject *self, PyObject *obj) +{ + const char stop_op = STOP; + int status = -1; + PyObject *tmp; + _Py_IDENTIFIER(reducer_override); + + if (_PyObject_LookupAttrId((PyObject *)self, &PyId_reducer_override, + &tmp) < 0) { + goto error; } - global = getattribute(module, global_name, self->proto >= 4); - Py_DECREF(module); - return global; -} - -/*[clinic input] - -_pickle.Unpickler.__sizeof__ -> Py_ssize_t - -Returns size in memory, in bytes. -[clinic start generated code]*/ - -static Py_ssize_t -_pickle_Unpickler___sizeof___impl(UnpicklerObject *self) -/*[clinic end generated code: output=119d9d03ad4c7651 input=13333471fdeedf5e]*/ -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); - if (self->memo != NULL) - res += self->memo_size * sizeof(PyObject *); - if (self->marks != NULL) - res += self->marks_size * sizeof(Py_ssize_t); - if (self->input_line != NULL) - res += strlen(self->input_line) + 1; - if (self->encoding != NULL) - res += strlen(self->encoding) + 1; - if (self->errors != NULL) - res += strlen(self->errors) + 1; - return res; -} - -static struct PyMethodDef Unpickler_methods[] = { - _PICKLE_UNPICKLER_LOAD_METHODDEF - _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF - _PICKLE_UNPICKLER___SIZEOF___METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static void -Unpickler_dealloc(UnpicklerObject *self) -{ - PyObject_GC_UnTrack((PyObject *)self); - Py_XDECREF(self->readline); - Py_XDECREF(self->readinto); - Py_XDECREF(self->read); - Py_XDECREF(self->peek); - Py_XDECREF(self->stack); - Py_XDECREF(self->pers_func); - Py_XDECREF(self->buffers); - if (self->buffer.buf != NULL) { - PyBuffer_Release(&self->buffer); - self->buffer.buf = NULL; + /* Cache the reducer_override method, if it exists. */ + if (tmp != NULL) { + Py_XSETREF(self->reducer_override, tmp); } - - _Unpickler_MemoCleanup(self); - PyMem_Free(self->marks); - PyMem_Free(self->input_line); - PyMem_Free(self->encoding); - PyMem_Free(self->errors); - - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->readline); - Py_VISIT(self->readinto); - Py_VISIT(self->read); - Py_VISIT(self->peek); - Py_VISIT(self->stack); - Py_VISIT(self->pers_func); - Py_VISIT(self->buffers); - return 0; -} - -static int -Unpickler_clear(UnpicklerObject *self) -{ - Py_CLEAR(self->readline); - Py_CLEAR(self->readinto); - Py_CLEAR(self->read); - Py_CLEAR(self->peek); - Py_CLEAR(self->stack); - Py_CLEAR(self->pers_func); - Py_CLEAR(self->buffers); - if (self->buffer.buf != NULL) { - PyBuffer_Release(&self->buffer); - self->buffer.buf = NULL; + else { + Py_CLEAR(self->reducer_override); } - _Unpickler_MemoCleanup(self); - PyMem_Free(self->marks); - self->marks = NULL; - PyMem_Free(self->input_line); - self->input_line = NULL; - PyMem_Free(self->encoding); - self->encoding = NULL; - PyMem_Free(self->errors); - self->errors = NULL; - - return 0; -} - -/*[clinic input] - -_pickle.Unpickler.__init__ - - file: object - * - fix_imports: bool = True - encoding: str = 'ASCII' - errors: str = 'strict' - buffers: object(c_default="NULL") = () - -This takes a binary file for reading a pickle data stream. - -The protocol version of the pickle is detected automatically, so no -protocol argument is needed. Bytes past the pickled object's -representation are ignored. + if (self->proto >= 2) { + char header[2]; + + header[0] = PROTO; + assert(self->proto >= 0 && self->proto < 256); + header[1] = (unsigned char)self->proto; + if (_Pickler_Write(self, header, 2) < 0) + goto error; + if (self->proto >= 4) + self->framing = 1; + } + + if (save(self, obj, 0) < 0 || + _Pickler_Write(self, &stop_op, 1) < 0 || + _Pickler_CommitFrame(self) < 0) + goto error; -The argument *file* must have two methods, a read() method that takes -an integer argument, and a readline() method that requires no -arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, an io.BytesIO object, or any -other custom object that meets this interface. + // Success + status = 0; -Optional keyword arguments are *fix_imports*, *encoding* and *errors*, -which are used to control compatibility support for pickle stream -generated by Python 2. If *fix_imports* is True, pickle will try to -map the old Python 2 names to the new names used in Python 3. The -*encoding* and *errors* tell pickle how to decode 8-bit string -instances pickled by Python 2; these default to 'ASCII' and 'strict', -respectively. The *encoding* can be 'bytes' to read these 8-bit -string instances as bytes objects. -[clinic start generated code]*/ + error: + self->framing = 0; -static int -_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, - int fix_imports, const char *encoding, - const char *errors, PyObject *buffers) -/*[clinic end generated code: output=09f0192649ea3f85 input=ca4c1faea9553121]*/ -{ - _Py_IDENTIFIER(persistent_load); + /* Break the reference cycle we generated at the beginning this function + * call when setting the reducer_override attribute of the Pickler instance + * to a bound method of the same instance. This is important as the Pickler + * instance holds a reference to each object it has pickled (through its + * memo): thus, these objects won't be garbage-collected as long as the + * Pickler itself is not collected. */ + Py_CLEAR(self->reducer_override); + return status; +} + +/*[clinic input] + +_pickle.Pickler.clear_memo + +Clears the pickler's "memo". + +The memo is the data structure that remembers which objects the +pickler has already seen, so that shared or recursive objects are +pickled by reference and not by value. This method is useful when +re-using picklers. +[clinic start generated code]*/ + +static PyObject * +_pickle_Pickler_clear_memo_impl(PicklerObject *self) +/*[clinic end generated code: output=8665c8658aaa094b input=01bdad52f3d93e56]*/ +{ + if (self->memo) + PyMemoTable_Clear(self->memo); + + Py_RETURN_NONE; +} + +/*[clinic input] + +_pickle.Pickler.dump + + obj: object + / + +Write a pickled representation of the given object to the open file. +[clinic start generated code]*/ + +static PyObject * +_pickle_Pickler_dump(PicklerObject *self, PyObject *obj) +/*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ +{ + /* Check whether the Pickler was initialized correctly (issue3664). + Developers often forget to call __init__() in their subclasses, which + would trigger a segfault without this check. */ + if (self->write == NULL) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->PicklingError, + "Pickler.__init__() was not called by %s.__init__()", + Py_TYPE(self)->tp_name); + return NULL; + } + + if (_Pickler_ClearBuffer(self) < 0) + return NULL; + + if (dump(self, obj) < 0) + return NULL; + + if (_Pickler_FlushToFile(self) < 0) + return NULL; + + Py_RETURN_NONE; +} + +/*[clinic input] + +_pickle.Pickler.__sizeof__ -> Py_ssize_t + +Returns size in memory, in bytes. +[clinic start generated code]*/ + +static Py_ssize_t +_pickle_Pickler___sizeof___impl(PicklerObject *self) +/*[clinic end generated code: output=106edb3123f332e1 input=8cbbec9bd5540d42]*/ +{ + Py_ssize_t res, s; + + res = _PyObject_SIZE(Py_TYPE(self)); + if (self->memo != NULL) { + res += sizeof(PyMemoTable); + res += self->memo->mt_allocated * sizeof(PyMemoEntry); + } + if (self->output_buffer != NULL) { + s = _PySys_GetSizeOf(self->output_buffer); + if (s == -1) + return -1; + res += s; + } + return res; +} + +static struct PyMethodDef Pickler_methods[] = { + _PICKLE_PICKLER_DUMP_METHODDEF + _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF + _PICKLE_PICKLER___SIZEOF___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static void +Pickler_dealloc(PicklerObject *self) +{ + PyObject_GC_UnTrack(self); + + Py_XDECREF(self->output_buffer); + Py_XDECREF(self->write); + Py_XDECREF(self->pers_func); + Py_XDECREF(self->dispatch_table); + Py_XDECREF(self->fast_memo); + Py_XDECREF(self->reducer_override); + Py_XDECREF(self->buffer_callback); + + PyMemoTable_Del(self->memo); + + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +Pickler_traverse(PicklerObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->write); + Py_VISIT(self->pers_func); + Py_VISIT(self->dispatch_table); + Py_VISIT(self->fast_memo); + Py_VISIT(self->reducer_override); + Py_VISIT(self->buffer_callback); + return 0; +} + +static int +Pickler_clear(PicklerObject *self) +{ + Py_CLEAR(self->output_buffer); + Py_CLEAR(self->write); + Py_CLEAR(self->pers_func); + Py_CLEAR(self->dispatch_table); + Py_CLEAR(self->fast_memo); + Py_CLEAR(self->reducer_override); + Py_CLEAR(self->buffer_callback); + + if (self->memo != NULL) { + PyMemoTable *memo = self->memo; + self->memo = NULL; + PyMemoTable_Del(memo); + } + return 0; +} + + +/*[clinic input] + +_pickle.Pickler.__init__ + + file: object + protocol: object = None + fix_imports: bool = True + buffer_callback: object = None + +This takes a binary file for writing a pickle data stream. + +The optional *protocol* argument tells the pickler to use the given +protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default +protocol is 4. It was introduced in Python 3.4, and is incompatible +with previous versions. + +Specifying a negative protocol version selects the highest protocol +version supported. The higher the protocol used, the more recent the +version of Python needed to read the pickle produced. + +The *file* argument must have a write() method that accepts a single +bytes argument. It can thus be a file object opened for binary +writing, an io.BytesIO instance, or any other custom object that meets +this interface. + +If *fix_imports* is True and protocol is less than 3, pickle will try +to map the new Python 3 names to the old module names used in Python +2, so that the pickle data stream is readable with Python 2. - /* In case of multiple __init__() calls, clear previous content. */ - if (self->read != NULL) - (void)Unpickler_clear(self); +If *buffer_callback* is None (the default), buffer views are +serialized into *file* as part of the pickle stream. - if (_Unpickler_SetInputStream(self, file) < 0) - return -1; +If *buffer_callback* is not None, then it can be called any number +of times with a buffer view. If the callback returns a false value +(such as None), the given buffer is out-of-band; otherwise the +buffer is serialized in-band, i.e. inside the pickle stream. - if (_Unpickler_SetInputEncoding(self, encoding, errors) < 0) - return -1; +It is an error if *buffer_callback* is not None and *protocol* +is None or smaller than 5. - if (_Unpickler_SetBuffers(self, buffers) < 0) +[clinic start generated code]*/ + +static int +_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, + PyObject *protocol, int fix_imports, + PyObject *buffer_callback) +/*[clinic end generated code: output=0abedc50590d259b input=a7c969699bf5dad3]*/ +{ + _Py_IDENTIFIER(persistent_id); + _Py_IDENTIFIER(dispatch_table); + + /* In case of multiple __init__() calls, clear previous content. */ + if (self->write != NULL) + (void)Pickler_clear(self); + + if (_Pickler_SetProtocol(self, protocol, fix_imports) < 0) + return -1; + + if (_Pickler_SetOutputStream(self, file) < 0) + return -1; + + if (_Pickler_SetBufferCallback(self, buffer_callback) < 0) return -1; - self->fix_imports = fix_imports; - - if (init_method_ref((PyObject *)self, &PyId_persistent_load, - &self->pers_func, &self->pers_func_self) < 0) - { + /* memo and output_buffer may have already been created in _Pickler_New */ + if (self->memo == NULL) { + self->memo = PyMemoTable_New(); + if (self->memo == NULL) + return -1; + } + self->output_len = 0; + if (self->output_buffer == NULL) { + self->max_output_len = WRITE_BUF_SIZE; + self->output_buffer = PyBytes_FromStringAndSize(NULL, + self->max_output_len); + if (self->output_buffer == NULL) + return -1; + } + + self->fast = 0; + self->fast_nesting = 0; + self->fast_memo = NULL; + + if (init_method_ref((PyObject *)self, &PyId_persistent_id, + &self->pers_func, &self->pers_func_self) < 0) + { + return -1; + } + + if (_PyObject_LookupAttrId((PyObject *)self, + &PyId_dispatch_table, &self->dispatch_table) < 0) { + return -1; + } + + return 0; +} + + +/* Define a proxy object for the Pickler's internal memo object. This is to + * avoid breaking code like: + * pickler.memo.clear() + * and + * pickler.memo = saved_memo + * Is this a good idea? Not really, but we don't want to break code that uses + * it. Note that we don't implement the entire mapping API here. This is + * intentional, as these should be treated as black-box implementation details. + */ + +/*[clinic input] +_pickle.PicklerMemoProxy.clear + +Remove all items from memo. +[clinic start generated code]*/ + +static PyObject * +_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self) +/*[clinic end generated code: output=5fb9370d48ae8b05 input=ccc186dacd0f1405]*/ +{ + if (self->pickler->memo) + PyMemoTable_Clear(self->pickler->memo); + Py_RETURN_NONE; +} + +/*[clinic input] +_pickle.PicklerMemoProxy.copy + +Copy the memo to a new object. +[clinic start generated code]*/ + +static PyObject * +_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self) +/*[clinic end generated code: output=bb83a919d29225ef input=b73043485ac30b36]*/ +{ + PyMemoTable *memo; + PyObject *new_memo = PyDict_New(); + if (new_memo == NULL) + return NULL; + + memo = self->pickler->memo; + for (size_t i = 0; i < memo->mt_allocated; ++i) { + PyMemoEntry entry = memo->mt_table[i]; + if (entry.me_key != NULL) { + int status; + PyObject *key, *value; + + key = PyLong_FromVoidPtr(entry.me_key); + value = Py_BuildValue("nO", entry.me_value, entry.me_key); + + if (key == NULL || value == NULL) { + Py_XDECREF(key); + Py_XDECREF(value); + goto error; + } + status = PyDict_SetItem(new_memo, key, value); + Py_DECREF(key); + Py_DECREF(value); + if (status < 0) + goto error; + } + } + return new_memo; + + error: + Py_XDECREF(new_memo); + return NULL; +} + +/*[clinic input] +_pickle.PicklerMemoProxy.__reduce__ + +Implement pickle support. +[clinic start generated code]*/ + +static PyObject * +_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) +/*[clinic end generated code: output=bebba1168863ab1d input=2f7c540e24b7aae4]*/ +{ + PyObject *reduce_value, *dict_args; + PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self); + if (contents == NULL) + return NULL; + + reduce_value = PyTuple_New(2); + if (reduce_value == NULL) { + Py_DECREF(contents); + return NULL; + } + dict_args = PyTuple_New(1); + if (dict_args == NULL) { + Py_DECREF(contents); + Py_DECREF(reduce_value); + return NULL; + } + PyTuple_SET_ITEM(dict_args, 0, contents); + Py_INCREF((PyObject *)&PyDict_Type); + PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); + PyTuple_SET_ITEM(reduce_value, 1, dict_args); + return reduce_value; +} + +static PyMethodDef picklerproxy_methods[] = { + _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF + _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF + _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static void +PicklerMemoProxy_dealloc(PicklerMemoProxyObject *self) +{ + PyObject_GC_UnTrack(self); + Py_XDECREF(self->pickler); + PyObject_GC_Del((PyObject *)self); +} + +static int +PicklerMemoProxy_traverse(PicklerMemoProxyObject *self, + visitproc visit, void *arg) +{ + Py_VISIT(self->pickler); + return 0; +} + +static int +PicklerMemoProxy_clear(PicklerMemoProxyObject *self) +{ + Py_CLEAR(self->pickler); + return 0; +} + +static PyTypeObject PicklerMemoProxyType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_pickle.PicklerMemoProxy", /*tp_name*/ + sizeof(PicklerMemoProxyObject), /*tp_basicsize*/ + 0, + (destructor)PicklerMemoProxy_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + PyObject_HashNotImplemented, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + 0, /* tp_doc */ + (traverseproc)PicklerMemoProxy_traverse, /* tp_traverse */ + (inquiry)PicklerMemoProxy_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + picklerproxy_methods, /* tp_methods */ +}; + +static PyObject * +PicklerMemoProxy_New(PicklerObject *pickler) +{ + PicklerMemoProxyObject *self; + + self = PyObject_GC_New(PicklerMemoProxyObject, &PicklerMemoProxyType); + if (self == NULL) + return NULL; + Py_INCREF(pickler); + self->pickler = pickler; + PyObject_GC_Track(self); + return (PyObject *)self; +} + +/*****************************************************************************/ + +static PyObject * +Pickler_get_memo(PicklerObject *self, void *Py_UNUSED(ignored)) +{ + return PicklerMemoProxy_New(self); +} + +static int +Pickler_set_memo(PicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored)) +{ + PyMemoTable *new_memo = NULL; + + if (obj == NULL) { + PyErr_SetString(PyExc_TypeError, + "attribute deletion is not supported"); + return -1; + } + + if (Py_IS_TYPE(obj, &PicklerMemoProxyType)) { + PicklerObject *pickler = + ((PicklerMemoProxyObject *)obj)->pickler; + + new_memo = PyMemoTable_Copy(pickler->memo); + if (new_memo == NULL) + return -1; + } + else if (PyDict_Check(obj)) { + Py_ssize_t i = 0; + PyObject *key, *value; + + new_memo = PyMemoTable_New(); + if (new_memo == NULL) + return -1; + + while (PyDict_Next(obj, &i, &key, &value)) { + Py_ssize_t memo_id; + PyObject *memo_obj; + + if (!PyTuple_Check(value) || PyTuple_GET_SIZE(value) != 2) { + PyErr_SetString(PyExc_TypeError, + "'memo' values must be 2-item tuples"); + goto error; + } + memo_id = PyLong_AsSsize_t(PyTuple_GET_ITEM(value, 0)); + if (memo_id == -1 && PyErr_Occurred()) + goto error; + memo_obj = PyTuple_GET_ITEM(value, 1); + if (PyMemoTable_Set(new_memo, memo_obj, memo_id) < 0) + goto error; + } + } + else { + PyErr_Format(PyExc_TypeError, + "'memo' attribute must be a PicklerMemoProxy object " + "or dict, not %.200s", Py_TYPE(obj)->tp_name); + return -1; + } + + PyMemoTable_Del(self->memo); + self->memo = new_memo; + + return 0; + + error: + if (new_memo) + PyMemoTable_Del(new_memo); + return -1; +} + +static PyObject * +Pickler_get_persid(PicklerObject *self, void *Py_UNUSED(ignored)) +{ + if (self->pers_func == NULL) { + PyErr_SetString(PyExc_AttributeError, "persistent_id"); + return NULL; + } + return reconstruct_method(self->pers_func, self->pers_func_self); +} + +static int +Pickler_set_persid(PicklerObject *self, PyObject *value, void *Py_UNUSED(ignored)) +{ + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "attribute deletion is not supported"); + return -1; + } + if (!PyCallable_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "persistent_id must be a callable taking one argument"); + return -1; + } + + self->pers_func_self = NULL; + Py_INCREF(value); + Py_XSETREF(self->pers_func, value); + + return 0; +} + +static PyMemberDef Pickler_members[] = { + {"bin", T_INT, offsetof(PicklerObject, bin)}, + {"fast", T_INT, offsetof(PicklerObject, fast)}, + {"dispatch_table", T_OBJECT_EX, offsetof(PicklerObject, dispatch_table)}, + {NULL} +}; + +static PyGetSetDef Pickler_getsets[] = { + {"memo", (getter)Pickler_get_memo, + (setter)Pickler_set_memo}, + {"persistent_id", (getter)Pickler_get_persid, + (setter)Pickler_set_persid}, + {NULL} +}; + +static PyTypeObject Pickler_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_pickle.Pickler" , /*tp_name*/ + sizeof(PicklerObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)Pickler_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + _pickle_Pickler___init____doc__, /*tp_doc*/ + (traverseproc)Pickler_traverse, /*tp_traverse*/ + (inquiry)Pickler_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Pickler_methods, /*tp_methods*/ + Pickler_members, /*tp_members*/ + Pickler_getsets, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + _pickle_Pickler___init__, /*tp_init*/ + PyType_GenericAlloc, /*tp_alloc*/ + PyType_GenericNew, /*tp_new*/ + PyObject_GC_Del, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +/* Temporary helper for calling self.find_class(). + + XXX: It would be nice to able to avoid Python function call overhead, by + using directly the C version of find_class(), when find_class() is not + overridden by a subclass. Although, this could become rather hackish. A + simpler optimization would be to call the C function when self is not a + subclass instance. */ +static PyObject * +find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) +{ + _Py_IDENTIFIER(find_class); + + return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_find_class, + module_name, global_name, NULL); +} + +static Py_ssize_t +marker(UnpicklerObject *self) +{ + Py_ssize_t mark; + + if (self->num_marks < 1) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, "could not find MARK"); + return -1; + } + + mark = self->marks[--self->num_marks]; + self->stack->mark_set = self->num_marks != 0; + self->stack->fence = self->num_marks ? + self->marks[self->num_marks - 1] : 0; + return mark; +} + +static int +load_none(UnpicklerObject *self) +{ + PDATA_APPEND(self->stack, Py_None, -1); + return 0; +} + +static int +load_int(UnpicklerObject *self) +{ + PyObject *value; + char *endptr, *s; + Py_ssize_t len; + long x; + + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 2) + return bad_readline(); + + errno = 0; + /* XXX: Should the base argument of strtol() be explicitly set to 10? + XXX(avassalotti): Should this uses PyOS_strtol()? */ + x = strtol(s, &endptr, 0); + + if (errno || (*endptr != '\n' && *endptr != '\0')) { + /* Hm, maybe we've got something long. Let's try reading + * it as a Python int object. */ + errno = 0; + /* XXX: Same thing about the base here. */ + value = PyLong_FromString(s, NULL, 0); + if (value == NULL) { + PyErr_SetString(PyExc_ValueError, + "could not convert string to int"); + return -1; + } + } + else { + if (len == 3 && (x == 0 || x == 1)) { + if ((value = PyBool_FromLong(x)) == NULL) + return -1; + } + else { + if ((value = PyLong_FromLong(x)) == NULL) + return -1; + } + } + + PDATA_PUSH(self->stack, value, -1); + return 0; +} + +static int +load_bool(UnpicklerObject *self, PyObject *boolean) +{ + assert(boolean == Py_True || boolean == Py_False); + PDATA_APPEND(self->stack, boolean, -1); + return 0; +} + +/* s contains x bytes of an unsigned little-endian integer. Return its value + * as a C Py_ssize_t, or -1 if it's higher than PY_SSIZE_T_MAX. + */ +static Py_ssize_t +calc_binsize(char *bytes, int nbytes) +{ + unsigned char *s = (unsigned char *)bytes; + int i; + size_t x = 0; + + if (nbytes > (int)sizeof(size_t)) { + /* Check for integer overflow. BINBYTES8 and BINUNICODE8 opcodes + * have 64-bit size that can't be represented on 32-bit platform. + */ + for (i = (int)sizeof(size_t); i < nbytes; i++) { + if (s[i]) + return -1; + } + nbytes = (int)sizeof(size_t); + } + for (i = 0; i < nbytes; i++) { + x |= (size_t) s[i] << (8 * i); + } + + if (x > PY_SSIZE_T_MAX) + return -1; + else + return (Py_ssize_t) x; +} + +/* s contains x bytes of a little-endian integer. Return its value as a + * C int. Obscure: when x is 1 or 2, this is an unsigned little-endian + * int, but when x is 4 it's a signed one. This is a historical source + * of x-platform bugs. + */ +static long +calc_binint(char *bytes, int nbytes) +{ + unsigned char *s = (unsigned char *)bytes; + Py_ssize_t i; + long x = 0; + + for (i = 0; i < nbytes; i++) { + x |= (long)s[i] << (8 * i); + } + + /* Unlike BININT1 and BININT2, BININT (more accurately BININT4) + * is signed, so on a box with longs bigger than 4 bytes we need + * to extend a BININT's sign bit to the full width. + */ + if (SIZEOF_LONG > 4 && nbytes == 4) { + x |= -(x & (1L << 31)); + } + + return x; +} + +static int +load_binintx(UnpicklerObject *self, char *s, int size) +{ + PyObject *value; + long x; + + x = calc_binint(s, size); + + if ((value = PyLong_FromLong(x)) == NULL) + return -1; + + PDATA_PUSH(self->stack, value, -1); + return 0; +} + +static int +load_binint(UnpicklerObject *self) +{ + char *s; + + if (_Unpickler_Read(self, &s, 4) < 0) + return -1; + + return load_binintx(self, s, 4); +} + +static int +load_binint1(UnpicklerObject *self) +{ + char *s; + + if (_Unpickler_Read(self, &s, 1) < 0) + return -1; + + return load_binintx(self, s, 1); +} + +static int +load_binint2(UnpicklerObject *self) +{ + char *s; + + if (_Unpickler_Read(self, &s, 2) < 0) + return -1; + + return load_binintx(self, s, 2); +} + +static int +load_long(UnpicklerObject *self) +{ + PyObject *value; + char *s = NULL; + Py_ssize_t len; + + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 2) + return bad_readline(); + + /* s[len-2] will usually be 'L' (and s[len-1] is '\n'); we need to remove + the 'L' before calling PyLong_FromString. In order to maintain + compatibility with Python 3.0.0, we don't actually *require* + the 'L' to be present. */ + if (s[len-2] == 'L') + s[len-2] = '\0'; + /* XXX: Should the base argument explicitly set to 10? */ + value = PyLong_FromString(s, NULL, 0); + if (value == NULL) + return -1; + + PDATA_PUSH(self->stack, value, -1); + return 0; +} + +/* 'size' bytes contain the # of bytes of little-endian 256's-complement + * data following. + */ +static int +load_counted_long(UnpicklerObject *self, int size) +{ + PyObject *value; + char *nbytes; + char *pdata; + + assert(size == 1 || size == 4); + if (_Unpickler_Read(self, &nbytes, size) < 0) + return -1; + + size = calc_binint(nbytes, size); + if (size < 0) { + PickleState *st = _Pickle_GetGlobalState(); + /* Corrupt or hostile pickle -- we never write one like this */ + PyErr_SetString(st->UnpicklingError, + "LONG pickle has negative byte count"); + return -1; + } + + if (size == 0) + value = PyLong_FromLong(0L); + else { + /* Read the raw little-endian bytes and convert. */ + if (_Unpickler_Read(self, &pdata, size) < 0) + return -1; + value = _PyLong_FromByteArray((unsigned char *)pdata, (size_t)size, + 1 /* little endian */ , 1 /* signed */ ); + } + if (value == NULL) + return -1; + PDATA_PUSH(self->stack, value, -1); + return 0; +} + +static int +load_float(UnpicklerObject *self) +{ + PyObject *value; + char *endptr, *s; + Py_ssize_t len; + double d; + + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 2) + return bad_readline(); + + errno = 0; + d = PyOS_string_to_double(s, &endptr, PyExc_OverflowError); + if (d == -1.0 && PyErr_Occurred()) + return -1; + if ((endptr[0] != '\n') && (endptr[0] != '\0')) { + PyErr_SetString(PyExc_ValueError, "could not convert string to float"); + return -1; + } + value = PyFloat_FromDouble(d); + if (value == NULL) + return -1; + + PDATA_PUSH(self->stack, value, -1); + return 0; +} + +static int +load_binfloat(UnpicklerObject *self) +{ + PyObject *value; + double x; + char *s; + + if (_Unpickler_Read(self, &s, 8) < 0) + return -1; + + x = _PyFloat_Unpack8((unsigned char *)s, 0); + if (x == -1.0 && PyErr_Occurred()) + return -1; + + if ((value = PyFloat_FromDouble(x)) == NULL) + return -1; + + PDATA_PUSH(self->stack, value, -1); + return 0; +} + +static int +load_string(UnpicklerObject *self) +{ + PyObject *bytes; + PyObject *obj; + Py_ssize_t len; + char *s, *p; + + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + /* Strip the newline */ + len--; + /* Strip outermost quotes */ + if (len >= 2 && s[0] == s[len - 1] && (s[0] == '\'' || s[0] == '"')) { + p = s + 1; + len -= 2; + } + else { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "the STRING opcode argument must be quoted"); + return -1; + } + assert(len >= 0); + + /* Use the PyBytes API to decode the string, since that is what is used + to encode, and then coerce the result to Unicode. */ + bytes = PyBytes_DecodeEscape(p, len, NULL, 0, NULL); + if (bytes == NULL) + return -1; + + /* Leave the Python 2.x strings as bytes if the *encoding* given to the + Unpickler was 'bytes'. Otherwise, convert them to unicode. */ + if (strcmp(self->encoding, "bytes") == 0) { + obj = bytes; + } + else { + obj = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors); + Py_DECREF(bytes); + if (obj == NULL) { + return -1; + } + } + + PDATA_PUSH(self->stack, obj, -1); + return 0; +} + +static int +load_counted_binstring(UnpicklerObject *self, int nbytes) +{ + PyObject *obj; + Py_ssize_t size; + char *s; + + if (_Unpickler_Read(self, &s, nbytes) < 0) + return -1; + + size = calc_binsize(s, nbytes); + if (size < 0) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, + "BINSTRING exceeds system's maximum size of %zd bytes", + PY_SSIZE_T_MAX); + return -1; + } + + if (_Unpickler_Read(self, &s, size) < 0) + return -1; + + /* Convert Python 2.x strings to bytes if the *encoding* given to the + Unpickler was 'bytes'. Otherwise, convert them to unicode. */ + if (strcmp(self->encoding, "bytes") == 0) { + obj = PyBytes_FromStringAndSize(s, size); + } + else { + obj = PyUnicode_Decode(s, size, self->encoding, self->errors); + } + if (obj == NULL) { + return -1; + } + + PDATA_PUSH(self->stack, obj, -1); + return 0; +} + +static int +load_counted_binbytes(UnpicklerObject *self, int nbytes) +{ + PyObject *bytes; + Py_ssize_t size; + char *s; + + if (_Unpickler_Read(self, &s, nbytes) < 0) + return -1; + + size = calc_binsize(s, nbytes); + if (size < 0) { + PyErr_Format(PyExc_OverflowError, + "BINBYTES exceeds system's maximum size of %zd bytes", + PY_SSIZE_T_MAX); + return -1; + } + + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) + return -1; + if (_Unpickler_ReadInto(self, PyBytes_AS_STRING(bytes), size) < 0) { + Py_DECREF(bytes); return -1; } + + PDATA_PUSH(self->stack, bytes, -1); + return 0; +} + +static int +load_counted_bytearray(UnpicklerObject *self) +{ + PyObject *bytearray; + Py_ssize_t size; + char *s; - self->stack = (Pdata *)Pdata_New(); - if (self->stack == NULL) + if (_Unpickler_Read(self, &s, 8) < 0) { return -1; + } - self->memo_size = 32; - self->memo = _Unpickler_NewMemo(self->memo_size); - if (self->memo == NULL) + size = calc_binsize(s, 8); + if (size < 0) { + PyErr_Format(PyExc_OverflowError, + "BYTEARRAY8 exceeds system's maximum size of %zd bytes", + PY_SSIZE_T_MAX); return -1; - - self->proto = 0; - - return 0; -} - - -/* Define a proxy object for the Unpickler's internal memo object. This is to - * avoid breaking code like: - * unpickler.memo.clear() - * and - * unpickler.memo = saved_memo - * Is this a good idea? Not really, but we don't want to break code that uses - * it. Note that we don't implement the entire mapping API here. This is - * intentional, as these should be treated as black-box implementation details. - * - * We do, however, have to implement pickling/unpickling support because of - * real-world code like cvs2svn. - */ - -/*[clinic input] -_pickle.UnpicklerMemoProxy.clear - -Remove all items from memo. -[clinic start generated code]*/ - -static PyObject * -_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self) -/*[clinic end generated code: output=d20cd43f4ba1fb1f input=b1df7c52e7afd9bd]*/ -{ - _Unpickler_MemoCleanup(self->unpickler); - self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size); - if (self->unpickler->memo == NULL) - return NULL; - Py_RETURN_NONE; -} - -/*[clinic input] -_pickle.UnpicklerMemoProxy.copy - -Copy the memo to a new object. -[clinic start generated code]*/ - -static PyObject * -_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self) -/*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/ -{ - size_t i; - PyObject *new_memo = PyDict_New(); - if (new_memo == NULL) - return NULL; - - for (i = 0; i < self->unpickler->memo_size; i++) { - int status; - PyObject *key, *value; - - value = self->unpickler->memo[i]; - if (value == NULL) - continue; - - key = PyLong_FromSsize_t(i); - if (key == NULL) - goto error; - status = PyDict_SetItem(new_memo, key, value); - Py_DECREF(key); - if (status < 0) - goto error; } - return new_memo; - -error: - Py_DECREF(new_memo); - return NULL; -} - -/*[clinic input] -_pickle.UnpicklerMemoProxy.__reduce__ - -Implement pickling support. -[clinic start generated code]*/ -static PyObject * -_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self) -/*[clinic end generated code: output=6da34ac048d94cca input=6920862413407199]*/ -{ - PyObject *reduce_value; - PyObject *constructor_args; - PyObject *contents = _pickle_UnpicklerMemoProxy_copy_impl(self); - if (contents == NULL) - return NULL; - - reduce_value = PyTuple_New(2); - if (reduce_value == NULL) { - Py_DECREF(contents); - return NULL; + bytearray = PyByteArray_FromStringAndSize(NULL, size); + if (bytearray == NULL) { + return -1; } - constructor_args = PyTuple_New(1); - if (constructor_args == NULL) { - Py_DECREF(contents); - Py_DECREF(reduce_value); - return NULL; + if (_Unpickler_ReadInto(self, PyByteArray_AS_STRING(bytearray), size) < 0) { + Py_DECREF(bytearray); + return -1; } - PyTuple_SET_ITEM(constructor_args, 0, contents); - Py_INCREF((PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 1, constructor_args); - return reduce_value; -} - -static PyMethodDef unpicklerproxy_methods[] = { - _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF - _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF - _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static void -UnpicklerMemoProxy_dealloc(UnpicklerMemoProxyObject *self) -{ - PyObject_GC_UnTrack(self); - Py_XDECREF(self->unpickler); - PyObject_GC_Del((PyObject *)self); -} -static int -UnpicklerMemoProxy_traverse(UnpicklerMemoProxyObject *self, - visitproc visit, void *arg) -{ - Py_VISIT(self->unpickler); + PDATA_PUSH(self->stack, bytearray, -1); return 0; } static int -UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self) -{ - Py_CLEAR(self->unpickler); - return 0; -} - -static PyTypeObject UnpicklerMemoProxyType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.UnpicklerMemoProxy", /*tp_name*/ - sizeof(UnpicklerMemoProxyObject), /*tp_basicsize*/ - 0, - (destructor)UnpicklerMemoProxy_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - 0, /* tp_doc */ - (traverseproc)UnpicklerMemoProxy_traverse, /* tp_traverse */ - (inquiry)UnpicklerMemoProxy_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - unpicklerproxy_methods, /* tp_methods */ -}; - -static PyObject * -UnpicklerMemoProxy_New(UnpicklerObject *unpickler) +load_next_buffer(UnpicklerObject *self) { - UnpicklerMemoProxyObject *self; - - self = PyObject_GC_New(UnpicklerMemoProxyObject, - &UnpicklerMemoProxyType); - if (self == NULL) - return NULL; - Py_INCREF(unpickler); - self->unpickler = unpickler; - PyObject_GC_Track(self); - return (PyObject *)self; -} - -/*****************************************************************************/ - + if (self->buffers == NULL) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "pickle stream refers to out-of-band data " + "but no *buffers* argument was given"); + return -1; + } + PyObject *buf = PyIter_Next(self->buffers); + if (buf == NULL) { + if (!PyErr_Occurred()) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "not enough out-of-band buffers"); + } + return -1; + } -static PyObject * -Unpickler_get_memo(UnpicklerObject *self, void *Py_UNUSED(ignored)) -{ - return UnpicklerMemoProxy_New(self); + PDATA_PUSH(self->stack, buf, -1); + return 0; } static int -Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored)) +load_readonly_buffer(UnpicklerObject *self) { - PyObject **new_memo; - size_t new_memo_size = 0; - - if (obj == NULL) { - PyErr_SetString(PyExc_TypeError, - "attribute deletion is not supported"); - return -1; + Py_ssize_t len = Py_SIZE(self->stack); + if (len <= self->stack->fence) { + return Pdata_stack_underflow(self->stack); } - if (Py_IS_TYPE(obj, &UnpicklerMemoProxyType)) { - UnpicklerObject *unpickler = - ((UnpicklerMemoProxyObject *)obj)->unpickler; - - new_memo_size = unpickler->memo_size; - new_memo = _Unpickler_NewMemo(new_memo_size); - if (new_memo == NULL) - return -1; - - for (size_t i = 0; i < new_memo_size; i++) { - Py_XINCREF(unpickler->memo[i]); - new_memo[i] = unpickler->memo[i]; - } + PyObject *obj = self->stack->data[len - 1]; + PyObject *view = PyMemoryView_FromObject(obj); + if (view == NULL) { + return -1; } - else if (PyDict_Check(obj)) { - Py_ssize_t i = 0; - PyObject *key, *value; - - new_memo_size = PyDict_GET_SIZE(obj); - new_memo = _Unpickler_NewMemo(new_memo_size); - if (new_memo == NULL) - return -1; - - while (PyDict_Next(obj, &i, &key, &value)) { - Py_ssize_t idx; - if (!PyLong_Check(key)) { - PyErr_SetString(PyExc_TypeError, - "memo key must be integers"); - goto error; - } - idx = PyLong_AsSsize_t(key); - if (idx == -1 && PyErr_Occurred()) - goto error; - if (idx < 0) { - PyErr_SetString(PyExc_ValueError, - "memo key must be positive integers."); - goto error; - } - if (_Unpickler_MemoPut(self, idx, value) < 0) - goto error; - } + if (!PyMemoryView_GET_BUFFER(view)->readonly) { + /* Original object is writable */ + PyMemoryView_GET_BUFFER(view)->readonly = 1; + self->stack->data[len - 1] = view; + Py_DECREF(obj); } else { - PyErr_Format(PyExc_TypeError, - "'memo' attribute must be an UnpicklerMemoProxy object " - "or dict, not %.200s", Py_TYPE(obj)->tp_name); - return -1; + /* Original object is read-only, no need to replace it */ + Py_DECREF(view); } - - _Unpickler_MemoCleanup(self); - self->memo_size = new_memo_size; - self->memo = new_memo; - return 0; +} - error: - if (new_memo_size) { - for (size_t i = new_memo_size - 1; i != SIZE_MAX; i--) { - Py_XDECREF(new_memo[i]); - } - PyMem_FREE(new_memo); +static int +load_unicode(UnpicklerObject *self) +{ + PyObject *str; + Py_ssize_t len; + char *s = NULL; + + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 1) + return bad_readline(); + + str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL); + if (str == NULL) + return -1; + + PDATA_PUSH(self->stack, str, -1); + return 0; +} + +static int +load_counted_binunicode(UnpicklerObject *self, int nbytes) +{ + PyObject *str; + Py_ssize_t size; + char *s; + + if (_Unpickler_Read(self, &s, nbytes) < 0) + return -1; + + size = calc_binsize(s, nbytes); + if (size < 0) { + PyErr_Format(PyExc_OverflowError, + "BINUNICODE exceeds system's maximum size of %zd bytes", + PY_SSIZE_T_MAX); + return -1; + } + + if (_Unpickler_Read(self, &s, size) < 0) + return -1; + + str = PyUnicode_DecodeUTF8(s, size, "surrogatepass"); + if (str == NULL) + return -1; + + PDATA_PUSH(self->stack, str, -1); + return 0; +} + +static int +load_counted_tuple(UnpicklerObject *self, Py_ssize_t len) +{ + PyObject *tuple; + + if (Py_SIZE(self->stack) < len) + return Pdata_stack_underflow(self->stack); + + tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len); + if (tuple == NULL) + return -1; + PDATA_PUSH(self->stack, tuple, -1); + return 0; +} + +static int +load_tuple(UnpicklerObject *self) +{ + Py_ssize_t i; + + if ((i = marker(self)) < 0) + return -1; + + return load_counted_tuple(self, Py_SIZE(self->stack) - i); +} + +static int +load_empty_list(UnpicklerObject *self) +{ + PyObject *list; + + if ((list = PyList_New(0)) == NULL) + return -1; + PDATA_PUSH(self->stack, list, -1); + return 0; +} + +static int +load_empty_dict(UnpicklerObject *self) +{ + PyObject *dict; + + if ((dict = PyDict_New()) == NULL) + return -1; + PDATA_PUSH(self->stack, dict, -1); + return 0; +} + +static int +load_empty_set(UnpicklerObject *self) +{ + PyObject *set; + + if ((set = PySet_New(NULL)) == NULL) + return -1; + PDATA_PUSH(self->stack, set, -1); + return 0; +} + +static int +load_list(UnpicklerObject *self) +{ + PyObject *list; + Py_ssize_t i; + + if ((i = marker(self)) < 0) + return -1; + + list = Pdata_poplist(self->stack, i); + if (list == NULL) + return -1; + PDATA_PUSH(self->stack, list, -1); + return 0; +} + +static int +load_dict(UnpicklerObject *self) +{ + PyObject *dict, *key, *value; + Py_ssize_t i, j, k; + + if ((i = marker(self)) < 0) + return -1; + j = Py_SIZE(self->stack); + + if ((dict = PyDict_New()) == NULL) + return -1; + + if ((j - i) % 2 != 0) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, "odd number of items for DICT"); + Py_DECREF(dict); + return -1; + } + + for (k = i + 1; k < j; k += 2) { + key = self->stack->data[k - 1]; + value = self->stack->data[k]; + if (PyDict_SetItem(dict, key, value) < 0) { + Py_DECREF(dict); + return -1; + } + } + Pdata_clear(self->stack, i); + PDATA_PUSH(self->stack, dict, -1); + return 0; +} + +static int +load_frozenset(UnpicklerObject *self) +{ + PyObject *items; + PyObject *frozenset; + Py_ssize_t i; + + if ((i = marker(self)) < 0) + return -1; + + items = Pdata_poptuple(self->stack, i); + if (items == NULL) + return -1; + + frozenset = PyFrozenSet_New(items); + Py_DECREF(items); + if (frozenset == NULL) + return -1; + + PDATA_PUSH(self->stack, frozenset, -1); + return 0; +} + +static PyObject * +instantiate(PyObject *cls, PyObject *args) +{ + /* Caller must assure args are a tuple. Normally, args come from + Pdata_poptuple which packs objects from the top of the stack + into a newly created tuple. */ + assert(PyTuple_Check(args)); + if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) { + _Py_IDENTIFIER(__getinitargs__); + _Py_IDENTIFIER(__new__); + PyObject *func; + if (_PyObject_LookupAttrId(cls, &PyId___getinitargs__, &func) < 0) { + return NULL; + } + if (func == NULL) { + return _PyObject_CallMethodIdOneArg(cls, &PyId___new__, cls); + } + Py_DECREF(func); + } + return PyObject_CallObject(cls, args); +} + +static int +load_obj(UnpicklerObject *self) +{ + PyObject *cls, *args, *obj = NULL; + Py_ssize_t i; + + if ((i = marker(self)) < 0) + return -1; + + if (Py_SIZE(self->stack) - i < 1) + return Pdata_stack_underflow(self->stack); + + args = Pdata_poptuple(self->stack, i + 1); + if (args == NULL) + return -1; + + PDATA_POP(self->stack, cls); + if (cls) { + obj = instantiate(cls, args); + Py_DECREF(cls); + } + Py_DECREF(args); + if (obj == NULL) + return -1; + + PDATA_PUSH(self->stack, obj, -1); + return 0; +} + +static int +load_inst(UnpicklerObject *self) +{ + PyObject *cls = NULL; + PyObject *args = NULL; + PyObject *obj = NULL; + PyObject *module_name; + PyObject *class_name; + Py_ssize_t len; + Py_ssize_t i; + char *s; + + if ((i = marker(self)) < 0) + return -1; + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 2) + return bad_readline(); + + /* Here it is safe to use PyUnicode_DecodeASCII(), even though non-ASCII + identifiers are permitted in Python 3.0, since the INST opcode is only + supported by older protocols on Python 2.x. */ + module_name = PyUnicode_DecodeASCII(s, len - 1, "strict"); + if (module_name == NULL) + return -1; + + if ((len = _Unpickler_Readline(self, &s)) >= 0) { + if (len < 2) { + Py_DECREF(module_name); + return bad_readline(); + } + class_name = PyUnicode_DecodeASCII(s, len - 1, "strict"); + if (class_name != NULL) { + cls = find_class(self, module_name, class_name); + Py_DECREF(class_name); + } + } + Py_DECREF(module_name); + + if (cls == NULL) + return -1; + + if ((args = Pdata_poptuple(self->stack, i)) != NULL) { + obj = instantiate(cls, args); + Py_DECREF(args); + } + Py_DECREF(cls); + + if (obj == NULL) + return -1; + + PDATA_PUSH(self->stack, obj, -1); + return 0; +} + +static int +load_newobj(UnpicklerObject *self) +{ + PyObject *args = NULL; + PyObject *clsraw = NULL; + PyTypeObject *cls; /* clsraw cast to its true type */ + PyObject *obj; + PickleState *st = _Pickle_GetGlobalState(); + + /* Stack is ... cls argtuple, and we want to call + * cls.__new__(cls, *argtuple). + */ + PDATA_POP(self->stack, args); + if (args == NULL) + goto error; + if (!PyTuple_Check(args)) { + PyErr_SetString(st->UnpicklingError, + "NEWOBJ expected an arg " "tuple."); + goto error; + } + + PDATA_POP(self->stack, clsraw); + cls = (PyTypeObject *)clsraw; + if (cls == NULL) + goto error; + if (!PyType_Check(cls)) { + PyErr_SetString(st->UnpicklingError, "NEWOBJ class argument " + "isn't a type object"); + goto error; + } + if (cls->tp_new == NULL) { + PyErr_SetString(st->UnpicklingError, "NEWOBJ class argument " + "has NULL tp_new"); + goto error; + } + + /* Call __new__. */ + obj = cls->tp_new(cls, args, NULL); + if (obj == NULL) + goto error; + + Py_DECREF(args); + Py_DECREF(clsraw); + PDATA_PUSH(self->stack, obj, -1); + return 0; + + error: + Py_XDECREF(args); + Py_XDECREF(clsraw); + return -1; +} + +static int +load_newobj_ex(UnpicklerObject *self) +{ + PyObject *cls, *args, *kwargs; + PyObject *obj; + PickleState *st = _Pickle_GetGlobalState(); + + PDATA_POP(self->stack, kwargs); + if (kwargs == NULL) { + return -1; + } + PDATA_POP(self->stack, args); + if (args == NULL) { + Py_DECREF(kwargs); + return -1; + } + PDATA_POP(self->stack, cls); + if (cls == NULL) { + Py_DECREF(kwargs); + Py_DECREF(args); + return -1; + } + + if (!PyType_Check(cls)) { + PyErr_Format(st->UnpicklingError, + "NEWOBJ_EX class argument must be a type, not %.200s", + Py_TYPE(cls)->tp_name); + goto error; + } + + if (((PyTypeObject *)cls)->tp_new == NULL) { + PyErr_SetString(st->UnpicklingError, + "NEWOBJ_EX class argument doesn't have __new__"); + goto error; + } + if (!PyTuple_Check(args)) { + PyErr_Format(st->UnpicklingError, + "NEWOBJ_EX args argument must be a tuple, not %.200s", + Py_TYPE(args)->tp_name); + goto error; } + if (!PyDict_Check(kwargs)) { + PyErr_Format(st->UnpicklingError, + "NEWOBJ_EX kwargs argument must be a dict, not %.200s", + Py_TYPE(kwargs)->tp_name); + goto error; + } + + obj = ((PyTypeObject *)cls)->tp_new((PyTypeObject *)cls, args, kwargs); + Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(cls); + if (obj == NULL) { + return -1; + } + PDATA_PUSH(self->stack, obj, -1); + return 0; + +error: + Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(cls); return -1; -} +} + +static int +load_global(UnpicklerObject *self) +{ + PyObject *global = NULL; + PyObject *module_name; + PyObject *global_name; + Py_ssize_t len; + char *s; + + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 2) + return bad_readline(); + module_name = PyUnicode_DecodeUTF8(s, len - 1, "strict"); + if (!module_name) + return -1; + + if ((len = _Unpickler_Readline(self, &s)) >= 0) { + if (len < 2) { + Py_DECREF(module_name); + return bad_readline(); + } + global_name = PyUnicode_DecodeUTF8(s, len - 1, "strict"); + if (global_name) { + global = find_class(self, module_name, global_name); + Py_DECREF(global_name); + } + } + Py_DECREF(module_name); + + if (global == NULL) + return -1; + PDATA_PUSH(self->stack, global, -1); + return 0; +} + +static int +load_stack_global(UnpicklerObject *self) +{ + PyObject *global; + PyObject *module_name; + PyObject *global_name; + + PDATA_POP(self->stack, global_name); + PDATA_POP(self->stack, module_name); + if (module_name == NULL || !PyUnicode_CheckExact(module_name) || + global_name == NULL || !PyUnicode_CheckExact(global_name)) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, "STACK_GLOBAL requires str"); + Py_XDECREF(global_name); + Py_XDECREF(module_name); + return -1; + } + global = find_class(self, module_name, global_name); + Py_DECREF(global_name); + Py_DECREF(module_name); + if (global == NULL) + return -1; + PDATA_PUSH(self->stack, global, -1); + return 0; +} + +static int +load_persid(UnpicklerObject *self) +{ + PyObject *pid, *obj; + Py_ssize_t len; + char *s; + + if (self->pers_func) { + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 1) + return bad_readline(); + + pid = PyUnicode_DecodeASCII(s, len - 1, "strict"); + if (pid == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + PyErr_SetString(_Pickle_GetGlobalState()->UnpicklingError, + "persistent IDs in protocol 0 must be " + "ASCII strings"); + } + return -1; + } + + obj = call_method(self->pers_func, self->pers_func_self, pid); + Py_DECREF(pid); + if (obj == NULL) + return -1; + + PDATA_PUSH(self->stack, obj, -1); + return 0; + } + else { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "A load persistent id instruction was encountered,\n" + "but no persistent_load function was specified."); + return -1; + } +} + +static int +load_binpersid(UnpicklerObject *self) +{ + PyObject *pid, *obj; + + if (self->pers_func) { + PDATA_POP(self->stack, pid); + if (pid == NULL) + return -1; + + obj = call_method(self->pers_func, self->pers_func_self, pid); + Py_DECREF(pid); + if (obj == NULL) + return -1; + + PDATA_PUSH(self->stack, obj, -1); + return 0; + } + else { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "A load persistent id instruction was encountered,\n" + "but no persistent_load function was specified."); + return -1; + } +} + +static int +load_pop(UnpicklerObject *self) +{ + Py_ssize_t len = Py_SIZE(self->stack); + + /* Note that we split the (pickle.py) stack into two stacks, + * an object stack and a mark stack. We have to be clever and + * pop the right one. We do this by looking at the top of the + * mark stack first, and only signalling a stack underflow if + * the object stack is empty and the mark stack doesn't match + * our expectations. + */ + if (self->num_marks > 0 && self->marks[self->num_marks - 1] == len) { + self->num_marks--; + self->stack->mark_set = self->num_marks != 0; + self->stack->fence = self->num_marks ? + self->marks[self->num_marks - 1] : 0; + } else if (len <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + else { + len--; + Py_DECREF(self->stack->data[len]); + Py_SET_SIZE(self->stack, len); + } + return 0; +} + +static int +load_pop_mark(UnpicklerObject *self) +{ + Py_ssize_t i; + + if ((i = marker(self)) < 0) + return -1; + + Pdata_clear(self->stack, i); + + return 0; +} + +static int +load_dup(UnpicklerObject *self) +{ + PyObject *last; + Py_ssize_t len = Py_SIZE(self->stack); + + if (len <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + last = self->stack->data[len - 1]; + PDATA_APPEND(self->stack, last, -1); + return 0; +} + +static int +load_get(UnpicklerObject *self) +{ + PyObject *key, *value; + Py_ssize_t idx; + Py_ssize_t len; + char *s; + + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 2) + return bad_readline(); + + key = PyLong_FromString(s, NULL, 10); + if (key == NULL) + return -1; + idx = PyLong_AsSsize_t(key); + if (idx == -1 && PyErr_Occurred()) { + Py_DECREF(key); + return -1; + } + + value = _Unpickler_MemoGet(self, idx); + if (value == NULL) { + if (!PyErr_Occurred()) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); + } + Py_DECREF(key); + return -1; + } + Py_DECREF(key); + + PDATA_APPEND(self->stack, value, -1); + return 0; +} + +static int +load_binget(UnpicklerObject *self) +{ + PyObject *value; + Py_ssize_t idx; + char *s; + + if (_Unpickler_Read(self, &s, 1) < 0) + return -1; + + idx = Py_CHARMASK(s[0]); + + value = _Unpickler_MemoGet(self, idx); + if (value == NULL) { + PyObject *key = PyLong_FromSsize_t(idx); + if (key != NULL) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); + Py_DECREF(key); + } + return -1; + } + + PDATA_APPEND(self->stack, value, -1); + return 0; +} + +static int +load_long_binget(UnpicklerObject *self) +{ + PyObject *value; + Py_ssize_t idx; + char *s; + + if (_Unpickler_Read(self, &s, 4) < 0) + return -1; + + idx = calc_binsize(s, 4); + + value = _Unpickler_MemoGet(self, idx); + if (value == NULL) { + PyObject *key = PyLong_FromSsize_t(idx); + if (key != NULL) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); + Py_DECREF(key); + } + return -1; + } + + PDATA_APPEND(self->stack, value, -1); + return 0; +} + +/* Push an object from the extension registry (EXT[124]). nbytes is + * the number of bytes following the opcode, holding the index (code) value. + */ +static int +load_extension(UnpicklerObject *self, int nbytes) +{ + char *codebytes; /* the nbytes bytes after the opcode */ + long code; /* calc_binint returns long */ + PyObject *py_code; /* code as a Python int */ + PyObject *obj; /* the object to push */ + PyObject *pair; /* (module_name, class_name) */ + PyObject *module_name, *class_name; + PickleState *st = _Pickle_GetGlobalState(); + + assert(nbytes == 1 || nbytes == 2 || nbytes == 4); + if (_Unpickler_Read(self, &codebytes, nbytes) < 0) + return -1; + code = calc_binint(codebytes, nbytes); + if (code <= 0) { /* note that 0 is forbidden */ + /* Corrupt or hostile pickle. */ + PyErr_SetString(st->UnpicklingError, "EXT specifies code <= 0"); + return -1; + } + + /* Look for the code in the cache. */ + py_code = PyLong_FromLong(code); + if (py_code == NULL) + return -1; + obj = PyDict_GetItemWithError(st->extension_cache, py_code); + if (obj != NULL) { + /* Bingo. */ + Py_DECREF(py_code); + PDATA_APPEND(self->stack, obj, -1); + return 0; + } + if (PyErr_Occurred()) { + Py_DECREF(py_code); + return -1; + } + + /* Look up the (module_name, class_name) pair. */ + pair = PyDict_GetItemWithError(st->inverted_registry, py_code); + if (pair == NULL) { + Py_DECREF(py_code); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, "unregistered extension " + "code %ld", code); + } + return -1; + } + /* Since the extension registry is manipulable via Python code, + * confirm that pair is really a 2-tuple of strings. + */ + if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2) { + goto error; + } -static PyObject * -Unpickler_get_persload(UnpicklerObject *self, void *Py_UNUSED(ignored)) -{ - if (self->pers_func == NULL) { - PyErr_SetString(PyExc_AttributeError, "persistent_load"); - return NULL; + module_name = PyTuple_GET_ITEM(pair, 0); + if (!PyUnicode_Check(module_name)) { + goto error; } - return reconstruct_method(self->pers_func, self->pers_func_self); -} -static int -Unpickler_set_persload(UnpicklerObject *self, PyObject *value, void *Py_UNUSED(ignored)) -{ - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "attribute deletion is not supported"); - return -1; - } - if (!PyCallable_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "persistent_load must be a callable taking " - "one argument"); - return -1; + class_name = PyTuple_GET_ITEM(pair, 1); + if (!PyUnicode_Check(class_name)) { + goto error; } - self->pers_func_self = NULL; - Py_INCREF(value); - Py_XSETREF(self->pers_func, value); + /* Load the object. */ + obj = find_class(self, module_name, class_name); + if (obj == NULL) { + Py_DECREF(py_code); + return -1; + } + /* Cache code -> obj. */ + code = PyDict_SetItem(st->extension_cache, py_code, obj); + Py_DECREF(py_code); + if (code < 0) { + Py_DECREF(obj); + return -1; + } + PDATA_PUSH(self->stack, obj, -1); + return 0; - return 0; -} +error: + Py_DECREF(py_code); + PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] " + "isn't a 2-tuple of strings", code); + return -1; +} + +static int +load_put(UnpicklerObject *self) +{ + PyObject *key, *value; + Py_ssize_t idx; + Py_ssize_t len; + char *s = NULL; + + if ((len = _Unpickler_Readline(self, &s)) < 0) + return -1; + if (len < 2) + return bad_readline(); + if (Py_SIZE(self->stack) <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + value = self->stack->data[Py_SIZE(self->stack) - 1]; + + key = PyLong_FromString(s, NULL, 10); + if (key == NULL) + return -1; + idx = PyLong_AsSsize_t(key); + Py_DECREF(key); + if (idx < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_ValueError, + "negative PUT argument"); + return -1; + } + + return _Unpickler_MemoPut(self, idx, value); +} + +static int +load_binput(UnpicklerObject *self) +{ + PyObject *value; + Py_ssize_t idx; + char *s; + + if (_Unpickler_Read(self, &s, 1) < 0) + return -1; + + if (Py_SIZE(self->stack) <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + value = self->stack->data[Py_SIZE(self->stack) - 1]; + + idx = Py_CHARMASK(s[0]); + + return _Unpickler_MemoPut(self, idx, value); +} + +static int +load_long_binput(UnpicklerObject *self) +{ + PyObject *value; + Py_ssize_t idx; + char *s; + + if (_Unpickler_Read(self, &s, 4) < 0) + return -1; + + if (Py_SIZE(self->stack) <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + value = self->stack->data[Py_SIZE(self->stack) - 1]; + + idx = calc_binsize(s, 4); + if (idx < 0) { + PyErr_SetString(PyExc_ValueError, + "negative LONG_BINPUT argument"); + return -1; + } + + return _Unpickler_MemoPut(self, idx, value); +} + +static int +load_memoize(UnpicklerObject *self) +{ + PyObject *value; + + if (Py_SIZE(self->stack) <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + value = self->stack->data[Py_SIZE(self->stack) - 1]; + + return _Unpickler_MemoPut(self, self->memo_len, value); +} + +static int +do_append(UnpicklerObject *self, Py_ssize_t x) +{ + PyObject *value; + PyObject *slice; + PyObject *list; + PyObject *result; + Py_ssize_t len, i; + + len = Py_SIZE(self->stack); + if (x > len || x <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + if (len == x) /* nothing to do */ + return 0; + + list = self->stack->data[x - 1]; + + if (PyList_CheckExact(list)) { + Py_ssize_t list_len; + int ret; + + slice = Pdata_poplist(self->stack, x); + if (!slice) + return -1; + list_len = PyList_GET_SIZE(list); + ret = PyList_SetSlice(list, list_len, list_len, slice); + Py_DECREF(slice); + return ret; + } + else { + PyObject *extend_func; + _Py_IDENTIFIER(extend); + + if (_PyObject_LookupAttrId(list, &PyId_extend, &extend_func) < 0) { + return -1; + } + if (extend_func != NULL) { + slice = Pdata_poplist(self->stack, x); + if (!slice) { + Py_DECREF(extend_func); + return -1; + } + result = _Pickle_FastCall(extend_func, slice); + Py_DECREF(extend_func); + if (result == NULL) + return -1; + Py_DECREF(result); + } + else { + PyObject *append_func; + _Py_IDENTIFIER(append); + + /* Even if the PEP 307 requires extend() and append() methods, + fall back on append() if the object has no extend() method + for backward compatibility. */ + append_func = _PyObject_GetAttrId(list, &PyId_append); + if (append_func == NULL) + return -1; + for (i = x; i < len; i++) { + value = self->stack->data[i]; + result = _Pickle_FastCall(append_func, value); + if (result == NULL) { + Pdata_clear(self->stack, i + 1); + Py_SET_SIZE(self->stack, x); + Py_DECREF(append_func); + return -1; + } + Py_DECREF(result); + } + Py_SET_SIZE(self->stack, x); + Py_DECREF(append_func); + } + } + + return 0; +} + +static int +load_append(UnpicklerObject *self) +{ + if (Py_SIZE(self->stack) - 1 <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + return do_append(self, Py_SIZE(self->stack) - 1); +} + +static int +load_appends(UnpicklerObject *self) +{ + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_append(self, i); +} + +static int +do_setitems(UnpicklerObject *self, Py_ssize_t x) +{ + PyObject *value, *key; + PyObject *dict; + Py_ssize_t len, i; + int status = 0; + + len = Py_SIZE(self->stack); + if (x > len || x <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + if (len == x) /* nothing to do */ + return 0; + if ((len - x) % 2 != 0) { + PickleState *st = _Pickle_GetGlobalState(); + /* Corrupt or hostile pickle -- we never write one like this. */ + PyErr_SetString(st->UnpicklingError, + "odd number of items for SETITEMS"); + return -1; + } + + /* Here, dict does not actually need to be a PyDict; it could be anything + that supports the __setitem__ attribute. */ + dict = self->stack->data[x - 1]; + + for (i = x + 1; i < len; i += 2) { + key = self->stack->data[i - 1]; + value = self->stack->data[i]; + if (PyObject_SetItem(dict, key, value) < 0) { + status = -1; + break; + } + } + + Pdata_clear(self->stack, x); + return status; +} + +static int +load_setitem(UnpicklerObject *self) +{ + return do_setitems(self, Py_SIZE(self->stack) - 2); +} + +static int +load_setitems(UnpicklerObject *self) +{ + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_setitems(self, i); +} + +static int +load_additems(UnpicklerObject *self) +{ + PyObject *set; + Py_ssize_t mark, len, i; + + mark = marker(self); + if (mark < 0) + return -1; + len = Py_SIZE(self->stack); + if (mark > len || mark <= self->stack->fence) + return Pdata_stack_underflow(self->stack); + if (len == mark) /* nothing to do */ + return 0; + + set = self->stack->data[mark - 1]; + + if (PySet_Check(set)) { + PyObject *items; + int status; + + items = Pdata_poptuple(self->stack, mark); + if (items == NULL) + return -1; + + status = _PySet_Update(set, items); + Py_DECREF(items); + return status; + } + else { + PyObject *add_func; + _Py_IDENTIFIER(add); + + add_func = _PyObject_GetAttrId(set, &PyId_add); + if (add_func == NULL) + return -1; + for (i = mark; i < len; i++) { + PyObject *result; + PyObject *item; + + item = self->stack->data[i]; + result = _Pickle_FastCall(add_func, item); + if (result == NULL) { + Pdata_clear(self->stack, i + 1); + Py_SET_SIZE(self->stack, mark); + return -1; + } + Py_DECREF(result); + } + Py_SET_SIZE(self->stack, mark); + } + + return 0; +} + +static int +load_build(UnpicklerObject *self) +{ + PyObject *state, *inst, *slotstate; + PyObject *setstate; + int status = 0; + _Py_IDENTIFIER(__setstate__); + + /* Stack is ... instance, state. We want to leave instance at + * the stack top, possibly mutated via instance.__setstate__(state). + */ + if (Py_SIZE(self->stack) - 2 < self->stack->fence) + return Pdata_stack_underflow(self->stack); + + PDATA_POP(self->stack, state); + if (state == NULL) + return -1; + + inst = self->stack->data[Py_SIZE(self->stack) - 1]; + + if (_PyObject_LookupAttrId(inst, &PyId___setstate__, &setstate) < 0) { + Py_DECREF(state); + return -1; + } + if (setstate != NULL) { + PyObject *result; + + /* The explicit __setstate__ is responsible for everything. */ + result = _Pickle_FastCall(setstate, state); + Py_DECREF(setstate); + if (result == NULL) + return -1; + Py_DECREF(result); + return 0; + } + + /* A default __setstate__. First see whether state embeds a + * slot state dict too (a proto 2 addition). + */ + if (PyTuple_Check(state) && PyTuple_GET_SIZE(state) == 2) { + PyObject *tmp = state; + + state = PyTuple_GET_ITEM(tmp, 0); + slotstate = PyTuple_GET_ITEM(tmp, 1); + Py_INCREF(state); + Py_INCREF(slotstate); + Py_DECREF(tmp); + } + else + slotstate = NULL; + + /* Set inst.__dict__ from the state dict (if any). */ + if (state != Py_None) { + PyObject *dict; + PyObject *d_key, *d_value; + Py_ssize_t i; + _Py_IDENTIFIER(__dict__); + + if (!PyDict_Check(state)) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, "state is not a dictionary"); + goto error; + } + dict = _PyObject_GetAttrId(inst, &PyId___dict__); + if (dict == NULL) + goto error; + + i = 0; + while (PyDict_Next(state, &i, &d_key, &d_value)) { + /* normally the keys for instance attributes are + interned. we should try to do that here. */ + Py_INCREF(d_key); + if (PyUnicode_CheckExact(d_key)) + PyUnicode_InternInPlace(&d_key); + if (PyObject_SetItem(dict, d_key, d_value) < 0) { + Py_DECREF(d_key); + goto error; + } + Py_DECREF(d_key); + } + Py_DECREF(dict); + } + + /* Also set instance attributes from the slotstate dict (if any). */ + if (slotstate != NULL) { + PyObject *d_key, *d_value; + Py_ssize_t i; + + if (!PyDict_Check(slotstate)) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "slot state is not a dictionary"); + goto error; + } + i = 0; + while (PyDict_Next(slotstate, &i, &d_key, &d_value)) { + if (PyObject_SetAttr(inst, d_key, d_value) < 0) + goto error; + } + } + + if (0) { + error: + status = -1; + } + + Py_DECREF(state); + Py_XDECREF(slotstate); + return status; +} + +static int +load_mark(UnpicklerObject *self) +{ + + /* Note that we split the (pickle.py) stack into two stacks, an + * object stack and a mark stack. Here we push a mark onto the + * mark stack. + */ + + if (self->num_marks >= self->marks_size) { + size_t alloc = ((size_t)self->num_marks << 1) + 20; + Py_ssize_t *marks_new = self->marks; + PyMem_RESIZE(marks_new, Py_ssize_t, alloc); + if (marks_new == NULL) { + PyErr_NoMemory(); + return -1; + } + self->marks = marks_new; + self->marks_size = (Py_ssize_t)alloc; + } + + self->stack->mark_set = 1; + self->marks[self->num_marks++] = self->stack->fence = Py_SIZE(self->stack); + + return 0; +} + +static int +load_reduce(UnpicklerObject *self) +{ + PyObject *callable = NULL; + PyObject *argtup = NULL; + PyObject *obj = NULL; + + PDATA_POP(self->stack, argtup); + if (argtup == NULL) + return -1; + PDATA_POP(self->stack, callable); + if (callable) { + obj = PyObject_CallObject(callable, argtup); + Py_DECREF(callable); + } + Py_DECREF(argtup); + + if (obj == NULL) + return -1; + + PDATA_PUSH(self->stack, obj, -1); + return 0; +} + +/* Just raises an error if we don't know the protocol specified. PROTO + * is the first opcode for protocols >= 2. + */ +static int +load_proto(UnpicklerObject *self) +{ + char *s; + int i; + + if (_Unpickler_Read(self, &s, 1) < 0) + return -1; + + i = (unsigned char)s[0]; + if (i <= HIGHEST_PROTOCOL) { + self->proto = i; + return 0; + } + + PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i); + return -1; +} + +static int +load_frame(UnpicklerObject *self) +{ + char *s; + Py_ssize_t frame_len; + + if (_Unpickler_Read(self, &s, 8) < 0) + return -1; + + frame_len = calc_binsize(s, 8); + if (frame_len < 0) { + PyErr_Format(PyExc_OverflowError, + "FRAME length exceeds system's maximum of %zd bytes", + PY_SSIZE_T_MAX); + return -1; + } + + if (_Unpickler_Read(self, &s, frame_len) < 0) + return -1; + + /* Rewind to start of frame */ + self->next_read_idx -= frame_len; + return 0; +} + +static PyObject * +load(UnpicklerObject *self) +{ + PyObject *value = NULL; + char *s = NULL; + + self->num_marks = 0; + self->stack->mark_set = 0; + self->stack->fence = 0; + self->proto = 0; + if (Py_SIZE(self->stack)) + Pdata_clear(self->stack, 0); + + /* Convenient macros for the dispatch while-switch loop just below. */ +#define OP(opcode, load_func) \ + case opcode: if (load_func(self) < 0) break; continue; + +#define OP_ARG(opcode, load_func, arg) \ + case opcode: if (load_func(self, (arg)) < 0) break; continue; + + while (1) { + if (_Unpickler_Read(self, &s, 1) < 0) { + PickleState *st = _Pickle_GetGlobalState(); + if (PyErr_ExceptionMatches(st->UnpicklingError)) { + PyErr_Format(PyExc_EOFError, "Ran out of input"); + } + return NULL; + } + + switch ((enum opcode)s[0]) { + OP(NONE, load_none) + OP(BININT, load_binint) + OP(BININT1, load_binint1) + OP(BININT2, load_binint2) + OP(INT_, load_int) + OP(LONG_, load_long) + OP_ARG(LONG1, load_counted_long, 1) + OP_ARG(LONG4, load_counted_long, 4) + OP(FLOAT_, load_float) + OP(BINFLOAT, load_binfloat) + OP_ARG(SHORT_BINBYTES, load_counted_binbytes, 1) + OP_ARG(BINBYTES, load_counted_binbytes, 4) + OP_ARG(BINBYTES8, load_counted_binbytes, 8) + OP(BYTEARRAY8, load_counted_bytearray) + OP(NEXT_BUFFER, load_next_buffer) + OP(READONLY_BUFFER, load_readonly_buffer) + OP_ARG(SHORT_BINSTRING, load_counted_binstring, 1) + OP_ARG(BINSTRING, load_counted_binstring, 4) + OP(STRING, load_string) + OP(UNICODE, load_unicode) + OP_ARG(SHORT_BINUNICODE, load_counted_binunicode, 1) + OP_ARG(BINUNICODE, load_counted_binunicode, 4) + OP_ARG(BINUNICODE8, load_counted_binunicode, 8) + OP_ARG(EMPTY_TUPLE, load_counted_tuple, 0) + OP_ARG(TUPLE1, load_counted_tuple, 1) + OP_ARG(TUPLE2, load_counted_tuple, 2) + OP_ARG(TUPLE3, load_counted_tuple, 3) + OP(TUPLE, load_tuple) + OP(EMPTY_LIST, load_empty_list) + OP(LIST, load_list) + OP(EMPTY_DICT, load_empty_dict) + OP(DICT, load_dict) + OP(EMPTY_SET, load_empty_set) + OP(ADDITEMS, load_additems) + OP(FROZENSET, load_frozenset) + OP(OBJ, load_obj) + OP(INST, load_inst) + OP(NEWOBJ, load_newobj) + OP(NEWOBJ_EX, load_newobj_ex) + OP(GLOBAL, load_global) + OP(STACK_GLOBAL, load_stack_global) + OP(APPEND, load_append) + OP(APPENDS, load_appends) + OP(BUILD, load_build) + OP(DUP, load_dup) + OP(BINGET, load_binget) + OP(LONG_BINGET, load_long_binget) + OP(GET, load_get) + OP(MARK, load_mark) + OP(BINPUT, load_binput) + OP(LONG_BINPUT, load_long_binput) + OP(PUT, load_put) + OP(MEMOIZE, load_memoize) + OP(POP, load_pop) + OP(POP_MARK, load_pop_mark) + OP(SETITEM, load_setitem) + OP(SETITEMS, load_setitems) + OP(PERSID, load_persid) + OP(BINPERSID, load_binpersid) + OP(REDUCE, load_reduce) + OP(PROTO, load_proto) + OP(FRAME, load_frame) + OP_ARG(EXT1, load_extension, 1) + OP_ARG(EXT2, load_extension, 2) + OP_ARG(EXT4, load_extension, 4) + OP_ARG(NEWTRUE, load_bool, Py_True) + OP_ARG(NEWFALSE, load_bool, Py_False) + + case STOP: + break; + + default: + { + PickleState *st = _Pickle_GetGlobalState(); + unsigned char c = (unsigned char) *s; + if (0x20 <= c && c <= 0x7e && c != '\'' && c != '\\') { + PyErr_Format(st->UnpicklingError, + "invalid load key, '%c'.", c); + } + else { + PyErr_Format(st->UnpicklingError, + "invalid load key, '\\x%02x'.", c); + } + return NULL; + } + } + + break; /* and we are done! */ + } + + if (PyErr_Occurred()) { + return NULL; + } + + if (_Unpickler_SkipConsumed(self) < 0) + return NULL; + + PDATA_POP(self->stack, value); + return value; +} + +/*[clinic input] + +_pickle.Unpickler.load + +Load a pickle. + +Read a pickled object representation from the open file object given +in the constructor, and return the reconstituted object hierarchy +specified therein. +[clinic start generated code]*/ + +static PyObject * +_pickle_Unpickler_load_impl(UnpicklerObject *self) +/*[clinic end generated code: output=fdcc488aad675b14 input=acbb91a42fa9b7b9]*/ +{ + UnpicklerObject *unpickler = (UnpicklerObject*)self; + + /* Check whether the Unpickler was initialized correctly. This prevents + segfaulting if a subclass overridden __init__ with a function that does + not call Unpickler.__init__(). Here, we simply ensure that self->read + is not NULL. */ + if (unpickler->read == NULL) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, + "Unpickler.__init__() was not called by %s.__init__()", + Py_TYPE(unpickler)->tp_name); + return NULL; + } + + return load(unpickler); +} + +/* The name of find_class() is misleading. In newer pickle protocols, this + function is used for loading any global (i.e., functions), not just + classes. The name is kept only for backward compatibility. */ + +/*[clinic input] + +_pickle.Unpickler.find_class + + module_name: object + global_name: object + / + +Return an object from a specified module. + +If necessary, the module will be imported. Subclasses may override +this method (e.g. to restrict unpickling of arbitrary classes and +functions). + +This method is called whenever a class or a function object is +needed. Both arguments passed are str objects. +[clinic start generated code]*/ + +static PyObject * +_pickle_Unpickler_find_class_impl(UnpicklerObject *self, + PyObject *module_name, + PyObject *global_name) +/*[clinic end generated code: output=becc08d7f9ed41e3 input=e2e6a865de093ef4]*/ +{ + PyObject *global; + PyObject *module; + + if (PySys_Audit("pickle.find_class", "OO", + module_name, global_name) < 0) { + return NULL; + } -static PyGetSetDef Unpickler_getsets[] = { - {"memo", (getter)Unpickler_get_memo, (setter)Unpickler_set_memo}, - {"persistent_load", (getter)Unpickler_get_persload, - (setter)Unpickler_set_persload}, - {NULL} -}; + /* Try to map the old names used in Python 2.x to the new ones used in + Python 3.x. We do this only with old pickle protocols and when the + user has not disabled the feature. */ + if (self->proto < 3 && self->fix_imports) { + PyObject *key; + PyObject *item; + PickleState *st = _Pickle_GetGlobalState(); + + /* Check if the global (i.e., a function or a class) was renamed + or moved to another module. */ + key = PyTuple_Pack(2, module_name, global_name); + if (key == NULL) + return NULL; + item = PyDict_GetItemWithError(st->name_mapping_2to3, key); + Py_DECREF(key); + if (item) { + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.NAME_MAPPING values should be " + "2-tuples, not %.200s", Py_TYPE(item)->tp_name); + return NULL; + } + module_name = PyTuple_GET_ITEM(item, 0); + global_name = PyTuple_GET_ITEM(item, 1); + if (!PyUnicode_Check(module_name) || + !PyUnicode_Check(global_name)) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.NAME_MAPPING values should be " + "pairs of str, not (%.200s, %.200s)", + Py_TYPE(module_name)->tp_name, + Py_TYPE(global_name)->tp_name); + return NULL; + } + } + else if (PyErr_Occurred()) { + return NULL; + } + else { + /* Check if the module was renamed. */ + item = PyDict_GetItemWithError(st->import_mapping_2to3, module_name); + if (item) { + if (!PyUnicode_Check(item)) { + PyErr_Format(PyExc_RuntimeError, + "_compat_pickle.IMPORT_MAPPING values should be " + "strings, not %.200s", Py_TYPE(item)->tp_name); + return NULL; + } + module_name = item; + } + else if (PyErr_Occurred()) { + return NULL; + } + } + } + + /* + * we don't use PyImport_GetModule here, because it can return partially- + * initialised modules, which then cause the getattribute to fail. + */ + module = PyImport_Import(module_name); + if (module == NULL) { + return NULL; + } + global = getattribute(module, global_name, self->proto >= 4); + Py_DECREF(module); + return global; +} + +/*[clinic input] + +_pickle.Unpickler.__sizeof__ -> Py_ssize_t + +Returns size in memory, in bytes. +[clinic start generated code]*/ + +static Py_ssize_t +_pickle_Unpickler___sizeof___impl(UnpicklerObject *self) +/*[clinic end generated code: output=119d9d03ad4c7651 input=13333471fdeedf5e]*/ +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(self)); + if (self->memo != NULL) + res += self->memo_size * sizeof(PyObject *); + if (self->marks != NULL) + res += self->marks_size * sizeof(Py_ssize_t); + if (self->input_line != NULL) + res += strlen(self->input_line) + 1; + if (self->encoding != NULL) + res += strlen(self->encoding) + 1; + if (self->errors != NULL) + res += strlen(self->errors) + 1; + return res; +} + +static struct PyMethodDef Unpickler_methods[] = { + _PICKLE_UNPICKLER_LOAD_METHODDEF + _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF + _PICKLE_UNPICKLER___SIZEOF___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static void +Unpickler_dealloc(UnpicklerObject *self) +{ + PyObject_GC_UnTrack((PyObject *)self); + Py_XDECREF(self->readline); + Py_XDECREF(self->readinto); + Py_XDECREF(self->read); + Py_XDECREF(self->peek); + Py_XDECREF(self->stack); + Py_XDECREF(self->pers_func); + Py_XDECREF(self->buffers); + if (self->buffer.buf != NULL) { + PyBuffer_Release(&self->buffer); + self->buffer.buf = NULL; + } + + _Unpickler_MemoCleanup(self); + PyMem_Free(self->marks); + PyMem_Free(self->input_line); + PyMem_Free(self->encoding); + PyMem_Free(self->errors); + + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int +Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->readline); + Py_VISIT(self->readinto); + Py_VISIT(self->read); + Py_VISIT(self->peek); + Py_VISIT(self->stack); + Py_VISIT(self->pers_func); + Py_VISIT(self->buffers); + return 0; +} + +static int +Unpickler_clear(UnpicklerObject *self) +{ + Py_CLEAR(self->readline); + Py_CLEAR(self->readinto); + Py_CLEAR(self->read); + Py_CLEAR(self->peek); + Py_CLEAR(self->stack); + Py_CLEAR(self->pers_func); + Py_CLEAR(self->buffers); + if (self->buffer.buf != NULL) { + PyBuffer_Release(&self->buffer); + self->buffer.buf = NULL; + } + + _Unpickler_MemoCleanup(self); + PyMem_Free(self->marks); + self->marks = NULL; + PyMem_Free(self->input_line); + self->input_line = NULL; + PyMem_Free(self->encoding); + self->encoding = NULL; + PyMem_Free(self->errors); + self->errors = NULL; + + return 0; +} + +/*[clinic input] + +_pickle.Unpickler.__init__ + + file: object + * + fix_imports: bool = True + encoding: str = 'ASCII' + errors: str = 'strict' + buffers: object(c_default="NULL") = () + +This takes a binary file for reading a pickle data stream. + +The protocol version of the pickle is detected automatically, so no +protocol argument is needed. Bytes past the pickled object's +representation are ignored. + +The argument *file* must have two methods, a read() method that takes +an integer argument, and a readline() method that requires no +arguments. Both methods should return bytes. Thus *file* can be a +binary file object opened for reading, an io.BytesIO object, or any +other custom object that meets this interface. + +Optional keyword arguments are *fix_imports*, *encoding* and *errors*, +which are used to control compatibility support for pickle stream +generated by Python 2. If *fix_imports* is True, pickle will try to +map the old Python 2 names to the new names used in Python 3. The +*encoding* and *errors* tell pickle how to decode 8-bit string +instances pickled by Python 2; these default to 'ASCII' and 'strict', +respectively. The *encoding* can be 'bytes' to read these 8-bit +string instances as bytes objects. +[clinic start generated code]*/ + +static int +_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, + int fix_imports, const char *encoding, + const char *errors, PyObject *buffers) +/*[clinic end generated code: output=09f0192649ea3f85 input=ca4c1faea9553121]*/ +{ + _Py_IDENTIFIER(persistent_load); + + /* In case of multiple __init__() calls, clear previous content. */ + if (self->read != NULL) + (void)Unpickler_clear(self); + + if (_Unpickler_SetInputStream(self, file) < 0) + return -1; + + if (_Unpickler_SetInputEncoding(self, encoding, errors) < 0) + return -1; + + if (_Unpickler_SetBuffers(self, buffers) < 0) + return -1; -static PyTypeObject Unpickler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.Unpickler", /*tp_name*/ - sizeof(UnpicklerObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)Unpickler_dealloc, /*tp_dealloc*/ + self->fix_imports = fix_imports; + + if (init_method_ref((PyObject *)self, &PyId_persistent_load, + &self->pers_func, &self->pers_func_self) < 0) + { + return -1; + } + + self->stack = (Pdata *)Pdata_New(); + if (self->stack == NULL) + return -1; + + self->memo_size = 32; + self->memo = _Unpickler_NewMemo(self->memo_size); + if (self->memo == NULL) + return -1; + + self->proto = 0; + + return 0; +} + + +/* Define a proxy object for the Unpickler's internal memo object. This is to + * avoid breaking code like: + * unpickler.memo.clear() + * and + * unpickler.memo = saved_memo + * Is this a good idea? Not really, but we don't want to break code that uses + * it. Note that we don't implement the entire mapping API here. This is + * intentional, as these should be treated as black-box implementation details. + * + * We do, however, have to implement pickling/unpickling support because of + * real-world code like cvs2svn. + */ + +/*[clinic input] +_pickle.UnpicklerMemoProxy.clear + +Remove all items from memo. +[clinic start generated code]*/ + +static PyObject * +_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self) +/*[clinic end generated code: output=d20cd43f4ba1fb1f input=b1df7c52e7afd9bd]*/ +{ + _Unpickler_MemoCleanup(self->unpickler); + self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size); + if (self->unpickler->memo == NULL) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +_pickle.UnpicklerMemoProxy.copy + +Copy the memo to a new object. +[clinic start generated code]*/ + +static PyObject * +_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self) +/*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/ +{ + size_t i; + PyObject *new_memo = PyDict_New(); + if (new_memo == NULL) + return NULL; + + for (i = 0; i < self->unpickler->memo_size; i++) { + int status; + PyObject *key, *value; + + value = self->unpickler->memo[i]; + if (value == NULL) + continue; + + key = PyLong_FromSsize_t(i); + if (key == NULL) + goto error; + status = PyDict_SetItem(new_memo, key, value); + Py_DECREF(key); + if (status < 0) + goto error; + } + return new_memo; + +error: + Py_DECREF(new_memo); + return NULL; +} + +/*[clinic input] +_pickle.UnpicklerMemoProxy.__reduce__ + +Implement pickling support. +[clinic start generated code]*/ + +static PyObject * +_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self) +/*[clinic end generated code: output=6da34ac048d94cca input=6920862413407199]*/ +{ + PyObject *reduce_value; + PyObject *constructor_args; + PyObject *contents = _pickle_UnpicklerMemoProxy_copy_impl(self); + if (contents == NULL) + return NULL; + + reduce_value = PyTuple_New(2); + if (reduce_value == NULL) { + Py_DECREF(contents); + return NULL; + } + constructor_args = PyTuple_New(1); + if (constructor_args == NULL) { + Py_DECREF(contents); + Py_DECREF(reduce_value); + return NULL; + } + PyTuple_SET_ITEM(constructor_args, 0, contents); + Py_INCREF((PyObject *)&PyDict_Type); + PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); + PyTuple_SET_ITEM(reduce_value, 1, constructor_args); + return reduce_value; +} + +static PyMethodDef unpicklerproxy_methods[] = { + _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF + _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF + _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static void +UnpicklerMemoProxy_dealloc(UnpicklerMemoProxyObject *self) +{ + PyObject_GC_UnTrack(self); + Py_XDECREF(self->unpickler); + PyObject_GC_Del((PyObject *)self); +} + +static int +UnpicklerMemoProxy_traverse(UnpicklerMemoProxyObject *self, + visitproc visit, void *arg) +{ + Py_VISIT(self->unpickler); + return 0; +} + +static int +UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self) +{ + Py_CLEAR(self->unpickler); + return 0; +} + +static PyTypeObject UnpicklerMemoProxyType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_pickle.UnpicklerMemoProxy", /*tp_name*/ + sizeof(UnpicklerMemoProxyObject), /*tp_basicsize*/ + 0, + (destructor)UnpicklerMemoProxy_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + PyObject_HashNotImplemented, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + 0, /* tp_doc */ + (traverseproc)UnpicklerMemoProxy_traverse, /* tp_traverse */ + (inquiry)UnpicklerMemoProxy_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + unpicklerproxy_methods, /* tp_methods */ +}; + +static PyObject * +UnpicklerMemoProxy_New(UnpicklerObject *unpickler) +{ + UnpicklerMemoProxyObject *self; + + self = PyObject_GC_New(UnpicklerMemoProxyObject, + &UnpicklerMemoProxyType); + if (self == NULL) + return NULL; + Py_INCREF(unpickler); + self->unpickler = unpickler; + PyObject_GC_Track(self); + return (PyObject *)self; +} + +/*****************************************************************************/ + + +static PyObject * +Unpickler_get_memo(UnpicklerObject *self, void *Py_UNUSED(ignored)) +{ + return UnpicklerMemoProxy_New(self); +} + +static int +Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored)) +{ + PyObject **new_memo; + size_t new_memo_size = 0; + + if (obj == NULL) { + PyErr_SetString(PyExc_TypeError, + "attribute deletion is not supported"); + return -1; + } + + if (Py_IS_TYPE(obj, &UnpicklerMemoProxyType)) { + UnpicklerObject *unpickler = + ((UnpicklerMemoProxyObject *)obj)->unpickler; + + new_memo_size = unpickler->memo_size; + new_memo = _Unpickler_NewMemo(new_memo_size); + if (new_memo == NULL) + return -1; + + for (size_t i = 0; i < new_memo_size; i++) { + Py_XINCREF(unpickler->memo[i]); + new_memo[i] = unpickler->memo[i]; + } + } + else if (PyDict_Check(obj)) { + Py_ssize_t i = 0; + PyObject *key, *value; + + new_memo_size = PyDict_GET_SIZE(obj); + new_memo = _Unpickler_NewMemo(new_memo_size); + if (new_memo == NULL) + return -1; + + while (PyDict_Next(obj, &i, &key, &value)) { + Py_ssize_t idx; + if (!PyLong_Check(key)) { + PyErr_SetString(PyExc_TypeError, + "memo key must be integers"); + goto error; + } + idx = PyLong_AsSsize_t(key); + if (idx == -1 && PyErr_Occurred()) + goto error; + if (idx < 0) { + PyErr_SetString(PyExc_ValueError, + "memo key must be positive integers."); + goto error; + } + if (_Unpickler_MemoPut(self, idx, value) < 0) + goto error; + } + } + else { + PyErr_Format(PyExc_TypeError, + "'memo' attribute must be an UnpicklerMemoProxy object " + "or dict, not %.200s", Py_TYPE(obj)->tp_name); + return -1; + } + + _Unpickler_MemoCleanup(self); + self->memo_size = new_memo_size; + self->memo = new_memo; + + return 0; + + error: + if (new_memo_size) { + for (size_t i = new_memo_size - 1; i != SIZE_MAX; i--) { + Py_XDECREF(new_memo[i]); + } + PyMem_FREE(new_memo); + } + return -1; +} + +static PyObject * +Unpickler_get_persload(UnpicklerObject *self, void *Py_UNUSED(ignored)) +{ + if (self->pers_func == NULL) { + PyErr_SetString(PyExc_AttributeError, "persistent_load"); + return NULL; + } + return reconstruct_method(self->pers_func, self->pers_func_self); +} + +static int +Unpickler_set_persload(UnpicklerObject *self, PyObject *value, void *Py_UNUSED(ignored)) +{ + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "attribute deletion is not supported"); + return -1; + } + if (!PyCallable_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "persistent_load must be a callable taking " + "one argument"); + return -1; + } + + self->pers_func_self = NULL; + Py_INCREF(value); + Py_XSETREF(self->pers_func, value); + + return 0; +} + +static PyGetSetDef Unpickler_getsets[] = { + {"memo", (getter)Unpickler_get_memo, (setter)Unpickler_set_memo}, + {"persistent_load", (getter)Unpickler_get_persload, + (setter)Unpickler_set_persload}, + {NULL} +}; + +static PyTypeObject Unpickler_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_pickle.Unpickler", /*tp_name*/ + sizeof(UnpicklerObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)Unpickler_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - _pickle_Unpickler___init____doc__, /*tp_doc*/ - (traverseproc)Unpickler_traverse, /*tp_traverse*/ - (inquiry)Unpickler_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - Unpickler_methods, /*tp_methods*/ - 0, /*tp_members*/ - Unpickler_getsets, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - _pickle_Unpickler___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - PyType_GenericNew, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ - 0, /*tp_is_gc*/ -}; - -/*[clinic input] - -_pickle.dump - - obj: object - file: object + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + _pickle_Unpickler___init____doc__, /*tp_doc*/ + (traverseproc)Unpickler_traverse, /*tp_traverse*/ + (inquiry)Unpickler_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + Unpickler_methods, /*tp_methods*/ + 0, /*tp_members*/ + Unpickler_getsets, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + _pickle_Unpickler___init__, /*tp_init*/ + PyType_GenericAlloc, /*tp_alloc*/ + PyType_GenericNew, /*tp_new*/ + PyObject_GC_Del, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +/*[clinic input] + +_pickle.dump + + obj: object + file: object protocol: object = None - * - fix_imports: bool = True + * + fix_imports: bool = True buffer_callback: object = None - -Write a pickled representation of obj to the open file object file. - -This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may -be more efficient. - -The optional *protocol* argument tells the pickler to use the given + +Write a pickled representation of obj to the open file object file. + +This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may +be more efficient. + +The optional *protocol* argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default protocol is 4. It was introduced in Python 3.4, and is incompatible with previous versions. - -Specifying a negative protocol version selects the highest protocol -version supported. The higher the protocol used, the more recent the -version of Python needed to read the pickle produced. - -The *file* argument must have a write() method that accepts a single -bytes argument. It can thus be a file object opened for binary -writing, an io.BytesIO instance, or any other custom object that meets -this interface. - -If *fix_imports* is True and protocol is less than 3, pickle will try -to map the new Python 3 names to the old module names used in Python -2, so that the pickle data stream is readable with Python 2. + +Specifying a negative protocol version selects the highest protocol +version supported. The higher the protocol used, the more recent the +version of Python needed to read the pickle produced. + +The *file* argument must have a write() method that accepts a single +bytes argument. It can thus be a file object opened for binary +writing, an io.BytesIO instance, or any other custom object that meets +this interface. + +If *fix_imports* is True and protocol is less than 3, pickle will try +to map the new Python 3 names to the old module names used in Python +2, so that the pickle data stream is readable with Python 2. If *buffer_callback* is None (the default), buffer views are serialized into *file* as part of the pickle stream. It is an error if *buffer_callback* is not None and *protocol* is None or smaller than 5. -[clinic start generated code]*/ - -static PyObject * -_pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, +[clinic start generated code]*/ + +static PyObject * +_pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports, PyObject *buffer_callback) /*[clinic end generated code: output=706186dba996490c input=5ed6653da99cd97c]*/ -{ - PicklerObject *pickler = _Pickler_New(); - - if (pickler == NULL) - return NULL; - - if (_Pickler_SetProtocol(pickler, protocol, fix_imports) < 0) - goto error; - - if (_Pickler_SetOutputStream(pickler, file) < 0) - goto error; - +{ + PicklerObject *pickler = _Pickler_New(); + + if (pickler == NULL) + return NULL; + + if (_Pickler_SetProtocol(pickler, protocol, fix_imports) < 0) + goto error; + + if (_Pickler_SetOutputStream(pickler, file) < 0) + goto error; + if (_Pickler_SetBufferCallback(pickler, buffer_callback) < 0) goto error; - if (dump(pickler, obj) < 0) - goto error; - - if (_Pickler_FlushToFile(pickler) < 0) - goto error; - - Py_DECREF(pickler); - Py_RETURN_NONE; - - error: - Py_XDECREF(pickler); - return NULL; -} - -/*[clinic input] - -_pickle.dumps - - obj: object + if (dump(pickler, obj) < 0) + goto error; + + if (_Pickler_FlushToFile(pickler) < 0) + goto error; + + Py_DECREF(pickler); + Py_RETURN_NONE; + + error: + Py_XDECREF(pickler); + return NULL; +} + +/*[clinic input] + +_pickle.dumps + + obj: object protocol: object = None - * - fix_imports: bool = True + * + fix_imports: bool = True buffer_callback: object = None - -Return the pickled representation of the object as a bytes object. - -The optional *protocol* argument tells the pickler to use the given + +Return the pickled representation of the object as a bytes object. + +The optional *protocol* argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default protocol is 4. It was introduced in Python 3.4, and is incompatible with previous versions. - -Specifying a negative protocol version selects the highest protocol -version supported. The higher the protocol used, the more recent the -version of Python needed to read the pickle produced. - -If *fix_imports* is True and *protocol* is less than 3, pickle will -try to map the new Python 3 names to the old module names used in -Python 2, so that the pickle data stream is readable with Python 2. + +Specifying a negative protocol version selects the highest protocol +version supported. The higher the protocol used, the more recent the +version of Python needed to read the pickle produced. + +If *fix_imports* is True and *protocol* is less than 3, pickle will +try to map the new Python 3 names to the old module names used in +Python 2, so that the pickle data stream is readable with Python 2. If *buffer_callback* is None (the default), buffer views are serialized into *file* as part of the pickle stream. It is an error if *buffer_callback* is not None and *protocol* is None or smaller than 5. -[clinic start generated code]*/ - -static PyObject * -_pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, +[clinic start generated code]*/ + +static PyObject * +_pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, int fix_imports, PyObject *buffer_callback) /*[clinic end generated code: output=fbab0093a5580fdf input=e543272436c6f987]*/ -{ - PyObject *result; - PicklerObject *pickler = _Pickler_New(); - - if (pickler == NULL) - return NULL; - - if (_Pickler_SetProtocol(pickler, protocol, fix_imports) < 0) - goto error; - +{ + PyObject *result; + PicklerObject *pickler = _Pickler_New(); + + if (pickler == NULL) + return NULL; + + if (_Pickler_SetProtocol(pickler, protocol, fix_imports) < 0) + goto error; + if (_Pickler_SetBufferCallback(pickler, buffer_callback) < 0) goto error; - if (dump(pickler, obj) < 0) - goto error; - - result = _Pickler_GetString(pickler); - Py_DECREF(pickler); - return result; - - error: - Py_XDECREF(pickler); - return NULL; -} - -/*[clinic input] - -_pickle.load - - file: object - * - fix_imports: bool = True - encoding: str = 'ASCII' - errors: str = 'strict' + if (dump(pickler, obj) < 0) + goto error; + + result = _Pickler_GetString(pickler); + Py_DECREF(pickler); + return result; + + error: + Py_XDECREF(pickler); + return NULL; +} + +/*[clinic input] + +_pickle.load + + file: object + * + fix_imports: bool = True + encoding: str = 'ASCII' + errors: str = 'strict' buffers: object(c_default="NULL") = () - -Read and return an object from the pickle data stored in a file. - -This is equivalent to ``Unpickler(file).load()``, but may be more -efficient. - -The protocol version of the pickle is detected automatically, so no -protocol argument is needed. Bytes past the pickled object's -representation are ignored. - -The argument *file* must have two methods, a read() method that takes -an integer argument, and a readline() method that requires no -arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, an io.BytesIO object, or any -other custom object that meets this interface. - -Optional keyword arguments are *fix_imports*, *encoding* and *errors*, -which are used to control compatibility support for pickle stream -generated by Python 2. If *fix_imports* is True, pickle will try to -map the old Python 2 names to the new names used in Python 3. The -*encoding* and *errors* tell pickle how to decode 8-bit string -instances pickled by Python 2; these default to 'ASCII' and 'strict', -respectively. The *encoding* can be 'bytes' to read these 8-bit -string instances as bytes objects. -[clinic start generated code]*/ - -static PyObject * -_pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, + +Read and return an object from the pickle data stored in a file. + +This is equivalent to ``Unpickler(file).load()``, but may be more +efficient. + +The protocol version of the pickle is detected automatically, so no +protocol argument is needed. Bytes past the pickled object's +representation are ignored. + +The argument *file* must have two methods, a read() method that takes +an integer argument, and a readline() method that requires no +arguments. Both methods should return bytes. Thus *file* can be a +binary file object opened for reading, an io.BytesIO object, or any +other custom object that meets this interface. + +Optional keyword arguments are *fix_imports*, *encoding* and *errors*, +which are used to control compatibility support for pickle stream +generated by Python 2. If *fix_imports* is True, pickle will try to +map the old Python 2 names to the new names used in Python 3. The +*encoding* and *errors* tell pickle how to decode 8-bit string +instances pickled by Python 2; these default to 'ASCII' and 'strict', +respectively. The *encoding* can be 'bytes' to read these 8-bit +string instances as bytes objects. +[clinic start generated code]*/ + +static PyObject * +_pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, const char *encoding, const char *errors, PyObject *buffers) /*[clinic end generated code: output=250452d141c23e76 input=46c7c31c92f4f371]*/ -{ - PyObject *result; - UnpicklerObject *unpickler = _Unpickler_New(); - - if (unpickler == NULL) - return NULL; - - if (_Unpickler_SetInputStream(unpickler, file) < 0) - goto error; - - if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0) - goto error; - +{ + PyObject *result; + UnpicklerObject *unpickler = _Unpickler_New(); + + if (unpickler == NULL) + return NULL; + + if (_Unpickler_SetInputStream(unpickler, file) < 0) + goto error; + + if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0) + goto error; + if (_Unpickler_SetBuffers(unpickler, buffers) < 0) goto error; - unpickler->fix_imports = fix_imports; - - result = load(unpickler); - Py_DECREF(unpickler); - return result; - - error: - Py_XDECREF(unpickler); - return NULL; -} - -/*[clinic input] - -_pickle.loads - - data: object + unpickler->fix_imports = fix_imports; + + result = load(unpickler); + Py_DECREF(unpickler); + return result; + + error: + Py_XDECREF(unpickler); + return NULL; +} + +/*[clinic input] + +_pickle.loads + + data: object / - * - fix_imports: bool = True - encoding: str = 'ASCII' - errors: str = 'strict' + * + fix_imports: bool = True + encoding: str = 'ASCII' + errors: str = 'strict' buffers: object(c_default="NULL") = () - -Read and return an object from the given pickle data. - -The protocol version of the pickle is detected automatically, so no -protocol argument is needed. Bytes past the pickled object's -representation are ignored. - -Optional keyword arguments are *fix_imports*, *encoding* and *errors*, -which are used to control compatibility support for pickle stream -generated by Python 2. If *fix_imports* is True, pickle will try to -map the old Python 2 names to the new names used in Python 3. The -*encoding* and *errors* tell pickle how to decode 8-bit string -instances pickled by Python 2; these default to 'ASCII' and 'strict', -respectively. The *encoding* can be 'bytes' to read these 8-bit -string instances as bytes objects. -[clinic start generated code]*/ - -static PyObject * -_pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, + +Read and return an object from the given pickle data. + +The protocol version of the pickle is detected automatically, so no +protocol argument is needed. Bytes past the pickled object's +representation are ignored. + +Optional keyword arguments are *fix_imports*, *encoding* and *errors*, +which are used to control compatibility support for pickle stream +generated by Python 2. If *fix_imports* is True, pickle will try to +map the old Python 2 names to the new names used in Python 3. The +*encoding* and *errors* tell pickle how to decode 8-bit string +instances pickled by Python 2; these default to 'ASCII' and 'strict', +respectively. The *encoding* can be 'bytes' to read these 8-bit +string instances as bytes objects. +[clinic start generated code]*/ + +static PyObject * +_pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, const char *encoding, const char *errors, PyObject *buffers) /*[clinic end generated code: output=82ac1e6b588e6d02 input=b3615540d0535087]*/ -{ - PyObject *result; - UnpicklerObject *unpickler = _Unpickler_New(); - - if (unpickler == NULL) - return NULL; - - if (_Unpickler_SetStringInput(unpickler, data) < 0) - goto error; - - if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0) - goto error; - +{ + PyObject *result; + UnpicklerObject *unpickler = _Unpickler_New(); + + if (unpickler == NULL) + return NULL; + + if (_Unpickler_SetStringInput(unpickler, data) < 0) + goto error; + + if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0) + goto error; + if (_Unpickler_SetBuffers(unpickler, buffers) < 0) goto error; - unpickler->fix_imports = fix_imports; - - result = load(unpickler); - Py_DECREF(unpickler); - return result; - - error: - Py_XDECREF(unpickler); - return NULL; -} - -static struct PyMethodDef pickle_methods[] = { - _PICKLE_DUMP_METHODDEF - _PICKLE_DUMPS_METHODDEF - _PICKLE_LOAD_METHODDEF - _PICKLE_LOADS_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static int -pickle_clear(PyObject *m) -{ - _Pickle_ClearState(_Pickle_GetState(m)); - return 0; -} - -static void -pickle_free(PyObject *m) -{ - _Pickle_ClearState(_Pickle_GetState(m)); -} - -static int -pickle_traverse(PyObject *m, visitproc visit, void *arg) -{ - PickleState *st = _Pickle_GetState(m); - Py_VISIT(st->PickleError); - Py_VISIT(st->PicklingError); - Py_VISIT(st->UnpicklingError); - Py_VISIT(st->dispatch_table); - Py_VISIT(st->extension_registry); - Py_VISIT(st->extension_cache); - Py_VISIT(st->inverted_registry); - Py_VISIT(st->name_mapping_2to3); - Py_VISIT(st->import_mapping_2to3); - Py_VISIT(st->name_mapping_3to2); - Py_VISIT(st->import_mapping_3to2); - Py_VISIT(st->codecs_encode); - Py_VISIT(st->getattr); + unpickler->fix_imports = fix_imports; + + result = load(unpickler); + Py_DECREF(unpickler); + return result; + + error: + Py_XDECREF(unpickler); + return NULL; +} + +static struct PyMethodDef pickle_methods[] = { + _PICKLE_DUMP_METHODDEF + _PICKLE_DUMPS_METHODDEF + _PICKLE_LOAD_METHODDEF + _PICKLE_LOADS_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static int +pickle_clear(PyObject *m) +{ + _Pickle_ClearState(_Pickle_GetState(m)); + return 0; +} + +static void +pickle_free(PyObject *m) +{ + _Pickle_ClearState(_Pickle_GetState(m)); +} + +static int +pickle_traverse(PyObject *m, visitproc visit, void *arg) +{ + PickleState *st = _Pickle_GetState(m); + Py_VISIT(st->PickleError); + Py_VISIT(st->PicklingError); + Py_VISIT(st->UnpicklingError); + Py_VISIT(st->dispatch_table); + Py_VISIT(st->extension_registry); + Py_VISIT(st->extension_cache); + Py_VISIT(st->inverted_registry); + Py_VISIT(st->name_mapping_2to3); + Py_VISIT(st->import_mapping_2to3); + Py_VISIT(st->name_mapping_3to2); + Py_VISIT(st->import_mapping_3to2); + Py_VISIT(st->codecs_encode); + Py_VISIT(st->getattr); Py_VISIT(st->partial); - return 0; -} - -static struct PyModuleDef _picklemodule = { - PyModuleDef_HEAD_INIT, - "_pickle", /* m_name */ - pickle_module_doc, /* m_doc */ - sizeof(PickleState), /* m_size */ - pickle_methods, /* m_methods */ - NULL, /* m_reload */ - pickle_traverse, /* m_traverse */ - pickle_clear, /* m_clear */ - (freefunc)pickle_free /* m_free */ -}; - -PyMODINIT_FUNC -PyInit__pickle(void) -{ - PyObject *m; - PickleState *st; - - m = PyState_FindModule(&_picklemodule); - if (m) { - Py_INCREF(m); - return m; - } - - if (PyType_Ready(&Pdata_Type) < 0) - return NULL; - if (PyType_Ready(&PicklerMemoProxyType) < 0) - return NULL; - if (PyType_Ready(&UnpicklerMemoProxyType) < 0) - return NULL; - - /* Create the module and add the functions. */ - m = PyModule_Create(&_picklemodule); - if (m == NULL) - return NULL; - + return 0; +} + +static struct PyModuleDef _picklemodule = { + PyModuleDef_HEAD_INIT, + "_pickle", /* m_name */ + pickle_module_doc, /* m_doc */ + sizeof(PickleState), /* m_size */ + pickle_methods, /* m_methods */ + NULL, /* m_reload */ + pickle_traverse, /* m_traverse */ + pickle_clear, /* m_clear */ + (freefunc)pickle_free /* m_free */ +}; + +PyMODINIT_FUNC +PyInit__pickle(void) +{ + PyObject *m; + PickleState *st; + + m = PyState_FindModule(&_picklemodule); + if (m) { + Py_INCREF(m); + return m; + } + + if (PyType_Ready(&Pdata_Type) < 0) + return NULL; + if (PyType_Ready(&PicklerMemoProxyType) < 0) + return NULL; + if (PyType_Ready(&UnpicklerMemoProxyType) < 0) + return NULL; + + /* Create the module and add the functions. */ + m = PyModule_Create(&_picklemodule); + if (m == NULL) + return NULL; + /* Add types */ if (PyModule_AddType(m, &Pickler_Type) < 0) { - return NULL; + return NULL; } if (PyModule_AddType(m, &Unpickler_Type) < 0) { - return NULL; + return NULL; } if (PyModule_AddType(m, &PyPickleBuffer_Type) < 0) { return NULL; } - - st = _Pickle_GetState(m); - - /* Initialize the exceptions. */ - st->PickleError = PyErr_NewException("_pickle.PickleError", NULL, NULL); - if (st->PickleError == NULL) - return NULL; - st->PicklingError = \ - PyErr_NewException("_pickle.PicklingError", st->PickleError, NULL); - if (st->PicklingError == NULL) - return NULL; - st->UnpicklingError = \ - PyErr_NewException("_pickle.UnpicklingError", st->PickleError, NULL); - if (st->UnpicklingError == NULL) - return NULL; - - Py_INCREF(st->PickleError); - if (PyModule_AddObject(m, "PickleError", st->PickleError) < 0) - return NULL; - Py_INCREF(st->PicklingError); - if (PyModule_AddObject(m, "PicklingError", st->PicklingError) < 0) - return NULL; - Py_INCREF(st->UnpicklingError); - if (PyModule_AddObject(m, "UnpicklingError", st->UnpicklingError) < 0) - return NULL; - - if (_Pickle_InitState(st) < 0) - return NULL; - - return m; -} + + st = _Pickle_GetState(m); + + /* Initialize the exceptions. */ + st->PickleError = PyErr_NewException("_pickle.PickleError", NULL, NULL); + if (st->PickleError == NULL) + return NULL; + st->PicklingError = \ + PyErr_NewException("_pickle.PicklingError", st->PickleError, NULL); + if (st->PicklingError == NULL) + return NULL; + st->UnpicklingError = \ + PyErr_NewException("_pickle.UnpicklingError", st->PickleError, NULL); + if (st->UnpicklingError == NULL) + return NULL; + + Py_INCREF(st->PickleError); + if (PyModule_AddObject(m, "PickleError", st->PickleError) < 0) + return NULL; + Py_INCREF(st->PicklingError); + if (PyModule_AddObject(m, "PicklingError", st->PicklingError) < 0) + return NULL; + Py_INCREF(st->UnpicklingError); + if (PyModule_AddObject(m, "UnpicklingError", st->UnpicklingError) < 0) + return NULL; + + if (_Pickle_InitState(st) < 0) + return NULL; + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_posixsubprocess.c b/contrib/tools/python3/src/Modules/_posixsubprocess.c index d64e0a1cfa0..2c5a940be08 100644 --- a/contrib/tools/python3/src/Modules/_posixsubprocess.c +++ b/contrib/tools/python3/src/Modules/_posixsubprocess.c @@ -1,71 +1,71 @@ -/* Authors: Gregory P. Smith & Jeffrey Yasskin */ -#include "Python.h" -#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE) -# define _GNU_SOURCE -#endif -#include -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif +/* Authors: Gregory P. Smith & Jeffrey Yasskin */ +#include "Python.h" +#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif #if defined(HAVE_SYS_STAT_H) -#include -#endif -#ifdef HAVE_SYS_SYSCALL_H -#include -#endif -#if defined(HAVE_SYS_RESOURCE_H) -#include -#endif -#ifdef HAVE_DIRENT_H -#include -#endif +#include +#endif +#ifdef HAVE_SYS_SYSCALL_H +#include +#endif +#if defined(HAVE_SYS_RESOURCE_H) +#include +#endif +#ifdef HAVE_DIRENT_H +#include +#endif #ifdef HAVE_GRP_H #include #endif /* HAVE_GRP_H */ - + #include "posixmodule.h" -#ifdef _Py_MEMORY_SANITIZER -# include -#endif - -#if defined(__ANDROID__) && __ANDROID_API__ < 21 && !defined(SYS_getdents64) -# include -# define SYS_getdents64 __NR_getdents64 -#endif - -#if defined(__sun) && defined(__SVR4) -/* readdir64 is used to work around Solaris 9 bug 6395699. */ -# define readdir readdir64 -# define dirent dirent64 -# if !defined(HAVE_DIRFD) -/* Some versions of Solaris lack dirfd(). */ -# define dirfd(dirp) ((dirp)->dd_fd) -# define HAVE_DIRFD -# endif -#endif - +#ifdef _Py_MEMORY_SANITIZER +# include +#endif + +#if defined(__ANDROID__) && __ANDROID_API__ < 21 && !defined(SYS_getdents64) +# include +# define SYS_getdents64 __NR_getdents64 +#endif + +#if defined(__sun) && defined(__SVR4) +/* readdir64 is used to work around Solaris 9 bug 6395699. */ +# define readdir readdir64 +# define dirent dirent64 +# if !defined(HAVE_DIRFD) +/* Some versions of Solaris lack dirfd(). */ +# define dirfd(dirp) ((dirp)->dd_fd) +# define HAVE_DIRFD +# endif +#endif + #if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__DragonFly__) -# define FD_DIR "/dev/fd" -#else -# define FD_DIR "/proc/self/fd" -#endif - +# define FD_DIR "/dev/fd" +#else +# define FD_DIR "/proc/self/fd" +#endif + #ifdef NGROUPS_MAX #define MAX_GROUPS NGROUPS_MAX #else #define MAX_GROUPS 64 #endif -#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0) - +#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0) + typedef struct { PyObject* disable; PyObject* enable; PyObject* isenabled; } _posixsubprocessstate; - + static struct PyModuleDef _posixsubprocessmodule; static inline _posixsubprocessstate* @@ -78,450 +78,450 @@ get_posixsubprocess_state(PyObject *module) #define _posixsubprocessstate_global get_posixsubprocess_state(PyState_FindModule(&_posixsubprocessmodule)) -/* If gc was disabled, call gc.enable(). Return 0 on success. */ -static int -_enable_gc(int need_to_reenable_gc, PyObject *gc_module) -{ - PyObject *result; - PyObject *exctype, *val, *tb; - - if (need_to_reenable_gc) { - PyErr_Fetch(&exctype, &val, &tb); +/* If gc was disabled, call gc.enable(). Return 0 on success. */ +static int +_enable_gc(int need_to_reenable_gc, PyObject *gc_module) +{ + PyObject *result; + PyObject *exctype, *val, *tb; + + if (need_to_reenable_gc) { + PyErr_Fetch(&exctype, &val, &tb); result = PyObject_CallMethodNoArgs( gc_module, _posixsubprocessstate_global->enable); - if (exctype != NULL) { - PyErr_Restore(exctype, val, tb); - } - if (result == NULL) { - return 1; - } - Py_DECREF(result); - } - return 0; -} - - -/* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */ -static int -_pos_int_from_ascii(const char *name) -{ - int num = 0; - while (*name >= '0' && *name <= '9') { - num = num * 10 + (*name - '0'); - ++name; - } - if (*name) - return -1; /* Non digit found, not a number. */ - return num; -} - - + if (exctype != NULL) { + PyErr_Restore(exctype, val, tb); + } + if (result == NULL) { + return 1; + } + Py_DECREF(result); + } + return 0; +} + + +/* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */ +static int +_pos_int_from_ascii(const char *name) +{ + int num = 0; + while (*name >= '0' && *name <= '9') { + num = num * 10 + (*name - '0'); + ++name; + } + if (*name) + return -1; /* Non digit found, not a number. */ + return num; +} + + #if defined(__FreeBSD__) || defined(__DragonFly__) -/* When /dev/fd isn't mounted it is often a static directory populated +/* When /dev/fd isn't mounted it is often a static directory populated * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD, OpenBSD and DragonFlyBSD. - * NetBSD and OpenBSD have a /proc fs available (though not necessarily - * mounted) and do not have fdescfs for /dev/fd. MacOS X has a devfs - * that properly supports /dev/fd. - */ -static int -_is_fdescfs_mounted_on_dev_fd(void) -{ - struct stat dev_stat; - struct stat dev_fd_stat; - if (stat("/dev", &dev_stat) != 0) - return 0; - if (stat(FD_DIR, &dev_fd_stat) != 0) - return 0; - if (dev_stat.st_dev == dev_fd_stat.st_dev) - return 0; /* / == /dev == /dev/fd means it is static. #fail */ - return 1; -} -#endif - - -/* Returns 1 if there is a problem with fd_sequence, 0 otherwise. */ -static int -_sanity_check_python_fd_sequence(PyObject *fd_sequence) -{ - Py_ssize_t seq_idx; - long prev_fd = -1; - for (seq_idx = 0; seq_idx < PyTuple_GET_SIZE(fd_sequence); ++seq_idx) { - PyObject* py_fd = PyTuple_GET_ITEM(fd_sequence, seq_idx); - long iter_fd; - if (!PyLong_Check(py_fd)) { - return 1; - } - iter_fd = PyLong_AsLong(py_fd); - if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) { - /* Negative, overflow, unsorted, too big for a fd. */ - return 1; - } - prev_fd = iter_fd; - } - return 0; -} - - -/* Is fd found in the sorted Python Sequence? */ -static int -_is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence) -{ - /* Binary search. */ - Py_ssize_t search_min = 0; - Py_ssize_t search_max = PyTuple_GET_SIZE(fd_sequence) - 1; - if (search_max < 0) - return 0; - do { - long middle = (search_min + search_max) / 2; - long middle_fd = PyLong_AsLong(PyTuple_GET_ITEM(fd_sequence, middle)); - if (fd == middle_fd) - return 1; - if (fd > middle_fd) - search_min = middle + 1; - else - search_max = middle - 1; - } while (search_min <= search_max); - return 0; -} - -static int -make_inheritable(PyObject *py_fds_to_keep, int errpipe_write) -{ - Py_ssize_t i, len; - - len = PyTuple_GET_SIZE(py_fds_to_keep); - for (i = 0; i < len; ++i) { - PyObject* fdobj = PyTuple_GET_ITEM(py_fds_to_keep, i); - long fd = PyLong_AsLong(fdobj); - assert(!PyErr_Occurred()); - assert(0 <= fd && fd <= INT_MAX); - if (fd == errpipe_write) { - /* errpipe_write is part of py_fds_to_keep. It must be closed at - exec(), but kept open in the child process until exec() is - called. */ - continue; - } - if (_Py_set_inheritable_async_safe((int)fd, 1, NULL) < 0) - return -1; - } - return 0; -} - - -/* Get the maximum file descriptor that could be opened by this process. - * This function is async signal safe for use between fork() and exec(). - */ -static long -safe_get_max_fd(void) -{ - long local_max_fd; -#if defined(__NetBSD__) - local_max_fd = fcntl(0, F_MAXFD); - if (local_max_fd >= 0) - return local_max_fd; -#endif -#if defined(HAVE_SYS_RESOURCE_H) && defined(__OpenBSD__) - struct rlimit rl; - /* Not on the POSIX async signal safe functions list but likely - * safe. TODO - Someone should audit OpenBSD to make sure. */ - if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) - return (long) rl.rlim_max; -#endif -#ifdef _SC_OPEN_MAX - local_max_fd = sysconf(_SC_OPEN_MAX); - if (local_max_fd == -1) -#endif - local_max_fd = 256; /* Matches legacy Lib/subprocess.py behavior. */ - return local_max_fd; -} - - -/* Close all file descriptors in the range from start_fd and higher - * except for those in py_fds_to_keep. If the range defined by - * [start_fd, safe_get_max_fd()) is large this will take a long - * time as it calls close() on EVERY possible fd. - * - * It isn't possible to know for sure what the max fd to go up to - * is for processes with the capability of raising their maximum. - */ -static void -_close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) -{ - long end_fd = safe_get_max_fd(); - Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE(py_fds_to_keep); - Py_ssize_t keep_seq_idx; - int fd_num; - /* As py_fds_to_keep is sorted we can loop through the list closing - * fds in between any in the keep list falling within our range. */ - for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) { - PyObject* py_keep_fd = PyTuple_GET_ITEM(py_fds_to_keep, keep_seq_idx); - int keep_fd = PyLong_AsLong(py_keep_fd); - if (keep_fd < start_fd) - continue; - for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) { - close(fd_num); - } - start_fd = keep_fd + 1; - } - if (start_fd <= end_fd) { + * NetBSD and OpenBSD have a /proc fs available (though not necessarily + * mounted) and do not have fdescfs for /dev/fd. MacOS X has a devfs + * that properly supports /dev/fd. + */ +static int +_is_fdescfs_mounted_on_dev_fd(void) +{ + struct stat dev_stat; + struct stat dev_fd_stat; + if (stat("/dev", &dev_stat) != 0) + return 0; + if (stat(FD_DIR, &dev_fd_stat) != 0) + return 0; + if (dev_stat.st_dev == dev_fd_stat.st_dev) + return 0; /* / == /dev == /dev/fd means it is static. #fail */ + return 1; +} +#endif + + +/* Returns 1 if there is a problem with fd_sequence, 0 otherwise. */ +static int +_sanity_check_python_fd_sequence(PyObject *fd_sequence) +{ + Py_ssize_t seq_idx; + long prev_fd = -1; + for (seq_idx = 0; seq_idx < PyTuple_GET_SIZE(fd_sequence); ++seq_idx) { + PyObject* py_fd = PyTuple_GET_ITEM(fd_sequence, seq_idx); + long iter_fd; + if (!PyLong_Check(py_fd)) { + return 1; + } + iter_fd = PyLong_AsLong(py_fd); + if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) { + /* Negative, overflow, unsorted, too big for a fd. */ + return 1; + } + prev_fd = iter_fd; + } + return 0; +} + + +/* Is fd found in the sorted Python Sequence? */ +static int +_is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence) +{ + /* Binary search. */ + Py_ssize_t search_min = 0; + Py_ssize_t search_max = PyTuple_GET_SIZE(fd_sequence) - 1; + if (search_max < 0) + return 0; + do { + long middle = (search_min + search_max) / 2; + long middle_fd = PyLong_AsLong(PyTuple_GET_ITEM(fd_sequence, middle)); + if (fd == middle_fd) + return 1; + if (fd > middle_fd) + search_min = middle + 1; + else + search_max = middle - 1; + } while (search_min <= search_max); + return 0; +} + +static int +make_inheritable(PyObject *py_fds_to_keep, int errpipe_write) +{ + Py_ssize_t i, len; + + len = PyTuple_GET_SIZE(py_fds_to_keep); + for (i = 0; i < len; ++i) { + PyObject* fdobj = PyTuple_GET_ITEM(py_fds_to_keep, i); + long fd = PyLong_AsLong(fdobj); + assert(!PyErr_Occurred()); + assert(0 <= fd && fd <= INT_MAX); + if (fd == errpipe_write) { + /* errpipe_write is part of py_fds_to_keep. It must be closed at + exec(), but kept open in the child process until exec() is + called. */ + continue; + } + if (_Py_set_inheritable_async_safe((int)fd, 1, NULL) < 0) + return -1; + } + return 0; +} + + +/* Get the maximum file descriptor that could be opened by this process. + * This function is async signal safe for use between fork() and exec(). + */ +static long +safe_get_max_fd(void) +{ + long local_max_fd; +#if defined(__NetBSD__) + local_max_fd = fcntl(0, F_MAXFD); + if (local_max_fd >= 0) + return local_max_fd; +#endif +#if defined(HAVE_SYS_RESOURCE_H) && defined(__OpenBSD__) + struct rlimit rl; + /* Not on the POSIX async signal safe functions list but likely + * safe. TODO - Someone should audit OpenBSD to make sure. */ + if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) + return (long) rl.rlim_max; +#endif +#ifdef _SC_OPEN_MAX + local_max_fd = sysconf(_SC_OPEN_MAX); + if (local_max_fd == -1) +#endif + local_max_fd = 256; /* Matches legacy Lib/subprocess.py behavior. */ + return local_max_fd; +} + + +/* Close all file descriptors in the range from start_fd and higher + * except for those in py_fds_to_keep. If the range defined by + * [start_fd, safe_get_max_fd()) is large this will take a long + * time as it calls close() on EVERY possible fd. + * + * It isn't possible to know for sure what the max fd to go up to + * is for processes with the capability of raising their maximum. + */ +static void +_close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) +{ + long end_fd = safe_get_max_fd(); + Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE(py_fds_to_keep); + Py_ssize_t keep_seq_idx; + int fd_num; + /* As py_fds_to_keep is sorted we can loop through the list closing + * fds in between any in the keep list falling within our range. */ + for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) { + PyObject* py_keep_fd = PyTuple_GET_ITEM(py_fds_to_keep, keep_seq_idx); + int keep_fd = PyLong_AsLong(py_keep_fd); + if (keep_fd < start_fd) + continue; + for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) { + close(fd_num); + } + start_fd = keep_fd + 1; + } + if (start_fd <= end_fd) { #if defined(__FreeBSD__) /* Any errors encountered while closing file descriptors are ignored */ closefrom(start_fd); #else - for (fd_num = start_fd; fd_num < end_fd; ++fd_num) { + for (fd_num = start_fd; fd_num < end_fd; ++fd_num) { /* Ignore errors */ (void)close(fd_num); - } + } #endif - } -} - - -#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) -/* It doesn't matter if d_name has room for NAME_MAX chars; we're using this - * only to read a directory of short file descriptor number names. The kernel - * will return an error if we didn't give it enough space. Highly Unlikely. - * This structure is very old and stable: It will not change unless the kernel - * chooses to break compatibility with all existing binaries. Highly Unlikely. - */ -struct linux_dirent64 { - unsigned long long d_ino; - long long d_off; - unsigned short d_reclen; /* Length of this linux_dirent */ - unsigned char d_type; - char d_name[256]; /* Filename (null-terminated) */ -}; - -/* Close all open file descriptors in the range from start_fd and higher - * Do not close any in the sorted py_fds_to_keep list. - * - * This version is async signal safe as it does not make any unsafe C library - * calls, malloc calls or handle any locks. It is _unfortunate_ to be forced - * to resort to making a kernel system call directly but this is the ONLY api - * available that does no harm. opendir/readdir/closedir perform memory - * allocation and locking so while they usually work they are not guaranteed - * to (especially if you have replaced your malloc implementation). A version - * of this function that uses those can be found in the _maybe_unsafe variant. - * - * This is Linux specific because that is all I am ready to test it on. It - * should be easy to add OS specific dirent or dirent64 structures and modify - * it with some cpp #define magic to work on other OSes as well if you want. - */ -static void -_close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) -{ - int fd_dir_fd; - - fd_dir_fd = _Py_open_noraise(FD_DIR, O_RDONLY); - if (fd_dir_fd == -1) { - /* No way to get a list of open fds. */ - _close_fds_by_brute_force(start_fd, py_fds_to_keep); - return; - } else { - char buffer[sizeof(struct linux_dirent64)]; - int bytes; - while ((bytes = syscall(SYS_getdents64, fd_dir_fd, - (struct linux_dirent64 *)buffer, - sizeof(buffer))) > 0) { - struct linux_dirent64 *entry; - int offset; -#ifdef _Py_MEMORY_SANITIZER - __msan_unpoison(buffer, bytes); -#endif - for (offset = 0; offset < bytes; offset += entry->d_reclen) { - int fd; - entry = (struct linux_dirent64 *)(buffer + offset); - if ((fd = _pos_int_from_ascii(entry->d_name)) < 0) - continue; /* Not a number. */ - if (fd != fd_dir_fd && fd >= start_fd && - !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { - close(fd); - } - } - } - close(fd_dir_fd); - } -} - -#define _close_open_fds _close_open_fds_safe - -#else /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ - - -/* Close all open file descriptors from start_fd and higher. - * Do not close any in the sorted py_fds_to_keep tuple. - * - * This function violates the strict use of async signal safe functions. :( - * It calls opendir(), readdir() and closedir(). Of these, the one most - * likely to ever cause a problem is opendir() as it performs an internal - * malloc(). Practically this should not be a problem. The Java VM makes the - * same calls between fork and exec in its own UNIXProcess_md.c implementation. - * - * readdir_r() is not used because it provides no benefit. It is typically - * implemented as readdir() followed by memcpy(). See also: - * http://womble.decadent.org.uk/readdir_r-advisory.html - */ -static void -_close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep) -{ - DIR *proc_fd_dir; -#ifndef HAVE_DIRFD - while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep)) { - ++start_fd; - } - /* Close our lowest fd before we call opendir so that it is likely to - * reuse that fd otherwise we might close opendir's file descriptor in - * our loop. This trick assumes that fd's are allocated on a lowest - * available basis. */ - close(start_fd); - ++start_fd; -#endif - + } +} + + +#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) +/* It doesn't matter if d_name has room for NAME_MAX chars; we're using this + * only to read a directory of short file descriptor number names. The kernel + * will return an error if we didn't give it enough space. Highly Unlikely. + * This structure is very old and stable: It will not change unless the kernel + * chooses to break compatibility with all existing binaries. Highly Unlikely. + */ +struct linux_dirent64 { + unsigned long long d_ino; + long long d_off; + unsigned short d_reclen; /* Length of this linux_dirent */ + unsigned char d_type; + char d_name[256]; /* Filename (null-terminated) */ +}; + +/* Close all open file descriptors in the range from start_fd and higher + * Do not close any in the sorted py_fds_to_keep list. + * + * This version is async signal safe as it does not make any unsafe C library + * calls, malloc calls or handle any locks. It is _unfortunate_ to be forced + * to resort to making a kernel system call directly but this is the ONLY api + * available that does no harm. opendir/readdir/closedir perform memory + * allocation and locking so while they usually work they are not guaranteed + * to (especially if you have replaced your malloc implementation). A version + * of this function that uses those can be found in the _maybe_unsafe variant. + * + * This is Linux specific because that is all I am ready to test it on. It + * should be easy to add OS specific dirent or dirent64 structures and modify + * it with some cpp #define magic to work on other OSes as well if you want. + */ +static void +_close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) +{ + int fd_dir_fd; + + fd_dir_fd = _Py_open_noraise(FD_DIR, O_RDONLY); + if (fd_dir_fd == -1) { + /* No way to get a list of open fds. */ + _close_fds_by_brute_force(start_fd, py_fds_to_keep); + return; + } else { + char buffer[sizeof(struct linux_dirent64)]; + int bytes; + while ((bytes = syscall(SYS_getdents64, fd_dir_fd, + (struct linux_dirent64 *)buffer, + sizeof(buffer))) > 0) { + struct linux_dirent64 *entry; + int offset; +#ifdef _Py_MEMORY_SANITIZER + __msan_unpoison(buffer, bytes); +#endif + for (offset = 0; offset < bytes; offset += entry->d_reclen) { + int fd; + entry = (struct linux_dirent64 *)(buffer + offset); + if ((fd = _pos_int_from_ascii(entry->d_name)) < 0) + continue; /* Not a number. */ + if (fd != fd_dir_fd && fd >= start_fd && + !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { + close(fd); + } + } + } + close(fd_dir_fd); + } +} + +#define _close_open_fds _close_open_fds_safe + +#else /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ + + +/* Close all open file descriptors from start_fd and higher. + * Do not close any in the sorted py_fds_to_keep tuple. + * + * This function violates the strict use of async signal safe functions. :( + * It calls opendir(), readdir() and closedir(). Of these, the one most + * likely to ever cause a problem is opendir() as it performs an internal + * malloc(). Practically this should not be a problem. The Java VM makes the + * same calls between fork and exec in its own UNIXProcess_md.c implementation. + * + * readdir_r() is not used because it provides no benefit. It is typically + * implemented as readdir() followed by memcpy(). See also: + * http://womble.decadent.org.uk/readdir_r-advisory.html + */ +static void +_close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep) +{ + DIR *proc_fd_dir; +#ifndef HAVE_DIRFD + while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep)) { + ++start_fd; + } + /* Close our lowest fd before we call opendir so that it is likely to + * reuse that fd otherwise we might close opendir's file descriptor in + * our loop. This trick assumes that fd's are allocated on a lowest + * available basis. */ + close(start_fd); + ++start_fd; +#endif + #if defined(__FreeBSD__) || defined(__DragonFly__) - if (!_is_fdescfs_mounted_on_dev_fd()) - proc_fd_dir = NULL; - else -#endif - proc_fd_dir = opendir(FD_DIR); - if (!proc_fd_dir) { - /* No way to get a list of open fds. */ - _close_fds_by_brute_force(start_fd, py_fds_to_keep); - } else { - struct dirent *dir_entry; -#ifdef HAVE_DIRFD - int fd_used_by_opendir = dirfd(proc_fd_dir); -#else - int fd_used_by_opendir = start_fd - 1; -#endif - errno = 0; - while ((dir_entry = readdir(proc_fd_dir))) { - int fd; - if ((fd = _pos_int_from_ascii(dir_entry->d_name)) < 0) - continue; /* Not a number. */ - if (fd != fd_used_by_opendir && fd >= start_fd && - !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { - close(fd); - } - errno = 0; - } - if (errno) { - /* readdir error, revert behavior. Highly Unlikely. */ - _close_fds_by_brute_force(start_fd, py_fds_to_keep); - } - closedir(proc_fd_dir); - } -} - -#define _close_open_fds _close_open_fds_maybe_unsafe - -#endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ - - -/* - * This function is code executed in the child process immediately after fork - * to set things up and call exec(). - * - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - * - * This restriction is documented at - * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html. - */ -static void -child_exec(char *const exec_array[], - char *const argv[], - char *const envp[], - const char *cwd, - int p2cread, int p2cwrite, - int c2pread, int c2pwrite, - int errread, int errwrite, - int errpipe_read, int errpipe_write, - int close_fds, int restore_signals, - int call_setsid, + if (!_is_fdescfs_mounted_on_dev_fd()) + proc_fd_dir = NULL; + else +#endif + proc_fd_dir = opendir(FD_DIR); + if (!proc_fd_dir) { + /* No way to get a list of open fds. */ + _close_fds_by_brute_force(start_fd, py_fds_to_keep); + } else { + struct dirent *dir_entry; +#ifdef HAVE_DIRFD + int fd_used_by_opendir = dirfd(proc_fd_dir); +#else + int fd_used_by_opendir = start_fd - 1; +#endif + errno = 0; + while ((dir_entry = readdir(proc_fd_dir))) { + int fd; + if ((fd = _pos_int_from_ascii(dir_entry->d_name)) < 0) + continue; /* Not a number. */ + if (fd != fd_used_by_opendir && fd >= start_fd && + !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { + close(fd); + } + errno = 0; + } + if (errno) { + /* readdir error, revert behavior. Highly Unlikely. */ + _close_fds_by_brute_force(start_fd, py_fds_to_keep); + } + closedir(proc_fd_dir); + } +} + +#define _close_open_fds _close_open_fds_maybe_unsafe + +#endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ + + +/* + * This function is code executed in the child process immediately after fork + * to set things up and call exec(). + * + * All of the code in this function must only use async-signal-safe functions, + * listed at `man 7 signal` or + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. + * + * This restriction is documented at + * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html. + */ +static void +child_exec(char *const exec_array[], + char *const argv[], + char *const envp[], + const char *cwd, + int p2cread, int p2cwrite, + int c2pread, int c2pwrite, + int errread, int errwrite, + int errpipe_read, int errpipe_write, + int close_fds, int restore_signals, + int call_setsid, int call_setgid, gid_t gid, int call_setgroups, size_t groups_size, const gid_t *groups, int call_setuid, uid_t uid, int child_umask, - PyObject *py_fds_to_keep, - PyObject *preexec_fn, - PyObject *preexec_fn_args_tuple) -{ - int i, saved_errno, reached_preexec = 0; - PyObject *result; - const char* err_msg = ""; - /* Buffer large enough to hold a hex integer. We can't malloc. */ - char hex_errno[sizeof(saved_errno)*2+1]; - - if (make_inheritable(py_fds_to_keep, errpipe_write) < 0) - goto error; - - /* Close parent's pipe ends. */ - if (p2cwrite != -1) - POSIX_CALL(close(p2cwrite)); - if (c2pread != -1) - POSIX_CALL(close(c2pread)); - if (errread != -1) - POSIX_CALL(close(errread)); - POSIX_CALL(close(errpipe_read)); - - /* When duping fds, if there arises a situation where one of the fds is - either 0, 1 or 2, it is possible that it is overwritten (#12607). */ - if (c2pwrite == 0) { - POSIX_CALL(c2pwrite = dup(c2pwrite)); - /* issue32270 */ - if (_Py_set_inheritable_async_safe(c2pwrite, 0, NULL) < 0) { - goto error; - } - } - while (errwrite == 0 || errwrite == 1) { - POSIX_CALL(errwrite = dup(errwrite)); - /* issue32270 */ - if (_Py_set_inheritable_async_safe(errwrite, 0, NULL) < 0) { - goto error; - } - } - - /* Dup fds for child. - dup2() removes the CLOEXEC flag but we must do it ourselves if dup2() - would be a no-op (issue #10806). */ - if (p2cread == 0) { - if (_Py_set_inheritable_async_safe(p2cread, 1, NULL) < 0) - goto error; - } - else if (p2cread != -1) - POSIX_CALL(dup2(p2cread, 0)); /* stdin */ - - if (c2pwrite == 1) { - if (_Py_set_inheritable_async_safe(c2pwrite, 1, NULL) < 0) - goto error; - } - else if (c2pwrite != -1) - POSIX_CALL(dup2(c2pwrite, 1)); /* stdout */ - - if (errwrite == 2) { - if (_Py_set_inheritable_async_safe(errwrite, 1, NULL) < 0) - goto error; - } - else if (errwrite != -1) - POSIX_CALL(dup2(errwrite, 2)); /* stderr */ - - /* We no longer manually close p2cread, c2pwrite, and errwrite here as - * _close_open_fds takes care when it is not already non-inheritable. */ - - if (cwd) - POSIX_CALL(chdir(cwd)); - + PyObject *py_fds_to_keep, + PyObject *preexec_fn, + PyObject *preexec_fn_args_tuple) +{ + int i, saved_errno, reached_preexec = 0; + PyObject *result; + const char* err_msg = ""; + /* Buffer large enough to hold a hex integer. We can't malloc. */ + char hex_errno[sizeof(saved_errno)*2+1]; + + if (make_inheritable(py_fds_to_keep, errpipe_write) < 0) + goto error; + + /* Close parent's pipe ends. */ + if (p2cwrite != -1) + POSIX_CALL(close(p2cwrite)); + if (c2pread != -1) + POSIX_CALL(close(c2pread)); + if (errread != -1) + POSIX_CALL(close(errread)); + POSIX_CALL(close(errpipe_read)); + + /* When duping fds, if there arises a situation where one of the fds is + either 0, 1 or 2, it is possible that it is overwritten (#12607). */ + if (c2pwrite == 0) { + POSIX_CALL(c2pwrite = dup(c2pwrite)); + /* issue32270 */ + if (_Py_set_inheritable_async_safe(c2pwrite, 0, NULL) < 0) { + goto error; + } + } + while (errwrite == 0 || errwrite == 1) { + POSIX_CALL(errwrite = dup(errwrite)); + /* issue32270 */ + if (_Py_set_inheritable_async_safe(errwrite, 0, NULL) < 0) { + goto error; + } + } + + /* Dup fds for child. + dup2() removes the CLOEXEC flag but we must do it ourselves if dup2() + would be a no-op (issue #10806). */ + if (p2cread == 0) { + if (_Py_set_inheritable_async_safe(p2cread, 1, NULL) < 0) + goto error; + } + else if (p2cread != -1) + POSIX_CALL(dup2(p2cread, 0)); /* stdin */ + + if (c2pwrite == 1) { + if (_Py_set_inheritable_async_safe(c2pwrite, 1, NULL) < 0) + goto error; + } + else if (c2pwrite != -1) + POSIX_CALL(dup2(c2pwrite, 1)); /* stdout */ + + if (errwrite == 2) { + if (_Py_set_inheritable_async_safe(errwrite, 1, NULL) < 0) + goto error; + } + else if (errwrite != -1) + POSIX_CALL(dup2(errwrite, 2)); /* stderr */ + + /* We no longer manually close p2cread, c2pwrite, and errwrite here as + * _close_open_fds takes care when it is not already non-inheritable. */ + + if (cwd) + POSIX_CALL(chdir(cwd)); + if (child_umask >= 0) umask(child_umask); /* umask() always succeeds. */ - if (restore_signals) - _Py_RestoreSignals(); - -#ifdef HAVE_SETSID - if (call_setsid) - POSIX_CALL(setsid()); -#endif - + if (restore_signals) + _Py_RestoreSignals(); + +#ifdef HAVE_SETSID + if (call_setsid) + POSIX_CALL(setsid()); +#endif + #ifdef HAVE_SETGROUPS if (call_setgroups) POSIX_CALL(setgroups(groups_size, groups)); @@ -538,115 +538,115 @@ child_exec(char *const exec_array[], #endif /* HAVE_SETREUID */ - reached_preexec = 1; - if (preexec_fn != Py_None && preexec_fn_args_tuple) { - /* This is where the user has asked us to deadlock their program. */ - result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL); - if (result == NULL) { - /* Stringifying the exception or traceback would involve - * memory allocation and thus potential for deadlock. - * We've already faced potential deadlock by calling back - * into Python in the first place, so it probably doesn't - * matter but we avoid it to minimize the possibility. */ - err_msg = "Exception occurred in preexec_fn."; - errno = 0; /* We don't want to report an OSError. */ - goto error; - } - /* Py_DECREF(result); - We're about to exec so why bother? */ - } - - /* close FDs after executing preexec_fn, which might open FDs */ - if (close_fds) { - /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */ - _close_open_fds(3, py_fds_to_keep); - } - - /* This loop matches the Lib/os.py _execvpe()'s PATH search when */ - /* given the executable_list generated by Lib/subprocess.py. */ - saved_errno = 0; - for (i = 0; exec_array[i] != NULL; ++i) { - const char *executable = exec_array[i]; - if (envp) { - execve(executable, argv, envp); - } else { - execv(executable, argv); - } - if (errno != ENOENT && errno != ENOTDIR && saved_errno == 0) { - saved_errno = errno; - } - } - /* Report the first exec error, not the last. */ - if (saved_errno) - errno = saved_errno; - -error: - saved_errno = errno; - /* Report the posix error to our parent process. */ - /* We ignore all write() return values as the total size of our writes is - less than PIPEBUF and we cannot do anything about an error anyways. - Use _Py_write_noraise() to retry write() if it is interrupted by a - signal (fails with EINTR). */ - if (saved_errno) { - char *cur; - _Py_write_noraise(errpipe_write, "OSError:", 8); - cur = hex_errno + sizeof(hex_errno); - while (saved_errno != 0 && cur != hex_errno) { - *--cur = Py_hexdigits[saved_errno % 16]; - saved_errno /= 16; - } - _Py_write_noraise(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur); - _Py_write_noraise(errpipe_write, ":", 1); - if (!reached_preexec) { - /* Indicate to the parent that the error happened before exec(). */ - _Py_write_noraise(errpipe_write, "noexec", 6); - } - /* We can't call strerror(saved_errno). It is not async signal safe. - * The parent process will look the error message up. */ - } else { - _Py_write_noraise(errpipe_write, "SubprocessError:0:", 18); - _Py_write_noraise(errpipe_write, err_msg, strlen(err_msg)); - } -} - - -static PyObject * -subprocess_fork_exec(PyObject* self, PyObject *args) -{ - PyObject *gc_module = NULL; - PyObject *executable_list, *py_fds_to_keep; - PyObject *env_list, *preexec_fn; - PyObject *process_args, *converted_args = NULL, *fast_args = NULL; - PyObject *preexec_fn_args_tuple = NULL; + reached_preexec = 1; + if (preexec_fn != Py_None && preexec_fn_args_tuple) { + /* This is where the user has asked us to deadlock their program. */ + result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL); + if (result == NULL) { + /* Stringifying the exception or traceback would involve + * memory allocation and thus potential for deadlock. + * We've already faced potential deadlock by calling back + * into Python in the first place, so it probably doesn't + * matter but we avoid it to minimize the possibility. */ + err_msg = "Exception occurred in preexec_fn."; + errno = 0; /* We don't want to report an OSError. */ + goto error; + } + /* Py_DECREF(result); - We're about to exec so why bother? */ + } + + /* close FDs after executing preexec_fn, which might open FDs */ + if (close_fds) { + /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */ + _close_open_fds(3, py_fds_to_keep); + } + + /* This loop matches the Lib/os.py _execvpe()'s PATH search when */ + /* given the executable_list generated by Lib/subprocess.py. */ + saved_errno = 0; + for (i = 0; exec_array[i] != NULL; ++i) { + const char *executable = exec_array[i]; + if (envp) { + execve(executable, argv, envp); + } else { + execv(executable, argv); + } + if (errno != ENOENT && errno != ENOTDIR && saved_errno == 0) { + saved_errno = errno; + } + } + /* Report the first exec error, not the last. */ + if (saved_errno) + errno = saved_errno; + +error: + saved_errno = errno; + /* Report the posix error to our parent process. */ + /* We ignore all write() return values as the total size of our writes is + less than PIPEBUF and we cannot do anything about an error anyways. + Use _Py_write_noraise() to retry write() if it is interrupted by a + signal (fails with EINTR). */ + if (saved_errno) { + char *cur; + _Py_write_noraise(errpipe_write, "OSError:", 8); + cur = hex_errno + sizeof(hex_errno); + while (saved_errno != 0 && cur != hex_errno) { + *--cur = Py_hexdigits[saved_errno % 16]; + saved_errno /= 16; + } + _Py_write_noraise(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur); + _Py_write_noraise(errpipe_write, ":", 1); + if (!reached_preexec) { + /* Indicate to the parent that the error happened before exec(). */ + _Py_write_noraise(errpipe_write, "noexec", 6); + } + /* We can't call strerror(saved_errno). It is not async signal safe. + * The parent process will look the error message up. */ + } else { + _Py_write_noraise(errpipe_write, "SubprocessError:0:", 18); + _Py_write_noraise(errpipe_write, err_msg, strlen(err_msg)); + } +} + + +static PyObject * +subprocess_fork_exec(PyObject* self, PyObject *args) +{ + PyObject *gc_module = NULL; + PyObject *executable_list, *py_fds_to_keep; + PyObject *env_list, *preexec_fn; + PyObject *process_args, *converted_args = NULL, *fast_args = NULL; + PyObject *preexec_fn_args_tuple = NULL; PyObject *groups_list; PyObject *uid_object, *gid_object; - int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite; - int errpipe_read, errpipe_write, close_fds, restore_signals; - int call_setsid; + int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite; + int errpipe_read, errpipe_write, close_fds, restore_signals; + int call_setsid; int call_setgid = 0, call_setgroups = 0, call_setuid = 0; uid_t uid; gid_t gid, *groups = NULL; int child_umask; PyObject *cwd_obj, *cwd_obj2 = NULL; - const char *cwd; - pid_t pid; - int need_to_reenable_gc = 0; - char *const *exec_array, *const *argv = NULL, *const *envp = NULL; + const char *cwd; + pid_t pid; + int need_to_reenable_gc = 0; + char *const *exec_array, *const *argv = NULL, *const *envp = NULL; Py_ssize_t arg_num, num_groups = 0; - int need_after_fork = 0; - int saved_errno = 0; - - if (!PyArg_ParseTuple( + int need_after_fork = 0; + int saved_errno = 0; + + if (!PyArg_ParseTuple( args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec", - &process_args, &executable_list, - &close_fds, &PyTuple_Type, &py_fds_to_keep, - &cwd_obj, &env_list, - &p2cread, &p2cwrite, &c2pread, &c2pwrite, - &errread, &errwrite, &errpipe_read, &errpipe_write, + &process_args, &executable_list, + &close_fds, &PyTuple_Type, &py_fds_to_keep, + &cwd_obj, &env_list, + &p2cread, &p2cwrite, &c2pread, &c2pwrite, + &errread, &errwrite, &errpipe_read, &errpipe_write, &restore_signals, &call_setsid, &gid_object, &groups_list, &uid_object, &child_umask, &preexec_fn)) - return NULL; - + return NULL; + if ((preexec_fn != Py_None) && (PyInterpreterState_Get() != PyInterpreterState_Main())) { PyErr_SetString(PyExc_RuntimeError, @@ -654,15 +654,15 @@ subprocess_fork_exec(PyObject* self, PyObject *args) return NULL; } - if (close_fds && errpipe_write < 3) { /* precondition */ - PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3"); - return NULL; - } - if (_sanity_check_python_fd_sequence(py_fds_to_keep)) { - PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep"); - return NULL; - } - + if (close_fds && errpipe_write < 3) { /* precondition */ + PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3"); + return NULL; + } + if (_sanity_check_python_fd_sequence(py_fds_to_keep)) { + PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep"); + return NULL; + } + PyInterpreterState *interp = PyInterpreterState_Get(); const PyConfig *config = _PyInterpreterState_GetConfig(interp); if (config->_isolated_interpreter) { @@ -671,85 +671,85 @@ subprocess_fork_exec(PyObject* self, PyObject *args) return NULL; } - /* We need to call gc.disable() when we'll be calling preexec_fn */ - if (preexec_fn != Py_None) { - PyObject *result; - - gc_module = PyImport_ImportModule("gc"); - if (gc_module == NULL) - return NULL; + /* We need to call gc.disable() when we'll be calling preexec_fn */ + if (preexec_fn != Py_None) { + PyObject *result; + + gc_module = PyImport_ImportModule("gc"); + if (gc_module == NULL) + return NULL; result = PyObject_CallMethodNoArgs( gc_module, _posixsubprocessstate_global->isenabled); - if (result == NULL) { - Py_DECREF(gc_module); - return NULL; - } - need_to_reenable_gc = PyObject_IsTrue(result); - Py_DECREF(result); - if (need_to_reenable_gc == -1) { - Py_DECREF(gc_module); - return NULL; - } + if (result == NULL) { + Py_DECREF(gc_module); + return NULL; + } + need_to_reenable_gc = PyObject_IsTrue(result); + Py_DECREF(result); + if (need_to_reenable_gc == -1) { + Py_DECREF(gc_module); + return NULL; + } result = PyObject_CallMethodNoArgs( gc_module, _posixsubprocessstate_global->disable); - if (result == NULL) { - Py_DECREF(gc_module); - return NULL; - } - Py_DECREF(result); - } - - exec_array = _PySequence_BytesToCharpArray(executable_list); - if (!exec_array) - goto cleanup; - - /* Convert args and env into appropriate arguments for exec() */ - /* These conversions are done in the parent process to avoid allocating - or freeing memory in the child process. */ - if (process_args != Py_None) { - Py_ssize_t num_args; - /* Equivalent to: */ - /* tuple(PyUnicode_FSConverter(arg) for arg in process_args) */ - fast_args = PySequence_Fast(process_args, "argv must be a tuple"); - if (fast_args == NULL) - goto cleanup; - num_args = PySequence_Fast_GET_SIZE(fast_args); - converted_args = PyTuple_New(num_args); - if (converted_args == NULL) - goto cleanup; - for (arg_num = 0; arg_num < num_args; ++arg_num) { - PyObject *borrowed_arg, *converted_arg; - if (PySequence_Fast_GET_SIZE(fast_args) != num_args) { - PyErr_SetString(PyExc_RuntimeError, "args changed during iteration"); - goto cleanup; - } - borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num); - if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0) - goto cleanup; - PyTuple_SET_ITEM(converted_args, arg_num, converted_arg); - } - - argv = _PySequence_BytesToCharpArray(converted_args); - Py_CLEAR(converted_args); - Py_CLEAR(fast_args); - if (!argv) - goto cleanup; - } - - if (env_list != Py_None) { - envp = _PySequence_BytesToCharpArray(env_list); - if (!envp) - goto cleanup; - } - - if (cwd_obj != Py_None) { - if (PyUnicode_FSConverter(cwd_obj, &cwd_obj2) == 0) - goto cleanup; - cwd = PyBytes_AsString(cwd_obj2); - } else { - cwd = NULL; - } - + if (result == NULL) { + Py_DECREF(gc_module); + return NULL; + } + Py_DECREF(result); + } + + exec_array = _PySequence_BytesToCharpArray(executable_list); + if (!exec_array) + goto cleanup; + + /* Convert args and env into appropriate arguments for exec() */ + /* These conversions are done in the parent process to avoid allocating + or freeing memory in the child process. */ + if (process_args != Py_None) { + Py_ssize_t num_args; + /* Equivalent to: */ + /* tuple(PyUnicode_FSConverter(arg) for arg in process_args) */ + fast_args = PySequence_Fast(process_args, "argv must be a tuple"); + if (fast_args == NULL) + goto cleanup; + num_args = PySequence_Fast_GET_SIZE(fast_args); + converted_args = PyTuple_New(num_args); + if (converted_args == NULL) + goto cleanup; + for (arg_num = 0; arg_num < num_args; ++arg_num) { + PyObject *borrowed_arg, *converted_arg; + if (PySequence_Fast_GET_SIZE(fast_args) != num_args) { + PyErr_SetString(PyExc_RuntimeError, "args changed during iteration"); + goto cleanup; + } + borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num); + if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0) + goto cleanup; + PyTuple_SET_ITEM(converted_args, arg_num, converted_arg); + } + + argv = _PySequence_BytesToCharpArray(converted_args); + Py_CLEAR(converted_args); + Py_CLEAR(fast_args); + if (!argv) + goto cleanup; + } + + if (env_list != Py_None) { + envp = _PySequence_BytesToCharpArray(env_list); + if (!envp) + goto cleanup; + } + + if (cwd_obj != Py_None) { + if (PyUnicode_FSConverter(cwd_obj, &cwd_obj2) == 0) + goto cleanup; + cwd = PyBytes_AsString(cwd_obj2); + } else { + cwd = NULL; + } + if (groups_list != Py_None) { #ifdef HAVE_SETGROUPS Py_ssize_t i; @@ -830,137 +830,137 @@ subprocess_fork_exec(PyObject* self, PyObject *args) #endif /* HAVE_SETREUID */ } - /* This must be the last thing done before fork() because we do not - * want to call PyOS_BeforeFork() if there is any chance of another - * error leading to the cleanup: code without calling fork(). */ - if (preexec_fn != Py_None) { - preexec_fn_args_tuple = PyTuple_New(0); - if (!preexec_fn_args_tuple) - goto cleanup; - PyOS_BeforeFork(); - need_after_fork = 1; - } - - pid = fork(); - if (pid == 0) { - /* Child process */ - /* - * Code from here to _exit() must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - */ - - if (preexec_fn != Py_None) { - /* We'll be calling back into Python later so we need to do this. - * This call may not be async-signal-safe but neither is calling - * back into Python. The user asked us to use hope as a strategy - * to avoid deadlock... */ - PyOS_AfterFork_Child(); - } - - child_exec(exec_array, argv, envp, cwd, - p2cread, p2cwrite, c2pread, c2pwrite, - errread, errwrite, errpipe_read, errpipe_write, - close_fds, restore_signals, call_setsid, + /* This must be the last thing done before fork() because we do not + * want to call PyOS_BeforeFork() if there is any chance of another + * error leading to the cleanup: code without calling fork(). */ + if (preexec_fn != Py_None) { + preexec_fn_args_tuple = PyTuple_New(0); + if (!preexec_fn_args_tuple) + goto cleanup; + PyOS_BeforeFork(); + need_after_fork = 1; + } + + pid = fork(); + if (pid == 0) { + /* Child process */ + /* + * Code from here to _exit() must only use async-signal-safe functions, + * listed at `man 7 signal` or + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. + */ + + if (preexec_fn != Py_None) { + /* We'll be calling back into Python later so we need to do this. + * This call may not be async-signal-safe but neither is calling + * back into Python. The user asked us to use hope as a strategy + * to avoid deadlock... */ + PyOS_AfterFork_Child(); + } + + child_exec(exec_array, argv, envp, cwd, + p2cread, p2cwrite, c2pread, c2pwrite, + errread, errwrite, errpipe_read, errpipe_write, + close_fds, restore_signals, call_setsid, call_setgid, gid, call_setgroups, num_groups, groups, call_setuid, uid, child_umask, - py_fds_to_keep, preexec_fn, preexec_fn_args_tuple); - _exit(255); - return NULL; /* Dead code to avoid a potential compiler warning. */ - } - /* Parent (original) process */ - if (pid == -1) { - /* Capture errno for the exception. */ - saved_errno = errno; - } - - Py_XDECREF(cwd_obj2); - - if (need_after_fork) - PyOS_AfterFork_Parent(); - if (envp) - _Py_FreeCharPArray(envp); - if (argv) - _Py_FreeCharPArray(argv); - _Py_FreeCharPArray(exec_array); - - /* Reenable gc in the parent process (or if fork failed). */ - if (_enable_gc(need_to_reenable_gc, gc_module)) { - pid = -1; - } + py_fds_to_keep, preexec_fn, preexec_fn_args_tuple); + _exit(255); + return NULL; /* Dead code to avoid a potential compiler warning. */ + } + /* Parent (original) process */ + if (pid == -1) { + /* Capture errno for the exception. */ + saved_errno = errno; + } + + Py_XDECREF(cwd_obj2); + + if (need_after_fork) + PyOS_AfterFork_Parent(); + if (envp) + _Py_FreeCharPArray(envp); + if (argv) + _Py_FreeCharPArray(argv); + _Py_FreeCharPArray(exec_array); + + /* Reenable gc in the parent process (or if fork failed). */ + if (_enable_gc(need_to_reenable_gc, gc_module)) { + pid = -1; + } PyMem_RawFree(groups); - Py_XDECREF(preexec_fn_args_tuple); - Py_XDECREF(gc_module); - - if (pid == -1) { - errno = saved_errno; - /* We can't call this above as PyOS_AfterFork_Parent() calls back - * into Python code which would see the unreturned error. */ - PyErr_SetFromErrno(PyExc_OSError); - return NULL; /* fork() failed. */ - } - - return PyLong_FromPid(pid); - -cleanup: + Py_XDECREF(preexec_fn_args_tuple); + Py_XDECREF(gc_module); + + if (pid == -1) { + errno = saved_errno; + /* We can't call this above as PyOS_AfterFork_Parent() calls back + * into Python code which would see the unreturned error. */ + PyErr_SetFromErrno(PyExc_OSError); + return NULL; /* fork() failed. */ + } + + return PyLong_FromPid(pid); + +cleanup: Py_XDECREF(cwd_obj2); - if (envp) - _Py_FreeCharPArray(envp); - if (argv) - _Py_FreeCharPArray(argv); - if (exec_array) - _Py_FreeCharPArray(exec_array); + if (envp) + _Py_FreeCharPArray(envp); + if (argv) + _Py_FreeCharPArray(argv); + if (exec_array) + _Py_FreeCharPArray(exec_array); PyMem_RawFree(groups); - Py_XDECREF(converted_args); - Py_XDECREF(fast_args); - Py_XDECREF(preexec_fn_args_tuple); - _enable_gc(need_to_reenable_gc, gc_module); - Py_XDECREF(gc_module); - return NULL; -} - - -PyDoc_STRVAR(subprocess_fork_exec_doc, + Py_XDECREF(converted_args); + Py_XDECREF(fast_args); + Py_XDECREF(preexec_fn_args_tuple); + _enable_gc(need_to_reenable_gc, gc_module); + Py_XDECREF(gc_module); + return NULL; +} + + +PyDoc_STRVAR(subprocess_fork_exec_doc, "fork_exec(args, executable_list, close_fds, pass_fds, cwd, env,\n\ - p2cread, p2cwrite, c2pread, c2pwrite,\n\ - errread, errwrite, errpipe_read, errpipe_write,\n\ + p2cread, p2cwrite, c2pread, c2pwrite,\n\ + errread, errwrite, errpipe_read, errpipe_write,\n\ restore_signals, call_setsid,\n\ gid, groups_list, uid,\n\ preexec_fn)\n\ -\n\ -Forks a child process, closes parent file descriptors as appropriate in the\n\ -child and dups the few that are needed before calling exec() in the child\n\ -process.\n\ -\n\ +\n\ +Forks a child process, closes parent file descriptors as appropriate in the\n\ +child and dups the few that are needed before calling exec() in the child\n\ +process.\n\ +\n\ If close_fds is true, close file descriptors 3 and higher, except those listed\n\ in the sorted tuple pass_fds.\n\ \n\ The preexec_fn, if supplied, will be called immediately before closing file\n\ descriptors and exec.\n\ -WARNING: preexec_fn is NOT SAFE if your application uses threads.\n\ - It may trigger infrequent, difficult to debug deadlocks.\n\ -\n\ -If an error occurs in the child process before the exec, it is\n\ -serialized and written to the errpipe_write fd per subprocess.py.\n\ -\n\ -Returns: the child process's PID.\n\ -\n\ -Raises: Only on an error in the parent process.\n\ -"); - -/* module level code ********************************************************/ - -PyDoc_STRVAR(module_doc, -"A POSIX helper for the subprocess module."); - - -static PyMethodDef module_methods[] = { - {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc}, - {NULL, NULL} /* sentinel */ -}; - - +WARNING: preexec_fn is NOT SAFE if your application uses threads.\n\ + It may trigger infrequent, difficult to debug deadlocks.\n\ +\n\ +If an error occurs in the child process before the exec, it is\n\ +serialized and written to the errpipe_write fd per subprocess.py.\n\ +\n\ +Returns: the child process's PID.\n\ +\n\ +Raises: Only on an error in the parent process.\n\ +"); + +/* module level code ********************************************************/ + +PyDoc_STRVAR(module_doc, +"A POSIX helper for the subprocess module."); + + +static PyMethodDef module_methods[] = { + {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc}, + {NULL, NULL} /* sentinel */ +}; + + static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(get_posixsubprocess_state(m)->disable); Py_VISIT(get_posixsubprocess_state(m)->enable); @@ -979,21 +979,21 @@ static void _posixsubprocess_free(void *m) { _posixsubprocess_clear((PyObject *)m); } -static struct PyModuleDef _posixsubprocessmodule = { - PyModuleDef_HEAD_INIT, - "_posixsubprocess", - module_doc, +static struct PyModuleDef _posixsubprocessmodule = { + PyModuleDef_HEAD_INIT, + "_posixsubprocess", + module_doc, sizeof(_posixsubprocessstate), - module_methods, + module_methods, NULL, _posixsubprocess_traverse, _posixsubprocess_clear, _posixsubprocess_free, -}; - -PyMODINIT_FUNC -PyInit__posixsubprocess(void) -{ +}; + +PyMODINIT_FUNC +PyInit__posixsubprocess(void) +{ PyObject* m; m = PyState_FindModule(&_posixsubprocessmodule); @@ -1013,4 +1013,4 @@ PyInit__posixsubprocess(void) PyState_AddModule(m, &_posixsubprocessmodule); return m; -} +} diff --git a/contrib/tools/python3/src/Modules/_queuemodule.c b/contrib/tools/python3/src/Modules/_queuemodule.c index b155ea94239..c1648b9d543 100644 --- a/contrib/tools/python3/src/Modules/_queuemodule.c +++ b/contrib/tools/python3/src/Modules/_queuemodule.c @@ -1,399 +1,399 @@ -#include "Python.h" +#include "Python.h" #include // offsetof() - -/*[clinic input] -module _queue -class _queue.SimpleQueue "simplequeueobject *" "&PySimpleQueueType" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cf49af81bcbbbea6]*/ - -static PyTypeObject PySimpleQueueType; /* forward decl */ - -static PyObject *EmptyError; - - -typedef struct { - PyObject_HEAD - PyThread_type_lock lock; - int locked; - PyObject *lst; - Py_ssize_t lst_pos; - PyObject *weakreflist; -} simplequeueobject; - - -static void -simplequeue_dealloc(simplequeueobject *self) -{ + +/*[clinic input] +module _queue +class _queue.SimpleQueue "simplequeueobject *" "&PySimpleQueueType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cf49af81bcbbbea6]*/ + +static PyTypeObject PySimpleQueueType; /* forward decl */ + +static PyObject *EmptyError; + + +typedef struct { + PyObject_HEAD + PyThread_type_lock lock; + int locked; + PyObject *lst; + Py_ssize_t lst_pos; + PyObject *weakreflist; +} simplequeueobject; + + +static void +simplequeue_dealloc(simplequeueobject *self) +{ PyObject_GC_UnTrack(self); - if (self->lock != NULL) { - /* Unlock the lock so it's safe to free it */ - if (self->locked > 0) - PyThread_release_lock(self->lock); - PyThread_free_lock(self->lock); - } - Py_XDECREF(self->lst); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free(self); -} - -static int -simplequeue_traverse(simplequeueobject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->lst); - return 0; -} - -/*[clinic input] -@classmethod -_queue.SimpleQueue.__new__ as simplequeue_new - -Simple, unbounded, reentrant FIFO queue. -[clinic start generated code]*/ - -static PyObject * -simplequeue_new_impl(PyTypeObject *type) -/*[clinic end generated code: output=ba97740608ba31cd input=a0674a1643e3e2fb]*/ -{ - simplequeueobject *self; - - self = (simplequeueobject *) type->tp_alloc(type, 0); - if (self != NULL) { - self->weakreflist = NULL; - self->lst = PyList_New(0); - self->lock = PyThread_allocate_lock(); - self->lst_pos = 0; - if (self->lock == NULL) { - Py_DECREF(self); - PyErr_SetString(PyExc_MemoryError, "can't allocate lock"); - return NULL; - } - if (self->lst == NULL) { - Py_DECREF(self); - return NULL; - } - } - - return (PyObject *) self; -} - -/*[clinic input] -_queue.SimpleQueue.put - item: object - block: bool = True - timeout: object = None - -Put the item on the queue. - -The optional 'block' and 'timeout' arguments are ignored, as this method -never blocks. They are provided for compatibility with the Queue class. - -[clinic start generated code]*/ - -static PyObject * -_queue_SimpleQueue_put_impl(simplequeueobject *self, PyObject *item, - int block, PyObject *timeout) -/*[clinic end generated code: output=4333136e88f90d8b input=6e601fa707a782d5]*/ -{ - /* BEGIN GIL-protected critical section */ - if (PyList_Append(self->lst, item) < 0) - return NULL; - if (self->locked) { - /* A get() may be waiting, wake it up */ - self->locked = 0; - PyThread_release_lock(self->lock); - } - /* END GIL-protected critical section */ - Py_RETURN_NONE; -} - -/*[clinic input] -_queue.SimpleQueue.put_nowait - item: object - -Put an item into the queue without blocking. - -This is exactly equivalent to `put(item)` and is only provided -for compatibility with the Queue class. - -[clinic start generated code]*/ - -static PyObject * -_queue_SimpleQueue_put_nowait_impl(simplequeueobject *self, PyObject *item) -/*[clinic end generated code: output=0990536715efb1f1 input=36b1ea96756b2ece]*/ -{ - return _queue_SimpleQueue_put_impl(self, item, 0, Py_None); -} - -static PyObject * -simplequeue_pop_item(simplequeueobject *self) -{ - Py_ssize_t count, n; - PyObject *item; - - n = PyList_GET_SIZE(self->lst); - assert(self->lst_pos < n); - - item = PyList_GET_ITEM(self->lst, self->lst_pos); - Py_INCREF(Py_None); - PyList_SET_ITEM(self->lst, self->lst_pos, Py_None); - self->lst_pos += 1; - count = n - self->lst_pos; - if (self->lst_pos > count) { - /* The list is more than 50% empty, reclaim space at the beginning */ - if (PyList_SetSlice(self->lst, 0, self->lst_pos, NULL)) { - /* Undo pop */ - self->lst_pos -= 1; - PyList_SET_ITEM(self->lst, self->lst_pos, item); - return NULL; - } - self->lst_pos = 0; - } - return item; -} - -/*[clinic input] -_queue.SimpleQueue.get - block: bool = True - timeout: object = None - -Remove and return an item from the queue. - -If optional args 'block' is true and 'timeout' is None (the default), -block if necessary until an item is available. If 'timeout' is -a non-negative number, it blocks at most 'timeout' seconds and raises -the Empty exception if no item was available within that time. -Otherwise ('block' is false), return an item if one is immediately -available, else raise the Empty exception ('timeout' is ignored -in that case). - -[clinic start generated code]*/ - -static PyObject * -_queue_SimpleQueue_get_impl(simplequeueobject *self, int block, - PyObject *timeout) -/*[clinic end generated code: output=ec82a7157dcccd1a input=4bf691f9f01fa297]*/ -{ - _PyTime_t endtime = 0; - _PyTime_t timeout_val; - PyObject *item; - PyLockStatus r; - PY_TIMEOUT_T microseconds; - - if (block == 0) { - /* Non-blocking */ - microseconds = 0; - } - else if (timeout != Py_None) { - /* With timeout */ - if (_PyTime_FromSecondsObject(&timeout_val, - timeout, _PyTime_ROUND_CEILING) < 0) - return NULL; - if (timeout_val < 0) { - PyErr_SetString(PyExc_ValueError, - "'timeout' must be a non-negative number"); - return NULL; - } - microseconds = _PyTime_AsMicroseconds(timeout_val, - _PyTime_ROUND_CEILING); - if (microseconds >= PY_TIMEOUT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "timeout value is too large"); - return NULL; - } - endtime = _PyTime_GetMonotonicClock() + timeout_val; - } - else { - /* Infinitely blocking */ - microseconds = -1; - } - - /* put() signals the queue to be non-empty by releasing the lock. - * So we simply try to acquire the lock in a loop, until the condition - * (queue non-empty) becomes true. - */ - while (self->lst_pos == PyList_GET_SIZE(self->lst)) { - /* First a simple non-blocking try without releasing the GIL */ - r = PyThread_acquire_lock_timed(self->lock, 0, 0); - if (r == PY_LOCK_FAILURE && microseconds != 0) { - Py_BEGIN_ALLOW_THREADS - r = PyThread_acquire_lock_timed(self->lock, microseconds, 1); - Py_END_ALLOW_THREADS - } - if (r == PY_LOCK_INTR && Py_MakePendingCalls() < 0) { - return NULL; - } - if (r == PY_LOCK_FAILURE) { - /* Timed out */ - PyErr_SetNone(EmptyError); - return NULL; - } - self->locked = 1; - /* Adjust timeout for next iteration (if any) */ - if (endtime > 0) { - timeout_val = endtime - _PyTime_GetMonotonicClock(); - microseconds = _PyTime_AsMicroseconds(timeout_val, _PyTime_ROUND_CEILING); - } - } - /* BEGIN GIL-protected critical section */ - assert(self->lst_pos < PyList_GET_SIZE(self->lst)); - item = simplequeue_pop_item(self); - if (self->locked) { - PyThread_release_lock(self->lock); - self->locked = 0; - } - /* END GIL-protected critical section */ - - return item; -} - -/*[clinic input] -_queue.SimpleQueue.get_nowait - -Remove and return an item from the queue without blocking. - -Only get an item if one is immediately available. Otherwise -raise the Empty exception. -[clinic start generated code]*/ - -static PyObject * -_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self) -/*[clinic end generated code: output=a89731a75dbe4937 input=6fe5102db540a1b9]*/ -{ - return _queue_SimpleQueue_get_impl(self, 0, Py_None); -} - -/*[clinic input] -_queue.SimpleQueue.empty -> bool - -Return True if the queue is empty, False otherwise (not reliable!). -[clinic start generated code]*/ - -static int -_queue_SimpleQueue_empty_impl(simplequeueobject *self) -/*[clinic end generated code: output=1a02a1b87c0ef838 input=1a98431c45fd66f9]*/ -{ - return self->lst_pos == PyList_GET_SIZE(self->lst); -} - -/*[clinic input] -_queue.SimpleQueue.qsize -> Py_ssize_t - -Return the approximate size of the queue (not reliable!). -[clinic start generated code]*/ - -static Py_ssize_t -_queue_SimpleQueue_qsize_impl(simplequeueobject *self) -/*[clinic end generated code: output=f9dcd9d0a90e121e input=7a74852b407868a1]*/ -{ - return PyList_GET_SIZE(self->lst) - self->lst_pos; -} - - -#include "clinic/_queuemodule.c.h" - - -static PyMethodDef simplequeue_methods[] = { - _QUEUE_SIMPLEQUEUE_EMPTY_METHODDEF - _QUEUE_SIMPLEQUEUE_GET_METHODDEF - _QUEUE_SIMPLEQUEUE_GET_NOWAIT_METHODDEF - _QUEUE_SIMPLEQUEUE_PUT_METHODDEF - _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF - _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF + if (self->lock != NULL) { + /* Unlock the lock so it's safe to free it */ + if (self->locked > 0) + PyThread_release_lock(self->lock); + PyThread_free_lock(self->lock); + } + Py_XDECREF(self->lst); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_TYPE(self)->tp_free(self); +} + +static int +simplequeue_traverse(simplequeueobject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->lst); + return 0; +} + +/*[clinic input] +@classmethod +_queue.SimpleQueue.__new__ as simplequeue_new + +Simple, unbounded, reentrant FIFO queue. +[clinic start generated code]*/ + +static PyObject * +simplequeue_new_impl(PyTypeObject *type) +/*[clinic end generated code: output=ba97740608ba31cd input=a0674a1643e3e2fb]*/ +{ + simplequeueobject *self; + + self = (simplequeueobject *) type->tp_alloc(type, 0); + if (self != NULL) { + self->weakreflist = NULL; + self->lst = PyList_New(0); + self->lock = PyThread_allocate_lock(); + self->lst_pos = 0; + if (self->lock == NULL) { + Py_DECREF(self); + PyErr_SetString(PyExc_MemoryError, "can't allocate lock"); + return NULL; + } + if (self->lst == NULL) { + Py_DECREF(self); + return NULL; + } + } + + return (PyObject *) self; +} + +/*[clinic input] +_queue.SimpleQueue.put + item: object + block: bool = True + timeout: object = None + +Put the item on the queue. + +The optional 'block' and 'timeout' arguments are ignored, as this method +never blocks. They are provided for compatibility with the Queue class. + +[clinic start generated code]*/ + +static PyObject * +_queue_SimpleQueue_put_impl(simplequeueobject *self, PyObject *item, + int block, PyObject *timeout) +/*[clinic end generated code: output=4333136e88f90d8b input=6e601fa707a782d5]*/ +{ + /* BEGIN GIL-protected critical section */ + if (PyList_Append(self->lst, item) < 0) + return NULL; + if (self->locked) { + /* A get() may be waiting, wake it up */ + self->locked = 0; + PyThread_release_lock(self->lock); + } + /* END GIL-protected critical section */ + Py_RETURN_NONE; +} + +/*[clinic input] +_queue.SimpleQueue.put_nowait + item: object + +Put an item into the queue without blocking. + +This is exactly equivalent to `put(item)` and is only provided +for compatibility with the Queue class. + +[clinic start generated code]*/ + +static PyObject * +_queue_SimpleQueue_put_nowait_impl(simplequeueobject *self, PyObject *item) +/*[clinic end generated code: output=0990536715efb1f1 input=36b1ea96756b2ece]*/ +{ + return _queue_SimpleQueue_put_impl(self, item, 0, Py_None); +} + +static PyObject * +simplequeue_pop_item(simplequeueobject *self) +{ + Py_ssize_t count, n; + PyObject *item; + + n = PyList_GET_SIZE(self->lst); + assert(self->lst_pos < n); + + item = PyList_GET_ITEM(self->lst, self->lst_pos); + Py_INCREF(Py_None); + PyList_SET_ITEM(self->lst, self->lst_pos, Py_None); + self->lst_pos += 1; + count = n - self->lst_pos; + if (self->lst_pos > count) { + /* The list is more than 50% empty, reclaim space at the beginning */ + if (PyList_SetSlice(self->lst, 0, self->lst_pos, NULL)) { + /* Undo pop */ + self->lst_pos -= 1; + PyList_SET_ITEM(self->lst, self->lst_pos, item); + return NULL; + } + self->lst_pos = 0; + } + return item; +} + +/*[clinic input] +_queue.SimpleQueue.get + block: bool = True + timeout: object = None + +Remove and return an item from the queue. + +If optional args 'block' is true and 'timeout' is None (the default), +block if necessary until an item is available. If 'timeout' is +a non-negative number, it blocks at most 'timeout' seconds and raises +the Empty exception if no item was available within that time. +Otherwise ('block' is false), return an item if one is immediately +available, else raise the Empty exception ('timeout' is ignored +in that case). + +[clinic start generated code]*/ + +static PyObject * +_queue_SimpleQueue_get_impl(simplequeueobject *self, int block, + PyObject *timeout) +/*[clinic end generated code: output=ec82a7157dcccd1a input=4bf691f9f01fa297]*/ +{ + _PyTime_t endtime = 0; + _PyTime_t timeout_val; + PyObject *item; + PyLockStatus r; + PY_TIMEOUT_T microseconds; + + if (block == 0) { + /* Non-blocking */ + microseconds = 0; + } + else if (timeout != Py_None) { + /* With timeout */ + if (_PyTime_FromSecondsObject(&timeout_val, + timeout, _PyTime_ROUND_CEILING) < 0) + return NULL; + if (timeout_val < 0) { + PyErr_SetString(PyExc_ValueError, + "'timeout' must be a non-negative number"); + return NULL; + } + microseconds = _PyTime_AsMicroseconds(timeout_val, + _PyTime_ROUND_CEILING); + if (microseconds >= PY_TIMEOUT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "timeout value is too large"); + return NULL; + } + endtime = _PyTime_GetMonotonicClock() + timeout_val; + } + else { + /* Infinitely blocking */ + microseconds = -1; + } + + /* put() signals the queue to be non-empty by releasing the lock. + * So we simply try to acquire the lock in a loop, until the condition + * (queue non-empty) becomes true. + */ + while (self->lst_pos == PyList_GET_SIZE(self->lst)) { + /* First a simple non-blocking try without releasing the GIL */ + r = PyThread_acquire_lock_timed(self->lock, 0, 0); + if (r == PY_LOCK_FAILURE && microseconds != 0) { + Py_BEGIN_ALLOW_THREADS + r = PyThread_acquire_lock_timed(self->lock, microseconds, 1); + Py_END_ALLOW_THREADS + } + if (r == PY_LOCK_INTR && Py_MakePendingCalls() < 0) { + return NULL; + } + if (r == PY_LOCK_FAILURE) { + /* Timed out */ + PyErr_SetNone(EmptyError); + return NULL; + } + self->locked = 1; + /* Adjust timeout for next iteration (if any) */ + if (endtime > 0) { + timeout_val = endtime - _PyTime_GetMonotonicClock(); + microseconds = _PyTime_AsMicroseconds(timeout_val, _PyTime_ROUND_CEILING); + } + } + /* BEGIN GIL-protected critical section */ + assert(self->lst_pos < PyList_GET_SIZE(self->lst)); + item = simplequeue_pop_item(self); + if (self->locked) { + PyThread_release_lock(self->lock); + self->locked = 0; + } + /* END GIL-protected critical section */ + + return item; +} + +/*[clinic input] +_queue.SimpleQueue.get_nowait + +Remove and return an item from the queue without blocking. + +Only get an item if one is immediately available. Otherwise +raise the Empty exception. +[clinic start generated code]*/ + +static PyObject * +_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self) +/*[clinic end generated code: output=a89731a75dbe4937 input=6fe5102db540a1b9]*/ +{ + return _queue_SimpleQueue_get_impl(self, 0, Py_None); +} + +/*[clinic input] +_queue.SimpleQueue.empty -> bool + +Return True if the queue is empty, False otherwise (not reliable!). +[clinic start generated code]*/ + +static int +_queue_SimpleQueue_empty_impl(simplequeueobject *self) +/*[clinic end generated code: output=1a02a1b87c0ef838 input=1a98431c45fd66f9]*/ +{ + return self->lst_pos == PyList_GET_SIZE(self->lst); +} + +/*[clinic input] +_queue.SimpleQueue.qsize -> Py_ssize_t + +Return the approximate size of the queue (not reliable!). +[clinic start generated code]*/ + +static Py_ssize_t +_queue_SimpleQueue_qsize_impl(simplequeueobject *self) +/*[clinic end generated code: output=f9dcd9d0a90e121e input=7a74852b407868a1]*/ +{ + return PyList_GET_SIZE(self->lst) - self->lst_pos; +} + + +#include "clinic/_queuemodule.c.h" + + +static PyMethodDef simplequeue_methods[] = { + _QUEUE_SIMPLEQUEUE_EMPTY_METHODDEF + _QUEUE_SIMPLEQUEUE_GET_METHODDEF + _QUEUE_SIMPLEQUEUE_GET_NOWAIT_METHODDEF + _QUEUE_SIMPLEQUEUE_PUT_METHODDEF + _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF + _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL, NULL} /* sentinel */ -}; - - -static PyTypeObject PySimpleQueueType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_queue.SimpleQueue", /*tp_name*/ - sizeof(simplequeueobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)simplequeue_dealloc, /*tp_dealloc*/ + {NULL, NULL} /* sentinel */ +}; + + +static PyTypeObject PySimpleQueueType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_queue.SimpleQueue", /*tp_name*/ + sizeof(simplequeueobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)simplequeue_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - simplequeue_new__doc__, /*tp_doc*/ - (traverseproc)simplequeue_traverse, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(simplequeueobject, weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - simplequeue_methods, /*tp_methods*/ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - simplequeue_new /* tp_new */ -}; - - -/* Initialization function */ - -PyDoc_STRVAR(queue_module_doc, -"C implementation of the Python queue module.\n\ -This module is an implementation detail, please do not use it directly."); - -static struct PyModuleDef queuemodule = { - PyModuleDef_HEAD_INIT, - "_queue", - queue_module_doc, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit__queue(void) -{ - PyObject *m; - - /* Create the module */ - m = PyModule_Create(&queuemodule); - if (m == NULL) - return NULL; - - EmptyError = PyErr_NewExceptionWithDoc( - "_queue.Empty", - "Exception raised by Queue.get(block=0)/get_nowait().", - NULL, NULL); - if (EmptyError == NULL) - return NULL; - - Py_INCREF(EmptyError); - if (PyModule_AddObject(m, "Empty", EmptyError) < 0) - return NULL; - + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + simplequeue_new__doc__, /*tp_doc*/ + (traverseproc)simplequeue_traverse, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + offsetof(simplequeueobject, weakreflist), /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + simplequeue_methods, /*tp_methods*/ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + simplequeue_new /* tp_new */ +}; + + +/* Initialization function */ + +PyDoc_STRVAR(queue_module_doc, +"C implementation of the Python queue module.\n\ +This module is an implementation detail, please do not use it directly."); + +static struct PyModuleDef queuemodule = { + PyModuleDef_HEAD_INIT, + "_queue", + queue_module_doc, + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__queue(void) +{ + PyObject *m; + + /* Create the module */ + m = PyModule_Create(&queuemodule); + if (m == NULL) + return NULL; + + EmptyError = PyErr_NewExceptionWithDoc( + "_queue.Empty", + "Exception raised by Queue.get(block=0)/get_nowait().", + NULL, NULL); + if (EmptyError == NULL) + return NULL; + + Py_INCREF(EmptyError); + if (PyModule_AddObject(m, "Empty", EmptyError) < 0) + return NULL; + if (PyModule_AddType(m, &PySimpleQueueType) < 0) { - return NULL; + return NULL; } - - return m; -} + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_randommodule.c b/contrib/tools/python3/src/Modules/_randommodule.c index a402b937f70..b5230a97010 100644 --- a/contrib/tools/python3/src/Modules/_randommodule.c +++ b/contrib/tools/python3/src/Modules/_randommodule.c @@ -1,85 +1,85 @@ -/* Random objects */ - -/* ------------------------------------------------------------------ - The code in this module was based on a download from: - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html - - It was modified in 2002 by Raymond Hettinger as follows: - - * the principal computational lines untouched. - - * renamed genrand_res53() to random_random() and wrapped - in python calling/return code. - +/* Random objects */ + +/* ------------------------------------------------------------------ + The code in this module was based on a download from: + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html + + It was modified in 2002 by Raymond Hettinger as follows: + + * the principal computational lines untouched. + + * renamed genrand_res53() to random_random() and wrapped + in python calling/return code. + * genrand_uint32() and the helper functions, init_genrand() - and init_by_array(), were declared static, wrapped in - Python calling/return code. also, their global data - references were replaced with structure references. - - * unused functions from the original were deleted. - new, original C python code was added to implement the - Random() interface. - - The following are the verbatim comments from the original code: - - A C-program for MT19937, with initialization improved 2002/1/26. - Coded by Takuji Nishimura and Makoto Matsumoto. - - Before using, initialize the state by using init_genrand(seed) - or init_by_array(init_key, key_length). - - Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - Any feedback is very welcome. - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) -*/ - -/* ---------------------------------------------------------------*/ - -#include "Python.h" + and init_by_array(), were declared static, wrapped in + Python calling/return code. also, their global data + references were replaced with structure references. + + * unused functions from the original were deleted. + new, original C python code was added to implement the + Random() interface. + + The following are the verbatim comments from the original code: + + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +/* ---------------------------------------------------------------*/ + +#include "Python.h" #include "pycore_byteswap.h" // _Py_bswap32() -#ifdef HAVE_PROCESS_H +#ifdef HAVE_PROCESS_H # include // getpid() -#endif - -/* Period parameters -- These are all magic. Don't change. */ -#define N 624 -#define M 397 -#define MATRIX_A 0x9908b0dfU /* constant vector a */ -#define UPPER_MASK 0x80000000U /* most significant w-r bits */ -#define LOWER_MASK 0x7fffffffU /* least significant r bits */ - -typedef struct { +#endif + +/* Period parameters -- These are all magic. Don't change. */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfU /* constant vector a */ +#define UPPER_MASK 0x80000000U /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffU /* least significant r bits */ + +typedef struct { PyObject *Random_Type; PyObject *Long___abs__; } _randomstate; @@ -97,67 +97,67 @@ static struct PyModuleDef _randommodule; #define _randomstate_global get_random_state(PyState_FindModule(&_randommodule)) typedef struct { - PyObject_HEAD - int index; - uint32_t state[N]; -} RandomObject; - - + PyObject_HEAD + int index; + uint32_t state[N]; +} RandomObject; + + #include "clinic/_randommodule.c.h" - + /*[clinic input] module _random class _random.Random "RandomObject *" "&Random_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=f79898ae7847c321]*/ -/* Random methods */ - - -/* generates a random number on [0,0xffffffff]-interval */ -static uint32_t +/* Random methods */ + + +/* generates a random number on [0,0xffffffff]-interval */ +static uint32_t genrand_uint32(RandomObject *self) -{ - uint32_t y; - static const uint32_t mag01[2] = {0x0U, MATRIX_A}; - /* mag01[x] = x * MATRIX_A for x=0,1 */ - uint32_t *mt; - - mt = self->state; - if (self->index >= N) { /* generate N words at one time */ - int kk; - - for (kk=0;kk> 1) ^ mag01[y & 0x1U]; - } - for (;kk> 1) ^ mag01[y & 0x1U]; - } - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1U]; - - self->index = 0; - } - - y = mt[self->index++]; - y ^= (y >> 11); - y ^= (y << 7) & 0x9d2c5680U; - y ^= (y << 15) & 0xefc60000U; - y ^= (y >> 18); - return y; -} - -/* random_random is the function named genrand_res53 in the original code; - * generates a random number on [0,1) with 53-bit resolution; note that - * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as - * multiply-by-reciprocal in the (likely vain) hope that the compiler will - * optimize the division away at compile-time. 67108864 is 2**26. In - * effect, a contains 27 random bits shifted left 26, and b fills in the - * lower 26 bits of the 53-bit numerator. - * The original code credited Isaku Wada for this algorithm, 2002/01/09. - */ +{ + uint32_t y; + static const uint32_t mag01[2] = {0x0U, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + uint32_t *mt; + + mt = self->state; + if (self->index >= N) { /* generate N words at one time */ + int kk; + + for (kk=0;kk> 1) ^ mag01[y & 0x1U]; + } + for (;kk> 1) ^ mag01[y & 0x1U]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1U]; + + self->index = 0; + } + + y = mt[self->index++]; + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680U; + y ^= (y << 15) & 0xefc60000U; + y ^= (y >> 18); + return y; +} + +/* random_random is the function named genrand_res53 in the original code; + * generates a random number on [0,1) with 53-bit resolution; note that + * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as + * multiply-by-reciprocal in the (likely vain) hope that the compiler will + * optimize the division away at compile-time. 67108864 is 2**26. In + * effect, a contains 27 random bits shifted left 26, and b fills in the + * lower 26 bits of the 53-bit numerator. + * The original code credited Isaku Wada for this algorithm, 2002/01/09. + */ /*[clinic input] _random.Random.random @@ -167,185 +167,185 @@ _random.Random.random random() -> x in the interval [0, 1). [clinic start generated code]*/ -static PyObject * +static PyObject * _random_Random_random_impl(RandomObject *self) /*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/ -{ +{ uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6; - return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); -} - -/* initializes mt[N] with a seed */ -static void -init_genrand(RandomObject *self, uint32_t s) -{ - int mti; - uint32_t *mt; - - mt = self->state; - mt[0]= s; - for (mti=1; mti> 30)) + mti); - /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ - /* In the previous versions, MSBs of the seed affect */ - /* only MSBs of the array mt[]. */ - /* 2002/01/09 modified by Makoto Matsumoto */ - } - self->index = mti; - return; -} - -/* initialize by an array with array-length */ -/* init_key is the array for initializing keys */ -/* key_length is its length */ -static void -init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) -{ - size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ - uint32_t *mt; - - mt = self->state; - init_genrand(self, 19650218U); - i=1; j=0; - k = (N>key_length ? N : key_length); - for (; k; k--) { - mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U)) - + init_key[j] + (uint32_t)j; /* non linear */ - i++; j++; - if (i>=N) { mt[0] = mt[N-1]; i=1; } - if (j>=key_length) j=0; - } - for (k=N-1; k; k--) { - mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U)) - - (uint32_t)i; /* non linear */ - i++; - if (i>=N) { mt[0] = mt[N-1]; i=1; } - } - - mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ -} - -/* - * The rest is Python-specific code, neither part of, nor derived from, the - * Twister download. - */ - -static int -random_seed_urandom(RandomObject *self) -{ + return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); +} + +/* initializes mt[N] with a seed */ +static void +init_genrand(RandomObject *self, uint32_t s) +{ + int mti; + uint32_t *mt; + + mt = self->state; + mt[0]= s; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + } + self->index = mti; + return; +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +static void +init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) +{ + size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ + uint32_t *mt; + + mt = self->state; + init_genrand(self, 19650218U); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U)) + + init_key[j] + (uint32_t)j; /* non linear */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U)) + - (uint32_t)i; /* non linear */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ +} + +/* + * The rest is Python-specific code, neither part of, nor derived from, the + * Twister download. + */ + +static int +random_seed_urandom(RandomObject *self) +{ uint32_t key[N]; - - if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) { - return -1; - } - init_by_array(self, key, Py_ARRAY_LENGTH(key)); - return 0; -} - -static void -random_seed_time_pid(RandomObject *self) -{ - _PyTime_t now; - uint32_t key[5]; - - now = _PyTime_GetSystemClock(); + + if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) { + return -1; + } + init_by_array(self, key, Py_ARRAY_LENGTH(key)); + return 0; +} + +static void +random_seed_time_pid(RandomObject *self) +{ + _PyTime_t now; + uint32_t key[5]; + + now = _PyTime_GetSystemClock(); key[0] = (uint32_t)(now & 0xffffffffU); key[1] = (uint32_t)(now >> 32); - + key[2] = (uint32_t)getpid(); - - now = _PyTime_GetMonotonicClock(); + + now = _PyTime_GetMonotonicClock(); key[3] = (uint32_t)(now & 0xffffffffU); key[4] = (uint32_t)(now >> 32); - - init_by_array(self, key, Py_ARRAY_LENGTH(key)); -} - -static PyObject * + + init_by_array(self, key, Py_ARRAY_LENGTH(key)); +} + +static PyObject * random_seed(RandomObject *self, PyObject *arg) -{ - PyObject *result = NULL; /* guilty until proved innocent */ - PyObject *n = NULL; - uint32_t *key = NULL; - size_t bits, keyused; - int res; - +{ + PyObject *result = NULL; /* guilty until proved innocent */ + PyObject *n = NULL; + uint32_t *key = NULL; + size_t bits, keyused; + int res; + if (arg == NULL || arg == Py_None) { if (random_seed_urandom(self) < 0) { - PyErr_Clear(); - - /* Reading system entropy failed, fall back on the worst entropy: - use the current time and process identifier. */ - random_seed_time_pid(self); - } - Py_RETURN_NONE; - } - - /* This algorithm relies on the number being unsigned. - * So: if the arg is a PyLong, use its absolute value. - * Otherwise use its hash value, cast to unsigned. - */ + PyErr_Clear(); + + /* Reading system entropy failed, fall back on the worst entropy: + use the current time and process identifier. */ + random_seed_time_pid(self); + } + Py_RETURN_NONE; + } + + /* This algorithm relies on the number being unsigned. + * So: if the arg is a PyLong, use its absolute value. + * Otherwise use its hash value, cast to unsigned. + */ if (PyLong_CheckExact(arg)) { n = PyNumber_Absolute(arg); } else if (PyLong_Check(arg)) { - /* Calling int.__abs__() prevents calling arg.__abs__(), which might - return an invalid value. See issue #31478. */ + /* Calling int.__abs__() prevents calling arg.__abs__(), which might + return an invalid value. See issue #31478. */ n = PyObject_CallOneArg(_randomstate_global->Long___abs__, arg); - } - else { - Py_hash_t hash = PyObject_Hash(arg); - if (hash == -1) - goto Done; - n = PyLong_FromSize_t((size_t)hash); - } - if (n == NULL) - goto Done; - - /* Now split n into 32-bit chunks, from the right. */ - bits = _PyLong_NumBits(n); - if (bits == (size_t)-1 && PyErr_Occurred()) - goto Done; - - /* Figure out how many 32-bit chunks this gives us. */ - keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1; - - /* Convert seed to byte sequence. */ - key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused); - if (key == NULL) { - PyErr_NoMemory(); - goto Done; - } - res = _PyLong_AsByteArray((PyLongObject *)n, - (unsigned char *)key, keyused * 4, - PY_LITTLE_ENDIAN, - 0); /* unsigned */ - if (res == -1) { - goto Done; - } - -#if PY_BIG_ENDIAN - { - size_t i, j; - /* Reverse an array. */ - for (i = 0, j = keyused - 1; i < j; i++, j--) { - uint32_t tmp = key[i]; - key[i] = key[j]; - key[j] = tmp; - } - } -#endif - init_by_array(self, key, keyused); - - Py_INCREF(Py_None); - result = Py_None; - -Done: - Py_XDECREF(n); - PyMem_Free(key); - return result; -} - + } + else { + Py_hash_t hash = PyObject_Hash(arg); + if (hash == -1) + goto Done; + n = PyLong_FromSize_t((size_t)hash); + } + if (n == NULL) + goto Done; + + /* Now split n into 32-bit chunks, from the right. */ + bits = _PyLong_NumBits(n); + if (bits == (size_t)-1 && PyErr_Occurred()) + goto Done; + + /* Figure out how many 32-bit chunks this gives us. */ + keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1; + + /* Convert seed to byte sequence. */ + key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused); + if (key == NULL) { + PyErr_NoMemory(); + goto Done; + } + res = _PyLong_AsByteArray((PyLongObject *)n, + (unsigned char *)key, keyused * 4, + PY_LITTLE_ENDIAN, + 0); /* unsigned */ + if (res == -1) { + goto Done; + } + +#if PY_BIG_ENDIAN + { + size_t i, j; + /* Reverse an array. */ + for (i = 0, j = keyused - 1; i < j; i++, j--) { + uint32_t tmp = key[i]; + key[i] = key[j]; + key[j] = tmp; + } + } +#endif + init_by_array(self, key, keyused); + + Py_INCREF(Py_None); + result = Py_None; + +Done: + Py_XDECREF(n); + PyMem_Free(key); + return result; +} + /*[clinic input] _random.Random.seed @@ -359,10 +359,10 @@ Defaults to use urandom and falls back to a combination of the current time and the process identifier. [clinic start generated code]*/ -static PyObject * +static PyObject * _random_Random_seed_impl(RandomObject *self, PyObject *n) /*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/ -{ +{ return random_seed(self, n); } @@ -378,30 +378,30 @@ static PyObject * _random_Random_getstate_impl(RandomObject *self) /*[clinic end generated code: output=bf6cef0c092c7180 input=b937a487928c0e89]*/ { - PyObject *state; - PyObject *element; - int i; - - state = PyTuple_New(N+1); - if (state == NULL) - return NULL; - for (i=0; istate[i]); - if (element == NULL) - goto Fail; - PyTuple_SET_ITEM(state, i, element); - } - element = PyLong_FromLong((long)(self->index)); - if (element == NULL) - goto Fail; - PyTuple_SET_ITEM(state, i, element); - return state; - -Fail: - Py_DECREF(state); - return NULL; -} - + PyObject *state; + PyObject *element; + int i; + + state = PyTuple_New(N+1); + if (state == NULL) + return NULL; + for (i=0; istate[i]); + if (element == NULL) + goto Fail; + PyTuple_SET_ITEM(state, i, element); + } + element = PyLong_FromLong((long)(self->index)); + if (element == NULL) + goto Fail; + PyTuple_SET_ITEM(state, i, element); + return state; + +Fail: + Py_DECREF(state); + return NULL; +} + /*[clinic input] _random.Random.setstate @@ -413,47 +413,47 @@ _random.Random.setstate setstate(state) -> None. Restores generator state. [clinic start generated code]*/ -static PyObject * +static PyObject * _random_Random_setstate(RandomObject *self, PyObject *state) /*[clinic end generated code: output=fd1c3cd0037b6681 input=b3b4efbb1bc66af8]*/ -{ - int i; - unsigned long element; - long index; - uint32_t new_state[N]; - - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, - "state vector must be a tuple"); - return NULL; - } - if (PyTuple_Size(state) != N+1) { - PyErr_SetString(PyExc_ValueError, - "state vector is the wrong size"); - return NULL; - } - - for (i=0; i N) { - PyErr_SetString(PyExc_ValueError, "invalid state"); - return NULL; - } - self->index = (int)index; - for (i = 0; i < N; i++) - self->state[i] = new_state[i]; - - Py_RETURN_NONE; -} - +{ + int i; + unsigned long element; + long index; + uint32_t new_state[N]; + + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, + "state vector must be a tuple"); + return NULL; + } + if (PyTuple_Size(state) != N+1) { + PyErr_SetString(PyExc_ValueError, + "state vector is the wrong size"); + return NULL; + } + + for (i=0; i N) { + PyErr_SetString(PyExc_ValueError, "invalid state"); + return NULL; + } + self->index = (int)index; + for (i = 0; i < N; i++) + self->state[i] = new_state[i]; + + Py_RETURN_NONE; +} + /*[clinic input] _random.Random.getrandbits @@ -465,98 +465,98 @@ _random.Random.getrandbits getrandbits(k) -> x. Generates an int with k random bits. [clinic start generated code]*/ -static PyObject * +static PyObject * _random_Random_getrandbits_impl(RandomObject *self, int k) /*[clinic end generated code: output=b402f82a2158887f input=8c0e6396dd176fc0]*/ -{ +{ int i, words; - uint32_t r; - uint32_t *wordarray; - PyObject *result; - + uint32_t r; + uint32_t *wordarray; + PyObject *result; + if (k < 0) { - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(PyExc_ValueError, "number of bits must be non-negative"); - return NULL; - } - + return NULL; + } + if (k == 0) return PyLong_FromLong(0); - if (k <= 32) /* Fast path */ + if (k <= 32) /* Fast path */ return PyLong_FromUnsignedLong(genrand_uint32(self) >> (32 - k)); - - words = (k - 1) / 32 + 1; - wordarray = (uint32_t *)PyMem_Malloc(words * 4); - if (wordarray == NULL) { - PyErr_NoMemory(); - return NULL; - } - - /* Fill-out bits of long integer, by 32-bit words, from least significant - to most significant. */ -#if PY_LITTLE_ENDIAN - for (i = 0; i < words; i++, k -= 32) -#else - for (i = words - 1; i >= 0; i--, k -= 32) -#endif - { + + words = (k - 1) / 32 + 1; + wordarray = (uint32_t *)PyMem_Malloc(words * 4); + if (wordarray == NULL) { + PyErr_NoMemory(); + return NULL; + } + + /* Fill-out bits of long integer, by 32-bit words, from least significant + to most significant. */ +#if PY_LITTLE_ENDIAN + for (i = 0; i < words; i++, k -= 32) +#else + for (i = words - 1; i >= 0; i--, k -= 32) +#endif + { r = genrand_uint32(self); - if (k < 32) - r >>= (32 - k); /* Drop least significant bits */ - wordarray[i] = r; - } - - result = _PyLong_FromByteArray((unsigned char *)wordarray, words * 4, - PY_LITTLE_ENDIAN, 0 /* unsigned */); - PyMem_Free(wordarray); - return result; -} - -static PyObject * -random_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - RandomObject *self; - PyObject *tmp; - + if (k < 32) + r >>= (32 - k); /* Drop least significant bits */ + wordarray[i] = r; + } + + result = _PyLong_FromByteArray((unsigned char *)wordarray, words * 4, + PY_LITTLE_ENDIAN, 0 /* unsigned */); + PyMem_Free(wordarray); + return result; +} + +static PyObject * +random_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + RandomObject *self; + PyObject *tmp; + if (type == (PyTypeObject*)_randomstate_global->Random_Type && !_PyArg_NoKeywords("Random()", kwds)) { - return NULL; + return NULL; } - + self = (RandomObject *)PyType_GenericAlloc(type, 0); - if (self == NULL) - return NULL; - tmp = random_seed(self, args); - if (tmp == NULL) { - Py_DECREF(self); - return NULL; - } - Py_DECREF(tmp); - return (PyObject *)self; -} - - -static PyMethodDef random_methods[] = { + if (self == NULL) + return NULL; + tmp = random_seed(self, args); + if (tmp == NULL) { + Py_DECREF(self); + return NULL; + } + Py_DECREF(tmp); + return (PyObject *)self; +} + + +static PyMethodDef random_methods[] = { _RANDOM_RANDOM_RANDOM_METHODDEF _RANDOM_RANDOM_SEED_METHODDEF _RANDOM_RANDOM_GETSTATE_METHODDEF _RANDOM_RANDOM_SETSTATE_METHODDEF _RANDOM_RANDOM_GETRANDBITS_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(random_doc, -"Random() -> create a random number generator with its own internal state."); - + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(random_doc, +"Random() -> create a random number generator with its own internal state."); + static PyType_Slot Random_Type_slots[] = { {Py_tp_doc, (void *)random_doc}, {Py_tp_methods, random_methods}, {Py_tp_new, random_new}, {Py_tp_free, PyObject_Free}, {0, 0}, -}; - +}; + static PyType_Spec Random_Type_spec = { "_random.Random", sizeof(RandomObject), @@ -565,16 +565,16 @@ static PyType_Spec Random_Type_spec = { Random_Type_slots }; -PyDoc_STRVAR(module_doc, -"Module implements the Mersenne Twister random number generator."); - +PyDoc_STRVAR(module_doc, +"Module implements the Mersenne Twister random number generator."); + static int _random_traverse(PyObject *module, visitproc visit, void *arg) { Py_VISIT(get_random_state(module)->Random_Type); return 0; } - + static int _random_clear(PyObject *module) { @@ -589,32 +589,32 @@ _random_free(void *module) _random_clear((PyObject *)module); } -static struct PyModuleDef _randommodule = { - PyModuleDef_HEAD_INIT, - "_random", - module_doc, +static struct PyModuleDef _randommodule = { + PyModuleDef_HEAD_INIT, + "_random", + module_doc, sizeof(_randomstate), - NULL, - NULL, + NULL, + NULL, _random_traverse, _random_clear, _random_free, -}; - -PyMODINIT_FUNC -PyInit__random(void) -{ - PyObject *m; - +}; + +PyMODINIT_FUNC +PyInit__random(void) +{ + PyObject *m; + PyObject *Random_Type = PyType_FromSpec(&Random_Type_spec); if (Random_Type == NULL) { - return NULL; + return NULL; } - m = PyModule_Create(&_randommodule); + m = PyModule_Create(&_randommodule); if (m == NULL) { Py_DECREF(Random_Type); - return NULL; + return NULL; } get_random_state(m)->Random_Type = Random_Type; @@ -636,11 +636,11 @@ PyInit__random(void) Py_DECREF(longval); get_random_state(m)->Long___abs__ = abs; - return m; + return m; fail: Py_XDECREF(longtype); Py_XDECREF(longval); Py_DECREF(m); return NULL; -} +} diff --git a/contrib/tools/python3/src/Modules/_scproxy.c b/contrib/tools/python3/src/Modules/_scproxy.c index dbee3f7367e..c02d197517c 100644 --- a/contrib/tools/python3/src/Modules/_scproxy.c +++ b/contrib/tools/python3/src/Modules/_scproxy.c @@ -1,262 +1,262 @@ -/* - * Helper method for urllib to fetch the proxy configuration settings - * using the SystemConfiguration framework. - */ -#include -#include - -static int32_t -cfnum_to_int32(CFNumberRef num) -{ - int32_t result; - - CFNumberGetValue(num, kCFNumberSInt32Type, &result); - return result; -} - -static PyObject* -cfstring_to_pystring(CFStringRef ref) -{ - const char* s; - - s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8); - if (s) { - return PyUnicode_DecodeUTF8( - s, strlen(s), NULL); - - } else { - CFIndex len = CFStringGetLength(ref); - Boolean ok; - PyObject* result; - char* buf; - - buf = PyMem_Malloc(len*4); - if (buf == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ok = CFStringGetCString(ref, - buf, len * 4, - kCFStringEncodingUTF8); - if (!ok) { - PyMem_Free(buf); - return NULL; - } else { - result = PyUnicode_DecodeUTF8( - buf, strlen(buf), NULL); - PyMem_Free(buf); - } - return result; - } -} - - -static PyObject* +/* + * Helper method for urllib to fetch the proxy configuration settings + * using the SystemConfiguration framework. + */ +#include +#include + +static int32_t +cfnum_to_int32(CFNumberRef num) +{ + int32_t result; + + CFNumberGetValue(num, kCFNumberSInt32Type, &result); + return result; +} + +static PyObject* +cfstring_to_pystring(CFStringRef ref) +{ + const char* s; + + s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8); + if (s) { + return PyUnicode_DecodeUTF8( + s, strlen(s), NULL); + + } else { + CFIndex len = CFStringGetLength(ref); + Boolean ok; + PyObject* result; + char* buf; + + buf = PyMem_Malloc(len*4); + if (buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ok = CFStringGetCString(ref, + buf, len * 4, + kCFStringEncodingUTF8); + if (!ok) { + PyMem_Free(buf); + return NULL; + } else { + result = PyUnicode_DecodeUTF8( + buf, strlen(buf), NULL); + PyMem_Free(buf); + } + return result; + } +} + + +static PyObject* get_proxy_settings(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) -{ - CFDictionaryRef proxyDict = NULL; - CFNumberRef aNum = NULL; - CFArrayRef anArray = NULL; - PyObject* result = NULL; - PyObject* v; - int r; - - Py_BEGIN_ALLOW_THREADS - proxyDict = SCDynamicStoreCopyProxies(NULL); - Py_END_ALLOW_THREADS - - if (!proxyDict) { - Py_RETURN_NONE; - } - - result = PyDict_New(); - if (result == NULL) goto error; - - aNum = CFDictionaryGetValue(proxyDict, - kSCPropNetProxiesExcludeSimpleHostnames); - if (aNum == NULL) { - v = PyBool_FromLong(0); - } else { - v = PyBool_FromLong(cfnum_to_int32(aNum)); - } - - if (v == NULL) goto error; - - r = PyDict_SetItemString(result, "exclude_simple", v); - Py_DECREF(v); v = NULL; - if (r == -1) goto error; - - anArray = CFDictionaryGetValue(proxyDict, - kSCPropNetProxiesExceptionsList); - if (anArray != NULL) { - CFIndex len = CFArrayGetCount(anArray); - CFIndex i; - v = PyTuple_New(len); - if (v == NULL) goto error; - - r = PyDict_SetItemString(result, "exceptions", v); - Py_DECREF(v); - if (r == -1) goto error; - - for (i = 0; i < len; i++) { - CFStringRef aString = NULL; - - aString = CFArrayGetValueAtIndex(anArray, i); - if (aString == NULL) { - PyTuple_SetItem(v, i, Py_None); - Py_INCREF(Py_None); - } else { - PyObject* t = cfstring_to_pystring(aString); - if (!t) { - PyTuple_SetItem(v, i, Py_None); - Py_INCREF(Py_None); - } else { - PyTuple_SetItem(v, i, t); - } - } - } - } - - CFRelease(proxyDict); - return result; - -error: - if (proxyDict) CFRelease(proxyDict); - Py_XDECREF(result); - return NULL; -} - -static int -set_proxy(PyObject* proxies, const char* proto, CFDictionaryRef proxyDict, - CFStringRef enabledKey, - CFStringRef hostKey, CFStringRef portKey) -{ - CFNumberRef aNum; - - aNum = CFDictionaryGetValue(proxyDict, enabledKey); - if (aNum && cfnum_to_int32(aNum)) { - CFStringRef hostString; - - hostString = CFDictionaryGetValue(proxyDict, hostKey); - aNum = CFDictionaryGetValue(proxyDict, portKey); - - if (hostString) { - int r; - PyObject* h = cfstring_to_pystring(hostString); - PyObject* v; - if (h) { - if (aNum) { - int32_t port = cfnum_to_int32(aNum); - v = PyUnicode_FromFormat("http://%U:%ld", - h, (long)port); - } else { - v = PyUnicode_FromFormat("http://%U", h); - } - Py_DECREF(h); - if (!v) return -1; - r = PyDict_SetItemString(proxies, proto, - v); - Py_DECREF(v); - return r; - } - } - - } - return 0; -} - - - -static PyObject* +{ + CFDictionaryRef proxyDict = NULL; + CFNumberRef aNum = NULL; + CFArrayRef anArray = NULL; + PyObject* result = NULL; + PyObject* v; + int r; + + Py_BEGIN_ALLOW_THREADS + proxyDict = SCDynamicStoreCopyProxies(NULL); + Py_END_ALLOW_THREADS + + if (!proxyDict) { + Py_RETURN_NONE; + } + + result = PyDict_New(); + if (result == NULL) goto error; + + aNum = CFDictionaryGetValue(proxyDict, + kSCPropNetProxiesExcludeSimpleHostnames); + if (aNum == NULL) { + v = PyBool_FromLong(0); + } else { + v = PyBool_FromLong(cfnum_to_int32(aNum)); + } + + if (v == NULL) goto error; + + r = PyDict_SetItemString(result, "exclude_simple", v); + Py_DECREF(v); v = NULL; + if (r == -1) goto error; + + anArray = CFDictionaryGetValue(proxyDict, + kSCPropNetProxiesExceptionsList); + if (anArray != NULL) { + CFIndex len = CFArrayGetCount(anArray); + CFIndex i; + v = PyTuple_New(len); + if (v == NULL) goto error; + + r = PyDict_SetItemString(result, "exceptions", v); + Py_DECREF(v); + if (r == -1) goto error; + + for (i = 0; i < len; i++) { + CFStringRef aString = NULL; + + aString = CFArrayGetValueAtIndex(anArray, i); + if (aString == NULL) { + PyTuple_SetItem(v, i, Py_None); + Py_INCREF(Py_None); + } else { + PyObject* t = cfstring_to_pystring(aString); + if (!t) { + PyTuple_SetItem(v, i, Py_None); + Py_INCREF(Py_None); + } else { + PyTuple_SetItem(v, i, t); + } + } + } + } + + CFRelease(proxyDict); + return result; + +error: + if (proxyDict) CFRelease(proxyDict); + Py_XDECREF(result); + return NULL; +} + +static int +set_proxy(PyObject* proxies, const char* proto, CFDictionaryRef proxyDict, + CFStringRef enabledKey, + CFStringRef hostKey, CFStringRef portKey) +{ + CFNumberRef aNum; + + aNum = CFDictionaryGetValue(proxyDict, enabledKey); + if (aNum && cfnum_to_int32(aNum)) { + CFStringRef hostString; + + hostString = CFDictionaryGetValue(proxyDict, hostKey); + aNum = CFDictionaryGetValue(proxyDict, portKey); + + if (hostString) { + int r; + PyObject* h = cfstring_to_pystring(hostString); + PyObject* v; + if (h) { + if (aNum) { + int32_t port = cfnum_to_int32(aNum); + v = PyUnicode_FromFormat("http://%U:%ld", + h, (long)port); + } else { + v = PyUnicode_FromFormat("http://%U", h); + } + Py_DECREF(h); + if (!v) return -1; + r = PyDict_SetItemString(proxies, proto, + v); + Py_DECREF(v); + return r; + } + } + + } + return 0; +} + + + +static PyObject* get_proxies(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) -{ - PyObject* result = NULL; - int r; - CFDictionaryRef proxyDict = NULL; - - Py_BEGIN_ALLOW_THREADS - proxyDict = SCDynamicStoreCopyProxies(NULL); - Py_END_ALLOW_THREADS - - if (proxyDict == NULL) { - return PyDict_New(); - } - - result = PyDict_New(); - if (result == NULL) goto error; - - r = set_proxy(result, "http", proxyDict, - kSCPropNetProxiesHTTPEnable, - kSCPropNetProxiesHTTPProxy, - kSCPropNetProxiesHTTPPort); - if (r == -1) goto error; - r = set_proxy(result, "https", proxyDict, - kSCPropNetProxiesHTTPSEnable, - kSCPropNetProxiesHTTPSProxy, - kSCPropNetProxiesHTTPSPort); - if (r == -1) goto error; - r = set_proxy(result, "ftp", proxyDict, - kSCPropNetProxiesFTPEnable, - kSCPropNetProxiesFTPProxy, - kSCPropNetProxiesFTPPort); - if (r == -1) goto error; - r = set_proxy(result, "gopher", proxyDict, - kSCPropNetProxiesGopherEnable, - kSCPropNetProxiesGopherProxy, - kSCPropNetProxiesGopherPort); - if (r == -1) goto error; - - CFRelease(proxyDict); - return result; -error: - if (proxyDict) CFRelease(proxyDict); - Py_XDECREF(result); - return NULL; -} - -static PyMethodDef mod_methods[] = { - { - "_get_proxy_settings", +{ + PyObject* result = NULL; + int r; + CFDictionaryRef proxyDict = NULL; + + Py_BEGIN_ALLOW_THREADS + proxyDict = SCDynamicStoreCopyProxies(NULL); + Py_END_ALLOW_THREADS + + if (proxyDict == NULL) { + return PyDict_New(); + } + + result = PyDict_New(); + if (result == NULL) goto error; + + r = set_proxy(result, "http", proxyDict, + kSCPropNetProxiesHTTPEnable, + kSCPropNetProxiesHTTPProxy, + kSCPropNetProxiesHTTPPort); + if (r == -1) goto error; + r = set_proxy(result, "https", proxyDict, + kSCPropNetProxiesHTTPSEnable, + kSCPropNetProxiesHTTPSProxy, + kSCPropNetProxiesHTTPSPort); + if (r == -1) goto error; + r = set_proxy(result, "ftp", proxyDict, + kSCPropNetProxiesFTPEnable, + kSCPropNetProxiesFTPProxy, + kSCPropNetProxiesFTPPort); + if (r == -1) goto error; + r = set_proxy(result, "gopher", proxyDict, + kSCPropNetProxiesGopherEnable, + kSCPropNetProxiesGopherProxy, + kSCPropNetProxiesGopherPort); + if (r == -1) goto error; + + CFRelease(proxyDict); + return result; +error: + if (proxyDict) CFRelease(proxyDict); + Py_XDECREF(result); + return NULL; +} + +static PyMethodDef mod_methods[] = { + { + "_get_proxy_settings", get_proxy_settings, - METH_NOARGS, - NULL, - }, - { - "_get_proxies", + METH_NOARGS, + NULL, + }, + { + "_get_proxies", get_proxies, - METH_NOARGS, - NULL, - }, - { 0, 0, 0, 0 } -}; - - - -static struct PyModuleDef mod_module = { - PyModuleDef_HEAD_INIT, - "_scproxy", - NULL, - -1, - mod_methods, - NULL, - NULL, - NULL, - NULL -}; - - -#ifdef __cplusplus -extern "C" { -#endif - -PyMODINIT_FUNC -PyInit__scproxy(void) -{ - return PyModule_Create(&mod_module); -} - -#ifdef __cplusplus -} -#endif - + METH_NOARGS, + NULL, + }, + { 0, 0, 0, 0 } +}; + + + +static struct PyModuleDef mod_module = { + PyModuleDef_HEAD_INIT, + "_scproxy", + NULL, + -1, + mod_methods, + NULL, + NULL, + NULL, + NULL +}; + + +#ifdef __cplusplus +extern "C" { +#endif + +PyMODINIT_FUNC +PyInit__scproxy(void) +{ + return PyModule_Create(&mod_module); +} + +#ifdef __cplusplus +} +#endif + diff --git a/contrib/tools/python3/src/Modules/_sha3/clinic/sha3module.c.h b/contrib/tools/python3/src/Modules/_sha3/clinic/sha3module.c.h index 1c79c269391..16e485876be 100644 --- a/contrib/tools/python3/src/Modules/_sha3/clinic/sha3module.c.h +++ b/contrib/tools/python3/src/Modules/_sha3/clinic/sha3module.c.h @@ -1,7 +1,7 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - +/*[clinic input] +preserve +[clinic start generated code]*/ + PyDoc_STRVAR(py_sha3_new__doc__, "sha3_224(data=b\'\', /, *, usedforsecurity=True)\n" "--\n" @@ -48,78 +48,78 @@ exit: return return_value; } -PyDoc_STRVAR(_sha3_sha3_224_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define _SHA3_SHA3_224_COPY_METHODDEF \ - {"copy", (PyCFunction)_sha3_sha3_224_copy, METH_NOARGS, _sha3_sha3_224_copy__doc__}, - -static PyObject * -_sha3_sha3_224_copy_impl(SHA3object *self); - -static PyObject * -_sha3_sha3_224_copy(SHA3object *self, PyObject *Py_UNUSED(ignored)) -{ - return _sha3_sha3_224_copy_impl(self); -} - -PyDoc_STRVAR(_sha3_sha3_224_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define _SHA3_SHA3_224_DIGEST_METHODDEF \ - {"digest", (PyCFunction)_sha3_sha3_224_digest, METH_NOARGS, _sha3_sha3_224_digest__doc__}, - -static PyObject * -_sha3_sha3_224_digest_impl(SHA3object *self); - -static PyObject * -_sha3_sha3_224_digest(SHA3object *self, PyObject *Py_UNUSED(ignored)) -{ - return _sha3_sha3_224_digest_impl(self); -} - -PyDoc_STRVAR(_sha3_sha3_224_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define _SHA3_SHA3_224_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)_sha3_sha3_224_hexdigest, METH_NOARGS, _sha3_sha3_224_hexdigest__doc__}, - -static PyObject * -_sha3_sha3_224_hexdigest_impl(SHA3object *self); - -static PyObject * -_sha3_sha3_224_hexdigest(SHA3object *self, PyObject *Py_UNUSED(ignored)) -{ - return _sha3_sha3_224_hexdigest_impl(self); -} - -PyDoc_STRVAR(_sha3_sha3_224_update__doc__, -"update($self, data, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided bytes-like object."); - -#define _SHA3_SHA3_224_UPDATE_METHODDEF \ - {"update", (PyCFunction)_sha3_sha3_224_update, METH_O, _sha3_sha3_224_update__doc__}, - -PyDoc_STRVAR(_sha3_shake_128_digest__doc__, -"digest($self, length, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define _SHA3_SHAKE_128_DIGEST_METHODDEF \ - {"digest", (PyCFunction)_sha3_shake_128_digest, METH_O, _sha3_shake_128_digest__doc__}, - +PyDoc_STRVAR(_sha3_sha3_224_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define _SHA3_SHA3_224_COPY_METHODDEF \ + {"copy", (PyCFunction)_sha3_sha3_224_copy, METH_NOARGS, _sha3_sha3_224_copy__doc__}, + +static PyObject * +_sha3_sha3_224_copy_impl(SHA3object *self); + +static PyObject * +_sha3_sha3_224_copy(SHA3object *self, PyObject *Py_UNUSED(ignored)) +{ + return _sha3_sha3_224_copy_impl(self); +} + +PyDoc_STRVAR(_sha3_sha3_224_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define _SHA3_SHA3_224_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_sha3_sha3_224_digest, METH_NOARGS, _sha3_sha3_224_digest__doc__}, + +static PyObject * +_sha3_sha3_224_digest_impl(SHA3object *self); + +static PyObject * +_sha3_sha3_224_digest(SHA3object *self, PyObject *Py_UNUSED(ignored)) +{ + return _sha3_sha3_224_digest_impl(self); +} + +PyDoc_STRVAR(_sha3_sha3_224_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define _SHA3_SHA3_224_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_sha3_sha3_224_hexdigest, METH_NOARGS, _sha3_sha3_224_hexdigest__doc__}, + +static PyObject * +_sha3_sha3_224_hexdigest_impl(SHA3object *self); + +static PyObject * +_sha3_sha3_224_hexdigest(SHA3object *self, PyObject *Py_UNUSED(ignored)) +{ + return _sha3_sha3_224_hexdigest_impl(self); +} + +PyDoc_STRVAR(_sha3_sha3_224_update__doc__, +"update($self, data, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided bytes-like object."); + +#define _SHA3_SHA3_224_UPDATE_METHODDEF \ + {"update", (PyCFunction)_sha3_sha3_224_update, METH_O, _sha3_sha3_224_update__doc__}, + +PyDoc_STRVAR(_sha3_shake_128_digest__doc__, +"digest($self, length, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define _SHA3_SHAKE_128_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_sha3_shake_128_digest, METH_O, _sha3_shake_128_digest__doc__}, + static PyObject * _sha3_shake_128_digest_impl(SHA3object *self, unsigned long length); @@ -138,14 +138,14 @@ exit: return return_value; } -PyDoc_STRVAR(_sha3_shake_128_hexdigest__doc__, -"hexdigest($self, length, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define _SHA3_SHAKE_128_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)_sha3_shake_128_hexdigest, METH_O, _sha3_shake_128_hexdigest__doc__}, +PyDoc_STRVAR(_sha3_shake_128_hexdigest__doc__, +"hexdigest($self, length, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define _SHA3_SHAKE_128_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_sha3_shake_128_hexdigest, METH_O, _sha3_shake_128_hexdigest__doc__}, static PyObject * _sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length); diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakHash.c b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakHash.c index e09fb43cace..f3f402d66d7 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakHash.c +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakHash.c @@ -1,82 +1,82 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -#include "KeccakHash.h" - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix) -{ - HashReturn result; - - if (delimitedSuffix == 0) - return FAIL; - result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity); - if (result != SUCCESS) - return result; - instance->fixedOutputLength = hashbitlen; - instance->delimitedSuffix = delimitedSuffix; - return SUCCESS; -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, DataLength databitlen) -{ - if ((databitlen % 8) == 0) - return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); - else { - HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); - if (ret == SUCCESS) { - /* The last partial byte is assumed to be aligned on the least significant bits */ - - unsigned char lastByte = data[databitlen/8]; - /* Concatenate the last few bits provided here with those of the suffix */ - - unsigned short delimitedLastBytes = (unsigned short)((unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8))); - if ((delimitedLastBytes & 0xFF00) == 0x0000) { - instance->delimitedSuffix = delimitedLastBytes & 0xFF; - } - else { - unsigned char oneByte[1]; - oneByte[0] = delimitedLastBytes & 0xFF; - ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1); - instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF; - } - } - return ret; - } -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval) -{ - HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix); - if (ret == SUCCESS) - return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8); - else - return ret; -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen) -{ - if ((databitlen % 8) != 0) - return FAIL; - return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8); -} +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include +#include "KeccakHash.h" + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix) +{ + HashReturn result; + + if (delimitedSuffix == 0) + return FAIL; + result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity); + if (result != SUCCESS) + return result; + instance->fixedOutputLength = hashbitlen; + instance->delimitedSuffix = delimitedSuffix; + return SUCCESS; +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, DataLength databitlen) +{ + if ((databitlen % 8) == 0) + return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); + else { + HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); + if (ret == SUCCESS) { + /* The last partial byte is assumed to be aligned on the least significant bits */ + + unsigned char lastByte = data[databitlen/8]; + /* Concatenate the last few bits provided here with those of the suffix */ + + unsigned short delimitedLastBytes = (unsigned short)((unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8))); + if ((delimitedLastBytes & 0xFF00) == 0x0000) { + instance->delimitedSuffix = delimitedLastBytes & 0xFF; + } + else { + unsigned char oneByte[1]; + oneByte[0] = delimitedLastBytes & 0xFF; + ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1); + instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF; + } + } + return ret; + } +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval) +{ + HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix); + if (ret == SUCCESS) + return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8); + else + return ret; +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen) +{ + if ((databitlen % 8) != 0) + return FAIL; + return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8); +} diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakHash.h b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakHash.h index bbd3dc64a22..4969bfa0011 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakHash.h +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakHash.h @@ -1,114 +1,114 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakHashInterface_h_ -#define _KeccakHashInterface_h_ - -#ifndef KeccakP1600_excluded - -#include "KeccakSponge.h" -#include - -typedef unsigned char BitSequence; -typedef size_t DataLength; -typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; - -typedef struct { - KeccakWidth1600_SpongeInstance sponge; - unsigned int fixedOutputLength; - unsigned char delimitedSuffix; -} Keccak_HashInstance; - -/** - * Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode. - * @param hashInstance Pointer to the hash instance to be initialized. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @param hashbitlen The desired number of output bits, - * or 0 for an arbitrarily-long output. - * @param delimitedSuffix Bits that will be automatically appended to the end - * of the input message, as in domain separation. - * This is a byte containing from 0 to 7 bits - * formatted like the @a delimitedData parameter of - * the Keccak_SpongeAbsorbLastFewBits() function. - * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix); - -/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F) - -/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F) - -/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06) - -/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) - -/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) - -/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) - -/** - * Function to give input data to be absorbed. - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * @param data Pointer to the input data. - * When @a databitLen is not a multiple of 8, the last bits of data must be - * in the least significant bits of the last byte (little-endian convention). - * @param databitLen The number of input bits provided in the input data. - * @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, DataLength databitlen); - -/** - * Function to call after all input blocks have been input and to get - * output bits if the length was specified when calling Keccak_HashInitialize(). - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of - * output bits is equal to @a hashbitlen. - * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits - * must be extracted using the Keccak_HashSqueeze() function. - * @param state Pointer to the state of the sponge function initialized by Init(). - * @param hashval Pointer to the buffer where to store the output data. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval); - - /** - * Function to squeeze output data. - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * @param data Pointer to the buffer where to store the output data. - * @param databitlen The number of output bits desired (must be a multiple of 8). - * @pre Keccak_HashFinal() must have been already called. - * @pre @a databitlen is a multiple of 8. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen); - -#endif - -#endif +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakHashInterface_h_ +#define _KeccakHashInterface_h_ + +#ifndef KeccakP1600_excluded + +#include "KeccakSponge.h" +#include + +typedef unsigned char BitSequence; +typedef size_t DataLength; +typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; + +typedef struct { + KeccakWidth1600_SpongeInstance sponge; + unsigned int fixedOutputLength; + unsigned char delimitedSuffix; +} Keccak_HashInstance; + +/** + * Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode. + * @param hashInstance Pointer to the hash instance to be initialized. + * @param rate The value of the rate r. + * @param capacity The value of the capacity c. + * @param hashbitlen The desired number of output bits, + * or 0 for an arbitrarily-long output. + * @param delimitedSuffix Bits that will be automatically appended to the end + * of the input message, as in domain separation. + * This is a byte containing from 0 to 7 bits + * formatted like the @a delimitedData parameter of + * the Keccak_SpongeAbsorbLastFewBits() function. + * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix); + +/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F) + +/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F) + +/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06) + +/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) + +/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) + +/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) + +/** + * Function to give input data to be absorbed. + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * @param data Pointer to the input data. + * When @a databitLen is not a multiple of 8, the last bits of data must be + * in the least significant bits of the last byte (little-endian convention). + * @param databitLen The number of input bits provided in the input data. + * @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, DataLength databitlen); + +/** + * Function to call after all input blocks have been input and to get + * output bits if the length was specified when calling Keccak_HashInitialize(). + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of + * output bits is equal to @a hashbitlen. + * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits + * must be extracted using the Keccak_HashSqueeze() function. + * @param state Pointer to the state of the sponge function initialized by Init(). + * @param hashval Pointer to the buffer where to store the output data. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval); + + /** + * Function to squeeze output data. + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * @param data Pointer to the buffer where to store the output data. + * @param databitlen The number of output bits desired (must be a multiple of 8). + * @pre Keccak_HashFinal() must have been already called. + * @pre @a databitlen is a multiple of 8. + * @return SUCCESS if successful, FAIL otherwise. + */ +HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen); + +#endif + +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-64.macros b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-64.macros index 1f11fe3e79f..739161ffd63 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-64.macros +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-64.macros @@ -1,2208 +1,2208 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - UINT64 Aba, Abe, Abi, Abo, Abu; \ - UINT64 Aga, Age, Agi, Ago, Agu; \ - UINT64 Aka, Ake, Aki, Ako, Aku; \ - UINT64 Ama, Ame, Ami, Amo, Amu; \ - UINT64 Asa, Ase, Asi, Aso, Asu; \ - UINT64 Bba, Bbe, Bbi, Bbo, Bbu; \ - UINT64 Bga, Bge, Bgi, Bgo, Bgu; \ - UINT64 Bka, Bke, Bki, Bko, Bku; \ - UINT64 Bma, Bme, Bmi, Bmo, Bmu; \ - UINT64 Bsa, Bse, Bsi, Bso, Bsu; \ - UINT64 Ca, Ce, Ci, Co, Cu; \ - UINT64 Da, De, Di, Do, Du; \ - UINT64 Eba, Ebe, Ebi, Ebo, Ebu; \ - UINT64 Ega, Ege, Egi, Ego, Egu; \ - UINT64 Eka, Eke, Eki, Eko, Eku; \ - UINT64 Ema, Eme, Emi, Emo, Emu; \ - UINT64 Esa, Ese, Esi, Eso, Esu; \ - -#define prepareTheta \ - Ca = Aba^Aga^Aka^Ama^Asa; \ - Ce = Abe^Age^Ake^Ame^Ase; \ - Ci = Abi^Agi^Aki^Ami^Asi; \ - Co = Abo^Ago^Ako^Amo^Aso; \ - Cu = Abu^Agu^Aku^Amu^Asu; \ - -#ifdef UseBebigokimisa -/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^( Bbe | Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - Ca = E##ba; \ - E##be = Bbe ^((~Bbi)| Bbo ); \ - Ce = E##be; \ - E##bi = Bbi ^( Bbo & Bbu ); \ - Ci = E##bi; \ - E##bo = Bbo ^( Bbu | Bba ); \ - Co = E##bo; \ - E##bu = Bbu ^( Bba & Bbe ); \ - Cu = E##bu; \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^( Bge | Bgi ); \ - Ca ^= E##ga; \ - E##ge = Bge ^( Bgi & Bgo ); \ - Ce ^= E##ge; \ - E##gi = Bgi ^( Bgo |(~Bgu)); \ - Ci ^= E##gi; \ - E##go = Bgo ^( Bgu | Bga ); \ - Co ^= E##go; \ - E##gu = Bgu ^( Bga & Bge ); \ - Cu ^= E##gu; \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^( Bke | Bki ); \ - Ca ^= E##ka; \ - E##ke = Bke ^( Bki & Bko ); \ - Ce ^= E##ke; \ - E##ki = Bki ^((~Bko)& Bku ); \ - Ci ^= E##ki; \ - E##ko = (~Bko)^( Bku | Bka ); \ - Co ^= E##ko; \ - E##ku = Bku ^( Bka & Bke ); \ - Cu ^= E##ku; \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^( Bme & Bmi ); \ - Ca ^= E##ma; \ - E##me = Bme ^( Bmi | Bmo ); \ - Ce ^= E##me; \ - E##mi = Bmi ^((~Bmo)| Bmu ); \ - Ci ^= E##mi; \ - E##mo = (~Bmo)^( Bmu & Bma ); \ - Co ^= E##mo; \ - E##mu = Bmu ^( Bma | Bme ); \ - Cu ^= E##mu; \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - Ca ^= E##sa; \ - E##se = (~Bse)^( Bsi | Bso ); \ - Ce ^= E##se; \ - E##si = Bsi ^( Bso & Bsu ); \ - Ci ^= E##si; \ - E##so = Bso ^( Bsu | Bsa ); \ - Co ^= E##so; \ - E##su = Bsu ^( Bsa & Bse ); \ - Cu ^= E##su; \ -\ - -/* --- Code for round (lane complementing pattern 'bebigokimisa') */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIota(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^( Bbe | Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - E##be = Bbe ^((~Bbi)| Bbo ); \ - E##bi = Bbi ^( Bbo & Bbu ); \ - E##bo = Bbo ^( Bbu | Bba ); \ - E##bu = Bbu ^( Bba & Bbe ); \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^( Bge | Bgi ); \ - E##ge = Bge ^( Bgi & Bgo ); \ - E##gi = Bgi ^( Bgo |(~Bgu)); \ - E##go = Bgo ^( Bgu | Bga ); \ - E##gu = Bgu ^( Bga & Bge ); \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^( Bke | Bki ); \ - E##ke = Bke ^( Bki & Bko ); \ - E##ki = Bki ^((~Bko)& Bku ); \ - E##ko = (~Bko)^( Bku | Bka ); \ - E##ku = Bku ^( Bka & Bke ); \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^( Bme & Bmi ); \ - E##me = Bme ^( Bmi | Bmo ); \ - E##mi = Bmi ^((~Bmo)| Bmu ); \ - E##mo = (~Bmo)^( Bmu & Bma ); \ - E##mu = Bmu ^( Bma | Bme ); \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - E##se = (~Bse)^( Bsi | Bso ); \ - E##si = Bsi ^( Bso & Bsu ); \ - E##so = Bso ^( Bsu | Bsa ); \ - E##su = Bsu ^( Bsa & Bse ); \ -\ - -#else /* UseBebigokimisa */ - -/* --- Code for round, with prepare-theta */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^((~Bbe)& Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - Ca = E##ba; \ - E##be = Bbe ^((~Bbi)& Bbo ); \ - Ce = E##be; \ - E##bi = Bbi ^((~Bbo)& Bbu ); \ - Ci = E##bi; \ - E##bo = Bbo ^((~Bbu)& Bba ); \ - Co = E##bo; \ - E##bu = Bbu ^((~Bba)& Bbe ); \ - Cu = E##bu; \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^((~Bge)& Bgi ); \ - Ca ^= E##ga; \ - E##ge = Bge ^((~Bgi)& Bgo ); \ - Ce ^= E##ge; \ - E##gi = Bgi ^((~Bgo)& Bgu ); \ - Ci ^= E##gi; \ - E##go = Bgo ^((~Bgu)& Bga ); \ - Co ^= E##go; \ - E##gu = Bgu ^((~Bga)& Bge ); \ - Cu ^= E##gu; \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^((~Bke)& Bki ); \ - Ca ^= E##ka; \ - E##ke = Bke ^((~Bki)& Bko ); \ - Ce ^= E##ke; \ - E##ki = Bki ^((~Bko)& Bku ); \ - Ci ^= E##ki; \ - E##ko = Bko ^((~Bku)& Bka ); \ - Co ^= E##ko; \ - E##ku = Bku ^((~Bka)& Bke ); \ - Cu ^= E##ku; \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^((~Bme)& Bmi ); \ - Ca ^= E##ma; \ - E##me = Bme ^((~Bmi)& Bmo ); \ - Ce ^= E##me; \ - E##mi = Bmi ^((~Bmo)& Bmu ); \ - Ci ^= E##mi; \ - E##mo = Bmo ^((~Bmu)& Bma ); \ - Co ^= E##mo; \ - E##mu = Bmu ^((~Bma)& Bme ); \ - Cu ^= E##mu; \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - Ca ^= E##sa; \ - E##se = Bse ^((~Bsi)& Bso ); \ - Ce ^= E##se; \ - E##si = Bsi ^((~Bso)& Bsu ); \ - Ci ^= E##si; \ - E##so = Bso ^((~Bsu)& Bsa ); \ - Co ^= E##so; \ - E##su = Bsu ^((~Bsa)& Bse ); \ - Cu ^= E##su; \ -\ - -/* --- Code for round */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIota(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^((~Bbe)& Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - E##be = Bbe ^((~Bbi)& Bbo ); \ - E##bi = Bbi ^((~Bbo)& Bbu ); \ - E##bo = Bbo ^((~Bbu)& Bba ); \ - E##bu = Bbu ^((~Bba)& Bbe ); \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^((~Bge)& Bgi ); \ - E##ge = Bge ^((~Bgi)& Bgo ); \ - E##gi = Bgi ^((~Bgo)& Bgu ); \ - E##go = Bgo ^((~Bgu)& Bga ); \ - E##gu = Bgu ^((~Bga)& Bge ); \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^((~Bke)& Bki ); \ - E##ke = Bke ^((~Bki)& Bko ); \ - E##ki = Bki ^((~Bko)& Bku ); \ - E##ko = Bko ^((~Bku)& Bka ); \ - E##ku = Bku ^((~Bka)& Bke ); \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^((~Bme)& Bmi ); \ - E##me = Bme ^((~Bmi)& Bmo ); \ - E##mi = Bmi ^((~Bmo)& Bmu ); \ - E##mo = Bmo ^((~Bmu)& Bma ); \ - E##mu = Bmu ^((~Bma)& Bme ); \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - E##se = Bse ^((~Bsi)& Bso ); \ - E##si = Bsi ^((~Bso)& Bsu ); \ - E##so = Bso ^((~Bsu)& Bsa ); \ - E##su = Bsu ^((~Bsa)& Bse ); \ -\ - -#endif /* UseBebigokimisa */ - - -#define copyFromState(X, state) \ - X##ba = state[ 0]; \ - X##be = state[ 1]; \ - X##bi = state[ 2]; \ - X##bo = state[ 3]; \ - X##bu = state[ 4]; \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - X##gi = state[ 7]; \ - X##go = state[ 8]; \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba; \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - -#define copyStateVariables(X, Y) \ - X##ba = Y##ba; \ - X##be = Y##be; \ - X##bi = Y##bi; \ - X##bo = Y##bo; \ - X##bu = Y##bu; \ - X##ga = Y##ga; \ - X##ge = Y##ge; \ - X##gi = Y##gi; \ - X##go = Y##go; \ - X##gu = Y##gu; \ - X##ka = Y##ka; \ - X##ke = Y##ke; \ - X##ki = Y##ki; \ - X##ko = Y##ko; \ - X##ku = Y##ku; \ - X##ma = Y##ma; \ - X##me = Y##me; \ - X##mi = Y##mi; \ - X##mo = Y##mo; \ - X##mu = Y##mu; \ - X##sa = Y##sa; \ - X##se = Y##se; \ - X##si = Y##si; \ - X##so = Y##so; \ - X##su = Y##su; \ - -#define copyFromStateAndAdd(X, state, input, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba = state[ 0]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - } \ - X##be = state[ 1]; \ - X##bi = state[ 2]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - if (laneCount < 3) { \ - X##bi = state[ 2]; \ - } \ - else { \ - X##bi = state[ 2]^input[ 2]; \ - } \ - } \ - X##bo = state[ 3]; \ - X##bu = state[ 4]; \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu = state[ 4]; \ - } \ - else { \ - X##bu = state[ 4]^input[ 4]; \ - } \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - } \ - else { \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - if (laneCount < 7) { \ - X##ge = state[ 6]; \ - } \ - else { \ - X##ge = state[ 6]^input[ 6]; \ - } \ - } \ - } \ - X##gi = state[ 7]; \ - X##go = state[ 8]; \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go = state[ 8]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - } \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - if (laneCount < 11) { \ - X##ka = state[10]; \ - } \ - else { \ - X##ka = state[10]^input[10]; \ - } \ - } \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki = state[12]; \ - } \ - else { \ - X##ki = state[12]^input[12]; \ - } \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - if (laneCount < 15) { \ - X##ku = state[14]; \ - } \ - else { \ - X##ku = state[14]^input[14]; \ - } \ - } \ - } \ - } \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - X##ku = state[14]^input[14]; \ - X##ma = state[15]^input[15]; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me = state[16]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - } \ - X##mi = state[17]; \ - X##mo = state[18]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - if (laneCount < 19) { \ - X##mo = state[18]; \ - } \ - else { \ - X##mo = state[18]^input[18]; \ - } \ - } \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - X##mo = state[18]^input[18]; \ - X##mu = state[19]^input[19]; \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa = state[20]; \ - } \ - else { \ - X##sa = state[20]^input[20]; \ - } \ - X##se = state[21]; \ - X##si = state[22]; \ - } \ - else { \ - X##sa = state[20]^input[20]; \ - X##se = state[21]^input[21]; \ - if (laneCount < 23) { \ - X##si = state[22]; \ - } \ - else { \ - X##si = state[22]^input[22]; \ - } \ - } \ - } \ - X##so = state[23]; \ - X##su = state[24]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - X##mo = state[18]^input[18]; \ - X##mu = state[19]^input[19]; \ - X##sa = state[20]^input[20]; \ - X##se = state[21]^input[21]; \ - X##si = state[22]^input[22]; \ - X##so = state[23]^input[23]; \ - if (laneCount < 25) { \ - X##su = state[24]; \ - } \ - else { \ - X##su = state[24]^input[24]; \ - } \ - } \ - } - -#define addInput(X, input, laneCount) \ - if (laneCount == 21) { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - X##ku ^= input[14]; \ - X##ma ^= input[15]; \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - X##sa ^= input[20]; \ - } \ - else if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - } \ - else { \ - X##ba ^= input[ 0]; \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - if (laneCount < 3) { \ - } \ - else { \ - X##bi ^= input[ 2]; \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - } \ - else { \ - X##bu ^= input[ 4]; \ - } \ - } \ - else { \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - if (laneCount < 7) { \ - } \ - else { \ - X##ge ^= input[ 6]; \ - } \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - } \ - else { \ - X##go ^= input[ 8]; \ - } \ - } \ - else { \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - if (laneCount < 11) { \ - } \ - else { \ - X##ka ^= input[10]; \ - } \ - } \ - } \ - else { \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - } \ - else { \ - X##ki ^= input[12]; \ - } \ - } \ - else { \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - if (laneCount < 15) { \ - } \ - else { \ - X##ku ^= input[14]; \ - } \ - } \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - X##ku ^= input[14]; \ - X##ma ^= input[15]; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - } \ - else { \ - X##me ^= input[16]; \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - if (laneCount < 19) { \ - } \ - else { \ - X##mo ^= input[18]; \ - } \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - } \ - else { \ - X##sa ^= input[20]; \ - } \ - } \ - else { \ - X##sa ^= input[20]; \ - X##se ^= input[21]; \ - if (laneCount < 23) { \ - } \ - else { \ - X##si ^= input[22]; \ - } \ - } \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - X##sa ^= input[20]; \ - X##se ^= input[21]; \ - X##si ^= input[22]; \ - X##so ^= input[23]; \ - if (laneCount < 25) { \ - } \ - else { \ - X##su ^= input[24]; \ - } \ - } \ - } - -#ifdef UseBebigokimisa - -#define copyToStateAndOutput(X, state, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - state[ 0] = X##ba; \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - if (laneCount >= 3) { \ - output[ 2] = ~X##bi; \ - } \ - } \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - state[ 4] = X##bu; \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - state[ 8] = X##go; \ - if (laneCount >= 9) { \ - output[ 8] = ~X##go; \ - } \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - state[12] = X##ki; \ - if (laneCount >= 13) { \ - output[12] = ~X##ki; \ - } \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[12] = X##ki; \ - output[12] = ~X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - state[12] = X##ki; \ - output[12] = ~X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - output[14] = X##ku; \ - state[15] = X##ma; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - state[16] = X##me; \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - state[17] = X##mi; \ - state[18] = X##mo; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - state[20] = X##sa; \ - if (laneCount >= 21) { \ - output[20] = ~X##sa; \ - } \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[20] = X##sa; \ - output[20] = ~X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - state[20] = X##sa; \ - output[20] = ~X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - output[22] = X##si; \ - state[23] = X##so; \ - output[23] = X##so; \ - state[24] = X##su; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define output(X, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - if (laneCount >= 3) { \ - output[ 2] = ~X##bi; \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - } \ - else { \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount >= 9) { \ - output[ 8] = ~X##go; \ - } \ - } \ - else { \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - } \ - else { \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - if (laneCount >= 13) { \ - output[12] = ~X##ki; \ - } \ - } \ - else { \ - output[12] = ~X##ki; \ - output[13] = X##ko; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - output[12] = ~X##ki; \ - output[13] = X##ko; \ - output[14] = X##ku; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - if (laneCount >= 21) { \ - output[20] = ~X##sa; \ - } \ - } \ - else { \ - output[20] = ~X##sa; \ - output[21] = X##se; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - output[20] = ~X##sa; \ - output[21] = X##se; \ - output[22] = X##si; \ - output[23] = X##so; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define wrapOne(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define wrapOneInvert(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = ~X##name; - -#define unwrapOne(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#define unwrapOneInvert(X, input, output, index, name) \ - output[index] = ~(input[index] ^ X##name); \ - X##name ^= output[index]; \ - -#else /* UseBebigokimisa */ - - -#define copyToStateAndOutput(X, state, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - state[ 0] = X##ba; \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - if (laneCount >= 3) { \ - output[ 2] = X##bi; \ - } \ - } \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - state[ 4] = X##bu; \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - state[ 8] = X##go; \ - if (laneCount >= 9) { \ - output[ 8] = X##go; \ - } \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - state[12] = X##ki; \ - if (laneCount >= 13) { \ - output[12]= X##ki; \ - } \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[12] = X##ki; \ - output[12]= X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - state[12] = X##ki; \ - output[12]= X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - output[14] = X##ku; \ - state[15] = X##ma; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - state[16] = X##me; \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - state[17] = X##mi; \ - state[18] = X##mo; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - state[20] = X##sa; \ - if (laneCount >= 21) { \ - output[20] = X##sa; \ - } \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[20] = X##sa; \ - output[20] = X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - state[20] = X##sa; \ - output[20] = X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - output[22] = X##si; \ - state[23] = X##so; \ - output[23] = X##so; \ - state[24] = X##su; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define output(X, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - if (laneCount >= 3) { \ - output[ 2] = X##bi; \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - } \ - else { \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount >= 9) { \ - output[ 8] = X##go; \ - } \ - } \ - else { \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - } \ - else { \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - if (laneCount >= 13) { \ - output[12] = X##ki; \ - } \ - } \ - else { \ - output[12] = X##ki; \ - output[13] = X##ko; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - output[12] = X##ki; \ - output[13] = X##ko; \ - output[14] = X##ku; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - if (laneCount >= 21) { \ - output[20] = X##sa; \ - } \ - } \ - else { \ - output[20] = X##sa; \ - output[21] = X##se; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - output[20] = X##sa; \ - output[21] = X##se; \ - output[22] = X##si; \ - output[23] = X##so; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define wrapOne(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define wrapOneInvert(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define unwrapOne(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#define unwrapOneInvert(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#endif - -#define wrap(X, input, output, laneCount, trailingBits) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - X##be ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - if (laneCount < 3) { \ - X##bi ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 2, bi) \ - X##bo ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 4, bu) \ - X##ga ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - if (laneCount < 7) { \ - X##ge ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 6, ge) \ - X##gi ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - wrapOne(X, input, output, 6, ge) \ - wrapOne(X, input, output, 7, gi) \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - X##gu ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - if (laneCount < 11) { \ - X##ka ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 10, ka) \ - X##ke ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - wrapOne(X, input, output, 10, ka) \ - wrapOne(X, input, output, 11, ke) \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 12, ki) \ - X##ko ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 12, ki) \ - wrapOne(X, input, output, 13, ko) \ - if (laneCount < 15) { \ - X##ku ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 14, ku) \ - X##ma ^= trailingBits; \ - } \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - wrapOne(X, input, output, 6, ge) \ - wrapOne(X, input, output, 7, gi) \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - wrapOne(X, input, output, 10, ka) \ - wrapOne(X, input, output, 11, ke) \ - wrapOneInvert(X, input, output, 12, ki) \ - wrapOne(X, input, output, 13, ko) \ - wrapOne(X, input, output, 14, ku) \ - wrapOne(X, input, output, 15, ma) \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - X##mi ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - if (laneCount < 19) { \ - X##mo ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 18, mo) \ - X##mu ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - wrapOne(X, input, output, 18, mo) \ - wrapOne(X, input, output, 19, mu) \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 20, sa) \ - X##se ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 20, sa) \ - wrapOne(X, input, output, 21, se) \ - if (laneCount < 23) { \ - X##si ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 22, si) \ - X##so ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - wrapOne(X, input, output, 18, mo) \ - wrapOne(X, input, output, 19, mu) \ - wrapOneInvert(X, input, output, 20, sa) \ - wrapOne(X, input, output, 21, se) \ - wrapOne(X, input, output, 22, si) \ - wrapOne(X, input, output, 23, so) \ - if (laneCount < 25) { \ - X##su ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 24, su) \ - } \ - } \ - } - -#define unwrap(X, input, output, laneCount, trailingBits) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - X##be ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - if (laneCount < 3) { \ - X##bi ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 2, bi) \ - X##bo ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 4, bu) \ - X##ga ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - if (laneCount < 7) { \ - X##ge ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 6, ge) \ - X##gi ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - unwrapOne(X, input, output, 6, ge) \ - unwrapOne(X, input, output, 7, gi) \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - X##gu ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - if (laneCount < 11) { \ - X##ka ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 10, ka) \ - X##ke ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - unwrapOne(X, input, output, 10, ka) \ - unwrapOne(X, input, output, 11, ke) \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 12, ki) \ - X##ko ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 12, ki) \ - unwrapOne(X, input, output, 13, ko) \ - if (laneCount < 15) { \ - X##ku ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 14, ku) \ - X##ma ^= trailingBits; \ - } \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - unwrapOne(X, input, output, 6, ge) \ - unwrapOne(X, input, output, 7, gi) \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - unwrapOne(X, input, output, 10, ka) \ - unwrapOne(X, input, output, 11, ke) \ - unwrapOneInvert(X, input, output, 12, ki) \ - unwrapOne(X, input, output, 13, ko) \ - unwrapOne(X, input, output, 14, ku) \ - unwrapOne(X, input, output, 15, ma) \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - X##mi ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - if (laneCount < 19) { \ - X##mo ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 18, mo) \ - X##mu ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - unwrapOne(X, input, output, 18, mo) \ - unwrapOne(X, input, output, 19, mu) \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 20, sa) \ - X##se ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 20, sa) \ - unwrapOne(X, input, output, 21, se) \ - if (laneCount < 23) { \ - X##si ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 22, si) \ - X##so ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - unwrapOne(X, input, output, 18, mo) \ - unwrapOne(X, input, output, 19, mu) \ - unwrapOneInvert(X, input, output, 20, sa) \ - unwrapOne(X, input, output, 21, se) \ - unwrapOne(X, input, output, 22, si) \ - unwrapOne(X, input, output, 23, so) \ - if (laneCount < 25) { \ - X##su ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 24, su) \ - } \ - } \ - } +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define declareABCDE \ + UINT64 Aba, Abe, Abi, Abo, Abu; \ + UINT64 Aga, Age, Agi, Ago, Agu; \ + UINT64 Aka, Ake, Aki, Ako, Aku; \ + UINT64 Ama, Ame, Ami, Amo, Amu; \ + UINT64 Asa, Ase, Asi, Aso, Asu; \ + UINT64 Bba, Bbe, Bbi, Bbo, Bbu; \ + UINT64 Bga, Bge, Bgi, Bgo, Bgu; \ + UINT64 Bka, Bke, Bki, Bko, Bku; \ + UINT64 Bma, Bme, Bmi, Bmo, Bmu; \ + UINT64 Bsa, Bse, Bsi, Bso, Bsu; \ + UINT64 Ca, Ce, Ci, Co, Cu; \ + UINT64 Da, De, Di, Do, Du; \ + UINT64 Eba, Ebe, Ebi, Ebo, Ebu; \ + UINT64 Ega, Ege, Egi, Ego, Egu; \ + UINT64 Eka, Eke, Eki, Eko, Eku; \ + UINT64 Ema, Eme, Emi, Emo, Emu; \ + UINT64 Esa, Ese, Esi, Eso, Esu; \ + +#define prepareTheta \ + Ca = Aba^Aga^Aka^Ama^Asa; \ + Ce = Abe^Age^Ake^Ame^Ase; \ + Ci = Abi^Agi^Aki^Ami^Asi; \ + Co = Abo^Ago^Ako^Amo^Aso; \ + Cu = Abu^Agu^Aku^Amu^Asu; \ + +#ifdef UseBebigokimisa +/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ + +/* --- 64-bit lanes mapped to 64-bit words */ + +#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^( Bbe | Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + Ca = E##ba; \ + E##be = Bbe ^((~Bbi)| Bbo ); \ + Ce = E##be; \ + E##bi = Bbi ^( Bbo & Bbu ); \ + Ci = E##bi; \ + E##bo = Bbo ^( Bbu | Bba ); \ + Co = E##bo; \ + E##bu = Bbu ^( Bba & Bbe ); \ + Cu = E##bu; \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^( Bge | Bgi ); \ + Ca ^= E##ga; \ + E##ge = Bge ^( Bgi & Bgo ); \ + Ce ^= E##ge; \ + E##gi = Bgi ^( Bgo |(~Bgu)); \ + Ci ^= E##gi; \ + E##go = Bgo ^( Bgu | Bga ); \ + Co ^= E##go; \ + E##gu = Bgu ^( Bga & Bge ); \ + Cu ^= E##gu; \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^( Bke | Bki ); \ + Ca ^= E##ka; \ + E##ke = Bke ^( Bki & Bko ); \ + Ce ^= E##ke; \ + E##ki = Bki ^((~Bko)& Bku ); \ + Ci ^= E##ki; \ + E##ko = (~Bko)^( Bku | Bka ); \ + Co ^= E##ko; \ + E##ku = Bku ^( Bka & Bke ); \ + Cu ^= E##ku; \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^( Bme & Bmi ); \ + Ca ^= E##ma; \ + E##me = Bme ^( Bmi | Bmo ); \ + Ce ^= E##me; \ + E##mi = Bmi ^((~Bmo)| Bmu ); \ + Ci ^= E##mi; \ + E##mo = (~Bmo)^( Bmu & Bma ); \ + Co ^= E##mo; \ + E##mu = Bmu ^( Bma | Bme ); \ + Cu ^= E##mu; \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + Ca ^= E##sa; \ + E##se = (~Bse)^( Bsi | Bso ); \ + Ce ^= E##se; \ + E##si = Bsi ^( Bso & Bsu ); \ + Ci ^= E##si; \ + E##so = Bso ^( Bsu | Bsa ); \ + Co ^= E##so; \ + E##su = Bsu ^( Bsa & Bse ); \ + Cu ^= E##su; \ +\ + +/* --- Code for round (lane complementing pattern 'bebigokimisa') */ + +/* --- 64-bit lanes mapped to 64-bit words */ + +#define thetaRhoPiChiIota(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^( Bbe | Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + E##be = Bbe ^((~Bbi)| Bbo ); \ + E##bi = Bbi ^( Bbo & Bbu ); \ + E##bo = Bbo ^( Bbu | Bba ); \ + E##bu = Bbu ^( Bba & Bbe ); \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^( Bge | Bgi ); \ + E##ge = Bge ^( Bgi & Bgo ); \ + E##gi = Bgi ^( Bgo |(~Bgu)); \ + E##go = Bgo ^( Bgu | Bga ); \ + E##gu = Bgu ^( Bga & Bge ); \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^( Bke | Bki ); \ + E##ke = Bke ^( Bki & Bko ); \ + E##ki = Bki ^((~Bko)& Bku ); \ + E##ko = (~Bko)^( Bku | Bka ); \ + E##ku = Bku ^( Bka & Bke ); \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^( Bme & Bmi ); \ + E##me = Bme ^( Bmi | Bmo ); \ + E##mi = Bmi ^((~Bmo)| Bmu ); \ + E##mo = (~Bmo)^( Bmu & Bma ); \ + E##mu = Bmu ^( Bma | Bme ); \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + E##se = (~Bse)^( Bsi | Bso ); \ + E##si = Bsi ^( Bso & Bsu ); \ + E##so = Bso ^( Bsu | Bsa ); \ + E##su = Bsu ^( Bsa & Bse ); \ +\ + +#else /* UseBebigokimisa */ + +/* --- Code for round, with prepare-theta */ + +/* --- 64-bit lanes mapped to 64-bit words */ + +#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^((~Bbe)& Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + Ca = E##ba; \ + E##be = Bbe ^((~Bbi)& Bbo ); \ + Ce = E##be; \ + E##bi = Bbi ^((~Bbo)& Bbu ); \ + Ci = E##bi; \ + E##bo = Bbo ^((~Bbu)& Bba ); \ + Co = E##bo; \ + E##bu = Bbu ^((~Bba)& Bbe ); \ + Cu = E##bu; \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^((~Bge)& Bgi ); \ + Ca ^= E##ga; \ + E##ge = Bge ^((~Bgi)& Bgo ); \ + Ce ^= E##ge; \ + E##gi = Bgi ^((~Bgo)& Bgu ); \ + Ci ^= E##gi; \ + E##go = Bgo ^((~Bgu)& Bga ); \ + Co ^= E##go; \ + E##gu = Bgu ^((~Bga)& Bge ); \ + Cu ^= E##gu; \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^((~Bke)& Bki ); \ + Ca ^= E##ka; \ + E##ke = Bke ^((~Bki)& Bko ); \ + Ce ^= E##ke; \ + E##ki = Bki ^((~Bko)& Bku ); \ + Ci ^= E##ki; \ + E##ko = Bko ^((~Bku)& Bka ); \ + Co ^= E##ko; \ + E##ku = Bku ^((~Bka)& Bke ); \ + Cu ^= E##ku; \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^((~Bme)& Bmi ); \ + Ca ^= E##ma; \ + E##me = Bme ^((~Bmi)& Bmo ); \ + Ce ^= E##me; \ + E##mi = Bmi ^((~Bmo)& Bmu ); \ + Ci ^= E##mi; \ + E##mo = Bmo ^((~Bmu)& Bma ); \ + Co ^= E##mo; \ + E##mu = Bmu ^((~Bma)& Bme ); \ + Cu ^= E##mu; \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + Ca ^= E##sa; \ + E##se = Bse ^((~Bsi)& Bso ); \ + Ce ^= E##se; \ + E##si = Bsi ^((~Bso)& Bsu ); \ + Ci ^= E##si; \ + E##so = Bso ^((~Bsu)& Bsa ); \ + Co ^= E##so; \ + E##su = Bsu ^((~Bsa)& Bse ); \ + Cu ^= E##su; \ +\ + +/* --- Code for round */ + +/* --- 64-bit lanes mapped to 64-bit words */ + +#define thetaRhoPiChiIota(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^((~Bbe)& Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + E##be = Bbe ^((~Bbi)& Bbo ); \ + E##bi = Bbi ^((~Bbo)& Bbu ); \ + E##bo = Bbo ^((~Bbu)& Bba ); \ + E##bu = Bbu ^((~Bba)& Bbe ); \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^((~Bge)& Bgi ); \ + E##ge = Bge ^((~Bgi)& Bgo ); \ + E##gi = Bgi ^((~Bgo)& Bgu ); \ + E##go = Bgo ^((~Bgu)& Bga ); \ + E##gu = Bgu ^((~Bga)& Bge ); \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^((~Bke)& Bki ); \ + E##ke = Bke ^((~Bki)& Bko ); \ + E##ki = Bki ^((~Bko)& Bku ); \ + E##ko = Bko ^((~Bku)& Bka ); \ + E##ku = Bku ^((~Bka)& Bke ); \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^((~Bme)& Bmi ); \ + E##me = Bme ^((~Bmi)& Bmo ); \ + E##mi = Bmi ^((~Bmo)& Bmu ); \ + E##mo = Bmo ^((~Bmu)& Bma ); \ + E##mu = Bmu ^((~Bma)& Bme ); \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + E##se = Bse ^((~Bsi)& Bso ); \ + E##si = Bsi ^((~Bso)& Bsu ); \ + E##so = Bso ^((~Bsu)& Bsa ); \ + E##su = Bsu ^((~Bsa)& Bse ); \ +\ + +#endif /* UseBebigokimisa */ + + +#define copyFromState(X, state) \ + X##ba = state[ 0]; \ + X##be = state[ 1]; \ + X##bi = state[ 2]; \ + X##bo = state[ 3]; \ + X##bu = state[ 4]; \ + X##ga = state[ 5]; \ + X##ge = state[ 6]; \ + X##gi = state[ 7]; \ + X##go = state[ 8]; \ + X##gu = state[ 9]; \ + X##ka = state[10]; \ + X##ke = state[11]; \ + X##ki = state[12]; \ + X##ko = state[13]; \ + X##ku = state[14]; \ + X##ma = state[15]; \ + X##me = state[16]; \ + X##mi = state[17]; \ + X##mo = state[18]; \ + X##mu = state[19]; \ + X##sa = state[20]; \ + X##se = state[21]; \ + X##si = state[22]; \ + X##so = state[23]; \ + X##su = state[24]; \ + +#define copyToState(state, X) \ + state[ 0] = X##ba; \ + state[ 1] = X##be; \ + state[ 2] = X##bi; \ + state[ 3] = X##bo; \ + state[ 4] = X##bu; \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + state[ 7] = X##gi; \ + state[ 8] = X##go; \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + state[15] = X##ma; \ + state[16] = X##me; \ + state[17] = X##mi; \ + state[18] = X##mo; \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + state[23] = X##so; \ + state[24] = X##su; \ + +#define copyStateVariables(X, Y) \ + X##ba = Y##ba; \ + X##be = Y##be; \ + X##bi = Y##bi; \ + X##bo = Y##bo; \ + X##bu = Y##bu; \ + X##ga = Y##ga; \ + X##ge = Y##ge; \ + X##gi = Y##gi; \ + X##go = Y##go; \ + X##gu = Y##gu; \ + X##ka = Y##ka; \ + X##ke = Y##ke; \ + X##ki = Y##ki; \ + X##ko = Y##ko; \ + X##ku = Y##ku; \ + X##ma = Y##ma; \ + X##me = Y##me; \ + X##mi = Y##mi; \ + X##mo = Y##mo; \ + X##mu = Y##mu; \ + X##sa = Y##sa; \ + X##se = Y##se; \ + X##si = Y##si; \ + X##so = Y##so; \ + X##su = Y##su; \ + +#define copyFromStateAndAdd(X, state, input, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + X##ba = state[ 0]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + } \ + X##be = state[ 1]; \ + X##bi = state[ 2]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + X##be = state[ 1]^input[ 1]; \ + if (laneCount < 3) { \ + X##bi = state[ 2]; \ + } \ + else { \ + X##bi = state[ 2]^input[ 2]; \ + } \ + } \ + X##bo = state[ 3]; \ + X##bu = state[ 4]; \ + X##ga = state[ 5]; \ + X##ge = state[ 6]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + X##be = state[ 1]^input[ 1]; \ + X##bi = state[ 2]^input[ 2]; \ + X##bo = state[ 3]^input[ 3]; \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + X##bu = state[ 4]; \ + } \ + else { \ + X##bu = state[ 4]^input[ 4]; \ + } \ + X##ga = state[ 5]; \ + X##ge = state[ 6]; \ + } \ + else { \ + X##bu = state[ 4]^input[ 4]; \ + X##ga = state[ 5]^input[ 5]; \ + if (laneCount < 7) { \ + X##ge = state[ 6]; \ + } \ + else { \ + X##ge = state[ 6]^input[ 6]; \ + } \ + } \ + } \ + X##gi = state[ 7]; \ + X##go = state[ 8]; \ + X##gu = state[ 9]; \ + X##ka = state[10]; \ + X##ke = state[11]; \ + X##ki = state[12]; \ + X##ko = state[13]; \ + X##ku = state[14]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + X##be = state[ 1]^input[ 1]; \ + X##bi = state[ 2]^input[ 2]; \ + X##bo = state[ 3]^input[ 3]; \ + X##bu = state[ 4]^input[ 4]; \ + X##ga = state[ 5]^input[ 5]; \ + X##ge = state[ 6]^input[ 6]; \ + X##gi = state[ 7]^input[ 7]; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + X##go = state[ 8]; \ + } \ + else { \ + X##go = state[ 8]^input[ 8]; \ + } \ + X##gu = state[ 9]; \ + X##ka = state[10]; \ + } \ + else { \ + X##go = state[ 8]^input[ 8]; \ + X##gu = state[ 9]^input[ 9]; \ + if (laneCount < 11) { \ + X##ka = state[10]; \ + } \ + else { \ + X##ka = state[10]^input[10]; \ + } \ + } \ + X##ke = state[11]; \ + X##ki = state[12]; \ + X##ko = state[13]; \ + X##ku = state[14]; \ + } \ + else { \ + X##go = state[ 8]^input[ 8]; \ + X##gu = state[ 9]^input[ 9]; \ + X##ka = state[10]^input[10]; \ + X##ke = state[11]^input[11]; \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + X##ki = state[12]; \ + } \ + else { \ + X##ki = state[12]^input[12]; \ + } \ + X##ko = state[13]; \ + X##ku = state[14]; \ + } \ + else { \ + X##ki = state[12]^input[12]; \ + X##ko = state[13]^input[13]; \ + if (laneCount < 15) { \ + X##ku = state[14]; \ + } \ + else { \ + X##ku = state[14]^input[14]; \ + } \ + } \ + } \ + } \ + X##ma = state[15]; \ + X##me = state[16]; \ + X##mi = state[17]; \ + X##mo = state[18]; \ + X##mu = state[19]; \ + X##sa = state[20]; \ + X##se = state[21]; \ + X##si = state[22]; \ + X##so = state[23]; \ + X##su = state[24]; \ + } \ + else { \ + X##ba = state[ 0]^input[ 0]; \ + X##be = state[ 1]^input[ 1]; \ + X##bi = state[ 2]^input[ 2]; \ + X##bo = state[ 3]^input[ 3]; \ + X##bu = state[ 4]^input[ 4]; \ + X##ga = state[ 5]^input[ 5]; \ + X##ge = state[ 6]^input[ 6]; \ + X##gi = state[ 7]^input[ 7]; \ + X##go = state[ 8]^input[ 8]; \ + X##gu = state[ 9]^input[ 9]; \ + X##ka = state[10]^input[10]; \ + X##ke = state[11]^input[11]; \ + X##ki = state[12]^input[12]; \ + X##ko = state[13]^input[13]; \ + X##ku = state[14]^input[14]; \ + X##ma = state[15]^input[15]; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + X##me = state[16]; \ + } \ + else { \ + X##me = state[16]^input[16]; \ + } \ + X##mi = state[17]; \ + X##mo = state[18]; \ + } \ + else { \ + X##me = state[16]^input[16]; \ + X##mi = state[17]^input[17]; \ + if (laneCount < 19) { \ + X##mo = state[18]; \ + } \ + else { \ + X##mo = state[18]^input[18]; \ + } \ + } \ + X##mu = state[19]; \ + X##sa = state[20]; \ + X##se = state[21]; \ + X##si = state[22]; \ + } \ + else { \ + X##me = state[16]^input[16]; \ + X##mi = state[17]^input[17]; \ + X##mo = state[18]^input[18]; \ + X##mu = state[19]^input[19]; \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + X##sa = state[20]; \ + } \ + else { \ + X##sa = state[20]^input[20]; \ + } \ + X##se = state[21]; \ + X##si = state[22]; \ + } \ + else { \ + X##sa = state[20]^input[20]; \ + X##se = state[21]^input[21]; \ + if (laneCount < 23) { \ + X##si = state[22]; \ + } \ + else { \ + X##si = state[22]^input[22]; \ + } \ + } \ + } \ + X##so = state[23]; \ + X##su = state[24]; \ + } \ + else { \ + X##me = state[16]^input[16]; \ + X##mi = state[17]^input[17]; \ + X##mo = state[18]^input[18]; \ + X##mu = state[19]^input[19]; \ + X##sa = state[20]^input[20]; \ + X##se = state[21]^input[21]; \ + X##si = state[22]^input[22]; \ + X##so = state[23]^input[23]; \ + if (laneCount < 25) { \ + X##su = state[24]; \ + } \ + else { \ + X##su = state[24]^input[24]; \ + } \ + } \ + } + +#define addInput(X, input, laneCount) \ + if (laneCount == 21) { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + X##bi ^= input[ 2]; \ + X##bo ^= input[ 3]; \ + X##bu ^= input[ 4]; \ + X##ga ^= input[ 5]; \ + X##ge ^= input[ 6]; \ + X##gi ^= input[ 7]; \ + X##go ^= input[ 8]; \ + X##gu ^= input[ 9]; \ + X##ka ^= input[10]; \ + X##ke ^= input[11]; \ + X##ki ^= input[12]; \ + X##ko ^= input[13]; \ + X##ku ^= input[14]; \ + X##ma ^= input[15]; \ + X##me ^= input[16]; \ + X##mi ^= input[17]; \ + X##mo ^= input[18]; \ + X##mu ^= input[19]; \ + X##sa ^= input[20]; \ + } \ + else if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + } \ + else { \ + X##ba ^= input[ 0]; \ + } \ + } \ + else { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + if (laneCount < 3) { \ + } \ + else { \ + X##bi ^= input[ 2]; \ + } \ + } \ + } \ + else { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + X##bi ^= input[ 2]; \ + X##bo ^= input[ 3]; \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + } \ + else { \ + X##bu ^= input[ 4]; \ + } \ + } \ + else { \ + X##bu ^= input[ 4]; \ + X##ga ^= input[ 5]; \ + if (laneCount < 7) { \ + } \ + else { \ + X##ge ^= input[ 6]; \ + } \ + } \ + } \ + } \ + else { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + X##bi ^= input[ 2]; \ + X##bo ^= input[ 3]; \ + X##bu ^= input[ 4]; \ + X##ga ^= input[ 5]; \ + X##ge ^= input[ 6]; \ + X##gi ^= input[ 7]; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + } \ + else { \ + X##go ^= input[ 8]; \ + } \ + } \ + else { \ + X##go ^= input[ 8]; \ + X##gu ^= input[ 9]; \ + if (laneCount < 11) { \ + } \ + else { \ + X##ka ^= input[10]; \ + } \ + } \ + } \ + else { \ + X##go ^= input[ 8]; \ + X##gu ^= input[ 9]; \ + X##ka ^= input[10]; \ + X##ke ^= input[11]; \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + } \ + else { \ + X##ki ^= input[12]; \ + } \ + } \ + else { \ + X##ki ^= input[12]; \ + X##ko ^= input[13]; \ + if (laneCount < 15) { \ + } \ + else { \ + X##ku ^= input[14]; \ + } \ + } \ + } \ + } \ + } \ + else { \ + X##ba ^= input[ 0]; \ + X##be ^= input[ 1]; \ + X##bi ^= input[ 2]; \ + X##bo ^= input[ 3]; \ + X##bu ^= input[ 4]; \ + X##ga ^= input[ 5]; \ + X##ge ^= input[ 6]; \ + X##gi ^= input[ 7]; \ + X##go ^= input[ 8]; \ + X##gu ^= input[ 9]; \ + X##ka ^= input[10]; \ + X##ke ^= input[11]; \ + X##ki ^= input[12]; \ + X##ko ^= input[13]; \ + X##ku ^= input[14]; \ + X##ma ^= input[15]; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + } \ + else { \ + X##me ^= input[16]; \ + } \ + } \ + else { \ + X##me ^= input[16]; \ + X##mi ^= input[17]; \ + if (laneCount < 19) { \ + } \ + else { \ + X##mo ^= input[18]; \ + } \ + } \ + } \ + else { \ + X##me ^= input[16]; \ + X##mi ^= input[17]; \ + X##mo ^= input[18]; \ + X##mu ^= input[19]; \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + } \ + else { \ + X##sa ^= input[20]; \ + } \ + } \ + else { \ + X##sa ^= input[20]; \ + X##se ^= input[21]; \ + if (laneCount < 23) { \ + } \ + else { \ + X##si ^= input[22]; \ + } \ + } \ + } \ + } \ + else { \ + X##me ^= input[16]; \ + X##mi ^= input[17]; \ + X##mo ^= input[18]; \ + X##mu ^= input[19]; \ + X##sa ^= input[20]; \ + X##se ^= input[21]; \ + X##si ^= input[22]; \ + X##so ^= input[23]; \ + if (laneCount < 25) { \ + } \ + else { \ + X##su ^= input[24]; \ + } \ + } \ + } + +#ifdef UseBebigokimisa + +#define copyToStateAndOutput(X, state, output, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + state[ 0] = X##ba; \ + if (laneCount >= 1) { \ + output[ 0] = X##ba; \ + } \ + state[ 1] = X##be; \ + state[ 2] = X##bi; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = ~X##be; \ + state[ 2] = X##bi; \ + if (laneCount >= 3) { \ + output[ 2] = ~X##bi; \ + } \ + } \ + state[ 3] = X##bo; \ + state[ 4] = X##bu; \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = ~X##be; \ + state[ 2] = X##bi; \ + output[ 2] = ~X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + if (laneCount < 6) { \ + state[ 4] = X##bu; \ + if (laneCount >= 5) { \ + output[ 4] = X##bu; \ + } \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + } \ + else { \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + if (laneCount >= 7) { \ + output[ 6] = X##ge; \ + } \ + } \ + } \ + state[ 7] = X##gi; \ + state[ 8] = X##go; \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = ~X##be; \ + state[ 2] = X##bi; \ + output[ 2] = ~X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + output[ 6] = X##ge; \ + state[ 7] = X##gi; \ + output[ 7] = X##gi; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + state[ 8] = X##go; \ + if (laneCount >= 9) { \ + output[ 8] = ~X##go; \ + } \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + } \ + else { \ + state[ 8] = X##go; \ + output[ 8] = ~X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + if (laneCount >= 11) { \ + output[10] = X##ka; \ + } \ + } \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[ 8] = X##go; \ + output[ 8] = ~X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + output[10] = X##ka; \ + state[11] = X##ke; \ + output[11] = X##ke; \ + if (laneCount < 14) { \ + state[12] = X##ki; \ + if (laneCount >= 13) { \ + output[12] = ~X##ki; \ + } \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[12] = X##ki; \ + output[12] = ~X##ki; \ + state[13] = X##ko; \ + output[13] = X##ko; \ + state[14] = X##ku; \ + if (laneCount >= 15) { \ + output[14] = X##ku; \ + } \ + } \ + } \ + } \ + state[15] = X##ma; \ + state[16] = X##me; \ + state[17] = X##mi; \ + state[18] = X##mo; \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + state[23] = X##so; \ + state[24] = X##su; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = ~X##be; \ + state[ 2] = X##bi; \ + output[ 2] = ~X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + output[ 6] = X##ge; \ + state[ 7] = X##gi; \ + output[ 7] = X##gi; \ + state[ 8] = X##go; \ + output[ 8] = ~X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + output[10] = X##ka; \ + state[11] = X##ke; \ + output[11] = X##ke; \ + state[12] = X##ki; \ + output[12] = ~X##ki; \ + state[13] = X##ko; \ + output[13] = X##ko; \ + state[14] = X##ku; \ + output[14] = X##ku; \ + state[15] = X##ma; \ + output[15] = X##ma; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + state[16] = X##me; \ + if (laneCount >= 17) { \ + output[16] = X##me; \ + } \ + state[17] = X##mi; \ + state[18] = X##mo; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = ~X##mi; \ + state[18] = X##mo; \ + if (laneCount >= 19) { \ + output[18] = X##mo; \ + } \ + } \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = ~X##mi; \ + state[18] = X##mo; \ + output[18] = X##mo; \ + state[19] = X##mu; \ + output[19] = X##mu; \ + if (laneCount < 22) { \ + state[20] = X##sa; \ + if (laneCount >= 21) { \ + output[20] = ~X##sa; \ + } \ + state[21] = X##se; \ + state[22] = X##si; \ + } \ + else { \ + state[20] = X##sa; \ + output[20] = ~X##sa; \ + state[21] = X##se; \ + output[21] = X##se; \ + state[22] = X##si; \ + if (laneCount >= 23) { \ + output[22] = X##si; \ + } \ + } \ + } \ + state[23] = X##so; \ + state[24] = X##su; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = ~X##mi; \ + state[18] = X##mo; \ + output[18] = X##mo; \ + state[19] = X##mu; \ + output[19] = X##mu; \ + state[20] = X##sa; \ + output[20] = ~X##sa; \ + state[21] = X##se; \ + output[21] = X##se; \ + state[22] = X##si; \ + output[22] = X##si; \ + state[23] = X##so; \ + output[23] = X##so; \ + state[24] = X##su; \ + if (laneCount >= 25) { \ + output[24] = X##su; \ + } \ + } \ + } + +#define output(X, output, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount >= 1) { \ + output[ 0] = X##ba; \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = ~X##be; \ + if (laneCount >= 3) { \ + output[ 2] = ~X##bi; \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = ~X##be; \ + output[ 2] = ~X##bi; \ + output[ 3] = X##bo; \ + if (laneCount < 6) { \ + if (laneCount >= 5) { \ + output[ 4] = X##bu; \ + } \ + } \ + else { \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + if (laneCount >= 7) { \ + output[ 6] = X##ge; \ + } \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = ~X##be; \ + output[ 2] = ~X##bi; \ + output[ 3] = X##bo; \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + output[ 6] = X##ge; \ + output[ 7] = X##gi; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount >= 9) { \ + output[ 8] = ~X##go; \ + } \ + } \ + else { \ + output[ 8] = ~X##go; \ + output[ 9] = X##gu; \ + if (laneCount >= 11) { \ + output[10] = X##ka; \ + } \ + } \ + } \ + else { \ + output[ 8] = ~X##go; \ + output[ 9] = X##gu; \ + output[10] = X##ka; \ + output[11] = X##ke; \ + if (laneCount < 14) { \ + if (laneCount >= 13) { \ + output[12] = ~X##ki; \ + } \ + } \ + else { \ + output[12] = ~X##ki; \ + output[13] = X##ko; \ + if (laneCount >= 15) { \ + output[14] = X##ku; \ + } \ + } \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = ~X##be; \ + output[ 2] = ~X##bi; \ + output[ 3] = X##bo; \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + output[ 6] = X##ge; \ + output[ 7] = X##gi; \ + output[ 8] = ~X##go; \ + output[ 9] = X##gu; \ + output[10] = X##ka; \ + output[11] = X##ke; \ + output[12] = ~X##ki; \ + output[13] = X##ko; \ + output[14] = X##ku; \ + output[15] = X##ma; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount >= 17) { \ + output[16] = X##me; \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = ~X##mi; \ + if (laneCount >= 19) { \ + output[18] = X##mo; \ + } \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = ~X##mi; \ + output[18] = X##mo; \ + output[19] = X##mu; \ + if (laneCount < 22) { \ + if (laneCount >= 21) { \ + output[20] = ~X##sa; \ + } \ + } \ + else { \ + output[20] = ~X##sa; \ + output[21] = X##se; \ + if (laneCount >= 23) { \ + output[22] = X##si; \ + } \ + } \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = ~X##mi; \ + output[18] = X##mo; \ + output[19] = X##mu; \ + output[20] = ~X##sa; \ + output[21] = X##se; \ + output[22] = X##si; \ + output[23] = X##so; \ + if (laneCount >= 25) { \ + output[24] = X##su; \ + } \ + } \ + } + +#define wrapOne(X, input, output, index, name) \ + X##name ^= input[index]; \ + output[index] = X##name; + +#define wrapOneInvert(X, input, output, index, name) \ + X##name ^= input[index]; \ + output[index] = ~X##name; + +#define unwrapOne(X, input, output, index, name) \ + output[index] = input[index] ^ X##name; \ + X##name ^= output[index]; + +#define unwrapOneInvert(X, input, output, index, name) \ + output[index] = ~(input[index] ^ X##name); \ + X##name ^= output[index]; \ + +#else /* UseBebigokimisa */ + + +#define copyToStateAndOutput(X, state, output, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + state[ 0] = X##ba; \ + if (laneCount >= 1) { \ + output[ 0] = X##ba; \ + } \ + state[ 1] = X##be; \ + state[ 2] = X##bi; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = X##be; \ + state[ 2] = X##bi; \ + if (laneCount >= 3) { \ + output[ 2] = X##bi; \ + } \ + } \ + state[ 3] = X##bo; \ + state[ 4] = X##bu; \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = X##be; \ + state[ 2] = X##bi; \ + output[ 2] = X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + if (laneCount < 6) { \ + state[ 4] = X##bu; \ + if (laneCount >= 5) { \ + output[ 4] = X##bu; \ + } \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + } \ + else { \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + if (laneCount >= 7) { \ + output[ 6] = X##ge; \ + } \ + } \ + } \ + state[ 7] = X##gi; \ + state[ 8] = X##go; \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = X##be; \ + state[ 2] = X##bi; \ + output[ 2] = X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + output[ 6] = X##ge; \ + state[ 7] = X##gi; \ + output[ 7] = X##gi; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + state[ 8] = X##go; \ + if (laneCount >= 9) { \ + output[ 8] = X##go; \ + } \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + } \ + else { \ + state[ 8] = X##go; \ + output[ 8] = X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + if (laneCount >= 11) { \ + output[10] = X##ka; \ + } \ + } \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[ 8] = X##go; \ + output[ 8] = X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + output[10] = X##ka; \ + state[11] = X##ke; \ + output[11] = X##ke; \ + if (laneCount < 14) { \ + state[12] = X##ki; \ + if (laneCount >= 13) { \ + output[12]= X##ki; \ + } \ + state[13] = X##ko; \ + state[14] = X##ku; \ + } \ + else { \ + state[12] = X##ki; \ + output[12]= X##ki; \ + state[13] = X##ko; \ + output[13] = X##ko; \ + state[14] = X##ku; \ + if (laneCount >= 15) { \ + output[14] = X##ku; \ + } \ + } \ + } \ + } \ + state[15] = X##ma; \ + state[16] = X##me; \ + state[17] = X##mi; \ + state[18] = X##mo; \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + state[23] = X##so; \ + state[24] = X##su; \ + } \ + else { \ + state[ 0] = X##ba; \ + output[ 0] = X##ba; \ + state[ 1] = X##be; \ + output[ 1] = X##be; \ + state[ 2] = X##bi; \ + output[ 2] = X##bi; \ + state[ 3] = X##bo; \ + output[ 3] = X##bo; \ + state[ 4] = X##bu; \ + output[ 4] = X##bu; \ + state[ 5] = X##ga; \ + output[ 5] = X##ga; \ + state[ 6] = X##ge; \ + output[ 6] = X##ge; \ + state[ 7] = X##gi; \ + output[ 7] = X##gi; \ + state[ 8] = X##go; \ + output[ 8] = X##go; \ + state[ 9] = X##gu; \ + output[ 9] = X##gu; \ + state[10] = X##ka; \ + output[10] = X##ka; \ + state[11] = X##ke; \ + output[11] = X##ke; \ + state[12] = X##ki; \ + output[12]= X##ki; \ + state[13] = X##ko; \ + output[13] = X##ko; \ + state[14] = X##ku; \ + output[14] = X##ku; \ + state[15] = X##ma; \ + output[15] = X##ma; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + state[16] = X##me; \ + if (laneCount >= 17) { \ + output[16] = X##me; \ + } \ + state[17] = X##mi; \ + state[18] = X##mo; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = X##mi; \ + state[18] = X##mo; \ + if (laneCount >= 19) { \ + output[18] = X##mo; \ + } \ + } \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = X##mi; \ + state[18] = X##mo; \ + output[18] = X##mo; \ + state[19] = X##mu; \ + output[19] = X##mu; \ + if (laneCount < 22) { \ + state[20] = X##sa; \ + if (laneCount >= 21) { \ + output[20] = X##sa; \ + } \ + state[21] = X##se; \ + state[22] = X##si; \ + } \ + else { \ + state[20] = X##sa; \ + output[20] = X##sa; \ + state[21] = X##se; \ + output[21] = X##se; \ + state[22] = X##si; \ + if (laneCount >= 23) { \ + output[22] = X##si; \ + } \ + } \ + } \ + state[23] = X##so; \ + state[24] = X##su; \ + } \ + else { \ + state[16] = X##me; \ + output[16] = X##me; \ + state[17] = X##mi; \ + output[17] = X##mi; \ + state[18] = X##mo; \ + output[18] = X##mo; \ + state[19] = X##mu; \ + output[19] = X##mu; \ + state[20] = X##sa; \ + output[20] = X##sa; \ + state[21] = X##se; \ + output[21] = X##se; \ + state[22] = X##si; \ + output[22] = X##si; \ + state[23] = X##so; \ + output[23] = X##so; \ + state[24] = X##su; \ + if (laneCount >= 25) { \ + output[24] = X##su; \ + } \ + } \ + } + +#define output(X, output, laneCount) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount >= 1) { \ + output[ 0] = X##ba; \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = X##be; \ + if (laneCount >= 3) { \ + output[ 2] = X##bi; \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = X##be; \ + output[ 2] = X##bi; \ + output[ 3] = X##bo; \ + if (laneCount < 6) { \ + if (laneCount >= 5) { \ + output[ 4] = X##bu; \ + } \ + } \ + else { \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + if (laneCount >= 7) { \ + output[ 6] = X##ge; \ + } \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = X##be; \ + output[ 2] = X##bi; \ + output[ 3] = X##bo; \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + output[ 6] = X##ge; \ + output[ 7] = X##gi; \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount >= 9) { \ + output[ 8] = X##go; \ + } \ + } \ + else { \ + output[ 8] = X##go; \ + output[ 9] = X##gu; \ + if (laneCount >= 11) { \ + output[10] = X##ka; \ + } \ + } \ + } \ + else { \ + output[ 8] = X##go; \ + output[ 9] = X##gu; \ + output[10] = X##ka; \ + output[11] = X##ke; \ + if (laneCount < 14) { \ + if (laneCount >= 13) { \ + output[12] = X##ki; \ + } \ + } \ + else { \ + output[12] = X##ki; \ + output[13] = X##ko; \ + if (laneCount >= 15) { \ + output[14] = X##ku; \ + } \ + } \ + } \ + } \ + } \ + else { \ + output[ 0] = X##ba; \ + output[ 1] = X##be; \ + output[ 2] = X##bi; \ + output[ 3] = X##bo; \ + output[ 4] = X##bu; \ + output[ 5] = X##ga; \ + output[ 6] = X##ge; \ + output[ 7] = X##gi; \ + output[ 8] = X##go; \ + output[ 9] = X##gu; \ + output[10] = X##ka; \ + output[11] = X##ke; \ + output[12] = X##ki; \ + output[13] = X##ko; \ + output[14] = X##ku; \ + output[15] = X##ma; \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount >= 17) { \ + output[16] = X##me; \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = X##mi; \ + if (laneCount >= 19) { \ + output[18] = X##mo; \ + } \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = X##mi; \ + output[18] = X##mo; \ + output[19] = X##mu; \ + if (laneCount < 22) { \ + if (laneCount >= 21) { \ + output[20] = X##sa; \ + } \ + } \ + else { \ + output[20] = X##sa; \ + output[21] = X##se; \ + if (laneCount >= 23) { \ + output[22] = X##si; \ + } \ + } \ + } \ + } \ + else { \ + output[16] = X##me; \ + output[17] = X##mi; \ + output[18] = X##mo; \ + output[19] = X##mu; \ + output[20] = X##sa; \ + output[21] = X##se; \ + output[22] = X##si; \ + output[23] = X##so; \ + if (laneCount >= 25) { \ + output[24] = X##su; \ + } \ + } \ + } + +#define wrapOne(X, input, output, index, name) \ + X##name ^= input[index]; \ + output[index] = X##name; + +#define wrapOneInvert(X, input, output, index, name) \ + X##name ^= input[index]; \ + output[index] = X##name; + +#define unwrapOne(X, input, output, index, name) \ + output[index] = input[index] ^ X##name; \ + X##name ^= output[index]; + +#define unwrapOneInvert(X, input, output, index, name) \ + output[index] = input[index] ^ X##name; \ + X##name ^= output[index]; + +#endif + +#define wrap(X, input, output, laneCount, trailingBits) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + X##ba ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + X##be ^= trailingBits; \ + } \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + wrapOneInvert(X, input, output, 1, be) \ + if (laneCount < 3) { \ + X##bi ^= trailingBits; \ + } \ + else { \ + wrapOneInvert(X, input, output, 2, bi) \ + X##bo ^= trailingBits; \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + wrapOneInvert(X, input, output, 1, be) \ + wrapOneInvert(X, input, output, 2, bi) \ + wrapOne(X, input, output, 3, bo) \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + X##bu ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 4, bu) \ + X##ga ^= trailingBits; \ + } \ + } \ + else { \ + wrapOne(X, input, output, 4, bu) \ + wrapOne(X, input, output, 5, ga) \ + if (laneCount < 7) { \ + X##ge ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 6, ge) \ + X##gi ^= trailingBits; \ + } \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + wrapOneInvert(X, input, output, 1, be) \ + wrapOneInvert(X, input, output, 2, bi) \ + wrapOne(X, input, output, 3, bo) \ + wrapOne(X, input, output, 4, bu) \ + wrapOne(X, input, output, 5, ga) \ + wrapOne(X, input, output, 6, ge) \ + wrapOne(X, input, output, 7, gi) \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + X##go ^= trailingBits; \ + } \ + else { \ + wrapOneInvert(X, input, output, 8, go) \ + X##gu ^= trailingBits; \ + } \ + } \ + else { \ + wrapOneInvert(X, input, output, 8, go) \ + wrapOne(X, input, output, 9, gu) \ + if (laneCount < 11) { \ + X##ka ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 10, ka) \ + X##ke ^= trailingBits; \ + } \ + } \ + } \ + else { \ + wrapOneInvert(X, input, output, 8, go) \ + wrapOne(X, input, output, 9, gu) \ + wrapOne(X, input, output, 10, ka) \ + wrapOne(X, input, output, 11, ke) \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + X##ki ^= trailingBits; \ + } \ + else { \ + wrapOneInvert(X, input, output, 12, ki) \ + X##ko ^= trailingBits; \ + } \ + } \ + else { \ + wrapOneInvert(X, input, output, 12, ki) \ + wrapOne(X, input, output, 13, ko) \ + if (laneCount < 15) { \ + X##ku ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 14, ku) \ + X##ma ^= trailingBits; \ + } \ + } \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 0, ba) \ + wrapOneInvert(X, input, output, 1, be) \ + wrapOneInvert(X, input, output, 2, bi) \ + wrapOne(X, input, output, 3, bo) \ + wrapOne(X, input, output, 4, bu) \ + wrapOne(X, input, output, 5, ga) \ + wrapOne(X, input, output, 6, ge) \ + wrapOne(X, input, output, 7, gi) \ + wrapOneInvert(X, input, output, 8, go) \ + wrapOne(X, input, output, 9, gu) \ + wrapOne(X, input, output, 10, ka) \ + wrapOne(X, input, output, 11, ke) \ + wrapOneInvert(X, input, output, 12, ki) \ + wrapOne(X, input, output, 13, ko) \ + wrapOne(X, input, output, 14, ku) \ + wrapOne(X, input, output, 15, ma) \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + X##me ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 16, me) \ + X##mi ^= trailingBits; \ + } \ + } \ + else { \ + wrapOne(X, input, output, 16, me) \ + wrapOneInvert(X, input, output, 17, mi) \ + if (laneCount < 19) { \ + X##mo ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 18, mo) \ + X##mu ^= trailingBits; \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 16, me) \ + wrapOneInvert(X, input, output, 17, mi) \ + wrapOne(X, input, output, 18, mo) \ + wrapOne(X, input, output, 19, mu) \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + X##sa ^= trailingBits; \ + } \ + else { \ + wrapOneInvert(X, input, output, 20, sa) \ + X##se ^= trailingBits; \ + } \ + } \ + else { \ + wrapOneInvert(X, input, output, 20, sa) \ + wrapOne(X, input, output, 21, se) \ + if (laneCount < 23) { \ + X##si ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 22, si) \ + X##so ^= trailingBits; \ + } \ + } \ + } \ + } \ + else { \ + wrapOne(X, input, output, 16, me) \ + wrapOneInvert(X, input, output, 17, mi) \ + wrapOne(X, input, output, 18, mo) \ + wrapOne(X, input, output, 19, mu) \ + wrapOneInvert(X, input, output, 20, sa) \ + wrapOne(X, input, output, 21, se) \ + wrapOne(X, input, output, 22, si) \ + wrapOne(X, input, output, 23, so) \ + if (laneCount < 25) { \ + X##su ^= trailingBits; \ + } \ + else { \ + wrapOne(X, input, output, 24, su) \ + } \ + } \ + } + +#define unwrap(X, input, output, laneCount, trailingBits) \ + if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + X##ba ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + X##be ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + unwrapOneInvert(X, input, output, 1, be) \ + if (laneCount < 3) { \ + X##bi ^= trailingBits; \ + } \ + else { \ + unwrapOneInvert(X, input, output, 2, bi) \ + X##bo ^= trailingBits; \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + unwrapOneInvert(X, input, output, 1, be) \ + unwrapOneInvert(X, input, output, 2, bi) \ + unwrapOne(X, input, output, 3, bo) \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + X##bu ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 4, bu) \ + X##ga ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 4, bu) \ + unwrapOne(X, input, output, 5, ga) \ + if (laneCount < 7) { \ + X##ge ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 6, ge) \ + X##gi ^= trailingBits; \ + } \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + unwrapOneInvert(X, input, output, 1, be) \ + unwrapOneInvert(X, input, output, 2, bi) \ + unwrapOne(X, input, output, 3, bo) \ + unwrapOne(X, input, output, 4, bu) \ + unwrapOne(X, input, output, 5, ga) \ + unwrapOne(X, input, output, 6, ge) \ + unwrapOne(X, input, output, 7, gi) \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + X##go ^= trailingBits; \ + } \ + else { \ + unwrapOneInvert(X, input, output, 8, go) \ + X##gu ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOneInvert(X, input, output, 8, go) \ + unwrapOne(X, input, output, 9, gu) \ + if (laneCount < 11) { \ + X##ka ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 10, ka) \ + X##ke ^= trailingBits; \ + } \ + } \ + } \ + else { \ + unwrapOneInvert(X, input, output, 8, go) \ + unwrapOne(X, input, output, 9, gu) \ + unwrapOne(X, input, output, 10, ka) \ + unwrapOne(X, input, output, 11, ke) \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + X##ki ^= trailingBits; \ + } \ + else { \ + unwrapOneInvert(X, input, output, 12, ki) \ + X##ko ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOneInvert(X, input, output, 12, ki) \ + unwrapOne(X, input, output, 13, ko) \ + if (laneCount < 15) { \ + X##ku ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 14, ku) \ + X##ma ^= trailingBits; \ + } \ + } \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 0, ba) \ + unwrapOneInvert(X, input, output, 1, be) \ + unwrapOneInvert(X, input, output, 2, bi) \ + unwrapOne(X, input, output, 3, bo) \ + unwrapOne(X, input, output, 4, bu) \ + unwrapOne(X, input, output, 5, ga) \ + unwrapOne(X, input, output, 6, ge) \ + unwrapOne(X, input, output, 7, gi) \ + unwrapOneInvert(X, input, output, 8, go) \ + unwrapOne(X, input, output, 9, gu) \ + unwrapOne(X, input, output, 10, ka) \ + unwrapOne(X, input, output, 11, ke) \ + unwrapOneInvert(X, input, output, 12, ki) \ + unwrapOne(X, input, output, 13, ko) \ + unwrapOne(X, input, output, 14, ku) \ + unwrapOne(X, input, output, 15, ma) \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + X##me ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 16, me) \ + X##mi ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 16, me) \ + unwrapOneInvert(X, input, output, 17, mi) \ + if (laneCount < 19) { \ + X##mo ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 18, mo) \ + X##mu ^= trailingBits; \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 16, me) \ + unwrapOneInvert(X, input, output, 17, mi) \ + unwrapOne(X, input, output, 18, mo) \ + unwrapOne(X, input, output, 19, mu) \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + X##sa ^= trailingBits; \ + } \ + else { \ + unwrapOneInvert(X, input, output, 20, sa) \ + X##se ^= trailingBits; \ + } \ + } \ + else { \ + unwrapOneInvert(X, input, output, 20, sa) \ + unwrapOne(X, input, output, 21, se) \ + if (laneCount < 23) { \ + X##si ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 22, si) \ + X##so ^= trailingBits; \ + } \ + } \ + } \ + } \ + else { \ + unwrapOne(X, input, output, 16, me) \ + unwrapOneInvert(X, input, output, 17, mi) \ + unwrapOne(X, input, output, 18, mo) \ + unwrapOne(X, input, output, 19, mu) \ + unwrapOneInvert(X, input, output, 20, sa) \ + unwrapOne(X, input, output, 21, se) \ + unwrapOne(X, input, output, 22, si) \ + unwrapOne(X, input, output, 23, so) \ + if (laneCount < 25) { \ + X##su ^= trailingBits; \ + } \ + else { \ + unwrapOne(X, input, output, 24, su) \ + } \ + } \ + } diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h index 6cf765e6ce1..4861cf360f6 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h @@ -1,37 +1,37 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakP_1600_SnP_h_ -#define _KeccakP_1600_SnP_h_ - -/** For the documentation, see SnP-documentation.h. - */ - -#define KeccakP1600_implementation "in-place 32-bit optimized implementation" -#define KeccakP1600_stateSizeInBytes 200 -#define KeccakP1600_stateAlignment 8 - -#define KeccakP1600_StaticInitialize() -void KeccakP1600_Initialize(void *state); -void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); -void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); -void KeccakP1600_Permute_12rounds(void *state); -void KeccakP1600_Permute_24rounds(void *state); -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); - -#endif +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakP_1600_SnP_h_ +#define _KeccakP_1600_SnP_h_ + +/** For the documentation, see SnP-documentation.h. + */ + +#define KeccakP1600_implementation "in-place 32-bit optimized implementation" +#define KeccakP1600_stateSizeInBytes 200 +#define KeccakP1600_stateAlignment 8 + +#define KeccakP1600_StaticInitialize() +void KeccakP1600_Initialize(void *state); +void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); +void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP1600_Permute_12rounds(void *state); +void KeccakP1600_Permute_24rounds(void *state); +void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); + +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h index 889a31a7944..a7c96a8c2f0 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h @@ -1,49 +1,49 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakP_1600_SnP_h_ -#define _KeccakP_1600_SnP_h_ - -/** For the documentation, see SnP-documentation.h. - */ - -/* #include "brg_endian.h" */ -#include "KeccakP-1600-opt64-config.h" - -#define KeccakP1600_implementation "generic 64-bit optimized implementation (" KeccakP1600_implementation_config ")" -#define KeccakP1600_stateSizeInBytes 200 -#define KeccakP1600_stateAlignment 8 -#define KeccakF1600_FastLoop_supported - -#include - -#define KeccakP1600_StaticInitialize() -void KeccakP1600_Initialize(void *state); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) -#define KeccakP1600_AddByte(state, byte, offset) \ - ((unsigned char*)(state))[(offset)] ^= (byte) -#else -void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); -#endif -void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); -void KeccakP1600_Permute_12rounds(void *state); -void KeccakP1600_Permute_24rounds(void *state); -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); -size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen); - -#endif +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakP_1600_SnP_h_ +#define _KeccakP_1600_SnP_h_ + +/** For the documentation, see SnP-documentation.h. + */ + +/* #include "brg_endian.h" */ +#include "KeccakP-1600-opt64-config.h" + +#define KeccakP1600_implementation "generic 64-bit optimized implementation (" KeccakP1600_implementation_config ")" +#define KeccakP1600_stateSizeInBytes 200 +#define KeccakP1600_stateAlignment 8 +#define KeccakF1600_FastLoop_supported + +#include + +#define KeccakP1600_StaticInitialize() +void KeccakP1600_Initialize(void *state); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define KeccakP1600_AddByte(state, byte, offset) \ + ((unsigned char*)(state))[(offset)] ^= (byte) +#else +void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); +#endif +void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); +void KeccakP1600_Permute_12rounds(void *state); +void KeccakP1600_Permute_24rounds(void *state); +void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); +size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen); + +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP.h b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP.h index 0b23f09a6a4..ed6ad448f92 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP.h +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-SnP.h @@ -1,7 +1,7 @@ -#if KeccakOpt == 64 - #include "KeccakP-1600-SnP-opt64.h" -#elif KeccakOpt == 32 - #include "KeccakP-1600-SnP-opt32.h" -#else - #error "No KeccakOpt" -#endif +#if KeccakOpt == 64 + #include "KeccakP-1600-SnP-opt64.h" +#elif KeccakOpt == 32 + #include "KeccakP-1600-SnP-opt32.h" +#else + #error "No KeccakOpt" +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c index a2f9ffea932..c6a71d5a887 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c @@ -1,1162 +1,1162 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -/* #include "brg_endian.h" */ -#include "KeccakP-1600-SnP.h" -#include "SnP-Relaned.h" - -typedef unsigned char UINT8; -typedef unsigned int UINT32; -/* WARNING: on 8-bit and 16-bit platforms, this should be replaced by: */ - -/*typedef unsigned long UINT32; */ - - -#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset)))) - -/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ - -#define prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - temp0 = (low); \ - temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ - temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ - temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ - temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ - temp1 = (high); \ - temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); \ - temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ - temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ - temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); - -#define toBitInterleavingAndXOR(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even ^= (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd ^= (temp0 >> 16) | (temp1 & 0xFFFF0000); - -#define toBitInterleavingAndAND(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even &= (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd &= (temp0 >> 16) | (temp1 & 0xFFFF0000); - -#define toBitInterleavingAndSet(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even = (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd = (temp0 >> 16) | (temp1 & 0xFFFF0000); - -/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ - -#define prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - temp0 = (even); \ - temp1 = (odd); \ - temp = (temp0 & 0x0000FFFF) | (temp1 << 16); \ - temp1 = (temp0 >> 16) | (temp1 & 0xFFFF0000); \ - temp0 = temp; \ - temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ - temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ - temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ - temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ - temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); \ - temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ - temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ - temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); - -#define fromBitInterleaving(even, odd, low, high, temp, temp0, temp1) \ - prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - low = temp0; \ - high = temp1; - -#define fromBitInterleavingAndXOR(even, odd, lowIn, highIn, lowOut, highOut, temp, temp0, temp1) \ - prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - lowOut = lowIn ^ temp0; \ - highOut = highIn ^ temp1; - -void KeccakP1600_SetBytesInLaneToZero(void *state, unsigned int lanePosition, unsigned int offset, unsigned int length) -{ - UINT8 laneAsBytes[8]; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - memset(laneAsBytes, 0xFF, offset); - memset(laneAsBytes+offset, 0x00, length); - memset(laneAsBytes+offset+length, 0xFF, 8-offset-length); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - low = *((UINT32*)(laneAsBytes+0)); - high = *((UINT32*)(laneAsBytes+4)); -#else - low = laneAsBytes[0] - | ((UINT32)(laneAsBytes[1]) << 8) - | ((UINT32)(laneAsBytes[2]) << 16) - | ((UINT32)(laneAsBytes[3]) << 24); - high = laneAsBytes[4] - | ((UINT32)(laneAsBytes[5]) << 8) - | ((UINT32)(laneAsBytes[6]) << 16) - | ((UINT32)(laneAsBytes[7]) << 24); -#endif - toBitInterleavingAndAND(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Initialize(void *state) -{ - memset(state, 0, 200); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) -{ - unsigned int lanePosition = offset/8; - unsigned int offsetInLane = offset%8; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - if (offsetInLane < 4) { - low = (UINT32)byte << (offsetInLane*8); - high = 0; - } - else { - low = 0; - high = (UINT32)byte << ((offsetInLane-4)*8); - } - toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) -{ - UINT8 laneAsBytes[8]; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - memset(laneAsBytes, 0, 8); - memcpy(laneAsBytes+offset, data, length); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - low = *((UINT32*)(laneAsBytes+0)); - high = *((UINT32*)(laneAsBytes+4)); -#else - low = laneAsBytes[0] - | ((UINT32)(laneAsBytes[1]) << 8) - | ((UINT32)(laneAsBytes[2]) << 16) - | ((UINT32)(laneAsBytes[3]) << 24); - high = laneAsBytes[4] - | ((UINT32)(laneAsBytes[5]) << 8) - | ((UINT32)(laneAsBytes[6]) << 16) - | ((UINT32)(laneAsBytes[7]) << 24); -#endif - toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - const UINT32 * pI = (const UINT32 *)data; - UINT32 * pS = (UINT32*)state; - UINT32 t, x0, x1; - int i; - for (i = laneCount-1; i >= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - memcpy(&low, pI++, 4); - memcpy(&high, pI++, 4); - toBitInterleavingAndXOR(low, high, *(pS++), *(pS++), t, x0, x1); -#else - toBitInterleavingAndXOR(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - memcpy(&low, pI++, 4); - memcpy(&high, pI++, 4); - toBitInterleavingAndSet(low, high, *(pS++), *(pS++), t, x0, x1); -#else - toBitInterleavingAndSet(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; -#endif - memcpy(data, laneAsBytes+offset, length); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - UINT32 * pI = (UINT32 *)data; - const UINT32 * pS = ( const UINT32 *)state; - UINT32 t, x0, x1; - int i; - for (i = laneCount-1; i >= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); - memcpy(pI++, &low, 4); - memcpy(pI++, &high, 4); -#else - fromBitInterleaving(*(pS++), *(pS++), *(pI++), *(pI++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; - memcpy(data+lanePosition*8, laneAsBytes, 8); - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) -{ - SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - UINT32 *stateAsHalfLanes = (UINT32*)state; - UINT32 low, high, temp, temp0, temp1; - UINT8 laneAsBytes[8]; - unsigned int i; - - fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - *((UINT32*)(laneAsBytes+0)) = low; - *((UINT32*)(laneAsBytes+4)) = high; -#else - laneAsBytes[0] = low & 0xFF; - laneAsBytes[1] = (low >> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; -#endif - for(i=0; i= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); - *(pO++) = *(pI++) ^ low; - *(pO++) = *(pI++) ^ high; -#else - fromBitInterleavingAndXOR(*(pS++), *(pS++), *(pI++), *(pI++), *(pO++), *(pO++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; - ((UINT32*)(output+lanePosition*8))[0] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+0)); - ((UINT32*)(output+lanePosition*8))[1] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+4)); - } -#endif -} -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -static const UINT32 KeccakF1600RoundConstants_int2[2*24+1] = -{ - 0x00000001UL, 0x00000000UL, - 0x00000000UL, 0x00000089UL, - 0x00000000UL, 0x8000008bUL, - 0x00000000UL, 0x80008080UL, - 0x00000001UL, 0x0000008bUL, - 0x00000001UL, 0x00008000UL, - 0x00000001UL, 0x80008088UL, - 0x00000001UL, 0x80000082UL, - 0x00000000UL, 0x0000000bUL, - 0x00000000UL, 0x0000000aUL, - 0x00000001UL, 0x00008082UL, - 0x00000000UL, 0x00008003UL, - 0x00000001UL, 0x0000808bUL, - 0x00000001UL, 0x8000000bUL, - 0x00000001UL, 0x8000008aUL, - 0x00000001UL, 0x80000081UL, - 0x00000000UL, 0x80000081UL, - 0x00000000UL, 0x80000008UL, - 0x00000000UL, 0x00000083UL, - 0x00000000UL, 0x80008003UL, - 0x00000001UL, 0x80008088UL, - 0x00000000UL, 0x80000088UL, - 0x00000001UL, 0x00008000UL, - 0x00000000UL, 0x80008082UL, - 0x000000FFUL -}; - -#define KeccakAtoD_round0() \ - Cx = Abu0^Agu0^Aku0^Amu0^Asu0; \ - Du1 = Abe1^Age1^Ake1^Ame1^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Abu1^Agu1^Aku1^Amu1^Asu1; \ - Du0 = Abe0^Age0^Ake0^Ame0^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Abi0^Agi0^Aki0^Ami0^Asi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Abi1^Agi1^Aki1^Ami1^Asi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Aga0^Aka0^Ama0^Asa0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Aga1^Aka1^Ama1^Asa1; \ - De1 = Cz^Cw; \ -\ - Cy = Abo1^Ago1^Ako1^Amo1^Aso1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Abo0^Ago0^Ako0^Amo0^Aso0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round1() \ - Cx = Asu0^Agu0^Amu0^Abu1^Aku1; \ - Du1 = Age1^Ame0^Abe0^Ake1^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Asu1^Agu1^Amu1^Abu0^Aku0; \ - Du0 = Age0^Ame1^Abe1^Ake0^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Aki1^Asi1^Agi0^Ami1^Abi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Aki0^Asi0^Agi1^Ami0^Abi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Aka1^Asa0^Aga0^Ama1; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Aka0^Asa1^Aga1^Ama0; \ - De1 = Cz^Cw; \ -\ - Cy = Amo0^Abo1^Ako0^Aso1^Ago0; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Amo1^Abo0^Ako1^Aso0^Ago1; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round2() \ - Cx = Aku1^Agu0^Abu1^Asu1^Amu1; \ - Du1 = Ame0^Ake0^Age0^Abe0^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Aku0^Agu1^Abu0^Asu0^Amu0; \ - Du0 = Ame1^Ake1^Age1^Abe1^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Agi1^Abi1^Asi1^Ami0^Aki1; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Agi0^Abi0^Asi0^Ami1^Aki0; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Asa1^Ama1^Aka1^Aga1; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Asa0^Ama0^Aka0^Aga0; \ - De1 = Cz^Cw; \ -\ - Cy = Aso0^Amo0^Ako1^Ago0^Abo0; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Aso1^Amo1^Ako0^Ago1^Abo1; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round3() \ - Cx = Amu1^Agu0^Asu1^Aku0^Abu0; \ - Du1 = Ake0^Abe1^Ame1^Age0^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Amu0^Agu1^Asu0^Aku1^Abu1; \ - Du0 = Ake1^Abe0^Ame0^Age1^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Asi0^Aki0^Abi1^Ami1^Agi1; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Asi1^Aki1^Abi0^Ami0^Agi0; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Ama0^Aga1^Asa1^Aka0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Ama1^Aga0^Asa0^Aka1; \ - De1 = Cz^Cw; \ -\ - Cy = Ago1^Aso0^Ako0^Abo0^Amo1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Ago0^Aso1^Ako1^Abo1^Amo0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -void KeccakP1600_Permute_Nrounds(void *state, unsigned int nRounds) -{ - { - UINT32 Da0, De0, Di0, Do0, Du0; - UINT32 Da1, De1, Di1, Do1, Du1; - UINT32 Ca0, Ce0, Ci0, Co0, Cu0; - UINT32 Cx, Cy, Cz, Cw; - #define Ba Ca0 - #define Be Ce0 - #define Bi Ci0 - #define Bo Co0 - #define Bu Cu0 - const UINT32 *pRoundConstants = KeccakF1600RoundConstants_int2+(24-nRounds)*2; - UINT32 *stateAsHalfLanes = (UINT32*)state; - #define Aba0 stateAsHalfLanes[ 0] - #define Aba1 stateAsHalfLanes[ 1] - #define Abe0 stateAsHalfLanes[ 2] - #define Abe1 stateAsHalfLanes[ 3] - #define Abi0 stateAsHalfLanes[ 4] - #define Abi1 stateAsHalfLanes[ 5] - #define Abo0 stateAsHalfLanes[ 6] - #define Abo1 stateAsHalfLanes[ 7] - #define Abu0 stateAsHalfLanes[ 8] - #define Abu1 stateAsHalfLanes[ 9] - #define Aga0 stateAsHalfLanes[10] - #define Aga1 stateAsHalfLanes[11] - #define Age0 stateAsHalfLanes[12] - #define Age1 stateAsHalfLanes[13] - #define Agi0 stateAsHalfLanes[14] - #define Agi1 stateAsHalfLanes[15] - #define Ago0 stateAsHalfLanes[16] - #define Ago1 stateAsHalfLanes[17] - #define Agu0 stateAsHalfLanes[18] - #define Agu1 stateAsHalfLanes[19] - #define Aka0 stateAsHalfLanes[20] - #define Aka1 stateAsHalfLanes[21] - #define Ake0 stateAsHalfLanes[22] - #define Ake1 stateAsHalfLanes[23] - #define Aki0 stateAsHalfLanes[24] - #define Aki1 stateAsHalfLanes[25] - #define Ako0 stateAsHalfLanes[26] - #define Ako1 stateAsHalfLanes[27] - #define Aku0 stateAsHalfLanes[28] - #define Aku1 stateAsHalfLanes[29] - #define Ama0 stateAsHalfLanes[30] - #define Ama1 stateAsHalfLanes[31] - #define Ame0 stateAsHalfLanes[32] - #define Ame1 stateAsHalfLanes[33] - #define Ami0 stateAsHalfLanes[34] - #define Ami1 stateAsHalfLanes[35] - #define Amo0 stateAsHalfLanes[36] - #define Amo1 stateAsHalfLanes[37] - #define Amu0 stateAsHalfLanes[38] - #define Amu1 stateAsHalfLanes[39] - #define Asa0 stateAsHalfLanes[40] - #define Asa1 stateAsHalfLanes[41] - #define Ase0 stateAsHalfLanes[42] - #define Ase1 stateAsHalfLanes[43] - #define Asi0 stateAsHalfLanes[44] - #define Asi1 stateAsHalfLanes[45] - #define Aso0 stateAsHalfLanes[46] - #define Aso1 stateAsHalfLanes[47] - #define Asu0 stateAsHalfLanes[48] - #define Asu1 stateAsHalfLanes[49] - - do - { - /* --- Code for 4 rounds */ - - /* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ - - KeccakAtoD_round0(); - - Ba = (Aba0^Da0); - Be = ROL32((Age0^De0), 22); - Bi = ROL32((Aki1^Di1), 22); - Bo = ROL32((Amo1^Do1), 11); - Bu = ROL32((Asu0^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Age0 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Age1^De1), 22); - Bi = ROL32((Aki0^Di0), 21); - Bo = ROL32((Amo0^Do0), 10); - Bu = ROL32((Asu1^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Age1 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aka1^Da1), 2); - Bo = ROL32((Ame1^De1), 23); - Bu = ROL32((Asi1^Di1), 31); - Ba = ROL32((Abo0^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Aka1 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aka0^Da0), 1); - Bo = ROL32((Ame0^De0), 22); - Bu = ROL32((Asi0^Di0), 30); - Ba = ROL32((Abo1^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Aka0 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Asa0^Da0), 9); - Ba = ROL32((Abe1^De1), 1); - Be = ROL32((Agi0^Di0), 3); - Bi = ROL32((Ako1^Do1), 13); - Bo = ROL32((Amu0^Du0), 4); - Asa0 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Asa1^Da1), 9); - Ba = (Abe0^De0); - Be = ROL32((Agi1^Di1), 3); - Bi = ROL32((Ako0^Do0), 12); - Bo = ROL32((Amu1^Du1), 4); - Asa1 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aga0^Da0), 18); - Bi = ROL32((Ake0^De0), 5); - Bo = ROL32((Ami1^Di1), 8); - Bu = ROL32((Aso0^Do0), 28); - Ba = ROL32((Abu1^Du1), 14); - Aga0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aga1^Da1), 18); - Bi = ROL32((Ake1^De1), 5); - Bo = ROL32((Ami0^Di0), 7); - Bu = ROL32((Aso1^Do1), 28); - Ba = ROL32((Abu0^Du0), 13); - Aga1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Ama1^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Abi0^Di0), 31); - Be = ROL32((Ago1^Do1), 28); - Bi = ROL32((Aku1^Du1), 20); - Ama1 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Ama0^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Abi1^Di1), 31); - Be = ROL32((Ago0^Do0), 27); - Bi = ROL32((Aku0^Du0), 19); - Ama0 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round1(); - - Ba = (Aba0^Da0); - Be = ROL32((Ame1^De0), 22); - Bi = ROL32((Agi1^Di1), 22); - Bo = ROL32((Aso1^Do1), 11); - Bu = ROL32((Aku1^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Ame1 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Ame0^De1), 22); - Bi = ROL32((Agi0^Di0), 21); - Bo = ROL32((Aso0^Do0), 10); - Bu = ROL32((Aku0^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Ame0 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Asa1^Da1), 2); - Bo = ROL32((Ake1^De1), 23); - Bu = ROL32((Abi1^Di1), 31); - Ba = ROL32((Amo1^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Asa1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Asa0^Da0), 1); - Bo = ROL32((Ake0^De0), 22); - Bu = ROL32((Abi0^Di0), 30); - Ba = ROL32((Amo0^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Asa0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Ama1^Da0), 9); - Ba = ROL32((Age1^De1), 1); - Be = ROL32((Asi1^Di0), 3); - Bi = ROL32((Ako0^Do1), 13); - Bo = ROL32((Abu1^Du0), 4); - Ama1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Ama0^Da1), 9); - Ba = (Age0^De0); - Be = ROL32((Asi0^Di1), 3); - Bi = ROL32((Ako1^Do0), 12); - Bo = ROL32((Abu0^Du1), 4); - Ama0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aka1^Da0), 18); - Bi = ROL32((Abe1^De0), 5); - Bo = ROL32((Ami0^Di1), 8); - Bu = ROL32((Ago1^Do0), 28); - Ba = ROL32((Asu1^Du1), 14); - Aka1 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aka0^Da1), 18); - Bi = ROL32((Abe0^De1), 5); - Bo = ROL32((Ami1^Di0), 7); - Bu = ROL32((Ago0^Do1), 28); - Ba = ROL32((Asu0^Du0), 13); - Aka0 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aga1^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Aki1^Di0), 31); - Be = ROL32((Abo1^Do1), 28); - Bi = ROL32((Amu1^Du1), 20); - Aga1 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aga0^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Aki0^Di1), 31); - Be = ROL32((Abo0^Do0), 27); - Bi = ROL32((Amu0^Du0), 19); - Aga0 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round2(); - - Ba = (Aba0^Da0); - Be = ROL32((Ake1^De0), 22); - Bi = ROL32((Asi0^Di1), 22); - Bo = ROL32((Ago0^Do1), 11); - Bu = ROL32((Amu1^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Ake1 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Ake0^De1), 22); - Bi = ROL32((Asi1^Di0), 21); - Bo = ROL32((Ago1^Do0), 10); - Bu = ROL32((Amu0^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Ake0 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Ama0^Da1), 2); - Bo = ROL32((Abe0^De1), 23); - Bu = ROL32((Aki0^Di1), 31); - Ba = ROL32((Aso1^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Ama0 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Ama1^Da0), 1); - Bo = ROL32((Abe1^De0), 22); - Bu = ROL32((Aki1^Di0), 30); - Ba = ROL32((Aso0^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Ama1 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aga1^Da0), 9); - Ba = ROL32((Ame0^De1), 1); - Be = ROL32((Abi1^Di0), 3); - Bi = ROL32((Ako1^Do1), 13); - Bo = ROL32((Asu1^Du0), 4); - Aga1 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aga0^Da1), 9); - Ba = (Ame1^De0); - Be = ROL32((Abi0^Di1), 3); - Bi = ROL32((Ako0^Do0), 12); - Bo = ROL32((Asu0^Du1), 4); - Aga0 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Asa1^Da0), 18); - Bi = ROL32((Age1^De0), 5); - Bo = ROL32((Ami1^Di1), 8); - Bu = ROL32((Abo1^Do0), 28); - Ba = ROL32((Aku0^Du1), 14); - Asa1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Asa0^Da1), 18); - Bi = ROL32((Age0^De1), 5); - Bo = ROL32((Ami0^Di0), 7); - Bu = ROL32((Abo0^Do1), 28); - Ba = ROL32((Aku1^Du0), 13); - Asa0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aka0^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Agi1^Di0), 31); - Be = ROL32((Amo0^Do1), 28); - Bi = ROL32((Abu0^Du1), 20); - Aka0 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aka1^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Agi0^Di1), 31); - Be = ROL32((Amo1^Do0), 27); - Bi = ROL32((Abu1^Du0), 19); - Aka1 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round3(); - - Ba = (Aba0^Da0); - Be = ROL32((Abe0^De0), 22); - Bi = ROL32((Abi0^Di1), 22); - Bo = ROL32((Abo0^Do1), 11); - Bu = ROL32((Abu0^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Abe0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Abe1^De1), 22); - Bi = ROL32((Abi1^Di0), 21); - Bo = ROL32((Abo1^Do0), 10); - Bu = ROL32((Abu1^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Abe1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aga0^Da1), 2); - Bo = ROL32((Age0^De1), 23); - Bu = ROL32((Agi0^Di1), 31); - Ba = ROL32((Ago0^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Aga0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aga1^Da0), 1); - Bo = ROL32((Age1^De0), 22); - Bu = ROL32((Agi1^Di0), 30); - Ba = ROL32((Ago1^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Aga1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aka0^Da0), 9); - Ba = ROL32((Ake0^De1), 1); - Be = ROL32((Aki0^Di0), 3); - Bi = ROL32((Ako0^Do1), 13); - Bo = ROL32((Aku0^Du0), 4); - Aka0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aka1^Da1), 9); - Ba = (Ake1^De0); - Be = ROL32((Aki1^Di1), 3); - Bi = ROL32((Ako1^Do0), 12); - Bo = ROL32((Aku1^Du1), 4); - Aka1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Ama0^Da0), 18); - Bi = ROL32((Ame0^De0), 5); - Bo = ROL32((Ami0^Di1), 8); - Bu = ROL32((Amo0^Do0), 28); - Ba = ROL32((Amu0^Du1), 14); - Ama0 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Ama1^Da1), 18); - Bi = ROL32((Ame1^De1), 5); - Bo = ROL32((Ami1^Di0), 7); - Bu = ROL32((Amo1^Do1), 28); - Ba = ROL32((Amu1^Du0), 13); - Ama1 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Asa0^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Asi0^Di0), 31); - Be = ROL32((Aso0^Do1), 28); - Bi = ROL32((Asu0^Du1), 20); - Asa0 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Asa1^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Asi1^Di1), 31); - Be = ROL32((Aso1^Do0), 27); - Bi = ROL32((Asu1^Du0), 19); - Asa1 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - } - while ( *pRoundConstants != 0xFF ); - - #undef Aba0 - #undef Aba1 - #undef Abe0 - #undef Abe1 - #undef Abi0 - #undef Abi1 - #undef Abo0 - #undef Abo1 - #undef Abu0 - #undef Abu1 - #undef Aga0 - #undef Aga1 - #undef Age0 - #undef Age1 - #undef Agi0 - #undef Agi1 - #undef Ago0 - #undef Ago1 - #undef Agu0 - #undef Agu1 - #undef Aka0 - #undef Aka1 - #undef Ake0 - #undef Ake1 - #undef Aki0 - #undef Aki1 - #undef Ako0 - #undef Ako1 - #undef Aku0 - #undef Aku1 - #undef Ama0 - #undef Ama1 - #undef Ame0 - #undef Ame1 - #undef Ami0 - #undef Ami1 - #undef Amo0 - #undef Amo1 - #undef Amu0 - #undef Amu1 - #undef Asa0 - #undef Asa1 - #undef Ase0 - #undef Ase1 - #undef Asi0 - #undef Asi1 - #undef Aso0 - #undef Aso1 - #undef Asu0 - #undef Asu1 - } -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Permute_12rounds(void *state) -{ - KeccakP1600_Permute_Nrounds(state, 12); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Permute_24rounds(void *state) -{ - KeccakP1600_Permute_Nrounds(state, 24); -} +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include +/* #include "brg_endian.h" */ +#include "KeccakP-1600-SnP.h" +#include "SnP-Relaned.h" + +typedef unsigned char UINT8; +typedef unsigned int UINT32; +/* WARNING: on 8-bit and 16-bit platforms, this should be replaced by: */ + +/*typedef unsigned long UINT32; */ + + +#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset)))) + +/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ + +#define prepareToBitInterleaving(low, high, temp, temp0, temp1) \ + temp0 = (low); \ + temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ + temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ + temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ + temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ + temp1 = (high); \ + temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); \ + temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ + temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ + temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); + +#define toBitInterleavingAndXOR(low, high, even, odd, temp, temp0, temp1) \ + prepareToBitInterleaving(low, high, temp, temp0, temp1) \ + even ^= (temp0 & 0x0000FFFF) | (temp1 << 16); \ + odd ^= (temp0 >> 16) | (temp1 & 0xFFFF0000); + +#define toBitInterleavingAndAND(low, high, even, odd, temp, temp0, temp1) \ + prepareToBitInterleaving(low, high, temp, temp0, temp1) \ + even &= (temp0 & 0x0000FFFF) | (temp1 << 16); \ + odd &= (temp0 >> 16) | (temp1 & 0xFFFF0000); + +#define toBitInterleavingAndSet(low, high, even, odd, temp, temp0, temp1) \ + prepareToBitInterleaving(low, high, temp, temp0, temp1) \ + even = (temp0 & 0x0000FFFF) | (temp1 << 16); \ + odd = (temp0 >> 16) | (temp1 & 0xFFFF0000); + +/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ + +#define prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ + temp0 = (even); \ + temp1 = (odd); \ + temp = (temp0 & 0x0000FFFF) | (temp1 << 16); \ + temp1 = (temp0 >> 16) | (temp1 & 0xFFFF0000); \ + temp0 = temp; \ + temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ + temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ + temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ + temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ + temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); \ + temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ + temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ + temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); + +#define fromBitInterleaving(even, odd, low, high, temp, temp0, temp1) \ + prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ + low = temp0; \ + high = temp1; + +#define fromBitInterleavingAndXOR(even, odd, lowIn, highIn, lowOut, highOut, temp, temp0, temp1) \ + prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ + lowOut = lowIn ^ temp0; \ + highOut = highIn ^ temp1; + +void KeccakP1600_SetBytesInLaneToZero(void *state, unsigned int lanePosition, unsigned int offset, unsigned int length) +{ + UINT8 laneAsBytes[8]; + UINT32 low, high; + UINT32 temp, temp0, temp1; + UINT32 *stateAsHalfLanes = (UINT32*)state; + + memset(laneAsBytes, 0xFF, offset); + memset(laneAsBytes+offset, 0x00, length); + memset(laneAsBytes+offset+length, 0xFF, 8-offset-length); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + low = *((UINT32*)(laneAsBytes+0)); + high = *((UINT32*)(laneAsBytes+4)); +#else + low = laneAsBytes[0] + | ((UINT32)(laneAsBytes[1]) << 8) + | ((UINT32)(laneAsBytes[2]) << 16) + | ((UINT32)(laneAsBytes[3]) << 24); + high = laneAsBytes[4] + | ((UINT32)(laneAsBytes[5]) << 8) + | ((UINT32)(laneAsBytes[6]) << 16) + | ((UINT32)(laneAsBytes[7]) << 24); +#endif + toBitInterleavingAndAND(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Initialize(void *state) +{ + memset(state, 0, 200); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) +{ + unsigned int lanePosition = offset/8; + unsigned int offsetInLane = offset%8; + UINT32 low, high; + UINT32 temp, temp0, temp1; + UINT32 *stateAsHalfLanes = (UINT32*)state; + + if (offsetInLane < 4) { + low = (UINT32)byte << (offsetInLane*8); + high = 0; + } + else { + low = 0; + high = (UINT32)byte << ((offsetInLane-4)*8); + } + toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) +{ + UINT8 laneAsBytes[8]; + UINT32 low, high; + UINT32 temp, temp0, temp1; + UINT32 *stateAsHalfLanes = (UINT32*)state; + + memset(laneAsBytes, 0, 8); + memcpy(laneAsBytes+offset, data, length); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + low = *((UINT32*)(laneAsBytes+0)); + high = *((UINT32*)(laneAsBytes+4)); +#else + low = laneAsBytes[0] + | ((UINT32)(laneAsBytes[1]) << 8) + | ((UINT32)(laneAsBytes[2]) << 16) + | ((UINT32)(laneAsBytes[3]) << 24); + high = laneAsBytes[4] + | ((UINT32)(laneAsBytes[5]) << 8) + | ((UINT32)(laneAsBytes[6]) << 16) + | ((UINT32)(laneAsBytes[7]) << 24); +#endif + toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + const UINT32 * pI = (const UINT32 *)data; + UINT32 * pS = (UINT32*)state; + UINT32 t, x0, x1; + int i; + for (i = laneCount-1; i >= 0; --i) { +#ifdef NO_MISALIGNED_ACCESSES + UINT32 low; + UINT32 high; + memcpy(&low, pI++, 4); + memcpy(&high, pI++, 4); + toBitInterleavingAndXOR(low, high, *(pS++), *(pS++), t, x0, x1); +#else + toBitInterleavingAndXOR(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) +#endif + } +#else + unsigned int lanePosition; + for(lanePosition=0; lanePosition= 0; --i) { +#ifdef NO_MISALIGNED_ACCESSES + UINT32 low; + UINT32 high; + memcpy(&low, pI++, 4); + memcpy(&high, pI++, 4); + toBitInterleavingAndSet(low, high, *(pS++), *(pS++), t, x0, x1); +#else + toBitInterleavingAndSet(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) +#endif + } +#else + unsigned int lanePosition; + for(lanePosition=0; lanePosition> 8) & 0xFF; + laneAsBytes[2] = (low >> 16) & 0xFF; + laneAsBytes[3] = (low >> 24) & 0xFF; + laneAsBytes[4] = high & 0xFF; + laneAsBytes[5] = (high >> 8) & 0xFF; + laneAsBytes[6] = (high >> 16) & 0xFF; + laneAsBytes[7] = (high >> 24) & 0xFF; +#endif + memcpy(data, laneAsBytes+offset, length); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + UINT32 * pI = (UINT32 *)data; + const UINT32 * pS = ( const UINT32 *)state; + UINT32 t, x0, x1; + int i; + for (i = laneCount-1; i >= 0; --i) { +#ifdef NO_MISALIGNED_ACCESSES + UINT32 low; + UINT32 high; + fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); + memcpy(pI++, &low, 4); + memcpy(pI++, &high, 4); +#else + fromBitInterleaving(*(pS++), *(pS++), *(pI++), *(pI++), t, x0, x1) +#endif + } +#else + unsigned int lanePosition; + for(lanePosition=0; lanePosition> 8) & 0xFF; + laneAsBytes[2] = (low >> 16) & 0xFF; + laneAsBytes[3] = (low >> 24) & 0xFF; + laneAsBytes[4] = high & 0xFF; + laneAsBytes[5] = (high >> 8) & 0xFF; + laneAsBytes[6] = (high >> 16) & 0xFF; + laneAsBytes[7] = (high >> 24) & 0xFF; + memcpy(data+lanePosition*8, laneAsBytes, 8); + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + UINT32 *stateAsHalfLanes = (UINT32*)state; + UINT32 low, high, temp, temp0, temp1; + UINT8 laneAsBytes[8]; + unsigned int i; + + fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + *((UINT32*)(laneAsBytes+0)) = low; + *((UINT32*)(laneAsBytes+4)) = high; +#else + laneAsBytes[0] = low & 0xFF; + laneAsBytes[1] = (low >> 8) & 0xFF; + laneAsBytes[2] = (low >> 16) & 0xFF; + laneAsBytes[3] = (low >> 24) & 0xFF; + laneAsBytes[4] = high & 0xFF; + laneAsBytes[5] = (high >> 8) & 0xFF; + laneAsBytes[6] = (high >> 16) & 0xFF; + laneAsBytes[7] = (high >> 24) & 0xFF; +#endif + for(i=0; i= 0; --i) { +#ifdef NO_MISALIGNED_ACCESSES + UINT32 low; + UINT32 high; + fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); + *(pO++) = *(pI++) ^ low; + *(pO++) = *(pI++) ^ high; +#else + fromBitInterleavingAndXOR(*(pS++), *(pS++), *(pI++), *(pI++), *(pO++), *(pO++), t, x0, x1) +#endif + } +#else + unsigned int lanePosition; + for(lanePosition=0; lanePosition> 8) & 0xFF; + laneAsBytes[2] = (low >> 16) & 0xFF; + laneAsBytes[3] = (low >> 24) & 0xFF; + laneAsBytes[4] = high & 0xFF; + laneAsBytes[5] = (high >> 8) & 0xFF; + laneAsBytes[6] = (high >> 16) & 0xFF; + laneAsBytes[7] = (high >> 24) & 0xFF; + ((UINT32*)(output+lanePosition*8))[0] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+0)); + ((UINT32*)(output+lanePosition*8))[1] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+4)); + } +#endif +} +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +static const UINT32 KeccakF1600RoundConstants_int2[2*24+1] = +{ + 0x00000001UL, 0x00000000UL, + 0x00000000UL, 0x00000089UL, + 0x00000000UL, 0x8000008bUL, + 0x00000000UL, 0x80008080UL, + 0x00000001UL, 0x0000008bUL, + 0x00000001UL, 0x00008000UL, + 0x00000001UL, 0x80008088UL, + 0x00000001UL, 0x80000082UL, + 0x00000000UL, 0x0000000bUL, + 0x00000000UL, 0x0000000aUL, + 0x00000001UL, 0x00008082UL, + 0x00000000UL, 0x00008003UL, + 0x00000001UL, 0x0000808bUL, + 0x00000001UL, 0x8000000bUL, + 0x00000001UL, 0x8000008aUL, + 0x00000001UL, 0x80000081UL, + 0x00000000UL, 0x80000081UL, + 0x00000000UL, 0x80000008UL, + 0x00000000UL, 0x00000083UL, + 0x00000000UL, 0x80008003UL, + 0x00000001UL, 0x80008088UL, + 0x00000000UL, 0x80000088UL, + 0x00000001UL, 0x00008000UL, + 0x00000000UL, 0x80008082UL, + 0x000000FFUL +}; + +#define KeccakAtoD_round0() \ + Cx = Abu0^Agu0^Aku0^Amu0^Asu0; \ + Du1 = Abe1^Age1^Ake1^Ame1^Ase1; \ + Da0 = Cx^ROL32(Du1, 1); \ + Cz = Abu1^Agu1^Aku1^Amu1^Asu1; \ + Du0 = Abe0^Age0^Ake0^Ame0^Ase0; \ + Da1 = Cz^Du0; \ +\ + Cw = Abi0^Agi0^Aki0^Ami0^Asi0; \ + Do0 = Cw^ROL32(Cz, 1); \ + Cy = Abi1^Agi1^Aki1^Ami1^Asi1; \ + Do1 = Cy^Cx; \ +\ + Cx = Aba0^Aga0^Aka0^Ama0^Asa0; \ + De0 = Cx^ROL32(Cy, 1); \ + Cz = Aba1^Aga1^Aka1^Ama1^Asa1; \ + De1 = Cz^Cw; \ +\ + Cy = Abo1^Ago1^Ako1^Amo1^Aso1; \ + Di0 = Du0^ROL32(Cy, 1); \ + Cw = Abo0^Ago0^Ako0^Amo0^Aso0; \ + Di1 = Du1^Cw; \ +\ + Du0 = Cw^ROL32(Cz, 1); \ + Du1 = Cy^Cx; \ + +#define KeccakAtoD_round1() \ + Cx = Asu0^Agu0^Amu0^Abu1^Aku1; \ + Du1 = Age1^Ame0^Abe0^Ake1^Ase1; \ + Da0 = Cx^ROL32(Du1, 1); \ + Cz = Asu1^Agu1^Amu1^Abu0^Aku0; \ + Du0 = Age0^Ame1^Abe1^Ake0^Ase0; \ + Da1 = Cz^Du0; \ +\ + Cw = Aki1^Asi1^Agi0^Ami1^Abi0; \ + Do0 = Cw^ROL32(Cz, 1); \ + Cy = Aki0^Asi0^Agi1^Ami0^Abi1; \ + Do1 = Cy^Cx; \ +\ + Cx = Aba0^Aka1^Asa0^Aga0^Ama1; \ + De0 = Cx^ROL32(Cy, 1); \ + Cz = Aba1^Aka0^Asa1^Aga1^Ama0; \ + De1 = Cz^Cw; \ +\ + Cy = Amo0^Abo1^Ako0^Aso1^Ago0; \ + Di0 = Du0^ROL32(Cy, 1); \ + Cw = Amo1^Abo0^Ako1^Aso0^Ago1; \ + Di1 = Du1^Cw; \ +\ + Du0 = Cw^ROL32(Cz, 1); \ + Du1 = Cy^Cx; \ + +#define KeccakAtoD_round2() \ + Cx = Aku1^Agu0^Abu1^Asu1^Amu1; \ + Du1 = Ame0^Ake0^Age0^Abe0^Ase1; \ + Da0 = Cx^ROL32(Du1, 1); \ + Cz = Aku0^Agu1^Abu0^Asu0^Amu0; \ + Du0 = Ame1^Ake1^Age1^Abe1^Ase0; \ + Da1 = Cz^Du0; \ +\ + Cw = Agi1^Abi1^Asi1^Ami0^Aki1; \ + Do0 = Cw^ROL32(Cz, 1); \ + Cy = Agi0^Abi0^Asi0^Ami1^Aki0; \ + Do1 = Cy^Cx; \ +\ + Cx = Aba0^Asa1^Ama1^Aka1^Aga1; \ + De0 = Cx^ROL32(Cy, 1); \ + Cz = Aba1^Asa0^Ama0^Aka0^Aga0; \ + De1 = Cz^Cw; \ +\ + Cy = Aso0^Amo0^Ako1^Ago0^Abo0; \ + Di0 = Du0^ROL32(Cy, 1); \ + Cw = Aso1^Amo1^Ako0^Ago1^Abo1; \ + Di1 = Du1^Cw; \ +\ + Du0 = Cw^ROL32(Cz, 1); \ + Du1 = Cy^Cx; \ + +#define KeccakAtoD_round3() \ + Cx = Amu1^Agu0^Asu1^Aku0^Abu0; \ + Du1 = Ake0^Abe1^Ame1^Age0^Ase1; \ + Da0 = Cx^ROL32(Du1, 1); \ + Cz = Amu0^Agu1^Asu0^Aku1^Abu1; \ + Du0 = Ake1^Abe0^Ame0^Age1^Ase0; \ + Da1 = Cz^Du0; \ +\ + Cw = Asi0^Aki0^Abi1^Ami1^Agi1; \ + Do0 = Cw^ROL32(Cz, 1); \ + Cy = Asi1^Aki1^Abi0^Ami0^Agi0; \ + Do1 = Cy^Cx; \ +\ + Cx = Aba0^Ama0^Aga1^Asa1^Aka0; \ + De0 = Cx^ROL32(Cy, 1); \ + Cz = Aba1^Ama1^Aga0^Asa0^Aka1; \ + De1 = Cz^Cw; \ +\ + Cy = Ago1^Aso0^Ako0^Abo0^Amo1; \ + Di0 = Du0^ROL32(Cy, 1); \ + Cw = Ago0^Aso1^Ako1^Abo1^Amo0; \ + Di1 = Du1^Cw; \ +\ + Du0 = Cw^ROL32(Cz, 1); \ + Du1 = Cy^Cx; \ + +void KeccakP1600_Permute_Nrounds(void *state, unsigned int nRounds) +{ + { + UINT32 Da0, De0, Di0, Do0, Du0; + UINT32 Da1, De1, Di1, Do1, Du1; + UINT32 Ca0, Ce0, Ci0, Co0, Cu0; + UINT32 Cx, Cy, Cz, Cw; + #define Ba Ca0 + #define Be Ce0 + #define Bi Ci0 + #define Bo Co0 + #define Bu Cu0 + const UINT32 *pRoundConstants = KeccakF1600RoundConstants_int2+(24-nRounds)*2; + UINT32 *stateAsHalfLanes = (UINT32*)state; + #define Aba0 stateAsHalfLanes[ 0] + #define Aba1 stateAsHalfLanes[ 1] + #define Abe0 stateAsHalfLanes[ 2] + #define Abe1 stateAsHalfLanes[ 3] + #define Abi0 stateAsHalfLanes[ 4] + #define Abi1 stateAsHalfLanes[ 5] + #define Abo0 stateAsHalfLanes[ 6] + #define Abo1 stateAsHalfLanes[ 7] + #define Abu0 stateAsHalfLanes[ 8] + #define Abu1 stateAsHalfLanes[ 9] + #define Aga0 stateAsHalfLanes[10] + #define Aga1 stateAsHalfLanes[11] + #define Age0 stateAsHalfLanes[12] + #define Age1 stateAsHalfLanes[13] + #define Agi0 stateAsHalfLanes[14] + #define Agi1 stateAsHalfLanes[15] + #define Ago0 stateAsHalfLanes[16] + #define Ago1 stateAsHalfLanes[17] + #define Agu0 stateAsHalfLanes[18] + #define Agu1 stateAsHalfLanes[19] + #define Aka0 stateAsHalfLanes[20] + #define Aka1 stateAsHalfLanes[21] + #define Ake0 stateAsHalfLanes[22] + #define Ake1 stateAsHalfLanes[23] + #define Aki0 stateAsHalfLanes[24] + #define Aki1 stateAsHalfLanes[25] + #define Ako0 stateAsHalfLanes[26] + #define Ako1 stateAsHalfLanes[27] + #define Aku0 stateAsHalfLanes[28] + #define Aku1 stateAsHalfLanes[29] + #define Ama0 stateAsHalfLanes[30] + #define Ama1 stateAsHalfLanes[31] + #define Ame0 stateAsHalfLanes[32] + #define Ame1 stateAsHalfLanes[33] + #define Ami0 stateAsHalfLanes[34] + #define Ami1 stateAsHalfLanes[35] + #define Amo0 stateAsHalfLanes[36] + #define Amo1 stateAsHalfLanes[37] + #define Amu0 stateAsHalfLanes[38] + #define Amu1 stateAsHalfLanes[39] + #define Asa0 stateAsHalfLanes[40] + #define Asa1 stateAsHalfLanes[41] + #define Ase0 stateAsHalfLanes[42] + #define Ase1 stateAsHalfLanes[43] + #define Asi0 stateAsHalfLanes[44] + #define Asi1 stateAsHalfLanes[45] + #define Aso0 stateAsHalfLanes[46] + #define Aso1 stateAsHalfLanes[47] + #define Asu0 stateAsHalfLanes[48] + #define Asu1 stateAsHalfLanes[49] + + do + { + /* --- Code for 4 rounds */ + + /* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ + + KeccakAtoD_round0(); + + Ba = (Aba0^Da0); + Be = ROL32((Age0^De0), 22); + Bi = ROL32((Aki1^Di1), 22); + Bo = ROL32((Amo1^Do1), 11); + Bu = ROL32((Asu0^Du0), 7); + Aba0 = Ba ^((~Be)& Bi ); + Aba0 ^= *(pRoundConstants++); + Age0 = Be ^((~Bi)& Bo ); + Aki1 = Bi ^((~Bo)& Bu ); + Amo1 = Bo ^((~Bu)& Ba ); + Asu0 = Bu ^((~Ba)& Be ); + + Ba = (Aba1^Da1); + Be = ROL32((Age1^De1), 22); + Bi = ROL32((Aki0^Di0), 21); + Bo = ROL32((Amo0^Do0), 10); + Bu = ROL32((Asu1^Du1), 7); + Aba1 = Ba ^((~Be)& Bi ); + Aba1 ^= *(pRoundConstants++); + Age1 = Be ^((~Bi)& Bo ); + Aki0 = Bi ^((~Bo)& Bu ); + Amo0 = Bo ^((~Bu)& Ba ); + Asu1 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Aka1^Da1), 2); + Bo = ROL32((Ame1^De1), 23); + Bu = ROL32((Asi1^Di1), 31); + Ba = ROL32((Abo0^Do0), 14); + Be = ROL32((Agu0^Du0), 10); + Aka1 = Ba ^((~Be)& Bi ); + Ame1 = Be ^((~Bi)& Bo ); + Asi1 = Bi ^((~Bo)& Bu ); + Abo0 = Bo ^((~Bu)& Ba ); + Agu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Aka0^Da0), 1); + Bo = ROL32((Ame0^De0), 22); + Bu = ROL32((Asi0^Di0), 30); + Ba = ROL32((Abo1^Do1), 14); + Be = ROL32((Agu1^Du1), 10); + Aka0 = Ba ^((~Be)& Bi ); + Ame0 = Be ^((~Bi)& Bo ); + Asi0 = Bi ^((~Bo)& Bu ); + Abo1 = Bo ^((~Bu)& Ba ); + Agu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Asa0^Da0), 9); + Ba = ROL32((Abe1^De1), 1); + Be = ROL32((Agi0^Di0), 3); + Bi = ROL32((Ako1^Do1), 13); + Bo = ROL32((Amu0^Du0), 4); + Asa0 = Ba ^((~Be)& Bi ); + Abe1 = Be ^((~Bi)& Bo ); + Agi0 = Bi ^((~Bo)& Bu ); + Ako1 = Bo ^((~Bu)& Ba ); + Amu0 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Asa1^Da1), 9); + Ba = (Abe0^De0); + Be = ROL32((Agi1^Di1), 3); + Bi = ROL32((Ako0^Do0), 12); + Bo = ROL32((Amu1^Du1), 4); + Asa1 = Ba ^((~Be)& Bi ); + Abe0 = Be ^((~Bi)& Bo ); + Agi1 = Bi ^((~Bo)& Bu ); + Ako0 = Bo ^((~Bu)& Ba ); + Amu1 = Bu ^((~Ba)& Be ); + + Be = ROL32((Aga0^Da0), 18); + Bi = ROL32((Ake0^De0), 5); + Bo = ROL32((Ami1^Di1), 8); + Bu = ROL32((Aso0^Do0), 28); + Ba = ROL32((Abu1^Du1), 14); + Aga0 = Ba ^((~Be)& Bi ); + Ake0 = Be ^((~Bi)& Bo ); + Ami1 = Bi ^((~Bo)& Bu ); + Aso0 = Bo ^((~Bu)& Ba ); + Abu1 = Bu ^((~Ba)& Be ); + + Be = ROL32((Aga1^Da1), 18); + Bi = ROL32((Ake1^De1), 5); + Bo = ROL32((Ami0^Di0), 7); + Bu = ROL32((Aso1^Do1), 28); + Ba = ROL32((Abu0^Du0), 13); + Aga1 = Ba ^((~Be)& Bi ); + Ake1 = Be ^((~Bi)& Bo ); + Ami0 = Bi ^((~Bo)& Bu ); + Aso1 = Bo ^((~Bu)& Ba ); + Abu0 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Ama1^Da1), 21); + Bu = ROL32((Ase0^De0), 1); + Ba = ROL32((Abi0^Di0), 31); + Be = ROL32((Ago1^Do1), 28); + Bi = ROL32((Aku1^Du1), 20); + Ama1 = Ba ^((~Be)& Bi ); + Ase0 = Be ^((~Bi)& Bo ); + Abi0 = Bi ^((~Bo)& Bu ); + Ago1 = Bo ^((~Bu)& Ba ); + Aku1 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Ama0^Da0), 20); + Bu = ROL32((Ase1^De1), 1); + Ba = ROL32((Abi1^Di1), 31); + Be = ROL32((Ago0^Do0), 27); + Bi = ROL32((Aku0^Du0), 19); + Ama0 = Ba ^((~Be)& Bi ); + Ase1 = Be ^((~Bi)& Bo ); + Abi1 = Bi ^((~Bo)& Bu ); + Ago0 = Bo ^((~Bu)& Ba ); + Aku0 = Bu ^((~Ba)& Be ); + + KeccakAtoD_round1(); + + Ba = (Aba0^Da0); + Be = ROL32((Ame1^De0), 22); + Bi = ROL32((Agi1^Di1), 22); + Bo = ROL32((Aso1^Do1), 11); + Bu = ROL32((Aku1^Du0), 7); + Aba0 = Ba ^((~Be)& Bi ); + Aba0 ^= *(pRoundConstants++); + Ame1 = Be ^((~Bi)& Bo ); + Agi1 = Bi ^((~Bo)& Bu ); + Aso1 = Bo ^((~Bu)& Ba ); + Aku1 = Bu ^((~Ba)& Be ); + + Ba = (Aba1^Da1); + Be = ROL32((Ame0^De1), 22); + Bi = ROL32((Agi0^Di0), 21); + Bo = ROL32((Aso0^Do0), 10); + Bu = ROL32((Aku0^Du1), 7); + Aba1 = Ba ^((~Be)& Bi ); + Aba1 ^= *(pRoundConstants++); + Ame0 = Be ^((~Bi)& Bo ); + Agi0 = Bi ^((~Bo)& Bu ); + Aso0 = Bo ^((~Bu)& Ba ); + Aku0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Asa1^Da1), 2); + Bo = ROL32((Ake1^De1), 23); + Bu = ROL32((Abi1^Di1), 31); + Ba = ROL32((Amo1^Do0), 14); + Be = ROL32((Agu0^Du0), 10); + Asa1 = Ba ^((~Be)& Bi ); + Ake1 = Be ^((~Bi)& Bo ); + Abi1 = Bi ^((~Bo)& Bu ); + Amo1 = Bo ^((~Bu)& Ba ); + Agu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Asa0^Da0), 1); + Bo = ROL32((Ake0^De0), 22); + Bu = ROL32((Abi0^Di0), 30); + Ba = ROL32((Amo0^Do1), 14); + Be = ROL32((Agu1^Du1), 10); + Asa0 = Ba ^((~Be)& Bi ); + Ake0 = Be ^((~Bi)& Bo ); + Abi0 = Bi ^((~Bo)& Bu ); + Amo0 = Bo ^((~Bu)& Ba ); + Agu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Ama1^Da0), 9); + Ba = ROL32((Age1^De1), 1); + Be = ROL32((Asi1^Di0), 3); + Bi = ROL32((Ako0^Do1), 13); + Bo = ROL32((Abu1^Du0), 4); + Ama1 = Ba ^((~Be)& Bi ); + Age1 = Be ^((~Bi)& Bo ); + Asi1 = Bi ^((~Bo)& Bu ); + Ako0 = Bo ^((~Bu)& Ba ); + Abu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Ama0^Da1), 9); + Ba = (Age0^De0); + Be = ROL32((Asi0^Di1), 3); + Bi = ROL32((Ako1^Do0), 12); + Bo = ROL32((Abu0^Du1), 4); + Ama0 = Ba ^((~Be)& Bi ); + Age0 = Be ^((~Bi)& Bo ); + Asi0 = Bi ^((~Bo)& Bu ); + Ako1 = Bo ^((~Bu)& Ba ); + Abu0 = Bu ^((~Ba)& Be ); + + Be = ROL32((Aka1^Da0), 18); + Bi = ROL32((Abe1^De0), 5); + Bo = ROL32((Ami0^Di1), 8); + Bu = ROL32((Ago1^Do0), 28); + Ba = ROL32((Asu1^Du1), 14); + Aka1 = Ba ^((~Be)& Bi ); + Abe1 = Be ^((~Bi)& Bo ); + Ami0 = Bi ^((~Bo)& Bu ); + Ago1 = Bo ^((~Bu)& Ba ); + Asu1 = Bu ^((~Ba)& Be ); + + Be = ROL32((Aka0^Da1), 18); + Bi = ROL32((Abe0^De1), 5); + Bo = ROL32((Ami1^Di0), 7); + Bu = ROL32((Ago0^Do1), 28); + Ba = ROL32((Asu0^Du0), 13); + Aka0 = Ba ^((~Be)& Bi ); + Abe0 = Be ^((~Bi)& Bo ); + Ami1 = Bi ^((~Bo)& Bu ); + Ago0 = Bo ^((~Bu)& Ba ); + Asu0 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Aga1^Da1), 21); + Bu = ROL32((Ase0^De0), 1); + Ba = ROL32((Aki1^Di0), 31); + Be = ROL32((Abo1^Do1), 28); + Bi = ROL32((Amu1^Du1), 20); + Aga1 = Ba ^((~Be)& Bi ); + Ase0 = Be ^((~Bi)& Bo ); + Aki1 = Bi ^((~Bo)& Bu ); + Abo1 = Bo ^((~Bu)& Ba ); + Amu1 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Aga0^Da0), 20); + Bu = ROL32((Ase1^De1), 1); + Ba = ROL32((Aki0^Di1), 31); + Be = ROL32((Abo0^Do0), 27); + Bi = ROL32((Amu0^Du0), 19); + Aga0 = Ba ^((~Be)& Bi ); + Ase1 = Be ^((~Bi)& Bo ); + Aki0 = Bi ^((~Bo)& Bu ); + Abo0 = Bo ^((~Bu)& Ba ); + Amu0 = Bu ^((~Ba)& Be ); + + KeccakAtoD_round2(); + + Ba = (Aba0^Da0); + Be = ROL32((Ake1^De0), 22); + Bi = ROL32((Asi0^Di1), 22); + Bo = ROL32((Ago0^Do1), 11); + Bu = ROL32((Amu1^Du0), 7); + Aba0 = Ba ^((~Be)& Bi ); + Aba0 ^= *(pRoundConstants++); + Ake1 = Be ^((~Bi)& Bo ); + Asi0 = Bi ^((~Bo)& Bu ); + Ago0 = Bo ^((~Bu)& Ba ); + Amu1 = Bu ^((~Ba)& Be ); + + Ba = (Aba1^Da1); + Be = ROL32((Ake0^De1), 22); + Bi = ROL32((Asi1^Di0), 21); + Bo = ROL32((Ago1^Do0), 10); + Bu = ROL32((Amu0^Du1), 7); + Aba1 = Ba ^((~Be)& Bi ); + Aba1 ^= *(pRoundConstants++); + Ake0 = Be ^((~Bi)& Bo ); + Asi1 = Bi ^((~Bo)& Bu ); + Ago1 = Bo ^((~Bu)& Ba ); + Amu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Ama0^Da1), 2); + Bo = ROL32((Abe0^De1), 23); + Bu = ROL32((Aki0^Di1), 31); + Ba = ROL32((Aso1^Do0), 14); + Be = ROL32((Agu0^Du0), 10); + Ama0 = Ba ^((~Be)& Bi ); + Abe0 = Be ^((~Bi)& Bo ); + Aki0 = Bi ^((~Bo)& Bu ); + Aso1 = Bo ^((~Bu)& Ba ); + Agu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Ama1^Da0), 1); + Bo = ROL32((Abe1^De0), 22); + Bu = ROL32((Aki1^Di0), 30); + Ba = ROL32((Aso0^Do1), 14); + Be = ROL32((Agu1^Du1), 10); + Ama1 = Ba ^((~Be)& Bi ); + Abe1 = Be ^((~Bi)& Bo ); + Aki1 = Bi ^((~Bo)& Bu ); + Aso0 = Bo ^((~Bu)& Ba ); + Agu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Aga1^Da0), 9); + Ba = ROL32((Ame0^De1), 1); + Be = ROL32((Abi1^Di0), 3); + Bi = ROL32((Ako1^Do1), 13); + Bo = ROL32((Asu1^Du0), 4); + Aga1 = Ba ^((~Be)& Bi ); + Ame0 = Be ^((~Bi)& Bo ); + Abi1 = Bi ^((~Bo)& Bu ); + Ako1 = Bo ^((~Bu)& Ba ); + Asu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Aga0^Da1), 9); + Ba = (Ame1^De0); + Be = ROL32((Abi0^Di1), 3); + Bi = ROL32((Ako0^Do0), 12); + Bo = ROL32((Asu0^Du1), 4); + Aga0 = Ba ^((~Be)& Bi ); + Ame1 = Be ^((~Bi)& Bo ); + Abi0 = Bi ^((~Bo)& Bu ); + Ako0 = Bo ^((~Bu)& Ba ); + Asu0 = Bu ^((~Ba)& Be ); + + Be = ROL32((Asa1^Da0), 18); + Bi = ROL32((Age1^De0), 5); + Bo = ROL32((Ami1^Di1), 8); + Bu = ROL32((Abo1^Do0), 28); + Ba = ROL32((Aku0^Du1), 14); + Asa1 = Ba ^((~Be)& Bi ); + Age1 = Be ^((~Bi)& Bo ); + Ami1 = Bi ^((~Bo)& Bu ); + Abo1 = Bo ^((~Bu)& Ba ); + Aku0 = Bu ^((~Ba)& Be ); + + Be = ROL32((Asa0^Da1), 18); + Bi = ROL32((Age0^De1), 5); + Bo = ROL32((Ami0^Di0), 7); + Bu = ROL32((Abo0^Do1), 28); + Ba = ROL32((Aku1^Du0), 13); + Asa0 = Ba ^((~Be)& Bi ); + Age0 = Be ^((~Bi)& Bo ); + Ami0 = Bi ^((~Bo)& Bu ); + Abo0 = Bo ^((~Bu)& Ba ); + Aku1 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Aka0^Da1), 21); + Bu = ROL32((Ase0^De0), 1); + Ba = ROL32((Agi1^Di0), 31); + Be = ROL32((Amo0^Do1), 28); + Bi = ROL32((Abu0^Du1), 20); + Aka0 = Ba ^((~Be)& Bi ); + Ase0 = Be ^((~Bi)& Bo ); + Agi1 = Bi ^((~Bo)& Bu ); + Amo0 = Bo ^((~Bu)& Ba ); + Abu0 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Aka1^Da0), 20); + Bu = ROL32((Ase1^De1), 1); + Ba = ROL32((Agi0^Di1), 31); + Be = ROL32((Amo1^Do0), 27); + Bi = ROL32((Abu1^Du0), 19); + Aka1 = Ba ^((~Be)& Bi ); + Ase1 = Be ^((~Bi)& Bo ); + Agi0 = Bi ^((~Bo)& Bu ); + Amo1 = Bo ^((~Bu)& Ba ); + Abu1 = Bu ^((~Ba)& Be ); + + KeccakAtoD_round3(); + + Ba = (Aba0^Da0); + Be = ROL32((Abe0^De0), 22); + Bi = ROL32((Abi0^Di1), 22); + Bo = ROL32((Abo0^Do1), 11); + Bu = ROL32((Abu0^Du0), 7); + Aba0 = Ba ^((~Be)& Bi ); + Aba0 ^= *(pRoundConstants++); + Abe0 = Be ^((~Bi)& Bo ); + Abi0 = Bi ^((~Bo)& Bu ); + Abo0 = Bo ^((~Bu)& Ba ); + Abu0 = Bu ^((~Ba)& Be ); + + Ba = (Aba1^Da1); + Be = ROL32((Abe1^De1), 22); + Bi = ROL32((Abi1^Di0), 21); + Bo = ROL32((Abo1^Do0), 10); + Bu = ROL32((Abu1^Du1), 7); + Aba1 = Ba ^((~Be)& Bi ); + Aba1 ^= *(pRoundConstants++); + Abe1 = Be ^((~Bi)& Bo ); + Abi1 = Bi ^((~Bo)& Bu ); + Abo1 = Bo ^((~Bu)& Ba ); + Abu1 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Aga0^Da1), 2); + Bo = ROL32((Age0^De1), 23); + Bu = ROL32((Agi0^Di1), 31); + Ba = ROL32((Ago0^Do0), 14); + Be = ROL32((Agu0^Du0), 10); + Aga0 = Ba ^((~Be)& Bi ); + Age0 = Be ^((~Bi)& Bo ); + Agi0 = Bi ^((~Bo)& Bu ); + Ago0 = Bo ^((~Bu)& Ba ); + Agu0 = Bu ^((~Ba)& Be ); + + Bi = ROL32((Aga1^Da0), 1); + Bo = ROL32((Age1^De0), 22); + Bu = ROL32((Agi1^Di0), 30); + Ba = ROL32((Ago1^Do1), 14); + Be = ROL32((Agu1^Du1), 10); + Aga1 = Ba ^((~Be)& Bi ); + Age1 = Be ^((~Bi)& Bo ); + Agi1 = Bi ^((~Bo)& Bu ); + Ago1 = Bo ^((~Bu)& Ba ); + Agu1 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Aka0^Da0), 9); + Ba = ROL32((Ake0^De1), 1); + Be = ROL32((Aki0^Di0), 3); + Bi = ROL32((Ako0^Do1), 13); + Bo = ROL32((Aku0^Du0), 4); + Aka0 = Ba ^((~Be)& Bi ); + Ake0 = Be ^((~Bi)& Bo ); + Aki0 = Bi ^((~Bo)& Bu ); + Ako0 = Bo ^((~Bu)& Ba ); + Aku0 = Bu ^((~Ba)& Be ); + + Bu = ROL32((Aka1^Da1), 9); + Ba = (Ake1^De0); + Be = ROL32((Aki1^Di1), 3); + Bi = ROL32((Ako1^Do0), 12); + Bo = ROL32((Aku1^Du1), 4); + Aka1 = Ba ^((~Be)& Bi ); + Ake1 = Be ^((~Bi)& Bo ); + Aki1 = Bi ^((~Bo)& Bu ); + Ako1 = Bo ^((~Bu)& Ba ); + Aku1 = Bu ^((~Ba)& Be ); + + Be = ROL32((Ama0^Da0), 18); + Bi = ROL32((Ame0^De0), 5); + Bo = ROL32((Ami0^Di1), 8); + Bu = ROL32((Amo0^Do0), 28); + Ba = ROL32((Amu0^Du1), 14); + Ama0 = Ba ^((~Be)& Bi ); + Ame0 = Be ^((~Bi)& Bo ); + Ami0 = Bi ^((~Bo)& Bu ); + Amo0 = Bo ^((~Bu)& Ba ); + Amu0 = Bu ^((~Ba)& Be ); + + Be = ROL32((Ama1^Da1), 18); + Bi = ROL32((Ame1^De1), 5); + Bo = ROL32((Ami1^Di0), 7); + Bu = ROL32((Amo1^Do1), 28); + Ba = ROL32((Amu1^Du0), 13); + Ama1 = Ba ^((~Be)& Bi ); + Ame1 = Be ^((~Bi)& Bo ); + Ami1 = Bi ^((~Bo)& Bu ); + Amo1 = Bo ^((~Bu)& Ba ); + Amu1 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Asa0^Da1), 21); + Bu = ROL32((Ase0^De0), 1); + Ba = ROL32((Asi0^Di0), 31); + Be = ROL32((Aso0^Do1), 28); + Bi = ROL32((Asu0^Du1), 20); + Asa0 = Ba ^((~Be)& Bi ); + Ase0 = Be ^((~Bi)& Bo ); + Asi0 = Bi ^((~Bo)& Bu ); + Aso0 = Bo ^((~Bu)& Ba ); + Asu0 = Bu ^((~Ba)& Be ); + + Bo = ROL32((Asa1^Da0), 20); + Bu = ROL32((Ase1^De1), 1); + Ba = ROL32((Asi1^Di1), 31); + Be = ROL32((Aso1^Do0), 27); + Bi = ROL32((Asu1^Du0), 19); + Asa1 = Ba ^((~Be)& Bi ); + Ase1 = Be ^((~Bi)& Bo ); + Asi1 = Bi ^((~Bo)& Bu ); + Aso1 = Bo ^((~Bu)& Ba ); + Asu1 = Bu ^((~Ba)& Be ); + } + while ( *pRoundConstants != 0xFF ); + + #undef Aba0 + #undef Aba1 + #undef Abe0 + #undef Abe1 + #undef Abi0 + #undef Abi1 + #undef Abo0 + #undef Abo1 + #undef Abu0 + #undef Abu1 + #undef Aga0 + #undef Aga1 + #undef Age0 + #undef Age1 + #undef Agi0 + #undef Agi1 + #undef Ago0 + #undef Ago1 + #undef Agu0 + #undef Agu1 + #undef Aka0 + #undef Aka1 + #undef Ake0 + #undef Ake1 + #undef Aki0 + #undef Aki1 + #undef Ako0 + #undef Ako1 + #undef Aku0 + #undef Aku1 + #undef Ama0 + #undef Ama1 + #undef Ame0 + #undef Ame1 + #undef Ami0 + #undef Ami1 + #undef Amo0 + #undef Amo1 + #undef Amu0 + #undef Amu1 + #undef Asa0 + #undef Asa1 + #undef Ase0 + #undef Ase1 + #undef Asi0 + #undef Asi1 + #undef Aso0 + #undef Aso1 + #undef Asu0 + #undef Asu1 + } +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_12rounds(void *state) +{ + KeccakP1600_Permute_Nrounds(state, 12); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_24rounds(void *state) +{ + KeccakP1600_Permute_Nrounds(state, 24); +} diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h index 9501c64b186..067b58c45a8 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h @@ -1,3 +1,3 @@ -#define KeccakP1600_implementation_config "lane complementing, all rounds unrolled" -#define KeccakP1600_fullUnrolling -#define KeccakP1600_useLaneComplementing +#define KeccakP1600_implementation_config "lane complementing, all rounds unrolled" +#define KeccakP1600_fullUnrolling +#define KeccakP1600_useLaneComplementing diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-opt64.c b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-opt64.c index c90010dd925..c9e1a29b281 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-opt64.c +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-opt64.c @@ -1,474 +1,474 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -#include -/* #include "brg_endian.h" */ -#include "KeccakP-1600-opt64-config.h" - -#if NOT_PYTHON -typedef unsigned char UINT8; -/* typedef unsigned long long int UINT64; */ -#endif - -#if defined(KeccakP1600_useLaneComplementing) -#define UseBebigokimisa -#endif - -#if defined(_MSC_VER) -#define ROL64(a, offset) _rotl64(a, offset) -#elif defined(KeccakP1600_useSHLD) - #define ROL64(x,N) ({ \ - register UINT64 __out; \ - register UINT64 __in = x; \ - __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ - __out; \ - }) -#else -#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) -#endif - -#include "KeccakP-1600-64.macros" -#ifdef KeccakP1600_fullUnrolling -#define FullUnrolling -#else -#define Unrolling KeccakP1600_unrolling -#endif -#include "KeccakP-1600-unrolling.macros" -#include "SnP-Relaned.h" - -static const UINT64 KeccakF1600RoundConstants[24] = { - 0x0000000000000001ULL, - 0x0000000000008082ULL, - 0x800000000000808aULL, - 0x8000000080008000ULL, - 0x000000000000808bULL, - 0x0000000080000001ULL, - 0x8000000080008081ULL, - 0x8000000000008009ULL, - 0x000000000000008aULL, - 0x0000000000000088ULL, - 0x0000000080008009ULL, - 0x000000008000000aULL, - 0x000000008000808bULL, - 0x800000000000008bULL, - 0x8000000000008089ULL, - 0x8000000000008003ULL, - 0x8000000000008002ULL, - 0x8000000000000080ULL, - 0x000000000000800aULL, - 0x800000008000000aULL, - 0x8000000080008081ULL, - 0x8000000000008080ULL, - 0x0000000080000001ULL, - 0x8000000080008008ULL }; - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Initialize(void *state) -{ - memset(state, 0, 200); -#ifdef KeccakP1600_useLaneComplementing - ((UINT64*)state)[ 1] = ~(UINT64)0; - ((UINT64*)state)[ 2] = ~(UINT64)0; - ((UINT64*)state)[ 8] = ~(UINT64)0; - ((UINT64*)state)[12] = ~(UINT64)0; - ((UINT64*)state)[17] = ~(UINT64)0; - ((UINT64*)state)[20] = ~(UINT64)0; -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - UINT64 lane; - if (length == 0) - return; - if (length == 1) - lane = data[0]; - else { - lane = 0; - memcpy(&lane, data, length); - } - lane <<= offset*8; -#else - UINT64 lane = 0; - unsigned int i; - for(i=0; i>= offset*8; - for(i=0; i>= 8; - } -#endif -} - -/* ---------------------------------------------------------------- */ - -#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) -void fromWordToBytes(UINT8 *bytes, const UINT64 word) -{ - unsigned int i; - - for(i=0; i<(64/8); i++) - bytes[i] = (word >> (8*i)) & 0xFF; -} -#endif - -void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - memcpy(data, state, laneCount*8); -#else - unsigned int i; - - for(i=0; i 1) { - ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; - if (laneCount > 2) { - ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; - if (laneCount > 8) { - ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; - if (laneCount > 12) { - ((UINT64*)data)[12] = ~((UINT64*)data)[12]; - if (laneCount > 17) { - ((UINT64*)data)[17] = ~((UINT64*)data)[17]; - if (laneCount > 20) { - ((UINT64*)data)[20] = ~((UINT64*)data)[20]; - } - } - } - } - } - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) -{ - SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - UINT64 lane = ((UINT64*)state)[lanePosition]; -#ifdef KeccakP1600_useLaneComplementing - if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) - lane = ~lane; -#endif -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - { - unsigned int i; - UINT64 lane1[1]; - lane1[0] = lane; - for(i=0; i>= offset*8; - for(i=0; i>= 8; - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) -{ - unsigned int i; -#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) - unsigned char temp[8]; - unsigned int j; -#endif - - for(i=0; i 1) { - ((UINT64*)output)[ 1] = ~((UINT64*)output)[ 1]; - if (laneCount > 2) { - ((UINT64*)output)[ 2] = ~((UINT64*)output)[ 2]; - if (laneCount > 8) { - ((UINT64*)output)[ 8] = ~((UINT64*)output)[ 8]; - if (laneCount > 12) { - ((UINT64*)output)[12] = ~((UINT64*)output)[12]; - if (laneCount > 17) { - ((UINT64*)output)[17] = ~((UINT64*)output)[17]; - if (laneCount > 20) { - ((UINT64*)output)[20] = ~((UINT64*)output)[20]; - } - } - } - } - } - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen) -{ - size_t originalDataByteLen = dataByteLen; - declareABCDE - #ifndef KeccakP1600_fullUnrolling - unsigned int i; - #endif - UINT64 *stateAsLanes = (UINT64*)state; - UINT64 *inDataAsLanes = (UINT64*)data; - - copyFromState(A, stateAsLanes) - while(dataByteLen >= laneCount*8) { - addInput(A, inDataAsLanes, laneCount) - rounds24 - inDataAsLanes += laneCount; - dataByteLen -= laneCount*8; - } - copyToState(stateAsLanes, A) - return originalDataByteLen - dataByteLen; -} +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include +#include +/* #include "brg_endian.h" */ +#include "KeccakP-1600-opt64-config.h" + +#if NOT_PYTHON +typedef unsigned char UINT8; +/* typedef unsigned long long int UINT64; */ +#endif + +#if defined(KeccakP1600_useLaneComplementing) +#define UseBebigokimisa +#endif + +#if defined(_MSC_VER) +#define ROL64(a, offset) _rotl64(a, offset) +#elif defined(KeccakP1600_useSHLD) + #define ROL64(x,N) ({ \ + register UINT64 __out; \ + register UINT64 __in = x; \ + __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ + __out; \ + }) +#else +#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) +#endif + +#include "KeccakP-1600-64.macros" +#ifdef KeccakP1600_fullUnrolling +#define FullUnrolling +#else +#define Unrolling KeccakP1600_unrolling +#endif +#include "KeccakP-1600-unrolling.macros" +#include "SnP-Relaned.h" + +static const UINT64 KeccakF1600RoundConstants[24] = { + 0x0000000000000001ULL, + 0x0000000000008082ULL, + 0x800000000000808aULL, + 0x8000000080008000ULL, + 0x000000000000808bULL, + 0x0000000080000001ULL, + 0x8000000080008081ULL, + 0x8000000000008009ULL, + 0x000000000000008aULL, + 0x0000000000000088ULL, + 0x0000000080008009ULL, + 0x000000008000000aULL, + 0x000000008000808bULL, + 0x800000000000008bULL, + 0x8000000000008089ULL, + 0x8000000000008003ULL, + 0x8000000000008002ULL, + 0x8000000000000080ULL, + 0x000000000000800aULL, + 0x800000008000000aULL, + 0x8000000080008081ULL, + 0x8000000000008080ULL, + 0x0000000080000001ULL, + 0x8000000080008008ULL }; + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Initialize(void *state) +{ + memset(state, 0, 200); +#ifdef KeccakP1600_useLaneComplementing + ((UINT64*)state)[ 1] = ~(UINT64)0; + ((UINT64*)state)[ 2] = ~(UINT64)0; + ((UINT64*)state)[ 8] = ~(UINT64)0; + ((UINT64*)state)[12] = ~(UINT64)0; + ((UINT64*)state)[17] = ~(UINT64)0; + ((UINT64*)state)[20] = ~(UINT64)0; +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + UINT64 lane; + if (length == 0) + return; + if (length == 1) + lane = data[0]; + else { + lane = 0; + memcpy(&lane, data, length); + } + lane <<= offset*8; +#else + UINT64 lane = 0; + unsigned int i; + for(i=0; i>= offset*8; + for(i=0; i>= 8; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) +void fromWordToBytes(UINT8 *bytes, const UINT64 word) +{ + unsigned int i; + + for(i=0; i<(64/8); i++) + bytes[i] = (word >> (8*i)) & 0xFF; +} +#endif + +void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + memcpy(data, state, laneCount*8); +#else + unsigned int i; + + for(i=0; i 1) { + ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; + if (laneCount > 2) { + ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; + if (laneCount > 8) { + ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; + if (laneCount > 12) { + ((UINT64*)data)[12] = ~((UINT64*)data)[12]; + if (laneCount > 17) { + ((UINT64*)data)[17] = ~((UINT64*)data)[17]; + if (laneCount > 20) { + ((UINT64*)data)[20] = ~((UINT64*)data)[20]; + } + } + } + } + } + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + UINT64 lane = ((UINT64*)state)[lanePosition]; +#ifdef KeccakP1600_useLaneComplementing + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + lane = ~lane; +#endif +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + { + unsigned int i; + UINT64 lane1[1]; + lane1[0] = lane; + for(i=0; i>= offset*8; + for(i=0; i>= 8; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) +{ + unsigned int i; +#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) + unsigned char temp[8]; + unsigned int j; +#endif + + for(i=0; i 1) { + ((UINT64*)output)[ 1] = ~((UINT64*)output)[ 1]; + if (laneCount > 2) { + ((UINT64*)output)[ 2] = ~((UINT64*)output)[ 2]; + if (laneCount > 8) { + ((UINT64*)output)[ 8] = ~((UINT64*)output)[ 8]; + if (laneCount > 12) { + ((UINT64*)output)[12] = ~((UINT64*)output)[12]; + if (laneCount > 17) { + ((UINT64*)output)[17] = ~((UINT64*)output)[17]; + if (laneCount > 20) { + ((UINT64*)output)[20] = ~((UINT64*)output)[20]; + } + } + } + } + } + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen) +{ + size_t originalDataByteLen = dataByteLen; + declareABCDE + #ifndef KeccakP1600_fullUnrolling + unsigned int i; + #endif + UINT64 *stateAsLanes = (UINT64*)state; + UINT64 *inDataAsLanes = (UINT64*)data; + + copyFromState(A, stateAsLanes) + while(dataByteLen >= laneCount*8) { + addInput(A, inDataAsLanes, laneCount) + rounds24 + inDataAsLanes += laneCount; + dataByteLen -= laneCount*8; + } + copyToState(stateAsLanes, A) + return originalDataByteLen - dataByteLen; +} diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros index 405ce29724c..ae70d90f0e4 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros @@ -1,185 +1,185 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#if (defined(FullUnrolling)) -#define rounds24 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta( 0, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 1, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 2, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 3, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 4, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 5, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 6, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 7, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 8, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 9, E, A) \ - thetaRhoPiChiIotaPrepareTheta(10, A, E) \ - thetaRhoPiChiIotaPrepareTheta(11, E, A) \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#define rounds12 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#elif (Unrolling == 12) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=12) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#elif (Unrolling == 6) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=6) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=6) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ - } \ - -#elif (Unrolling == 4) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=4) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=4) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - } \ - -#elif (Unrolling == 3) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=3) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - copyStateVariables(A, E) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=3) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - copyStateVariables(A, E) \ - } \ - -#elif (Unrolling == 2) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=2) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=2) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - } \ - -#elif (Unrolling == 1) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i++) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - copyStateVariables(A, E) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i++) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - copyStateVariables(A, E) \ - } \ - -#else -#error "Unrolling is not correctly specified!" -#endif +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#if (defined(FullUnrolling)) +#define rounds24 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta( 0, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 1, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 2, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 3, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 4, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 5, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 6, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 7, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 8, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 9, E, A) \ + thetaRhoPiChiIotaPrepareTheta(10, A, E) \ + thetaRhoPiChiIotaPrepareTheta(11, E, A) \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#define rounds12 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#elif (Unrolling == 12) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=12) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#elif (Unrolling == 6) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=6) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=6) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ + } \ + +#elif (Unrolling == 4) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=4) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=4) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + } \ + +#elif (Unrolling == 3) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=3) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=3) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + copyStateVariables(A, E) \ + } \ + +#elif (Unrolling == 2) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#elif (Unrolling == 1) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i++) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i++) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + copyStateVariables(A, E) \ + } \ + +#else +#error "Unrolling is not correctly specified!" +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.c b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.c index f3bfdf0b947..5f455d06c72 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.c +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.c @@ -1,92 +1,92 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include "KeccakSponge.h" - -#ifdef KeccakReference - #include "displayIntermediateValues.h" // Y_IGNORE -#endif - -#ifndef KeccakP200_excluded - #include "KeccakP-200-SnP.h" // Y_IGNORE - - #define prefix KeccakWidth200 - #define SnP KeccakP200 - #define SnP_width 200 - #define SnP_Permute KeccakP200_Permute_18rounds - #if defined(KeccakF200_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP400_excluded - #include "KeccakP-400-SnP.h" // Y_IGNORE - - #define prefix KeccakWidth400 - #define SnP KeccakP400 - #define SnP_width 400 - #define SnP_Permute KeccakP400_Permute_20rounds - #if defined(KeccakF400_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP800_excluded - #include "KeccakP-800-SnP.h" // Y_IGNORE - - #define prefix KeccakWidth800 - #define SnP KeccakP800 - #define SnP_width 800 - #define SnP_Permute KeccakP800_Permute_22rounds - #if defined(KeccakF800_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF800_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP1600_excluded - #include "KeccakP-1600-SnP.h" - - #define prefix KeccakWidth1600 - #define SnP KeccakP1600 - #define SnP_width 1600 - #define SnP_Permute KeccakP1600_Permute_24rounds - #if defined(KeccakF1600_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "KeccakSponge.h" + +#ifdef KeccakReference + #include "displayIntermediateValues.h" // Y_IGNORE +#endif + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" // Y_IGNORE + + #define prefix KeccakWidth200 + #define SnP KeccakP200 + #define SnP_width 200 + #define SnP_Permute KeccakP200_Permute_18rounds + #if defined(KeccakF200_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifndef KeccakP400_excluded + #include "KeccakP-400-SnP.h" // Y_IGNORE + + #define prefix KeccakWidth400 + #define SnP KeccakP400 + #define SnP_width 400 + #define SnP_Permute KeccakP400_Permute_20rounds + #if defined(KeccakF400_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifndef KeccakP800_excluded + #include "KeccakP-800-SnP.h" // Y_IGNORE + + #define prefix KeccakWidth800 + #define SnP KeccakP800 + #define SnP_width 800 + #define SnP_Permute KeccakP800_Permute_22rounds + #if defined(KeccakF800_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF800_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifndef KeccakP1600_excluded + #include "KeccakP-1600-SnP.h" + + #define prefix KeccakWidth1600 + #define SnP KeccakP1600 + #define SnP_width 1600 + #define SnP_Permute KeccakP1600_Permute_24rounds + #if defined(KeccakF1600_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.h b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.h index cead2af9a3f..b90906acdd1 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.h +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.h @@ -1,172 +1,172 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakSponge_h_ -#define _KeccakSponge_h_ - -/** General information - * - * The following type and functions are not actually implemented. Their - * documentation is generic, with the prefix Prefix replaced by - * - KeccakWidth200 for a sponge function based on Keccak-f[200] - * - KeccakWidth400 for a sponge function based on Keccak-f[400] - * - KeccakWidth800 for a sponge function based on Keccak-f[800] - * - KeccakWidth1600 for a sponge function based on Keccak-f[1600] - * - * In all these functions, the rate and capacity must sum to the width of the - * chosen permutation. For instance, to use the sponge function - * Keccak[r=1344, c=256], one must use KeccakWidth1600_Sponge() or a combination - * of KeccakWidth1600_SpongeInitialize(), KeccakWidth1600_SpongeAbsorb(), - * KeccakWidth1600_SpongeAbsorbLastFewBits() and - * KeccakWidth1600_SpongeSqueeze(). - * - * The Prefix_SpongeInstance contains the sponge instance attributes for use - * with the Prefix_Sponge* functions. - * It gathers the state processed by the permutation as well as the rate, - * the position of input/output bytes in the state and the phase - * (absorbing or squeezing). - */ - -#ifdef DontReallyInclude_DocumentationOnly -/** Function to evaluate the sponge function Keccak[r, c] in a single call. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @param input Pointer to the input message (before the suffix). - * @param inputByteLen The length of the input message in bytes. - * @param suffix Byte containing from 0 to 7 suffix bits - * that must be absorbed after @a input. - * These n bits must be in the least significant bit positions. - * These bits must be delimited with a bit 1 at position n - * (counting from 0=LSB to 7=MSB) and followed by bits 0 - * from position n+1 to position 7. - * Some examples: - * - If no bits are to be absorbed, then @a suffix must be 0x01. - * - If the 2-bit sequence 0,0 is to be absorbed, @a suffix must be 0x04. - * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a suffix must be 0x32. - * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a suffix must be 0x8B. - * . - * @param output Pointer to the output buffer. - * @param outputByteLen The desired number of output bytes. - * @pre One must have r+c equal to the supported width of this implementation - * and the rate a multiple of 8 bits (one byte) in this implementation. - * @pre @a suffix ≠ 0x00 - * @return Zero if successful, 1 otherwise. - */ -int Prefix_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); - -/** - * Function to initialize the state of the Keccak[r, c] sponge function. - * The phase of the sponge function is set to absorbing. - * @param spongeInstance Pointer to the sponge instance to be initialized. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @pre One must have r+c equal to the supported width of this implementation - * and the rate a multiple of 8 bits (one byte) in this implementation. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeInitialize(Prefix_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); - -/** - * Function to give input data bytes for the sponge function to absorb. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param data Pointer to the input data. - * @param dataByteLen The number of input bytes provided in the input data. - * @pre The sponge function must be in the absorbing phase, - * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() - * must not have been called before. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeAbsorb(Prefix_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); - -/** - * Function to give input data bits for the sponge function to absorb - * and then to switch to the squeezing phase. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param delimitedData Byte containing from 0 to 7 trailing bits - * that must be absorbed. - * These n bits must be in the least significant bit positions. - * These bits must be delimited with a bit 1 at position n - * (counting from 0=LSB to 7=MSB) and followed by bits 0 - * from position n+1 to position 7. - * Some examples: - * - If no bits are to be absorbed, then @a delimitedData must be 0x01. - * - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04. - * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32. - * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B. - * . - * @pre The sponge function must be in the absorbing phase, - * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() - * must not have been called before. - * @pre @a delimitedData ≠ 0x00 - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeAbsorbLastFewBits(Prefix_SpongeInstance *spongeInstance, unsigned char delimitedData); - -/** - * Function to squeeze output data from the sponge function. - * If the sponge function was in the absorbing phase, this function - * switches it to the squeezing phase - * as if Prefix_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param data Pointer to the buffer where to store the output data. - * @param dataByteLen The number of output bytes desired. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeSqueeze(Prefix_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); -#endif - -#include -#include "align.h" - -#define KCP_DeclareSpongeStructure(prefix, size, alignment) \ - ALIGN(alignment) typedef struct prefix##_SpongeInstanceStruct { \ - unsigned char state[size]; \ - unsigned int rate; \ - unsigned int byteIOIndex; \ - int squeezing; \ - } prefix##_SpongeInstance; - -#define KCP_DeclareSpongeFunctions(prefix) \ - int prefix##_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); \ - int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); \ - int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); \ - int prefix##_SpongeAbsorbLastFewBits(prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \ - int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); - -#ifndef KeccakP200_excluded - #include "KeccakP-200-SnP.h" // Y_IGNORE - KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth200) -#endif - -#ifndef KeccakP400_excluded - #include "KeccakP-400-SnP.h" // Y_IGNORE - KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth400) -#endif - -#ifndef KeccakP800_excluded - #include "KeccakP-800-SnP.h" // Y_IGNORE - KCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth800) -#endif - -#ifndef KeccakP1600_excluded - #include "KeccakP-1600-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth1600) -#endif - -#endif +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakSponge_h_ +#define _KeccakSponge_h_ + +/** General information + * + * The following type and functions are not actually implemented. Their + * documentation is generic, with the prefix Prefix replaced by + * - KeccakWidth200 for a sponge function based on Keccak-f[200] + * - KeccakWidth400 for a sponge function based on Keccak-f[400] + * - KeccakWidth800 for a sponge function based on Keccak-f[800] + * - KeccakWidth1600 for a sponge function based on Keccak-f[1600] + * + * In all these functions, the rate and capacity must sum to the width of the + * chosen permutation. For instance, to use the sponge function + * Keccak[r=1344, c=256], one must use KeccakWidth1600_Sponge() or a combination + * of KeccakWidth1600_SpongeInitialize(), KeccakWidth1600_SpongeAbsorb(), + * KeccakWidth1600_SpongeAbsorbLastFewBits() and + * KeccakWidth1600_SpongeSqueeze(). + * + * The Prefix_SpongeInstance contains the sponge instance attributes for use + * with the Prefix_Sponge* functions. + * It gathers the state processed by the permutation as well as the rate, + * the position of input/output bytes in the state and the phase + * (absorbing or squeezing). + */ + +#ifdef DontReallyInclude_DocumentationOnly +/** Function to evaluate the sponge function Keccak[r, c] in a single call. + * @param rate The value of the rate r. + * @param capacity The value of the capacity c. + * @param input Pointer to the input message (before the suffix). + * @param inputByteLen The length of the input message in bytes. + * @param suffix Byte containing from 0 to 7 suffix bits + * that must be absorbed after @a input. + * These n bits must be in the least significant bit positions. + * These bits must be delimited with a bit 1 at position n + * (counting from 0=LSB to 7=MSB) and followed by bits 0 + * from position n+1 to position 7. + * Some examples: + * - If no bits are to be absorbed, then @a suffix must be 0x01. + * - If the 2-bit sequence 0,0 is to be absorbed, @a suffix must be 0x04. + * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a suffix must be 0x32. + * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a suffix must be 0x8B. + * . + * @param output Pointer to the output buffer. + * @param outputByteLen The desired number of output bytes. + * @pre One must have r+c equal to the supported width of this implementation + * and the rate a multiple of 8 bits (one byte) in this implementation. + * @pre @a suffix ≠ 0x00 + * @return Zero if successful, 1 otherwise. + */ +int Prefix_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); + +/** + * Function to initialize the state of the Keccak[r, c] sponge function. + * The phase of the sponge function is set to absorbing. + * @param spongeInstance Pointer to the sponge instance to be initialized. + * @param rate The value of the rate r. + * @param capacity The value of the capacity c. + * @pre One must have r+c equal to the supported width of this implementation + * and the rate a multiple of 8 bits (one byte) in this implementation. + * @return Zero if successful, 1 otherwise. + */ +int Prefix_SpongeInitialize(Prefix_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); + +/** + * Function to give input data bytes for the sponge function to absorb. + * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). + * @param data Pointer to the input data. + * @param dataByteLen The number of input bytes provided in the input data. + * @pre The sponge function must be in the absorbing phase, + * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() + * must not have been called before. + * @return Zero if successful, 1 otherwise. + */ +int Prefix_SpongeAbsorb(Prefix_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); + +/** + * Function to give input data bits for the sponge function to absorb + * and then to switch to the squeezing phase. + * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). + * @param delimitedData Byte containing from 0 to 7 trailing bits + * that must be absorbed. + * These n bits must be in the least significant bit positions. + * These bits must be delimited with a bit 1 at position n + * (counting from 0=LSB to 7=MSB) and followed by bits 0 + * from position n+1 to position 7. + * Some examples: + * - If no bits are to be absorbed, then @a delimitedData must be 0x01. + * - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04. + * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32. + * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B. + * . + * @pre The sponge function must be in the absorbing phase, + * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() + * must not have been called before. + * @pre @a delimitedData ≠ 0x00 + * @return Zero if successful, 1 otherwise. + */ +int Prefix_SpongeAbsorbLastFewBits(Prefix_SpongeInstance *spongeInstance, unsigned char delimitedData); + +/** + * Function to squeeze output data from the sponge function. + * If the sponge function was in the absorbing phase, this function + * switches it to the squeezing phase + * as if Prefix_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called. + * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). + * @param data Pointer to the buffer where to store the output data. + * @param dataByteLen The number of output bytes desired. + * @return Zero if successful, 1 otherwise. + */ +int Prefix_SpongeSqueeze(Prefix_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); +#endif + +#include +#include "align.h" + +#define KCP_DeclareSpongeStructure(prefix, size, alignment) \ + ALIGN(alignment) typedef struct prefix##_SpongeInstanceStruct { \ + unsigned char state[size]; \ + unsigned int rate; \ + unsigned int byteIOIndex; \ + int squeezing; \ + } prefix##_SpongeInstance; + +#define KCP_DeclareSpongeFunctions(prefix) \ + int prefix##_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); \ + int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); \ + int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); \ + int prefix##_SpongeAbsorbLastFewBits(prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \ + int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); + +#ifndef KeccakP200_excluded + #include "KeccakP-200-SnP.h" // Y_IGNORE + KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth200) +#endif + +#ifndef KeccakP400_excluded + #include "KeccakP-400-SnP.h" // Y_IGNORE + KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth400) +#endif + +#ifndef KeccakP800_excluded + #include "KeccakP-800-SnP.h" // Y_IGNORE + KCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth800) +#endif + +#ifndef KeccakP1600_excluded + #include "KeccakP-1600-SnP.h" + KCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment) + KCP_DeclareSpongeFunctions(KeccakWidth1600) +#endif + +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.inc b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.inc index e10739deafa..1b8f5f81c12 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.inc +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/KeccakSponge.inc @@ -1,332 +1,332 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define JOIN0(a, b) a ## b -#define JOIN(a, b) JOIN0(a, b) - -#define Sponge JOIN(prefix, _Sponge) -#define SpongeInstance JOIN(prefix, _SpongeInstance) -#define SpongeInitialize JOIN(prefix, _SpongeInitialize) -#define SpongeAbsorb JOIN(prefix, _SpongeAbsorb) -#define SpongeAbsorbLastFewBits JOIN(prefix, _SpongeAbsorbLastFewBits) -#define SpongeSqueeze JOIN(prefix, _SpongeSqueeze) - -#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) -#define SnP_stateAlignment JOIN(SnP, _stateAlignment) -#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) -#define SnP_Initialize JOIN(SnP, _Initialize) -#define SnP_AddByte JOIN(SnP, _AddByte) -#define SnP_AddBytes JOIN(SnP, _AddBytes) -#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) - -int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen) -{ - ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes]; - unsigned int partialBlock; - const unsigned char *curInput = input; - unsigned char *curOutput = output; - unsigned int rateInBytes = rate/8; - - if (rate+capacity != SnP_width) - return 1; - if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) - return 1; - if (suffix == 0) - return 1; - - /* Initialize the state */ - - SnP_StaticInitialize(); - SnP_Initialize(state); - - /* First, absorb whole blocks */ - -#ifdef SnP_FastLoop_Absorb - if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) { - /* fast lane: whole lane rate */ - - size_t j; - j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen); - curInput += j; - inputByteLen -= j; - } -#endif - while(inputByteLen >= (size_t)rateInBytes) { - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", curInput, rateInBytes); - #endif - SnP_AddBytes(state, curInput, 0, rateInBytes); - SnP_Permute(state); - curInput += rateInBytes; - inputByteLen -= rateInBytes; - } - - /* Then, absorb what remains */ - - partialBlock = (unsigned int)inputByteLen; - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock); - #endif - SnP_AddBytes(state, curInput, 0, partialBlock); - - /* Finally, absorb the suffix */ - - #ifdef KeccakReference - { - unsigned char delimitedData1[1]; - delimitedData1[0] = suffix; - displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); - } - #endif - /* Last few bits, whose delimiter coincides with first bit of padding */ - - SnP_AddByte(state, suffix, partialBlock); - /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ - - if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1))) - SnP_Permute(state); - /* Second bit of padding */ - - SnP_AddByte(state, 0x80, rateInBytes-1); - #ifdef KeccakReference - { - unsigned char block[SnP_width/8]; - memset(block, 0, SnP_width/8); - block[rateInBytes-1] = 0x80; - displayBytes(1, "Second bit of padding", block, rateInBytes); - } - #endif - SnP_Permute(state); - #ifdef KeccakReference - displayText(1, "--- Switching to squeezing phase ---"); - #endif - - /* First, output whole blocks */ - - while(outputByteLen > (size_t)rateInBytes) { - SnP_ExtractBytes(state, curOutput, 0, rateInBytes); - SnP_Permute(state); - #ifdef KeccakReference - displayBytes(1, "Squeezed block", curOutput, rateInBytes); - #endif - curOutput += rateInBytes; - outputByteLen -= rateInBytes; - } - - /* Finally, output what remains */ - - partialBlock = (unsigned int)outputByteLen; - SnP_ExtractBytes(state, curOutput, 0, partialBlock); - #ifdef KeccakReference - displayBytes(1, "Squeezed block (part)", curOutput, partialBlock); - #endif - - return 0; -} - -/* ---------------------------------------------------------------- */ -/* ---------------------------------------------------------------- */ -/* ---------------------------------------------------------------- */ - -int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity) -{ - if (rate+capacity != SnP_width) - return 1; - if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) - return 1; - SnP_StaticInitialize(); - SnP_Initialize(instance->state); - instance->rate = rate; - instance->byteIOIndex = 0; - instance->squeezing = 0; - - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen) -{ - size_t i, j; - unsigned int partialBlock; - const unsigned char *curData; - unsigned int rateInBytes = instance->rate/8; - - if (instance->squeezing) - return 1; /* Too late for additional input */ - - - i = 0; - curData = data; - while(i < dataByteLen) { - if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { -#ifdef SnP_FastLoop_Absorb - /* processing full blocks first */ - - if ((rateInBytes % (SnP_width/200)) == 0) { - /* fast lane: whole lane rate */ - - j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i); - i += j; - curData += j; - } - else { -#endif - for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", curData, rateInBytes); - #endif - SnP_AddBytes(instance->state, curData, 0, rateInBytes); - SnP_Permute(instance->state); - curData+=rateInBytes; - } - i = dataByteLen - j; -#ifdef SnP_FastLoop_Absorb - } -#endif - } - else { - /* normal lane: using the message queue */ - - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) - partialBlock = rateInBytes-instance->byteIOIndex; - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); - #endif - i += partialBlock; - - SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock); - curData += partialBlock; - instance->byteIOIndex += partialBlock; - if (instance->byteIOIndex == rateInBytes) { - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - } - } - } - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData) -{ - unsigned int rateInBytes = instance->rate/8; - - if (delimitedData == 0) - return 1; - if (instance->squeezing) - return 1; /* Too late for additional input */ - - - #ifdef KeccakReference - { - unsigned char delimitedData1[1]; - delimitedData1[0] = delimitedData; - displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); - } - #endif - /* Last few bits, whose delimiter coincides with first bit of padding */ - - SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex); - /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ - - if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1))) - SnP_Permute(instance->state); - /* Second bit of padding */ - - SnP_AddByte(instance->state, 0x80, rateInBytes-1); - #ifdef KeccakReference - { - unsigned char block[SnP_width/8]; - memset(block, 0, SnP_width/8); - block[rateInBytes-1] = 0x80; - displayBytes(1, "Second bit of padding", block, rateInBytes); - } - #endif - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - instance->squeezing = 1; - #ifdef KeccakReference - displayText(1, "--- Switching to squeezing phase ---"); - #endif - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen) -{ - size_t i, j; - unsigned int partialBlock; - unsigned int rateInBytes = instance->rate/8; - unsigned char *curData; - - if (!instance->squeezing) - SpongeAbsorbLastFewBits(instance, 0x01); - - i = 0; - curData = data; - while(i < dataByteLen) { - if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { - for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { - SnP_Permute(instance->state); - SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); - #ifdef KeccakReference - displayBytes(1, "Squeezed block", curData, rateInBytes); - #endif - curData+=rateInBytes; - } - i = dataByteLen - j; - } - else { - /* normal lane: using the message queue */ - - if (instance->byteIOIndex == rateInBytes) { - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - } - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) - partialBlock = rateInBytes-instance->byteIOIndex; - i += partialBlock; - - SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); - #ifdef KeccakReference - displayBytes(1, "Squeezed block (part)", curData, partialBlock); - #endif - curData += partialBlock; - instance->byteIOIndex += partialBlock; - } - } - return 0; -} - -/* ---------------------------------------------------------------- */ - -#undef Sponge -#undef SpongeInstance -#undef SpongeInitialize -#undef SpongeAbsorb -#undef SpongeAbsorbLastFewBits -#undef SpongeSqueeze -#undef SnP_stateSizeInBytes -#undef SnP_stateAlignment -#undef SnP_StaticInitialize -#undef SnP_Initialize -#undef SnP_AddByte -#undef SnP_AddBytes -#undef SnP_ExtractBytes +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define Sponge JOIN(prefix, _Sponge) +#define SpongeInstance JOIN(prefix, _SpongeInstance) +#define SpongeInitialize JOIN(prefix, _SpongeInitialize) +#define SpongeAbsorb JOIN(prefix, _SpongeAbsorb) +#define SpongeAbsorbLastFewBits JOIN(prefix, _SpongeAbsorbLastFewBits) +#define SpongeSqueeze JOIN(prefix, _SpongeSqueeze) + +#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) +#define SnP_stateAlignment JOIN(SnP, _stateAlignment) +#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) +#define SnP_Initialize JOIN(SnP, _Initialize) +#define SnP_AddByte JOIN(SnP, _AddByte) +#define SnP_AddBytes JOIN(SnP, _AddBytes) +#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) + +int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen) +{ + ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes]; + unsigned int partialBlock; + const unsigned char *curInput = input; + unsigned char *curOutput = output; + unsigned int rateInBytes = rate/8; + + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) + return 1; + if (suffix == 0) + return 1; + + /* Initialize the state */ + + SnP_StaticInitialize(); + SnP_Initialize(state); + + /* First, absorb whole blocks */ + +#ifdef SnP_FastLoop_Absorb + if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) { + /* fast lane: whole lane rate */ + + size_t j; + j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen); + curInput += j; + inputByteLen -= j; + } +#endif + while(inputByteLen >= (size_t)rateInBytes) { + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed", curInput, rateInBytes); + #endif + SnP_AddBytes(state, curInput, 0, rateInBytes); + SnP_Permute(state); + curInput += rateInBytes; + inputByteLen -= rateInBytes; + } + + /* Then, absorb what remains */ + + partialBlock = (unsigned int)inputByteLen; + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock); + #endif + SnP_AddBytes(state, curInput, 0, partialBlock); + + /* Finally, absorb the suffix */ + + #ifdef KeccakReference + { + unsigned char delimitedData1[1]; + delimitedData1[0] = suffix; + displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); + } + #endif + /* Last few bits, whose delimiter coincides with first bit of padding */ + + SnP_AddByte(state, suffix, partialBlock); + /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ + + if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1))) + SnP_Permute(state); + /* Second bit of padding */ + + SnP_AddByte(state, 0x80, rateInBytes-1); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memset(block, 0, SnP_width/8); + block[rateInBytes-1] = 0x80; + displayBytes(1, "Second bit of padding", block, rateInBytes); + } + #endif + SnP_Permute(state); + #ifdef KeccakReference + displayText(1, "--- Switching to squeezing phase ---"); + #endif + + /* First, output whole blocks */ + + while(outputByteLen > (size_t)rateInBytes) { + SnP_ExtractBytes(state, curOutput, 0, rateInBytes); + SnP_Permute(state); + #ifdef KeccakReference + displayBytes(1, "Squeezed block", curOutput, rateInBytes); + #endif + curOutput += rateInBytes; + outputByteLen -= rateInBytes; + } + + /* Finally, output what remains */ + + partialBlock = (unsigned int)outputByteLen; + SnP_ExtractBytes(state, curOutput, 0, partialBlock); + #ifdef KeccakReference + displayBytes(1, "Squeezed block (part)", curOutput, partialBlock); + #endif + + return 0; +} + +/* ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- */ + +int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity) +{ + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) + return 1; + SnP_StaticInitialize(); + SnP_Initialize(instance->state); + instance->rate = rate; + instance->byteIOIndex = 0; + instance->squeezing = 0; + + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen) +{ + size_t i, j; + unsigned int partialBlock; + const unsigned char *curData; + unsigned int rateInBytes = instance->rate/8; + + if (instance->squeezing) + return 1; /* Too late for additional input */ + + + i = 0; + curData = data; + while(i < dataByteLen) { + if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { +#ifdef SnP_FastLoop_Absorb + /* processing full blocks first */ + + if ((rateInBytes % (SnP_width/200)) == 0) { + /* fast lane: whole lane rate */ + + j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i); + i += j; + curData += j; + } + else { +#endif + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed", curData, rateInBytes); + #endif + SnP_AddBytes(instance->state, curData, 0, rateInBytes); + SnP_Permute(instance->state); + curData+=rateInBytes; + } + i = dataByteLen - j; +#ifdef SnP_FastLoop_Absorb + } +#endif + } + else { + /* normal lane: using the message queue */ + + partialBlock = (unsigned int)(dataByteLen - i); + if (partialBlock+instance->byteIOIndex > rateInBytes) + partialBlock = rateInBytes-instance->byteIOIndex; + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); + #endif + i += partialBlock; + + SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock); + curData += partialBlock; + instance->byteIOIndex += partialBlock; + if (instance->byteIOIndex == rateInBytes) { + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + } + } + } + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData) +{ + unsigned int rateInBytes = instance->rate/8; + + if (delimitedData == 0) + return 1; + if (instance->squeezing) + return 1; /* Too late for additional input */ + + + #ifdef KeccakReference + { + unsigned char delimitedData1[1]; + delimitedData1[0] = delimitedData; + displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); + } + #endif + /* Last few bits, whose delimiter coincides with first bit of padding */ + + SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex); + /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ + + if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1))) + SnP_Permute(instance->state); + /* Second bit of padding */ + + SnP_AddByte(instance->state, 0x80, rateInBytes-1); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memset(block, 0, SnP_width/8); + block[rateInBytes-1] = 0x80; + displayBytes(1, "Second bit of padding", block, rateInBytes); + } + #endif + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + instance->squeezing = 1; + #ifdef KeccakReference + displayText(1, "--- Switching to squeezing phase ---"); + #endif + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen) +{ + size_t i, j; + unsigned int partialBlock; + unsigned int rateInBytes = instance->rate/8; + unsigned char *curData; + + if (!instance->squeezing) + SpongeAbsorbLastFewBits(instance, 0x01); + + i = 0; + curData = data; + while(i < dataByteLen) { + if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); + #ifdef KeccakReference + displayBytes(1, "Squeezed block", curData, rateInBytes); + #endif + curData+=rateInBytes; + } + i = dataByteLen - j; + } + else { + /* normal lane: using the message queue */ + + if (instance->byteIOIndex == rateInBytes) { + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + } + partialBlock = (unsigned int)(dataByteLen - i); + if (partialBlock+instance->byteIOIndex > rateInBytes) + partialBlock = rateInBytes-instance->byteIOIndex; + i += partialBlock; + + SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); + #ifdef KeccakReference + displayBytes(1, "Squeezed block (part)", curData, partialBlock); + #endif + curData += partialBlock; + instance->byteIOIndex += partialBlock; + } + } + return 0; +} + +/* ---------------------------------------------------------------- */ + +#undef Sponge +#undef SpongeInstance +#undef SpongeInitialize +#undef SpongeAbsorb +#undef SpongeAbsorbLastFewBits +#undef SpongeSqueeze +#undef SnP_stateSizeInBytes +#undef SnP_stateAlignment +#undef SnP_StaticInitialize +#undef SnP_Initialize +#undef SnP_AddByte +#undef SnP_AddBytes +#undef SnP_ExtractBytes diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/PlSnP-Fallback.inc b/contrib/tools/python3/src/Modules/_sha3/kcp/PlSnP-Fallback.inc index 3a9119ab4b6..a33528e1f43 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/PlSnP-Fallback.inc +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/PlSnP-Fallback.inc @@ -1,257 +1,257 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -/* expect PlSnP_baseParallelism, PlSnP_targetParallelism */ - -/* expect SnP_stateSizeInBytes, SnP_stateAlignment */ - -/* expect prefix */ - -/* expect SnP_* */ - - -#define JOIN0(a, b) a ## b -#define JOIN(a, b) JOIN0(a, b) - -#define PlSnP_StaticInitialize JOIN(prefix, _StaticInitialize) -#define PlSnP_InitializeAll JOIN(prefix, _InitializeAll) -#define PlSnP_AddByte JOIN(prefix, _AddByte) -#define PlSnP_AddBytes JOIN(prefix, _AddBytes) -#define PlSnP_AddLanesAll JOIN(prefix, _AddLanesAll) -#define PlSnP_OverwriteBytes JOIN(prefix, _OverwriteBytes) -#define PlSnP_OverwriteLanesAll JOIN(prefix, _OverwriteLanesAll) -#define PlSnP_OverwriteWithZeroes JOIN(prefix, _OverwriteWithZeroes) -#define PlSnP_ExtractBytes JOIN(prefix, _ExtractBytes) -#define PlSnP_ExtractLanesAll JOIN(prefix, _ExtractLanesAll) -#define PlSnP_ExtractAndAddBytes JOIN(prefix, _ExtractAndAddBytes) -#define PlSnP_ExtractAndAddLanesAll JOIN(prefix, _ExtractAndAddLanesAll) - -#if (PlSnP_baseParallelism == 1) - #define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) - #define SnP_stateAlignment JOIN(SnP, _stateAlignment) -#else - #define SnP_stateSizeInBytes JOIN(SnP, _statesSizeInBytes) - #define SnP_stateAlignment JOIN(SnP, _statesAlignment) -#endif -#define PlSnP_factor ((PlSnP_targetParallelism)/(PlSnP_baseParallelism)) -#define SnP_stateOffset (((SnP_stateSizeInBytes+(SnP_stateAlignment-1))/SnP_stateAlignment)*SnP_stateAlignment) -#define stateWithIndex(i) ((unsigned char *)states+((i)*SnP_stateOffset)) - -#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) -#define SnP_Initialize JOIN(SnP, _Initialize) -#define SnP_InitializeAll JOIN(SnP, _InitializeAll) -#define SnP_AddByte JOIN(SnP, _AddByte) -#define SnP_AddBytes JOIN(SnP, _AddBytes) -#define SnP_AddLanesAll JOIN(SnP, _AddLanesAll) -#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes) -#define SnP_OverwriteLanesAll JOIN(SnP, _OverwriteLanesAll) -#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes) -#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) -#define SnP_ExtractLanesAll JOIN(SnP, _ExtractLanesAll) -#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes) -#define SnP_ExtractAndAddLanesAll JOIN(SnP, _ExtractAndAddLanesAll) - -void PlSnP_StaticInitialize( void ) -{ - SnP_StaticInitialize(); -} - -void PlSnP_InitializeAll(void *states) -{ - unsigned int i; - - for(i=0; i 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \ - SnP_OverwriteBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - const unsigned char *_curData = (data); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \ - SnP_ExtractBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - unsigned char *_curData = (data); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \ - SnP_ExtractAndAddBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - (output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - const unsigned char *_curInput = (input); \ - unsigned char *_curOutput = (output); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curInput += _bytesInLane; \ - _curOutput += _bytesInLane; \ - } \ - } \ - } - -#endif +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _SnP_Relaned_h_ +#define _SnP_Relaned_h_ + +#define SnP_AddBytes(state, data, offset, length, SnP_AddLanes, SnP_AddBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_AddLanes(state, data, (length)/SnP_laneLengthInBytes); \ + SnP_AddBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \ + SnP_OverwriteBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \ + SnP_ExtractBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \ + SnP_ExtractAndAddBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + (output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curInput = (input); \ + unsigned char *_curOutput = (output); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curInput += _bytesInLane; \ + _curOutput += _bytesInLane; \ + } \ + } \ + } + +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/kcp/align.h b/contrib/tools/python3/src/Modules/_sha3/kcp/align.h index 6650fe8c3cf..7aaebf70d08 100644 --- a/contrib/tools/python3/src/Modules/_sha3/kcp/align.h +++ b/contrib/tools/python3/src/Modules/_sha3/kcp/align.h @@ -1,35 +1,35 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _align_h_ -#define _align_h_ - -/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ - -#ifdef ALIGN -#undef ALIGN -#endif - -#if defined(__GNUC__) -#define ALIGN(x) __attribute__ ((aligned(x))) -#elif defined(_MSC_VER) -#define ALIGN(x) __declspec(align(x)) -#elif defined(__ARMCC_VERSION) -#define ALIGN(x) __align(x) -#else -#define ALIGN(x) -#endif - -#endif +/* +Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +denoted as "the implementer". + +For more information, feedback or questions, please refer to our websites: +http://keccak.noekeon.org/ +http://keyak.noekeon.org/ +http://ketje.noekeon.org/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _align_h_ +#define _align_h_ + +/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ + +#ifdef ALIGN +#undef ALIGN +#endif + +#if defined(__GNUC__) +#define ALIGN(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +#define ALIGN(x) __declspec(align(x)) +#elif defined(__ARMCC_VERSION) +#define ALIGN(x) __align(x) +#else +#define ALIGN(x) +#endif + +#endif diff --git a/contrib/tools/python3/src/Modules/_sha3/sha3module.c b/contrib/tools/python3/src/Modules/_sha3/sha3module.c index b6a7130dd86..243ed1c1f19 100644 --- a/contrib/tools/python3/src/Modules/_sha3/sha3module.c +++ b/contrib/tools/python3/src/Modules/_sha3/sha3module.c @@ -1,179 +1,179 @@ -/* SHA3 module - * - * This module provides an interface to the SHA3 algorithm - * - * See below for information about the original code this module was - * based upon. Additional work performed by: - * - * Andrew Kuchling (amk@amk.ca) - * Greg Stein (gstein@lyra.org) - * Trevor Perrin (trevp@trevp.net) - * Gregory P. Smith (greg@krypto.org) - * - * Copyright (C) 2012-2016 Christian Heimes (christian@python.org) - * Licensed to PSF under a Contributor Agreement. - * - */ - -#include "Python.h" -#include "pystrhex.h" -#include "../hashlib.h" - -/* ************************************************************************** - * SHA-3 (Keccak) and SHAKE - * - * The code is based on KeccakCodePackage from 2016-04-23 - * commit 647f93079afc4ada3d23737477a6e52511ca41fd - * - * The reference implementation is altered in this points: - * - C++ comments are converted to ANSI C comments. - * - all function names are mangled - * - typedef for UINT64 is commented out. - * - brg_endian.h is removed - * - * *************************************************************************/ - -#ifdef __sparc - /* opt64 uses un-aligned memory access that causes a BUS error with msg - * 'invalid address alignment' on SPARC. */ - #define KeccakOpt 32 -#elif PY_BIG_ENDIAN - /* opt64 is not yet supported on big endian platforms */ - #define KeccakOpt 32 +/* SHA3 module + * + * This module provides an interface to the SHA3 algorithm + * + * See below for information about the original code this module was + * based upon. Additional work performed by: + * + * Andrew Kuchling (amk@amk.ca) + * Greg Stein (gstein@lyra.org) + * Trevor Perrin (trevp@trevp.net) + * Gregory P. Smith (greg@krypto.org) + * + * Copyright (C) 2012-2016 Christian Heimes (christian@python.org) + * Licensed to PSF under a Contributor Agreement. + * + */ + +#include "Python.h" +#include "pystrhex.h" +#include "../hashlib.h" + +/* ************************************************************************** + * SHA-3 (Keccak) and SHAKE + * + * The code is based on KeccakCodePackage from 2016-04-23 + * commit 647f93079afc4ada3d23737477a6e52511ca41fd + * + * The reference implementation is altered in this points: + * - C++ comments are converted to ANSI C comments. + * - all function names are mangled + * - typedef for UINT64 is commented out. + * - brg_endian.h is removed + * + * *************************************************************************/ + +#ifdef __sparc + /* opt64 uses un-aligned memory access that causes a BUS error with msg + * 'invalid address alignment' on SPARC. */ + #define KeccakOpt 32 +#elif PY_BIG_ENDIAN + /* opt64 is not yet supported on big endian platforms */ + #define KeccakOpt 32 #elif SIZEOF_VOID_P == 8 - /* opt64 works only on little-endian 64bit platforms with unsigned int64 */ - #define KeccakOpt 64 -#else - /* opt32 is used for the remaining 32 and 64bit platforms */ - #define KeccakOpt 32 -#endif - + /* opt64 works only on little-endian 64bit platforms with unsigned int64 */ + #define KeccakOpt 64 +#else + /* opt32 is used for the remaining 32 and 64bit platforms */ + #define KeccakOpt 32 +#endif + #if KeccakOpt == 64 - /* 64bit platforms with unsigned int64 */ + /* 64bit platforms with unsigned int64 */ typedef uint64_t UINT64; - typedef unsigned char UINT8; -#endif - -/* replacement for brg_endian.h */ -#define IS_LITTLE_ENDIAN 1234 -#define IS_BIG_ENDIAN 4321 -#if PY_LITTLE_ENDIAN -#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif -#if PY_BIG_ENDIAN -#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#endif - + typedef unsigned char UINT8; +#endif + +/* replacement for brg_endian.h */ +#define IS_LITTLE_ENDIAN 1234 +#define IS_BIG_ENDIAN 4321 +#if PY_LITTLE_ENDIAN +#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif +#if PY_BIG_ENDIAN +#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#endif + /* Prevent bus errors on platforms requiring aligned accesses such ARM. */ #if HAVE_ALIGNED_REQUIRED && !defined(NO_MISALIGNED_ACCESSES) #define NO_MISALIGNED_ACCESSES #endif -/* mangle names */ -#define KeccakF1600_FastLoop_Absorb _PySHA3_KeccakF1600_FastLoop_Absorb -#define Keccak_HashFinal _PySHA3_Keccak_HashFinal -#define Keccak_HashInitialize _PySHA3_Keccak_HashInitialize -#define Keccak_HashSqueeze _PySHA3_Keccak_HashSqueeze -#define Keccak_HashUpdate _PySHA3_Keccak_HashUpdate -#define KeccakP1600_AddBytes _PySHA3_KeccakP1600_AddBytes -#define KeccakP1600_AddBytesInLane _PySHA3_KeccakP1600_AddBytesInLane -#define KeccakP1600_AddLanes _PySHA3_KeccakP1600_AddLanes -#define KeccakP1600_ExtractAndAddBytes _PySHA3_KeccakP1600_ExtractAndAddBytes -#define KeccakP1600_ExtractAndAddBytesInLane _PySHA3_KeccakP1600_ExtractAndAddBytesInLane -#define KeccakP1600_ExtractAndAddLanes _PySHA3_KeccakP1600_ExtractAndAddLanes -#define KeccakP1600_ExtractBytes _PySHA3_KeccakP1600_ExtractBytes -#define KeccakP1600_ExtractBytesInLane _PySHA3_KeccakP1600_ExtractBytesInLane -#define KeccakP1600_ExtractLanes _PySHA3_KeccakP1600_ExtractLanes -#define KeccakP1600_Initialize _PySHA3_KeccakP1600_Initialize -#define KeccakP1600_OverwriteBytes _PySHA3_KeccakP1600_OverwriteBytes -#define KeccakP1600_OverwriteBytesInLane _PySHA3_KeccakP1600_OverwriteBytesInLane -#define KeccakP1600_OverwriteLanes _PySHA3_KeccakP1600_OverwriteLanes -#define KeccakP1600_OverwriteWithZeroes _PySHA3_KeccakP1600_OverwriteWithZeroes -#define KeccakP1600_Permute_12rounds _PySHA3_KeccakP1600_Permute_12rounds -#define KeccakP1600_Permute_24rounds _PySHA3_KeccakP1600_Permute_24rounds -#define KeccakWidth1600_Sponge _PySHA3_KeccakWidth1600_Sponge -#define KeccakWidth1600_SpongeAbsorb _PySHA3_KeccakWidth1600_SpongeAbsorb -#define KeccakWidth1600_SpongeAbsorbLastFewBits _PySHA3_KeccakWidth1600_SpongeAbsorbLastFewBits -#define KeccakWidth1600_SpongeInitialize _PySHA3_KeccakWidth1600_SpongeInitialize -#define KeccakWidth1600_SpongeSqueeze _PySHA3_KeccakWidth1600_SpongeSqueeze -#if KeccakOpt == 32 -#define KeccakP1600_AddByte _PySHA3_KeccakP1600_AddByte -#define KeccakP1600_Permute_Nrounds _PySHA3_KeccakP1600_Permute_Nrounds -#define KeccakP1600_SetBytesInLaneToZero _PySHA3_KeccakP1600_SetBytesInLaneToZero -#endif - -/* we are only interested in KeccakP1600 */ -#define KeccakP200_excluded 1 -#define KeccakP400_excluded 1 -#define KeccakP800_excluded 1 - -/* inline all Keccak dependencies */ -#include "kcp/KeccakHash.h" -#include "kcp/KeccakSponge.h" -#include "kcp/KeccakHash.c" -#include "kcp/KeccakSponge.c" -#if KeccakOpt == 64 - #include "kcp/KeccakP-1600-opt64.c" -#elif KeccakOpt == 32 - #include "kcp/KeccakP-1600-inplace32BI.c" -#endif - -#define SHA3_MAX_DIGESTSIZE 64 /* 64 Bytes (512 Bits) for 224 to 512 */ -#define SHA3_LANESIZE (20 * 8) /* ExtractLane needs max uint64_t[20] extra. */ -#define SHA3_state Keccak_HashInstance -#define SHA3_init Keccak_HashInitialize -#define SHA3_process Keccak_HashUpdate -#define SHA3_done Keccak_HashFinal -#define SHA3_squeeze Keccak_HashSqueeze -#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) - - -/*[clinic input] -module _sha3 -class _sha3.sha3_224 "SHA3object *" "&SHA3_224typ" -class _sha3.sha3_256 "SHA3object *" "&SHA3_256typ" -class _sha3.sha3_384 "SHA3object *" "&SHA3_384typ" -class _sha3.sha3_512 "SHA3object *" "&SHA3_512typ" -class _sha3.shake_128 "SHA3object *" "&SHAKE128type" -class _sha3.shake_256 "SHA3object *" "&SHAKE256type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b8a53680f370285a]*/ - -/* The structure for storing SHA3 info */ - -typedef struct { - PyObject_HEAD - SHA3_state hash_state; - PyThread_type_lock lock; -} SHA3object; - -static PyTypeObject SHA3_224type; -static PyTypeObject SHA3_256type; -static PyTypeObject SHA3_384type; -static PyTypeObject SHA3_512type; -#ifdef PY_WITH_KECCAK -static PyTypeObject Keccak_224type; -static PyTypeObject Keccak_256type; -static PyTypeObject Keccak_384type; -static PyTypeObject Keccak_512type; -#endif -static PyTypeObject SHAKE128type; -static PyTypeObject SHAKE256type; - -#include "clinic/sha3module.c.h" - -static SHA3object * -newSHA3object(PyTypeObject *type) -{ - SHA3object *newobj; - newobj = (SHA3object *)PyObject_New(SHA3object, type); - if (newobj == NULL) { - return NULL; - } - newobj->lock = NULL; - return newobj; -} - +/* mangle names */ +#define KeccakF1600_FastLoop_Absorb _PySHA3_KeccakF1600_FastLoop_Absorb +#define Keccak_HashFinal _PySHA3_Keccak_HashFinal +#define Keccak_HashInitialize _PySHA3_Keccak_HashInitialize +#define Keccak_HashSqueeze _PySHA3_Keccak_HashSqueeze +#define Keccak_HashUpdate _PySHA3_Keccak_HashUpdate +#define KeccakP1600_AddBytes _PySHA3_KeccakP1600_AddBytes +#define KeccakP1600_AddBytesInLane _PySHA3_KeccakP1600_AddBytesInLane +#define KeccakP1600_AddLanes _PySHA3_KeccakP1600_AddLanes +#define KeccakP1600_ExtractAndAddBytes _PySHA3_KeccakP1600_ExtractAndAddBytes +#define KeccakP1600_ExtractAndAddBytesInLane _PySHA3_KeccakP1600_ExtractAndAddBytesInLane +#define KeccakP1600_ExtractAndAddLanes _PySHA3_KeccakP1600_ExtractAndAddLanes +#define KeccakP1600_ExtractBytes _PySHA3_KeccakP1600_ExtractBytes +#define KeccakP1600_ExtractBytesInLane _PySHA3_KeccakP1600_ExtractBytesInLane +#define KeccakP1600_ExtractLanes _PySHA3_KeccakP1600_ExtractLanes +#define KeccakP1600_Initialize _PySHA3_KeccakP1600_Initialize +#define KeccakP1600_OverwriteBytes _PySHA3_KeccakP1600_OverwriteBytes +#define KeccakP1600_OverwriteBytesInLane _PySHA3_KeccakP1600_OverwriteBytesInLane +#define KeccakP1600_OverwriteLanes _PySHA3_KeccakP1600_OverwriteLanes +#define KeccakP1600_OverwriteWithZeroes _PySHA3_KeccakP1600_OverwriteWithZeroes +#define KeccakP1600_Permute_12rounds _PySHA3_KeccakP1600_Permute_12rounds +#define KeccakP1600_Permute_24rounds _PySHA3_KeccakP1600_Permute_24rounds +#define KeccakWidth1600_Sponge _PySHA3_KeccakWidth1600_Sponge +#define KeccakWidth1600_SpongeAbsorb _PySHA3_KeccakWidth1600_SpongeAbsorb +#define KeccakWidth1600_SpongeAbsorbLastFewBits _PySHA3_KeccakWidth1600_SpongeAbsorbLastFewBits +#define KeccakWidth1600_SpongeInitialize _PySHA3_KeccakWidth1600_SpongeInitialize +#define KeccakWidth1600_SpongeSqueeze _PySHA3_KeccakWidth1600_SpongeSqueeze +#if KeccakOpt == 32 +#define KeccakP1600_AddByte _PySHA3_KeccakP1600_AddByte +#define KeccakP1600_Permute_Nrounds _PySHA3_KeccakP1600_Permute_Nrounds +#define KeccakP1600_SetBytesInLaneToZero _PySHA3_KeccakP1600_SetBytesInLaneToZero +#endif + +/* we are only interested in KeccakP1600 */ +#define KeccakP200_excluded 1 +#define KeccakP400_excluded 1 +#define KeccakP800_excluded 1 + +/* inline all Keccak dependencies */ +#include "kcp/KeccakHash.h" +#include "kcp/KeccakSponge.h" +#include "kcp/KeccakHash.c" +#include "kcp/KeccakSponge.c" +#if KeccakOpt == 64 + #include "kcp/KeccakP-1600-opt64.c" +#elif KeccakOpt == 32 + #include "kcp/KeccakP-1600-inplace32BI.c" +#endif + +#define SHA3_MAX_DIGESTSIZE 64 /* 64 Bytes (512 Bits) for 224 to 512 */ +#define SHA3_LANESIZE (20 * 8) /* ExtractLane needs max uint64_t[20] extra. */ +#define SHA3_state Keccak_HashInstance +#define SHA3_init Keccak_HashInitialize +#define SHA3_process Keccak_HashUpdate +#define SHA3_done Keccak_HashFinal +#define SHA3_squeeze Keccak_HashSqueeze +#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) + + +/*[clinic input] +module _sha3 +class _sha3.sha3_224 "SHA3object *" "&SHA3_224typ" +class _sha3.sha3_256 "SHA3object *" "&SHA3_256typ" +class _sha3.sha3_384 "SHA3object *" "&SHA3_384typ" +class _sha3.sha3_512 "SHA3object *" "&SHA3_512typ" +class _sha3.shake_128 "SHA3object *" "&SHAKE128type" +class _sha3.shake_256 "SHA3object *" "&SHAKE256type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b8a53680f370285a]*/ + +/* The structure for storing SHA3 info */ + +typedef struct { + PyObject_HEAD + SHA3_state hash_state; + PyThread_type_lock lock; +} SHA3object; + +static PyTypeObject SHA3_224type; +static PyTypeObject SHA3_256type; +static PyTypeObject SHA3_384type; +static PyTypeObject SHA3_512type; +#ifdef PY_WITH_KECCAK +static PyTypeObject Keccak_224type; +static PyTypeObject Keccak_256type; +static PyTypeObject Keccak_384type; +static PyTypeObject Keccak_512type; +#endif +static PyTypeObject SHAKE128type; +static PyTypeObject SHAKE256type; + +#include "clinic/sha3module.c.h" + +static SHA3object * +newSHA3object(PyTypeObject *type) +{ + SHA3object *newobj; + newobj = (SHA3object *)PyObject_New(SHA3object, type); + if (newobj == NULL) { + return NULL; + } + newobj->lock = NULL; + return newobj; +} + /*[clinic input] @classmethod _sha3.sha3_224.__new__ as py_sha3_new @@ -181,578 +181,578 @@ _sha3.sha3_224.__new__ as py_sha3_new / * usedforsecurity: bool = True - + Return a new BLAKE2b hash object. [clinic start generated code]*/ -static PyObject * +static PyObject * py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) /*[clinic end generated code: output=90409addc5d5e8b0 input=bcfcdf2e4368347a]*/ -{ - SHA3object *self = NULL; - Py_buffer buf = {NULL, NULL}; - HashReturn res; - - self = newSHA3object(type); - if (self == NULL) { - goto error; - } - - if (type == &SHA3_224type) { - res = Keccak_HashInitialize_SHA3_224(&self->hash_state); - } else if (type == &SHA3_256type) { - res = Keccak_HashInitialize_SHA3_256(&self->hash_state); - } else if (type == &SHA3_384type) { - res = Keccak_HashInitialize_SHA3_384(&self->hash_state); - } else if (type == &SHA3_512type) { - res = Keccak_HashInitialize_SHA3_512(&self->hash_state); -#ifdef PY_WITH_KECCAK - } else if (type == &Keccak_224type) { - res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); - } else if (type == &Keccak_256type) { - res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); - } else if (type == &Keccak_384type) { - res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); - } else if (type == &Keccak_512type) { - res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); -#endif - } else if (type == &SHAKE128type) { - res = Keccak_HashInitialize_SHAKE128(&self->hash_state); - } else if (type == &SHAKE256type) { - res = Keccak_HashInitialize_SHAKE256(&self->hash_state); - } else { - PyErr_BadInternalCall(); - goto error; - } - - if (data) { - GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); - if (buf.len >= HASHLIB_GIL_MINSIZE) { - /* invariant: New objects can't be accessed by other code yet, - * thus it's safe to release the GIL without locking the object. - */ - Py_BEGIN_ALLOW_THREADS - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); - Py_END_ALLOW_THREADS - } - else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); - } - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - goto error; - } - PyBuffer_Release(&buf); - } - - return (PyObject *)self; - - error: - if (self) { - Py_DECREF(self); - } - if (data && buf.obj) { - PyBuffer_Release(&buf); - } - return NULL; -} - - -/* Internal methods for a hash object */ - -static void -SHA3_dealloc(SHA3object *self) -{ - if (self->lock) { - PyThread_free_lock(self->lock); - } - PyObject_Del(self); -} - - -/* External methods for a hash object */ - - -/*[clinic input] -_sha3.sha3_224.copy - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -_sha3_sha3_224_copy_impl(SHA3object *self) -/*[clinic end generated code: output=6c537411ecdcda4c input=93a44aaebea51ba8]*/ -{ - SHA3object *newobj; - - if ((newobj = newSHA3object(Py_TYPE(self))) == NULL) { - return NULL; - } - ENTER_HASHLIB(self); - SHA3_copystate(newobj->hash_state, self->hash_state); - LEAVE_HASHLIB(self); - return (PyObject *)newobj; -} - - -/*[clinic input] -_sha3.sha3_224.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -_sha3_sha3_224_digest_impl(SHA3object *self) -/*[clinic end generated code: output=fd531842e20b2d5b input=5b2a659536bbd248]*/ -{ - unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; - SHA3_state temp; - HashReturn res; - - ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); - LEAVE_HASHLIB(self); - res = SHA3_done(&temp, digest); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); - return NULL; - } - return PyBytes_FromStringAndSize((const char *)digest, - self->hash_state.fixedOutputLength / 8); -} - - -/*[clinic input] -_sha3.sha3_224.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -_sha3_sha3_224_hexdigest_impl(SHA3object *self) -/*[clinic end generated code: output=75ad03257906918d input=2d91bb6e0d114ee3]*/ -{ - unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; - SHA3_state temp; - HashReturn res; - - /* Get the raw (binary) digest value */ - ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); - LEAVE_HASHLIB(self); - res = SHA3_done(&temp, digest); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); - return NULL; - } - return _Py_strhex((const char *)digest, - self->hash_state.fixedOutputLength / 8); -} - - -/*[clinic input] -_sha3.sha3_224.update - - data: object - / - -Update this hash object's state with the provided bytes-like object. -[clinic start generated code]*/ - -static PyObject * -_sha3_sha3_224_update(SHA3object *self, PyObject *data) -/*[clinic end generated code: output=d3223352286ed357 input=a887f54dcc4ae227]*/ -{ - Py_buffer buf; - HashReturn res; - - GET_BUFFER_VIEW_OR_ERROUT(data, &buf); - - /* add new data, the function takes the length in bits not bytes */ - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); - } - /* Once a lock exists all code paths must be synchronized. We have to - * release the GIL even for small buffers as acquiring the lock may take - * an unlimited amount of time when another thread updates this object - * with lots of data. */ - if (self->lock) { - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); - PyThread_release_lock(self->lock); - Py_END_ALLOW_THREADS - } - else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); - } - - if (res != SUCCESS) { - PyBuffer_Release(&buf); - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - return NULL; - } - - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - - -static PyMethodDef SHA3_methods[] = { - _SHA3_SHA3_224_COPY_METHODDEF - _SHA3_SHA3_224_DIGEST_METHODDEF - _SHA3_SHA3_224_HEXDIGEST_METHODDEF - _SHA3_SHA3_224_UPDATE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -static PyObject * -SHA3_get_block_size(SHA3object *self, void *closure) -{ - int rate = self->hash_state.sponge.rate; - return PyLong_FromLong(rate / 8); -} - - -static PyObject * -SHA3_get_name(SHA3object *self, void *closure) -{ - PyTypeObject *type = Py_TYPE(self); - if (type == &SHA3_224type) { - return PyUnicode_FromString("sha3_224"); - } else if (type == &SHA3_256type) { - return PyUnicode_FromString("sha3_256"); - } else if (type == &SHA3_384type) { - return PyUnicode_FromString("sha3_384"); - } else if (type == &SHA3_512type) { - return PyUnicode_FromString("sha3_512"); -#ifdef PY_WITH_KECCAK - } else if (type == &Keccak_224type) { - return PyUnicode_FromString("keccak_224"); - } else if (type == &Keccak_256type) { - return PyUnicode_FromString("keccak_256"); - } else if (type == &Keccak_384type) { - return PyUnicode_FromString("keccak_384"); - } else if (type == &Keccak_512type) { - return PyUnicode_FromString("keccak_512"); -#endif - } else if (type == &SHAKE128type) { - return PyUnicode_FromString("shake_128"); - } else if (type == &SHAKE256type) { - return PyUnicode_FromString("shake_256"); - } else { - PyErr_BadInternalCall(); - return NULL; - } -} - - -static PyObject * -SHA3_get_digest_size(SHA3object *self, void *closure) -{ - return PyLong_FromLong(self->hash_state.fixedOutputLength / 8); -} - - -static PyObject * -SHA3_get_capacity_bits(SHA3object *self, void *closure) -{ - int capacity = 1600 - self->hash_state.sponge.rate; - return PyLong_FromLong(capacity); -} - - -static PyObject * -SHA3_get_rate_bits(SHA3object *self, void *closure) -{ - unsigned int rate = self->hash_state.sponge.rate; - return PyLong_FromLong(rate); -} - -static PyObject * -SHA3_get_suffix(SHA3object *self, void *closure) -{ - unsigned char suffix[2]; - suffix[0] = self->hash_state.delimitedSuffix; - suffix[1] = 0; - return PyBytes_FromStringAndSize((const char *)suffix, 1); -} - - -static PyGetSetDef SHA3_getseters[] = { - {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, - {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, - {"digest_size", (getter)SHA3_get_digest_size, NULL, NULL, NULL}, - {"_capacity_bits", (getter)SHA3_get_capacity_bits, NULL, NULL, NULL}, - {"_rate_bits", (getter)SHA3_get_rate_bits, NULL, NULL, NULL}, - {"_suffix", (getter)SHA3_get_suffix, NULL, NULL, NULL}, - {NULL} /* Sentinel */ -}; - - -#define SHA3_TYPE(type_obj, type_name, type_doc, type_methods) \ - static PyTypeObject type_obj = { \ - PyVarObject_HEAD_INIT(NULL, 0) \ - type_name, /* tp_name */ \ - sizeof(SHA3object), /* tp_basicsize */ \ - 0, /* tp_itemsize */ \ - /* methods */ \ - (destructor)SHA3_dealloc, /* tp_dealloc */ \ +{ + SHA3object *self = NULL; + Py_buffer buf = {NULL, NULL}; + HashReturn res; + + self = newSHA3object(type); + if (self == NULL) { + goto error; + } + + if (type == &SHA3_224type) { + res = Keccak_HashInitialize_SHA3_224(&self->hash_state); + } else if (type == &SHA3_256type) { + res = Keccak_HashInitialize_SHA3_256(&self->hash_state); + } else if (type == &SHA3_384type) { + res = Keccak_HashInitialize_SHA3_384(&self->hash_state); + } else if (type == &SHA3_512type) { + res = Keccak_HashInitialize_SHA3_512(&self->hash_state); +#ifdef PY_WITH_KECCAK + } else if (type == &Keccak_224type) { + res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); + } else if (type == &Keccak_256type) { + res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); + } else if (type == &Keccak_384type) { + res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); + } else if (type == &Keccak_512type) { + res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); +#endif + } else if (type == &SHAKE128type) { + res = Keccak_HashInitialize_SHAKE128(&self->hash_state); + } else if (type == &SHAKE256type) { + res = Keccak_HashInitialize_SHAKE256(&self->hash_state); + } else { + PyErr_BadInternalCall(); + goto error; + } + + if (data) { + GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* invariant: New objects can't be accessed by other code yet, + * thus it's safe to release the GIL without locking the object. + */ + Py_BEGIN_ALLOW_THREADS + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + Py_END_ALLOW_THREADS + } + else { + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + } + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, + "internal error in SHA3 Update()"); + goto error; + } + PyBuffer_Release(&buf); + } + + return (PyObject *)self; + + error: + if (self) { + Py_DECREF(self); + } + if (data && buf.obj) { + PyBuffer_Release(&buf); + } + return NULL; +} + + +/* Internal methods for a hash object */ + +static void +SHA3_dealloc(SHA3object *self) +{ + if (self->lock) { + PyThread_free_lock(self->lock); + } + PyObject_Del(self); +} + + +/* External methods for a hash object */ + + +/*[clinic input] +_sha3.sha3_224.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +_sha3_sha3_224_copy_impl(SHA3object *self) +/*[clinic end generated code: output=6c537411ecdcda4c input=93a44aaebea51ba8]*/ +{ + SHA3object *newobj; + + if ((newobj = newSHA3object(Py_TYPE(self))) == NULL) { + return NULL; + } + ENTER_HASHLIB(self); + SHA3_copystate(newobj->hash_state, self->hash_state); + LEAVE_HASHLIB(self); + return (PyObject *)newobj; +} + + +/*[clinic input] +_sha3.sha3_224.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +_sha3_sha3_224_digest_impl(SHA3object *self) +/*[clinic end generated code: output=fd531842e20b2d5b input=5b2a659536bbd248]*/ +{ + unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; + SHA3_state temp; + HashReturn res; + + ENTER_HASHLIB(self); + SHA3_copystate(temp, self->hash_state); + LEAVE_HASHLIB(self); + res = SHA3_done(&temp, digest); + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); + return NULL; + } + return PyBytes_FromStringAndSize((const char *)digest, + self->hash_state.fixedOutputLength / 8); +} + + +/*[clinic input] +_sha3.sha3_224.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +_sha3_sha3_224_hexdigest_impl(SHA3object *self) +/*[clinic end generated code: output=75ad03257906918d input=2d91bb6e0d114ee3]*/ +{ + unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; + SHA3_state temp; + HashReturn res; + + /* Get the raw (binary) digest value */ + ENTER_HASHLIB(self); + SHA3_copystate(temp, self->hash_state); + LEAVE_HASHLIB(self); + res = SHA3_done(&temp, digest); + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); + return NULL; + } + return _Py_strhex((const char *)digest, + self->hash_state.fixedOutputLength / 8); +} + + +/*[clinic input] +_sha3.sha3_224.update + + data: object + / + +Update this hash object's state with the provided bytes-like object. +[clinic start generated code]*/ + +static PyObject * +_sha3_sha3_224_update(SHA3object *self, PyObject *data) +/*[clinic end generated code: output=d3223352286ed357 input=a887f54dcc4ae227]*/ +{ + Py_buffer buf; + HashReturn res; + + GET_BUFFER_VIEW_OR_ERROUT(data, &buf); + + /* add new data, the function takes the length in bits not bytes */ + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { + self->lock = PyThread_allocate_lock(); + } + /* Once a lock exists all code paths must be synchronized. We have to + * release the GIL even for small buffers as acquiring the lock may take + * an unlimited amount of time when another thread updates this object + * with lots of data. */ + if (self->lock) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } + else { + res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + } + + if (res != SUCCESS) { + PyBuffer_Release(&buf); + PyErr_SetString(PyExc_RuntimeError, + "internal error in SHA3 Update()"); + return NULL; + } + + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + + +static PyMethodDef SHA3_methods[] = { + _SHA3_SHA3_224_COPY_METHODDEF + _SHA3_SHA3_224_DIGEST_METHODDEF + _SHA3_SHA3_224_HEXDIGEST_METHODDEF + _SHA3_SHA3_224_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +static PyObject * +SHA3_get_block_size(SHA3object *self, void *closure) +{ + int rate = self->hash_state.sponge.rate; + return PyLong_FromLong(rate / 8); +} + + +static PyObject * +SHA3_get_name(SHA3object *self, void *closure) +{ + PyTypeObject *type = Py_TYPE(self); + if (type == &SHA3_224type) { + return PyUnicode_FromString("sha3_224"); + } else if (type == &SHA3_256type) { + return PyUnicode_FromString("sha3_256"); + } else if (type == &SHA3_384type) { + return PyUnicode_FromString("sha3_384"); + } else if (type == &SHA3_512type) { + return PyUnicode_FromString("sha3_512"); +#ifdef PY_WITH_KECCAK + } else if (type == &Keccak_224type) { + return PyUnicode_FromString("keccak_224"); + } else if (type == &Keccak_256type) { + return PyUnicode_FromString("keccak_256"); + } else if (type == &Keccak_384type) { + return PyUnicode_FromString("keccak_384"); + } else if (type == &Keccak_512type) { + return PyUnicode_FromString("keccak_512"); +#endif + } else if (type == &SHAKE128type) { + return PyUnicode_FromString("shake_128"); + } else if (type == &SHAKE256type) { + return PyUnicode_FromString("shake_256"); + } else { + PyErr_BadInternalCall(); + return NULL; + } +} + + +static PyObject * +SHA3_get_digest_size(SHA3object *self, void *closure) +{ + return PyLong_FromLong(self->hash_state.fixedOutputLength / 8); +} + + +static PyObject * +SHA3_get_capacity_bits(SHA3object *self, void *closure) +{ + int capacity = 1600 - self->hash_state.sponge.rate; + return PyLong_FromLong(capacity); +} + + +static PyObject * +SHA3_get_rate_bits(SHA3object *self, void *closure) +{ + unsigned int rate = self->hash_state.sponge.rate; + return PyLong_FromLong(rate); +} + +static PyObject * +SHA3_get_suffix(SHA3object *self, void *closure) +{ + unsigned char suffix[2]; + suffix[0] = self->hash_state.delimitedSuffix; + suffix[1] = 0; + return PyBytes_FromStringAndSize((const char *)suffix, 1); +} + + +static PyGetSetDef SHA3_getseters[] = { + {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, + {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, + {"digest_size", (getter)SHA3_get_digest_size, NULL, NULL, NULL}, + {"_capacity_bits", (getter)SHA3_get_capacity_bits, NULL, NULL, NULL}, + {"_rate_bits", (getter)SHA3_get_rate_bits, NULL, NULL, NULL}, + {"_suffix", (getter)SHA3_get_suffix, NULL, NULL, NULL}, + {NULL} /* Sentinel */ +}; + + +#define SHA3_TYPE(type_obj, type_name, type_doc, type_methods) \ + static PyTypeObject type_obj = { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + type_name, /* tp_name */ \ + sizeof(SHA3object), /* tp_basicsize */ \ + 0, /* tp_itemsize */ \ + /* methods */ \ + (destructor)SHA3_dealloc, /* tp_dealloc */ \ 0, /* tp_vectorcall_offset */ \ - 0, /* tp_getattr */ \ - 0, /* tp_setattr */ \ + 0, /* tp_getattr */ \ + 0, /* tp_setattr */ \ 0, /* tp_as_async */ \ - 0, /* tp_repr */ \ - 0, /* tp_as_number */ \ - 0, /* tp_as_sequence */ \ - 0, /* tp_as_mapping */ \ - 0, /* tp_hash */ \ - 0, /* tp_call */ \ - 0, /* tp_str */ \ - 0, /* tp_getattro */ \ - 0, /* tp_setattro */ \ - 0, /* tp_as_buffer */ \ - Py_TPFLAGS_DEFAULT, /* tp_flags */ \ - type_doc, /* tp_doc */ \ - 0, /* tp_traverse */ \ - 0, /* tp_clear */ \ - 0, /* tp_richcompare */ \ - 0, /* tp_weaklistoffset */ \ - 0, /* tp_iter */ \ - 0, /* tp_iternext */ \ - type_methods, /* tp_methods */ \ - NULL, /* tp_members */ \ - SHA3_getseters, /* tp_getset */ \ - 0, /* tp_base */ \ - 0, /* tp_dict */ \ - 0, /* tp_descr_get */ \ - 0, /* tp_descr_set */ \ - 0, /* tp_dictoffset */ \ - 0, /* tp_init */ \ - 0, /* tp_alloc */ \ - py_sha3_new, /* tp_new */ \ - } - -PyDoc_STRVAR(sha3_224__doc__, + 0, /* tp_repr */ \ + 0, /* tp_as_number */ \ + 0, /* tp_as_sequence */ \ + 0, /* tp_as_mapping */ \ + 0, /* tp_hash */ \ + 0, /* tp_call */ \ + 0, /* tp_str */ \ + 0, /* tp_getattro */ \ + 0, /* tp_setattro */ \ + 0, /* tp_as_buffer */ \ + Py_TPFLAGS_DEFAULT, /* tp_flags */ \ + type_doc, /* tp_doc */ \ + 0, /* tp_traverse */ \ + 0, /* tp_clear */ \ + 0, /* tp_richcompare */ \ + 0, /* tp_weaklistoffset */ \ + 0, /* tp_iter */ \ + 0, /* tp_iternext */ \ + type_methods, /* tp_methods */ \ + NULL, /* tp_members */ \ + SHA3_getseters, /* tp_getset */ \ + 0, /* tp_base */ \ + 0, /* tp_dict */ \ + 0, /* tp_descr_get */ \ + 0, /* tp_descr_set */ \ + 0, /* tp_dictoffset */ \ + 0, /* tp_init */ \ + 0, /* tp_alloc */ \ + py_sha3_new, /* tp_new */ \ + } + +PyDoc_STRVAR(sha3_224__doc__, "sha3_224([data], *, usedforsecurity=True) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 28 bytes."); - -PyDoc_STRVAR(sha3_256__doc__, +\n\ +Return a new SHA3 hash object with a hashbit length of 28 bytes."); + +PyDoc_STRVAR(sha3_256__doc__, "sha3_256([data], *, usedforsecurity=True) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 32 bytes."); - -PyDoc_STRVAR(sha3_384__doc__, +\n\ +Return a new SHA3 hash object with a hashbit length of 32 bytes."); + +PyDoc_STRVAR(sha3_384__doc__, "sha3_384([data], *, usedforsecurity=True) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 48 bytes."); - -PyDoc_STRVAR(sha3_512__doc__, +\n\ +Return a new SHA3 hash object with a hashbit length of 48 bytes."); + +PyDoc_STRVAR(sha3_512__doc__, "sha3_512([data], *, usedforsecurity=True) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 64 bytes."); - -SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", sha3_224__doc__, SHA3_methods); -SHA3_TYPE(SHA3_256type, "_sha3.sha3_256", sha3_256__doc__, SHA3_methods); -SHA3_TYPE(SHA3_384type, "_sha3.sha3_384", sha3_384__doc__, SHA3_methods); -SHA3_TYPE(SHA3_512type, "_sha3.sha3_512", sha3_512__doc__, SHA3_methods); - -#ifdef PY_WITH_KECCAK -PyDoc_STRVAR(keccak_224__doc__, +\n\ +Return a new SHA3 hash object with a hashbit length of 64 bytes."); + +SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", sha3_224__doc__, SHA3_methods); +SHA3_TYPE(SHA3_256type, "_sha3.sha3_256", sha3_256__doc__, SHA3_methods); +SHA3_TYPE(SHA3_384type, "_sha3.sha3_384", sha3_384__doc__, SHA3_methods); +SHA3_TYPE(SHA3_512type, "_sha3.sha3_512", sha3_512__doc__, SHA3_methods); + +#ifdef PY_WITH_KECCAK +PyDoc_STRVAR(keccak_224__doc__, "keccak_224([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 28 bytes."); - -PyDoc_STRVAR(keccak_256__doc__, +\n\ +Return a new Keccak hash object with a hashbit length of 28 bytes."); + +PyDoc_STRVAR(keccak_256__doc__, "keccak_256([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 32 bytes."); - -PyDoc_STRVAR(keccak_384__doc__, +\n\ +Return a new Keccak hash object with a hashbit length of 32 bytes."); + +PyDoc_STRVAR(keccak_384__doc__, "keccak_384([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 48 bytes."); - -PyDoc_STRVAR(keccak_512__doc__, +\n\ +Return a new Keccak hash object with a hashbit length of 48 bytes."); + +PyDoc_STRVAR(keccak_512__doc__, "keccak_512([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 64 bytes."); - -SHA3_TYPE(Keccak_224type, "_sha3.keccak_224", keccak_224__doc__, SHA3_methods); -SHA3_TYPE(Keccak_256type, "_sha3.keccak_256", keccak_256__doc__, SHA3_methods); -SHA3_TYPE(Keccak_384type, "_sha3.keccak_384", keccak_384__doc__, SHA3_methods); -SHA3_TYPE(Keccak_512type, "_sha3.keccak_512", keccak_512__doc__, SHA3_methods); -#endif - - -static PyObject * +\n\ +Return a new Keccak hash object with a hashbit length of 64 bytes."); + +SHA3_TYPE(Keccak_224type, "_sha3.keccak_224", keccak_224__doc__, SHA3_methods); +SHA3_TYPE(Keccak_256type, "_sha3.keccak_256", keccak_256__doc__, SHA3_methods); +SHA3_TYPE(Keccak_384type, "_sha3.keccak_384", keccak_384__doc__, SHA3_methods); +SHA3_TYPE(Keccak_512type, "_sha3.keccak_512", keccak_512__doc__, SHA3_methods); +#endif + + +static PyObject * _SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex) -{ - unsigned char *digest = NULL; - SHA3_state temp; - int res; - PyObject *result = NULL; - - if (digestlen >= (1 << 29)) { - PyErr_SetString(PyExc_ValueError, "length is too large"); - return NULL; - } - /* ExtractLane needs at least SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE and - * SHA3_LANESIZE extra space. - */ - digest = (unsigned char*)PyMem_Malloc(digestlen + SHA3_LANESIZE); - if (digest == NULL) { - return PyErr_NoMemory(); - } - - /* Get the raw (binary) digest value */ - ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); - LEAVE_HASHLIB(self); - res = SHA3_done(&temp, NULL); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 done()"); - goto error; - } - res = SHA3_squeeze(&temp, digest, digestlen * 8); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Squeeze()"); - return NULL; - } - if (hex) { - result = _Py_strhex((const char *)digest, digestlen); - } else { - result = PyBytes_FromStringAndSize((const char *)digest, - digestlen); - } - error: - if (digest != NULL) { - PyMem_Free(digest); - } - return result; -} - - -/*[clinic input] -_sha3.shake_128.digest - +{ + unsigned char *digest = NULL; + SHA3_state temp; + int res; + PyObject *result = NULL; + + if (digestlen >= (1 << 29)) { + PyErr_SetString(PyExc_ValueError, "length is too large"); + return NULL; + } + /* ExtractLane needs at least SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE and + * SHA3_LANESIZE extra space. + */ + digest = (unsigned char*)PyMem_Malloc(digestlen + SHA3_LANESIZE); + if (digest == NULL) { + return PyErr_NoMemory(); + } + + /* Get the raw (binary) digest value */ + ENTER_HASHLIB(self); + SHA3_copystate(temp, self->hash_state); + LEAVE_HASHLIB(self); + res = SHA3_done(&temp, NULL); + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 done()"); + goto error; + } + res = SHA3_squeeze(&temp, digest, digestlen * 8); + if (res != SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Squeeze()"); + return NULL; + } + if (hex) { + result = _Py_strhex((const char *)digest, digestlen); + } else { + result = PyBytes_FromStringAndSize((const char *)digest, + digestlen); + } + error: + if (digest != NULL) { + PyMem_Free(digest); + } + return result; +} + + +/*[clinic input] +_sha3.shake_128.digest + length: unsigned_long - / - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * + / + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * _sha3_shake_128_digest_impl(SHA3object *self, unsigned long length) /*[clinic end generated code: output=2313605e2f87bb8f input=418ef6a36d2e6082]*/ -{ - return _SHAKE_digest(self, length, 0); -} - - -/*[clinic input] -_sha3.shake_128.hexdigest - +{ + return _SHAKE_digest(self, length, 0); +} + + +/*[clinic input] +_sha3.shake_128.hexdigest + length: unsigned_long - / - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * + / + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * _sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length) /*[clinic end generated code: output=bf8e2f1e490944a8 input=69fb29b0926ae321]*/ -{ - return _SHAKE_digest(self, length, 1); -} - - -static PyMethodDef SHAKE_methods[] = { - _SHA3_SHA3_224_COPY_METHODDEF - _SHA3_SHAKE_128_DIGEST_METHODDEF - _SHA3_SHAKE_128_HEXDIGEST_METHODDEF - _SHA3_SHA3_224_UPDATE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(shake_128__doc__, +{ + return _SHAKE_digest(self, length, 1); +} + + +static PyMethodDef SHAKE_methods[] = { + _SHA3_SHA3_224_COPY_METHODDEF + _SHA3_SHAKE_128_DIGEST_METHODDEF + _SHA3_SHAKE_128_HEXDIGEST_METHODDEF + _SHA3_SHA3_224_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(shake_128__doc__, "shake_128([data], *, usedforsecurity=True) -> SHAKE object\n\ -\n\ -Return a new SHAKE hash object."); - -PyDoc_STRVAR(shake_256__doc__, +\n\ +Return a new SHAKE hash object."); + +PyDoc_STRVAR(shake_256__doc__, "shake_256([data], *, usedforsecurity=True) -> SHAKE object\n\ -\n\ -Return a new SHAKE hash object."); - -SHA3_TYPE(SHAKE128type, "_sha3.shake_128", shake_128__doc__, SHAKE_methods); -SHA3_TYPE(SHAKE256type, "_sha3.shake_256", shake_256__doc__, SHAKE_methods); - - -/* Initialize this module. */ -static struct PyModuleDef _SHA3module = { - PyModuleDef_HEAD_INIT, - "_sha3", - NULL, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit__sha3(void) -{ - PyObject *m = NULL; - - if ((m = PyModule_Create(&_SHA3module)) == NULL) { - return NULL; - } - -#define init_sha3type(name, type) \ - do { \ +\n\ +Return a new SHAKE hash object."); + +SHA3_TYPE(SHAKE128type, "_sha3.shake_128", shake_128__doc__, SHAKE_methods); +SHA3_TYPE(SHAKE256type, "_sha3.shake_256", shake_256__doc__, SHAKE_methods); + + +/* Initialize this module. */ +static struct PyModuleDef _SHA3module = { + PyModuleDef_HEAD_INIT, + "_sha3", + NULL, + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__sha3(void) +{ + PyObject *m = NULL; + + if ((m = PyModule_Create(&_SHA3module)) == NULL) { + return NULL; + } + +#define init_sha3type(name, type) \ + do { \ Py_SET_TYPE(type, &PyType_Type); \ - if (PyType_Ready(type) < 0) { \ - goto error; \ - } \ - Py_INCREF((PyObject *)type); \ - if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ - goto error; \ - } \ - } while(0) - - init_sha3type("sha3_224", &SHA3_224type); - init_sha3type("sha3_256", &SHA3_256type); - init_sha3type("sha3_384", &SHA3_384type); - init_sha3type("sha3_512", &SHA3_512type); -#ifdef PY_WITH_KECCAK - init_sha3type("keccak_224", &Keccak_224type); - init_sha3type("keccak_256", &Keccak_256type); - init_sha3type("keccak_384", &Keccak_384type); - init_sha3type("keccak_512", &Keccak_512type); -#endif - init_sha3type("shake_128", &SHAKE128type); - init_sha3type("shake_256", &SHAKE256type); - -#undef init_sha3type - - if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { - goto error; - } - if (PyModule_AddStringConstant(m, "implementation", - KeccakP1600_implementation) < 0) { - goto error; - } - - return m; - error: - Py_DECREF(m); - return NULL; -} + if (PyType_Ready(type) < 0) { \ + goto error; \ + } \ + Py_INCREF((PyObject *)type); \ + if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ + goto error; \ + } \ + } while(0) + + init_sha3type("sha3_224", &SHA3_224type); + init_sha3type("sha3_256", &SHA3_256type); + init_sha3type("sha3_384", &SHA3_384type); + init_sha3type("sha3_512", &SHA3_512type); +#ifdef PY_WITH_KECCAK + init_sha3type("keccak_224", &Keccak_224type); + init_sha3type("keccak_256", &Keccak_256type); + init_sha3type("keccak_384", &Keccak_384type); + init_sha3type("keccak_512", &Keccak_512type); +#endif + init_sha3type("shake_128", &SHAKE128type); + init_sha3type("shake_256", &SHAKE256type); + +#undef init_sha3type + + if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { + goto error; + } + if (PyModule_AddStringConstant(m, "implementation", + KeccakP1600_implementation) < 0) { + goto error; + } + + return m; + error: + Py_DECREF(m); + return NULL; +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/cache.c b/contrib/tools/python3/src/Modules/_sqlite/cache.c index 758fc022f78..7c6d7953b6f 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cache.c +++ b/contrib/tools/python3/src/Modules/_sqlite/cache.c @@ -1,362 +1,362 @@ -/* cache .c - a LRU cache - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "cache.h" -#include - -/* only used internally */ -pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) -{ - pysqlite_Node* node; - - node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0)); - if (!node) { - return NULL; - } - - Py_INCREF(key); - node->key = key; - - Py_INCREF(data); - node->data = data; - - node->prev = NULL; - node->next = NULL; - - return node; -} - -void pysqlite_node_dealloc(pysqlite_Node* self) -{ - Py_DECREF(self->key); - Py_DECREF(self->data); - - Py_TYPE(self)->tp_free((PyObject*)self); -} - -int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) -{ - PyObject* factory; - int size = 10; - - self->factory = NULL; - - if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) { - return -1; - } - - /* minimum cache size is 5 entries */ - if (size < 5) { - size = 5; - } - self->size = size; - self->first = NULL; - self->last = NULL; - - self->mapping = PyDict_New(); - if (!self->mapping) { - return -1; - } - - Py_INCREF(factory); - self->factory = factory; - - self->decref_factory = 1; - - return 0; -} - -void pysqlite_cache_dealloc(pysqlite_Cache* self) -{ - pysqlite_Node* node; - pysqlite_Node* delete_node; - - if (!self->factory) { - /* constructor failed, just get out of here */ - return; - } - - /* iterate over all nodes and deallocate them */ - node = self->first; - while (node) { - delete_node = node; - node = node->next; - Py_DECREF(delete_node); - } - - if (self->decref_factory) { - Py_DECREF(self->factory); - } - Py_DECREF(self->mapping); - - Py_TYPE(self)->tp_free((PyObject*)self); -} - +/* cache .c - a LRU cache + * + * Copyright (C) 2004-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "cache.h" +#include + +/* only used internally */ +pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) +{ + pysqlite_Node* node; + + node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0)); + if (!node) { + return NULL; + } + + Py_INCREF(key); + node->key = key; + + Py_INCREF(data); + node->data = data; + + node->prev = NULL; + node->next = NULL; + + return node; +} + +void pysqlite_node_dealloc(pysqlite_Node* self) +{ + Py_DECREF(self->key); + Py_DECREF(self->data); + + Py_TYPE(self)->tp_free((PyObject*)self); +} + +int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) +{ + PyObject* factory; + int size = 10; + + self->factory = NULL; + + if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) { + return -1; + } + + /* minimum cache size is 5 entries */ + if (size < 5) { + size = 5; + } + self->size = size; + self->first = NULL; + self->last = NULL; + + self->mapping = PyDict_New(); + if (!self->mapping) { + return -1; + } + + Py_INCREF(factory); + self->factory = factory; + + self->decref_factory = 1; + + return 0; +} + +void pysqlite_cache_dealloc(pysqlite_Cache* self) +{ + pysqlite_Node* node; + pysqlite_Node* delete_node; + + if (!self->factory) { + /* constructor failed, just get out of here */ + return; + } + + /* iterate over all nodes and deallocate them */ + node = self->first; + while (node) { + delete_node = node; + node = node->next; + Py_DECREF(delete_node); + } + + if (self->decref_factory) { + Py_DECREF(self->factory); + } + Py_DECREF(self->mapping); + + Py_TYPE(self)->tp_free((PyObject*)self); +} + PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) -{ - pysqlite_Node* node; - pysqlite_Node* ptr; - PyObject* data; - +{ + pysqlite_Node* node; + pysqlite_Node* ptr; + PyObject* data; + node = (pysqlite_Node*)PyDict_GetItemWithError(self->mapping, key); - if (node) { - /* an entry for this key already exists in the cache */ - - /* increase usage counter of the node found */ - if (node->count < LONG_MAX) { - node->count++; - } - - /* if necessary, reorder entries in the cache by swapping positions */ - if (node->prev && node->count > node->prev->count) { - ptr = node->prev; - - while (ptr->prev && node->count > ptr->prev->count) { - ptr = ptr->prev; - } - - if (node->next) { - node->next->prev = node->prev; - } else { - self->last = node->prev; - } - if (node->prev) { - node->prev->next = node->next; - } - if (ptr->prev) { - ptr->prev->next = node; - } else { - self->first = node; - } - - node->next = ptr; - node->prev = ptr->prev; - if (!node->prev) { - self->first = node; - } - ptr->prev = node; - } + if (node) { + /* an entry for this key already exists in the cache */ + + /* increase usage counter of the node found */ + if (node->count < LONG_MAX) { + node->count++; + } + + /* if necessary, reorder entries in the cache by swapping positions */ + if (node->prev && node->count > node->prev->count) { + ptr = node->prev; + + while (ptr->prev && node->count > ptr->prev->count) { + ptr = ptr->prev; + } + + if (node->next) { + node->next->prev = node->prev; + } else { + self->last = node->prev; + } + if (node->prev) { + node->prev->next = node->next; + } + if (ptr->prev) { + ptr->prev->next = node; + } else { + self->first = node; + } + + node->next = ptr; + node->prev = ptr->prev; + if (!node->prev) { + self->first = node; + } + ptr->prev = node; + } } else if (PyErr_Occurred()) { return NULL; } else { - /* There is no entry for this key in the cache, yet. We'll insert a new - * entry in the cache, and make space if necessary by throwing the - * least used item out of the cache. */ - - if (PyDict_GET_SIZE(self->mapping) == self->size) { - if (self->last) { - node = self->last; - - if (PyDict_DelItem(self->mapping, self->last->key) != 0) { - return NULL; - } - - if (node->prev) { - node->prev->next = NULL; - } - self->last = node->prev; - node->prev = NULL; - - Py_DECREF(node); - } - } - + /* There is no entry for this key in the cache, yet. We'll insert a new + * entry in the cache, and make space if necessary by throwing the + * least used item out of the cache. */ + + if (PyDict_GET_SIZE(self->mapping) == self->size) { + if (self->last) { + node = self->last; + + if (PyDict_DelItem(self->mapping, self->last->key) != 0) { + return NULL; + } + + if (node->prev) { + node->prev->next = NULL; + } + self->last = node->prev; + node->prev = NULL; + + Py_DECREF(node); + } + } + /* We cannot replace this by PyObject_CallOneArg() since * PyObject_CallFunction() has a special case when using a * single tuple as argument. */ - data = PyObject_CallFunction(self->factory, "O", key); - - if (!data) { - return NULL; - } - - node = pysqlite_new_node(key, data); - if (!node) { - return NULL; - } - node->prev = self->last; - - Py_DECREF(data); - - if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) { - Py_DECREF(node); - return NULL; - } - - if (self->last) { - self->last->next = node; - } else { - self->first = node; - } - self->last = node; - } - - Py_INCREF(node->data); - return node->data; -} - -PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) -{ - pysqlite_Node* ptr; - PyObject* prevkey; - PyObject* nextkey; - PyObject* display_str; - - ptr = self->first; - - while (ptr) { - if (ptr->prev) { - prevkey = ptr->prev->key; - } else { - prevkey = Py_None; - } - - if (ptr->next) { - nextkey = ptr->next->key; - } else { - nextkey = Py_None; - } - - display_str = PyUnicode_FromFormat("%S <- %S -> %S\n", - prevkey, ptr->key, nextkey); - if (!display_str) { - return NULL; - } - PyObject_Print(display_str, stdout, Py_PRINT_RAW); - Py_DECREF(display_str); - - ptr = ptr->next; - } - - Py_RETURN_NONE; -} - -static PyMethodDef cache_methods[] = { - {"get", (PyCFunction)pysqlite_cache_get, METH_O, - PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, - {"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS, - PyDoc_STR("For debugging only.")}, - {NULL, NULL} -}; - -PyTypeObject pysqlite_NodeType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME "Node", /* tp_name */ - sizeof(pysqlite_Node), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_node_dealloc, /* tp_dealloc */ + data = PyObject_CallFunction(self->factory, "O", key); + + if (!data) { + return NULL; + } + + node = pysqlite_new_node(key, data); + if (!node) { + return NULL; + } + node->prev = self->last; + + Py_DECREF(data); + + if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) { + Py_DECREF(node); + return NULL; + } + + if (self->last) { + self->last->next = node; + } else { + self->first = node; + } + self->last = node; + } + + Py_INCREF(node->data); + return node->data; +} + +PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) +{ + pysqlite_Node* ptr; + PyObject* prevkey; + PyObject* nextkey; + PyObject* display_str; + + ptr = self->first; + + while (ptr) { + if (ptr->prev) { + prevkey = ptr->prev->key; + } else { + prevkey = Py_None; + } + + if (ptr->next) { + nextkey = ptr->next->key; + } else { + nextkey = Py_None; + } + + display_str = PyUnicode_FromFormat("%S <- %S -> %S\n", + prevkey, ptr->key, nextkey); + if (!display_str) { + return NULL; + } + PyObject_Print(display_str, stdout, Py_PRINT_RAW); + Py_DECREF(display_str); + + ptr = ptr->next; + } + + Py_RETURN_NONE; +} + +static PyMethodDef cache_methods[] = { + {"get", (PyCFunction)pysqlite_cache_get, METH_O, + PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, + {"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS, + PyDoc_STR("For debugging only.")}, + {NULL, NULL} +}; + +PyTypeObject pysqlite_NodeType = { + PyVarObject_HEAD_INIT(NULL, 0) + MODULE_NAME "Node", /* tp_name */ + sizeof(pysqlite_Node), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pysqlite_node_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ -}; - -PyTypeObject pysqlite_CacheType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cache", /* tp_name */ - sizeof(pysqlite_Cache), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cache_dealloc, /* tp_dealloc */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0 /* tp_free */ +}; + +PyTypeObject pysqlite_CacheType = { + PyVarObject_HEAD_INIT(NULL, 0) + MODULE_NAME ".Cache", /* tp_name */ + sizeof(pysqlite_Cache), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pysqlite_cache_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - cache_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_cache_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ -}; - -extern int pysqlite_cache_setup_types(void) -{ - int rc; - - pysqlite_NodeType.tp_new = PyType_GenericNew; - pysqlite_CacheType.tp_new = PyType_GenericNew; - - rc = PyType_Ready(&pysqlite_NodeType); - if (rc < 0) { - return rc; - } - - rc = PyType_Ready(&pysqlite_CacheType); - return rc; -} + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + cache_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pysqlite_cache_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0 /* tp_free */ +}; + +extern int pysqlite_cache_setup_types(void) +{ + int rc; + + pysqlite_NodeType.tp_new = PyType_GenericNew; + pysqlite_CacheType.tp_new = PyType_GenericNew; + + rc = PyType_Ready(&pysqlite_NodeType); + if (rc < 0) { + return rc; + } + + rc = PyType_Ready(&pysqlite_CacheType); + return rc; +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/cache.h b/contrib/tools/python3/src/Modules/_sqlite/cache.h index 529010967c4..b1988c30c3f 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cache.h +++ b/contrib/tools/python3/src/Modules/_sqlite/cache.h @@ -1,74 +1,74 @@ -/* cache.h - definitions for the LRU cache - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PYSQLITE_CACHE_H -#define PYSQLITE_CACHE_H +/* cache.h - definitions for the LRU cache + * + * Copyright (C) 2004-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PYSQLITE_CACHE_H +#define PYSQLITE_CACHE_H #define PY_SSIZE_T_CLEAN -#include "Python.h" - -/* The LRU cache is implemented as a combination of a doubly-linked with a - * dictionary. The list items are of type 'Node' and the dictionary has the - * nodes as values. */ - -typedef struct _pysqlite_Node -{ - PyObject_HEAD - PyObject* key; - PyObject* data; - long count; - struct _pysqlite_Node* prev; - struct _pysqlite_Node* next; -} pysqlite_Node; - -typedef struct -{ - PyObject_HEAD - int size; - - /* a dictionary mapping keys to Node entries */ - PyObject* mapping; - - /* the factory callable */ - PyObject* factory; - - pysqlite_Node* first; - pysqlite_Node* last; - - /* if set, decrement the factory function when the Cache is deallocated. - * this is almost always desirable, but not in the pysqlite context */ - int decref_factory; -} pysqlite_Cache; - -extern PyTypeObject pysqlite_NodeType; -extern PyTypeObject pysqlite_CacheType; - -int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); -void pysqlite_node_dealloc(pysqlite_Node* self); - -int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs); -void pysqlite_cache_dealloc(pysqlite_Cache* self); -PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args); - -int pysqlite_cache_setup_types(void); - -#endif +#include "Python.h" + +/* The LRU cache is implemented as a combination of a doubly-linked with a + * dictionary. The list items are of type 'Node' and the dictionary has the + * nodes as values. */ + +typedef struct _pysqlite_Node +{ + PyObject_HEAD + PyObject* key; + PyObject* data; + long count; + struct _pysqlite_Node* prev; + struct _pysqlite_Node* next; +} pysqlite_Node; + +typedef struct +{ + PyObject_HEAD + int size; + + /* a dictionary mapping keys to Node entries */ + PyObject* mapping; + + /* the factory callable */ + PyObject* factory; + + pysqlite_Node* first; + pysqlite_Node* last; + + /* if set, decrement the factory function when the Cache is deallocated. + * this is almost always desirable, but not in the pysqlite context */ + int decref_factory; +} pysqlite_Cache; + +extern PyTypeObject pysqlite_NodeType; +extern PyTypeObject pysqlite_CacheType; + +int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); +void pysqlite_node_dealloc(pysqlite_Node* self); + +int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs); +void pysqlite_cache_dealloc(pysqlite_Cache* self); +PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args); + +int pysqlite_cache_setup_types(void); + +#endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/connection.c b/contrib/tools/python3/src/Modules/_sqlite/connection.c index 30e333a4b86..f4d41b73fac 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/connection.c +++ b/contrib/tools/python3/src/Modules/_sqlite/connection.c @@ -1,529 +1,529 @@ -/* connection.c - the connection type - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "cache.h" -#include "module.h" +/* connection.c - the connection type + * + * Copyright (C) 2004-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "cache.h" +#include "module.h" #include "structmember.h" // PyMemberDef -#include "connection.h" -#include "statement.h" -#include "cursor.h" -#include "prepare_protocol.h" -#include "util.h" - -#define ACTION_FINALIZE 1 -#define ACTION_RESET 2 - -#if SQLITE_VERSION_NUMBER >= 3003008 -#ifndef SQLITE_OMIT_LOAD_EXTENSION -#define HAVE_LOAD_EXTENSION -#endif -#endif - -#if SQLITE_VERSION_NUMBER >= 3006011 -#define HAVE_BACKUP_API -#endif - -_Py_IDENTIFIER(cursor); - -static const char * const begin_statements[] = { - "BEGIN ", - "BEGIN DEFERRED", - "BEGIN IMMEDIATE", - "BEGIN EXCLUSIVE", - NULL -}; - -static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored)); -static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); - - -static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len) -{ - /* in older SQLite versions, calling sqlite3_result_error in callbacks - * triggers a bug in SQLite that leads either to irritating results or - * segfaults, depending on the SQLite version */ -#if SQLITE_VERSION_NUMBER >= 3003003 - sqlite3_result_error(ctx, errmsg, len); -#else - PyErr_SetString(pysqlite_OperationalError, errmsg); -#endif -} - -int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - static char *kwlist[] = { - "database", "timeout", "detect_types", "isolation_level", - "check_same_thread", "factory", "cached_statements", "uri", - NULL - }; - +#include "connection.h" +#include "statement.h" +#include "cursor.h" +#include "prepare_protocol.h" +#include "util.h" + +#define ACTION_FINALIZE 1 +#define ACTION_RESET 2 + +#if SQLITE_VERSION_NUMBER >= 3003008 +#ifndef SQLITE_OMIT_LOAD_EXTENSION +#define HAVE_LOAD_EXTENSION +#endif +#endif + +#if SQLITE_VERSION_NUMBER >= 3006011 +#define HAVE_BACKUP_API +#endif + +_Py_IDENTIFIER(cursor); + +static const char * const begin_statements[] = { + "BEGIN ", + "BEGIN DEFERRED", + "BEGIN IMMEDIATE", + "BEGIN EXCLUSIVE", + NULL +}; + +static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored)); +static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); + + +static void _sqlite3_result_error(sqlite3_context* ctx, const char* errmsg, int len) +{ + /* in older SQLite versions, calling sqlite3_result_error in callbacks + * triggers a bug in SQLite that leads either to irritating results or + * segfaults, depending on the SQLite version */ +#if SQLITE_VERSION_NUMBER >= 3003003 + sqlite3_result_error(ctx, errmsg, len); +#else + PyErr_SetString(pysqlite_OperationalError, errmsg); +#endif +} + +int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = { + "database", "timeout", "detect_types", "isolation_level", + "check_same_thread", "factory", "cached_statements", "uri", + NULL + }; + const char* database; - PyObject* database_obj; - int detect_types = 0; - PyObject* isolation_level = NULL; - PyObject* factory = NULL; - int check_same_thread = 1; - int cached_statements = 100; - int uri = 0; - double timeout = 5.0; - int rc; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|diOiOip", kwlist, - PyUnicode_FSConverter, &database_obj, &timeout, &detect_types, - &isolation_level, &check_same_thread, - &factory, &cached_statements, &uri)) - { - return -1; - } - + PyObject* database_obj; + int detect_types = 0; + PyObject* isolation_level = NULL; + PyObject* factory = NULL; + int check_same_thread = 1; + int cached_statements = 100; + int uri = 0; + double timeout = 5.0; + int rc; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|diOiOip", kwlist, + PyUnicode_FSConverter, &database_obj, &timeout, &detect_types, + &isolation_level, &check_same_thread, + &factory, &cached_statements, &uri)) + { + return -1; + } + if (PySys_Audit("sqlite3.connect", "O", database_obj) < 0) { Py_DECREF(database_obj); return -1; } - database = PyBytes_AsString(database_obj); - - self->begin_statement = NULL; - - Py_CLEAR(self->statement_cache); - Py_CLEAR(self->statements); - Py_CLEAR(self->cursors); - - Py_INCREF(Py_None); - Py_XSETREF(self->row_factory, Py_None); - - Py_INCREF(&PyUnicode_Type); - Py_XSETREF(self->text_factory, (PyObject*)&PyUnicode_Type); - -#ifdef SQLITE_OPEN_URI - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_open_v2(database, &self->db, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | - (uri ? SQLITE_OPEN_URI : 0), NULL); -#else - if (uri) { - PyErr_SetString(pysqlite_NotSupportedError, "URIs not supported"); - return -1; - } - Py_BEGIN_ALLOW_THREADS - /* No need to use sqlite3_open_v2 as sqlite3_open(filename, db) is the - same as sqlite3_open_v2(filename, db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL). */ - rc = sqlite3_open(database, &self->db); -#endif - Py_END_ALLOW_THREADS - - Py_DECREF(database_obj); - + database = PyBytes_AsString(database_obj); + + self->begin_statement = NULL; + + Py_CLEAR(self->statement_cache); + Py_CLEAR(self->statements); + Py_CLEAR(self->cursors); + + Py_INCREF(Py_None); + Py_XSETREF(self->row_factory, Py_None); + + Py_INCREF(&PyUnicode_Type); + Py_XSETREF(self->text_factory, (PyObject*)&PyUnicode_Type); + +#ifdef SQLITE_OPEN_URI + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_open_v2(database, &self->db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + (uri ? SQLITE_OPEN_URI : 0), NULL); +#else + if (uri) { + PyErr_SetString(pysqlite_NotSupportedError, "URIs not supported"); + return -1; + } + Py_BEGIN_ALLOW_THREADS + /* No need to use sqlite3_open_v2 as sqlite3_open(filename, db) is the + same as sqlite3_open_v2(filename, db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL). */ + rc = sqlite3_open(database, &self->db); +#endif + Py_END_ALLOW_THREADS + + Py_DECREF(database_obj); + if (self->db == NULL && rc == SQLITE_NOMEM) { PyErr_NoMemory(); return -1; } - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db, NULL); - return -1; - } - - if (!isolation_level) { - isolation_level = PyUnicode_FromString(""); - if (!isolation_level) { - return -1; - } - } else { - Py_INCREF(isolation_level); - } - Py_CLEAR(self->isolation_level); + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, NULL); + return -1; + } + + if (!isolation_level) { + isolation_level = PyUnicode_FromString(""); + if (!isolation_level) { + return -1; + } + } else { + Py_INCREF(isolation_level); + } + Py_CLEAR(self->isolation_level); if (pysqlite_connection_set_isolation_level(self, isolation_level, NULL) != 0) { - Py_DECREF(isolation_level); - return -1; - } - Py_DECREF(isolation_level); - - self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); - if (PyErr_Occurred()) { - return -1; - } - - self->created_statements = 0; - self->created_cursors = 0; - - /* Create lists of weak references to statements/cursors */ - self->statements = PyList_New(0); - self->cursors = PyList_New(0); - if (!self->statements || !self->cursors) { - return -1; - } - - /* By default, the Cache class INCREFs the factory in its initializer, and - * decrefs it in its deallocator method. Since this would create a circular - * reference here, we're breaking it by decrementing self, and telling the - * cache class to not decref the factory (self) in its deallocator. - */ - self->statement_cache->decref_factory = 0; - Py_DECREF(self); - - self->detect_types = detect_types; - self->timeout = timeout; - (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); - self->thread_ident = PyThread_get_thread_ident(); - if (!check_same_thread && sqlite3_libversion_number() < 3003001) { - PyErr_SetString(pysqlite_NotSupportedError, "shared connections not available"); - return -1; - } - self->check_same_thread = check_same_thread; - + Py_DECREF(isolation_level); + return -1; + } + Py_DECREF(isolation_level); + + self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); + if (PyErr_Occurred()) { + return -1; + } + + self->created_statements = 0; + self->created_cursors = 0; + + /* Create lists of weak references to statements/cursors */ + self->statements = PyList_New(0); + self->cursors = PyList_New(0); + if (!self->statements || !self->cursors) { + return -1; + } + + /* By default, the Cache class INCREFs the factory in its initializer, and + * decrefs it in its deallocator method. Since this would create a circular + * reference here, we're breaking it by decrementing self, and telling the + * cache class to not decref the factory (self) in its deallocator. + */ + self->statement_cache->decref_factory = 0; + Py_DECREF(self); + + self->detect_types = detect_types; + self->timeout = timeout; + (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); + self->thread_ident = PyThread_get_thread_ident(); + if (!check_same_thread && sqlite3_libversion_number() < 3003001) { + PyErr_SetString(pysqlite_NotSupportedError, "shared connections not available"); + return -1; + } + self->check_same_thread = check_same_thread; + self->function_pinboard_trace_callback = NULL; self->function_pinboard_progress_handler = NULL; self->function_pinboard_authorizer_cb = NULL; - - Py_XSETREF(self->collations, PyDict_New()); - if (!self->collations) { - return -1; - } - - self->Warning = pysqlite_Warning; - self->Error = pysqlite_Error; - self->InterfaceError = pysqlite_InterfaceError; - self->DatabaseError = pysqlite_DatabaseError; - self->DataError = pysqlite_DataError; - self->OperationalError = pysqlite_OperationalError; - self->IntegrityError = pysqlite_IntegrityError; - self->InternalError = pysqlite_InternalError; - self->ProgrammingError = pysqlite_ProgrammingError; - self->NotSupportedError = pysqlite_NotSupportedError; - + + Py_XSETREF(self->collations, PyDict_New()); + if (!self->collations) { + return -1; + } + + self->Warning = pysqlite_Warning; + self->Error = pysqlite_Error; + self->InterfaceError = pysqlite_InterfaceError; + self->DatabaseError = pysqlite_DatabaseError; + self->DataError = pysqlite_DataError; + self->OperationalError = pysqlite_OperationalError; + self->IntegrityError = pysqlite_IntegrityError; + self->InternalError = pysqlite_InternalError; + self->ProgrammingError = pysqlite_ProgrammingError; + self->NotSupportedError = pysqlite_NotSupportedError; + self->initialized = 1; - return 0; -} - -/* action in (ACTION_RESET, ACTION_FINALIZE) */ -void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset_cursors) -{ - int i; - PyObject* weakref; - PyObject* statement; - pysqlite_Cursor* cursor; - - for (i = 0; i < PyList_Size(self->statements); i++) { - weakref = PyList_GetItem(self->statements, i); - statement = PyWeakref_GetObject(weakref); - if (statement != Py_None) { - Py_INCREF(statement); - if (action == ACTION_RESET) { - (void)pysqlite_statement_reset((pysqlite_Statement*)statement); - } else { - (void)pysqlite_statement_finalize((pysqlite_Statement*)statement); - } - Py_DECREF(statement); - } - } - - if (reset_cursors) { - for (i = 0; i < PyList_Size(self->cursors); i++) { - weakref = PyList_GetItem(self->cursors, i); - cursor = (pysqlite_Cursor*)PyWeakref_GetObject(weakref); - if ((PyObject*)cursor != Py_None) { - cursor->reset = 1; - } - } - } -} - -void pysqlite_connection_dealloc(pysqlite_Connection* self) -{ - Py_XDECREF(self->statement_cache); - - /* Clean up if user has not called .close() explicitly. */ - if (self->db) { - SQLITE3_CLOSE(self->db); - } - - Py_XDECREF(self->isolation_level); + return 0; +} + +/* action in (ACTION_RESET, ACTION_FINALIZE) */ +void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset_cursors) +{ + int i; + PyObject* weakref; + PyObject* statement; + pysqlite_Cursor* cursor; + + for (i = 0; i < PyList_Size(self->statements); i++) { + weakref = PyList_GetItem(self->statements, i); + statement = PyWeakref_GetObject(weakref); + if (statement != Py_None) { + Py_INCREF(statement); + if (action == ACTION_RESET) { + (void)pysqlite_statement_reset((pysqlite_Statement*)statement); + } else { + (void)pysqlite_statement_finalize((pysqlite_Statement*)statement); + } + Py_DECREF(statement); + } + } + + if (reset_cursors) { + for (i = 0; i < PyList_Size(self->cursors); i++) { + weakref = PyList_GetItem(self->cursors, i); + cursor = (pysqlite_Cursor*)PyWeakref_GetObject(weakref); + if ((PyObject*)cursor != Py_None) { + cursor->reset = 1; + } + } + } +} + +void pysqlite_connection_dealloc(pysqlite_Connection* self) +{ + Py_XDECREF(self->statement_cache); + + /* Clean up if user has not called .close() explicitly. */ + if (self->db) { + SQLITE3_CLOSE(self->db); + } + + Py_XDECREF(self->isolation_level); Py_XDECREF(self->function_pinboard_trace_callback); Py_XDECREF(self->function_pinboard_progress_handler); Py_XDECREF(self->function_pinboard_authorizer_cb); - Py_XDECREF(self->row_factory); - Py_XDECREF(self->text_factory); - Py_XDECREF(self->collations); - Py_XDECREF(self->statements); - Py_XDECREF(self->cursors); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -/* - * Registers a cursor with the connection. - * - * 0 => error; 1 => ok - */ -int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor) -{ - PyObject* weakref; - - weakref = PyWeakref_NewRef((PyObject*)cursor, NULL); - if (!weakref) { - goto error; - } - - if (PyList_Append(connection->cursors, weakref) != 0) { - Py_CLEAR(weakref); - goto error; - } - - Py_DECREF(weakref); - - return 1; -error: - return 0; -} - -PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - static char *kwlist[] = {"factory", NULL}; - PyObject* factory = NULL; - PyObject* cursor; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, - &factory)) { - return NULL; - } - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (factory == NULL) { - factory = (PyObject*)&pysqlite_CursorType; - } - + Py_XDECREF(self->row_factory); + Py_XDECREF(self->text_factory); + Py_XDECREF(self->collations); + Py_XDECREF(self->statements); + Py_XDECREF(self->cursors); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +/* + * Registers a cursor with the connection. + * + * 0 => error; 1 => ok + */ +int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor) +{ + PyObject* weakref; + + weakref = PyWeakref_NewRef((PyObject*)cursor, NULL); + if (!weakref) { + goto error; + } + + if (PyList_Append(connection->cursors, weakref) != 0) { + Py_CLEAR(weakref); + goto error; + } + + Py_DECREF(weakref); + + return 1; +error: + return 0; +} + +PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"factory", NULL}; + PyObject* factory = NULL; + PyObject* cursor; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, + &factory)) { + return NULL; + } + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (factory == NULL) { + factory = (PyObject*)&pysqlite_CursorType; + } + cursor = PyObject_CallOneArg(factory, (PyObject *)self); - if (cursor == NULL) - return NULL; - if (!PyObject_TypeCheck(cursor, &pysqlite_CursorType)) { - PyErr_Format(PyExc_TypeError, - "factory must return a cursor, not %.100s", - Py_TYPE(cursor)->tp_name); - Py_DECREF(cursor); - return NULL; - } - - _pysqlite_drop_unused_cursor_references(self); - - if (cursor && self->row_factory != Py_None) { - Py_INCREF(self->row_factory); - Py_XSETREF(((pysqlite_Cursor *)cursor)->row_factory, self->row_factory); - } - - return cursor; -} - -PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) -{ - int rc; - - if (!pysqlite_check_thread(self)) { - return NULL; - } - + if (cursor == NULL) + return NULL; + if (!PyObject_TypeCheck(cursor, &pysqlite_CursorType)) { + PyErr_Format(PyExc_TypeError, + "factory must return a cursor, not %.100s", + Py_TYPE(cursor)->tp_name); + Py_DECREF(cursor); + return NULL; + } + + _pysqlite_drop_unused_cursor_references(self); + + if (cursor && self->row_factory != Py_None) { + Py_INCREF(self->row_factory); + Py_XSETREF(((pysqlite_Cursor *)cursor)->row_factory, self->row_factory); + } + + return cursor; +} + +PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) +{ + int rc; + + if (!pysqlite_check_thread(self)) { + return NULL; + } + if (!self->initialized) { PyErr_SetString(pysqlite_ProgrammingError, "Base Connection.__init__ not called."); return NULL; } - pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); - - if (self->db) { - rc = SQLITE3_CLOSE(self->db); - - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db, NULL); - return NULL; - } else { - self->db = NULL; - } - } - - Py_RETURN_NONE; -} - -/* - * Checks if a connection object is usable (i. e. not closed). - * - * 0 => error; 1 => ok - */ -int pysqlite_check_connection(pysqlite_Connection* con) -{ - if (!con->initialized) { - PyErr_SetString(pysqlite_ProgrammingError, "Base Connection.__init__ not called."); - return 0; - } - - if (!con->db) { - PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed database."); - return 0; - } else { - return 1; - } -} - -PyObject* _pysqlite_connection_begin(pysqlite_Connection* self) -{ - int rc; - const char* tail; - sqlite3_stmt* statement; - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement, &tail); - Py_END_ALLOW_THREADS - - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db, statement); - goto error; - } - - rc = pysqlite_step(statement, self); - if (rc != SQLITE_DONE) { - _pysqlite_seterror(self->db, statement); - } - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_finalize(statement); - Py_END_ALLOW_THREADS - - if (rc != SQLITE_OK && !PyErr_Occurred()) { - _pysqlite_seterror(self->db, NULL); - } - -error: - if (PyErr_Occurred()) { - return NULL; - } else { - Py_RETURN_NONE; - } -} - -PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args) -{ - int rc; - const char* tail; - sqlite3_stmt* statement; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!sqlite3_get_autocommit(self->db)) { - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(self->db, "COMMIT", -1, &statement, &tail); - Py_END_ALLOW_THREADS - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db, NULL); - goto error; - } - - rc = pysqlite_step(statement, self); - if (rc != SQLITE_DONE) { - _pysqlite_seterror(self->db, statement); - } - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_finalize(statement); - Py_END_ALLOW_THREADS - if (rc != SQLITE_OK && !PyErr_Occurred()) { - _pysqlite_seterror(self->db, NULL); - } - - } - -error: - if (PyErr_Occurred()) { - return NULL; - } else { - Py_RETURN_NONE; - } -} - -PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args) -{ - int rc; - const char* tail; - sqlite3_stmt* statement; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!sqlite3_get_autocommit(self->db)) { - pysqlite_do_all_statements(self, ACTION_RESET, 1); - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(self->db, "ROLLBACK", -1, &statement, &tail); - Py_END_ALLOW_THREADS - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->db, NULL); - goto error; - } - - rc = pysqlite_step(statement, self); - if (rc != SQLITE_DONE) { - _pysqlite_seterror(self->db, statement); - } - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_finalize(statement); - Py_END_ALLOW_THREADS - if (rc != SQLITE_OK && !PyErr_Occurred()) { - _pysqlite_seterror(self->db, NULL); - } - - } - -error: - if (PyErr_Occurred()) { - return NULL; - } else { - Py_RETURN_NONE; - } -} - -static int -_pysqlite_set_result(sqlite3_context* context, PyObject* py_val) -{ - if (py_val == Py_None) { - sqlite3_result_null(context); - } else if (PyLong_Check(py_val)) { - sqlite_int64 value = _pysqlite_long_as_int64(py_val); - if (value == -1 && PyErr_Occurred()) - return -1; - sqlite3_result_int64(context, value); - } else if (PyFloat_Check(py_val)) { - sqlite3_result_double(context, PyFloat_AsDouble(py_val)); - } else if (PyUnicode_Check(py_val)) { + pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); + + if (self->db) { + rc = SQLITE3_CLOSE(self->db); + + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, NULL); + return NULL; + } else { + self->db = NULL; + } + } + + Py_RETURN_NONE; +} + +/* + * Checks if a connection object is usable (i. e. not closed). + * + * 0 => error; 1 => ok + */ +int pysqlite_check_connection(pysqlite_Connection* con) +{ + if (!con->initialized) { + PyErr_SetString(pysqlite_ProgrammingError, "Base Connection.__init__ not called."); + return 0; + } + + if (!con->db) { + PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed database."); + return 0; + } else { + return 1; + } +} + +PyObject* _pysqlite_connection_begin(pysqlite_Connection* self) +{ + int rc; + const char* tail; + sqlite3_stmt* statement; + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_prepare_v2(self->db, self->begin_statement, -1, &statement, &tail); + Py_END_ALLOW_THREADS + + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, statement); + goto error; + } + + rc = pysqlite_step(statement, self); + if (rc != SQLITE_DONE) { + _pysqlite_seterror(self->db, statement); + } + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_finalize(statement); + Py_END_ALLOW_THREADS + + if (rc != SQLITE_OK && !PyErr_Occurred()) { + _pysqlite_seterror(self->db, NULL); + } + +error: + if (PyErr_Occurred()) { + return NULL; + } else { + Py_RETURN_NONE; + } +} + +PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args) +{ + int rc; + const char* tail; + sqlite3_stmt* statement; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!sqlite3_get_autocommit(self->db)) { + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_prepare_v2(self->db, "COMMIT", -1, &statement, &tail); + Py_END_ALLOW_THREADS + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, NULL); + goto error; + } + + rc = pysqlite_step(statement, self); + if (rc != SQLITE_DONE) { + _pysqlite_seterror(self->db, statement); + } + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_finalize(statement); + Py_END_ALLOW_THREADS + if (rc != SQLITE_OK && !PyErr_Occurred()) { + _pysqlite_seterror(self->db, NULL); + } + + } + +error: + if (PyErr_Occurred()) { + return NULL; + } else { + Py_RETURN_NONE; + } +} + +PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args) +{ + int rc; + const char* tail; + sqlite3_stmt* statement; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!sqlite3_get_autocommit(self->db)) { + pysqlite_do_all_statements(self, ACTION_RESET, 1); + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_prepare_v2(self->db, "ROLLBACK", -1, &statement, &tail); + Py_END_ALLOW_THREADS + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, NULL); + goto error; + } + + rc = pysqlite_step(statement, self); + if (rc != SQLITE_DONE) { + _pysqlite_seterror(self->db, statement); + } + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_finalize(statement); + Py_END_ALLOW_THREADS + if (rc != SQLITE_OK && !PyErr_Occurred()) { + _pysqlite_seterror(self->db, NULL); + } + + } + +error: + if (PyErr_Occurred()) { + return NULL; + } else { + Py_RETURN_NONE; + } +} + +static int +_pysqlite_set_result(sqlite3_context* context, PyObject* py_val) +{ + if (py_val == Py_None) { + sqlite3_result_null(context); + } else if (PyLong_Check(py_val)) { + sqlite_int64 value = _pysqlite_long_as_int64(py_val); + if (value == -1 && PyErr_Occurred()) + return -1; + sqlite3_result_int64(context, value); + } else if (PyFloat_Check(py_val)) { + sqlite3_result_double(context, PyFloat_AsDouble(py_val)); + } else if (PyUnicode_Check(py_val)) { Py_ssize_t sz; const char *str = PyUnicode_AsUTF8AndSize(py_val, &sz); if (str == NULL) { - return -1; + return -1; } if (sz > INT_MAX) { PyErr_SetString(PyExc_OverflowError, @@ -531,49 +531,49 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) return -1; } sqlite3_result_text(context, str, (int)sz, SQLITE_TRANSIENT); - } else if (PyObject_CheckBuffer(py_val)) { - Py_buffer view; - if (PyObject_GetBuffer(py_val, &view, PyBUF_SIMPLE) != 0) { - PyErr_SetString(PyExc_ValueError, - "could not convert BLOB to buffer"); - return -1; - } - if (view.len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "BLOB longer than INT_MAX bytes"); - PyBuffer_Release(&view); - return -1; - } - sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT); - PyBuffer_Release(&view); - } else { - return -1; - } - return 0; -} - -PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv) -{ - PyObject* args; - int i; - sqlite3_value* cur_value; - PyObject* cur_py_value; - Py_ssize_t buflen; - - args = PyTuple_New(argc); - if (!args) { - return NULL; - } - - for (i = 0; i < argc; i++) { - cur_value = argv[i]; - switch (sqlite3_value_type(argv[i])) { - case SQLITE_INTEGER: + } else if (PyObject_CheckBuffer(py_val)) { + Py_buffer view; + if (PyObject_GetBuffer(py_val, &view, PyBUF_SIMPLE) != 0) { + PyErr_SetString(PyExc_ValueError, + "could not convert BLOB to buffer"); + return -1; + } + if (view.len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "BLOB longer than INT_MAX bytes"); + PyBuffer_Release(&view); + return -1; + } + sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT); + PyBuffer_Release(&view); + } else { + return -1; + } + return 0; +} + +PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv) +{ + PyObject* args; + int i; + sqlite3_value* cur_value; + PyObject* cur_py_value; + Py_ssize_t buflen; + + args = PyTuple_New(argc); + if (!args) { + return NULL; + } + + for (i = 0; i < argc; i++) { + cur_value = argv[i]; + switch (sqlite3_value_type(argv[i])) { + case SQLITE_INTEGER: cur_py_value = PyLong_FromLongLong(sqlite3_value_int64(cur_value)); - break; - case SQLITE_FLOAT: - cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value)); - break; + break; + case SQLITE_FLOAT: + cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value)); + break; case SQLITE_TEXT: { sqlite3 *db = sqlite3_context_db_handle(context); const char *text = (const char *)sqlite3_value_text(cur_value); @@ -581,626 +581,626 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_ if (text == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) { PyErr_NoMemory(); goto error; - } + } Py_ssize_t size = sqlite3_value_bytes(cur_value); cur_py_value = PyUnicode_FromStringAndSize(text, size); - break; + break; } - case SQLITE_BLOB: - buflen = sqlite3_value_bytes(cur_value); - cur_py_value = PyBytes_FromStringAndSize( - sqlite3_value_blob(cur_value), buflen); - break; - case SQLITE_NULL: - default: - Py_INCREF(Py_None); - cur_py_value = Py_None; - } - - if (!cur_py_value) { + case SQLITE_BLOB: + buflen = sqlite3_value_bytes(cur_value); + cur_py_value = PyBytes_FromStringAndSize( + sqlite3_value_blob(cur_value), buflen); + break; + case SQLITE_NULL: + default: + Py_INCREF(Py_None); + cur_py_value = Py_None; + } + + if (!cur_py_value) { goto error; - } - - PyTuple_SetItem(args, i, cur_py_value); - - } - - return args; + } + + PyTuple_SetItem(args, i, cur_py_value); + + } + + return args; error: Py_DECREF(args); return NULL; -} - -void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** argv) -{ - PyObject* args; - PyObject* py_func; - PyObject* py_retval = NULL; - int ok; - - PyGILState_STATE threadstate; - - threadstate = PyGILState_Ensure(); - - py_func = (PyObject*)sqlite3_user_data(context); - - args = _pysqlite_build_py_params(context, argc, argv); - if (args) { - py_retval = PyObject_CallObject(py_func, args); - Py_DECREF(args); - } - - ok = 0; - if (py_retval) { - ok = _pysqlite_set_result(context, py_retval) == 0; - Py_DECREF(py_retval); - } - if (!ok) { - if (_pysqlite_enable_callback_tracebacks) { - PyErr_Print(); - } else { - PyErr_Clear(); - } - _sqlite3_result_error(context, "user-defined function raised exception", -1); - } - - PyGILState_Release(threadstate); -} - -static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params) -{ - PyObject* args; - PyObject* function_result = NULL; - PyObject* aggregate_class; - PyObject** aggregate_instance; - PyObject* stepmethod = NULL; - - PyGILState_STATE threadstate; - - threadstate = PyGILState_Ensure(); - - aggregate_class = (PyObject*)sqlite3_user_data(context); - - aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); - - if (*aggregate_instance == NULL) { - *aggregate_instance = _PyObject_CallNoArg(aggregate_class); - - if (PyErr_Occurred()) { - *aggregate_instance = 0; - if (_pysqlite_enable_callback_tracebacks) { - PyErr_Print(); - } else { - PyErr_Clear(); - } - _sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1); - goto error; - } - } - - stepmethod = PyObject_GetAttrString(*aggregate_instance, "step"); - if (!stepmethod) { - goto error; - } - - args = _pysqlite_build_py_params(context, argc, params); - if (!args) { - goto error; - } - - function_result = PyObject_CallObject(stepmethod, args); - Py_DECREF(args); - - if (!function_result) { - if (_pysqlite_enable_callback_tracebacks) { - PyErr_Print(); - } else { - PyErr_Clear(); - } - _sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1); - } - -error: - Py_XDECREF(stepmethod); - Py_XDECREF(function_result); - - PyGILState_Release(threadstate); -} - -void _pysqlite_final_callback(sqlite3_context* context) -{ - PyObject* function_result; - PyObject** aggregate_instance; - _Py_IDENTIFIER(finalize); - int ok; - PyObject *exception, *value, *tb; - int restore; - - PyGILState_STATE threadstate; - - threadstate = PyGILState_Ensure(); - - aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); - if (!*aggregate_instance) { - /* this branch is executed if there was an exception in the aggregate's - * __init__ */ - - goto error; - } - - /* Keep the exception (if any) of the last call to step() */ - PyErr_Fetch(&exception, &value, &tb); - restore = 1; - +} + +void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** argv) +{ + PyObject* args; + PyObject* py_func; + PyObject* py_retval = NULL; + int ok; + + PyGILState_STATE threadstate; + + threadstate = PyGILState_Ensure(); + + py_func = (PyObject*)sqlite3_user_data(context); + + args = _pysqlite_build_py_params(context, argc, argv); + if (args) { + py_retval = PyObject_CallObject(py_func, args); + Py_DECREF(args); + } + + ok = 0; + if (py_retval) { + ok = _pysqlite_set_result(context, py_retval) == 0; + Py_DECREF(py_retval); + } + if (!ok) { + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + _sqlite3_result_error(context, "user-defined function raised exception", -1); + } + + PyGILState_Release(threadstate); +} + +static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params) +{ + PyObject* args; + PyObject* function_result = NULL; + PyObject* aggregate_class; + PyObject** aggregate_instance; + PyObject* stepmethod = NULL; + + PyGILState_STATE threadstate; + + threadstate = PyGILState_Ensure(); + + aggregate_class = (PyObject*)sqlite3_user_data(context); + + aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); + + if (*aggregate_instance == NULL) { + *aggregate_instance = _PyObject_CallNoArg(aggregate_class); + + if (PyErr_Occurred()) { + *aggregate_instance = 0; + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + _sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1); + goto error; + } + } + + stepmethod = PyObject_GetAttrString(*aggregate_instance, "step"); + if (!stepmethod) { + goto error; + } + + args = _pysqlite_build_py_params(context, argc, params); + if (!args) { + goto error; + } + + function_result = PyObject_CallObject(stepmethod, args); + Py_DECREF(args); + + if (!function_result) { + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + _sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1); + } + +error: + Py_XDECREF(stepmethod); + Py_XDECREF(function_result); + + PyGILState_Release(threadstate); +} + +void _pysqlite_final_callback(sqlite3_context* context) +{ + PyObject* function_result; + PyObject** aggregate_instance; + _Py_IDENTIFIER(finalize); + int ok; + PyObject *exception, *value, *tb; + int restore; + + PyGILState_STATE threadstate; + + threadstate = PyGILState_Ensure(); + + aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); + if (!*aggregate_instance) { + /* this branch is executed if there was an exception in the aggregate's + * __init__ */ + + goto error; + } + + /* Keep the exception (if any) of the last call to step() */ + PyErr_Fetch(&exception, &value, &tb); + restore = 1; + function_result = _PyObject_CallMethodIdNoArgs(*aggregate_instance, &PyId_finalize); - - Py_DECREF(*aggregate_instance); - - ok = 0; - if (function_result) { - ok = _pysqlite_set_result(context, function_result) == 0; - Py_DECREF(function_result); - } - if (!ok) { - if (_pysqlite_enable_callback_tracebacks) { - PyErr_Print(); - } else { - PyErr_Clear(); - } - _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); -#if SQLITE_VERSION_NUMBER < 3003003 - /* with old SQLite versions, _sqlite3_result_error() sets a new Python - exception, so don't restore the previous exception */ - restore = 0; -#endif - } - - if (restore) { - /* Restore the exception (if any) of the last call to step(), - but clear also the current exception if finalize() failed */ - PyErr_Restore(exception, value, tb); - } - -error: - PyGILState_Release(threadstate); -} - -static void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self) -{ - PyObject* new_list; - PyObject* weakref; - int i; - - /* we only need to do this once in a while */ - if (self->created_statements++ < 200) { - return; - } - - self->created_statements = 0; - - new_list = PyList_New(0); - if (!new_list) { - return; - } - - for (i = 0; i < PyList_Size(self->statements); i++) { - weakref = PyList_GetItem(self->statements, i); - if (PyWeakref_GetObject(weakref) != Py_None) { - if (PyList_Append(new_list, weakref) != 0) { - Py_DECREF(new_list); - return; - } - } - } - - Py_SETREF(self->statements, new_list); -} - -static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self) -{ - PyObject* new_list; - PyObject* weakref; - int i; - - /* we only need to do this once in a while */ - if (self->created_cursors++ < 200) { - return; - } - - self->created_cursors = 0; - - new_list = PyList_New(0); - if (!new_list) { - return; - } - - for (i = 0; i < PyList_Size(self->cursors); i++) { - weakref = PyList_GetItem(self->cursors, i); - if (PyWeakref_GetObject(weakref) != Py_None) { - if (PyList_Append(new_list, weakref) != 0) { - Py_DECREF(new_list); - return; - } - } - } - - Py_SETREF(self->cursors, new_list); -} - + + Py_DECREF(*aggregate_instance); + + ok = 0; + if (function_result) { + ok = _pysqlite_set_result(context, function_result) == 0; + Py_DECREF(function_result); + } + if (!ok) { + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + _sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); +#if SQLITE_VERSION_NUMBER < 3003003 + /* with old SQLite versions, _sqlite3_result_error() sets a new Python + exception, so don't restore the previous exception */ + restore = 0; +#endif + } + + if (restore) { + /* Restore the exception (if any) of the last call to step(), + but clear also the current exception if finalize() failed */ + PyErr_Restore(exception, value, tb); + } + +error: + PyGILState_Release(threadstate); +} + +static void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self) +{ + PyObject* new_list; + PyObject* weakref; + int i; + + /* we only need to do this once in a while */ + if (self->created_statements++ < 200) { + return; + } + + self->created_statements = 0; + + new_list = PyList_New(0); + if (!new_list) { + return; + } + + for (i = 0; i < PyList_Size(self->statements); i++) { + weakref = PyList_GetItem(self->statements, i); + if (PyWeakref_GetObject(weakref) != Py_None) { + if (PyList_Append(new_list, weakref) != 0) { + Py_DECREF(new_list); + return; + } + } + } + + Py_SETREF(self->statements, new_list); +} + +static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self) +{ + PyObject* new_list; + PyObject* weakref; + int i; + + /* we only need to do this once in a while */ + if (self->created_cursors++ < 200) { + return; + } + + self->created_cursors = 0; + + new_list = PyList_New(0); + if (!new_list) { + return; + } + + for (i = 0; i < PyList_Size(self->cursors); i++) { + weakref = PyList_GetItem(self->cursors, i); + if (PyWeakref_GetObject(weakref) != Py_None) { + if (PyList_Append(new_list, weakref) != 0) { + Py_DECREF(new_list); + return; + } + } + } + + Py_SETREF(self->cursors, new_list); +} + static void _destructor(void* args) { Py_DECREF((PyObject*)args); } -PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ +PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +{ static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL}; - - PyObject* func; - char* name; - int narg; - int rc; + + PyObject* func; + char* name; + int narg; + int rc; int deterministic = 0; int flags = SQLITE_UTF8; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|$p", kwlist, &name, &narg, &func, &deterministic)) - { - return NULL; - } - + { + return NULL; + } + if (deterministic) { #if SQLITE_VERSION_NUMBER < 3008003 PyErr_SetString(pysqlite_NotSupportedError, "deterministic=True requires SQLite 3.8.3 or higher"); - return NULL; + return NULL; #else - if (sqlite3_libversion_number() < 3008003) { - PyErr_SetString(pysqlite_NotSupportedError, - "deterministic=True requires SQLite 3.8.3 or higher"); - return NULL; - } - flags |= SQLITE_DETERMINISTIC; -#endif - } - Py_INCREF(func); - rc = sqlite3_create_function_v2(self->db, - name, - narg, - flags, - (void*)func, - _pysqlite_func_callback, - NULL, - NULL, - &_destructor); // will decref func - - if (rc != SQLITE_OK) { - /* Workaround for SQLite bug: no error code or string is available here */ - PyErr_SetString(pysqlite_OperationalError, "Error creating function"); - return NULL; - } - Py_RETURN_NONE; -} - -PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* aggregate_class; - - int n_arg; - char* name; - static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL }; - int rc; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate", - kwlist, &name, &n_arg, &aggregate_class)) { - return NULL; - } - Py_INCREF(aggregate_class); - rc = sqlite3_create_function_v2(self->db, - name, - n_arg, - SQLITE_UTF8, - (void*)aggregate_class, - 0, - &_pysqlite_step_callback, - &_pysqlite_final_callback, - &_destructor); // will decref func - if (rc != SQLITE_OK) { - /* Workaround for SQLite bug: no error code or string is available here */ - PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate"); - return NULL; - } - Py_RETURN_NONE; -} - -static int _authorizer_callback(void* user_arg, int action, const char* arg1, const char* arg2 , const char* dbname, const char* access_attempt_source) -{ - PyObject *ret; - int rc; - PyGILState_STATE gilstate; - - gilstate = PyGILState_Ensure(); - - ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); - - if (ret == NULL) { - if (_pysqlite_enable_callback_tracebacks) - PyErr_Print(); - else - PyErr_Clear(); - - rc = SQLITE_DENY; - } - else { - if (PyLong_Check(ret)) { - rc = _PyLong_AsInt(ret); - if (rc == -1 && PyErr_Occurred()) { - if (_pysqlite_enable_callback_tracebacks) - PyErr_Print(); - else - PyErr_Clear(); - rc = SQLITE_DENY; - } - } - else { - rc = SQLITE_DENY; - } - Py_DECREF(ret); - } - - PyGILState_Release(gilstate); - return rc; -} - -static int _progress_handler(void* user_arg) -{ - int rc; - PyObject *ret; - PyGILState_STATE gilstate; - - gilstate = PyGILState_Ensure(); - ret = _PyObject_CallNoArg((PyObject*)user_arg); - - if (!ret) { - if (_pysqlite_enable_callback_tracebacks) { - PyErr_Print(); - } else { - PyErr_Clear(); - } - - /* abort query if error occurred */ - rc = 1; - } else { - rc = (int)PyObject_IsTrue(ret); - Py_DECREF(ret); - } - - PyGILState_Release(gilstate); - return rc; -} - -static void _trace_callback(void* user_arg, const char* statement_string) -{ - PyObject *py_statement = NULL; - PyObject *ret = NULL; - - PyGILState_STATE gilstate; - - gilstate = PyGILState_Ensure(); - py_statement = PyUnicode_DecodeUTF8(statement_string, - strlen(statement_string), "replace"); - if (py_statement) { - ret = PyObject_CallOneArg((PyObject*)user_arg, py_statement); - Py_DECREF(py_statement); - } - - if (ret) { - Py_DECREF(ret); - } else { - if (_pysqlite_enable_callback_tracebacks) { - PyErr_Print(); - } else { - PyErr_Clear(); - } - } - - PyGILState_Release(gilstate); -} - -static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* authorizer_cb; - - static char *kwlist[] = { "authorizer_callback", NULL }; - int rc; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer", - kwlist, &authorizer_cb)) { - return NULL; - } - - rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb); - if (rc != SQLITE_OK) { - PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback"); - Py_XSETREF(self->function_pinboard_authorizer_cb, NULL); - return NULL; - } else { - Py_INCREF(authorizer_cb); - Py_XSETREF(self->function_pinboard_authorizer_cb, authorizer_cb); - } - Py_RETURN_NONE; -} - -static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* progress_handler; - int n; - - static char *kwlist[] = { "progress_handler", "n", NULL }; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi:set_progress_handler", - kwlist, &progress_handler, &n)) { - return NULL; - } - - if (progress_handler == Py_None) { - /* None clears the progress handler previously set */ - sqlite3_progress_handler(self->db, 0, 0, (void*)0); - Py_XSETREF(self->function_pinboard_progress_handler, NULL); - } else { - sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler); - Py_INCREF(progress_handler); - Py_XSETREF(self->function_pinboard_progress_handler, progress_handler); - } - Py_RETURN_NONE; -} - -static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* trace_callback; - - static char *kwlist[] = { "trace_callback", NULL }; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_trace_callback", - kwlist, &trace_callback)) { - return NULL; - } - - if (trace_callback == Py_None) { - /* None clears the trace callback previously set */ - sqlite3_trace(self->db, 0, (void*)0); - Py_XSETREF(self->function_pinboard_trace_callback, NULL); - } else { - sqlite3_trace(self->db, _trace_callback, trace_callback); - Py_INCREF(trace_callback); - Py_XSETREF(self->function_pinboard_trace_callback, trace_callback); - } - - Py_RETURN_NONE; -} - -#ifdef HAVE_LOAD_EXTENSION -static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObject* args) -{ - int rc; - int onoff; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!PyArg_ParseTuple(args, "i", &onoff)) { - return NULL; - } - - rc = sqlite3_enable_load_extension(self->db, onoff); - - if (rc != SQLITE_OK) { - PyErr_SetString(pysqlite_OperationalError, "Error enabling load extension"); - return NULL; - } else { - Py_RETURN_NONE; - } -} - -static PyObject* pysqlite_load_extension(pysqlite_Connection* self, PyObject* args) -{ - int rc; - char* extension_name; - char* errmsg; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!PyArg_ParseTuple(args, "s", &extension_name)) { - return NULL; - } - - rc = sqlite3_load_extension(self->db, extension_name, 0, &errmsg); - if (rc != 0) { - PyErr_SetString(pysqlite_OperationalError, errmsg); - return NULL; - } else { - Py_RETURN_NONE; - } -} -#endif - -int pysqlite_check_thread(pysqlite_Connection* self) -{ - if (self->check_same_thread) { - if (PyThread_get_thread_ident() != self->thread_ident) { - PyErr_Format(pysqlite_ProgrammingError, - "SQLite objects created in a thread can only be used in that same thread. " - "The object was created in thread id %lu and this is thread id %lu.", - self->thread_ident, PyThread_get_thread_ident()); - return 0; - } - - } - return 1; -} - -static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* self, void* unused) -{ - if (!pysqlite_check_connection(self)) { - return NULL; - } - Py_INCREF(self->isolation_level); - return self->isolation_level; -} - -static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self, void* unused) -{ - if (!pysqlite_check_connection(self)) { - return NULL; + if (sqlite3_libversion_number() < 3008003) { + PyErr_SetString(pysqlite_NotSupportedError, + "deterministic=True requires SQLite 3.8.3 or higher"); + return NULL; + } + flags |= SQLITE_DETERMINISTIC; +#endif + } + Py_INCREF(func); + rc = sqlite3_create_function_v2(self->db, + name, + narg, + flags, + (void*)func, + _pysqlite_func_callback, + NULL, + NULL, + &_destructor); // will decref func + + if (rc != SQLITE_OK) { + /* Workaround for SQLite bug: no error code or string is available here */ + PyErr_SetString(pysqlite_OperationalError, "Error creating function"); + return NULL; + } + Py_RETURN_NONE; +} + +PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +{ + PyObject* aggregate_class; + + int n_arg; + char* name; + static char *kwlist[] = { "name", "n_arg", "aggregate_class", NULL }; + int rc; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO:create_aggregate", + kwlist, &name, &n_arg, &aggregate_class)) { + return NULL; + } + Py_INCREF(aggregate_class); + rc = sqlite3_create_function_v2(self->db, + name, + n_arg, + SQLITE_UTF8, + (void*)aggregate_class, + 0, + &_pysqlite_step_callback, + &_pysqlite_final_callback, + &_destructor); // will decref func + if (rc != SQLITE_OK) { + /* Workaround for SQLite bug: no error code or string is available here */ + PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate"); + return NULL; + } + Py_RETURN_NONE; +} + +static int _authorizer_callback(void* user_arg, int action, const char* arg1, const char* arg2 , const char* dbname, const char* access_attempt_source) +{ + PyObject *ret; + int rc; + PyGILState_STATE gilstate; + + gilstate = PyGILState_Ensure(); + + ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); + + if (ret == NULL) { + if (_pysqlite_enable_callback_tracebacks) + PyErr_Print(); + else + PyErr_Clear(); + + rc = SQLITE_DENY; + } + else { + if (PyLong_Check(ret)) { + rc = _PyLong_AsInt(ret); + if (rc == -1 && PyErr_Occurred()) { + if (_pysqlite_enable_callback_tracebacks) + PyErr_Print(); + else + PyErr_Clear(); + rc = SQLITE_DENY; + } + } + else { + rc = SQLITE_DENY; + } + Py_DECREF(ret); + } + + PyGILState_Release(gilstate); + return rc; +} + +static int _progress_handler(void* user_arg) +{ + int rc; + PyObject *ret; + PyGILState_STATE gilstate; + + gilstate = PyGILState_Ensure(); + ret = _PyObject_CallNoArg((PyObject*)user_arg); + + if (!ret) { + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + + /* abort query if error occurred */ + rc = 1; + } else { + rc = (int)PyObject_IsTrue(ret); + Py_DECREF(ret); + } + + PyGILState_Release(gilstate); + return rc; +} + +static void _trace_callback(void* user_arg, const char* statement_string) +{ + PyObject *py_statement = NULL; + PyObject *ret = NULL; + + PyGILState_STATE gilstate; + + gilstate = PyGILState_Ensure(); + py_statement = PyUnicode_DecodeUTF8(statement_string, + strlen(statement_string), "replace"); + if (py_statement) { + ret = PyObject_CallOneArg((PyObject*)user_arg, py_statement); + Py_DECREF(py_statement); + } + + if (ret) { + Py_DECREF(ret); + } else { + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + } + + PyGILState_Release(gilstate); +} + +static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +{ + PyObject* authorizer_cb; + + static char *kwlist[] = { "authorizer_callback", NULL }; + int rc; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_authorizer", + kwlist, &authorizer_cb)) { + return NULL; + } + + rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb); + if (rc != SQLITE_OK) { + PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback"); + Py_XSETREF(self->function_pinboard_authorizer_cb, NULL); + return NULL; } else { - return Py_BuildValue("i", sqlite3_total_changes(self->db)); - } -} - -static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* self, void* unused) -{ + Py_INCREF(authorizer_cb); + Py_XSETREF(self->function_pinboard_authorizer_cb, authorizer_cb); + } + Py_RETURN_NONE; +} + +static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +{ + PyObject* progress_handler; + int n; + + static char *kwlist[] = { "progress_handler", "n", NULL }; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi:set_progress_handler", + kwlist, &progress_handler, &n)) { + return NULL; + } + + if (progress_handler == Py_None) { + /* None clears the progress handler previously set */ + sqlite3_progress_handler(self->db, 0, 0, (void*)0); + Py_XSETREF(self->function_pinboard_progress_handler, NULL); + } else { + sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler); + Py_INCREF(progress_handler); + Py_XSETREF(self->function_pinboard_progress_handler, progress_handler); + } + Py_RETURN_NONE; +} + +static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +{ + PyObject* trace_callback; + + static char *kwlist[] = { "trace_callback", NULL }; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:set_trace_callback", + kwlist, &trace_callback)) { + return NULL; + } + + if (trace_callback == Py_None) { + /* None clears the trace callback previously set */ + sqlite3_trace(self->db, 0, (void*)0); + Py_XSETREF(self->function_pinboard_trace_callback, NULL); + } else { + sqlite3_trace(self->db, _trace_callback, trace_callback); + Py_INCREF(trace_callback); + Py_XSETREF(self->function_pinboard_trace_callback, trace_callback); + } + + Py_RETURN_NONE; +} + +#ifdef HAVE_LOAD_EXTENSION +static PyObject* pysqlite_enable_load_extension(pysqlite_Connection* self, PyObject* args) +{ + int rc; + int onoff; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!PyArg_ParseTuple(args, "i", &onoff)) { + return NULL; + } + + rc = sqlite3_enable_load_extension(self->db, onoff); + + if (rc != SQLITE_OK) { + PyErr_SetString(pysqlite_OperationalError, "Error enabling load extension"); + return NULL; + } else { + Py_RETURN_NONE; + } +} + +static PyObject* pysqlite_load_extension(pysqlite_Connection* self, PyObject* args) +{ + int rc; + char* extension_name; + char* errmsg; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!PyArg_ParseTuple(args, "s", &extension_name)) { + return NULL; + } + + rc = sqlite3_load_extension(self->db, extension_name, 0, &errmsg); + if (rc != 0) { + PyErr_SetString(pysqlite_OperationalError, errmsg); + return NULL; + } else { + Py_RETURN_NONE; + } +} +#endif + +int pysqlite_check_thread(pysqlite_Connection* self) +{ + if (self->check_same_thread) { + if (PyThread_get_thread_ident() != self->thread_ident) { + PyErr_Format(pysqlite_ProgrammingError, + "SQLite objects created in a thread can only be used in that same thread. " + "The object was created in thread id %lu and this is thread id %lu.", + self->thread_ident, PyThread_get_thread_ident()); + return 0; + } + + } + return 1; +} + +static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* self, void* unused) +{ if (!pysqlite_check_connection(self)) { return NULL; } - if (!sqlite3_get_autocommit(self->db)) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; -} - -static int -pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored)) -{ - if (isolation_level == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - if (isolation_level == Py_None) { + Py_INCREF(self->isolation_level); + return self->isolation_level; +} + +static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self, void* unused) +{ + if (!pysqlite_check_connection(self)) { + return NULL; + } else { + return Py_BuildValue("i", sqlite3_total_changes(self->db)); + } +} + +static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* self, void* unused) +{ + if (!pysqlite_check_connection(self)) { + return NULL; + } + if (!sqlite3_get_autocommit(self->db)) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static int +pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored)) +{ + if (isolation_level == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + if (isolation_level == Py_None) { /* We might get called during connection init, so we cannot use * pysqlite_connection_commit() here. */ if (self->db && !sqlite3_get_autocommit(self->db)) { @@ -1211,330 +1211,330 @@ pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* iso if (rc != SQLITE_OK) { return _pysqlite_seterror(self->db, NULL); } - } - - self->begin_statement = NULL; - } else { - const char * const *candidate; - PyObject *uppercase_level; - _Py_IDENTIFIER(upper); - - if (!PyUnicode_Check(isolation_level)) { - PyErr_Format(PyExc_TypeError, - "isolation_level must be a string or None, not %.100s", - Py_TYPE(isolation_level)->tp_name); - return -1; - } - + } + + self->begin_statement = NULL; + } else { + const char * const *candidate; + PyObject *uppercase_level; + _Py_IDENTIFIER(upper); + + if (!PyUnicode_Check(isolation_level)) { + PyErr_Format(PyExc_TypeError, + "isolation_level must be a string or None, not %.100s", + Py_TYPE(isolation_level)->tp_name); + return -1; + } + uppercase_level = _PyObject_CallMethodIdOneArg( - (PyObject *)&PyUnicode_Type, &PyId_upper, + (PyObject *)&PyUnicode_Type, &PyId_upper, isolation_level); - if (!uppercase_level) { - return -1; - } - for (candidate = begin_statements; *candidate; candidate++) { - if (_PyUnicode_EqualToASCIIString(uppercase_level, *candidate + 6)) - break; - } - Py_DECREF(uppercase_level); - if (!*candidate) { - PyErr_SetString(PyExc_ValueError, - "invalid value for isolation_level"); - return -1; - } - self->begin_statement = *candidate; - } - - Py_INCREF(isolation_level); - Py_XSETREF(self->isolation_level, isolation_level); - return 0; -} - -PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) -{ - PyObject* sql; - pysqlite_Statement* statement; - PyObject* weakref; - int rc; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - return NULL; - } - - if (!_PyArg_NoKeywords(MODULE_NAME ".Connection", kwargs)) - return NULL; - + if (!uppercase_level) { + return -1; + } + for (candidate = begin_statements; *candidate; candidate++) { + if (_PyUnicode_EqualToASCIIString(uppercase_level, *candidate + 6)) + break; + } + Py_DECREF(uppercase_level); + if (!*candidate) { + PyErr_SetString(PyExc_ValueError, + "invalid value for isolation_level"); + return -1; + } + self->begin_statement = *candidate; + } + + Py_INCREF(isolation_level); + Py_XSETREF(self->isolation_level, isolation_level); + return 0; +} + +PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +{ + PyObject* sql; + pysqlite_Statement* statement; + PyObject* weakref; + int rc; + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + if (!_PyArg_NoKeywords(MODULE_NAME ".Connection", kwargs)) + return NULL; + if (!PyArg_ParseTuple(args, "U", &sql)) - return NULL; - - _pysqlite_drop_unused_statement_references(self); - - statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType); - if (!statement) { - return NULL; - } - - statement->db = NULL; - statement->st = NULL; - statement->sql = NULL; - statement->in_use = 0; - statement->in_weakreflist = NULL; - - rc = pysqlite_statement_create(statement, self, sql); - if (rc != SQLITE_OK) { - if (rc == PYSQLITE_TOO_MUCH_SQL) { - PyErr_SetString(pysqlite_Warning, "You can only execute one statement at a time."); - } else if (rc == PYSQLITE_SQL_WRONG_TYPE) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_SetString(pysqlite_Warning, "SQL is of wrong type. Must be string."); - } else { - (void)pysqlite_statement_reset(statement); - _pysqlite_seterror(self->db, NULL); - } - goto error; - } - - weakref = PyWeakref_NewRef((PyObject*)statement, NULL); - if (weakref == NULL) - goto error; - if (PyList_Append(self->statements, weakref) != 0) { - Py_DECREF(weakref); - goto error; - } - Py_DECREF(weakref); - - return (PyObject*)statement; - -error: - Py_DECREF(statement); - return NULL; -} - -PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args) -{ - PyObject* cursor = 0; - PyObject* result = 0; - PyObject* method = 0; - + return NULL; + + _pysqlite_drop_unused_statement_references(self); + + statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType); + if (!statement) { + return NULL; + } + + statement->db = NULL; + statement->st = NULL; + statement->sql = NULL; + statement->in_use = 0; + statement->in_weakreflist = NULL; + + rc = pysqlite_statement_create(statement, self, sql); + if (rc != SQLITE_OK) { + if (rc == PYSQLITE_TOO_MUCH_SQL) { + PyErr_SetString(pysqlite_Warning, "You can only execute one statement at a time."); + } else if (rc == PYSQLITE_SQL_WRONG_TYPE) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_SetString(pysqlite_Warning, "SQL is of wrong type. Must be string."); + } else { + (void)pysqlite_statement_reset(statement); + _pysqlite_seterror(self->db, NULL); + } + goto error; + } + + weakref = PyWeakref_NewRef((PyObject*)statement, NULL); + if (weakref == NULL) + goto error; + if (PyList_Append(self->statements, weakref) != 0) { + Py_DECREF(weakref); + goto error; + } + Py_DECREF(weakref); + + return (PyObject*)statement; + +error: + Py_DECREF(statement); + return NULL; +} + +PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args) +{ + PyObject* cursor = 0; + PyObject* result = 0; + PyObject* method = 0; + cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); - if (!cursor) { - goto error; - } - - method = PyObject_GetAttrString(cursor, "execute"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); - if (!result) { - Py_CLEAR(cursor); - } - -error: - Py_XDECREF(result); - Py_XDECREF(method); - - return cursor; -} - -PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* args) -{ - PyObject* cursor = 0; - PyObject* result = 0; - PyObject* method = 0; - + if (!cursor) { + goto error; + } + + method = PyObject_GetAttrString(cursor, "execute"); + if (!method) { + Py_CLEAR(cursor); + goto error; + } + + result = PyObject_CallObject(method, args); + if (!result) { + Py_CLEAR(cursor); + } + +error: + Py_XDECREF(result); + Py_XDECREF(method); + + return cursor; +} + +PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* args) +{ + PyObject* cursor = 0; + PyObject* result = 0; + PyObject* method = 0; + cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); - if (!cursor) { - goto error; - } - - method = PyObject_GetAttrString(cursor, "executemany"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); - if (!result) { - Py_CLEAR(cursor); - } - -error: - Py_XDECREF(result); - Py_XDECREF(method); - - return cursor; -} - -PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* args) -{ - PyObject* cursor = 0; - PyObject* result = 0; - PyObject* method = 0; - + if (!cursor) { + goto error; + } + + method = PyObject_GetAttrString(cursor, "executemany"); + if (!method) { + Py_CLEAR(cursor); + goto error; + } + + result = PyObject_CallObject(method, args); + if (!result) { + Py_CLEAR(cursor); + } + +error: + Py_XDECREF(result); + Py_XDECREF(method); + + return cursor; +} + +PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* args) +{ + PyObject* cursor = 0; + PyObject* result = 0; + PyObject* method = 0; + cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); - if (!cursor) { - goto error; - } - - method = PyObject_GetAttrString(cursor, "executescript"); - if (!method) { - Py_CLEAR(cursor); - goto error; - } - - result = PyObject_CallObject(method, args); - if (!result) { - Py_CLEAR(cursor); - } - -error: - Py_XDECREF(result); - Py_XDECREF(method); - - return cursor; -} - -/* ------------------------- COLLATION CODE ------------------------ */ - -static int -pysqlite_collation_callback( - void* context, - int text1_length, const void* text1_data, - int text2_length, const void* text2_data) -{ - PyObject* callback = (PyObject*)context; - PyObject* string1 = 0; - PyObject* string2 = 0; - PyGILState_STATE gilstate; - PyObject* retval = NULL; - long longval; - int result = 0; - gilstate = PyGILState_Ensure(); - - if (PyErr_Occurred()) { - goto finally; - } - - string1 = PyUnicode_FromStringAndSize((const char*)text1_data, text1_length); - string2 = PyUnicode_FromStringAndSize((const char*)text2_data, text2_length); - - if (!string1 || !string2) { - goto finally; /* failed to allocate strings */ - } - - retval = PyObject_CallFunctionObjArgs(callback, string1, string2, NULL); - - if (!retval) { - /* execution failed */ - goto finally; - } - - longval = PyLong_AsLongAndOverflow(retval, &result); - if (longval == -1 && PyErr_Occurred()) { - PyErr_Clear(); - result = 0; - } - else if (!result) { - if (longval > 0) - result = 1; - else if (longval < 0) - result = -1; - } - -finally: - Py_XDECREF(string1); - Py_XDECREF(string2); - Py_XDECREF(retval); - PyGILState_Release(gilstate); - return result; -} - -static PyObject * -pysqlite_connection_interrupt(pysqlite_Connection* self, PyObject* args) -{ - PyObject* retval = NULL; - - if (!pysqlite_check_connection(self)) { - goto finally; - } - - sqlite3_interrupt(self->db); - - Py_INCREF(Py_None); - retval = Py_None; - -finally: - return retval; -} - -/* Function author: Paul Kippes - * Class method of Connection to call the Python function _iterdump - * of the sqlite3 module. - */ -static PyObject * -pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) -{ + if (!cursor) { + goto error; + } + + method = PyObject_GetAttrString(cursor, "executescript"); + if (!method) { + Py_CLEAR(cursor); + goto error; + } + + result = PyObject_CallObject(method, args); + if (!result) { + Py_CLEAR(cursor); + } + +error: + Py_XDECREF(result); + Py_XDECREF(method); + + return cursor; +} + +/* ------------------------- COLLATION CODE ------------------------ */ + +static int +pysqlite_collation_callback( + void* context, + int text1_length, const void* text1_data, + int text2_length, const void* text2_data) +{ + PyObject* callback = (PyObject*)context; + PyObject* string1 = 0; + PyObject* string2 = 0; + PyGILState_STATE gilstate; + PyObject* retval = NULL; + long longval; + int result = 0; + gilstate = PyGILState_Ensure(); + + if (PyErr_Occurred()) { + goto finally; + } + + string1 = PyUnicode_FromStringAndSize((const char*)text1_data, text1_length); + string2 = PyUnicode_FromStringAndSize((const char*)text2_data, text2_length); + + if (!string1 || !string2) { + goto finally; /* failed to allocate strings */ + } + + retval = PyObject_CallFunctionObjArgs(callback, string1, string2, NULL); + + if (!retval) { + /* execution failed */ + goto finally; + } + + longval = PyLong_AsLongAndOverflow(retval, &result); + if (longval == -1 && PyErr_Occurred()) { + PyErr_Clear(); + result = 0; + } + else if (!result) { + if (longval > 0) + result = 1; + else if (longval < 0) + result = -1; + } + +finally: + Py_XDECREF(string1); + Py_XDECREF(string2); + Py_XDECREF(retval); + PyGILState_Release(gilstate); + return result; +} + +static PyObject * +pysqlite_connection_interrupt(pysqlite_Connection* self, PyObject* args) +{ + PyObject* retval = NULL; + + if (!pysqlite_check_connection(self)) { + goto finally; + } + + sqlite3_interrupt(self->db); + + Py_INCREF(Py_None); + retval = Py_None; + +finally: + return retval; +} + +/* Function author: Paul Kippes + * Class method of Connection to call the Python function _iterdump + * of the sqlite3 module. + */ +static PyObject * +pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) +{ _Py_IDENTIFIER(_iterdump); - PyObject* retval = NULL; - PyObject* module = NULL; - PyObject* module_dict; - PyObject* pyfn_iterdump; - - if (!pysqlite_check_connection(self)) { - goto finally; - } - - module = PyImport_ImportModule(MODULE_NAME ".dump"); - if (!module) { - goto finally; - } - - module_dict = PyModule_GetDict(module); - if (!module_dict) { - goto finally; - } - + PyObject* retval = NULL; + PyObject* module = NULL; + PyObject* module_dict; + PyObject* pyfn_iterdump; + + if (!pysqlite_check_connection(self)) { + goto finally; + } + + module = PyImport_ImportModule(MODULE_NAME ".dump"); + if (!module) { + goto finally; + } + + module_dict = PyModule_GetDict(module); + if (!module_dict) { + goto finally; + } + pyfn_iterdump = _PyDict_GetItemIdWithError(module_dict, &PyId__iterdump); - if (!pyfn_iterdump) { + if (!pyfn_iterdump) { if (!PyErr_Occurred()) { PyErr_SetString(pysqlite_OperationalError, "Failed to obtain _iterdump() reference"); } - goto finally; - } - + goto finally; + } + retval = PyObject_CallOneArg(pyfn_iterdump, (PyObject *)self); - -finally: - Py_XDECREF(module); - return retval; -} - -#ifdef HAVE_BACKUP_API -static PyObject * -pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *kwds) -{ - PyObject *target = NULL; - int pages = -1; - PyObject *progress = Py_None; - const char *name = "main"; - int rc; - int callback_error = 0; + +finally: + Py_XDECREF(module); + return retval; +} + +#ifdef HAVE_BACKUP_API +static PyObject * +pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *kwds) +{ + PyObject *target = NULL; + int pages = -1; + PyObject *progress = Py_None; + const char *name = "main"; + int rc; + int callback_error = 0; PyObject *sleep_obj = NULL; int sleep_ms = 250; - sqlite3 *bck_conn; - sqlite3_backup *bck_handle; - static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - + sqlite3 *bck_conn; + sqlite3_backup *bck_handle; + static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, - &pysqlite_ConnectionType, &target, + &pysqlite_ConnectionType, &target, &pages, &progress, &name, &sleep_obj)) { - return NULL; - } - + return NULL; + } + if (sleep_obj != NULL) { _PyTime_t sleep_secs; if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj, @@ -1554,243 +1554,243 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * return NULL; } - if (!pysqlite_check_connection((pysqlite_Connection *)target)) { - return NULL; - } - - if ((pysqlite_Connection *)target == self) { - PyErr_SetString(PyExc_ValueError, "target cannot be the same connection instance"); - return NULL; - } - -#if SQLITE_VERSION_NUMBER < 3008008 - /* Since 3.8.8 this is already done, per commit - https://www.sqlite.org/src/info/169b5505498c0a7e */ - if (!sqlite3_get_autocommit(((pysqlite_Connection *)target)->db)) { - PyErr_SetString(pysqlite_OperationalError, "target is in transaction"); - return NULL; - } -#endif - - if (progress != Py_None && !PyCallable_Check(progress)) { - PyErr_SetString(PyExc_TypeError, "progress argument must be a callable"); - return NULL; - } - - if (pages == 0) { - pages = -1; - } - - bck_conn = ((pysqlite_Connection *)target)->db; - - Py_BEGIN_ALLOW_THREADS - bck_handle = sqlite3_backup_init(bck_conn, "main", self->db, name); - Py_END_ALLOW_THREADS - - if (bck_handle) { - do { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_backup_step(bck_handle, pages); - Py_END_ALLOW_THREADS - - if (progress != Py_None) { - PyObject *res; - - res = PyObject_CallFunction(progress, "iii", rc, - sqlite3_backup_remaining(bck_handle), - sqlite3_backup_pagecount(bck_handle)); - if (res == NULL) { - /* User's callback raised an error: interrupt the loop and - propagate it. */ - callback_error = 1; - rc = -1; - } else { - Py_DECREF(res); - } - } - - /* Sleep for a while if there are still further pages to copy and - the engine could not make any progress */ - if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { - Py_BEGIN_ALLOW_THREADS + if (!pysqlite_check_connection((pysqlite_Connection *)target)) { + return NULL; + } + + if ((pysqlite_Connection *)target == self) { + PyErr_SetString(PyExc_ValueError, "target cannot be the same connection instance"); + return NULL; + } + +#if SQLITE_VERSION_NUMBER < 3008008 + /* Since 3.8.8 this is already done, per commit + https://www.sqlite.org/src/info/169b5505498c0a7e */ + if (!sqlite3_get_autocommit(((pysqlite_Connection *)target)->db)) { + PyErr_SetString(pysqlite_OperationalError, "target is in transaction"); + return NULL; + } +#endif + + if (progress != Py_None && !PyCallable_Check(progress)) { + PyErr_SetString(PyExc_TypeError, "progress argument must be a callable"); + return NULL; + } + + if (pages == 0) { + pages = -1; + } + + bck_conn = ((pysqlite_Connection *)target)->db; + + Py_BEGIN_ALLOW_THREADS + bck_handle = sqlite3_backup_init(bck_conn, "main", self->db, name); + Py_END_ALLOW_THREADS + + if (bck_handle) { + do { + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_backup_step(bck_handle, pages); + Py_END_ALLOW_THREADS + + if (progress != Py_None) { + PyObject *res; + + res = PyObject_CallFunction(progress, "iii", rc, + sqlite3_backup_remaining(bck_handle), + sqlite3_backup_pagecount(bck_handle)); + if (res == NULL) { + /* User's callback raised an error: interrupt the loop and + propagate it. */ + callback_error = 1; + rc = -1; + } else { + Py_DECREF(res); + } + } + + /* Sleep for a while if there are still further pages to copy and + the engine could not make any progress */ + if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { + Py_BEGIN_ALLOW_THREADS sqlite3_sleep(sleep_ms); - Py_END_ALLOW_THREADS - } - } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_backup_finish(bck_handle); - Py_END_ALLOW_THREADS - } else { - rc = _pysqlite_seterror(bck_conn, NULL); - } - - if (!callback_error && rc != SQLITE_OK) { - /* We cannot use _pysqlite_seterror() here because the backup APIs do - not set the error status on the connection object, but rather on - the backup handle. */ - if (rc == SQLITE_NOMEM) { - (void)PyErr_NoMemory(); - } else { -#if SQLITE_VERSION_NUMBER > 3007015 - PyErr_SetString(pysqlite_OperationalError, sqlite3_errstr(rc)); -#else - switch (rc) { - case SQLITE_ERROR: - /* Description of SQLITE_ERROR in SQLite 3.7.14 and older - releases. */ - PyErr_SetString(pysqlite_OperationalError, - "SQL logic error or missing database"); - break; - case SQLITE_READONLY: - PyErr_SetString(pysqlite_OperationalError, - "attempt to write a readonly database"); - break; - case SQLITE_BUSY: - PyErr_SetString(pysqlite_OperationalError, "database is locked"); - break; - case SQLITE_LOCKED: - PyErr_SetString(pysqlite_OperationalError, - "database table is locked"); - break; - default: - PyErr_Format(pysqlite_OperationalError, - "unrecognized error code: %d", rc); - break; - } -#endif - } - } - - if (!callback_error && rc == SQLITE_OK) { - Py_RETURN_NONE; - } else { - return NULL; - } -} -#endif - -static PyObject * -pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) -{ - PyObject* callable; - PyObject* uppercase_name = 0; - PyObject* name; - PyObject* retval; - Py_ssize_t i, len; - _Py_IDENTIFIER(upper); - const char *uppercase_name_str; - int rc; - unsigned int kind; + Py_END_ALLOW_THREADS + } + } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_backup_finish(bck_handle); + Py_END_ALLOW_THREADS + } else { + rc = _pysqlite_seterror(bck_conn, NULL); + } + + if (!callback_error && rc != SQLITE_OK) { + /* We cannot use _pysqlite_seterror() here because the backup APIs do + not set the error status on the connection object, but rather on + the backup handle. */ + if (rc == SQLITE_NOMEM) { + (void)PyErr_NoMemory(); + } else { +#if SQLITE_VERSION_NUMBER > 3007015 + PyErr_SetString(pysqlite_OperationalError, sqlite3_errstr(rc)); +#else + switch (rc) { + case SQLITE_ERROR: + /* Description of SQLITE_ERROR in SQLite 3.7.14 and older + releases. */ + PyErr_SetString(pysqlite_OperationalError, + "SQL logic error or missing database"); + break; + case SQLITE_READONLY: + PyErr_SetString(pysqlite_OperationalError, + "attempt to write a readonly database"); + break; + case SQLITE_BUSY: + PyErr_SetString(pysqlite_OperationalError, "database is locked"); + break; + case SQLITE_LOCKED: + PyErr_SetString(pysqlite_OperationalError, + "database table is locked"); + break; + default: + PyErr_Format(pysqlite_OperationalError, + "unrecognized error code: %d", rc); + break; + } +#endif + } + } + + if (!callback_error && rc == SQLITE_OK) { + Py_RETURN_NONE; + } else { + return NULL; + } +} +#endif + +static PyObject * +pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) +{ + PyObject* callable; + PyObject* uppercase_name = 0; + PyObject* name; + PyObject* retval; + Py_ssize_t i, len; + _Py_IDENTIFIER(upper); + const char *uppercase_name_str; + int rc; + unsigned int kind; const void *data; - - if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { - goto finally; - } - - if (!PyArg_ParseTuple(args, "UO:create_collation(name, callback)", - &name, &callable)) { - goto finally; - } - + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + goto finally; + } + + if (!PyArg_ParseTuple(args, "UO:create_collation(name, callback)", + &name, &callable)) { + goto finally; + } + uppercase_name = _PyObject_CallMethodIdOneArg((PyObject *)&PyUnicode_Type, &PyId_upper, name); - if (!uppercase_name) { - goto finally; - } - - if (PyUnicode_READY(uppercase_name)) - goto finally; - len = PyUnicode_GET_LENGTH(uppercase_name); - kind = PyUnicode_KIND(uppercase_name); - data = PyUnicode_DATA(uppercase_name); - for (i=0; i= '0' && ch <= '9') - || (ch >= 'A' && ch <= 'Z') - || (ch == '_')) - { - continue; - } else { - PyErr_SetString(pysqlite_ProgrammingError, "invalid character in collation name"); - goto finally; - } - } - - uppercase_name_str = PyUnicode_AsUTF8(uppercase_name); - if (!uppercase_name_str) - goto finally; - - if (callable != Py_None && !PyCallable_Check(callable)) { - PyErr_SetString(PyExc_TypeError, "parameter must be callable"); - goto finally; - } - - if (callable != Py_None) { - if (PyDict_SetItem(self->collations, uppercase_name, callable) == -1) - goto finally; - } else { - if (PyDict_DelItem(self->collations, uppercase_name) == -1) - goto finally; - } - - rc = sqlite3_create_collation(self->db, - uppercase_name_str, - SQLITE_UTF8, - (callable != Py_None) ? callable : NULL, - (callable != Py_None) ? pysqlite_collation_callback : NULL); - if (rc != SQLITE_OK) { + if (!uppercase_name) { + goto finally; + } + + if (PyUnicode_READY(uppercase_name)) + goto finally; + len = PyUnicode_GET_LENGTH(uppercase_name); + kind = PyUnicode_KIND(uppercase_name); + data = PyUnicode_DATA(uppercase_name); + for (i=0; i= '0' && ch <= '9') + || (ch >= 'A' && ch <= 'Z') + || (ch == '_')) + { + continue; + } else { + PyErr_SetString(pysqlite_ProgrammingError, "invalid character in collation name"); + goto finally; + } + } + + uppercase_name_str = PyUnicode_AsUTF8(uppercase_name); + if (!uppercase_name_str) + goto finally; + + if (callable != Py_None && !PyCallable_Check(callable)) { + PyErr_SetString(PyExc_TypeError, "parameter must be callable"); + goto finally; + } + + if (callable != Py_None) { + if (PyDict_SetItem(self->collations, uppercase_name, callable) == -1) + goto finally; + } else { + if (PyDict_DelItem(self->collations, uppercase_name) == -1) + goto finally; + } + + rc = sqlite3_create_collation(self->db, + uppercase_name_str, + SQLITE_UTF8, + (callable != Py_None) ? callable : NULL, + (callable != Py_None) ? pysqlite_collation_callback : NULL); + if (rc != SQLITE_OK) { if (callable != Py_None) { if (PyDict_DelItem(self->collations, uppercase_name) < 0) { PyErr_Clear(); } } - _pysqlite_seterror(self->db, NULL); - goto finally; - } - -finally: - Py_XDECREF(uppercase_name); - - if (PyErr_Occurred()) { - retval = NULL; - } else { - Py_INCREF(Py_None); - retval = Py_None; - } - - return retval; -} - -/* Called when the connection is used as a context manager. Returns itself as a - * convenience to the caller. */ -static PyObject * -pysqlite_connection_enter(pysqlite_Connection* self, PyObject* args) -{ - Py_INCREF(self); - return (PyObject*)self; -} - -/** Called when the connection is used as a context manager. If there was any - * exception, a rollback takes place; otherwise we commit. */ -static PyObject * -pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) -{ + _pysqlite_seterror(self->db, NULL); + goto finally; + } + +finally: + Py_XDECREF(uppercase_name); + + if (PyErr_Occurred()) { + retval = NULL; + } else { + Py_INCREF(Py_None); + retval = Py_None; + } + + return retval; +} + +/* Called when the connection is used as a context manager. Returns itself as a + * convenience to the caller. */ +static PyObject * +pysqlite_connection_enter(pysqlite_Connection* self, PyObject* args) +{ + Py_INCREF(self); + return (PyObject*)self; +} + +/** Called when the connection is used as a context manager. If there was any + * exception, a rollback takes place; otherwise we commit. */ +static PyObject * +pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) +{ PyObject *exc_type, *exc_value, *exc_tb; - if (!PyArg_ParseTuple(args, "OOO", &exc_type, &exc_value, &exc_tb)) { - return NULL; - } - + if (!PyArg_ParseTuple(args, "OOO", &exc_type, &exc_value, &exc_tb)) { + return NULL; + } + int commit = 0; PyObject *result; - if (exc_type == Py_None && exc_value == Py_None && exc_tb == Py_None) { + if (exc_type == Py_None && exc_value == Py_None && exc_tb == Py_None) { commit = 1; result = pysqlite_connection_commit(self, NULL); - } + } else { result = pysqlite_connection_rollback(self, NULL); } - + if (result == NULL) { if (commit) { /* Commit failed; try to rollback in order to unlock the database. @@ -1806,132 +1806,132 @@ pysqlite_connection_exit(pysqlite_Connection* self, PyObject* args) PyErr_Restore(exc, val, tb); } } - return NULL; - } - Py_DECREF(result); - - Py_RETURN_FALSE; -} - -static const char connection_doc[] = -PyDoc_STR("SQLite database connection object."); - -static PyGetSetDef connection_getset[] = { - {"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level}, - {"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0}, - {"in_transaction", (getter)pysqlite_connection_get_in_transaction, (setter)0}, - {NULL} -}; - -static PyMethodDef connection_methods[] = { + return NULL; + } + Py_DECREF(result); + + Py_RETURN_FALSE; +} + +static const char connection_doc[] = +PyDoc_STR("SQLite database connection object."); + +static PyGetSetDef connection_getset[] = { + {"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level}, + {"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0}, + {"in_transaction", (getter)pysqlite_connection_get_in_transaction, (setter)0}, + {NULL} +}; + +static PyMethodDef connection_methods[] = { {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Return a cursor for the connection.")}, - {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, - PyDoc_STR("Closes the connection.")}, - {"commit", (PyCFunction)pysqlite_connection_commit, METH_NOARGS, - PyDoc_STR("Commit the current transaction.")}, - {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, - PyDoc_STR("Roll back the current transaction.")}, + PyDoc_STR("Return a cursor for the connection.")}, + {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, + PyDoc_STR("Closes the connection.")}, + {"commit", (PyCFunction)pysqlite_connection_commit, METH_NOARGS, + PyDoc_STR("Commit the current transaction.")}, + {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, + PyDoc_STR("Roll back the current transaction.")}, {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Creates a new function. Non-standard.")}, + PyDoc_STR("Creates a new function. Non-standard.")}, {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Creates a new aggregate. Non-standard.")}, + PyDoc_STR("Creates a new aggregate. Non-standard.")}, {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets authorizer callback. Non-standard.")}, - #ifdef HAVE_LOAD_EXTENSION - {"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS, - PyDoc_STR("Enable dynamic loading of SQLite extension modules. Non-standard.")}, - {"load_extension", (PyCFunction)pysqlite_load_extension, METH_VARARGS, - PyDoc_STR("Load SQLite extension module. Non-standard.")}, - #endif + PyDoc_STR("Sets authorizer callback. Non-standard.")}, + #ifdef HAVE_LOAD_EXTENSION + {"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS, + PyDoc_STR("Enable dynamic loading of SQLite extension modules. Non-standard.")}, + {"load_extension", (PyCFunction)pysqlite_load_extension, METH_VARARGS, + PyDoc_STR("Load SQLite extension module. Non-standard.")}, + #endif {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets progress handler callback. Non-standard.")}, + PyDoc_STR("Sets progress handler callback. Non-standard.")}, {"set_trace_callback", (PyCFunction)(void(*)(void))pysqlite_connection_set_trace_callback, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets a trace callback called for each SQL statement (passed as unicode). Non-standard.")}, - {"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS, - PyDoc_STR("Executes a SQL statement. Non-standard.")}, - {"executemany", (PyCFunction)pysqlite_connection_executemany, METH_VARARGS, - PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")}, - {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_VARARGS, - PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, - {"create_collation", (PyCFunction)pysqlite_connection_create_collation, METH_VARARGS, - PyDoc_STR("Creates a collation function. Non-standard.")}, - {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, - PyDoc_STR("Abort any pending database operation. Non-standard.")}, - {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, - PyDoc_STR("Returns iterator to the dump of the database in an SQL text format. Non-standard.")}, - #ifdef HAVE_BACKUP_API + PyDoc_STR("Sets a trace callback called for each SQL statement (passed as unicode). Non-standard.")}, + {"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS, + PyDoc_STR("Executes a SQL statement. Non-standard.")}, + {"executemany", (PyCFunction)pysqlite_connection_executemany, METH_VARARGS, + PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")}, + {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_VARARGS, + PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, + {"create_collation", (PyCFunction)pysqlite_connection_create_collation, METH_VARARGS, + PyDoc_STR("Creates a collation function. Non-standard.")}, + {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, + PyDoc_STR("Abort any pending database operation. Non-standard.")}, + {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, + PyDoc_STR("Returns iterator to the dump of the database in an SQL text format. Non-standard.")}, + #ifdef HAVE_BACKUP_API {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Makes a backup of the database. Non-standard.")}, - #endif - {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, - PyDoc_STR("For context manager. Non-standard.")}, - {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS, - PyDoc_STR("For context manager. Non-standard.")}, - {NULL, NULL} -}; - -static struct PyMemberDef connection_members[] = -{ - {"Warning", T_OBJECT, offsetof(pysqlite_Connection, Warning), READONLY}, - {"Error", T_OBJECT, offsetof(pysqlite_Connection, Error), READONLY}, - {"InterfaceError", T_OBJECT, offsetof(pysqlite_Connection, InterfaceError), READONLY}, - {"DatabaseError", T_OBJECT, offsetof(pysqlite_Connection, DatabaseError), READONLY}, - {"DataError", T_OBJECT, offsetof(pysqlite_Connection, DataError), READONLY}, - {"OperationalError", T_OBJECT, offsetof(pysqlite_Connection, OperationalError), READONLY}, - {"IntegrityError", T_OBJECT, offsetof(pysqlite_Connection, IntegrityError), READONLY}, - {"InternalError", T_OBJECT, offsetof(pysqlite_Connection, InternalError), READONLY}, - {"ProgrammingError", T_OBJECT, offsetof(pysqlite_Connection, ProgrammingError), READONLY}, - {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY}, - {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, - {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, - {NULL} -}; - -PyTypeObject pysqlite_ConnectionType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Connection", /* tp_name */ - sizeof(pysqlite_Connection), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_connection_dealloc, /* tp_dealloc */ + PyDoc_STR("Makes a backup of the database. Non-standard.")}, + #endif + {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, + PyDoc_STR("For context manager. Non-standard.")}, + {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS, + PyDoc_STR("For context manager. Non-standard.")}, + {NULL, NULL} +}; + +static struct PyMemberDef connection_members[] = +{ + {"Warning", T_OBJECT, offsetof(pysqlite_Connection, Warning), READONLY}, + {"Error", T_OBJECT, offsetof(pysqlite_Connection, Error), READONLY}, + {"InterfaceError", T_OBJECT, offsetof(pysqlite_Connection, InterfaceError), READONLY}, + {"DatabaseError", T_OBJECT, offsetof(pysqlite_Connection, DatabaseError), READONLY}, + {"DataError", T_OBJECT, offsetof(pysqlite_Connection, DataError), READONLY}, + {"OperationalError", T_OBJECT, offsetof(pysqlite_Connection, OperationalError), READONLY}, + {"IntegrityError", T_OBJECT, offsetof(pysqlite_Connection, IntegrityError), READONLY}, + {"InternalError", T_OBJECT, offsetof(pysqlite_Connection, InternalError), READONLY}, + {"ProgrammingError", T_OBJECT, offsetof(pysqlite_Connection, ProgrammingError), READONLY}, + {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY}, + {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, + {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, + {NULL} +}; + +PyTypeObject pysqlite_ConnectionType = { + PyVarObject_HEAD_INIT(NULL, 0) + MODULE_NAME ".Connection", /* tp_name */ + sizeof(pysqlite_Connection), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pysqlite_connection_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)pysqlite_connection_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - connection_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - connection_methods, /* tp_methods */ - connection_members, /* tp_members */ - connection_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_connection_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ -}; - -extern int pysqlite_connection_setup_types(void) -{ - pysqlite_ConnectionType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_ConnectionType); -} + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)pysqlite_connection_call, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ + connection_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + connection_methods, /* tp_methods */ + connection_members, /* tp_members */ + connection_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pysqlite_connection_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0 /* tp_free */ +}; + +extern int pysqlite_connection_setup_types(void) +{ + pysqlite_ConnectionType.tp_new = PyType_GenericNew; + return PyType_Ready(&pysqlite_ConnectionType); +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/connection.h b/contrib/tools/python3/src/Modules/_sqlite/connection.h index 206085e00a0..3875fe2aebf 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/connection.h +++ b/contrib/tools/python3/src/Modules/_sqlite/connection.h @@ -1,127 +1,127 @@ -/* connection.h - definitions for the connection type - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PYSQLITE_CONNECTION_H -#define PYSQLITE_CONNECTION_H +/* connection.h - definitions for the connection type + * + * Copyright (C) 2004-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PYSQLITE_CONNECTION_H +#define PYSQLITE_CONNECTION_H #define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "pythread.h" -#include "structmember.h" - -#include "cache.h" -#include "module.h" - -#include "sqlite3.h" - -typedef struct -{ - PyObject_HEAD - sqlite3* db; - - /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a - * bitwise combination thereof makes sense */ - int detect_types; - - /* the timeout value in seconds for database locks */ - double timeout; - - /* for internal use in the timeout handler: when did the timeout handler - * first get called with count=0? */ - double timeout_started; - - /* None for autocommit, otherwise a PyUnicode with the isolation level */ - PyObject* isolation_level; - - /* NULL for autocommit, otherwise a string with the BEGIN statement */ - const char* begin_statement; - - /* 1 if a check should be performed for each API call if the connection is - * used from the same thread it was created in */ - int check_same_thread; - - int initialized; - - /* thread identification of the thread the connection was created in */ - unsigned long thread_ident; - - pysqlite_Cache* statement_cache; - - /* Lists of weak references to statements and cursors used within this connection */ - PyObject* statements; - PyObject* cursors; - - /* Counters for how many statements/cursors were created in the connection. May be - * reset to 0 at certain intervals */ - int created_statements; - int created_cursors; - - PyObject* row_factory; - - /* Determines how bytestrings from SQLite are converted to Python objects: - * - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings - * - PyBytes_Type: The bytestrings are returned as-is. - * - Any custom callable: Any object returned from the callable called with the bytestring - * as single parameter. - */ - PyObject* text_factory; - +#include "Python.h" +#include "pythread.h" +#include "structmember.h" + +#include "cache.h" +#include "module.h" + +#include "sqlite3.h" + +typedef struct +{ + PyObject_HEAD + sqlite3* db; + + /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a + * bitwise combination thereof makes sense */ + int detect_types; + + /* the timeout value in seconds for database locks */ + double timeout; + + /* for internal use in the timeout handler: when did the timeout handler + * first get called with count=0? */ + double timeout_started; + + /* None for autocommit, otherwise a PyUnicode with the isolation level */ + PyObject* isolation_level; + + /* NULL for autocommit, otherwise a string with the BEGIN statement */ + const char* begin_statement; + + /* 1 if a check should be performed for each API call if the connection is + * used from the same thread it was created in */ + int check_same_thread; + + int initialized; + + /* thread identification of the thread the connection was created in */ + unsigned long thread_ident; + + pysqlite_Cache* statement_cache; + + /* Lists of weak references to statements and cursors used within this connection */ + PyObject* statements; + PyObject* cursors; + + /* Counters for how many statements/cursors were created in the connection. May be + * reset to 0 at certain intervals */ + int created_statements; + int created_cursors; + + PyObject* row_factory; + + /* Determines how bytestrings from SQLite are converted to Python objects: + * - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings + * - PyBytes_Type: The bytestrings are returned as-is. + * - Any custom callable: Any object returned from the callable called with the bytestring + * as single parameter. + */ + PyObject* text_factory; + /* remember references to object used in trace_callback/progress_handler/authorizer_cb */ PyObject* function_pinboard_trace_callback; PyObject* function_pinboard_progress_handler; PyObject* function_pinboard_authorizer_cb; - - /* a dictionary of registered collation name => collation callable mappings */ - PyObject* collations; - - /* Exception objects */ - PyObject* Warning; - PyObject* Error; - PyObject* InterfaceError; - PyObject* DatabaseError; - PyObject* DataError; - PyObject* OperationalError; - PyObject* IntegrityError; - PyObject* InternalError; - PyObject* ProgrammingError; - PyObject* NotSupportedError; -} pysqlite_Connection; - -extern PyTypeObject pysqlite_ConnectionType; - -PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware); -void pysqlite_connection_dealloc(pysqlite_Connection* self); -PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); -PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args); -PyObject* _pysqlite_connection_begin(pysqlite_Connection* self); -PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args); -PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args); -PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw); -int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); - -int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor); -int pysqlite_check_thread(pysqlite_Connection* self); -int pysqlite_check_connection(pysqlite_Connection* con); - -int pysqlite_connection_setup_types(void); - -#endif + + /* a dictionary of registered collation name => collation callable mappings */ + PyObject* collations; + + /* Exception objects */ + PyObject* Warning; + PyObject* Error; + PyObject* InterfaceError; + PyObject* DatabaseError; + PyObject* DataError; + PyObject* OperationalError; + PyObject* IntegrityError; + PyObject* InternalError; + PyObject* ProgrammingError; + PyObject* NotSupportedError; +} pysqlite_Connection; + +extern PyTypeObject pysqlite_ConnectionType; + +PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware); +void pysqlite_connection_dealloc(pysqlite_Connection* self); +PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); +PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args); +PyObject* _pysqlite_connection_begin(pysqlite_Connection* self); +PyObject* pysqlite_connection_commit(pysqlite_Connection* self, PyObject* args); +PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args); +PyObject* pysqlite_connection_new(PyTypeObject* type, PyObject* args, PyObject* kw); +int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject* kwargs); + +int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor); +int pysqlite_check_thread(pysqlite_Connection* self); +int pysqlite_check_connection(pysqlite_Connection* con); + +int pysqlite_connection_setup_types(void); + +#endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/cursor.c b/contrib/tools/python3/src/Modules/_sqlite/cursor.c index dd0ce7e1ea6..1884694373e 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cursor.c +++ b/contrib/tools/python3/src/Modules/_sqlite/cursor.c @@ -1,207 +1,207 @@ -/* cursor.c - the cursor type - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "cursor.h" -#include "module.h" -#include "util.h" - -PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self); - -static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from."; - -static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) -{ - pysqlite_Connection* connection; - - if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection)) - { - return -1; - } - - Py_INCREF(connection); - Py_XSETREF(self->connection, connection); - Py_CLEAR(self->statement); - Py_CLEAR(self->next_row); +/* cursor.c - the cursor type + * + * Copyright (C) 2004-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "cursor.h" +#include "module.h" +#include "util.h" + +PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self); + +static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from."; + +static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) +{ + pysqlite_Connection* connection; + + if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection)) + { + return -1; + } + + Py_INCREF(connection); + Py_XSETREF(self->connection, connection); + Py_CLEAR(self->statement); + Py_CLEAR(self->next_row); Py_CLEAR(self->row_cast_map); - - Py_INCREF(Py_None); - Py_XSETREF(self->description, Py_None); - - Py_INCREF(Py_None); - Py_XSETREF(self->lastrowid, Py_None); - - self->arraysize = 1; - self->closed = 0; - self->reset = 0; - - self->rowcount = -1L; - - Py_INCREF(Py_None); - Py_XSETREF(self->row_factory, Py_None); - - if (!pysqlite_check_thread(self->connection)) { - return -1; - } - - if (!pysqlite_connection_register_cursor(connection, (PyObject*)self)) { - return -1; - } - - self->initialized = 1; - - return 0; -} - -static void pysqlite_cursor_dealloc(pysqlite_Cursor* self) -{ - /* Reset the statement if the user has not closed the cursor */ - if (self->statement) { - pysqlite_statement_reset(self->statement); - Py_DECREF(self->statement); - } - - Py_XDECREF(self->connection); - Py_XDECREF(self->row_cast_map); - Py_XDECREF(self->description); - Py_XDECREF(self->lastrowid); - Py_XDECREF(self->row_factory); - Py_XDECREF(self->next_row); - - if (self->in_weakreflist != NULL) { - PyObject_ClearWeakRefs((PyObject*)self); - } - - Py_TYPE(self)->tp_free((PyObject*)self); -} - + + Py_INCREF(Py_None); + Py_XSETREF(self->description, Py_None); + + Py_INCREF(Py_None); + Py_XSETREF(self->lastrowid, Py_None); + + self->arraysize = 1; + self->closed = 0; + self->reset = 0; + + self->rowcount = -1L; + + Py_INCREF(Py_None); + Py_XSETREF(self->row_factory, Py_None); + + if (!pysqlite_check_thread(self->connection)) { + return -1; + } + + if (!pysqlite_connection_register_cursor(connection, (PyObject*)self)) { + return -1; + } + + self->initialized = 1; + + return 0; +} + +static void pysqlite_cursor_dealloc(pysqlite_Cursor* self) +{ + /* Reset the statement if the user has not closed the cursor */ + if (self->statement) { + pysqlite_statement_reset(self->statement); + Py_DECREF(self->statement); + } + + Py_XDECREF(self->connection); + Py_XDECREF(self->row_cast_map); + Py_XDECREF(self->description); + Py_XDECREF(self->lastrowid); + Py_XDECREF(self->row_factory); + Py_XDECREF(self->next_row); + + if (self->in_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*)self); + } + + Py_TYPE(self)->tp_free((PyObject*)self); +} + static PyObject * _pysqlite_get_converter(const char *keystr, Py_ssize_t keylen) -{ +{ PyObject *key; PyObject *upcase_key; PyObject *retval; - _Py_IDENTIFIER(upper); - + _Py_IDENTIFIER(upper); + key = PyUnicode_FromStringAndSize(keystr, keylen); if (!key) { return NULL; } upcase_key = _PyObject_CallMethodIdNoArgs(key, &PyId_upper); Py_DECREF(key); - if (!upcase_key) { - return NULL; - } - + if (!upcase_key) { + return NULL; + } + retval = PyDict_GetItemWithError(_pysqlite_converters, upcase_key); - Py_DECREF(upcase_key); - - return retval; -} - + Py_DECREF(upcase_key); + + return retval; +} + static int pysqlite_build_row_cast_map(pysqlite_Cursor* self) -{ - int i; - const char* pos; - const char* colname; - const char* decltype; - PyObject* converter; - - if (!self->connection->detect_types) { - return 0; - } - - Py_XSETREF(self->row_cast_map, PyList_New(0)); +{ + int i; + const char* pos; + const char* colname; + const char* decltype; + PyObject* converter; + + if (!self->connection->detect_types) { + return 0; + } + + Py_XSETREF(self->row_cast_map, PyList_New(0)); if (!self->row_cast_map) { return -1; } - - for (i = 0; i < sqlite3_column_count(self->statement->st); i++) { - converter = NULL; - - if (self->connection->detect_types & PARSE_COLNAMES) { - colname = sqlite3_column_name(self->statement->st, i); - if (colname) { + + for (i = 0; i < sqlite3_column_count(self->statement->st); i++) { + converter = NULL; + + if (self->connection->detect_types & PARSE_COLNAMES) { + colname = sqlite3_column_name(self->statement->st, i); + if (colname) { const char *type_start = NULL; - for (pos = colname; *pos != 0; pos++) { - if (*pos == '[') { - type_start = pos + 1; + for (pos = colname; *pos != 0; pos++) { + if (*pos == '[') { + type_start = pos + 1; } else if (*pos == ']' && type_start != NULL) { converter = _pysqlite_get_converter(type_start, pos - type_start); if (!converter && PyErr_Occurred()) { Py_CLEAR(self->row_cast_map); return -1; - } - break; - } - } - } - } - - if (!converter && self->connection->detect_types & PARSE_DECLTYPES) { - decltype = sqlite3_column_decltype(self->statement->st, i); - if (decltype) { - for (pos = decltype;;pos++) { - /* Converter names are split at '(' and blanks. - * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and - * 'NUMBER(10)' to be treated as 'NUMBER', for example. - * In other words, it will work as people expect it to work.*/ - if (*pos == ' ' || *pos == '(' || *pos == 0) { + } + break; + } + } + } + } + + if (!converter && self->connection->detect_types & PARSE_DECLTYPES) { + decltype = sqlite3_column_decltype(self->statement->st, i); + if (decltype) { + for (pos = decltype;;pos++) { + /* Converter names are split at '(' and blanks. + * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and + * 'NUMBER(10)' to be treated as 'NUMBER', for example. + * In other words, it will work as people expect it to work.*/ + if (*pos == ' ' || *pos == '(' || *pos == 0) { converter = _pysqlite_get_converter(decltype, pos - decltype); if (!converter && PyErr_Occurred()) { Py_CLEAR(self->row_cast_map); - return -1; - } - break; - } - } - } - } - - if (!converter) { - converter = Py_None; - } - - if (PyList_Append(self->row_cast_map, converter) != 0) { - Py_CLEAR(self->row_cast_map); - return -1; - } - } - - return 0; -} - + return -1; + } + break; + } + } + } + } + + if (!converter) { + converter = Py_None; + } + + if (PyList_Append(self->row_cast_map, converter) != 0) { + Py_CLEAR(self->row_cast_map); + return -1; + } + } + + return 0; +} + static PyObject * _pysqlite_build_column_name(pysqlite_Cursor *self, const char *colname) -{ - const char* pos; +{ + const char* pos; Py_ssize_t len; - - if (!colname) { - Py_RETURN_NONE; - } - + + if (!colname) { + Py_RETURN_NONE; + } + if (self->connection->detect_types & PARSE_COLNAMES) { for (pos = colname; *pos; pos++) { if (*pos == '[') { @@ -209,51 +209,51 @@ _pysqlite_build_column_name(pysqlite_Cursor *self, const char *colname) pos--; } break; - } - } + } + } len = pos - colname; - } + } else { len = strlen(colname); } return PyUnicode_FromStringAndSize(colname, len); -} - -/* - * Returns a row from the currently active SQLite statement - * - * Precondidition: - * - sqlite3_step() has been called before and it returned SQLITE_ROW. - */ +} + +/* + * Returns a row from the currently active SQLite statement + * + * Precondidition: + * - sqlite3_step() has been called before and it returned SQLITE_ROW. + */ static PyObject * _pysqlite_fetch_one_row(pysqlite_Cursor* self) -{ - int i, numcols; - PyObject* row; - PyObject* item = NULL; - int coltype; - PyObject* converter; - PyObject* converted; - Py_ssize_t nbytes; - const char* val_str; - char buf[200]; - const char* colname; +{ + int i, numcols; + PyObject* row; + PyObject* item = NULL; + int coltype; + PyObject* converter; + PyObject* converted; + Py_ssize_t nbytes; + const char* val_str; + char buf[200]; + const char* colname; PyObject* error_msg; - - if (self->reset) { - PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - numcols = sqlite3_data_count(self->statement->st); - Py_END_ALLOW_THREADS - - row = PyTuple_New(numcols); - if (!row) - return NULL; - - for (i = 0; i < numcols; i++) { + + if (self->reset) { + PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + numcols = sqlite3_data_count(self->statement->st); + Py_END_ALLOW_THREADS + + row = PyTuple_New(numcols); + if (!row) + return NULL; + + for (i = 0; i < numcols; i++) { if (self->connection->detect_types && self->row_cast_map != NULL && i < PyList_GET_SIZE(self->row_cast_map)) @@ -261,290 +261,290 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) converter = PyList_GET_ITEM(self->row_cast_map, i); } else { - converter = Py_None; - } - - if (converter != Py_None) { - nbytes = sqlite3_column_bytes(self->statement->st, i); - val_str = (const char*)sqlite3_column_blob(self->statement->st, i); - if (!val_str) { - Py_INCREF(Py_None); - converted = Py_None; - } else { - item = PyBytes_FromStringAndSize(val_str, nbytes); - if (!item) - goto error; + converter = Py_None; + } + + if (converter != Py_None) { + nbytes = sqlite3_column_bytes(self->statement->st, i); + val_str = (const char*)sqlite3_column_blob(self->statement->st, i); + if (!val_str) { + Py_INCREF(Py_None); + converted = Py_None; + } else { + item = PyBytes_FromStringAndSize(val_str, nbytes); + if (!item) + goto error; converted = PyObject_CallOneArg(converter, item); - Py_DECREF(item); - } - } else { - Py_BEGIN_ALLOW_THREADS - coltype = sqlite3_column_type(self->statement->st, i); - Py_END_ALLOW_THREADS - if (coltype == SQLITE_NULL) { - Py_INCREF(Py_None); - converted = Py_None; - } else if (coltype == SQLITE_INTEGER) { + Py_DECREF(item); + } + } else { + Py_BEGIN_ALLOW_THREADS + coltype = sqlite3_column_type(self->statement->st, i); + Py_END_ALLOW_THREADS + if (coltype == SQLITE_NULL) { + Py_INCREF(Py_None); + converted = Py_None; + } else if (coltype == SQLITE_INTEGER) { converted = PyLong_FromLongLong(sqlite3_column_int64(self->statement->st, i)); - } else if (coltype == SQLITE_FLOAT) { - converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i)); - } else if (coltype == SQLITE_TEXT) { - val_str = (const char*)sqlite3_column_text(self->statement->st, i); - nbytes = sqlite3_column_bytes(self->statement->st, i); - if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) { - converted = PyUnicode_FromStringAndSize(val_str, nbytes); + } else if (coltype == SQLITE_FLOAT) { + converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i)); + } else if (coltype == SQLITE_TEXT) { + val_str = (const char*)sqlite3_column_text(self->statement->st, i); + nbytes = sqlite3_column_bytes(self->statement->st, i); + if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) { + converted = PyUnicode_FromStringAndSize(val_str, nbytes); if (!converted && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { - PyErr_Clear(); - colname = sqlite3_column_name(self->statement->st, i); - if (!colname) { - colname = ""; - } - PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'", - colname , val_str); + PyErr_Clear(); + colname = sqlite3_column_name(self->statement->st, i); + if (!colname) { + colname = ""; + } + PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'", + colname , val_str); error_msg = PyUnicode_Decode(buf, strlen(buf), "ascii", "replace"); if (!error_msg) { - PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8"); - } else { + PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8"); + } else { PyErr_SetObject(pysqlite_OperationalError, error_msg); Py_DECREF(error_msg); - } - } - } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) { - converted = PyBytes_FromStringAndSize(val_str, nbytes); - } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) { - converted = PyByteArray_FromStringAndSize(val_str, nbytes); - } else { - converted = PyObject_CallFunction(self->connection->text_factory, "y#", val_str, nbytes); - } - } else { - /* coltype == SQLITE_BLOB */ - nbytes = sqlite3_column_bytes(self->statement->st, i); + } + } + } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) { + converted = PyBytes_FromStringAndSize(val_str, nbytes); + } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) { + converted = PyByteArray_FromStringAndSize(val_str, nbytes); + } else { + converted = PyObject_CallFunction(self->connection->text_factory, "y#", val_str, nbytes); + } + } else { + /* coltype == SQLITE_BLOB */ + nbytes = sqlite3_column_bytes(self->statement->st, i); converted = PyBytes_FromStringAndSize( - sqlite3_column_blob(self->statement->st, i), nbytes); - } - } - + sqlite3_column_blob(self->statement->st, i), nbytes); + } + } + if (!converted) { goto error; - } + } PyTuple_SetItem(row, i, converted); - } - - if (PyErr_Occurred()) - goto error; - - return row; - -error: - Py_DECREF(row); - return NULL; -} - -/* - * Checks if a cursor object is usable. - * - * 0 => error; 1 => ok - */ -static int check_cursor(pysqlite_Cursor* cur) -{ - if (!cur->initialized) { - PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called."); - return 0; - } - - if (cur->closed) { - PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed cursor."); - return 0; - } - - if (cur->locked) { - PyErr_SetString(pysqlite_ProgrammingError, "Recursive use of cursors not allowed."); - return 0; - } - - return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection); -} - + } + + if (PyErr_Occurred()) + goto error; + + return row; + +error: + Py_DECREF(row); + return NULL; +} + +/* + * Checks if a cursor object is usable. + * + * 0 => error; 1 => ok + */ +static int check_cursor(pysqlite_Cursor* cur) +{ + if (!cur->initialized) { + PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called."); + return 0; + } + + if (cur->closed) { + PyErr_SetString(pysqlite_ProgrammingError, "Cannot operate on a closed cursor."); + return 0; + } + + if (cur->locked) { + PyErr_SetString(pysqlite_ProgrammingError, "Recursive use of cursors not allowed."); + return 0; + } + + return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection); +} + static PyObject * _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) -{ - PyObject* operation; - PyObject* parameters_list = NULL; - PyObject* parameters_iter = NULL; - PyObject* parameters = NULL; - int i; - int rc; - PyObject* func_args; - PyObject* result; - int numcols; - PyObject* descriptor; +{ + PyObject* operation; + PyObject* parameters_list = NULL; + PyObject* parameters_iter = NULL; + PyObject* parameters = NULL; + int i; + int rc; + PyObject* func_args; + PyObject* result; + int numcols; + PyObject* descriptor; PyObject* column_name; - PyObject* second_argument = NULL; - sqlite_int64 lastrowid; - - if (!check_cursor(self)) { - goto error; - } - - self->locked = 1; - self->reset = 0; - - Py_CLEAR(self->next_row); - - if (multiple) { - /* executemany() */ + PyObject* second_argument = NULL; + sqlite_int64 lastrowid; + + if (!check_cursor(self)) { + goto error; + } + + self->locked = 1; + self->reset = 0; + + Py_CLEAR(self->next_row); + + if (multiple) { + /* executemany() */ if (!PyArg_ParseTuple(args, "UO", &operation, &second_argument)) { - goto error; - } - - if (PyIter_Check(second_argument)) { - /* iterator */ - Py_INCREF(second_argument); - parameters_iter = second_argument; - } else { - /* sequence */ - parameters_iter = PyObject_GetIter(second_argument); - if (!parameters_iter) { - goto error; - } - } - } else { - /* execute() */ + goto error; + } + + if (PyIter_Check(second_argument)) { + /* iterator */ + Py_INCREF(second_argument); + parameters_iter = second_argument; + } else { + /* sequence */ + parameters_iter = PyObject_GetIter(second_argument); + if (!parameters_iter) { + goto error; + } + } + } else { + /* execute() */ if (!PyArg_ParseTuple(args, "U|O", &operation, &second_argument)) { - goto error; - } - - parameters_list = PyList_New(0); - if (!parameters_list) { - goto error; - } - - if (second_argument == NULL) { - second_argument = PyTuple_New(0); - if (!second_argument) { - goto error; - } - } else { - Py_INCREF(second_argument); - } - if (PyList_Append(parameters_list, second_argument) != 0) { - Py_DECREF(second_argument); - goto error; - } - Py_DECREF(second_argument); - - parameters_iter = PyObject_GetIter(parameters_list); - if (!parameters_iter) { - goto error; - } - } - - if (self->statement != NULL) { - /* There is an active statement */ - pysqlite_statement_reset(self->statement); - } - - /* reset description and rowcount */ - Py_INCREF(Py_None); - Py_SETREF(self->description, Py_None); - self->rowcount = 0L; - - func_args = PyTuple_New(1); - if (!func_args) { - goto error; - } - Py_INCREF(operation); - if (PyTuple_SetItem(func_args, 0, operation) != 0) { - goto error; - } - - if (self->statement) { - (void)pysqlite_statement_reset(self->statement); - } - - Py_XSETREF(self->statement, - (pysqlite_Statement *)pysqlite_cache_get(self->connection->statement_cache, func_args)); - Py_DECREF(func_args); - - if (!self->statement) { - goto error; - } - - if (self->statement->in_use) { - Py_SETREF(self->statement, - PyObject_New(pysqlite_Statement, &pysqlite_StatementType)); - if (!self->statement) { - goto error; - } - rc = pysqlite_statement_create(self->statement, self->connection, operation); - if (rc != SQLITE_OK) { - Py_CLEAR(self->statement); - goto error; - } - } - - pysqlite_statement_reset(self->statement); - pysqlite_statement_mark_dirty(self->statement); - - /* We start a transaction implicitly before a DML statement. - SELECT is the only exception. See #9924. */ - if (self->connection->begin_statement && self->statement->is_dml) { - if (sqlite3_get_autocommit(self->connection->db)) { - result = _pysqlite_connection_begin(self->connection); - if (!result) { - goto error; - } - Py_DECREF(result); - } - } - - while (1) { - parameters = PyIter_Next(parameters_iter); - if (!parameters) { - break; - } - - pysqlite_statement_mark_dirty(self->statement); - - pysqlite_statement_bind_parameters(self->statement, parameters); - if (PyErr_Occurred()) { - goto error; - } - - rc = pysqlite_step(self->statement->st, self->connection); - if (rc != SQLITE_DONE && rc != SQLITE_ROW) { - if (PyErr_Occurred()) { - /* there was an error that occurred in a user-defined callback */ - if (_pysqlite_enable_callback_tracebacks) { - PyErr_Print(); - } else { - PyErr_Clear(); - } - } - (void)pysqlite_statement_reset(self->statement); - _pysqlite_seterror(self->connection->db, NULL); - goto error; - } - - if (pysqlite_build_row_cast_map(self) != 0) { + goto error; + } + + parameters_list = PyList_New(0); + if (!parameters_list) { + goto error; + } + + if (second_argument == NULL) { + second_argument = PyTuple_New(0); + if (!second_argument) { + goto error; + } + } else { + Py_INCREF(second_argument); + } + if (PyList_Append(parameters_list, second_argument) != 0) { + Py_DECREF(second_argument); + goto error; + } + Py_DECREF(second_argument); + + parameters_iter = PyObject_GetIter(parameters_list); + if (!parameters_iter) { + goto error; + } + } + + if (self->statement != NULL) { + /* There is an active statement */ + pysqlite_statement_reset(self->statement); + } + + /* reset description and rowcount */ + Py_INCREF(Py_None); + Py_SETREF(self->description, Py_None); + self->rowcount = 0L; + + func_args = PyTuple_New(1); + if (!func_args) { + goto error; + } + Py_INCREF(operation); + if (PyTuple_SetItem(func_args, 0, operation) != 0) { + goto error; + } + + if (self->statement) { + (void)pysqlite_statement_reset(self->statement); + } + + Py_XSETREF(self->statement, + (pysqlite_Statement *)pysqlite_cache_get(self->connection->statement_cache, func_args)); + Py_DECREF(func_args); + + if (!self->statement) { + goto error; + } + + if (self->statement->in_use) { + Py_SETREF(self->statement, + PyObject_New(pysqlite_Statement, &pysqlite_StatementType)); + if (!self->statement) { + goto error; + } + rc = pysqlite_statement_create(self->statement, self->connection, operation); + if (rc != SQLITE_OK) { + Py_CLEAR(self->statement); + goto error; + } + } + + pysqlite_statement_reset(self->statement); + pysqlite_statement_mark_dirty(self->statement); + + /* We start a transaction implicitly before a DML statement. + SELECT is the only exception. See #9924. */ + if (self->connection->begin_statement && self->statement->is_dml) { + if (sqlite3_get_autocommit(self->connection->db)) { + result = _pysqlite_connection_begin(self->connection); + if (!result) { + goto error; + } + Py_DECREF(result); + } + } + + while (1) { + parameters = PyIter_Next(parameters_iter); + if (!parameters) { + break; + } + + pysqlite_statement_mark_dirty(self->statement); + + pysqlite_statement_bind_parameters(self->statement, parameters); + if (PyErr_Occurred()) { + goto error; + } + + rc = pysqlite_step(self->statement->st, self->connection); + if (rc != SQLITE_DONE && rc != SQLITE_ROW) { + if (PyErr_Occurred()) { + /* there was an error that occurred in a user-defined callback */ + if (_pysqlite_enable_callback_tracebacks) { + PyErr_Print(); + } else { + PyErr_Clear(); + } + } + (void)pysqlite_statement_reset(self->statement); + _pysqlite_seterror(self->connection->db, NULL); + goto error; + } + + if (pysqlite_build_row_cast_map(self) != 0) { _PyErr_FormatFromCause(pysqlite_OperationalError, "Error while building row_cast_map"); - goto error; - } - - assert(rc == SQLITE_ROW || rc == SQLITE_DONE); - Py_BEGIN_ALLOW_THREADS - numcols = sqlite3_column_count(self->statement->st); - Py_END_ALLOW_THREADS - if (self->description == Py_None && numcols > 0) { - Py_SETREF(self->description, PyTuple_New(numcols)); - if (!self->description) { - goto error; - } - for (i = 0; i < numcols; i++) { - descriptor = PyTuple_New(7); - if (!descriptor) { - goto error; - } + goto error; + } + + assert(rc == SQLITE_ROW || rc == SQLITE_DONE); + Py_BEGIN_ALLOW_THREADS + numcols = sqlite3_column_count(self->statement->st); + Py_END_ALLOW_THREADS + if (self->description == Py_None && numcols > 0) { + Py_SETREF(self->description, PyTuple_New(numcols)); + if (!self->description) { + goto error; + } + for (i = 0; i < numcols; i++) { + descriptor = PyTuple_New(7); + if (!descriptor) { + goto error; + } column_name = _pysqlite_build_column_name(self, sqlite3_column_name(self->statement->st, i)); if (!column_name) { @@ -552,410 +552,410 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) goto error; } PyTuple_SetItem(descriptor, 0, column_name); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None); - PyTuple_SetItem(self->description, i, descriptor); - } - } - - if (self->statement->is_dml) { - self->rowcount += (long)sqlite3_changes(self->connection->db); - } else { - self->rowcount= -1L; - } - - if (!multiple) { - Py_BEGIN_ALLOW_THREADS - lastrowid = sqlite3_last_insert_rowid(self->connection->db); - Py_END_ALLOW_THREADS + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None); + Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None); + PyTuple_SetItem(self->description, i, descriptor); + } + } + + if (self->statement->is_dml) { + self->rowcount += (long)sqlite3_changes(self->connection->db); + } else { + self->rowcount= -1L; + } + + if (!multiple) { + Py_BEGIN_ALLOW_THREADS + lastrowid = sqlite3_last_insert_rowid(self->connection->db); + Py_END_ALLOW_THREADS Py_SETREF(self->lastrowid, PyLong_FromLongLong(lastrowid)); if (self->lastrowid == NULL) { goto error; } - } - - if (rc == SQLITE_ROW) { - if (multiple) { - PyErr_SetString(pysqlite_ProgrammingError, "executemany() can only execute DML statements."); - goto error; - } - - self->next_row = _pysqlite_fetch_one_row(self); - if (self->next_row == NULL) - goto error; - } else if (rc == SQLITE_DONE && !multiple) { - pysqlite_statement_reset(self->statement); - Py_CLEAR(self->statement); - } - - if (multiple) { - pysqlite_statement_reset(self->statement); - } - Py_XDECREF(parameters); - } - -error: - Py_XDECREF(parameters); - Py_XDECREF(parameters_iter); - Py_XDECREF(parameters_list); - - self->locked = 0; - - if (PyErr_Occurred()) { - self->rowcount = -1L; - return NULL; - } else { - Py_INCREF(self); - return (PyObject*)self; - } -} - -PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args) -{ - return _pysqlite_query_execute(self, 0, args); -} - -PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args) -{ - return _pysqlite_query_execute(self, 1, args); -} - + } + + if (rc == SQLITE_ROW) { + if (multiple) { + PyErr_SetString(pysqlite_ProgrammingError, "executemany() can only execute DML statements."); + goto error; + } + + self->next_row = _pysqlite_fetch_one_row(self); + if (self->next_row == NULL) + goto error; + } else if (rc == SQLITE_DONE && !multiple) { + pysqlite_statement_reset(self->statement); + Py_CLEAR(self->statement); + } + + if (multiple) { + pysqlite_statement_reset(self->statement); + } + Py_XDECREF(parameters); + } + +error: + Py_XDECREF(parameters); + Py_XDECREF(parameters_iter); + Py_XDECREF(parameters_list); + + self->locked = 0; + + if (PyErr_Occurred()) { + self->rowcount = -1L; + return NULL; + } else { + Py_INCREF(self); + return (PyObject*)self; + } +} + +PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args) +{ + return _pysqlite_query_execute(self, 0, args); +} + +PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args) +{ + return _pysqlite_query_execute(self, 1, args); +} + static PyObject * pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) -{ - PyObject* script_obj; - const char* script_cstr; - sqlite3_stmt* statement; - int rc; - PyObject* result; - - if (!PyArg_ParseTuple(args, "O", &script_obj)) { - return NULL; - } - - if (!check_cursor(self)) { - return NULL; - } - - self->reset = 0; - - if (PyUnicode_Check(script_obj)) { - script_cstr = PyUnicode_AsUTF8(script_obj); - if (!script_cstr) { - return NULL; - } - } else { - PyErr_SetString(PyExc_ValueError, "script argument must be unicode."); - return NULL; - } - - /* commit first */ - result = pysqlite_connection_commit(self->connection, NULL); - if (!result) { - goto error; - } - Py_DECREF(result); - - while (1) { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(self->connection->db, - script_cstr, - -1, - &statement, - &script_cstr); - Py_END_ALLOW_THREADS - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->connection->db, NULL); - goto error; - } - - /* execute statement, and ignore results of SELECT statements */ - rc = SQLITE_ROW; - while (rc == SQLITE_ROW) { - rc = pysqlite_step(statement, self->connection); - if (PyErr_Occurred()) { - (void)sqlite3_finalize(statement); - goto error; - } - } - - if (rc != SQLITE_DONE) { - (void)sqlite3_finalize(statement); - _pysqlite_seterror(self->connection->db, NULL); - goto error; - } - - rc = sqlite3_finalize(statement); - if (rc != SQLITE_OK) { - _pysqlite_seterror(self->connection->db, NULL); - goto error; - } - - if (*script_cstr == (char)0) { - break; - } - } - -error: - if (PyErr_Occurred()) { - return NULL; - } else { - Py_INCREF(self); - return (PyObject*)self; - } -} - -PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) -{ - PyObject* next_row_tuple; - PyObject* next_row; - int rc; - - if (!check_cursor(self)) { - return NULL; - } - - if (self->reset) { - PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback); - return NULL; - } - - if (!self->next_row) { - if (self->statement) { - (void)pysqlite_statement_reset(self->statement); - Py_CLEAR(self->statement); - } - return NULL; - } - - next_row_tuple = self->next_row; - assert(next_row_tuple != NULL); - self->next_row = NULL; - - if (self->row_factory != Py_None) { - next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple); - if (next_row == NULL) { - self->next_row = next_row_tuple; - return NULL; - } - Py_DECREF(next_row_tuple); - } else { - next_row = next_row_tuple; - } - - if (self->statement) { - rc = pysqlite_step(self->statement->st, self->connection); - if (PyErr_Occurred()) { - (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - return NULL; - } - if (rc != SQLITE_DONE && rc != SQLITE_ROW) { - (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - _pysqlite_seterror(self->connection->db, NULL); - return NULL; - } - - if (rc == SQLITE_ROW) { - self->next_row = _pysqlite_fetch_one_row(self); - if (self->next_row == NULL) { - (void)pysqlite_statement_reset(self->statement); - return NULL; - } - } - } - - return next_row; -} - -PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) -{ - PyObject* row; - - row = pysqlite_cursor_iternext(self); - if (!row && !PyErr_Occurred()) { - Py_RETURN_NONE; - } - - return row; -} - -PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) -{ +{ + PyObject* script_obj; + const char* script_cstr; + sqlite3_stmt* statement; + int rc; + PyObject* result; + + if (!PyArg_ParseTuple(args, "O", &script_obj)) { + return NULL; + } + + if (!check_cursor(self)) { + return NULL; + } + + self->reset = 0; + + if (PyUnicode_Check(script_obj)) { + script_cstr = PyUnicode_AsUTF8(script_obj); + if (!script_cstr) { + return NULL; + } + } else { + PyErr_SetString(PyExc_ValueError, "script argument must be unicode."); + return NULL; + } + + /* commit first */ + result = pysqlite_connection_commit(self->connection, NULL); + if (!result) { + goto error; + } + Py_DECREF(result); + + while (1) { + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_prepare_v2(self->connection->db, + script_cstr, + -1, + &statement, + &script_cstr); + Py_END_ALLOW_THREADS + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->connection->db, NULL); + goto error; + } + + /* execute statement, and ignore results of SELECT statements */ + rc = SQLITE_ROW; + while (rc == SQLITE_ROW) { + rc = pysqlite_step(statement, self->connection); + if (PyErr_Occurred()) { + (void)sqlite3_finalize(statement); + goto error; + } + } + + if (rc != SQLITE_DONE) { + (void)sqlite3_finalize(statement); + _pysqlite_seterror(self->connection->db, NULL); + goto error; + } + + rc = sqlite3_finalize(statement); + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->connection->db, NULL); + goto error; + } + + if (*script_cstr == (char)0) { + break; + } + } + +error: + if (PyErr_Occurred()) { + return NULL; + } else { + Py_INCREF(self); + return (PyObject*)self; + } +} + +PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) +{ + PyObject* next_row_tuple; + PyObject* next_row; + int rc; + + if (!check_cursor(self)) { + return NULL; + } + + if (self->reset) { + PyErr_SetString(pysqlite_InterfaceError, errmsg_fetch_across_rollback); + return NULL; + } + + if (!self->next_row) { + if (self->statement) { + (void)pysqlite_statement_reset(self->statement); + Py_CLEAR(self->statement); + } + return NULL; + } + + next_row_tuple = self->next_row; + assert(next_row_tuple != NULL); + self->next_row = NULL; + + if (self->row_factory != Py_None) { + next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple); + if (next_row == NULL) { + self->next_row = next_row_tuple; + return NULL; + } + Py_DECREF(next_row_tuple); + } else { + next_row = next_row_tuple; + } + + if (self->statement) { + rc = pysqlite_step(self->statement->st, self->connection); + if (PyErr_Occurred()) { + (void)pysqlite_statement_reset(self->statement); + Py_DECREF(next_row); + return NULL; + } + if (rc != SQLITE_DONE && rc != SQLITE_ROW) { + (void)pysqlite_statement_reset(self->statement); + Py_DECREF(next_row); + _pysqlite_seterror(self->connection->db, NULL); + return NULL; + } + + if (rc == SQLITE_ROW) { + self->next_row = _pysqlite_fetch_one_row(self); + if (self->next_row == NULL) { + (void)pysqlite_statement_reset(self->statement); + return NULL; + } + } + } + + return next_row; +} + +PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) +{ + PyObject* row; + + row = pysqlite_cursor_iternext(self); + if (!row && !PyErr_Occurred()) { + Py_RETURN_NONE; + } + + return row; +} + +PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) +{ static char *kwlist[] = {"size", NULL}; - - PyObject* row; - PyObject* list; - int maxrows = self->arraysize; - int counter = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:fetchmany", kwlist, &maxrows)) { - return NULL; - } - - list = PyList_New(0); - if (!list) { - return NULL; - } - + + PyObject* row; + PyObject* list; + int maxrows = self->arraysize; + int counter = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:fetchmany", kwlist, &maxrows)) { + return NULL; + } + + list = PyList_New(0); + if (!list) { + return NULL; + } + while ((row = pysqlite_cursor_iternext(self))) { if (PyList_Append(list, row) < 0) { Py_DECREF(row); break; } Py_DECREF(row); - - if (++counter == maxrows) { - break; - } - } - - if (PyErr_Occurred()) { - Py_DECREF(list); - return NULL; - } else { - return list; - } -} - -PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) -{ - PyObject* row; - PyObject* list; - - list = PyList_New(0); - if (!list) { - return NULL; - } - + + if (++counter == maxrows) { + break; + } + } + + if (PyErr_Occurred()) { + Py_DECREF(list); + return NULL; + } else { + return list; + } +} + +PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args) +{ + PyObject* row; + PyObject* list; + + list = PyList_New(0); + if (!list) { + return NULL; + } + while ((row = pysqlite_cursor_iternext(self))) { if (PyList_Append(list, row) < 0) { Py_DECREF(row); break; } Py_DECREF(row); - } - - if (PyErr_Occurred()) { - Py_DECREF(list); - return NULL; - } else { - return list; - } -} - -PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args) -{ - /* don't care, return None */ - Py_RETURN_NONE; -} - -PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) -{ - if (!self->connection) { - PyErr_SetString(pysqlite_ProgrammingError, - "Base Cursor.__init__ not called."); - return NULL; - } - if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) { - return NULL; - } - - if (self->statement) { - (void)pysqlite_statement_reset(self->statement); - Py_CLEAR(self->statement); - } - - self->closed = 1; - - Py_RETURN_NONE; -} - -static PyMethodDef cursor_methods[] = { - {"execute", (PyCFunction)pysqlite_cursor_execute, METH_VARARGS, - PyDoc_STR("Executes a SQL statement.")}, - {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS, - PyDoc_STR("Repeatedly executes a SQL statement.")}, - {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, - PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, - {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, - PyDoc_STR("Fetches one row from the resultset.")}, + } + + if (PyErr_Occurred()) { + Py_DECREF(list); + return NULL; + } else { + return list; + } +} + +PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args) +{ + /* don't care, return None */ + Py_RETURN_NONE; +} + +PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) +{ + if (!self->connection) { + PyErr_SetString(pysqlite_ProgrammingError, + "Base Cursor.__init__ not called."); + return NULL; + } + if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) { + return NULL; + } + + if (self->statement) { + (void)pysqlite_statement_reset(self->statement); + Py_CLEAR(self->statement); + } + + self->closed = 1; + + Py_RETURN_NONE; +} + +static PyMethodDef cursor_methods[] = { + {"execute", (PyCFunction)pysqlite_cursor_execute, METH_VARARGS, + PyDoc_STR("Executes a SQL statement.")}, + {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS, + PyDoc_STR("Repeatedly executes a SQL statement.")}, + {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, + PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, + {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, + PyDoc_STR("Fetches one row from the resultset.")}, {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Fetches several rows from the resultset.")}, - {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, - PyDoc_STR("Fetches all rows from the resultset.")}, - {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, - PyDoc_STR("Closes the cursor.")}, - {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS, - PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, - {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS, - PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, - {NULL, NULL} -}; - -static struct PyMemberDef cursor_members[] = -{ - {"connection", T_OBJECT, offsetof(pysqlite_Cursor, connection), READONLY}, - {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), READONLY}, - {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0}, - {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY}, - {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY}, - {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, - {NULL} -}; - -static const char cursor_doc[] = -PyDoc_STR("SQLite database cursor class."); - -PyTypeObject pysqlite_CursorType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cursor", /* tp_name */ - sizeof(pysqlite_Cursor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cursor_dealloc, /* tp_dealloc */ + PyDoc_STR("Fetches several rows from the resultset.")}, + {"fetchall", (PyCFunction)pysqlite_cursor_fetchall, METH_NOARGS, + PyDoc_STR("Fetches all rows from the resultset.")}, + {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, + PyDoc_STR("Closes the cursor.")}, + {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS, + PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, + {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS, + PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, + {NULL, NULL} +}; + +static struct PyMemberDef cursor_members[] = +{ + {"connection", T_OBJECT, offsetof(pysqlite_Cursor, connection), READONLY}, + {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), READONLY}, + {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0}, + {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY}, + {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY}, + {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, + {NULL} +}; + +static const char cursor_doc[] = +PyDoc_STR("SQLite database cursor class."); + +PyTypeObject pysqlite_CursorType = { + PyVarObject_HEAD_INIT(NULL, 0) + MODULE_NAME ".Cursor", /* tp_name */ + sizeof(pysqlite_Cursor), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pysqlite_cursor_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - cursor_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ + cursor_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ - (iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */ - cursor_methods, /* tp_methods */ - cursor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_cursor_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ -}; - -extern int pysqlite_cursor_setup_types(void) -{ - pysqlite_CursorType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_CursorType); -} + (iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */ + cursor_methods, /* tp_methods */ + cursor_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pysqlite_cursor_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0 /* tp_free */ +}; + +extern int pysqlite_cursor_setup_types(void) +{ + pysqlite_CursorType.tp_new = PyType_GenericNew; + return PyType_Ready(&pysqlite_CursorType); +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/cursor.h b/contrib/tools/python3/src/Modules/_sqlite/cursor.h index 4a20e756f78..6e0fe913960 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/cursor.h +++ b/contrib/tools/python3/src/Modules/_sqlite/cursor.h @@ -1,70 +1,70 @@ -/* cursor.h - definitions for the cursor type - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PYSQLITE_CURSOR_H -#define PYSQLITE_CURSOR_H +/* cursor.h - definitions for the cursor type + * + * Copyright (C) 2004-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PYSQLITE_CURSOR_H +#define PYSQLITE_CURSOR_H #define PY_SSIZE_T_CLEAN -#include "Python.h" - -#include "statement.h" -#include "connection.h" -#include "module.h" - -typedef struct -{ - PyObject_HEAD - pysqlite_Connection* connection; - PyObject* description; - PyObject* row_cast_map; - int arraysize; - PyObject* lastrowid; - long rowcount; - PyObject* row_factory; - pysqlite_Statement* statement; - int closed; - int reset; - int locked; - int initialized; - - /* the next row to be returned, NULL if no next row available */ - PyObject* next_row; - - PyObject* in_weakreflist; /* List of weak references */ -} pysqlite_Cursor; - -extern PyTypeObject pysqlite_CursorType; - -PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self); -PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self); -PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs); -PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args); -PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args); -PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args); - -int pysqlite_cursor_setup_types(void); - -#define UNKNOWN (-1) -#endif +#include "Python.h" + +#include "statement.h" +#include "connection.h" +#include "module.h" + +typedef struct +{ + PyObject_HEAD + pysqlite_Connection* connection; + PyObject* description; + PyObject* row_cast_map; + int arraysize; + PyObject* lastrowid; + long rowcount; + PyObject* row_factory; + pysqlite_Statement* statement; + int closed; + int reset; + int locked; + int initialized; + + /* the next row to be returned, NULL if no next row available */ + PyObject* next_row; + + PyObject* in_weakreflist; /* List of weak references */ +} pysqlite_Cursor; + +extern PyTypeObject pysqlite_CursorType; + +PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args); +PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args); +PyObject* pysqlite_cursor_getiter(pysqlite_Cursor *self); +PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self); +PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args); +PyObject* pysqlite_cursor_fetchmany(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs); +PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args); +PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args); +PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args); + +int pysqlite_cursor_setup_types(void); + +#define UNKNOWN (-1) +#endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c index 3b2d7f42b87..cac71a61869 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c +++ b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.c @@ -1,104 +1,104 @@ -/* microprotocols.c - minimalist and non-validating protocols implementation - * - * Copyright (C) 2003-2004 Federico Di Gregorio - * - * This file is part of psycopg and was adapted for pysqlite. Federico Di - * Gregorio gave the permission to use it within pysqlite under the following - * license: - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include - -#include "cursor.h" -#include "microprotocols.h" -#include "prepare_protocol.h" - - -/** the adapters registry **/ - -static PyObject *psyco_adapters = NULL; - -/* pysqlite_microprotocols_init - initialize the adapters dictionary */ - -int -pysqlite_microprotocols_init(PyObject *dict) -{ - /* create adapters dictionary and put it in module namespace */ - if ((psyco_adapters = PyDict_New()) == NULL) { - return -1; - } - - return PyDict_SetItemString(dict, "adapters", psyco_adapters); -} - - -/* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */ - -int -pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) -{ - PyObject* key; - int rc; - - if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType; - - key = Py_BuildValue("(OO)", (PyObject*)type, proto); - if (!key) { - return -1; - } - - rc = PyDict_SetItem(psyco_adapters, key, cast); - Py_DECREF(key); - - return rc; -} - -/* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */ - -PyObject * -pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) -{ +/* microprotocols.c - minimalist and non-validating protocols implementation + * + * Copyright (C) 2003-2004 Federico Di Gregorio + * + * This file is part of psycopg and was adapted for pysqlite. Federico Di + * Gregorio gave the permission to use it within pysqlite under the following + * license: + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include + +#include "cursor.h" +#include "microprotocols.h" +#include "prepare_protocol.h" + + +/** the adapters registry **/ + +static PyObject *psyco_adapters = NULL; + +/* pysqlite_microprotocols_init - initialize the adapters dictionary */ + +int +pysqlite_microprotocols_init(PyObject *dict) +{ + /* create adapters dictionary and put it in module namespace */ + if ((psyco_adapters = PyDict_New()) == NULL) { + return -1; + } + + return PyDict_SetItemString(dict, "adapters", psyco_adapters); +} + + +/* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */ + +int +pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) +{ + PyObject* key; + int rc; + + if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType; + + key = Py_BuildValue("(OO)", (PyObject*)type, proto); + if (!key) { + return -1; + } + + rc = PyDict_SetItem(psyco_adapters, key, cast); + Py_DECREF(key); + + return rc; +} + +/* pysqlite_microprotocols_adapt - adapt an object to the built-in protocol */ + +PyObject * +pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) +{ _Py_IDENTIFIER(__adapt__); _Py_IDENTIFIER(__conform__); PyObject *adapter, *key, *adapted; - - /* we don't check for exact type conformance as specified in PEP 246 - because the pysqlite_PrepareProtocolType type is abstract and there is no - way to get a quotable object to be its instance */ - - /* look for an adapter in the registry */ + + /* we don't check for exact type conformance as specified in PEP 246 + because the pysqlite_PrepareProtocolType type is abstract and there is no + way to get a quotable object to be its instance */ + + /* look for an adapter in the registry */ key = Py_BuildValue("(OO)", (PyObject*)Py_TYPE(obj), proto); - if (!key) { - return NULL; - } + if (!key) { + return NULL; + } adapter = PyDict_GetItemWithError(psyco_adapters, key); - Py_DECREF(key); - if (adapter) { + Py_DECREF(key); + if (adapter) { Py_INCREF(adapter); adapted = PyObject_CallOneArg(adapter, obj); Py_DECREF(adapter); - return adapted; - } + return adapted; + } if (PyErr_Occurred()) { return NULL; } - + /* try to have the protocol adapt this object */ if (_PyObject_LookupAttrId(proto, &PyId___adapt__, &adapter) < 0) { return NULL; @@ -106,54 +106,54 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) if (adapter) { adapted = PyObject_CallOneArg(adapter, obj); Py_DECREF(adapter); - + if (adapted == Py_None) { Py_DECREF(adapted); - } + } else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) { return adapted; } else { PyErr_Clear(); } - } - - /* and finally try to have the object adapt itself */ + } + + /* and finally try to have the object adapt itself */ if (_PyObject_LookupAttrId(obj, &PyId___conform__, &adapter) < 0) { return NULL; } if (adapter) { adapted = PyObject_CallOneArg(adapter, proto); Py_DECREF(adapter); - + if (adapted == Py_None) { Py_DECREF(adapted); - } + } else if (adapted || !PyErr_ExceptionMatches(PyExc_TypeError)) { return adapted; - } + } else { PyErr_Clear(); } - } - + } + if (alt) { Py_INCREF(alt); return alt; } - /* else set the right exception and return NULL */ - PyErr_SetString(pysqlite_ProgrammingError, "can't adapt"); - return NULL; -} - -/** module-level functions **/ - -PyObject * -pysqlite_adapt(pysqlite_Cursor *self, PyObject *args) -{ - PyObject *obj, *alt = NULL; - PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType; - - if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL; - return pysqlite_microprotocols_adapt(obj, proto, alt); -} + /* else set the right exception and return NULL */ + PyErr_SetString(pysqlite_ProgrammingError, "can't adapt"); + return NULL; +} + +/** module-level functions **/ + +PyObject * +pysqlite_adapt(pysqlite_Cursor *self, PyObject *args) +{ + PyObject *obj, *alt = NULL; + PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType; + + if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL; + return pysqlite_microprotocols_adapt(obj, proto, alt); +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.h b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.h index 5418c2b98fd..33e82e680cc 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/microprotocols.h +++ b/contrib/tools/python3/src/Modules/_sqlite/microprotocols.h @@ -1,52 +1,52 @@ -/* microprotocols.c - definitions for minimalist and non-validating protocols - * - * Copyright (C) 2003-2004 Federico Di Gregorio - * - * This file is part of psycopg and was adapted for pysqlite. Federico Di - * Gregorio gave the permission to use it within pysqlite under the following - * license: - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PSYCOPG_MICROPROTOCOLS_H -#define PSYCOPG_MICROPROTOCOLS_H 1 - +/* microprotocols.c - definitions for minimalist and non-validating protocols + * + * Copyright (C) 2003-2004 Federico Di Gregorio + * + * This file is part of psycopg and was adapted for pysqlite. Federico Di + * Gregorio gave the permission to use it within pysqlite under the following + * license: + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PSYCOPG_MICROPROTOCOLS_H +#define PSYCOPG_MICROPROTOCOLS_H 1 + #define PY_SSIZE_T_CLEAN -#include - -/** the names of the three mandatory methods **/ - -#define MICROPROTOCOLS_GETQUOTED_NAME "getquoted" -#define MICROPROTOCOLS_GETSTRING_NAME "getstring" -#define MICROPROTOCOLS_GETBINARY_NAME "getbinary" - -/** exported functions **/ - -/* used by module.c to init the microprotocols system */ -extern int pysqlite_microprotocols_init(PyObject *dict); -extern int pysqlite_microprotocols_add( - PyTypeObject *type, PyObject *proto, PyObject *cast); -extern PyObject *pysqlite_microprotocols_adapt( - PyObject *obj, PyObject *proto, PyObject *alt); - -extern PyObject * - pysqlite_adapt(pysqlite_Cursor* self, PyObject *args); -#define pysqlite_adapt_doc \ - "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard." - -#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */ +#include + +/** the names of the three mandatory methods **/ + +#define MICROPROTOCOLS_GETQUOTED_NAME "getquoted" +#define MICROPROTOCOLS_GETSTRING_NAME "getstring" +#define MICROPROTOCOLS_GETBINARY_NAME "getbinary" + +/** exported functions **/ + +/* used by module.c to init the microprotocols system */ +extern int pysqlite_microprotocols_init(PyObject *dict); +extern int pysqlite_microprotocols_add( + PyTypeObject *type, PyObject *proto, PyObject *cast); +extern PyObject *pysqlite_microprotocols_adapt( + PyObject *obj, PyObject *proto, PyObject *alt); + +extern PyObject * + pysqlite_adapt(pysqlite_Cursor* self, PyObject *args); +#define pysqlite_adapt_doc \ + "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard." + +#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */ diff --git a/contrib/tools/python3/src/Modules/_sqlite/module.c b/contrib/tools/python3/src/Modules/_sqlite/module.c index 44811835d42..d43280b4f2c 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/module.c +++ b/contrib/tools/python3/src/Modules/_sqlite/module.c @@ -1,343 +1,343 @@ -/* module.c - the module itself - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "connection.h" -#include "statement.h" -#include "cursor.h" -#include "cache.h" -#include "prepare_protocol.h" -#include "microprotocols.h" -#include "row.h" - -#if SQLITE_VERSION_NUMBER >= 3003003 -#define HAVE_SHARED_CACHE -#endif - -/* static objects at module-level */ - -PyObject *pysqlite_Error = NULL; -PyObject *pysqlite_Warning = NULL; -PyObject *pysqlite_InterfaceError = NULL; -PyObject *pysqlite_DatabaseError = NULL; -PyObject *pysqlite_InternalError = NULL; -PyObject *pysqlite_OperationalError = NULL; -PyObject *pysqlite_ProgrammingError = NULL; -PyObject *pysqlite_IntegrityError = NULL; -PyObject *pysqlite_DataError = NULL; -PyObject *pysqlite_NotSupportedError = NULL; - -PyObject* _pysqlite_converters = NULL; -int _pysqlite_enable_callback_tracebacks = 0; -int pysqlite_BaseTypeAdapted = 0; - -static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* - kwargs) -{ - /* Python seems to have no way of extracting a single keyword-arg at - * C-level, so this code is redundant with the one in connection_init in - * connection.c and must always be copied from there ... */ - - static char *kwlist[] = { - "database", "timeout", "detect_types", "isolation_level", - "check_same_thread", "factory", "cached_statements", "uri", - NULL - }; - PyObject* database; - int detect_types = 0; - PyObject* isolation_level; - PyObject* factory = NULL; - int check_same_thread = 1; - int cached_statements; - int uri = 0; - double timeout = 5.0; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOip", kwlist, - &database, &timeout, &detect_types, - &isolation_level, &check_same_thread, - &factory, &cached_statements, &uri)) - { - return NULL; - } - - if (factory == NULL) { - factory = (PyObject*)&pysqlite_ConnectionType; - } - +/* module.c - the module itself + * + * Copyright (C) 2004-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "connection.h" +#include "statement.h" +#include "cursor.h" +#include "cache.h" +#include "prepare_protocol.h" +#include "microprotocols.h" +#include "row.h" + +#if SQLITE_VERSION_NUMBER >= 3003003 +#define HAVE_SHARED_CACHE +#endif + +/* static objects at module-level */ + +PyObject *pysqlite_Error = NULL; +PyObject *pysqlite_Warning = NULL; +PyObject *pysqlite_InterfaceError = NULL; +PyObject *pysqlite_DatabaseError = NULL; +PyObject *pysqlite_InternalError = NULL; +PyObject *pysqlite_OperationalError = NULL; +PyObject *pysqlite_ProgrammingError = NULL; +PyObject *pysqlite_IntegrityError = NULL; +PyObject *pysqlite_DataError = NULL; +PyObject *pysqlite_NotSupportedError = NULL; + +PyObject* _pysqlite_converters = NULL; +int _pysqlite_enable_callback_tracebacks = 0; +int pysqlite_BaseTypeAdapted = 0; + +static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* + kwargs) +{ + /* Python seems to have no way of extracting a single keyword-arg at + * C-level, so this code is redundant with the one in connection_init in + * connection.c and must always be copied from there ... */ + + static char *kwlist[] = { + "database", "timeout", "detect_types", "isolation_level", + "check_same_thread", "factory", "cached_statements", "uri", + NULL + }; + PyObject* database; + int detect_types = 0; + PyObject* isolation_level; + PyObject* factory = NULL; + int check_same_thread = 1; + int cached_statements; + int uri = 0; + double timeout = 5.0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|diOiOip", kwlist, + &database, &timeout, &detect_types, + &isolation_level, &check_same_thread, + &factory, &cached_statements, &uri)) + { + return NULL; + } + + if (factory == NULL) { + factory = (PyObject*)&pysqlite_ConnectionType; + } + return PyObject_Call(factory, args, kwargs); -} - -PyDoc_STRVAR(module_connect_doc, -"connect(database[, timeout, detect_types, isolation_level,\n\ - check_same_thread, factory, cached_statements, uri])\n\ -\n\ -Opens a connection to the SQLite database file *database*. You can use\n\ -\":memory:\" to open a database connection to a database that resides in\n\ -RAM instead of on disk."); - -static PyObject* module_complete(PyObject* self, PyObject* args, PyObject* - kwargs) -{ +} + +PyDoc_STRVAR(module_connect_doc, +"connect(database[, timeout, detect_types, isolation_level,\n\ + check_same_thread, factory, cached_statements, uri])\n\ +\n\ +Opens a connection to the SQLite database file *database*. You can use\n\ +\":memory:\" to open a database connection to a database that resides in\n\ +RAM instead of on disk."); + +static PyObject* module_complete(PyObject* self, PyObject* args, PyObject* + kwargs) +{ static char *kwlist[] = {"statement", NULL}; - char* statement; - - PyObject* result; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement)) - { - return NULL; - } - - if (sqlite3_complete(statement)) { - result = Py_True; - } else { - result = Py_False; - } - - Py_INCREF(result); - - return result; -} - -PyDoc_STRVAR(module_complete_doc, -"complete_statement(sql)\n\ -\n\ -Checks if a string contains a complete SQL statement. Non-standard."); - -#ifdef HAVE_SHARED_CACHE -static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject* - kwargs) -{ + char* statement; + + PyObject* result; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement)) + { + return NULL; + } + + if (sqlite3_complete(statement)) { + result = Py_True; + } else { + result = Py_False; + } + + Py_INCREF(result); + + return result; +} + +PyDoc_STRVAR(module_complete_doc, +"complete_statement(sql)\n\ +\n\ +Checks if a string contains a complete SQL statement. Non-standard."); + +#ifdef HAVE_SHARED_CACHE +static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject* + kwargs) +{ static char *kwlist[] = {"do_enable", NULL}; - int do_enable; - int rc; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable)) - { - return NULL; - } - - rc = sqlite3_enable_shared_cache(do_enable); - - if (rc != SQLITE_OK) { - PyErr_SetString(pysqlite_OperationalError, "Changing the shared_cache flag failed"); - return NULL; - } else { - Py_RETURN_NONE; - } -} - -PyDoc_STRVAR(module_enable_shared_cache_doc, -"enable_shared_cache(do_enable)\n\ -\n\ -Enable or disable shared cache mode for the calling thread.\n\ -Experimental/Non-standard."); -#endif /* HAVE_SHARED_CACHE */ - -static PyObject* module_register_adapter(PyObject* self, PyObject* args) -{ - PyTypeObject* type; - PyObject* caster; - int rc; - - if (!PyArg_ParseTuple(args, "OO", &type, &caster)) { - return NULL; - } - - /* a basic type is adapted; there's a performance optimization if that's not the case - * (99 % of all usages) */ - if (type == &PyLong_Type || type == &PyFloat_Type - || type == &PyUnicode_Type || type == &PyByteArray_Type) { - pysqlite_BaseTypeAdapted = 1; - } - - rc = pysqlite_microprotocols_add(type, (PyObject*)&pysqlite_PrepareProtocolType, caster); - if (rc == -1) - return NULL; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(module_register_adapter_doc, -"register_adapter(type, callable)\n\ -\n\ -Registers an adapter with pysqlite's adapter registry. Non-standard."); - -static PyObject* module_register_converter(PyObject* self, PyObject* args) -{ - PyObject* orig_name; - PyObject* name = NULL; - PyObject* callable; - PyObject* retval = NULL; - _Py_IDENTIFIER(upper); - - if (!PyArg_ParseTuple(args, "UO", &orig_name, &callable)) { - return NULL; - } - - /* convert the name to upper case */ + int do_enable; + int rc; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable)) + { + return NULL; + } + + rc = sqlite3_enable_shared_cache(do_enable); + + if (rc != SQLITE_OK) { + PyErr_SetString(pysqlite_OperationalError, "Changing the shared_cache flag failed"); + return NULL; + } else { + Py_RETURN_NONE; + } +} + +PyDoc_STRVAR(module_enable_shared_cache_doc, +"enable_shared_cache(do_enable)\n\ +\n\ +Enable or disable shared cache mode for the calling thread.\n\ +Experimental/Non-standard."); +#endif /* HAVE_SHARED_CACHE */ + +static PyObject* module_register_adapter(PyObject* self, PyObject* args) +{ + PyTypeObject* type; + PyObject* caster; + int rc; + + if (!PyArg_ParseTuple(args, "OO", &type, &caster)) { + return NULL; + } + + /* a basic type is adapted; there's a performance optimization if that's not the case + * (99 % of all usages) */ + if (type == &PyLong_Type || type == &PyFloat_Type + || type == &PyUnicode_Type || type == &PyByteArray_Type) { + pysqlite_BaseTypeAdapted = 1; + } + + rc = pysqlite_microprotocols_add(type, (PyObject*)&pysqlite_PrepareProtocolType, caster); + if (rc == -1) + return NULL; + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(module_register_adapter_doc, +"register_adapter(type, callable)\n\ +\n\ +Registers an adapter with pysqlite's adapter registry. Non-standard."); + +static PyObject* module_register_converter(PyObject* self, PyObject* args) +{ + PyObject* orig_name; + PyObject* name = NULL; + PyObject* callable; + PyObject* retval = NULL; + _Py_IDENTIFIER(upper); + + if (!PyArg_ParseTuple(args, "UO", &orig_name, &callable)) { + return NULL; + } + + /* convert the name to upper case */ name = _PyObject_CallMethodIdNoArgs(orig_name, &PyId_upper); - if (!name) { - goto error; - } - - if (PyDict_SetItem(_pysqlite_converters, name, callable) != 0) { - goto error; - } - - Py_INCREF(Py_None); - retval = Py_None; -error: - Py_XDECREF(name); - return retval; -} - -PyDoc_STRVAR(module_register_converter_doc, -"register_converter(typename, callable)\n\ -\n\ -Registers a converter with pysqlite. Non-standard."); - -static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, "i", &_pysqlite_enable_callback_tracebacks)) { - return NULL; - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(enable_callback_tracebacks_doc, -"enable_callback_tracebacks(flag)\n\ -\n\ -Enable or disable callback functions throwing errors to stderr."); - -static void converters_init(PyObject* dict) -{ - _pysqlite_converters = PyDict_New(); - if (!_pysqlite_converters) { - return; - } - - PyDict_SetItemString(dict, "converters", _pysqlite_converters); -} - -static PyMethodDef module_methods[] = { + if (!name) { + goto error; + } + + if (PyDict_SetItem(_pysqlite_converters, name, callable) != 0) { + goto error; + } + + Py_INCREF(Py_None); + retval = Py_None; +error: + Py_XDECREF(name); + return retval; +} + +PyDoc_STRVAR(module_register_converter_doc, +"register_converter(typename, callable)\n\ +\n\ +Registers a converter with pysqlite. Non-standard."); + +static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args) +{ + if (!PyArg_ParseTuple(args, "i", &_pysqlite_enable_callback_tracebacks)) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(enable_callback_tracebacks_doc, +"enable_callback_tracebacks(flag)\n\ +\n\ +Enable or disable callback functions throwing errors to stderr."); + +static void converters_init(PyObject* dict) +{ + _pysqlite_converters = PyDict_New(); + if (!_pysqlite_converters) { + return; + } + + PyDict_SetItemString(dict, "converters", _pysqlite_converters); +} + +static PyMethodDef module_methods[] = { {"connect", (PyCFunction)(void(*)(void))module_connect, - METH_VARARGS | METH_KEYWORDS, module_connect_doc}, + METH_VARARGS | METH_KEYWORDS, module_connect_doc}, {"complete_statement", (PyCFunction)(void(*)(void))module_complete, - METH_VARARGS | METH_KEYWORDS, module_complete_doc}, -#ifdef HAVE_SHARED_CACHE + METH_VARARGS | METH_KEYWORDS, module_complete_doc}, +#ifdef HAVE_SHARED_CACHE {"enable_shared_cache", (PyCFunction)(void(*)(void))module_enable_shared_cache, - METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc}, -#endif - {"register_adapter", (PyCFunction)module_register_adapter, - METH_VARARGS, module_register_adapter_doc}, - {"register_converter", (PyCFunction)module_register_converter, - METH_VARARGS, module_register_converter_doc}, - {"adapt", (PyCFunction)pysqlite_adapt, METH_VARARGS, - pysqlite_adapt_doc}, - {"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, - METH_VARARGS, enable_callback_tracebacks_doc}, - {NULL, NULL} -}; - -struct _IntConstantPair { - const char *constant_name; - int constant_value; -}; - -typedef struct _IntConstantPair IntConstantPair; - -static const IntConstantPair _int_constants[] = { - {"PARSE_DECLTYPES", PARSE_DECLTYPES}, - {"PARSE_COLNAMES", PARSE_COLNAMES}, - - {"SQLITE_OK", SQLITE_OK}, - {"SQLITE_DENY", SQLITE_DENY}, - {"SQLITE_IGNORE", SQLITE_IGNORE}, - {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX}, - {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE}, - {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX}, - {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE}, - {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER}, - {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW}, - {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER}, - {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW}, - {"SQLITE_DELETE", SQLITE_DELETE}, - {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX}, - {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE}, - {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX}, - {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE}, - {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER}, - {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW}, - {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER}, - {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW}, - {"SQLITE_INSERT", SQLITE_INSERT}, - {"SQLITE_PRAGMA", SQLITE_PRAGMA}, - {"SQLITE_READ", SQLITE_READ}, - {"SQLITE_SELECT", SQLITE_SELECT}, - {"SQLITE_TRANSACTION", SQLITE_TRANSACTION}, - {"SQLITE_UPDATE", SQLITE_UPDATE}, - {"SQLITE_ATTACH", SQLITE_ATTACH}, - {"SQLITE_DETACH", SQLITE_DETACH}, -#if SQLITE_VERSION_NUMBER >= 3002001 - {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE}, - {"SQLITE_REINDEX", SQLITE_REINDEX}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003000 - {"SQLITE_ANALYZE", SQLITE_ANALYZE}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003007 - {"SQLITE_CREATE_VTABLE", SQLITE_CREATE_VTABLE}, - {"SQLITE_DROP_VTABLE", SQLITE_DROP_VTABLE}, -#endif -#if SQLITE_VERSION_NUMBER >= 3003008 - {"SQLITE_FUNCTION", SQLITE_FUNCTION}, -#endif -#if SQLITE_VERSION_NUMBER >= 3006008 - {"SQLITE_SAVEPOINT", SQLITE_SAVEPOINT}, -#endif -#if SQLITE_VERSION_NUMBER >= 3008003 - {"SQLITE_RECURSIVE", SQLITE_RECURSIVE}, -#endif -#if SQLITE_VERSION_NUMBER >= 3006011 - {"SQLITE_DONE", SQLITE_DONE}, -#endif - {(char*)NULL, 0} -}; - - -static struct PyModuleDef _sqlite3module = { - PyModuleDef_HEAD_INIT, - "_sqlite3", - NULL, - -1, - module_methods, - NULL, - NULL, - NULL, - NULL -}; - + METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc}, +#endif + {"register_adapter", (PyCFunction)module_register_adapter, + METH_VARARGS, module_register_adapter_doc}, + {"register_converter", (PyCFunction)module_register_converter, + METH_VARARGS, module_register_converter_doc}, + {"adapt", (PyCFunction)pysqlite_adapt, METH_VARARGS, + pysqlite_adapt_doc}, + {"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, + METH_VARARGS, enable_callback_tracebacks_doc}, + {NULL, NULL} +}; + +struct _IntConstantPair { + const char *constant_name; + int constant_value; +}; + +typedef struct _IntConstantPair IntConstantPair; + +static const IntConstantPair _int_constants[] = { + {"PARSE_DECLTYPES", PARSE_DECLTYPES}, + {"PARSE_COLNAMES", PARSE_COLNAMES}, + + {"SQLITE_OK", SQLITE_OK}, + {"SQLITE_DENY", SQLITE_DENY}, + {"SQLITE_IGNORE", SQLITE_IGNORE}, + {"SQLITE_CREATE_INDEX", SQLITE_CREATE_INDEX}, + {"SQLITE_CREATE_TABLE", SQLITE_CREATE_TABLE}, + {"SQLITE_CREATE_TEMP_INDEX", SQLITE_CREATE_TEMP_INDEX}, + {"SQLITE_CREATE_TEMP_TABLE", SQLITE_CREATE_TEMP_TABLE}, + {"SQLITE_CREATE_TEMP_TRIGGER", SQLITE_CREATE_TEMP_TRIGGER}, + {"SQLITE_CREATE_TEMP_VIEW", SQLITE_CREATE_TEMP_VIEW}, + {"SQLITE_CREATE_TRIGGER", SQLITE_CREATE_TRIGGER}, + {"SQLITE_CREATE_VIEW", SQLITE_CREATE_VIEW}, + {"SQLITE_DELETE", SQLITE_DELETE}, + {"SQLITE_DROP_INDEX", SQLITE_DROP_INDEX}, + {"SQLITE_DROP_TABLE", SQLITE_DROP_TABLE}, + {"SQLITE_DROP_TEMP_INDEX", SQLITE_DROP_TEMP_INDEX}, + {"SQLITE_DROP_TEMP_TABLE", SQLITE_DROP_TEMP_TABLE}, + {"SQLITE_DROP_TEMP_TRIGGER", SQLITE_DROP_TEMP_TRIGGER}, + {"SQLITE_DROP_TEMP_VIEW", SQLITE_DROP_TEMP_VIEW}, + {"SQLITE_DROP_TRIGGER", SQLITE_DROP_TRIGGER}, + {"SQLITE_DROP_VIEW", SQLITE_DROP_VIEW}, + {"SQLITE_INSERT", SQLITE_INSERT}, + {"SQLITE_PRAGMA", SQLITE_PRAGMA}, + {"SQLITE_READ", SQLITE_READ}, + {"SQLITE_SELECT", SQLITE_SELECT}, + {"SQLITE_TRANSACTION", SQLITE_TRANSACTION}, + {"SQLITE_UPDATE", SQLITE_UPDATE}, + {"SQLITE_ATTACH", SQLITE_ATTACH}, + {"SQLITE_DETACH", SQLITE_DETACH}, +#if SQLITE_VERSION_NUMBER >= 3002001 + {"SQLITE_ALTER_TABLE", SQLITE_ALTER_TABLE}, + {"SQLITE_REINDEX", SQLITE_REINDEX}, +#endif +#if SQLITE_VERSION_NUMBER >= 3003000 + {"SQLITE_ANALYZE", SQLITE_ANALYZE}, +#endif +#if SQLITE_VERSION_NUMBER >= 3003007 + {"SQLITE_CREATE_VTABLE", SQLITE_CREATE_VTABLE}, + {"SQLITE_DROP_VTABLE", SQLITE_DROP_VTABLE}, +#endif +#if SQLITE_VERSION_NUMBER >= 3003008 + {"SQLITE_FUNCTION", SQLITE_FUNCTION}, +#endif +#if SQLITE_VERSION_NUMBER >= 3006008 + {"SQLITE_SAVEPOINT", SQLITE_SAVEPOINT}, +#endif +#if SQLITE_VERSION_NUMBER >= 3008003 + {"SQLITE_RECURSIVE", SQLITE_RECURSIVE}, +#endif +#if SQLITE_VERSION_NUMBER >= 3006011 + {"SQLITE_DONE", SQLITE_DONE}, +#endif + {(char*)NULL, 0} +}; + + +static struct PyModuleDef _sqlite3module = { + PyModuleDef_HEAD_INIT, + "_sqlite3", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + #define ADD_TYPE(module, type) \ do { \ if (PyModule_AddType(module, &type) < 0) { \ @@ -346,133 +346,133 @@ do { \ } \ } while (0) -PyMODINIT_FUNC PyInit__sqlite3(void) -{ - PyObject *module, *dict; - PyObject *tmp_obj; - int i; - - module = PyModule_Create(&_sqlite3module); - - if (!module || - (pysqlite_row_setup_types() < 0) || - (pysqlite_cursor_setup_types() < 0) || - (pysqlite_connection_setup_types() < 0) || - (pysqlite_cache_setup_types() < 0) || - (pysqlite_statement_setup_types() < 0) || - (pysqlite_prepare_protocol_setup_types() < 0) - ) { - Py_XDECREF(module); - return NULL; - } - +PyMODINIT_FUNC PyInit__sqlite3(void) +{ + PyObject *module, *dict; + PyObject *tmp_obj; + int i; + + module = PyModule_Create(&_sqlite3module); + + if (!module || + (pysqlite_row_setup_types() < 0) || + (pysqlite_cursor_setup_types() < 0) || + (pysqlite_connection_setup_types() < 0) || + (pysqlite_cache_setup_types() < 0) || + (pysqlite_statement_setup_types() < 0) || + (pysqlite_prepare_protocol_setup_types() < 0) + ) { + Py_XDECREF(module); + return NULL; + } + ADD_TYPE(module, pysqlite_ConnectionType); ADD_TYPE(module, pysqlite_CursorType); ADD_TYPE(module, pysqlite_PrepareProtocolType); ADD_TYPE(module, pysqlite_RowType); - - if (!(dict = PyModule_GetDict(module))) { - goto error; - } - - /*** Create DB-API Exception hierarchy */ - - if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_Exception, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "Error", pysqlite_Error); - - if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_Exception, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "Warning", pysqlite_Warning); - - /* Error subclasses */ - - if (!(pysqlite_InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", pysqlite_Error, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "InterfaceError", pysqlite_InterfaceError); - - if (!(pysqlite_DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", pysqlite_Error, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "DatabaseError", pysqlite_DatabaseError); - - /* pysqlite_DatabaseError subclasses */ - - if (!(pysqlite_InternalError = PyErr_NewException(MODULE_NAME ".InternalError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "InternalError", pysqlite_InternalError); - - if (!(pysqlite_OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "OperationalError", pysqlite_OperationalError); - - if (!(pysqlite_ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "ProgrammingError", pysqlite_ProgrammingError); - - if (!(pysqlite_IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", pysqlite_DatabaseError,NULL))) { - goto error; - } - PyDict_SetItemString(dict, "IntegrityError", pysqlite_IntegrityError); - - if (!(pysqlite_DataError = PyErr_NewException(MODULE_NAME ".DataError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "DataError", pysqlite_DataError); - - if (!(pysqlite_NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", pysqlite_DatabaseError, NULL))) { - goto error; - } - PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError); - - /* In Python 2.x, setting Connection.text_factory to - OptimizedUnicode caused Unicode objects to be returned for - non-ASCII data and bytestrings to be returned for ASCII data. - Now OptimizedUnicode is an alias for str, so it has no - effect. */ - Py_INCREF((PyObject*)&PyUnicode_Type); - PyDict_SetItemString(dict, "OptimizedUnicode", (PyObject*)&PyUnicode_Type); - - /* Set integer constants */ - for (i = 0; _int_constants[i].constant_name != NULL; i++) { - tmp_obj = PyLong_FromLong(_int_constants[i].constant_value); - if (!tmp_obj) { - goto error; - } - PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj); - Py_DECREF(tmp_obj); - } - - if (!(tmp_obj = PyUnicode_FromString(PYSQLITE_VERSION))) { - goto error; - } - PyDict_SetItemString(dict, "version", tmp_obj); - Py_DECREF(tmp_obj); - - if (!(tmp_obj = PyUnicode_FromString(sqlite3_libversion()))) { - goto error; - } - PyDict_SetItemString(dict, "sqlite_version", tmp_obj); - Py_DECREF(tmp_obj); - - /* initialize microprotocols layer */ - pysqlite_microprotocols_init(dict); - - /* initialize the default converters */ - converters_init(dict); - -error: - if (PyErr_Occurred()) - { - PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed"); - Py_DECREF(module); - module = NULL; - } - return module; -} + + if (!(dict = PyModule_GetDict(module))) { + goto error; + } + + /*** Create DB-API Exception hierarchy */ + + if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_Exception, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "Error", pysqlite_Error); + + if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_Exception, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "Warning", pysqlite_Warning); + + /* Error subclasses */ + + if (!(pysqlite_InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", pysqlite_Error, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "InterfaceError", pysqlite_InterfaceError); + + if (!(pysqlite_DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", pysqlite_Error, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "DatabaseError", pysqlite_DatabaseError); + + /* pysqlite_DatabaseError subclasses */ + + if (!(pysqlite_InternalError = PyErr_NewException(MODULE_NAME ".InternalError", pysqlite_DatabaseError, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "InternalError", pysqlite_InternalError); + + if (!(pysqlite_OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", pysqlite_DatabaseError, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "OperationalError", pysqlite_OperationalError); + + if (!(pysqlite_ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", pysqlite_DatabaseError, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "ProgrammingError", pysqlite_ProgrammingError); + + if (!(pysqlite_IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", pysqlite_DatabaseError,NULL))) { + goto error; + } + PyDict_SetItemString(dict, "IntegrityError", pysqlite_IntegrityError); + + if (!(pysqlite_DataError = PyErr_NewException(MODULE_NAME ".DataError", pysqlite_DatabaseError, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "DataError", pysqlite_DataError); + + if (!(pysqlite_NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", pysqlite_DatabaseError, NULL))) { + goto error; + } + PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError); + + /* In Python 2.x, setting Connection.text_factory to + OptimizedUnicode caused Unicode objects to be returned for + non-ASCII data and bytestrings to be returned for ASCII data. + Now OptimizedUnicode is an alias for str, so it has no + effect. */ + Py_INCREF((PyObject*)&PyUnicode_Type); + PyDict_SetItemString(dict, "OptimizedUnicode", (PyObject*)&PyUnicode_Type); + + /* Set integer constants */ + for (i = 0; _int_constants[i].constant_name != NULL; i++) { + tmp_obj = PyLong_FromLong(_int_constants[i].constant_value); + if (!tmp_obj) { + goto error; + } + PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj); + Py_DECREF(tmp_obj); + } + + if (!(tmp_obj = PyUnicode_FromString(PYSQLITE_VERSION))) { + goto error; + } + PyDict_SetItemString(dict, "version", tmp_obj); + Py_DECREF(tmp_obj); + + if (!(tmp_obj = PyUnicode_FromString(sqlite3_libversion()))) { + goto error; + } + PyDict_SetItemString(dict, "sqlite_version", tmp_obj); + Py_DECREF(tmp_obj); + + /* initialize microprotocols layer */ + pysqlite_microprotocols_init(dict); + + /* initialize the default converters */ + converters_init(dict); + +error: + if (PyErr_Occurred()) + { + PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed"); + Py_DECREF(module); + module = NULL; + } + return module; +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/module.h b/contrib/tools/python3/src/Modules/_sqlite/module.h index 3185ec97888..30794127d39 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/module.h +++ b/contrib/tools/python3/src/Modules/_sqlite/module.h @@ -1,53 +1,53 @@ -/* module.h - definitions for the module - * - * Copyright (C) 2004-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PYSQLITE_MODULE_H -#define PYSQLITE_MODULE_H +/* module.h - definitions for the module + * + * Copyright (C) 2004-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PYSQLITE_MODULE_H +#define PYSQLITE_MODULE_H #define PY_SSIZE_T_CLEAN -#include "Python.h" - -#define PYSQLITE_VERSION "2.6.0" - -extern PyObject* pysqlite_Error; -extern PyObject* pysqlite_Warning; -extern PyObject* pysqlite_InterfaceError; -extern PyObject* pysqlite_DatabaseError; -extern PyObject* pysqlite_InternalError; -extern PyObject* pysqlite_OperationalError; -extern PyObject* pysqlite_ProgrammingError; -extern PyObject* pysqlite_IntegrityError; -extern PyObject* pysqlite_DataError; -extern PyObject* pysqlite_NotSupportedError; - -/* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter - * functions, that convert the SQL value to the appropriate Python value. - * The key is uppercase. - */ -extern PyObject* _pysqlite_converters; - -extern int _pysqlite_enable_callback_tracebacks; -extern int pysqlite_BaseTypeAdapted; - -#define PARSE_DECLTYPES 1 -#define PARSE_COLNAMES 2 -#endif +#include "Python.h" + +#define PYSQLITE_VERSION "2.6.0" + +extern PyObject* pysqlite_Error; +extern PyObject* pysqlite_Warning; +extern PyObject* pysqlite_InterfaceError; +extern PyObject* pysqlite_DatabaseError; +extern PyObject* pysqlite_InternalError; +extern PyObject* pysqlite_OperationalError; +extern PyObject* pysqlite_ProgrammingError; +extern PyObject* pysqlite_IntegrityError; +extern PyObject* pysqlite_DataError; +extern PyObject* pysqlite_NotSupportedError; + +/* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter + * functions, that convert the SQL value to the appropriate Python value. + * The key is uppercase. + */ +extern PyObject* _pysqlite_converters; + +extern int _pysqlite_enable_callback_tracebacks; +extern int pysqlite_BaseTypeAdapted; + +#define PARSE_DECLTYPES 1 +#define PARSE_COLNAMES 2 +#endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.c b/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.c index 05a2ca5a652..f027f0bea42 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.c +++ b/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.c @@ -1,83 +1,83 @@ -/* prepare_protocol.c - the protocol for preparing values for SQLite - * - * Copyright (C) 2005-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "prepare_protocol.h" - -int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs) -{ - return 0; -} - -void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self) -{ - Py_TYPE(self)->tp_free((PyObject*)self); -} - -PyTypeObject pysqlite_PrepareProtocolType= { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".PrepareProtocol", /* tp_name */ - sizeof(pysqlite_PrepareProtocol), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_prepare_protocol_dealloc, /* tp_dealloc */ +/* prepare_protocol.c - the protocol for preparing values for SQLite + * + * Copyright (C) 2005-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "prepare_protocol.h" + +int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs) +{ + return 0; +} + +void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self) +{ + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyTypeObject pysqlite_PrepareProtocolType= { + PyVarObject_HEAD_INIT(NULL, 0) + MODULE_NAME ".PrepareProtocol", /* tp_name */ + sizeof(pysqlite_PrepareProtocol), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pysqlite_prepare_protocol_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_prepare_protocol_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ -}; - -extern int pysqlite_prepare_protocol_setup_types(void) -{ - pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew; + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pysqlite_prepare_protocol_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0 /* tp_free */ +}; + +extern int pysqlite_prepare_protocol_setup_types(void) +{ + pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew; Py_SET_TYPE(&pysqlite_PrepareProtocolType, &PyType_Type); - return PyType_Ready(&pysqlite_PrepareProtocolType); -} + return PyType_Ready(&pysqlite_PrepareProtocolType); +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.h b/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.h index 3998a55e51c..885b8065903 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.h +++ b/contrib/tools/python3/src/Modules/_sqlite/prepare_protocol.h @@ -1,42 +1,42 @@ -/* prepare_protocol.h - the protocol for preparing values for SQLite - * - * Copyright (C) 2005-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PYSQLITE_PREPARE_PROTOCOL_H -#define PYSQLITE_PREPARE_PROTOCOL_H +/* prepare_protocol.h - the protocol for preparing values for SQLite + * + * Copyright (C) 2005-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PYSQLITE_PREPARE_PROTOCOL_H +#define PYSQLITE_PREPARE_PROTOCOL_H #define PY_SSIZE_T_CLEAN -#include "Python.h" - -typedef struct -{ - PyObject_HEAD -} pysqlite_PrepareProtocol; - -extern PyTypeObject pysqlite_PrepareProtocolType; - -int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs); -void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self); - -int pysqlite_prepare_protocol_setup_types(void); - -#define UNKNOWN (-1) -#endif +#include "Python.h" + +typedef struct +{ + PyObject_HEAD +} pysqlite_PrepareProtocol; + +extern PyTypeObject pysqlite_PrepareProtocolType; + +int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs); +void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self); + +int pysqlite_prepare_protocol_setup_types(void); + +#define UNKNOWN (-1) +#endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/row.c b/contrib/tools/python3/src/Modules/_sqlite/row.c index 4b47108278a..07e7ce9990b 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/row.c +++ b/contrib/tools/python3/src/Modules/_sqlite/row.c @@ -1,81 +1,81 @@ -/* row.c - an enhanced tuple for database rows - * - * Copyright (C) 2005-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "row.h" -#include "cursor.h" - -void pysqlite_row_dealloc(pysqlite_Row* self) -{ - Py_XDECREF(self->data); - Py_XDECREF(self->description); - - Py_TYPE(self)->tp_free((PyObject*)self); -} - -static PyObject * -pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - pysqlite_Row *self; - PyObject* data; - pysqlite_Cursor* cursor; - - assert(type != NULL && type->tp_alloc != NULL); - - if (!_PyArg_NoKeywords("Row", kwargs)) - return NULL; - if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) - return NULL; - - if (!PyObject_TypeCheck((PyObject*)cursor, &pysqlite_CursorType)) { - PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); - return NULL; - } - - if (!PyTuple_Check(data)) { - PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); - return NULL; - } - - self = (pysqlite_Row *) type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - Py_INCREF(data); - self->data = data; - - Py_INCREF(cursor->description); - self->description = cursor->description; - - return (PyObject *) self; -} - -PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx) -{ - PyObject* item = PyTuple_GetItem(self->data, idx); - Py_XINCREF(item); - return item; -} - +/* row.c - an enhanced tuple for database rows + * + * Copyright (C) 2005-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "row.h" +#include "cursor.h" + +void pysqlite_row_dealloc(pysqlite_Row* self) +{ + Py_XDECREF(self->data); + Py_XDECREF(self->description); + + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyObject * +pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + pysqlite_Row *self; + PyObject* data; + pysqlite_Cursor* cursor; + + assert(type != NULL && type->tp_alloc != NULL); + + if (!_PyArg_NoKeywords("Row", kwargs)) + return NULL; + if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) + return NULL; + + if (!PyObject_TypeCheck((PyObject*)cursor, &pysqlite_CursorType)) { + PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); + return NULL; + } + + if (!PyTuple_Check(data)) { + PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); + return NULL; + } + + self = (pysqlite_Row *) type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + Py_INCREF(data); + self->data = data; + + Py_INCREF(cursor->description); + self->description = cursor->description; + + return (PyObject *) self; +} + +PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx) +{ + PyObject* item = PyTuple_GetItem(self->data, idx); + Py_XINCREF(item); + return item; +} + static int equal_ignore_case(PyObject *left, PyObject *right) { @@ -104,175 +104,175 @@ equal_ignore_case(PyObject *left, PyObject *right) return 1; } -PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) -{ - Py_ssize_t _idx; - Py_ssize_t nitems, i; - PyObject* item; - - if (PyLong_Check(idx)) { - _idx = PyNumber_AsSsize_t(idx, PyExc_IndexError); - if (_idx == -1 && PyErr_Occurred()) - return NULL; - if (_idx < 0) - _idx += PyTuple_GET_SIZE(self->data); - item = PyTuple_GetItem(self->data, _idx); - Py_XINCREF(item); - return item; - } else if (PyUnicode_Check(idx)) { - nitems = PyTuple_Size(self->description); - - for (i = 0; i < nitems; i++) { - PyObject *obj; - obj = PyTuple_GET_ITEM(self->description, i); - obj = PyTuple_GET_ITEM(obj, 0); +PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) +{ + Py_ssize_t _idx; + Py_ssize_t nitems, i; + PyObject* item; + + if (PyLong_Check(idx)) { + _idx = PyNumber_AsSsize_t(idx, PyExc_IndexError); + if (_idx == -1 && PyErr_Occurred()) + return NULL; + if (_idx < 0) + _idx += PyTuple_GET_SIZE(self->data); + item = PyTuple_GetItem(self->data, _idx); + Py_XINCREF(item); + return item; + } else if (PyUnicode_Check(idx)) { + nitems = PyTuple_Size(self->description); + + for (i = 0; i < nitems; i++) { + PyObject *obj; + obj = PyTuple_GET_ITEM(self->description, i); + obj = PyTuple_GET_ITEM(obj, 0); int eq = equal_ignore_case(idx, obj); if (eq < 0) { - return NULL; - } + return NULL; + } if (eq) { - /* found item */ - item = PyTuple_GetItem(self->data, i); - Py_INCREF(item); - return item; - } - } - - PyErr_SetString(PyExc_IndexError, "No item with that key"); - return NULL; - } - else if (PySlice_Check(idx)) { - return PyObject_GetItem(self->data, idx); - } - else { - PyErr_SetString(PyExc_IndexError, "Index must be int or string"); - return NULL; - } -} - -static Py_ssize_t -pysqlite_row_length(pysqlite_Row* self) -{ - return PyTuple_GET_SIZE(self->data); -} - + /* found item */ + item = PyTuple_GetItem(self->data, i); + Py_INCREF(item); + return item; + } + } + + PyErr_SetString(PyExc_IndexError, "No item with that key"); + return NULL; + } + else if (PySlice_Check(idx)) { + return PyObject_GetItem(self->data, idx); + } + else { + PyErr_SetString(PyExc_IndexError, "Index must be int or string"); + return NULL; + } +} + +static Py_ssize_t +pysqlite_row_length(pysqlite_Row* self) +{ + return PyTuple_GET_SIZE(self->data); +} + PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject *Py_UNUSED(ignored)) -{ - PyObject* list; - Py_ssize_t nitems, i; - - list = PyList_New(0); - if (!list) { - return NULL; - } - nitems = PyTuple_Size(self->description); - - for (i = 0; i < nitems; i++) { - if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)) != 0) { - Py_DECREF(list); - return NULL; - } - } - - return list; -} - -static PyObject* pysqlite_iter(pysqlite_Row* self) -{ - return PyObject_GetIter(self->data); -} - -static Py_hash_t pysqlite_row_hash(pysqlite_Row *self) -{ - return PyObject_Hash(self->description) ^ PyObject_Hash(self->data); -} - -static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid) -{ - if (opid != Py_EQ && opid != Py_NE) - Py_RETURN_NOTIMPLEMENTED; - +{ + PyObject* list; + Py_ssize_t nitems, i; + + list = PyList_New(0); + if (!list) { + return NULL; + } + nitems = PyTuple_Size(self->description); + + for (i = 0; i < nitems; i++) { + if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)) != 0) { + Py_DECREF(list); + return NULL; + } + } + + return list; +} + +static PyObject* pysqlite_iter(pysqlite_Row* self) +{ + return PyObject_GetIter(self->data); +} + +static Py_hash_t pysqlite_row_hash(pysqlite_Row *self) +{ + return PyObject_Hash(self->description) ^ PyObject_Hash(self->data); +} + +static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, int opid) +{ + if (opid != Py_EQ && opid != Py_NE) + Py_RETURN_NOTIMPLEMENTED; + if (PyObject_TypeCheck(_other, &pysqlite_RowType)) { - pysqlite_Row *other = (pysqlite_Row *)_other; + pysqlite_Row *other = (pysqlite_Row *)_other; int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ); if (eq < 0) { return NULL; } if (eq) { - return PyObject_RichCompare(self->data, other->data, opid); - } + return PyObject_RichCompare(self->data, other->data, opid); + } return PyBool_FromLong(opid != Py_EQ); - } - Py_RETURN_NOTIMPLEMENTED; -} - -PyMappingMethods pysqlite_row_as_mapping = { - /* mp_length */ (lenfunc)pysqlite_row_length, - /* mp_subscript */ (binaryfunc)pysqlite_row_subscript, - /* mp_ass_subscript */ (objobjargproc)0, -}; - -static PySequenceMethods pysqlite_row_as_sequence = { - /* sq_length */ (lenfunc)pysqlite_row_length, - /* sq_concat */ 0, - /* sq_repeat */ 0, - /* sq_item */ (ssizeargfunc)pysqlite_row_item, -}; - - -static PyMethodDef pysqlite_row_methods[] = { - {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, - PyDoc_STR("Returns the keys of the row.")}, - {NULL, NULL} -}; - - -PyTypeObject pysqlite_RowType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Row", /* tp_name */ - sizeof(pysqlite_Row), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_row_dealloc, /* tp_dealloc */ + } + Py_RETURN_NOTIMPLEMENTED; +} + +PyMappingMethods pysqlite_row_as_mapping = { + /* mp_length */ (lenfunc)pysqlite_row_length, + /* mp_subscript */ (binaryfunc)pysqlite_row_subscript, + /* mp_ass_subscript */ (objobjargproc)0, +}; + +static PySequenceMethods pysqlite_row_as_sequence = { + /* sq_length */ (lenfunc)pysqlite_row_length, + /* sq_concat */ 0, + /* sq_repeat */ 0, + /* sq_item */ (ssizeargfunc)pysqlite_row_item, +}; + + +static PyMethodDef pysqlite_row_methods[] = { + {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, + PyDoc_STR("Returns the keys of the row.")}, + {NULL, NULL} +}; + + +PyTypeObject pysqlite_RowType = { + PyVarObject_HEAD_INIT(NULL, 0) + MODULE_NAME ".Row", /* tp_name */ + sizeof(pysqlite_Row), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pysqlite_row_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)pysqlite_row_hash, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - (getiterfunc)pysqlite_iter, /* tp_iter */ - 0, /* tp_iternext */ - pysqlite_row_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ -}; - -extern int pysqlite_row_setup_types(void) -{ - pysqlite_RowType.tp_new = pysqlite_row_new; - pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; - pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence; - return PyType_Ready(&pysqlite_RowType); -} + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)pysqlite_row_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)pysqlite_iter, /* tp_iter */ + 0, /* tp_iternext */ + pysqlite_row_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0 /* tp_free */ +}; + +extern int pysqlite_row_setup_types(void) +{ + pysqlite_RowType.tp_new = pysqlite_row_new; + pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; + pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence; + return PyType_Ready(&pysqlite_RowType); +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/row.h b/contrib/tools/python3/src/Modules/_sqlite/row.h index 4ad506f8dd9..0c9e5860714 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/row.h +++ b/contrib/tools/python3/src/Modules/_sqlite/row.h @@ -1,40 +1,40 @@ -/* row.h - an enhanced tuple for database rows - * - * Copyright (C) 2005-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PYSQLITE_ROW_H -#define PYSQLITE_ROW_H +/* row.h - an enhanced tuple for database rows + * + * Copyright (C) 2005-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PYSQLITE_ROW_H +#define PYSQLITE_ROW_H #define PY_SSIZE_T_CLEAN -#include "Python.h" - -typedef struct _Row -{ - PyObject_HEAD - PyObject* data; - PyObject* description; -} pysqlite_Row; - -extern PyTypeObject pysqlite_RowType; - -int pysqlite_row_setup_types(void); - -#endif +#include "Python.h" + +typedef struct _Row +{ + PyObject_HEAD + PyObject* data; + PyObject* description; +} pysqlite_Row; + +extern PyTypeObject pysqlite_RowType; + +int pysqlite_row_setup_types(void); + +#endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/statement.c b/contrib/tools/python3/src/Modules/_sqlite/statement.c index 23c204e7521..382046b6da2 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/statement.c +++ b/contrib/tools/python3/src/Modules/_sqlite/statement.c @@ -1,507 +1,507 @@ -/* statement.c - the statement type - * - * Copyright (C) 2005-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "statement.h" -#include "cursor.h" -#include "connection.h" -#include "microprotocols.h" -#include "prepare_protocol.h" -#include "util.h" - -/* prototypes */ -static int pysqlite_check_remaining_sql(const char* tail); - -typedef enum { - LINECOMMENT_1, - IN_LINECOMMENT, - COMMENTSTART_1, - IN_COMMENT, - COMMENTEND_1, - NORMAL -} parse_remaining_sql_state; - -typedef enum { - TYPE_LONG, - TYPE_FLOAT, - TYPE_UNICODE, - TYPE_BUFFER, - TYPE_UNKNOWN -} parameter_type; - -int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql) -{ - const char* tail; - int rc; - const char* sql_cstr; - Py_ssize_t sql_cstr_len; - const char* p; - - self->st = NULL; - self->in_use = 0; - +/* statement.c - the statement type + * + * Copyright (C) 2005-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "statement.h" +#include "cursor.h" +#include "connection.h" +#include "microprotocols.h" +#include "prepare_protocol.h" +#include "util.h" + +/* prototypes */ +static int pysqlite_check_remaining_sql(const char* tail); + +typedef enum { + LINECOMMENT_1, + IN_LINECOMMENT, + COMMENTSTART_1, + IN_COMMENT, + COMMENTEND_1, + NORMAL +} parse_remaining_sql_state; + +typedef enum { + TYPE_LONG, + TYPE_FLOAT, + TYPE_UNICODE, + TYPE_BUFFER, + TYPE_UNKNOWN +} parameter_type; + +int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql) +{ + const char* tail; + int rc; + const char* sql_cstr; + Py_ssize_t sql_cstr_len; + const char* p; + + self->st = NULL; + self->in_use = 0; + assert(PyUnicode_Check(sql)); - sql_cstr = PyUnicode_AsUTF8AndSize(sql, &sql_cstr_len); - if (sql_cstr == NULL) { - rc = PYSQLITE_SQL_WRONG_TYPE; - return rc; - } - if (strlen(sql_cstr) != (size_t)sql_cstr_len) { - PyErr_SetString(PyExc_ValueError, "the query contains a null character"); - return PYSQLITE_SQL_WRONG_TYPE; - } - - self->in_weakreflist = NULL; - Py_INCREF(sql); - self->sql = sql; - - /* Determine if the statement is a DML statement. - SELECT is the only exception. See #9924. */ - self->is_dml = 0; - for (p = sql_cstr; *p != 0; p++) { - switch (*p) { - case ' ': - case '\r': - case '\n': - case '\t': - continue; - } - - self->is_dml = (PyOS_strnicmp(p, "insert", 6) == 0) - || (PyOS_strnicmp(p, "update", 6) == 0) - || (PyOS_strnicmp(p, "delete", 6) == 0) - || (PyOS_strnicmp(p, "replace", 7) == 0); - break; - } - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(connection->db, - sql_cstr, - -1, - &self->st, - &tail); - Py_END_ALLOW_THREADS - - self->db = connection->db; - - if (rc == SQLITE_OK && pysqlite_check_remaining_sql(tail)) { - (void)sqlite3_finalize(self->st); - self->st = NULL; - rc = PYSQLITE_TOO_MUCH_SQL; - } - - return rc; -} - -int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) -{ - int rc = SQLITE_OK; - const char *string; - Py_ssize_t buflen; - parameter_type paramtype; - - if (parameter == Py_None) { - rc = sqlite3_bind_null(self->st, pos); - goto final; - } - - if (PyLong_CheckExact(parameter)) { - paramtype = TYPE_LONG; - } else if (PyFloat_CheckExact(parameter)) { - paramtype = TYPE_FLOAT; - } else if (PyUnicode_CheckExact(parameter)) { - paramtype = TYPE_UNICODE; - } else if (PyLong_Check(parameter)) { - paramtype = TYPE_LONG; - } else if (PyFloat_Check(parameter)) { - paramtype = TYPE_FLOAT; - } else if (PyUnicode_Check(parameter)) { - paramtype = TYPE_UNICODE; - } else if (PyObject_CheckBuffer(parameter)) { - paramtype = TYPE_BUFFER; - } else { - paramtype = TYPE_UNKNOWN; - } - - switch (paramtype) { - case TYPE_LONG: { - sqlite_int64 value = _pysqlite_long_as_int64(parameter); - if (value == -1 && PyErr_Occurred()) - rc = -1; - else - rc = sqlite3_bind_int64(self->st, pos, value); - break; - } - case TYPE_FLOAT: - rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); - break; - case TYPE_UNICODE: - string = PyUnicode_AsUTF8AndSize(parameter, &buflen); - if (string == NULL) - return -1; - if (buflen > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "string longer than INT_MAX bytes"); - return -1; - } - rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT); - break; - case TYPE_BUFFER: { - Py_buffer view; - if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) { - PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); - return -1; - } - if (view.len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "BLOB longer than INT_MAX bytes"); - PyBuffer_Release(&view); - return -1; - } - rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT); - PyBuffer_Release(&view); - break; - } - case TYPE_UNKNOWN: - rc = -1; - } - -final: - return rc; -} - -/* returns 0 if the object is one of Python's internal ones that don't need to be adapted */ -static int _need_adapt(PyObject* obj) -{ - if (pysqlite_BaseTypeAdapted) { - return 1; - } - - if (PyLong_CheckExact(obj) || PyFloat_CheckExact(obj) - || PyUnicode_CheckExact(obj) || PyByteArray_CheckExact(obj)) { - return 0; - } else { - return 1; - } -} - -void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters) -{ - PyObject* current_param; - PyObject* adapted; - const char* binding_name; - int i; - int rc; - int num_params_needed; - Py_ssize_t num_params; - - Py_BEGIN_ALLOW_THREADS - num_params_needed = sqlite3_bind_parameter_count(self->st); - Py_END_ALLOW_THREADS - - if (PyTuple_CheckExact(parameters) || PyList_CheckExact(parameters) || (!PyDict_Check(parameters) && PySequence_Check(parameters))) { - /* parameters passed as sequence */ - if (PyTuple_CheckExact(parameters)) { - num_params = PyTuple_GET_SIZE(parameters); - } else if (PyList_CheckExact(parameters)) { - num_params = PyList_GET_SIZE(parameters); - } else { - num_params = PySequence_Size(parameters); + sql_cstr = PyUnicode_AsUTF8AndSize(sql, &sql_cstr_len); + if (sql_cstr == NULL) { + rc = PYSQLITE_SQL_WRONG_TYPE; + return rc; + } + if (strlen(sql_cstr) != (size_t)sql_cstr_len) { + PyErr_SetString(PyExc_ValueError, "the query contains a null character"); + return PYSQLITE_SQL_WRONG_TYPE; + } + + self->in_weakreflist = NULL; + Py_INCREF(sql); + self->sql = sql; + + /* Determine if the statement is a DML statement. + SELECT is the only exception. See #9924. */ + self->is_dml = 0; + for (p = sql_cstr; *p != 0; p++) { + switch (*p) { + case ' ': + case '\r': + case '\n': + case '\t': + continue; + } + + self->is_dml = (PyOS_strnicmp(p, "insert", 6) == 0) + || (PyOS_strnicmp(p, "update", 6) == 0) + || (PyOS_strnicmp(p, "delete", 6) == 0) + || (PyOS_strnicmp(p, "replace", 7) == 0); + break; + } + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_prepare_v2(connection->db, + sql_cstr, + -1, + &self->st, + &tail); + Py_END_ALLOW_THREADS + + self->db = connection->db; + + if (rc == SQLITE_OK && pysqlite_check_remaining_sql(tail)) { + (void)sqlite3_finalize(self->st); + self->st = NULL; + rc = PYSQLITE_TOO_MUCH_SQL; + } + + return rc; +} + +int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) +{ + int rc = SQLITE_OK; + const char *string; + Py_ssize_t buflen; + parameter_type paramtype; + + if (parameter == Py_None) { + rc = sqlite3_bind_null(self->st, pos); + goto final; + } + + if (PyLong_CheckExact(parameter)) { + paramtype = TYPE_LONG; + } else if (PyFloat_CheckExact(parameter)) { + paramtype = TYPE_FLOAT; + } else if (PyUnicode_CheckExact(parameter)) { + paramtype = TYPE_UNICODE; + } else if (PyLong_Check(parameter)) { + paramtype = TYPE_LONG; + } else if (PyFloat_Check(parameter)) { + paramtype = TYPE_FLOAT; + } else if (PyUnicode_Check(parameter)) { + paramtype = TYPE_UNICODE; + } else if (PyObject_CheckBuffer(parameter)) { + paramtype = TYPE_BUFFER; + } else { + paramtype = TYPE_UNKNOWN; + } + + switch (paramtype) { + case TYPE_LONG: { + sqlite_int64 value = _pysqlite_long_as_int64(parameter); + if (value == -1 && PyErr_Occurred()) + rc = -1; + else + rc = sqlite3_bind_int64(self->st, pos, value); + break; + } + case TYPE_FLOAT: + rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); + break; + case TYPE_UNICODE: + string = PyUnicode_AsUTF8AndSize(parameter, &buflen); + if (string == NULL) + return -1; + if (buflen > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "string longer than INT_MAX bytes"); + return -1; + } + rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT); + break; + case TYPE_BUFFER: { + Py_buffer view; + if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) { + PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); + return -1; + } + if (view.len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "BLOB longer than INT_MAX bytes"); + PyBuffer_Release(&view); + return -1; + } + rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT); + PyBuffer_Release(&view); + break; + } + case TYPE_UNKNOWN: + rc = -1; + } + +final: + return rc; +} + +/* returns 0 if the object is one of Python's internal ones that don't need to be adapted */ +static int _need_adapt(PyObject* obj) +{ + if (pysqlite_BaseTypeAdapted) { + return 1; + } + + if (PyLong_CheckExact(obj) || PyFloat_CheckExact(obj) + || PyUnicode_CheckExact(obj) || PyByteArray_CheckExact(obj)) { + return 0; + } else { + return 1; + } +} + +void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters) +{ + PyObject* current_param; + PyObject* adapted; + const char* binding_name; + int i; + int rc; + int num_params_needed; + Py_ssize_t num_params; + + Py_BEGIN_ALLOW_THREADS + num_params_needed = sqlite3_bind_parameter_count(self->st); + Py_END_ALLOW_THREADS + + if (PyTuple_CheckExact(parameters) || PyList_CheckExact(parameters) || (!PyDict_Check(parameters) && PySequence_Check(parameters))) { + /* parameters passed as sequence */ + if (PyTuple_CheckExact(parameters)) { + num_params = PyTuple_GET_SIZE(parameters); + } else if (PyList_CheckExact(parameters)) { + num_params = PyList_GET_SIZE(parameters); + } else { + num_params = PySequence_Size(parameters); if (num_params == -1) { return; } - } - if (num_params != num_params_needed) { - PyErr_Format(pysqlite_ProgrammingError, - "Incorrect number of bindings supplied. The current " - "statement uses %d, and there are %zd supplied.", - num_params_needed, num_params); - return; - } - for (i = 0; i < num_params; i++) { - if (PyTuple_CheckExact(parameters)) { - current_param = PyTuple_GET_ITEM(parameters, i); + } + if (num_params != num_params_needed) { + PyErr_Format(pysqlite_ProgrammingError, + "Incorrect number of bindings supplied. The current " + "statement uses %d, and there are %zd supplied.", + num_params_needed, num_params); + return; + } + for (i = 0; i < num_params; i++) { + if (PyTuple_CheckExact(parameters)) { + current_param = PyTuple_GET_ITEM(parameters, i); Py_INCREF(current_param); - } else if (PyList_CheckExact(parameters)) { + } else if (PyList_CheckExact(parameters)) { current_param = PyList_GetItem(parameters, i); - Py_XINCREF(current_param); - } else { - current_param = PySequence_GetItem(parameters, i); - } - if (!current_param) { - return; - } - - if (!_need_adapt(current_param)) { - adapted = current_param; - } else { + Py_XINCREF(current_param); + } else { + current_param = PySequence_GetItem(parameters, i); + } + if (!current_param) { + return; + } + + if (!_need_adapt(current_param)) { + adapted = current_param; + } else { adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; - } - } - - rc = pysqlite_statement_bind_parameter(self, i + 1, adapted); - Py_DECREF(adapted); - - if (rc != SQLITE_OK) { - if (!PyErr_Occurred()) { - PyErr_Format(pysqlite_InterfaceError, "Error binding parameter %d - probably unsupported type.", i); - } - return; - } - } - } else if (PyDict_Check(parameters)) { - /* parameters passed as dictionary */ - for (i = 1; i <= num_params_needed; i++) { + } + } + + rc = pysqlite_statement_bind_parameter(self, i + 1, adapted); + Py_DECREF(adapted); + + if (rc != SQLITE_OK) { + if (!PyErr_Occurred()) { + PyErr_Format(pysqlite_InterfaceError, "Error binding parameter %d - probably unsupported type.", i); + } + return; + } + } + } else if (PyDict_Check(parameters)) { + /* parameters passed as dictionary */ + for (i = 1; i <= num_params_needed; i++) { PyObject *binding_name_obj; - Py_BEGIN_ALLOW_THREADS - binding_name = sqlite3_bind_parameter_name(self->st, i); - Py_END_ALLOW_THREADS - if (!binding_name) { - PyErr_Format(pysqlite_ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i); - return; - } - - binding_name++; /* skip first char (the colon) */ + Py_BEGIN_ALLOW_THREADS + binding_name = sqlite3_bind_parameter_name(self->st, i); + Py_END_ALLOW_THREADS + if (!binding_name) { + PyErr_Format(pysqlite_ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i); + return; + } + + binding_name++; /* skip first char (the colon) */ binding_name_obj = PyUnicode_FromString(binding_name); if (!binding_name_obj) { return; } - if (PyDict_CheckExact(parameters)) { + if (PyDict_CheckExact(parameters)) { current_param = PyDict_GetItemWithError(parameters, binding_name_obj); - Py_XINCREF(current_param); - } else { + Py_XINCREF(current_param); + } else { current_param = PyObject_GetItem(parameters, binding_name_obj); - } + } Py_DECREF(binding_name_obj); - if (!current_param) { + if (!current_param) { if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) { PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i); } - return; - } - - if (!_need_adapt(current_param)) { - adapted = current_param; - } else { + return; + } + + if (!_need_adapt(current_param)) { + adapted = current_param; + } else { adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; - } - } - - rc = pysqlite_statement_bind_parameter(self, i, adapted); - Py_DECREF(adapted); - - if (rc != SQLITE_OK) { - if (!PyErr_Occurred()) { - PyErr_Format(pysqlite_InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name); - } - return; - } - } - } else { - PyErr_SetString(PyExc_ValueError, "parameters are of unsupported type"); - } -} - -int pysqlite_statement_finalize(pysqlite_Statement* self) -{ - int rc; - - rc = SQLITE_OK; - if (self->st) { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_finalize(self->st); - Py_END_ALLOW_THREADS - self->st = NULL; - } - - self->in_use = 0; - - return rc; -} - -int pysqlite_statement_reset(pysqlite_Statement* self) -{ - int rc; - - rc = SQLITE_OK; - - if (self->in_use && self->st) { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_reset(self->st); - Py_END_ALLOW_THREADS - - if (rc == SQLITE_OK) { - self->in_use = 0; - } - } - - return rc; -} - -void pysqlite_statement_mark_dirty(pysqlite_Statement* self) -{ - self->in_use = 1; -} - -void pysqlite_statement_dealloc(pysqlite_Statement* self) -{ - if (self->st) { - Py_BEGIN_ALLOW_THREADS - sqlite3_finalize(self->st); - Py_END_ALLOW_THREADS - } - - self->st = NULL; - - Py_XDECREF(self->sql); - - if (self->in_weakreflist != NULL) { - PyObject_ClearWeakRefs((PyObject*)self); - } - - Py_TYPE(self)->tp_free((PyObject*)self); -} - -/* - * Checks if there is anything left in an SQL string after SQLite compiled it. - * This is used to check if somebody tried to execute more than one SQL command - * with one execute()/executemany() command, which the DB-API and we don't - * allow. - * - * Returns 1 if there is more left than should be. 0 if ok. - */ -static int pysqlite_check_remaining_sql(const char* tail) -{ - const char* pos = tail; - - parse_remaining_sql_state state = NORMAL; - - for (;;) { - switch (*pos) { - case 0: - return 0; - case '-': - if (state == NORMAL) { - state = LINECOMMENT_1; - } else if (state == LINECOMMENT_1) { - state = IN_LINECOMMENT; - } - break; - case ' ': - case '\t': - break; - case '\n': - case 13: - if (state == IN_LINECOMMENT) { - state = NORMAL; - } - break; - case '/': - if (state == NORMAL) { - state = COMMENTSTART_1; - } else if (state == COMMENTEND_1) { - state = NORMAL; - } else if (state == COMMENTSTART_1) { - return 1; - } - break; - case '*': - if (state == NORMAL) { - return 1; - } else if (state == LINECOMMENT_1) { - return 1; - } else if (state == COMMENTSTART_1) { - state = IN_COMMENT; - } else if (state == IN_COMMENT) { - state = COMMENTEND_1; - } - break; - default: - if (state == COMMENTEND_1) { - state = IN_COMMENT; - } else if (state == IN_LINECOMMENT) { - } else if (state == IN_COMMENT) { - } else { - return 1; - } - } - - pos++; - } - - return 0; -} - -PyTypeObject pysqlite_StatementType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Statement", /* tp_name */ - sizeof(pysqlite_Statement), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_statement_dealloc, /* tp_dealloc */ + } + } + + rc = pysqlite_statement_bind_parameter(self, i, adapted); + Py_DECREF(adapted); + + if (rc != SQLITE_OK) { + if (!PyErr_Occurred()) { + PyErr_Format(pysqlite_InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name); + } + return; + } + } + } else { + PyErr_SetString(PyExc_ValueError, "parameters are of unsupported type"); + } +} + +int pysqlite_statement_finalize(pysqlite_Statement* self) +{ + int rc; + + rc = SQLITE_OK; + if (self->st) { + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_finalize(self->st); + Py_END_ALLOW_THREADS + self->st = NULL; + } + + self->in_use = 0; + + return rc; +} + +int pysqlite_statement_reset(pysqlite_Statement* self) +{ + int rc; + + rc = SQLITE_OK; + + if (self->in_use && self->st) { + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_reset(self->st); + Py_END_ALLOW_THREADS + + if (rc == SQLITE_OK) { + self->in_use = 0; + } + } + + return rc; +} + +void pysqlite_statement_mark_dirty(pysqlite_Statement* self) +{ + self->in_use = 1; +} + +void pysqlite_statement_dealloc(pysqlite_Statement* self) +{ + if (self->st) { + Py_BEGIN_ALLOW_THREADS + sqlite3_finalize(self->st); + Py_END_ALLOW_THREADS + } + + self->st = NULL; + + Py_XDECREF(self->sql); + + if (self->in_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*)self); + } + + Py_TYPE(self)->tp_free((PyObject*)self); +} + +/* + * Checks if there is anything left in an SQL string after SQLite compiled it. + * This is used to check if somebody tried to execute more than one SQL command + * with one execute()/executemany() command, which the DB-API and we don't + * allow. + * + * Returns 1 if there is more left than should be. 0 if ok. + */ +static int pysqlite_check_remaining_sql(const char* tail) +{ + const char* pos = tail; + + parse_remaining_sql_state state = NORMAL; + + for (;;) { + switch (*pos) { + case 0: + return 0; + case '-': + if (state == NORMAL) { + state = LINECOMMENT_1; + } else if (state == LINECOMMENT_1) { + state = IN_LINECOMMENT; + } + break; + case ' ': + case '\t': + break; + case '\n': + case 13: + if (state == IN_LINECOMMENT) { + state = NORMAL; + } + break; + case '/': + if (state == NORMAL) { + state = COMMENTSTART_1; + } else if (state == COMMENTEND_1) { + state = NORMAL; + } else if (state == COMMENTSTART_1) { + return 1; + } + break; + case '*': + if (state == NORMAL) { + return 1; + } else if (state == LINECOMMENT_1) { + return 1; + } else if (state == COMMENTSTART_1) { + state = IN_COMMENT; + } else if (state == IN_COMMENT) { + state = COMMENTEND_1; + } + break; + default: + if (state == COMMENTEND_1) { + state = IN_COMMENT; + } else if (state == IN_LINECOMMENT) { + } else if (state == IN_COMMENT) { + } else { + return 1; + } + } + + pos++; + } + + return 0; +} + +PyTypeObject pysqlite_StatementType = { + PyVarObject_HEAD_INIT(NULL, 0) + MODULE_NAME ".Statement", /* tp_name */ + sizeof(pysqlite_Statement), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pysqlite_statement_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Statement, in_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ -}; - -extern int pysqlite_statement_setup_types(void) -{ - pysqlite_StatementType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_StatementType); -} + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(pysqlite_Statement, in_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0 /* tp_free */ +}; + +extern int pysqlite_statement_setup_types(void) +{ + pysqlite_StatementType.tp_new = PyType_GenericNew; + return PyType_Ready(&pysqlite_StatementType); +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/statement.h b/contrib/tools/python3/src/Modules/_sqlite/statement.h index 5002f02dc5b..52d5c4f823d 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/statement.h +++ b/contrib/tools/python3/src/Modules/_sqlite/statement.h @@ -1,60 +1,60 @@ -/* statement.h - definitions for the statement type - * - * Copyright (C) 2005-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PYSQLITE_STATEMENT_H -#define PYSQLITE_STATEMENT_H +/* statement.h - definitions for the statement type + * + * Copyright (C) 2005-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PYSQLITE_STATEMENT_H +#define PYSQLITE_STATEMENT_H #define PY_SSIZE_T_CLEAN -#include "Python.h" - -#include "connection.h" -#include "sqlite3.h" - -#define PYSQLITE_TOO_MUCH_SQL (-100) -#define PYSQLITE_SQL_WRONG_TYPE (-101) - -typedef struct -{ - PyObject_HEAD - sqlite3* db; - sqlite3_stmt* st; - PyObject* sql; - int in_use; - int is_dml; - PyObject* in_weakreflist; /* List of weak references */ -} pysqlite_Statement; - -extern PyTypeObject pysqlite_StatementType; - -int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql); -void pysqlite_statement_dealloc(pysqlite_Statement* self); - -int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter); -void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters); - -int pysqlite_statement_finalize(pysqlite_Statement* self); -int pysqlite_statement_reset(pysqlite_Statement* self); -void pysqlite_statement_mark_dirty(pysqlite_Statement* self); - -int pysqlite_statement_setup_types(void); - -#endif +#include "Python.h" + +#include "connection.h" +#include "sqlite3.h" + +#define PYSQLITE_TOO_MUCH_SQL (-100) +#define PYSQLITE_SQL_WRONG_TYPE (-101) + +typedef struct +{ + PyObject_HEAD + sqlite3* db; + sqlite3_stmt* st; + PyObject* sql; + int in_use; + int is_dml; + PyObject* in_weakreflist; /* List of weak references */ +} pysqlite_Statement; + +extern PyTypeObject pysqlite_StatementType; + +int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql); +void pysqlite_statement_dealloc(pysqlite_Statement* self); + +int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter); +void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters); + +int pysqlite_statement_finalize(pysqlite_Statement* self); +int pysqlite_statement_reset(pysqlite_Statement* self); +void pysqlite_statement_mark_dirty(pysqlite_Statement* self); + +int pysqlite_statement_setup_types(void); + +#endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/util.c b/contrib/tools/python3/src/Modules/_sqlite/util.c index 1dbabcdd94a..4501b3c7181 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/util.c +++ b/contrib/tools/python3/src/Modules/_sqlite/util.c @@ -1,130 +1,130 @@ -/* util.c - various utility functions - * - * Copyright (C) 2005-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "module.h" -#include "connection.h" - -int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection) -{ - int rc; - - if (statement == NULL) { - /* this is a workaround for SQLite 3.5 and later. it now apparently - * returns NULL for "no-operation" statements */ - rc = SQLITE_OK; - } else { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_step(statement); - Py_END_ALLOW_THREADS - } - - return rc; -} - -/** - * Checks the SQLite error code and sets the appropriate DB-API exception. - * Returns the error code (0 means no error occurred). - */ -int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st) -{ - int errorcode = sqlite3_errcode(db); - - switch (errorcode) - { - case SQLITE_OK: - PyErr_Clear(); - break; - case SQLITE_INTERNAL: - case SQLITE_NOTFOUND: - PyErr_SetString(pysqlite_InternalError, sqlite3_errmsg(db)); - break; - case SQLITE_NOMEM: - (void)PyErr_NoMemory(); - break; - case SQLITE_ERROR: - case SQLITE_PERM: - case SQLITE_ABORT: - case SQLITE_BUSY: - case SQLITE_LOCKED: - case SQLITE_READONLY: - case SQLITE_INTERRUPT: - case SQLITE_IOERR: - case SQLITE_FULL: - case SQLITE_CANTOPEN: - case SQLITE_PROTOCOL: - case SQLITE_EMPTY: - case SQLITE_SCHEMA: - PyErr_SetString(pysqlite_OperationalError, sqlite3_errmsg(db)); - break; - case SQLITE_CORRUPT: - PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db)); - break; - case SQLITE_TOOBIG: - PyErr_SetString(pysqlite_DataError, sqlite3_errmsg(db)); - break; - case SQLITE_CONSTRAINT: - case SQLITE_MISMATCH: - PyErr_SetString(pysqlite_IntegrityError, sqlite3_errmsg(db)); - break; - case SQLITE_MISUSE: - PyErr_SetString(pysqlite_ProgrammingError, sqlite3_errmsg(db)); - break; - default: - PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db)); - break; - } - - return errorcode; -} - -#ifdef WORDS_BIGENDIAN -# define IS_LITTLE_ENDIAN 0 -#else -# define IS_LITTLE_ENDIAN 1 -#endif - -sqlite_int64 -_pysqlite_long_as_int64(PyObject * py_val) -{ - int overflow; - long long value = PyLong_AsLongLongAndOverflow(py_val, &overflow); - if (value == -1 && PyErr_Occurred()) - return -1; - if (!overflow) { -# if SIZEOF_LONG_LONG > 8 - if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL) -# endif - return value; - } - else if (sizeof(value) < sizeof(sqlite_int64)) { - sqlite_int64 int64val; - if (_PyLong_AsByteArray((PyLongObject *)py_val, - (unsigned char *)&int64val, sizeof(int64val), - IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) { - return int64val; - } - } - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to SQLite INTEGER"); - return -1; -} +/* util.c - various utility functions + * + * Copyright (C) 2005-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "module.h" +#include "connection.h" + +int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection) +{ + int rc; + + if (statement == NULL) { + /* this is a workaround for SQLite 3.5 and later. it now apparently + * returns NULL for "no-operation" statements */ + rc = SQLITE_OK; + } else { + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_step(statement); + Py_END_ALLOW_THREADS + } + + return rc; +} + +/** + * Checks the SQLite error code and sets the appropriate DB-API exception. + * Returns the error code (0 means no error occurred). + */ +int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st) +{ + int errorcode = sqlite3_errcode(db); + + switch (errorcode) + { + case SQLITE_OK: + PyErr_Clear(); + break; + case SQLITE_INTERNAL: + case SQLITE_NOTFOUND: + PyErr_SetString(pysqlite_InternalError, sqlite3_errmsg(db)); + break; + case SQLITE_NOMEM: + (void)PyErr_NoMemory(); + break; + case SQLITE_ERROR: + case SQLITE_PERM: + case SQLITE_ABORT: + case SQLITE_BUSY: + case SQLITE_LOCKED: + case SQLITE_READONLY: + case SQLITE_INTERRUPT: + case SQLITE_IOERR: + case SQLITE_FULL: + case SQLITE_CANTOPEN: + case SQLITE_PROTOCOL: + case SQLITE_EMPTY: + case SQLITE_SCHEMA: + PyErr_SetString(pysqlite_OperationalError, sqlite3_errmsg(db)); + break; + case SQLITE_CORRUPT: + PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db)); + break; + case SQLITE_TOOBIG: + PyErr_SetString(pysqlite_DataError, sqlite3_errmsg(db)); + break; + case SQLITE_CONSTRAINT: + case SQLITE_MISMATCH: + PyErr_SetString(pysqlite_IntegrityError, sqlite3_errmsg(db)); + break; + case SQLITE_MISUSE: + PyErr_SetString(pysqlite_ProgrammingError, sqlite3_errmsg(db)); + break; + default: + PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db)); + break; + } + + return errorcode; +} + +#ifdef WORDS_BIGENDIAN +# define IS_LITTLE_ENDIAN 0 +#else +# define IS_LITTLE_ENDIAN 1 +#endif + +sqlite_int64 +_pysqlite_long_as_int64(PyObject * py_val) +{ + int overflow; + long long value = PyLong_AsLongLongAndOverflow(py_val, &overflow); + if (value == -1 && PyErr_Occurred()) + return -1; + if (!overflow) { +# if SIZEOF_LONG_LONG > 8 + if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL) +# endif + return value; + } + else if (sizeof(value) < sizeof(sqlite_int64)) { + sqlite_int64 int64val; + if (_PyLong_AsByteArray((PyLongObject *)py_val, + (unsigned char *)&int64val, sizeof(int64val), + IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) { + return int64val; + } + } + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to SQLite INTEGER"); + return -1; +} diff --git a/contrib/tools/python3/src/Modules/_sqlite/util.h b/contrib/tools/python3/src/Modules/_sqlite/util.h index c5a220e9b0a..a3e01e24462 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/util.h +++ b/contrib/tools/python3/src/Modules/_sqlite/util.h @@ -1,48 +1,48 @@ -/* util.h - various utility functions - * - * Copyright (C) 2005-2010 Gerhard Häring - * - * This file is part of pysqlite. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#ifndef PYSQLITE_UTIL_H -#define PYSQLITE_UTIL_H +/* util.h - various utility functions + * + * Copyright (C) 2005-2010 Gerhard Häring + * + * This file is part of pysqlite. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef PYSQLITE_UTIL_H +#define PYSQLITE_UTIL_H #define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "pythread.h" -#include "sqlite3.h" -#include "connection.h" - -int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection); - -/** - * Checks the SQLite error code and sets the appropriate DB-API exception. - * Returns the error code (0 means no error occurred). - */ -int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st); - -sqlite_int64 _pysqlite_long_as_int64(PyObject * value); - -#if SQLITE_VERSION_NUMBER >= 3007014 -#define SQLITE3_CLOSE sqlite3_close_v2 -#else -#define SQLITE3_CLOSE sqlite3_close -#endif - -#endif +#include "Python.h" +#include "pythread.h" +#include "sqlite3.h" +#include "connection.h" + +int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection); + +/** + * Checks the SQLite error code and sets the appropriate DB-API exception. + * Returns the error code (0 means no error occurred). + */ +int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st); + +sqlite_int64 _pysqlite_long_as_int64(PyObject * value); + +#if SQLITE_VERSION_NUMBER >= 3007014 +#define SQLITE3_CLOSE sqlite3_close_v2 +#else +#define SQLITE3_CLOSE sqlite3_close +#endif + +#endif diff --git a/contrib/tools/python3/src/Modules/_sqlite/ya.make b/contrib/tools/python3/src/Modules/_sqlite/ya.make index 44f7188be0c..f0d6ca9c4d3 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/ya.make +++ b/contrib/tools/python3/src/Modules/_sqlite/ya.make @@ -1,46 +1,46 @@ -LIBRARY() - -OWNER(g:contrib orivej) - -LICENSE(Python-2.0) - -PEERDIR( - contrib/libs/sqlite3 -) - -ADDINCL( - contrib/libs/sqlite3 -) - -IF (USE_SYSTEM_PYTHON) - # Prevent configure error when arcadia python is a tool in a system python graph. - ADDINCL( - contrib/tools/python3/src/Include - ) -ENDIF() - +LIBRARY() + +OWNER(g:contrib orivej) + +LICENSE(Python-2.0) + +PEERDIR( + contrib/libs/sqlite3 +) + +ADDINCL( + contrib/libs/sqlite3 +) + +IF (USE_SYSTEM_PYTHON) + # Prevent configure error when arcadia python is a tool in a system python graph. + ADDINCL( + contrib/tools/python3/src/Include + ) +ENDIF() + CFLAGS( -DMODULE_NAME=\"sqlite3\" ) -PYTHON3_ADDINCL() - -NO_COMPILER_WARNINGS() - -NO_RUNTIME() - -SRCS( - cache.c - connection.c - cursor.c - microprotocols.c - module.c - prepare_protocol.c - row.c - statement.c - util.c -) - -PY_REGISTER(_sqlite3) - -END() +PYTHON3_ADDINCL() + +NO_COMPILER_WARNINGS() + +NO_RUNTIME() + +SRCS( + cache.c + connection.c + cursor.c + microprotocols.c + module.c + prepare_protocol.c + row.c + statement.c + util.c +) + +PY_REGISTER(_sqlite3) + +END() diff --git a/contrib/tools/python3/src/Modules/_sre.c b/contrib/tools/python3/src/Modules/_sre.c index 8225c36da1a..3450ac9186a 100644 --- a/contrib/tools/python3/src/Modules/_sre.c +++ b/contrib/tools/python3/src/Modules/_sre.c @@ -1,1952 +1,1952 @@ -/* - * Secret Labs' Regular Expression Engine - * - * regular expression matching engine - * - * partial history: - * 1999-10-24 fl created (based on existing template matcher code) - * 2000-03-06 fl first alpha, sort of - * 2000-08-01 fl fixes for 1.6b1 - * 2000-08-07 fl use PyOS_CheckStack() if available - * 2000-09-20 fl added expand method - * 2001-03-20 fl lots of fixes for 2.1b2 - * 2001-04-15 fl export copyright as Python attribute, not global - * 2001-04-28 fl added __copy__ methods (work in progress) - * 2001-05-14 fl fixes for 1.5.2 compatibility - * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis) - * 2001-10-18 fl fixed group reset issue (from Matthew Mueller) +/* + * Secret Labs' Regular Expression Engine + * + * regular expression matching engine + * + * partial history: + * 1999-10-24 fl created (based on existing template matcher code) + * 2000-03-06 fl first alpha, sort of + * 2000-08-01 fl fixes for 1.6b1 + * 2000-08-07 fl use PyOS_CheckStack() if available + * 2000-09-20 fl added expand method + * 2001-03-20 fl lots of fixes for 2.1b2 + * 2001-04-15 fl export copyright as Python attribute, not global + * 2001-04-28 fl added __copy__ methods (work in progress) + * 2001-05-14 fl fixes for 1.5.2 compatibility + * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis) + * 2001-10-18 fl fixed group reset issue (from Matthew Mueller) * 2001-10-20 fl added split primitive; re-enable unicode for 1.6/2.0/2.1 - * 2001-10-21 fl added sub/subn primitive - * 2001-10-24 fl added finditer primitive (for 2.2 only) - * 2001-12-07 fl fixed memory leak in sub/subn (Guido van Rossum) - * 2002-11-09 fl fixed empty sub/subn return type - * 2003-04-18 mvl fully support 4-byte codes - * 2003-10-17 gn implemented non recursive scheme - * 2013-02-04 mrab added fullmatch primitive - * - * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. - * - * This version of the SRE library can be redistributed under CNRI's - * Python 1.6 license. For any other use, please contact Secret Labs - * AB (info@pythonware.com). - * - * Portions of this engine have been developed in cooperation with - * CNRI. Hewlett-Packard provided funding for 1.6 integration and - * other compatibility work. - */ - -static const char copyright[] = - " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB "; - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" -#include "structmember.h" // PyMemberDef - -#include "sre.h" - -#define SRE_CODE_BITS (8 * sizeof(SRE_CODE)) - -#include - -/* name of this module, minus the leading underscore */ -#if !defined(SRE_MODULE) -#define SRE_MODULE "sre" -#endif - -#define SRE_PY_MODULE "re" - -/* defining this one enables tracing */ -#undef VERBOSE - -/* -------------------------------------------------------------------- */ - -#if defined(_MSC_VER) -#pragma optimize("agtw", on) /* doesn't seem to make much difference... */ -#pragma warning(disable: 4710) /* who cares if functions are not inlined ;-) */ -/* fastest possible local call under MSVC */ -#define LOCAL(type) static __inline type __fastcall -#else -#define LOCAL(type) static inline type -#endif - -/* error codes */ -#define SRE_ERROR_ILLEGAL -1 /* illegal opcode */ -#define SRE_ERROR_STATE -2 /* illegal state */ -#define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */ -#define SRE_ERROR_MEMORY -9 /* out of memory */ -#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */ - -#if defined(VERBOSE) -#define TRACE(v) printf v -#else -#define TRACE(v) -#endif - -/* -------------------------------------------------------------------- */ -/* search engine state */ - -#define SRE_IS_DIGIT(ch)\ - ((ch) <= '9' && Py_ISDIGIT(ch)) -#define SRE_IS_SPACE(ch)\ - ((ch) <= ' ' && Py_ISSPACE(ch)) -#define SRE_IS_LINEBREAK(ch)\ - ((ch) == '\n') -#define SRE_IS_WORD(ch)\ - ((ch) <= 'z' && (Py_ISALNUM(ch) || (ch) == '_')) - -static unsigned int sre_lower_ascii(unsigned int ch) -{ - return ((ch) < 128 ? Py_TOLOWER(ch) : ch); -} - -/* locale-specific character predicates */ -/* !(c & ~N) == (c < N+1) for any unsigned c, this avoids - * warnings when c's type supports only numbers < N+1 */ -#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0) -#define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_') - -static unsigned int sre_lower_locale(unsigned int ch) -{ - return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch); -} - -static unsigned int sre_upper_locale(unsigned int ch) -{ - return ((ch) < 256 ? (unsigned int)toupper((ch)) : ch); -} - -/* unicode-specific character predicates */ - -#define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDECIMAL(ch) -#define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE(ch) -#define SRE_UNI_IS_LINEBREAK(ch) Py_UNICODE_ISLINEBREAK(ch) -#define SRE_UNI_IS_ALNUM(ch) Py_UNICODE_ISALNUM(ch) -#define SRE_UNI_IS_WORD(ch) (SRE_UNI_IS_ALNUM(ch) || (ch) == '_') - -static unsigned int sre_lower_unicode(unsigned int ch) -{ - return (unsigned int) Py_UNICODE_TOLOWER(ch); -} - -static unsigned int sre_upper_unicode(unsigned int ch) -{ - return (unsigned int) Py_UNICODE_TOUPPER(ch); -} - -LOCAL(int) -sre_category(SRE_CODE category, unsigned int ch) -{ - switch (category) { - - case SRE_CATEGORY_DIGIT: - return SRE_IS_DIGIT(ch); - case SRE_CATEGORY_NOT_DIGIT: - return !SRE_IS_DIGIT(ch); - case SRE_CATEGORY_SPACE: - return SRE_IS_SPACE(ch); - case SRE_CATEGORY_NOT_SPACE: - return !SRE_IS_SPACE(ch); - case SRE_CATEGORY_WORD: - return SRE_IS_WORD(ch); - case SRE_CATEGORY_NOT_WORD: - return !SRE_IS_WORD(ch); - case SRE_CATEGORY_LINEBREAK: - return SRE_IS_LINEBREAK(ch); - case SRE_CATEGORY_NOT_LINEBREAK: - return !SRE_IS_LINEBREAK(ch); - - case SRE_CATEGORY_LOC_WORD: - return SRE_LOC_IS_WORD(ch); - case SRE_CATEGORY_LOC_NOT_WORD: - return !SRE_LOC_IS_WORD(ch); - - case SRE_CATEGORY_UNI_DIGIT: - return SRE_UNI_IS_DIGIT(ch); - case SRE_CATEGORY_UNI_NOT_DIGIT: - return !SRE_UNI_IS_DIGIT(ch); - case SRE_CATEGORY_UNI_SPACE: - return SRE_UNI_IS_SPACE(ch); - case SRE_CATEGORY_UNI_NOT_SPACE: - return !SRE_UNI_IS_SPACE(ch); - case SRE_CATEGORY_UNI_WORD: - return SRE_UNI_IS_WORD(ch); - case SRE_CATEGORY_UNI_NOT_WORD: - return !SRE_UNI_IS_WORD(ch); - case SRE_CATEGORY_UNI_LINEBREAK: - return SRE_UNI_IS_LINEBREAK(ch); - case SRE_CATEGORY_UNI_NOT_LINEBREAK: - return !SRE_UNI_IS_LINEBREAK(ch); - } - return 0; -} - -LOCAL(int) -char_loc_ignore(SRE_CODE pattern, SRE_CODE ch) -{ - return ch == pattern - || (SRE_CODE) sre_lower_locale(ch) == pattern - || (SRE_CODE) sre_upper_locale(ch) == pattern; -} - - -/* helpers */ - -static void -data_stack_dealloc(SRE_STATE* state) -{ - if (state->data_stack) { - PyMem_FREE(state->data_stack); - state->data_stack = NULL; - } - state->data_stack_size = state->data_stack_base = 0; -} - -static int -data_stack_grow(SRE_STATE* state, Py_ssize_t size) -{ - Py_ssize_t minsize, cursize; - minsize = state->data_stack_base+size; - cursize = state->data_stack_size; - if (cursize < minsize) { - void* stack; - cursize = minsize+minsize/4+1024; - TRACE(("allocate/grow stack %" PY_FORMAT_SIZE_T "d\n", cursize)); - stack = PyMem_REALLOC(state->data_stack, cursize); - if (!stack) { - data_stack_dealloc(state); - return SRE_ERROR_MEMORY; - } - state->data_stack = (char *)stack; - state->data_stack_size = cursize; - } - return 0; -} - -/* generate 8-bit version */ - -#define SRE_CHAR Py_UCS1 -#define SIZEOF_SRE_CHAR 1 -#define SRE(F) sre_ucs1_##F -#include "sre_lib.h" - -/* generate 16-bit unicode version */ - -#define SRE_CHAR Py_UCS2 -#define SIZEOF_SRE_CHAR 2 -#define SRE(F) sre_ucs2_##F -#include "sre_lib.h" - -/* generate 32-bit unicode version */ - -#define SRE_CHAR Py_UCS4 -#define SIZEOF_SRE_CHAR 4 -#define SRE(F) sre_ucs4_##F -#include "sre_lib.h" - -/* -------------------------------------------------------------------- */ -/* factories and destructors */ - -/* see sre.h for object declarations */ -static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, Py_ssize_t); -static PyObject *pattern_scanner(PatternObject *, PyObject *, Py_ssize_t, Py_ssize_t); - - -/*[clinic input] -module _sre -class _sre.SRE_Pattern "PatternObject *" "&Pattern_Type" -class _sre.SRE_Match "MatchObject *" "&Match_Type" -class _sre.SRE_Scanner "ScannerObject *" "&Scanner_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0230ec19a0deac8]*/ - -static PyTypeObject Pattern_Type; -static PyTypeObject Match_Type; -static PyTypeObject Scanner_Type; - -/*[clinic input] -_sre.getcodesize -> int -[clinic start generated code]*/ - -static int -_sre_getcodesize_impl(PyObject *module) -/*[clinic end generated code: output=e0db7ce34a6dd7b1 input=bd6f6ecf4916bb2b]*/ -{ - return sizeof(SRE_CODE); -} - -/*[clinic input] -_sre.ascii_iscased -> bool - - character: int - / - -[clinic start generated code]*/ - -static int -_sre_ascii_iscased_impl(PyObject *module, int character) -/*[clinic end generated code: output=4f454b630fbd19a2 input=9f0bd952812c7ed3]*/ -{ - unsigned int ch = (unsigned int)character; - return ch < 128 && Py_ISALPHA(ch); -} - -/*[clinic input] -_sre.unicode_iscased -> bool - - character: int - / - -[clinic start generated code]*/ - -static int -_sre_unicode_iscased_impl(PyObject *module, int character) -/*[clinic end generated code: output=9c5ddee0dc2bc258 input=51e42c3b8dddb78e]*/ -{ - unsigned int ch = (unsigned int)character; - return ch != sre_lower_unicode(ch) || ch != sre_upper_unicode(ch); -} - -/*[clinic input] -_sre.ascii_tolower -> int - - character: int - / - -[clinic start generated code]*/ - -static int -_sre_ascii_tolower_impl(PyObject *module, int character) -/*[clinic end generated code: output=228294ed6ff2a612 input=272c609b5b61f136]*/ -{ - return sre_lower_ascii(character); -} - -/*[clinic input] -_sre.unicode_tolower -> int - - character: int - / - -[clinic start generated code]*/ - -static int -_sre_unicode_tolower_impl(PyObject *module, int character) -/*[clinic end generated code: output=6422272d7d7fee65 input=91d708c5f3c2045a]*/ -{ - return sre_lower_unicode(character); -} - -LOCAL(void) -state_reset(SRE_STATE* state) -{ - /* state->mark will be set to 0 in SRE_OP_MARK dynamically. */ - /*memset(state->mark, 0, sizeof(*state->mark) * SRE_MARK_SIZE);*/ - - state->lastmark = -1; - state->lastindex = -1; - - state->repeat = NULL; - - data_stack_dealloc(state); -} - -static const void* -getstring(PyObject* string, Py_ssize_t* p_length, - int* p_isbytes, int* p_charsize, - Py_buffer *view) -{ - /* given a python object, return a data pointer, a length (in - characters), and a character size. return NULL if the object - is not a string (or not compatible) */ - - /* Unicode objects do not support the buffer API. So, get the data - directly instead. */ - if (PyUnicode_Check(string)) { - if (PyUnicode_READY(string) == -1) - return NULL; - *p_length = PyUnicode_GET_LENGTH(string); - *p_charsize = PyUnicode_KIND(string); - *p_isbytes = 0; - return PyUnicode_DATA(string); - } - - /* get pointer to byte string buffer */ - if (PyObject_GetBuffer(string, view, PyBUF_SIMPLE) != 0) { - PyErr_SetString(PyExc_TypeError, "expected string or bytes-like object"); - return NULL; - } - - *p_length = view->len; - *p_charsize = 1; - *p_isbytes = 1; - - if (view->buf == NULL) { - PyErr_SetString(PyExc_ValueError, "Buffer is NULL"); - PyBuffer_Release(view); - view->buf = NULL; - return NULL; - } - return view->buf; -} - -LOCAL(PyObject*) -state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, - Py_ssize_t start, Py_ssize_t end) -{ - /* prepare state object */ - - Py_ssize_t length; - int isbytes, charsize; - const void* ptr; - - memset(state, 0, sizeof(SRE_STATE)); - - state->mark = PyMem_New(const void *, pattern->groups * 2); - if (!state->mark) { - PyErr_NoMemory(); - goto err; - } - state->lastmark = -1; - state->lastindex = -1; - - state->buffer.buf = NULL; - ptr = getstring(string, &length, &isbytes, &charsize, &state->buffer); - if (!ptr) - goto err; - - if (isbytes && pattern->isbytes == 0) { - PyErr_SetString(PyExc_TypeError, - "cannot use a string pattern on a bytes-like object"); - goto err; - } - if (!isbytes && pattern->isbytes > 0) { - PyErr_SetString(PyExc_TypeError, - "cannot use a bytes pattern on a string-like object"); - goto err; - } - - /* adjust boundaries */ - if (start < 0) - start = 0; - else if (start > length) - start = length; - - if (end < 0) - end = 0; - else if (end > length) - end = length; - - state->isbytes = isbytes; - state->charsize = charsize; - state->match_all = 0; - state->must_advance = 0; - - state->beginning = ptr; - - state->start = (void*) ((char*) ptr + start * state->charsize); - state->end = (void*) ((char*) ptr + end * state->charsize); - - Py_INCREF(string); - state->string = string; - state->pos = start; - state->endpos = end; - - return string; - err: - /* We add an explicit cast here because MSVC has a bug when - compiling C code where it believes that `const void**` cannot be - safely casted to `void*`, see bpo-39943 for details. */ - PyMem_Del((void*) state->mark); - state->mark = NULL; - if (state->buffer.buf) - PyBuffer_Release(&state->buffer); - return NULL; -} - -LOCAL(void) -state_fini(SRE_STATE* state) -{ - if (state->buffer.buf) - PyBuffer_Release(&state->buffer); - Py_XDECREF(state->string); - data_stack_dealloc(state); - /* See above PyMem_Del for why we explicitly cast here. */ - PyMem_Del((void*) state->mark); - state->mark = NULL; -} - -/* calculate offset from start of string */ -#define STATE_OFFSET(state, member)\ - (((char*)(member) - (char*)(state)->beginning) / (state)->charsize) - -LOCAL(PyObject*) -getslice(int isbytes, const void *ptr, - PyObject* string, Py_ssize_t start, Py_ssize_t end) -{ - if (isbytes) { - if (PyBytes_CheckExact(string) && - start == 0 && end == PyBytes_GET_SIZE(string)) { - Py_INCREF(string); - return string; - } - return PyBytes_FromStringAndSize( - (const char *)ptr + start, end - start); - } - else { - return PyUnicode_Substring(string, start, end); - } -} - -LOCAL(PyObject*) -state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty) -{ - Py_ssize_t i, j; - - index = (index - 1) * 2; - - if (string == Py_None || index >= state->lastmark || !state->mark[index] || !state->mark[index+1]) { - if (empty) - /* want empty string */ - i = j = 0; - else { - Py_RETURN_NONE; - } - } else { - i = STATE_OFFSET(state, state->mark[index]); - j = STATE_OFFSET(state, state->mark[index+1]); - } - - return getslice(state->isbytes, state->beginning, string, i, j); -} - -static void -pattern_error(Py_ssize_t status) -{ - switch (status) { - case SRE_ERROR_RECURSION_LIMIT: - /* This error code seems to be unused. */ - PyErr_SetString( - PyExc_RecursionError, - "maximum recursion limit exceeded" - ); - break; - case SRE_ERROR_MEMORY: - PyErr_NoMemory(); - break; - case SRE_ERROR_INTERRUPTED: - /* An exception has already been raised, so let it fly */ - break; - default: - /* other error codes indicate compiler/engine bugs */ - PyErr_SetString( - PyExc_RuntimeError, - "internal error in regular expression engine" - ); - } -} - -static void -pattern_dealloc(PatternObject* self) -{ - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_XDECREF(self->pattern); - Py_XDECREF(self->groupindex); - Py_XDECREF(self->indexgroup); - PyObject_DEL(self); -} - -LOCAL(Py_ssize_t) -sre_match(SRE_STATE* state, SRE_CODE* pattern) -{ - if (state->charsize == 1) - return sre_ucs1_match(state, pattern, 1); - if (state->charsize == 2) - return sre_ucs2_match(state, pattern, 1); - assert(state->charsize == 4); - return sre_ucs4_match(state, pattern, 1); -} - -LOCAL(Py_ssize_t) -sre_search(SRE_STATE* state, SRE_CODE* pattern) -{ - if (state->charsize == 1) - return sre_ucs1_search(state, pattern); - if (state->charsize == 2) - return sre_ucs2_search(state, pattern); - assert(state->charsize == 4); - return sre_ucs4_search(state, pattern); -} - -/*[clinic input] -_sre.SRE_Pattern.match - - string: object - pos: Py_ssize_t = 0 - endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize - -Matches zero or more characters at the beginning of the string. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=ea2d838888510661 input=a2ba191647abebe5]*/ -{ - SRE_STATE state; - Py_ssize_t status; - PyObject *match; - - if (!state_init(&state, (PatternObject *)self, string, pos, endpos)) - return NULL; - - state.ptr = state.start; - - TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr)); - - status = sre_match(&state, PatternObject_GetCode(self)); - - TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - if (PyErr_Occurred()) { - state_fini(&state); - return NULL; - } - - match = pattern_new_match(self, &state, status); - state_fini(&state); - return match; -} - -/*[clinic input] -_sre.SRE_Pattern.fullmatch - - string: object - pos: Py_ssize_t = 0 - endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize - -Matches against all of the string. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=5833c47782a35f4a input=d9fb03a7625b5828]*/ -{ - SRE_STATE state; - Py_ssize_t status; - PyObject *match; - - if (!state_init(&state, self, string, pos, endpos)) - return NULL; - - state.ptr = state.start; - - TRACE(("|%p|%p|FULLMATCH\n", PatternObject_GetCode(self), state.ptr)); - - state.match_all = 1; - status = sre_match(&state, PatternObject_GetCode(self)); - - TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - if (PyErr_Occurred()) { - state_fini(&state); - return NULL; - } - - match = pattern_new_match(self, &state, status); - state_fini(&state); - return match; -} - -/*[clinic input] -_sre.SRE_Pattern.search - - string: object - pos: Py_ssize_t = 0 - endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize - -Scan through string looking for a match, and return a corresponding match object instance. - -Return None if no position in the string matches. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=25f302a644e951e8 input=4ae5cb7dc38fed1b]*/ -{ - SRE_STATE state; - Py_ssize_t status; - PyObject *match; - - if (!state_init(&state, self, string, pos, endpos)) - return NULL; - - TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr)); - - status = sre_search(&state, PatternObject_GetCode(self)); - - TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - - if (PyErr_Occurred()) { - state_fini(&state); - return NULL; - } - - match = pattern_new_match(self, &state, status); - state_fini(&state); - return match; -} - -static PyObject* -call(const char* module, const char* function, PyObject* args) -{ - PyObject* name; - PyObject* mod; - PyObject* func; - PyObject* result; - - if (!args) - return NULL; - name = PyUnicode_FromString(module); - if (!name) - return NULL; - mod = PyImport_Import(name); - Py_DECREF(name); - if (!mod) - return NULL; - func = PyObject_GetAttrString(mod, function); - Py_DECREF(mod); - if (!func) - return NULL; - result = PyObject_CallObject(func, args); - Py_DECREF(func); - Py_DECREF(args); - return result; -} - -/*[clinic input] -_sre.SRE_Pattern.findall - - string: object - pos: Py_ssize_t = 0 - endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize - -Return a list of all non-overlapping matches of pattern in string. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_findall_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=f4966baceea60aca input=5b6a4ee799741563]*/ -{ - SRE_STATE state; - PyObject* list; - Py_ssize_t status; - Py_ssize_t i, b, e; - - if (!state_init(&state, self, string, pos, endpos)) - return NULL; - - list = PyList_New(0); - if (!list) { - state_fini(&state); - return NULL; - } - - while (state.start <= state.end) { - - PyObject* item; - - state_reset(&state); - - state.ptr = state.start; - - status = sre_search(&state, PatternObject_GetCode(self)); - if (PyErr_Occurred()) - goto error; - - if (status <= 0) { - if (status == 0) - break; - pattern_error(status); - goto error; - } - - /* don't bother to build a match object */ - switch (self->groups) { - case 0: - b = STATE_OFFSET(&state, state.start); - e = STATE_OFFSET(&state, state.ptr); - item = getslice(state.isbytes, state.beginning, - string, b, e); - if (!item) - goto error; - break; - case 1: - item = state_getslice(&state, 1, string, 1); - if (!item) - goto error; - break; - default: - item = PyTuple_New(self->groups); - if (!item) - goto error; - for (i = 0; i < self->groups; i++) { - PyObject* o = state_getslice(&state, i+1, string, 1); - if (!o) { - Py_DECREF(item); - goto error; - } - PyTuple_SET_ITEM(item, i, o); - } - break; - } - - status = PyList_Append(list, item); - Py_DECREF(item); - if (status < 0) - goto error; - - state.must_advance = (state.ptr == state.start); - state.start = state.ptr; - } - - state_fini(&state); - return list; - -error: - Py_DECREF(list); - state_fini(&state); - return NULL; - -} - -/*[clinic input] -_sre.SRE_Pattern.finditer - - string: object - pos: Py_ssize_t = 0 - endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize - -Return an iterator over all non-overlapping matches for the RE pattern in string. - -For each match, the iterator returns a match object. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=0bbb1a0aeb38bb14 input=612aab69e9fe08e4]*/ -{ - PyObject* scanner; - PyObject* search; - PyObject* iterator; - - scanner = pattern_scanner(self, string, pos, endpos); - if (!scanner) - return NULL; - - search = PyObject_GetAttrString(scanner, "search"); - Py_DECREF(scanner); - if (!search) - return NULL; - - iterator = PyCallIter_New(search, Py_None); - Py_DECREF(search); - - return iterator; -} - -/*[clinic input] -_sre.SRE_Pattern.scanner - - string: object - pos: Py_ssize_t = 0 - endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos) -/*[clinic end generated code: output=54ea548aed33890b input=3aacdbde77a3a637]*/ -{ - return pattern_scanner(self, string, pos, endpos); -} - -/*[clinic input] -_sre.SRE_Pattern.split - - string: object - maxsplit: Py_ssize_t = 0 - -Split string by the occurrences of pattern. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string, - Py_ssize_t maxsplit) -/*[clinic end generated code: output=7ac66f381c45e0be input=1eeeb10dafc9947a]*/ -{ - SRE_STATE state; - PyObject* list; - PyObject* item; - Py_ssize_t status; - Py_ssize_t n; - Py_ssize_t i; - const void* last; - - assert(self->codesize != 0); - - if (!state_init(&state, self, string, 0, PY_SSIZE_T_MAX)) - return NULL; - - list = PyList_New(0); - if (!list) { - state_fini(&state); - return NULL; - } - - n = 0; - last = state.start; - - while (!maxsplit || n < maxsplit) { - - state_reset(&state); - - state.ptr = state.start; - - status = sre_search(&state, PatternObject_GetCode(self)); - if (PyErr_Occurred()) - goto error; - - if (status <= 0) { - if (status == 0) - break; - pattern_error(status); - goto error; - } - - /* get segment before this match */ - item = getslice(state.isbytes, state.beginning, - string, STATE_OFFSET(&state, last), - STATE_OFFSET(&state, state.start) - ); - if (!item) - goto error; - status = PyList_Append(list, item); - Py_DECREF(item); - if (status < 0) - goto error; - - /* add groups (if any) */ - for (i = 0; i < self->groups; i++) { - item = state_getslice(&state, i+1, string, 0); - if (!item) - goto error; - status = PyList_Append(list, item); - Py_DECREF(item); - if (status < 0) - goto error; - } - - n = n + 1; - state.must_advance = (state.ptr == state.start); - last = state.start = state.ptr; - - } - - /* get segment following last match (even if empty) */ - item = getslice(state.isbytes, state.beginning, - string, STATE_OFFSET(&state, last), state.endpos - ); - if (!item) - goto error; - status = PyList_Append(list, item); - Py_DECREF(item); - if (status < 0) - goto error; - - state_fini(&state); - return list; - -error: - Py_DECREF(list); - state_fini(&state); - return NULL; - -} - -static PyObject* -pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, - Py_ssize_t count, Py_ssize_t subn) -{ - SRE_STATE state; - PyObject* list; - PyObject* joiner; - PyObject* item; - PyObject* filter; - PyObject* match; - const void* ptr; - Py_ssize_t status; - Py_ssize_t n; - Py_ssize_t i, b, e; - int isbytes, charsize; - int filter_is_callable; - Py_buffer view; - - if (PyCallable_Check(ptemplate)) { - /* sub/subn takes either a function or a template */ - filter = ptemplate; - Py_INCREF(filter); - filter_is_callable = 1; - } else { - /* if not callable, check if it's a literal string */ - int literal; - view.buf = NULL; - ptr = getstring(ptemplate, &n, &isbytes, &charsize, &view); - if (ptr) { - if (charsize == 1) - literal = memchr(ptr, '\\', n) == NULL; - else - literal = PyUnicode_FindChar(ptemplate, '\\', 0, n, 1) == -1; - } else { - PyErr_Clear(); - literal = 0; - } - if (view.buf) - PyBuffer_Release(&view); - if (literal) { - filter = ptemplate; - Py_INCREF(filter); - filter_is_callable = 0; - } else { - /* not a literal; hand it over to the template compiler */ - filter = call( - SRE_PY_MODULE, "_subx", - PyTuple_Pack(2, self, ptemplate) - ); - if (!filter) - return NULL; - filter_is_callable = PyCallable_Check(filter); - } - } - - if (!state_init(&state, self, string, 0, PY_SSIZE_T_MAX)) { - Py_DECREF(filter); - return NULL; - } - - list = PyList_New(0); - if (!list) { - Py_DECREF(filter); - state_fini(&state); - return NULL; - } - - n = i = 0; - - while (!count || n < count) { - - state_reset(&state); - - state.ptr = state.start; - - status = sre_search(&state, PatternObject_GetCode(self)); - if (PyErr_Occurred()) - goto error; - - if (status <= 0) { - if (status == 0) - break; - pattern_error(status); - goto error; - } - - b = STATE_OFFSET(&state, state.start); - e = STATE_OFFSET(&state, state.ptr); - - if (i < b) { - /* get segment before this match */ - item = getslice(state.isbytes, state.beginning, - string, i, b); - if (!item) - goto error; - status = PyList_Append(list, item); - Py_DECREF(item); - if (status < 0) - goto error; - - } - - if (filter_is_callable) { - /* pass match object through filter */ - match = pattern_new_match(self, &state, 1); - if (!match) - goto error; - item = PyObject_CallOneArg(filter, match); - Py_DECREF(match); - if (!item) - goto error; - } else { - /* filter is literal string */ - item = filter; - Py_INCREF(item); - } - - /* add to list */ - if (item != Py_None) { - status = PyList_Append(list, item); - Py_DECREF(item); - if (status < 0) - goto error; - } - - i = e; - n = n + 1; - state.must_advance = (state.ptr == state.start); - state.start = state.ptr; - } - - /* get segment following last match */ - if (i < state.endpos) { - item = getslice(state.isbytes, state.beginning, - string, i, state.endpos); - if (!item) - goto error; - status = PyList_Append(list, item); - Py_DECREF(item); - if (status < 0) - goto error; - } - - state_fini(&state); - - Py_DECREF(filter); - - /* convert list to single string (also removes list) */ - joiner = getslice(state.isbytes, state.beginning, string, 0, 0); - if (!joiner) { - Py_DECREF(list); - return NULL; - } - if (PyList_GET_SIZE(list) == 0) { - Py_DECREF(list); - item = joiner; - } - else { - if (state.isbytes) - item = _PyBytes_Join(joiner, list); - else - item = PyUnicode_Join(joiner, list); - Py_DECREF(joiner); - Py_DECREF(list); - if (!item) - return NULL; - } - - if (subn) - return Py_BuildValue("Nn", item, n); - - return item; - -error: - Py_DECREF(list); - state_fini(&state); - Py_DECREF(filter); - return NULL; - -} - -/*[clinic input] -_sre.SRE_Pattern.sub - - repl: object - string: object - count: Py_ssize_t = 0 - -Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_sub_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count) -/*[clinic end generated code: output=1dbf2ec3479cba00 input=c53d70be0b3caf86]*/ -{ - return pattern_subx(self, repl, string, count, 0); -} - -/*[clinic input] -_sre.SRE_Pattern.subn - - repl: object - string: object - count: Py_ssize_t = 0 - -Return the tuple (new_string, number_of_subs_made) found by replacing the leftmost non-overlapping occurrences of pattern with the replacement repl. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern_subn_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count) -/*[clinic end generated code: output=0d9522cd529e9728 input=e7342d7ce6083577]*/ -{ - return pattern_subx(self, repl, string, count, 1); -} - -/*[clinic input] -_sre.SRE_Pattern.__copy__ - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern___copy___impl(PatternObject *self) -/*[clinic end generated code: output=85dedc2db1bd8694 input=a730a59d863bc9f5]*/ -{ - Py_INCREF(self); - return (PyObject *)self; -} - -/*[clinic input] -_sre.SRE_Pattern.__deepcopy__ - - memo: object - / - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Pattern___deepcopy__(PatternObject *self, PyObject *memo) -/*[clinic end generated code: output=2ad25679c1f1204a input=a465b1602f997bed]*/ -{ - Py_INCREF(self); - return (PyObject *)self; -} - -static PyObject * -pattern_repr(PatternObject *obj) -{ - static const struct { - const char *name; - int value; - } flag_names[] = { - {"re.TEMPLATE", SRE_FLAG_TEMPLATE}, - {"re.IGNORECASE", SRE_FLAG_IGNORECASE}, - {"re.LOCALE", SRE_FLAG_LOCALE}, - {"re.MULTILINE", SRE_FLAG_MULTILINE}, - {"re.DOTALL", SRE_FLAG_DOTALL}, - {"re.UNICODE", SRE_FLAG_UNICODE}, - {"re.VERBOSE", SRE_FLAG_VERBOSE}, - {"re.DEBUG", SRE_FLAG_DEBUG}, - {"re.ASCII", SRE_FLAG_ASCII}, - }; - PyObject *result = NULL; - PyObject *flag_items; - size_t i; - int flags = obj->flags; - - /* Omit re.UNICODE for valid string patterns. */ - if (obj->isbytes == 0 && - (flags & (SRE_FLAG_LOCALE|SRE_FLAG_UNICODE|SRE_FLAG_ASCII)) == - SRE_FLAG_UNICODE) - flags &= ~SRE_FLAG_UNICODE; - - flag_items = PyList_New(0); - if (!flag_items) - return NULL; - - for (i = 0; i < Py_ARRAY_LENGTH(flag_names); i++) { - if (flags & flag_names[i].value) { - PyObject *item = PyUnicode_FromString(flag_names[i].name); - if (!item) - goto done; - - if (PyList_Append(flag_items, item) < 0) { - Py_DECREF(item); - goto done; - } - Py_DECREF(item); - flags &= ~flag_names[i].value; - } - } - if (flags) { - PyObject *item = PyUnicode_FromFormat("0x%x", flags); - if (!item) - goto done; - - if (PyList_Append(flag_items, item) < 0) { - Py_DECREF(item); - goto done; - } - Py_DECREF(item); - } - - if (PyList_Size(flag_items) > 0) { - PyObject *flags_result; - PyObject *sep = PyUnicode_FromString("|"); - if (!sep) - goto done; - flags_result = PyUnicode_Join(sep, flag_items); - Py_DECREF(sep); - if (!flags_result) - goto done; - result = PyUnicode_FromFormat("re.compile(%.200R, %S)", - obj->pattern, flags_result); - Py_DECREF(flags_result); - } - else { - result = PyUnicode_FromFormat("re.compile(%.200R)", obj->pattern); - } - -done: - Py_DECREF(flag_items); - return result; -} - -PyDoc_STRVAR(pattern_doc, "Compiled regular expression object."); - -/* PatternObject's 'groupindex' method. */ -static PyObject * -pattern_groupindex(PatternObject *self, void *Py_UNUSED(ignored)) -{ - if (self->groupindex == NULL) - return PyDict_New(); - return PyDictProxy_New(self->groupindex); -} - -static int _validate(PatternObject *self); /* Forward */ - -/*[clinic input] -_sre.compile - - pattern: object - flags: int - code: object(subclass_of='&PyList_Type') - groups: Py_ssize_t - groupindex: object(subclass_of='&PyDict_Type') - indexgroup: object(subclass_of='&PyTuple_Type') - -[clinic start generated code]*/ - -static PyObject * -_sre_compile_impl(PyObject *module, PyObject *pattern, int flags, - PyObject *code, Py_ssize_t groups, PyObject *groupindex, - PyObject *indexgroup) -/*[clinic end generated code: output=ef9c2b3693776404 input=0a68476dbbe5db30]*/ -{ - /* "compile" pattern descriptor to pattern object */ - - PatternObject* self; - Py_ssize_t i, n; - - n = PyList_GET_SIZE(code); - /* coverity[ampersand_in_size] */ - self = PyObject_NewVar(PatternObject, &Pattern_Type, n); - if (!self) - return NULL; - self->weakreflist = NULL; - self->pattern = NULL; - self->groupindex = NULL; - self->indexgroup = NULL; - - self->codesize = n; - - for (i = 0; i < n; i++) { - PyObject *o = PyList_GET_ITEM(code, i); - unsigned long value = PyLong_AsUnsignedLong(o); - self->code[i] = (SRE_CODE) value; - if ((unsigned long) self->code[i] != value) { - PyErr_SetString(PyExc_OverflowError, - "regular expression code size limit exceeded"); - break; - } - } - - if (PyErr_Occurred()) { - Py_DECREF(self); - return NULL; - } - - if (pattern == Py_None) { - self->isbytes = -1; - } - else { - Py_ssize_t p_length; - int charsize; - Py_buffer view; - view.buf = NULL; - if (!getstring(pattern, &p_length, &self->isbytes, - &charsize, &view)) { - Py_DECREF(self); - return NULL; - } - if (view.buf) - PyBuffer_Release(&view); - } - - Py_INCREF(pattern); - self->pattern = pattern; - - self->flags = flags; - - self->groups = groups; - - if (PyDict_GET_SIZE(groupindex) > 0) { - Py_INCREF(groupindex); - self->groupindex = groupindex; - if (PyTuple_GET_SIZE(indexgroup) > 0) { - Py_INCREF(indexgroup); - self->indexgroup = indexgroup; - } - } - - if (!_validate(self)) { - Py_DECREF(self); - return NULL; - } - - return (PyObject*) self; -} - -/* -------------------------------------------------------------------- */ -/* Code validation */ - -/* To learn more about this code, have a look at the _compile() function in - Lib/sre_compile.py. The validation functions below checks the code array - for conformance with the code patterns generated there. - - The nice thing about the generated code is that it is position-independent: - all jumps are relative jumps forward. Also, jumps don't cross each other: - the target of a later jump is always earlier than the target of an earlier - jump. IOW, this is okay: - - J---------J-------T--------T - \ \_____/ / - \______________________/ - - but this is not: - - J---------J-------T--------T - \_________\_____/ / - \____________/ - - It also helps that SRE_CODE is always an unsigned type. -*/ - -/* Defining this one enables tracing of the validator */ -#undef VVERBOSE - -/* Trace macro for the validator */ -#if defined(VVERBOSE) -#define VTRACE(v) printf v -#else -#define VTRACE(v) do {} while(0) /* do nothing */ -#endif - -/* Report failure */ -#define FAIL do { VTRACE(("FAIL: %d\n", __LINE__)); return 0; } while (0) - -/* Extract opcode, argument, or skip count from code array */ -#define GET_OP \ - do { \ - VTRACE(("%p: ", code)); \ - if (code >= end) FAIL; \ - op = *code++; \ - VTRACE(("%lu (op)\n", (unsigned long)op)); \ - } while (0) -#define GET_ARG \ - do { \ - VTRACE(("%p= ", code)); \ - if (code >= end) FAIL; \ - arg = *code++; \ - VTRACE(("%lu (arg)\n", (unsigned long)arg)); \ - } while (0) -#define GET_SKIP_ADJ(adj) \ - do { \ - VTRACE(("%p= ", code)); \ - if (code >= end) FAIL; \ - skip = *code; \ - VTRACE(("%lu (skip to %p)\n", \ - (unsigned long)skip, code+skip)); \ - if (skip-adj > (uintptr_t)(end - code)) \ - FAIL; \ - code++; \ - } while (0) -#define GET_SKIP GET_SKIP_ADJ(0) - -static int -_validate_charset(SRE_CODE *code, SRE_CODE *end) -{ - /* Some variables are manipulated by the macros above */ - SRE_CODE op; - SRE_CODE arg; - SRE_CODE offset; - int i; - - while (code < end) { - GET_OP; - switch (op) { - - case SRE_OP_NEGATE: - break; - - case SRE_OP_LITERAL: - GET_ARG; - break; - - case SRE_OP_RANGE: - case SRE_OP_RANGE_UNI_IGNORE: - GET_ARG; - GET_ARG; - break; - - case SRE_OP_CHARSET: - offset = 256/SRE_CODE_BITS; /* 256-bit bitmap */ - if (offset > (uintptr_t)(end - code)) - FAIL; - code += offset; - break; - - case SRE_OP_BIGCHARSET: - GET_ARG; /* Number of blocks */ - offset = 256/sizeof(SRE_CODE); /* 256-byte table */ - if (offset > (uintptr_t)(end - code)) - FAIL; - /* Make sure that each byte points to a valid block */ - for (i = 0; i < 256; i++) { - if (((unsigned char *)code)[i] >= arg) - FAIL; - } - code += offset; - offset = arg * (256/SRE_CODE_BITS); /* 256-bit bitmap times arg */ - if (offset > (uintptr_t)(end - code)) - FAIL; - code += offset; - break; - - case SRE_OP_CATEGORY: - GET_ARG; - switch (arg) { - case SRE_CATEGORY_DIGIT: - case SRE_CATEGORY_NOT_DIGIT: - case SRE_CATEGORY_SPACE: - case SRE_CATEGORY_NOT_SPACE: - case SRE_CATEGORY_WORD: - case SRE_CATEGORY_NOT_WORD: - case SRE_CATEGORY_LINEBREAK: - case SRE_CATEGORY_NOT_LINEBREAK: - case SRE_CATEGORY_LOC_WORD: - case SRE_CATEGORY_LOC_NOT_WORD: - case SRE_CATEGORY_UNI_DIGIT: - case SRE_CATEGORY_UNI_NOT_DIGIT: - case SRE_CATEGORY_UNI_SPACE: - case SRE_CATEGORY_UNI_NOT_SPACE: - case SRE_CATEGORY_UNI_WORD: - case SRE_CATEGORY_UNI_NOT_WORD: - case SRE_CATEGORY_UNI_LINEBREAK: - case SRE_CATEGORY_UNI_NOT_LINEBREAK: - break; - default: - FAIL; - } - break; - - default: - FAIL; - - } - } - - return 1; -} - -static int -_validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) -{ - /* Some variables are manipulated by the macros above */ - SRE_CODE op; - SRE_CODE arg; - SRE_CODE skip; - - VTRACE(("code=%p, end=%p\n", code, end)); - - if (code > end) - FAIL; - - while (code < end) { - GET_OP; - switch (op) { - - case SRE_OP_MARK: - /* We don't check whether marks are properly nested; the - sre_match() code is robust even if they don't, and the worst - you can get is nonsensical match results. */ - GET_ARG; - if (arg > 2 * (size_t)groups + 1) { - VTRACE(("arg=%d, groups=%d\n", (int)arg, (int)groups)); - FAIL; - } - break; - - case SRE_OP_LITERAL: - case SRE_OP_NOT_LITERAL: - case SRE_OP_LITERAL_IGNORE: - case SRE_OP_NOT_LITERAL_IGNORE: - case SRE_OP_LITERAL_UNI_IGNORE: - case SRE_OP_NOT_LITERAL_UNI_IGNORE: - case SRE_OP_LITERAL_LOC_IGNORE: - case SRE_OP_NOT_LITERAL_LOC_IGNORE: - GET_ARG; - /* The arg is just a character, nothing to check */ - break; - - case SRE_OP_SUCCESS: - case SRE_OP_FAILURE: - /* Nothing to check; these normally end the matching process */ - break; - - case SRE_OP_AT: - GET_ARG; - switch (arg) { - case SRE_AT_BEGINNING: - case SRE_AT_BEGINNING_STRING: - case SRE_AT_BEGINNING_LINE: - case SRE_AT_END: - case SRE_AT_END_LINE: - case SRE_AT_END_STRING: - case SRE_AT_BOUNDARY: - case SRE_AT_NON_BOUNDARY: - case SRE_AT_LOC_BOUNDARY: - case SRE_AT_LOC_NON_BOUNDARY: - case SRE_AT_UNI_BOUNDARY: - case SRE_AT_UNI_NON_BOUNDARY: - break; - default: - FAIL; - } - break; - - case SRE_OP_ANY: - case SRE_OP_ANY_ALL: - /* These have no operands */ - break; - - case SRE_OP_IN: - case SRE_OP_IN_IGNORE: - case SRE_OP_IN_UNI_IGNORE: - case SRE_OP_IN_LOC_IGNORE: - GET_SKIP; - /* Stop 1 before the end; we check the FAILURE below */ - if (!_validate_charset(code, code+skip-2)) - FAIL; - if (code[skip-2] != SRE_OP_FAILURE) - FAIL; - code += skip-1; - break; - - case SRE_OP_INFO: - { - /* A minimal info field is - <1=skip> <2=flags> <3=min> <4=max>; - If SRE_INFO_PREFIX or SRE_INFO_CHARSET is in the flags, - more follows. */ - SRE_CODE flags, i; - SRE_CODE *newcode; - GET_SKIP; - newcode = code+skip-1; - GET_ARG; flags = arg; - GET_ARG; - GET_ARG; - /* Check that only valid flags are present */ - if ((flags & ~(SRE_INFO_PREFIX | - SRE_INFO_LITERAL | - SRE_INFO_CHARSET)) != 0) - FAIL; - /* PREFIX and CHARSET are mutually exclusive */ - if ((flags & SRE_INFO_PREFIX) && - (flags & SRE_INFO_CHARSET)) - FAIL; - /* LITERAL implies PREFIX */ - if ((flags & SRE_INFO_LITERAL) && - !(flags & SRE_INFO_PREFIX)) - FAIL; - /* Validate the prefix */ - if (flags & SRE_INFO_PREFIX) { - SRE_CODE prefix_len; - GET_ARG; prefix_len = arg; - GET_ARG; - /* Here comes the prefix string */ - if (prefix_len > (uintptr_t)(newcode - code)) - FAIL; - code += prefix_len; - /* And here comes the overlap table */ - if (prefix_len > (uintptr_t)(newcode - code)) - FAIL; - /* Each overlap value should be < prefix_len */ - for (i = 0; i < prefix_len; i++) { - if (code[i] >= prefix_len) - FAIL; - } - code += prefix_len; - } - /* Validate the charset */ - if (flags & SRE_INFO_CHARSET) { - if (!_validate_charset(code, newcode-1)) - FAIL; - if (newcode[-1] != SRE_OP_FAILURE) - FAIL; - code = newcode; - } - else if (code != newcode) { - VTRACE(("code=%p, newcode=%p\n", code, newcode)); - FAIL; - } - } - break; - - case SRE_OP_BRANCH: - { - SRE_CODE *target = NULL; - for (;;) { - GET_SKIP; - if (skip == 0) - break; - /* Stop 2 before the end; we check the JUMP below */ - if (!_validate_inner(code, code+skip-3, groups)) - FAIL; - code += skip-3; - /* Check that it ends with a JUMP, and that each JUMP - has the same target */ - GET_OP; - if (op != SRE_OP_JUMP) - FAIL; - GET_SKIP; - if (target == NULL) - target = code+skip-1; - else if (code+skip-1 != target) - FAIL; - } - } - break; - - case SRE_OP_REPEAT_ONE: - case SRE_OP_MIN_REPEAT_ONE: - { - SRE_CODE min, max; - GET_SKIP; - GET_ARG; min = arg; - GET_ARG; max = arg; - if (min > max) - FAIL; - if (max > SRE_MAXREPEAT) - FAIL; - if (!_validate_inner(code, code+skip-4, groups)) - FAIL; - code += skip-4; - GET_OP; - if (op != SRE_OP_SUCCESS) - FAIL; - } - break; - - case SRE_OP_REPEAT: - { - SRE_CODE min, max; - GET_SKIP; - GET_ARG; min = arg; - GET_ARG; max = arg; - if (min > max) - FAIL; - if (max > SRE_MAXREPEAT) - FAIL; - if (!_validate_inner(code, code+skip-3, groups)) - FAIL; - code += skip-3; - GET_OP; - if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL) - FAIL; - } - break; - - case SRE_OP_GROUPREF: - case SRE_OP_GROUPREF_IGNORE: - case SRE_OP_GROUPREF_UNI_IGNORE: - case SRE_OP_GROUPREF_LOC_IGNORE: - GET_ARG; - if (arg >= (size_t)groups) - FAIL; - break; - - case SRE_OP_GROUPREF_EXISTS: - /* The regex syntax for this is: '(?(group)then|else)', where - 'group' is either an integer group number or a group name, - 'then' and 'else' are sub-regexes, and 'else' is optional. */ - GET_ARG; - if (arg >= (size_t)groups) - FAIL; - GET_SKIP_ADJ(1); - code--; /* The skip is relative to the first arg! */ - /* There are two possibilities here: if there is both a 'then' - part and an 'else' part, the generated code looks like: - - GROUPREF_EXISTS - - - ...then part... - JUMP - - ( jumps here) - ...else part... - ( jumps here) - - If there is only a 'then' part, it looks like: - - GROUPREF_EXISTS - - - ...then part... - ( jumps here) - - There is no direct way to decide which it is, and we don't want - to allow arbitrary jumps anywhere in the code; so we just look - for a JUMP opcode preceding our skip target. - */ - if (skip >= 3 && skip-3 < (uintptr_t)(end - code) && - code[skip-3] == SRE_OP_JUMP) - { - VTRACE(("both then and else parts present\n")); - if (!_validate_inner(code+1, code+skip-3, groups)) - FAIL; - code += skip-2; /* Position after JUMP, at */ - GET_SKIP; - if (!_validate_inner(code, code+skip-1, groups)) - FAIL; - code += skip-1; - } - else { - VTRACE(("only a then part present\n")); - if (!_validate_inner(code+1, code+skip-1, groups)) - FAIL; - code += skip-1; - } - break; - - case SRE_OP_ASSERT: - case SRE_OP_ASSERT_NOT: - GET_SKIP; - GET_ARG; /* 0 for lookahead, width for lookbehind */ - code--; /* Back up over arg to simplify math below */ - if (arg & 0x80000000) - FAIL; /* Width too large */ - /* Stop 1 before the end; we check the SUCCESS below */ - if (!_validate_inner(code+1, code+skip-2, groups)) - FAIL; - code += skip-2; - GET_OP; - if (op != SRE_OP_SUCCESS) - FAIL; - break; - - default: - FAIL; - - } - } - - VTRACE(("okay\n")); - return 1; -} - -static int -_validate_outer(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) -{ - if (groups < 0 || (size_t)groups > SRE_MAXGROUPS || - code >= end || end[-1] != SRE_OP_SUCCESS) - FAIL; - return _validate_inner(code, end-1, groups); -} - -static int -_validate(PatternObject *self) -{ - if (!_validate_outer(self->code, self->code+self->codesize, self->groups)) - { - PyErr_SetString(PyExc_RuntimeError, "invalid SRE code"); - return 0; - } - else - VTRACE(("Success!\n")); - return 1; -} - -/* -------------------------------------------------------------------- */ -/* match methods */ - -static void -match_dealloc(MatchObject* self) -{ - Py_XDECREF(self->regs); - Py_XDECREF(self->string); - Py_DECREF(self->pattern); - PyObject_DEL(self); -} - -static PyObject* -match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def) -{ - Py_ssize_t length; - int isbytes, charsize; - Py_buffer view; - PyObject *result; + * 2001-10-21 fl added sub/subn primitive + * 2001-10-24 fl added finditer primitive (for 2.2 only) + * 2001-12-07 fl fixed memory leak in sub/subn (Guido van Rossum) + * 2002-11-09 fl fixed empty sub/subn return type + * 2003-04-18 mvl fully support 4-byte codes + * 2003-10-17 gn implemented non recursive scheme + * 2013-02-04 mrab added fullmatch primitive + * + * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. + * + * This version of the SRE library can be redistributed under CNRI's + * Python 1.6 license. For any other use, please contact Secret Labs + * AB (info@pythonware.com). + * + * Portions of this engine have been developed in cooperation with + * CNRI. Hewlett-Packard provided funding for 1.6 integration and + * other compatibility work. + */ + +static const char copyright[] = + " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB "; + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "structmember.h" // PyMemberDef + +#include "sre.h" + +#define SRE_CODE_BITS (8 * sizeof(SRE_CODE)) + +#include + +/* name of this module, minus the leading underscore */ +#if !defined(SRE_MODULE) +#define SRE_MODULE "sre" +#endif + +#define SRE_PY_MODULE "re" + +/* defining this one enables tracing */ +#undef VERBOSE + +/* -------------------------------------------------------------------- */ + +#if defined(_MSC_VER) +#pragma optimize("agtw", on) /* doesn't seem to make much difference... */ +#pragma warning(disable: 4710) /* who cares if functions are not inlined ;-) */ +/* fastest possible local call under MSVC */ +#define LOCAL(type) static __inline type __fastcall +#else +#define LOCAL(type) static inline type +#endif + +/* error codes */ +#define SRE_ERROR_ILLEGAL -1 /* illegal opcode */ +#define SRE_ERROR_STATE -2 /* illegal state */ +#define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */ +#define SRE_ERROR_MEMORY -9 /* out of memory */ +#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */ + +#if defined(VERBOSE) +#define TRACE(v) printf v +#else +#define TRACE(v) +#endif + +/* -------------------------------------------------------------------- */ +/* search engine state */ + +#define SRE_IS_DIGIT(ch)\ + ((ch) <= '9' && Py_ISDIGIT(ch)) +#define SRE_IS_SPACE(ch)\ + ((ch) <= ' ' && Py_ISSPACE(ch)) +#define SRE_IS_LINEBREAK(ch)\ + ((ch) == '\n') +#define SRE_IS_WORD(ch)\ + ((ch) <= 'z' && (Py_ISALNUM(ch) || (ch) == '_')) + +static unsigned int sre_lower_ascii(unsigned int ch) +{ + return ((ch) < 128 ? Py_TOLOWER(ch) : ch); +} + +/* locale-specific character predicates */ +/* !(c & ~N) == (c < N+1) for any unsigned c, this avoids + * warnings when c's type supports only numbers < N+1 */ +#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0) +#define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_') + +static unsigned int sre_lower_locale(unsigned int ch) +{ + return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch); +} + +static unsigned int sre_upper_locale(unsigned int ch) +{ + return ((ch) < 256 ? (unsigned int)toupper((ch)) : ch); +} + +/* unicode-specific character predicates */ + +#define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDECIMAL(ch) +#define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE(ch) +#define SRE_UNI_IS_LINEBREAK(ch) Py_UNICODE_ISLINEBREAK(ch) +#define SRE_UNI_IS_ALNUM(ch) Py_UNICODE_ISALNUM(ch) +#define SRE_UNI_IS_WORD(ch) (SRE_UNI_IS_ALNUM(ch) || (ch) == '_') + +static unsigned int sre_lower_unicode(unsigned int ch) +{ + return (unsigned int) Py_UNICODE_TOLOWER(ch); +} + +static unsigned int sre_upper_unicode(unsigned int ch) +{ + return (unsigned int) Py_UNICODE_TOUPPER(ch); +} + +LOCAL(int) +sre_category(SRE_CODE category, unsigned int ch) +{ + switch (category) { + + case SRE_CATEGORY_DIGIT: + return SRE_IS_DIGIT(ch); + case SRE_CATEGORY_NOT_DIGIT: + return !SRE_IS_DIGIT(ch); + case SRE_CATEGORY_SPACE: + return SRE_IS_SPACE(ch); + case SRE_CATEGORY_NOT_SPACE: + return !SRE_IS_SPACE(ch); + case SRE_CATEGORY_WORD: + return SRE_IS_WORD(ch); + case SRE_CATEGORY_NOT_WORD: + return !SRE_IS_WORD(ch); + case SRE_CATEGORY_LINEBREAK: + return SRE_IS_LINEBREAK(ch); + case SRE_CATEGORY_NOT_LINEBREAK: + return !SRE_IS_LINEBREAK(ch); + + case SRE_CATEGORY_LOC_WORD: + return SRE_LOC_IS_WORD(ch); + case SRE_CATEGORY_LOC_NOT_WORD: + return !SRE_LOC_IS_WORD(ch); + + case SRE_CATEGORY_UNI_DIGIT: + return SRE_UNI_IS_DIGIT(ch); + case SRE_CATEGORY_UNI_NOT_DIGIT: + return !SRE_UNI_IS_DIGIT(ch); + case SRE_CATEGORY_UNI_SPACE: + return SRE_UNI_IS_SPACE(ch); + case SRE_CATEGORY_UNI_NOT_SPACE: + return !SRE_UNI_IS_SPACE(ch); + case SRE_CATEGORY_UNI_WORD: + return SRE_UNI_IS_WORD(ch); + case SRE_CATEGORY_UNI_NOT_WORD: + return !SRE_UNI_IS_WORD(ch); + case SRE_CATEGORY_UNI_LINEBREAK: + return SRE_UNI_IS_LINEBREAK(ch); + case SRE_CATEGORY_UNI_NOT_LINEBREAK: + return !SRE_UNI_IS_LINEBREAK(ch); + } + return 0; +} + +LOCAL(int) +char_loc_ignore(SRE_CODE pattern, SRE_CODE ch) +{ + return ch == pattern + || (SRE_CODE) sre_lower_locale(ch) == pattern + || (SRE_CODE) sre_upper_locale(ch) == pattern; +} + + +/* helpers */ + +static void +data_stack_dealloc(SRE_STATE* state) +{ + if (state->data_stack) { + PyMem_FREE(state->data_stack); + state->data_stack = NULL; + } + state->data_stack_size = state->data_stack_base = 0; +} + +static int +data_stack_grow(SRE_STATE* state, Py_ssize_t size) +{ + Py_ssize_t minsize, cursize; + minsize = state->data_stack_base+size; + cursize = state->data_stack_size; + if (cursize < minsize) { + void* stack; + cursize = minsize+minsize/4+1024; + TRACE(("allocate/grow stack %" PY_FORMAT_SIZE_T "d\n", cursize)); + stack = PyMem_REALLOC(state->data_stack, cursize); + if (!stack) { + data_stack_dealloc(state); + return SRE_ERROR_MEMORY; + } + state->data_stack = (char *)stack; + state->data_stack_size = cursize; + } + return 0; +} + +/* generate 8-bit version */ + +#define SRE_CHAR Py_UCS1 +#define SIZEOF_SRE_CHAR 1 +#define SRE(F) sre_ucs1_##F +#include "sre_lib.h" + +/* generate 16-bit unicode version */ + +#define SRE_CHAR Py_UCS2 +#define SIZEOF_SRE_CHAR 2 +#define SRE(F) sre_ucs2_##F +#include "sre_lib.h" + +/* generate 32-bit unicode version */ + +#define SRE_CHAR Py_UCS4 +#define SIZEOF_SRE_CHAR 4 +#define SRE(F) sre_ucs4_##F +#include "sre_lib.h" + +/* -------------------------------------------------------------------- */ +/* factories and destructors */ + +/* see sre.h for object declarations */ +static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, Py_ssize_t); +static PyObject *pattern_scanner(PatternObject *, PyObject *, Py_ssize_t, Py_ssize_t); + + +/*[clinic input] +module _sre +class _sre.SRE_Pattern "PatternObject *" "&Pattern_Type" +class _sre.SRE_Match "MatchObject *" "&Match_Type" +class _sre.SRE_Scanner "ScannerObject *" "&Scanner_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0230ec19a0deac8]*/ + +static PyTypeObject Pattern_Type; +static PyTypeObject Match_Type; +static PyTypeObject Scanner_Type; + +/*[clinic input] +_sre.getcodesize -> int +[clinic start generated code]*/ + +static int +_sre_getcodesize_impl(PyObject *module) +/*[clinic end generated code: output=e0db7ce34a6dd7b1 input=bd6f6ecf4916bb2b]*/ +{ + return sizeof(SRE_CODE); +} + +/*[clinic input] +_sre.ascii_iscased -> bool + + character: int + / + +[clinic start generated code]*/ + +static int +_sre_ascii_iscased_impl(PyObject *module, int character) +/*[clinic end generated code: output=4f454b630fbd19a2 input=9f0bd952812c7ed3]*/ +{ + unsigned int ch = (unsigned int)character; + return ch < 128 && Py_ISALPHA(ch); +} + +/*[clinic input] +_sre.unicode_iscased -> bool + + character: int + / + +[clinic start generated code]*/ + +static int +_sre_unicode_iscased_impl(PyObject *module, int character) +/*[clinic end generated code: output=9c5ddee0dc2bc258 input=51e42c3b8dddb78e]*/ +{ + unsigned int ch = (unsigned int)character; + return ch != sre_lower_unicode(ch) || ch != sre_upper_unicode(ch); +} + +/*[clinic input] +_sre.ascii_tolower -> int + + character: int + / + +[clinic start generated code]*/ + +static int +_sre_ascii_tolower_impl(PyObject *module, int character) +/*[clinic end generated code: output=228294ed6ff2a612 input=272c609b5b61f136]*/ +{ + return sre_lower_ascii(character); +} + +/*[clinic input] +_sre.unicode_tolower -> int + + character: int + / + +[clinic start generated code]*/ + +static int +_sre_unicode_tolower_impl(PyObject *module, int character) +/*[clinic end generated code: output=6422272d7d7fee65 input=91d708c5f3c2045a]*/ +{ + return sre_lower_unicode(character); +} + +LOCAL(void) +state_reset(SRE_STATE* state) +{ + /* state->mark will be set to 0 in SRE_OP_MARK dynamically. */ + /*memset(state->mark, 0, sizeof(*state->mark) * SRE_MARK_SIZE);*/ + + state->lastmark = -1; + state->lastindex = -1; + + state->repeat = NULL; + + data_stack_dealloc(state); +} + +static const void* +getstring(PyObject* string, Py_ssize_t* p_length, + int* p_isbytes, int* p_charsize, + Py_buffer *view) +{ + /* given a python object, return a data pointer, a length (in + characters), and a character size. return NULL if the object + is not a string (or not compatible) */ + + /* Unicode objects do not support the buffer API. So, get the data + directly instead. */ + if (PyUnicode_Check(string)) { + if (PyUnicode_READY(string) == -1) + return NULL; + *p_length = PyUnicode_GET_LENGTH(string); + *p_charsize = PyUnicode_KIND(string); + *p_isbytes = 0; + return PyUnicode_DATA(string); + } + + /* get pointer to byte string buffer */ + if (PyObject_GetBuffer(string, view, PyBUF_SIMPLE) != 0) { + PyErr_SetString(PyExc_TypeError, "expected string or bytes-like object"); + return NULL; + } + + *p_length = view->len; + *p_charsize = 1; + *p_isbytes = 1; + + if (view->buf == NULL) { + PyErr_SetString(PyExc_ValueError, "Buffer is NULL"); + PyBuffer_Release(view); + view->buf = NULL; + return NULL; + } + return view->buf; +} + +LOCAL(PyObject*) +state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, + Py_ssize_t start, Py_ssize_t end) +{ + /* prepare state object */ + + Py_ssize_t length; + int isbytes, charsize; const void* ptr; - Py_ssize_t i, j; - + + memset(state, 0, sizeof(SRE_STATE)); + + state->mark = PyMem_New(const void *, pattern->groups * 2); + if (!state->mark) { + PyErr_NoMemory(); + goto err; + } + state->lastmark = -1; + state->lastindex = -1; + + state->buffer.buf = NULL; + ptr = getstring(string, &length, &isbytes, &charsize, &state->buffer); + if (!ptr) + goto err; + + if (isbytes && pattern->isbytes == 0) { + PyErr_SetString(PyExc_TypeError, + "cannot use a string pattern on a bytes-like object"); + goto err; + } + if (!isbytes && pattern->isbytes > 0) { + PyErr_SetString(PyExc_TypeError, + "cannot use a bytes pattern on a string-like object"); + goto err; + } + + /* adjust boundaries */ + if (start < 0) + start = 0; + else if (start > length) + start = length; + + if (end < 0) + end = 0; + else if (end > length) + end = length; + + state->isbytes = isbytes; + state->charsize = charsize; + state->match_all = 0; + state->must_advance = 0; + + state->beginning = ptr; + + state->start = (void*) ((char*) ptr + start * state->charsize); + state->end = (void*) ((char*) ptr + end * state->charsize); + + Py_INCREF(string); + state->string = string; + state->pos = start; + state->endpos = end; + + return string; + err: + /* We add an explicit cast here because MSVC has a bug when + compiling C code where it believes that `const void**` cannot be + safely casted to `void*`, see bpo-39943 for details. */ + PyMem_Del((void*) state->mark); + state->mark = NULL; + if (state->buffer.buf) + PyBuffer_Release(&state->buffer); + return NULL; +} + +LOCAL(void) +state_fini(SRE_STATE* state) +{ + if (state->buffer.buf) + PyBuffer_Release(&state->buffer); + Py_XDECREF(state->string); + data_stack_dealloc(state); + /* See above PyMem_Del for why we explicitly cast here. */ + PyMem_Del((void*) state->mark); + state->mark = NULL; +} + +/* calculate offset from start of string */ +#define STATE_OFFSET(state, member)\ + (((char*)(member) - (char*)(state)->beginning) / (state)->charsize) + +LOCAL(PyObject*) +getslice(int isbytes, const void *ptr, + PyObject* string, Py_ssize_t start, Py_ssize_t end) +{ + if (isbytes) { + if (PyBytes_CheckExact(string) && + start == 0 && end == PyBytes_GET_SIZE(string)) { + Py_INCREF(string); + return string; + } + return PyBytes_FromStringAndSize( + (const char *)ptr + start, end - start); + } + else { + return PyUnicode_Substring(string, start, end); + } +} + +LOCAL(PyObject*) +state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty) +{ + Py_ssize_t i, j; + + index = (index - 1) * 2; + + if (string == Py_None || index >= state->lastmark || !state->mark[index] || !state->mark[index+1]) { + if (empty) + /* want empty string */ + i = j = 0; + else { + Py_RETURN_NONE; + } + } else { + i = STATE_OFFSET(state, state->mark[index]); + j = STATE_OFFSET(state, state->mark[index+1]); + } + + return getslice(state->isbytes, state->beginning, string, i, j); +} + +static void +pattern_error(Py_ssize_t status) +{ + switch (status) { + case SRE_ERROR_RECURSION_LIMIT: + /* This error code seems to be unused. */ + PyErr_SetString( + PyExc_RecursionError, + "maximum recursion limit exceeded" + ); + break; + case SRE_ERROR_MEMORY: + PyErr_NoMemory(); + break; + case SRE_ERROR_INTERRUPTED: + /* An exception has already been raised, so let it fly */ + break; + default: + /* other error codes indicate compiler/engine bugs */ + PyErr_SetString( + PyExc_RuntimeError, + "internal error in regular expression engine" + ); + } +} + +static void +pattern_dealloc(PatternObject* self) +{ + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_XDECREF(self->pattern); + Py_XDECREF(self->groupindex); + Py_XDECREF(self->indexgroup); + PyObject_DEL(self); +} + +LOCAL(Py_ssize_t) +sre_match(SRE_STATE* state, SRE_CODE* pattern) +{ + if (state->charsize == 1) + return sre_ucs1_match(state, pattern, 1); + if (state->charsize == 2) + return sre_ucs2_match(state, pattern, 1); + assert(state->charsize == 4); + return sre_ucs4_match(state, pattern, 1); +} + +LOCAL(Py_ssize_t) +sre_search(SRE_STATE* state, SRE_CODE* pattern) +{ + if (state->charsize == 1) + return sre_ucs1_search(state, pattern); + if (state->charsize == 2) + return sre_ucs2_search(state, pattern); + assert(state->charsize == 4); + return sre_ucs4_search(state, pattern); +} + +/*[clinic input] +_sre.SRE_Pattern.match + + string: object + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + +Matches zero or more characters at the beginning of the string. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos) +/*[clinic end generated code: output=ea2d838888510661 input=a2ba191647abebe5]*/ +{ + SRE_STATE state; + Py_ssize_t status; + PyObject *match; + + if (!state_init(&state, (PatternObject *)self, string, pos, endpos)) + return NULL; + + state.ptr = state.start; + + TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr)); + + status = sre_match(&state, PatternObject_GetCode(self)); + + TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); + if (PyErr_Occurred()) { + state_fini(&state); + return NULL; + } + + match = pattern_new_match(self, &state, status); + state_fini(&state); + return match; +} + +/*[clinic input] +_sre.SRE_Pattern.fullmatch + + string: object + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + +Matches against all of the string. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos) +/*[clinic end generated code: output=5833c47782a35f4a input=d9fb03a7625b5828]*/ +{ + SRE_STATE state; + Py_ssize_t status; + PyObject *match; + + if (!state_init(&state, self, string, pos, endpos)) + return NULL; + + state.ptr = state.start; + + TRACE(("|%p|%p|FULLMATCH\n", PatternObject_GetCode(self), state.ptr)); + + state.match_all = 1; + status = sre_match(&state, PatternObject_GetCode(self)); + + TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); + if (PyErr_Occurred()) { + state_fini(&state); + return NULL; + } + + match = pattern_new_match(self, &state, status); + state_fini(&state); + return match; +} + +/*[clinic input] +_sre.SRE_Pattern.search + + string: object + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + +Scan through string looking for a match, and return a corresponding match object instance. + +Return None if no position in the string matches. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos) +/*[clinic end generated code: output=25f302a644e951e8 input=4ae5cb7dc38fed1b]*/ +{ + SRE_STATE state; + Py_ssize_t status; + PyObject *match; + + if (!state_init(&state, self, string, pos, endpos)) + return NULL; + + TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr)); + + status = sre_search(&state, PatternObject_GetCode(self)); + + TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); + + if (PyErr_Occurred()) { + state_fini(&state); + return NULL; + } + + match = pattern_new_match(self, &state, status); + state_fini(&state); + return match; +} + +static PyObject* +call(const char* module, const char* function, PyObject* args) +{ + PyObject* name; + PyObject* mod; + PyObject* func; + PyObject* result; + + if (!args) + return NULL; + name = PyUnicode_FromString(module); + if (!name) + return NULL; + mod = PyImport_Import(name); + Py_DECREF(name); + if (!mod) + return NULL; + func = PyObject_GetAttrString(mod, function); + Py_DECREF(mod); + if (!func) + return NULL; + result = PyObject_CallObject(func, args); + Py_DECREF(func); + Py_DECREF(args); + return result; +} + +/*[clinic input] +_sre.SRE_Pattern.findall + + string: object + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + +Return a list of all non-overlapping matches of pattern in string. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_findall_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos) +/*[clinic end generated code: output=f4966baceea60aca input=5b6a4ee799741563]*/ +{ + SRE_STATE state; + PyObject* list; + Py_ssize_t status; + Py_ssize_t i, b, e; + + if (!state_init(&state, self, string, pos, endpos)) + return NULL; + + list = PyList_New(0); + if (!list) { + state_fini(&state); + return NULL; + } + + while (state.start <= state.end) { + + PyObject* item; + + state_reset(&state); + + state.ptr = state.start; + + status = sre_search(&state, PatternObject_GetCode(self)); + if (PyErr_Occurred()) + goto error; + + if (status <= 0) { + if (status == 0) + break; + pattern_error(status); + goto error; + } + + /* don't bother to build a match object */ + switch (self->groups) { + case 0: + b = STATE_OFFSET(&state, state.start); + e = STATE_OFFSET(&state, state.ptr); + item = getslice(state.isbytes, state.beginning, + string, b, e); + if (!item) + goto error; + break; + case 1: + item = state_getslice(&state, 1, string, 1); + if (!item) + goto error; + break; + default: + item = PyTuple_New(self->groups); + if (!item) + goto error; + for (i = 0; i < self->groups; i++) { + PyObject* o = state_getslice(&state, i+1, string, 1); + if (!o) { + Py_DECREF(item); + goto error; + } + PyTuple_SET_ITEM(item, i, o); + } + break; + } + + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + state.must_advance = (state.ptr == state.start); + state.start = state.ptr; + } + + state_fini(&state); + return list; + +error: + Py_DECREF(list); + state_fini(&state); + return NULL; + +} + +/*[clinic input] +_sre.SRE_Pattern.finditer + + string: object + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + +Return an iterator over all non-overlapping matches for the RE pattern in string. + +For each match, the iterator returns a match object. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos) +/*[clinic end generated code: output=0bbb1a0aeb38bb14 input=612aab69e9fe08e4]*/ +{ + PyObject* scanner; + PyObject* search; + PyObject* iterator; + + scanner = pattern_scanner(self, string, pos, endpos); + if (!scanner) + return NULL; + + search = PyObject_GetAttrString(scanner, "search"); + Py_DECREF(scanner); + if (!search) + return NULL; + + iterator = PyCallIter_New(search, Py_None); + Py_DECREF(search); + + return iterator; +} + +/*[clinic input] +_sre.SRE_Pattern.scanner + + string: object + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos) +/*[clinic end generated code: output=54ea548aed33890b input=3aacdbde77a3a637]*/ +{ + return pattern_scanner(self, string, pos, endpos); +} + +/*[clinic input] +_sre.SRE_Pattern.split + + string: object + maxsplit: Py_ssize_t = 0 + +Split string by the occurrences of pattern. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string, + Py_ssize_t maxsplit) +/*[clinic end generated code: output=7ac66f381c45e0be input=1eeeb10dafc9947a]*/ +{ + SRE_STATE state; + PyObject* list; + PyObject* item; + Py_ssize_t status; + Py_ssize_t n; + Py_ssize_t i; + const void* last; + + assert(self->codesize != 0); + + if (!state_init(&state, self, string, 0, PY_SSIZE_T_MAX)) + return NULL; + + list = PyList_New(0); + if (!list) { + state_fini(&state); + return NULL; + } + + n = 0; + last = state.start; + + while (!maxsplit || n < maxsplit) { + + state_reset(&state); + + state.ptr = state.start; + + status = sre_search(&state, PatternObject_GetCode(self)); + if (PyErr_Occurred()) + goto error; + + if (status <= 0) { + if (status == 0) + break; + pattern_error(status); + goto error; + } + + /* get segment before this match */ + item = getslice(state.isbytes, state.beginning, + string, STATE_OFFSET(&state, last), + STATE_OFFSET(&state, state.start) + ); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + /* add groups (if any) */ + for (i = 0; i < self->groups; i++) { + item = state_getslice(&state, i+1, string, 0); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + } + + n = n + 1; + state.must_advance = (state.ptr == state.start); + last = state.start = state.ptr; + + } + + /* get segment following last match (even if empty) */ + item = getslice(state.isbytes, state.beginning, + string, STATE_OFFSET(&state, last), state.endpos + ); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + state_fini(&state); + return list; + +error: + Py_DECREF(list); + state_fini(&state); + return NULL; + +} + +static PyObject* +pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, + Py_ssize_t count, Py_ssize_t subn) +{ + SRE_STATE state; + PyObject* list; + PyObject* joiner; + PyObject* item; + PyObject* filter; + PyObject* match; + const void* ptr; + Py_ssize_t status; + Py_ssize_t n; + Py_ssize_t i, b, e; + int isbytes, charsize; + int filter_is_callable; + Py_buffer view; + + if (PyCallable_Check(ptemplate)) { + /* sub/subn takes either a function or a template */ + filter = ptemplate; + Py_INCREF(filter); + filter_is_callable = 1; + } else { + /* if not callable, check if it's a literal string */ + int literal; + view.buf = NULL; + ptr = getstring(ptemplate, &n, &isbytes, &charsize, &view); + if (ptr) { + if (charsize == 1) + literal = memchr(ptr, '\\', n) == NULL; + else + literal = PyUnicode_FindChar(ptemplate, '\\', 0, n, 1) == -1; + } else { + PyErr_Clear(); + literal = 0; + } + if (view.buf) + PyBuffer_Release(&view); + if (literal) { + filter = ptemplate; + Py_INCREF(filter); + filter_is_callable = 0; + } else { + /* not a literal; hand it over to the template compiler */ + filter = call( + SRE_PY_MODULE, "_subx", + PyTuple_Pack(2, self, ptemplate) + ); + if (!filter) + return NULL; + filter_is_callable = PyCallable_Check(filter); + } + } + + if (!state_init(&state, self, string, 0, PY_SSIZE_T_MAX)) { + Py_DECREF(filter); + return NULL; + } + + list = PyList_New(0); + if (!list) { + Py_DECREF(filter); + state_fini(&state); + return NULL; + } + + n = i = 0; + + while (!count || n < count) { + + state_reset(&state); + + state.ptr = state.start; + + status = sre_search(&state, PatternObject_GetCode(self)); + if (PyErr_Occurred()) + goto error; + + if (status <= 0) { + if (status == 0) + break; + pattern_error(status); + goto error; + } + + b = STATE_OFFSET(&state, state.start); + e = STATE_OFFSET(&state, state.ptr); + + if (i < b) { + /* get segment before this match */ + item = getslice(state.isbytes, state.beginning, + string, i, b); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + } + + if (filter_is_callable) { + /* pass match object through filter */ + match = pattern_new_match(self, &state, 1); + if (!match) + goto error; + item = PyObject_CallOneArg(filter, match); + Py_DECREF(match); + if (!item) + goto error; + } else { + /* filter is literal string */ + item = filter; + Py_INCREF(item); + } + + /* add to list */ + if (item != Py_None) { + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + } + + i = e; + n = n + 1; + state.must_advance = (state.ptr == state.start); + state.start = state.ptr; + } + + /* get segment following last match */ + if (i < state.endpos) { + item = getslice(state.isbytes, state.beginning, + string, i, state.endpos); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + } + + state_fini(&state); + + Py_DECREF(filter); + + /* convert list to single string (also removes list) */ + joiner = getslice(state.isbytes, state.beginning, string, 0, 0); + if (!joiner) { + Py_DECREF(list); + return NULL; + } + if (PyList_GET_SIZE(list) == 0) { + Py_DECREF(list); + item = joiner; + } + else { + if (state.isbytes) + item = _PyBytes_Join(joiner, list); + else + item = PyUnicode_Join(joiner, list); + Py_DECREF(joiner); + Py_DECREF(list); + if (!item) + return NULL; + } + + if (subn) + return Py_BuildValue("Nn", item, n); + + return item; + +error: + Py_DECREF(list); + state_fini(&state); + Py_DECREF(filter); + return NULL; + +} + +/*[clinic input] +_sre.SRE_Pattern.sub + + repl: object + string: object + count: Py_ssize_t = 0 + +Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_sub_impl(PatternObject *self, PyObject *repl, + PyObject *string, Py_ssize_t count) +/*[clinic end generated code: output=1dbf2ec3479cba00 input=c53d70be0b3caf86]*/ +{ + return pattern_subx(self, repl, string, count, 0); +} + +/*[clinic input] +_sre.SRE_Pattern.subn + + repl: object + string: object + count: Py_ssize_t = 0 + +Return the tuple (new_string, number_of_subs_made) found by replacing the leftmost non-overlapping occurrences of pattern with the replacement repl. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern_subn_impl(PatternObject *self, PyObject *repl, + PyObject *string, Py_ssize_t count) +/*[clinic end generated code: output=0d9522cd529e9728 input=e7342d7ce6083577]*/ +{ + return pattern_subx(self, repl, string, count, 1); +} + +/*[clinic input] +_sre.SRE_Pattern.__copy__ + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern___copy___impl(PatternObject *self) +/*[clinic end generated code: output=85dedc2db1bd8694 input=a730a59d863bc9f5]*/ +{ + Py_INCREF(self); + return (PyObject *)self; +} + +/*[clinic input] +_sre.SRE_Pattern.__deepcopy__ + + memo: object + / + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern___deepcopy__(PatternObject *self, PyObject *memo) +/*[clinic end generated code: output=2ad25679c1f1204a input=a465b1602f997bed]*/ +{ + Py_INCREF(self); + return (PyObject *)self; +} + +static PyObject * +pattern_repr(PatternObject *obj) +{ + static const struct { + const char *name; + int value; + } flag_names[] = { + {"re.TEMPLATE", SRE_FLAG_TEMPLATE}, + {"re.IGNORECASE", SRE_FLAG_IGNORECASE}, + {"re.LOCALE", SRE_FLAG_LOCALE}, + {"re.MULTILINE", SRE_FLAG_MULTILINE}, + {"re.DOTALL", SRE_FLAG_DOTALL}, + {"re.UNICODE", SRE_FLAG_UNICODE}, + {"re.VERBOSE", SRE_FLAG_VERBOSE}, + {"re.DEBUG", SRE_FLAG_DEBUG}, + {"re.ASCII", SRE_FLAG_ASCII}, + }; + PyObject *result = NULL; + PyObject *flag_items; + size_t i; + int flags = obj->flags; + + /* Omit re.UNICODE for valid string patterns. */ + if (obj->isbytes == 0 && + (flags & (SRE_FLAG_LOCALE|SRE_FLAG_UNICODE|SRE_FLAG_ASCII)) == + SRE_FLAG_UNICODE) + flags &= ~SRE_FLAG_UNICODE; + + flag_items = PyList_New(0); + if (!flag_items) + return NULL; + + for (i = 0; i < Py_ARRAY_LENGTH(flag_names); i++) { + if (flags & flag_names[i].value) { + PyObject *item = PyUnicode_FromString(flag_names[i].name); + if (!item) + goto done; + + if (PyList_Append(flag_items, item) < 0) { + Py_DECREF(item); + goto done; + } + Py_DECREF(item); + flags &= ~flag_names[i].value; + } + } + if (flags) { + PyObject *item = PyUnicode_FromFormat("0x%x", flags); + if (!item) + goto done; + + if (PyList_Append(flag_items, item) < 0) { + Py_DECREF(item); + goto done; + } + Py_DECREF(item); + } + + if (PyList_Size(flag_items) > 0) { + PyObject *flags_result; + PyObject *sep = PyUnicode_FromString("|"); + if (!sep) + goto done; + flags_result = PyUnicode_Join(sep, flag_items); + Py_DECREF(sep); + if (!flags_result) + goto done; + result = PyUnicode_FromFormat("re.compile(%.200R, %S)", + obj->pattern, flags_result); + Py_DECREF(flags_result); + } + else { + result = PyUnicode_FromFormat("re.compile(%.200R)", obj->pattern); + } + +done: + Py_DECREF(flag_items); + return result; +} + +PyDoc_STRVAR(pattern_doc, "Compiled regular expression object."); + +/* PatternObject's 'groupindex' method. */ +static PyObject * +pattern_groupindex(PatternObject *self, void *Py_UNUSED(ignored)) +{ + if (self->groupindex == NULL) + return PyDict_New(); + return PyDictProxy_New(self->groupindex); +} + +static int _validate(PatternObject *self); /* Forward */ + +/*[clinic input] +_sre.compile + + pattern: object + flags: int + code: object(subclass_of='&PyList_Type') + groups: Py_ssize_t + groupindex: object(subclass_of='&PyDict_Type') + indexgroup: object(subclass_of='&PyTuple_Type') + +[clinic start generated code]*/ + +static PyObject * +_sre_compile_impl(PyObject *module, PyObject *pattern, int flags, + PyObject *code, Py_ssize_t groups, PyObject *groupindex, + PyObject *indexgroup) +/*[clinic end generated code: output=ef9c2b3693776404 input=0a68476dbbe5db30]*/ +{ + /* "compile" pattern descriptor to pattern object */ + + PatternObject* self; + Py_ssize_t i, n; + + n = PyList_GET_SIZE(code); + /* coverity[ampersand_in_size] */ + self = PyObject_NewVar(PatternObject, &Pattern_Type, n); + if (!self) + return NULL; + self->weakreflist = NULL; + self->pattern = NULL; + self->groupindex = NULL; + self->indexgroup = NULL; + + self->codesize = n; + + for (i = 0; i < n; i++) { + PyObject *o = PyList_GET_ITEM(code, i); + unsigned long value = PyLong_AsUnsignedLong(o); + self->code[i] = (SRE_CODE) value; + if ((unsigned long) self->code[i] != value) { + PyErr_SetString(PyExc_OverflowError, + "regular expression code size limit exceeded"); + break; + } + } + + if (PyErr_Occurred()) { + Py_DECREF(self); + return NULL; + } + + if (pattern == Py_None) { + self->isbytes = -1; + } + else { + Py_ssize_t p_length; + int charsize; + Py_buffer view; + view.buf = NULL; + if (!getstring(pattern, &p_length, &self->isbytes, + &charsize, &view)) { + Py_DECREF(self); + return NULL; + } + if (view.buf) + PyBuffer_Release(&view); + } + + Py_INCREF(pattern); + self->pattern = pattern; + + self->flags = flags; + + self->groups = groups; + + if (PyDict_GET_SIZE(groupindex) > 0) { + Py_INCREF(groupindex); + self->groupindex = groupindex; + if (PyTuple_GET_SIZE(indexgroup) > 0) { + Py_INCREF(indexgroup); + self->indexgroup = indexgroup; + } + } + + if (!_validate(self)) { + Py_DECREF(self); + return NULL; + } + + return (PyObject*) self; +} + +/* -------------------------------------------------------------------- */ +/* Code validation */ + +/* To learn more about this code, have a look at the _compile() function in + Lib/sre_compile.py. The validation functions below checks the code array + for conformance with the code patterns generated there. + + The nice thing about the generated code is that it is position-independent: + all jumps are relative jumps forward. Also, jumps don't cross each other: + the target of a later jump is always earlier than the target of an earlier + jump. IOW, this is okay: + + J---------J-------T--------T + \ \_____/ / + \______________________/ + + but this is not: + + J---------J-------T--------T + \_________\_____/ / + \____________/ + + It also helps that SRE_CODE is always an unsigned type. +*/ + +/* Defining this one enables tracing of the validator */ +#undef VVERBOSE + +/* Trace macro for the validator */ +#if defined(VVERBOSE) +#define VTRACE(v) printf v +#else +#define VTRACE(v) do {} while(0) /* do nothing */ +#endif + +/* Report failure */ +#define FAIL do { VTRACE(("FAIL: %d\n", __LINE__)); return 0; } while (0) + +/* Extract opcode, argument, or skip count from code array */ +#define GET_OP \ + do { \ + VTRACE(("%p: ", code)); \ + if (code >= end) FAIL; \ + op = *code++; \ + VTRACE(("%lu (op)\n", (unsigned long)op)); \ + } while (0) +#define GET_ARG \ + do { \ + VTRACE(("%p= ", code)); \ + if (code >= end) FAIL; \ + arg = *code++; \ + VTRACE(("%lu (arg)\n", (unsigned long)arg)); \ + } while (0) +#define GET_SKIP_ADJ(adj) \ + do { \ + VTRACE(("%p= ", code)); \ + if (code >= end) FAIL; \ + skip = *code; \ + VTRACE(("%lu (skip to %p)\n", \ + (unsigned long)skip, code+skip)); \ + if (skip-adj > (uintptr_t)(end - code)) \ + FAIL; \ + code++; \ + } while (0) +#define GET_SKIP GET_SKIP_ADJ(0) + +static int +_validate_charset(SRE_CODE *code, SRE_CODE *end) +{ + /* Some variables are manipulated by the macros above */ + SRE_CODE op; + SRE_CODE arg; + SRE_CODE offset; + int i; + + while (code < end) { + GET_OP; + switch (op) { + + case SRE_OP_NEGATE: + break; + + case SRE_OP_LITERAL: + GET_ARG; + break; + + case SRE_OP_RANGE: + case SRE_OP_RANGE_UNI_IGNORE: + GET_ARG; + GET_ARG; + break; + + case SRE_OP_CHARSET: + offset = 256/SRE_CODE_BITS; /* 256-bit bitmap */ + if (offset > (uintptr_t)(end - code)) + FAIL; + code += offset; + break; + + case SRE_OP_BIGCHARSET: + GET_ARG; /* Number of blocks */ + offset = 256/sizeof(SRE_CODE); /* 256-byte table */ + if (offset > (uintptr_t)(end - code)) + FAIL; + /* Make sure that each byte points to a valid block */ + for (i = 0; i < 256; i++) { + if (((unsigned char *)code)[i] >= arg) + FAIL; + } + code += offset; + offset = arg * (256/SRE_CODE_BITS); /* 256-bit bitmap times arg */ + if (offset > (uintptr_t)(end - code)) + FAIL; + code += offset; + break; + + case SRE_OP_CATEGORY: + GET_ARG; + switch (arg) { + case SRE_CATEGORY_DIGIT: + case SRE_CATEGORY_NOT_DIGIT: + case SRE_CATEGORY_SPACE: + case SRE_CATEGORY_NOT_SPACE: + case SRE_CATEGORY_WORD: + case SRE_CATEGORY_NOT_WORD: + case SRE_CATEGORY_LINEBREAK: + case SRE_CATEGORY_NOT_LINEBREAK: + case SRE_CATEGORY_LOC_WORD: + case SRE_CATEGORY_LOC_NOT_WORD: + case SRE_CATEGORY_UNI_DIGIT: + case SRE_CATEGORY_UNI_NOT_DIGIT: + case SRE_CATEGORY_UNI_SPACE: + case SRE_CATEGORY_UNI_NOT_SPACE: + case SRE_CATEGORY_UNI_WORD: + case SRE_CATEGORY_UNI_NOT_WORD: + case SRE_CATEGORY_UNI_LINEBREAK: + case SRE_CATEGORY_UNI_NOT_LINEBREAK: + break; + default: + FAIL; + } + break; + + default: + FAIL; + + } + } + + return 1; +} + +static int +_validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) +{ + /* Some variables are manipulated by the macros above */ + SRE_CODE op; + SRE_CODE arg; + SRE_CODE skip; + + VTRACE(("code=%p, end=%p\n", code, end)); + + if (code > end) + FAIL; + + while (code < end) { + GET_OP; + switch (op) { + + case SRE_OP_MARK: + /* We don't check whether marks are properly nested; the + sre_match() code is robust even if they don't, and the worst + you can get is nonsensical match results. */ + GET_ARG; + if (arg > 2 * (size_t)groups + 1) { + VTRACE(("arg=%d, groups=%d\n", (int)arg, (int)groups)); + FAIL; + } + break; + + case SRE_OP_LITERAL: + case SRE_OP_NOT_LITERAL: + case SRE_OP_LITERAL_IGNORE: + case SRE_OP_NOT_LITERAL_IGNORE: + case SRE_OP_LITERAL_UNI_IGNORE: + case SRE_OP_NOT_LITERAL_UNI_IGNORE: + case SRE_OP_LITERAL_LOC_IGNORE: + case SRE_OP_NOT_LITERAL_LOC_IGNORE: + GET_ARG; + /* The arg is just a character, nothing to check */ + break; + + case SRE_OP_SUCCESS: + case SRE_OP_FAILURE: + /* Nothing to check; these normally end the matching process */ + break; + + case SRE_OP_AT: + GET_ARG; + switch (arg) { + case SRE_AT_BEGINNING: + case SRE_AT_BEGINNING_STRING: + case SRE_AT_BEGINNING_LINE: + case SRE_AT_END: + case SRE_AT_END_LINE: + case SRE_AT_END_STRING: + case SRE_AT_BOUNDARY: + case SRE_AT_NON_BOUNDARY: + case SRE_AT_LOC_BOUNDARY: + case SRE_AT_LOC_NON_BOUNDARY: + case SRE_AT_UNI_BOUNDARY: + case SRE_AT_UNI_NON_BOUNDARY: + break; + default: + FAIL; + } + break; + + case SRE_OP_ANY: + case SRE_OP_ANY_ALL: + /* These have no operands */ + break; + + case SRE_OP_IN: + case SRE_OP_IN_IGNORE: + case SRE_OP_IN_UNI_IGNORE: + case SRE_OP_IN_LOC_IGNORE: + GET_SKIP; + /* Stop 1 before the end; we check the FAILURE below */ + if (!_validate_charset(code, code+skip-2)) + FAIL; + if (code[skip-2] != SRE_OP_FAILURE) + FAIL; + code += skip-1; + break; + + case SRE_OP_INFO: + { + /* A minimal info field is + <1=skip> <2=flags> <3=min> <4=max>; + If SRE_INFO_PREFIX or SRE_INFO_CHARSET is in the flags, + more follows. */ + SRE_CODE flags, i; + SRE_CODE *newcode; + GET_SKIP; + newcode = code+skip-1; + GET_ARG; flags = arg; + GET_ARG; + GET_ARG; + /* Check that only valid flags are present */ + if ((flags & ~(SRE_INFO_PREFIX | + SRE_INFO_LITERAL | + SRE_INFO_CHARSET)) != 0) + FAIL; + /* PREFIX and CHARSET are mutually exclusive */ + if ((flags & SRE_INFO_PREFIX) && + (flags & SRE_INFO_CHARSET)) + FAIL; + /* LITERAL implies PREFIX */ + if ((flags & SRE_INFO_LITERAL) && + !(flags & SRE_INFO_PREFIX)) + FAIL; + /* Validate the prefix */ + if (flags & SRE_INFO_PREFIX) { + SRE_CODE prefix_len; + GET_ARG; prefix_len = arg; + GET_ARG; + /* Here comes the prefix string */ + if (prefix_len > (uintptr_t)(newcode - code)) + FAIL; + code += prefix_len; + /* And here comes the overlap table */ + if (prefix_len > (uintptr_t)(newcode - code)) + FAIL; + /* Each overlap value should be < prefix_len */ + for (i = 0; i < prefix_len; i++) { + if (code[i] >= prefix_len) + FAIL; + } + code += prefix_len; + } + /* Validate the charset */ + if (flags & SRE_INFO_CHARSET) { + if (!_validate_charset(code, newcode-1)) + FAIL; + if (newcode[-1] != SRE_OP_FAILURE) + FAIL; + code = newcode; + } + else if (code != newcode) { + VTRACE(("code=%p, newcode=%p\n", code, newcode)); + FAIL; + } + } + break; + + case SRE_OP_BRANCH: + { + SRE_CODE *target = NULL; + for (;;) { + GET_SKIP; + if (skip == 0) + break; + /* Stop 2 before the end; we check the JUMP below */ + if (!_validate_inner(code, code+skip-3, groups)) + FAIL; + code += skip-3; + /* Check that it ends with a JUMP, and that each JUMP + has the same target */ + GET_OP; + if (op != SRE_OP_JUMP) + FAIL; + GET_SKIP; + if (target == NULL) + target = code+skip-1; + else if (code+skip-1 != target) + FAIL; + } + } + break; + + case SRE_OP_REPEAT_ONE: + case SRE_OP_MIN_REPEAT_ONE: + { + SRE_CODE min, max; + GET_SKIP; + GET_ARG; min = arg; + GET_ARG; max = arg; + if (min > max) + FAIL; + if (max > SRE_MAXREPEAT) + FAIL; + if (!_validate_inner(code, code+skip-4, groups)) + FAIL; + code += skip-4; + GET_OP; + if (op != SRE_OP_SUCCESS) + FAIL; + } + break; + + case SRE_OP_REPEAT: + { + SRE_CODE min, max; + GET_SKIP; + GET_ARG; min = arg; + GET_ARG; max = arg; + if (min > max) + FAIL; + if (max > SRE_MAXREPEAT) + FAIL; + if (!_validate_inner(code, code+skip-3, groups)) + FAIL; + code += skip-3; + GET_OP; + if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL) + FAIL; + } + break; + + case SRE_OP_GROUPREF: + case SRE_OP_GROUPREF_IGNORE: + case SRE_OP_GROUPREF_UNI_IGNORE: + case SRE_OP_GROUPREF_LOC_IGNORE: + GET_ARG; + if (arg >= (size_t)groups) + FAIL; + break; + + case SRE_OP_GROUPREF_EXISTS: + /* The regex syntax for this is: '(?(group)then|else)', where + 'group' is either an integer group number or a group name, + 'then' and 'else' are sub-regexes, and 'else' is optional. */ + GET_ARG; + if (arg >= (size_t)groups) + FAIL; + GET_SKIP_ADJ(1); + code--; /* The skip is relative to the first arg! */ + /* There are two possibilities here: if there is both a 'then' + part and an 'else' part, the generated code looks like: + + GROUPREF_EXISTS + + + ...then part... + JUMP + + ( jumps here) + ...else part... + ( jumps here) + + If there is only a 'then' part, it looks like: + + GROUPREF_EXISTS + + + ...then part... + ( jumps here) + + There is no direct way to decide which it is, and we don't want + to allow arbitrary jumps anywhere in the code; so we just look + for a JUMP opcode preceding our skip target. + */ + if (skip >= 3 && skip-3 < (uintptr_t)(end - code) && + code[skip-3] == SRE_OP_JUMP) + { + VTRACE(("both then and else parts present\n")); + if (!_validate_inner(code+1, code+skip-3, groups)) + FAIL; + code += skip-2; /* Position after JUMP, at */ + GET_SKIP; + if (!_validate_inner(code, code+skip-1, groups)) + FAIL; + code += skip-1; + } + else { + VTRACE(("only a then part present\n")); + if (!_validate_inner(code+1, code+skip-1, groups)) + FAIL; + code += skip-1; + } + break; + + case SRE_OP_ASSERT: + case SRE_OP_ASSERT_NOT: + GET_SKIP; + GET_ARG; /* 0 for lookahead, width for lookbehind */ + code--; /* Back up over arg to simplify math below */ + if (arg & 0x80000000) + FAIL; /* Width too large */ + /* Stop 1 before the end; we check the SUCCESS below */ + if (!_validate_inner(code+1, code+skip-2, groups)) + FAIL; + code += skip-2; + GET_OP; + if (op != SRE_OP_SUCCESS) + FAIL; + break; + + default: + FAIL; + + } + } + + VTRACE(("okay\n")); + return 1; +} + +static int +_validate_outer(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) +{ + if (groups < 0 || (size_t)groups > SRE_MAXGROUPS || + code >= end || end[-1] != SRE_OP_SUCCESS) + FAIL; + return _validate_inner(code, end-1, groups); +} + +static int +_validate(PatternObject *self) +{ + if (!_validate_outer(self->code, self->code+self->codesize, self->groups)) + { + PyErr_SetString(PyExc_RuntimeError, "invalid SRE code"); + return 0; + } + else + VTRACE(("Success!\n")); + return 1; +} + +/* -------------------------------------------------------------------- */ +/* match methods */ + +static void +match_dealloc(MatchObject* self) +{ + Py_XDECREF(self->regs); + Py_XDECREF(self->string); + Py_DECREF(self->pattern); + PyObject_DEL(self); +} + +static PyObject* +match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def) +{ + Py_ssize_t length; + int isbytes, charsize; + Py_buffer view; + PyObject *result; + const void* ptr; + Py_ssize_t i, j; + assert(0 <= index && index < self->groups); - index *= 2; - - if (self->string == Py_None || self->mark[index] < 0) { - /* return default value if the string or group is undefined */ - Py_INCREF(def); - return def; - } - - ptr = getstring(self->string, &length, &isbytes, &charsize, &view); - if (ptr == NULL) - return NULL; - - i = self->mark[index]; - j = self->mark[index+1]; - i = Py_MIN(i, length); - j = Py_MIN(j, length); - result = getslice(isbytes, ptr, self->string, i, j); - if (isbytes && view.buf != NULL) - PyBuffer_Release(&view); - return result; -} - -static Py_ssize_t -match_getindex(MatchObject* self, PyObject* index) -{ - Py_ssize_t i; - - if (index == NULL) - /* Default value */ - return 0; - - if (PyIndex_Check(index)) { + index *= 2; + + if (self->string == Py_None || self->mark[index] < 0) { + /* return default value if the string or group is undefined */ + Py_INCREF(def); + return def; + } + + ptr = getstring(self->string, &length, &isbytes, &charsize, &view); + if (ptr == NULL) + return NULL; + + i = self->mark[index]; + j = self->mark[index+1]; + i = Py_MIN(i, length); + j = Py_MIN(j, length); + result = getslice(isbytes, ptr, self->string, i, j); + if (isbytes && view.buf != NULL) + PyBuffer_Release(&view); + return result; +} + +static Py_ssize_t +match_getindex(MatchObject* self, PyObject* index) +{ + Py_ssize_t i; + + if (index == NULL) + /* Default value */ + return 0; + + if (PyIndex_Check(index)) { i = PyNumber_AsSsize_t(index, NULL); - } + } else { i = -1; - + if (self->pattern->groupindex) { index = PyDict_GetItemWithError(self->pattern->groupindex, index); if (index && PyLong_Check(index)) { i = PyLong_AsSsize_t(index); } - } - } + } + } if (i < 0 || i >= self->groups) { /* raise IndexError if we were given a bad group number */ if (!PyErr_Occurred()) { @@ -1954,13 +1954,13 @@ match_getindex(MatchObject* self, PyObject* index) } return -1; } - - return i; -} - -static PyObject* -match_getslice(MatchObject* self, PyObject* index, PyObject* def) -{ + + return i; +} + +static PyObject* +match_getslice(MatchObject* self, PyObject* index, PyObject* def) +{ Py_ssize_t i = match_getindex(self, index); if (i < 0) { @@ -1968,857 +1968,857 @@ match_getslice(MatchObject* self, PyObject* index, PyObject* def) } return match_getslice_by_index(self, i, def); -} - -/*[clinic input] -_sre.SRE_Match.expand - - template: object - -Return the string obtained by doing backslash substitution on the string template, as done by the sub() method. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Match_expand_impl(MatchObject *self, PyObject *template) -/*[clinic end generated code: output=931b58ccc323c3a1 input=4bfdb22c2f8b146a]*/ -{ - /* delegate to Python code */ - return call( - SRE_PY_MODULE, "_expand", - PyTuple_Pack(3, self->pattern, self, template) - ); -} - -static PyObject* -match_group(MatchObject* self, PyObject* args) -{ - PyObject* result; - Py_ssize_t i, size; - - size = PyTuple_GET_SIZE(args); - - switch (size) { - case 0: - result = match_getslice(self, _PyLong_Zero, Py_None); - break; - case 1: - result = match_getslice(self, PyTuple_GET_ITEM(args, 0), Py_None); - break; - default: - /* fetch multiple items */ - result = PyTuple_New(size); - if (!result) - return NULL; - for (i = 0; i < size; i++) { - PyObject* item = match_getslice( - self, PyTuple_GET_ITEM(args, i), Py_None - ); - if (!item) { - Py_DECREF(result); - return NULL; - } - PyTuple_SET_ITEM(result, i, item); - } - break; - } - return result; -} - -static PyObject* -match_getitem(MatchObject* self, PyObject* name) -{ - return match_getslice(self, name, Py_None); -} - -/*[clinic input] -_sre.SRE_Match.groups - - default: object = None - Is used for groups that did not participate in the match. - -Return a tuple containing all the subgroups of the match, from 1. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Match_groups_impl(MatchObject *self, PyObject *default_value) -/*[clinic end generated code: output=daf8e2641537238a input=bb069ef55dabca91]*/ -{ - PyObject* result; - Py_ssize_t index; - - result = PyTuple_New(self->groups-1); - if (!result) - return NULL; - - for (index = 1; index < self->groups; index++) { - PyObject* item; - item = match_getslice_by_index(self, index, default_value); - if (!item) { - Py_DECREF(result); - return NULL; - } - PyTuple_SET_ITEM(result, index-1, item); - } - - return result; -} - -/*[clinic input] -_sre.SRE_Match.groupdict - - default: object = None - Is used for groups that did not participate in the match. - -Return a dictionary containing all the named subgroups of the match, keyed by the subgroup name. -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Match_groupdict_impl(MatchObject *self, PyObject *default_value) -/*[clinic end generated code: output=29917c9073e41757 input=0ded7960b23780aa]*/ -{ - PyObject *result; - PyObject *key; - PyObject *value; - Py_ssize_t pos = 0; - Py_hash_t hash; - - result = PyDict_New(); - if (!result || !self->pattern->groupindex) - return result; - - while (_PyDict_Next(self->pattern->groupindex, &pos, &key, &value, &hash)) { - int status; - Py_INCREF(key); - value = match_getslice(self, key, default_value); - if (!value) { - Py_DECREF(key); - goto failed; - } - status = _PyDict_SetItem_KnownHash(result, key, value, hash); - Py_DECREF(value); - Py_DECREF(key); - if (status < 0) - goto failed; - } - - return result; - -failed: - Py_DECREF(result); - return NULL; -} - -/*[clinic input] -_sre.SRE_Match.start -> Py_ssize_t - - group: object(c_default="NULL") = 0 - / - -Return index of the start of the substring matched by group. -[clinic start generated code]*/ - -static Py_ssize_t -_sre_SRE_Match_start_impl(MatchObject *self, PyObject *group) -/*[clinic end generated code: output=3f6e7f9df2fb5201 input=ced8e4ed4b33ee6c]*/ -{ - Py_ssize_t index = match_getindex(self, group); - +} + +/*[clinic input] +_sre.SRE_Match.expand + + template: object + +Return the string obtained by doing backslash substitution on the string template, as done by the sub() method. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Match_expand_impl(MatchObject *self, PyObject *template) +/*[clinic end generated code: output=931b58ccc323c3a1 input=4bfdb22c2f8b146a]*/ +{ + /* delegate to Python code */ + return call( + SRE_PY_MODULE, "_expand", + PyTuple_Pack(3, self->pattern, self, template) + ); +} + +static PyObject* +match_group(MatchObject* self, PyObject* args) +{ + PyObject* result; + Py_ssize_t i, size; + + size = PyTuple_GET_SIZE(args); + + switch (size) { + case 0: + result = match_getslice(self, _PyLong_Zero, Py_None); + break; + case 1: + result = match_getslice(self, PyTuple_GET_ITEM(args, 0), Py_None); + break; + default: + /* fetch multiple items */ + result = PyTuple_New(size); + if (!result) + return NULL; + for (i = 0; i < size; i++) { + PyObject* item = match_getslice( + self, PyTuple_GET_ITEM(args, i), Py_None + ); + if (!item) { + Py_DECREF(result); + return NULL; + } + PyTuple_SET_ITEM(result, i, item); + } + break; + } + return result; +} + +static PyObject* +match_getitem(MatchObject* self, PyObject* name) +{ + return match_getslice(self, name, Py_None); +} + +/*[clinic input] +_sre.SRE_Match.groups + + default: object = None + Is used for groups that did not participate in the match. + +Return a tuple containing all the subgroups of the match, from 1. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Match_groups_impl(MatchObject *self, PyObject *default_value) +/*[clinic end generated code: output=daf8e2641537238a input=bb069ef55dabca91]*/ +{ + PyObject* result; + Py_ssize_t index; + + result = PyTuple_New(self->groups-1); + if (!result) + return NULL; + + for (index = 1; index < self->groups; index++) { + PyObject* item; + item = match_getslice_by_index(self, index, default_value); + if (!item) { + Py_DECREF(result); + return NULL; + } + PyTuple_SET_ITEM(result, index-1, item); + } + + return result; +} + +/*[clinic input] +_sre.SRE_Match.groupdict + + default: object = None + Is used for groups that did not participate in the match. + +Return a dictionary containing all the named subgroups of the match, keyed by the subgroup name. +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Match_groupdict_impl(MatchObject *self, PyObject *default_value) +/*[clinic end generated code: output=29917c9073e41757 input=0ded7960b23780aa]*/ +{ + PyObject *result; + PyObject *key; + PyObject *value; + Py_ssize_t pos = 0; + Py_hash_t hash; + + result = PyDict_New(); + if (!result || !self->pattern->groupindex) + return result; + + while (_PyDict_Next(self->pattern->groupindex, &pos, &key, &value, &hash)) { + int status; + Py_INCREF(key); + value = match_getslice(self, key, default_value); + if (!value) { + Py_DECREF(key); + goto failed; + } + status = _PyDict_SetItem_KnownHash(result, key, value, hash); + Py_DECREF(value); + Py_DECREF(key); + if (status < 0) + goto failed; + } + + return result; + +failed: + Py_DECREF(result); + return NULL; +} + +/*[clinic input] +_sre.SRE_Match.start -> Py_ssize_t + + group: object(c_default="NULL") = 0 + / + +Return index of the start of the substring matched by group. +[clinic start generated code]*/ + +static Py_ssize_t +_sre_SRE_Match_start_impl(MatchObject *self, PyObject *group) +/*[clinic end generated code: output=3f6e7f9df2fb5201 input=ced8e4ed4b33ee6c]*/ +{ + Py_ssize_t index = match_getindex(self, group); + if (index < 0) { - return -1; - } - - /* mark is -1 if group is undefined */ - return self->mark[index*2]; -} - -/*[clinic input] -_sre.SRE_Match.end -> Py_ssize_t - - group: object(c_default="NULL") = 0 - / - -Return index of the end of the substring matched by group. -[clinic start generated code]*/ - -static Py_ssize_t -_sre_SRE_Match_end_impl(MatchObject *self, PyObject *group) -/*[clinic end generated code: output=f4240b09911f7692 input=1b799560c7f3d7e6]*/ -{ - Py_ssize_t index = match_getindex(self, group); - + return -1; + } + + /* mark is -1 if group is undefined */ + return self->mark[index*2]; +} + +/*[clinic input] +_sre.SRE_Match.end -> Py_ssize_t + + group: object(c_default="NULL") = 0 + / + +Return index of the end of the substring matched by group. +[clinic start generated code]*/ + +static Py_ssize_t +_sre_SRE_Match_end_impl(MatchObject *self, PyObject *group) +/*[clinic end generated code: output=f4240b09911f7692 input=1b799560c7f3d7e6]*/ +{ + Py_ssize_t index = match_getindex(self, group); + if (index < 0) { - return -1; - } - - /* mark is -1 if group is undefined */ - return self->mark[index*2+1]; -} - -LOCAL(PyObject*) -_pair(Py_ssize_t i1, Py_ssize_t i2) -{ - PyObject* pair; - PyObject* item; - - pair = PyTuple_New(2); - if (!pair) - return NULL; - - item = PyLong_FromSsize_t(i1); - if (!item) - goto error; - PyTuple_SET_ITEM(pair, 0, item); - - item = PyLong_FromSsize_t(i2); - if (!item) - goto error; - PyTuple_SET_ITEM(pair, 1, item); - - return pair; - - error: - Py_DECREF(pair); - return NULL; -} - -/*[clinic input] -_sre.SRE_Match.span - - group: object(c_default="NULL") = 0 - / - -For match object m, return the 2-tuple (m.start(group), m.end(group)). -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Match_span_impl(MatchObject *self, PyObject *group) -/*[clinic end generated code: output=f02ae40594d14fe6 input=8fa6014e982d71d4]*/ -{ - Py_ssize_t index = match_getindex(self, group); - + return -1; + } + + /* mark is -1 if group is undefined */ + return self->mark[index*2+1]; +} + +LOCAL(PyObject*) +_pair(Py_ssize_t i1, Py_ssize_t i2) +{ + PyObject* pair; + PyObject* item; + + pair = PyTuple_New(2); + if (!pair) + return NULL; + + item = PyLong_FromSsize_t(i1); + if (!item) + goto error; + PyTuple_SET_ITEM(pair, 0, item); + + item = PyLong_FromSsize_t(i2); + if (!item) + goto error; + PyTuple_SET_ITEM(pair, 1, item); + + return pair; + + error: + Py_DECREF(pair); + return NULL; +} + +/*[clinic input] +_sre.SRE_Match.span + + group: object(c_default="NULL") = 0 + / + +For match object m, return the 2-tuple (m.start(group), m.end(group)). +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Match_span_impl(MatchObject *self, PyObject *group) +/*[clinic end generated code: output=f02ae40594d14fe6 input=8fa6014e982d71d4]*/ +{ + Py_ssize_t index = match_getindex(self, group); + if (index < 0) { - return NULL; - } - - /* marks are -1 if group is undefined */ - return _pair(self->mark[index*2], self->mark[index*2+1]); -} - -static PyObject* -match_regs(MatchObject* self) -{ - PyObject* regs; - PyObject* item; - Py_ssize_t index; - - regs = PyTuple_New(self->groups); - if (!regs) - return NULL; - - for (index = 0; index < self->groups; index++) { - item = _pair(self->mark[index*2], self->mark[index*2+1]); - if (!item) { - Py_DECREF(regs); - return NULL; - } - PyTuple_SET_ITEM(regs, index, item); - } - - Py_INCREF(regs); - self->regs = regs; - - return regs; -} - -/*[clinic input] -_sre.SRE_Match.__copy__ - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Match___copy___impl(MatchObject *self) -/*[clinic end generated code: output=a779c5fc8b5b4eb4 input=3bb4d30b6baddb5b]*/ -{ - Py_INCREF(self); - return (PyObject *)self; -} - -/*[clinic input] -_sre.SRE_Match.__deepcopy__ - - memo: object - / - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Match___deepcopy__(MatchObject *self, PyObject *memo) -/*[clinic end generated code: output=ba7cb46d655e4ee2 input=779d12a31c2c325e]*/ -{ - Py_INCREF(self); - return (PyObject *)self; -} - -PyDoc_STRVAR(match_doc, -"The result of re.match() and re.search().\n\ -Match objects always have a boolean value of True."); - -PyDoc_STRVAR(match_group_doc, -"group([group1, ...]) -> str or tuple.\n\ - Return subgroup(s) of the match by indices or names.\n\ - For 0 returns the entire match."); - -static PyObject * -match_lastindex_get(MatchObject *self, void *Py_UNUSED(ignored)) -{ - if (self->lastindex >= 0) - return PyLong_FromSsize_t(self->lastindex); - Py_RETURN_NONE; -} - -static PyObject * -match_lastgroup_get(MatchObject *self, void *Py_UNUSED(ignored)) -{ - if (self->pattern->indexgroup && - self->lastindex >= 0 && - self->lastindex < PyTuple_GET_SIZE(self->pattern->indexgroup)) - { - PyObject *result = PyTuple_GET_ITEM(self->pattern->indexgroup, - self->lastindex); - Py_INCREF(result); - return result; - } - Py_RETURN_NONE; -} - -static PyObject * -match_regs_get(MatchObject *self, void *Py_UNUSED(ignored)) -{ - if (self->regs) { - Py_INCREF(self->regs); - return self->regs; - } else - return match_regs(self); -} - -static PyObject * -match_repr(MatchObject *self) -{ - PyObject *result; - PyObject *group0 = match_getslice_by_index(self, 0, Py_None); - if (group0 == NULL) - return NULL; - result = PyUnicode_FromFormat( - "<%s object; span=(%zd, %zd), match=%.50R>", - Py_TYPE(self)->tp_name, - self->mark[0], self->mark[1], group0); - Py_DECREF(group0); - return result; -} - - -static PyObject* -pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) -{ - /* create match object (from state object) */ - - MatchObject* match; - Py_ssize_t i, j; - char* base; - int n; - - if (status > 0) { - - /* create match object (with room for extra group marks) */ - /* coverity[ampersand_in_size] */ + return NULL; + } + + /* marks are -1 if group is undefined */ + return _pair(self->mark[index*2], self->mark[index*2+1]); +} + +static PyObject* +match_regs(MatchObject* self) +{ + PyObject* regs; + PyObject* item; + Py_ssize_t index; + + regs = PyTuple_New(self->groups); + if (!regs) + return NULL; + + for (index = 0; index < self->groups; index++) { + item = _pair(self->mark[index*2], self->mark[index*2+1]); + if (!item) { + Py_DECREF(regs); + return NULL; + } + PyTuple_SET_ITEM(regs, index, item); + } + + Py_INCREF(regs); + self->regs = regs; + + return regs; +} + +/*[clinic input] +_sre.SRE_Match.__copy__ + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Match___copy___impl(MatchObject *self) +/*[clinic end generated code: output=a779c5fc8b5b4eb4 input=3bb4d30b6baddb5b]*/ +{ + Py_INCREF(self); + return (PyObject *)self; +} + +/*[clinic input] +_sre.SRE_Match.__deepcopy__ + + memo: object + / + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Match___deepcopy__(MatchObject *self, PyObject *memo) +/*[clinic end generated code: output=ba7cb46d655e4ee2 input=779d12a31c2c325e]*/ +{ + Py_INCREF(self); + return (PyObject *)self; +} + +PyDoc_STRVAR(match_doc, +"The result of re.match() and re.search().\n\ +Match objects always have a boolean value of True."); + +PyDoc_STRVAR(match_group_doc, +"group([group1, ...]) -> str or tuple.\n\ + Return subgroup(s) of the match by indices or names.\n\ + For 0 returns the entire match."); + +static PyObject * +match_lastindex_get(MatchObject *self, void *Py_UNUSED(ignored)) +{ + if (self->lastindex >= 0) + return PyLong_FromSsize_t(self->lastindex); + Py_RETURN_NONE; +} + +static PyObject * +match_lastgroup_get(MatchObject *self, void *Py_UNUSED(ignored)) +{ + if (self->pattern->indexgroup && + self->lastindex >= 0 && + self->lastindex < PyTuple_GET_SIZE(self->pattern->indexgroup)) + { + PyObject *result = PyTuple_GET_ITEM(self->pattern->indexgroup, + self->lastindex); + Py_INCREF(result); + return result; + } + Py_RETURN_NONE; +} + +static PyObject * +match_regs_get(MatchObject *self, void *Py_UNUSED(ignored)) +{ + if (self->regs) { + Py_INCREF(self->regs); + return self->regs; + } else + return match_regs(self); +} + +static PyObject * +match_repr(MatchObject *self) +{ + PyObject *result; + PyObject *group0 = match_getslice_by_index(self, 0, Py_None); + if (group0 == NULL) + return NULL; + result = PyUnicode_FromFormat( + "<%s object; span=(%zd, %zd), match=%.50R>", + Py_TYPE(self)->tp_name, + self->mark[0], self->mark[1], group0); + Py_DECREF(group0); + return result; +} + + +static PyObject* +pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) +{ + /* create match object (from state object) */ + + MatchObject* match; + Py_ssize_t i, j; + char* base; + int n; + + if (status > 0) { + + /* create match object (with room for extra group marks) */ + /* coverity[ampersand_in_size] */ match = PyObject_NewVar(MatchObject, &Match_Type, 2*(pattern->groups+1)); - if (!match) - return NULL; - - Py_INCREF(pattern); - match->pattern = pattern; - - Py_INCREF(state->string); - match->string = state->string; - - match->regs = NULL; - match->groups = pattern->groups+1; - - /* fill in group slices */ - - base = (char*) state->beginning; - n = state->charsize; - - match->mark[0] = ((char*) state->start - base) / n; - match->mark[1] = ((char*) state->ptr - base) / n; - - for (i = j = 0; i < pattern->groups; i++, j+=2) - if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) { - match->mark[j+2] = ((char*) state->mark[j] - base) / n; - match->mark[j+3] = ((char*) state->mark[j+1] - base) / n; - } else - match->mark[j+2] = match->mark[j+3] = -1; /* undefined */ - - match->pos = state->pos; - match->endpos = state->endpos; - - match->lastindex = state->lastindex; - - return (PyObject*) match; - - } else if (status == 0) { - - /* no match */ - Py_RETURN_NONE; - - } - - /* internal error */ - pattern_error(status); - return NULL; -} - - -/* -------------------------------------------------------------------- */ -/* scanner methods (experimental) */ - -static void -scanner_dealloc(ScannerObject* self) -{ - state_fini(&self->state); - Py_XDECREF(self->pattern); - PyObject_DEL(self); -} - -/*[clinic input] -_sre.SRE_Scanner.match - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self) -/*[clinic end generated code: output=936b30c63d4b81eb input=881a0154f8c13d9a]*/ -{ - SRE_STATE* state = &self->state; - PyObject* match; - Py_ssize_t status; - - if (state->start == NULL) - Py_RETURN_NONE; - - state_reset(state); - - state->ptr = state->start; - - status = sre_match(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) - return NULL; - - match = pattern_new_match((PatternObject*) self->pattern, - state, status); - - if (status == 0) - state->start = NULL; - else { - state->must_advance = (state->ptr == state->start); - state->start = state->ptr; - } - - return match; -} - - -/*[clinic input] -_sre.SRE_Scanner.search - -[clinic start generated code]*/ - -static PyObject * -_sre_SRE_Scanner_search_impl(ScannerObject *self) -/*[clinic end generated code: output=7dc211986088f025 input=161223ee92ef9270]*/ -{ - SRE_STATE* state = &self->state; - PyObject* match; - Py_ssize_t status; - - if (state->start == NULL) - Py_RETURN_NONE; - - state_reset(state); - - state->ptr = state->start; - - status = sre_search(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) - return NULL; - - match = pattern_new_match((PatternObject*) self->pattern, - state, status); - - if (status == 0) - state->start = NULL; - else { - state->must_advance = (state->ptr == state->start); - state->start = state->ptr; - } - - return match; -} - -static PyObject * -pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_t endpos) -{ - ScannerObject* scanner; - - /* create scanner object */ + if (!match) + return NULL; + + Py_INCREF(pattern); + match->pattern = pattern; + + Py_INCREF(state->string); + match->string = state->string; + + match->regs = NULL; + match->groups = pattern->groups+1; + + /* fill in group slices */ + + base = (char*) state->beginning; + n = state->charsize; + + match->mark[0] = ((char*) state->start - base) / n; + match->mark[1] = ((char*) state->ptr - base) / n; + + for (i = j = 0; i < pattern->groups; i++, j+=2) + if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) { + match->mark[j+2] = ((char*) state->mark[j] - base) / n; + match->mark[j+3] = ((char*) state->mark[j+1] - base) / n; + } else + match->mark[j+2] = match->mark[j+3] = -1; /* undefined */ + + match->pos = state->pos; + match->endpos = state->endpos; + + match->lastindex = state->lastindex; + + return (PyObject*) match; + + } else if (status == 0) { + + /* no match */ + Py_RETURN_NONE; + + } + + /* internal error */ + pattern_error(status); + return NULL; +} + + +/* -------------------------------------------------------------------- */ +/* scanner methods (experimental) */ + +static void +scanner_dealloc(ScannerObject* self) +{ + state_fini(&self->state); + Py_XDECREF(self->pattern); + PyObject_DEL(self); +} + +/*[clinic input] +_sre.SRE_Scanner.match + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Scanner_match_impl(ScannerObject *self) +/*[clinic end generated code: output=936b30c63d4b81eb input=881a0154f8c13d9a]*/ +{ + SRE_STATE* state = &self->state; + PyObject* match; + Py_ssize_t status; + + if (state->start == NULL) + Py_RETURN_NONE; + + state_reset(state); + + state->ptr = state->start; + + status = sre_match(state, PatternObject_GetCode(self->pattern)); + if (PyErr_Occurred()) + return NULL; + + match = pattern_new_match((PatternObject*) self->pattern, + state, status); + + if (status == 0) + state->start = NULL; + else { + state->must_advance = (state->ptr == state->start); + state->start = state->ptr; + } + + return match; +} + + +/*[clinic input] +_sre.SRE_Scanner.search + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Scanner_search_impl(ScannerObject *self) +/*[clinic end generated code: output=7dc211986088f025 input=161223ee92ef9270]*/ +{ + SRE_STATE* state = &self->state; + PyObject* match; + Py_ssize_t status; + + if (state->start == NULL) + Py_RETURN_NONE; + + state_reset(state); + + state->ptr = state->start; + + status = sre_search(state, PatternObject_GetCode(self->pattern)); + if (PyErr_Occurred()) + return NULL; + + match = pattern_new_match((PatternObject*) self->pattern, + state, status); + + if (status == 0) + state->start = NULL; + else { + state->must_advance = (state->ptr == state->start); + state->start = state->ptr; + } + + return match; +} + +static PyObject * +pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_t endpos) +{ + ScannerObject* scanner; + + /* create scanner object */ scanner = PyObject_New(ScannerObject, &Scanner_Type); - if (!scanner) - return NULL; - scanner->pattern = NULL; - - /* create search state object */ - if (!state_init(&scanner->state, self, string, pos, endpos)) { - Py_DECREF(scanner); - return NULL; - } - - Py_INCREF(self); - scanner->pattern = (PyObject*) self; - - return (PyObject*) scanner; -} - -static Py_hash_t -pattern_hash(PatternObject *self) -{ - Py_hash_t hash, hash2; - - hash = PyObject_Hash(self->pattern); - if (hash == -1) { - return -1; - } - - hash2 = _Py_HashBytes(self->code, sizeof(self->code[0]) * self->codesize); - hash ^= hash2; - - hash ^= self->flags; - hash ^= self->isbytes; - hash ^= self->codesize; - - if (hash == -1) { - hash = -2; - } - return hash; -} - -static PyObject* -pattern_richcompare(PyObject *lefto, PyObject *righto, int op) -{ - PatternObject *left, *right; - int cmp; - - if (op != Py_EQ && op != Py_NE) { - Py_RETURN_NOTIMPLEMENTED; - } - + if (!scanner) + return NULL; + scanner->pattern = NULL; + + /* create search state object */ + if (!state_init(&scanner->state, self, string, pos, endpos)) { + Py_DECREF(scanner); + return NULL; + } + + Py_INCREF(self); + scanner->pattern = (PyObject*) self; + + return (PyObject*) scanner; +} + +static Py_hash_t +pattern_hash(PatternObject *self) +{ + Py_hash_t hash, hash2; + + hash = PyObject_Hash(self->pattern); + if (hash == -1) { + return -1; + } + + hash2 = _Py_HashBytes(self->code, sizeof(self->code[0]) * self->codesize); + hash ^= hash2; + + hash ^= self->flags; + hash ^= self->isbytes; + hash ^= self->codesize; + + if (hash == -1) { + hash = -2; + } + return hash; +} + +static PyObject* +pattern_richcompare(PyObject *lefto, PyObject *righto, int op) +{ + PatternObject *left, *right; + int cmp; + + if (op != Py_EQ && op != Py_NE) { + Py_RETURN_NOTIMPLEMENTED; + } + if (!Py_IS_TYPE(lefto, &Pattern_Type) || !Py_IS_TYPE(righto, &Pattern_Type)) { - Py_RETURN_NOTIMPLEMENTED; - } - - if (lefto == righto) { - /* a pattern is equal to itself */ - return PyBool_FromLong(op == Py_EQ); - } - - left = (PatternObject *)lefto; - right = (PatternObject *)righto; - - cmp = (left->flags == right->flags - && left->isbytes == right->isbytes - && left->codesize == right->codesize); - if (cmp) { - /* Compare the code and the pattern because the same pattern can - produce different codes depending on the locale used to compile the - pattern when the re.LOCALE flag is used. Don't compare groups, - indexgroup nor groupindex: they are derivated from the pattern. */ - cmp = (memcmp(left->code, right->code, - sizeof(left->code[0]) * left->codesize) == 0); - } - if (cmp) { - cmp = PyObject_RichCompareBool(left->pattern, right->pattern, - Py_EQ); - if (cmp < 0) { - return NULL; - } - } - if (op == Py_NE) { - cmp = !cmp; - } - return PyBool_FromLong(cmp); -} - -#include "clinic/_sre.c.h" - -static PyMethodDef pattern_methods[] = { - _SRE_SRE_PATTERN_MATCH_METHODDEF - _SRE_SRE_PATTERN_FULLMATCH_METHODDEF - _SRE_SRE_PATTERN_SEARCH_METHODDEF - _SRE_SRE_PATTERN_SUB_METHODDEF - _SRE_SRE_PATTERN_SUBN_METHODDEF - _SRE_SRE_PATTERN_FINDALL_METHODDEF - _SRE_SRE_PATTERN_SPLIT_METHODDEF - _SRE_SRE_PATTERN_FINDITER_METHODDEF - _SRE_SRE_PATTERN_SCANNER_METHODDEF - _SRE_SRE_PATTERN___COPY___METHODDEF - _SRE_SRE_PATTERN___DEEPCOPY___METHODDEF + Py_RETURN_NOTIMPLEMENTED; + } + + if (lefto == righto) { + /* a pattern is equal to itself */ + return PyBool_FromLong(op == Py_EQ); + } + + left = (PatternObject *)lefto; + right = (PatternObject *)righto; + + cmp = (left->flags == right->flags + && left->isbytes == right->isbytes + && left->codesize == right->codesize); + if (cmp) { + /* Compare the code and the pattern because the same pattern can + produce different codes depending on the locale used to compile the + pattern when the re.LOCALE flag is used. Don't compare groups, + indexgroup nor groupindex: they are derivated from the pattern. */ + cmp = (memcmp(left->code, right->code, + sizeof(left->code[0]) * left->codesize) == 0); + } + if (cmp) { + cmp = PyObject_RichCompareBool(left->pattern, right->pattern, + Py_EQ); + if (cmp < 0) { + return NULL; + } + } + if (op == Py_NE) { + cmp = !cmp; + } + return PyBool_FromLong(cmp); +} + +#include "clinic/_sre.c.h" + +static PyMethodDef pattern_methods[] = { + _SRE_SRE_PATTERN_MATCH_METHODDEF + _SRE_SRE_PATTERN_FULLMATCH_METHODDEF + _SRE_SRE_PATTERN_SEARCH_METHODDEF + _SRE_SRE_PATTERN_SUB_METHODDEF + _SRE_SRE_PATTERN_SUBN_METHODDEF + _SRE_SRE_PATTERN_FINDALL_METHODDEF + _SRE_SRE_PATTERN_SPLIT_METHODDEF + _SRE_SRE_PATTERN_FINDITER_METHODDEF + _SRE_SRE_PATTERN_SCANNER_METHODDEF + _SRE_SRE_PATTERN___COPY___METHODDEF + _SRE_SRE_PATTERN___DEEPCOPY___METHODDEF {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL, NULL} -}; - -static PyGetSetDef pattern_getset[] = { - {"groupindex", (getter)pattern_groupindex, (setter)NULL, - "A dictionary mapping group names to group numbers."}, - {NULL} /* Sentinel */ -}; - -#define PAT_OFF(x) offsetof(PatternObject, x) -static PyMemberDef pattern_members[] = { - {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY, - "The pattern string from which the RE object was compiled."}, - {"flags", T_INT, PAT_OFF(flags), READONLY, - "The regex matching flags."}, - {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY, - "The number of capturing groups in the pattern."}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject Pattern_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "re.Pattern", - sizeof(PatternObject), sizeof(SRE_CODE), - (destructor)pattern_dealloc, /* tp_dealloc */ + {NULL, NULL} +}; + +static PyGetSetDef pattern_getset[] = { + {"groupindex", (getter)pattern_groupindex, (setter)NULL, + "A dictionary mapping group names to group numbers."}, + {NULL} /* Sentinel */ +}; + +#define PAT_OFF(x) offsetof(PatternObject, x) +static PyMemberDef pattern_members[] = { + {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY, + "The pattern string from which the RE object was compiled."}, + {"flags", T_INT, PAT_OFF(flags), READONLY, + "The regex matching flags."}, + {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY, + "The number of capturing groups in the pattern."}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject Pattern_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "re.Pattern", + sizeof(PatternObject), sizeof(SRE_CODE), + (destructor)pattern_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)pattern_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)pattern_hash, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - pattern_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - pattern_richcompare, /* tp_richcompare */ - offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pattern_methods, /* tp_methods */ - pattern_members, /* tp_members */ - pattern_getset, /* tp_getset */ -}; - -/* Match objects do not support length or assignment, but do support - __getitem__. */ -static PyMappingMethods match_as_mapping = { - NULL, - (binaryfunc)match_getitem, - NULL -}; - -static PyMethodDef match_methods[] = { - {"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc}, - _SRE_SRE_MATCH_START_METHODDEF - _SRE_SRE_MATCH_END_METHODDEF - _SRE_SRE_MATCH_SPAN_METHODDEF - _SRE_SRE_MATCH_GROUPS_METHODDEF - _SRE_SRE_MATCH_GROUPDICT_METHODDEF - _SRE_SRE_MATCH_EXPAND_METHODDEF - _SRE_SRE_MATCH___COPY___METHODDEF - _SRE_SRE_MATCH___DEEPCOPY___METHODDEF + (reprfunc)pattern_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)pattern_hash, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + pattern_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + pattern_richcompare, /* tp_richcompare */ + offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pattern_methods, /* tp_methods */ + pattern_members, /* tp_members */ + pattern_getset, /* tp_getset */ +}; + +/* Match objects do not support length or assignment, but do support + __getitem__. */ +static PyMappingMethods match_as_mapping = { + NULL, + (binaryfunc)match_getitem, + NULL +}; + +static PyMethodDef match_methods[] = { + {"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc}, + _SRE_SRE_MATCH_START_METHODDEF + _SRE_SRE_MATCH_END_METHODDEF + _SRE_SRE_MATCH_SPAN_METHODDEF + _SRE_SRE_MATCH_GROUPS_METHODDEF + _SRE_SRE_MATCH_GROUPDICT_METHODDEF + _SRE_SRE_MATCH_EXPAND_METHODDEF + _SRE_SRE_MATCH___COPY___METHODDEF + _SRE_SRE_MATCH___DEEPCOPY___METHODDEF {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL, NULL} -}; - -static PyGetSetDef match_getset[] = { - {"lastindex", (getter)match_lastindex_get, (setter)NULL, - "The integer index of the last matched capturing group."}, - {"lastgroup", (getter)match_lastgroup_get, (setter)NULL, - "The name of the last matched capturing group."}, - {"regs", (getter)match_regs_get, (setter)NULL}, - {NULL} -}; - -#define MATCH_OFF(x) offsetof(MatchObject, x) -static PyMemberDef match_members[] = { - {"string", T_OBJECT, MATCH_OFF(string), READONLY, - "The string passed to match() or search()."}, - {"re", T_OBJECT, MATCH_OFF(pattern), READONLY, - "The regular expression object."}, - {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY, - "The index into the string at which the RE engine started looking for a match."}, - {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY, - "The index into the string beyond which the RE engine will not go."}, - {NULL} -}; - -/* FIXME: implement setattr("string", None) as a special case (to - detach the associated string, if any */ - -static PyTypeObject Match_Type = { - PyVarObject_HEAD_INIT(NULL,0) - "re.Match", - sizeof(MatchObject), sizeof(Py_ssize_t), - (destructor)match_dealloc, /* tp_dealloc */ + {NULL, NULL} +}; + +static PyGetSetDef match_getset[] = { + {"lastindex", (getter)match_lastindex_get, (setter)NULL, + "The integer index of the last matched capturing group."}, + {"lastgroup", (getter)match_lastgroup_get, (setter)NULL, + "The name of the last matched capturing group."}, + {"regs", (getter)match_regs_get, (setter)NULL}, + {NULL} +}; + +#define MATCH_OFF(x) offsetof(MatchObject, x) +static PyMemberDef match_members[] = { + {"string", T_OBJECT, MATCH_OFF(string), READONLY, + "The string passed to match() or search()."}, + {"re", T_OBJECT, MATCH_OFF(pattern), READONLY, + "The regular expression object."}, + {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY, + "The index into the string at which the RE engine started looking for a match."}, + {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY, + "The index into the string beyond which the RE engine will not go."}, + {NULL} +}; + +/* FIXME: implement setattr("string", None) as a special case (to + detach the associated string, if any */ + +static PyTypeObject Match_Type = { + PyVarObject_HEAD_INIT(NULL,0) + "re.Match", + sizeof(MatchObject), sizeof(Py_ssize_t), + (destructor)match_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)match_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - &match_as_mapping, /* 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 */ - match_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - match_methods, /* tp_methods */ - match_members, /* tp_members */ - match_getset, /* tp_getset */ -}; - -static PyMethodDef scanner_methods[] = { - _SRE_SRE_SCANNER_MATCH_METHODDEF - _SRE_SRE_SCANNER_SEARCH_METHODDEF - {NULL, NULL} -}; - -#define SCAN_OFF(x) offsetof(ScannerObject, x) -static PyMemberDef scanner_members[] = { - {"pattern", T_OBJECT, SCAN_OFF(pattern), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject Scanner_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_" SRE_MODULE ".SRE_Scanner", - sizeof(ScannerObject), 0, - (destructor)scanner_dealloc,/* tp_dealloc */ + (reprfunc)match_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + &match_as_mapping, /* 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 */ + match_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + match_methods, /* tp_methods */ + match_members, /* tp_members */ + match_getset, /* tp_getset */ +}; + +static PyMethodDef scanner_methods[] = { + _SRE_SRE_SCANNER_MATCH_METHODDEF + _SRE_SRE_SCANNER_SEARCH_METHODDEF + {NULL, NULL} +}; + +#define SCAN_OFF(x) offsetof(ScannerObject, x) +static PyMemberDef scanner_members[] = { + {"pattern", T_OBJECT, SCAN_OFF(pattern), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject Scanner_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_" SRE_MODULE ".SRE_Scanner", + sizeof(ScannerObject), 0, + (destructor)scanner_dealloc,/* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - scanner_methods, /* tp_methods */ - scanner_members, /* tp_members */ - 0, /* tp_getset */ -}; - -static PyMethodDef _functions[] = { - _SRE_COMPILE_METHODDEF - _SRE_GETCODESIZE_METHODDEF - _SRE_ASCII_ISCASED_METHODDEF - _SRE_UNICODE_ISCASED_METHODDEF - _SRE_ASCII_TOLOWER_METHODDEF - _SRE_UNICODE_TOLOWER_METHODDEF - {NULL, NULL} -}; - -static struct PyModuleDef sremodule = { - PyModuleDef_HEAD_INIT, - "_" SRE_MODULE, - NULL, - -1, - _functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC PyInit__sre(void) -{ - PyObject* m; - PyObject* d; - PyObject* x; - - /* Patch object types */ - if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) || - PyType_Ready(&Scanner_Type)) - return NULL; - - m = PyModule_Create(&sremodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - - x = PyLong_FromLong(SRE_MAGIC); - if (x) { - PyDict_SetItemString(d, "MAGIC", x); - Py_DECREF(x); - } - - x = PyLong_FromLong(sizeof(SRE_CODE)); - if (x) { - PyDict_SetItemString(d, "CODESIZE", x); - Py_DECREF(x); - } - - x = PyLong_FromUnsignedLong(SRE_MAXREPEAT); - if (x) { - PyDict_SetItemString(d, "MAXREPEAT", x); - Py_DECREF(x); - } - - x = PyLong_FromUnsignedLong(SRE_MAXGROUPS); - if (x) { - PyDict_SetItemString(d, "MAXGROUPS", x); - Py_DECREF(x); - } - - x = PyUnicode_FromString(copyright); - if (x) { - PyDict_SetItemString(d, "copyright", x); - Py_DECREF(x); - } - return m; -} - -/* vim:ts=4:sw=4:et -*/ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + scanner_methods, /* tp_methods */ + scanner_members, /* tp_members */ + 0, /* tp_getset */ +}; + +static PyMethodDef _functions[] = { + _SRE_COMPILE_METHODDEF + _SRE_GETCODESIZE_METHODDEF + _SRE_ASCII_ISCASED_METHODDEF + _SRE_UNICODE_ISCASED_METHODDEF + _SRE_ASCII_TOLOWER_METHODDEF + _SRE_UNICODE_TOLOWER_METHODDEF + {NULL, NULL} +}; + +static struct PyModuleDef sremodule = { + PyModuleDef_HEAD_INIT, + "_" SRE_MODULE, + NULL, + -1, + _functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit__sre(void) +{ + PyObject* m; + PyObject* d; + PyObject* x; + + /* Patch object types */ + if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) || + PyType_Ready(&Scanner_Type)) + return NULL; + + m = PyModule_Create(&sremodule); + if (m == NULL) + return NULL; + d = PyModule_GetDict(m); + + x = PyLong_FromLong(SRE_MAGIC); + if (x) { + PyDict_SetItemString(d, "MAGIC", x); + Py_DECREF(x); + } + + x = PyLong_FromLong(sizeof(SRE_CODE)); + if (x) { + PyDict_SetItemString(d, "CODESIZE", x); + Py_DECREF(x); + } + + x = PyLong_FromUnsignedLong(SRE_MAXREPEAT); + if (x) { + PyDict_SetItemString(d, "MAXREPEAT", x); + Py_DECREF(x); + } + + x = PyLong_FromUnsignedLong(SRE_MAXGROUPS); + if (x) { + PyDict_SetItemString(d, "MAXGROUPS", x); + Py_DECREF(x); + } + + x = PyUnicode_FromString(copyright); + if (x) { + PyDict_SetItemString(d, "copyright", x); + Py_DECREF(x); + } + return m; +} + +/* vim:ts=4:sw=4:et +*/ diff --git a/contrib/tools/python3/src/Modules/_ssl.c b/contrib/tools/python3/src/Modules/_ssl.c index b42e78e916b..86f106cb49d 100644 --- a/contrib/tools/python3/src/Modules/_ssl.c +++ b/contrib/tools/python3/src/Modules/_ssl.c @@ -1,19 +1,19 @@ -/* SSL socket module - - SSL support based on patches by Brian E Gallew and Laszlo Kovacs. - Re-worked a bit by Bill Janssen to add server-side support and - certificate decoding. Chris Stawarz contributed some non-blocking - patches. - - This module is imported by ssl.py. It should *not* be used - directly. - - XXX should partial writes be enabled, SSL_MODE_ENABLE_PARTIAL_WRITE? - - XXX integrate several "shutdown modes" as suggested in - http://bugs.python.org/issue8108#msg102867 ? -*/ - +/* SSL socket module + + SSL support based on patches by Brian E Gallew and Laszlo Kovacs. + Re-worked a bit by Bill Janssen to add server-side support and + certificate decoding. Chris Stawarz contributed some non-blocking + patches. + + This module is imported by ssl.py. It should *not* be used + directly. + + XXX should partial writes be enabled, SSL_MODE_ENABLE_PARTIAL_WRITE? + + XXX integrate several "shutdown modes" as suggested in + http://bugs.python.org/issue8108#msg102867 ? +*/ + /* Don't warn about deprecated functions, */ #ifndef OPENSSL_API_COMPAT // 0x10101000L == 1.1.1, 30000 == 3.0.0 @@ -21,136 +21,136 @@ #endif #define OPENSSL_NO_DEPRECATED 1 -#define PY_SSIZE_T_CLEAN - -#include "Python.h" - -/* Redefined below for Windows debug builds after important #includes */ -#define _PySSL_FIX_ERRNO - -#define PySSL_BEGIN_ALLOW_THREADS_S(save) \ - do { if (_ssl_locks_count>0) { (save) = PyEval_SaveThread(); } } while (0) -#define PySSL_END_ALLOW_THREADS_S(save) \ - do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } _PySSL_FIX_ERRNO; } while (0) -#define PySSL_BEGIN_ALLOW_THREADS { \ - PyThreadState *_save = NULL; \ - PySSL_BEGIN_ALLOW_THREADS_S(_save); -#define PySSL_BLOCK_THREADS PySSL_END_ALLOW_THREADS_S(_save); -#define PySSL_UNBLOCK_THREADS PySSL_BEGIN_ALLOW_THREADS_S(_save); -#define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } - -/* Include symbols from _socket module */ -#include "socketmodule.h" - -static PySocketModule_APIObject PySocketModule; - -#if defined(HAVE_POLL_H) -#include -#elif defined(HAVE_SYS_POLL_H) -#include -#endif - -#ifdef _MSC_VER -#include -#endif - -/* Include OpenSSL header files */ -#include "openssl/rsa.h" -#include "openssl/crypto.h" -#include "openssl/x509.h" -#include "openssl/x509v3.h" -#include "openssl/pem.h" -#include "openssl/ssl.h" -#include "openssl/err.h" -#include "openssl/rand.h" -#include "openssl/bio.h" -#include "openssl/dh.h" - -#ifndef HAVE_X509_VERIFY_PARAM_SET1_HOST -# ifdef LIBRESSL_VERSION_NUMBER -# error "LibreSSL is missing X509_VERIFY_PARAM_set1_host(), see https://github.com/libressl-portable/portable/issues/381" -# elif OPENSSL_VERSION_NUMBER > 0x1000200fL -# define HAVE_X509_VERIFY_PARAM_SET1_HOST -# else -# error "libssl is too old and does not support X509_VERIFY_PARAM_set1_host()" -# endif -#endif - +#define PY_SSIZE_T_CLEAN + +#include "Python.h" + +/* Redefined below for Windows debug builds after important #includes */ +#define _PySSL_FIX_ERRNO + +#define PySSL_BEGIN_ALLOW_THREADS_S(save) \ + do { if (_ssl_locks_count>0) { (save) = PyEval_SaveThread(); } } while (0) +#define PySSL_END_ALLOW_THREADS_S(save) \ + do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } _PySSL_FIX_ERRNO; } while (0) +#define PySSL_BEGIN_ALLOW_THREADS { \ + PyThreadState *_save = NULL; \ + PySSL_BEGIN_ALLOW_THREADS_S(_save); +#define PySSL_BLOCK_THREADS PySSL_END_ALLOW_THREADS_S(_save); +#define PySSL_UNBLOCK_THREADS PySSL_BEGIN_ALLOW_THREADS_S(_save); +#define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } + +/* Include symbols from _socket module */ +#include "socketmodule.h" + +static PySocketModule_APIObject PySocketModule; + +#if defined(HAVE_POLL_H) +#include +#elif defined(HAVE_SYS_POLL_H) +#include +#endif + +#ifdef _MSC_VER +#include +#endif + +/* Include OpenSSL header files */ +#include "openssl/rsa.h" +#include "openssl/crypto.h" +#include "openssl/x509.h" +#include "openssl/x509v3.h" +#include "openssl/pem.h" +#include "openssl/ssl.h" +#include "openssl/err.h" +#include "openssl/rand.h" +#include "openssl/bio.h" +#include "openssl/dh.h" + +#ifndef HAVE_X509_VERIFY_PARAM_SET1_HOST +# ifdef LIBRESSL_VERSION_NUMBER +# error "LibreSSL is missing X509_VERIFY_PARAM_set1_host(), see https://github.com/libressl-portable/portable/issues/381" +# elif OPENSSL_VERSION_NUMBER > 0x1000200fL +# define HAVE_X509_VERIFY_PARAM_SET1_HOST +# else +# error "libssl is too old and does not support X509_VERIFY_PARAM_set1_host()" +# endif +#endif + #ifndef OPENSSL_THREADS # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" #endif -/* SSL error object */ -static PyObject *PySSLErrorObject; -static PyObject *PySSLCertVerificationErrorObject; -static PyObject *PySSLZeroReturnErrorObject; -static PyObject *PySSLWantReadErrorObject; -static PyObject *PySSLWantWriteErrorObject; -static PyObject *PySSLSyscallErrorObject; -static PyObject *PySSLEOFErrorObject; - -/* Error mappings */ -static PyObject *err_codes_to_names; -static PyObject *err_names_to_codes; -static PyObject *lib_codes_to_names; - -struct py_ssl_error_code { - const char *mnemonic; - int library, reason; -}; -struct py_ssl_library_code { - const char *library; - int code; -}; - -#if defined(MS_WINDOWS) && defined(Py_DEBUG) -/* Debug builds on Windows rely on getting errno directly from OpenSSL. - * However, because it uses a different CRT, we need to transfer the - * value of errno from OpenSSL into our debug CRT. - * - * Don't be fooled - this is horribly ugly code. The only reasonable - * alternative is to do both debug and release builds of OpenSSL, which - * requires much uglier code to transform their automatically generated - * makefile. This is the lesser of all the evils. - */ - -static void _PySSLFixErrno(void) { - HMODULE ucrtbase = GetModuleHandleW(L"ucrtbase.dll"); - if (!ucrtbase) { - /* If ucrtbase.dll is not loaded but the SSL DLLs are, we likely - * have a catastrophic failure, but this function is not the - * place to raise it. */ - return; - } - - typedef int *(__stdcall *errno_func)(void); - errno_func ssl_errno = (errno_func)GetProcAddress(ucrtbase, "_errno"); - if (ssl_errno) { - errno = *ssl_errno(); - *ssl_errno() = 0; - } else { - errno = ENOTRECOVERABLE; - } -} - -#undef _PySSL_FIX_ERRNO -#define _PySSL_FIX_ERRNO _PySSLFixErrno() -#endif - -/* Include generated data (error codes) */ +/* SSL error object */ +static PyObject *PySSLErrorObject; +static PyObject *PySSLCertVerificationErrorObject; +static PyObject *PySSLZeroReturnErrorObject; +static PyObject *PySSLWantReadErrorObject; +static PyObject *PySSLWantWriteErrorObject; +static PyObject *PySSLSyscallErrorObject; +static PyObject *PySSLEOFErrorObject; + +/* Error mappings */ +static PyObject *err_codes_to_names; +static PyObject *err_names_to_codes; +static PyObject *lib_codes_to_names; + +struct py_ssl_error_code { + const char *mnemonic; + int library, reason; +}; +struct py_ssl_library_code { + const char *library; + int code; +}; + +#if defined(MS_WINDOWS) && defined(Py_DEBUG) +/* Debug builds on Windows rely on getting errno directly from OpenSSL. + * However, because it uses a different CRT, we need to transfer the + * value of errno from OpenSSL into our debug CRT. + * + * Don't be fooled - this is horribly ugly code. The only reasonable + * alternative is to do both debug and release builds of OpenSSL, which + * requires much uglier code to transform their automatically generated + * makefile. This is the lesser of all the evils. + */ + +static void _PySSLFixErrno(void) { + HMODULE ucrtbase = GetModuleHandleW(L"ucrtbase.dll"); + if (!ucrtbase) { + /* If ucrtbase.dll is not loaded but the SSL DLLs are, we likely + * have a catastrophic failure, but this function is not the + * place to raise it. */ + return; + } + + typedef int *(__stdcall *errno_func)(void); + errno_func ssl_errno = (errno_func)GetProcAddress(ucrtbase, "_errno"); + if (ssl_errno) { + errno = *ssl_errno(); + *ssl_errno() = 0; + } else { + errno = ENOTRECOVERABLE; + } +} + +#undef _PySSL_FIX_ERRNO +#define _PySSL_FIX_ERRNO _PySSLFixErrno() +#endif + +/* Include generated data (error codes) */ #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) #include "_ssl_data_300.h" #elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) #include "_ssl_data_111.h" #else -#include "_ssl_data.h" -#endif - -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) -# define OPENSSL_VERSION_1_1 1 -# define PY_OPENSSL_1_1_API 1 -#endif - +#include "_ssl_data.h" +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) +# define OPENSSL_VERSION_1_1 1 +# define PY_OPENSSL_1_1_API 1 +#endif + /* OpenSSL API 1.1.0+ does not include version methods. Define the methods * unless OpenSSL is compiled without the methods. It's the easiest way to * make 1.0.2, 1.1.0, 1.1.1, and 3.0.0 happy without deprecation warnings. @@ -165,312 +165,312 @@ extern const SSL_METHOD *TLSv1_1_method(void); extern const SSL_METHOD *TLSv1_2_method(void); #endif -/* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */ -#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL -# define PY_OPENSSL_1_1_API 1 -#endif - -/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f - * This includes the SSL_set_SSL_CTX() function. - */ -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -# define HAVE_SNI 1 -#else -# define HAVE_SNI 0 -#endif - -#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation -# define HAVE_ALPN 1 -#else -# define HAVE_ALPN 0 -#endif - -/* We cannot rely on OPENSSL_NO_NEXTPROTONEG because LibreSSL 2.6.1 dropped - * NPN support but did not set OPENSSL_NO_NEXTPROTONEG for compatibility - * reasons. The check for TLSEXT_TYPE_next_proto_neg works with - * OpenSSL 1.0.1+ and LibreSSL. - * OpenSSL 1.1.1-pre1 dropped NPN but still has TLSEXT_TYPE_next_proto_neg. - */ -#ifdef OPENSSL_NO_NEXTPROTONEG -# define HAVE_NPN 0 -#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) -# define HAVE_NPN 0 -#elif defined(TLSEXT_TYPE_next_proto_neg) -# define HAVE_NPN 1 -#else -# define HAVE_NPN 0 -#endif - +/* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */ +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL +# define PY_OPENSSL_1_1_API 1 +#endif + +/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f + * This includes the SSL_set_SSL_CTX() function. + */ +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME +# define HAVE_SNI 1 +#else +# define HAVE_SNI 0 +#endif + +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation +# define HAVE_ALPN 1 +#else +# define HAVE_ALPN 0 +#endif + +/* We cannot rely on OPENSSL_NO_NEXTPROTONEG because LibreSSL 2.6.1 dropped + * NPN support but did not set OPENSSL_NO_NEXTPROTONEG for compatibility + * reasons. The check for TLSEXT_TYPE_next_proto_neg works with + * OpenSSL 1.0.1+ and LibreSSL. + * OpenSSL 1.1.1-pre1 dropped NPN but still has TLSEXT_TYPE_next_proto_neg. + */ +#ifdef OPENSSL_NO_NEXTPROTONEG +# define HAVE_NPN 0 +#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +# define HAVE_NPN 0 +#elif defined(TLSEXT_TYPE_next_proto_neg) +# define HAVE_NPN 1 +#else +# define HAVE_NPN 0 +#endif + #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) #define HAVE_OPENSSL_KEYLOG 1 #endif -#ifndef INVALID_SOCKET /* MS defines this */ -#define INVALID_SOCKET (-1) -#endif - -/* OpenSSL 1.0.2 and LibreSSL needs extra code for locking */ -#ifndef OPENSSL_VERSION_1_1 -#define HAVE_OPENSSL_CRYPTO_LOCK -#endif - -#if defined(OPENSSL_VERSION_1_1) && !defined(OPENSSL_NO_SSL2) -#define OPENSSL_NO_SSL2 -#endif - -#ifndef PY_OPENSSL_1_1_API -/* OpenSSL 1.1 API shims for OpenSSL < 1.1.0 and LibreSSL < 2.7.0 */ - -#define TLS_method SSLv23_method -#define TLS_client_method SSLv23_client_method -#define TLS_server_method SSLv23_server_method +#ifndef INVALID_SOCKET /* MS defines this */ +#define INVALID_SOCKET (-1) +#endif + +/* OpenSSL 1.0.2 and LibreSSL needs extra code for locking */ +#ifndef OPENSSL_VERSION_1_1 +#define HAVE_OPENSSL_CRYPTO_LOCK +#endif + +#if defined(OPENSSL_VERSION_1_1) && !defined(OPENSSL_NO_SSL2) +#define OPENSSL_NO_SSL2 +#endif + +#ifndef PY_OPENSSL_1_1_API +/* OpenSSL 1.1 API shims for OpenSSL < 1.1.0 and LibreSSL < 2.7.0 */ + +#define TLS_method SSLv23_method +#define TLS_client_method SSLv23_client_method +#define TLS_server_method SSLv23_server_method #define ASN1_STRING_get0_data ASN1_STRING_data #define X509_get0_notBefore X509_get_notBefore #define X509_get0_notAfter X509_get_notAfter #define OpenSSL_version_num SSLeay #define OpenSSL_version SSLeay_version #define OPENSSL_VERSION SSLEAY_VERSION - -static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) -{ - return ne->set; -} - -#ifndef OPENSSL_NO_COMP -/* LCOV_EXCL_START */ -static int COMP_get_type(const COMP_METHOD *meth) -{ - return meth->type; -} -/* LCOV_EXCL_STOP */ -#endif - -static pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) -{ - return ctx->default_passwd_callback; -} - -static void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) -{ - return ctx->default_passwd_callback_userdata; -} - -static int X509_OBJECT_get_type(X509_OBJECT *x) -{ - return x->type; -} - -static X509 *X509_OBJECT_get0_X509(X509_OBJECT *x) -{ - return x->data.x509; -} - -static int BIO_up_ref(BIO *b) -{ - CRYPTO_add(&b->references, 1, CRYPTO_LOCK_BIO); - return 1; -} - -static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store) { - return store->objs; -} - -static int -SSL_SESSION_has_ticket(const SSL_SESSION *s) -{ - return (s->tlsext_ticklen > 0) ? 1 : 0; -} - -static unsigned long -SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s) -{ - return s->tlsext_tick_lifetime_hint; -} - -#endif /* OpenSSL < 1.1.0 or LibreSSL < 2.7.0 */ - -/* Default cipher suites */ -#ifndef PY_SSL_DEFAULT_CIPHERS -#define PY_SSL_DEFAULT_CIPHERS 1 -#endif - -#if PY_SSL_DEFAULT_CIPHERS == 0 - #ifndef PY_SSL_DEFAULT_CIPHER_STRING - #error "Py_SSL_DEFAULT_CIPHERS 0 needs Py_SSL_DEFAULT_CIPHER_STRING" - #endif -#elif PY_SSL_DEFAULT_CIPHERS == 1 -/* Python custom selection of sensible cipher suites - * DEFAULT: OpenSSL's default cipher list. Since 1.0.2 the list is in sensible order. - * !aNULL:!eNULL: really no NULL ciphers - * !MD5:!3DES:!DES:!RC4:!IDEA:!SEED: no weak or broken algorithms on old OpenSSL versions. - * !aDSS: no authentication with discrete logarithm DSA algorithm - * !SRP:!PSK: no secure remote password or pre-shared key authentication - */ - #define PY_SSL_DEFAULT_CIPHER_STRING "DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK" -#elif PY_SSL_DEFAULT_CIPHERS == 2 -/* Ignored in SSLContext constructor, only used to as _ssl.DEFAULT_CIPHER_STRING */ - #define PY_SSL_DEFAULT_CIPHER_STRING SSL_DEFAULT_CIPHER_LIST -#else - #error "Unsupported PY_SSL_DEFAULT_CIPHERS" -#endif - - -enum py_ssl_error { - /* these mirror ssl.h */ - PY_SSL_ERROR_NONE, - PY_SSL_ERROR_SSL, - PY_SSL_ERROR_WANT_READ, - PY_SSL_ERROR_WANT_WRITE, - PY_SSL_ERROR_WANT_X509_LOOKUP, - PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */ - PY_SSL_ERROR_ZERO_RETURN, - PY_SSL_ERROR_WANT_CONNECT, - /* start of non ssl.h errorcodes */ - PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */ - PY_SSL_ERROR_NO_SOCKET, /* socket has been GC'd */ - PY_SSL_ERROR_INVALID_ERROR_CODE -}; - -enum py_ssl_server_or_client { - PY_SSL_CLIENT, - PY_SSL_SERVER -}; - -enum py_ssl_cert_requirements { - PY_SSL_CERT_NONE, - PY_SSL_CERT_OPTIONAL, - PY_SSL_CERT_REQUIRED -}; - -enum py_ssl_version { - PY_SSL_VERSION_SSL2, - PY_SSL_VERSION_SSL3=1, - PY_SSL_VERSION_TLS, /* SSLv23 */ - PY_SSL_VERSION_TLS1, - PY_SSL_VERSION_TLS1_1, - PY_SSL_VERSION_TLS1_2, - PY_SSL_VERSION_TLS_CLIENT=0x10, - PY_SSL_VERSION_TLS_SERVER, -}; - -enum py_proto_version { - PY_PROTO_MINIMUM_SUPPORTED = -2, - PY_PROTO_SSLv3 = SSL3_VERSION, - PY_PROTO_TLSv1 = TLS1_VERSION, - PY_PROTO_TLSv1_1 = TLS1_1_VERSION, - PY_PROTO_TLSv1_2 = TLS1_2_VERSION, -#ifdef TLS1_3_VERSION - PY_PROTO_TLSv1_3 = TLS1_3_VERSION, -#else - PY_PROTO_TLSv1_3 = 0x304, -#endif - PY_PROTO_MAXIMUM_SUPPORTED = -1, - -/* OpenSSL has no dedicated API to set the minimum version to the maximum - * available version, and the other way around. We have to figure out the - * minimum and maximum available version on our own and hope for the best. - */ -#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) - PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_SSLv3, -#elif defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) - PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_TLSv1, -#elif defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) - PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_TLSv1_1, -#elif defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) - PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_TLSv1_2, -#elif defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) - PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_TLSv1_3, -#else - #error "PY_PROTO_MINIMUM_AVAILABLE not found" -#endif - -#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) - PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_TLSv1_3, -#elif defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) - PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_TLSv1_2, -#elif defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) - PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_TLSv1_1, -#elif defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) - PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_TLSv1, -#elif defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) - PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_SSLv3, -#else - #error "PY_PROTO_MAXIMUM_AVAILABLE not found" -#endif -}; - - -/* serves as a flag to see whether we've initialized the SSL thread support. */ -/* 0 means no, greater than 0 means yes */ - -static unsigned int _ssl_locks_count = 0; - -/* SSL socket object */ - -#define X509_NAME_MAXLEN 256 - -/* SSL_CTX_clear_options() and SSL_clear_options() were first added in - * OpenSSL 0.9.8m but do not appear in some 0.9.9-dev versions such the - * 0.9.9 from "May 2008" that NetBSD 5.0 uses. */ -#if OPENSSL_VERSION_NUMBER >= 0x009080dfL && OPENSSL_VERSION_NUMBER != 0x00909000L -# define HAVE_SSL_CTX_CLEAR_OPTIONS -#else -# undef HAVE_SSL_CTX_CLEAR_OPTIONS -#endif - -/* In case of 'tls-unique' it will be 12 bytes for TLS, 36 bytes for - * older SSL, but let's be safe */ -#define PySSL_CB_MAXLEN 128 - - -typedef struct { - PyObject_HEAD - SSL_CTX *ctx; -#if HAVE_NPN - unsigned char *npn_protocols; - int npn_protocols_len; -#endif -#if HAVE_ALPN - unsigned char *alpn_protocols; - unsigned int alpn_protocols_len; -#endif -#ifndef OPENSSL_NO_TLSEXT - PyObject *set_sni_cb; -#endif - int check_hostname; - /* OpenSSL has no API to get hostflags from X509_VERIFY_PARAM* struct. - * We have to maintain our own copy. OpenSSL's hostflags default to 0. - */ - unsigned int hostflags; - int protocol; -#ifdef TLS1_3_VERSION - int post_handshake_auth; -#endif + +static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) +{ + return ne->set; +} + +#ifndef OPENSSL_NO_COMP +/* LCOV_EXCL_START */ +static int COMP_get_type(const COMP_METHOD *meth) +{ + return meth->type; +} +/* LCOV_EXCL_STOP */ +#endif + +static pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) +{ + return ctx->default_passwd_callback; +} + +static void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) +{ + return ctx->default_passwd_callback_userdata; +} + +static int X509_OBJECT_get_type(X509_OBJECT *x) +{ + return x->type; +} + +static X509 *X509_OBJECT_get0_X509(X509_OBJECT *x) +{ + return x->data.x509; +} + +static int BIO_up_ref(BIO *b) +{ + CRYPTO_add(&b->references, 1, CRYPTO_LOCK_BIO); + return 1; +} + +static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store) { + return store->objs; +} + +static int +SSL_SESSION_has_ticket(const SSL_SESSION *s) +{ + return (s->tlsext_ticklen > 0) ? 1 : 0; +} + +static unsigned long +SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s) +{ + return s->tlsext_tick_lifetime_hint; +} + +#endif /* OpenSSL < 1.1.0 or LibreSSL < 2.7.0 */ + +/* Default cipher suites */ +#ifndef PY_SSL_DEFAULT_CIPHERS +#define PY_SSL_DEFAULT_CIPHERS 1 +#endif + +#if PY_SSL_DEFAULT_CIPHERS == 0 + #ifndef PY_SSL_DEFAULT_CIPHER_STRING + #error "Py_SSL_DEFAULT_CIPHERS 0 needs Py_SSL_DEFAULT_CIPHER_STRING" + #endif +#elif PY_SSL_DEFAULT_CIPHERS == 1 +/* Python custom selection of sensible cipher suites + * DEFAULT: OpenSSL's default cipher list. Since 1.0.2 the list is in sensible order. + * !aNULL:!eNULL: really no NULL ciphers + * !MD5:!3DES:!DES:!RC4:!IDEA:!SEED: no weak or broken algorithms on old OpenSSL versions. + * !aDSS: no authentication with discrete logarithm DSA algorithm + * !SRP:!PSK: no secure remote password or pre-shared key authentication + */ + #define PY_SSL_DEFAULT_CIPHER_STRING "DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK" +#elif PY_SSL_DEFAULT_CIPHERS == 2 +/* Ignored in SSLContext constructor, only used to as _ssl.DEFAULT_CIPHER_STRING */ + #define PY_SSL_DEFAULT_CIPHER_STRING SSL_DEFAULT_CIPHER_LIST +#else + #error "Unsupported PY_SSL_DEFAULT_CIPHERS" +#endif + + +enum py_ssl_error { + /* these mirror ssl.h */ + PY_SSL_ERROR_NONE, + PY_SSL_ERROR_SSL, + PY_SSL_ERROR_WANT_READ, + PY_SSL_ERROR_WANT_WRITE, + PY_SSL_ERROR_WANT_X509_LOOKUP, + PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */ + PY_SSL_ERROR_ZERO_RETURN, + PY_SSL_ERROR_WANT_CONNECT, + /* start of non ssl.h errorcodes */ + PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */ + PY_SSL_ERROR_NO_SOCKET, /* socket has been GC'd */ + PY_SSL_ERROR_INVALID_ERROR_CODE +}; + +enum py_ssl_server_or_client { + PY_SSL_CLIENT, + PY_SSL_SERVER +}; + +enum py_ssl_cert_requirements { + PY_SSL_CERT_NONE, + PY_SSL_CERT_OPTIONAL, + PY_SSL_CERT_REQUIRED +}; + +enum py_ssl_version { + PY_SSL_VERSION_SSL2, + PY_SSL_VERSION_SSL3=1, + PY_SSL_VERSION_TLS, /* SSLv23 */ + PY_SSL_VERSION_TLS1, + PY_SSL_VERSION_TLS1_1, + PY_SSL_VERSION_TLS1_2, + PY_SSL_VERSION_TLS_CLIENT=0x10, + PY_SSL_VERSION_TLS_SERVER, +}; + +enum py_proto_version { + PY_PROTO_MINIMUM_SUPPORTED = -2, + PY_PROTO_SSLv3 = SSL3_VERSION, + PY_PROTO_TLSv1 = TLS1_VERSION, + PY_PROTO_TLSv1_1 = TLS1_1_VERSION, + PY_PROTO_TLSv1_2 = TLS1_2_VERSION, +#ifdef TLS1_3_VERSION + PY_PROTO_TLSv1_3 = TLS1_3_VERSION, +#else + PY_PROTO_TLSv1_3 = 0x304, +#endif + PY_PROTO_MAXIMUM_SUPPORTED = -1, + +/* OpenSSL has no dedicated API to set the minimum version to the maximum + * available version, and the other way around. We have to figure out the + * minimum and maximum available version on our own and hope for the best. + */ +#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) + PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_SSLv3, +#elif defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) + PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_TLSv1, +#elif defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) + PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_TLSv1_1, +#elif defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) + PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_TLSv1_2, +#elif defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) + PY_PROTO_MINIMUM_AVAILABLE = PY_PROTO_TLSv1_3, +#else + #error "PY_PROTO_MINIMUM_AVAILABLE not found" +#endif + +#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) + PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_TLSv1_3, +#elif defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) + PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_TLSv1_2, +#elif defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) + PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_TLSv1_1, +#elif defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) + PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_TLSv1, +#elif defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) + PY_PROTO_MAXIMUM_AVAILABLE = PY_PROTO_SSLv3, +#else + #error "PY_PROTO_MAXIMUM_AVAILABLE not found" +#endif +}; + + +/* serves as a flag to see whether we've initialized the SSL thread support. */ +/* 0 means no, greater than 0 means yes */ + +static unsigned int _ssl_locks_count = 0; + +/* SSL socket object */ + +#define X509_NAME_MAXLEN 256 + +/* SSL_CTX_clear_options() and SSL_clear_options() were first added in + * OpenSSL 0.9.8m but do not appear in some 0.9.9-dev versions such the + * 0.9.9 from "May 2008" that NetBSD 5.0 uses. */ +#if OPENSSL_VERSION_NUMBER >= 0x009080dfL && OPENSSL_VERSION_NUMBER != 0x00909000L +# define HAVE_SSL_CTX_CLEAR_OPTIONS +#else +# undef HAVE_SSL_CTX_CLEAR_OPTIONS +#endif + +/* In case of 'tls-unique' it will be 12 bytes for TLS, 36 bytes for + * older SSL, but let's be safe */ +#define PySSL_CB_MAXLEN 128 + + +typedef struct { + PyObject_HEAD + SSL_CTX *ctx; +#if HAVE_NPN + unsigned char *npn_protocols; + int npn_protocols_len; +#endif +#if HAVE_ALPN + unsigned char *alpn_protocols; + unsigned int alpn_protocols_len; +#endif +#ifndef OPENSSL_NO_TLSEXT + PyObject *set_sni_cb; +#endif + int check_hostname; + /* OpenSSL has no API to get hostflags from X509_VERIFY_PARAM* struct. + * We have to maintain our own copy. OpenSSL's hostflags default to 0. + */ + unsigned int hostflags; + int protocol; +#ifdef TLS1_3_VERSION + int post_handshake_auth; +#endif PyObject *msg_cb; #ifdef HAVE_OPENSSL_KEYLOG PyObject *keylog_filename; BIO *keylog_bio; #endif -} PySSLContext; - -typedef struct { - int ssl; /* last seen error from SSL */ - int c; /* last seen error from libc */ -#ifdef MS_WINDOWS - int ws; /* last seen error from winsock */ -#endif -} _PySSLError; - -typedef struct { - PyObject_HEAD - PyObject *Socket; /* weakref to socket on which we're layered */ - SSL *ssl; - PySSLContext *ctx; /* weakref to SSL context */ - char shutdown_seen_zero; - enum py_ssl_server_or_client socket_type; - PyObject *owner; /* Python level "owner" passed to servername callback */ - PyObject *server_hostname; - _PySSLError err; /* last seen error from various sources */ +} PySSLContext; + +typedef struct { + int ssl; /* last seen error from SSL */ + int c; /* last seen error from libc */ +#ifdef MS_WINDOWS + int ws; /* last seen error from winsock */ +#endif +} _PySSLError; + +typedef struct { + PyObject_HEAD + PyObject *Socket; /* weakref to socket on which we're layered */ + SSL *ssl; + PySSLContext *ctx; /* weakref to SSL context */ + char shutdown_seen_zero; + enum py_ssl_server_or_client socket_type; + PyObject *owner; /* Python level "owner" passed to servername callback */ + PyObject *server_hostname; + _PySSLError err; /* last seen error from various sources */ /* Some SSL callbacks don't have error reporting. Callback wrappers * store exception information on the socket. The handshake, read, write, * and shutdown methods check for chained exceptions. @@ -478,267 +478,267 @@ typedef struct { PyObject *exc_type; PyObject *exc_value; PyObject *exc_tb; -} PySSLSocket; - -typedef struct { - PyObject_HEAD - BIO *bio; - int eof_written; -} PySSLMemoryBIO; - -typedef struct { - PyObject_HEAD - SSL_SESSION *session; - PySSLContext *ctx; -} PySSLSession; - -static PyTypeObject PySSLContext_Type; -static PyTypeObject PySSLSocket_Type; -static PyTypeObject PySSLMemoryBIO_Type; -static PyTypeObject PySSLSession_Type; - -static inline _PySSLError _PySSL_errno(int failed, const SSL *ssl, int retcode) -{ - _PySSLError err = { 0 }; - if (failed) { -#ifdef MS_WINDOWS - err.ws = WSAGetLastError(); - _PySSL_FIX_ERRNO; -#endif - err.c = errno; - err.ssl = SSL_get_error(ssl, retcode); - } - return err; -} - -/*[clinic input] -module _ssl -class _ssl._SSLContext "PySSLContext *" "&PySSLContext_Type" -class _ssl._SSLSocket "PySSLSocket *" "&PySSLSocket_Type" -class _ssl.MemoryBIO "PySSLMemoryBIO *" "&PySSLMemoryBIO_Type" -class _ssl.SSLSession "PySSLSession *" "&PySSLSession_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bdc67fafeeaa8109]*/ - -#include "clinic/_ssl.c.h" - -static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout); - -static int PySSL_set_owner(PySSLSocket *, PyObject *, void *); -static int PySSL_set_session(PySSLSocket *, PyObject *, void *); +} PySSLSocket; + +typedef struct { + PyObject_HEAD + BIO *bio; + int eof_written; +} PySSLMemoryBIO; + +typedef struct { + PyObject_HEAD + SSL_SESSION *session; + PySSLContext *ctx; +} PySSLSession; + +static PyTypeObject PySSLContext_Type; +static PyTypeObject PySSLSocket_Type; +static PyTypeObject PySSLMemoryBIO_Type; +static PyTypeObject PySSLSession_Type; + +static inline _PySSLError _PySSL_errno(int failed, const SSL *ssl, int retcode) +{ + _PySSLError err = { 0 }; + if (failed) { +#ifdef MS_WINDOWS + err.ws = WSAGetLastError(); + _PySSL_FIX_ERRNO; +#endif + err.c = errno; + err.ssl = SSL_get_error(ssl, retcode); + } + return err; +} + +/*[clinic input] +module _ssl +class _ssl._SSLContext "PySSLContext *" "&PySSLContext_Type" +class _ssl._SSLSocket "PySSLSocket *" "&PySSLSocket_Type" +class _ssl.MemoryBIO "PySSLMemoryBIO *" "&PySSLMemoryBIO_Type" +class _ssl.SSLSession "PySSLSession *" "&PySSLSession_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bdc67fafeeaa8109]*/ + +#include "clinic/_ssl.c.h" + +static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout); + +static int PySSL_set_owner(PySSLSocket *, PyObject *, void *); +static int PySSL_set_session(PySSLSocket *, PyObject *, void *); #define PySSLSocket_Check(v) Py_IS_TYPE(v, &PySSLSocket_Type) #define PySSLMemoryBIO_Check(v) Py_IS_TYPE(v, &PySSLMemoryBIO_Type) #define PySSLSession_Check(v) Py_IS_TYPE(v, &PySSLSession_Type) - -typedef enum { - SOCKET_IS_NONBLOCKING, - SOCKET_IS_BLOCKING, - SOCKET_HAS_TIMED_OUT, - SOCKET_HAS_BEEN_CLOSED, - SOCKET_TOO_LARGE_FOR_SELECT, - SOCKET_OPERATION_OK -} timeout_state; - -/* Wrap error strings with filename and line # */ -#define ERRSTR1(x,y,z) (x ":" y ": " z) -#define ERRSTR(x) ERRSTR1("_ssl.c", Py_STRINGIFY(__LINE__), x) - -/* Get the socket from a PySSLSocket, if it has one */ -#define GET_SOCKET(obj) ((obj)->Socket ? \ - (PySocketSockObject *) PyWeakref_GetObject((obj)->Socket) : NULL) - -/* If sock is NULL, use a timeout of 0 second */ -#define GET_SOCKET_TIMEOUT(sock) \ - ((sock != NULL) ? (sock)->sock_timeout : 0) - + +typedef enum { + SOCKET_IS_NONBLOCKING, + SOCKET_IS_BLOCKING, + SOCKET_HAS_TIMED_OUT, + SOCKET_HAS_BEEN_CLOSED, + SOCKET_TOO_LARGE_FOR_SELECT, + SOCKET_OPERATION_OK +} timeout_state; + +/* Wrap error strings with filename and line # */ +#define ERRSTR1(x,y,z) (x ":" y ": " z) +#define ERRSTR(x) ERRSTR1("_ssl.c", Py_STRINGIFY(__LINE__), x) + +/* Get the socket from a PySSLSocket, if it has one */ +#define GET_SOCKET(obj) ((obj)->Socket ? \ + (PySocketSockObject *) PyWeakref_GetObject((obj)->Socket) : NULL) + +/* If sock is NULL, use a timeout of 0 second */ +#define GET_SOCKET_TIMEOUT(sock) \ + ((sock != NULL) ? (sock)->sock_timeout : 0) + #include "_ssl/debughelpers.c" -/* - * SSL errors. - */ - -PyDoc_STRVAR(SSLError_doc, -"An error occurred in the SSL implementation."); - -PyDoc_STRVAR(SSLCertVerificationError_doc, -"A certificate could not be verified."); - -PyDoc_STRVAR(SSLZeroReturnError_doc, -"SSL/TLS session closed cleanly."); - -PyDoc_STRVAR(SSLWantReadError_doc, -"Non-blocking SSL socket needs to read more data\n" -"before the requested operation can be completed."); - -PyDoc_STRVAR(SSLWantWriteError_doc, -"Non-blocking SSL socket needs to write more data\n" -"before the requested operation can be completed."); - -PyDoc_STRVAR(SSLSyscallError_doc, -"System error when attempting SSL operation."); - -PyDoc_STRVAR(SSLEOFError_doc, -"SSL/TLS connection terminated abruptly."); - -static PyObject * -SSLError_str(PyOSErrorObject *self) -{ - if (self->strerror != NULL && PyUnicode_Check(self->strerror)) { - Py_INCREF(self->strerror); - return self->strerror; - } - else - return PyObject_Str(self->args); -} - -static PyType_Slot sslerror_type_slots[] = { - {Py_tp_base, NULL}, /* Filled out in module init as it's not a constant */ +/* + * SSL errors. + */ + +PyDoc_STRVAR(SSLError_doc, +"An error occurred in the SSL implementation."); + +PyDoc_STRVAR(SSLCertVerificationError_doc, +"A certificate could not be verified."); + +PyDoc_STRVAR(SSLZeroReturnError_doc, +"SSL/TLS session closed cleanly."); + +PyDoc_STRVAR(SSLWantReadError_doc, +"Non-blocking SSL socket needs to read more data\n" +"before the requested operation can be completed."); + +PyDoc_STRVAR(SSLWantWriteError_doc, +"Non-blocking SSL socket needs to write more data\n" +"before the requested operation can be completed."); + +PyDoc_STRVAR(SSLSyscallError_doc, +"System error when attempting SSL operation."); + +PyDoc_STRVAR(SSLEOFError_doc, +"SSL/TLS connection terminated abruptly."); + +static PyObject * +SSLError_str(PyOSErrorObject *self) +{ + if (self->strerror != NULL && PyUnicode_Check(self->strerror)) { + Py_INCREF(self->strerror); + return self->strerror; + } + else + return PyObject_Str(self->args); +} + +static PyType_Slot sslerror_type_slots[] = { + {Py_tp_base, NULL}, /* Filled out in module init as it's not a constant */ {Py_tp_doc, (void*)SSLError_doc}, - {Py_tp_str, SSLError_str}, - {0, 0}, -}; - -static PyType_Spec sslerror_type_spec = { - "ssl.SSLError", - sizeof(PyOSErrorObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - sslerror_type_slots -}; - -static void -fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, - const char *errstr, int lineno, unsigned long errcode) -{ - PyObject *err_value = NULL, *reason_obj = NULL, *lib_obj = NULL; - PyObject *verify_obj = NULL, *verify_code_obj = NULL; - PyObject *init_value, *msg, *key; - _Py_IDENTIFIER(reason); - _Py_IDENTIFIER(library); - _Py_IDENTIFIER(verify_message); - _Py_IDENTIFIER(verify_code); - - if (errcode != 0) { - int lib, reason; - - lib = ERR_GET_LIB(errcode); - reason = ERR_GET_REASON(errcode); - key = Py_BuildValue("ii", lib, reason); - if (key == NULL) - goto fail; + {Py_tp_str, SSLError_str}, + {0, 0}, +}; + +static PyType_Spec sslerror_type_spec = { + "ssl.SSLError", + sizeof(PyOSErrorObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + sslerror_type_slots +}; + +static void +fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, + const char *errstr, int lineno, unsigned long errcode) +{ + PyObject *err_value = NULL, *reason_obj = NULL, *lib_obj = NULL; + PyObject *verify_obj = NULL, *verify_code_obj = NULL; + PyObject *init_value, *msg, *key; + _Py_IDENTIFIER(reason); + _Py_IDENTIFIER(library); + _Py_IDENTIFIER(verify_message); + _Py_IDENTIFIER(verify_code); + + if (errcode != 0) { + int lib, reason; + + lib = ERR_GET_LIB(errcode); + reason = ERR_GET_REASON(errcode); + key = Py_BuildValue("ii", lib, reason); + if (key == NULL) + goto fail; reason_obj = PyDict_GetItemWithError(err_codes_to_names, key); - Py_DECREF(key); + Py_DECREF(key); if (reason_obj == NULL && PyErr_Occurred()) { goto fail; - } - key = PyLong_FromLong(lib); - if (key == NULL) - goto fail; + } + key = PyLong_FromLong(lib); + if (key == NULL) + goto fail; lib_obj = PyDict_GetItemWithError(lib_codes_to_names, key); - Py_DECREF(key); + Py_DECREF(key); if (lib_obj == NULL && PyErr_Occurred()) { goto fail; - } - if (errstr == NULL) - errstr = ERR_reason_error_string(errcode); - } - if (errstr == NULL) - errstr = "unknown error"; - - /* verify code for cert validation error */ - if ((sslsock != NULL) && (type == PySSLCertVerificationErrorObject)) { - const char *verify_str = NULL; - long verify_code; - - verify_code = SSL_get_verify_result(sslsock->ssl); - verify_code_obj = PyLong_FromLong(verify_code); - if (verify_code_obj == NULL) { - goto fail; - } - - switch (verify_code) { -#ifdef X509_V_ERR_HOSTNAME_MISMATCH - /* OpenSSL >= 1.0.2, LibreSSL >= 2.5.3 */ - case X509_V_ERR_HOSTNAME_MISMATCH: - verify_obj = PyUnicode_FromFormat( - "Hostname mismatch, certificate is not valid for '%S'.", - sslsock->server_hostname - ); - break; -#endif -#ifdef X509_V_ERR_IP_ADDRESS_MISMATCH - case X509_V_ERR_IP_ADDRESS_MISMATCH: - verify_obj = PyUnicode_FromFormat( - "IP address mismatch, certificate is not valid for '%S'.", - sslsock->server_hostname - ); - break; -#endif - default: - verify_str = X509_verify_cert_error_string(verify_code); - if (verify_str != NULL) { - verify_obj = PyUnicode_FromString(verify_str); - } else { - verify_obj = Py_None; - Py_INCREF(verify_obj); - } - break; - } - if (verify_obj == NULL) { - goto fail; - } - } - - if (verify_obj && reason_obj && lib_obj) - msg = PyUnicode_FromFormat("[%S: %S] %s: %S (_ssl.c:%d)", - lib_obj, reason_obj, errstr, verify_obj, - lineno); - else if (reason_obj && lib_obj) - msg = PyUnicode_FromFormat("[%S: %S] %s (_ssl.c:%d)", - lib_obj, reason_obj, errstr, lineno); - else if (lib_obj) - msg = PyUnicode_FromFormat("[%S] %s (_ssl.c:%d)", - lib_obj, errstr, lineno); - else - msg = PyUnicode_FromFormat("%s (_ssl.c:%d)", errstr, lineno); - if (msg == NULL) - goto fail; - + } + if (errstr == NULL) + errstr = ERR_reason_error_string(errcode); + } + if (errstr == NULL) + errstr = "unknown error"; + + /* verify code for cert validation error */ + if ((sslsock != NULL) && (type == PySSLCertVerificationErrorObject)) { + const char *verify_str = NULL; + long verify_code; + + verify_code = SSL_get_verify_result(sslsock->ssl); + verify_code_obj = PyLong_FromLong(verify_code); + if (verify_code_obj == NULL) { + goto fail; + } + + switch (verify_code) { +#ifdef X509_V_ERR_HOSTNAME_MISMATCH + /* OpenSSL >= 1.0.2, LibreSSL >= 2.5.3 */ + case X509_V_ERR_HOSTNAME_MISMATCH: + verify_obj = PyUnicode_FromFormat( + "Hostname mismatch, certificate is not valid for '%S'.", + sslsock->server_hostname + ); + break; +#endif +#ifdef X509_V_ERR_IP_ADDRESS_MISMATCH + case X509_V_ERR_IP_ADDRESS_MISMATCH: + verify_obj = PyUnicode_FromFormat( + "IP address mismatch, certificate is not valid for '%S'.", + sslsock->server_hostname + ); + break; +#endif + default: + verify_str = X509_verify_cert_error_string(verify_code); + if (verify_str != NULL) { + verify_obj = PyUnicode_FromString(verify_str); + } else { + verify_obj = Py_None; + Py_INCREF(verify_obj); + } + break; + } + if (verify_obj == NULL) { + goto fail; + } + } + + if (verify_obj && reason_obj && lib_obj) + msg = PyUnicode_FromFormat("[%S: %S] %s: %S (_ssl.c:%d)", + lib_obj, reason_obj, errstr, verify_obj, + lineno); + else if (reason_obj && lib_obj) + msg = PyUnicode_FromFormat("[%S: %S] %s (_ssl.c:%d)", + lib_obj, reason_obj, errstr, lineno); + else if (lib_obj) + msg = PyUnicode_FromFormat("[%S] %s (_ssl.c:%d)", + lib_obj, errstr, lineno); + else + msg = PyUnicode_FromFormat("%s (_ssl.c:%d)", errstr, lineno); + if (msg == NULL) + goto fail; + init_value = Py_BuildValue("iN", ERR_GET_REASON(ssl_errno), msg); - if (init_value == NULL) - goto fail; - - err_value = PyObject_CallObject(type, init_value); - Py_DECREF(init_value); - if (err_value == NULL) - goto fail; - - if (reason_obj == NULL) - reason_obj = Py_None; - if (_PyObject_SetAttrId(err_value, &PyId_reason, reason_obj)) - goto fail; - - if (lib_obj == NULL) - lib_obj = Py_None; - if (_PyObject_SetAttrId(err_value, &PyId_library, lib_obj)) - goto fail; - - if ((sslsock != NULL) && (type == PySSLCertVerificationErrorObject)) { - /* Only set verify code / message for SSLCertVerificationError */ - if (_PyObject_SetAttrId(err_value, &PyId_verify_code, - verify_code_obj)) - goto fail; - if (_PyObject_SetAttrId(err_value, &PyId_verify_message, verify_obj)) - goto fail; - } - - PyErr_SetObject(type, err_value); -fail: - Py_XDECREF(err_value); - Py_XDECREF(verify_code_obj); - Py_XDECREF(verify_obj); -} - + if (init_value == NULL) + goto fail; + + err_value = PyObject_CallObject(type, init_value); + Py_DECREF(init_value); + if (err_value == NULL) + goto fail; + + if (reason_obj == NULL) + reason_obj = Py_None; + if (_PyObject_SetAttrId(err_value, &PyId_reason, reason_obj)) + goto fail; + + if (lib_obj == NULL) + lib_obj = Py_None; + if (_PyObject_SetAttrId(err_value, &PyId_library, lib_obj)) + goto fail; + + if ((sslsock != NULL) && (type == PySSLCertVerificationErrorObject)) { + /* Only set verify code / message for SSLCertVerificationError */ + if (_PyObject_SetAttrId(err_value, &PyId_verify_code, + verify_code_obj)) + goto fail; + if (_PyObject_SetAttrId(err_value, &PyId_verify_message, verify_obj)) + goto fail; + } + + PyErr_SetObject(type, err_value); +fail: + Py_XDECREF(err_value); + Py_XDECREF(verify_code_obj); + Py_XDECREF(verify_obj); +} + static int PySSL_ChainExceptions(PySSLSocket *sslsock) { if (sslsock->exc_type == NULL) @@ -751,690 +751,690 @@ PySSL_ChainExceptions(PySSLSocket *sslsock) { return -1; } -static PyObject * -PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) -{ - PyObject *type = PySSLErrorObject; - char *errstr = NULL; - _PySSLError err; - enum py_ssl_error p = PY_SSL_ERROR_NONE; - unsigned long e = 0; - - assert(ret <= 0); - e = ERR_peek_last_error(); - - if (sslsock->ssl != NULL) { - err = sslsock->err; - - switch (err.ssl) { - case SSL_ERROR_ZERO_RETURN: - errstr = "TLS/SSL connection has been closed (EOF)"; - type = PySSLZeroReturnErrorObject; - p = PY_SSL_ERROR_ZERO_RETURN; - break; - case SSL_ERROR_WANT_READ: - errstr = "The operation did not complete (read)"; - type = PySSLWantReadErrorObject; - p = PY_SSL_ERROR_WANT_READ; - break; - case SSL_ERROR_WANT_WRITE: - p = PY_SSL_ERROR_WANT_WRITE; - type = PySSLWantWriteErrorObject; - errstr = "The operation did not complete (write)"; - break; - case SSL_ERROR_WANT_X509_LOOKUP: - p = PY_SSL_ERROR_WANT_X509_LOOKUP; - errstr = "The operation did not complete (X509 lookup)"; - break; - case SSL_ERROR_WANT_CONNECT: - p = PY_SSL_ERROR_WANT_CONNECT; - errstr = "The operation did not complete (connect)"; - break; - case SSL_ERROR_SYSCALL: - { - if (e == 0) { - PySocketSockObject *s = GET_SOCKET(sslsock); - if (ret == 0 || (((PyObject *)s) == Py_None)) { - p = PY_SSL_ERROR_EOF; - type = PySSLEOFErrorObject; - errstr = "EOF occurred in violation of protocol"; - } else if (s && ret == -1) { - /* underlying BIO reported an I/O error */ - ERR_clear_error(); -#ifdef MS_WINDOWS - if (err.ws) { - return PyErr_SetFromWindowsErr(err.ws); - } -#endif - if (err.c) { - errno = err.c; - return PyErr_SetFromErrno(PyExc_OSError); - } +static PyObject * +PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) +{ + PyObject *type = PySSLErrorObject; + char *errstr = NULL; + _PySSLError err; + enum py_ssl_error p = PY_SSL_ERROR_NONE; + unsigned long e = 0; + + assert(ret <= 0); + e = ERR_peek_last_error(); + + if (sslsock->ssl != NULL) { + err = sslsock->err; + + switch (err.ssl) { + case SSL_ERROR_ZERO_RETURN: + errstr = "TLS/SSL connection has been closed (EOF)"; + type = PySSLZeroReturnErrorObject; + p = PY_SSL_ERROR_ZERO_RETURN; + break; + case SSL_ERROR_WANT_READ: + errstr = "The operation did not complete (read)"; + type = PySSLWantReadErrorObject; + p = PY_SSL_ERROR_WANT_READ; + break; + case SSL_ERROR_WANT_WRITE: + p = PY_SSL_ERROR_WANT_WRITE; + type = PySSLWantWriteErrorObject; + errstr = "The operation did not complete (write)"; + break; + case SSL_ERROR_WANT_X509_LOOKUP: + p = PY_SSL_ERROR_WANT_X509_LOOKUP; + errstr = "The operation did not complete (X509 lookup)"; + break; + case SSL_ERROR_WANT_CONNECT: + p = PY_SSL_ERROR_WANT_CONNECT; + errstr = "The operation did not complete (connect)"; + break; + case SSL_ERROR_SYSCALL: + { + if (e == 0) { + PySocketSockObject *s = GET_SOCKET(sslsock); + if (ret == 0 || (((PyObject *)s) == Py_None)) { + p = PY_SSL_ERROR_EOF; + type = PySSLEOFErrorObject; + errstr = "EOF occurred in violation of protocol"; + } else if (s && ret == -1) { + /* underlying BIO reported an I/O error */ + ERR_clear_error(); +#ifdef MS_WINDOWS + if (err.ws) { + return PyErr_SetFromWindowsErr(err.ws); + } +#endif + if (err.c) { + errno = err.c; + return PyErr_SetFromErrno(PyExc_OSError); + } else { p = PY_SSL_ERROR_EOF; type = PySSLEOFErrorObject; errstr = "EOF occurred in violation of protocol"; } - } else { /* possible? */ - p = PY_SSL_ERROR_SYSCALL; - type = PySSLSyscallErrorObject; - errstr = "Some I/O error occurred"; - } - } else { - p = PY_SSL_ERROR_SYSCALL; - } - break; - } - case SSL_ERROR_SSL: - { - p = PY_SSL_ERROR_SSL; - if (e == 0) { - /* possible? */ - errstr = "A failure in the SSL library occurred"; - } - if (ERR_GET_LIB(e) == ERR_LIB_SSL && - ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) { - type = PySSLCertVerificationErrorObject; + } else { /* possible? */ + p = PY_SSL_ERROR_SYSCALL; + type = PySSLSyscallErrorObject; + errstr = "Some I/O error occurred"; + } + } else { + p = PY_SSL_ERROR_SYSCALL; + } + break; + } + case SSL_ERROR_SSL: + { + p = PY_SSL_ERROR_SSL; + if (e == 0) { + /* possible? */ + errstr = "A failure in the SSL library occurred"; + } + if (ERR_GET_LIB(e) == ERR_LIB_SSL && + ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) { + type = PySSLCertVerificationErrorObject; + } + break; + } + default: + p = PY_SSL_ERROR_INVALID_ERROR_CODE; + errstr = "Invalid error code"; + } + } + fill_and_set_sslerror(sslsock, type, p, errstr, lineno, e); + ERR_clear_error(); + PySSL_ChainExceptions(sslsock); + return NULL; +} + +static PyObject * +_setSSLError (const char *errstr, int errcode, const char *filename, int lineno) { + + if (errstr == NULL) + errcode = ERR_peek_last_error(); + else + errcode = 0; + fill_and_set_sslerror(NULL, PySSLErrorObject, errcode, errstr, lineno, errcode); + ERR_clear_error(); + return NULL; +} + +/* + * SSL objects + */ + +static int +_ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) +{ + int retval = -1; + ASN1_OCTET_STRING *ip; + PyObject *hostname; + size_t len; + + assert(server_hostname); + + /* Disable OpenSSL's special mode with leading dot in hostname: + * When name starts with a dot (e.g ".example.com"), it will be + * matched by a certificate valid for any sub-domain of name. + */ + len = strlen(server_hostname); + if (len == 0 || *server_hostname == '.') { + PyErr_SetString( + PyExc_ValueError, + "server_hostname cannot be an empty string or start with a " + "leading dot."); + return retval; + } + + /* inet_pton is not available on all platforms. */ + ip = a2i_IPADDRESS(server_hostname); + if (ip == NULL) { + ERR_clear_error(); + } + + hostname = PyUnicode_Decode(server_hostname, len, "ascii", "strict"); + if (hostname == NULL) { + goto error; + } + self->server_hostname = hostname; + + /* Only send SNI extension for non-IP hostnames */ + if (ip == NULL) { + if (!SSL_set_tlsext_host_name(self->ssl, server_hostname)) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto error; + } + } + if (self->ctx->check_hostname) { + X509_VERIFY_PARAM *param = SSL_get0_param(self->ssl); + if (ip == NULL) { + if (!X509_VERIFY_PARAM_set1_host(param, server_hostname, + strlen(server_hostname))) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto error; + } + } else { + if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip), + ASN1_STRING_length(ip))) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto error; + } + } + } + retval = 0; + error: + if (ip != NULL) { + ASN1_OCTET_STRING_free(ip); + } + return retval; +} + +static PySSLSocket * +newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, + enum py_ssl_server_or_client socket_type, + char *server_hostname, + PyObject *owner, PyObject *session, + PySSLMemoryBIO *inbio, PySSLMemoryBIO *outbio) +{ + PySSLSocket *self; + SSL_CTX *ctx = sslctx->ctx; + _PySSLError err = { 0 }; + + self = PyObject_New(PySSLSocket, &PySSLSocket_Type); + if (self == NULL) + return NULL; + + self->ssl = NULL; + self->Socket = NULL; + self->ctx = sslctx; + Py_INCREF(sslctx); + self->shutdown_seen_zero = 0; + self->owner = NULL; + self->server_hostname = NULL; + self->err = err; + self->exc_type = NULL; + self->exc_value = NULL; + self->exc_tb = NULL; + + /* Make sure the SSL error state is initialized */ + ERR_clear_error(); + + PySSL_BEGIN_ALLOW_THREADS + self->ssl = SSL_new(ctx); + PySSL_END_ALLOW_THREADS + if (self->ssl == NULL) { + Py_DECREF(self); + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + /* bpo43522 and OpenSSL < 1.1.1l: copy hostflags manually */ +#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION < 0x101010cf + X509_VERIFY_PARAM *ssl_params = SSL_get0_param(self->ssl); + X509_VERIFY_PARAM_set_hostflags(ssl_params, sslctx->hostflags); +#endif + SSL_set_app_data(self->ssl, self); + if (sock) { + SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int)); + } else { + /* BIOs are reference counted and SSL_set_bio borrows our reference. + * To prevent a double free in memory_bio_dealloc() we need to take an + * extra reference here. */ + BIO_up_ref(inbio->bio); + BIO_up_ref(outbio->bio); + SSL_set_bio(self->ssl, inbio->bio, outbio->bio); + } + SSL_set_mode(self->ssl, + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY); + +#ifdef TLS1_3_VERSION + if (sslctx->post_handshake_auth == 1) { + if (socket_type == PY_SSL_SERVER) { + /* bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE. + * Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and + * only in combination with SSL_VERIFY_PEER flag. */ + int mode = SSL_get_verify_mode(self->ssl); + if (mode & SSL_VERIFY_PEER) { + int (*verify_cb)(int, X509_STORE_CTX *) = NULL; + verify_cb = SSL_get_verify_callback(self->ssl); + mode |= SSL_VERIFY_POST_HANDSHAKE; + SSL_set_verify(self->ssl, mode, verify_cb); } - break; - } - default: - p = PY_SSL_ERROR_INVALID_ERROR_CODE; - errstr = "Invalid error code"; + } else { + /* client socket */ + SSL_set_post_handshake_auth(self->ssl, 1); } } - fill_and_set_sslerror(sslsock, type, p, errstr, lineno, e); - ERR_clear_error(); - PySSL_ChainExceptions(sslsock); - return NULL; -} - -static PyObject * -_setSSLError (const char *errstr, int errcode, const char *filename, int lineno) { - - if (errstr == NULL) - errcode = ERR_peek_last_error(); - else - errcode = 0; - fill_and_set_sslerror(NULL, PySSLErrorObject, errcode, errstr, lineno, errcode); - ERR_clear_error(); - return NULL; -} - -/* - * SSL objects - */ +#endif -static int -_ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) -{ - int retval = -1; - ASN1_OCTET_STRING *ip; - PyObject *hostname; - size_t len; - - assert(server_hostname); - - /* Disable OpenSSL's special mode with leading dot in hostname: - * When name starts with a dot (e.g ".example.com"), it will be - * matched by a certificate valid for any sub-domain of name. - */ - len = strlen(server_hostname); - if (len == 0 || *server_hostname == '.') { - PyErr_SetString( - PyExc_ValueError, - "server_hostname cannot be an empty string or start with a " - "leading dot."); - return retval; - } - - /* inet_pton is not available on all platforms. */ - ip = a2i_IPADDRESS(server_hostname); - if (ip == NULL) { - ERR_clear_error(); - } - - hostname = PyUnicode_Decode(server_hostname, len, "ascii", "strict"); - if (hostname == NULL) { - goto error; - } - self->server_hostname = hostname; - - /* Only send SNI extension for non-IP hostnames */ - if (ip == NULL) { - if (!SSL_set_tlsext_host_name(self->ssl, server_hostname)) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto error; - } - } - if (self->ctx->check_hostname) { - X509_VERIFY_PARAM *param = SSL_get0_param(self->ssl); - if (ip == NULL) { - if (!X509_VERIFY_PARAM_set1_host(param, server_hostname, - strlen(server_hostname))) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto error; - } - } else { - if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip), - ASN1_STRING_length(ip))) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto error; - } - } - } - retval = 0; - error: - if (ip != NULL) { - ASN1_OCTET_STRING_free(ip); - } - return retval; -} - -static PySSLSocket * -newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, - enum py_ssl_server_or_client socket_type, - char *server_hostname, - PyObject *owner, PyObject *session, - PySSLMemoryBIO *inbio, PySSLMemoryBIO *outbio) -{ - PySSLSocket *self; - SSL_CTX *ctx = sslctx->ctx; - _PySSLError err = { 0 }; - - self = PyObject_New(PySSLSocket, &PySSLSocket_Type); - if (self == NULL) - return NULL; - - self->ssl = NULL; - self->Socket = NULL; - self->ctx = sslctx; - Py_INCREF(sslctx); - self->shutdown_seen_zero = 0; - self->owner = NULL; - self->server_hostname = NULL; - self->err = err; - self->exc_type = NULL; - self->exc_value = NULL; - self->exc_tb = NULL; - - /* Make sure the SSL error state is initialized */ - ERR_clear_error(); - - PySSL_BEGIN_ALLOW_THREADS - self->ssl = SSL_new(ctx); - PySSL_END_ALLOW_THREADS - if (self->ssl == NULL) { - Py_DECREF(self); - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - /* bpo43522 and OpenSSL < 1.1.1l: copy hostflags manually */ -#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION < 0x101010cf - X509_VERIFY_PARAM *ssl_params = SSL_get0_param(self->ssl); - X509_VERIFY_PARAM_set_hostflags(ssl_params, sslctx->hostflags); -#endif - SSL_set_app_data(self->ssl, self); - if (sock) { - SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int)); - } else { - /* BIOs are reference counted and SSL_set_bio borrows our reference. - * To prevent a double free in memory_bio_dealloc() we need to take an - * extra reference here. */ - BIO_up_ref(inbio->bio); - BIO_up_ref(outbio->bio); - SSL_set_bio(self->ssl, inbio->bio, outbio->bio); - } - SSL_set_mode(self->ssl, - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY); - -#ifdef TLS1_3_VERSION - if (sslctx->post_handshake_auth == 1) { - if (socket_type == PY_SSL_SERVER) { - /* bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE. - * Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and - * only in combination with SSL_VERIFY_PEER flag. */ - int mode = SSL_get_verify_mode(self->ssl); - if (mode & SSL_VERIFY_PEER) { - int (*verify_cb)(int, X509_STORE_CTX *) = NULL; - verify_cb = SSL_get_verify_callback(self->ssl); - mode |= SSL_VERIFY_POST_HANDSHAKE; - SSL_set_verify(self->ssl, mode, verify_cb); - } - } else { - /* client socket */ - SSL_set_post_handshake_auth(self->ssl, 1); - } - } -#endif - - if (server_hostname != NULL) { - if (_ssl_configure_hostname(self, server_hostname) < 0) { - Py_DECREF(self); - return NULL; - } - } - /* If the socket is in non-blocking mode or timeout mode, set the BIO - * to non-blocking mode (blocking is the default) - */ - if (sock && sock->sock_timeout >= 0) { - BIO_set_nbio(SSL_get_rbio(self->ssl), 1); - BIO_set_nbio(SSL_get_wbio(self->ssl), 1); - } - - PySSL_BEGIN_ALLOW_THREADS - if (socket_type == PY_SSL_CLIENT) - SSL_set_connect_state(self->ssl); - else - SSL_set_accept_state(self->ssl); - PySSL_END_ALLOW_THREADS - - self->socket_type = socket_type; - if (sock != NULL) { - self->Socket = PyWeakref_NewRef((PyObject *) sock, NULL); - if (self->Socket == NULL) { - Py_DECREF(self); - return NULL; - } - } - if (owner && owner != Py_None) { - if (PySSL_set_owner(self, owner, NULL) == -1) { - Py_DECREF(self); - return NULL; - } - } - if (session && session != Py_None) { - if (PySSL_set_session(self, session, NULL) == -1) { - Py_DECREF(self); - return NULL; - } - } - return self; -} - -/* SSL object methods */ - -/*[clinic input] -_ssl._SSLSocket.do_handshake -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) -/*[clinic end generated code: output=6c0898a8936548f6 input=d2d737de3df018c8]*/ -{ - int ret; - _PySSLError err; - int sockstate, nonblocking; - PySocketSockObject *sock = GET_SOCKET(self); - _PyTime_t timeout, deadline = 0; - int has_timeout; - - if (sock) { - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; - } - Py_INCREF(sock); - - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - } - - timeout = GET_SOCKET_TIMEOUT(sock); - has_timeout = (timeout > 0); - if (has_timeout) - deadline = _PyTime_GetMonotonicClock() + timeout; - - /* Actually negotiate SSL connection */ - /* XXX If SSL_do_handshake() returns 0, it's also a failure. */ - do { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_do_handshake(self->ssl); - err = _PySSL_errno(ret < 1, self->ssl, ret); - PySSL_END_ALLOW_THREADS - self->err = err; - - if (PyErr_CheckSignals()) - goto error; - - if (has_timeout) - timeout = deadline - _PyTime_GetMonotonicClock(); - - if (err.ssl == SSL_ERROR_WANT_READ) { - sockstate = PySSL_select(sock, 0, timeout); - } else if (err.ssl == SSL_ERROR_WANT_WRITE) { - sockstate = PySSL_select(sock, 1, timeout); - } else { - sockstate = SOCKET_OPERATION_OK; - } - - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, - ERRSTR("The handshake operation timed out")); - goto error; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("Underlying socket has been closed.")); - goto error; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("Underlying socket too large for select().")); - goto error; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err.ssl == SSL_ERROR_WANT_READ || - err.ssl == SSL_ERROR_WANT_WRITE); - Py_XDECREF(sock); - if (ret < 1) - return PySSL_SetError(self, ret, __FILE__, __LINE__); + if (server_hostname != NULL) { + if (_ssl_configure_hostname(self, server_hostname) < 0) { + Py_DECREF(self); + return NULL; + } + } + /* If the socket is in non-blocking mode or timeout mode, set the BIO + * to non-blocking mode (blocking is the default) + */ + if (sock && sock->sock_timeout >= 0) { + BIO_set_nbio(SSL_get_rbio(self->ssl), 1); + BIO_set_nbio(SSL_get_wbio(self->ssl), 1); + } + + PySSL_BEGIN_ALLOW_THREADS + if (socket_type == PY_SSL_CLIENT) + SSL_set_connect_state(self->ssl); + else + SSL_set_accept_state(self->ssl); + PySSL_END_ALLOW_THREADS + + self->socket_type = socket_type; + if (sock != NULL) { + self->Socket = PyWeakref_NewRef((PyObject *) sock, NULL); + if (self->Socket == NULL) { + Py_DECREF(self); + return NULL; + } + } + if (owner && owner != Py_None) { + if (PySSL_set_owner(self, owner, NULL) == -1) { + Py_DECREF(self); + return NULL; + } + } + if (session && session != Py_None) { + if (PySSL_set_session(self, session, NULL) == -1) { + Py_DECREF(self); + return NULL; + } + } + return self; +} + +/* SSL object methods */ + +/*[clinic input] +_ssl._SSLSocket.do_handshake +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) +/*[clinic end generated code: output=6c0898a8936548f6 input=d2d737de3df018c8]*/ +{ + int ret; + _PySSLError err; + int sockstate, nonblocking; + PySocketSockObject *sock = GET_SOCKET(self); + _PyTime_t timeout, deadline = 0; + int has_timeout; + + if (sock) { + if (((PyObject*)sock) == Py_None) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); + + /* just in case the blocking state of the socket has been changed */ + nonblocking = (sock->sock_timeout >= 0); + BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); + BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + } + + timeout = GET_SOCKET_TIMEOUT(sock); + has_timeout = (timeout > 0); + if (has_timeout) + deadline = _PyTime_GetMonotonicClock() + timeout; + + /* Actually negotiate SSL connection */ + /* XXX If SSL_do_handshake() returns 0, it's also a failure. */ + do { + PySSL_BEGIN_ALLOW_THREADS + ret = SSL_do_handshake(self->ssl); + err = _PySSL_errno(ret < 1, self->ssl, ret); + PySSL_END_ALLOW_THREADS + self->err = err; + + if (PyErr_CheckSignals()) + goto error; + + if (has_timeout) + timeout = deadline - _PyTime_GetMonotonicClock(); + + if (err.ssl == SSL_ERROR_WANT_READ) { + sockstate = PySSL_select(sock, 0, timeout); + } else if (err.ssl == SSL_ERROR_WANT_WRITE) { + sockstate = PySSL_select(sock, 1, timeout); + } else { + sockstate = SOCKET_OPERATION_OK; + } + + if (sockstate == SOCKET_HAS_TIMED_OUT) { + PyErr_SetString(PySocketModule.timeout_error, + ERRSTR("The handshake operation timed out")); + goto error; + } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { + PyErr_SetString(PySSLErrorObject, + ERRSTR("Underlying socket has been closed.")); + goto error; + } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { + PyErr_SetString(PySSLErrorObject, + ERRSTR("Underlying socket too large for select().")); + goto error; + } else if (sockstate == SOCKET_IS_NONBLOCKING) { + break; + } + } while (err.ssl == SSL_ERROR_WANT_READ || + err.ssl == SSL_ERROR_WANT_WRITE); + Py_XDECREF(sock); + if (ret < 1) + return PySSL_SetError(self, ret, __FILE__, __LINE__); if (PySSL_ChainExceptions(self) < 0) return NULL; - Py_RETURN_NONE; -error: - Py_XDECREF(sock); + Py_RETURN_NONE; +error: + Py_XDECREF(sock); PySSL_ChainExceptions(self); - return NULL; -} - -static PyObject * -_asn1obj2py(const ASN1_OBJECT *name, int no_name) -{ - char buf[X509_NAME_MAXLEN]; - char *namebuf = buf; - int buflen; - PyObject *name_obj = NULL; - - buflen = OBJ_obj2txt(namebuf, X509_NAME_MAXLEN, name, no_name); - if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - /* initial buffer is too small for oid + terminating null byte */ - if (buflen > X509_NAME_MAXLEN - 1) { - /* make OBJ_obj2txt() calculate the required buflen */ - buflen = OBJ_obj2txt(NULL, 0, name, no_name); - /* allocate len + 1 for terminating NULL byte */ - namebuf = PyMem_Malloc(buflen + 1); - if (namebuf == NULL) { - PyErr_NoMemory(); - return NULL; - } - buflen = OBJ_obj2txt(namebuf, buflen + 1, name, no_name); - if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto done; - } - } - if (!buflen && no_name) { - Py_INCREF(Py_None); - name_obj = Py_None; - } - else { - name_obj = PyUnicode_FromStringAndSize(namebuf, buflen); - } - - done: - if (buf != namebuf) { - PyMem_Free(namebuf); - } - return name_obj; -} - -static PyObject * -_create_tuple_for_attribute(ASN1_OBJECT *name, ASN1_STRING *value) -{ - Py_ssize_t buflen; - unsigned char *valuebuf = NULL; - PyObject *attr; - - buflen = ASN1_STRING_to_UTF8(&valuebuf, value); - if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - attr = Py_BuildValue("Ns#", _asn1obj2py(name, 0), valuebuf, buflen); - OPENSSL_free(valuebuf); - return attr; -} - -static PyObject * -_create_tuple_for_X509_NAME (X509_NAME *xname) -{ - PyObject *dn = NULL; /* tuple which represents the "distinguished name" */ - PyObject *rdn = NULL; /* tuple to hold a "relative distinguished name" */ - PyObject *rdnt; - PyObject *attr = NULL; /* tuple to hold an attribute */ - int entry_count = X509_NAME_entry_count(xname); - X509_NAME_ENTRY *entry; - ASN1_OBJECT *name; - ASN1_STRING *value; - int index_counter; - int rdn_level = -1; - int retcode; - - dn = PyList_New(0); - if (dn == NULL) - return NULL; - /* now create another tuple to hold the top-level RDN */ - rdn = PyList_New(0); - if (rdn == NULL) - goto fail0; - - for (index_counter = 0; - index_counter < entry_count; - index_counter++) - { - entry = X509_NAME_get_entry(xname, index_counter); - - /* check to see if we've gotten to a new RDN */ - if (rdn_level >= 0) { - if (rdn_level != X509_NAME_ENTRY_set(entry)) { - /* yes, new RDN */ - /* add old RDN to DN */ - rdnt = PyList_AsTuple(rdn); - Py_DECREF(rdn); - if (rdnt == NULL) - goto fail0; - retcode = PyList_Append(dn, rdnt); - Py_DECREF(rdnt); - if (retcode < 0) - goto fail0; - /* create new RDN */ - rdn = PyList_New(0); - if (rdn == NULL) - goto fail0; - } - } - rdn_level = X509_NAME_ENTRY_set(entry); - - /* now add this attribute to the current RDN */ - name = X509_NAME_ENTRY_get_object(entry); - value = X509_NAME_ENTRY_get_data(entry); - attr = _create_tuple_for_attribute(name, value); - /* - fprintf(stderr, "RDN level %d, attribute %s: %s\n", - entry->set, - PyBytes_AS_STRING(PyTuple_GET_ITEM(attr, 0)), - PyBytes_AS_STRING(PyTuple_GET_ITEM(attr, 1))); - */ - if (attr == NULL) - goto fail1; - retcode = PyList_Append(rdn, attr); - Py_DECREF(attr); - if (retcode < 0) - goto fail1; - } - /* now, there's typically a dangling RDN */ - if (rdn != NULL) { - if (PyList_GET_SIZE(rdn) > 0) { - rdnt = PyList_AsTuple(rdn); - Py_DECREF(rdn); - if (rdnt == NULL) - goto fail0; - retcode = PyList_Append(dn, rdnt); - Py_DECREF(rdnt); - if (retcode < 0) - goto fail0; - } - else { - Py_DECREF(rdn); - } - } - - /* convert list to tuple */ - rdnt = PyList_AsTuple(dn); - Py_DECREF(dn); - if (rdnt == NULL) - return NULL; - return rdnt; - - fail1: - Py_XDECREF(rdn); - - fail0: - Py_XDECREF(dn); - return NULL; -} - -static PyObject * -_get_peer_alt_names (X509 *certificate) { - - /* this code follows the procedure outlined in - OpenSSL's crypto/x509v3/v3_prn.c:X509v3_EXT_print() - function to extract the STACK_OF(GENERAL_NAME), - then iterates through the stack to add the - names. */ - - int j; - PyObject *peer_alt_names = Py_None; - PyObject *v = NULL, *t; - GENERAL_NAMES *names = NULL; - GENERAL_NAME *name; - BIO *biobuf = NULL; - char buf[2048]; - char *vptr; - int len; - - if (certificate == NULL) - return peer_alt_names; - - /* get a memory buffer */ - biobuf = BIO_new(BIO_s_mem()); - if (biobuf == NULL) { - PyErr_SetString(PySSLErrorObject, "failed to allocate BIO"); - return NULL; - } - - names = (GENERAL_NAMES *)X509_get_ext_d2i( - certificate, NID_subject_alt_name, NULL, NULL); - if (names != NULL) { - if (peer_alt_names == Py_None) { - peer_alt_names = PyList_New(0); - if (peer_alt_names == NULL) - goto fail; - } - - for(j = 0; j < sk_GENERAL_NAME_num(names); j++) { - /* get a rendering of each name in the set of names */ - int gntype; - ASN1_STRING *as = NULL; - - name = sk_GENERAL_NAME_value(names, j); - gntype = name->type; - switch (gntype) { - case GEN_DIRNAME: - /* we special-case DirName as a tuple of - tuples of attributes */ - - t = PyTuple_New(2); - if (t == NULL) { - goto fail; - } - - v = PyUnicode_FromString("DirName"); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 0, v); - - v = _create_tuple_for_X509_NAME (name->d.dirn); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 1, v); - break; - - case GEN_EMAIL: - case GEN_DNS: - case GEN_URI: - /* GENERAL_NAME_print() doesn't handle NULL bytes in ASN1_string - correctly, CVE-2013-4238 */ - t = PyTuple_New(2); - if (t == NULL) - goto fail; - switch (gntype) { - case GEN_EMAIL: - v = PyUnicode_FromString("email"); - as = name->d.rfc822Name; - break; - case GEN_DNS: - v = PyUnicode_FromString("DNS"); - as = name->d.dNSName; - break; - case GEN_URI: - v = PyUnicode_FromString("URI"); - as = name->d.uniformResourceIdentifier; - break; - } - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 0, v); + return NULL; +} + +static PyObject * +_asn1obj2py(const ASN1_OBJECT *name, int no_name) +{ + char buf[X509_NAME_MAXLEN]; + char *namebuf = buf; + int buflen; + PyObject *name_obj = NULL; + + buflen = OBJ_obj2txt(namebuf, X509_NAME_MAXLEN, name, no_name); + if (buflen < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + /* initial buffer is too small for oid + terminating null byte */ + if (buflen > X509_NAME_MAXLEN - 1) { + /* make OBJ_obj2txt() calculate the required buflen */ + buflen = OBJ_obj2txt(NULL, 0, name, no_name); + /* allocate len + 1 for terminating NULL byte */ + namebuf = PyMem_Malloc(buflen + 1); + if (namebuf == NULL) { + PyErr_NoMemory(); + return NULL; + } + buflen = OBJ_obj2txt(namebuf, buflen + 1, name, no_name); + if (buflen < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto done; + } + } + if (!buflen && no_name) { + Py_INCREF(Py_None); + name_obj = Py_None; + } + else { + name_obj = PyUnicode_FromStringAndSize(namebuf, buflen); + } + + done: + if (buf != namebuf) { + PyMem_Free(namebuf); + } + return name_obj; +} + +static PyObject * +_create_tuple_for_attribute(ASN1_OBJECT *name, ASN1_STRING *value) +{ + Py_ssize_t buflen; + unsigned char *valuebuf = NULL; + PyObject *attr; + + buflen = ASN1_STRING_to_UTF8(&valuebuf, value); + if (buflen < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + attr = Py_BuildValue("Ns#", _asn1obj2py(name, 0), valuebuf, buflen); + OPENSSL_free(valuebuf); + return attr; +} + +static PyObject * +_create_tuple_for_X509_NAME (X509_NAME *xname) +{ + PyObject *dn = NULL; /* tuple which represents the "distinguished name" */ + PyObject *rdn = NULL; /* tuple to hold a "relative distinguished name" */ + PyObject *rdnt; + PyObject *attr = NULL; /* tuple to hold an attribute */ + int entry_count = X509_NAME_entry_count(xname); + X509_NAME_ENTRY *entry; + ASN1_OBJECT *name; + ASN1_STRING *value; + int index_counter; + int rdn_level = -1; + int retcode; + + dn = PyList_New(0); + if (dn == NULL) + return NULL; + /* now create another tuple to hold the top-level RDN */ + rdn = PyList_New(0); + if (rdn == NULL) + goto fail0; + + for (index_counter = 0; + index_counter < entry_count; + index_counter++) + { + entry = X509_NAME_get_entry(xname, index_counter); + + /* check to see if we've gotten to a new RDN */ + if (rdn_level >= 0) { + if (rdn_level != X509_NAME_ENTRY_set(entry)) { + /* yes, new RDN */ + /* add old RDN to DN */ + rdnt = PyList_AsTuple(rdn); + Py_DECREF(rdn); + if (rdnt == NULL) + goto fail0; + retcode = PyList_Append(dn, rdnt); + Py_DECREF(rdnt); + if (retcode < 0) + goto fail0; + /* create new RDN */ + rdn = PyList_New(0); + if (rdn == NULL) + goto fail0; + } + } + rdn_level = X509_NAME_ENTRY_set(entry); + + /* now add this attribute to the current RDN */ + name = X509_NAME_ENTRY_get_object(entry); + value = X509_NAME_ENTRY_get_data(entry); + attr = _create_tuple_for_attribute(name, value); + /* + fprintf(stderr, "RDN level %d, attribute %s: %s\n", + entry->set, + PyBytes_AS_STRING(PyTuple_GET_ITEM(attr, 0)), + PyBytes_AS_STRING(PyTuple_GET_ITEM(attr, 1))); + */ + if (attr == NULL) + goto fail1; + retcode = PyList_Append(rdn, attr); + Py_DECREF(attr); + if (retcode < 0) + goto fail1; + } + /* now, there's typically a dangling RDN */ + if (rdn != NULL) { + if (PyList_GET_SIZE(rdn) > 0) { + rdnt = PyList_AsTuple(rdn); + Py_DECREF(rdn); + if (rdnt == NULL) + goto fail0; + retcode = PyList_Append(dn, rdnt); + Py_DECREF(rdnt); + if (retcode < 0) + goto fail0; + } + else { + Py_DECREF(rdn); + } + } + + /* convert list to tuple */ + rdnt = PyList_AsTuple(dn); + Py_DECREF(dn); + if (rdnt == NULL) + return NULL; + return rdnt; + + fail1: + Py_XDECREF(rdn); + + fail0: + Py_XDECREF(dn); + return NULL; +} + +static PyObject * +_get_peer_alt_names (X509 *certificate) { + + /* this code follows the procedure outlined in + OpenSSL's crypto/x509v3/v3_prn.c:X509v3_EXT_print() + function to extract the STACK_OF(GENERAL_NAME), + then iterates through the stack to add the + names. */ + + int j; + PyObject *peer_alt_names = Py_None; + PyObject *v = NULL, *t; + GENERAL_NAMES *names = NULL; + GENERAL_NAME *name; + BIO *biobuf = NULL; + char buf[2048]; + char *vptr; + int len; + + if (certificate == NULL) + return peer_alt_names; + + /* get a memory buffer */ + biobuf = BIO_new(BIO_s_mem()); + if (biobuf == NULL) { + PyErr_SetString(PySSLErrorObject, "failed to allocate BIO"); + return NULL; + } + + names = (GENERAL_NAMES *)X509_get_ext_d2i( + certificate, NID_subject_alt_name, NULL, NULL); + if (names != NULL) { + if (peer_alt_names == Py_None) { + peer_alt_names = PyList_New(0); + if (peer_alt_names == NULL) + goto fail; + } + + for(j = 0; j < sk_GENERAL_NAME_num(names); j++) { + /* get a rendering of each name in the set of names */ + int gntype; + ASN1_STRING *as = NULL; + + name = sk_GENERAL_NAME_value(names, j); + gntype = name->type; + switch (gntype) { + case GEN_DIRNAME: + /* we special-case DirName as a tuple of + tuples of attributes */ + + t = PyTuple_New(2); + if (t == NULL) { + goto fail; + } + + v = PyUnicode_FromString("DirName"); + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 0, v); + + v = _create_tuple_for_X509_NAME (name->d.dirn); + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 1, v); + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + /* GENERAL_NAME_print() doesn't handle NULL bytes in ASN1_string + correctly, CVE-2013-4238 */ + t = PyTuple_New(2); + if (t == NULL) + goto fail; + switch (gntype) { + case GEN_EMAIL: + v = PyUnicode_FromString("email"); + as = name->d.rfc822Name; + break; + case GEN_DNS: + v = PyUnicode_FromString("DNS"); + as = name->d.dNSName; + break; + case GEN_URI: + v = PyUnicode_FromString("URI"); + as = name->d.uniformResourceIdentifier; + break; + } + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 0, v); v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_get0_data(as), - ASN1_STRING_length(as)); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 1, v); - break; - - case GEN_RID: - t = PyTuple_New(2); - if (t == NULL) - goto fail; - - v = PyUnicode_FromString("Registered ID"); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 0, v); - - len = i2t_ASN1_OBJECT(buf, sizeof(buf)-1, name->d.rid); - if (len < 0) { - Py_DECREF(t); - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } else if (len >= (int)sizeof(buf)) { - v = PyUnicode_FromString(""); - } else { - v = PyUnicode_FromStringAndSize(buf, len); - } - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 1, v); - break; - + ASN1_STRING_length(as)); + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 1, v); + break; + + case GEN_RID: + t = PyTuple_New(2); + if (t == NULL) + goto fail; + + v = PyUnicode_FromString("Registered ID"); + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 0, v); + + len = i2t_ASN1_OBJECT(buf, sizeof(buf)-1, name->d.rid); + if (len < 0) { + Py_DECREF(t); + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto fail; + } else if (len >= (int)sizeof(buf)) { + v = PyUnicode_FromString(""); + } else { + v = PyUnicode_FromStringAndSize(buf, len); + } + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 1, v); + break; + case GEN_IPADD: /* OpenSSL < 3.0.0 adds a trailing \n to IPv6. 3.0.0 removed * the trailing newline. Remove it in all versions @@ -1483,4185 +1483,4185 @@ _get_peer_alt_names (X509 *certificate) { PyTuple_SET_ITEM(t, 1, v); break; - default: - /* for everything else, we use the OpenSSL print form */ - switch (gntype) { - /* check for new general name type */ - case GEN_OTHERNAME: - case GEN_X400: - case GEN_EDIPARTY: - case GEN_RID: - break; - default: - if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, - "Unknown general name type %d", - gntype) == -1) { - goto fail; - } - break; - } - (void) BIO_reset(biobuf); - GENERAL_NAME_print(biobuf, name); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } - vptr = strchr(buf, ':'); - if (vptr == NULL) { - PyErr_Format(PyExc_ValueError, - "Invalid value %.200s", - buf); - goto fail; - } - t = PyTuple_New(2); - if (t == NULL) - goto fail; - v = PyUnicode_FromStringAndSize(buf, (vptr - buf)); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 0, v); - v = PyUnicode_FromStringAndSize((vptr + 1), - (len - (vptr - buf + 1))); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 1, v); - break; - } + default: + /* for everything else, we use the OpenSSL print form */ + switch (gntype) { + /* check for new general name type */ + case GEN_OTHERNAME: + case GEN_X400: + case GEN_EDIPARTY: + case GEN_RID: + break; + default: + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "Unknown general name type %d", + gntype) == -1) { + goto fail; + } + break; + } + (void) BIO_reset(biobuf); + GENERAL_NAME_print(biobuf, name); + len = BIO_gets(biobuf, buf, sizeof(buf)-1); + if (len < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto fail; + } + vptr = strchr(buf, ':'); + if (vptr == NULL) { + PyErr_Format(PyExc_ValueError, + "Invalid value %.200s", + buf); + goto fail; + } + t = PyTuple_New(2); + if (t == NULL) + goto fail; + v = PyUnicode_FromStringAndSize(buf, (vptr - buf)); + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 0, v); + v = PyUnicode_FromStringAndSize((vptr + 1), + (len - (vptr - buf + 1))); + if (v == NULL) { + Py_DECREF(t); + goto fail; + } + PyTuple_SET_ITEM(t, 1, v); + break; + } + + /* and add that rendering to the list */ + + if (PyList_Append(peer_alt_names, t) < 0) { + Py_DECREF(t); + goto fail; + } + Py_DECREF(t); + } + sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); + } + BIO_free(biobuf); + if (peer_alt_names != Py_None) { + v = PyList_AsTuple(peer_alt_names); + Py_DECREF(peer_alt_names); + return v; + } else { + return peer_alt_names; + } + + + fail: + if (biobuf != NULL) + BIO_free(biobuf); + + if (peer_alt_names != Py_None) { + Py_XDECREF(peer_alt_names); + } + + return NULL; +} + +static PyObject * +_get_aia_uri(X509 *certificate, int nid) { + PyObject *lst = NULL, *ostr = NULL; + int i, result; + AUTHORITY_INFO_ACCESS *info; + + info = X509_get_ext_d2i(certificate, NID_info_access, NULL, NULL); + if (info == NULL) + return Py_None; + if (sk_ACCESS_DESCRIPTION_num(info) == 0) { + AUTHORITY_INFO_ACCESS_free(info); + return Py_None; + } + + if ((lst = PyList_New(0)) == NULL) { + goto fail; + } + + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { + ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); + ASN1_IA5STRING *uri; + + if ((OBJ_obj2nid(ad->method) != nid) || + (ad->location->type != GEN_URI)) { + continue; + } + uri = ad->location->d.uniformResourceIdentifier; + ostr = PyUnicode_FromStringAndSize((char *)uri->data, + uri->length); + if (ostr == NULL) { + goto fail; + } + result = PyList_Append(lst, ostr); + Py_DECREF(ostr); + if (result < 0) { + goto fail; + } + } + AUTHORITY_INFO_ACCESS_free(info); + + /* convert to tuple or None */ + if (PyList_Size(lst) == 0) { + Py_DECREF(lst); + return Py_None; + } else { + PyObject *tup; + tup = PyList_AsTuple(lst); + Py_DECREF(lst); + return tup; + } + + fail: + AUTHORITY_INFO_ACCESS_free(info); + Py_XDECREF(lst); + return NULL; +} + +static PyObject * +_get_crl_dp(X509 *certificate) { + STACK_OF(DIST_POINT) *dps; + int i, j; + PyObject *lst, *res = NULL; + + dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); + + if (dps == NULL) + return Py_None; + + lst = PyList_New(0); + if (lst == NULL) + goto done; + + for (i=0; i < sk_DIST_POINT_num(dps); i++) { + DIST_POINT *dp; + STACK_OF(GENERAL_NAME) *gns; + + dp = sk_DIST_POINT_value(dps, i); + if (dp->distpoint == NULL) { + /* Ignore empty DP value, CVE-2019-5010 */ + continue; + } + gns = dp->distpoint->name.fullname; + + for (j=0; j < sk_GENERAL_NAME_num(gns); j++) { + GENERAL_NAME *gn; + ASN1_IA5STRING *uri; + PyObject *ouri; + int err; + + gn = sk_GENERAL_NAME_value(gns, j); + if (gn->type != GEN_URI) { + continue; + } + uri = gn->d.uniformResourceIdentifier; + ouri = PyUnicode_FromStringAndSize((char *)uri->data, + uri->length); + if (ouri == NULL) + goto done; + + err = PyList_Append(lst, ouri); + Py_DECREF(ouri); + if (err < 0) + goto done; + } + } + + /* Convert to tuple. */ + res = (PyList_GET_SIZE(lst) > 0) ? PyList_AsTuple(lst) : Py_None; + + done: + Py_XDECREF(lst); + CRL_DIST_POINTS_free(dps); + return res; +} + +static PyObject * +_decode_certificate(X509 *certificate) { + + PyObject *retval = NULL; + BIO *biobuf = NULL; + PyObject *peer; + PyObject *peer_alt_names = NULL; + PyObject *issuer; + PyObject *version; + PyObject *sn_obj; + PyObject *obj; + ASN1_INTEGER *serialNumber; + char buf[2048]; + int len, result; + const ASN1_TIME *notBefore, *notAfter; + PyObject *pnotBefore, *pnotAfter; + + retval = PyDict_New(); + if (retval == NULL) + return NULL; + + peer = _create_tuple_for_X509_NAME( + X509_get_subject_name(certificate)); + if (peer == NULL) + goto fail0; + if (PyDict_SetItemString(retval, (const char *) "subject", peer) < 0) { + Py_DECREF(peer); + goto fail0; + } + Py_DECREF(peer); + + issuer = _create_tuple_for_X509_NAME( + X509_get_issuer_name(certificate)); + if (issuer == NULL) + goto fail0; + if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) { + Py_DECREF(issuer); + goto fail0; + } + Py_DECREF(issuer); + + version = PyLong_FromLong(X509_get_version(certificate) + 1); + if (version == NULL) + goto fail0; + if (PyDict_SetItemString(retval, "version", version) < 0) { + Py_DECREF(version); + goto fail0; + } + Py_DECREF(version); + + /* get a memory buffer */ + biobuf = BIO_new(BIO_s_mem()); + if (biobuf == NULL) { + PyErr_SetString(PySSLErrorObject, "failed to allocate BIO"); + goto fail0; + } + + (void) BIO_reset(biobuf); + serialNumber = X509_get_serialNumber(certificate); + /* should not exceed 20 octets, 160 bits, so buf is big enough */ + i2a_ASN1_INTEGER(biobuf, serialNumber); + len = BIO_gets(biobuf, buf, sizeof(buf)-1); + if (len < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto fail1; + } + sn_obj = PyUnicode_FromStringAndSize(buf, len); + if (sn_obj == NULL) + goto fail1; + if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) { + Py_DECREF(sn_obj); + goto fail1; + } + Py_DECREF(sn_obj); + + (void) BIO_reset(biobuf); + notBefore = X509_get0_notBefore(certificate); + ASN1_TIME_print(biobuf, notBefore); + len = BIO_gets(biobuf, buf, sizeof(buf)-1); + if (len < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto fail1; + } + pnotBefore = PyUnicode_FromStringAndSize(buf, len); + if (pnotBefore == NULL) + goto fail1; + if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) { + Py_DECREF(pnotBefore); + goto fail1; + } + Py_DECREF(pnotBefore); + + (void) BIO_reset(biobuf); + notAfter = X509_get0_notAfter(certificate); + ASN1_TIME_print(biobuf, notAfter); + len = BIO_gets(biobuf, buf, sizeof(buf)-1); + if (len < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto fail1; + } + pnotAfter = PyUnicode_FromStringAndSize(buf, len); + if (pnotAfter == NULL) + goto fail1; + if (PyDict_SetItemString(retval, "notAfter", pnotAfter) < 0) { + Py_DECREF(pnotAfter); + goto fail1; + } + Py_DECREF(pnotAfter); + + /* Now look for subjectAltName */ + + peer_alt_names = _get_peer_alt_names(certificate); + if (peer_alt_names == NULL) + goto fail1; + else if (peer_alt_names != Py_None) { + if (PyDict_SetItemString(retval, "subjectAltName", + peer_alt_names) < 0) { + Py_DECREF(peer_alt_names); + goto fail1; + } + Py_DECREF(peer_alt_names); + } + + /* Authority Information Access: OCSP URIs */ + obj = _get_aia_uri(certificate, NID_ad_OCSP); + if (obj == NULL) { + goto fail1; + } else if (obj != Py_None) { + result = PyDict_SetItemString(retval, "OCSP", obj); + Py_DECREF(obj); + if (result < 0) { + goto fail1; + } + } + + obj = _get_aia_uri(certificate, NID_ad_ca_issuers); + if (obj == NULL) { + goto fail1; + } else if (obj != Py_None) { + result = PyDict_SetItemString(retval, "caIssuers", obj); + Py_DECREF(obj); + if (result < 0) { + goto fail1; + } + } + + /* CDP (CRL distribution points) */ + obj = _get_crl_dp(certificate); + if (obj == NULL) { + goto fail1; + } else if (obj != Py_None) { + result = PyDict_SetItemString(retval, "crlDistributionPoints", obj); + Py_DECREF(obj); + if (result < 0) { + goto fail1; + } + } + + BIO_free(biobuf); + return retval; + + fail1: + if (biobuf != NULL) + BIO_free(biobuf); + fail0: + Py_XDECREF(retval); + return NULL; +} + +static PyObject * +_certificate_to_der(X509 *certificate) +{ + unsigned char *bytes_buf = NULL; + int len; + PyObject *retval; + + bytes_buf = NULL; + len = i2d_X509(certificate, &bytes_buf); + if (len < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + /* this is actually an immutable bytes sequence */ + retval = PyBytes_FromStringAndSize((const char *) bytes_buf, len); + OPENSSL_free(bytes_buf); + return retval; +} + +/*[clinic input] +_ssl._test_decode_cert + path: object(converter="PyUnicode_FSConverter") + / + +[clinic start generated code]*/ + +static PyObject * +_ssl__test_decode_cert_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=96becb9abb23c091 input=cdeaaf02d4346628]*/ +{ + PyObject *retval = NULL; + X509 *x=NULL; + BIO *cert; + + if ((cert=BIO_new(BIO_s_file())) == NULL) { + PyErr_SetString(PySSLErrorObject, + "Can't malloc memory to read file"); + goto fail0; + } + + if (BIO_read_filename(cert, PyBytes_AsString(path)) <= 0) { + PyErr_SetString(PySSLErrorObject, + "Can't open file"); + goto fail0; + } + + x = PEM_read_bio_X509(cert, NULL, NULL, NULL); + if (x == NULL) { + PyErr_SetString(PySSLErrorObject, + "Error decoding PEM-encoded file"); + goto fail0; + } + + retval = _decode_certificate(x); + X509_free(x); + + fail0: + Py_DECREF(path); + if (cert != NULL) BIO_free(cert); + return retval; +} + + +/*[clinic input] +_ssl._SSLSocket.getpeercert + der as binary_mode: bool = False + / + +Returns the certificate for the peer. + +If no certificate was provided, returns None. If a certificate was +provided, but not validated, returns an empty dictionary. Otherwise +returns a dict containing information about the peer certificate. + +If the optional argument is True, returns a DER-encoded copy of the +peer certificate, or None if no certificate was provided. This will +return the certificate even if it wasn't validated. +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) +/*[clinic end generated code: output=1f0ab66dfb693c88 input=c0fbe802e57629b7]*/ +{ + int verification; + X509 *peer_cert; + PyObject *result; + + if (!SSL_is_init_finished(self->ssl)) { + PyErr_SetString(PyExc_ValueError, + "handshake not done yet"); + return NULL; + } + peer_cert = SSL_get_peer_certificate(self->ssl); + if (peer_cert == NULL) + Py_RETURN_NONE; + + if (binary_mode) { + /* return cert in DER-encoded format */ + result = _certificate_to_der(peer_cert); + } else { + verification = SSL_CTX_get_verify_mode(SSL_get_SSL_CTX(self->ssl)); + if ((verification & SSL_VERIFY_PEER) == 0) + result = PyDict_New(); + else + result = _decode_certificate(peer_cert); + } + X509_free(peer_cert); + return result; +} + +static PyObject * +cipher_to_tuple(const SSL_CIPHER *cipher) +{ + const char *cipher_name, *cipher_protocol; + PyObject *v, *retval = PyTuple_New(3); + if (retval == NULL) + return NULL; + + cipher_name = SSL_CIPHER_get_name(cipher); + if (cipher_name == NULL) { + Py_INCREF(Py_None); + PyTuple_SET_ITEM(retval, 0, Py_None); + } else { + v = PyUnicode_FromString(cipher_name); + if (v == NULL) + goto fail; + PyTuple_SET_ITEM(retval, 0, v); + } + + cipher_protocol = SSL_CIPHER_get_version(cipher); + if (cipher_protocol == NULL) { + Py_INCREF(Py_None); + PyTuple_SET_ITEM(retval, 1, Py_None); + } else { + v = PyUnicode_FromString(cipher_protocol); + if (v == NULL) + goto fail; + PyTuple_SET_ITEM(retval, 1, v); + } + + v = PyLong_FromLong(SSL_CIPHER_get_bits(cipher, NULL)); + if (v == NULL) + goto fail; + PyTuple_SET_ITEM(retval, 2, v); + + return retval; + + fail: + Py_DECREF(retval); + return NULL; +} + +#if OPENSSL_VERSION_NUMBER >= 0x10002000UL +static PyObject * +cipher_to_dict(const SSL_CIPHER *cipher) +{ + const char *cipher_name, *cipher_protocol; + + unsigned long cipher_id; + int alg_bits, strength_bits, len; + char buf[512] = {0}; +#if OPENSSL_VERSION_1_1 + int aead, nid; + const char *skcipher = NULL, *digest = NULL, *kx = NULL, *auth = NULL; +#endif + + /* can be NULL */ + cipher_name = SSL_CIPHER_get_name(cipher); + cipher_protocol = SSL_CIPHER_get_version(cipher); + cipher_id = SSL_CIPHER_get_id(cipher); + SSL_CIPHER_description(cipher, buf, sizeof(buf) - 1); + /* Downcast to avoid a warning. Safe since buf is always 512 bytes */ + len = (int)strlen(buf); + if (len > 1 && buf[len-1] == '\n') + buf[len-1] = '\0'; + strength_bits = SSL_CIPHER_get_bits(cipher, &alg_bits); + +#if OPENSSL_VERSION_1_1 + aead = SSL_CIPHER_is_aead(cipher); + nid = SSL_CIPHER_get_cipher_nid(cipher); + skcipher = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; + nid = SSL_CIPHER_get_digest_nid(cipher); + digest = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; + nid = SSL_CIPHER_get_kx_nid(cipher); + kx = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; + nid = SSL_CIPHER_get_auth_nid(cipher); + auth = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; +#endif + + return Py_BuildValue( + "{sksssssssisi" +#if OPENSSL_VERSION_1_1 + "sOssssssss" +#endif + "}", + "id", cipher_id, + "name", cipher_name, + "protocol", cipher_protocol, + "description", buf, + "strength_bits", strength_bits, + "alg_bits", alg_bits +#if OPENSSL_VERSION_1_1 + ,"aead", aead ? Py_True : Py_False, + "symmetric", skcipher, + "digest", digest, + "kea", kx, + "auth", auth +#endif + ); +} +#endif + +/*[clinic input] +_ssl._SSLSocket.shared_ciphers +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) +/*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/ +{ + STACK_OF(SSL_CIPHER) *ciphers; + int i; + PyObject *res; + + ciphers = SSL_get_ciphers(self->ssl); + if (!ciphers) + Py_RETURN_NONE; + res = PyList_New(sk_SSL_CIPHER_num(ciphers)); + if (!res) + return NULL; + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + PyObject *tup = cipher_to_tuple(sk_SSL_CIPHER_value(ciphers, i)); + if (!tup) { + Py_DECREF(res); + return NULL; + } + PyList_SET_ITEM(res, i, tup); + } + return res; +} + +/*[clinic input] +_ssl._SSLSocket.cipher +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_cipher_impl(PySSLSocket *self) +/*[clinic end generated code: output=376417c16d0e5815 input=548fb0e27243796d]*/ +{ + const SSL_CIPHER *current; + + if (self->ssl == NULL) + Py_RETURN_NONE; + current = SSL_get_current_cipher(self->ssl); + if (current == NULL) + Py_RETURN_NONE; + return cipher_to_tuple(current); +} + +/*[clinic input] +_ssl._SSLSocket.version +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_version_impl(PySSLSocket *self) +/*[clinic end generated code: output=178aed33193b2cdb input=900186a503436fd6]*/ +{ + const char *version; + + if (self->ssl == NULL) + Py_RETURN_NONE; + if (!SSL_is_init_finished(self->ssl)) { + /* handshake not finished */ + Py_RETURN_NONE; + } + version = SSL_get_version(self->ssl); + if (!strcmp(version, "unknown")) + Py_RETURN_NONE; + return PyUnicode_FromString(version); +} + +#if HAVE_NPN +/*[clinic input] +_ssl._SSLSocket.selected_npn_protocol +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self) +/*[clinic end generated code: output=b91d494cd207ecf6 input=c28fde139204b826]*/ +{ + const unsigned char *out; + unsigned int outlen; + + SSL_get0_next_proto_negotiated(self->ssl, + &out, &outlen); + + if (out == NULL) + Py_RETURN_NONE; + return PyUnicode_FromStringAndSize((char *)out, outlen); +} +#endif + +#if HAVE_ALPN +/*[clinic input] +_ssl._SSLSocket.selected_alpn_protocol +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self) +/*[clinic end generated code: output=ec33688b303d250f input=442de30e35bc2913]*/ +{ + const unsigned char *out; + unsigned int outlen; + + SSL_get0_alpn_selected(self->ssl, &out, &outlen); + + if (out == NULL) + Py_RETURN_NONE; + return PyUnicode_FromStringAndSize((char *)out, outlen); +} +#endif + +/*[clinic input] +_ssl._SSLSocket.compression +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_compression_impl(PySSLSocket *self) +/*[clinic end generated code: output=bd16cb1bb4646ae7 input=5d059d0a2bbc32c8]*/ +{ +#ifdef OPENSSL_NO_COMP + Py_RETURN_NONE; +#else + const COMP_METHOD *comp_method; + const char *short_name; + + if (self->ssl == NULL) + Py_RETURN_NONE; + comp_method = SSL_get_current_compression(self->ssl); + if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef) + Py_RETURN_NONE; + short_name = OBJ_nid2sn(COMP_get_type(comp_method)); + if (short_name == NULL) + Py_RETURN_NONE; + return PyUnicode_DecodeFSDefault(short_name); +#endif +} + +static PySSLContext *PySSL_get_context(PySSLSocket *self, void *closure) { + Py_INCREF(self->ctx); + return self->ctx; +} + +static int PySSL_set_context(PySSLSocket *self, PyObject *value, + void *closure) { + + if (PyObject_TypeCheck(value, &PySSLContext_Type)) { +#if !HAVE_SNI + PyErr_SetString(PyExc_NotImplementedError, "setting a socket's " + "context is not supported by your OpenSSL library"); + return -1; +#else + Py_INCREF(value); + Py_SETREF(self->ctx, (PySSLContext *)value); + SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); + /* Set SSL* internal msg_callback to state of new context's state */ + SSL_set_msg_callback( + self->ssl, + self->ctx->msg_cb ? _PySSL_msg_callback : NULL + ); +#endif + } else { + PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext"); + return -1; + } + + return 0; +} + +PyDoc_STRVAR(PySSL_set_context_doc, +"_setter_context(ctx)\n\ +\ +This changes the context associated with the SSLSocket. This is typically\n\ +used from within a callback function set by the sni_callback\n\ +on the SSLContext to change the certificate information associated with the\n\ +SSLSocket before the cryptographic exchange handshake messages\n"); + + +static PyObject * +PySSL_get_server_side(PySSLSocket *self, void *c) +{ + return PyBool_FromLong(self->socket_type == PY_SSL_SERVER); +} + +PyDoc_STRVAR(PySSL_get_server_side_doc, +"Whether this is a server-side socket."); + +static PyObject * +PySSL_get_server_hostname(PySSLSocket *self, void *c) +{ + if (self->server_hostname == NULL) + Py_RETURN_NONE; + Py_INCREF(self->server_hostname); + return self->server_hostname; +} + +PyDoc_STRVAR(PySSL_get_server_hostname_doc, +"The currently set server hostname (for SNI)."); + +static PyObject * +PySSL_get_owner(PySSLSocket *self, void *c) +{ + PyObject *owner; + + if (self->owner == NULL) + Py_RETURN_NONE; + + owner = PyWeakref_GetObject(self->owner); + Py_INCREF(owner); + return owner; +} + +static int +PySSL_set_owner(PySSLSocket *self, PyObject *value, void *c) +{ + Py_XSETREF(self->owner, PyWeakref_NewRef(value, NULL)); + if (self->owner == NULL) + return -1; + return 0; +} + +PyDoc_STRVAR(PySSL_get_owner_doc, +"The Python-level owner of this object.\ +Passed as \"self\" in servername callback."); + +static int +PySSL_traverse(PySSLSocket *self, visitproc visit, void *arg) +{ + Py_VISIT(self->exc_type); + Py_VISIT(self->exc_value); + Py_VISIT(self->exc_tb); + return 0; +} + +static int +PySSL_clear(PySSLSocket *self) +{ + Py_CLEAR(self->exc_type); + Py_CLEAR(self->exc_value); + Py_CLEAR(self->exc_tb); + return 0; +} - /* and add that rendering to the list */ - - if (PyList_Append(peer_alt_names, t) < 0) { - Py_DECREF(t); - goto fail; - } - Py_DECREF(t); - } - sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); - } - BIO_free(biobuf); - if (peer_alt_names != Py_None) { - v = PyList_AsTuple(peer_alt_names); - Py_DECREF(peer_alt_names); - return v; - } else { - return peer_alt_names; - } - - - fail: - if (biobuf != NULL) - BIO_free(biobuf); - - if (peer_alt_names != Py_None) { - Py_XDECREF(peer_alt_names); - } - - return NULL; -} - -static PyObject * -_get_aia_uri(X509 *certificate, int nid) { - PyObject *lst = NULL, *ostr = NULL; - int i, result; - AUTHORITY_INFO_ACCESS *info; - - info = X509_get_ext_d2i(certificate, NID_info_access, NULL, NULL); - if (info == NULL) - return Py_None; - if (sk_ACCESS_DESCRIPTION_num(info) == 0) { - AUTHORITY_INFO_ACCESS_free(info); - return Py_None; - } - - if ((lst = PyList_New(0)) == NULL) { - goto fail; - } - - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { - ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); - ASN1_IA5STRING *uri; - - if ((OBJ_obj2nid(ad->method) != nid) || - (ad->location->type != GEN_URI)) { - continue; - } - uri = ad->location->d.uniformResourceIdentifier; - ostr = PyUnicode_FromStringAndSize((char *)uri->data, - uri->length); - if (ostr == NULL) { - goto fail; - } - result = PyList_Append(lst, ostr); - Py_DECREF(ostr); - if (result < 0) { - goto fail; - } - } - AUTHORITY_INFO_ACCESS_free(info); - - /* convert to tuple or None */ - if (PyList_Size(lst) == 0) { - Py_DECREF(lst); - return Py_None; - } else { - PyObject *tup; - tup = PyList_AsTuple(lst); - Py_DECREF(lst); - return tup; - } - - fail: - AUTHORITY_INFO_ACCESS_free(info); - Py_XDECREF(lst); - return NULL; -} - -static PyObject * -_get_crl_dp(X509 *certificate) { - STACK_OF(DIST_POINT) *dps; - int i, j; - PyObject *lst, *res = NULL; - - dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); - - if (dps == NULL) - return Py_None; - - lst = PyList_New(0); - if (lst == NULL) - goto done; - - for (i=0; i < sk_DIST_POINT_num(dps); i++) { - DIST_POINT *dp; - STACK_OF(GENERAL_NAME) *gns; - - dp = sk_DIST_POINT_value(dps, i); - if (dp->distpoint == NULL) { - /* Ignore empty DP value, CVE-2019-5010 */ - continue; - } - gns = dp->distpoint->name.fullname; - - for (j=0; j < sk_GENERAL_NAME_num(gns); j++) { - GENERAL_NAME *gn; - ASN1_IA5STRING *uri; - PyObject *ouri; - int err; - - gn = sk_GENERAL_NAME_value(gns, j); - if (gn->type != GEN_URI) { - continue; - } - uri = gn->d.uniformResourceIdentifier; - ouri = PyUnicode_FromStringAndSize((char *)uri->data, - uri->length); - if (ouri == NULL) - goto done; - - err = PyList_Append(lst, ouri); - Py_DECREF(ouri); - if (err < 0) - goto done; - } - } - - /* Convert to tuple. */ - res = (PyList_GET_SIZE(lst) > 0) ? PyList_AsTuple(lst) : Py_None; - - done: - Py_XDECREF(lst); - CRL_DIST_POINTS_free(dps); - return res; -} - -static PyObject * -_decode_certificate(X509 *certificate) { - - PyObject *retval = NULL; - BIO *biobuf = NULL; - PyObject *peer; - PyObject *peer_alt_names = NULL; - PyObject *issuer; - PyObject *version; - PyObject *sn_obj; - PyObject *obj; - ASN1_INTEGER *serialNumber; - char buf[2048]; - int len, result; - const ASN1_TIME *notBefore, *notAfter; - PyObject *pnotBefore, *pnotAfter; - - retval = PyDict_New(); - if (retval == NULL) - return NULL; - - peer = _create_tuple_for_X509_NAME( - X509_get_subject_name(certificate)); - if (peer == NULL) - goto fail0; - if (PyDict_SetItemString(retval, (const char *) "subject", peer) < 0) { - Py_DECREF(peer); - goto fail0; - } - Py_DECREF(peer); - - issuer = _create_tuple_for_X509_NAME( - X509_get_issuer_name(certificate)); - if (issuer == NULL) - goto fail0; - if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) { - Py_DECREF(issuer); - goto fail0; - } - Py_DECREF(issuer); - - version = PyLong_FromLong(X509_get_version(certificate) + 1); - if (version == NULL) - goto fail0; - if (PyDict_SetItemString(retval, "version", version) < 0) { - Py_DECREF(version); - goto fail0; - } - Py_DECREF(version); - - /* get a memory buffer */ - biobuf = BIO_new(BIO_s_mem()); - if (biobuf == NULL) { - PyErr_SetString(PySSLErrorObject, "failed to allocate BIO"); - goto fail0; - } - - (void) BIO_reset(biobuf); - serialNumber = X509_get_serialNumber(certificate); - /* should not exceed 20 octets, 160 bits, so buf is big enough */ - i2a_ASN1_INTEGER(biobuf, serialNumber); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - sn_obj = PyUnicode_FromStringAndSize(buf, len); - if (sn_obj == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) { - Py_DECREF(sn_obj); - goto fail1; - } - Py_DECREF(sn_obj); - - (void) BIO_reset(biobuf); - notBefore = X509_get0_notBefore(certificate); - ASN1_TIME_print(biobuf, notBefore); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - pnotBefore = PyUnicode_FromStringAndSize(buf, len); - if (pnotBefore == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) { - Py_DECREF(pnotBefore); - goto fail1; - } - Py_DECREF(pnotBefore); - - (void) BIO_reset(biobuf); - notAfter = X509_get0_notAfter(certificate); - ASN1_TIME_print(biobuf, notAfter); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - pnotAfter = PyUnicode_FromStringAndSize(buf, len); - if (pnotAfter == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "notAfter", pnotAfter) < 0) { - Py_DECREF(pnotAfter); - goto fail1; - } - Py_DECREF(pnotAfter); - - /* Now look for subjectAltName */ - - peer_alt_names = _get_peer_alt_names(certificate); - if (peer_alt_names == NULL) - goto fail1; - else if (peer_alt_names != Py_None) { - if (PyDict_SetItemString(retval, "subjectAltName", - peer_alt_names) < 0) { - Py_DECREF(peer_alt_names); - goto fail1; - } - Py_DECREF(peer_alt_names); - } - - /* Authority Information Access: OCSP URIs */ - obj = _get_aia_uri(certificate, NID_ad_OCSP); - if (obj == NULL) { - goto fail1; - } else if (obj != Py_None) { - result = PyDict_SetItemString(retval, "OCSP", obj); - Py_DECREF(obj); - if (result < 0) { - goto fail1; - } - } - - obj = _get_aia_uri(certificate, NID_ad_ca_issuers); - if (obj == NULL) { - goto fail1; - } else if (obj != Py_None) { - result = PyDict_SetItemString(retval, "caIssuers", obj); - Py_DECREF(obj); - if (result < 0) { - goto fail1; - } - } - - /* CDP (CRL distribution points) */ - obj = _get_crl_dp(certificate); - if (obj == NULL) { - goto fail1; - } else if (obj != Py_None) { - result = PyDict_SetItemString(retval, "crlDistributionPoints", obj); - Py_DECREF(obj); - if (result < 0) { - goto fail1; - } - } - - BIO_free(biobuf); - return retval; - - fail1: - if (biobuf != NULL) - BIO_free(biobuf); - fail0: - Py_XDECREF(retval); - return NULL; -} - -static PyObject * -_certificate_to_der(X509 *certificate) -{ - unsigned char *bytes_buf = NULL; - int len; - PyObject *retval; - - bytes_buf = NULL; - len = i2d_X509(certificate, &bytes_buf); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - /* this is actually an immutable bytes sequence */ - retval = PyBytes_FromStringAndSize((const char *) bytes_buf, len); - OPENSSL_free(bytes_buf); - return retval; -} - -/*[clinic input] -_ssl._test_decode_cert - path: object(converter="PyUnicode_FSConverter") - / - -[clinic start generated code]*/ - -static PyObject * -_ssl__test_decode_cert_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=96becb9abb23c091 input=cdeaaf02d4346628]*/ -{ - PyObject *retval = NULL; - X509 *x=NULL; - BIO *cert; - - if ((cert=BIO_new(BIO_s_file())) == NULL) { - PyErr_SetString(PySSLErrorObject, - "Can't malloc memory to read file"); - goto fail0; - } - - if (BIO_read_filename(cert, PyBytes_AsString(path)) <= 0) { - PyErr_SetString(PySSLErrorObject, - "Can't open file"); - goto fail0; - } - - x = PEM_read_bio_X509(cert, NULL, NULL, NULL); - if (x == NULL) { - PyErr_SetString(PySSLErrorObject, - "Error decoding PEM-encoded file"); - goto fail0; - } - - retval = _decode_certificate(x); - X509_free(x); - - fail0: - Py_DECREF(path); - if (cert != NULL) BIO_free(cert); - return retval; -} - - -/*[clinic input] -_ssl._SSLSocket.getpeercert - der as binary_mode: bool = False - / - -Returns the certificate for the peer. - -If no certificate was provided, returns None. If a certificate was -provided, but not validated, returns an empty dictionary. Otherwise -returns a dict containing information about the peer certificate. - -If the optional argument is True, returns a DER-encoded copy of the -peer certificate, or None if no certificate was provided. This will -return the certificate even if it wasn't validated. -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) -/*[clinic end generated code: output=1f0ab66dfb693c88 input=c0fbe802e57629b7]*/ -{ - int verification; - X509 *peer_cert; - PyObject *result; - - if (!SSL_is_init_finished(self->ssl)) { - PyErr_SetString(PyExc_ValueError, - "handshake not done yet"); - return NULL; - } - peer_cert = SSL_get_peer_certificate(self->ssl); - if (peer_cert == NULL) - Py_RETURN_NONE; - - if (binary_mode) { - /* return cert in DER-encoded format */ - result = _certificate_to_der(peer_cert); - } else { - verification = SSL_CTX_get_verify_mode(SSL_get_SSL_CTX(self->ssl)); - if ((verification & SSL_VERIFY_PEER) == 0) - result = PyDict_New(); - else - result = _decode_certificate(peer_cert); - } - X509_free(peer_cert); - return result; -} - -static PyObject * -cipher_to_tuple(const SSL_CIPHER *cipher) -{ - const char *cipher_name, *cipher_protocol; - PyObject *v, *retval = PyTuple_New(3); - if (retval == NULL) - return NULL; - - cipher_name = SSL_CIPHER_get_name(cipher); - if (cipher_name == NULL) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(retval, 0, Py_None); - } else { - v = PyUnicode_FromString(cipher_name); - if (v == NULL) - goto fail; - PyTuple_SET_ITEM(retval, 0, v); - } - - cipher_protocol = SSL_CIPHER_get_version(cipher); - if (cipher_protocol == NULL) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(retval, 1, Py_None); - } else { - v = PyUnicode_FromString(cipher_protocol); - if (v == NULL) - goto fail; - PyTuple_SET_ITEM(retval, 1, v); - } - - v = PyLong_FromLong(SSL_CIPHER_get_bits(cipher, NULL)); - if (v == NULL) - goto fail; - PyTuple_SET_ITEM(retval, 2, v); - - return retval; - - fail: - Py_DECREF(retval); - return NULL; -} - -#if OPENSSL_VERSION_NUMBER >= 0x10002000UL -static PyObject * -cipher_to_dict(const SSL_CIPHER *cipher) -{ - const char *cipher_name, *cipher_protocol; - - unsigned long cipher_id; - int alg_bits, strength_bits, len; - char buf[512] = {0}; -#if OPENSSL_VERSION_1_1 - int aead, nid; - const char *skcipher = NULL, *digest = NULL, *kx = NULL, *auth = NULL; -#endif - - /* can be NULL */ - cipher_name = SSL_CIPHER_get_name(cipher); - cipher_protocol = SSL_CIPHER_get_version(cipher); - cipher_id = SSL_CIPHER_get_id(cipher); - SSL_CIPHER_description(cipher, buf, sizeof(buf) - 1); - /* Downcast to avoid a warning. Safe since buf is always 512 bytes */ - len = (int)strlen(buf); - if (len > 1 && buf[len-1] == '\n') - buf[len-1] = '\0'; - strength_bits = SSL_CIPHER_get_bits(cipher, &alg_bits); - -#if OPENSSL_VERSION_1_1 - aead = SSL_CIPHER_is_aead(cipher); - nid = SSL_CIPHER_get_cipher_nid(cipher); - skcipher = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; - nid = SSL_CIPHER_get_digest_nid(cipher); - digest = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; - nid = SSL_CIPHER_get_kx_nid(cipher); - kx = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; - nid = SSL_CIPHER_get_auth_nid(cipher); - auth = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; -#endif - - return Py_BuildValue( - "{sksssssssisi" -#if OPENSSL_VERSION_1_1 - "sOssssssss" -#endif - "}", - "id", cipher_id, - "name", cipher_name, - "protocol", cipher_protocol, - "description", buf, - "strength_bits", strength_bits, - "alg_bits", alg_bits -#if OPENSSL_VERSION_1_1 - ,"aead", aead ? Py_True : Py_False, - "symmetric", skcipher, - "digest", digest, - "kea", kx, - "auth", auth -#endif - ); -} -#endif - -/*[clinic input] -_ssl._SSLSocket.shared_ciphers -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) -/*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/ -{ - STACK_OF(SSL_CIPHER) *ciphers; - int i; - PyObject *res; - - ciphers = SSL_get_ciphers(self->ssl); - if (!ciphers) - Py_RETURN_NONE; - res = PyList_New(sk_SSL_CIPHER_num(ciphers)); - if (!res) - return NULL; - for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { - PyObject *tup = cipher_to_tuple(sk_SSL_CIPHER_value(ciphers, i)); - if (!tup) { - Py_DECREF(res); - return NULL; - } - PyList_SET_ITEM(res, i, tup); - } - return res; -} - -/*[clinic input] -_ssl._SSLSocket.cipher -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_cipher_impl(PySSLSocket *self) -/*[clinic end generated code: output=376417c16d0e5815 input=548fb0e27243796d]*/ -{ - const SSL_CIPHER *current; - - if (self->ssl == NULL) - Py_RETURN_NONE; - current = SSL_get_current_cipher(self->ssl); - if (current == NULL) - Py_RETURN_NONE; - return cipher_to_tuple(current); -} - -/*[clinic input] -_ssl._SSLSocket.version -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_version_impl(PySSLSocket *self) -/*[clinic end generated code: output=178aed33193b2cdb input=900186a503436fd6]*/ -{ - const char *version; - - if (self->ssl == NULL) - Py_RETURN_NONE; - if (!SSL_is_init_finished(self->ssl)) { - /* handshake not finished */ - Py_RETURN_NONE; - } - version = SSL_get_version(self->ssl); - if (!strcmp(version, "unknown")) - Py_RETURN_NONE; - return PyUnicode_FromString(version); -} - -#if HAVE_NPN -/*[clinic input] -_ssl._SSLSocket.selected_npn_protocol -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self) -/*[clinic end generated code: output=b91d494cd207ecf6 input=c28fde139204b826]*/ -{ - const unsigned char *out; - unsigned int outlen; - - SSL_get0_next_proto_negotiated(self->ssl, - &out, &outlen); - - if (out == NULL) - Py_RETURN_NONE; - return PyUnicode_FromStringAndSize((char *)out, outlen); -} -#endif - -#if HAVE_ALPN -/*[clinic input] -_ssl._SSLSocket.selected_alpn_protocol -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self) -/*[clinic end generated code: output=ec33688b303d250f input=442de30e35bc2913]*/ -{ - const unsigned char *out; - unsigned int outlen; - - SSL_get0_alpn_selected(self->ssl, &out, &outlen); - - if (out == NULL) - Py_RETURN_NONE; - return PyUnicode_FromStringAndSize((char *)out, outlen); -} -#endif - -/*[clinic input] -_ssl._SSLSocket.compression -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_compression_impl(PySSLSocket *self) -/*[clinic end generated code: output=bd16cb1bb4646ae7 input=5d059d0a2bbc32c8]*/ -{ -#ifdef OPENSSL_NO_COMP - Py_RETURN_NONE; -#else - const COMP_METHOD *comp_method; - const char *short_name; - - if (self->ssl == NULL) - Py_RETURN_NONE; - comp_method = SSL_get_current_compression(self->ssl); - if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef) - Py_RETURN_NONE; - short_name = OBJ_nid2sn(COMP_get_type(comp_method)); - if (short_name == NULL) - Py_RETURN_NONE; - return PyUnicode_DecodeFSDefault(short_name); -#endif -} - -static PySSLContext *PySSL_get_context(PySSLSocket *self, void *closure) { - Py_INCREF(self->ctx); - return self->ctx; -} - -static int PySSL_set_context(PySSLSocket *self, PyObject *value, - void *closure) { - - if (PyObject_TypeCheck(value, &PySSLContext_Type)) { -#if !HAVE_SNI - PyErr_SetString(PyExc_NotImplementedError, "setting a socket's " - "context is not supported by your OpenSSL library"); - return -1; -#else - Py_INCREF(value); - Py_SETREF(self->ctx, (PySSLContext *)value); - SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); - /* Set SSL* internal msg_callback to state of new context's state */ - SSL_set_msg_callback( - self->ssl, - self->ctx->msg_cb ? _PySSL_msg_callback : NULL - ); -#endif - } else { - PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext"); - return -1; - } - - return 0; -} - -PyDoc_STRVAR(PySSL_set_context_doc, -"_setter_context(ctx)\n\ -\ -This changes the context associated with the SSLSocket. This is typically\n\ -used from within a callback function set by the sni_callback\n\ -on the SSLContext to change the certificate information associated with the\n\ -SSLSocket before the cryptographic exchange handshake messages\n"); - - -static PyObject * -PySSL_get_server_side(PySSLSocket *self, void *c) -{ - return PyBool_FromLong(self->socket_type == PY_SSL_SERVER); -} - -PyDoc_STRVAR(PySSL_get_server_side_doc, -"Whether this is a server-side socket."); - -static PyObject * -PySSL_get_server_hostname(PySSLSocket *self, void *c) -{ - if (self->server_hostname == NULL) - Py_RETURN_NONE; - Py_INCREF(self->server_hostname); - return self->server_hostname; -} - -PyDoc_STRVAR(PySSL_get_server_hostname_doc, -"The currently set server hostname (for SNI)."); - -static PyObject * -PySSL_get_owner(PySSLSocket *self, void *c) -{ - PyObject *owner; - - if (self->owner == NULL) - Py_RETURN_NONE; - - owner = PyWeakref_GetObject(self->owner); - Py_INCREF(owner); - return owner; -} - -static int -PySSL_set_owner(PySSLSocket *self, PyObject *value, void *c) -{ - Py_XSETREF(self->owner, PyWeakref_NewRef(value, NULL)); - if (self->owner == NULL) - return -1; - return 0; -} - -PyDoc_STRVAR(PySSL_get_owner_doc, -"The Python-level owner of this object.\ -Passed as \"self\" in servername callback."); - -static int -PySSL_traverse(PySSLSocket *self, visitproc visit, void *arg) -{ - Py_VISIT(self->exc_type); - Py_VISIT(self->exc_value); - Py_VISIT(self->exc_tb); - return 0; -} - -static int -PySSL_clear(PySSLSocket *self) -{ - Py_CLEAR(self->exc_type); - Py_CLEAR(self->exc_value); - Py_CLEAR(self->exc_tb); - return 0; -} - -static void -PySSL_dealloc(PySSLSocket *self) -{ - if (self->ssl) - SSL_free(self->ssl); - Py_XDECREF(self->Socket); - Py_XDECREF(self->ctx); - Py_XDECREF(self->server_hostname); - Py_XDECREF(self->owner); - PyObject_Del(self); -} - -/* If the socket has a timeout, do a select()/poll() on the socket. - The argument writing indicates the direction. - Returns one of the possibilities in the timeout_state enum (above). - */ - -static int -PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout) -{ - int rc; -#ifdef HAVE_POLL - struct pollfd pollfd; - _PyTime_t ms; -#else - int nfds; - fd_set fds; - struct timeval tv; -#endif - - /* Nothing to do unless we're in timeout mode (not non-blocking) */ - if ((s == NULL) || (timeout == 0)) - return SOCKET_IS_NONBLOCKING; - else if (timeout < 0) { - if (s->sock_timeout > 0) - return SOCKET_HAS_TIMED_OUT; - else - return SOCKET_IS_BLOCKING; - } - - /* Guard against closed socket */ - if (s->sock_fd == INVALID_SOCKET) - return SOCKET_HAS_BEEN_CLOSED; - - /* Prefer poll, if available, since you can poll() any fd - * which can't be done with select(). */ -#ifdef HAVE_POLL - pollfd.fd = s->sock_fd; - pollfd.events = writing ? POLLOUT : POLLIN; - - /* timeout is in seconds, poll() uses milliseconds */ - ms = (int)_PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); - assert(ms <= INT_MAX); - - PySSL_BEGIN_ALLOW_THREADS - rc = poll(&pollfd, 1, (int)ms); - PySSL_END_ALLOW_THREADS -#else - /* Guard against socket too large for select*/ - if (!_PyIsSelectable_fd(s->sock_fd)) - return SOCKET_TOO_LARGE_FOR_SELECT; - - _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING); - - FD_ZERO(&fds); - FD_SET(s->sock_fd, &fds); - - /* Wait until the socket becomes ready */ - PySSL_BEGIN_ALLOW_THREADS - nfds = Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int); - if (writing) - rc = select(nfds, NULL, &fds, NULL, &tv); - else - rc = select(nfds, &fds, NULL, NULL, &tv); - PySSL_END_ALLOW_THREADS -#endif - - /* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise - (when we are able to write or when there's something to read) */ - return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK; -} - -/*[clinic input] -_ssl._SSLSocket.write - b: Py_buffer - / - -Writes the bytes-like object b into the SSL object. - -Returns the number of bytes written. -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) -/*[clinic end generated code: output=aa7a6be5527358d8 input=77262d994fe5100a]*/ -{ - int len; - int sockstate; - _PySSLError err; - int nonblocking; - PySocketSockObject *sock = GET_SOCKET(self); - _PyTime_t timeout, deadline = 0; - int has_timeout; - - if (sock != NULL) { - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; - } - Py_INCREF(sock); - } - - if (b->len > INT_MAX) { - PyErr_Format(PyExc_OverflowError, - "string longer than %d bytes", INT_MAX); - goto error; - } - - if (sock != NULL) { - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - } - - timeout = GET_SOCKET_TIMEOUT(sock); - has_timeout = (timeout > 0); - if (has_timeout) - deadline = _PyTime_GetMonotonicClock() + timeout; - - sockstate = PySSL_select(sock, 1, timeout); - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, - "The write operation timed out"); - goto error; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket has been closed."); - goto error; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket too large for select()."); - goto error; - } - - do { - PySSL_BEGIN_ALLOW_THREADS - len = SSL_write(self->ssl, b->buf, (int)b->len); - err = _PySSL_errno(len <= 0, self->ssl, len); - PySSL_END_ALLOW_THREADS - self->err = err; - - if (PyErr_CheckSignals()) - goto error; - - if (has_timeout) - timeout = deadline - _PyTime_GetMonotonicClock(); - - if (err.ssl == SSL_ERROR_WANT_READ) { - sockstate = PySSL_select(sock, 0, timeout); - } else if (err.ssl == SSL_ERROR_WANT_WRITE) { - sockstate = PySSL_select(sock, 1, timeout); - } else { - sockstate = SOCKET_OPERATION_OK; - } - - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, - "The write operation timed out"); - goto error; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket has been closed."); - goto error; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err.ssl == SSL_ERROR_WANT_READ || - err.ssl == SSL_ERROR_WANT_WRITE); - - Py_XDECREF(sock); - if (len <= 0) - return PySSL_SetError(self, len, __FILE__, __LINE__); - if (PySSL_ChainExceptions(self) < 0) - return NULL; - return PyLong_FromLong(len); -error: - Py_XDECREF(sock); - PySSL_ChainExceptions(self); - return NULL; -} - -/*[clinic input] -_ssl._SSLSocket.pending - -Returns the number of already decrypted bytes available for read, pending on the connection. -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_pending_impl(PySSLSocket *self) -/*[clinic end generated code: output=983d9fecdc308a83 input=2b77487d6dfd597f]*/ -{ - int count = 0; - _PySSLError err; - - PySSL_BEGIN_ALLOW_THREADS - count = SSL_pending(self->ssl); - err = _PySSL_errno(count < 0, self->ssl, count); - PySSL_END_ALLOW_THREADS - self->err = err; - - if (count < 0) - return PySSL_SetError(self, count, __FILE__, __LINE__); - else - return PyLong_FromLong(count); -} - -/*[clinic input] -_ssl._SSLSocket.read - size as len: int - [ - buffer: Py_buffer(accept={rwbuffer}) - ] - / - -Read up to size bytes from the SSL socket. -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, - Py_buffer *buffer) -/*[clinic end generated code: output=00097776cec2a0af input=ff157eb918d0905b]*/ -{ - PyObject *dest = NULL; - char *mem; - int count; - int sockstate; - _PySSLError err; - int nonblocking; - PySocketSockObject *sock = GET_SOCKET(self); - _PyTime_t timeout, deadline = 0; - int has_timeout; - - if (!group_right_1 && len < 0) { - PyErr_SetString(PyExc_ValueError, "size should not be negative"); - return NULL; - } - - if (sock != NULL) { - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; - } - Py_INCREF(sock); - } - - if (!group_right_1) { - dest = PyBytes_FromStringAndSize(NULL, len); - if (dest == NULL) - goto error; - if (len == 0) { - Py_XDECREF(sock); - return dest; - } - mem = PyBytes_AS_STRING(dest); - } - else { - mem = buffer->buf; - if (len <= 0 || len > buffer->len) { - len = (int) buffer->len; - if (buffer->len != len) { - PyErr_SetString(PyExc_OverflowError, - "maximum length can't fit in a C 'int'"); - goto error; - } - if (len == 0) { - count = 0; - goto done; - } - } - } - - if (sock != NULL) { - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - } - - timeout = GET_SOCKET_TIMEOUT(sock); - has_timeout = (timeout > 0); - if (has_timeout) - deadline = _PyTime_GetMonotonicClock() + timeout; - - do { - PySSL_BEGIN_ALLOW_THREADS - count = SSL_read(self->ssl, mem, len); - err = _PySSL_errno(count <= 0, self->ssl, count); - PySSL_END_ALLOW_THREADS - self->err = err; - - if (PyErr_CheckSignals()) - goto error; - - if (has_timeout) - timeout = deadline - _PyTime_GetMonotonicClock(); - - if (err.ssl == SSL_ERROR_WANT_READ) { - sockstate = PySSL_select(sock, 0, timeout); - } else if (err.ssl == SSL_ERROR_WANT_WRITE) { - sockstate = PySSL_select(sock, 1, timeout); - } else if (err.ssl == SSL_ERROR_ZERO_RETURN && - SSL_get_shutdown(self->ssl) == SSL_RECEIVED_SHUTDOWN) - { - count = 0; - goto done; - } - else - sockstate = SOCKET_OPERATION_OK; - - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, - "The read operation timed out"); - goto error; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err.ssl == SSL_ERROR_WANT_READ || - err.ssl == SSL_ERROR_WANT_WRITE); - - if (count <= 0) { - PySSL_SetError(self, count, __FILE__, __LINE__); - goto error; - } - if (self->exc_type != NULL) - goto error; - -done: - Py_XDECREF(sock); - if (!group_right_1) { - _PyBytes_Resize(&dest, count); - return dest; - } - else { - return PyLong_FromLong(count); - } - -error: - PySSL_ChainExceptions(self); - Py_XDECREF(sock); - if (!group_right_1) - Py_XDECREF(dest); - return NULL; -} - -/*[clinic input] -_ssl._SSLSocket.shutdown - -Does the SSL shutdown handshake with the remote end. -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_shutdown_impl(PySSLSocket *self) -/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=11d39e69b0a2bf4a]*/ -{ - _PySSLError err; - int sockstate, nonblocking, ret; - int zeros = 0; - PySocketSockObject *sock = GET_SOCKET(self); - _PyTime_t timeout, deadline = 0; - int has_timeout; - - if (sock != NULL) { - /* Guard against closed socket */ - if ((((PyObject*)sock) == Py_None) || (sock->sock_fd == INVALID_SOCKET)) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; - } - Py_INCREF(sock); - - /* Just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - } - - timeout = GET_SOCKET_TIMEOUT(sock); - has_timeout = (timeout > 0); - if (has_timeout) - deadline = _PyTime_GetMonotonicClock() + timeout; - - while (1) { - PySSL_BEGIN_ALLOW_THREADS - /* Disable read-ahead so that unwrap can work correctly. - * Otherwise OpenSSL might read in too much data, - * eating clear text data that happens to be - * transmitted after the SSL shutdown. - * Should be safe to call repeatedly every time this - * function is used and the shutdown_seen_zero != 0 - * condition is met. - */ - if (self->shutdown_seen_zero) - SSL_set_read_ahead(self->ssl, 0); - ret = SSL_shutdown(self->ssl); - err = _PySSL_errno(ret < 0, self->ssl, ret); - PySSL_END_ALLOW_THREADS - self->err = err; - - /* If err == 1, a secure shutdown with SSL_shutdown() is complete */ - if (ret > 0) - break; - if (ret == 0) { - /* Don't loop endlessly; instead preserve legacy - behaviour of trying SSL_shutdown() only twice. - This looks necessary for OpenSSL < 0.9.8m */ - if (++zeros > 1) - break; - /* Shutdown was sent, now try receiving */ - self->shutdown_seen_zero = 1; - continue; - } - - if (has_timeout) - timeout = deadline - _PyTime_GetMonotonicClock(); - - /* Possibly retry shutdown until timeout or failure */ - if (err.ssl == SSL_ERROR_WANT_READ) - sockstate = PySSL_select(sock, 0, timeout); - else if (err.ssl == SSL_ERROR_WANT_WRITE) - sockstate = PySSL_select(sock, 1, timeout); - else - break; - - if (sockstate == SOCKET_HAS_TIMED_OUT) { - if (err.ssl == SSL_ERROR_WANT_READ) - PyErr_SetString(PySocketModule.timeout_error, - "The read operation timed out"); - else - PyErr_SetString(PySocketModule.timeout_error, - "The write operation timed out"); - goto error; - } - else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket too large for select()."); - goto error; - } - else if (sockstate != SOCKET_OPERATION_OK) - /* Retain the SSL error code */ - break; - } - if (ret < 0) { - Py_XDECREF(sock); - PySSL_SetError(self, ret, __FILE__, __LINE__); - return NULL; - } - if (self->exc_type != NULL) - goto error; - if (sock) - /* It's already INCREF'ed */ - return (PyObject *) sock; - else - Py_RETURN_NONE; - -error: - Py_XDECREF(sock); - PySSL_ChainExceptions(self); - return NULL; -} - -/*[clinic input] -_ssl._SSLSocket.get_channel_binding - cb_type: str = "tls-unique" - -Get channel binding data for current connection. - -Raise ValueError if the requested `cb_type` is not supported. Return bytes -of the data or None if the data is not available (e.g. before the handshake). -Only 'tls-unique' channel binding data from RFC 5929 is supported. -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, - const char *cb_type) -/*[clinic end generated code: output=34bac9acb6a61d31 input=08b7e43b99c17d41]*/ -{ - char buf[PySSL_CB_MAXLEN]; - size_t len; - - if (strcmp(cb_type, "tls-unique") == 0) { - if (SSL_session_reused(self->ssl) ^ !self->socket_type) { - /* if session is resumed XOR we are the client */ - len = SSL_get_finished(self->ssl, buf, PySSL_CB_MAXLEN); - } - else { - /* if a new session XOR we are the server */ - len = SSL_get_peer_finished(self->ssl, buf, PySSL_CB_MAXLEN); - } - } - else { - PyErr_Format( - PyExc_ValueError, - "'%s' channel binding type not implemented", - cb_type - ); - return NULL; - } - - /* It cannot be negative in current OpenSSL version as of July 2011 */ - if (len == 0) - Py_RETURN_NONE; - - return PyBytes_FromStringAndSize(buf, len); -} - -/*[clinic input] -_ssl._SSLSocket.verify_client_post_handshake - -Initiate TLS 1.3 post-handshake authentication -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) -/*[clinic end generated code: output=532147f3b1341425 input=6bfa874810a3d889]*/ -{ -#ifdef TLS1_3_VERSION - int err = SSL_verify_client_post_handshake(self->ssl); - if (err == 0) - return _setSSLError(NULL, 0, __FILE__, __LINE__); - else - Py_RETURN_NONE; -#else - PyErr_SetString(PyExc_NotImplementedError, - "Post-handshake auth is not supported by your " - "OpenSSL version."); - return NULL; -#endif -} - -#ifdef OPENSSL_VERSION_1_1 - -static SSL_SESSION* -_ssl_session_dup(SSL_SESSION *session) { - SSL_SESSION *newsession = NULL; - int slen; - unsigned char *senc = NULL, *p; - const unsigned char *const_p; - - if (session == NULL) { - PyErr_SetString(PyExc_ValueError, "Invalid session"); - goto error; - } - - /* get length */ - slen = i2d_SSL_SESSION(session, NULL); - if (slen == 0 || slen > 0xFF00) { - PyErr_SetString(PyExc_ValueError, "i2d() failed."); - goto error; - } - if ((senc = PyMem_Malloc(slen)) == NULL) { - PyErr_NoMemory(); - goto error; - } - p = senc; - if (!i2d_SSL_SESSION(session, &p)) { - PyErr_SetString(PyExc_ValueError, "i2d() failed."); - goto error; - } - const_p = senc; - newsession = d2i_SSL_SESSION(NULL, &const_p, slen); - if (session == NULL) { - goto error; - } - PyMem_Free(senc); - return newsession; - error: - if (senc != NULL) { - PyMem_Free(senc); - } - return NULL; -} -#endif - -static PyObject * -PySSL_get_session(PySSLSocket *self, void *closure) { - /* get_session can return sessions from a server-side connection, - * it does not check for handshake done or client socket. */ - PySSLSession *pysess; - SSL_SESSION *session; - -#ifdef OPENSSL_VERSION_1_1 - /* duplicate session as workaround for session bug in OpenSSL 1.1.0, - * https://github.com/openssl/openssl/issues/1550 */ - session = SSL_get0_session(self->ssl); /* borrowed reference */ - if (session == NULL) { - Py_RETURN_NONE; - } - if ((session = _ssl_session_dup(session)) == NULL) { - return NULL; - } -#else - session = SSL_get1_session(self->ssl); - if (session == NULL) { - Py_RETURN_NONE; - } -#endif - pysess = PyObject_GC_New(PySSLSession, &PySSLSession_Type); - if (pysess == NULL) { - SSL_SESSION_free(session); - return NULL; - } - - assert(self->ctx); - pysess->ctx = self->ctx; - Py_INCREF(pysess->ctx); - pysess->session = session; - PyObject_GC_Track(pysess); - return (PyObject *)pysess; -} - -static int PySSL_set_session(PySSLSocket *self, PyObject *value, - void *closure) - { - PySSLSession *pysess; -#ifdef OPENSSL_VERSION_1_1 - SSL_SESSION *session; -#endif - int result; - - if (!PySSLSession_Check(value)) { - PyErr_SetString(PyExc_TypeError, "Value is not a SSLSession."); - return -1; - } - pysess = (PySSLSession *)value; - - if (self->ctx->ctx != pysess->ctx->ctx) { - PyErr_SetString(PyExc_ValueError, - "Session refers to a different SSLContext."); - return -1; - } - if (self->socket_type != PY_SSL_CLIENT) { - PyErr_SetString(PyExc_ValueError, - "Cannot set session for server-side SSLSocket."); - return -1; - } - if (SSL_is_init_finished(self->ssl)) { - PyErr_SetString(PyExc_ValueError, - "Cannot set session after handshake."); - return -1; - } -#ifdef OPENSSL_VERSION_1_1 - /* duplicate session */ - if ((session = _ssl_session_dup(pysess->session)) == NULL) { - return -1; - } - result = SSL_set_session(self->ssl, session); - /* free duplicate, SSL_set_session() bumps ref count */ - SSL_SESSION_free(session); -#else - result = SSL_set_session(self->ssl, pysess->session); -#endif - if (result == 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return -1; - } - return 0; -} - -PyDoc_STRVAR(PySSL_set_session_doc, -"_setter_session(session)\n\ -\ -Get / set SSLSession."); - -static PyObject * -PySSL_get_session_reused(PySSLSocket *self, void *closure) { - if (SSL_session_reused(self->ssl)) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } -} - -PyDoc_STRVAR(PySSL_get_session_reused_doc, -"Was the client session reused during handshake?"); - -static PyGetSetDef ssl_getsetlist[] = { - {"context", (getter) PySSL_get_context, - (setter) PySSL_set_context, PySSL_set_context_doc}, - {"server_side", (getter) PySSL_get_server_side, NULL, - PySSL_get_server_side_doc}, - {"server_hostname", (getter) PySSL_get_server_hostname, NULL, - PySSL_get_server_hostname_doc}, - {"owner", (getter) PySSL_get_owner, (setter) PySSL_set_owner, - PySSL_get_owner_doc}, - {"session", (getter) PySSL_get_session, - (setter) PySSL_set_session, PySSL_set_session_doc}, - {"session_reused", (getter) PySSL_get_session_reused, NULL, - PySSL_get_session_reused_doc}, - {NULL}, /* sentinel */ -}; - -static PyMethodDef PySSLMethods[] = { - _SSL__SSLSOCKET_DO_HANDSHAKE_METHODDEF - _SSL__SSLSOCKET_WRITE_METHODDEF - _SSL__SSLSOCKET_READ_METHODDEF - _SSL__SSLSOCKET_PENDING_METHODDEF - _SSL__SSLSOCKET_GETPEERCERT_METHODDEF - _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF - _SSL__SSLSOCKET_CIPHER_METHODDEF - _SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF - _SSL__SSLSOCKET_VERSION_METHODDEF - _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF - _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF - _SSL__SSLSOCKET_COMPRESSION_METHODDEF - _SSL__SSLSOCKET_SHUTDOWN_METHODDEF - _SSL__SSLSOCKET_VERIFY_CLIENT_POST_HANDSHAKE_METHODDEF - {NULL, NULL} -}; - -static PyTypeObject PySSLSocket_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl._SSLSocket", /*tp_name*/ - sizeof(PySSLSocket), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PySSL_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc) PySSL_traverse, /*tp_traverse*/ - (inquiry) PySSL_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - PySSLMethods, /*tp_methods*/ - 0, /*tp_members*/ - ssl_getsetlist, /*tp_getset*/ -}; - - -/* - * _SSLContext objects - */ - -static int -_set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n) -{ - int mode; - int (*verify_cb)(int, X509_STORE_CTX *) = NULL; - - switch(n) { - case PY_SSL_CERT_NONE: - mode = SSL_VERIFY_NONE; - break; - case PY_SSL_CERT_OPTIONAL: - mode = SSL_VERIFY_PEER; - break; - case PY_SSL_CERT_REQUIRED: - mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - break; - default: - PyErr_SetString(PyExc_ValueError, - "invalid value for verify_mode"); - return -1; - } - - /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for - * server sockets and SSL_set_post_handshake_auth() for client. */ - - /* keep current verify cb */ - verify_cb = SSL_CTX_get_verify_callback(self->ctx); - SSL_CTX_set_verify(self->ctx, mode, verify_cb); - return 0; -} - -/*[clinic input] -@classmethod -_ssl._SSLContext.__new__ - protocol as proto_version: int - / -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_impl(PyTypeObject *type, int proto_version) -/*[clinic end generated code: output=2cf0d7a0741b6bd1 input=8d58a805b95fc534]*/ -{ - PySSLContext *self; - long options; - SSL_CTX *ctx = NULL; - X509_VERIFY_PARAM *params; - int result; -#if defined(SSL_MODE_RELEASE_BUFFERS) - unsigned long libver; -#endif - - PySSL_BEGIN_ALLOW_THREADS - switch(proto_version) { -#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) - case PY_SSL_VERSION_SSL3: - ctx = SSL_CTX_new(SSLv3_method()); - break; -#endif -#if (defined(TLS1_VERSION) && \ - !defined(OPENSSL_NO_TLS1) && \ - !defined(OPENSSL_NO_TLS1_METHOD)) - case PY_SSL_VERSION_TLS1: - ctx = SSL_CTX_new(TLSv1_method()); - break; -#endif -#if (defined(TLS1_1_VERSION) && \ - !defined(OPENSSL_NO_TLS1_1) && \ - !defined(OPENSSL_NO_TLS1_1_METHOD)) - case PY_SSL_VERSION_TLS1_1: - ctx = SSL_CTX_new(TLSv1_1_method()); - break; -#endif -#if (defined(TLS1_2_VERSION) && \ - !defined(OPENSSL_NO_TLS1_2) && \ - !defined(OPENSSL_NO_TLS1_2_METHOD)) - case PY_SSL_VERSION_TLS1_2: - ctx = SSL_CTX_new(TLSv1_2_method()); - break; -#endif - case PY_SSL_VERSION_TLS: - /* SSLv23 */ - ctx = SSL_CTX_new(TLS_method()); - break; - case PY_SSL_VERSION_TLS_CLIENT: - ctx = SSL_CTX_new(TLS_client_method()); - break; - case PY_SSL_VERSION_TLS_SERVER: - ctx = SSL_CTX_new(TLS_server_method()); - break; - default: - proto_version = -1; - } - PySSL_END_ALLOW_THREADS - - if (proto_version == -1) { - PyErr_SetString(PyExc_ValueError, - "invalid or unsupported protocol version"); - return NULL; - } - if (ctx == NULL) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - - assert(type != NULL && type->tp_alloc != NULL); - self = (PySSLContext *) type->tp_alloc(type, 0); - if (self == NULL) { - SSL_CTX_free(ctx); - return NULL; - } - self->ctx = ctx; - self->hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; - self->protocol = proto_version; - self->msg_cb = NULL; -#ifdef HAVE_OPENSSL_KEYLOG - self->keylog_filename = NULL; - self->keylog_bio = NULL; -#endif -#if HAVE_NPN - self->npn_protocols = NULL; -#endif -#if HAVE_ALPN - self->alpn_protocols = NULL; -#endif -#ifndef OPENSSL_NO_TLSEXT - self->set_sni_cb = NULL; -#endif - /* Don't check host name by default */ - if (proto_version == PY_SSL_VERSION_TLS_CLIENT) { - self->check_hostname = 1; - if (_set_verify_mode(self, PY_SSL_CERT_REQUIRED) == -1) { - Py_DECREF(self); - return NULL; - } - } else { - self->check_hostname = 0; - if (_set_verify_mode(self, PY_SSL_CERT_NONE) == -1) { - Py_DECREF(self); - return NULL; - } - } - /* Defaults */ - options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; - if (proto_version != PY_SSL_VERSION_SSL2) - options |= SSL_OP_NO_SSLv2; - if (proto_version != PY_SSL_VERSION_SSL3) - options |= SSL_OP_NO_SSLv3; - /* Minimal security flags for server and client side context. - * Client sockets ignore server-side parameters. */ -#ifdef SSL_OP_NO_COMPRESSION - options |= SSL_OP_NO_COMPRESSION; -#endif -#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE - options |= SSL_OP_CIPHER_SERVER_PREFERENCE; -#endif -#ifdef SSL_OP_SINGLE_DH_USE - options |= SSL_OP_SINGLE_DH_USE; -#endif -#ifdef SSL_OP_SINGLE_ECDH_USE - options |= SSL_OP_SINGLE_ECDH_USE; -#endif -#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF - /* Make OpenSSL 3.0.0 behave like 1.1.1 */ - options |= SSL_OP_IGNORE_UNEXPECTED_EOF; -#endif - SSL_CTX_set_options(self->ctx, options); - - /* A bare minimum cipher list without completely broken cipher suites. - * It's far from perfect but gives users a better head start. */ - if (proto_version != PY_SSL_VERSION_SSL2) { -#if PY_SSL_DEFAULT_CIPHERS == 2 - /* stick to OpenSSL's default settings */ - result = 1; -#else - result = SSL_CTX_set_cipher_list(ctx, PY_SSL_DEFAULT_CIPHER_STRING); -#endif - } else { - /* SSLv2 needs MD5 */ - result = SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!eNULL"); - } - if (result == 0) { - Py_DECREF(self); - ERR_clear_error(); - PyErr_SetString(PySSLErrorObject, - "No cipher can be selected."); - return NULL; - } - -#if defined(SSL_MODE_RELEASE_BUFFERS) - /* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory - usage for no cost at all. However, don't do this for OpenSSL versions - between 1.0.1 and 1.0.1h or 1.0.0 and 1.0.0m, which are affected by CVE - 2014-0198. I can't find exactly which beta fixed this CVE, so be - conservative and assume it wasn't fixed until release. We do this check - at runtime to avoid problems from the dynamic linker. - See #25672 for more on this. */ - libver = OpenSSL_version_num(); - if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) && - !(libver >= 0x10000000UL && libver < 0x100000dfUL)) { - SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); - } -#endif - - -#if !defined(OPENSSL_NO_ECDH) && !defined(OPENSSL_VERSION_1_1) - /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use - prime256v1 by default. This is Apache mod_ssl's initialization - policy, so we should be safe. OpenSSL 1.1 has it enabled by default. - */ -#if defined(SSL_CTX_set_ecdh_auto) - SSL_CTX_set_ecdh_auto(self->ctx, 1); -#else - { - EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - SSL_CTX_set_tmp_ecdh(self->ctx, key); - EC_KEY_free(key); - } -#endif -#endif - -#define SID_CTX "Python" - SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX, - sizeof(SID_CTX)); -#undef SID_CTX - - params = SSL_CTX_get0_param(self->ctx); -#ifdef X509_V_FLAG_TRUSTED_FIRST - /* Improve trust chain building when cross-signed intermediate - certificates are present. See https://bugs.python.org/issue23476. */ - X509_VERIFY_PARAM_set_flags(params, X509_V_FLAG_TRUSTED_FIRST); -#endif - X509_VERIFY_PARAM_set_hostflags(params, self->hostflags); - -#ifdef TLS1_3_VERSION - self->post_handshake_auth = 0; - SSL_CTX_set_post_handshake_auth(self->ctx, self->post_handshake_auth); -#endif - - return (PyObject *)self; -} - -static int -context_traverse(PySSLContext *self, visitproc visit, void *arg) -{ -#ifndef OPENSSL_NO_TLSEXT - Py_VISIT(self->set_sni_cb); -#endif - Py_VISIT(self->msg_cb); - return 0; -} - -static int -context_clear(PySSLContext *self) -{ -#ifndef OPENSSL_NO_TLSEXT - Py_CLEAR(self->set_sni_cb); -#endif - Py_CLEAR(self->msg_cb); -#ifdef HAVE_OPENSSL_KEYLOG - Py_CLEAR(self->keylog_filename); - if (self->keylog_bio != NULL) { - PySSL_BEGIN_ALLOW_THREADS - BIO_free_all(self->keylog_bio); - PySSL_END_ALLOW_THREADS - self->keylog_bio = NULL; - } -#endif - return 0; -} - -static void -context_dealloc(PySSLContext *self) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(self); - context_clear(self); - SSL_CTX_free(self->ctx); -#if HAVE_NPN - PyMem_FREE(self->npn_protocols); -#endif -#if HAVE_ALPN - PyMem_FREE(self->alpn_protocols); -#endif - Py_TYPE(self)->tp_free(self); -} - -/*[clinic input] -_ssl._SSLContext.set_ciphers - cipherlist: str - / -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) -/*[clinic end generated code: output=3a3162f3557c0f3f input=a7ac931b9f3ca7fc]*/ -{ - int ret = SSL_CTX_set_cipher_list(self->ctx, cipherlist); - if (ret == 0) { - /* Clearing the error queue is necessary on some OpenSSL versions, - otherwise the error will be reported again when another SSL call - is done. */ - ERR_clear_error(); - PyErr_SetString(PySSLErrorObject, - "No cipher can be selected."); - return NULL; - } - Py_RETURN_NONE; -} - -#if OPENSSL_VERSION_NUMBER >= 0x10002000UL -/*[clinic input] -_ssl._SSLContext.get_ciphers -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_get_ciphers_impl(PySSLContext *self) -/*[clinic end generated code: output=a56e4d68a406dfc4 input=a2aadc9af89b79c5]*/ -{ - SSL *ssl = NULL; - STACK_OF(SSL_CIPHER) *sk = NULL; - const SSL_CIPHER *cipher; - int i=0; - PyObject *result = NULL, *dct; - - ssl = SSL_new(self->ctx); - if (ssl == NULL) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto exit; - } - sk = SSL_get_ciphers(ssl); - - result = PyList_New(sk_SSL_CIPHER_num(sk)); - if (result == NULL) { - goto exit; - } - - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - cipher = sk_SSL_CIPHER_value(sk, i); - dct = cipher_to_dict(cipher); - if (dct == NULL) { - Py_CLEAR(result); - goto exit; - } - PyList_SET_ITEM(result, i, dct); - } - - exit: - if (ssl != NULL) - SSL_free(ssl); - return result; - -} -#endif - - -#if HAVE_NPN || HAVE_ALPN -static int -do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, - const unsigned char *server_protocols, unsigned int server_protocols_len, - const unsigned char *client_protocols, unsigned int client_protocols_len) -{ - int ret; - if (client_protocols == NULL) { - client_protocols = (unsigned char *)""; - client_protocols_len = 0; - } - if (server_protocols == NULL) { - server_protocols = (unsigned char *)""; - server_protocols_len = 0; - } - - ret = SSL_select_next_proto(out, outlen, - server_protocols, server_protocols_len, - client_protocols, client_protocols_len); - if (alpn && ret != OPENSSL_NPN_NEGOTIATED) - return SSL_TLSEXT_ERR_NOACK; - - return SSL_TLSEXT_ERR_OK; -} -#endif - -#if HAVE_NPN -/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */ -static int -_advertiseNPN_cb(SSL *s, - const unsigned char **data, unsigned int *len, - void *args) -{ - PySSLContext *ssl_ctx = (PySSLContext *) args; - - if (ssl_ctx->npn_protocols == NULL) { - *data = (unsigned char *)""; - *len = 0; - } else { - *data = ssl_ctx->npn_protocols; - *len = ssl_ctx->npn_protocols_len; - } - - return SSL_TLSEXT_ERR_OK; -} -/* this callback gets passed to SSL_CTX_set_next_proto_select_cb */ -static int -_selectNPN_cb(SSL *s, - unsigned char **out, unsigned char *outlen, - const unsigned char *server, unsigned int server_len, - void *args) -{ - PySSLContext *ctx = (PySSLContext *)args; - return do_protocol_selection(0, out, outlen, server, server_len, - ctx->npn_protocols, ctx->npn_protocols_len); -} -#endif - -/*[clinic input] -_ssl._SSLContext._set_npn_protocols - protos: Py_buffer - / -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, - Py_buffer *protos) -/*[clinic end generated code: output=72b002c3324390c6 input=319fcb66abf95bd7]*/ -{ -#if HAVE_NPN - PyMem_Free(self->npn_protocols); - self->npn_protocols = PyMem_Malloc(protos->len); - if (self->npn_protocols == NULL) - return PyErr_NoMemory(); - memcpy(self->npn_protocols, protos->buf, protos->len); - self->npn_protocols_len = (int) protos->len; - - /* set both server and client callbacks, because the context can - * be used to create both types of sockets */ - SSL_CTX_set_next_protos_advertised_cb(self->ctx, - _advertiseNPN_cb, - self); - SSL_CTX_set_next_proto_select_cb(self->ctx, - _selectNPN_cb, - self); - - Py_RETURN_NONE; -#else - PyErr_SetString(PyExc_NotImplementedError, - "The NPN extension requires OpenSSL 1.0.1 or later."); - return NULL; -#endif -} - -#if HAVE_ALPN -static int -_selectALPN_cb(SSL *s, - const unsigned char **out, unsigned char *outlen, - const unsigned char *client_protocols, unsigned int client_protocols_len, - void *args) -{ - PySSLContext *ctx = (PySSLContext *)args; - return do_protocol_selection(1, (unsigned char **)out, outlen, - ctx->alpn_protocols, ctx->alpn_protocols_len, - client_protocols, client_protocols_len); -} -#endif - -/*[clinic input] -_ssl._SSLContext._set_alpn_protocols - protos: Py_buffer - / -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, - Py_buffer *protos) -/*[clinic end generated code: output=87599a7f76651a9b input=9bba964595d519be]*/ -{ -#if HAVE_ALPN - if ((size_t)protos->len > UINT_MAX) { - PyErr_Format(PyExc_OverflowError, - "protocols longer than %u bytes", UINT_MAX); - return NULL; - } - - PyMem_FREE(self->alpn_protocols); - self->alpn_protocols = PyMem_Malloc(protos->len); - if (!self->alpn_protocols) - return PyErr_NoMemory(); - memcpy(self->alpn_protocols, protos->buf, protos->len); - self->alpn_protocols_len = (unsigned int)protos->len; - - if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) - return PyErr_NoMemory(); - SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); - - Py_RETURN_NONE; -#else - PyErr_SetString(PyExc_NotImplementedError, - "The ALPN extension requires OpenSSL 1.0.2 or later."); - return NULL; -#endif -} - -static PyObject * -get_verify_mode(PySSLContext *self, void *c) -{ - /* ignore SSL_VERIFY_CLIENT_ONCE and SSL_VERIFY_POST_HANDSHAKE */ - int mask = (SSL_VERIFY_NONE | SSL_VERIFY_PEER | - SSL_VERIFY_FAIL_IF_NO_PEER_CERT); - switch (SSL_CTX_get_verify_mode(self->ctx) & mask) { - case SSL_VERIFY_NONE: - return PyLong_FromLong(PY_SSL_CERT_NONE); - case SSL_VERIFY_PEER: - return PyLong_FromLong(PY_SSL_CERT_OPTIONAL); - case SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT: - return PyLong_FromLong(PY_SSL_CERT_REQUIRED); - } - PyErr_SetString(PySSLErrorObject, - "invalid return value from SSL_CTX_get_verify_mode"); - return NULL; -} - -static int -set_verify_mode(PySSLContext *self, PyObject *arg, void *c) -{ - int n; - if (!PyArg_Parse(arg, "i", &n)) - return -1; - if (n == PY_SSL_CERT_NONE && self->check_hostname) { - PyErr_SetString(PyExc_ValueError, - "Cannot set verify_mode to CERT_NONE when " - "check_hostname is enabled."); - return -1; - } - return _set_verify_mode(self, n); -} - -static PyObject * -get_verify_flags(PySSLContext *self, void *c) -{ - X509_VERIFY_PARAM *param; - unsigned long flags; - - param = SSL_CTX_get0_param(self->ctx); - flags = X509_VERIFY_PARAM_get_flags(param); - return PyLong_FromUnsignedLong(flags); -} - -static int -set_verify_flags(PySSLContext *self, PyObject *arg, void *c) -{ - X509_VERIFY_PARAM *param; - unsigned long new_flags, flags, set, clear; - - if (!PyArg_Parse(arg, "k", &new_flags)) - return -1; - param = SSL_CTX_get0_param(self->ctx); - flags = X509_VERIFY_PARAM_get_flags(param); - clear = flags & ~new_flags; - set = ~flags & new_flags; - if (clear) { - if (!X509_VERIFY_PARAM_clear_flags(param, clear)) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return -1; - } - } - if (set) { - if (!X509_VERIFY_PARAM_set_flags(param, set)) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return -1; - } - } - return 0; -} - -/* Getter and setter for protocol version */ -#if defined(SSL_CTRL_GET_MAX_PROTO_VERSION) - - -static int -set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) -{ - long v; - int result; - - if (!PyArg_Parse(arg, "l", &v)) - return -1; - if (v > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "Option is too long"); - return -1; - } - - switch(self->protocol) { - case PY_SSL_VERSION_TLS_CLIENT: /* fall through */ - case PY_SSL_VERSION_TLS_SERVER: /* fall through */ - case PY_SSL_VERSION_TLS: - break; - default: - PyErr_SetString( - PyExc_ValueError, - "The context's protocol doesn't support modification of " - "highest and lowest version." - ); - return -1; - } - - if (what == 0) { - switch(v) { - case PY_PROTO_MINIMUM_SUPPORTED: - v = 0; - break; - case PY_PROTO_MAXIMUM_SUPPORTED: - /* Emulate max for set_min_proto_version */ - v = PY_PROTO_MAXIMUM_AVAILABLE; - break; - default: - break; - } - result = SSL_CTX_set_min_proto_version(self->ctx, v); - } - else { - switch(v) { - case PY_PROTO_MAXIMUM_SUPPORTED: - v = 0; - break; - case PY_PROTO_MINIMUM_SUPPORTED: - /* Emulate max for set_min_proto_version */ - v = PY_PROTO_MINIMUM_AVAILABLE; - break; - default: - break; - } - result = SSL_CTX_set_max_proto_version(self->ctx, v); - } - if (result == 0) { - PyErr_Format(PyExc_ValueError, - "Unsupported protocol version 0x%x", v); - return -1; - } - return 0; -} - -static PyObject * -get_minimum_version(PySSLContext *self, void *c) -{ - int v = SSL_CTX_ctrl(self->ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL); - if (v == 0) { - v = PY_PROTO_MINIMUM_SUPPORTED; - } - return PyLong_FromLong(v); -} - -static int -set_minimum_version(PySSLContext *self, PyObject *arg, void *c) -{ - return set_min_max_proto_version(self, arg, 0); -} - -static PyObject * -get_maximum_version(PySSLContext *self, void *c) -{ - int v = SSL_CTX_ctrl(self->ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL); - if (v == 0) { - v = PY_PROTO_MAXIMUM_SUPPORTED; - } - return PyLong_FromLong(v); -} - -static int -set_maximum_version(PySSLContext *self, PyObject *arg, void *c) -{ - return set_min_max_proto_version(self, arg, 1); -} -#endif /* SSL_CTRL_GET_MAX_PROTO_VERSION */ - -#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) -static PyObject * -get_num_tickets(PySSLContext *self, void *c) -{ - return PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); -} - -static int -set_num_tickets(PySSLContext *self, PyObject *arg, void *c) -{ - long num; - if (!PyArg_Parse(arg, "l", &num)) - return -1; - if (num < 0) { - PyErr_SetString(PyExc_ValueError, "value must be non-negative"); - return -1; - } - if (self->protocol != PY_SSL_VERSION_TLS_SERVER) { - PyErr_SetString(PyExc_ValueError, - "SSLContext is not a server context."); - return -1; - } - if (SSL_CTX_set_num_tickets(self->ctx, num) != 1) { - PyErr_SetString(PyExc_ValueError, "failed to set num tickets."); - return -1; - } - return 0; -} - -PyDoc_STRVAR(PySSLContext_num_tickets_doc, -"Control the number of TLSv1.3 session tickets"); -#endif /* OpenSSL 1.1.1 */ - -static PyObject * -get_options(PySSLContext *self, void *c) -{ - return PyLong_FromLong(SSL_CTX_get_options(self->ctx)); -} - -static int -set_options(PySSLContext *self, PyObject *arg, void *c) -{ - long new_opts, opts, set, clear; - if (!PyArg_Parse(arg, "l", &new_opts)) - return -1; - opts = SSL_CTX_get_options(self->ctx); - clear = opts & ~new_opts; - set = ~opts & new_opts; - if (clear) { -#ifdef HAVE_SSL_CTX_CLEAR_OPTIONS - SSL_CTX_clear_options(self->ctx, clear); -#else - PyErr_SetString(PyExc_ValueError, - "can't clear options before OpenSSL 0.9.8m"); - return -1; -#endif - } - if (set) - SSL_CTX_set_options(self->ctx, set); - return 0; -} - -static PyObject * -get_host_flags(PySSLContext *self, void *c) -{ - return PyLong_FromUnsignedLong(self->hostflags); -} - -static int -set_host_flags(PySSLContext *self, PyObject *arg, void *c) -{ - X509_VERIFY_PARAM *param; - unsigned int new_flags = 0; - - if (!PyArg_Parse(arg, "I", &new_flags)) - return -1; - - param = SSL_CTX_get0_param(self->ctx); - self->hostflags = new_flags; - X509_VERIFY_PARAM_set_hostflags(param, new_flags); - return 0; -} - -static PyObject * -get_check_hostname(PySSLContext *self, void *c) -{ - return PyBool_FromLong(self->check_hostname); -} - -static int -set_check_hostname(PySSLContext *self, PyObject *arg, void *c) -{ - int check_hostname; - if (!PyArg_Parse(arg, "p", &check_hostname)) - return -1; - if (check_hostname && - SSL_CTX_get_verify_mode(self->ctx) == SSL_VERIFY_NONE) { - /* check_hostname = True sets verify_mode = CERT_REQUIRED */ - if (_set_verify_mode(self, PY_SSL_CERT_REQUIRED) == -1) { - return -1; - } - } - self->check_hostname = check_hostname; - return 0; -} - -static PyObject * -get_post_handshake_auth(PySSLContext *self, void *c) { -#if TLS1_3_VERSION - return PyBool_FromLong(self->post_handshake_auth); -#else - Py_RETURN_NONE; -#endif -} - -#if TLS1_3_VERSION -static int -set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) { - if (arg == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - int pha = PyObject_IsTrue(arg); - - if (pha == -1) { - return -1; - } - self->post_handshake_auth = pha; - - /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for - * server sockets and SSL_set_post_handshake_auth() for client. */ - - return 0; -} -#endif - -static PyObject * -get_protocol(PySSLContext *self, void *c) { - return PyLong_FromLong(self->protocol); -} - -typedef struct { - PyThreadState *thread_state; - PyObject *callable; - char *password; - int size; - int error; -} _PySSLPasswordInfo; - -static int -_pwinfo_set(_PySSLPasswordInfo *pw_info, PyObject* password, - const char *bad_type_error) -{ - /* Set the password and size fields of a _PySSLPasswordInfo struct - from a unicode, bytes, or byte array object. - The password field will be dynamically allocated and must be freed - by the caller */ - PyObject *password_bytes = NULL; - const char *data = NULL; - Py_ssize_t size; - - if (PyUnicode_Check(password)) { - password_bytes = PyUnicode_AsUTF8String(password); - if (!password_bytes) { - goto error; - } - data = PyBytes_AS_STRING(password_bytes); - size = PyBytes_GET_SIZE(password_bytes); - } else if (PyBytes_Check(password)) { - data = PyBytes_AS_STRING(password); - size = PyBytes_GET_SIZE(password); - } else if (PyByteArray_Check(password)) { - data = PyByteArray_AS_STRING(password); - size = PyByteArray_GET_SIZE(password); - } else { - PyErr_SetString(PyExc_TypeError, bad_type_error); - goto error; - } - - if (size > (Py_ssize_t)INT_MAX) { - PyErr_Format(PyExc_ValueError, - "password cannot be longer than %d bytes", INT_MAX); - goto error; - } - - PyMem_Free(pw_info->password); - pw_info->password = PyMem_Malloc(size); - if (!pw_info->password) { - PyErr_SetString(PyExc_MemoryError, - "unable to allocate password buffer"); - goto error; - } - memcpy(pw_info->password, data, size); - pw_info->size = (int)size; - - Py_XDECREF(password_bytes); - return 1; - -error: - Py_XDECREF(password_bytes); - return 0; -} - -static int -_password_callback(char *buf, int size, int rwflag, void *userdata) -{ - _PySSLPasswordInfo *pw_info = (_PySSLPasswordInfo*) userdata; - PyObject *fn_ret = NULL; - - PySSL_END_ALLOW_THREADS_S(pw_info->thread_state); - - if (pw_info->error) { - /* already failed previously. OpenSSL 3.0.0-alpha14 invokes the - * callback multiple times which can lead to fatal Python error in - * exception check. */ - goto error; - } - - if (pw_info->callable) { - fn_ret = _PyObject_CallNoArg(pw_info->callable); - if (!fn_ret) { - /* TODO: It would be nice to move _ctypes_add_traceback() into the - core python API, so we could use it to add a frame here */ - goto error; - } - - if (!_pwinfo_set(pw_info, fn_ret, - "password callback must return a string")) { - goto error; - } - Py_CLEAR(fn_ret); - } - - if (pw_info->size > size) { - PyErr_Format(PyExc_ValueError, - "password cannot be longer than %d bytes", size); - goto error; - } - - PySSL_BEGIN_ALLOW_THREADS_S(pw_info->thread_state); - memcpy(buf, pw_info->password, pw_info->size); - return pw_info->size; - -error: - Py_XDECREF(fn_ret); - PySSL_BEGIN_ALLOW_THREADS_S(pw_info->thread_state); - pw_info->error = 1; - return -1; -} - -/*[clinic input] -_ssl._SSLContext.load_cert_chain - certfile: object - keyfile: object = None - password: object = None - -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, - PyObject *keyfile, PyObject *password) -/*[clinic end generated code: output=9480bc1c380e2095 input=30bc7e967ea01a58]*/ -{ - PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; - pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); - void *orig_passwd_userdata = SSL_CTX_get_default_passwd_cb_userdata(self->ctx); - _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; - int r; - - errno = 0; - ERR_clear_error(); - if (keyfile == Py_None) - keyfile = NULL; - if (!PyUnicode_FSConverter(certfile, &certfile_bytes)) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_SetString(PyExc_TypeError, - "certfile should be a valid filesystem path"); - } - return NULL; - } - if (keyfile && !PyUnicode_FSConverter(keyfile, &keyfile_bytes)) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_SetString(PyExc_TypeError, - "keyfile should be a valid filesystem path"); - } - goto error; - } - if (password != Py_None) { - if (PyCallable_Check(password)) { - pw_info.callable = password; - } else if (!_pwinfo_set(&pw_info, password, - "password should be a string or callable")) { - goto error; - } - SSL_CTX_set_default_passwd_cb(self->ctx, _password_callback); - SSL_CTX_set_default_passwd_cb_userdata(self->ctx, &pw_info); - } - PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); - r = SSL_CTX_use_certificate_chain_file(self->ctx, - PyBytes_AS_STRING(certfile_bytes)); - PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); - if (r != 1) { - if (pw_info.error) { - ERR_clear_error(); - /* the password callback has already set the error information */ - } - else if (errno != 0) { - ERR_clear_error(); - PyErr_SetFromErrno(PyExc_OSError); - } - else { - _setSSLError(NULL, 0, __FILE__, __LINE__); - } - goto error; - } - PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); - r = SSL_CTX_use_PrivateKey_file(self->ctx, - PyBytes_AS_STRING(keyfile ? keyfile_bytes : certfile_bytes), - SSL_FILETYPE_PEM); - PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); - Py_CLEAR(keyfile_bytes); - Py_CLEAR(certfile_bytes); - if (r != 1) { - if (pw_info.error) { - ERR_clear_error(); - /* the password callback has already set the error information */ - } - else if (errno != 0) { - ERR_clear_error(); - PyErr_SetFromErrno(PyExc_OSError); - } - else { - _setSSLError(NULL, 0, __FILE__, __LINE__); - } - goto error; - } - PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); - r = SSL_CTX_check_private_key(self->ctx); - PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); - if (r != 1) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto error; - } - SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); - SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); - PyMem_Free(pw_info.password); - Py_RETURN_NONE; - -error: - SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); - SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); - PyMem_Free(pw_info.password); - Py_XDECREF(keyfile_bytes); - Py_XDECREF(certfile_bytes); - return NULL; -} - -/* internal helper function, returns -1 on error - */ -static int -_add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, - int filetype) -{ - BIO *biobuf = NULL; - X509_STORE *store; - int retval = -1, err, loaded = 0; - - assert(filetype == SSL_FILETYPE_ASN1 || filetype == SSL_FILETYPE_PEM); - - if (len <= 0) { - PyErr_SetString(PyExc_ValueError, - "Empty certificate data"); - return -1; - } else if (len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "Certificate data is too long."); - return -1; - } - - biobuf = BIO_new_mem_buf(data, (int)len); - if (biobuf == NULL) { - _setSSLError("Can't allocate buffer", 0, __FILE__, __LINE__); - return -1; - } - - store = SSL_CTX_get_cert_store(self->ctx); - assert(store != NULL); - - while (1) { - X509 *cert = NULL; - int r; - - if (filetype == SSL_FILETYPE_ASN1) { - cert = d2i_X509_bio(biobuf, NULL); - } else { - cert = PEM_read_bio_X509(biobuf, NULL, - SSL_CTX_get_default_passwd_cb(self->ctx), - SSL_CTX_get_default_passwd_cb_userdata(self->ctx) - ); - } - if (cert == NULL) { - break; - } - r = X509_STORE_add_cert(store, cert); - X509_free(cert); - if (!r) { - err = ERR_peek_last_error(); - if ((ERR_GET_LIB(err) == ERR_LIB_X509) && - (ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) { - /* cert already in hash table, not an error */ - ERR_clear_error(); - } else { - break; - } - } - loaded++; - } - - err = ERR_peek_last_error(); - if (loaded == 0) { - const char *msg = NULL; - if (filetype == SSL_FILETYPE_PEM) { - msg = "no start line: cadata does not contain a certificate"; - } else { - msg = "not enough data: cadata does not contain a certificate"; - } - _setSSLError(msg, 0, __FILE__, __LINE__); - retval = -1; - } else if ((filetype == SSL_FILETYPE_ASN1) && - (ERR_GET_LIB(err) == ERR_LIB_ASN1) && - (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG)) { - /* EOF ASN1 file, not an error */ - ERR_clear_error(); - retval = 0; - } else if ((filetype == SSL_FILETYPE_PEM) && - (ERR_GET_LIB(err) == ERR_LIB_PEM) && - (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { - /* EOF PEM file, not an error */ - ERR_clear_error(); - retval = 0; - } else if (err != 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - retval = -1; - } else { - retval = 0; - } - - BIO_free(biobuf); - return retval; -} - - -/*[clinic input] -_ssl._SSLContext.load_verify_locations - cafile: object = None - capath: object = None - cadata: object = None - -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, - PyObject *cafile, - PyObject *capath, - PyObject *cadata) -/*[clinic end generated code: output=454c7e41230ca551 input=42ecfe258233e194]*/ -{ - PyObject *cafile_bytes = NULL, *capath_bytes = NULL; - const char *cafile_buf = NULL, *capath_buf = NULL; - int r = 0, ok = 1; - - errno = 0; - if (cafile == Py_None) - cafile = NULL; - if (capath == Py_None) - capath = NULL; - if (cadata == Py_None) - cadata = NULL; - - if (cafile == NULL && capath == NULL && cadata == NULL) { - PyErr_SetString(PyExc_TypeError, - "cafile, capath and cadata cannot be all omitted"); - goto error; - } - if (cafile && !PyUnicode_FSConverter(cafile, &cafile_bytes)) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_SetString(PyExc_TypeError, - "cafile should be a valid filesystem path"); - } - goto error; - } - if (capath && !PyUnicode_FSConverter(capath, &capath_bytes)) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_SetString(PyExc_TypeError, - "capath should be a valid filesystem path"); - } - goto error; - } - - /* validate cadata type and load cadata */ - if (cadata) { - if (PyUnicode_Check(cadata)) { - PyObject *cadata_ascii = PyUnicode_AsASCIIString(cadata); - if (cadata_ascii == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { - goto invalid_cadata; - } - goto error; - } - r = _add_ca_certs(self, - PyBytes_AS_STRING(cadata_ascii), - PyBytes_GET_SIZE(cadata_ascii), - SSL_FILETYPE_PEM); - Py_DECREF(cadata_ascii); - if (r == -1) { - goto error; - } - } - else if (PyObject_CheckBuffer(cadata)) { - Py_buffer buf; - if (PyObject_GetBuffer(cadata, &buf, PyBUF_SIMPLE)) { - goto error; - } - if (!PyBuffer_IsContiguous(&buf, 'C') || buf.ndim > 1) { - PyBuffer_Release(&buf); - PyErr_SetString(PyExc_TypeError, - "cadata should be a contiguous buffer with " - "a single dimension"); - goto error; - } - r = _add_ca_certs(self, buf.buf, buf.len, SSL_FILETYPE_ASN1); - PyBuffer_Release(&buf); - if (r == -1) { - goto error; - } - } - else { - invalid_cadata: - PyErr_SetString(PyExc_TypeError, - "cadata should be an ASCII string or a " - "bytes-like object"); - goto error; - } - } - - /* load cafile or capath */ - if (cafile || capath) { - if (cafile) - cafile_buf = PyBytes_AS_STRING(cafile_bytes); - if (capath) - capath_buf = PyBytes_AS_STRING(capath_bytes); - PySSL_BEGIN_ALLOW_THREADS - r = SSL_CTX_load_verify_locations(self->ctx, cafile_buf, capath_buf); - PySSL_END_ALLOW_THREADS - if (r != 1) { - if (errno != 0) { - ERR_clear_error(); - PyErr_SetFromErrno(PyExc_OSError); - } - else { - _setSSLError(NULL, 0, __FILE__, __LINE__); - } - goto error; - } - } - goto end; - - error: - ok = 0; - end: - Py_XDECREF(cafile_bytes); - Py_XDECREF(capath_bytes); - if (ok) { - Py_RETURN_NONE; - } else { - return NULL; - } -} - -/*[clinic input] -_ssl._SSLContext.load_dh_params - path as filepath: object - / - -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) -/*[clinic end generated code: output=1c8e57a38e055af0 input=c8871f3c796ae1d6]*/ -{ - FILE *f; - DH *dh; - - f = _Py_fopen_obj(filepath, "rb"); - if (f == NULL) - return NULL; - - errno = 0; - PySSL_BEGIN_ALLOW_THREADS - dh = PEM_read_DHparams(f, NULL, NULL, NULL); - fclose(f); - PySSL_END_ALLOW_THREADS - if (dh == NULL) { - if (errno != 0) { - ERR_clear_error(); - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, filepath); - } - else { - _setSSLError(NULL, 0, __FILE__, __LINE__); - } - return NULL; - } - if (!SSL_CTX_set_tmp_dh(self->ctx, dh)) { - DH_free(dh); - return _setSSLError(NULL, 0, __FILE__, __LINE__); - } - DH_free(dh); - Py_RETURN_NONE; -} - -/*[clinic input] -_ssl._SSLContext._wrap_socket - sock: object(subclass_of="PySocketModule.Sock_Type") - server_side: int - server_hostname as hostname_obj: object = None - * - owner: object = None - session: object = None - -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, - int server_side, PyObject *hostname_obj, - PyObject *owner, PyObject *session) -/*[clinic end generated code: output=f103f238633940b4 input=957d5006183d1894]*/ -{ - char *hostname = NULL; - PyObject *res; - - /* server_hostname is either None (or absent), or to be encoded - as IDN A-label (ASCII str) without NULL bytes. */ - if (hostname_obj != Py_None) { - if (!PyArg_Parse(hostname_obj, "es", "ascii", &hostname)) - return NULL; - } - - res = (PyObject *) newPySSLSocket(self, (PySocketSockObject *)sock, - server_side, hostname, - owner, session, - NULL, NULL); - if (hostname != NULL) - PyMem_Free(hostname); - return res; -} - -/*[clinic input] -_ssl._SSLContext._wrap_bio - incoming: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") - outgoing: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") - server_side: int - server_hostname as hostname_obj: object = None - * - owner: object = None - session: object = None - -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, - PySSLMemoryBIO *outgoing, int server_side, - PyObject *hostname_obj, PyObject *owner, - PyObject *session) -/*[clinic end generated code: output=5c5d6d9b41f99332 input=8cf22f4d586ac56a]*/ -{ - char *hostname = NULL; - PyObject *res; - - /* server_hostname is either None (or absent), or to be encoded - as IDN A-label (ASCII str) without NULL bytes. */ - if (hostname_obj != Py_None) { - if (!PyArg_Parse(hostname_obj, "es", "ascii", &hostname)) - return NULL; - } - - res = (PyObject *) newPySSLSocket(self, NULL, server_side, hostname, - owner, session, - incoming, outgoing); - - PyMem_Free(hostname); - return res; -} - -/*[clinic input] -_ssl._SSLContext.session_stats -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_session_stats_impl(PySSLContext *self) -/*[clinic end generated code: output=0d96411c42893bfb input=7e0a81fb11102c8b]*/ -{ - int r; - PyObject *value, *stats = PyDict_New(); - if (!stats) - return NULL; - -#define ADD_STATS(SSL_NAME, KEY_NAME) \ - value = PyLong_FromLong(SSL_CTX_sess_ ## SSL_NAME (self->ctx)); \ - if (value == NULL) \ - goto error; \ - r = PyDict_SetItemString(stats, KEY_NAME, value); \ - Py_DECREF(value); \ - if (r < 0) \ - goto error; - - ADD_STATS(number, "number"); - ADD_STATS(connect, "connect"); - ADD_STATS(connect_good, "connect_good"); - ADD_STATS(connect_renegotiate, "connect_renegotiate"); - ADD_STATS(accept, "accept"); - ADD_STATS(accept_good, "accept_good"); - ADD_STATS(accept_renegotiate, "accept_renegotiate"); - ADD_STATS(accept, "accept"); - ADD_STATS(hits, "hits"); - ADD_STATS(misses, "misses"); - ADD_STATS(timeouts, "timeouts"); - ADD_STATS(cache_full, "cache_full"); - -#undef ADD_STATS - - return stats; - -error: - Py_DECREF(stats); - return NULL; -} - -/*[clinic input] -_ssl._SSLContext.set_default_verify_paths -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) -/*[clinic end generated code: output=0bee74e6e09deaaa input=35f3408021463d74]*/ -{ - if (!SSL_CTX_set_default_verify_paths(self->ctx)) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - Py_RETURN_NONE; -} - -#ifndef OPENSSL_NO_ECDH -/*[clinic input] -_ssl._SSLContext.set_ecdh_curve - name: object - / - -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) -/*[clinic end generated code: output=23022c196e40d7d2 input=c2bafb6f6e34726b]*/ -{ - PyObject *name_bytes; - int nid; - EC_KEY *key; - - if (!PyUnicode_FSConverter(name, &name_bytes)) - return NULL; - assert(PyBytes_Check(name_bytes)); - nid = OBJ_sn2nid(PyBytes_AS_STRING(name_bytes)); - Py_DECREF(name_bytes); - if (nid == 0) { - PyErr_Format(PyExc_ValueError, - "unknown elliptic curve name %R", name); - return NULL; - } - key = EC_KEY_new_by_curve_name(nid); - if (key == NULL) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - SSL_CTX_set_tmp_ecdh(self->ctx, key); - EC_KEY_free(key); - Py_RETURN_NONE; -} -#endif - -#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) -static int -_servername_callback(SSL *s, int *al, void *args) -{ - int ret; - PySSLContext *ssl_ctx = (PySSLContext *) args; - PySSLSocket *ssl; - PyObject *result; - /* The high-level ssl.SSLSocket object */ - PyObject *ssl_socket; - const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); - PyGILState_STATE gstate = PyGILState_Ensure(); - - if (ssl_ctx->set_sni_cb == NULL) { - /* remove race condition in this the call back while if removing the - * callback is in progress */ - PyGILState_Release(gstate); - return SSL_TLSEXT_ERR_OK; - } - - ssl = SSL_get_app_data(s); - assert(PySSLSocket_Check(ssl)); - - /* The servername callback expects an argument that represents the current - * SSL connection and that has a .context attribute that can be changed to - * identify the requested hostname. Since the official API is the Python - * level API we want to pass the callback a Python level object rather than - * a _ssl.SSLSocket instance. If there's an "owner" (typically an - * SSLObject) that will be passed. Otherwise if there's a socket then that - * will be passed. If both do not exist only then the C-level object is - * passed. */ - if (ssl->owner) - ssl_socket = PyWeakref_GetObject(ssl->owner); - else if (ssl->Socket) - ssl_socket = PyWeakref_GetObject(ssl->Socket); - else - ssl_socket = (PyObject *) ssl; - - Py_INCREF(ssl_socket); - if (ssl_socket == Py_None) - goto error; - - if (servername == NULL) { - result = PyObject_CallFunctionObjArgs(ssl_ctx->set_sni_cb, ssl_socket, - Py_None, ssl_ctx, NULL); - } - else { - PyObject *servername_bytes; - PyObject *servername_str; - - servername_bytes = PyBytes_FromString(servername); - if (servername_bytes == NULL) { - PyErr_WriteUnraisable((PyObject *) ssl_ctx); - goto error; - } - /* server_hostname was encoded to an A-label by our caller; put it - * back into a str object, but still as an A-label (bpo-28414) - */ - servername_str = PyUnicode_FromEncodedObject(servername_bytes, "ascii", NULL); - if (servername_str == NULL) { - PyErr_WriteUnraisable(servername_bytes); - Py_DECREF(servername_bytes); - goto error; - } - Py_DECREF(servername_bytes); - result = PyObject_CallFunctionObjArgs( - ssl_ctx->set_sni_cb, ssl_socket, servername_str, - ssl_ctx, NULL); - Py_DECREF(servername_str); - } - Py_DECREF(ssl_socket); - - if (result == NULL) { - PyErr_WriteUnraisable(ssl_ctx->set_sni_cb); - *al = SSL_AD_HANDSHAKE_FAILURE; - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - } - else { - /* Result may be None, a SSLContext or an integer - * None and SSLContext are OK, integer or other values are an error. - */ - if (result == Py_None) { - ret = SSL_TLSEXT_ERR_OK; - } else { - *al = (int) PyLong_AsLong(result); - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(result); - *al = SSL_AD_INTERNAL_ERROR; - } - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - } - Py_DECREF(result); - } - - PyGILState_Release(gstate); - return ret; - -error: - Py_DECREF(ssl_socket); - *al = SSL_AD_INTERNAL_ERROR; - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - PyGILState_Release(gstate); - return ret; -} -#endif - -static PyObject * -get_sni_callback(PySSLContext *self, void *c) -{ - PyObject *cb = self->set_sni_cb; - if (cb == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(cb); - return cb; -} - -static int -set_sni_callback(PySSLContext *self, PyObject *arg, void *c) -{ - if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) { - PyErr_SetString(PyExc_ValueError, - "sni_callback cannot be set on TLS_CLIENT context"); - return -1; - } -#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) - Py_CLEAR(self->set_sni_cb); - if (arg == Py_None) { - SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); - } - else { - if (!PyCallable_Check(arg)) { - SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); - PyErr_SetString(PyExc_TypeError, - "not a callable object"); - return -1; - } - Py_INCREF(arg); - self->set_sni_cb = arg; - SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); - SSL_CTX_set_tlsext_servername_arg(self->ctx, self); - } - return 0; -#else - PyErr_SetString(PyExc_NotImplementedError, - "The TLS extension servername callback, " - "SSL_CTX_set_tlsext_servername_callback, " - "is not in the current OpenSSL library."); - return -1; -#endif -} - -PyDoc_STRVAR(PySSLContext_sni_callback_doc, -"Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.\n\ -\n\ -If the argument is None then the callback is disabled. The method is called\n\ -with the SSLSocket, the server name as a string, and the SSLContext object.\n\ -See RFC 6066 for details of the SNI extension."); - -/*[clinic input] -_ssl._SSLContext.cert_store_stats - -Returns quantities of loaded X.509 certificates. - -X.509 certificates with a CA extension and certificate revocation lists -inside the context's cert store. - -NOTE: Certificates in a capath directory aren't loaded unless they have -been used at least once. -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) -/*[clinic end generated code: output=5f356f4d9cca874d input=eb40dd0f6d0e40cf]*/ -{ - X509_STORE *store; - STACK_OF(X509_OBJECT) *objs; - X509_OBJECT *obj; - int x509 = 0, crl = 0, ca = 0, i; - - store = SSL_CTX_get_cert_store(self->ctx); - objs = X509_STORE_get0_objects(store); - for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { - obj = sk_X509_OBJECT_value(objs, i); - switch (X509_OBJECT_get_type(obj)) { - case X509_LU_X509: - x509++; - if (X509_check_ca(X509_OBJECT_get0_X509(obj))) { - ca++; - } - break; - case X509_LU_CRL: - crl++; - break; - default: - /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY. - * As far as I can tell they are internal states and never - * stored in a cert store */ - break; - } - } - return Py_BuildValue("{sisisi}", "x509", x509, "crl", crl, - "x509_ca", ca); -} - -/*[clinic input] -_ssl._SSLContext.get_ca_certs - binary_form: bool = False - -Returns a list of dicts with information of loaded CA certs. - -If the optional argument is True, returns a DER-encoded copy of the CA -certificate. - -NOTE: Certificates in a capath directory aren't loaded unless they have -been used at least once. -[clinic start generated code]*/ - -static PyObject * -_ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) -/*[clinic end generated code: output=0d58f148f37e2938 input=6887b5a09b7f9076]*/ -{ - X509_STORE *store; - STACK_OF(X509_OBJECT) *objs; - PyObject *ci = NULL, *rlist = NULL; - int i; - - if ((rlist = PyList_New(0)) == NULL) { - return NULL; - } - - store = SSL_CTX_get_cert_store(self->ctx); - objs = X509_STORE_get0_objects(store); - for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { - X509_OBJECT *obj; - X509 *cert; - - obj = sk_X509_OBJECT_value(objs, i); - if (X509_OBJECT_get_type(obj) != X509_LU_X509) { - /* not a x509 cert */ - continue; - } - /* CA for any purpose */ - cert = X509_OBJECT_get0_X509(obj); - if (!X509_check_ca(cert)) { - continue; - } - if (binary_form) { - ci = _certificate_to_der(cert); - } else { - ci = _decode_certificate(cert); - } - if (ci == NULL) { - goto error; - } - if (PyList_Append(rlist, ci) == -1) { - goto error; - } - Py_CLEAR(ci); - } - return rlist; - - error: - Py_XDECREF(ci); - Py_XDECREF(rlist); - return NULL; -} - - -static PyGetSetDef context_getsetlist[] = { - {"check_hostname", (getter) get_check_hostname, - (setter) set_check_hostname, NULL}, - {"_host_flags", (getter) get_host_flags, - (setter) set_host_flags, NULL}, -#if SSL_CTRL_GET_MAX_PROTO_VERSION - {"minimum_version", (getter) get_minimum_version, - (setter) set_minimum_version, NULL}, - {"maximum_version", (getter) get_maximum_version, - (setter) set_maximum_version, NULL}, -#endif -#ifdef HAVE_OPENSSL_KEYLOG - {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, - (setter) _PySSLContext_set_keylog_filename, NULL}, -#endif - {"_msg_callback", (getter) _PySSLContext_get_msg_callback, - (setter) _PySSLContext_set_msg_callback, NULL}, - {"sni_callback", (getter) get_sni_callback, - (setter) set_sni_callback, PySSLContext_sni_callback_doc}, -#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) - {"num_tickets", (getter) get_num_tickets, - (setter) set_num_tickets, PySSLContext_num_tickets_doc}, -#endif - {"options", (getter) get_options, - (setter) set_options, NULL}, - {"post_handshake_auth", (getter) get_post_handshake_auth, -#ifdef TLS1_3_VERSION - (setter) set_post_handshake_auth, -#else - NULL, -#endif - NULL}, - {"protocol", (getter) get_protocol, - NULL, NULL}, - {"verify_flags", (getter) get_verify_flags, - (setter) set_verify_flags, NULL}, - {"verify_mode", (getter) get_verify_mode, - (setter) set_verify_mode, NULL}, - {NULL}, /* sentinel */ -}; - -static struct PyMethodDef context_methods[] = { - _SSL__SSLCONTEXT__WRAP_SOCKET_METHODDEF - _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF - _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF - _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF - _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF - _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF - _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF - _SSL__SSLCONTEXT_LOAD_VERIFY_LOCATIONS_METHODDEF - _SSL__SSLCONTEXT_SESSION_STATS_METHODDEF - _SSL__SSLCONTEXT_SET_DEFAULT_VERIFY_PATHS_METHODDEF - _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF - _SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF - _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF - _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject PySSLContext_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl._SSLContext", /*tp_name*/ - sizeof(PySSLContext), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)context_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc) context_traverse, /*tp_traverse*/ - (inquiry) context_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - context_methods, /*tp_methods*/ - 0, /*tp_members*/ - context_getsetlist, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - _ssl__SSLContext, /*tp_new*/ -}; - - -/* - * MemoryBIO objects - */ - -/*[clinic input] -@classmethod -_ssl.MemoryBIO.__new__ - -[clinic start generated code]*/ - -static PyObject * -_ssl_MemoryBIO_impl(PyTypeObject *type) -/*[clinic end generated code: output=8820a58db78330ac input=26d22e4909ecb1b5]*/ -{ - BIO *bio; - PySSLMemoryBIO *self; - - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) { - PyErr_SetString(PySSLErrorObject, - "failed to allocate BIO"); - return NULL; - } - /* Since our BIO is non-blocking an empty read() does not indicate EOF, - * just that no data is currently available. The SSL routines should retry - * the read, which we can achieve by calling BIO_set_retry_read(). */ - BIO_set_retry_read(bio); - BIO_set_mem_eof_return(bio, -1); - - assert(type != NULL && type->tp_alloc != NULL); - self = (PySSLMemoryBIO *) type->tp_alloc(type, 0); - if (self == NULL) { - BIO_free(bio); - return NULL; - } - self->bio = bio; - self->eof_written = 0; - - return (PyObject *) self; -} - -static void -memory_bio_dealloc(PySSLMemoryBIO *self) -{ - BIO_free(self->bio); - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -memory_bio_get_pending(PySSLMemoryBIO *self, void *c) -{ - return PyLong_FromSize_t(BIO_ctrl_pending(self->bio)); -} - -PyDoc_STRVAR(PySSL_memory_bio_pending_doc, -"The number of bytes pending in the memory BIO."); - -static PyObject * -memory_bio_get_eof(PySSLMemoryBIO *self, void *c) -{ - return PyBool_FromLong((BIO_ctrl_pending(self->bio) == 0) - && self->eof_written); -} - -PyDoc_STRVAR(PySSL_memory_bio_eof_doc, -"Whether the memory BIO is at EOF."); - -/*[clinic input] -_ssl.MemoryBIO.read - size as len: int = -1 - / - -Read up to size bytes from the memory BIO. - -If size is not specified, read the entire buffer. -If the return value is an empty bytes instance, this means either -EOF or that no data is available. Use the "eof" property to -distinguish between the two. -[clinic start generated code]*/ - -static PyObject * -_ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) -/*[clinic end generated code: output=a657aa1e79cd01b3 input=574d7be06a902366]*/ -{ - int avail, nbytes; - PyObject *result; - - avail = (int)Py_MIN(BIO_ctrl_pending(self->bio), INT_MAX); - if ((len < 0) || (len > avail)) - len = avail; - - result = PyBytes_FromStringAndSize(NULL, len); - if ((result == NULL) || (len == 0)) - return result; - - nbytes = BIO_read(self->bio, PyBytes_AS_STRING(result), len); - if (nbytes < 0) { - Py_DECREF(result); - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - - /* There should never be any short reads but check anyway. */ - if (nbytes < len) { - _PyBytes_Resize(&result, nbytes); - } - - return result; -} - -/*[clinic input] -_ssl.MemoryBIO.write - b: Py_buffer - / - -Writes the bytes b into the memory BIO. - -Returns the number of bytes written. -[clinic start generated code]*/ - -static PyObject * -_ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) -/*[clinic end generated code: output=156ec59110d75935 input=e45757b3e17c4808]*/ -{ - int nbytes; - - if (b->len > INT_MAX) { - PyErr_Format(PyExc_OverflowError, - "string longer than %d bytes", INT_MAX); - return NULL; - } - - if (self->eof_written) { - PyErr_SetString(PySSLErrorObject, - "cannot write() after write_eof()"); - return NULL; - } - - nbytes = BIO_write(self->bio, b->buf, (int)b->len); - if (nbytes < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - return NULL; - } - - return PyLong_FromLong(nbytes); -} - -/*[clinic input] -_ssl.MemoryBIO.write_eof - -Write an EOF marker to the memory BIO. - -When all data has been read, the "eof" property will be True. -[clinic start generated code]*/ - -static PyObject * -_ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) -/*[clinic end generated code: output=d4106276ccd1ed34 input=56a945f1d29e8bd6]*/ -{ - self->eof_written = 1; - /* After an EOF is written, a zero return from read() should be a real EOF - * i.e. it should not be retried. Clear the SHOULD_RETRY flag. */ - BIO_clear_retry_flags(self->bio); - BIO_set_mem_eof_return(self->bio, 0); - - Py_RETURN_NONE; -} - -static PyGetSetDef memory_bio_getsetlist[] = { - {"pending", (getter) memory_bio_get_pending, NULL, - PySSL_memory_bio_pending_doc}, - {"eof", (getter) memory_bio_get_eof, NULL, - PySSL_memory_bio_eof_doc}, - {NULL}, /* sentinel */ -}; - -static struct PyMethodDef memory_bio_methods[] = { - _SSL_MEMORYBIO_READ_METHODDEF - _SSL_MEMORYBIO_WRITE_METHODDEF - _SSL_MEMORYBIO_WRITE_EOF_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject PySSLMemoryBIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl.MemoryBIO", /*tp_name*/ - sizeof(PySSLMemoryBIO), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)memory_bio_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - memory_bio_methods, /*tp_methods*/ - 0, /*tp_members*/ - memory_bio_getsetlist, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - _ssl_MemoryBIO, /*tp_new*/ -}; - - -/* - * SSL Session object - */ - -static void -PySSLSession_dealloc(PySSLSession *self) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ - PyObject_GC_UnTrack(self); - Py_XDECREF(self->ctx); - if (self->session != NULL) { - SSL_SESSION_free(self->session); - } - PyObject_GC_Del(self); -} - -static PyObject * -PySSLSession_richcompare(PyObject *left, PyObject *right, int op) -{ - int result; - - if (left == NULL || right == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - - if (!PySSLSession_Check(left) || !PySSLSession_Check(right)) { - Py_RETURN_NOTIMPLEMENTED; - } - - if (left == right) { - result = 0; - } else { - const unsigned char *left_id, *right_id; - unsigned int left_len, right_len; - left_id = SSL_SESSION_get_id(((PySSLSession *)left)->session, - &left_len); - right_id = SSL_SESSION_get_id(((PySSLSession *)right)->session, - &right_len); - if (left_len == right_len) { - result = memcmp(left_id, right_id, left_len); - } else { - result = 1; - } - } - - switch (op) { - case Py_EQ: - if (result == 0) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } - break; - case Py_NE: - if (result != 0) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } - break; - case Py_LT: - case Py_LE: - case Py_GT: - case Py_GE: - Py_RETURN_NOTIMPLEMENTED; - break; - default: - PyErr_BadArgument(); - return NULL; - } -} - -static int -PySSLSession_traverse(PySSLSession *self, visitproc visit, void *arg) -{ - Py_VISIT(self->ctx); - return 0; -} - -static int -PySSLSession_clear(PySSLSession *self) -{ - Py_CLEAR(self->ctx); - return 0; -} - - -static PyObject * -PySSLSession_get_time(PySSLSession *self, void *closure) { - return PyLong_FromLong(SSL_SESSION_get_time(self->session)); -} - -PyDoc_STRVAR(PySSLSession_get_time_doc, -"Session creation time (seconds since epoch)."); - - -static PyObject * -PySSLSession_get_timeout(PySSLSession *self, void *closure) { - return PyLong_FromLong(SSL_SESSION_get_timeout(self->session)); -} - -PyDoc_STRVAR(PySSLSession_get_timeout_doc, -"Session timeout (delta in seconds)."); - - -static PyObject * -PySSLSession_get_ticket_lifetime_hint(PySSLSession *self, void *closure) { - unsigned long hint = SSL_SESSION_get_ticket_lifetime_hint(self->session); - return PyLong_FromUnsignedLong(hint); -} - -PyDoc_STRVAR(PySSLSession_get_ticket_lifetime_hint_doc, -"Ticket life time hint."); - - -static PyObject * -PySSLSession_get_session_id(PySSLSession *self, void *closure) { - const unsigned char *id; - unsigned int len; - id = SSL_SESSION_get_id(self->session, &len); - return PyBytes_FromStringAndSize((const char *)id, len); -} - -PyDoc_STRVAR(PySSLSession_get_session_id_doc, -"Session id"); - - -static PyObject * -PySSLSession_get_has_ticket(PySSLSession *self, void *closure) { - if (SSL_SESSION_has_ticket(self->session)) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } -} - -PyDoc_STRVAR(PySSLSession_get_has_ticket_doc, -"Does the session contain a ticket?"); - - -static PyGetSetDef PySSLSession_getsetlist[] = { - {"has_ticket", (getter) PySSLSession_get_has_ticket, NULL, - PySSLSession_get_has_ticket_doc}, - {"id", (getter) PySSLSession_get_session_id, NULL, - PySSLSession_get_session_id_doc}, - {"ticket_lifetime_hint", (getter) PySSLSession_get_ticket_lifetime_hint, - NULL, PySSLSession_get_ticket_lifetime_hint_doc}, - {"time", (getter) PySSLSession_get_time, NULL, - PySSLSession_get_time_doc}, - {"timeout", (getter) PySSLSession_get_timeout, NULL, - PySSLSession_get_timeout_doc}, - {NULL}, /* sentinel */ -}; - -static PyTypeObject PySSLSession_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl.Session", /*tp_name*/ - sizeof(PySSLSession), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)PySSLSession_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc)PySSLSession_traverse, /*tp_traverse*/ - (inquiry)PySSLSession_clear, /*tp_clear*/ - PySSLSession_richcompare, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - PySSLSession_getsetlist, /*tp_getset*/ -}; - - -/* helper routines for seeding the SSL PRNG */ -/*[clinic input] -_ssl.RAND_add - string as view: Py_buffer(accept={str, buffer}) - entropy: double - / - -Mix string into the OpenSSL PRNG state. - -entropy (a float) is a lower bound on the entropy contained in -string. See RFC 4086. -[clinic start generated code]*/ - -static PyObject * -_ssl_RAND_add_impl(PyObject *module, Py_buffer *view, double entropy) -/*[clinic end generated code: output=e6dd48df9c9024e9 input=5c33017422828f5c]*/ -{ - const char *buf; - Py_ssize_t len, written; - - buf = (const char *)view->buf; - len = view->len; - do { - written = Py_MIN(len, INT_MAX); - RAND_add(buf, (int)written, entropy); - buf += written; - len -= written; - } while (len); - Py_RETURN_NONE; -} - -static PyObject * -PySSL_RAND(int len, int pseudo) +static void +PySSL_dealloc(PySSLSocket *self) { - int ok; - PyObject *bytes; - unsigned long err; - const char *errstr; - PyObject *v; - - if (len < 0) { - PyErr_SetString(PyExc_ValueError, "num must be positive"); + if (self->ssl) + SSL_free(self->ssl); + Py_XDECREF(self->Socket); + Py_XDECREF(self->ctx); + Py_XDECREF(self->server_hostname); + Py_XDECREF(self->owner); + PyObject_Del(self); +} + +/* If the socket has a timeout, do a select()/poll() on the socket. + The argument writing indicates the direction. + Returns one of the possibilities in the timeout_state enum (above). + */ + +static int +PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout) +{ + int rc; +#ifdef HAVE_POLL + struct pollfd pollfd; + _PyTime_t ms; +#else + int nfds; + fd_set fds; + struct timeval tv; +#endif + + /* Nothing to do unless we're in timeout mode (not non-blocking) */ + if ((s == NULL) || (timeout == 0)) + return SOCKET_IS_NONBLOCKING; + else if (timeout < 0) { + if (s->sock_timeout > 0) + return SOCKET_HAS_TIMED_OUT; + else + return SOCKET_IS_BLOCKING; + } + + /* Guard against closed socket */ + if (s->sock_fd == INVALID_SOCKET) + return SOCKET_HAS_BEEN_CLOSED; + + /* Prefer poll, if available, since you can poll() any fd + * which can't be done with select(). */ +#ifdef HAVE_POLL + pollfd.fd = s->sock_fd; + pollfd.events = writing ? POLLOUT : POLLIN; + + /* timeout is in seconds, poll() uses milliseconds */ + ms = (int)_PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); + assert(ms <= INT_MAX); + + PySSL_BEGIN_ALLOW_THREADS + rc = poll(&pollfd, 1, (int)ms); + PySSL_END_ALLOW_THREADS +#else + /* Guard against socket too large for select*/ + if (!_PyIsSelectable_fd(s->sock_fd)) + return SOCKET_TOO_LARGE_FOR_SELECT; + + _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING); + + FD_ZERO(&fds); + FD_SET(s->sock_fd, &fds); + + /* Wait until the socket becomes ready */ + PySSL_BEGIN_ALLOW_THREADS + nfds = Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int); + if (writing) + rc = select(nfds, NULL, &fds, NULL, &tv); + else + rc = select(nfds, &fds, NULL, NULL, &tv); + PySSL_END_ALLOW_THREADS +#endif + + /* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise + (when we are able to write or when there's something to read) */ + return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK; +} + +/*[clinic input] +_ssl._SSLSocket.write + b: Py_buffer + / + +Writes the bytes-like object b into the SSL object. + +Returns the number of bytes written. +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) +/*[clinic end generated code: output=aa7a6be5527358d8 input=77262d994fe5100a]*/ +{ + int len; + int sockstate; + _PySSLError err; + int nonblocking; + PySocketSockObject *sock = GET_SOCKET(self); + _PyTime_t timeout, deadline = 0; + int has_timeout; + + if (sock != NULL) { + if (((PyObject*)sock) == Py_None) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); + } + + if (b->len > INT_MAX) { + PyErr_Format(PyExc_OverflowError, + "string longer than %d bytes", INT_MAX); + goto error; + } + + if (sock != NULL) { + /* just in case the blocking state of the socket has been changed */ + nonblocking = (sock->sock_timeout >= 0); + BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); + BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + } + + timeout = GET_SOCKET_TIMEOUT(sock); + has_timeout = (timeout > 0); + if (has_timeout) + deadline = _PyTime_GetMonotonicClock() + timeout; + + sockstate = PySSL_select(sock, 1, timeout); + if (sockstate == SOCKET_HAS_TIMED_OUT) { + PyErr_SetString(PySocketModule.timeout_error, + "The write operation timed out"); + goto error; + } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { + PyErr_SetString(PySSLErrorObject, + "Underlying socket has been closed."); + goto error; + } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { + PyErr_SetString(PySSLErrorObject, + "Underlying socket too large for select()."); + goto error; + } + + do { + PySSL_BEGIN_ALLOW_THREADS + len = SSL_write(self->ssl, b->buf, (int)b->len); + err = _PySSL_errno(len <= 0, self->ssl, len); + PySSL_END_ALLOW_THREADS + self->err = err; + + if (PyErr_CheckSignals()) + goto error; + + if (has_timeout) + timeout = deadline - _PyTime_GetMonotonicClock(); + + if (err.ssl == SSL_ERROR_WANT_READ) { + sockstate = PySSL_select(sock, 0, timeout); + } else if (err.ssl == SSL_ERROR_WANT_WRITE) { + sockstate = PySSL_select(sock, 1, timeout); + } else { + sockstate = SOCKET_OPERATION_OK; + } + + if (sockstate == SOCKET_HAS_TIMED_OUT) { + PyErr_SetString(PySocketModule.timeout_error, + "The write operation timed out"); + goto error; + } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { + PyErr_SetString(PySSLErrorObject, + "Underlying socket has been closed."); + goto error; + } else if (sockstate == SOCKET_IS_NONBLOCKING) { + break; + } + } while (err.ssl == SSL_ERROR_WANT_READ || + err.ssl == SSL_ERROR_WANT_WRITE); + + Py_XDECREF(sock); + if (len <= 0) + return PySSL_SetError(self, len, __FILE__, __LINE__); + if (PySSL_ChainExceptions(self) < 0) return NULL; - } - - bytes = PyBytes_FromStringAndSize(NULL, len); - if (bytes == NULL) + return PyLong_FromLong(len); +error: + Py_XDECREF(sock); + PySSL_ChainExceptions(self); + return NULL; +} + +/*[clinic input] +_ssl._SSLSocket.pending + +Returns the number of already decrypted bytes available for read, pending on the connection. +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_pending_impl(PySSLSocket *self) +/*[clinic end generated code: output=983d9fecdc308a83 input=2b77487d6dfd597f]*/ +{ + int count = 0; + _PySSLError err; + + PySSL_BEGIN_ALLOW_THREADS + count = SSL_pending(self->ssl); + err = _PySSL_errno(count < 0, self->ssl, count); + PySSL_END_ALLOW_THREADS + self->err = err; + + if (count < 0) + return PySSL_SetError(self, count, __FILE__, __LINE__); + else + return PyLong_FromLong(count); +} + +/*[clinic input] +_ssl._SSLSocket.read + size as len: int + [ + buffer: Py_buffer(accept={rwbuffer}) + ] + / + +Read up to size bytes from the SSL socket. +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, + Py_buffer *buffer) +/*[clinic end generated code: output=00097776cec2a0af input=ff157eb918d0905b]*/ +{ + PyObject *dest = NULL; + char *mem; + int count; + int sockstate; + _PySSLError err; + int nonblocking; + PySocketSockObject *sock = GET_SOCKET(self); + _PyTime_t timeout, deadline = 0; + int has_timeout; + + if (!group_right_1 && len < 0) { + PyErr_SetString(PyExc_ValueError, "size should not be negative"); + return NULL; + } + + if (sock != NULL) { + if (((PyObject*)sock) == Py_None) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); + } + + if (!group_right_1) { + dest = PyBytes_FromStringAndSize(NULL, len); + if (dest == NULL) + goto error; + if (len == 0) { + Py_XDECREF(sock); + return dest; + } + mem = PyBytes_AS_STRING(dest); + } + else { + mem = buffer->buf; + if (len <= 0 || len > buffer->len) { + len = (int) buffer->len; + if (buffer->len != len) { + PyErr_SetString(PyExc_OverflowError, + "maximum length can't fit in a C 'int'"); + goto error; + } + if (len == 0) { + count = 0; + goto done; + } + } + } + + if (sock != NULL) { + /* just in case the blocking state of the socket has been changed */ + nonblocking = (sock->sock_timeout >= 0); + BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); + BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + } + + timeout = GET_SOCKET_TIMEOUT(sock); + has_timeout = (timeout > 0); + if (has_timeout) + deadline = _PyTime_GetMonotonicClock() + timeout; + + do { + PySSL_BEGIN_ALLOW_THREADS + count = SSL_read(self->ssl, mem, len); + err = _PySSL_errno(count <= 0, self->ssl, count); + PySSL_END_ALLOW_THREADS + self->err = err; + + if (PyErr_CheckSignals()) + goto error; + + if (has_timeout) + timeout = deadline - _PyTime_GetMonotonicClock(); + + if (err.ssl == SSL_ERROR_WANT_READ) { + sockstate = PySSL_select(sock, 0, timeout); + } else if (err.ssl == SSL_ERROR_WANT_WRITE) { + sockstate = PySSL_select(sock, 1, timeout); + } else if (err.ssl == SSL_ERROR_ZERO_RETURN && + SSL_get_shutdown(self->ssl) == SSL_RECEIVED_SHUTDOWN) + { + count = 0; + goto done; + } + else + sockstate = SOCKET_OPERATION_OK; + + if (sockstate == SOCKET_HAS_TIMED_OUT) { + PyErr_SetString(PySocketModule.timeout_error, + "The read operation timed out"); + goto error; + } else if (sockstate == SOCKET_IS_NONBLOCKING) { + break; + } + } while (err.ssl == SSL_ERROR_WANT_READ || + err.ssl == SSL_ERROR_WANT_WRITE); + + if (count <= 0) { + PySSL_SetError(self, count, __FILE__, __LINE__); + goto error; + } + if (self->exc_type != NULL) + goto error; + +done: + Py_XDECREF(sock); + if (!group_right_1) { + _PyBytes_Resize(&dest, count); + return dest; + } + else { + return PyLong_FromLong(count); + } + +error: + PySSL_ChainExceptions(self); + Py_XDECREF(sock); + if (!group_right_1) + Py_XDECREF(dest); + return NULL; +} + +/*[clinic input] +_ssl._SSLSocket.shutdown + +Does the SSL shutdown handshake with the remote end. +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_shutdown_impl(PySSLSocket *self) +/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=11d39e69b0a2bf4a]*/ +{ + _PySSLError err; + int sockstate, nonblocking, ret; + int zeros = 0; + PySocketSockObject *sock = GET_SOCKET(self); + _PyTime_t timeout, deadline = 0; + int has_timeout; + + if (sock != NULL) { + /* Guard against closed socket */ + if ((((PyObject*)sock) == Py_None) || (sock->sock_fd == INVALID_SOCKET)) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); + + /* Just in case the blocking state of the socket has been changed */ + nonblocking = (sock->sock_timeout >= 0); + BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); + BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + } + + timeout = GET_SOCKET_TIMEOUT(sock); + has_timeout = (timeout > 0); + if (has_timeout) + deadline = _PyTime_GetMonotonicClock() + timeout; + + while (1) { + PySSL_BEGIN_ALLOW_THREADS + /* Disable read-ahead so that unwrap can work correctly. + * Otherwise OpenSSL might read in too much data, + * eating clear text data that happens to be + * transmitted after the SSL shutdown. + * Should be safe to call repeatedly every time this + * function is used and the shutdown_seen_zero != 0 + * condition is met. + */ + if (self->shutdown_seen_zero) + SSL_set_read_ahead(self->ssl, 0); + ret = SSL_shutdown(self->ssl); + err = _PySSL_errno(ret < 0, self->ssl, ret); + PySSL_END_ALLOW_THREADS + self->err = err; + + /* If err == 1, a secure shutdown with SSL_shutdown() is complete */ + if (ret > 0) + break; + if (ret == 0) { + /* Don't loop endlessly; instead preserve legacy + behaviour of trying SSL_shutdown() only twice. + This looks necessary for OpenSSL < 0.9.8m */ + if (++zeros > 1) + break; + /* Shutdown was sent, now try receiving */ + self->shutdown_seen_zero = 1; + continue; + } + + if (has_timeout) + timeout = deadline - _PyTime_GetMonotonicClock(); + + /* Possibly retry shutdown until timeout or failure */ + if (err.ssl == SSL_ERROR_WANT_READ) + sockstate = PySSL_select(sock, 0, timeout); + else if (err.ssl == SSL_ERROR_WANT_WRITE) + sockstate = PySSL_select(sock, 1, timeout); + else + break; + + if (sockstate == SOCKET_HAS_TIMED_OUT) { + if (err.ssl == SSL_ERROR_WANT_READ) + PyErr_SetString(PySocketModule.timeout_error, + "The read operation timed out"); + else + PyErr_SetString(PySocketModule.timeout_error, + "The write operation timed out"); + goto error; + } + else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { + PyErr_SetString(PySSLErrorObject, + "Underlying socket too large for select()."); + goto error; + } + else if (sockstate != SOCKET_OPERATION_OK) + /* Retain the SSL error code */ + break; + } + if (ret < 0) { + Py_XDECREF(sock); + PySSL_SetError(self, ret, __FILE__, __LINE__); return NULL; - if (pseudo) { -#ifdef PY_OPENSSL_1_1_API - ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); -#else - ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); -#endif - if (ok == 0 || ok == 1) - return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); - } - else { - ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); - if (ok == 1) - return bytes; - } - Py_DECREF(bytes); - - err = ERR_get_error(); - errstr = ERR_reason_error_string(err); - v = Py_BuildValue("(ks)", err, errstr); - if (v != NULL) { - PyErr_SetObject(PySSLErrorObject, v); - Py_DECREF(v); - } - return NULL; -} - -/*[clinic input] -_ssl.RAND_bytes - n: int - / - -Generate n cryptographically strong pseudo-random bytes. -[clinic start generated code]*/ - -static PyObject * -_ssl_RAND_bytes_impl(PyObject *module, int n) -/*[clinic end generated code: output=977da635e4838bc7 input=678ddf2872dfebfc]*/ -{ - return PySSL_RAND(n, 0); -} - -/*[clinic input] -_ssl.RAND_pseudo_bytes - n: int - / - -Generate n pseudo-random bytes. - -Return a pair (bytes, is_cryptographic). is_cryptographic is True -if the bytes generated are cryptographically strong. -[clinic start generated code]*/ - -static PyObject * -_ssl_RAND_pseudo_bytes_impl(PyObject *module, int n) -/*[clinic end generated code: output=b1509e937000e52d input=58312bd53f9bbdd0]*/ -{ - return PySSL_RAND(n, 1); -} - -/*[clinic input] -_ssl.RAND_status - -Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not. - -It is necessary to seed the PRNG with RAND_add() on some platforms before -using the ssl() function. -[clinic start generated code]*/ - -static PyObject * -_ssl_RAND_status_impl(PyObject *module) -/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=8a774b02d1dc81f3]*/ -{ - return PyLong_FromLong(RAND_status()); -} - -#ifndef OPENSSL_NO_EGD -/* LCOV_EXCL_START */ -/*[clinic input] -_ssl.RAND_egd - path: object(converter="PyUnicode_FSConverter") - / - -Queries the entropy gather daemon (EGD) on the socket named by 'path'. + } + if (self->exc_type != NULL) + goto error; + if (sock) + /* It's already INCREF'ed */ + return (PyObject *) sock; + else + Py_RETURN_NONE; + +error: + Py_XDECREF(sock); + PySSL_ChainExceptions(self); + return NULL; +} + +/*[clinic input] +_ssl._SSLSocket.get_channel_binding + cb_type: str = "tls-unique" + +Get channel binding data for current connection. + +Raise ValueError if the requested `cb_type` is not supported. Return bytes +of the data or None if the data is not available (e.g. before the handshake). +Only 'tls-unique' channel binding data from RFC 5929 is supported. +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, + const char *cb_type) +/*[clinic end generated code: output=34bac9acb6a61d31 input=08b7e43b99c17d41]*/ +{ + char buf[PySSL_CB_MAXLEN]; + size_t len; + + if (strcmp(cb_type, "tls-unique") == 0) { + if (SSL_session_reused(self->ssl) ^ !self->socket_type) { + /* if session is resumed XOR we are the client */ + len = SSL_get_finished(self->ssl, buf, PySSL_CB_MAXLEN); + } + else { + /* if a new session XOR we are the server */ + len = SSL_get_peer_finished(self->ssl, buf, PySSL_CB_MAXLEN); + } + } + else { + PyErr_Format( + PyExc_ValueError, + "'%s' channel binding type not implemented", + cb_type + ); + return NULL; + } + + /* It cannot be negative in current OpenSSL version as of July 2011 */ + if (len == 0) + Py_RETURN_NONE; + + return PyBytes_FromStringAndSize(buf, len); +} + +/*[clinic input] +_ssl._SSLSocket.verify_client_post_handshake + +Initiate TLS 1.3 post-handshake authentication +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) +/*[clinic end generated code: output=532147f3b1341425 input=6bfa874810a3d889]*/ +{ +#ifdef TLS1_3_VERSION + int err = SSL_verify_client_post_handshake(self->ssl); + if (err == 0) + return _setSSLError(NULL, 0, __FILE__, __LINE__); + else + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_NotImplementedError, + "Post-handshake auth is not supported by your " + "OpenSSL version."); + return NULL; +#endif +} + +#ifdef OPENSSL_VERSION_1_1 + +static SSL_SESSION* +_ssl_session_dup(SSL_SESSION *session) { + SSL_SESSION *newsession = NULL; + int slen; + unsigned char *senc = NULL, *p; + const unsigned char *const_p; + + if (session == NULL) { + PyErr_SetString(PyExc_ValueError, "Invalid session"); + goto error; + } + + /* get length */ + slen = i2d_SSL_SESSION(session, NULL); + if (slen == 0 || slen > 0xFF00) { + PyErr_SetString(PyExc_ValueError, "i2d() failed."); + goto error; + } + if ((senc = PyMem_Malloc(slen)) == NULL) { + PyErr_NoMemory(); + goto error; + } + p = senc; + if (!i2d_SSL_SESSION(session, &p)) { + PyErr_SetString(PyExc_ValueError, "i2d() failed."); + goto error; + } + const_p = senc; + newsession = d2i_SSL_SESSION(NULL, &const_p, slen); + if (session == NULL) { + goto error; + } + PyMem_Free(senc); + return newsession; + error: + if (senc != NULL) { + PyMem_Free(senc); + } + return NULL; +} +#endif + +static PyObject * +PySSL_get_session(PySSLSocket *self, void *closure) { + /* get_session can return sessions from a server-side connection, + * it does not check for handshake done or client socket. */ + PySSLSession *pysess; + SSL_SESSION *session; + +#ifdef OPENSSL_VERSION_1_1 + /* duplicate session as workaround for session bug in OpenSSL 1.1.0, + * https://github.com/openssl/openssl/issues/1550 */ + session = SSL_get0_session(self->ssl); /* borrowed reference */ + if (session == NULL) { + Py_RETURN_NONE; + } + if ((session = _ssl_session_dup(session)) == NULL) { + return NULL; + } +#else + session = SSL_get1_session(self->ssl); + if (session == NULL) { + Py_RETURN_NONE; + } +#endif + pysess = PyObject_GC_New(PySSLSession, &PySSLSession_Type); + if (pysess == NULL) { + SSL_SESSION_free(session); + return NULL; + } + + assert(self->ctx); + pysess->ctx = self->ctx; + Py_INCREF(pysess->ctx); + pysess->session = session; + PyObject_GC_Track(pysess); + return (PyObject *)pysess; +} + +static int PySSL_set_session(PySSLSocket *self, PyObject *value, + void *closure) + { + PySSLSession *pysess; +#ifdef OPENSSL_VERSION_1_1 + SSL_SESSION *session; +#endif + int result; + + if (!PySSLSession_Check(value)) { + PyErr_SetString(PyExc_TypeError, "Value is not a SSLSession."); + return -1; + } + pysess = (PySSLSession *)value; + + if (self->ctx->ctx != pysess->ctx->ctx) { + PyErr_SetString(PyExc_ValueError, + "Session refers to a different SSLContext."); + return -1; + } + if (self->socket_type != PY_SSL_CLIENT) { + PyErr_SetString(PyExc_ValueError, + "Cannot set session for server-side SSLSocket."); + return -1; + } + if (SSL_is_init_finished(self->ssl)) { + PyErr_SetString(PyExc_ValueError, + "Cannot set session after handshake."); + return -1; + } +#ifdef OPENSSL_VERSION_1_1 + /* duplicate session */ + if ((session = _ssl_session_dup(pysess->session)) == NULL) { + return -1; + } + result = SSL_set_session(self->ssl, session); + /* free duplicate, SSL_set_session() bumps ref count */ + SSL_SESSION_free(session); +#else + result = SSL_set_session(self->ssl, pysess->session); +#endif + if (result == 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return -1; + } + return 0; +} + +PyDoc_STRVAR(PySSL_set_session_doc, +"_setter_session(session)\n\ +\ +Get / set SSLSession."); + +static PyObject * +PySSL_get_session_reused(PySSLSocket *self, void *closure) { + if (SSL_session_reused(self->ssl)) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +PyDoc_STRVAR(PySSL_get_session_reused_doc, +"Was the client session reused during handshake?"); + +static PyGetSetDef ssl_getsetlist[] = { + {"context", (getter) PySSL_get_context, + (setter) PySSL_set_context, PySSL_set_context_doc}, + {"server_side", (getter) PySSL_get_server_side, NULL, + PySSL_get_server_side_doc}, + {"server_hostname", (getter) PySSL_get_server_hostname, NULL, + PySSL_get_server_hostname_doc}, + {"owner", (getter) PySSL_get_owner, (setter) PySSL_set_owner, + PySSL_get_owner_doc}, + {"session", (getter) PySSL_get_session, + (setter) PySSL_set_session, PySSL_set_session_doc}, + {"session_reused", (getter) PySSL_get_session_reused, NULL, + PySSL_get_session_reused_doc}, + {NULL}, /* sentinel */ +}; + +static PyMethodDef PySSLMethods[] = { + _SSL__SSLSOCKET_DO_HANDSHAKE_METHODDEF + _SSL__SSLSOCKET_WRITE_METHODDEF + _SSL__SSLSOCKET_READ_METHODDEF + _SSL__SSLSOCKET_PENDING_METHODDEF + _SSL__SSLSOCKET_GETPEERCERT_METHODDEF + _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF + _SSL__SSLSOCKET_CIPHER_METHODDEF + _SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF + _SSL__SSLSOCKET_VERSION_METHODDEF + _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF + _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF + _SSL__SSLSOCKET_COMPRESSION_METHODDEF + _SSL__SSLSOCKET_SHUTDOWN_METHODDEF + _SSL__SSLSOCKET_VERIFY_CLIENT_POST_HANDSHAKE_METHODDEF + {NULL, NULL} +}; + +static PyTypeObject PySSLSocket_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ssl._SSLSocket", /*tp_name*/ + sizeof(PySSLSocket), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PySSL_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + (traverseproc) PySSL_traverse, /*tp_traverse*/ + (inquiry) PySSL_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PySSLMethods, /*tp_methods*/ + 0, /*tp_members*/ + ssl_getsetlist, /*tp_getset*/ +}; + + +/* + * _SSLContext objects + */ + +static int +_set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n) +{ + int mode; + int (*verify_cb)(int, X509_STORE_CTX *) = NULL; + + switch(n) { + case PY_SSL_CERT_NONE: + mode = SSL_VERIFY_NONE; + break; + case PY_SSL_CERT_OPTIONAL: + mode = SSL_VERIFY_PEER; + break; + case PY_SSL_CERT_REQUIRED: + mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + break; + default: + PyErr_SetString(PyExc_ValueError, + "invalid value for verify_mode"); + return -1; + } -Returns number of bytes read. Raises SSLError if connection to EGD -fails or if it does not provide enough data to seed PRNG. -[clinic start generated code]*/ + /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for + * server sockets and SSL_set_post_handshake_auth() for client. */ -static PyObject * -_ssl_RAND_egd_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=02a67c7c367f52fa input=1aeb7eb948312195]*/ -{ - int bytes = RAND_egd(PyBytes_AsString(path)); - Py_DECREF(path); - if (bytes == -1) { - PyErr_SetString(PySSLErrorObject, - "EGD connection failed or EGD did not return " - "enough data to seed the PRNG"); - return NULL; + /* keep current verify cb */ + verify_cb = SSL_CTX_get_verify_callback(self->ctx); + SSL_CTX_set_verify(self->ctx, mode, verify_cb); + return 0; +} + +/*[clinic input] +@classmethod +_ssl._SSLContext.__new__ + protocol as proto_version: int + / +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_impl(PyTypeObject *type, int proto_version) +/*[clinic end generated code: output=2cf0d7a0741b6bd1 input=8d58a805b95fc534]*/ +{ + PySSLContext *self; + long options; + SSL_CTX *ctx = NULL; + X509_VERIFY_PARAM *params; + int result; +#if defined(SSL_MODE_RELEASE_BUFFERS) + unsigned long libver; +#endif + + PySSL_BEGIN_ALLOW_THREADS + switch(proto_version) { +#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) + case PY_SSL_VERSION_SSL3: + ctx = SSL_CTX_new(SSLv3_method()); + break; +#endif +#if (defined(TLS1_VERSION) && \ + !defined(OPENSSL_NO_TLS1) && \ + !defined(OPENSSL_NO_TLS1_METHOD)) + case PY_SSL_VERSION_TLS1: + ctx = SSL_CTX_new(TLSv1_method()); + break; +#endif +#if (defined(TLS1_1_VERSION) && \ + !defined(OPENSSL_NO_TLS1_1) && \ + !defined(OPENSSL_NO_TLS1_1_METHOD)) + case PY_SSL_VERSION_TLS1_1: + ctx = SSL_CTX_new(TLSv1_1_method()); + break; +#endif +#if (defined(TLS1_2_VERSION) && \ + !defined(OPENSSL_NO_TLS1_2) && \ + !defined(OPENSSL_NO_TLS1_2_METHOD)) + case PY_SSL_VERSION_TLS1_2: + ctx = SSL_CTX_new(TLSv1_2_method()); + break; +#endif + case PY_SSL_VERSION_TLS: + /* SSLv23 */ + ctx = SSL_CTX_new(TLS_method()); + break; + case PY_SSL_VERSION_TLS_CLIENT: + ctx = SSL_CTX_new(TLS_client_method()); + break; + case PY_SSL_VERSION_TLS_SERVER: + ctx = SSL_CTX_new(TLS_server_method()); + break; + default: + proto_version = -1; } - return PyLong_FromLong(bytes); -} -/* LCOV_EXCL_STOP */ -#endif /* OPENSSL_NO_EGD */ - - - -/*[clinic input] -_ssl.get_default_verify_paths - -Return search paths and environment vars that are used by SSLContext's set_default_verify_paths() to load default CAs. - -The values are 'cert_file_env', 'cert_file', 'cert_dir_env', 'cert_dir'. -[clinic start generated code]*/ - -static PyObject * -_ssl_get_default_verify_paths_impl(PyObject *module) -/*[clinic end generated code: output=e5b62a466271928b input=5210c953d98c3eb5]*/ -{ - PyObject *ofile_env = NULL; - PyObject *ofile = NULL; - PyObject *odir_env = NULL; - PyObject *odir = NULL; - -#define CONVERT(info, target) { \ - const char *tmp = (info); \ - target = NULL; \ - if (!tmp) { Py_INCREF(Py_None); target = Py_None; } \ - else if ((target = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ - target = PyBytes_FromString(tmp); } \ - if (!target) goto error; \ + PySSL_END_ALLOW_THREADS + + if (proto_version == -1) { + PyErr_SetString(PyExc_ValueError, + "invalid or unsupported protocol version"); + return NULL; + } + if (ctx == NULL) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + + assert(type != NULL && type->tp_alloc != NULL); + self = (PySSLContext *) type->tp_alloc(type, 0); + if (self == NULL) { + SSL_CTX_free(ctx); + return NULL; + } + self->ctx = ctx; + self->hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; + self->protocol = proto_version; + self->msg_cb = NULL; +#ifdef HAVE_OPENSSL_KEYLOG + self->keylog_filename = NULL; + self->keylog_bio = NULL; +#endif +#if HAVE_NPN + self->npn_protocols = NULL; +#endif +#if HAVE_ALPN + self->alpn_protocols = NULL; +#endif +#ifndef OPENSSL_NO_TLSEXT + self->set_sni_cb = NULL; +#endif + /* Don't check host name by default */ + if (proto_version == PY_SSL_VERSION_TLS_CLIENT) { + self->check_hostname = 1; + if (_set_verify_mode(self, PY_SSL_CERT_REQUIRED) == -1) { + Py_DECREF(self); + return NULL; + } + } else { + self->check_hostname = 0; + if (_set_verify_mode(self, PY_SSL_CERT_NONE) == -1) { + Py_DECREF(self); + return NULL; + } + } + /* Defaults */ + options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + if (proto_version != PY_SSL_VERSION_SSL2) + options |= SSL_OP_NO_SSLv2; + if (proto_version != PY_SSL_VERSION_SSL3) + options |= SSL_OP_NO_SSLv3; + /* Minimal security flags for server and client side context. + * Client sockets ignore server-side parameters. */ +#ifdef SSL_OP_NO_COMPRESSION + options |= SSL_OP_NO_COMPRESSION; +#endif +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE + options |= SSL_OP_CIPHER_SERVER_PREFERENCE; +#endif +#ifdef SSL_OP_SINGLE_DH_USE + options |= SSL_OP_SINGLE_DH_USE; +#endif +#ifdef SSL_OP_SINGLE_ECDH_USE + options |= SSL_OP_SINGLE_ECDH_USE; +#endif +#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF + /* Make OpenSSL 3.0.0 behave like 1.1.1 */ + options |= SSL_OP_IGNORE_UNEXPECTED_EOF; +#endif + SSL_CTX_set_options(self->ctx, options); + + /* A bare minimum cipher list without completely broken cipher suites. + * It's far from perfect but gives users a better head start. */ + if (proto_version != PY_SSL_VERSION_SSL2) { +#if PY_SSL_DEFAULT_CIPHERS == 2 + /* stick to OpenSSL's default settings */ + result = 1; +#else + result = SSL_CTX_set_cipher_list(ctx, PY_SSL_DEFAULT_CIPHER_STRING); +#endif + } else { + /* SSLv2 needs MD5 */ + result = SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!eNULL"); + } + if (result == 0) { + Py_DECREF(self); + ERR_clear_error(); + PyErr_SetString(PySSLErrorObject, + "No cipher can be selected."); + return NULL; + } + +#if defined(SSL_MODE_RELEASE_BUFFERS) + /* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory + usage for no cost at all. However, don't do this for OpenSSL versions + between 1.0.1 and 1.0.1h or 1.0.0 and 1.0.0m, which are affected by CVE + 2014-0198. I can't find exactly which beta fixed this CVE, so be + conservative and assume it wasn't fixed until release. We do this check + at runtime to avoid problems from the dynamic linker. + See #25672 for more on this. */ + libver = OpenSSL_version_num(); + if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) && + !(libver >= 0x10000000UL && libver < 0x100000dfUL)) { + SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); + } +#endif + + +#if !defined(OPENSSL_NO_ECDH) && !defined(OPENSSL_VERSION_1_1) + /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use + prime256v1 by default. This is Apache mod_ssl's initialization + policy, so we should be safe. OpenSSL 1.1 has it enabled by default. + */ +#if defined(SSL_CTX_set_ecdh_auto) + SSL_CTX_set_ecdh_auto(self->ctx, 1); +#else + { + EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + SSL_CTX_set_tmp_ecdh(self->ctx, key); + EC_KEY_free(key); + } +#endif +#endif + +#define SID_CTX "Python" + SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX, + sizeof(SID_CTX)); +#undef SID_CTX + + params = SSL_CTX_get0_param(self->ctx); +#ifdef X509_V_FLAG_TRUSTED_FIRST + /* Improve trust chain building when cross-signed intermediate + certificates are present. See https://bugs.python.org/issue23476. */ + X509_VERIFY_PARAM_set_flags(params, X509_V_FLAG_TRUSTED_FIRST); +#endif + X509_VERIFY_PARAM_set_hostflags(params, self->hostflags); + +#ifdef TLS1_3_VERSION + self->post_handshake_auth = 0; + SSL_CTX_set_post_handshake_auth(self->ctx, self->post_handshake_auth); +#endif + + return (PyObject *)self; +} + +static int +context_traverse(PySSLContext *self, visitproc visit, void *arg) +{ +#ifndef OPENSSL_NO_TLSEXT + Py_VISIT(self->set_sni_cb); +#endif + Py_VISIT(self->msg_cb); + return 0; +} + +static int +context_clear(PySSLContext *self) +{ +#ifndef OPENSSL_NO_TLSEXT + Py_CLEAR(self->set_sni_cb); +#endif + Py_CLEAR(self->msg_cb); +#ifdef HAVE_OPENSSL_KEYLOG + Py_CLEAR(self->keylog_filename); + if (self->keylog_bio != NULL) { + PySSL_BEGIN_ALLOW_THREADS + BIO_free_all(self->keylog_bio); + PySSL_END_ALLOW_THREADS + self->keylog_bio = NULL; } - - CONVERT(X509_get_default_cert_file_env(), ofile_env); - CONVERT(X509_get_default_cert_file(), ofile); - CONVERT(X509_get_default_cert_dir_env(), odir_env); - CONVERT(X509_get_default_cert_dir(), odir); -#undef CONVERT - - return Py_BuildValue("NNNN", ofile_env, ofile, odir_env, odir); - - error: - Py_XDECREF(ofile_env); - Py_XDECREF(ofile); - Py_XDECREF(odir_env); - Py_XDECREF(odir); - return NULL; -} - -static PyObject* -asn1obj2py(ASN1_OBJECT *obj) +#endif + return 0; +} + +static void +context_dealloc(PySSLContext *self) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(self); + context_clear(self); + SSL_CTX_free(self->ctx); +#if HAVE_NPN + PyMem_FREE(self->npn_protocols); +#endif +#if HAVE_ALPN + PyMem_FREE(self->alpn_protocols); +#endif + Py_TYPE(self)->tp_free(self); +} + +/*[clinic input] +_ssl._SSLContext.set_ciphers + cipherlist: str + / +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) +/*[clinic end generated code: output=3a3162f3557c0f3f input=a7ac931b9f3ca7fc]*/ +{ + int ret = SSL_CTX_set_cipher_list(self->ctx, cipherlist); + if (ret == 0) { + /* Clearing the error queue is necessary on some OpenSSL versions, + otherwise the error will be reported again when another SSL call + is done. */ + ERR_clear_error(); + PyErr_SetString(PySSLErrorObject, + "No cipher can be selected."); + return NULL; + } + Py_RETURN_NONE; +} + +#if OPENSSL_VERSION_NUMBER >= 0x10002000UL +/*[clinic input] +_ssl._SSLContext.get_ciphers +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_get_ciphers_impl(PySSLContext *self) +/*[clinic end generated code: output=a56e4d68a406dfc4 input=a2aadc9af89b79c5]*/ +{ + SSL *ssl = NULL; + STACK_OF(SSL_CIPHER) *sk = NULL; + const SSL_CIPHER *cipher; + int i=0; + PyObject *result = NULL, *dct; + + ssl = SSL_new(self->ctx); + if (ssl == NULL) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto exit; + } + sk = SSL_get_ciphers(ssl); + + result = PyList_New(sk_SSL_CIPHER_num(sk)); + if (result == NULL) { + goto exit; + } + + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + cipher = sk_SSL_CIPHER_value(sk, i); + dct = cipher_to_dict(cipher); + if (dct == NULL) { + Py_CLEAR(result); + goto exit; + } + PyList_SET_ITEM(result, i, dct); + } + + exit: + if (ssl != NULL) + SSL_free(ssl); + return result; + +} +#endif + + +#if HAVE_NPN || HAVE_ALPN +static int +do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, + const unsigned char *server_protocols, unsigned int server_protocols_len, + const unsigned char *client_protocols, unsigned int client_protocols_len) +{ + int ret; + if (client_protocols == NULL) { + client_protocols = (unsigned char *)""; + client_protocols_len = 0; + } + if (server_protocols == NULL) { + server_protocols = (unsigned char *)""; + server_protocols_len = 0; + } + + ret = SSL_select_next_proto(out, outlen, + server_protocols, server_protocols_len, + client_protocols, client_protocols_len); + if (alpn && ret != OPENSSL_NPN_NEGOTIATED) + return SSL_TLSEXT_ERR_NOACK; + + return SSL_TLSEXT_ERR_OK; +} +#endif + +#if HAVE_NPN +/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */ +static int +_advertiseNPN_cb(SSL *s, + const unsigned char **data, unsigned int *len, + void *args) +{ + PySSLContext *ssl_ctx = (PySSLContext *) args; + + if (ssl_ctx->npn_protocols == NULL) { + *data = (unsigned char *)""; + *len = 0; + } else { + *data = ssl_ctx->npn_protocols; + *len = ssl_ctx->npn_protocols_len; + } + + return SSL_TLSEXT_ERR_OK; +} +/* this callback gets passed to SSL_CTX_set_next_proto_select_cb */ +static int +_selectNPN_cb(SSL *s, + unsigned char **out, unsigned char *outlen, + const unsigned char *server, unsigned int server_len, + void *args) +{ + PySSLContext *ctx = (PySSLContext *)args; + return do_protocol_selection(0, out, outlen, server, server_len, + ctx->npn_protocols, ctx->npn_protocols_len); +} +#endif + +/*[clinic input] +_ssl._SSLContext._set_npn_protocols + protos: Py_buffer + / +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, + Py_buffer *protos) +/*[clinic end generated code: output=72b002c3324390c6 input=319fcb66abf95bd7]*/ +{ +#if HAVE_NPN + PyMem_Free(self->npn_protocols); + self->npn_protocols = PyMem_Malloc(protos->len); + if (self->npn_protocols == NULL) + return PyErr_NoMemory(); + memcpy(self->npn_protocols, protos->buf, protos->len); + self->npn_protocols_len = (int) protos->len; + + /* set both server and client callbacks, because the context can + * be used to create both types of sockets */ + SSL_CTX_set_next_protos_advertised_cb(self->ctx, + _advertiseNPN_cb, + self); + SSL_CTX_set_next_proto_select_cb(self->ctx, + _selectNPN_cb, + self); + + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_NotImplementedError, + "The NPN extension requires OpenSSL 1.0.1 or later."); + return NULL; +#endif +} + +#if HAVE_ALPN +static int +_selectALPN_cb(SSL *s, + const unsigned char **out, unsigned char *outlen, + const unsigned char *client_protocols, unsigned int client_protocols_len, + void *args) +{ + PySSLContext *ctx = (PySSLContext *)args; + return do_protocol_selection(1, (unsigned char **)out, outlen, + ctx->alpn_protocols, ctx->alpn_protocols_len, + client_protocols, client_protocols_len); +} +#endif + +/*[clinic input] +_ssl._SSLContext._set_alpn_protocols + protos: Py_buffer + / +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, + Py_buffer *protos) +/*[clinic end generated code: output=87599a7f76651a9b input=9bba964595d519be]*/ +{ +#if HAVE_ALPN + if ((size_t)protos->len > UINT_MAX) { + PyErr_Format(PyExc_OverflowError, + "protocols longer than %u bytes", UINT_MAX); + return NULL; + } + + PyMem_FREE(self->alpn_protocols); + self->alpn_protocols = PyMem_Malloc(protos->len); + if (!self->alpn_protocols) + return PyErr_NoMemory(); + memcpy(self->alpn_protocols, protos->buf, protos->len); + self->alpn_protocols_len = (unsigned int)protos->len; + + if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) + return PyErr_NoMemory(); + SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); + + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_NotImplementedError, + "The ALPN extension requires OpenSSL 1.0.2 or later."); + return NULL; +#endif +} + +static PyObject * +get_verify_mode(PySSLContext *self, void *c) +{ + /* ignore SSL_VERIFY_CLIENT_ONCE and SSL_VERIFY_POST_HANDSHAKE */ + int mask = (SSL_VERIFY_NONE | SSL_VERIFY_PEER | + SSL_VERIFY_FAIL_IF_NO_PEER_CERT); + switch (SSL_CTX_get_verify_mode(self->ctx) & mask) { + case SSL_VERIFY_NONE: + return PyLong_FromLong(PY_SSL_CERT_NONE); + case SSL_VERIFY_PEER: + return PyLong_FromLong(PY_SSL_CERT_OPTIONAL); + case SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT: + return PyLong_FromLong(PY_SSL_CERT_REQUIRED); + } + PyErr_SetString(PySSLErrorObject, + "invalid return value from SSL_CTX_get_verify_mode"); + return NULL; +} + +static int +set_verify_mode(PySSLContext *self, PyObject *arg, void *c) +{ + int n; + if (!PyArg_Parse(arg, "i", &n)) + return -1; + if (n == PY_SSL_CERT_NONE && self->check_hostname) { + PyErr_SetString(PyExc_ValueError, + "Cannot set verify_mode to CERT_NONE when " + "check_hostname is enabled."); + return -1; + } + return _set_verify_mode(self, n); +} + +static PyObject * +get_verify_flags(PySSLContext *self, void *c) +{ + X509_VERIFY_PARAM *param; + unsigned long flags; + + param = SSL_CTX_get0_param(self->ctx); + flags = X509_VERIFY_PARAM_get_flags(param); + return PyLong_FromUnsignedLong(flags); +} + +static int +set_verify_flags(PySSLContext *self, PyObject *arg, void *c) +{ + X509_VERIFY_PARAM *param; + unsigned long new_flags, flags, set, clear; + + if (!PyArg_Parse(arg, "k", &new_flags)) + return -1; + param = SSL_CTX_get0_param(self->ctx); + flags = X509_VERIFY_PARAM_get_flags(param); + clear = flags & ~new_flags; + set = ~flags & new_flags; + if (clear) { + if (!X509_VERIFY_PARAM_clear_flags(param, clear)) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return -1; + } + } + if (set) { + if (!X509_VERIFY_PARAM_set_flags(param, set)) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return -1; + } + } + return 0; +} + +/* Getter and setter for protocol version */ +#if defined(SSL_CTRL_GET_MAX_PROTO_VERSION) + + +static int +set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) +{ + long v; + int result; + + if (!PyArg_Parse(arg, "l", &v)) + return -1; + if (v > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "Option is too long"); + return -1; + } + + switch(self->protocol) { + case PY_SSL_VERSION_TLS_CLIENT: /* fall through */ + case PY_SSL_VERSION_TLS_SERVER: /* fall through */ + case PY_SSL_VERSION_TLS: + break; + default: + PyErr_SetString( + PyExc_ValueError, + "The context's protocol doesn't support modification of " + "highest and lowest version." + ); + return -1; + } + + if (what == 0) { + switch(v) { + case PY_PROTO_MINIMUM_SUPPORTED: + v = 0; + break; + case PY_PROTO_MAXIMUM_SUPPORTED: + /* Emulate max for set_min_proto_version */ + v = PY_PROTO_MAXIMUM_AVAILABLE; + break; + default: + break; + } + result = SSL_CTX_set_min_proto_version(self->ctx, v); + } + else { + switch(v) { + case PY_PROTO_MAXIMUM_SUPPORTED: + v = 0; + break; + case PY_PROTO_MINIMUM_SUPPORTED: + /* Emulate max for set_min_proto_version */ + v = PY_PROTO_MINIMUM_AVAILABLE; + break; + default: + break; + } + result = SSL_CTX_set_max_proto_version(self->ctx, v); + } + if (result == 0) { + PyErr_Format(PyExc_ValueError, + "Unsupported protocol version 0x%x", v); + return -1; + } + return 0; +} + +static PyObject * +get_minimum_version(PySSLContext *self, void *c) +{ + int v = SSL_CTX_ctrl(self->ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL); + if (v == 0) { + v = PY_PROTO_MINIMUM_SUPPORTED; + } + return PyLong_FromLong(v); +} + +static int +set_minimum_version(PySSLContext *self, PyObject *arg, void *c) +{ + return set_min_max_proto_version(self, arg, 0); +} + +static PyObject * +get_maximum_version(PySSLContext *self, void *c) +{ + int v = SSL_CTX_ctrl(self->ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL); + if (v == 0) { + v = PY_PROTO_MAXIMUM_SUPPORTED; + } + return PyLong_FromLong(v); +} + +static int +set_maximum_version(PySSLContext *self, PyObject *arg, void *c) +{ + return set_min_max_proto_version(self, arg, 1); +} +#endif /* SSL_CTRL_GET_MAX_PROTO_VERSION */ + +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +static PyObject * +get_num_tickets(PySSLContext *self, void *c) { - int nid; - const char *ln, *sn; - - nid = OBJ_obj2nid(obj); - if (nid == NID_undef) { - PyErr_Format(PyExc_ValueError, "Unknown object"); - return NULL; - } - sn = OBJ_nid2sn(nid); - ln = OBJ_nid2ln(nid); - return Py_BuildValue("issN", nid, sn, ln, _asn1obj2py(obj, 1)); + return PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); } -/*[clinic input] -_ssl.txt2obj - txt: str - name: bool = False - -Lookup NID, short name, long name and OID of an ASN1_OBJECT. - -By default objects are looked up by OID. With name=True short and -long name are also matched. -[clinic start generated code]*/ - -static PyObject * -_ssl_txt2obj_impl(PyObject *module, const char *txt, int name) -/*[clinic end generated code: output=c38e3991347079c1 input=1c1e7d0aa7c48602]*/ +static int +set_num_tickets(PySSLContext *self, PyObject *arg, void *c) { - PyObject *result = NULL; - ASN1_OBJECT *obj; - - obj = OBJ_txt2obj(txt, name ? 0 : 1); - if (obj == NULL) { - PyErr_Format(PyExc_ValueError, "unknown object '%.100s'", txt); - return NULL; + long num; + if (!PyArg_Parse(arg, "l", &num)) + return -1; + if (num < 0) { + PyErr_SetString(PyExc_ValueError, "value must be non-negative"); + return -1; } - result = asn1obj2py(obj); - ASN1_OBJECT_free(obj); - return result; -} - -/*[clinic input] -_ssl.nid2obj - nid: int - / - -Lookup NID, short name, long name and OID of an ASN1_OBJECT by NID. -[clinic start generated code]*/ - -static PyObject * -_ssl_nid2obj_impl(PyObject *module, int nid) -/*[clinic end generated code: output=4a98ab691cd4f84a input=51787a3bee7d8f98]*/ -{ - PyObject *result = NULL; - ASN1_OBJECT *obj; - - if (nid < NID_undef) { - PyErr_SetString(PyExc_ValueError, "NID must be positive."); - return NULL; + if (self->protocol != PY_SSL_VERSION_TLS_SERVER) { + PyErr_SetString(PyExc_ValueError, + "SSLContext is not a server context."); + return -1; } - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - PyErr_Format(PyExc_ValueError, "unknown NID %i", nid); - return NULL; + if (SSL_CTX_set_num_tickets(self->ctx, num) != 1) { + PyErr_SetString(PyExc_ValueError, "failed to set num tickets."); + return -1; } - result = asn1obj2py(obj); - ASN1_OBJECT_free(obj); - return result; + return 0; } -#ifdef _MSC_VER - -static PyObject* -certEncodingType(DWORD encodingType) -{ - static PyObject *x509_asn = NULL; - static PyObject *pkcs_7_asn = NULL; +PyDoc_STRVAR(PySSLContext_num_tickets_doc, +"Control the number of TLSv1.3 session tickets"); +#endif /* OpenSSL 1.1.1 */ - if (x509_asn == NULL) { - x509_asn = PyUnicode_InternFromString("x509_asn"); - if (x509_asn == NULL) - return NULL; - } - if (pkcs_7_asn == NULL) { - pkcs_7_asn = PyUnicode_InternFromString("pkcs_7_asn"); - if (pkcs_7_asn == NULL) - return NULL; - } - switch(encodingType) { - case X509_ASN_ENCODING: - Py_INCREF(x509_asn); - return x509_asn; - case PKCS_7_ASN_ENCODING: - Py_INCREF(pkcs_7_asn); - return pkcs_7_asn; - default: - return PyLong_FromLong(encodingType); +static PyObject * +get_options(PySSLContext *self, void *c) +{ + return PyLong_FromLong(SSL_CTX_get_options(self->ctx)); +} + +static int +set_options(PySSLContext *self, PyObject *arg, void *c) +{ + long new_opts, opts, set, clear; + if (!PyArg_Parse(arg, "l", &new_opts)) + return -1; + opts = SSL_CTX_get_options(self->ctx); + clear = opts & ~new_opts; + set = ~opts & new_opts; + if (clear) { +#ifdef HAVE_SSL_CTX_CLEAR_OPTIONS + SSL_CTX_clear_options(self->ctx, clear); +#else + PyErr_SetString(PyExc_ValueError, + "can't clear options before OpenSSL 0.9.8m"); + return -1; +#endif + } + if (set) + SSL_CTX_set_options(self->ctx, set); + return 0; +} + +static PyObject * +get_host_flags(PySSLContext *self, void *c) +{ + return PyLong_FromUnsignedLong(self->hostflags); +} + +static int +set_host_flags(PySSLContext *self, PyObject *arg, void *c) +{ + X509_VERIFY_PARAM *param; + unsigned int new_flags = 0; + + if (!PyArg_Parse(arg, "I", &new_flags)) + return -1; + + param = SSL_CTX_get0_param(self->ctx); + self->hostflags = new_flags; + X509_VERIFY_PARAM_set_hostflags(param, new_flags); + return 0; +} + +static PyObject * +get_check_hostname(PySSLContext *self, void *c) +{ + return PyBool_FromLong(self->check_hostname); +} + +static int +set_check_hostname(PySSLContext *self, PyObject *arg, void *c) +{ + int check_hostname; + if (!PyArg_Parse(arg, "p", &check_hostname)) + return -1; + if (check_hostname && + SSL_CTX_get_verify_mode(self->ctx) == SSL_VERIFY_NONE) { + /* check_hostname = True sets verify_mode = CERT_REQUIRED */ + if (_set_verify_mode(self, PY_SSL_CERT_REQUIRED) == -1) { + return -1; + } + } + self->check_hostname = check_hostname; + return 0; +} + +static PyObject * +get_post_handshake_auth(PySSLContext *self, void *c) { +#if TLS1_3_VERSION + return PyBool_FromLong(self->post_handshake_auth); +#else + Py_RETURN_NONE; +#endif +} + +#if TLS1_3_VERSION +static int +set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) { + if (arg == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + int pha = PyObject_IsTrue(arg); + + if (pha == -1) { + return -1; + } + self->post_handshake_auth = pha; + + /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for + * server sockets and SSL_set_post_handshake_auth() for client. */ + + return 0; +} +#endif + +static PyObject * +get_protocol(PySSLContext *self, void *c) { + return PyLong_FromLong(self->protocol); +} + +typedef struct { + PyThreadState *thread_state; + PyObject *callable; + char *password; + int size; + int error; +} _PySSLPasswordInfo; + +static int +_pwinfo_set(_PySSLPasswordInfo *pw_info, PyObject* password, + const char *bad_type_error) +{ + /* Set the password and size fields of a _PySSLPasswordInfo struct + from a unicode, bytes, or byte array object. + The password field will be dynamically allocated and must be freed + by the caller */ + PyObject *password_bytes = NULL; + const char *data = NULL; + Py_ssize_t size; + + if (PyUnicode_Check(password)) { + password_bytes = PyUnicode_AsUTF8String(password); + if (!password_bytes) { + goto error; + } + data = PyBytes_AS_STRING(password_bytes); + size = PyBytes_GET_SIZE(password_bytes); + } else if (PyBytes_Check(password)) { + data = PyBytes_AS_STRING(password); + size = PyBytes_GET_SIZE(password); + } else if (PyByteArray_Check(password)) { + data = PyByteArray_AS_STRING(password); + size = PyByteArray_GET_SIZE(password); + } else { + PyErr_SetString(PyExc_TypeError, bad_type_error); + goto error; + } + + if (size > (Py_ssize_t)INT_MAX) { + PyErr_Format(PyExc_ValueError, + "password cannot be longer than %d bytes", INT_MAX); + goto error; + } + + PyMem_Free(pw_info->password); + pw_info->password = PyMem_Malloc(size); + if (!pw_info->password) { + PyErr_SetString(PyExc_MemoryError, + "unable to allocate password buffer"); + goto error; + } + memcpy(pw_info->password, data, size); + pw_info->size = (int)size; + + Py_XDECREF(password_bytes); + return 1; + +error: + Py_XDECREF(password_bytes); + return 0; +} + +static int +_password_callback(char *buf, int size, int rwflag, void *userdata) +{ + _PySSLPasswordInfo *pw_info = (_PySSLPasswordInfo*) userdata; + PyObject *fn_ret = NULL; + + PySSL_END_ALLOW_THREADS_S(pw_info->thread_state); + + if (pw_info->error) { + /* already failed previously. OpenSSL 3.0.0-alpha14 invokes the + * callback multiple times which can lead to fatal Python error in + * exception check. */ + goto error; } -} - -static PyObject* -parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags) -{ - CERT_ENHKEY_USAGE *usage; - DWORD size, error, i; - PyObject *retval; - if (!CertGetEnhancedKeyUsage(pCertCtx, flags, NULL, &size)) { - error = GetLastError(); - if (error == CRYPT_E_NOT_FOUND) { - Py_RETURN_TRUE; + if (pw_info->callable) { + fn_ret = _PyObject_CallNoArg(pw_info->callable); + if (!fn_ret) { + /* TODO: It would be nice to move _ctypes_add_traceback() into the + core python API, so we could use it to add a frame here */ + goto error; + } + + if (!_pwinfo_set(pw_info, fn_ret, + "password callback must return a string")) { + goto error; + } + Py_CLEAR(fn_ret); + } + + if (pw_info->size > size) { + PyErr_Format(PyExc_ValueError, + "password cannot be longer than %d bytes", size); + goto error; + } + + PySSL_BEGIN_ALLOW_THREADS_S(pw_info->thread_state); + memcpy(buf, pw_info->password, pw_info->size); + return pw_info->size; + +error: + Py_XDECREF(fn_ret); + PySSL_BEGIN_ALLOW_THREADS_S(pw_info->thread_state); + pw_info->error = 1; + return -1; +} + +/*[clinic input] +_ssl._SSLContext.load_cert_chain + certfile: object + keyfile: object = None + password: object = None + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, + PyObject *keyfile, PyObject *password) +/*[clinic end generated code: output=9480bc1c380e2095 input=30bc7e967ea01a58]*/ +{ + PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; + pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); + void *orig_passwd_userdata = SSL_CTX_get_default_passwd_cb_userdata(self->ctx); + _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; + int r; + + errno = 0; + ERR_clear_error(); + if (keyfile == Py_None) + keyfile = NULL; + if (!PyUnicode_FSConverter(certfile, &certfile_bytes)) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "certfile should be a valid filesystem path"); } - return PyErr_SetFromWindowsErr(error); - } - - usage = (CERT_ENHKEY_USAGE*)PyMem_Malloc(size); - if (usage == NULL) { - return PyErr_NoMemory(); - } - - /* Now get the actual enhanced usage property */ - if (!CertGetEnhancedKeyUsage(pCertCtx, flags, usage, &size)) { - PyMem_Free(usage); - error = GetLastError(); - if (error == CRYPT_E_NOT_FOUND) { - Py_RETURN_TRUE; + return NULL; + } + if (keyfile && !PyUnicode_FSConverter(keyfile, &keyfile_bytes)) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "keyfile should be a valid filesystem path"); } - return PyErr_SetFromWindowsErr(error); - } - retval = PyFrozenSet_New(NULL); - if (retval == NULL) { - goto error; - } - for (i = 0; i < usage->cUsageIdentifier; ++i) { - if (usage->rgpszUsageIdentifier[i]) { - PyObject *oid; - int err; - oid = PyUnicode_FromString(usage->rgpszUsageIdentifier[i]); - if (oid == NULL) { - Py_CLEAR(retval); + goto error; + } + if (password != Py_None) { + if (PyCallable_Check(password)) { + pw_info.callable = password; + } else if (!_pwinfo_set(&pw_info, password, + "password should be a string or callable")) { + goto error; + } + SSL_CTX_set_default_passwd_cb(self->ctx, _password_callback); + SSL_CTX_set_default_passwd_cb_userdata(self->ctx, &pw_info); + } + PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); + r = SSL_CTX_use_certificate_chain_file(self->ctx, + PyBytes_AS_STRING(certfile_bytes)); + PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); + if (r != 1) { + if (pw_info.error) { + ERR_clear_error(); + /* the password callback has already set the error information */ + } + else if (errno != 0) { + ERR_clear_error(); + PyErr_SetFromErrno(PyExc_OSError); + } + else { + _setSSLError(NULL, 0, __FILE__, __LINE__); + } + goto error; + } + PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); + r = SSL_CTX_use_PrivateKey_file(self->ctx, + PyBytes_AS_STRING(keyfile ? keyfile_bytes : certfile_bytes), + SSL_FILETYPE_PEM); + PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); + Py_CLEAR(keyfile_bytes); + Py_CLEAR(certfile_bytes); + if (r != 1) { + if (pw_info.error) { + ERR_clear_error(); + /* the password callback has already set the error information */ + } + else if (errno != 0) { + ERR_clear_error(); + PyErr_SetFromErrno(PyExc_OSError); + } + else { + _setSSLError(NULL, 0, __FILE__, __LINE__); + } + goto error; + } + PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); + r = SSL_CTX_check_private_key(self->ctx); + PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); + if (r != 1) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto error; + } + SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); + SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); + PyMem_Free(pw_info.password); + Py_RETURN_NONE; + +error: + SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); + SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); + PyMem_Free(pw_info.password); + Py_XDECREF(keyfile_bytes); + Py_XDECREF(certfile_bytes); + return NULL; +} + +/* internal helper function, returns -1 on error + */ +static int +_add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, + int filetype) +{ + BIO *biobuf = NULL; + X509_STORE *store; + int retval = -1, err, loaded = 0; + + assert(filetype == SSL_FILETYPE_ASN1 || filetype == SSL_FILETYPE_PEM); + + if (len <= 0) { + PyErr_SetString(PyExc_ValueError, + "Empty certificate data"); + return -1; + } else if (len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "Certificate data is too long."); + return -1; + } + + biobuf = BIO_new_mem_buf(data, (int)len); + if (biobuf == NULL) { + _setSSLError("Can't allocate buffer", 0, __FILE__, __LINE__); + return -1; + } + + store = SSL_CTX_get_cert_store(self->ctx); + assert(store != NULL); + + while (1) { + X509 *cert = NULL; + int r; + + if (filetype == SSL_FILETYPE_ASN1) { + cert = d2i_X509_bio(biobuf, NULL); + } else { + cert = PEM_read_bio_X509(biobuf, NULL, + SSL_CTX_get_default_passwd_cb(self->ctx), + SSL_CTX_get_default_passwd_cb_userdata(self->ctx) + ); + } + if (cert == NULL) { + break; + } + r = X509_STORE_add_cert(store, cert); + X509_free(cert); + if (!r) { + err = ERR_peek_last_error(); + if ((ERR_GET_LIB(err) == ERR_LIB_X509) && + (ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) { + /* cert already in hash table, not an error */ + ERR_clear_error(); + } else { + break; + } + } + loaded++; + } + + err = ERR_peek_last_error(); + if (loaded == 0) { + const char *msg = NULL; + if (filetype == SSL_FILETYPE_PEM) { + msg = "no start line: cadata does not contain a certificate"; + } else { + msg = "not enough data: cadata does not contain a certificate"; + } + _setSSLError(msg, 0, __FILE__, __LINE__); + retval = -1; + } else if ((filetype == SSL_FILETYPE_ASN1) && + (ERR_GET_LIB(err) == ERR_LIB_ASN1) && + (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG)) { + /* EOF ASN1 file, not an error */ + ERR_clear_error(); + retval = 0; + } else if ((filetype == SSL_FILETYPE_PEM) && + (ERR_GET_LIB(err) == ERR_LIB_PEM) && + (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { + /* EOF PEM file, not an error */ + ERR_clear_error(); + retval = 0; + } else if (err != 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + retval = -1; + } else { + retval = 0; + } + + BIO_free(biobuf); + return retval; +} + + +/*[clinic input] +_ssl._SSLContext.load_verify_locations + cafile: object = None + capath: object = None + cadata: object = None + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, + PyObject *cafile, + PyObject *capath, + PyObject *cadata) +/*[clinic end generated code: output=454c7e41230ca551 input=42ecfe258233e194]*/ +{ + PyObject *cafile_bytes = NULL, *capath_bytes = NULL; + const char *cafile_buf = NULL, *capath_buf = NULL; + int r = 0, ok = 1; + + errno = 0; + if (cafile == Py_None) + cafile = NULL; + if (capath == Py_None) + capath = NULL; + if (cadata == Py_None) + cadata = NULL; + + if (cafile == NULL && capath == NULL && cadata == NULL) { + PyErr_SetString(PyExc_TypeError, + "cafile, capath and cadata cannot be all omitted"); + goto error; + } + if (cafile && !PyUnicode_FSConverter(cafile, &cafile_bytes)) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "cafile should be a valid filesystem path"); + } + goto error; + } + if (capath && !PyUnicode_FSConverter(capath, &capath_bytes)) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "capath should be a valid filesystem path"); + } + goto error; + } + + /* validate cadata type and load cadata */ + if (cadata) { + if (PyUnicode_Check(cadata)) { + PyObject *cadata_ascii = PyUnicode_AsASCIIString(cadata); + if (cadata_ascii == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + goto invalid_cadata; + } + goto error; + } + r = _add_ca_certs(self, + PyBytes_AS_STRING(cadata_ascii), + PyBytes_GET_SIZE(cadata_ascii), + SSL_FILETYPE_PEM); + Py_DECREF(cadata_ascii); + if (r == -1) { goto error; } - err = PySet_Add(retval, oid); - Py_DECREF(oid); - if (err == -1) { - Py_CLEAR(retval); + } + else if (PyObject_CheckBuffer(cadata)) { + Py_buffer buf; + if (PyObject_GetBuffer(cadata, &buf, PyBUF_SIMPLE)) { goto error; } + if (!PyBuffer_IsContiguous(&buf, 'C') || buf.ndim > 1) { + PyBuffer_Release(&buf); + PyErr_SetString(PyExc_TypeError, + "cadata should be a contiguous buffer with " + "a single dimension"); + goto error; + } + r = _add_ca_certs(self, buf.buf, buf.len, SSL_FILETYPE_ASN1); + PyBuffer_Release(&buf); + if (r == -1) { + goto error; + } + } + else { + invalid_cadata: + PyErr_SetString(PyExc_TypeError, + "cadata should be an ASCII string or a " + "bytes-like object"); + goto error; } + } + + /* load cafile or capath */ + if (cafile || capath) { + if (cafile) + cafile_buf = PyBytes_AS_STRING(cafile_bytes); + if (capath) + capath_buf = PyBytes_AS_STRING(capath_bytes); + PySSL_BEGIN_ALLOW_THREADS + r = SSL_CTX_load_verify_locations(self->ctx, cafile_buf, capath_buf); + PySSL_END_ALLOW_THREADS + if (r != 1) { + if (errno != 0) { + ERR_clear_error(); + PyErr_SetFromErrno(PyExc_OSError); + } + else { + _setSSLError(NULL, 0, __FILE__, __LINE__); + } + goto error; + } + } + goto end; + + error: + ok = 0; + end: + Py_XDECREF(cafile_bytes); + Py_XDECREF(capath_bytes); + if (ok) { + Py_RETURN_NONE; + } else { + return NULL; + } +} + +/*[clinic input] +_ssl._SSLContext.load_dh_params + path as filepath: object + / + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) +/*[clinic end generated code: output=1c8e57a38e055af0 input=c8871f3c796ae1d6]*/ +{ + FILE *f; + DH *dh; + + f = _Py_fopen_obj(filepath, "rb"); + if (f == NULL) + return NULL; + + errno = 0; + PySSL_BEGIN_ALLOW_THREADS + dh = PEM_read_DHparams(f, NULL, NULL, NULL); + fclose(f); + PySSL_END_ALLOW_THREADS + if (dh == NULL) { + if (errno != 0) { + ERR_clear_error(); + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, filepath); + } + else { + _setSSLError(NULL, 0, __FILE__, __LINE__); + } + return NULL; + } + if (!SSL_CTX_set_tmp_dh(self->ctx, dh)) { + DH_free(dh); + return _setSSLError(NULL, 0, __FILE__, __LINE__); } - error: - PyMem_Free(usage); - return retval; -} - + DH_free(dh); + Py_RETURN_NONE; +} + +/*[clinic input] +_ssl._SSLContext._wrap_socket + sock: object(subclass_of="PySocketModule.Sock_Type") + server_side: int + server_hostname as hostname_obj: object = None + * + owner: object = None + session: object = None + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, + int server_side, PyObject *hostname_obj, + PyObject *owner, PyObject *session) +/*[clinic end generated code: output=f103f238633940b4 input=957d5006183d1894]*/ +{ + char *hostname = NULL; + PyObject *res; + + /* server_hostname is either None (or absent), or to be encoded + as IDN A-label (ASCII str) without NULL bytes. */ + if (hostname_obj != Py_None) { + if (!PyArg_Parse(hostname_obj, "es", "ascii", &hostname)) + return NULL; + } + + res = (PyObject *) newPySSLSocket(self, (PySocketSockObject *)sock, + server_side, hostname, + owner, session, + NULL, NULL); + if (hostname != NULL) + PyMem_Free(hostname); + return res; +} + +/*[clinic input] +_ssl._SSLContext._wrap_bio + incoming: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") + outgoing: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") + server_side: int + server_hostname as hostname_obj: object = None + * + owner: object = None + session: object = None + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, + PySSLMemoryBIO *outgoing, int server_side, + PyObject *hostname_obj, PyObject *owner, + PyObject *session) +/*[clinic end generated code: output=5c5d6d9b41f99332 input=8cf22f4d586ac56a]*/ +{ + char *hostname = NULL; + PyObject *res; + + /* server_hostname is either None (or absent), or to be encoded + as IDN A-label (ASCII str) without NULL bytes. */ + if (hostname_obj != Py_None) { + if (!PyArg_Parse(hostname_obj, "es", "ascii", &hostname)) + return NULL; + } + + res = (PyObject *) newPySSLSocket(self, NULL, server_side, hostname, + owner, session, + incoming, outgoing); + + PyMem_Free(hostname); + return res; +} + +/*[clinic input] +_ssl._SSLContext.session_stats +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_session_stats_impl(PySSLContext *self) +/*[clinic end generated code: output=0d96411c42893bfb input=7e0a81fb11102c8b]*/ +{ + int r; + PyObject *value, *stats = PyDict_New(); + if (!stats) + return NULL; + +#define ADD_STATS(SSL_NAME, KEY_NAME) \ + value = PyLong_FromLong(SSL_CTX_sess_ ## SSL_NAME (self->ctx)); \ + if (value == NULL) \ + goto error; \ + r = PyDict_SetItemString(stats, KEY_NAME, value); \ + Py_DECREF(value); \ + if (r < 0) \ + goto error; + + ADD_STATS(number, "number"); + ADD_STATS(connect, "connect"); + ADD_STATS(connect_good, "connect_good"); + ADD_STATS(connect_renegotiate, "connect_renegotiate"); + ADD_STATS(accept, "accept"); + ADD_STATS(accept_good, "accept_good"); + ADD_STATS(accept_renegotiate, "accept_renegotiate"); + ADD_STATS(accept, "accept"); + ADD_STATS(hits, "hits"); + ADD_STATS(misses, "misses"); + ADD_STATS(timeouts, "timeouts"); + ADD_STATS(cache_full, "cache_full"); + +#undef ADD_STATS + + return stats; + +error: + Py_DECREF(stats); + return NULL; +} + +/*[clinic input] +_ssl._SSLContext.set_default_verify_paths +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) +/*[clinic end generated code: output=0bee74e6e09deaaa input=35f3408021463d74]*/ +{ + if (!SSL_CTX_set_default_verify_paths(self->ctx)) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + Py_RETURN_NONE; +} + +#ifndef OPENSSL_NO_ECDH +/*[clinic input] +_ssl._SSLContext.set_ecdh_curve + name: object + / + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) +/*[clinic end generated code: output=23022c196e40d7d2 input=c2bafb6f6e34726b]*/ +{ + PyObject *name_bytes; + int nid; + EC_KEY *key; + + if (!PyUnicode_FSConverter(name, &name_bytes)) + return NULL; + assert(PyBytes_Check(name_bytes)); + nid = OBJ_sn2nid(PyBytes_AS_STRING(name_bytes)); + Py_DECREF(name_bytes); + if (nid == 0) { + PyErr_Format(PyExc_ValueError, + "unknown elliptic curve name %R", name); + return NULL; + } + key = EC_KEY_new_by_curve_name(nid); + if (key == NULL) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + SSL_CTX_set_tmp_ecdh(self->ctx, key); + EC_KEY_free(key); + Py_RETURN_NONE; +} +#endif + +#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) +static int +_servername_callback(SSL *s, int *al, void *args) +{ + int ret; + PySSLContext *ssl_ctx = (PySSLContext *) args; + PySSLSocket *ssl; + PyObject *result; + /* The high-level ssl.SSLSocket object */ + PyObject *ssl_socket; + const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); + PyGILState_STATE gstate = PyGILState_Ensure(); + + if (ssl_ctx->set_sni_cb == NULL) { + /* remove race condition in this the call back while if removing the + * callback is in progress */ + PyGILState_Release(gstate); + return SSL_TLSEXT_ERR_OK; + } + + ssl = SSL_get_app_data(s); + assert(PySSLSocket_Check(ssl)); + + /* The servername callback expects an argument that represents the current + * SSL connection and that has a .context attribute that can be changed to + * identify the requested hostname. Since the official API is the Python + * level API we want to pass the callback a Python level object rather than + * a _ssl.SSLSocket instance. If there's an "owner" (typically an + * SSLObject) that will be passed. Otherwise if there's a socket then that + * will be passed. If both do not exist only then the C-level object is + * passed. */ + if (ssl->owner) + ssl_socket = PyWeakref_GetObject(ssl->owner); + else if (ssl->Socket) + ssl_socket = PyWeakref_GetObject(ssl->Socket); + else + ssl_socket = (PyObject *) ssl; + + Py_INCREF(ssl_socket); + if (ssl_socket == Py_None) + goto error; + + if (servername == NULL) { + result = PyObject_CallFunctionObjArgs(ssl_ctx->set_sni_cb, ssl_socket, + Py_None, ssl_ctx, NULL); + } + else { + PyObject *servername_bytes; + PyObject *servername_str; + + servername_bytes = PyBytes_FromString(servername); + if (servername_bytes == NULL) { + PyErr_WriteUnraisable((PyObject *) ssl_ctx); + goto error; + } + /* server_hostname was encoded to an A-label by our caller; put it + * back into a str object, but still as an A-label (bpo-28414) + */ + servername_str = PyUnicode_FromEncodedObject(servername_bytes, "ascii", NULL); + if (servername_str == NULL) { + PyErr_WriteUnraisable(servername_bytes); + Py_DECREF(servername_bytes); + goto error; + } + Py_DECREF(servername_bytes); + result = PyObject_CallFunctionObjArgs( + ssl_ctx->set_sni_cb, ssl_socket, servername_str, + ssl_ctx, NULL); + Py_DECREF(servername_str); + } + Py_DECREF(ssl_socket); + + if (result == NULL) { + PyErr_WriteUnraisable(ssl_ctx->set_sni_cb); + *al = SSL_AD_HANDSHAKE_FAILURE; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + else { + /* Result may be None, a SSLContext or an integer + * None and SSLContext are OK, integer or other values are an error. + */ + if (result == Py_None) { + ret = SSL_TLSEXT_ERR_OK; + } else { + *al = (int) PyLong_AsLong(result); + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(result); + *al = SSL_AD_INTERNAL_ERROR; + } + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + Py_DECREF(result); + } + + PyGILState_Release(gstate); + return ret; + +error: + Py_DECREF(ssl_socket); + *al = SSL_AD_INTERNAL_ERROR; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + PyGILState_Release(gstate); + return ret; +} +#endif + +static PyObject * +get_sni_callback(PySSLContext *self, void *c) +{ + PyObject *cb = self->set_sni_cb; + if (cb == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(cb); + return cb; +} + +static int +set_sni_callback(PySSLContext *self, PyObject *arg, void *c) +{ + if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) { + PyErr_SetString(PyExc_ValueError, + "sni_callback cannot be set on TLS_CLIENT context"); + return -1; + } +#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) + Py_CLEAR(self->set_sni_cb); + if (arg == Py_None) { + SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); + } + else { + if (!PyCallable_Check(arg)) { + SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); + PyErr_SetString(PyExc_TypeError, + "not a callable object"); + return -1; + } + Py_INCREF(arg); + self->set_sni_cb = arg; + SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); + SSL_CTX_set_tlsext_servername_arg(self->ctx, self); + } + return 0; +#else + PyErr_SetString(PyExc_NotImplementedError, + "The TLS extension servername callback, " + "SSL_CTX_set_tlsext_servername_callback, " + "is not in the current OpenSSL library."); + return -1; +#endif +} + +PyDoc_STRVAR(PySSLContext_sni_callback_doc, +"Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.\n\ +\n\ +If the argument is None then the callback is disabled. The method is called\n\ +with the SSLSocket, the server name as a string, and the SSLContext object.\n\ +See RFC 6066 for details of the SNI extension."); + +/*[clinic input] +_ssl._SSLContext.cert_store_stats + +Returns quantities of loaded X.509 certificates. + +X.509 certificates with a CA extension and certificate revocation lists +inside the context's cert store. + +NOTE: Certificates in a capath directory aren't loaded unless they have +been used at least once. +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) +/*[clinic end generated code: output=5f356f4d9cca874d input=eb40dd0f6d0e40cf]*/ +{ + X509_STORE *store; + STACK_OF(X509_OBJECT) *objs; + X509_OBJECT *obj; + int x509 = 0, crl = 0, ca = 0, i; + + store = SSL_CTX_get_cert_store(self->ctx); + objs = X509_STORE_get0_objects(store); + for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { + obj = sk_X509_OBJECT_value(objs, i); + switch (X509_OBJECT_get_type(obj)) { + case X509_LU_X509: + x509++; + if (X509_check_ca(X509_OBJECT_get0_X509(obj))) { + ca++; + } + break; + case X509_LU_CRL: + crl++; + break; + default: + /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY. + * As far as I can tell they are internal states and never + * stored in a cert store */ + break; + } + } + return Py_BuildValue("{sisisi}", "x509", x509, "crl", crl, + "x509_ca", ca); +} + +/*[clinic input] +_ssl._SSLContext.get_ca_certs + binary_form: bool = False + +Returns a list of dicts with information of loaded CA certs. + +If the optional argument is True, returns a DER-encoded copy of the CA +certificate. + +NOTE: Certificates in a capath directory aren't loaded unless they have +been used at least once. +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) +/*[clinic end generated code: output=0d58f148f37e2938 input=6887b5a09b7f9076]*/ +{ + X509_STORE *store; + STACK_OF(X509_OBJECT) *objs; + PyObject *ci = NULL, *rlist = NULL; + int i; + + if ((rlist = PyList_New(0)) == NULL) { + return NULL; + } + + store = SSL_CTX_get_cert_store(self->ctx); + objs = X509_STORE_get0_objects(store); + for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { + X509_OBJECT *obj; + X509 *cert; + + obj = sk_X509_OBJECT_value(objs, i); + if (X509_OBJECT_get_type(obj) != X509_LU_X509) { + /* not a x509 cert */ + continue; + } + /* CA for any purpose */ + cert = X509_OBJECT_get0_X509(obj); + if (!X509_check_ca(cert)) { + continue; + } + if (binary_form) { + ci = _certificate_to_der(cert); + } else { + ci = _decode_certificate(cert); + } + if (ci == NULL) { + goto error; + } + if (PyList_Append(rlist, ci) == -1) { + goto error; + } + Py_CLEAR(ci); + } + return rlist; + + error: + Py_XDECREF(ci); + Py_XDECREF(rlist); + return NULL; +} + + +static PyGetSetDef context_getsetlist[] = { + {"check_hostname", (getter) get_check_hostname, + (setter) set_check_hostname, NULL}, + {"_host_flags", (getter) get_host_flags, + (setter) set_host_flags, NULL}, +#if SSL_CTRL_GET_MAX_PROTO_VERSION + {"minimum_version", (getter) get_minimum_version, + (setter) set_minimum_version, NULL}, + {"maximum_version", (getter) get_maximum_version, + (setter) set_maximum_version, NULL}, +#endif +#ifdef HAVE_OPENSSL_KEYLOG + {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, + (setter) _PySSLContext_set_keylog_filename, NULL}, +#endif + {"_msg_callback", (getter) _PySSLContext_get_msg_callback, + (setter) _PySSLContext_set_msg_callback, NULL}, + {"sni_callback", (getter) get_sni_callback, + (setter) set_sni_callback, PySSLContext_sni_callback_doc}, +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) + {"num_tickets", (getter) get_num_tickets, + (setter) set_num_tickets, PySSLContext_num_tickets_doc}, +#endif + {"options", (getter) get_options, + (setter) set_options, NULL}, + {"post_handshake_auth", (getter) get_post_handshake_auth, +#ifdef TLS1_3_VERSION + (setter) set_post_handshake_auth, +#else + NULL, +#endif + NULL}, + {"protocol", (getter) get_protocol, + NULL, NULL}, + {"verify_flags", (getter) get_verify_flags, + (setter) set_verify_flags, NULL}, + {"verify_mode", (getter) get_verify_mode, + (setter) set_verify_mode, NULL}, + {NULL}, /* sentinel */ +}; + +static struct PyMethodDef context_methods[] = { + _SSL__SSLCONTEXT__WRAP_SOCKET_METHODDEF + _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF + _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF + _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF + _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF + _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF + _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF + _SSL__SSLCONTEXT_LOAD_VERIFY_LOCATIONS_METHODDEF + _SSL__SSLCONTEXT_SESSION_STATS_METHODDEF + _SSL__SSLCONTEXT_SET_DEFAULT_VERIFY_PATHS_METHODDEF + _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF + _SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF + _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF + _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject PySSLContext_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ssl._SSLContext", /*tp_name*/ + sizeof(PySSLContext), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)context_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + (traverseproc) context_traverse, /*tp_traverse*/ + (inquiry) context_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + context_methods, /*tp_methods*/ + 0, /*tp_members*/ + context_getsetlist, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + _ssl__SSLContext, /*tp_new*/ +}; + + +/* + * MemoryBIO objects + */ + +/*[clinic input] +@classmethod +_ssl.MemoryBIO.__new__ + +[clinic start generated code]*/ + +static PyObject * +_ssl_MemoryBIO_impl(PyTypeObject *type) +/*[clinic end generated code: output=8820a58db78330ac input=26d22e4909ecb1b5]*/ +{ + BIO *bio; + PySSLMemoryBIO *self; + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + PyErr_SetString(PySSLErrorObject, + "failed to allocate BIO"); + return NULL; + } + /* Since our BIO is non-blocking an empty read() does not indicate EOF, + * just that no data is currently available. The SSL routines should retry + * the read, which we can achieve by calling BIO_set_retry_read(). */ + BIO_set_retry_read(bio); + BIO_set_mem_eof_return(bio, -1); + + assert(type != NULL && type->tp_alloc != NULL); + self = (PySSLMemoryBIO *) type->tp_alloc(type, 0); + if (self == NULL) { + BIO_free(bio); + return NULL; + } + self->bio = bio; + self->eof_written = 0; + + return (PyObject *) self; +} + +static void +memory_bio_dealloc(PySSLMemoryBIO *self) +{ + BIO_free(self->bio); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +memory_bio_get_pending(PySSLMemoryBIO *self, void *c) +{ + return PyLong_FromSize_t(BIO_ctrl_pending(self->bio)); +} + +PyDoc_STRVAR(PySSL_memory_bio_pending_doc, +"The number of bytes pending in the memory BIO."); + +static PyObject * +memory_bio_get_eof(PySSLMemoryBIO *self, void *c) +{ + return PyBool_FromLong((BIO_ctrl_pending(self->bio) == 0) + && self->eof_written); +} + +PyDoc_STRVAR(PySSL_memory_bio_eof_doc, +"Whether the memory BIO is at EOF."); + +/*[clinic input] +_ssl.MemoryBIO.read + size as len: int = -1 + / + +Read up to size bytes from the memory BIO. + +If size is not specified, read the entire buffer. +If the return value is an empty bytes instance, this means either +EOF or that no data is available. Use the "eof" property to +distinguish between the two. +[clinic start generated code]*/ + +static PyObject * +_ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) +/*[clinic end generated code: output=a657aa1e79cd01b3 input=574d7be06a902366]*/ +{ + int avail, nbytes; + PyObject *result; + + avail = (int)Py_MIN(BIO_ctrl_pending(self->bio), INT_MAX); + if ((len < 0) || (len > avail)) + len = avail; + + result = PyBytes_FromStringAndSize(NULL, len); + if ((result == NULL) || (len == 0)) + return result; + + nbytes = BIO_read(self->bio, PyBytes_AS_STRING(result), len); + if (nbytes < 0) { + Py_DECREF(result); + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + + /* There should never be any short reads but check anyway. */ + if (nbytes < len) { + _PyBytes_Resize(&result, nbytes); + } + + return result; +} + +/*[clinic input] +_ssl.MemoryBIO.write + b: Py_buffer + / + +Writes the bytes b into the memory BIO. + +Returns the number of bytes written. +[clinic start generated code]*/ + +static PyObject * +_ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) +/*[clinic end generated code: output=156ec59110d75935 input=e45757b3e17c4808]*/ +{ + int nbytes; + + if (b->len > INT_MAX) { + PyErr_Format(PyExc_OverflowError, + "string longer than %d bytes", INT_MAX); + return NULL; + } + + if (self->eof_written) { + PyErr_SetString(PySSLErrorObject, + "cannot write() after write_eof()"); + return NULL; + } + + nbytes = BIO_write(self->bio, b->buf, (int)b->len); + if (nbytes < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return NULL; + } + + return PyLong_FromLong(nbytes); +} + +/*[clinic input] +_ssl.MemoryBIO.write_eof + +Write an EOF marker to the memory BIO. + +When all data has been read, the "eof" property will be True. +[clinic start generated code]*/ + +static PyObject * +_ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) +/*[clinic end generated code: output=d4106276ccd1ed34 input=56a945f1d29e8bd6]*/ +{ + self->eof_written = 1; + /* After an EOF is written, a zero return from read() should be a real EOF + * i.e. it should not be retried. Clear the SHOULD_RETRY flag. */ + BIO_clear_retry_flags(self->bio); + BIO_set_mem_eof_return(self->bio, 0); + + Py_RETURN_NONE; +} + +static PyGetSetDef memory_bio_getsetlist[] = { + {"pending", (getter) memory_bio_get_pending, NULL, + PySSL_memory_bio_pending_doc}, + {"eof", (getter) memory_bio_get_eof, NULL, + PySSL_memory_bio_eof_doc}, + {NULL}, /* sentinel */ +}; + +static struct PyMethodDef memory_bio_methods[] = { + _SSL_MEMORYBIO_READ_METHODDEF + _SSL_MEMORYBIO_WRITE_METHODDEF + _SSL_MEMORYBIO_WRITE_EOF_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject PySSLMemoryBIO_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ssl.MemoryBIO", /*tp_name*/ + sizeof(PySSLMemoryBIO), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)memory_bio_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + memory_bio_methods, /*tp_methods*/ + 0, /*tp_members*/ + memory_bio_getsetlist, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + _ssl_MemoryBIO, /*tp_new*/ +}; + + +/* + * SSL Session object + */ + +static void +PySSLSession_dealloc(PySSLSession *self) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyObject_GC_UnTrack(self); + Py_XDECREF(self->ctx); + if (self->session != NULL) { + SSL_SESSION_free(self->session); + } + PyObject_GC_Del(self); +} + +static PyObject * +PySSLSession_richcompare(PyObject *left, PyObject *right, int op) +{ + int result; + + if (left == NULL || right == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + if (!PySSLSession_Check(left) || !PySSLSession_Check(right)) { + Py_RETURN_NOTIMPLEMENTED; + } + + if (left == right) { + result = 0; + } else { + const unsigned char *left_id, *right_id; + unsigned int left_len, right_len; + left_id = SSL_SESSION_get_id(((PySSLSession *)left)->session, + &left_len); + right_id = SSL_SESSION_get_id(((PySSLSession *)right)->session, + &right_len); + if (left_len == right_len) { + result = memcmp(left_id, right_id, left_len); + } else { + result = 1; + } + } + + switch (op) { + case Py_EQ: + if (result == 0) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + break; + case Py_NE: + if (result != 0) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + break; + case Py_LT: + case Py_LE: + case Py_GT: + case Py_GE: + Py_RETURN_NOTIMPLEMENTED; + break; + default: + PyErr_BadArgument(); + return NULL; + } +} + +static int +PySSLSession_traverse(PySSLSession *self, visitproc visit, void *arg) +{ + Py_VISIT(self->ctx); + return 0; +} + +static int +PySSLSession_clear(PySSLSession *self) +{ + Py_CLEAR(self->ctx); + return 0; +} + + +static PyObject * +PySSLSession_get_time(PySSLSession *self, void *closure) { + return PyLong_FromLong(SSL_SESSION_get_time(self->session)); +} + +PyDoc_STRVAR(PySSLSession_get_time_doc, +"Session creation time (seconds since epoch)."); + + +static PyObject * +PySSLSession_get_timeout(PySSLSession *self, void *closure) { + return PyLong_FromLong(SSL_SESSION_get_timeout(self->session)); +} + +PyDoc_STRVAR(PySSLSession_get_timeout_doc, +"Session timeout (delta in seconds)."); + + +static PyObject * +PySSLSession_get_ticket_lifetime_hint(PySSLSession *self, void *closure) { + unsigned long hint = SSL_SESSION_get_ticket_lifetime_hint(self->session); + return PyLong_FromUnsignedLong(hint); +} + +PyDoc_STRVAR(PySSLSession_get_ticket_lifetime_hint_doc, +"Ticket life time hint."); + + +static PyObject * +PySSLSession_get_session_id(PySSLSession *self, void *closure) { + const unsigned char *id; + unsigned int len; + id = SSL_SESSION_get_id(self->session, &len); + return PyBytes_FromStringAndSize((const char *)id, len); +} + +PyDoc_STRVAR(PySSLSession_get_session_id_doc, +"Session id"); + + +static PyObject * +PySSLSession_get_has_ticket(PySSLSession *self, void *closure) { + if (SSL_SESSION_has_ticket(self->session)) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +PyDoc_STRVAR(PySSLSession_get_has_ticket_doc, +"Does the session contain a ticket?"); + + +static PyGetSetDef PySSLSession_getsetlist[] = { + {"has_ticket", (getter) PySSLSession_get_has_ticket, NULL, + PySSLSession_get_has_ticket_doc}, + {"id", (getter) PySSLSession_get_session_id, NULL, + PySSLSession_get_session_id_doc}, + {"ticket_lifetime_hint", (getter) PySSLSession_get_ticket_lifetime_hint, + NULL, PySSLSession_get_ticket_lifetime_hint_doc}, + {"time", (getter) PySSLSession_get_time, NULL, + PySSLSession_get_time_doc}, + {"timeout", (getter) PySSLSession_get_timeout, NULL, + PySSLSession_get_timeout_doc}, + {NULL}, /* sentinel */ +}; + +static PyTypeObject PySSLSession_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ssl.Session", /*tp_name*/ + sizeof(PySSLSession), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PySSLSession_dealloc, /*tp_dealloc*/ + 0, /*tp_vectorcall_offset*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_as_async*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + (traverseproc)PySSLSession_traverse, /*tp_traverse*/ + (inquiry)PySSLSession_clear, /*tp_clear*/ + PySSLSession_richcompare, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + PySSLSession_getsetlist, /*tp_getset*/ +}; + + +/* helper routines for seeding the SSL PRNG */ +/*[clinic input] +_ssl.RAND_add + string as view: Py_buffer(accept={str, buffer}) + entropy: double + / + +Mix string into the OpenSSL PRNG state. + +entropy (a float) is a lower bound on the entropy contained in +string. See RFC 4086. +[clinic start generated code]*/ + +static PyObject * +_ssl_RAND_add_impl(PyObject *module, Py_buffer *view, double entropy) +/*[clinic end generated code: output=e6dd48df9c9024e9 input=5c33017422828f5c]*/ +{ + const char *buf; + Py_ssize_t len, written; + + buf = (const char *)view->buf; + len = view->len; + do { + written = Py_MIN(len, INT_MAX); + RAND_add(buf, (int)written, entropy); + buf += written; + len -= written; + } while (len); + Py_RETURN_NONE; +} + +static PyObject * +PySSL_RAND(int len, int pseudo) +{ + int ok; + PyObject *bytes; + unsigned long err; + const char *errstr; + PyObject *v; + + if (len < 0) { + PyErr_SetString(PyExc_ValueError, "num must be positive"); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(NULL, len); + if (bytes == NULL) + return NULL; + if (pseudo) { +#ifdef PY_OPENSSL_1_1_API + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#else + ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#endif + if (ok == 0 || ok == 1) + return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); + } + else { + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); + if (ok == 1) + return bytes; + } + Py_DECREF(bytes); + + err = ERR_get_error(); + errstr = ERR_reason_error_string(err); + v = Py_BuildValue("(ks)", err, errstr); + if (v != NULL) { + PyErr_SetObject(PySSLErrorObject, v); + Py_DECREF(v); + } + return NULL; +} + +/*[clinic input] +_ssl.RAND_bytes + n: int + / + +Generate n cryptographically strong pseudo-random bytes. +[clinic start generated code]*/ + +static PyObject * +_ssl_RAND_bytes_impl(PyObject *module, int n) +/*[clinic end generated code: output=977da635e4838bc7 input=678ddf2872dfebfc]*/ +{ + return PySSL_RAND(n, 0); +} + +/*[clinic input] +_ssl.RAND_pseudo_bytes + n: int + / + +Generate n pseudo-random bytes. + +Return a pair (bytes, is_cryptographic). is_cryptographic is True +if the bytes generated are cryptographically strong. +[clinic start generated code]*/ + +static PyObject * +_ssl_RAND_pseudo_bytes_impl(PyObject *module, int n) +/*[clinic end generated code: output=b1509e937000e52d input=58312bd53f9bbdd0]*/ +{ + return PySSL_RAND(n, 1); +} + +/*[clinic input] +_ssl.RAND_status + +Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not. + +It is necessary to seed the PRNG with RAND_add() on some platforms before +using the ssl() function. +[clinic start generated code]*/ + +static PyObject * +_ssl_RAND_status_impl(PyObject *module) +/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=8a774b02d1dc81f3]*/ +{ + return PyLong_FromLong(RAND_status()); +} + +#ifndef OPENSSL_NO_EGD +/* LCOV_EXCL_START */ +/*[clinic input] +_ssl.RAND_egd + path: object(converter="PyUnicode_FSConverter") + / + +Queries the entropy gather daemon (EGD) on the socket named by 'path'. + +Returns number of bytes read. Raises SSLError if connection to EGD +fails or if it does not provide enough data to seed PRNG. +[clinic start generated code]*/ + +static PyObject * +_ssl_RAND_egd_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=02a67c7c367f52fa input=1aeb7eb948312195]*/ +{ + int bytes = RAND_egd(PyBytes_AsString(path)); + Py_DECREF(path); + if (bytes == -1) { + PyErr_SetString(PySSLErrorObject, + "EGD connection failed or EGD did not return " + "enough data to seed the PRNG"); + return NULL; + } + return PyLong_FromLong(bytes); +} +/* LCOV_EXCL_STOP */ +#endif /* OPENSSL_NO_EGD */ + + + +/*[clinic input] +_ssl.get_default_verify_paths + +Return search paths and environment vars that are used by SSLContext's set_default_verify_paths() to load default CAs. + +The values are 'cert_file_env', 'cert_file', 'cert_dir_env', 'cert_dir'. +[clinic start generated code]*/ + +static PyObject * +_ssl_get_default_verify_paths_impl(PyObject *module) +/*[clinic end generated code: output=e5b62a466271928b input=5210c953d98c3eb5]*/ +{ + PyObject *ofile_env = NULL; + PyObject *ofile = NULL; + PyObject *odir_env = NULL; + PyObject *odir = NULL; + +#define CONVERT(info, target) { \ + const char *tmp = (info); \ + target = NULL; \ + if (!tmp) { Py_INCREF(Py_None); target = Py_None; } \ + else if ((target = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ + target = PyBytes_FromString(tmp); } \ + if (!target) goto error; \ + } + + CONVERT(X509_get_default_cert_file_env(), ofile_env); + CONVERT(X509_get_default_cert_file(), ofile); + CONVERT(X509_get_default_cert_dir_env(), odir_env); + CONVERT(X509_get_default_cert_dir(), odir); +#undef CONVERT + + return Py_BuildValue("NNNN", ofile_env, ofile, odir_env, odir); + + error: + Py_XDECREF(ofile_env); + Py_XDECREF(ofile); + Py_XDECREF(odir_env); + Py_XDECREF(odir); + return NULL; +} + +static PyObject* +asn1obj2py(ASN1_OBJECT *obj) +{ + int nid; + const char *ln, *sn; + + nid = OBJ_obj2nid(obj); + if (nid == NID_undef) { + PyErr_Format(PyExc_ValueError, "Unknown object"); + return NULL; + } + sn = OBJ_nid2sn(nid); + ln = OBJ_nid2ln(nid); + return Py_BuildValue("issN", nid, sn, ln, _asn1obj2py(obj, 1)); +} + +/*[clinic input] +_ssl.txt2obj + txt: str + name: bool = False + +Lookup NID, short name, long name and OID of an ASN1_OBJECT. + +By default objects are looked up by OID. With name=True short and +long name are also matched. +[clinic start generated code]*/ + +static PyObject * +_ssl_txt2obj_impl(PyObject *module, const char *txt, int name) +/*[clinic end generated code: output=c38e3991347079c1 input=1c1e7d0aa7c48602]*/ +{ + PyObject *result = NULL; + ASN1_OBJECT *obj; + + obj = OBJ_txt2obj(txt, name ? 0 : 1); + if (obj == NULL) { + PyErr_Format(PyExc_ValueError, "unknown object '%.100s'", txt); + return NULL; + } + result = asn1obj2py(obj); + ASN1_OBJECT_free(obj); + return result; +} + +/*[clinic input] +_ssl.nid2obj + nid: int + / + +Lookup NID, short name, long name and OID of an ASN1_OBJECT by NID. +[clinic start generated code]*/ + +static PyObject * +_ssl_nid2obj_impl(PyObject *module, int nid) +/*[clinic end generated code: output=4a98ab691cd4f84a input=51787a3bee7d8f98]*/ +{ + PyObject *result = NULL; + ASN1_OBJECT *obj; + + if (nid < NID_undef) { + PyErr_SetString(PyExc_ValueError, "NID must be positive."); + return NULL; + } + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + PyErr_Format(PyExc_ValueError, "unknown NID %i", nid); + return NULL; + } + result = asn1obj2py(obj); + ASN1_OBJECT_free(obj); + return result; +} + +#ifdef _MSC_VER + +static PyObject* +certEncodingType(DWORD encodingType) +{ + static PyObject *x509_asn = NULL; + static PyObject *pkcs_7_asn = NULL; + + if (x509_asn == NULL) { + x509_asn = PyUnicode_InternFromString("x509_asn"); + if (x509_asn == NULL) + return NULL; + } + if (pkcs_7_asn == NULL) { + pkcs_7_asn = PyUnicode_InternFromString("pkcs_7_asn"); + if (pkcs_7_asn == NULL) + return NULL; + } + switch(encodingType) { + case X509_ASN_ENCODING: + Py_INCREF(x509_asn); + return x509_asn; + case PKCS_7_ASN_ENCODING: + Py_INCREF(pkcs_7_asn); + return pkcs_7_asn; + default: + return PyLong_FromLong(encodingType); + } +} + +static PyObject* +parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags) +{ + CERT_ENHKEY_USAGE *usage; + DWORD size, error, i; + PyObject *retval; + + if (!CertGetEnhancedKeyUsage(pCertCtx, flags, NULL, &size)) { + error = GetLastError(); + if (error == CRYPT_E_NOT_FOUND) { + Py_RETURN_TRUE; + } + return PyErr_SetFromWindowsErr(error); + } + + usage = (CERT_ENHKEY_USAGE*)PyMem_Malloc(size); + if (usage == NULL) { + return PyErr_NoMemory(); + } + + /* Now get the actual enhanced usage property */ + if (!CertGetEnhancedKeyUsage(pCertCtx, flags, usage, &size)) { + PyMem_Free(usage); + error = GetLastError(); + if (error == CRYPT_E_NOT_FOUND) { + Py_RETURN_TRUE; + } + return PyErr_SetFromWindowsErr(error); + } + retval = PyFrozenSet_New(NULL); + if (retval == NULL) { + goto error; + } + for (i = 0; i < usage->cUsageIdentifier; ++i) { + if (usage->rgpszUsageIdentifier[i]) { + PyObject *oid; + int err; + oid = PyUnicode_FromString(usage->rgpszUsageIdentifier[i]); + if (oid == NULL) { + Py_CLEAR(retval); + goto error; + } + err = PySet_Add(retval, oid); + Py_DECREF(oid); + if (err == -1) { + Py_CLEAR(retval); + goto error; + } + } + } + error: + PyMem_Free(usage); + return retval; +} + static HCERTSTORE ssl_collect_certificates(const char *store_name) { @@ -5711,94 +5711,94 @@ ssl_collect_certificates(const char *store_name) return hCollectionStore; } -/*[clinic input] -_ssl.enum_certificates - store_name: str - -Retrieve certificates from Windows' cert store. - -store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide -more cert storages, too. The function returns a list of (bytes, -encoding_type, trust) tuples. The encoding_type flag can be interpreted -with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either -a set of OIDs or the boolean True. -[clinic start generated code]*/ - -static PyObject * -_ssl_enum_certificates_impl(PyObject *module, const char *store_name) -/*[clinic end generated code: output=5134dc8bb3a3c893 input=915f60d70461ea4e]*/ -{ +/*[clinic input] +_ssl.enum_certificates + store_name: str + +Retrieve certificates from Windows' cert store. + +store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide +more cert storages, too. The function returns a list of (bytes, +encoding_type, trust) tuples. The encoding_type flag can be interpreted +with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either +a set of OIDs or the boolean True. +[clinic start generated code]*/ + +static PyObject * +_ssl_enum_certificates_impl(PyObject *module, const char *store_name) +/*[clinic end generated code: output=5134dc8bb3a3c893 input=915f60d70461ea4e]*/ +{ HCERTSTORE hCollectionStore = NULL; - PCCERT_CONTEXT pCertCtx = NULL; - PyObject *keyusage = NULL, *cert = NULL, *enc = NULL, *tup = NULL; - PyObject *result = NULL; - + PCCERT_CONTEXT pCertCtx = NULL; + PyObject *keyusage = NULL, *cert = NULL, *enc = NULL, *tup = NULL; + PyObject *result = NULL; + result = PySet_New(NULL); - if (result == NULL) { - return NULL; - } + if (result == NULL) { + return NULL; + } hCollectionStore = ssl_collect_certificates(store_name); if (hCollectionStore == NULL) { - Py_DECREF(result); - return PyErr_SetFromWindowsErr(GetLastError()); - } - + Py_DECREF(result); + return PyErr_SetFromWindowsErr(GetLastError()); + } + while (pCertCtx = CertEnumCertificatesInStore(hCollectionStore, pCertCtx)) { - cert = PyBytes_FromStringAndSize((const char*)pCertCtx->pbCertEncoded, - pCertCtx->cbCertEncoded); - if (!cert) { - Py_CLEAR(result); - break; - } - if ((enc = certEncodingType(pCertCtx->dwCertEncodingType)) == NULL) { - Py_CLEAR(result); - break; - } - keyusage = parseKeyUsage(pCertCtx, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG); - if (keyusage == Py_True) { - Py_DECREF(keyusage); - keyusage = parseKeyUsage(pCertCtx, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG); - } - if (keyusage == NULL) { - Py_CLEAR(result); - break; - } - if ((tup = PyTuple_New(3)) == NULL) { - Py_CLEAR(result); - break; - } - PyTuple_SET_ITEM(tup, 0, cert); - cert = NULL; - PyTuple_SET_ITEM(tup, 1, enc); - enc = NULL; - PyTuple_SET_ITEM(tup, 2, keyusage); - keyusage = NULL; + cert = PyBytes_FromStringAndSize((const char*)pCertCtx->pbCertEncoded, + pCertCtx->cbCertEncoded); + if (!cert) { + Py_CLEAR(result); + break; + } + if ((enc = certEncodingType(pCertCtx->dwCertEncodingType)) == NULL) { + Py_CLEAR(result); + break; + } + keyusage = parseKeyUsage(pCertCtx, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG); + if (keyusage == Py_True) { + Py_DECREF(keyusage); + keyusage = parseKeyUsage(pCertCtx, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG); + } + if (keyusage == NULL) { + Py_CLEAR(result); + break; + } + if ((tup = PyTuple_New(3)) == NULL) { + Py_CLEAR(result); + break; + } + PyTuple_SET_ITEM(tup, 0, cert); + cert = NULL; + PyTuple_SET_ITEM(tup, 1, enc); + enc = NULL; + PyTuple_SET_ITEM(tup, 2, keyusage); + keyusage = NULL; if (PySet_Add(result, tup) == -1) { Py_CLEAR(result); Py_CLEAR(tup); break; - } - Py_CLEAR(tup); - } - if (pCertCtx) { - /* loop ended with an error, need to clean up context manually */ - CertFreeCertificateContext(pCertCtx); - } - - /* In error cases cert, enc and tup may not be NULL */ - Py_XDECREF(cert); - Py_XDECREF(enc); - Py_XDECREF(keyusage); - Py_XDECREF(tup); - + } + Py_CLEAR(tup); + } + if (pCertCtx) { + /* loop ended with an error, need to clean up context manually */ + CertFreeCertificateContext(pCertCtx); + } + + /* In error cases cert, enc and tup may not be NULL */ + Py_XDECREF(cert); + Py_XDECREF(enc); + Py_XDECREF(keyusage); + Py_XDECREF(tup); + /* CERT_CLOSE_STORE_FORCE_FLAG forces freeing of memory for all contexts associated with the store, in this case our collection store and the associated system stores. */ if (!CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_FORCE_FLAG)) { - /* This error case might shadow another exception.*/ - Py_XDECREF(result); - return PyErr_SetFromWindowsErr(GetLastError()); - } + /* This error case might shadow another exception.*/ + Py_XDECREF(result); + return PyErr_SetFromWindowsErr(GetLastError()); + } /* convert set to list */ if (result == NULL) { @@ -5808,84 +5808,84 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) Py_DECREF(result); return lst; } -} - -/*[clinic input] -_ssl.enum_crls - store_name: str - -Retrieve CRLs from Windows' cert store. - -store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide -more cert storages, too. The function returns a list of (bytes, -encoding_type) tuples. The encoding_type flag can be interpreted with -X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. -[clinic start generated code]*/ - -static PyObject * -_ssl_enum_crls_impl(PyObject *module, const char *store_name) -/*[clinic end generated code: output=bce467f60ccd03b6 input=a1f1d7629f1c5d3d]*/ -{ +} + +/*[clinic input] +_ssl.enum_crls + store_name: str + +Retrieve CRLs from Windows' cert store. + +store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide +more cert storages, too. The function returns a list of (bytes, +encoding_type) tuples. The encoding_type flag can be interpreted with +X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. +[clinic start generated code]*/ + +static PyObject * +_ssl_enum_crls_impl(PyObject *module, const char *store_name) +/*[clinic end generated code: output=bce467f60ccd03b6 input=a1f1d7629f1c5d3d]*/ +{ HCERTSTORE hCollectionStore = NULL; - PCCRL_CONTEXT pCrlCtx = NULL; - PyObject *crl = NULL, *enc = NULL, *tup = NULL; - PyObject *result = NULL; - + PCCRL_CONTEXT pCrlCtx = NULL; + PyObject *crl = NULL, *enc = NULL, *tup = NULL; + PyObject *result = NULL; + result = PySet_New(NULL); - if (result == NULL) { - return NULL; - } + if (result == NULL) { + return NULL; + } hCollectionStore = ssl_collect_certificates(store_name); if (hCollectionStore == NULL) { - Py_DECREF(result); - return PyErr_SetFromWindowsErr(GetLastError()); - } - + Py_DECREF(result); + return PyErr_SetFromWindowsErr(GetLastError()); + } + while (pCrlCtx = CertEnumCRLsInStore(hCollectionStore, pCrlCtx)) { - crl = PyBytes_FromStringAndSize((const char*)pCrlCtx->pbCrlEncoded, - pCrlCtx->cbCrlEncoded); - if (!crl) { - Py_CLEAR(result); - break; - } - if ((enc = certEncodingType(pCrlCtx->dwCertEncodingType)) == NULL) { - Py_CLEAR(result); - break; - } - if ((tup = PyTuple_New(2)) == NULL) { - Py_CLEAR(result); - break; - } - PyTuple_SET_ITEM(tup, 0, crl); - crl = NULL; - PyTuple_SET_ITEM(tup, 1, enc); - enc = NULL; - + crl = PyBytes_FromStringAndSize((const char*)pCrlCtx->pbCrlEncoded, + pCrlCtx->cbCrlEncoded); + if (!crl) { + Py_CLEAR(result); + break; + } + if ((enc = certEncodingType(pCrlCtx->dwCertEncodingType)) == NULL) { + Py_CLEAR(result); + break; + } + if ((tup = PyTuple_New(2)) == NULL) { + Py_CLEAR(result); + break; + } + PyTuple_SET_ITEM(tup, 0, crl); + crl = NULL; + PyTuple_SET_ITEM(tup, 1, enc); + enc = NULL; + if (PySet_Add(result, tup) == -1) { Py_CLEAR(result); Py_CLEAR(tup); break; - } - Py_CLEAR(tup); - } - if (pCrlCtx) { - /* loop ended with an error, need to clean up context manually */ - CertFreeCRLContext(pCrlCtx); - } - - /* In error cases cert, enc and tup may not be NULL */ - Py_XDECREF(crl); - Py_XDECREF(enc); - Py_XDECREF(tup); - + } + Py_CLEAR(tup); + } + if (pCrlCtx) { + /* loop ended with an error, need to clean up context manually */ + CertFreeCRLContext(pCrlCtx); + } + + /* In error cases cert, enc and tup may not be NULL */ + Py_XDECREF(crl); + Py_XDECREF(enc); + Py_XDECREF(tup); + /* CERT_CLOSE_STORE_FORCE_FLAG forces freeing of memory for all contexts associated with the store, in this case our collection store and the associated system stores. */ if (!CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_FORCE_FLAG)) { - /* This error case might shadow another exception.*/ - Py_XDECREF(result); - return PyErr_SetFromWindowsErr(GetLastError()); - } + /* This error case might shadow another exception.*/ + Py_XDECREF(result); + return PyErr_SetFromWindowsErr(GetLastError()); + } /* convert set to list */ if (result == NULL) { return NULL; @@ -5894,582 +5894,582 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) Py_DECREF(result); return lst; } -} - -#endif /* _MSC_VER */ - -/* List of functions exported by this module. */ -static PyMethodDef PySSL_methods[] = { - _SSL__TEST_DECODE_CERT_METHODDEF - _SSL_RAND_ADD_METHODDEF - _SSL_RAND_BYTES_METHODDEF - _SSL_RAND_PSEUDO_BYTES_METHODDEF - _SSL_RAND_EGD_METHODDEF - _SSL_RAND_STATUS_METHODDEF - _SSL_GET_DEFAULT_VERIFY_PATHS_METHODDEF - _SSL_ENUM_CERTIFICATES_METHODDEF - _SSL_ENUM_CRLS_METHODDEF - _SSL_TXT2OBJ_METHODDEF - _SSL_NID2OBJ_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - - -#ifdef HAVE_OPENSSL_CRYPTO_LOCK - -/* an implementation of OpenSSL threading operations in terms - * of the Python C thread library - * Only used up to 1.0.2. OpenSSL 1.1.0+ has its own locking code. - */ - -static PyThread_type_lock *_ssl_locks = NULL; - -#if OPENSSL_VERSION_NUMBER >= 0x10000000 -/* use new CRYPTO_THREADID API. */ -static void -_ssl_threadid_callback(CRYPTO_THREADID *id) -{ - CRYPTO_THREADID_set_numeric(id, PyThread_get_thread_ident()); -} -#else -/* deprecated CRYPTO_set_id_callback() API. */ -static unsigned long -_ssl_thread_id_function (void) { - return PyThread_get_thread_ident(); -} -#endif - -static void _ssl_thread_locking_function - (int mode, int n, const char *file, int line) { - /* this function is needed to perform locking on shared data - structures. (Note that OpenSSL uses a number of global data - structures that will be implicitly shared whenever multiple - threads use OpenSSL.) Multi-threaded applications will - crash at random if it is not set. - - locking_function() must be able to handle up to - CRYPTO_num_locks() different mutex locks. It sets the n-th - lock if mode & CRYPTO_LOCK, and releases it otherwise. - - file and line are the file number of the function setting the - lock. They can be useful for debugging. - */ - - if ((_ssl_locks == NULL) || - (n < 0) || ((unsigned)n >= _ssl_locks_count)) - return; - - if (mode & CRYPTO_LOCK) { - PyThread_acquire_lock(_ssl_locks[n], 1); - } else { - PyThread_release_lock(_ssl_locks[n]); - } -} - -static int _setup_ssl_threads(void) { - - unsigned int i; - - if (_ssl_locks == NULL) { - _ssl_locks_count = CRYPTO_num_locks(); - _ssl_locks = PyMem_Calloc(_ssl_locks_count, - sizeof(PyThread_type_lock)); - if (_ssl_locks == NULL) { - PyErr_NoMemory(); - return 0; - } - for (i = 0; i < _ssl_locks_count; i++) { - _ssl_locks[i] = PyThread_allocate_lock(); - if (_ssl_locks[i] == NULL) { - unsigned int j; - for (j = 0; j < i; j++) { - PyThread_free_lock(_ssl_locks[j]); - } - PyMem_Free(_ssl_locks); - return 0; - } - } - CRYPTO_set_locking_callback(_ssl_thread_locking_function); -#if OPENSSL_VERSION_NUMBER >= 0x10000000 - CRYPTO_THREADID_set_callback(_ssl_threadid_callback); -#else - CRYPTO_set_id_callback(_ssl_thread_id_function); -#endif - } - return 1; -} - -#endif /* HAVE_OPENSSL_CRYPTO_LOCK for OpenSSL < 1.1.0 */ - -PyDoc_STRVAR(module_doc, -"Implementation module for SSL socket operations. See the socket module\n\ -for documentation."); - - -static struct PyModuleDef _sslmodule = { - PyModuleDef_HEAD_INIT, - "_ssl", - module_doc, - -1, - PySSL_methods, - NULL, - NULL, - NULL, - NULL -}; - - -static void -parse_openssl_version(unsigned long libver, - unsigned int *major, unsigned int *minor, - unsigned int *fix, unsigned int *patch, - unsigned int *status) -{ - *status = libver & 0xF; - libver >>= 4; - *patch = libver & 0xFF; - libver >>= 8; - *fix = libver & 0xFF; - libver >>= 8; - *minor = libver & 0xFF; - libver >>= 8; - *major = libver & 0xFF; -} - -PyMODINIT_FUNC -PyInit__ssl(void) -{ - PyObject *m, *d, *r, *bases; - unsigned long libver; - unsigned int major, minor, fix, patch, status; - PySocketModule_APIObject *socket_api; - struct py_ssl_error_code *errcode; - struct py_ssl_library_code *libcode; - - if (PyType_Ready(&PySSLContext_Type) < 0) - return NULL; - if (PyType_Ready(&PySSLSocket_Type) < 0) - return NULL; - if (PyType_Ready(&PySSLMemoryBIO_Type) < 0) - return NULL; - if (PyType_Ready(&PySSLSession_Type) < 0) - return NULL; - - - m = PyModule_Create(&_sslmodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - - /* Load _socket module and its C API */ - socket_api = PySocketModule_ImportModuleAndAPI(); - if (!socket_api) - return NULL; - PySocketModule = *socket_api; - -#ifndef OPENSSL_VERSION_1_1 - /* Load all algorithms and initialize cpuid */ - OPENSSL_add_all_algorithms_noconf(); - /* Init OpenSSL */ - SSL_load_error_strings(); - SSL_library_init(); -#endif - -#ifdef HAVE_OPENSSL_CRYPTO_LOCK - /* note that this will start threading if not already started */ - if (!_setup_ssl_threads()) { - return NULL; - } +} + +#endif /* _MSC_VER */ + +/* List of functions exported by this module. */ +static PyMethodDef PySSL_methods[] = { + _SSL__TEST_DECODE_CERT_METHODDEF + _SSL_RAND_ADD_METHODDEF + _SSL_RAND_BYTES_METHODDEF + _SSL_RAND_PSEUDO_BYTES_METHODDEF + _SSL_RAND_EGD_METHODDEF + _SSL_RAND_STATUS_METHODDEF + _SSL_GET_DEFAULT_VERIFY_PATHS_METHODDEF + _SSL_ENUM_CERTIFICATES_METHODDEF + _SSL_ENUM_CRLS_METHODDEF + _SSL_TXT2OBJ_METHODDEF + _SSL_NID2OBJ_METHODDEF + {NULL, NULL} /* Sentinel */ +}; + + +#ifdef HAVE_OPENSSL_CRYPTO_LOCK + +/* an implementation of OpenSSL threading operations in terms + * of the Python C thread library + * Only used up to 1.0.2. OpenSSL 1.1.0+ has its own locking code. + */ + +static PyThread_type_lock *_ssl_locks = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x10000000 +/* use new CRYPTO_THREADID API. */ +static void +_ssl_threadid_callback(CRYPTO_THREADID *id) +{ + CRYPTO_THREADID_set_numeric(id, PyThread_get_thread_ident()); +} +#else +/* deprecated CRYPTO_set_id_callback() API. */ +static unsigned long +_ssl_thread_id_function (void) { + return PyThread_get_thread_ident(); +} +#endif + +static void _ssl_thread_locking_function + (int mode, int n, const char *file, int line) { + /* this function is needed to perform locking on shared data + structures. (Note that OpenSSL uses a number of global data + structures that will be implicitly shared whenever multiple + threads use OpenSSL.) Multi-threaded applications will + crash at random if it is not set. + + locking_function() must be able to handle up to + CRYPTO_num_locks() different mutex locks. It sets the n-th + lock if mode & CRYPTO_LOCK, and releases it otherwise. + + file and line are the file number of the function setting the + lock. They can be useful for debugging. + */ + + if ((_ssl_locks == NULL) || + (n < 0) || ((unsigned)n >= _ssl_locks_count)) + return; + + if (mode & CRYPTO_LOCK) { + PyThread_acquire_lock(_ssl_locks[n], 1); + } else { + PyThread_release_lock(_ssl_locks[n]); + } +} + +static int _setup_ssl_threads(void) { + + unsigned int i; + + if (_ssl_locks == NULL) { + _ssl_locks_count = CRYPTO_num_locks(); + _ssl_locks = PyMem_Calloc(_ssl_locks_count, + sizeof(PyThread_type_lock)); + if (_ssl_locks == NULL) { + PyErr_NoMemory(); + return 0; + } + for (i = 0; i < _ssl_locks_count; i++) { + _ssl_locks[i] = PyThread_allocate_lock(); + if (_ssl_locks[i] == NULL) { + unsigned int j; + for (j = 0; j < i; j++) { + PyThread_free_lock(_ssl_locks[j]); + } + PyMem_Free(_ssl_locks); + return 0; + } + } + CRYPTO_set_locking_callback(_ssl_thread_locking_function); +#if OPENSSL_VERSION_NUMBER >= 0x10000000 + CRYPTO_THREADID_set_callback(_ssl_threadid_callback); +#else + CRYPTO_set_id_callback(_ssl_thread_id_function); +#endif + } + return 1; +} + +#endif /* HAVE_OPENSSL_CRYPTO_LOCK for OpenSSL < 1.1.0 */ + +PyDoc_STRVAR(module_doc, +"Implementation module for SSL socket operations. See the socket module\n\ +for documentation."); + + +static struct PyModuleDef _sslmodule = { + PyModuleDef_HEAD_INIT, + "_ssl", + module_doc, + -1, + PySSL_methods, + NULL, + NULL, + NULL, + NULL +}; + + +static void +parse_openssl_version(unsigned long libver, + unsigned int *major, unsigned int *minor, + unsigned int *fix, unsigned int *patch, + unsigned int *status) +{ + *status = libver & 0xF; + libver >>= 4; + *patch = libver & 0xFF; + libver >>= 8; + *fix = libver & 0xFF; + libver >>= 8; + *minor = libver & 0xFF; + libver >>= 8; + *major = libver & 0xFF; +} + +PyMODINIT_FUNC +PyInit__ssl(void) +{ + PyObject *m, *d, *r, *bases; + unsigned long libver; + unsigned int major, minor, fix, patch, status; + PySocketModule_APIObject *socket_api; + struct py_ssl_error_code *errcode; + struct py_ssl_library_code *libcode; + + if (PyType_Ready(&PySSLContext_Type) < 0) + return NULL; + if (PyType_Ready(&PySSLSocket_Type) < 0) + return NULL; + if (PyType_Ready(&PySSLMemoryBIO_Type) < 0) + return NULL; + if (PyType_Ready(&PySSLSession_Type) < 0) + return NULL; + + + m = PyModule_Create(&_sslmodule); + if (m == NULL) + return NULL; + d = PyModule_GetDict(m); + + /* Load _socket module and its C API */ + socket_api = PySocketModule_ImportModuleAndAPI(); + if (!socket_api) + return NULL; + PySocketModule = *socket_api; + +#ifndef OPENSSL_VERSION_1_1 + /* Load all algorithms and initialize cpuid */ + OPENSSL_add_all_algorithms_noconf(); + /* Init OpenSSL */ + SSL_load_error_strings(); + SSL_library_init(); +#endif + +#ifdef HAVE_OPENSSL_CRYPTO_LOCK + /* note that this will start threading if not already started */ + if (!_setup_ssl_threads()) { + return NULL; + } #elif OPENSSL_VERSION_1_1 - /* OpenSSL 1.1.0 builtin thread support is enabled */ - _ssl_locks_count++; -#endif - - /* Add symbols to module dict */ - sslerror_type_slots[0].pfunc = PyExc_OSError; - PySSLErrorObject = PyType_FromSpec(&sslerror_type_spec); - if (PySSLErrorObject == NULL) - return NULL; - - /* ssl.CertificateError used to be a subclass of ValueError */ - bases = Py_BuildValue("OO", PySSLErrorObject, PyExc_ValueError); - if (bases == NULL) - return NULL; - PySSLCertVerificationErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLCertVerificationError", SSLCertVerificationError_doc, - bases, NULL); - Py_DECREF(bases); - PySSLZeroReturnErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLZeroReturnError", SSLZeroReturnError_doc, - PySSLErrorObject, NULL); - PySSLWantReadErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLWantReadError", SSLWantReadError_doc, - PySSLErrorObject, NULL); - PySSLWantWriteErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLWantWriteError", SSLWantWriteError_doc, - PySSLErrorObject, NULL); - PySSLSyscallErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLSyscallError", SSLSyscallError_doc, - PySSLErrorObject, NULL); - PySSLEOFErrorObject = PyErr_NewExceptionWithDoc( - "ssl.SSLEOFError", SSLEOFError_doc, - PySSLErrorObject, NULL); - if (PySSLCertVerificationErrorObject == NULL - || PySSLZeroReturnErrorObject == NULL - || PySSLWantReadErrorObject == NULL - || PySSLWantWriteErrorObject == NULL - || PySSLSyscallErrorObject == NULL - || PySSLEOFErrorObject == NULL) - return NULL; - if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0 - || PyDict_SetItemString(d, "SSLCertVerificationError", - PySSLCertVerificationErrorObject) != 0 - || PyDict_SetItemString(d, "SSLZeroReturnError", PySSLZeroReturnErrorObject) != 0 - || PyDict_SetItemString(d, "SSLWantReadError", PySSLWantReadErrorObject) != 0 - || PyDict_SetItemString(d, "SSLWantWriteError", PySSLWantWriteErrorObject) != 0 - || PyDict_SetItemString(d, "SSLSyscallError", PySSLSyscallErrorObject) != 0 - || PyDict_SetItemString(d, "SSLEOFError", PySSLEOFErrorObject) != 0) - return NULL; - if (PyDict_SetItemString(d, "_SSLContext", - (PyObject *)&PySSLContext_Type) != 0) - return NULL; - if (PyDict_SetItemString(d, "_SSLSocket", - (PyObject *)&PySSLSocket_Type) != 0) - return NULL; - if (PyDict_SetItemString(d, "MemoryBIO", - (PyObject *)&PySSLMemoryBIO_Type) != 0) - return NULL; - if (PyDict_SetItemString(d, "SSLSession", - (PyObject *)&PySSLSession_Type) != 0) - return NULL; - - PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS", - PY_SSL_DEFAULT_CIPHER_STRING); - - PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", - PY_SSL_ERROR_ZERO_RETURN); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", - PY_SSL_ERROR_WANT_READ); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", - PY_SSL_ERROR_WANT_WRITE); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", - PY_SSL_ERROR_WANT_X509_LOOKUP); - PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", - PY_SSL_ERROR_SYSCALL); - PyModule_AddIntConstant(m, "SSL_ERROR_SSL", - PY_SSL_ERROR_SSL); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT", - PY_SSL_ERROR_WANT_CONNECT); - /* non ssl.h errorcodes */ - PyModule_AddIntConstant(m, "SSL_ERROR_EOF", - PY_SSL_ERROR_EOF); - PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE", - PY_SSL_ERROR_INVALID_ERROR_CODE); - /* cert requirements */ - PyModule_AddIntConstant(m, "CERT_NONE", - PY_SSL_CERT_NONE); - PyModule_AddIntConstant(m, "CERT_OPTIONAL", - PY_SSL_CERT_OPTIONAL); - PyModule_AddIntConstant(m, "CERT_REQUIRED", - PY_SSL_CERT_REQUIRED); - /* CRL verification for verification_flags */ - PyModule_AddIntConstant(m, "VERIFY_DEFAULT", - 0); - PyModule_AddIntConstant(m, "VERIFY_CRL_CHECK_LEAF", - X509_V_FLAG_CRL_CHECK); - PyModule_AddIntConstant(m, "VERIFY_CRL_CHECK_CHAIN", - X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); - PyModule_AddIntConstant(m, "VERIFY_X509_STRICT", - X509_V_FLAG_X509_STRICT); -#ifdef X509_V_FLAG_TRUSTED_FIRST - PyModule_AddIntConstant(m, "VERIFY_X509_TRUSTED_FIRST", - X509_V_FLAG_TRUSTED_FIRST); -#endif - - /* Alert Descriptions from ssl.h */ - /* note RESERVED constants no longer intended for use have been removed */ - /* http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6 */ - -#define ADD_AD_CONSTANT(s) \ - PyModule_AddIntConstant(m, "ALERT_DESCRIPTION_"#s, \ - SSL_AD_##s) - - ADD_AD_CONSTANT(CLOSE_NOTIFY); - ADD_AD_CONSTANT(UNEXPECTED_MESSAGE); - ADD_AD_CONSTANT(BAD_RECORD_MAC); - ADD_AD_CONSTANT(RECORD_OVERFLOW); - ADD_AD_CONSTANT(DECOMPRESSION_FAILURE); - ADD_AD_CONSTANT(HANDSHAKE_FAILURE); - ADD_AD_CONSTANT(BAD_CERTIFICATE); - ADD_AD_CONSTANT(UNSUPPORTED_CERTIFICATE); - ADD_AD_CONSTANT(CERTIFICATE_REVOKED); - ADD_AD_CONSTANT(CERTIFICATE_EXPIRED); - ADD_AD_CONSTANT(CERTIFICATE_UNKNOWN); - ADD_AD_CONSTANT(ILLEGAL_PARAMETER); - ADD_AD_CONSTANT(UNKNOWN_CA); - ADD_AD_CONSTANT(ACCESS_DENIED); - ADD_AD_CONSTANT(DECODE_ERROR); - ADD_AD_CONSTANT(DECRYPT_ERROR); - ADD_AD_CONSTANT(PROTOCOL_VERSION); - ADD_AD_CONSTANT(INSUFFICIENT_SECURITY); - ADD_AD_CONSTANT(INTERNAL_ERROR); - ADD_AD_CONSTANT(USER_CANCELLED); - ADD_AD_CONSTANT(NO_RENEGOTIATION); - /* Not all constants are in old OpenSSL versions */ -#ifdef SSL_AD_UNSUPPORTED_EXTENSION - ADD_AD_CONSTANT(UNSUPPORTED_EXTENSION); -#endif -#ifdef SSL_AD_CERTIFICATE_UNOBTAINABLE - ADD_AD_CONSTANT(CERTIFICATE_UNOBTAINABLE); -#endif -#ifdef SSL_AD_UNRECOGNIZED_NAME - ADD_AD_CONSTANT(UNRECOGNIZED_NAME); -#endif -#ifdef SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE - ADD_AD_CONSTANT(BAD_CERTIFICATE_STATUS_RESPONSE); -#endif -#ifdef SSL_AD_BAD_CERTIFICATE_HASH_VALUE - ADD_AD_CONSTANT(BAD_CERTIFICATE_HASH_VALUE); -#endif -#ifdef SSL_AD_UNKNOWN_PSK_IDENTITY - ADD_AD_CONSTANT(UNKNOWN_PSK_IDENTITY); -#endif - -#undef ADD_AD_CONSTANT - - /* protocol versions */ -#ifndef OPENSSL_NO_SSL2 - PyModule_AddIntConstant(m, "PROTOCOL_SSLv2", - PY_SSL_VERSION_SSL2); -#endif -#ifndef OPENSSL_NO_SSL3 - PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", - PY_SSL_VERSION_SSL3); -#endif - PyModule_AddIntConstant(m, "PROTOCOL_SSLv23", - PY_SSL_VERSION_TLS); - PyModule_AddIntConstant(m, "PROTOCOL_TLS", - PY_SSL_VERSION_TLS); - PyModule_AddIntConstant(m, "PROTOCOL_TLS_CLIENT", - PY_SSL_VERSION_TLS_CLIENT); - PyModule_AddIntConstant(m, "PROTOCOL_TLS_SERVER", - PY_SSL_VERSION_TLS_SERVER); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", - PY_SSL_VERSION_TLS1); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_1", - PY_SSL_VERSION_TLS1_1); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2", - PY_SSL_VERSION_TLS1_2); - - /* protocol options */ - PyModule_AddIntConstant(m, "OP_ALL", - SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); - PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); - PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); - PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); - PyModule_AddIntConstant(m, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1); - PyModule_AddIntConstant(m, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2); -#ifdef SSL_OP_NO_TLSv1_3 - PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3); -#else - PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", 0); -#endif - PyModule_AddIntConstant(m, "OP_CIPHER_SERVER_PREFERENCE", - SSL_OP_CIPHER_SERVER_PREFERENCE); - PyModule_AddIntConstant(m, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE); - PyModule_AddIntConstant(m, "OP_NO_TICKET", SSL_OP_NO_TICKET); -#ifdef SSL_OP_SINGLE_ECDH_USE - PyModule_AddIntConstant(m, "OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE); -#endif -#ifdef SSL_OP_NO_COMPRESSION - PyModule_AddIntConstant(m, "OP_NO_COMPRESSION", - SSL_OP_NO_COMPRESSION); -#endif -#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT - PyModule_AddIntConstant(m, "OP_ENABLE_MIDDLEBOX_COMPAT", - SSL_OP_ENABLE_MIDDLEBOX_COMPAT); -#endif -#ifdef SSL_OP_NO_RENEGOTIATION - PyModule_AddIntConstant(m, "OP_NO_RENEGOTIATION", - SSL_OP_NO_RENEGOTIATION); -#endif + /* OpenSSL 1.1.0 builtin thread support is enabled */ + _ssl_locks_count++; +#endif + + /* Add symbols to module dict */ + sslerror_type_slots[0].pfunc = PyExc_OSError; + PySSLErrorObject = PyType_FromSpec(&sslerror_type_spec); + if (PySSLErrorObject == NULL) + return NULL; + + /* ssl.CertificateError used to be a subclass of ValueError */ + bases = Py_BuildValue("OO", PySSLErrorObject, PyExc_ValueError); + if (bases == NULL) + return NULL; + PySSLCertVerificationErrorObject = PyErr_NewExceptionWithDoc( + "ssl.SSLCertVerificationError", SSLCertVerificationError_doc, + bases, NULL); + Py_DECREF(bases); + PySSLZeroReturnErrorObject = PyErr_NewExceptionWithDoc( + "ssl.SSLZeroReturnError", SSLZeroReturnError_doc, + PySSLErrorObject, NULL); + PySSLWantReadErrorObject = PyErr_NewExceptionWithDoc( + "ssl.SSLWantReadError", SSLWantReadError_doc, + PySSLErrorObject, NULL); + PySSLWantWriteErrorObject = PyErr_NewExceptionWithDoc( + "ssl.SSLWantWriteError", SSLWantWriteError_doc, + PySSLErrorObject, NULL); + PySSLSyscallErrorObject = PyErr_NewExceptionWithDoc( + "ssl.SSLSyscallError", SSLSyscallError_doc, + PySSLErrorObject, NULL); + PySSLEOFErrorObject = PyErr_NewExceptionWithDoc( + "ssl.SSLEOFError", SSLEOFError_doc, + PySSLErrorObject, NULL); + if (PySSLCertVerificationErrorObject == NULL + || PySSLZeroReturnErrorObject == NULL + || PySSLWantReadErrorObject == NULL + || PySSLWantWriteErrorObject == NULL + || PySSLSyscallErrorObject == NULL + || PySSLEOFErrorObject == NULL) + return NULL; + if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0 + || PyDict_SetItemString(d, "SSLCertVerificationError", + PySSLCertVerificationErrorObject) != 0 + || PyDict_SetItemString(d, "SSLZeroReturnError", PySSLZeroReturnErrorObject) != 0 + || PyDict_SetItemString(d, "SSLWantReadError", PySSLWantReadErrorObject) != 0 + || PyDict_SetItemString(d, "SSLWantWriteError", PySSLWantWriteErrorObject) != 0 + || PyDict_SetItemString(d, "SSLSyscallError", PySSLSyscallErrorObject) != 0 + || PyDict_SetItemString(d, "SSLEOFError", PySSLEOFErrorObject) != 0) + return NULL; + if (PyDict_SetItemString(d, "_SSLContext", + (PyObject *)&PySSLContext_Type) != 0) + return NULL; + if (PyDict_SetItemString(d, "_SSLSocket", + (PyObject *)&PySSLSocket_Type) != 0) + return NULL; + if (PyDict_SetItemString(d, "MemoryBIO", + (PyObject *)&PySSLMemoryBIO_Type) != 0) + return NULL; + if (PyDict_SetItemString(d, "SSLSession", + (PyObject *)&PySSLSession_Type) != 0) + return NULL; + + PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS", + PY_SSL_DEFAULT_CIPHER_STRING); + + PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", + PY_SSL_ERROR_ZERO_RETURN); + PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", + PY_SSL_ERROR_WANT_READ); + PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", + PY_SSL_ERROR_WANT_WRITE); + PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", + PY_SSL_ERROR_WANT_X509_LOOKUP); + PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", + PY_SSL_ERROR_SYSCALL); + PyModule_AddIntConstant(m, "SSL_ERROR_SSL", + PY_SSL_ERROR_SSL); + PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT", + PY_SSL_ERROR_WANT_CONNECT); + /* non ssl.h errorcodes */ + PyModule_AddIntConstant(m, "SSL_ERROR_EOF", + PY_SSL_ERROR_EOF); + PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE", + PY_SSL_ERROR_INVALID_ERROR_CODE); + /* cert requirements */ + PyModule_AddIntConstant(m, "CERT_NONE", + PY_SSL_CERT_NONE); + PyModule_AddIntConstant(m, "CERT_OPTIONAL", + PY_SSL_CERT_OPTIONAL); + PyModule_AddIntConstant(m, "CERT_REQUIRED", + PY_SSL_CERT_REQUIRED); + /* CRL verification for verification_flags */ + PyModule_AddIntConstant(m, "VERIFY_DEFAULT", + 0); + PyModule_AddIntConstant(m, "VERIFY_CRL_CHECK_LEAF", + X509_V_FLAG_CRL_CHECK); + PyModule_AddIntConstant(m, "VERIFY_CRL_CHECK_CHAIN", + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + PyModule_AddIntConstant(m, "VERIFY_X509_STRICT", + X509_V_FLAG_X509_STRICT); +#ifdef X509_V_FLAG_TRUSTED_FIRST + PyModule_AddIntConstant(m, "VERIFY_X509_TRUSTED_FIRST", + X509_V_FLAG_TRUSTED_FIRST); +#endif + + /* Alert Descriptions from ssl.h */ + /* note RESERVED constants no longer intended for use have been removed */ + /* http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6 */ + +#define ADD_AD_CONSTANT(s) \ + PyModule_AddIntConstant(m, "ALERT_DESCRIPTION_"#s, \ + SSL_AD_##s) + + ADD_AD_CONSTANT(CLOSE_NOTIFY); + ADD_AD_CONSTANT(UNEXPECTED_MESSAGE); + ADD_AD_CONSTANT(BAD_RECORD_MAC); + ADD_AD_CONSTANT(RECORD_OVERFLOW); + ADD_AD_CONSTANT(DECOMPRESSION_FAILURE); + ADD_AD_CONSTANT(HANDSHAKE_FAILURE); + ADD_AD_CONSTANT(BAD_CERTIFICATE); + ADD_AD_CONSTANT(UNSUPPORTED_CERTIFICATE); + ADD_AD_CONSTANT(CERTIFICATE_REVOKED); + ADD_AD_CONSTANT(CERTIFICATE_EXPIRED); + ADD_AD_CONSTANT(CERTIFICATE_UNKNOWN); + ADD_AD_CONSTANT(ILLEGAL_PARAMETER); + ADD_AD_CONSTANT(UNKNOWN_CA); + ADD_AD_CONSTANT(ACCESS_DENIED); + ADD_AD_CONSTANT(DECODE_ERROR); + ADD_AD_CONSTANT(DECRYPT_ERROR); + ADD_AD_CONSTANT(PROTOCOL_VERSION); + ADD_AD_CONSTANT(INSUFFICIENT_SECURITY); + ADD_AD_CONSTANT(INTERNAL_ERROR); + ADD_AD_CONSTANT(USER_CANCELLED); + ADD_AD_CONSTANT(NO_RENEGOTIATION); + /* Not all constants are in old OpenSSL versions */ +#ifdef SSL_AD_UNSUPPORTED_EXTENSION + ADD_AD_CONSTANT(UNSUPPORTED_EXTENSION); +#endif +#ifdef SSL_AD_CERTIFICATE_UNOBTAINABLE + ADD_AD_CONSTANT(CERTIFICATE_UNOBTAINABLE); +#endif +#ifdef SSL_AD_UNRECOGNIZED_NAME + ADD_AD_CONSTANT(UNRECOGNIZED_NAME); +#endif +#ifdef SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE + ADD_AD_CONSTANT(BAD_CERTIFICATE_STATUS_RESPONSE); +#endif +#ifdef SSL_AD_BAD_CERTIFICATE_HASH_VALUE + ADD_AD_CONSTANT(BAD_CERTIFICATE_HASH_VALUE); +#endif +#ifdef SSL_AD_UNKNOWN_PSK_IDENTITY + ADD_AD_CONSTANT(UNKNOWN_PSK_IDENTITY); +#endif + +#undef ADD_AD_CONSTANT + + /* protocol versions */ +#ifndef OPENSSL_NO_SSL2 + PyModule_AddIntConstant(m, "PROTOCOL_SSLv2", + PY_SSL_VERSION_SSL2); +#endif +#ifndef OPENSSL_NO_SSL3 + PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", + PY_SSL_VERSION_SSL3); +#endif + PyModule_AddIntConstant(m, "PROTOCOL_SSLv23", + PY_SSL_VERSION_TLS); + PyModule_AddIntConstant(m, "PROTOCOL_TLS", + PY_SSL_VERSION_TLS); + PyModule_AddIntConstant(m, "PROTOCOL_TLS_CLIENT", + PY_SSL_VERSION_TLS_CLIENT); + PyModule_AddIntConstant(m, "PROTOCOL_TLS_SERVER", + PY_SSL_VERSION_TLS_SERVER); + PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", + PY_SSL_VERSION_TLS1); + PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_1", + PY_SSL_VERSION_TLS1_1); + PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2", + PY_SSL_VERSION_TLS1_2); + + /* protocol options */ + PyModule_AddIntConstant(m, "OP_ALL", + SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); + PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); + PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); + PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); + PyModule_AddIntConstant(m, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1); + PyModule_AddIntConstant(m, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2); +#ifdef SSL_OP_NO_TLSv1_3 + PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3); +#else + PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", 0); +#endif + PyModule_AddIntConstant(m, "OP_CIPHER_SERVER_PREFERENCE", + SSL_OP_CIPHER_SERVER_PREFERENCE); + PyModule_AddIntConstant(m, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE); + PyModule_AddIntConstant(m, "OP_NO_TICKET", SSL_OP_NO_TICKET); +#ifdef SSL_OP_SINGLE_ECDH_USE + PyModule_AddIntConstant(m, "OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE); +#endif +#ifdef SSL_OP_NO_COMPRESSION + PyModule_AddIntConstant(m, "OP_NO_COMPRESSION", + SSL_OP_NO_COMPRESSION); +#endif +#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT + PyModule_AddIntConstant(m, "OP_ENABLE_MIDDLEBOX_COMPAT", + SSL_OP_ENABLE_MIDDLEBOX_COMPAT); +#endif +#ifdef SSL_OP_NO_RENEGOTIATION + PyModule_AddIntConstant(m, "OP_NO_RENEGOTIATION", + SSL_OP_NO_RENEGOTIATION); +#endif #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF PyModule_AddIntConstant(m, "OP_IGNORE_UNEXPECTED_EOF", SSL_OP_IGNORE_UNEXPECTED_EOF); #endif - -#ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT - PyModule_AddIntConstant(m, "HOSTFLAG_ALWAYS_CHECK_SUBJECT", - X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT); -#endif -#ifdef X509_CHECK_FLAG_NEVER_CHECK_SUBJECT - PyModule_AddIntConstant(m, "HOSTFLAG_NEVER_CHECK_SUBJECT", - X509_CHECK_FLAG_NEVER_CHECK_SUBJECT); -#endif -#ifdef X509_CHECK_FLAG_NO_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_NO_WILDCARDS", - X509_CHECK_FLAG_NO_WILDCARDS); -#endif -#ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_NO_PARTIAL_WILDCARDS", - X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); -#endif -#ifdef X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_MULTI_LABEL_WILDCARDS", - X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS); -#endif -#ifdef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS - PyModule_AddIntConstant(m, "HOSTFLAG_SINGLE_LABEL_SUBDOMAINS", - X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); -#endif - - /* protocol versions */ - PyModule_AddIntConstant(m, "PROTO_MINIMUM_SUPPORTED", - PY_PROTO_MINIMUM_SUPPORTED); - PyModule_AddIntConstant(m, "PROTO_MAXIMUM_SUPPORTED", - PY_PROTO_MAXIMUM_SUPPORTED); - PyModule_AddIntConstant(m, "PROTO_SSLv3", PY_PROTO_SSLv3); - PyModule_AddIntConstant(m, "PROTO_TLSv1", PY_PROTO_TLSv1); - PyModule_AddIntConstant(m, "PROTO_TLSv1_1", PY_PROTO_TLSv1_1); - PyModule_AddIntConstant(m, "PROTO_TLSv1_2", PY_PROTO_TLSv1_2); - PyModule_AddIntConstant(m, "PROTO_TLSv1_3", PY_PROTO_TLSv1_3); - + +#ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT + PyModule_AddIntConstant(m, "HOSTFLAG_ALWAYS_CHECK_SUBJECT", + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT); +#endif +#ifdef X509_CHECK_FLAG_NEVER_CHECK_SUBJECT + PyModule_AddIntConstant(m, "HOSTFLAG_NEVER_CHECK_SUBJECT", + X509_CHECK_FLAG_NEVER_CHECK_SUBJECT); +#endif +#ifdef X509_CHECK_FLAG_NO_WILDCARDS + PyModule_AddIntConstant(m, "HOSTFLAG_NO_WILDCARDS", + X509_CHECK_FLAG_NO_WILDCARDS); +#endif +#ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS + PyModule_AddIntConstant(m, "HOSTFLAG_NO_PARTIAL_WILDCARDS", + X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); +#endif +#ifdef X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS + PyModule_AddIntConstant(m, "HOSTFLAG_MULTI_LABEL_WILDCARDS", + X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS); +#endif +#ifdef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS + PyModule_AddIntConstant(m, "HOSTFLAG_SINGLE_LABEL_SUBDOMAINS", + X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); +#endif + + /* protocol versions */ + PyModule_AddIntConstant(m, "PROTO_MINIMUM_SUPPORTED", + PY_PROTO_MINIMUM_SUPPORTED); + PyModule_AddIntConstant(m, "PROTO_MAXIMUM_SUPPORTED", + PY_PROTO_MAXIMUM_SUPPORTED); + PyModule_AddIntConstant(m, "PROTO_SSLv3", PY_PROTO_SSLv3); + PyModule_AddIntConstant(m, "PROTO_TLSv1", PY_PROTO_TLSv1); + PyModule_AddIntConstant(m, "PROTO_TLSv1_1", PY_PROTO_TLSv1_1); + PyModule_AddIntConstant(m, "PROTO_TLSv1_2", PY_PROTO_TLSv1_2); + PyModule_AddIntConstant(m, "PROTO_TLSv1_3", PY_PROTO_TLSv1_3); + #define addbool(m, key, value) \ do { \ PyObject *bool_obj = (value) ? Py_True : Py_False; \ Py_INCREF(bool_obj); \ PyModule_AddObject((m), (key), bool_obj); \ } while (0) - -#if HAVE_SNI - addbool(m, "HAS_SNI", 1); -#else - addbool(m, "HAS_SNI", 0); -#endif - - addbool(m, "HAS_TLS_UNIQUE", 1); - -#ifndef OPENSSL_NO_ECDH - addbool(m, "HAS_ECDH", 1); -#else - addbool(m, "HAS_ECDH", 0); -#endif - -#if HAVE_NPN - addbool(m, "HAS_NPN", 1); -#else - addbool(m, "HAS_NPN", 0); -#endif - -#if HAVE_ALPN - addbool(m, "HAS_ALPN", 1); -#else - addbool(m, "HAS_ALPN", 0); -#endif - -#if defined(SSL2_VERSION) && !defined(OPENSSL_NO_SSL2) - addbool(m, "HAS_SSLv2", 1); -#else - addbool(m, "HAS_SSLv2", 0); -#endif - -#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) - addbool(m, "HAS_SSLv3", 1); -#else - addbool(m, "HAS_SSLv3", 0); -#endif - -#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) - addbool(m, "HAS_TLSv1", 1); -#else - addbool(m, "HAS_TLSv1", 0); -#endif - -#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) - addbool(m, "HAS_TLSv1_1", 1); -#else - addbool(m, "HAS_TLSv1_1", 0); -#endif - -#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) - addbool(m, "HAS_TLSv1_2", 1); -#else - addbool(m, "HAS_TLSv1_2", 0); -#endif - -#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) - addbool(m, "HAS_TLSv1_3", 1); -#else - addbool(m, "HAS_TLSv1_3", 0); -#endif - - /* Mappings for error codes */ - err_codes_to_names = PyDict_New(); - err_names_to_codes = PyDict_New(); - if (err_codes_to_names == NULL || err_names_to_codes == NULL) - return NULL; - errcode = error_codes; - while (errcode->mnemonic != NULL) { - PyObject *mnemo, *key; - mnemo = PyUnicode_FromString(errcode->mnemonic); - key = Py_BuildValue("ii", errcode->library, errcode->reason); - if (mnemo == NULL || key == NULL) - return NULL; - if (PyDict_SetItem(err_codes_to_names, key, mnemo)) - return NULL; - if (PyDict_SetItem(err_names_to_codes, mnemo, key)) - return NULL; - Py_DECREF(key); - Py_DECREF(mnemo); - errcode++; - } - if (PyModule_AddObject(m, "err_codes_to_names", err_codes_to_names)) - return NULL; - if (PyModule_AddObject(m, "err_names_to_codes", err_names_to_codes)) - return NULL; - - lib_codes_to_names = PyDict_New(); - if (lib_codes_to_names == NULL) - return NULL; - libcode = library_codes; - while (libcode->library != NULL) { - PyObject *mnemo, *key; - key = PyLong_FromLong(libcode->code); - mnemo = PyUnicode_FromString(libcode->library); - if (key == NULL || mnemo == NULL) - return NULL; - if (PyDict_SetItem(lib_codes_to_names, key, mnemo)) - return NULL; - Py_DECREF(key); - Py_DECREF(mnemo); - libcode++; - } - if (PyModule_AddObject(m, "lib_codes_to_names", lib_codes_to_names)) - return NULL; - - /* OpenSSL version */ - /* SSLeay() gives us the version of the library linked against, - which could be different from the headers version. - */ + +#if HAVE_SNI + addbool(m, "HAS_SNI", 1); +#else + addbool(m, "HAS_SNI", 0); +#endif + + addbool(m, "HAS_TLS_UNIQUE", 1); + +#ifndef OPENSSL_NO_ECDH + addbool(m, "HAS_ECDH", 1); +#else + addbool(m, "HAS_ECDH", 0); +#endif + +#if HAVE_NPN + addbool(m, "HAS_NPN", 1); +#else + addbool(m, "HAS_NPN", 0); +#endif + +#if HAVE_ALPN + addbool(m, "HAS_ALPN", 1); +#else + addbool(m, "HAS_ALPN", 0); +#endif + +#if defined(SSL2_VERSION) && !defined(OPENSSL_NO_SSL2) + addbool(m, "HAS_SSLv2", 1); +#else + addbool(m, "HAS_SSLv2", 0); +#endif + +#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) + addbool(m, "HAS_SSLv3", 1); +#else + addbool(m, "HAS_SSLv3", 0); +#endif + +#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) + addbool(m, "HAS_TLSv1", 1); +#else + addbool(m, "HAS_TLSv1", 0); +#endif + +#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) + addbool(m, "HAS_TLSv1_1", 1); +#else + addbool(m, "HAS_TLSv1_1", 0); +#endif + +#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) + addbool(m, "HAS_TLSv1_2", 1); +#else + addbool(m, "HAS_TLSv1_2", 0); +#endif + +#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) + addbool(m, "HAS_TLSv1_3", 1); +#else + addbool(m, "HAS_TLSv1_3", 0); +#endif + + /* Mappings for error codes */ + err_codes_to_names = PyDict_New(); + err_names_to_codes = PyDict_New(); + if (err_codes_to_names == NULL || err_names_to_codes == NULL) + return NULL; + errcode = error_codes; + while (errcode->mnemonic != NULL) { + PyObject *mnemo, *key; + mnemo = PyUnicode_FromString(errcode->mnemonic); + key = Py_BuildValue("ii", errcode->library, errcode->reason); + if (mnemo == NULL || key == NULL) + return NULL; + if (PyDict_SetItem(err_codes_to_names, key, mnemo)) + return NULL; + if (PyDict_SetItem(err_names_to_codes, mnemo, key)) + return NULL; + Py_DECREF(key); + Py_DECREF(mnemo); + errcode++; + } + if (PyModule_AddObject(m, "err_codes_to_names", err_codes_to_names)) + return NULL; + if (PyModule_AddObject(m, "err_names_to_codes", err_names_to_codes)) + return NULL; + + lib_codes_to_names = PyDict_New(); + if (lib_codes_to_names == NULL) + return NULL; + libcode = library_codes; + while (libcode->library != NULL) { + PyObject *mnemo, *key; + key = PyLong_FromLong(libcode->code); + mnemo = PyUnicode_FromString(libcode->library); + if (key == NULL || mnemo == NULL) + return NULL; + if (PyDict_SetItem(lib_codes_to_names, key, mnemo)) + return NULL; + Py_DECREF(key); + Py_DECREF(mnemo); + libcode++; + } + if (PyModule_AddObject(m, "lib_codes_to_names", lib_codes_to_names)) + return NULL; + + /* OpenSSL version */ + /* SSLeay() gives us the version of the library linked against, + which could be different from the headers version. + */ libver = OpenSSL_version_num(); - r = PyLong_FromUnsignedLong(libver); - if (r == NULL) - return NULL; - if (PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r)) - return NULL; - parse_openssl_version(libver, &major, &minor, &fix, &patch, &status); - r = Py_BuildValue("IIIII", major, minor, fix, patch, status); - if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r)) - return NULL; + r = PyLong_FromUnsignedLong(libver); + if (r == NULL) + return NULL; + if (PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r)) + return NULL; + parse_openssl_version(libver, &major, &minor, &fix, &patch, &status); + r = Py_BuildValue("IIIII", major, minor, fix, patch, status); + if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r)) + return NULL; r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION)); - if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) - return NULL; - - libver = OPENSSL_VERSION_NUMBER; - parse_openssl_version(libver, &major, &minor, &fix, &patch, &status); - r = Py_BuildValue("IIIII", major, minor, fix, patch, status); - if (r == NULL || PyModule_AddObject(m, "_OPENSSL_API_VERSION", r)) - return NULL; - - return m; -} + if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) + return NULL; + + libver = OPENSSL_VERSION_NUMBER; + parse_openssl_version(libver, &major, &minor, &fix, &patch, &status); + r = Py_BuildValue("IIIII", major, minor, fix, patch, status); + if (r == NULL || PyModule_AddObject(m, "_OPENSSL_API_VERSION", r)) + return NULL; + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_ssl_data.h b/contrib/tools/python3/src/Modules/_ssl_data.h index 8f2994f52df..e268a7c2317 100644 --- a/contrib/tools/python3/src/Modules/_ssl_data.h +++ b/contrib/tools/python3/src/Modules/_ssl_data.h @@ -1,7 +1,7 @@ -/* File generated by Tools/ssl/make_ssl_data.py */ +/* File generated by Tools/ssl/make_ssl_data.py */ /* Generated on 2020-04-13T21:45:54.559159 */ - -static struct py_ssl_library_code library_codes[] = { + +static struct py_ssl_library_code library_codes[] = { #ifdef ERR_LIB_ASN1 {"ASN1", ERR_LIB_ASN1}, #endif @@ -51,7 +51,7 @@ static struct py_ssl_library_code library_codes[] = { {"OCSP", ERR_LIB_OCSP}, #endif #ifdef ERR_LIB_PEM - {"PEM", ERR_LIB_PEM}, + {"PEM", ERR_LIB_PEM}, #endif #ifdef ERR_LIB_PKCS12 {"PKCS12", ERR_LIB_PKCS12}, @@ -66,7 +66,7 @@ static struct py_ssl_library_code library_codes[] = { {"RSA", ERR_LIB_RSA}, #endif #ifdef ERR_LIB_SSL - {"SSL", ERR_LIB_SSL}, + {"SSL", ERR_LIB_SSL}, #endif #ifdef ERR_LIB_TS {"TS", ERR_LIB_TS}, @@ -75,15 +75,15 @@ static struct py_ssl_library_code library_codes[] = { {"UI", ERR_LIB_UI}, #endif #ifdef ERR_LIB_X509 - {"X509", ERR_LIB_X509}, + {"X509", ERR_LIB_X509}, #endif #ifdef ERR_LIB_X509V3 {"X509V3", ERR_LIB_X509V3}, #endif - { NULL } -}; - -static struct py_ssl_error_code error_codes[] = { + { NULL } +}; + +static struct py_ssl_error_code error_codes[] = { #ifdef ASN1_R_ADDING_OBJECT {"ADDING_OBJECT", ERR_LIB_ASN1, ASN1_R_ADDING_OBJECT}, #else @@ -2834,161 +2834,161 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNSUPPORTED_REQUESTORNAME_TYPE", 39, 129}, #endif - #ifdef PEM_R_BAD_BASE64_DECODE - {"BAD_BASE64_DECODE", ERR_LIB_PEM, PEM_R_BAD_BASE64_DECODE}, - #else + #ifdef PEM_R_BAD_BASE64_DECODE + {"BAD_BASE64_DECODE", ERR_LIB_PEM, PEM_R_BAD_BASE64_DECODE}, + #else {"BAD_BASE64_DECODE", 9, 100}, - #endif - #ifdef PEM_R_BAD_DECRYPT - {"BAD_DECRYPT", ERR_LIB_PEM, PEM_R_BAD_DECRYPT}, - #else + #endif + #ifdef PEM_R_BAD_DECRYPT + {"BAD_DECRYPT", ERR_LIB_PEM, PEM_R_BAD_DECRYPT}, + #else {"BAD_DECRYPT", 9, 101}, - #endif - #ifdef PEM_R_BAD_END_LINE - {"BAD_END_LINE", ERR_LIB_PEM, PEM_R_BAD_END_LINE}, - #else + #endif + #ifdef PEM_R_BAD_END_LINE + {"BAD_END_LINE", ERR_LIB_PEM, PEM_R_BAD_END_LINE}, + #else {"BAD_END_LINE", 9, 102}, - #endif - #ifdef PEM_R_BAD_IV_CHARS - {"BAD_IV_CHARS", ERR_LIB_PEM, PEM_R_BAD_IV_CHARS}, - #else + #endif + #ifdef PEM_R_BAD_IV_CHARS + {"BAD_IV_CHARS", ERR_LIB_PEM, PEM_R_BAD_IV_CHARS}, + #else {"BAD_IV_CHARS", 9, 103}, - #endif - #ifdef PEM_R_BAD_MAGIC_NUMBER - {"BAD_MAGIC_NUMBER", ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER}, - #else + #endif + #ifdef PEM_R_BAD_MAGIC_NUMBER + {"BAD_MAGIC_NUMBER", ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER}, + #else {"BAD_MAGIC_NUMBER", 9, 116}, - #endif - #ifdef PEM_R_BAD_PASSWORD_READ - {"BAD_PASSWORD_READ", ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ}, - #else + #endif + #ifdef PEM_R_BAD_PASSWORD_READ + {"BAD_PASSWORD_READ", ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ}, + #else {"BAD_PASSWORD_READ", 9, 104}, - #endif - #ifdef PEM_R_BAD_VERSION_NUMBER - {"BAD_VERSION_NUMBER", ERR_LIB_PEM, PEM_R_BAD_VERSION_NUMBER}, - #else + #endif + #ifdef PEM_R_BAD_VERSION_NUMBER + {"BAD_VERSION_NUMBER", ERR_LIB_PEM, PEM_R_BAD_VERSION_NUMBER}, + #else {"BAD_VERSION_NUMBER", 9, 117}, - #endif - #ifdef PEM_R_BIO_WRITE_FAILURE - {"BIO_WRITE_FAILURE", ERR_LIB_PEM, PEM_R_BIO_WRITE_FAILURE}, - #else + #endif + #ifdef PEM_R_BIO_WRITE_FAILURE + {"BIO_WRITE_FAILURE", ERR_LIB_PEM, PEM_R_BIO_WRITE_FAILURE}, + #else {"BIO_WRITE_FAILURE", 9, 118}, - #endif - #ifdef PEM_R_CIPHER_IS_NULL - {"CIPHER_IS_NULL", ERR_LIB_PEM, PEM_R_CIPHER_IS_NULL}, - #else + #endif + #ifdef PEM_R_CIPHER_IS_NULL + {"CIPHER_IS_NULL", ERR_LIB_PEM, PEM_R_CIPHER_IS_NULL}, + #else {"CIPHER_IS_NULL", 9, 127}, - #endif - #ifdef PEM_R_ERROR_CONVERTING_PRIVATE_KEY - {"ERROR_CONVERTING_PRIVATE_KEY", ERR_LIB_PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY}, - #else + #endif + #ifdef PEM_R_ERROR_CONVERTING_PRIVATE_KEY + {"ERROR_CONVERTING_PRIVATE_KEY", ERR_LIB_PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY}, + #else {"ERROR_CONVERTING_PRIVATE_KEY", 9, 115}, - #endif - #ifdef PEM_R_EXPECTING_PRIVATE_KEY_BLOB - {"EXPECTING_PRIVATE_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB}, - #else + #endif + #ifdef PEM_R_EXPECTING_PRIVATE_KEY_BLOB + {"EXPECTING_PRIVATE_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB}, + #else {"EXPECTING_PRIVATE_KEY_BLOB", 9, 119}, - #endif - #ifdef PEM_R_EXPECTING_PUBLIC_KEY_BLOB - {"EXPECTING_PUBLIC_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB}, - #else + #endif + #ifdef PEM_R_EXPECTING_PUBLIC_KEY_BLOB + {"EXPECTING_PUBLIC_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB}, + #else {"EXPECTING_PUBLIC_KEY_BLOB", 9, 120}, - #endif + #endif #ifdef PEM_R_HEADER_TOO_LONG {"HEADER_TOO_LONG", ERR_LIB_PEM, PEM_R_HEADER_TOO_LONG}, #else {"HEADER_TOO_LONG", 9, 128}, #endif - #ifdef PEM_R_INCONSISTENT_HEADER - {"INCONSISTENT_HEADER", ERR_LIB_PEM, PEM_R_INCONSISTENT_HEADER}, - #else + #ifdef PEM_R_INCONSISTENT_HEADER + {"INCONSISTENT_HEADER", ERR_LIB_PEM, PEM_R_INCONSISTENT_HEADER}, + #else {"INCONSISTENT_HEADER", 9, 121}, - #endif - #ifdef PEM_R_KEYBLOB_HEADER_PARSE_ERROR - {"KEYBLOB_HEADER_PARSE_ERROR", ERR_LIB_PEM, PEM_R_KEYBLOB_HEADER_PARSE_ERROR}, - #else + #endif + #ifdef PEM_R_KEYBLOB_HEADER_PARSE_ERROR + {"KEYBLOB_HEADER_PARSE_ERROR", ERR_LIB_PEM, PEM_R_KEYBLOB_HEADER_PARSE_ERROR}, + #else {"KEYBLOB_HEADER_PARSE_ERROR", 9, 122}, - #endif - #ifdef PEM_R_KEYBLOB_TOO_SHORT - {"KEYBLOB_TOO_SHORT", ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT}, - #else + #endif + #ifdef PEM_R_KEYBLOB_TOO_SHORT + {"KEYBLOB_TOO_SHORT", ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT}, + #else {"KEYBLOB_TOO_SHORT", 9, 123}, - #endif + #endif #ifdef PEM_R_MISSING_DEK_IV {"MISSING_DEK_IV", ERR_LIB_PEM, PEM_R_MISSING_DEK_IV}, #else {"MISSING_DEK_IV", 9, 129}, #endif - #ifdef PEM_R_NOT_DEK_INFO - {"NOT_DEK_INFO", ERR_LIB_PEM, PEM_R_NOT_DEK_INFO}, - #else + #ifdef PEM_R_NOT_DEK_INFO + {"NOT_DEK_INFO", ERR_LIB_PEM, PEM_R_NOT_DEK_INFO}, + #else {"NOT_DEK_INFO", 9, 105}, - #endif - #ifdef PEM_R_NOT_ENCRYPTED - {"NOT_ENCRYPTED", ERR_LIB_PEM, PEM_R_NOT_ENCRYPTED}, - #else + #endif + #ifdef PEM_R_NOT_ENCRYPTED + {"NOT_ENCRYPTED", ERR_LIB_PEM, PEM_R_NOT_ENCRYPTED}, + #else {"NOT_ENCRYPTED", 9, 106}, - #endif - #ifdef PEM_R_NOT_PROC_TYPE - {"NOT_PROC_TYPE", ERR_LIB_PEM, PEM_R_NOT_PROC_TYPE}, - #else + #endif + #ifdef PEM_R_NOT_PROC_TYPE + {"NOT_PROC_TYPE", ERR_LIB_PEM, PEM_R_NOT_PROC_TYPE}, + #else {"NOT_PROC_TYPE", 9, 107}, - #endif - #ifdef PEM_R_NO_START_LINE - {"NO_START_LINE", ERR_LIB_PEM, PEM_R_NO_START_LINE}, - #else + #endif + #ifdef PEM_R_NO_START_LINE + {"NO_START_LINE", ERR_LIB_PEM, PEM_R_NO_START_LINE}, + #else {"NO_START_LINE", 9, 108}, - #endif - #ifdef PEM_R_PROBLEMS_GETTING_PASSWORD - {"PROBLEMS_GETTING_PASSWORD", ERR_LIB_PEM, PEM_R_PROBLEMS_GETTING_PASSWORD}, - #else + #endif + #ifdef PEM_R_PROBLEMS_GETTING_PASSWORD + {"PROBLEMS_GETTING_PASSWORD", ERR_LIB_PEM, PEM_R_PROBLEMS_GETTING_PASSWORD}, + #else {"PROBLEMS_GETTING_PASSWORD", 9, 109}, - #endif - #ifdef PEM_R_PUBLIC_KEY_NO_RSA - {"PUBLIC_KEY_NO_RSA", ERR_LIB_PEM, PEM_R_PUBLIC_KEY_NO_RSA}, - #else + #endif + #ifdef PEM_R_PUBLIC_KEY_NO_RSA + {"PUBLIC_KEY_NO_RSA", ERR_LIB_PEM, PEM_R_PUBLIC_KEY_NO_RSA}, + #else {"PUBLIC_KEY_NO_RSA", 9, 110}, - #endif - #ifdef PEM_R_PVK_DATA_TOO_SHORT - {"PVK_DATA_TOO_SHORT", ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT}, - #else + #endif + #ifdef PEM_R_PVK_DATA_TOO_SHORT + {"PVK_DATA_TOO_SHORT", ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT}, + #else {"PVK_DATA_TOO_SHORT", 9, 124}, - #endif - #ifdef PEM_R_PVK_TOO_SHORT - {"PVK_TOO_SHORT", ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT}, - #else + #endif + #ifdef PEM_R_PVK_TOO_SHORT + {"PVK_TOO_SHORT", ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT}, + #else {"PVK_TOO_SHORT", 9, 125}, - #endif - #ifdef PEM_R_READ_KEY - {"READ_KEY", ERR_LIB_PEM, PEM_R_READ_KEY}, - #else + #endif + #ifdef PEM_R_READ_KEY + {"READ_KEY", ERR_LIB_PEM, PEM_R_READ_KEY}, + #else {"READ_KEY", 9, 111}, - #endif - #ifdef PEM_R_SHORT_HEADER - {"SHORT_HEADER", ERR_LIB_PEM, PEM_R_SHORT_HEADER}, - #else + #endif + #ifdef PEM_R_SHORT_HEADER + {"SHORT_HEADER", ERR_LIB_PEM, PEM_R_SHORT_HEADER}, + #else {"SHORT_HEADER", 9, 112}, - #endif + #endif #ifdef PEM_R_UNEXPECTED_DEK_IV {"UNEXPECTED_DEK_IV", ERR_LIB_PEM, PEM_R_UNEXPECTED_DEK_IV}, #else {"UNEXPECTED_DEK_IV", 9, 130}, #endif - #ifdef PEM_R_UNSUPPORTED_CIPHER - {"UNSUPPORTED_CIPHER", ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER}, - #else + #ifdef PEM_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER}, + #else {"UNSUPPORTED_CIPHER", 9, 113}, - #endif - #ifdef PEM_R_UNSUPPORTED_ENCRYPTION - {"UNSUPPORTED_ENCRYPTION", ERR_LIB_PEM, PEM_R_UNSUPPORTED_ENCRYPTION}, - #else + #endif + #ifdef PEM_R_UNSUPPORTED_ENCRYPTION + {"UNSUPPORTED_ENCRYPTION", ERR_LIB_PEM, PEM_R_UNSUPPORTED_ENCRYPTION}, + #else {"UNSUPPORTED_ENCRYPTION", 9, 114}, - #endif - #ifdef PEM_R_UNSUPPORTED_KEY_COMPONENTS - {"UNSUPPORTED_KEY_COMPONENTS", ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS}, - #else + #endif + #ifdef PEM_R_UNSUPPORTED_KEY_COMPONENTS + {"UNSUPPORTED_KEY_COMPONENTS", ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS}, + #else {"UNSUPPORTED_KEY_COMPONENTS", 9, 126}, - #endif + #endif #ifdef PKCS12_R_CANT_PACK_STRUCTURE {"CANT_PACK_STRUCTURE", ERR_LIB_PKCS12, PKCS12_R_CANT_PACK_STRUCTURE}, #else @@ -3839,101 +3839,101 @@ static struct py_ssl_error_code error_codes[] = { #else {"APPLICATION_DATA_AFTER_CLOSE_NOTIFY", 20, 291}, #endif - #ifdef SSL_R_APP_DATA_IN_HANDSHAKE - {"APP_DATA_IN_HANDSHAKE", ERR_LIB_SSL, SSL_R_APP_DATA_IN_HANDSHAKE}, - #else + #ifdef SSL_R_APP_DATA_IN_HANDSHAKE + {"APP_DATA_IN_HANDSHAKE", ERR_LIB_SSL, SSL_R_APP_DATA_IN_HANDSHAKE}, + #else {"APP_DATA_IN_HANDSHAKE", 20, 100}, - #endif - #ifdef SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT - {"ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT", ERR_LIB_SSL, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT}, - #else + #endif + #ifdef SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT + {"ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT", ERR_LIB_SSL, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT}, + #else {"ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT", 20, 272}, - #endif + #endif #ifdef SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE {"AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE", ERR_LIB_SSL, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE}, - #else + #else {"AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE", 20, 143}, - #endif + #endif #ifdef SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE {"AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE}, - #else + #else {"AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE", 20, 158}, - #endif - #ifdef SSL_R_BAD_CHANGE_CIPHER_SPEC - {"BAD_CHANGE_CIPHER_SPEC", ERR_LIB_SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC}, - #else + #endif + #ifdef SSL_R_BAD_CHANGE_CIPHER_SPEC + {"BAD_CHANGE_CIPHER_SPEC", ERR_LIB_SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC}, + #else {"BAD_CHANGE_CIPHER_SPEC", 20, 103}, - #endif + #endif #ifdef SSL_R_BAD_CIPHER {"BAD_CIPHER", ERR_LIB_SSL, SSL_R_BAD_CIPHER}, - #else + #else {"BAD_CIPHER", 20, 186}, - #endif - #ifdef SSL_R_BAD_DATA - {"BAD_DATA", ERR_LIB_SSL, SSL_R_BAD_DATA}, - #else + #endif + #ifdef SSL_R_BAD_DATA + {"BAD_DATA", ERR_LIB_SSL, SSL_R_BAD_DATA}, + #else {"BAD_DATA", 20, 390}, - #endif - #ifdef SSL_R_BAD_DATA_RETURNED_BY_CALLBACK - {"BAD_DATA_RETURNED_BY_CALLBACK", ERR_LIB_SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK}, - #else + #endif + #ifdef SSL_R_BAD_DATA_RETURNED_BY_CALLBACK + {"BAD_DATA_RETURNED_BY_CALLBACK", ERR_LIB_SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK}, + #else {"BAD_DATA_RETURNED_BY_CALLBACK", 20, 106}, - #endif - #ifdef SSL_R_BAD_DECOMPRESSION - {"BAD_DECOMPRESSION", ERR_LIB_SSL, SSL_R_BAD_DECOMPRESSION}, - #else + #endif + #ifdef SSL_R_BAD_DECOMPRESSION + {"BAD_DECOMPRESSION", ERR_LIB_SSL, SSL_R_BAD_DECOMPRESSION}, + #else {"BAD_DECOMPRESSION", 20, 107}, - #endif + #endif #ifdef SSL_R_BAD_DH_VALUE {"BAD_DH_VALUE", ERR_LIB_SSL, SSL_R_BAD_DH_VALUE}, - #else + #else {"BAD_DH_VALUE", 20, 102}, - #endif - #ifdef SSL_R_BAD_DIGEST_LENGTH - {"BAD_DIGEST_LENGTH", ERR_LIB_SSL, SSL_R_BAD_DIGEST_LENGTH}, - #else + #endif + #ifdef SSL_R_BAD_DIGEST_LENGTH + {"BAD_DIGEST_LENGTH", ERR_LIB_SSL, SSL_R_BAD_DIGEST_LENGTH}, + #else {"BAD_DIGEST_LENGTH", 20, 111}, - #endif + #endif #ifdef SSL_R_BAD_EARLY_DATA {"BAD_EARLY_DATA", ERR_LIB_SSL, SSL_R_BAD_EARLY_DATA}, - #else + #else {"BAD_EARLY_DATA", 20, 233}, - #endif - #ifdef SSL_R_BAD_ECC_CERT - {"BAD_ECC_CERT", ERR_LIB_SSL, SSL_R_BAD_ECC_CERT}, - #else + #endif + #ifdef SSL_R_BAD_ECC_CERT + {"BAD_ECC_CERT", ERR_LIB_SSL, SSL_R_BAD_ECC_CERT}, + #else {"BAD_ECC_CERT", 20, 304}, - #endif - #ifdef SSL_R_BAD_ECDSA_SIGNATURE - {"BAD_ECDSA_SIGNATURE", ERR_LIB_SSL, SSL_R_BAD_ECDSA_SIGNATURE}, - #else + #endif + #ifdef SSL_R_BAD_ECDSA_SIGNATURE + {"BAD_ECDSA_SIGNATURE", ERR_LIB_SSL, SSL_R_BAD_ECDSA_SIGNATURE}, + #else {"BAD_ECDSA_SIGNATURE", 20, 305}, - #endif - #ifdef SSL_R_BAD_ECPOINT - {"BAD_ECPOINT", ERR_LIB_SSL, SSL_R_BAD_ECPOINT}, - #else + #endif + #ifdef SSL_R_BAD_ECPOINT + {"BAD_ECPOINT", ERR_LIB_SSL, SSL_R_BAD_ECPOINT}, + #else {"BAD_ECPOINT", 20, 306}, - #endif + #endif #ifdef SSL_R_BAD_EXTENSION {"BAD_EXTENSION", ERR_LIB_SSL, SSL_R_BAD_EXTENSION}, #else {"BAD_EXTENSION", 20, 110}, #endif - #ifdef SSL_R_BAD_HANDSHAKE_LENGTH - {"BAD_HANDSHAKE_LENGTH", ERR_LIB_SSL, SSL_R_BAD_HANDSHAKE_LENGTH}, - #else + #ifdef SSL_R_BAD_HANDSHAKE_LENGTH + {"BAD_HANDSHAKE_LENGTH", ERR_LIB_SSL, SSL_R_BAD_HANDSHAKE_LENGTH}, + #else {"BAD_HANDSHAKE_LENGTH", 20, 332}, - #endif + #endif #ifdef SSL_R_BAD_HANDSHAKE_STATE {"BAD_HANDSHAKE_STATE", ERR_LIB_SSL, SSL_R_BAD_HANDSHAKE_STATE}, #else {"BAD_HANDSHAKE_STATE", 20, 236}, #endif - #ifdef SSL_R_BAD_HELLO_REQUEST - {"BAD_HELLO_REQUEST", ERR_LIB_SSL, SSL_R_BAD_HELLO_REQUEST}, - #else + #ifdef SSL_R_BAD_HELLO_REQUEST + {"BAD_HELLO_REQUEST", ERR_LIB_SSL, SSL_R_BAD_HELLO_REQUEST}, + #else {"BAD_HELLO_REQUEST", 20, 105}, - #endif + #endif #ifdef SSL_R_BAD_HRR_VERSION {"BAD_HRR_VERSION", ERR_LIB_SSL, SSL_R_BAD_HRR_VERSION}, #else @@ -3954,31 +3954,31 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_LEGACY_VERSION", 20, 292}, #endif - #ifdef SSL_R_BAD_LENGTH - {"BAD_LENGTH", ERR_LIB_SSL, SSL_R_BAD_LENGTH}, - #else + #ifdef SSL_R_BAD_LENGTH + {"BAD_LENGTH", ERR_LIB_SSL, SSL_R_BAD_LENGTH}, + #else {"BAD_LENGTH", 20, 271}, - #endif - #ifdef SSL_R_BAD_MAC_LENGTH - {"BAD_MAC_LENGTH", ERR_LIB_SSL, SSL_R_BAD_MAC_LENGTH}, - #else + #endif + #ifdef SSL_R_BAD_MAC_LENGTH + {"BAD_MAC_LENGTH", ERR_LIB_SSL, SSL_R_BAD_MAC_LENGTH}, + #else {"BAD_MAC_LENGTH", 20, 333}, - #endif + #endif #ifdef SSL_R_BAD_PACKET {"BAD_PACKET", ERR_LIB_SSL, SSL_R_BAD_PACKET}, - #else + #else {"BAD_PACKET", 20, 240}, - #endif - #ifdef SSL_R_BAD_PACKET_LENGTH - {"BAD_PACKET_LENGTH", ERR_LIB_SSL, SSL_R_BAD_PACKET_LENGTH}, - #else + #endif + #ifdef SSL_R_BAD_PACKET_LENGTH + {"BAD_PACKET_LENGTH", ERR_LIB_SSL, SSL_R_BAD_PACKET_LENGTH}, + #else {"BAD_PACKET_LENGTH", 20, 115}, - #endif - #ifdef SSL_R_BAD_PROTOCOL_VERSION_NUMBER - {"BAD_PROTOCOL_VERSION_NUMBER", ERR_LIB_SSL, SSL_R_BAD_PROTOCOL_VERSION_NUMBER}, - #else + #endif + #ifdef SSL_R_BAD_PROTOCOL_VERSION_NUMBER + {"BAD_PROTOCOL_VERSION_NUMBER", ERR_LIB_SSL, SSL_R_BAD_PROTOCOL_VERSION_NUMBER}, + #else {"BAD_PROTOCOL_VERSION_NUMBER", 20, 116}, - #endif + #endif #ifdef SSL_R_BAD_PSK {"BAD_PSK", ERR_LIB_SSL, SSL_R_BAD_PSK}, #else @@ -3989,101 +3989,101 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_PSK_IDENTITY", 20, 114}, #endif - #ifdef SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH - {"BAD_PSK_IDENTITY_HINT_LENGTH", ERR_LIB_SSL, SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH}, - #else + #ifdef SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH + {"BAD_PSK_IDENTITY_HINT_LENGTH", ERR_LIB_SSL, SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH}, + #else {"BAD_PSK_IDENTITY_HINT_LENGTH", 20, 316}, - #endif + #endif #ifdef SSL_R_BAD_RECORD_TYPE {"BAD_RECORD_TYPE", ERR_LIB_SSL, SSL_R_BAD_RECORD_TYPE}, - #else + #else {"BAD_RECORD_TYPE", 20, 443}, - #endif - #ifdef SSL_R_BAD_RSA_ENCRYPT - {"BAD_RSA_ENCRYPT", ERR_LIB_SSL, SSL_R_BAD_RSA_ENCRYPT}, - #else + #endif + #ifdef SSL_R_BAD_RSA_ENCRYPT + {"BAD_RSA_ENCRYPT", ERR_LIB_SSL, SSL_R_BAD_RSA_ENCRYPT}, + #else {"BAD_RSA_ENCRYPT", 20, 119}, - #endif - #ifdef SSL_R_BAD_SIGNATURE - {"BAD_SIGNATURE", ERR_LIB_SSL, SSL_R_BAD_SIGNATURE}, - #else + #endif + #ifdef SSL_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_SSL, SSL_R_BAD_SIGNATURE}, + #else {"BAD_SIGNATURE", 20, 123}, - #endif - #ifdef SSL_R_BAD_SRP_A_LENGTH - {"BAD_SRP_A_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_A_LENGTH}, - #else + #endif + #ifdef SSL_R_BAD_SRP_A_LENGTH + {"BAD_SRP_A_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_A_LENGTH}, + #else {"BAD_SRP_A_LENGTH", 20, 347}, - #endif - #ifdef SSL_R_BAD_SRP_B_LENGTH - {"BAD_SRP_B_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_B_LENGTH}, - #else + #endif + #ifdef SSL_R_BAD_SRP_B_LENGTH + {"BAD_SRP_B_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_B_LENGTH}, + #else {"BAD_SRP_B_LENGTH", 20, 348}, - #endif - #ifdef SSL_R_BAD_SRP_G_LENGTH - {"BAD_SRP_G_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_G_LENGTH}, - #else + #endif + #ifdef SSL_R_BAD_SRP_G_LENGTH + {"BAD_SRP_G_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_G_LENGTH}, + #else {"BAD_SRP_G_LENGTH", 20, 349}, - #endif - #ifdef SSL_R_BAD_SRP_N_LENGTH - {"BAD_SRP_N_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_N_LENGTH}, - #else + #endif + #ifdef SSL_R_BAD_SRP_N_LENGTH + {"BAD_SRP_N_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_N_LENGTH}, + #else {"BAD_SRP_N_LENGTH", 20, 350}, - #endif - #ifdef SSL_R_BAD_SRP_PARAMETERS - {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, SSL_R_BAD_SRP_PARAMETERS}, - #else + #endif + #ifdef SSL_R_BAD_SRP_PARAMETERS + {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, SSL_R_BAD_SRP_PARAMETERS}, + #else {"BAD_SRP_PARAMETERS", 20, 371}, - #endif - #ifdef SSL_R_BAD_SRP_S_LENGTH - {"BAD_SRP_S_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_S_LENGTH}, - #else + #endif + #ifdef SSL_R_BAD_SRP_S_LENGTH + {"BAD_SRP_S_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_S_LENGTH}, + #else {"BAD_SRP_S_LENGTH", 20, 351}, - #endif - #ifdef SSL_R_BAD_SRTP_MKI_VALUE - {"BAD_SRTP_MKI_VALUE", ERR_LIB_SSL, SSL_R_BAD_SRTP_MKI_VALUE}, - #else + #endif + #ifdef SSL_R_BAD_SRTP_MKI_VALUE + {"BAD_SRTP_MKI_VALUE", ERR_LIB_SSL, SSL_R_BAD_SRTP_MKI_VALUE}, + #else {"BAD_SRTP_MKI_VALUE", 20, 352}, - #endif - #ifdef SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST - {"BAD_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST}, - #else + #endif + #ifdef SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST + {"BAD_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST}, + #else {"BAD_SRTP_PROTECTION_PROFILE_LIST", 20, 353}, - #endif - #ifdef SSL_R_BAD_SSL_FILETYPE - {"BAD_SSL_FILETYPE", ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE}, - #else + #endif + #ifdef SSL_R_BAD_SSL_FILETYPE + {"BAD_SSL_FILETYPE", ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE}, + #else {"BAD_SSL_FILETYPE", 20, 124}, - #endif - #ifdef SSL_R_BAD_VALUE - {"BAD_VALUE", ERR_LIB_SSL, SSL_R_BAD_VALUE}, - #else + #endif + #ifdef SSL_R_BAD_VALUE + {"BAD_VALUE", ERR_LIB_SSL, SSL_R_BAD_VALUE}, + #else {"BAD_VALUE", 20, 384}, - #endif - #ifdef SSL_R_BAD_WRITE_RETRY - {"BAD_WRITE_RETRY", ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY}, - #else + #endif + #ifdef SSL_R_BAD_WRITE_RETRY + {"BAD_WRITE_RETRY", ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY}, + #else {"BAD_WRITE_RETRY", 20, 127}, - #endif + #endif #ifdef SSL_R_BINDER_DOES_NOT_VERIFY {"BINDER_DOES_NOT_VERIFY", ERR_LIB_SSL, SSL_R_BINDER_DOES_NOT_VERIFY}, #else {"BINDER_DOES_NOT_VERIFY", 20, 253}, #endif - #ifdef SSL_R_BIO_NOT_SET - {"BIO_NOT_SET", ERR_LIB_SSL, SSL_R_BIO_NOT_SET}, - #else + #ifdef SSL_R_BIO_NOT_SET + {"BIO_NOT_SET", ERR_LIB_SSL, SSL_R_BIO_NOT_SET}, + #else {"BIO_NOT_SET", 20, 128}, - #endif - #ifdef SSL_R_BLOCK_CIPHER_PAD_IS_WRONG - {"BLOCK_CIPHER_PAD_IS_WRONG", ERR_LIB_SSL, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG}, - #else + #endif + #ifdef SSL_R_BLOCK_CIPHER_PAD_IS_WRONG + {"BLOCK_CIPHER_PAD_IS_WRONG", ERR_LIB_SSL, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG}, + #else {"BLOCK_CIPHER_PAD_IS_WRONG", 20, 129}, - #endif - #ifdef SSL_R_BN_LIB - {"BN_LIB", ERR_LIB_SSL, SSL_R_BN_LIB}, - #else + #endif + #ifdef SSL_R_BN_LIB + {"BN_LIB", ERR_LIB_SSL, SSL_R_BN_LIB}, + #else {"BN_LIB", 20, 130}, - #endif + #endif #ifdef SSL_R_CALLBACK_FAILED {"CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_CALLBACK_FAILED}, #else @@ -4094,91 +4094,91 @@ static struct py_ssl_error_code error_codes[] = { #else {"CANNOT_CHANGE_CIPHER", 20, 109}, #endif - #ifdef SSL_R_CA_DN_LENGTH_MISMATCH - {"CA_DN_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CA_DN_LENGTH_MISMATCH}, - #else + #ifdef SSL_R_CA_DN_LENGTH_MISMATCH + {"CA_DN_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CA_DN_LENGTH_MISMATCH}, + #else {"CA_DN_LENGTH_MISMATCH", 20, 131}, - #endif - #ifdef SSL_R_CA_KEY_TOO_SMALL - {"CA_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_CA_KEY_TOO_SMALL}, - #else + #endif + #ifdef SSL_R_CA_KEY_TOO_SMALL + {"CA_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_CA_KEY_TOO_SMALL}, + #else {"CA_KEY_TOO_SMALL", 20, 397}, - #endif - #ifdef SSL_R_CA_MD_TOO_WEAK - {"CA_MD_TOO_WEAK", ERR_LIB_SSL, SSL_R_CA_MD_TOO_WEAK}, - #else + #endif + #ifdef SSL_R_CA_MD_TOO_WEAK + {"CA_MD_TOO_WEAK", ERR_LIB_SSL, SSL_R_CA_MD_TOO_WEAK}, + #else {"CA_MD_TOO_WEAK", 20, 398}, - #endif - #ifdef SSL_R_CCS_RECEIVED_EARLY - {"CCS_RECEIVED_EARLY", ERR_LIB_SSL, SSL_R_CCS_RECEIVED_EARLY}, - #else + #endif + #ifdef SSL_R_CCS_RECEIVED_EARLY + {"CCS_RECEIVED_EARLY", ERR_LIB_SSL, SSL_R_CCS_RECEIVED_EARLY}, + #else {"CCS_RECEIVED_EARLY", 20, 133}, - #endif - #ifdef SSL_R_CERTIFICATE_VERIFY_FAILED - {"CERTIFICATE_VERIFY_FAILED", ERR_LIB_SSL, SSL_R_CERTIFICATE_VERIFY_FAILED}, - #else + #endif + #ifdef SSL_R_CERTIFICATE_VERIFY_FAILED + {"CERTIFICATE_VERIFY_FAILED", ERR_LIB_SSL, SSL_R_CERTIFICATE_VERIFY_FAILED}, + #else {"CERTIFICATE_VERIFY_FAILED", 20, 134}, - #endif - #ifdef SSL_R_CERT_CB_ERROR - {"CERT_CB_ERROR", ERR_LIB_SSL, SSL_R_CERT_CB_ERROR}, - #else + #endif + #ifdef SSL_R_CERT_CB_ERROR + {"CERT_CB_ERROR", ERR_LIB_SSL, SSL_R_CERT_CB_ERROR}, + #else {"CERT_CB_ERROR", 20, 377}, - #endif - #ifdef SSL_R_CERT_LENGTH_MISMATCH - {"CERT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CERT_LENGTH_MISMATCH}, - #else + #endif + #ifdef SSL_R_CERT_LENGTH_MISMATCH + {"CERT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CERT_LENGTH_MISMATCH}, + #else {"CERT_LENGTH_MISMATCH", 20, 135}, - #endif + #endif #ifdef SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED {"CIPHERSUITE_DIGEST_HAS_CHANGED", ERR_LIB_SSL, SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED}, - #else + #else {"CIPHERSUITE_DIGEST_HAS_CHANGED", 20, 218}, - #endif - #ifdef SSL_R_CIPHER_CODE_WRONG_LENGTH - {"CIPHER_CODE_WRONG_LENGTH", ERR_LIB_SSL, SSL_R_CIPHER_CODE_WRONG_LENGTH}, - #else + #endif + #ifdef SSL_R_CIPHER_CODE_WRONG_LENGTH + {"CIPHER_CODE_WRONG_LENGTH", ERR_LIB_SSL, SSL_R_CIPHER_CODE_WRONG_LENGTH}, + #else {"CIPHER_CODE_WRONG_LENGTH", 20, 137}, - #endif - #ifdef SSL_R_CIPHER_OR_HASH_UNAVAILABLE - {"CIPHER_OR_HASH_UNAVAILABLE", ERR_LIB_SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE}, - #else + #endif + #ifdef SSL_R_CIPHER_OR_HASH_UNAVAILABLE + {"CIPHER_OR_HASH_UNAVAILABLE", ERR_LIB_SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE}, + #else {"CIPHER_OR_HASH_UNAVAILABLE", 20, 138}, - #endif - #ifdef SSL_R_CLIENTHELLO_TLSEXT - {"CLIENTHELLO_TLSEXT", ERR_LIB_SSL, SSL_R_CLIENTHELLO_TLSEXT}, - #else + #endif + #ifdef SSL_R_CLIENTHELLO_TLSEXT + {"CLIENTHELLO_TLSEXT", ERR_LIB_SSL, SSL_R_CLIENTHELLO_TLSEXT}, + #else {"CLIENTHELLO_TLSEXT", 20, 226}, - #endif - #ifdef SSL_R_COMPRESSED_LENGTH_TOO_LONG - {"COMPRESSED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_COMPRESSED_LENGTH_TOO_LONG}, - #else + #endif + #ifdef SSL_R_COMPRESSED_LENGTH_TOO_LONG + {"COMPRESSED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_COMPRESSED_LENGTH_TOO_LONG}, + #else {"COMPRESSED_LENGTH_TOO_LONG", 20, 140}, - #endif - #ifdef SSL_R_COMPRESSION_DISABLED - {"COMPRESSION_DISABLED", ERR_LIB_SSL, SSL_R_COMPRESSION_DISABLED}, - #else + #endif + #ifdef SSL_R_COMPRESSION_DISABLED + {"COMPRESSION_DISABLED", ERR_LIB_SSL, SSL_R_COMPRESSION_DISABLED}, + #else {"COMPRESSION_DISABLED", 20, 343}, - #endif - #ifdef SSL_R_COMPRESSION_FAILURE - {"COMPRESSION_FAILURE", ERR_LIB_SSL, SSL_R_COMPRESSION_FAILURE}, - #else + #endif + #ifdef SSL_R_COMPRESSION_FAILURE + {"COMPRESSION_FAILURE", ERR_LIB_SSL, SSL_R_COMPRESSION_FAILURE}, + #else {"COMPRESSION_FAILURE", 20, 141}, - #endif - #ifdef SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE - {"COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE", ERR_LIB_SSL, SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE}, - #else + #endif + #ifdef SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE + {"COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE", ERR_LIB_SSL, SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE}, + #else {"COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE", 20, 307}, - #endif - #ifdef SSL_R_COMPRESSION_LIBRARY_ERROR - {"COMPRESSION_LIBRARY_ERROR", ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR}, - #else + #endif + #ifdef SSL_R_COMPRESSION_LIBRARY_ERROR + {"COMPRESSION_LIBRARY_ERROR", ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR}, + #else {"COMPRESSION_LIBRARY_ERROR", 20, 142}, - #endif - #ifdef SSL_R_CONNECTION_TYPE_NOT_SET - {"CONNECTION_TYPE_NOT_SET", ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET}, - #else + #endif + #ifdef SSL_R_CONNECTION_TYPE_NOT_SET + {"CONNECTION_TYPE_NOT_SET", ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET}, + #else {"CONNECTION_TYPE_NOT_SET", 20, 144}, - #endif + #endif #ifdef SSL_R_CONTEXT_NOT_DANE_ENABLED {"CONTEXT_NOT_DANE_ENABLED", ERR_LIB_SSL, SSL_R_CONTEXT_NOT_DANE_ENABLED}, #else @@ -4189,11 +4189,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"COOKIE_GEN_CALLBACK_FAILURE", 20, 400}, #endif - #ifdef SSL_R_COOKIE_MISMATCH - {"COOKIE_MISMATCH", ERR_LIB_SSL, SSL_R_COOKIE_MISMATCH}, - #else + #ifdef SSL_R_COOKIE_MISMATCH + {"COOKIE_MISMATCH", ERR_LIB_SSL, SSL_R_COOKIE_MISMATCH}, + #else {"COOKIE_MISMATCH", 20, 308}, - #endif + #endif #ifdef SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED {"CUSTOM_EXT_HANDLER_ALREADY_INSTALLED", ERR_LIB_SSL, SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED}, #else @@ -4254,101 +4254,101 @@ static struct py_ssl_error_code error_codes[] = { #else {"DANE_TLSA_NULL_DATA", 20, 203}, #endif - #ifdef SSL_R_DATA_BETWEEN_CCS_AND_FINISHED - {"DATA_BETWEEN_CCS_AND_FINISHED", ERR_LIB_SSL, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED}, - #else + #ifdef SSL_R_DATA_BETWEEN_CCS_AND_FINISHED + {"DATA_BETWEEN_CCS_AND_FINISHED", ERR_LIB_SSL, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED}, + #else {"DATA_BETWEEN_CCS_AND_FINISHED", 20, 145}, - #endif - #ifdef SSL_R_DATA_LENGTH_TOO_LONG - {"DATA_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_DATA_LENGTH_TOO_LONG}, - #else + #endif + #ifdef SSL_R_DATA_LENGTH_TOO_LONG + {"DATA_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_DATA_LENGTH_TOO_LONG}, + #else {"DATA_LENGTH_TOO_LONG", 20, 146}, - #endif - #ifdef SSL_R_DECRYPTION_FAILED - {"DECRYPTION_FAILED", ERR_LIB_SSL, SSL_R_DECRYPTION_FAILED}, - #else + #endif + #ifdef SSL_R_DECRYPTION_FAILED + {"DECRYPTION_FAILED", ERR_LIB_SSL, SSL_R_DECRYPTION_FAILED}, + #else {"DECRYPTION_FAILED", 20, 147}, - #endif - #ifdef SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC - {"DECRYPTION_FAILED_OR_BAD_RECORD_MAC", ERR_LIB_SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC}, - #else + #endif + #ifdef SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC + {"DECRYPTION_FAILED_OR_BAD_RECORD_MAC", ERR_LIB_SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC}, + #else {"DECRYPTION_FAILED_OR_BAD_RECORD_MAC", 20, 281}, - #endif - #ifdef SSL_R_DH_KEY_TOO_SMALL - {"DH_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL}, - #else + #endif + #ifdef SSL_R_DH_KEY_TOO_SMALL + {"DH_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL}, + #else {"DH_KEY_TOO_SMALL", 20, 394}, - #endif - #ifdef SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG - {"DH_PUBLIC_VALUE_LENGTH_IS_WRONG", ERR_LIB_SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG}, - #else + #endif + #ifdef SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG + {"DH_PUBLIC_VALUE_LENGTH_IS_WRONG", ERR_LIB_SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG}, + #else {"DH_PUBLIC_VALUE_LENGTH_IS_WRONG", 20, 148}, - #endif - #ifdef SSL_R_DIGEST_CHECK_FAILED - {"DIGEST_CHECK_FAILED", ERR_LIB_SSL, SSL_R_DIGEST_CHECK_FAILED}, - #else + #endif + #ifdef SSL_R_DIGEST_CHECK_FAILED + {"DIGEST_CHECK_FAILED", ERR_LIB_SSL, SSL_R_DIGEST_CHECK_FAILED}, + #else {"DIGEST_CHECK_FAILED", 20, 149}, - #endif - #ifdef SSL_R_DTLS_MESSAGE_TOO_BIG - {"DTLS_MESSAGE_TOO_BIG", ERR_LIB_SSL, SSL_R_DTLS_MESSAGE_TOO_BIG}, - #else + #endif + #ifdef SSL_R_DTLS_MESSAGE_TOO_BIG + {"DTLS_MESSAGE_TOO_BIG", ERR_LIB_SSL, SSL_R_DTLS_MESSAGE_TOO_BIG}, + #else {"DTLS_MESSAGE_TOO_BIG", 20, 334}, - #endif - #ifdef SSL_R_DUPLICATE_COMPRESSION_ID - {"DUPLICATE_COMPRESSION_ID", ERR_LIB_SSL, SSL_R_DUPLICATE_COMPRESSION_ID}, - #else + #endif + #ifdef SSL_R_DUPLICATE_COMPRESSION_ID + {"DUPLICATE_COMPRESSION_ID", ERR_LIB_SSL, SSL_R_DUPLICATE_COMPRESSION_ID}, + #else {"DUPLICATE_COMPRESSION_ID", 20, 309}, - #endif - #ifdef SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT - {"ECC_CERT_NOT_FOR_KEY_AGREEMENT", ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT}, - #else + #endif + #ifdef SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT + {"ECC_CERT_NOT_FOR_KEY_AGREEMENT", ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT}, + #else {"ECC_CERT_NOT_FOR_KEY_AGREEMENT", 20, 317}, - #endif - #ifdef SSL_R_ECC_CERT_NOT_FOR_SIGNING - {"ECC_CERT_NOT_FOR_SIGNING", ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING}, - #else + #endif + #ifdef SSL_R_ECC_CERT_NOT_FOR_SIGNING + {"ECC_CERT_NOT_FOR_SIGNING", ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING}, + #else {"ECC_CERT_NOT_FOR_SIGNING", 20, 318}, - #endif - #ifdef SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE - {"ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE", ERR_LIB_SSL, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE}, - #else + #endif + #ifdef SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE + {"ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE", ERR_LIB_SSL, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE}, + #else {"ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE", 20, 322}, - #endif - #ifdef SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE - {"ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE", ERR_LIB_SSL, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE}, - #else + #endif + #ifdef SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE + {"ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE", ERR_LIB_SSL, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE}, + #else {"ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE", 20, 323}, - #endif - #ifdef SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE - {"ECDH_REQUIRED_FOR_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE}, - #else + #endif + #ifdef SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE + {"ECDH_REQUIRED_FOR_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE}, + #else {"ECDH_REQUIRED_FOR_SUITEB_MODE", 20, 374}, - #endif - #ifdef SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER - {"ECGROUP_TOO_LARGE_FOR_CIPHER", ERR_LIB_SSL, SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER}, - #else + #endif + #ifdef SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER + {"ECGROUP_TOO_LARGE_FOR_CIPHER", ERR_LIB_SSL, SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER}, + #else {"ECGROUP_TOO_LARGE_FOR_CIPHER", 20, 310}, - #endif - #ifdef SSL_R_EE_KEY_TOO_SMALL - {"EE_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_EE_KEY_TOO_SMALL}, - #else + #endif + #ifdef SSL_R_EE_KEY_TOO_SMALL + {"EE_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_EE_KEY_TOO_SMALL}, + #else {"EE_KEY_TOO_SMALL", 20, 399}, - #endif - #ifdef SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST - {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST}, - #else + #endif + #ifdef SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST + {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST}, + #else {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", 20, 354}, - #endif - #ifdef SSL_R_ENCRYPTED_LENGTH_TOO_LONG - {"ENCRYPTED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG}, - #else + #endif + #ifdef SSL_R_ENCRYPTED_LENGTH_TOO_LONG + {"ENCRYPTED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG}, + #else {"ENCRYPTED_LENGTH_TOO_LONG", 20, 150}, - #endif - #ifdef SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST - {"ERROR_IN_RECEIVED_CIPHER_LIST", ERR_LIB_SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST}, - #else + #endif + #ifdef SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST + {"ERROR_IN_RECEIVED_CIPHER_LIST", ERR_LIB_SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST}, + #else {"ERROR_IN_RECEIVED_CIPHER_LIST", 20, 151}, - #endif + #endif #ifdef SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN {"ERROR_SETTING_TLSA_BASE_DOMAIN", ERR_LIB_SSL, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN}, #else @@ -4359,21 +4359,21 @@ static struct py_ssl_error_code error_codes[] = { #else {"EXCEEDS_MAX_FRAGMENT_SIZE", 20, 194}, #endif - #ifdef SSL_R_EXCESSIVE_MESSAGE_SIZE - {"EXCESSIVE_MESSAGE_SIZE", ERR_LIB_SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE}, - #else + #ifdef SSL_R_EXCESSIVE_MESSAGE_SIZE + {"EXCESSIVE_MESSAGE_SIZE", ERR_LIB_SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE}, + #else {"EXCESSIVE_MESSAGE_SIZE", 20, 152}, - #endif + #endif #ifdef SSL_R_EXTENSION_NOT_RECEIVED {"EXTENSION_NOT_RECEIVED", ERR_LIB_SSL, SSL_R_EXTENSION_NOT_RECEIVED}, #else {"EXTENSION_NOT_RECEIVED", 20, 279}, #endif - #ifdef SSL_R_EXTRA_DATA_IN_MESSAGE - {"EXTRA_DATA_IN_MESSAGE", ERR_LIB_SSL, SSL_R_EXTRA_DATA_IN_MESSAGE}, - #else + #ifdef SSL_R_EXTRA_DATA_IN_MESSAGE + {"EXTRA_DATA_IN_MESSAGE", ERR_LIB_SSL, SSL_R_EXTRA_DATA_IN_MESSAGE}, + #else {"EXTRA_DATA_IN_MESSAGE", 20, 153}, - #endif + #endif #ifdef SSL_R_EXT_LENGTH_MISMATCH {"EXT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_EXT_LENGTH_MISMATCH}, #else @@ -4389,151 +4389,151 @@ static struct py_ssl_error_code error_codes[] = { #else {"FRAGMENTED_CLIENT_HELLO", 20, 401}, #endif - #ifdef SSL_R_GOT_A_FIN_BEFORE_A_CCS - {"GOT_A_FIN_BEFORE_A_CCS", ERR_LIB_SSL, SSL_R_GOT_A_FIN_BEFORE_A_CCS}, - #else + #ifdef SSL_R_GOT_A_FIN_BEFORE_A_CCS + {"GOT_A_FIN_BEFORE_A_CCS", ERR_LIB_SSL, SSL_R_GOT_A_FIN_BEFORE_A_CCS}, + #else {"GOT_A_FIN_BEFORE_A_CCS", 20, 154}, - #endif - #ifdef SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS - {"GOT_NEXT_PROTO_BEFORE_A_CCS", ERR_LIB_SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS}, - #else + #endif + #ifdef SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS + {"GOT_NEXT_PROTO_BEFORE_A_CCS", ERR_LIB_SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS}, + #else {"GOT_NEXT_PROTO_BEFORE_A_CCS", 20, 355}, - #endif - #ifdef SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION - {"GOT_NEXT_PROTO_WITHOUT_EXTENSION", ERR_LIB_SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION}, - #else + #endif + #ifdef SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION + {"GOT_NEXT_PROTO_WITHOUT_EXTENSION", ERR_LIB_SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION}, + #else {"GOT_NEXT_PROTO_WITHOUT_EXTENSION", 20, 356}, - #endif - #ifdef SSL_R_HTTPS_PROXY_REQUEST - {"HTTPS_PROXY_REQUEST", ERR_LIB_SSL, SSL_R_HTTPS_PROXY_REQUEST}, - #else + #endif + #ifdef SSL_R_HTTPS_PROXY_REQUEST + {"HTTPS_PROXY_REQUEST", ERR_LIB_SSL, SSL_R_HTTPS_PROXY_REQUEST}, + #else {"HTTPS_PROXY_REQUEST", 20, 155}, - #endif - #ifdef SSL_R_HTTP_REQUEST - {"HTTP_REQUEST", ERR_LIB_SSL, SSL_R_HTTP_REQUEST}, - #else + #endif + #ifdef SSL_R_HTTP_REQUEST + {"HTTP_REQUEST", ERR_LIB_SSL, SSL_R_HTTP_REQUEST}, + #else {"HTTP_REQUEST", 20, 156}, - #endif + #endif #ifdef SSL_R_ILLEGAL_POINT_COMPRESSION {"ILLEGAL_POINT_COMPRESSION", ERR_LIB_SSL, SSL_R_ILLEGAL_POINT_COMPRESSION}, - #else + #else {"ILLEGAL_POINT_COMPRESSION", 20, 162}, - #endif - #ifdef SSL_R_ILLEGAL_SUITEB_DIGEST - {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, SSL_R_ILLEGAL_SUITEB_DIGEST}, - #else + #endif + #ifdef SSL_R_ILLEGAL_SUITEB_DIGEST + {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, SSL_R_ILLEGAL_SUITEB_DIGEST}, + #else {"ILLEGAL_SUITEB_DIGEST", 20, 380}, - #endif - #ifdef SSL_R_INAPPROPRIATE_FALLBACK - {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_INAPPROPRIATE_FALLBACK}, - #else + #endif + #ifdef SSL_R_INAPPROPRIATE_FALLBACK + {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_INAPPROPRIATE_FALLBACK}, + #else {"INAPPROPRIATE_FALLBACK", 20, 373}, - #endif - #ifdef SSL_R_INCONSISTENT_COMPRESSION - {"INCONSISTENT_COMPRESSION", ERR_LIB_SSL, SSL_R_INCONSISTENT_COMPRESSION}, - #else + #endif + #ifdef SSL_R_INCONSISTENT_COMPRESSION + {"INCONSISTENT_COMPRESSION", ERR_LIB_SSL, SSL_R_INCONSISTENT_COMPRESSION}, + #else {"INCONSISTENT_COMPRESSION", 20, 340}, - #endif + #endif #ifdef SSL_R_INCONSISTENT_EARLY_DATA_ALPN {"INCONSISTENT_EARLY_DATA_ALPN", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_ALPN}, - #else + #else {"INCONSISTENT_EARLY_DATA_ALPN", 20, 222}, - #endif + #endif #ifdef SSL_R_INCONSISTENT_EARLY_DATA_SNI {"INCONSISTENT_EARLY_DATA_SNI", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_SNI}, - #else + #else {"INCONSISTENT_EARLY_DATA_SNI", 20, 231}, - #endif + #endif #ifdef SSL_R_INCONSISTENT_EXTMS {"INCONSISTENT_EXTMS", ERR_LIB_SSL, SSL_R_INCONSISTENT_EXTMS}, - #else + #else {"INCONSISTENT_EXTMS", 20, 104}, - #endif + #endif #ifdef SSL_R_INSUFFICIENT_SECURITY {"INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_INSUFFICIENT_SECURITY}, - #else + #else {"INSUFFICIENT_SECURITY", 20, 241}, - #endif + #endif #ifdef SSL_R_INVALID_ALERT {"INVALID_ALERT", ERR_LIB_SSL, SSL_R_INVALID_ALERT}, - #else + #else {"INVALID_ALERT", 20, 205}, - #endif + #endif #ifdef SSL_R_INVALID_CCS_MESSAGE {"INVALID_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_INVALID_CCS_MESSAGE}, - #else + #else {"INVALID_CCS_MESSAGE", 20, 260}, - #endif + #endif #ifdef SSL_R_INVALID_CERTIFICATE_OR_ALG {"INVALID_CERTIFICATE_OR_ALG", ERR_LIB_SSL, SSL_R_INVALID_CERTIFICATE_OR_ALG}, - #else + #else {"INVALID_CERTIFICATE_OR_ALG", 20, 238}, - #endif + #endif #ifdef SSL_R_INVALID_COMMAND {"INVALID_COMMAND", ERR_LIB_SSL, SSL_R_INVALID_COMMAND}, - #else + #else {"INVALID_COMMAND", 20, 280}, - #endif + #endif #ifdef SSL_R_INVALID_COMPRESSION_ALGORITHM {"INVALID_COMPRESSION_ALGORITHM", ERR_LIB_SSL, SSL_R_INVALID_COMPRESSION_ALGORITHM}, - #else + #else {"INVALID_COMPRESSION_ALGORITHM", 20, 341}, - #endif + #endif #ifdef SSL_R_INVALID_CONFIG {"INVALID_CONFIG", ERR_LIB_SSL, SSL_R_INVALID_CONFIG}, - #else + #else {"INVALID_CONFIG", 20, 283}, - #endif + #endif #ifdef SSL_R_INVALID_CONFIGURATION_NAME {"INVALID_CONFIGURATION_NAME", ERR_LIB_SSL, SSL_R_INVALID_CONFIGURATION_NAME}, - #else + #else {"INVALID_CONFIGURATION_NAME", 20, 113}, - #endif + #endif #ifdef SSL_R_INVALID_CONTEXT {"INVALID_CONTEXT", ERR_LIB_SSL, SSL_R_INVALID_CONTEXT}, - #else + #else {"INVALID_CONTEXT", 20, 282}, - #endif + #endif #ifdef SSL_R_INVALID_CT_VALIDATION_TYPE {"INVALID_CT_VALIDATION_TYPE", ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE}, - #else + #else {"INVALID_CT_VALIDATION_TYPE", 20, 212}, - #endif + #endif #ifdef SSL_R_INVALID_KEY_UPDATE_TYPE {"INVALID_KEY_UPDATE_TYPE", ERR_LIB_SSL, SSL_R_INVALID_KEY_UPDATE_TYPE}, - #else + #else {"INVALID_KEY_UPDATE_TYPE", 20, 120}, - #endif + #endif #ifdef SSL_R_INVALID_MAX_EARLY_DATA {"INVALID_MAX_EARLY_DATA", ERR_LIB_SSL, SSL_R_INVALID_MAX_EARLY_DATA}, - #else + #else {"INVALID_MAX_EARLY_DATA", 20, 174}, - #endif + #endif #ifdef SSL_R_INVALID_NULL_CMD_NAME {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME}, - #else + #else {"INVALID_NULL_CMD_NAME", 20, 385}, - #endif + #endif #ifdef SSL_R_INVALID_SEQUENCE_NUMBER {"INVALID_SEQUENCE_NUMBER", ERR_LIB_SSL, SSL_R_INVALID_SEQUENCE_NUMBER}, - #else + #else {"INVALID_SEQUENCE_NUMBER", 20, 402}, - #endif + #endif #ifdef SSL_R_INVALID_SERVERINFO_DATA {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA}, - #else + #else {"INVALID_SERVERINFO_DATA", 20, 388}, - #endif + #endif #ifdef SSL_R_INVALID_SESSION_ID {"INVALID_SESSION_ID", ERR_LIB_SSL, SSL_R_INVALID_SESSION_ID}, - #else + #else {"INVALID_SESSION_ID", 20, 999}, - #endif + #endif #ifdef SSL_R_INVALID_SRP_USERNAME {"INVALID_SRP_USERNAME", ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME}, - #else + #else {"INVALID_SRP_USERNAME", 20, 357}, - #endif + #endif #ifdef SSL_R_INVALID_STATUS_RESPONSE {"INVALID_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_INVALID_STATUS_RESPONSE}, #else @@ -4544,86 +4544,86 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_TICKET_KEYS_LENGTH", 20, 325}, #endif - #ifdef SSL_R_KRB5_S_TKT_NYV - {"KRB5_S_TKT_NYV", ERR_LIB_SSL, SSL_R_KRB5_S_TKT_NYV}, - #else + #ifdef SSL_R_KRB5_S_TKT_NYV + {"KRB5_S_TKT_NYV", ERR_LIB_SSL, SSL_R_KRB5_S_TKT_NYV}, + #else {"KRB5_S_TKT_NYV", 20, 294}, - #endif - #ifdef SSL_R_KRB5_S_TKT_SKEW - {"KRB5_S_TKT_SKEW", ERR_LIB_SSL, SSL_R_KRB5_S_TKT_SKEW}, - #else + #endif + #ifdef SSL_R_KRB5_S_TKT_SKEW + {"KRB5_S_TKT_SKEW", ERR_LIB_SSL, SSL_R_KRB5_S_TKT_SKEW}, + #else {"KRB5_S_TKT_SKEW", 20, 295}, - #endif - #ifdef SSL_R_LENGTH_MISMATCH - {"LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH}, - #else + #endif + #ifdef SSL_R_LENGTH_MISMATCH + {"LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH}, + #else {"LENGTH_MISMATCH", 20, 159}, - #endif + #endif #ifdef SSL_R_LENGTH_TOO_LONG {"LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_LENGTH_TOO_LONG}, #else {"LENGTH_TOO_LONG", 20, 404}, #endif - #ifdef SSL_R_LENGTH_TOO_SHORT - {"LENGTH_TOO_SHORT", ERR_LIB_SSL, SSL_R_LENGTH_TOO_SHORT}, - #else + #ifdef SSL_R_LENGTH_TOO_SHORT + {"LENGTH_TOO_SHORT", ERR_LIB_SSL, SSL_R_LENGTH_TOO_SHORT}, + #else {"LENGTH_TOO_SHORT", 20, 160}, - #endif - #ifdef SSL_R_LIBRARY_BUG - {"LIBRARY_BUG", ERR_LIB_SSL, SSL_R_LIBRARY_BUG}, - #else + #endif + #ifdef SSL_R_LIBRARY_BUG + {"LIBRARY_BUG", ERR_LIB_SSL, SSL_R_LIBRARY_BUG}, + #else {"LIBRARY_BUG", 20, 274}, - #endif - #ifdef SSL_R_LIBRARY_HAS_NO_CIPHERS - {"LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS}, - #else + #endif + #ifdef SSL_R_LIBRARY_HAS_NO_CIPHERS + {"LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS}, + #else {"LIBRARY_HAS_NO_CIPHERS", 20, 161}, - #endif - #ifdef SSL_R_MESSAGE_TOO_LONG - {"MESSAGE_TOO_LONG", ERR_LIB_SSL, SSL_R_MESSAGE_TOO_LONG}, - #else + #endif + #ifdef SSL_R_MESSAGE_TOO_LONG + {"MESSAGE_TOO_LONG", ERR_LIB_SSL, SSL_R_MESSAGE_TOO_LONG}, + #else {"MESSAGE_TOO_LONG", 20, 296}, - #endif - #ifdef SSL_R_MISSING_DSA_SIGNING_CERT - {"MISSING_DSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_DSA_SIGNING_CERT}, - #else + #endif + #ifdef SSL_R_MISSING_DSA_SIGNING_CERT + {"MISSING_DSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_DSA_SIGNING_CERT}, + #else {"MISSING_DSA_SIGNING_CERT", 20, 165}, - #endif - #ifdef SSL_R_MISSING_ECDH_CERT - {"MISSING_ECDH_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDH_CERT}, - #else + #endif + #ifdef SSL_R_MISSING_ECDH_CERT + {"MISSING_ECDH_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDH_CERT}, + #else {"MISSING_ECDH_CERT", 20, 382}, - #endif - #ifdef SSL_R_MISSING_ECDSA_SIGNING_CERT - {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDSA_SIGNING_CERT}, - #else + #endif + #ifdef SSL_R_MISSING_ECDSA_SIGNING_CERT + {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDSA_SIGNING_CERT}, + #else {"MISSING_ECDSA_SIGNING_CERT", 20, 381}, - #endif + #endif #ifdef SSL_R_MISSING_FATAL {"MISSING_FATAL", ERR_LIB_SSL, SSL_R_MISSING_FATAL}, - #else + #else {"MISSING_FATAL", 20, 256}, - #endif + #endif #ifdef SSL_R_MISSING_PARAMETERS {"MISSING_PARAMETERS", ERR_LIB_SSL, SSL_R_MISSING_PARAMETERS}, - #else + #else {"MISSING_PARAMETERS", 20, 290}, - #endif - #ifdef SSL_R_MISSING_RSA_CERTIFICATE - {"MISSING_RSA_CERTIFICATE", ERR_LIB_SSL, SSL_R_MISSING_RSA_CERTIFICATE}, - #else + #endif + #ifdef SSL_R_MISSING_RSA_CERTIFICATE + {"MISSING_RSA_CERTIFICATE", ERR_LIB_SSL, SSL_R_MISSING_RSA_CERTIFICATE}, + #else {"MISSING_RSA_CERTIFICATE", 20, 168}, - #endif - #ifdef SSL_R_MISSING_RSA_ENCRYPTING_CERT - {"MISSING_RSA_ENCRYPTING_CERT", ERR_LIB_SSL, SSL_R_MISSING_RSA_ENCRYPTING_CERT}, - #else + #endif + #ifdef SSL_R_MISSING_RSA_ENCRYPTING_CERT + {"MISSING_RSA_ENCRYPTING_CERT", ERR_LIB_SSL, SSL_R_MISSING_RSA_ENCRYPTING_CERT}, + #else {"MISSING_RSA_ENCRYPTING_CERT", 20, 169}, - #endif - #ifdef SSL_R_MISSING_RSA_SIGNING_CERT - {"MISSING_RSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_RSA_SIGNING_CERT}, - #else + #endif + #ifdef SSL_R_MISSING_RSA_SIGNING_CERT + {"MISSING_RSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_RSA_SIGNING_CERT}, + #else {"MISSING_RSA_SIGNING_CERT", 20, 170}, - #endif + #endif #ifdef SSL_R_MISSING_SIGALGS_EXTENSION {"MISSING_SIGALGS_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_SIGALGS_EXTENSION}, #else @@ -4634,166 +4634,166 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_SIGNING_CERT", 20, 221}, #endif - #ifdef SSL_R_MISSING_SRP_PARAM - {"MISSING_SRP_PARAM", ERR_LIB_SSL, SSL_R_MISSING_SRP_PARAM}, - #else + #ifdef SSL_R_MISSING_SRP_PARAM + {"MISSING_SRP_PARAM", ERR_LIB_SSL, SSL_R_MISSING_SRP_PARAM}, + #else {"MISSING_SRP_PARAM", 20, 358}, - #endif + #endif #ifdef SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION {"MISSING_SUPPORTED_GROUPS_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION}, #else {"MISSING_SUPPORTED_GROUPS_EXTENSION", 20, 209}, #endif - #ifdef SSL_R_MISSING_TMP_DH_KEY - {"MISSING_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_DH_KEY}, - #else + #ifdef SSL_R_MISSING_TMP_DH_KEY + {"MISSING_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_DH_KEY}, + #else {"MISSING_TMP_DH_KEY", 20, 171}, - #endif - #ifdef SSL_R_MISSING_TMP_ECDH_KEY - {"MISSING_TMP_ECDH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_ECDH_KEY}, - #else + #endif + #ifdef SSL_R_MISSING_TMP_ECDH_KEY + {"MISSING_TMP_ECDH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_ECDH_KEY}, + #else {"MISSING_TMP_ECDH_KEY", 20, 311}, - #endif + #endif #ifdef SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA {"MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA", ERR_LIB_SSL, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA}, - #else + #else {"MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA", 20, 293}, - #endif + #endif #ifdef SSL_R_MULTIPLE_SGC_RESTARTS {"MULTIPLE_SGC_RESTARTS", ERR_LIB_SSL, SSL_R_MULTIPLE_SGC_RESTARTS}, - #else + #else {"MULTIPLE_SGC_RESTARTS", 20, 346}, - #endif + #endif #ifdef SSL_R_NOT_ON_RECORD_BOUNDARY {"NOT_ON_RECORD_BOUNDARY", ERR_LIB_SSL, SSL_R_NOT_ON_RECORD_BOUNDARY}, - #else + #else {"NOT_ON_RECORD_BOUNDARY", 20, 182}, - #endif + #endif #ifdef SSL_R_NOT_REPLACING_CERTIFICATE {"NOT_REPLACING_CERTIFICATE", ERR_LIB_SSL, SSL_R_NOT_REPLACING_CERTIFICATE}, - #else + #else {"NOT_REPLACING_CERTIFICATE", 20, 289}, - #endif + #endif #ifdef SSL_R_NOT_SERVER {"NOT_SERVER", ERR_LIB_SSL, SSL_R_NOT_SERVER}, - #else + #else {"NOT_SERVER", 20, 284}, - #endif + #endif #ifdef SSL_R_NO_APPLICATION_PROTOCOL {"NO_APPLICATION_PROTOCOL", ERR_LIB_SSL, SSL_R_NO_APPLICATION_PROTOCOL}, #else {"NO_APPLICATION_PROTOCOL", 20, 235}, #endif - #ifdef SSL_R_NO_CERTIFICATES_RETURNED - {"NO_CERTIFICATES_RETURNED", ERR_LIB_SSL, SSL_R_NO_CERTIFICATES_RETURNED}, - #else + #ifdef SSL_R_NO_CERTIFICATES_RETURNED + {"NO_CERTIFICATES_RETURNED", ERR_LIB_SSL, SSL_R_NO_CERTIFICATES_RETURNED}, + #else {"NO_CERTIFICATES_RETURNED", 20, 176}, - #endif - #ifdef SSL_R_NO_CERTIFICATE_ASSIGNED - {"NO_CERTIFICATE_ASSIGNED", ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED}, - #else + #endif + #ifdef SSL_R_NO_CERTIFICATE_ASSIGNED + {"NO_CERTIFICATE_ASSIGNED", ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED}, + #else {"NO_CERTIFICATE_ASSIGNED", 20, 177}, - #endif - #ifdef SSL_R_NO_CERTIFICATE_SET - {"NO_CERTIFICATE_SET", ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET}, - #else + #endif + #ifdef SSL_R_NO_CERTIFICATE_SET + {"NO_CERTIFICATE_SET", ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET}, + #else {"NO_CERTIFICATE_SET", 20, 179}, - #endif + #endif #ifdef SSL_R_NO_CHANGE_FOLLOWING_HRR {"NO_CHANGE_FOLLOWING_HRR", ERR_LIB_SSL, SSL_R_NO_CHANGE_FOLLOWING_HRR}, - #else + #else {"NO_CHANGE_FOLLOWING_HRR", 20, 214}, - #endif - #ifdef SSL_R_NO_CIPHERS_AVAILABLE - {"NO_CIPHERS_AVAILABLE", ERR_LIB_SSL, SSL_R_NO_CIPHERS_AVAILABLE}, - #else + #endif + #ifdef SSL_R_NO_CIPHERS_AVAILABLE + {"NO_CIPHERS_AVAILABLE", ERR_LIB_SSL, SSL_R_NO_CIPHERS_AVAILABLE}, + #else {"NO_CIPHERS_AVAILABLE", 20, 181}, - #endif - #ifdef SSL_R_NO_CIPHERS_SPECIFIED - {"NO_CIPHERS_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_CIPHERS_SPECIFIED}, - #else + #endif + #ifdef SSL_R_NO_CIPHERS_SPECIFIED + {"NO_CIPHERS_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_CIPHERS_SPECIFIED}, + #else {"NO_CIPHERS_SPECIFIED", 20, 183}, - #endif - #ifdef SSL_R_NO_CIPHER_MATCH - {"NO_CIPHER_MATCH", ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH}, - #else + #endif + #ifdef SSL_R_NO_CIPHER_MATCH + {"NO_CIPHER_MATCH", ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH}, + #else {"NO_CIPHER_MATCH", 20, 185}, - #endif - #ifdef SSL_R_NO_CLIENT_CERT_METHOD - {"NO_CLIENT_CERT_METHOD", ERR_LIB_SSL, SSL_R_NO_CLIENT_CERT_METHOD}, - #else + #endif + #ifdef SSL_R_NO_CLIENT_CERT_METHOD + {"NO_CLIENT_CERT_METHOD", ERR_LIB_SSL, SSL_R_NO_CLIENT_CERT_METHOD}, + #else {"NO_CLIENT_CERT_METHOD", 20, 331}, - #endif - #ifdef SSL_R_NO_COMPRESSION_SPECIFIED - {"NO_COMPRESSION_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_COMPRESSION_SPECIFIED}, - #else + #endif + #ifdef SSL_R_NO_COMPRESSION_SPECIFIED + {"NO_COMPRESSION_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_COMPRESSION_SPECIFIED}, + #else {"NO_COMPRESSION_SPECIFIED", 20, 187}, - #endif + #endif #ifdef SSL_R_NO_COOKIE_CALLBACK_SET {"NO_COOKIE_CALLBACK_SET", ERR_LIB_SSL, SSL_R_NO_COOKIE_CALLBACK_SET}, #else {"NO_COOKIE_CALLBACK_SET", 20, 287}, #endif - #ifdef SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER - {"NO_GOST_CERTIFICATE_SENT_BY_PEER", ERR_LIB_SSL, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER}, - #else + #ifdef SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER + {"NO_GOST_CERTIFICATE_SENT_BY_PEER", ERR_LIB_SSL, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER}, + #else {"NO_GOST_CERTIFICATE_SENT_BY_PEER", 20, 330}, - #endif - #ifdef SSL_R_NO_METHOD_SPECIFIED - {"NO_METHOD_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_METHOD_SPECIFIED}, - #else + #endif + #ifdef SSL_R_NO_METHOD_SPECIFIED + {"NO_METHOD_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_METHOD_SPECIFIED}, + #else {"NO_METHOD_SPECIFIED", 20, 188}, - #endif - #ifdef SSL_R_NO_PEM_EXTENSIONS - {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, SSL_R_NO_PEM_EXTENSIONS}, - #else + #endif + #ifdef SSL_R_NO_PEM_EXTENSIONS + {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, SSL_R_NO_PEM_EXTENSIONS}, + #else {"NO_PEM_EXTENSIONS", 20, 389}, - #endif - #ifdef SSL_R_NO_PRIVATE_KEY_ASSIGNED - {"NO_PRIVATE_KEY_ASSIGNED", ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED}, - #else + #endif + #ifdef SSL_R_NO_PRIVATE_KEY_ASSIGNED + {"NO_PRIVATE_KEY_ASSIGNED", ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED}, + #else {"NO_PRIVATE_KEY_ASSIGNED", 20, 190}, - #endif - #ifdef SSL_R_NO_PROTOCOLS_AVAILABLE - {"NO_PROTOCOLS_AVAILABLE", ERR_LIB_SSL, SSL_R_NO_PROTOCOLS_AVAILABLE}, - #else + #endif + #ifdef SSL_R_NO_PROTOCOLS_AVAILABLE + {"NO_PROTOCOLS_AVAILABLE", ERR_LIB_SSL, SSL_R_NO_PROTOCOLS_AVAILABLE}, + #else {"NO_PROTOCOLS_AVAILABLE", 20, 191}, - #endif - #ifdef SSL_R_NO_RENEGOTIATION - {"NO_RENEGOTIATION", ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION}, - #else + #endif + #ifdef SSL_R_NO_RENEGOTIATION + {"NO_RENEGOTIATION", ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION}, + #else {"NO_RENEGOTIATION", 20, 339}, - #endif - #ifdef SSL_R_NO_REQUIRED_DIGEST - {"NO_REQUIRED_DIGEST", ERR_LIB_SSL, SSL_R_NO_REQUIRED_DIGEST}, - #else + #endif + #ifdef SSL_R_NO_REQUIRED_DIGEST + {"NO_REQUIRED_DIGEST", ERR_LIB_SSL, SSL_R_NO_REQUIRED_DIGEST}, + #else {"NO_REQUIRED_DIGEST", 20, 324}, - #endif - #ifdef SSL_R_NO_SHARED_CIPHER - {"NO_SHARED_CIPHER", ERR_LIB_SSL, SSL_R_NO_SHARED_CIPHER}, - #else + #endif + #ifdef SSL_R_NO_SHARED_CIPHER + {"NO_SHARED_CIPHER", ERR_LIB_SSL, SSL_R_NO_SHARED_CIPHER}, + #else {"NO_SHARED_CIPHER", 20, 193}, - #endif + #endif #ifdef SSL_R_NO_SHARED_GROUPS {"NO_SHARED_GROUPS", ERR_LIB_SSL, SSL_R_NO_SHARED_GROUPS}, - #else + #else {"NO_SHARED_GROUPS", 20, 410}, - #endif + #endif #ifdef SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS {"NO_SHARED_SIGNATURE_ALGORITHMS", ERR_LIB_SSL, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS}, #else {"NO_SHARED_SIGNATURE_ALGORITHMS", 20, 376}, #endif - #ifdef SSL_R_NO_SRTP_PROFILES - {"NO_SRTP_PROFILES", ERR_LIB_SSL, SSL_R_NO_SRTP_PROFILES}, - #else + #ifdef SSL_R_NO_SRTP_PROFILES + {"NO_SRTP_PROFILES", ERR_LIB_SSL, SSL_R_NO_SRTP_PROFILES}, + #else {"NO_SRTP_PROFILES", 20, 359}, - #endif + #endif #ifdef SSL_R_NO_SUITABLE_KEY_SHARE {"NO_SUITABLE_KEY_SHARE", ERR_LIB_SSL, SSL_R_NO_SUITABLE_KEY_SHARE}, - #else + #else {"NO_SUITABLE_KEY_SHARE", 20, 101}, - #endif + #endif #ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM {"NO_SUITABLE_SIGNATURE_ALGORITHM", ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM}, #else @@ -4809,311 +4809,311 @@ static struct py_ssl_error_code error_codes[] = { #else {"NO_VERIFY_COOKIE_CALLBACK", 20, 403}, #endif - #ifdef SSL_R_NULL_SSL_CTX - {"NULL_SSL_CTX", ERR_LIB_SSL, SSL_R_NULL_SSL_CTX}, - #else + #ifdef SSL_R_NULL_SSL_CTX + {"NULL_SSL_CTX", ERR_LIB_SSL, SSL_R_NULL_SSL_CTX}, + #else {"NULL_SSL_CTX", 20, 195}, - #endif - #ifdef SSL_R_NULL_SSL_METHOD_PASSED - {"NULL_SSL_METHOD_PASSED", ERR_LIB_SSL, SSL_R_NULL_SSL_METHOD_PASSED}, - #else + #endif + #ifdef SSL_R_NULL_SSL_METHOD_PASSED + {"NULL_SSL_METHOD_PASSED", ERR_LIB_SSL, SSL_R_NULL_SSL_METHOD_PASSED}, + #else {"NULL_SSL_METHOD_PASSED", 20, 196}, - #endif - #ifdef SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED - {"OLD_SESSION_CIPHER_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED}, - #else + #endif + #ifdef SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED + {"OLD_SESSION_CIPHER_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED}, + #else {"OLD_SESSION_CIPHER_NOT_RETURNED", 20, 197}, - #endif - #ifdef SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED - {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED}, - #else + #endif + #ifdef SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED + {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED}, + #else {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", 20, 344}, - #endif - #ifdef SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE - {"ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE}, - #else + #endif + #ifdef SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE + {"ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE}, + #else {"ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE", 20, 387}, - #endif - #ifdef SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE - {"ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE}, - #else + #endif + #ifdef SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE + {"ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE}, + #else {"ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE", 20, 379}, - #endif - #ifdef SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE - {"ONLY_TLS_ALLOWED_IN_FIPS_MODE", ERR_LIB_SSL, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE}, - #else + #endif + #ifdef SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE + {"ONLY_TLS_ALLOWED_IN_FIPS_MODE", ERR_LIB_SSL, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE}, + #else {"ONLY_TLS_ALLOWED_IN_FIPS_MODE", 20, 297}, - #endif - #ifdef SSL_R_OPAQUE_PRF_INPUT_TOO_LONG - {"OPAQUE_PRF_INPUT_TOO_LONG", ERR_LIB_SSL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG}, - #else + #endif + #ifdef SSL_R_OPAQUE_PRF_INPUT_TOO_LONG + {"OPAQUE_PRF_INPUT_TOO_LONG", ERR_LIB_SSL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG}, + #else {"OPAQUE_PRF_INPUT_TOO_LONG", 20, 327}, - #endif + #endif #ifdef SSL_R_OVERFLOW_ERROR {"OVERFLOW_ERROR", ERR_LIB_SSL, SSL_R_OVERFLOW_ERROR}, #else {"OVERFLOW_ERROR", 20, 237}, #endif - #ifdef SSL_R_PACKET_LENGTH_TOO_LONG - {"PACKET_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_PACKET_LENGTH_TOO_LONG}, - #else + #ifdef SSL_R_PACKET_LENGTH_TOO_LONG + {"PACKET_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_PACKET_LENGTH_TOO_LONG}, + #else {"PACKET_LENGTH_TOO_LONG", 20, 198}, - #endif - #ifdef SSL_R_PARSE_TLSEXT - {"PARSE_TLSEXT", ERR_LIB_SSL, SSL_R_PARSE_TLSEXT}, - #else + #endif + #ifdef SSL_R_PARSE_TLSEXT + {"PARSE_TLSEXT", ERR_LIB_SSL, SSL_R_PARSE_TLSEXT}, + #else {"PARSE_TLSEXT", 20, 227}, - #endif - #ifdef SSL_R_PATH_TOO_LONG - {"PATH_TOO_LONG", ERR_LIB_SSL, SSL_R_PATH_TOO_LONG}, - #else + #endif + #ifdef SSL_R_PATH_TOO_LONG + {"PATH_TOO_LONG", ERR_LIB_SSL, SSL_R_PATH_TOO_LONG}, + #else {"PATH_TOO_LONG", 20, 270}, - #endif - #ifdef SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE - {"PEER_DID_NOT_RETURN_A_CERTIFICATE", ERR_LIB_SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE}, - #else + #endif + #ifdef SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE + {"PEER_DID_NOT_RETURN_A_CERTIFICATE", ERR_LIB_SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE}, + #else {"PEER_DID_NOT_RETURN_A_CERTIFICATE", 20, 199}, - #endif - #ifdef SSL_R_PEM_NAME_BAD_PREFIX - {"PEM_NAME_BAD_PREFIX", ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX}, - #else + #endif + #ifdef SSL_R_PEM_NAME_BAD_PREFIX + {"PEM_NAME_BAD_PREFIX", ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX}, + #else {"PEM_NAME_BAD_PREFIX", 20, 391}, - #endif - #ifdef SSL_R_PEM_NAME_TOO_SHORT - {"PEM_NAME_TOO_SHORT", ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT}, - #else + #endif + #ifdef SSL_R_PEM_NAME_TOO_SHORT + {"PEM_NAME_TOO_SHORT", ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT}, + #else {"PEM_NAME_TOO_SHORT", 20, 392}, - #endif + #endif #ifdef SSL_R_PIPELINE_FAILURE {"PIPELINE_FAILURE", ERR_LIB_SSL, SSL_R_PIPELINE_FAILURE}, - #else + #else {"PIPELINE_FAILURE", 20, 406}, - #endif + #endif #ifdef SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR {"POST_HANDSHAKE_AUTH_ENCODING_ERR", ERR_LIB_SSL, SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR}, - #else + #else {"POST_HANDSHAKE_AUTH_ENCODING_ERR", 20, 278}, - #endif + #endif #ifdef SSL_R_PRIVATE_KEY_MISMATCH {"PRIVATE_KEY_MISMATCH", ERR_LIB_SSL, SSL_R_PRIVATE_KEY_MISMATCH}, #else {"PRIVATE_KEY_MISMATCH", 20, 288}, #endif - #ifdef SSL_R_PROTOCOL_IS_SHUTDOWN - {"PROTOCOL_IS_SHUTDOWN", ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN}, - #else + #ifdef SSL_R_PROTOCOL_IS_SHUTDOWN + {"PROTOCOL_IS_SHUTDOWN", ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN}, + #else {"PROTOCOL_IS_SHUTDOWN", 20, 207}, - #endif - #ifdef SSL_R_PSK_IDENTITY_NOT_FOUND - {"PSK_IDENTITY_NOT_FOUND", ERR_LIB_SSL, SSL_R_PSK_IDENTITY_NOT_FOUND}, - #else + #endif + #ifdef SSL_R_PSK_IDENTITY_NOT_FOUND + {"PSK_IDENTITY_NOT_FOUND", ERR_LIB_SSL, SSL_R_PSK_IDENTITY_NOT_FOUND}, + #else {"PSK_IDENTITY_NOT_FOUND", 20, 223}, - #endif - #ifdef SSL_R_PSK_NO_CLIENT_CB - {"PSK_NO_CLIENT_CB", ERR_LIB_SSL, SSL_R_PSK_NO_CLIENT_CB}, - #else + #endif + #ifdef SSL_R_PSK_NO_CLIENT_CB + {"PSK_NO_CLIENT_CB", ERR_LIB_SSL, SSL_R_PSK_NO_CLIENT_CB}, + #else {"PSK_NO_CLIENT_CB", 20, 224}, - #endif - #ifdef SSL_R_PSK_NO_SERVER_CB - {"PSK_NO_SERVER_CB", ERR_LIB_SSL, SSL_R_PSK_NO_SERVER_CB}, - #else + #endif + #ifdef SSL_R_PSK_NO_SERVER_CB + {"PSK_NO_SERVER_CB", ERR_LIB_SSL, SSL_R_PSK_NO_SERVER_CB}, + #else {"PSK_NO_SERVER_CB", 20, 225}, - #endif - #ifdef SSL_R_READ_BIO_NOT_SET - {"READ_BIO_NOT_SET", ERR_LIB_SSL, SSL_R_READ_BIO_NOT_SET}, - #else + #endif + #ifdef SSL_R_READ_BIO_NOT_SET + {"READ_BIO_NOT_SET", ERR_LIB_SSL, SSL_R_READ_BIO_NOT_SET}, + #else {"READ_BIO_NOT_SET", 20, 211}, - #endif - #ifdef SSL_R_READ_TIMEOUT_EXPIRED - {"READ_TIMEOUT_EXPIRED", ERR_LIB_SSL, SSL_R_READ_TIMEOUT_EXPIRED}, - #else + #endif + #ifdef SSL_R_READ_TIMEOUT_EXPIRED + {"READ_TIMEOUT_EXPIRED", ERR_LIB_SSL, SSL_R_READ_TIMEOUT_EXPIRED}, + #else {"READ_TIMEOUT_EXPIRED", 20, 312}, - #endif - #ifdef SSL_R_RECORD_LENGTH_MISMATCH - {"RECORD_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_RECORD_LENGTH_MISMATCH}, - #else + #endif + #ifdef SSL_R_RECORD_LENGTH_MISMATCH + {"RECORD_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_RECORD_LENGTH_MISMATCH}, + #else {"RECORD_LENGTH_MISMATCH", 20, 213}, - #endif - #ifdef SSL_R_RECORD_TOO_SMALL - {"RECORD_TOO_SMALL", ERR_LIB_SSL, SSL_R_RECORD_TOO_SMALL}, - #else + #endif + #ifdef SSL_R_RECORD_TOO_SMALL + {"RECORD_TOO_SMALL", ERR_LIB_SSL, SSL_R_RECORD_TOO_SMALL}, + #else {"RECORD_TOO_SMALL", 20, 298}, - #endif - #ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG - {"RENEGOTIATE_EXT_TOO_LONG", ERR_LIB_SSL, SSL_R_RENEGOTIATE_EXT_TOO_LONG}, - #else + #endif + #ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG + {"RENEGOTIATE_EXT_TOO_LONG", ERR_LIB_SSL, SSL_R_RENEGOTIATE_EXT_TOO_LONG}, + #else {"RENEGOTIATE_EXT_TOO_LONG", 20, 335}, - #endif - #ifdef SSL_R_RENEGOTIATION_ENCODING_ERR - {"RENEGOTIATION_ENCODING_ERR", ERR_LIB_SSL, SSL_R_RENEGOTIATION_ENCODING_ERR}, - #else + #endif + #ifdef SSL_R_RENEGOTIATION_ENCODING_ERR + {"RENEGOTIATION_ENCODING_ERR", ERR_LIB_SSL, SSL_R_RENEGOTIATION_ENCODING_ERR}, + #else {"RENEGOTIATION_ENCODING_ERR", 20, 336}, - #endif - #ifdef SSL_R_RENEGOTIATION_MISMATCH - {"RENEGOTIATION_MISMATCH", ERR_LIB_SSL, SSL_R_RENEGOTIATION_MISMATCH}, - #else + #endif + #ifdef SSL_R_RENEGOTIATION_MISMATCH + {"RENEGOTIATION_MISMATCH", ERR_LIB_SSL, SSL_R_RENEGOTIATION_MISMATCH}, + #else {"RENEGOTIATION_MISMATCH", 20, 337}, - #endif + #endif #ifdef SSL_R_REQUEST_PENDING {"REQUEST_PENDING", ERR_LIB_SSL, SSL_R_REQUEST_PENDING}, - #else + #else {"REQUEST_PENDING", 20, 285}, - #endif + #endif #ifdef SSL_R_REQUEST_SENT {"REQUEST_SENT", ERR_LIB_SSL, SSL_R_REQUEST_SENT}, - #else + #else {"REQUEST_SENT", 20, 286}, - #endif + #endif #ifdef SSL_R_REQUIRED_CIPHER_MISSING {"REQUIRED_CIPHER_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_CIPHER_MISSING}, - #else + #else {"REQUIRED_CIPHER_MISSING", 20, 215}, - #endif + #endif #ifdef SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING {"REQUIRED_COMPRESSION_ALGORITHM_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING}, - #else + #else {"REQUIRED_COMPRESSION_ALGORITHM_MISSING", 20, 342}, - #endif - #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING - {"SCSV_RECEIVED_WHEN_RENEGOTIATING", ERR_LIB_SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING}, - #else + #endif + #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING + {"SCSV_RECEIVED_WHEN_RENEGOTIATING", ERR_LIB_SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING}, + #else {"SCSV_RECEIVED_WHEN_RENEGOTIATING", 20, 345}, - #endif + #endif #ifdef SSL_R_SCT_VERIFICATION_FAILED {"SCT_VERIFICATION_FAILED", ERR_LIB_SSL, SSL_R_SCT_VERIFICATION_FAILED}, #else {"SCT_VERIFICATION_FAILED", 20, 208}, #endif - #ifdef SSL_R_SERVERHELLO_TLSEXT - {"SERVERHELLO_TLSEXT", ERR_LIB_SSL, SSL_R_SERVERHELLO_TLSEXT}, - #else + #ifdef SSL_R_SERVERHELLO_TLSEXT + {"SERVERHELLO_TLSEXT", ERR_LIB_SSL, SSL_R_SERVERHELLO_TLSEXT}, + #else {"SERVERHELLO_TLSEXT", 20, 275}, - #endif - #ifdef SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED - {"SESSION_ID_CONTEXT_UNINITIALIZED", ERR_LIB_SSL, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED}, - #else + #endif + #ifdef SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED + {"SESSION_ID_CONTEXT_UNINITIALIZED", ERR_LIB_SSL, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED}, + #else {"SESSION_ID_CONTEXT_UNINITIALIZED", 20, 277}, - #endif + #endif #ifdef SSL_R_SHUTDOWN_WHILE_IN_INIT {"SHUTDOWN_WHILE_IN_INIT", ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT}, - #else + #else {"SHUTDOWN_WHILE_IN_INIT", 20, 407}, - #endif - #ifdef SSL_R_SIGNATURE_ALGORITHMS_ERROR - {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, SSL_R_SIGNATURE_ALGORITHMS_ERROR}, - #else + #endif + #ifdef SSL_R_SIGNATURE_ALGORITHMS_ERROR + {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, SSL_R_SIGNATURE_ALGORITHMS_ERROR}, + #else {"SIGNATURE_ALGORITHMS_ERROR", 20, 360}, - #endif - #ifdef SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE - {"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", ERR_LIB_SSL, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE}, - #else + #endif + #ifdef SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE + {"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", ERR_LIB_SSL, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE}, + #else {"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", 20, 220}, - #endif - #ifdef SSL_R_SRP_A_CALC - {"SRP_A_CALC", ERR_LIB_SSL, SSL_R_SRP_A_CALC}, - #else + #endif + #ifdef SSL_R_SRP_A_CALC + {"SRP_A_CALC", ERR_LIB_SSL, SSL_R_SRP_A_CALC}, + #else {"SRP_A_CALC", 20, 361}, - #endif - #ifdef SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES - {"SRTP_COULD_NOT_ALLOCATE_PROFILES", ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES}, - #else + #endif + #ifdef SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES + {"SRTP_COULD_NOT_ALLOCATE_PROFILES", ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES}, + #else {"SRTP_COULD_NOT_ALLOCATE_PROFILES", 20, 362}, - #endif - #ifdef SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG - {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", ERR_LIB_SSL, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG}, - #else + #endif + #ifdef SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG + {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", ERR_LIB_SSL, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG}, + #else {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", 20, 363}, - #endif - #ifdef SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE - {"SRTP_UNKNOWN_PROTECTION_PROFILE", ERR_LIB_SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE}, - #else + #endif + #ifdef SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE + {"SRTP_UNKNOWN_PROTECTION_PROFILE", ERR_LIB_SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE}, + #else {"SRTP_UNKNOWN_PROTECTION_PROFILE", 20, 364}, - #endif - #ifdef SSL_R_SSL2_CONNECTION_ID_TOO_LONG - {"SSL2_CONNECTION_ID_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL2_CONNECTION_ID_TOO_LONG}, - #else + #endif + #ifdef SSL_R_SSL2_CONNECTION_ID_TOO_LONG + {"SSL2_CONNECTION_ID_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL2_CONNECTION_ID_TOO_LONG}, + #else {"SSL2_CONNECTION_ID_TOO_LONG", 20, 299}, - #endif - #ifdef SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT - {"SSL3_EXT_INVALID_ECPOINTFORMAT", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT}, - #else + #endif + #ifdef SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT + {"SSL3_EXT_INVALID_ECPOINTFORMAT", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT}, + #else {"SSL3_EXT_INVALID_ECPOINTFORMAT", 20, 321}, - #endif + #endif #ifdef SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH {"SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH}, #else {"SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH", 20, 232}, #endif - #ifdef SSL_R_SSL3_EXT_INVALID_SERVERNAME - {"SSL3_EXT_INVALID_SERVERNAME", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME}, - #else + #ifdef SSL_R_SSL3_EXT_INVALID_SERVERNAME + {"SSL3_EXT_INVALID_SERVERNAME", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME}, + #else {"SSL3_EXT_INVALID_SERVERNAME", 20, 319}, - #endif - #ifdef SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE - {"SSL3_EXT_INVALID_SERVERNAME_TYPE", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE}, - #else + #endif + #ifdef SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE + {"SSL3_EXT_INVALID_SERVERNAME_TYPE", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE}, + #else {"SSL3_EXT_INVALID_SERVERNAME_TYPE", 20, 320}, - #endif - #ifdef SSL_R_SSL3_SESSION_ID_TOO_LONG - {"SSL3_SESSION_ID_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL3_SESSION_ID_TOO_LONG}, - #else + #endif + #ifdef SSL_R_SSL3_SESSION_ID_TOO_LONG + {"SSL3_SESSION_ID_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL3_SESSION_ID_TOO_LONG}, + #else {"SSL3_SESSION_ID_TOO_LONG", 20, 300}, - #endif - #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE - {"SSLV3_ALERT_BAD_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_BAD_CERTIFICATE}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE + {"SSLV3_ALERT_BAD_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_BAD_CERTIFICATE}, + #else {"SSLV3_ALERT_BAD_CERTIFICATE", 20, 1042}, - #endif - #ifdef SSL_R_SSLV3_ALERT_BAD_RECORD_MAC - {"SSLV3_ALERT_BAD_RECORD_MAC", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_BAD_RECORD_MAC}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_BAD_RECORD_MAC + {"SSLV3_ALERT_BAD_RECORD_MAC", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_BAD_RECORD_MAC}, + #else {"SSLV3_ALERT_BAD_RECORD_MAC", 20, 1020}, - #endif - #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED - {"SSLV3_ALERT_CERTIFICATE_EXPIRED", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED + {"SSLV3_ALERT_CERTIFICATE_EXPIRED", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED}, + #else {"SSLV3_ALERT_CERTIFICATE_EXPIRED", 20, 1045}, - #endif - #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED - {"SSLV3_ALERT_CERTIFICATE_REVOKED", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED + {"SSLV3_ALERT_CERTIFICATE_REVOKED", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED}, + #else {"SSLV3_ALERT_CERTIFICATE_REVOKED", 20, 1044}, - #endif - #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN - {"SSLV3_ALERT_CERTIFICATE_UNKNOWN", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN + {"SSLV3_ALERT_CERTIFICATE_UNKNOWN", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN}, + #else {"SSLV3_ALERT_CERTIFICATE_UNKNOWN", 20, 1046}, - #endif - #ifdef SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE - {"SSLV3_ALERT_DECOMPRESSION_FAILURE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE + {"SSLV3_ALERT_DECOMPRESSION_FAILURE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE}, + #else {"SSLV3_ALERT_DECOMPRESSION_FAILURE", 20, 1030}, - #endif - #ifdef SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE - {"SSLV3_ALERT_HANDSHAKE_FAILURE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE + {"SSLV3_ALERT_HANDSHAKE_FAILURE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE}, + #else {"SSLV3_ALERT_HANDSHAKE_FAILURE", 20, 1040}, - #endif - #ifdef SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER - {"SSLV3_ALERT_ILLEGAL_PARAMETER", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER + {"SSLV3_ALERT_ILLEGAL_PARAMETER", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER}, + #else {"SSLV3_ALERT_ILLEGAL_PARAMETER", 20, 1047}, - #endif - #ifdef SSL_R_SSLV3_ALERT_NO_CERTIFICATE - {"SSLV3_ALERT_NO_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_NO_CERTIFICATE}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_NO_CERTIFICATE + {"SSLV3_ALERT_NO_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_NO_CERTIFICATE}, + #else {"SSLV3_ALERT_NO_CERTIFICATE", 20, 1041}, - #endif - #ifdef SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE - {"SSLV3_ALERT_UNEXPECTED_MESSAGE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE + {"SSLV3_ALERT_UNEXPECTED_MESSAGE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE}, + #else {"SSLV3_ALERT_UNEXPECTED_MESSAGE", 20, 1010}, - #endif - #ifdef SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE - {"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE}, - #else + #endif + #ifdef SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE + {"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE}, + #else {"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE", 20, 1043}, - #endif + #endif #ifdef SSL_R_SSL_COMMAND_SECTION_EMPTY {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_EMPTY}, #else @@ -5124,26 +5124,26 @@ static struct py_ssl_error_code error_codes[] = { #else {"SSL_COMMAND_SECTION_NOT_FOUND", 20, 125}, #endif - #ifdef SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION - {"SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION", ERR_LIB_SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION}, - #else + #ifdef SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION + {"SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION", ERR_LIB_SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION}, + #else {"SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION", 20, 228}, - #endif - #ifdef SSL_R_SSL_HANDSHAKE_FAILURE - {"SSL_HANDSHAKE_FAILURE", ERR_LIB_SSL, SSL_R_SSL_HANDSHAKE_FAILURE}, - #else + #endif + #ifdef SSL_R_SSL_HANDSHAKE_FAILURE + {"SSL_HANDSHAKE_FAILURE", ERR_LIB_SSL, SSL_R_SSL_HANDSHAKE_FAILURE}, + #else {"SSL_HANDSHAKE_FAILURE", 20, 229}, - #endif - #ifdef SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS - {"SSL_LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS}, - #else + #endif + #ifdef SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS + {"SSL_LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS}, + #else {"SSL_LIBRARY_HAS_NO_CIPHERS", 20, 230}, - #endif - #ifdef SSL_R_SSL_NEGATIVE_LENGTH - {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, SSL_R_SSL_NEGATIVE_LENGTH}, - #else + #endif + #ifdef SSL_R_SSL_NEGATIVE_LENGTH + {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, SSL_R_SSL_NEGATIVE_LENGTH}, + #else {"SSL_NEGATIVE_LENGTH", 20, 372}, - #endif + #endif #ifdef SSL_R_SSL_SECTION_EMPTY {"SSL_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_SECTION_EMPTY}, #else @@ -5154,31 +5154,31 @@ static struct py_ssl_error_code error_codes[] = { #else {"SSL_SECTION_NOT_FOUND", 20, 136}, #endif - #ifdef SSL_R_SSL_SESSION_ID_CALLBACK_FAILED - {"SSL_SESSION_ID_CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED}, - #else + #ifdef SSL_R_SSL_SESSION_ID_CALLBACK_FAILED + {"SSL_SESSION_ID_CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED}, + #else {"SSL_SESSION_ID_CALLBACK_FAILED", 20, 301}, - #endif - #ifdef SSL_R_SSL_SESSION_ID_CONFLICT - {"SSL_SESSION_ID_CONFLICT", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONFLICT}, - #else + #endif + #ifdef SSL_R_SSL_SESSION_ID_CONFLICT + {"SSL_SESSION_ID_CONFLICT", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONFLICT}, + #else {"SSL_SESSION_ID_CONFLICT", 20, 302}, - #endif - #ifdef SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG - {"SSL_SESSION_ID_CONTEXT_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG}, - #else + #endif + #ifdef SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG + {"SSL_SESSION_ID_CONTEXT_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG}, + #else {"SSL_SESSION_ID_CONTEXT_TOO_LONG", 20, 273}, - #endif - #ifdef SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH - {"SSL_SESSION_ID_HAS_BAD_LENGTH", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH}, - #else + #endif + #ifdef SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH + {"SSL_SESSION_ID_HAS_BAD_LENGTH", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH}, + #else {"SSL_SESSION_ID_HAS_BAD_LENGTH", 20, 303}, - #endif + #endif #ifdef SSL_R_SSL_SESSION_ID_TOO_LONG {"SSL_SESSION_ID_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_TOO_LONG}, - #else + #else {"SSL_SESSION_ID_TOO_LONG", 20, 408}, - #endif + #endif #ifdef SSL_R_SSL_SESSION_VERSION_MISMATCH {"SSL_SESSION_VERSION_MISMATCH", ERR_LIB_SSL, SSL_R_SSL_SESSION_VERSION_MISMATCH}, #else @@ -5199,156 +5199,156 @@ static struct py_ssl_error_code error_codes[] = { #else {"TLSV13_ALERT_MISSING_EXTENSION", 20, 1109}, #endif - #ifdef SSL_R_TLSV1_ALERT_ACCESS_DENIED - {"TLSV1_ALERT_ACCESS_DENIED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_ACCESS_DENIED}, - #else + #ifdef SSL_R_TLSV1_ALERT_ACCESS_DENIED + {"TLSV1_ALERT_ACCESS_DENIED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_ACCESS_DENIED}, + #else {"TLSV1_ALERT_ACCESS_DENIED", 20, 1049}, - #endif - #ifdef SSL_R_TLSV1_ALERT_DECODE_ERROR - {"TLSV1_ALERT_DECODE_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECODE_ERROR}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_DECODE_ERROR + {"TLSV1_ALERT_DECODE_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECODE_ERROR}, + #else {"TLSV1_ALERT_DECODE_ERROR", 20, 1050}, - #endif - #ifdef SSL_R_TLSV1_ALERT_DECRYPTION_FAILED - {"TLSV1_ALERT_DECRYPTION_FAILED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECRYPTION_FAILED}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_DECRYPTION_FAILED + {"TLSV1_ALERT_DECRYPTION_FAILED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECRYPTION_FAILED}, + #else {"TLSV1_ALERT_DECRYPTION_FAILED", 20, 1021}, - #endif - #ifdef SSL_R_TLSV1_ALERT_DECRYPT_ERROR - {"TLSV1_ALERT_DECRYPT_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECRYPT_ERROR}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_DECRYPT_ERROR + {"TLSV1_ALERT_DECRYPT_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECRYPT_ERROR}, + #else {"TLSV1_ALERT_DECRYPT_ERROR", 20, 1051}, - #endif - #ifdef SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION - {"TLSV1_ALERT_EXPORT_RESTRICTION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION + {"TLSV1_ALERT_EXPORT_RESTRICTION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION}, + #else {"TLSV1_ALERT_EXPORT_RESTRICTION", 20, 1060}, - #endif - #ifdef SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK - {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK + {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK}, + #else {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", 20, 1086}, - #endif - #ifdef SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY - {"TLSV1_ALERT_INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY + {"TLSV1_ALERT_INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY}, + #else {"TLSV1_ALERT_INSUFFICIENT_SECURITY", 20, 1071}, - #endif - #ifdef SSL_R_TLSV1_ALERT_INTERNAL_ERROR - {"TLSV1_ALERT_INTERNAL_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INTERNAL_ERROR}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_INTERNAL_ERROR + {"TLSV1_ALERT_INTERNAL_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INTERNAL_ERROR}, + #else {"TLSV1_ALERT_INTERNAL_ERROR", 20, 1080}, - #endif - #ifdef SSL_R_TLSV1_ALERT_NO_RENEGOTIATION - {"TLSV1_ALERT_NO_RENEGOTIATION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_NO_RENEGOTIATION}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_NO_RENEGOTIATION + {"TLSV1_ALERT_NO_RENEGOTIATION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_NO_RENEGOTIATION}, + #else {"TLSV1_ALERT_NO_RENEGOTIATION", 20, 1100}, - #endif - #ifdef SSL_R_TLSV1_ALERT_PROTOCOL_VERSION - {"TLSV1_ALERT_PROTOCOL_VERSION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_PROTOCOL_VERSION}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_PROTOCOL_VERSION + {"TLSV1_ALERT_PROTOCOL_VERSION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_PROTOCOL_VERSION}, + #else {"TLSV1_ALERT_PROTOCOL_VERSION", 20, 1070}, - #endif - #ifdef SSL_R_TLSV1_ALERT_RECORD_OVERFLOW - {"TLSV1_ALERT_RECORD_OVERFLOW", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_RECORD_OVERFLOW}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_RECORD_OVERFLOW + {"TLSV1_ALERT_RECORD_OVERFLOW", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_RECORD_OVERFLOW}, + #else {"TLSV1_ALERT_RECORD_OVERFLOW", 20, 1022}, - #endif - #ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA - {"TLSV1_ALERT_UNKNOWN_CA", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_UNKNOWN_CA}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA + {"TLSV1_ALERT_UNKNOWN_CA", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_UNKNOWN_CA}, + #else {"TLSV1_ALERT_UNKNOWN_CA", 20, 1048}, - #endif - #ifdef SSL_R_TLSV1_ALERT_USER_CANCELLED - {"TLSV1_ALERT_USER_CANCELLED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_USER_CANCELLED}, - #else + #endif + #ifdef SSL_R_TLSV1_ALERT_USER_CANCELLED + {"TLSV1_ALERT_USER_CANCELLED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_USER_CANCELLED}, + #else {"TLSV1_ALERT_USER_CANCELLED", 20, 1090}, - #endif - #ifdef SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE - {"TLSV1_BAD_CERTIFICATE_HASH_VALUE", ERR_LIB_SSL, SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE}, - #else + #endif + #ifdef SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE + {"TLSV1_BAD_CERTIFICATE_HASH_VALUE", ERR_LIB_SSL, SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE}, + #else {"TLSV1_BAD_CERTIFICATE_HASH_VALUE", 20, 1114}, - #endif - #ifdef SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE - {"TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE}, - #else + #endif + #ifdef SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE + {"TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE}, + #else {"TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE", 20, 1113}, - #endif - #ifdef SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE - {"TLSV1_CERTIFICATE_UNOBTAINABLE", ERR_LIB_SSL, SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE}, - #else + #endif + #ifdef SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE + {"TLSV1_CERTIFICATE_UNOBTAINABLE", ERR_LIB_SSL, SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE}, + #else {"TLSV1_CERTIFICATE_UNOBTAINABLE", 20, 1111}, - #endif - #ifdef SSL_R_TLSV1_UNRECOGNIZED_NAME - {"TLSV1_UNRECOGNIZED_NAME", ERR_LIB_SSL, SSL_R_TLSV1_UNRECOGNIZED_NAME}, - #else + #endif + #ifdef SSL_R_TLSV1_UNRECOGNIZED_NAME + {"TLSV1_UNRECOGNIZED_NAME", ERR_LIB_SSL, SSL_R_TLSV1_UNRECOGNIZED_NAME}, + #else {"TLSV1_UNRECOGNIZED_NAME", 20, 1112}, - #endif - #ifdef SSL_R_TLSV1_UNSUPPORTED_EXTENSION - {"TLSV1_UNSUPPORTED_EXTENSION", ERR_LIB_SSL, SSL_R_TLSV1_UNSUPPORTED_EXTENSION}, - #else + #endif + #ifdef SSL_R_TLSV1_UNSUPPORTED_EXTENSION + {"TLSV1_UNSUPPORTED_EXTENSION", ERR_LIB_SSL, SSL_R_TLSV1_UNSUPPORTED_EXTENSION}, + #else {"TLSV1_UNSUPPORTED_EXTENSION", 20, 1110}, - #endif - #ifdef SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT - {"TLS_HEARTBEAT_PEER_DOESNT_ACCEPT", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT}, - #else + #endif + #ifdef SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT + {"TLS_HEARTBEAT_PEER_DOESNT_ACCEPT", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT}, + #else {"TLS_HEARTBEAT_PEER_DOESNT_ACCEPT", 20, 365}, - #endif - #ifdef SSL_R_TLS_HEARTBEAT_PENDING - {"TLS_HEARTBEAT_PENDING", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PENDING}, - #else + #endif + #ifdef SSL_R_TLS_HEARTBEAT_PENDING + {"TLS_HEARTBEAT_PENDING", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PENDING}, + #else {"TLS_HEARTBEAT_PENDING", 20, 366}, - #endif - #ifdef SSL_R_TLS_ILLEGAL_EXPORTER_LABEL - {"TLS_ILLEGAL_EXPORTER_LABEL", ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL}, - #else + #endif + #ifdef SSL_R_TLS_ILLEGAL_EXPORTER_LABEL + {"TLS_ILLEGAL_EXPORTER_LABEL", ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL}, + #else {"TLS_ILLEGAL_EXPORTER_LABEL", 20, 367}, - #endif - #ifdef SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST - {"TLS_INVALID_ECPOINTFORMAT_LIST", ERR_LIB_SSL, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST}, - #else + #endif + #ifdef SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST + {"TLS_INVALID_ECPOINTFORMAT_LIST", ERR_LIB_SSL, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST}, + #else {"TLS_INVALID_ECPOINTFORMAT_LIST", 20, 157}, - #endif + #endif #ifdef SSL_R_TOO_MANY_KEY_UPDATES {"TOO_MANY_KEY_UPDATES", ERR_LIB_SSL, SSL_R_TOO_MANY_KEY_UPDATES}, - #else + #else {"TOO_MANY_KEY_UPDATES", 20, 132}, - #endif + #endif #ifdef SSL_R_TOO_MANY_WARN_ALERTS {"TOO_MANY_WARN_ALERTS", ERR_LIB_SSL, SSL_R_TOO_MANY_WARN_ALERTS}, - #else + #else {"TOO_MANY_WARN_ALERTS", 20, 409}, - #endif + #endif #ifdef SSL_R_TOO_MUCH_EARLY_DATA {"TOO_MUCH_EARLY_DATA", ERR_LIB_SSL, SSL_R_TOO_MUCH_EARLY_DATA}, - #else + #else {"TOO_MUCH_EARLY_DATA", 20, 164}, - #endif - #ifdef SSL_R_UNABLE_TO_DECODE_ECDH_CERTS - {"UNABLE_TO_DECODE_ECDH_CERTS", ERR_LIB_SSL, SSL_R_UNABLE_TO_DECODE_ECDH_CERTS}, - #else + #endif + #ifdef SSL_R_UNABLE_TO_DECODE_ECDH_CERTS + {"UNABLE_TO_DECODE_ECDH_CERTS", ERR_LIB_SSL, SSL_R_UNABLE_TO_DECODE_ECDH_CERTS}, + #else {"UNABLE_TO_DECODE_ECDH_CERTS", 20, 313}, - #endif - #ifdef SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS - {"UNABLE_TO_FIND_ECDH_PARAMETERS", ERR_LIB_SSL, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS}, - #else + #endif + #ifdef SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS + {"UNABLE_TO_FIND_ECDH_PARAMETERS", ERR_LIB_SSL, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS}, + #else {"UNABLE_TO_FIND_ECDH_PARAMETERS", 20, 314}, - #endif - #ifdef SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS - {"UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS", ERR_LIB_SSL, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS}, - #else + #endif + #ifdef SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS + {"UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS", ERR_LIB_SSL, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS}, + #else {"UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS", 20, 239}, - #endif - #ifdef SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES - {"UNABLE_TO_LOAD_SSL3_MD5_ROUTINES", ERR_LIB_SSL, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES}, - #else + #endif + #ifdef SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES + {"UNABLE_TO_LOAD_SSL3_MD5_ROUTINES", ERR_LIB_SSL, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES}, + #else {"UNABLE_TO_LOAD_SSL3_MD5_ROUTINES", 20, 242}, - #endif - #ifdef SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES - {"UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES", ERR_LIB_SSL, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES}, - #else + #endif + #ifdef SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES + {"UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES", ERR_LIB_SSL, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES}, + #else {"UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES", 20, 243}, - #endif + #endif #ifdef SSL_R_UNEXPECTED_CCS_MESSAGE {"UNEXPECTED_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_UNEXPECTED_CCS_MESSAGE}, #else @@ -5359,186 +5359,186 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNEXPECTED_END_OF_EARLY_DATA", 20, 178}, #endif - #ifdef SSL_R_UNEXPECTED_MESSAGE - {"UNEXPECTED_MESSAGE", ERR_LIB_SSL, SSL_R_UNEXPECTED_MESSAGE}, - #else + #ifdef SSL_R_UNEXPECTED_MESSAGE + {"UNEXPECTED_MESSAGE", ERR_LIB_SSL, SSL_R_UNEXPECTED_MESSAGE}, + #else {"UNEXPECTED_MESSAGE", 20, 244}, - #endif - #ifdef SSL_R_UNEXPECTED_RECORD - {"UNEXPECTED_RECORD", ERR_LIB_SSL, SSL_R_UNEXPECTED_RECORD}, - #else + #endif + #ifdef SSL_R_UNEXPECTED_RECORD + {"UNEXPECTED_RECORD", ERR_LIB_SSL, SSL_R_UNEXPECTED_RECORD}, + #else {"UNEXPECTED_RECORD", 20, 245}, - #endif - #ifdef SSL_R_UNINITIALIZED - {"UNINITIALIZED", ERR_LIB_SSL, SSL_R_UNINITIALIZED}, - #else + #endif + #ifdef SSL_R_UNINITIALIZED + {"UNINITIALIZED", ERR_LIB_SSL, SSL_R_UNINITIALIZED}, + #else {"UNINITIALIZED", 20, 276}, - #endif - #ifdef SSL_R_UNKNOWN_ALERT_TYPE - {"UNKNOWN_ALERT_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_ALERT_TYPE}, - #else + #endif + #ifdef SSL_R_UNKNOWN_ALERT_TYPE + {"UNKNOWN_ALERT_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_ALERT_TYPE}, + #else {"UNKNOWN_ALERT_TYPE", 20, 246}, - #endif - #ifdef SSL_R_UNKNOWN_CERTIFICATE_TYPE - {"UNKNOWN_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE}, - #else + #endif + #ifdef SSL_R_UNKNOWN_CERTIFICATE_TYPE + {"UNKNOWN_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE}, + #else {"UNKNOWN_CERTIFICATE_TYPE", 20, 247}, - #endif - #ifdef SSL_R_UNKNOWN_CIPHER_RETURNED - {"UNKNOWN_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_UNKNOWN_CIPHER_RETURNED}, - #else + #endif + #ifdef SSL_R_UNKNOWN_CIPHER_RETURNED + {"UNKNOWN_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_UNKNOWN_CIPHER_RETURNED}, + #else {"UNKNOWN_CIPHER_RETURNED", 20, 248}, - #endif - #ifdef SSL_R_UNKNOWN_CIPHER_TYPE - {"UNKNOWN_CIPHER_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_CIPHER_TYPE}, - #else + #endif + #ifdef SSL_R_UNKNOWN_CIPHER_TYPE + {"UNKNOWN_CIPHER_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_CIPHER_TYPE}, + #else {"UNKNOWN_CIPHER_TYPE", 20, 249}, - #endif - #ifdef SSL_R_UNKNOWN_CMD_NAME - {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME}, - #else + #endif + #ifdef SSL_R_UNKNOWN_CMD_NAME + {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME}, + #else {"UNKNOWN_CMD_NAME", 20, 386}, - #endif + #endif #ifdef SSL_R_UNKNOWN_COMMAND {"UNKNOWN_COMMAND", ERR_LIB_SSL, SSL_R_UNKNOWN_COMMAND}, #else {"UNKNOWN_COMMAND", 20, 139}, #endif - #ifdef SSL_R_UNKNOWN_DIGEST - {"UNKNOWN_DIGEST", ERR_LIB_SSL, SSL_R_UNKNOWN_DIGEST}, - #else + #ifdef SSL_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_SSL, SSL_R_UNKNOWN_DIGEST}, + #else {"UNKNOWN_DIGEST", 20, 368}, - #endif - #ifdef SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE - {"UNKNOWN_KEY_EXCHANGE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE}, - #else + #endif + #ifdef SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE + {"UNKNOWN_KEY_EXCHANGE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE}, + #else {"UNKNOWN_KEY_EXCHANGE_TYPE", 20, 250}, - #endif - #ifdef SSL_R_UNKNOWN_PKEY_TYPE - {"UNKNOWN_PKEY_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_PKEY_TYPE}, - #else + #endif + #ifdef SSL_R_UNKNOWN_PKEY_TYPE + {"UNKNOWN_PKEY_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_PKEY_TYPE}, + #else {"UNKNOWN_PKEY_TYPE", 20, 251}, - #endif - #ifdef SSL_R_UNKNOWN_PROTOCOL - {"UNKNOWN_PROTOCOL", ERR_LIB_SSL, SSL_R_UNKNOWN_PROTOCOL}, - #else + #endif + #ifdef SSL_R_UNKNOWN_PROTOCOL + {"UNKNOWN_PROTOCOL", ERR_LIB_SSL, SSL_R_UNKNOWN_PROTOCOL}, + #else {"UNKNOWN_PROTOCOL", 20, 252}, - #endif - #ifdef SSL_R_UNKNOWN_SSL_VERSION - {"UNKNOWN_SSL_VERSION", ERR_LIB_SSL, SSL_R_UNKNOWN_SSL_VERSION}, - #else + #endif + #ifdef SSL_R_UNKNOWN_SSL_VERSION + {"UNKNOWN_SSL_VERSION", ERR_LIB_SSL, SSL_R_UNKNOWN_SSL_VERSION}, + #else {"UNKNOWN_SSL_VERSION", 20, 254}, - #endif - #ifdef SSL_R_UNKNOWN_STATE - {"UNKNOWN_STATE", ERR_LIB_SSL, SSL_R_UNKNOWN_STATE}, - #else + #endif + #ifdef SSL_R_UNKNOWN_STATE + {"UNKNOWN_STATE", ERR_LIB_SSL, SSL_R_UNKNOWN_STATE}, + #else {"UNKNOWN_STATE", 20, 255}, - #endif - #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED - {"UNSAFE_LEGACY_RENEGOTIATION_DISABLED", ERR_LIB_SSL, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED}, - #else + #endif + #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED + {"UNSAFE_LEGACY_RENEGOTIATION_DISABLED", ERR_LIB_SSL, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED}, + #else {"UNSAFE_LEGACY_RENEGOTIATION_DISABLED", 20, 338}, - #endif + #endif #ifdef SSL_R_UNSOLICITED_EXTENSION {"UNSOLICITED_EXTENSION", ERR_LIB_SSL, SSL_R_UNSOLICITED_EXTENSION}, - #else + #else {"UNSOLICITED_EXTENSION", 20, 217}, - #endif - #ifdef SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM - {"UNSUPPORTED_COMPRESSION_ALGORITHM", ERR_LIB_SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM}, - #else + #endif + #ifdef SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM + {"UNSUPPORTED_COMPRESSION_ALGORITHM", ERR_LIB_SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM}, + #else {"UNSUPPORTED_COMPRESSION_ALGORITHM", 20, 257}, - #endif - #ifdef SSL_R_UNSUPPORTED_DIGEST_TYPE - {"UNSUPPORTED_DIGEST_TYPE", ERR_LIB_SSL, SSL_R_UNSUPPORTED_DIGEST_TYPE}, - #else + #endif + #ifdef SSL_R_UNSUPPORTED_DIGEST_TYPE + {"UNSUPPORTED_DIGEST_TYPE", ERR_LIB_SSL, SSL_R_UNSUPPORTED_DIGEST_TYPE}, + #else {"UNSUPPORTED_DIGEST_TYPE", 20, 326}, - #endif - #ifdef SSL_R_UNSUPPORTED_ELLIPTIC_CURVE - {"UNSUPPORTED_ELLIPTIC_CURVE", ERR_LIB_SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE}, - #else + #endif + #ifdef SSL_R_UNSUPPORTED_ELLIPTIC_CURVE + {"UNSUPPORTED_ELLIPTIC_CURVE", ERR_LIB_SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE}, + #else {"UNSUPPORTED_ELLIPTIC_CURVE", 20, 315}, - #endif - #ifdef SSL_R_UNSUPPORTED_PROTOCOL - {"UNSUPPORTED_PROTOCOL", ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL}, - #else + #endif + #ifdef SSL_R_UNSUPPORTED_PROTOCOL + {"UNSUPPORTED_PROTOCOL", ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL}, + #else {"UNSUPPORTED_PROTOCOL", 20, 258}, - #endif - #ifdef SSL_R_UNSUPPORTED_SSL_VERSION - {"UNSUPPORTED_SSL_VERSION", ERR_LIB_SSL, SSL_R_UNSUPPORTED_SSL_VERSION}, - #else + #endif + #ifdef SSL_R_UNSUPPORTED_SSL_VERSION + {"UNSUPPORTED_SSL_VERSION", ERR_LIB_SSL, SSL_R_UNSUPPORTED_SSL_VERSION}, + #else {"UNSUPPORTED_SSL_VERSION", 20, 259}, - #endif - #ifdef SSL_R_UNSUPPORTED_STATUS_TYPE - {"UNSUPPORTED_STATUS_TYPE", ERR_LIB_SSL, SSL_R_UNSUPPORTED_STATUS_TYPE}, - #else + #endif + #ifdef SSL_R_UNSUPPORTED_STATUS_TYPE + {"UNSUPPORTED_STATUS_TYPE", ERR_LIB_SSL, SSL_R_UNSUPPORTED_STATUS_TYPE}, + #else {"UNSUPPORTED_STATUS_TYPE", 20, 329}, - #endif - #ifdef SSL_R_USE_SRTP_NOT_NEGOTIATED - {"USE_SRTP_NOT_NEGOTIATED", ERR_LIB_SSL, SSL_R_USE_SRTP_NOT_NEGOTIATED}, - #else + #endif + #ifdef SSL_R_USE_SRTP_NOT_NEGOTIATED + {"USE_SRTP_NOT_NEGOTIATED", ERR_LIB_SSL, SSL_R_USE_SRTP_NOT_NEGOTIATED}, + #else {"USE_SRTP_NOT_NEGOTIATED", 20, 369}, - #endif + #endif #ifdef SSL_R_VERSION_TOO_HIGH {"VERSION_TOO_HIGH", ERR_LIB_SSL, SSL_R_VERSION_TOO_HIGH}, #else {"VERSION_TOO_HIGH", 20, 166}, #endif - #ifdef SSL_R_VERSION_TOO_LOW - {"VERSION_TOO_LOW", ERR_LIB_SSL, SSL_R_VERSION_TOO_LOW}, - #else + #ifdef SSL_R_VERSION_TOO_LOW + {"VERSION_TOO_LOW", ERR_LIB_SSL, SSL_R_VERSION_TOO_LOW}, + #else {"VERSION_TOO_LOW", 20, 396}, - #endif - #ifdef SSL_R_WRONG_CERTIFICATE_TYPE - {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_CERTIFICATE_TYPE}, - #else + #endif + #ifdef SSL_R_WRONG_CERTIFICATE_TYPE + {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_CERTIFICATE_TYPE}, + #else {"WRONG_CERTIFICATE_TYPE", 20, 383}, - #endif - #ifdef SSL_R_WRONG_CIPHER_RETURNED - {"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_WRONG_CIPHER_RETURNED}, - #else + #endif + #ifdef SSL_R_WRONG_CIPHER_RETURNED + {"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_WRONG_CIPHER_RETURNED}, + #else {"WRONG_CIPHER_RETURNED", 20, 261}, - #endif - #ifdef SSL_R_WRONG_CURVE - {"WRONG_CURVE", ERR_LIB_SSL, SSL_R_WRONG_CURVE}, - #else + #endif + #ifdef SSL_R_WRONG_CURVE + {"WRONG_CURVE", ERR_LIB_SSL, SSL_R_WRONG_CURVE}, + #else {"WRONG_CURVE", 20, 378}, - #endif - #ifdef SSL_R_WRONG_SIGNATURE_LENGTH - {"WRONG_SIGNATURE_LENGTH", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_LENGTH}, - #else + #endif + #ifdef SSL_R_WRONG_SIGNATURE_LENGTH + {"WRONG_SIGNATURE_LENGTH", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_LENGTH}, + #else {"WRONG_SIGNATURE_LENGTH", 20, 264}, - #endif - #ifdef SSL_R_WRONG_SIGNATURE_SIZE - {"WRONG_SIGNATURE_SIZE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_SIZE}, - #else + #endif + #ifdef SSL_R_WRONG_SIGNATURE_SIZE + {"WRONG_SIGNATURE_SIZE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_SIZE}, + #else {"WRONG_SIGNATURE_SIZE", 20, 265}, - #endif - #ifdef SSL_R_WRONG_SIGNATURE_TYPE - {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_TYPE}, - #else + #endif + #ifdef SSL_R_WRONG_SIGNATURE_TYPE + {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_TYPE}, + #else {"WRONG_SIGNATURE_TYPE", 20, 370}, - #endif - #ifdef SSL_R_WRONG_SSL_VERSION - {"WRONG_SSL_VERSION", ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION}, - #else + #endif + #ifdef SSL_R_WRONG_SSL_VERSION + {"WRONG_SSL_VERSION", ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION}, + #else {"WRONG_SSL_VERSION", 20, 266}, - #endif - #ifdef SSL_R_WRONG_VERSION_NUMBER - {"WRONG_VERSION_NUMBER", ERR_LIB_SSL, SSL_R_WRONG_VERSION_NUMBER}, - #else + #endif + #ifdef SSL_R_WRONG_VERSION_NUMBER + {"WRONG_VERSION_NUMBER", ERR_LIB_SSL, SSL_R_WRONG_VERSION_NUMBER}, + #else {"WRONG_VERSION_NUMBER", 20, 267}, - #endif - #ifdef SSL_R_X509_LIB - {"X509_LIB", ERR_LIB_SSL, SSL_R_X509_LIB}, - #else + #endif + #ifdef SSL_R_X509_LIB + {"X509_LIB", ERR_LIB_SSL, SSL_R_X509_LIB}, + #else {"X509_LIB", 20, 268}, - #endif - #ifdef SSL_R_X509_VERIFICATION_SETUP_PROBLEMS - {"X509_VERIFICATION_SETUP_PROBLEMS", ERR_LIB_SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS}, - #else + #endif + #ifdef SSL_R_X509_VERIFICATION_SETUP_PROBLEMS + {"X509_VERIFICATION_SETUP_PROBLEMS", ERR_LIB_SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS}, + #else {"X509_VERIFICATION_SETUP_PROBLEMS", 20, 269}, - #endif + #endif #ifdef TS_R_BAD_PKCS7_TYPE {"BAD_PKCS7_TYPE", ERR_LIB_TS, TS_R_BAD_PKCS7_TYPE}, #else @@ -6124,116 +6124,116 @@ static struct py_ssl_error_code error_codes[] = { #else {"USER_TOO_LONG", 34, 132}, #endif - #ifdef X509_R_AKID_MISMATCH - {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH}, - #else + #ifdef X509_R_AKID_MISMATCH + {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH}, + #else {"AKID_MISMATCH", 11, 110}, - #endif + #endif #ifdef X509_R_BAD_SELECTOR {"BAD_SELECTOR", ERR_LIB_X509, X509_R_BAD_SELECTOR}, #else {"BAD_SELECTOR", 11, 133}, #endif - #ifdef X509_R_BAD_X509_FILETYPE - {"BAD_X509_FILETYPE", ERR_LIB_X509, X509_R_BAD_X509_FILETYPE}, - #else + #ifdef X509_R_BAD_X509_FILETYPE + {"BAD_X509_FILETYPE", ERR_LIB_X509, X509_R_BAD_X509_FILETYPE}, + #else {"BAD_X509_FILETYPE", 11, 100}, - #endif - #ifdef X509_R_BASE64_DECODE_ERROR - {"BASE64_DECODE_ERROR", ERR_LIB_X509, X509_R_BASE64_DECODE_ERROR}, - #else + #endif + #ifdef X509_R_BASE64_DECODE_ERROR + {"BASE64_DECODE_ERROR", ERR_LIB_X509, X509_R_BASE64_DECODE_ERROR}, + #else {"BASE64_DECODE_ERROR", 11, 118}, - #endif - #ifdef X509_R_CANT_CHECK_DH_KEY - {"CANT_CHECK_DH_KEY", ERR_LIB_X509, X509_R_CANT_CHECK_DH_KEY}, - #else + #endif + #ifdef X509_R_CANT_CHECK_DH_KEY + {"CANT_CHECK_DH_KEY", ERR_LIB_X509, X509_R_CANT_CHECK_DH_KEY}, + #else {"CANT_CHECK_DH_KEY", 11, 114}, - #endif - #ifdef X509_R_CERT_ALREADY_IN_HASH_TABLE - {"CERT_ALREADY_IN_HASH_TABLE", ERR_LIB_X509, X509_R_CERT_ALREADY_IN_HASH_TABLE}, - #else + #endif + #ifdef X509_R_CERT_ALREADY_IN_HASH_TABLE + {"CERT_ALREADY_IN_HASH_TABLE", ERR_LIB_X509, X509_R_CERT_ALREADY_IN_HASH_TABLE}, + #else {"CERT_ALREADY_IN_HASH_TABLE", 11, 101}, - #endif - #ifdef X509_R_CRL_ALREADY_DELTA - {"CRL_ALREADY_DELTA", ERR_LIB_X509, X509_R_CRL_ALREADY_DELTA}, - #else + #endif + #ifdef X509_R_CRL_ALREADY_DELTA + {"CRL_ALREADY_DELTA", ERR_LIB_X509, X509_R_CRL_ALREADY_DELTA}, + #else {"CRL_ALREADY_DELTA", 11, 127}, - #endif - #ifdef X509_R_CRL_VERIFY_FAILURE - {"CRL_VERIFY_FAILURE", ERR_LIB_X509, X509_R_CRL_VERIFY_FAILURE}, - #else + #endif + #ifdef X509_R_CRL_VERIFY_FAILURE + {"CRL_VERIFY_FAILURE", ERR_LIB_X509, X509_R_CRL_VERIFY_FAILURE}, + #else {"CRL_VERIFY_FAILURE", 11, 131}, - #endif - #ifdef X509_R_ERR_ASN1_LIB - {"ERR_ASN1_LIB", ERR_LIB_X509, X509_R_ERR_ASN1_LIB}, - #else + #endif + #ifdef X509_R_ERR_ASN1_LIB + {"ERR_ASN1_LIB", ERR_LIB_X509, X509_R_ERR_ASN1_LIB}, + #else {"ERR_ASN1_LIB", 11, 102}, - #endif - #ifdef X509_R_IDP_MISMATCH - {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH}, - #else + #endif + #ifdef X509_R_IDP_MISMATCH + {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH}, + #else {"IDP_MISMATCH", 11, 128}, - #endif + #endif #ifdef X509_R_INVALID_ATTRIBUTES {"INVALID_ATTRIBUTES", ERR_LIB_X509, X509_R_INVALID_ATTRIBUTES}, #else {"INVALID_ATTRIBUTES", 11, 138}, #endif - #ifdef X509_R_INVALID_DIRECTORY - {"INVALID_DIRECTORY", ERR_LIB_X509, X509_R_INVALID_DIRECTORY}, - #else + #ifdef X509_R_INVALID_DIRECTORY + {"INVALID_DIRECTORY", ERR_LIB_X509, X509_R_INVALID_DIRECTORY}, + #else {"INVALID_DIRECTORY", 11, 113}, - #endif - #ifdef X509_R_INVALID_FIELD_NAME - {"INVALID_FIELD_NAME", ERR_LIB_X509, X509_R_INVALID_FIELD_NAME}, - #else + #endif + #ifdef X509_R_INVALID_FIELD_NAME + {"INVALID_FIELD_NAME", ERR_LIB_X509, X509_R_INVALID_FIELD_NAME}, + #else {"INVALID_FIELD_NAME", 11, 119}, - #endif - #ifdef X509_R_INVALID_TRUST - {"INVALID_TRUST", ERR_LIB_X509, X509_R_INVALID_TRUST}, - #else + #endif + #ifdef X509_R_INVALID_TRUST + {"INVALID_TRUST", ERR_LIB_X509, X509_R_INVALID_TRUST}, + #else {"INVALID_TRUST", 11, 123}, - #endif - #ifdef X509_R_ISSUER_MISMATCH - {"ISSUER_MISMATCH", ERR_LIB_X509, X509_R_ISSUER_MISMATCH}, - #else + #endif + #ifdef X509_R_ISSUER_MISMATCH + {"ISSUER_MISMATCH", ERR_LIB_X509, X509_R_ISSUER_MISMATCH}, + #else {"ISSUER_MISMATCH", 11, 129}, - #endif - #ifdef X509_R_KEY_TYPE_MISMATCH - {"KEY_TYPE_MISMATCH", ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH}, - #else + #endif + #ifdef X509_R_KEY_TYPE_MISMATCH + {"KEY_TYPE_MISMATCH", ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH}, + #else {"KEY_TYPE_MISMATCH", 11, 115}, - #endif - #ifdef X509_R_KEY_VALUES_MISMATCH - {"KEY_VALUES_MISMATCH", ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH}, - #else + #endif + #ifdef X509_R_KEY_VALUES_MISMATCH + {"KEY_VALUES_MISMATCH", ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH}, + #else {"KEY_VALUES_MISMATCH", 11, 116}, - #endif - #ifdef X509_R_LOADING_CERT_DIR - {"LOADING_CERT_DIR", ERR_LIB_X509, X509_R_LOADING_CERT_DIR}, - #else + #endif + #ifdef X509_R_LOADING_CERT_DIR + {"LOADING_CERT_DIR", ERR_LIB_X509, X509_R_LOADING_CERT_DIR}, + #else {"LOADING_CERT_DIR", 11, 103}, - #endif - #ifdef X509_R_LOADING_DEFAULTS - {"LOADING_DEFAULTS", ERR_LIB_X509, X509_R_LOADING_DEFAULTS}, - #else + #endif + #ifdef X509_R_LOADING_DEFAULTS + {"LOADING_DEFAULTS", ERR_LIB_X509, X509_R_LOADING_DEFAULTS}, + #else {"LOADING_DEFAULTS", 11, 104}, - #endif - #ifdef X509_R_METHOD_NOT_SUPPORTED - {"METHOD_NOT_SUPPORTED", ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED}, - #else + #endif + #ifdef X509_R_METHOD_NOT_SUPPORTED + {"METHOD_NOT_SUPPORTED", ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED}, + #else {"METHOD_NOT_SUPPORTED", 11, 124}, - #endif + #endif #ifdef X509_R_NAME_TOO_LONG {"NAME_TOO_LONG", ERR_LIB_X509, X509_R_NAME_TOO_LONG}, #else {"NAME_TOO_LONG", 11, 134}, #endif - #ifdef X509_R_NEWER_CRL_NOT_NEWER - {"NEWER_CRL_NOT_NEWER", ERR_LIB_X509, X509_R_NEWER_CRL_NOT_NEWER}, - #else + #ifdef X509_R_NEWER_CRL_NOT_NEWER + {"NEWER_CRL_NOT_NEWER", ERR_LIB_X509, X509_R_NEWER_CRL_NOT_NEWER}, + #else {"NEWER_CRL_NOT_NEWER", 11, 132}, - #endif + #endif #ifdef X509_R_NO_CERTIFICATE_FOUND {"NO_CERTIFICATE_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND}, #else @@ -6244,80 +6244,80 @@ static struct py_ssl_error_code error_codes[] = { #else {"NO_CERTIFICATE_OR_CRL_FOUND", 11, 136}, #endif - #ifdef X509_R_NO_CERT_SET_FOR_US_TO_VERIFY - {"NO_CERT_SET_FOR_US_TO_VERIFY", ERR_LIB_X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY}, - #else + #ifdef X509_R_NO_CERT_SET_FOR_US_TO_VERIFY + {"NO_CERT_SET_FOR_US_TO_VERIFY", ERR_LIB_X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY}, + #else {"NO_CERT_SET_FOR_US_TO_VERIFY", 11, 105}, - #endif + #endif #ifdef X509_R_NO_CRL_FOUND {"NO_CRL_FOUND", ERR_LIB_X509, X509_R_NO_CRL_FOUND}, #else {"NO_CRL_FOUND", 11, 137}, #endif - #ifdef X509_R_NO_CRL_NUMBER - {"NO_CRL_NUMBER", ERR_LIB_X509, X509_R_NO_CRL_NUMBER}, - #else + #ifdef X509_R_NO_CRL_NUMBER + {"NO_CRL_NUMBER", ERR_LIB_X509, X509_R_NO_CRL_NUMBER}, + #else {"NO_CRL_NUMBER", 11, 130}, - #endif - #ifdef X509_R_PUBLIC_KEY_DECODE_ERROR - {"PUBLIC_KEY_DECODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_DECODE_ERROR}, - #else + #endif + #ifdef X509_R_PUBLIC_KEY_DECODE_ERROR + {"PUBLIC_KEY_DECODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_DECODE_ERROR}, + #else {"PUBLIC_KEY_DECODE_ERROR", 11, 125}, - #endif - #ifdef X509_R_PUBLIC_KEY_ENCODE_ERROR - {"PUBLIC_KEY_ENCODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_ENCODE_ERROR}, - #else + #endif + #ifdef X509_R_PUBLIC_KEY_ENCODE_ERROR + {"PUBLIC_KEY_ENCODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_ENCODE_ERROR}, + #else {"PUBLIC_KEY_ENCODE_ERROR", 11, 126}, - #endif - #ifdef X509_R_SHOULD_RETRY - {"SHOULD_RETRY", ERR_LIB_X509, X509_R_SHOULD_RETRY}, - #else + #endif + #ifdef X509_R_SHOULD_RETRY + {"SHOULD_RETRY", ERR_LIB_X509, X509_R_SHOULD_RETRY}, + #else {"SHOULD_RETRY", 11, 106}, - #endif - #ifdef X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN - {"UNABLE_TO_FIND_PARAMETERS_IN_CHAIN", ERR_LIB_X509, X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN}, - #else + #endif + #ifdef X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN + {"UNABLE_TO_FIND_PARAMETERS_IN_CHAIN", ERR_LIB_X509, X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN}, + #else {"UNABLE_TO_FIND_PARAMETERS_IN_CHAIN", 11, 107}, - #endif - #ifdef X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY - {"UNABLE_TO_GET_CERTS_PUBLIC_KEY", ERR_LIB_X509, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY}, - #else + #endif + #ifdef X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY + {"UNABLE_TO_GET_CERTS_PUBLIC_KEY", ERR_LIB_X509, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY}, + #else {"UNABLE_TO_GET_CERTS_PUBLIC_KEY", 11, 108}, - #endif - #ifdef X509_R_UNKNOWN_KEY_TYPE - {"UNKNOWN_KEY_TYPE", ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE}, - #else + #endif + #ifdef X509_R_UNKNOWN_KEY_TYPE + {"UNKNOWN_KEY_TYPE", ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE}, + #else {"UNKNOWN_KEY_TYPE", 11, 117}, - #endif - #ifdef X509_R_UNKNOWN_NID - {"UNKNOWN_NID", ERR_LIB_X509, X509_R_UNKNOWN_NID}, - #else + #endif + #ifdef X509_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_X509, X509_R_UNKNOWN_NID}, + #else {"UNKNOWN_NID", 11, 109}, - #endif - #ifdef X509_R_UNKNOWN_PURPOSE_ID - {"UNKNOWN_PURPOSE_ID", ERR_LIB_X509, X509_R_UNKNOWN_PURPOSE_ID}, - #else + #endif + #ifdef X509_R_UNKNOWN_PURPOSE_ID + {"UNKNOWN_PURPOSE_ID", ERR_LIB_X509, X509_R_UNKNOWN_PURPOSE_ID}, + #else {"UNKNOWN_PURPOSE_ID", 11, 121}, - #endif - #ifdef X509_R_UNKNOWN_TRUST_ID - {"UNKNOWN_TRUST_ID", ERR_LIB_X509, X509_R_UNKNOWN_TRUST_ID}, - #else + #endif + #ifdef X509_R_UNKNOWN_TRUST_ID + {"UNKNOWN_TRUST_ID", ERR_LIB_X509, X509_R_UNKNOWN_TRUST_ID}, + #else {"UNKNOWN_TRUST_ID", 11, 120}, - #endif - #ifdef X509_R_UNSUPPORTED_ALGORITHM - {"UNSUPPORTED_ALGORITHM", ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM}, - #else + #endif + #ifdef X509_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM}, + #else {"UNSUPPORTED_ALGORITHM", 11, 111}, - #endif - #ifdef X509_R_WRONG_LOOKUP_TYPE - {"WRONG_LOOKUP_TYPE", ERR_LIB_X509, X509_R_WRONG_LOOKUP_TYPE}, - #else + #endif + #ifdef X509_R_WRONG_LOOKUP_TYPE + {"WRONG_LOOKUP_TYPE", ERR_LIB_X509, X509_R_WRONG_LOOKUP_TYPE}, + #else {"WRONG_LOOKUP_TYPE", 11, 112}, - #endif - #ifdef X509_R_WRONG_TYPE - {"WRONG_TYPE", ERR_LIB_X509, X509_R_WRONG_TYPE}, - #else + #endif + #ifdef X509_R_WRONG_TYPE + {"WRONG_TYPE", ERR_LIB_X509, X509_R_WRONG_TYPE}, + #else {"WRONG_TYPE", 11, 122}, - #endif - { NULL } -}; + #endif + { NULL } +}; diff --git a/contrib/tools/python3/src/Modules/_stat.c b/contrib/tools/python3/src/Modules/_stat.c index 546e6a5f94c..6ce44da2419 100644 --- a/contrib/tools/python3/src/Modules/_stat.c +++ b/contrib/tools/python3/src/Modules/_stat.c @@ -1,511 +1,511 @@ -/* stat.h interface - * - * The module defines all S_IF*, S_I*, UF_*, SF_* and ST_* constants to - * sensible default values as well as defines S_IS*() macros in order to keep - * backward compatibility with the old stat.py module. - * - * New constants and macros such as S_IFDOOR / S_ISDOOR() are always defined - * as int 0. - * - * NOTE: POSIX only defines the values of the S_I* permission bits. - * - */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_SYS_STAT_H -#include -#endif /* HAVE_SYS_STAT_H */ - -#ifdef MS_WINDOWS -#include -typedef unsigned short mode_t; - -/* FILE_ATTRIBUTE_INTEGRITY_STREAM and FILE_ATTRIBUTE_NO_SCRUB_DATA - are not present in VC2010, so define them manually */ -#ifndef FILE_ATTRIBUTE_INTEGRITY_STREAM -# define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x8000 -#endif - -#ifndef FILE_ATTRIBUTE_NO_SCRUB_DATA -# define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x20000 -#endif - +/* stat.h interface + * + * The module defines all S_IF*, S_I*, UF_*, SF_* and ST_* constants to + * sensible default values as well as defines S_IS*() macros in order to keep + * backward compatibility with the old stat.py module. + * + * New constants and macros such as S_IFDOOR / S_ISDOOR() are always defined + * as int 0. + * + * NOTE: POSIX only defines the values of the S_I* permission bits. + * + */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif /* HAVE_SYS_TYPES_H */ + +#ifdef HAVE_SYS_STAT_H +#include +#endif /* HAVE_SYS_STAT_H */ + +#ifdef MS_WINDOWS +#include +typedef unsigned short mode_t; + +/* FILE_ATTRIBUTE_INTEGRITY_STREAM and FILE_ATTRIBUTE_NO_SCRUB_DATA + are not present in VC2010, so define them manually */ +#ifndef FILE_ATTRIBUTE_INTEGRITY_STREAM +# define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x8000 +#endif + +#ifndef FILE_ATTRIBUTE_NO_SCRUB_DATA +# define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x20000 +#endif + #ifndef IO_REPARSE_TAG_APPEXECLINK # define IO_REPARSE_TAG_APPEXECLINK 0x8000001BL #endif -#endif /* MS_WINDOWS */ - -/* From Python's stat.py */ -#ifndef S_IMODE -# define S_IMODE 07777 -#endif - -/* S_IFXXX constants (file types) - * - * Only the names are defined by POSIX but not their value. All common file - * types seems to have the same numeric value on all platforms, though. - * - * pyport.h guarantees S_IFMT, S_IFDIR, S_IFCHR, S_IFREG and S_IFLNK - */ - -#ifndef S_IFBLK -# define S_IFBLK 0060000 -#endif - -#ifndef S_IFIFO -# define S_IFIFO 0010000 -#endif - -#ifndef S_IFSOCK -# define S_IFSOCK 0140000 -#endif - -#ifndef S_IFDOOR -# define S_IFDOOR 0 -#endif - -#ifndef S_IFPORT -# define S_IFPORT 0 -#endif - -#ifndef S_IFWHT -# define S_IFWHT 0 -#endif - - -/* S_ISXXX() - * pyport.h defines S_ISDIR(), S_ISREG() and S_ISCHR() - */ - -#ifndef S_ISBLK -# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) -#endif - -#ifndef S_ISFIFO -# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) -#endif - -#ifndef S_ISLNK -# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) -#endif - -#ifndef S_ISSOCK -# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) -#endif - -#ifndef S_ISDOOR -# define S_ISDOOR(mode) 0 -#endif - -#ifndef S_ISPORT -# define S_ISPORT(mode) 0 -#endif - -#ifndef S_ISWHT -# define S_ISWHT(mode) 0 -#endif - - -/* S_I* file permission - * - * The permission bit value are defined by POSIX standards. - */ -#ifndef S_ISUID -# define S_ISUID 04000 -#endif - -#ifndef S_ISGID -# define S_ISGID 02000 -#endif - -/* what is S_ENFMT? */ -#ifndef S_ENFMT -# define S_ENFMT S_ISGID -#endif - -#ifndef S_ISVTX -# define S_ISVTX 01000 -#endif - -#ifndef S_IREAD -# define S_IREAD 00400 -#endif - -#ifndef S_IWRITE -# define S_IWRITE 00200 -#endif - -#ifndef S_IEXEC -# define S_IEXEC 00100 -#endif - -#ifndef S_IRWXU -# define S_IRWXU 00700 -#endif - -#ifndef S_IRUSR -# define S_IRUSR 00400 -#endif - -#ifndef S_IWUSR -# define S_IWUSR 00200 -#endif - -#ifndef S_IXUSR -# define S_IXUSR 00100 -#endif - -#ifndef S_IRWXG -# define S_IRWXG 00070 -#endif - -#ifndef S_IRGRP -# define S_IRGRP 00040 -#endif - -#ifndef S_IWGRP -# define S_IWGRP 00020 -#endif - -#ifndef S_IXGRP -# define S_IXGRP 00010 -#endif - -#ifndef S_IRWXO -# define S_IRWXO 00007 -#endif - -#ifndef S_IROTH -# define S_IROTH 00004 -#endif - -#ifndef S_IWOTH -# define S_IWOTH 00002 -#endif - -#ifndef S_IXOTH -# define S_IXOTH 00001 -#endif - - -/* Names for file flags */ -#ifndef UF_NODUMP -# define UF_NODUMP 0x00000001 -#endif - -#ifndef UF_IMMUTABLE -# define UF_IMMUTABLE 0x00000002 -#endif - -#ifndef UF_APPEND -# define UF_APPEND 0x00000004 -#endif - -#ifndef UF_OPAQUE -# define UF_OPAQUE 0x00000008 -#endif - -#ifndef UF_NOUNLINK -# define UF_NOUNLINK 0x00000010 -#endif - -#ifndef UF_COMPRESSED -# define UF_COMPRESSED 0x00000020 -#endif - -#ifndef UF_HIDDEN -# define UF_HIDDEN 0x00008000 -#endif - -#ifndef SF_ARCHIVED -# define SF_ARCHIVED 0x00010000 -#endif - -#ifndef SF_IMMUTABLE -# define SF_IMMUTABLE 0x00020000 -#endif - -#ifndef SF_APPEND -# define SF_APPEND 0x00040000 -#endif - -#ifndef SF_NOUNLINK -# define SF_NOUNLINK 0x00100000 -#endif - -#ifndef SF_SNAPSHOT -# define SF_SNAPSHOT 0x00200000 -#endif - -static mode_t -_PyLong_AsMode_t(PyObject *op) -{ - unsigned long value; - mode_t mode; - - value = PyLong_AsUnsignedLong(op); - if ((value == (unsigned long)-1) && PyErr_Occurred()) - return (mode_t)-1; - - mode = (mode_t)value; - if ((unsigned long)mode != value) { - PyErr_SetString(PyExc_OverflowError, "mode out of range"); - return (mode_t)-1; - } - return mode; -} - - -#define stat_S_ISFUNC(isfunc, doc) \ - static PyObject * \ - stat_ ##isfunc (PyObject *self, PyObject *omode) \ - { \ - mode_t mode = _PyLong_AsMode_t(omode); \ - if ((mode == (mode_t)-1) && PyErr_Occurred()) \ - return NULL; \ - return PyBool_FromLong(isfunc(mode)); \ - } \ - PyDoc_STRVAR(stat_ ## isfunc ## _doc, doc) - -stat_S_ISFUNC(S_ISDIR, - "S_ISDIR(mode) -> bool\n\n" - "Return True if mode is from a directory."); - -stat_S_ISFUNC(S_ISCHR, - "S_ISCHR(mode) -> bool\n\n" - "Return True if mode is from a character special device file."); - -stat_S_ISFUNC(S_ISBLK, - "S_ISBLK(mode) -> bool\n\n" - "Return True if mode is from a block special device file."); - -stat_S_ISFUNC(S_ISREG, - "S_ISREG(mode) -> bool\n\n" - "Return True if mode is from a regular file."); - -stat_S_ISFUNC(S_ISFIFO, - "S_ISFIFO(mode) -> bool\n\n" - "Return True if mode is from a FIFO (named pipe)."); - -stat_S_ISFUNC(S_ISLNK, - "S_ISLNK(mode) -> bool\n\n" - "Return True if mode is from a symbolic link."); - -stat_S_ISFUNC(S_ISSOCK, - "S_ISSOCK(mode) -> bool\n\n" - "Return True if mode is from a socket."); - -stat_S_ISFUNC(S_ISDOOR, - "S_ISDOOR(mode) -> bool\n\n" - "Return True if mode is from a door."); - -stat_S_ISFUNC(S_ISPORT, - "S_ISPORT(mode) -> bool\n\n" - "Return True if mode is from an event port."); - -stat_S_ISFUNC(S_ISWHT, - "S_ISWHT(mode) -> bool\n\n" - "Return True if mode is from a whiteout."); - - -PyDoc_STRVAR(stat_S_IMODE_doc, -"Return the portion of the file's mode that can be set by os.chmod()."); - -static PyObject * -stat_S_IMODE(PyObject *self, PyObject *omode) -{ - mode_t mode = _PyLong_AsMode_t(omode); - if ((mode == (mode_t)-1) && PyErr_Occurred()) - return NULL; - return PyLong_FromUnsignedLong(mode & S_IMODE); -} - - -PyDoc_STRVAR(stat_S_IFMT_doc, -"Return the portion of the file's mode that describes the file type."); - -static PyObject * -stat_S_IFMT(PyObject *self, PyObject *omode) -{ - mode_t mode = _PyLong_AsMode_t(omode); - if ((mode == (mode_t)-1) && PyErr_Occurred()) - return NULL; - return PyLong_FromUnsignedLong(mode & S_IFMT); -} - -/* file type chars according to - http://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h */ - -static char -filetype(mode_t mode) -{ - /* common cases first */ - if (S_ISREG(mode)) return '-'; - if (S_ISDIR(mode)) return 'd'; - if (S_ISLNK(mode)) return 'l'; - /* special files */ - if (S_ISBLK(mode)) return 'b'; - if (S_ISCHR(mode)) return 'c'; - if (S_ISFIFO(mode)) return 'p'; - if (S_ISSOCK(mode)) return 's'; - /* non-standard types */ - if (S_ISDOOR(mode)) return 'D'; - if (S_ISPORT(mode)) return 'P'; - if (S_ISWHT(mode)) return 'w'; - /* unknown */ - return '?'; -} - -static void -fileperm(mode_t mode, char *buf) -{ - buf[0] = mode & S_IRUSR ? 'r' : '-'; - buf[1] = mode & S_IWUSR ? 'w' : '-'; - if (mode & S_ISUID) { - buf[2] = mode & S_IXUSR ? 's' : 'S'; - } else { - buf[2] = mode & S_IXUSR ? 'x' : '-'; - } - buf[3] = mode & S_IRGRP ? 'r' : '-'; - buf[4] = mode & S_IWGRP ? 'w' : '-'; - if (mode & S_ISGID) { - buf[5] = mode & S_IXGRP ? 's' : 'S'; - } else { - buf[5] = mode & S_IXGRP ? 'x' : '-'; - } - buf[6] = mode & S_IROTH ? 'r' : '-'; - buf[7] = mode & S_IWOTH ? 'w' : '-'; - if (mode & S_ISVTX) { - buf[8] = mode & S_IXOTH ? 't' : 'T'; - } else { - buf[8] = mode & S_IXOTH ? 'x' : '-'; - } -} - -PyDoc_STRVAR(stat_filemode_doc, -"Convert a file's mode to a string of the form '-rwxrwxrwx'"); - -static PyObject * -stat_filemode(PyObject *self, PyObject *omode) -{ - char buf[10]; - mode_t mode; - - mode = _PyLong_AsMode_t(omode); - if ((mode == (mode_t)-1) && PyErr_Occurred()) - return NULL; - - buf[0] = filetype(mode); - fileperm(mode, &buf[1]); - return PyUnicode_FromStringAndSize(buf, 10); -} - - -static PyMethodDef stat_methods[] = { - {"S_ISDIR", stat_S_ISDIR, METH_O, stat_S_ISDIR_doc}, - {"S_ISCHR", stat_S_ISCHR, METH_O, stat_S_ISCHR_doc}, - {"S_ISBLK", stat_S_ISBLK, METH_O, stat_S_ISBLK_doc}, - {"S_ISREG", stat_S_ISREG, METH_O, stat_S_ISREG_doc}, - {"S_ISFIFO", stat_S_ISFIFO, METH_O, stat_S_ISFIFO_doc}, - {"S_ISLNK", stat_S_ISLNK, METH_O, stat_S_ISLNK_doc}, - {"S_ISSOCK", stat_S_ISSOCK, METH_O, stat_S_ISSOCK_doc}, - {"S_ISDOOR", stat_S_ISDOOR, METH_O, stat_S_ISDOOR_doc}, - {"S_ISPORT", stat_S_ISPORT, METH_O, stat_S_ISPORT_doc}, - {"S_ISWHT", stat_S_ISWHT, METH_O, stat_S_ISWHT_doc}, - {"S_IMODE", stat_S_IMODE, METH_O, stat_S_IMODE_doc}, - {"S_IFMT", stat_S_IFMT, METH_O, stat_S_IFMT_doc}, - {"filemode", stat_filemode, METH_O, stat_filemode_doc}, - {NULL, NULL} /* sentinel */ -}; - - -PyDoc_STRVAR(module_doc, -"S_IFMT_: file type bits\n\ -S_IFDIR: directory\n\ -S_IFCHR: character device\n\ -S_IFBLK: block device\n\ -S_IFREG: regular file\n\ -S_IFIFO: fifo (named pipe)\n\ -S_IFLNK: symbolic link\n\ -S_IFSOCK: socket file\n\ -S_IFDOOR: door\n\ -S_IFPORT: event port\n\ -S_IFWHT: whiteout\n\ -\n" - -"S_ISUID: set UID bit\n\ -S_ISGID: set GID bit\n\ -S_ENFMT: file locking enforcement\n\ -S_ISVTX: sticky bit\n\ -S_IREAD: Unix V7 synonym for S_IRUSR\n\ -S_IWRITE: Unix V7 synonym for S_IWUSR\n\ -S_IEXEC: Unix V7 synonym for S_IXUSR\n\ -S_IRWXU: mask for owner permissions\n\ -S_IRUSR: read by owner\n\ -S_IWUSR: write by owner\n\ -S_IXUSR: execute by owner\n\ -S_IRWXG: mask for group permissions\n\ -S_IRGRP: read by group\n\ -S_IWGRP: write by group\n\ -S_IXGRP: execute by group\n\ -S_IRWXO: mask for others (not in group) permissions\n\ -S_IROTH: read by others\n\ -S_IWOTH: write by others\n\ -S_IXOTH: execute by others\n\ -\n" - -"UF_NODUMP: do not dump file\n\ -UF_IMMUTABLE: file may not be changed\n\ -UF_APPEND: file may only be appended to\n\ -UF_OPAQUE: directory is opaque when viewed through a union stack\n\ -UF_NOUNLINK: file may not be renamed or deleted\n\ -UF_COMPRESSED: OS X: file is hfs-compressed\n\ -UF_HIDDEN: OS X: file should not be displayed\n\ -SF_ARCHIVED: file may be archived\n\ -SF_IMMUTABLE: file may not be changed\n\ -SF_APPEND: file may only be appended to\n\ -SF_NOUNLINK: file may not be renamed or deleted\n\ -SF_SNAPSHOT: file is a snapshot file\n\ -\n" - -"ST_MODE\n\ -ST_INO\n\ -ST_DEV\n\ -ST_NLINK\n\ -ST_UID\n\ -ST_GID\n\ -ST_SIZE\n\ -ST_ATIME\n\ -ST_MTIME\n\ -ST_CTIME\n\ -\n" - -"FILE_ATTRIBUTE_*: Windows file attribute constants\n\ - (only present on Windows)\n\ -"); - - +#endif /* MS_WINDOWS */ + +/* From Python's stat.py */ +#ifndef S_IMODE +# define S_IMODE 07777 +#endif + +/* S_IFXXX constants (file types) + * + * Only the names are defined by POSIX but not their value. All common file + * types seems to have the same numeric value on all platforms, though. + * + * pyport.h guarantees S_IFMT, S_IFDIR, S_IFCHR, S_IFREG and S_IFLNK + */ + +#ifndef S_IFBLK +# define S_IFBLK 0060000 +#endif + +#ifndef S_IFIFO +# define S_IFIFO 0010000 +#endif + +#ifndef S_IFSOCK +# define S_IFSOCK 0140000 +#endif + +#ifndef S_IFDOOR +# define S_IFDOOR 0 +#endif + +#ifndef S_IFPORT +# define S_IFPORT 0 +#endif + +#ifndef S_IFWHT +# define S_IFWHT 0 +#endif + + +/* S_ISXXX() + * pyport.h defines S_ISDIR(), S_ISREG() and S_ISCHR() + */ + +#ifndef S_ISBLK +# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +#endif + +#ifndef S_ISFIFO +# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#endif + +#ifndef S_ISLNK +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#endif + +#ifndef S_ISSOCK +# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#endif + +#ifndef S_ISDOOR +# define S_ISDOOR(mode) 0 +#endif + +#ifndef S_ISPORT +# define S_ISPORT(mode) 0 +#endif + +#ifndef S_ISWHT +# define S_ISWHT(mode) 0 +#endif + + +/* S_I* file permission + * + * The permission bit value are defined by POSIX standards. + */ +#ifndef S_ISUID +# define S_ISUID 04000 +#endif + +#ifndef S_ISGID +# define S_ISGID 02000 +#endif + +/* what is S_ENFMT? */ +#ifndef S_ENFMT +# define S_ENFMT S_ISGID +#endif + +#ifndef S_ISVTX +# define S_ISVTX 01000 +#endif + +#ifndef S_IREAD +# define S_IREAD 00400 +#endif + +#ifndef S_IWRITE +# define S_IWRITE 00200 +#endif + +#ifndef S_IEXEC +# define S_IEXEC 00100 +#endif + +#ifndef S_IRWXU +# define S_IRWXU 00700 +#endif + +#ifndef S_IRUSR +# define S_IRUSR 00400 +#endif + +#ifndef S_IWUSR +# define S_IWUSR 00200 +#endif + +#ifndef S_IXUSR +# define S_IXUSR 00100 +#endif + +#ifndef S_IRWXG +# define S_IRWXG 00070 +#endif + +#ifndef S_IRGRP +# define S_IRGRP 00040 +#endif + +#ifndef S_IWGRP +# define S_IWGRP 00020 +#endif + +#ifndef S_IXGRP +# define S_IXGRP 00010 +#endif + +#ifndef S_IRWXO +# define S_IRWXO 00007 +#endif + +#ifndef S_IROTH +# define S_IROTH 00004 +#endif + +#ifndef S_IWOTH +# define S_IWOTH 00002 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 00001 +#endif + + +/* Names for file flags */ +#ifndef UF_NODUMP +# define UF_NODUMP 0x00000001 +#endif + +#ifndef UF_IMMUTABLE +# define UF_IMMUTABLE 0x00000002 +#endif + +#ifndef UF_APPEND +# define UF_APPEND 0x00000004 +#endif + +#ifndef UF_OPAQUE +# define UF_OPAQUE 0x00000008 +#endif + +#ifndef UF_NOUNLINK +# define UF_NOUNLINK 0x00000010 +#endif + +#ifndef UF_COMPRESSED +# define UF_COMPRESSED 0x00000020 +#endif + +#ifndef UF_HIDDEN +# define UF_HIDDEN 0x00008000 +#endif + +#ifndef SF_ARCHIVED +# define SF_ARCHIVED 0x00010000 +#endif + +#ifndef SF_IMMUTABLE +# define SF_IMMUTABLE 0x00020000 +#endif + +#ifndef SF_APPEND +# define SF_APPEND 0x00040000 +#endif + +#ifndef SF_NOUNLINK +# define SF_NOUNLINK 0x00100000 +#endif + +#ifndef SF_SNAPSHOT +# define SF_SNAPSHOT 0x00200000 +#endif + +static mode_t +_PyLong_AsMode_t(PyObject *op) +{ + unsigned long value; + mode_t mode; + + value = PyLong_AsUnsignedLong(op); + if ((value == (unsigned long)-1) && PyErr_Occurred()) + return (mode_t)-1; + + mode = (mode_t)value; + if ((unsigned long)mode != value) { + PyErr_SetString(PyExc_OverflowError, "mode out of range"); + return (mode_t)-1; + } + return mode; +} + + +#define stat_S_ISFUNC(isfunc, doc) \ + static PyObject * \ + stat_ ##isfunc (PyObject *self, PyObject *omode) \ + { \ + mode_t mode = _PyLong_AsMode_t(omode); \ + if ((mode == (mode_t)-1) && PyErr_Occurred()) \ + return NULL; \ + return PyBool_FromLong(isfunc(mode)); \ + } \ + PyDoc_STRVAR(stat_ ## isfunc ## _doc, doc) + +stat_S_ISFUNC(S_ISDIR, + "S_ISDIR(mode) -> bool\n\n" + "Return True if mode is from a directory."); + +stat_S_ISFUNC(S_ISCHR, + "S_ISCHR(mode) -> bool\n\n" + "Return True if mode is from a character special device file."); + +stat_S_ISFUNC(S_ISBLK, + "S_ISBLK(mode) -> bool\n\n" + "Return True if mode is from a block special device file."); + +stat_S_ISFUNC(S_ISREG, + "S_ISREG(mode) -> bool\n\n" + "Return True if mode is from a regular file."); + +stat_S_ISFUNC(S_ISFIFO, + "S_ISFIFO(mode) -> bool\n\n" + "Return True if mode is from a FIFO (named pipe)."); + +stat_S_ISFUNC(S_ISLNK, + "S_ISLNK(mode) -> bool\n\n" + "Return True if mode is from a symbolic link."); + +stat_S_ISFUNC(S_ISSOCK, + "S_ISSOCK(mode) -> bool\n\n" + "Return True if mode is from a socket."); + +stat_S_ISFUNC(S_ISDOOR, + "S_ISDOOR(mode) -> bool\n\n" + "Return True if mode is from a door."); + +stat_S_ISFUNC(S_ISPORT, + "S_ISPORT(mode) -> bool\n\n" + "Return True if mode is from an event port."); + +stat_S_ISFUNC(S_ISWHT, + "S_ISWHT(mode) -> bool\n\n" + "Return True if mode is from a whiteout."); + + +PyDoc_STRVAR(stat_S_IMODE_doc, +"Return the portion of the file's mode that can be set by os.chmod()."); + +static PyObject * +stat_S_IMODE(PyObject *self, PyObject *omode) +{ + mode_t mode = _PyLong_AsMode_t(omode); + if ((mode == (mode_t)-1) && PyErr_Occurred()) + return NULL; + return PyLong_FromUnsignedLong(mode & S_IMODE); +} + + +PyDoc_STRVAR(stat_S_IFMT_doc, +"Return the portion of the file's mode that describes the file type."); + +static PyObject * +stat_S_IFMT(PyObject *self, PyObject *omode) +{ + mode_t mode = _PyLong_AsMode_t(omode); + if ((mode == (mode_t)-1) && PyErr_Occurred()) + return NULL; + return PyLong_FromUnsignedLong(mode & S_IFMT); +} + +/* file type chars according to + http://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h */ + +static char +filetype(mode_t mode) +{ + /* common cases first */ + if (S_ISREG(mode)) return '-'; + if (S_ISDIR(mode)) return 'd'; + if (S_ISLNK(mode)) return 'l'; + /* special files */ + if (S_ISBLK(mode)) return 'b'; + if (S_ISCHR(mode)) return 'c'; + if (S_ISFIFO(mode)) return 'p'; + if (S_ISSOCK(mode)) return 's'; + /* non-standard types */ + if (S_ISDOOR(mode)) return 'D'; + if (S_ISPORT(mode)) return 'P'; + if (S_ISWHT(mode)) return 'w'; + /* unknown */ + return '?'; +} + +static void +fileperm(mode_t mode, char *buf) +{ + buf[0] = mode & S_IRUSR ? 'r' : '-'; + buf[1] = mode & S_IWUSR ? 'w' : '-'; + if (mode & S_ISUID) { + buf[2] = mode & S_IXUSR ? 's' : 'S'; + } else { + buf[2] = mode & S_IXUSR ? 'x' : '-'; + } + buf[3] = mode & S_IRGRP ? 'r' : '-'; + buf[4] = mode & S_IWGRP ? 'w' : '-'; + if (mode & S_ISGID) { + buf[5] = mode & S_IXGRP ? 's' : 'S'; + } else { + buf[5] = mode & S_IXGRP ? 'x' : '-'; + } + buf[6] = mode & S_IROTH ? 'r' : '-'; + buf[7] = mode & S_IWOTH ? 'w' : '-'; + if (mode & S_ISVTX) { + buf[8] = mode & S_IXOTH ? 't' : 'T'; + } else { + buf[8] = mode & S_IXOTH ? 'x' : '-'; + } +} + +PyDoc_STRVAR(stat_filemode_doc, +"Convert a file's mode to a string of the form '-rwxrwxrwx'"); + +static PyObject * +stat_filemode(PyObject *self, PyObject *omode) +{ + char buf[10]; + mode_t mode; + + mode = _PyLong_AsMode_t(omode); + if ((mode == (mode_t)-1) && PyErr_Occurred()) + return NULL; + + buf[0] = filetype(mode); + fileperm(mode, &buf[1]); + return PyUnicode_FromStringAndSize(buf, 10); +} + + +static PyMethodDef stat_methods[] = { + {"S_ISDIR", stat_S_ISDIR, METH_O, stat_S_ISDIR_doc}, + {"S_ISCHR", stat_S_ISCHR, METH_O, stat_S_ISCHR_doc}, + {"S_ISBLK", stat_S_ISBLK, METH_O, stat_S_ISBLK_doc}, + {"S_ISREG", stat_S_ISREG, METH_O, stat_S_ISREG_doc}, + {"S_ISFIFO", stat_S_ISFIFO, METH_O, stat_S_ISFIFO_doc}, + {"S_ISLNK", stat_S_ISLNK, METH_O, stat_S_ISLNK_doc}, + {"S_ISSOCK", stat_S_ISSOCK, METH_O, stat_S_ISSOCK_doc}, + {"S_ISDOOR", stat_S_ISDOOR, METH_O, stat_S_ISDOOR_doc}, + {"S_ISPORT", stat_S_ISPORT, METH_O, stat_S_ISPORT_doc}, + {"S_ISWHT", stat_S_ISWHT, METH_O, stat_S_ISWHT_doc}, + {"S_IMODE", stat_S_IMODE, METH_O, stat_S_IMODE_doc}, + {"S_IFMT", stat_S_IFMT, METH_O, stat_S_IFMT_doc}, + {"filemode", stat_filemode, METH_O, stat_filemode_doc}, + {NULL, NULL} /* sentinel */ +}; + + +PyDoc_STRVAR(module_doc, +"S_IFMT_: file type bits\n\ +S_IFDIR: directory\n\ +S_IFCHR: character device\n\ +S_IFBLK: block device\n\ +S_IFREG: regular file\n\ +S_IFIFO: fifo (named pipe)\n\ +S_IFLNK: symbolic link\n\ +S_IFSOCK: socket file\n\ +S_IFDOOR: door\n\ +S_IFPORT: event port\n\ +S_IFWHT: whiteout\n\ +\n" + +"S_ISUID: set UID bit\n\ +S_ISGID: set GID bit\n\ +S_ENFMT: file locking enforcement\n\ +S_ISVTX: sticky bit\n\ +S_IREAD: Unix V7 synonym for S_IRUSR\n\ +S_IWRITE: Unix V7 synonym for S_IWUSR\n\ +S_IEXEC: Unix V7 synonym for S_IXUSR\n\ +S_IRWXU: mask for owner permissions\n\ +S_IRUSR: read by owner\n\ +S_IWUSR: write by owner\n\ +S_IXUSR: execute by owner\n\ +S_IRWXG: mask for group permissions\n\ +S_IRGRP: read by group\n\ +S_IWGRP: write by group\n\ +S_IXGRP: execute by group\n\ +S_IRWXO: mask for others (not in group) permissions\n\ +S_IROTH: read by others\n\ +S_IWOTH: write by others\n\ +S_IXOTH: execute by others\n\ +\n" + +"UF_NODUMP: do not dump file\n\ +UF_IMMUTABLE: file may not be changed\n\ +UF_APPEND: file may only be appended to\n\ +UF_OPAQUE: directory is opaque when viewed through a union stack\n\ +UF_NOUNLINK: file may not be renamed or deleted\n\ +UF_COMPRESSED: OS X: file is hfs-compressed\n\ +UF_HIDDEN: OS X: file should not be displayed\n\ +SF_ARCHIVED: file may be archived\n\ +SF_IMMUTABLE: file may not be changed\n\ +SF_APPEND: file may only be appended to\n\ +SF_NOUNLINK: file may not be renamed or deleted\n\ +SF_SNAPSHOT: file is a snapshot file\n\ +\n" + +"ST_MODE\n\ +ST_INO\n\ +ST_DEV\n\ +ST_NLINK\n\ +ST_UID\n\ +ST_GID\n\ +ST_SIZE\n\ +ST_ATIME\n\ +ST_MTIME\n\ +ST_CTIME\n\ +\n" + +"FILE_ATTRIBUTE_*: Windows file attribute constants\n\ + (only present on Windows)\n\ +"); + + static int stat_exec(PyObject *module) -{ +{ #define ADD_INT_MACRO(module, macro) \ do { \ if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \ return -1; \ } \ } while (0) - + ADD_INT_MACRO(module, S_IFDIR); ADD_INT_MACRO(module, S_IFCHR); ADD_INT_MACRO(module, S_IFBLK); @@ -516,31 +516,31 @@ stat_exec(PyObject *module) ADD_INT_MACRO(module, S_IFDOOR); ADD_INT_MACRO(module, S_IFPORT); ADD_INT_MACRO(module, S_IFWHT); - + ADD_INT_MACRO(module, S_ISUID); ADD_INT_MACRO(module, S_ISGID); ADD_INT_MACRO(module, S_ISVTX); ADD_INT_MACRO(module, S_ENFMT); - + ADD_INT_MACRO(module, S_IREAD); ADD_INT_MACRO(module, S_IWRITE); ADD_INT_MACRO(module, S_IEXEC); - + ADD_INT_MACRO(module, S_IRWXU); ADD_INT_MACRO(module, S_IRUSR); ADD_INT_MACRO(module, S_IWUSR); ADD_INT_MACRO(module, S_IXUSR); - + ADD_INT_MACRO(module, S_IRWXG); ADD_INT_MACRO(module, S_IRGRP); ADD_INT_MACRO(module, S_IWGRP); ADD_INT_MACRO(module, S_IXGRP); - + ADD_INT_MACRO(module, S_IRWXO); ADD_INT_MACRO(module, S_IROTH); ADD_INT_MACRO(module, S_IWOTH); ADD_INT_MACRO(module, S_IXOTH); - + ADD_INT_MACRO(module, UF_NODUMP); ADD_INT_MACRO(module, UF_IMMUTABLE); ADD_INT_MACRO(module, UF_APPEND); @@ -553,7 +553,7 @@ stat_exec(PyObject *module) ADD_INT_MACRO(module, SF_APPEND); ADD_INT_MACRO(module, SF_NOUNLINK); ADD_INT_MACRO(module, SF_SNAPSHOT); - + const char* st_constants[] = { "ST_MODE", "ST_INO", @@ -566,14 +566,14 @@ stat_exec(PyObject *module) "ST_MTIME", "ST_CTIME" }; - + for (int i = 0; i < (int)Py_ARRAY_LENGTH(st_constants); i++) { if (PyModule_AddIntConstant(module, st_constants[i], i) < 0) { return -1; } } -#ifdef MS_WINDOWS +#ifdef MS_WINDOWS ADD_INT_MACRO(module, FILE_ATTRIBUTE_ARCHIVE); ADD_INT_MACRO(module, FILE_ATTRIBUTE_COMPRESSED); ADD_INT_MACRO(module, FILE_ATTRIBUTE_DEVICE); @@ -604,11 +604,11 @@ stat_exec(PyObject *module) PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK)) < 0) { return -1; } -#endif - +#endif + return 0; -} - +} + static PyModuleDef_Slot stat_slots[] = { {Py_mod_exec, stat_exec}, @@ -632,6 +632,6 @@ PyInit__stat(void) return PyModuleDef_Init(&statmodule); } -#ifdef __cplusplus -} -#endif +#ifdef __cplusplus +} +#endif diff --git a/contrib/tools/python3/src/Modules/_struct.c b/contrib/tools/python3/src/Modules/_struct.c index f759f0b1694..be20fb29ef8 100644 --- a/contrib/tools/python3/src/Modules/_struct.c +++ b/contrib/tools/python3/src/Modules/_struct.c @@ -1,25 +1,25 @@ -/* struct module -- pack values into and (out of) bytes objects */ - -/* New version supporting byte order, alignment and size options, - character strings, and unsigned numbers */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" +/* struct module -- pack values into and (out of) bytes objects */ + +/* New version supporting byte order, alignment and size options, + character strings, and unsigned numbers */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" #include "structmember.h" // PyMemberDef -#include - -/*[clinic input] -class Struct "PyStructObject *" "&PyStructType" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/ - +#include + +/*[clinic input] +class Struct "PyStructObject *" "&PyStructType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/ + typedef struct { PyObject *PyStructType; PyObject *unpackiter_type; PyObject *StructError; } _structmodulestate; - + static inline _structmodulestate* get_struct_state(PyObject *module) { @@ -32,1561 +32,1561 @@ static struct PyModuleDef _structmodule; #define _structmodulestate_global get_struct_state(PyState_FindModule(&_structmodule)) -/* The translation function for each format character is table driven */ -typedef struct _formatdef { - char format; - Py_ssize_t size; - Py_ssize_t alignment; - PyObject* (*unpack)(const char *, - const struct _formatdef *); - int (*pack)(char *, PyObject *, - const struct _formatdef *); -} formatdef; - -typedef struct _formatcode { - const struct _formatdef *fmtdef; - Py_ssize_t offset; - Py_ssize_t size; - Py_ssize_t repeat; -} formatcode; - -/* Struct object interface */ - -typedef struct { - PyObject_HEAD - Py_ssize_t s_size; - Py_ssize_t s_len; - formatcode *s_codes; - PyObject *s_format; - PyObject *weakreflist; /* List of weak references */ -} PyStructObject; - - +/* The translation function for each format character is table driven */ +typedef struct _formatdef { + char format; + Py_ssize_t size; + Py_ssize_t alignment; + PyObject* (*unpack)(const char *, + const struct _formatdef *); + int (*pack)(char *, PyObject *, + const struct _formatdef *); +} formatdef; + +typedef struct _formatcode { + const struct _formatdef *fmtdef; + Py_ssize_t offset; + Py_ssize_t size; + Py_ssize_t repeat; +} formatcode; + +/* Struct object interface */ + +typedef struct { + PyObject_HEAD + Py_ssize_t s_size; + Py_ssize_t s_len; + formatcode *s_codes; + PyObject *s_format; + PyObject *weakreflist; /* List of weak references */ +} PyStructObject; + + #define PyStruct_Check(op) PyObject_TypeCheck(op, (PyTypeObject *)_structmodulestate_global->PyStructType) #define PyStruct_CheckExact(op) Py_IS_TYPE(op, (PyTypeObject *)_structmodulestate_global->PyStructType) - - -/* Define various structs to figure out the alignments of types */ - - -typedef struct { char c; short x; } st_short; -typedef struct { char c; int x; } st_int; -typedef struct { char c; long x; } st_long; -typedef struct { char c; float x; } st_float; -typedef struct { char c; double x; } st_double; -typedef struct { char c; void *x; } st_void_p; -typedef struct { char c; size_t x; } st_size_t; -typedef struct { char c; _Bool x; } st_bool; - -#define SHORT_ALIGN (sizeof(st_short) - sizeof(short)) -#define INT_ALIGN (sizeof(st_int) - sizeof(int)) -#define LONG_ALIGN (sizeof(st_long) - sizeof(long)) -#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float)) -#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double)) -#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *)) -#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t)) -#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool)) - -/* We can't support q and Q in native mode unless the compiler does; - in std mode, they're 8 bytes on all platforms. */ -typedef struct { char c; long long x; } s_long_long; -#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) - -#ifdef __powerc -#pragma options align=reset -#endif - -/*[python input] -class cache_struct_converter(CConverter): - type = 'PyStructObject *' - converter = 'cache_struct_converter' - c_default = "NULL" - - def cleanup(self): - return "Py_XDECREF(%s);\n" % self.name -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/ - + + +/* Define various structs to figure out the alignments of types */ + + +typedef struct { char c; short x; } st_short; +typedef struct { char c; int x; } st_int; +typedef struct { char c; long x; } st_long; +typedef struct { char c; float x; } st_float; +typedef struct { char c; double x; } st_double; +typedef struct { char c; void *x; } st_void_p; +typedef struct { char c; size_t x; } st_size_t; +typedef struct { char c; _Bool x; } st_bool; + +#define SHORT_ALIGN (sizeof(st_short) - sizeof(short)) +#define INT_ALIGN (sizeof(st_int) - sizeof(int)) +#define LONG_ALIGN (sizeof(st_long) - sizeof(long)) +#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float)) +#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double)) +#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *)) +#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t)) +#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool)) + +/* We can't support q and Q in native mode unless the compiler does; + in std mode, they're 8 bytes on all platforms. */ +typedef struct { char c; long long x; } s_long_long; +#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) + +#ifdef __powerc +#pragma options align=reset +#endif + +/*[python input] +class cache_struct_converter(CConverter): + type = 'PyStructObject *' + converter = 'cache_struct_converter' + c_default = "NULL" + + def cleanup(self): + return "Py_XDECREF(%s);\n" % self.name +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/ + static int cache_struct_converter(PyObject *, PyStructObject **); - -#include "clinic/_struct.c.h" - -/* Helper for integer format codes: converts an arbitrary Python object to a - PyLongObject if possible, otherwise fails. Caller should decref. */ - -static PyObject * -get_pylong(PyObject *v) -{ - assert(v != NULL); - if (!PyLong_Check(v)) { - /* Not an integer; try to use __index__ to convert. */ - if (PyIndex_Check(v)) { - v = PyNumber_Index(v); - if (v == NULL) - return NULL; - } - else { + +#include "clinic/_struct.c.h" + +/* Helper for integer format codes: converts an arbitrary Python object to a + PyLongObject if possible, otherwise fails. Caller should decref. */ + +static PyObject * +get_pylong(PyObject *v) +{ + assert(v != NULL); + if (!PyLong_Check(v)) { + /* Not an integer; try to use __index__ to convert. */ + if (PyIndex_Check(v)) { + v = PyNumber_Index(v); + if (v == NULL) + return NULL; + } + else { PyErr_SetString(_structmodulestate_global->StructError, - "required argument is not an integer"); - return NULL; - } - } - else - Py_INCREF(v); - - assert(PyLong_Check(v)); - return v; -} - -/* Helper routine to get a C long and raise the appropriate error if it isn't - one */ - -static int -get_long(PyObject *v, long *p) -{ - long x; - - v = get_pylong(v); - if (v == NULL) - return -1; - assert(PyLong_Check(v)); - x = PyLong_AsLong(v); - Py_DECREF(v); - if (x == (long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) + "required argument is not an integer"); + return NULL; + } + } + else + Py_INCREF(v); + + assert(PyLong_Check(v)); + return v; +} + +/* Helper routine to get a C long and raise the appropriate error if it isn't + one */ + +static int +get_long(PyObject *v, long *p) +{ + long x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsLong(v); + Py_DECREF(v); + if (x == (long)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(_structmodulestate_global->StructError, - "argument out of range"); - return -1; - } - *p = x; - return 0; -} - - -/* Same, but handling unsigned long */ - -static int -get_ulong(PyObject *v, unsigned long *p) -{ - unsigned long x; - - v = get_pylong(v); - if (v == NULL) - return -1; - assert(PyLong_Check(v)); - x = PyLong_AsUnsignedLong(v); - Py_DECREF(v); - if (x == (unsigned long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) + "argument out of range"); + return -1; + } + *p = x; + return 0; +} + + +/* Same, but handling unsigned long */ + +static int +get_ulong(PyObject *v, unsigned long *p) +{ + unsigned long x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsUnsignedLong(v); + Py_DECREF(v); + if (x == (unsigned long)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(_structmodulestate_global->StructError, - "argument out of range"); - return -1; - } - *p = x; - return 0; -} - -/* Same, but handling native long long. */ - -static int -get_longlong(PyObject *v, long long *p) -{ - long long x; - - v = get_pylong(v); - if (v == NULL) - return -1; - assert(PyLong_Check(v)); - x = PyLong_AsLongLong(v); - Py_DECREF(v); - if (x == (long long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) + "argument out of range"); + return -1; + } + *p = x; + return 0; +} + +/* Same, but handling native long long. */ + +static int +get_longlong(PyObject *v, long long *p) +{ + long long x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsLongLong(v); + Py_DECREF(v); + if (x == (long long)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(_structmodulestate_global->StructError, - "argument out of range"); - return -1; - } - *p = x; - return 0; -} - -/* Same, but handling native unsigned long long. */ - -static int -get_ulonglong(PyObject *v, unsigned long long *p) -{ - unsigned long long x; - - v = get_pylong(v); - if (v == NULL) - return -1; - assert(PyLong_Check(v)); - x = PyLong_AsUnsignedLongLong(v); - Py_DECREF(v); - if (x == (unsigned long long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) + "argument out of range"); + return -1; + } + *p = x; + return 0; +} + +/* Same, but handling native unsigned long long. */ + +static int +get_ulonglong(PyObject *v, unsigned long long *p) +{ + unsigned long long x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsUnsignedLongLong(v); + Py_DECREF(v); + if (x == (unsigned long long)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(_structmodulestate_global->StructError, - "argument out of range"); - return -1; - } - *p = x; - return 0; -} - -/* Same, but handling Py_ssize_t */ - -static int -get_ssize_t(PyObject *v, Py_ssize_t *p) -{ - Py_ssize_t x; - - v = get_pylong(v); - if (v == NULL) - return -1; - assert(PyLong_Check(v)); - x = PyLong_AsSsize_t(v); - Py_DECREF(v); - if (x == (Py_ssize_t)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) + "argument out of range"); + return -1; + } + *p = x; + return 0; +} + +/* Same, but handling Py_ssize_t */ + +static int +get_ssize_t(PyObject *v, Py_ssize_t *p) +{ + Py_ssize_t x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsSsize_t(v); + Py_DECREF(v); + if (x == (Py_ssize_t)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(_structmodulestate_global->StructError, - "argument out of range"); - return -1; - } - *p = x; - return 0; -} - -/* Same, but handling size_t */ - -static int -get_size_t(PyObject *v, size_t *p) -{ - size_t x; - - v = get_pylong(v); - if (v == NULL) - return -1; - assert(PyLong_Check(v)); - x = PyLong_AsSize_t(v); - Py_DECREF(v); - if (x == (size_t)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) + "argument out of range"); + return -1; + } + *p = x; + return 0; +} + +/* Same, but handling size_t */ + +static int +get_size_t(PyObject *v, size_t *p) +{ + size_t x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsSize_t(v); + Py_DECREF(v); + if (x == (size_t)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(_structmodulestate_global->StructError, - "argument out of range"); - return -1; - } - *p = x; - return 0; -} - - -#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag) - - -/* Floating point helpers */ - -static PyObject * -unpack_halffloat(const char *p, /* start of 2-byte string */ - int le) /* true for little-endian, false for big-endian */ -{ - double x; - - x = _PyFloat_Unpack2((unsigned char *)p, le); - if (x == -1.0 && PyErr_Occurred()) { - return NULL; - } - return PyFloat_FromDouble(x); -} - -static int -pack_halffloat(char *p, /* start of 2-byte string */ - PyObject *v, /* value to pack */ - int le) /* true for little-endian, false for big-endian */ -{ - double x = PyFloat_AsDouble(v); - if (x == -1.0 && PyErr_Occurred()) { + "argument out of range"); + return -1; + } + *p = x; + return 0; +} + + +#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag) + + +/* Floating point helpers */ + +static PyObject * +unpack_halffloat(const char *p, /* start of 2-byte string */ + int le) /* true for little-endian, false for big-endian */ +{ + double x; + + x = _PyFloat_Unpack2((unsigned char *)p, le); + if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(x); +} + +static int +pack_halffloat(char *p, /* start of 2-byte string */ + PyObject *v, /* value to pack */ + int le) /* true for little-endian, false for big-endian */ +{ + double x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) { PyErr_SetString(_structmodulestate_global->StructError, - "required argument is not a float"); - return -1; - } - return _PyFloat_Pack2(x, (unsigned char *)p, le); -} - -static PyObject * -unpack_float(const char *p, /* start of 4-byte string */ - int le) /* true for little-endian, false for big-endian */ -{ - double x; - - x = _PyFloat_Unpack4((unsigned char *)p, le); - if (x == -1.0 && PyErr_Occurred()) - return NULL; - return PyFloat_FromDouble(x); -} - -static PyObject * -unpack_double(const char *p, /* start of 8-byte string */ - int le) /* true for little-endian, false for big-endian */ -{ - double x; - - x = _PyFloat_Unpack8((unsigned char *)p, le); - if (x == -1.0 && PyErr_Occurred()) - return NULL; - return PyFloat_FromDouble(x); -} - -/* Helper to format the range error exceptions */ -static int -_range_error(const formatdef *f, int is_unsigned) -{ - /* ulargest is the largest unsigned value with f->size bytes. - * Note that the simpler: - * ((size_t)1 << (f->size * 8)) - 1 - * doesn't work when f->size == sizeof(size_t) because C doesn't - * define what happens when a left shift count is >= the number of - * bits in the integer being shifted; e.g., on some boxes it doesn't - * shift at all when they're equal. - */ - const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8); - assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T); - if (is_unsigned) + "required argument is not a float"); + return -1; + } + return _PyFloat_Pack2(x, (unsigned char *)p, le); +} + +static PyObject * +unpack_float(const char *p, /* start of 4-byte string */ + int le) /* true for little-endian, false for big-endian */ +{ + double x; + + x = _PyFloat_Unpack4((unsigned char *)p, le); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble(x); +} + +static PyObject * +unpack_double(const char *p, /* start of 8-byte string */ + int le) /* true for little-endian, false for big-endian */ +{ + double x; + + x = _PyFloat_Unpack8((unsigned char *)p, le); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble(x); +} + +/* Helper to format the range error exceptions */ +static int +_range_error(const formatdef *f, int is_unsigned) +{ + /* ulargest is the largest unsigned value with f->size bytes. + * Note that the simpler: + * ((size_t)1 << (f->size * 8)) - 1 + * doesn't work when f->size == sizeof(size_t) because C doesn't + * define what happens when a left shift count is >= the number of + * bits in the integer being shifted; e.g., on some boxes it doesn't + * shift at all when they're equal. + */ + const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8); + assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T); + if (is_unsigned) PyErr_Format(_structmodulestate_global->StructError, - "'%c' format requires 0 <= number <= %zu", - f->format, - ulargest); - else { - const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1); + "'%c' format requires 0 <= number <= %zu", + f->format, + ulargest); + else { + const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1); PyErr_Format(_structmodulestate_global->StructError, - "'%c' format requires %zd <= number <= %zd", - f->format, - ~ largest, - largest); - } - - return -1; -} - - - -/* A large number of small routines follow, with names of the form - - [bln][up]_TYPE - + "'%c' format requires %zd <= number <= %zd", + f->format, + ~ largest, + largest); + } + + return -1; +} + + + +/* A large number of small routines follow, with names of the form + + [bln][up]_TYPE + [bln] distinguishes among big-endian, little-endian and native. [pu] distinguishes between pack (to struct) and unpack (from struct). - TYPE is one of char, byte, ubyte, etc. -*/ - -/* Native mode routines. ****************************************************/ -/* NOTE: - In all n[up]_ routines handling types larger than 1 byte, there is - *no* guarantee that the p pointer is properly aligned for each type, - therefore memcpy is called. An intermediate variable is used to - compensate for big-endian architectures. - Normally both the intermediate variable and the memcpy call will be - skipped by C optimisation in little-endian architectures (gcc >= 2.91 - does this). */ - -static PyObject * -nu_char(const char *p, const formatdef *f) -{ - return PyBytes_FromStringAndSize(p, 1); -} - -static PyObject * -nu_byte(const char *p, const formatdef *f) -{ - return PyLong_FromLong((long) *(signed char *)p); -} - -static PyObject * -nu_ubyte(const char *p, const formatdef *f) -{ - return PyLong_FromLong((long) *(unsigned char *)p); -} - -static PyObject * -nu_short(const char *p, const formatdef *f) -{ - short x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromLong((long)x); -} - -static PyObject * -nu_ushort(const char *p, const formatdef *f) -{ - unsigned short x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromLong((long)x); -} - -static PyObject * -nu_int(const char *p, const formatdef *f) -{ - int x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromLong((long)x); -} - -static PyObject * -nu_uint(const char *p, const formatdef *f) -{ - unsigned int x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromUnsignedLong((unsigned long)x); -} - -static PyObject * -nu_long(const char *p, const formatdef *f) -{ - long x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromLong(x); -} - -static PyObject * -nu_ulong(const char *p, const formatdef *f) -{ - unsigned long x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromUnsignedLong(x); -} - -static PyObject * -nu_ssize_t(const char *p, const formatdef *f) -{ - Py_ssize_t x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromSsize_t(x); -} - -static PyObject * -nu_size_t(const char *p, const formatdef *f) -{ - size_t x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromSize_t(x); -} - -static PyObject * -nu_longlong(const char *p, const formatdef *f) -{ - long long x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromLongLong(x); -} - -static PyObject * -nu_ulonglong(const char *p, const formatdef *f) -{ - unsigned long long x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromUnsignedLongLong(x); -} - -static PyObject * -nu_bool(const char *p, const formatdef *f) -{ - _Bool x; - memcpy((char *)&x, p, sizeof x); - return PyBool_FromLong(x != 0); -} - - -static PyObject * -nu_halffloat(const char *p, const formatdef *f) -{ -#if PY_LITTLE_ENDIAN - return unpack_halffloat(p, 1); -#else - return unpack_halffloat(p, 0); -#endif -} - -static PyObject * -nu_float(const char *p, const formatdef *f) -{ - float x; - memcpy((char *)&x, p, sizeof x); - return PyFloat_FromDouble((double)x); -} - -static PyObject * -nu_double(const char *p, const formatdef *f) -{ - double x; - memcpy((char *)&x, p, sizeof x); - return PyFloat_FromDouble(x); -} - -static PyObject * -nu_void_p(const char *p, const formatdef *f) -{ - void *x; - memcpy((char *)&x, p, sizeof x); - return PyLong_FromVoidPtr(x); -} - -static int -np_byte(char *p, PyObject *v, const formatdef *f) -{ - long x; - if (get_long(v, &x) < 0) - return -1; - if (x < -128 || x > 127) { + TYPE is one of char, byte, ubyte, etc. +*/ + +/* Native mode routines. ****************************************************/ +/* NOTE: + In all n[up]_ routines handling types larger than 1 byte, there is + *no* guarantee that the p pointer is properly aligned for each type, + therefore memcpy is called. An intermediate variable is used to + compensate for big-endian architectures. + Normally both the intermediate variable and the memcpy call will be + skipped by C optimisation in little-endian architectures (gcc >= 2.91 + does this). */ + +static PyObject * +nu_char(const char *p, const formatdef *f) +{ + return PyBytes_FromStringAndSize(p, 1); +} + +static PyObject * +nu_byte(const char *p, const formatdef *f) +{ + return PyLong_FromLong((long) *(signed char *)p); +} + +static PyObject * +nu_ubyte(const char *p, const formatdef *f) +{ + return PyLong_FromLong((long) *(unsigned char *)p); +} + +static PyObject * +nu_short(const char *p, const formatdef *f) +{ + short x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromLong((long)x); +} + +static PyObject * +nu_ushort(const char *p, const formatdef *f) +{ + unsigned short x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromLong((long)x); +} + +static PyObject * +nu_int(const char *p, const formatdef *f) +{ + int x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromLong((long)x); +} + +static PyObject * +nu_uint(const char *p, const formatdef *f) +{ + unsigned int x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromUnsignedLong((unsigned long)x); +} + +static PyObject * +nu_long(const char *p, const formatdef *f) +{ + long x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromLong(x); +} + +static PyObject * +nu_ulong(const char *p, const formatdef *f) +{ + unsigned long x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromUnsignedLong(x); +} + +static PyObject * +nu_ssize_t(const char *p, const formatdef *f) +{ + Py_ssize_t x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromSsize_t(x); +} + +static PyObject * +nu_size_t(const char *p, const formatdef *f) +{ + size_t x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromSize_t(x); +} + +static PyObject * +nu_longlong(const char *p, const formatdef *f) +{ + long long x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromLongLong(x); +} + +static PyObject * +nu_ulonglong(const char *p, const formatdef *f) +{ + unsigned long long x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromUnsignedLongLong(x); +} + +static PyObject * +nu_bool(const char *p, const formatdef *f) +{ + _Bool x; + memcpy((char *)&x, p, sizeof x); + return PyBool_FromLong(x != 0); +} + + +static PyObject * +nu_halffloat(const char *p, const formatdef *f) +{ +#if PY_LITTLE_ENDIAN + return unpack_halffloat(p, 1); +#else + return unpack_halffloat(p, 0); +#endif +} + +static PyObject * +nu_float(const char *p, const formatdef *f) +{ + float x; + memcpy((char *)&x, p, sizeof x); + return PyFloat_FromDouble((double)x); +} + +static PyObject * +nu_double(const char *p, const formatdef *f) +{ + double x; + memcpy((char *)&x, p, sizeof x); + return PyFloat_FromDouble(x); +} + +static PyObject * +nu_void_p(const char *p, const formatdef *f) +{ + void *x; + memcpy((char *)&x, p, sizeof x); + return PyLong_FromVoidPtr(x); +} + +static int +np_byte(char *p, PyObject *v, const formatdef *f) +{ + long x; + if (get_long(v, &x) < 0) + return -1; + if (x < -128 || x > 127) { PyErr_SetString(_structmodulestate_global->StructError, - "byte format requires -128 <= number <= 127"); - return -1; - } - *p = (char)x; - return 0; -} - -static int -np_ubyte(char *p, PyObject *v, const formatdef *f) -{ - long x; - if (get_long(v, &x) < 0) - return -1; - if (x < 0 || x > 255) { + "byte format requires -128 <= number <= 127"); + return -1; + } + *p = (char)x; + return 0; +} + +static int +np_ubyte(char *p, PyObject *v, const formatdef *f) +{ + long x; + if (get_long(v, &x) < 0) + return -1; + if (x < 0 || x > 255) { PyErr_SetString(_structmodulestate_global->StructError, - "ubyte format requires 0 <= number <= 255"); - return -1; - } - *(unsigned char *)p = (unsigned char)x; - return 0; -} - -static int -np_char(char *p, PyObject *v, const formatdef *f) -{ + "ubyte format requires 0 <= number <= 255"); + return -1; + } + *(unsigned char *)p = (unsigned char)x; + return 0; +} + +static int +np_char(char *p, PyObject *v, const formatdef *f) +{ if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) { PyErr_SetString(_structmodulestate_global->StructError, - "char format requires a bytes object of length 1"); - return -1; - } - *p = *PyBytes_AS_STRING(v); - return 0; -} - -static int -np_short(char *p, PyObject *v, const formatdef *f) -{ - long x; - short y; - if (get_long(v, &x) < 0) - return -1; - if (x < SHRT_MIN || x > SHRT_MAX) { + "char format requires a bytes object of length 1"); + return -1; + } + *p = *PyBytes_AS_STRING(v); + return 0; +} + +static int +np_short(char *p, PyObject *v, const formatdef *f) +{ + long x; + short y; + if (get_long(v, &x) < 0) + return -1; + if (x < SHRT_MIN || x > SHRT_MAX) { PyErr_SetString(_structmodulestate_global->StructError, - "short format requires " Py_STRINGIFY(SHRT_MIN) - " <= number <= " Py_STRINGIFY(SHRT_MAX)); - return -1; - } - y = (short)x; - memcpy(p, (char *)&y, sizeof y); - return 0; -} - -static int -np_ushort(char *p, PyObject *v, const formatdef *f) -{ - long x; - unsigned short y; - if (get_long(v, &x) < 0) - return -1; - if (x < 0 || x > USHRT_MAX) { + "short format requires " Py_STRINGIFY(SHRT_MIN) + " <= number <= " Py_STRINGIFY(SHRT_MAX)); + return -1; + } + y = (short)x; + memcpy(p, (char *)&y, sizeof y); + return 0; +} + +static int +np_ushort(char *p, PyObject *v, const formatdef *f) +{ + long x; + unsigned short y; + if (get_long(v, &x) < 0) + return -1; + if (x < 0 || x > USHRT_MAX) { + PyErr_SetString(_structmodulestate_global->StructError, + "ushort format requires 0 <= number <= " + Py_STRINGIFY(USHRT_MAX)); + return -1; + } + y = (unsigned short)x; + memcpy(p, (char *)&y, sizeof y); + return 0; +} + +static int +np_int(char *p, PyObject *v, const formatdef *f) +{ + long x; + int y; + if (get_long(v, &x) < 0) + return -1; +#if (SIZEOF_LONG > SIZEOF_INT) + if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX))) + RANGE_ERROR(x, f, 0, -1); +#endif + y = (int)x; + memcpy(p, (char *)&y, sizeof y); + return 0; +} + +static int +np_uint(char *p, PyObject *v, const formatdef *f) +{ + unsigned long x; + unsigned int y; + if (get_ulong(v, &x) < 0) + return -1; + y = (unsigned int)x; +#if (SIZEOF_LONG > SIZEOF_INT) + if (x > ((unsigned long)UINT_MAX)) + RANGE_ERROR(y, f, 1, -1); +#endif + memcpy(p, (char *)&y, sizeof y); + return 0; +} + +static int +np_long(char *p, PyObject *v, const formatdef *f) +{ + long x; + if (get_long(v, &x) < 0) + return -1; + memcpy(p, (char *)&x, sizeof x); + return 0; +} + +static int +np_ulong(char *p, PyObject *v, const formatdef *f) +{ + unsigned long x; + if (get_ulong(v, &x) < 0) + return -1; + memcpy(p, (char *)&x, sizeof x); + return 0; +} + +static int +np_ssize_t(char *p, PyObject *v, const formatdef *f) +{ + Py_ssize_t x; + if (get_ssize_t(v, &x) < 0) + return -1; + memcpy(p, (char *)&x, sizeof x); + return 0; +} + +static int +np_size_t(char *p, PyObject *v, const formatdef *f) +{ + size_t x; + if (get_size_t(v, &x) < 0) + return -1; + memcpy(p, (char *)&x, sizeof x); + return 0; +} + +static int +np_longlong(char *p, PyObject *v, const formatdef *f) +{ + long long x; + if (get_longlong(v, &x) < 0) + return -1; + memcpy(p, (char *)&x, sizeof x); + return 0; +} + +static int +np_ulonglong(char *p, PyObject *v, const formatdef *f) +{ + unsigned long long x; + if (get_ulonglong(v, &x) < 0) + return -1; + memcpy(p, (char *)&x, sizeof x); + return 0; +} + + +static int +np_bool(char *p, PyObject *v, const formatdef *f) +{ + int y; + _Bool x; + y = PyObject_IsTrue(v); + if (y < 0) + return -1; + x = y; + memcpy(p, (char *)&x, sizeof x); + return 0; +} + +static int +np_halffloat(char *p, PyObject *v, const formatdef *f) +{ +#if PY_LITTLE_ENDIAN + return pack_halffloat(p, v, 1); +#else + return pack_halffloat(p, v, 0); +#endif +} + +static int +np_float(char *p, PyObject *v, const formatdef *f) +{ + float x = (float)PyFloat_AsDouble(v); + if (x == -1 && PyErr_Occurred()) { + PyErr_SetString(_structmodulestate_global->StructError, + "required argument is not a float"); + return -1; + } + memcpy(p, (char *)&x, sizeof x); + return 0; +} + +static int +np_double(char *p, PyObject *v, const formatdef *f) +{ + double x = PyFloat_AsDouble(v); + if (x == -1 && PyErr_Occurred()) { + PyErr_SetString(_structmodulestate_global->StructError, + "required argument is not a float"); + return -1; + } + memcpy(p, (char *)&x, sizeof(double)); + return 0; +} + +static int +np_void_p(char *p, PyObject *v, const formatdef *f) +{ + void *x; + + v = get_pylong(v); + if (v == NULL) + return -1; + assert(PyLong_Check(v)); + x = PyLong_AsVoidPtr(v); + Py_DECREF(v); + if (x == NULL && PyErr_Occurred()) + return -1; + memcpy(p, (char *)&x, sizeof x); + return 0; +} + +static const formatdef native_table[] = { + {'x', sizeof(char), 0, NULL}, + {'b', sizeof(char), 0, nu_byte, np_byte}, + {'B', sizeof(char), 0, nu_ubyte, np_ubyte}, + {'c', sizeof(char), 0, nu_char, np_char}, + {'s', sizeof(char), 0, NULL}, + {'p', sizeof(char), 0, NULL}, + {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short}, + {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort}, + {'i', sizeof(int), INT_ALIGN, nu_int, np_int}, + {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint}, + {'l', sizeof(long), LONG_ALIGN, nu_long, np_long}, + {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong}, + {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t}, + {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t}, + {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong}, + {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, + {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool}, + {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat}, + {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float}, + {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double}, + {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p}, + {0} +}; + +/* Big-endian routines. *****************************************************/ + +static PyObject * +bu_int(const char *p, const formatdef *f) +{ + long x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | *bytes++; + } while (--i > 0); + /* Extend the sign bit. */ + if (SIZEOF_LONG > f->size) + x |= -(x & (1L << ((8 * f->size) - 1))); + return PyLong_FromLong(x); +} + +static PyObject * +bu_uint(const char *p, const formatdef *f) +{ + unsigned long x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | *bytes++; + } while (--i > 0); + return PyLong_FromUnsignedLong(x); +} + +static PyObject * +bu_longlong(const char *p, const formatdef *f) +{ + long long x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | *bytes++; + } while (--i > 0); + /* Extend the sign bit. */ + if (SIZEOF_LONG_LONG > f->size) + x |= -(x & ((long long)1 << ((8 * f->size) - 1))); + return PyLong_FromLongLong(x); +} + +static PyObject * +bu_ulonglong(const char *p, const formatdef *f) +{ + unsigned long long x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | *bytes++; + } while (--i > 0); + return PyLong_FromUnsignedLongLong(x); +} + +static PyObject * +bu_halffloat(const char *p, const formatdef *f) +{ + return unpack_halffloat(p, 0); +} + +static PyObject * +bu_float(const char *p, const formatdef *f) +{ + return unpack_float(p, 0); +} + +static PyObject * +bu_double(const char *p, const formatdef *f) +{ + return unpack_double(p, 0); +} + +static PyObject * +bu_bool(const char *p, const formatdef *f) +{ + return PyBool_FromLong(*p != 0); +} + +static int +bp_int(char *p, PyObject *v, const formatdef *f) +{ + long x; + Py_ssize_t i; + unsigned char *q = (unsigned char *)p; + if (get_long(v, &x) < 0) + return -1; + i = f->size; + if (i != SIZEOF_LONG) { + if ((i == 2) && (x < -32768 || x > 32767)) + RANGE_ERROR(x, f, 0, 0xffffL); +#if (SIZEOF_LONG != 4) + else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) + RANGE_ERROR(x, f, 0, 0xffffffffL); +#endif + } + do { + q[--i] = (unsigned char)(x & 0xffL); + x >>= 8; + } while (i > 0); + return 0; +} + +static int +bp_uint(char *p, PyObject *v, const formatdef *f) +{ + unsigned long x; + Py_ssize_t i; + unsigned char *q = (unsigned char *)p; + if (get_ulong(v, &x) < 0) + return -1; + i = f->size; + if (i != SIZEOF_LONG) { + unsigned long maxint = 1; + maxint <<= (unsigned long)(i * 8); + if (x >= maxint) + RANGE_ERROR(x, f, 1, maxint - 1); + } + do { + q[--i] = (unsigned char)(x & 0xffUL); + x >>= 8; + } while (i > 0); + return 0; +} + +static int +bp_longlong(char *p, PyObject *v, const formatdef *f) +{ + int res; + v = get_pylong(v); + if (v == NULL) + return -1; + res = _PyLong_AsByteArray((PyLongObject *)v, + (unsigned char *)p, + 8, + 0, /* little_endian */ + 1 /* signed */); + Py_DECREF(v); + return res; +} + +static int +bp_ulonglong(char *p, PyObject *v, const formatdef *f) +{ + int res; + v = get_pylong(v); + if (v == NULL) + return -1; + res = _PyLong_AsByteArray((PyLongObject *)v, + (unsigned char *)p, + 8, + 0, /* little_endian */ + 0 /* signed */); + Py_DECREF(v); + return res; +} + +static int +bp_halffloat(char *p, PyObject *v, const formatdef *f) +{ + return pack_halffloat(p, v, 0); +} + +static int +bp_float(char *p, PyObject *v, const formatdef *f) +{ + double x = PyFloat_AsDouble(v); + if (x == -1 && PyErr_Occurred()) { PyErr_SetString(_structmodulestate_global->StructError, - "ushort format requires 0 <= number <= " - Py_STRINGIFY(USHRT_MAX)); + "required argument is not a float"); + return -1; + } + return _PyFloat_Pack4(x, (unsigned char *)p, 0); +} + +static int +bp_double(char *p, PyObject *v, const formatdef *f) +{ + double x = PyFloat_AsDouble(v); + if (x == -1 && PyErr_Occurred()) { + PyErr_SetString(_structmodulestate_global->StructError, + "required argument is not a float"); + return -1; + } + return _PyFloat_Pack8(x, (unsigned char *)p, 0); +} + +static int +bp_bool(char *p, PyObject *v, const formatdef *f) +{ + int y; + y = PyObject_IsTrue(v); + if (y < 0) + return -1; + *p = (char)y; + return 0; +} + +static formatdef bigendian_table[] = { + {'x', 1, 0, NULL}, + {'b', 1, 0, nu_byte, np_byte}, + {'B', 1, 0, nu_ubyte, np_ubyte}, + {'c', 1, 0, nu_char, np_char}, + {'s', 1, 0, NULL}, + {'p', 1, 0, NULL}, + {'h', 2, 0, bu_int, bp_int}, + {'H', 2, 0, bu_uint, bp_uint}, + {'i', 4, 0, bu_int, bp_int}, + {'I', 4, 0, bu_uint, bp_uint}, + {'l', 4, 0, bu_int, bp_int}, + {'L', 4, 0, bu_uint, bp_uint}, + {'q', 8, 0, bu_longlong, bp_longlong}, + {'Q', 8, 0, bu_ulonglong, bp_ulonglong}, + {'?', 1, 0, bu_bool, bp_bool}, + {'e', 2, 0, bu_halffloat, bp_halffloat}, + {'f', 4, 0, bu_float, bp_float}, + {'d', 8, 0, bu_double, bp_double}, + {0} +}; + +/* Little-endian routines. *****************************************************/ + +static PyObject * +lu_int(const char *p, const formatdef *f) +{ + long x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | bytes[--i]; + } while (i > 0); + /* Extend the sign bit. */ + if (SIZEOF_LONG > f->size) + x |= -(x & (1L << ((8 * f->size) - 1))); + return PyLong_FromLong(x); +} + +static PyObject * +lu_uint(const char *p, const formatdef *f) +{ + unsigned long x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | bytes[--i]; + } while (i > 0); + return PyLong_FromUnsignedLong(x); +} + +static PyObject * +lu_longlong(const char *p, const formatdef *f) +{ + long long x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | bytes[--i]; + } while (i > 0); + /* Extend the sign bit. */ + if (SIZEOF_LONG_LONG > f->size) + x |= -(x & ((long long)1 << ((8 * f->size) - 1))); + return PyLong_FromLongLong(x); +} + +static PyObject * +lu_ulonglong(const char *p, const formatdef *f) +{ + unsigned long long x = 0; + Py_ssize_t i = f->size; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | bytes[--i]; + } while (i > 0); + return PyLong_FromUnsignedLongLong(x); +} + +static PyObject * +lu_halffloat(const char *p, const formatdef *f) +{ + return unpack_halffloat(p, 1); +} + +static PyObject * +lu_float(const char *p, const formatdef *f) +{ + return unpack_float(p, 1); +} + +static PyObject * +lu_double(const char *p, const formatdef *f) +{ + return unpack_double(p, 1); +} + +static int +lp_int(char *p, PyObject *v, const formatdef *f) +{ + long x; + Py_ssize_t i; + unsigned char *q = (unsigned char *)p; + if (get_long(v, &x) < 0) + return -1; + i = f->size; + if (i != SIZEOF_LONG) { + if ((i == 2) && (x < -32768 || x > 32767)) + RANGE_ERROR(x, f, 0, 0xffffL); +#if (SIZEOF_LONG != 4) + else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) + RANGE_ERROR(x, f, 0, 0xffffffffL); +#endif + } + do { + *q++ = (unsigned char)(x & 0xffL); + x >>= 8; + } while (--i > 0); + return 0; +} + +static int +lp_uint(char *p, PyObject *v, const formatdef *f) +{ + unsigned long x; + Py_ssize_t i; + unsigned char *q = (unsigned char *)p; + if (get_ulong(v, &x) < 0) + return -1; + i = f->size; + if (i != SIZEOF_LONG) { + unsigned long maxint = 1; + maxint <<= (unsigned long)(i * 8); + if (x >= maxint) + RANGE_ERROR(x, f, 1, maxint - 1); + } + do { + *q++ = (unsigned char)(x & 0xffUL); + x >>= 8; + } while (--i > 0); + return 0; +} + +static int +lp_longlong(char *p, PyObject *v, const formatdef *f) +{ + int res; + v = get_pylong(v); + if (v == NULL) + return -1; + res = _PyLong_AsByteArray((PyLongObject*)v, + (unsigned char *)p, + 8, + 1, /* little_endian */ + 1 /* signed */); + Py_DECREF(v); + return res; +} + +static int +lp_ulonglong(char *p, PyObject *v, const formatdef *f) +{ + int res; + v = get_pylong(v); + if (v == NULL) + return -1; + res = _PyLong_AsByteArray((PyLongObject*)v, + (unsigned char *)p, + 8, + 1, /* little_endian */ + 0 /* signed */); + Py_DECREF(v); + return res; +} + +static int +lp_halffloat(char *p, PyObject *v, const formatdef *f) +{ + return pack_halffloat(p, v, 1); +} + +static int +lp_float(char *p, PyObject *v, const formatdef *f) +{ + double x = PyFloat_AsDouble(v); + if (x == -1 && PyErr_Occurred()) { + PyErr_SetString(_structmodulestate_global->StructError, + "required argument is not a float"); + return -1; + } + return _PyFloat_Pack4(x, (unsigned char *)p, 1); +} + +static int +lp_double(char *p, PyObject *v, const formatdef *f) +{ + double x = PyFloat_AsDouble(v); + if (x == -1 && PyErr_Occurred()) { + PyErr_SetString(_structmodulestate_global->StructError, + "required argument is not a float"); + return -1; + } + return _PyFloat_Pack8(x, (unsigned char *)p, 1); +} + +static formatdef lilendian_table[] = { + {'x', 1, 0, NULL}, + {'b', 1, 0, nu_byte, np_byte}, + {'B', 1, 0, nu_ubyte, np_ubyte}, + {'c', 1, 0, nu_char, np_char}, + {'s', 1, 0, NULL}, + {'p', 1, 0, NULL}, + {'h', 2, 0, lu_int, lp_int}, + {'H', 2, 0, lu_uint, lp_uint}, + {'i', 4, 0, lu_int, lp_int}, + {'I', 4, 0, lu_uint, lp_uint}, + {'l', 4, 0, lu_int, lp_int}, + {'L', 4, 0, lu_uint, lp_uint}, + {'q', 8, 0, lu_longlong, lp_longlong}, + {'Q', 8, 0, lu_ulonglong, lp_ulonglong}, + {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep, + but potentially different from native rep -- reuse bx_bool funcs. */ + {'e', 2, 0, lu_halffloat, lp_halffloat}, + {'f', 4, 0, lu_float, lp_float}, + {'d', 8, 0, lu_double, lp_double}, + {0} +}; + + +static const formatdef * +whichtable(const char **pfmt) +{ + const char *fmt = (*pfmt)++; /* May be backed out of later */ + switch (*fmt) { + case '<': + return lilendian_table; + case '>': + case '!': /* Network byte order is big-endian */ + return bigendian_table; + case '=': { /* Host byte order -- different from native in alignment! */ +#if PY_LITTLE_ENDIAN + return lilendian_table; +#else + return bigendian_table; +#endif + } + default: + --*pfmt; /* Back out of pointer increment */ + /* Fall through */ + case '@': + return native_table; + } +} + + +/* Get the table entry for a format code */ + +static const formatdef * +getentry(int c, const formatdef *f) +{ + for (; f->format != '\0'; f++) { + if (f->format == c) { + return f; + } + } + PyErr_SetString(_structmodulestate_global->StructError, "bad char in struct format"); + return NULL; +} + + +/* Align a size according to a format code. Return -1 on overflow. */ + +static Py_ssize_t +align(Py_ssize_t size, char c, const formatdef *e) +{ + Py_ssize_t extra; + + if (e->format == c) { + if (e->alignment && size > 0) { + extra = (e->alignment - 1) - (size - 1) % (e->alignment); + if (extra > PY_SSIZE_T_MAX - size) + return -1; + size += extra; + } + } + return size; +} + +/* + * Struct object implementation. + */ + +/* calculate the size of a format string */ + +static int +prepare_s(PyStructObject *self) +{ + const formatdef *f; + const formatdef *e; + formatcode *codes; + + const char *s; + const char *fmt; + char c; + Py_ssize_t size, len, num, itemsize; + size_t ncodes; + + fmt = PyBytes_AS_STRING(self->s_format); + if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) { + PyErr_SetString(_structmodulestate_global->StructError, + "embedded null character"); return -1; } - y = (unsigned short)x; - memcpy(p, (char *)&y, sizeof y); - return 0; -} - -static int -np_int(char *p, PyObject *v, const formatdef *f) -{ - long x; - int y; - if (get_long(v, &x) < 0) - return -1; -#if (SIZEOF_LONG > SIZEOF_INT) - if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX))) - RANGE_ERROR(x, f, 0, -1); -#endif - y = (int)x; - memcpy(p, (char *)&y, sizeof y); - return 0; -} - -static int -np_uint(char *p, PyObject *v, const formatdef *f) -{ - unsigned long x; - unsigned int y; - if (get_ulong(v, &x) < 0) - return -1; - y = (unsigned int)x; -#if (SIZEOF_LONG > SIZEOF_INT) - if (x > ((unsigned long)UINT_MAX)) - RANGE_ERROR(y, f, 1, -1); -#endif - memcpy(p, (char *)&y, sizeof y); - return 0; -} - -static int -np_long(char *p, PyObject *v, const formatdef *f) -{ - long x; - if (get_long(v, &x) < 0) - return -1; - memcpy(p, (char *)&x, sizeof x); - return 0; -} - -static int -np_ulong(char *p, PyObject *v, const formatdef *f) -{ - unsigned long x; - if (get_ulong(v, &x) < 0) - return -1; - memcpy(p, (char *)&x, sizeof x); - return 0; -} - -static int -np_ssize_t(char *p, PyObject *v, const formatdef *f) -{ - Py_ssize_t x; - if (get_ssize_t(v, &x) < 0) - return -1; - memcpy(p, (char *)&x, sizeof x); - return 0; -} - -static int -np_size_t(char *p, PyObject *v, const formatdef *f) -{ - size_t x; - if (get_size_t(v, &x) < 0) - return -1; - memcpy(p, (char *)&x, sizeof x); - return 0; -} - -static int -np_longlong(char *p, PyObject *v, const formatdef *f) -{ - long long x; - if (get_longlong(v, &x) < 0) - return -1; - memcpy(p, (char *)&x, sizeof x); - return 0; -} - -static int -np_ulonglong(char *p, PyObject *v, const formatdef *f) -{ - unsigned long long x; - if (get_ulonglong(v, &x) < 0) - return -1; - memcpy(p, (char *)&x, sizeof x); - return 0; -} - - -static int -np_bool(char *p, PyObject *v, const formatdef *f) -{ - int y; - _Bool x; - y = PyObject_IsTrue(v); - if (y < 0) - return -1; - x = y; - memcpy(p, (char *)&x, sizeof x); - return 0; -} - -static int -np_halffloat(char *p, PyObject *v, const formatdef *f) -{ -#if PY_LITTLE_ENDIAN - return pack_halffloat(p, v, 1); -#else - return pack_halffloat(p, v, 0); -#endif -} - -static int -np_float(char *p, PyObject *v, const formatdef *f) -{ - float x = (float)PyFloat_AsDouble(v); - if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, - "required argument is not a float"); - return -1; - } - memcpy(p, (char *)&x, sizeof x); - return 0; -} - -static int -np_double(char *p, PyObject *v, const formatdef *f) -{ - double x = PyFloat_AsDouble(v); - if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, - "required argument is not a float"); - return -1; - } - memcpy(p, (char *)&x, sizeof(double)); - return 0; -} - -static int -np_void_p(char *p, PyObject *v, const formatdef *f) -{ - void *x; - - v = get_pylong(v); - if (v == NULL) - return -1; - assert(PyLong_Check(v)); - x = PyLong_AsVoidPtr(v); - Py_DECREF(v); - if (x == NULL && PyErr_Occurred()) - return -1; - memcpy(p, (char *)&x, sizeof x); - return 0; -} - -static const formatdef native_table[] = { - {'x', sizeof(char), 0, NULL}, - {'b', sizeof(char), 0, nu_byte, np_byte}, - {'B', sizeof(char), 0, nu_ubyte, np_ubyte}, - {'c', sizeof(char), 0, nu_char, np_char}, - {'s', sizeof(char), 0, NULL}, - {'p', sizeof(char), 0, NULL}, - {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short}, - {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort}, - {'i', sizeof(int), INT_ALIGN, nu_int, np_int}, - {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint}, - {'l', sizeof(long), LONG_ALIGN, nu_long, np_long}, - {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong}, - {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t}, - {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t}, - {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong}, - {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, - {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool}, - {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat}, - {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float}, - {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double}, - {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p}, - {0} -}; - -/* Big-endian routines. *****************************************************/ - -static PyObject * -bu_int(const char *p, const formatdef *f) -{ - long x = 0; - Py_ssize_t i = f->size; - const unsigned char *bytes = (const unsigned char *)p; - do { - x = (x<<8) | *bytes++; - } while (--i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG > f->size) - x |= -(x & (1L << ((8 * f->size) - 1))); - return PyLong_FromLong(x); -} - -static PyObject * -bu_uint(const char *p, const formatdef *f) -{ - unsigned long x = 0; - Py_ssize_t i = f->size; - const unsigned char *bytes = (const unsigned char *)p; - do { - x = (x<<8) | *bytes++; - } while (--i > 0); - return PyLong_FromUnsignedLong(x); -} - -static PyObject * -bu_longlong(const char *p, const formatdef *f) -{ - long long x = 0; - Py_ssize_t i = f->size; - const unsigned char *bytes = (const unsigned char *)p; - do { - x = (x<<8) | *bytes++; - } while (--i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG_LONG > f->size) - x |= -(x & ((long long)1 << ((8 * f->size) - 1))); - return PyLong_FromLongLong(x); -} - -static PyObject * -bu_ulonglong(const char *p, const formatdef *f) -{ - unsigned long long x = 0; - Py_ssize_t i = f->size; - const unsigned char *bytes = (const unsigned char *)p; - do { - x = (x<<8) | *bytes++; - } while (--i > 0); - return PyLong_FromUnsignedLongLong(x); -} - -static PyObject * -bu_halffloat(const char *p, const formatdef *f) -{ - return unpack_halffloat(p, 0); -} - -static PyObject * -bu_float(const char *p, const formatdef *f) -{ - return unpack_float(p, 0); -} - -static PyObject * -bu_double(const char *p, const formatdef *f) -{ - return unpack_double(p, 0); -} - -static PyObject * -bu_bool(const char *p, const formatdef *f) -{ - return PyBool_FromLong(*p != 0); -} - -static int -bp_int(char *p, PyObject *v, const formatdef *f) -{ - long x; - Py_ssize_t i; - unsigned char *q = (unsigned char *)p; - if (get_long(v, &x) < 0) - return -1; - i = f->size; - if (i != SIZEOF_LONG) { - if ((i == 2) && (x < -32768 || x > 32767)) - RANGE_ERROR(x, f, 0, 0xffffL); -#if (SIZEOF_LONG != 4) - else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) - RANGE_ERROR(x, f, 0, 0xffffffffL); -#endif - } - do { - q[--i] = (unsigned char)(x & 0xffL); - x >>= 8; - } while (i > 0); - return 0; -} - -static int -bp_uint(char *p, PyObject *v, const formatdef *f) -{ - unsigned long x; - Py_ssize_t i; - unsigned char *q = (unsigned char *)p; - if (get_ulong(v, &x) < 0) - return -1; - i = f->size; - if (i != SIZEOF_LONG) { - unsigned long maxint = 1; - maxint <<= (unsigned long)(i * 8); - if (x >= maxint) - RANGE_ERROR(x, f, 1, maxint - 1); - } - do { - q[--i] = (unsigned char)(x & 0xffUL); - x >>= 8; - } while (i > 0); - return 0; -} - -static int -bp_longlong(char *p, PyObject *v, const formatdef *f) -{ - int res; - v = get_pylong(v); - if (v == NULL) - return -1; - res = _PyLong_AsByteArray((PyLongObject *)v, - (unsigned char *)p, - 8, - 0, /* little_endian */ - 1 /* signed */); - Py_DECREF(v); - return res; -} - -static int -bp_ulonglong(char *p, PyObject *v, const formatdef *f) -{ - int res; - v = get_pylong(v); - if (v == NULL) - return -1; - res = _PyLong_AsByteArray((PyLongObject *)v, - (unsigned char *)p, - 8, - 0, /* little_endian */ - 0 /* signed */); - Py_DECREF(v); - return res; -} - -static int -bp_halffloat(char *p, PyObject *v, const formatdef *f) -{ - return pack_halffloat(p, v, 0); -} - -static int -bp_float(char *p, PyObject *v, const formatdef *f) -{ - double x = PyFloat_AsDouble(v); - if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, - "required argument is not a float"); - return -1; - } - return _PyFloat_Pack4(x, (unsigned char *)p, 0); -} - -static int -bp_double(char *p, PyObject *v, const formatdef *f) -{ - double x = PyFloat_AsDouble(v); - if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, - "required argument is not a float"); - return -1; - } - return _PyFloat_Pack8(x, (unsigned char *)p, 0); -} - -static int -bp_bool(char *p, PyObject *v, const formatdef *f) -{ - int y; - y = PyObject_IsTrue(v); - if (y < 0) - return -1; - *p = (char)y; - return 0; -} - -static formatdef bigendian_table[] = { - {'x', 1, 0, NULL}, - {'b', 1, 0, nu_byte, np_byte}, - {'B', 1, 0, nu_ubyte, np_ubyte}, - {'c', 1, 0, nu_char, np_char}, - {'s', 1, 0, NULL}, - {'p', 1, 0, NULL}, - {'h', 2, 0, bu_int, bp_int}, - {'H', 2, 0, bu_uint, bp_uint}, - {'i', 4, 0, bu_int, bp_int}, - {'I', 4, 0, bu_uint, bp_uint}, - {'l', 4, 0, bu_int, bp_int}, - {'L', 4, 0, bu_uint, bp_uint}, - {'q', 8, 0, bu_longlong, bp_longlong}, - {'Q', 8, 0, bu_ulonglong, bp_ulonglong}, - {'?', 1, 0, bu_bool, bp_bool}, - {'e', 2, 0, bu_halffloat, bp_halffloat}, - {'f', 4, 0, bu_float, bp_float}, - {'d', 8, 0, bu_double, bp_double}, - {0} -}; - -/* Little-endian routines. *****************************************************/ - -static PyObject * -lu_int(const char *p, const formatdef *f) -{ - long x = 0; - Py_ssize_t i = f->size; - const unsigned char *bytes = (const unsigned char *)p; - do { - x = (x<<8) | bytes[--i]; - } while (i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG > f->size) - x |= -(x & (1L << ((8 * f->size) - 1))); - return PyLong_FromLong(x); -} - -static PyObject * -lu_uint(const char *p, const formatdef *f) -{ - unsigned long x = 0; - Py_ssize_t i = f->size; - const unsigned char *bytes = (const unsigned char *)p; - do { - x = (x<<8) | bytes[--i]; - } while (i > 0); - return PyLong_FromUnsignedLong(x); -} - -static PyObject * -lu_longlong(const char *p, const formatdef *f) -{ - long long x = 0; - Py_ssize_t i = f->size; - const unsigned char *bytes = (const unsigned char *)p; - do { - x = (x<<8) | bytes[--i]; - } while (i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG_LONG > f->size) - x |= -(x & ((long long)1 << ((8 * f->size) - 1))); - return PyLong_FromLongLong(x); -} - -static PyObject * -lu_ulonglong(const char *p, const formatdef *f) -{ - unsigned long long x = 0; - Py_ssize_t i = f->size; - const unsigned char *bytes = (const unsigned char *)p; - do { - x = (x<<8) | bytes[--i]; - } while (i > 0); - return PyLong_FromUnsignedLongLong(x); -} - -static PyObject * -lu_halffloat(const char *p, const formatdef *f) -{ - return unpack_halffloat(p, 1); -} - -static PyObject * -lu_float(const char *p, const formatdef *f) -{ - return unpack_float(p, 1); -} - -static PyObject * -lu_double(const char *p, const formatdef *f) -{ - return unpack_double(p, 1); -} - -static int -lp_int(char *p, PyObject *v, const formatdef *f) -{ - long x; - Py_ssize_t i; - unsigned char *q = (unsigned char *)p; - if (get_long(v, &x) < 0) - return -1; - i = f->size; - if (i != SIZEOF_LONG) { - if ((i == 2) && (x < -32768 || x > 32767)) - RANGE_ERROR(x, f, 0, 0xffffL); -#if (SIZEOF_LONG != 4) - else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) - RANGE_ERROR(x, f, 0, 0xffffffffL); -#endif - } - do { - *q++ = (unsigned char)(x & 0xffL); - x >>= 8; - } while (--i > 0); - return 0; -} - -static int -lp_uint(char *p, PyObject *v, const formatdef *f) -{ - unsigned long x; - Py_ssize_t i; - unsigned char *q = (unsigned char *)p; - if (get_ulong(v, &x) < 0) - return -1; - i = f->size; - if (i != SIZEOF_LONG) { - unsigned long maxint = 1; - maxint <<= (unsigned long)(i * 8); - if (x >= maxint) - RANGE_ERROR(x, f, 1, maxint - 1); - } - do { - *q++ = (unsigned char)(x & 0xffUL); - x >>= 8; - } while (--i > 0); - return 0; -} - -static int -lp_longlong(char *p, PyObject *v, const formatdef *f) -{ - int res; - v = get_pylong(v); - if (v == NULL) - return -1; - res = _PyLong_AsByteArray((PyLongObject*)v, - (unsigned char *)p, - 8, - 1, /* little_endian */ - 1 /* signed */); - Py_DECREF(v); - return res; -} - -static int -lp_ulonglong(char *p, PyObject *v, const formatdef *f) -{ - int res; - v = get_pylong(v); - if (v == NULL) - return -1; - res = _PyLong_AsByteArray((PyLongObject*)v, - (unsigned char *)p, - 8, - 1, /* little_endian */ - 0 /* signed */); - Py_DECREF(v); - return res; -} - -static int -lp_halffloat(char *p, PyObject *v, const formatdef *f) -{ - return pack_halffloat(p, v, 1); -} - -static int -lp_float(char *p, PyObject *v, const formatdef *f) -{ - double x = PyFloat_AsDouble(v); - if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, - "required argument is not a float"); - return -1; - } - return _PyFloat_Pack4(x, (unsigned char *)p, 1); -} - -static int -lp_double(char *p, PyObject *v, const formatdef *f) -{ - double x = PyFloat_AsDouble(v); - if (x == -1 && PyErr_Occurred()) { - PyErr_SetString(_structmodulestate_global->StructError, - "required argument is not a float"); - return -1; - } - return _PyFloat_Pack8(x, (unsigned char *)p, 1); -} - -static formatdef lilendian_table[] = { - {'x', 1, 0, NULL}, - {'b', 1, 0, nu_byte, np_byte}, - {'B', 1, 0, nu_ubyte, np_ubyte}, - {'c', 1, 0, nu_char, np_char}, - {'s', 1, 0, NULL}, - {'p', 1, 0, NULL}, - {'h', 2, 0, lu_int, lp_int}, - {'H', 2, 0, lu_uint, lp_uint}, - {'i', 4, 0, lu_int, lp_int}, - {'I', 4, 0, lu_uint, lp_uint}, - {'l', 4, 0, lu_int, lp_int}, - {'L', 4, 0, lu_uint, lp_uint}, - {'q', 8, 0, lu_longlong, lp_longlong}, - {'Q', 8, 0, lu_ulonglong, lp_ulonglong}, - {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep, - but potentially different from native rep -- reuse bx_bool funcs. */ - {'e', 2, 0, lu_halffloat, lp_halffloat}, - {'f', 4, 0, lu_float, lp_float}, - {'d', 8, 0, lu_double, lp_double}, - {0} -}; - - -static const formatdef * -whichtable(const char **pfmt) -{ - const char *fmt = (*pfmt)++; /* May be backed out of later */ - switch (*fmt) { - case '<': - return lilendian_table; - case '>': - case '!': /* Network byte order is big-endian */ - return bigendian_table; - case '=': { /* Host byte order -- different from native in alignment! */ -#if PY_LITTLE_ENDIAN - return lilendian_table; -#else - return bigendian_table; -#endif - } - default: - --*pfmt; /* Back out of pointer increment */ - /* Fall through */ - case '@': - return native_table; - } -} - - -/* Get the table entry for a format code */ - -static const formatdef * -getentry(int c, const formatdef *f) -{ - for (; f->format != '\0'; f++) { - if (f->format == c) { - return f; - } - } - PyErr_SetString(_structmodulestate_global->StructError, "bad char in struct format"); - return NULL; -} - - -/* Align a size according to a format code. Return -1 on overflow. */ - -static Py_ssize_t -align(Py_ssize_t size, char c, const formatdef *e) -{ - Py_ssize_t extra; - - if (e->format == c) { - if (e->alignment && size > 0) { - extra = (e->alignment - 1) - (size - 1) % (e->alignment); - if (extra > PY_SSIZE_T_MAX - size) - return -1; - size += extra; - } - } - return size; -} - -/* - * Struct object implementation. - */ - -/* calculate the size of a format string */ - -static int -prepare_s(PyStructObject *self) -{ - const formatdef *f; - const formatdef *e; - formatcode *codes; - - const char *s; - const char *fmt; - char c; - Py_ssize_t size, len, num, itemsize; - size_t ncodes; - - fmt = PyBytes_AS_STRING(self->s_format); - if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) { - PyErr_SetString(_structmodulestate_global->StructError, - "embedded null character"); - return -1; - } - - f = whichtable(&fmt); - - s = fmt; - size = 0; - len = 0; - ncodes = 0; - while ((c = *s++) != '\0') { + + f = whichtable(&fmt); + + s = fmt; + size = 0; + len = 0; + ncodes = 0; + while ((c = *s++) != '\0') { if (Py_ISSPACE(c)) - continue; - if ('0' <= c && c <= '9') { - num = c - '0'; - while ('0' <= (c = *s++) && c <= '9') { - /* overflow-safe version of - if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ - if (num >= PY_SSIZE_T_MAX / 10 && ( - num > PY_SSIZE_T_MAX / 10 || - (c - '0') > PY_SSIZE_T_MAX % 10)) - goto overflow; - num = num*10 + (c - '0'); - } - if (c == '\0') { + continue; + if ('0' <= c && c <= '9') { + num = c - '0'; + while ('0' <= (c = *s++) && c <= '9') { + /* overflow-safe version of + if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ + if (num >= PY_SSIZE_T_MAX / 10 && ( + num > PY_SSIZE_T_MAX / 10 || + (c - '0') > PY_SSIZE_T_MAX % 10)) + goto overflow; + num = num*10 + (c - '0'); + } + if (c == '\0') { PyErr_SetString(_structmodulestate_global->StructError, - "repeat count given without format specifier"); - return -1; - } - } - else - num = 1; - - e = getentry(c, f); - if (e == NULL) - return -1; - - switch (c) { - case 's': /* fall through */ - case 'p': len++; ncodes++; break; - case 'x': break; - default: len += num; if (num) ncodes++; break; - } - - itemsize = e->size; - size = align(size, c, e); - if (size == -1) - goto overflow; - - /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ - if (num > (PY_SSIZE_T_MAX - size) / itemsize) - goto overflow; - size += num * itemsize; - } - - /* check for overflow */ - if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) { - PyErr_NoMemory(); - return -1; - } - - self->s_size = size; - self->s_len = len; - codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode)); - if (codes == NULL) { - PyErr_NoMemory(); - return -1; - } - /* Free any s_codes value left over from a previous initialization. */ - if (self->s_codes != NULL) - PyMem_FREE(self->s_codes); - self->s_codes = codes; - - s = fmt; - size = 0; - while ((c = *s++) != '\0') { + "repeat count given without format specifier"); + return -1; + } + } + else + num = 1; + + e = getentry(c, f); + if (e == NULL) + return -1; + + switch (c) { + case 's': /* fall through */ + case 'p': len++; ncodes++; break; + case 'x': break; + default: len += num; if (num) ncodes++; break; + } + + itemsize = e->size; + size = align(size, c, e); + if (size == -1) + goto overflow; + + /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ + if (num > (PY_SSIZE_T_MAX - size) / itemsize) + goto overflow; + size += num * itemsize; + } + + /* check for overflow */ + if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) { + PyErr_NoMemory(); + return -1; + } + + self->s_size = size; + self->s_len = len; + codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode)); + if (codes == NULL) { + PyErr_NoMemory(); + return -1; + } + /* Free any s_codes value left over from a previous initialization. */ + if (self->s_codes != NULL) + PyMem_FREE(self->s_codes); + self->s_codes = codes; + + s = fmt; + size = 0; + while ((c = *s++) != '\0') { if (Py_ISSPACE(c)) - continue; - if ('0' <= c && c <= '9') { - num = c - '0'; - while ('0' <= (c = *s++) && c <= '9') - num = num*10 + (c - '0'); - } - else - num = 1; - - e = getentry(c, f); - - size = align(size, c, e); - if (c == 's' || c == 'p') { - codes->offset = size; - codes->size = num; - codes->fmtdef = e; - codes->repeat = 1; - codes++; - size += num; - } else if (c == 'x') { - size += num; - } else if (num) { - codes->offset = size; - codes->size = e->size; - codes->fmtdef = e; - codes->repeat = num; - codes++; - size += e->size * num; - } - } - codes->fmtdef = NULL; - codes->offset = size; - codes->size = 0; - codes->repeat = 0; - - return 0; - - overflow: + continue; + if ('0' <= c && c <= '9') { + num = c - '0'; + while ('0' <= (c = *s++) && c <= '9') + num = num*10 + (c - '0'); + } + else + num = 1; + + e = getentry(c, f); + + size = align(size, c, e); + if (c == 's' || c == 'p') { + codes->offset = size; + codes->size = num; + codes->fmtdef = e; + codes->repeat = 1; + codes++; + size += num; + } else if (c == 'x') { + size += num; + } else if (num) { + codes->offset = size; + codes->size = e->size; + codes->fmtdef = e; + codes->repeat = num; + codes++; + size += e->size * num; + } + } + codes->fmtdef = NULL; + codes->offset = size; + codes->size = 0; + codes->repeat = 0; + + return 0; + + overflow: PyErr_SetString(_structmodulestate_global->StructError, - "total struct size too long"); - return -1; -} - -static PyObject * -s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *self; - + "total struct size too long"); + return -1; +} + +static PyObject * +s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *self; + assert(type != NULL); allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); assert(alloc_func != NULL); - + self = alloc_func(type, 0); - if (self != NULL) { - PyStructObject *s = (PyStructObject*)self; - Py_INCREF(Py_None); - s->s_format = Py_None; - s->s_codes = NULL; - s->s_size = -1; - s->s_len = -1; - } - return self; -} - -/*[clinic input] -Struct.__init__ - - format: object - -Create a compiled struct object. - -Return a new Struct object which writes and reads binary data according to -the format string. - -See help(struct) for more on format strings. -[clinic start generated code]*/ - -static int -Struct___init___impl(PyStructObject *self, PyObject *format) -/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/ -{ - int ret = 0; - - if (PyUnicode_Check(format)) { - format = PyUnicode_AsASCIIString(format); - if (format == NULL) - return -1; - } - /* XXX support buffer interface, too */ - else { - Py_INCREF(format); - } - - if (!PyBytes_Check(format)) { - Py_DECREF(format); - PyErr_Format(PyExc_TypeError, - "Struct() argument 1 must be a str or bytes object, " - "not %.200s", + if (self != NULL) { + PyStructObject *s = (PyStructObject*)self; + Py_INCREF(Py_None); + s->s_format = Py_None; + s->s_codes = NULL; + s->s_size = -1; + s->s_len = -1; + } + return self; +} + +/*[clinic input] +Struct.__init__ + + format: object + +Create a compiled struct object. + +Return a new Struct object which writes and reads binary data according to +the format string. + +See help(struct) for more on format strings. +[clinic start generated code]*/ + +static int +Struct___init___impl(PyStructObject *self, PyObject *format) +/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/ +{ + int ret = 0; + + if (PyUnicode_Check(format)) { + format = PyUnicode_AsASCIIString(format); + if (format == NULL) + return -1; + } + /* XXX support buffer interface, too */ + else { + Py_INCREF(format); + } + + if (!PyBytes_Check(format)) { + Py_DECREF(format); + PyErr_Format(PyExc_TypeError, + "Struct() argument 1 must be a str or bytes object, " + "not %.200s", _PyType_Name(Py_TYPE(format))); - return -1; - } - - Py_SETREF(self->s_format, format); - - ret = prepare_s(self); - return ret; -} - -static void -s_dealloc(PyStructObject *s) -{ + return -1; + } + + Py_SETREF(self->s_format, format); + + ret = prepare_s(self); + return ret; +} + +static void +s_dealloc(PyStructObject *s) +{ PyTypeObject *tp = Py_TYPE(s); - if (s->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)s); - if (s->s_codes != NULL) { - PyMem_FREE(s->s_codes); - } + if (s->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)s); + if (s->s_codes != NULL) { + PyMem_FREE(s->s_codes); + } Py_XDECREF(s->s_format); freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free); free_func(s); Py_DECREF(tp); -} - -static PyObject * -s_unpack_internal(PyStructObject *soself, const char *startfrom) { - formatcode *code; - Py_ssize_t i = 0; - PyObject *result = PyTuple_New(soself->s_len); - if (result == NULL) - return NULL; - - for (code = soself->s_codes; code->fmtdef != NULL; code++) { - const formatdef *e = code->fmtdef; - const char *res = startfrom + code->offset; - Py_ssize_t j = code->repeat; - while (j--) { - PyObject *v; - if (e->format == 's') { - v = PyBytes_FromStringAndSize(res, code->size); - } else if (e->format == 'p') { - Py_ssize_t n = *(unsigned char*)res; - if (n >= code->size) - n = code->size - 1; - v = PyBytes_FromStringAndSize(res + 1, n); - } else { - v = e->unpack(res, e); - } - if (v == NULL) - goto fail; - PyTuple_SET_ITEM(result, i++, v); - res += code->size; - } - } - - return result; -fail: - Py_DECREF(result); - return NULL; -} - - -/*[clinic input] -Struct.unpack - - buffer: Py_buffer - / - -Return a tuple containing unpacked values. - -Unpack according to the format string Struct.format. The buffer's size -in bytes must be Struct.size. - -See help(struct) for more on format strings. -[clinic start generated code]*/ - -static PyObject * -Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer) -/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/ -{ - assert(self->s_codes != NULL); - if (buffer->len != self->s_size) { +} + +static PyObject * +s_unpack_internal(PyStructObject *soself, const char *startfrom) { + formatcode *code; + Py_ssize_t i = 0; + PyObject *result = PyTuple_New(soself->s_len); + if (result == NULL) + return NULL; + + for (code = soself->s_codes; code->fmtdef != NULL; code++) { + const formatdef *e = code->fmtdef; + const char *res = startfrom + code->offset; + Py_ssize_t j = code->repeat; + while (j--) { + PyObject *v; + if (e->format == 's') { + v = PyBytes_FromStringAndSize(res, code->size); + } else if (e->format == 'p') { + Py_ssize_t n = *(unsigned char*)res; + if (n >= code->size) + n = code->size - 1; + v = PyBytes_FromStringAndSize(res + 1, n); + } else { + v = e->unpack(res, e); + } + if (v == NULL) + goto fail; + PyTuple_SET_ITEM(result, i++, v); + res += code->size; + } + } + + return result; +fail: + Py_DECREF(result); + return NULL; +} + + +/*[clinic input] +Struct.unpack + + buffer: Py_buffer + / + +Return a tuple containing unpacked values. + +Unpack according to the format string Struct.format. The buffer's size +in bytes must be Struct.size. + +See help(struct) for more on format strings. +[clinic start generated code]*/ + +static PyObject * +Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer) +/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/ +{ + assert(self->s_codes != NULL); + if (buffer->len != self->s_size) { PyErr_Format(_structmodulestate_global->StructError, - "unpack requires a buffer of %zd bytes", - self->s_size); - return NULL; - } - return s_unpack_internal(self, buffer->buf); -} - -/*[clinic input] -Struct.unpack_from - - buffer: Py_buffer - offset: Py_ssize_t = 0 - -Return a tuple containing unpacked values. - -Values are unpacked according to the format string Struct.format. - + "unpack requires a buffer of %zd bytes", + self->s_size); + return NULL; + } + return s_unpack_internal(self, buffer->buf); +} + +/*[clinic input] +Struct.unpack_from + + buffer: Py_buffer + offset: Py_ssize_t = 0 + +Return a tuple containing unpacked values. + +Values are unpacked according to the format string Struct.format. + The buffer's size in bytes, starting at position offset, must be at least Struct.size. - -See help(struct) for more on format strings. -[clinic start generated code]*/ - -static PyObject * -Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, - Py_ssize_t offset) + +See help(struct) for more on format strings. +[clinic start generated code]*/ + +static PyObject * +Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, + Py_ssize_t offset) /*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/ -{ - assert(self->s_codes != NULL); - +{ + assert(self->s_codes != NULL); + if (offset < 0) { if (offset + self->s_size > 0) { PyErr_Format(_structmodulestate_global->StructError, @@ -1603,7 +1603,7 @@ Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, buffer->len); return NULL; } - offset += buffer->len; + offset += buffer->len; } if ((buffer->len - offset) < self->s_size) { @@ -1615,78 +1615,78 @@ Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, self->s_size, offset, buffer->len); - return NULL; - } - return s_unpack_internal(self, (char*)buffer->buf + offset); -} - - - -/* Unpack iterator type */ - -typedef struct { - PyObject_HEAD - PyStructObject *so; - Py_buffer buf; - Py_ssize_t index; -} unpackiterobject; - -static void -unpackiter_dealloc(unpackiterobject *self) -{ - /* bpo-31095: UnTrack is needed before calling any callbacks */ + return NULL; + } + return s_unpack_internal(self, (char*)buffer->buf + offset); +} + + + +/* Unpack iterator type */ + +typedef struct { + PyObject_HEAD + PyStructObject *so; + Py_buffer buf; + Py_ssize_t index; +} unpackiterobject; + +static void +unpackiter_dealloc(unpackiterobject *self) +{ + /* bpo-31095: UnTrack is needed before calling any callbacks */ PyTypeObject *tp = Py_TYPE(self); - PyObject_GC_UnTrack(self); - Py_XDECREF(self->so); - PyBuffer_Release(&self->buf); - PyObject_GC_Del(self); + PyObject_GC_UnTrack(self); + Py_XDECREF(self->so); + PyBuffer_Release(&self->buf); + PyObject_GC_Del(self); Py_DECREF(tp); -} - -static int -unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg) -{ +} + +static int +unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg) +{ Py_VISIT(Py_TYPE(self)); - Py_VISIT(self->so); - Py_VISIT(self->buf.obj); - return 0; -} - -static PyObject * + Py_VISIT(self->so); + Py_VISIT(self->buf.obj); + return 0; +} + +static PyObject * unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored)) -{ - Py_ssize_t len; - if (self->so == NULL) - len = 0; - else - len = (self->buf.len - self->index) / self->so->s_size; - return PyLong_FromSsize_t(len); -} - -static PyMethodDef unpackiter_methods[] = { - {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -unpackiter_iternext(unpackiterobject *self) -{ - PyObject *result; - if (self->so == NULL) - return NULL; - if (self->index >= self->buf.len) { - /* Iterator exhausted */ - Py_CLEAR(self->so); - PyBuffer_Release(&self->buf); - return NULL; - } - assert(self->index + self->so->s_size <= self->buf.len); - result = s_unpack_internal(self->so, - (char*) self->buf.buf + self->index); - self->index += self->so->s_size; - return result; -} - +{ + Py_ssize_t len; + if (self->so == NULL) + len = 0; + else + len = (self->buf.len - self->index) / self->so->s_size; + return PyLong_FromSsize_t(len); +} + +static PyMethodDef unpackiter_methods[] = { + {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +unpackiter_iternext(unpackiterobject *self) +{ + PyObject *result; + if (self->so == NULL) + return NULL; + if (self->index >= self->buf.len) { + /* Iterator exhausted */ + Py_CLEAR(self->so); + PyBuffer_Release(&self->buf); + return NULL; + } + assert(self->index + self->so->s_size <= self->buf.len); + result = s_unpack_internal(self->so, + (char*) self->buf.buf + self->index); + self->index += self->so->s_size; + return result; +} + PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type)); return NULL; @@ -1701,8 +1701,8 @@ static PyType_Slot unpackiter_type_slots[] = { {Py_tp_methods, unpackiter_methods}, {Py_tp_new, unpackiter_new}, {0, 0}, -}; - +}; + static PyType_Spec unpackiter_type_spec = { "_struct.unpack_iterator", sizeof(unpackiterobject), @@ -1711,343 +1711,343 @@ static PyType_Spec unpackiter_type_spec = { unpackiter_type_slots }; -/*[clinic input] -Struct.iter_unpack - - buffer: object - / - -Return an iterator yielding tuples. - -Tuples are unpacked from the given bytes source, like a repeated -invocation of unpack_from(). - -Requires that the bytes length be a multiple of the struct size. -[clinic start generated code]*/ - -static PyObject * -Struct_iter_unpack(PyStructObject *self, PyObject *buffer) -/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/ -{ - unpackiterobject *iter; - - assert(self->s_codes != NULL); - - if (self->s_size == 0) { +/*[clinic input] +Struct.iter_unpack + + buffer: object + / + +Return an iterator yielding tuples. + +Tuples are unpacked from the given bytes source, like a repeated +invocation of unpack_from(). + +Requires that the bytes length be a multiple of the struct size. +[clinic start generated code]*/ + +static PyObject * +Struct_iter_unpack(PyStructObject *self, PyObject *buffer) +/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/ +{ + unpackiterobject *iter; + + assert(self->s_codes != NULL); + + if (self->s_size == 0) { PyErr_Format(_structmodulestate_global->StructError, - "cannot iteratively unpack with a struct of length 0"); - return NULL; - } - + "cannot iteratively unpack with a struct of length 0"); + return NULL; + } + iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)_structmodulestate_global->unpackiter_type, 0); - if (iter == NULL) - return NULL; - - if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) { - Py_DECREF(iter); - return NULL; - } - if (iter->buf.len % self->s_size != 0) { + if (iter == NULL) + return NULL; + + if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) { + Py_DECREF(iter); + return NULL; + } + if (iter->buf.len % self->s_size != 0) { PyErr_Format(_structmodulestate_global->StructError, - "iterative unpacking requires a buffer of " - "a multiple of %zd bytes", - self->s_size); - Py_DECREF(iter); - return NULL; - } - Py_INCREF(self); - iter->so = self; - iter->index = 0; - return (PyObject *)iter; -} - - -/* - * Guts of the pack function. - * - * Takes a struct object, a tuple of arguments, and offset in that tuple of - * argument for where to start processing the arguments for packing, and a - * character buffer for writing the packed string. The caller must insure - * that the buffer may contain the required length for packing the arguments. - * 0 is returned on success, 1 is returned if there is an error. - * - */ -static int -s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf) -{ - formatcode *code; - /* XXX(nnorwitz): why does i need to be a local? can we use - the offset parameter or do we need the wider width? */ - Py_ssize_t i; - - memset(buf, '\0', soself->s_size); - i = offset; - for (code = soself->s_codes; code->fmtdef != NULL; code++) { - const formatdef *e = code->fmtdef; - char *res = buf + code->offset; - Py_ssize_t j = code->repeat; - while (j--) { - PyObject *v = args[i++]; - if (e->format == 's') { - Py_ssize_t n; - int isstring; + "iterative unpacking requires a buffer of " + "a multiple of %zd bytes", + self->s_size); + Py_DECREF(iter); + return NULL; + } + Py_INCREF(self); + iter->so = self; + iter->index = 0; + return (PyObject *)iter; +} + + +/* + * Guts of the pack function. + * + * Takes a struct object, a tuple of arguments, and offset in that tuple of + * argument for where to start processing the arguments for packing, and a + * character buffer for writing the packed string. The caller must insure + * that the buffer may contain the required length for packing the arguments. + * 0 is returned on success, 1 is returned if there is an error. + * + */ +static int +s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf) +{ + formatcode *code; + /* XXX(nnorwitz): why does i need to be a local? can we use + the offset parameter or do we need the wider width? */ + Py_ssize_t i; + + memset(buf, '\0', soself->s_size); + i = offset; + for (code = soself->s_codes; code->fmtdef != NULL; code++) { + const formatdef *e = code->fmtdef; + char *res = buf + code->offset; + Py_ssize_t j = code->repeat; + while (j--) { + PyObject *v = args[i++]; + if (e->format == 's') { + Py_ssize_t n; + int isstring; const void *p; - isstring = PyBytes_Check(v); - if (!isstring && !PyByteArray_Check(v)) { + isstring = PyBytes_Check(v); + if (!isstring && !PyByteArray_Check(v)) { PyErr_SetString(_structmodulestate_global->StructError, - "argument for 's' must be a bytes object"); - return -1; - } - if (isstring) { - n = PyBytes_GET_SIZE(v); - p = PyBytes_AS_STRING(v); - } - else { - n = PyByteArray_GET_SIZE(v); - p = PyByteArray_AS_STRING(v); - } - if (n > code->size) - n = code->size; - if (n > 0) - memcpy(res, p, n); - } else if (e->format == 'p') { - Py_ssize_t n; - int isstring; + "argument for 's' must be a bytes object"); + return -1; + } + if (isstring) { + n = PyBytes_GET_SIZE(v); + p = PyBytes_AS_STRING(v); + } + else { + n = PyByteArray_GET_SIZE(v); + p = PyByteArray_AS_STRING(v); + } + if (n > code->size) + n = code->size; + if (n > 0) + memcpy(res, p, n); + } else if (e->format == 'p') { + Py_ssize_t n; + int isstring; const void *p; - isstring = PyBytes_Check(v); - if (!isstring && !PyByteArray_Check(v)) { + isstring = PyBytes_Check(v); + if (!isstring && !PyByteArray_Check(v)) { PyErr_SetString(_structmodulestate_global->StructError, - "argument for 'p' must be a bytes object"); - return -1; - } - if (isstring) { - n = PyBytes_GET_SIZE(v); - p = PyBytes_AS_STRING(v); - } - else { - n = PyByteArray_GET_SIZE(v); - p = PyByteArray_AS_STRING(v); - } - if (n > (code->size - 1)) - n = code->size - 1; - if (n > 0) - memcpy(res + 1, p, n); - if (n > 255) - n = 255; - *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char); - } else { - if (e->pack(res, v, e) < 0) { - if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError)) + "argument for 'p' must be a bytes object"); + return -1; + } + if (isstring) { + n = PyBytes_GET_SIZE(v); + p = PyBytes_AS_STRING(v); + } + else { + n = PyByteArray_GET_SIZE(v); + p = PyByteArray_AS_STRING(v); + } + if (n > (code->size - 1)) + n = code->size - 1; + if (n > 0) + memcpy(res + 1, p, n); + if (n > 255) + n = 255; + *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char); + } else { + if (e->pack(res, v, e) < 0) { + if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(_structmodulestate_global->StructError, - "int too large to convert"); - return -1; - } - } - res += code->size; - } - } - - /* Success */ - return 0; -} - - -PyDoc_STRVAR(s_pack__doc__, -"S.pack(v1, v2, ...) -> bytes\n\ -\n\ -Return a bytes object containing values v1, v2, ... packed according\n\ -to the format string S.format. See help(struct) for more on format\n\ -strings."); - -static PyObject * -s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ + "int too large to convert"); + return -1; + } + } + res += code->size; + } + } + + /* Success */ + return 0; +} + + +PyDoc_STRVAR(s_pack__doc__, +"S.pack(v1, v2, ...) -> bytes\n\ +\n\ +Return a bytes object containing values v1, v2, ... packed according\n\ +to the format string S.format. See help(struct) for more on format\n\ +strings."); + +static PyObject * +s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ char *buf; - PyStructObject *soself; - - /* Validate arguments. */ - soself = (PyStructObject *)self; - assert(PyStruct_Check(self)); - assert(soself->s_codes != NULL); - if (nargs != soself->s_len) - { + PyStructObject *soself; + + /* Validate arguments. */ + soself = (PyStructObject *)self; + assert(PyStruct_Check(self)); + assert(soself->s_codes != NULL); + if (nargs != soself->s_len) + { PyErr_Format(_structmodulestate_global->StructError, - "pack expected %zd items for packing (got %zd)", soself->s_len, nargs); - return NULL; - } - + "pack expected %zd items for packing (got %zd)", soself->s_len, nargs); + return NULL; + } + /* Allocate a new string */ _PyBytesWriter writer; _PyBytesWriter_Init(&writer); buf = _PyBytesWriter_Alloc(&writer, soself->s_size); if (buf == NULL) { _PyBytesWriter_Dealloc(&writer); - return NULL; + return NULL; } - - /* Call the guts */ + + /* Call the guts */ if ( s_pack_internal(soself, args, 0, buf) != 0 ) { _PyBytesWriter_Dealloc(&writer); - return NULL; - } - + return NULL; + } + return _PyBytesWriter_Finish(&writer, buf + soself->s_size); -} - -PyDoc_STRVAR(s_pack_into__doc__, -"S.pack_into(buffer, offset, v1, v2, ...)\n\ -\n\ -Pack the values v1, v2, ... according to the format string S.format\n\ -and write the packed bytes into the writable buffer buf starting at\n\ -offset. Note that the offset is a required argument. See\n\ -help(struct) for more on format strings."); - -static PyObject * -s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyStructObject *soself; - Py_buffer buffer; - Py_ssize_t offset; - - /* Validate arguments. +1 is for the first arg as buffer. */ - soself = (PyStructObject *)self; - assert(PyStruct_Check(self)); - assert(soself->s_codes != NULL); - if (nargs != (soself->s_len + 2)) - { - if (nargs == 0) { +} + +PyDoc_STRVAR(s_pack_into__doc__, +"S.pack_into(buffer, offset, v1, v2, ...)\n\ +\n\ +Pack the values v1, v2, ... according to the format string S.format\n\ +and write the packed bytes into the writable buffer buf starting at\n\ +offset. Note that the offset is a required argument. See\n\ +help(struct) for more on format strings."); + +static PyObject * +s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyStructObject *soself; + Py_buffer buffer; + Py_ssize_t offset; + + /* Validate arguments. +1 is for the first arg as buffer. */ + soself = (PyStructObject *)self; + assert(PyStruct_Check(self)); + assert(soself->s_codes != NULL); + if (nargs != (soself->s_len + 2)) + { + if (nargs == 0) { PyErr_Format(_structmodulestate_global->StructError, - "pack_into expected buffer argument"); - } - else if (nargs == 1) { + "pack_into expected buffer argument"); + } + else if (nargs == 1) { PyErr_Format(_structmodulestate_global->StructError, - "pack_into expected offset argument"); - } - else { + "pack_into expected offset argument"); + } + else { PyErr_Format(_structmodulestate_global->StructError, - "pack_into expected %zd items for packing (got %zd)", - soself->s_len, (nargs - 2)); - } - return NULL; - } - - /* Extract a writable memory buffer from the first argument */ - if (!PyArg_Parse(args[0], "w*", &buffer)) - return NULL; - assert(buffer.len >= 0); - - /* Extract the offset from the first argument */ - offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError); - if (offset == -1 && PyErr_Occurred()) { - PyBuffer_Release(&buffer); - return NULL; - } - - /* Support negative offsets. */ - if (offset < 0) { - /* Check that negative offset is low enough to fit data */ - if (offset + soself->s_size > 0) { + "pack_into expected %zd items for packing (got %zd)", + soself->s_len, (nargs - 2)); + } + return NULL; + } + + /* Extract a writable memory buffer from the first argument */ + if (!PyArg_Parse(args[0], "w*", &buffer)) + return NULL; + assert(buffer.len >= 0); + + /* Extract the offset from the first argument */ + offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError); + if (offset == -1 && PyErr_Occurred()) { + PyBuffer_Release(&buffer); + return NULL; + } + + /* Support negative offsets. */ + if (offset < 0) { + /* Check that negative offset is low enough to fit data */ + if (offset + soself->s_size > 0) { PyErr_Format(_structmodulestate_global->StructError, - "no space to pack %zd bytes at offset %zd", - soself->s_size, - offset); - PyBuffer_Release(&buffer); - return NULL; - } - - /* Check that negative offset is not crossing buffer boundary */ - if (offset + buffer.len < 0) { + "no space to pack %zd bytes at offset %zd", + soself->s_size, + offset); + PyBuffer_Release(&buffer); + return NULL; + } + + /* Check that negative offset is not crossing buffer boundary */ + if (offset + buffer.len < 0) { PyErr_Format(_structmodulestate_global->StructError, - "offset %zd out of range for %zd-byte buffer", - offset, - buffer.len); - PyBuffer_Release(&buffer); - return NULL; - } - - offset += buffer.len; - } - - /* Check boundaries */ - if ((buffer.len - offset) < soself->s_size) { - assert(offset >= 0); - assert(soself->s_size >= 0); - + "offset %zd out of range for %zd-byte buffer", + offset, + buffer.len); + PyBuffer_Release(&buffer); + return NULL; + } + + offset += buffer.len; + } + + /* Check boundaries */ + if ((buffer.len - offset) < soself->s_size) { + assert(offset >= 0); + assert(soself->s_size >= 0); + PyErr_Format(_structmodulestate_global->StructError, - "pack_into requires a buffer of at least %zu bytes for " - "packing %zd bytes at offset %zd " - "(actual buffer size is %zd)", - (size_t)soself->s_size + (size_t)offset, - soself->s_size, - offset, - buffer.len); - PyBuffer_Release(&buffer); - return NULL; - } - - /* Call the guts */ - if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) { - PyBuffer_Release(&buffer); - return NULL; - } - - PyBuffer_Release(&buffer); - Py_RETURN_NONE; -} - -static PyObject * -s_get_format(PyStructObject *self, void *unused) -{ - return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format), - PyBytes_GET_SIZE(self->s_format)); -} - -static PyObject * -s_get_size(PyStructObject *self, void *unused) -{ - return PyLong_FromSsize_t(self->s_size); -} - -PyDoc_STRVAR(s_sizeof__doc__, -"S.__sizeof__() -> size of S in memory, in bytes"); - -static PyObject * -s_sizeof(PyStructObject *self, void *unused) -{ - Py_ssize_t size; - formatcode *code; - - size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); - for (code = self->s_codes; code->fmtdef != NULL; code++) - size += sizeof(formatcode); - return PyLong_FromSsize_t(size); -} - -/* List of functions */ - -static struct PyMethodDef s_methods[] = { - STRUCT_ITER_UNPACK_METHODDEF + "pack_into requires a buffer of at least %zu bytes for " + "packing %zd bytes at offset %zd " + "(actual buffer size is %zd)", + (size_t)soself->s_size + (size_t)offset, + soself->s_size, + offset, + buffer.len); + PyBuffer_Release(&buffer); + return NULL; + } + + /* Call the guts */ + if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) { + PyBuffer_Release(&buffer); + return NULL; + } + + PyBuffer_Release(&buffer); + Py_RETURN_NONE; +} + +static PyObject * +s_get_format(PyStructObject *self, void *unused) +{ + return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format), + PyBytes_GET_SIZE(self->s_format)); +} + +static PyObject * +s_get_size(PyStructObject *self, void *unused) +{ + return PyLong_FromSsize_t(self->s_size); +} + +PyDoc_STRVAR(s_sizeof__doc__, +"S.__sizeof__() -> size of S in memory, in bytes"); + +static PyObject * +s_sizeof(PyStructObject *self, void *unused) +{ + Py_ssize_t size; + formatcode *code; + + size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); + for (code = self->s_codes; code->fmtdef != NULL; code++) + size += sizeof(formatcode); + return PyLong_FromSsize_t(size); +} + +/* List of functions */ + +static struct PyMethodDef s_methods[] = { + STRUCT_ITER_UNPACK_METHODDEF {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__}, {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__}, - STRUCT_UNPACK_METHODDEF - STRUCT_UNPACK_FROM_METHODDEF - {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__}, - {NULL, NULL} /* sentinel */ -}; - + STRUCT_UNPACK_METHODDEF + STRUCT_UNPACK_FROM_METHODDEF + {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__}, + {NULL, NULL} /* sentinel */ +}; + static PyMemberDef s_members[] = { {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY}, {NULL} /* sentinel */ }; -#define OFF(x) offsetof(PyStructObject, x) - -static PyGetSetDef s_getsetlist[] = { - {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL}, - {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL}, - {NULL} /* sentinel */ -}; - +#define OFF(x) offsetof(PyStructObject, x) + +static PyGetSetDef s_getsetlist[] = { + {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL}, + {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL}, + {NULL} /* sentinel */ +}; + PyDoc_STRVAR(s__doc__, "Struct(fmt) --> compiled struct object\n" "\n" @@ -2070,255 +2070,255 @@ static PyType_Slot PyStructType_slots[] = { static PyType_Spec PyStructType_spec = { "_struct.Struct", - sizeof(PyStructObject), - 0, + sizeof(PyStructObject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, PyStructType_slots -}; - - -/* ---- Standalone functions ---- */ - -#define MAXCACHE 100 -static PyObject *cache = NULL; - -static int +}; + + +/* ---- Standalone functions ---- */ + +#define MAXCACHE 100 +static PyObject *cache = NULL; + +static int cache_struct_converter(PyObject *fmt, PyStructObject **ptr) -{ - PyObject * s_object; - - if (fmt == NULL) { - Py_DECREF(*ptr); - *ptr = NULL; - return 1; - } - - if (cache == NULL) { - cache = PyDict_New(); - if (cache == NULL) - return 0; - } - +{ + PyObject * s_object; + + if (fmt == NULL) { + Py_DECREF(*ptr); + *ptr = NULL; + return 1; + } + + if (cache == NULL) { + cache = PyDict_New(); + if (cache == NULL) + return 0; + } + s_object = PyDict_GetItemWithError(cache, fmt); - if (s_object != NULL) { - Py_INCREF(s_object); + if (s_object != NULL) { + Py_INCREF(s_object); *ptr = (PyStructObject *)s_object; - return Py_CLEANUP_SUPPORTED; - } + return Py_CLEANUP_SUPPORTED; + } else if (PyErr_Occurred()) { return 0; } - + s_object = PyObject_CallOneArg(_structmodulestate_global->PyStructType, fmt); - if (s_object != NULL) { - if (PyDict_GET_SIZE(cache) >= MAXCACHE) - PyDict_Clear(cache); - /* Attempt to cache the result */ - if (PyDict_SetItem(cache, fmt, s_object) == -1) - PyErr_Clear(); + if (s_object != NULL) { + if (PyDict_GET_SIZE(cache) >= MAXCACHE) + PyDict_Clear(cache); + /* Attempt to cache the result */ + if (PyDict_SetItem(cache, fmt, s_object) == -1) + PyErr_Clear(); *ptr = (PyStructObject *)s_object; - return Py_CLEANUP_SUPPORTED; - } - return 0; -} - -/*[clinic input] -_clearcache - -Clear the internal cache. -[clinic start generated code]*/ - -static PyObject * -_clearcache_impl(PyObject *module) -/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/ -{ - Py_CLEAR(cache); - Py_RETURN_NONE; -} - - -/*[clinic input] -calcsize -> Py_ssize_t - - format as s_object: cache_struct - / - -Return size in bytes of the struct described by the format string. -[clinic start generated code]*/ - -static Py_ssize_t -calcsize_impl(PyObject *module, PyStructObject *s_object) -/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/ -{ - return s_object->s_size; -} - -PyDoc_STRVAR(pack_doc, -"pack(format, v1, v2, ...) -> bytes\n\ -\n\ -Return a bytes object containing the values v1, v2, ... packed according\n\ -to the format string. See help(struct) for more on format strings."); - -static PyObject * -pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *s_object = NULL; - PyObject *format, *result; - - if (nargs == 0) { - PyErr_SetString(PyExc_TypeError, "missing format argument"); - return NULL; - } - format = args[0]; - + return Py_CLEANUP_SUPPORTED; + } + return 0; +} + +/*[clinic input] +_clearcache + +Clear the internal cache. +[clinic start generated code]*/ + +static PyObject * +_clearcache_impl(PyObject *module) +/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/ +{ + Py_CLEAR(cache); + Py_RETURN_NONE; +} + + +/*[clinic input] +calcsize -> Py_ssize_t + + format as s_object: cache_struct + / + +Return size in bytes of the struct described by the format string. +[clinic start generated code]*/ + +static Py_ssize_t +calcsize_impl(PyObject *module, PyStructObject *s_object) +/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/ +{ + return s_object->s_size; +} + +PyDoc_STRVAR(pack_doc, +"pack(format, v1, v2, ...) -> bytes\n\ +\n\ +Return a bytes object containing the values v1, v2, ... packed according\n\ +to the format string. See help(struct) for more on format strings."); + +static PyObject * +pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *s_object = NULL; + PyObject *format, *result; + + if (nargs == 0) { + PyErr_SetString(PyExc_TypeError, "missing format argument"); + return NULL; + } + format = args[0]; + if (!cache_struct_converter(format, (PyStructObject **)&s_object)) { - return NULL; - } - result = s_pack(s_object, args + 1, nargs - 1); - Py_DECREF(s_object); - return result; -} - -PyDoc_STRVAR(pack_into_doc, -"pack_into(format, buffer, offset, v1, v2, ...)\n\ -\n\ -Pack the values v1, v2, ... according to the format string and write\n\ -the packed bytes into the writable buffer buf starting at offset. Note\n\ -that the offset is a required argument. See help(struct) for more\n\ -on format strings."); - -static PyObject * -pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *s_object = NULL; - PyObject *format, *result; - - if (nargs == 0) { - PyErr_SetString(PyExc_TypeError, "missing format argument"); - return NULL; - } - format = args[0]; - + return NULL; + } + result = s_pack(s_object, args + 1, nargs - 1); + Py_DECREF(s_object); + return result; +} + +PyDoc_STRVAR(pack_into_doc, +"pack_into(format, buffer, offset, v1, v2, ...)\n\ +\n\ +Pack the values v1, v2, ... according to the format string and write\n\ +the packed bytes into the writable buffer buf starting at offset. Note\n\ +that the offset is a required argument. See help(struct) for more\n\ +on format strings."); + +static PyObject * +pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *s_object = NULL; + PyObject *format, *result; + + if (nargs == 0) { + PyErr_SetString(PyExc_TypeError, "missing format argument"); + return NULL; + } + format = args[0]; + if (!cache_struct_converter(format, (PyStructObject **)&s_object)) { - return NULL; - } - result = s_pack_into(s_object, args + 1, nargs - 1); - Py_DECREF(s_object); - return result; -} - -/*[clinic input] -unpack - - format as s_object: cache_struct - buffer: Py_buffer - / - -Return a tuple containing values unpacked according to the format string. - -The buffer's size in bytes must be calcsize(format). - -See help(struct) for more on format strings. -[clinic start generated code]*/ - -static PyObject * -unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer) -/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/ -{ - return Struct_unpack_impl(s_object, buffer); -} - -/*[clinic input] -unpack_from - - format as s_object: cache_struct - / - buffer: Py_buffer - offset: Py_ssize_t = 0 - -Return a tuple containing values unpacked according to the format string. - -The buffer's size, minus offset, must be at least calcsize(format). - -See help(struct) for more on format strings. -[clinic start generated code]*/ - -static PyObject * -unpack_from_impl(PyObject *module, PyStructObject *s_object, - Py_buffer *buffer, Py_ssize_t offset) -/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/ -{ - return Struct_unpack_from_impl(s_object, buffer, offset); -} - -/*[clinic input] -iter_unpack - - format as s_object: cache_struct - buffer: object - / - -Return an iterator yielding tuples unpacked from the given bytes. - -The bytes are unpacked according to the format string, like -a repeated invocation of unpack_from(). - -Requires that the bytes length be a multiple of the format struct size. -[clinic start generated code]*/ - -static PyObject * -iter_unpack_impl(PyObject *module, PyStructObject *s_object, - PyObject *buffer) -/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/ -{ - return Struct_iter_unpack(s_object, buffer); -} - -static struct PyMethodDef module_functions[] = { - _CLEARCACHE_METHODDEF - CALCSIZE_METHODDEF - ITER_UNPACK_METHODDEF + return NULL; + } + result = s_pack_into(s_object, args + 1, nargs - 1); + Py_DECREF(s_object); + return result; +} + +/*[clinic input] +unpack + + format as s_object: cache_struct + buffer: Py_buffer + / + +Return a tuple containing values unpacked according to the format string. + +The buffer's size in bytes must be calcsize(format). + +See help(struct) for more on format strings. +[clinic start generated code]*/ + +static PyObject * +unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer) +/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/ +{ + return Struct_unpack_impl(s_object, buffer); +} + +/*[clinic input] +unpack_from + + format as s_object: cache_struct + / + buffer: Py_buffer + offset: Py_ssize_t = 0 + +Return a tuple containing values unpacked according to the format string. + +The buffer's size, minus offset, must be at least calcsize(format). + +See help(struct) for more on format strings. +[clinic start generated code]*/ + +static PyObject * +unpack_from_impl(PyObject *module, PyStructObject *s_object, + Py_buffer *buffer, Py_ssize_t offset) +/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/ +{ + return Struct_unpack_from_impl(s_object, buffer, offset); +} + +/*[clinic input] +iter_unpack + + format as s_object: cache_struct + buffer: object + / + +Return an iterator yielding tuples unpacked from the given bytes. + +The bytes are unpacked according to the format string, like +a repeated invocation of unpack_from(). + +Requires that the bytes length be a multiple of the format struct size. +[clinic start generated code]*/ + +static PyObject * +iter_unpack_impl(PyObject *module, PyStructObject *s_object, + PyObject *buffer) +/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/ +{ + return Struct_iter_unpack(s_object, buffer); +} + +static struct PyMethodDef module_functions[] = { + _CLEARCACHE_METHODDEF + CALCSIZE_METHODDEF + ITER_UNPACK_METHODDEF {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc}, {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc}, - UNPACK_METHODDEF - UNPACK_FROM_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -/* Module initialization */ - -PyDoc_STRVAR(module_doc, -"Functions to convert between Python values and C structs.\n\ -Python bytes objects are used to hold the data representing the C struct\n\ -and also as format strings (explained below) to describe the layout of data\n\ -in the C struct.\n\ -\n\ -The optional first format char indicates byte order, size and alignment:\n\ - @: native order, size & alignment (default)\n\ - =: native order, std. size & alignment\n\ - <: little-endian, std. size & alignment\n\ - >: big-endian, std. size & alignment\n\ - !: same as >\n\ -\n\ -The remaining chars indicate types of args and must match exactly;\n\ -these can be preceded by a decimal repeat count:\n\ - x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\ - ?: _Bool (requires C99; if not available, char is used instead)\n\ - h:short; H:unsigned short; i:int; I:unsigned int;\n\ - l:long; L:unsigned long; f:float; d:double; e:half-float.\n\ -Special cases (preceding decimal count indicates length):\n\ - s:string (array of char); p: pascal string (with count byte).\n\ -Special cases (only available in native format):\n\ - n:ssize_t; N:size_t;\n\ - P:an integer type that is wide enough to hold a pointer.\n\ -Special case (not in native mode unless 'long long' in platform C):\n\ - q:long long; Q:unsigned long long\n\ -Whitespace between formats is ignored.\n\ -\n\ -The variable struct.error is an exception raised on errors.\n"); - - + UNPACK_METHODDEF + UNPACK_FROM_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +/* Module initialization */ + +PyDoc_STRVAR(module_doc, +"Functions to convert between Python values and C structs.\n\ +Python bytes objects are used to hold the data representing the C struct\n\ +and also as format strings (explained below) to describe the layout of data\n\ +in the C struct.\n\ +\n\ +The optional first format char indicates byte order, size and alignment:\n\ + @: native order, size & alignment (default)\n\ + =: native order, std. size & alignment\n\ + <: little-endian, std. size & alignment\n\ + >: big-endian, std. size & alignment\n\ + !: same as >\n\ +\n\ +The remaining chars indicate types of args and must match exactly;\n\ +these can be preceded by a decimal repeat count:\n\ + x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\ + ?: _Bool (requires C99; if not available, char is used instead)\n\ + h:short; H:unsigned short; i:int; I:unsigned int;\n\ + l:long; L:unsigned long; f:float; d:double; e:half-float.\n\ +Special cases (preceding decimal count indicates length):\n\ + s:string (array of char); p: pascal string (with count byte).\n\ +Special cases (only available in native format):\n\ + n:ssize_t; N:size_t;\n\ + P:an integer type that is wide enough to hold a pointer.\n\ +Special case (not in native mode unless 'long long' in platform C):\n\ + q:long long; Q:unsigned long long\n\ +Whitespace between formats is ignored.\n\ +\n\ +The variable struct.error is an exception raised on errors.\n"); + + static int _structmodule_traverse(PyObject *module, visitproc visit, void *arg) { @@ -2349,90 +2349,90 @@ _structmodule_free(void *module) _structmodule_clear((PyObject *)module); } -static struct PyModuleDef _structmodule = { - PyModuleDef_HEAD_INIT, - "_struct", - module_doc, +static struct PyModuleDef _structmodule = { + PyModuleDef_HEAD_INIT, + "_struct", + module_doc, sizeof(_structmodulestate), - module_functions, - NULL, + module_functions, + NULL, _structmodule_traverse, _structmodule_clear, _structmodule_free, -}; - -PyMODINIT_FUNC -PyInit__struct(void) -{ - PyObject *m; - - m = PyModule_Create(&_structmodule); - if (m == NULL) - return NULL; - +}; + +PyMODINIT_FUNC +PyInit__struct(void) +{ + PyObject *m; + + m = PyModule_Create(&_structmodule); + if (m == NULL) + return NULL; + PyObject *PyStructType = PyType_FromSpec(&PyStructType_spec); if (PyStructType == NULL) { - return NULL; + return NULL; } Py_INCREF(PyStructType); PyModule_AddObject(m, "Struct", PyStructType); get_struct_state(m)->PyStructType = PyStructType; - + PyObject *unpackiter_type = PyType_FromSpec(&unpackiter_type_spec); if (unpackiter_type == NULL) { - return NULL; + return NULL; } get_struct_state(m)->unpackiter_type = unpackiter_type; - - /* Check endian and swap in faster functions */ - { - const formatdef *native = native_table; - formatdef *other, *ptr; -#if PY_LITTLE_ENDIAN - other = lilendian_table; -#else - other = bigendian_table; -#endif - /* Scan through the native table, find a matching - entry in the endian table and swap in the - native implementations whenever possible - (64-bit platforms may not have "standard" sizes) */ - while (native->format != '\0' && other->format != '\0') { - ptr = other; - while (ptr->format != '\0') { - if (ptr->format == native->format) { - /* Match faster when formats are - listed in the same order */ - if (ptr == other) - other++; - /* Only use the trick if the - size matches */ - if (ptr->size != native->size) - break; - /* Skip float and double, could be - "unknown" float format */ - if (ptr->format == 'd' || ptr->format == 'f') - break; + + /* Check endian and swap in faster functions */ + { + const formatdef *native = native_table; + formatdef *other, *ptr; +#if PY_LITTLE_ENDIAN + other = lilendian_table; +#else + other = bigendian_table; +#endif + /* Scan through the native table, find a matching + entry in the endian table and swap in the + native implementations whenever possible + (64-bit platforms may not have "standard" sizes) */ + while (native->format != '\0' && other->format != '\0') { + ptr = other; + while (ptr->format != '\0') { + if (ptr->format == native->format) { + /* Match faster when formats are + listed in the same order */ + if (ptr == other) + other++; + /* Only use the trick if the + size matches */ + if (ptr->size != native->size) + break; + /* Skip float and double, could be + "unknown" float format */ + if (ptr->format == 'd' || ptr->format == 'f') + break; /* Skip _Bool, semantics are different for standard size */ if (ptr->format == '?') break; - ptr->pack = native->pack; - ptr->unpack = native->unpack; - break; - } - ptr++; - } - native++; - } - } - - /* Add some symbolic constants to the module */ + ptr->pack = native->pack; + ptr->unpack = native->unpack; + break; + } + ptr++; + } + native++; + } + } + + /* Add some symbolic constants to the module */ PyObject *StructError = PyErr_NewException("struct.error", NULL, NULL); if (StructError == NULL) return NULL; - Py_INCREF(StructError); - PyModule_AddObject(m, "error", StructError); + Py_INCREF(StructError); + PyModule_AddObject(m, "error", StructError); get_struct_state(m)->StructError = StructError; - - return m; -} + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_threadmodule.c b/contrib/tools/python3/src/Modules/_threadmodule.c index a370352238d..48f0aaab87e 100644 --- a/contrib/tools/python3/src/Modules/_threadmodule.c +++ b/contrib/tools/python3/src/Modules/_threadmodule.c @@ -1,210 +1,210 @@ - -/* Thread module */ -/* Interface to Sjoerd's portable C thread library */ - -#include "Python.h" + +/* Thread module */ +/* Interface to Sjoerd's portable C thread library */ + +#include "Python.h" #include "pycore_pylifecycle.h" #include "pycore_interp.h" // _PyInterpreterState.num_threads #include "pycore_pystate.h" // _PyThreadState_Init() #include // offsetof() - -static PyObject *ThreadError; -static PyObject *str_dict; - -_Py_IDENTIFIER(stderr); + +static PyObject *ThreadError; +static PyObject *str_dict; + +_Py_IDENTIFIER(stderr); _Py_IDENTIFIER(flush); - -/* Lock objects */ - -typedef struct { - PyObject_HEAD - PyThread_type_lock lock_lock; - PyObject *in_weakreflist; - char locked; /* for sanity checking */ -} lockobject; - -static void -lock_dealloc(lockobject *self) -{ - if (self->in_weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - if (self->lock_lock != NULL) { - /* Unlock the lock so it's safe to free it */ - if (self->locked) - PyThread_release_lock(self->lock_lock); - PyThread_free_lock(self->lock_lock); - } - PyObject_Del(self); -} - -/* Helper to acquire an interruptible lock with a timeout. If the lock acquire - * is interrupted, signal handlers are run, and if they raise an exception, - * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE - * are returned, depending on whether the lock can be acquired within the - * timeout. - */ -static PyLockStatus -acquire_timed(PyThread_type_lock lock, _PyTime_t timeout) -{ - PyLockStatus r; - _PyTime_t endtime = 0; - _PyTime_t microseconds; - - if (timeout > 0) - endtime = _PyTime_GetMonotonicClock() + timeout; - - do { - microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING); - - /* first a simple non-blocking try without releasing the GIL */ - r = PyThread_acquire_lock_timed(lock, 0, 0); - if (r == PY_LOCK_FAILURE && microseconds != 0) { - Py_BEGIN_ALLOW_THREADS - r = PyThread_acquire_lock_timed(lock, microseconds, 1); - Py_END_ALLOW_THREADS - } - - if (r == PY_LOCK_INTR) { - /* Run signal handlers if we were interrupted. Propagate - * exceptions from signal handlers, such as KeyboardInterrupt, by - * passing up PY_LOCK_INTR. */ - if (Py_MakePendingCalls() < 0) { - return PY_LOCK_INTR; - } - - /* If we're using a timeout, recompute the timeout after processing - * signals, since those can take time. */ - if (timeout > 0) { - timeout = endtime - _PyTime_GetMonotonicClock(); - - /* Check for negative values, since those mean block forever. - */ - if (timeout < 0) { - r = PY_LOCK_FAILURE; - } - } - } - } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */ - - return r; -} - -static int -lock_acquire_parse_args(PyObject *args, PyObject *kwds, - _PyTime_t *timeout) -{ - char *kwlist[] = {"blocking", "timeout", NULL}; - int blocking = 1; - PyObject *timeout_obj = NULL; - const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1); - - *timeout = unset_timeout ; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist, - &blocking, &timeout_obj)) - return -1; - - if (timeout_obj - && _PyTime_FromSecondsObject(timeout, - timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) - return -1; - - if (!blocking && *timeout != unset_timeout ) { - PyErr_SetString(PyExc_ValueError, - "can't specify a timeout for a non-blocking call"); - return -1; - } - if (*timeout < 0 && *timeout != unset_timeout) { - PyErr_SetString(PyExc_ValueError, - "timeout value must be positive"); - return -1; - } - if (!blocking) - *timeout = 0; - else if (*timeout != unset_timeout) { - _PyTime_t microseconds; - - microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT); - if (microseconds >= PY_TIMEOUT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "timeout value is too large"); - return -1; - } - } - return 0; -} - -static PyObject * -lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds) -{ - _PyTime_t timeout; - PyLockStatus r; - - if (lock_acquire_parse_args(args, kwds, &timeout) < 0) - return NULL; - - r = acquire_timed(self->lock_lock, timeout); - if (r == PY_LOCK_INTR) { - return NULL; - } - - if (r == PY_LOCK_ACQUIRED) - self->locked = 1; - return PyBool_FromLong(r == PY_LOCK_ACQUIRED); -} - -PyDoc_STRVAR(acquire_doc, -"acquire(blocking=True, timeout=-1) -> bool\n\ -(acquire_lock() is an obsolete synonym)\n\ -\n\ -Lock the lock. Without argument, this blocks if the lock is already\n\ -locked (even by the same thread), waiting for another thread to release\n\ -the lock, and return True once the lock is acquired.\n\ -With an argument, this will only block if the argument is true,\n\ -and the return value reflects whether the lock is acquired.\n\ -The blocking operation is interruptible."); - -static PyObject * + +/* Lock objects */ + +typedef struct { + PyObject_HEAD + PyThread_type_lock lock_lock; + PyObject *in_weakreflist; + char locked; /* for sanity checking */ +} lockobject; + +static void +lock_dealloc(lockobject *self) +{ + if (self->in_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + if (self->lock_lock != NULL) { + /* Unlock the lock so it's safe to free it */ + if (self->locked) + PyThread_release_lock(self->lock_lock); + PyThread_free_lock(self->lock_lock); + } + PyObject_Del(self); +} + +/* Helper to acquire an interruptible lock with a timeout. If the lock acquire + * is interrupted, signal handlers are run, and if they raise an exception, + * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE + * are returned, depending on whether the lock can be acquired within the + * timeout. + */ +static PyLockStatus +acquire_timed(PyThread_type_lock lock, _PyTime_t timeout) +{ + PyLockStatus r; + _PyTime_t endtime = 0; + _PyTime_t microseconds; + + if (timeout > 0) + endtime = _PyTime_GetMonotonicClock() + timeout; + + do { + microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING); + + /* first a simple non-blocking try without releasing the GIL */ + r = PyThread_acquire_lock_timed(lock, 0, 0); + if (r == PY_LOCK_FAILURE && microseconds != 0) { + Py_BEGIN_ALLOW_THREADS + r = PyThread_acquire_lock_timed(lock, microseconds, 1); + Py_END_ALLOW_THREADS + } + + if (r == PY_LOCK_INTR) { + /* Run signal handlers if we were interrupted. Propagate + * exceptions from signal handlers, such as KeyboardInterrupt, by + * passing up PY_LOCK_INTR. */ + if (Py_MakePendingCalls() < 0) { + return PY_LOCK_INTR; + } + + /* If we're using a timeout, recompute the timeout after processing + * signals, since those can take time. */ + if (timeout > 0) { + timeout = endtime - _PyTime_GetMonotonicClock(); + + /* Check for negative values, since those mean block forever. + */ + if (timeout < 0) { + r = PY_LOCK_FAILURE; + } + } + } + } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */ + + return r; +} + +static int +lock_acquire_parse_args(PyObject *args, PyObject *kwds, + _PyTime_t *timeout) +{ + char *kwlist[] = {"blocking", "timeout", NULL}; + int blocking = 1; + PyObject *timeout_obj = NULL; + const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1); + + *timeout = unset_timeout ; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist, + &blocking, &timeout_obj)) + return -1; + + if (timeout_obj + && _PyTime_FromSecondsObject(timeout, + timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) + return -1; + + if (!blocking && *timeout != unset_timeout ) { + PyErr_SetString(PyExc_ValueError, + "can't specify a timeout for a non-blocking call"); + return -1; + } + if (*timeout < 0 && *timeout != unset_timeout) { + PyErr_SetString(PyExc_ValueError, + "timeout value must be positive"); + return -1; + } + if (!blocking) + *timeout = 0; + else if (*timeout != unset_timeout) { + _PyTime_t microseconds; + + microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT); + if (microseconds >= PY_TIMEOUT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "timeout value is too large"); + return -1; + } + } + return 0; +} + +static PyObject * +lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds) +{ + _PyTime_t timeout; + PyLockStatus r; + + if (lock_acquire_parse_args(args, kwds, &timeout) < 0) + return NULL; + + r = acquire_timed(self->lock_lock, timeout); + if (r == PY_LOCK_INTR) { + return NULL; + } + + if (r == PY_LOCK_ACQUIRED) + self->locked = 1; + return PyBool_FromLong(r == PY_LOCK_ACQUIRED); +} + +PyDoc_STRVAR(acquire_doc, +"acquire(blocking=True, timeout=-1) -> bool\n\ +(acquire_lock() is an obsolete synonym)\n\ +\n\ +Lock the lock. Without argument, this blocks if the lock is already\n\ +locked (even by the same thread), waiting for another thread to release\n\ +the lock, and return True once the lock is acquired.\n\ +With an argument, this will only block if the argument is true,\n\ +and the return value reflects whether the lock is acquired.\n\ +The blocking operation is interruptible."); + +static PyObject * lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored)) -{ - /* Sanity check: the lock must be locked */ - if (!self->locked) { - PyErr_SetString(ThreadError, "release unlocked lock"); - return NULL; - } - - PyThread_release_lock(self->lock_lock); - self->locked = 0; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(release_doc, -"release()\n\ -(release_lock() is an obsolete synonym)\n\ -\n\ -Release the lock, allowing another thread that is blocked waiting for\n\ -the lock to acquire the lock. The lock must be in the locked state,\n\ -but it needn't be locked by the same thread that unlocks it."); - -static PyObject * +{ + /* Sanity check: the lock must be locked */ + if (!self->locked) { + PyErr_SetString(ThreadError, "release unlocked lock"); + return NULL; + } + + PyThread_release_lock(self->lock_lock); + self->locked = 0; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(release_doc, +"release()\n\ +(release_lock() is an obsolete synonym)\n\ +\n\ +Release the lock, allowing another thread that is blocked waiting for\n\ +the lock to acquire the lock. The lock must be in the locked state,\n\ +but it needn't be locked by the same thread that unlocks it."); + +static PyObject * lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored)) -{ - return PyBool_FromLong((long)self->locked); -} - -PyDoc_STRVAR(locked_doc, -"locked() -> bool\n\ -(locked_lock() is an obsolete synonym)\n\ -\n\ -Return whether the lock is in the locked state."); - -static PyObject * -lock_repr(lockobject *self) -{ - return PyUnicode_FromFormat("<%s %s object at %p>", - self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self); -} - +{ + return PyBool_FromLong((long)self->locked); +} + +PyDoc_STRVAR(locked_doc, +"locked() -> bool\n\ +(locked_lock() is an obsolete synonym)\n\ +\n\ +Return whether the lock is in the locked state."); + +static PyObject * +lock_repr(lockobject *self) +{ + return PyUnicode_FromFormat("<%s %s object at %p>", + self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self); +} + #ifdef HAVE_FORK static PyObject * lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args)) @@ -221,243 +221,243 @@ lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args)) #endif /* HAVE_FORK */ -static PyMethodDef lock_methods[] = { +static PyMethodDef lock_methods[] = { {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock, - METH_VARARGS | METH_KEYWORDS, acquire_doc}, + METH_VARARGS | METH_KEYWORDS, acquire_doc}, {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock, - METH_VARARGS | METH_KEYWORDS, acquire_doc}, - {"release_lock", (PyCFunction)lock_PyThread_release_lock, - METH_NOARGS, release_doc}, - {"release", (PyCFunction)lock_PyThread_release_lock, - METH_NOARGS, release_doc}, - {"locked_lock", (PyCFunction)lock_locked_lock, - METH_NOARGS, locked_doc}, - {"locked", (PyCFunction)lock_locked_lock, - METH_NOARGS, locked_doc}, + METH_VARARGS | METH_KEYWORDS, acquire_doc}, + {"release_lock", (PyCFunction)lock_PyThread_release_lock, + METH_NOARGS, release_doc}, + {"release", (PyCFunction)lock_PyThread_release_lock, + METH_NOARGS, release_doc}, + {"locked_lock", (PyCFunction)lock_locked_lock, + METH_NOARGS, locked_doc}, + {"locked", (PyCFunction)lock_locked_lock, + METH_NOARGS, locked_doc}, {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock, - METH_VARARGS | METH_KEYWORDS, acquire_doc}, - {"__exit__", (PyCFunction)lock_PyThread_release_lock, - METH_VARARGS, release_doc}, + METH_VARARGS | METH_KEYWORDS, acquire_doc}, + {"__exit__", (PyCFunction)lock_PyThread_release_lock, + METH_VARARGS, release_doc}, #ifdef HAVE_FORK {"_at_fork_reinit", (PyCFunction)lock__at_fork_reinit, METH_NOARGS, NULL}, #endif - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject Locktype = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_thread.lock", /*tp_name*/ - sizeof(lockobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)lock_dealloc, /*tp_dealloc*/ + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject Locktype = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "_thread.lock", /*tp_name*/ + sizeof(lockobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)lock_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - (reprfunc)lock_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*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - lock_methods, /*tp_methods*/ -}; - -/* Recursive lock objects */ - -typedef struct { - PyObject_HEAD - PyThread_type_lock rlock_lock; - unsigned long rlock_owner; - unsigned long rlock_count; - PyObject *in_weakreflist; -} rlockobject; - -static void -rlock_dealloc(rlockobject *self) -{ - if (self->in_weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed - in rlock_new() */ - if (self->rlock_lock != NULL) { - /* Unlock the lock so it's safe to free it */ - if (self->rlock_count > 0) - PyThread_release_lock(self->rlock_lock); - - PyThread_free_lock(self->rlock_lock); - } - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) -{ - _PyTime_t timeout; - unsigned long tid; - PyLockStatus r = PY_LOCK_ACQUIRED; - - if (lock_acquire_parse_args(args, kwds, &timeout) < 0) - return NULL; - - tid = PyThread_get_thread_ident(); - if (self->rlock_count > 0 && tid == self->rlock_owner) { - unsigned long count = self->rlock_count + 1; - if (count <= self->rlock_count) { - PyErr_SetString(PyExc_OverflowError, - "Internal lock count overflowed"); - return NULL; - } - self->rlock_count = count; - Py_RETURN_TRUE; - } - r = acquire_timed(self->rlock_lock, timeout); - if (r == PY_LOCK_ACQUIRED) { - assert(self->rlock_count == 0); - self->rlock_owner = tid; - self->rlock_count = 1; - } - else if (r == PY_LOCK_INTR) { - return NULL; - } - - return PyBool_FromLong(r == PY_LOCK_ACQUIRED); -} - -PyDoc_STRVAR(rlock_acquire_doc, -"acquire(blocking=True) -> bool\n\ -\n\ -Lock the lock. `blocking` indicates whether we should wait\n\ -for the lock to be available or not. If `blocking` is False\n\ -and another thread holds the lock, the method will return False\n\ -immediately. If `blocking` is True and another thread holds\n\ -the lock, the method will wait for the lock to be released,\n\ -take it and then return True.\n\ -(note: the blocking operation is interruptible.)\n\ -\n\ -In all other cases, the method will return True immediately.\n\ -Precisely, if the current thread already holds the lock, its\n\ -internal counter is simply incremented. If nobody holds the lock,\n\ -the lock is taken and its internal counter initialized to 1."); - -static PyObject * + (reprfunc)lock_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*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + lock_methods, /*tp_methods*/ +}; + +/* Recursive lock objects */ + +typedef struct { + PyObject_HEAD + PyThread_type_lock rlock_lock; + unsigned long rlock_owner; + unsigned long rlock_count; + PyObject *in_weakreflist; +} rlockobject; + +static void +rlock_dealloc(rlockobject *self) +{ + if (self->in_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed + in rlock_new() */ + if (self->rlock_lock != NULL) { + /* Unlock the lock so it's safe to free it */ + if (self->rlock_count > 0) + PyThread_release_lock(self->rlock_lock); + + PyThread_free_lock(self->rlock_lock); + } + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) +{ + _PyTime_t timeout; + unsigned long tid; + PyLockStatus r = PY_LOCK_ACQUIRED; + + if (lock_acquire_parse_args(args, kwds, &timeout) < 0) + return NULL; + + tid = PyThread_get_thread_ident(); + if (self->rlock_count > 0 && tid == self->rlock_owner) { + unsigned long count = self->rlock_count + 1; + if (count <= self->rlock_count) { + PyErr_SetString(PyExc_OverflowError, + "Internal lock count overflowed"); + return NULL; + } + self->rlock_count = count; + Py_RETURN_TRUE; + } + r = acquire_timed(self->rlock_lock, timeout); + if (r == PY_LOCK_ACQUIRED) { + assert(self->rlock_count == 0); + self->rlock_owner = tid; + self->rlock_count = 1; + } + else if (r == PY_LOCK_INTR) { + return NULL; + } + + return PyBool_FromLong(r == PY_LOCK_ACQUIRED); +} + +PyDoc_STRVAR(rlock_acquire_doc, +"acquire(blocking=True) -> bool\n\ +\n\ +Lock the lock. `blocking` indicates whether we should wait\n\ +for the lock to be available or not. If `blocking` is False\n\ +and another thread holds the lock, the method will return False\n\ +immediately. If `blocking` is True and another thread holds\n\ +the lock, the method will wait for the lock to be released,\n\ +take it and then return True.\n\ +(note: the blocking operation is interruptible.)\n\ +\n\ +In all other cases, the method will return True immediately.\n\ +Precisely, if the current thread already holds the lock, its\n\ +internal counter is simply incremented. If nobody holds the lock,\n\ +the lock is taken and its internal counter initialized to 1."); + +static PyObject * rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored)) -{ - unsigned long tid = PyThread_get_thread_ident(); - - if (self->rlock_count == 0 || self->rlock_owner != tid) { - PyErr_SetString(PyExc_RuntimeError, - "cannot release un-acquired lock"); - return NULL; - } - if (--self->rlock_count == 0) { - self->rlock_owner = 0; - PyThread_release_lock(self->rlock_lock); - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(rlock_release_doc, -"release()\n\ -\n\ -Release the lock, allowing another thread that is blocked waiting for\n\ -the lock to acquire the lock. The lock must be in the locked state,\n\ -and must be locked by the same thread that unlocks it; otherwise a\n\ -`RuntimeError` is raised.\n\ -\n\ -Do note that if the lock was acquire()d several times in a row by the\n\ -current thread, release() needs to be called as many times for the lock\n\ -to be available for other threads."); - -static PyObject * -rlock_acquire_restore(rlockobject *self, PyObject *args) -{ - unsigned long owner; - unsigned long count; - int r = 1; - - if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner)) - return NULL; - - if (!PyThread_acquire_lock(self->rlock_lock, 0)) { - Py_BEGIN_ALLOW_THREADS - r = PyThread_acquire_lock(self->rlock_lock, 1); - Py_END_ALLOW_THREADS - } - if (!r) { - PyErr_SetString(ThreadError, "couldn't acquire lock"); - return NULL; - } - assert(self->rlock_count == 0); - self->rlock_owner = owner; - self->rlock_count = count; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(rlock_acquire_restore_doc, -"_acquire_restore(state) -> None\n\ -\n\ -For internal use by `threading.Condition`."); - -static PyObject * +{ + unsigned long tid = PyThread_get_thread_ident(); + + if (self->rlock_count == 0 || self->rlock_owner != tid) { + PyErr_SetString(PyExc_RuntimeError, + "cannot release un-acquired lock"); + return NULL; + } + if (--self->rlock_count == 0) { + self->rlock_owner = 0; + PyThread_release_lock(self->rlock_lock); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(rlock_release_doc, +"release()\n\ +\n\ +Release the lock, allowing another thread that is blocked waiting for\n\ +the lock to acquire the lock. The lock must be in the locked state,\n\ +and must be locked by the same thread that unlocks it; otherwise a\n\ +`RuntimeError` is raised.\n\ +\n\ +Do note that if the lock was acquire()d several times in a row by the\n\ +current thread, release() needs to be called as many times for the lock\n\ +to be available for other threads."); + +static PyObject * +rlock_acquire_restore(rlockobject *self, PyObject *args) +{ + unsigned long owner; + unsigned long count; + int r = 1; + + if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner)) + return NULL; + + if (!PyThread_acquire_lock(self->rlock_lock, 0)) { + Py_BEGIN_ALLOW_THREADS + r = PyThread_acquire_lock(self->rlock_lock, 1); + Py_END_ALLOW_THREADS + } + if (!r) { + PyErr_SetString(ThreadError, "couldn't acquire lock"); + return NULL; + } + assert(self->rlock_count == 0); + self->rlock_owner = owner; + self->rlock_count = count; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(rlock_acquire_restore_doc, +"_acquire_restore(state) -> None\n\ +\n\ +For internal use by `threading.Condition`."); + +static PyObject * rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored)) -{ - unsigned long owner; - unsigned long count; - - if (self->rlock_count == 0) { - PyErr_SetString(PyExc_RuntimeError, - "cannot release un-acquired lock"); - return NULL; - } - - owner = self->rlock_owner; - count = self->rlock_count; - self->rlock_count = 0; - self->rlock_owner = 0; - PyThread_release_lock(self->rlock_lock); - return Py_BuildValue("kk", count, owner); -} - -PyDoc_STRVAR(rlock_release_save_doc, -"_release_save() -> tuple\n\ -\n\ -For internal use by `threading.Condition`."); - - -static PyObject * +{ + unsigned long owner; + unsigned long count; + + if (self->rlock_count == 0) { + PyErr_SetString(PyExc_RuntimeError, + "cannot release un-acquired lock"); + return NULL; + } + + owner = self->rlock_owner; + count = self->rlock_count; + self->rlock_count = 0; + self->rlock_owner = 0; + PyThread_release_lock(self->rlock_lock); + return Py_BuildValue("kk", count, owner); +} + +PyDoc_STRVAR(rlock_release_save_doc, +"_release_save() -> tuple\n\ +\n\ +For internal use by `threading.Condition`."); + + +static PyObject * rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored)) -{ - unsigned long tid = PyThread_get_thread_ident(); - - if (self->rlock_count > 0 && self->rlock_owner == tid) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; -} - -PyDoc_STRVAR(rlock_is_owned_doc, -"_is_owned() -> bool\n\ -\n\ -For internal use by `threading.Condition`."); - -static PyObject * -rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ +{ + unsigned long tid = PyThread_get_thread_ident(); + + if (self->rlock_count > 0 && self->rlock_owner == tid) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +PyDoc_STRVAR(rlock_is_owned_doc, +"_is_owned() -> bool\n\ +\n\ +For internal use by `threading.Condition`."); + +static PyObject * +rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ rlockobject *self = (rlockobject *) type->tp_alloc(type, 0); if (self == NULL) { return NULL; @@ -465,26 +465,26 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->in_weakreflist = NULL; self->rlock_owner = 0; self->rlock_count = 0; - + self->rlock_lock = PyThread_allocate_lock(); if (self->rlock_lock == NULL) { Py_DECREF(self); PyErr_SetString(ThreadError, "can't allocate lock"); return NULL; - } - return (PyObject *) self; -} - -static PyObject * -rlock_repr(rlockobject *self) -{ - return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>", - self->rlock_count ? "locked" : "unlocked", - Py_TYPE(self)->tp_name, self->rlock_owner, - self->rlock_count, self); -} - - + } + return (PyObject *) self; +} + +static PyObject * +rlock_repr(rlockobject *self) +{ + return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>", + self->rlock_count ? "locked" : "unlocked", + Py_TYPE(self)->tp_name, self->rlock_owner, + self->rlock_count, self); +} + + #ifdef HAVE_FORK static PyObject * rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args)) @@ -502,477 +502,477 @@ rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args)) #endif /* HAVE_FORK */ -static PyMethodDef rlock_methods[] = { +static PyMethodDef rlock_methods[] = { {"acquire", (PyCFunction)(void(*)(void))rlock_acquire, - METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, - {"release", (PyCFunction)rlock_release, - METH_NOARGS, rlock_release_doc}, - {"_is_owned", (PyCFunction)rlock_is_owned, - METH_NOARGS, rlock_is_owned_doc}, - {"_acquire_restore", (PyCFunction)rlock_acquire_restore, - METH_VARARGS, rlock_acquire_restore_doc}, - {"_release_save", (PyCFunction)rlock_release_save, - METH_NOARGS, rlock_release_save_doc}, + METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, + {"release", (PyCFunction)rlock_release, + METH_NOARGS, rlock_release_doc}, + {"_is_owned", (PyCFunction)rlock_is_owned, + METH_NOARGS, rlock_is_owned_doc}, + {"_acquire_restore", (PyCFunction)rlock_acquire_restore, + METH_VARARGS, rlock_acquire_restore_doc}, + {"_release_save", (PyCFunction)rlock_release_save, + METH_NOARGS, rlock_release_save_doc}, {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire, - METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, - {"__exit__", (PyCFunction)rlock_release, - METH_VARARGS, rlock_release_doc}, + METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, + {"__exit__", (PyCFunction)rlock_release, + METH_VARARGS, rlock_release_doc}, #ifdef HAVE_FORK {"_at_fork_reinit", (PyCFunction)rlock__at_fork_reinit, METH_NOARGS, NULL}, #endif - {NULL, NULL} /* sentinel */ -}; - - -static PyTypeObject RLocktype = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_thread.RLock", /*tp_name*/ - sizeof(rlockobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)rlock_dealloc, /*tp_dealloc*/ + {NULL, NULL} /* sentinel */ +}; + + +static PyTypeObject RLocktype = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "_thread.RLock", /*tp_name*/ + sizeof(rlockobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)rlock_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - (reprfunc)rlock_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*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - rlock_methods, /*tp_methods*/ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - rlock_new /* tp_new */ -}; - -static lockobject * -newlockobject(void) -{ - lockobject *self; - self = PyObject_New(lockobject, &Locktype); - if (self == NULL) - return NULL; - self->lock_lock = PyThread_allocate_lock(); - self->locked = 0; - self->in_weakreflist = NULL; - if (self->lock_lock == NULL) { - Py_DECREF(self); - PyErr_SetString(ThreadError, "can't allocate lock"); - return NULL; - } - return self; -} - -/* Thread-local objects */ - -/* Quick overview: - - We need to be able to reclaim reference cycles as soon as possible - (both when a thread is being terminated, or a thread-local object - becomes unreachable from user data). Constraints: - - it must not be possible for thread-state dicts to be involved in - reference cycles (otherwise the cyclic GC will refuse to consider - objects referenced from a reachable thread-state dict, even though - local_dealloc would clear them) - - the death of a thread-state dict must still imply destruction of the - corresponding local dicts in all thread-local objects. - - Our implementation uses small "localdummy" objects in order to break - the reference chain. These trivial objects are hashable (using the - default scheme of identity hashing) and weakrefable. - Each thread-state holds a separate localdummy for each local object - (as a /strong reference/), - and each thread-local object holds a dict mapping /weak references/ - of localdummies to local dicts. - - Therefore: - - only the thread-state dict holds a strong reference to the dummies - - only the thread-local object holds a strong reference to the local dicts - - only outside objects (application- or library-level) hold strong - references to the thread-local objects - - as soon as a thread-state dict is destroyed, the weakref callbacks of all - dummies attached to that thread are called, and destroy the corresponding - local dicts from thread-local objects - - as soon as a thread-local object is destroyed, its local dicts are - destroyed and its dummies are manually removed from all thread states - - the GC can do its work correctly when a thread-local object is dangling, - without any interference from the thread-state dicts - - As an additional optimization, each localdummy holds a borrowed reference - to the corresponding localdict. This borrowed reference is only used - by the thread-local object which has created the localdummy, which should - guarantee that the localdict still exists when accessed. -*/ - -typedef struct { - PyObject_HEAD - PyObject *localdict; /* Borrowed reference! */ - PyObject *weakreflist; /* List of weak references to self */ -} localdummyobject; - -static void -localdummy_dealloc(localdummyobject *self) -{ - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -static PyTypeObject localdummytype = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_thread._localdummy", - /* tp_basicsize */ sizeof(localdummyobject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor)localdummy_dealloc, + (reprfunc)rlock_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*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + rlock_methods, /*tp_methods*/ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + rlock_new /* tp_new */ +}; + +static lockobject * +newlockobject(void) +{ + lockobject *self; + self = PyObject_New(lockobject, &Locktype); + if (self == NULL) + return NULL; + self->lock_lock = PyThread_allocate_lock(); + self->locked = 0; + self->in_weakreflist = NULL; + if (self->lock_lock == NULL) { + Py_DECREF(self); + PyErr_SetString(ThreadError, "can't allocate lock"); + return NULL; + } + return self; +} + +/* Thread-local objects */ + +/* Quick overview: + + We need to be able to reclaim reference cycles as soon as possible + (both when a thread is being terminated, or a thread-local object + becomes unreachable from user data). Constraints: + - it must not be possible for thread-state dicts to be involved in + reference cycles (otherwise the cyclic GC will refuse to consider + objects referenced from a reachable thread-state dict, even though + local_dealloc would clear them) + - the death of a thread-state dict must still imply destruction of the + corresponding local dicts in all thread-local objects. + + Our implementation uses small "localdummy" objects in order to break + the reference chain. These trivial objects are hashable (using the + default scheme of identity hashing) and weakrefable. + Each thread-state holds a separate localdummy for each local object + (as a /strong reference/), + and each thread-local object holds a dict mapping /weak references/ + of localdummies to local dicts. + + Therefore: + - only the thread-state dict holds a strong reference to the dummies + - only the thread-local object holds a strong reference to the local dicts + - only outside objects (application- or library-level) hold strong + references to the thread-local objects + - as soon as a thread-state dict is destroyed, the weakref callbacks of all + dummies attached to that thread are called, and destroy the corresponding + local dicts from thread-local objects + - as soon as a thread-local object is destroyed, its local dicts are + destroyed and its dummies are manually removed from all thread states + - the GC can do its work correctly when a thread-local object is dangling, + without any interference from the thread-state dicts + + As an additional optimization, each localdummy holds a borrowed reference + to the corresponding localdict. This borrowed reference is only used + by the thread-local object which has created the localdummy, which should + guarantee that the localdict still exists when accessed. +*/ + +typedef struct { + PyObject_HEAD + PyObject *localdict; /* Borrowed reference! */ + PyObject *weakreflist; /* List of weak references to self */ +} localdummyobject; + +static void +localdummy_dealloc(localdummyobject *self) +{ + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyTypeObject localdummytype = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_thread._localdummy", + /* tp_basicsize */ sizeof(localdummyobject), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)localdummy_dealloc, /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, + /* tp_getattr */ 0, + /* tp_setattr */ 0, /* tp_as_async */ 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 */ Py_TPFLAGS_DEFAULT, - /* tp_doc */ "Thread-local dummy", - /* tp_traverse */ 0, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist) -}; - - -typedef struct { - PyObject_HEAD - PyObject *key; - PyObject *args; - PyObject *kw; - PyObject *weakreflist; /* List of weak references to self */ - /* A {localdummy weakref -> localdict} dict */ - PyObject *dummies; - /* The callback for weakrefs to localdummies */ - PyObject *wr_callback; -} localobject; - -/* Forward declaration */ -static PyObject *_ldict(localobject *self); -static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref); - -/* Create and register the dummy for the current thread. - Returns a borrowed reference of the corresponding local dict */ -static PyObject * -_local_create_dummy(localobject *self) -{ - PyObject *tdict, *ldict = NULL, *wr = NULL; - localdummyobject *dummy = NULL; - int r; - - tdict = PyThreadState_GetDict(); - if (tdict == NULL) { - PyErr_SetString(PyExc_SystemError, - "Couldn't get thread-state dictionary"); - goto err; - } - - ldict = PyDict_New(); - if (ldict == NULL) - goto err; - dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0); - if (dummy == NULL) - goto err; - dummy->localdict = ldict; - wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback); - if (wr == NULL) - goto err; - - /* As a side-effect, this will cache the weakref's hash before the - dummy gets deleted */ - r = PyDict_SetItem(self->dummies, wr, ldict); - if (r < 0) - goto err; - Py_CLEAR(wr); - r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy); - if (r < 0) - goto err; - Py_CLEAR(dummy); - - Py_DECREF(ldict); - return ldict; - -err: - Py_XDECREF(ldict); - Py_XDECREF(wr); - Py_XDECREF(dummy); - return NULL; -} - -static PyObject * -local_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - localobject *self; - PyObject *wr; - static PyMethodDef wr_callback_def = { - "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O - }; - - if (type->tp_init == PyBaseObject_Type.tp_init) { - int rc = 0; - if (args != NULL) - rc = PyObject_IsTrue(args); - if (rc == 0 && kw != NULL) - rc = PyObject_IsTrue(kw); - if (rc != 0) { - if (rc > 0) - PyErr_SetString(PyExc_TypeError, - "Initialization arguments are not supported"); - return NULL; - } - } - - self = (localobject *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - Py_XINCREF(args); - self->args = args; - Py_XINCREF(kw); - self->kw = kw; - self->key = PyUnicode_FromFormat("thread.local.%p", self); - if (self->key == NULL) - goto err; - - self->dummies = PyDict_New(); - if (self->dummies == NULL) - goto err; - - /* We use a weak reference to self in the callback closure - in order to avoid spurious reference cycles */ - wr = PyWeakref_NewRef((PyObject *) self, NULL); - if (wr == NULL) - goto err; - self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL); - Py_DECREF(wr); - if (self->wr_callback == NULL) - goto err; - - if (_local_create_dummy(self) == NULL) - goto err; - - return (PyObject *)self; - - err: - Py_DECREF(self); - return NULL; -} - -static int -local_traverse(localobject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->args); - Py_VISIT(self->kw); - Py_VISIT(self->dummies); - return 0; -} - -static int -local_clear(localobject *self) -{ - PyThreadState *tstate; - Py_CLEAR(self->args); - Py_CLEAR(self->kw); - Py_CLEAR(self->dummies); - Py_CLEAR(self->wr_callback); - /* Remove all strong references to dummies from the thread states */ - if (self->key - && (tstate = PyThreadState_Get()) - && tstate->interp) { - for(tstate = PyInterpreterState_ThreadHead(tstate->interp); - tstate; - tstate = PyThreadState_Next(tstate)) - if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) { - if (PyDict_DelItem(tstate->dict, self->key)) { - PyErr_Clear(); - } - } - } - return 0; -} - -static void -local_dealloc(localobject *self) -{ - /* Weakrefs must be invalidated right now, otherwise they can be used - from code called below, which is very dangerous since Py_REFCNT(self) == 0 */ - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - - PyObject_GC_UnTrack(self); - - local_clear(self); - Py_XDECREF(self->key); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -/* Returns a borrowed reference to the local dict, creating it if necessary */ -static PyObject * -_ldict(localobject *self) -{ - PyObject *tdict, *ldict, *dummy; - - tdict = PyThreadState_GetDict(); - if (tdict == NULL) { - PyErr_SetString(PyExc_SystemError, - "Couldn't get thread-state dictionary"); - return NULL; - } - + /* 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 */ Py_TPFLAGS_DEFAULT, + /* tp_doc */ "Thread-local dummy", + /* tp_traverse */ 0, + /* tp_clear */ 0, + /* tp_richcompare */ 0, + /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist) +}; + + +typedef struct { + PyObject_HEAD + PyObject *key; + PyObject *args; + PyObject *kw; + PyObject *weakreflist; /* List of weak references to self */ + /* A {localdummy weakref -> localdict} dict */ + PyObject *dummies; + /* The callback for weakrefs to localdummies */ + PyObject *wr_callback; +} localobject; + +/* Forward declaration */ +static PyObject *_ldict(localobject *self); +static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref); + +/* Create and register the dummy for the current thread. + Returns a borrowed reference of the corresponding local dict */ +static PyObject * +_local_create_dummy(localobject *self) +{ + PyObject *tdict, *ldict = NULL, *wr = NULL; + localdummyobject *dummy = NULL; + int r; + + tdict = PyThreadState_GetDict(); + if (tdict == NULL) { + PyErr_SetString(PyExc_SystemError, + "Couldn't get thread-state dictionary"); + goto err; + } + + ldict = PyDict_New(); + if (ldict == NULL) + goto err; + dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0); + if (dummy == NULL) + goto err; + dummy->localdict = ldict; + wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback); + if (wr == NULL) + goto err; + + /* As a side-effect, this will cache the weakref's hash before the + dummy gets deleted */ + r = PyDict_SetItem(self->dummies, wr, ldict); + if (r < 0) + goto err; + Py_CLEAR(wr); + r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy); + if (r < 0) + goto err; + Py_CLEAR(dummy); + + Py_DECREF(ldict); + return ldict; + +err: + Py_XDECREF(ldict); + Py_XDECREF(wr); + Py_XDECREF(dummy); + return NULL; +} + +static PyObject * +local_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + localobject *self; + PyObject *wr; + static PyMethodDef wr_callback_def = { + "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O + }; + + if (type->tp_init == PyBaseObject_Type.tp_init) { + int rc = 0; + if (args != NULL) + rc = PyObject_IsTrue(args); + if (rc == 0 && kw != NULL) + rc = PyObject_IsTrue(kw); + if (rc != 0) { + if (rc > 0) + PyErr_SetString(PyExc_TypeError, + "Initialization arguments are not supported"); + return NULL; + } + } + + self = (localobject *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + Py_XINCREF(args); + self->args = args; + Py_XINCREF(kw); + self->kw = kw; + self->key = PyUnicode_FromFormat("thread.local.%p", self); + if (self->key == NULL) + goto err; + + self->dummies = PyDict_New(); + if (self->dummies == NULL) + goto err; + + /* We use a weak reference to self in the callback closure + in order to avoid spurious reference cycles */ + wr = PyWeakref_NewRef((PyObject *) self, NULL); + if (wr == NULL) + goto err; + self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL); + Py_DECREF(wr); + if (self->wr_callback == NULL) + goto err; + + if (_local_create_dummy(self) == NULL) + goto err; + + return (PyObject *)self; + + err: + Py_DECREF(self); + return NULL; +} + +static int +local_traverse(localobject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->args); + Py_VISIT(self->kw); + Py_VISIT(self->dummies); + return 0; +} + +static int +local_clear(localobject *self) +{ + PyThreadState *tstate; + Py_CLEAR(self->args); + Py_CLEAR(self->kw); + Py_CLEAR(self->dummies); + Py_CLEAR(self->wr_callback); + /* Remove all strong references to dummies from the thread states */ + if (self->key + && (tstate = PyThreadState_Get()) + && tstate->interp) { + for(tstate = PyInterpreterState_ThreadHead(tstate->interp); + tstate; + tstate = PyThreadState_Next(tstate)) + if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) { + if (PyDict_DelItem(tstate->dict, self->key)) { + PyErr_Clear(); + } + } + } + return 0; +} + +static void +local_dealloc(localobject *self) +{ + /* Weakrefs must be invalidated right now, otherwise they can be used + from code called below, which is very dangerous since Py_REFCNT(self) == 0 */ + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + + PyObject_GC_UnTrack(self); + + local_clear(self); + Py_XDECREF(self->key); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +/* Returns a borrowed reference to the local dict, creating it if necessary */ +static PyObject * +_ldict(localobject *self) +{ + PyObject *tdict, *ldict, *dummy; + + tdict = PyThreadState_GetDict(); + if (tdict == NULL) { + PyErr_SetString(PyExc_SystemError, + "Couldn't get thread-state dictionary"); + return NULL; + } + dummy = PyDict_GetItemWithError(tdict, self->key); - if (dummy == NULL) { + if (dummy == NULL) { if (PyErr_Occurred()) { return NULL; } - ldict = _local_create_dummy(self); - if (ldict == NULL) - return NULL; - - if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init && - Py_TYPE(self)->tp_init((PyObject*)self, - self->args, self->kw) < 0) { - /* we need to get rid of ldict from thread so - we create a new one the next time we do an attr - access */ - PyDict_DelItem(tdict, self->key); - return NULL; - } - } - else { + ldict = _local_create_dummy(self); + if (ldict == NULL) + return NULL; + + if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init && + Py_TYPE(self)->tp_init((PyObject*)self, + self->args, self->kw) < 0) { + /* we need to get rid of ldict from thread so + we create a new one the next time we do an attr + access */ + PyDict_DelItem(tdict, self->key); + return NULL; + } + } + else { assert(Py_IS_TYPE(dummy, &localdummytype)); - ldict = ((localdummyobject *) dummy)->localdict; - } - - return ldict; -} - -static int -local_setattro(localobject *self, PyObject *name, PyObject *v) -{ - PyObject *ldict; - int r; - - ldict = _ldict(self); - if (ldict == NULL) - return -1; - - r = PyObject_RichCompareBool(name, str_dict, Py_EQ); - if (r == 1) { - PyErr_Format(PyExc_AttributeError, - "'%.50s' object attribute '%U' is read-only", - Py_TYPE(self)->tp_name, name); - return -1; - } - if (r == -1) - return -1; - - return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict); -} - -static PyObject *local_getattro(localobject *, PyObject *); - -static PyTypeObject localtype = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_thread._local", - /* tp_basicsize */ sizeof(localobject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor)local_dealloc, + ldict = ((localdummyobject *) dummy)->localdict; + } + + return ldict; +} + +static int +local_setattro(localobject *self, PyObject *name, PyObject *v) +{ + PyObject *ldict; + int r; + + ldict = _ldict(self); + if (ldict == NULL) + return -1; + + r = PyObject_RichCompareBool(name, str_dict, Py_EQ); + if (r == 1) { + PyErr_Format(PyExc_AttributeError, + "'%.50s' object attribute '%U' is read-only", + Py_TYPE(self)->tp_name, name); + return -1; + } + if (r == -1) + return -1; + + return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict); +} + +static PyObject *local_getattro(localobject *, PyObject *); + +static PyTypeObject localtype = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_thread._local", + /* tp_basicsize */ sizeof(localobject), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor)local_dealloc, /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, + /* tp_getattr */ 0, + /* tp_setattr */ 0, /* tp_as_async */ 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 */ (getattrofunc)local_getattro, - /* tp_setattro */ (setattrofunc)local_setattro, - /* tp_as_buffer */ 0, - /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, - /* tp_doc */ "Thread-local data", - /* tp_traverse */ (traverseproc)local_traverse, - /* tp_clear */ (inquiry)local_clear, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ offsetof(localobject, weakreflist), - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ 0, - /* tp_members */ 0, - /* tp_getset */ 0, - /* tp_base */ 0, - /* tp_dict */ 0, /* internal use */ - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ local_new, - /* tp_free */ 0, /* Low-level free-mem routine */ - /* tp_is_gc */ 0, /* For PyObject_IS_GC */ -}; - -static PyObject * -local_getattro(localobject *self, PyObject *name) -{ - PyObject *ldict, *value; - int r; - - ldict = _ldict(self); - if (ldict == NULL) - return NULL; - - r = PyObject_RichCompareBool(name, str_dict, Py_EQ); - if (r == 1) { - Py_INCREF(ldict); - return ldict; - } - if (r == -1) - return NULL; - + /* 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 */ (getattrofunc)local_getattro, + /* tp_setattro */ (setattrofunc)local_setattro, + /* tp_as_buffer */ 0, + /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_HAVE_GC, + /* tp_doc */ "Thread-local data", + /* tp_traverse */ (traverseproc)local_traverse, + /* tp_clear */ (inquiry)local_clear, + /* tp_richcompare */ 0, + /* tp_weaklistoffset */ offsetof(localobject, weakreflist), + /* tp_iter */ 0, + /* tp_iternext */ 0, + /* tp_methods */ 0, + /* tp_members */ 0, + /* tp_getset */ 0, + /* tp_base */ 0, + /* tp_dict */ 0, /* internal use */ + /* tp_descr_get */ 0, + /* tp_descr_set */ 0, + /* tp_dictoffset */ 0, + /* tp_init */ 0, + /* tp_alloc */ 0, + /* tp_new */ local_new, + /* tp_free */ 0, /* Low-level free-mem routine */ + /* tp_is_gc */ 0, /* For PyObject_IS_GC */ +}; + +static PyObject * +local_getattro(localobject *self, PyObject *name) +{ + PyObject *ldict, *value; + int r; + + ldict = _ldict(self); + if (ldict == NULL) + return NULL; + + r = PyObject_RichCompareBool(name, str_dict, Py_EQ); + if (r == 1) { + Py_INCREF(ldict); + return ldict; + } + if (r == -1) + return NULL; + if (!Py_IS_TYPE(self, &localtype)) - /* use generic lookup for subtypes */ - return _PyObject_GenericGetAttrWithDict( - (PyObject *)self, name, ldict, 0); - - /* Optimization: just look in dict ourselves */ + /* use generic lookup for subtypes */ + return _PyObject_GenericGetAttrWithDict( + (PyObject *)self, name, ldict, 0); + + /* Optimization: just look in dict ourselves */ value = PyDict_GetItemWithError(ldict, name); if (value != NULL) { Py_INCREF(value); @@ -984,110 +984,110 @@ local_getattro(localobject *self, PyObject *name) /* Fall back on generic to get __class__ and __dict__ */ return _PyObject_GenericGetAttrWithDict( (PyObject *)self, name, ldict, 0); -} - -/* Called when a dummy is destroyed. */ -static PyObject * -_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref) -{ - PyObject *obj; - localobject *self; - assert(PyWeakref_CheckRef(localweakref)); - obj = PyWeakref_GET_OBJECT(localweakref); - if (obj == Py_None) - Py_RETURN_NONE; - Py_INCREF(obj); - assert(PyObject_TypeCheck(obj, &localtype)); - /* If the thread-local object is still alive and not being cleared, - remove the corresponding local dict */ - self = (localobject *) obj; - if (self->dummies != NULL) { - PyObject *ldict; +} + +/* Called when a dummy is destroyed. */ +static PyObject * +_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref) +{ + PyObject *obj; + localobject *self; + assert(PyWeakref_CheckRef(localweakref)); + obj = PyWeakref_GET_OBJECT(localweakref); + if (obj == Py_None) + Py_RETURN_NONE; + Py_INCREF(obj); + assert(PyObject_TypeCheck(obj, &localtype)); + /* If the thread-local object is still alive and not being cleared, + remove the corresponding local dict */ + self = (localobject *) obj; + if (self->dummies != NULL) { + PyObject *ldict; ldict = PyDict_GetItemWithError(self->dummies, dummyweakref); - if (ldict != NULL) { - PyDict_DelItem(self->dummies, dummyweakref); - } - if (PyErr_Occurred()) - PyErr_WriteUnraisable(obj); - } - Py_DECREF(obj); - Py_RETURN_NONE; -} - -/* Module functions */ - -struct bootstate { - PyInterpreterState *interp; - PyObject *func; - PyObject *args; - PyObject *keyw; - PyThreadState *tstate; + if (ldict != NULL) { + PyDict_DelItem(self->dummies, dummyweakref); + } + if (PyErr_Occurred()) + PyErr_WriteUnraisable(obj); + } + Py_DECREF(obj); + Py_RETURN_NONE; +} + +/* Module functions */ + +struct bootstate { + PyInterpreterState *interp; + PyObject *func; + PyObject *args; + PyObject *keyw; + PyThreadState *tstate; _PyRuntimeState *runtime; -}; - -static void -t_bootstrap(void *boot_raw) -{ - struct bootstate *boot = (struct bootstate *) boot_raw; - PyThreadState *tstate; - PyObject *res; - - tstate = boot->tstate; - tstate->thread_id = PyThread_get_thread_ident(); +}; + +static void +t_bootstrap(void *boot_raw) +{ + struct bootstate *boot = (struct bootstate *) boot_raw; + PyThreadState *tstate; + PyObject *res; + + tstate = boot->tstate; + tstate->thread_id = PyThread_get_thread_ident(); _PyThreadState_Init(tstate); - PyEval_AcquireThread(tstate); - tstate->interp->num_threads++; - res = PyObject_Call(boot->func, boot->args, boot->keyw); - if (res == NULL) { - if (PyErr_ExceptionMatches(PyExc_SystemExit)) + PyEval_AcquireThread(tstate); + tstate->interp->num_threads++; + res = PyObject_Call(boot->func, boot->args, boot->keyw); + if (res == NULL) { + if (PyErr_ExceptionMatches(PyExc_SystemExit)) /* SystemExit is ignored silently */ - PyErr_Clear(); - else { + PyErr_Clear(); + else { _PyErr_WriteUnraisableMsg("in thread started by", boot->func); - } - } + } + } else { - Py_DECREF(res); + Py_DECREF(res); } - Py_DECREF(boot->func); - Py_DECREF(boot->args); - Py_XDECREF(boot->keyw); - PyMem_DEL(boot_raw); - tstate->interp->num_threads--; - PyThreadState_Clear(tstate); + Py_DECREF(boot->func); + Py_DECREF(boot->args); + Py_XDECREF(boot->keyw); + PyMem_DEL(boot_raw); + tstate->interp->num_threads--; + PyThreadState_Clear(tstate); _PyThreadState_DeleteCurrent(tstate); // bpo-44434: Don't call explicitly PyThread_exit_thread(). On Linux with // the glibc, pthread_exit() can abort the whole process if dlopen() fails // to open the libgcc_s.so library (ex: EMFILE error). -} - -static PyObject * -thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) -{ +} + +static PyObject * +thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) +{ _PyRuntimeState *runtime = &_PyRuntime; - PyObject *func, *args, *keyw = NULL; - struct bootstate *boot; - unsigned long ident; - - if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, - &func, &args, &keyw)) - return NULL; - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_TypeError, - "first arg must be callable"); - return NULL; - } - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "2nd arg must be a tuple"); - return NULL; - } - if (keyw != NULL && !PyDict_Check(keyw)) { - PyErr_SetString(PyExc_TypeError, - "optional 3rd arg must be a dictionary"); - return NULL; - } + PyObject *func, *args, *keyw = NULL; + struct bootstate *boot; + unsigned long ident; + + if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, + &func, &args, &keyw)) + return NULL; + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "first arg must be callable"); + return NULL; + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, + "2nd arg must be a tuple"); + return NULL; + } + if (keyw != NULL && !PyDict_Check(keyw)) { + PyErr_SetString(PyExc_TypeError, + "optional 3rd arg must be a dictionary"); + return NULL; + } PyInterpreterState *interp = _PyInterpreterState_GET(); if (interp->config._isolated_interpreter) { @@ -1096,120 +1096,120 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) return NULL; } - boot = PyMem_NEW(struct bootstate, 1); - if (boot == NULL) - return PyErr_NoMemory(); + boot = PyMem_NEW(struct bootstate, 1); + if (boot == NULL) + return PyErr_NoMemory(); boot->interp = _PyInterpreterState_GET(); - boot->func = func; - boot->args = args; - boot->keyw = keyw; - boot->tstate = _PyThreadState_Prealloc(boot->interp); + boot->func = func; + boot->args = args; + boot->keyw = keyw; + boot->tstate = _PyThreadState_Prealloc(boot->interp); boot->runtime = runtime; - if (boot->tstate == NULL) { - PyMem_DEL(boot); - return PyErr_NoMemory(); - } - Py_INCREF(func); - Py_INCREF(args); - Py_XINCREF(keyw); - - ident = PyThread_start_new_thread(t_bootstrap, (void*) boot); - if (ident == PYTHREAD_INVALID_THREAD_ID) { - PyErr_SetString(ThreadError, "can't start new thread"); - Py_DECREF(func); - Py_DECREF(args); - Py_XDECREF(keyw); - PyThreadState_Clear(boot->tstate); - PyMem_DEL(boot); - return NULL; - } - return PyLong_FromUnsignedLong(ident); -} - -PyDoc_STRVAR(start_new_doc, -"start_new_thread(function, args[, kwargs])\n\ -(start_new() is an obsolete synonym)\n\ -\n\ -Start a new thread and return its identifier. The thread will call the\n\ -function with positional arguments from the tuple args and keyword arguments\n\ -taken from the optional dictionary kwargs. The thread exits when the\n\ -function returns; the return value is ignored. The thread will also exit\n\ -when the function raises an unhandled exception; a stack trace will be\n\ -printed unless the exception is SystemExit.\n"); - -static PyObject * + if (boot->tstate == NULL) { + PyMem_DEL(boot); + return PyErr_NoMemory(); + } + Py_INCREF(func); + Py_INCREF(args); + Py_XINCREF(keyw); + + ident = PyThread_start_new_thread(t_bootstrap, (void*) boot); + if (ident == PYTHREAD_INVALID_THREAD_ID) { + PyErr_SetString(ThreadError, "can't start new thread"); + Py_DECREF(func); + Py_DECREF(args); + Py_XDECREF(keyw); + PyThreadState_Clear(boot->tstate); + PyMem_DEL(boot); + return NULL; + } + return PyLong_FromUnsignedLong(ident); +} + +PyDoc_STRVAR(start_new_doc, +"start_new_thread(function, args[, kwargs])\n\ +(start_new() is an obsolete synonym)\n\ +\n\ +Start a new thread and return its identifier. The thread will call the\n\ +function with positional arguments from the tuple args and keyword arguments\n\ +taken from the optional dictionary kwargs. The thread exits when the\n\ +function returns; the return value is ignored. The thread will also exit\n\ +when the function raises an unhandled exception; a stack trace will be\n\ +printed unless the exception is SystemExit.\n"); + +static PyObject * thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyErr_SetNone(PyExc_SystemExit); - return NULL; -} - -PyDoc_STRVAR(exit_doc, -"exit()\n\ -(exit_thread() is an obsolete synonym)\n\ -\n\ -This is synonymous to ``raise SystemExit''. It will cause the current\n\ -thread to exit silently unless the exception is caught."); - -static PyObject * +{ + PyErr_SetNone(PyExc_SystemExit); + return NULL; +} + +PyDoc_STRVAR(exit_doc, +"exit()\n\ +(exit_thread() is an obsolete synonym)\n\ +\n\ +This is synonymous to ``raise SystemExit''. It will cause the current\n\ +thread to exit silently unless the exception is caught."); + +static PyObject * thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored)) -{ - PyErr_SetInterrupt(); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(interrupt_doc, -"interrupt_main()\n\ -\n\ -Raise a KeyboardInterrupt in the main thread.\n\ -A subthread can use this function to interrupt the main thread." -); - -static lockobject *newlockobject(void); - -static PyObject * +{ + PyErr_SetInterrupt(); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(interrupt_doc, +"interrupt_main()\n\ +\n\ +Raise a KeyboardInterrupt in the main thread.\n\ +A subthread can use this function to interrupt the main thread." +); + +static lockobject *newlockobject(void); + +static PyObject * thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return (PyObject *) newlockobject(); -} - -PyDoc_STRVAR(allocate_doc, -"allocate_lock() -> lock object\n\ -(allocate() is an obsolete synonym)\n\ -\n\ -Create a new lock object. See help(type(threading.Lock())) for\n\ -information about locks."); - -static PyObject * +{ + return (PyObject *) newlockobject(); +} + +PyDoc_STRVAR(allocate_doc, +"allocate_lock() -> lock object\n\ +(allocate() is an obsolete synonym)\n\ +\n\ +Create a new lock object. See help(type(threading.Lock())) for\n\ +information about locks."); + +static PyObject * thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - unsigned long ident = PyThread_get_thread_ident(); - if (ident == PYTHREAD_INVALID_THREAD_ID) { - PyErr_SetString(ThreadError, "no current thread ident"); - return NULL; - } - return PyLong_FromUnsignedLong(ident); -} - -PyDoc_STRVAR(get_ident_doc, -"get_ident() -> integer\n\ -\n\ -Return a non-zero integer that uniquely identifies the current thread\n\ -amongst other threads that exist simultaneously.\n\ -This may be used to identify per-thread resources.\n\ -Even though on some platforms threads identities may appear to be\n\ -allocated consecutive numbers starting at 1, this behavior should not\n\ -be relied upon, and the number should be seen purely as a magic cookie.\n\ -A thread's identity may be reused for another thread after it exits."); - +{ + unsigned long ident = PyThread_get_thread_ident(); + if (ident == PYTHREAD_INVALID_THREAD_ID) { + PyErr_SetString(ThreadError, "no current thread ident"); + return NULL; + } + return PyLong_FromUnsignedLong(ident); +} + +PyDoc_STRVAR(get_ident_doc, +"get_ident() -> integer\n\ +\n\ +Return a non-zero integer that uniquely identifies the current thread\n\ +amongst other threads that exist simultaneously.\n\ +This may be used to identify per-thread resources.\n\ +Even though on some platforms threads identities may appear to be\n\ +allocated consecutive numbers starting at 1, this behavior should not\n\ +be relied upon, and the number should be seen purely as a magic cookie.\n\ +A thread's identity may be reused for another thread after it exits."); + #ifdef PY_HAVE_THREAD_NATIVE_ID -static PyObject * +static PyObject * thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ +{ unsigned long native_id = PyThread_get_thread_native_id(); return PyLong_FromUnsignedLong(native_id); -} - +} + PyDoc_STRVAR(get_native_id_doc, "get_native_id() -> integer\n\ \n\ @@ -1225,133 +1225,133 @@ thread__count(PyObject *self, PyObject *Py_UNUSED(ignored)) return PyLong_FromLong(interp->num_threads); } -PyDoc_STRVAR(_count_doc, -"_count() -> integer\n\ -\n\ -\ +PyDoc_STRVAR(_count_doc, +"_count() -> integer\n\ +\n\ +\ Return the number of currently running Python threads, excluding\n\ -the main thread. The returned number comprises all threads created\n\ -through `start_new_thread()` as well as `threading.Thread`, and not\n\ -yet finished.\n\ -\n\ -This function is meant for internal and specialized purposes only.\n\ -In most applications `threading.enumerate()` should be used instead."); - -static void +the main thread. The returned number comprises all threads created\n\ +through `start_new_thread()` as well as `threading.Thread`, and not\n\ +yet finished.\n\ +\n\ +This function is meant for internal and specialized purposes only.\n\ +In most applications `threading.enumerate()` should be used instead."); + +static void release_sentinel(void *wr_raw) -{ +{ PyObject *wr = _PyObject_CAST(wr_raw); - /* Tricky: this function is called when the current thread state - is being deleted. Therefore, only simple C code can safely - execute here. */ - PyObject *obj = PyWeakref_GET_OBJECT(wr); - lockobject *lock; - if (obj != Py_None) { + /* Tricky: this function is called when the current thread state + is being deleted. Therefore, only simple C code can safely + execute here. */ + PyObject *obj = PyWeakref_GET_OBJECT(wr); + lockobject *lock; + if (obj != Py_None) { assert(Py_IS_TYPE(obj, &Locktype)); - lock = (lockobject *) obj; - if (lock->locked) { - PyThread_release_lock(lock->lock_lock); - lock->locked = 0; - } - } - /* Deallocating a weakref with a NULL callback only calls - PyObject_GC_Del(), which can't call any Python code. */ - Py_DECREF(wr); -} - -static PyObject * + lock = (lockobject *) obj; + if (lock->locked) { + PyThread_release_lock(lock->lock_lock); + lock->locked = 0; + } + } + /* Deallocating a weakref with a NULL callback only calls + PyObject_GC_Del(), which can't call any Python code. */ + Py_DECREF(wr); +} + +static PyObject * thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *wr; - PyThreadState *tstate = PyThreadState_Get(); - lockobject *lock; - - if (tstate->on_delete_data != NULL) { - /* We must support the re-creation of the lock from a - fork()ed child. */ - assert(tstate->on_delete == &release_sentinel); - wr = (PyObject *) tstate->on_delete_data; - tstate->on_delete = NULL; - tstate->on_delete_data = NULL; - Py_DECREF(wr); - } - lock = newlockobject(); - if (lock == NULL) - return NULL; - /* The lock is owned by whoever called _set_sentinel(), but the weakref - hangs to the thread state. */ - wr = PyWeakref_NewRef((PyObject *) lock, NULL); - if (wr == NULL) { - Py_DECREF(lock); - return NULL; - } - tstate->on_delete_data = (void *) wr; - tstate->on_delete = &release_sentinel; - return (PyObject *) lock; -} - -PyDoc_STRVAR(_set_sentinel_doc, -"_set_sentinel() -> lock\n\ -\n\ -Set a sentinel lock that will be released when the current thread\n\ -state is finalized (after it is untied from the interpreter).\n\ -\n\ -This is a private API for the threading module."); - -static PyObject * -thread_stack_size(PyObject *self, PyObject *args) -{ - size_t old_size; - Py_ssize_t new_size = 0; - int rc; - - if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size)) - return NULL; - - if (new_size < 0) { - PyErr_SetString(PyExc_ValueError, - "size must be 0 or a positive value"); - return NULL; - } - - old_size = PyThread_get_stacksize(); - - rc = PyThread_set_stacksize((size_t) new_size); - if (rc == -1) { - PyErr_Format(PyExc_ValueError, - "size not valid: %zd bytes", - new_size); - return NULL; - } - if (rc == -2) { - PyErr_SetString(ThreadError, - "setting stack size not supported"); - return NULL; - } - - return PyLong_FromSsize_t((Py_ssize_t) old_size); -} - -PyDoc_STRVAR(stack_size_doc, -"stack_size([size]) -> size\n\ -\n\ -Return the thread stack size used when creating new threads. The\n\ -optional size argument specifies the stack size (in bytes) to be used\n\ -for subsequently created threads, and must be 0 (use platform or\n\ -configured default) or a positive integer value of at least 32,768 (32k).\n\ -If changing the thread stack size is unsupported, a ThreadError\n\ -exception is raised. If the specified size is invalid, a ValueError\n\ -exception is raised, and the stack size is unmodified. 32k bytes\n\ - currently the minimum supported stack size value to guarantee\n\ -sufficient stack space for the interpreter itself.\n\ -\n\ -Note that some platforms may have particular restrictions on values for\n\ -the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\ -requiring allocation in multiples of the system memory page size\n\ -- platform documentation should be referred to for more information\n\ -(4 KiB pages are common; using multiples of 4096 for the stack size is\n\ -the suggested approach in the absence of more specific information)."); - +{ + PyObject *wr; + PyThreadState *tstate = PyThreadState_Get(); + lockobject *lock; + + if (tstate->on_delete_data != NULL) { + /* We must support the re-creation of the lock from a + fork()ed child. */ + assert(tstate->on_delete == &release_sentinel); + wr = (PyObject *) tstate->on_delete_data; + tstate->on_delete = NULL; + tstate->on_delete_data = NULL; + Py_DECREF(wr); + } + lock = newlockobject(); + if (lock == NULL) + return NULL; + /* The lock is owned by whoever called _set_sentinel(), but the weakref + hangs to the thread state. */ + wr = PyWeakref_NewRef((PyObject *) lock, NULL); + if (wr == NULL) { + Py_DECREF(lock); + return NULL; + } + tstate->on_delete_data = (void *) wr; + tstate->on_delete = &release_sentinel; + return (PyObject *) lock; +} + +PyDoc_STRVAR(_set_sentinel_doc, +"_set_sentinel() -> lock\n\ +\n\ +Set a sentinel lock that will be released when the current thread\n\ +state is finalized (after it is untied from the interpreter).\n\ +\n\ +This is a private API for the threading module."); + +static PyObject * +thread_stack_size(PyObject *self, PyObject *args) +{ + size_t old_size; + Py_ssize_t new_size = 0; + int rc; + + if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size)) + return NULL; + + if (new_size < 0) { + PyErr_SetString(PyExc_ValueError, + "size must be 0 or a positive value"); + return NULL; + } + + old_size = PyThread_get_stacksize(); + + rc = PyThread_set_stacksize((size_t) new_size); + if (rc == -1) { + PyErr_Format(PyExc_ValueError, + "size not valid: %zd bytes", + new_size); + return NULL; + } + if (rc == -2) { + PyErr_SetString(ThreadError, + "setting stack size not supported"); + return NULL; + } + + return PyLong_FromSsize_t((Py_ssize_t) old_size); +} + +PyDoc_STRVAR(stack_size_doc, +"stack_size([size]) -> size\n\ +\n\ +Return the thread stack size used when creating new threads. The\n\ +optional size argument specifies the stack size (in bytes) to be used\n\ +for subsequently created threads, and must be 0 (use platform or\n\ +configured default) or a positive integer value of at least 32,768 (32k).\n\ +If changing the thread stack size is unsupported, a ThreadError\n\ +exception is raised. If the specified size is invalid, a ValueError\n\ +exception is raised, and the stack size is unmodified. 32k bytes\n\ + currently the minimum supported stack size value to guarantee\n\ +sufficient stack space for the interpreter itself.\n\ +\n\ +Note that some platforms may have particular restrictions on values for\n\ +the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\ +requiring allocation in multiples of the system memory page size\n\ +- platform documentation should be referred to for more information\n\ +(4 KiB pages are common; using multiples of 4096 for the stack size is\n\ +the suggested approach in the absence of more specific information)."); + static int thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, PyObject *exc_traceback, PyObject *thread) @@ -1494,141 +1494,141 @@ PyDoc_STRVAR(excepthook_doc, \n\ Handle uncaught Thread.run() exception."); -static PyMethodDef thread_methods[] = { - {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread, - METH_VARARGS, start_new_doc}, - {"start_new", (PyCFunction)thread_PyThread_start_new_thread, - METH_VARARGS, start_new_doc}, +static PyMethodDef thread_methods[] = { + {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread, + METH_VARARGS, start_new_doc}, + {"start_new", (PyCFunction)thread_PyThread_start_new_thread, + METH_VARARGS, start_new_doc}, {"allocate_lock", thread_PyThread_allocate_lock, - METH_NOARGS, allocate_doc}, + METH_NOARGS, allocate_doc}, {"allocate", thread_PyThread_allocate_lock, - METH_NOARGS, allocate_doc}, + METH_NOARGS, allocate_doc}, {"exit_thread", thread_PyThread_exit_thread, - METH_NOARGS, exit_doc}, + METH_NOARGS, exit_doc}, {"exit", thread_PyThread_exit_thread, - METH_NOARGS, exit_doc}, + METH_NOARGS, exit_doc}, {"interrupt_main", thread_PyThread_interrupt_main, - METH_NOARGS, interrupt_doc}, + METH_NOARGS, interrupt_doc}, {"get_ident", thread_get_ident, - METH_NOARGS, get_ident_doc}, + METH_NOARGS, get_ident_doc}, #ifdef PY_HAVE_THREAD_NATIVE_ID {"get_native_id", thread_get_native_id, METH_NOARGS, get_native_id_doc}, #endif {"_count", thread__count, - METH_NOARGS, _count_doc}, - {"stack_size", (PyCFunction)thread_stack_size, - METH_VARARGS, stack_size_doc}, + METH_NOARGS, _count_doc}, + {"stack_size", (PyCFunction)thread_stack_size, + METH_VARARGS, stack_size_doc}, {"_set_sentinel", thread__set_sentinel, - METH_NOARGS, _set_sentinel_doc}, + METH_NOARGS, _set_sentinel_doc}, {"_excepthook", thread_excepthook, METH_O, excepthook_doc}, - {NULL, NULL} /* sentinel */ -}; - - -/* Initialization function */ - -PyDoc_STRVAR(thread_doc, -"This module provides primitive operations to write multi-threaded programs.\n\ -The 'threading' module provides a more convenient interface."); - -PyDoc_STRVAR(lock_doc, -"A lock object is a synchronization primitive. To create a lock,\n\ -call threading.Lock(). Methods are:\n\ -\n\ -acquire() -- lock the lock, possibly blocking until it can be obtained\n\ -release() -- unlock of the lock\n\ -locked() -- test whether the lock is currently locked\n\ -\n\ -A lock is not owned by the thread that locked it; another thread may\n\ -unlock it. A thread attempting to lock a lock that it has already locked\n\ -will block until another thread unlocks it. Deadlocks may ensue."); - -static struct PyModuleDef threadmodule = { - PyModuleDef_HEAD_INIT, - "_thread", - thread_doc, - -1, - thread_methods, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit__thread(void) -{ - PyObject *m, *d, *v; - double time_max; - double timeout_max; + {NULL, NULL} /* sentinel */ +}; + + +/* Initialization function */ + +PyDoc_STRVAR(thread_doc, +"This module provides primitive operations to write multi-threaded programs.\n\ +The 'threading' module provides a more convenient interface."); + +PyDoc_STRVAR(lock_doc, +"A lock object is a synchronization primitive. To create a lock,\n\ +call threading.Lock(). Methods are:\n\ +\n\ +acquire() -- lock the lock, possibly blocking until it can be obtained\n\ +release() -- unlock of the lock\n\ +locked() -- test whether the lock is currently locked\n\ +\n\ +A lock is not owned by the thread that locked it; another thread may\n\ +unlock it. A thread attempting to lock a lock that it has already locked\n\ +will block until another thread unlocks it. Deadlocks may ensue."); + +static struct PyModuleDef threadmodule = { + PyModuleDef_HEAD_INIT, + "_thread", + thread_doc, + -1, + thread_methods, + NULL, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit__thread(void) +{ + PyObject *m, *d, *v; + double time_max; + double timeout_max; PyInterpreterState *interp = _PyInterpreterState_GET(); - - /* Initialize types: */ - if (PyType_Ready(&localdummytype) < 0) - return NULL; - if (PyType_Ready(&localtype) < 0) - return NULL; - if (PyType_Ready(&Locktype) < 0) - return NULL; - if (PyType_Ready(&RLocktype) < 0) - return NULL; + + /* Initialize types: */ + if (PyType_Ready(&localdummytype) < 0) + return NULL; + if (PyType_Ready(&localtype) < 0) + return NULL; + if (PyType_Ready(&Locktype) < 0) + return NULL; + if (PyType_Ready(&RLocktype) < 0) + return NULL; if (ExceptHookArgsType.tp_name == NULL) { if (PyStructSequence_InitType2(&ExceptHookArgsType, &ExceptHookArgs_desc) < 0) { return NULL; } } - - /* Create the module and add the functions */ - m = PyModule_Create(&threadmodule); - if (m == NULL) - return NULL; - - timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6; - time_max = _PyTime_AsSecondsDouble(_PyTime_MAX); - timeout_max = Py_MIN(timeout_max, time_max); - /* Round towards minus infinity */ - timeout_max = floor(timeout_max); - - v = PyFloat_FromDouble(timeout_max); - if (!v) - return NULL; - if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0) - return NULL; - - /* Add a symbolic constant */ - d = PyModule_GetDict(m); - ThreadError = PyExc_RuntimeError; - Py_INCREF(ThreadError); - - PyDict_SetItemString(d, "error", ThreadError); - Locktype.tp_doc = lock_doc; - Py_INCREF(&Locktype); - PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype); - - Py_INCREF(&RLocktype); - if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0) - return NULL; - - Py_INCREF(&localtype); - if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0) - return NULL; - + + /* Create the module and add the functions */ + m = PyModule_Create(&threadmodule); + if (m == NULL) + return NULL; + + timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6; + time_max = _PyTime_AsSecondsDouble(_PyTime_MAX); + timeout_max = Py_MIN(timeout_max, time_max); + /* Round towards minus infinity */ + timeout_max = floor(timeout_max); + + v = PyFloat_FromDouble(timeout_max); + if (!v) + return NULL; + if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0) + return NULL; + + /* Add a symbolic constant */ + d = PyModule_GetDict(m); + ThreadError = PyExc_RuntimeError; + Py_INCREF(ThreadError); + + PyDict_SetItemString(d, "error", ThreadError); + Locktype.tp_doc = lock_doc; + Py_INCREF(&Locktype); + PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype); + + Py_INCREF(&RLocktype); + if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0) + return NULL; + + Py_INCREF(&localtype); + if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0) + return NULL; + Py_INCREF(&ExceptHookArgsType); if (PyModule_AddObject(m, "_ExceptHookArgs", (PyObject *)&ExceptHookArgsType) < 0) return NULL; - + interp->num_threads = 0; - str_dict = PyUnicode_InternFromString("__dict__"); - if (str_dict == NULL) - return NULL; - - /* Initialize the C thread library */ - PyThread_init_thread(); - return m; -} + str_dict = PyUnicode_InternFromString("__dict__"); + if (str_dict == NULL) + return NULL; + + /* Initialize the C thread library */ + PyThread_init_thread(); + return m; +} diff --git a/contrib/tools/python3/src/Modules/_tracemalloc.c b/contrib/tools/python3/src/Modules/_tracemalloc.c index 4c8f3c4cd83..0078f0fde90 100644 --- a/contrib/tools/python3/src/Modules/_tracemalloc.c +++ b/contrib/tools/python3/src/Modules/_tracemalloc.c @@ -1,221 +1,221 @@ -#include "Python.h" +#include "Python.h" #include "pycore_gc.h" // PyGC_Head #include "pycore_pymem.h" // _Py_tracemalloc_config #include "pycore_traceback.h" #include "pycore_hashtable.h" #include "frameobject.h" // PyFrame_GetBack() - -#include "clinic/_tracemalloc.c.h" -/*[clinic input] -module _tracemalloc -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/ - -/* Trace memory blocks allocated by PyMem_RawMalloc() */ -#define TRACE_RAW_MALLOC - -/* Forward declaration */ -static void tracemalloc_stop(void); -static void* raw_malloc(size_t size); -static void raw_free(void *ptr); - -#ifdef Py_DEBUG -# define TRACE_DEBUG -#endif - + +#include "clinic/_tracemalloc.c.h" +/*[clinic input] +module _tracemalloc +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/ + +/* Trace memory blocks allocated by PyMem_RawMalloc() */ +#define TRACE_RAW_MALLOC + +/* Forward declaration */ +static void tracemalloc_stop(void); +static void* raw_malloc(size_t size); +static void raw_free(void *ptr); + +#ifdef Py_DEBUG +# define TRACE_DEBUG +#endif + #define TO_PTR(key) ((const void *)(uintptr_t)(key)) #define FROM_PTR(key) ((uintptr_t)(key)) -/* Protected by the GIL */ -static struct { - PyMemAllocatorEx mem; - PyMemAllocatorEx raw; - PyMemAllocatorEx obj; -} allocators; - - -#if defined(TRACE_RAW_MALLOC) -/* This lock is needed because tracemalloc_free() is called without - the GIL held from PyMem_RawFree(). It cannot acquire the lock because it +/* Protected by the GIL */ +static struct { + PyMemAllocatorEx mem; + PyMemAllocatorEx raw; + PyMemAllocatorEx obj; +} allocators; + + +#if defined(TRACE_RAW_MALLOC) +/* This lock is needed because tracemalloc_free() is called without + the GIL held from PyMem_RawFree(). It cannot acquire the lock because it would introduce a deadlock in _PyThreadState_DeleteCurrent(). */ -static PyThread_type_lock tables_lock; -# define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1) -# define TABLES_UNLOCK() PyThread_release_lock(tables_lock) -#else - /* variables are protected by the GIL */ -# define TABLES_LOCK() -# define TABLES_UNLOCK() -#endif - - -#define DEFAULT_DOMAIN 0 - -/* Pack the frame_t structure to reduce the memory footprint on 64-bit - architectures: 12 bytes instead of 16. */ -typedef struct +static PyThread_type_lock tables_lock; +# define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1) +# define TABLES_UNLOCK() PyThread_release_lock(tables_lock) +#else + /* variables are protected by the GIL */ +# define TABLES_LOCK() +# define TABLES_UNLOCK() +#endif + + +#define DEFAULT_DOMAIN 0 + +/* Pack the frame_t structure to reduce the memory footprint on 64-bit + architectures: 12 bytes instead of 16. */ +typedef struct #if defined(__GNUC__) || defined(__clang__) -__attribute__((packed)) -#elif defined(_MSC_VER) -#pragma pack(push, 4) -#endif -{ - /* filename cannot be NULL: "" is used if the Python frame - filename is NULL */ - PyObject *filename; - unsigned int lineno; -} frame_t; +__attribute__((packed)) +#elif defined(_MSC_VER) +#pragma pack(push, 4) +#endif +{ + /* filename cannot be NULL: "" is used if the Python frame + filename is NULL */ + PyObject *filename; + unsigned int lineno; +} frame_t; #if defined(_MSC_VER) && !defined(__clang__) -#pragma pack(pop) -#endif - - -typedef struct { - Py_uhash_t hash; +#pragma pack(pop) +#endif + + +typedef struct { + Py_uhash_t hash; /* Number of frames stored */ uint16_t nframe; /* Total number of frames the traceback had */ uint16_t total_nframe; - frame_t frames[1]; -} traceback_t; - -#define TRACEBACK_SIZE(NFRAME) \ - (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1)) - + frame_t frames[1]; +} traceback_t; + +#define TRACEBACK_SIZE(NFRAME) \ + (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1)) + /* The maximum number of frames is either: - The maximum number of frames we can store in `traceback_t.nframe` - The maximum memory size_t we can allocate */ static const unsigned long MAX_NFRAME = Py_MIN(UINT16_MAX, ((SIZE_MAX - sizeof(traceback_t)) / sizeof(frame_t) + 1)); - - -static PyObject *unknown_filename = NULL; -static traceback_t tracemalloc_empty_traceback; - -/* Trace of a memory block */ -typedef struct { - /* Size of the memory block in bytes */ - size_t size; - - /* Traceback where the memory block was allocated */ - traceback_t *traceback; -} trace_t; - - -/* Size in bytes of currently traced memory. - Protected by TABLES_LOCK(). */ -static size_t tracemalloc_traced_memory = 0; - -/* Peak size in bytes of traced memory. - Protected by TABLES_LOCK(). */ -static size_t tracemalloc_peak_traced_memory = 0; - -/* Hash table used as a set to intern filenames: - PyObject* => PyObject*. - Protected by the GIL */ -static _Py_hashtable_t *tracemalloc_filenames = NULL; - -/* Buffer to store a new traceback in traceback_new(). - Protected by the GIL. */ -static traceback_t *tracemalloc_traceback = NULL; - -/* Hash table used as a set to intern tracebacks: - traceback_t* => traceback_t* - Protected by the GIL */ -static _Py_hashtable_t *tracemalloc_tracebacks = NULL; - + + +static PyObject *unknown_filename = NULL; +static traceback_t tracemalloc_empty_traceback; + +/* Trace of a memory block */ +typedef struct { + /* Size of the memory block in bytes */ + size_t size; + + /* Traceback where the memory block was allocated */ + traceback_t *traceback; +} trace_t; + + +/* Size in bytes of currently traced memory. + Protected by TABLES_LOCK(). */ +static size_t tracemalloc_traced_memory = 0; + +/* Peak size in bytes of traced memory. + Protected by TABLES_LOCK(). */ +static size_t tracemalloc_peak_traced_memory = 0; + +/* Hash table used as a set to intern filenames: + PyObject* => PyObject*. + Protected by the GIL */ +static _Py_hashtable_t *tracemalloc_filenames = NULL; + +/* Buffer to store a new traceback in traceback_new(). + Protected by the GIL. */ +static traceback_t *tracemalloc_traceback = NULL; + +/* Hash table used as a set to intern tracebacks: + traceback_t* => traceback_t* + Protected by the GIL */ +static _Py_hashtable_t *tracemalloc_tracebacks = NULL; + /* pointer (void*) => trace (trace_t*). - Protected by TABLES_LOCK(). */ -static _Py_hashtable_t *tracemalloc_traces = NULL; - + Protected by TABLES_LOCK(). */ +static _Py_hashtable_t *tracemalloc_traces = NULL; + /* domain (unsigned int) => traces (_Py_hashtable_t). Protected by TABLES_LOCK(). */ static _Py_hashtable_t *tracemalloc_domains = NULL; - - -#ifdef TRACE_DEBUG -static void -tracemalloc_error(const char *format, ...) -{ - va_list ap; - fprintf(stderr, "tracemalloc: "); - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - fprintf(stderr, "\n"); - fflush(stderr); -} -#endif - - -#if defined(TRACE_RAW_MALLOC) -#define REENTRANT_THREADLOCAL - -static Py_tss_t tracemalloc_reentrant_key = Py_tss_NEEDS_INIT; - -/* Any non-NULL pointer can be used */ -#define REENTRANT Py_True - -static int -get_reentrant(void) -{ - void *ptr; - - assert(PyThread_tss_is_created(&tracemalloc_reentrant_key)); - ptr = PyThread_tss_get(&tracemalloc_reentrant_key); - if (ptr != NULL) { - assert(ptr == REENTRANT); - return 1; - } - else - return 0; -} - -static void -set_reentrant(int reentrant) -{ - assert(reentrant == 0 || reentrant == 1); - assert(PyThread_tss_is_created(&tracemalloc_reentrant_key)); - - if (reentrant) { - assert(!get_reentrant()); - PyThread_tss_set(&tracemalloc_reentrant_key, REENTRANT); - } - else { - assert(get_reentrant()); - PyThread_tss_set(&tracemalloc_reentrant_key, NULL); - } -} - -#else - -/* TRACE_RAW_MALLOC not defined: variable protected by the GIL */ -static int tracemalloc_reentrant = 0; - -static int -get_reentrant(void) -{ - return tracemalloc_reentrant; -} - -static void -set_reentrant(int reentrant) -{ - assert(reentrant != tracemalloc_reentrant); - tracemalloc_reentrant = reentrant; -} -#endif - - -static Py_uhash_t + + +#ifdef TRACE_DEBUG +static void +tracemalloc_error(const char *format, ...) +{ + va_list ap; + fprintf(stderr, "tracemalloc: "); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fprintf(stderr, "\n"); + fflush(stderr); +} +#endif + + +#if defined(TRACE_RAW_MALLOC) +#define REENTRANT_THREADLOCAL + +static Py_tss_t tracemalloc_reentrant_key = Py_tss_NEEDS_INIT; + +/* Any non-NULL pointer can be used */ +#define REENTRANT Py_True + +static int +get_reentrant(void) +{ + void *ptr; + + assert(PyThread_tss_is_created(&tracemalloc_reentrant_key)); + ptr = PyThread_tss_get(&tracemalloc_reentrant_key); + if (ptr != NULL) { + assert(ptr == REENTRANT); + return 1; + } + else + return 0; +} + +static void +set_reentrant(int reentrant) +{ + assert(reentrant == 0 || reentrant == 1); + assert(PyThread_tss_is_created(&tracemalloc_reentrant_key)); + + if (reentrant) { + assert(!get_reentrant()); + PyThread_tss_set(&tracemalloc_reentrant_key, REENTRANT); + } + else { + assert(get_reentrant()); + PyThread_tss_set(&tracemalloc_reentrant_key, NULL); + } +} + +#else + +/* TRACE_RAW_MALLOC not defined: variable protected by the GIL */ +static int tracemalloc_reentrant = 0; + +static int +get_reentrant(void) +{ + return tracemalloc_reentrant; +} + +static void +set_reentrant(int reentrant) +{ + assert(reentrant != tracemalloc_reentrant); + tracemalloc_reentrant = reentrant; +} +#endif + + +static Py_uhash_t hashtable_hash_pyobject(const void *key) -{ +{ PyObject *obj = (PyObject *)key; - return PyObject_Hash(obj); -} - - -static int + return PyObject_Hash(obj); +} + + +static int hashtable_compare_unicode(const void *key1, const void *key2) -{ +{ PyObject *obj1 = (PyObject *)key1; PyObject *obj2 = (PyObject *)key2; if (obj1 != NULL && obj2 != NULL) { @@ -224,177 +224,177 @@ hashtable_compare_unicode(const void *key1, const void *key2) else { return obj1 == obj2; } -} - - -static Py_uhash_t +} + + +static Py_uhash_t hashtable_hash_uint(const void *key_raw) -{ +{ unsigned int key = (unsigned int)FROM_PTR(key_raw); return (Py_uhash_t)key; -} - - -static _Py_hashtable_t * +} + + +static _Py_hashtable_t * hashtable_new(_Py_hashtable_hash_func hash_func, _Py_hashtable_compare_func compare_func, _Py_hashtable_destroy_func key_destroy_func, _Py_hashtable_destroy_func value_destroy_func) -{ - _Py_hashtable_allocator_t hashtable_alloc = {malloc, free}; +{ + _Py_hashtable_allocator_t hashtable_alloc = {malloc, free}; return _Py_hashtable_new_full(hash_func, compare_func, key_destroy_func, value_destroy_func, - &hashtable_alloc); -} - - -static void* -raw_malloc(size_t size) -{ - return allocators.raw.malloc(allocators.raw.ctx, size); -} - -static void -raw_free(void *ptr) -{ - allocators.raw.free(allocators.raw.ctx, ptr); -} - - -static Py_uhash_t + &hashtable_alloc); +} + + +static void* +raw_malloc(size_t size) +{ + return allocators.raw.malloc(allocators.raw.ctx, size); +} + +static void +raw_free(void *ptr) +{ + allocators.raw.free(allocators.raw.ctx, ptr); +} + + +static Py_uhash_t hashtable_hash_traceback(const void *key) -{ +{ const traceback_t *traceback = (const traceback_t *)key; - return traceback->hash; -} - - -static int + return traceback->hash; +} + + +static int hashtable_compare_traceback(const void *key1, const void *key2) -{ +{ const traceback_t *traceback1 = (const traceback_t *)key1; const traceback_t *traceback2 = (const traceback_t *)key2; - + if (traceback1->nframe != traceback2->nframe) { - return 0; + return 0; } if (traceback1->total_nframe != traceback2->total_nframe) { return 0; } - + for (int i=0; i < traceback1->nframe; i++) { const frame_t *frame1 = &traceback1->frames[i]; const frame_t *frame2 = &traceback2->frames[i]; - + if (frame1->lineno != frame2->lineno) { - return 0; + return 0; } - if (frame1->filename != frame2->filename) { - assert(PyUnicode_Compare(frame1->filename, frame2->filename) != 0); - return 0; - } - } - return 1; -} - - -static void -tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame) -{ - frame->filename = unknown_filename; + if (frame1->filename != frame2->filename) { + assert(PyUnicode_Compare(frame1->filename, frame2->filename) != 0); + return 0; + } + } + return 1; +} + + +static void +tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame) +{ + frame->filename = unknown_filename; int lineno = PyFrame_GetLineNumber(pyframe); if (lineno < 0) { - lineno = 0; + lineno = 0; } - frame->lineno = (unsigned int)lineno; - + frame->lineno = (unsigned int)lineno; + PyCodeObject *code = PyFrame_GetCode(pyframe); PyObject *filename = code->co_filename; Py_DECREF(code); - + if (filename == NULL) { -#ifdef TRACE_DEBUG - tracemalloc_error("failed to get the filename of the code object"); -#endif - return; - } - - if (!PyUnicode_Check(filename)) { -#ifdef TRACE_DEBUG - tracemalloc_error("filename is not a unicode string"); -#endif - return; - } - if (!PyUnicode_IS_READY(filename)) { - /* Don't make a Unicode string ready to avoid reentrant calls - to tracemalloc_malloc() or tracemalloc_realloc() */ -#ifdef TRACE_DEBUG - tracemalloc_error("filename is not a ready unicode string"); -#endif - return; - } - - /* intern the filename */ +#ifdef TRACE_DEBUG + tracemalloc_error("failed to get the filename of the code object"); +#endif + return; + } + + if (!PyUnicode_Check(filename)) { +#ifdef TRACE_DEBUG + tracemalloc_error("filename is not a unicode string"); +#endif + return; + } + if (!PyUnicode_IS_READY(filename)) { + /* Don't make a Unicode string ready to avoid reentrant calls + to tracemalloc_malloc() or tracemalloc_realloc() */ +#ifdef TRACE_DEBUG + tracemalloc_error("filename is not a ready unicode string"); +#endif + return; + } + + /* intern the filename */ _Py_hashtable_entry_t *entry; entry = _Py_hashtable_get_entry(tracemalloc_filenames, filename); - if (entry != NULL) { + if (entry != NULL) { filename = (PyObject *)entry->key; - } - else { - /* tracemalloc_filenames is responsible to keep a reference - to the filename */ - Py_INCREF(filename); + } + else { + /* tracemalloc_filenames is responsible to keep a reference + to the filename */ + Py_INCREF(filename); if (_Py_hashtable_set(tracemalloc_filenames, filename, NULL) < 0) { - Py_DECREF(filename); -#ifdef TRACE_DEBUG - tracemalloc_error("failed to intern the filename"); -#endif - return; - } - } - - /* the tracemalloc_filenames table keeps a reference to the filename */ - frame->filename = filename; -} - - -static Py_uhash_t -traceback_hash(traceback_t *traceback) -{ - /* code based on tuplehash() of Objects/tupleobject.c */ - Py_uhash_t x, y; /* Unsigned for defined overflow behavior. */ - int len = traceback->nframe; - Py_uhash_t mult = _PyHASH_MULTIPLIER; - frame_t *frame; - - x = 0x345678UL; - frame = traceback->frames; - while (--len >= 0) { - y = (Py_uhash_t)PyObject_Hash(frame->filename); - y ^= (Py_uhash_t)frame->lineno; - frame++; - - x = (x ^ y) * mult; - /* the cast might truncate len; that doesn't change hash stability */ - mult += (Py_uhash_t)(82520UL + len + len); - } + Py_DECREF(filename); +#ifdef TRACE_DEBUG + tracemalloc_error("failed to intern the filename"); +#endif + return; + } + } + + /* the tracemalloc_filenames table keeps a reference to the filename */ + frame->filename = filename; +} + + +static Py_uhash_t +traceback_hash(traceback_t *traceback) +{ + /* code based on tuplehash() of Objects/tupleobject.c */ + Py_uhash_t x, y; /* Unsigned for defined overflow behavior. */ + int len = traceback->nframe; + Py_uhash_t mult = _PyHASH_MULTIPLIER; + frame_t *frame; + + x = 0x345678UL; + frame = traceback->frames; + while (--len >= 0) { + y = (Py_uhash_t)PyObject_Hash(frame->filename); + y ^= (Py_uhash_t)frame->lineno; + frame++; + + x = (x ^ y) * mult; + /* the cast might truncate len; that doesn't change hash stability */ + mult += (Py_uhash_t)(82520UL + len + len); + } x ^= traceback->total_nframe; - x += 97531UL; - return x; -} - - -static void -traceback_get_frames(traceback_t *traceback) -{ + x += 97531UL; + return x; +} + + +static void +traceback_get_frames(traceback_t *traceback) +{ PyThreadState *tstate = PyGILState_GetThisThreadState(); - if (tstate == NULL) { -#ifdef TRACE_DEBUG - tracemalloc_error("failed to get the current thread state"); -#endif - return; - } - + if (tstate == NULL) { +#ifdef TRACE_DEBUG + tracemalloc_error("failed to get the current thread state"); +#endif + return; + } + PyFrameObject *pyframe = PyThreadState_GetFrame(tstate); for (; pyframe != NULL;) { if (traceback->nframe < _Py_tracemalloc_config.max_nframe) { @@ -409,69 +409,69 @@ traceback_get_frames(traceback_t *traceback) PyFrameObject *back = PyFrame_GetBack(pyframe); Py_DECREF(pyframe); pyframe = back; - } -} - - -static traceback_t * -traceback_new(void) -{ - traceback_t *traceback; - _Py_hashtable_entry_t *entry; - - assert(PyGILState_Check()); - - /* get frames */ - traceback = tracemalloc_traceback; - traceback->nframe = 0; + } +} + + +static traceback_t * +traceback_new(void) +{ + traceback_t *traceback; + _Py_hashtable_entry_t *entry; + + assert(PyGILState_Check()); + + /* get frames */ + traceback = tracemalloc_traceback; + traceback->nframe = 0; traceback->total_nframe = 0; - traceback_get_frames(traceback); - if (traceback->nframe == 0) - return &tracemalloc_empty_traceback; - traceback->hash = traceback_hash(traceback); - - /* intern the traceback */ + traceback_get_frames(traceback); + if (traceback->nframe == 0) + return &tracemalloc_empty_traceback; + traceback->hash = traceback_hash(traceback); + + /* intern the traceback */ entry = _Py_hashtable_get_entry(tracemalloc_tracebacks, traceback); - if (entry != NULL) { + if (entry != NULL) { traceback = (traceback_t *)entry->key; - } - else { - traceback_t *copy; - size_t traceback_size; - - traceback_size = TRACEBACK_SIZE(traceback->nframe); - - copy = raw_malloc(traceback_size); - if (copy == NULL) { -#ifdef TRACE_DEBUG - tracemalloc_error("failed to intern the traceback: malloc failed"); -#endif - return NULL; - } - memcpy(copy, traceback, traceback_size); - + } + else { + traceback_t *copy; + size_t traceback_size; + + traceback_size = TRACEBACK_SIZE(traceback->nframe); + + copy = raw_malloc(traceback_size); + if (copy == NULL) { +#ifdef TRACE_DEBUG + tracemalloc_error("failed to intern the traceback: malloc failed"); +#endif + return NULL; + } + memcpy(copy, traceback, traceback_size); + if (_Py_hashtable_set(tracemalloc_tracebacks, copy, NULL) < 0) { - raw_free(copy); -#ifdef TRACE_DEBUG - tracemalloc_error("failed to intern the traceback: putdata failed"); -#endif - return NULL; - } - traceback = copy; - } - return traceback; -} - - + raw_free(copy); +#ifdef TRACE_DEBUG + tracemalloc_error("failed to intern the traceback: putdata failed"); +#endif + return NULL; + } + traceback = copy; + } + return traceback; +} + + static _Py_hashtable_t* tracemalloc_create_traces_table(void) -{ +{ return hashtable_new(_Py_hashtable_hash_ptr, _Py_hashtable_compare_direct, NULL, raw_free); } - - + + static _Py_hashtable_t* tracemalloc_create_domains_table(void) { @@ -479,696 +479,696 @@ tracemalloc_create_domains_table(void) _Py_hashtable_compare_direct, NULL, (_Py_hashtable_destroy_func)_Py_hashtable_destroy); -} - - +} + + static _Py_hashtable_t* tracemalloc_get_traces_table(unsigned int domain) -{ +{ if (domain == DEFAULT_DOMAIN) { return tracemalloc_traces; - } + } else { return _Py_hashtable_get(tracemalloc_domains, TO_PTR(domain)); - } -} - - -static void -tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr) -{ + } +} + + +static void +tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr) +{ assert(_Py_tracemalloc_config.tracing); - + _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); if (!traces) { return; - } + } trace_t *trace = _Py_hashtable_steal(traces, TO_PTR(ptr)); if (!trace) { - return; - } + return; + } assert(tracemalloc_traced_memory >= trace->size); tracemalloc_traced_memory -= trace->size; raw_free(trace); -} - -#define REMOVE_TRACE(ptr) \ - tracemalloc_remove_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr)) - - -static int -tracemalloc_add_trace(unsigned int domain, uintptr_t ptr, - size_t size) -{ +} + +#define REMOVE_TRACE(ptr) \ + tracemalloc_remove_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr)) + + +static int +tracemalloc_add_trace(unsigned int domain, uintptr_t ptr, + size_t size) +{ assert(_Py_tracemalloc_config.tracing); - + traceback_t *traceback = traceback_new(); - if (traceback == NULL) { - return -1; - } - + if (traceback == NULL) { + return -1; + } + _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); if (traces == NULL) { traces = tracemalloc_create_traces_table(); if (traces == NULL) { - return -1; - } - + return -1; + } + if (_Py_hashtable_set(tracemalloc_domains, TO_PTR(domain), traces) < 0) { _Py_hashtable_destroy(traces); return -1; } - } - + } + trace_t *trace = _Py_hashtable_get(traces, TO_PTR(ptr)); if (trace != NULL) { - /* the memory block is already tracked */ + /* the memory block is already tracked */ assert(tracemalloc_traced_memory >= trace->size); tracemalloc_traced_memory -= trace->size; - + trace->size = size; trace->traceback = traceback; - } - else { + } + else { trace = raw_malloc(sizeof(trace_t)); if (trace == NULL) { return -1; } trace->size = size; trace->traceback = traceback; - + int res = _Py_hashtable_set(traces, TO_PTR(ptr), trace); - if (res != 0) { + if (res != 0) { raw_free(trace); - return res; - } - } - - assert(tracemalloc_traced_memory <= SIZE_MAX - size); - tracemalloc_traced_memory += size; + return res; + } + } + + assert(tracemalloc_traced_memory <= SIZE_MAX - size); + tracemalloc_traced_memory += size; if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory) { - tracemalloc_peak_traced_memory = tracemalloc_traced_memory; - } - return 0; -} - -#define ADD_TRACE(ptr, size) \ - tracemalloc_add_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr), size) - - -static void* -tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - void *ptr; - - assert(elsize == 0 || nelem <= SIZE_MAX / elsize); - - if (use_calloc) - ptr = alloc->calloc(alloc->ctx, nelem, elsize); - else - ptr = alloc->malloc(alloc->ctx, nelem * elsize); - if (ptr == NULL) - return NULL; - - TABLES_LOCK(); - if (ADD_TRACE(ptr, nelem * elsize) < 0) { - /* Failed to allocate a trace for the new memory block */ - TABLES_UNLOCK(); - alloc->free(alloc->ctx, ptr); - return NULL; - } - TABLES_UNLOCK(); - return ptr; -} - - -static void* -tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - void *ptr2; - - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); - if (ptr2 == NULL) - return NULL; - - if (ptr != NULL) { - /* an existing memory block has been resized */ - - TABLES_LOCK(); - - /* tracemalloc_add_trace() updates the trace if there is already + tracemalloc_peak_traced_memory = tracemalloc_traced_memory; + } + return 0; +} + +#define ADD_TRACE(ptr, size) \ + tracemalloc_add_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr), size) + + +static void* +tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + void *ptr; + + assert(elsize == 0 || nelem <= SIZE_MAX / elsize); + + if (use_calloc) + ptr = alloc->calloc(alloc->ctx, nelem, elsize); + else + ptr = alloc->malloc(alloc->ctx, nelem * elsize); + if (ptr == NULL) + return NULL; + + TABLES_LOCK(); + if (ADD_TRACE(ptr, nelem * elsize) < 0) { + /* Failed to allocate a trace for the new memory block */ + TABLES_UNLOCK(); + alloc->free(alloc->ctx, ptr); + return NULL; + } + TABLES_UNLOCK(); + return ptr; +} + + +static void* +tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + void *ptr2; + + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + if (ptr2 == NULL) + return NULL; + + if (ptr != NULL) { + /* an existing memory block has been resized */ + + TABLES_LOCK(); + + /* tracemalloc_add_trace() updates the trace if there is already a trace at address ptr2 */ - if (ptr2 != ptr) { - REMOVE_TRACE(ptr); - } - - if (ADD_TRACE(ptr2, new_size) < 0) { - /* Memory allocation failed. The error cannot be reported to - the caller, because realloc() may already have shrunk the - memory block and so removed bytes. - - This case is very unlikely: a hash entry has just been - released, so the hash table should have at least one free entry. - - The GIL and the table lock ensures that only one thread is - allocating memory. */ + if (ptr2 != ptr) { + REMOVE_TRACE(ptr); + } + + if (ADD_TRACE(ptr2, new_size) < 0) { + /* Memory allocation failed. The error cannot be reported to + the caller, because realloc() may already have shrunk the + memory block and so removed bytes. + + This case is very unlikely: a hash entry has just been + released, so the hash table should have at least one free entry. + + The GIL and the table lock ensures that only one thread is + allocating memory. */ Py_FatalError("tracemalloc_realloc() failed to allocate a trace"); - } - TABLES_UNLOCK(); - } - else { - /* new allocation */ - - TABLES_LOCK(); - if (ADD_TRACE(ptr2, new_size) < 0) { - /* Failed to allocate a trace for the new memory block */ - TABLES_UNLOCK(); - alloc->free(alloc->ctx, ptr2); - return NULL; - } - TABLES_UNLOCK(); - } - return ptr2; -} - - -static void -tracemalloc_free(void *ctx, void *ptr) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - - if (ptr == NULL) - return; - - /* GIL cannot be locked in PyMem_RawFree() because it would introduce + } + TABLES_UNLOCK(); + } + else { + /* new allocation */ + + TABLES_LOCK(); + if (ADD_TRACE(ptr2, new_size) < 0) { + /* Failed to allocate a trace for the new memory block */ + TABLES_UNLOCK(); + alloc->free(alloc->ctx, ptr2); + return NULL; + } + TABLES_UNLOCK(); + } + return ptr2; +} + + +static void +tracemalloc_free(void *ctx, void *ptr) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + + if (ptr == NULL) + return; + + /* GIL cannot be locked in PyMem_RawFree() because it would introduce a deadlock in _PyThreadState_DeleteCurrent(). */ - - alloc->free(alloc->ctx, ptr); - - TABLES_LOCK(); - REMOVE_TRACE(ptr); - TABLES_UNLOCK(); -} - - -static void* -tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) -{ - void *ptr; - - if (get_reentrant()) { - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - if (use_calloc) - return alloc->calloc(alloc->ctx, nelem, elsize); - else - return alloc->malloc(alloc->ctx, nelem * elsize); - } - - /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() for - allocations larger than 512 bytes, don't trace the same memory - allocation twice. */ - set_reentrant(1); - - ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); - - set_reentrant(0); - return ptr; -} - - -static void* -tracemalloc_malloc_gil(void *ctx, size_t size) -{ - return tracemalloc_alloc_gil(0, ctx, 1, size); -} - - -static void* -tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize) -{ - return tracemalloc_alloc_gil(1, ctx, nelem, elsize); -} - - -static void* -tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) -{ - void *ptr2; - - if (get_reentrant()) { - /* Reentrant call to PyMem_Realloc() and PyMem_RawRealloc(). - Example: PyMem_RawRealloc() is called internally by pymalloc - (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new - arena (new_arena()). */ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); - if (ptr2 != NULL && ptr != NULL) { - TABLES_LOCK(); - REMOVE_TRACE(ptr); - TABLES_UNLOCK(); - } - return ptr2; - } - - /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for - allocations larger than 512 bytes. Don't trace the same memory - allocation twice. */ - set_reentrant(1); - - ptr2 = tracemalloc_realloc(ctx, ptr, new_size); - - set_reentrant(0); - return ptr2; -} - - -#ifdef TRACE_RAW_MALLOC -static void* -tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) -{ - PyGILState_STATE gil_state; - void *ptr; - - if (get_reentrant()) { - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - if (use_calloc) - return alloc->calloc(alloc->ctx, nelem, elsize); - else - return alloc->malloc(alloc->ctx, nelem * elsize); - } - - /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() - indirectly which would call PyGILState_Ensure() if reentrant are not - disabled. */ - set_reentrant(1); - - gil_state = PyGILState_Ensure(); - ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); - PyGILState_Release(gil_state); - - set_reentrant(0); - return ptr; -} - - -static void* -tracemalloc_raw_malloc(void *ctx, size_t size) -{ - return tracemalloc_raw_alloc(0, ctx, 1, size); -} - - -static void* -tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize) -{ - return tracemalloc_raw_alloc(1, ctx, nelem, elsize); -} - - -static void* -tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) -{ - PyGILState_STATE gil_state; - void *ptr2; - - if (get_reentrant()) { - /* Reentrant call to PyMem_RawRealloc(). */ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); - - if (ptr2 != NULL && ptr != NULL) { - TABLES_LOCK(); - REMOVE_TRACE(ptr); - TABLES_UNLOCK(); - } - return ptr2; - } - - /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() - indirectly which would call PyGILState_Ensure() if reentrant calls are - not disabled. */ - set_reentrant(1); - - gil_state = PyGILState_Ensure(); - ptr2 = tracemalloc_realloc(ctx, ptr, new_size); - PyGILState_Release(gil_state); - - set_reentrant(0); - return ptr2; -} -#endif /* TRACE_RAW_MALLOC */ - - + + alloc->free(alloc->ctx, ptr); + + TABLES_LOCK(); + REMOVE_TRACE(ptr); + TABLES_UNLOCK(); +} + + +static void* +tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) +{ + void *ptr; + + if (get_reentrant()) { + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (use_calloc) + return alloc->calloc(alloc->ctx, nelem, elsize); + else + return alloc->malloc(alloc->ctx, nelem * elsize); + } + + /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() for + allocations larger than 512 bytes, don't trace the same memory + allocation twice. */ + set_reentrant(1); + + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); + + set_reentrant(0); + return ptr; +} + + +static void* +tracemalloc_malloc_gil(void *ctx, size_t size) +{ + return tracemalloc_alloc_gil(0, ctx, 1, size); +} + + +static void* +tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize) +{ + return tracemalloc_alloc_gil(1, ctx, nelem, elsize); +} + + +static void* +tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) +{ + void *ptr2; + + if (get_reentrant()) { + /* Reentrant call to PyMem_Realloc() and PyMem_RawRealloc(). + Example: PyMem_RawRealloc() is called internally by pymalloc + (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new + arena (new_arena()). */ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + if (ptr2 != NULL && ptr != NULL) { + TABLES_LOCK(); + REMOVE_TRACE(ptr); + TABLES_UNLOCK(); + } + return ptr2; + } + + /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for + allocations larger than 512 bytes. Don't trace the same memory + allocation twice. */ + set_reentrant(1); + + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); + + set_reentrant(0); + return ptr2; +} + + +#ifdef TRACE_RAW_MALLOC +static void* +tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) +{ + PyGILState_STATE gil_state; + void *ptr; + + if (get_reentrant()) { + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (use_calloc) + return alloc->calloc(alloc->ctx, nelem, elsize); + else + return alloc->malloc(alloc->ctx, nelem * elsize); + } + + /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() + indirectly which would call PyGILState_Ensure() if reentrant are not + disabled. */ + set_reentrant(1); + + gil_state = PyGILState_Ensure(); + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); + PyGILState_Release(gil_state); + + set_reentrant(0); + return ptr; +} + + +static void* +tracemalloc_raw_malloc(void *ctx, size_t size) +{ + return tracemalloc_raw_alloc(0, ctx, 1, size); +} + + +static void* +tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize) +{ + return tracemalloc_raw_alloc(1, ctx, nelem, elsize); +} + + +static void* +tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) +{ + PyGILState_STATE gil_state; + void *ptr2; + + if (get_reentrant()) { + /* Reentrant call to PyMem_RawRealloc(). */ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + + if (ptr2 != NULL && ptr != NULL) { + TABLES_LOCK(); + REMOVE_TRACE(ptr); + TABLES_UNLOCK(); + } + return ptr2; + } + + /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() + indirectly which would call PyGILState_Ensure() if reentrant calls are + not disabled. */ + set_reentrant(1); + + gil_state = PyGILState_Ensure(); + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); + PyGILState_Release(gil_state); + + set_reentrant(0); + return ptr2; +} +#endif /* TRACE_RAW_MALLOC */ + + static void tracemalloc_clear_filename(void *value) -{ +{ PyObject *filename = (PyObject *)value; - Py_DECREF(filename); -} - - -/* reentrant flag must be set to call this function and GIL must be held */ -static void -tracemalloc_clear_traces(void) -{ + Py_DECREF(filename); +} + + +/* reentrant flag must be set to call this function and GIL must be held */ +static void +tracemalloc_clear_traces(void) +{ /* The GIL protects variables against concurrent access */ - assert(PyGILState_Check()); - - TABLES_LOCK(); - _Py_hashtable_clear(tracemalloc_traces); + assert(PyGILState_Check()); + + TABLES_LOCK(); + _Py_hashtable_clear(tracemalloc_traces); _Py_hashtable_clear(tracemalloc_domains); - tracemalloc_traced_memory = 0; - tracemalloc_peak_traced_memory = 0; - TABLES_UNLOCK(); - - _Py_hashtable_clear(tracemalloc_tracebacks); - - _Py_hashtable_clear(tracemalloc_filenames); -} - - -static int -tracemalloc_init(void) -{ + tracemalloc_traced_memory = 0; + tracemalloc_peak_traced_memory = 0; + TABLES_UNLOCK(); + + _Py_hashtable_clear(tracemalloc_tracebacks); + + _Py_hashtable_clear(tracemalloc_filenames); +} + + +static int +tracemalloc_init(void) +{ if (_Py_tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) { - PyErr_SetString(PyExc_RuntimeError, - "the tracemalloc module has been unloaded"); - return -1; - } - + PyErr_SetString(PyExc_RuntimeError, + "the tracemalloc module has been unloaded"); + return -1; + } + if (_Py_tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED) - return 0; - - PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); - -#ifdef REENTRANT_THREADLOCAL - if (PyThread_tss_create(&tracemalloc_reentrant_key) != 0) { -#ifdef MS_WINDOWS - PyErr_SetFromWindowsErr(0); -#else - PyErr_SetFromErrno(PyExc_OSError); -#endif - return -1; - } -#endif - -#if defined(TRACE_RAW_MALLOC) - if (tables_lock == NULL) { - tables_lock = PyThread_allocate_lock(); - if (tables_lock == NULL) { - PyErr_SetString(PyExc_RuntimeError, "cannot allocate lock"); - return -1; - } - } -#endif - + return 0; + + PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); + +#ifdef REENTRANT_THREADLOCAL + if (PyThread_tss_create(&tracemalloc_reentrant_key) != 0) { +#ifdef MS_WINDOWS + PyErr_SetFromWindowsErr(0); +#else + PyErr_SetFromErrno(PyExc_OSError); +#endif + return -1; + } +#endif + +#if defined(TRACE_RAW_MALLOC) + if (tables_lock == NULL) { + tables_lock = PyThread_allocate_lock(); + if (tables_lock == NULL) { + PyErr_SetString(PyExc_RuntimeError, "cannot allocate lock"); + return -1; + } + } +#endif + tracemalloc_filenames = hashtable_new(hashtable_hash_pyobject, hashtable_compare_unicode, tracemalloc_clear_filename, NULL); - + tracemalloc_tracebacks = hashtable_new(hashtable_hash_traceback, hashtable_compare_traceback, NULL, raw_free); - + tracemalloc_traces = tracemalloc_create_traces_table(); tracemalloc_domains = tracemalloc_create_domains_table(); - - if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL + + if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL || tracemalloc_traces == NULL || tracemalloc_domains == NULL) { - PyErr_NoMemory(); - return -1; - } - - unknown_filename = PyUnicode_FromString(""); - if (unknown_filename == NULL) - return -1; - PyUnicode_InternInPlace(&unknown_filename); - - tracemalloc_empty_traceback.nframe = 1; + PyErr_NoMemory(); + return -1; + } + + unknown_filename = PyUnicode_FromString(""); + if (unknown_filename == NULL) + return -1; + PyUnicode_InternInPlace(&unknown_filename); + + tracemalloc_empty_traceback.nframe = 1; tracemalloc_empty_traceback.total_nframe = 1; - /* borrowed reference */ - tracemalloc_empty_traceback.frames[0].filename = unknown_filename; - tracemalloc_empty_traceback.frames[0].lineno = 0; - tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback); - + /* borrowed reference */ + tracemalloc_empty_traceback.frames[0].filename = unknown_filename; + tracemalloc_empty_traceback.frames[0].lineno = 0; + tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback); + _Py_tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED; - return 0; -} - - -static void -tracemalloc_deinit(void) -{ + return 0; +} + + +static void +tracemalloc_deinit(void) +{ if (_Py_tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED) - return; + return; _Py_tracemalloc_config.initialized = TRACEMALLOC_FINALIZED; - - tracemalloc_stop(); - - /* destroy hash tables */ + + tracemalloc_stop(); + + /* destroy hash tables */ _Py_hashtable_destroy(tracemalloc_domains); _Py_hashtable_destroy(tracemalloc_traces); - _Py_hashtable_destroy(tracemalloc_tracebacks); - _Py_hashtable_destroy(tracemalloc_filenames); - -#if defined(TRACE_RAW_MALLOC) - if (tables_lock != NULL) { - PyThread_free_lock(tables_lock); - tables_lock = NULL; - } -#endif - -#ifdef REENTRANT_THREADLOCAL - PyThread_tss_delete(&tracemalloc_reentrant_key); -#endif - - Py_XDECREF(unknown_filename); -} - - -static int -tracemalloc_start(int max_nframe) -{ - PyMemAllocatorEx alloc; - size_t size; - + _Py_hashtable_destroy(tracemalloc_tracebacks); + _Py_hashtable_destroy(tracemalloc_filenames); + +#if defined(TRACE_RAW_MALLOC) + if (tables_lock != NULL) { + PyThread_free_lock(tables_lock); + tables_lock = NULL; + } +#endif + +#ifdef REENTRANT_THREADLOCAL + PyThread_tss_delete(&tracemalloc_reentrant_key); +#endif + + Py_XDECREF(unknown_filename); +} + + +static int +tracemalloc_start(int max_nframe) +{ + PyMemAllocatorEx alloc; + size_t size; + if (max_nframe < 1 || (unsigned long) max_nframe > MAX_NFRAME) { - PyErr_Format(PyExc_ValueError, + PyErr_Format(PyExc_ValueError, "the number of frames must be in range [1; %lu]", MAX_NFRAME); - return -1; - } - - if (tracemalloc_init() < 0) { - return -1; - } - + return -1; + } + + if (tracemalloc_init() < 0) { + return -1; + } + if (_Py_tracemalloc_config.tracing) { - /* hook already installed: do nothing */ - return 0; - } - + /* hook already installed: do nothing */ + return 0; + } + _Py_tracemalloc_config.max_nframe = max_nframe; - - /* allocate a buffer to store a new traceback */ - size = TRACEBACK_SIZE(max_nframe); - assert(tracemalloc_traceback == NULL); - tracemalloc_traceback = raw_malloc(size); - if (tracemalloc_traceback == NULL) { - PyErr_NoMemory(); - return -1; - } - -#ifdef TRACE_RAW_MALLOC - alloc.malloc = tracemalloc_raw_malloc; - alloc.calloc = tracemalloc_raw_calloc; - alloc.realloc = tracemalloc_raw_realloc; - alloc.free = tracemalloc_free; - - alloc.ctx = &allocators.raw; - PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); -#endif - - alloc.malloc = tracemalloc_malloc_gil; - alloc.calloc = tracemalloc_calloc_gil; - alloc.realloc = tracemalloc_realloc_gil; - alloc.free = tracemalloc_free; - - alloc.ctx = &allocators.mem; - PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); - - alloc.ctx = &allocators.obj; - PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); - - /* everything is ready: start tracing Python memory allocations */ + + /* allocate a buffer to store a new traceback */ + size = TRACEBACK_SIZE(max_nframe); + assert(tracemalloc_traceback == NULL); + tracemalloc_traceback = raw_malloc(size); + if (tracemalloc_traceback == NULL) { + PyErr_NoMemory(); + return -1; + } + +#ifdef TRACE_RAW_MALLOC + alloc.malloc = tracemalloc_raw_malloc; + alloc.calloc = tracemalloc_raw_calloc; + alloc.realloc = tracemalloc_raw_realloc; + alloc.free = tracemalloc_free; + + alloc.ctx = &allocators.raw; + PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); +#endif + + alloc.malloc = tracemalloc_malloc_gil; + alloc.calloc = tracemalloc_calloc_gil; + alloc.realloc = tracemalloc_realloc_gil; + alloc.free = tracemalloc_free; + + alloc.ctx = &allocators.mem; + PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); + + alloc.ctx = &allocators.obj; + PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); + + /* everything is ready: start tracing Python memory allocations */ _Py_tracemalloc_config.tracing = 1; - - return 0; -} - - -static void -tracemalloc_stop(void) -{ + + return 0; +} + + +static void +tracemalloc_stop(void) +{ if (!_Py_tracemalloc_config.tracing) - return; - - /* stop tracing Python memory allocations */ + return; + + /* stop tracing Python memory allocations */ _Py_tracemalloc_config.tracing = 0; - - /* unregister the hook on memory allocators */ -#ifdef TRACE_RAW_MALLOC - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); -#endif - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); - - tracemalloc_clear_traces(); - - /* release memory */ - raw_free(tracemalloc_traceback); - tracemalloc_traceback = NULL; -} - - - -/*[clinic input] -_tracemalloc.is_tracing - -Return True if the tracemalloc module is tracing Python memory allocations. -[clinic start generated code]*/ - -static PyObject * -_tracemalloc_is_tracing_impl(PyObject *module) -/*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/ -{ + + /* unregister the hook on memory allocators */ +#ifdef TRACE_RAW_MALLOC + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); +#endif + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); + + tracemalloc_clear_traces(); + + /* release memory */ + raw_free(tracemalloc_traceback); + tracemalloc_traceback = NULL; +} + + + +/*[clinic input] +_tracemalloc.is_tracing + +Return True if the tracemalloc module is tracing Python memory allocations. +[clinic start generated code]*/ + +static PyObject * +_tracemalloc_is_tracing_impl(PyObject *module) +/*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/ +{ return PyBool_FromLong(_Py_tracemalloc_config.tracing); -} - - -/*[clinic input] -_tracemalloc.clear_traces - -Clear traces of memory blocks allocated by Python. -[clinic start generated code]*/ - -static PyObject * -_tracemalloc_clear_traces_impl(PyObject *module) -/*[clinic end generated code: output=a86080ee41b84197 input=0dab5b6c785183a5]*/ -{ - if (!_Py_tracemalloc_config.tracing) - Py_RETURN_NONE; - - set_reentrant(1); - tracemalloc_clear_traces(); - set_reentrant(0); - - Py_RETURN_NONE; -} - - -static PyObject* -frame_to_pyobject(frame_t *frame) -{ - PyObject *frame_obj, *lineno_obj; - - frame_obj = PyTuple_New(2); - if (frame_obj == NULL) - return NULL; - - Py_INCREF(frame->filename); - PyTuple_SET_ITEM(frame_obj, 0, frame->filename); - - lineno_obj = PyLong_FromUnsignedLong(frame->lineno); - if (lineno_obj == NULL) { - Py_DECREF(frame_obj); - return NULL; - } - PyTuple_SET_ITEM(frame_obj, 1, lineno_obj); - - return frame_obj; -} - - -static PyObject* -traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table) -{ +} + + +/*[clinic input] +_tracemalloc.clear_traces + +Clear traces of memory blocks allocated by Python. +[clinic start generated code]*/ + +static PyObject * +_tracemalloc_clear_traces_impl(PyObject *module) +/*[clinic end generated code: output=a86080ee41b84197 input=0dab5b6c785183a5]*/ +{ + if (!_Py_tracemalloc_config.tracing) + Py_RETURN_NONE; + + set_reentrant(1); + tracemalloc_clear_traces(); + set_reentrant(0); + + Py_RETURN_NONE; +} + + +static PyObject* +frame_to_pyobject(frame_t *frame) +{ + PyObject *frame_obj, *lineno_obj; + + frame_obj = PyTuple_New(2); + if (frame_obj == NULL) + return NULL; + + Py_INCREF(frame->filename); + PyTuple_SET_ITEM(frame_obj, 0, frame->filename); + + lineno_obj = PyLong_FromUnsignedLong(frame->lineno); + if (lineno_obj == NULL) { + Py_DECREF(frame_obj); + return NULL; + } + PyTuple_SET_ITEM(frame_obj, 1, lineno_obj); + + return frame_obj; +} + + +static PyObject* +traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table) +{ PyObject *frames; - - if (intern_table != NULL) { + + if (intern_table != NULL) { frames = _Py_hashtable_get(intern_table, (const void *)traceback); if (frames) { - Py_INCREF(frames); - return frames; - } - } - - frames = PyTuple_New(traceback->nframe); - if (frames == NULL) - return NULL; - + Py_INCREF(frames); + return frames; + } + } + + frames = PyTuple_New(traceback->nframe); + if (frames == NULL) + return NULL; + for (int i=0; i < traceback->nframe; i++) { PyObject *frame = frame_to_pyobject(&traceback->frames[i]); - if (frame == NULL) { - Py_DECREF(frames); - return NULL; - } - PyTuple_SET_ITEM(frames, i, frame); - } - - if (intern_table != NULL) { + if (frame == NULL) { + Py_DECREF(frames); + return NULL; + } + PyTuple_SET_ITEM(frames, i, frame); + } + + if (intern_table != NULL) { if (_Py_hashtable_set(intern_table, traceback, frames) < 0) { - Py_DECREF(frames); - PyErr_NoMemory(); - return NULL; - } - /* intern_table keeps a new reference to frames */ - Py_INCREF(frames); - } - return frames; -} - - -static PyObject* + Py_DECREF(frames); + PyErr_NoMemory(); + return NULL; + } + /* intern_table keeps a new reference to frames */ + Py_INCREF(frames); + } + return frames; +} + + +static PyObject* trace_to_pyobject(unsigned int domain, const trace_t *trace, - _Py_hashtable_t *intern_tracebacks) -{ - PyObject *trace_obj = NULL; - PyObject *obj; - + _Py_hashtable_t *intern_tracebacks) +{ + PyObject *trace_obj = NULL; + PyObject *obj; + trace_obj = PyTuple_New(4); - if (trace_obj == NULL) - return NULL; - - obj = PyLong_FromSize_t(domain); - if (obj == NULL) { - Py_DECREF(trace_obj); - return NULL; - } - PyTuple_SET_ITEM(trace_obj, 0, obj); - - obj = PyLong_FromSize_t(trace->size); - if (obj == NULL) { - Py_DECREF(trace_obj); - return NULL; - } - PyTuple_SET_ITEM(trace_obj, 1, obj); - - obj = traceback_to_pyobject(trace->traceback, intern_tracebacks); - if (obj == NULL) { - Py_DECREF(trace_obj); - return NULL; - } - PyTuple_SET_ITEM(trace_obj, 2, obj); - + if (trace_obj == NULL) + return NULL; + + obj = PyLong_FromSize_t(domain); + if (obj == NULL) { + Py_DECREF(trace_obj); + return NULL; + } + PyTuple_SET_ITEM(trace_obj, 0, obj); + + obj = PyLong_FromSize_t(trace->size); + if (obj == NULL) { + Py_DECREF(trace_obj); + return NULL; + } + PyTuple_SET_ITEM(trace_obj, 1, obj); + + obj = traceback_to_pyobject(trace->traceback, intern_tracebacks); + if (obj == NULL) { + Py_DECREF(trace_obj); + return NULL; + } + PyTuple_SET_ITEM(trace_obj, 2, obj); + obj = PyLong_FromUnsignedLong(trace->traceback->total_nframe); if (obj == NULL) { Py_DECREF(trace_obj); @@ -1176,40 +1176,40 @@ trace_to_pyobject(unsigned int domain, const trace_t *trace, } PyTuple_SET_ITEM(trace_obj, 3, obj); - return trace_obj; -} - - -typedef struct { - _Py_hashtable_t *traces; + return trace_obj; +} + + +typedef struct { + _Py_hashtable_t *traces; _Py_hashtable_t *domains; - _Py_hashtable_t *tracebacks; - PyObject *list; + _Py_hashtable_t *tracebacks; + PyObject *list; unsigned int domain; -} get_traces_t; - +} get_traces_t; + -static int +static int tracemalloc_copy_trace(_Py_hashtable_t *traces, const void *key, const void *value, void *user_data) -{ +{ _Py_hashtable_t *traces2 = (_Py_hashtable_t *)user_data; - + trace_t *trace = (trace_t *)value; trace_t *trace2 = raw_malloc(sizeof(trace_t)); if (trace2 == NULL) { return -1; - } + } *trace2 = *trace; if (_Py_hashtable_set(traces2, key, trace2) < 0) { raw_free(trace2); return -1; - } + } return 0; } - + static _Py_hashtable_t* tracemalloc_copy_traces(_Py_hashtable_t *traces) @@ -1280,24 +1280,24 @@ tracemalloc_get_traces_fill(_Py_hashtable_t *traces, PyObject *tuple = trace_to_pyobject(get_traces->domain, trace, get_traces->tracebacks); if (tuple == NULL) { - return 1; + return 1; } - + int res = PyList_Append(get_traces->list, tuple); Py_DECREF(tuple); if (res < 0) { - return 1; - } - - return 0; -} - - -static int + return 1; + } + + return 0; +} + + +static int tracemalloc_get_traces_domain(_Py_hashtable_t *domains, const void *key, const void *value, void *user_data) -{ +{ get_traces_t *get_traces = user_data; unsigned int domain = (unsigned int)FROM_PTR(key); @@ -1314,58 +1314,58 @@ static void tracemalloc_pyobject_decref(void *value) { PyObject *obj = (PyObject *)value; - Py_DECREF(obj); -} - - - -/*[clinic input] -_tracemalloc._get_traces - -Get traces of all memory blocks allocated by Python. - -Return a list of (size: int, traceback: tuple) tuples. -traceback is a tuple of (filename: str, lineno: int) tuples. - -Return an empty list if the tracemalloc module is disabled. -[clinic start generated code]*/ - -static PyObject * -_tracemalloc__get_traces_impl(PyObject *module) -/*[clinic end generated code: output=e9929876ced4b5cc input=6c7d2230b24255aa]*/ -{ - get_traces_t get_traces; + Py_DECREF(obj); +} + + + +/*[clinic input] +_tracemalloc._get_traces + +Get traces of all memory blocks allocated by Python. + +Return a list of (size: int, traceback: tuple) tuples. +traceback is a tuple of (filename: str, lineno: int) tuples. + +Return an empty list if the tracemalloc module is disabled. +[clinic start generated code]*/ + +static PyObject * +_tracemalloc__get_traces_impl(PyObject *module) +/*[clinic end generated code: output=e9929876ced4b5cc input=6c7d2230b24255aa]*/ +{ + get_traces_t get_traces; get_traces.domain = DEFAULT_DOMAIN; - get_traces.traces = NULL; + get_traces.traces = NULL; get_traces.domains = NULL; - get_traces.tracebacks = NULL; - get_traces.list = PyList_New(0); - if (get_traces.list == NULL) - goto error; - + get_traces.tracebacks = NULL; + get_traces.list = PyList_New(0); + if (get_traces.list == NULL) + goto error; + if (!_Py_tracemalloc_config.tracing) - return get_traces.list; - - /* the traceback hash table is used temporarily to intern traceback tuple - of (filename, lineno) tuples */ + return get_traces.list; + + /* the traceback hash table is used temporarily to intern traceback tuple + of (filename, lineno) tuples */ get_traces.tracebacks = hashtable_new(_Py_hashtable_hash_ptr, _Py_hashtable_compare_direct, NULL, tracemalloc_pyobject_decref); - if (get_traces.tracebacks == NULL) { + if (get_traces.tracebacks == NULL) { goto no_memory; - } - + } + // Copy all traces so tracemalloc_get_traces_fill() doesn't have to disable // temporarily tracemalloc which would impact other threads and so would // miss allocations while get_traces() is called. - TABLES_LOCK(); + TABLES_LOCK(); get_traces.traces = tracemalloc_copy_traces(tracemalloc_traces); - TABLES_UNLOCK(); - - if (get_traces.traces == NULL) { + TABLES_UNLOCK(); + + if (get_traces.traces == NULL) { goto no_memory; - } - + } + TABLES_LOCK(); get_traces.domains = tracemalloc_copy_domains(tracemalloc_domains); TABLES_UNLOCK(); @@ -1375,7 +1375,7 @@ _tracemalloc__get_traces_impl(PyObject *module) } // Convert traces to a list of tuples - set_reentrant(1); + set_reentrant(1); int err = _Py_hashtable_foreach(get_traces.traces, tracemalloc_get_traces_fill, &get_traces); @@ -1384,196 +1384,196 @@ _tracemalloc__get_traces_impl(PyObject *module) tracemalloc_get_traces_domain, &get_traces); } - set_reentrant(0); + set_reentrant(0); if (err) { - goto error; + goto error; } - - goto finally; - + + goto finally; + no_memory: PyErr_NoMemory(); -error: - Py_CLEAR(get_traces.list); - -finally: - if (get_traces.tracebacks != NULL) { - _Py_hashtable_destroy(get_traces.tracebacks); - } - if (get_traces.traces != NULL) { - _Py_hashtable_destroy(get_traces.traces); - } +error: + Py_CLEAR(get_traces.list); + +finally: + if (get_traces.tracebacks != NULL) { + _Py_hashtable_destroy(get_traces.tracebacks); + } + if (get_traces.traces != NULL) { + _Py_hashtable_destroy(get_traces.traces); + } if (get_traces.domains != NULL) { _Py_hashtable_destroy(get_traces.domains); } - - return get_traces.list; -} - - -static traceback_t* -tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr) -{ - + + return get_traces.list; +} + + +static traceback_t* +tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr) +{ + if (!_Py_tracemalloc_config.tracing) - return NULL; - + return NULL; + trace_t *trace; - TABLES_LOCK(); + TABLES_LOCK(); _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); if (traces) { trace = _Py_hashtable_get(traces, TO_PTR(ptr)); - } - else { + } + else { trace = NULL; - } - TABLES_UNLOCK(); - + } + TABLES_UNLOCK(); + if (!trace) { - return NULL; + return NULL; } - + return trace->traceback; -} - - - -/*[clinic input] -_tracemalloc._get_object_traceback - - obj: object - / - -Get the traceback where the Python object obj was allocated. - -Return a tuple of (filename: str, lineno: int) tuples. -Return None if the tracemalloc module is disabled or did not -trace the allocation of the object. -[clinic start generated code]*/ - -static PyObject * -_tracemalloc__get_object_traceback(PyObject *module, PyObject *obj) -/*[clinic end generated code: output=41ee0553a658b0aa input=29495f1b21c53212]*/ -{ - PyTypeObject *type; - void *ptr; - traceback_t *traceback; - - type = Py_TYPE(obj); +} + + + +/*[clinic input] +_tracemalloc._get_object_traceback + + obj: object + / + +Get the traceback where the Python object obj was allocated. + +Return a tuple of (filename: str, lineno: int) tuples. +Return None if the tracemalloc module is disabled or did not +trace the allocation of the object. +[clinic start generated code]*/ + +static PyObject * +_tracemalloc__get_object_traceback(PyObject *module, PyObject *obj) +/*[clinic end generated code: output=41ee0553a658b0aa input=29495f1b21c53212]*/ +{ + PyTypeObject *type; + void *ptr; + traceback_t *traceback; + + type = Py_TYPE(obj); if (PyType_IS_GC(type)) { - ptr = (void *)((char *)obj - sizeof(PyGC_Head)); + ptr = (void *)((char *)obj - sizeof(PyGC_Head)); } else { - ptr = (void *)obj; - } - - traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); - if (traceback == NULL) - Py_RETURN_NONE; - - return traceback_to_pyobject(traceback, NULL); -} - - -#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) - -static void -_PyMem_DumpFrame(int fd, frame_t * frame) -{ - PUTS(fd, " File \""); - _Py_DumpASCII(fd, frame->filename); - PUTS(fd, "\", line "); - _Py_DumpDecimal(fd, frame->lineno); - PUTS(fd, "\n"); -} - -/* Dump the traceback where a memory block was allocated into file descriptor - fd. The function may block on TABLES_LOCK() but it is unlikely. */ -void -_PyMem_DumpTraceback(int fd, const void *ptr) -{ - traceback_t *traceback; - int i; - + ptr = (void *)obj; + } + + traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); + if (traceback == NULL) + Py_RETURN_NONE; + + return traceback_to_pyobject(traceback, NULL); +} + + +#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) + +static void +_PyMem_DumpFrame(int fd, frame_t * frame) +{ + PUTS(fd, " File \""); + _Py_DumpASCII(fd, frame->filename); + PUTS(fd, "\", line "); + _Py_DumpDecimal(fd, frame->lineno); + PUTS(fd, "\n"); +} + +/* Dump the traceback where a memory block was allocated into file descriptor + fd. The function may block on TABLES_LOCK() but it is unlikely. */ +void +_PyMem_DumpTraceback(int fd, const void *ptr) +{ + traceback_t *traceback; + int i; + if (!_Py_tracemalloc_config.tracing) { - PUTS(fd, "Enable tracemalloc to get the memory block " - "allocation traceback\n\n"); - return; - } - - traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); - if (traceback == NULL) - return; - - PUTS(fd, "Memory block allocated at (most recent call first):\n"); - for (i=0; i < traceback->nframe; i++) { - _PyMem_DumpFrame(fd, &traceback->frames[i]); - } - PUTS(fd, "\n"); -} - -#undef PUTS - - - -/*[clinic input] -_tracemalloc.start - - nframe: int = 1 - / - -Start tracing Python memory allocations. - -Also set the maximum number of frames stored in the traceback of a -trace to nframe. -[clinic start generated code]*/ - -static PyObject * -_tracemalloc_start_impl(PyObject *module, int nframe) -/*[clinic end generated code: output=caae05c23c159d3c input=40d849b5b29d1933]*/ -{ - if (tracemalloc_start(nframe) < 0) { - return NULL; - } - Py_RETURN_NONE; -} - - -/*[clinic input] -_tracemalloc.stop - -Stop tracing Python memory allocations. - -Also clear traces of memory blocks allocated by Python. -[clinic start generated code]*/ - -static PyObject * -_tracemalloc_stop_impl(PyObject *module) -/*[clinic end generated code: output=c3c42ae03e3955cd input=7478f075e51dae18]*/ -{ - tracemalloc_stop(); - Py_RETURN_NONE; -} - - -/*[clinic input] -_tracemalloc.get_traceback_limit - -Get the maximum number of frames stored in the traceback of a trace. - -By default, a trace of an allocated memory block only stores -the most recent frame: the limit is 1. -[clinic start generated code]*/ - -static PyObject * -_tracemalloc_get_traceback_limit_impl(PyObject *module) -/*[clinic end generated code: output=d556d9306ba95567 input=da3cd977fc68ae3b]*/ -{ + PUTS(fd, "Enable tracemalloc to get the memory block " + "allocation traceback\n\n"); + return; + } + + traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); + if (traceback == NULL) + return; + + PUTS(fd, "Memory block allocated at (most recent call first):\n"); + for (i=0; i < traceback->nframe; i++) { + _PyMem_DumpFrame(fd, &traceback->frames[i]); + } + PUTS(fd, "\n"); +} + +#undef PUTS + + + +/*[clinic input] +_tracemalloc.start + + nframe: int = 1 + / + +Start tracing Python memory allocations. + +Also set the maximum number of frames stored in the traceback of a +trace to nframe. +[clinic start generated code]*/ + +static PyObject * +_tracemalloc_start_impl(PyObject *module, int nframe) +/*[clinic end generated code: output=caae05c23c159d3c input=40d849b5b29d1933]*/ +{ + if (tracemalloc_start(nframe) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +/*[clinic input] +_tracemalloc.stop + +Stop tracing Python memory allocations. + +Also clear traces of memory blocks allocated by Python. +[clinic start generated code]*/ + +static PyObject * +_tracemalloc_stop_impl(PyObject *module) +/*[clinic end generated code: output=c3c42ae03e3955cd input=7478f075e51dae18]*/ +{ + tracemalloc_stop(); + Py_RETURN_NONE; +} + + +/*[clinic input] +_tracemalloc.get_traceback_limit + +Get the maximum number of frames stored in the traceback of a trace. + +By default, a trace of an allocated memory block only stores +the most recent frame: the limit is 1. +[clinic start generated code]*/ + +static PyObject * +_tracemalloc_get_traceback_limit_impl(PyObject *module) +/*[clinic end generated code: output=d556d9306ba95567 input=da3cd977fc68ae3b]*/ +{ return PyLong_FromLong(_Py_tracemalloc_config.max_nframe); -} - - +} + + static int tracemalloc_get_tracemalloc_memory_cb(_Py_hashtable_t *domains, const void *key, const void *value, @@ -1584,64 +1584,64 @@ tracemalloc_get_tracemalloc_memory_cb(_Py_hashtable_t *domains, *size += _Py_hashtable_size(traces); return 0; } - - -/*[clinic input] -_tracemalloc.get_tracemalloc_memory - -Get the memory usage in bytes of the tracemalloc module. - -This memory is used internally to trace memory allocations. -[clinic start generated code]*/ - -static PyObject * -_tracemalloc_get_tracemalloc_memory_impl(PyObject *module) -/*[clinic end generated code: output=e3f14e280a55f5aa input=5d919c0f4d5132ad]*/ -{ - size_t size; - - size = _Py_hashtable_size(tracemalloc_tracebacks); - size += _Py_hashtable_size(tracemalloc_filenames); - - TABLES_LOCK(); - size += _Py_hashtable_size(tracemalloc_traces); + + +/*[clinic input] +_tracemalloc.get_tracemalloc_memory + +Get the memory usage in bytes of the tracemalloc module. + +This memory is used internally to trace memory allocations. +[clinic start generated code]*/ + +static PyObject * +_tracemalloc_get_tracemalloc_memory_impl(PyObject *module) +/*[clinic end generated code: output=e3f14e280a55f5aa input=5d919c0f4d5132ad]*/ +{ + size_t size; + + size = _Py_hashtable_size(tracemalloc_tracebacks); + size += _Py_hashtable_size(tracemalloc_filenames); + + TABLES_LOCK(); + size += _Py_hashtable_size(tracemalloc_traces); _Py_hashtable_foreach(tracemalloc_domains, tracemalloc_get_tracemalloc_memory_cb, &size); - TABLES_UNLOCK(); - - return PyLong_FromSize_t(size); -} - - - -/*[clinic input] -_tracemalloc.get_traced_memory - -Get the current size and peak size of memory blocks traced by tracemalloc. - -Returns a tuple: (current: int, peak: int). -[clinic start generated code]*/ - -static PyObject * -_tracemalloc_get_traced_memory_impl(PyObject *module) -/*[clinic end generated code: output=5b167189adb9e782 input=61ddb5478400ff66]*/ -{ - Py_ssize_t size, peak_size; - + TABLES_UNLOCK(); + + return PyLong_FromSize_t(size); +} + + + +/*[clinic input] +_tracemalloc.get_traced_memory + +Get the current size and peak size of memory blocks traced by tracemalloc. + +Returns a tuple: (current: int, peak: int). +[clinic start generated code]*/ + +static PyObject * +_tracemalloc_get_traced_memory_impl(PyObject *module) +/*[clinic end generated code: output=5b167189adb9e782 input=61ddb5478400ff66]*/ +{ + Py_ssize_t size, peak_size; + if (!_Py_tracemalloc_config.tracing) - return Py_BuildValue("ii", 0, 0); - - TABLES_LOCK(); - size = tracemalloc_traced_memory; - peak_size = tracemalloc_peak_traced_memory; - TABLES_UNLOCK(); - - return Py_BuildValue("nn", size, peak_size); -} - + return Py_BuildValue("ii", 0, 0); + + TABLES_LOCK(); + size = tracemalloc_traced_memory; + peak_size = tracemalloc_peak_traced_memory; + TABLES_UNLOCK(); + + return Py_BuildValue("nn", size, peak_size); +} + /*[clinic input] _tracemalloc.reset_peak - + Set the peak size of memory blocks traced by tracemalloc to the current size. Do nothing if the tracemalloc module is not tracing memory allocations. @@ -1664,107 +1664,107 @@ _tracemalloc_reset_peak_impl(PyObject *module) } -static PyMethodDef module_methods[] = { - _TRACEMALLOC_IS_TRACING_METHODDEF - _TRACEMALLOC_CLEAR_TRACES_METHODDEF - _TRACEMALLOC__GET_TRACES_METHODDEF - _TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF - _TRACEMALLOC_START_METHODDEF - _TRACEMALLOC_STOP_METHODDEF - _TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF - _TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF - _TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF +static PyMethodDef module_methods[] = { + _TRACEMALLOC_IS_TRACING_METHODDEF + _TRACEMALLOC_CLEAR_TRACES_METHODDEF + _TRACEMALLOC__GET_TRACES_METHODDEF + _TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF + _TRACEMALLOC_START_METHODDEF + _TRACEMALLOC_STOP_METHODDEF + _TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF + _TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF + _TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF _TRACEMALLOC_RESET_PEAK_METHODDEF - /* sentinel */ - {NULL, NULL} -}; - -PyDoc_STRVAR(module_doc, -"Debug module to trace memory blocks allocated by Python."); - -static struct PyModuleDef module_def = { - PyModuleDef_HEAD_INIT, - "_tracemalloc", - module_doc, - 0, /* non-negative size to be able to unload the module */ - module_methods, - NULL, -}; - -PyMODINIT_FUNC -PyInit__tracemalloc(void) -{ - PyObject *m; - m = PyModule_Create(&module_def); - if (m == NULL) - return NULL; - + /* sentinel */ + {NULL, NULL} +}; + +PyDoc_STRVAR(module_doc, +"Debug module to trace memory blocks allocated by Python."); + +static struct PyModuleDef module_def = { + PyModuleDef_HEAD_INIT, + "_tracemalloc", + module_doc, + 0, /* non-negative size to be able to unload the module */ + module_methods, + NULL, +}; + +PyMODINIT_FUNC +PyInit__tracemalloc(void) +{ + PyObject *m; + m = PyModule_Create(&module_def); + if (m == NULL) + return NULL; + if (tracemalloc_init() < 0) { Py_DECREF(m); - return NULL; - } - - return m; -} - - -int -_PyTraceMalloc_Init(int nframe) -{ - assert(PyGILState_Check()); - if (nframe == 0) { - return 0; - } - return tracemalloc_start(nframe); -} - - -void -_PyTraceMalloc_Fini(void) -{ - assert(PyGILState_Check()); - tracemalloc_deinit(); -} - -int -PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, - size_t size) -{ - int res; - PyGILState_STATE gil_state; - + return NULL; + } + + return m; +} + + +int +_PyTraceMalloc_Init(int nframe) +{ + assert(PyGILState_Check()); + if (nframe == 0) { + return 0; + } + return tracemalloc_start(nframe); +} + + +void +_PyTraceMalloc_Fini(void) +{ + assert(PyGILState_Check()); + tracemalloc_deinit(); +} + +int +PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, + size_t size) +{ + int res; + PyGILState_STATE gil_state; + if (!_Py_tracemalloc_config.tracing) { - /* tracemalloc is not tracing: do nothing */ - return -2; - } - - gil_state = PyGILState_Ensure(); - - TABLES_LOCK(); - res = tracemalloc_add_trace(domain, ptr, size); - TABLES_UNLOCK(); - - PyGILState_Release(gil_state); - return res; -} - - -int -PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) -{ + /* tracemalloc is not tracing: do nothing */ + return -2; + } + + gil_state = PyGILState_Ensure(); + + TABLES_LOCK(); + res = tracemalloc_add_trace(domain, ptr, size); + TABLES_UNLOCK(); + + PyGILState_Release(gil_state); + return res; +} + + +int +PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) +{ if (!_Py_tracemalloc_config.tracing) { - /* tracemalloc is not tracing: do nothing */ - return -2; - } - - TABLES_LOCK(); - tracemalloc_remove_trace(domain, ptr); - TABLES_UNLOCK(); - - return 0; -} - - + /* tracemalloc is not tracing: do nothing */ + return -2; + } + + TABLES_LOCK(); + tracemalloc_remove_trace(domain, ptr); + TABLES_UNLOCK(); + + return 0; +} + + /* If the object memory block is already traced, update its trace with the current Python traceback. @@ -1808,14 +1808,14 @@ _PyTraceMalloc_NewReference(PyObject *op) } -PyObject* -_PyTraceMalloc_GetTraceback(unsigned int domain, uintptr_t ptr) -{ - traceback_t *traceback; - - traceback = tracemalloc_get_traceback(domain, ptr); - if (traceback == NULL) - Py_RETURN_NONE; - - return traceback_to_pyobject(traceback, NULL); -} +PyObject* +_PyTraceMalloc_GetTraceback(unsigned int domain, uintptr_t ptr) +{ + traceback_t *traceback; + + traceback = tracemalloc_get_traceback(domain, ptr); + if (traceback == NULL) + Py_RETURN_NONE; + + return traceback_to_pyobject(traceback, NULL); +} diff --git a/contrib/tools/python3/src/Modules/_weakref.c b/contrib/tools/python3/src/Modules/_weakref.c index e33cba2a3dd..0ffe420bff9 100644 --- a/contrib/tools/python3/src/Modules/_weakref.c +++ b/contrib/tools/python3/src/Modules/_weakref.c @@ -1,142 +1,142 @@ -#include "Python.h" +#include "Python.h" #include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR - - -#define GET_WEAKREFS_LISTPTR(o) \ + + +#define GET_WEAKREFS_LISTPTR(o) \ ((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o)) - -/*[clinic input] -module _weakref -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ffec73b85846596d]*/ - -#include "clinic/_weakref.c.h" - -/*[clinic input] - -_weakref.getweakrefcount -> Py_ssize_t - - object: object - / - -Return the number of weak references to 'object'. -[clinic start generated code]*/ - -static Py_ssize_t -_weakref_getweakrefcount_impl(PyObject *module, PyObject *object) -/*[clinic end generated code: output=301806d59558ff3e input=cedb69711b6a2507]*/ -{ - PyWeakReference **list; - - if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) - return 0; - - list = GET_WEAKREFS_LISTPTR(object); - return _PyWeakref_GetWeakrefCount(*list); -} - - -static int -is_dead_weakref(PyObject *value) -{ - if (!PyWeakref_Check(value)) { - PyErr_SetString(PyExc_TypeError, "not a weakref"); - return -1; - } - return PyWeakref_GET_OBJECT(value) == Py_None; -} - -/*[clinic input] - -_weakref._remove_dead_weakref -> object - - dct: object(subclass_of='&PyDict_Type') - key: object - / - -Atomically remove key from dict if it points to a dead weakref. -[clinic start generated code]*/ - -static PyObject * -_weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, - PyObject *key) -/*[clinic end generated code: output=d9ff53061fcb875c input=19fc91f257f96a1d]*/ -{ - if (_PyDict_DelItemIf(dct, key, is_dead_weakref) < 0) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) - /* This function is meant to allow safe weak-value dicts - with GC in another thread (see issue #28427), so it's - ok if the key doesn't exist anymore. - */ - PyErr_Clear(); - else - return NULL; - } - Py_RETURN_NONE; -} - - -PyDoc_STRVAR(weakref_getweakrefs__doc__, -"getweakrefs(object) -- return a list of all weak reference objects\n" -"that point to 'object'."); - -static PyObject * -weakref_getweakrefs(PyObject *self, PyObject *object) -{ - PyObject *result = NULL; - - if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { - PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); - Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); - - result = PyList_New(count); - if (result != NULL) { - PyWeakReference *current = *list; - Py_ssize_t i; - for (i = 0; i < count; ++i) { - PyList_SET_ITEM(result, i, (PyObject *) current); - Py_INCREF(current); - current = current->wr_next; - } - } - } - else { - result = PyList_New(0); - } - return result; -} - - -PyDoc_STRVAR(weakref_proxy__doc__, -"proxy(object[, callback]) -- create a proxy object that weakly\n" -"references 'object'. 'callback', if given, is called with a\n" -"reference to the proxy when 'object' is about to be finalized."); - -static PyObject * -weakref_proxy(PyObject *self, PyObject *args) -{ - PyObject *object; - PyObject *callback = NULL; - PyObject *result = NULL; - - if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) { - result = PyWeakref_NewProxy(object, callback); - } - return result; -} - - -static PyMethodDef -weakref_functions[] = { - _WEAKREF_GETWEAKREFCOUNT_METHODDEF - _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF - {"getweakrefs", weakref_getweakrefs, METH_O, - weakref_getweakrefs__doc__}, - {"proxy", weakref_proxy, METH_VARARGS, - weakref_proxy__doc__}, - {NULL, NULL, 0, NULL} -}; - + +/*[clinic input] +module _weakref +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ffec73b85846596d]*/ + +#include "clinic/_weakref.c.h" + +/*[clinic input] + +_weakref.getweakrefcount -> Py_ssize_t + + object: object + / + +Return the number of weak references to 'object'. +[clinic start generated code]*/ + +static Py_ssize_t +_weakref_getweakrefcount_impl(PyObject *module, PyObject *object) +/*[clinic end generated code: output=301806d59558ff3e input=cedb69711b6a2507]*/ +{ + PyWeakReference **list; + + if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) + return 0; + + list = GET_WEAKREFS_LISTPTR(object); + return _PyWeakref_GetWeakrefCount(*list); +} + + +static int +is_dead_weakref(PyObject *value) +{ + if (!PyWeakref_Check(value)) { + PyErr_SetString(PyExc_TypeError, "not a weakref"); + return -1; + } + return PyWeakref_GET_OBJECT(value) == Py_None; +} + +/*[clinic input] + +_weakref._remove_dead_weakref -> object + + dct: object(subclass_of='&PyDict_Type') + key: object + / + +Atomically remove key from dict if it points to a dead weakref. +[clinic start generated code]*/ + +static PyObject * +_weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, + PyObject *key) +/*[clinic end generated code: output=d9ff53061fcb875c input=19fc91f257f96a1d]*/ +{ + if (_PyDict_DelItemIf(dct, key, is_dead_weakref) < 0) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) + /* This function is meant to allow safe weak-value dicts + with GC in another thread (see issue #28427), so it's + ok if the key doesn't exist anymore. + */ + PyErr_Clear(); + else + return NULL; + } + Py_RETURN_NONE; +} + + +PyDoc_STRVAR(weakref_getweakrefs__doc__, +"getweakrefs(object) -- return a list of all weak reference objects\n" +"that point to 'object'."); + +static PyObject * +weakref_getweakrefs(PyObject *self, PyObject *object) +{ + PyObject *result = NULL; + + if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { + PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); + Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); + + result = PyList_New(count); + if (result != NULL) { + PyWeakReference *current = *list; + Py_ssize_t i; + for (i = 0; i < count; ++i) { + PyList_SET_ITEM(result, i, (PyObject *) current); + Py_INCREF(current); + current = current->wr_next; + } + } + } + else { + result = PyList_New(0); + } + return result; +} + + +PyDoc_STRVAR(weakref_proxy__doc__, +"proxy(object[, callback]) -- create a proxy object that weakly\n" +"references 'object'. 'callback', if given, is called with a\n" +"reference to the proxy when 'object' is about to be finalized."); + +static PyObject * +weakref_proxy(PyObject *self, PyObject *args) +{ + PyObject *object; + PyObject *callback = NULL; + PyObject *result = NULL; + + if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) { + result = PyWeakref_NewProxy(object, callback); + } + return result; +} + + +static PyMethodDef +weakref_functions[] = { + _WEAKREF_GETWEAKREFCOUNT_METHODDEF + _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF + {"getweakrefs", weakref_getweakrefs, METH_O, + weakref_getweakrefs__doc__}, + {"proxy", weakref_proxy, METH_VARARGS, + weakref_proxy__doc__}, + {NULL, NULL, 0, NULL} +}; + static int weakref_exec(PyObject *module) { @@ -163,7 +163,7 @@ weakref_exec(PyObject *module) Py_DECREF(&_PyWeakref_CallableProxyType); return -1; } - + return 0; } @@ -172,20 +172,20 @@ static struct PyModuleDef_Slot weakref_slots[] = { {0, NULL} }; -static struct PyModuleDef weakrefmodule = { - PyModuleDef_HEAD_INIT, - "_weakref", - "Weak-reference support module.", +static struct PyModuleDef weakrefmodule = { + PyModuleDef_HEAD_INIT, + "_weakref", + "Weak-reference support module.", 0, - weakref_functions, + weakref_functions, weakref_slots, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__weakref(void) -{ + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__weakref(void) +{ return PyModuleDef_Init(&weakrefmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/_winapi.c b/contrib/tools/python3/src/Modules/_winapi.c index 5b7f075722e..d66c6c5dea6 100644 --- a/contrib/tools/python3/src/Modules/_winapi.c +++ b/contrib/tools/python3/src/Modules/_winapi.c @@ -1,193 +1,193 @@ -/* - * Support routines from the Windows API - * - * This module was originally created by merging PC/_subprocess.c with - * Modules/_multiprocessing/win32_functions.c. - * - * Copyright (c) 2004 by Fredrik Lundh - * Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com - * Copyright (c) 2004 by Peter Astrand - * - * By obtaining, using, and/or copying this software and/or its - * associated documentation, you agree that you have read, understood, - * and will comply with the following terms and conditions: - * - * Permission to use, copy, modify, and distribute this software and - * its associated documentation for any purpose and without fee is - * hereby granted, provided that the above copyright notice appears in - * all copies, and that both that copyright notice and this permission - * notice appear in supporting documentation, and that the name of the - * authors not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. - * - * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -/* Licensed to PSF under a Contributor Agreement. */ +/* + * Support routines from the Windows API + * + * This module was originally created by merging PC/_subprocess.c with + * Modules/_multiprocessing/win32_functions.c. + * + * Copyright (c) 2004 by Fredrik Lundh + * Copyright (c) 2004 by Secret Labs AB, http://www.pythonware.com + * Copyright (c) 2004 by Peter Astrand + * + * By obtaining, using, and/or copying this software and/or its + * associated documentation, you agree that you have read, understood, + * and will comply with the following terms and conditions: + * + * Permission to use, copy, modify, and distribute this software and + * its associated documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice appears in + * all copies, and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * authors not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. + * + * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* Licensed to PSF under a Contributor Agreement. */ /* See https://www.python.org/2.4/license for licensing details. */ - -#include "Python.h" + +#include "Python.h" #include "structmember.h" // PyMemberDef - -#define WINDOWS_LEAN_AND_MEAN -#include "windows.h" -#include -#include -#include "winreparse.h" - -#if defined(MS_WIN32) && !defined(MS_WIN64) -#define HANDLE_TO_PYNUM(handle) \ - PyLong_FromUnsignedLong((unsigned long) handle) -#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLong(obj)) -#define F_POINTER "k" -#define T_POINTER T_ULONG -#else -#define HANDLE_TO_PYNUM(handle) \ - PyLong_FromUnsignedLongLong((unsigned long long) handle) -#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLongLong(obj)) -#define F_POINTER "K" -#define T_POINTER T_ULONGLONG -#endif - -#define F_HANDLE F_POINTER -#define F_DWORD "k" - -#define T_HANDLE T_POINTER - -/* Grab CancelIoEx dynamically from kernel32 */ -static int has_CancelIoEx = -1; -static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED); - -static int -check_CancelIoEx() -{ - if (has_CancelIoEx == -1) - { - HINSTANCE hKernel32 = GetModuleHandle("KERNEL32"); - * (FARPROC *) &Py_CancelIoEx = GetProcAddress(hKernel32, - "CancelIoEx"); - has_CancelIoEx = (Py_CancelIoEx != NULL); - } - return has_CancelIoEx; -} - - -/* - * A Python object wrapping an OVERLAPPED structure and other useful data - * for overlapped I/O - */ - -typedef struct { - PyObject_HEAD - OVERLAPPED overlapped; - /* For convenience, we store the file handle too */ - HANDLE handle; - /* Whether there's I/O in flight */ - int pending; - /* Whether I/O completed successfully */ - int completed; - /* Buffer used for reading (optional) */ - PyObject *read_buffer; - /* Buffer used for writing (optional) */ - Py_buffer write_buffer; -} OverlappedObject; - -static void -overlapped_dealloc(OverlappedObject *self) -{ - DWORD bytes; - int err = GetLastError(); - - if (self->pending) { - if (check_CancelIoEx() && - Py_CancelIoEx(self->handle, &self->overlapped) && - GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE)) - { - /* The operation is no longer pending -- nothing to do. */ - } - else if (_Py_IsFinalizing()) - { - /* The operation is still pending -- give a warning. This - will probably only happen on Windows XP. */ - PyErr_SetString(PyExc_RuntimeError, - "I/O operations still in flight while destroying " - "Overlapped object, the process may crash"); - PyErr_WriteUnraisable(NULL); - } - else - { - /* The operation is still pending, but the process is - probably about to exit, so we need not worry too much - about memory leaks. Leaking self prevents a potential - crash. This can happen when a daemon thread is cleaned - up at exit -- see #19565. We only expect to get here - on Windows XP. */ - CloseHandle(self->overlapped.hEvent); - SetLastError(err); - return; - } - } - - CloseHandle(self->overlapped.hEvent); - SetLastError(err); - if (self->write_buffer.obj) - PyBuffer_Release(&self->write_buffer); - Py_CLEAR(self->read_buffer); - PyObject_Del(self); -} - -/*[clinic input] -module _winapi -class _winapi.Overlapped "OverlappedObject *" "&WinApiOverlappedType" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c13d3f5fd1dabb84]*/ - -/*[python input] -def create_converter(type_, format_unit): - name = type_ + '_converter' - # registered upon creation by CConverter's metaclass - type(name, (CConverter,), {'type': type_, 'format_unit': format_unit}) - -# format unit differs between platforms for these -create_converter('HANDLE', '" F_HANDLE "') -create_converter('HMODULE', '" F_HANDLE "') -create_converter('LPSECURITY_ATTRIBUTES', '" F_POINTER "') + +#define WINDOWS_LEAN_AND_MEAN +#include "windows.h" +#include +#include +#include "winreparse.h" + +#if defined(MS_WIN32) && !defined(MS_WIN64) +#define HANDLE_TO_PYNUM(handle) \ + PyLong_FromUnsignedLong((unsigned long) handle) +#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLong(obj)) +#define F_POINTER "k" +#define T_POINTER T_ULONG +#else +#define HANDLE_TO_PYNUM(handle) \ + PyLong_FromUnsignedLongLong((unsigned long long) handle) +#define PYNUM_TO_HANDLE(obj) ((HANDLE)PyLong_AsUnsignedLongLong(obj)) +#define F_POINTER "K" +#define T_POINTER T_ULONGLONG +#endif + +#define F_HANDLE F_POINTER +#define F_DWORD "k" + +#define T_HANDLE T_POINTER + +/* Grab CancelIoEx dynamically from kernel32 */ +static int has_CancelIoEx = -1; +static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED); + +static int +check_CancelIoEx() +{ + if (has_CancelIoEx == -1) + { + HINSTANCE hKernel32 = GetModuleHandle("KERNEL32"); + * (FARPROC *) &Py_CancelIoEx = GetProcAddress(hKernel32, + "CancelIoEx"); + has_CancelIoEx = (Py_CancelIoEx != NULL); + } + return has_CancelIoEx; +} + + +/* + * A Python object wrapping an OVERLAPPED structure and other useful data + * for overlapped I/O + */ + +typedef struct { + PyObject_HEAD + OVERLAPPED overlapped; + /* For convenience, we store the file handle too */ + HANDLE handle; + /* Whether there's I/O in flight */ + int pending; + /* Whether I/O completed successfully */ + int completed; + /* Buffer used for reading (optional) */ + PyObject *read_buffer; + /* Buffer used for writing (optional) */ + Py_buffer write_buffer; +} OverlappedObject; + +static void +overlapped_dealloc(OverlappedObject *self) +{ + DWORD bytes; + int err = GetLastError(); + + if (self->pending) { + if (check_CancelIoEx() && + Py_CancelIoEx(self->handle, &self->overlapped) && + GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE)) + { + /* The operation is no longer pending -- nothing to do. */ + } + else if (_Py_IsFinalizing()) + { + /* The operation is still pending -- give a warning. This + will probably only happen on Windows XP. */ + PyErr_SetString(PyExc_RuntimeError, + "I/O operations still in flight while destroying " + "Overlapped object, the process may crash"); + PyErr_WriteUnraisable(NULL); + } + else + { + /* The operation is still pending, but the process is + probably about to exit, so we need not worry too much + about memory leaks. Leaking self prevents a potential + crash. This can happen when a daemon thread is cleaned + up at exit -- see #19565. We only expect to get here + on Windows XP. */ + CloseHandle(self->overlapped.hEvent); + SetLastError(err); + return; + } + } + + CloseHandle(self->overlapped.hEvent); + SetLastError(err); + if (self->write_buffer.obj) + PyBuffer_Release(&self->write_buffer); + Py_CLEAR(self->read_buffer); + PyObject_Del(self); +} + +/*[clinic input] +module _winapi +class _winapi.Overlapped "OverlappedObject *" "&WinApiOverlappedType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c13d3f5fd1dabb84]*/ + +/*[python input] +def create_converter(type_, format_unit): + name = type_ + '_converter' + # registered upon creation by CConverter's metaclass + type(name, (CConverter,), {'type': type_, 'format_unit': format_unit}) + +# format unit differs between platforms for these +create_converter('HANDLE', '" F_HANDLE "') +create_converter('HMODULE', '" F_HANDLE "') +create_converter('LPSECURITY_ATTRIBUTES', '" F_POINTER "') create_converter('LPCVOID', '" F_POINTER "') - -create_converter('BOOL', 'i') # F_BOOL used previously (always 'i') -create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter) -create_converter('LPCTSTR', 's') + +create_converter('BOOL', 'i') # F_BOOL used previously (always 'i') +create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter) +create_converter('LPCTSTR', 's') create_converter('LPCWSTR', 'u') -create_converter('LPWSTR', 'u') -create_converter('UINT', 'I') # F_UINT used previously (always 'I') - -class HANDLE_return_converter(CReturnConverter): - type = 'HANDLE' - - def render(self, function, data): - self.declare(data) - self.err_occurred_if("_return_value == INVALID_HANDLE_VALUE", data) - data.return_conversion.append( - 'if (_return_value == NULL) {\n Py_RETURN_NONE;\n}\n') - data.return_conversion.append( - 'return_value = HANDLE_TO_PYNUM(_return_value);\n') - -class DWORD_return_converter(CReturnConverter): - type = 'DWORD' - - def render(self, function, data): - self.declare(data) - self.err_occurred_if("_return_value == PY_DWORD_MAX", data) - data.return_conversion.append( - 'return_value = Py_BuildValue("k", _return_value);\n') +create_converter('LPWSTR', 'u') +create_converter('UINT', 'I') # F_UINT used previously (always 'I') + +class HANDLE_return_converter(CReturnConverter): + type = 'HANDLE' + + def render(self, function, data): + self.declare(data) + self.err_occurred_if("_return_value == INVALID_HANDLE_VALUE", data) + data.return_conversion.append( + 'if (_return_value == NULL) {\n Py_RETURN_NONE;\n}\n') + data.return_conversion.append( + 'return_value = HANDLE_TO_PYNUM(_return_value);\n') + +class DWORD_return_converter(CReturnConverter): + type = 'DWORD' + + def render(self, function, data): + self.declare(data) + self.err_occurred_if("_return_value == PY_DWORD_MAX", data) + data.return_conversion.append( + 'return_value = Py_BuildValue("k", _return_value);\n') class LPVOID_return_converter(CReturnConverter): type = 'LPVOID' @@ -197,291 +197,291 @@ class LPVOID_return_converter(CReturnConverter): self.err_occurred_if("_return_value == NULL", data) data.return_conversion.append( 'return_value = HANDLE_TO_PYNUM(_return_value);\n') -[python start generated code]*/ +[python start generated code]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=79464c61a31ae932]*/ - -#include "clinic/_winapi.c.h" - -/*[clinic input] -_winapi.Overlapped.GetOverlappedResult - - wait: bool - / -[clinic start generated code]*/ - -static PyObject * -_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait) -/*[clinic end generated code: output=bdd0c1ed6518cd03 input=194505ee8e0e3565]*/ -{ - BOOL res; - DWORD transferred = 0; - DWORD err; - - Py_BEGIN_ALLOW_THREADS - res = GetOverlappedResult(self->handle, &self->overlapped, &transferred, - wait != 0); - Py_END_ALLOW_THREADS - - err = res ? ERROR_SUCCESS : GetLastError(); - switch (err) { - case ERROR_SUCCESS: - case ERROR_MORE_DATA: - case ERROR_OPERATION_ABORTED: - self->completed = 1; - self->pending = 0; - break; - case ERROR_IO_INCOMPLETE: - break; - default: - self->pending = 0; - return PyErr_SetExcFromWindowsErr(PyExc_OSError, err); - } - if (self->completed && self->read_buffer != NULL) { - assert(PyBytes_CheckExact(self->read_buffer)); - if (transferred != PyBytes_GET_SIZE(self->read_buffer) && - _PyBytes_Resize(&self->read_buffer, transferred)) - return NULL; - } - return Py_BuildValue("II", (unsigned) transferred, (unsigned) err); -} - -/*[clinic input] -_winapi.Overlapped.getbuffer -[clinic start generated code]*/ - -static PyObject * -_winapi_Overlapped_getbuffer_impl(OverlappedObject *self) -/*[clinic end generated code: output=95a3eceefae0f748 input=347fcfd56b4ceabd]*/ -{ - PyObject *res; - if (!self->completed) { - PyErr_SetString(PyExc_ValueError, - "can't get read buffer before GetOverlappedResult() " - "signals the operation completed"); - return NULL; - } - res = self->read_buffer ? self->read_buffer : Py_None; - Py_INCREF(res); - return res; -} - -/*[clinic input] -_winapi.Overlapped.cancel -[clinic start generated code]*/ - -static PyObject * -_winapi_Overlapped_cancel_impl(OverlappedObject *self) -/*[clinic end generated code: output=fcb9ab5df4ebdae5 input=cbf3da142290039f]*/ -{ - BOOL res = TRUE; - - if (self->pending) { - Py_BEGIN_ALLOW_THREADS - if (check_CancelIoEx()) - res = Py_CancelIoEx(self->handle, &self->overlapped); - else - res = CancelIo(self->handle); - Py_END_ALLOW_THREADS - } - - /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */ - if (!res && GetLastError() != ERROR_NOT_FOUND) - return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); - self->pending = 0; - Py_RETURN_NONE; -} - -static PyMethodDef overlapped_methods[] = { - _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF - _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF - _WINAPI_OVERLAPPED_CANCEL_METHODDEF - {NULL} -}; - -static PyMemberDef overlapped_members[] = { - {"event", T_HANDLE, - offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent), - READONLY, "overlapped event handle"}, - {NULL} -}; - -PyTypeObject WinApiOverlappedType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_winapi.Overlapped", - /* tp_basicsize */ sizeof(OverlappedObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor) overlapped_dealloc, + +#include "clinic/_winapi.c.h" + +/*[clinic input] +_winapi.Overlapped.GetOverlappedResult + + wait: bool + / +[clinic start generated code]*/ + +static PyObject * +_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait) +/*[clinic end generated code: output=bdd0c1ed6518cd03 input=194505ee8e0e3565]*/ +{ + BOOL res; + DWORD transferred = 0; + DWORD err; + + Py_BEGIN_ALLOW_THREADS + res = GetOverlappedResult(self->handle, &self->overlapped, &transferred, + wait != 0); + Py_END_ALLOW_THREADS + + err = res ? ERROR_SUCCESS : GetLastError(); + switch (err) { + case ERROR_SUCCESS: + case ERROR_MORE_DATA: + case ERROR_OPERATION_ABORTED: + self->completed = 1; + self->pending = 0; + break; + case ERROR_IO_INCOMPLETE: + break; + default: + self->pending = 0; + return PyErr_SetExcFromWindowsErr(PyExc_OSError, err); + } + if (self->completed && self->read_buffer != NULL) { + assert(PyBytes_CheckExact(self->read_buffer)); + if (transferred != PyBytes_GET_SIZE(self->read_buffer) && + _PyBytes_Resize(&self->read_buffer, transferred)) + return NULL; + } + return Py_BuildValue("II", (unsigned) transferred, (unsigned) err); +} + +/*[clinic input] +_winapi.Overlapped.getbuffer +[clinic start generated code]*/ + +static PyObject * +_winapi_Overlapped_getbuffer_impl(OverlappedObject *self) +/*[clinic end generated code: output=95a3eceefae0f748 input=347fcfd56b4ceabd]*/ +{ + PyObject *res; + if (!self->completed) { + PyErr_SetString(PyExc_ValueError, + "can't get read buffer before GetOverlappedResult() " + "signals the operation completed"); + return NULL; + } + res = self->read_buffer ? self->read_buffer : Py_None; + Py_INCREF(res); + return res; +} + +/*[clinic input] +_winapi.Overlapped.cancel +[clinic start generated code]*/ + +static PyObject * +_winapi_Overlapped_cancel_impl(OverlappedObject *self) +/*[clinic end generated code: output=fcb9ab5df4ebdae5 input=cbf3da142290039f]*/ +{ + BOOL res = TRUE; + + if (self->pending) { + Py_BEGIN_ALLOW_THREADS + if (check_CancelIoEx()) + res = Py_CancelIoEx(self->handle, &self->overlapped); + else + res = CancelIo(self->handle); + Py_END_ALLOW_THREADS + } + + /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */ + if (!res && GetLastError() != ERROR_NOT_FOUND) + return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); + self->pending = 0; + Py_RETURN_NONE; +} + +static PyMethodDef overlapped_methods[] = { + _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF + _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF + _WINAPI_OVERLAPPED_CANCEL_METHODDEF + {NULL} +}; + +static PyMemberDef overlapped_members[] = { + {"event", T_HANDLE, + offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent), + READONLY, "overlapped event handle"}, + {NULL} +}; + +PyTypeObject WinApiOverlappedType = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_winapi.Overlapped", + /* tp_basicsize */ sizeof(OverlappedObject), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor) overlapped_dealloc, /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, + /* tp_getattr */ 0, + /* tp_setattr */ 0, /* tp_as_async */ 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 */ Py_TPFLAGS_DEFAULT, - /* tp_doc */ "OVERLAPPED structure wrapper", - /* tp_traverse */ 0, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ overlapped_methods, - /* tp_members */ overlapped_members, - /* tp_getset */ 0, - /* tp_base */ 0, - /* tp_dict */ 0, - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ 0, -}; - -static OverlappedObject * -new_overlapped(HANDLE handle) -{ - OverlappedObject *self; - - self = PyObject_New(OverlappedObject, &WinApiOverlappedType); - if (!self) - return NULL; - self->handle = handle; - self->read_buffer = NULL; - self->pending = 0; - self->completed = 0; - memset(&self->overlapped, 0, sizeof(OVERLAPPED)); - memset(&self->write_buffer, 0, sizeof(Py_buffer)); - /* Manual reset, initially non-signalled */ - self->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - return self; -} - -/* -------------------------------------------------------------------- */ -/* windows API functions */ - -/*[clinic input] -_winapi.CloseHandle - - handle: HANDLE - / - -Close handle. -[clinic start generated code]*/ - -static PyObject * -_winapi_CloseHandle_impl(PyObject *module, HANDLE handle) -/*[clinic end generated code: output=7ad37345f07bd782 input=7f0e4ac36e0352b8]*/ -{ - BOOL success; - - Py_BEGIN_ALLOW_THREADS - success = CloseHandle(handle); - Py_END_ALLOW_THREADS - - if (!success) - return PyErr_SetFromWindowsErr(0); - - Py_RETURN_NONE; -} - -/*[clinic input] -_winapi.ConnectNamedPipe - - handle: HANDLE - overlapped as use_overlapped: bool(accept={int}) = False -[clinic start generated code]*/ - -static PyObject * -_winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, - int use_overlapped) -/*[clinic end generated code: output=335a0e7086800671 input=34f937c1c86e5e68]*/ -{ - BOOL success; - OverlappedObject *overlapped = NULL; - - if (use_overlapped) { - overlapped = new_overlapped(handle); - if (!overlapped) - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - success = ConnectNamedPipe(handle, - overlapped ? &overlapped->overlapped : NULL); - Py_END_ALLOW_THREADS - - if (overlapped) { - int err = GetLastError(); - /* Overlapped ConnectNamedPipe never returns a success code */ - assert(success == 0); - if (err == ERROR_IO_PENDING) - overlapped->pending = 1; - else if (err == ERROR_PIPE_CONNECTED) - SetEvent(overlapped->overlapped.hEvent); - else { - Py_DECREF(overlapped); - return PyErr_SetFromWindowsErr(err); - } - return (PyObject *) overlapped; - } - if (!success) - return PyErr_SetFromWindowsErr(0); - - Py_RETURN_NONE; -} - -/*[clinic input] -_winapi.CreateFile -> HANDLE - - file_name: LPCTSTR - desired_access: DWORD - share_mode: DWORD - security_attributes: LPSECURITY_ATTRIBUTES - creation_disposition: DWORD - flags_and_attributes: DWORD - template_file: HANDLE - / -[clinic start generated code]*/ - -static HANDLE -_winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name, - DWORD desired_access, DWORD share_mode, - LPSECURITY_ATTRIBUTES security_attributes, - DWORD creation_disposition, - DWORD flags_and_attributes, HANDLE template_file) -/*[clinic end generated code: output=417ddcebfc5a3d53 input=6423c3e40372dbd5]*/ -{ - HANDLE handle; - + /* 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 */ Py_TPFLAGS_DEFAULT, + /* tp_doc */ "OVERLAPPED structure wrapper", + /* tp_traverse */ 0, + /* tp_clear */ 0, + /* tp_richcompare */ 0, + /* tp_weaklistoffset */ 0, + /* tp_iter */ 0, + /* tp_iternext */ 0, + /* tp_methods */ overlapped_methods, + /* tp_members */ overlapped_members, + /* tp_getset */ 0, + /* tp_base */ 0, + /* tp_dict */ 0, + /* tp_descr_get */ 0, + /* tp_descr_set */ 0, + /* tp_dictoffset */ 0, + /* tp_init */ 0, + /* tp_alloc */ 0, + /* tp_new */ 0, +}; + +static OverlappedObject * +new_overlapped(HANDLE handle) +{ + OverlappedObject *self; + + self = PyObject_New(OverlappedObject, &WinApiOverlappedType); + if (!self) + return NULL; + self->handle = handle; + self->read_buffer = NULL; + self->pending = 0; + self->completed = 0; + memset(&self->overlapped, 0, sizeof(OVERLAPPED)); + memset(&self->write_buffer, 0, sizeof(Py_buffer)); + /* Manual reset, initially non-signalled */ + self->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + return self; +} + +/* -------------------------------------------------------------------- */ +/* windows API functions */ + +/*[clinic input] +_winapi.CloseHandle + + handle: HANDLE + / + +Close handle. +[clinic start generated code]*/ + +static PyObject * +_winapi_CloseHandle_impl(PyObject *module, HANDLE handle) +/*[clinic end generated code: output=7ad37345f07bd782 input=7f0e4ac36e0352b8]*/ +{ + BOOL success; + + Py_BEGIN_ALLOW_THREADS + success = CloseHandle(handle); + Py_END_ALLOW_THREADS + + if (!success) + return PyErr_SetFromWindowsErr(0); + + Py_RETURN_NONE; +} + +/*[clinic input] +_winapi.ConnectNamedPipe + + handle: HANDLE + overlapped as use_overlapped: bool(accept={int}) = False +[clinic start generated code]*/ + +static PyObject * +_winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, + int use_overlapped) +/*[clinic end generated code: output=335a0e7086800671 input=34f937c1c86e5e68]*/ +{ + BOOL success; + OverlappedObject *overlapped = NULL; + + if (use_overlapped) { + overlapped = new_overlapped(handle); + if (!overlapped) + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + success = ConnectNamedPipe(handle, + overlapped ? &overlapped->overlapped : NULL); + Py_END_ALLOW_THREADS + + if (overlapped) { + int err = GetLastError(); + /* Overlapped ConnectNamedPipe never returns a success code */ + assert(success == 0); + if (err == ERROR_IO_PENDING) + overlapped->pending = 1; + else if (err == ERROR_PIPE_CONNECTED) + SetEvent(overlapped->overlapped.hEvent); + else { + Py_DECREF(overlapped); + return PyErr_SetFromWindowsErr(err); + } + return (PyObject *) overlapped; + } + if (!success) + return PyErr_SetFromWindowsErr(0); + + Py_RETURN_NONE; +} + +/*[clinic input] +_winapi.CreateFile -> HANDLE + + file_name: LPCTSTR + desired_access: DWORD + share_mode: DWORD + security_attributes: LPSECURITY_ATTRIBUTES + creation_disposition: DWORD + flags_and_attributes: DWORD + template_file: HANDLE + / +[clinic start generated code]*/ + +static HANDLE +_winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name, + DWORD desired_access, DWORD share_mode, + LPSECURITY_ATTRIBUTES security_attributes, + DWORD creation_disposition, + DWORD flags_and_attributes, HANDLE template_file) +/*[clinic end generated code: output=417ddcebfc5a3d53 input=6423c3e40372dbd5]*/ +{ + HANDLE handle; + if (PySys_Audit("_winapi.CreateFile", "uIIII", file_name, desired_access, share_mode, creation_disposition, flags_and_attributes) < 0) { return INVALID_HANDLE_VALUE; } - Py_BEGIN_ALLOW_THREADS - handle = CreateFile(file_name, desired_access, - share_mode, security_attributes, - creation_disposition, - flags_and_attributes, template_file); - Py_END_ALLOW_THREADS - - if (handle == INVALID_HANDLE_VALUE) - PyErr_SetFromWindowsErr(0); - - return handle; -} - -/*[clinic input] + Py_BEGIN_ALLOW_THREADS + handle = CreateFile(file_name, desired_access, + share_mode, security_attributes, + creation_disposition, + flags_and_attributes, template_file); + Py_END_ALLOW_THREADS + + if (handle == INVALID_HANDLE_VALUE) + PyErr_SetFromWindowsErr(0); + + return handle; +} + +/*[clinic input] _winapi.CreateFileMapping -> HANDLE file_handle: HANDLE @@ -508,863 +508,863 @@ _winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle, name); Py_END_ALLOW_THREADS - if (handle == NULL) { - PyObject *temp = PyUnicode_FromWideChar(name, -1); - PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, temp); - Py_XDECREF(temp); - handle = INVALID_HANDLE_VALUE; - } - - return handle; -} - -/*[clinic input] -_winapi.CreateJunction - - src_path: LPWSTR - dst_path: LPWSTR - / -[clinic start generated code]*/ - -static PyObject * -_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, - LPWSTR dst_path) -/*[clinic end generated code: output=66b7eb746e1dfa25 input=8cd1f9964b6e3d36]*/ -{ - /* Privilege adjustment */ - HANDLE token = NULL; - TOKEN_PRIVILEGES tp; - - /* Reparse data buffer */ - const USHORT prefix_len = 4; - USHORT print_len = 0; - USHORT rdb_size = 0; - _Py_PREPARSE_DATA_BUFFER rdb = NULL; - - /* Junction point creation */ - HANDLE junction = NULL; - DWORD ret = 0; - - if (src_path == NULL || dst_path == NULL) - return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER); - - if (wcsncmp(src_path, L"\\??\\", prefix_len) == 0) - return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER); - - if (PySys_Audit("_winapi.CreateJunction", "uu", src_path, dst_path) < 0) { - return NULL; - } - - /* Adjust privileges to allow rewriting directory entry as a - junction point. */ - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) - goto cleanup; - - if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid)) - goto cleanup; - - tp.PrivilegeCount = 1; - tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), - NULL, NULL)) - goto cleanup; - - if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES) - goto cleanup; - - /* Store the absolute link target path length in print_len. */ - print_len = (USHORT)GetFullPathNameW(src_path, 0, NULL, NULL); - if (print_len == 0) - goto cleanup; - - /* NUL terminator should not be part of print_len. */ - --print_len; - - /* REPARSE_DATA_BUFFER usage is heavily under-documented, especially for - junction points. Here's what I've learned along the way: - - A junction point has two components: a print name and a substitute - name. They both describe the link target, but the substitute name is - the physical target and the print name is shown in directory listings. - - The print name must be a native name, prefixed with "\??\". - - Both names are stored after each other in the same buffer (the - PathBuffer) and both must be NUL-terminated. - - There are four members defining their respective offset and length - inside PathBuffer: SubstituteNameOffset, SubstituteNameLength, - PrintNameOffset and PrintNameLength. - - The total size we need to allocate for the REPARSE_DATA_BUFFER, thus, - is the sum of: - - the fixed header size (REPARSE_DATA_BUFFER_HEADER_SIZE) - - the size of the MountPointReparseBuffer member without the PathBuffer - - the size of the prefix ("\??\") in bytes - - the size of the print name in bytes - - the size of the substitute name in bytes - - the size of two NUL terminators in bytes */ - rdb_size = _Py_REPARSE_DATA_BUFFER_HEADER_SIZE + - sizeof(rdb->MountPointReparseBuffer) - - sizeof(rdb->MountPointReparseBuffer.PathBuffer) + - /* Two +1's for NUL terminators. */ - (prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR); - rdb = (_Py_PREPARSE_DATA_BUFFER)PyMem_RawCalloc(1, rdb_size); - if (rdb == NULL) - goto cleanup; - - rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - rdb->ReparseDataLength = rdb_size - _Py_REPARSE_DATA_BUFFER_HEADER_SIZE; - rdb->MountPointReparseBuffer.SubstituteNameOffset = 0; - rdb->MountPointReparseBuffer.SubstituteNameLength = - (prefix_len + print_len) * sizeof(WCHAR); - rdb->MountPointReparseBuffer.PrintNameOffset = - rdb->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR); - rdb->MountPointReparseBuffer.PrintNameLength = print_len * sizeof(WCHAR); - - /* Store the full native path of link target at the substitute name - offset (0). */ - wcscpy(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\"); - if (GetFullPathNameW(src_path, print_len + 1, - rdb->MountPointReparseBuffer.PathBuffer + prefix_len, - NULL) == 0) - goto cleanup; - - /* Copy everything but the native prefix to the print name offset. */ - wcscpy(rdb->MountPointReparseBuffer.PathBuffer + - prefix_len + print_len + 1, - rdb->MountPointReparseBuffer.PathBuffer + prefix_len); - - /* Create a directory for the junction point. */ - if (!CreateDirectoryW(dst_path, NULL)) - goto cleanup; - - junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (junction == INVALID_HANDLE_VALUE) - goto cleanup; - - /* Make the directory entry a junction point. */ - if (!DeviceIoControl(junction, FSCTL_SET_REPARSE_POINT, rdb, rdb_size, - NULL, 0, &ret, NULL)) - goto cleanup; - -cleanup: - ret = GetLastError(); - - CloseHandle(token); - CloseHandle(junction); - PyMem_RawFree(rdb); - - if (ret != 0) - return PyErr_SetFromWindowsErr(ret); - - Py_RETURN_NONE; -} - -/*[clinic input] -_winapi.CreateNamedPipe -> HANDLE - - name: LPCTSTR - open_mode: DWORD - pipe_mode: DWORD - max_instances: DWORD - out_buffer_size: DWORD - in_buffer_size: DWORD - default_timeout: DWORD - security_attributes: LPSECURITY_ATTRIBUTES - / -[clinic start generated code]*/ - -static HANDLE -_winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode, - DWORD pipe_mode, DWORD max_instances, - DWORD out_buffer_size, DWORD in_buffer_size, - DWORD default_timeout, - LPSECURITY_ATTRIBUTES security_attributes) -/*[clinic end generated code: output=80f8c07346a94fbc input=5a73530b84d8bc37]*/ -{ - HANDLE handle; - - if (PySys_Audit("_winapi.CreateNamedPipe", "uII", - name, open_mode, pipe_mode) < 0) { - return INVALID_HANDLE_VALUE; - } - - Py_BEGIN_ALLOW_THREADS - handle = CreateNamedPipe(name, open_mode, pipe_mode, - max_instances, out_buffer_size, - in_buffer_size, default_timeout, - security_attributes); - Py_END_ALLOW_THREADS - - if (handle == INVALID_HANDLE_VALUE) - PyErr_SetFromWindowsErr(0); - - return handle; -} - -/*[clinic input] -_winapi.CreatePipe - - pipe_attrs: object - Ignored internally, can be None. - size: DWORD - / - -Create an anonymous pipe. - -Returns a 2-tuple of handles, to the read and write ends of the pipe. -[clinic start generated code]*/ - -static PyObject * -_winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size) -/*[clinic end generated code: output=1c4411d8699f0925 input=c4f2cfa56ef68d90]*/ -{ - HANDLE read_pipe; - HANDLE write_pipe; - BOOL result; - - if (PySys_Audit("_winapi.CreatePipe", NULL) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - result = CreatePipe(&read_pipe, &write_pipe, NULL, size); - Py_END_ALLOW_THREADS - - if (! result) - return PyErr_SetFromWindowsErr(GetLastError()); - - return Py_BuildValue( - "NN", HANDLE_TO_PYNUM(read_pipe), HANDLE_TO_PYNUM(write_pipe)); -} - -/* helpers for createprocess */ - -static unsigned long -getulong(PyObject* obj, const char* name) -{ - PyObject* value; - unsigned long ret; - - value = PyObject_GetAttrString(obj, name); - if (! value) { - PyErr_Clear(); /* FIXME: propagate error? */ - return 0; - } - ret = PyLong_AsUnsignedLong(value); - Py_DECREF(value); - return ret; -} - -static HANDLE -gethandle(PyObject* obj, const char* name) -{ - PyObject* value; - HANDLE ret; - - value = PyObject_GetAttrString(obj, name); - if (! value) { - PyErr_Clear(); /* FIXME: propagate error? */ - return NULL; - } - if (value == Py_None) - ret = NULL; - else - ret = PYNUM_TO_HANDLE(value); - Py_DECREF(value); - return ret; -} - -static wchar_t * -getenvironment(PyObject* environment) -{ - Py_ssize_t i, envsize, totalsize; - wchar_t *buffer = NULL, *p, *end; - PyObject *keys, *values; - - /* convert environment dictionary to windows environment string */ - if (! PyMapping_Check(environment)) { - PyErr_SetString( - PyExc_TypeError, "environment must be dictionary or None"); - return NULL; - } - - keys = PyMapping_Keys(environment); - if (!keys) { - return NULL; - } - values = PyMapping_Values(environment); - if (!values) { - goto error; - } - - envsize = PyList_GET_SIZE(keys); - if (PyList_GET_SIZE(values) != envsize) { - PyErr_SetString(PyExc_RuntimeError, - "environment changed size during iteration"); - goto error; - } - - totalsize = 1; /* trailing null character */ - for (i = 0; i < envsize; i++) { - PyObject* key = PyList_GET_ITEM(keys, i); - PyObject* value = PyList_GET_ITEM(values, i); - Py_ssize_t size; - - if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "environment can only contain strings"); - goto error; - } - if (PyUnicode_FindChar(key, '\0', 0, PyUnicode_GET_LENGTH(key), 1) != -1 || - PyUnicode_FindChar(value, '\0', 0, PyUnicode_GET_LENGTH(value), 1) != -1) - { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto error; - } - /* Search from index 1 because on Windows starting '=' is allowed for - defining hidden environment variables. */ - if (PyUnicode_GET_LENGTH(key) == 0 || - PyUnicode_FindChar(key, '=', 1, PyUnicode_GET_LENGTH(key), 1) != -1) - { - PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); - goto error; - } - - size = PyUnicode_AsWideChar(key, NULL, 0); - assert(size > 1); - if (totalsize > PY_SSIZE_T_MAX - size) { - PyErr_SetString(PyExc_OverflowError, "environment too long"); - goto error; - } - totalsize += size; /* including '=' */ - - size = PyUnicode_AsWideChar(value, NULL, 0); - assert(size > 0); - if (totalsize > PY_SSIZE_T_MAX - size) { - PyErr_SetString(PyExc_OverflowError, "environment too long"); - goto error; - } - totalsize += size; /* including trailing '\0' */ - } - - buffer = PyMem_NEW(wchar_t, totalsize); - if (! buffer) { - PyErr_NoMemory(); - goto error; - } - p = buffer; - end = buffer + totalsize; - - for (i = 0; i < envsize; i++) { - PyObject* key = PyList_GET_ITEM(keys, i); - PyObject* value = PyList_GET_ITEM(values, i); - Py_ssize_t size = PyUnicode_AsWideChar(key, p, end - p); - assert(1 <= size && size < end - p); - p += size; - *p++ = L'='; - size = PyUnicode_AsWideChar(value, p, end - p); - assert(0 <= size && size < end - p); - p += size + 1; - } - - /* add trailing null character */ - *p++ = L'\0'; - assert(p == end); - - error: - Py_XDECREF(keys); - Py_XDECREF(values); - return buffer; -} - -static LPHANDLE -gethandlelist(PyObject *mapping, const char *name, Py_ssize_t *size) -{ - LPHANDLE ret = NULL; - PyObject *value_fast = NULL; - PyObject *value; - Py_ssize_t i; - - value = PyMapping_GetItemString(mapping, name); - if (!value) { - PyErr_Clear(); - return NULL; - } - - if (value == Py_None) { - goto cleanup; - } - - value_fast = PySequence_Fast(value, "handle_list must be a sequence or None"); - if (value_fast == NULL) - goto cleanup; - - *size = PySequence_Fast_GET_SIZE(value_fast) * sizeof(HANDLE); - - /* Passing an empty array causes CreateProcess to fail so just don't set it */ - if (*size == 0) { - goto cleanup; - } - - ret = PyMem_Malloc(*size); - if (ret == NULL) - goto cleanup; - - for (i = 0; i < PySequence_Fast_GET_SIZE(value_fast); i++) { - ret[i] = PYNUM_TO_HANDLE(PySequence_Fast_GET_ITEM(value_fast, i)); - if (ret[i] == (HANDLE)-1 && PyErr_Occurred()) { - PyMem_Free(ret); - ret = NULL; - goto cleanup; - } - } - -cleanup: - Py_DECREF(value); - Py_XDECREF(value_fast); - return ret; -} - -typedef struct { - LPPROC_THREAD_ATTRIBUTE_LIST attribute_list; - LPHANDLE handle_list; -} AttributeList; - -static void -freeattributelist(AttributeList *attribute_list) -{ - if (attribute_list->attribute_list != NULL) { - DeleteProcThreadAttributeList(attribute_list->attribute_list); - PyMem_Free(attribute_list->attribute_list); - } - - PyMem_Free(attribute_list->handle_list); - - memset(attribute_list, 0, sizeof(*attribute_list)); -} - -static int -getattributelist(PyObject *obj, const char *name, AttributeList *attribute_list) -{ - int ret = 0; - DWORD err; - BOOL result; - PyObject *value; - Py_ssize_t handle_list_size; - DWORD attribute_count = 0; - SIZE_T attribute_list_size = 0; - - value = PyObject_GetAttrString(obj, name); - if (!value) { - PyErr_Clear(); /* FIXME: propagate error? */ - return 0; - } - - if (value == Py_None) { - ret = 0; - goto cleanup; - } - - if (!PyMapping_Check(value)) { - ret = -1; - PyErr_Format(PyExc_TypeError, "%s must be a mapping or None", name); - goto cleanup; - } - - attribute_list->handle_list = gethandlelist(value, "handle_list", &handle_list_size); - if (attribute_list->handle_list == NULL && PyErr_Occurred()) { - ret = -1; - goto cleanup; - } - - if (attribute_list->handle_list != NULL) - ++attribute_count; - - /* Get how many bytes we need for the attribute list */ - result = InitializeProcThreadAttributeList(NULL, attribute_count, 0, &attribute_list_size); - if (result || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - ret = -1; - PyErr_SetFromWindowsErr(GetLastError()); - goto cleanup; - } - - attribute_list->attribute_list = PyMem_Malloc(attribute_list_size); - if (attribute_list->attribute_list == NULL) { - ret = -1; - goto cleanup; - } - - result = InitializeProcThreadAttributeList( - attribute_list->attribute_list, - attribute_count, - 0, - &attribute_list_size); - if (!result) { - err = GetLastError(); - - /* So that we won't call DeleteProcThreadAttributeList */ - PyMem_Free(attribute_list->attribute_list); - attribute_list->attribute_list = NULL; - - ret = -1; - PyErr_SetFromWindowsErr(err); - goto cleanup; - } - - if (attribute_list->handle_list != NULL) { - result = UpdateProcThreadAttribute( - attribute_list->attribute_list, - 0, - PROC_THREAD_ATTRIBUTE_HANDLE_LIST, - attribute_list->handle_list, - handle_list_size, - NULL, - NULL); - if (!result) { - ret = -1; - PyErr_SetFromWindowsErr(GetLastError()); - goto cleanup; - } - } - -cleanup: - Py_DECREF(value); - - if (ret < 0) - freeattributelist(attribute_list); - - return ret; -} - -/*[clinic input] -_winapi.CreateProcess - - application_name: Py_UNICODE(accept={str, NoneType}) - command_line: object - Can be str or None - proc_attrs: object - Ignored internally, can be None. - thread_attrs: object - Ignored internally, can be None. - inherit_handles: BOOL - creation_flags: DWORD - env_mapping: object - current_directory: Py_UNICODE(accept={str, NoneType}) - startup_info: object - / - -Create a new process and its primary thread. - -The return value is a tuple of the process handle, thread handle, -process ID, and thread ID. -[clinic start generated code]*/ - -static PyObject * -_winapi_CreateProcess_impl(PyObject *module, - const Py_UNICODE *application_name, - PyObject *command_line, PyObject *proc_attrs, - PyObject *thread_attrs, BOOL inherit_handles, - DWORD creation_flags, PyObject *env_mapping, - const Py_UNICODE *current_directory, - PyObject *startup_info) -/*[clinic end generated code: output=9b2423a609230132 input=42ac293eaea03fc4]*/ -{ - PyObject *ret = NULL; - BOOL result; - PROCESS_INFORMATION pi; - STARTUPINFOEXW si; - wchar_t *wenvironment = NULL; - wchar_t *command_line_copy = NULL; - AttributeList attribute_list = {0}; - - if (PySys_Audit("_winapi.CreateProcess", "uuu", application_name, - command_line, current_directory) < 0) { - return NULL; - } - - PyInterpreterState *interp = PyInterpreterState_Get(); - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - if (config->_isolated_interpreter) { - PyErr_SetString(PyExc_RuntimeError, - "subprocess not supported for isolated subinterpreters"); - return NULL; - } - - ZeroMemory(&si, sizeof(si)); - si.StartupInfo.cb = sizeof(si); - - /* note: we only support a small subset of all SI attributes */ - si.StartupInfo.dwFlags = getulong(startup_info, "dwFlags"); - si.StartupInfo.wShowWindow = (WORD)getulong(startup_info, "wShowWindow"); - si.StartupInfo.hStdInput = gethandle(startup_info, "hStdInput"); - si.StartupInfo.hStdOutput = gethandle(startup_info, "hStdOutput"); - si.StartupInfo.hStdError = gethandle(startup_info, "hStdError"); - if (PyErr_Occurred()) - goto cleanup; - - if (env_mapping != Py_None) { - wenvironment = getenvironment(env_mapping); - if (wenvironment == NULL) { - goto cleanup; - } - } - - if (getattributelist(startup_info, "lpAttributeList", &attribute_list) < 0) - goto cleanup; - - si.lpAttributeList = attribute_list.attribute_list; - if (PyUnicode_Check(command_line)) { - command_line_copy = PyUnicode_AsWideCharString(command_line, NULL); - if (command_line_copy == NULL) { - goto cleanup; - } - } - else if (command_line != Py_None) { - PyErr_Format(PyExc_TypeError, - "CreateProcess() argument 2 must be str or None, not %s", - Py_TYPE(command_line)->tp_name); - goto cleanup; - } - - - Py_BEGIN_ALLOW_THREADS - result = CreateProcessW(application_name, - command_line_copy, - NULL, - NULL, - inherit_handles, - creation_flags | EXTENDED_STARTUPINFO_PRESENT | - CREATE_UNICODE_ENVIRONMENT, - wenvironment, - current_directory, - (LPSTARTUPINFOW)&si, - &pi); - Py_END_ALLOW_THREADS - - if (!result) { - PyErr_SetFromWindowsErr(GetLastError()); - goto cleanup; - } - - ret = Py_BuildValue("NNkk", - HANDLE_TO_PYNUM(pi.hProcess), - HANDLE_TO_PYNUM(pi.hThread), - pi.dwProcessId, - pi.dwThreadId); - -cleanup: - PyMem_Free(command_line_copy); - PyMem_Free(wenvironment); - freeattributelist(&attribute_list); - - return ret; -} - -/*[clinic input] -_winapi.DuplicateHandle -> HANDLE - - source_process_handle: HANDLE - source_handle: HANDLE - target_process_handle: HANDLE - desired_access: DWORD - inherit_handle: BOOL - options: DWORD = 0 - / - -Return a duplicate handle object. - -The duplicate handle refers to the same object as the original -handle. Therefore, any changes to the object are reflected -through both handles. -[clinic start generated code]*/ - -static HANDLE -_winapi_DuplicateHandle_impl(PyObject *module, HANDLE source_process_handle, - HANDLE source_handle, - HANDLE target_process_handle, - DWORD desired_access, BOOL inherit_handle, - DWORD options) -/*[clinic end generated code: output=ad9711397b5dcd4e input=b933e3f2356a8c12]*/ -{ - HANDLE target_handle; - BOOL result; - - Py_BEGIN_ALLOW_THREADS - result = DuplicateHandle( - source_process_handle, - source_handle, - target_process_handle, - &target_handle, - desired_access, - inherit_handle, - options - ); - Py_END_ALLOW_THREADS - - if (! result) { - PyErr_SetFromWindowsErr(GetLastError()); - return INVALID_HANDLE_VALUE; - } - - return target_handle; -} - -/*[clinic input] -_winapi.ExitProcess - - ExitCode: UINT - / - -[clinic start generated code]*/ - -static PyObject * -_winapi_ExitProcess_impl(PyObject *module, UINT ExitCode) -/*[clinic end generated code: output=a387deb651175301 input=4f05466a9406c558]*/ -{ - #if defined(Py_DEBUG) - SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT| - SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); - #endif - - ExitProcess(ExitCode); - - return NULL; -} - -/*[clinic input] -_winapi.GetCurrentProcess -> HANDLE - -Return a handle object for the current process. -[clinic start generated code]*/ - -static HANDLE -_winapi_GetCurrentProcess_impl(PyObject *module) -/*[clinic end generated code: output=ddeb4dd2ffadf344 input=b213403fd4b96b41]*/ -{ - return GetCurrentProcess(); -} - -/*[clinic input] -_winapi.GetExitCodeProcess -> DWORD - - process: HANDLE - / - -Return the termination status of the specified process. -[clinic start generated code]*/ - -static DWORD -_winapi_GetExitCodeProcess_impl(PyObject *module, HANDLE process) -/*[clinic end generated code: output=b4620bdf2bccf36b input=61b6bfc7dc2ee374]*/ -{ - DWORD exit_code; - BOOL result; - - result = GetExitCodeProcess(process, &exit_code); - - if (! result) { - PyErr_SetFromWindowsErr(GetLastError()); - exit_code = PY_DWORD_MAX; - } - - return exit_code; -} - -/*[clinic input] -_winapi.GetLastError -> DWORD -[clinic start generated code]*/ - -static DWORD -_winapi_GetLastError_impl(PyObject *module) -/*[clinic end generated code: output=8585b827cb1a92c5 input=62d47fb9bce038ba]*/ -{ - return GetLastError(); -} - -/*[clinic input] -_winapi.GetModuleFileName - - module_handle: HMODULE - / - -Return the fully-qualified path for the file that contains module. - -The module must have been loaded by the current process. - -The module parameter should be a handle to the loaded module -whose path is being requested. If this parameter is 0, -GetModuleFileName retrieves the path of the executable file -of the current process. -[clinic start generated code]*/ - -static PyObject * -_winapi_GetModuleFileName_impl(PyObject *module, HMODULE module_handle) -/*[clinic end generated code: output=85b4b728c5160306 input=6d66ff7deca5d11f]*/ -{ - BOOL result; - WCHAR filename[MAX_PATH]; - - Py_BEGIN_ALLOW_THREADS - result = GetModuleFileNameW(module_handle, filename, MAX_PATH); - filename[MAX_PATH-1] = '\0'; - Py_END_ALLOW_THREADS - - if (! result) - return PyErr_SetFromWindowsErr(GetLastError()); - - return PyUnicode_FromWideChar(filename, wcslen(filename)); -} - -/*[clinic input] -_winapi.GetStdHandle -> HANDLE - - std_handle: DWORD - One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE. - / - -Return a handle to the specified standard device. - -The integer associated with the handle object is returned. -[clinic start generated code]*/ - -static HANDLE -_winapi_GetStdHandle_impl(PyObject *module, DWORD std_handle) -/*[clinic end generated code: output=0e613001e73ab614 input=07016b06a2fc8826]*/ -{ - HANDLE handle; - - Py_BEGIN_ALLOW_THREADS - handle = GetStdHandle(std_handle); - Py_END_ALLOW_THREADS - - if (handle == INVALID_HANDLE_VALUE) - PyErr_SetFromWindowsErr(GetLastError()); + if (handle == NULL) { + PyObject *temp = PyUnicode_FromWideChar(name, -1); + PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, temp); + Py_XDECREF(temp); + handle = INVALID_HANDLE_VALUE; + } return handle; } /*[clinic input] -_winapi.GetVersion -> long +_winapi.CreateJunction + + src_path: LPWSTR + dst_path: LPWSTR + / +[clinic start generated code]*/ + +static PyObject * +_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, + LPWSTR dst_path) +/*[clinic end generated code: output=66b7eb746e1dfa25 input=8cd1f9964b6e3d36]*/ +{ + /* Privilege adjustment */ + HANDLE token = NULL; + TOKEN_PRIVILEGES tp; + + /* Reparse data buffer */ + const USHORT prefix_len = 4; + USHORT print_len = 0; + USHORT rdb_size = 0; + _Py_PREPARSE_DATA_BUFFER rdb = NULL; + + /* Junction point creation */ + HANDLE junction = NULL; + DWORD ret = 0; + + if (src_path == NULL || dst_path == NULL) + return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER); + + if (wcsncmp(src_path, L"\\??\\", prefix_len) == 0) + return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER); + + if (PySys_Audit("_winapi.CreateJunction", "uu", src_path, dst_path) < 0) { + return NULL; + } -Return the version number of the current operating system. -[clinic start generated code]*/ + /* Adjust privileges to allow rewriting directory entry as a + junction point. */ + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) + goto cleanup; + + if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid)) + goto cleanup; + + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), + NULL, NULL)) + goto cleanup; + + if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES) + goto cleanup; + + /* Store the absolute link target path length in print_len. */ + print_len = (USHORT)GetFullPathNameW(src_path, 0, NULL, NULL); + if (print_len == 0) + goto cleanup; + + /* NUL terminator should not be part of print_len. */ + --print_len; + + /* REPARSE_DATA_BUFFER usage is heavily under-documented, especially for + junction points. Here's what I've learned along the way: + - A junction point has two components: a print name and a substitute + name. They both describe the link target, but the substitute name is + the physical target and the print name is shown in directory listings. + - The print name must be a native name, prefixed with "\??\". + - Both names are stored after each other in the same buffer (the + PathBuffer) and both must be NUL-terminated. + - There are four members defining their respective offset and length + inside PathBuffer: SubstituteNameOffset, SubstituteNameLength, + PrintNameOffset and PrintNameLength. + - The total size we need to allocate for the REPARSE_DATA_BUFFER, thus, + is the sum of: + - the fixed header size (REPARSE_DATA_BUFFER_HEADER_SIZE) + - the size of the MountPointReparseBuffer member without the PathBuffer + - the size of the prefix ("\??\") in bytes + - the size of the print name in bytes + - the size of the substitute name in bytes + - the size of two NUL terminators in bytes */ + rdb_size = _Py_REPARSE_DATA_BUFFER_HEADER_SIZE + + sizeof(rdb->MountPointReparseBuffer) - + sizeof(rdb->MountPointReparseBuffer.PathBuffer) + + /* Two +1's for NUL terminators. */ + (prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR); + rdb = (_Py_PREPARSE_DATA_BUFFER)PyMem_RawCalloc(1, rdb_size); + if (rdb == NULL) + goto cleanup; + + rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + rdb->ReparseDataLength = rdb_size - _Py_REPARSE_DATA_BUFFER_HEADER_SIZE; + rdb->MountPointReparseBuffer.SubstituteNameOffset = 0; + rdb->MountPointReparseBuffer.SubstituteNameLength = + (prefix_len + print_len) * sizeof(WCHAR); + rdb->MountPointReparseBuffer.PrintNameOffset = + rdb->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR); + rdb->MountPointReparseBuffer.PrintNameLength = print_len * sizeof(WCHAR); + + /* Store the full native path of link target at the substitute name + offset (0). */ + wcscpy(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\"); + if (GetFullPathNameW(src_path, print_len + 1, + rdb->MountPointReparseBuffer.PathBuffer + prefix_len, + NULL) == 0) + goto cleanup; + + /* Copy everything but the native prefix to the print name offset. */ + wcscpy(rdb->MountPointReparseBuffer.PathBuffer + + prefix_len + print_len + 1, + rdb->MountPointReparseBuffer.PathBuffer + prefix_len); + + /* Create a directory for the junction point. */ + if (!CreateDirectoryW(dst_path, NULL)) + goto cleanup; + + junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (junction == INVALID_HANDLE_VALUE) + goto cleanup; + + /* Make the directory entry a junction point. */ + if (!DeviceIoControl(junction, FSCTL_SET_REPARSE_POINT, rdb, rdb_size, + NULL, 0, &ret, NULL)) + goto cleanup; + +cleanup: + ret = GetLastError(); + + CloseHandle(token); + CloseHandle(junction); + PyMem_RawFree(rdb); + + if (ret != 0) + return PyErr_SetFromWindowsErr(ret); + + Py_RETURN_NONE; +} + +/*[clinic input] +_winapi.CreateNamedPipe -> HANDLE + + name: LPCTSTR + open_mode: DWORD + pipe_mode: DWORD + max_instances: DWORD + out_buffer_size: DWORD + in_buffer_size: DWORD + default_timeout: DWORD + security_attributes: LPSECURITY_ATTRIBUTES + / +[clinic start generated code]*/ + +static HANDLE +_winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode, + DWORD pipe_mode, DWORD max_instances, + DWORD out_buffer_size, DWORD in_buffer_size, + DWORD default_timeout, + LPSECURITY_ATTRIBUTES security_attributes) +/*[clinic end generated code: output=80f8c07346a94fbc input=5a73530b84d8bc37]*/ +{ + HANDLE handle; + + if (PySys_Audit("_winapi.CreateNamedPipe", "uII", + name, open_mode, pipe_mode) < 0) { + return INVALID_HANDLE_VALUE; + } -static long -_winapi_GetVersion_impl(PyObject *module) -/*[clinic end generated code: output=e41f0db5a3b82682 input=e21dff8d0baeded2]*/ -/* Disable deprecation warnings about GetVersionEx as the result is - being passed straight through to the caller, who is responsible for - using it correctly. */ -#pragma warning(push) -#pragma warning(disable:4996) + Py_BEGIN_ALLOW_THREADS + handle = CreateNamedPipe(name, open_mode, pipe_mode, + max_instances, out_buffer_size, + in_buffer_size, default_timeout, + security_attributes); + Py_END_ALLOW_THREADS + + if (handle == INVALID_HANDLE_VALUE) + PyErr_SetFromWindowsErr(0); + + return handle; +} + +/*[clinic input] +_winapi.CreatePipe + + pipe_attrs: object + Ignored internally, can be None. + size: DWORD + / + +Create an anonymous pipe. + +Returns a 2-tuple of handles, to the read and write ends of the pipe. +[clinic start generated code]*/ + +static PyObject * +_winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size) +/*[clinic end generated code: output=1c4411d8699f0925 input=c4f2cfa56ef68d90]*/ +{ + HANDLE read_pipe; + HANDLE write_pipe; + BOOL result; + + if (PySys_Audit("_winapi.CreatePipe", NULL) < 0) { + return NULL; + } -{ - return GetVersion(); -} + Py_BEGIN_ALLOW_THREADS + result = CreatePipe(&read_pipe, &write_pipe, NULL, size); + Py_END_ALLOW_THREADS + + if (! result) + return PyErr_SetFromWindowsErr(GetLastError()); + + return Py_BuildValue( + "NN", HANDLE_TO_PYNUM(read_pipe), HANDLE_TO_PYNUM(write_pipe)); +} + +/* helpers for createprocess */ + +static unsigned long +getulong(PyObject* obj, const char* name) +{ + PyObject* value; + unsigned long ret; + + value = PyObject_GetAttrString(obj, name); + if (! value) { + PyErr_Clear(); /* FIXME: propagate error? */ + return 0; + } + ret = PyLong_AsUnsignedLong(value); + Py_DECREF(value); + return ret; +} + +static HANDLE +gethandle(PyObject* obj, const char* name) +{ + PyObject* value; + HANDLE ret; + + value = PyObject_GetAttrString(obj, name); + if (! value) { + PyErr_Clear(); /* FIXME: propagate error? */ + return NULL; + } + if (value == Py_None) + ret = NULL; + else + ret = PYNUM_TO_HANDLE(value); + Py_DECREF(value); + return ret; +} + +static wchar_t * +getenvironment(PyObject* environment) +{ + Py_ssize_t i, envsize, totalsize; + wchar_t *buffer = NULL, *p, *end; + PyObject *keys, *values; + + /* convert environment dictionary to windows environment string */ + if (! PyMapping_Check(environment)) { + PyErr_SetString( + PyExc_TypeError, "environment must be dictionary or None"); + return NULL; + } + + keys = PyMapping_Keys(environment); + if (!keys) { + return NULL; + } + values = PyMapping_Values(environment); + if (!values) { + goto error; + } + + envsize = PyList_GET_SIZE(keys); + if (PyList_GET_SIZE(values) != envsize) { + PyErr_SetString(PyExc_RuntimeError, + "environment changed size during iteration"); + goto error; + } + + totalsize = 1; /* trailing null character */ + for (i = 0; i < envsize; i++) { + PyObject* key = PyList_GET_ITEM(keys, i); + PyObject* value = PyList_GET_ITEM(values, i); + Py_ssize_t size; + + if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "environment can only contain strings"); + goto error; + } + if (PyUnicode_FindChar(key, '\0', 0, PyUnicode_GET_LENGTH(key), 1) != -1 || + PyUnicode_FindChar(value, '\0', 0, PyUnicode_GET_LENGTH(value), 1) != -1) + { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto error; + } + /* Search from index 1 because on Windows starting '=' is allowed for + defining hidden environment variables. */ + if (PyUnicode_GET_LENGTH(key) == 0 || + PyUnicode_FindChar(key, '=', 1, PyUnicode_GET_LENGTH(key), 1) != -1) + { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + goto error; + } + + size = PyUnicode_AsWideChar(key, NULL, 0); + assert(size > 1); + if (totalsize > PY_SSIZE_T_MAX - size) { + PyErr_SetString(PyExc_OverflowError, "environment too long"); + goto error; + } + totalsize += size; /* including '=' */ -#pragma warning(pop) + size = PyUnicode_AsWideChar(value, NULL, 0); + assert(size > 0); + if (totalsize > PY_SSIZE_T_MAX - size) { + PyErr_SetString(PyExc_OverflowError, "environment too long"); + goto error; + } + totalsize += size; /* including trailing '\0' */ + } + + buffer = PyMem_NEW(wchar_t, totalsize); + if (! buffer) { + PyErr_NoMemory(); + goto error; + } + p = buffer; + end = buffer + totalsize; + + for (i = 0; i < envsize; i++) { + PyObject* key = PyList_GET_ITEM(keys, i); + PyObject* value = PyList_GET_ITEM(values, i); + Py_ssize_t size = PyUnicode_AsWideChar(key, p, end - p); + assert(1 <= size && size < end - p); + p += size; + *p++ = L'='; + size = PyUnicode_AsWideChar(value, p, end - p); + assert(0 <= size && size < end - p); + p += size + 1; + } + + /* add trailing null character */ + *p++ = L'\0'; + assert(p == end); + + error: + Py_XDECREF(keys); + Py_XDECREF(values); + return buffer; +} + +static LPHANDLE +gethandlelist(PyObject *mapping, const char *name, Py_ssize_t *size) +{ + LPHANDLE ret = NULL; + PyObject *value_fast = NULL; + PyObject *value; + Py_ssize_t i; + + value = PyMapping_GetItemString(mapping, name); + if (!value) { + PyErr_Clear(); + return NULL; + } + + if (value == Py_None) { + goto cleanup; + } + + value_fast = PySequence_Fast(value, "handle_list must be a sequence or None"); + if (value_fast == NULL) + goto cleanup; + + *size = PySequence_Fast_GET_SIZE(value_fast) * sizeof(HANDLE); + + /* Passing an empty array causes CreateProcess to fail so just don't set it */ + if (*size == 0) { + goto cleanup; + } + + ret = PyMem_Malloc(*size); + if (ret == NULL) + goto cleanup; + + for (i = 0; i < PySequence_Fast_GET_SIZE(value_fast); i++) { + ret[i] = PYNUM_TO_HANDLE(PySequence_Fast_GET_ITEM(value_fast, i)); + if (ret[i] == (HANDLE)-1 && PyErr_Occurred()) { + PyMem_Free(ret); + ret = NULL; + goto cleanup; + } + } + +cleanup: + Py_DECREF(value); + Py_XDECREF(value_fast); + return ret; +} + +typedef struct { + LPPROC_THREAD_ATTRIBUTE_LIST attribute_list; + LPHANDLE handle_list; +} AttributeList; + +static void +freeattributelist(AttributeList *attribute_list) +{ + if (attribute_list->attribute_list != NULL) { + DeleteProcThreadAttributeList(attribute_list->attribute_list); + PyMem_Free(attribute_list->attribute_list); + } + + PyMem_Free(attribute_list->handle_list); + + memset(attribute_list, 0, sizeof(*attribute_list)); +} + +static int +getattributelist(PyObject *obj, const char *name, AttributeList *attribute_list) +{ + int ret = 0; + DWORD err; + BOOL result; + PyObject *value; + Py_ssize_t handle_list_size; + DWORD attribute_count = 0; + SIZE_T attribute_list_size = 0; + + value = PyObject_GetAttrString(obj, name); + if (!value) { + PyErr_Clear(); /* FIXME: propagate error? */ + return 0; + } + + if (value == Py_None) { + ret = 0; + goto cleanup; + } + + if (!PyMapping_Check(value)) { + ret = -1; + PyErr_Format(PyExc_TypeError, "%s must be a mapping or None", name); + goto cleanup; + } + + attribute_list->handle_list = gethandlelist(value, "handle_list", &handle_list_size); + if (attribute_list->handle_list == NULL && PyErr_Occurred()) { + ret = -1; + goto cleanup; + } + + if (attribute_list->handle_list != NULL) + ++attribute_count; + + /* Get how many bytes we need for the attribute list */ + result = InitializeProcThreadAttributeList(NULL, attribute_count, 0, &attribute_list_size); + if (result || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + ret = -1; + PyErr_SetFromWindowsErr(GetLastError()); + goto cleanup; + } + + attribute_list->attribute_list = PyMem_Malloc(attribute_list_size); + if (attribute_list->attribute_list == NULL) { + ret = -1; + goto cleanup; + } + + result = InitializeProcThreadAttributeList( + attribute_list->attribute_list, + attribute_count, + 0, + &attribute_list_size); + if (!result) { + err = GetLastError(); + + /* So that we won't call DeleteProcThreadAttributeList */ + PyMem_Free(attribute_list->attribute_list); + attribute_list->attribute_list = NULL; + + ret = -1; + PyErr_SetFromWindowsErr(err); + goto cleanup; + } + + if (attribute_list->handle_list != NULL) { + result = UpdateProcThreadAttribute( + attribute_list->attribute_list, + 0, + PROC_THREAD_ATTRIBUTE_HANDLE_LIST, + attribute_list->handle_list, + handle_list_size, + NULL, + NULL); + if (!result) { + ret = -1; + PyErr_SetFromWindowsErr(GetLastError()); + goto cleanup; + } + } + +cleanup: + Py_DECREF(value); + + if (ret < 0) + freeattributelist(attribute_list); + + return ret; +} + +/*[clinic input] +_winapi.CreateProcess + + application_name: Py_UNICODE(accept={str, NoneType}) + command_line: object + Can be str or None + proc_attrs: object + Ignored internally, can be None. + thread_attrs: object + Ignored internally, can be None. + inherit_handles: BOOL + creation_flags: DWORD + env_mapping: object + current_directory: Py_UNICODE(accept={str, NoneType}) + startup_info: object + / + +Create a new process and its primary thread. + +The return value is a tuple of the process handle, thread handle, +process ID, and thread ID. +[clinic start generated code]*/ + +static PyObject * +_winapi_CreateProcess_impl(PyObject *module, + const Py_UNICODE *application_name, + PyObject *command_line, PyObject *proc_attrs, + PyObject *thread_attrs, BOOL inherit_handles, + DWORD creation_flags, PyObject *env_mapping, + const Py_UNICODE *current_directory, + PyObject *startup_info) +/*[clinic end generated code: output=9b2423a609230132 input=42ac293eaea03fc4]*/ +{ + PyObject *ret = NULL; + BOOL result; + PROCESS_INFORMATION pi; + STARTUPINFOEXW si; + wchar_t *wenvironment = NULL; + wchar_t *command_line_copy = NULL; + AttributeList attribute_list = {0}; + + if (PySys_Audit("_winapi.CreateProcess", "uuu", application_name, + command_line, current_directory) < 0) { + return NULL; + } -/*[clinic input] + PyInterpreterState *interp = PyInterpreterState_Get(); + const PyConfig *config = _PyInterpreterState_GetConfig(interp); + if (config->_isolated_interpreter) { + PyErr_SetString(PyExc_RuntimeError, + "subprocess not supported for isolated subinterpreters"); + return NULL; + } + + ZeroMemory(&si, sizeof(si)); + si.StartupInfo.cb = sizeof(si); + + /* note: we only support a small subset of all SI attributes */ + si.StartupInfo.dwFlags = getulong(startup_info, "dwFlags"); + si.StartupInfo.wShowWindow = (WORD)getulong(startup_info, "wShowWindow"); + si.StartupInfo.hStdInput = gethandle(startup_info, "hStdInput"); + si.StartupInfo.hStdOutput = gethandle(startup_info, "hStdOutput"); + si.StartupInfo.hStdError = gethandle(startup_info, "hStdError"); + if (PyErr_Occurred()) + goto cleanup; + + if (env_mapping != Py_None) { + wenvironment = getenvironment(env_mapping); + if (wenvironment == NULL) { + goto cleanup; + } + } + + if (getattributelist(startup_info, "lpAttributeList", &attribute_list) < 0) + goto cleanup; + + si.lpAttributeList = attribute_list.attribute_list; + if (PyUnicode_Check(command_line)) { + command_line_copy = PyUnicode_AsWideCharString(command_line, NULL); + if (command_line_copy == NULL) { + goto cleanup; + } + } + else if (command_line != Py_None) { + PyErr_Format(PyExc_TypeError, + "CreateProcess() argument 2 must be str or None, not %s", + Py_TYPE(command_line)->tp_name); + goto cleanup; + } + + + Py_BEGIN_ALLOW_THREADS + result = CreateProcessW(application_name, + command_line_copy, + NULL, + NULL, + inherit_handles, + creation_flags | EXTENDED_STARTUPINFO_PRESENT | + CREATE_UNICODE_ENVIRONMENT, + wenvironment, + current_directory, + (LPSTARTUPINFOW)&si, + &pi); + Py_END_ALLOW_THREADS + + if (!result) { + PyErr_SetFromWindowsErr(GetLastError()); + goto cleanup; + } + + ret = Py_BuildValue("NNkk", + HANDLE_TO_PYNUM(pi.hProcess), + HANDLE_TO_PYNUM(pi.hThread), + pi.dwProcessId, + pi.dwThreadId); + +cleanup: + PyMem_Free(command_line_copy); + PyMem_Free(wenvironment); + freeattributelist(&attribute_list); + + return ret; +} + +/*[clinic input] +_winapi.DuplicateHandle -> HANDLE + + source_process_handle: HANDLE + source_handle: HANDLE + target_process_handle: HANDLE + desired_access: DWORD + inherit_handle: BOOL + options: DWORD = 0 + / + +Return a duplicate handle object. + +The duplicate handle refers to the same object as the original +handle. Therefore, any changes to the object are reflected +through both handles. +[clinic start generated code]*/ + +static HANDLE +_winapi_DuplicateHandle_impl(PyObject *module, HANDLE source_process_handle, + HANDLE source_handle, + HANDLE target_process_handle, + DWORD desired_access, BOOL inherit_handle, + DWORD options) +/*[clinic end generated code: output=ad9711397b5dcd4e input=b933e3f2356a8c12]*/ +{ + HANDLE target_handle; + BOOL result; + + Py_BEGIN_ALLOW_THREADS + result = DuplicateHandle( + source_process_handle, + source_handle, + target_process_handle, + &target_handle, + desired_access, + inherit_handle, + options + ); + Py_END_ALLOW_THREADS + + if (! result) { + PyErr_SetFromWindowsErr(GetLastError()); + return INVALID_HANDLE_VALUE; + } + + return target_handle; +} + +/*[clinic input] +_winapi.ExitProcess + + ExitCode: UINT + / + +[clinic start generated code]*/ + +static PyObject * +_winapi_ExitProcess_impl(PyObject *module, UINT ExitCode) +/*[clinic end generated code: output=a387deb651175301 input=4f05466a9406c558]*/ +{ + #if defined(Py_DEBUG) + SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT| + SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + #endif + + ExitProcess(ExitCode); + + return NULL; +} + +/*[clinic input] +_winapi.GetCurrentProcess -> HANDLE + +Return a handle object for the current process. +[clinic start generated code]*/ + +static HANDLE +_winapi_GetCurrentProcess_impl(PyObject *module) +/*[clinic end generated code: output=ddeb4dd2ffadf344 input=b213403fd4b96b41]*/ +{ + return GetCurrentProcess(); +} + +/*[clinic input] +_winapi.GetExitCodeProcess -> DWORD + + process: HANDLE + / + +Return the termination status of the specified process. +[clinic start generated code]*/ + +static DWORD +_winapi_GetExitCodeProcess_impl(PyObject *module, HANDLE process) +/*[clinic end generated code: output=b4620bdf2bccf36b input=61b6bfc7dc2ee374]*/ +{ + DWORD exit_code; + BOOL result; + + result = GetExitCodeProcess(process, &exit_code); + + if (! result) { + PyErr_SetFromWindowsErr(GetLastError()); + exit_code = PY_DWORD_MAX; + } + + return exit_code; +} + +/*[clinic input] +_winapi.GetLastError -> DWORD +[clinic start generated code]*/ + +static DWORD +_winapi_GetLastError_impl(PyObject *module) +/*[clinic end generated code: output=8585b827cb1a92c5 input=62d47fb9bce038ba]*/ +{ + return GetLastError(); +} + +/*[clinic input] +_winapi.GetModuleFileName + + module_handle: HMODULE + / + +Return the fully-qualified path for the file that contains module. + +The module must have been loaded by the current process. + +The module parameter should be a handle to the loaded module +whose path is being requested. If this parameter is 0, +GetModuleFileName retrieves the path of the executable file +of the current process. +[clinic start generated code]*/ + +static PyObject * +_winapi_GetModuleFileName_impl(PyObject *module, HMODULE module_handle) +/*[clinic end generated code: output=85b4b728c5160306 input=6d66ff7deca5d11f]*/ +{ + BOOL result; + WCHAR filename[MAX_PATH]; + + Py_BEGIN_ALLOW_THREADS + result = GetModuleFileNameW(module_handle, filename, MAX_PATH); + filename[MAX_PATH-1] = '\0'; + Py_END_ALLOW_THREADS + + if (! result) + return PyErr_SetFromWindowsErr(GetLastError()); + + return PyUnicode_FromWideChar(filename, wcslen(filename)); +} + +/*[clinic input] +_winapi.GetStdHandle -> HANDLE + + std_handle: DWORD + One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE. + / + +Return a handle to the specified standard device. + +The integer associated with the handle object is returned. +[clinic start generated code]*/ + +static HANDLE +_winapi_GetStdHandle_impl(PyObject *module, DWORD std_handle) +/*[clinic end generated code: output=0e613001e73ab614 input=07016b06a2fc8826]*/ +{ + HANDLE handle; + + Py_BEGIN_ALLOW_THREADS + handle = GetStdHandle(std_handle); + Py_END_ALLOW_THREADS + + if (handle == INVALID_HANDLE_VALUE) + PyErr_SetFromWindowsErr(GetLastError()); + + return handle; +} + +/*[clinic input] +_winapi.GetVersion -> long + +Return the version number of the current operating system. +[clinic start generated code]*/ + +static long +_winapi_GetVersion_impl(PyObject *module) +/*[clinic end generated code: output=e41f0db5a3b82682 input=e21dff8d0baeded2]*/ +/* Disable deprecation warnings about GetVersionEx as the result is + being passed straight through to the caller, who is responsible for + using it correctly. */ +#pragma warning(push) +#pragma warning(disable:4996) + +{ + return GetVersion(); +} + +#pragma warning(pop) + +/*[clinic input] _winapi.MapViewOfFile -> LPVOID file_map: HANDLE @@ -1425,218 +1425,218 @@ _winapi_OpenFileMapping_impl(PyObject *module, DWORD desired_access, } /*[clinic input] -_winapi.OpenProcess -> HANDLE - - desired_access: DWORD - inherit_handle: BOOL - process_id: DWORD - / -[clinic start generated code]*/ - -static HANDLE -_winapi_OpenProcess_impl(PyObject *module, DWORD desired_access, - BOOL inherit_handle, DWORD process_id) -/*[clinic end generated code: output=b42b6b81ea5a0fc3 input=ec98c4cf4ea2ec36]*/ -{ - HANDLE handle; - +_winapi.OpenProcess -> HANDLE + + desired_access: DWORD + inherit_handle: BOOL + process_id: DWORD + / +[clinic start generated code]*/ + +static HANDLE +_winapi_OpenProcess_impl(PyObject *module, DWORD desired_access, + BOOL inherit_handle, DWORD process_id) +/*[clinic end generated code: output=b42b6b81ea5a0fc3 input=ec98c4cf4ea2ec36]*/ +{ + HANDLE handle; + if (PySys_Audit("_winapi.OpenProcess", "II", process_id, desired_access) < 0) { return INVALID_HANDLE_VALUE; } Py_BEGIN_ALLOW_THREADS - handle = OpenProcess(desired_access, inherit_handle, process_id); + handle = OpenProcess(desired_access, inherit_handle, process_id); Py_END_ALLOW_THREADS - if (handle == NULL) { + if (handle == NULL) { PyErr_SetFromWindowsErr(GetLastError()); - handle = INVALID_HANDLE_VALUE; - } - - return handle; -} - -/*[clinic input] -_winapi.PeekNamedPipe - - handle: HANDLE - size: int = 0 - / -[clinic start generated code]*/ - -static PyObject * -_winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size) -/*[clinic end generated code: output=d0c3e29e49d323dd input=c7aa53bfbce69d70]*/ -{ - PyObject *buf = NULL; - DWORD nread, navail, nleft; - BOOL ret; - - if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative size"); - return NULL; - } - - if (size) { - buf = PyBytes_FromStringAndSize(NULL, size); - if (!buf) - return NULL; - Py_BEGIN_ALLOW_THREADS - ret = PeekNamedPipe(handle, PyBytes_AS_STRING(buf), size, &nread, - &navail, &nleft); - Py_END_ALLOW_THREADS - if (!ret) { - Py_DECREF(buf); - return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); - } - if (_PyBytes_Resize(&buf, nread)) - return NULL; - return Py_BuildValue("NII", buf, navail, nleft); - } - else { - Py_BEGIN_ALLOW_THREADS - ret = PeekNamedPipe(handle, NULL, 0, NULL, &navail, &nleft); - Py_END_ALLOW_THREADS - if (!ret) { - return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); - } - return Py_BuildValue("II", navail, nleft); - } -} - -/*[clinic input] -_winapi.ReadFile - - handle: HANDLE - size: DWORD - overlapped as use_overlapped: bool(accept={int}) = False -[clinic start generated code]*/ - -static PyObject * -_winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, - int use_overlapped) -/*[clinic end generated code: output=d3d5b44a8201b944 input=08c439d03a11aac5]*/ -{ - DWORD nread; - PyObject *buf; - BOOL ret; - DWORD err; - OverlappedObject *overlapped = NULL; - - buf = PyBytes_FromStringAndSize(NULL, size); - if (!buf) - return NULL; - if (use_overlapped) { - overlapped = new_overlapped(handle); - if (!overlapped) { - Py_DECREF(buf); - return NULL; - } - /* Steals reference to buf */ - overlapped->read_buffer = buf; - } - - Py_BEGIN_ALLOW_THREADS - ret = ReadFile(handle, PyBytes_AS_STRING(buf), size, &nread, - overlapped ? &overlapped->overlapped : NULL); - Py_END_ALLOW_THREADS - - err = ret ? 0 : GetLastError(); - - if (overlapped) { - if (!ret) { - if (err == ERROR_IO_PENDING) - overlapped->pending = 1; - else if (err != ERROR_MORE_DATA) { - Py_DECREF(overlapped); - return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); - } - } - return Py_BuildValue("NI", (PyObject *) overlapped, err); - } - - if (!ret && err != ERROR_MORE_DATA) { - Py_DECREF(buf); - return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); - } - if (_PyBytes_Resize(&buf, nread)) - return NULL; - return Py_BuildValue("NI", buf, err); -} - -/*[clinic input] -_winapi.SetNamedPipeHandleState - - named_pipe: HANDLE - mode: object - max_collection_count: object - collect_data_timeout: object - / -[clinic start generated code]*/ - -static PyObject * -_winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe, - PyObject *mode, - PyObject *max_collection_count, - PyObject *collect_data_timeout) -/*[clinic end generated code: output=f2129d222cbfa095 input=9142d72163d0faa6]*/ -{ - PyObject *oArgs[3] = {mode, max_collection_count, collect_data_timeout}; - DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL}; - int i; + handle = INVALID_HANDLE_VALUE; + } + + return handle; +} + +/*[clinic input] +_winapi.PeekNamedPipe + + handle: HANDLE + size: int = 0 + / +[clinic start generated code]*/ + +static PyObject * +_winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size) +/*[clinic end generated code: output=d0c3e29e49d323dd input=c7aa53bfbce69d70]*/ +{ + PyObject *buf = NULL; + DWORD nread, navail, nleft; + BOOL ret; + + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative size"); + return NULL; + } + + if (size) { + buf = PyBytes_FromStringAndSize(NULL, size); + if (!buf) + return NULL; + Py_BEGIN_ALLOW_THREADS + ret = PeekNamedPipe(handle, PyBytes_AS_STRING(buf), size, &nread, + &navail, &nleft); + Py_END_ALLOW_THREADS + if (!ret) { + Py_DECREF(buf); + return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); + } + if (_PyBytes_Resize(&buf, nread)) + return NULL; + return Py_BuildValue("NII", buf, navail, nleft); + } + else { + Py_BEGIN_ALLOW_THREADS + ret = PeekNamedPipe(handle, NULL, 0, NULL, &navail, &nleft); + Py_END_ALLOW_THREADS + if (!ret) { + return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); + } + return Py_BuildValue("II", navail, nleft); + } +} + +/*[clinic input] +_winapi.ReadFile + + handle: HANDLE + size: DWORD + overlapped as use_overlapped: bool(accept={int}) = False +[clinic start generated code]*/ + +static PyObject * +_winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, + int use_overlapped) +/*[clinic end generated code: output=d3d5b44a8201b944 input=08c439d03a11aac5]*/ +{ + DWORD nread; + PyObject *buf; + BOOL ret; + DWORD err; + OverlappedObject *overlapped = NULL; + + buf = PyBytes_FromStringAndSize(NULL, size); + if (!buf) + return NULL; + if (use_overlapped) { + overlapped = new_overlapped(handle); + if (!overlapped) { + Py_DECREF(buf); + return NULL; + } + /* Steals reference to buf */ + overlapped->read_buffer = buf; + } + + Py_BEGIN_ALLOW_THREADS + ret = ReadFile(handle, PyBytes_AS_STRING(buf), size, &nread, + overlapped ? &overlapped->overlapped : NULL); + Py_END_ALLOW_THREADS + + err = ret ? 0 : GetLastError(); + + if (overlapped) { + if (!ret) { + if (err == ERROR_IO_PENDING) + overlapped->pending = 1; + else if (err != ERROR_MORE_DATA) { + Py_DECREF(overlapped); + return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); + } + } + return Py_BuildValue("NI", (PyObject *) overlapped, err); + } + + if (!ret && err != ERROR_MORE_DATA) { + Py_DECREF(buf); + return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); + } + if (_PyBytes_Resize(&buf, nread)) + return NULL; + return Py_BuildValue("NI", buf, err); +} + +/*[clinic input] +_winapi.SetNamedPipeHandleState + + named_pipe: HANDLE + mode: object + max_collection_count: object + collect_data_timeout: object + / +[clinic start generated code]*/ + +static PyObject * +_winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe, + PyObject *mode, + PyObject *max_collection_count, + PyObject *collect_data_timeout) +/*[clinic end generated code: output=f2129d222cbfa095 input=9142d72163d0faa6]*/ +{ + PyObject *oArgs[3] = {mode, max_collection_count, collect_data_timeout}; + DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL}; + int i; BOOL b; - - for (i = 0 ; i < 3 ; i++) { - if (oArgs[i] != Py_None) { - dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]); - if (PyErr_Occurred()) - return NULL; - pArgs[i] = &dwArgs[i]; - } - } - + + for (i = 0 ; i < 3 ; i++) { + if (oArgs[i] != Py_None) { + dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]); + if (PyErr_Occurred()) + return NULL; + pArgs[i] = &dwArgs[i]; + } + } + Py_BEGIN_ALLOW_THREADS b = SetNamedPipeHandleState(named_pipe, pArgs[0], pArgs[1], pArgs[2]); Py_END_ALLOW_THREADS if (!b) - return PyErr_SetFromWindowsErr(0); - - Py_RETURN_NONE; -} - - -/*[clinic input] -_winapi.TerminateProcess - - handle: HANDLE - exit_code: UINT - / - -Terminate the specified process and all of its threads. -[clinic start generated code]*/ - -static PyObject * -_winapi_TerminateProcess_impl(PyObject *module, HANDLE handle, - UINT exit_code) -/*[clinic end generated code: output=f4e99ac3f0b1f34a input=d6bc0aa1ee3bb4df]*/ -{ - BOOL result; - + return PyErr_SetFromWindowsErr(0); + + Py_RETURN_NONE; +} + + +/*[clinic input] +_winapi.TerminateProcess + + handle: HANDLE + exit_code: UINT + / + +Terminate the specified process and all of its threads. +[clinic start generated code]*/ + +static PyObject * +_winapi_TerminateProcess_impl(PyObject *module, HANDLE handle, + UINT exit_code) +/*[clinic end generated code: output=f4e99ac3f0b1f34a input=d6bc0aa1ee3bb4df]*/ +{ + BOOL result; + if (PySys_Audit("_winapi.TerminateProcess", "nI", (Py_ssize_t)handle, exit_code) < 0) { return NULL; } - result = TerminateProcess(handle, exit_code); - - if (! result) - return PyErr_SetFromWindowsErr(GetLastError()); - - Py_RETURN_NONE; -} - -/*[clinic input] + result = TerminateProcess(handle, exit_code); + + if (! result) + return PyErr_SetFromWindowsErr(GetLastError()); + + Py_RETURN_NONE; +} + +/*[clinic input] _winapi.VirtualQuerySize -> size_t address: LPCVOID @@ -1663,326 +1663,326 @@ _winapi_VirtualQuerySize_impl(PyObject *module, LPCVOID address) } /*[clinic input] -_winapi.WaitNamedPipe - - name: LPCTSTR - timeout: DWORD - / -[clinic start generated code]*/ - -static PyObject * -_winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout) -/*[clinic end generated code: output=c2866f4439b1fe38 input=36fc781291b1862c]*/ -{ - BOOL success; - - Py_BEGIN_ALLOW_THREADS - success = WaitNamedPipe(name, timeout); - Py_END_ALLOW_THREADS - - if (!success) - return PyErr_SetFromWindowsErr(0); - - Py_RETURN_NONE; -} - -/*[clinic input] -_winapi.WaitForMultipleObjects - - handle_seq: object - wait_flag: BOOL - milliseconds: DWORD(c_default='INFINITE') = _winapi.INFINITE - / -[clinic start generated code]*/ - -static PyObject * -_winapi_WaitForMultipleObjects_impl(PyObject *module, PyObject *handle_seq, - BOOL wait_flag, DWORD milliseconds) -/*[clinic end generated code: output=295e3f00b8e45899 input=36f76ca057cd28a0]*/ -{ - DWORD result; - HANDLE handles[MAXIMUM_WAIT_OBJECTS]; - HANDLE sigint_event = NULL; - Py_ssize_t nhandles, i; - - if (!PySequence_Check(handle_seq)) { - PyErr_Format(PyExc_TypeError, - "sequence type expected, got '%s'", - Py_TYPE(handle_seq)->tp_name); - return NULL; - } - nhandles = PySequence_Length(handle_seq); - if (nhandles == -1) - return NULL; +_winapi.WaitNamedPipe + + name: LPCTSTR + timeout: DWORD + / +[clinic start generated code]*/ + +static PyObject * +_winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout) +/*[clinic end generated code: output=c2866f4439b1fe38 input=36fc781291b1862c]*/ +{ + BOOL success; + + Py_BEGIN_ALLOW_THREADS + success = WaitNamedPipe(name, timeout); + Py_END_ALLOW_THREADS + + if (!success) + return PyErr_SetFromWindowsErr(0); + + Py_RETURN_NONE; +} + +/*[clinic input] +_winapi.WaitForMultipleObjects + + handle_seq: object + wait_flag: BOOL + milliseconds: DWORD(c_default='INFINITE') = _winapi.INFINITE + / +[clinic start generated code]*/ + +static PyObject * +_winapi_WaitForMultipleObjects_impl(PyObject *module, PyObject *handle_seq, + BOOL wait_flag, DWORD milliseconds) +/*[clinic end generated code: output=295e3f00b8e45899 input=36f76ca057cd28a0]*/ +{ + DWORD result; + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + HANDLE sigint_event = NULL; + Py_ssize_t nhandles, i; + + if (!PySequence_Check(handle_seq)) { + PyErr_Format(PyExc_TypeError, + "sequence type expected, got '%s'", + Py_TYPE(handle_seq)->tp_name); + return NULL; + } + nhandles = PySequence_Length(handle_seq); + if (nhandles == -1) + return NULL; if (nhandles < 0 || nhandles > MAXIMUM_WAIT_OBJECTS - 1) { - PyErr_Format(PyExc_ValueError, - "need at most %zd handles, got a sequence of length %zd", - MAXIMUM_WAIT_OBJECTS - 1, nhandles); - return NULL; - } - for (i = 0; i < nhandles; i++) { - HANDLE h; - PyObject *v = PySequence_GetItem(handle_seq, i); - if (v == NULL) - return NULL; - if (!PyArg_Parse(v, F_HANDLE, &h)) { - Py_DECREF(v); - return NULL; - } - handles[i] = h; - Py_DECREF(v); - } - /* If this is the main thread then make the wait interruptible - by Ctrl-C unless we are waiting for *all* handles */ - if (!wait_flag && _PyOS_IsMainThread()) { - sigint_event = _PyOS_SigintEvent(); - assert(sigint_event != NULL); - handles[nhandles++] = sigint_event; - } - - Py_BEGIN_ALLOW_THREADS - if (sigint_event != NULL) - ResetEvent(sigint_event); - result = WaitForMultipleObjects((DWORD) nhandles, handles, - wait_flag, milliseconds); - Py_END_ALLOW_THREADS - - if (result == WAIT_FAILED) - return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); - else if (sigint_event != NULL && result == WAIT_OBJECT_0 + nhandles - 1) { - errno = EINTR; - return PyErr_SetFromErrno(PyExc_OSError); - } - - return PyLong_FromLong((int) result); -} - -/*[clinic input] -_winapi.WaitForSingleObject -> long - - handle: HANDLE - milliseconds: DWORD - / - -Wait for a single object. - -Wait until the specified object is in the signaled state or -the time-out interval elapses. The timeout value is specified -in milliseconds. -[clinic start generated code]*/ - -static long -_winapi_WaitForSingleObject_impl(PyObject *module, HANDLE handle, - DWORD milliseconds) -/*[clinic end generated code: output=3c4715d8f1b39859 input=443d1ab076edc7b1]*/ -{ - DWORD result; - - Py_BEGIN_ALLOW_THREADS - result = WaitForSingleObject(handle, milliseconds); - Py_END_ALLOW_THREADS - - if (result == WAIT_FAILED) { - PyErr_SetFromWindowsErr(GetLastError()); - return -1; - } - - return result; -} - -/*[clinic input] -_winapi.WriteFile - - handle: HANDLE - buffer: object - overlapped as use_overlapped: bool(accept={int}) = False -[clinic start generated code]*/ - -static PyObject * -_winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, - int use_overlapped) -/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=11eae2a03aa32731]*/ -{ - Py_buffer _buf, *buf; - DWORD len, written; - BOOL ret; - DWORD err; - OverlappedObject *overlapped = NULL; - - if (use_overlapped) { - overlapped = new_overlapped(handle); - if (!overlapped) - return NULL; - buf = &overlapped->write_buffer; - } - else - buf = &_buf; - - if (!PyArg_Parse(buffer, "y*", buf)) { - Py_XDECREF(overlapped); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - len = (DWORD)Py_MIN(buf->len, PY_DWORD_MAX); - ret = WriteFile(handle, buf->buf, len, &written, - overlapped ? &overlapped->overlapped : NULL); - Py_END_ALLOW_THREADS - - err = ret ? 0 : GetLastError(); - - if (overlapped) { - if (!ret) { - if (err == ERROR_IO_PENDING) - overlapped->pending = 1; - else { - Py_DECREF(overlapped); - return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); - } - } - return Py_BuildValue("NI", (PyObject *) overlapped, err); - } - - PyBuffer_Release(buf); - if (!ret) - return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); - return Py_BuildValue("II", written, err); -} - -/*[clinic input] -_winapi.GetACP - -Get the current Windows ANSI code page identifier. -[clinic start generated code]*/ - -static PyObject * -_winapi_GetACP_impl(PyObject *module) -/*[clinic end generated code: output=f7ee24bf705dbb88 input=1433c96d03a05229]*/ -{ - return PyLong_FromUnsignedLong(GetACP()); -} - -/*[clinic input] -_winapi.GetFileType -> DWORD - - handle: HANDLE -[clinic start generated code]*/ - -static DWORD -_winapi_GetFileType_impl(PyObject *module, HANDLE handle) -/*[clinic end generated code: output=92b8466ac76ecc17 input=0058366bc40bbfbf]*/ -{ - DWORD result; - - Py_BEGIN_ALLOW_THREADS - result = GetFileType(handle); - Py_END_ALLOW_THREADS - - if (result == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR) { - PyErr_SetFromWindowsErr(0); - return -1; - } - - return result; -} - - -static PyMethodDef winapi_functions[] = { - _WINAPI_CLOSEHANDLE_METHODDEF - _WINAPI_CONNECTNAMEDPIPE_METHODDEF - _WINAPI_CREATEFILE_METHODDEF + PyErr_Format(PyExc_ValueError, + "need at most %zd handles, got a sequence of length %zd", + MAXIMUM_WAIT_OBJECTS - 1, nhandles); + return NULL; + } + for (i = 0; i < nhandles; i++) { + HANDLE h; + PyObject *v = PySequence_GetItem(handle_seq, i); + if (v == NULL) + return NULL; + if (!PyArg_Parse(v, F_HANDLE, &h)) { + Py_DECREF(v); + return NULL; + } + handles[i] = h; + Py_DECREF(v); + } + /* If this is the main thread then make the wait interruptible + by Ctrl-C unless we are waiting for *all* handles */ + if (!wait_flag && _PyOS_IsMainThread()) { + sigint_event = _PyOS_SigintEvent(); + assert(sigint_event != NULL); + handles[nhandles++] = sigint_event; + } + + Py_BEGIN_ALLOW_THREADS + if (sigint_event != NULL) + ResetEvent(sigint_event); + result = WaitForMultipleObjects((DWORD) nhandles, handles, + wait_flag, milliseconds); + Py_END_ALLOW_THREADS + + if (result == WAIT_FAILED) + return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); + else if (sigint_event != NULL && result == WAIT_OBJECT_0 + nhandles - 1) { + errno = EINTR; + return PyErr_SetFromErrno(PyExc_OSError); + } + + return PyLong_FromLong((int) result); +} + +/*[clinic input] +_winapi.WaitForSingleObject -> long + + handle: HANDLE + milliseconds: DWORD + / + +Wait for a single object. + +Wait until the specified object is in the signaled state or +the time-out interval elapses. The timeout value is specified +in milliseconds. +[clinic start generated code]*/ + +static long +_winapi_WaitForSingleObject_impl(PyObject *module, HANDLE handle, + DWORD milliseconds) +/*[clinic end generated code: output=3c4715d8f1b39859 input=443d1ab076edc7b1]*/ +{ + DWORD result; + + Py_BEGIN_ALLOW_THREADS + result = WaitForSingleObject(handle, milliseconds); + Py_END_ALLOW_THREADS + + if (result == WAIT_FAILED) { + PyErr_SetFromWindowsErr(GetLastError()); + return -1; + } + + return result; +} + +/*[clinic input] +_winapi.WriteFile + + handle: HANDLE + buffer: object + overlapped as use_overlapped: bool(accept={int}) = False +[clinic start generated code]*/ + +static PyObject * +_winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, + int use_overlapped) +/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=11eae2a03aa32731]*/ +{ + Py_buffer _buf, *buf; + DWORD len, written; + BOOL ret; + DWORD err; + OverlappedObject *overlapped = NULL; + + if (use_overlapped) { + overlapped = new_overlapped(handle); + if (!overlapped) + return NULL; + buf = &overlapped->write_buffer; + } + else + buf = &_buf; + + if (!PyArg_Parse(buffer, "y*", buf)) { + Py_XDECREF(overlapped); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + len = (DWORD)Py_MIN(buf->len, PY_DWORD_MAX); + ret = WriteFile(handle, buf->buf, len, &written, + overlapped ? &overlapped->overlapped : NULL); + Py_END_ALLOW_THREADS + + err = ret ? 0 : GetLastError(); + + if (overlapped) { + if (!ret) { + if (err == ERROR_IO_PENDING) + overlapped->pending = 1; + else { + Py_DECREF(overlapped); + return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); + } + } + return Py_BuildValue("NI", (PyObject *) overlapped, err); + } + + PyBuffer_Release(buf); + if (!ret) + return PyErr_SetExcFromWindowsErr(PyExc_OSError, 0); + return Py_BuildValue("II", written, err); +} + +/*[clinic input] +_winapi.GetACP + +Get the current Windows ANSI code page identifier. +[clinic start generated code]*/ + +static PyObject * +_winapi_GetACP_impl(PyObject *module) +/*[clinic end generated code: output=f7ee24bf705dbb88 input=1433c96d03a05229]*/ +{ + return PyLong_FromUnsignedLong(GetACP()); +} + +/*[clinic input] +_winapi.GetFileType -> DWORD + + handle: HANDLE +[clinic start generated code]*/ + +static DWORD +_winapi_GetFileType_impl(PyObject *module, HANDLE handle) +/*[clinic end generated code: output=92b8466ac76ecc17 input=0058366bc40bbfbf]*/ +{ + DWORD result; + + Py_BEGIN_ALLOW_THREADS + result = GetFileType(handle); + Py_END_ALLOW_THREADS + + if (result == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR) { + PyErr_SetFromWindowsErr(0); + return -1; + } + + return result; +} + + +static PyMethodDef winapi_functions[] = { + _WINAPI_CLOSEHANDLE_METHODDEF + _WINAPI_CONNECTNAMEDPIPE_METHODDEF + _WINAPI_CREATEFILE_METHODDEF _WINAPI_CREATEFILEMAPPING_METHODDEF - _WINAPI_CREATENAMEDPIPE_METHODDEF - _WINAPI_CREATEPIPE_METHODDEF - _WINAPI_CREATEPROCESS_METHODDEF - _WINAPI_CREATEJUNCTION_METHODDEF - _WINAPI_DUPLICATEHANDLE_METHODDEF - _WINAPI_EXITPROCESS_METHODDEF - _WINAPI_GETCURRENTPROCESS_METHODDEF - _WINAPI_GETEXITCODEPROCESS_METHODDEF - _WINAPI_GETLASTERROR_METHODDEF - _WINAPI_GETMODULEFILENAME_METHODDEF - _WINAPI_GETSTDHANDLE_METHODDEF - _WINAPI_GETVERSION_METHODDEF + _WINAPI_CREATENAMEDPIPE_METHODDEF + _WINAPI_CREATEPIPE_METHODDEF + _WINAPI_CREATEPROCESS_METHODDEF + _WINAPI_CREATEJUNCTION_METHODDEF + _WINAPI_DUPLICATEHANDLE_METHODDEF + _WINAPI_EXITPROCESS_METHODDEF + _WINAPI_GETCURRENTPROCESS_METHODDEF + _WINAPI_GETEXITCODEPROCESS_METHODDEF + _WINAPI_GETLASTERROR_METHODDEF + _WINAPI_GETMODULEFILENAME_METHODDEF + _WINAPI_GETSTDHANDLE_METHODDEF + _WINAPI_GETVERSION_METHODDEF _WINAPI_MAPVIEWOFFILE_METHODDEF _WINAPI_OPENFILEMAPPING_METHODDEF - _WINAPI_OPENPROCESS_METHODDEF - _WINAPI_PEEKNAMEDPIPE_METHODDEF - _WINAPI_READFILE_METHODDEF - _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF - _WINAPI_TERMINATEPROCESS_METHODDEF + _WINAPI_OPENPROCESS_METHODDEF + _WINAPI_PEEKNAMEDPIPE_METHODDEF + _WINAPI_READFILE_METHODDEF + _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF + _WINAPI_TERMINATEPROCESS_METHODDEF _WINAPI_VIRTUALQUERYSIZE_METHODDEF - _WINAPI_WAITNAMEDPIPE_METHODDEF - _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF - _WINAPI_WAITFORSINGLEOBJECT_METHODDEF - _WINAPI_WRITEFILE_METHODDEF - _WINAPI_GETACP_METHODDEF - _WINAPI_GETFILETYPE_METHODDEF - {NULL, NULL} -}; - -static struct PyModuleDef winapi_module = { - PyModuleDef_HEAD_INIT, - "_winapi", - NULL, - -1, - winapi_functions, - NULL, - NULL, - NULL, - NULL -}; - -#define WINAPI_CONSTANT(fmt, con) \ - PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) - -PyMODINIT_FUNC -PyInit__winapi(void) -{ - PyObject *d; - PyObject *m; - - if (PyType_Ready(&WinApiOverlappedType) < 0) - return NULL; - - m = PyModule_Create(&winapi_module); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - - PyDict_SetItemString(d, "Overlapped", (PyObject *) &WinApiOverlappedType); - - /* constants */ - WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE); - WINAPI_CONSTANT(F_DWORD, CREATE_NEW_PROCESS_GROUP); - WINAPI_CONSTANT(F_DWORD, DUPLICATE_SAME_ACCESS); - WINAPI_CONSTANT(F_DWORD, DUPLICATE_CLOSE_SOURCE); - WINAPI_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS); - WINAPI_CONSTANT(F_DWORD, ERROR_BROKEN_PIPE); - WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); - WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA); - WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); - WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES); - WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA); - WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); - WINAPI_CONSTANT(F_DWORD, ERROR_NO_DATA); - WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES); - WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED); - WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY); - WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED); - WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT); - WINAPI_CONSTANT(F_DWORD, FILE_FLAG_FIRST_PIPE_INSTANCE); - WINAPI_CONSTANT(F_DWORD, FILE_FLAG_OVERLAPPED); - WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_READ); - WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_WRITE); + _WINAPI_WAITNAMEDPIPE_METHODDEF + _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF + _WINAPI_WAITFORSINGLEOBJECT_METHODDEF + _WINAPI_WRITEFILE_METHODDEF + _WINAPI_GETACP_METHODDEF + _WINAPI_GETFILETYPE_METHODDEF + {NULL, NULL} +}; + +static struct PyModuleDef winapi_module = { + PyModuleDef_HEAD_INIT, + "_winapi", + NULL, + -1, + winapi_functions, + NULL, + NULL, + NULL, + NULL +}; + +#define WINAPI_CONSTANT(fmt, con) \ + PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) + +PyMODINIT_FUNC +PyInit__winapi(void) +{ + PyObject *d; + PyObject *m; + + if (PyType_Ready(&WinApiOverlappedType) < 0) + return NULL; + + m = PyModule_Create(&winapi_module); + if (m == NULL) + return NULL; + d = PyModule_GetDict(m); + + PyDict_SetItemString(d, "Overlapped", (PyObject *) &WinApiOverlappedType); + + /* constants */ + WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE); + WINAPI_CONSTANT(F_DWORD, CREATE_NEW_PROCESS_GROUP); + WINAPI_CONSTANT(F_DWORD, DUPLICATE_SAME_ACCESS); + WINAPI_CONSTANT(F_DWORD, DUPLICATE_CLOSE_SOURCE); + WINAPI_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS); + WINAPI_CONSTANT(F_DWORD, ERROR_BROKEN_PIPE); + WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); + WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA); + WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); + WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES); + WINAPI_CONSTANT(F_DWORD, ERROR_MORE_DATA); + WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); + WINAPI_CONSTANT(F_DWORD, ERROR_NO_DATA); + WINAPI_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES); + WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED); + WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY); + WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED); + WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT); + WINAPI_CONSTANT(F_DWORD, FILE_FLAG_FIRST_PIPE_INSTANCE); + WINAPI_CONSTANT(F_DWORD, FILE_FLAG_OVERLAPPED); + WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_READ); + WINAPI_CONSTANT(F_DWORD, FILE_GENERIC_WRITE); WINAPI_CONSTANT(F_DWORD, FILE_MAP_ALL_ACCESS); WINAPI_CONSTANT(F_DWORD, FILE_MAP_COPY); WINAPI_CONSTANT(F_DWORD, FILE_MAP_EXECUTE); WINAPI_CONSTANT(F_DWORD, FILE_MAP_READ); WINAPI_CONSTANT(F_DWORD, FILE_MAP_WRITE); - WINAPI_CONSTANT(F_DWORD, GENERIC_READ); - WINAPI_CONSTANT(F_DWORD, GENERIC_WRITE); - WINAPI_CONSTANT(F_DWORD, INFINITE); + WINAPI_CONSTANT(F_DWORD, GENERIC_READ); + WINAPI_CONSTANT(F_DWORD, GENERIC_WRITE); + WINAPI_CONSTANT(F_DWORD, INFINITE); WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE); WINAPI_CONSTANT(F_DWORD, MEM_COMMIT); WINAPI_CONSTANT(F_DWORD, MEM_FREE); @@ -1990,8 +1990,8 @@ PyInit__winapi(void) WINAPI_CONSTANT(F_DWORD, MEM_MAPPED); WINAPI_CONSTANT(F_DWORD, MEM_PRIVATE); WINAPI_CONSTANT(F_DWORD, MEM_RESERVE); - WINAPI_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER); - WINAPI_CONSTANT(F_DWORD, OPEN_EXISTING); + WINAPI_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER); + WINAPI_CONSTANT(F_DWORD, OPEN_EXISTING); WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE); WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READ); WINAPI_CONSTANT(F_DWORD, PAGE_EXECUTE_READWRITE); @@ -2003,51 +2003,51 @@ PyInit__winapi(void) WINAPI_CONSTANT(F_DWORD, PAGE_READWRITE); WINAPI_CONSTANT(F_DWORD, PAGE_WRITECOMBINE); WINAPI_CONSTANT(F_DWORD, PAGE_WRITECOPY); - WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX); - WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND); - WINAPI_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE); - WINAPI_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE); - WINAPI_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES); - WINAPI_CONSTANT(F_DWORD, PIPE_WAIT); - WINAPI_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS); + WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX); + WINAPI_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND); + WINAPI_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE); + WINAPI_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE); + WINAPI_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES); + WINAPI_CONSTANT(F_DWORD, PIPE_WAIT); + WINAPI_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS); WINAPI_CONSTANT(F_DWORD, SYNCHRONIZE); - WINAPI_CONSTANT(F_DWORD, PROCESS_DUP_HANDLE); + WINAPI_CONSTANT(F_DWORD, PROCESS_DUP_HANDLE); WINAPI_CONSTANT(F_DWORD, SEC_COMMIT); WINAPI_CONSTANT(F_DWORD, SEC_IMAGE); WINAPI_CONSTANT(F_DWORD, SEC_LARGE_PAGES); WINAPI_CONSTANT(F_DWORD, SEC_NOCACHE); WINAPI_CONSTANT(F_DWORD, SEC_RESERVE); WINAPI_CONSTANT(F_DWORD, SEC_WRITECOMBINE); - WINAPI_CONSTANT(F_DWORD, STARTF_USESHOWWINDOW); - WINAPI_CONSTANT(F_DWORD, STARTF_USESTDHANDLES); - WINAPI_CONSTANT(F_DWORD, STD_INPUT_HANDLE); - WINAPI_CONSTANT(F_DWORD, STD_OUTPUT_HANDLE); - WINAPI_CONSTANT(F_DWORD, STD_ERROR_HANDLE); - WINAPI_CONSTANT(F_DWORD, STILL_ACTIVE); - WINAPI_CONSTANT(F_DWORD, SW_HIDE); - WINAPI_CONSTANT(F_DWORD, WAIT_OBJECT_0); - WINAPI_CONSTANT(F_DWORD, WAIT_ABANDONED_0); - WINAPI_CONSTANT(F_DWORD, WAIT_TIMEOUT); - - WINAPI_CONSTANT(F_DWORD, ABOVE_NORMAL_PRIORITY_CLASS); - WINAPI_CONSTANT(F_DWORD, BELOW_NORMAL_PRIORITY_CLASS); - WINAPI_CONSTANT(F_DWORD, HIGH_PRIORITY_CLASS); - WINAPI_CONSTANT(F_DWORD, IDLE_PRIORITY_CLASS); - WINAPI_CONSTANT(F_DWORD, NORMAL_PRIORITY_CLASS); - WINAPI_CONSTANT(F_DWORD, REALTIME_PRIORITY_CLASS); - - WINAPI_CONSTANT(F_DWORD, CREATE_NO_WINDOW); - WINAPI_CONSTANT(F_DWORD, DETACHED_PROCESS); - WINAPI_CONSTANT(F_DWORD, CREATE_DEFAULT_ERROR_MODE); - WINAPI_CONSTANT(F_DWORD, CREATE_BREAKAWAY_FROM_JOB); - - WINAPI_CONSTANT(F_DWORD, FILE_TYPE_UNKNOWN); - WINAPI_CONSTANT(F_DWORD, FILE_TYPE_DISK); - WINAPI_CONSTANT(F_DWORD, FILE_TYPE_CHAR); - WINAPI_CONSTANT(F_DWORD, FILE_TYPE_PIPE); - WINAPI_CONSTANT(F_DWORD, FILE_TYPE_REMOTE); - - WINAPI_CONSTANT("i", NULL); - - return m; -} + WINAPI_CONSTANT(F_DWORD, STARTF_USESHOWWINDOW); + WINAPI_CONSTANT(F_DWORD, STARTF_USESTDHANDLES); + WINAPI_CONSTANT(F_DWORD, STD_INPUT_HANDLE); + WINAPI_CONSTANT(F_DWORD, STD_OUTPUT_HANDLE); + WINAPI_CONSTANT(F_DWORD, STD_ERROR_HANDLE); + WINAPI_CONSTANT(F_DWORD, STILL_ACTIVE); + WINAPI_CONSTANT(F_DWORD, SW_HIDE); + WINAPI_CONSTANT(F_DWORD, WAIT_OBJECT_0); + WINAPI_CONSTANT(F_DWORD, WAIT_ABANDONED_0); + WINAPI_CONSTANT(F_DWORD, WAIT_TIMEOUT); + + WINAPI_CONSTANT(F_DWORD, ABOVE_NORMAL_PRIORITY_CLASS); + WINAPI_CONSTANT(F_DWORD, BELOW_NORMAL_PRIORITY_CLASS); + WINAPI_CONSTANT(F_DWORD, HIGH_PRIORITY_CLASS); + WINAPI_CONSTANT(F_DWORD, IDLE_PRIORITY_CLASS); + WINAPI_CONSTANT(F_DWORD, NORMAL_PRIORITY_CLASS); + WINAPI_CONSTANT(F_DWORD, REALTIME_PRIORITY_CLASS); + + WINAPI_CONSTANT(F_DWORD, CREATE_NO_WINDOW); + WINAPI_CONSTANT(F_DWORD, DETACHED_PROCESS); + WINAPI_CONSTANT(F_DWORD, CREATE_DEFAULT_ERROR_MODE); + WINAPI_CONSTANT(F_DWORD, CREATE_BREAKAWAY_FROM_JOB); + + WINAPI_CONSTANT(F_DWORD, FILE_TYPE_UNKNOWN); + WINAPI_CONSTANT(F_DWORD, FILE_TYPE_DISK); + WINAPI_CONSTANT(F_DWORD, FILE_TYPE_CHAR); + WINAPI_CONSTANT(F_DWORD, FILE_TYPE_PIPE); + WINAPI_CONSTANT(F_DWORD, FILE_TYPE_REMOTE); + + WINAPI_CONSTANT("i", NULL); + + return m; +} diff --git a/contrib/tools/python3/src/Modules/_xxtestfuzz/_xxtestfuzz.c b/contrib/tools/python3/src/Modules/_xxtestfuzz/_xxtestfuzz.c index e0694de6719..c21d467d150 100644 --- a/contrib/tools/python3/src/Modules/_xxtestfuzz/_xxtestfuzz.c +++ b/contrib/tools/python3/src/Modules/_xxtestfuzz/_xxtestfuzz.c @@ -1,48 +1,48 @@ -#define PY_SSIZE_T_CLEAN -#include -#include -#include - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -static PyObject* _fuzz_run(PyObject* self, PyObject* args) { - const char* buf; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "s#", &buf, &size)) { - return NULL; - } - int rv = LLVMFuzzerTestOneInput((const uint8_t*)buf, size); - if (PyErr_Occurred()) { - return NULL; - } - if (rv != 0) { - // Nonzero return codes are reserved for future use. - PyErr_Format( - PyExc_RuntimeError, "Nonzero return code from fuzzer: %d", rv); - return NULL; - } - Py_RETURN_NONE; -} - -static PyMethodDef module_methods[] = { - {"run", (PyCFunction)_fuzz_run, METH_VARARGS, ""}, - {NULL}, -}; - -static struct PyModuleDef _fuzzmodule = { - PyModuleDef_HEAD_INIT, - "_fuzz", - NULL, - 0, - module_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__xxtestfuzz(void) -{ +#define PY_SSIZE_T_CLEAN +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +static PyObject* _fuzz_run(PyObject* self, PyObject* args) { + const char* buf; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &buf, &size)) { + return NULL; + } + int rv = LLVMFuzzerTestOneInput((const uint8_t*)buf, size); + if (PyErr_Occurred()) { + return NULL; + } + if (rv != 0) { + // Nonzero return codes are reserved for future use. + PyErr_Format( + PyExc_RuntimeError, "Nonzero return code from fuzzer: %d", rv); + return NULL; + } + Py_RETURN_NONE; +} + +static PyMethodDef module_methods[] = { + {"run", (PyCFunction)_fuzz_run, METH_VARARGS, ""}, + {NULL}, +}; + +static struct PyModuleDef _fuzzmodule = { + PyModuleDef_HEAD_INIT, + "_fuzz", + NULL, + 0, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__xxtestfuzz(void) +{ return PyModule_Create(&_fuzzmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/_xxtestfuzz/fuzzer.c b/contrib/tools/python3/src/Modules/_xxtestfuzz/fuzzer.c index 6bd2c3aedcc..dbf6a446276 100644 --- a/contrib/tools/python3/src/Modules/_xxtestfuzz/fuzzer.c +++ b/contrib/tools/python3/src/Modules/_xxtestfuzz/fuzzer.c @@ -1,84 +1,84 @@ -/* A fuzz test for CPython. - - The only exposed function is LLVMFuzzerTestOneInput, which is called by - fuzzers and by the _fuzz module for smoke tests. - - To build exactly one fuzz test, as when running in oss-fuzz etc., - build with -D _Py_FUZZ_ONE and -D _Py_FUZZ_. e.g. to build - LLVMFuzzerTestOneInput to only run "fuzz_builtin_float", build this file with - -D _Py_FUZZ_ONE -D _Py_FUZZ_fuzz_builtin_float. - - See the source code for LLVMFuzzerTestOneInput for details. */ - -#include -#include -#include - -/* Fuzz PyFloat_FromString as a proxy for float(str). */ -static int fuzz_builtin_float(const char* data, size_t size) { - PyObject* s = PyBytes_FromStringAndSize(data, size); - if (s == NULL) return 0; - PyObject* f = PyFloat_FromString(s); - if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - } - - Py_XDECREF(f); - Py_DECREF(s); - return 0; -} - +/* A fuzz test for CPython. + + The only exposed function is LLVMFuzzerTestOneInput, which is called by + fuzzers and by the _fuzz module for smoke tests. + + To build exactly one fuzz test, as when running in oss-fuzz etc., + build with -D _Py_FUZZ_ONE and -D _Py_FUZZ_. e.g. to build + LLVMFuzzerTestOneInput to only run "fuzz_builtin_float", build this file with + -D _Py_FUZZ_ONE -D _Py_FUZZ_fuzz_builtin_float. + + See the source code for LLVMFuzzerTestOneInput for details. */ + +#include +#include +#include + +/* Fuzz PyFloat_FromString as a proxy for float(str). */ +static int fuzz_builtin_float(const char* data, size_t size) { + PyObject* s = PyBytes_FromStringAndSize(data, size); + if (s == NULL) return 0; + PyObject* f = PyFloat_FromString(s); + if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + } + + Py_XDECREF(f); + Py_DECREF(s); + return 0; +} + #define MAX_INT_TEST_SIZE 0x10000 -/* Fuzz PyLong_FromUnicodeObject as a proxy for int(str). */ -static int fuzz_builtin_int(const char* data, size_t size) { +/* Fuzz PyLong_FromUnicodeObject as a proxy for int(str). */ +static int fuzz_builtin_int(const char* data, size_t size) { /* Ignore test cases with very long ints to avoid timeouts int("9" * 1000000) is not a very interesting test caase */ if (size > MAX_INT_TEST_SIZE) { return 0; } - /* Pick a random valid base. (When the fuzzed function takes extra - parameters, it's somewhat normal to hash the input to generate those - parameters. We want to exercise all code paths, so we do so here.) */ - int base = _Py_HashBytes(data, size) % 37; - if (base == 1) { - // 1 is the only number between 0 and 36 that is not a valid base. - base = 0; - } - if (base == -1) { - return 0; // An error occurred, bail early. - } - if (base < 0) { - base = -base; - } - - PyObject* s = PyUnicode_FromStringAndSize(data, size); - if (s == NULL) { - if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { - PyErr_Clear(); - } - return 0; - } - PyObject* l = PyLong_FromUnicodeObject(s, base); - if (l == NULL && PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - } - PyErr_Clear(); - Py_XDECREF(l); - Py_DECREF(s); - return 0; -} - -/* Fuzz PyUnicode_FromStringAndSize as a proxy for unicode(str). */ -static int fuzz_builtin_unicode(const char* data, size_t size) { - PyObject* s = PyUnicode_FromStringAndSize(data, size); - if (s == NULL && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { - PyErr_Clear(); - } - Py_XDECREF(s); - return 0; -} - + /* Pick a random valid base. (When the fuzzed function takes extra + parameters, it's somewhat normal to hash the input to generate those + parameters. We want to exercise all code paths, so we do so here.) */ + int base = _Py_HashBytes(data, size) % 37; + if (base == 1) { + // 1 is the only number between 0 and 36 that is not a valid base. + base = 0; + } + if (base == -1) { + return 0; // An error occurred, bail early. + } + if (base < 0) { + base = -base; + } + + PyObject* s = PyUnicode_FromStringAndSize(data, size); + if (s == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + PyErr_Clear(); + } + return 0; + } + PyObject* l = PyLong_FromUnicodeObject(s, base); + if (l == NULL && PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + } + PyErr_Clear(); + Py_XDECREF(l); + Py_DECREF(s); + return 0; +} + +/* Fuzz PyUnicode_FromStringAndSize as a proxy for unicode(str). */ +static int fuzz_builtin_unicode(const char* data, size_t size) { + PyObject* s = PyUnicode_FromStringAndSize(data, size); + if (s == NULL && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + PyErr_Clear(); + } + Py_XDECREF(s); + return 0; +} + PyObject* struct_unpack_method = NULL; PyObject* struct_error = NULL; @@ -393,22 +393,22 @@ static int fuzz_csv_reader(const char* data, size_t size) { return 0; } -/* Run fuzzer and abort on failure. */ -static int _run_fuzz(const uint8_t *data, size_t size, int(*fuzzer)(const char* , size_t)) { - int rv = fuzzer((const char*) data, size); - if (PyErr_Occurred()) { - /* Fuzz tests should handle expected errors for themselves. - This is last-ditch check in case they didn't. */ - PyErr_Print(); - abort(); - } - /* Someday the return value might mean something, propagate it. */ - return rv; -} - -/* CPython generates a lot of leak warnings for whatever reason. */ -int __lsan_is_turned_off(void) { return 1; } - +/* Run fuzzer and abort on failure. */ +static int _run_fuzz(const uint8_t *data, size_t size, int(*fuzzer)(const char* , size_t)) { + int rv = fuzzer((const char*) data, size); + if (PyErr_Occurred()) { + /* Fuzz tests should handle expected errors for themselves. + This is last-ditch check in case they didn't. */ + PyErr_Print(); + abort(); + } + /* Someday the return value might mean something, propagate it. */ + return rv; +} + +/* CPython generates a lot of leak warnings for whatever reason. */ +int __lsan_is_turned_off(void) { return 1; } + int LLVMFuzzerInitialize(int *argc, char ***argv) { wchar_t* wide_program_name = Py_DecodeLocale(*argv[0], NULL); @@ -416,32 +416,32 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { return 0; } -/* Fuzz test interface. - This returns the bitwise or of all fuzz test's return values. - - All fuzz tests must return 0, as all nonzero return codes are reserved for - future use -- we propagate the return values for that future case. - (And we bitwise or when running multiple tests to verify that normally we - only return 0.) */ -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - if (!Py_IsInitialized()) { - /* LLVMFuzzerTestOneInput is called repeatedly from the same process, - with no separate initialization phase, sadly, so we need to - initialize CPython ourselves on the first run. */ - Py_InitializeEx(0); - } - - int rv = 0; - -#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_float) - rv |= _run_fuzz(data, size, fuzz_builtin_float); -#endif -#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_int) - rv |= _run_fuzz(data, size, fuzz_builtin_int); -#endif -#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_unicode) - rv |= _run_fuzz(data, size, fuzz_builtin_unicode); -#endif +/* Fuzz test interface. + This returns the bitwise or of all fuzz test's return values. + + All fuzz tests must return 0, as all nonzero return codes are reserved for + future use -- we propagate the return values for that future case. + (And we bitwise or when running multiple tests to verify that normally we + only return 0.) */ +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (!Py_IsInitialized()) { + /* LLVMFuzzerTestOneInput is called repeatedly from the same process, + with no separate initialization phase, sadly, so we need to + initialize CPython ourselves on the first run. */ + Py_InitializeEx(0); + } + + int rv = 0; + +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_float) + rv |= _run_fuzz(data, size, fuzz_builtin_float); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_int) + rv |= _run_fuzz(data, size, fuzz_builtin_int); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_unicode) + rv |= _run_fuzz(data, size, fuzz_builtin_unicode); +#endif #if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_struct_unpack) static int STRUCT_UNPACK_INITIALIZED = 0; if (!STRUCT_UNPACK_INITIALIZED && !init_struct_unpack()) { @@ -496,5 +496,5 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { rv |= _run_fuzz(data, size, fuzz_csv_reader); #endif - return rv; -} + return rv; +} diff --git a/contrib/tools/python3/src/Modules/addrinfo.h b/contrib/tools/python3/src/Modules/addrinfo.h index c3c86248dd4..3a3d6704b71 100644 --- a/contrib/tools/python3/src/Modules/addrinfo.h +++ b/contrib/tools/python3/src/Modules/addrinfo.h @@ -1,168 +1,168 @@ -/* - * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef HAVE_GETADDRINFO - -/* - * Error return codes from getaddrinfo() - */ -#ifdef EAI_ADDRFAMILY -/* If this is defined, there is a conflicting implementation - in the C library, which can't be used for some reason. - Make sure it won't interfere with this emulation. */ - -#undef EAI_ADDRFAMILY -#undef EAI_AGAIN -#undef EAI_BADFLAGS -#undef EAI_FAIL -#undef EAI_FAMILY -#undef EAI_MEMORY -#undef EAI_NODATA -#undef EAI_NONAME -#undef EAI_SERVICE -#undef EAI_SOCKTYPE -#undef EAI_SYSTEM -#undef EAI_BADHINTS -#undef EAI_PROTOCOL -#undef EAI_MAX -#undef getaddrinfo -#define getaddrinfo fake_getaddrinfo -#endif /* EAI_ADDRFAMILY */ - -#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ -#define EAI_AGAIN 2 /* temporary failure in name resolution */ -#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ -#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ -#define EAI_FAMILY 5 /* ai_family not supported */ -#define EAI_MEMORY 6 /* memory allocation failure */ -#define EAI_NODATA 7 /* no address associated with hostname */ -#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ -#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ -#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ -#define EAI_SYSTEM 11 /* system error returned in errno */ -#define EAI_BADHINTS 12 -#define EAI_PROTOCOL 13 -#define EAI_MAX 14 - -/* - * Flag values for getaddrinfo() - */ -#ifdef AI_PASSIVE -#undef AI_PASSIVE -#undef AI_CANONNAME -#undef AI_NUMERICHOST -#undef AI_MASK -#undef AI_ALL -#undef AI_V4MAPPED_CFG -#undef AI_ADDRCONFIG -#undef AI_V4MAPPED -#undef AI_DEFAULT -#endif /* AI_PASSIVE */ - -#define AI_PASSIVE 0x00000001 /* get address to use bind() */ -#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ -#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ -/* valid flags for addrinfo */ -#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) - -#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ -#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ -#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ -#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ -/* special recommended flags for getipnodebyname */ -#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) - -#endif /* !HAVE_GETADDRINFO */ - -#ifndef HAVE_GETNAMEINFO - -/* - * Constants for getnameinfo() - */ -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#define NI_MAXSERV 32 -#endif /* !NI_MAXHOST */ - -/* - * Flag values for getnameinfo() - */ -#ifndef NI_NOFQDN -#define NI_NOFQDN 0x00000001 -#define NI_NUMERICHOST 0x00000002 -#define NI_NAMEREQD 0x00000004 -#define NI_NUMERICSERV 0x00000008 -#define NI_DGRAM 0x00000010 -#endif /* !NI_NOFQDN */ - -#endif /* !HAVE_GETNAMEINFO */ - -#ifndef HAVE_ADDRINFO -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif /* !HAVE_ADDRINFO */ - -#ifndef HAVE_SOCKADDR_STORAGE -/* - * RFC 2553: protocol-independent placeholder for socket addresses - */ -#define _SS_MAXSIZE 128 -#define _SS_ALIGNSIZE (sizeof(long long)) -#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) -#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ - _SS_PAD1SIZE - _SS_ALIGNSIZE) - -struct sockaddr_storage { -#ifdef HAVE_SOCKADDR_SA_LEN - unsigned char ss_len; /* address length */ - unsigned char ss_family; /* address family */ -#else - unsigned short ss_family; /* address family */ -#endif /* HAVE_SOCKADDR_SA_LEN */ - char __ss_pad1[_SS_PAD1SIZE]; - long long __ss_align; /* force desired structure storage alignment */ - char __ss_pad2[_SS_PAD2SIZE]; -}; -#endif /* !HAVE_SOCKADDR_STORAGE */ - -#ifdef __cplusplus -extern "C" { -#endif -extern void freehostent(struct hostent *); -#ifdef __cplusplus -} -#endif +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HAVE_GETADDRINFO + +/* + * Error return codes from getaddrinfo() + */ +#ifdef EAI_ADDRFAMILY +/* If this is defined, there is a conflicting implementation + in the C library, which can't be used for some reason. + Make sure it won't interfere with this emulation. */ + +#undef EAI_ADDRFAMILY +#undef EAI_AGAIN +#undef EAI_BADFLAGS +#undef EAI_FAIL +#undef EAI_FAMILY +#undef EAI_MEMORY +#undef EAI_NODATA +#undef EAI_NONAME +#undef EAI_SERVICE +#undef EAI_SOCKTYPE +#undef EAI_SYSTEM +#undef EAI_BADHINTS +#undef EAI_PROTOCOL +#undef EAI_MAX +#undef getaddrinfo +#define getaddrinfo fake_getaddrinfo +#endif /* EAI_ADDRFAMILY */ + +#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#define EAI_NODATA 7 /* no address associated with hostname */ +#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ +#define EAI_BADHINTS 12 +#define EAI_PROTOCOL 13 +#define EAI_MAX 14 + +/* + * Flag values for getaddrinfo() + */ +#ifdef AI_PASSIVE +#undef AI_PASSIVE +#undef AI_CANONNAME +#undef AI_NUMERICHOST +#undef AI_MASK +#undef AI_ALL +#undef AI_V4MAPPED_CFG +#undef AI_ADDRCONFIG +#undef AI_V4MAPPED +#undef AI_DEFAULT +#endif /* AI_PASSIVE */ + +#define AI_PASSIVE 0x00000001 /* get address to use bind() */ +#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ +#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ +/* valid flags for addrinfo */ +#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) + +#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ +#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ +#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ +#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ +/* special recommended flags for getipnodebyname */ +#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) + +#endif /* !HAVE_GETADDRINFO */ + +#ifndef HAVE_GETNAMEINFO + +/* + * Constants for getnameinfo() + */ +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 +#endif /* !NI_MAXHOST */ + +/* + * Flag values for getnameinfo() + */ +#ifndef NI_NOFQDN +#define NI_NOFQDN 0x00000001 +#define NI_NUMERICHOST 0x00000002 +#define NI_NAMEREQD 0x00000004 +#define NI_NUMERICSERV 0x00000008 +#define NI_DGRAM 0x00000010 +#endif /* !NI_NOFQDN */ + +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef HAVE_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_ADDRINFO */ + +#ifndef HAVE_SOCKADDR_STORAGE +/* + * RFC 2553: protocol-independent placeholder for socket addresses + */ +#define _SS_MAXSIZE 128 +#define _SS_ALIGNSIZE (sizeof(long long)) +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) +#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ + _SS_PAD1SIZE - _SS_ALIGNSIZE) + +struct sockaddr_storage { +#ifdef HAVE_SOCKADDR_SA_LEN + unsigned char ss_len; /* address length */ + unsigned char ss_family; /* address family */ +#else + unsigned short ss_family; /* address family */ +#endif /* HAVE_SOCKADDR_SA_LEN */ + char __ss_pad1[_SS_PAD1SIZE]; + long long __ss_align; /* force desired structure storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; +}; +#endif /* !HAVE_SOCKADDR_STORAGE */ + +#ifdef __cplusplus +extern "C" { +#endif +extern void freehostent(struct hostent *); +#ifdef __cplusplus +} +#endif diff --git a/contrib/tools/python3/src/Modules/arraymodule.c b/contrib/tools/python3/src/Modules/arraymodule.c index 7c7fc917454..5332ea0f800 100644 --- a/contrib/tools/python3/src/Modules/arraymodule.c +++ b/contrib/tools/python3/src/Modules/arraymodule.c @@ -1,2744 +1,2744 @@ -/* Array object implementation */ - -/* An array is a uniform list -- all items have the same type. - The item type is restricted to simple C types like int or float */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" +/* Array object implementation */ + +/* An array is a uniform list -- all items have the same type. + The item type is restricted to simple C types like int or float */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include // offsetof() - -#ifdef STDC_HEADERS -#include -#else /* !STDC_HEADERS */ -#ifdef HAVE_SYS_TYPES_H -#include /* For size_t */ -#endif /* HAVE_SYS_TYPES_H */ -#endif /* !STDC_HEADERS */ - -/*[clinic input] -module array -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7d1b8d7f5958fd83]*/ - -struct arrayobject; /* Forward */ - -/* All possible arraydescr values are defined in the vector "descriptors" - * below. That's defined later because the appropriate get and set - * functions aren't visible yet. - */ -struct arraydescr { - char typecode; - int itemsize; - PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); - int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); - int (*compareitems)(const void *, const void *, Py_ssize_t); - const char *formats; - int is_integer_type; - int is_signed; -}; - -typedef struct arrayobject { - PyObject_VAR_HEAD - char *ob_item; - Py_ssize_t allocated; - const struct arraydescr *ob_descr; - PyObject *weakreflist; /* List of weak references */ + +#ifdef STDC_HEADERS +#include +#else /* !STDC_HEADERS */ +#ifdef HAVE_SYS_TYPES_H +#include /* For size_t */ +#endif /* HAVE_SYS_TYPES_H */ +#endif /* !STDC_HEADERS */ + +/*[clinic input] +module array +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7d1b8d7f5958fd83]*/ + +struct arrayobject; /* Forward */ + +/* All possible arraydescr values are defined in the vector "descriptors" + * below. That's defined later because the appropriate get and set + * functions aren't visible yet. + */ +struct arraydescr { + char typecode; + int itemsize; + PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); + int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); + int (*compareitems)(const void *, const void *, Py_ssize_t); + const char *formats; + int is_integer_type; + int is_signed; +}; + +typedef struct arrayobject { + PyObject_VAR_HEAD + char *ob_item; + Py_ssize_t allocated; + const struct arraydescr *ob_descr; + PyObject *weakreflist; /* List of weak references */ Py_ssize_t ob_exports; /* Number of exported buffers */ -} arrayobject; - -static PyTypeObject Arraytype; - -typedef struct { - PyObject_HEAD - Py_ssize_t index; - arrayobject *ao; - PyObject* (*getitem)(struct arrayobject *, Py_ssize_t); -} arrayiterobject; - -static PyTypeObject PyArrayIter_Type; - -#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) - -enum machine_format_code { - UNKNOWN_FORMAT = -1, - /* UNKNOWN_FORMAT is used to indicate that the machine format for an - * array type code cannot be interpreted. When this occurs, a list of - * Python objects is used to represent the content of the array - * instead of using the memory content of the array directly. In that - * case, the array_reconstructor mechanism is bypassed completely, and - * the standard array constructor is used instead. - * - * This is will most likely occur when the machine doesn't use IEEE - * floating-point numbers. - */ - - UNSIGNED_INT8 = 0, - SIGNED_INT8 = 1, - UNSIGNED_INT16_LE = 2, - UNSIGNED_INT16_BE = 3, - SIGNED_INT16_LE = 4, - SIGNED_INT16_BE = 5, - UNSIGNED_INT32_LE = 6, - UNSIGNED_INT32_BE = 7, - SIGNED_INT32_LE = 8, - SIGNED_INT32_BE = 9, - UNSIGNED_INT64_LE = 10, - UNSIGNED_INT64_BE = 11, - SIGNED_INT64_LE = 12, - SIGNED_INT64_BE = 13, - IEEE_754_FLOAT_LE = 14, - IEEE_754_FLOAT_BE = 15, - IEEE_754_DOUBLE_LE = 16, - IEEE_754_DOUBLE_BE = 17, - UTF16_LE = 18, - UTF16_BE = 19, - UTF32_LE = 20, - UTF32_BE = 21 -}; -#define MACHINE_FORMAT_CODE_MIN 0 -#define MACHINE_FORMAT_CODE_MAX 21 - - -/* - * Must come after arrayobject, arrayiterobject, - * and enum machine_code_type definitions. - */ -#include "clinic/arraymodule.c.h" - -#define array_Check(op) PyObject_TypeCheck(op, &Arraytype) +} arrayobject; + +static PyTypeObject Arraytype; + +typedef struct { + PyObject_HEAD + Py_ssize_t index; + arrayobject *ao; + PyObject* (*getitem)(struct arrayobject *, Py_ssize_t); +} arrayiterobject; + +static PyTypeObject PyArrayIter_Type; + +#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) + +enum machine_format_code { + UNKNOWN_FORMAT = -1, + /* UNKNOWN_FORMAT is used to indicate that the machine format for an + * array type code cannot be interpreted. When this occurs, a list of + * Python objects is used to represent the content of the array + * instead of using the memory content of the array directly. In that + * case, the array_reconstructor mechanism is bypassed completely, and + * the standard array constructor is used instead. + * + * This is will most likely occur when the machine doesn't use IEEE + * floating-point numbers. + */ + + UNSIGNED_INT8 = 0, + SIGNED_INT8 = 1, + UNSIGNED_INT16_LE = 2, + UNSIGNED_INT16_BE = 3, + SIGNED_INT16_LE = 4, + SIGNED_INT16_BE = 5, + UNSIGNED_INT32_LE = 6, + UNSIGNED_INT32_BE = 7, + SIGNED_INT32_LE = 8, + SIGNED_INT32_BE = 9, + UNSIGNED_INT64_LE = 10, + UNSIGNED_INT64_BE = 11, + SIGNED_INT64_LE = 12, + SIGNED_INT64_BE = 13, + IEEE_754_FLOAT_LE = 14, + IEEE_754_FLOAT_BE = 15, + IEEE_754_DOUBLE_LE = 16, + IEEE_754_DOUBLE_BE = 17, + UTF16_LE = 18, + UTF16_BE = 19, + UTF32_LE = 20, + UTF32_BE = 21 +}; +#define MACHINE_FORMAT_CODE_MIN 0 +#define MACHINE_FORMAT_CODE_MAX 21 + + +/* + * Must come after arrayobject, arrayiterobject, + * and enum machine_code_type definitions. + */ +#include "clinic/arraymodule.c.h" + +#define array_Check(op) PyObject_TypeCheck(op, &Arraytype) #define array_CheckExact(op) Py_IS_TYPE(op, &Arraytype) - -static int -array_resize(arrayobject *self, Py_ssize_t newsize) -{ - char *items; - size_t _new_size; - - if (self->ob_exports > 0 && newsize != Py_SIZE(self)) { - PyErr_SetString(PyExc_BufferError, - "cannot resize an array that is exporting buffers"); - return -1; - } - - /* Bypass realloc() when a previous overallocation is large enough - to accommodate the newsize. If the newsize is 16 smaller than the - current size, then proceed with the realloc() to shrink the array. - */ - - if (self->allocated >= newsize && - Py_SIZE(self) < newsize + 16 && - self->ob_item != NULL) { + +static int +array_resize(arrayobject *self, Py_ssize_t newsize) +{ + char *items; + size_t _new_size; + + if (self->ob_exports > 0 && newsize != Py_SIZE(self)) { + PyErr_SetString(PyExc_BufferError, + "cannot resize an array that is exporting buffers"); + return -1; + } + + /* Bypass realloc() when a previous overallocation is large enough + to accommodate the newsize. If the newsize is 16 smaller than the + current size, then proceed with the realloc() to shrink the array. + */ + + if (self->allocated >= newsize && + Py_SIZE(self) < newsize + 16 && + self->ob_item != NULL) { Py_SET_SIZE(self, newsize); - return 0; - } - - if (newsize == 0) { - PyMem_FREE(self->ob_item); - self->ob_item = NULL; + return 0; + } + + if (newsize == 0) { + PyMem_FREE(self->ob_item); + self->ob_item = NULL; Py_SET_SIZE(self, 0); - self->allocated = 0; - return 0; - } - - /* This over-allocates proportional to the array size, making room - * for additional growth. The over-allocation is mild, but is - * enough to give linear-time amortized behavior over a long - * sequence of appends() in the presence of a poorly-performing - * system realloc(). - * The growth pattern is: 0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ... - * Note, the pattern starts out the same as for lists but then - * grows at a smaller rate so that larger arrays only overallocate - * by about 1/16th -- this is done because arrays are presumed to be more - * memory critical. - */ - - _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize; - items = self->ob_item; - /* XXX The following multiplication and division does not optimize away - like it does for lists since the size is not known at compile time */ - if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize)) - PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize)); - else - items = NULL; - if (items == NULL) { - PyErr_NoMemory(); - return -1; - } - self->ob_item = items; + self->allocated = 0; + return 0; + } + + /* This over-allocates proportional to the array size, making room + * for additional growth. The over-allocation is mild, but is + * enough to give linear-time amortized behavior over a long + * sequence of appends() in the presence of a poorly-performing + * system realloc(). + * The growth pattern is: 0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ... + * Note, the pattern starts out the same as for lists but then + * grows at a smaller rate so that larger arrays only overallocate + * by about 1/16th -- this is done because arrays are presumed to be more + * memory critical. + */ + + _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize; + items = self->ob_item; + /* XXX The following multiplication and division does not optimize away + like it does for lists since the size is not known at compile time */ + if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize)) + PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize)); + else + items = NULL; + if (items == NULL) { + PyErr_NoMemory(); + return -1; + } + self->ob_item = items; Py_SET_SIZE(self, newsize); - self->allocated = _new_size; - return 0; -} - -/**************************************************************************** -Get and Set functions for each type. -A Get function takes an arrayobject* and an integer index, returning the -array value at that index wrapped in an appropriate PyObject*. -A Set function takes an arrayobject, integer index, and PyObject*; sets -the array value at that index to the raw C data extracted from the PyObject*, -and returns 0 if successful, else nonzero on failure (PyObject* not of an -appropriate type or value). -Note that the basic Get and Set functions do NOT check that the index is -in bounds; that's the responsibility of the caller. -****************************************************************************/ - -static PyObject * -b_getitem(arrayobject *ap, Py_ssize_t i) -{ + self->allocated = _new_size; + return 0; +} + +/**************************************************************************** +Get and Set functions for each type. +A Get function takes an arrayobject* and an integer index, returning the +array value at that index wrapped in an appropriate PyObject*. +A Set function takes an arrayobject, integer index, and PyObject*; sets +the array value at that index to the raw C data extracted from the PyObject*, +and returns 0 if successful, else nonzero on failure (PyObject* not of an +appropriate type or value). +Note that the basic Get and Set functions do NOT check that the index is +in bounds; that's the responsibility of the caller. +****************************************************************************/ + +static PyObject * +b_getitem(arrayobject *ap, Py_ssize_t i) +{ long x = ((signed char *)ap->ob_item)[i]; - return PyLong_FromLong(x); -} - -static int -b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - short x; - /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore - must use the next size up that is signed ('h') and manually do - the overflow checking */ - if (!PyArg_Parse(v, "h;array item must be integer", &x)) - return -1; - else if (x < -128) { - PyErr_SetString(PyExc_OverflowError, - "signed char is less than minimum"); - return -1; - } - else if (x > 127) { - PyErr_SetString(PyExc_OverflowError, - "signed char is greater than maximum"); - return -1; - } - if (i >= 0) - ((char *)ap->ob_item)[i] = (char)x; - return 0; -} - -static PyObject * -BB_getitem(arrayobject *ap, Py_ssize_t i) -{ - long x = ((unsigned char *)ap->ob_item)[i]; - return PyLong_FromLong(x); -} - -static int -BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - unsigned char x; - /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */ - if (!PyArg_Parse(v, "b;array item must be integer", &x)) - return -1; - if (i >= 0) - ((char *)ap->ob_item)[i] = x; - return 0; -} - -static PyObject * -u_getitem(arrayobject *ap, Py_ssize_t i) -{ + return PyLong_FromLong(x); +} + +static int +b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + short x; + /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore + must use the next size up that is signed ('h') and manually do + the overflow checking */ + if (!PyArg_Parse(v, "h;array item must be integer", &x)) + return -1; + else if (x < -128) { + PyErr_SetString(PyExc_OverflowError, + "signed char is less than minimum"); + return -1; + } + else if (x > 127) { + PyErr_SetString(PyExc_OverflowError, + "signed char is greater than maximum"); + return -1; + } + if (i >= 0) + ((char *)ap->ob_item)[i] = (char)x; + return 0; +} + +static PyObject * +BB_getitem(arrayobject *ap, Py_ssize_t i) +{ + long x = ((unsigned char *)ap->ob_item)[i]; + return PyLong_FromLong(x); +} + +static int +BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + unsigned char x; + /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */ + if (!PyArg_Parse(v, "b;array item must be integer", &x)) + return -1; + if (i >= 0) + ((char *)ap->ob_item)[i] = x; + return 0; +} + +static PyObject * +u_getitem(arrayobject *ap, Py_ssize_t i) +{ return PyUnicode_FromOrdinal(((wchar_t *) ap->ob_item)[i]); -} - -static int -u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ +} + +static int +u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ PyObject *u; if (!PyArg_Parse(v, "U;array item must be unicode character", &u)) { return -1; } - + Py_ssize_t len = PyUnicode_AsWideChar(u, NULL, 0); if (len != 2) { - PyErr_SetString(PyExc_TypeError, - "array item must be unicode character"); - return -1; - } + PyErr_SetString(PyExc_TypeError, + "array item must be unicode character"); + return -1; + } wchar_t w; len = PyUnicode_AsWideChar(u, &w, 1); - assert(len == 1); - - if (i >= 0) { - ((wchar_t *)ap->ob_item)[i] = w; - } - return 0; -} - - -static PyObject * -h_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyLong_FromLong((long) ((short *)ap->ob_item)[i]); -} - - -static int -h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - short x; - /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */ - if (!PyArg_Parse(v, "h;array item must be integer", &x)) - return -1; - if (i >= 0) - ((short *)ap->ob_item)[i] = x; - return 0; -} - -static PyObject * -HH_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyLong_FromLong((long) ((unsigned short *)ap->ob_item)[i]); -} - -static int -HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - int x; - /* PyArg_Parse's 'h' formatter is for a signed short, therefore - must use the next size up and manually do the overflow checking */ - if (!PyArg_Parse(v, "i;array item must be integer", &x)) - return -1; - else if (x < 0) { - PyErr_SetString(PyExc_OverflowError, - "unsigned short is less than minimum"); - return -1; - } - else if (x > USHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "unsigned short is greater than maximum"); - return -1; - } - if (i >= 0) - ((short *)ap->ob_item)[i] = (short)x; - return 0; -} - -static PyObject * -i_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyLong_FromLong((long) ((int *)ap->ob_item)[i]); -} - -static int -i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - int x; - /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */ - if (!PyArg_Parse(v, "i;array item must be integer", &x)) - return -1; - if (i >= 0) - ((int *)ap->ob_item)[i] = x; - return 0; -} - -static PyObject * -II_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyLong_FromUnsignedLong( - (unsigned long) ((unsigned int *)ap->ob_item)[i]); -} - -static PyObject * -get_int_unless_float(PyObject *v) -{ - if (PyFloat_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "array item must be integer"); - return NULL; - } - return _PyLong_FromNbIndexOrNbInt(v); -} - -static int -II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - unsigned long x; - int do_decref = 0; /* if nb_int was called */ - - if (!PyLong_Check(v)) { - v = get_int_unless_float(v); - if (NULL == v) { - return -1; - } - do_decref = 1; - } - x = PyLong_AsUnsignedLong(v); - if (x == (unsigned long)-1 && PyErr_Occurred()) { - if (do_decref) { - Py_DECREF(v); - } - return -1; - } - if (x > UINT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "unsigned int is greater than maximum"); - if (do_decref) { - Py_DECREF(v); - } - return -1; - } - if (i >= 0) - ((unsigned int *)ap->ob_item)[i] = (unsigned int)x; - - if (do_decref) { - Py_DECREF(v); - } - return 0; -} - -static PyObject * -l_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyLong_FromLong(((long *)ap->ob_item)[i]); -} - -static int -l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - long x; - if (!PyArg_Parse(v, "l;array item must be integer", &x)) - return -1; - if (i >= 0) - ((long *)ap->ob_item)[i] = x; - return 0; -} - -static PyObject * -LL_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]); -} - -static int -LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - unsigned long x; - int do_decref = 0; /* if nb_int was called */ - - if (!PyLong_Check(v)) { - v = get_int_unless_float(v); - if (NULL == v) { - return -1; - } - do_decref = 1; - } - x = PyLong_AsUnsignedLong(v); - if (x == (unsigned long)-1 && PyErr_Occurred()) { - if (do_decref) { - Py_DECREF(v); - } - return -1; - } - if (i >= 0) - ((unsigned long *)ap->ob_item)[i] = x; - - if (do_decref) { - Py_DECREF(v); - } - return 0; -} - -static PyObject * -q_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyLong_FromLongLong(((long long *)ap->ob_item)[i]); -} - -static int -q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - long long x; - if (!PyArg_Parse(v, "L;array item must be integer", &x)) - return -1; - if (i >= 0) - ((long long *)ap->ob_item)[i] = x; - return 0; -} - -static PyObject * -QQ_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyLong_FromUnsignedLongLong( - ((unsigned long long *)ap->ob_item)[i]); -} - -static int -QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - unsigned long long x; - int do_decref = 0; /* if nb_int was called */ - - if (!PyLong_Check(v)) { - v = get_int_unless_float(v); - if (NULL == v) { - return -1; - } - do_decref = 1; - } - x = PyLong_AsUnsignedLongLong(v); - if (x == (unsigned long long)-1 && PyErr_Occurred()) { - if (do_decref) { - Py_DECREF(v); - } - return -1; - } - if (i >= 0) - ((unsigned long long *)ap->ob_item)[i] = x; - - if (do_decref) { - Py_DECREF(v); - } - return 0; -} - -static PyObject * -f_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]); -} - -static int -f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - float x; - if (!PyArg_Parse(v, "f;array item must be float", &x)) - return -1; - if (i >= 0) - ((float *)ap->ob_item)[i] = x; - return 0; -} - -static PyObject * -d_getitem(arrayobject *ap, Py_ssize_t i) -{ - return PyFloat_FromDouble(((double *)ap->ob_item)[i]); -} - -static int -d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) -{ - double x; - if (!PyArg_Parse(v, "d;array item must be float", &x)) - return -1; - if (i >= 0) - ((double *)ap->ob_item)[i] = x; - return 0; -} - -#define DEFINE_COMPAREITEMS(code, type) \ - static int \ - code##_compareitems(const void *lhs, const void *rhs, Py_ssize_t length) \ - { \ - const type *a = lhs, *b = rhs; \ - for (Py_ssize_t i = 0; i < length; ++i) \ - if (a[i] != b[i]) \ - return a[i] < b[i] ? -1 : 1; \ - return 0; \ - } - -DEFINE_COMPAREITEMS(b, signed char) -DEFINE_COMPAREITEMS(BB, unsigned char) -DEFINE_COMPAREITEMS(u, wchar_t) -DEFINE_COMPAREITEMS(h, short) -DEFINE_COMPAREITEMS(HH, unsigned short) -DEFINE_COMPAREITEMS(i, int) -DEFINE_COMPAREITEMS(II, unsigned int) -DEFINE_COMPAREITEMS(l, long) -DEFINE_COMPAREITEMS(LL, unsigned long) -DEFINE_COMPAREITEMS(q, long long) -DEFINE_COMPAREITEMS(QQ, unsigned long long) - -/* Description of types. - * - * Don't forget to update typecode_to_mformat_code() if you add a new - * typecode. - */ -static const struct arraydescr descriptors[] = { - {'b', 1, b_getitem, b_setitem, b_compareitems, "b", 1, 1}, - {'B', 1, BB_getitem, BB_setitem, BB_compareitems, "B", 1, 0}, - {'u', sizeof(wchar_t), u_getitem, u_setitem, u_compareitems, "u", 0, 0}, - {'h', sizeof(short), h_getitem, h_setitem, h_compareitems, "h", 1, 1}, - {'H', sizeof(short), HH_getitem, HH_setitem, HH_compareitems, "H", 1, 0}, - {'i', sizeof(int), i_getitem, i_setitem, i_compareitems, "i", 1, 1}, - {'I', sizeof(int), II_getitem, II_setitem, II_compareitems, "I", 1, 0}, - {'l', sizeof(long), l_getitem, l_setitem, l_compareitems, "l", 1, 1}, - {'L', sizeof(long), LL_getitem, LL_setitem, LL_compareitems, "L", 1, 0}, - {'q', sizeof(long long), q_getitem, q_setitem, q_compareitems, "q", 1, 1}, - {'Q', sizeof(long long), QQ_getitem, QQ_setitem, QQ_compareitems, "Q", 1, 0}, - {'f', sizeof(float), f_getitem, f_setitem, NULL, "f", 0, 0}, - {'d', sizeof(double), d_getitem, d_setitem, NULL, "d", 0, 0}, - {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */ -}; - -/**************************************************************************** -Implementations of array object methods. -****************************************************************************/ -/*[clinic input] -class array.array "arrayobject *" "&Arraytype" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/ - -static PyObject * -newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr) -{ - arrayobject *op; - size_t nbytes; - - if (size < 0) { - PyErr_BadInternalCall(); - return NULL; - } - - /* Check for overflow */ - if (size > PY_SSIZE_T_MAX / descr->itemsize) { - return PyErr_NoMemory(); - } - nbytes = size * descr->itemsize; - op = (arrayobject *) type->tp_alloc(type, 0); - if (op == NULL) { - return NULL; - } - op->ob_descr = descr; - op->allocated = size; - op->weakreflist = NULL; - Py_SET_SIZE(op, size); - if (size <= 0) { - op->ob_item = NULL; - } - else { - op->ob_item = PyMem_NEW(char, nbytes); - if (op->ob_item == NULL) { - Py_DECREF(op); - return PyErr_NoMemory(); - } - } - op->ob_exports = 0; - return (PyObject *) op; -} - -static PyObject * -getarrayitem(PyObject *op, Py_ssize_t i) -{ - arrayobject *ap; - assert(array_Check(op)); - ap = (arrayobject *)op; - assert(i>=0 && iob_descr->getitem)(ap, i); -} - -static int -ins1(arrayobject *self, Py_ssize_t where, PyObject *v) -{ - char *items; - Py_ssize_t n = Py_SIZE(self); - if (v == NULL) { - PyErr_BadInternalCall(); - return -1; - } - if ((*self->ob_descr->setitem)(self, -1, v) < 0) - return -1; - - if (array_resize(self, n+1) == -1) - return -1; - items = self->ob_item; - if (where < 0) { - where += n; - if (where < 0) - where = 0; - } - if (where > n) - where = n; - /* appends don't need to call memmove() */ - if (where != n) - memmove(items + (where+1)*self->ob_descr->itemsize, - items + where*self->ob_descr->itemsize, - (n-where)*self->ob_descr->itemsize); - return (*self->ob_descr->setitem)(self, where, v); -} - -/* Methods */ - -static void -array_dealloc(arrayobject *op) -{ - if (op->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) op); - if (op->ob_item != NULL) - PyMem_DEL(op->ob_item); - Py_TYPE(op)->tp_free((PyObject *)op); -} - -static PyObject * -array_richcompare(PyObject *v, PyObject *w, int op) -{ - arrayobject *va, *wa; - PyObject *vi = NULL; - PyObject *wi = NULL; - Py_ssize_t i, k; - PyObject *res; - - if (!array_Check(v) || !array_Check(w)) - Py_RETURN_NOTIMPLEMENTED; - - va = (arrayobject *)v; - wa = (arrayobject *)w; - - if (Py_SIZE(va) != Py_SIZE(wa) && (op == Py_EQ || op == Py_NE)) { - /* Shortcut: if the lengths differ, the arrays differ */ - if (op == Py_EQ) - res = Py_False; - else - res = Py_True; - Py_INCREF(res); - return res; - } - - if (va->ob_descr == wa->ob_descr && va->ob_descr->compareitems != NULL) { - /* Fast path: - arrays with same types can have their buffers compared directly */ - Py_ssize_t common_length = Py_MIN(Py_SIZE(va), Py_SIZE(wa)); - int result = va->ob_descr->compareitems(va->ob_item, wa->ob_item, - common_length); - if (result == 0) - goto compare_sizes; - - int cmp; - switch (op) { - case Py_LT: cmp = result < 0; break; - case Py_LE: cmp = result <= 0; break; - case Py_EQ: cmp = result == 0; break; - case Py_NE: cmp = result != 0; break; - case Py_GT: cmp = result > 0; break; - case Py_GE: cmp = result >= 0; break; - default: return NULL; /* cannot happen */ - } - PyObject *res = cmp ? Py_True : Py_False; - Py_INCREF(res); - return res; - } - - - /* Search for the first index where items are different */ - k = 1; - for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) { - vi = getarrayitem(v, i); - wi = getarrayitem(w, i); - if (vi == NULL || wi == NULL) { - Py_XDECREF(vi); - Py_XDECREF(wi); - return NULL; - } - k = PyObject_RichCompareBool(vi, wi, Py_EQ); - if (k == 0) - break; /* Keeping vi and wi alive! */ - Py_DECREF(vi); - Py_DECREF(wi); - if (k < 0) - return NULL; - } - - if (k) { - /* No more items to compare -- compare sizes */ - compare_sizes: ; - Py_ssize_t vs = Py_SIZE(va); - Py_ssize_t ws = Py_SIZE(wa); - int cmp; - switch (op) { - case Py_LT: cmp = vs < ws; break; - case Py_LE: cmp = vs <= ws; break; - /* If the lengths were not equal, - the earlier fast-path check would have caught that. */ - case Py_EQ: assert(vs == ws); cmp = 1; break; - case Py_NE: assert(vs == ws); cmp = 0; break; - case Py_GT: cmp = vs > ws; break; - case Py_GE: cmp = vs >= ws; break; - default: return NULL; /* cannot happen */ - } - if (cmp) - res = Py_True; - else - res = Py_False; - Py_INCREF(res); - return res; - } - - /* We have an item that differs. First, shortcuts for EQ/NE */ - if (op == Py_EQ) { - Py_INCREF(Py_False); - res = Py_False; - } - else if (op == Py_NE) { - Py_INCREF(Py_True); - res = Py_True; - } - else { - /* Compare the final item again using the proper operator */ - res = PyObject_RichCompare(vi, wi, op); - } - Py_DECREF(vi); - Py_DECREF(wi); - return res; -} - -static Py_ssize_t -array_length(arrayobject *a) -{ - return Py_SIZE(a); -} - -static PyObject * -array_item(arrayobject *a, Py_ssize_t i) -{ - if (i < 0 || i >= Py_SIZE(a)) { - PyErr_SetString(PyExc_IndexError, "array index out of range"); - return NULL; - } - return getarrayitem((PyObject *)a, i); -} - -static PyObject * -array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) -{ - arrayobject *np; - if (ilow < 0) - ilow = 0; - else if (ilow > Py_SIZE(a)) - ilow = Py_SIZE(a); - if (ihigh < 0) - ihigh = 0; - if (ihigh < ilow) - ihigh = ilow; - else if (ihigh > Py_SIZE(a)) - ihigh = Py_SIZE(a); - np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr); - if (np == NULL) - return NULL; - if (ihigh > ilow) { - memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize, - (ihigh-ilow) * a->ob_descr->itemsize); - } - return (PyObject *)np; -} - - -/*[clinic input] -array.array.__copy__ - -Return a copy of the array. -[clinic start generated code]*/ - -static PyObject * -array_array___copy___impl(arrayobject *self) -/*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/ -{ - return array_slice(self, 0, Py_SIZE(self)); -} - -/*[clinic input] -array.array.__deepcopy__ - - unused: object - / - -Return a copy of the array. -[clinic start generated code]*/ - -static PyObject * -array_array___deepcopy__(arrayobject *self, PyObject *unused) -/*[clinic end generated code: output=1ec748d8e14a9faa input=2405ecb4933748c4]*/ -{ - return array_array___copy___impl(self); -} - -static PyObject * -array_concat(arrayobject *a, PyObject *bb) -{ - Py_ssize_t size; - arrayobject *np; - if (!array_Check(bb)) { - PyErr_Format(PyExc_TypeError, - "can only append array (not \"%.200s\") to array", - Py_TYPE(bb)->tp_name); - return NULL; - } -#define b ((arrayobject *)bb) - if (a->ob_descr != b->ob_descr) { - PyErr_BadArgument(); - return NULL; - } - if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) { - return PyErr_NoMemory(); - } - size = Py_SIZE(a) + Py_SIZE(b); - np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); - if (np == NULL) { - return NULL; - } - if (Py_SIZE(a) > 0) { - memcpy(np->ob_item, a->ob_item, Py_SIZE(a)*a->ob_descr->itemsize); - } - if (Py_SIZE(b) > 0) { - memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize, - b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize); - } - return (PyObject *)np; -#undef b -} - -static PyObject * -array_repeat(arrayobject *a, Py_ssize_t n) -{ - Py_ssize_t size; - arrayobject *np; - Py_ssize_t oldbytes, newbytes; - if (n < 0) - n = 0; - if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) { - return PyErr_NoMemory(); - } - size = Py_SIZE(a) * n; - np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); - if (np == NULL) - return NULL; - if (size == 0) - return (PyObject *)np; - oldbytes = Py_SIZE(a) * a->ob_descr->itemsize; - newbytes = oldbytes * n; - /* this follows the code in unicode_repeat */ - if (oldbytes == 1) { - memset(np->ob_item, a->ob_item[0], newbytes); - } else { - Py_ssize_t done = oldbytes; - memcpy(np->ob_item, a->ob_item, oldbytes); - while (done < newbytes) { - Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done; - memcpy(np->ob_item+done, np->ob_item, ncopy); - done += ncopy; - } - } - return (PyObject *)np; -} - -static int -array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) -{ - char *item; - Py_ssize_t d; /* Change in size */ - if (ilow < 0) - ilow = 0; - else if (ilow > Py_SIZE(a)) - ilow = Py_SIZE(a); - if (ihigh < 0) - ihigh = 0; - if (ihigh < ilow) - ihigh = ilow; - else if (ihigh > Py_SIZE(a)) - ihigh = Py_SIZE(a); - item = a->ob_item; - d = ihigh-ilow; - /* Issue #4509: If the array has exported buffers and the slice - assignment would change the size of the array, fail early to make - sure we don't modify it. */ - if (d != 0 && a->ob_exports > 0) { - PyErr_SetString(PyExc_BufferError, - "cannot resize an array that is exporting buffers"); - return -1; - } - if (d > 0) { /* Delete d items */ - memmove(item + (ihigh-d)*a->ob_descr->itemsize, - item + ihigh*a->ob_descr->itemsize, - (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize); - if (array_resize(a, Py_SIZE(a) - d) == -1) - return -1; - } - return 0; -} - -static int -array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v) -{ - if (i < 0 || i >= Py_SIZE(a)) { - PyErr_SetString(PyExc_IndexError, - "array assignment index out of range"); - return -1; - } - if (v == NULL) - return array_del_slice(a, i, i+1); - return (*a->ob_descr->setitem)(a, i, v); -} - -static int -setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v) -{ - assert(array_Check(a)); - return array_ass_item((arrayobject *)a, i, v); -} - -static int -array_iter_extend(arrayobject *self, PyObject *bb) -{ - PyObject *it, *v; - - it = PyObject_GetIter(bb); - if (it == NULL) - return -1; - - while ((v = PyIter_Next(it)) != NULL) { - if (ins1(self, Py_SIZE(self), v) != 0) { - Py_DECREF(v); - Py_DECREF(it); - return -1; - } - Py_DECREF(v); - } - Py_DECREF(it); - if (PyErr_Occurred()) - return -1; - return 0; -} - -static int -array_do_extend(arrayobject *self, PyObject *bb) -{ - Py_ssize_t size, oldsize, bbsize; - - if (!array_Check(bb)) - return array_iter_extend(self, bb); -#define b ((arrayobject *)bb) - if (self->ob_descr != b->ob_descr) { - PyErr_SetString(PyExc_TypeError, - "can only extend with array of same kind"); - return -1; - } - if ((Py_SIZE(self) > PY_SSIZE_T_MAX - Py_SIZE(b)) || - ((Py_SIZE(self) + Py_SIZE(b)) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { - PyErr_NoMemory(); - return -1; - } - oldsize = Py_SIZE(self); - /* Get the size of bb before resizing the array since bb could be self. */ - bbsize = Py_SIZE(bb); - size = oldsize + Py_SIZE(b); - if (array_resize(self, size) == -1) - return -1; - if (bbsize > 0) { - memcpy(self->ob_item + oldsize * self->ob_descr->itemsize, - b->ob_item, bbsize * b->ob_descr->itemsize); - } - - return 0; -#undef b -} - -static PyObject * -array_inplace_concat(arrayobject *self, PyObject *bb) -{ - if (!array_Check(bb)) { - PyErr_Format(PyExc_TypeError, - "can only extend array with array (not \"%.200s\")", - Py_TYPE(bb)->tp_name); - return NULL; - } - if (array_do_extend(self, bb) == -1) - return NULL; - Py_INCREF(self); - return (PyObject *)self; -} - -static PyObject * -array_inplace_repeat(arrayobject *self, Py_ssize_t n) -{ - char *items, *p; - Py_ssize_t size, i; - - if (Py_SIZE(self) > 0) { - if (n < 0) - n = 0; - if ((self->ob_descr->itemsize != 0) && - (Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { - return PyErr_NoMemory(); - } - size = Py_SIZE(self) * self->ob_descr->itemsize; - if (n > 0 && size > PY_SSIZE_T_MAX / n) { - return PyErr_NoMemory(); - } - if (array_resize(self, n * Py_SIZE(self)) == -1) - return NULL; - items = p = self->ob_item; - for (i = 1; i < n; i++) { - p += size; - memcpy(p, items, size); - } - } - Py_INCREF(self); - return (PyObject *)self; -} - - -static PyObject * -ins(arrayobject *self, Py_ssize_t where, PyObject *v) -{ - if (ins1(self, where, v) != 0) - return NULL; - Py_RETURN_NONE; -} - -/*[clinic input] -array.array.count - - v: object - / - -Return number of occurrences of v in the array. -[clinic start generated code]*/ - -static PyObject * -array_array_count(arrayobject *self, PyObject *v) -/*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/ -{ - Py_ssize_t count = 0; - Py_ssize_t i; - - for (i = 0; i < Py_SIZE(self); i++) { - PyObject *selfi; - int cmp; - - selfi = getarrayitem((PyObject *)self, i); - if (selfi == NULL) - return NULL; - cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); - Py_DECREF(selfi); - if (cmp > 0) - count++; - else if (cmp < 0) - return NULL; - } - return PyLong_FromSsize_t(count); -} - - -/*[clinic input] -array.array.index - - v: object - / - -Return index of first occurrence of v in the array. -[clinic start generated code]*/ - -static PyObject * -array_array_index(arrayobject *self, PyObject *v) -/*[clinic end generated code: output=d48498d325602167 input=cf619898c6649d08]*/ -{ - Py_ssize_t i; - - for (i = 0; i < Py_SIZE(self); i++) { - PyObject *selfi; - int cmp; - - selfi = getarrayitem((PyObject *)self, i); - if (selfi == NULL) - return NULL; - cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); - Py_DECREF(selfi); - if (cmp > 0) { - return PyLong_FromSsize_t(i); - } - else if (cmp < 0) - return NULL; - } - PyErr_SetString(PyExc_ValueError, "array.index(x): x not in array"); - return NULL; -} - -static int -array_contains(arrayobject *self, PyObject *v) -{ - Py_ssize_t i; - int cmp; - - for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) { - PyObject *selfi = getarrayitem((PyObject *)self, i); - if (selfi == NULL) - return -1; - cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); - Py_DECREF(selfi); - } - return cmp; -} - -/*[clinic input] -array.array.remove - - v: object - / - -Remove the first occurrence of v in the array. -[clinic start generated code]*/ - -static PyObject * -array_array_remove(arrayobject *self, PyObject *v) -/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/ -{ - Py_ssize_t i; - - for (i = 0; i < Py_SIZE(self); i++) { - PyObject *selfi; - int cmp; - - selfi = getarrayitem((PyObject *)self,i); - if (selfi == NULL) - return NULL; - cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); - Py_DECREF(selfi); - if (cmp > 0) { - if (array_del_slice(self, i, i+1) != 0) - return NULL; - Py_RETURN_NONE; - } - else if (cmp < 0) - return NULL; - } - PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in array"); - return NULL; -} - -/*[clinic input] -array.array.pop - - i: Py_ssize_t = -1 - / - -Return the i-th element and delete it from the array. - -i defaults to -1. -[clinic start generated code]*/ - -static PyObject * -array_array_pop_impl(arrayobject *self, Py_ssize_t i) -/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/ -{ - PyObject *v; - - if (Py_SIZE(self) == 0) { - /* Special-case most common failure cause */ - PyErr_SetString(PyExc_IndexError, "pop from empty array"); - return NULL; - } - if (i < 0) - i += Py_SIZE(self); - if (i < 0 || i >= Py_SIZE(self)) { - PyErr_SetString(PyExc_IndexError, "pop index out of range"); - return NULL; - } - v = getarrayitem((PyObject *)self, i); - if (v == NULL) - return NULL; - if (array_del_slice(self, i, i+1) != 0) { - Py_DECREF(v); - return NULL; - } - return v; -} - -/*[clinic input] -array.array.extend - - bb: object - / - -Append items to the end of the array. -[clinic start generated code]*/ - -static PyObject * -array_array_extend(arrayobject *self, PyObject *bb) -/*[clinic end generated code: output=bbddbc8e8bef871d input=43be86aba5c31e44]*/ -{ - if (array_do_extend(self, bb) == -1) - return NULL; - Py_RETURN_NONE; -} - -/*[clinic input] -array.array.insert - - i: Py_ssize_t - v: object - / - -Insert a new item v into the array before position i. -[clinic start generated code]*/ - -static PyObject * -array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v) -/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/ -{ - return ins(self, i, v); -} - -/*[clinic input] -array.array.buffer_info - -Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array's contents. - -The length should be multiplied by the itemsize attribute to calculate -the buffer length in bytes. -[clinic start generated code]*/ - -static PyObject * -array_array_buffer_info_impl(arrayobject *self) -/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/ -{ - PyObject *retval = NULL, *v; - - retval = PyTuple_New(2); - if (!retval) - return NULL; - - v = PyLong_FromVoidPtr(self->ob_item); - if (v == NULL) { - Py_DECREF(retval); - return NULL; - } - PyTuple_SET_ITEM(retval, 0, v); - - v = PyLong_FromSsize_t(Py_SIZE(self)); - if (v == NULL) { - Py_DECREF(retval); - return NULL; - } - PyTuple_SET_ITEM(retval, 1, v); - - return retval; -} - -/*[clinic input] -array.array.append - - v: object - / - -Append new value v to the end of the array. -[clinic start generated code]*/ - -static PyObject * -array_array_append(arrayobject *self, PyObject *v) -/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/ -{ - return ins(self, Py_SIZE(self), v); -} - -/*[clinic input] -array.array.byteswap - -Byteswap all items of the array. - -If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is -raised. -[clinic start generated code]*/ - -static PyObject * -array_array_byteswap_impl(arrayobject *self) -/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/ -{ - char *p; - Py_ssize_t i; - - switch (self->ob_descr->itemsize) { - case 1: - break; - case 2: - for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) { - char p0 = p[0]; - p[0] = p[1]; - p[1] = p0; - } - break; - case 4: - for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 4) { - char p0 = p[0]; - char p1 = p[1]; - p[0] = p[3]; - p[1] = p[2]; - p[2] = p1; - p[3] = p0; - } - break; - case 8: - for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) { - char p0 = p[0]; - char p1 = p[1]; - char p2 = p[2]; - char p3 = p[3]; - p[0] = p[7]; - p[1] = p[6]; - p[2] = p[5]; - p[3] = p[4]; - p[4] = p3; - p[5] = p2; - p[6] = p1; - p[7] = p0; - } - break; - default: - PyErr_SetString(PyExc_RuntimeError, - "don't know how to byteswap this array type"); - return NULL; - } - Py_RETURN_NONE; -} - -/*[clinic input] -array.array.reverse - -Reverse the order of the items in the array. -[clinic start generated code]*/ - -static PyObject * -array_array_reverse_impl(arrayobject *self) -/*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/ -{ - Py_ssize_t itemsize = self->ob_descr->itemsize; - char *p, *q; - /* little buffer to hold items while swapping */ - char tmp[256]; /* 8 is probably enough -- but why skimp */ - assert((size_t)itemsize <= sizeof(tmp)); - - if (Py_SIZE(self) > 1) { - for (p = self->ob_item, - q = self->ob_item + (Py_SIZE(self) - 1)*itemsize; - p < q; - p += itemsize, q -= itemsize) { - /* memory areas guaranteed disjoint, so memcpy - * is safe (& memmove may be slower). - */ - memcpy(tmp, p, itemsize); - memcpy(p, q, itemsize); - memcpy(q, tmp, itemsize); - } - } - - Py_RETURN_NONE; -} - -/*[clinic input] -array.array.fromfile - - f: object - n: Py_ssize_t - / - -Read n objects from the file object f and append them to the end of the array. -[clinic start generated code]*/ - -static PyObject * -array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n) -/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/ -{ - PyObject *b, *res; - Py_ssize_t itemsize = self->ob_descr->itemsize; - Py_ssize_t nbytes; - _Py_IDENTIFIER(read); - int not_enough_bytes; - - if (n < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return NULL; - } - if (n > PY_SSIZE_T_MAX / itemsize) { - PyErr_NoMemory(); - return NULL; - } - nbytes = n * itemsize; - - b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes); - if (b == NULL) - return NULL; - - if (!PyBytes_Check(b)) { - PyErr_SetString(PyExc_TypeError, - "read() didn't return bytes"); - Py_DECREF(b); - return NULL; - } - - not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes); - - res = array_array_frombytes(self, b); - Py_DECREF(b); - if (res == NULL) - return NULL; - - if (not_enough_bytes) { - PyErr_SetString(PyExc_EOFError, - "read() didn't return enough bytes"); - Py_DECREF(res); - return NULL; - } - - return res; -} - -/*[clinic input] -array.array.tofile - - f: object - / - -Write all items (as machine values) to the file object f. -[clinic start generated code]*/ - -static PyObject * -array_array_tofile(arrayobject *self, PyObject *f) -/*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831]*/ -{ - Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize; - /* Write 64K blocks at a time */ - /* XXX Make the block size settable */ - int BLOCKSIZE = 64*1024; - Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE; - Py_ssize_t i; - - if (Py_SIZE(self) == 0) - goto done; - - for (i = 0; i < nblocks; i++) { - char* ptr = self->ob_item + i*BLOCKSIZE; - Py_ssize_t size = BLOCKSIZE; - PyObject *bytes, *res; - _Py_IDENTIFIER(write); - - if (i*BLOCKSIZE + size > nbytes) - size = nbytes - i*BLOCKSIZE; - bytes = PyBytes_FromStringAndSize(ptr, size); - if (bytes == NULL) - return NULL; - res = _PyObject_CallMethodIdOneArg(f, &PyId_write, bytes); - Py_DECREF(bytes); - if (res == NULL) - return NULL; - Py_DECREF(res); /* drop write result */ - } - - done: - Py_RETURN_NONE; -} - -/*[clinic input] -array.array.fromlist - - list: object - / - -Append items to array from list. -[clinic start generated code]*/ - -static PyObject * -array_array_fromlist(arrayobject *self, PyObject *list) -/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/ -{ - Py_ssize_t n; - - if (!PyList_Check(list)) { - PyErr_SetString(PyExc_TypeError, "arg must be list"); - return NULL; - } - n = PyList_Size(list); - if (n > 0) { - Py_ssize_t i, old_size; - old_size = Py_SIZE(self); - if (array_resize(self, old_size + n) == -1) - return NULL; - for (i = 0; i < n; i++) { - PyObject *v = PyList_GET_ITEM(list, i); - if ((*self->ob_descr->setitem)(self, - Py_SIZE(self) - n + i, v) != 0) { - array_resize(self, old_size); - return NULL; - } - if (n != PyList_GET_SIZE(list)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - array_resize(self, old_size); - return NULL; - } - } - } - Py_RETURN_NONE; -} - -/*[clinic input] -array.array.tolist - -Convert array to an ordinary list with the same items. -[clinic start generated code]*/ - -static PyObject * -array_array_tolist_impl(arrayobject *self) -/*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/ -{ - PyObject *list = PyList_New(Py_SIZE(self)); - Py_ssize_t i; - - if (list == NULL) - return NULL; - for (i = 0; i < Py_SIZE(self); i++) { - PyObject *v = getarrayitem((PyObject *)self, i); - if (v == NULL) - goto error; - PyList_SET_ITEM(list, i, v); - } - return list; - -error: - Py_DECREF(list); - return NULL; -} - -static PyObject * -frombytes(arrayobject *self, Py_buffer *buffer) -{ - int itemsize = self->ob_descr->itemsize; - Py_ssize_t n; - if (buffer->itemsize != 1) { - PyBuffer_Release(buffer); - PyErr_SetString(PyExc_TypeError, "a bytes-like object is required"); - return NULL; - } - n = buffer->len; - if (n % itemsize != 0) { - PyBuffer_Release(buffer); - PyErr_SetString(PyExc_ValueError, - "bytes length not a multiple of item size"); - return NULL; - } - n = n / itemsize; - if (n > 0) { - Py_ssize_t old_size = Py_SIZE(self); - if ((n > PY_SSIZE_T_MAX - old_size) || - ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) { - PyBuffer_Release(buffer); - return PyErr_NoMemory(); - } - if (array_resize(self, old_size + n) == -1) { - PyBuffer_Release(buffer); - return NULL; - } - memcpy(self->ob_item + old_size * itemsize, - buffer->buf, n * itemsize); - } - PyBuffer_Release(buffer); - Py_RETURN_NONE; -} - -/*[clinic input] -array.array.frombytes - - buffer: Py_buffer - / - -Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method. -[clinic start generated code]*/ - -static PyObject * -array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer) -/*[clinic end generated code: output=d9842c8f7510a516 input=378db226dfac949e]*/ -{ - return frombytes(self, buffer); -} - -/*[clinic input] -array.array.tobytes - -Convert the array to an array of machine values and return the bytes representation. -[clinic start generated code]*/ + assert(len == 1); -static PyObject * -array_array_tobytes_impl(arrayobject *self) -/*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/ -{ - if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) { - return PyBytes_FromStringAndSize(self->ob_item, - Py_SIZE(self) * self->ob_descr->itemsize); - } else { - return PyErr_NoMemory(); + if (i >= 0) { + ((wchar_t *)ap->ob_item)[i] = w; } -} - -/*[clinic input] -array.array.fromunicode - + return 0; +} + + +static PyObject * +h_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyLong_FromLong((long) ((short *)ap->ob_item)[i]); +} + + +static int +h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + short x; + /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */ + if (!PyArg_Parse(v, "h;array item must be integer", &x)) + return -1; + if (i >= 0) + ((short *)ap->ob_item)[i] = x; + return 0; +} + +static PyObject * +HH_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyLong_FromLong((long) ((unsigned short *)ap->ob_item)[i]); +} + +static int +HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + int x; + /* PyArg_Parse's 'h' formatter is for a signed short, therefore + must use the next size up and manually do the overflow checking */ + if (!PyArg_Parse(v, "i;array item must be integer", &x)) + return -1; + else if (x < 0) { + PyErr_SetString(PyExc_OverflowError, + "unsigned short is less than minimum"); + return -1; + } + else if (x > USHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned short is greater than maximum"); + return -1; + } + if (i >= 0) + ((short *)ap->ob_item)[i] = (short)x; + return 0; +} + +static PyObject * +i_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyLong_FromLong((long) ((int *)ap->ob_item)[i]); +} + +static int +i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + int x; + /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */ + if (!PyArg_Parse(v, "i;array item must be integer", &x)) + return -1; + if (i >= 0) + ((int *)ap->ob_item)[i] = x; + return 0; +} + +static PyObject * +II_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyLong_FromUnsignedLong( + (unsigned long) ((unsigned int *)ap->ob_item)[i]); +} + +static PyObject * +get_int_unless_float(PyObject *v) +{ + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "array item must be integer"); + return NULL; + } + return _PyLong_FromNbIndexOrNbInt(v); +} + +static int +II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + unsigned long x; + int do_decref = 0; /* if nb_int was called */ + + if (!PyLong_Check(v)) { + v = get_int_unless_float(v); + if (NULL == v) { + return -1; + } + do_decref = 1; + } + x = PyLong_AsUnsignedLong(v); + if (x == (unsigned long)-1 && PyErr_Occurred()) { + if (do_decref) { + Py_DECREF(v); + } + return -1; + } + if (x > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned int is greater than maximum"); + if (do_decref) { + Py_DECREF(v); + } + return -1; + } + if (i >= 0) + ((unsigned int *)ap->ob_item)[i] = (unsigned int)x; + + if (do_decref) { + Py_DECREF(v); + } + return 0; +} + +static PyObject * +l_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyLong_FromLong(((long *)ap->ob_item)[i]); +} + +static int +l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + long x; + if (!PyArg_Parse(v, "l;array item must be integer", &x)) + return -1; + if (i >= 0) + ((long *)ap->ob_item)[i] = x; + return 0; +} + +static PyObject * +LL_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]); +} + +static int +LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + unsigned long x; + int do_decref = 0; /* if nb_int was called */ + + if (!PyLong_Check(v)) { + v = get_int_unless_float(v); + if (NULL == v) { + return -1; + } + do_decref = 1; + } + x = PyLong_AsUnsignedLong(v); + if (x == (unsigned long)-1 && PyErr_Occurred()) { + if (do_decref) { + Py_DECREF(v); + } + return -1; + } + if (i >= 0) + ((unsigned long *)ap->ob_item)[i] = x; + + if (do_decref) { + Py_DECREF(v); + } + return 0; +} + +static PyObject * +q_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyLong_FromLongLong(((long long *)ap->ob_item)[i]); +} + +static int +q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + long long x; + if (!PyArg_Parse(v, "L;array item must be integer", &x)) + return -1; + if (i >= 0) + ((long long *)ap->ob_item)[i] = x; + return 0; +} + +static PyObject * +QQ_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyLong_FromUnsignedLongLong( + ((unsigned long long *)ap->ob_item)[i]); +} + +static int +QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + unsigned long long x; + int do_decref = 0; /* if nb_int was called */ + + if (!PyLong_Check(v)) { + v = get_int_unless_float(v); + if (NULL == v) { + return -1; + } + do_decref = 1; + } + x = PyLong_AsUnsignedLongLong(v); + if (x == (unsigned long long)-1 && PyErr_Occurred()) { + if (do_decref) { + Py_DECREF(v); + } + return -1; + } + if (i >= 0) + ((unsigned long long *)ap->ob_item)[i] = x; + + if (do_decref) { + Py_DECREF(v); + } + return 0; +} + +static PyObject * +f_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]); +} + +static int +f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + float x; + if (!PyArg_Parse(v, "f;array item must be float", &x)) + return -1; + if (i >= 0) + ((float *)ap->ob_item)[i] = x; + return 0; +} + +static PyObject * +d_getitem(arrayobject *ap, Py_ssize_t i) +{ + return PyFloat_FromDouble(((double *)ap->ob_item)[i]); +} + +static int +d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) +{ + double x; + if (!PyArg_Parse(v, "d;array item must be float", &x)) + return -1; + if (i >= 0) + ((double *)ap->ob_item)[i] = x; + return 0; +} + +#define DEFINE_COMPAREITEMS(code, type) \ + static int \ + code##_compareitems(const void *lhs, const void *rhs, Py_ssize_t length) \ + { \ + const type *a = lhs, *b = rhs; \ + for (Py_ssize_t i = 0; i < length; ++i) \ + if (a[i] != b[i]) \ + return a[i] < b[i] ? -1 : 1; \ + return 0; \ + } + +DEFINE_COMPAREITEMS(b, signed char) +DEFINE_COMPAREITEMS(BB, unsigned char) +DEFINE_COMPAREITEMS(u, wchar_t) +DEFINE_COMPAREITEMS(h, short) +DEFINE_COMPAREITEMS(HH, unsigned short) +DEFINE_COMPAREITEMS(i, int) +DEFINE_COMPAREITEMS(II, unsigned int) +DEFINE_COMPAREITEMS(l, long) +DEFINE_COMPAREITEMS(LL, unsigned long) +DEFINE_COMPAREITEMS(q, long long) +DEFINE_COMPAREITEMS(QQ, unsigned long long) + +/* Description of types. + * + * Don't forget to update typecode_to_mformat_code() if you add a new + * typecode. + */ +static const struct arraydescr descriptors[] = { + {'b', 1, b_getitem, b_setitem, b_compareitems, "b", 1, 1}, + {'B', 1, BB_getitem, BB_setitem, BB_compareitems, "B", 1, 0}, + {'u', sizeof(wchar_t), u_getitem, u_setitem, u_compareitems, "u", 0, 0}, + {'h', sizeof(short), h_getitem, h_setitem, h_compareitems, "h", 1, 1}, + {'H', sizeof(short), HH_getitem, HH_setitem, HH_compareitems, "H", 1, 0}, + {'i', sizeof(int), i_getitem, i_setitem, i_compareitems, "i", 1, 1}, + {'I', sizeof(int), II_getitem, II_setitem, II_compareitems, "I", 1, 0}, + {'l', sizeof(long), l_getitem, l_setitem, l_compareitems, "l", 1, 1}, + {'L', sizeof(long), LL_getitem, LL_setitem, LL_compareitems, "L", 1, 0}, + {'q', sizeof(long long), q_getitem, q_setitem, q_compareitems, "q", 1, 1}, + {'Q', sizeof(long long), QQ_getitem, QQ_setitem, QQ_compareitems, "Q", 1, 0}, + {'f', sizeof(float), f_getitem, f_setitem, NULL, "f", 0, 0}, + {'d', sizeof(double), d_getitem, d_setitem, NULL, "d", 0, 0}, + {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */ +}; + +/**************************************************************************** +Implementations of array object methods. +****************************************************************************/ +/*[clinic input] +class array.array "arrayobject *" "&Arraytype" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/ + +static PyObject * +newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr) +{ + arrayobject *op; + size_t nbytes; + + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } + + /* Check for overflow */ + if (size > PY_SSIZE_T_MAX / descr->itemsize) { + return PyErr_NoMemory(); + } + nbytes = size * descr->itemsize; + op = (arrayobject *) type->tp_alloc(type, 0); + if (op == NULL) { + return NULL; + } + op->ob_descr = descr; + op->allocated = size; + op->weakreflist = NULL; + Py_SET_SIZE(op, size); + if (size <= 0) { + op->ob_item = NULL; + } + else { + op->ob_item = PyMem_NEW(char, nbytes); + if (op->ob_item == NULL) { + Py_DECREF(op); + return PyErr_NoMemory(); + } + } + op->ob_exports = 0; + return (PyObject *) op; +} + +static PyObject * +getarrayitem(PyObject *op, Py_ssize_t i) +{ + arrayobject *ap; + assert(array_Check(op)); + ap = (arrayobject *)op; + assert(i>=0 && iob_descr->getitem)(ap, i); +} + +static int +ins1(arrayobject *self, Py_ssize_t where, PyObject *v) +{ + char *items; + Py_ssize_t n = Py_SIZE(self); + if (v == NULL) { + PyErr_BadInternalCall(); + return -1; + } + if ((*self->ob_descr->setitem)(self, -1, v) < 0) + return -1; + + if (array_resize(self, n+1) == -1) + return -1; + items = self->ob_item; + if (where < 0) { + where += n; + if (where < 0) + where = 0; + } + if (where > n) + where = n; + /* appends don't need to call memmove() */ + if (where != n) + memmove(items + (where+1)*self->ob_descr->itemsize, + items + where*self->ob_descr->itemsize, + (n-where)*self->ob_descr->itemsize); + return (*self->ob_descr->setitem)(self, where, v); +} + +/* Methods */ + +static void +array_dealloc(arrayobject *op) +{ + if (op->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) op); + if (op->ob_item != NULL) + PyMem_DEL(op->ob_item); + Py_TYPE(op)->tp_free((PyObject *)op); +} + +static PyObject * +array_richcompare(PyObject *v, PyObject *w, int op) +{ + arrayobject *va, *wa; + PyObject *vi = NULL; + PyObject *wi = NULL; + Py_ssize_t i, k; + PyObject *res; + + if (!array_Check(v) || !array_Check(w)) + Py_RETURN_NOTIMPLEMENTED; + + va = (arrayobject *)v; + wa = (arrayobject *)w; + + if (Py_SIZE(va) != Py_SIZE(wa) && (op == Py_EQ || op == Py_NE)) { + /* Shortcut: if the lengths differ, the arrays differ */ + if (op == Py_EQ) + res = Py_False; + else + res = Py_True; + Py_INCREF(res); + return res; + } + + if (va->ob_descr == wa->ob_descr && va->ob_descr->compareitems != NULL) { + /* Fast path: + arrays with same types can have their buffers compared directly */ + Py_ssize_t common_length = Py_MIN(Py_SIZE(va), Py_SIZE(wa)); + int result = va->ob_descr->compareitems(va->ob_item, wa->ob_item, + common_length); + if (result == 0) + goto compare_sizes; + + int cmp; + switch (op) { + case Py_LT: cmp = result < 0; break; + case Py_LE: cmp = result <= 0; break; + case Py_EQ: cmp = result == 0; break; + case Py_NE: cmp = result != 0; break; + case Py_GT: cmp = result > 0; break; + case Py_GE: cmp = result >= 0; break; + default: return NULL; /* cannot happen */ + } + PyObject *res = cmp ? Py_True : Py_False; + Py_INCREF(res); + return res; + } + + + /* Search for the first index where items are different */ + k = 1; + for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) { + vi = getarrayitem(v, i); + wi = getarrayitem(w, i); + if (vi == NULL || wi == NULL) { + Py_XDECREF(vi); + Py_XDECREF(wi); + return NULL; + } + k = PyObject_RichCompareBool(vi, wi, Py_EQ); + if (k == 0) + break; /* Keeping vi and wi alive! */ + Py_DECREF(vi); + Py_DECREF(wi); + if (k < 0) + return NULL; + } + + if (k) { + /* No more items to compare -- compare sizes */ + compare_sizes: ; + Py_ssize_t vs = Py_SIZE(va); + Py_ssize_t ws = Py_SIZE(wa); + int cmp; + switch (op) { + case Py_LT: cmp = vs < ws; break; + case Py_LE: cmp = vs <= ws; break; + /* If the lengths were not equal, + the earlier fast-path check would have caught that. */ + case Py_EQ: assert(vs == ws); cmp = 1; break; + case Py_NE: assert(vs == ws); cmp = 0; break; + case Py_GT: cmp = vs > ws; break; + case Py_GE: cmp = vs >= ws; break; + default: return NULL; /* cannot happen */ + } + if (cmp) + res = Py_True; + else + res = Py_False; + Py_INCREF(res); + return res; + } + + /* We have an item that differs. First, shortcuts for EQ/NE */ + if (op == Py_EQ) { + Py_INCREF(Py_False); + res = Py_False; + } + else if (op == Py_NE) { + Py_INCREF(Py_True); + res = Py_True; + } + else { + /* Compare the final item again using the proper operator */ + res = PyObject_RichCompare(vi, wi, op); + } + Py_DECREF(vi); + Py_DECREF(wi); + return res; +} + +static Py_ssize_t +array_length(arrayobject *a) +{ + return Py_SIZE(a); +} + +static PyObject * +array_item(arrayobject *a, Py_ssize_t i) +{ + if (i < 0 || i >= Py_SIZE(a)) { + PyErr_SetString(PyExc_IndexError, "array index out of range"); + return NULL; + } + return getarrayitem((PyObject *)a, i); +} + +static PyObject * +array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) +{ + arrayobject *np; + if (ilow < 0) + ilow = 0; + else if (ilow > Py_SIZE(a)) + ilow = Py_SIZE(a); + if (ihigh < 0) + ihigh = 0; + if (ihigh < ilow) + ihigh = ilow; + else if (ihigh > Py_SIZE(a)) + ihigh = Py_SIZE(a); + np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr); + if (np == NULL) + return NULL; + if (ihigh > ilow) { + memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize, + (ihigh-ilow) * a->ob_descr->itemsize); + } + return (PyObject *)np; +} + + +/*[clinic input] +array.array.__copy__ + +Return a copy of the array. +[clinic start generated code]*/ + +static PyObject * +array_array___copy___impl(arrayobject *self) +/*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/ +{ + return array_slice(self, 0, Py_SIZE(self)); +} + +/*[clinic input] +array.array.__deepcopy__ + + unused: object + / + +Return a copy of the array. +[clinic start generated code]*/ + +static PyObject * +array_array___deepcopy__(arrayobject *self, PyObject *unused) +/*[clinic end generated code: output=1ec748d8e14a9faa input=2405ecb4933748c4]*/ +{ + return array_array___copy___impl(self); +} + +static PyObject * +array_concat(arrayobject *a, PyObject *bb) +{ + Py_ssize_t size; + arrayobject *np; + if (!array_Check(bb)) { + PyErr_Format(PyExc_TypeError, + "can only append array (not \"%.200s\") to array", + Py_TYPE(bb)->tp_name); + return NULL; + } +#define b ((arrayobject *)bb) + if (a->ob_descr != b->ob_descr) { + PyErr_BadArgument(); + return NULL; + } + if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) { + return PyErr_NoMemory(); + } + size = Py_SIZE(a) + Py_SIZE(b); + np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); + if (np == NULL) { + return NULL; + } + if (Py_SIZE(a) > 0) { + memcpy(np->ob_item, a->ob_item, Py_SIZE(a)*a->ob_descr->itemsize); + } + if (Py_SIZE(b) > 0) { + memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize, + b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize); + } + return (PyObject *)np; +#undef b +} + +static PyObject * +array_repeat(arrayobject *a, Py_ssize_t n) +{ + Py_ssize_t size; + arrayobject *np; + Py_ssize_t oldbytes, newbytes; + if (n < 0) + n = 0; + if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) { + return PyErr_NoMemory(); + } + size = Py_SIZE(a) * n; + np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); + if (np == NULL) + return NULL; + if (size == 0) + return (PyObject *)np; + oldbytes = Py_SIZE(a) * a->ob_descr->itemsize; + newbytes = oldbytes * n; + /* this follows the code in unicode_repeat */ + if (oldbytes == 1) { + memset(np->ob_item, a->ob_item[0], newbytes); + } else { + Py_ssize_t done = oldbytes; + memcpy(np->ob_item, a->ob_item, oldbytes); + while (done < newbytes) { + Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done; + memcpy(np->ob_item+done, np->ob_item, ncopy); + done += ncopy; + } + } + return (PyObject *)np; +} + +static int +array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) +{ + char *item; + Py_ssize_t d; /* Change in size */ + if (ilow < 0) + ilow = 0; + else if (ilow > Py_SIZE(a)) + ilow = Py_SIZE(a); + if (ihigh < 0) + ihigh = 0; + if (ihigh < ilow) + ihigh = ilow; + else if (ihigh > Py_SIZE(a)) + ihigh = Py_SIZE(a); + item = a->ob_item; + d = ihigh-ilow; + /* Issue #4509: If the array has exported buffers and the slice + assignment would change the size of the array, fail early to make + sure we don't modify it. */ + if (d != 0 && a->ob_exports > 0) { + PyErr_SetString(PyExc_BufferError, + "cannot resize an array that is exporting buffers"); + return -1; + } + if (d > 0) { /* Delete d items */ + memmove(item + (ihigh-d)*a->ob_descr->itemsize, + item + ihigh*a->ob_descr->itemsize, + (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize); + if (array_resize(a, Py_SIZE(a) - d) == -1) + return -1; + } + return 0; +} + +static int +array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v) +{ + if (i < 0 || i >= Py_SIZE(a)) { + PyErr_SetString(PyExc_IndexError, + "array assignment index out of range"); + return -1; + } + if (v == NULL) + return array_del_slice(a, i, i+1); + return (*a->ob_descr->setitem)(a, i, v); +} + +static int +setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v) +{ + assert(array_Check(a)); + return array_ass_item((arrayobject *)a, i, v); +} + +static int +array_iter_extend(arrayobject *self, PyObject *bb) +{ + PyObject *it, *v; + + it = PyObject_GetIter(bb); + if (it == NULL) + return -1; + + while ((v = PyIter_Next(it)) != NULL) { + if (ins1(self, Py_SIZE(self), v) != 0) { + Py_DECREF(v); + Py_DECREF(it); + return -1; + } + Py_DECREF(v); + } + Py_DECREF(it); + if (PyErr_Occurred()) + return -1; + return 0; +} + +static int +array_do_extend(arrayobject *self, PyObject *bb) +{ + Py_ssize_t size, oldsize, bbsize; + + if (!array_Check(bb)) + return array_iter_extend(self, bb); +#define b ((arrayobject *)bb) + if (self->ob_descr != b->ob_descr) { + PyErr_SetString(PyExc_TypeError, + "can only extend with array of same kind"); + return -1; + } + if ((Py_SIZE(self) > PY_SSIZE_T_MAX - Py_SIZE(b)) || + ((Py_SIZE(self) + Py_SIZE(b)) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { + PyErr_NoMemory(); + return -1; + } + oldsize = Py_SIZE(self); + /* Get the size of bb before resizing the array since bb could be self. */ + bbsize = Py_SIZE(bb); + size = oldsize + Py_SIZE(b); + if (array_resize(self, size) == -1) + return -1; + if (bbsize > 0) { + memcpy(self->ob_item + oldsize * self->ob_descr->itemsize, + b->ob_item, bbsize * b->ob_descr->itemsize); + } + + return 0; +#undef b +} + +static PyObject * +array_inplace_concat(arrayobject *self, PyObject *bb) +{ + if (!array_Check(bb)) { + PyErr_Format(PyExc_TypeError, + "can only extend array with array (not \"%.200s\")", + Py_TYPE(bb)->tp_name); + return NULL; + } + if (array_do_extend(self, bb) == -1) + return NULL; + Py_INCREF(self); + return (PyObject *)self; +} + +static PyObject * +array_inplace_repeat(arrayobject *self, Py_ssize_t n) +{ + char *items, *p; + Py_ssize_t size, i; + + if (Py_SIZE(self) > 0) { + if (n < 0) + n = 0; + if ((self->ob_descr->itemsize != 0) && + (Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { + return PyErr_NoMemory(); + } + size = Py_SIZE(self) * self->ob_descr->itemsize; + if (n > 0 && size > PY_SSIZE_T_MAX / n) { + return PyErr_NoMemory(); + } + if (array_resize(self, n * Py_SIZE(self)) == -1) + return NULL; + items = p = self->ob_item; + for (i = 1; i < n; i++) { + p += size; + memcpy(p, items, size); + } + } + Py_INCREF(self); + return (PyObject *)self; +} + + +static PyObject * +ins(arrayobject *self, Py_ssize_t where, PyObject *v) +{ + if (ins1(self, where, v) != 0) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +array.array.count + + v: object + / + +Return number of occurrences of v in the array. +[clinic start generated code]*/ + +static PyObject * +array_array_count(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/ +{ + Py_ssize_t count = 0; + Py_ssize_t i; + + for (i = 0; i < Py_SIZE(self); i++) { + PyObject *selfi; + int cmp; + + selfi = getarrayitem((PyObject *)self, i); + if (selfi == NULL) + return NULL; + cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); + Py_DECREF(selfi); + if (cmp > 0) + count++; + else if (cmp < 0) + return NULL; + } + return PyLong_FromSsize_t(count); +} + + +/*[clinic input] +array.array.index + + v: object + / + +Return index of first occurrence of v in the array. +[clinic start generated code]*/ + +static PyObject * +array_array_index(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=d48498d325602167 input=cf619898c6649d08]*/ +{ + Py_ssize_t i; + + for (i = 0; i < Py_SIZE(self); i++) { + PyObject *selfi; + int cmp; + + selfi = getarrayitem((PyObject *)self, i); + if (selfi == NULL) + return NULL; + cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); + Py_DECREF(selfi); + if (cmp > 0) { + return PyLong_FromSsize_t(i); + } + else if (cmp < 0) + return NULL; + } + PyErr_SetString(PyExc_ValueError, "array.index(x): x not in array"); + return NULL; +} + +static int +array_contains(arrayobject *self, PyObject *v) +{ + Py_ssize_t i; + int cmp; + + for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) { + PyObject *selfi = getarrayitem((PyObject *)self, i); + if (selfi == NULL) + return -1; + cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); + Py_DECREF(selfi); + } + return cmp; +} + +/*[clinic input] +array.array.remove + + v: object + / + +Remove the first occurrence of v in the array. +[clinic start generated code]*/ + +static PyObject * +array_array_remove(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/ +{ + Py_ssize_t i; + + for (i = 0; i < Py_SIZE(self); i++) { + PyObject *selfi; + int cmp; + + selfi = getarrayitem((PyObject *)self,i); + if (selfi == NULL) + return NULL; + cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); + Py_DECREF(selfi); + if (cmp > 0) { + if (array_del_slice(self, i, i+1) != 0) + return NULL; + Py_RETURN_NONE; + } + else if (cmp < 0) + return NULL; + } + PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in array"); + return NULL; +} + +/*[clinic input] +array.array.pop + + i: Py_ssize_t = -1 + / + +Return the i-th element and delete it from the array. + +i defaults to -1. +[clinic start generated code]*/ + +static PyObject * +array_array_pop_impl(arrayobject *self, Py_ssize_t i) +/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/ +{ + PyObject *v; + + if (Py_SIZE(self) == 0) { + /* Special-case most common failure cause */ + PyErr_SetString(PyExc_IndexError, "pop from empty array"); + return NULL; + } + if (i < 0) + i += Py_SIZE(self); + if (i < 0 || i >= Py_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, "pop index out of range"); + return NULL; + } + v = getarrayitem((PyObject *)self, i); + if (v == NULL) + return NULL; + if (array_del_slice(self, i, i+1) != 0) { + Py_DECREF(v); + return NULL; + } + return v; +} + +/*[clinic input] +array.array.extend + + bb: object + / + +Append items to the end of the array. +[clinic start generated code]*/ + +static PyObject * +array_array_extend(arrayobject *self, PyObject *bb) +/*[clinic end generated code: output=bbddbc8e8bef871d input=43be86aba5c31e44]*/ +{ + if (array_do_extend(self, bb) == -1) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +array.array.insert + + i: Py_ssize_t + v: object + / + +Insert a new item v into the array before position i. +[clinic start generated code]*/ + +static PyObject * +array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v) +/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/ +{ + return ins(self, i, v); +} + +/*[clinic input] +array.array.buffer_info + +Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array's contents. + +The length should be multiplied by the itemsize attribute to calculate +the buffer length in bytes. +[clinic start generated code]*/ + +static PyObject * +array_array_buffer_info_impl(arrayobject *self) +/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/ +{ + PyObject *retval = NULL, *v; + + retval = PyTuple_New(2); + if (!retval) + return NULL; + + v = PyLong_FromVoidPtr(self->ob_item); + if (v == NULL) { + Py_DECREF(retval); + return NULL; + } + PyTuple_SET_ITEM(retval, 0, v); + + v = PyLong_FromSsize_t(Py_SIZE(self)); + if (v == NULL) { + Py_DECREF(retval); + return NULL; + } + PyTuple_SET_ITEM(retval, 1, v); + + return retval; +} + +/*[clinic input] +array.array.append + + v: object + / + +Append new value v to the end of the array. +[clinic start generated code]*/ + +static PyObject * +array_array_append(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/ +{ + return ins(self, Py_SIZE(self), v); +} + +/*[clinic input] +array.array.byteswap + +Byteswap all items of the array. + +If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is +raised. +[clinic start generated code]*/ + +static PyObject * +array_array_byteswap_impl(arrayobject *self) +/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/ +{ + char *p; + Py_ssize_t i; + + switch (self->ob_descr->itemsize) { + case 1: + break; + case 2: + for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) { + char p0 = p[0]; + p[0] = p[1]; + p[1] = p0; + } + break; + case 4: + for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 4) { + char p0 = p[0]; + char p1 = p[1]; + p[0] = p[3]; + p[1] = p[2]; + p[2] = p1; + p[3] = p0; + } + break; + case 8: + for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) { + char p0 = p[0]; + char p1 = p[1]; + char p2 = p[2]; + char p3 = p[3]; + p[0] = p[7]; + p[1] = p[6]; + p[2] = p[5]; + p[3] = p[4]; + p[4] = p3; + p[5] = p2; + p[6] = p1; + p[7] = p0; + } + break; + default: + PyErr_SetString(PyExc_RuntimeError, + "don't know how to byteswap this array type"); + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +array.array.reverse + +Reverse the order of the items in the array. +[clinic start generated code]*/ + +static PyObject * +array_array_reverse_impl(arrayobject *self) +/*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/ +{ + Py_ssize_t itemsize = self->ob_descr->itemsize; + char *p, *q; + /* little buffer to hold items while swapping */ + char tmp[256]; /* 8 is probably enough -- but why skimp */ + assert((size_t)itemsize <= sizeof(tmp)); + + if (Py_SIZE(self) > 1) { + for (p = self->ob_item, + q = self->ob_item + (Py_SIZE(self) - 1)*itemsize; + p < q; + p += itemsize, q -= itemsize) { + /* memory areas guaranteed disjoint, so memcpy + * is safe (& memmove may be slower). + */ + memcpy(tmp, p, itemsize); + memcpy(p, q, itemsize); + memcpy(q, tmp, itemsize); + } + } + + Py_RETURN_NONE; +} + +/*[clinic input] +array.array.fromfile + + f: object + n: Py_ssize_t + / + +Read n objects from the file object f and append them to the end of the array. +[clinic start generated code]*/ + +static PyObject * +array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n) +/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/ +{ + PyObject *b, *res; + Py_ssize_t itemsize = self->ob_descr->itemsize; + Py_ssize_t nbytes; + _Py_IDENTIFIER(read); + int not_enough_bytes; + + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + if (n > PY_SSIZE_T_MAX / itemsize) { + PyErr_NoMemory(); + return NULL; + } + nbytes = n * itemsize; + + b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes); + if (b == NULL) + return NULL; + + if (!PyBytes_Check(b)) { + PyErr_SetString(PyExc_TypeError, + "read() didn't return bytes"); + Py_DECREF(b); + return NULL; + } + + not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes); + + res = array_array_frombytes(self, b); + Py_DECREF(b); + if (res == NULL) + return NULL; + + if (not_enough_bytes) { + PyErr_SetString(PyExc_EOFError, + "read() didn't return enough bytes"); + Py_DECREF(res); + return NULL; + } + + return res; +} + +/*[clinic input] +array.array.tofile + + f: object + / + +Write all items (as machine values) to the file object f. +[clinic start generated code]*/ + +static PyObject * +array_array_tofile(arrayobject *self, PyObject *f) +/*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831]*/ +{ + Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize; + /* Write 64K blocks at a time */ + /* XXX Make the block size settable */ + int BLOCKSIZE = 64*1024; + Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE; + Py_ssize_t i; + + if (Py_SIZE(self) == 0) + goto done; + + for (i = 0; i < nblocks; i++) { + char* ptr = self->ob_item + i*BLOCKSIZE; + Py_ssize_t size = BLOCKSIZE; + PyObject *bytes, *res; + _Py_IDENTIFIER(write); + + if (i*BLOCKSIZE + size > nbytes) + size = nbytes - i*BLOCKSIZE; + bytes = PyBytes_FromStringAndSize(ptr, size); + if (bytes == NULL) + return NULL; + res = _PyObject_CallMethodIdOneArg(f, &PyId_write, bytes); + Py_DECREF(bytes); + if (res == NULL) + return NULL; + Py_DECREF(res); /* drop write result */ + } + + done: + Py_RETURN_NONE; +} + +/*[clinic input] +array.array.fromlist + + list: object + / + +Append items to array from list. +[clinic start generated code]*/ + +static PyObject * +array_array_fromlist(arrayobject *self, PyObject *list) +/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/ +{ + Py_ssize_t n; + + if (!PyList_Check(list)) { + PyErr_SetString(PyExc_TypeError, "arg must be list"); + return NULL; + } + n = PyList_Size(list); + if (n > 0) { + Py_ssize_t i, old_size; + old_size = Py_SIZE(self); + if (array_resize(self, old_size + n) == -1) + return NULL; + for (i = 0; i < n; i++) { + PyObject *v = PyList_GET_ITEM(list, i); + if ((*self->ob_descr->setitem)(self, + Py_SIZE(self) - n + i, v) != 0) { + array_resize(self, old_size); + return NULL; + } + if (n != PyList_GET_SIZE(list)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); + array_resize(self, old_size); + return NULL; + } + } + } + Py_RETURN_NONE; +} + +/*[clinic input] +array.array.tolist + +Convert array to an ordinary list with the same items. +[clinic start generated code]*/ + +static PyObject * +array_array_tolist_impl(arrayobject *self) +/*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/ +{ + PyObject *list = PyList_New(Py_SIZE(self)); + Py_ssize_t i; + + if (list == NULL) + return NULL; + for (i = 0; i < Py_SIZE(self); i++) { + PyObject *v = getarrayitem((PyObject *)self, i); + if (v == NULL) + goto error; + PyList_SET_ITEM(list, i, v); + } + return list; + +error: + Py_DECREF(list); + return NULL; +} + +static PyObject * +frombytes(arrayobject *self, Py_buffer *buffer) +{ + int itemsize = self->ob_descr->itemsize; + Py_ssize_t n; + if (buffer->itemsize != 1) { + PyBuffer_Release(buffer); + PyErr_SetString(PyExc_TypeError, "a bytes-like object is required"); + return NULL; + } + n = buffer->len; + if (n % itemsize != 0) { + PyBuffer_Release(buffer); + PyErr_SetString(PyExc_ValueError, + "bytes length not a multiple of item size"); + return NULL; + } + n = n / itemsize; + if (n > 0) { + Py_ssize_t old_size = Py_SIZE(self); + if ((n > PY_SSIZE_T_MAX - old_size) || + ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) { + PyBuffer_Release(buffer); + return PyErr_NoMemory(); + } + if (array_resize(self, old_size + n) == -1) { + PyBuffer_Release(buffer); + return NULL; + } + memcpy(self->ob_item + old_size * itemsize, + buffer->buf, n * itemsize); + } + PyBuffer_Release(buffer); + Py_RETURN_NONE; +} + +/*[clinic input] +array.array.frombytes + + buffer: Py_buffer + / + +Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method. +[clinic start generated code]*/ + +static PyObject * +array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer) +/*[clinic end generated code: output=d9842c8f7510a516 input=378db226dfac949e]*/ +{ + return frombytes(self, buffer); +} + +/*[clinic input] +array.array.tobytes + +Convert the array to an array of machine values and return the bytes representation. +[clinic start generated code]*/ + +static PyObject * +array_array_tobytes_impl(arrayobject *self) +/*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/ +{ + if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) { + return PyBytes_FromStringAndSize(self->ob_item, + Py_SIZE(self) * self->ob_descr->itemsize); + } else { + return PyErr_NoMemory(); + } +} + +/*[clinic input] +array.array.fromunicode + ustr: unicode - / - -Extends this array with data from the unicode string ustr. - -The array must be a unicode type array; otherwise a ValueError is raised. -Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of -some other type. -[clinic start generated code]*/ - -static PyObject * + / + +Extends this array with data from the unicode string ustr. + +The array must be a unicode type array; otherwise a ValueError is raised. +Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of +some other type. +[clinic start generated code]*/ + +static PyObject * array_array_fromunicode_impl(arrayobject *self, PyObject *ustr) /*[clinic end generated code: output=24359f5e001a7f2b input=025db1fdade7a4ce]*/ -{ +{ if (self->ob_descr->typecode != 'u') { - PyErr_SetString(PyExc_ValueError, - "fromunicode() may only be called on " - "unicode type arrays"); - return NULL; - } + PyErr_SetString(PyExc_ValueError, + "fromunicode() may only be called on " + "unicode type arrays"); + return NULL; + } Py_ssize_t ustr_length = PyUnicode_AsWideChar(ustr, NULL, 0); assert(ustr_length > 0); if (ustr_length > 1) { ustr_length--; /* trim trailing NUL character */ - Py_ssize_t old_size = Py_SIZE(self); + Py_ssize_t old_size = Py_SIZE(self); if (array_resize(self, old_size + ustr_length) == -1) { - return NULL; + return NULL; } // must not fail PyUnicode_AsWideChar( ustr, ((wchar_t *)self->ob_item) + old_size, ustr_length); - } - - Py_RETURN_NONE; -} - -/*[clinic input] -array.array.tounicode - -Extends this array with data from the unicode string ustr. - -Convert the array to a unicode string. The array must be a unicode type array; -otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a -unicode string from an array of some other type. -[clinic start generated code]*/ - -static PyObject * -array_array_tounicode_impl(arrayobject *self) -/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/ -{ + } + + Py_RETURN_NONE; +} + +/*[clinic input] +array.array.tounicode + +Extends this array with data from the unicode string ustr. + +Convert the array to a unicode string. The array must be a unicode type array; +otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a +unicode string from an array of some other type. +[clinic start generated code]*/ + +static PyObject * +array_array_tounicode_impl(arrayobject *self) +/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/ +{ if (self->ob_descr->typecode != 'u') { - PyErr_SetString(PyExc_ValueError, - "tounicode() may only be called on unicode type arrays"); - return NULL; - } + PyErr_SetString(PyExc_ValueError, + "tounicode() may only be called on unicode type arrays"); + return NULL; + } return PyUnicode_FromWideChar((wchar_t *) self->ob_item, Py_SIZE(self)); -} - -/*[clinic input] -array.array.__sizeof__ - -Size of the array in memory, in bytes. -[clinic start generated code]*/ - -static PyObject * -array_array___sizeof___impl(arrayobject *self) -/*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/ -{ - Py_ssize_t res; - res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize; - return PyLong_FromSsize_t(res); -} - - -/*********************** Pickling support ************************/ - -static const struct mformatdescr { - size_t size; - int is_signed; - int is_big_endian; -} mformat_descriptors[] = { - {1, 0, 0}, /* 0: UNSIGNED_INT8 */ - {1, 1, 0}, /* 1: SIGNED_INT8 */ - {2, 0, 0}, /* 2: UNSIGNED_INT16_LE */ - {2, 0, 1}, /* 3: UNSIGNED_INT16_BE */ - {2, 1, 0}, /* 4: SIGNED_INT16_LE */ - {2, 1, 1}, /* 5: SIGNED_INT16_BE */ - {4, 0, 0}, /* 6: UNSIGNED_INT32_LE */ - {4, 0, 1}, /* 7: UNSIGNED_INT32_BE */ - {4, 1, 0}, /* 8: SIGNED_INT32_LE */ - {4, 1, 1}, /* 9: SIGNED_INT32_BE */ - {8, 0, 0}, /* 10: UNSIGNED_INT64_LE */ - {8, 0, 1}, /* 11: UNSIGNED_INT64_BE */ - {8, 1, 0}, /* 12: SIGNED_INT64_LE */ - {8, 1, 1}, /* 13: SIGNED_INT64_BE */ - {4, 0, 0}, /* 14: IEEE_754_FLOAT_LE */ - {4, 0, 1}, /* 15: IEEE_754_FLOAT_BE */ - {8, 0, 0}, /* 16: IEEE_754_DOUBLE_LE */ - {8, 0, 1}, /* 17: IEEE_754_DOUBLE_BE */ - {4, 0, 0}, /* 18: UTF16_LE */ - {4, 0, 1}, /* 19: UTF16_BE */ - {8, 0, 0}, /* 20: UTF32_LE */ - {8, 0, 1} /* 21: UTF32_BE */ -}; - - -/* - * Internal: This function is used to find the machine format of a given - * array type code. This returns UNKNOWN_FORMAT when the machine format cannot - * be found. - */ -static enum machine_format_code -typecode_to_mformat_code(char typecode) -{ - const int is_big_endian = PY_BIG_ENDIAN; - - size_t intsize; - int is_signed; - - switch (typecode) { - case 'b': - return SIGNED_INT8; - case 'B': - return UNSIGNED_INT8; - - case 'u': - if (sizeof(Py_UNICODE) == 2) { - return UTF16_LE + is_big_endian; - } - if (sizeof(Py_UNICODE) == 4) { - return UTF32_LE + is_big_endian; - } - return UNKNOWN_FORMAT; - - case 'f': - if (sizeof(float) == 4) { - const float y = 16711938.0; - if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0) - return IEEE_754_FLOAT_BE; - if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0) - return IEEE_754_FLOAT_LE; - } - return UNKNOWN_FORMAT; - - case 'd': - if (sizeof(double) == 8) { - const double x = 9006104071832581.0; - if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) - return IEEE_754_DOUBLE_BE; - if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) - return IEEE_754_DOUBLE_LE; - } - return UNKNOWN_FORMAT; - - /* Integers */ - case 'h': - intsize = sizeof(short); - is_signed = 1; - break; - case 'H': - intsize = sizeof(short); - is_signed = 0; - break; - case 'i': - intsize = sizeof(int); - is_signed = 1; - break; - case 'I': - intsize = sizeof(int); - is_signed = 0; - break; - case 'l': - intsize = sizeof(long); - is_signed = 1; - break; - case 'L': - intsize = sizeof(long); - is_signed = 0; - break; - case 'q': - intsize = sizeof(long long); - is_signed = 1; - break; - case 'Q': - intsize = sizeof(long long); - is_signed = 0; - break; - default: - return UNKNOWN_FORMAT; - } - switch (intsize) { - case 2: - return UNSIGNED_INT16_LE + is_big_endian + (2 * is_signed); - case 4: - return UNSIGNED_INT32_LE + is_big_endian + (2 * is_signed); - case 8: - return UNSIGNED_INT64_LE + is_big_endian + (2 * is_signed); - default: - return UNKNOWN_FORMAT; - } -} - -/* Forward declaration. */ -static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds); - -/* - * Internal: This function wraps the array constructor--i.e., array_new()--to - * allow the creation of array objects from C code without having to deal - * directly the tuple argument of array_new(). The typecode argument is a - * Unicode character value, like 'i' or 'f' for example, representing an array - * type code. The items argument is a bytes or a list object from which - * contains the initial value of the array. - * - * On success, this functions returns the array object created. Otherwise, - * NULL is returned to indicate a failure. - */ -static PyObject * -make_array(PyTypeObject *arraytype, char typecode, PyObject *items) -{ - PyObject *new_args; - PyObject *array_obj; - PyObject *typecode_obj; - - assert(arraytype != NULL); - assert(items != NULL); - - typecode_obj = PyUnicode_FromOrdinal(typecode); - if (typecode_obj == NULL) - return NULL; - - new_args = PyTuple_New(2); - if (new_args == NULL) { - Py_DECREF(typecode_obj); - return NULL; - } - Py_INCREF(items); - PyTuple_SET_ITEM(new_args, 0, typecode_obj); - PyTuple_SET_ITEM(new_args, 1, items); - - array_obj = array_new(arraytype, new_args, NULL); - Py_DECREF(new_args); - if (array_obj == NULL) - return NULL; - - return array_obj; -} - -/* - * This functions is a special constructor used when unpickling an array. It - * provides a portable way to rebuild an array from its memory representation. - */ -/*[clinic input] -array._array_reconstructor - - arraytype: object(type="PyTypeObject *") - typecode: int(accept={str}) - mformat_code: int(type="enum machine_format_code") - items: object - / - -Internal. Used for pickling support. -[clinic start generated code]*/ - -static PyObject * -array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, - int typecode, - enum machine_format_code mformat_code, - PyObject *items) -/*[clinic end generated code: output=e05263141ba28365 input=2464dc8f4c7736b5]*/ -{ - PyObject *converted_items; - PyObject *result; - const struct arraydescr *descr; - - if (!PyType_Check(arraytype)) { - PyErr_Format(PyExc_TypeError, - "first argument must be a type object, not %.200s", - Py_TYPE(arraytype)->tp_name); - return NULL; - } - if (!PyType_IsSubtype(arraytype, &Arraytype)) { - PyErr_Format(PyExc_TypeError, - "%.200s is not a subtype of %.200s", - arraytype->tp_name, Arraytype.tp_name); - return NULL; - } - for (descr = descriptors; descr->typecode != '\0'; descr++) { - if ((int)descr->typecode == typecode) - break; - } - if (descr->typecode == '\0') { - PyErr_SetString(PyExc_ValueError, - "second argument must be a valid type code"); - return NULL; - } - if (mformat_code < MACHINE_FORMAT_CODE_MIN || - mformat_code > MACHINE_FORMAT_CODE_MAX) { - PyErr_SetString(PyExc_ValueError, - "third argument must be a valid machine format code."); - return NULL; - } - if (!PyBytes_Check(items)) { - PyErr_Format(PyExc_TypeError, - "fourth argument should be bytes, not %.200s", - Py_TYPE(items)->tp_name); - return NULL; - } - - /* Fast path: No decoding has to be done. */ - if (mformat_code == typecode_to_mformat_code((char)typecode) || - mformat_code == UNKNOWN_FORMAT) { - return make_array(arraytype, (char)typecode, items); - } - - /* Slow path: Decode the byte string according to the given machine - * format code. This occurs when the computer unpickling the array - * object is architecturally different from the one that pickled the - * array. - */ - if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) { - PyErr_SetString(PyExc_ValueError, - "string length not a multiple of item size"); - return NULL; - } - switch (mformat_code) { - case IEEE_754_FLOAT_LE: - case IEEE_754_FLOAT_BE: { +} + +/*[clinic input] +array.array.__sizeof__ + +Size of the array in memory, in bytes. +[clinic start generated code]*/ + +static PyObject * +array_array___sizeof___impl(arrayobject *self) +/*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/ +{ + Py_ssize_t res; + res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize; + return PyLong_FromSsize_t(res); +} + + +/*********************** Pickling support ************************/ + +static const struct mformatdescr { + size_t size; + int is_signed; + int is_big_endian; +} mformat_descriptors[] = { + {1, 0, 0}, /* 0: UNSIGNED_INT8 */ + {1, 1, 0}, /* 1: SIGNED_INT8 */ + {2, 0, 0}, /* 2: UNSIGNED_INT16_LE */ + {2, 0, 1}, /* 3: UNSIGNED_INT16_BE */ + {2, 1, 0}, /* 4: SIGNED_INT16_LE */ + {2, 1, 1}, /* 5: SIGNED_INT16_BE */ + {4, 0, 0}, /* 6: UNSIGNED_INT32_LE */ + {4, 0, 1}, /* 7: UNSIGNED_INT32_BE */ + {4, 1, 0}, /* 8: SIGNED_INT32_LE */ + {4, 1, 1}, /* 9: SIGNED_INT32_BE */ + {8, 0, 0}, /* 10: UNSIGNED_INT64_LE */ + {8, 0, 1}, /* 11: UNSIGNED_INT64_BE */ + {8, 1, 0}, /* 12: SIGNED_INT64_LE */ + {8, 1, 1}, /* 13: SIGNED_INT64_BE */ + {4, 0, 0}, /* 14: IEEE_754_FLOAT_LE */ + {4, 0, 1}, /* 15: IEEE_754_FLOAT_BE */ + {8, 0, 0}, /* 16: IEEE_754_DOUBLE_LE */ + {8, 0, 1}, /* 17: IEEE_754_DOUBLE_BE */ + {4, 0, 0}, /* 18: UTF16_LE */ + {4, 0, 1}, /* 19: UTF16_BE */ + {8, 0, 0}, /* 20: UTF32_LE */ + {8, 0, 1} /* 21: UTF32_BE */ +}; + + +/* + * Internal: This function is used to find the machine format of a given + * array type code. This returns UNKNOWN_FORMAT when the machine format cannot + * be found. + */ +static enum machine_format_code +typecode_to_mformat_code(char typecode) +{ + const int is_big_endian = PY_BIG_ENDIAN; + + size_t intsize; + int is_signed; + + switch (typecode) { + case 'b': + return SIGNED_INT8; + case 'B': + return UNSIGNED_INT8; + + case 'u': + if (sizeof(Py_UNICODE) == 2) { + return UTF16_LE + is_big_endian; + } + if (sizeof(Py_UNICODE) == 4) { + return UTF32_LE + is_big_endian; + } + return UNKNOWN_FORMAT; + + case 'f': + if (sizeof(float) == 4) { + const float y = 16711938.0; + if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0) + return IEEE_754_FLOAT_BE; + if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0) + return IEEE_754_FLOAT_LE; + } + return UNKNOWN_FORMAT; + + case 'd': + if (sizeof(double) == 8) { + const double x = 9006104071832581.0; + if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) + return IEEE_754_DOUBLE_BE; + if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) + return IEEE_754_DOUBLE_LE; + } + return UNKNOWN_FORMAT; + + /* Integers */ + case 'h': + intsize = sizeof(short); + is_signed = 1; + break; + case 'H': + intsize = sizeof(short); + is_signed = 0; + break; + case 'i': + intsize = sizeof(int); + is_signed = 1; + break; + case 'I': + intsize = sizeof(int); + is_signed = 0; + break; + case 'l': + intsize = sizeof(long); + is_signed = 1; + break; + case 'L': + intsize = sizeof(long); + is_signed = 0; + break; + case 'q': + intsize = sizeof(long long); + is_signed = 1; + break; + case 'Q': + intsize = sizeof(long long); + is_signed = 0; + break; + default: + return UNKNOWN_FORMAT; + } + switch (intsize) { + case 2: + return UNSIGNED_INT16_LE + is_big_endian + (2 * is_signed); + case 4: + return UNSIGNED_INT32_LE + is_big_endian + (2 * is_signed); + case 8: + return UNSIGNED_INT64_LE + is_big_endian + (2 * is_signed); + default: + return UNKNOWN_FORMAT; + } +} + +/* Forward declaration. */ +static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + +/* + * Internal: This function wraps the array constructor--i.e., array_new()--to + * allow the creation of array objects from C code without having to deal + * directly the tuple argument of array_new(). The typecode argument is a + * Unicode character value, like 'i' or 'f' for example, representing an array + * type code. The items argument is a bytes or a list object from which + * contains the initial value of the array. + * + * On success, this functions returns the array object created. Otherwise, + * NULL is returned to indicate a failure. + */ +static PyObject * +make_array(PyTypeObject *arraytype, char typecode, PyObject *items) +{ + PyObject *new_args; + PyObject *array_obj; + PyObject *typecode_obj; + + assert(arraytype != NULL); + assert(items != NULL); + + typecode_obj = PyUnicode_FromOrdinal(typecode); + if (typecode_obj == NULL) + return NULL; + + new_args = PyTuple_New(2); + if (new_args == NULL) { + Py_DECREF(typecode_obj); + return NULL; + } + Py_INCREF(items); + PyTuple_SET_ITEM(new_args, 0, typecode_obj); + PyTuple_SET_ITEM(new_args, 1, items); + + array_obj = array_new(arraytype, new_args, NULL); + Py_DECREF(new_args); + if (array_obj == NULL) + return NULL; + + return array_obj; +} + +/* + * This functions is a special constructor used when unpickling an array. It + * provides a portable way to rebuild an array from its memory representation. + */ +/*[clinic input] +array._array_reconstructor + + arraytype: object(type="PyTypeObject *") + typecode: int(accept={str}) + mformat_code: int(type="enum machine_format_code") + items: object + / + +Internal. Used for pickling support. +[clinic start generated code]*/ + +static PyObject * +array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, + int typecode, + enum machine_format_code mformat_code, + PyObject *items) +/*[clinic end generated code: output=e05263141ba28365 input=2464dc8f4c7736b5]*/ +{ + PyObject *converted_items; + PyObject *result; + const struct arraydescr *descr; + + if (!PyType_Check(arraytype)) { + PyErr_Format(PyExc_TypeError, + "first argument must be a type object, not %.200s", + Py_TYPE(arraytype)->tp_name); + return NULL; + } + if (!PyType_IsSubtype(arraytype, &Arraytype)) { + PyErr_Format(PyExc_TypeError, + "%.200s is not a subtype of %.200s", + arraytype->tp_name, Arraytype.tp_name); + return NULL; + } + for (descr = descriptors; descr->typecode != '\0'; descr++) { + if ((int)descr->typecode == typecode) + break; + } + if (descr->typecode == '\0') { + PyErr_SetString(PyExc_ValueError, + "second argument must be a valid type code"); + return NULL; + } + if (mformat_code < MACHINE_FORMAT_CODE_MIN || + mformat_code > MACHINE_FORMAT_CODE_MAX) { + PyErr_SetString(PyExc_ValueError, + "third argument must be a valid machine format code."); + return NULL; + } + if (!PyBytes_Check(items)) { + PyErr_Format(PyExc_TypeError, + "fourth argument should be bytes, not %.200s", + Py_TYPE(items)->tp_name); + return NULL; + } + + /* Fast path: No decoding has to be done. */ + if (mformat_code == typecode_to_mformat_code((char)typecode) || + mformat_code == UNKNOWN_FORMAT) { + return make_array(arraytype, (char)typecode, items); + } + + /* Slow path: Decode the byte string according to the given machine + * format code. This occurs when the computer unpickling the array + * object is architecturally different from the one that pickled the + * array. + */ + if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) { + PyErr_SetString(PyExc_ValueError, + "string length not a multiple of item size"); + return NULL; + } + switch (mformat_code) { + case IEEE_754_FLOAT_LE: + case IEEE_754_FLOAT_BE: { Py_ssize_t i; - int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0; - Py_ssize_t itemcount = Py_SIZE(items) / 4; - const unsigned char *memstr = - (unsigned char *)PyBytes_AS_STRING(items); - - converted_items = PyList_New(itemcount); - if (converted_items == NULL) - return NULL; - for (i = 0; i < itemcount; i++) { - PyObject *pyfloat = PyFloat_FromDouble( - _PyFloat_Unpack4(&memstr[i * 4], le)); - if (pyfloat == NULL) { - Py_DECREF(converted_items); - return NULL; - } - PyList_SET_ITEM(converted_items, i, pyfloat); - } - break; - } - case IEEE_754_DOUBLE_LE: - case IEEE_754_DOUBLE_BE: { + int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0; + Py_ssize_t itemcount = Py_SIZE(items) / 4; + const unsigned char *memstr = + (unsigned char *)PyBytes_AS_STRING(items); + + converted_items = PyList_New(itemcount); + if (converted_items == NULL) + return NULL; + for (i = 0; i < itemcount; i++) { + PyObject *pyfloat = PyFloat_FromDouble( + _PyFloat_Unpack4(&memstr[i * 4], le)); + if (pyfloat == NULL) { + Py_DECREF(converted_items); + return NULL; + } + PyList_SET_ITEM(converted_items, i, pyfloat); + } + break; + } + case IEEE_754_DOUBLE_LE: + case IEEE_754_DOUBLE_BE: { Py_ssize_t i; - int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0; - Py_ssize_t itemcount = Py_SIZE(items) / 8; - const unsigned char *memstr = - (unsigned char *)PyBytes_AS_STRING(items); - - converted_items = PyList_New(itemcount); - if (converted_items == NULL) - return NULL; - for (i = 0; i < itemcount; i++) { - PyObject *pyfloat = PyFloat_FromDouble( - _PyFloat_Unpack8(&memstr[i * 8], le)); - if (pyfloat == NULL) { - Py_DECREF(converted_items); - return NULL; - } - PyList_SET_ITEM(converted_items, i, pyfloat); - } - break; - } - case UTF16_LE: - case UTF16_BE: { - int byteorder = (mformat_code == UTF16_LE) ? -1 : 1; - converted_items = PyUnicode_DecodeUTF16( - PyBytes_AS_STRING(items), Py_SIZE(items), - "strict", &byteorder); - if (converted_items == NULL) - return NULL; - break; - } - case UTF32_LE: - case UTF32_BE: { - int byteorder = (mformat_code == UTF32_LE) ? -1 : 1; - converted_items = PyUnicode_DecodeUTF32( - PyBytes_AS_STRING(items), Py_SIZE(items), - "strict", &byteorder); - if (converted_items == NULL) - return NULL; - break; - } - - case UNSIGNED_INT8: - case SIGNED_INT8: - case UNSIGNED_INT16_LE: - case UNSIGNED_INT16_BE: - case SIGNED_INT16_LE: - case SIGNED_INT16_BE: - case UNSIGNED_INT32_LE: - case UNSIGNED_INT32_BE: - case SIGNED_INT32_LE: - case SIGNED_INT32_BE: - case UNSIGNED_INT64_LE: - case UNSIGNED_INT64_BE: - case SIGNED_INT64_LE: - case SIGNED_INT64_BE: { + int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0; + Py_ssize_t itemcount = Py_SIZE(items) / 8; + const unsigned char *memstr = + (unsigned char *)PyBytes_AS_STRING(items); + + converted_items = PyList_New(itemcount); + if (converted_items == NULL) + return NULL; + for (i = 0; i < itemcount; i++) { + PyObject *pyfloat = PyFloat_FromDouble( + _PyFloat_Unpack8(&memstr[i * 8], le)); + if (pyfloat == NULL) { + Py_DECREF(converted_items); + return NULL; + } + PyList_SET_ITEM(converted_items, i, pyfloat); + } + break; + } + case UTF16_LE: + case UTF16_BE: { + int byteorder = (mformat_code == UTF16_LE) ? -1 : 1; + converted_items = PyUnicode_DecodeUTF16( + PyBytes_AS_STRING(items), Py_SIZE(items), + "strict", &byteorder); + if (converted_items == NULL) + return NULL; + break; + } + case UTF32_LE: + case UTF32_BE: { + int byteorder = (mformat_code == UTF32_LE) ? -1 : 1; + converted_items = PyUnicode_DecodeUTF32( + PyBytes_AS_STRING(items), Py_SIZE(items), + "strict", &byteorder); + if (converted_items == NULL) + return NULL; + break; + } + + case UNSIGNED_INT8: + case SIGNED_INT8: + case UNSIGNED_INT16_LE: + case UNSIGNED_INT16_BE: + case SIGNED_INT16_LE: + case SIGNED_INT16_BE: + case UNSIGNED_INT32_LE: + case UNSIGNED_INT32_BE: + case SIGNED_INT32_LE: + case SIGNED_INT32_BE: + case UNSIGNED_INT64_LE: + case UNSIGNED_INT64_BE: + case SIGNED_INT64_LE: + case SIGNED_INT64_BE: { Py_ssize_t i; - const struct mformatdescr mf_descr = - mformat_descriptors[mformat_code]; - Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size; - const unsigned char *memstr = - (unsigned char *)PyBytes_AS_STRING(items); - const struct arraydescr *descr; - - /* If possible, try to pack array's items using a data type - * that fits better. This may result in an array with narrower - * or wider elements. - * - * For example, if a 32-bit machine pickles an L-code array of - * unsigned longs, then the array will be unpickled by 64-bit - * machine as an I-code array of unsigned ints. - * - * XXX: Is it possible to write a unit test for this? - */ - for (descr = descriptors; descr->typecode != '\0'; descr++) { - if (descr->is_integer_type && - (size_t)descr->itemsize == mf_descr.size && - descr->is_signed == mf_descr.is_signed) - typecode = descr->typecode; - } - - converted_items = PyList_New(itemcount); - if (converted_items == NULL) - return NULL; - for (i = 0; i < itemcount; i++) { - PyObject *pylong; - - pylong = _PyLong_FromByteArray( - &memstr[i * mf_descr.size], - mf_descr.size, - !mf_descr.is_big_endian, - mf_descr.is_signed); - if (pylong == NULL) { - Py_DECREF(converted_items); - return NULL; - } - PyList_SET_ITEM(converted_items, i, pylong); - } - break; - } - case UNKNOWN_FORMAT: - /* Impossible, but needed to shut up GCC about the unhandled - * enumeration value. - */ - default: - PyErr_BadArgument(); - return NULL; - } - - result = make_array(arraytype, (char)typecode, converted_items); - Py_DECREF(converted_items); - return result; -} - -/*[clinic input] -array.array.__reduce_ex__ - - value: object - / - -Return state information for pickling. -[clinic start generated code]*/ - -static PyObject * -array_array___reduce_ex__(arrayobject *self, PyObject *value) -/*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/ -{ - PyObject *dict; - PyObject *result; - PyObject *array_str; - int typecode = self->ob_descr->typecode; - int mformat_code; - static PyObject *array_reconstructor = NULL; - long protocol; - _Py_IDENTIFIER(_array_reconstructor); - _Py_IDENTIFIER(__dict__); - - if (array_reconstructor == NULL) { - PyObject *array_module = PyImport_ImportModule("array"); - if (array_module == NULL) - return NULL; - array_reconstructor = _PyObject_GetAttrId( - array_module, - &PyId__array_reconstructor); - Py_DECREF(array_module); - if (array_reconstructor == NULL) - return NULL; - } - - if (!PyLong_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__reduce_ex__ argument should be an integer"); - return NULL; - } - protocol = PyLong_AsLong(value); - if (protocol == -1 && PyErr_Occurred()) - return NULL; - - if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) { - return NULL; - } - if (dict == NULL) { - dict = Py_None; - Py_INCREF(dict); - } - - mformat_code = typecode_to_mformat_code(typecode); - if (mformat_code == UNKNOWN_FORMAT || protocol < 3) { - /* Convert the array to a list if we got something weird - * (e.g., non-IEEE floats), or we are pickling the array using - * a Python 2.x compatible protocol. - * - * It is necessary to use a list representation for Python 2.x - * compatible pickle protocol, since Python 2's str objects - * are unpickled as unicode by Python 3. Thus it is impossible - * to make arrays unpicklable by Python 3 by using their memory - * representation, unless we resort to ugly hacks such as - * coercing unicode objects to bytes in array_reconstructor. - */ - PyObject *list; - list = array_array_tolist_impl(self); - if (list == NULL) { - Py_DECREF(dict); - return NULL; - } - result = Py_BuildValue( - "O(CO)O", Py_TYPE(self), typecode, list, dict); - Py_DECREF(list); - Py_DECREF(dict); - return result; - } - - array_str = array_array_tobytes_impl(self); - if (array_str == NULL) { - Py_DECREF(dict); - return NULL; - } - result = Py_BuildValue( - "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode, - mformat_code, array_str, dict); - Py_DECREF(dict); - return result; -} - -static PyObject * -array_get_typecode(arrayobject *a, void *closure) -{ - char typecode = a->ob_descr->typecode; - return PyUnicode_FromOrdinal(typecode); -} - -static PyObject * -array_get_itemsize(arrayobject *a, void *closure) -{ - return PyLong_FromLong((long)a->ob_descr->itemsize); -} - -static PyGetSetDef array_getsets [] = { - {"typecode", (getter) array_get_typecode, NULL, - "the typecode character used to create the array"}, - {"itemsize", (getter) array_get_itemsize, NULL, - "the size, in bytes, of one array item"}, - {NULL} -}; - -static PyMethodDef array_methods[] = { - ARRAY_ARRAY_APPEND_METHODDEF - ARRAY_ARRAY_BUFFER_INFO_METHODDEF - ARRAY_ARRAY_BYTESWAP_METHODDEF - ARRAY_ARRAY___COPY___METHODDEF - ARRAY_ARRAY_COUNT_METHODDEF - ARRAY_ARRAY___DEEPCOPY___METHODDEF - ARRAY_ARRAY_EXTEND_METHODDEF - ARRAY_ARRAY_FROMFILE_METHODDEF - ARRAY_ARRAY_FROMLIST_METHODDEF - ARRAY_ARRAY_FROMBYTES_METHODDEF - ARRAY_ARRAY_FROMUNICODE_METHODDEF - ARRAY_ARRAY_INDEX_METHODDEF - ARRAY_ARRAY_INSERT_METHODDEF - ARRAY_ARRAY_POP_METHODDEF - ARRAY_ARRAY___REDUCE_EX___METHODDEF - ARRAY_ARRAY_REMOVE_METHODDEF - ARRAY_ARRAY_REVERSE_METHODDEF - ARRAY_ARRAY_TOFILE_METHODDEF - ARRAY_ARRAY_TOLIST_METHODDEF - ARRAY_ARRAY_TOBYTES_METHODDEF - ARRAY_ARRAY_TOUNICODE_METHODDEF - ARRAY_ARRAY___SIZEOF___METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -array_repr(arrayobject *a) -{ - char typecode; - PyObject *s, *v = NULL; - Py_ssize_t len; - - len = Py_SIZE(a); - typecode = a->ob_descr->typecode; - if (len == 0) { - return PyUnicode_FromFormat("%s('%c')", - _PyType_Name(Py_TYPE(a)), (int)typecode); - } - if (typecode == 'u') { - v = array_array_tounicode_impl(a); - } else { - v = array_array_tolist_impl(a); - } - if (v == NULL) - return NULL; - - s = PyUnicode_FromFormat("%s('%c', %R)", - _PyType_Name(Py_TYPE(a)), (int)typecode, v); - Py_DECREF(v); - return s; -} - -static PyObject* -array_subscr(arrayobject* self, PyObject* item) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i==-1 && PyErr_Occurred()) { - return NULL; - } - if (i < 0) - i += Py_SIZE(self); - return array_item(self, i); - } - else if (PySlice_Check(item)) { + const struct mformatdescr mf_descr = + mformat_descriptors[mformat_code]; + Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size; + const unsigned char *memstr = + (unsigned char *)PyBytes_AS_STRING(items); + const struct arraydescr *descr; + + /* If possible, try to pack array's items using a data type + * that fits better. This may result in an array with narrower + * or wider elements. + * + * For example, if a 32-bit machine pickles an L-code array of + * unsigned longs, then the array will be unpickled by 64-bit + * machine as an I-code array of unsigned ints. + * + * XXX: Is it possible to write a unit test for this? + */ + for (descr = descriptors; descr->typecode != '\0'; descr++) { + if (descr->is_integer_type && + (size_t)descr->itemsize == mf_descr.size && + descr->is_signed == mf_descr.is_signed) + typecode = descr->typecode; + } + + converted_items = PyList_New(itemcount); + if (converted_items == NULL) + return NULL; + for (i = 0; i < itemcount; i++) { + PyObject *pylong; + + pylong = _PyLong_FromByteArray( + &memstr[i * mf_descr.size], + mf_descr.size, + !mf_descr.is_big_endian, + mf_descr.is_signed); + if (pylong == NULL) { + Py_DECREF(converted_items); + return NULL; + } + PyList_SET_ITEM(converted_items, i, pylong); + } + break; + } + case UNKNOWN_FORMAT: + /* Impossible, but needed to shut up GCC about the unhandled + * enumeration value. + */ + default: + PyErr_BadArgument(); + return NULL; + } + + result = make_array(arraytype, (char)typecode, converted_items); + Py_DECREF(converted_items); + return result; +} + +/*[clinic input] +array.array.__reduce_ex__ + + value: object + / + +Return state information for pickling. +[clinic start generated code]*/ + +static PyObject * +array_array___reduce_ex__(arrayobject *self, PyObject *value) +/*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/ +{ + PyObject *dict; + PyObject *result; + PyObject *array_str; + int typecode = self->ob_descr->typecode; + int mformat_code; + static PyObject *array_reconstructor = NULL; + long protocol; + _Py_IDENTIFIER(_array_reconstructor); + _Py_IDENTIFIER(__dict__); + + if (array_reconstructor == NULL) { + PyObject *array_module = PyImport_ImportModule("array"); + if (array_module == NULL) + return NULL; + array_reconstructor = _PyObject_GetAttrId( + array_module, + &PyId__array_reconstructor); + Py_DECREF(array_module); + if (array_reconstructor == NULL) + return NULL; + } + + if (!PyLong_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__reduce_ex__ argument should be an integer"); + return NULL; + } + protocol = PyLong_AsLong(value); + if (protocol == -1 && PyErr_Occurred()) + return NULL; + + if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) { + return NULL; + } + if (dict == NULL) { + dict = Py_None; + Py_INCREF(dict); + } + + mformat_code = typecode_to_mformat_code(typecode); + if (mformat_code == UNKNOWN_FORMAT || protocol < 3) { + /* Convert the array to a list if we got something weird + * (e.g., non-IEEE floats), or we are pickling the array using + * a Python 2.x compatible protocol. + * + * It is necessary to use a list representation for Python 2.x + * compatible pickle protocol, since Python 2's str objects + * are unpickled as unicode by Python 3. Thus it is impossible + * to make arrays unpicklable by Python 3 by using their memory + * representation, unless we resort to ugly hacks such as + * coercing unicode objects to bytes in array_reconstructor. + */ + PyObject *list; + list = array_array_tolist_impl(self); + if (list == NULL) { + Py_DECREF(dict); + return NULL; + } + result = Py_BuildValue( + "O(CO)O", Py_TYPE(self), typecode, list, dict); + Py_DECREF(list); + Py_DECREF(dict); + return result; + } + + array_str = array_array_tobytes_impl(self); + if (array_str == NULL) { + Py_DECREF(dict); + return NULL; + } + result = Py_BuildValue( + "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode, + mformat_code, array_str, dict); + Py_DECREF(dict); + return result; +} + +static PyObject * +array_get_typecode(arrayobject *a, void *closure) +{ + char typecode = a->ob_descr->typecode; + return PyUnicode_FromOrdinal(typecode); +} + +static PyObject * +array_get_itemsize(arrayobject *a, void *closure) +{ + return PyLong_FromLong((long)a->ob_descr->itemsize); +} + +static PyGetSetDef array_getsets [] = { + {"typecode", (getter) array_get_typecode, NULL, + "the typecode character used to create the array"}, + {"itemsize", (getter) array_get_itemsize, NULL, + "the size, in bytes, of one array item"}, + {NULL} +}; + +static PyMethodDef array_methods[] = { + ARRAY_ARRAY_APPEND_METHODDEF + ARRAY_ARRAY_BUFFER_INFO_METHODDEF + ARRAY_ARRAY_BYTESWAP_METHODDEF + ARRAY_ARRAY___COPY___METHODDEF + ARRAY_ARRAY_COUNT_METHODDEF + ARRAY_ARRAY___DEEPCOPY___METHODDEF + ARRAY_ARRAY_EXTEND_METHODDEF + ARRAY_ARRAY_FROMFILE_METHODDEF + ARRAY_ARRAY_FROMLIST_METHODDEF + ARRAY_ARRAY_FROMBYTES_METHODDEF + ARRAY_ARRAY_FROMUNICODE_METHODDEF + ARRAY_ARRAY_INDEX_METHODDEF + ARRAY_ARRAY_INSERT_METHODDEF + ARRAY_ARRAY_POP_METHODDEF + ARRAY_ARRAY___REDUCE_EX___METHODDEF + ARRAY_ARRAY_REMOVE_METHODDEF + ARRAY_ARRAY_REVERSE_METHODDEF + ARRAY_ARRAY_TOFILE_METHODDEF + ARRAY_ARRAY_TOLIST_METHODDEF + ARRAY_ARRAY_TOBYTES_METHODDEF + ARRAY_ARRAY_TOUNICODE_METHODDEF + ARRAY_ARRAY___SIZEOF___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +array_repr(arrayobject *a) +{ + char typecode; + PyObject *s, *v = NULL; + Py_ssize_t len; + + len = Py_SIZE(a); + typecode = a->ob_descr->typecode; + if (len == 0) { + return PyUnicode_FromFormat("%s('%c')", + _PyType_Name(Py_TYPE(a)), (int)typecode); + } + if (typecode == 'u') { + v = array_array_tounicode_impl(a); + } else { + v = array_array_tolist_impl(a); + } + if (v == NULL) + return NULL; + + s = PyUnicode_FromFormat("%s('%c', %R)", + _PyType_Name(Py_TYPE(a)), (int)typecode, v); + Py_DECREF(v); + return s; +} + +static PyObject* +array_subscr(arrayobject* self, PyObject* item) +{ + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i==-1 && PyErr_Occurred()) { + return NULL; + } + if (i < 0) + i += Py_SIZE(self); + return array_item(self, i); + } + else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength, i; size_t cur; - PyObject* result; - arrayobject* ar; - int itemsize = self->ob_descr->itemsize; - - if (PySlice_Unpack(item, &start, &stop, &step) < 0) { - return NULL; - } - slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, - step); - - if (slicelength <= 0) { - return newarrayobject(&Arraytype, 0, self->ob_descr); - } - else if (step == 1) { - PyObject *result = newarrayobject(&Arraytype, - slicelength, self->ob_descr); - if (result == NULL) - return NULL; - memcpy(((arrayobject *)result)->ob_item, - self->ob_item + start * itemsize, - slicelength * itemsize); - return result; - } - else { - result = newarrayobject(&Arraytype, slicelength, self->ob_descr); - if (!result) return NULL; - - ar = (arrayobject*)result; - - for (cur = start, i = 0; i < slicelength; - cur += step, i++) { - memcpy(ar->ob_item + i*itemsize, - self->ob_item + cur*itemsize, - itemsize); - } - - return result; - } - } - else { - PyErr_SetString(PyExc_TypeError, - "array indices must be integers"); - return NULL; - } -} - -static int -array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) -{ - Py_ssize_t start, stop, step, slicelength, needed; - arrayobject* other; - int itemsize; - - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += Py_SIZE(self); - if (i < 0 || i >= Py_SIZE(self)) { - PyErr_SetString(PyExc_IndexError, - "array assignment index out of range"); - return -1; - } - if (value == NULL) { - /* Fall through to slice assignment */ - start = i; - stop = i + 1; - step = 1; - slicelength = 1; - } - else - return (*self->ob_descr->setitem)(self, i, value); - } - else if (PySlice_Check(item)) { - if (PySlice_Unpack(item, &start, &stop, &step) < 0) { - return -1; - } - slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, - step); - } - else { - PyErr_SetString(PyExc_TypeError, - "array indices must be integers"); - return -1; - } - if (value == NULL) { - other = NULL; - needed = 0; - } - else if (array_Check(value)) { - other = (arrayobject *)value; - needed = Py_SIZE(other); - if (self == other) { - /* Special case "self[i:j] = self" -- copy self first */ - int ret; - value = array_slice(other, 0, needed); - if (value == NULL) - return -1; - ret = array_ass_subscr(self, item, value); - Py_DECREF(value); - return ret; - } - if (other->ob_descr != self->ob_descr) { - PyErr_BadArgument(); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, - "can only assign array (not \"%.200s\") to array slice", - Py_TYPE(value)->tp_name); - return -1; - } - itemsize = self->ob_descr->itemsize; - /* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */ - if ((step > 0 && stop < start) || - (step < 0 && stop > start)) - stop = start; - - /* Issue #4509: If the array has exported buffers and the slice - assignment would change the size of the array, fail early to make - sure we don't modify it. */ - if ((needed == 0 || slicelength != needed) && self->ob_exports > 0) { - PyErr_SetString(PyExc_BufferError, - "cannot resize an array that is exporting buffers"); - return -1; - } - - if (step == 1) { - if (slicelength > needed) { - memmove(self->ob_item + (start + needed) * itemsize, - self->ob_item + stop * itemsize, - (Py_SIZE(self) - stop) * itemsize); - if (array_resize(self, Py_SIZE(self) + - needed - slicelength) < 0) - return -1; - } - else if (slicelength < needed) { - if (array_resize(self, Py_SIZE(self) + - needed - slicelength) < 0) - return -1; - memmove(self->ob_item + (start + needed) * itemsize, - self->ob_item + stop * itemsize, - (Py_SIZE(self) - start - needed) * itemsize); - } - if (needed > 0) - memcpy(self->ob_item + start * itemsize, - other->ob_item, needed * itemsize); - return 0; - } - else if (needed == 0) { - /* Delete slice */ - size_t cur; - Py_ssize_t i; - - if (step < 0) { - stop = start + 1; - start = stop + step * (slicelength - 1) - 1; - step = -step; - } - for (cur = start, i = 0; i < slicelength; - cur += step, i++) { - Py_ssize_t lim = step - 1; - - if (cur + step >= (size_t)Py_SIZE(self)) - lim = Py_SIZE(self) - cur - 1; - memmove(self->ob_item + (cur - i) * itemsize, - self->ob_item + (cur + 1) * itemsize, - lim * itemsize); - } - cur = start + (size_t)slicelength * step; - if (cur < (size_t)Py_SIZE(self)) { - memmove(self->ob_item + (cur-slicelength) * itemsize, - self->ob_item + cur * itemsize, - (Py_SIZE(self) - cur) * itemsize); - } - if (array_resize(self, Py_SIZE(self) - slicelength) < 0) - return -1; - return 0; - } - else { + PyObject* result; + arrayobject* ar; + int itemsize = self->ob_descr->itemsize; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return NULL; + } + slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, + step); + + if (slicelength <= 0) { + return newarrayobject(&Arraytype, 0, self->ob_descr); + } + else if (step == 1) { + PyObject *result = newarrayobject(&Arraytype, + slicelength, self->ob_descr); + if (result == NULL) + return NULL; + memcpy(((arrayobject *)result)->ob_item, + self->ob_item + start * itemsize, + slicelength * itemsize); + return result; + } + else { + result = newarrayobject(&Arraytype, slicelength, self->ob_descr); + if (!result) return NULL; + + ar = (arrayobject*)result; + + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + memcpy(ar->ob_item + i*itemsize, + self->ob_item + cur*itemsize, + itemsize); + } + + return result; + } + } + else { + PyErr_SetString(PyExc_TypeError, + "array indices must be integers"); + return NULL; + } +} + +static int +array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) +{ + Py_ssize_t start, stop, step, slicelength, needed; + arrayobject* other; + int itemsize; + + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += Py_SIZE(self); + if (i < 0 || i >= Py_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, + "array assignment index out of range"); + return -1; + } + if (value == NULL) { + /* Fall through to slice assignment */ + start = i; + stop = i + 1; + step = 1; + slicelength = 1; + } + else + return (*self->ob_descr->setitem)(self, i, value); + } + else if (PySlice_Check(item)) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return -1; + } + slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, + step); + } + else { + PyErr_SetString(PyExc_TypeError, + "array indices must be integers"); + return -1; + } + if (value == NULL) { + other = NULL; + needed = 0; + } + else if (array_Check(value)) { + other = (arrayobject *)value; + needed = Py_SIZE(other); + if (self == other) { + /* Special case "self[i:j] = self" -- copy self first */ + int ret; + value = array_slice(other, 0, needed); + if (value == NULL) + return -1; + ret = array_ass_subscr(self, item, value); + Py_DECREF(value); + return ret; + } + if (other->ob_descr != self->ob_descr) { + PyErr_BadArgument(); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "can only assign array (not \"%.200s\") to array slice", + Py_TYPE(value)->tp_name); + return -1; + } + itemsize = self->ob_descr->itemsize; + /* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */ + if ((step > 0 && stop < start) || + (step < 0 && stop > start)) + stop = start; + + /* Issue #4509: If the array has exported buffers and the slice + assignment would change the size of the array, fail early to make + sure we don't modify it. */ + if ((needed == 0 || slicelength != needed) && self->ob_exports > 0) { + PyErr_SetString(PyExc_BufferError, + "cannot resize an array that is exporting buffers"); + return -1; + } + + if (step == 1) { + if (slicelength > needed) { + memmove(self->ob_item + (start + needed) * itemsize, + self->ob_item + stop * itemsize, + (Py_SIZE(self) - stop) * itemsize); + if (array_resize(self, Py_SIZE(self) + + needed - slicelength) < 0) + return -1; + } + else if (slicelength < needed) { + if (array_resize(self, Py_SIZE(self) + + needed - slicelength) < 0) + return -1; + memmove(self->ob_item + (start + needed) * itemsize, + self->ob_item + stop * itemsize, + (Py_SIZE(self) - start - needed) * itemsize); + } + if (needed > 0) + memcpy(self->ob_item + start * itemsize, + other->ob_item, needed * itemsize); + return 0; + } + else if (needed == 0) { + /* Delete slice */ + size_t cur; + Py_ssize_t i; + + if (step < 0) { + stop = start + 1; + start = stop + step * (slicelength - 1) - 1; + step = -step; + } + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + Py_ssize_t lim = step - 1; + + if (cur + step >= (size_t)Py_SIZE(self)) + lim = Py_SIZE(self) - cur - 1; + memmove(self->ob_item + (cur - i) * itemsize, + self->ob_item + (cur + 1) * itemsize, + lim * itemsize); + } + cur = start + (size_t)slicelength * step; + if (cur < (size_t)Py_SIZE(self)) { + memmove(self->ob_item + (cur-slicelength) * itemsize, + self->ob_item + cur * itemsize, + (Py_SIZE(self) - cur) * itemsize); + } + if (array_resize(self, Py_SIZE(self) - slicelength) < 0) + return -1; + return 0; + } + else { size_t cur; Py_ssize_t i; - - if (needed != slicelength) { - PyErr_Format(PyExc_ValueError, - "attempt to assign array of size %zd " - "to extended slice of size %zd", - needed, slicelength); - return -1; - } - for (cur = start, i = 0; i < slicelength; - cur += step, i++) { - memcpy(self->ob_item + cur * itemsize, - other->ob_item + i * itemsize, - itemsize); - } - return 0; - } -} - -static PyMappingMethods array_as_mapping = { - (lenfunc)array_length, - (binaryfunc)array_subscr, - (objobjargproc)array_ass_subscr -}; - -static const void *emptybuf = ""; - - -static int -array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) -{ - if (view == NULL) { - PyErr_SetString(PyExc_BufferError, - "array_buffer_getbuf: view==NULL argument is obsolete"); - return -1; - } - - view->buf = (void *)self->ob_item; - view->obj = (PyObject*)self; - Py_INCREF(self); - if (view->buf == NULL) - view->buf = (void *)emptybuf; - view->len = (Py_SIZE(self)) * self->ob_descr->itemsize; - view->readonly = 0; - view->ndim = 1; - view->itemsize = self->ob_descr->itemsize; - view->suboffsets = NULL; - view->shape = NULL; - if ((flags & PyBUF_ND)==PyBUF_ND) { - view->shape = &((Py_SIZE(self))); - } - view->strides = NULL; - if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES) - view->strides = &(view->itemsize); - view->format = NULL; - view->internal = NULL; - if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { - view->format = (char *)self->ob_descr->formats; -#ifdef Py_UNICODE_WIDE - if (self->ob_descr->typecode == 'u') { - view->format = "w"; - } -#endif - } - - self->ob_exports++; - return 0; -} - -static void -array_buffer_relbuf(arrayobject *self, Py_buffer *view) -{ - self->ob_exports--; -} - -static PySequenceMethods array_as_sequence = { - (lenfunc)array_length, /*sq_length*/ - (binaryfunc)array_concat, /*sq_concat*/ - (ssizeargfunc)array_repeat, /*sq_repeat*/ - (ssizeargfunc)array_item, /*sq_item*/ - 0, /*sq_slice*/ - (ssizeobjargproc)array_ass_item, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - (objobjproc)array_contains, /*sq_contains*/ - (binaryfunc)array_inplace_concat, /*sq_inplace_concat*/ - (ssizeargfunc)array_inplace_repeat /*sq_inplace_repeat*/ -}; - -static PyBufferProcs array_as_buffer = { - (getbufferproc)array_buffer_getbuf, - (releasebufferproc)array_buffer_relbuf -}; - -static PyObject * -array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - int c; - PyObject *initial = NULL, *it = NULL; - const struct arraydescr *descr; - - if (type == &Arraytype && !_PyArg_NoKeywords("array.array", kwds)) - return NULL; - - if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial)) - return NULL; - + + if (needed != slicelength) { + PyErr_Format(PyExc_ValueError, + "attempt to assign array of size %zd " + "to extended slice of size %zd", + needed, slicelength); + return -1; + } + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + memcpy(self->ob_item + cur * itemsize, + other->ob_item + i * itemsize, + itemsize); + } + return 0; + } +} + +static PyMappingMethods array_as_mapping = { + (lenfunc)array_length, + (binaryfunc)array_subscr, + (objobjargproc)array_ass_subscr +}; + +static const void *emptybuf = ""; + + +static int +array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) +{ + if (view == NULL) { + PyErr_SetString(PyExc_BufferError, + "array_buffer_getbuf: view==NULL argument is obsolete"); + return -1; + } + + view->buf = (void *)self->ob_item; + view->obj = (PyObject*)self; + Py_INCREF(self); + if (view->buf == NULL) + view->buf = (void *)emptybuf; + view->len = (Py_SIZE(self)) * self->ob_descr->itemsize; + view->readonly = 0; + view->ndim = 1; + view->itemsize = self->ob_descr->itemsize; + view->suboffsets = NULL; + view->shape = NULL; + if ((flags & PyBUF_ND)==PyBUF_ND) { + view->shape = &((Py_SIZE(self))); + } + view->strides = NULL; + if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES) + view->strides = &(view->itemsize); + view->format = NULL; + view->internal = NULL; + if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { + view->format = (char *)self->ob_descr->formats; +#ifdef Py_UNICODE_WIDE + if (self->ob_descr->typecode == 'u') { + view->format = "w"; + } +#endif + } + + self->ob_exports++; + return 0; +} + +static void +array_buffer_relbuf(arrayobject *self, Py_buffer *view) +{ + self->ob_exports--; +} + +static PySequenceMethods array_as_sequence = { + (lenfunc)array_length, /*sq_length*/ + (binaryfunc)array_concat, /*sq_concat*/ + (ssizeargfunc)array_repeat, /*sq_repeat*/ + (ssizeargfunc)array_item, /*sq_item*/ + 0, /*sq_slice*/ + (ssizeobjargproc)array_ass_item, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + (objobjproc)array_contains, /*sq_contains*/ + (binaryfunc)array_inplace_concat, /*sq_inplace_concat*/ + (ssizeargfunc)array_inplace_repeat /*sq_inplace_repeat*/ +}; + +static PyBufferProcs array_as_buffer = { + (getbufferproc)array_buffer_getbuf, + (releasebufferproc)array_buffer_relbuf +}; + +static PyObject * +array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + int c; + PyObject *initial = NULL, *it = NULL; + const struct arraydescr *descr; + + if (type == &Arraytype && !_PyArg_NoKeywords("array.array", kwds)) + return NULL; + + if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial)) + return NULL; + if (PySys_Audit("array.__new__", "CO", c, initial ? initial : Py_None) < 0) { return NULL; } - if (initial && c != 'u') { - if (PyUnicode_Check(initial)) { - PyErr_Format(PyExc_TypeError, "cannot use a str to initialize " - "an array with typecode '%c'", c); - return NULL; - } - else if (array_Check(initial) && - ((arrayobject*)initial)->ob_descr->typecode == 'u') { - PyErr_Format(PyExc_TypeError, "cannot use a unicode array to " - "initialize an array with typecode '%c'", c); - return NULL; - } - } - - if (!(initial == NULL || PyList_Check(initial) - || PyByteArray_Check(initial) - || PyBytes_Check(initial) - || PyTuple_Check(initial) - || ((c=='u') && PyUnicode_Check(initial)) - || (array_Check(initial) - && c == ((arrayobject*)initial)->ob_descr->typecode))) { - it = PyObject_GetIter(initial); - if (it == NULL) - return NULL; - /* We set initial to NULL so that the subsequent code - will create an empty array of the appropriate type - and afterwards we can use array_iter_extend to populate - the array. - */ - initial = NULL; - } - for (descr = descriptors; descr->typecode != '\0'; descr++) { - if (descr->typecode == c) { - PyObject *a; - Py_ssize_t len; - - if (initial == NULL) - len = 0; - else if (PyList_Check(initial)) - len = PyList_GET_SIZE(initial); - else if (PyTuple_Check(initial) || array_Check(initial)) - len = Py_SIZE(initial); - else - len = 0; - - a = newarrayobject(type, len, descr); - if (a == NULL) - return NULL; - - if (len > 0 && !array_Check(initial)) { - Py_ssize_t i; - for (i = 0; i < len; i++) { - PyObject *v = - PySequence_GetItem(initial, i); - if (v == NULL) { - Py_DECREF(a); - return NULL; - } - if (setarrayitem(a, i, v) != 0) { - Py_DECREF(v); - Py_DECREF(a); - return NULL; - } - Py_DECREF(v); - } - } - else if (initial != NULL && (PyByteArray_Check(initial) || - PyBytes_Check(initial))) { - PyObject *v; - v = array_array_frombytes((arrayobject *)a, - initial); - if (v == NULL) { - Py_DECREF(a); - return NULL; - } - Py_DECREF(v); - } - else if (initial != NULL && PyUnicode_Check(initial)) { - Py_ssize_t n; + if (initial && c != 'u') { + if (PyUnicode_Check(initial)) { + PyErr_Format(PyExc_TypeError, "cannot use a str to initialize " + "an array with typecode '%c'", c); + return NULL; + } + else if (array_Check(initial) && + ((arrayobject*)initial)->ob_descr->typecode == 'u') { + PyErr_Format(PyExc_TypeError, "cannot use a unicode array to " + "initialize an array with typecode '%c'", c); + return NULL; + } + } + + if (!(initial == NULL || PyList_Check(initial) + || PyByteArray_Check(initial) + || PyBytes_Check(initial) + || PyTuple_Check(initial) + || ((c=='u') && PyUnicode_Check(initial)) + || (array_Check(initial) + && c == ((arrayobject*)initial)->ob_descr->typecode))) { + it = PyObject_GetIter(initial); + if (it == NULL) + return NULL; + /* We set initial to NULL so that the subsequent code + will create an empty array of the appropriate type + and afterwards we can use array_iter_extend to populate + the array. + */ + initial = NULL; + } + for (descr = descriptors; descr->typecode != '\0'; descr++) { + if (descr->typecode == c) { + PyObject *a; + Py_ssize_t len; + + if (initial == NULL) + len = 0; + else if (PyList_Check(initial)) + len = PyList_GET_SIZE(initial); + else if (PyTuple_Check(initial) || array_Check(initial)) + len = Py_SIZE(initial); + else + len = 0; + + a = newarrayobject(type, len, descr); + if (a == NULL) + return NULL; + + if (len > 0 && !array_Check(initial)) { + Py_ssize_t i; + for (i = 0; i < len; i++) { + PyObject *v = + PySequence_GetItem(initial, i); + if (v == NULL) { + Py_DECREF(a); + return NULL; + } + if (setarrayitem(a, i, v) != 0) { + Py_DECREF(v); + Py_DECREF(a); + return NULL; + } + Py_DECREF(v); + } + } + else if (initial != NULL && (PyByteArray_Check(initial) || + PyBytes_Check(initial))) { + PyObject *v; + v = array_array_frombytes((arrayobject *)a, + initial); + if (v == NULL) { + Py_DECREF(a); + return NULL; + } + Py_DECREF(v); + } + else if (initial != NULL && PyUnicode_Check(initial)) { + Py_ssize_t n; wchar_t *ustr = PyUnicode_AsWideCharString(initial, &n); - if (ustr == NULL) { - Py_DECREF(a); - return NULL; - } - - if (n > 0) { - arrayobject *self = (arrayobject *)a; + if (ustr == NULL) { + Py_DECREF(a); + return NULL; + } + + if (n > 0) { + arrayobject *self = (arrayobject *)a; // self->ob_item may be NULL but it is safe. PyMem_Free(self->ob_item); self->ob_item = (char *)ustr; Py_SET_SIZE(self, n); self->allocated = n; - } - } - else if (initial != NULL && array_Check(initial) && len > 0) { - arrayobject *self = (arrayobject *)a; - arrayobject *other = (arrayobject *)initial; - memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize); - } - if (it != NULL) { - if (array_iter_extend((arrayobject *)a, it) == -1) { - Py_DECREF(it); - Py_DECREF(a); - return NULL; - } - Py_DECREF(it); - } - return a; - } - } - PyErr_SetString(PyExc_ValueError, - "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)"); - return NULL; -} - - -PyDoc_STRVAR(module_doc, -"This module defines an object type which can efficiently represent\n\ -an array of basic values: characters, integers, floating point\n\ -numbers. Arrays are sequence types and behave very much like lists,\n\ -except that the type of objects stored in them is constrained.\n"); - -PyDoc_STRVAR(arraytype_doc, -"array(typecode [, initializer]) -> array\n\ -\n\ -Return a new array whose items are restricted by typecode, and\n\ -initialized from the optional initializer value, which must be a list,\n\ -string or iterable over elements of the appropriate type.\n\ -\n\ -Arrays represent basic values and behave very much like lists, except\n\ -the type of objects stored in them is constrained. The type is specified\n\ -at object creation time by using a type code, which is a single character.\n\ -The following type codes are defined:\n\ -\n\ + } + } + else if (initial != NULL && array_Check(initial) && len > 0) { + arrayobject *self = (arrayobject *)a; + arrayobject *other = (arrayobject *)initial; + memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize); + } + if (it != NULL) { + if (array_iter_extend((arrayobject *)a, it) == -1) { + Py_DECREF(it); + Py_DECREF(a); + return NULL; + } + Py_DECREF(it); + } + return a; + } + } + PyErr_SetString(PyExc_ValueError, + "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)"); + return NULL; +} + + +PyDoc_STRVAR(module_doc, +"This module defines an object type which can efficiently represent\n\ +an array of basic values: characters, integers, floating point\n\ +numbers. Arrays are sequence types and behave very much like lists,\n\ +except that the type of objects stored in them is constrained.\n"); + +PyDoc_STRVAR(arraytype_doc, +"array(typecode [, initializer]) -> array\n\ +\n\ +Return a new array whose items are restricted by typecode, and\n\ +initialized from the optional initializer value, which must be a list,\n\ +string or iterable over elements of the appropriate type.\n\ +\n\ +Arrays represent basic values and behave very much like lists, except\n\ +the type of objects stored in them is constrained. The type is specified\n\ +at object creation time by using a type code, which is a single character.\n\ +The following type codes are defined:\n\ +\n\ Type code C Type Minimum size in bytes\n\ 'b' signed integer 1\n\ 'B' unsigned integer 1\n\ @@ -2753,293 +2753,293 @@ The following type codes are defined:\n\ 'Q' unsigned integer 8 (see note)\n\ 'f' floating point 4\n\ 'd' floating point 8\n\ -\n\ +\n\ NOTE: The 'u' typecode corresponds to Python's unicode character. On\n\ -narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\ -\n\ +narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\ +\n\ NOTE: The 'q' and 'Q' type codes are only available if the platform\n\ C compiler used to build Python supports 'long long', or, on Windows,\n\ -'__int64'.\n\ -\n\ -Methods:\n\ -\n\ -append() -- append a new item to the end of the array\n\ -buffer_info() -- return information giving the current memory info\n\ -byteswap() -- byteswap all the items of the array\n\ -count() -- return number of occurrences of an object\n\ -extend() -- extend array by appending multiple elements from an iterable\n\ -fromfile() -- read items from a file object\n\ -fromlist() -- append items from the list\n\ -frombytes() -- append items from the string\n\ -index() -- return index of first occurrence of an object\n\ -insert() -- insert a new item into the array at a provided position\n\ -pop() -- remove and return item (default last)\n\ -remove() -- remove first occurrence of an object\n\ -reverse() -- reverse the order of the items in the array\n\ -tofile() -- write all items to a file object\n\ -tolist() -- return the array converted to an ordinary list\n\ -tobytes() -- return the array converted to a string\n\ -\n\ -Attributes:\n\ -\n\ -typecode -- the typecode character used to create the array\n\ -itemsize -- the length in bytes of one array item\n\ -"); - -static PyObject *array_iter(arrayobject *ao); - -static PyTypeObject Arraytype = { - PyVarObject_HEAD_INIT(NULL, 0) - "array.array", - sizeof(arrayobject), - 0, - (destructor)array_dealloc, /* tp_dealloc */ +'__int64'.\n\ +\n\ +Methods:\n\ +\n\ +append() -- append a new item to the end of the array\n\ +buffer_info() -- return information giving the current memory info\n\ +byteswap() -- byteswap all the items of the array\n\ +count() -- return number of occurrences of an object\n\ +extend() -- extend array by appending multiple elements from an iterable\n\ +fromfile() -- read items from a file object\n\ +fromlist() -- append items from the list\n\ +frombytes() -- append items from the string\n\ +index() -- return index of first occurrence of an object\n\ +insert() -- insert a new item into the array at a provided position\n\ +pop() -- remove and return item (default last)\n\ +remove() -- remove first occurrence of an object\n\ +reverse() -- reverse the order of the items in the array\n\ +tofile() -- write all items to a file object\n\ +tolist() -- return the array converted to an ordinary list\n\ +tobytes() -- return the array converted to a string\n\ +\n\ +Attributes:\n\ +\n\ +typecode -- the typecode character used to create the array\n\ +itemsize -- the length in bytes of one array item\n\ +"); + +static PyObject *array_iter(arrayobject *ao); + +static PyTypeObject Arraytype = { + PyVarObject_HEAD_INIT(NULL, 0) + "array.array", + sizeof(arrayobject), + 0, + (destructor)array_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)array_repr, /* tp_repr */ - 0, /* tp_as_number*/ - &array_as_sequence, /* tp_as_sequence*/ - &array_as_mapping, /* tp_as_mapping*/ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - &array_as_buffer, /* tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - arraytype_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - array_richcompare, /* tp_richcompare */ - offsetof(arrayobject, weakreflist), /* tp_weaklistoffset */ - (getiterfunc)array_iter, /* tp_iter */ - 0, /* tp_iternext */ - array_methods, /* tp_methods */ - 0, /* tp_members */ - array_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - array_new, /* tp_new */ - PyObject_Del, /* tp_free */ -}; - - -/*********************** Array Iterator **************************/ - -/*[clinic input] -class array.arrayiterator "arrayiterobject *" "&PyArrayIter_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5aefd2d74d8c8e30]*/ - -static PyObject * -array_iter(arrayobject *ao) -{ - arrayiterobject *it; - - if (!array_Check(ao)) { - PyErr_BadInternalCall(); - return NULL; - } - - it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type); - if (it == NULL) - return NULL; - - Py_INCREF(ao); - it->ao = ao; - it->index = 0; - it->getitem = ao->ob_descr->getitem; - PyObject_GC_Track(it); - return (PyObject *)it; -} - -static PyObject * -arrayiter_next(arrayiterobject *it) -{ - arrayobject *ao; - - assert(it != NULL); - assert(PyArrayIter_Check(it)); - ao = it->ao; - if (ao == NULL) { - return NULL; - } - assert(array_Check(ao)); - if (it->index < Py_SIZE(ao)) { - return (*it->getitem)(ao, it->index++); - } - it->ao = NULL; - Py_DECREF(ao); - return NULL; -} - -static void -arrayiter_dealloc(arrayiterobject *it) -{ - PyObject_GC_UnTrack(it); - Py_XDECREF(it->ao); - PyObject_GC_Del(it); -} - -static int -arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg) -{ - Py_VISIT(it->ao); - return 0; -} - -/*[clinic input] -array.arrayiterator.__reduce__ - -Return state information for pickling. -[clinic start generated code]*/ - -static PyObject * -array_arrayiterator___reduce___impl(arrayiterobject *self) -/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ -{ + (reprfunc)array_repr, /* tp_repr */ + 0, /* tp_as_number*/ + &array_as_sequence, /* tp_as_sequence*/ + &array_as_mapping, /* tp_as_mapping*/ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + &array_as_buffer, /* tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + arraytype_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + array_richcompare, /* tp_richcompare */ + offsetof(arrayobject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)array_iter, /* tp_iter */ + 0, /* tp_iternext */ + array_methods, /* tp_methods */ + 0, /* tp_members */ + array_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + array_new, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + + +/*********************** Array Iterator **************************/ + +/*[clinic input] +class array.arrayiterator "arrayiterobject *" "&PyArrayIter_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5aefd2d74d8c8e30]*/ + +static PyObject * +array_iter(arrayobject *ao) +{ + arrayiterobject *it; + + if (!array_Check(ao)) { + PyErr_BadInternalCall(); + return NULL; + } + + it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type); + if (it == NULL) + return NULL; + + Py_INCREF(ao); + it->ao = ao; + it->index = 0; + it->getitem = ao->ob_descr->getitem; + PyObject_GC_Track(it); + return (PyObject *)it; +} + +static PyObject * +arrayiter_next(arrayiterobject *it) +{ + arrayobject *ao; + + assert(it != NULL); + assert(PyArrayIter_Check(it)); + ao = it->ao; + if (ao == NULL) { + return NULL; + } + assert(array_Check(ao)); + if (it->index < Py_SIZE(ao)) { + return (*it->getitem)(ao, it->index++); + } + it->ao = NULL; + Py_DECREF(ao); + return NULL; +} + +static void +arrayiter_dealloc(arrayiterobject *it) +{ + PyObject_GC_UnTrack(it); + Py_XDECREF(it->ao); + PyObject_GC_Del(it); +} + +static int +arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg) +{ + Py_VISIT(it->ao); + return 0; +} + +/*[clinic input] +array.arrayiterator.__reduce__ + +Return state information for pickling. +[clinic start generated code]*/ + +static PyObject * +array_arrayiterator___reduce___impl(arrayiterobject *self) +/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ +{ _Py_IDENTIFIER(iter); PyObject *func = _PyEval_GetBuiltinId(&PyId_iter); - if (self->ao == NULL) { - return Py_BuildValue("N(())", func); - } - return Py_BuildValue("N(O)n", func, self->ao, self->index); -} - -/*[clinic input] -array.arrayiterator.__setstate__ - - state: object - / - -Set state information for unpickling. -[clinic start generated code]*/ - -static PyObject * -array_arrayiterator___setstate__(arrayiterobject *self, PyObject *state) -/*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/ -{ - Py_ssize_t index = PyLong_AsSsize_t(state); - if (index == -1 && PyErr_Occurred()) - return NULL; - if (index < 0) - index = 0; - else if (index > Py_SIZE(self->ao)) - index = Py_SIZE(self->ao); /* iterator exhausted */ - self->index = index; - Py_RETURN_NONE; -} - -static PyMethodDef arrayiter_methods[] = { - ARRAY_ARRAYITERATOR___REDUCE___METHODDEF - ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject PyArrayIter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "arrayiterator", /* tp_name */ - sizeof(arrayiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)arrayiter_dealloc, /* tp_dealloc */ + if (self->ao == NULL) { + return Py_BuildValue("N(())", func); + } + return Py_BuildValue("N(O)n", func, self->ao, self->index); +} + +/*[clinic input] +array.arrayiterator.__setstate__ + + state: object + / + +Set state information for unpickling. +[clinic start generated code]*/ + +static PyObject * +array_arrayiterator___setstate__(arrayiterobject *self, PyObject *state) +/*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/ +{ + Py_ssize_t index = PyLong_AsSsize_t(state); + if (index == -1 && PyErr_Occurred()) + return NULL; + if (index < 0) + index = 0; + else if (index > Py_SIZE(self->ao)) + index = Py_SIZE(self->ao); /* iterator exhausted */ + self->index = index; + Py_RETURN_NONE; +} + +static PyMethodDef arrayiter_methods[] = { + ARRAY_ARRAYITERATOR___REDUCE___METHODDEF + ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject PyArrayIter_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "arrayiterator", /* tp_name */ + sizeof(arrayiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)arrayiter_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - 0, /* tp_doc */ - (traverseproc)arrayiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)arrayiter_next, /* tp_iternext */ - arrayiter_methods, /* tp_methods */ -}; - - -/*********************** Install Module **************************/ - -/* No functions in array module. */ -static PyMethodDef a_methods[] = { - ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -static int -array_modexec(PyObject *m) -{ - char buffer[Py_ARRAY_LENGTH(descriptors)], *p; - PyObject *typecodes; - const struct arraydescr *descr; - - if (PyType_Ready(&Arraytype) < 0) - return -1; + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)arrayiter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)arrayiter_next, /* tp_iternext */ + arrayiter_methods, /* tp_methods */ +}; + + +/*********************** Install Module **************************/ + +/* No functions in array module. */ +static PyMethodDef a_methods[] = { + ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + +static int +array_modexec(PyObject *m) +{ + char buffer[Py_ARRAY_LENGTH(descriptors)], *p; + PyObject *typecodes; + const struct arraydescr *descr; + + if (PyType_Ready(&Arraytype) < 0) + return -1; Py_SET_TYPE(&PyArrayIter_Type, &PyType_Type); - - Py_INCREF((PyObject *)&Arraytype); + + Py_INCREF((PyObject *)&Arraytype); if (PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype) < 0) { Py_DECREF((PyObject *)&Arraytype); return -1; } - Py_INCREF((PyObject *)&Arraytype); + Py_INCREF((PyObject *)&Arraytype); if (PyModule_AddObject(m, "array", (PyObject *)&Arraytype) < 0) { Py_DECREF((PyObject *)&Arraytype); return -1; } - - p = buffer; - for (descr = descriptors; descr->typecode != '\0'; descr++) { - *p++ = (char)descr->typecode; - } - typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL); + + p = buffer; + for (descr = descriptors; descr->typecode != '\0'; descr++) { + *p++ = (char)descr->typecode; + } + typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL); if (PyModule_AddObject(m, "typecodes", typecodes) < 0) { Py_XDECREF(typecodes); return -1; } - - return 0; -} - -static PyModuleDef_Slot arrayslots[] = { - {Py_mod_exec, array_modexec}, - {0, NULL} -}; - - -static struct PyModuleDef arraymodule = { - PyModuleDef_HEAD_INIT, - "array", - module_doc, - 0, - a_methods, - arrayslots, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit_array(void) -{ - return PyModuleDef_Init(&arraymodule); -} + + return 0; +} + +static PyModuleDef_Slot arrayslots[] = { + {Py_mod_exec, array_modexec}, + {0, NULL} +}; + + +static struct PyModuleDef arraymodule = { + PyModuleDef_HEAD_INIT, + "array", + module_doc, + 0, + a_methods, + arrayslots, + NULL, + NULL, + NULL +}; + + +PyMODINIT_FUNC +PyInit_array(void) +{ + return PyModuleDef_Init(&arraymodule); +} diff --git a/contrib/tools/python3/src/Modules/atexitmodule.c b/contrib/tools/python3/src/Modules/atexitmodule.c index 8cef64ceb9b..38dfe501158 100644 --- a/contrib/tools/python3/src/Modules/atexitmodule.c +++ b/contrib/tools/python3/src/Modules/atexitmodule.c @@ -1,33 +1,33 @@ -/* - * atexit - allow programmer to define multiple exit functions to be executed - * upon normal program termination. - * - * Translated from atexit.py by Collin Winter. - + Copyright 2007 Python Software Foundation. - */ - -#include "Python.h" - -/* Forward declaration (for atexit_cleanup) */ -static PyObject *atexit_clear(PyObject*, PyObject*); -/* Forward declaration of module object */ -static struct PyModuleDef atexitmodule; - -/* ===================================================================== */ -/* Callback machinery. */ - -typedef struct { - PyObject *func; - PyObject *args; - PyObject *kwargs; -} atexit_callback; - -typedef struct { - atexit_callback **atexit_callbacks; - int ncallbacks; - int callback_len; -} atexitmodule_state; - +/* + * atexit - allow programmer to define multiple exit functions to be executed + * upon normal program termination. + * + * Translated from atexit.py by Collin Winter. + + Copyright 2007 Python Software Foundation. + */ + +#include "Python.h" + +/* Forward declaration (for atexit_cleanup) */ +static PyObject *atexit_clear(PyObject*, PyObject*); +/* Forward declaration of module object */ +static struct PyModuleDef atexitmodule; + +/* ===================================================================== */ +/* Callback machinery. */ + +typedef struct { + PyObject *func; + PyObject *args; + PyObject *kwargs; +} atexit_callback; + +typedef struct { + atexit_callback **atexit_callbacks; + int ncallbacks; + int callback_len; +} atexitmodule_state; + static inline atexitmodule_state* get_atexit_state(PyObject *module) { @@ -35,199 +35,199 @@ get_atexit_state(PyObject *module) assert(state != NULL); return (atexitmodule_state *)state; } - - -static void -atexit_delete_cb(atexitmodule_state *modstate, int i) -{ - atexit_callback *cb; - - cb = modstate->atexit_callbacks[i]; - modstate->atexit_callbacks[i] = NULL; - Py_DECREF(cb->func); - Py_DECREF(cb->args); - Py_XDECREF(cb->kwargs); - PyMem_Free(cb); -} - -/* Clear all callbacks without calling them */ -static void -atexit_cleanup(atexitmodule_state *modstate) -{ - atexit_callback *cb; - int i; - for (i = 0; i < modstate->ncallbacks; i++) { - cb = modstate->atexit_callbacks[i]; - if (cb == NULL) - continue; - - atexit_delete_cb(modstate, i); - } - modstate->ncallbacks = 0; -} - -/* Installed into pylifecycle.c's atexit mechanism */ - -static void -atexit_callfuncs(PyObject *module) -{ - PyObject *exc_type = NULL, *exc_value, *exc_tb, *r; - atexit_callback *cb; - atexitmodule_state *modstate; - int i; - - if (module == NULL) - return; + + +static void +atexit_delete_cb(atexitmodule_state *modstate, int i) +{ + atexit_callback *cb; + + cb = modstate->atexit_callbacks[i]; + modstate->atexit_callbacks[i] = NULL; + Py_DECREF(cb->func); + Py_DECREF(cb->args); + Py_XDECREF(cb->kwargs); + PyMem_Free(cb); +} + +/* Clear all callbacks without calling them */ +static void +atexit_cleanup(atexitmodule_state *modstate) +{ + atexit_callback *cb; + int i; + for (i = 0; i < modstate->ncallbacks; i++) { + cb = modstate->atexit_callbacks[i]; + if (cb == NULL) + continue; + + atexit_delete_cb(modstate, i); + } + modstate->ncallbacks = 0; +} + +/* Installed into pylifecycle.c's atexit mechanism */ + +static void +atexit_callfuncs(PyObject *module) +{ + PyObject *exc_type = NULL, *exc_value, *exc_tb, *r; + atexit_callback *cb; + atexitmodule_state *modstate; + int i; + + if (module == NULL) + return; modstate = get_atexit_state(module); - - if (modstate->ncallbacks == 0) - return; - - - for (i = modstate->ncallbacks - 1; i >= 0; i--) - { - cb = modstate->atexit_callbacks[i]; - if (cb == NULL) - continue; - - r = PyObject_Call(cb->func, cb->args, cb->kwargs); - Py_XDECREF(r); - if (r == NULL) { - /* Maintain the last exception, but don't leak if there are - multiple exceptions. */ - if (exc_type) { - Py_DECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - } - PyErr_Fetch(&exc_type, &exc_value, &exc_tb); - if (!PyErr_GivenExceptionMatches(exc_type, PyExc_SystemExit)) { - PySys_WriteStderr("Error in atexit._run_exitfuncs:\n"); - PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb); - PyErr_Display(exc_type, exc_value, exc_tb); - } - } - } - - atexit_cleanup(modstate); - - if (exc_type) - PyErr_Restore(exc_type, exc_value, exc_tb); -} - -/* ===================================================================== */ -/* Module methods. */ - -PyDoc_STRVAR(atexit_register__doc__, -"register(func, *args, **kwargs) -> func\n\ -\n\ -Register a function to be executed upon normal program termination\n\ -\n\ - func - function to be called at exit\n\ - args - optional arguments to pass to func\n\ - kwargs - optional keyword arguments to pass to func\n\ -\n\ - func is returned to facilitate usage as a decorator."); - -static PyObject * -atexit_register(PyObject *self, PyObject *args, PyObject *kwargs) -{ - atexitmodule_state *modstate; - atexit_callback *new_callback; - PyObject *func = NULL; - + + if (modstate->ncallbacks == 0) + return; + + + for (i = modstate->ncallbacks - 1; i >= 0; i--) + { + cb = modstate->atexit_callbacks[i]; + if (cb == NULL) + continue; + + r = PyObject_Call(cb->func, cb->args, cb->kwargs); + Py_XDECREF(r); + if (r == NULL) { + /* Maintain the last exception, but don't leak if there are + multiple exceptions. */ + if (exc_type) { + Py_DECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + if (!PyErr_GivenExceptionMatches(exc_type, PyExc_SystemExit)) { + PySys_WriteStderr("Error in atexit._run_exitfuncs:\n"); + PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb); + PyErr_Display(exc_type, exc_value, exc_tb); + } + } + } + + atexit_cleanup(modstate); + + if (exc_type) + PyErr_Restore(exc_type, exc_value, exc_tb); +} + +/* ===================================================================== */ +/* Module methods. */ + +PyDoc_STRVAR(atexit_register__doc__, +"register(func, *args, **kwargs) -> func\n\ +\n\ +Register a function to be executed upon normal program termination\n\ +\n\ + func - function to be called at exit\n\ + args - optional arguments to pass to func\n\ + kwargs - optional keyword arguments to pass to func\n\ +\n\ + func is returned to facilitate usage as a decorator."); + +static PyObject * +atexit_register(PyObject *self, PyObject *args, PyObject *kwargs) +{ + atexitmodule_state *modstate; + atexit_callback *new_callback; + PyObject *func = NULL; + modstate = get_atexit_state(self); - - if (modstate->ncallbacks >= modstate->callback_len) { - atexit_callback **r; - modstate->callback_len += 16; - r = (atexit_callback**)PyMem_Realloc(modstate->atexit_callbacks, - sizeof(atexit_callback*) * modstate->callback_len); - if (r == NULL) - return PyErr_NoMemory(); - modstate->atexit_callbacks = r; - } - - if (PyTuple_GET_SIZE(args) == 0) { - PyErr_SetString(PyExc_TypeError, - "register() takes at least 1 argument (0 given)"); - return NULL; - } - - func = PyTuple_GET_ITEM(args, 0); - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_TypeError, - "the first argument must be callable"); - return NULL; - } - - new_callback = PyMem_Malloc(sizeof(atexit_callback)); - if (new_callback == NULL) - return PyErr_NoMemory(); - - new_callback->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); - if (new_callback->args == NULL) { - PyMem_Free(new_callback); - return NULL; - } - new_callback->func = func; - new_callback->kwargs = kwargs; - Py_INCREF(func); - Py_XINCREF(kwargs); - - modstate->atexit_callbacks[modstate->ncallbacks++] = new_callback; - - Py_INCREF(func); - return func; -} - -PyDoc_STRVAR(atexit_run_exitfuncs__doc__, -"_run_exitfuncs() -> None\n\ -\n\ -Run all registered exit functions."); - -static PyObject * -atexit_run_exitfuncs(PyObject *self, PyObject *unused) -{ - atexit_callfuncs(self); - if (PyErr_Occurred()) - return NULL; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(atexit_clear__doc__, -"_clear() -> None\n\ -\n\ -Clear the list of previously registered exit functions."); - -static PyObject * -atexit_clear(PyObject *self, PyObject *unused) -{ + + if (modstate->ncallbacks >= modstate->callback_len) { + atexit_callback **r; + modstate->callback_len += 16; + r = (atexit_callback**)PyMem_Realloc(modstate->atexit_callbacks, + sizeof(atexit_callback*) * modstate->callback_len); + if (r == NULL) + return PyErr_NoMemory(); + modstate->atexit_callbacks = r; + } + + if (PyTuple_GET_SIZE(args) == 0) { + PyErr_SetString(PyExc_TypeError, + "register() takes at least 1 argument (0 given)"); + return NULL; + } + + func = PyTuple_GET_ITEM(args, 0); + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "the first argument must be callable"); + return NULL; + } + + new_callback = PyMem_Malloc(sizeof(atexit_callback)); + if (new_callback == NULL) + return PyErr_NoMemory(); + + new_callback->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + if (new_callback->args == NULL) { + PyMem_Free(new_callback); + return NULL; + } + new_callback->func = func; + new_callback->kwargs = kwargs; + Py_INCREF(func); + Py_XINCREF(kwargs); + + modstate->atexit_callbacks[modstate->ncallbacks++] = new_callback; + + Py_INCREF(func); + return func; +} + +PyDoc_STRVAR(atexit_run_exitfuncs__doc__, +"_run_exitfuncs() -> None\n\ +\n\ +Run all registered exit functions."); + +static PyObject * +atexit_run_exitfuncs(PyObject *self, PyObject *unused) +{ + atexit_callfuncs(self); + if (PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(atexit_clear__doc__, +"_clear() -> None\n\ +\n\ +Clear the list of previously registered exit functions."); + +static PyObject * +atexit_clear(PyObject *self, PyObject *unused) +{ atexit_cleanup(get_atexit_state(self)); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(atexit_ncallbacks__doc__, -"_ncallbacks() -> int\n\ -\n\ -Return the number of registered exit functions."); - -static PyObject * -atexit_ncallbacks(PyObject *self, PyObject *unused) -{ - atexitmodule_state *modstate; - + Py_RETURN_NONE; +} + +PyDoc_STRVAR(atexit_ncallbacks__doc__, +"_ncallbacks() -> int\n\ +\n\ +Return the number of registered exit functions."); + +static PyObject * +atexit_ncallbacks(PyObject *self, PyObject *unused) +{ + atexitmodule_state *modstate; + modstate = get_atexit_state(self); - - return PyLong_FromSsize_t(modstate->ncallbacks); -} - -static int -atexit_m_traverse(PyObject *self, visitproc visit, void *arg) -{ - int i; - atexitmodule_state *modstate; - + + return PyLong_FromSsize_t(modstate->ncallbacks); +} + +static int +atexit_m_traverse(PyObject *self, visitproc visit, void *arg) +{ + int i; + atexitmodule_state *modstate; + modstate = (atexitmodule_state *)PyModule_GetState(self); for (i = 0; i < modstate->ncallbacks; i++) { @@ -237,119 +237,119 @@ atexit_m_traverse(PyObject *self, visitproc visit, void *arg) Py_VISIT(cb->func); Py_VISIT(cb->args); Py_VISIT(cb->kwargs); - } - return 0; -} - -static int -atexit_m_clear(PyObject *self) -{ - atexitmodule_state *modstate; + } + return 0; +} + +static int +atexit_m_clear(PyObject *self) +{ + atexitmodule_state *modstate; modstate = (atexitmodule_state *)PyModule_GetState(self); atexit_cleanup(modstate); - return 0; -} - -static void -atexit_free(PyObject *m) -{ - atexitmodule_state *modstate; + return 0; +} + +static void +atexit_free(PyObject *m) +{ + atexitmodule_state *modstate; modstate = (atexitmodule_state *)PyModule_GetState(m); atexit_cleanup(modstate); PyMem_Free(modstate->atexit_callbacks); -} - -PyDoc_STRVAR(atexit_unregister__doc__, -"unregister(func) -> None\n\ -\n\ -Unregister an exit function which was previously registered using\n\ -atexit.register\n\ -\n\ - func - function to be unregistered"); - -static PyObject * -atexit_unregister(PyObject *self, PyObject *func) -{ - atexitmodule_state *modstate; - atexit_callback *cb; - int i, eq; - +} + +PyDoc_STRVAR(atexit_unregister__doc__, +"unregister(func) -> None\n\ +\n\ +Unregister an exit function which was previously registered using\n\ +atexit.register\n\ +\n\ + func - function to be unregistered"); + +static PyObject * +atexit_unregister(PyObject *self, PyObject *func) +{ + atexitmodule_state *modstate; + atexit_callback *cb; + int i, eq; + modstate = get_atexit_state(self); - - for (i = 0; i < modstate->ncallbacks; i++) - { - cb = modstate->atexit_callbacks[i]; - if (cb == NULL) - continue; - - eq = PyObject_RichCompareBool(cb->func, func, Py_EQ); - if (eq < 0) - return NULL; - if (eq) - atexit_delete_cb(modstate, i); - } - Py_RETURN_NONE; -} - -static PyMethodDef atexit_methods[] = { + + for (i = 0; i < modstate->ncallbacks; i++) + { + cb = modstate->atexit_callbacks[i]; + if (cb == NULL) + continue; + + eq = PyObject_RichCompareBool(cb->func, func, Py_EQ); + if (eq < 0) + return NULL; + if (eq) + atexit_delete_cb(modstate, i); + } + Py_RETURN_NONE; +} + +static PyMethodDef atexit_methods[] = { {"register", (PyCFunction)(void(*)(void)) atexit_register, METH_VARARGS|METH_KEYWORDS, - atexit_register__doc__}, - {"_clear", (PyCFunction) atexit_clear, METH_NOARGS, - atexit_clear__doc__}, - {"unregister", (PyCFunction) atexit_unregister, METH_O, - atexit_unregister__doc__}, - {"_run_exitfuncs", (PyCFunction) atexit_run_exitfuncs, METH_NOARGS, - atexit_run_exitfuncs__doc__}, - {"_ncallbacks", (PyCFunction) atexit_ncallbacks, METH_NOARGS, - atexit_ncallbacks__doc__}, - {NULL, NULL} /* sentinel */ -}; - -/* ===================================================================== */ -/* Initialization function. */ - -PyDoc_STRVAR(atexit__doc__, -"allow programmer to define multiple exit functions to be executed\ -upon normal program termination.\n\ -\n\ -Two public functions, register and unregister, are defined.\n\ -"); - -static int -atexit_exec(PyObject *m) { - atexitmodule_state *modstate; - + atexit_register__doc__}, + {"_clear", (PyCFunction) atexit_clear, METH_NOARGS, + atexit_clear__doc__}, + {"unregister", (PyCFunction) atexit_unregister, METH_O, + atexit_unregister__doc__}, + {"_run_exitfuncs", (PyCFunction) atexit_run_exitfuncs, METH_NOARGS, + atexit_run_exitfuncs__doc__}, + {"_ncallbacks", (PyCFunction) atexit_ncallbacks, METH_NOARGS, + atexit_ncallbacks__doc__}, + {NULL, NULL} /* sentinel */ +}; + +/* ===================================================================== */ +/* Initialization function. */ + +PyDoc_STRVAR(atexit__doc__, +"allow programmer to define multiple exit functions to be executed\ +upon normal program termination.\n\ +\n\ +Two public functions, register and unregister, are defined.\n\ +"); + +static int +atexit_exec(PyObject *m) { + atexitmodule_state *modstate; + modstate = get_atexit_state(m); - modstate->callback_len = 32; - modstate->ncallbacks = 0; - modstate->atexit_callbacks = PyMem_New(atexit_callback*, - modstate->callback_len); - if (modstate->atexit_callbacks == NULL) - return -1; - - _Py_PyAtExit(atexit_callfuncs, m); - return 0; -} - -static PyModuleDef_Slot atexit_slots[] = { - {Py_mod_exec, atexit_exec}, - {0, NULL} -}; - -static struct PyModuleDef atexitmodule = { - PyModuleDef_HEAD_INIT, - "atexit", - atexit__doc__, - sizeof(atexitmodule_state), - atexit_methods, - atexit_slots, - atexit_m_traverse, - atexit_m_clear, - (freefunc)atexit_free -}; - -PyMODINIT_FUNC -PyInit_atexit(void) -{ - return PyModuleDef_Init(&atexitmodule); -} + modstate->callback_len = 32; + modstate->ncallbacks = 0; + modstate->atexit_callbacks = PyMem_New(atexit_callback*, + modstate->callback_len); + if (modstate->atexit_callbacks == NULL) + return -1; + + _Py_PyAtExit(atexit_callfuncs, m); + return 0; +} + +static PyModuleDef_Slot atexit_slots[] = { + {Py_mod_exec, atexit_exec}, + {0, NULL} +}; + +static struct PyModuleDef atexitmodule = { + PyModuleDef_HEAD_INIT, + "atexit", + atexit__doc__, + sizeof(atexitmodule_state), + atexit_methods, + atexit_slots, + atexit_m_traverse, + atexit_m_clear, + (freefunc)atexit_free +}; + +PyMODINIT_FUNC +PyInit_atexit(void) +{ + return PyModuleDef_Init(&atexitmodule); +} diff --git a/contrib/tools/python3/src/Modules/audioop.c b/contrib/tools/python3/src/Modules/audioop.c index 3aeb6f04f13..b871bda432d 100644 --- a/contrib/tools/python3/src/Modules/audioop.c +++ b/contrib/tools/python3/src/Modules/audioop.c @@ -1,382 +1,382 @@ - -/* audioopmodule - Module to detect peak values in arrays */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" - -#if defined(__CHAR_UNSIGNED__) -#if defined(signed) -/* This module currently does not work on systems where only unsigned - characters are available. Take it out of Setup. Sorry. */ -#endif -#endif - -static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF}; -/* -1 trick is needed on Windows to support -0x80000000 without a warning */ -static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1}; -static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF}; - -static int -fbound(double val, double minval, double maxval) -{ - if (val > maxval) { - val = maxval; - } - else if (val < minval + 1.0) { - val = minval; - } - - /* Round towards minus infinity (-inf) */ - val = floor(val); - - /* Cast double to integer: round towards zero */ - return (int)val; -} - - -/* Code shamelessly stolen from sox, 12.17.7, g711.c -** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */ - -/* From g711.c: - * - * December 30, 1994: - * Functions linear2alaw, linear2ulaw have been updated to correctly - * convert unquantized 16 bit values. - * Tables for direct u- to A-law and A- to u-law conversions have been - * corrected. - * Borge Lindberg, Center for PersonKommunikation, Aalborg University. - * bli@cpk.auc.dk - * - */ -#define BIAS 0x84 /* define the add-in bias for 16 bit samples */ -#define CLIP 32635 -#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */ -#define QUANT_MASK (0xf) /* Quantization field mask. */ -#define SEG_SHIFT (4) /* Left shift for segment number. */ -#define SEG_MASK (0x70) /* Segment field mask. */ - -static const int16_t seg_aend[8] = { - 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF -}; -static const int16_t seg_uend[8] = { - 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF -}; - -static int16_t -search(int16_t val, const int16_t *table, int size) -{ - int i; - - for (i = 0; i < size; i++) { - if (val <= *table++) - return (i); - } - return (size); -} -#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc]) -#define st_alaw2linear16(uc) (_st_alaw2linear16[uc]) - -static const int16_t _st_ulaw2linear16[256] = { - -32124, -31100, -30076, -29052, -28028, -27004, -25980, - -24956, -23932, -22908, -21884, -20860, -19836, -18812, - -17788, -16764, -15996, -15484, -14972, -14460, -13948, - -13436, -12924, -12412, -11900, -11388, -10876, -10364, - -9852, -9340, -8828, -8316, -7932, -7676, -7420, - -7164, -6908, -6652, -6396, -6140, -5884, -5628, - -5372, -5116, -4860, -4604, -4348, -4092, -3900, - -3772, -3644, -3516, -3388, -3260, -3132, -3004, - -2876, -2748, -2620, -2492, -2364, -2236, -2108, - -1980, -1884, -1820, -1756, -1692, -1628, -1564, - -1500, -1436, -1372, -1308, -1244, -1180, -1116, - -1052, -988, -924, -876, -844, -812, -780, - -748, -716, -684, -652, -620, -588, -556, - -524, -492, -460, -428, -396, -372, -356, - -340, -324, -308, -292, -276, -260, -244, - -228, -212, -196, -180, -164, -148, -132, - -120, -112, -104, -96, -88, -80, -72, - -64, -56, -48, -40, -32, -24, -16, - -8, 0, 32124, 31100, 30076, 29052, 28028, - 27004, 25980, 24956, 23932, 22908, 21884, 20860, - 19836, 18812, 17788, 16764, 15996, 15484, 14972, - 14460, 13948, 13436, 12924, 12412, 11900, 11388, - 10876, 10364, 9852, 9340, 8828, 8316, 7932, - 7676, 7420, 7164, 6908, 6652, 6396, 6140, - 5884, 5628, 5372, 5116, 4860, 4604, 4348, - 4092, 3900, 3772, 3644, 3516, 3388, 3260, - 3132, 3004, 2876, 2748, 2620, 2492, 2364, - 2236, 2108, 1980, 1884, 1820, 1756, 1692, - 1628, 1564, 1500, 1436, 1372, 1308, 1244, - 1180, 1116, 1052, 988, 924, 876, 844, - 812, 780, 748, 716, 684, 652, 620, - 588, 556, 524, 492, 460, 428, 396, - 372, 356, 340, 324, 308, 292, 276, - 260, 244, 228, 212, 196, 180, 164, - 148, 132, 120, 112, 104, 96, 88, - 80, 72, 64, 56, 48, 40, 32, - 24, 16, 8, 0 -}; - -/* - * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data - * stored in an unsigned char. This function should only be called with - * the data shifted such that it only contains information in the lower - * 14-bits. - * - * In order to simplify the encoding process, the original linear magnitude - * is biased by adding 33 which shifts the encoding range from (0 - 8158) to - * (33 - 8191). The result can be seen in the following encoding table: - * - * Biased Linear Input Code Compressed Code - * ------------------------ --------------- - * 00000001wxyza 000wxyz - * 0000001wxyzab 001wxyz - * 000001wxyzabc 010wxyz - * 00001wxyzabcd 011wxyz - * 0001wxyzabcde 100wxyz - * 001wxyzabcdef 101wxyz - * 01wxyzabcdefg 110wxyz - * 1wxyzabcdefgh 111wxyz - * - * Each biased linear code has a leading 1 which identifies the segment - * number. The value of the segment number is equal to 7 minus the number - * of leading 0's. The quantization interval is directly available as the - * four bits wxyz. * The trailing bits (a - h) are ignored. - * - * Ordinarily the complement of the resulting code word is used for - * transmission, and so the code word is complemented before it is returned. - * - * For further information see John C. Bellamy's Digital Telephony, 1982, - * John Wiley & Sons, pps 98-111 and 472-476. - */ -static unsigned char -st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */ -{ - int16_t mask; - int16_t seg; - unsigned char uval; - - /* u-law inverts all bits */ - /* Get the sign and the magnitude of the value. */ - if (pcm_val < 0) { - pcm_val = -pcm_val; - mask = 0x7F; - } else { - mask = 0xFF; - } - if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ - pcm_val += (BIAS >> 2); - - /* Convert the scaled magnitude to segment number. */ - seg = search(pcm_val, seg_uend, 8); - - /* - * Combine the sign, segment, quantization bits; - * and complement the code word. - */ - if (seg >= 8) /* out of range, return maximum value. */ - return (unsigned char) (0x7F ^ mask); - else { - uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); - return (uval ^ mask); - } - -} - -static const int16_t _st_alaw2linear16[256] = { - -5504, -5248, -6016, -5760, -4480, -4224, -4992, - -4736, -7552, -7296, -8064, -7808, -6528, -6272, - -7040, -6784, -2752, -2624, -3008, -2880, -2240, - -2112, -2496, -2368, -3776, -3648, -4032, -3904, - -3264, -3136, -3520, -3392, -22016, -20992, -24064, - -23040, -17920, -16896, -19968, -18944, -30208, -29184, - -32256, -31232, -26112, -25088, -28160, -27136, -11008, - -10496, -12032, -11520, -8960, -8448, -9984, -9472, - -15104, -14592, -16128, -15616, -13056, -12544, -14080, - -13568, -344, -328, -376, -360, -280, -264, - -312, -296, -472, -456, -504, -488, -408, - -392, -440, -424, -88, -72, -120, -104, - -24, -8, -56, -40, -216, -200, -248, - -232, -152, -136, -184, -168, -1376, -1312, - -1504, -1440, -1120, -1056, -1248, -1184, -1888, - -1824, -2016, -1952, -1632, -1568, -1760, -1696, - -688, -656, -752, -720, -560, -528, -624, - -592, -944, -912, -1008, -976, -816, -784, - -880, -848, 5504, 5248, 6016, 5760, 4480, - 4224, 4992, 4736, 7552, 7296, 8064, 7808, - 6528, 6272, 7040, 6784, 2752, 2624, 3008, - 2880, 2240, 2112, 2496, 2368, 3776, 3648, - 4032, 3904, 3264, 3136, 3520, 3392, 22016, - 20992, 24064, 23040, 17920, 16896, 19968, 18944, - 30208, 29184, 32256, 31232, 26112, 25088, 28160, - 27136, 11008, 10496, 12032, 11520, 8960, 8448, - 9984, 9472, 15104, 14592, 16128, 15616, 13056, - 12544, 14080, 13568, 344, 328, 376, 360, - 280, 264, 312, 296, 472, 456, 504, - 488, 408, 392, 440, 424, 88, 72, - 120, 104, 24, 8, 56, 40, 216, - 200, 248, 232, 152, 136, 184, 168, - 1376, 1312, 1504, 1440, 1120, 1056, 1248, - 1184, 1888, 1824, 2016, 1952, 1632, 1568, - 1760, 1696, 688, 656, 752, 720, 560, - 528, 624, 592, 944, 912, 1008, 976, - 816, 784, 880, 848 -}; - -/* - * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data - * stored in an unsigned char. This function should only be called with - * the data shifted such that it only contains information in the lower - * 13-bits. - * - * Linear Input Code Compressed Code - * ------------------------ --------------- - * 0000000wxyza 000wxyz - * 0000001wxyza 001wxyz - * 000001wxyzab 010wxyz - * 00001wxyzabc 011wxyz - * 0001wxyzabcd 100wxyz - * 001wxyzabcde 101wxyz - * 01wxyzabcdef 110wxyz - * 1wxyzabcdefg 111wxyz - * - * For further information see John C. Bellamy's Digital Telephony, 1982, - * John Wiley & Sons, pps 98-111 and 472-476. - */ -static unsigned char -st_linear2alaw(int16_t pcm_val) /* 2's complement (13-bit range) */ -{ - int16_t mask; - int16_t seg; - unsigned char aval; - - /* A-law using even bit inversion */ - if (pcm_val >= 0) { - mask = 0xD5; /* sign (7th) bit = 1 */ - } else { - mask = 0x55; /* sign bit = 0 */ - pcm_val = -pcm_val - 1; - } - - /* Convert the scaled magnitude to segment number. */ - seg = search(pcm_val, seg_aend, 8); - - /* Combine the sign, segment, and quantization bits. */ - - if (seg >= 8) /* out of range, return maximum value. */ - return (unsigned char) (0x7F ^ mask); - else { - aval = (unsigned char) seg << SEG_SHIFT; - if (seg < 2) - aval |= (pcm_val >> 1) & QUANT_MASK; - else - aval |= (pcm_val >> seg) & QUANT_MASK; - return (aval ^ mask); - } -} -/* End of code taken from sox */ - -/* Intel ADPCM step variation table */ -static const int indexTable[16] = { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8, -}; - -static const int stepsizeTable[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 -}; - -#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i))) -#define SETINTX(T, cp, i, val) do { \ - *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \ - } while (0) - - -#define GETINT8(cp, i) GETINTX(signed char, (cp), (i)) -#define GETINT16(cp, i) GETINTX(int16_t, (cp), (i)) -#define GETINT32(cp, i) GETINTX(int32_t, (cp), (i)) - -#if WORDS_BIGENDIAN -#define GETINT24(cp, i) ( \ - ((unsigned char *)(cp) + (i))[2] + \ - (((unsigned char *)(cp) + (i))[1] << 8) + \ - (((signed char *)(cp) + (i))[0] << 16) ) -#else -#define GETINT24(cp, i) ( \ - ((unsigned char *)(cp) + (i))[0] + \ - (((unsigned char *)(cp) + (i))[1] << 8) + \ - (((signed char *)(cp) + (i))[2] << 16) ) -#endif - - -#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val)) -#define SETINT16(cp, i, val) SETINTX(int16_t, (cp), (i), (val)) -#define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val)) - -#if WORDS_BIGENDIAN -#define SETINT24(cp, i, val) do { \ - ((unsigned char *)(cp) + (i))[2] = (int)(val); \ - ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \ - ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \ - } while (0) -#else -#define SETINT24(cp, i, val) do { \ - ((unsigned char *)(cp) + (i))[0] = (int)(val); \ - ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \ - ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \ - } while (0) -#endif - - -#define GETRAWSAMPLE(size, cp, i) ( \ - (size == 1) ? (int)GETINT8((cp), (i)) : \ - (size == 2) ? (int)GETINT16((cp), (i)) : \ - (size == 3) ? (int)GETINT24((cp), (i)) : \ - (int)GETINT32((cp), (i))) - -#define SETRAWSAMPLE(size, cp, i, val) do { \ - if (size == 1) \ - SETINT8((cp), (i), (val)); \ - else if (size == 2) \ - SETINT16((cp), (i), (val)); \ - else if (size == 3) \ - SETINT24((cp), (i), (val)); \ - else \ - SETINT32((cp), (i), (val)); \ - } while(0) - - -#define GETSAMPLE32(size, cp, i) ( \ - (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \ - (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \ - (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \ - (int)GETINT32((cp), (i))) - -#define SETSAMPLE32(size, cp, i, val) do { \ - if (size == 1) \ - SETINT8((cp), (i), (val) >> 24); \ - else if (size == 2) \ - SETINT16((cp), (i), (val) >> 16); \ - else if (size == 3) \ - SETINT24((cp), (i), (val) >> 8); \ - else \ - SETINT32((cp), (i), (val)); \ - } while(0) - + +/* audioopmodule - Module to detect peak values in arrays */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" + +#if defined(__CHAR_UNSIGNED__) +#if defined(signed) +/* This module currently does not work on systems where only unsigned + characters are available. Take it out of Setup. Sorry. */ +#endif +#endif + +static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF}; +/* -1 trick is needed on Windows to support -0x80000000 without a warning */ +static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1}; +static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF}; + +static int +fbound(double val, double minval, double maxval) +{ + if (val > maxval) { + val = maxval; + } + else if (val < minval + 1.0) { + val = minval; + } + + /* Round towards minus infinity (-inf) */ + val = floor(val); + + /* Cast double to integer: round towards zero */ + return (int)val; +} + + +/* Code shamelessly stolen from sox, 12.17.7, g711.c +** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */ + +/* From g711.c: + * + * December 30, 1994: + * Functions linear2alaw, linear2ulaw have been updated to correctly + * convert unquantized 16 bit values. + * Tables for direct u- to A-law and A- to u-law conversions have been + * corrected. + * Borge Lindberg, Center for PersonKommunikation, Aalborg University. + * bli@cpk.auc.dk + * + */ +#define BIAS 0x84 /* define the add-in bias for 16 bit samples */ +#define CLIP 32635 +#define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */ +#define QUANT_MASK (0xf) /* Quantization field mask. */ +#define SEG_SHIFT (4) /* Left shift for segment number. */ +#define SEG_MASK (0x70) /* Segment field mask. */ + +static const int16_t seg_aend[8] = { + 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF +}; +static const int16_t seg_uend[8] = { + 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF +}; + +static int16_t +search(int16_t val, const int16_t *table, int size) +{ + int i; + + for (i = 0; i < size; i++) { + if (val <= *table++) + return (i); + } + return (size); +} +#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc]) +#define st_alaw2linear16(uc) (_st_alaw2linear16[uc]) + +static const int16_t _st_ulaw2linear16[256] = { + -32124, -31100, -30076, -29052, -28028, -27004, -25980, + -24956, -23932, -22908, -21884, -20860, -19836, -18812, + -17788, -16764, -15996, -15484, -14972, -14460, -13948, + -13436, -12924, -12412, -11900, -11388, -10876, -10364, + -9852, -9340, -8828, -8316, -7932, -7676, -7420, + -7164, -6908, -6652, -6396, -6140, -5884, -5628, + -5372, -5116, -4860, -4604, -4348, -4092, -3900, + -3772, -3644, -3516, -3388, -3260, -3132, -3004, + -2876, -2748, -2620, -2492, -2364, -2236, -2108, + -1980, -1884, -1820, -1756, -1692, -1628, -1564, + -1500, -1436, -1372, -1308, -1244, -1180, -1116, + -1052, -988, -924, -876, -844, -812, -780, + -748, -716, -684, -652, -620, -588, -556, + -524, -492, -460, -428, -396, -372, -356, + -340, -324, -308, -292, -276, -260, -244, + -228, -212, -196, -180, -164, -148, -132, + -120, -112, -104, -96, -88, -80, -72, + -64, -56, -48, -40, -32, -24, -16, + -8, 0, 32124, 31100, 30076, 29052, 28028, + 27004, 25980, 24956, 23932, 22908, 21884, 20860, + 19836, 18812, 17788, 16764, 15996, 15484, 14972, + 14460, 13948, 13436, 12924, 12412, 11900, 11388, + 10876, 10364, 9852, 9340, 8828, 8316, 7932, + 7676, 7420, 7164, 6908, 6652, 6396, 6140, + 5884, 5628, 5372, 5116, 4860, 4604, 4348, + 4092, 3900, 3772, 3644, 3516, 3388, 3260, + 3132, 3004, 2876, 2748, 2620, 2492, 2364, + 2236, 2108, 1980, 1884, 1820, 1756, 1692, + 1628, 1564, 1500, 1436, 1372, 1308, 1244, + 1180, 1116, 1052, 988, 924, 876, 844, + 812, 780, 748, 716, 684, 652, 620, + 588, 556, 524, 492, 460, 428, 396, + 372, 356, 340, 324, 308, 292, 276, + 260, 244, 228, 212, 196, 180, 164, + 148, 132, 120, 112, 104, 96, 88, + 80, 72, 64, 56, 48, 40, 32, + 24, 16, 8, 0 +}; + +/* + * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data + * stored in an unsigned char. This function should only be called with + * the data shifted such that it only contains information in the lower + * 14-bits. + * + * In order to simplify the encoding process, the original linear magnitude + * is biased by adding 33 which shifts the encoding range from (0 - 8158) to + * (33 - 8191). The result can be seen in the following encoding table: + * + * Biased Linear Input Code Compressed Code + * ------------------------ --------------- + * 00000001wxyza 000wxyz + * 0000001wxyzab 001wxyz + * 000001wxyzabc 010wxyz + * 00001wxyzabcd 011wxyz + * 0001wxyzabcde 100wxyz + * 001wxyzabcdef 101wxyz + * 01wxyzabcdefg 110wxyz + * 1wxyzabcdefgh 111wxyz + * + * Each biased linear code has a leading 1 which identifies the segment + * number. The value of the segment number is equal to 7 minus the number + * of leading 0's. The quantization interval is directly available as the + * four bits wxyz. * The trailing bits (a - h) are ignored. + * + * Ordinarily the complement of the resulting code word is used for + * transmission, and so the code word is complemented before it is returned. + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ +static unsigned char +st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */ +{ + int16_t mask; + int16_t seg; + unsigned char uval; + + /* u-law inverts all bits */ + /* Get the sign and the magnitude of the value. */ + if (pcm_val < 0) { + pcm_val = -pcm_val; + mask = 0x7F; + } else { + mask = 0xFF; + } + if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ + pcm_val += (BIAS >> 2); + + /* Convert the scaled magnitude to segment number. */ + seg = search(pcm_val, seg_uend, 8); + + /* + * Combine the sign, segment, quantization bits; + * and complement the code word. + */ + if (seg >= 8) /* out of range, return maximum value. */ + return (unsigned char) (0x7F ^ mask); + else { + uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); + return (uval ^ mask); + } + +} + +static const int16_t _st_alaw2linear16[256] = { + -5504, -5248, -6016, -5760, -4480, -4224, -4992, + -4736, -7552, -7296, -8064, -7808, -6528, -6272, + -7040, -6784, -2752, -2624, -3008, -2880, -2240, + -2112, -2496, -2368, -3776, -3648, -4032, -3904, + -3264, -3136, -3520, -3392, -22016, -20992, -24064, + -23040, -17920, -16896, -19968, -18944, -30208, -29184, + -32256, -31232, -26112, -25088, -28160, -27136, -11008, + -10496, -12032, -11520, -8960, -8448, -9984, -9472, + -15104, -14592, -16128, -15616, -13056, -12544, -14080, + -13568, -344, -328, -376, -360, -280, -264, + -312, -296, -472, -456, -504, -488, -408, + -392, -440, -424, -88, -72, -120, -104, + -24, -8, -56, -40, -216, -200, -248, + -232, -152, -136, -184, -168, -1376, -1312, + -1504, -1440, -1120, -1056, -1248, -1184, -1888, + -1824, -2016, -1952, -1632, -1568, -1760, -1696, + -688, -656, -752, -720, -560, -528, -624, + -592, -944, -912, -1008, -976, -816, -784, + -880, -848, 5504, 5248, 6016, 5760, 4480, + 4224, 4992, 4736, 7552, 7296, 8064, 7808, + 6528, 6272, 7040, 6784, 2752, 2624, 3008, + 2880, 2240, 2112, 2496, 2368, 3776, 3648, + 4032, 3904, 3264, 3136, 3520, 3392, 22016, + 20992, 24064, 23040, 17920, 16896, 19968, 18944, + 30208, 29184, 32256, 31232, 26112, 25088, 28160, + 27136, 11008, 10496, 12032, 11520, 8960, 8448, + 9984, 9472, 15104, 14592, 16128, 15616, 13056, + 12544, 14080, 13568, 344, 328, 376, 360, + 280, 264, 312, 296, 472, 456, 504, + 488, 408, 392, 440, 424, 88, 72, + 120, 104, 24, 8, 56, 40, 216, + 200, 248, 232, 152, 136, 184, 168, + 1376, 1312, 1504, 1440, 1120, 1056, 1248, + 1184, 1888, 1824, 2016, 1952, 1632, 1568, + 1760, 1696, 688, 656, 752, 720, 560, + 528, 624, 592, 944, 912, 1008, 976, + 816, 784, 880, 848 +}; + +/* + * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data + * stored in an unsigned char. This function should only be called with + * the data shifted such that it only contains information in the lower + * 13-bits. + * + * Linear Input Code Compressed Code + * ------------------------ --------------- + * 0000000wxyza 000wxyz + * 0000001wxyza 001wxyz + * 000001wxyzab 010wxyz + * 00001wxyzabc 011wxyz + * 0001wxyzabcd 100wxyz + * 001wxyzabcde 101wxyz + * 01wxyzabcdef 110wxyz + * 1wxyzabcdefg 111wxyz + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ +static unsigned char +st_linear2alaw(int16_t pcm_val) /* 2's complement (13-bit range) */ +{ + int16_t mask; + int16_t seg; + unsigned char aval; + + /* A-law using even bit inversion */ + if (pcm_val >= 0) { + mask = 0xD5; /* sign (7th) bit = 1 */ + } else { + mask = 0x55; /* sign bit = 0 */ + pcm_val = -pcm_val - 1; + } + + /* Convert the scaled magnitude to segment number. */ + seg = search(pcm_val, seg_aend, 8); + + /* Combine the sign, segment, and quantization bits. */ + + if (seg >= 8) /* out of range, return maximum value. */ + return (unsigned char) (0x7F ^ mask); + else { + aval = (unsigned char) seg << SEG_SHIFT; + if (seg < 2) + aval |= (pcm_val >> 1) & QUANT_MASK; + else + aval |= (pcm_val >> seg) & QUANT_MASK; + return (aval ^ mask); + } +} +/* End of code taken from sox */ + +/* Intel ADPCM step variation table */ +static const int indexTable[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +static const int stepsizeTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i))) +#define SETINTX(T, cp, i, val) do { \ + *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \ + } while (0) + + +#define GETINT8(cp, i) GETINTX(signed char, (cp), (i)) +#define GETINT16(cp, i) GETINTX(int16_t, (cp), (i)) +#define GETINT32(cp, i) GETINTX(int32_t, (cp), (i)) + +#if WORDS_BIGENDIAN +#define GETINT24(cp, i) ( \ + ((unsigned char *)(cp) + (i))[2] + \ + (((unsigned char *)(cp) + (i))[1] << 8) + \ + (((signed char *)(cp) + (i))[0] << 16) ) +#else +#define GETINT24(cp, i) ( \ + ((unsigned char *)(cp) + (i))[0] + \ + (((unsigned char *)(cp) + (i))[1] << 8) + \ + (((signed char *)(cp) + (i))[2] << 16) ) +#endif + + +#define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val)) +#define SETINT16(cp, i, val) SETINTX(int16_t, (cp), (i), (val)) +#define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val)) + +#if WORDS_BIGENDIAN +#define SETINT24(cp, i, val) do { \ + ((unsigned char *)(cp) + (i))[2] = (int)(val); \ + ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \ + ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \ + } while (0) +#else +#define SETINT24(cp, i, val) do { \ + ((unsigned char *)(cp) + (i))[0] = (int)(val); \ + ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \ + ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \ + } while (0) +#endif + + +#define GETRAWSAMPLE(size, cp, i) ( \ + (size == 1) ? (int)GETINT8((cp), (i)) : \ + (size == 2) ? (int)GETINT16((cp), (i)) : \ + (size == 3) ? (int)GETINT24((cp), (i)) : \ + (int)GETINT32((cp), (i))) + +#define SETRAWSAMPLE(size, cp, i, val) do { \ + if (size == 1) \ + SETINT8((cp), (i), (val)); \ + else if (size == 2) \ + SETINT16((cp), (i), (val)); \ + else if (size == 3) \ + SETINT24((cp), (i), (val)); \ + else \ + SETINT32((cp), (i), (val)); \ + } while(0) + + +#define GETSAMPLE32(size, cp, i) ( \ + (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \ + (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \ + (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \ + (int)GETINT32((cp), (i))) + +#define SETSAMPLE32(size, cp, i, val) do { \ + if (size == 1) \ + SETINT8((cp), (i), (val) >> 24); \ + else if (size == 2) \ + SETINT16((cp), (i), (val) >> 16); \ + else if (size == 3) \ + SETINT24((cp), (i), (val) >> 8); \ + else \ + SETINT32((cp), (i), (val)); \ + } while(0) + static PyModuleDef audioopmodule; - + typedef struct { PyObject *AudioopError; } audioop_state; - + static inline audioop_state * get_audioop_state(PyObject *module) { @@ -385,1543 +385,1543 @@ get_audioop_state(PyObject *module) return (audioop_state *)state; } -static int +static int audioop_check_size(PyObject *module, int size) -{ - if (size < 1 || size > 4) { +{ + if (size < 1 || size > 4) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Size should be 1, 2, 3 or 4"); - return 0; - } - else - return 1; -} - -static int + return 0; + } + else + return 1; +} + +static int audioop_check_parameters(PyObject *module, Py_ssize_t len, int size) -{ +{ if (!audioop_check_size(module, size)) - return 0; - if (len % size != 0) { + return 0; + if (len % size != 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "not a whole number of frames"); - return 0; - } - return 1; -} - -/*[clinic input] -module audioop -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/ - -/*[clinic input] -audioop.getsample - - fragment: Py_buffer - width: int - index: Py_ssize_t - / - -Return the value of sample index from the fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width, - Py_ssize_t index) -/*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/ -{ - int val; - + return 0; + } + return 1; +} + +/*[clinic input] +module audioop +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/ + +/*[clinic input] +audioop.getsample + + fragment: Py_buffer + width: int + index: Py_ssize_t + / + +Return the value of sample index from the fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width, + Py_ssize_t index) +/*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/ +{ + int val; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - if (index < 0 || index >= fragment->len/width) { + return NULL; + if (index < 0 || index >= fragment->len/width) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Index out of range"); - return NULL; - } - val = GETRAWSAMPLE(width, fragment->buf, index*width); - return PyLong_FromLong(val); -} - -/*[clinic input] -audioop.max - - fragment: Py_buffer - width: int - / - -Return the maximum of the absolute value of all samples in a fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_max_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/ -{ - Py_ssize_t i; - unsigned int absval, max = 0; - + return NULL; + } + val = GETRAWSAMPLE(width, fragment->buf, index*width); + return PyLong_FromLong(val); +} + +/*[clinic input] +audioop.max + + fragment: Py_buffer + width: int + / + +Return the maximum of the absolute value of all samples in a fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_max_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/ +{ + Py_ssize_t i; + unsigned int absval, max = 0; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - for (i = 0; i < fragment->len; i += width) { - int val = GETRAWSAMPLE(width, fragment->buf, i); - /* Cast to unsigned before negating. Unsigned overflow is well- - defined, but signed overflow is not. */ - if (val < 0) absval = (unsigned int)-(int64_t)val; - else absval = val; - if (absval > max) max = absval; - } - return PyLong_FromUnsignedLong(max); -} - -/*[clinic input] -audioop.minmax - - fragment: Py_buffer - width: int - / - -Return the minimum and maximum values of all samples in the sound fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/ -{ - Py_ssize_t i; - /* -1 trick below is needed on Windows to support -0x80000000 without - a warning */ - int min = 0x7fffffff, max = -0x7FFFFFFF-1; - + return NULL; + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); + /* Cast to unsigned before negating. Unsigned overflow is well- + defined, but signed overflow is not. */ + if (val < 0) absval = (unsigned int)-(int64_t)val; + else absval = val; + if (absval > max) max = absval; + } + return PyLong_FromUnsignedLong(max); +} + +/*[clinic input] +audioop.minmax + + fragment: Py_buffer + width: int + / + +Return the minimum and maximum values of all samples in the sound fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/ +{ + Py_ssize_t i; + /* -1 trick below is needed on Windows to support -0x80000000 without + a warning */ + int min = 0x7fffffff, max = -0x7FFFFFFF-1; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - for (i = 0; i < fragment->len; i += width) { - int val = GETRAWSAMPLE(width, fragment->buf, i); - if (val > max) max = val; - if (val < min) min = val; - } - return Py_BuildValue("(ii)", min, max); -} - -/*[clinic input] -audioop.avg - - fragment: Py_buffer - width: int - / - -Return the average over all samples in the fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/ -{ - Py_ssize_t i; - int avg; - double sum = 0.0; - + return NULL; + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); + if (val > max) max = val; + if (val < min) min = val; + } + return Py_BuildValue("(ii)", min, max); +} + +/*[clinic input] +audioop.avg + + fragment: Py_buffer + width: int + / + +Return the average over all samples in the fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/ +{ + Py_ssize_t i; + int avg; + double sum = 0.0; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - for (i = 0; i < fragment->len; i += width) - sum += GETRAWSAMPLE(width, fragment->buf, i); - if (fragment->len == 0) - avg = 0; - else - avg = (int)floor(sum / (double)(fragment->len/width)); - return PyLong_FromLong(avg); -} - -/*[clinic input] -audioop.rms - - fragment: Py_buffer - width: int - / - -Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n). -[clinic start generated code]*/ - -static PyObject * -audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/ -{ - Py_ssize_t i; - unsigned int res; - double sum_squares = 0.0; - + return NULL; + for (i = 0; i < fragment->len; i += width) + sum += GETRAWSAMPLE(width, fragment->buf, i); + if (fragment->len == 0) + avg = 0; + else + avg = (int)floor(sum / (double)(fragment->len/width)); + return PyLong_FromLong(avg); +} + +/*[clinic input] +audioop.rms + + fragment: Py_buffer + width: int + / + +Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n). +[clinic start generated code]*/ + +static PyObject * +audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/ +{ + Py_ssize_t i; + unsigned int res; + double sum_squares = 0.0; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - for (i = 0; i < fragment->len; i += width) { - double val = GETRAWSAMPLE(width, fragment->buf, i); - sum_squares += val*val; - } - if (fragment->len == 0) - res = 0; - else - res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width)); - return PyLong_FromUnsignedLong(res); -} - -static double _sum2(const int16_t *a, const int16_t *b, Py_ssize_t len) -{ - Py_ssize_t i; - double sum = 0.0; - - for( i=0; i n, and let all sums be over i from 0 to n-1. -** -** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A -** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This -** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2). -** -** Next, we compute the relative distance between the original signal and -** the modified signal and minimize that over j: -** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) => -** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 ) -** -** In the code variables correspond as follows: -** cp1 A -** cp2 R -** len1 N -** len2 n -** aj_m1 A[j-1] -** aj_lm1 A[j+n-1] -** sum_ri_2 sum(R[i]^2) -** sum_aij_2 sum(A[i+j]^2) -** sum_aij_ri sum(A[i+j]R[i]) -** -** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri -** is completely recalculated each step. -*/ -/*[clinic input] -audioop.findfit - - fragment: Py_buffer - reference: Py_buffer - / - -Try to match reference as well as possible to a portion of fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_findfit_impl(PyObject *module, Py_buffer *fragment, - Py_buffer *reference) -/*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/ -{ - const int16_t *cp1, *cp2; - Py_ssize_t len1, len2; - Py_ssize_t j, best_j; - double aj_m1, aj_lm1; - double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor; - - if (fragment->len & 1 || reference->len & 1) { + return NULL; + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); + sum_squares += val*val; + } + if (fragment->len == 0) + res = 0; + else + res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width)); + return PyLong_FromUnsignedLong(res); +} + +static double _sum2(const int16_t *a, const int16_t *b, Py_ssize_t len) +{ + Py_ssize_t i; + double sum = 0.0; + + for( i=0; i n, and let all sums be over i from 0 to n-1. +** +** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A +** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This +** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2). +** +** Next, we compute the relative distance between the original signal and +** the modified signal and minimize that over j: +** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) => +** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 ) +** +** In the code variables correspond as follows: +** cp1 A +** cp2 R +** len1 N +** len2 n +** aj_m1 A[j-1] +** aj_lm1 A[j+n-1] +** sum_ri_2 sum(R[i]^2) +** sum_aij_2 sum(A[i+j]^2) +** sum_aij_ri sum(A[i+j]R[i]) +** +** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri +** is completely recalculated each step. +*/ +/*[clinic input] +audioop.findfit + + fragment: Py_buffer + reference: Py_buffer + / + +Try to match reference as well as possible to a portion of fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_findfit_impl(PyObject *module, Py_buffer *fragment, + Py_buffer *reference) +/*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/ +{ + const int16_t *cp1, *cp2; + Py_ssize_t len1, len2; + Py_ssize_t j, best_j; + double aj_m1, aj_lm1; + double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor; + + if (fragment->len & 1 || reference->len & 1) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Strings should be even-sized"); - return NULL; - } - cp1 = (const int16_t *)fragment->buf; - len1 = fragment->len >> 1; - cp2 = (const int16_t *)reference->buf; - len2 = reference->len >> 1; - - if (len1 < len2) { + return NULL; + } + cp1 = (const int16_t *)fragment->buf; + len1 = fragment->len >> 1; + cp2 = (const int16_t *)reference->buf; + len2 = reference->len >> 1; + + if (len1 < len2) { PyErr_SetString(get_audioop_state(module)->AudioopError, "First sample should be longer"); - return NULL; - } - sum_ri_2 = _sum2(cp2, cp2, len2); - sum_aij_2 = _sum2(cp1, cp1, len2); - sum_aij_ri = _sum2(cp1, cp2, len2); - - result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2; - - best_result = result; - best_j = 0; - - for ( j=1; j<=len1-len2; j++) { - aj_m1 = (double)cp1[j-1]; - aj_lm1 = (double)cp1[j+len2-1]; - - sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1; - sum_aij_ri = _sum2(cp1+j, cp2, len2); - - result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) - / sum_aij_2; - - if ( result < best_result ) { - best_result = result; - best_j = j; - } - - } - - factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2; - - return Py_BuildValue("(nf)", best_j, factor); -} - -/* -** findfactor finds a factor f so that the energy in A-fB is minimal. -** See the comment for findfit for details. -*/ -/*[clinic input] -audioop.findfactor - - fragment: Py_buffer - reference: Py_buffer - / - -Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal. -[clinic start generated code]*/ - -static PyObject * -audioop_findfactor_impl(PyObject *module, Py_buffer *fragment, - Py_buffer *reference) -/*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/ -{ - const int16_t *cp1, *cp2; - Py_ssize_t len; - double sum_ri_2, sum_aij_ri, result; - - if (fragment->len & 1 || reference->len & 1) { + return NULL; + } + sum_ri_2 = _sum2(cp2, cp2, len2); + sum_aij_2 = _sum2(cp1, cp1, len2); + sum_aij_ri = _sum2(cp1, cp2, len2); + + result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2; + + best_result = result; + best_j = 0; + + for ( j=1; j<=len1-len2; j++) { + aj_m1 = (double)cp1[j-1]; + aj_lm1 = (double)cp1[j+len2-1]; + + sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1; + sum_aij_ri = _sum2(cp1+j, cp2, len2); + + result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) + / sum_aij_2; + + if ( result < best_result ) { + best_result = result; + best_j = j; + } + + } + + factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2; + + return Py_BuildValue("(nf)", best_j, factor); +} + +/* +** findfactor finds a factor f so that the energy in A-fB is minimal. +** See the comment for findfit for details. +*/ +/*[clinic input] +audioop.findfactor + + fragment: Py_buffer + reference: Py_buffer + / + +Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal. +[clinic start generated code]*/ + +static PyObject * +audioop_findfactor_impl(PyObject *module, Py_buffer *fragment, + Py_buffer *reference) +/*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/ +{ + const int16_t *cp1, *cp2; + Py_ssize_t len; + double sum_ri_2, sum_aij_ri, result; + + if (fragment->len & 1 || reference->len & 1) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Strings should be even-sized"); - return NULL; - } - if (fragment->len != reference->len) { + return NULL; + } + if (fragment->len != reference->len) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Samples should be same size"); - return NULL; - } - cp1 = (const int16_t *)fragment->buf; - cp2 = (const int16_t *)reference->buf; - len = fragment->len >> 1; - sum_ri_2 = _sum2(cp2, cp2, len); - sum_aij_ri = _sum2(cp1, cp2, len); - - result = sum_aij_ri / sum_ri_2; - - return PyFloat_FromDouble(result); -} - -/* -** findmax returns the index of the n-sized segment of the input sample -** that contains the most energy. -*/ -/*[clinic input] -audioop.findmax - - fragment: Py_buffer - length: Py_ssize_t - / - -Search fragment for a slice of specified number of samples with maximum energy. -[clinic start generated code]*/ - -static PyObject * -audioop_findmax_impl(PyObject *module, Py_buffer *fragment, - Py_ssize_t length) -/*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/ -{ - const int16_t *cp1; - Py_ssize_t len1; - Py_ssize_t j, best_j; - double aj_m1, aj_lm1; - double result, best_result; - - if (fragment->len & 1) { + return NULL; + } + cp1 = (const int16_t *)fragment->buf; + cp2 = (const int16_t *)reference->buf; + len = fragment->len >> 1; + sum_ri_2 = _sum2(cp2, cp2, len); + sum_aij_ri = _sum2(cp1, cp2, len); + + result = sum_aij_ri / sum_ri_2; + + return PyFloat_FromDouble(result); +} + +/* +** findmax returns the index of the n-sized segment of the input sample +** that contains the most energy. +*/ +/*[clinic input] +audioop.findmax + + fragment: Py_buffer + length: Py_ssize_t + / + +Search fragment for a slice of specified number of samples with maximum energy. +[clinic start generated code]*/ + +static PyObject * +audioop_findmax_impl(PyObject *module, Py_buffer *fragment, + Py_ssize_t length) +/*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/ +{ + const int16_t *cp1; + Py_ssize_t len1; + Py_ssize_t j, best_j; + double aj_m1, aj_lm1; + double result, best_result; + + if (fragment->len & 1) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Strings should be even-sized"); - return NULL; - } - cp1 = (const int16_t *)fragment->buf; - len1 = fragment->len >> 1; - - if (length < 0 || len1 < length) { + return NULL; + } + cp1 = (const int16_t *)fragment->buf; + len1 = fragment->len >> 1; + + if (length < 0 || len1 < length) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Input sample should be longer"); - return NULL; - } - - result = _sum2(cp1, cp1, length); - - best_result = result; - best_j = 0; - - for ( j=1; j<=len1-length; j++) { - aj_m1 = (double)cp1[j-1]; - aj_lm1 = (double)cp1[j+length-1]; - - result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1; - - if ( result > best_result ) { - best_result = result; - best_j = j; - } - - } - - return PyLong_FromSsize_t(best_j); -} - -/*[clinic input] -audioop.avgpp - - fragment: Py_buffer - width: int - / - -Return the average peak-peak value over all samples in the fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/ -{ - Py_ssize_t i; - int prevval, prevextremevalid = 0, prevextreme = 0; - double sum = 0.0; - unsigned int avg; - int diff, prevdiff, nextreme = 0; - + return NULL; + } + + result = _sum2(cp1, cp1, length); + + best_result = result; + best_j = 0; + + for ( j=1; j<=len1-length; j++) { + aj_m1 = (double)cp1[j-1]; + aj_lm1 = (double)cp1[j+length-1]; + + result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1; + + if ( result > best_result ) { + best_result = result; + best_j = j; + } + + } + + return PyLong_FromSsize_t(best_j); +} + +/*[clinic input] +audioop.avgpp + + fragment: Py_buffer + width: int + / + +Return the average peak-peak value over all samples in the fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/ +{ + Py_ssize_t i; + int prevval, prevextremevalid = 0, prevextreme = 0; + double sum = 0.0; + unsigned int avg; + int diff, prevdiff, nextreme = 0; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - if (fragment->len <= width) - return PyLong_FromLong(0); - prevval = GETRAWSAMPLE(width, fragment->buf, 0); - prevdiff = 17; /* Anything != 0, 1 */ - for (i = width; i < fragment->len; i += width) { - int val = GETRAWSAMPLE(width, fragment->buf, i); - if (val != prevval) { - diff = val < prevval; - if (prevdiff == !diff) { - /* Derivative changed sign. Compute difference to last - ** extreme value and remember. - */ - if (prevextremevalid) { - if (prevval < prevextreme) - sum += (double)((unsigned int)prevextreme - - (unsigned int)prevval); - else - sum += (double)((unsigned int)prevval - - (unsigned int)prevextreme); - nextreme++; - } - prevextremevalid = 1; - prevextreme = prevval; - } - prevval = val; - prevdiff = diff; - } - } - if ( nextreme == 0 ) - avg = 0; - else - avg = (unsigned int)(sum / (double)nextreme); - return PyLong_FromUnsignedLong(avg); -} - -/*[clinic input] -audioop.maxpp - - fragment: Py_buffer - width: int - / - -Return the maximum peak-peak value in the sound fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/ -{ - Py_ssize_t i; - int prevval, prevextremevalid = 0, prevextreme = 0; - unsigned int max = 0, extremediff; - int diff, prevdiff; - + return NULL; + if (fragment->len <= width) + return PyLong_FromLong(0); + prevval = GETRAWSAMPLE(width, fragment->buf, 0); + prevdiff = 17; /* Anything != 0, 1 */ + for (i = width; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); + if (val != prevval) { + diff = val < prevval; + if (prevdiff == !diff) { + /* Derivative changed sign. Compute difference to last + ** extreme value and remember. + */ + if (prevextremevalid) { + if (prevval < prevextreme) + sum += (double)((unsigned int)prevextreme - + (unsigned int)prevval); + else + sum += (double)((unsigned int)prevval - + (unsigned int)prevextreme); + nextreme++; + } + prevextremevalid = 1; + prevextreme = prevval; + } + prevval = val; + prevdiff = diff; + } + } + if ( nextreme == 0 ) + avg = 0; + else + avg = (unsigned int)(sum / (double)nextreme); + return PyLong_FromUnsignedLong(avg); +} + +/*[clinic input] +audioop.maxpp + + fragment: Py_buffer + width: int + / + +Return the maximum peak-peak value in the sound fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/ +{ + Py_ssize_t i; + int prevval, prevextremevalid = 0, prevextreme = 0; + unsigned int max = 0, extremediff; + int diff, prevdiff; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - if (fragment->len <= width) - return PyLong_FromLong(0); - prevval = GETRAWSAMPLE(width, fragment->buf, 0); - prevdiff = 17; /* Anything != 0, 1 */ - for (i = width; i < fragment->len; i += width) { - int val = GETRAWSAMPLE(width, fragment->buf, i); - if (val != prevval) { - diff = val < prevval; - if (prevdiff == !diff) { - /* Derivative changed sign. Compute difference to - ** last extreme value and remember. - */ - if (prevextremevalid) { - if (prevval < prevextreme) - extremediff = (unsigned int)prevextreme - - (unsigned int)prevval; - else - extremediff = (unsigned int)prevval - - (unsigned int)prevextreme; - if ( extremediff > max ) - max = extremediff; - } - prevextremevalid = 1; - prevextreme = prevval; - } - prevval = val; - prevdiff = diff; - } - } - return PyLong_FromUnsignedLong(max); -} - -/*[clinic input] -audioop.cross - - fragment: Py_buffer - width: int - / - -Return the number of zero crossings in the fragment passed as an argument. -[clinic start generated code]*/ - -static PyObject * -audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/ -{ - Py_ssize_t i; - int prevval; - Py_ssize_t ncross; - + return NULL; + if (fragment->len <= width) + return PyLong_FromLong(0); + prevval = GETRAWSAMPLE(width, fragment->buf, 0); + prevdiff = 17; /* Anything != 0, 1 */ + for (i = width; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); + if (val != prevval) { + diff = val < prevval; + if (prevdiff == !diff) { + /* Derivative changed sign. Compute difference to + ** last extreme value and remember. + */ + if (prevextremevalid) { + if (prevval < prevextreme) + extremediff = (unsigned int)prevextreme - + (unsigned int)prevval; + else + extremediff = (unsigned int)prevval - + (unsigned int)prevextreme; + if ( extremediff > max ) + max = extremediff; + } + prevextremevalid = 1; + prevextreme = prevval; + } + prevval = val; + prevdiff = diff; + } + } + return PyLong_FromUnsignedLong(max); +} + +/*[clinic input] +audioop.cross + + fragment: Py_buffer + width: int + / + +Return the number of zero crossings in the fragment passed as an argument. +[clinic start generated code]*/ + +static PyObject * +audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/ +{ + Py_ssize_t i; + int prevval; + Py_ssize_t ncross; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - ncross = -1; - prevval = 17; /* Anything <> 0,1 */ - for (i = 0; i < fragment->len; i += width) { - int val = GETRAWSAMPLE(width, fragment->buf, i) < 0; - if (val != prevval) ncross++; - prevval = val; - } - return PyLong_FromSsize_t(ncross); -} - -/*[clinic input] -audioop.mul - - fragment: Py_buffer - width: int - factor: double - / - -Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor. -[clinic start generated code]*/ - -static PyObject * -audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, - double factor) -/*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/ -{ - signed char *ncp; - Py_ssize_t i; - double maxval, minval; - PyObject *rv; - + return NULL; + ncross = -1; + prevval = 17; /* Anything <> 0,1 */ + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i) < 0; + if (val != prevval) ncross++; + prevval = val; + } + return PyLong_FromSsize_t(ncross); +} + +/*[clinic input] +audioop.mul + + fragment: Py_buffer + width: int + factor: double + / + +Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor. +[clinic start generated code]*/ + +static PyObject * +audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, + double factor) +/*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/ +{ + signed char *ncp; + Py_ssize_t i; + double maxval, minval; + PyObject *rv; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - - maxval = (double) maxvals[width]; - minval = (double) minvals[width]; - - rv = PyBytes_FromStringAndSize(NULL, fragment->len); - if (rv == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(rv); - - for (i = 0; i < fragment->len; i += width) { - double val = GETRAWSAMPLE(width, fragment->buf, i); - int ival = fbound(val * factor, minval, maxval); - SETRAWSAMPLE(width, ncp, i, ival); - } - return rv; -} - -/*[clinic input] -audioop.tomono - - fragment: Py_buffer - width: int - lfactor: double - rfactor: double - / - -Convert a stereo fragment to a mono fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, - double lfactor, double rfactor) -/*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/ -{ - signed char *cp, *ncp; - Py_ssize_t len, i; - double maxval, minval; - PyObject *rv; - - cp = fragment->buf; - len = fragment->len; + return NULL; + + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; + + rv = PyBytes_FromStringAndSize(NULL, fragment->len); + if (rv == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(rv); + + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); + int ival = fbound(val * factor, minval, maxval); + SETRAWSAMPLE(width, ncp, i, ival); + } + return rv; +} + +/*[clinic input] +audioop.tomono + + fragment: Py_buffer + width: int + lfactor: double + rfactor: double + / + +Convert a stereo fragment to a mono fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, + double lfactor, double rfactor) +/*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/ +{ + signed char *cp, *ncp; + Py_ssize_t len, i; + double maxval, minval; + PyObject *rv; + + cp = fragment->buf; + len = fragment->len; if (!audioop_check_parameters(module, len, width)) - return NULL; - if (((len / width) & 1) != 0) { + return NULL; + if (((len / width) & 1) != 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "not a whole number of frames"); - return NULL; - } - - maxval = (double) maxvals[width]; - minval = (double) minvals[width]; - - rv = PyBytes_FromStringAndSize(NULL, len/2); - if (rv == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(rv); - - for (i = 0; i < len; i += width*2) { - double val1 = GETRAWSAMPLE(width, cp, i); - double val2 = GETRAWSAMPLE(width, cp, i + width); - double val = val1 * lfactor + val2 * rfactor; - int ival = fbound(val, minval, maxval); - SETRAWSAMPLE(width, ncp, i/2, ival); - } - return rv; -} - -/*[clinic input] -audioop.tostereo - - fragment: Py_buffer - width: int - lfactor: double - rfactor: double - / - -Generate a stereo fragment from a mono fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, - double lfactor, double rfactor) -/*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/ -{ - signed char *ncp; - Py_ssize_t i; - double maxval, minval; - PyObject *rv; - + return NULL; + } + + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; + + rv = PyBytes_FromStringAndSize(NULL, len/2); + if (rv == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(rv); + + for (i = 0; i < len; i += width*2) { + double val1 = GETRAWSAMPLE(width, cp, i); + double val2 = GETRAWSAMPLE(width, cp, i + width); + double val = val1 * lfactor + val2 * rfactor; + int ival = fbound(val, minval, maxval); + SETRAWSAMPLE(width, ncp, i/2, ival); + } + return rv; +} + +/*[clinic input] +audioop.tostereo + + fragment: Py_buffer + width: int + lfactor: double + rfactor: double + / + +Generate a stereo fragment from a mono fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, + double lfactor, double rfactor) +/*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/ +{ + signed char *ncp; + Py_ssize_t i; + double maxval, minval; + PyObject *rv; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - - maxval = (double) maxvals[width]; - minval = (double) minvals[width]; - - if (fragment->len > PY_SSIZE_T_MAX/2) { - PyErr_SetString(PyExc_MemoryError, - "not enough memory for output buffer"); - return NULL; - } - - rv = PyBytes_FromStringAndSize(NULL, fragment->len*2); - if (rv == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(rv); - - for (i = 0; i < fragment->len; i += width) { - double val = GETRAWSAMPLE(width, fragment->buf, i); - int val1 = fbound(val * lfactor, minval, maxval); - int val2 = fbound(val * rfactor, minval, maxval); - SETRAWSAMPLE(width, ncp, i*2, val1); - SETRAWSAMPLE(width, ncp, i*2 + width, val2); - } - return rv; -} - -/*[clinic input] -audioop.add - - fragment1: Py_buffer - fragment2: Py_buffer - width: int - / - -Return a fragment which is the addition of the two samples passed as parameters. -[clinic start generated code]*/ - -static PyObject * -audioop_add_impl(PyObject *module, Py_buffer *fragment1, - Py_buffer *fragment2, int width) -/*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/ -{ - signed char *ncp; - Py_ssize_t i; - int minval, maxval, newval; - PyObject *rv; - + return NULL; + + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; + + if (fragment->len > PY_SSIZE_T_MAX/2) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return NULL; + } + + rv = PyBytes_FromStringAndSize(NULL, fragment->len*2); + if (rv == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(rv); + + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); + int val1 = fbound(val * lfactor, minval, maxval); + int val2 = fbound(val * rfactor, minval, maxval); + SETRAWSAMPLE(width, ncp, i*2, val1); + SETRAWSAMPLE(width, ncp, i*2 + width, val2); + } + return rv; +} + +/*[clinic input] +audioop.add + + fragment1: Py_buffer + fragment2: Py_buffer + width: int + / + +Return a fragment which is the addition of the two samples passed as parameters. +[clinic start generated code]*/ + +static PyObject * +audioop_add_impl(PyObject *module, Py_buffer *fragment1, + Py_buffer *fragment2, int width) +/*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/ +{ + signed char *ncp; + Py_ssize_t i; + int minval, maxval, newval; + PyObject *rv; + if (!audioop_check_parameters(module, fragment1->len, width)) - return NULL; - if (fragment1->len != fragment2->len) { + return NULL; + if (fragment1->len != fragment2->len) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Lengths should be the same"); - return NULL; - } - - maxval = maxvals[width]; - minval = minvals[width]; - - rv = PyBytes_FromStringAndSize(NULL, fragment1->len); - if (rv == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(rv); - - for (i = 0; i < fragment1->len; i += width) { - int val1 = GETRAWSAMPLE(width, fragment1->buf, i); - int val2 = GETRAWSAMPLE(width, fragment2->buf, i); - - if (width < 4) { - newval = val1 + val2; - /* truncate in case of overflow */ - if (newval > maxval) - newval = maxval; - else if (newval < minval) - newval = minval; - } - else { - double fval = (double)val1 + (double)val2; - /* truncate in case of overflow */ - newval = fbound(fval, minval, maxval); - } - - SETRAWSAMPLE(width, ncp, i, newval); - } - return rv; -} - -/*[clinic input] -audioop.bias - - fragment: Py_buffer - width: int - bias: int - / - -Return a fragment that is the original fragment with a bias added to each sample. -[clinic start generated code]*/ - -static PyObject * -audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias) -/*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/ -{ - signed char *ncp; - Py_ssize_t i; - unsigned int val = 0, mask; - PyObject *rv; - + return NULL; + } + + maxval = maxvals[width]; + minval = minvals[width]; + + rv = PyBytes_FromStringAndSize(NULL, fragment1->len); + if (rv == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(rv); + + for (i = 0; i < fragment1->len; i += width) { + int val1 = GETRAWSAMPLE(width, fragment1->buf, i); + int val2 = GETRAWSAMPLE(width, fragment2->buf, i); + + if (width < 4) { + newval = val1 + val2; + /* truncate in case of overflow */ + if (newval > maxval) + newval = maxval; + else if (newval < minval) + newval = minval; + } + else { + double fval = (double)val1 + (double)val2; + /* truncate in case of overflow */ + newval = fbound(fval, minval, maxval); + } + + SETRAWSAMPLE(width, ncp, i, newval); + } + return rv; +} + +/*[clinic input] +audioop.bias + + fragment: Py_buffer + width: int + bias: int + / + +Return a fragment that is the original fragment with a bias added to each sample. +[clinic start generated code]*/ + +static PyObject * +audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias) +/*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/ +{ + signed char *ncp; + Py_ssize_t i; + unsigned int val = 0, mask; + PyObject *rv; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - - rv = PyBytes_FromStringAndSize(NULL, fragment->len); - if (rv == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(rv); - - mask = masks[width]; - - for (i = 0; i < fragment->len; i += width) { - if (width == 1) - val = GETINTX(unsigned char, fragment->buf, i); - else if (width == 2) - val = GETINTX(uint16_t, fragment->buf, i); - else if (width == 3) - val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu; - else { - assert(width == 4); - val = GETINTX(uint32_t, fragment->buf, i); - } - - val += (unsigned int)bias; - /* wrap around in case of overflow */ - val &= mask; - - if (width == 1) - SETINTX(unsigned char, ncp, i, val); - else if (width == 2) - SETINTX(uint16_t, ncp, i, val); - else if (width == 3) - SETINT24(ncp, i, (int)val); - else { - assert(width == 4); - SETINTX(uint32_t, ncp, i, val); - } - } - return rv; -} - -/*[clinic input] -audioop.reverse - - fragment: Py_buffer - width: int - / - -Reverse the samples in a fragment and returns the modified fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/ -{ - unsigned char *ncp; - Py_ssize_t i; - PyObject *rv; - + return NULL; + + rv = PyBytes_FromStringAndSize(NULL, fragment->len); + if (rv == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(rv); + + mask = masks[width]; + + for (i = 0; i < fragment->len; i += width) { + if (width == 1) + val = GETINTX(unsigned char, fragment->buf, i); + else if (width == 2) + val = GETINTX(uint16_t, fragment->buf, i); + else if (width == 3) + val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu; + else { + assert(width == 4); + val = GETINTX(uint32_t, fragment->buf, i); + } + + val += (unsigned int)bias; + /* wrap around in case of overflow */ + val &= mask; + + if (width == 1) + SETINTX(unsigned char, ncp, i, val); + else if (width == 2) + SETINTX(uint16_t, ncp, i, val); + else if (width == 3) + SETINT24(ncp, i, (int)val); + else { + assert(width == 4); + SETINTX(uint32_t, ncp, i, val); + } + } + return rv; +} + +/*[clinic input] +audioop.reverse + + fragment: Py_buffer + width: int + / + +Reverse the samples in a fragment and returns the modified fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/ +{ + unsigned char *ncp; + Py_ssize_t i; + PyObject *rv; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - - rv = PyBytes_FromStringAndSize(NULL, fragment->len); - if (rv == NULL) - return NULL; - ncp = (unsigned char *)PyBytes_AsString(rv); - - for (i = 0; i < fragment->len; i += width) { - int val = GETRAWSAMPLE(width, fragment->buf, i); - SETRAWSAMPLE(width, ncp, fragment->len - i - width, val); - } - return rv; -} - -/*[clinic input] -audioop.byteswap - - fragment: Py_buffer - width: int - / - -Convert big-endian samples to little-endian and vice versa. -[clinic start generated code]*/ - -static PyObject * -audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/ -{ - unsigned char *ncp; - Py_ssize_t i; - PyObject *rv; - + return NULL; + + rv = PyBytes_FromStringAndSize(NULL, fragment->len); + if (rv == NULL) + return NULL; + ncp = (unsigned char *)PyBytes_AsString(rv); + + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); + SETRAWSAMPLE(width, ncp, fragment->len - i - width, val); + } + return rv; +} + +/*[clinic input] +audioop.byteswap + + fragment: Py_buffer + width: int + / + +Convert big-endian samples to little-endian and vice versa. +[clinic start generated code]*/ + +static PyObject * +audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/ +{ + unsigned char *ncp; + Py_ssize_t i; + PyObject *rv; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - - rv = PyBytes_FromStringAndSize(NULL, fragment->len); - if (rv == NULL) - return NULL; - ncp = (unsigned char *)PyBytes_AsString(rv); - - for (i = 0; i < fragment->len; i += width) { - int j; - for (j = 0; j < width; j++) - ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j]; - } - return rv; -} - -/*[clinic input] -audioop.lin2lin - - fragment: Py_buffer - width: int - newwidth: int - / - -Convert samples between 1-, 2-, 3- and 4-byte formats. -[clinic start generated code]*/ - -static PyObject * -audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width, - int newwidth) -/*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/ -{ - unsigned char *ncp; - Py_ssize_t i, j; - PyObject *rv; - + return NULL; + + rv = PyBytes_FromStringAndSize(NULL, fragment->len); + if (rv == NULL) + return NULL; + ncp = (unsigned char *)PyBytes_AsString(rv); + + for (i = 0; i < fragment->len; i += width) { + int j; + for (j = 0; j < width; j++) + ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j]; + } + return rv; +} + +/*[clinic input] +audioop.lin2lin + + fragment: Py_buffer + width: int + newwidth: int + / + +Convert samples between 1-, 2-, 3- and 4-byte formats. +[clinic start generated code]*/ + +static PyObject * +audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width, + int newwidth) +/*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/ +{ + unsigned char *ncp; + Py_ssize_t i, j; + PyObject *rv; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; + return NULL; if (!audioop_check_size(module, newwidth)) - return NULL; - - if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) { - PyErr_SetString(PyExc_MemoryError, - "not enough memory for output buffer"); - return NULL; - } - rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth); - if (rv == NULL) - return NULL; - ncp = (unsigned char *)PyBytes_AsString(rv); - - for (i = j = 0; i < fragment->len; i += width, j += newwidth) { - int val = GETSAMPLE32(width, fragment->buf, i); - SETSAMPLE32(newwidth, ncp, j, val); - } - return rv; -} - -static int -gcd(int a, int b) -{ - while (b > 0) { - int tmp = a % b; - a = b; - b = tmp; - } - return a; -} - -/*[clinic input] -audioop.ratecv - - fragment: Py_buffer - width: int - nchannels: int - inrate: int - outrate: int - state: object - weightA: int = 1 - weightB: int = 0 - / - -Convert the frame rate of the input fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, - int nchannels, int inrate, int outrate, PyObject *state, - int weightA, int weightB) -/*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/ -{ - char *cp, *ncp; - Py_ssize_t len; - int chan, d, *prev_i, *cur_i, cur_o; - PyObject *samps, *str, *rv = NULL, *channel; - int bytes_per_frame; - + return NULL; + + if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return NULL; + } + rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth); + if (rv == NULL) + return NULL; + ncp = (unsigned char *)PyBytes_AsString(rv); + + for (i = j = 0; i < fragment->len; i += width, j += newwidth) { + int val = GETSAMPLE32(width, fragment->buf, i); + SETSAMPLE32(newwidth, ncp, j, val); + } + return rv; +} + +static int +gcd(int a, int b) +{ + while (b > 0) { + int tmp = a % b; + a = b; + b = tmp; + } + return a; +} + +/*[clinic input] +audioop.ratecv + + fragment: Py_buffer + width: int + nchannels: int + inrate: int + outrate: int + state: object + weightA: int = 1 + weightB: int = 0 + / + +Convert the frame rate of the input fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, + int nchannels, int inrate, int outrate, PyObject *state, + int weightA, int weightB) +/*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/ +{ + char *cp, *ncp; + Py_ssize_t len; + int chan, d, *prev_i, *cur_i, cur_o; + PyObject *samps, *str, *rv = NULL, *channel; + int bytes_per_frame; + if (!audioop_check_size(module, width)) - return NULL; - if (nchannels < 1) { + return NULL; + if (nchannels < 1) { PyErr_SetString(get_audioop_state(module)->AudioopError, "# of channels should be >= 1"); - return NULL; - } - if (width > INT_MAX / nchannels) { - /* This overflow test is rigorously correct because - both multiplicands are >= 1. Use the argument names - from the docs for the error msg. */ - PyErr_SetString(PyExc_OverflowError, - "width * nchannels too big for a C int"); - return NULL; - } - bytes_per_frame = width * nchannels; - if (weightA < 1 || weightB < 0) { + return NULL; + } + if (width > INT_MAX / nchannels) { + /* This overflow test is rigorously correct because + both multiplicands are >= 1. Use the argument names + from the docs for the error msg. */ + PyErr_SetString(PyExc_OverflowError, + "width * nchannels too big for a C int"); + return NULL; + } + bytes_per_frame = width * nchannels; + if (weightA < 1 || weightB < 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, - "weightA should be >= 1, weightB should be >= 0"); - return NULL; - } - assert(fragment->len >= 0); - if (fragment->len % bytes_per_frame != 0) { + "weightA should be >= 1, weightB should be >= 0"); + return NULL; + } + assert(fragment->len >= 0); + if (fragment->len % bytes_per_frame != 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "not a whole number of frames"); - return NULL; - } - if (inrate <= 0 || outrate <= 0) { + return NULL; + } + if (inrate <= 0 || outrate <= 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "sampling rate not > 0"); - return NULL; - } - /* divide inrate and outrate by their greatest common divisor */ - d = gcd(inrate, outrate); - inrate /= d; - outrate /= d; - /* divide weightA and weightB by their greatest common divisor */ - d = gcd(weightA, weightB); - weightA /= d; - weightB /= d; - - if ((size_t)nchannels > SIZE_MAX/sizeof(int)) { - PyErr_SetString(PyExc_MemoryError, - "not enough memory for output buffer"); - return NULL; - } - prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); - cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); - if (prev_i == NULL || cur_i == NULL) { - (void) PyErr_NoMemory(); - goto exit; - } - - len = fragment->len / bytes_per_frame; /* # of frames */ - - if (state == Py_None) { - d = -outrate; - for (chan = 0; chan < nchannels; chan++) - prev_i[chan] = cur_i[chan] = 0; - } - else { - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); - goto exit; - } - if (!PyArg_ParseTuple(state, - "iO!;ratecv(): illegal state argument", - &d, &PyTuple_Type, &samps)) - goto exit; - if (PyTuple_Size(samps) != nchannels) { + return NULL; + } + /* divide inrate and outrate by their greatest common divisor */ + d = gcd(inrate, outrate); + inrate /= d; + outrate /= d; + /* divide weightA and weightB by their greatest common divisor */ + d = gcd(weightA, weightB); + weightA /= d; + weightB /= d; + + if ((size_t)nchannels > SIZE_MAX/sizeof(int)) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return NULL; + } + prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); + cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); + if (prev_i == NULL || cur_i == NULL) { + (void) PyErr_NoMemory(); + goto exit; + } + + len = fragment->len / bytes_per_frame; /* # of frames */ + + if (state == Py_None) { + d = -outrate; + for (chan = 0; chan < nchannels; chan++) + prev_i[chan] = cur_i[chan] = 0; + } + else { + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); + goto exit; + } + if (!PyArg_ParseTuple(state, + "iO!;ratecv(): illegal state argument", + &d, &PyTuple_Type, &samps)) + goto exit; + if (PyTuple_Size(samps) != nchannels) { PyErr_SetString(get_audioop_state(module)->AudioopError, - "illegal state argument"); - goto exit; - } - for (chan = 0; chan < nchannels; chan++) { - channel = PyTuple_GetItem(samps, chan); - if (!PyTuple_Check(channel)) { - PyErr_SetString(PyExc_TypeError, - "ratecv(): illegal state argument"); - goto exit; - } - if (!PyArg_ParseTuple(channel, - "ii;ratecv(): illegal state argument", - &prev_i[chan], &cur_i[chan])) - { - goto exit; - } - } - } - - /* str <- Space for the output buffer. */ - if (len == 0) - str = PyBytes_FromStringAndSize(NULL, 0); - else { - /* There are len input frames, so we need (mathematically) - ceiling(len*outrate/inrate) output frames, and each frame - requires bytes_per_frame bytes. Computing this - without spurious overflow is the challenge; we can - settle for a reasonable upper bound, though, in this - case ceiling(len/inrate) * outrate. */ - - /* compute ceiling(len/inrate) without overflow */ - Py_ssize_t q = 1 + (len - 1) / inrate; - if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame) - str = NULL; - else - str = PyBytes_FromStringAndSize(NULL, - q * outrate * bytes_per_frame); - } - if (str == NULL) { - PyErr_SetString(PyExc_MemoryError, - "not enough memory for output buffer"); - goto exit; - } - ncp = PyBytes_AsString(str); - cp = fragment->buf; - - for (;;) { - while (d < 0) { - if (len == 0) { - samps = PyTuple_New(nchannels); - if (samps == NULL) - goto exit; - for (chan = 0; chan < nchannels; chan++) - PyTuple_SetItem(samps, chan, - Py_BuildValue("(ii)", - prev_i[chan], - cur_i[chan])); - if (PyErr_Occurred()) - goto exit; - /* We have checked before that the length - * of the string fits into int. */ - len = (Py_ssize_t)(ncp - PyBytes_AsString(str)); - rv = PyBytes_FromStringAndSize - (PyBytes_AsString(str), len); - Py_DECREF(str); - str = rv; - if (str == NULL) - goto exit; - rv = Py_BuildValue("(O(iO))", str, d, samps); - Py_DECREF(samps); - Py_DECREF(str); - goto exit; /* return rv */ - } - for (chan = 0; chan < nchannels; chan++) { - prev_i[chan] = cur_i[chan]; - cur_i[chan] = GETSAMPLE32(width, cp, 0); - cp += width; - /* implements a simple digital filter */ - cur_i[chan] = (int)( - ((double)weightA * (double)cur_i[chan] + - (double)weightB * (double)prev_i[chan]) / - ((double)weightA + (double)weightB)); - } - len--; - d += outrate; - } - while (d >= 0) { - for (chan = 0; chan < nchannels; chan++) { - cur_o = (int)(((double)prev_i[chan] * (double)d + - (double)cur_i[chan] * (double)(outrate - d)) / - (double)outrate); - SETSAMPLE32(width, ncp, 0, cur_o); - ncp += width; - } - d -= inrate; - } - } - exit: - PyMem_Free(prev_i); - PyMem_Free(cur_i); - return rv; -} - -/*[clinic input] -audioop.lin2ulaw - - fragment: Py_buffer - width: int - / - -Convert samples in the audio fragment to u-LAW encoding. -[clinic start generated code]*/ - -static PyObject * -audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/ -{ - unsigned char *ncp; - Py_ssize_t i; - PyObject *rv; - + "illegal state argument"); + goto exit; + } + for (chan = 0; chan < nchannels; chan++) { + channel = PyTuple_GetItem(samps, chan); + if (!PyTuple_Check(channel)) { + PyErr_SetString(PyExc_TypeError, + "ratecv(): illegal state argument"); + goto exit; + } + if (!PyArg_ParseTuple(channel, + "ii;ratecv(): illegal state argument", + &prev_i[chan], &cur_i[chan])) + { + goto exit; + } + } + } + + /* str <- Space for the output buffer. */ + if (len == 0) + str = PyBytes_FromStringAndSize(NULL, 0); + else { + /* There are len input frames, so we need (mathematically) + ceiling(len*outrate/inrate) output frames, and each frame + requires bytes_per_frame bytes. Computing this + without spurious overflow is the challenge; we can + settle for a reasonable upper bound, though, in this + case ceiling(len/inrate) * outrate. */ + + /* compute ceiling(len/inrate) without overflow */ + Py_ssize_t q = 1 + (len - 1) / inrate; + if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame) + str = NULL; + else + str = PyBytes_FromStringAndSize(NULL, + q * outrate * bytes_per_frame); + } + if (str == NULL) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + goto exit; + } + ncp = PyBytes_AsString(str); + cp = fragment->buf; + + for (;;) { + while (d < 0) { + if (len == 0) { + samps = PyTuple_New(nchannels); + if (samps == NULL) + goto exit; + for (chan = 0; chan < nchannels; chan++) + PyTuple_SetItem(samps, chan, + Py_BuildValue("(ii)", + prev_i[chan], + cur_i[chan])); + if (PyErr_Occurred()) + goto exit; + /* We have checked before that the length + * of the string fits into int. */ + len = (Py_ssize_t)(ncp - PyBytes_AsString(str)); + rv = PyBytes_FromStringAndSize + (PyBytes_AsString(str), len); + Py_DECREF(str); + str = rv; + if (str == NULL) + goto exit; + rv = Py_BuildValue("(O(iO))", str, d, samps); + Py_DECREF(samps); + Py_DECREF(str); + goto exit; /* return rv */ + } + for (chan = 0; chan < nchannels; chan++) { + prev_i[chan] = cur_i[chan]; + cur_i[chan] = GETSAMPLE32(width, cp, 0); + cp += width; + /* implements a simple digital filter */ + cur_i[chan] = (int)( + ((double)weightA * (double)cur_i[chan] + + (double)weightB * (double)prev_i[chan]) / + ((double)weightA + (double)weightB)); + } + len--; + d += outrate; + } + while (d >= 0) { + for (chan = 0; chan < nchannels; chan++) { + cur_o = (int)(((double)prev_i[chan] * (double)d + + (double)cur_i[chan] * (double)(outrate - d)) / + (double)outrate); + SETSAMPLE32(width, ncp, 0, cur_o); + ncp += width; + } + d -= inrate; + } + } + exit: + PyMem_Free(prev_i); + PyMem_Free(cur_i); + return rv; +} + +/*[clinic input] +audioop.lin2ulaw + + fragment: Py_buffer + width: int + / + +Convert samples in the audio fragment to u-LAW encoding. +[clinic start generated code]*/ + +static PyObject * +audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/ +{ + unsigned char *ncp; + Py_ssize_t i; + PyObject *rv; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - - rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); - if (rv == NULL) - return NULL; - ncp = (unsigned char *)PyBytes_AsString(rv); - - for (i = 0; i < fragment->len; i += width) { - int val = GETSAMPLE32(width, fragment->buf, i); - *ncp++ = st_14linear2ulaw(val >> 18); - } - return rv; -} - -/*[clinic input] -audioop.ulaw2lin - - fragment: Py_buffer - width: int - / - -Convert sound fragments in u-LAW encoding to linearly encoded sound fragments. -[clinic start generated code]*/ - -static PyObject * -audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/ -{ - unsigned char *cp; - signed char *ncp; - Py_ssize_t i; - PyObject *rv; - + return NULL; + + rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); + if (rv == NULL) + return NULL; + ncp = (unsigned char *)PyBytes_AsString(rv); + + for (i = 0; i < fragment->len; i += width) { + int val = GETSAMPLE32(width, fragment->buf, i); + *ncp++ = st_14linear2ulaw(val >> 18); + } + return rv; +} + +/*[clinic input] +audioop.ulaw2lin + + fragment: Py_buffer + width: int + / + +Convert sound fragments in u-LAW encoding to linearly encoded sound fragments. +[clinic start generated code]*/ + +static PyObject * +audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/ +{ + unsigned char *cp; + signed char *ncp; + Py_ssize_t i; + PyObject *rv; + if (!audioop_check_size(module, width)) - return NULL; - - if (fragment->len > PY_SSIZE_T_MAX/width) { - PyErr_SetString(PyExc_MemoryError, - "not enough memory for output buffer"); - return NULL; - } - rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); - if (rv == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(rv); - - cp = fragment->buf; - for (i = 0; i < fragment->len*width; i += width) { - int val = st_ulaw2linear16(*cp++) << 16; - SETSAMPLE32(width, ncp, i, val); - } - return rv; -} - -/*[clinic input] -audioop.lin2alaw - - fragment: Py_buffer - width: int - / - -Convert samples in the audio fragment to a-LAW encoding. -[clinic start generated code]*/ - -static PyObject * -audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/ -{ - unsigned char *ncp; - Py_ssize_t i; - PyObject *rv; - + return NULL; + + if (fragment->len > PY_SSIZE_T_MAX/width) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return NULL; + } + rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); + if (rv == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(rv); + + cp = fragment->buf; + for (i = 0; i < fragment->len*width; i += width) { + int val = st_ulaw2linear16(*cp++) << 16; + SETSAMPLE32(width, ncp, i, val); + } + return rv; +} + +/*[clinic input] +audioop.lin2alaw + + fragment: Py_buffer + width: int + / + +Convert samples in the audio fragment to a-LAW encoding. +[clinic start generated code]*/ + +static PyObject * +audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/ +{ + unsigned char *ncp; + Py_ssize_t i; + PyObject *rv; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - - rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); - if (rv == NULL) - return NULL; - ncp = (unsigned char *)PyBytes_AsString(rv); - - for (i = 0; i < fragment->len; i += width) { - int val = GETSAMPLE32(width, fragment->buf, i); - *ncp++ = st_linear2alaw(val >> 19); - } - return rv; -} - -/*[clinic input] -audioop.alaw2lin - - fragment: Py_buffer - width: int - / - -Convert sound fragments in a-LAW encoding to linearly encoded sound fragments. -[clinic start generated code]*/ - -static PyObject * -audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) -/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/ -{ - unsigned char *cp; - signed char *ncp; - Py_ssize_t i; - int val; - PyObject *rv; - + return NULL; + + rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); + if (rv == NULL) + return NULL; + ncp = (unsigned char *)PyBytes_AsString(rv); + + for (i = 0; i < fragment->len; i += width) { + int val = GETSAMPLE32(width, fragment->buf, i); + *ncp++ = st_linear2alaw(val >> 19); + } + return rv; +} + +/*[clinic input] +audioop.alaw2lin + + fragment: Py_buffer + width: int + / + +Convert sound fragments in a-LAW encoding to linearly encoded sound fragments. +[clinic start generated code]*/ + +static PyObject * +audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/ +{ + unsigned char *cp; + signed char *ncp; + Py_ssize_t i; + int val; + PyObject *rv; + if (!audioop_check_size(module, width)) - return NULL; - - if (fragment->len > PY_SSIZE_T_MAX/width) { - PyErr_SetString(PyExc_MemoryError, - "not enough memory for output buffer"); - return NULL; - } - rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); - if (rv == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(rv); - cp = fragment->buf; - - for (i = 0; i < fragment->len*width; i += width) { - val = st_alaw2linear16(*cp++) << 16; - SETSAMPLE32(width, ncp, i, val); - } - return rv; -} - -/*[clinic input] -audioop.lin2adpcm - - fragment: Py_buffer - width: int - state: object - / - -Convert samples to 4 bit Intel/DVI ADPCM encoding. -[clinic start generated code]*/ - -static PyObject * -audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, - PyObject *state) -/*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/ -{ - signed char *ncp; - Py_ssize_t i; - int step, valpred, delta, - index, sign, vpdiff, diff; - PyObject *rv = NULL, *str; - int outputbuffer = 0, bufferstep; - + return NULL; + + if (fragment->len > PY_SSIZE_T_MAX/width) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return NULL; + } + rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); + if (rv == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(rv); + cp = fragment->buf; + + for (i = 0; i < fragment->len*width; i += width) { + val = st_alaw2linear16(*cp++) << 16; + SETSAMPLE32(width, ncp, i, val); + } + return rv; +} + +/*[clinic input] +audioop.lin2adpcm + + fragment: Py_buffer + width: int + state: object + / + +Convert samples to 4 bit Intel/DVI ADPCM encoding. +[clinic start generated code]*/ + +static PyObject * +audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, + PyObject *state) +/*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/ +{ + signed char *ncp; + Py_ssize_t i; + int step, valpred, delta, + index, sign, vpdiff, diff; + PyObject *rv = NULL, *str; + int outputbuffer = 0, bufferstep; + if (!audioop_check_parameters(module, fragment->len, width)) - return NULL; - - /* Decode state, should have (value, step) */ - if ( state == Py_None ) { - /* First time, it seems. Set defaults */ - valpred = 0; - index = 0; - } - else if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); - return NULL; - } - else if (!PyArg_ParseTuple(state, "ii;lin2adpcm(): illegal state argument", - &valpred, &index)) - { - return NULL; - } - else if (valpred >= 0x8000 || valpred < -0x8000 || - (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) { - PyErr_SetString(PyExc_ValueError, "bad state"); - return NULL; - } - - str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2)); - if (str == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(str); - - step = stepsizeTable[index]; - bufferstep = 1; - - for (i = 0; i < fragment->len; i += width) { - int val = GETSAMPLE32(width, fragment->buf, i) >> 16; - - /* Step 1 - compute difference with previous value */ - if (val < valpred) { - diff = valpred - val; - sign = 8; - } - else { - diff = val - valpred; - sign = 0; - } - - /* Step 2 - Divide and clamp */ - /* Note: - ** This code *approximately* computes: - ** delta = diff*4/step; - ** vpdiff = (delta+0.5)*step/4; - ** but in shift step bits are dropped. The net result of this - ** is that even if you have fast mul/div hardware you cannot - ** put it to good use since the fixup would be too expensive. - */ - delta = 0; - vpdiff = (step >> 3); - - if ( diff >= step ) { - delta = 4; - diff -= step; - vpdiff += step; - } - step >>= 1; - if ( diff >= step ) { - delta |= 2; - diff -= step; - vpdiff += step; - } - step >>= 1; - if ( diff >= step ) { - delta |= 1; - vpdiff += step; - } - - /* Step 3 - Update previous value */ - if ( sign ) - valpred -= vpdiff; - else - valpred += vpdiff; - - /* Step 4 - Clamp previous value to 16 bits */ - if ( valpred > 32767 ) - valpred = 32767; - else if ( valpred < -32768 ) - valpred = -32768; - - /* Step 5 - Assemble value, update index and step values */ - delta |= sign; - - index += indexTable[delta]; - if ( index < 0 ) index = 0; - if ( index > 88 ) index = 88; - step = stepsizeTable[index]; - - /* Step 6 - Output value */ - if ( bufferstep ) { - outputbuffer = (delta << 4) & 0xf0; - } else { - *ncp++ = (delta & 0x0f) | outputbuffer; - } - bufferstep = !bufferstep; - } - rv = Py_BuildValue("(O(ii))", str, valpred, index); - Py_DECREF(str); - return rv; -} - -/*[clinic input] -audioop.adpcm2lin - - fragment: Py_buffer - width: int - state: object - / - -Decode an Intel/DVI ADPCM coded fragment to a linear fragment. -[clinic start generated code]*/ - -static PyObject * -audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, - PyObject *state) -/*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/ -{ - signed char *cp; - signed char *ncp; - Py_ssize_t i, outlen; - int valpred, step, delta, index, sign, vpdiff; - PyObject *rv, *str; - int inputbuffer = 0, bufferstep; - + return NULL; + + /* Decode state, should have (value, step) */ + if ( state == Py_None ) { + /* First time, it seems. Set defaults */ + valpred = 0; + index = 0; + } + else if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); + return NULL; + } + else if (!PyArg_ParseTuple(state, "ii;lin2adpcm(): illegal state argument", + &valpred, &index)) + { + return NULL; + } + else if (valpred >= 0x8000 || valpred < -0x8000 || + (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) { + PyErr_SetString(PyExc_ValueError, "bad state"); + return NULL; + } + + str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2)); + if (str == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(str); + + step = stepsizeTable[index]; + bufferstep = 1; + + for (i = 0; i < fragment->len; i += width) { + int val = GETSAMPLE32(width, fragment->buf, i) >> 16; + + /* Step 1 - compute difference with previous value */ + if (val < valpred) { + diff = valpred - val; + sign = 8; + } + else { + diff = val - valpred; + sign = 0; + } + + /* Step 2 - Divide and clamp */ + /* Note: + ** This code *approximately* computes: + ** delta = diff*4/step; + ** vpdiff = (delta+0.5)*step/4; + ** but in shift step bits are dropped. The net result of this + ** is that even if you have fast mul/div hardware you cannot + ** put it to good use since the fixup would be too expensive. + */ + delta = 0; + vpdiff = (step >> 3); + + if ( diff >= step ) { + delta = 4; + diff -= step; + vpdiff += step; + } + step >>= 1; + if ( diff >= step ) { + delta |= 2; + diff -= step; + vpdiff += step; + } + step >>= 1; + if ( diff >= step ) { + delta |= 1; + vpdiff += step; + } + + /* Step 3 - Update previous value */ + if ( sign ) + valpred -= vpdiff; + else + valpred += vpdiff; + + /* Step 4 - Clamp previous value to 16 bits */ + if ( valpred > 32767 ) + valpred = 32767; + else if ( valpred < -32768 ) + valpred = -32768; + + /* Step 5 - Assemble value, update index and step values */ + delta |= sign; + + index += indexTable[delta]; + if ( index < 0 ) index = 0; + if ( index > 88 ) index = 88; + step = stepsizeTable[index]; + + /* Step 6 - Output value */ + if ( bufferstep ) { + outputbuffer = (delta << 4) & 0xf0; + } else { + *ncp++ = (delta & 0x0f) | outputbuffer; + } + bufferstep = !bufferstep; + } + rv = Py_BuildValue("(O(ii))", str, valpred, index); + Py_DECREF(str); + return rv; +} + +/*[clinic input] +audioop.adpcm2lin + + fragment: Py_buffer + width: int + state: object + / + +Decode an Intel/DVI ADPCM coded fragment to a linear fragment. +[clinic start generated code]*/ + +static PyObject * +audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, + PyObject *state) +/*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/ +{ + signed char *cp; + signed char *ncp; + Py_ssize_t i, outlen; + int valpred, step, delta, index, sign, vpdiff; + PyObject *rv, *str; + int inputbuffer = 0, bufferstep; + if (!audioop_check_size(module, width)) - return NULL; - - /* Decode state, should have (value, step) */ - if ( state == Py_None ) { - /* First time, it seems. Set defaults */ - valpred = 0; - index = 0; - } - else if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); - return NULL; - } - else if (!PyArg_ParseTuple(state, "ii;adpcm2lin(): illegal state argument", - &valpred, &index)) - { - return NULL; - } - else if (valpred >= 0x8000 || valpred < -0x8000 || - (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) { - PyErr_SetString(PyExc_ValueError, "bad state"); - return NULL; - } - - if (fragment->len > (PY_SSIZE_T_MAX/2)/width) { - PyErr_SetString(PyExc_MemoryError, - "not enough memory for output buffer"); - return NULL; - } - outlen = fragment->len*width*2; - str = PyBytes_FromStringAndSize(NULL, outlen); - if (str == NULL) - return NULL; - ncp = (signed char *)PyBytes_AsString(str); - cp = fragment->buf; - - step = stepsizeTable[index]; - bufferstep = 0; - - for (i = 0; i < outlen; i += width) { - /* Step 1 - get the delta value and compute next index */ - if ( bufferstep ) { - delta = inputbuffer & 0xf; - } else { - inputbuffer = *cp++; - delta = (inputbuffer >> 4) & 0xf; - } - - bufferstep = !bufferstep; - - /* Step 2 - Find new index value (for later) */ - index += indexTable[delta]; - if ( index < 0 ) index = 0; - if ( index > 88 ) index = 88; - - /* Step 3 - Separate sign and magnitude */ - sign = delta & 8; - delta = delta & 7; - - /* Step 4 - Compute difference and new predicted value */ - /* - ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment - ** in adpcm_coder. - */ - vpdiff = step >> 3; - if ( delta & 4 ) vpdiff += step; - if ( delta & 2 ) vpdiff += step>>1; - if ( delta & 1 ) vpdiff += step>>2; - - if ( sign ) - valpred -= vpdiff; - else - valpred += vpdiff; - - /* Step 5 - clamp output value */ - if ( valpred > 32767 ) - valpred = 32767; - else if ( valpred < -32768 ) - valpred = -32768; - - /* Step 6 - Update step value */ - step = stepsizeTable[index]; - - /* Step 6 - Output value */ - SETSAMPLE32(width, ncp, i, valpred << 16); - } - - rv = Py_BuildValue("(O(ii))", str, valpred, index); - Py_DECREF(str); - return rv; -} - -#include "clinic/audioop.c.h" - -static PyMethodDef audioop_methods[] = { - AUDIOOP_MAX_METHODDEF - AUDIOOP_MINMAX_METHODDEF - AUDIOOP_AVG_METHODDEF - AUDIOOP_MAXPP_METHODDEF - AUDIOOP_AVGPP_METHODDEF - AUDIOOP_RMS_METHODDEF - AUDIOOP_FINDFIT_METHODDEF - AUDIOOP_FINDMAX_METHODDEF - AUDIOOP_FINDFACTOR_METHODDEF - AUDIOOP_CROSS_METHODDEF - AUDIOOP_MUL_METHODDEF - AUDIOOP_ADD_METHODDEF - AUDIOOP_BIAS_METHODDEF - AUDIOOP_ULAW2LIN_METHODDEF - AUDIOOP_LIN2ULAW_METHODDEF - AUDIOOP_ALAW2LIN_METHODDEF - AUDIOOP_LIN2ALAW_METHODDEF - AUDIOOP_LIN2LIN_METHODDEF - AUDIOOP_ADPCM2LIN_METHODDEF - AUDIOOP_LIN2ADPCM_METHODDEF - AUDIOOP_TOMONO_METHODDEF - AUDIOOP_TOSTEREO_METHODDEF - AUDIOOP_GETSAMPLE_METHODDEF - AUDIOOP_REVERSE_METHODDEF - AUDIOOP_BYTESWAP_METHODDEF - AUDIOOP_RATECV_METHODDEF - { 0, 0 } -}; - + return NULL; + + /* Decode state, should have (value, step) */ + if ( state == Py_None ) { + /* First time, it seems. Set defaults */ + valpred = 0; + index = 0; + } + else if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); + return NULL; + } + else if (!PyArg_ParseTuple(state, "ii;adpcm2lin(): illegal state argument", + &valpred, &index)) + { + return NULL; + } + else if (valpred >= 0x8000 || valpred < -0x8000 || + (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) { + PyErr_SetString(PyExc_ValueError, "bad state"); + return NULL; + } + + if (fragment->len > (PY_SSIZE_T_MAX/2)/width) { + PyErr_SetString(PyExc_MemoryError, + "not enough memory for output buffer"); + return NULL; + } + outlen = fragment->len*width*2; + str = PyBytes_FromStringAndSize(NULL, outlen); + if (str == NULL) + return NULL; + ncp = (signed char *)PyBytes_AsString(str); + cp = fragment->buf; + + step = stepsizeTable[index]; + bufferstep = 0; + + for (i = 0; i < outlen; i += width) { + /* Step 1 - get the delta value and compute next index */ + if ( bufferstep ) { + delta = inputbuffer & 0xf; + } else { + inputbuffer = *cp++; + delta = (inputbuffer >> 4) & 0xf; + } + + bufferstep = !bufferstep; + + /* Step 2 - Find new index value (for later) */ + index += indexTable[delta]; + if ( index < 0 ) index = 0; + if ( index > 88 ) index = 88; + + /* Step 3 - Separate sign and magnitude */ + sign = delta & 8; + delta = delta & 7; + + /* Step 4 - Compute difference and new predicted value */ + /* + ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment + ** in adpcm_coder. + */ + vpdiff = step >> 3; + if ( delta & 4 ) vpdiff += step; + if ( delta & 2 ) vpdiff += step>>1; + if ( delta & 1 ) vpdiff += step>>2; + + if ( sign ) + valpred -= vpdiff; + else + valpred += vpdiff; + + /* Step 5 - clamp output value */ + if ( valpred > 32767 ) + valpred = 32767; + else if ( valpred < -32768 ) + valpred = -32768; + + /* Step 6 - Update step value */ + step = stepsizeTable[index]; + + /* Step 6 - Output value */ + SETSAMPLE32(width, ncp, i, valpred << 16); + } + + rv = Py_BuildValue("(O(ii))", str, valpred, index); + Py_DECREF(str); + return rv; +} + +#include "clinic/audioop.c.h" + +static PyMethodDef audioop_methods[] = { + AUDIOOP_MAX_METHODDEF + AUDIOOP_MINMAX_METHODDEF + AUDIOOP_AVG_METHODDEF + AUDIOOP_MAXPP_METHODDEF + AUDIOOP_AVGPP_METHODDEF + AUDIOOP_RMS_METHODDEF + AUDIOOP_FINDFIT_METHODDEF + AUDIOOP_FINDMAX_METHODDEF + AUDIOOP_FINDFACTOR_METHODDEF + AUDIOOP_CROSS_METHODDEF + AUDIOOP_MUL_METHODDEF + AUDIOOP_ADD_METHODDEF + AUDIOOP_BIAS_METHODDEF + AUDIOOP_ULAW2LIN_METHODDEF + AUDIOOP_LIN2ULAW_METHODDEF + AUDIOOP_ALAW2LIN_METHODDEF + AUDIOOP_LIN2ALAW_METHODDEF + AUDIOOP_LIN2LIN_METHODDEF + AUDIOOP_ADPCM2LIN_METHODDEF + AUDIOOP_LIN2ADPCM_METHODDEF + AUDIOOP_TOMONO_METHODDEF + AUDIOOP_TOSTEREO_METHODDEF + AUDIOOP_GETSAMPLE_METHODDEF + AUDIOOP_REVERSE_METHODDEF + AUDIOOP_BYTESWAP_METHODDEF + AUDIOOP_RATECV_METHODDEF + { 0, 0 } +}; + static int audioop_traverse(PyObject *module, visitproc visit, void *arg) { @@ -1929,7 +1929,7 @@ audioop_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->AudioopError); return 0; } - + static int audioop_clear(PyObject *module) { @@ -1967,20 +1967,20 @@ static PyModuleDef_Slot audioop_slots[] = { {0, NULL} }; -static struct PyModuleDef audioopmodule = { - PyModuleDef_HEAD_INIT, - "audioop", - NULL, +static struct PyModuleDef audioopmodule = { + PyModuleDef_HEAD_INIT, + "audioop", + NULL, sizeof(audioop_state), - audioop_methods, + audioop_methods, audioop_slots, audioop_traverse, audioop_clear, audioop_free -}; - -PyMODINIT_FUNC -PyInit_audioop(void) -{ +}; + +PyMODINIT_FUNC +PyInit_audioop(void) +{ return PyModuleDef_Init(&audioopmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/binascii.c b/contrib/tools/python3/src/Modules/binascii.c index 1f3248b6049..f32bd966230 100644 --- a/contrib/tools/python3/src/Modules/binascii.c +++ b/contrib/tools/python3/src/Modules/binascii.c @@ -1,149 +1,149 @@ -/* -** Routines to represent binary data in ASCII and vice-versa -** -** This module currently supports the following encodings: -** uuencode: -** each line encodes 45 bytes (except possibly the last) -** First char encodes (binary) length, rest data -** each char encodes 6 bits, as follows: -** binary: 01234567 abcdefgh ijklmnop -** ascii: 012345 67abcd efghij klmnop -** ASCII encoding method is "excess-space": 000000 is encoded as ' ', etc. -** short binary data is zero-extended (so the bits are always in the -** right place), this does *not* reflect in the length. -** base64: -** Line breaks are insignificant, but lines are at most 76 chars -** each char encodes 6 bits, in similar order as uucode/hqx. Encoding -** is done via a table. -** Short binary data is filled (in ASCII) with '='. -** hqx: -** File starts with introductory text, real data starts and ends -** with colons. -** Data consists of three similar parts: info, datafork, resourcefork. -** Each part is protected (at the end) with a 16-bit crc -** The binary data is run-length encoded, and then ascii-fied: -** binary: 01234567 abcdefgh ijklmnop -** ascii: 012345 67abcd efghij klmnop -** ASCII encoding is table-driven, see the code. -** Short binary data results in the runt ascii-byte being output with -** the bits in the right place. -** -** While I was reading dozens of programs that encode or decode the formats -** here (documentation? hihi:-) I have formulated Jansen's Observation: -** -** Programs that encode binary data in ASCII are written in -** such a style that they are as unreadable as possible. Devices used -** include unnecessary global variables, burying important tables -** in unrelated sourcefiles, putting functions in include files, -** using seemingly-descriptive variable names for different purposes, -** calls to empty subroutines and a host of others. -** -** I have attempted to break with this tradition, but I guess that that -** does make the performance sub-optimal. Oh well, too bad... -** -** Jack Jansen, CWI, July 1995. -** -** Added support for quoted-printable encoding, based on rfc 1521 et al -** quoted-printable encoding specifies that non printable characters (anything -** below 32 and above 126) be encoded as =XX where XX is the hexadecimal value -** of the character. It also specifies some other behavior to enable 8bit data -** in a mail message with little difficulty (maximum line sizes, protecting -** some cases of whitespace, etc). -** -** Brandon Long, September 2001. -*/ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" -#include "pystrhex.h" -#ifdef USE_ZLIB_CRC32 -#include "zlib.h" -#endif - +/* +** Routines to represent binary data in ASCII and vice-versa +** +** This module currently supports the following encodings: +** uuencode: +** each line encodes 45 bytes (except possibly the last) +** First char encodes (binary) length, rest data +** each char encodes 6 bits, as follows: +** binary: 01234567 abcdefgh ijklmnop +** ascii: 012345 67abcd efghij klmnop +** ASCII encoding method is "excess-space": 000000 is encoded as ' ', etc. +** short binary data is zero-extended (so the bits are always in the +** right place), this does *not* reflect in the length. +** base64: +** Line breaks are insignificant, but lines are at most 76 chars +** each char encodes 6 bits, in similar order as uucode/hqx. Encoding +** is done via a table. +** Short binary data is filled (in ASCII) with '='. +** hqx: +** File starts with introductory text, real data starts and ends +** with colons. +** Data consists of three similar parts: info, datafork, resourcefork. +** Each part is protected (at the end) with a 16-bit crc +** The binary data is run-length encoded, and then ascii-fied: +** binary: 01234567 abcdefgh ijklmnop +** ascii: 012345 67abcd efghij klmnop +** ASCII encoding is table-driven, see the code. +** Short binary data results in the runt ascii-byte being output with +** the bits in the right place. +** +** While I was reading dozens of programs that encode or decode the formats +** here (documentation? hihi:-) I have formulated Jansen's Observation: +** +** Programs that encode binary data in ASCII are written in +** such a style that they are as unreadable as possible. Devices used +** include unnecessary global variables, burying important tables +** in unrelated sourcefiles, putting functions in include files, +** using seemingly-descriptive variable names for different purposes, +** calls to empty subroutines and a host of others. +** +** I have attempted to break with this tradition, but I guess that that +** does make the performance sub-optimal. Oh well, too bad... +** +** Jack Jansen, CWI, July 1995. +** +** Added support for quoted-printable encoding, based on rfc 1521 et al +** quoted-printable encoding specifies that non printable characters (anything +** below 32 and above 126) be encoded as =XX where XX is the hexadecimal value +** of the character. It also specifies some other behavior to enable 8bit data +** in a mail message with little difficulty (maximum line sizes, protecting +** some cases of whitespace, etc). +** +** Brandon Long, September 2001. +*/ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "pystrhex.h" +#ifdef USE_ZLIB_CRC32 +#include "zlib.h" +#endif + typedef struct binascii_state { PyObject *Error; PyObject *Incomplete; } binascii_state; - + static binascii_state * get_binascii_state(PyObject *module) { return (binascii_state *)PyModule_GetState(module); } -/* -** hqx lookup table, ascii->binary. -*/ - -#define RUNCHAR 0x90 - -#define DONE 0x7F -#define SKIP 0x7E -#define FAIL 0x7D - -static const unsigned char table_a2b_hqx[256] = { -/* ^@ ^A ^B ^C ^D ^E ^F ^G */ -/* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, -/* \b \t \n ^K ^L \r ^N ^O */ -/* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL, -/* ^P ^Q ^R ^S ^T ^U ^V ^W */ -/* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, -/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */ -/* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, -/* ! " # $ % & ' */ -/* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, -/* ( ) * + , - . / */ -/* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL, -/* 0 1 2 3 4 5 6 7 */ -/* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL, -/* 8 9 : ; < = > ? */ -/* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL, -/* @ A B C D E F G */ -/* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, -/* H I J K L M N O */ -/* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL, -/* P Q R S T U V W */ -/*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL, -/* X Y Z [ \ ] ^ _ */ -/*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL, -/* ` a b c d e f g */ -/*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL, -/* h i j k l m n o */ -/*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL, -/* p q r s t u v w */ -/*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL, -/* x y z { | } ~ ^? */ -/*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, -/*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, - FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, -}; - -static const unsigned char table_b2a_hqx[] = -"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; - +/* +** hqx lookup table, ascii->binary. +*/ + +#define RUNCHAR 0x90 + +#define DONE 0x7F +#define SKIP 0x7E +#define FAIL 0x7D + +static const unsigned char table_a2b_hqx[256] = { +/* ^@ ^A ^B ^C ^D ^E ^F ^G */ +/* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, +/* \b \t \n ^K ^L \r ^N ^O */ +/* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL, +/* ^P ^Q ^R ^S ^T ^U ^V ^W */ +/* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, +/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */ +/* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, +/* ! " # $ % & ' */ +/* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, +/* ( ) * + , - . / */ +/* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL, +/* 0 1 2 3 4 5 6 7 */ +/* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL, +/* 8 9 : ; < = > ? */ +/* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL, +/* @ A B C D E F G */ +/* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, +/* H I J K L M N O */ +/* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL, +/* P Q R S T U V W */ +/*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL, +/* X Y Z [ \ ] ^ _ */ +/*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL, +/* ` a b c d e f g */ +/*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL, +/* h i j k l m n o */ +/*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL, +/* p q r s t u v w */ +/*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL, +/* x y z { | } ~ ^? */ +/*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, +/*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, + FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, +}; + +static const unsigned char table_b2a_hqx[] = +"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; + static const unsigned char table_a2b_base64[] = { - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */ - -1, 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,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */ + -1, 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,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, @@ -154,333 +154,333 @@ static const unsigned char table_a2b_base64[] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -}; - -#define BASE64_PAD '=' - -/* Max binary chunk size; limited only by available memory */ -#define BASE64_MAXBIN ((PY_SSIZE_T_MAX - 3) / 2) - -static const unsigned char table_b2a_base64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - - -static const unsigned short crctab_hqx[256] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, -}; - -/*[clinic input] -module binascii -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=de89fb46bcaf3fec]*/ - -/*[python input] - -class ascii_buffer_converter(CConverter): - type = 'Py_buffer' - converter = 'ascii_buffer_converter' - impl_by_reference = True - c_default = "{NULL, NULL}" - - def cleanup(self): - name = self.name - return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"]) - -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=3eb7b63610da92cd]*/ - -static int -ascii_buffer_converter(PyObject *arg, Py_buffer *buf) -{ - if (arg == NULL) { - PyBuffer_Release(buf); - return 1; - } - if (PyUnicode_Check(arg)) { - if (PyUnicode_READY(arg) < 0) - return 0; - if (!PyUnicode_IS_ASCII(arg)) { - PyErr_SetString(PyExc_ValueError, - "string argument should contain only ASCII characters"); - return 0; - } - assert(PyUnicode_KIND(arg) == PyUnicode_1BYTE_KIND); - buf->buf = (void *) PyUnicode_1BYTE_DATA(arg); - buf->len = PyUnicode_GET_LENGTH(arg); - buf->obj = NULL; - return 1; - } - if (PyObject_GetBuffer(arg, buf, PyBUF_SIMPLE) != 0) { - PyErr_Format(PyExc_TypeError, - "argument should be bytes, buffer or ASCII string, " - "not '%.100s'", Py_TYPE(arg)->tp_name); - return 0; - } - if (!PyBuffer_IsContiguous(buf, 'C')) { - PyErr_Format(PyExc_TypeError, - "argument should be a contiguous buffer, " - "not '%.100s'", Py_TYPE(arg)->tp_name); - PyBuffer_Release(buf); - return 0; - } - return Py_CLEANUP_SUPPORTED; -} - -#include "clinic/binascii.c.h" - -/*[clinic input] -binascii.a2b_uu - - data: ascii_buffer - / - -Decode a line of uuencoded data. -[clinic start generated code]*/ - -static PyObject * -binascii_a2b_uu_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=e027f8e0b0598742 input=7cafeaf73df63d1c]*/ -{ - const unsigned char *ascii_data; - unsigned char *bin_data; - int leftbits = 0; - unsigned char this_ch; - unsigned int leftchar = 0; - PyObject *rv; - Py_ssize_t ascii_len, bin_len; +}; + +#define BASE64_PAD '=' + +/* Max binary chunk size; limited only by available memory */ +#define BASE64_MAXBIN ((PY_SSIZE_T_MAX - 3) / 2) + +static const unsigned char table_b2a_base64[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + + +static const unsigned short crctab_hqx[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, +}; + +/*[clinic input] +module binascii +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=de89fb46bcaf3fec]*/ + +/*[python input] + +class ascii_buffer_converter(CConverter): + type = 'Py_buffer' + converter = 'ascii_buffer_converter' + impl_by_reference = True + c_default = "{NULL, NULL}" + + def cleanup(self): + name = self.name + return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"]) + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3eb7b63610da92cd]*/ + +static int +ascii_buffer_converter(PyObject *arg, Py_buffer *buf) +{ + if (arg == NULL) { + PyBuffer_Release(buf); + return 1; + } + if (PyUnicode_Check(arg)) { + if (PyUnicode_READY(arg) < 0) + return 0; + if (!PyUnicode_IS_ASCII(arg)) { + PyErr_SetString(PyExc_ValueError, + "string argument should contain only ASCII characters"); + return 0; + } + assert(PyUnicode_KIND(arg) == PyUnicode_1BYTE_KIND); + buf->buf = (void *) PyUnicode_1BYTE_DATA(arg); + buf->len = PyUnicode_GET_LENGTH(arg); + buf->obj = NULL; + return 1; + } + if (PyObject_GetBuffer(arg, buf, PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, + "argument should be bytes, buffer or ASCII string, " + "not '%.100s'", Py_TYPE(arg)->tp_name); + return 0; + } + if (!PyBuffer_IsContiguous(buf, 'C')) { + PyErr_Format(PyExc_TypeError, + "argument should be a contiguous buffer, " + "not '%.100s'", Py_TYPE(arg)->tp_name); + PyBuffer_Release(buf); + return 0; + } + return Py_CLEANUP_SUPPORTED; +} + +#include "clinic/binascii.c.h" + +/*[clinic input] +binascii.a2b_uu + + data: ascii_buffer + / + +Decode a line of uuencoded data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_uu_impl(PyObject *module, Py_buffer *data) +/*[clinic end generated code: output=e027f8e0b0598742 input=7cafeaf73df63d1c]*/ +{ + const unsigned char *ascii_data; + unsigned char *bin_data; + int leftbits = 0; + unsigned char this_ch; + unsigned int leftchar = 0; + PyObject *rv; + Py_ssize_t ascii_len, bin_len; binascii_state *state; - - ascii_data = data->buf; - ascii_len = data->len; - - assert(ascii_len >= 0); - - /* First byte: binary data length (in bytes) */ - bin_len = (*ascii_data++ - ' ') & 077; - ascii_len--; - - /* Allocate the buffer */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) - return NULL; - bin_data = (unsigned char *)PyBytes_AS_STRING(rv); - - for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) { - /* XXX is it really best to add NULs if there's no more data */ - this_ch = (ascii_len > 0) ? *ascii_data : 0; - if ( this_ch == '\n' || this_ch == '\r' || ascii_len <= 0) { - /* - ** Whitespace. Assume some spaces got eaten at - ** end-of-line. (We check this later) - */ - this_ch = 0; - } else { - /* Check the character for legality - ** The 64 in stead of the expected 63 is because - ** there are a few uuencodes out there that use - ** '`' as zero instead of space. - */ - if ( this_ch < ' ' || this_ch > (' ' + 64)) { + + ascii_data = data->buf; + ascii_len = data->len; + + assert(ascii_len >= 0); + + /* First byte: binary data length (in bytes) */ + bin_len = (*ascii_data++ - ' ') & 077; + ascii_len--; + + /* Allocate the buffer */ + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) + return NULL; + bin_data = (unsigned char *)PyBytes_AS_STRING(rv); + + for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) { + /* XXX is it really best to add NULs if there's no more data */ + this_ch = (ascii_len > 0) ? *ascii_data : 0; + if ( this_ch == '\n' || this_ch == '\r' || ascii_len <= 0) { + /* + ** Whitespace. Assume some spaces got eaten at + ** end-of-line. (We check this later) + */ + this_ch = 0; + } else { + /* Check the character for legality + ** The 64 in stead of the expected 63 is because + ** there are a few uuencodes out there that use + ** '`' as zero instead of space. + */ + if ( this_ch < ' ' || this_ch > (' ' + 64)) { state = PyModule_GetState(module); if (state == NULL) { return NULL; } PyErr_SetString(state->Error, "Illegal char"); - Py_DECREF(rv); - return NULL; - } - this_ch = (this_ch - ' ') & 077; - } - /* - ** Shift it in on the low end, and see if there's - ** a byte ready for output. - */ - leftchar = (leftchar << 6) | (this_ch); - leftbits += 6; - if ( leftbits >= 8 ) { - leftbits -= 8; - *bin_data++ = (leftchar >> leftbits) & 0xff; - leftchar &= ((1 << leftbits) - 1); - bin_len--; - } - } - /* - ** Finally, check that if there's anything left on the line - ** that it's whitespace only. - */ - while( ascii_len-- > 0 ) { - this_ch = *ascii_data++; - /* Extra '`' may be written as padding in some cases */ - if ( this_ch != ' ' && this_ch != ' '+64 && - this_ch != '\n' && this_ch != '\r' ) { + Py_DECREF(rv); + return NULL; + } + this_ch = (this_ch - ' ') & 077; + } + /* + ** Shift it in on the low end, and see if there's + ** a byte ready for output. + */ + leftchar = (leftchar << 6) | (this_ch); + leftbits += 6; + if ( leftbits >= 8 ) { + leftbits -= 8; + *bin_data++ = (leftchar >> leftbits) & 0xff; + leftchar &= ((1 << leftbits) - 1); + bin_len--; + } + } + /* + ** Finally, check that if there's anything left on the line + ** that it's whitespace only. + */ + while( ascii_len-- > 0 ) { + this_ch = *ascii_data++; + /* Extra '`' may be written as padding in some cases */ + if ( this_ch != ' ' && this_ch != ' '+64 && + this_ch != '\n' && this_ch != '\r' ) { state = PyModule_GetState(module); if (state == NULL) { return NULL; } PyErr_SetString(state->Error, "Trailing garbage"); - Py_DECREF(rv); - return NULL; - } - } - return rv; -} - -/*[clinic input] -binascii.b2a_uu - - data: Py_buffer - / - * - backtick: bool(accept={int}) = False - -Uuencode line of data. -[clinic start generated code]*/ - -static PyObject * -binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick) -/*[clinic end generated code: output=b1b99de62d9bbeb8 input=b26bc8d32b6ed2f6]*/ -{ - unsigned char *ascii_data; - const unsigned char *bin_data; - int leftbits = 0; - unsigned char this_ch; - unsigned int leftchar = 0; + Py_DECREF(rv); + return NULL; + } + } + return rv; +} + +/*[clinic input] +binascii.b2a_uu + + data: Py_buffer + / + * + backtick: bool(accept={int}) = False + +Uuencode line of data. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick) +/*[clinic end generated code: output=b1b99de62d9bbeb8 input=b26bc8d32b6ed2f6]*/ +{ + unsigned char *ascii_data; + const unsigned char *bin_data; + int leftbits = 0; + unsigned char this_ch; + unsigned int leftchar = 0; binascii_state *state; - Py_ssize_t bin_len, out_len; - _PyBytesWriter writer; - - _PyBytesWriter_Init(&writer); - bin_data = data->buf; - bin_len = data->len; - if ( bin_len > 45 ) { - /* The 45 is a limit that appears in all uuencode's */ + Py_ssize_t bin_len, out_len; + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); + bin_data = data->buf; + bin_len = data->len; + if ( bin_len > 45 ) { + /* The 45 is a limit that appears in all uuencode's */ state = PyModule_GetState(module); if (state == NULL) { return NULL; } PyErr_SetString(state->Error, "At most 45 bytes at once"); - return NULL; - } - - /* We're lazy and allocate to much (fixed up later) */ - out_len = 2 + (bin_len + 2) / 3 * 4; - ascii_data = _PyBytesWriter_Alloc(&writer, out_len); - if (ascii_data == NULL) - return NULL; - - /* Store the length */ - if (backtick && !bin_len) - *ascii_data++ = '`'; - else - *ascii_data++ = ' ' + (unsigned char)bin_len; - - for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) { - /* Shift the data (or padding) into our buffer */ - if ( bin_len > 0 ) /* Data */ - leftchar = (leftchar << 8) | *bin_data; - else /* Padding */ - leftchar <<= 8; - leftbits += 8; - - /* See if there are 6-bit groups ready */ - while ( leftbits >= 6 ) { - this_ch = (leftchar >> (leftbits-6)) & 0x3f; - leftbits -= 6; - if (backtick && !this_ch) - *ascii_data++ = '`'; - else - *ascii_data++ = this_ch + ' '; - } - } - *ascii_data++ = '\n'; /* Append a courtesy newline */ - - return _PyBytesWriter_Finish(&writer, ascii_data); -} - -/*[clinic input] -binascii.a2b_base64 - - data: ascii_buffer - / - -Decode a line of base64 data. -[clinic start generated code]*/ - -static PyObject * -binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=0628223f19fd3f9b input=5872acf6e1cac243]*/ -{ + return NULL; + } + + /* We're lazy and allocate to much (fixed up later) */ + out_len = 2 + (bin_len + 2) / 3 * 4; + ascii_data = _PyBytesWriter_Alloc(&writer, out_len); + if (ascii_data == NULL) + return NULL; + + /* Store the length */ + if (backtick && !bin_len) + *ascii_data++ = '`'; + else + *ascii_data++ = ' ' + (unsigned char)bin_len; + + for( ; bin_len > 0 || leftbits != 0 ; bin_len--, bin_data++ ) { + /* Shift the data (or padding) into our buffer */ + if ( bin_len > 0 ) /* Data */ + leftchar = (leftchar << 8) | *bin_data; + else /* Padding */ + leftchar <<= 8; + leftbits += 8; + + /* See if there are 6-bit groups ready */ + while ( leftbits >= 6 ) { + this_ch = (leftchar >> (leftbits-6)) & 0x3f; + leftbits -= 6; + if (backtick && !this_ch) + *ascii_data++ = '`'; + else + *ascii_data++ = this_ch + ' '; + } + } + *ascii_data++ = '\n'; /* Append a courtesy newline */ + + return _PyBytesWriter_Finish(&writer, ascii_data); +} + +/*[clinic input] +binascii.a2b_base64 + + data: ascii_buffer + / + +Decode a line of base64 data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) +/*[clinic end generated code: output=0628223f19fd3f9b input=5872acf6e1cac243]*/ +{ assert(data->len >= 0); - + const unsigned char *ascii_data = data->buf; size_t ascii_len = data->len; - + /* Allocate the buffer */ Py_ssize_t bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ _PyBytesWriter writer; - _PyBytesWriter_Init(&writer); + _PyBytesWriter_Init(&writer); unsigned char *bin_data = _PyBytesWriter_Alloc(&writer, bin_len); - if (bin_data == NULL) - return NULL; + if (bin_data == NULL) + return NULL; unsigned char *bin_data_start = bin_data; - + int quad_pos = 0; unsigned char leftchar = 0; int pads = 0; for (size_t i = 0; i < ascii_len; i++) { unsigned char this_ch = ascii_data[i]; - - /* Check for pad sequences and ignore - ** the invalid ones. - */ - if (this_ch == BASE64_PAD) { + + /* Check for pad sequences and ignore + ** the invalid ones. + */ + if (this_ch == BASE64_PAD) { if (quad_pos >= 2 && quad_pos + ++pads >= 4) { - /* A pad sequence means no more input. - ** We've already interpreted the data - ** from the quad at this point. - */ + /* A pad sequence means no more input. + ** We've already interpreted the data + ** from the quad at this point. + */ goto done; - } + } continue; - } - + } + this_ch = table_a2b_base64[this_ch]; if (this_ch >= 64) { - continue; + continue; } pads = 0; - + switch (quad_pos) { case 0: quad_pos = 1; @@ -501,670 +501,670 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) *bin_data++ = (leftchar << 6) | (this_ch); leftchar = 0; break; - } - } - + } + } + if (quad_pos != 0) { binascii_state *state = PyModule_GetState(module); if (state == NULL) { /* error already set, from PyModule_GetState */ } else if (quad_pos == 1) { - /* - ** There is exactly one extra valid, non-padding, base64 character. - ** This is an invalid length, as there is no possible input that - ** could encoded into such a base64 string. - */ + /* + ** There is exactly one extra valid, non-padding, base64 character. + ** This is an invalid length, as there is no possible input that + ** could encoded into such a base64 string. + */ PyErr_Format(state->Error, - "Invalid base64-encoded string: " + "Invalid base64-encoded string: " "number of data characters (%zd) cannot be 1 more " - "than a multiple of 4", - (bin_data - bin_data_start) / 3 * 4 + 1); - } else { + "than a multiple of 4", + (bin_data - bin_data_start) / 3 * 4 + 1); + } else { PyErr_SetString(state->Error, "Incorrect padding"); - } - _PyBytesWriter_Dealloc(&writer); - return NULL; - } - + } + _PyBytesWriter_Dealloc(&writer); + return NULL; + } + done: - return _PyBytesWriter_Finish(&writer, bin_data); -} - - -/*[clinic input] -binascii.b2a_base64 - - data: Py_buffer - / - * - newline: bool(accept={int}) = True - -Base64-code line of data. -[clinic start generated code]*/ - -static PyObject * -binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline) -/*[clinic end generated code: output=4ad62c8e8485d3b3 input=6083dac5777fa45d]*/ -{ - unsigned char *ascii_data; - const unsigned char *bin_data; - int leftbits = 0; - unsigned char this_ch; - unsigned int leftchar = 0; - Py_ssize_t bin_len, out_len; - _PyBytesWriter writer; + return _PyBytesWriter_Finish(&writer, bin_data); +} + + +/*[clinic input] +binascii.b2a_base64 + + data: Py_buffer + / + * + newline: bool(accept={int}) = True + +Base64-code line of data. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline) +/*[clinic end generated code: output=4ad62c8e8485d3b3 input=6083dac5777fa45d]*/ +{ + unsigned char *ascii_data; + const unsigned char *bin_data; + int leftbits = 0; + unsigned char this_ch; + unsigned int leftchar = 0; + Py_ssize_t bin_len, out_len; + _PyBytesWriter writer; binascii_state *state; - - bin_data = data->buf; - bin_len = data->len; - _PyBytesWriter_Init(&writer); - - assert(bin_len >= 0); - - if ( bin_len > BASE64_MAXBIN ) { + + bin_data = data->buf; + bin_len = data->len; + _PyBytesWriter_Init(&writer); + + assert(bin_len >= 0); + + if ( bin_len > BASE64_MAXBIN ) { state = PyModule_GetState(module); if (state == NULL) { return NULL; } PyErr_SetString(state->Error, "Too much data for base64 line"); - return NULL; - } - - /* We're lazy and allocate too much (fixed up later). - "+2" leaves room for up to two pad characters. - Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ - out_len = bin_len*2 + 2; - if (newline) - out_len++; - ascii_data = _PyBytesWriter_Alloc(&writer, out_len); - if (ascii_data == NULL) - return NULL; - - for( ; bin_len > 0 ; bin_len--, bin_data++ ) { - /* Shift the data into our buffer */ - leftchar = (leftchar << 8) | *bin_data; - leftbits += 8; - - /* See if there are 6-bit groups ready */ - while ( leftbits >= 6 ) { - this_ch = (leftchar >> (leftbits-6)) & 0x3f; - leftbits -= 6; - *ascii_data++ = table_b2a_base64[this_ch]; - } - } - if ( leftbits == 2 ) { - *ascii_data++ = table_b2a_base64[(leftchar&3) << 4]; - *ascii_data++ = BASE64_PAD; - *ascii_data++ = BASE64_PAD; - } else if ( leftbits == 4 ) { - *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2]; - *ascii_data++ = BASE64_PAD; - } - if (newline) - *ascii_data++ = '\n'; /* Append a courtesy newline */ - - return _PyBytesWriter_Finish(&writer, ascii_data); -} - -/*[clinic input] -binascii.a2b_hqx - - data: ascii_buffer - / - -Decode .hqx coding. -[clinic start generated code]*/ - -static PyObject * -binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=4d6d8c54d54ea1c1 input=0d914c680e0eed55]*/ -{ + return NULL; + } + + /* We're lazy and allocate too much (fixed up later). + "+2" leaves room for up to two pad characters. + Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ + out_len = bin_len*2 + 2; + if (newline) + out_len++; + ascii_data = _PyBytesWriter_Alloc(&writer, out_len); + if (ascii_data == NULL) + return NULL; + + for( ; bin_len > 0 ; bin_len--, bin_data++ ) { + /* Shift the data into our buffer */ + leftchar = (leftchar << 8) | *bin_data; + leftbits += 8; + + /* See if there are 6-bit groups ready */ + while ( leftbits >= 6 ) { + this_ch = (leftchar >> (leftbits-6)) & 0x3f; + leftbits -= 6; + *ascii_data++ = table_b2a_base64[this_ch]; + } + } + if ( leftbits == 2 ) { + *ascii_data++ = table_b2a_base64[(leftchar&3) << 4]; + *ascii_data++ = BASE64_PAD; + *ascii_data++ = BASE64_PAD; + } else if ( leftbits == 4 ) { + *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2]; + *ascii_data++ = BASE64_PAD; + } + if (newline) + *ascii_data++ = '\n'; /* Append a courtesy newline */ + + return _PyBytesWriter_Finish(&writer, ascii_data); +} + +/*[clinic input] +binascii.a2b_hqx + + data: ascii_buffer + / + +Decode .hqx coding. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) +/*[clinic end generated code: output=4d6d8c54d54ea1c1 input=0d914c680e0eed55]*/ +{ if (PyErr_WarnEx(PyExc_DeprecationWarning, "binascii.a2b_hqx() is deprecated", 1) < 0) { return NULL; } - const unsigned char *ascii_data; - unsigned char *bin_data; - int leftbits = 0; - unsigned char this_ch; - unsigned int leftchar = 0; - PyObject *res; - Py_ssize_t len; - int done = 0; - _PyBytesWriter writer; + const unsigned char *ascii_data; + unsigned char *bin_data; + int leftbits = 0; + unsigned char this_ch; + unsigned int leftchar = 0; + PyObject *res; + Py_ssize_t len; + int done = 0; + _PyBytesWriter writer; binascii_state *state; - - ascii_data = data->buf; - len = data->len; - _PyBytesWriter_Init(&writer); - - assert(len >= 0); - - if (len > PY_SSIZE_T_MAX - 2) - return PyErr_NoMemory(); - - /* Allocate a string that is too big (fixed later) - Add two to the initial length to prevent interning which - would preclude subsequent resizing. */ - bin_data = _PyBytesWriter_Alloc(&writer, len + 2); - if (bin_data == NULL) - return NULL; - - for( ; len > 0 ; len--, ascii_data++ ) { - /* Get the byte and look it up */ - this_ch = table_a2b_hqx[*ascii_data]; - if ( this_ch == SKIP ) - continue; - if ( this_ch == FAIL ) { + + ascii_data = data->buf; + len = data->len; + _PyBytesWriter_Init(&writer); + + assert(len >= 0); + + if (len > PY_SSIZE_T_MAX - 2) + return PyErr_NoMemory(); + + /* Allocate a string that is too big (fixed later) + Add two to the initial length to prevent interning which + would preclude subsequent resizing. */ + bin_data = _PyBytesWriter_Alloc(&writer, len + 2); + if (bin_data == NULL) + return NULL; + + for( ; len > 0 ; len--, ascii_data++ ) { + /* Get the byte and look it up */ + this_ch = table_a2b_hqx[*ascii_data]; + if ( this_ch == SKIP ) + continue; + if ( this_ch == FAIL ) { state = PyModule_GetState(module); if (state == NULL) { return NULL; } PyErr_SetString(state->Error, "Illegal char"); - _PyBytesWriter_Dealloc(&writer); - return NULL; - } - if ( this_ch == DONE ) { - /* The terminating colon */ - done = 1; - break; - } - - /* Shift it into the buffer and see if any bytes are ready */ - leftchar = (leftchar << 6) | (this_ch); - leftbits += 6; - if ( leftbits >= 8 ) { - leftbits -= 8; - *bin_data++ = (leftchar >> leftbits) & 0xff; - leftchar &= ((1 << leftbits) - 1); - } - } - - if ( leftbits && !done ) { + _PyBytesWriter_Dealloc(&writer); + return NULL; + } + if ( this_ch == DONE ) { + /* The terminating colon */ + done = 1; + break; + } + + /* Shift it into the buffer and see if any bytes are ready */ + leftchar = (leftchar << 6) | (this_ch); + leftbits += 6; + if ( leftbits >= 8 ) { + leftbits -= 8; + *bin_data++ = (leftchar >> leftbits) & 0xff; + leftchar &= ((1 << leftbits) - 1); + } + } + + if ( leftbits && !done ) { state = PyModule_GetState(module); if (state == NULL) { return NULL; } PyErr_SetString(state->Incomplete, - "String has incomplete number of bytes"); - _PyBytesWriter_Dealloc(&writer); - return NULL; - } - - res = _PyBytesWriter_Finish(&writer, bin_data); - if (res == NULL) - return NULL; - return Py_BuildValue("Ni", res, done); -} - - -/*[clinic input] -binascii.rlecode_hqx - - data: Py_buffer - / - -Binhex RLE-code binary data. -[clinic start generated code]*/ - -static PyObject * -binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=393d79338f5f5629 input=e1f1712447a82b09]*/ -{ + "String has incomplete number of bytes"); + _PyBytesWriter_Dealloc(&writer); + return NULL; + } + + res = _PyBytesWriter_Finish(&writer, bin_data); + if (res == NULL) + return NULL; + return Py_BuildValue("Ni", res, done); +} + + +/*[clinic input] +binascii.rlecode_hqx + + data: Py_buffer + / + +Binhex RLE-code binary data. +[clinic start generated code]*/ + +static PyObject * +binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data) +/*[clinic end generated code: output=393d79338f5f5629 input=e1f1712447a82b09]*/ +{ if (PyErr_WarnEx(PyExc_DeprecationWarning, "binascii.rlecode_hqx() is deprecated", 1) < 0) { return NULL; } - const unsigned char *in_data; - unsigned char *out_data; - unsigned char ch; - Py_ssize_t in, inend, len; - _PyBytesWriter writer; - - _PyBytesWriter_Init(&writer); - in_data = data->buf; - len = data->len; - - assert(len >= 0); - - if (len > PY_SSIZE_T_MAX / 2 - 2) - return PyErr_NoMemory(); - - /* Worst case: output is twice as big as input (fixed later) */ - out_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); - if (out_data == NULL) - return NULL; - - for( in=0; in 3 ) { - /* More than 3 in a row. Output RLE. */ - *out_data++ = ch; - *out_data++ = RUNCHAR; - *out_data++ = (unsigned char) (inend-in); - in = inend-1; - } else { - /* Less than 3. Output the byte itself */ - *out_data++ = ch; - } - } - } - - return _PyBytesWriter_Finish(&writer, out_data); -} - - -/*[clinic input] -binascii.b2a_hqx - - data: Py_buffer - / - -Encode .hqx data. -[clinic start generated code]*/ - -static PyObject * -binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=d0aa5a704bc9f7de input=9596ebe019fe12ba]*/ -{ + const unsigned char *in_data; + unsigned char *out_data; + unsigned char ch; + Py_ssize_t in, inend, len; + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); + in_data = data->buf; + len = data->len; + + assert(len >= 0); + + if (len > PY_SSIZE_T_MAX / 2 - 2) + return PyErr_NoMemory(); + + /* Worst case: output is twice as big as input (fixed later) */ + out_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); + if (out_data == NULL) + return NULL; + + for( in=0; in 3 ) { + /* More than 3 in a row. Output RLE. */ + *out_data++ = ch; + *out_data++ = RUNCHAR; + *out_data++ = (unsigned char) (inend-in); + in = inend-1; + } else { + /* Less than 3. Output the byte itself */ + *out_data++ = ch; + } + } + } + + return _PyBytesWriter_Finish(&writer, out_data); +} + + +/*[clinic input] +binascii.b2a_hqx + + data: Py_buffer + / + +Encode .hqx data. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data) +/*[clinic end generated code: output=d0aa5a704bc9f7de input=9596ebe019fe12ba]*/ +{ if (PyErr_WarnEx(PyExc_DeprecationWarning, "binascii.b2a_hqx() is deprecated", 1) < 0) { return NULL; } - unsigned char *ascii_data; - const unsigned char *bin_data; - int leftbits = 0; - unsigned char this_ch; - unsigned int leftchar = 0; - Py_ssize_t len; - _PyBytesWriter writer; - - bin_data = data->buf; - len = data->len; - _PyBytesWriter_Init(&writer); - - assert(len >= 0); - - if (len > PY_SSIZE_T_MAX / 2 - 2) - return PyErr_NoMemory(); - - /* Allocate a buffer that is at least large enough */ - ascii_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); - if (ascii_data == NULL) - return NULL; - - for( ; len > 0 ; len--, bin_data++ ) { - /* Shift into our buffer, and output any 6bits ready */ - leftchar = (leftchar << 8) | *bin_data; - leftbits += 8; - while ( leftbits >= 6 ) { - this_ch = (leftchar >> (leftbits-6)) & 0x3f; - leftbits -= 6; - *ascii_data++ = table_b2a_hqx[this_ch]; - } - } - /* Output a possible runt byte */ - if ( leftbits ) { - leftchar <<= (6-leftbits); - *ascii_data++ = table_b2a_hqx[leftchar & 0x3f]; - } - - return _PyBytesWriter_Finish(&writer, ascii_data); -} - - -/*[clinic input] -binascii.rledecode_hqx - - data: Py_buffer - / - -Decode hexbin RLE-coded string. -[clinic start generated code]*/ - -static PyObject * -binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=9826619565de1c6c input=54cdd49fc014402c]*/ -{ + unsigned char *ascii_data; + const unsigned char *bin_data; + int leftbits = 0; + unsigned char this_ch; + unsigned int leftchar = 0; + Py_ssize_t len; + _PyBytesWriter writer; + + bin_data = data->buf; + len = data->len; + _PyBytesWriter_Init(&writer); + + assert(len >= 0); + + if (len > PY_SSIZE_T_MAX / 2 - 2) + return PyErr_NoMemory(); + + /* Allocate a buffer that is at least large enough */ + ascii_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); + if (ascii_data == NULL) + return NULL; + + for( ; len > 0 ; len--, bin_data++ ) { + /* Shift into our buffer, and output any 6bits ready */ + leftchar = (leftchar << 8) | *bin_data; + leftbits += 8; + while ( leftbits >= 6 ) { + this_ch = (leftchar >> (leftbits-6)) & 0x3f; + leftbits -= 6; + *ascii_data++ = table_b2a_hqx[this_ch]; + } + } + /* Output a possible runt byte */ + if ( leftbits ) { + leftchar <<= (6-leftbits); + *ascii_data++ = table_b2a_hqx[leftchar & 0x3f]; + } + + return _PyBytesWriter_Finish(&writer, ascii_data); +} + + +/*[clinic input] +binascii.rledecode_hqx + + data: Py_buffer + / + +Decode hexbin RLE-coded string. +[clinic start generated code]*/ + +static PyObject * +binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data) +/*[clinic end generated code: output=9826619565de1c6c input=54cdd49fc014402c]*/ +{ if (PyErr_WarnEx(PyExc_DeprecationWarning, "binascii.rledecode_hqx() is deprecated", 1) < 0) { return NULL; } - const unsigned char *in_data; - unsigned char *out_data; - unsigned char in_byte, in_repeat; - Py_ssize_t in_len; - _PyBytesWriter writer; - - in_data = data->buf; - in_len = data->len; - _PyBytesWriter_Init(&writer); + const unsigned char *in_data; + unsigned char *out_data; + unsigned char in_byte, in_repeat; + Py_ssize_t in_len; + _PyBytesWriter writer; + + in_data = data->buf; + in_len = data->len; + _PyBytesWriter_Init(&writer); binascii_state *state; - - assert(in_len >= 0); - - /* Empty string is a special case */ - if ( in_len == 0 ) - return PyBytes_FromStringAndSize("", 0); - else if (in_len > PY_SSIZE_T_MAX / 2) - return PyErr_NoMemory(); - - /* Allocate a buffer of reasonable size. Resized when needed */ - out_data = _PyBytesWriter_Alloc(&writer, in_len); - if (out_data == NULL) - return NULL; - - /* Use overallocation */ - writer.overallocate = 1; - - /* - ** We need two macros here to get/put bytes and handle - ** end-of-buffer for input and output strings. - */ -#define INBYTE(b) \ - do { \ - if ( --in_len < 0 ) { \ + + assert(in_len >= 0); + + /* Empty string is a special case */ + if ( in_len == 0 ) + return PyBytes_FromStringAndSize("", 0); + else if (in_len > PY_SSIZE_T_MAX / 2) + return PyErr_NoMemory(); + + /* Allocate a buffer of reasonable size. Resized when needed */ + out_data = _PyBytesWriter_Alloc(&writer, in_len); + if (out_data == NULL) + return NULL; + + /* Use overallocation */ + writer.overallocate = 1; + + /* + ** We need two macros here to get/put bytes and handle + ** end-of-buffer for input and output strings. + */ +#define INBYTE(b) \ + do { \ + if ( --in_len < 0 ) { \ state = PyModule_GetState(module); \ if (state == NULL) { \ return NULL; \ } \ PyErr_SetString(state->Incomplete, ""); \ - goto error; \ - } \ - b = *in_data++; \ - } while(0) - - /* - ** Handle first byte separately (since we have to get angry - ** in case of an orphaned RLE code). - */ - INBYTE(in_byte); - - if (in_byte == RUNCHAR) { - INBYTE(in_repeat); - /* only 1 byte will be written, but 2 bytes were preallocated: - subtract 1 byte to prevent overallocation */ - writer.min_size--; - - if (in_repeat != 0) { - /* Note Error, not Incomplete (which is at the end - ** of the string only). This is a programmer error. - */ + goto error; \ + } \ + b = *in_data++; \ + } while(0) + + /* + ** Handle first byte separately (since we have to get angry + ** in case of an orphaned RLE code). + */ + INBYTE(in_byte); + + if (in_byte == RUNCHAR) { + INBYTE(in_repeat); + /* only 1 byte will be written, but 2 bytes were preallocated: + subtract 1 byte to prevent overallocation */ + writer.min_size--; + + if (in_repeat != 0) { + /* Note Error, not Incomplete (which is at the end + ** of the string only). This is a programmer error. + */ state = PyModule_GetState(module); if (state == NULL) { return NULL; } PyErr_SetString(state->Error, "Orphaned RLE code at start"); - goto error; - } - *out_data++ = RUNCHAR; - } else { - *out_data++ = in_byte; - } - - while( in_len > 0 ) { - INBYTE(in_byte); - - if (in_byte == RUNCHAR) { - INBYTE(in_repeat); - /* only 1 byte will be written, but 2 bytes were preallocated: - subtract 1 byte to prevent overallocation */ - writer.min_size--; - - if ( in_repeat == 0 ) { - /* Just an escaped RUNCHAR value */ - *out_data++ = RUNCHAR; - } else { - /* Pick up value and output a sequence of it */ - in_byte = out_data[-1]; - - /* enlarge the buffer if needed */ - if (in_repeat > 1) { - /* -1 because we already preallocated 1 byte */ - out_data = _PyBytesWriter_Prepare(&writer, out_data, - in_repeat - 1); - if (out_data == NULL) - goto error; - } - - while ( --in_repeat > 0 ) - *out_data++ = in_byte; - } - } else { - /* Normal byte */ - *out_data++ = in_byte; - } - } - return _PyBytesWriter_Finish(&writer, out_data); - -error: - _PyBytesWriter_Dealloc(&writer); - return NULL; -} - - -/*[clinic input] + goto error; + } + *out_data++ = RUNCHAR; + } else { + *out_data++ = in_byte; + } + + while( in_len > 0 ) { + INBYTE(in_byte); + + if (in_byte == RUNCHAR) { + INBYTE(in_repeat); + /* only 1 byte will be written, but 2 bytes were preallocated: + subtract 1 byte to prevent overallocation */ + writer.min_size--; + + if ( in_repeat == 0 ) { + /* Just an escaped RUNCHAR value */ + *out_data++ = RUNCHAR; + } else { + /* Pick up value and output a sequence of it */ + in_byte = out_data[-1]; + + /* enlarge the buffer if needed */ + if (in_repeat > 1) { + /* -1 because we already preallocated 1 byte */ + out_data = _PyBytesWriter_Prepare(&writer, out_data, + in_repeat - 1); + if (out_data == NULL) + goto error; + } + + while ( --in_repeat > 0 ) + *out_data++ = in_byte; + } + } else { + /* Normal byte */ + *out_data++ = in_byte; + } + } + return _PyBytesWriter_Finish(&writer, out_data); + +error: + _PyBytesWriter_Dealloc(&writer); + return NULL; +} + + +/*[clinic input] binascii.crc_hqx - - data: Py_buffer - crc: unsigned_int(bitwise=True) - / - -Compute CRC-CCITT incrementally. -[clinic start generated code]*/ - + + data: Py_buffer + crc: unsigned_int(bitwise=True) + / + +Compute CRC-CCITT incrementally. +[clinic start generated code]*/ + static PyObject * -binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc) +binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc) /*[clinic end generated code: output=2fde213d0f547a98 input=56237755370a951c]*/ -{ - const unsigned char *bin_data; - Py_ssize_t len; - - crc &= 0xffff; - bin_data = data->buf; - len = data->len; - - while(len-- > 0) { - crc = ((crc<<8)&0xff00) ^ crctab_hqx[(crc>>8)^*bin_data++]; - } - +{ + const unsigned char *bin_data; + Py_ssize_t len; + + crc &= 0xffff; + bin_data = data->buf; + len = data->len; + + while(len-- > 0) { + crc = ((crc<<8)&0xff00) ^ crctab_hqx[(crc>>8)^*bin_data++]; + } + return PyLong_FromUnsignedLong(crc); -} - -#ifndef USE_ZLIB_CRC32 -/* Crc - 32 BIT ANSI X3.66 CRC checksum files - Also known as: ISO 3307 -**********************************************************************| -* *| -* Demonstration program to compute the 32-bit CRC used as the frame *| -* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| -* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| -* protocol). The 32-bit FCS was added via the Federal Register, *| -* 1 June 1982, p.23798. I presume but don't know for certain that *| -* this polynomial is or will be included in CCITT V.41, which *| -* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| -* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| -* errors by a factor of 10^-5 over 16-bit FCS. *| -* *| -**********************************************************************| - - Copyright (C) 1986 Gary S. Brown. You may use this program, or - code or tables extracted from it, as desired without restriction. - - First, the polynomial itself and its table of feedback terms. The - polynomial is - X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 - Note that we take it "backwards" and put the highest-order term in - the lowest-order bit. The X^32 term is "implied"; the LSB is the - X^31 term, etc. The X^0 term (usually shown as "+1") results in - the MSB being 1. - - Note that the usual hardware shift register implementation, which - is what we're using (we're merely optimizing it by doing eight-bit - chunks at a time) shifts bits into the lowest-order term. In our - implementation, that means shifting towards the right. Why do we - do it this way? Because the calculated CRC must be transmitted in - order from highest-order term to lowest-order term. UARTs transmit - characters in order from LSB to MSB. By storing the CRC this way, - we hand it to the UART in the order low-byte to high-byte; the UART - sends each low-bit to hight-bit; and the result is transmission bit - by bit from highest- to lowest-order term without requiring any bit - shuffling on our part. Reception works similarly. - - The feedback terms table consists of 256, 32-bit entries. Notes: - - 1. The table can be generated at runtime if desired; code to do so - is shown later. It might not be obvious, but the feedback - terms simply represent the results of eight shift/xor opera- - tions for all combinations of data and CRC register values. - - 2. The CRC accumulation logic is the same for all CRC polynomials, - be they sixteen or thirty-two bits wide. You simply choose the - appropriate table. Alternatively, because the table can be - generated at runtime, you can start by generating the table for - the polynomial in question and use exactly the same "updcrc", - if your application needn't simultaneously handle two CRC - polynomials. (Note, however, that XMODEM is strange.) - - 3. For 16-bit CRCs, the table entries need be only 16 bits wide; - of course, 32-bit entries work OK if the high 16 bits are zero. - - 4. The values must be right-shifted by eight bits by the "updcrc" - logic; the shift must be unsigned (bring in zeroes). On some - hardware you could probably optimize the shift in assembler by - using byte-swap instructions. -********************************************************************/ - -static const unsigned int crc_32_tab[256] = { -0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, -0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, -0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, -0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, -0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, -0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, -0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, -0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, -0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, -0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, -0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, -0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, -0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, -0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, -0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, -0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, -0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, -0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, -0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, -0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, -0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, -0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, -0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, -0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, -0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, -0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, -0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, -0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, -0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, -0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, -0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, -0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, -0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, -0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, -0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, -0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, -0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, -0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, -0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, -0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, -0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, -0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, -0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, -0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, -0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, -0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, -0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, -0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, -0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, -0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, -0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, -0x2d02ef8dU -}; -#endif /* USE_ZLIB_CRC32 */ - -/*[clinic input] -binascii.crc32 -> unsigned_int - - data: Py_buffer - crc: unsigned_int(bitwise=True) = 0 - / - -Compute CRC-32 incrementally. -[clinic start generated code]*/ - -static unsigned int -binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) -/*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/ - -#ifdef USE_ZLIB_CRC32 -/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ -{ - const Byte *buf; - Py_ssize_t len; - int signed_val; - - buf = (Byte*)data->buf; - len = data->len; - signed_val = crc32(crc, buf, len); - return (unsigned int)signed_val & 0xffffffffU; -} -#else /* USE_ZLIB_CRC32 */ -{ /* By Jim Ahlstrom; All rights transferred to CNRI */ - const unsigned char *bin_data; - Py_ssize_t len; - unsigned int result; - - bin_data = data->buf; - len = data->len; - - crc = ~ crc; - while (len-- > 0) { - crc = crc_32_tab[(crc ^ *bin_data++) & 0xff] ^ (crc >> 8); - /* Note: (crc >> 8) MUST zero fill on left */ - } - - result = (crc ^ 0xFFFFFFFF); - return result & 0xffffffff; -} -#endif /* USE_ZLIB_CRC32 */ - -/*[clinic input] -binascii.b2a_hex - - data: Py_buffer +} + +#ifndef USE_ZLIB_CRC32 +/* Crc - 32 BIT ANSI X3.66 CRC checksum files + Also known as: ISO 3307 +**********************************************************************| +* *| +* Demonstration program to compute the 32-bit CRC used as the frame *| +* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| +* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| +* protocol). The 32-bit FCS was added via the Federal Register, *| +* 1 June 1982, p.23798. I presume but don't know for certain that *| +* this polynomial is or will be included in CCITT V.41, which *| +* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| +* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| +* errors by a factor of 10^-5 over 16-bit FCS. *| +* *| +**********************************************************************| + + Copyright (C) 1986 Gary S. Brown. You may use this program, or + code or tables extracted from it, as desired without restriction. + + First, the polynomial itself and its table of feedback terms. The + polynomial is + X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + Note that we take it "backwards" and put the highest-order term in + the lowest-order bit. The X^32 term is "implied"; the LSB is the + X^31 term, etc. The X^0 term (usually shown as "+1") results in + the MSB being 1. + + Note that the usual hardware shift register implementation, which + is what we're using (we're merely optimizing it by doing eight-bit + chunks at a time) shifts bits into the lowest-order term. In our + implementation, that means shifting towards the right. Why do we + do it this way? Because the calculated CRC must be transmitted in + order from highest-order term to lowest-order term. UARTs transmit + characters in order from LSB to MSB. By storing the CRC this way, + we hand it to the UART in the order low-byte to high-byte; the UART + sends each low-bit to hight-bit; and the result is transmission bit + by bit from highest- to lowest-order term without requiring any bit + shuffling on our part. Reception works similarly. + + The feedback terms table consists of 256, 32-bit entries. Notes: + + 1. The table can be generated at runtime if desired; code to do so + is shown later. It might not be obvious, but the feedback + terms simply represent the results of eight shift/xor opera- + tions for all combinations of data and CRC register values. + + 2. The CRC accumulation logic is the same for all CRC polynomials, + be they sixteen or thirty-two bits wide. You simply choose the + appropriate table. Alternatively, because the table can be + generated at runtime, you can start by generating the table for + the polynomial in question and use exactly the same "updcrc", + if your application needn't simultaneously handle two CRC + polynomials. (Note, however, that XMODEM is strange.) + + 3. For 16-bit CRCs, the table entries need be only 16 bits wide; + of course, 32-bit entries work OK if the high 16 bits are zero. + + 4. The values must be right-shifted by eight bits by the "updcrc" + logic; the shift must be unsigned (bring in zeroes). On some + hardware you could probably optimize the shift in assembler by + using byte-swap instructions. +********************************************************************/ + +static const unsigned int crc_32_tab[256] = { +0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, +0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, +0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, +0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, +0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, +0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, +0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, +0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, +0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, +0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, +0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, +0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, +0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, +0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, +0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, +0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, +0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, +0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, +0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, +0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, +0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, +0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, +0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, +0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, +0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, +0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, +0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, +0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, +0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, +0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, +0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, +0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, +0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, +0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, +0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, +0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, +0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, +0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, +0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, +0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, +0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, +0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, +0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, +0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, +0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, +0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, +0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, +0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, +0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, +0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, +0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, +0x2d02ef8dU +}; +#endif /* USE_ZLIB_CRC32 */ + +/*[clinic input] +binascii.crc32 -> unsigned_int + + data: Py_buffer + crc: unsigned_int(bitwise=True) = 0 + / + +Compute CRC-32 incrementally. +[clinic start generated code]*/ + +static unsigned int +binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/ + +#ifdef USE_ZLIB_CRC32 +/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ +{ + const Byte *buf; + Py_ssize_t len; + int signed_val; + + buf = (Byte*)data->buf; + len = data->len; + signed_val = crc32(crc, buf, len); + return (unsigned int)signed_val & 0xffffffffU; +} +#else /* USE_ZLIB_CRC32 */ +{ /* By Jim Ahlstrom; All rights transferred to CNRI */ + const unsigned char *bin_data; + Py_ssize_t len; + unsigned int result; + + bin_data = data->buf; + len = data->len; + + crc = ~ crc; + while (len-- > 0) { + crc = crc_32_tab[(crc ^ *bin_data++) & 0xff] ^ (crc >> 8); + /* Note: (crc >> 8) MUST zero fill on left */ + } + + result = (crc ^ 0xFFFFFFFF); + return result & 0xffffffff; +} +#endif /* USE_ZLIB_CRC32 */ + +/*[clinic input] +binascii.b2a_hex + + data: Py_buffer sep: object = NULL An optional single character or byte to separate hex bytes. bytes_per_sep: int = 1 How many bytes between separators. Positive values count from the right, negative values count from the left. - -Hexadecimal representation of binary data. - -The return value is a bytes object. This function is also -available as "hexlify()". + +Hexadecimal representation of binary data. + +The return value is a bytes object. This function is also +available as "hexlify()". Example: >>> binascii.b2a_hex(b'\xb9\x01\xef') @@ -1173,82 +1173,82 @@ b'b901ef' b'b9:01:ef' >>> binascii.b2a_hex(b'\xb9\x01\xef', b'_', 2) b'b9_01ef' -[clinic start generated code]*/ - -static PyObject * +[clinic start generated code]*/ + +static PyObject * binascii_b2a_hex_impl(PyObject *module, Py_buffer *data, PyObject *sep, int bytes_per_sep) /*[clinic end generated code: output=a26937946a81d2c7 input=ec0ade6ba2e43543]*/ -{ +{ return _Py_strhex_bytes_with_sep((const char *)data->buf, data->len, sep, bytes_per_sep); -} - -/*[clinic input] -binascii.hexlify = binascii.b2a_hex - -Hexadecimal representation of binary data. - +} + +/*[clinic input] +binascii.hexlify = binascii.b2a_hex + +Hexadecimal representation of binary data. + The return value is a bytes object. This function is also available as "b2a_hex()". -[clinic start generated code]*/ - -static PyObject * +[clinic start generated code]*/ + +static PyObject * binascii_hexlify_impl(PyObject *module, Py_buffer *data, PyObject *sep, int bytes_per_sep) /*[clinic end generated code: output=d12aa1b001b15199 input=bc317bd4e241f76b]*/ -{ +{ return _Py_strhex_bytes_with_sep((const char *)data->buf, data->len, sep, bytes_per_sep); -} - -/*[clinic input] -binascii.a2b_hex - - hexstr: ascii_buffer - / - -Binary data of hexadecimal representation. - -hexstr must contain an even number of hex digits (upper or lower case). -This function is also available as "unhexlify()". -[clinic start generated code]*/ - -static PyObject * -binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr) -/*[clinic end generated code: output=0cc1a139af0eeecb input=9e1e7f2f94db24fd]*/ -{ - const char* argbuf; - Py_ssize_t arglen; - PyObject *retval; - char* retbuf; - Py_ssize_t i, j; +} + +/*[clinic input] +binascii.a2b_hex + + hexstr: ascii_buffer + / + +Binary data of hexadecimal representation. + +hexstr must contain an even number of hex digits (upper or lower case). +This function is also available as "unhexlify()". +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr) +/*[clinic end generated code: output=0cc1a139af0eeecb input=9e1e7f2f94db24fd]*/ +{ + const char* argbuf; + Py_ssize_t arglen; + PyObject *retval; + char* retbuf; + Py_ssize_t i, j; binascii_state *state; - - argbuf = hexstr->buf; - arglen = hexstr->len; - - assert(arglen >= 0); - - /* XXX What should we do about strings with an odd length? Should - * we add an implicit leading zero, or a trailing zero? For now, - * raise an exception. - */ - if (arglen % 2) { + + argbuf = hexstr->buf; + arglen = hexstr->len; + + assert(arglen >= 0); + + /* XXX What should we do about strings with an odd length? Should + * we add an implicit leading zero, or a trailing zero? For now, + * raise an exception. + */ + if (arglen % 2) { state = PyModule_GetState(module); if (state == NULL) { return NULL; } PyErr_SetString(state->Error, "Odd-length string"); - return NULL; - } - - retval = PyBytes_FromStringAndSize(NULL, (arglen/2)); - if (!retval) - return NULL; - retbuf = PyBytes_AS_STRING(retval); - - for (i=j=0; i < arglen; i += 2) { + return NULL; + } + + retval = PyBytes_FromStringAndSize(NULL, (arglen/2)); + if (!retval) + return NULL; + retbuf = PyBytes_AS_STRING(retval); + + for (i=j=0; i < arglen; i += 2) { unsigned int top = _PyLong_DigitValue[Py_CHARMASK(argbuf[i])]; unsigned int bot = _PyLong_DigitValue[Py_CHARMASK(argbuf[i+1])]; if (top >= 16 || bot >= 16) { @@ -1257,354 +1257,354 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr) return NULL; } PyErr_SetString(state->Error, - "Non-hexadecimal digit found"); - goto finally; - } - retbuf[j++] = (top << 4) + bot; - } - return retval; - - finally: - Py_DECREF(retval); - return NULL; -} - -/*[clinic input] -binascii.unhexlify = binascii.a2b_hex - -Binary data of hexadecimal representation. - -hexstr must contain an even number of hex digits (upper or lower case). -[clinic start generated code]*/ - -static PyObject * -binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr) -/*[clinic end generated code: output=51a64c06c79629e3 input=dd8c012725f462da]*/ -{ - return binascii_a2b_hex_impl(module, hexstr); -} - -#define MAXLINESIZE 76 - - -/*[clinic input] -binascii.a2b_qp - - data: ascii_buffer - header: bool(accept={int}) = False - -Decode a string of qp-encoded data. -[clinic start generated code]*/ - -static PyObject * -binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header) -/*[clinic end generated code: output=e99f7846cfb9bc53 input=bf6766fea76cce8f]*/ -{ - Py_ssize_t in, out; - char ch; - const unsigned char *ascii_data; - unsigned char *odata; - Py_ssize_t datalen = 0; - PyObject *rv; - - ascii_data = data->buf; - datalen = data->len; - - /* We allocate the output same size as input, this is overkill. - */ + "Non-hexadecimal digit found"); + goto finally; + } + retbuf[j++] = (top << 4) + bot; + } + return retval; + + finally: + Py_DECREF(retval); + return NULL; +} + +/*[clinic input] +binascii.unhexlify = binascii.a2b_hex + +Binary data of hexadecimal representation. + +hexstr must contain an even number of hex digits (upper or lower case). +[clinic start generated code]*/ + +static PyObject * +binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr) +/*[clinic end generated code: output=51a64c06c79629e3 input=dd8c012725f462da]*/ +{ + return binascii_a2b_hex_impl(module, hexstr); +} + +#define MAXLINESIZE 76 + + +/*[clinic input] +binascii.a2b_qp + + data: ascii_buffer + header: bool(accept={int}) = False + +Decode a string of qp-encoded data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header) +/*[clinic end generated code: output=e99f7846cfb9bc53 input=bf6766fea76cce8f]*/ +{ + Py_ssize_t in, out; + char ch; + const unsigned char *ascii_data; + unsigned char *odata; + Py_ssize_t datalen = 0; + PyObject *rv; + + ascii_data = data->buf; + datalen = data->len; + + /* We allocate the output same size as input, this is overkill. + */ odata = (unsigned char *) PyMem_Calloc(1, datalen); - if (odata == NULL) { - PyErr_NoMemory(); - return NULL; - } - - in = out = 0; - while (in < datalen) { - if (ascii_data[in] == '=') { - in++; - if (in >= datalen) break; - /* Soft line breaks */ - if ((ascii_data[in] == '\n') || (ascii_data[in] == '\r')) { - if (ascii_data[in] != '\n') { - while (in < datalen && ascii_data[in] != '\n') in++; - } - if (in < datalen) in++; - } - else if (ascii_data[in] == '=') { - /* broken case from broken python qp */ - odata[out++] = '='; - in++; - } - else if ((in + 1 < datalen) && - ((ascii_data[in] >= 'A' && ascii_data[in] <= 'F') || - (ascii_data[in] >= 'a' && ascii_data[in] <= 'f') || - (ascii_data[in] >= '0' && ascii_data[in] <= '9')) && - ((ascii_data[in+1] >= 'A' && ascii_data[in+1] <= 'F') || - (ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') || - (ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) { - /* hexval */ + if (odata == NULL) { + PyErr_NoMemory(); + return NULL; + } + + in = out = 0; + while (in < datalen) { + if (ascii_data[in] == '=') { + in++; + if (in >= datalen) break; + /* Soft line breaks */ + if ((ascii_data[in] == '\n') || (ascii_data[in] == '\r')) { + if (ascii_data[in] != '\n') { + while (in < datalen && ascii_data[in] != '\n') in++; + } + if (in < datalen) in++; + } + else if (ascii_data[in] == '=') { + /* broken case from broken python qp */ + odata[out++] = '='; + in++; + } + else if ((in + 1 < datalen) && + ((ascii_data[in] >= 'A' && ascii_data[in] <= 'F') || + (ascii_data[in] >= 'a' && ascii_data[in] <= 'f') || + (ascii_data[in] >= '0' && ascii_data[in] <= '9')) && + ((ascii_data[in+1] >= 'A' && ascii_data[in+1] <= 'F') || + (ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') || + (ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) { + /* hexval */ ch = _PyLong_DigitValue[ascii_data[in]] << 4; - in++; + in++; ch |= _PyLong_DigitValue[ascii_data[in]]; - in++; - odata[out++] = ch; - } - else { - odata[out++] = '='; - } - } - else if (header && ascii_data[in] == '_') { - odata[out++] = ' '; - in++; - } - else { - odata[out] = ascii_data[in]; - in++; - out++; - } - } - if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyMem_Free(odata); - return NULL; - } - PyMem_Free(odata); - return rv; -} - -static int -to_hex (unsigned char ch, unsigned char *s) -{ - unsigned int uvalue = ch; - - s[1] = "0123456789ABCDEF"[uvalue % 16]; - uvalue = (uvalue / 16); - s[0] = "0123456789ABCDEF"[uvalue % 16]; - return 0; -} - -/* XXX: This is ridiculously complicated to be backward compatible - * (mostly) with the quopri module. It doesn't re-create the quopri - * module bug where text ending in CRLF has the CR encoded */ - -/*[clinic input] -binascii.b2a_qp - - data: Py_buffer - quotetabs: bool(accept={int}) = False - istext: bool(accept={int}) = True - header: bool(accept={int}) = False - -Encode a string using quoted-printable encoding. - -On encoding, when istext is set, newlines are not encoded, and white -space at end of lines is. When istext is not set, \r and \n (CR/LF) -are both encoded. When quotetabs is set, space and tabs are encoded. -[clinic start generated code]*/ - -static PyObject * -binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, - int istext, int header) -/*[clinic end generated code: output=e9884472ebb1a94c input=21fb7eea4a184ba6]*/ -{ - Py_ssize_t in, out; - const unsigned char *databuf; - unsigned char *odata; - Py_ssize_t datalen = 0, odatalen = 0; - PyObject *rv; - unsigned int linelen = 0; - unsigned char ch; - int crlf = 0; - const unsigned char *p; - - databuf = data->buf; - datalen = data->len; - - /* See if this string is using CRLF line ends */ - /* XXX: this function has the side effect of converting all of - * the end of lines to be the same depending on this detection - * here */ - p = (const unsigned char *) memchr(databuf, '\n', datalen); - if ((p != NULL) && (p > databuf) && (*(p-1) == '\r')) - crlf = 1; - - /* First, scan to see how many characters need to be encoded */ - in = 0; - while (in < datalen) { - Py_ssize_t delta = 0; - if ((databuf[in] > 126) || - (databuf[in] == '=') || - (header && databuf[in] == '_') || - ((databuf[in] == '.') && (linelen == 0) && - (in + 1 == datalen || databuf[in+1] == '\n' || - databuf[in+1] == '\r' || databuf[in+1] == 0)) || - (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || - ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || - ((databuf[in] < 33) && - (databuf[in] != '\r') && (databuf[in] != '\n') && - (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' '))))) - { - if ((linelen + 3) >= MAXLINESIZE) { - linelen = 0; - if (crlf) - delta += 3; - else - delta += 2; - } - linelen += 3; - delta += 3; - in++; - } - else { - if (istext && - ((databuf[in] == '\n') || - ((in+1 < datalen) && (databuf[in] == '\r') && - (databuf[in+1] == '\n')))) - { - linelen = 0; - /* Protect against whitespace on end of line */ - if (in && ((databuf[in-1] == ' ') || (databuf[in-1] == '\t'))) - delta += 2; - if (crlf) - delta += 2; - else - delta += 1; - if (databuf[in] == '\r') - in += 2; - else - in++; - } - else { - if ((in + 1 != datalen) && - (databuf[in+1] != '\n') && - (linelen + 1) >= MAXLINESIZE) { - linelen = 0; - if (crlf) - delta += 3; - else - delta += 2; - } - linelen++; - delta++; - in++; - } - } - if (PY_SSIZE_T_MAX - delta < odatalen) { - PyErr_NoMemory(); - return NULL; - } - odatalen += delta; - } - - /* We allocate the output same size as input, this is overkill. - */ + in++; + odata[out++] = ch; + } + else { + odata[out++] = '='; + } + } + else if (header && ascii_data[in] == '_') { + odata[out++] = ' '; + in++; + } + else { + odata[out] = ascii_data[in]; + in++; + out++; + } + } + if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { + PyMem_Free(odata); + return NULL; + } + PyMem_Free(odata); + return rv; +} + +static int +to_hex (unsigned char ch, unsigned char *s) +{ + unsigned int uvalue = ch; + + s[1] = "0123456789ABCDEF"[uvalue % 16]; + uvalue = (uvalue / 16); + s[0] = "0123456789ABCDEF"[uvalue % 16]; + return 0; +} + +/* XXX: This is ridiculously complicated to be backward compatible + * (mostly) with the quopri module. It doesn't re-create the quopri + * module bug where text ending in CRLF has the CR encoded */ + +/*[clinic input] +binascii.b2a_qp + + data: Py_buffer + quotetabs: bool(accept={int}) = False + istext: bool(accept={int}) = True + header: bool(accept={int}) = False + +Encode a string using quoted-printable encoding. + +On encoding, when istext is set, newlines are not encoded, and white +space at end of lines is. When istext is not set, \r and \n (CR/LF) +are both encoded. When quotetabs is set, space and tabs are encoded. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, + int istext, int header) +/*[clinic end generated code: output=e9884472ebb1a94c input=21fb7eea4a184ba6]*/ +{ + Py_ssize_t in, out; + const unsigned char *databuf; + unsigned char *odata; + Py_ssize_t datalen = 0, odatalen = 0; + PyObject *rv; + unsigned int linelen = 0; + unsigned char ch; + int crlf = 0; + const unsigned char *p; + + databuf = data->buf; + datalen = data->len; + + /* See if this string is using CRLF line ends */ + /* XXX: this function has the side effect of converting all of + * the end of lines to be the same depending on this detection + * here */ + p = (const unsigned char *) memchr(databuf, '\n', datalen); + if ((p != NULL) && (p > databuf) && (*(p-1) == '\r')) + crlf = 1; + + /* First, scan to see how many characters need to be encoded */ + in = 0; + while (in < datalen) { + Py_ssize_t delta = 0; + if ((databuf[in] > 126) || + (databuf[in] == '=') || + (header && databuf[in] == '_') || + ((databuf[in] == '.') && (linelen == 0) && + (in + 1 == datalen || databuf[in+1] == '\n' || + databuf[in+1] == '\r' || databuf[in+1] == 0)) || + (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || + ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || + ((databuf[in] < 33) && + (databuf[in] != '\r') && (databuf[in] != '\n') && + (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' '))))) + { + if ((linelen + 3) >= MAXLINESIZE) { + linelen = 0; + if (crlf) + delta += 3; + else + delta += 2; + } + linelen += 3; + delta += 3; + in++; + } + else { + if (istext && + ((databuf[in] == '\n') || + ((in+1 < datalen) && (databuf[in] == '\r') && + (databuf[in+1] == '\n')))) + { + linelen = 0; + /* Protect against whitespace on end of line */ + if (in && ((databuf[in-1] == ' ') || (databuf[in-1] == '\t'))) + delta += 2; + if (crlf) + delta += 2; + else + delta += 1; + if (databuf[in] == '\r') + in += 2; + else + in++; + } + else { + if ((in + 1 != datalen) && + (databuf[in+1] != '\n') && + (linelen + 1) >= MAXLINESIZE) { + linelen = 0; + if (crlf) + delta += 3; + else + delta += 2; + } + linelen++; + delta++; + in++; + } + } + if (PY_SSIZE_T_MAX - delta < odatalen) { + PyErr_NoMemory(); + return NULL; + } + odatalen += delta; + } + + /* We allocate the output same size as input, this is overkill. + */ odata = (unsigned char *) PyMem_Calloc(1, odatalen); - if (odata == NULL) { - PyErr_NoMemory(); - return NULL; - } - - in = out = linelen = 0; - while (in < datalen) { - if ((databuf[in] > 126) || - (databuf[in] == '=') || - (header && databuf[in] == '_') || - ((databuf[in] == '.') && (linelen == 0) && - (in + 1 == datalen || databuf[in+1] == '\n' || - databuf[in+1] == '\r' || databuf[in+1] == 0)) || - (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || - ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || - ((databuf[in] < 33) && - (databuf[in] != '\r') && (databuf[in] != '\n') && - (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' '))))) - { - if ((linelen + 3 )>= MAXLINESIZE) { - odata[out++] = '='; - if (crlf) odata[out++] = '\r'; - odata[out++] = '\n'; - linelen = 0; - } - odata[out++] = '='; - to_hex(databuf[in], &odata[out]); - out += 2; - in++; - linelen += 3; - } - else { - if (istext && - ((databuf[in] == '\n') || - ((in+1 < datalen) && (databuf[in] == '\r') && - (databuf[in+1] == '\n')))) - { - linelen = 0; - /* Protect against whitespace on end of line */ - if (out && ((odata[out-1] == ' ') || (odata[out-1] == '\t'))) { - ch = odata[out-1]; - odata[out-1] = '='; - to_hex(ch, &odata[out]); - out += 2; - } - - if (crlf) odata[out++] = '\r'; - odata[out++] = '\n'; - if (databuf[in] == '\r') - in += 2; - else - in++; - } - else { - if ((in + 1 != datalen) && - (databuf[in+1] != '\n') && - (linelen + 1) >= MAXLINESIZE) { - odata[out++] = '='; - if (crlf) odata[out++] = '\r'; - odata[out++] = '\n'; - linelen = 0; - } - linelen++; - if (header && databuf[in] == ' ') { - odata[out++] = '_'; - in++; - } - else { - odata[out++] = databuf[in++]; - } - } - } - } - if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyMem_Free(odata); - return NULL; - } - PyMem_Free(odata); - return rv; -} - -/* List of functions defined in the module */ - -static struct PyMethodDef binascii_module_methods[] = { - BINASCII_A2B_UU_METHODDEF - BINASCII_B2A_UU_METHODDEF - BINASCII_A2B_BASE64_METHODDEF - BINASCII_B2A_BASE64_METHODDEF - BINASCII_A2B_HQX_METHODDEF - BINASCII_B2A_HQX_METHODDEF - BINASCII_A2B_HEX_METHODDEF - BINASCII_B2A_HEX_METHODDEF - BINASCII_HEXLIFY_METHODDEF - BINASCII_UNHEXLIFY_METHODDEF - BINASCII_RLECODE_HQX_METHODDEF - BINASCII_RLEDECODE_HQX_METHODDEF - BINASCII_CRC_HQX_METHODDEF - BINASCII_CRC32_METHODDEF - BINASCII_A2B_QP_METHODDEF - BINASCII_B2A_QP_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -/* Initialization function for the module (*must* be called PyInit_binascii) */ -PyDoc_STRVAR(doc_binascii, "Conversion between binary data and ASCII"); - + if (odata == NULL) { + PyErr_NoMemory(); + return NULL; + } + + in = out = linelen = 0; + while (in < datalen) { + if ((databuf[in] > 126) || + (databuf[in] == '=') || + (header && databuf[in] == '_') || + ((databuf[in] == '.') && (linelen == 0) && + (in + 1 == datalen || databuf[in+1] == '\n' || + databuf[in+1] == '\r' || databuf[in+1] == 0)) || + (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || + ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || + ((databuf[in] < 33) && + (databuf[in] != '\r') && (databuf[in] != '\n') && + (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' '))))) + { + if ((linelen + 3 )>= MAXLINESIZE) { + odata[out++] = '='; + if (crlf) odata[out++] = '\r'; + odata[out++] = '\n'; + linelen = 0; + } + odata[out++] = '='; + to_hex(databuf[in], &odata[out]); + out += 2; + in++; + linelen += 3; + } + else { + if (istext && + ((databuf[in] == '\n') || + ((in+1 < datalen) && (databuf[in] == '\r') && + (databuf[in+1] == '\n')))) + { + linelen = 0; + /* Protect against whitespace on end of line */ + if (out && ((odata[out-1] == ' ') || (odata[out-1] == '\t'))) { + ch = odata[out-1]; + odata[out-1] = '='; + to_hex(ch, &odata[out]); + out += 2; + } + + if (crlf) odata[out++] = '\r'; + odata[out++] = '\n'; + if (databuf[in] == '\r') + in += 2; + else + in++; + } + else { + if ((in + 1 != datalen) && + (databuf[in+1] != '\n') && + (linelen + 1) >= MAXLINESIZE) { + odata[out++] = '='; + if (crlf) odata[out++] = '\r'; + odata[out++] = '\n'; + linelen = 0; + } + linelen++; + if (header && databuf[in] == ' ') { + odata[out++] = '_'; + in++; + } + else { + odata[out++] = databuf[in++]; + } + } + } + } + if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { + PyMem_Free(odata); + return NULL; + } + PyMem_Free(odata); + return rv; +} + +/* List of functions defined in the module */ + +static struct PyMethodDef binascii_module_methods[] = { + BINASCII_A2B_UU_METHODDEF + BINASCII_B2A_UU_METHODDEF + BINASCII_A2B_BASE64_METHODDEF + BINASCII_B2A_BASE64_METHODDEF + BINASCII_A2B_HQX_METHODDEF + BINASCII_B2A_HQX_METHODDEF + BINASCII_A2B_HEX_METHODDEF + BINASCII_B2A_HEX_METHODDEF + BINASCII_HEXLIFY_METHODDEF + BINASCII_UNHEXLIFY_METHODDEF + BINASCII_RLECODE_HQX_METHODDEF + BINASCII_RLEDECODE_HQX_METHODDEF + BINASCII_CRC_HQX_METHODDEF + BINASCII_CRC32_METHODDEF + BINASCII_A2B_QP_METHODDEF + BINASCII_B2A_QP_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +/* Initialization function for the module (*must* be called PyInit_binascii) */ +PyDoc_STRVAR(doc_binascii, "Conversion between binary data and ASCII"); + static int binascii_exec(PyObject *module) { int result; @@ -1612,7 +1612,7 @@ binascii_exec(PyObject *module) { if (state == NULL) { return -1; } - + state->Error = PyErr_NewException("binascii.Error", PyExc_ValueError, NULL); if (state->Error == NULL) { return -1; @@ -1667,20 +1667,20 @@ binascii_free(void *module) binascii_clear((PyObject *)module); } -static struct PyModuleDef binasciimodule = { - PyModuleDef_HEAD_INIT, - "binascii", - doc_binascii, +static struct PyModuleDef binasciimodule = { + PyModuleDef_HEAD_INIT, + "binascii", + doc_binascii, sizeof(binascii_state), - binascii_module_methods, + binascii_module_methods, binascii_slots, binascii_traverse, binascii_clear, binascii_free -}; - -PyMODINIT_FUNC -PyInit_binascii(void) -{ +}; + +PyMODINIT_FUNC +PyInit_binascii(void) +{ return PyModuleDef_Init(&binasciimodule); -} +} diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_cn.c b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_cn.c index 8a62f7e257c..d3b7f8aa11e 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_cn.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_cn.c @@ -1,470 +1,470 @@ -/* - * _codecs_cn.c: Codecs collection for Mainland Chinese encodings - * - * Written by Hye-Shik Chang - */ - -#include "cjkcodecs.h" -#include "mappings_cn.h" - -/** - * hz is predefined as 100 on AIX. So we undefine it to avoid - * conflict against hz codec's. - */ -#ifdef _AIX -#undef hz -#endif - -/* GBK and GB2312 map differently in few code points that are listed below: - * - * gb2312 gbk - * A1A4 U+30FB KATAKANA MIDDLE DOT U+00B7 MIDDLE DOT - * A1AA U+2015 HORIZONTAL BAR U+2014 EM DASH - * A844 undefined U+2015 HORIZONTAL BAR - */ - -#define GBK_DECODE(dc1, dc2, writer) \ - if ((dc1) == 0xa1 && (dc2) == 0xaa) { \ - OUTCHAR(0x2014); \ - } \ - else if ((dc1) == 0xa8 && (dc2) == 0x44) { \ - OUTCHAR(0x2015); \ - } \ - else if ((dc1) == 0xa1 && (dc2) == 0xa4) { \ - OUTCHAR(0x00b7); \ - } \ - else if (TRYMAP_DEC(gb2312, decoded, dc1 ^ 0x80, dc2 ^ 0x80)) { \ - OUTCHAR(decoded); \ - } \ - else if (TRYMAP_DEC(gbkext, decoded, dc1, dc2)) { \ - OUTCHAR(decoded); \ - } - -#define GBK_ENCODE(code, assi) \ - if ((code) == 0x2014) { \ - (assi) = 0xa1aa; \ - } else if ((code) == 0x2015) { \ - (assi) = 0xa844; \ - } else if ((code) == 0x00b7) { \ - (assi) = 0xa1a4; \ - } else if ((code) != 0x30fb && TRYMAP_ENC(gbcommon, assi, code)) { \ - ; \ - } - -/* +/* + * _codecs_cn.c: Codecs collection for Mainland Chinese encodings + * + * Written by Hye-Shik Chang + */ + +#include "cjkcodecs.h" +#include "mappings_cn.h" + +/** + * hz is predefined as 100 on AIX. So we undefine it to avoid + * conflict against hz codec's. + */ +#ifdef _AIX +#undef hz +#endif + +/* GBK and GB2312 map differently in few code points that are listed below: + * + * gb2312 gbk + * A1A4 U+30FB KATAKANA MIDDLE DOT U+00B7 MIDDLE DOT + * A1AA U+2015 HORIZONTAL BAR U+2014 EM DASH + * A844 undefined U+2015 HORIZONTAL BAR + */ + +#define GBK_DECODE(dc1, dc2, writer) \ + if ((dc1) == 0xa1 && (dc2) == 0xaa) { \ + OUTCHAR(0x2014); \ + } \ + else if ((dc1) == 0xa8 && (dc2) == 0x44) { \ + OUTCHAR(0x2015); \ + } \ + else if ((dc1) == 0xa1 && (dc2) == 0xa4) { \ + OUTCHAR(0x00b7); \ + } \ + else if (TRYMAP_DEC(gb2312, decoded, dc1 ^ 0x80, dc2 ^ 0x80)) { \ + OUTCHAR(decoded); \ + } \ + else if (TRYMAP_DEC(gbkext, decoded, dc1, dc2)) { \ + OUTCHAR(decoded); \ + } + +#define GBK_ENCODE(code, assi) \ + if ((code) == 0x2014) { \ + (assi) = 0xa1aa; \ + } else if ((code) == 0x2015) { \ + (assi) = 0xa844; \ + } else if ((code) == 0x00b7) { \ + (assi) = 0xa1a4; \ + } else if ((code) != 0x30fb && TRYMAP_ENC(gbcommon, assi, code)) { \ + ; \ + } + +/* * codecs in this file use the first byte of MultibyteCodec_State.c[8] * to store a 0 or 1 state value */ #define CN_STATE_OFFSET 0 /* - * GB2312 codec - */ - -ENCODER(gb2312) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - - REQUIRE_OUTBUF(2); - if (TRYMAP_ENC(gbcommon, code, c)) - ; - else - return 1; - - if (code & 0x8000) /* MSB set: GBK */ - return 1; - - OUTBYTE1((code >> 8) | 0x80); - OUTBYTE2((code & 0xFF) | 0x80); - NEXT(1, 2); - } - - return 0; -} - -DECODER(gb2312) -{ - while (inleft > 0) { - unsigned char c = **inbuf; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - if (TRYMAP_DEC(gb2312, decoded, c ^ 0x80, INBYTE2 ^ 0x80)) { - OUTCHAR(decoded); - NEXT_IN(2); - } - else - return 1; - } - - return 0; -} - - -/* - * GBK codec - */ - -ENCODER(gbk) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - - REQUIRE_OUTBUF(2); - - GBK_ENCODE(c, code) - else - return 1; - - OUTBYTE1((code >> 8) | 0x80); - if (code & 0x8000) - OUTBYTE2((code & 0xFF)); /* MSB set: GBK */ - else - OUTBYTE2((code & 0xFF) | 0x80); /* MSB unset: GB2312 */ - NEXT(1, 2); - } - - return 0; -} - -DECODER(gbk) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - - GBK_DECODE(c, INBYTE2, writer) - else - return 1; - - NEXT_IN(2); - } - - return 0; -} - - -/* - * GB18030 codec - */ - -ENCODER(gb18030) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - WRITEBYTE1(c); - NEXT(1, 1); - continue; - } - - if (c >= 0x10000) { - Py_UCS4 tc = c - 0x10000; - assert (c <= 0x10FFFF); - - REQUIRE_OUTBUF(4); - - OUTBYTE4((unsigned char)(tc % 10) + 0x30); - tc /= 10; - OUTBYTE3((unsigned char)(tc % 126) + 0x81); - tc /= 126; - OUTBYTE2((unsigned char)(tc % 10) + 0x30); - tc /= 10; - OUTBYTE1((unsigned char)(tc + 0x90)); - - NEXT(1, 4); - continue; - } - - REQUIRE_OUTBUF(2); - - GBK_ENCODE(c, code) - else if (TRYMAP_ENC(gb18030ext, code, c)) - ; - else { - const struct _gb18030_to_unibmp_ranges *utrrange; - - REQUIRE_OUTBUF(4); - - for (utrrange = gb18030_to_unibmp_ranges; - utrrange->first != 0; - utrrange++) - if (utrrange->first <= c && - c <= utrrange->last) { - Py_UCS4 tc; - - tc = c - utrrange->first + - utrrange->base; - - OUTBYTE4((unsigned char)(tc % 10) + 0x30); - tc /= 10; - OUTBYTE3((unsigned char)(tc % 126) + 0x81); - tc /= 126; - OUTBYTE2((unsigned char)(tc % 10) + 0x30); - tc /= 10; - OUTBYTE1((unsigned char)tc + 0x81); - - NEXT(1, 4); - break; - } - - if (utrrange->first == 0) - return 1; - continue; - } - - OUTBYTE1((code >> 8) | 0x80); - if (code & 0x8000) - OUTBYTE2((code & 0xFF)); /* MSB set: GBK or GB18030ext */ - else - OUTBYTE2((code & 0xFF) | 0x80); /* MSB unset: GB2312 */ - - NEXT(1, 2); - } - - return 0; -} - -DECODER(gb18030) -{ - while (inleft > 0) { - unsigned char c = INBYTE1, c2; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - - c2 = INBYTE2; - if (c2 >= 0x30 && c2 <= 0x39) { /* 4 bytes seq */ - const struct _gb18030_to_unibmp_ranges *utr; - unsigned char c3, c4; - Py_UCS4 lseq; - - REQUIRE_INBUF(4); - c3 = INBYTE3; - c4 = INBYTE4; - if (c < 0x81 || c > 0xFE || - c3 < 0x81 || c3 > 0xFE || - c4 < 0x30 || c4 > 0x39) - return 1; - c -= 0x81; c2 -= 0x30; - c3 -= 0x81; c4 -= 0x30; - - if (c < 4) { /* U+0080 - U+FFFF */ - lseq = ((Py_UCS4)c * 10 + c2) * 1260 + - (Py_UCS4)c3 * 10 + c4; - if (lseq < 39420) { - for (utr = gb18030_to_unibmp_ranges; - lseq >= (utr + 1)->base; - utr++) ; - OUTCHAR(utr->first - utr->base + lseq); - NEXT_IN(4); - continue; - } - } - else if (c >= 15) { /* U+10000 - U+10FFFF */ - lseq = 0x10000 + (((Py_UCS4)c-15) * 10 + c2) - * 1260 + (Py_UCS4)c3 * 10 + c4; - if (lseq <= 0x10FFFF) { - OUTCHAR(lseq); - NEXT_IN(4); - continue; - } - } - return 1; - } - - GBK_DECODE(c, c2, writer) - else if (TRYMAP_DEC(gb18030ext, decoded, c, c2)) - OUTCHAR(decoded); - else - return 1; - - NEXT_IN(2); - } - - return 0; -} - - -/* - * HZ codec - */ - -ENCODER_INIT(hz) -{ + * GB2312 codec + */ + +ENCODER(gb2312) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + + REQUIRE_OUTBUF(2); + if (TRYMAP_ENC(gbcommon, code, c)) + ; + else + return 1; + + if (code & 0x8000) /* MSB set: GBK */ + return 1; + + OUTBYTE1((code >> 8) | 0x80); + OUTBYTE2((code & 0xFF) | 0x80); + NEXT(1, 2); + } + + return 0; +} + +DECODER(gb2312) +{ + while (inleft > 0) { + unsigned char c = **inbuf; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + if (TRYMAP_DEC(gb2312, decoded, c ^ 0x80, INBYTE2 ^ 0x80)) { + OUTCHAR(decoded); + NEXT_IN(2); + } + else + return 1; + } + + return 0; +} + + +/* + * GBK codec + */ + +ENCODER(gbk) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + + REQUIRE_OUTBUF(2); + + GBK_ENCODE(c, code) + else + return 1; + + OUTBYTE1((code >> 8) | 0x80); + if (code & 0x8000) + OUTBYTE2((code & 0xFF)); /* MSB set: GBK */ + else + OUTBYTE2((code & 0xFF) | 0x80); /* MSB unset: GB2312 */ + NEXT(1, 2); + } + + return 0; +} + +DECODER(gbk) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + + GBK_DECODE(c, INBYTE2, writer) + else + return 1; + + NEXT_IN(2); + } + + return 0; +} + + +/* + * GB18030 codec + */ + +ENCODER(gb18030) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + WRITEBYTE1(c); + NEXT(1, 1); + continue; + } + + if (c >= 0x10000) { + Py_UCS4 tc = c - 0x10000; + assert (c <= 0x10FFFF); + + REQUIRE_OUTBUF(4); + + OUTBYTE4((unsigned char)(tc % 10) + 0x30); + tc /= 10; + OUTBYTE3((unsigned char)(tc % 126) + 0x81); + tc /= 126; + OUTBYTE2((unsigned char)(tc % 10) + 0x30); + tc /= 10; + OUTBYTE1((unsigned char)(tc + 0x90)); + + NEXT(1, 4); + continue; + } + + REQUIRE_OUTBUF(2); + + GBK_ENCODE(c, code) + else if (TRYMAP_ENC(gb18030ext, code, c)) + ; + else { + const struct _gb18030_to_unibmp_ranges *utrrange; + + REQUIRE_OUTBUF(4); + + for (utrrange = gb18030_to_unibmp_ranges; + utrrange->first != 0; + utrrange++) + if (utrrange->first <= c && + c <= utrrange->last) { + Py_UCS4 tc; + + tc = c - utrrange->first + + utrrange->base; + + OUTBYTE4((unsigned char)(tc % 10) + 0x30); + tc /= 10; + OUTBYTE3((unsigned char)(tc % 126) + 0x81); + tc /= 126; + OUTBYTE2((unsigned char)(tc % 10) + 0x30); + tc /= 10; + OUTBYTE1((unsigned char)tc + 0x81); + + NEXT(1, 4); + break; + } + + if (utrrange->first == 0) + return 1; + continue; + } + + OUTBYTE1((code >> 8) | 0x80); + if (code & 0x8000) + OUTBYTE2((code & 0xFF)); /* MSB set: GBK or GB18030ext */ + else + OUTBYTE2((code & 0xFF) | 0x80); /* MSB unset: GB2312 */ + + NEXT(1, 2); + } + + return 0; +} + +DECODER(gb18030) +{ + while (inleft > 0) { + unsigned char c = INBYTE1, c2; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + + c2 = INBYTE2; + if (c2 >= 0x30 && c2 <= 0x39) { /* 4 bytes seq */ + const struct _gb18030_to_unibmp_ranges *utr; + unsigned char c3, c4; + Py_UCS4 lseq; + + REQUIRE_INBUF(4); + c3 = INBYTE3; + c4 = INBYTE4; + if (c < 0x81 || c > 0xFE || + c3 < 0x81 || c3 > 0xFE || + c4 < 0x30 || c4 > 0x39) + return 1; + c -= 0x81; c2 -= 0x30; + c3 -= 0x81; c4 -= 0x30; + + if (c < 4) { /* U+0080 - U+FFFF */ + lseq = ((Py_UCS4)c * 10 + c2) * 1260 + + (Py_UCS4)c3 * 10 + c4; + if (lseq < 39420) { + for (utr = gb18030_to_unibmp_ranges; + lseq >= (utr + 1)->base; + utr++) ; + OUTCHAR(utr->first - utr->base + lseq); + NEXT_IN(4); + continue; + } + } + else if (c >= 15) { /* U+10000 - U+10FFFF */ + lseq = 0x10000 + (((Py_UCS4)c-15) * 10 + c2) + * 1260 + (Py_UCS4)c3 * 10 + c4; + if (lseq <= 0x10FFFF) { + OUTCHAR(lseq); + NEXT_IN(4); + continue; + } + } + return 1; + } + + GBK_DECODE(c, c2, writer) + else if (TRYMAP_DEC(gb18030ext, decoded, c, c2)) + OUTCHAR(decoded); + else + return 1; + + NEXT_IN(2); + } + + return 0; +} + + +/* + * HZ codec + */ + +ENCODER_INIT(hz) +{ state->c[CN_STATE_OFFSET] = 0; - return 0; -} - -ENCODER_RESET(hz) -{ + return 0; +} + +ENCODER_RESET(hz) +{ if (state->c[CN_STATE_OFFSET] != 0) { - WRITEBYTE2('~', '}'); + WRITEBYTE2('~', '}'); state->c[CN_STATE_OFFSET] = 0; - NEXT_OUT(2); - } - return 0; -} - -ENCODER(hz) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { + NEXT_OUT(2); + } + return 0; +} + +ENCODER(hz) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { if (state->c[CN_STATE_OFFSET]) { - WRITEBYTE2('~', '}'); - NEXT_OUT(2); + WRITEBYTE2('~', '}'); + NEXT_OUT(2); state->c[CN_STATE_OFFSET] = 0; - } - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - if (c == '~') { - WRITEBYTE1('~'); - NEXT_OUT(1); - } - continue; - } - - if (c > 0xFFFF) - return 1; - - if (TRYMAP_ENC(gbcommon, code, c)) - ; - else - return 1; - - if (code & 0x8000) /* MSB set: GBK */ - return 1; - + } + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + if (c == '~') { + WRITEBYTE1('~'); + NEXT_OUT(1); + } + continue; + } + + if (c > 0xFFFF) + return 1; + + if (TRYMAP_ENC(gbcommon, code, c)) + ; + else + return 1; + + if (code & 0x8000) /* MSB set: GBK */ + return 1; + if (state->c[CN_STATE_OFFSET] == 0) { - WRITEBYTE4('~', '{', code >> 8, code & 0xff); - NEXT(1, 4); + WRITEBYTE4('~', '{', code >> 8, code & 0xff); + NEXT(1, 4); state->c[CN_STATE_OFFSET] = 1; - } - else { - WRITEBYTE2(code >> 8, code & 0xff); - NEXT(1, 2); - } - } - - return 0; -} - -DECODER_INIT(hz) -{ + } + else { + WRITEBYTE2(code >> 8, code & 0xff); + NEXT(1, 2); + } + } + + return 0; +} + +DECODER_INIT(hz) +{ state->c[CN_STATE_OFFSET] = 0; - return 0; -} - -DECODER_RESET(hz) -{ + return 0; +} + +DECODER_RESET(hz) +{ state->c[CN_STATE_OFFSET] = 0; - return 0; -} - -DECODER(hz) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - - if (c == '~') { - unsigned char c2 = INBYTE2; - - REQUIRE_INBUF(2); + return 0; +} + +DECODER(hz) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + + if (c == '~') { + unsigned char c2 = INBYTE2; + + REQUIRE_INBUF(2); if (c2 == '~' && state->c[CN_STATE_OFFSET] == 0) - OUTCHAR('~'); + OUTCHAR('~'); else if (c2 == '{' && state->c[CN_STATE_OFFSET] == 0) state->c[CN_STATE_OFFSET] = 1; /* set GB */ else if (c2 == '\n' && state->c[CN_STATE_OFFSET] == 0) - ; /* line-continuation */ + ; /* line-continuation */ else if (c2 == '}' && state->c[CN_STATE_OFFSET] == 1) state->c[CN_STATE_OFFSET] = 0; /* set ASCII */ - else - return 1; - NEXT_IN(2); - continue; - } - - if (c & 0x80) - return 1; - + else + return 1; + NEXT_IN(2); + continue; + } + + if (c & 0x80) + return 1; + if (state->c[CN_STATE_OFFSET] == 0) { /* ASCII mode */ - OUTCHAR(c); - NEXT_IN(1); - } - else { /* GB mode */ - REQUIRE_INBUF(2); - if (TRYMAP_DEC(gb2312, decoded, c, INBYTE2)) { - OUTCHAR(decoded); - NEXT_IN(2); - } - else - return 1; - } - } - - return 0; -} - - -BEGIN_MAPPINGS_LIST - MAPPING_DECONLY(gb2312) - MAPPING_DECONLY(gbkext) - MAPPING_ENCONLY(gbcommon) - MAPPING_ENCDEC(gb18030ext) -END_MAPPINGS_LIST - -BEGIN_CODECS_LIST - CODEC_STATELESS(gb2312) - CODEC_STATELESS(gbk) - CODEC_STATELESS(gb18030) - CODEC_STATEFUL(hz) -END_CODECS_LIST - -I_AM_A_MODULE_FOR(cn) + OUTCHAR(c); + NEXT_IN(1); + } + else { /* GB mode */ + REQUIRE_INBUF(2); + if (TRYMAP_DEC(gb2312, decoded, c, INBYTE2)) { + OUTCHAR(decoded); + NEXT_IN(2); + } + else + return 1; + } + } + + return 0; +} + + +BEGIN_MAPPINGS_LIST + MAPPING_DECONLY(gb2312) + MAPPING_DECONLY(gbkext) + MAPPING_ENCONLY(gbcommon) + MAPPING_ENCDEC(gb18030ext) +END_MAPPINGS_LIST + +BEGIN_CODECS_LIST + CODEC_STATELESS(gb2312) + CODEC_STATELESS(gbk) + CODEC_STATELESS(gb18030) + CODEC_STATEFUL(hz) +END_CODECS_LIST + +I_AM_A_MODULE_FOR(cn) diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_hk.c b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_hk.c index 4f21569a0ce..1029adb1309 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_hk.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_hk.c @@ -1,191 +1,191 @@ -/* - * _codecs_hk.c: Codecs collection for encodings from Hong Kong - * - * Written by Hye-Shik Chang - */ - -#define USING_IMPORTED_MAPS - -#include "cjkcodecs.h" -#include "mappings_hk.h" - -/* - * BIG5HKSCS codec - */ - -static const encode_map *big5_encmap = NULL; -static const decode_map *big5_decmap = NULL; - -CODEC_INIT(big5hkscs) -{ - static int initialized = 0; - - if (!initialized && IMPORT_MAP(tw, big5, &big5_encmap, &big5_decmap)) - return -1; - initialized = 1; - return 0; -} - -/* - * There are four possible pair unicode -> big5hkscs maps as in HKSCS 2004: - * U+00CA U+0304 -> 8862 (U+00CA alone is mapped to 8866) - * U+00CA U+030C -> 8864 - * U+00EA U+0304 -> 88a3 (U+00EA alone is mapped to 88a7) - * U+00EA U+030C -> 88a5 - * These are handled by not mapping tables but a hand-written code. - */ -static const DBCHAR big5hkscs_pairenc_table[4] = {0x8862, 0x8864, 0x88a3, 0x88a5}; - -ENCODER(big5hkscs) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - Py_ssize_t insize; - - if (c < 0x80) { - REQUIRE_OUTBUF(1); - **outbuf = (unsigned char)c; - NEXT(1, 1); - continue; - } - - insize = 1; - REQUIRE_OUTBUF(2); - - if (c < 0x10000) { - if (TRYMAP_ENC(big5hkscs_bmp, code, c)) { - if (code == MULTIC) { - Py_UCS4 c2; - if (inlen - *inpos >= 2) - c2 = INCHAR2; - else - c2 = 0; - - if (inlen - *inpos >= 2 && - ((c & 0xffdf) == 0x00ca) && - ((c2 & 0xfff7) == 0x0304)) { - code = big5hkscs_pairenc_table[ - ((c >> 4) | - (c2 >> 3)) & 3]; - insize = 2; - } - else if (inlen - *inpos < 2 && - !(flags & MBENC_FLUSH)) - return MBERR_TOOFEW; - else { - if (c == 0xca) - code = 0x8866; - else /* c == 0xea */ - code = 0x88a7; - } - } - } - else if (TRYMAP_ENC(big5, code, c)) - ; - else - return 1; - } - else if (c < 0x20000) - return insize; - else if (c < 0x30000) { - if (TRYMAP_ENC(big5hkscs_nonbmp, code, c & 0xffff)) - ; - else - return insize; - } - else - return insize; - - OUTBYTE1(code >> 8); - OUTBYTE2(code & 0xFF); - NEXT(insize, 2); - } - - return 0; -} - -#define BH2S(c1, c2) (((c1) - 0x87) * (0xfe - 0x40 + 1) + ((c2) - 0x40)) - -DECODER(big5hkscs) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - - if (0xc6 > c || c > 0xc8 || (c < 0xc7 && INBYTE2 < 0xa1)) { - if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) { - OUTCHAR(decoded); - NEXT_IN(2); - continue; - } - } - - if (TRYMAP_DEC(big5hkscs, decoded, c, INBYTE2)) - { - int s = BH2S(c, INBYTE2); - const unsigned char *hintbase; - - assert(0x87 <= c && c <= 0xfe); - assert(0x40 <= INBYTE2 && INBYTE2 <= 0xfe); - - if (BH2S(0x87, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) { - hintbase = big5hkscs_phint_0; - s -= BH2S(0x87, 0x40); - } - else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){ - hintbase = big5hkscs_phint_12130; - s -= BH2S(0xc6, 0xa1); - } - else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){ - hintbase = big5hkscs_phint_21924; - s -= BH2S(0xf9, 0xd6); - } - else - return MBERR_INTERNAL; - - if (hintbase[s >> 3] & (1 << (s & 7))) { - OUTCHAR(decoded | 0x20000); - NEXT_IN(2); - } - else { - OUTCHAR(decoded); - NEXT_IN(2); - } - continue; - } - - switch ((c << 8) | INBYTE2) { - case 0x8862: OUTCHAR2(0x00ca, 0x0304); break; - case 0x8864: OUTCHAR2(0x00ca, 0x030c); break; - case 0x88a3: OUTCHAR2(0x00ea, 0x0304); break; - case 0x88a5: OUTCHAR2(0x00ea, 0x030c); break; - default: return 1; - } - - NEXT_IN(2); /* all decoded code points are pairs, above. */ - } - - return 0; -} - - -BEGIN_MAPPINGS_LIST - MAPPING_DECONLY(big5hkscs) - MAPPING_ENCONLY(big5hkscs_bmp) - MAPPING_ENCONLY(big5hkscs_nonbmp) -END_MAPPINGS_LIST - -BEGIN_CODECS_LIST - CODEC_STATELESS_WINIT(big5hkscs) -END_CODECS_LIST - -I_AM_A_MODULE_FOR(hk) +/* + * _codecs_hk.c: Codecs collection for encodings from Hong Kong + * + * Written by Hye-Shik Chang + */ + +#define USING_IMPORTED_MAPS + +#include "cjkcodecs.h" +#include "mappings_hk.h" + +/* + * BIG5HKSCS codec + */ + +static const encode_map *big5_encmap = NULL; +static const decode_map *big5_decmap = NULL; + +CODEC_INIT(big5hkscs) +{ + static int initialized = 0; + + if (!initialized && IMPORT_MAP(tw, big5, &big5_encmap, &big5_decmap)) + return -1; + initialized = 1; + return 0; +} + +/* + * There are four possible pair unicode -> big5hkscs maps as in HKSCS 2004: + * U+00CA U+0304 -> 8862 (U+00CA alone is mapped to 8866) + * U+00CA U+030C -> 8864 + * U+00EA U+0304 -> 88a3 (U+00EA alone is mapped to 88a7) + * U+00EA U+030C -> 88a5 + * These are handled by not mapping tables but a hand-written code. + */ +static const DBCHAR big5hkscs_pairenc_table[4] = {0x8862, 0x8864, 0x88a3, 0x88a5}; + +ENCODER(big5hkscs) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + Py_ssize_t insize; + + if (c < 0x80) { + REQUIRE_OUTBUF(1); + **outbuf = (unsigned char)c; + NEXT(1, 1); + continue; + } + + insize = 1; + REQUIRE_OUTBUF(2); + + if (c < 0x10000) { + if (TRYMAP_ENC(big5hkscs_bmp, code, c)) { + if (code == MULTIC) { + Py_UCS4 c2; + if (inlen - *inpos >= 2) + c2 = INCHAR2; + else + c2 = 0; + + if (inlen - *inpos >= 2 && + ((c & 0xffdf) == 0x00ca) && + ((c2 & 0xfff7) == 0x0304)) { + code = big5hkscs_pairenc_table[ + ((c >> 4) | + (c2 >> 3)) & 3]; + insize = 2; + } + else if (inlen - *inpos < 2 && + !(flags & MBENC_FLUSH)) + return MBERR_TOOFEW; + else { + if (c == 0xca) + code = 0x8866; + else /* c == 0xea */ + code = 0x88a7; + } + } + } + else if (TRYMAP_ENC(big5, code, c)) + ; + else + return 1; + } + else if (c < 0x20000) + return insize; + else if (c < 0x30000) { + if (TRYMAP_ENC(big5hkscs_nonbmp, code, c & 0xffff)) + ; + else + return insize; + } + else + return insize; + + OUTBYTE1(code >> 8); + OUTBYTE2(code & 0xFF); + NEXT(insize, 2); + } + + return 0; +} + +#define BH2S(c1, c2) (((c1) - 0x87) * (0xfe - 0x40 + 1) + ((c2) - 0x40)) + +DECODER(big5hkscs) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + + if (0xc6 > c || c > 0xc8 || (c < 0xc7 && INBYTE2 < 0xa1)) { + if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) { + OUTCHAR(decoded); + NEXT_IN(2); + continue; + } + } + + if (TRYMAP_DEC(big5hkscs, decoded, c, INBYTE2)) + { + int s = BH2S(c, INBYTE2); + const unsigned char *hintbase; + + assert(0x87 <= c && c <= 0xfe); + assert(0x40 <= INBYTE2 && INBYTE2 <= 0xfe); + + if (BH2S(0x87, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) { + hintbase = big5hkscs_phint_0; + s -= BH2S(0x87, 0x40); + } + else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){ + hintbase = big5hkscs_phint_12130; + s -= BH2S(0xc6, 0xa1); + } + else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){ + hintbase = big5hkscs_phint_21924; + s -= BH2S(0xf9, 0xd6); + } + else + return MBERR_INTERNAL; + + if (hintbase[s >> 3] & (1 << (s & 7))) { + OUTCHAR(decoded | 0x20000); + NEXT_IN(2); + } + else { + OUTCHAR(decoded); + NEXT_IN(2); + } + continue; + } + + switch ((c << 8) | INBYTE2) { + case 0x8862: OUTCHAR2(0x00ca, 0x0304); break; + case 0x8864: OUTCHAR2(0x00ca, 0x030c); break; + case 0x88a3: OUTCHAR2(0x00ea, 0x0304); break; + case 0x88a5: OUTCHAR2(0x00ea, 0x030c); break; + default: return 1; + } + + NEXT_IN(2); /* all decoded code points are pairs, above. */ + } + + return 0; +} + + +BEGIN_MAPPINGS_LIST + MAPPING_DECONLY(big5hkscs) + MAPPING_ENCONLY(big5hkscs_bmp) + MAPPING_ENCONLY(big5hkscs_nonbmp) +END_MAPPINGS_LIST + +BEGIN_CODECS_LIST + CODEC_STATELESS_WINIT(big5hkscs) +END_CODECS_LIST + +I_AM_A_MODULE_FOR(hk) diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_iso2022.c b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_iso2022.c index 7394cf67e0e..38bfd74c22b 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_iso2022.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_iso2022.c @@ -1,1143 +1,1143 @@ -/* - * _codecs_iso2022.c: Codecs collection for ISO-2022 encodings. - * - * Written by Hye-Shik Chang - */ - -#define USING_IMPORTED_MAPS -#define USING_BINARY_PAIR_SEARCH -#define EXTERN_JISX0213_PAIR -#define EMULATE_JISX0213_2000_ENCODE_INVALID MAP_UNMAPPABLE -#define EMULATE_JISX0213_2000_DECODE_INVALID MAP_UNMAPPABLE - -#include "cjkcodecs.h" -#include "alg_jisx0201.h" -#include "emu_jisx0213_2000.h" -#include "mappings_jisx0213_pair.h" - -/* STATE - - state->c[0-3] - - 00000000 - ||^^^^^| - |+-----+---- G0-3 Character Set - +----------- Is G0-3 double byte? - - state->c[4] - - 00000000 - || - |+---- Locked-Shift? - +----- ESC Throughout -*/ - -#define ESC 0x1B -#define SO 0x0E -#define SI 0x0F -#define LF 0x0A - -#define MAX_ESCSEQLEN 16 - -#define CHARSET_ISO8859_1 'A' -#define CHARSET_ASCII 'B' -#define CHARSET_ISO8859_7 'F' -#define CHARSET_JISX0201_K 'I' -#define CHARSET_JISX0201_R 'J' - -#define CHARSET_GB2312 ('A'|CHARSET_DBCS) -#define CHARSET_JISX0208 ('B'|CHARSET_DBCS) -#define CHARSET_KSX1001 ('C'|CHARSET_DBCS) -#define CHARSET_JISX0212 ('D'|CHARSET_DBCS) -#define CHARSET_GB2312_8565 ('E'|CHARSET_DBCS) -#define CHARSET_CNS11643_1 ('G'|CHARSET_DBCS) -#define CHARSET_CNS11643_2 ('H'|CHARSET_DBCS) -#define CHARSET_JISX0213_2000_1 ('O'|CHARSET_DBCS) -#define CHARSET_JISX0213_2 ('P'|CHARSET_DBCS) -#define CHARSET_JISX0213_2004_1 ('Q'|CHARSET_DBCS) -#define CHARSET_JISX0208_O ('@'|CHARSET_DBCS) - -#define CHARSET_DBCS 0x80 -#define ESCMARK(mark) ((mark) & 0x7f) - -#define IS_ESCEND(c) (((c) >= 'A' && (c) <= 'Z') || (c) == '@') -#define IS_ISO2022ESC(c2) \ - ((c2) == '(' || (c2) == ')' || (c2) == '$' || \ - (c2) == '.' || (c2) == '&') - /* this is not a complete list of ISO-2022 escape sequence headers. - * but, it's enough to implement CJK instances of iso-2022. */ - -#define MAP_UNMAPPABLE 0xFFFF -#define MAP_MULTIPLE_AVAIL 0xFFFE /* for JIS X 0213 */ - -#define F_SHIFTED 0x01 -#define F_ESCTHROUGHOUT 0x02 - -#define STATE_SETG(dn, v) do { ((state)->c[dn]) = (v); } while (0) -#define STATE_GETG(dn) ((state)->c[dn]) - -#define STATE_G0 STATE_GETG(0) -#define STATE_G1 STATE_GETG(1) -#define STATE_G2 STATE_GETG(2) -#define STATE_G3 STATE_GETG(3) -#define STATE_SETG0(v) STATE_SETG(0, v) -#define STATE_SETG1(v) STATE_SETG(1, v) -#define STATE_SETG2(v) STATE_SETG(2, v) -#define STATE_SETG3(v) STATE_SETG(3, v) - -#define STATE_SETFLAG(f) do { ((state)->c[4]) |= (f); } while (0) -#define STATE_GETFLAG(f) ((state)->c[4] & (f)) -#define STATE_CLEARFLAG(f) do { ((state)->c[4]) &= ~(f); } while (0) -#define STATE_CLEARFLAGS() do { ((state)->c[4]) = 0; } while (0) - -#define ISO2022_CONFIG ((const struct iso2022_config *)config) -#define CONFIG_ISSET(flag) (ISO2022_CONFIG->flags & (flag)) -#define CONFIG_DESIGNATIONS (ISO2022_CONFIG->designations) - -/* iso2022_config.flags */ -#define NO_SHIFT 0x01 -#define USE_G2 0x02 -#define USE_JISX0208_EXT 0x04 - -/*-*- internal data structures -*-*/ - -typedef int (*iso2022_init_func)(void); -typedef Py_UCS4 (*iso2022_decode_func)(const unsigned char *data); -typedef DBCHAR (*iso2022_encode_func)(const Py_UCS4 *data, Py_ssize_t *length); - -struct iso2022_designation { - unsigned char mark; - unsigned char plane; - unsigned char width; - iso2022_init_func initializer; - iso2022_decode_func decoder; - iso2022_encode_func encoder; -}; - -struct iso2022_config { - int flags; - const struct iso2022_designation *designations; /* non-ascii desigs */ -}; - -/*-*- iso-2022 codec implementation -*-*/ - -CODEC_INIT(iso2022) -{ - const struct iso2022_designation *desig; - for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++) - if (desig->initializer != NULL && desig->initializer() != 0) - return -1; - return 0; -} - -ENCODER_INIT(iso2022) -{ - STATE_CLEARFLAGS(); - STATE_SETG0(CHARSET_ASCII); - STATE_SETG1(CHARSET_ASCII); - return 0; -} - -ENCODER_RESET(iso2022) -{ - if (STATE_GETFLAG(F_SHIFTED)) { - WRITEBYTE1(SI); - NEXT_OUT(1); - STATE_CLEARFLAG(F_SHIFTED); - } - if (STATE_G0 != CHARSET_ASCII) { - WRITEBYTE3(ESC, '(', 'B'); - NEXT_OUT(3); - STATE_SETG0(CHARSET_ASCII); - } - return 0; -} - -ENCODER(iso2022) -{ - while (*inpos < inlen) { - const struct iso2022_designation *dsg; - DBCHAR encoded; - Py_UCS4 c = INCHAR1; - Py_ssize_t insize; - - if (c < 0x80) { - if (STATE_G0 != CHARSET_ASCII) { - WRITEBYTE3(ESC, '(', 'B'); - STATE_SETG0(CHARSET_ASCII); - NEXT_OUT(3); - } - if (STATE_GETFLAG(F_SHIFTED)) { - WRITEBYTE1(SI); - STATE_CLEARFLAG(F_SHIFTED); - NEXT_OUT(1); - } - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - - insize = 1; - - encoded = MAP_UNMAPPABLE; - for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { - Py_ssize_t length = 1; - encoded = dsg->encoder(&c, &length); - if (encoded == MAP_MULTIPLE_AVAIL) { - /* this implementation won't work for pair - * of non-bmp characters. */ - if (inlen - *inpos < 2) { - if (!(flags & MBENC_FLUSH)) - return MBERR_TOOFEW; - length = -1; - } - else - length = 2; - encoded = dsg->encoder(&c, &length); - if (encoded != MAP_UNMAPPABLE) { - insize = length; - break; - } - } - else if (encoded != MAP_UNMAPPABLE) - break; - } - - if (!dsg->mark) - return 1; - assert(dsg->width == 1 || dsg->width == 2); - - switch (dsg->plane) { - case 0: /* G0 */ - if (STATE_GETFLAG(F_SHIFTED)) { - WRITEBYTE1(SI); - STATE_CLEARFLAG(F_SHIFTED); - NEXT_OUT(1); - } - if (STATE_G0 != dsg->mark) { - if (dsg->width == 1) { - WRITEBYTE3(ESC, '(', ESCMARK(dsg->mark)); - STATE_SETG0(dsg->mark); - NEXT_OUT(3); - } - else if (dsg->mark == CHARSET_JISX0208) { - WRITEBYTE3(ESC, '$', ESCMARK(dsg->mark)); - STATE_SETG0(dsg->mark); - NEXT_OUT(3); - } - else { - WRITEBYTE4(ESC, '$', '(', - ESCMARK(dsg->mark)); - STATE_SETG0(dsg->mark); - NEXT_OUT(4); - } - } - break; - case 1: /* G1 */ - if (STATE_G1 != dsg->mark) { - if (dsg->width == 1) { - WRITEBYTE3(ESC, ')', ESCMARK(dsg->mark)); - STATE_SETG1(dsg->mark); - NEXT_OUT(3); - } - else { - WRITEBYTE4(ESC, '$', ')', ESCMARK(dsg->mark)); - STATE_SETG1(dsg->mark); - NEXT_OUT(4); - } - } - if (!STATE_GETFLAG(F_SHIFTED)) { - WRITEBYTE1(SO); - STATE_SETFLAG(F_SHIFTED); - NEXT_OUT(1); - } - break; - default: /* G2 and G3 is not supported: no encoding in - * CJKCodecs are using them yet */ - return MBERR_INTERNAL; - } - - if (dsg->width == 1) { - WRITEBYTE1((unsigned char)encoded); - NEXT_OUT(1); - } - else { - WRITEBYTE2(encoded >> 8, encoded & 0xff); - NEXT_OUT(2); - } - NEXT_INCHAR(insize); - } - - return 0; -} - -DECODER_INIT(iso2022) -{ - STATE_CLEARFLAGS(); - STATE_SETG0(CHARSET_ASCII); - STATE_SETG1(CHARSET_ASCII); - STATE_SETG2(CHARSET_ASCII); - return 0; -} - -DECODER_RESET(iso2022) -{ - STATE_SETG0(CHARSET_ASCII); - STATE_CLEARFLAG(F_SHIFTED); - return 0; -} - -static Py_ssize_t -iso2022processesc(const void *config, MultibyteCodec_State *state, - const unsigned char **inbuf, Py_ssize_t *inleft) -{ - unsigned char charset, designation; - Py_ssize_t i, esclen = 0; - - for (i = 1;i < MAX_ESCSEQLEN;i++) { - if (i >= *inleft) - return MBERR_TOOFEW; - if (IS_ESCEND((*inbuf)[i])) { - esclen = i + 1; - break; - } - else if (CONFIG_ISSET(USE_JISX0208_EXT) && i+1 < *inleft && - (*inbuf)[i] == '&' && (*inbuf)[i+1] == '@') { - i += 2; - } - } - - switch (esclen) { - case 0: - return 1; /* unterminated escape sequence */ - case 3: - if (INBYTE2 == '$') { - charset = INBYTE3 | CHARSET_DBCS; - designation = 0; - } - else { - charset = INBYTE3; - if (INBYTE2 == '(') - designation = 0; - else if (INBYTE2 == ')') - designation = 1; - else if (CONFIG_ISSET(USE_G2) && INBYTE2 == '.') - designation = 2; - else - return 3; - } - break; - case 4: - if (INBYTE2 != '$') - return 4; - - charset = INBYTE4 | CHARSET_DBCS; - if (INBYTE3 == '(') - designation = 0; - else if (INBYTE3 == ')') - designation = 1; - else - return 4; - break; - case 6: /* designation with prefix */ - if (CONFIG_ISSET(USE_JISX0208_EXT) && - (*inbuf)[3] == ESC && (*inbuf)[4] == '$' && - (*inbuf)[5] == 'B') { - charset = 'B' | CHARSET_DBCS; - designation = 0; - } - else - return 6; - break; - default: - return esclen; - } - - /* raise error when the charset is not designated for this encoding */ - if (charset != CHARSET_ASCII) { - const struct iso2022_designation *dsg; - - for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { - if (dsg->mark == charset) - break; - } - if (!dsg->mark) - return esclen; - } - - STATE_SETG(designation, charset); - *inleft -= esclen; - (*inbuf) += esclen; - return 0; -} - -#define ISO8859_7_DECODE(c, writer) \ - if ((c) < 0xa0) { \ - OUTCHAR(c); \ - } else if ((c) < 0xc0 && (0x288f3bc9L & (1L << ((c)-0xa0)))) { \ - OUTCHAR(c); \ - } else if ((c) >= 0xb4 && (c) <= 0xfe && ((c) >= 0xd4 || \ - (0xbffffd77L & (1L << ((c)-0xb4))))) { \ - OUTCHAR(0x02d0 + (c)); \ - } else if ((c) == 0xa1) { \ - OUTCHAR(0x2018); \ - } else if ((c) == 0xa2) { \ - OUTCHAR(0x2019); \ - } else if ((c) == 0xaf) { \ - OUTCHAR(0x2015); \ - } - -static Py_ssize_t -iso2022processg2(const void *config, MultibyteCodec_State *state, - const unsigned char **inbuf, Py_ssize_t *inleft, - _PyUnicodeWriter *writer) -{ - /* not written to use encoder, decoder functions because only few - * encodings use G2 designations in CJKCodecs */ - if (STATE_G2 == CHARSET_ISO8859_1) { - if (INBYTE3 < 0x80) - OUTCHAR(INBYTE3 + 0x80); - else - return 3; - } - else if (STATE_G2 == CHARSET_ISO8859_7) { - ISO8859_7_DECODE(INBYTE3 ^ 0x80, writer) - else - return 3; - } - else if (STATE_G2 == CHARSET_ASCII) { - if (INBYTE3 & 0x80) - return 3; - else - OUTCHAR(INBYTE3); - } - else - return MBERR_INTERNAL; - - (*inbuf) += 3; - *inleft -= 3; - return 0; -} - -DECODER(iso2022) -{ - const struct iso2022_designation *dsgcache = NULL; - - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_ssize_t err; - - if (STATE_GETFLAG(F_ESCTHROUGHOUT)) { - /* ESC throughout mode: - * for non-iso2022 escape sequences */ - OUTCHAR(c); /* assume as ISO-8859-1 */ - NEXT_IN(1); - if (IS_ESCEND(c)) { - STATE_CLEARFLAG(F_ESCTHROUGHOUT); - } - continue; - } - - switch (c) { - case ESC: - REQUIRE_INBUF(2); - if (IS_ISO2022ESC(INBYTE2)) { - err = iso2022processesc(config, state, - inbuf, &inleft); - if (err != 0) - return err; - } - else if (CONFIG_ISSET(USE_G2) && INBYTE2 == 'N') {/* SS2 */ - REQUIRE_INBUF(3); - err = iso2022processg2(config, state, - inbuf, &inleft, writer); - if (err != 0) - return err; - } - else { - OUTCHAR(ESC); - STATE_SETFLAG(F_ESCTHROUGHOUT); - NEXT_IN(1); - } - break; - case SI: - if (CONFIG_ISSET(NO_SHIFT)) - goto bypass; - STATE_CLEARFLAG(F_SHIFTED); - NEXT_IN(1); - break; - case SO: - if (CONFIG_ISSET(NO_SHIFT)) - goto bypass; - STATE_SETFLAG(F_SHIFTED); - NEXT_IN(1); - break; - case LF: - STATE_CLEARFLAG(F_SHIFTED); - OUTCHAR(LF); - NEXT_IN(1); - break; - default: - if (c < 0x20) /* C0 */ - goto bypass; - else if (c >= 0x80) - return 1; - else { - const struct iso2022_designation *dsg; - unsigned char charset; - Py_UCS4 decoded; - - if (STATE_GETFLAG(F_SHIFTED)) - charset = STATE_G1; - else - charset = STATE_G0; - - if (charset == CHARSET_ASCII) { -bypass: - OUTCHAR(c); - NEXT_IN(1); - break; - } - - if (dsgcache != NULL && - dsgcache->mark == charset) - dsg = dsgcache; - else { - for (dsg = CONFIG_DESIGNATIONS; - dsg->mark != charset -#ifdef Py_DEBUG - && dsg->mark != '\0' -#endif - ; dsg++) - { - /* noop */ - } - assert(dsg->mark != '\0'); - dsgcache = dsg; - } - - REQUIRE_INBUF(dsg->width); - decoded = dsg->decoder(*inbuf); - if (decoded == MAP_UNMAPPABLE) - return dsg->width; - - if (decoded < 0x10000) { - OUTCHAR(decoded); - } - else if (decoded < 0x30000) { - OUTCHAR(decoded); - } - else { /* JIS X 0213 pairs */ - OUTCHAR2(decoded >> 16, decoded & 0xffff); - } - NEXT_IN(dsg->width); - } - break; - } - } - return 0; -} - -/*-*- mapping table holders -*-*/ - -#define ENCMAP(enc) static const encode_map *enc##_encmap = NULL; -#define DECMAP(enc) static const decode_map *enc##_decmap = NULL; - -/* kr */ -ENCMAP(cp949) -DECMAP(ksx1001) - -/* jp */ -ENCMAP(jisxcommon) -DECMAP(jisx0208) -DECMAP(jisx0212) -ENCMAP(jisx0213_bmp) -DECMAP(jisx0213_1_bmp) -DECMAP(jisx0213_2_bmp) -ENCMAP(jisx0213_emp) -DECMAP(jisx0213_1_emp) -DECMAP(jisx0213_2_emp) - -/* cn */ -ENCMAP(gbcommon) -DECMAP(gb2312) - -/* tw */ - -/*-*- mapping access functions -*-*/ - -static int -ksx1001_init(void) -{ - static int initialized = 0; - - if (!initialized && ( - IMPORT_MAP(kr, cp949, &cp949_encmap, NULL) || - IMPORT_MAP(kr, ksx1001, NULL, &ksx1001_decmap))) - return -1; - initialized = 1; - return 0; -} - -static Py_UCS4 -ksx1001_decoder(const unsigned char *data) -{ - Py_UCS4 u; - if (TRYMAP_DEC(ksx1001, u, data[0], data[1])) - return u; - else - return MAP_UNMAPPABLE; -} - -static DBCHAR -ksx1001_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded; - assert(*length == 1); - if (*data < 0x10000) { - if (TRYMAP_ENC(cp949, coded, *data)) { - if (!(coded & 0x8000)) - return coded; - } - } - return MAP_UNMAPPABLE; -} - -static int -jisx0208_init(void) -{ - static int initialized = 0; - - if (!initialized && ( - IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) || - IMPORT_MAP(jp, jisx0208, NULL, &jisx0208_decmap))) - return -1; - initialized = 1; - return 0; -} - -static Py_UCS4 -jisx0208_decoder(const unsigned char *data) -{ - Py_UCS4 u; - if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ - return 0xff3c; - else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) - return u; - else - return MAP_UNMAPPABLE; -} - -static DBCHAR -jisx0208_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded; - assert(*length == 1); - if (*data < 0x10000) { - if (*data == 0xff3c) /* F/W REVERSE SOLIDUS */ - return 0x2140; - else if (TRYMAP_ENC(jisxcommon, coded, *data)) { - if (!(coded & 0x8000)) - return coded; - } - } - return MAP_UNMAPPABLE; -} - -static int -jisx0212_init(void) -{ - static int initialized = 0; - - if (!initialized && ( - IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) || - IMPORT_MAP(jp, jisx0212, NULL, &jisx0212_decmap))) - return -1; - initialized = 1; - return 0; -} - -static Py_UCS4 -jisx0212_decoder(const unsigned char *data) -{ - Py_UCS4 u; - if (TRYMAP_DEC(jisx0212, u, data[0], data[1])) - return u; - else - return MAP_UNMAPPABLE; -} - -static DBCHAR -jisx0212_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded; - assert(*length == 1); - if (*data < 0x10000) { - if (TRYMAP_ENC(jisxcommon, coded, *data)) { - if (coded & 0x8000) - return coded & 0x7fff; - } - } - return MAP_UNMAPPABLE; -} - -static int -jisx0213_init(void) -{ - static int initialized = 0; - - if (!initialized && ( - jisx0208_init() || - IMPORT_MAP(jp, jisx0213_bmp, - &jisx0213_bmp_encmap, NULL) || - IMPORT_MAP(jp, jisx0213_1_bmp, - NULL, &jisx0213_1_bmp_decmap) || - IMPORT_MAP(jp, jisx0213_2_bmp, - NULL, &jisx0213_2_bmp_decmap) || - IMPORT_MAP(jp, jisx0213_emp, - &jisx0213_emp_encmap, NULL) || - IMPORT_MAP(jp, jisx0213_1_emp, - NULL, &jisx0213_1_emp_decmap) || - IMPORT_MAP(jp, jisx0213_2_emp, - NULL, &jisx0213_2_emp_decmap) || - IMPORT_MAP(jp, jisx0213_pair, &jisx0213_pair_encmap, - &jisx0213_pair_decmap))) - return -1; - initialized = 1; - return 0; -} - -#define config ((void *)2000) -static Py_UCS4 -jisx0213_2000_1_decoder(const unsigned char *data) -{ - Py_UCS4 u; - EMULATE_JISX0213_2000_DECODE_PLANE1(u, data[0], data[1]) - else if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ - return 0xff3c; - else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) - ; - else if (TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1])) - ; - else if (TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])) - u |= 0x20000; - else if (TRYMAP_DEC(jisx0213_pair, u, data[0], data[1])) - ; - else - return MAP_UNMAPPABLE; - return u; -} - -static Py_UCS4 -jisx0213_2000_2_decoder(const unsigned char *data) -{ - Py_UCS4 u; - EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(u, data[0], data[1]) - if (TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1])) - ; - else if (TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])) - u |= 0x20000; - else - return MAP_UNMAPPABLE; - return u; -} -#undef config - -static Py_UCS4 -jisx0213_2004_1_decoder(const unsigned char *data) -{ - Py_UCS4 u; - if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ - return 0xff3c; - else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) - ; - else if (TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1])) - ; - else if (TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])) - u |= 0x20000; - else if (TRYMAP_DEC(jisx0213_pair, u, data[0], data[1])) - ; - else - return MAP_UNMAPPABLE; - return u; -} - -static Py_UCS4 -jisx0213_2004_2_decoder(const unsigned char *data) -{ - Py_UCS4 u; - if (TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1])) - ; - else if (TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])) - u |= 0x20000; - else - return MAP_UNMAPPABLE; - return u; -} - -static DBCHAR -jisx0213_encoder(const Py_UCS4 *data, Py_ssize_t *length, void *config) -{ - DBCHAR coded; - - switch (*length) { - case 1: /* first character */ - if (*data >= 0x10000) { - if ((*data) >> 16 == 0x20000 >> 16) { - EMULATE_JISX0213_2000_ENCODE_EMP(coded, *data) - else if (TRYMAP_ENC(jisx0213_emp, coded, (*data) & 0xffff)) - return coded; - } - return MAP_UNMAPPABLE; - } - - EMULATE_JISX0213_2000_ENCODE_BMP(coded, *data) - else if (TRYMAP_ENC(jisx0213_bmp, coded, *data)) { - if (coded == MULTIC) - return MAP_MULTIPLE_AVAIL; - } - else if (TRYMAP_ENC(jisxcommon, coded, *data)) { - if (coded & 0x8000) - return MAP_UNMAPPABLE; - } - else - return MAP_UNMAPPABLE; - return coded; - - case 2: /* second character of unicode pair */ - coded = find_pairencmap((ucs2_t)data[0], (ucs2_t)data[1], - jisx0213_pair_encmap, JISX0213_ENCPAIRS); - if (coded != DBCINV) - return coded; - /* fall through */ - - case -1: /* flush unterminated */ - *length = 1; - coded = find_pairencmap((ucs2_t)data[0], 0, - jisx0213_pair_encmap, JISX0213_ENCPAIRS); - if (coded == DBCINV) - return MAP_UNMAPPABLE; - else - return coded; - break; - - default: - return MAP_UNMAPPABLE; - } -} - -static DBCHAR -jisx0213_2000_1_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded = jisx0213_encoder(data, length, (void *)2000); - if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) - return coded; - else if (coded & 0x8000) - return MAP_UNMAPPABLE; - else - return coded; -} - -static DBCHAR -jisx0213_2000_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded; - Py_ssize_t ilength = *length; - - coded = jisx0213_encoder(data, length, (void *)2000); - switch (ilength) { - case 1: - if (coded == MAP_MULTIPLE_AVAIL) - return MAP_MULTIPLE_AVAIL; - else - return MAP_UNMAPPABLE; - case 2: - if (*length != 2) - return MAP_UNMAPPABLE; - else - return coded; - default: - return MAP_UNMAPPABLE; - } -} - -static DBCHAR -jisx0213_2000_2_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded = jisx0213_encoder(data, length, (void *)2000); - if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) - return coded; - else if (coded & 0x8000) - return coded & 0x7fff; - else - return MAP_UNMAPPABLE; -} - -static DBCHAR -jisx0213_2004_1_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded = jisx0213_encoder(data, length, NULL); - if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) - return coded; - else if (coded & 0x8000) - return MAP_UNMAPPABLE; - else - return coded; -} - -static DBCHAR -jisx0213_2004_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded; - Py_ssize_t ilength = *length; - - coded = jisx0213_encoder(data, length, NULL); - switch (ilength) { - case 1: - if (coded == MAP_MULTIPLE_AVAIL) - return MAP_MULTIPLE_AVAIL; - else - return MAP_UNMAPPABLE; - case 2: - if (*length != 2) - return MAP_UNMAPPABLE; - else - return coded; - default: - return MAP_UNMAPPABLE; - } -} - -static DBCHAR -jisx0213_2004_2_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded = jisx0213_encoder(data, length, NULL); - if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) - return coded; - else if (coded & 0x8000) - return coded & 0x7fff; - else - return MAP_UNMAPPABLE; -} - -static Py_UCS4 -jisx0201_r_decoder(const unsigned char *data) -{ - Py_UCS4 u; - JISX0201_R_DECODE_CHAR(*data, u) - else - return MAP_UNMAPPABLE; - return u; -} - -static DBCHAR -jisx0201_r_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded; - JISX0201_R_ENCODE(*data, coded) - else - return MAP_UNMAPPABLE; - return coded; -} - -static Py_UCS4 -jisx0201_k_decoder(const unsigned char *data) -{ - Py_UCS4 u; - JISX0201_K_DECODE_CHAR(*data ^ 0x80, u) - else - return MAP_UNMAPPABLE; - return u; -} - -static DBCHAR -jisx0201_k_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded; - JISX0201_K_ENCODE(*data, coded) - else - return MAP_UNMAPPABLE; - return coded - 0x80; -} - -static int -gb2312_init(void) -{ - static int initialized = 0; - - if (!initialized && ( - IMPORT_MAP(cn, gbcommon, &gbcommon_encmap, NULL) || - IMPORT_MAP(cn, gb2312, NULL, &gb2312_decmap))) - return -1; - initialized = 1; - return 0; -} - -static Py_UCS4 -gb2312_decoder(const unsigned char *data) -{ - Py_UCS4 u; - if (TRYMAP_DEC(gb2312, u, data[0], data[1])) - return u; - else - return MAP_UNMAPPABLE; -} - -static DBCHAR -gb2312_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - DBCHAR coded; - assert(*length == 1); - if (*data < 0x10000) { - if (TRYMAP_ENC(gbcommon, coded, *data)) { - if (!(coded & 0x8000)) - return coded; - } - } - return MAP_UNMAPPABLE; -} - - -static Py_UCS4 -dummy_decoder(const unsigned char *data) -{ - return MAP_UNMAPPABLE; -} - -static DBCHAR -dummy_encoder(const Py_UCS4 *data, Py_ssize_t *length) -{ - return MAP_UNMAPPABLE; -} - -/*-*- registry tables -*-*/ - -#define REGISTRY_KSX1001_G0 { CHARSET_KSX1001, 0, 2, \ - ksx1001_init, \ - ksx1001_decoder, ksx1001_encoder } -#define REGISTRY_KSX1001_G1 { CHARSET_KSX1001, 1, 2, \ - ksx1001_init, \ - ksx1001_decoder, ksx1001_encoder } -#define REGISTRY_JISX0201_R { CHARSET_JISX0201_R, 0, 1, \ - NULL, \ - jisx0201_r_decoder, jisx0201_r_encoder } -#define REGISTRY_JISX0201_K { CHARSET_JISX0201_K, 0, 1, \ - NULL, \ - jisx0201_k_decoder, jisx0201_k_encoder } -#define REGISTRY_JISX0208 { CHARSET_JISX0208, 0, 2, \ - jisx0208_init, \ - jisx0208_decoder, jisx0208_encoder } -#define REGISTRY_JISX0208_O { CHARSET_JISX0208_O, 0, 2, \ - jisx0208_init, \ - jisx0208_decoder, jisx0208_encoder } -#define REGISTRY_JISX0212 { CHARSET_JISX0212, 0, 2, \ - jisx0212_init, \ - jisx0212_decoder, jisx0212_encoder } -#define REGISTRY_JISX0213_2000_1 { CHARSET_JISX0213_2000_1, 0, 2, \ - jisx0213_init, \ - jisx0213_2000_1_decoder, \ - jisx0213_2000_1_encoder } -#define REGISTRY_JISX0213_2000_1_PAIRONLY { CHARSET_JISX0213_2000_1, 0, 2, \ - jisx0213_init, \ - jisx0213_2000_1_decoder, \ - jisx0213_2000_1_encoder_paironly } -#define REGISTRY_JISX0213_2000_2 { CHARSET_JISX0213_2, 0, 2, \ - jisx0213_init, \ - jisx0213_2000_2_decoder, \ - jisx0213_2000_2_encoder } -#define REGISTRY_JISX0213_2004_1 { CHARSET_JISX0213_2004_1, 0, 2, \ - jisx0213_init, \ - jisx0213_2004_1_decoder, \ - jisx0213_2004_1_encoder } -#define REGISTRY_JISX0213_2004_1_PAIRONLY { CHARSET_JISX0213_2004_1, 0, 2, \ - jisx0213_init, \ - jisx0213_2004_1_decoder, \ - jisx0213_2004_1_encoder_paironly } -#define REGISTRY_JISX0213_2004_2 { CHARSET_JISX0213_2, 0, 2, \ - jisx0213_init, \ - jisx0213_2004_2_decoder, \ - jisx0213_2004_2_encoder } -#define REGISTRY_GB2312 { CHARSET_GB2312, 0, 2, \ - gb2312_init, \ - gb2312_decoder, gb2312_encoder } -#define REGISTRY_CNS11643_1 { CHARSET_CNS11643_1, 1, 2, \ - cns11643_init, \ - cns11643_1_decoder, cns11643_1_encoder } -#define REGISTRY_CNS11643_2 { CHARSET_CNS11643_2, 2, 2, \ - cns11643_init, \ - cns11643_2_decoder, cns11643_2_encoder } -#define REGISTRY_ISO8859_1 { CHARSET_ISO8859_1, 2, 1, \ - NULL, dummy_decoder, dummy_encoder } -#define REGISTRY_ISO8859_7 { CHARSET_ISO8859_7, 2, 1, \ - NULL, dummy_decoder, dummy_encoder } -#define REGISTRY_SENTINEL { 0, } -#define CONFIGDEF(var, attrs) \ - static const struct iso2022_config iso2022_##var##_config = { \ - attrs, iso2022_##var##_designations \ - }; - -static const struct iso2022_designation iso2022_kr_designations[] = { - REGISTRY_KSX1001_G1, REGISTRY_SENTINEL -}; -CONFIGDEF(kr, 0) - -static const struct iso2022_designation iso2022_jp_designations[] = { - REGISTRY_JISX0208, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O, - REGISTRY_SENTINEL -}; -CONFIGDEF(jp, NO_SHIFT | USE_JISX0208_EXT) - -static const struct iso2022_designation iso2022_jp_1_designations[] = { - REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R, - REGISTRY_JISX0208_O, REGISTRY_SENTINEL -}; -CONFIGDEF(jp_1, NO_SHIFT | USE_JISX0208_EXT) - -static const struct iso2022_designation iso2022_jp_2_designations[] = { - REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_KSX1001_G0, - REGISTRY_GB2312, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O, - REGISTRY_ISO8859_1, REGISTRY_ISO8859_7, REGISTRY_SENTINEL -}; -CONFIGDEF(jp_2, NO_SHIFT | USE_G2 | USE_JISX0208_EXT) - -static const struct iso2022_designation iso2022_jp_2004_designations[] = { - REGISTRY_JISX0213_2004_1_PAIRONLY, REGISTRY_JISX0208, - REGISTRY_JISX0213_2004_1, REGISTRY_JISX0213_2004_2, REGISTRY_SENTINEL -}; -CONFIGDEF(jp_2004, NO_SHIFT | USE_JISX0208_EXT) - -static const struct iso2022_designation iso2022_jp_3_designations[] = { - REGISTRY_JISX0213_2000_1_PAIRONLY, REGISTRY_JISX0208, - REGISTRY_JISX0213_2000_1, REGISTRY_JISX0213_2000_2, REGISTRY_SENTINEL -}; -CONFIGDEF(jp_3, NO_SHIFT | USE_JISX0208_EXT) - -static const struct iso2022_designation iso2022_jp_ext_designations[] = { - REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R, - REGISTRY_JISX0201_K, REGISTRY_JISX0208_O, REGISTRY_SENTINEL -}; -CONFIGDEF(jp_ext, NO_SHIFT | USE_JISX0208_EXT) - - -BEGIN_MAPPINGS_LIST - /* no mapping table here */ -END_MAPPINGS_LIST - -#define ISO2022_CODEC(variation) { \ - "iso2022_" #variation, \ - &iso2022_##variation##_config, \ - iso2022_codec_init, \ - _STATEFUL_METHODS(iso2022) \ -}, - -BEGIN_CODECS_LIST - ISO2022_CODEC(kr) - ISO2022_CODEC(jp) - ISO2022_CODEC(jp_1) - ISO2022_CODEC(jp_2) - ISO2022_CODEC(jp_2004) - ISO2022_CODEC(jp_3) - ISO2022_CODEC(jp_ext) -END_CODECS_LIST - -I_AM_A_MODULE_FOR(iso2022) +/* + * _codecs_iso2022.c: Codecs collection for ISO-2022 encodings. + * + * Written by Hye-Shik Chang + */ + +#define USING_IMPORTED_MAPS +#define USING_BINARY_PAIR_SEARCH +#define EXTERN_JISX0213_PAIR +#define EMULATE_JISX0213_2000_ENCODE_INVALID MAP_UNMAPPABLE +#define EMULATE_JISX0213_2000_DECODE_INVALID MAP_UNMAPPABLE + +#include "cjkcodecs.h" +#include "alg_jisx0201.h" +#include "emu_jisx0213_2000.h" +#include "mappings_jisx0213_pair.h" + +/* STATE + + state->c[0-3] + + 00000000 + ||^^^^^| + |+-----+---- G0-3 Character Set + +----------- Is G0-3 double byte? + + state->c[4] + + 00000000 + || + |+---- Locked-Shift? + +----- ESC Throughout +*/ + +#define ESC 0x1B +#define SO 0x0E +#define SI 0x0F +#define LF 0x0A + +#define MAX_ESCSEQLEN 16 + +#define CHARSET_ISO8859_1 'A' +#define CHARSET_ASCII 'B' +#define CHARSET_ISO8859_7 'F' +#define CHARSET_JISX0201_K 'I' +#define CHARSET_JISX0201_R 'J' + +#define CHARSET_GB2312 ('A'|CHARSET_DBCS) +#define CHARSET_JISX0208 ('B'|CHARSET_DBCS) +#define CHARSET_KSX1001 ('C'|CHARSET_DBCS) +#define CHARSET_JISX0212 ('D'|CHARSET_DBCS) +#define CHARSET_GB2312_8565 ('E'|CHARSET_DBCS) +#define CHARSET_CNS11643_1 ('G'|CHARSET_DBCS) +#define CHARSET_CNS11643_2 ('H'|CHARSET_DBCS) +#define CHARSET_JISX0213_2000_1 ('O'|CHARSET_DBCS) +#define CHARSET_JISX0213_2 ('P'|CHARSET_DBCS) +#define CHARSET_JISX0213_2004_1 ('Q'|CHARSET_DBCS) +#define CHARSET_JISX0208_O ('@'|CHARSET_DBCS) + +#define CHARSET_DBCS 0x80 +#define ESCMARK(mark) ((mark) & 0x7f) + +#define IS_ESCEND(c) (((c) >= 'A' && (c) <= 'Z') || (c) == '@') +#define IS_ISO2022ESC(c2) \ + ((c2) == '(' || (c2) == ')' || (c2) == '$' || \ + (c2) == '.' || (c2) == '&') + /* this is not a complete list of ISO-2022 escape sequence headers. + * but, it's enough to implement CJK instances of iso-2022. */ + +#define MAP_UNMAPPABLE 0xFFFF +#define MAP_MULTIPLE_AVAIL 0xFFFE /* for JIS X 0213 */ + +#define F_SHIFTED 0x01 +#define F_ESCTHROUGHOUT 0x02 + +#define STATE_SETG(dn, v) do { ((state)->c[dn]) = (v); } while (0) +#define STATE_GETG(dn) ((state)->c[dn]) + +#define STATE_G0 STATE_GETG(0) +#define STATE_G1 STATE_GETG(1) +#define STATE_G2 STATE_GETG(2) +#define STATE_G3 STATE_GETG(3) +#define STATE_SETG0(v) STATE_SETG(0, v) +#define STATE_SETG1(v) STATE_SETG(1, v) +#define STATE_SETG2(v) STATE_SETG(2, v) +#define STATE_SETG3(v) STATE_SETG(3, v) + +#define STATE_SETFLAG(f) do { ((state)->c[4]) |= (f); } while (0) +#define STATE_GETFLAG(f) ((state)->c[4] & (f)) +#define STATE_CLEARFLAG(f) do { ((state)->c[4]) &= ~(f); } while (0) +#define STATE_CLEARFLAGS() do { ((state)->c[4]) = 0; } while (0) + +#define ISO2022_CONFIG ((const struct iso2022_config *)config) +#define CONFIG_ISSET(flag) (ISO2022_CONFIG->flags & (flag)) +#define CONFIG_DESIGNATIONS (ISO2022_CONFIG->designations) + +/* iso2022_config.flags */ +#define NO_SHIFT 0x01 +#define USE_G2 0x02 +#define USE_JISX0208_EXT 0x04 + +/*-*- internal data structures -*-*/ + +typedef int (*iso2022_init_func)(void); +typedef Py_UCS4 (*iso2022_decode_func)(const unsigned char *data); +typedef DBCHAR (*iso2022_encode_func)(const Py_UCS4 *data, Py_ssize_t *length); + +struct iso2022_designation { + unsigned char mark; + unsigned char plane; + unsigned char width; + iso2022_init_func initializer; + iso2022_decode_func decoder; + iso2022_encode_func encoder; +}; + +struct iso2022_config { + int flags; + const struct iso2022_designation *designations; /* non-ascii desigs */ +}; + +/*-*- iso-2022 codec implementation -*-*/ + +CODEC_INIT(iso2022) +{ + const struct iso2022_designation *desig; + for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++) + if (desig->initializer != NULL && desig->initializer() != 0) + return -1; + return 0; +} + +ENCODER_INIT(iso2022) +{ + STATE_CLEARFLAGS(); + STATE_SETG0(CHARSET_ASCII); + STATE_SETG1(CHARSET_ASCII); + return 0; +} + +ENCODER_RESET(iso2022) +{ + if (STATE_GETFLAG(F_SHIFTED)) { + WRITEBYTE1(SI); + NEXT_OUT(1); + STATE_CLEARFLAG(F_SHIFTED); + } + if (STATE_G0 != CHARSET_ASCII) { + WRITEBYTE3(ESC, '(', 'B'); + NEXT_OUT(3); + STATE_SETG0(CHARSET_ASCII); + } + return 0; +} + +ENCODER(iso2022) +{ + while (*inpos < inlen) { + const struct iso2022_designation *dsg; + DBCHAR encoded; + Py_UCS4 c = INCHAR1; + Py_ssize_t insize; + + if (c < 0x80) { + if (STATE_G0 != CHARSET_ASCII) { + WRITEBYTE3(ESC, '(', 'B'); + STATE_SETG0(CHARSET_ASCII); + NEXT_OUT(3); + } + if (STATE_GETFLAG(F_SHIFTED)) { + WRITEBYTE1(SI); + STATE_CLEARFLAG(F_SHIFTED); + NEXT_OUT(1); + } + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + + insize = 1; + + encoded = MAP_UNMAPPABLE; + for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { + Py_ssize_t length = 1; + encoded = dsg->encoder(&c, &length); + if (encoded == MAP_MULTIPLE_AVAIL) { + /* this implementation won't work for pair + * of non-bmp characters. */ + if (inlen - *inpos < 2) { + if (!(flags & MBENC_FLUSH)) + return MBERR_TOOFEW; + length = -1; + } + else + length = 2; + encoded = dsg->encoder(&c, &length); + if (encoded != MAP_UNMAPPABLE) { + insize = length; + break; + } + } + else if (encoded != MAP_UNMAPPABLE) + break; + } + + if (!dsg->mark) + return 1; + assert(dsg->width == 1 || dsg->width == 2); + + switch (dsg->plane) { + case 0: /* G0 */ + if (STATE_GETFLAG(F_SHIFTED)) { + WRITEBYTE1(SI); + STATE_CLEARFLAG(F_SHIFTED); + NEXT_OUT(1); + } + if (STATE_G0 != dsg->mark) { + if (dsg->width == 1) { + WRITEBYTE3(ESC, '(', ESCMARK(dsg->mark)); + STATE_SETG0(dsg->mark); + NEXT_OUT(3); + } + else if (dsg->mark == CHARSET_JISX0208) { + WRITEBYTE3(ESC, '$', ESCMARK(dsg->mark)); + STATE_SETG0(dsg->mark); + NEXT_OUT(3); + } + else { + WRITEBYTE4(ESC, '$', '(', + ESCMARK(dsg->mark)); + STATE_SETG0(dsg->mark); + NEXT_OUT(4); + } + } + break; + case 1: /* G1 */ + if (STATE_G1 != dsg->mark) { + if (dsg->width == 1) { + WRITEBYTE3(ESC, ')', ESCMARK(dsg->mark)); + STATE_SETG1(dsg->mark); + NEXT_OUT(3); + } + else { + WRITEBYTE4(ESC, '$', ')', ESCMARK(dsg->mark)); + STATE_SETG1(dsg->mark); + NEXT_OUT(4); + } + } + if (!STATE_GETFLAG(F_SHIFTED)) { + WRITEBYTE1(SO); + STATE_SETFLAG(F_SHIFTED); + NEXT_OUT(1); + } + break; + default: /* G2 and G3 is not supported: no encoding in + * CJKCodecs are using them yet */ + return MBERR_INTERNAL; + } + + if (dsg->width == 1) { + WRITEBYTE1((unsigned char)encoded); + NEXT_OUT(1); + } + else { + WRITEBYTE2(encoded >> 8, encoded & 0xff); + NEXT_OUT(2); + } + NEXT_INCHAR(insize); + } + + return 0; +} + +DECODER_INIT(iso2022) +{ + STATE_CLEARFLAGS(); + STATE_SETG0(CHARSET_ASCII); + STATE_SETG1(CHARSET_ASCII); + STATE_SETG2(CHARSET_ASCII); + return 0; +} + +DECODER_RESET(iso2022) +{ + STATE_SETG0(CHARSET_ASCII); + STATE_CLEARFLAG(F_SHIFTED); + return 0; +} + +static Py_ssize_t +iso2022processesc(const void *config, MultibyteCodec_State *state, + const unsigned char **inbuf, Py_ssize_t *inleft) +{ + unsigned char charset, designation; + Py_ssize_t i, esclen = 0; + + for (i = 1;i < MAX_ESCSEQLEN;i++) { + if (i >= *inleft) + return MBERR_TOOFEW; + if (IS_ESCEND((*inbuf)[i])) { + esclen = i + 1; + break; + } + else if (CONFIG_ISSET(USE_JISX0208_EXT) && i+1 < *inleft && + (*inbuf)[i] == '&' && (*inbuf)[i+1] == '@') { + i += 2; + } + } + + switch (esclen) { + case 0: + return 1; /* unterminated escape sequence */ + case 3: + if (INBYTE2 == '$') { + charset = INBYTE3 | CHARSET_DBCS; + designation = 0; + } + else { + charset = INBYTE3; + if (INBYTE2 == '(') + designation = 0; + else if (INBYTE2 == ')') + designation = 1; + else if (CONFIG_ISSET(USE_G2) && INBYTE2 == '.') + designation = 2; + else + return 3; + } + break; + case 4: + if (INBYTE2 != '$') + return 4; + + charset = INBYTE4 | CHARSET_DBCS; + if (INBYTE3 == '(') + designation = 0; + else if (INBYTE3 == ')') + designation = 1; + else + return 4; + break; + case 6: /* designation with prefix */ + if (CONFIG_ISSET(USE_JISX0208_EXT) && + (*inbuf)[3] == ESC && (*inbuf)[4] == '$' && + (*inbuf)[5] == 'B') { + charset = 'B' | CHARSET_DBCS; + designation = 0; + } + else + return 6; + break; + default: + return esclen; + } + + /* raise error when the charset is not designated for this encoding */ + if (charset != CHARSET_ASCII) { + const struct iso2022_designation *dsg; + + for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { + if (dsg->mark == charset) + break; + } + if (!dsg->mark) + return esclen; + } + + STATE_SETG(designation, charset); + *inleft -= esclen; + (*inbuf) += esclen; + return 0; +} + +#define ISO8859_7_DECODE(c, writer) \ + if ((c) < 0xa0) { \ + OUTCHAR(c); \ + } else if ((c) < 0xc0 && (0x288f3bc9L & (1L << ((c)-0xa0)))) { \ + OUTCHAR(c); \ + } else if ((c) >= 0xb4 && (c) <= 0xfe && ((c) >= 0xd4 || \ + (0xbffffd77L & (1L << ((c)-0xb4))))) { \ + OUTCHAR(0x02d0 + (c)); \ + } else if ((c) == 0xa1) { \ + OUTCHAR(0x2018); \ + } else if ((c) == 0xa2) { \ + OUTCHAR(0x2019); \ + } else if ((c) == 0xaf) { \ + OUTCHAR(0x2015); \ + } + +static Py_ssize_t +iso2022processg2(const void *config, MultibyteCodec_State *state, + const unsigned char **inbuf, Py_ssize_t *inleft, + _PyUnicodeWriter *writer) +{ + /* not written to use encoder, decoder functions because only few + * encodings use G2 designations in CJKCodecs */ + if (STATE_G2 == CHARSET_ISO8859_1) { + if (INBYTE3 < 0x80) + OUTCHAR(INBYTE3 + 0x80); + else + return 3; + } + else if (STATE_G2 == CHARSET_ISO8859_7) { + ISO8859_7_DECODE(INBYTE3 ^ 0x80, writer) + else + return 3; + } + else if (STATE_G2 == CHARSET_ASCII) { + if (INBYTE3 & 0x80) + return 3; + else + OUTCHAR(INBYTE3); + } + else + return MBERR_INTERNAL; + + (*inbuf) += 3; + *inleft -= 3; + return 0; +} + +DECODER(iso2022) +{ + const struct iso2022_designation *dsgcache = NULL; + + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_ssize_t err; + + if (STATE_GETFLAG(F_ESCTHROUGHOUT)) { + /* ESC throughout mode: + * for non-iso2022 escape sequences */ + OUTCHAR(c); /* assume as ISO-8859-1 */ + NEXT_IN(1); + if (IS_ESCEND(c)) { + STATE_CLEARFLAG(F_ESCTHROUGHOUT); + } + continue; + } + + switch (c) { + case ESC: + REQUIRE_INBUF(2); + if (IS_ISO2022ESC(INBYTE2)) { + err = iso2022processesc(config, state, + inbuf, &inleft); + if (err != 0) + return err; + } + else if (CONFIG_ISSET(USE_G2) && INBYTE2 == 'N') {/* SS2 */ + REQUIRE_INBUF(3); + err = iso2022processg2(config, state, + inbuf, &inleft, writer); + if (err != 0) + return err; + } + else { + OUTCHAR(ESC); + STATE_SETFLAG(F_ESCTHROUGHOUT); + NEXT_IN(1); + } + break; + case SI: + if (CONFIG_ISSET(NO_SHIFT)) + goto bypass; + STATE_CLEARFLAG(F_SHIFTED); + NEXT_IN(1); + break; + case SO: + if (CONFIG_ISSET(NO_SHIFT)) + goto bypass; + STATE_SETFLAG(F_SHIFTED); + NEXT_IN(1); + break; + case LF: + STATE_CLEARFLAG(F_SHIFTED); + OUTCHAR(LF); + NEXT_IN(1); + break; + default: + if (c < 0x20) /* C0 */ + goto bypass; + else if (c >= 0x80) + return 1; + else { + const struct iso2022_designation *dsg; + unsigned char charset; + Py_UCS4 decoded; + + if (STATE_GETFLAG(F_SHIFTED)) + charset = STATE_G1; + else + charset = STATE_G0; + + if (charset == CHARSET_ASCII) { +bypass: + OUTCHAR(c); + NEXT_IN(1); + break; + } + + if (dsgcache != NULL && + dsgcache->mark == charset) + dsg = dsgcache; + else { + for (dsg = CONFIG_DESIGNATIONS; + dsg->mark != charset +#ifdef Py_DEBUG + && dsg->mark != '\0' +#endif + ; dsg++) + { + /* noop */ + } + assert(dsg->mark != '\0'); + dsgcache = dsg; + } + + REQUIRE_INBUF(dsg->width); + decoded = dsg->decoder(*inbuf); + if (decoded == MAP_UNMAPPABLE) + return dsg->width; + + if (decoded < 0x10000) { + OUTCHAR(decoded); + } + else if (decoded < 0x30000) { + OUTCHAR(decoded); + } + else { /* JIS X 0213 pairs */ + OUTCHAR2(decoded >> 16, decoded & 0xffff); + } + NEXT_IN(dsg->width); + } + break; + } + } + return 0; +} + +/*-*- mapping table holders -*-*/ + +#define ENCMAP(enc) static const encode_map *enc##_encmap = NULL; +#define DECMAP(enc) static const decode_map *enc##_decmap = NULL; + +/* kr */ +ENCMAP(cp949) +DECMAP(ksx1001) + +/* jp */ +ENCMAP(jisxcommon) +DECMAP(jisx0208) +DECMAP(jisx0212) +ENCMAP(jisx0213_bmp) +DECMAP(jisx0213_1_bmp) +DECMAP(jisx0213_2_bmp) +ENCMAP(jisx0213_emp) +DECMAP(jisx0213_1_emp) +DECMAP(jisx0213_2_emp) + +/* cn */ +ENCMAP(gbcommon) +DECMAP(gb2312) + +/* tw */ + +/*-*- mapping access functions -*-*/ + +static int +ksx1001_init(void) +{ + static int initialized = 0; + + if (!initialized && ( + IMPORT_MAP(kr, cp949, &cp949_encmap, NULL) || + IMPORT_MAP(kr, ksx1001, NULL, &ksx1001_decmap))) + return -1; + initialized = 1; + return 0; +} + +static Py_UCS4 +ksx1001_decoder(const unsigned char *data) +{ + Py_UCS4 u; + if (TRYMAP_DEC(ksx1001, u, data[0], data[1])) + return u; + else + return MAP_UNMAPPABLE; +} + +static DBCHAR +ksx1001_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded; + assert(*length == 1); + if (*data < 0x10000) { + if (TRYMAP_ENC(cp949, coded, *data)) { + if (!(coded & 0x8000)) + return coded; + } + } + return MAP_UNMAPPABLE; +} + +static int +jisx0208_init(void) +{ + static int initialized = 0; + + if (!initialized && ( + IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) || + IMPORT_MAP(jp, jisx0208, NULL, &jisx0208_decmap))) + return -1; + initialized = 1; + return 0; +} + +static Py_UCS4 +jisx0208_decoder(const unsigned char *data) +{ + Py_UCS4 u; + if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ + return 0xff3c; + else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) + return u; + else + return MAP_UNMAPPABLE; +} + +static DBCHAR +jisx0208_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded; + assert(*length == 1); + if (*data < 0x10000) { + if (*data == 0xff3c) /* F/W REVERSE SOLIDUS */ + return 0x2140; + else if (TRYMAP_ENC(jisxcommon, coded, *data)) { + if (!(coded & 0x8000)) + return coded; + } + } + return MAP_UNMAPPABLE; +} + +static int +jisx0212_init(void) +{ + static int initialized = 0; + + if (!initialized && ( + IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) || + IMPORT_MAP(jp, jisx0212, NULL, &jisx0212_decmap))) + return -1; + initialized = 1; + return 0; +} + +static Py_UCS4 +jisx0212_decoder(const unsigned char *data) +{ + Py_UCS4 u; + if (TRYMAP_DEC(jisx0212, u, data[0], data[1])) + return u; + else + return MAP_UNMAPPABLE; +} + +static DBCHAR +jisx0212_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded; + assert(*length == 1); + if (*data < 0x10000) { + if (TRYMAP_ENC(jisxcommon, coded, *data)) { + if (coded & 0x8000) + return coded & 0x7fff; + } + } + return MAP_UNMAPPABLE; +} + +static int +jisx0213_init(void) +{ + static int initialized = 0; + + if (!initialized && ( + jisx0208_init() || + IMPORT_MAP(jp, jisx0213_bmp, + &jisx0213_bmp_encmap, NULL) || + IMPORT_MAP(jp, jisx0213_1_bmp, + NULL, &jisx0213_1_bmp_decmap) || + IMPORT_MAP(jp, jisx0213_2_bmp, + NULL, &jisx0213_2_bmp_decmap) || + IMPORT_MAP(jp, jisx0213_emp, + &jisx0213_emp_encmap, NULL) || + IMPORT_MAP(jp, jisx0213_1_emp, + NULL, &jisx0213_1_emp_decmap) || + IMPORT_MAP(jp, jisx0213_2_emp, + NULL, &jisx0213_2_emp_decmap) || + IMPORT_MAP(jp, jisx0213_pair, &jisx0213_pair_encmap, + &jisx0213_pair_decmap))) + return -1; + initialized = 1; + return 0; +} + +#define config ((void *)2000) +static Py_UCS4 +jisx0213_2000_1_decoder(const unsigned char *data) +{ + Py_UCS4 u; + EMULATE_JISX0213_2000_DECODE_PLANE1(u, data[0], data[1]) + else if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ + return 0xff3c; + else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) + ; + else if (TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1])) + ; + else if (TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])) + u |= 0x20000; + else if (TRYMAP_DEC(jisx0213_pair, u, data[0], data[1])) + ; + else + return MAP_UNMAPPABLE; + return u; +} + +static Py_UCS4 +jisx0213_2000_2_decoder(const unsigned char *data) +{ + Py_UCS4 u; + EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(u, data[0], data[1]) + if (TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1])) + ; + else if (TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])) + u |= 0x20000; + else + return MAP_UNMAPPABLE; + return u; +} +#undef config + +static Py_UCS4 +jisx0213_2004_1_decoder(const unsigned char *data) +{ + Py_UCS4 u; + if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ + return 0xff3c; + else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) + ; + else if (TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1])) + ; + else if (TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])) + u |= 0x20000; + else if (TRYMAP_DEC(jisx0213_pair, u, data[0], data[1])) + ; + else + return MAP_UNMAPPABLE; + return u; +} + +static Py_UCS4 +jisx0213_2004_2_decoder(const unsigned char *data) +{ + Py_UCS4 u; + if (TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1])) + ; + else if (TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])) + u |= 0x20000; + else + return MAP_UNMAPPABLE; + return u; +} + +static DBCHAR +jisx0213_encoder(const Py_UCS4 *data, Py_ssize_t *length, void *config) +{ + DBCHAR coded; + + switch (*length) { + case 1: /* first character */ + if (*data >= 0x10000) { + if ((*data) >> 16 == 0x20000 >> 16) { + EMULATE_JISX0213_2000_ENCODE_EMP(coded, *data) + else if (TRYMAP_ENC(jisx0213_emp, coded, (*data) & 0xffff)) + return coded; + } + return MAP_UNMAPPABLE; + } + + EMULATE_JISX0213_2000_ENCODE_BMP(coded, *data) + else if (TRYMAP_ENC(jisx0213_bmp, coded, *data)) { + if (coded == MULTIC) + return MAP_MULTIPLE_AVAIL; + } + else if (TRYMAP_ENC(jisxcommon, coded, *data)) { + if (coded & 0x8000) + return MAP_UNMAPPABLE; + } + else + return MAP_UNMAPPABLE; + return coded; + + case 2: /* second character of unicode pair */ + coded = find_pairencmap((ucs2_t)data[0], (ucs2_t)data[1], + jisx0213_pair_encmap, JISX0213_ENCPAIRS); + if (coded != DBCINV) + return coded; + /* fall through */ + + case -1: /* flush unterminated */ + *length = 1; + coded = find_pairencmap((ucs2_t)data[0], 0, + jisx0213_pair_encmap, JISX0213_ENCPAIRS); + if (coded == DBCINV) + return MAP_UNMAPPABLE; + else + return coded; + break; + + default: + return MAP_UNMAPPABLE; + } +} + +static DBCHAR +jisx0213_2000_1_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded = jisx0213_encoder(data, length, (void *)2000); + if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) + return coded; + else if (coded & 0x8000) + return MAP_UNMAPPABLE; + else + return coded; +} + +static DBCHAR +jisx0213_2000_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded; + Py_ssize_t ilength = *length; + + coded = jisx0213_encoder(data, length, (void *)2000); + switch (ilength) { + case 1: + if (coded == MAP_MULTIPLE_AVAIL) + return MAP_MULTIPLE_AVAIL; + else + return MAP_UNMAPPABLE; + case 2: + if (*length != 2) + return MAP_UNMAPPABLE; + else + return coded; + default: + return MAP_UNMAPPABLE; + } +} + +static DBCHAR +jisx0213_2000_2_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded = jisx0213_encoder(data, length, (void *)2000); + if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) + return coded; + else if (coded & 0x8000) + return coded & 0x7fff; + else + return MAP_UNMAPPABLE; +} + +static DBCHAR +jisx0213_2004_1_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded = jisx0213_encoder(data, length, NULL); + if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) + return coded; + else if (coded & 0x8000) + return MAP_UNMAPPABLE; + else + return coded; +} + +static DBCHAR +jisx0213_2004_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded; + Py_ssize_t ilength = *length; + + coded = jisx0213_encoder(data, length, NULL); + switch (ilength) { + case 1: + if (coded == MAP_MULTIPLE_AVAIL) + return MAP_MULTIPLE_AVAIL; + else + return MAP_UNMAPPABLE; + case 2: + if (*length != 2) + return MAP_UNMAPPABLE; + else + return coded; + default: + return MAP_UNMAPPABLE; + } +} + +static DBCHAR +jisx0213_2004_2_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded = jisx0213_encoder(data, length, NULL); + if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) + return coded; + else if (coded & 0x8000) + return coded & 0x7fff; + else + return MAP_UNMAPPABLE; +} + +static Py_UCS4 +jisx0201_r_decoder(const unsigned char *data) +{ + Py_UCS4 u; + JISX0201_R_DECODE_CHAR(*data, u) + else + return MAP_UNMAPPABLE; + return u; +} + +static DBCHAR +jisx0201_r_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded; + JISX0201_R_ENCODE(*data, coded) + else + return MAP_UNMAPPABLE; + return coded; +} + +static Py_UCS4 +jisx0201_k_decoder(const unsigned char *data) +{ + Py_UCS4 u; + JISX0201_K_DECODE_CHAR(*data ^ 0x80, u) + else + return MAP_UNMAPPABLE; + return u; +} + +static DBCHAR +jisx0201_k_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded; + JISX0201_K_ENCODE(*data, coded) + else + return MAP_UNMAPPABLE; + return coded - 0x80; +} + +static int +gb2312_init(void) +{ + static int initialized = 0; + + if (!initialized && ( + IMPORT_MAP(cn, gbcommon, &gbcommon_encmap, NULL) || + IMPORT_MAP(cn, gb2312, NULL, &gb2312_decmap))) + return -1; + initialized = 1; + return 0; +} + +static Py_UCS4 +gb2312_decoder(const unsigned char *data) +{ + Py_UCS4 u; + if (TRYMAP_DEC(gb2312, u, data[0], data[1])) + return u; + else + return MAP_UNMAPPABLE; +} + +static DBCHAR +gb2312_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + DBCHAR coded; + assert(*length == 1); + if (*data < 0x10000) { + if (TRYMAP_ENC(gbcommon, coded, *data)) { + if (!(coded & 0x8000)) + return coded; + } + } + return MAP_UNMAPPABLE; +} + + +static Py_UCS4 +dummy_decoder(const unsigned char *data) +{ + return MAP_UNMAPPABLE; +} + +static DBCHAR +dummy_encoder(const Py_UCS4 *data, Py_ssize_t *length) +{ + return MAP_UNMAPPABLE; +} + +/*-*- registry tables -*-*/ + +#define REGISTRY_KSX1001_G0 { CHARSET_KSX1001, 0, 2, \ + ksx1001_init, \ + ksx1001_decoder, ksx1001_encoder } +#define REGISTRY_KSX1001_G1 { CHARSET_KSX1001, 1, 2, \ + ksx1001_init, \ + ksx1001_decoder, ksx1001_encoder } +#define REGISTRY_JISX0201_R { CHARSET_JISX0201_R, 0, 1, \ + NULL, \ + jisx0201_r_decoder, jisx0201_r_encoder } +#define REGISTRY_JISX0201_K { CHARSET_JISX0201_K, 0, 1, \ + NULL, \ + jisx0201_k_decoder, jisx0201_k_encoder } +#define REGISTRY_JISX0208 { CHARSET_JISX0208, 0, 2, \ + jisx0208_init, \ + jisx0208_decoder, jisx0208_encoder } +#define REGISTRY_JISX0208_O { CHARSET_JISX0208_O, 0, 2, \ + jisx0208_init, \ + jisx0208_decoder, jisx0208_encoder } +#define REGISTRY_JISX0212 { CHARSET_JISX0212, 0, 2, \ + jisx0212_init, \ + jisx0212_decoder, jisx0212_encoder } +#define REGISTRY_JISX0213_2000_1 { CHARSET_JISX0213_2000_1, 0, 2, \ + jisx0213_init, \ + jisx0213_2000_1_decoder, \ + jisx0213_2000_1_encoder } +#define REGISTRY_JISX0213_2000_1_PAIRONLY { CHARSET_JISX0213_2000_1, 0, 2, \ + jisx0213_init, \ + jisx0213_2000_1_decoder, \ + jisx0213_2000_1_encoder_paironly } +#define REGISTRY_JISX0213_2000_2 { CHARSET_JISX0213_2, 0, 2, \ + jisx0213_init, \ + jisx0213_2000_2_decoder, \ + jisx0213_2000_2_encoder } +#define REGISTRY_JISX0213_2004_1 { CHARSET_JISX0213_2004_1, 0, 2, \ + jisx0213_init, \ + jisx0213_2004_1_decoder, \ + jisx0213_2004_1_encoder } +#define REGISTRY_JISX0213_2004_1_PAIRONLY { CHARSET_JISX0213_2004_1, 0, 2, \ + jisx0213_init, \ + jisx0213_2004_1_decoder, \ + jisx0213_2004_1_encoder_paironly } +#define REGISTRY_JISX0213_2004_2 { CHARSET_JISX0213_2, 0, 2, \ + jisx0213_init, \ + jisx0213_2004_2_decoder, \ + jisx0213_2004_2_encoder } +#define REGISTRY_GB2312 { CHARSET_GB2312, 0, 2, \ + gb2312_init, \ + gb2312_decoder, gb2312_encoder } +#define REGISTRY_CNS11643_1 { CHARSET_CNS11643_1, 1, 2, \ + cns11643_init, \ + cns11643_1_decoder, cns11643_1_encoder } +#define REGISTRY_CNS11643_2 { CHARSET_CNS11643_2, 2, 2, \ + cns11643_init, \ + cns11643_2_decoder, cns11643_2_encoder } +#define REGISTRY_ISO8859_1 { CHARSET_ISO8859_1, 2, 1, \ + NULL, dummy_decoder, dummy_encoder } +#define REGISTRY_ISO8859_7 { CHARSET_ISO8859_7, 2, 1, \ + NULL, dummy_decoder, dummy_encoder } +#define REGISTRY_SENTINEL { 0, } +#define CONFIGDEF(var, attrs) \ + static const struct iso2022_config iso2022_##var##_config = { \ + attrs, iso2022_##var##_designations \ + }; + +static const struct iso2022_designation iso2022_kr_designations[] = { + REGISTRY_KSX1001_G1, REGISTRY_SENTINEL +}; +CONFIGDEF(kr, 0) + +static const struct iso2022_designation iso2022_jp_designations[] = { + REGISTRY_JISX0208, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O, + REGISTRY_SENTINEL +}; +CONFIGDEF(jp, NO_SHIFT | USE_JISX0208_EXT) + +static const struct iso2022_designation iso2022_jp_1_designations[] = { + REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R, + REGISTRY_JISX0208_O, REGISTRY_SENTINEL +}; +CONFIGDEF(jp_1, NO_SHIFT | USE_JISX0208_EXT) + +static const struct iso2022_designation iso2022_jp_2_designations[] = { + REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_KSX1001_G0, + REGISTRY_GB2312, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O, + REGISTRY_ISO8859_1, REGISTRY_ISO8859_7, REGISTRY_SENTINEL +}; +CONFIGDEF(jp_2, NO_SHIFT | USE_G2 | USE_JISX0208_EXT) + +static const struct iso2022_designation iso2022_jp_2004_designations[] = { + REGISTRY_JISX0213_2004_1_PAIRONLY, REGISTRY_JISX0208, + REGISTRY_JISX0213_2004_1, REGISTRY_JISX0213_2004_2, REGISTRY_SENTINEL +}; +CONFIGDEF(jp_2004, NO_SHIFT | USE_JISX0208_EXT) + +static const struct iso2022_designation iso2022_jp_3_designations[] = { + REGISTRY_JISX0213_2000_1_PAIRONLY, REGISTRY_JISX0208, + REGISTRY_JISX0213_2000_1, REGISTRY_JISX0213_2000_2, REGISTRY_SENTINEL +}; +CONFIGDEF(jp_3, NO_SHIFT | USE_JISX0208_EXT) + +static const struct iso2022_designation iso2022_jp_ext_designations[] = { + REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R, + REGISTRY_JISX0201_K, REGISTRY_JISX0208_O, REGISTRY_SENTINEL +}; +CONFIGDEF(jp_ext, NO_SHIFT | USE_JISX0208_EXT) + + +BEGIN_MAPPINGS_LIST + /* no mapping table here */ +END_MAPPINGS_LIST + +#define ISO2022_CODEC(variation) { \ + "iso2022_" #variation, \ + &iso2022_##variation##_config, \ + iso2022_codec_init, \ + _STATEFUL_METHODS(iso2022) \ +}, + +BEGIN_CODECS_LIST + ISO2022_CODEC(kr) + ISO2022_CODEC(jp) + ISO2022_CODEC(jp_1) + ISO2022_CODEC(jp_2) + ISO2022_CODEC(jp_2004) + ISO2022_CODEC(jp_3) + ISO2022_CODEC(jp_ext) +END_CODECS_LIST + +I_AM_A_MODULE_FOR(iso2022) diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_jp.c b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_jp.c index 3a332953b95..76311e58e90 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_jp.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_jp.c @@ -1,760 +1,760 @@ -/* - * _codecs_jp.c: Codecs collection for Japanese encodings - * - * Written by Hye-Shik Chang - */ - -#define USING_BINARY_PAIR_SEARCH -#define EMPBASE 0x20000 - -#include "cjkcodecs.h" -#include "mappings_jp.h" -#include "mappings_jisx0213_pair.h" -#include "alg_jisx0201.h" -#include "emu_jisx0213_2000.h" - -/* - * CP932 codec - */ - -ENCODER(cp932) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - unsigned char c1, c2; - - if (c <= 0x80) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - else if (c >= 0xff61 && c <= 0xff9f) { - WRITEBYTE1(c - 0xfec0); - NEXT(1, 1); - continue; - } - else if (c >= 0xf8f0 && c <= 0xf8f3) { - /* Windows compatibility */ - REQUIRE_OUTBUF(1); - if (c == 0xf8f0) - OUTBYTE1(0xa0); - else - OUTBYTE1(c - 0xf8f1 + 0xfd); - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - REQUIRE_OUTBUF(2); - - if (TRYMAP_ENC(cp932ext, code, c)) { - OUTBYTE1(code >> 8); - OUTBYTE2(code & 0xff); - } - else if (TRYMAP_ENC(jisxcommon, code, c)) { - if (code & 0x8000) /* MSB set: JIS X 0212 */ - return 1; - - /* JIS X 0208 */ - c1 = code >> 8; - c2 = code & 0xff; - c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21); - c1 = (c1 - 0x21) >> 1; - OUTBYTE1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1); - OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41); - } - else if (c >= 0xe000 && c < 0xe758) { - /* User-defined area */ - c1 = (Py_UCS4)(c - 0xe000) / 188; - c2 = (Py_UCS4)(c - 0xe000) % 188; - OUTBYTE1(c1 + 0xf0); - OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41); - } - else - return 1; - - NEXT(1, 2); - } - - return 0; -} - -DECODER(cp932) -{ - while (inleft > 0) { - unsigned char c = INBYTE1, c2; - Py_UCS4 decoded; - - if (c <= 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - else if (c >= 0xa0 && c <= 0xdf) { - if (c == 0xa0) - OUTCHAR(0xf8f0); /* half-width katakana */ - else - OUTCHAR(0xfec0 + c); - NEXT_IN(1); - continue; - } - else if (c >= 0xfd/* && c <= 0xff*/) { - /* Windows compatibility */ - OUTCHAR(0xf8f1 - 0xfd + c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - c2 = INBYTE2; - - if (TRYMAP_DEC(cp932ext, decoded, c, c2)) - OUTCHAR(decoded); - else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){ - if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc) - return 1; - - c = (c < 0xe0 ? c - 0x81 : c - 0xc1); - c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41); - c = (2 * c + (c2 < 0x5e ? 0 : 1) + 0x21); - c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21; - - if (TRYMAP_DEC(jisx0208, decoded, c, c2)) - OUTCHAR(decoded); - else - return 1; - } - else if (c >= 0xf0 && c <= 0xf9) { - if ((c2 >= 0x40 && c2 <= 0x7e) || - (c2 >= 0x80 && c2 <= 0xfc)) - OUTCHAR(0xe000 + 188 * (c - 0xf0) + - (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41)); - else - return 1; - } - else - return 1; - - NEXT_IN(2); - } - - return 0; -} - - -/* - * EUC-JIS-2004 codec - */ - -ENCODER(euc_jis_2004) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - Py_ssize_t insize; - - if (c < 0x80) { - WRITEBYTE1(c); - NEXT(1, 1); - continue; - } - - insize = 1; - - if (c <= 0xFFFF) { - EMULATE_JISX0213_2000_ENCODE_BMP(code, c) - else if (TRYMAP_ENC(jisx0213_bmp, code, c)) { - if (code == MULTIC) { - if (inlen - *inpos < 2) { - if (flags & MBENC_FLUSH) { - code = find_pairencmap( - (ucs2_t)c, 0, - jisx0213_pair_encmap, - JISX0213_ENCPAIRS); - if (code == DBCINV) - return 1; - } - else - return MBERR_TOOFEW; - } - else { - Py_UCS4 c2 = INCHAR2; - code = find_pairencmap( - (ucs2_t)c, c2, - jisx0213_pair_encmap, - JISX0213_ENCPAIRS); - if (code == DBCINV) { - code = find_pairencmap( - (ucs2_t)c, 0, - jisx0213_pair_encmap, - JISX0213_ENCPAIRS); - if (code == DBCINV) - return 1; - } else - insize = 2; - } - } - } - else if (TRYMAP_ENC(jisxcommon, code, c)) - ; - else if (c >= 0xff61 && c <= 0xff9f) { - /* JIS X 0201 half-width katakana */ - WRITEBYTE2(0x8e, c - 0xfec0); - NEXT(1, 2); - continue; - } - else if (c == 0xff3c) - /* F/W REVERSE SOLIDUS (see NOTES) */ - code = 0x2140; - else if (c == 0xff5e) - /* F/W TILDE (see NOTES) */ - code = 0x2232; - else - return 1; - } - else if (c >> 16 == EMPBASE >> 16) { - EMULATE_JISX0213_2000_ENCODE_EMP(code, c) - else if (TRYMAP_ENC(jisx0213_emp, code, c & 0xffff)) - ; - else - return insize; - } - else - return insize; - - if (code & 0x8000) { - /* Codeset 2 */ - WRITEBYTE3(0x8f, code >> 8, (code & 0xFF) | 0x80); - NEXT(insize, 3); - } else { - /* Codeset 1 */ - WRITEBYTE2((code >> 8) | 0x80, (code & 0xFF) | 0x80); - NEXT(insize, 2); - } - } - - return 0; -} - -DECODER(euc_jis_2004) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 code, decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - if (c == 0x8e) { - /* JIS X 0201 half-width katakana */ - unsigned char c2; - - REQUIRE_INBUF(2); - c2 = INBYTE2; - if (c2 >= 0xa1 && c2 <= 0xdf) { - OUTCHAR(0xfec0 + c2); - NEXT_IN(2); - } - else - return 1; - } - else if (c == 0x8f) { - unsigned char c2, c3; - - REQUIRE_INBUF(3); - c2 = INBYTE2 ^ 0x80; - c3 = INBYTE3 ^ 0x80; - - /* JIS X 0213 Plane 2 or JIS X 0212 (see NOTES) */ - EMULATE_JISX0213_2000_DECODE_PLANE2(writer, c2, c3) - else if (TRYMAP_DEC(jisx0213_2_bmp, decoded, c2, c3)) - OUTCHAR(decoded); - else if (TRYMAP_DEC(jisx0213_2_emp, code, c2, c3)) { - OUTCHAR(EMPBASE | code); - NEXT_IN(3); - continue; - } - else if (TRYMAP_DEC(jisx0212, decoded, c2, c3)) - OUTCHAR(decoded); - else - return 1; - NEXT_IN(3); - } - else { - unsigned char c2; - - REQUIRE_INBUF(2); - c ^= 0x80; - c2 = INBYTE2 ^ 0x80; - - /* JIS X 0213 Plane 1 */ - EMULATE_JISX0213_2000_DECODE_PLANE1(writer, c, c2) - else if (c == 0x21 && c2 == 0x40) - OUTCHAR(0xff3c); - else if (c == 0x22 && c2 == 0x32) - OUTCHAR(0xff5e); - else if (TRYMAP_DEC(jisx0208, decoded, c, c2)) - OUTCHAR(decoded); - else if (TRYMAP_DEC(jisx0213_1_bmp, decoded, c, c2)) - OUTCHAR(decoded); - else if (TRYMAP_DEC(jisx0213_1_emp, code, c, c2)) { - OUTCHAR(EMPBASE | code); - NEXT_IN(2); - continue; - } - else if (TRYMAP_DEC(jisx0213_pair, code, c, c2)) { - OUTCHAR2(code >> 16, code & 0xffff); - NEXT_IN(2); - continue; - } - else - return 1; - NEXT_IN(2); - } - } - - return 0; -} - - -/* - * EUC-JP codec - */ - -ENCODER(euc_jp) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - - if (TRYMAP_ENC(jisxcommon, code, c)) - ; - else if (c >= 0xff61 && c <= 0xff9f) { - /* JIS X 0201 half-width katakana */ - WRITEBYTE2(0x8e, c - 0xfec0); - NEXT(1, 2); - continue; - } -#ifndef STRICT_BUILD - else if (c == 0xff3c) /* FULL-WIDTH REVERSE SOLIDUS */ - code = 0x2140; - else if (c == 0xa5) { /* YEN SIGN */ - WRITEBYTE1(0x5c); - NEXT(1, 1); - continue; - } else if (c == 0x203e) { /* OVERLINE */ - WRITEBYTE1(0x7e); - NEXT(1, 1); - continue; - } -#endif - else - return 1; - - if (code & 0x8000) { - /* JIS X 0212 */ - WRITEBYTE3(0x8f, code >> 8, (code & 0xFF) | 0x80); - NEXT(1, 3); - } else { - /* JIS X 0208 */ - WRITEBYTE2((code >> 8) | 0x80, (code & 0xFF) | 0x80); - NEXT(1, 2); - } - } - - return 0; -} - -DECODER(euc_jp) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - if (c == 0x8e) { - /* JIS X 0201 half-width katakana */ - unsigned char c2; - - REQUIRE_INBUF(2); - c2 = INBYTE2; - if (c2 >= 0xa1 && c2 <= 0xdf) { - OUTCHAR(0xfec0 + c2); - NEXT_IN(2); - } - else - return 1; - } - else if (c == 0x8f) { - unsigned char c2, c3; - - REQUIRE_INBUF(3); - c2 = INBYTE2; - c3 = INBYTE3; - /* JIS X 0212 */ - if (TRYMAP_DEC(jisx0212, decoded, c2 ^ 0x80, c3 ^ 0x80)) { - OUTCHAR(decoded); - NEXT_IN(3); - } - else - return 1; - } - else { - unsigned char c2; - - REQUIRE_INBUF(2); - c2 = INBYTE2; - /* JIS X 0208 */ -#ifndef STRICT_BUILD - if (c == 0xa1 && c2 == 0xc0) - /* FULL-WIDTH REVERSE SOLIDUS */ - OUTCHAR(0xff3c); - else -#endif - if (TRYMAP_DEC(jisx0208, decoded, c ^ 0x80, c2 ^ 0x80)) - OUTCHAR(decoded); - else - return 1; - NEXT_IN(2); - } - } - - return 0; -} - - -/* - * SHIFT_JIS codec - */ - -ENCODER(shift_jis) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - unsigned char c1, c2; - -#ifdef STRICT_BUILD - JISX0201_R_ENCODE(c, code) -#else - if (c < 0x80) - code = c; - else if (c == 0x00a5) - code = 0x5c; /* YEN SIGN */ - else if (c == 0x203e) - code = 0x7e; /* OVERLINE */ -#endif - else JISX0201_K_ENCODE(c, code) - else if (c > 0xFFFF) - return 1; - else - code = NOCHAR; - - if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) { - REQUIRE_OUTBUF(1); - - OUTBYTE1((unsigned char)code); - NEXT(1, 1); - continue; - } - - REQUIRE_OUTBUF(2); - - if (code == NOCHAR) { - if (TRYMAP_ENC(jisxcommon, code, c)) - ; -#ifndef STRICT_BUILD - else if (c == 0xff3c) - code = 0x2140; /* FULL-WIDTH REVERSE SOLIDUS */ -#endif - else - return 1; - - if (code & 0x8000) /* MSB set: JIS X 0212 */ - return 1; - } - - c1 = code >> 8; - c2 = code & 0xff; - c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21); - c1 = (c1 - 0x21) >> 1; - OUTBYTE1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1); - OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41); - NEXT(1, 2); - } - - return 0; -} - -DECODER(shift_jis) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - -#ifdef STRICT_BUILD - JISX0201_R_DECODE(c, writer) -#else - if (c < 0x80) - OUTCHAR(c); -#endif - else JISX0201_K_DECODE(c, writer) - else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){ - unsigned char c1, c2; - - REQUIRE_INBUF(2); - c2 = INBYTE2; - if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc) - return 1; - - c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1); - c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41); - c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1) + 0x21); - c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21; - -#ifndef STRICT_BUILD - if (c1 == 0x21 && c2 == 0x40) { - /* FULL-WIDTH REVERSE SOLIDUS */ - OUTCHAR(0xff3c); - NEXT_IN(2); - continue; - } -#endif - if (TRYMAP_DEC(jisx0208, decoded, c1, c2)) { - OUTCHAR(decoded); - NEXT_IN(2); - continue; - } - else - return 1; - } - else - return 1; - - NEXT_IN(1); /* JIS X 0201 */ - } - - return 0; -} - - -/* - * SHIFT_JIS-2004 codec - */ - -ENCODER(shift_jis_2004) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code = NOCHAR; - int c1, c2; - Py_ssize_t insize; - - JISX0201_ENCODE(c, code) - - if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) { - WRITEBYTE1((unsigned char)code); - NEXT(1, 1); - continue; - } - - REQUIRE_OUTBUF(2); - insize = 1; - - if (code == NOCHAR) { - if (c <= 0xffff) { - EMULATE_JISX0213_2000_ENCODE_BMP(code, c) - else if (TRYMAP_ENC(jisx0213_bmp, code, c)) { - if (code == MULTIC) { - if (inlen - *inpos < 2) { - if (flags & MBENC_FLUSH) { - code = find_pairencmap - ((ucs2_t)c, 0, - jisx0213_pair_encmap, - JISX0213_ENCPAIRS); - if (code == DBCINV) - return 1; - } - else - return MBERR_TOOFEW; - } - else { - Py_UCS4 ch2 = INCHAR2; - code = find_pairencmap( - (ucs2_t)c, ch2, - jisx0213_pair_encmap, - JISX0213_ENCPAIRS); - if (code == DBCINV) { - code = find_pairencmap( - (ucs2_t)c, 0, - jisx0213_pair_encmap, - JISX0213_ENCPAIRS); - if (code == DBCINV) - return 1; - } - else - insize = 2; - } - } - } - else if (TRYMAP_ENC(jisxcommon, code, c)) { - /* abandon JIS X 0212 codes */ - if (code & 0x8000) - return 1; - } - else - return 1; - } - else if (c >> 16 == EMPBASE >> 16) { - EMULATE_JISX0213_2000_ENCODE_EMP(code, c) - else if (TRYMAP_ENC(jisx0213_emp, code, c&0xffff)) - ; - else - return insize; - } - else - return insize; - } - - c1 = code >> 8; - c2 = (code & 0xff) - 0x21; - - if (c1 & 0x80) { - /* Plane 2 */ - if (c1 >= 0xee) - c1 -= 0x87; - else if (c1 >= 0xac || c1 == 0xa8) - c1 -= 0x49; - else - c1 -= 0x43; - } - else { - /* Plane 1 */ - c1 -= 0x21; - } - - if (c1 & 1) - c2 += 0x5e; - c1 >>= 1; - OUTBYTE1(c1 + (c1 < 0x1f ? 0x81 : 0xc1)); - OUTBYTE2(c2 + (c2 < 0x3f ? 0x40 : 0x41)); - - NEXT(insize, 2); - } - - return 0; -} - -DECODER(shift_jis_2004) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - - JISX0201_DECODE(c, writer) - else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)){ - unsigned char c1, c2; - Py_UCS4 code, decoded; - - REQUIRE_INBUF(2); - c2 = INBYTE2; - if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc) - return 1; - - c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1); - c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41); - c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1)); - c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21; - - if (c1 < 0x5e) { /* Plane 1 */ - c1 += 0x21; - EMULATE_JISX0213_2000_DECODE_PLANE1(writer, - c1, c2) - else if (TRYMAP_DEC(jisx0208, decoded, c1, c2)) - OUTCHAR(decoded); - else if (TRYMAP_DEC(jisx0213_1_bmp, decoded, c1, c2)) - OUTCHAR(decoded); - else if (TRYMAP_DEC(jisx0213_1_emp, code, c1, c2)) - OUTCHAR(EMPBASE | code); - else if (TRYMAP_DEC(jisx0213_pair, code, c1, c2)) - OUTCHAR2(code >> 16, code & 0xffff); - else - return 1; - NEXT_IN(2); - } - else { /* Plane 2 */ - if (c1 >= 0x67) - c1 += 0x07; - else if (c1 >= 0x63 || c1 == 0x5f) - c1 -= 0x37; - else - c1 -= 0x3d; - - EMULATE_JISX0213_2000_DECODE_PLANE2(writer, - c1, c2) - else if (TRYMAP_DEC(jisx0213_2_bmp, decoded, c1, c2)) - OUTCHAR(decoded); - else if (TRYMAP_DEC(jisx0213_2_emp, code, c1, c2)) { - OUTCHAR(EMPBASE | code); - NEXT_IN(2); - continue; - } - else - return 1; - NEXT_IN(2); - } - continue; - } - else - return 1; - - NEXT_IN(1); /* JIS X 0201 */ - } - - return 0; -} - - -BEGIN_MAPPINGS_LIST - MAPPING_DECONLY(jisx0208) - MAPPING_DECONLY(jisx0212) - MAPPING_ENCONLY(jisxcommon) - MAPPING_DECONLY(jisx0213_1_bmp) - MAPPING_DECONLY(jisx0213_2_bmp) - MAPPING_ENCONLY(jisx0213_bmp) - MAPPING_DECONLY(jisx0213_1_emp) - MAPPING_DECONLY(jisx0213_2_emp) - MAPPING_ENCONLY(jisx0213_emp) - MAPPING_ENCDEC(jisx0213_pair) - MAPPING_ENCDEC(cp932ext) -END_MAPPINGS_LIST - -BEGIN_CODECS_LIST - CODEC_STATELESS(shift_jis) - CODEC_STATELESS(cp932) - CODEC_STATELESS(euc_jp) - CODEC_STATELESS(shift_jis_2004) - CODEC_STATELESS(euc_jis_2004) - { "euc_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(euc_jis_2004) }, - { "shift_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(shift_jis_2004) }, -END_CODECS_LIST - -I_AM_A_MODULE_FOR(jp) +/* + * _codecs_jp.c: Codecs collection for Japanese encodings + * + * Written by Hye-Shik Chang + */ + +#define USING_BINARY_PAIR_SEARCH +#define EMPBASE 0x20000 + +#include "cjkcodecs.h" +#include "mappings_jp.h" +#include "mappings_jisx0213_pair.h" +#include "alg_jisx0201.h" +#include "emu_jisx0213_2000.h" + +/* + * CP932 codec + */ + +ENCODER(cp932) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + unsigned char c1, c2; + + if (c <= 0x80) { + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + else if (c >= 0xff61 && c <= 0xff9f) { + WRITEBYTE1(c - 0xfec0); + NEXT(1, 1); + continue; + } + else if (c >= 0xf8f0 && c <= 0xf8f3) { + /* Windows compatibility */ + REQUIRE_OUTBUF(1); + if (c == 0xf8f0) + OUTBYTE1(0xa0); + else + OUTBYTE1(c - 0xf8f1 + 0xfd); + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + REQUIRE_OUTBUF(2); + + if (TRYMAP_ENC(cp932ext, code, c)) { + OUTBYTE1(code >> 8); + OUTBYTE2(code & 0xff); + } + else if (TRYMAP_ENC(jisxcommon, code, c)) { + if (code & 0x8000) /* MSB set: JIS X 0212 */ + return 1; + + /* JIS X 0208 */ + c1 = code >> 8; + c2 = code & 0xff; + c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21); + c1 = (c1 - 0x21) >> 1; + OUTBYTE1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1); + OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41); + } + else if (c >= 0xe000 && c < 0xe758) { + /* User-defined area */ + c1 = (Py_UCS4)(c - 0xe000) / 188; + c2 = (Py_UCS4)(c - 0xe000) % 188; + OUTBYTE1(c1 + 0xf0); + OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41); + } + else + return 1; + + NEXT(1, 2); + } + + return 0; +} + +DECODER(cp932) +{ + while (inleft > 0) { + unsigned char c = INBYTE1, c2; + Py_UCS4 decoded; + + if (c <= 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + else if (c >= 0xa0 && c <= 0xdf) { + if (c == 0xa0) + OUTCHAR(0xf8f0); /* half-width katakana */ + else + OUTCHAR(0xfec0 + c); + NEXT_IN(1); + continue; + } + else if (c >= 0xfd/* && c <= 0xff*/) { + /* Windows compatibility */ + OUTCHAR(0xf8f1 - 0xfd + c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + c2 = INBYTE2; + + if (TRYMAP_DEC(cp932ext, decoded, c, c2)) + OUTCHAR(decoded); + else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){ + if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc) + return 1; + + c = (c < 0xe0 ? c - 0x81 : c - 0xc1); + c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41); + c = (2 * c + (c2 < 0x5e ? 0 : 1) + 0x21); + c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21; + + if (TRYMAP_DEC(jisx0208, decoded, c, c2)) + OUTCHAR(decoded); + else + return 1; + } + else if (c >= 0xf0 && c <= 0xf9) { + if ((c2 >= 0x40 && c2 <= 0x7e) || + (c2 >= 0x80 && c2 <= 0xfc)) + OUTCHAR(0xe000 + 188 * (c - 0xf0) + + (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41)); + else + return 1; + } + else + return 1; + + NEXT_IN(2); + } + + return 0; +} + + +/* + * EUC-JIS-2004 codec + */ + +ENCODER(euc_jis_2004) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + Py_ssize_t insize; + + if (c < 0x80) { + WRITEBYTE1(c); + NEXT(1, 1); + continue; + } + + insize = 1; + + if (c <= 0xFFFF) { + EMULATE_JISX0213_2000_ENCODE_BMP(code, c) + else if (TRYMAP_ENC(jisx0213_bmp, code, c)) { + if (code == MULTIC) { + if (inlen - *inpos < 2) { + if (flags & MBENC_FLUSH) { + code = find_pairencmap( + (ucs2_t)c, 0, + jisx0213_pair_encmap, + JISX0213_ENCPAIRS); + if (code == DBCINV) + return 1; + } + else + return MBERR_TOOFEW; + } + else { + Py_UCS4 c2 = INCHAR2; + code = find_pairencmap( + (ucs2_t)c, c2, + jisx0213_pair_encmap, + JISX0213_ENCPAIRS); + if (code == DBCINV) { + code = find_pairencmap( + (ucs2_t)c, 0, + jisx0213_pair_encmap, + JISX0213_ENCPAIRS); + if (code == DBCINV) + return 1; + } else + insize = 2; + } + } + } + else if (TRYMAP_ENC(jisxcommon, code, c)) + ; + else if (c >= 0xff61 && c <= 0xff9f) { + /* JIS X 0201 half-width katakana */ + WRITEBYTE2(0x8e, c - 0xfec0); + NEXT(1, 2); + continue; + } + else if (c == 0xff3c) + /* F/W REVERSE SOLIDUS (see NOTES) */ + code = 0x2140; + else if (c == 0xff5e) + /* F/W TILDE (see NOTES) */ + code = 0x2232; + else + return 1; + } + else if (c >> 16 == EMPBASE >> 16) { + EMULATE_JISX0213_2000_ENCODE_EMP(code, c) + else if (TRYMAP_ENC(jisx0213_emp, code, c & 0xffff)) + ; + else + return insize; + } + else + return insize; + + if (code & 0x8000) { + /* Codeset 2 */ + WRITEBYTE3(0x8f, code >> 8, (code & 0xFF) | 0x80); + NEXT(insize, 3); + } else { + /* Codeset 1 */ + WRITEBYTE2((code >> 8) | 0x80, (code & 0xFF) | 0x80); + NEXT(insize, 2); + } + } + + return 0; +} + +DECODER(euc_jis_2004) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 code, decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + if (c == 0x8e) { + /* JIS X 0201 half-width katakana */ + unsigned char c2; + + REQUIRE_INBUF(2); + c2 = INBYTE2; + if (c2 >= 0xa1 && c2 <= 0xdf) { + OUTCHAR(0xfec0 + c2); + NEXT_IN(2); + } + else + return 1; + } + else if (c == 0x8f) { + unsigned char c2, c3; + + REQUIRE_INBUF(3); + c2 = INBYTE2 ^ 0x80; + c3 = INBYTE3 ^ 0x80; + + /* JIS X 0213 Plane 2 or JIS X 0212 (see NOTES) */ + EMULATE_JISX0213_2000_DECODE_PLANE2(writer, c2, c3) + else if (TRYMAP_DEC(jisx0213_2_bmp, decoded, c2, c3)) + OUTCHAR(decoded); + else if (TRYMAP_DEC(jisx0213_2_emp, code, c2, c3)) { + OUTCHAR(EMPBASE | code); + NEXT_IN(3); + continue; + } + else if (TRYMAP_DEC(jisx0212, decoded, c2, c3)) + OUTCHAR(decoded); + else + return 1; + NEXT_IN(3); + } + else { + unsigned char c2; + + REQUIRE_INBUF(2); + c ^= 0x80; + c2 = INBYTE2 ^ 0x80; + + /* JIS X 0213 Plane 1 */ + EMULATE_JISX0213_2000_DECODE_PLANE1(writer, c, c2) + else if (c == 0x21 && c2 == 0x40) + OUTCHAR(0xff3c); + else if (c == 0x22 && c2 == 0x32) + OUTCHAR(0xff5e); + else if (TRYMAP_DEC(jisx0208, decoded, c, c2)) + OUTCHAR(decoded); + else if (TRYMAP_DEC(jisx0213_1_bmp, decoded, c, c2)) + OUTCHAR(decoded); + else if (TRYMAP_DEC(jisx0213_1_emp, code, c, c2)) { + OUTCHAR(EMPBASE | code); + NEXT_IN(2); + continue; + } + else if (TRYMAP_DEC(jisx0213_pair, code, c, c2)) { + OUTCHAR2(code >> 16, code & 0xffff); + NEXT_IN(2); + continue; + } + else + return 1; + NEXT_IN(2); + } + } + + return 0; +} + + +/* + * EUC-JP codec + */ + +ENCODER(euc_jp) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + + if (TRYMAP_ENC(jisxcommon, code, c)) + ; + else if (c >= 0xff61 && c <= 0xff9f) { + /* JIS X 0201 half-width katakana */ + WRITEBYTE2(0x8e, c - 0xfec0); + NEXT(1, 2); + continue; + } +#ifndef STRICT_BUILD + else if (c == 0xff3c) /* FULL-WIDTH REVERSE SOLIDUS */ + code = 0x2140; + else if (c == 0xa5) { /* YEN SIGN */ + WRITEBYTE1(0x5c); + NEXT(1, 1); + continue; + } else if (c == 0x203e) { /* OVERLINE */ + WRITEBYTE1(0x7e); + NEXT(1, 1); + continue; + } +#endif + else + return 1; + + if (code & 0x8000) { + /* JIS X 0212 */ + WRITEBYTE3(0x8f, code >> 8, (code & 0xFF) | 0x80); + NEXT(1, 3); + } else { + /* JIS X 0208 */ + WRITEBYTE2((code >> 8) | 0x80, (code & 0xFF) | 0x80); + NEXT(1, 2); + } + } + + return 0; +} + +DECODER(euc_jp) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + if (c == 0x8e) { + /* JIS X 0201 half-width katakana */ + unsigned char c2; + + REQUIRE_INBUF(2); + c2 = INBYTE2; + if (c2 >= 0xa1 && c2 <= 0xdf) { + OUTCHAR(0xfec0 + c2); + NEXT_IN(2); + } + else + return 1; + } + else if (c == 0x8f) { + unsigned char c2, c3; + + REQUIRE_INBUF(3); + c2 = INBYTE2; + c3 = INBYTE3; + /* JIS X 0212 */ + if (TRYMAP_DEC(jisx0212, decoded, c2 ^ 0x80, c3 ^ 0x80)) { + OUTCHAR(decoded); + NEXT_IN(3); + } + else + return 1; + } + else { + unsigned char c2; + + REQUIRE_INBUF(2); + c2 = INBYTE2; + /* JIS X 0208 */ +#ifndef STRICT_BUILD + if (c == 0xa1 && c2 == 0xc0) + /* FULL-WIDTH REVERSE SOLIDUS */ + OUTCHAR(0xff3c); + else +#endif + if (TRYMAP_DEC(jisx0208, decoded, c ^ 0x80, c2 ^ 0x80)) + OUTCHAR(decoded); + else + return 1; + NEXT_IN(2); + } + } + + return 0; +} + + +/* + * SHIFT_JIS codec + */ + +ENCODER(shift_jis) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + unsigned char c1, c2; + +#ifdef STRICT_BUILD + JISX0201_R_ENCODE(c, code) +#else + if (c < 0x80) + code = c; + else if (c == 0x00a5) + code = 0x5c; /* YEN SIGN */ + else if (c == 0x203e) + code = 0x7e; /* OVERLINE */ +#endif + else JISX0201_K_ENCODE(c, code) + else if (c > 0xFFFF) + return 1; + else + code = NOCHAR; + + if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) { + REQUIRE_OUTBUF(1); + + OUTBYTE1((unsigned char)code); + NEXT(1, 1); + continue; + } + + REQUIRE_OUTBUF(2); + + if (code == NOCHAR) { + if (TRYMAP_ENC(jisxcommon, code, c)) + ; +#ifndef STRICT_BUILD + else if (c == 0xff3c) + code = 0x2140; /* FULL-WIDTH REVERSE SOLIDUS */ +#endif + else + return 1; + + if (code & 0x8000) /* MSB set: JIS X 0212 */ + return 1; + } + + c1 = code >> 8; + c2 = code & 0xff; + c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21); + c1 = (c1 - 0x21) >> 1; + OUTBYTE1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1); + OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41); + NEXT(1, 2); + } + + return 0; +} + +DECODER(shift_jis) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + +#ifdef STRICT_BUILD + JISX0201_R_DECODE(c, writer) +#else + if (c < 0x80) + OUTCHAR(c); +#endif + else JISX0201_K_DECODE(c, writer) + else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){ + unsigned char c1, c2; + + REQUIRE_INBUF(2); + c2 = INBYTE2; + if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc) + return 1; + + c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1); + c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41); + c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1) + 0x21); + c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21; + +#ifndef STRICT_BUILD + if (c1 == 0x21 && c2 == 0x40) { + /* FULL-WIDTH REVERSE SOLIDUS */ + OUTCHAR(0xff3c); + NEXT_IN(2); + continue; + } +#endif + if (TRYMAP_DEC(jisx0208, decoded, c1, c2)) { + OUTCHAR(decoded); + NEXT_IN(2); + continue; + } + else + return 1; + } + else + return 1; + + NEXT_IN(1); /* JIS X 0201 */ + } + + return 0; +} + + +/* + * SHIFT_JIS-2004 codec + */ + +ENCODER(shift_jis_2004) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code = NOCHAR; + int c1, c2; + Py_ssize_t insize; + + JISX0201_ENCODE(c, code) + + if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) { + WRITEBYTE1((unsigned char)code); + NEXT(1, 1); + continue; + } + + REQUIRE_OUTBUF(2); + insize = 1; + + if (code == NOCHAR) { + if (c <= 0xffff) { + EMULATE_JISX0213_2000_ENCODE_BMP(code, c) + else if (TRYMAP_ENC(jisx0213_bmp, code, c)) { + if (code == MULTIC) { + if (inlen - *inpos < 2) { + if (flags & MBENC_FLUSH) { + code = find_pairencmap + ((ucs2_t)c, 0, + jisx0213_pair_encmap, + JISX0213_ENCPAIRS); + if (code == DBCINV) + return 1; + } + else + return MBERR_TOOFEW; + } + else { + Py_UCS4 ch2 = INCHAR2; + code = find_pairencmap( + (ucs2_t)c, ch2, + jisx0213_pair_encmap, + JISX0213_ENCPAIRS); + if (code == DBCINV) { + code = find_pairencmap( + (ucs2_t)c, 0, + jisx0213_pair_encmap, + JISX0213_ENCPAIRS); + if (code == DBCINV) + return 1; + } + else + insize = 2; + } + } + } + else if (TRYMAP_ENC(jisxcommon, code, c)) { + /* abandon JIS X 0212 codes */ + if (code & 0x8000) + return 1; + } + else + return 1; + } + else if (c >> 16 == EMPBASE >> 16) { + EMULATE_JISX0213_2000_ENCODE_EMP(code, c) + else if (TRYMAP_ENC(jisx0213_emp, code, c&0xffff)) + ; + else + return insize; + } + else + return insize; + } + + c1 = code >> 8; + c2 = (code & 0xff) - 0x21; + + if (c1 & 0x80) { + /* Plane 2 */ + if (c1 >= 0xee) + c1 -= 0x87; + else if (c1 >= 0xac || c1 == 0xa8) + c1 -= 0x49; + else + c1 -= 0x43; + } + else { + /* Plane 1 */ + c1 -= 0x21; + } + + if (c1 & 1) + c2 += 0x5e; + c1 >>= 1; + OUTBYTE1(c1 + (c1 < 0x1f ? 0x81 : 0xc1)); + OUTBYTE2(c2 + (c2 < 0x3f ? 0x40 : 0x41)); + + NEXT(insize, 2); + } + + return 0; +} + +DECODER(shift_jis_2004) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + + JISX0201_DECODE(c, writer) + else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)){ + unsigned char c1, c2; + Py_UCS4 code, decoded; + + REQUIRE_INBUF(2); + c2 = INBYTE2; + if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc) + return 1; + + c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1); + c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41); + c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1)); + c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21; + + if (c1 < 0x5e) { /* Plane 1 */ + c1 += 0x21; + EMULATE_JISX0213_2000_DECODE_PLANE1(writer, + c1, c2) + else if (TRYMAP_DEC(jisx0208, decoded, c1, c2)) + OUTCHAR(decoded); + else if (TRYMAP_DEC(jisx0213_1_bmp, decoded, c1, c2)) + OUTCHAR(decoded); + else if (TRYMAP_DEC(jisx0213_1_emp, code, c1, c2)) + OUTCHAR(EMPBASE | code); + else if (TRYMAP_DEC(jisx0213_pair, code, c1, c2)) + OUTCHAR2(code >> 16, code & 0xffff); + else + return 1; + NEXT_IN(2); + } + else { /* Plane 2 */ + if (c1 >= 0x67) + c1 += 0x07; + else if (c1 >= 0x63 || c1 == 0x5f) + c1 -= 0x37; + else + c1 -= 0x3d; + + EMULATE_JISX0213_2000_DECODE_PLANE2(writer, + c1, c2) + else if (TRYMAP_DEC(jisx0213_2_bmp, decoded, c1, c2)) + OUTCHAR(decoded); + else if (TRYMAP_DEC(jisx0213_2_emp, code, c1, c2)) { + OUTCHAR(EMPBASE | code); + NEXT_IN(2); + continue; + } + else + return 1; + NEXT_IN(2); + } + continue; + } + else + return 1; + + NEXT_IN(1); /* JIS X 0201 */ + } + + return 0; +} + + +BEGIN_MAPPINGS_LIST + MAPPING_DECONLY(jisx0208) + MAPPING_DECONLY(jisx0212) + MAPPING_ENCONLY(jisxcommon) + MAPPING_DECONLY(jisx0213_1_bmp) + MAPPING_DECONLY(jisx0213_2_bmp) + MAPPING_ENCONLY(jisx0213_bmp) + MAPPING_DECONLY(jisx0213_1_emp) + MAPPING_DECONLY(jisx0213_2_emp) + MAPPING_ENCONLY(jisx0213_emp) + MAPPING_ENCDEC(jisx0213_pair) + MAPPING_ENCDEC(cp932ext) +END_MAPPINGS_LIST + +BEGIN_CODECS_LIST + CODEC_STATELESS(shift_jis) + CODEC_STATELESS(cp932) + CODEC_STATELESS(euc_jp) + CODEC_STATELESS(shift_jis_2004) + CODEC_STATELESS(euc_jis_2004) + { "euc_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(euc_jis_2004) }, + { "shift_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(shift_jis_2004) }, +END_CODECS_LIST + +I_AM_A_MODULE_FOR(jp) diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_kr.c b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_kr.c index 6d6acb5c4be..29e0d56cfbc 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_kr.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_kr.c @@ -1,468 +1,468 @@ -/* - * _codecs_kr.c: Codecs collection for Korean encodings - * - * Written by Hye-Shik Chang - */ - -#include "cjkcodecs.h" -#include "mappings_kr.h" - -/* - * EUC-KR codec - */ - -#define EUCKR_JAMO_FIRSTBYTE 0xA4 -#define EUCKR_JAMO_FILLER 0xD4 - -static const unsigned char u2cgk_choseong[19] = { - 0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xa9, 0xb1, 0xb2, - 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, - 0xbc, 0xbd, 0xbe -}; -static const unsigned char u2cgk_jungseong[21] = { - 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, - 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, - 0xcf, 0xd0, 0xd1, 0xd2, 0xd3 -}; -static const unsigned char u2cgk_jongseong[28] = { - 0xd4, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, - 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xba, - 0xbb, 0xbc, 0xbd, 0xbe -}; - -ENCODER(euc_kr) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - - REQUIRE_OUTBUF(2); - if (TRYMAP_ENC(cp949, code, c)) - ; - else - return 1; - - if ((code & 0x8000) == 0) { - /* KS X 1001 coded character */ - OUTBYTE1((code >> 8) | 0x80); - OUTBYTE2((code & 0xFF) | 0x80); - NEXT(1, 2); - } - else { - /* Mapping is found in CP949 extension, - but we encode it in KS X 1001:1998 Annex 3, - make-up sequence for EUC-KR. */ - - REQUIRE_OUTBUF(8); - - /* syllable composition precedence */ - OUTBYTE1(EUCKR_JAMO_FIRSTBYTE); - OUTBYTE2(EUCKR_JAMO_FILLER); - - /* All code points in CP949 extension are in unicode - * Hangul Syllable area. */ - assert(0xac00 <= c && c <= 0xd7a3); - c -= 0xac00; - - OUTBYTE3(EUCKR_JAMO_FIRSTBYTE); - OUTBYTE4(u2cgk_choseong[c / 588]); - NEXT_OUT(4); - - OUTBYTE1(EUCKR_JAMO_FIRSTBYTE); - OUTBYTE2(u2cgk_jungseong[(c / 28) % 21]); - OUTBYTE3(EUCKR_JAMO_FIRSTBYTE); - OUTBYTE4(u2cgk_jongseong[c % 28]); - NEXT(1, 4); - } - } - - return 0; -} - -#define NONE 127 - -static const unsigned char cgk2u_choseong[] = { /* [A1, BE] */ - 0, 1, NONE, 2, NONE, NONE, 3, 4, - 5, NONE, NONE, NONE, NONE, NONE, NONE, NONE, - 6, 7, 8, NONE, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18 -}; -static const unsigned char cgk2u_jongseong[] = { /* [A1, BE] */ - 1, 2, 3, 4, 5, 6, 7, NONE, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, NONE, 18, 19, 20, 21, 22, - NONE, 23, 24, 25, 26, 27 -}; - -DECODER(euc_kr) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - - if (c == EUCKR_JAMO_FIRSTBYTE && - INBYTE2 == EUCKR_JAMO_FILLER) { - /* KS X 1001:1998 Annex 3 make-up sequence */ - DBCHAR cho, jung, jong; - - REQUIRE_INBUF(8); - if ((*inbuf)[2] != EUCKR_JAMO_FIRSTBYTE || - (*inbuf)[4] != EUCKR_JAMO_FIRSTBYTE || - (*inbuf)[6] != EUCKR_JAMO_FIRSTBYTE) - return 1; - - c = (*inbuf)[3]; - if (0xa1 <= c && c <= 0xbe) - cho = cgk2u_choseong[c - 0xa1]; - else - cho = NONE; - - c = (*inbuf)[5]; - jung = (0xbf <= c && c <= 0xd3) ? c - 0xbf : NONE; - - c = (*inbuf)[7]; - if (c == EUCKR_JAMO_FILLER) - jong = 0; - else if (0xa1 <= c && c <= 0xbe) - jong = cgk2u_jongseong[c - 0xa1]; - else - jong = NONE; - - if (cho == NONE || jung == NONE || jong == NONE) - return 1; - - OUTCHAR(0xac00 + cho*588 + jung*28 + jong); - NEXT_IN(8); - } - else if (TRYMAP_DEC(ksx1001, decoded, c ^ 0x80, INBYTE2 ^ 0x80)) { - OUTCHAR(decoded); - NEXT_IN(2); - } - else - return 1; - } - - return 0; -} -#undef NONE - - -/* - * CP949 codec - */ - -ENCODER(cp949) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - - REQUIRE_OUTBUF(2); - if (TRYMAP_ENC(cp949, code, c)) - ; - else - return 1; - - OUTBYTE1((code >> 8) | 0x80); - if (code & 0x8000) - OUTBYTE2(code & 0xFF); /* MSB set: CP949 */ - else - OUTBYTE2((code & 0xFF) | 0x80); /* MSB unset: ks x 1001 */ - NEXT(1, 2); - } - - return 0; -} - -DECODER(cp949) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - if (TRYMAP_DEC(ksx1001, decoded, c ^ 0x80, INBYTE2 ^ 0x80)) - OUTCHAR(decoded); - else if (TRYMAP_DEC(cp949ext, decoded, c, INBYTE2)) - OUTCHAR(decoded); - else - return 1; - - NEXT_IN(2); - } - - return 0; -} - - -/* - * JOHAB codec - */ - -static const unsigned char u2johabidx_choseong[32] = { - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, -}; -static const unsigned char u2johabidx_jungseong[32] = { - 0x03, 0x04, 0x05, 0x06, 0x07, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x1a, 0x1b, 0x1c, 0x1d, -}; -static const unsigned char u2johabidx_jongseong[32] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, -}; -static const DBCHAR u2johabjamo[] = { - 0x8841, 0x8c41, 0x8444, 0x9041, 0x8446, 0x8447, 0x9441, - 0x9841, 0x9c41, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, - 0x8450, 0xa041, 0xa441, 0xa841, 0x8454, 0xac41, 0xb041, 0xb441, - 0xb841, 0xbc41, 0xc041, 0xc441, 0xc841, 0xcc41, 0xd041, 0x8461, - 0x8481, 0x84a1, 0x84c1, 0x84e1, 0x8541, 0x8561, 0x8581, 0x85a1, - 0x85c1, 0x85e1, 0x8641, 0x8661, 0x8681, 0x86a1, 0x86c1, 0x86e1, - 0x8741, 0x8761, 0x8781, 0x87a1, -}; - -ENCODER(johab) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - - REQUIRE_OUTBUF(2); - - if (c >= 0xac00 && c <= 0xd7a3) { - c -= 0xac00; - code = 0x8000 | - (u2johabidx_choseong[c / 588] << 10) | - (u2johabidx_jungseong[(c / 28) % 21] << 5) | - u2johabidx_jongseong[c % 28]; - } - else if (c >= 0x3131 && c <= 0x3163) - code = u2johabjamo[c - 0x3131]; - else if (TRYMAP_ENC(cp949, code, c)) { - unsigned char c1, c2, t2; - unsigned short t1; - - assert((code & 0x8000) == 0); - c1 = code >> 8; - c2 = code & 0xff; - if (((c1 >= 0x21 && c1 <= 0x2c) || - (c1 >= 0x4a && c1 <= 0x7d)) && - (c2 >= 0x21 && c2 <= 0x7e)) { - t1 = (c1 < 0x4a ? (c1 - 0x21 + 0x1b2) : - (c1 - 0x21 + 0x197)); - t2 = ((t1 & 1) ? 0x5e : 0) + (c2 - 0x21); - OUTBYTE1(t1 >> 1); - OUTBYTE2(t2 < 0x4e ? t2 + 0x31 : t2 + 0x43); - NEXT(1, 2); - continue; - } - else - return 1; - } - else - return 1; - - OUTBYTE1(code >> 8); - OUTBYTE2(code & 0xff); - NEXT(1, 2); - } - - return 0; -} - -#define FILL 0xfd -#define NONE 0xff - -static const unsigned char johabidx_choseong[32] = { - NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, - 0x0e, 0x0f, 0x10, 0x11, 0x12, NONE, NONE, NONE, - NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -}; -static const unsigned char johabidx_jungseong[32] = { - NONE, NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04, - NONE, NONE, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - NONE, NONE, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, - NONE, NONE, 0x11, 0x12, 0x13, 0x14, NONE, NONE, -}; -static const unsigned char johabidx_jongseong[32] = { - NONE, FILL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x0f, 0x10, NONE, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, NONE, NONE, -}; - -static const unsigned char johabjamo_choseong[32] = { - NONE, FILL, 0x31, 0x32, 0x34, 0x37, 0x38, 0x39, - 0x41, 0x42, 0x43, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE, NONE, - NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -}; -static const unsigned char johabjamo_jungseong[32] = { - NONE, NONE, FILL, 0x4f, 0x50, 0x51, 0x52, 0x53, - NONE, NONE, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - NONE, NONE, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - NONE, NONE, 0x60, 0x61, 0x62, 0x63, NONE, NONE, -}; -static const unsigned char johabjamo_jongseong[32] = { - NONE, FILL, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, NONE, 0x42, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE, -}; - -DECODER(johab) -{ - while (inleft > 0) { - unsigned char c = INBYTE1, c2; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - c2 = INBYTE2; - - if (c < 0xd8) { - /* johab hangul */ - unsigned char c_cho, c_jung, c_jong; - unsigned char i_cho, i_jung, i_jong; - - c_cho = (c >> 2) & 0x1f; - c_jung = ((c << 3) | c2 >> 5) & 0x1f; - c_jong = c2 & 0x1f; - - i_cho = johabidx_choseong[c_cho]; - i_jung = johabidx_jungseong[c_jung]; - i_jong = johabidx_jongseong[c_jong]; - - if (i_cho == NONE || i_jung == NONE || i_jong == NONE) - return 1; - - /* we don't use U+1100 hangul jamo yet. */ - if (i_cho == FILL) { - if (i_jung == FILL) { - if (i_jong == FILL) - OUTCHAR(0x3000); - else - OUTCHAR(0x3100 | - johabjamo_jongseong[c_jong]); - } - else { - if (i_jong == FILL) - OUTCHAR(0x3100 | - johabjamo_jungseong[c_jung]); - else - return 1; - } - } else { - if (i_jung == FILL) { - if (i_jong == FILL) - OUTCHAR(0x3100 | - johabjamo_choseong[c_cho]); - else - return 1; - } - else - OUTCHAR(0xac00 + - i_cho * 588 + - i_jung * 28 + - (i_jong == FILL ? 0 : i_jong)); - } - NEXT_IN(2); - } else { - /* KS X 1001 except hangul jamos and syllables */ - if (c == 0xdf || c > 0xf9 || - c2 < 0x31 || (c2 >= 0x80 && c2 < 0x91) || - (c2 & 0x7f) == 0x7f || - (c == 0xda && (c2 >= 0xa1 && c2 <= 0xd3))) - return 1; - else { - unsigned char t1, t2; - - t1 = (c < 0xe0 ? 2 * (c - 0xd9) : - 2 * c - 0x197); - t2 = (c2 < 0x91 ? c2 - 0x31 : c2 - 0x43); - t1 = t1 + (t2 < 0x5e ? 0 : 1) + 0x21; - t2 = (t2 < 0x5e ? t2 : t2 - 0x5e) + 0x21; - - if (TRYMAP_DEC(ksx1001, decoded, t1, t2)) { - OUTCHAR(decoded); - NEXT_IN(2); - } - else { - return 1; - } - } - } - } - - return 0; -} -#undef NONE -#undef FILL - - -BEGIN_MAPPINGS_LIST - MAPPING_DECONLY(ksx1001) - MAPPING_ENCONLY(cp949) - MAPPING_DECONLY(cp949ext) -END_MAPPINGS_LIST - -BEGIN_CODECS_LIST - CODEC_STATELESS(euc_kr) - CODEC_STATELESS(cp949) - CODEC_STATELESS(johab) -END_CODECS_LIST - -I_AM_A_MODULE_FOR(kr) +/* + * _codecs_kr.c: Codecs collection for Korean encodings + * + * Written by Hye-Shik Chang + */ + +#include "cjkcodecs.h" +#include "mappings_kr.h" + +/* + * EUC-KR codec + */ + +#define EUCKR_JAMO_FIRSTBYTE 0xA4 +#define EUCKR_JAMO_FILLER 0xD4 + +static const unsigned char u2cgk_choseong[19] = { + 0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xa9, 0xb1, 0xb2, + 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, + 0xbc, 0xbd, 0xbe +}; +static const unsigned char u2cgk_jungseong[21] = { + 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, + 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, + 0xcf, 0xd0, 0xd1, 0xd2, 0xd3 +}; +static const unsigned char u2cgk_jongseong[28] = { + 0xd4, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, + 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xba, + 0xbb, 0xbc, 0xbd, 0xbe +}; + +ENCODER(euc_kr) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + + REQUIRE_OUTBUF(2); + if (TRYMAP_ENC(cp949, code, c)) + ; + else + return 1; + + if ((code & 0x8000) == 0) { + /* KS X 1001 coded character */ + OUTBYTE1((code >> 8) | 0x80); + OUTBYTE2((code & 0xFF) | 0x80); + NEXT(1, 2); + } + else { + /* Mapping is found in CP949 extension, + but we encode it in KS X 1001:1998 Annex 3, + make-up sequence for EUC-KR. */ + + REQUIRE_OUTBUF(8); + + /* syllable composition precedence */ + OUTBYTE1(EUCKR_JAMO_FIRSTBYTE); + OUTBYTE2(EUCKR_JAMO_FILLER); + + /* All code points in CP949 extension are in unicode + * Hangul Syllable area. */ + assert(0xac00 <= c && c <= 0xd7a3); + c -= 0xac00; + + OUTBYTE3(EUCKR_JAMO_FIRSTBYTE); + OUTBYTE4(u2cgk_choseong[c / 588]); + NEXT_OUT(4); + + OUTBYTE1(EUCKR_JAMO_FIRSTBYTE); + OUTBYTE2(u2cgk_jungseong[(c / 28) % 21]); + OUTBYTE3(EUCKR_JAMO_FIRSTBYTE); + OUTBYTE4(u2cgk_jongseong[c % 28]); + NEXT(1, 4); + } + } + + return 0; +} + +#define NONE 127 + +static const unsigned char cgk2u_choseong[] = { /* [A1, BE] */ + 0, 1, NONE, 2, NONE, NONE, 3, 4, + 5, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + 6, 7, 8, NONE, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18 +}; +static const unsigned char cgk2u_jongseong[] = { /* [A1, BE] */ + 1, 2, 3, 4, 5, 6, 7, NONE, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, NONE, 18, 19, 20, 21, 22, + NONE, 23, 24, 25, 26, 27 +}; + +DECODER(euc_kr) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + + if (c == EUCKR_JAMO_FIRSTBYTE && + INBYTE2 == EUCKR_JAMO_FILLER) { + /* KS X 1001:1998 Annex 3 make-up sequence */ + DBCHAR cho, jung, jong; + + REQUIRE_INBUF(8); + if ((*inbuf)[2] != EUCKR_JAMO_FIRSTBYTE || + (*inbuf)[4] != EUCKR_JAMO_FIRSTBYTE || + (*inbuf)[6] != EUCKR_JAMO_FIRSTBYTE) + return 1; + + c = (*inbuf)[3]; + if (0xa1 <= c && c <= 0xbe) + cho = cgk2u_choseong[c - 0xa1]; + else + cho = NONE; + + c = (*inbuf)[5]; + jung = (0xbf <= c && c <= 0xd3) ? c - 0xbf : NONE; + + c = (*inbuf)[7]; + if (c == EUCKR_JAMO_FILLER) + jong = 0; + else if (0xa1 <= c && c <= 0xbe) + jong = cgk2u_jongseong[c - 0xa1]; + else + jong = NONE; + + if (cho == NONE || jung == NONE || jong == NONE) + return 1; + + OUTCHAR(0xac00 + cho*588 + jung*28 + jong); + NEXT_IN(8); + } + else if (TRYMAP_DEC(ksx1001, decoded, c ^ 0x80, INBYTE2 ^ 0x80)) { + OUTCHAR(decoded); + NEXT_IN(2); + } + else + return 1; + } + + return 0; +} +#undef NONE + + +/* + * CP949 codec + */ + +ENCODER(cp949) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + + REQUIRE_OUTBUF(2); + if (TRYMAP_ENC(cp949, code, c)) + ; + else + return 1; + + OUTBYTE1((code >> 8) | 0x80); + if (code & 0x8000) + OUTBYTE2(code & 0xFF); /* MSB set: CP949 */ + else + OUTBYTE2((code & 0xFF) | 0x80); /* MSB unset: ks x 1001 */ + NEXT(1, 2); + } + + return 0; +} + +DECODER(cp949) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + if (TRYMAP_DEC(ksx1001, decoded, c ^ 0x80, INBYTE2 ^ 0x80)) + OUTCHAR(decoded); + else if (TRYMAP_DEC(cp949ext, decoded, c, INBYTE2)) + OUTCHAR(decoded); + else + return 1; + + NEXT_IN(2); + } + + return 0; +} + + +/* + * JOHAB codec + */ + +static const unsigned char u2johabidx_choseong[32] = { + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, +}; +static const unsigned char u2johabidx_jungseong[32] = { + 0x03, 0x04, 0x05, 0x06, 0x07, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x1a, 0x1b, 0x1c, 0x1d, +}; +static const unsigned char u2johabidx_jongseong[32] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, +}; +static const DBCHAR u2johabjamo[] = { + 0x8841, 0x8c41, 0x8444, 0x9041, 0x8446, 0x8447, 0x9441, + 0x9841, 0x9c41, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, + 0x8450, 0xa041, 0xa441, 0xa841, 0x8454, 0xac41, 0xb041, 0xb441, + 0xb841, 0xbc41, 0xc041, 0xc441, 0xc841, 0xcc41, 0xd041, 0x8461, + 0x8481, 0x84a1, 0x84c1, 0x84e1, 0x8541, 0x8561, 0x8581, 0x85a1, + 0x85c1, 0x85e1, 0x8641, 0x8661, 0x8681, 0x86a1, 0x86c1, 0x86e1, + 0x8741, 0x8761, 0x8781, 0x87a1, +}; + +ENCODER(johab) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + + REQUIRE_OUTBUF(2); + + if (c >= 0xac00 && c <= 0xd7a3) { + c -= 0xac00; + code = 0x8000 | + (u2johabidx_choseong[c / 588] << 10) | + (u2johabidx_jungseong[(c / 28) % 21] << 5) | + u2johabidx_jongseong[c % 28]; + } + else if (c >= 0x3131 && c <= 0x3163) + code = u2johabjamo[c - 0x3131]; + else if (TRYMAP_ENC(cp949, code, c)) { + unsigned char c1, c2, t2; + unsigned short t1; + + assert((code & 0x8000) == 0); + c1 = code >> 8; + c2 = code & 0xff; + if (((c1 >= 0x21 && c1 <= 0x2c) || + (c1 >= 0x4a && c1 <= 0x7d)) && + (c2 >= 0x21 && c2 <= 0x7e)) { + t1 = (c1 < 0x4a ? (c1 - 0x21 + 0x1b2) : + (c1 - 0x21 + 0x197)); + t2 = ((t1 & 1) ? 0x5e : 0) + (c2 - 0x21); + OUTBYTE1(t1 >> 1); + OUTBYTE2(t2 < 0x4e ? t2 + 0x31 : t2 + 0x43); + NEXT(1, 2); + continue; + } + else + return 1; + } + else + return 1; + + OUTBYTE1(code >> 8); + OUTBYTE2(code & 0xff); + NEXT(1, 2); + } + + return 0; +} + +#define FILL 0xfd +#define NONE 0xff + +static const unsigned char johabidx_choseong[32] = { + NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, +}; +static const unsigned char johabidx_jungseong[32] = { + NONE, NONE, FILL, 0x00, 0x01, 0x02, 0x03, 0x04, + NONE, NONE, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + NONE, NONE, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + NONE, NONE, 0x11, 0x12, 0x13, 0x14, NONE, NONE, +}; +static const unsigned char johabidx_jongseong[32] = { + NONE, FILL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, NONE, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, NONE, NONE, +}; + +static const unsigned char johabjamo_choseong[32] = { + NONE, FILL, 0x31, 0x32, 0x34, 0x37, 0x38, 0x39, + 0x41, 0x42, 0x43, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, +}; +static const unsigned char johabjamo_jungseong[32] = { + NONE, NONE, FILL, 0x4f, 0x50, 0x51, 0x52, 0x53, + NONE, NONE, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + NONE, NONE, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + NONE, NONE, 0x60, 0x61, 0x62, 0x63, NONE, NONE, +}; +static const unsigned char johabjamo_jongseong[32] = { + NONE, FILL, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, NONE, 0x42, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, NONE, NONE, +}; + +DECODER(johab) +{ + while (inleft > 0) { + unsigned char c = INBYTE1, c2; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + c2 = INBYTE2; + + if (c < 0xd8) { + /* johab hangul */ + unsigned char c_cho, c_jung, c_jong; + unsigned char i_cho, i_jung, i_jong; + + c_cho = (c >> 2) & 0x1f; + c_jung = ((c << 3) | c2 >> 5) & 0x1f; + c_jong = c2 & 0x1f; + + i_cho = johabidx_choseong[c_cho]; + i_jung = johabidx_jungseong[c_jung]; + i_jong = johabidx_jongseong[c_jong]; + + if (i_cho == NONE || i_jung == NONE || i_jong == NONE) + return 1; + + /* we don't use U+1100 hangul jamo yet. */ + if (i_cho == FILL) { + if (i_jung == FILL) { + if (i_jong == FILL) + OUTCHAR(0x3000); + else + OUTCHAR(0x3100 | + johabjamo_jongseong[c_jong]); + } + else { + if (i_jong == FILL) + OUTCHAR(0x3100 | + johabjamo_jungseong[c_jung]); + else + return 1; + } + } else { + if (i_jung == FILL) { + if (i_jong == FILL) + OUTCHAR(0x3100 | + johabjamo_choseong[c_cho]); + else + return 1; + } + else + OUTCHAR(0xac00 + + i_cho * 588 + + i_jung * 28 + + (i_jong == FILL ? 0 : i_jong)); + } + NEXT_IN(2); + } else { + /* KS X 1001 except hangul jamos and syllables */ + if (c == 0xdf || c > 0xf9 || + c2 < 0x31 || (c2 >= 0x80 && c2 < 0x91) || + (c2 & 0x7f) == 0x7f || + (c == 0xda && (c2 >= 0xa1 && c2 <= 0xd3))) + return 1; + else { + unsigned char t1, t2; + + t1 = (c < 0xe0 ? 2 * (c - 0xd9) : + 2 * c - 0x197); + t2 = (c2 < 0x91 ? c2 - 0x31 : c2 - 0x43); + t1 = t1 + (t2 < 0x5e ? 0 : 1) + 0x21; + t2 = (t2 < 0x5e ? t2 : t2 - 0x5e) + 0x21; + + if (TRYMAP_DEC(ksx1001, decoded, t1, t2)) { + OUTCHAR(decoded); + NEXT_IN(2); + } + else { + return 1; + } + } + } + } + + return 0; +} +#undef NONE +#undef FILL + + +BEGIN_MAPPINGS_LIST + MAPPING_DECONLY(ksx1001) + MAPPING_ENCONLY(cp949) + MAPPING_DECONLY(cp949ext) +END_MAPPINGS_LIST + +BEGIN_CODECS_LIST + CODEC_STATELESS(euc_kr) + CODEC_STATELESS(cp949) + CODEC_STATELESS(johab) +END_CODECS_LIST + +I_AM_A_MODULE_FOR(kr) diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_tw.c b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_tw.c index 722b26b128a..ec3db18559e 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_tw.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/_codecs_tw.c @@ -1,143 +1,143 @@ -/* - * _codecs_tw.c: Codecs collection for Taiwan's encodings - * - * Written by Hye-Shik Chang - */ - -#include "cjkcodecs.h" -#include "mappings_tw.h" - -/* - * BIG5 codec - */ - -ENCODER(big5) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - REQUIRE_OUTBUF(1); - **outbuf = (unsigned char)c; - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - - REQUIRE_OUTBUF(2); - - if (TRYMAP_ENC(big5, code, c)) - ; - else - return 1; - - OUTBYTE1(code >> 8); - OUTBYTE2(code & 0xFF); - NEXT(1, 2); - } - - return 0; -} - -DECODER(big5) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) { - OUTCHAR(decoded); - NEXT_IN(2); - } - else return 1; - } - - return 0; -} - - -/* - * CP950 codec - */ - -ENCODER(cp950) -{ - while (*inpos < inlen) { - Py_UCS4 c = INCHAR1; - DBCHAR code; - - if (c < 0x80) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - continue; - } - - if (c > 0xFFFF) - return 1; - - REQUIRE_OUTBUF(2); - if (TRYMAP_ENC(cp950ext, code, c)) - ; - else if (TRYMAP_ENC(big5, code, c)) - ; - else - return 1; - - OUTBYTE1(code >> 8); - OUTBYTE2(code & 0xFF); - NEXT(1, 2); - } - - return 0; -} - -DECODER(cp950) -{ - while (inleft > 0) { - unsigned char c = INBYTE1; - Py_UCS4 decoded; - - if (c < 0x80) { - OUTCHAR(c); - NEXT_IN(1); - continue; - } - - REQUIRE_INBUF(2); - - if (TRYMAP_DEC(cp950ext, decoded, c, INBYTE2)) - OUTCHAR(decoded); - else if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) - OUTCHAR(decoded); - else - return 1; - - NEXT_IN(2); - } - - return 0; -} - - - -BEGIN_MAPPINGS_LIST - MAPPING_ENCDEC(big5) - MAPPING_ENCDEC(cp950ext) -END_MAPPINGS_LIST - -BEGIN_CODECS_LIST - CODEC_STATELESS(big5) - CODEC_STATELESS(cp950) -END_CODECS_LIST - -I_AM_A_MODULE_FOR(tw) +/* + * _codecs_tw.c: Codecs collection for Taiwan's encodings + * + * Written by Hye-Shik Chang + */ + +#include "cjkcodecs.h" +#include "mappings_tw.h" + +/* + * BIG5 codec + */ + +ENCODER(big5) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + REQUIRE_OUTBUF(1); + **outbuf = (unsigned char)c; + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + + REQUIRE_OUTBUF(2); + + if (TRYMAP_ENC(big5, code, c)) + ; + else + return 1; + + OUTBYTE1(code >> 8); + OUTBYTE2(code & 0xFF); + NEXT(1, 2); + } + + return 0; +} + +DECODER(big5) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) { + OUTCHAR(decoded); + NEXT_IN(2); + } + else return 1; + } + + return 0; +} + + +/* + * CP950 codec + */ + +ENCODER(cp950) +{ + while (*inpos < inlen) { + Py_UCS4 c = INCHAR1; + DBCHAR code; + + if (c < 0x80) { + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + continue; + } + + if (c > 0xFFFF) + return 1; + + REQUIRE_OUTBUF(2); + if (TRYMAP_ENC(cp950ext, code, c)) + ; + else if (TRYMAP_ENC(big5, code, c)) + ; + else + return 1; + + OUTBYTE1(code >> 8); + OUTBYTE2(code & 0xFF); + NEXT(1, 2); + } + + return 0; +} + +DECODER(cp950) +{ + while (inleft > 0) { + unsigned char c = INBYTE1; + Py_UCS4 decoded; + + if (c < 0x80) { + OUTCHAR(c); + NEXT_IN(1); + continue; + } + + REQUIRE_INBUF(2); + + if (TRYMAP_DEC(cp950ext, decoded, c, INBYTE2)) + OUTCHAR(decoded); + else if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) + OUTCHAR(decoded); + else + return 1; + + NEXT_IN(2); + } + + return 0; +} + + + +BEGIN_MAPPINGS_LIST + MAPPING_ENCDEC(big5) + MAPPING_ENCDEC(cp950ext) +END_MAPPINGS_LIST + +BEGIN_CODECS_LIST + CODEC_STATELESS(big5) + CODEC_STATELESS(cp950) +END_CODECS_LIST + +I_AM_A_MODULE_FOR(tw) diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/alg_jisx0201.h b/contrib/tools/python3/src/Modules/cjkcodecs/alg_jisx0201.h index 3034b5ab9df..3efdea6589f 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/alg_jisx0201.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/alg_jisx0201.h @@ -1,65 +1,65 @@ -#define JISX0201_R_ENCODE(c, assi) \ - if ((c) < 0x80 && (c) != 0x5c && (c) != 0x7e) { \ - (assi) = (c); \ - } \ - else if ((c) == 0x00a5) { \ - (assi) = 0x5c; \ - } \ - else if ((c) == 0x203e) { \ - (assi) = 0x7e; \ - } - -#define JISX0201_K_ENCODE(c, assi) \ - if ((c) >= 0xff61 && (c) <= 0xff9f) { \ - (assi) = (c) - 0xfec0; \ - } - -#define JISX0201_ENCODE(c, assi) \ - JISX0201_R_ENCODE(c, assi) \ - else JISX0201_K_ENCODE(c, assi) - -#define JISX0201_R_DECODE_CHAR(c, assi) \ - if ((c) < 0x5c) { \ - (assi) = (c); \ - } \ - else if ((c) == 0x5c) { \ - (assi) = 0x00a5; \ - } \ - else if ((c) < 0x7e) { \ - (assi) = (c); \ - } \ - else if ((c) == 0x7e) { \ - (assi) = 0x203e; \ - } \ - else if ((c) == 0x7f) { \ - (assi) = 0x7f; \ - } - -#define JISX0201_R_DECODE(c, writer) \ - if ((c) < 0x5c) { \ - OUTCHAR(c); \ - } \ - else if ((c) == 0x5c) { \ - OUTCHAR(0x00a5); \ - } \ - else if ((c) < 0x7e) { \ - OUTCHAR(c); \ - } \ - else if ((c) == 0x7e) { \ - OUTCHAR(0x203e); \ - } \ - else if ((c) == 0x7f) { \ - OUTCHAR(0x7f); \ - } - -#define JISX0201_K_DECODE(c, writer) \ - if ((c) >= 0xa1 && (c) <= 0xdf) { \ - OUTCHAR(0xfec0 + (c)); \ - } -#define JISX0201_K_DECODE_CHAR(c, assi) \ - if ((c) >= 0xa1 && (c) <= 0xdf) { \ - (assi) = 0xfec0 + (c); \ - } -#define JISX0201_DECODE(c, writer) \ - JISX0201_R_DECODE(c, writer) \ - else JISX0201_K_DECODE(c, writer) +#define JISX0201_R_ENCODE(c, assi) \ + if ((c) < 0x80 && (c) != 0x5c && (c) != 0x7e) { \ + (assi) = (c); \ + } \ + else if ((c) == 0x00a5) { \ + (assi) = 0x5c; \ + } \ + else if ((c) == 0x203e) { \ + (assi) = 0x7e; \ + } + +#define JISX0201_K_ENCODE(c, assi) \ + if ((c) >= 0xff61 && (c) <= 0xff9f) { \ + (assi) = (c) - 0xfec0; \ + } + +#define JISX0201_ENCODE(c, assi) \ + JISX0201_R_ENCODE(c, assi) \ + else JISX0201_K_ENCODE(c, assi) + +#define JISX0201_R_DECODE_CHAR(c, assi) \ + if ((c) < 0x5c) { \ + (assi) = (c); \ + } \ + else if ((c) == 0x5c) { \ + (assi) = 0x00a5; \ + } \ + else if ((c) < 0x7e) { \ + (assi) = (c); \ + } \ + else if ((c) == 0x7e) { \ + (assi) = 0x203e; \ + } \ + else if ((c) == 0x7f) { \ + (assi) = 0x7f; \ + } + +#define JISX0201_R_DECODE(c, writer) \ + if ((c) < 0x5c) { \ + OUTCHAR(c); \ + } \ + else if ((c) == 0x5c) { \ + OUTCHAR(0x00a5); \ + } \ + else if ((c) < 0x7e) { \ + OUTCHAR(c); \ + } \ + else if ((c) == 0x7e) { \ + OUTCHAR(0x203e); \ + } \ + else if ((c) == 0x7f) { \ + OUTCHAR(0x7f); \ + } + +#define JISX0201_K_DECODE(c, writer) \ + if ((c) >= 0xa1 && (c) <= 0xdf) { \ + OUTCHAR(0xfec0 + (c)); \ + } +#define JISX0201_K_DECODE_CHAR(c, assi) \ + if ((c) >= 0xa1 && (c) <= 0xdf) { \ + (assi) = 0xfec0 + (c); \ + } +#define JISX0201_DECODE(c, writer) \ + JISX0201_R_DECODE(c, writer) \ + else JISX0201_K_DECODE(c, writer) diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h b/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h index e41755b197f..b518d9a2329 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h @@ -1,419 +1,419 @@ -/* - * cjkcodecs.h: common header for cjkcodecs - * - * Written by Hye-Shik Chang - */ - -#ifndef _CJKCODECS_H_ -#define _CJKCODECS_H_ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "multibytecodec.h" - - -/* a unicode "undefined" code point */ -#define UNIINV 0xFFFE - -/* internal-use DBCS code points which aren't used by any charsets */ -#define NOCHAR 0xFFFF -#define MULTIC 0xFFFE -#define DBCINV 0xFFFD - -/* shorter macros to save source size of mapping tables */ -#define U UNIINV -#define N NOCHAR -#define M MULTIC -#define D DBCINV - -struct dbcs_index { - const ucs2_t *map; - unsigned char bottom, top; -}; -typedef struct dbcs_index decode_map; - -struct widedbcs_index { - const Py_UCS4 *map; - unsigned char bottom, top; -}; -typedef struct widedbcs_index widedecode_map; - -struct unim_index { - const DBCHAR *map; - unsigned char bottom, top; -}; -typedef struct unim_index encode_map; - -struct unim_index_bytebased { - const unsigned char *map; - unsigned char bottom, top; -}; - -struct dbcs_map { - const char *charset; - const struct unim_index *encmap; - const struct dbcs_index *decmap; -}; - -struct pair_encodemap { - Py_UCS4 uniseq; - DBCHAR code; -}; - -static const MultibyteCodec *codec_list; -static const struct dbcs_map *mapping_list; - -#define CODEC_INIT(encoding) \ - static int encoding##_codec_init(const void *config) - -#define ENCODER_INIT(encoding) \ - static int encoding##_encode_init( \ - MultibyteCodec_State *state, const void *config) -#define ENCODER(encoding) \ - static Py_ssize_t encoding##_encode( \ - MultibyteCodec_State *state, const void *config, \ +/* + * cjkcodecs.h: common header for cjkcodecs + * + * Written by Hye-Shik Chang + */ + +#ifndef _CJKCODECS_H_ +#define _CJKCODECS_H_ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include "multibytecodec.h" + + +/* a unicode "undefined" code point */ +#define UNIINV 0xFFFE + +/* internal-use DBCS code points which aren't used by any charsets */ +#define NOCHAR 0xFFFF +#define MULTIC 0xFFFE +#define DBCINV 0xFFFD + +/* shorter macros to save source size of mapping tables */ +#define U UNIINV +#define N NOCHAR +#define M MULTIC +#define D DBCINV + +struct dbcs_index { + const ucs2_t *map; + unsigned char bottom, top; +}; +typedef struct dbcs_index decode_map; + +struct widedbcs_index { + const Py_UCS4 *map; + unsigned char bottom, top; +}; +typedef struct widedbcs_index widedecode_map; + +struct unim_index { + const DBCHAR *map; + unsigned char bottom, top; +}; +typedef struct unim_index encode_map; + +struct unim_index_bytebased { + const unsigned char *map; + unsigned char bottom, top; +}; + +struct dbcs_map { + const char *charset; + const struct unim_index *encmap; + const struct dbcs_index *decmap; +}; + +struct pair_encodemap { + Py_UCS4 uniseq; + DBCHAR code; +}; + +static const MultibyteCodec *codec_list; +static const struct dbcs_map *mapping_list; + +#define CODEC_INIT(encoding) \ + static int encoding##_codec_init(const void *config) + +#define ENCODER_INIT(encoding) \ + static int encoding##_encode_init( \ + MultibyteCodec_State *state, const void *config) +#define ENCODER(encoding) \ + static Py_ssize_t encoding##_encode( \ + MultibyteCodec_State *state, const void *config, \ int kind, const void *data, \ - Py_ssize_t *inpos, Py_ssize_t inlen, \ - unsigned char **outbuf, Py_ssize_t outleft, int flags) -#define ENCODER_RESET(encoding) \ - static Py_ssize_t encoding##_encode_reset( \ - MultibyteCodec_State *state, const void *config, \ - unsigned char **outbuf, Py_ssize_t outleft) - -#define DECODER_INIT(encoding) \ - static int encoding##_decode_init( \ - MultibyteCodec_State *state, const void *config) -#define DECODER(encoding) \ - static Py_ssize_t encoding##_decode( \ - MultibyteCodec_State *state, const void *config, \ - const unsigned char **inbuf, Py_ssize_t inleft, \ - _PyUnicodeWriter *writer) -#define DECODER_RESET(encoding) \ - static Py_ssize_t encoding##_decode_reset( \ - MultibyteCodec_State *state, const void *config) - -#define NEXT_IN(i) \ - do { \ - (*inbuf) += (i); \ - (inleft) -= (i); \ - } while (0) -#define NEXT_INCHAR(i) \ - do { \ - (*inpos) += (i); \ - } while (0) -#define NEXT_OUT(o) \ - do { \ - (*outbuf) += (o); \ - (outleft) -= (o); \ - } while (0) -#define NEXT(i, o) \ - do { \ - NEXT_INCHAR(i); \ - NEXT_OUT(o); \ - } while (0) - -#define REQUIRE_INBUF(n) \ - do { \ - if (inleft < (n)) \ - return MBERR_TOOFEW; \ - } while (0) - -#define REQUIRE_OUTBUF(n) \ - do { \ - if (outleft < (n)) \ - return MBERR_TOOSMALL; \ - } while (0) - -#define INBYTE1 ((*inbuf)[0]) -#define INBYTE2 ((*inbuf)[1]) -#define INBYTE3 ((*inbuf)[2]) -#define INBYTE4 ((*inbuf)[3]) - -#define INCHAR1 (PyUnicode_READ(kind, data, *inpos)) -#define INCHAR2 (PyUnicode_READ(kind, data, *inpos + 1)) - -#define OUTCHAR(c) \ - do { \ - if (_PyUnicodeWriter_WriteChar(writer, (c)) < 0) \ - return MBERR_EXCEPTION; \ - } while (0) - -#define OUTCHAR2(c1, c2) \ - do { \ - Py_UCS4 _c1 = (c1); \ - Py_UCS4 _c2 = (c2); \ - if (_PyUnicodeWriter_Prepare(writer, 2, Py_MAX(_c1, c2)) < 0) \ - return MBERR_EXCEPTION; \ - PyUnicode_WRITE(writer->kind, writer->data, writer->pos, _c1); \ - PyUnicode_WRITE(writer->kind, writer->data, writer->pos + 1, _c2); \ - writer->pos += 2; \ - } while (0) - + Py_ssize_t *inpos, Py_ssize_t inlen, \ + unsigned char **outbuf, Py_ssize_t outleft, int flags) +#define ENCODER_RESET(encoding) \ + static Py_ssize_t encoding##_encode_reset( \ + MultibyteCodec_State *state, const void *config, \ + unsigned char **outbuf, Py_ssize_t outleft) + +#define DECODER_INIT(encoding) \ + static int encoding##_decode_init( \ + MultibyteCodec_State *state, const void *config) +#define DECODER(encoding) \ + static Py_ssize_t encoding##_decode( \ + MultibyteCodec_State *state, const void *config, \ + const unsigned char **inbuf, Py_ssize_t inleft, \ + _PyUnicodeWriter *writer) +#define DECODER_RESET(encoding) \ + static Py_ssize_t encoding##_decode_reset( \ + MultibyteCodec_State *state, const void *config) + +#define NEXT_IN(i) \ + do { \ + (*inbuf) += (i); \ + (inleft) -= (i); \ + } while (0) +#define NEXT_INCHAR(i) \ + do { \ + (*inpos) += (i); \ + } while (0) +#define NEXT_OUT(o) \ + do { \ + (*outbuf) += (o); \ + (outleft) -= (o); \ + } while (0) +#define NEXT(i, o) \ + do { \ + NEXT_INCHAR(i); \ + NEXT_OUT(o); \ + } while (0) + +#define REQUIRE_INBUF(n) \ + do { \ + if (inleft < (n)) \ + return MBERR_TOOFEW; \ + } while (0) + +#define REQUIRE_OUTBUF(n) \ + do { \ + if (outleft < (n)) \ + return MBERR_TOOSMALL; \ + } while (0) + +#define INBYTE1 ((*inbuf)[0]) +#define INBYTE2 ((*inbuf)[1]) +#define INBYTE3 ((*inbuf)[2]) +#define INBYTE4 ((*inbuf)[3]) + +#define INCHAR1 (PyUnicode_READ(kind, data, *inpos)) +#define INCHAR2 (PyUnicode_READ(kind, data, *inpos + 1)) + +#define OUTCHAR(c) \ + do { \ + if (_PyUnicodeWriter_WriteChar(writer, (c)) < 0) \ + return MBERR_EXCEPTION; \ + } while (0) + +#define OUTCHAR2(c1, c2) \ + do { \ + Py_UCS4 _c1 = (c1); \ + Py_UCS4 _c2 = (c2); \ + if (_PyUnicodeWriter_Prepare(writer, 2, Py_MAX(_c1, c2)) < 0) \ + return MBERR_EXCEPTION; \ + PyUnicode_WRITE(writer->kind, writer->data, writer->pos, _c1); \ + PyUnicode_WRITE(writer->kind, writer->data, writer->pos + 1, _c2); \ + writer->pos += 2; \ + } while (0) + #define OUTBYTEI(c, i) \ do { \ assert((unsigned char)(c) == (c)); \ ((*outbuf)[i]) = (c); \ } while (0) - + #define OUTBYTE1(c) OUTBYTEI(c, 0) #define OUTBYTE2(c) OUTBYTEI(c, 1) #define OUTBYTE3(c) OUTBYTEI(c, 2) #define OUTBYTE4(c) OUTBYTEI(c, 3) -#define WRITEBYTE1(c1) \ - do { \ - REQUIRE_OUTBUF(1); \ +#define WRITEBYTE1(c1) \ + do { \ + REQUIRE_OUTBUF(1); \ OUTBYTE1(c1); \ - } while (0) -#define WRITEBYTE2(c1, c2) \ - do { \ - REQUIRE_OUTBUF(2); \ + } while (0) +#define WRITEBYTE2(c1, c2) \ + do { \ + REQUIRE_OUTBUF(2); \ OUTBYTE1(c1); \ OUTBYTE2(c2); \ - } while (0) -#define WRITEBYTE3(c1, c2, c3) \ - do { \ - REQUIRE_OUTBUF(3); \ + } while (0) +#define WRITEBYTE3(c1, c2, c3) \ + do { \ + REQUIRE_OUTBUF(3); \ OUTBYTE1(c1); \ OUTBYTE2(c2); \ OUTBYTE3(c3); \ - } while (0) -#define WRITEBYTE4(c1, c2, c3, c4) \ - do { \ - REQUIRE_OUTBUF(4); \ + } while (0) +#define WRITEBYTE4(c1, c2, c3, c4) \ + do { \ + REQUIRE_OUTBUF(4); \ OUTBYTE1(c1); \ OUTBYTE2(c2); \ OUTBYTE3(c3); \ OUTBYTE4(c4); \ - } while (0) - -#define _TRYMAP_ENC(m, assi, val) \ - ((m)->map != NULL && (val) >= (m)->bottom && \ - (val)<= (m)->top && ((assi) = (m)->map[(val) - \ - (m)->bottom]) != NOCHAR) -#define TRYMAP_ENC(charset, assi, uni) \ - _TRYMAP_ENC(&charset##_encmap[(uni) >> 8], assi, (uni) & 0xff) - -#define _TRYMAP_DEC(m, assi, val) \ - ((m)->map != NULL && \ - (val) >= (m)->bottom && \ - (val)<= (m)->top && \ - ((assi) = (m)->map[(val) - (m)->bottom]) != UNIINV) -#define TRYMAP_DEC(charset, assi, c1, c2) \ - _TRYMAP_DEC(&charset##_decmap[c1], assi, c2) - -#define BEGIN_MAPPINGS_LIST static const struct dbcs_map _mapping_list[] = { -#define MAPPING_ENCONLY(enc) {#enc, (void*)enc##_encmap, NULL}, -#define MAPPING_DECONLY(enc) {#enc, NULL, (void*)enc##_decmap}, -#define MAPPING_ENCDEC(enc) {#enc, (void*)enc##_encmap, (void*)enc##_decmap}, -#define END_MAPPINGS_LIST \ - {"", NULL, NULL} }; \ - static const struct dbcs_map *mapping_list = \ - (const struct dbcs_map *)_mapping_list; - -#define BEGIN_CODECS_LIST static const MultibyteCodec _codec_list[] = { -#define _STATEFUL_METHODS(enc) \ - enc##_encode, \ - enc##_encode_init, \ - enc##_encode_reset, \ - enc##_decode, \ - enc##_decode_init, \ - enc##_decode_reset, -#define _STATELESS_METHODS(enc) \ - enc##_encode, NULL, NULL, \ - enc##_decode, NULL, NULL, -#define CODEC_STATEFUL(enc) { \ - #enc, NULL, NULL, \ - _STATEFUL_METHODS(enc) \ -}, -#define CODEC_STATELESS(enc) { \ - #enc, NULL, NULL, \ - _STATELESS_METHODS(enc) \ -}, -#define CODEC_STATELESS_WINIT(enc) { \ - #enc, NULL, \ - enc##_codec_init, \ - _STATELESS_METHODS(enc) \ -}, -#define END_CODECS_LIST \ - {"", NULL,} }; \ - static const MultibyteCodec *codec_list = \ - (const MultibyteCodec *)_codec_list; - - - -static PyObject * -getmultibytecodec(void) -{ - static PyObject *cofunc = NULL; - - if (cofunc == NULL) { - PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); - if (mod == NULL) - return NULL; - cofunc = PyObject_GetAttrString(mod, "__create_codec"); - Py_DECREF(mod); - } - return cofunc; -} - -static PyObject * -getcodec(PyObject *self, PyObject *encoding) -{ - PyObject *codecobj, *r, *cofunc; - const MultibyteCodec *codec; - const char *enc; - - if (!PyUnicode_Check(encoding)) { - PyErr_SetString(PyExc_TypeError, - "encoding name must be a string."); - return NULL; - } - enc = PyUnicode_AsUTF8(encoding); - if (enc == NULL) - return NULL; - - cofunc = getmultibytecodec(); - if (cofunc == NULL) - return NULL; - - for (codec = codec_list; codec->encoding[0]; codec++) - if (strcmp(codec->encoding, enc) == 0) - break; - - if (codec->encoding[0] == '\0') { - PyErr_SetString(PyExc_LookupError, - "no such codec is supported."); - return NULL; - } - - codecobj = PyCapsule_New((void *)codec, PyMultibyteCodec_CAPSULE_NAME, NULL); - if (codecobj == NULL) - return NULL; - + } while (0) + +#define _TRYMAP_ENC(m, assi, val) \ + ((m)->map != NULL && (val) >= (m)->bottom && \ + (val)<= (m)->top && ((assi) = (m)->map[(val) - \ + (m)->bottom]) != NOCHAR) +#define TRYMAP_ENC(charset, assi, uni) \ + _TRYMAP_ENC(&charset##_encmap[(uni) >> 8], assi, (uni) & 0xff) + +#define _TRYMAP_DEC(m, assi, val) \ + ((m)->map != NULL && \ + (val) >= (m)->bottom && \ + (val)<= (m)->top && \ + ((assi) = (m)->map[(val) - (m)->bottom]) != UNIINV) +#define TRYMAP_DEC(charset, assi, c1, c2) \ + _TRYMAP_DEC(&charset##_decmap[c1], assi, c2) + +#define BEGIN_MAPPINGS_LIST static const struct dbcs_map _mapping_list[] = { +#define MAPPING_ENCONLY(enc) {#enc, (void*)enc##_encmap, NULL}, +#define MAPPING_DECONLY(enc) {#enc, NULL, (void*)enc##_decmap}, +#define MAPPING_ENCDEC(enc) {#enc, (void*)enc##_encmap, (void*)enc##_decmap}, +#define END_MAPPINGS_LIST \ + {"", NULL, NULL} }; \ + static const struct dbcs_map *mapping_list = \ + (const struct dbcs_map *)_mapping_list; + +#define BEGIN_CODECS_LIST static const MultibyteCodec _codec_list[] = { +#define _STATEFUL_METHODS(enc) \ + enc##_encode, \ + enc##_encode_init, \ + enc##_encode_reset, \ + enc##_decode, \ + enc##_decode_init, \ + enc##_decode_reset, +#define _STATELESS_METHODS(enc) \ + enc##_encode, NULL, NULL, \ + enc##_decode, NULL, NULL, +#define CODEC_STATEFUL(enc) { \ + #enc, NULL, NULL, \ + _STATEFUL_METHODS(enc) \ +}, +#define CODEC_STATELESS(enc) { \ + #enc, NULL, NULL, \ + _STATELESS_METHODS(enc) \ +}, +#define CODEC_STATELESS_WINIT(enc) { \ + #enc, NULL, \ + enc##_codec_init, \ + _STATELESS_METHODS(enc) \ +}, +#define END_CODECS_LIST \ + {"", NULL,} }; \ + static const MultibyteCodec *codec_list = \ + (const MultibyteCodec *)_codec_list; + + + +static PyObject * +getmultibytecodec(void) +{ + static PyObject *cofunc = NULL; + + if (cofunc == NULL) { + PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); + if (mod == NULL) + return NULL; + cofunc = PyObject_GetAttrString(mod, "__create_codec"); + Py_DECREF(mod); + } + return cofunc; +} + +static PyObject * +getcodec(PyObject *self, PyObject *encoding) +{ + PyObject *codecobj, *r, *cofunc; + const MultibyteCodec *codec; + const char *enc; + + if (!PyUnicode_Check(encoding)) { + PyErr_SetString(PyExc_TypeError, + "encoding name must be a string."); + return NULL; + } + enc = PyUnicode_AsUTF8(encoding); + if (enc == NULL) + return NULL; + + cofunc = getmultibytecodec(); + if (cofunc == NULL) + return NULL; + + for (codec = codec_list; codec->encoding[0]; codec++) + if (strcmp(codec->encoding, enc) == 0) + break; + + if (codec->encoding[0] == '\0') { + PyErr_SetString(PyExc_LookupError, + "no such codec is supported."); + return NULL; + } + + codecobj = PyCapsule_New((void *)codec, PyMultibyteCodec_CAPSULE_NAME, NULL); + if (codecobj == NULL) + return NULL; + r = PyObject_CallOneArg(cofunc, codecobj); - Py_DECREF(codecobj); - - return r; -} - -static struct PyMethodDef __methods[] = { - {"getcodec", (PyCFunction)getcodec, METH_O, ""}, - {NULL, NULL}, -}; - -static int -register_maps(PyObject *module) -{ - const struct dbcs_map *h; - - for (h = mapping_list; h->charset[0] != '\0'; h++) { - char mhname[256] = "__map_"; - int r; - strcpy(mhname + sizeof("__map_") - 1, h->charset); - r = PyModule_AddObject(module, mhname, - PyCapsule_New((void *)h, PyMultibyteCodec_CAPSULE_NAME, NULL)); - if (r == -1) - return -1; - } - return 0; -} - -#ifdef USING_BINARY_PAIR_SEARCH -static DBCHAR -find_pairencmap(ucs2_t body, ucs2_t modifier, - const struct pair_encodemap *haystack, int haystacksize) -{ - int pos, min, max; - Py_UCS4 value = body << 16 | modifier; - - min = 0; - max = haystacksize; - - for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1) { - if (value < haystack[pos].uniseq) { - if (max != pos) { - max = pos; - continue; - } - } - else if (value > haystack[pos].uniseq) { - if (min != pos) { - min = pos; - continue; - } - } - break; - } - - if (value == haystack[pos].uniseq) { - return haystack[pos].code; - } - return DBCINV; -} -#endif - -#ifdef USING_IMPORTED_MAPS -#define IMPORT_MAP(locale, charset, encmap, decmap) \ - importmap("_codecs_" #locale, "__map_" #charset, \ - (const void**)encmap, (const void**)decmap) - -static int -importmap(const char *modname, const char *symbol, - const void **encmap, const void **decmap) -{ - PyObject *o, *mod; - - mod = PyImport_ImportModule(modname); - if (mod == NULL) - return -1; - - o = PyObject_GetAttrString(mod, symbol); - if (o == NULL) - goto errorexit; - else if (!PyCapsule_IsValid(o, PyMultibyteCodec_CAPSULE_NAME)) { - PyErr_SetString(PyExc_ValueError, - "map data must be a Capsule."); - goto errorexit; - } - else { - struct dbcs_map *map; - map = PyCapsule_GetPointer(o, PyMultibyteCodec_CAPSULE_NAME); - if (encmap != NULL) - *encmap = map->encmap; - if (decmap != NULL) - *decmap = map->decmap; - Py_DECREF(o); - } - - Py_DECREF(mod); - return 0; - -errorexit: - Py_DECREF(mod); - return -1; -} -#endif - -#define I_AM_A_MODULE_FOR(loc) \ - static struct PyModuleDef __module = { \ - PyModuleDef_HEAD_INIT, \ - "_codecs_"#loc, \ - NULL, \ - 0, \ - __methods, \ - NULL, \ - NULL, \ - NULL, \ - NULL \ - }; \ - PyMODINIT_FUNC \ - PyInit__codecs_##loc(void) \ - { \ - PyObject *m = PyModule_Create(&__module); \ - if (m != NULL) \ - (void)register_maps(m); \ - return m; \ - } - -#endif + Py_DECREF(codecobj); + + return r; +} + +static struct PyMethodDef __methods[] = { + {"getcodec", (PyCFunction)getcodec, METH_O, ""}, + {NULL, NULL}, +}; + +static int +register_maps(PyObject *module) +{ + const struct dbcs_map *h; + + for (h = mapping_list; h->charset[0] != '\0'; h++) { + char mhname[256] = "__map_"; + int r; + strcpy(mhname + sizeof("__map_") - 1, h->charset); + r = PyModule_AddObject(module, mhname, + PyCapsule_New((void *)h, PyMultibyteCodec_CAPSULE_NAME, NULL)); + if (r == -1) + return -1; + } + return 0; +} + +#ifdef USING_BINARY_PAIR_SEARCH +static DBCHAR +find_pairencmap(ucs2_t body, ucs2_t modifier, + const struct pair_encodemap *haystack, int haystacksize) +{ + int pos, min, max; + Py_UCS4 value = body << 16 | modifier; + + min = 0; + max = haystacksize; + + for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1) { + if (value < haystack[pos].uniseq) { + if (max != pos) { + max = pos; + continue; + } + } + else if (value > haystack[pos].uniseq) { + if (min != pos) { + min = pos; + continue; + } + } + break; + } + + if (value == haystack[pos].uniseq) { + return haystack[pos].code; + } + return DBCINV; +} +#endif + +#ifdef USING_IMPORTED_MAPS +#define IMPORT_MAP(locale, charset, encmap, decmap) \ + importmap("_codecs_" #locale, "__map_" #charset, \ + (const void**)encmap, (const void**)decmap) + +static int +importmap(const char *modname, const char *symbol, + const void **encmap, const void **decmap) +{ + PyObject *o, *mod; + + mod = PyImport_ImportModule(modname); + if (mod == NULL) + return -1; + + o = PyObject_GetAttrString(mod, symbol); + if (o == NULL) + goto errorexit; + else if (!PyCapsule_IsValid(o, PyMultibyteCodec_CAPSULE_NAME)) { + PyErr_SetString(PyExc_ValueError, + "map data must be a Capsule."); + goto errorexit; + } + else { + struct dbcs_map *map; + map = PyCapsule_GetPointer(o, PyMultibyteCodec_CAPSULE_NAME); + if (encmap != NULL) + *encmap = map->encmap; + if (decmap != NULL) + *decmap = map->decmap; + Py_DECREF(o); + } + + Py_DECREF(mod); + return 0; + +errorexit: + Py_DECREF(mod); + return -1; +} +#endif + +#define I_AM_A_MODULE_FOR(loc) \ + static struct PyModuleDef __module = { \ + PyModuleDef_HEAD_INIT, \ + "_codecs_"#loc, \ + NULL, \ + 0, \ + __methods, \ + NULL, \ + NULL, \ + NULL, \ + NULL \ + }; \ + PyMODINIT_FUNC \ + PyInit__codecs_##loc(void) \ + { \ + PyObject *m = PyModule_Create(&__module); \ + if (m != NULL) \ + (void)register_maps(m); \ + return m; \ + } + +#endif diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h b/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h index 5ddbbe221b9..028d24b6415 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -1,41 +1,41 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, -"encode($self, /, input, errors=None)\n" -"--\n" -"\n" -"Return an encoded string version of `input\'.\n" -"\n" -"\'errors\' may be given to set a different error handling scheme. Default is\n" -"\'strict\' meaning that encoding errors raise a UnicodeEncodeError. Other possible\n" -"values are \'ignore\', \'replace\' and \'xmlcharrefreplace\' as well as any other name\n" -"registered with codecs.register_error that can handle UnicodeEncodeErrors."); - -#define _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, +"encode($self, /, input, errors=None)\n" +"--\n" +"\n" +"Return an encoded string version of `input\'.\n" +"\n" +"\'errors\' may be given to set a different error handling scheme. Default is\n" +"\'strict\' meaning that encoding errors raise a UnicodeEncodeError. Other possible\n" +"values are \'ignore\', \'replace\' and \'xmlcharrefreplace\' as well as any other name\n" +"registered with codecs.register_error that can handle UnicodeEncodeErrors."); + +#define _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF \ {"encode", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteCodec_encode, METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteCodec_encode__doc__}, - -static PyObject * -_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, - PyObject *input, - const char *errors); - -static PyObject * -_multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"input", "errors", NULL}; + +static PyObject * +_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, + PyObject *input, + const char *errors); + +static PyObject * +_multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"input", "errors", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *input; - const char *errors = NULL; - + PyObject *input; + const char *errors = NULL; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } input = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -59,46 +59,46 @@ _multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *cons goto exit; } skip_optional_pos: - return_value = _multibytecodec_MultibyteCodec_encode_impl(self, input, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_multibytecodec_MultibyteCodec_decode__doc__, -"decode($self, /, input, errors=None)\n" -"--\n" -"\n" -"Decodes \'input\'.\n" -"\n" -"\'errors\' may be given to set a different error handling scheme. Default is\n" -"\'strict\' meaning that encoding errors raise a UnicodeDecodeError. Other possible\n" -"values are \'ignore\' and \'replace\' as well as any other name registered with\n" -"codecs.register_error that is able to handle UnicodeDecodeErrors.\""); - -#define _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF \ + return_value = _multibytecodec_MultibyteCodec_encode_impl(self, input, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteCodec_decode__doc__, +"decode($self, /, input, errors=None)\n" +"--\n" +"\n" +"Decodes \'input\'.\n" +"\n" +"\'errors\' may be given to set a different error handling scheme. Default is\n" +"\'strict\' meaning that encoding errors raise a UnicodeDecodeError. Other possible\n" +"values are \'ignore\' and \'replace\' as well as any other name registered with\n" +"codecs.register_error that is able to handle UnicodeDecodeErrors.\""); + +#define _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF \ {"decode", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteCodec_decode, METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteCodec_decode__doc__}, - -static PyObject * -_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, - Py_buffer *input, - const char *errors); - -static PyObject * -_multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"input", "errors", NULL}; + +static PyObject * +_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, + Py_buffer *input, + const char *errors); + +static PyObject * +_multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"input", "errors", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer input = {NULL, NULL}; - const char *errors = NULL; - + Py_buffer input = {NULL, NULL}; + const char *errors = NULL; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &input, PyBUF_SIMPLE) != 0) { goto exit; } @@ -128,45 +128,45 @@ _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *cons goto exit; } skip_optional_pos: - return_value = _multibytecodec_MultibyteCodec_decode_impl(self, &input, errors); - -exit: - /* Cleanup for input */ - if (input.obj) { - PyBuffer_Release(&input); - } - - return return_value; -} - -PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_encode__doc__, -"encode($self, /, input, final=False)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF \ + return_value = _multibytecodec_MultibyteCodec_decode_impl(self, &input, errors); + +exit: + /* Cleanup for input */ + if (input.obj) { + PyBuffer_Release(&input); + } + + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_encode__doc__, +"encode($self, /, input, final=False)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF \ {"encode", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteIncrementalEncoder_encode, METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalEncoder_encode__doc__}, - -static PyObject * -_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, - PyObject *input, - int final); - -static PyObject * -_multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"input", "final", NULL}; + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, + PyObject *input, + int final); + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"input", "final", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *input; - int final = 0; - + PyObject *input; + int final = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } input = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -181,12 +181,12 @@ _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderOb goto exit; } skip_optional_pos: - return_value = _multibytecodec_MultibyteIncrementalEncoder_encode_impl(self, input, final); - -exit: - return return_value; -} - + return_value = _multibytecodec_MultibyteIncrementalEncoder_encode_impl(self, input, final); + +exit: + return return_value; +} + PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_getstate__doc__, "getstate($self, /)\n" "--\n" @@ -233,51 +233,51 @@ exit: return return_value; } -PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_reset__doc__, -"reset($self, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF \ - {"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalEncoder_reset__doc__}, - -static PyObject * -_multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self); - -static PyObject * -_multibytecodec_MultibyteIncrementalEncoder_reset(MultibyteIncrementalEncoderObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _multibytecodec_MultibyteIncrementalEncoder_reset_impl(self); -} - -PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_decode__doc__, -"decode($self, /, input, final=False)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF \ +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_reset__doc__, +"reset($self, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF \ + {"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalEncoder_reset__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self); + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_reset(MultibyteIncrementalEncoderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteIncrementalEncoder_reset_impl(self); +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_decode__doc__, +"decode($self, /, input, final=False)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF \ {"decode", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteIncrementalDecoder_decode, METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalDecoder_decode__doc__}, - -static PyObject * -_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, - Py_buffer *input, - int final); - -static PyObject * -_multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"input", "final", NULL}; + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, + Py_buffer *input, + int final); + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"input", "final", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer input = {NULL, NULL}; - int final = 0; - + Py_buffer input = {NULL, NULL}; + int final = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &input, PyBUF_SIMPLE) != 0) { goto exit; } @@ -298,17 +298,17 @@ _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderOb goto exit; } skip_optional_pos: - return_value = _multibytecodec_MultibyteIncrementalDecoder_decode_impl(self, &input, final); - -exit: - /* Cleanup for input */ - if (input.obj) { - PyBuffer_Release(&input); - } - - return return_value; -} - + return_value = _multibytecodec_MultibyteIncrementalDecoder_decode_impl(self, &input, final); + +exit: + /* Cleanup for input */ + if (input.obj) { + PyBuffer_Release(&input); + } + + return return_value; +} + PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_getstate__doc__, "getstate($self, /)\n" "--\n" @@ -355,174 +355,174 @@ exit: return return_value; } -PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_reset__doc__, -"reset($self, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF \ - {"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalDecoder_reset__doc__}, - -static PyObject * -_multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self); - -static PyObject * -_multibytecodec_MultibyteIncrementalDecoder_reset(MultibyteIncrementalDecoderObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _multibytecodec_MultibyteIncrementalDecoder_reset_impl(self); -} - -PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_read__doc__, -"read($self, sizeobj=None, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF \ +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_reset__doc__, +"reset($self, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF \ + {"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalDecoder_reset__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self); + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_reset(MultibyteIncrementalDecoderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteIncrementalDecoder_reset_impl(self); +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_read__doc__, +"read($self, sizeobj=None, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamReader_read, METH_FASTCALL, _multibytecodec_MultibyteStreamReader_read__doc__}, - -static PyObject * -_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, - PyObject *sizeobj); - -static PyObject * -_multibytecodec_MultibyteStreamReader_read(MultibyteStreamReaderObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *sizeobj = Py_None; - + +static PyObject * +_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, + PyObject *sizeobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_read(MultibyteStreamReaderObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sizeobj = Py_None; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } sizeobj = args[0]; skip_optional: - return_value = _multibytecodec_MultibyteStreamReader_read_impl(self, sizeobj); - -exit: - return return_value; -} - -PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readline__doc__, -"readline($self, sizeobj=None, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF \ + return_value = _multibytecodec_MultibyteStreamReader_read_impl(self, sizeobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readline__doc__, +"readline($self, sizeobj=None, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF \ {"readline", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamReader_readline, METH_FASTCALL, _multibytecodec_MultibyteStreamReader_readline__doc__}, - -static PyObject * -_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, - PyObject *sizeobj); - -static PyObject * -_multibytecodec_MultibyteStreamReader_readline(MultibyteStreamReaderObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *sizeobj = Py_None; - + +static PyObject * +_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, + PyObject *sizeobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_readline(MultibyteStreamReaderObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sizeobj = Py_None; + if (!_PyArg_CheckPositional("readline", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } sizeobj = args[0]; skip_optional: - return_value = _multibytecodec_MultibyteStreamReader_readline_impl(self, sizeobj); - -exit: - return return_value; -} - -PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readlines__doc__, -"readlines($self, sizehintobj=None, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF \ + return_value = _multibytecodec_MultibyteStreamReader_readline_impl(self, sizeobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readlines__doc__, +"readlines($self, sizehintobj=None, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF \ {"readlines", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamReader_readlines, METH_FASTCALL, _multibytecodec_MultibyteStreamReader_readlines__doc__}, - -static PyObject * -_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, - PyObject *sizehintobj); - -static PyObject * -_multibytecodec_MultibyteStreamReader_readlines(MultibyteStreamReaderObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *sizehintobj = Py_None; - + +static PyObject * +_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, + PyObject *sizehintobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_readlines(MultibyteStreamReaderObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *sizehintobj = Py_None; + if (!_PyArg_CheckPositional("readlines", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } sizehintobj = args[0]; skip_optional: - return_value = _multibytecodec_MultibyteStreamReader_readlines_impl(self, sizehintobj); - -exit: - return return_value; -} - -PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_reset__doc__, -"reset($self, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF \ - {"reset", (PyCFunction)_multibytecodec_MultibyteStreamReader_reset, METH_NOARGS, _multibytecodec_MultibyteStreamReader_reset__doc__}, - -static PyObject * -_multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self); - -static PyObject * -_multibytecodec_MultibyteStreamReader_reset(MultibyteStreamReaderObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _multibytecodec_MultibyteStreamReader_reset_impl(self); -} - -PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_write__doc__, -"write($self, strobj, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF \ - {"write", (PyCFunction)_multibytecodec_MultibyteStreamWriter_write, METH_O, _multibytecodec_MultibyteStreamWriter_write__doc__}, - -PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__, -"writelines($self, lines, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF \ - {"writelines", (PyCFunction)_multibytecodec_MultibyteStreamWriter_writelines, METH_O, _multibytecodec_MultibyteStreamWriter_writelines__doc__}, - -PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__, -"reset($self, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF \ - {"reset", (PyCFunction)_multibytecodec_MultibyteStreamWriter_reset, METH_NOARGS, _multibytecodec_MultibyteStreamWriter_reset__doc__}, - -static PyObject * -_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self); - -static PyObject * -_multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _multibytecodec_MultibyteStreamWriter_reset_impl(self); -} - -PyDoc_STRVAR(_multibytecodec___create_codec__doc__, -"__create_codec($module, arg, /)\n" -"--\n" -"\n"); - -#define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ - {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, + return_value = _multibytecodec_MultibyteStreamReader_readlines_impl(self, sizehintobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_reset__doc__, +"reset($self, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF \ + {"reset", (PyCFunction)_multibytecodec_MultibyteStreamReader_reset, METH_NOARGS, _multibytecodec_MultibyteStreamReader_reset__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self); + +static PyObject * +_multibytecodec_MultibyteStreamReader_reset(MultibyteStreamReaderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteStreamReader_reset_impl(self); +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_write__doc__, +"write($self, strobj, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF \ + {"write", (PyCFunction)_multibytecodec_MultibyteStreamWriter_write, METH_O, _multibytecodec_MultibyteStreamWriter_write__doc__}, + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__, +"writelines($self, lines, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF \ + {"writelines", (PyCFunction)_multibytecodec_MultibyteStreamWriter_writelines, METH_O, _multibytecodec_MultibyteStreamWriter_writelines__doc__}, + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__, +"reset($self, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF \ + {"reset", (PyCFunction)_multibytecodec_MultibyteStreamWriter_reset, METH_NOARGS, _multibytecodec_MultibyteStreamWriter_reset__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self); + +static PyObject * +_multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteStreamWriter_reset_impl(self); +} + +PyDoc_STRVAR(_multibytecodec___create_codec__doc__, +"__create_codec($module, arg, /)\n" +"--\n" +"\n"); + +#define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ + {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, /*[clinic end generated code: output=5ce6fd4ca1f95620 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/emu_jisx0213_2000.h b/contrib/tools/python3/src/Modules/cjkcodecs/emu_jisx0213_2000.h index a5d5a7063d3..1d408d3d53f 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/emu_jisx0213_2000.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/emu_jisx0213_2000.h @@ -1,54 +1,54 @@ -/* These routines may be quite inefficient, but it's used only to emulate old - * standards. */ - -#ifndef EMULATE_JISX0213_2000_ENCODE_INVALID -# define EMULATE_JISX0213_2000_ENCODE_INVALID 1 -#endif - -#define EMULATE_JISX0213_2000_ENCODE_BMP(assi, c) \ - if (config == (void *)2000 && ( \ - (c) == 0x9B1C || (c) == 0x4FF1 || \ - (c) == 0x525D || (c) == 0x541E || \ - (c) == 0x5653 || (c) == 0x59F8 || \ - (c) == 0x5C5B || (c) == 0x5E77 || \ - (c) == 0x7626 || (c) == 0x7E6B)) { \ - return EMULATE_JISX0213_2000_ENCODE_INVALID; \ - } \ - else if (config == (void *)2000 && (c) == 0x9B1D) { \ - (assi) = 0x8000 | 0x7d3b; \ - } - -#define EMULATE_JISX0213_2000_ENCODE_EMP(assi, c) \ - if (config == (void *)2000 && (c) == 0x20B9F) { \ - return EMULATE_JISX0213_2000_ENCODE_INVALID; \ - } - -#ifndef EMULATE_JISX0213_2000_DECODE_INVALID -# define EMULATE_JISX0213_2000_DECODE_INVALID 2 -#endif - -#define EMULATE_JISX0213_2000_DECODE_PLANE1(assi, c1, c2) \ - if (config == (void *)2000 && \ - (((c1) == 0x2E && (c2) == 0x21) || \ - ((c1) == 0x2F && (c2) == 0x7E) || \ - ((c1) == 0x4F && (c2) == 0x54) || \ - ((c1) == 0x4F && (c2) == 0x7E) || \ - ((c1) == 0x74 && (c2) == 0x27) || \ - ((c1) == 0x7E && (c2) == 0x7A) || \ - ((c1) == 0x7E && (c2) == 0x7B) || \ - ((c1) == 0x7E && (c2) == 0x7C) || \ - ((c1) == 0x7E && (c2) == 0x7D) || \ - ((c1) == 0x7E && (c2) == 0x7E))) { \ - return EMULATE_JISX0213_2000_DECODE_INVALID; \ - } - -#define EMULATE_JISX0213_2000_DECODE_PLANE2(writer, c1, c2) \ - if (config == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) { \ - OUTCHAR(0x9B1D); \ - } - -#define EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(assi, c1, c2) \ - if (config == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) { \ - (assi) = 0x9B1D; \ - } - +/* These routines may be quite inefficient, but it's used only to emulate old + * standards. */ + +#ifndef EMULATE_JISX0213_2000_ENCODE_INVALID +# define EMULATE_JISX0213_2000_ENCODE_INVALID 1 +#endif + +#define EMULATE_JISX0213_2000_ENCODE_BMP(assi, c) \ + if (config == (void *)2000 && ( \ + (c) == 0x9B1C || (c) == 0x4FF1 || \ + (c) == 0x525D || (c) == 0x541E || \ + (c) == 0x5653 || (c) == 0x59F8 || \ + (c) == 0x5C5B || (c) == 0x5E77 || \ + (c) == 0x7626 || (c) == 0x7E6B)) { \ + return EMULATE_JISX0213_2000_ENCODE_INVALID; \ + } \ + else if (config == (void *)2000 && (c) == 0x9B1D) { \ + (assi) = 0x8000 | 0x7d3b; \ + } + +#define EMULATE_JISX0213_2000_ENCODE_EMP(assi, c) \ + if (config == (void *)2000 && (c) == 0x20B9F) { \ + return EMULATE_JISX0213_2000_ENCODE_INVALID; \ + } + +#ifndef EMULATE_JISX0213_2000_DECODE_INVALID +# define EMULATE_JISX0213_2000_DECODE_INVALID 2 +#endif + +#define EMULATE_JISX0213_2000_DECODE_PLANE1(assi, c1, c2) \ + if (config == (void *)2000 && \ + (((c1) == 0x2E && (c2) == 0x21) || \ + ((c1) == 0x2F && (c2) == 0x7E) || \ + ((c1) == 0x4F && (c2) == 0x54) || \ + ((c1) == 0x4F && (c2) == 0x7E) || \ + ((c1) == 0x74 && (c2) == 0x27) || \ + ((c1) == 0x7E && (c2) == 0x7A) || \ + ((c1) == 0x7E && (c2) == 0x7B) || \ + ((c1) == 0x7E && (c2) == 0x7C) || \ + ((c1) == 0x7E && (c2) == 0x7D) || \ + ((c1) == 0x7E && (c2) == 0x7E))) { \ + return EMULATE_JISX0213_2000_DECODE_INVALID; \ + } + +#define EMULATE_JISX0213_2000_DECODE_PLANE2(writer, c1, c2) \ + if (config == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) { \ + OUTCHAR(0x9B1D); \ + } + +#define EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(assi, c1, c2) \ + if (config == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) { \ + (assi) = 0x9B1D; \ + } + diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_cn.h b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_cn.h index 87ca0de784a..45a8569cd74 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_cn.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_cn.h @@ -1,4104 +1,4104 @@ // AUTO-GENERATED FILE FROM genmap_schinese.py: DO NOT EDIT -static const ucs2_t __gb2312_decmap[7482] = { -12288,12289,12290,12539,713,711,168,12291,12293,8213,65374,8214,8230,8216, -8217,8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303, -12310,12311,12304,12305,177,215,247,8758,8743,8744,8721,8719,8746,8745,8712, -8759,8730,8869,8741,8736,8978,8857,8747,8750,8801,8780,8776,8765,8733,8800, -8814,8815,8804,8805,8734,8757,8756,9794,9792,176,8242,8243,8451,65284,164, -65504,65505,8240,167,8470,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651, -9650,8251,8594,8592,8593,8595,12307,9352,9353,9354,9355,9356,9357,9358,9359, -9360,9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9332,9333,9334, -9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349, -9350,9351,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,U,U,12832,12833, -12834,12835,12836,12837,12838,12839,12840,12841,U,U,8544,8545,8546,8547,8548, -8549,8550,8551,8552,8553,8554,8555,65281,65282,65283,65509,65285,65286,65287, -65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,65300, -65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,65313, -65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326, -65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65339, -65340,65341,65342,65343,65344,65345,65346,65347,65348,65349,65350,65351,65352, -65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365, -65366,65367,65368,65369,65370,65371,65372,65373,65507,12353,12354,12355,12356, -12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369, -12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382, -12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395, -12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408, -12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421, -12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434, -12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460, -12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473, -12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486, -12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499, -12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512, -12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525, -12526,12527,12528,12529,12530,12531,12532,12533,12534,913,914,915,916,917,918, -919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,U,U,U, -U,U,U,U,U,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961, -963,964,965,966,967,968,969,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048, -1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063, -1064,1065,1066,1067,1068,1069,1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072, -1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086, -1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101, -1102,1103,257,225,462,224,275,233,283,232,299,237,464,236,333,243,466,242,363, -250,468,249,470,472,474,476,252,234,U,U,U,U,U,U,U,U,U,U,12549,12550,12551, -12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564, -12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577, -12578,12579,12580,12581,12582,12583,12584,12585,9472,9473,9474,9475,9476,9477, -9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492, -9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507, -9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522, -9523,9524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537, -9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,21834,38463,22467,25384, -21710,21769,21696,30353,30284,34108,30702,33406,30861,29233,38552,38797,27688, -23433,20474,25353,26263,23736,33018,26696,32942,26114,30414,20985,25942,29100, -32753,34948,20658,22885,25034,28595,33453,25420,25170,21485,21543,31494,20843, -30116,24052,25300,36299,38774,25226,32793,22365,38712,32610,29240,30333,26575, -30334,25670,20336,36133,25308,31255,26001,29677,25644,25203,33324,39041,26495, -29256,25198,25292,20276,29923,21322,21150,32458,37030,24110,26758,27036,33152, -32465,26834,30917,34444,38225,20621,35876,33502,32990,21253,35090,21093,34180, -38649,20445,22561,39281,23453,25265,25253,26292,35961,40077,29190,26479,30865, -24754,21329,21271,36744,32972,36125,38049,20493,29384,22791,24811,28953,34987, -22868,33519,26412,31528,23849,32503,29997,27893,36454,36856,36924,40763,27604, -37145,31508,24444,30887,34006,34109,27605,27609,27606,24065,24199,30201,38381, -25949,24330,24517,36767,22721,33218,36991,38491,38829,36793,32534,36140,25153, -20415,21464,21342,36776,36777,36779,36941,26631,24426,33176,34920,40150,24971, -21035,30250,24428,25996,28626,28392,23486,25672,20853,20912,26564,19993,31177, -39292,28851,30149,24182,29627,33760,25773,25320,38069,27874,21338,21187,25615, -38082,31636,20271,24091,33334,33046,33162,28196,27850,39539,25429,21340,21754, -34917,22496,19981,24067,27493,31807,37096,24598,25830,29468,35009,26448,25165, -36130,30572,36393,37319,24425,33756,34081,39184,21442,34453,27531,24813,24808, -28799,33485,33329,20179,27815,34255,25805,31961,27133,26361,33609,21397,31574, -20391,20876,27979,23618,36461,25554,21449,33580,33590,26597,30900,25661,23519, -23700,24046,35815,25286,26612,35962,25600,25530,34633,39307,35863,32544,38130, -20135,38416,39076,26124,29462,22330,23581,24120,38271,20607,32928,21378,25950, -30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,21557,28818,36710, -25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,24561,27785,38472, -36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,24809,28548,35802, -25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,24347,39536,32827, -40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,23815,23456,25277, -37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,33261,21021,20986, -27249,21416,36487,38148,38607,28353,38500,26970,30784,20648,30679,25616,35302, -22788,25571,24029,31359,26941,20256,33337,21912,20018,30126,31383,24162,24202, -38383,21019,21561,28810,25462,38180,22402,26149,26943,37255,21767,28147,32431, -34850,25139,32496,30133,33576,30913,38604,36766,24904,29943,35789,27492,21050, -36176,27425,32874,33905,22257,21254,20174,19995,20945,31895,37259,31751,20419, -36479,31713,31388,25703,23828,20652,33030,30209,31929,28140,32736,26449,23384, -23544,30923,25774,25619,25514,25387,38169,25645,36798,31572,30249,25171,22823, -21574,27513,20643,25140,24102,27526,20195,36151,34955,24453,36910,24608,32829, -25285,20025,21333,37112,25528,32966,26086,27694,20294,24814,28129,35806,24377, -34507,24403,25377,20826,33633,26723,20992,25443,36424,20498,23707,31095,23548, -21040,31291,24764,36947,30423,24503,24471,30340,36460,28783,30331,31561,30634, -20979,37011,22564,20302,28404,36842,25932,31515,29380,28068,32735,23265,25269, -24213,22320,33922,31532,24093,24351,36882,32532,39072,25474,28359,30872,28857, -20856,38747,22443,30005,20291,30008,24215,24806,22880,28096,27583,30857,21500, -38613,20939,20993,25481,21514,38035,35843,36300,29241,30879,34678,36845,35853, -21472,19969,30447,21486,38025,39030,40718,38189,23450,35746,20002,19996,20908, -33891,25026,21160,26635,20375,24683,20923,27934,20828,25238,26007,38497,35910, -36887,30168,37117,30563,27602,29322,29420,35835,22581,30585,36172,26460,38208, -32922,24230,28193,22930,31471,30701,38203,27573,26029,32526,22534,20817,38431, -23545,22697,21544,36466,25958,39039,22244,38045,30462,36929,25479,21702,22810, -22842,22427,36530,26421,36346,33333,21057,24816,22549,34558,23784,40517,20420, -39069,35769,23077,24694,21380,25212,36943,37122,39295,24681,32780,20799,32819, -23572,39285,27953,20108,36144,21457,32602,31567,20240,20047,38400,27861,29648, -34281,24070,30058,32763,27146,30718,38034,32321,20961,28902,21453,36820,33539, -36137,29359,39277,27867,22346,33459,26041,32938,25151,38450,22952,20223,35775, -32442,25918,33778,38750,21857,39134,32933,21290,35837,21536,32954,24223,27832, -36153,33452,37210,21545,27675,20998,32439,22367,28954,27774,31881,22859,20221, -24575,24868,31914,20016,23553,26539,34562,23792,38155,39118,30127,28925,36898, -20911,32541,35773,22857,20964,20315,21542,22827,25975,32932,23413,25206,25282, -36752,24133,27679,31526,20239,20440,26381,28014,28074,31119,34993,24343,29995, -25242,36741,20463,37340,26023,33071,33105,24220,33104,36212,21103,35206,36171, -22797,20613,20184,38428,29238,33145,36127,23500,35747,38468,22919,32538,21648, -22134,22030,35813,25913,27010,38041,30422,28297,24178,29976,26438,26577,31487, -32925,36214,24863,31174,25954,36195,20872,21018,38050,32568,32923,32434,23703, -28207,26464,31705,30347,39640,33167,32660,31957,25630,38224,31295,21578,21733, -27468,25601,25096,40509,33011,30105,21106,38761,33883,26684,34532,38401,38548, -38124,20010,21508,32473,26681,36319,32789,26356,24218,32697,22466,32831,26775, -24037,25915,21151,24685,40858,20379,36524,20844,23467,24339,24041,27742,25329, -36129,20849,38057,21246,27807,33503,29399,22434,26500,36141,22815,36764,33735, -21653,31629,20272,27837,23396,22993,40723,21476,34506,39592,35895,32929,25925, -39038,22266,38599,21038,29916,21072,23521,25346,35074,20054,25296,24618,26874, -20851,23448,20896,35266,31649,39302,32592,24815,28748,36143,20809,24191,36891, -29808,35268,22317,30789,24402,40863,38394,36712,39740,35809,30328,26690,26588, -36330,36149,21053,36746,28378,26829,38149,37101,22269,26524,35065,36807,21704, -39608,23401,28023,27686,20133,23475,39559,37219,25000,37039,38889,21547,28085, -23506,20989,21898,32597,32752,25788,25421,26097,25022,24717,28938,27735,27721, -22831,26477,33322,22741,22158,35946,27627,37085,22909,32791,21495,28009,21621, -21917,33655,33743,26680,31166,21644,20309,21512,30418,35977,38402,27827,28088, -36203,35088,40548,36154,22079,40657,30165,24456,29408,24680,21756,20136,27178, -34913,24658,36720,21700,28888,34425,40511,27946,23439,24344,32418,21897,20399, -29492,21564,21402,20505,21518,21628,20046,24573,29786,22774,33899,32993,34676, -29392,31946,28246,24359,34382,21804,25252,20114,27818,25143,33457,21719,21326, -29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,27426,29615, -26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,24187,33618, -24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,24653,35854, -28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,24800,26214, -36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,39746,27985, -28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,20987,22334, -22522,26426,30072,31293,31215,31637,32908,39269,36857,28608,35749,40481,23020, -32489,32521,21513,26497,26840,36753,31821,38598,21450,24613,30142,27762,21363, -23241,32423,25380,20960,33034,24049,34015,25216,20864,23395,20238,31085,21058, -24760,27982,23492,23490,35745,35760,26082,24524,38469,22931,32487,32426,22025, -26551,22841,20339,23478,21152,33626,39050,36158,30002,38078,20551,31292,20215, -26550,39550,23233,27516,30417,22362,23574,31546,38388,29006,20860,32937,33392, -22904,32516,33575,26816,26604,30897,30839,25315,25441,31616,20461,21098,20943, -33616,27099,37492,36341,36145,35265,38190,31661,20214,20581,33328,21073,39279, -28176,28293,28071,24314,20725,23004,23558,27974,27743,30086,33931,26728,22870, -35762,21280,37233,38477,34121,26898,30977,28966,33014,20132,37066,27975,39556, -23047,22204,25605,38128,30699,20389,33050,29409,35282,39290,32564,32478,21119, -25945,37237,36735,36739,21483,31382,25581,25509,30342,31224,34903,38454,25130, -21163,33410,26708,26480,25463,30571,31469,27905,32467,35299,22992,25106,34249, -33445,30028,20511,20171,30117,35819,23626,24062,31563,26020,37329,20170,27941, -35167,32039,38182,20165,35880,36827,38771,26187,31105,36817,28908,28024,23613, -21170,33606,20834,33550,30555,26230,40120,20140,24778,31934,31923,32463,20117, -35686,26223,39048,38745,22659,25964,38236,24452,30153,38742,31455,31454,20928, -28847,31384,25578,31350,32416,29590,38893,20037,28792,20061,37202,21417,25937, -26087,33276,33285,21646,23601,30106,38816,25304,29401,30141,23621,39545,33738, -23616,21632,30697,20030,27822,32858,25298,25454,24040,20855,36317,36382,38191, -20465,21477,24807,28844,21095,25424,40515,23071,20518,30519,21367,32482,25733, -25899,25225,25496,20500,29237,35273,20915,35776,32477,22343,33740,38055,20891, -21531,23803,20426,31459,27994,37089,39567,21888,21654,21345,21679,24320,25577, -26999,20975,24936,21002,22570,21208,22350,30733,30475,24247,24951,31968,25179, -25239,20130,28821,32771,25335,28900,38752,22391,33499,26607,26869,30933,39063, -31185,22771,21683,21487,28212,20811,21051,23458,35838,32943,21827,22438,24691, -22353,21549,31354,24656,23380,25511,25248,21475,25187,23495,26543,21741,31391, -33510,37239,24211,35044,22840,22446,25358,36328,33007,22359,31607,20393,24555, -23485,27454,21281,31568,29378,26694,30719,30518,26103,20917,20111,30420,23743, -31397,33909,22862,39745,20608,39304,24871,28291,22372,26118,25414,22256,25324, -25193,24275,38420,22403,25289,21895,34593,33098,36771,21862,33713,26469,36182, -34013,23146,26639,25318,31726,38417,20848,28572,35888,25597,35272,25042,32518, -28866,28389,29701,27028,29436,24266,37070,26391,28010,25438,21171,29282,32769, -20332,23013,37226,28889,28061,21202,20048,38647,38253,34174,30922,32047,20769, -22418,25794,32907,31867,27882,26865,26974,20919,21400,26792,29313,40654,31729, -29432,31163,28435,29702,26446,37324,40100,31036,33673,33620,21519,26647,20029, -21385,21169,30782,21382,21033,20616,20363,20432,30178,31435,31890,27813,38582, -21147,29827,21737,20457,32852,33714,36830,38256,24265,24604,28063,24088,25947, -33080,38142,24651,28860,32451,31918,20937,26753,31921,33391,20004,36742,37327, -26238,20142,35845,25769,32842,20698,30103,29134,23525,36797,28518,20102,25730, -38243,24278,26009,21015,35010,28872,21155,29454,29747,26519,30967,38678,20020, -37051,40158,28107,20955,36161,21533,25294,29618,33777,38646,40836,38083,20278, -32666,20940,28789,38517,23725,39046,21478,20196,28316,29705,27060,30827,39311, -30041,21016,30244,27969,26611,20845,40857,32843,21657,31548,31423,38534,22404, -25314,38471,27004,23044,25602,31699,28431,38475,33446,21346,39045,24208,28809, -25523,21348,34383,40065,40595,30860,38706,36335,36162,40575,28510,31108,24405, -38470,25134,39540,21525,38109,20387,26053,23653,23649,32533,34385,27695,24459, -29575,28388,32511,23782,25371,23402,28390,21365,20081,25504,30053,25249,36718, -20262,20177,27814,32438,35770,33821,34746,32599,36923,38179,31657,39585,35064, -33853,27931,39558,32476,22920,40635,29595,30721,34434,39532,39554,22043,21527, -22475,20080,40614,21334,36808,33033,30610,39314,34542,28385,34067,26364,24930, -28459,35881,33426,33579,30450,27667,24537,33725,29483,33541,38170,27611,30683, -38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,26757,37238,38665, -29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,23194,38376,38391, -20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,37274,38753,31964, -36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,26825,30496,32501, -20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,31186,28218,24217, -22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,34719,40483,38125, -21517,21629,35884,25720,25721,34321,27169,33180,30952,25705,39764,25273,26411, -33707,22696,40664,27819,28448,23518,38476,35851,29279,26576,25287,29281,20137, -22982,27597,22675,26286,24149,21215,24917,26408,30446,30566,29287,31302,25343, -21738,21584,38048,37027,23068,32435,27670,20035,22902,32784,22856,21335,30007, -38590,22218,25376,33041,24700,38393,28118,21602,39297,20869,23273,33021,22958, -38675,20522,27877,23612,25311,20320,21311,33147,36870,28346,34091,25288,24180, -30910,25781,25467,24565,23064,37247,40479,23615,25423,32834,23421,21870,38218, -38221,28037,24744,26592,29406,20957,23425,25319,27870,29275,25197,38062,32445, -33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,25386,25062, -31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,36276,29228, -24085,24597,29750,25293,25490,29260,24472,28227,27966,25856,28504,30424,30928, -30460,30036,21028,21467,20051,24222,26049,32810,32982,25243,21638,21032,28846, -34957,36305,27873,21624,32986,22521,35060,36180,38506,37197,20329,27803,21943, -30406,30768,25256,28921,28558,24429,34028,26842,30844,31735,33192,26379,40527, -25447,30896,22383,30738,38713,25209,25259,21128,29749,27607,21860,33086,30130, -30382,21305,30174,20731,23617,35692,31687,20559,29255,39575,39128,28418,29922, -31080,25735,30629,25340,39057,36139,21697,32856,20050,22378,33529,33805,24179, -20973,29942,35780,23631,22369,27900,39047,23110,30772,39748,36843,31893,21078, -25169,38138,20166,33670,33889,33769,33970,22484,26420,22275,26222,28006,35889, -26333,28689,26399,27450,26646,25114,22971,19971,20932,28422,26578,27791,20854, -26827,22855,27495,30054,23822,33040,40784,26071,31048,31041,39569,36215,23682, -20062,20225,21551,22865,30732,22120,27668,36804,24323,27773,27875,35755,25488, -24688,27965,29301,25190,38030,38085,21315,36801,31614,20191,35878,20094,40660, -38065,38067,21069,28508,36963,27973,35892,22545,23884,27424,27465,26538,21595, -33108,32652,22681,34103,24378,25250,27207,38201,25970,24708,26725,30631,20052, -20392,24039,38808,25772,32728,23789,20431,31373,20999,33540,19988,24623,31363, -38054,20405,20146,31206,29748,21220,33465,25810,31165,23517,27777,38738,36731, -27682,20542,21375,28165,25806,26228,27696,24773,39031,35831,24198,29756,31351, -31179,19992,37041,29699,27714,22234,37195,27845,36235,21306,34502,26354,36527, -23624,39537,28192,21462,23094,40843,36259,21435,22280,39079,26435,37275,27849, -20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,40522,27063,30830, -38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,22199,35753,39286, -25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,35748,20995,22922, -32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,28342,23481,32466, -20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,20083,27741,20837, -35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,25746,27922,33832, -33134,40131,22622,36187,19977,21441,20254,25955,26705,21971,20007,25620,39578, -25195,23234,29791,33394,28073,26862,20711,33678,30722,26432,21049,27801,32433, -20667,21861,29022,31579,26194,29642,33515,26441,23665,21024,29053,34923,38378, -38485,25797,36193,33203,21892,27733,25159,32558,22674,20260,21830,36175,26188, -19978,23578,35059,26786,25422,31245,28903,33421,21242,38902,23569,21736,37045, -32461,22882,36170,34503,33292,33293,36198,25668,23556,24913,28041,31038,35774, -30775,30003,21627,20280,36523,28145,23072,32453,31070,27784,23457,23158,29978, -32958,24910,28183,22768,29983,29989,29298,21319,32499,30465,30427,21097,32988, -22307,24072,22833,29422,26045,28287,35799,23608,34417,21313,30707,25342,26102, -20160,39135,34432,23454,35782,21490,30690,20351,23630,39542,22987,24335,31034, -22763,19990,26623,20107,25325,35475,36893,21183,26159,21980,22124,36866,20181, -20365,37322,39280,27663,24066,24643,23460,35270,35797,25910,25163,39318,23432, -23551,25480,21806,21463,30246,20861,34092,26530,26803,27530,25234,36755,21460, -33298,28113,30095,20070,36174,23408,29087,34223,26257,26329,32626,34560,40653, -40736,23646,26415,36848,26641,26463,25101,31446,22661,24246,25968,28465,24661, -21047,32781,25684,34928,29993,24069,26643,25332,38684,21452,29245,35841,27700, -30561,31246,21550,30636,39034,33308,35828,30805,26388,28865,26031,25749,22070, -24605,31169,21496,19997,27515,32902,23546,21987,22235,20282,20284,39282,24051, -26494,32824,24578,39042,36865,23435,35772,35829,25628,33368,25822,22013,33487, -37221,20439,32032,36895,31903,20723,22609,28335,23487,35785,32899,37240,33948, -31639,34429,38539,38543,32485,39635,30862,23681,31319,36930,38567,31071,23385, -25439,31499,34001,26797,21766,32553,29712,32034,38145,25152,22604,20182,23427, -22905,22612,29549,25374,36427,36367,32974,33492,25260,21488,27888,37214,22826, -24577,27760,22349,25674,36138,30251,28393,22363,27264,30192,28525,35885,35848, -22374,27631,34962,30899,25506,21497,28845,27748,22616,25642,22530,26848,33179, -21776,31958,20504,36538,28108,36255,28907,25487,28059,28372,32486,33796,26691, -36867,28120,38518,35752,22871,29305,34276,33150,30140,35466,26799,21076,36386, -38161,25552,39064,36420,21884,20307,26367,22159,24789,28053,21059,23625,22825, -28155,22635,30000,29980,24684,33300,33094,25361,26465,36834,30522,36339,36148, -38081,24086,21381,21548,28867,27712,24311,20572,20141,24237,25402,33351,36890, -26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,20599, -25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,21520, -20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,25302, -25176,33073,40501,38464,39534,39548,26925,22949,25299,21822,25366,21703,34521, -27964,23043,29926,34972,27498,22806,35916,24367,28286,29609,39037,20024,28919, -23436,30871,25405,26202,30358,24779,23451,23113,19975,33109,27754,29579,20129, -26505,32593,24448,26106,26395,24536,22916,23041,24013,24494,21361,38886,36829, -26693,22260,21807,24799,20026,28493,32500,33479,33806,22996,20255,20266,23614, -32428,26410,34074,21619,30031,32963,21890,39759,20301,28205,35859,23561,24944, -21355,30239,28201,34442,25991,38395,32441,21563,31283,32010,38382,21985,32705, -29934,25373,34583,28065,31389,25105,26017,21351,25569,27779,24043,21596,38056, -20044,27745,35820,23627,26080,33436,26791,21566,21556,27595,27494,20116,25410, -21320,33310,20237,20398,22366,25098,38654,26212,29289,21247,21153,24735,35823, -26132,29081,26512,35199,30802,30717,26224,22075,21560,38177,29306,31232,24687, -24076,24713,33181,22805,24796,29060,28911,28330,27728,29312,27268,34989,24109, -20064,23219,21916,38115,27927,31995,38553,25103,32454,30606,34430,21283,38686, -36758,26247,23777,20384,29421,19979,21414,22799,21523,25472,38184,20808,20185, -40092,32420,21688,36132,34900,33335,38386,28046,24358,23244,26174,38505,29616, -29486,21439,33146,39301,32673,23466,38519,38480,32447,30456,21410,38262,39321, -31665,35140,28248,20065,32724,31077,35814,24819,21709,20139,39033,24055,27233, -20687,21521,35937,33831,30813,38660,21066,21742,22179,38144,28040,23477,28102, -26195,23567,23389,26657,32918,21880,31505,25928,26964,20123,27463,34638,38795, -21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,34809,25032,27844, -27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,24515,20449,34885, -26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,37266,24184,26447, -24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,20462,32670,26429, -21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,39035,24464,35768, -33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,32493,36713,21927, -23459,24748,26059,29572,36873,30307,30505,32474,38772,34203,23398,31348,38634, -34880,21195,29071,24490,26092,35810,23547,39535,24033,27529,27739,35757,35759, -36874,36805,21387,25276,40486,40493,21568,20011,33469,29273,34460,23830,34905, -28079,38597,21713,20122,35766,28937,21693,38409,28895,28153,30416,20005,30740, -34578,23721,24310,35328,39068,38414,28814,27839,22852,25513,30524,34893,28436, -33395,22576,29141,21388,30746,38593,21761,24422,28976,23476,35866,39564,27523, -22830,40495,31207,26472,25196,20335,30113,32650,27915,38451,27687,20208,30162, -20859,26679,28478,36992,33136,22934,29814,25671,23591,36965,31377,35875,23002, -21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,20918,20063,39029, -25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,25558,38129,20381, -20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,23452,23016,24413, -26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,37009,23673,20159, -24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,20041,30410,28322, -35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,22240,27575,38899, -38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,21360,33521,27185, -23156,40560,24212,32552,33721,33828,33829,33639,34631,36814,36194,30408,24433, -39062,30828,26144,21727,25317,20323,33219,30152,24248,38605,36362,34553,21647, -27891,28044,27704,24703,21191,29992,24189,20248,24736,24551,23588,30001,37038, -38080,29369,27833,28216,37193,26377,21451,21491,20305,37321,35825,21448,24188, -36802,28132,20110,30402,27014,34398,24858,33286,20313,20446,36926,40060,24841, -28189,28180,38533,20104,23089,38632,19982,23679,31161,23431,35821,32701,29577, -22495,33419,37057,21505,36935,21947,23786,24481,24840,27442,29425,32946,35465, -28020,23507,35029,39044,35947,39533,40499,28170,20900,20803,22435,34945,21407, -25588,36757,22253,21592,22278,29503,28304,32536,36828,33489,24895,24616,38498, -26352,32422,36234,36291,38053,23731,31908,26376,24742,38405,32792,20113,37095, -21248,38504,20801,36816,34164,37213,26197,38901,23381,21277,30776,26434,26685, -21705,28798,23472,36733,20877,22312,21681,25874,26242,36190,36163,33039,33900, -36973,31967,20991,34299,26531,26089,28577,34468,36481,22122,36896,30338,28790, -29157,36131,25321,21017,27901,36156,24590,22686,24974,26366,36192,25166,21939, -28195,26413,36711,38113,38392,30504,26629,27048,21643,20045,28856,35784,25688, -25995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,26025,36759, -23853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,24432,28467, -24352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,25307,26157, -25214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,34544,36761, -32773,38167,34071,36825,27993,29645,26015,30495,29956,30759,33275,36126,38024, -20390,26517,30137,35786,38663,25391,38215,38453,33976,25379,30529,24449,29424, -20105,24596,25972,25327,27491,25919,24103,30151,37073,35777,33437,26525,25903, -21553,34584,30693,32930,33026,27713,20043,32455,32844,30452,26893,27542,25191, -20540,20356,22336,25351,27490,36286,21482,26088,32440,24535,25370,25527,33267, -33268,32622,24092,23769,21046,26234,31209,31258,36136,28825,30164,28382,27835, -31378,20013,30405,24544,38047,34935,32456,31181,32959,37325,20210,20247,33311, -21608,24030,27954,35788,31909,36724,32920,24090,21650,30385,23449,26172,39588, -29664,26666,34523,26417,29482,35832,35803,36880,31481,28891,29038,25284,30633, -22065,20027,33879,26609,21161,34496,36142,38136,31569,20303,27880,31069,39547, -25235,29226,25341,19987,30742,36716,25776,36186,31686,26729,24196,35013,22918, -25758,22766,29366,26894,38181,36861,36184,22368,32512,35846,20934,25417,25305, -21331,26700,29730,33537,37196,21828,30528,28796,27978,20857,21672,36164,23039, -28363,28100,23388,32043,20180,31869,28371,23376,33258,28173,23383,39683,26837, -36394,23447,32508,24635,32437,37049,36208,22863,25549,31199,36275,21330,26063, -31062,35781,38459,32452,38075,32386,22068,37257,26368,32618,23562,36981,26152, -24038,20304,26590,20570,20316,22352,24231,20109,19980,20800,19984,24319,21317, -19989,20120,19998,39730,23404,22121,20008,31162,20031,21269,20039,22829,29243, -21358,27664,22239,32996,39319,27603,30590,40727,20022,20127,40720,20060,20073, -20115,33416,23387,21868,22031,20164,21389,21405,21411,21413,21422,38757,36189, -21274,21493,21286,21294,21310,36188,21350,21347,20994,21000,21006,21037,21043, -21055,21056,21068,21086,21089,21084,33967,21117,21122,21121,21136,21139,20866, -32596,20155,20163,20169,20162,20200,20193,20203,20190,20251,20211,20258,20324, -20213,20261,20263,20233,20267,20318,20327,25912,20314,20317,20319,20311,20274, -20285,20342,20340,20369,20361,20355,20367,20350,20347,20394,20348,20396,20372, -20454,20456,20458,20421,20442,20451,20444,20433,20447,20472,20521,20556,20467, -20524,20495,20526,20525,20478,20508,20492,20517,20520,20606,20547,20565,20552, -20558,20588,20603,20645,20647,20649,20666,20694,20742,20717,20716,20710,20718, -20743,20747,20189,27709,20312,20325,20430,40864,27718,31860,20846,24061,40649, -39320,20865,22804,21241,21261,35335,21264,20971,22809,20821,20128,20822,20147, -34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,20925,20924, -20935,20886,20898,20901,35744,35750,35751,35754,35764,35765,35767,35778,35779, -35787,35791,35790,35794,35795,35796,35798,35800,35801,35804,35807,35808,35812, -35816,35817,35822,35824,35827,35830,35833,35836,35839,35840,35842,35844,35847, -35852,35855,35857,35858,35860,35861,35862,35865,35867,35864,35869,35871,35872, -35873,35877,35879,35882,35883,35886,35887,35890,35891,35893,35894,21353,21370, -38429,38434,38433,38449,38442,38461,38460,38466,38473,38484,38495,38503,38508, -38514,38516,38536,38541,38551,38576,37015,37019,37021,37017,37036,37025,37044, -37043,37046,37050,37048,37040,37071,37061,37054,37072,37060,37063,37075,37094, -37090,37084,37079,37083,37099,37103,37118,37124,37154,37150,37155,37169,37167, -37177,37187,37190,21005,22850,21154,21164,21165,21182,21759,21200,21206,21232, -21471,29166,30669,24308,20981,20988,39727,21430,24321,30042,24047,22348,22441, -22433,22654,22716,22725,22737,22313,22316,22314,22323,22329,22318,22319,22364, -22331,22338,22377,22405,22379,22406,22396,22395,22376,22381,22390,22387,22445, -22436,22412,22450,22479,22439,22452,22419,22432,22485,22488,22490,22489,22482, -22456,22516,22511,22520,22500,22493,22539,22541,22525,22509,22528,22558,22553, -22596,22560,22629,22636,22657,22665,22682,22656,39336,40729,25087,33401,33405, -33407,33423,33418,33448,33412,33422,33425,33431,33433,33451,33464,33470,33456, -33480,33482,33507,33432,33463,33454,33483,33484,33473,33449,33460,33441,33450, -33439,33476,33486,33444,33505,33545,33527,33508,33551,33543,33500,33524,33490, -33496,33548,33531,33491,33553,33562,33542,33556,33557,33504,33493,33564,33617, -33627,33628,33544,33682,33596,33588,33585,33691,33630,33583,33615,33607,33603, -33631,33600,33559,33632,33581,33594,33587,33638,33637,33640,33563,33641,33644, -33642,33645,33646,33712,33656,33715,33716,33696,33706,33683,33692,33669,33660, -33718,33705,33661,33720,33659,33688,33694,33704,33722,33724,33729,33793,33765, -33752,22535,33816,33803,33757,33789,33750,33820,33848,33809,33798,33748,33759, -33807,33795,33784,33785,33770,33733,33728,33830,33776,33761,33884,33873,33882, -33881,33907,33927,33928,33914,33929,33912,33852,33862,33897,33910,33932,33934, -33841,33901,33985,33997,34000,34022,33981,34003,33994,33983,33978,34016,33953, -33977,33972,33943,34021,34019,34060,29965,34104,34032,34105,34079,34106,34134, -34107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171, -34212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241, -34268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869, -22874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306, -25303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524, -25453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550, -25682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732, -25709,25750,25722,25783,25784,25753,25786,25792,25808,25815,25828,25826,25865, -25893,25902,24331,24530,29977,24337,21343,21489,21501,21481,21480,21499,21522, -21526,21510,21579,21586,21587,21588,21590,21571,21537,21591,21593,21539,21554, -21634,21652,21623,21617,21604,21658,21659,21636,21622,21606,21661,21712,21677, -21698,21684,21714,21671,21670,21715,21716,21618,21667,21717,21691,21695,21708, -21721,21722,21724,21673,21674,21668,21725,21711,21726,21787,21735,21792,21757, -21780,21747,21794,21795,21775,21777,21799,21802,21863,21903,21941,21833,21869, -21825,21845,21823,21840,21820,21815,21846,21877,21878,21879,21811,21808,21852, -21899,21970,21891,21937,21945,21896,21889,21919,21886,21974,21905,21883,21983, -21949,21950,21908,21913,21994,22007,21961,22047,21969,21995,21996,21972,21990, -21981,21956,21999,21989,22002,22003,21964,21965,21992,22005,21988,36756,22046, -22024,22028,22017,22052,22051,22014,22016,22055,22061,22104,22073,22103,22060, -22093,22114,22105,22108,22092,22100,22150,22116,22129,22123,22139,22140,22149, -22163,22191,22228,22231,22237,22241,22261,22251,22265,22271,22276,22282,22281, -22300,24079,24089,24084,24081,24113,24123,24124,24119,24132,24148,24155,24158, -24161,23692,23674,23693,23696,23702,23688,23704,23705,23697,23706,23708,23733, -23714,23741,23724,23723,23729,23715,23745,23735,23748,23762,23780,23755,23781, -23810,23811,23847,23846,23854,23844,23838,23814,23835,23896,23870,23860,23869, -23916,23899,23919,23901,23915,23883,23882,23913,23924,23938,23961,23965,35955, -23991,24005,24435,24439,24450,24455,24457,24460,24469,24473,24476,24488,24493, -24501,24508,34914,24417,29357,29360,29364,29367,29368,29379,29377,29390,29389, -29394,29416,29423,29417,29426,29428,29431,29441,29427,29443,29434,29435,29463, -29459,29473,29450,29470,29469,29461,29474,29497,29477,29484,29496,29489,29520, -29517,29527,29536,29548,29551,29566,33307,22821,39143,22820,22786,39267,39271, -39272,39273,39274,39275,39276,39284,39287,39293,39296,39300,39303,39306,39309, -39312,39313,39315,39316,39317,24192,24209,24203,24214,24229,24224,24249,24245, -24254,24243,36179,24274,24273,24283,24296,24298,33210,24516,24521,24534,24527, -24579,24558,24580,24545,24548,24574,24581,24582,24554,24557,24568,24601,24629, -24614,24603,24591,24589,24617,24619,24586,24639,24609,24696,24697,24699,24698, -24642,24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,24812,24763, -24753,24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,24832,24846, -24875,24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,38377,38379, -38385,38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,38411,38412, -38413,38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,27701,27732, -27740,27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,27782,27817, -27856,27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,27883,27886, -27825,27859,27887,27902,27961,27943,27916,27971,27976,27911,27908,27929,27918, -27947,27981,27950,27957,27930,27983,27986,27988,27955,28049,28015,28062,28064, -27998,28051,28052,27996,28000,28028,28003,28186,28103,28101,28126,28174,28095, -28128,28177,28134,28125,28121,28182,28075,28172,28078,28203,28270,28238,28267, -28338,28255,28294,28243,28244,28210,28197,28228,28383,28337,28312,28384,28461, -28386,28325,28327,28349,28347,28343,28375,28340,28367,28303,28354,28319,28514, -28486,28487,28452,28437,28409,28463,28470,28491,28532,28458,28425,28457,28553, -28557,28556,28536,28530,28540,28538,28625,28617,28583,28601,28598,28610,28641, -28654,28638,28640,28655,28698,28707,28699,28729,28725,28751,28766,23424,23428, -23445,23443,23461,23480,29999,39582,25652,23524,23534,35120,23536,36423,35591, -36790,36819,36821,36837,36846,36836,36841,36838,36851,36840,36869,36868,36875, -36902,36881,36877,36886,36897,36917,36918,36909,36911,36932,36945,36946,36944, -36968,36952,36962,36955,26297,36980,36989,36994,37000,36995,37003,24400,24407, -24406,24408,23611,21675,23632,23641,23409,23651,23654,32700,24362,24361,24365, -33396,24380,39739,23662,22913,22915,22925,22953,22954,22947,22935,22986,22955, -22942,22948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,23000, -23033,23052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,23100, -23138,23157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,23224, -23264,23267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,23360, -23573,23580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,39551, -39549,39552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,39580, -39581,39583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,32425, -32429,32432,32446,32448,32449,32450,32457,32459,32460,32464,32468,32471,32475, -32480,32481,32488,32491,32494,32495,32497,32498,32525,32502,32506,32507,32510, -32513,32514,32515,32519,32520,32523,32524,32527,32529,32530,32535,32537,32540, -32539,32543,32545,32546,32547,32548,32549,32550,32551,32554,32555,32556,32557, -32559,32560,32561,32562,32563,32565,24186,30079,24027,30014,37013,29582,29585, -29614,29602,29599,29647,29634,29649,29623,29619,29632,29641,29640,29669,29657, -39036,29706,29673,29671,29662,29626,29682,29711,29738,29787,29734,29733,29736, -29744,29742,29740,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822, -29852,29838,29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882, -38890,38891,38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520, -26535,26485,26536,26526,26541,26507,26487,26492,26608,26633,26584,26634,26601, -26544,26636,26585,26549,26586,26547,26589,26624,26563,26552,26594,26638,26561, -26621,26674,26675,26720,26721,26702,26722,26692,26724,26755,26653,26709,26726, -26689,26727,26688,26686,26698,26697,26665,26805,26767,26740,26743,26771,26731, -26818,26990,26876,26911,26912,26873,26916,26864,26891,26881,26967,26851,26896, -26993,26937,26976,26946,26973,27012,26987,27008,27032,27000,26932,27084,27015, -27016,27086,27017,26982,26979,27001,27035,27047,27067,27051,27053,27092,27057, -27073,27082,27103,27029,27104,27021,27135,27183,27117,27159,27160,27237,27122, -27204,27198,27296,27216,27227,27189,27278,27257,27197,27176,27224,27260,27281, -27280,27305,27287,27307,29495,29522,27521,27522,27527,27524,27538,27539,27533, -27546,27547,27553,27562,36715,36717,36721,36722,36723,36725,36726,36728,36727, -36729,36730,36732,36734,36737,36738,36740,36743,36747,36749,36750,36751,36760, -36762,36558,25099,25111,25115,25119,25122,25121,25125,25124,25132,33255,29935, -29940,29951,29967,29969,29971,25908,26094,26095,26096,26122,26137,26482,26115, -26133,26112,28805,26359,26141,26164,26161,26166,26165,32774,26207,26196,26177, -26191,26198,26209,26199,26231,26244,26252,26279,26269,26302,26331,26332,26342, -26345,36146,36147,36150,36155,36157,36160,36165,36166,36168,36169,36167,36173, -36181,36185,35271,35274,35275,35276,35278,35279,35280,35281,29294,29343,29277, -29286,29295,29310,29311,29316,29323,29325,29327,29330,25352,25394,25520,25663, -25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,27672, -27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,29270, -29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,32948, -32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,32989, -33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,33054, -33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,33148, -33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,26406, -33226,33211,33217,33190,27428,27447,27449,27459,27462,27481,39121,39122,39123, -39125,39129,39130,27571,24384,27586,35315,26000,40785,26003,26044,26054,26052, -26051,26060,26062,26066,26070,28800,28828,28822,28829,28859,28864,28855,28843, -28849,28904,28874,28944,28947,28950,28975,28977,29043,29020,29032,28997,29042, -29002,29048,29050,29080,29107,29109,29096,29088,29152,29140,29159,29177,29213, -29224,28780,28952,29030,29113,25150,25149,25155,25160,25161,31035,31040,31046, -31049,31067,31068,31059,31066,31074,31063,31072,31087,31079,31098,31109,31114, -31130,31143,31155,24529,24528,24636,24669,24666,24679,24641,24665,24675,24747, -24838,24845,24925,25001,24989,25035,25041,25094,32896,32895,27795,27894,28156, -30710,30712,30720,30729,30743,30744,30737,26027,30765,30748,30749,30777,30778, -30779,30751,30780,30757,30764,30755,30761,30798,30829,30806,30807,30758,30800, -30791,30796,30826,30875,30867,30874,30855,30876,30881,30883,30898,30905,30885, -30932,30937,30921,30956,30962,30981,30964,30995,31012,31006,31028,40859,40697, -40699,40700,30449,30468,30477,30457,30471,30472,30490,30498,30489,30509,30502, -30517,30520,30544,30545,30535,30531,30554,30568,30562,30565,30591,30605,30589, -30592,30604,30609,30623,30624,30640,30645,30653,30010,30016,30030,30027,30024, -30043,30066,30073,30083,32600,32609,32607,35400,32616,32628,32625,32633,32641, -32638,30413,30437,34866,38021,38022,38023,38027,38026,38028,38029,38031,38032, -38036,38039,38037,38042,38043,38044,38051,38052,38059,38058,38061,38060,38063, -38064,38066,38068,38070,38071,38072,38073,38074,38076,38077,38079,38084,38088, -38089,38090,38091,38092,38093,38094,38096,38097,38098,38101,38102,38103,38105, -38104,38107,38110,38111,38112,38114,38116,38117,38119,38120,38122,38121,38123, -38126,38127,38131,38132,38133,38135,38137,38140,38141,38143,38147,38146,38150, -38151,38153,38154,38157,38158,38159,38162,38163,38164,38165,38166,38168,38171, -38173,38174,38175,38178,38186,38187,38185,38188,38193,38194,38196,38198,38199, -38200,38204,38206,38207,38210,38197,38212,38213,38214,38217,38220,38222,38223, -38226,38227,38228,38230,38231,38232,38233,38235,38238,38239,38237,38241,38242, -38244,38245,38246,38247,38248,38249,38250,38251,38252,38255,38257,38258,38259, -38202,30695,30700,38601,31189,31213,31203,31211,31238,23879,31235,31234,31262, -31252,31289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918, -29920,29996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504, -40503,40505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524, -40526,40529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553, -40554,40555,40556,40561,40557,40563,30098,30100,30102,30112,30109,30124,30115, -30131,30132,30136,30148,30129,30128,30147,30146,30166,30157,30179,30184,30182, -30180,30187,30183,30211,30193,30204,30207,30224,30208,30213,30220,30231,30218, -30245,30232,30229,30233,30235,30268,30242,30240,30272,30253,30256,30271,30261, -30275,30270,30259,30285,30302,30292,30300,30294,30315,30319,32714,31462,31352, -31353,31360,31366,31368,31381,31398,31392,31404,31400,31405,31411,34916,34921, -34930,34941,34943,34946,34978,35014,34999,35004,35017,35042,35022,35043,35045, -35057,35098,35068,35048,35070,35056,35105,35097,35091,35099,35082,35124,35115, -35126,35137,35174,35195,30091,32997,30386,30388,30684,32786,32788,32790,32796, -32800,32802,32805,32806,32807,32809,32808,32817,32779,32821,32835,32838,32845, -32850,32873,32881,35203,39032,39040,39043,39049,39052,39053,39055,39060,39066, -39067,39070,39071,39073,39074,39077,39078,34381,34388,34412,34414,34431,34426, -34428,34427,34472,34445,34443,34476,34461,34471,34467,34474,34451,34473,34486, -34500,34485,34510,34480,34490,34481,34479,34505,34511,34484,34537,34545,34546, -34541,34547,34512,34579,34526,34548,34527,34520,34513,34563,34567,34552,34568, -34570,34573,34569,34595,34619,34590,34597,34606,34586,34622,34632,34612,34609, -34601,34615,34623,34690,34594,34685,34686,34683,34656,34672,34636,34670,34699, -34643,34659,34684,34660,34649,34661,34707,34735,34728,34770,34758,34696,34693, -34733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,34752, -34762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,34876, -32566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,31531, -31503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,31518, -31576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,31632, -31654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,31697, -31681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,31755, -31775,31786,31782,31800,31809,31808,33278,33281,33282,33284,33260,34884,33313, -33314,33315,33325,33327,33320,33323,33336,33339,33331,33332,33342,33348,33353, -33355,33359,33370,33375,33384,34942,34949,34952,35032,35039,35166,32669,32671, -32679,32687,32688,32690,31868,25929,31889,31901,31900,31902,31906,31922,31932, -31933,31937,31943,31948,31949,31944,31941,31959,31976,33390,26280,32703,32718, -32725,32741,32737,32742,32745,32750,32755,31992,32119,32166,32174,32327,32411, -40632,40628,36211,36228,36244,36241,36273,36199,36205,35911,35913,37194,37200, -37198,37199,37220,37218,37217,37232,37225,37231,37245,37246,37234,37236,37241, -37260,37253,37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,37300, -37306,35925,40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,36292, -36310,36311,36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,36345, -36347,36324,36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,36416, -36409,36405,36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,36476, -36463,36468,36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,35992, -35988,26011,35286,35294,35290,35292,35301,35307,35311,35390,35622,38739,38633, -38643,38639,38662,38657,38664,38671,38670,38698,38701,38704,38718,40832,40835, -40837,40838,40839,40840,40841,40842,40844,40702,40715,40717,38585,38588,38589, -38606,38610,30655,38624,37518,37550,37576,37694,37738,37834,37775,37950,37995, -40063,40066,40069,40070,40071,40072,31267,40075,40078,40080,40081,40082,40084, -40085,40090,40091,40094,40095,40096,40097,40098,40099,40101,40102,40103,40104, -40105,40107,40109,40110,40112,40113,40114,40115,40116,40117,40118,40119,40122, -40123,40124,40125,40132,40133,40134,40135,40138,40139,40140,40141,40142,40143, -40144,40147,40148,40149,40151,40152,40153,40156,40157,40159,40162,38780,38789, -38801,38802,38804,38831,38827,38819,38834,38836,39601,39600,39607,40536,39606, -39610,39612,39617,39616,39621,39618,39627,39628,39633,39749,39747,39751,39753, -39752,39757,39761,39144,39181,39214,39253,39252,39647,39649,39654,39663,39659, -39675,39661,39673,39688,39695,39699,39711,39715,40637,40638,32315,40578,40583, -40584,40587,40594,37846,40605,40607,40667,40668,40669,40672,40671,40674,40681, -40679,40677,40682,40687,40738,40748,40751,40761,40759,40765,40766,40772, -}; - -static const struct dbcs_index gb2312_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb2312_decmap+0,33,126},{__gb2312_decmap+94, -49,124},{__gb2312_decmap+170,33,126},{__gb2312_decmap+264,33,115},{ -__gb2312_decmap+347,33,118},{__gb2312_decmap+433,33,88},{__gb2312_decmap+489, -33,113},{__gb2312_decmap+570,33,105},{__gb2312_decmap+643,36,111},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb2312_decmap+719,33,126},{ -__gb2312_decmap+813,33,126},{__gb2312_decmap+907,33,126},{__gb2312_decmap+1001 -,33,126},{__gb2312_decmap+1095,33,126},{__gb2312_decmap+1189,33,126},{ -__gb2312_decmap+1283,33,126},{__gb2312_decmap+1377,33,126},{__gb2312_decmap+ -1471,33,126},{__gb2312_decmap+1565,33,126},{__gb2312_decmap+1659,33,126},{ -__gb2312_decmap+1753,33,126},{__gb2312_decmap+1847,33,126},{__gb2312_decmap+ -1941,33,126},{__gb2312_decmap+2035,33,126},{__gb2312_decmap+2129,33,126},{ -__gb2312_decmap+2223,33,126},{__gb2312_decmap+2317,33,126},{__gb2312_decmap+ -2411,33,126},{__gb2312_decmap+2505,33,126},{__gb2312_decmap+2599,33,126},{ -__gb2312_decmap+2693,33,126},{__gb2312_decmap+2787,33,126},{__gb2312_decmap+ -2881,33,126},{__gb2312_decmap+2975,33,126},{__gb2312_decmap+3069,33,126},{ -__gb2312_decmap+3163,33,126},{__gb2312_decmap+3257,33,126},{__gb2312_decmap+ -3351,33,126},{__gb2312_decmap+3445,33,126},{__gb2312_decmap+3539,33,126},{ -__gb2312_decmap+3633,33,126},{__gb2312_decmap+3727,33,126},{__gb2312_decmap+ -3821,33,126},{__gb2312_decmap+3915,33,126},{__gb2312_decmap+4009,33,126},{ -__gb2312_decmap+4103,33,126},{__gb2312_decmap+4197,33,126},{__gb2312_decmap+ -4291,33,126},{__gb2312_decmap+4385,33,121},{__gb2312_decmap+4474,33,126},{ -__gb2312_decmap+4568,33,126},{__gb2312_decmap+4662,33,126},{__gb2312_decmap+ -4756,33,126},{__gb2312_decmap+4850,33,126},{__gb2312_decmap+4944,33,126},{ -__gb2312_decmap+5038,33,126},{__gb2312_decmap+5132,33,126},{__gb2312_decmap+ -5226,33,126},{__gb2312_decmap+5320,33,126},{__gb2312_decmap+5414,33,126},{ -__gb2312_decmap+5508,33,126},{__gb2312_decmap+5602,33,126},{__gb2312_decmap+ -5696,33,126},{__gb2312_decmap+5790,33,126},{__gb2312_decmap+5884,33,126},{ -__gb2312_decmap+5978,33,126},{__gb2312_decmap+6072,33,126},{__gb2312_decmap+ -6166,33,126},{__gb2312_decmap+6260,33,126},{__gb2312_decmap+6354,33,126},{ -__gb2312_decmap+6448,33,126},{__gb2312_decmap+6542,33,126},{__gb2312_decmap+ -6636,33,126},{__gb2312_decmap+6730,33,126},{__gb2312_decmap+6824,33,126},{ -__gb2312_decmap+6918,33,126},{__gb2312_decmap+7012,33,126},{__gb2312_decmap+ -7106,33,126},{__gb2312_decmap+7200,33,126},{__gb2312_decmap+7294,33,126},{ -__gb2312_decmap+7388,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const ucs2_t __gbkext_decmap[14531] = { -19970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009, -20014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042, -20049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075, -20076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091, -20092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,U,20112, -20118,20119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150, -20151,20152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187, -20188,20192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217, -20218,20220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236, -20242,20243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269, -20270,20273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292, -20293,20295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326, -20328,20330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349, -20352,20353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373, -20374,20376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400, -20401,20402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414, -20416,20417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436, -20437,20438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466, -20468,20469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483, -20484,20485,20486,20487,20488,20489,20490,U,20491,20494,20496,20497,20499, -20501,20502,20503,20507,20509,20510,20512,20514,20515,20516,20519,20523,20527, -20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20539,20541,20543, -20544,20545,20546,20548,20549,20550,20553,20554,20555,20557,20560,20561,20562, -20563,20564,20566,20567,20568,20569,20571,20573,20574,20575,20576,20577,20578, -20579,20580,20582,20583,20584,20585,20586,20587,20589,20590,20591,20592,20593, -20594,20595,20596,20597,20600,20601,20602,20604,20605,20609,20610,20611,20612, -20614,20615,20617,20618,20619,20620,20622,20623,20624,20625,20626,20627,20628, -20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641, -20642,20644,20646,20650,20651,20653,20654,20655,20656,20657,20659,20660,20661, -20662,20663,20664,20665,20668,20669,20670,20671,20672,20673,20674,20675,20676, -20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,20688,20689,20690, -20691,20692,20693,20695,20696,20697,20699,20700,20701,20702,20703,20704,20705, -20706,20707,20708,20709,20712,20713,20714,20715,20719,20720,20721,20722,20724, -20726,20727,20728,20729,20730,20732,20733,20734,20735,20736,20737,20738,20739, -20740,20741,20744,U,20745,20746,20748,20749,20750,20751,20752,20753,20755, -20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,20768, -20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782, -20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,20795, -20796,20797,20798,20802,20807,20810,20812,20814,20815,20816,20818,20819,20823, -20824,20825,20827,20829,20830,20831,20832,20833,20835,20836,20838,20839,20841, -20842,20847,20850,20858,20862,20863,20867,20868,20870,20871,20874,20875,20878, -20879,20880,20881,20883,20884,20888,20890,20893,20894,20895,20897,20899,20902, -20903,20904,20905,20906,20909,20910,20916,20920,20921,20922,20926,20927,20929, -20930,20931,20933,20936,20938,20941,20942,20944,20946,20947,20948,20949,20950, -20951,20952,20953,20954,20956,20958,20959,20962,20963,20965,20966,20967,20968, -20969,20970,20972,20974,20977,20978,20980,20983,20990,20996,20997,21001,21003, -21004,21007,21008,21011,21012,21013,21020,21022,21023,21025,21026,21027,21029, -21030,21031,21034,21036,21039,21041,21042,21044,21045,21052,21054,21060,21061, -21062,21063,21064,21065,21067,21070,21071,21074,21075,21077,21079,21080,U, -21081,21082,21083,21085,21087,21088,21090,21091,21092,21094,21096,21099,21100, -21101,21102,21104,21105,21107,21108,21109,21110,21111,21112,21113,21114,21115, -21116,21118,21120,21123,21124,21125,21126,21127,21129,21130,21131,21132,21133, -21134,21135,21137,21138,21140,21141,21142,21143,21144,21145,21146,21148,21156, -21157,21158,21159,21166,21167,21168,21172,21173,21174,21175,21176,21177,21178, -21179,21180,21181,21184,21185,21186,21188,21189,21190,21192,21194,21196,21197, -21198,21199,21201,21203,21204,21205,21207,21209,21210,21211,21212,21213,21214, -21216,21217,21218,21219,21221,21222,21223,21224,21225,21226,21227,21228,21229, -21230,21231,21233,21234,21235,21236,21237,21238,21239,21240,21243,21244,21245, -21249,21250,21251,21252,21255,21257,21258,21259,21260,21262,21265,21266,21267, -21268,21272,21275,21276,21278,21279,21282,21284,21285,21287,21288,21289,21291, -21292,21293,21295,21296,21297,21298,21299,21300,21301,21302,21303,21304,21308, -21309,21312,21314,21316,21318,21323,21324,21325,21328,21332,21336,21337,21339, -21341,21349,21352,21354,21356,21357,21362,21366,21369,21371,21372,21373,21374, -21376,21377,21379,21383,21384,21386,21390,21391,U,21392,21393,21394,21395, -21396,21398,21399,21401,21403,21404,21406,21408,21409,21412,21415,21418,21419, -21420,21421,21423,21424,21425,21426,21427,21428,21429,21431,21432,21433,21434, -21436,21437,21438,21440,21443,21444,21445,21446,21447,21454,21455,21456,21458, -21459,21461,21466,21468,21469,21470,21473,21474,21479,21492,21498,21502,21503, -21504,21506,21509,21511,21515,21524,21528,21529,21530,21532,21538,21540,21541, -21546,21552,21555,21558,21559,21562,21565,21567,21569,21570,21572,21573,21575, -21577,21580,21581,21582,21583,21585,21594,21597,21598,21599,21600,21601,21603, -21605,21607,21609,21610,21611,21612,21613,21614,21615,21616,21620,21625,21626, -21630,21631,21633,21635,21637,21639,21640,21641,21642,21645,21649,21651,21655, -21656,21660,21662,21663,21664,21665,21666,21669,21678,21680,21682,21685,21686, -21687,21689,21690,21692,21694,21699,21701,21706,21707,21718,21720,21723,21728, -21729,21730,21731,21732,21739,21740,21743,21744,21745,21748,21749,21750,21751, -21752,21753,21755,21758,21760,21762,21763,21764,21765,21768,21770,21771,21772, -21773,21774,21778,21779,21781,21782,21783,21784,21785,21786,21788,21789,21790, -21791,21793,21797,21798,U,21800,21801,21803,21805,21810,21812,21813,21814, -21816,21817,21818,21819,21821,21824,21826,21829,21831,21832,21835,21836,21837, -21838,21839,21841,21842,21843,21844,21847,21848,21849,21850,21851,21853,21854, -21855,21856,21858,21859,21864,21865,21867,21871,21872,21873,21874,21875,21876, -21881,21882,21885,21887,21893,21894,21900,21901,21902,21904,21906,21907,21909, -21910,21911,21914,21915,21918,21920,21921,21922,21923,21924,21925,21926,21928, -21929,21930,21931,21932,21933,21934,21935,21936,21938,21940,21942,21944,21946, -21948,21951,21952,21953,21954,21955,21958,21959,21960,21962,21963,21966,21967, -21968,21973,21975,21976,21977,21978,21979,21982,21984,21986,21991,21993,21997, -21998,22000,22001,22004,22006,22008,22009,22010,22011,22012,22015,22018,22019, -22020,22021,22022,22023,22026,22027,22029,22032,22033,22034,22035,22036,22037, -22038,22039,22041,22042,22044,22045,22048,22049,22050,22053,22054,22056,22057, -22058,22059,22062,22063,22064,22067,22069,22071,22072,22074,22076,22077,22078, -22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22095, -22096,22097,22098,22099,22101,22102,22106,22107,22109,22110,22111,22112,22113, -U,22115,22117,22118,22119,22125,22126,22127,22128,22130,22131,22132,22133, -22135,22136,22137,22138,22141,22142,22143,22144,22145,22146,22147,22148,22151, -22152,22153,22154,22155,22156,22157,22160,22161,22162,22164,22165,22166,22167, -22168,22169,22170,22171,22172,22173,22174,22175,22176,22177,22178,22180,22181, -22182,22183,22184,22185,22186,22187,22188,22189,22190,22192,22193,22194,22195, -22196,22197,22198,22200,22201,22202,22203,22205,22206,22207,22208,22209,22210, -22211,22212,22213,22214,22215,22216,22217,22219,22220,22221,22222,22223,22224, -22225,22226,22227,22229,22230,22232,22233,22236,22243,22245,22246,22247,22248, -22249,22250,22252,22254,22255,22258,22259,22262,22263,22264,22267,22268,22272, -22273,22274,22277,22279,22283,22284,22285,22286,22287,22288,22289,22290,22291, -22292,22293,22294,22295,22296,22297,22298,22299,22301,22302,22304,22305,22306, -22308,22309,22310,22311,22315,22321,22322,22324,22325,22326,22327,22328,22332, -22333,22335,22337,22339,22340,22341,22342,22344,22345,22347,22354,22355,22356, -22357,22358,22360,22361,22370,22371,22373,22375,22380,22382,22384,22385,22386, -22388,22389,22392,22393,22394,22397,22398,22399,22400,U,22401,22407,22408, -22409,22410,22413,22414,22415,22416,22417,22420,22421,22422,22423,22424,22425, -22426,22428,22429,22430,22431,22437,22440,22442,22444,22447,22448,22449,22451, -22453,22454,22455,22457,22458,22459,22460,22461,22462,22463,22464,22465,22468, -22469,22470,22471,22472,22473,22474,22476,22477,22480,22481,22483,22486,22487, -22491,22492,22494,22497,22498,22499,22501,22502,22503,22504,22505,22506,22507, -22508,22510,22512,22513,22514,22515,22517,22518,22519,22523,22524,22526,22527, -22529,22531,22532,22533,22536,22537,22538,22540,22542,22543,22544,22546,22547, -22548,22550,22551,22552,22554,22555,22556,22557,22559,22562,22563,22565,22566, -22567,22568,22569,22571,22572,22573,22574,22575,22577,22578,22579,22580,22582, -22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595, -22597,22598,22599,22600,22601,22602,22603,22606,22607,22608,22610,22611,22613, -22614,22615,22617,22618,22619,22620,22621,22623,22624,22625,22626,22627,22628, -22630,22631,22632,22633,22634,22637,22638,22639,22640,22641,22642,22643,22644, -22645,22646,22647,22648,22649,22650,22651,22652,22653,22655,22658,22660,22662, -22663,22664,22666,22667,22668,U,22669,22670,22671,22672,22673,22676,22677, -22678,22679,22680,22683,22684,22685,22688,22689,22690,22691,22692,22693,22694, -22695,22698,22699,22700,22701,22702,22703,22704,22705,22706,22707,22708,22709, -22710,22711,22712,22713,22714,22715,22717,22718,22719,22720,22722,22723,22724, -22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22738,22739, -22740,22742,22743,22744,22745,22746,22747,22748,22749,22750,22751,22752,22753, -22754,22755,22757,22758,22759,22760,22761,22762,22765,22767,22769,22770,22772, -22773,22775,22776,22778,22779,22780,22781,22782,22783,22784,22785,22787,22789, -22790,22792,22793,22794,22795,22796,22798,22800,22801,22802,22803,22807,22808, -22811,22813,22814,22816,22817,22818,22819,22822,22824,22828,22832,22834,22835, -22837,22838,22843,22845,22846,22847,22848,22851,22853,22854,22858,22860,22861, -22864,22866,22867,22873,22875,22876,22877,22878,22879,22881,22883,22884,22886, -22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,22897,22898,22901, -22903,22906,22907,22908,22910,22911,22912,22917,22921,22923,22924,22926,22927, -22928,22929,22932,22933,22936,22938,22939,22940,22941,22943,22944,22945,22946, -22950,U,22951,22956,22957,22960,22961,22963,22964,22965,22966,22967,22968, -22970,22972,22973,22975,22976,22977,22978,22979,22980,22981,22983,22984,22985, -22988,22989,22990,22991,22997,22998,23001,23003,23006,23007,23008,23009,23010, -23012,23014,23015,23017,23018,23019,23021,23022,23023,23024,23025,23026,23027, -23028,23029,23030,23031,23032,23034,23036,23037,23038,23040,23042,23050,23051, -23053,23054,23055,23056,23058,23060,23061,23062,23063,23065,23066,23067,23069, -23070,23073,23074,23076,23078,23079,23080,23082,23083,23084,23085,23086,23087, -23088,23091,23093,23095,23096,23097,23098,23099,23101,23102,23103,23105,23106, -23107,23108,23109,23111,23112,23115,23116,23117,23118,23119,23120,23121,23122, -23123,23124,23126,23127,23128,23129,23131,23132,23133,23134,23135,23136,23137, -23139,23140,23141,23142,23144,23145,23147,23148,23149,23150,23151,23152,23153, -23154,23155,23160,23161,23163,23164,23165,23166,23168,23169,23170,23171,23172, -23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,23183,23184,23185, -23187,23188,23189,23190,23191,23192,23193,23196,23197,23198,23199,23200,23201, -23202,23203,23204,23205,23206,23207,23208,23209,23211,23212,U,23213,23214, -23215,23216,23217,23220,23222,23223,23225,23226,23227,23228,23229,23231,23232, -23235,23236,23237,23238,23239,23240,23242,23243,23245,23246,23247,23248,23249, -23251,23253,23255,23257,23258,23259,23261,23262,23263,23266,23268,23269,23271, -23272,23274,23276,23277,23278,23279,23280,23282,23283,23284,23285,23286,23287, -23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,23300, -23301,23302,23303,23304,23306,23307,23308,23309,23310,23311,23312,23313,23314, -23315,23316,23317,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329, -23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,23341,23342, -23343,23344,23345,23347,23349,23350,23352,23353,23354,23355,23356,23357,23358, -23359,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,23372, -23373,23374,23375,23378,23382,23390,23392,23393,23399,23400,23403,23405,23406, -23407,23410,23412,23414,23415,23416,23417,23419,23420,23422,23423,23426,23430, -23434,23437,23438,23440,23441,23442,23444,23446,23455,23463,23464,23465,23468, -23469,23470,23471,23473,23474,23479,23482,23483,23484,23488,23489,23491,23496, -23497,23498,23499,23501,23502,23503,U,23505,23508,23509,23510,23511,23512, -23513,23514,23515,23516,23520,23522,23523,23526,23527,23529,23530,23531,23532, -23533,23535,23537,23538,23539,23540,23541,23542,23543,23549,23550,23552,23554, -23555,23557,23559,23560,23563,23564,23565,23566,23568,23570,23571,23575,23577, -23579,23582,23583,23584,23585,23587,23590,23592,23593,23594,23595,23597,23598, -23599,23600,23602,23603,23605,23606,23607,23619,23620,23622,23623,23628,23629, -23634,23635,23636,23638,23639,23640,23642,23643,23644,23645,23647,23650,23652, -23655,23656,23657,23658,23659,23660,23661,23664,23666,23667,23668,23669,23670, -23671,23672,23675,23676,23677,23678,23680,23683,23684,23685,23686,23687,23689, -23690,23691,23694,23695,23698,23699,23701,23709,23710,23711,23712,23713,23716, -23717,23718,23719,23720,23722,23726,23727,23728,23730,23732,23734,23737,23738, -23739,23740,23742,23744,23746,23747,23749,23750,23751,23752,23753,23754,23756, -23757,23758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,23771, -23772,23773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,23791, -23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,23806, -23807,23808,U,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823, -23824,23825,23826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840, -23841,23842,23843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859, -23861,23862,23863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875, -23876,23877,23878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892, -23893,23894,23895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908, -23909,23910,23911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926, -23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940, -23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953, -23954,23955,23956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968, -23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981, -23982,23983,23984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995, -23996,23997,23998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009, -24010,24011,24012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023, -24024,24025,24026,24028,24031,24032,24035,24036,24042,24044,24045,U,24048, -24053,24054,24056,24057,24058,24059,24060,24063,24064,24068,24071,24073,24074, -24075,24077,24078,24082,24083,24087,24094,24095,24096,24097,24098,24099,24100, -24101,24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,24118, -24121,24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,24139, -24141,24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,24156, -24157,24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172, -24173,24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,24197, -24200,24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,24228, -24232,24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,24251, -24252,24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24267, -24268,24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,24285, -24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,24300, -24301,24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,24317, -24325,24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,24346, -24348,24349,24350,24353,24354,24355,24356,U,24360,24363,24364,24366,24368, -24370,24371,24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386, -24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399, -24401,24404,24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424, -24427,24430,24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451, -24454,24461,24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479, -24480,24482,24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497, -24498,24499,24500,24502,24504,24505,24506,24507,24510,24511,24512,24513,24514, -24519,24520,24522,24523,24526,24531,24532,24533,24538,24539,24540,24542,24543, -24546,24547,24549,24550,24552,24553,24556,24559,24560,24562,24563,24564,24566, -24567,24569,24570,24572,24583,24584,24585,24587,24588,24592,24593,24595,24599, -24600,24602,24606,24607,24610,24611,24612,24620,24621,24622,24624,24625,24626, -24627,24628,24630,24631,24632,24633,24634,24637,24638,24640,24644,24645,24646, -24647,24648,24649,24650,24652,24654,24655,24657,24659,24660,24662,24663,24664, -24667,24668,24670,24671,24672,24673,24677,24678,24686,24689,24690,24692,24693, -24695,24702,24704,U,24705,24706,24709,24710,24711,24712,24714,24715,24718, -24719,24720,24721,24723,24725,24727,24728,24729,24732,24734,24737,24738,24740, -24741,24743,24745,24746,24750,24752,24755,24757,24758,24759,24761,24762,24765, -24766,24767,24768,24769,24770,24771,24772,24775,24776,24777,24780,24781,24782, -24783,24784,24786,24787,24788,24790,24791,24793,24795,24798,24801,24802,24803, -24804,24805,24810,24817,24818,24821,24823,24824,24827,24828,24829,24830,24831, -24834,24835,24836,24837,24839,24842,24843,24844,24848,24849,24850,24851,24852, -24854,24855,24856,24857,24859,24860,24861,24862,24865,24866,24869,24872,24873, -24874,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887, -24888,24889,24890,24891,24892,24893,24894,24896,24897,24898,24899,24900,24901, -24902,24903,24905,24907,24909,24911,24912,24914,24915,24916,24918,24919,24920, -24921,24922,24923,24924,24926,24927,24928,24929,24931,24932,24933,24934,24937, -24938,24939,24940,24941,24942,24943,24945,24946,24947,24948,24950,24952,24953, -24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966, -24967,24968,24969,24970,24972,24973,24975,24976,24977,24978,24979,24981,U, -24982,24983,24984,24985,24986,24987,24988,24990,24991,24992,24993,24994,24995, -24996,24997,24998,25002,25003,25005,25006,25007,25008,25009,25010,25011,25012, -25013,25014,25016,25017,25018,25019,25020,25021,25023,25024,25025,25027,25028, -25029,25030,25031,25033,25036,25037,25038,25039,25040,25043,25045,25046,25047, -25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060, -25061,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074, -25075,25076,25078,25079,25080,25081,25082,25083,25084,25085,25086,25088,25089, -25090,25091,25092,25093,25095,25097,25107,25108,25113,25116,25117,25118,25120, -25123,25126,25127,25128,25129,25131,25133,25135,25136,25137,25138,25141,25142, -25144,25145,25146,25147,25148,25154,25156,25157,25158,25162,25167,25168,25173, -25174,25175,25177,25178,25180,25181,25182,25183,25184,25185,25186,25188,25189, -25192,25201,25202,25204,25205,25207,25208,25210,25211,25213,25217,25218,25219, -25221,25222,25223,25224,25227,25228,25229,25230,25231,25232,25236,25241,25244, -25245,25246,25251,25254,25255,25257,25258,25261,25262,25263,25264,25266,25267, -25268,25270,25271,25272,25274,25278,25280,25281,U,25283,25291,25295,25297, -25301,25309,25310,25312,25313,25316,25322,25323,25328,25330,25333,25336,25337, -25338,25339,25344,25347,25348,25349,25350,25354,25355,25356,25357,25359,25360, -25362,25363,25364,25365,25367,25368,25369,25372,25382,25383,25385,25388,25389, -25390,25392,25393,25395,25396,25397,25398,25399,25400,25403,25404,25406,25407, -25408,25409,25412,25415,25416,25418,25425,25426,25427,25428,25430,25431,25432, -25433,25434,25435,25436,25437,25440,25444,25445,25446,25448,25450,25451,25452, -25455,25456,25458,25459,25460,25461,25464,25465,25468,25469,25470,25471,25473, -25475,25476,25477,25478,25483,25485,25489,25491,25492,25493,25495,25497,25498, -25499,25500,25501,25502,25503,25505,25508,25510,25515,25519,25521,25522,25525, -25526,25529,25531,25533,25535,25536,25537,25538,25539,25541,25543,25544,25546, -25547,25548,25553,25555,25556,25557,25559,25560,25561,25562,25563,25564,25565, -25567,25570,25572,25573,25574,25575,25576,25579,25580,25582,25583,25584,25585, -25587,25589,25591,25593,25594,25595,25596,25598,25603,25604,25606,25607,25608, -25609,25610,25613,25614,25617,25618,25621,25622,25623,25624,25625,25626,25629, -25631,25634,25635,25636,U,25637,25639,25640,25641,25643,25646,25647,25648, -25649,25650,25651,25653,25654,25655,25656,25657,25659,25660,25662,25664,25666, -25667,25673,25675,25676,25677,25678,25679,25680,25681,25683,25685,25686,25687, -25689,25690,25691,25692,25693,25695,25696,25697,25698,25699,25700,25701,25702, -25704,25706,25707,25708,25710,25711,25712,25713,25714,25715,25716,25717,25718, -25719,25723,25724,25725,25726,25727,25728,25729,25731,25734,25736,25737,25738, -25739,25740,25741,25742,25743,25744,25747,25748,25751,25752,25754,25755,25756, -25757,25759,25760,25761,25762,25763,25765,25766,25767,25768,25770,25771,25775, -25777,25778,25779,25780,25782,25785,25787,25789,25790,25791,25793,25795,25796, -25798,25799,25800,25801,25802,25803,25804,25807,25809,25811,25812,25813,25814, -25817,25818,25819,25820,25821,25823,25824,25825,25827,25829,25831,25832,25833, -25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846, -25847,25848,25849,25850,25851,25852,25853,25854,25855,25857,25858,25859,25860, -25861,25862,25863,25864,25866,25867,25868,25869,25870,25871,25872,25873,25875, -25876,25877,25878,25879,25881,25882,25883,25884,25885,25886,25887,25888,25889, -U,25890,25891,25892,25894,25895,25896,25897,25898,25900,25901,25904,25905, -25906,25907,25911,25914,25916,25917,25920,25921,25922,25923,25924,25926,25927, -25930,25931,25933,25934,25936,25938,25939,25940,25943,25944,25946,25948,25951, -25952,25953,25956,25957,25959,25960,25961,25962,25965,25966,25967,25969,25971, -25973,25974,25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986, -25987,25988,25989,25990,25992,25993,25994,25997,25998,25999,26002,26004,26005, -26006,26008,26010,26013,26014,26016,26018,26019,26022,26024,26026,26028,26030, -26033,26034,26035,26036,26037,26038,26039,26040,26042,26043,26046,26047,26048, -26050,26055,26056,26057,26058,26061,26064,26065,26067,26068,26069,26072,26073, -26074,26075,26076,26077,26078,26079,26081,26083,26084,26090,26091,26098,26099, -26100,26101,26104,26105,26107,26108,26109,26110,26111,26113,26116,26117,26119, -26120,26121,26123,26125,26128,26129,26130,26134,26135,26136,26138,26139,26140, -26142,26145,26146,26147,26148,26150,26153,26154,26155,26156,26158,26160,26162, -26163,26167,26168,26169,26170,26171,26173,26175,26176,26178,26180,26181,26182, -26183,26184,26185,26186,26189,26190,26192,26193,26200,U,26201,26203,26204, -26205,26206,26208,26210,26211,26213,26215,26217,26218,26219,26220,26221,26225, -26226,26227,26229,26232,26233,26235,26236,26237,26239,26240,26241,26243,26245, -26246,26248,26249,26250,26251,26253,26254,26255,26256,26258,26259,26260,26261, -26264,26265,26266,26267,26268,26270,26271,26272,26273,26274,26275,26276,26277, -26278,26281,26282,26283,26284,26285,26287,26288,26289,26290,26291,26293,26294, -26295,26296,26298,26299,26300,26301,26303,26304,26305,26306,26307,26308,26309, -26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322, -26323,26324,26325,26326,26327,26328,26330,26334,26335,26336,26337,26338,26339, -26340,26341,26343,26344,26346,26347,26348,26349,26350,26351,26353,26357,26358, -26360,26362,26363,26365,26369,26370,26371,26372,26373,26374,26375,26380,26382, -26383,26385,26386,26387,26390,26392,26393,26394,26396,26398,26400,26401,26402, -26403,26404,26405,26407,26409,26414,26416,26418,26419,26422,26423,26424,26425, -26427,26428,26430,26431,26433,26436,26437,26439,26442,26443,26445,26450,26452, -26453,26455,26456,26457,26458,26459,26461,26466,26467,26468,26470,26471,26475, -26476,26478,26481,26484,26486,U,26488,26489,26490,26491,26493,26496,26498, -26499,26501,26502,26504,26506,26508,26509,26510,26511,26513,26514,26515,26516, -26518,26521,26523,26527,26528,26529,26532,26534,26537,26540,26542,26545,26546, -26548,26553,26554,26555,26556,26557,26558,26559,26560,26562,26565,26566,26567, -26568,26569,26570,26571,26572,26573,26574,26581,26582,26583,26587,26591,26593, -26595,26596,26598,26599,26600,26602,26603,26605,26606,26610,26613,26614,26615, -26616,26617,26618,26619,26620,26622,26625,26626,26627,26628,26630,26637,26640, -26642,26644,26645,26648,26649,26650,26651,26652,26654,26655,26656,26658,26659, -26660,26661,26662,26663,26664,26667,26668,26669,26670,26671,26672,26673,26676, -26677,26678,26682,26683,26687,26695,26699,26701,26703,26706,26710,26711,26712, -26713,26714,26715,26716,26717,26718,26719,26730,26732,26733,26734,26735,26736, -26737,26738,26739,26741,26744,26745,26746,26747,26748,26749,26750,26751,26752, -26754,26756,26759,26760,26761,26762,26763,26764,26765,26766,26768,26769,26770, -26772,26773,26774,26776,26777,26778,26779,26780,26781,26782,26783,26784,26785, -26787,26788,26789,26793,26794,26795,26796,26798,26801,26802,26804,26806,26807, -26808,U,26809,26810,26811,26812,26813,26814,26815,26817,26819,26820,26821, -26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,26836,26838,26839, -26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,26854,26855,26856, -26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,26871,26872,26875, -26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,26889,26890,26892, -26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,26907,26908,26909, -26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,26923,26924,26926, -26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,26940,26942,26944, -26945,26947,26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958, -26959,26960,26961,26962,26963,26965,26966,26968,26969,26971,26972,26975,26977, -26978,26980,26981,26983,26984,26985,26986,26988,26989,26991,26992,26994,26995, -26996,26997,26998,27002,27003,27005,27006,27007,27009,27011,27013,27018,27019, -27020,27022,27023,27024,27025,27026,27027,27030,27031,27033,27034,27037,27038, -27039,27040,27041,27042,27043,27044,27045,27046,27049,27050,27052,27054,27055, -27056,27058,27059,27061,27062,27064,27065,27066,27068,27069,U,27070,27071, -27072,27074,27075,27076,27077,27078,27079,27080,27081,27083,27085,27087,27089, -27090,27091,27093,27094,27095,27096,27097,27098,27100,27101,27102,27105,27106, -27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27118,27119,27120, -27121,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,27134,27136, -27137,27138,27139,27140,27141,27142,27143,27144,27145,27147,27148,27149,27150, -27151,27152,27153,27154,27155,27156,27157,27158,27161,27162,27163,27164,27165, -27166,27168,27170,27171,27172,27173,27174,27175,27177,27179,27180,27181,27182, -27184,27186,27187,27188,27190,27191,27192,27193,27194,27195,27196,27199,27200, -27201,27202,27203,27205,27206,27208,27209,27210,27211,27212,27213,27214,27215, -27217,27218,27219,27220,27221,27222,27223,27226,27228,27229,27230,27231,27232, -27234,27235,27236,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247, -27248,27250,27251,27252,27253,27254,27255,27256,27258,27259,27261,27262,27263, -27265,27266,27267,27269,27270,27271,27272,27273,27274,27275,27276,27277,27279, -27282,27283,27284,27285,27286,27288,27289,27290,27291,27292,27293,27294,27295, -27297,27298,27299,27300,27301,27302,U,27303,27304,27306,27309,27310,27311, -27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,27324, -27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,27337, -27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,27350, -27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,27363, -27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,27376, -27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,27389, -27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402, -27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415, -27416,27417,27418,27419,27420,27421,27422,27423,27429,27430,27432,27433,27434, -27435,27436,27437,27438,27439,27440,27441,27443,27444,27445,27446,27448,27451, -27452,27453,27455,27456,27457,27458,27460,27461,27464,27466,27467,27469,27470, -27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27482,27483,27484, -27485,27486,27487,27488,27489,27496,27497,27499,27500,27501,27502,27503,27504, -27505,27506,27507,27508,27509,27510,27511,27512,27514,27517,27518,27519,27520, -27525,27528,U,27532,27534,27535,27536,27537,27540,27541,27543,27544,27545, -27548,27549,27550,27551,27552,27554,27555,27556,27557,27558,27559,27560,27561, -27563,27564,27565,27566,27567,27568,27569,27570,27574,27576,27577,27578,27579, -27580,27581,27582,27584,27587,27588,27590,27591,27592,27593,27594,27596,27598, -27600,27601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621, -27622,27623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639, -27640,27642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657, -27658,27659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691, -27692,27693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715, -27716,27717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736, -27737,27738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761, -27763,27765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787, -27789,27790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808, -27810,27816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842, -27843,27846,27847,27848,27851,27853,27854,27855,27857,27858,27864,U,27865, -27866,27868,27869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897, -27903,27904,27906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921, -27923,27924,27925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940, -27942,27944,27945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967, -27968,27970,27972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999, -28001,28002,28004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019, -28021,28022,28025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038, -28039,28042,28043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060, -28066,28069,28076,28077,28080,28081,28083,28084,28086,28087,28089,28090,28091, -28092,28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,28111,28112, -28114,28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,28133,28135, -28136,28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,28154,28157, -28158,28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,28171,28175, -28178,28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,28199,28200, -28202,28204,28206,28208,28209,28211,28213,U,28214,28215,28217,28219,28220, -28221,28222,28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,28235, -28236,28239,28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,28256, -28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,28271, -28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284, -28285,28288,28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,28305, -28306,28307,28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,28321, -28323,28324,28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,28344, -28345,28348,28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,28364, -28365,28366,28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,28394, -28395,28396,28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,28408, -28410,28411,28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,28424, -28426,28427,28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,28442, -28443,28444,28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,28460, -28462,28464,28466,28468,28469,28471,28472,28473,28474,28475,28476,28477,28479, -28480,28481,28482,U,28483,28484,28485,28488,28489,28490,28492,28494,28495, -28496,28497,28498,28499,28500,28501,28502,28503,28505,28506,28507,28509,28511, -28512,28513,28515,28516,28517,28519,28520,28521,28522,28523,28524,28527,28528, -28529,28531,28533,28534,28535,28537,28539,28541,28542,28543,28544,28545,28546, -28547,28549,28550,28551,28554,28555,28559,28560,28561,28562,28563,28564,28565, -28566,28567,28568,28569,28570,28571,28573,28574,28575,28576,28578,28579,28580, -28581,28582,28584,28585,28586,28587,28588,28589,28590,28591,28592,28593,28594, -28596,28597,28599,28600,28602,28603,28604,28605,28606,28607,28609,28611,28612, -28613,28614,28615,28616,28618,28619,28620,28621,28622,28623,28624,28627,28628, -28629,28630,28631,28632,28633,28634,28635,28636,28637,28639,28642,28643,28644, -28645,28646,28647,28648,28649,28650,28651,28652,28653,28656,28657,28658,28659, -28660,28661,28662,28663,28664,28665,28666,28667,28668,28669,28670,28671,28672, -28673,28674,28675,28676,28677,28678,28679,28680,28681,28682,28683,28684,28685, -28686,28687,28688,28690,28691,28692,28693,28694,28695,28696,28697,28700,28701, -28702,28703,28704,28705,28706,28708,28709,28710,28711,28712,28713,28714,U, -28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,28726,28727,28728, -28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,28740,28741,28742, -28743,28744,28745,28746,28747,28749,28750,28752,28753,28754,28755,28756,28757, -28758,28759,28760,28761,28762,28763,28764,28765,28767,28768,28769,28770,28771, -28772,28773,28774,28775,28776,28777,28778,28782,28785,28786,28787,28788,28791, -28793,28794,28795,28797,28801,28802,28803,28804,28806,28807,28808,28811,28812, -28813,28815,28816,28817,28819,28823,28824,28826,28827,28830,28831,28832,28833, -28834,28835,28836,28837,28838,28839,28840,28841,28842,28848,28850,28852,28853, -28854,28858,28862,28863,28868,28869,28870,28871,28873,28875,28876,28877,28878, -28879,28880,28881,28882,28883,28884,28885,28886,28887,28890,28892,28893,28894, -28896,28897,28898,28899,28901,28906,28910,28912,28913,28914,28915,28916,28917, -28918,28920,28922,28923,28924,28926,28927,28928,28929,28930,28931,28932,28933, -28934,28935,28936,28939,28940,28941,28942,28943,28945,28946,28948,28951,28955, -28956,28957,28958,28959,28960,28961,28962,28963,28964,28965,28967,28968,28969, -28970,28971,28972,28973,28974,28978,28979,28980,U,28981,28983,28984,28985, -28986,28987,28988,28989,28990,28991,28992,28993,28994,28995,28996,28998,28999, -29000,29001,29003,29005,29007,29008,29009,29010,29011,29012,29013,29014,29015, -29016,29017,29018,29019,29021,29023,29024,29025,29026,29027,29029,29033,29034, -29035,29036,29037,29039,29040,29041,29044,29045,29046,29047,29049,29051,29052, -29054,29055,29056,29057,29058,29059,29061,29062,29063,29064,29065,29067,29068, -29069,29070,29072,29073,29074,29075,29077,29078,29079,29082,29083,29084,29085, -29086,29089,29090,29091,29092,29093,29094,29095,29097,29098,29099,29101,29102, -29103,29104,29105,29106,29108,29110,29111,29112,29114,29115,29116,29117,29118, -29119,29120,29121,29122,29124,29125,29126,29127,29128,29129,29130,29131,29132, -29133,29135,29136,29137,29138,29139,29142,29143,29144,29145,29146,29147,29148, -29149,29150,29151,29153,29154,29155,29156,29158,29160,29161,29162,29163,29164, -29165,29167,29168,29169,29170,29171,29172,29173,29174,29175,29176,29178,29179, -29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29191,29192,29193, -29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,29204,29205,29206, -29207,29208,29209,29210,U,29211,29212,29214,29215,29216,29217,29218,29219, -29220,29221,29222,29223,29225,29227,29229,29230,29231,29234,29235,29236,29242, -29244,29246,29248,29249,29250,29251,29252,29253,29254,29257,29258,29259,29262, -29263,29264,29265,29267,29268,29269,29271,29272,29274,29276,29278,29280,29283, -29284,29285,29288,29290,29291,29292,29293,29296,29297,29299,29300,29302,29303, -29304,29307,29308,29309,29314,29315,29317,29318,29319,29320,29321,29324,29326, -29328,29329,29331,29332,29333,29334,29335,29336,29337,29338,29339,29340,29341, -29342,29344,29345,29346,29347,29348,29349,29350,29351,29352,29353,29354,29355, -29358,29361,29362,29363,29365,29370,29371,29372,29373,29374,29375,29376,29381, -29382,29383,29385,29386,29387,29388,29391,29393,29395,29396,29397,29398,29400, -29402,29403,183,U,U,U,U,U,8212,8560,8561,8562,8563,8564,8565,8566,8567,8568, -8569,65077,65078,65081,65082,65087,65088,65085,65086,65089,65090,65091,65092, -U,U,65083,65084,65079,65080,65073,U,65075,65076,714,715,729,8211,8213,8229, -8245,8453,8457,8598,8599,8600,8601,8725,8735,8739,8786,8806,8807,8895,9552, -9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567, -9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582, -9583,9584,9585,9586,9587,9601,9602,9603,9604,9605,9606,9607,U,9608,9609,9610, -9611,9612,9613,9614,9615,9619,9620,9621,9660,9661,9698,9699,9700,9701,9737, -8853,12306,12317,12318,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,593,U,324,328,U,609,12321,12322,12323,12324,12325,12326, -12327,12328,12329,12963,13198,13199,13212,13213,13214,13217,13252,13262,13265, -13266,13269,65072,65506,65508,U,8481,12849,U,8208,U,U,U,12540,12443,12444, -12541,12542,12294,12445,12446,65097,65098,65099,65100,65101,65102,65103,65104, -65105,65106,65108,65109,65110,65111,65113,65114,65115,65116,65117,65118,65119, -65120,65121,U,65122,65123,65124,65125,65126,65128,65129,65130,65131,U,U,U,U,U, -U,U,U,U,U,U,U,U,12295,29404,29405,29407,29410,29411,29412,29413,29414,29415, -29418,29419,29429,29430,29433,29437,29438,29439,29440,29442,29444,29445,29446, -29447,29448,29449,29451,29452,29453,29455,29456,29457,29458,29460,29464,29465, -29466,29471,29472,29475,29476,29478,29479,29480,29485,29487,29488,29490,29491, -29493,29494,29498,29499,29500,29501,29504,29505,29506,29507,29508,29509,29510, -29511,29512,U,29513,29514,29515,29516,29518,29519,29521,29523,29524,29525, -29526,29528,29529,29530,29531,29532,29533,29534,29535,29537,29538,29539,29540, -29541,29542,29543,29544,29545,29546,29547,29550,29552,29553,29554,29555,29556, -29557,29558,29559,29560,29561,29562,29563,29564,29565,29567,29568,29569,29570, -29571,29573,29574,29576,29578,29580,29581,29583,29584,29586,29587,29588,29589, -29591,29592,29593,29594,29596,29597,29598,29600,29601,29603,29604,29605,29606, -29607,29608,29610,29612,29613,29617,29620,29621,29622,29624,29625,29628,29629, -29630,29631,29633,29635,29636,29637,29638,29639,U,29643,29644,29646,29650, -29651,29652,29653,29654,29655,29656,29658,29659,29660,29661,29663,29665,29666, -29667,29668,29670,29672,29674,29675,29676,29678,29679,29680,29681,29683,29684, -29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697, -29698,29700,29703,29704,29707,29708,29709,29710,29713,29714,29715,29716,29717, -29718,29719,29720,29721,29724,29725,29726,29727,29728,29729,29731,29732,29735, -29737,29739,29741,29743,29745,29746,29751,29752,29753,29754,29755,29757,29758, -29759,29760,29762,29763,29764,29765,29766,29767,29768,29769,29770,29771,29772, -29773,U,29774,29775,29776,29777,29778,29779,29780,29782,29784,29789,29792, -29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,29806, -29807,29809,29810,29811,29812,29813,29816,29817,29818,29819,29820,29821,29823, -29826,29828,29829,29830,29832,29833,29834,29836,29837,29839,29841,29842,29843, -29844,29845,29846,29847,29848,29849,29850,29851,29853,29855,29856,29857,29858, -29859,29860,29861,29862,29866,29867,29868,29869,29870,29871,29872,29873,29874, -29875,29876,29877,29878,29879,29880,29881,29883,29884,29885,29886,29887,29888, -29889,29890,29891,29892,29893,29894,29895,U,29896,29897,29898,29899,29900, -29901,29902,29903,29904,29905,29907,29908,29909,29910,29911,29912,29913,29914, -29915,29917,29919,29921,29925,29927,29928,29929,29930,29931,29932,29933,29936, -29937,29938,29939,29941,29944,29945,29946,29947,29948,29949,29950,29952,29953, -29954,29955,29957,29958,29959,29960,29961,29962,29963,29964,29966,29968,29970, -29972,29973,29974,29975,29979,29981,29982,29984,29985,29986,29987,29988,29990, -29991,29994,29998,30004,30006,30009,30012,30013,30015,30017,30018,30019,30020, -30022,30023,30025,30026,30029,30032,30033,30034,30035,30037,30038,30039,30040, -U,30045,30046,30047,30048,30049,30050,30051,30052,30055,30056,30057,30059, -30060,30061,30062,30063,30064,30065,30067,30069,30070,30071,30074,30075,30076, -30077,30078,30080,30081,30082,30084,30085,30087,30088,30089,30090,30092,30093, -30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,30119,30120,30121, -30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,30155,30156,30158, -30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,30176,30177,30181, -30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,30200,30202,30203, -30205,30206,30210,30212,30214,30215,U,30216,30217,30219,30221,30222,30223, -30225,30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,30247,30248, -30252,30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,30273,30274, -30276,30277,30278,30279,30280,30281,30282,30283,30286,30287,30288,30289,30290, -30291,30293,30295,30296,30297,30298,30299,30301,30303,30304,30305,30306,30308, -30309,30310,30311,30312,30313,30314,30316,30317,30318,30320,30321,30322,30323, -30324,30325,30326,30327,30329,30330,30332,30335,30336,30337,30339,30341,30345, -30346,30348,30349,30351,30352,30354,30356,30357,30359,30360,30362,30363,U, -30364,30365,30366,30367,30368,30369,30370,30371,30373,30374,30375,30376,30377, -30378,30379,30380,30381,30383,30384,30387,30389,30390,30391,30392,30393,30394, -30395,30396,30397,30398,30400,30401,30403,30404,30407,30409,30411,30412,30419, -30421,30425,30426,30428,30429,30430,30432,30433,30434,30435,30436,30438,30439, -30440,30441,30442,30443,30444,30445,30448,30451,30453,30454,30455,30458,30459, -30461,30463,30464,30466,30467,30469,30470,30474,30476,30478,30479,30480,30481, -30482,30483,30484,30485,30486,30487,30488,30491,30492,30493,30494,30497,30499, -30500,30501,30503,30506,30507,U,30508,30510,30512,30513,30514,30515,30516, -30521,30523,30525,30526,30527,30530,30532,30533,30534,30536,30537,30538,30539, -30540,30541,30542,30543,30546,30547,30548,30549,30550,30551,30552,30553,30556, -30557,30558,30559,30560,30564,30567,30569,30570,30573,30574,30575,30576,30577, -30578,30579,30580,30581,30582,30583,30584,30586,30587,30588,30593,30594,30595, -30598,30599,30600,30601,30602,30603,30607,30608,30611,30612,30613,30614,30615, -30616,30617,30618,30619,30620,30621,30622,30625,30627,30628,30630,30632,30635, -30637,30638,30639,30641,30642,30644,30646,30647,30648,30649,30650,U,30652, -30654,30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667, -30668,30670,30671,30672,30673,30674,30675,30676,30677,30678,30680,30681,30682, -30685,30686,30687,30688,30689,30692,30694,30696,30698,30703,30704,30705,30706, -30708,30709,30711,30713,30714,30715,30716,30723,30724,30725,30726,30727,30728, -30730,30731,30734,30735,30736,30739,30741,30745,30747,30750,30752,30753,30754, -30756,30760,30762,30763,30766,30767,30769,30770,30771,30773,30774,30781,30783, -30785,30786,30787,30788,30790,30792,30793,30794,30795,30797,30799,30801,30803, -30804,30808,30809,30810,U,30811,30812,30814,30815,30816,30817,30818,30819, -30820,30821,30822,30823,30824,30825,30831,30832,30833,30834,30835,30836,30837, -30838,30840,30841,30842,30843,30845,30846,30847,30848,30849,30850,30851,30852, -30853,30854,30856,30858,30859,30863,30864,30866,30868,30869,30870,30873,30877, -30878,30880,30882,30884,30886,30888,30889,30890,30891,30892,30893,30894,30895, -30901,30902,30903,30904,30906,30907,30908,30909,30911,30912,30914,30915,30916, -30918,30919,30920,30924,30925,30926,30927,30929,30930,30931,30934,30935,30936, -30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,U,30948,30949, -30950,30951,30953,30954,30955,30957,30958,30959,30960,30961,30963,30965,30966, -30968,30969,30971,30972,30973,30974,30975,30976,30978,30979,30980,30982,30983, -30984,30985,30986,30987,30988,30989,30990,30991,30992,30993,30994,30996,30997, -30998,30999,31000,31001,31002,31003,31004,31005,31007,31008,31009,31010,31011, -31013,31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025, -31026,31027,31029,31030,31031,31032,31033,31037,31039,31042,31043,31044,31045, -31047,31050,31051,31052,31053,31054,31055,31056,31057,31058,31060,31061,31064, -31065,31073,31075,U,31076,31078,31081,31082,31083,31084,31086,31088,31089, -31090,31091,31092,31093,31094,31097,31099,31100,31101,31102,31103,31106,31107, -31110,31111,31112,31113,31115,31116,31117,31118,31120,31121,31122,31123,31124, -31125,31126,31127,31128,31129,31131,31132,31133,31134,31135,31136,31137,31138, -31139,31140,31141,31142,31144,31145,31146,31147,31148,31149,31150,31151,31152, -31153,31154,31156,31157,31158,31159,31160,31164,31167,31170,31172,31173,31175, -31176,31178,31180,31182,31183,31184,31187,31188,31190,31191,31193,31194,31195, -31196,31197,31198,31200,31201,31202,31205,31208,31210,U,31212,31214,31217, -31218,31219,31220,31221,31222,31223,31225,31226,31228,31230,31231,31233,31236, -31237,31239,31240,31241,31242,31244,31247,31248,31249,31250,31251,31253,31254, -31256,31257,31259,31260,31261,31263,31265,31266,31268,31269,31270,31271,31272, -31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,31284,31285,31286, -31288,31290,31294,31296,31297,31298,31299,31300,31301,31303,31304,31305,31306, -31307,31308,31309,31310,31311,31312,31314,31315,31316,31317,31318,31320,31321, -31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,31332,31333,31334, -31335,31336,U,31337,31338,31339,31340,31341,31342,31343,31345,31346,31347, -31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,31371,31372,31374, -31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,31395,31396,31399, -31401,31402,31403,31406,31407,31408,31409,31410,31412,31413,31414,31415,31416, -31417,31418,31419,31420,31421,31422,31424,31425,31426,31427,31428,31429,31430, -31431,31432,31433,31434,31436,31437,31438,31439,31440,31441,31442,31443,31444, -31445,31447,31448,31450,31451,31452,31453,31457,31458,31460,31463,31464,31465, -31466,31467,31468,31470,31472,31473,31474,31475,U,31476,31477,31478,31479, -31480,31483,31484,31486,31488,31489,31490,31493,31495,31497,31500,31501,31502, -31504,31506,31507,31510,31511,31512,31514,31516,31517,31519,31521,31522,31523, -31527,31529,31533,31535,31536,31538,31540,31541,31542,31543,31545,31547,31549, -31551,31552,31553,31554,31555,31556,31558,31560,31562,31565,31566,31571,31573, -31575,31577,31580,31582,31583,31585,31587,31588,31589,31590,31591,31592,31593, -31594,31595,31596,31597,31599,31600,31603,31604,31606,31608,31610,31612,31613, -31615,31617,31618,31619,31620,31622,31623,31624,31625,31626,31627,31628,31630, -31631,U,31633,31634,31635,31638,31640,31641,31642,31643,31646,31647,31648, -31651,31652,31653,31662,31663,31664,31666,31667,31669,31670,31671,31673,31674, -31675,31676,31677,31678,31679,31680,31682,31683,31684,31685,31688,31689,31690, -31691,31693,31694,31695,31696,31698,31700,31701,31702,31703,31704,31707,31708, -31710,31711,31712,31714,31715,31716,31719,31720,31721,31723,31724,31725,31727, -31728,31730,31731,31732,31733,31734,31736,31737,31738,31739,31741,31743,31744, -31745,31746,31747,31748,31749,31750,31752,31753,31754,31757,31758,31760,31761, -31762,31763,31764,31765,31767,31768,31769,U,31770,31771,31772,31773,31774, -31776,31777,31778,31779,31780,31781,31784,31785,31787,31788,31789,31790,31791, -31792,31793,31794,31795,31796,31797,31798,31799,31801,31802,31803,31804,31805, -31806,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822, -31823,31824,31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835, -31836,31837,31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848, -31849,31850,31851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863, -31864,31865,31866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879, -U,31880,31882,31883,31884,31885,31886,31887,31888,31891,31892,31894,31897, -31898,31899,31904,31905,31907,31910,31911,31912,31913,31915,31916,31917,31919, -31920,31924,31925,31926,31927,31928,31930,31931,31935,31936,31938,31939,31940, -31942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963, -31965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980, -31981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996, -31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009, -32011,32012,32013,32014,32015,32016,U,32017,32018,32019,32020,32021,32022, -32023,32024,32025,32026,32027,32028,32029,32030,32031,32033,32035,32036,32037, -32038,32040,32041,32042,32044,32045,32046,32048,32049,32050,32051,32052,32053, -32054,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,32065,32066, -32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,32078,32079, -32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,32091,32092, -32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,32104,32105, -32106,32107,32108,32109,32111,32112,32113,32114,32115,32116,32117,32118,U, -32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,32132, -32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,32145, -32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,32156,32157,32158, -32159,32160,32161,32162,32163,32164,32165,32167,32168,32169,32170,32171,32172, -32173,32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186, -32187,32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199, -32200,32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212, -32213,32214,32215,32216,32217,U,32218,32219,32220,32221,32222,32223,32224, -32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237, -32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250, -32251,32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263, -32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,32276, -32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,32288,32289, -32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,32300,32301,32302, -32303,32304,32305,32306,32307,32308,32309,32310,32311,32312,32313,U,32314, -32316,32317,32318,32319,32320,32322,32323,32324,32325,32326,32328,32329,32330, -32331,32332,32333,32334,32335,32336,32337,32338,32339,32340,32341,32342,32343, -32344,32345,32346,32347,32348,32349,32350,32351,32352,32353,32354,32355,32356, -32357,32358,32359,32360,32361,32362,32363,32364,32365,32366,32367,32368,32369, -32370,32371,32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382, -32383,32384,32385,32387,32388,32389,32390,32391,32392,32393,32394,32395,32396, -32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,32408,32409, -32410,32412,32413,32414,U,32430,32436,32443,32444,32470,32484,32492,32505, -32522,32528,32542,32567,32569,32571,32572,32573,32574,32575,32576,32577,32579, -32582,32583,32584,32585,32586,32587,32588,32589,32590,32591,32594,32595,32598, -32601,32603,32604,32605,32606,32608,32611,32612,32613,32614,32615,32619,32620, -32621,32623,32624,32627,32629,32630,32631,32632,32634,32635,32636,32637,32639, -32640,32642,32643,32644,32645,32646,32647,32648,32649,32651,32653,32655,32656, -32657,32658,32659,32661,32662,32663,32664,32665,32667,32668,32672,32674,32675, -32677,32678,32680,32681,32682,32683,32684,32685,32686,32689,U,32691,32692, -32693,32694,32695,32698,32699,32702,32704,32706,32707,32708,32710,32711,32712, -32713,32715,32717,32719,32720,32721,32722,32723,32726,32727,32729,32730,32731, -32732,32733,32734,32738,32739,32740,32743,32744,32746,32747,32748,32749,32751, -32754,32756,32757,32758,32759,32760,32761,32762,32765,32766,32767,32770,32775, -32776,32777,32778,32782,32783,32785,32787,32794,32795,32797,32798,32799,32801, -32803,32804,32811,32812,32813,32814,32815,32816,32818,32820,32825,32826,32828, -32830,32832,32833,32836,32837,32839,32840,32841,32846,32847,32848,32849,32851, -32853,32854,32855,U,32857,32859,32860,32861,32862,32863,32864,32865,32866, -32867,32868,32869,32870,32871,32872,32875,32876,32877,32878,32879,32880,32882, -32883,32884,32885,32886,32887,32888,32889,32890,32891,32892,32893,32894,32897, -32898,32901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,32919, -32921,32926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,32953, -32955,32965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,32980, -32981,32984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,33022, -33023,33024,33025,33027,33028,33029,33031,33032,33035,U,33036,33045,33047, -33049,33051,33052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063, -33064,33065,33066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082, -33083,33084,33085,33087,33088,33089,33090,33091,33092,33093,33095,33097,33101, -33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,33119,33121,33122, -33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,33141,33142,33143, -33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,33165,33166,33168, -33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,33184,33185,33186, -33188,33189,U,33191,33193,33195,33196,33197,33198,33199,33200,33201,33202, -33204,33205,33206,33207,33208,33209,33212,33213,33214,33215,33220,33221,33223, -33224,33225,33227,33229,33230,33231,33232,33233,33234,33235,33236,33237,33238, -33239,33240,33241,33242,33243,33244,33245,33246,33247,33248,33249,33250,33252, -33253,33254,33256,33257,33259,33262,33263,33264,33265,33266,33269,33270,33271, -33272,33273,33274,33277,33279,33283,33287,33288,33289,33290,33291,33294,33295, -33297,33299,33301,33302,33303,33304,33305,33306,33309,33312,33316,33317,33318, -33319,33321,33326,33330,33338,33340,33341,33343,U,33344,33345,33346,33347, -33349,33350,33352,33354,33356,33357,33358,33360,33361,33362,33363,33364,33365, -33366,33367,33369,33371,33372,33373,33374,33376,33377,33378,33379,33380,33381, -33382,33383,33385,33386,33387,33388,33389,33393,33397,33398,33399,33400,33403, -33404,33408,33409,33411,33413,33414,33415,33417,33420,33424,33427,33428,33429, -33430,33434,33435,33438,33440,33442,33443,33447,33458,33461,33462,33466,33467, -33468,33471,33472,33474,33475,33477,33478,33481,33488,33494,33497,33498,33501, -33506,33511,33512,33513,33514,33516,33517,33518,33520,33522,33523,33525,33526, -33528,U,33530,33532,33533,33534,33535,33536,33546,33547,33549,33552,33554, -33555,33558,33560,33561,33565,33566,33567,33568,33569,33570,33571,33572,33573, -33574,33577,33578,33582,33584,33586,33591,33595,33597,33598,33599,33601,33602, -33604,33605,33608,33610,33611,33612,33613,33614,33619,33621,33622,33623,33624, -33625,33629,33634,33648,33649,33650,33651,33652,33653,33654,33657,33658,33662, -33663,33664,33665,33666,33667,33668,33671,33672,33674,33675,33676,33677,33679, -33680,33681,33684,33685,33686,33687,33689,33690,33693,33695,33697,33698,33699, -33700,33701,33702,33703,33708,33709,33710,U,33711,33717,33723,33726,33727, -33730,33731,33732,33734,33736,33737,33739,33741,33742,33744,33745,33746,33747, -33749,33751,33753,33754,33755,33758,33762,33763,33764,33766,33767,33768,33771, -33772,33773,33774,33775,33779,33780,33781,33782,33783,33786,33787,33788,33790, -33791,33792,33794,33797,33799,33800,33801,33802,33808,33810,33811,33812,33813, -33814,33815,33817,33818,33819,33822,33823,33824,33825,33826,33827,33833,33834, -33835,33836,33837,33838,33839,33840,33842,33843,33844,33845,33846,33847,33849, -33850,33851,33854,33855,33856,33857,33858,33859,33860,33861,33863,33864,33865, -U,33866,33867,33868,33869,33870,33871,33872,33874,33875,33876,33877,33878, -33880,33885,33886,33887,33888,33890,33892,33893,33894,33895,33896,33898,33902, -33903,33904,33906,33908,33911,33913,33915,33916,33917,33918,33919,33920,33921, -33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,33941, -33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,33958, -33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,33974, -33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,33996, -33998,33999,34002,34004,34005,34007,U,34008,34009,34010,34011,34012,34014, -34017,34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034, -34035,34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049, -34050,34051,34052,34053,34054,34055,34056,34057,34058,34059,34061,34062,34063, -34064,34066,34068,34069,34070,34072,34073,34075,34076,34077,34078,34080,34082, -34083,34084,34085,34086,34087,34088,34089,34090,34093,34094,34095,34096,34097, -34098,34099,34100,34101,34102,34110,34111,34112,34113,34114,34116,34117,34118, -34119,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,U, -34135,34136,34138,34139,34140,34141,34143,34144,34145,34146,34147,34149,34150, -34151,34153,34154,34155,34156,34157,34158,34159,34160,34161,34163,34165,34166, -34167,34168,34172,34173,34175,34176,34177,34178,34179,34182,34184,34185,34186, -34187,34188,34189,34190,34192,34193,34194,34195,34196,34197,34198,34199,34200, -34201,34202,34205,34206,34207,34208,34209,34210,34211,34213,34214,34215,34217, -34219,34220,34221,34225,34226,34227,34228,34229,34230,34232,34234,34235,34236, -34237,34238,34239,34240,34242,34243,34244,34245,34246,34247,34248,34250,34251, -34252,34253,34254,34257,34258,U,34260,34262,34263,34264,34265,34266,34267, -34269,34270,34271,34272,34273,34274,34275,34277,34278,34279,34280,34282,34283, -34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296, -34297,34298,34300,34301,34302,34304,34305,34306,34307,34308,34310,34311,34312, -34313,34314,34315,34316,34317,34318,34319,34320,34322,34323,34324,34325,34327, -34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,34339,34340, -34341,34342,34344,34346,34347,34348,34349,34350,34351,34352,34353,34354,34355, -34356,34357,34358,34359,34361,34362,34363,34365,34366,34367,34368,U,34369, -34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34386,34387, -34389,34390,34391,34392,34393,34395,34396,34397,34399,34400,34401,34403,34404, -34405,34406,34407,34408,34409,34410,34413,34415,34416,34418,34419,34420,34421, -34422,34423,34424,34435,34436,34437,34438,34439,34440,34441,34446,34447,34448, -34449,34450,34452,34454,34455,34456,34457,34458,34459,34462,34463,34464,34465, -34466,34469,34470,34475,34477,34478,34482,34483,34487,34488,34489,34491,34492, -34493,34494,34495,34497,34498,34499,34501,34504,34508,34509,34514,34515,34517, -34518,34519,34522,34524,U,34525,34528,34529,34530,34531,34533,34534,34535, -34536,34538,34539,34540,34543,34549,34550,34551,34554,34555,34556,34557,34559, -34561,34564,34565,34566,34571,34572,34574,34575,34576,34577,34580,34582,34585, -34587,34589,34591,34592,34596,34598,34599,34600,34602,34603,34604,34605,34607, -34608,34610,34611,34613,34614,34616,34617,34618,34620,34621,34624,34625,34626, -34627,34628,34629,34630,34634,34635,34637,34639,34640,34641,34642,34644,34645, -34646,34648,34650,34651,34652,34653,34654,34655,34657,34658,34662,34663,34664, -34665,34666,34667,34668,34669,34671,34673,34674,34675,34677,U,34679,34680, -34681,34682,34687,34688,34689,34692,34694,34695,34697,34698,34700,34702,34703, -34704,34705,34706,34708,34709,34710,34712,34713,34714,34715,34716,34717,34718, -34720,34721,34722,34723,34724,34725,34726,34727,34729,34730,34734,34736,34737, -34738,34740,34742,34743,34744,34745,34747,34748,34750,34751,34753,34754,34755, -34756,34757,34759,34760,34761,34764,34765,34766,34767,34768,34772,34773,34774, -34775,34776,34777,34778,34780,34781,34782,34783,34785,34786,34787,34788,34790, -34791,34792,34793,34795,34796,34797,34799,34800,34801,34802,34803,34804,34805, -34806,34807,34808,U,34810,34811,34812,34813,34815,34816,34817,34818,34820, -34821,34822,34823,34824,34825,34827,34828,34829,34830,34831,34832,34833,34834, -34836,34839,34840,34841,34842,34844,34845,34846,34847,34848,34851,34852,34853, -34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34867, -34868,34869,34870,34871,34872,34874,34875,34877,34878,34879,34881,34882,34883, -34886,34887,34888,34889,34890,34891,34894,34895,34896,34897,34898,34899,34901, -34902,34904,34906,34907,34908,34909,34910,34911,34912,34918,34919,34922,34925, -34927,34929,34931,34932,34933,34934,34936,34937,34938,U,34939,34940,34944, -34947,34950,34951,34953,34954,34956,34958,34959,34960,34961,34963,34964,34965, -34967,34968,34969,34970,34971,34973,34974,34975,34976,34977,34979,34981,34982, -34983,34984,34985,34986,34988,34990,34991,34992,34994,34995,34996,34997,34998, -35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,35015,35016,35018, -35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,35035,35036,35037, -35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,35054,35055,35058, -35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,35076,35077,35078, -35079,35080,U,35081,35083,35084,35085,35086,35087,35089,35092,35093,35094, -35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,35111,35112, -35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,35128,35129,35130, -35131,35132,35133,35134,35135,35136,35138,35139,35141,35142,35143,35144,35145, -35146,35147,35148,35149,35150,35151,35152,35153,35154,35155,35156,35157,35158, -35159,35160,35161,35162,35163,35164,35165,35168,35169,35170,35171,35172,35173, -35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,35185,35186,35187, -35188,35189,35190,35191,35192,35193,35194,35196,U,35197,35198,35200,35202, -35204,35205,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217, -35218,35219,35220,35221,35222,35223,35224,35225,35226,35227,35228,35229,35230, -35231,35232,35233,35234,35235,35236,35237,35238,35239,35240,35241,35242,35243, -35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,35254,35255,35256, -35257,35258,35259,35260,35261,35262,35263,35264,35267,35277,35283,35284,35285, -35287,35288,35289,35291,35293,35295,35296,35297,35298,35300,35303,35304,35305, -35306,35308,35309,35310,35312,35313,35314,35316,35317,35318,35319,35320,35321, -35322,U,35323,35324,35325,35326,35327,35329,35330,35331,35332,35333,35334, -35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348, -35349,35350,35351,35352,35353,35354,35355,35356,35357,35358,35359,35360,35361, -35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,35372,35373,35374, -35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,35385,35386,35387, -35388,35389,35391,35392,35393,35394,35395,35396,35397,35398,35399,35401,35402, -35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,35413,35414,35415, -35416,35417,35418,35419,35420,35421,35422,U,35423,35424,35425,35426,35427, -35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,35439,35440, -35441,35442,35443,35444,35445,35446,35447,35448,35450,35451,35452,35453,35454, -35455,35456,35457,35458,35459,35460,35461,35462,35463,35464,35467,35468,35469, -35470,35471,35472,35473,35474,35476,35477,35478,35479,35480,35481,35482,35483, -35484,35485,35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496, -35497,35498,35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509, -35510,35511,35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522, -U,35523,35524,35525,35526,35527,35528,35529,35530,35531,35532,35533,35534, -35535,35536,35537,35538,35539,35540,35541,35542,35543,35544,35545,35546,35547, -35548,35549,35550,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560, -35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573, -35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586, -35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,35599,35600, -35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613, -35614,35615,35616,35617,35618,35619,U,35620,35621,35623,35624,35625,35626, -35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639, -35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652, -35653,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,35664,35665, -35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,35677,35678, -35679,35680,35681,35682,35683,35684,35685,35687,35688,35689,35690,35691,35693, -35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706, -35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,35718,U, -35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,35731, -35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,35756, -35761,35771,35783,35792,35818,35849,35870,35896,35897,35898,35899,35900,35901, -35902,35903,35904,35906,35907,35908,35909,35912,35914,35915,35917,35918,35919, -35920,35921,35922,35923,35924,35926,35927,35928,35929,35931,35932,35933,35934, -35935,35936,35939,35940,35941,35942,35943,35944,35945,35948,35949,35950,35951, -35952,35953,35954,35956,35957,35958,35959,35963,35964,35965,35966,35967,35968, -35969,35971,35972,35974,35975,U,35976,35979,35981,35982,35983,35984,35985, -35986,35987,35989,35990,35991,35993,35994,35995,35996,35997,35998,35999,36000, -36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,36011,36012,36013, -36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,36024,36025,36026, -36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,36037,36038,36039, -36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,36050,36051,36052, -36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,36063,36064,36065, -36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,36076,U,36077, -36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,36090, -36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,36102,36103, -36104,36105,36106,36107,36108,36109,36110,36111,36112,36113,36114,36115,36116, -36117,36118,36119,36120,36121,36122,36123,36124,36128,36177,36178,36183,36191, -36197,36200,36201,36202,36204,36206,36207,36209,36210,36216,36217,36218,36219, -36220,36221,36222,36223,36224,36226,36227,36230,36231,36232,36233,36236,36237, -36238,36239,36240,36242,36243,36245,36246,36247,36248,36249,36250,36251,36252, -36253,36254,36256,36257,U,36258,36260,36261,36262,36263,36264,36265,36266, -36267,36268,36269,36270,36271,36272,36274,36278,36279,36281,36283,36285,36288, -36289,36290,36293,36295,36296,36297,36298,36301,36304,36306,36307,36308,36309, -36312,36313,36316,36320,36321,36322,36325,36326,36327,36329,36333,36334,36336, -36337,36338,36340,36342,36348,36350,36351,36352,36353,36354,36355,36356,36358, -36359,36360,36363,36365,36366,36368,36369,36370,36371,36373,36374,36375,36376, -36377,36378,36379,36380,36384,36385,36388,36389,36390,36391,36392,36395,36397, -36400,36402,36403,36404,36406,36407,36408,36411,36412,36414,U,36415,36419, -36421,36422,36428,36429,36430,36431,36432,36435,36436,36437,36438,36439,36440, -36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,36455, -36456,36458,36459,36462,36465,36467,36469,36471,36472,36473,36474,36475,36477, -36478,36480,36482,36483,36484,36486,36488,36489,36490,36491,36492,36493,36494, -36497,36498,36499,36501,36502,36503,36504,36505,36506,36507,36509,36511,36512, -36513,36514,36515,36516,36517,36518,36519,36520,36521,36522,36525,36526,36528, -36529,36531,36532,36533,36534,36535,36536,36537,36539,36540,36541,36542,36543, -36544,36545,36546,U,36547,36548,36549,36550,36551,36552,36553,36554,36555, -36556,36557,36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569, -36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,36580,36581,36582, -36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,36595, -36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,36608, -36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,36621, -36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,36634, -36635,36636,36637,36638,36639,36640,36641,36642,36643,U,36644,36645,36646, -36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659, -36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672, -36673,36674,36675,36676,36677,36678,36679,36680,36681,36682,36683,36684,36685, -36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,36698, -36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,36709,36714,36736, -36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,36778,36780,36781, -36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,36796,36799,36800, -36803,36806,U,36809,36810,36811,36812,36813,36815,36818,36822,36823,36826, -36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,36858,36859, -36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,36889,36892,36899, -36900,36901,36903,36904,36905,36906,36907,36908,36912,36913,36914,36915,36916, -36919,36921,36922,36925,36927,36928,36931,36933,36934,36936,36937,36938,36939, -36940,36942,36948,36949,36950,36953,36954,36956,36957,36958,36959,36960,36961, -36964,36966,36967,36969,36970,36971,36972,36975,36976,36977,36978,36979,36982, -36983,36984,36985,36986,36987,36988,36990,36993,U,36996,36997,36998,36999, -37001,37002,37004,37005,37006,37007,37008,37010,37012,37014,37016,37018,37020, -37022,37023,37024,37028,37029,37031,37032,37033,37035,37037,37042,37047,37052, -37053,37055,37056,37058,37059,37062,37064,37065,37067,37068,37069,37074,37076, -37077,37078,37080,37081,37082,37086,37087,37088,37091,37092,37093,37097,37098, -37100,37102,37104,37105,37106,37107,37109,37110,37111,37113,37114,37115,37116, -37119,37120,37121,37123,37125,37126,37127,37128,37129,37130,37131,37132,37133, -37134,37135,37136,37137,37138,37139,37140,37141,37142,37143,37144,37146,37147, -37148,U,37149,37151,37152,37153,37156,37157,37158,37159,37160,37161,37162, -37163,37164,37165,37166,37168,37170,37171,37172,37173,37174,37175,37176,37178, -37179,37180,37181,37182,37183,37184,37185,37186,37188,37189,37191,37192,37201, -37203,37204,37205,37206,37208,37209,37211,37212,37215,37216,37222,37223,37224, -37227,37229,37235,37242,37243,37244,37248,37249,37250,37251,37252,37254,37256, -37258,37262,37263,37267,37268,37269,37270,37271,37272,37273,37276,37277,37278, -37279,37280,37281,37284,37285,37286,37287,37288,37289,37291,37292,37296,37297, -37298,37299,37302,37303,37304,37305,37307,U,37308,37309,37310,37311,37312, -37313,37314,37315,37316,37317,37318,37320,37323,37328,37330,37331,37332,37333, -37334,37335,37336,37337,37338,37339,37341,37342,37343,37344,37345,37346,37347, -37348,37349,37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360, -37361,37362,37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373, -37374,37375,37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386, -37387,37388,37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399, -37400,37401,37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412, -U,37413,37414,37415,37416,37417,37418,37419,37420,37421,37422,37423,37424, -37425,37426,37427,37428,37429,37430,37431,37432,37433,37434,37435,37436,37437, -37438,37439,37440,37441,37442,37443,37444,37445,37446,37447,37448,37449,37450, -37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463, -37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476, -37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489, -37490,37491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503, -37504,37505,37506,37507,37508,37509,U,37510,37511,37512,37513,37514,37515, -37516,37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529, -37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542, -37543,37544,37545,37546,37547,37548,37549,37551,37552,37553,37554,37555,37556, -37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,37568,37569, -37570,37571,37572,37573,37574,37575,37577,37578,37579,37580,37581,37582,37583, -37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,37595,37596, -37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,37608,U, -37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,37621, -37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,37634, -37635,37636,37637,37638,37639,37640,37641,37642,37643,37644,37645,37646,37647, -37648,37649,37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660, -37661,37662,37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673, -37674,37675,37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686, -37687,37688,37689,37690,37691,37692,37693,37695,37696,37697,37698,37699,37700, -37701,37702,37703,37704,37705,U,37706,37707,37708,37709,37710,37711,37712, -37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,37723,37724,37725, -37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,37736,37737,37739, -37740,37741,37742,37743,37744,37745,37746,37747,37748,37749,37750,37751,37752, -37753,37754,37755,37756,37757,37758,37759,37760,37761,37762,37763,37764,37765, -37766,37767,37768,37769,37770,37771,37772,37773,37774,37776,37777,37778,37779, -37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792, -37793,37794,37795,37796,37797,37798,37799,37800,37801,37802,37803,U,37804, -37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,37815,37816,37817, -37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,37828,37829,37830, -37831,37832,37833,37835,37836,37837,37838,37839,37840,37841,37842,37843,37844, -37845,37847,37848,37849,37850,37851,37852,37853,37854,37855,37856,37857,37858, -37859,37860,37861,37862,37863,37864,37865,37866,37867,37868,37869,37870,37871, -37872,37873,37874,37875,37876,37877,37878,37879,37880,37881,37882,37883,37884, -37885,37886,37887,37888,37889,37890,37891,37892,37893,37894,37895,37896,37897, -37898,37899,37900,37901,U,37902,37903,37904,37905,37906,37907,37908,37909, -37910,37911,37912,37913,37914,37915,37916,37917,37918,37919,37920,37921,37922, -37923,37924,37925,37926,37927,37928,37929,37930,37931,37932,37933,37934,37935, -37936,37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948, -37949,37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962, -37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975, -37976,37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988, -37989,37990,37991,37992,37993,37994,37996,37997,37998,37999,U,38000,38001, -38002,38003,38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014, -38015,38016,38017,38018,38019,38020,38033,38038,38040,38087,38095,38099,38100, -38106,38118,38139,38172,38176,38183,38195,38205,38211,38216,38219,38229,38234, -38240,38254,38260,38261,38263,38264,38265,38266,38267,38268,38269,38270,38272, -38273,38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285, -38286,38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298, -38299,38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311, -38312,38313,38314,U,38315,38316,38317,38318,38319,38320,38321,38322,38323, -38324,38325,38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336, -38337,38338,38339,38340,38341,38342,38343,38344,38345,38346,38347,38348,38349, -38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,38362, -38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375, -38380,38399,38407,38419,38424,38427,38430,38432,38435,38436,38437,38438,38439, -38440,38441,38443,38444,38445,38447,38448,38455,38456,38457,38458,38462,38465, -38467,38474,38478,38479,38481,38482,38483,38486,38487,U,38488,38489,38490, -38492,38493,38494,38496,38499,38501,38502,38507,38509,38510,38511,38512,38513, -38515,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531, -38532,38535,38537,38538,38540,38542,38545,38546,38547,38549,38550,38554,38555, -38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38568,38569,38570, -38571,38572,38573,38574,38575,38577,38578,38580,38581,38583,38584,38586,38587, -38591,38594,38595,38600,38602,38603,38608,38609,38611,38612,38614,38615,38616, -38617,38618,38619,38620,38621,38622,38623,38625,38626,38627,38628,38629,38630, -38631,38635,U,38636,38637,38638,38640,38641,38642,38644,38645,38648,38650, -38651,38652,38653,38655,38658,38659,38661,38666,38667,38668,38672,38673,38674, -38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,38689,38690,38691, -38692,38693,38694,38695,38696,38697,38699,38700,38702,38703,38705,38707,38708, -38709,38710,38711,38714,38715,38716,38717,38719,38720,38721,38722,38723,38724, -38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737, -38740,38741,38743,38744,38746,38748,38749,38751,38755,38756,38758,38759,38760, -38762,38763,38764,38765,38766,38767,38768,38769,U,38770,38773,38775,38776, -38777,38778,38779,38781,38782,38783,38784,38785,38786,38787,38788,38790,38791, -38792,38793,38794,38796,38798,38799,38800,38803,38805,38806,38807,38809,38810, -38811,38812,38813,38814,38815,38817,38818,38820,38821,38822,38823,38824,38825, -38826,38828,38830,38832,38833,38835,38837,38838,38839,38840,38841,38842,38843, -38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856, -38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869, -38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882, -38883,U,38884,38885,38888,38894,38895,38896,38897,38898,38900,38903,38904, -38905,38906,38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917, -38918,38919,38920,38921,38922,38923,38924,38925,38926,38927,38928,38929,38930, -38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,38943, -38944,38945,38946,38947,38948,38949,38950,38951,38952,38953,38954,38955,38956, -38957,38958,38959,38960,38961,38962,38963,38964,38965,38966,38967,38968,38969, -38970,38971,38972,38973,38974,38975,38976,38977,38978,38979,38980,38981,38982, -38983,38984,38985,38986,38987,38988,38989,U,38990,38991,38992,38993,38994, -38995,38996,38997,38998,38999,39000,39001,39002,39003,39004,39005,39006,39007, -39008,39009,39010,39011,39012,39013,39014,39015,39016,39017,39018,39019,39020, -39021,39022,39023,39024,39025,39026,39027,39028,39051,39054,39058,39061,39065, -39075,39080,39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091, -39092,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104, -39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117, -39119,39120,39124,39126,39127,39131,39132,39133,39136,39137,39138,39139,39140, -U,39141,39142,39145,39146,39147,39148,39149,39150,39151,39152,39153,39154, -39155,39156,39157,39158,39159,39160,39161,39162,39163,39164,39165,39166,39167, -39168,39169,39170,39171,39172,39173,39174,39175,39176,39177,39178,39179,39180, -39182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195, -39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208, -39209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222, -39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235, -39236,39237,39238,39239,39240,39241,U,39242,39243,39244,39245,39246,39247, -39248,39249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262, -39263,39264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299, -39305,39308,39310,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331, -39332,39334,39335,39337,39338,39339,39340,39341,39342,39343,39344,39345,39346, -39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,39358,39359, -39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,39371,39372, -39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,39384,U, -39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,39397, -39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,39410, -39411,39412,39413,39414,39415,39416,39417,39418,39419,39420,39421,39422,39423, -39424,39425,39426,39427,39428,39429,39430,39431,39432,39433,39434,39435,39436, -39437,39438,39439,39440,39441,39442,39443,39444,39445,39446,39447,39448,39449, -39450,39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462, -39463,39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475, -39476,39477,39478,39479,39480,U,39481,39482,39483,39484,39485,39486,39487, -39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500, -39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513, -39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,39526, -39527,39528,39529,39530,39531,39538,39555,39561,39565,39566,39572,39573,39577, -39590,39593,39594,39595,39596,39597,39598,39599,39602,39603,39604,39605,39609, -39611,39613,39614,39615,39619,39620,39622,39623,39624,39625,39626,39629,39630, -39631,39632,39634,39636,39637,39638,39639,39641,39642,39643,39644,U,39645, -39646,39648,39650,39651,39652,39653,39655,39656,39657,39658,39660,39662,39664, -39665,39666,39667,39668,39669,39670,39671,39672,39674,39676,39677,39678,39679, -39680,39681,39682,39684,39685,39686,39687,39689,39690,39691,39692,39693,39694, -39696,39697,39698,39700,39701,39702,39703,39704,39705,39706,39707,39708,39709, -39710,39712,39713,39714,39716,39717,39718,39719,39720,39721,39722,39723,39724, -39725,39726,39728,39729,39731,39732,39733,39734,39735,39736,39737,39738,39741, -39742,39743,39744,39750,39754,39755,39756,39758,39760,39762,39763,39765,39766, -39767,39768,39769,39770,U,39771,39772,39773,39774,39775,39776,39777,39778, -39779,39780,39781,39782,39783,39784,39785,39786,39787,39788,39789,39790,39791, -39792,39793,39794,39795,39796,39797,39798,39799,39800,39801,39802,39803,39804, -39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817, -39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830, -39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843, -39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856, -39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,U,39867,39868, -39869,39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881, -39882,39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894, -39895,39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907, -39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920, -39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933, -39934,39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946, -39947,39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959, -39960,39961,39962,U,39963,39964,39965,39966,39967,39968,39969,39970,39971, -39972,39973,39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984, -39985,39986,39987,39988,39989,39990,39991,39992,39993,39994,39995,39996,39997, -39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,40010, -40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,40023, -40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,40036, -40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,40049, -40050,40051,40052,40053,40054,40055,40056,40057,40058,U,40059,40061,40062, -40064,40067,40068,40073,40074,40076,40079,40083,40086,40087,40088,40089,40093, -40106,40108,40111,40121,40126,40127,40128,40129,40130,40136,40137,40145,40146, -40154,40155,40160,40161,40163,40164,40165,40166,40167,40168,40169,40170,40171, -40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,40184, -40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,40197, -40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,40210, -40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,40223, -40224,40225,U,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235, -40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248, -40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,40259,40260,40261, -40262,40263,40264,40265,40266,40267,40268,40269,40270,40271,40272,40273,40274, -40275,40276,40277,40278,40279,40280,40281,40282,40283,40284,40285,40286,40287, -40288,40289,40290,40291,40292,40293,40294,40295,40296,40297,40298,40299,40300, -40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,40311,40312,40313, -40314,40315,40316,40317,40318,40319,40320,40321,U,40322,40323,40324,40325, -40326,40327,40328,40329,40330,40331,40332,40333,40334,40335,40336,40337,40338, -40339,40340,40341,40342,40343,40344,40345,40346,40347,40348,40349,40350,40351, -40352,40353,40354,40355,40356,40357,40358,40359,40360,40361,40362,40363,40364, -40365,40366,40367,40368,40369,40370,40371,40372,40373,40374,40375,40376,40377, -40378,40379,40380,40381,40382,40383,40384,40385,40386,40387,40388,40389,40390, -40391,40392,40393,40394,40395,40396,40397,40398,40399,40400,40401,40402,40403, -40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416, -40417,U,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428, -40429,40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441, -40442,40443,40444,40445,40446,40447,40448,40449,40450,40451,40452,40453,40454, -40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,40466,40467, -40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,40484,40487, -40494,40496,40500,40507,40508,40512,40525,40528,40530,40531,40532,40534,40537, -40541,40543,40544,40545,40546,40549,40558,40559,40562,40564,40565,40566,40567, -40568,40569,40570,40571,40572,40573,40576,U,40577,40579,40580,40581,40582, -40585,40586,40588,40589,40590,40591,40592,40593,40596,40597,40598,40599,40600, -40601,40602,40603,40604,40606,40608,40609,40610,40611,40612,40613,40615,40616, -40617,40618,40619,40620,40621,40622,40623,40624,40625,40626,40627,40629,40630, -40631,40633,40634,40636,40639,40640,40641,40642,40643,40645,40646,40647,40648, -40650,40651,40652,40656,40658,40659,40661,40662,40663,40665,40666,40670,40673, -40675,40676,40678,40680,40683,40684,40685,40686,40688,40689,40690,40691,40692, -40693,40694,40695,40696,40698,40701,40703,40704,40705,40706,40707,40708,40709, -U,40710,40711,40712,40713,40714,40716,40719,40721,40722,40724,40725,40726, -40728,40730,40731,40732,40733,40734,40735,40737,40739,40740,40741,40742,40743, -40744,40745,40746,40747,40749,40750,40752,40753,40754,40755,40756,40757,40758, -40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,40777, -40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,40792, -40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805, -40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818, -40819,40820,40821,40822,40823,40824,U,40825,40826,40827,40828,40829,40830, -40833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855, -40856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975, -63985,64012,64013,64014,64015,64017,64019,64020,64024,64031,64032,64033,64035, -64036,64039,64040,64041, -}; - -static const struct dbcs_index gbkext_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{__gbkext_decmap+0,64,254},{__gbkext_decmap+191,64, -254},{__gbkext_decmap+382,64,254},{__gbkext_decmap+573,64,254},{ -__gbkext_decmap+764,64,254},{__gbkext_decmap+955,64,254},{__gbkext_decmap+1146 -,64,254},{__gbkext_decmap+1337,64,254},{__gbkext_decmap+1528,64,254},{ -__gbkext_decmap+1719,64,254},{__gbkext_decmap+1910,64,254},{__gbkext_decmap+ -2101,64,254},{__gbkext_decmap+2292,64,254},{__gbkext_decmap+2483,64,254},{ -__gbkext_decmap+2674,64,254},{__gbkext_decmap+2865,64,254},{__gbkext_decmap+ -3056,64,254},{__gbkext_decmap+3247,64,254},{__gbkext_decmap+3438,64,254},{ -__gbkext_decmap+3629,64,254},{__gbkext_decmap+3820,64,254},{__gbkext_decmap+ -4011,64,254},{__gbkext_decmap+4202,64,254},{__gbkext_decmap+4393,64,254},{ -__gbkext_decmap+4584,64,254},{__gbkext_decmap+4775,64,254},{__gbkext_decmap+ -4966,64,254},{__gbkext_decmap+5157,64,254},{__gbkext_decmap+5348,64,254},{ -__gbkext_decmap+5539,64,254},{__gbkext_decmap+5730,64,254},{__gbkext_decmap+ -5921,64,254},{__gbkext_decmap+6112,164,170},{__gbkext_decmap+6119,161,170},{0, -0,0},{0,0,0},{0,0,0},{__gbkext_decmap+6129,224,245},{0,0,0},{__gbkext_decmap+ -6151,64,192},{__gbkext_decmap+6280,64,150},{__gbkext_decmap+6367,64,160},{ -__gbkext_decmap+6464,64,160},{__gbkext_decmap+6561,64,160},{__gbkext_decmap+ -6658,64,160},{__gbkext_decmap+6755,64,160},{__gbkext_decmap+6852,64,160},{ -__gbkext_decmap+6949,64,160},{__gbkext_decmap+7046,64,160},{__gbkext_decmap+ -7143,64,160},{__gbkext_decmap+7240,64,160},{__gbkext_decmap+7337,64,160},{ -__gbkext_decmap+7434,64,160},{__gbkext_decmap+7531,64,160},{__gbkext_decmap+ -7628,64,160},{__gbkext_decmap+7725,64,160},{__gbkext_decmap+7822,64,160},{ -__gbkext_decmap+7919,64,160},{__gbkext_decmap+8016,64,160},{__gbkext_decmap+ -8113,64,160},{__gbkext_decmap+8210,64,160},{__gbkext_decmap+8307,64,160},{ -__gbkext_decmap+8404,64,160},{__gbkext_decmap+8501,64,160},{__gbkext_decmap+ -8598,64,160},{__gbkext_decmap+8695,64,160},{__gbkext_decmap+8792,64,160},{ -__gbkext_decmap+8889,64,160},{__gbkext_decmap+8986,64,160},{__gbkext_decmap+ -9083,64,160},{__gbkext_decmap+9180,64,160},{__gbkext_decmap+9277,64,160},{ -__gbkext_decmap+9374,64,160},{__gbkext_decmap+9471,64,160},{__gbkext_decmap+ -9568,64,160},{__gbkext_decmap+9665,64,160},{__gbkext_decmap+9762,64,160},{ -__gbkext_decmap+9859,64,160},{__gbkext_decmap+9956,64,160},{__gbkext_decmap+ -10053,64,160},{__gbkext_decmap+10150,64,160},{__gbkext_decmap+10247,64,160},{ -__gbkext_decmap+10344,64,160},{__gbkext_decmap+10441,64,160},{__gbkext_decmap+ -10538,64,160},{__gbkext_decmap+10635,64,160},{__gbkext_decmap+10732,64,160},{ -__gbkext_decmap+10829,64,160},{__gbkext_decmap+10926,64,160},{__gbkext_decmap+ -11023,64,160},{__gbkext_decmap+11120,64,160},{__gbkext_decmap+11217,64,160},{ -__gbkext_decmap+11314,64,160},{__gbkext_decmap+11411,64,160},{__gbkext_decmap+ -11508,64,160},{__gbkext_decmap+11605,64,160},{__gbkext_decmap+11702,64,160},{ -__gbkext_decmap+11799,64,160},{__gbkext_decmap+11896,64,160},{__gbkext_decmap+ -11993,64,160},{__gbkext_decmap+12090,64,160},{__gbkext_decmap+12187,64,160},{ -__gbkext_decmap+12284,64,160},{__gbkext_decmap+12381,64,160},{__gbkext_decmap+ -12478,64,160},{__gbkext_decmap+12575,64,160},{__gbkext_decmap+12672,64,160},{ -__gbkext_decmap+12769,64,160},{__gbkext_decmap+12866,64,160},{__gbkext_decmap+ -12963,64,160},{__gbkext_decmap+13060,64,160},{__gbkext_decmap+13157,64,160},{ -__gbkext_decmap+13254,64,160},{__gbkext_decmap+13351,64,160},{__gbkext_decmap+ -13448,64,160},{__gbkext_decmap+13545,64,160},{__gbkext_decmap+13642,64,160},{ -__gbkext_decmap+13739,64,160},{__gbkext_decmap+13836,64,160},{__gbkext_decmap+ -13933,64,160},{__gbkext_decmap+14030,64,160},{__gbkext_decmap+14127,64,160},{ -__gbkext_decmap+14224,64,160},{__gbkext_decmap+14321,64,160},{__gbkext_decmap+ -14418,64,160},{__gbkext_decmap+14515,64,79},{0,0,0}, -}; - -static const DBCHAR __gbcommon_encmap[23231] = { -8552,N,N,8556,8487,N,N,N,N,N,N,N,8547,8512,N,N,N,N,N,41380,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8513,N,N,N,N,N,N,N,N,10276,10274, -N,N,N,N,N,N,10280,10278,10298,N,10284,10282,N,N,N,N,10288,10286,N,N,N,8514,N, -10292,10290,N,10297,10273,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10277,N,N,N,N,N,N, -N,10279,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,43197,N,N,N,43198,N,N,N,N,10285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,10289,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10275, -N,10283,N,10287,N,10291,N,10293,N,10294,N,10295,N,10296,43195,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,43200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8486,N,8485, -43072,43073,N,N,N,N,N,N,N,N,N,N,N,N,N,43074,9761,9762,9763,9764,9765,9766, -9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,N,9778,9779,9780,9781, -9782,9783,9784,N,N,N,N,N,N,N,9793,9794,9795,9796,9797,9798,9799,9800,9801, -9802,9803,9804,9805,9806,9807,9808,9809,N,9810,9811,9812,9813,9814,9815,9816, -10023,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10017,10018,10019,10020,10021,10022,10024, -10025,10026,10027,10028,10029,10030,10031,10032,10033,10034,10035,10036,10037, -10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,10049,10065, -10066,10067,10068,10069,10070,10072,10073,10074,10075,10076,10077,10078,10079, -10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,10092, -10093,10094,10095,10096,10097,N,10071,43356,N,N,43075,41386,8490,8492,N,8494, -8495,N,N,8496,8497,N,N,N,N,N,N,N,43077,8493,N,N,N,N,N,N,N,N,N,8555,N,8548, -8549,N,43078,N,N,N,N,N,8569,8550,N,43079,N,N,N,43080,N,N,N,N,N,N,N,N,N,N,N,N, -8557,N,N,N,N,N,N,N,N,N,N,43353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -8817,8818,8819,8820,8821,8822,8823,8824,8825,8826,8827,8828,N,N,N,N,41633, -41634,41635,41636,41637,41638,41639,41640,41641,41642,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,8571,8572,8570,8573,N,N,43081,43082,43083,43084,8522,N,N, -N,N,N,N,8519,N,8518,N,N,N,43085,N,N,N,N,8524,N,N,8536,8542,43086,8527,N,N, -43087,N,8526,N,8516,8517,8521,8520,8530,N,N,8531,N,N,N,N,N,8544,8543,8515, -8523,N,N,N,N,N,8535,N,N,N,N,N,N,N,N,N,N,8534,N,N,N,8533,N,N,N,N,N,43088,N,N,N, -N,N,N,N,N,N,N,N,N,N,8537,8532,N,N,8540,8541,43089,43090,N,N,N,N,N,N,8538,8539, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -43154,N,N,N,8529,N,N,N,N,N,N,N,N,N,N,N,8525,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,43091,8528,8793,8794,8795,8796,8797,8798,8799,8800,8801,8802, -N,N,N,N,N,N,N,N,N,N,8773,8774,8775,8776,8777,8778,8779,8780,8781,8782,8783, -8784,8785,8786,8787,8788,8789,8790,8791,8792,8753,8754,8755,8756,8757,8758, -8759,8760,8761,8762,8763,8764,8765,8766,8767,8768,8769,8770,8771,8772,10532, -10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543,10544,10545, -10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557,10558, -10559,10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571, -10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584, -10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597, -10598,10599,10600,10601,10602,10603,10604,10605,10606,10607,N,N,N,N,43092, -43093,43094,43095,43096,43097,43098,43099,43100,43101,43102,43103,43104,43105, -43106,43107,43108,43109,43110,43111,43112,43113,43114,43115,43116,43117,43118, -43119,43120,43121,43122,43123,43124,43125,43126,43127,N,N,N,N,N,N,N,N,N,N,N,N, -N,43128,43129,43130,43131,43132,43133,43134,43136,43137,43138,43139,43140, -43141,43142,43143,N,N,N,43144,43145,43146,N,N,N,N,N,N,N,N,N,N,8566,8565,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,8568,8567,N,N,N,N,N,N,N,N,43147,43148,N,N,N,N,N,N,N, -N,8564,8563,N,N,N,8560,N,N,8562,8561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -43149,43150,43151,43152,8559,8558,N,N,43153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -8546,N,8545,8481,8482,8483,8488,N,8489,43365,43414,8500,8501,8502,8503,8504, -8505,8506,8507,8510,8511,43155,8574,8498,8499,8508,8509,N,N,N,N,N,43156,43157, -N,N,43328,43329,43330,43331,43332,43333,43334,43335,43336,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258, -9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273, -9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288, -9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303, -9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318, -9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,N,N,N,N,N,N, -N,43361,43362,43366,43367,N,N,9505,9506,9507,9508,9509,9510,9511,9512,9513, -9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528, -9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543, -9544,9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558, -9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573, -9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588, -9589,9590,N,N,N,N,8484,43360,43363,43364,10309,10310,10311,10312,10313,10314, -10315,10316,10317,10318,10319,10320,10321,10322,10323,10324,10325,10326,10327, -10328,10329,10330,10331,10332,10333,10334,10335,10336,10337,10338,10339,10340, -10341,10342,10343,10344,10345,8805,8806,8807,8808,8809,8810,8811,8812,8813, -8814,N,N,N,N,N,N,N,43354,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,43337,43338,43339,N,N,N,N,N,N,N,N,N,N,N,N,43340,43341,43342, -N,N,43343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -43344,N,N,N,N,N,N,N,N,N,43345,N,N,43346,43347,N,N,43348,21051,13857,33088, -18015,33089,33090,33091,19826,21833,18557,18767,20290,22562,12859,21355,33092, -22564,13171,33093,22312,18258,22567,19008,33094,18288,12667,21045,13396,13867, -19263,22569,33095,33096,33097,13866,33098,16701,20815,33099,18725,22573,33100, -14454,20798,25436,22096,33101,33102,14177,33103,13358,33104,16729,33105,22588, -33106,19816,13604,20010,22135,33107,16502,15961,22575,33108,33109,33110,17483, -33111,15939,33112,22577,17204,21093,33113,22062,20058,21799,14965,14118,16470, -33114,17977,17746,18247,33115,14676,33116,13131,21074,33117,33118,22591,15941, -18034,21042,20272,20327,33119,33120,33121,33122,19049,33123,33124,22592,33125, -33126,33127,33128,33129,33130,17010,16978,33131,18537,33132,33133,33134,33135, -33136,33137,33138,33139,33140,33141,18220,33142,33143,33144,33145,33146,33147, -33148,16715,33149,21352,21881,33150,19010,13950,22561,21338,16247,33152,21574, -15141,22593,20069,15918,33153,33154,22568,33155,20807,20521,33156,33157,33158, -22589,22895,19830,16186,33159,15675,14885,21088,12922,14944,17462,33160,20333, -15913,19748,16705,33161,33162,33163,18263,22897,33164,22900,33165,33166,33167, -33168,18507,22633,33169,33170,33171,21082,18994,18506,22636,22634,22598,15734, -17997,13168,33172,22635,15729,15721,33173,18516,13395,33174,33175,16984,33176, -12886,22352,19019,19323,21836,14390,20297,33177,33178,33179,22874,22640,18218, -33180,22638,33181,13434,16750,21076,33182,33183,22637,33184,21063,22639,17223, -33185,33186,33187,20854,33188,22105,22642,33189,22645,15486,15451,33190,33191, -33192,18510,33193,14173,33194,14146,33195,18035,33196,33197,33198,33199,33200, -33201,33202,22648,21057,33203,33204,20073,15423,14204,14117,20573,33205,33206, -33207,33208,33209,22106,21317,15215,15201,22641,33210,33211,18721,20016,13355, -33212,22643,33213,18763,22646,16983,22647,33214,33215,20017,22649,33216,33217, -33218,12846,14656,33219,22819,33220,12393,33221,16742,33222,18796,33223,19269, -33224,19270,22820,33225,33226,33227,33228,33229,13672,33230,33231,13611,33232, -33233,33234,33235,33236,33237,20027,13645,22305,22388,21331,33238,19557,33239, -14926,33240,22818,22876,21344,22653,14192,22391,22654,22650,22817,17507,33241, -33242,21302,22644,22877,33243,22651,33244,17765,33245,33246,16464,33247,33248, -20848,12379,33249,33250,15441,22822,33251,22821,33252,33253,33254,33255,22828, -22830,33256,22827,19001,33257,33258,33259,22825,22070,33260,33261,33262,13150, -22824,33263,16509,33264,19020,33265,22826,33266,22823,33267,33268,22832,33269, -33270,13873,33271,33272,33273,14633,33274,21056,33275,33276,20288,33277,33278, -16962,33344,15684,21868,12896,18248,16235,22829,33345,22831,33346,20074,14958, -33347,33348,33349,33350,33351,18262,33352,33353,33354,33355,33356,33357,33358, -33359,33360,12643,33361,33362,33363,13401,13933,22836,33364,33365,33366,33367, -16161,33368,33369,33370,22878,18254,16510,22840,33371,33372,33373,33374,33375, -19287,14205,33376,22837,33377,22839,12579,21345,22841,33378,20549,33379,22838, -33380,33381,22833,33382,22834,16681,22835,33383,33384,15475,20574,14377,33385, -15971,33386,22845,33387,33388,33389,33390,22842,33391,12339,33392,33393,33394, -22850,33395,33396,33397,33398,33399,33400,33401,33402,33403,33404,33405,33406, -33408,22852,12598,33409,22847,33410,33411,13625,33412,15987,33413,33414,33415, -19528,14962,21072,33416,22851,33417,33418,15720,33419,13099,33420,33421,33422, -22853,15979,33423,22854,22843,17503,33424,22846,22849,22848,33425,33426,33427, -33428,33429,33430,33431,33432,33433,33434,33435,21806,33436,22069,33437,18275, -33438,33439,33440,33441,22856,33442,33443,33444,15449,22858,33445,33446,33447, -22844,33448,22859,17963,33449,33450,33451,33452,33453,22857,33454,33455,33456, -33457,22390,33458,19747,33459,33460,33461,33462,33463,33464,33465,33466,15649, -33467,33468,33469,33470,33471,33472,22860,33473,33474,33475,33476,33477,33478, -33479,33480,33481,17724,19765,33482,33483,33484,22861,33485,33486,22855,13093, -16254,33487,33488,33489,33490,14389,33491,33492,16508,33493,33494,33495,33496, -12408,33497,33498,33499,33500,33501,33502,33503,33504,33505,33506,33507,33508, -33509,33510,33511,33512,33513,33514,33515,33516,33517,13430,33518,22862,33519, -22863,13346,22864,33520,33521,13407,33522,33523,33524,33525,33526,12353,33527, -33528,33529,33530,33531,33532,33533,22865,18741,33534,33600,33601,33602,33603, -33604,33605,33606,33607,33608,33609,33610,33611,33612,33613,33614,33615,33616, -33617,20337,33618,33619,33620,33621,33622,33623,22866,33624,33625,33626,16709, -33627,33628,33629,33630,33631,33632,33633,33634,33635,33636,33637,22870,18734, -33638,33639,33640,33641,22869,22868,22871,33642,33643,33644,33645,19291,33646, -15657,33647,33648,33649,33650,33651,17959,33652,33653,33654,33655,33656,33657, -33658,33659,33660,33661,22867,22872,33662,33664,33665,22873,33666,33667,33668, -33669,33670,33671,18533,33672,33673,33674,33675,33676,33677,33678,33679,33680, -33681,33682,33683,33684,33685,16476,33686,33687,33688,33689,33690,33691,33692, -33693,33694,33695,33696,33697,33698,33699,33700,33701,33702,33703,33704,33705, -33706,33707,33708,33709,33710,33711,33712,33713,33714,13945,22563,21578,33715, -21546,20566,13156,21847,33716,20296,14690,33717,16203,33718,17250,33719,33720, -33721,13906,33722,33723,19779,22894,22896,33724,33725,33726,13619,33727,13877, -33728,33729,33730,33731,33732,15908,33733,33734,18539,33735,33736,18475,33737, -33738,12363,14635,16761,22882,33739,16444,14642,33740,14680,20555,12664,18020, -15967,13668,22344,33741,20856,15462,19038,33742,33743,15421,22886,22631,33744, -33745,17498,33746,33747,14420,18493,33748,33749,12897,21593,33750,33751,33752, -33753,17200,33754,33755,17249,23074,18527,33756,20532,33757,15996,17705,33758, -33759,33760,14682,33761,23075,33762,21545,23076,33763,33764,33765,33766,33767, -22907,13868,33768,33769,14187,12665,22908,13157,15990,33770,16246,21041,16484, -33771,33772,33773,13875,22910,22909,33774,33775,15931,33776,33777,33778,18016, -33779,22332,23073,33780,16697,33781,13682,16744,33782,33783,15477,33784,13397, -33785,33786,33787,33788,33789,33790,33856,33857,33858,16733,33859,17533,33860, -33861,15416,14130,33862,33863,14191,33864,33865,33866,33867,33868,33869,22892, -33870,17982,33871,16173,15179,33872,33873,13642,33874,23369,20567,33875,19769, -12348,13174,15223,23370,14895,33876,21604,13622,13683,22614,18512,33877,33878, -14166,18256,22615,33879,16175,33880,33881,23355,22616,33882,33883,20556,15150, -33884,33885,33886,27454,16720,16757,21618,14421,13364,33887,13173,33888,33889, -18750,33890,33891,33892,17744,33893,33894,33895,17753,16507,33896,12656,33897, -22617,14670,33898,13629,33899,33900,22618,33901,33902,22086,19234,18479,18738, -13388,16204,33903,14708,33904,22619,22620,13927,15425,19562,33905,33906,33907, -33908,33909,33910,20343,33911,22621,18224,33912,33913,14672,15651,33914,33915, -19550,33916,17994,33917,33918,33920,33921,33922,22624,33923,22622,33924,33925, -22623,33926,33927,33928,12414,33929,15975,33930,18979,15476,33931,33932,33933, -33934,14385,33935,33936,14446,33937,33938,33939,33940,33941,33942,33943,33944, -33945,33946,22626,33947,15691,33948,22628,22627,33949,33950,33951,33952,33953, -17788,33954,33955,33956,33957,33958,33959,33960,22629,33961,33962,22630,33963, -33964,33965,33966,33967,33968,33969,16678,33970,18480,12396,14630,15443,20081, -23357,16723,33971,33972,33973,33974,13871,22138,17708,15705,23358,23359,33975, -33976,33977,16504,15906,16461,33978,33979,33980,33981,33982,33983,33984,33985, -33986,33987,23360,19014,33988,33989,33990,12842,33991,33992,33993,21314,33994, -17251,33995,20779,33996,33997,33998,33999,23362,34000,16469,34001,34002,34003, -23363,34004,16177,34005,34006,34007,34008,34009,34010,17468,34011,34012,34013, -34014,18266,34015,34016,34017,34018,34019,34020,34021,34022,34023,34024,34025, -23364,34026,34027,34028,34029,34030,34031,34032,34033,22888,18775,34034,34035, -34036,14644,20080,21576,34037,34038,34039,34040,12412,13394,34041,20569,34042, -34043,34044,34045,22889,34046,24139,22891,34112,34113,34114,34115,22576,15151, -12593,34116,13143,22606,34117,34118,21585,34119,34120,15667,16239,34121,20283, -34122,34123,22608,34124,34125,34126,14155,34127,34128,34129,22609,34130,34131, -34132,34133,34134,34135,34136,34137,34138,34139,17957,18296,21053,34140,34141, -22610,17508,34142,18990,34143,18215,34144,22566,34145,18813,20071,15196,12395, -34146,34147,34148,15146,20525,34149,12592,22372,22335,34150,13605,17012,17487, -34151,34152,12841,34153,12855,34154,12645,24370,21820,16168,16940,22613,16945, -34155,22612,20052,34156,23136,34157,20032,34158,34159,22580,17198,21281,20003, -34160,15412,18484,16977,34161,15981,20534,34162,23137,34163,34164,34165,34166, -18276,34167,34168,13095,34169,13938,19580,16506,34170,34171,16503,34172,20793, -20833,22599,34173,34174,34176,34177,34178,34179,34180,12894,34181,34182,16485, -34183,14961,34184,34185,22600,34186,21549,34187,34188,20321,22601,34189,22602, -20291,34190,13176,15943,34191,34192,34193,34194,22603,34195,34196,34197,34198, -34199,34200,34201,23372,34202,34203,34204,34205,18469,34206,34207,34208,20312, -34209,18558,12878,34210,34211,34212,34213,34214,21334,12902,15408,21329,19243, -14132,34215,34216,34217,14114,34218,34219,19045,34220,18465,19036,12644,20592, -34221,17745,34222,34223,34224,23365,13694,34225,34226,16218,14661,15972,16749, -34227,24374,24373,22075,15696,21849,12360,13859,16201,19496,24371,18999,21330, -34228,22607,21046,14917,19262,19518,34229,24375,13680,24372,34230,34231,34232, -21365,34233,13140,14455,34234,24378,34235,14927,15402,13685,34236,19756,17275, -14963,16500,19778,20338,24376,20293,34237,16960,24377,17008,34238,34239,34240, -15997,34241,16735,19788,21111,14157,24385,34242,24388,34243,34244,14193,12361, -13910,14164,34245,14892,19581,16212,19249,18036,34246,22056,24389,34247,20066, -13107,34248,34249,20092,13365,34250,20039,14960,34251,20065,34252,20797,34253, -34254,24384,34255,34256,13428,34257,13130,34258,14438,24379,34259,34260,34261, -34262,17477,34263,24380,24381,24382,17723,24383,24386,21553,24387,34264,18234, -20056,34265,34266,34267,34268,34269,17496,34270,24394,34271,24399,34272,22108, -34273,34274,34275,34276,34277,34278,34279,34280,24393,24410,20022,34281,14919, -24398,24392,17758,34282,34283,18795,14964,17276,34284,34285,15959,34286,24390, -34287,24397,34288,17752,34289,34290,34291,34292,21798,14925,34293,15948,21309, -14400,34294,22116,34295,24391,14654,16167,34296,34297,16764,24395,24396,34298, -24400,34299,34300,34301,34302,34368,24411,24421,34369,24407,24406,22345,24419, -24420,25963,21031,24402,34370,16169,34371,21595,34372,16200,24404,34373,34374, -34375,20300,34376,34377,24413,34378,20810,34379,24414,12327,17975,24403,34380, -14949,34381,13919,19803,14718,21589,34382,34383,24415,20332,12325,24423,24401, -20806,24405,24408,24409,24412,34384,15145,34385,24416,24417,34386,24418,24422, -24424,21300,34387,34388,34389,34390,34391,14439,17718,24426,18778,16680,17476, -34392,34393,16222,20344,34394,34395,34396,21852,24430,34397,34398,34399,34400, -34401,34402,12856,34403,14943,24428,34404,23361,34405,20836,34406,34407,34408, -34409,19316,13373,34410,12326,34411,34412,34413,34414,34415,24433,19526,24434, -34416,34417,24429,34418,34419,34420,34421,34422,34423,24425,34424,34425,34426, -34427,24427,34428,24431,24432,15165,34429,34430,24435,34432,34433,24436,34434, -15139,34435,19035,20008,24615,13098,34436,24614,34437,34438,34439,24609,34440, -34441,34442,34443,24446,34444,19801,24444,34445,24442,34446,16208,22340,34447, -18764,34448,34449,24440,12321,34450,34451,34452,34453,34454,24445,34455,34456, -34457,34458,24443,24610,34459,34460,34461,34462,34463,24616,34464,34465,34466, -34467,14152,34468,34469,17953,18742,16434,24437,34470,34471,17726,34472,22596, -24441,17526,34473,34474,34475,34476,34477,34478,24611,24612,24613,20517,34479, -34480,24628,19556,34481,24625,34482,16166,24623,20025,24619,18758,34483,34484, -16430,24622,14957,14896,24617,34485,34486,34487,24438,34488,24627,34489,34490, -24632,34491,34492,34493,13357,24633,34494,34495,20274,14920,34496,24624,34497, -34498,34499,34500,34501,34502,34503,20602,34504,34505,34506,34507,34508,34509, -34510,34511,34512,24620,34513,21627,34514,24439,34515,17767,34516,24621,34517, -21367,34518,24630,24631,34519,34520,34521,34522,34523,24644,20577,34524,34525, -34526,24636,34527,34528,24649,24650,34529,34530,34531,24638,24618,18724,24641, -34532,24626,34533,34534,34535,34536,34537,19016,24643,34538,24629,34539,20043, -34540,19267,24653,24646,24642,34541,24651,34542,24634,24639,24640,34543,34544, -24645,34545,34546,24647,24648,34547,24652,34548,24635,34549,34550,34551,34552, -34553,19284,24661,34554,24662,24658,34555,34556,34557,34558,34624,34625,24656, -15438,34626,34627,24657,34628,14402,22597,34629,34630,34631,34632,34633,34634, -34635,34636,20586,34637,34638,17007,34639,34640,24655,24637,34641,34642,34643, -24660,24659,34644,34645,24663,34646,34647,34648,34649,24668,24664,34650,34651, -34652,22134,13104,34653,22380,34654,19259,34655,34656,24666,34657,20091,34658, -34659,34660,14937,34661,34662,34663,34664,34665,34666,34667,34668,34669,34670, -34671,34672,24673,24669,21037,34673,34674,34675,34676,34677,24674,34678,34679, -24667,24665,24671,34680,34681,24672,34682,34683,34684,34685,34686,24670,34688, -24676,34689,34690,34691,18039,22572,21611,24678,19017,34692,34693,34694,34695, -24677,34696,34697,34698,34699,14401,34700,34701,34702,34703,24679,24680,34704, -34705,34706,34707,34708,34709,34710,34711,24681,24675,34712,34713,34714,34715, -34716,34717,34718,14911,19559,34719,34720,34721,24682,34722,34723,34724,34725, -34726,34727,34728,34729,34730,34731,34732,34733,34734,34735,34736,20345,34737, -34738,34739,34740,34741,34742,34743,34744,34745,34746,34747,24683,34748,34749, -34750,34751,34752,34753,34754,18498,34755,34756,34757,34758,15680,34759,34760, -34761,34762,34763,34764,34765,34766,34767,34768,34769,34770,34771,17490,34772, -34773,34774,34775,34776,34777,34778,34779,34780,24684,34781,34782,24685,34783, -34784,18292,19268,34785,24686,15192,22582,21106,24687,19781,34786,13914,34787, -34788,34789,34790,34791,34792,24689,34793,21552,34794,34795,16423,13393,34796, -34797,20007,24688,34798,34799,34800,24690,14668,34801,34802,14714,19772,24691, -34803,34804,34805,18004,24692,34806,21554,34807,18470,24694,24693,34808,34809, -34810,34811,34812,34813,34814,34880,34881,34882,34883,34884,34885,34886,34887, -34888,34889,24695,34890,34891,19777,34892,34893,34894,18981,34895,34896,34897, -34898,21594,23383,23385,34899,23384,14695,23388,23389,13656,34900,34901,23386, -34902,34903,34904,34905,34906,23387,13089,23391,34907,34908,15224,34909,22071, -34910,23392,34911,34912,34913,34914,15993,34915,34916,14139,34917,23376,19502, -16178,15157,22392,16211,34918,34919,34920,34921,34922,16233,34923,34924,15457, -19507,23390,12371,20075,14168,22329,17986,34925,34926,16420,34927,19513,34928, -23399,23393,17978,23395,34929,23400,34930,17783,34931,34932,34933,23402,34934, -34935,23401,16192,34936,34937,34938,23398,23397,34939,34940,34941,34942,34944, -13369,16428,16930,23394,23396,34945,34946,34947,34948,20557,23405,34949,34950, -34951,34952,34953,16477,23410,34954,34955,34956,34957,34958,34959,34960,13922, -34961,34962,34963,34964,23411,23378,14648,21547,23404,34965,16209,23408,34966, -23377,34967,13670,34968,23403,16229,34969,34970,34971,23406,34972,23409,34973, -34974,34975,23417,34976,34977,34978,34979,34980,34981,34982,34983,34984,14625, -12323,34985,34986,34987,34988,34989,34990,34991,17009,34992,34993,13127,23407, -34994,34995,23416,34996,18002,23412,34997,34998,23413,23415,23414,34999,35000, -23422,35001,21362,12858,35002,35003,35004,23421,35005,35006,35007,35008,35009, -35010,35011,35012,23588,35013,23419,35014,35015,35016,35017,23418,35018,35019, -35020,23420,17760,15225,35021,35022,23587,35023,35024,23589,35025,19523,35026, -35027,35028,13905,23872,35029,35030,35031,23585,35032,23586,35033,35034,35035, -18229,35036,35037,35038,13929,35039,35040,35041,23591,35042,35043,35044,35045, -23590,35046,23593,12580,35047,35048,13644,35049,35050,35051,35052,35053,16176, -35054,35055,35056,35057,35058,20831,35059,35060,35061,35062,13890,35063,35064, -35065,35066,35067,35068,35069,35070,35136,35137,35138,35139,35140,35141,23592, -35142,35143,35144,35145,35146,35147,35148,19322,27507,35149,35150,35151,19292, -35152,35153,19326,35154,35155,35156,19521,35157,35158,35159,35160,35161,18555, -35162,35163,35164,35165,35166,35167,23594,35168,35169,35170,35171,35172,19566, -23595,35173,35174,35175,35176,35177,35178,35179,35180,35181,35182,35183,35184, -35185,35186,35187,35188,35189,23379,35190,23599,23596,35191,15923,35192,19067, -35193,35194,35195,23597,35196,35197,35198,35200,35201,35202,35203,35204,18762, -17465,35205,35206,35207,35208,35209,18237,23598,35210,35211,35212,21622,20582, -35213,35214,35215,35216,35217,35218,35219,35220,17451,13909,35221,35222,35223, -35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,35234,35235,35236, -35237,35238,23380,35239,35240,35241,35242,12634,35243,35244,35245,23381,35246, -35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,23382,35257,35258, -35259,14910,35260,35261,35262,35263,35264,35265,35266,35267,35268,35269,35270, -35271,35272,35273,18496,35274,35275,35276,35277,35278,35279,19007,18505,35280, -22323,35281,18809,35282,35283,16199,35284,35285,14968,35286,35287,21052,35288, -35289,35290,35291,35292,35293,35294,35295,25146,35296,13350,35297,35298,12600, -35299,35300,35301,35302,35303,14388,35304,20292,35305,35306,35307,35308,22887, -20262,19810,35309,35310,22893,13920,35311,21049,35312,35313,14651,35314,35315, -35316,35317,25145,25143,35318,13427,35319,19564,19499,14194,35320,22578,20843, -14907,35321,18983,35322,35323,19767,35324,35325,21060,16228,15440,13921,35326, -24133,35392,35393,35394,35395,24134,23356,35396,20825,35397,35398,18022,17486, -14190,35399,14172,35400,35401,16252,22368,35402,18037,35403,35404,12604,24136, -15665,19543,24138,35405,24137,35406,35407,35408,35409,35410,13676,35411,18781, -35412,35413,12354,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423, -35424,35425,35426,17710,17707,35427,17484,35428,15465,19325,35429,35430,35431, -14915,35432,35433,35434,25977,18535,25978,19837,35435,22321,14398,17000,35436, -18513,35437,35438,25979,35439,35440,35441,35442,13898,15435,35443,35444,20861, -26145,35445,17262,35446,35447,35448,35449,26148,35450,35451,35452,35453,25982, -26149,19799,35454,35456,14145,25980,25981,26147,35457,35458,17501,26152,35459, -35460,26151,35461,35462,35463,35464,35465,35466,17219,35467,18014,35468,35469, -26154,35470,35471,35472,35473,35474,35475,35476,17463,35477,35478,35479,26146, -19004,35480,35481,35482,35483,15715,14659,26150,20565,20015,35484,35485,26153, -26160,35486,21030,35487,15658,26157,35488,35489,35490,35491,35492,26159,35493, -16465,35494,35495,21068,35496,35497,35498,15399,35499,35500,35501,35502,35503, -35504,35505,35506,35507,35508,35509,35510,26161,35511,21110,35512,35513,35514, -22347,35515,19838,35516,19806,16934,26155,26156,15679,26158,26163,35517,35518, -26162,35519,35520,35521,35522,26166,35523,26168,35524,35525,35526,35527,17519, -35528,35529,35530,17480,35531,35532,15978,18799,35533,35534,26167,35535,13936, -35536,35537,35538,17252,35539,35540,35541,35542,35543,35544,35545,21353,26164, -35546,26165,35547,18466,35548,35549,35550,35551,35552,26173,35553,35554,35555, -26169,35556,35557,35558,35559,35560,17989,35561,35562,19825,26171,35563,35564, -35565,35566,35567,35568,35569,35570,35571,35572,26172,35573,35574,35575,35576, -15209,35577,35578,35579,35580,35581,35582,35648,26174,35649,35650,35651,35652, -26170,35653,35654,16439,35655,35656,35657,35658,35659,35660,35661,35662,35663, -21284,26175,18804,26179,35664,35665,26180,35666,35667,35668,35669,20598,35670, -35671,35672,35673,35674,35675,35676,35677,35678,35679,35680,35681,35682,35683, -35684,35685,35686,35687,17213,35688,35689,35690,35691,35692,35693,35694,17220, -26178,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706, -35707,35708,26177,35709,35710,35712,35713,35714,35715,35716,26183,20273,35717, -27508,35718,35719,26186,35720,35721,35722,35723,35724,26181,35725,35726,15454, -18729,35727,35728,35729,35730,35731,35732,15413,35733,35734,20307,35735,35736, -35737,35738,35739,26184,35740,26185,35741,26190,35742,26192,35743,35744,35745, -26193,35746,35747,35748,26187,13653,35749,26188,35750,35751,26191,35752,35753, -17499,35754,26182,35755,35756,35757,35758,35759,26189,35760,35761,35762,35763, -35764,35765,35766,35767,35768,35769,35770,35771,35772,35773,35774,35775,35776, -35777,35778,35779,35780,35781,35782,26194,35783,35784,35785,35786,35787,35788, -35789,35790,35791,35792,35793,35794,26196,26195,35795,35796,35797,35798,35799, -35800,35801,35802,35803,35804,35805,35806,35807,35808,35809,35810,35811,35812, -35813,35814,35815,35816,35817,35818,35819,35820,26197,35821,22904,35822,35823, -26198,35824,35825,35826,35827,35828,35829,35830,35831,26199,35832,35833,35834, -35835,35836,35837,35838,35904,35905,35906,35907,35908,35909,35910,35911,22355, -26205,35912,26206,16215,21584,35913,22358,13414,19311,26202,22595,22350,20514, -35914,17231,35915,35916,26207,15422,14658,26203,20775,35917,35918,14882,16975, -35919,22571,35920,35921,35922,19051,25966,35923,26204,35924,14197,35925,35926, -35927,35928,18534,35929,35930,17525,35931,35932,25906,17534,35933,19324,25907, -21804,35934,21358,19032,12338,35935,19278,19818,35936,35937,14954,35938,35939, -35940,25909,35941,25908,35942,22362,14681,22118,13864,19824,21067,12582,18997, -35943,13160,18803,16205,20603,19026,25910,15170,35944,35945,35946,20316,14636, -35947,35948,35949,35950,21591,35951,35952,14886,20839,20348,15442,35953,25911, -18525,35954,35955,35956,16237,12662,19294,35957,35958,15429,35959,15428,21114, -17244,16220,35960,35961,35962,35963,14395,35964,35965,35966,17218,35968,14894, -21538,35969,35970,35971,35972,35973,35974,35975,35976,35977,18270,17455,12908, -35978,14673,35979,35980,25915,16712,35981,35982,21807,35983,35984,35985,35986, -35987,25916,35988,25918,35989,35990,35991,35992,35993,35994,35995,13415,13908, -19266,20784,13628,35996,35997,19033,35998,14178,35999,36000,18788,36001,15659, -36002,36003,20030,22384,36004,36005,36006,36007,20513,36008,18777,36009,36010, -13947,26200,15458,36011,13118,36012,18768,36013,26201,13090,36014,36015,36016, -36017,24140,36018,21320,24141,36019,21026,36020,36021,36022,36023,24142,36024, -36025,36026,36027,15949,36028,36029,24143,36030,36031,36032,18988,21116,13151, -25962,17505,15905,20018,17522,15958,17960,12899,36033,36034,15955,36035,36036, -18300,19563,15724,20061,36037,36038,19002,17985,25964,20540,36039,36040,36041, -21817,36042,36043,36044,25965,36045,36046,36047,36048,19060,36049,19776,16965, -36050,25967,36051,16964,25968,36052,36053,36054,36055,36056,36057,36058,25976, -19789,36059,18749,36060,36061,36062,36063,36064,36065,36066,21081,24872,36067, -36068,36069,36070,21356,36071,19306,18033,36072,36073,36074,36075,36076,24876, -36077,36078,36079,24871,24873,36080,36081,24874,24879,36082,36083,12909,36084, -24875,14426,24877,24878,24880,13626,24881,36085,36086,36087,36088,36089,24883, -24888,36090,36091,36092,36093,36094,20818,36160,24886,24885,16747,36161,36162, -36163,24887,36164,21568,36165,24882,36166,24890,12342,36167,36168,36169,36170, -24884,36171,16249,36172,24889,36173,36174,24891,36175,36176,36177,36178,36179, -36180,24894,36181,36182,36183,36184,36185,36186,24892,36187,36188,36189,36190, -36191,36192,22085,36193,36194,36195,36196,36197,36198,36199,20287,36200,36201, -24893,24895,16973,36202,13931,36203,21368,36204,36205,18253,36206,36207,14181, -36208,36209,36210,36211,36212,36213,36214,36215,36216,36217,15998,36218,36219, -36220,36221,36222,36224,24896,24897,36225,36226,24903,13159,36227,36228,36229, -36230,36231,36232,18025,36233,36234,36235,36236,36237,13406,36238,20802,36239, -36240,36241,36242,24904,36243,36244,24902,36245,36246,36247,36248,36249,24901, -36250,24899,24898,36251,12608,36252,36253,36254,21816,24900,36255,36256,36257, -36258,36259,24907,36260,36261,36262,36263,36264,36265,36266,36267,24908,24906, -36268,36269,36270,36271,36272,36273,36274,36275,28538,36276,36277,24915,24914, -18230,36278,36279,36280,36281,36282,36283,36284,36285,36286,36287,36288,24905, -36289,36290,24910,36291,24912,36292,36293,36294,36295,36296,36297,36298,36299, -36300,36301,36302,24916,36303,24913,24909,36304,36305,24911,36306,36307,36308, -36309,24917,36310,36311,36312,36313,36314,36315,36316,36317,36318,36319,36320, -36321,36322,24918,36323,36324,36325,36326,36327,36328,36329,36330,36331,36332, -36333,36334,36335,36336,36337,36338,36339,36340,36341,36342,36343,36344,24919, -36345,36346,36347,24920,36348,36349,36350,36416,36417,36418,36419,36420,36421, -36422,36423,36424,36425,36426,36427,36428,36429,36430,36431,36432,36433,36434, -36435,36436,36437,24922,36438,36439,36440,36441,36442,36443,36444,36445,36446, -36447,36448,36449,36450,24923,36451,36452,36453,36454,36455,36456,36457,20001, -36458,36459,36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470, -26461,36471,13352,22109,36472,36473,20786,13106,36474,36475,14628,22387,18249, -15966,14638,36476,20055,36477,36478,12910,23375,36480,15418,21073,19272,12365, -36481,36482,20335,36483,36484,36485,36486,36487,22883,15725,36488,36489,12626, -19024,12860,36490,19239,14123,36491,18982,36492,36493,36494,20259,36495,36496, -24696,21834,24699,36497,36498,24698,17729,19579,36499,16689,24697,22115,12847, -22084,13659,36500,36501,36502,36503,36504,36505,36506,36507,13432,22049,36508, -36509,36510,36511,36512,20271,12399,36513,36514,24700,36515,36516,36517,36518, -36519,24865,13091,36520,36521,24701,24702,17201,36522,36523,36524,36525,17245, -36526,24866,14201,36527,36528,36529,36530,36531,36532,15183,36533,36534,36535, -36536,36537,36538,36539,24867,17467,36540,36541,36542,36543,36544,24868,36545, -36546,24869,36547,36548,24870,13361,36549,36550,36551,36552,36553,36554,36555, -36556,36557,36558,36559,36560,36561,36562,36563,14409,17981,17514,36564,12834, -36565,20562,36566,26459,15171,21335,21316,36567,14691,25167,36568,36569,36570, -22319,36571,18284,12627,36572,36573,13362,25169,36574,36575,36576,20594,16942, -25168,36577,16226,21286,13655,25170,13674,36578,17261,14461,36579,14382,36580, -17747,14159,25172,36581,36582,36583,36584,25171,13896,22393,36585,36586,36587, -36588,36589,19749,36590,36591,36592,36593,36594,25176,36595,25174,19068,16181, -21305,25173,36596,36597,36598,36599,25175,36600,36601,36602,36603,36604,36605, -36606,36672,36673,36674,16686,16456,36675,36676,36677,36678,36679,36680,25179, -25178,16426,36681,36682,16718,36683,36684,36685,36686,25180,36687,36688,36689, -36690,36691,36692,36693,36694,36695,36696,36697,36698,25181,36699,25182,36700, -36701,36702,36703,36704,36705,36706,36707,36708,23368,36709,20819,19746,36710, -36711,15656,36712,36713,36714,24131,22565,16170,23373,21100,18042,17706,36715, -36716,36717,24132,36718,12631,24366,36719,36720,36721,19005,36722,24369,36723, -14637,36724,21117,36725,14373,14955,36726,36727,13146,36728,36729,36730,13660, -21829,36731,36732,36733,36734,17238,20306,15137,36736,25971,25970,36737,36738, -25972,36739,19812,36740,18549,36741,36742,36743,36744,36745,36746,36747,13615, -18239,36748,25974,36749,36750,36751,27696,36752,36753,36754,36755,36756,36757, -36758,36759,36760,36761,36762,36763,36764,36765,36766,25958,36767,14697,13617, -36768,16956,25960,25959,25961,36769,36770,36771,36772,21069,36773,36774,36775, -24938,20558,36776,19758,36777,20837,36778,36779,12874,12651,36780,12658,17773, -36781,36782,21827,21296,36783,24924,36784,36785,36786,24925,36787,21083,36788, -13113,12619,36789,36790,36791,19833,21879,24926,36792,15926,13437,36793,24927, -14940,24928,15154,16969,24929,36794,36795,36796,20588,36797,19773,36798,36799, -24930,36800,13635,17735,24931,36801,36802,24932,36803,36804,36805,36806,21369, -36807,36808,36809,36810,36811,36812,24933,36813,20781,36814,36815,24934,20002, -36816,36817,36818,36819,36820,36821,24935,36822,13634,36823,36824,36825,36826, -24936,15189,36827,36828,36829,36830,36831,20548,25184,12632,21092,36832,36833, -25185,36834,36835,15433,18508,36836,25187,27774,27773,24367,36837,36838,36839, -25186,22078,19836,17190,36840,36841,36842,25411,36843,36844,22098,25191,36845, -36846,25192,36847,36848,21319,36849,36850,25196,16236,36851,25197,25189,36852, -36853,13120,36854,36855,36856,17518,36857,36858,25198,36859,36860,20547,36861, -14966,25193,14174,15155,19500,19275,25188,25190,25194,25195,36862,36928,36929, -25207,36930,36931,25204,21621,25203,36932,36933,17709,36934,21882,17730,12864, -36935,36936,25199,36937,25202,16687,19260,36938,36939,13601,25209,36940,36941, -36942,15409,25201,20564,21561,25205,14678,25206,36943,36944,36945,18259,36946, -36947,36948,36949,36950,25200,36951,36952,36953,36954,36955,22364,27937,36956, -36957,25208,36958,27941,25214,19025,36959,36960,36961,36962,36963,36964,36965, -16693,36966,15184,36967,36968,16214,36969,14947,36970,36971,19233,36972,36973, -36974,27942,27939,36975,36976,27938,36977,36978,36979,36980,15190,27943,20596, -36981,36982,27940,14942,13943,25377,13874,19569,14631,36983,20258,18209,36984, -36985,16210,36986,36987,13937,36988,25210,25211,25213,25212,17493,25378,36989, -21313,36990,36992,36993,25383,18244,36994,36995,36996,36997,20260,36998,36999, -25385,14903,37000,37001,37002,37003,25384,37004,15194,37005,25379,37006,37007, -37008,25380,25386,37009,25382,37010,20082,21318,37011,37012,15164,37013,37014, -21571,37015,17530,37016,37017,27944,20604,25381,37018,17269,37019,25389,12591, -37020,25394,37021,37022,37023,15426,37024,37025,25388,13631,37026,37027,37028, -37029,37030,37031,37032,37033,18281,25392,37034,37035,37036,15914,19823,37037, -37038,37039,37040,37041,15219,37042,37043,37044,19560,37045,37046,25391,37047, -25393,37048,20263,25390,37049,20009,15197,37050,37051,37052,37053,37054,13675, -15973,12882,13133,37055,12601,25387,12881,13612,14687,13928,37056,37057,20331, -25399,37058,15180,37059,37060,18503,20554,37061,37062,37063,37064,37065,25400, -13166,37066,37067,37068,37069,27945,37070,21370,21348,37071,37072,37073,27946, -25401,21090,37074,37075,37076,37077,37078,25397,37079,37080,37081,37082,21342, -37083,37084,37085,37086,14416,25395,37087,37088,25398,14175,37089,25396,16418, -37090,37091,37092,25402,37093,37094,37095,37096,37097,37098,37099,37100,37101, -37102,37103,37104,37105,37106,37107,37108,37109,37110,37111,21560,37112,37113, -37114,37115,37116,37117,37118,37184,13384,37185,25403,37186,15173,37187,18807, -37188,37189,18789,37190,37191,37192,17469,37193,37194,37195,37196,37197,37198, -37199,27947,37200,37201,37202,37203,17021,37204,37205,37206,37207,15195,16174, -37208,37209,37210,37211,37212,37213,37214,20031,37215,37216,37217,37218,25404, -37219,16182,37220,37221,37222,37223,37224,37225,37226,37227,37228,37229,37230, -37231,37232,37233,37234,37235,37236,37237,37238,12655,37239,37240,21623,37241, -37242,37243,37244,37245,25406,37246,37248,37249,37250,37251,37252,37253,37254, -27949,37255,37256,37257,37258,37259,37260,37261,37262,37263,25407,14889,27948, -37264,37265,25405,37266,37267,37268,37269,37270,37271,37272,37273,37274,37275, -25408,37276,37277,37278,37279,37280,37281,14902,37282,37283,37284,13870,37285, -37286,37287,37288,37289,20536,37290,12355,27950,37291,37292,37293,37294,37295, -27951,16449,37296,25409,37297,37298,37299,37300,37301,37302,37303,37304,37305, -37306,37307,37308,37309,37310,37311,37312,37313,17715,37314,37315,37316,37317, -37318,37319,37320,37321,37322,37323,37324,37325,37326,37327,25410,37328,37329, -37330,37331,37332,37333,37334,37335,37336,23602,37337,37338,37339,37340,37341, -37342,27952,37343,14442,37344,20076,27175,20583,19065,18518,20279,13129,20050, -15716,37345,37346,25438,15218,27176,21821,37347,18013,27177,37348,37349,37350, -27178,37351,27180,27179,37352,27182,27181,37353,37354,37355,37356,15704,37357, -27183,37358,16958,37359,37360,37361,37362,13377,13431,37363,37364,15143,37365, -37366,37367,37368,37369,27750,27749,14143,19321,12642,37370,27751,37371,37372, -37373,18760,27752,27753,37374,19030,24144,12869,21626,37440,37441,17995,12359, -13426,18515,37442,37443,37444,19792,37445,37446,16184,37447,37448,37449,37450, -37451,37452,37453,16219,37454,37455,18212,22068,37456,16425,24145,18728,20847, -17700,12391,13110,18501,37457,37458,12386,37459,37460,14198,37461,37462,17786, -37463,37464,13939,37465,21842,13136,15420,37466,37467,37468,13101,37469,37470, -37471,37472,15985,12369,37473,37474,37475,37476,37477,37478,21078,19043,22309, -37479,19766,13878,16185,21851,37480,14375,17751,37481,37482,37483,24146,16217, -16981,18240,37484,15140,12584,37485,37486,17770,37487,37488,17787,19495,37489, -37490,37491,37492,12583,37493,37494,37495,13654,37496,37497,37498,17448,37499, -24147,20794,13161,37500,17266,37501,37502,14199,37504,22132,13603,12912,17460, -17513,16429,24148,37505,12392,17732,16736,37506,14677,37507,15964,19800,12366, -37508,19791,24150,15952,22334,24149,21840,12381,37509,37510,17506,37511,37512, -16931,15472,37513,21301,16441,17697,12838,21617,37514,37515,16424,19011,24151, -21884,37516,14640,37517,18477,19241,37518,24153,16189,37519,37520,37521,37522, -17972,22311,18992,17475,37523,13142,14674,37524,37525,37526,37527,22072,27260, -12340,37528,37529,37530,37531,16230,37532,37533,19572,37534,37535,37536,37537, -19802,37538,37539,37540,22079,16974,37541,20046,19490,20526,17491,13618,24152, -21877,15415,15187,37542,37543,12324,37544,17714,13420,37545,37546,37547,21873, -37548,37549,27261,37550,37551,37552,37553,37554,37555,24154,19750,37556,37557, -19820,37558,37559,37560,37561,20070,24156,37562,19761,16422,37563,37564,22333, -37565,24155,12358,14900,18771,17523,15976,37566,37567,37568,37569,12854,37570, -37571,37572,37573,37574,37575,37576,37577,16460,19312,37578,15473,15163,13623, -37579,37580,37581,17781,37582,24166,37583,37584,37585,24163,15965,37586,37587, -24159,37588,37589,37590,37591,13367,15709,37592,37593,24160,17517,37594,37595, -37596,37597,20294,37598,13664,37599,37600,37601,37602,13918,19034,13684,24165, -37603,21830,37604,24161,19533,18046,37605,17733,37606,37607,37608,21044,37609, -15986,37610,37611,37612,37613,37614,37615,37616,16979,37617,19517,13112,37618, -15699,37619,16216,19782,20826,13419,37620,24164,24157,24167,37621,27262,37622, -37623,16944,24162,37624,37625,22080,13607,37626,12916,37627,24168,37628,24178, -37629,37630,37696,37697,37698,24173,37699,24177,37700,37701,18528,37702,37703, -37704,22369,24175,17256,19553,37705,12901,37706,37707,37708,21054,37709,37710, -37711,37712,37713,37714,37715,24174,37716,24171,20053,37717,13351,37718,37719, -37720,37721,37722,16171,15934,37723,37724,15698,37725,37726,37727,37728,24169, -37729,21550,37730,24158,37731,24170,37732,37733,37734,37735,16447,37736,24172, -12915,14441,16935,37737,37738,15681,37739,37740,37741,37742,37743,24181,24184, -37744,37745,12843,13348,37746,37747,13418,18726,37748,37749,37750,37751,37752, -37753,24182,19281,37754,14435,37755,24183,24186,37756,37757,37758,37760,24185, -37761,37762,37763,19522,37764,12385,13422,37765,37766,37767,37768,37769,37770, -25914,37771,37772,37773,37774,37775,20527,37776,37777,12907,37778,27425,37779, -24180,37780,37781,18787,24179,12378,21025,12663,37782,19503,37783,37784,37785, -37786,37787,37788,37789,24176,37790,19236,37791,37792,37793,21802,37794,37795, -37796,37797,37798,24187,37799,37800,37801,37802,37803,37804,37805,37806,13405, -37807,17446,37808,37809,37810,24189,37811,37812,37813,37814,37815,37816,37817, -37818,37819,37820,17278,17441,24353,37821,37822,37823,37824,37825,37826,37827, -16716,37828,24188,15983,37829,17970,37830,37831,37832,37833,37834,37835,37836, -37837,37838,13125,18550,37839,37840,19258,24190,37841,37842,24356,37843,37844, -37845,37846,22322,37847,37848,37849,37850,37851,13111,37852,37853,37854,37855, -16707,37856,37857,18251,12837,13417,37858,22315,37859,37860,37861,37862,17516, -37863,24354,24355,37864,24357,37865,14899,37866,37867,37868,24358,37869,16478, -37870,37871,18755,37872,37873,37874,37875,37876,37877,37878,12889,18278,37879, -24359,37880,18268,37881,37882,37883,37884,24360,27426,37885,37886,37952,37953, -37954,19283,37955,37956,37957,24362,37958,24361,37959,12865,37960,37961,37962, -37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975, -37976,37977,37978,37979,37980,37981,37982,37983,37984,17738,37985,37986,37987, -37988,37989,37990,37991,37992,24363,37993,37994,37995,37996,37997,37998,37999, -38000,21596,38001,38002,38003,38004,38005,18497,38006,38007,38008,38009,38010, -38011,38012,38013,38014,38016,38017,38018,24364,38019,38020,38021,38022,38023, -15984,38024,38025,24365,22055,38026,38027,38028,38029,27191,27446,19029,38030, -22652,14404,38031,14629,38032,38033,14149,21886,38034,38035,38036,38037,38038, -14666,38039,38040,20519,29773,38041,38042,13648,38043,38044,17268,38045,15944, -38046,38047,38048,27447,12349,38049,38050,15692,38051,16690,38052,12630,13096, -38053,38054,38055,14418,18722,38056,38057,13912,38058,38059,38060,38061,27448, -15924,38062,38063,38064,19069,38065,18243,38066,21883,38067,38068,14195,38069, -38070,38071,38072,38073,38074,38075,38076,38077,38078,38079,38080,38081,38082, -38083,20036,38084,38085,38086,21803,12659,38087,38088,38089,27699,12383,38090, -27701,38091,38092,38093,13879,38094,16719,38095,30074,20529,38096,38097,21861, -38098,20051,38099,38100,15727,13154,38101,14379,38102,21814,38103,27965,38104, -13903,38105,19257,20546,38106,38107,38108,38109,38110,38111,38112,38113,14141, -38114,38115,27702,18985,38116,38117,38118,17748,38119,27705,27704,16963,27703, -38120,38121,38122,38123,20605,27706,38124,27707,22373,38125,38126,27708,38127, -38128,38129,27709,18028,38130,38131,38132,38133,38134,38135,38136,38137,20062, -38138,15432,38139,38140,18517,13609,15945,22076,21607,38141,38142,20782,20593, -27192,27193,27194,14901,38208,38209,38210,38211,18993,16245,38212,38213,19834, -38214,38215,38216,38217,38218,27200,38219,12346,27198,38220,38221,16421,38222, -38223,38224,27195,38225,12925,38226,17271,15208,38227,38228,38229,21079,20084, -27199,38230,38231,38232,27196,38233,38234,38235,27203,38236,20551,21299,38237, -38238,38239,38240,13370,38241,17217,22386,38242,38243,38244,38245,21841,38246, -19015,38247,27205,38248,38249,27204,27207,27206,38250,38251,38252,38253,38254, -22119,38255,20308,38256,38257,27211,38258,15182,38259,38260,38261,38262,38263, -38264,38265,15738,18766,38266,38267,27212,38268,38269,18745,20350,27210,21582, -27213,27215,38270,38272,19821,38273,38274,38275,38276,27209,38277,27214,38278, -38279,20078,38280,15198,38281,13119,38282,38283,38284,38285,38286,18005,15920, -20090,38287,38288,38289,18279,38290,15911,27216,38291,38292,22087,38293,38294, -38295,16704,38296,38297,38298,21597,38299,27217,38300,38301,20286,38302,38303, -38304,38305,27218,38306,38307,38308,38309,19054,38310,38311,38312,38313,17711, -12341,38314,38315,38316,38317,38318,27220,38319,38320,38321,38322,38323,38324, -38325,38326,38327,27219,29791,38328,38329,38330,38331,38332,17466,38333,38334, -38335,38336,38337,12585,38338,38339,38340,38341,25951,38342,38343,38344,38345, -27221,38346,38347,38348,38349,38350,38351,38352,38353,38354,38355,38356,38357, -38358,38359,38360,38361,38362,38363,38364,38365,38366,38367,38368,38369,38370, -38371,19055,38372,27222,27223,18008,38373,38374,38375,38376,38377,38378,38379, -38380,27224,38381,38382,27225,38383,38384,38385,38386,38387,38388,21563,38389, -18298,21047,14460,38390,38391,27202,38392,12892,38393,38394,17020,38395,21624, -19558,22382,38396,38397,38398,38464,38465,38466,38467,21570,21328,27459,17779, -38468,14206,38469,38470,27476,38471,38472,38473,19255,27486,38474,16458,38475, -38476,38477,19835,38478,13103,38479,18010,38480,38481,38482,38483,38484,38485, -27516,38486,17470,38487,20020,17449,12606,21629,38488,19061,38489,22124,38490, -38491,18003,13924,38492,38493,38494,38495,15226,38496,38497,20576,38498,38499, -18737,38500,21587,18472,38501,38502,14411,38503,26686,18748,38504,38505,26683, -38506,16494,20563,12868,13413,38507,26684,38508,38509,21832,38510,38511,38512, -38513,38514,13893,38515,26685,19064,14428,19573,38516,38517,38518,16436,38519, -38520,20846,26687,26690,38521,38522,14908,38523,12589,15708,38524,27197,26691, -38525,26694,38526,26699,38528,38529,38530,38531,26700,38532,19273,12389,38533, -15403,38534,38535,14649,38536,38537,26689,38538,19831,38539,26698,38540,38541, -38542,38543,20086,38544,38545,38546,38547,21869,38548,16726,26692,38549,17206, -38550,14715,22054,26696,38551,38552,38553,19040,21606,38554,26688,38555,26693, -26695,38556,18233,14179,38557,26697,38558,16221,26706,38559,38560,26711,38561, -26709,15452,15439,26715,38562,38563,38564,38565,38566,38567,38568,38569,26718, -38570,26714,12666,38571,38572,38573,38574,38575,38576,38577,38578,38579,38580, -12376,17459,14412,18018,18494,18529,38581,38582,38583,26703,26708,26710,38584, -14705,26712,22389,38585,17531,38586,26716,38587,38588,12905,38589,38590,38591, -26705,38592,38593,15469,38594,38595,16194,26701,22137,38596,16760,12913,38597, -38598,38599,38600,38601,38602,38603,38604,26719,38605,19009,26713,38606,38607, -38608,38609,21796,38610,12650,21819,26702,26704,13872,26707,38611,26717,16440, -38612,19063,38613,19240,38614,38615,18012,16501,38616,38617,38618,38619,38620, -26729,38621,38622,38623,20515,38624,38625,38626,38627,38628,38629,38630,26738, -22122,38631,38632,38633,38634,38635,38636,38637,26720,26721,38638,38639,38640, -20857,14923,14457,38641,38642,14449,21588,26735,38643,26734,26732,14704,19538, -26726,20006,16242,38644,12344,26737,26736,38645,22336,38646,26724,38647,19753, -18723,38648,15160,15707,26730,38649,38650,38651,38652,38653,38654,38720,38721, -38722,38723,26722,26723,26725,13621,26727,18245,26731,26733,15664,22318,38724, -26744,38725,38726,38727,38728,38729,38730,38731,38732,26741,38733,19760,26742, -38734,38735,38736,38737,38738,38739,38740,38741,38742,16698,38743,26728,38744, -17207,12400,38745,38746,38747,38748,38749,38750,38751,38752,26740,38753,38754, -38755,26743,38756,38757,38758,14627,38759,38760,38761,38762,38763,38764,38765, -38766,38767,38768,18770,38769,38770,38771,17230,20064,16486,38772,38773,38774, -38775,19315,38776,19549,20533,38777,38778,19041,38779,26739,38780,38781,38782, -38784,38785,38786,38787,38788,38789,38790,15468,38791,26745,38792,38793,38794, -38795,38796,38797,17246,38798,18021,38799,14711,38800,38801,38802,38803,12404, -38804,38805,22360,38806,38807,15404,38808,17775,38809,38810,38811,38812,38813, -19524,38814,38815,26918,38816,38817,38818,38819,38820,38821,38822,38823,38824, -38825,18733,38826,26914,16482,38827,38828,38829,16195,38830,38831,38832,26750, -14679,38833,26747,38834,38835,38836,38837,26916,38838,38839,38840,21070,38841, -38842,38843,38844,38845,26915,38846,22066,22325,38847,26919,38848,15671,38849, -38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,26748,26749, -38861,38862,38863,26913,38864,38865,38866,38867,38868,38869,38870,38871,19798, -38872,38873,21036,38874,38875,38876,26930,38877,38878,38879,38880,26921,38881, -38882,38883,13354,38884,13371,38885,38886,26923,38887,38888,38889,38890,38891, -38892,38893,38894,38895,38896,38897,38898,38899,38900,38901,38902,38903,20520, -38904,38905,26917,38906,38907,13182,38908,38909,26924,16483,38910,26922,38976, -38977,26937,38978,38979,26936,38980,38981,38982,38983,26926,38984,38985,26746, -38986,38987,26920,38988,38989,38990,38991,38992,16172,26929,26938,38993,38994, -16933,38995,38996,38997,26927,38998,14405,38999,26925,39000,21340,26932,26933, -26935,39001,39002,39003,26951,39004,39005,39006,39007,39008,39009,16454,26949, -39010,39011,26928,39012,39013,26939,12401,39014,39015,39016,39017,39018,39019, -39020,39021,39022,39023,26940,21797,39024,39025,26942,39026,26943,39027,39028, -39029,26945,39030,39031,16753,39032,39033,18486,39034,39035,39036,26941,39037, -39038,39040,39041,39042,26946,39043,39044,39045,39046,39047,39048,39049,39050, -26947,39051,26931,39052,26934,39053,15153,39054,39055,39056,26944,39057,39058, -39059,39060,39061,39062,15479,39063,39064,39065,26948,26950,39066,39067,39068, -39069,39070,39071,39072,39073,39074,39075,39076,39077,26954,39078,39079,39080, -39081,26958,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,12891, -39092,26952,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,14126, -39103,39104,39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,26955, -26956,39115,39116,39117,39118,39119,39120,21825,39121,17443,39122,39123,39124, -39125,39126,39127,26968,39128,14945,39129,39130,39131,39132,26953,39133,21283, -39134,39135,39136,26964,39137,39138,39139,39140,39141,39142,39143,26967,26960, -39144,39145,39146,39147,39148,26959,39149,39150,18241,39151,39152,39153,39154, -39155,39156,39157,39158,26962,39159,39160,39161,39162,39163,39164,39165,26969, -13128,39166,26963,39232,39233,39234,39235,39236,20336,39237,39238,39239,26957, -39240,39241,39242,39243,39244,39245,39246,39247,39248,39249,39250,13175,39251, -39252,39253,39254,39255,39256,39257,26966,39258,39259,26970,39260,39261,39262, -19508,39263,39264,39265,20269,39266,39267,39268,39269,39270,39271,39272,39273, -39274,26965,39275,26972,26971,39276,39277,39278,39279,39280,26974,39281,39282, -39283,39284,39285,39286,39287,39288,26961,39289,39290,39291,39292,39293,39294, -39296,39297,26973,39298,26975,17226,39299,39300,39301,39302,39303,39304,39305, -39306,39307,39308,39309,39310,39311,39312,39313,39314,39315,39316,39317,39318, -39319,39320,39321,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331, -39332,39333,39334,39335,39336,39337,39338,39339,39340,39341,39342,39343,39344, -39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357, -39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370, -39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383, -39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396, -39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409, -39410,39411,39412,39413,18231,13390,15158,20544,27683,39414,39415,17719,39416, -39417,39418,39419,39420,39421,39422,39488,39489,39490,21371,39491,39492,39493, -39494,27684,39495,27685,18011,39496,39497,39498,16238,39499,39500,39501,39502, -27686,39503,39504,27687,20522,39505,18232,39506,39507,14440,39508,39509,39510, -39511,39512,39513,39514,39515,39516,39517,39518,39519,27688,39520,39521,39522, -39523,39524,39525,39526,39527,22073,21885,13387,12861,20068,18023,39528,39529, -19809,39530,39531,39532,39533,39534,39535,39536,39537,39538,39539,39540,39541, -39542,39543,13429,39544,19264,15455,39545,39546,39547,39548,26978,26979,20842, -26981,39549,13433,26980,39550,20787,19042,12880,39552,26984,39553,39554,39555, -39556,26982,26983,39557,39558,22067,39559,39560,39561,26985,26986,39562,39563, -39564,39565,39566,26987,39567,39568,39569,39570,39571,39572,39573,39574,26988, -39575,39576,39577,39578,39579,39580,39581,39582,27695,17721,13902,39583,21107, -39584,39585,39586,39587,39588,39589,39590,13678,39591,15193,27697,39592,39593, -21091,39594,39595,39596,39597,39598,20067,39599,17464,39600,17215,39601,39602, -13886,22585,12616,12623,12625,17790,39603,12624,39604,17195,39605,39606,39607, -39608,39609,21809,39610,39611,39612,39613,39614,39615,39616,39617,27428,14913, -39618,39619,39620,19514,39621,39622,39623,27429,39624,27431,39625,39626,39627, -27432,39628,39629,39630,27430,39631,39632,39633,39634,39635,39636,39637,27433, -27435,27434,39638,39639,39640,39641,39642,27436,39643,19023,22581,17265,39644, -17189,18040,27437,17482,39645,27438,27439,27440,14165,39646,39647,39648,14202, -39649,27441,18274,39650,27443,39651,14884,20853,12337,27442,27444,39652,39653, -39654,13610,16968,18280,39655,27445,39656,19246,25439,39657,39658,21312,39659, -39660,39661,39662,22875,39663,39664,19745,22061,18291,39665,39666,39667,22880, -15203,39668,14906,25442,39669,39670,39671,39672,39673,20267,39674,39675,39676, -25440,18759,39677,14905,39678,39744,39745,20788,25441,18538,14639,15661,13144, -20059,39746,39747,19520,39748,39749,39750,25448,25449,19828,39751,39752,39753, -39754,39755,19501,39756,15411,39757,25450,39758,25451,39759,39760,20570,39761, -39762,39763,18043,14170,39764,39765,18271,21066,20054,39766,25444,25452,39767, -18802,13121,39768,39769,25447,39770,39771,18019,25445,39772,39773,27955,25446, -39774,39775,39776,39777,18739,39778,17766,39779,39780,39781,14645,39782,17211, -39783,25443,17725,16676,16985,12887,39784,25453,15142,17453,39785,25456,15962, -39786,39787,25467,25461,14931,39788,39789,39790,39791,14160,21325,39792,22094, -21843,14657,21812,20824,39793,39794,39795,39796,20537,18294,39797,39798,39799, -18474,12852,39800,17242,39801,39802,39803,25454,39804,39805,25468,25455,14120, -25463,25460,39806,39808,39809,14138,39810,39811,17698,39812,25462,17757,12840, -18044,39813,17504,39814,39815,22306,39816,16481,25465,39817,39818,25466,25469, -19497,25459,39819,21310,39820,12611,27956,25457,25458,39821,25464,20538,17987, -21619,25470,39822,39823,15712,39824,39825,25639,39826,39827,25638,39828,39829, -39830,20851,25635,39831,25641,39832,39833,39834,18551,39835,39836,39837,39838, -20276,39839,25640,25646,16997,39840,39841,13876,39842,39843,39844,39845,39846, -39847,15730,39848,25634,39849,39850,14953,25642,39851,39852,25644,39853,39854, -13949,22110,25650,39855,25645,39856,39857,39858,25633,39859,15214,19805,18210, -17737,39860,39861,16759,39862,25636,39863,18227,15660,15677,25637,39864,22343, -12898,39865,25643,15427,25647,39866,15211,25648,17704,25649,39867,39868,39869, -39870,21859,16163,39871,25658,39872,25655,39873,25659,39874,39875,25661,39876, -39877,18006,39878,39879,14918,16459,39880,39881,39882,14369,25652,39883,39884, -39885,39886,21537,39887,39888,14883,15742,39889,39890,39891,25660,39892,39893, -39894,39895,39896,19775,39897,39898,17529,39899,39900,20347,18790,39901,39902, -21311,39903,20305,39904,39905,25651,39906,25656,25657,19561,39907,39908,39909, -39910,39911,19534,39912,16468,25653,16688,25654,20048,39913,15169,13651,39914, -18547,15655,21831,18732,14370,25674,39915,39916,25676,20804,39917,39918,21050, -39919,39920,14893,39921,39922,14932,39923,39924,39925,39926,39927,39928,25667, -13677,39929,39930,39931,22349,25664,20349,25663,39932,39933,39934,16732,19530, -40000,40001,40002,40003,19047,40004,40005,40006,40007,17495,40008,19540,25672, -40009,40010,40011,25671,25665,40012,25668,13613,40013,40014,21337,40015,25670, -40016,40017,40018,40019,21113,13411,40020,15156,40021,40022,18798,40023,13374, -40024,40025,40026,15212,40027,20813,40028,19565,27957,40029,40030,40031,40032, -40033,40034,40035,40036,18277,40037,40038,40039,40040,21544,40041,25675,22357, -25666,40042,15653,25669,40043,40044,21350,40045,25673,18808,40046,40047,25662, -40048,40049,21349,40050,40051,18302,13897,40052,21628,12851,25687,40053,40054, -40055,20034,40056,25677,40057,20028,40058,14427,40059,40060,25686,40061,16202, -40062,40064,40065,21326,40066,17260,40067,40068,40069,40070,40071,40072,40073, -40074,17736,25688,40075,40076,40077,40078,40079,40080,40081,40082,19780,25679, -40083,40084,40085,40086,25684,25685,40087,14974,40088,20326,40089,40090,21823, -40091,40092,40093,25682,40094,40095,40096,40097,40098,40099,40100,40101,40102, -40103,40104,25680,40105,40106,25678,40107,40108,40109,40110,40111,40112,40113, -40114,40115,40116,40117,40118,40119,40120,40121,19813,18986,40122,40123,40124, -16419,40125,15654,25683,40126,40127,14408,40128,40129,40130,40131,40132,25703, -21556,40133,40134,40135,40136,40137,40138,40139,25691,40140,40141,40142,16751, -40143,40144,25705,40145,40146,21095,40147,40148,25695,40149,25696,40150,40151, -20266,40152,40153,40154,40155,19293,40156,25690,25681,40157,25701,40158,18524, -25699,40159,40160,17511,25698,40161,25697,40162,40163,40164,13180,25704,40165, -40166,40167,40168,13665,40169,40170,40171,22348,40172,40173,40174,25702,40175, -15148,40176,22354,19535,27512,40177,25700,40178,40179,14710,40180,40181,40182, -22093,25689,25692,17018,25694,40183,16971,16452,16976,40184,12661,19506,40185, -40186,40187,40188,40189,40190,40256,40257,40258,40259,13646,40260,40261,40262, -40263,25711,40264,40265,40266,40267,40268,40269,40270,40271,17967,40272,40273, -40274,18017,40275,40276,25717,40277,40278,40279,40280,40281,16937,40282,40283, -40284,16492,20829,25710,40285,40286,40287,40288,40289,40290,40291,40292,40293, -40294,17454,40295,40296,40297,25709,40298,40299,40300,40301,25718,25716,17022, -40302,25693,40303,25712,40304,19070,40305,21828,40306,40307,25713,40308,40309, -40310,40311,40312,40313,40314,20858,40315,40316,40317,40318,40320,40321,40322, -25707,25708,40323,40324,40325,25714,40326,20011,40327,40328,40329,40330,40331, -40332,40333,40334,40335,40336,17739,40337,40338,40339,18225,40340,16954,40341, -40342,40343,25706,40344,40345,40346,16714,40347,40348,40349,40350,40351,40352, -19510,13105,40353,40354,40355,25723,40356,25715,40357,40358,40359,25722,40360, -25725,40361,25724,40362,40363,40364,40365,40366,40367,40368,13134,40369,40370, -40371,13114,25719,40372,40373,25721,25720,17772,40374,40375,40376,40377,40378, -40379,40380,40381,40382,40383,40384,40385,40386,16445,40387,40388,40389,40390, -21608,40391,40392,40393,40394,40395,25890,40396,40397,40398,40399,40400,40401, -40402,40403,40404,40405,40406,12356,40407,40408,25892,40409,40410,25891,40411, -40412,40413,40414,40415,40416,15396,40417,25893,40418,40419,40420,40421,40422, -40423,25889,40424,40425,40426,40427,40428,40429,40430,25726,12660,40431,40432, -40433,40434,40435,40436,40437,40438,40439,40440,40441,25896,40442,25897,25894, -40443,40444,40445,40446,40512,40513,40514,40515,40516,40517,40518,40519,25895, -25898,40520,40521,40522,40523,40524,40525,40526,40527,40528,40529,40530,40531, -40532,40533,40534,40535,40536,40537,40538,40539,40540,40541,40542,40543,40544, -40545,40546,40547,40548,40549,40550,40551,40552,18009,40553,40554,40555,40556, -40557,40558,40559,40560,25899,25901,40561,40562,40563,40564,40565,40566,40567, -25900,40568,40569,40570,40571,40572,40573,40574,40576,40577,40578,40579,40580, -40581,40582,40583,40584,40585,25903,40586,40587,40588,25902,40589,40590,40591, -40592,40593,40594,40595,40596,40597,40598,40599,40600,40601,40602,40603,40604, -40605,40606,14688,40607,40608,25904,40609,40610,40611,40612,40613,40614,40615, -40616,40617,40618,40619,40620,40621,40622,25905,40623,40624,40625,40626,40627, -40628,40629,40630,40631,40632,40633,40634,15216,27745,17264,40635,13638,15186, -40636,40637,40638,40639,16745,21614,40640,15940,40641,40642,40643,22342,40644, -21590,12883,27710,40645,40646,40647,40648,27201,40649,40650,40651,16943,13366, -40652,40653,40654,20823,40655,40656,40657,13108,40658,18482,16187,27712,40659, -40660,22091,40661,40662,27711,27713,40663,40664,40665,40666,40667,40668,40669, -40670,40671,40672,40673,40674,40675,27717,15974,19519,17754,15932,40676,27718, -40677,12670,40678,40679,40680,27716,21800,13667,40681,27714,16694,13155,40682, -40683,27715,19256,16451,19582,40684,40685,40686,40687,16722,40688,27720,40689, -40690,40691,40692,40693,40694,40695,40696,40697,40698,40699,40700,40701,14950, -16467,40702,22130,40768,40769,40770,20812,40771,40772,40773,40774,16190,40775, -14131,18773,27719,15202,40776,19532,15741,18504,40777,20265,40778,40779,40780, -40781,40782,40783,40784,19817,40785,17771,40786,40787,40788,14185,40789,40790, -40791,40792,40793,40794,40795,40796,40797,40798,40799,20809,14904,40800,40801, -40802,40803,40804,27721,40805,40806,27722,40807,15168,27723,40808,27746,12602, -14169,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,40819,15673, -40820,40821,40822,40823,40824,40825,40826,40827,27724,20838,27725,40828,40829, -40830,40832,18491,40833,40834,40835,40836,40837,40838,40839,40840,40841,40842, -40843,40844,40845,40846,27729,40847,40848,40849,40850,27731,40851,15181,40852, -15461,40853,40854,40855,40856,40857,40858,40859,40860,40861,40862,40863,40864, -40865,27727,40866,18743,40867,40868,40869,40870,40871,17210,40872,27747,21845, -27728,40873,40874,40875,40876,40877,22131,40878,40879,40880,27730,27726,40881, -40882,40883,40884,27732,40885,27733,40886,40887,18751,40888,40889,40890,40891, -40892,40893,20264,40894,40895,40896,40897,40898,20572,40899,40900,40901,40902, -20780,40903,40904,40905,40906,18523,40907,40908,40909,27734,20085,40910,40911, -40912,40913,40914,19052,27738,40915,40916,40917,40918,40919,40920,40921,27737, -40922,40923,40924,12350,40925,40926,40927,40928,40929,40930,27735,40931,27736, -40932,40933,40934,27748,40935,40936,40937,40938,40939,40940,40941,40942,40943, -18492,40944,40945,40946,40947,40948,40949,40950,40951,40952,40953,16711,40954, -40955,40956,40957,40958,27740,20832,41024,41025,41026,41027,41028,41029,41030, -41031,41032,41033,27739,41034,41035,41036,41037,21615,41038,27741,41039,41040, -41041,41042,41043,41044,23366,41045,41046,41047,41048,41049,41050,41051,41052, -41053,41054,27742,41055,41056,41057,41058,41059,41060,41061,41062,41063,41064, -41065,41066,12588,41067,41068,41069,41070,41071,41072,41073,41074,41075,41076, -41077,41078,41079,41080,41081,41082,41083,41084,41085,41086,41088,41089,27743, -41090,41091,41092,41093,41094,41095,41096,41097,41098,41099,27744,41100,22310, -41101,17728,41102,41103,41104,27452,12334,41105,41106,41107,15988,14392,21039, -12374,13689,41108,22579,41109,19244,41110,25437,41111,41112,41113,41114,41115, -41116,41117,17964,12390,41118,41119,41120,17734,27449,41121,41122,41123,41124, -27450,41125,41126,41127,27451,41128,41129,20800,41130,17699,41131,27250,41132, -17458,41133,17461,16462,41134,41135,41136,27251,17473,41137,20079,41138,41139, -41140,41141,27248,27252,41142,41143,18812,41144,41145,18211,41146,41147,41148, -19544,20094,41149,41150,41151,27253,27254,20268,16487,41152,41153,27255,41154, -41155,41156,41157,41158,13887,27256,41159,27257,41160,27258,41161,41162,27259, -41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,41174,27249, -41175,41176,41177,41178,41179,41180,41181,41182,41183,41184,41185,41186,18478, -24939,41187,14136,24940,41188,41189,41190,24941,41191,22324,24942,24943,21324, -41192,41193,41194,41195,41196,41197,41198,24945,16241,24944,13650,41199,41200, -41201,12599,41202,41203,41204,41205,24947,24946,41206,14972,41207,24948,41208, -41209,41210,41211,14647,41212,15953,41213,41214,43584,43585,17532,43586,14941, -15686,43587,43588,43589,43590,43591,43592,24949,24951,43593,43594,13888,20289, -18984,24950,21880,21372,24952,24956,24953,43595,43596,24954,16490,43597,24958, -25121,16455,43598,43599,43600,43601,24955,43602,24957,43603,43604,43605,43606, -43607,43608,25125,43609,43610,43611,16724,43612,43613,43614,43615,25123,43616, -25128,12926,25122,43617,43618,43619,17229,12866,25127,25126,43620,43621,25124, -25129,43622,43623,25131,43624,43625,43626,20553,22125,17192,25132,43627,20311, -43628,43629,25134,43630,43631,14959,43632,43633,26976,25133,25130,43634,43635, -43636,43637,15147,21555,43638,43639,43640,43641,43642,43643,43644,43645,43646, -43648,43649,43650,43651,25136,43652,43653,25135,43654,26977,43655,43656,43657, -43658,25137,43659,43660,43661,43662,43663,43664,43665,43666,25138,43667,43668, -43669,43670,43671,43672,43673,43674,43675,43676,43677,25139,19489,43678,25140, -43679,43680,43840,43841,43842,43843,43844,43845,43846,43847,43848,43849,43850, -43851,25141,43852,43853,43854,43855,43856,20606,43857,43858,16970,43859,21361, -43860,19829,43861,43862,26464,43863,43864,26465,43865,43866,43867,43868,15937, -43869,43870,43871,43872,17002,43873,43874,43875,26468,43876,43877,26467,43878, -43879,43880,43881,43882,43883,19814,43884,17205,43885,43886,26466,15159,20310, -43887,16737,26473,43888,43889,43890,26472,43891,43892,26484,12835,43893,43894, -43895,43896,26474,43897,26470,43898,43899,43900,43901,43902,26476,26475,18746, -43904,43905,21860,43906,26469,14121,26471,43907,43908,43909,43910,43911,43912, -43913,26478,43914,43915,43916,43917,26483,43918,22121,43919,43920,43921,43922, -26477,43923,26482,43924,26481,43925,43926,43927,12384,43928,43929,43930,43931, -26485,43932,43933,43934,43935,43936,44096,44097,44098,44099,44100,44101,44102, -44103,44104,44105,44106,18290,44107,16453,16493,44108,44109,16752,26480,44110, -44111,44112,44113,26486,19318,44114,44115,44116,44117,44118,44119,44120,44121, -44122,26658,26657,44123,44124,44125,44126,44127,44128,22337,44129,44130,26490, -26489,44131,26491,44132,26487,44133,26494,44134,26493,44135,26492,44136,44137, -16725,18265,17789,17731,44138,44139,44140,44141,44142,18285,44143,44144,44145, -44146,26659,44147,44148,44149,44150,44151,44152,44153,44154,44155,44156,44157, -44158,44160,44161,44162,44163,44164,44165,44166,26662,44167,26661,44168,26663, -14967,26488,26660,44169,18544,18730,44170,44171,44172,44173,44174,44175,44176, -44177,44178,44179,44180,44181,44182,26665,44183,44184,14693,44185,44186,44187, -44188,44189,20862,26664,44190,44191,44192,44352,44353,44354,26666,44355,26669, -26670,44356,16679,44357,44358,44359,26671,44360,44361,44362,26672,44363,44364, -26668,44365,26676,44366,44367,44368,44369,44370,44371,44372,44373,44374,44375, -44376,26667,44377,26673,44378,44379,44380,44381,44382,44383,44384,44385,26677, -26674,26675,44386,44387,44388,44389,44390,44391,44392,44393,44394,44395,44396, -44397,44398,44399,44400,44401,26679,44402,44403,44404,44405,44406,44407,44408, -44409,44410,44411,44412,44413,44414,44416,44417,44418,44419,44420,44421,44422, -44423,44424,44425,26678,44426,44427,44428,44429,44430,44431,44432,44433,44434, -14671,44435,28716,44436,28717,44437,17968,12394,18495,44438,19807,44439,44440, -44441,44442,44443,44444,44445,20045,27185,44446,44447,44448,44608,27186,44609, -17983,13385,44610,44611,44612,44613,44614,44615,44616,27187,44617,44618,44619, -44620,21863,44621,44622,44623,44624,44625,44626,44627,44628,23929,44629,27188, -44630,27189,44631,27190,44632,44633,44634,44635,14410,24368,18805,44636,19568, -44637,44638,18810,44639,44640,44641,44642,44643,18811,44644,44645,21315,19238, -44646,14374,28718,12610,44647,25912,19567,21321,15447,18794,44648,13671,44649, -17488,13673,44650,28206,15149,44651,44652,26462,44653,28207,44654,44655,44656, -44657,13097,44658,44659,28210,44660,44661,28209,15719,44662,28208,20023,44663, -44664,44665,44666,17743,44667,44668,44669,44670,16756,23374,28211,20595,44672, -44673,44674,44675,44676,44677,44678,44679,16980,18024,44680,44681,44682,14124, -44683,44684,44685,44686,44687,44688,44689,28212,44690,13163,44691,44692,44693, -15227,28213,44694,44695,44696,44697,44698,26460,44699,44700,44701,28214,44702, -44703,15662,44704,44864,44865,44866,29026,44867,44868,44869,19048,44870,21065, -28762,44871,28763,44872,28764,16710,44873,14445,15950,44874,44875,28766,44876, -17713,28765,20849,44877,28768,12364,15722,44878,44879,44880,44881,44882,21087, -28767,44883,13359,14184,28774,28773,17955,28769,28770,13379,44884,44885,28771, -21870,44886,44887,19547,15954,15410,44888,44889,44890,28776,28775,28772,12833, -44891,22050,21304,15927,18476,44892,44893,28778,44894,44895,44896,44897,20855, -44898,22092,14939,28777,44899,13883,44900,44901,19764,44902,44903,17958,44904, -44905,44906,16673,28779,28782,44907,28781,28784,28780,44908,15166,28783,44909, -44910,44911,44912,19509,28786,44913,44914,13141,44915,44916,44917,44918,12628, -44919,44920,28787,44921,44922,28788,28790,13409,44923,28785,44924,28791,44925, -44926,44928,44929,28794,44930,28792,44931,44932,44933,28789,44934,44935,44936, -44937,28797,44938,28793,28796,28798,44939,28961,44940,44941,44942,20033,28964, -44943,28963,44944,16758,28795,19037,44945,44946,13425,12657,19505,44947,28966, -44948,44949,28967,44950,44951,28972,21838,28969,44952,44953,18483,44954,44955, -44956,28962,44957,28971,28968,28965,44958,44959,28970,44960,45120,45121,45122, -45123,45124,45125,45126,12329,28973,45127,45128,45129,45130,45131,45132,28975, -45133,28977,45134,45135,45136,45137,45138,28976,45139,28974,45140,45141,45142, -45143,20770,45144,45145,45146,45147,45148,45149,45150,28978,45151,45152,45153, -28979,45154,45155,45156,45157,45158,45159,45160,45161,14703,45162,45163,13639, -45164,12375,12377,45165,45166,45167,21613,45168,13636,45169,15700,15178,28711, -45170,45171,14430,45172,45173,28712,45174,45175,12328,45176,28713,45177,45178, -19822,45179,45180,28714,45181,45182,45184,45185,45186,45187,45188,45189,45190, -45191,28715,45192,45193,45194,45195,45196,45197,45198,45199,45200,17956,45201, -45202,22117,29028,45203,29029,45204,45205,45206,45207,45208,45209,45210,45211, -45212,45213,17267,45214,45215,21339,45216,45376,22097,17768,45377,21295,45378, -21094,45379,45380,28225,12347,21813,20814,15456,14928,45381,16248,45382,14407, -13633,17740,45383,45384,18978,45385,45386,45387,17227,45388,45389,45390,45391, -45392,28226,45393,45394,45395,45396,45397,45398,45399,45400,17471,13858,45401, -28012,17188,45402,22065,45403,45404,45405,20320,28015,45406,45407,17742,45408, -13916,45409,45410,18977,45411,45412,28013,45413,45414,28016,28017,17212,45415, -16180,45416,28014,45417,45418,45419,45420,45421,45422,45423,45424,45425,45426, -45427,28020,28018,45428,45429,45430,45431,21862,17247,45432,28019,45433,45434, -45435,28022,45436,21795,20771,45437,45438,45440,28021,45441,17232,45442,45443, -45444,45445,45446,28023,16244,15980,28024,45447,19575,45448,20827,45449,45450, -45451,22341,21878,45452,28028,45453,45454,45455,28027,45456,45457,45458,45459, -45460,45461,45462,45463,28025,28026,45464,45465,45466,45467,45468,45469,45470, -45471,28029,15910,45472,45632,45633,45634,45635,19247,28193,13885,45636,28194, -17472,45637,28030,45638,45639,15710,12871,45640,45641,45642,45643,45644,45645, -45646,45647,45648,45649,45650,45651,13891,45652,45653,45654,28197,22586,28195, -28198,45655,45656,45657,17257,13170,45658,45659,45660,45661,45662,45663,28199, -28196,20281,45664,45665,28200,17015,45666,45667,45668,45669,45670,45671,45672, -45673,45674,45675,45676,45677,28201,28202,45678,24107,45679,45680,17971,45681, -18246,45682,22133,13641,45683,19250,45684,45685,45686,28203,45687,45688,19755, -45689,28204,45690,45691,45692,45693,45694,21808,45696,28205,45697,30276,45698, -45699,45700,45701,45702,45703,45704,45705,45706,45707,45708,45709,45710,23367, -45711,45712,45713,45714,45715,45716,45717,45718,45719,13347,45720,45721,45722, -17196,29030,45723,45724,45725,45726,45727,19000,21075,45728,22058,45888,28530, -45889,15960,45890,15683,28531,13900,12331,45891,45892,45893,45894,18991,45895, -45896,27958,45897,27959,45898,45899,45900,45901,20089,14127,16243,27960,17003, -18736,45902,45903,45904,45905,45906,45907,27961,45908,45909,18038,16179,45910, -45911,45912,27964,17784,45913,20816,45914,22313,27962,27963,45915,20834,45916, -27967,27968,45917,27972,45918,45919,45920,27976,45921,27974,27982,21864,45922, -27977,45923,45924,27975,27966,45925,45926,17769,45927,45928,45929,17990,45930, -45931,18793,21586,27969,27970,27971,27973,45932,16505,45933,13345,45934,45935, -45936,45937,14696,45938,27984,45939,45940,45941,45942,27985,45943,27978,45944, -27983,45945,20088,45946,45947,19254,27980,27981,45948,45949,45950,45952,45953, -20341,45954,45955,45956,45957,45958,45959,45960,45961,45962,45963,45964,45965, -27986,16754,21298,27979,18487,45966,45967,45968,45969,45970,45971,45972,45973, -15471,45974,45975,45976,45977,17776,45978,45979,45980,45981,45982,45983,45984, -46144,46145,46146,27990,46147,13679,46148,46149,16949,12333,19305,46150,46151, -12590,46152,27988,46153,46154,46155,19819,13666,46156,27989,27987,27991,46157, -46158,13690,46159,27992,46160,27993,46161,27996,46162,12620,46163,46164,46165, -46166,46167,46168,46169,46170,17782,15470,27994,19516,12906,46171,46172,46173, -46174,27995,46175,46176,46177,46178,17515,46179,46180,13381,46181,46182,46183, -12405,46184,46185,46186,27999,16474,13416,46187,46188,46189,46190,17741,46191, -46192,46193,27997,16196,46194,46195,46196,27998,46197,46198,46199,46200,46201, -46202,46203,46204,46205,46206,46208,46209,46210,46211,17445,46212,46213,46214, -28000,46215,46216,46217,46218,46219,28001,46220,28003,46221,46222,16727,46223, -46224,15175,46225,46226,46227,46228,46229,46230,15672,46231,46232,46233,28002, -46234,46235,46236,46237,46238,46239,46240,46400,46401,46402,46403,46404,46405, -28004,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,28006,46416, -46417,46418,46419,46420,28005,46421,46422,46423,46424,46425,46426,46427,46428, -46429,46430,46431,46432,46433,46434,46435,28007,46436,46437,46438,46439,46440, -19006,27754,16497,46441,18791,46442,27755,18030,46443,46444,46445,46446,27756, -46447,18029,27757,46448,46449,46450,46451,46452,46453,46454,46455,46456,27760, -46457,46458,22374,27763,46459,46460,27761,27758,27759,22307,18801,19310,27764, -46461,27762,46462,46464,20329,46465,27766,17969,46466,46467,46468,46469,15424, -46470,27765,46471,46472,46473,46474,46475,46476,46477,13627,15222,46478,27767, -46479,46480,46481,46482,46483,22903,15739,46484,46485,16955,27768,46486,46487, -46488,46489,27769,46490,46491,46492,46493,14371,46494,46495,46496,46656,46657, -46658,46659,46660,46661,46662,27770,46663,46664,46665,46666,46667,46668,46669, -46670,46671,46672,46673,46674,27771,46675,46676,46677,46678,46679,46680,46681, -46682,46683,46684,46685,27772,46686,46687,46688,46689,46690,21357,22574,16491, -46691,18269,14924,46692,20579,19261,46693,19770,46694,46695,14417,46696,46697, -12668,46698,18287,46699,22102,46700,46701,46702,16198,17259,46703,46704,28533, -46705,46706,17240,46707,46708,46709,46710,46711,46712,22370,46713,46714,46715, -28535,13139,46716,18264,20845,46717,22088,46718,28536,46720,28534,46721,15229, -13126,46722,46723,46724,46725,46726,46727,46728,15701,46729,46730,21062,46731, -15200,46732,46733,20257,46734,28540,28539,46735,46736,28537,46737,46738,46739, -46740,13132,46741,18772,19248,46742,46743,46744,46745,46746,28542,46747,46748, -12382,46749,46750,22089,46751,46752,46912,28541,46913,13165,46914,46915,30293, -46916,46917,46918,46919,46920,46921,46922,46923,46924,46925,46926,46927,46928, -46929,46930,20040,46931,46932,46933,28706,46934,28705,46935,13630,15450,15228, -46936,14437,46937,46938,46939,46940,46941,46942,17474,46943,46944,46945,46946, -46947,46948,46949,46950,46951,46952,28707,46953,46954,46955,46956,46957,19307, -46958,46959,46960,46961,46962,46963,46964,46965,46966,46967,46968,46969,46970, -46971,46972,46973,46974,46976,46977,46978,46979,46980,46981,46982,28710,46983, -46984,46985,20776,46986,15935,18286,28982,28983,16213,46987,46988,46989,46990, -13353,28984,19771,46991,18260,21805,46992,28985,46993,28986,46994,46995,46996, -46997,18255,46998,46999,47000,21028,22095,47001,47002,28987,15697,13360,15933, -47003,47004,47005,13404,20049,47006,16223,28989,47007,47008,47168,47169,16250, -28988,47170,28991,47171,47172,47173,28990,28992,47174,47175,47176,47177,47178, -28993,47179,47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,16766, -47190,47191,47192,47193,47194,47195,47196,47197,47198,47199,47200,16674,47201, -47202,47203,47204,47205,47206,47207,47208,47209,47210,19066,47211,47212,21822, -47213,47214,47215,47216,15930,15929,21826,47217,47218,16162,47219,19759,28981, -47220,47221,47222,47223,47224,47225,15711,47226,13899,47227,47228,47229,47230, -47232,47233,47234,47235,47236,22129,29507,47237,47238,29508,47239,14413,47240, -47241,47242,29510,29511,47243,12362,47244,29509,47245,29513,19313,47246,47247, -47248,29515,47249,20518,47250,47251,12618,29512,47252,47253,47254,29519,47255, -13649,47256,47257,29527,47258,29522,47259,47260,47261,29524,29523,14203,47262, -12607,47263,29518,29514,13658,47264,29520,47424,47425,29521,47426,29525,47427, -47428,47429,47430,29517,47431,15459,47432,16765,47433,29526,47434,47435,47436, -47437,47438,47439,29530,47440,29516,47441,13640,47442,15726,29532,47443,47444, -14116,16240,22142,19762,47445,13424,47446,12895,47447,29528,47448,29529,18744, -47449,29533,47450,47451,29534,47452,29537,47453,47454,47455,47456,47457,47458, -47459,47460,47461,47462,47463,29535,47464,47465,29539,29538,47466,47467,29531, -47468,16234,47469,13167,47470,29536,47471,47472,18217,47473,15474,47474,47475, -47476,47477,29547,47478,47479,47480,47481,47482,47483,47484,14655,47485,47486, -29540,47488,47489,47490,12845,15230,47491,19299,47492,47493,47494,47495,29549, -29545,47496,47497,47498,14684,29550,47499,47500,47501,29541,29542,29546,16993, -29548,29551,29544,15485,47502,47503,47504,20324,47505,47506,29552,47507,47508, -47509,29543,47510,47511,47512,47513,47514,47515,47516,47517,29554,47518,47519, -47520,47680,22317,17962,47681,47682,47683,47684,29555,47685,47686,47687,47688, -29553,47689,16936,47690,47691,47692,47693,47694,14429,29557,47695,47696,29556, -47697,47698,47699,13403,47700,47701,47702,29558,29559,47703,47704,47705,29560, -47706,47707,47708,16442,47709,47710,16489,47711,47712,47713,47714,47715,17777, -47716,47717,47718,47719,29563,47720,29562,47721,47722,47723,47724,47725,47726, -47727,47728,13400,47729,47730,47731,29566,29561,47732,47733,29564,47734,47735, -47736,47737,47738,47739,29565,47740,47741,47742,47744,47745,47746,47747,47748, -29729,47749,47750,47751,47752,47753,47754,29731,15177,47755,47756,29730,47757, -47758,47759,47760,47761,47762,47763,47764,47765,47766,47767,47768,47769,29732, -47770,47771,47772,47773,47774,47775,12862,29734,29733,47776,47936,47937,47938, -47939,47940,47941,47942,47943,47944,47945,15406,47946,47947,47948,47949,47950, -47951,47952,47953,47954,47955,47956,47957,47958,47959,47960,47961,47962,47963, -47964,47965,47966,47967,47968,47969,47970,47971,47972,47973,47974,47975,47976, -47977,47978,47979,47980,47981,47982,17239,22881,47983,47984,47985,47986,47987, -47988,16480,29772,22353,47989,47990,47991,47992,47993,47994,47995,47996,47997, -47998,48000,14171,48001,48002,48003,48004,48005,48006,48007,29774,16675,48008, -48009,17993,48010,13398,21811,48011,48012,48013,29776,29775,29777,19290,48014, -48015,29778,48016,21569,22112,48017,48018,48019,48020,14176,48021,48022,48023, -16696,48024,48025,16699,29779,15916,48026,48027,48028,48029,48030,13410,48031, -48032,29780,29781,15915,48192,48193,29782,48194,48195,48196,29787,48197,29783, -29786,48198,14973,48199,29784,29785,48200,48201,48202,48203,48204,48205,48206, -14434,19527,29788,48207,12890,48208,48209,17235,48210,48211,21603,16183,48212, -48213,48214,48215,48216,48217,48218,29789,48219,48220,48221,48222,48223,48224, -17716,48225,48226,48227,48228,48229,48230,48231,48232,29801,48233,48234,20277, -48235,48236,48237,48238,48239,48240,48241,48242,48243,48244,48245,48246,48247, -48248,20041,48249,48250,48251,48252,48253,48254,48256,48257,48258,48259,48260, -48261,48262,48263,48264,48265,48266,48267,48268,48269,48270,19288,48271,19319, -48272,48273,48274,48275,15732,48276,48277,48278,22351,48279,48280,48281,16475, -48282,48283,48284,48285,48286,48287,48288,48448,48449,48450,48451,48452,48453, -48454,48455,48456,48457,48458,48459,48460,48461,48462,48463,48464,48465,48466, -48467,48468,48469,48470,48471,48472,48473,48474,48475,48476,48477,48478,48479, -48480,48481,48482,48483,48484,48485,48486,48487,48488,48489,48490,48491,48492, -48493,48494,48495,48496,48497,48498,48499,48500,48501,48502,20597,48503,48504, -48505,48506,48507,48508,48509,48510,29802,48512,48513,48514,48515,48516,48517, -48518,48519,48520,48521,48522,48523,48524,48525,48526,48527,48528,48529,48530, -48531,48532,48533,48534,48535,48536,48537,48538,48539,48540,48541,48542,48543, -48544,48704,48705,48706,48707,48708,48709,48710,48711,48712,48713,48714,48715, -48716,29803,48717,48718,48719,48720,48721,48722,48723,29804,48724,48725,48726, -48727,48728,48729,48730,48731,48732,48733,48734,48735,48736,48737,48738,48739, -48740,48741,48742,48743,48744,48745,48746,48747,48748,48749,48750,48751,48752, -48753,48754,48755,48756,48757,48758,48759,48760,48761,48762,48763,48764,48765, -48766,48768,48769,48770,48771,48772,48773,48774,48775,48776,48777,48778,48779, -48780,48781,48782,48783,48784,48785,48786,48787,48788,48789,48790,48791,48792, -48793,48794,48795,48796,48797,48798,48799,48800,48960,48961,48962,48963,48964, -48965,48966,48967,48968,48969,48970,48971,48972,48973,48974,48975,48976,48977, -48978,48979,48980,48981,48982,48983,48984,48985,48986,48987,48988,48989,48990, -48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,49001,49002,49003, -49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,49014,49015,49016, -49017,49018,49019,49020,49021,49022,49024,30563,49025,49026,49027,49028,49029, -14129,49030,49031,49032,49033,49034,29805,49035,49036,49037,49038,49039,49040, -49041,49042,49043,49044,49045,49046,49047,49048,49049,49050,49051,49052,49053, -49054,49055,49056,49216,49217,49218,49219,49220,49221,49222,49223,49224,49225, -49226,49227,49228,49229,49230,49231,49232,49233,49234,49235,49236,49237,49238, -49239,49240,49241,49242,49243,49244,49245,49246,49247,49248,49249,49250,49251, -22379,49252,49253,49254,49255,49256,49257,49258,49259,49260,49261,49262,49263, -49264,49265,49266,49267,49268,49269,49270,49271,49272,49273,49274,49275,29806, -49276,49277,49278,26233,15936,26234,14956,26235,20299,26236,21564,15414,26237, -26238,15437,18514,20019,26401,49280,13375,26402,18740,14425,17481,49281,22365, -16986,14167,22077,20038,14148,49282,49283,17702,26403,20319,26404,26405,26406, -16695,22377,18800,20280,22063,22101,26407,12397,26408,26409,18780,21103,15917, -26410,12403,18526,15713,26411,18502,49284,26412,15206,14456,20772,26413,16999, -15992,15690,19763,26414,26415,15982,20581,49285,19303,19536,15436,26416,15400, -20599,26417,49286,20600,26418,26419,13378,26420,26421,18814,20012,17248,26423, -12609,13169,49287,26424,26425,22363,21824,26426,16972,22330,26427,26428,26429, -15466,17253,16450,26430,26431,15401,49288,26432,26433,26422,13904,26434,49289, -26435,26436,15162,13662,16966,12640,26437,21557,26438,14399,26440,26439,14188, -49290,26441,12920,26442,26443,26444,26445,26446,26447,26448,21287,19317,26449, -26450,26451,26452,18761,26453,26454,26455,26456,26457,15689,26458,29502,49291, -14423,49292,18481,49293,49294,49295,49296,49297,49298,49299,29503,49300,29504, -29505,49301,49302,49303,49304,49305,49306,49307,49308,49309,49310,14686,19832, -49311,49312,22632,14897,49472,16990,28215,49473,14115,49474,49475,49476,49477, -28217,49478,28216,12373,49479,49480,49481,49482,49483,28219,21846,22383,49484, -49485,49486,22083,49487,49488,28221,19056,49489,28220,49490,49491,49492,49493, -28222,49494,49495,49496,49497,28224,49498,49499,28223,49500,49501,49502,49503, -49504,49505,49506,49507,20850,49508,18236,49509,17216,49510,49511,49512,49513, -49514,14433,49515,49516,49517,49518,49519,16743,49520,49521,29766,20575,29767, -49522,20315,49523,49524,18490,49525,49526,29768,49527,49528,49529,49530,49531, -49532,49533,29769,29770,49534,29771,49536,49537,49538,49539,49540,22906,14462, -49541,49542,25969,21360,49543,29792,49544,20044,49545,49546,49547,13153,49548, -49549,49550,49551,28980,49552,21102,49553,29793,49554,49555,49556,49557,49558, -20328,29794,49559,49560,18252,49561,49562,49563,49564,49565,49566,13652,13412, -29796,49567,49568,49728,29795,29797,49729,49730,29798,49731,49732,49733,49734, -29799,49735,14898,12351,49736,29800,49737,49738,49739,49740,49741,49742,49743, -14125,21101,49744,49745,49746,21035,16463,49747,16188,27427,21855,27208,49748, -49749,49750,49751,29043,13944,19235,49752,49753,17485,49754,29031,49755,29032, -14459,29033,14916,21573,12370,49756,49757,29034,49758,49759,49760,29035,49761, -29036,49762,49763,29037,29038,29039,29041,29040,17749,49764,49765,49766,49767, -49768,49769,29042,49770,13946,49771,29044,21038,24135,19274,49772,49773,13148, -49774,13602,49775,14626,49776,49777,17524,29045,49778,49779,29046,49780,49781, -49782,16708,16763,22064,29047,49783,49784,49785,49786,29048,49787,16682,49788, -49789,49790,17976,49792,15963,49793,49794,49795,49796,49797,49798,49799,49800, -49801,49802,49803,49804,49805,49806,29049,13391,49807,49808,49809,49810,49811, -49812,29050,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,49823, -49824,49984,27954,27953,49985,49986,19296,21086,49987,19265,21848,49988,18530, -49989,16479,15393,49990,49991,49992,49993,49994,49995,27457,49996,49997,20516, -49998,22114,49999,13895,14424,27456,14414,50000,27455,13094,14665,22059,50001, -14196,14154,50002,50003,50004,15463,14142,27462,50005,27463,12345,16207,50006, -27461,21373,50007,27464,50008,50009,27465,50010,50011,14158,50012,27458,27460, -18806,22103,21837,20530,27471,20024,27472,50013,13608,50014,50015,50016,50017, -50018,12595,27474,19493,50019,50020,50021,50022,50023,50024,50025,17750,27475, -50026,27473,17759,27470,18980,27477,12411,50027,50028,14970,50029,50030,22583, -29027,50031,27466,27467,27468,27469,27478,26176,27481,50032,16232,21064,27479, -27484,14444,27480,50033,15674,50034,20568,50035,12343,50036,27485,17500,50037, -50038,50039,50040,22060,50041,50042,50043,13408,50044,50045,17014,15417,50046, -50048,27482,27483,21600,18026,17492,27487,17703,22901,50049,12849,50050,27492, -50051,15685,50052,50053,50054,27490,50055,50056,50057,50058,50059,50060,50061, -50062,50063,50064,50065,50066,50067,27491,50068,50069,14380,50070,19793,27493, -50071,50072,50073,27489,50074,16691,50075,50076,50077,50078,50079,17954,50080, -50240,50241,50242,50243,50244,50245,19571,50246,27494,50247,16432,21048,27495, -50248,50249,50250,14383,14381,50251,27496,18235,19827,50252,50253,50254,27498, -27499,50255,50256,50257,50258,50259,27501,50260,50261,50262,50263,20552,50264, -27506,50265,27502,50266,50267,50268,27505,18553,50269,20860,27500,50270,50271, -27497,50272,50273,50274,50275,14393,20313,17509,27503,27504,19546,19784,12402, -50276,27510,50277,50278,50279,50280,50281,27509,50282,12850,50283,50284,50285, -50286,14432,50287,27511,50288,50289,50290,50291,50292,50293,12652,50294,50295, -19525,17444,20261,50296,50297,50298,50299,50300,27513,50301,50302,27682,50304, -17778,50305,27514,50306,50307,50308,50309,50310,50311,50312,50313,18757,50314, -50315,50316,50317,50318,50319,25183,27518,50320,50321,50322,50323,19790,27681, -12635,21303,50324,50325,21084,50326,50327,50328,27517,50329,27515,50330,50331, -50332,50333,50334,50335,50336,50496,50497,50498,50499,50500,50501,50502,50503, -50504,50505,50506,50507,50508,50509,50510,13116,50511,50512,50513,27184,50514, -50515,22356,50516,29739,13172,50517,50518,50519,50520,50521,22081,22082,50522, -50523,50524,50525,50526,50527,21865,15946,50528,29735,50529,21032,29736,29737, -50530,29738,15947,21343,50531,50532,50533,50534,50535,18784,18785,50536,50537, -29506,50538,19046,50539,19570,50540,50541,50542,50543,50544,50545,25142,19252, -50546,20072,22107,50547,29741,29742,29743,50548,50549,50550,50551,29746,50552, -14909,29747,12387,29744,50553,29745,15650,12885,50554,29750,29751,13926,12848, -20303,29748,13356,50555,29749,50556,50557,29752,50558,50560,50561,50562,50563, -29753,50564,50565,19751,50566,29754,50567,29755,50568,50569,50570,29756,50571, -50572,50573,50574,50575,50576,50577,50578,19282,50579,29757,50580,50581,50582, -50583,29758,50584,50585,50586,50587,50588,50589,50590,50591,29759,50592,50752, -50753,50754,50755,29790,16700,15464,50756,18731,20830,25973,50757,50758,50759, -50760,23603,21077,50761,50762,23604,12332,23605,50763,50764,15706,50765,23609, -50766,50767,50768,22594,50769,23607,21363,50770,18774,23610,23606,50771,23611, -17186,50772,50773,50774,50775,23612,23621,23613,50776,50777,20063,22053,50778, -23631,50779,23629,50780,50781,23634,15718,16939,50782,23608,23627,23630,23614, -14162,12357,23623,20542,23617,15144,50783,14140,23628,50784,50785,23622,23615, -18267,50786,50787,50788,20799,23616,50789,50790,23626,50791,50792,23632,50793, -50794,20013,23618,50795,23619,23624,23625,12884,23633,19285,50796,21559,23643, -23647,19494,23654,50797,17255,23644,50798,50799,16193,23641,50800,12410,14646, -23653,23635,50801,23620,23638,18548,16224,50802,50803,50804,50805,18747,50806, -50807,50808,12605,50809,21282,50810,50811,23642,50812,50813,23637,50814,17979, -50816,23646,50817,50818,50819,50820,50821,22338,17199,14134,18257,17193,23650, -23640,23659,23636,50822,50823,23645,50824,15909,23639,50825,23648,50826,50827, -23651,23652,50828,23672,50829,50830,23649,23842,23655,50831,50832,50833,50834, -50835,50836,50837,50838,50839,50840,15467,13380,50841,50842,17187,12903,23674, -50843,23666,50844,23663,50845,23676,23662,21104,12904,50846,18519,18531,23675, -50847,23661,50848,51008,51009,23671,51010,51011,23669,51012,51013,15907,23668, -51014,12893,51015,51016,51017,51018,51019,23667,15478,23656,15172,51020,16499, -51021,51022,51023,51024,51025,15444,23657,23658,51026,23665,23670,23673,13620, -51027,18521,15207,23678,23677,21291,23841,23843,23845,21105,23844,23846,23847, -21033,51028,51029,51030,51031,51032,51033,51034,14921,23849,51035,51036,23862, -23857,23860,51037,51038,51039,51040,51041,51042,51043,23856,17998,51044,51045, -16498,51046,51047,51048,51049,18735,51050,51051,51052,23660,23854,51053,51054, -51055,51056,23863,51057,51058,23664,23855,51059,23864,51060,23852,51061,51062, -51063,51064,51065,51066,51067,23865,23859,23853,17450,51068,51069,51070,51072, -23848,16435,16683,23850,23851,51073,23858,15217,23861,21288,23866,51074,23867, -17191,51075,51076,23890,23868,51077,51078,51079,23889,51080,14653,51081,51082, -15957,51083,15994,51084,51085,14922,51086,51087,51088,51089,23882,51090,23877, -51091,23871,51092,51093,51094,12875,23875,51095,23883,12836,23893,51096,51097, -51098,23870,51099,51100,51101,18000,23888,51102,51103,51104,51264,51265,23892, -16738,14150,51266,51267,51268,51269,51270,23886,23887,51271,51272,51273,23876, -51274,51275,51276,23869,51277,23885,19537,51278,23881,51279,51280,51281,51282, -23874,17224,17980,20014,23884,51283,23880,51284,51285,51286,51287,51288,51289, -23873,51290,51291,51292,23878,16988,51293,51294,51295,51296,51297,51298,21289, -21290,23891,20340,18552,51299,51300,51301,51302,51303,51304,51305,51306,23910, -51307,51308,51309,51310,51311,51312,23879,51313,51314,51315,23904,16996,51316, -51317,51318,51319,51320,51321,51322,51323,23905,51324,51325,51326,51328,51329, -51330,51331,51332,51333,51334,23895,51335,51336,51337,51338,51339,22136,51340, -23897,23896,14448,23894,51341,51342,51343,51344,17999,51345,13869,51346,51347, -51348,51349,51350,23906,51351,14969,21601,23911,51352,51353,51354,13392,51355, -23898,51356,16251,23907,51357,23903,51358,23901,51359,51360,51520,51521,51522, -51523,51524,13657,51525,51526,51527,51528,23899,23900,23902,51529,15663,23908, -51530,23909,51531,51532,51533,51534,51535,51536,51537,51538,23925,51539,17225, -51540,51541,19298,51542,51543,51544,51545,23922,51546,51547,51548,51549,51550, -51551,51552,51553,51554,51555,51556,51557,51558,22625,51559,51560,18001,51561, -23924,51562,51563,51564,21876,23923,23920,51565,51566,23916,51567,23919,51568, -23912,51569,51570,20590,51571,51572,51573,51574,18520,23918,51575,51576,23913, -51577,51578,23914,19314,51579,23917,51580,51581,12621,51582,51584,51585,51586, -51587,51588,16438,51589,15419,23921,51590,51591,23927,51592,23926,23915,51593, -51594,51595,51596,51597,17774,51598,51599,51600,23931,51601,51602,51603,51604, -51605,51606,51607,51608,51609,51610,51611,24100,51612,51613,24099,51614,51615, -51616,51776,51777,51778,51779,51780,51781,51782,51783,51784,23928,51785,51786, -51787,51788,17263,51789,17019,51790,51791,51792,21857,51793,51794,20021,51795, -51796,51797,51798,23933,51799,12876,51800,51801,51802,51803,51804,51805,51806, -51807,51808,17512,19039,51809,51810,51811,51812,51813,51814,51815,51816,51817, -51818,18238,23930,23932,23934,24098,12330,12622,51819,51820,51821,51822,51823, -24108,51824,51825,51826,51827,24102,15670,18543,51828,51829,51830,51831,51832, -51833,51834,51835,51836,51837,51838,24097,51840,51841,24101,51842,51843,51844, -51845,24105,51846,51847,51848,51849,51850,24104,51851,51852,51853,24103,51854, -51855,51856,51857,51858,51859,51860,51861,51862,24109,51863,21580,51864,51865, -51866,51867,24115,24106,24110,51868,51869,16473,51870,51871,51872,52032,52033, -12577,24118,52034,24113,52035,52036,52037,52038,52039,52040,52041,24114,52042, -52043,52044,52045,52046,52047,52048,52049,52050,52051,52052,20774,24117,52053, -52054,52055,52056,52057,52058,52059,24111,52060,52061,52062,24112,52063,20541, -52064,52065,52066,24116,19053,24121,52067,52068,52069,52070,52071,52072,24120, -52073,24119,52074,52075,52076,52077,52078,52079,52080,24123,52081,52082,52083, -52084,52085,52086,52087,15717,52088,52089,52090,52091,52092,12888,17258,52093, -52094,24122,52096,17722,52097,52098,52099,52100,52101,52102,24124,52103,52104, -52105,52106,52107,52108,52109,19545,52110,52111,52112,52113,14122,52114,52115, -52116,52117,52118,52119,52120,52121,52122,52123,52124,52125,52126,52127,52128, -52288,52289,21605,52290,52291,52292,24125,52293,52294,52295,52296,52297,24127, -52298,52299,52300,52301,52302,52303,52304,52305,52306,52307,52308,17442,52309, -52310,52311,52312,24129,52313,52314,52315,52316,52317,52318,52319,52320,52321, -52322,52323,52324,52325,52326,52327,52328,24126,52329,24128,52330,52331,52332, -52333,52334,52335,52336,52337,52338,52339,52340,52341,52342,52343,21818,52344, -52345,52346,24130,52347,52348,52349,52350,52352,52353,52354,52355,52356,52357, -52358,52359,52360,52361,52362,52363,29230,15138,16946,17712,16967,52364,52365, -29231,52366,52367,52368,52369,52370,20585,52371,52372,52373,21341,52374,52375, -52376,27453,52377,52378,52379,52380,52381,52382,52383,52384,13158,29232,52544, -29233,52545,52546,18989,52547,52548,52549,52550,52551,52552,52553,14951,29235, -29237,29236,19300,20282,29234,18996,21071,17004,52554,52555,52556,52557,52558, -52559,52560,20035,29240,12406,29239,52561,52562,52563,52564,52565,29246,52566, -12879,52567,52568,52569,52570,52571,52572,20801,29242,52573,52574,52575,52576, -52577,29244,21609,52578,52579,29243,29238,29247,29245,52580,29241,52581,52582, -29255,29252,29254,52583,52584,29258,29250,29248,52585,52586,52587,29253,52588, -52589,52590,52591,52592,22139,52593,52594,52595,29249,52596,18297,18783,52597, -29256,14662,13616,52598,52599,29251,29257,29264,29270,52600,52601,15191,52602, -52603,52604,29269,19804,52605,22123,52606,52608,29266,29268,52609,52610,52611, -52612,14450,52613,52614,52615,52616,29259,52617,52618,52619,29262,17017,52620, -21853,29260,29261,29263,29267,52621,52622,52623,29273,21308,52624,52625,52626, -52627,13930,52628,19057,52629,14180,29271,52630,52631,52632,29272,29274,29277, -29275,52633,52634,29276,52635,52636,52637,52638,20817,29265,52639,19785,52640, -20047,22057,52800,29283,52801,17243,52802,29280,52803,52804,16431,29292,29278, -52805,29281,52806,52807,52808,29288,52809,52810,52811,52812,29282,52813,52814, -29287,52815,52816,29286,52817,52818,29289,52819,52820,52821,29279,52822,52823, -29284,29290,52824,52825,52826,52827,52828,52829,52830,21292,29285,12917,52831, -52832,29298,52833,20523,52834,52835,52836,52837,29301,52838,52839,52840,15176, -52841,29305,52842,52843,52844,52845,52846,52847,29296,52848,52849,29302,29304, -29306,52850,52851,52852,52853,52854,52855,52856,52857,29299,52858,29297,52859, -52860,52861,14971,52862,13691,52864,52865,52866,52867,29295,29303,29293,29294, -52868,52869,52870,29291,29478,52871,29475,52872,52873,29474,52874,52875,29300, -52876,18522,52877,52878,52879,52880,52881,29307,52882,52883,52884,29477,52885, -52886,52887,52888,52889,52890,52891,17272,52892,52893,52894,52895,52896,53056, -53057,53058,29309,53059,53060,29479,29481,29476,53061,29308,53062,53063,53064, -29483,53065,29482,53066,53067,53068,53069,16989,53070,53071,29486,53072,53073, -29488,53074,53075,53076,53077,53078,29473,53079,53080,53081,29489,29484,53082, -53083,53084,53085,53086,29487,29310,29485,53087,53088,53089,53090,53091,53092, -53093,29490,53094,53095,53096,53097,29492,53098,53099,53100,53101,29480,53102, -53103,53104,53105,29491,53106,53107,53108,29493,53109,53110,53111,53112,53113, -53114,53115,53116,53117,53118,20535,53120,53121,53122,53123,29496,53124,53125, -53126,53127,22905,53128,53129,53130,53131,53132,53133,29497,53134,53135,53136, -53137,53138,53139,53140,53141,29495,53142,18532,29494,53143,53144,53145,53146, -29498,53147,53148,53149,53150,53151,29499,13376,53152,53312,53313,53314,53315, -53316,53317,53318,53319,53320,53321,53322,53323,53324,53325,28227,53326,53327, -53328,53329,53330,53331,29500,53332,53333,29501,53334,53335,53336,20778,53337, -53338,53339,29740,20550,53340,53341,53342,53343,53344,53345,20560,20828,53346, -53347,53348,53349,53350,53351,20302,53352,53353,15702,53354,20803,53355,53356, -53357,53358,53359,53360,53361,14946,24937,21058,28994,12857,53362,53363,12653, -28995,53364,18752,13124,53365,22898,53366,19237,53367,28996,53368,53369,53370, -53371,22100,53372,53373,53374,53376,53377,28997,29760,28998,53378,21548,28999, -53379,12352,29761,53380,53381,29762,53382,53383,13436,53384,17755,53385,53386, -53387,53388,19515,53389,53390,53391,20580,53392,53393,53394,53395,53396,19808, -53397,53398,53399,53400,53401,29000,53402,22899,53403,53404,53405,53406,53407, -53408,12603,53568,20270,53569,53570,53571,14372,53572,53573,53574,53575,53576, -29002,53577,53578,53579,53580,29003,53581,53582,53583,53584,12867,16721,53585, -53586,22320,29001,53587,53588,29004,53589,53590,53591,53592,29006,53593,53594, -53595,22902,53596,21089,21539,53597,53598,29763,18489,53599,53600,53601,53602, -53603,29764,53604,53605,29005,29007,16227,29008,53606,53607,29012,53608,53609, -53610,53611,53612,53613,53614,29014,29009,53615,18769,17761,53616,53617,53618, -16995,14716,53619,53620,29011,53621,29013,53622,53623,53624,14675,53625,53626, -53627,53628,53629,53630,53632,29019,53633,53634,53635,53636,53637,14934,53638, -12413,29017,53639,53640,53641,53642,53643,29016,29010,29018,53644,53645,53646, -53647,53648,29015,53649,53650,53651,18540,53652,53653,53654,53655,19786,29021, -53656,53657,53658,53659,25917,53660,53661,53662,29020,53663,29022,53664,53824, -53825,53826,53827,53828,53829,53830,53831,53832,29023,53833,53834,20325,53835, -53836,53837,53838,53839,53840,53841,53842,53843,53844,53845,53846,53847,53848, -53849,53850,53851,53852,53853,53854,53855,53856,53857,53858,53859,29765,15731, -53860,53861,53862,53863,53864,53865,29024,53866,53867,53868,53869,53870,53871, -53872,53873,53874,53875,53876,53877,53878,53879,53880,53881,53882,53883,53884, -53885,29025,53886,53888,53889,20087,53890,21034,53891,29051,53892,53893,14386, -53894,53895,53896,53897,53898,53899,53900,53901,53902,53903,53904,53905,53906, -53907,53908,53909,53910,53911,53912,53913,53914,53915,53916,53917,53918,53919, -53920,54080,54081,54082,54083,54084,54085,54086,54087,54088,54089,54090,54091, -54092,54093,54094,54095,54096,54097,54098,54099,54100,54101,54102,54103,54104, -54105,54106,54107,54108,54109,54110,15483,14683,54111,14694,17241,19027,27240, -16448,15989,27241,27242,27243,54112,27244,27245,27246,27247,15687,54113,54114, -54115,30075,54116,54117,54118,30077,54119,30078,54120,30076,54121,54122,54123, -54124,15714,54125,30241,13349,54126,54127,54128,54129,30242,54130,54131,54132, -30243,54133,54134,54135,27698,54136,54137,54138,54139,54140,54141,54142,54144, -54145,54146,54147,54148,20820,54149,54150,54151,54152,54153,54154,22890,54155, -54156,54157,54158,54159,54160,54161,54162,54163,54164,54165,54166,54167,54168, -54169,54170,54171,54172,54173,54174,54175,54176,54336,54337,54338,54339,54340, -54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,54352,54353, -54354,54355,54356,54357,54358,54359,54360,54361,54362,54363,54364,54365,54366, -54367,30244,54368,54369,54370,54371,54372,54373,54374,54375,54376,28218,54377, -54378,54379,54380,54381,54382,54383,54384,54385,54386,54387,54388,54389,54390, -54391,54392,54393,54394,54395,54396,54397,54398,54400,54401,54402,54403,54404, -54405,54406,54407,54408,54409,54410,54411,54412,54413,54414,54415,54416,54417, -54418,54419,54420,54421,54422,54423,54424,54425,21810,54426,54427,54428,54429, -54430,54431,54432,54592,54593,54594,54595,54596,54597,54598,54599,21374,19548, -54600,54601,54602,54603,54604,54605,54606,54607,19012,54608,54609,54610,54611, -54612,54613,54614,54615,54616,54617,54618,54619,54620,54621,54622,54623,54624, -54625,54626,54627,54628,54629,54630,54631,54632,54633,54634,54635,54636,54637, -54638,54639,54640,54641,54642,54643,54644,54645,54646,54647,54648,54649,54650, -54651,54652,54653,54654,54656,54657,54658,54659,54660,54661,54662,54663,54664, -54665,54666,54667,54668,54669,54670,54671,54672,54673,54674,54675,54676,54677, -54678,54679,54680,54681,54682,54683,54684,54685,54686,54687,54688,54848,54849, -54850,54851,54852,54853,54854,54855,54856,54857,54858,54859,54860,54861,54862, -54863,54864,54865,54866,54867,54868,54869,54870,54871,54872,54873,54874,54875, -54876,54877,54878,54879,54880,54881,54882,25920,54883,54884,54885,54886,54887, -54888,54889,54890,54891,54892,54893,54894,54895,54896,54897,54898,54899,54900, -54901,54902,54903,54904,54905,54906,54907,54908,54909,54910,54912,54913,30245, -54914,54915,54916,54917,54918,54919,54920,54921,54922,54923,54924,54925,54926, -54927,54928,54929,54930,54931,54932,54933,54934,54935,54936,54937,54938,54939, -54940,54941,54942,54943,54944,55104,55105,55106,55107,55108,55109,55110,55111, -55112,55113,55114,55115,55116,55117,55118,55119,55120,55121,55122,55123,55124, -55125,55126,55127,55128,55129,55130,55131,55132,55133,55134,55135,15919,55136, -55137,55138,55139,55140,17961,55141,55142,55143,55144,55145,55146,55147,55148, -55149,55150,55151,55152,55153,55154,55155,55156,55157,55158,55159,55160,55161, -55162,55163,55164,55165,55166,55168,55169,55170,55171,55172,55173,55174,55175, -55176,55177,55178,55179,55180,55181,55182,55183,55184,55185,55186,55187,55188, -55189,55190,55191,55192,23077,15430,13865,14396,18511,15397,23078,23079,19542, -18499,23080,18045,55193,20789,21097,20790,15431,55194,15666,15204,23081,23082, -20808,23083,20589,13935,16987,55195,19279,14189,18792,14147,15991,22052,23084, -23085,17984,22375,18998,55196,21801,19295,21871,23086,22111,13386,23088,23087, -55197,21099,23089,23090,23091,19028,23092,18987,23093,23094,13135,22127,23095, -15152,13614,23096,23097,14702,20783,21096,23098,14403,20330,12911,23099,23100, -55198,15723,20060,21359,23101,20083,23102,21333,15205,23103,19253,19280,23104, -18283,22126,23105,17717,13889,23106,14156,16206,23107,23108,19245,23109,13687, -23110,16706,22331,23111,19512,55199,21098,17457,23112,13693,15185,23113,20531, -23114,23115,20029,23116,23117,23118,12919,23121,23119,20840,23120,17237,23122, -55200,23123,23124,23125,20539,21029,12409,23126,18219,23127,15735,17185,23128, -23129,17277,19511,23130,23131,16446,18007,23132,23133,18228,23134,23135,14664, -55360,55361,55362,55363,55364,55365,55366,55367,55368,15213,55369,55370,55371, -55372,13881,29816,55373,29817,55374,55375,19811,55376,55377,55378,55379,55380, -55381,55382,55383,30009,55384,55385,55386,55387,27488,55388,55389,55390,55391, -55392,55393,20339,15167,55394,55395,55396,55397,55398,55399,55400,14912,21541, -55401,55402,55403,55404,55405,55406,55407,24921,55408,55409,55410,55411,30068, -12586,12914,55412,55413,55414,55415,55416,55417,55418,30069,55419,55420,30071, -55421,55422,55424,14929,30070,55425,17202,55426,55427,55428,55429,55430,55431, -55432,30073,55433,55434,55435,30072,55436,55437,55438,55439,55440,55441,55442, -55443,55444,55445,55446,55447,55448,55449,55450,55451,55452,55453,55454,55455, -55456,55616,55617,55618,55619,55620,55621,55622,55623,55624,55625,55626,55627, -55628,55629,55630,55631,55632,55633,55634,55635,55636,55637,55638,55639,55640, -55641,55642,55643,55644,55645,55646,55647,55648,55649,55650,55651,55652,55653, -55654,55655,55656,55657,55658,55659,55660,55661,55662,55663,55664,55665,55666, -55667,55668,55669,55670,55671,55672,55673,55674,55675,55676,55677,55678,55680, -55681,55682,55683,55684,55685,55686,55687,55688,55689,55690,55691,55692,55693, -55694,55695,55696,55697,55698,55699,55700,55701,55702,55703,55704,55705,55706, -55707,55708,55709,55710,55711,55712,55872,55873,55874,55875,55876,55877,55878, -55879,55880,55881,55882,55883,55884,55885,55886,12596,21866,14394,55887,14641, -12870,21616,20301,12380,21835,15221,22090,14135,19504,17974,12641,14650,22140, -14689,14113,15482,27226,27227,19577,14707,27228,13435,17203,14161,14936,27229, -21620,27230,15446,15199,27231,16734,16952,21599,22346,27232,27233,27236,27234, -27235,18782,14387,13892,27237,19050,18765,13389,55888,55889,25177,17762,27238, -16437,55890,22328,27239,22316,18556,22611,22605,21598,55891,21625,18756,21294, -14419,13152,55892,18786,29814,55893,55894,55895,14933,55896,29815,55897,55898, -22367,55899,55900,29809,14384,21844,14415,18032,55901,55902,55903,55904,55905, -55906,55907,55908,55909,13123,55910,55911,29810,13100,55912,55913,55914,55915, -21565,18295,55916,55917,55918,55919,55920,29812,55921,55922,29811,55923,55924, -55925,55926,55927,55928,55929,55930,55931,55932,19531,55933,55934,55936,18468, -55937,55938,55939,55940,55941,55942,55943,55944,55945,55946,55947,55948,55949, -29813,55950,22371,17727,30016,55951,55952,30011,55953,30019,55954,30018,55955, -22074,30017,55956,55957,55958,21566,30020,55959,30028,55960,55961,55962,55963, -12367,13688,55964,30025,30026,55965,17756,55966,55967,55968,56128,30021,30022, -56129,56130,30023,30027,56131,15968,30024,14458,56132,56133,56134,30032,30035, -56135,56136,56137,16231,56138,14706,30012,30029,56139,56140,16951,56141,56142, -56143,19576,56144,15481,56145,30030,30031,30033,13925,30034,56146,30037,56147, -56148,56149,56150,56151,56152,56153,30013,56154,56155,56156,30036,21307,56157, -13164,56158,56159,19492,56160,56161,56162,56163,30038,56164,56165,56166,56167, -56168,56169,56170,56171,30039,15969,30040,56172,56173,19551,30043,56174,56175, -56176,56177,56178,12872,22361,56179,30041,56180,30042,30044,56181,30050,56182, -56183,56184,30048,56185,56186,56187,30047,30045,56188,56189,30049,56190,56192, -30046,30052,30053,56193,19555,56194,56195,25919,13624,30051,30056,19491,56196, -56197,56198,56199,56200,30054,30055,56201,56202,56203,56204,56205,56206,30014, -56207,56208,56209,56210,56211,56212,56213,56214,56215,56216,56217,56218,12612, -56219,56220,30015,56221,56222,13637,12900,56223,30060,30057,56224,13911,56384, -30061,56385,30058,56386,56387,56388,56389,56390,30059,56391,56392,13402,56393, -21610,56394,56395,56396,30062,56397,13177,56398,56399,56400,56401,56402,56403, -56404,30063,30065,56405,56406,56407,30064,56408,56409,56410,56411,56412,56413, -56414,30066,56415,30067,56416,56417,56418,56419,56420,56421,56422,56423,56424, -56425,56426,56427,18797,14634,56428,56429,18299,56430,56431,13923,56432,56433, -56434,56435,56436,56437,56438,19529,56439,56440,56441,56442,56443,56444,56445, -56446,56448,56449,56450,56451,56452,56453,56454,56455,56456,56457,56458,27174, -56459,56460,56461,56462,56463,56464,56465,56466,56467,56468,56469,56470,56471, -56472,56473,56474,56475,56476,56477,56478,56479,56480,56640,56641,56642,56643, -56644,56645,56646,56647,56648,56649,56650,56651,56652,56653,56654,56655,56656, -56657,56658,56659,56660,56661,56662,56663,56664,56665,56666,56667,56668,56669, -56670,56671,56672,56673,56674,56675,56676,56677,56678,56679,56680,56681,56682, -56683,56684,56685,56686,56687,56688,56689,56690,56691,56692,56693,56694,56695, -56696,56697,56698,56699,56700,56701,56702,56704,56705,56706,56707,56708,56709, -56710,56711,56712,56713,56714,56715,56716,56717,56718,56719,56720,56721,56722, -56723,56724,56725,56726,56727,56728,56729,56730,56731,56732,56733,56734,56735, -56736,56896,56897,56898,56899,56900,56901,56902,56903,56904,56905,56906,56907, -56908,56909,56910,56911,56912,56913,56914,56915,56916,56917,56918,56919,56920, -56921,56922,56923,56924,56925,56926,56927,56928,13109,21630,14700,20601,56929, -26989,22314,26990,16982,18541,14948,26991,26992,26993,22113,26994,26995,26997, -26996,26998,26999,18273,27000,21592,27001,15694,56930,27002,27003,15695,27004, -14376,16702,27005,12594,15188,14709,27006,56931,27169,27170,27171,14200,15405, -56932,19044,24654,21551,20285,21815,27172,21854,27173,20545,14652,56933,13383, -12633,56934,56935,56936,16433,56937,56938,56939,56940,12646,12647,56941,12648, -56942,56943,56944,56945,13117,18536,56946,56947,56948,56949,25921,56950,56951, -12639,56952,56953,56954,16713,13423,56955,56956,18216,21336,56957,18041,20792, -56958,14717,17013,56960,56961,56962,56963,56964,21293,56965,21579,15740,56966, -25922,14133,25923,56967,56968,15161,21858,56969,15736,21558,20005,16684,13145, -56970,56971,19574,56972,25926,25924,25928,56973,25930,25927,13647,17992,56974, -13692,25925,56975,19062,56976,56977,25929,56978,56979,56980,17236,12613,15395, -56981,56982,56983,22327,56984,56985,19787,19277,19018,19539,25932,25931,17510, -56986,56987,20769,20791,25933,56988,25936,56989,19768,22128,25935,13661,56990, -19774,56991,25937,13882,56992,57152,19752,14692,57153,19013,13137,19289,21612, -25938,14186,57154,57155,57156,25934,57157,57158,57159,57160,57161,57162,25941, -13438,25942,57163,57164,57165,57166,57167,25939,25940,57168,21085,57169,57170, -16991,12614,57171,21346,57172,57173,13917,19308,57174,25943,57175,57176,21366, -57177,57178,57179,57180,57181,12649,57182,13940,25946,25944,25945,13632,57183, -57184,57185,21061,25948,57186,57187,25950,57188,57189,57190,57191,57192,57193, -25949,18226,57194,21027,57195,57196,25947,57197,57198,57199,57200,21602,21850, -57201,57202,57203,57204,57205,25952,22385,57206,57207,57208,57209,57210,57211, -57212,25953,57213,12636,20859,57214,25954,25956,57216,57217,57218,57219,25955, -57220,57221,25957,57222,57223,57224,57225,57226,21080,57227,13643,57228,26463, -57229,23157,57230,23160,57231,23158,57232,23159,57233,57234,57235,23162,20559, -17479,57236,57237,12398,57238,57239,57240,20528,57241,23161,57242,21322,14890, -23330,18289,57243,23164,23163,18779,23165,57244,23329,22366,23166,16730,57245, -57246,23333,57247,57248,21364,57408,57409,23335,23332,57410,23336,57411,57412, -15676,57413,57414,57415,16457,23331,23334,22051,57416,23337,57417,57418,57419, -23341,57420,57421,57422,23342,23340,14914,57423,57424,57425,16164,23339,57426, -57427,57428,23338,21575,12863,57429,57430,23343,57431,14713,57432,23344,57433, -57434,57435,57436,13115,57437,57438,57439,13606,57440,57441,57442,57443,13884, -23345,57444,57445,57446,13941,57447,23346,57448,57449,57450,57451,57452,57453, -57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,57466, -57467,12617,57468,57469,57470,57472,23348,57473,57474,57475,23347,23349,57476, -57477,57478,57479,57480,57481,57482,57483,57484,57485,57486,23351,57487,23350, -57488,57489,57490,57491,57492,57493,57494,23352,57495,57496,57497,57498,57499, -57500,57501,57502,57503,23353,57504,57664,23354,57665,57666,21327,29818,18293, -22339,17764,29820,29821,29819,57667,15942,57668,57669,57670,57671,20591,57672, -57673,14163,57674,57675,21581,19498,57676,57677,29986,29985,14888,29822,19286, -57678,57679,57680,29988,16466,57681,13162,57682,19754,29989,29987,15668,29992, -57683,29993,15693,17208,16225,19297,29994,57684,57685,57686,29990,29991,17520, -57687,57688,57689,57690,57691,29996,57692,13372,57693,22381,57694,13399,29995, -29998,57695,57696,29997,29999,20561,57697,57698,57699,57700,57701,57702,57703, -17233,18473,57704,57705,57706,57707,57708,57709,30000,30001,57710,57711,57712, -57713,57714,57715,30002,57716,57717,30003,30004,30005,57718,57719,57720,57721, -30007,30006,57722,57723,57724,57725,30008,57726,57728,57729,57730,57731,57732, -57733,57734,57735,57736,57737,57738,12873,57739,21332,19021,57740,16495,22104, -21040,16703,57741,15728,57742,57743,57744,57745,57746,57747,57748,57749,57750, -57751,14378,57752,57753,57754,57755,57756,57757,57758,57759,57760,57920,57921, -57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934, -57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947, -57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960, -57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973, -57974,57975,57976,57977,57978,57979,57980,57981,57982,57984,57985,57986,57987, -57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998,57999,58000, -58001,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011,58012,58013, -58014,58015,58016,58176,58177,58178,58179,58180,58181,58182,58183,58184,58185, -58186,58187,58188,58189,58190,58191,58192,58193,58194,58195,58196,58197,58198, -58199,58200,58201,58202,58203,58204,58205,58206,58207,58208,58209,58210,58211, -58212,58213,58214,58215,58216,58217,58218,58219,58220,58221,15480,58222,58223, -58224,58225,58226,58227,58228,58229,58230,58231,58232,58233,58234,58235,58236, -58237,58238,58240,58241,58242,58243,58244,58245,58246,58247,30278,58248,58249, -58250,58251,58252,58253,58254,58255,58256,58257,58258,58259,58260,58261,58262, -58263,58264,58265,58266,58267,58268,58269,58270,58271,58272,58432,58433,58434, -58435,58436,58437,30279,58438,58439,58440,58441,58442,58443,58444,58445,58446, -58447,58448,58449,58450,58451,58452,58453,58454,58455,58456,58457,58458,58459, -58460,58461,58462,30280,58463,58464,58465,58466,58467,58468,58469,58470,58471, -58472,58473,58474,58475,58476,58477,58478,58479,58480,58481,58482,58483,58484, -58485,58486,58487,58488,58489,58490,58491,58492,58493,58494,58496,58497,58498, -58499,58500,58501,58502,58503,58504,58505,58506,58507,58508,58509,58510,58511, -58512,58513,58514,58515,58516,58517,58518,58519,58520,58521,58522,58523,58524, -58525,58526,58527,58528,58688,58689,58690,58691,58692,58693,58694,58695,58696, -58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707,58708,58709, -58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720,58721,58722, -58723,58724,58725,58726,58727,58728,58729,58730,58731,58732,58733,58734,58735, -58736,58737,58738,58739,30281,58740,58741,58742,58743,58744,58745,58746,58747, -58748,58749,58750,58752,58753,58754,58755,58756,58757,58758,58759,58760,58761, -58762,58763,58764,58765,58766,58767,58768,58769,58770,58771,58772,58773,58774, -58775,58776,58777,58778,58779,58780,58781,58782,58783,30282,58784,58944,58945, -58946,58947,58948,58949,58950,58951,58952,58953,58954,58955,58956,58957,58958, -58959,58960,58961,58962,58963,58964,58965,58966,58967,58968,58969,58970,58971, -58972,58973,58974,58975,58976,58977,58978,30284,58979,58980,58981,58982,58983, -58984,58985,58986,58987,58988,58989,58990,58991,58992,58993,58994,58995,58996, -58997,58998,58999,59000,59001,59002,59003,59004,59005,59006,59008,59009,59010, -59011,59012,59013,59014,59015,59016,59017,59018,59019,59020,59021,59022,59023, -59024,59025,59026,59027,59028,59029,59030,59031,59032,59033,59034,59035,59036, -59037,30283,59038,59039,59040,59200,59201,59202,59203,59204,59205,59206,59207, -30569,59208,59209,59210,59211,59212,59213,59214,59215,59216,59217,59218,59219, -59220,59221,59222,59223,59224,59225,59226,59227,59228,59229,59230,59231,59232, -59233,59234,59235,59236,59237,59238,59239,59240,59241,59242,59243,59244,59245, -59246,59247,59248,59249,59250,59251,59252,59253,59254,59255,59256,59257,59258, -59259,59260,59261,59262,59264,59265,59266,59267,59268,59269,59270,59271,59272, -59273,59274,59275,59276,59277,59278,59279,59280,59281,59282,59283,59284,59285, -59286,59287,59288,59289,59290,59291,59292,59293,59294,59295,59296,59456,59457, -59458,59459,59460,59461,59462,59463,59464,59465,59466,59467,59468,59469,59470, -30285,59471,59472,59473,59474,59475,59476,59477,59478,59479,59480,59481,59482, -59483,59484,59485,59486,59487,59488,59489,59490,59491,59492,59493,59494,59495, -59496,59497,59498,59499,59500,59501,59502,59503,59504,59505,59506,59507,59508, -59509,59510,59511,59512,59513,59514,30286,59515,59516,59517,59518,59520,59521, -59522,59523,59524,59525,59526,59527,59528,59529,59530,59531,59532,59533,59534, -59535,59536,59537,59538,59539,59540,28228,28229,28230,21867,13860,28232,28231, -28233,28234,18213,28235,28236,59541,14128,13686,28237,28239,59542,28238,59543, -14406,28240,28241,28242,13915,13102,22099,17478,12597,14422,28243,28244,21567, -18261,15995,20057,14643,28246,28245,28248,28247,17701,28249,28250,18222,28251, -18223,28252,12839,28253,28254,28255,28256,28257,22378,28258,28259,15448,28260, -21323,19578,12844,16741,28261,18214,17197,59544,28262,28263,28264,28265,28266, -28267,28268,59545,28269,28270,28271,59546,59547,28272,28273,28274,28276,28275, -59548,28277,19757,16961,28278,28279,28280,21793,28281,20275,28282,28283,59549, -28284,28285,28449,28286,28450,14453,17274,28451,28452,15682,21055,12921,28453, -28454,28455,21112,28456,22141,28457,17996,59550,28458,28459,16692,28460,20346, -19320,28462,28461,13178,14712,28463,28464,20578,28465,28466,14182,20543,28467, -28468,28469,18545,19552,28470,28471,28472,28473,28474,21856,28475,13421,17194, -28476,59551,28477,28478,28479,59552,20093,28480,16992,13368,22326,15733,59712, -20295,28483,28481,28482,28484,13863,15484,15970,17228,28485,28486,59713,28487, -28495,28488,28489,28490,18242,28529,13901,28491,59714,28492,28493,13894,17214, -28494,59715,28496,28497,28498,21874,59716,28499,17527,59717,28500,17528,28501, -28502,14436,12407,28503,28504,28505,59718,28506,28507,28508,28509,59719,28510, -15925,28513,28511,28512,59720,28514,28515,16717,28516,28517,28518,28519,28520, -28521,28522,28523,28524,16472,59721,28525,16685,28526,28527,28528,59722,59723, -20322,59724,59725,59726,59727,59728,59729,59730,59731,13092,59732,59733,59734, -59735,59736,59737,59738,59739,59740,59741,59742,59743,59744,59745,59746,59747, -59748,59749,59750,59751,59752,59753,59754,59755,59756,59757,59758,59759,59760, -59761,59762,59763,59764,59765,59766,59767,59768,59769,59770,59771,59772,59773, -59774,59776,59777,59778,59779,59780,59781,59782,59783,59784,59785,59786,59787, -59788,59789,59790,59791,59792,59793,59794,59795,59796,59797,59798,59799,59800, -59801,59802,59803,59804,59805,59806,59807,59808,59968,59969,59970,59971,59972, -59973,59974,59975,59976,59977,59978,59979,59980,59981,59982,59983,59984,59985, -59986,59987,59988,59989,59990,59991,59992,59993,59994,59995,17221,25413,18753, -25414,59996,12629,20042,13363,18546,25415,20304,25416,15460,25417,25418,17222, -21794,17494,14699,20037,25419,17270,25420,59997,14119,14451,14930,25421,25422, -21572,25423,59998,25424,20811,25425,25426,25427,25428,20822,25429,12923,16443, -25430,59999,16427,25431,25432,25433,60000,25434,25435,60001,14391,23138,60002, -13907,60003,23140,23139,60004,60005,60006,60007,60008,60009,60010,23142,60011, -60012,60013,18542,60014,60015,23141,14144,20852,21109,21875,15703,60016,60017, -60018,60019,22376,23144,23143,60020,12322,19795,60021,23145,60022,14397,15434, -16957,16932,13122,23146,60023,16938,17456,15669,60024,60025,20318,60026,60027, -60028,23147,18754,60029,60030,60032,60033,60034,12637,60035,60036,60037,23148, -60038,13880,21562,60039,13181,60040,60041,23149,21577,20309,17763,60042,23150, -60043,60044,60045,60046,60047,23151,60048,23152,16746,19541,20317,60049,60050, -60051,60052,60053,60054,60055,60056,60057,60058,60059,60060,60061,21351,16929, -60062,23153,60063,60064,19301,60224,23154,60225,19302,21118,60226,60227,60228, -14452,60229,60230,23155,12335,20278,60231,60232,21839,60233,60234,60235,60236, -60237,60238,60239,60240,60241,60242,19309,60243,60244,60245,60246,60247,60248, -60249,60250,23156,60251,60252,25412,60253,60254,16677,60255,60256,30271,60257, -60258,30272,30273,17489,60259,18488,20835,60260,60261,20571,20805,15407,14669, -60262,28532,60263,60264,13382,21306,30274,13179,60265,60266,30275,60267,60268, -13681,60269,60270,60271,60272,60273,60274,60275,60276,60277,60278,30277,60279, -60280,60281,60282,60283,60284,60285,21354,30247,20777,60286,60288,60289,60290, -30249,60291,60292,60293,30248,60294,60295,16739,16471,60296,12578,60297,60298, -60299,60300,20077,60301,20584,30251,60302,60303,20342,60304,30250,21872,30252, -17209,60305,60306,60307,15220,30254,30253,60308,60309,60310,17502,60311,60312, -16728,60313,60314,60315,60316,60317,19242,60318,20284,60319,60320,60480,60481, -60482,60483,60484,60485,60486,60487,60488,30255,60489,60490,30256,60491,60492, -30257,60493,16950,60494,60495,60496,60497,60498,12372,17785,60499,60500,60501, -60502,30258,60503,60504,60505,60506,60507,60508,60509,60510,60511,60512,60513, -60514,60515,60516,60517,60518,60519,60520,60521,18272,30246,60522,60523,15928, -60524,60525,15922,60526,13669,60527,60528,14151,60529,16191,17234,17254,60530, -60531,22604,60532,60533,60534,14447,60535,60536,60537,60538,60539,60540,60541, -60542,60544,15737,20773,60545,12368,60546,60547,60548,60549,60550,30512,60551, -60552,60553,60554,60555,60556,60557,60558,30513,60559,60560,60561,60562,60563, -20524,60564,12336,60565,60566,60567,30514,30515,60568,30516,60569,60570,60571, -18250,60572,60573,60574,60575,60576,60736,60737,15951,60738,60739,30519,60740, -60741,60742,60743,60744,60745,60746,30518,60747,12638,60748,30517,60749,60750, -30520,60751,30521,60752,60753,60754,60755,60756,60757,60758,60759,60760,60761, -60762,60763,60764,60765,60766,60767,60768,60769,60770,60771,60772,60773,60774, -60775,60776,60777,60778,60779,60780,60781,60782,60783,60784,60785,60786,60787, -60788,60789,60790,60791,60792,60793,60794,60795,60796,60797,60798,60800,60801, -20004,18509,60802,14891,26680,26681,26682,15938,60803,60804,60805,60806,60807, -21108,60808,21583,18776,60809,60810,60811,60812,60813,60814,60815,60816,60817, -60818,60819,60820,60821,60822,60823,60824,60825,60826,60827,60828,60829,60830, -60831,60832,60992,60993,60994,60995,60996,60997,60998,60999,61000,61001,61002, -61003,61004,61005,61006,61007,61008,61009,61010,61011,61012,61013,61014,61015, -61016,61017,61018,61019,61020,61021,61022,61023,61024,61025,61026,61027,61028, -61029,61030,61031,61032,61033,61034,61035,61036,61037,61038,61039,61040,61041, -61042,61043,61044,61045,61046,61047,61048,61049,61050,61051,61052,61053,61054, -61056,61057,61058,61059,61060,61061,61062,61063,61064,61065,61066,61067,61068, -61069,61070,61071,61072,61073,61074,61075,61076,61077,61078,61079,61080,61081, -61082,61083,61084,61085,61086,61087,61088,61248,61249,61250,61251,61252,61253, -21043,13861,18282,29052,20334,19251,20587,26479,19815,14667,13913,29053,12388, -19276,29054,21540,16941,16748,17988,15921,29217,15445,61254,29218,29219,61255, -29220,21059,17973,61256,19783,29221,61257,21297,16197,19554,61258,29222,29223, -20821,13934,29224,29225,13663,29226,29227,61259,12924,29228,29229,18471,61260, -61261,61262,61263,61264,61265,61266,61267,61268,61269,61270,61271,61272,61273, -61274,61275,61276,61277,61278,61279,61280,61281,61282,61283,61284,61285,61286, -61287,61288,61289,61290,61291,61292,61293,61294,61295,61296,61297,14183,61298, -61299,27689,27690,27691,61300,27692,61301,61302,17966,27693,27694,61303,61304, -61305,14153,18995,61306,61307,61308,61309,61310,61312,61313,25144,30543,61314, -61315,61316,61317,61318,61319,61320,61321,61322,61323,61324,61325,61326,61327, -61328,61329,61330,61331,61332,61333,61334,61335,61336,61337,61338,61339,61340, -61341,61342,61343,61344,61504,61505,61506,61507,61508,30544,61509,61510,12877, -61511,61512,61513,61514,61515,61516,61517,61518,61519,61520,61521,61522,61523, -61524,61525,61526,61527,61528,61529,61530,61531,61532,61533,61534,61535,61536, -61537,61538,61539,30545,61540,61541,61542,61543,61544,61545,61546,61547,61548, -61549,61550,61551,61552,61553,61554,61555,61556,61557,61558,61559,61560,61561, -61562,61563,61564,61565,61566,61568,61569,61570,61571,61572,61573,61574,61575, -61576,61577,30547,30546,61578,61579,61580,61581,61582,61583,61584,61585,61586, -61587,61588,61589,61590,25147,61591,15394,61592,25148,25149,25150,25151,25152, -25153,14137,21115,15652,19022,12581,19271,61593,25154,13948,18500,25155,61594, -61595,15688,61596,12669,25156,61597,13942,25157,17497,61598,61599,25158,20314, -14685,25159,16417,61600,25160,12918,61760,25161,61761,16755,25162,25163,17016, -25164,25165,25166,19031,22584,22885,20323,61762,61763,61764,61765,61766,61767, -61768,61769,61770,61771,61772,28709,61773,61774,23600,61775,61776,61777,61778, -61779,61780,61781,61782,61783,61784,61785,61786,61787,61788,61789,61790,61791, -61792,61793,61794,61795,61796,61797,61798,61799,61800,61801,61802,61803,61804, -61805,61806,61807,61808,61809,61810,61811,61812,61813,61814,61815,61816,61817, -61818,61819,61820,61821,61822,61824,61825,61826,61827,61828,61829,61830,61831, -61832,61833,61834,61835,61836,61837,61838,61839,61840,61841,61842,61843,61844, -61845,61846,61847,61848,61849,61850,61851,61852,61853,61854,61855,61856,62016, -62017,62018,62019,62020,62021,62022,62023,62024,62025,62026,62027,62028,62029, -62030,62031,62032,62033,62034,62035,62036,62037,62038,62039,62040,62041,62042, -62043,62044,62045,62046,62047,62048,62049,62050,62051,62052,62053,62054,62055, -62056,62057,62058,62059,62060,62061,62062,62063,62064,62065,62066,62067,62068, -62069,62070,62071,62072,62073,62074,62075,62076,62077,62078,62080,62081,62082, -62083,62084,62085,62086,62087,62088,62089,62090,62091,62092,62093,62094,62095, -62096,62097,62098,62099,62100,62101,62102,62103,62104,62105,62106,62107,62108, -62109,62110,62111,62112,62272,62273,62274,62275,62276,62277,62278,62279,62280, -62281,62282,62283,62284,62285,62286,62287,62288,62289,17005,21542,19796,20785, -13147,18301,62290,12853,16959,26208,19003,26209,26210,15956,26211,22308,19797, -26213,15453,26212,26214,26215,17006,62291,15678,26216,16998,14887,26217,62292, -26218,13138,20841,62293,62294,16165,26219,18031,26220,26221,62295,62296,26222, -17965,26223,62297,18727,26224,26225,26226,25913,26227,26228,16994,26229,26230, -22120,26231,62298,26232,14663,62299,62300,62301,62302,62303,62304,62305,30523, -30522,62306,62307,62308,62309,30526,30524,14881,62310,30527,62311,30528,62312, -62313,62314,30530,30529,30532,62315,62316,30531,62317,62318,62319,62320,62321, -30533,30534,62322,62323,62324,62325,30535,62326,19304,62327,62328,62329,62330, -14431,62331,62332,62333,62334,62336,62337,30548,62338,30549,62339,62340,62341, -62342,30550,62343,62344,62345,62346,30552,62347,30554,62348,30551,62349,62350, -62351,62352,62353,62354,62355,62356,62357,30555,62358,30553,62359,62360,62361, -62362,62363,62364,62365,22359,62366,62367,62368,62528,30556,62529,62530,62531, -62532,62533,62534,30557,62535,62536,62537,30558,62538,62539,62540,62541,62542, -62543,62544,62545,62546,62547,62548,30559,62549,62550,62551,30560,62552,62553, -62554,62555,62556,62557,62558,62559,62560,62561,62562,23371,62563,62564,22570, -62565,62566,62567,62568,62569,62570,62571,62572,25975,14701,62573,62574,62575, -62576,16253,15210,30537,17991,30536,62577,30538,30540,30539,62578,62579,62580, -30541,62581,20026,62582,30542,62583,62584,17447,62585,62586,62587,62588,62589, -62590,62592,62593,62594,62595,62596,62597,62598,62599,62600,62601,62602,62603, -62604,62605,62606,62607,62608,62609,62610,62611,62612,62613,62614,62615,62616, -62617,62618,62619,62620,62621,62622,62623,62624,62784,62785,62786,62787,62788, -62789,62790,62791,62792,62793,62794,62795,62796,62797,62798,62799,62800,62801, -62802,62803,62804,62805,62806,62807,62808,62809,62810,62811,62812,62813,62814, -62815,62816,62817,62818,62819,62820,62821,62822,62823,62824,62825,62826,62827, -62828,62829,62830,62831,62832,62833,62834,62835,62836,62837,62838,62839,62840, -62841,62842,62843,62844,62845,62846,62848,62849,62850,62851,62852,62853,62854, -62855,62856,62857,62858,62859,62860,62861,62862,62863,62864,62865,62866,62867, -62868,62869,62870,62871,62872,62873,62874,62875,62876,62877,62878,62879,62880, -63040,63041,63042,63043,63044,63045,63046,63047,63048,63049,63050,63051,63052, -63053,63054,63055,63056,63057,63058,63059,63060,63061,63062,63063,63064,63065, -63066,63067,63068,63069,63070,63071,63072,63073,63074,63075,63076,63077,63078, -63079,63080,63081,63082,63083,63084,63085,63086,63087,63088,63089,63090,63091, -63092,63093,63094,63095,63096,63097,63098,63099,63100,63101,63102,63104,63105, -63106,63107,63108,63109,63110,63111,63112,63113,63114,63115,63116,63117,63118, -63119,63120,63121,63122,63123,63124,63125,63126,63127,63128,63129,63130,63131, -63132,63133,63134,63135,63136,63296,63297,63298,63299,63300,63301,63302,63303, -63304,63305,63306,63307,63308,63309,63310,63311,63312,63313,63314,63315,63316, -63317,63318,63319,63320,63321,63322,63323,63324,63325,63326,63327,63328,63329, -63330,63331,63332,63333,63334,63335,63336,63337,63338,63339,63340,63341,63342, -63343,63344,63345,63346,63347,63348,63349,63350,63351,63352,63353,63354,63355, -63356,63357,63358,63360,21347,63361,63362,30287,63363,16947,30288,63364,63365, -30289,30290,30291,30292,63366,63367,30294,63368,12587,30295,63369,30296,30297, -30298,63370,30299,30300,63371,63372,63373,63374,30301,30302,20298,63375,30303, -30304,30305,30306,30307,30308,16496,30309,30310,30311,30312,30313,63376,30314, -63377,30315,30316,63378,30317,30318,30319,30320,30321,30322,30323,30324,15912, -63379,30325,30326,30327,30328,63380,63381,63382,63383,63384,18554,30329,30330, -30331,30332,63385,63386,30333,30334,30497,30498,30499,30500,30501,63387,63388, -30502,30503,30504,12654,30505,30506,30507,63389,63390,30508,30509,16731,30510, -63391,63392,30511,63552,63553,63554,63555,63556,63557,63558,63559,63560,63561, -63562,63563,63564,63565,63566,63567,63568,63569,63570,63571,63572,63573,63574, -63575,63576,63577,63578,63579,63580,63581,63582,63583,63584,63585,63586,63587, -63588,63589,63590,63591,63592,63593,63594,63595,63596,63597,63598,63599,63600, -63601,63602,63603,63604,63605,63606,63607,63608,63609,63610,63611,63612,63613, -63614,63616,63617,63618,63619,63620,63621,63622,63623,63624,63625,63626,63627, -63628,63629,63630,63631,63632,63633,63634,63635,63636,63637,63638,63639,63640, -63641,63642,63643,63644,63645,63646,63647,63648,63808,63809,63810,63811,63812, -63813,63814,63815,63816,63817,63818,63819,63820,63821,63822,63823,63824,63825, -63826,63827,63828,63829,63830,63831,63832,63833,63834,63835,63836,63837,63838, -63839,63840,63841,63842,63843,63844,63845,63846,63847,63848,63849,63850,63851, -63852,63853,63854,63855,63856,63857,63858,63859,63860,63861,63862,63863,63864, -63865,63866,63867,63868,63869,63870,63872,63873,63874,63875,63876,63877,63878, -63879,63880,63881,63882,63883,63884,63885,63886,63887,63888,63889,63890,63891, -63892,63893,63894,63895,63896,63897,63898,63899,63900,63901,63902,63903,63904, -64064,64065,64066,64067,64068,64069,64070,64071,64072,64073,64074,64075,64076, -64077,64078,64079,64080,64081,64082,64083,64084,64085,64086,64087,64088,64089, -64090,64091,64092,64093,64094,64095,64096,64097,64098,64099,64100,64101,64102, -64103,64104,64105,64106,64107,64108,64109,64110,64111,64112,64113,64114,64115, -64116,64117,64118,64119,64120,64121,64122,64123,64124,64125,64126,64128,64129, -64130,64131,64132,64133,64134,64135,64136,64137,64138,64139,64140,64141,64142, -64143,64144,64145,64146,64147,64148,64149,64150,64151,64152,64153,64154,64155, -64156,64157,64158,64159,64160,64320,64321,64322,64323,64324,64325,64326,64327, -64328,64329,64330,64331,64332,64333,64334,64335,64336,64337,64338,64339,64340, -64341,64342,64343,64344,64345,64346,64347,17521,28719,15398,28720,17273,64348, -17720,20795,64349,28721,28722,28723,28724,28725,20796,64350,20844,64351,28727, -28726,21543,64352,19794,28728,28730,28729,28731,28732,64353,64354,14443,28733, -14952,64355,28734,28735,15977,28736,13932,28737,28738,28739,28740,18485,28741, -28742,64356,28743,17780,64357,28744,64358,64359,64360,28745,64361,28746,30525, -64362,28747,28748,28749,64363,28750,64364,64365,64366,64367,28751,14935,64368, -28752,28753,28754,28755,28756,28757,28758,28760,64369,64370,21285,28759,64371, -28761,64372,64373,64374,64375,64376,64377,64378,64379,64380,64381,30010,16953, -64382,64384,30564,64385,64386,64387,64388,30565,30566,64389,64390,30567,64391, -64392,64393,64394,64395,64396,30568,16948,64397,64398,64399,64400,64401,64402, -64403,64404,64405,30570,64406,30571,64407,64408,64409,64410,64411,64412,17011, -64413,64414,64415,64416,64576,64577,64578,64579,64580,64581,64582,64583,64584, -29808,64585,64586,64587,29807,64588,64589,17001,64590,30561,30562,64591,64592, -64593,64594,64595,15174,64596,64597,64598,64599,22884,64600,64601,64602,19058, -16488,28708,64603,14938,64604,64605,18221,64606,64607,64608,17452,64609,64610, -30572,30573,30574,64611,30576,30575,64612,30577,64613,64614,30580,64615,30579, -64616,30578,30581,64617,64618,64619,64620,30582,64621,64622,64623,64624,64625, -64626,64627,64628,64629,28009,64630,28010,28011,64631,30268,64632,64633,64634, -64635,64636,64637,64638,64640,64641,64642,64643,64644,30269,64645,30270,13862, -64646,22590,64647,64648,14660,64649,64650,64651,22587,64652,23601,64653,64654, -64655,64656,64657,64658,19059,64659,30583,64660,64661,64662,64663,64664,64665, -64666,64667,64668,30584,64669,64670,30585,64671,64672,64832,64833,64834,64835, -64836,30587,64837,30586,64838,12615,64839,30588,30589,64840,64841,64842,64843, -64844,30590,64845,64846,64847,64848,64849,64850,64851,64852,64853,64854,64855, -18027,27700,64856,64857,64858,64859,64860,64861,64862,64863,64864,64865,64866, -64867,64868,64869,64870,64871,64872,64873,64874,64875,64876,64877,64878,64879, -64880,64881,64882,64883,64884,64885,64886,64887,64888,64889,64890,64891,64892, -64893,64894,64896,64897,64898,64899,64900,64901,13149,30259,64902,64903,30260, -16740,30261,30262,30263,30264,30265,30266,18467,30267,64904,64905,64906,64907, -64908,64909,64910,64911,64912,64913,64914,64915,16762,14632,28008,64916,64917, -64918,14698,22879,64919,64920,64921,64922,64923,64924,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64925,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64927,N,N,N,N,N,N,N,N,N,64928, -65088,65089,65090,65091,N,65092,N,65093,65094,N,N,N,65095,N,N,N,N,N,N,65096, -65097,65098,N,65099,65100,N,N,65101,65102,65103,43349,42738,N,42740,42741, -42720,42721,42736,42737,42722,42723,42734,42735,42726,42727,42724,42725,42728, -42729,42730,42731,N,N,N,N,43368,43369,43370,43371,43372,43373,43374,43375, -43376,43377,N,43378,43379,43380,43381,N,43382,43383,43384,43385,43386,43387, -43388,43389,43390,43392,43393,43394,43395,43396,N,43397,43398,43399,43400, -8993,8994,8995,8551,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007, -9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,9022, -9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037, -9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052, -9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064,9065,9066,9067, -9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082, -9083,9084,9085,8491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8553,8554,43350,9086,43351,8996, -}; - -static const struct unim_index gbcommon_encmap[256] = { -{__gbcommon_encmap+0,164,252},{__gbcommon_encmap+89,1,220},{__gbcommon_encmap+ -309,81,217},{__gbcommon_encmap+446,145,201},{__gbcommon_encmap+503,1,81},{0,0, -0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gbcommon_encmap+584, -16,59},{__gbcommon_encmap+628,3,153},{__gbcommon_encmap+779,8,191},{ -__gbcommon_encmap+963,18,18},{__gbcommon_encmap+964,96,155},{__gbcommon_encmap -+1024,0,229},{__gbcommon_encmap+1254,5,66},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gbcommon_encmap+1316,0,254},{ -__gbcommon_encmap+1571,5,41},{__gbcommon_encmap+1608,32,163},{ -__gbcommon_encmap+1740,142,213},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{__gbcommon_encmap+1812,0,255},{__gbcommon_encmap+2068,0,255},{ -__gbcommon_encmap+2324,0,255},{__gbcommon_encmap+2580,0,255},{ -__gbcommon_encmap+2836,0,255},{__gbcommon_encmap+3092,0,255},{ -__gbcommon_encmap+3348,0,255},{__gbcommon_encmap+3604,0,255},{ -__gbcommon_encmap+3860,0,255},{__gbcommon_encmap+4116,0,255},{ -__gbcommon_encmap+4372,0,255},{__gbcommon_encmap+4628,0,255},{ -__gbcommon_encmap+4884,0,255},{__gbcommon_encmap+5140,0,255},{ -__gbcommon_encmap+5396,0,255},{__gbcommon_encmap+5652,0,255},{ -__gbcommon_encmap+5908,0,255},{__gbcommon_encmap+6164,0,255},{ -__gbcommon_encmap+6420,0,255},{__gbcommon_encmap+6676,0,255},{ -__gbcommon_encmap+6932,0,255},{__gbcommon_encmap+7188,0,255},{ -__gbcommon_encmap+7444,0,255},{__gbcommon_encmap+7700,0,255},{ -__gbcommon_encmap+7956,0,255},{__gbcommon_encmap+8212,0,255},{ -__gbcommon_encmap+8468,0,255},{__gbcommon_encmap+8724,0,255},{ -__gbcommon_encmap+8980,0,255},{__gbcommon_encmap+9236,0,255},{ -__gbcommon_encmap+9492,0,255},{__gbcommon_encmap+9748,0,255},{ -__gbcommon_encmap+10004,0,255},{__gbcommon_encmap+10260,0,255},{ -__gbcommon_encmap+10516,0,255},{__gbcommon_encmap+10772,0,255},{ -__gbcommon_encmap+11028,0,255},{__gbcommon_encmap+11284,0,255},{ -__gbcommon_encmap+11540,0,255},{__gbcommon_encmap+11796,0,255},{ -__gbcommon_encmap+12052,0,255},{__gbcommon_encmap+12308,0,255},{ -__gbcommon_encmap+12564,0,255},{__gbcommon_encmap+12820,0,255},{ -__gbcommon_encmap+13076,0,255},{__gbcommon_encmap+13332,0,255},{ -__gbcommon_encmap+13588,0,255},{__gbcommon_encmap+13844,0,255},{ -__gbcommon_encmap+14100,0,255},{__gbcommon_encmap+14356,0,255},{ -__gbcommon_encmap+14612,0,255},{__gbcommon_encmap+14868,0,255},{ -__gbcommon_encmap+15124,0,255},{__gbcommon_encmap+15380,0,255},{ -__gbcommon_encmap+15636,0,255},{__gbcommon_encmap+15892,0,255},{ -__gbcommon_encmap+16148,0,255},{__gbcommon_encmap+16404,0,255},{ -__gbcommon_encmap+16660,0,255},{__gbcommon_encmap+16916,0,255},{ -__gbcommon_encmap+17172,0,255},{__gbcommon_encmap+17428,0,255},{ -__gbcommon_encmap+17684,0,255},{__gbcommon_encmap+17940,0,255},{ -__gbcommon_encmap+18196,0,255},{__gbcommon_encmap+18452,0,255},{ -__gbcommon_encmap+18708,0,255},{__gbcommon_encmap+18964,0,255},{ -__gbcommon_encmap+19220,0,255},{__gbcommon_encmap+19476,0,255},{ -__gbcommon_encmap+19732,0,255},{__gbcommon_encmap+19988,0,255},{ -__gbcommon_encmap+20244,0,255},{__gbcommon_encmap+20500,0,255},{ -__gbcommon_encmap+20756,0,255},{__gbcommon_encmap+21012,0,255},{ -__gbcommon_encmap+21268,0,255},{__gbcommon_encmap+21524,0,255},{ -__gbcommon_encmap+21780,0,255},{__gbcommon_encmap+22036,0,255},{ -__gbcommon_encmap+22292,0,255},{__gbcommon_encmap+22548,0,165},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{__gbcommon_encmap+22714,44,241},{__gbcommon_encmap+22912,12,41},{0,0,0},{0, -0,0},{0,0,0},{__gbcommon_encmap+22942,48,107},{__gbcommon_encmap+23002,1,229}, -}; - -static const ucs2_t __gb18030ext_decmap[2729] = { -58566,58567,58568,58569,58570,58571,58572,58573,58574,58575,58576,58577,58578, -58579,58580,58581,58582,58583,58584,58585,58586,58587,58588,58589,58590,58591, -58592,58593,58594,58595,58596,58597,58598,58599,58600,58601,58602,58603,58604, -58605,58606,58607,58608,58609,58610,58611,58612,58613,58614,58615,58616,58617, -58618,58619,58620,58621,58622,58623,58624,58625,58626,58627,58628,U,58629, -58630,58631,58632,58633,58634,58635,58636,58637,58638,58639,58640,58641,58642, -58643,58644,58645,58646,58647,58648,58649,58650,58651,58652,58653,58654,58655, -58656,58657,58658,58659,58660,58661,58662,58663,58664,58665,58666,58667,58668, -58669,58670,58671,58672,58673,58674,58675,58676,58677,58678,58679,58680,58681, -58682,58683,58684,58685,58686,58687,58688,58689,58690,58691,58692,58693,58694, -58695,58696,58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707, -58708,58709,58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720, -58721,58722,58723,58724,U,58725,58726,58727,58728,58729,58730,58731,58732, -58733,58734,58735,58736,58737,58738,58739,58740,58741,58742,58743,58744,58745, -58746,58747,58748,58749,58750,58751,58752,58753,58754,58755,58756,58757,U,U,U, -U,U,U,U,U,U,U,59238,59239,59240,59241,59242,59243,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8364, -59245,U,U,U,U,U,U,U,U,U,U,59246,59247,U,U,U,U,U,U,U,U,U,U,U,U,59248,59249, -58758,58759,58760,58761,58762,58763,58764,58765,58766,58767,58768,58769,58770, -58771,58772,58773,58774,58775,58776,58777,58778,58779,58780,58781,58782,58783, -58784,58785,58786,58787,58788,58789,58790,58791,58792,58793,58794,58795,58796, -58797,58798,58799,58800,58801,58802,58803,58804,58805,58806,58807,58808,58809, -58810,58811,58812,58813,58814,58815,58816,58817,58818,58819,58820,U,58821, -58822,58823,58824,58825,58826,58827,58828,58829,58830,58831,58832,58833,58834, -58835,58836,58837,58838,58839,58840,58841,58842,58843,58844,58845,58846,58847, -58848,58849,58850,58851,58852,58853,58854,58855,58856,58857,58858,58859,58860, -58861,58862,58863,58864,58865,58866,58867,58868,58869,58870,58871,58872,58873, -58874,58875,58876,58877,58878,58879,58880,58881,58882,58883,58884,58885,58886, -58887,58888,58889,58890,58891,58892,58893,58894,58895,58896,58897,58898,58899, -58900,58901,58902,58903,58904,58905,58906,58907,58908,58909,58910,58911,58912, -58913,58914,58915,58916,U,58917,58918,58919,58920,58921,58922,58923,58924, -58925,58926,58927,58928,58929,58930,58931,58932,58933,58934,58935,58936,58937, -58938,58939,58940,58941,58942,58943,58944,58945,58946,58947,58948,58949,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,59250,59251,59252,59253,59254,59255,59256,59257,59258,59259,59260,58950, -58951,58952,58953,58954,58955,58956,58957,58958,58959,58960,58961,58962,58963, -58964,58965,58966,58967,58968,58969,58970,58971,58972,58973,58974,58975,58976, -58977,58978,58979,58980,58981,58982,58983,58984,58985,58986,58987,58988,58989, -58990,58991,58992,58993,58994,58995,58996,58997,58998,58999,59000,59001,59002, -59003,59004,59005,59006,59007,59008,59009,59010,59011,59012,U,59013,59014, -59015,59016,59017,59018,59019,59020,59021,59022,59023,59024,59025,59026,59027, -59028,59029,59030,59031,59032,59033,59034,59035,59036,59037,59038,59039,59040, -59041,59042,59043,59044,59045,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59261,59262,59263,59264,59265, -59266,59267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055, -59056,59057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068, -59069,59070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081, -59082,59083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094, -59095,59096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107, -59108,U,59109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119, -59120,59121,59122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132, -59133,59134,59135,59136,59137,59138,59139,59140,59141,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,59269,59270,59271,59272,59273,59274,59275,59276,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59277,59278,59279,59280,59281,59282, -59283,U,U,U,U,U,U,U,U,U,U,U,U,59284,59285,U,U,U,U,U,59286,U,U,59287,59288, -59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,59146,59147, -59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,59159,59160, -59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,59172,59173, -59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,59185,59186, -59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,59198,59199, -59200,59201,59202,59203,59204,U,59205,59206,59207,59208,59209,59210,59211, -59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,59224, -59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,59237, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59296,59297, -59298,59299,59300,59301,59302,59303,59304,59305,59306,59307,59308,59309,59310, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59311,59312, -59313,59314,59315,59316,59317,59318,59319,59320,59321,59322,59323,59324,59325, -59326,59327,59328,59329,59330,59331,59332,59333,59334,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59335,U,U,505,U,59337,59338,59339,59340,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59341,59342, -59343,59344,59345,59346,59347,59348,59349,59350,59351,59352,59353,59354,59355, -59356,59357,59358,59359,59360,59361,59362,U,U,59363,U,59364,59365,59366,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -12350,12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283, -U,59380,59381,59382,59383,59384,59385,59386,59387,59388,59389,59390,59391, -59392,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,59393,59394,59395,59396,59397,59398,59399,59400,59401,59402,59403,59404, -59405,59406,59407,57344,57345,57346,57347,57348,57349,57350,57351,57352,57353, -57354,57355,57356,57357,57358,57359,57360,57361,57362,57363,57364,57365,57366, -57367,57368,57369,57370,57371,57372,57373,57374,57375,57376,57377,57378,57379, -57380,57381,57382,57383,57384,57385,57386,57387,57388,57389,57390,57391,57392, -57393,57394,57395,57396,57397,57398,57399,57400,57401,57402,57403,57404,57405, -57406,57407,57408,57409,57410,57411,57412,57413,57414,57415,57416,57417,57418, -57419,57420,57421,57422,57423,57424,57425,57426,57427,57428,57429,57430,57431, -57432,57433,57434,57435,57436,57437,57438,57439,57440,57441,57442,57443,57444, -57445,57446,57447,57448,57449,57450,57451,57452,57453,57454,57455,57456,57457, -57458,57459,57460,57461,57462,57463,57464,57465,57466,57467,57468,57469,57470, -57471,57472,57473,57474,57475,57476,57477,57478,57479,57480,57481,57482,57483, -57484,57485,57486,57487,57488,57489,57490,57491,57492,57493,57494,57495,57496, -57497,57498,57499,57500,57501,57502,57503,57504,57505,57506,57507,57508,57509, -57510,57511,57512,57513,57514,57515,57516,57517,57518,57519,57520,57521,57522, -57523,57524,57525,57526,57527,57528,57529,57530,57531,57532,57533,57534,57535, -57536,57537,57538,57539,57540,57541,57542,57543,57544,57545,57546,57547,57548, -57549,57550,57551,57552,57553,57554,57555,57556,57557,57558,57559,57560,57561, -57562,57563,57564,57565,57566,57567,57568,57569,57570,57571,57572,57573,57574, -57575,57576,57577,57578,57579,57580,57581,57582,57583,57584,57585,57586,57587, -57588,57589,57590,57591,57592,57593,57594,57595,57596,57597,57598,57599,57600, -57601,57602,57603,57604,57605,57606,57607,57608,57609,57610,57611,57612,57613, -57614,57615,57616,57617,57618,57619,57620,57621,57622,57623,57624,57625,57626, -57627,57628,57629,57630,57631,57632,57633,57634,57635,57636,57637,57638,57639, -57640,57641,57642,57643,57644,57645,57646,57647,57648,57649,57650,57651,57652, -57653,57654,57655,57656,57657,57658,57659,57660,57661,57662,57663,57664,57665, -57666,57667,57668,57669,57670,57671,57672,57673,57674,57675,57676,57677,57678, -57679,57680,57681,57682,57683,57684,57685,57686,57687,57688,57689,57690,57691, -57692,57693,57694,57695,57696,57697,57698,57699,57700,57701,57702,57703,57704, -57705,57706,57707,57708,57709,57710,57711,57712,57713,57714,57715,57716,57717, -57718,57719,57720,57721,57722,57723,57724,57725,57726,57727,57728,57729,57730, -57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,57741,57742,57743, -57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,57754,57755,57756, -57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,57767,57768,57769, -57770,57771,57772,57773,57774,57775,57776,57777,57778,57779,57780,57781,57782, -57783,57784,57785,57786,57787,57788,57789,57790,57791,57792,57793,57794,57795, -57796,57797,57798,57799,57800,57801,57802,57803,57804,57805,57806,57807,57808, -57809,57810,57811,57812,57813,57814,57815,57816,57817,57818,57819,57820,57821, -57822,57823,57824,57825,57826,57827,57828,57829,57830,57831,57832,57833,57834, -57835,57836,57837,57838,57839,57840,57841,57842,57843,57844,57845,57846,57847, -57848,57849,57850,57851,57852,57853,57854,57855,57856,57857,57858,57859,57860, -57861,57862,57863,57864,57865,57866,57867,57868,57869,57870,57871,57872,57873, -57874,57875,57876,57877,57878,57879,57880,57881,57882,57883,57884,57885,57886, -57887,57888,57889,57890,57891,57892,57893,57894,57895,57896,57897,57898,57899, -57900,57901,57902,57903,57904,57905,57906,57907,59408,59409,59410,59411,59412, -57908,57909,57910,57911,57912,57913,57914,57915,57916,57917,57918,57919,57920, -57921,57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933, -57934,57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946, -57947,57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959, -57960,57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972, -57973,57974,57975,57976,57977,57978,57979,57980,57981,57982,57983,57984,57985, -57986,57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998, -57999,58000,58001,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011, -58012,58013,58014,58015,58016,58017,58018,58019,58020,58021,58022,58023,58024, -58025,58026,58027,58028,58029,58030,58031,58032,58033,58034,58035,58036,58037, -58038,58039,58040,58041,58042,58043,58044,58045,58046,58047,58048,58049,58050, -58051,58052,58053,58054,58055,58056,58057,58058,58059,58060,58061,58062,58063, -58064,58065,58066,58067,58068,58069,58070,58071,58072,58073,58074,58075,58076, -58077,58078,58079,58080,58081,58082,58083,58084,58085,58086,58087,58088,58089, -58090,58091,58092,58093,58094,58095,58096,58097,58098,58099,58100,58101,58102, -58103,58104,58105,58106,58107,58108,58109,58110,58111,58112,58113,58114,58115, -58116,58117,58118,58119,58120,58121,58122,58123,58124,58125,58126,58127,58128, -58129,58130,58131,58132,58133,58134,58135,58136,58137,58138,58139,58140,58141, -58142,58143,58144,58145,58146,58147,58148,58149,58150,58151,58152,58153,58154, -58155,58156,58157,58158,58159,58160,58161,58162,58163,58164,58165,58166,58167, -58168,58169,58170,58171,58172,58173,58174,58175,58176,58177,58178,58179,58180, -58181,58182,58183,58184,58185,58186,58187,58188,58189,58190,58191,58192,58193, -58194,58195,58196,58197,58198,58199,58200,58201,58202,58203,58204,58205,58206, -58207,58208,58209,58210,58211,58212,58213,58214,58215,58216,58217,58218,58219, -58220,58221,58222,58223,58224,58225,58226,58227,58228,58229,58230,58231,58232, -58233,58234,58235,58236,58237,58238,58239,58240,58241,58242,58243,58244,58245, -58246,58247,58248,58249,58250,58251,58252,58253,58254,58255,58256,58257,58258, -58259,58260,58261,58262,58263,58264,58265,58266,58267,58268,58269,58270,58271, -58272,58273,58274,58275,58276,58277,58278,58279,58280,58281,58282,58283,58284, -58285,58286,58287,58288,58289,58290,58291,58292,58293,58294,58295,58296,58297, -58298,58299,58300,58301,58302,58303,58304,58305,58306,58307,58308,58309,58310, -58311,58312,58313,58314,58315,58316,58317,58318,58319,58320,58321,58322,58323, -58324,58325,58326,58327,58328,58329,58330,58331,58332,58333,58334,58335,58336, -58337,58338,58339,58340,58341,58342,58343,58344,58345,58346,58347,58348,58349, -58350,58351,58352,58353,58354,58355,58356,58357,58358,58359,58360,58361,58362, -58363,58364,58365,58366,58367,58368,58369,58370,58371,58372,58373,58374,58375, -58376,58377,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388, -58389,58390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401, -58402,58403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414, -58415,58416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427, -58428,58429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440, -58441,58442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453, -58454,58455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466, -58467,58468,58469,58470,58471,11905,59414,59415,59416,11908,13427,13383,11912, -11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,14815,14963, -14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,16735,11950, -17207,11955,11958,11959,59451,17329,17324,11963,17373,17622,18017,17996,59459, -U,18211,18217,18300,18317,11978,18759,18810,18813,18818,18819,18821,18822, -18847,18843,18871,18870,59476,59477,19619,19615,19616,19617,19575,19618,19731, -19732,19733,19734,19735,19736,19737,19886,59492,58472,58473,58474,58475,58476, -58477,58478,58479,58480,58481,58482,58483,58484,58485,58486,58487,58488,58489, -58490,58491,58492,58493,58494,58495,58496,58497,58498,58499,58500,58501,58502, -58503,58504,58505,58506,58507,58508,58509,58510,58511,58512,58513,58514,58515, -58516,58517,58518,58519,58520,58521,58522,58523,58524,58525,58526,58527,58528, -58529,58530,58531,58532,58533,58534,58535,58536,58537,58538,58539,58540,58541, -58542,58543,58544,58545,58546,58547,58548,58549,58550,58551,58552,58553,58554, -58555,58556,58557,58558,58559,58560,58561,58562,58563,58564,58565, -}; - -static const struct dbcs_index gb18030ext_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_decmap+0,64, -160},{__gb18030ext_decmap+97,64,254},{__gb18030ext_decmap+288,64,160},{ -__gb18030ext_decmap+385,64,254},{__gb18030ext_decmap+576,64,254},{ -__gb18030ext_decmap+767,64,254},{__gb18030ext_decmap+958,64,254},{ -__gb18030ext_decmap+1149,150,254},{__gb18030ext_decmap+1254,88,254},{ -__gb18030ext_decmap+1421,161,254},{__gb18030ext_decmap+1515,161,254},{ -__gb18030ext_decmap+1609,161,254},{__gb18030ext_decmap+1703,161,254},{ -__gb18030ext_decmap+1797,161,254},{__gb18030ext_decmap+1891,161,254},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__gb18030ext_decmap+1985,250,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_decmap -+1990,161,254},{__gb18030ext_decmap+2084,161,254},{__gb18030ext_decmap+2178, -161,254},{__gb18030ext_decmap+2272,161,254},{__gb18030ext_decmap+2366,161,254 -},{__gb18030ext_decmap+2460,161,254},{__gb18030ext_decmap+2554,80,254},{0,0,0 -}, -}; - -static const DBCHAR __gb18030ext_encmap[3227] = { -43199,41699,65104,N,N,65108,N,N,N,65111,N,N,65112,65117,N,N,N,N,N,N,N,N,N,N, -65118,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65131,N,N,65134,N,N,N,65137,N,N,N,N,65139, -N,N,65140,65141,N,N,N,65145,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65156,43402,43403, -43404,43405,43406,43407,43408,43409,43410,43411,43412,43413,43401,65110,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,65109,65114,65116,N,N,N,N,N,N,N,N,N,N,N,65115,65120,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65119,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65122,65125,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65123, -65124,65128,65129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,65130,65135,65136,65138,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65144,N,N,N,N,65143,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65146,65147,65149, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65148,65152,N,N,N,N,N,65153,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -65154,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65155,65157,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65158, -N,N,65159,N,N,N,N,65160,65161,N,65162,65163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,65165,N,N,N,65164,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65167, -65166,65174,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,65171,65172,65173,65175,65170,65176,65177,65178,65179,65180,65181, -65182,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65183, -43681,43682,43683,43684,43685,43686,43687,43688,43689,43690,43691,43692,43693, -43694,43695,43696,43697,43698,43699,43700,43701,43702,43703,43704,43705,43706, -43707,43708,43709,43710,43711,43712,43713,43714,43715,43716,43717,43718,43719, -43720,43721,43722,43723,43724,43725,43726,43727,43728,43729,43730,43731,43732, -43733,43734,43735,43736,43737,43738,43739,43740,43741,43742,43743,43744,43745, -43746,43747,43748,43749,43750,43751,43752,43753,43754,43755,43756,43757,43758, -43759,43760,43761,43762,43763,43764,43765,43766,43767,43768,43769,43770,43771, -43772,43773,43774,43937,43938,43939,43940,43941,43942,43943,43944,43945,43946, -43947,43948,43949,43950,43951,43952,43953,43954,43955,43956,43957,43958,43959, -43960,43961,43962,43963,43964,43965,43966,43967,43968,43969,43970,43971,43972, -43973,43974,43975,43976,43977,43978,43979,43980,43981,43982,43983,43984,43985, -43986,43987,43988,43989,43990,43991,43992,43993,43994,43995,43996,43997,43998, -43999,44000,44001,44002,44003,44004,44005,44006,44007,44008,44009,44010,44011, -44012,44013,44014,44015,44016,44017,44018,44019,44020,44021,44022,44023,44024, -44025,44026,44027,44028,44029,44030,44193,44194,44195,44196,44197,44198,44199, -44200,44201,44202,44203,44204,44205,44206,44207,44208,44209,44210,44211,44212, -44213,44214,44215,44216,44217,44218,44219,44220,44221,44222,44223,44224,44225, -44226,44227,44228,44229,44230,44231,44232,44233,44234,44235,44236,44237,44238, -44239,44240,44241,44242,44243,44244,44245,44246,44247,44248,44249,44250,44251, -44252,44253,44254,44255,44256,44257,44258,44259,44260,44261,44262,44263,44264, -44265,44266,44267,44268,44269,44270,44271,44272,44273,44274,44275,44276,44277, -44278,44279,44280,44281,44282,44283,44284,44285,44286,44449,44450,44451,44452, -44453,44454,44455,44456,44457,44458,44459,44460,44461,44462,44463,44464,44465, -44466,44467,44468,44469,44470,44471,44472,44473,44474,44475,44476,44477,44478, -44479,44480,44481,44482,44483,44484,44485,44486,44487,44488,44489,44490,44491, -44492,44493,44494,44495,44496,44497,44498,44499,44500,44501,44502,44503,44504, -44505,44506,44507,44508,44509,44510,44511,44512,44513,44514,44515,44516,44517, -44518,44519,44520,44521,44522,44523,44524,44525,44526,44527,44528,44529,44530, -44531,44532,44533,44534,44535,44536,44537,44538,44539,44540,44541,44542,44705, -44706,44707,44708,44709,44710,44711,44712,44713,44714,44715,44716,44717,44718, -44719,44720,44721,44722,44723,44724,44725,44726,44727,44728,44729,44730,44731, -44732,44733,44734,44735,44736,44737,44738,44739,44740,44741,44742,44743,44744, -44745,44746,44747,44748,44749,44750,44751,44752,44753,44754,44755,44756,44757, -44758,44759,44760,44761,44762,44763,44764,44765,44766,44767,44768,44769,44770, -44771,44772,44773,44774,44775,44776,44777,44778,44779,44780,44781,44782,44783, -44784,44785,44786,44787,44788,44789,44790,44791,44792,44793,44794,44795,44796, -44797,44798,44961,44962,44963,44964,44965,44966,44967,44968,44969,44970,44971, -44972,44973,44974,44975,44976,44977,44978,44979,44980,44981,44982,44983,44984, -44985,44986,44987,44988,44989,44990,44991,44992,44993,44994,44995,44996,44997, -44998,44999,45000,45001,45002,45003,45004,45005,45006,45007,45008,45009,45010, -45011,45012,45013,45014,45015,45016,45017,45018,45019,45020,45021,45022,45023, -45024,45025,45026,45027,45028,45029,45030,45031,45032,45033,45034,45035,45036, -45037,45038,45039,45040,45041,45042,45043,45044,45045,45046,45047,45048,45049, -45050,45051,45052,45053,45054,63649,63650,63651,63652,63653,63654,63655,63656, -63657,63658,63659,63660,63661,63662,63663,63664,63665,63666,63667,63668,63669, -63670,63671,63672,63673,63674,63675,63676,63677,63678,63679,63680,63681,63682, -63683,63684,63685,63686,63687,63688,63689,63690,63691,63692,63693,63694,63695, -63696,63697,63698,63699,63700,63701,63702,63703,63704,63705,63706,63707,63708, -63709,63710,63711,63712,63713,63714,63715,63716,63717,63718,63719,63720,63721, -63722,63723,63724,63725,63726,63727,63728,63729,63730,63731,63732,63733,63734, -63735,63736,63737,63738,63739,63740,63741,63742,63905,63906,63907,63908,63909, -63910,63911,63912,63913,63914,63915,63916,63917,63918,63919,63920,63921,63922, -63923,63924,63925,63926,63927,63928,63929,63930,63931,63932,63933,63934,63935, -63936,63937,63938,63939,63940,63941,63942,63943,63944,63945,63946,63947,63948, -63949,63950,63951,63952,63953,63954,63955,63956,63957,63958,63959,63960,63961, -63962,63963,63964,63965,63966,63967,63968,63969,63970,63971,63972,63973,63974, -63975,63976,63977,63978,63979,63980,63981,63982,63983,63984,63985,63986,63987, -63988,63989,63990,63991,63992,63993,63994,63995,63996,63997,63998,64161,64162, -64163,64164,64165,64166,64167,64168,64169,64170,64171,64172,64173,64174,64175, -64176,64177,64178,64179,64180,64181,64182,64183,64184,64185,64186,64187,64188, -64189,64190,64191,64192,64193,64194,64195,64196,64197,64198,64199,64200,64201, -64202,64203,64204,64205,64206,64207,64208,64209,64210,64211,64212,64213,64214, -64215,64216,64217,64218,64219,64220,64221,64222,64223,64224,64225,64226,64227, -64228,64229,64230,64231,64232,64233,64234,64235,64236,64237,64238,64239,64240, -64241,64242,64243,64244,64245,64246,64247,64248,64249,64250,64251,64252,64253, -64254,64417,64418,64419,64420,64421,64422,64423,64424,64425,64426,64427,64428, -64429,64430,64431,64432,64433,64434,64435,64436,64437,64438,64439,64440,64441, -64442,64443,64444,64445,64446,64447,64448,64449,64450,64451,64452,64453,64454, -64455,64456,64457,64458,64459,64460,64461,64462,64463,64464,64465,64466,64467, -64468,64469,64470,64471,64472,64473,64474,64475,64476,64477,64478,64479,64480, -64481,64482,64483,64484,64485,64486,64487,64488,64489,64490,64491,64492,64493, -64494,64495,64496,64497,64498,64499,64500,64501,64502,64503,64504,64505,64506, -64507,64508,64509,64510,64673,64674,64675,64676,64677,64678,64679,64680,64681, -64682,64683,64684,64685,64686,64687,64688,64689,64690,64691,64692,64693,64694, -64695,64696,64697,64698,64699,64700,64701,64702,64703,64704,64705,64706,64707, -64708,64709,64710,64711,64712,64713,64714,64715,64716,64717,64718,64719,64720, -64721,64722,64723,64724,64725,64726,64727,64728,64729,64730,64731,64732,64733, -64734,64735,64736,64737,64738,64739,64740,64741,64742,64743,64744,64745,64746, -64747,64748,64749,64750,64751,64752,64753,64754,64755,64756,64757,64758,64759, -64760,64761,64762,64763,64764,64765,64766,64929,64930,64931,64932,64933,64934, -64935,64936,64937,64938,64939,64940,64941,64942,64943,64944,64945,64946,64947, -64948,64949,64950,64951,64952,64953,64954,64955,64956,64957,64958,64959,64960, -64961,64962,64963,64964,64965,64966,64967,64968,64969,64970,64971,64972,64973, -64974,64975,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986, -64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999, -65000,65001,65002,65003,65004,65005,65006,65007,65008,65009,65010,65011,65012, -65013,65014,65015,65016,65017,65018,65019,65020,65021,65022,65185,65186,65187, -65188,65189,65190,65191,65192,65193,65194,65195,65196,65197,65198,65199,65200, -65201,65202,65203,65204,65205,65206,65207,65208,65209,65210,65211,65212,65213, -65214,65215,65216,65217,65218,65219,65220,65221,65222,65223,65224,65225,65226, -65227,65228,65229,65230,65231,65232,65233,65234,65235,65236,65237,65238,65239, -65240,65241,65242,65243,65244,65245,65246,65247,65248,65249,65250,65251,65252, -65253,65254,65255,65256,65257,65258,65259,65260,65261,65262,65263,65264,65265, -65266,65267,65268,65269,65270,65271,65272,65273,65274,65275,65276,65277,65278, -41280,41281,41282,41283,41284,41285,41286,41287,41288,41289,41290,41291,41292, -41293,41294,41295,41296,41297,41298,41299,41300,41301,41302,41303,41304,41305, -41306,41307,41308,41309,41310,41311,41312,41313,41314,41315,41316,41317,41318, -41319,41320,41321,41322,41323,41324,41325,41326,41327,41328,41329,41330,41331, -41332,41333,41334,41335,41336,41337,41338,41339,41340,41341,41342,41344,41345, -41346,41347,41348,41349,41350,41351,41352,41353,41354,41355,41356,41357,41358, -41359,41360,41361,41362,41363,41364,41365,41366,41367,41368,41369,41370,41371, -41372,41373,41374,41375,41376,41536,41537,41538,41539,41540,41541,41542,41543, -41544,41545,41546,41547,41548,41549,41550,41551,41552,41553,41554,41555,41556, -41557,41558,41559,41560,41561,41562,41563,41564,41565,41566,41567,41568,41569, -41570,41571,41572,41573,41574,41575,41576,41577,41578,41579,41580,41581,41582, -41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,41594,41595, -41596,41597,41598,41600,41601,41602,41603,41604,41605,41606,41607,41608,41609, -41610,41611,41612,41613,41614,41615,41616,41617,41618,41619,41620,41621,41622, -41623,41624,41625,41626,41627,41628,41629,41630,41631,41632,41792,41793,41794, -41795,41796,41797,41798,41799,41800,41801,41802,41803,41804,41805,41806,41807, -41808,41809,41810,41811,41812,41813,41814,41815,41816,41817,41818,41819,41820, -41821,41822,41823,41824,41825,41826,41827,41828,41829,41830,41831,41832,41833, -41834,41835,41836,41837,41838,41839,41840,41841,41842,41843,41844,41845,41846, -41847,41848,41849,41850,41851,41852,41853,41854,41856,41857,41858,41859,41860, -41861,41862,41863,41864,41865,41866,41867,41868,41869,41870,41871,41872,41873, -41874,41875,41876,41877,41878,41879,41880,41881,41882,41883,41884,41885,41886, -41887,41888,42048,42049,42050,42051,42052,42053,42054,42055,42056,42057,42058, -42059,42060,42061,42062,42063,42064,42065,42066,42067,42068,42069,42070,42071, -42072,42073,42074,42075,42076,42077,42078,42079,42080,42081,42082,42083,42084, -42085,42086,42087,42088,42089,42090,42091,42092,42093,42094,42095,42096,42097, -42098,42099,42100,42101,42102,42103,42104,42105,42106,42107,42108,42109,42110, -42112,42113,42114,42115,42116,42117,42118,42119,42120,42121,42122,42123,42124, -42125,42126,42127,42128,42129,42130,42131,42132,42133,42134,42135,42136,42137, -42138,42139,42140,42141,42142,42143,42144,42304,42305,42306,42307,42308,42309, -42310,42311,42312,42313,42314,42315,42316,42317,42318,42319,42320,42321,42322, -42323,42324,42325,42326,42327,42328,42329,42330,42331,42332,42333,42334,42335, -42336,42337,42338,42339,42340,42341,42342,42343,42344,42345,42346,42347,42348, -42349,42350,42351,42352,42353,42354,42355,42356,42357,42358,42359,42360,42361, -42362,42363,42364,42365,42366,42368,42369,42370,42371,42372,42373,42374,42375, -42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,42386,42387,42388, -42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,42399,42400,42560, -42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,42572,42573, -42574,42575,42576,42577,42578,42579,42580,42581,42582,42583,42584,42585,42586, -42587,42588,42589,42590,42591,42592,42593,42594,42595,42596,42597,42598,42599, -42600,42601,42602,42603,42604,42605,42606,42607,42608,42609,42610,42611,42612, -42613,42614,42615,42616,42617,42618,42619,42620,42621,42622,42624,42625,42626, -42627,42628,42629,42630,42631,42632,42633,42634,42635,42636,42637,42638,42639, -42640,42641,42642,42643,42644,42645,42646,42647,42648,42649,42650,42651,42652, -42653,42654,42655,42656,42816,42817,42818,42819,42820,42821,42822,42823,42824, -42825,42826,42827,42828,42829,42830,42831,42832,42833,42834,42835,42836,42837, -42838,42839,42840,42841,42842,42843,42844,42845,42846,42847,42848,42849,42850, -42851,42852,42853,42854,42855,42856,42857,42858,42859,42860,42861,42862,42863, -42864,42865,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876, -42877,42878,42880,42881,42882,42883,42884,42885,42886,42887,42888,42889,42890, -42891,42892,42893,42894,42895,42896,42897,42898,42899,42900,42901,42902,42903, -42904,42905,42906,42907,42908,42909,42910,42911,42912,41643,41644,41645,41646, -41647,41648,N,41700,41711,41712,41725,41726,42228,42229,42230,42231,42232, -42233,42234,42235,42236,42237,42238,42487,42488,42489,42490,42491,42492,42493, -42494,42681,42682,42683,42684,42685,42686,42687,42688,42713,42714,42715,42716, -42717,42718,42719,42732,42733,42739,42742,42743,42744,42745,42746,42747,42748, -42749,42750,42946,42947,42948,42949,42950,42951,42952,42953,42954,42955,42956, -42957,42958,42959,42960,42994,42995,42996,42997,42998,42999,43000,43001,43002, -43003,43004,43005,43006,43158,43159,43160,43161,43162,43163,43164,43165,43166, -43167,43168,43196,N,43201,43202,43203,43204,43242,43243,43244,43245,43246, -43247,43248,43249,43250,43251,43252,43253,43254,43255,43256,43257,43258,43259, -43260,43261,43262,43352,43355,43357,43358,43359,N,N,N,N,N,N,N,N,N,N,N,N,N, -43415,43416,43417,43418,43419,43420,43421,43422,43423,43424,43425,43426,43427, -43504,43505,43506,43507,43508,43509,43510,43511,43512,43513,43514,43515,43516, -43517,43518,55290,55291,55292,55293,55294,N,65105,65106,65107,N,N,N,N,N,65113, -N,N,N,N,N,N,N,65121,N,N,N,N,65126,65127,N,N,N,N,65132,65133,N,N,N,N,N,N,N,N, -65142,N,N,N,N,N,N,N,65150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65168,65169,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,65184, -}; - -static const struct unim_index gb18030ext_encmap[256] = { -{0,0,0},{__gb18030ext_encmap+0,249,249},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+1,172,172 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+2,129,202},{ -__gb18030ext_encmap+76,240,251},{__gb18030ext_encmap+88,62,62},{0,0,0},{0,0,0 -},{0,0,0},{__gb18030ext_encmap+89,71,115},{__gb18030ext_encmap+134,158,158},{ -__gb18030ext_encmap+135,14,26},{0,0,0},{0,0,0},{__gb18030ext_encmap+148,24,223 -},{__gb18030ext_encmap+348,115,115},{__gb18030ext_encmap+349,78,78},{ -__gb18030ext_encmap+350,110,224},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+ -465,86,86},{__gb18030ext_encmap+466,95,95},{0,0,0},{__gb18030ext_encmap+467, -55,221},{__gb18030ext_encmap+634,214,214},{0,0,0},{__gb18030ext_encmap+635,76, -97},{__gb18030ext_encmap+657,35,141},{0,0,0},{__gb18030ext_encmap+764,71,183}, -{0,0,0},{0,0,0},{__gb18030ext_encmap+877,119,163},{__gb18030ext_encmap+922,19, -174},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{__gb18030ext_encmap+1078,0,255},{__gb18030ext_encmap+1334,0,255 -},{__gb18030ext_encmap+1590,0,255},{__gb18030ext_encmap+1846,0,255},{ -__gb18030ext_encmap+2102,0,255},{__gb18030ext_encmap+2358,0,255},{ -__gb18030ext_encmap+2614,0,255},{__gb18030ext_encmap+2870,0,255},{ -__gb18030ext_encmap+3126,0,100},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - - -static const struct _gb18030_to_unibmp_ranges { - Py_UCS4 first, last; - DBCHAR base; -} gb18030_to_unibmp_ranges[] = { -{128,163,0},{165,166,36},{169,175,38},{178,182,45},{184,214,50},{216,223,81},{ -226,231,89},{235,235,95},{238,241,96},{244,246,100},{248,248,103},{251,251,104 -},{253,256,105},{258,274,109},{276,282,126},{284,298,133},{300,323,148},{325, -327,172},{329,332,175},{334,362,179},{364,461,208},{463,463,306},{465,465,307 -},{467,467,308},{469,469,309},{471,471,310},{473,473,311},{475,475,312},{477, -504,313},{506,592,341},{594,608,428},{610,710,443},{712,712,544},{716,728,545 -},{730,912,558},{930,930,741},{938,944,742},{962,962,749},{970,1024,750},{1026 -,1039,805},{1104,1104,819},{1106,8207,820},{8209,8210,7922},{8215,8215,7924},{ -8218,8219,7925},{8222,8228,7927},{8231,8239,7934},{8241,8241,7943},{8244,8244, -7944},{8246,8250,7945},{8252,8363,7950},{8365,8450,8062},{8452,8452,8148},{ -8454,8456,8149},{8458,8469,8152},{8471,8480,8164},{8482,8543,8174},{8556,8559, -8236},{8570,8591,8240},{8596,8597,8262},{8602,8711,8264},{8713,8718,8374},{ -8720,8720,8380},{8722,8724,8381},{8726,8729,8384},{8731,8732,8388},{8737,8738, -8390},{8740,8740,8392},{8742,8742,8393},{8748,8749,8394},{8751,8755,8396},{ -8760,8764,8401},{8766,8775,8406},{8777,8779,8416},{8781,8785,8419},{8787,8799, -8424},{8802,8803,8437},{8808,8813,8439},{8816,8852,8445},{8854,8856,8482},{ -8858,8868,8485},{8870,8894,8496},{8896,8977,8521},{8979,9311,8603},{9322,9331, -8936},{9372,9471,8946},{9548,9551,9046},{9588,9600,9050},{9616,9618,9063},{ -9622,9631,9066},{9634,9649,9076},{9652,9659,9092},{9662,9669,9100},{9672,9674, -9108},{9676,9677,9111},{9680,9697,9113},{9702,9732,9131},{9735,9736,9162},{ -9738,9791,9164},{9793,9793,9218},{9795,11904,9219},{11906,11907,11329},{11909, -11911,11331},{11913,11914,11334},{11917,11926,11336},{11928,11942,11346},{ -11944,11945,11361},{11947,11949,11363},{11951,11954,11366},{11956,11957,11370 -},{11960,11962,11372},{11964,11977,11375},{11979,12271,11389},{12284,12287, -11682},{12292,12292,11686},{12312,12316,11687},{12319,12320,11692},{12330, -12349,11694},{12351,12352,11714},{12436,12442,11716},{12447,12448,11723},{ -12535,12539,11725},{12543,12548,11730},{12586,12831,11736},{12842,12848,11982 -},{12850,12962,11989},{12964,13197,12102},{13200,13211,12336},{13215,13216, -12348},{13218,13251,12350},{13253,13261,12384},{13263,13264,12393},{13267, -13268,12395},{13270,13382,12397},{13384,13426,12510},{13428,13725,12553},{ -13727,13837,12851},{13839,13849,12962},{13851,14615,12973},{14617,14701,13738 -},{14703,14798,13823},{14801,14814,13919},{14816,14962,13933},{14964,15181, -14080},{15183,15469,14298},{15471,15583,14585},{15585,16469,14698},{16471, -16734,15583},{16736,17206,15847},{17208,17323,16318},{17325,17328,16434},{ -17330,17372,16438},{17374,17621,16481},{17623,17995,16729},{17997,18016,17102 -},{18018,18210,17122},{18212,18216,17315},{18218,18299,17320},{18301,18316, -17402},{18318,18758,17418},{18760,18809,17859},{18811,18812,17909},{18814, -18817,17911},{18820,18820,17915},{18823,18842,17916},{18844,18846,17936},{ -18848,18869,17939},{18872,19574,17961},{19576,19614,18664},{19620,19730,18703 -},{19738,19885,18814},{19887,19967,18962},{40870,55295,19043},{59244,59244, -33469},{59336,59336,33470},{59367,59379,33471},{59413,59413,33484},{59417, -59421,33485},{59423,59429,33490},{59431,59434,33497},{59437,59440,33501},{ -59443,59450,33505},{59452,59458,33513},{59460,59475,33520},{59478,59491,33536 -},{59493,63787,33550},{63789,63864,37845},{63866,63892,37921},{63894,63974, -37948},{63976,63984,38029},{63986,64011,38038},{64016,64016,38064},{64018, -64018,38065},{64021,64023,38066},{64025,64030,38069},{64034,64034,38075},{ -64037,64038,38076},{64042,65071,38078},{65074,65074,39108},{65093,65096,39109 -},{65107,65107,39113},{65112,65112,39114},{65127,65127,39115},{65132,65280, -39116},{65375,65503,39265},{65510,65535,39394},{0,0,39420}}; +static const ucs2_t __gb2312_decmap[7482] = { +12288,12289,12290,12539,713,711,168,12291,12293,8213,65374,8214,8230,8216, +8217,8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303, +12310,12311,12304,12305,177,215,247,8758,8743,8744,8721,8719,8746,8745,8712, +8759,8730,8869,8741,8736,8978,8857,8747,8750,8801,8780,8776,8765,8733,8800, +8814,8815,8804,8805,8734,8757,8756,9794,9792,176,8242,8243,8451,65284,164, +65504,65505,8240,167,8470,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651, +9650,8251,8594,8592,8593,8595,12307,9352,9353,9354,9355,9356,9357,9358,9359, +9360,9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9332,9333,9334, +9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349, +9350,9351,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,U,U,12832,12833, +12834,12835,12836,12837,12838,12839,12840,12841,U,U,8544,8545,8546,8547,8548, +8549,8550,8551,8552,8553,8554,8555,65281,65282,65283,65509,65285,65286,65287, +65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,65300, +65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,65313, +65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326, +65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65339, +65340,65341,65342,65343,65344,65345,65346,65347,65348,65349,65350,65351,65352, +65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365, +65366,65367,65368,65369,65370,65371,65372,65373,65507,12353,12354,12355,12356, +12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369, +12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382, +12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395, +12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408, +12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421, +12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434, +12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460, +12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473, +12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486, +12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499, +12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512, +12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525, +12526,12527,12528,12529,12530,12531,12532,12533,12534,913,914,915,916,917,918, +919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,U,U,U, +U,U,U,U,U,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961, +963,964,965,966,967,968,969,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048, +1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063, +1064,1065,1066,1067,1068,1069,1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072, +1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086, +1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101, +1102,1103,257,225,462,224,275,233,283,232,299,237,464,236,333,243,466,242,363, +250,468,249,470,472,474,476,252,234,U,U,U,U,U,U,U,U,U,U,12549,12550,12551, +12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564, +12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577, +12578,12579,12580,12581,12582,12583,12584,12585,9472,9473,9474,9475,9476,9477, +9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492, +9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507, +9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522, +9523,9524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537, +9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,21834,38463,22467,25384, +21710,21769,21696,30353,30284,34108,30702,33406,30861,29233,38552,38797,27688, +23433,20474,25353,26263,23736,33018,26696,32942,26114,30414,20985,25942,29100, +32753,34948,20658,22885,25034,28595,33453,25420,25170,21485,21543,31494,20843, +30116,24052,25300,36299,38774,25226,32793,22365,38712,32610,29240,30333,26575, +30334,25670,20336,36133,25308,31255,26001,29677,25644,25203,33324,39041,26495, +29256,25198,25292,20276,29923,21322,21150,32458,37030,24110,26758,27036,33152, +32465,26834,30917,34444,38225,20621,35876,33502,32990,21253,35090,21093,34180, +38649,20445,22561,39281,23453,25265,25253,26292,35961,40077,29190,26479,30865, +24754,21329,21271,36744,32972,36125,38049,20493,29384,22791,24811,28953,34987, +22868,33519,26412,31528,23849,32503,29997,27893,36454,36856,36924,40763,27604, +37145,31508,24444,30887,34006,34109,27605,27609,27606,24065,24199,30201,38381, +25949,24330,24517,36767,22721,33218,36991,38491,38829,36793,32534,36140,25153, +20415,21464,21342,36776,36777,36779,36941,26631,24426,33176,34920,40150,24971, +21035,30250,24428,25996,28626,28392,23486,25672,20853,20912,26564,19993,31177, +39292,28851,30149,24182,29627,33760,25773,25320,38069,27874,21338,21187,25615, +38082,31636,20271,24091,33334,33046,33162,28196,27850,39539,25429,21340,21754, +34917,22496,19981,24067,27493,31807,37096,24598,25830,29468,35009,26448,25165, +36130,30572,36393,37319,24425,33756,34081,39184,21442,34453,27531,24813,24808, +28799,33485,33329,20179,27815,34255,25805,31961,27133,26361,33609,21397,31574, +20391,20876,27979,23618,36461,25554,21449,33580,33590,26597,30900,25661,23519, +23700,24046,35815,25286,26612,35962,25600,25530,34633,39307,35863,32544,38130, +20135,38416,39076,26124,29462,22330,23581,24120,38271,20607,32928,21378,25950, +30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,21557,28818,36710, +25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,24561,27785,38472, +36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,24809,28548,35802, +25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,24347,39536,32827, +40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,23815,23456,25277, +37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,33261,21021,20986, +27249,21416,36487,38148,38607,28353,38500,26970,30784,20648,30679,25616,35302, +22788,25571,24029,31359,26941,20256,33337,21912,20018,30126,31383,24162,24202, +38383,21019,21561,28810,25462,38180,22402,26149,26943,37255,21767,28147,32431, +34850,25139,32496,30133,33576,30913,38604,36766,24904,29943,35789,27492,21050, +36176,27425,32874,33905,22257,21254,20174,19995,20945,31895,37259,31751,20419, +36479,31713,31388,25703,23828,20652,33030,30209,31929,28140,32736,26449,23384, +23544,30923,25774,25619,25514,25387,38169,25645,36798,31572,30249,25171,22823, +21574,27513,20643,25140,24102,27526,20195,36151,34955,24453,36910,24608,32829, +25285,20025,21333,37112,25528,32966,26086,27694,20294,24814,28129,35806,24377, +34507,24403,25377,20826,33633,26723,20992,25443,36424,20498,23707,31095,23548, +21040,31291,24764,36947,30423,24503,24471,30340,36460,28783,30331,31561,30634, +20979,37011,22564,20302,28404,36842,25932,31515,29380,28068,32735,23265,25269, +24213,22320,33922,31532,24093,24351,36882,32532,39072,25474,28359,30872,28857, +20856,38747,22443,30005,20291,30008,24215,24806,22880,28096,27583,30857,21500, +38613,20939,20993,25481,21514,38035,35843,36300,29241,30879,34678,36845,35853, +21472,19969,30447,21486,38025,39030,40718,38189,23450,35746,20002,19996,20908, +33891,25026,21160,26635,20375,24683,20923,27934,20828,25238,26007,38497,35910, +36887,30168,37117,30563,27602,29322,29420,35835,22581,30585,36172,26460,38208, +32922,24230,28193,22930,31471,30701,38203,27573,26029,32526,22534,20817,38431, +23545,22697,21544,36466,25958,39039,22244,38045,30462,36929,25479,21702,22810, +22842,22427,36530,26421,36346,33333,21057,24816,22549,34558,23784,40517,20420, +39069,35769,23077,24694,21380,25212,36943,37122,39295,24681,32780,20799,32819, +23572,39285,27953,20108,36144,21457,32602,31567,20240,20047,38400,27861,29648, +34281,24070,30058,32763,27146,30718,38034,32321,20961,28902,21453,36820,33539, +36137,29359,39277,27867,22346,33459,26041,32938,25151,38450,22952,20223,35775, +32442,25918,33778,38750,21857,39134,32933,21290,35837,21536,32954,24223,27832, +36153,33452,37210,21545,27675,20998,32439,22367,28954,27774,31881,22859,20221, +24575,24868,31914,20016,23553,26539,34562,23792,38155,39118,30127,28925,36898, +20911,32541,35773,22857,20964,20315,21542,22827,25975,32932,23413,25206,25282, +36752,24133,27679,31526,20239,20440,26381,28014,28074,31119,34993,24343,29995, +25242,36741,20463,37340,26023,33071,33105,24220,33104,36212,21103,35206,36171, +22797,20613,20184,38428,29238,33145,36127,23500,35747,38468,22919,32538,21648, +22134,22030,35813,25913,27010,38041,30422,28297,24178,29976,26438,26577,31487, +32925,36214,24863,31174,25954,36195,20872,21018,38050,32568,32923,32434,23703, +28207,26464,31705,30347,39640,33167,32660,31957,25630,38224,31295,21578,21733, +27468,25601,25096,40509,33011,30105,21106,38761,33883,26684,34532,38401,38548, +38124,20010,21508,32473,26681,36319,32789,26356,24218,32697,22466,32831,26775, +24037,25915,21151,24685,40858,20379,36524,20844,23467,24339,24041,27742,25329, +36129,20849,38057,21246,27807,33503,29399,22434,26500,36141,22815,36764,33735, +21653,31629,20272,27837,23396,22993,40723,21476,34506,39592,35895,32929,25925, +39038,22266,38599,21038,29916,21072,23521,25346,35074,20054,25296,24618,26874, +20851,23448,20896,35266,31649,39302,32592,24815,28748,36143,20809,24191,36891, +29808,35268,22317,30789,24402,40863,38394,36712,39740,35809,30328,26690,26588, +36330,36149,21053,36746,28378,26829,38149,37101,22269,26524,35065,36807,21704, +39608,23401,28023,27686,20133,23475,39559,37219,25000,37039,38889,21547,28085, +23506,20989,21898,32597,32752,25788,25421,26097,25022,24717,28938,27735,27721, +22831,26477,33322,22741,22158,35946,27627,37085,22909,32791,21495,28009,21621, +21917,33655,33743,26680,31166,21644,20309,21512,30418,35977,38402,27827,28088, +36203,35088,40548,36154,22079,40657,30165,24456,29408,24680,21756,20136,27178, +34913,24658,36720,21700,28888,34425,40511,27946,23439,24344,32418,21897,20399, +29492,21564,21402,20505,21518,21628,20046,24573,29786,22774,33899,32993,34676, +29392,31946,28246,24359,34382,21804,25252,20114,27818,25143,33457,21719,21326, +29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,27426,29615, +26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,24187,33618, +24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,24653,35854, +28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,24800,26214, +36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,39746,27985, +28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,20987,22334, +22522,26426,30072,31293,31215,31637,32908,39269,36857,28608,35749,40481,23020, +32489,32521,21513,26497,26840,36753,31821,38598,21450,24613,30142,27762,21363, +23241,32423,25380,20960,33034,24049,34015,25216,20864,23395,20238,31085,21058, +24760,27982,23492,23490,35745,35760,26082,24524,38469,22931,32487,32426,22025, +26551,22841,20339,23478,21152,33626,39050,36158,30002,38078,20551,31292,20215, +26550,39550,23233,27516,30417,22362,23574,31546,38388,29006,20860,32937,33392, +22904,32516,33575,26816,26604,30897,30839,25315,25441,31616,20461,21098,20943, +33616,27099,37492,36341,36145,35265,38190,31661,20214,20581,33328,21073,39279, +28176,28293,28071,24314,20725,23004,23558,27974,27743,30086,33931,26728,22870, +35762,21280,37233,38477,34121,26898,30977,28966,33014,20132,37066,27975,39556, +23047,22204,25605,38128,30699,20389,33050,29409,35282,39290,32564,32478,21119, +25945,37237,36735,36739,21483,31382,25581,25509,30342,31224,34903,38454,25130, +21163,33410,26708,26480,25463,30571,31469,27905,32467,35299,22992,25106,34249, +33445,30028,20511,20171,30117,35819,23626,24062,31563,26020,37329,20170,27941, +35167,32039,38182,20165,35880,36827,38771,26187,31105,36817,28908,28024,23613, +21170,33606,20834,33550,30555,26230,40120,20140,24778,31934,31923,32463,20117, +35686,26223,39048,38745,22659,25964,38236,24452,30153,38742,31455,31454,20928, +28847,31384,25578,31350,32416,29590,38893,20037,28792,20061,37202,21417,25937, +26087,33276,33285,21646,23601,30106,38816,25304,29401,30141,23621,39545,33738, +23616,21632,30697,20030,27822,32858,25298,25454,24040,20855,36317,36382,38191, +20465,21477,24807,28844,21095,25424,40515,23071,20518,30519,21367,32482,25733, +25899,25225,25496,20500,29237,35273,20915,35776,32477,22343,33740,38055,20891, +21531,23803,20426,31459,27994,37089,39567,21888,21654,21345,21679,24320,25577, +26999,20975,24936,21002,22570,21208,22350,30733,30475,24247,24951,31968,25179, +25239,20130,28821,32771,25335,28900,38752,22391,33499,26607,26869,30933,39063, +31185,22771,21683,21487,28212,20811,21051,23458,35838,32943,21827,22438,24691, +22353,21549,31354,24656,23380,25511,25248,21475,25187,23495,26543,21741,31391, +33510,37239,24211,35044,22840,22446,25358,36328,33007,22359,31607,20393,24555, +23485,27454,21281,31568,29378,26694,30719,30518,26103,20917,20111,30420,23743, +31397,33909,22862,39745,20608,39304,24871,28291,22372,26118,25414,22256,25324, +25193,24275,38420,22403,25289,21895,34593,33098,36771,21862,33713,26469,36182, +34013,23146,26639,25318,31726,38417,20848,28572,35888,25597,35272,25042,32518, +28866,28389,29701,27028,29436,24266,37070,26391,28010,25438,21171,29282,32769, +20332,23013,37226,28889,28061,21202,20048,38647,38253,34174,30922,32047,20769, +22418,25794,32907,31867,27882,26865,26974,20919,21400,26792,29313,40654,31729, +29432,31163,28435,29702,26446,37324,40100,31036,33673,33620,21519,26647,20029, +21385,21169,30782,21382,21033,20616,20363,20432,30178,31435,31890,27813,38582, +21147,29827,21737,20457,32852,33714,36830,38256,24265,24604,28063,24088,25947, +33080,38142,24651,28860,32451,31918,20937,26753,31921,33391,20004,36742,37327, +26238,20142,35845,25769,32842,20698,30103,29134,23525,36797,28518,20102,25730, +38243,24278,26009,21015,35010,28872,21155,29454,29747,26519,30967,38678,20020, +37051,40158,28107,20955,36161,21533,25294,29618,33777,38646,40836,38083,20278, +32666,20940,28789,38517,23725,39046,21478,20196,28316,29705,27060,30827,39311, +30041,21016,30244,27969,26611,20845,40857,32843,21657,31548,31423,38534,22404, +25314,38471,27004,23044,25602,31699,28431,38475,33446,21346,39045,24208,28809, +25523,21348,34383,40065,40595,30860,38706,36335,36162,40575,28510,31108,24405, +38470,25134,39540,21525,38109,20387,26053,23653,23649,32533,34385,27695,24459, +29575,28388,32511,23782,25371,23402,28390,21365,20081,25504,30053,25249,36718, +20262,20177,27814,32438,35770,33821,34746,32599,36923,38179,31657,39585,35064, +33853,27931,39558,32476,22920,40635,29595,30721,34434,39532,39554,22043,21527, +22475,20080,40614,21334,36808,33033,30610,39314,34542,28385,34067,26364,24930, +28459,35881,33426,33579,30450,27667,24537,33725,29483,33541,38170,27611,30683, +38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,26757,37238,38665, +29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,23194,38376,38391, +20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,37274,38753,31964, +36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,26825,30496,32501, +20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,31186,28218,24217, +22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,34719,40483,38125, +21517,21629,35884,25720,25721,34321,27169,33180,30952,25705,39764,25273,26411, +33707,22696,40664,27819,28448,23518,38476,35851,29279,26576,25287,29281,20137, +22982,27597,22675,26286,24149,21215,24917,26408,30446,30566,29287,31302,25343, +21738,21584,38048,37027,23068,32435,27670,20035,22902,32784,22856,21335,30007, +38590,22218,25376,33041,24700,38393,28118,21602,39297,20869,23273,33021,22958, +38675,20522,27877,23612,25311,20320,21311,33147,36870,28346,34091,25288,24180, +30910,25781,25467,24565,23064,37247,40479,23615,25423,32834,23421,21870,38218, +38221,28037,24744,26592,29406,20957,23425,25319,27870,29275,25197,38062,32445, +33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,25386,25062, +31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,36276,29228, +24085,24597,29750,25293,25490,29260,24472,28227,27966,25856,28504,30424,30928, +30460,30036,21028,21467,20051,24222,26049,32810,32982,25243,21638,21032,28846, +34957,36305,27873,21624,32986,22521,35060,36180,38506,37197,20329,27803,21943, +30406,30768,25256,28921,28558,24429,34028,26842,30844,31735,33192,26379,40527, +25447,30896,22383,30738,38713,25209,25259,21128,29749,27607,21860,33086,30130, +30382,21305,30174,20731,23617,35692,31687,20559,29255,39575,39128,28418,29922, +31080,25735,30629,25340,39057,36139,21697,32856,20050,22378,33529,33805,24179, +20973,29942,35780,23631,22369,27900,39047,23110,30772,39748,36843,31893,21078, +25169,38138,20166,33670,33889,33769,33970,22484,26420,22275,26222,28006,35889, +26333,28689,26399,27450,26646,25114,22971,19971,20932,28422,26578,27791,20854, +26827,22855,27495,30054,23822,33040,40784,26071,31048,31041,39569,36215,23682, +20062,20225,21551,22865,30732,22120,27668,36804,24323,27773,27875,35755,25488, +24688,27965,29301,25190,38030,38085,21315,36801,31614,20191,35878,20094,40660, +38065,38067,21069,28508,36963,27973,35892,22545,23884,27424,27465,26538,21595, +33108,32652,22681,34103,24378,25250,27207,38201,25970,24708,26725,30631,20052, +20392,24039,38808,25772,32728,23789,20431,31373,20999,33540,19988,24623,31363, +38054,20405,20146,31206,29748,21220,33465,25810,31165,23517,27777,38738,36731, +27682,20542,21375,28165,25806,26228,27696,24773,39031,35831,24198,29756,31351, +31179,19992,37041,29699,27714,22234,37195,27845,36235,21306,34502,26354,36527, +23624,39537,28192,21462,23094,40843,36259,21435,22280,39079,26435,37275,27849, +20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,40522,27063,30830, +38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,22199,35753,39286, +25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,35748,20995,22922, +32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,28342,23481,32466, +20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,20083,27741,20837, +35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,25746,27922,33832, +33134,40131,22622,36187,19977,21441,20254,25955,26705,21971,20007,25620,39578, +25195,23234,29791,33394,28073,26862,20711,33678,30722,26432,21049,27801,32433, +20667,21861,29022,31579,26194,29642,33515,26441,23665,21024,29053,34923,38378, +38485,25797,36193,33203,21892,27733,25159,32558,22674,20260,21830,36175,26188, +19978,23578,35059,26786,25422,31245,28903,33421,21242,38902,23569,21736,37045, +32461,22882,36170,34503,33292,33293,36198,25668,23556,24913,28041,31038,35774, +30775,30003,21627,20280,36523,28145,23072,32453,31070,27784,23457,23158,29978, +32958,24910,28183,22768,29983,29989,29298,21319,32499,30465,30427,21097,32988, +22307,24072,22833,29422,26045,28287,35799,23608,34417,21313,30707,25342,26102, +20160,39135,34432,23454,35782,21490,30690,20351,23630,39542,22987,24335,31034, +22763,19990,26623,20107,25325,35475,36893,21183,26159,21980,22124,36866,20181, +20365,37322,39280,27663,24066,24643,23460,35270,35797,25910,25163,39318,23432, +23551,25480,21806,21463,30246,20861,34092,26530,26803,27530,25234,36755,21460, +33298,28113,30095,20070,36174,23408,29087,34223,26257,26329,32626,34560,40653, +40736,23646,26415,36848,26641,26463,25101,31446,22661,24246,25968,28465,24661, +21047,32781,25684,34928,29993,24069,26643,25332,38684,21452,29245,35841,27700, +30561,31246,21550,30636,39034,33308,35828,30805,26388,28865,26031,25749,22070, +24605,31169,21496,19997,27515,32902,23546,21987,22235,20282,20284,39282,24051, +26494,32824,24578,39042,36865,23435,35772,35829,25628,33368,25822,22013,33487, +37221,20439,32032,36895,31903,20723,22609,28335,23487,35785,32899,37240,33948, +31639,34429,38539,38543,32485,39635,30862,23681,31319,36930,38567,31071,23385, +25439,31499,34001,26797,21766,32553,29712,32034,38145,25152,22604,20182,23427, +22905,22612,29549,25374,36427,36367,32974,33492,25260,21488,27888,37214,22826, +24577,27760,22349,25674,36138,30251,28393,22363,27264,30192,28525,35885,35848, +22374,27631,34962,30899,25506,21497,28845,27748,22616,25642,22530,26848,33179, +21776,31958,20504,36538,28108,36255,28907,25487,28059,28372,32486,33796,26691, +36867,28120,38518,35752,22871,29305,34276,33150,30140,35466,26799,21076,36386, +38161,25552,39064,36420,21884,20307,26367,22159,24789,28053,21059,23625,22825, +28155,22635,30000,29980,24684,33300,33094,25361,26465,36834,30522,36339,36148, +38081,24086,21381,21548,28867,27712,24311,20572,20141,24237,25402,33351,36890, +26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,20599, +25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,21520, +20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,25302, +25176,33073,40501,38464,39534,39548,26925,22949,25299,21822,25366,21703,34521, +27964,23043,29926,34972,27498,22806,35916,24367,28286,29609,39037,20024,28919, +23436,30871,25405,26202,30358,24779,23451,23113,19975,33109,27754,29579,20129, +26505,32593,24448,26106,26395,24536,22916,23041,24013,24494,21361,38886,36829, +26693,22260,21807,24799,20026,28493,32500,33479,33806,22996,20255,20266,23614, +32428,26410,34074,21619,30031,32963,21890,39759,20301,28205,35859,23561,24944, +21355,30239,28201,34442,25991,38395,32441,21563,31283,32010,38382,21985,32705, +29934,25373,34583,28065,31389,25105,26017,21351,25569,27779,24043,21596,38056, +20044,27745,35820,23627,26080,33436,26791,21566,21556,27595,27494,20116,25410, +21320,33310,20237,20398,22366,25098,38654,26212,29289,21247,21153,24735,35823, +26132,29081,26512,35199,30802,30717,26224,22075,21560,38177,29306,31232,24687, +24076,24713,33181,22805,24796,29060,28911,28330,27728,29312,27268,34989,24109, +20064,23219,21916,38115,27927,31995,38553,25103,32454,30606,34430,21283,38686, +36758,26247,23777,20384,29421,19979,21414,22799,21523,25472,38184,20808,20185, +40092,32420,21688,36132,34900,33335,38386,28046,24358,23244,26174,38505,29616, +29486,21439,33146,39301,32673,23466,38519,38480,32447,30456,21410,38262,39321, +31665,35140,28248,20065,32724,31077,35814,24819,21709,20139,39033,24055,27233, +20687,21521,35937,33831,30813,38660,21066,21742,22179,38144,28040,23477,28102, +26195,23567,23389,26657,32918,21880,31505,25928,26964,20123,27463,34638,38795, +21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,34809,25032,27844, +27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,24515,20449,34885, +26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,37266,24184,26447, +24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,20462,32670,26429, +21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,39035,24464,35768, +33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,32493,36713,21927, +23459,24748,26059,29572,36873,30307,30505,32474,38772,34203,23398,31348,38634, +34880,21195,29071,24490,26092,35810,23547,39535,24033,27529,27739,35757,35759, +36874,36805,21387,25276,40486,40493,21568,20011,33469,29273,34460,23830,34905, +28079,38597,21713,20122,35766,28937,21693,38409,28895,28153,30416,20005,30740, +34578,23721,24310,35328,39068,38414,28814,27839,22852,25513,30524,34893,28436, +33395,22576,29141,21388,30746,38593,21761,24422,28976,23476,35866,39564,27523, +22830,40495,31207,26472,25196,20335,30113,32650,27915,38451,27687,20208,30162, +20859,26679,28478,36992,33136,22934,29814,25671,23591,36965,31377,35875,23002, +21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,20918,20063,39029, +25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,25558,38129,20381, +20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,23452,23016,24413, +26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,37009,23673,20159, +24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,20041,30410,28322, +35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,22240,27575,38899, +38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,21360,33521,27185, +23156,40560,24212,32552,33721,33828,33829,33639,34631,36814,36194,30408,24433, +39062,30828,26144,21727,25317,20323,33219,30152,24248,38605,36362,34553,21647, +27891,28044,27704,24703,21191,29992,24189,20248,24736,24551,23588,30001,37038, +38080,29369,27833,28216,37193,26377,21451,21491,20305,37321,35825,21448,24188, +36802,28132,20110,30402,27014,34398,24858,33286,20313,20446,36926,40060,24841, +28189,28180,38533,20104,23089,38632,19982,23679,31161,23431,35821,32701,29577, +22495,33419,37057,21505,36935,21947,23786,24481,24840,27442,29425,32946,35465, +28020,23507,35029,39044,35947,39533,40499,28170,20900,20803,22435,34945,21407, +25588,36757,22253,21592,22278,29503,28304,32536,36828,33489,24895,24616,38498, +26352,32422,36234,36291,38053,23731,31908,26376,24742,38405,32792,20113,37095, +21248,38504,20801,36816,34164,37213,26197,38901,23381,21277,30776,26434,26685, +21705,28798,23472,36733,20877,22312,21681,25874,26242,36190,36163,33039,33900, +36973,31967,20991,34299,26531,26089,28577,34468,36481,22122,36896,30338,28790, +29157,36131,25321,21017,27901,36156,24590,22686,24974,26366,36192,25166,21939, +28195,26413,36711,38113,38392,30504,26629,27048,21643,20045,28856,35784,25688, +25995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,26025,36759, +23853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,24432,28467, +24352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,25307,26157, +25214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,34544,36761, +32773,38167,34071,36825,27993,29645,26015,30495,29956,30759,33275,36126,38024, +20390,26517,30137,35786,38663,25391,38215,38453,33976,25379,30529,24449,29424, +20105,24596,25972,25327,27491,25919,24103,30151,37073,35777,33437,26525,25903, +21553,34584,30693,32930,33026,27713,20043,32455,32844,30452,26893,27542,25191, +20540,20356,22336,25351,27490,36286,21482,26088,32440,24535,25370,25527,33267, +33268,32622,24092,23769,21046,26234,31209,31258,36136,28825,30164,28382,27835, +31378,20013,30405,24544,38047,34935,32456,31181,32959,37325,20210,20247,33311, +21608,24030,27954,35788,31909,36724,32920,24090,21650,30385,23449,26172,39588, +29664,26666,34523,26417,29482,35832,35803,36880,31481,28891,29038,25284,30633, +22065,20027,33879,26609,21161,34496,36142,38136,31569,20303,27880,31069,39547, +25235,29226,25341,19987,30742,36716,25776,36186,31686,26729,24196,35013,22918, +25758,22766,29366,26894,38181,36861,36184,22368,32512,35846,20934,25417,25305, +21331,26700,29730,33537,37196,21828,30528,28796,27978,20857,21672,36164,23039, +28363,28100,23388,32043,20180,31869,28371,23376,33258,28173,23383,39683,26837, +36394,23447,32508,24635,32437,37049,36208,22863,25549,31199,36275,21330,26063, +31062,35781,38459,32452,38075,32386,22068,37257,26368,32618,23562,36981,26152, +24038,20304,26590,20570,20316,22352,24231,20109,19980,20800,19984,24319,21317, +19989,20120,19998,39730,23404,22121,20008,31162,20031,21269,20039,22829,29243, +21358,27664,22239,32996,39319,27603,30590,40727,20022,20127,40720,20060,20073, +20115,33416,23387,21868,22031,20164,21389,21405,21411,21413,21422,38757,36189, +21274,21493,21286,21294,21310,36188,21350,21347,20994,21000,21006,21037,21043, +21055,21056,21068,21086,21089,21084,33967,21117,21122,21121,21136,21139,20866, +32596,20155,20163,20169,20162,20200,20193,20203,20190,20251,20211,20258,20324, +20213,20261,20263,20233,20267,20318,20327,25912,20314,20317,20319,20311,20274, +20285,20342,20340,20369,20361,20355,20367,20350,20347,20394,20348,20396,20372, +20454,20456,20458,20421,20442,20451,20444,20433,20447,20472,20521,20556,20467, +20524,20495,20526,20525,20478,20508,20492,20517,20520,20606,20547,20565,20552, +20558,20588,20603,20645,20647,20649,20666,20694,20742,20717,20716,20710,20718, +20743,20747,20189,27709,20312,20325,20430,40864,27718,31860,20846,24061,40649, +39320,20865,22804,21241,21261,35335,21264,20971,22809,20821,20128,20822,20147, +34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,20925,20924, +20935,20886,20898,20901,35744,35750,35751,35754,35764,35765,35767,35778,35779, +35787,35791,35790,35794,35795,35796,35798,35800,35801,35804,35807,35808,35812, +35816,35817,35822,35824,35827,35830,35833,35836,35839,35840,35842,35844,35847, +35852,35855,35857,35858,35860,35861,35862,35865,35867,35864,35869,35871,35872, +35873,35877,35879,35882,35883,35886,35887,35890,35891,35893,35894,21353,21370, +38429,38434,38433,38449,38442,38461,38460,38466,38473,38484,38495,38503,38508, +38514,38516,38536,38541,38551,38576,37015,37019,37021,37017,37036,37025,37044, +37043,37046,37050,37048,37040,37071,37061,37054,37072,37060,37063,37075,37094, +37090,37084,37079,37083,37099,37103,37118,37124,37154,37150,37155,37169,37167, +37177,37187,37190,21005,22850,21154,21164,21165,21182,21759,21200,21206,21232, +21471,29166,30669,24308,20981,20988,39727,21430,24321,30042,24047,22348,22441, +22433,22654,22716,22725,22737,22313,22316,22314,22323,22329,22318,22319,22364, +22331,22338,22377,22405,22379,22406,22396,22395,22376,22381,22390,22387,22445, +22436,22412,22450,22479,22439,22452,22419,22432,22485,22488,22490,22489,22482, +22456,22516,22511,22520,22500,22493,22539,22541,22525,22509,22528,22558,22553, +22596,22560,22629,22636,22657,22665,22682,22656,39336,40729,25087,33401,33405, +33407,33423,33418,33448,33412,33422,33425,33431,33433,33451,33464,33470,33456, +33480,33482,33507,33432,33463,33454,33483,33484,33473,33449,33460,33441,33450, +33439,33476,33486,33444,33505,33545,33527,33508,33551,33543,33500,33524,33490, +33496,33548,33531,33491,33553,33562,33542,33556,33557,33504,33493,33564,33617, +33627,33628,33544,33682,33596,33588,33585,33691,33630,33583,33615,33607,33603, +33631,33600,33559,33632,33581,33594,33587,33638,33637,33640,33563,33641,33644, +33642,33645,33646,33712,33656,33715,33716,33696,33706,33683,33692,33669,33660, +33718,33705,33661,33720,33659,33688,33694,33704,33722,33724,33729,33793,33765, +33752,22535,33816,33803,33757,33789,33750,33820,33848,33809,33798,33748,33759, +33807,33795,33784,33785,33770,33733,33728,33830,33776,33761,33884,33873,33882, +33881,33907,33927,33928,33914,33929,33912,33852,33862,33897,33910,33932,33934, +33841,33901,33985,33997,34000,34022,33981,34003,33994,33983,33978,34016,33953, +33977,33972,33943,34021,34019,34060,29965,34104,34032,34105,34079,34106,34134, +34107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171, +34212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241, +34268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869, +22874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306, +25303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524, +25453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550, +25682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732, +25709,25750,25722,25783,25784,25753,25786,25792,25808,25815,25828,25826,25865, +25893,25902,24331,24530,29977,24337,21343,21489,21501,21481,21480,21499,21522, +21526,21510,21579,21586,21587,21588,21590,21571,21537,21591,21593,21539,21554, +21634,21652,21623,21617,21604,21658,21659,21636,21622,21606,21661,21712,21677, +21698,21684,21714,21671,21670,21715,21716,21618,21667,21717,21691,21695,21708, +21721,21722,21724,21673,21674,21668,21725,21711,21726,21787,21735,21792,21757, +21780,21747,21794,21795,21775,21777,21799,21802,21863,21903,21941,21833,21869, +21825,21845,21823,21840,21820,21815,21846,21877,21878,21879,21811,21808,21852, +21899,21970,21891,21937,21945,21896,21889,21919,21886,21974,21905,21883,21983, +21949,21950,21908,21913,21994,22007,21961,22047,21969,21995,21996,21972,21990, +21981,21956,21999,21989,22002,22003,21964,21965,21992,22005,21988,36756,22046, +22024,22028,22017,22052,22051,22014,22016,22055,22061,22104,22073,22103,22060, +22093,22114,22105,22108,22092,22100,22150,22116,22129,22123,22139,22140,22149, +22163,22191,22228,22231,22237,22241,22261,22251,22265,22271,22276,22282,22281, +22300,24079,24089,24084,24081,24113,24123,24124,24119,24132,24148,24155,24158, +24161,23692,23674,23693,23696,23702,23688,23704,23705,23697,23706,23708,23733, +23714,23741,23724,23723,23729,23715,23745,23735,23748,23762,23780,23755,23781, +23810,23811,23847,23846,23854,23844,23838,23814,23835,23896,23870,23860,23869, +23916,23899,23919,23901,23915,23883,23882,23913,23924,23938,23961,23965,35955, +23991,24005,24435,24439,24450,24455,24457,24460,24469,24473,24476,24488,24493, +24501,24508,34914,24417,29357,29360,29364,29367,29368,29379,29377,29390,29389, +29394,29416,29423,29417,29426,29428,29431,29441,29427,29443,29434,29435,29463, +29459,29473,29450,29470,29469,29461,29474,29497,29477,29484,29496,29489,29520, +29517,29527,29536,29548,29551,29566,33307,22821,39143,22820,22786,39267,39271, +39272,39273,39274,39275,39276,39284,39287,39293,39296,39300,39303,39306,39309, +39312,39313,39315,39316,39317,24192,24209,24203,24214,24229,24224,24249,24245, +24254,24243,36179,24274,24273,24283,24296,24298,33210,24516,24521,24534,24527, +24579,24558,24580,24545,24548,24574,24581,24582,24554,24557,24568,24601,24629, +24614,24603,24591,24589,24617,24619,24586,24639,24609,24696,24697,24699,24698, +24642,24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,24812,24763, +24753,24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,24832,24846, +24875,24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,38377,38379, +38385,38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,38411,38412, +38413,38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,27701,27732, +27740,27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,27782,27817, +27856,27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,27883,27886, +27825,27859,27887,27902,27961,27943,27916,27971,27976,27911,27908,27929,27918, +27947,27981,27950,27957,27930,27983,27986,27988,27955,28049,28015,28062,28064, +27998,28051,28052,27996,28000,28028,28003,28186,28103,28101,28126,28174,28095, +28128,28177,28134,28125,28121,28182,28075,28172,28078,28203,28270,28238,28267, +28338,28255,28294,28243,28244,28210,28197,28228,28383,28337,28312,28384,28461, +28386,28325,28327,28349,28347,28343,28375,28340,28367,28303,28354,28319,28514, +28486,28487,28452,28437,28409,28463,28470,28491,28532,28458,28425,28457,28553, +28557,28556,28536,28530,28540,28538,28625,28617,28583,28601,28598,28610,28641, +28654,28638,28640,28655,28698,28707,28699,28729,28725,28751,28766,23424,23428, +23445,23443,23461,23480,29999,39582,25652,23524,23534,35120,23536,36423,35591, +36790,36819,36821,36837,36846,36836,36841,36838,36851,36840,36869,36868,36875, +36902,36881,36877,36886,36897,36917,36918,36909,36911,36932,36945,36946,36944, +36968,36952,36962,36955,26297,36980,36989,36994,37000,36995,37003,24400,24407, +24406,24408,23611,21675,23632,23641,23409,23651,23654,32700,24362,24361,24365, +33396,24380,39739,23662,22913,22915,22925,22953,22954,22947,22935,22986,22955, +22942,22948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,23000, +23033,23052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,23100, +23138,23157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,23224, +23264,23267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,23360, +23573,23580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,39551, +39549,39552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,39580, +39581,39583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,32425, +32429,32432,32446,32448,32449,32450,32457,32459,32460,32464,32468,32471,32475, +32480,32481,32488,32491,32494,32495,32497,32498,32525,32502,32506,32507,32510, +32513,32514,32515,32519,32520,32523,32524,32527,32529,32530,32535,32537,32540, +32539,32543,32545,32546,32547,32548,32549,32550,32551,32554,32555,32556,32557, +32559,32560,32561,32562,32563,32565,24186,30079,24027,30014,37013,29582,29585, +29614,29602,29599,29647,29634,29649,29623,29619,29632,29641,29640,29669,29657, +39036,29706,29673,29671,29662,29626,29682,29711,29738,29787,29734,29733,29736, +29744,29742,29740,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822, +29852,29838,29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882, +38890,38891,38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520, +26535,26485,26536,26526,26541,26507,26487,26492,26608,26633,26584,26634,26601, +26544,26636,26585,26549,26586,26547,26589,26624,26563,26552,26594,26638,26561, +26621,26674,26675,26720,26721,26702,26722,26692,26724,26755,26653,26709,26726, +26689,26727,26688,26686,26698,26697,26665,26805,26767,26740,26743,26771,26731, +26818,26990,26876,26911,26912,26873,26916,26864,26891,26881,26967,26851,26896, +26993,26937,26976,26946,26973,27012,26987,27008,27032,27000,26932,27084,27015, +27016,27086,27017,26982,26979,27001,27035,27047,27067,27051,27053,27092,27057, +27073,27082,27103,27029,27104,27021,27135,27183,27117,27159,27160,27237,27122, +27204,27198,27296,27216,27227,27189,27278,27257,27197,27176,27224,27260,27281, +27280,27305,27287,27307,29495,29522,27521,27522,27527,27524,27538,27539,27533, +27546,27547,27553,27562,36715,36717,36721,36722,36723,36725,36726,36728,36727, +36729,36730,36732,36734,36737,36738,36740,36743,36747,36749,36750,36751,36760, +36762,36558,25099,25111,25115,25119,25122,25121,25125,25124,25132,33255,29935, +29940,29951,29967,29969,29971,25908,26094,26095,26096,26122,26137,26482,26115, +26133,26112,28805,26359,26141,26164,26161,26166,26165,32774,26207,26196,26177, +26191,26198,26209,26199,26231,26244,26252,26279,26269,26302,26331,26332,26342, +26345,36146,36147,36150,36155,36157,36160,36165,36166,36168,36169,36167,36173, +36181,36185,35271,35274,35275,35276,35278,35279,35280,35281,29294,29343,29277, +29286,29295,29310,29311,29316,29323,29325,29327,29330,25352,25394,25520,25663, +25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,27672, +27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,29270, +29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,32948, +32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,32989, +33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,33054, +33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,33148, +33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,26406, +33226,33211,33217,33190,27428,27447,27449,27459,27462,27481,39121,39122,39123, +39125,39129,39130,27571,24384,27586,35315,26000,40785,26003,26044,26054,26052, +26051,26060,26062,26066,26070,28800,28828,28822,28829,28859,28864,28855,28843, +28849,28904,28874,28944,28947,28950,28975,28977,29043,29020,29032,28997,29042, +29002,29048,29050,29080,29107,29109,29096,29088,29152,29140,29159,29177,29213, +29224,28780,28952,29030,29113,25150,25149,25155,25160,25161,31035,31040,31046, +31049,31067,31068,31059,31066,31074,31063,31072,31087,31079,31098,31109,31114, +31130,31143,31155,24529,24528,24636,24669,24666,24679,24641,24665,24675,24747, +24838,24845,24925,25001,24989,25035,25041,25094,32896,32895,27795,27894,28156, +30710,30712,30720,30729,30743,30744,30737,26027,30765,30748,30749,30777,30778, +30779,30751,30780,30757,30764,30755,30761,30798,30829,30806,30807,30758,30800, +30791,30796,30826,30875,30867,30874,30855,30876,30881,30883,30898,30905,30885, +30932,30937,30921,30956,30962,30981,30964,30995,31012,31006,31028,40859,40697, +40699,40700,30449,30468,30477,30457,30471,30472,30490,30498,30489,30509,30502, +30517,30520,30544,30545,30535,30531,30554,30568,30562,30565,30591,30605,30589, +30592,30604,30609,30623,30624,30640,30645,30653,30010,30016,30030,30027,30024, +30043,30066,30073,30083,32600,32609,32607,35400,32616,32628,32625,32633,32641, +32638,30413,30437,34866,38021,38022,38023,38027,38026,38028,38029,38031,38032, +38036,38039,38037,38042,38043,38044,38051,38052,38059,38058,38061,38060,38063, +38064,38066,38068,38070,38071,38072,38073,38074,38076,38077,38079,38084,38088, +38089,38090,38091,38092,38093,38094,38096,38097,38098,38101,38102,38103,38105, +38104,38107,38110,38111,38112,38114,38116,38117,38119,38120,38122,38121,38123, +38126,38127,38131,38132,38133,38135,38137,38140,38141,38143,38147,38146,38150, +38151,38153,38154,38157,38158,38159,38162,38163,38164,38165,38166,38168,38171, +38173,38174,38175,38178,38186,38187,38185,38188,38193,38194,38196,38198,38199, +38200,38204,38206,38207,38210,38197,38212,38213,38214,38217,38220,38222,38223, +38226,38227,38228,38230,38231,38232,38233,38235,38238,38239,38237,38241,38242, +38244,38245,38246,38247,38248,38249,38250,38251,38252,38255,38257,38258,38259, +38202,30695,30700,38601,31189,31213,31203,31211,31238,23879,31235,31234,31262, +31252,31289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918, +29920,29996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504, +40503,40505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524, +40526,40529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553, +40554,40555,40556,40561,40557,40563,30098,30100,30102,30112,30109,30124,30115, +30131,30132,30136,30148,30129,30128,30147,30146,30166,30157,30179,30184,30182, +30180,30187,30183,30211,30193,30204,30207,30224,30208,30213,30220,30231,30218, +30245,30232,30229,30233,30235,30268,30242,30240,30272,30253,30256,30271,30261, +30275,30270,30259,30285,30302,30292,30300,30294,30315,30319,32714,31462,31352, +31353,31360,31366,31368,31381,31398,31392,31404,31400,31405,31411,34916,34921, +34930,34941,34943,34946,34978,35014,34999,35004,35017,35042,35022,35043,35045, +35057,35098,35068,35048,35070,35056,35105,35097,35091,35099,35082,35124,35115, +35126,35137,35174,35195,30091,32997,30386,30388,30684,32786,32788,32790,32796, +32800,32802,32805,32806,32807,32809,32808,32817,32779,32821,32835,32838,32845, +32850,32873,32881,35203,39032,39040,39043,39049,39052,39053,39055,39060,39066, +39067,39070,39071,39073,39074,39077,39078,34381,34388,34412,34414,34431,34426, +34428,34427,34472,34445,34443,34476,34461,34471,34467,34474,34451,34473,34486, +34500,34485,34510,34480,34490,34481,34479,34505,34511,34484,34537,34545,34546, +34541,34547,34512,34579,34526,34548,34527,34520,34513,34563,34567,34552,34568, +34570,34573,34569,34595,34619,34590,34597,34606,34586,34622,34632,34612,34609, +34601,34615,34623,34690,34594,34685,34686,34683,34656,34672,34636,34670,34699, +34643,34659,34684,34660,34649,34661,34707,34735,34728,34770,34758,34696,34693, +34733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,34752, +34762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,34876, +32566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,31531, +31503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,31518, +31576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,31632, +31654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,31697, +31681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,31755, +31775,31786,31782,31800,31809,31808,33278,33281,33282,33284,33260,34884,33313, +33314,33315,33325,33327,33320,33323,33336,33339,33331,33332,33342,33348,33353, +33355,33359,33370,33375,33384,34942,34949,34952,35032,35039,35166,32669,32671, +32679,32687,32688,32690,31868,25929,31889,31901,31900,31902,31906,31922,31932, +31933,31937,31943,31948,31949,31944,31941,31959,31976,33390,26280,32703,32718, +32725,32741,32737,32742,32745,32750,32755,31992,32119,32166,32174,32327,32411, +40632,40628,36211,36228,36244,36241,36273,36199,36205,35911,35913,37194,37200, +37198,37199,37220,37218,37217,37232,37225,37231,37245,37246,37234,37236,37241, +37260,37253,37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,37300, +37306,35925,40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,36292, +36310,36311,36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,36345, +36347,36324,36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,36416, +36409,36405,36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,36476, +36463,36468,36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,35992, +35988,26011,35286,35294,35290,35292,35301,35307,35311,35390,35622,38739,38633, +38643,38639,38662,38657,38664,38671,38670,38698,38701,38704,38718,40832,40835, +40837,40838,40839,40840,40841,40842,40844,40702,40715,40717,38585,38588,38589, +38606,38610,30655,38624,37518,37550,37576,37694,37738,37834,37775,37950,37995, +40063,40066,40069,40070,40071,40072,31267,40075,40078,40080,40081,40082,40084, +40085,40090,40091,40094,40095,40096,40097,40098,40099,40101,40102,40103,40104, +40105,40107,40109,40110,40112,40113,40114,40115,40116,40117,40118,40119,40122, +40123,40124,40125,40132,40133,40134,40135,40138,40139,40140,40141,40142,40143, +40144,40147,40148,40149,40151,40152,40153,40156,40157,40159,40162,38780,38789, +38801,38802,38804,38831,38827,38819,38834,38836,39601,39600,39607,40536,39606, +39610,39612,39617,39616,39621,39618,39627,39628,39633,39749,39747,39751,39753, +39752,39757,39761,39144,39181,39214,39253,39252,39647,39649,39654,39663,39659, +39675,39661,39673,39688,39695,39699,39711,39715,40637,40638,32315,40578,40583, +40584,40587,40594,37846,40605,40607,40667,40668,40669,40672,40671,40674,40681, +40679,40677,40682,40687,40738,40748,40751,40761,40759,40765,40766,40772, +}; + +static const struct dbcs_index gb2312_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb2312_decmap+0,33,126},{__gb2312_decmap+94, +49,124},{__gb2312_decmap+170,33,126},{__gb2312_decmap+264,33,115},{ +__gb2312_decmap+347,33,118},{__gb2312_decmap+433,33,88},{__gb2312_decmap+489, +33,113},{__gb2312_decmap+570,33,105},{__gb2312_decmap+643,36,111},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb2312_decmap+719,33,126},{ +__gb2312_decmap+813,33,126},{__gb2312_decmap+907,33,126},{__gb2312_decmap+1001 +,33,126},{__gb2312_decmap+1095,33,126},{__gb2312_decmap+1189,33,126},{ +__gb2312_decmap+1283,33,126},{__gb2312_decmap+1377,33,126},{__gb2312_decmap+ +1471,33,126},{__gb2312_decmap+1565,33,126},{__gb2312_decmap+1659,33,126},{ +__gb2312_decmap+1753,33,126},{__gb2312_decmap+1847,33,126},{__gb2312_decmap+ +1941,33,126},{__gb2312_decmap+2035,33,126},{__gb2312_decmap+2129,33,126},{ +__gb2312_decmap+2223,33,126},{__gb2312_decmap+2317,33,126},{__gb2312_decmap+ +2411,33,126},{__gb2312_decmap+2505,33,126},{__gb2312_decmap+2599,33,126},{ +__gb2312_decmap+2693,33,126},{__gb2312_decmap+2787,33,126},{__gb2312_decmap+ +2881,33,126},{__gb2312_decmap+2975,33,126},{__gb2312_decmap+3069,33,126},{ +__gb2312_decmap+3163,33,126},{__gb2312_decmap+3257,33,126},{__gb2312_decmap+ +3351,33,126},{__gb2312_decmap+3445,33,126},{__gb2312_decmap+3539,33,126},{ +__gb2312_decmap+3633,33,126},{__gb2312_decmap+3727,33,126},{__gb2312_decmap+ +3821,33,126},{__gb2312_decmap+3915,33,126},{__gb2312_decmap+4009,33,126},{ +__gb2312_decmap+4103,33,126},{__gb2312_decmap+4197,33,126},{__gb2312_decmap+ +4291,33,126},{__gb2312_decmap+4385,33,121},{__gb2312_decmap+4474,33,126},{ +__gb2312_decmap+4568,33,126},{__gb2312_decmap+4662,33,126},{__gb2312_decmap+ +4756,33,126},{__gb2312_decmap+4850,33,126},{__gb2312_decmap+4944,33,126},{ +__gb2312_decmap+5038,33,126},{__gb2312_decmap+5132,33,126},{__gb2312_decmap+ +5226,33,126},{__gb2312_decmap+5320,33,126},{__gb2312_decmap+5414,33,126},{ +__gb2312_decmap+5508,33,126},{__gb2312_decmap+5602,33,126},{__gb2312_decmap+ +5696,33,126},{__gb2312_decmap+5790,33,126},{__gb2312_decmap+5884,33,126},{ +__gb2312_decmap+5978,33,126},{__gb2312_decmap+6072,33,126},{__gb2312_decmap+ +6166,33,126},{__gb2312_decmap+6260,33,126},{__gb2312_decmap+6354,33,126},{ +__gb2312_decmap+6448,33,126},{__gb2312_decmap+6542,33,126},{__gb2312_decmap+ +6636,33,126},{__gb2312_decmap+6730,33,126},{__gb2312_decmap+6824,33,126},{ +__gb2312_decmap+6918,33,126},{__gb2312_decmap+7012,33,126},{__gb2312_decmap+ +7106,33,126},{__gb2312_decmap+7200,33,126},{__gb2312_decmap+7294,33,126},{ +__gb2312_decmap+7388,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const ucs2_t __gbkext_decmap[14531] = { +19970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009, +20014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042, +20049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075, +20076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091, +20092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,U,20112, +20118,20119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150, +20151,20152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187, +20188,20192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217, +20218,20220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236, +20242,20243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269, +20270,20273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292, +20293,20295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326, +20328,20330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349, +20352,20353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373, +20374,20376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400, +20401,20402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414, +20416,20417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436, +20437,20438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466, +20468,20469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483, +20484,20485,20486,20487,20488,20489,20490,U,20491,20494,20496,20497,20499, +20501,20502,20503,20507,20509,20510,20512,20514,20515,20516,20519,20523,20527, +20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20539,20541,20543, +20544,20545,20546,20548,20549,20550,20553,20554,20555,20557,20560,20561,20562, +20563,20564,20566,20567,20568,20569,20571,20573,20574,20575,20576,20577,20578, +20579,20580,20582,20583,20584,20585,20586,20587,20589,20590,20591,20592,20593, +20594,20595,20596,20597,20600,20601,20602,20604,20605,20609,20610,20611,20612, +20614,20615,20617,20618,20619,20620,20622,20623,20624,20625,20626,20627,20628, +20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641, +20642,20644,20646,20650,20651,20653,20654,20655,20656,20657,20659,20660,20661, +20662,20663,20664,20665,20668,20669,20670,20671,20672,20673,20674,20675,20676, +20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,20688,20689,20690, +20691,20692,20693,20695,20696,20697,20699,20700,20701,20702,20703,20704,20705, +20706,20707,20708,20709,20712,20713,20714,20715,20719,20720,20721,20722,20724, +20726,20727,20728,20729,20730,20732,20733,20734,20735,20736,20737,20738,20739, +20740,20741,20744,U,20745,20746,20748,20749,20750,20751,20752,20753,20755, +20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,20768, +20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782, +20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,20795, +20796,20797,20798,20802,20807,20810,20812,20814,20815,20816,20818,20819,20823, +20824,20825,20827,20829,20830,20831,20832,20833,20835,20836,20838,20839,20841, +20842,20847,20850,20858,20862,20863,20867,20868,20870,20871,20874,20875,20878, +20879,20880,20881,20883,20884,20888,20890,20893,20894,20895,20897,20899,20902, +20903,20904,20905,20906,20909,20910,20916,20920,20921,20922,20926,20927,20929, +20930,20931,20933,20936,20938,20941,20942,20944,20946,20947,20948,20949,20950, +20951,20952,20953,20954,20956,20958,20959,20962,20963,20965,20966,20967,20968, +20969,20970,20972,20974,20977,20978,20980,20983,20990,20996,20997,21001,21003, +21004,21007,21008,21011,21012,21013,21020,21022,21023,21025,21026,21027,21029, +21030,21031,21034,21036,21039,21041,21042,21044,21045,21052,21054,21060,21061, +21062,21063,21064,21065,21067,21070,21071,21074,21075,21077,21079,21080,U, +21081,21082,21083,21085,21087,21088,21090,21091,21092,21094,21096,21099,21100, +21101,21102,21104,21105,21107,21108,21109,21110,21111,21112,21113,21114,21115, +21116,21118,21120,21123,21124,21125,21126,21127,21129,21130,21131,21132,21133, +21134,21135,21137,21138,21140,21141,21142,21143,21144,21145,21146,21148,21156, +21157,21158,21159,21166,21167,21168,21172,21173,21174,21175,21176,21177,21178, +21179,21180,21181,21184,21185,21186,21188,21189,21190,21192,21194,21196,21197, +21198,21199,21201,21203,21204,21205,21207,21209,21210,21211,21212,21213,21214, +21216,21217,21218,21219,21221,21222,21223,21224,21225,21226,21227,21228,21229, +21230,21231,21233,21234,21235,21236,21237,21238,21239,21240,21243,21244,21245, +21249,21250,21251,21252,21255,21257,21258,21259,21260,21262,21265,21266,21267, +21268,21272,21275,21276,21278,21279,21282,21284,21285,21287,21288,21289,21291, +21292,21293,21295,21296,21297,21298,21299,21300,21301,21302,21303,21304,21308, +21309,21312,21314,21316,21318,21323,21324,21325,21328,21332,21336,21337,21339, +21341,21349,21352,21354,21356,21357,21362,21366,21369,21371,21372,21373,21374, +21376,21377,21379,21383,21384,21386,21390,21391,U,21392,21393,21394,21395, +21396,21398,21399,21401,21403,21404,21406,21408,21409,21412,21415,21418,21419, +21420,21421,21423,21424,21425,21426,21427,21428,21429,21431,21432,21433,21434, +21436,21437,21438,21440,21443,21444,21445,21446,21447,21454,21455,21456,21458, +21459,21461,21466,21468,21469,21470,21473,21474,21479,21492,21498,21502,21503, +21504,21506,21509,21511,21515,21524,21528,21529,21530,21532,21538,21540,21541, +21546,21552,21555,21558,21559,21562,21565,21567,21569,21570,21572,21573,21575, +21577,21580,21581,21582,21583,21585,21594,21597,21598,21599,21600,21601,21603, +21605,21607,21609,21610,21611,21612,21613,21614,21615,21616,21620,21625,21626, +21630,21631,21633,21635,21637,21639,21640,21641,21642,21645,21649,21651,21655, +21656,21660,21662,21663,21664,21665,21666,21669,21678,21680,21682,21685,21686, +21687,21689,21690,21692,21694,21699,21701,21706,21707,21718,21720,21723,21728, +21729,21730,21731,21732,21739,21740,21743,21744,21745,21748,21749,21750,21751, +21752,21753,21755,21758,21760,21762,21763,21764,21765,21768,21770,21771,21772, +21773,21774,21778,21779,21781,21782,21783,21784,21785,21786,21788,21789,21790, +21791,21793,21797,21798,U,21800,21801,21803,21805,21810,21812,21813,21814, +21816,21817,21818,21819,21821,21824,21826,21829,21831,21832,21835,21836,21837, +21838,21839,21841,21842,21843,21844,21847,21848,21849,21850,21851,21853,21854, +21855,21856,21858,21859,21864,21865,21867,21871,21872,21873,21874,21875,21876, +21881,21882,21885,21887,21893,21894,21900,21901,21902,21904,21906,21907,21909, +21910,21911,21914,21915,21918,21920,21921,21922,21923,21924,21925,21926,21928, +21929,21930,21931,21932,21933,21934,21935,21936,21938,21940,21942,21944,21946, +21948,21951,21952,21953,21954,21955,21958,21959,21960,21962,21963,21966,21967, +21968,21973,21975,21976,21977,21978,21979,21982,21984,21986,21991,21993,21997, +21998,22000,22001,22004,22006,22008,22009,22010,22011,22012,22015,22018,22019, +22020,22021,22022,22023,22026,22027,22029,22032,22033,22034,22035,22036,22037, +22038,22039,22041,22042,22044,22045,22048,22049,22050,22053,22054,22056,22057, +22058,22059,22062,22063,22064,22067,22069,22071,22072,22074,22076,22077,22078, +22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22095, +22096,22097,22098,22099,22101,22102,22106,22107,22109,22110,22111,22112,22113, +U,22115,22117,22118,22119,22125,22126,22127,22128,22130,22131,22132,22133, +22135,22136,22137,22138,22141,22142,22143,22144,22145,22146,22147,22148,22151, +22152,22153,22154,22155,22156,22157,22160,22161,22162,22164,22165,22166,22167, +22168,22169,22170,22171,22172,22173,22174,22175,22176,22177,22178,22180,22181, +22182,22183,22184,22185,22186,22187,22188,22189,22190,22192,22193,22194,22195, +22196,22197,22198,22200,22201,22202,22203,22205,22206,22207,22208,22209,22210, +22211,22212,22213,22214,22215,22216,22217,22219,22220,22221,22222,22223,22224, +22225,22226,22227,22229,22230,22232,22233,22236,22243,22245,22246,22247,22248, +22249,22250,22252,22254,22255,22258,22259,22262,22263,22264,22267,22268,22272, +22273,22274,22277,22279,22283,22284,22285,22286,22287,22288,22289,22290,22291, +22292,22293,22294,22295,22296,22297,22298,22299,22301,22302,22304,22305,22306, +22308,22309,22310,22311,22315,22321,22322,22324,22325,22326,22327,22328,22332, +22333,22335,22337,22339,22340,22341,22342,22344,22345,22347,22354,22355,22356, +22357,22358,22360,22361,22370,22371,22373,22375,22380,22382,22384,22385,22386, +22388,22389,22392,22393,22394,22397,22398,22399,22400,U,22401,22407,22408, +22409,22410,22413,22414,22415,22416,22417,22420,22421,22422,22423,22424,22425, +22426,22428,22429,22430,22431,22437,22440,22442,22444,22447,22448,22449,22451, +22453,22454,22455,22457,22458,22459,22460,22461,22462,22463,22464,22465,22468, +22469,22470,22471,22472,22473,22474,22476,22477,22480,22481,22483,22486,22487, +22491,22492,22494,22497,22498,22499,22501,22502,22503,22504,22505,22506,22507, +22508,22510,22512,22513,22514,22515,22517,22518,22519,22523,22524,22526,22527, +22529,22531,22532,22533,22536,22537,22538,22540,22542,22543,22544,22546,22547, +22548,22550,22551,22552,22554,22555,22556,22557,22559,22562,22563,22565,22566, +22567,22568,22569,22571,22572,22573,22574,22575,22577,22578,22579,22580,22582, +22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595, +22597,22598,22599,22600,22601,22602,22603,22606,22607,22608,22610,22611,22613, +22614,22615,22617,22618,22619,22620,22621,22623,22624,22625,22626,22627,22628, +22630,22631,22632,22633,22634,22637,22638,22639,22640,22641,22642,22643,22644, +22645,22646,22647,22648,22649,22650,22651,22652,22653,22655,22658,22660,22662, +22663,22664,22666,22667,22668,U,22669,22670,22671,22672,22673,22676,22677, +22678,22679,22680,22683,22684,22685,22688,22689,22690,22691,22692,22693,22694, +22695,22698,22699,22700,22701,22702,22703,22704,22705,22706,22707,22708,22709, +22710,22711,22712,22713,22714,22715,22717,22718,22719,22720,22722,22723,22724, +22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22738,22739, +22740,22742,22743,22744,22745,22746,22747,22748,22749,22750,22751,22752,22753, +22754,22755,22757,22758,22759,22760,22761,22762,22765,22767,22769,22770,22772, +22773,22775,22776,22778,22779,22780,22781,22782,22783,22784,22785,22787,22789, +22790,22792,22793,22794,22795,22796,22798,22800,22801,22802,22803,22807,22808, +22811,22813,22814,22816,22817,22818,22819,22822,22824,22828,22832,22834,22835, +22837,22838,22843,22845,22846,22847,22848,22851,22853,22854,22858,22860,22861, +22864,22866,22867,22873,22875,22876,22877,22878,22879,22881,22883,22884,22886, +22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,22897,22898,22901, +22903,22906,22907,22908,22910,22911,22912,22917,22921,22923,22924,22926,22927, +22928,22929,22932,22933,22936,22938,22939,22940,22941,22943,22944,22945,22946, +22950,U,22951,22956,22957,22960,22961,22963,22964,22965,22966,22967,22968, +22970,22972,22973,22975,22976,22977,22978,22979,22980,22981,22983,22984,22985, +22988,22989,22990,22991,22997,22998,23001,23003,23006,23007,23008,23009,23010, +23012,23014,23015,23017,23018,23019,23021,23022,23023,23024,23025,23026,23027, +23028,23029,23030,23031,23032,23034,23036,23037,23038,23040,23042,23050,23051, +23053,23054,23055,23056,23058,23060,23061,23062,23063,23065,23066,23067,23069, +23070,23073,23074,23076,23078,23079,23080,23082,23083,23084,23085,23086,23087, +23088,23091,23093,23095,23096,23097,23098,23099,23101,23102,23103,23105,23106, +23107,23108,23109,23111,23112,23115,23116,23117,23118,23119,23120,23121,23122, +23123,23124,23126,23127,23128,23129,23131,23132,23133,23134,23135,23136,23137, +23139,23140,23141,23142,23144,23145,23147,23148,23149,23150,23151,23152,23153, +23154,23155,23160,23161,23163,23164,23165,23166,23168,23169,23170,23171,23172, +23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,23183,23184,23185, +23187,23188,23189,23190,23191,23192,23193,23196,23197,23198,23199,23200,23201, +23202,23203,23204,23205,23206,23207,23208,23209,23211,23212,U,23213,23214, +23215,23216,23217,23220,23222,23223,23225,23226,23227,23228,23229,23231,23232, +23235,23236,23237,23238,23239,23240,23242,23243,23245,23246,23247,23248,23249, +23251,23253,23255,23257,23258,23259,23261,23262,23263,23266,23268,23269,23271, +23272,23274,23276,23277,23278,23279,23280,23282,23283,23284,23285,23286,23287, +23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,23300, +23301,23302,23303,23304,23306,23307,23308,23309,23310,23311,23312,23313,23314, +23315,23316,23317,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329, +23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,23341,23342, +23343,23344,23345,23347,23349,23350,23352,23353,23354,23355,23356,23357,23358, +23359,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,23372, +23373,23374,23375,23378,23382,23390,23392,23393,23399,23400,23403,23405,23406, +23407,23410,23412,23414,23415,23416,23417,23419,23420,23422,23423,23426,23430, +23434,23437,23438,23440,23441,23442,23444,23446,23455,23463,23464,23465,23468, +23469,23470,23471,23473,23474,23479,23482,23483,23484,23488,23489,23491,23496, +23497,23498,23499,23501,23502,23503,U,23505,23508,23509,23510,23511,23512, +23513,23514,23515,23516,23520,23522,23523,23526,23527,23529,23530,23531,23532, +23533,23535,23537,23538,23539,23540,23541,23542,23543,23549,23550,23552,23554, +23555,23557,23559,23560,23563,23564,23565,23566,23568,23570,23571,23575,23577, +23579,23582,23583,23584,23585,23587,23590,23592,23593,23594,23595,23597,23598, +23599,23600,23602,23603,23605,23606,23607,23619,23620,23622,23623,23628,23629, +23634,23635,23636,23638,23639,23640,23642,23643,23644,23645,23647,23650,23652, +23655,23656,23657,23658,23659,23660,23661,23664,23666,23667,23668,23669,23670, +23671,23672,23675,23676,23677,23678,23680,23683,23684,23685,23686,23687,23689, +23690,23691,23694,23695,23698,23699,23701,23709,23710,23711,23712,23713,23716, +23717,23718,23719,23720,23722,23726,23727,23728,23730,23732,23734,23737,23738, +23739,23740,23742,23744,23746,23747,23749,23750,23751,23752,23753,23754,23756, +23757,23758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,23771, +23772,23773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,23791, +23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,23806, +23807,23808,U,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823, +23824,23825,23826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840, +23841,23842,23843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859, +23861,23862,23863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875, +23876,23877,23878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892, +23893,23894,23895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908, +23909,23910,23911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926, +23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940, +23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953, +23954,23955,23956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968, +23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981, +23982,23983,23984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995, +23996,23997,23998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009, +24010,24011,24012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023, +24024,24025,24026,24028,24031,24032,24035,24036,24042,24044,24045,U,24048, +24053,24054,24056,24057,24058,24059,24060,24063,24064,24068,24071,24073,24074, +24075,24077,24078,24082,24083,24087,24094,24095,24096,24097,24098,24099,24100, +24101,24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,24118, +24121,24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,24139, +24141,24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,24156, +24157,24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172, +24173,24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,24197, +24200,24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,24228, +24232,24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,24251, +24252,24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24267, +24268,24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,24285, +24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,24300, +24301,24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,24317, +24325,24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,24346, +24348,24349,24350,24353,24354,24355,24356,U,24360,24363,24364,24366,24368, +24370,24371,24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386, +24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399, +24401,24404,24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424, +24427,24430,24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451, +24454,24461,24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479, +24480,24482,24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497, +24498,24499,24500,24502,24504,24505,24506,24507,24510,24511,24512,24513,24514, +24519,24520,24522,24523,24526,24531,24532,24533,24538,24539,24540,24542,24543, +24546,24547,24549,24550,24552,24553,24556,24559,24560,24562,24563,24564,24566, +24567,24569,24570,24572,24583,24584,24585,24587,24588,24592,24593,24595,24599, +24600,24602,24606,24607,24610,24611,24612,24620,24621,24622,24624,24625,24626, +24627,24628,24630,24631,24632,24633,24634,24637,24638,24640,24644,24645,24646, +24647,24648,24649,24650,24652,24654,24655,24657,24659,24660,24662,24663,24664, +24667,24668,24670,24671,24672,24673,24677,24678,24686,24689,24690,24692,24693, +24695,24702,24704,U,24705,24706,24709,24710,24711,24712,24714,24715,24718, +24719,24720,24721,24723,24725,24727,24728,24729,24732,24734,24737,24738,24740, +24741,24743,24745,24746,24750,24752,24755,24757,24758,24759,24761,24762,24765, +24766,24767,24768,24769,24770,24771,24772,24775,24776,24777,24780,24781,24782, +24783,24784,24786,24787,24788,24790,24791,24793,24795,24798,24801,24802,24803, +24804,24805,24810,24817,24818,24821,24823,24824,24827,24828,24829,24830,24831, +24834,24835,24836,24837,24839,24842,24843,24844,24848,24849,24850,24851,24852, +24854,24855,24856,24857,24859,24860,24861,24862,24865,24866,24869,24872,24873, +24874,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887, +24888,24889,24890,24891,24892,24893,24894,24896,24897,24898,24899,24900,24901, +24902,24903,24905,24907,24909,24911,24912,24914,24915,24916,24918,24919,24920, +24921,24922,24923,24924,24926,24927,24928,24929,24931,24932,24933,24934,24937, +24938,24939,24940,24941,24942,24943,24945,24946,24947,24948,24950,24952,24953, +24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966, +24967,24968,24969,24970,24972,24973,24975,24976,24977,24978,24979,24981,U, +24982,24983,24984,24985,24986,24987,24988,24990,24991,24992,24993,24994,24995, +24996,24997,24998,25002,25003,25005,25006,25007,25008,25009,25010,25011,25012, +25013,25014,25016,25017,25018,25019,25020,25021,25023,25024,25025,25027,25028, +25029,25030,25031,25033,25036,25037,25038,25039,25040,25043,25045,25046,25047, +25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060, +25061,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074, +25075,25076,25078,25079,25080,25081,25082,25083,25084,25085,25086,25088,25089, +25090,25091,25092,25093,25095,25097,25107,25108,25113,25116,25117,25118,25120, +25123,25126,25127,25128,25129,25131,25133,25135,25136,25137,25138,25141,25142, +25144,25145,25146,25147,25148,25154,25156,25157,25158,25162,25167,25168,25173, +25174,25175,25177,25178,25180,25181,25182,25183,25184,25185,25186,25188,25189, +25192,25201,25202,25204,25205,25207,25208,25210,25211,25213,25217,25218,25219, +25221,25222,25223,25224,25227,25228,25229,25230,25231,25232,25236,25241,25244, +25245,25246,25251,25254,25255,25257,25258,25261,25262,25263,25264,25266,25267, +25268,25270,25271,25272,25274,25278,25280,25281,U,25283,25291,25295,25297, +25301,25309,25310,25312,25313,25316,25322,25323,25328,25330,25333,25336,25337, +25338,25339,25344,25347,25348,25349,25350,25354,25355,25356,25357,25359,25360, +25362,25363,25364,25365,25367,25368,25369,25372,25382,25383,25385,25388,25389, +25390,25392,25393,25395,25396,25397,25398,25399,25400,25403,25404,25406,25407, +25408,25409,25412,25415,25416,25418,25425,25426,25427,25428,25430,25431,25432, +25433,25434,25435,25436,25437,25440,25444,25445,25446,25448,25450,25451,25452, +25455,25456,25458,25459,25460,25461,25464,25465,25468,25469,25470,25471,25473, +25475,25476,25477,25478,25483,25485,25489,25491,25492,25493,25495,25497,25498, +25499,25500,25501,25502,25503,25505,25508,25510,25515,25519,25521,25522,25525, +25526,25529,25531,25533,25535,25536,25537,25538,25539,25541,25543,25544,25546, +25547,25548,25553,25555,25556,25557,25559,25560,25561,25562,25563,25564,25565, +25567,25570,25572,25573,25574,25575,25576,25579,25580,25582,25583,25584,25585, +25587,25589,25591,25593,25594,25595,25596,25598,25603,25604,25606,25607,25608, +25609,25610,25613,25614,25617,25618,25621,25622,25623,25624,25625,25626,25629, +25631,25634,25635,25636,U,25637,25639,25640,25641,25643,25646,25647,25648, +25649,25650,25651,25653,25654,25655,25656,25657,25659,25660,25662,25664,25666, +25667,25673,25675,25676,25677,25678,25679,25680,25681,25683,25685,25686,25687, +25689,25690,25691,25692,25693,25695,25696,25697,25698,25699,25700,25701,25702, +25704,25706,25707,25708,25710,25711,25712,25713,25714,25715,25716,25717,25718, +25719,25723,25724,25725,25726,25727,25728,25729,25731,25734,25736,25737,25738, +25739,25740,25741,25742,25743,25744,25747,25748,25751,25752,25754,25755,25756, +25757,25759,25760,25761,25762,25763,25765,25766,25767,25768,25770,25771,25775, +25777,25778,25779,25780,25782,25785,25787,25789,25790,25791,25793,25795,25796, +25798,25799,25800,25801,25802,25803,25804,25807,25809,25811,25812,25813,25814, +25817,25818,25819,25820,25821,25823,25824,25825,25827,25829,25831,25832,25833, +25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846, +25847,25848,25849,25850,25851,25852,25853,25854,25855,25857,25858,25859,25860, +25861,25862,25863,25864,25866,25867,25868,25869,25870,25871,25872,25873,25875, +25876,25877,25878,25879,25881,25882,25883,25884,25885,25886,25887,25888,25889, +U,25890,25891,25892,25894,25895,25896,25897,25898,25900,25901,25904,25905, +25906,25907,25911,25914,25916,25917,25920,25921,25922,25923,25924,25926,25927, +25930,25931,25933,25934,25936,25938,25939,25940,25943,25944,25946,25948,25951, +25952,25953,25956,25957,25959,25960,25961,25962,25965,25966,25967,25969,25971, +25973,25974,25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986, +25987,25988,25989,25990,25992,25993,25994,25997,25998,25999,26002,26004,26005, +26006,26008,26010,26013,26014,26016,26018,26019,26022,26024,26026,26028,26030, +26033,26034,26035,26036,26037,26038,26039,26040,26042,26043,26046,26047,26048, +26050,26055,26056,26057,26058,26061,26064,26065,26067,26068,26069,26072,26073, +26074,26075,26076,26077,26078,26079,26081,26083,26084,26090,26091,26098,26099, +26100,26101,26104,26105,26107,26108,26109,26110,26111,26113,26116,26117,26119, +26120,26121,26123,26125,26128,26129,26130,26134,26135,26136,26138,26139,26140, +26142,26145,26146,26147,26148,26150,26153,26154,26155,26156,26158,26160,26162, +26163,26167,26168,26169,26170,26171,26173,26175,26176,26178,26180,26181,26182, +26183,26184,26185,26186,26189,26190,26192,26193,26200,U,26201,26203,26204, +26205,26206,26208,26210,26211,26213,26215,26217,26218,26219,26220,26221,26225, +26226,26227,26229,26232,26233,26235,26236,26237,26239,26240,26241,26243,26245, +26246,26248,26249,26250,26251,26253,26254,26255,26256,26258,26259,26260,26261, +26264,26265,26266,26267,26268,26270,26271,26272,26273,26274,26275,26276,26277, +26278,26281,26282,26283,26284,26285,26287,26288,26289,26290,26291,26293,26294, +26295,26296,26298,26299,26300,26301,26303,26304,26305,26306,26307,26308,26309, +26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322, +26323,26324,26325,26326,26327,26328,26330,26334,26335,26336,26337,26338,26339, +26340,26341,26343,26344,26346,26347,26348,26349,26350,26351,26353,26357,26358, +26360,26362,26363,26365,26369,26370,26371,26372,26373,26374,26375,26380,26382, +26383,26385,26386,26387,26390,26392,26393,26394,26396,26398,26400,26401,26402, +26403,26404,26405,26407,26409,26414,26416,26418,26419,26422,26423,26424,26425, +26427,26428,26430,26431,26433,26436,26437,26439,26442,26443,26445,26450,26452, +26453,26455,26456,26457,26458,26459,26461,26466,26467,26468,26470,26471,26475, +26476,26478,26481,26484,26486,U,26488,26489,26490,26491,26493,26496,26498, +26499,26501,26502,26504,26506,26508,26509,26510,26511,26513,26514,26515,26516, +26518,26521,26523,26527,26528,26529,26532,26534,26537,26540,26542,26545,26546, +26548,26553,26554,26555,26556,26557,26558,26559,26560,26562,26565,26566,26567, +26568,26569,26570,26571,26572,26573,26574,26581,26582,26583,26587,26591,26593, +26595,26596,26598,26599,26600,26602,26603,26605,26606,26610,26613,26614,26615, +26616,26617,26618,26619,26620,26622,26625,26626,26627,26628,26630,26637,26640, +26642,26644,26645,26648,26649,26650,26651,26652,26654,26655,26656,26658,26659, +26660,26661,26662,26663,26664,26667,26668,26669,26670,26671,26672,26673,26676, +26677,26678,26682,26683,26687,26695,26699,26701,26703,26706,26710,26711,26712, +26713,26714,26715,26716,26717,26718,26719,26730,26732,26733,26734,26735,26736, +26737,26738,26739,26741,26744,26745,26746,26747,26748,26749,26750,26751,26752, +26754,26756,26759,26760,26761,26762,26763,26764,26765,26766,26768,26769,26770, +26772,26773,26774,26776,26777,26778,26779,26780,26781,26782,26783,26784,26785, +26787,26788,26789,26793,26794,26795,26796,26798,26801,26802,26804,26806,26807, +26808,U,26809,26810,26811,26812,26813,26814,26815,26817,26819,26820,26821, +26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,26836,26838,26839, +26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,26854,26855,26856, +26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,26871,26872,26875, +26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,26889,26890,26892, +26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,26907,26908,26909, +26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,26923,26924,26926, +26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,26940,26942,26944, +26945,26947,26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958, +26959,26960,26961,26962,26963,26965,26966,26968,26969,26971,26972,26975,26977, +26978,26980,26981,26983,26984,26985,26986,26988,26989,26991,26992,26994,26995, +26996,26997,26998,27002,27003,27005,27006,27007,27009,27011,27013,27018,27019, +27020,27022,27023,27024,27025,27026,27027,27030,27031,27033,27034,27037,27038, +27039,27040,27041,27042,27043,27044,27045,27046,27049,27050,27052,27054,27055, +27056,27058,27059,27061,27062,27064,27065,27066,27068,27069,U,27070,27071, +27072,27074,27075,27076,27077,27078,27079,27080,27081,27083,27085,27087,27089, +27090,27091,27093,27094,27095,27096,27097,27098,27100,27101,27102,27105,27106, +27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27118,27119,27120, +27121,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,27134,27136, +27137,27138,27139,27140,27141,27142,27143,27144,27145,27147,27148,27149,27150, +27151,27152,27153,27154,27155,27156,27157,27158,27161,27162,27163,27164,27165, +27166,27168,27170,27171,27172,27173,27174,27175,27177,27179,27180,27181,27182, +27184,27186,27187,27188,27190,27191,27192,27193,27194,27195,27196,27199,27200, +27201,27202,27203,27205,27206,27208,27209,27210,27211,27212,27213,27214,27215, +27217,27218,27219,27220,27221,27222,27223,27226,27228,27229,27230,27231,27232, +27234,27235,27236,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247, +27248,27250,27251,27252,27253,27254,27255,27256,27258,27259,27261,27262,27263, +27265,27266,27267,27269,27270,27271,27272,27273,27274,27275,27276,27277,27279, +27282,27283,27284,27285,27286,27288,27289,27290,27291,27292,27293,27294,27295, +27297,27298,27299,27300,27301,27302,U,27303,27304,27306,27309,27310,27311, +27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,27324, +27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,27337, +27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,27350, +27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,27363, +27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,27376, +27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,27389, +27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402, +27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415, +27416,27417,27418,27419,27420,27421,27422,27423,27429,27430,27432,27433,27434, +27435,27436,27437,27438,27439,27440,27441,27443,27444,27445,27446,27448,27451, +27452,27453,27455,27456,27457,27458,27460,27461,27464,27466,27467,27469,27470, +27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27482,27483,27484, +27485,27486,27487,27488,27489,27496,27497,27499,27500,27501,27502,27503,27504, +27505,27506,27507,27508,27509,27510,27511,27512,27514,27517,27518,27519,27520, +27525,27528,U,27532,27534,27535,27536,27537,27540,27541,27543,27544,27545, +27548,27549,27550,27551,27552,27554,27555,27556,27557,27558,27559,27560,27561, +27563,27564,27565,27566,27567,27568,27569,27570,27574,27576,27577,27578,27579, +27580,27581,27582,27584,27587,27588,27590,27591,27592,27593,27594,27596,27598, +27600,27601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621, +27622,27623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639, +27640,27642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657, +27658,27659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691, +27692,27693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715, +27716,27717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736, +27737,27738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761, +27763,27765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787, +27789,27790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808, +27810,27816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842, +27843,27846,27847,27848,27851,27853,27854,27855,27857,27858,27864,U,27865, +27866,27868,27869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897, +27903,27904,27906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921, +27923,27924,27925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940, +27942,27944,27945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967, +27968,27970,27972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999, +28001,28002,28004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019, +28021,28022,28025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038, +28039,28042,28043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060, +28066,28069,28076,28077,28080,28081,28083,28084,28086,28087,28089,28090,28091, +28092,28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,28111,28112, +28114,28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,28133,28135, +28136,28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,28154,28157, +28158,28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,28171,28175, +28178,28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,28199,28200, +28202,28204,28206,28208,28209,28211,28213,U,28214,28215,28217,28219,28220, +28221,28222,28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,28235, +28236,28239,28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,28256, +28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,28271, +28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284, +28285,28288,28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,28305, +28306,28307,28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,28321, +28323,28324,28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,28344, +28345,28348,28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,28364, +28365,28366,28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,28394, +28395,28396,28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,28408, +28410,28411,28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,28424, +28426,28427,28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,28442, +28443,28444,28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,28460, +28462,28464,28466,28468,28469,28471,28472,28473,28474,28475,28476,28477,28479, +28480,28481,28482,U,28483,28484,28485,28488,28489,28490,28492,28494,28495, +28496,28497,28498,28499,28500,28501,28502,28503,28505,28506,28507,28509,28511, +28512,28513,28515,28516,28517,28519,28520,28521,28522,28523,28524,28527,28528, +28529,28531,28533,28534,28535,28537,28539,28541,28542,28543,28544,28545,28546, +28547,28549,28550,28551,28554,28555,28559,28560,28561,28562,28563,28564,28565, +28566,28567,28568,28569,28570,28571,28573,28574,28575,28576,28578,28579,28580, +28581,28582,28584,28585,28586,28587,28588,28589,28590,28591,28592,28593,28594, +28596,28597,28599,28600,28602,28603,28604,28605,28606,28607,28609,28611,28612, +28613,28614,28615,28616,28618,28619,28620,28621,28622,28623,28624,28627,28628, +28629,28630,28631,28632,28633,28634,28635,28636,28637,28639,28642,28643,28644, +28645,28646,28647,28648,28649,28650,28651,28652,28653,28656,28657,28658,28659, +28660,28661,28662,28663,28664,28665,28666,28667,28668,28669,28670,28671,28672, +28673,28674,28675,28676,28677,28678,28679,28680,28681,28682,28683,28684,28685, +28686,28687,28688,28690,28691,28692,28693,28694,28695,28696,28697,28700,28701, +28702,28703,28704,28705,28706,28708,28709,28710,28711,28712,28713,28714,U, +28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,28726,28727,28728, +28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,28740,28741,28742, +28743,28744,28745,28746,28747,28749,28750,28752,28753,28754,28755,28756,28757, +28758,28759,28760,28761,28762,28763,28764,28765,28767,28768,28769,28770,28771, +28772,28773,28774,28775,28776,28777,28778,28782,28785,28786,28787,28788,28791, +28793,28794,28795,28797,28801,28802,28803,28804,28806,28807,28808,28811,28812, +28813,28815,28816,28817,28819,28823,28824,28826,28827,28830,28831,28832,28833, +28834,28835,28836,28837,28838,28839,28840,28841,28842,28848,28850,28852,28853, +28854,28858,28862,28863,28868,28869,28870,28871,28873,28875,28876,28877,28878, +28879,28880,28881,28882,28883,28884,28885,28886,28887,28890,28892,28893,28894, +28896,28897,28898,28899,28901,28906,28910,28912,28913,28914,28915,28916,28917, +28918,28920,28922,28923,28924,28926,28927,28928,28929,28930,28931,28932,28933, +28934,28935,28936,28939,28940,28941,28942,28943,28945,28946,28948,28951,28955, +28956,28957,28958,28959,28960,28961,28962,28963,28964,28965,28967,28968,28969, +28970,28971,28972,28973,28974,28978,28979,28980,U,28981,28983,28984,28985, +28986,28987,28988,28989,28990,28991,28992,28993,28994,28995,28996,28998,28999, +29000,29001,29003,29005,29007,29008,29009,29010,29011,29012,29013,29014,29015, +29016,29017,29018,29019,29021,29023,29024,29025,29026,29027,29029,29033,29034, +29035,29036,29037,29039,29040,29041,29044,29045,29046,29047,29049,29051,29052, +29054,29055,29056,29057,29058,29059,29061,29062,29063,29064,29065,29067,29068, +29069,29070,29072,29073,29074,29075,29077,29078,29079,29082,29083,29084,29085, +29086,29089,29090,29091,29092,29093,29094,29095,29097,29098,29099,29101,29102, +29103,29104,29105,29106,29108,29110,29111,29112,29114,29115,29116,29117,29118, +29119,29120,29121,29122,29124,29125,29126,29127,29128,29129,29130,29131,29132, +29133,29135,29136,29137,29138,29139,29142,29143,29144,29145,29146,29147,29148, +29149,29150,29151,29153,29154,29155,29156,29158,29160,29161,29162,29163,29164, +29165,29167,29168,29169,29170,29171,29172,29173,29174,29175,29176,29178,29179, +29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29191,29192,29193, +29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,29204,29205,29206, +29207,29208,29209,29210,U,29211,29212,29214,29215,29216,29217,29218,29219, +29220,29221,29222,29223,29225,29227,29229,29230,29231,29234,29235,29236,29242, +29244,29246,29248,29249,29250,29251,29252,29253,29254,29257,29258,29259,29262, +29263,29264,29265,29267,29268,29269,29271,29272,29274,29276,29278,29280,29283, +29284,29285,29288,29290,29291,29292,29293,29296,29297,29299,29300,29302,29303, +29304,29307,29308,29309,29314,29315,29317,29318,29319,29320,29321,29324,29326, +29328,29329,29331,29332,29333,29334,29335,29336,29337,29338,29339,29340,29341, +29342,29344,29345,29346,29347,29348,29349,29350,29351,29352,29353,29354,29355, +29358,29361,29362,29363,29365,29370,29371,29372,29373,29374,29375,29376,29381, +29382,29383,29385,29386,29387,29388,29391,29393,29395,29396,29397,29398,29400, +29402,29403,183,U,U,U,U,U,8212,8560,8561,8562,8563,8564,8565,8566,8567,8568, +8569,65077,65078,65081,65082,65087,65088,65085,65086,65089,65090,65091,65092, +U,U,65083,65084,65079,65080,65073,U,65075,65076,714,715,729,8211,8213,8229, +8245,8453,8457,8598,8599,8600,8601,8725,8735,8739,8786,8806,8807,8895,9552, +9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567, +9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582, +9583,9584,9585,9586,9587,9601,9602,9603,9604,9605,9606,9607,U,9608,9609,9610, +9611,9612,9613,9614,9615,9619,9620,9621,9660,9661,9698,9699,9700,9701,9737, +8853,12306,12317,12318,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,593,U,324,328,U,609,12321,12322,12323,12324,12325,12326, +12327,12328,12329,12963,13198,13199,13212,13213,13214,13217,13252,13262,13265, +13266,13269,65072,65506,65508,U,8481,12849,U,8208,U,U,U,12540,12443,12444, +12541,12542,12294,12445,12446,65097,65098,65099,65100,65101,65102,65103,65104, +65105,65106,65108,65109,65110,65111,65113,65114,65115,65116,65117,65118,65119, +65120,65121,U,65122,65123,65124,65125,65126,65128,65129,65130,65131,U,U,U,U,U, +U,U,U,U,U,U,U,U,12295,29404,29405,29407,29410,29411,29412,29413,29414,29415, +29418,29419,29429,29430,29433,29437,29438,29439,29440,29442,29444,29445,29446, +29447,29448,29449,29451,29452,29453,29455,29456,29457,29458,29460,29464,29465, +29466,29471,29472,29475,29476,29478,29479,29480,29485,29487,29488,29490,29491, +29493,29494,29498,29499,29500,29501,29504,29505,29506,29507,29508,29509,29510, +29511,29512,U,29513,29514,29515,29516,29518,29519,29521,29523,29524,29525, +29526,29528,29529,29530,29531,29532,29533,29534,29535,29537,29538,29539,29540, +29541,29542,29543,29544,29545,29546,29547,29550,29552,29553,29554,29555,29556, +29557,29558,29559,29560,29561,29562,29563,29564,29565,29567,29568,29569,29570, +29571,29573,29574,29576,29578,29580,29581,29583,29584,29586,29587,29588,29589, +29591,29592,29593,29594,29596,29597,29598,29600,29601,29603,29604,29605,29606, +29607,29608,29610,29612,29613,29617,29620,29621,29622,29624,29625,29628,29629, +29630,29631,29633,29635,29636,29637,29638,29639,U,29643,29644,29646,29650, +29651,29652,29653,29654,29655,29656,29658,29659,29660,29661,29663,29665,29666, +29667,29668,29670,29672,29674,29675,29676,29678,29679,29680,29681,29683,29684, +29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697, +29698,29700,29703,29704,29707,29708,29709,29710,29713,29714,29715,29716,29717, +29718,29719,29720,29721,29724,29725,29726,29727,29728,29729,29731,29732,29735, +29737,29739,29741,29743,29745,29746,29751,29752,29753,29754,29755,29757,29758, +29759,29760,29762,29763,29764,29765,29766,29767,29768,29769,29770,29771,29772, +29773,U,29774,29775,29776,29777,29778,29779,29780,29782,29784,29789,29792, +29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,29806, +29807,29809,29810,29811,29812,29813,29816,29817,29818,29819,29820,29821,29823, +29826,29828,29829,29830,29832,29833,29834,29836,29837,29839,29841,29842,29843, +29844,29845,29846,29847,29848,29849,29850,29851,29853,29855,29856,29857,29858, +29859,29860,29861,29862,29866,29867,29868,29869,29870,29871,29872,29873,29874, +29875,29876,29877,29878,29879,29880,29881,29883,29884,29885,29886,29887,29888, +29889,29890,29891,29892,29893,29894,29895,U,29896,29897,29898,29899,29900, +29901,29902,29903,29904,29905,29907,29908,29909,29910,29911,29912,29913,29914, +29915,29917,29919,29921,29925,29927,29928,29929,29930,29931,29932,29933,29936, +29937,29938,29939,29941,29944,29945,29946,29947,29948,29949,29950,29952,29953, +29954,29955,29957,29958,29959,29960,29961,29962,29963,29964,29966,29968,29970, +29972,29973,29974,29975,29979,29981,29982,29984,29985,29986,29987,29988,29990, +29991,29994,29998,30004,30006,30009,30012,30013,30015,30017,30018,30019,30020, +30022,30023,30025,30026,30029,30032,30033,30034,30035,30037,30038,30039,30040, +U,30045,30046,30047,30048,30049,30050,30051,30052,30055,30056,30057,30059, +30060,30061,30062,30063,30064,30065,30067,30069,30070,30071,30074,30075,30076, +30077,30078,30080,30081,30082,30084,30085,30087,30088,30089,30090,30092,30093, +30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,30119,30120,30121, +30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,30155,30156,30158, +30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,30176,30177,30181, +30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,30200,30202,30203, +30205,30206,30210,30212,30214,30215,U,30216,30217,30219,30221,30222,30223, +30225,30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,30247,30248, +30252,30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,30273,30274, +30276,30277,30278,30279,30280,30281,30282,30283,30286,30287,30288,30289,30290, +30291,30293,30295,30296,30297,30298,30299,30301,30303,30304,30305,30306,30308, +30309,30310,30311,30312,30313,30314,30316,30317,30318,30320,30321,30322,30323, +30324,30325,30326,30327,30329,30330,30332,30335,30336,30337,30339,30341,30345, +30346,30348,30349,30351,30352,30354,30356,30357,30359,30360,30362,30363,U, +30364,30365,30366,30367,30368,30369,30370,30371,30373,30374,30375,30376,30377, +30378,30379,30380,30381,30383,30384,30387,30389,30390,30391,30392,30393,30394, +30395,30396,30397,30398,30400,30401,30403,30404,30407,30409,30411,30412,30419, +30421,30425,30426,30428,30429,30430,30432,30433,30434,30435,30436,30438,30439, +30440,30441,30442,30443,30444,30445,30448,30451,30453,30454,30455,30458,30459, +30461,30463,30464,30466,30467,30469,30470,30474,30476,30478,30479,30480,30481, +30482,30483,30484,30485,30486,30487,30488,30491,30492,30493,30494,30497,30499, +30500,30501,30503,30506,30507,U,30508,30510,30512,30513,30514,30515,30516, +30521,30523,30525,30526,30527,30530,30532,30533,30534,30536,30537,30538,30539, +30540,30541,30542,30543,30546,30547,30548,30549,30550,30551,30552,30553,30556, +30557,30558,30559,30560,30564,30567,30569,30570,30573,30574,30575,30576,30577, +30578,30579,30580,30581,30582,30583,30584,30586,30587,30588,30593,30594,30595, +30598,30599,30600,30601,30602,30603,30607,30608,30611,30612,30613,30614,30615, +30616,30617,30618,30619,30620,30621,30622,30625,30627,30628,30630,30632,30635, +30637,30638,30639,30641,30642,30644,30646,30647,30648,30649,30650,U,30652, +30654,30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667, +30668,30670,30671,30672,30673,30674,30675,30676,30677,30678,30680,30681,30682, +30685,30686,30687,30688,30689,30692,30694,30696,30698,30703,30704,30705,30706, +30708,30709,30711,30713,30714,30715,30716,30723,30724,30725,30726,30727,30728, +30730,30731,30734,30735,30736,30739,30741,30745,30747,30750,30752,30753,30754, +30756,30760,30762,30763,30766,30767,30769,30770,30771,30773,30774,30781,30783, +30785,30786,30787,30788,30790,30792,30793,30794,30795,30797,30799,30801,30803, +30804,30808,30809,30810,U,30811,30812,30814,30815,30816,30817,30818,30819, +30820,30821,30822,30823,30824,30825,30831,30832,30833,30834,30835,30836,30837, +30838,30840,30841,30842,30843,30845,30846,30847,30848,30849,30850,30851,30852, +30853,30854,30856,30858,30859,30863,30864,30866,30868,30869,30870,30873,30877, +30878,30880,30882,30884,30886,30888,30889,30890,30891,30892,30893,30894,30895, +30901,30902,30903,30904,30906,30907,30908,30909,30911,30912,30914,30915,30916, +30918,30919,30920,30924,30925,30926,30927,30929,30930,30931,30934,30935,30936, +30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,U,30948,30949, +30950,30951,30953,30954,30955,30957,30958,30959,30960,30961,30963,30965,30966, +30968,30969,30971,30972,30973,30974,30975,30976,30978,30979,30980,30982,30983, +30984,30985,30986,30987,30988,30989,30990,30991,30992,30993,30994,30996,30997, +30998,30999,31000,31001,31002,31003,31004,31005,31007,31008,31009,31010,31011, +31013,31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025, +31026,31027,31029,31030,31031,31032,31033,31037,31039,31042,31043,31044,31045, +31047,31050,31051,31052,31053,31054,31055,31056,31057,31058,31060,31061,31064, +31065,31073,31075,U,31076,31078,31081,31082,31083,31084,31086,31088,31089, +31090,31091,31092,31093,31094,31097,31099,31100,31101,31102,31103,31106,31107, +31110,31111,31112,31113,31115,31116,31117,31118,31120,31121,31122,31123,31124, +31125,31126,31127,31128,31129,31131,31132,31133,31134,31135,31136,31137,31138, +31139,31140,31141,31142,31144,31145,31146,31147,31148,31149,31150,31151,31152, +31153,31154,31156,31157,31158,31159,31160,31164,31167,31170,31172,31173,31175, +31176,31178,31180,31182,31183,31184,31187,31188,31190,31191,31193,31194,31195, +31196,31197,31198,31200,31201,31202,31205,31208,31210,U,31212,31214,31217, +31218,31219,31220,31221,31222,31223,31225,31226,31228,31230,31231,31233,31236, +31237,31239,31240,31241,31242,31244,31247,31248,31249,31250,31251,31253,31254, +31256,31257,31259,31260,31261,31263,31265,31266,31268,31269,31270,31271,31272, +31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,31284,31285,31286, +31288,31290,31294,31296,31297,31298,31299,31300,31301,31303,31304,31305,31306, +31307,31308,31309,31310,31311,31312,31314,31315,31316,31317,31318,31320,31321, +31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,31332,31333,31334, +31335,31336,U,31337,31338,31339,31340,31341,31342,31343,31345,31346,31347, +31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,31371,31372,31374, +31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,31395,31396,31399, +31401,31402,31403,31406,31407,31408,31409,31410,31412,31413,31414,31415,31416, +31417,31418,31419,31420,31421,31422,31424,31425,31426,31427,31428,31429,31430, +31431,31432,31433,31434,31436,31437,31438,31439,31440,31441,31442,31443,31444, +31445,31447,31448,31450,31451,31452,31453,31457,31458,31460,31463,31464,31465, +31466,31467,31468,31470,31472,31473,31474,31475,U,31476,31477,31478,31479, +31480,31483,31484,31486,31488,31489,31490,31493,31495,31497,31500,31501,31502, +31504,31506,31507,31510,31511,31512,31514,31516,31517,31519,31521,31522,31523, +31527,31529,31533,31535,31536,31538,31540,31541,31542,31543,31545,31547,31549, +31551,31552,31553,31554,31555,31556,31558,31560,31562,31565,31566,31571,31573, +31575,31577,31580,31582,31583,31585,31587,31588,31589,31590,31591,31592,31593, +31594,31595,31596,31597,31599,31600,31603,31604,31606,31608,31610,31612,31613, +31615,31617,31618,31619,31620,31622,31623,31624,31625,31626,31627,31628,31630, +31631,U,31633,31634,31635,31638,31640,31641,31642,31643,31646,31647,31648, +31651,31652,31653,31662,31663,31664,31666,31667,31669,31670,31671,31673,31674, +31675,31676,31677,31678,31679,31680,31682,31683,31684,31685,31688,31689,31690, +31691,31693,31694,31695,31696,31698,31700,31701,31702,31703,31704,31707,31708, +31710,31711,31712,31714,31715,31716,31719,31720,31721,31723,31724,31725,31727, +31728,31730,31731,31732,31733,31734,31736,31737,31738,31739,31741,31743,31744, +31745,31746,31747,31748,31749,31750,31752,31753,31754,31757,31758,31760,31761, +31762,31763,31764,31765,31767,31768,31769,U,31770,31771,31772,31773,31774, +31776,31777,31778,31779,31780,31781,31784,31785,31787,31788,31789,31790,31791, +31792,31793,31794,31795,31796,31797,31798,31799,31801,31802,31803,31804,31805, +31806,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822, +31823,31824,31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835, +31836,31837,31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848, +31849,31850,31851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863, +31864,31865,31866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879, +U,31880,31882,31883,31884,31885,31886,31887,31888,31891,31892,31894,31897, +31898,31899,31904,31905,31907,31910,31911,31912,31913,31915,31916,31917,31919, +31920,31924,31925,31926,31927,31928,31930,31931,31935,31936,31938,31939,31940, +31942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963, +31965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980, +31981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996, +31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009, +32011,32012,32013,32014,32015,32016,U,32017,32018,32019,32020,32021,32022, +32023,32024,32025,32026,32027,32028,32029,32030,32031,32033,32035,32036,32037, +32038,32040,32041,32042,32044,32045,32046,32048,32049,32050,32051,32052,32053, +32054,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,32065,32066, +32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,32078,32079, +32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,32091,32092, +32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,32104,32105, +32106,32107,32108,32109,32111,32112,32113,32114,32115,32116,32117,32118,U, +32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,32132, +32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,32145, +32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,32156,32157,32158, +32159,32160,32161,32162,32163,32164,32165,32167,32168,32169,32170,32171,32172, +32173,32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186, +32187,32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199, +32200,32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212, +32213,32214,32215,32216,32217,U,32218,32219,32220,32221,32222,32223,32224, +32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237, +32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250, +32251,32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263, +32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,32276, +32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,32288,32289, +32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,32300,32301,32302, +32303,32304,32305,32306,32307,32308,32309,32310,32311,32312,32313,U,32314, +32316,32317,32318,32319,32320,32322,32323,32324,32325,32326,32328,32329,32330, +32331,32332,32333,32334,32335,32336,32337,32338,32339,32340,32341,32342,32343, +32344,32345,32346,32347,32348,32349,32350,32351,32352,32353,32354,32355,32356, +32357,32358,32359,32360,32361,32362,32363,32364,32365,32366,32367,32368,32369, +32370,32371,32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382, +32383,32384,32385,32387,32388,32389,32390,32391,32392,32393,32394,32395,32396, +32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,32408,32409, +32410,32412,32413,32414,U,32430,32436,32443,32444,32470,32484,32492,32505, +32522,32528,32542,32567,32569,32571,32572,32573,32574,32575,32576,32577,32579, +32582,32583,32584,32585,32586,32587,32588,32589,32590,32591,32594,32595,32598, +32601,32603,32604,32605,32606,32608,32611,32612,32613,32614,32615,32619,32620, +32621,32623,32624,32627,32629,32630,32631,32632,32634,32635,32636,32637,32639, +32640,32642,32643,32644,32645,32646,32647,32648,32649,32651,32653,32655,32656, +32657,32658,32659,32661,32662,32663,32664,32665,32667,32668,32672,32674,32675, +32677,32678,32680,32681,32682,32683,32684,32685,32686,32689,U,32691,32692, +32693,32694,32695,32698,32699,32702,32704,32706,32707,32708,32710,32711,32712, +32713,32715,32717,32719,32720,32721,32722,32723,32726,32727,32729,32730,32731, +32732,32733,32734,32738,32739,32740,32743,32744,32746,32747,32748,32749,32751, +32754,32756,32757,32758,32759,32760,32761,32762,32765,32766,32767,32770,32775, +32776,32777,32778,32782,32783,32785,32787,32794,32795,32797,32798,32799,32801, +32803,32804,32811,32812,32813,32814,32815,32816,32818,32820,32825,32826,32828, +32830,32832,32833,32836,32837,32839,32840,32841,32846,32847,32848,32849,32851, +32853,32854,32855,U,32857,32859,32860,32861,32862,32863,32864,32865,32866, +32867,32868,32869,32870,32871,32872,32875,32876,32877,32878,32879,32880,32882, +32883,32884,32885,32886,32887,32888,32889,32890,32891,32892,32893,32894,32897, +32898,32901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,32919, +32921,32926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,32953, +32955,32965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,32980, +32981,32984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,33022, +33023,33024,33025,33027,33028,33029,33031,33032,33035,U,33036,33045,33047, +33049,33051,33052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063, +33064,33065,33066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082, +33083,33084,33085,33087,33088,33089,33090,33091,33092,33093,33095,33097,33101, +33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,33119,33121,33122, +33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,33141,33142,33143, +33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,33165,33166,33168, +33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,33184,33185,33186, +33188,33189,U,33191,33193,33195,33196,33197,33198,33199,33200,33201,33202, +33204,33205,33206,33207,33208,33209,33212,33213,33214,33215,33220,33221,33223, +33224,33225,33227,33229,33230,33231,33232,33233,33234,33235,33236,33237,33238, +33239,33240,33241,33242,33243,33244,33245,33246,33247,33248,33249,33250,33252, +33253,33254,33256,33257,33259,33262,33263,33264,33265,33266,33269,33270,33271, +33272,33273,33274,33277,33279,33283,33287,33288,33289,33290,33291,33294,33295, +33297,33299,33301,33302,33303,33304,33305,33306,33309,33312,33316,33317,33318, +33319,33321,33326,33330,33338,33340,33341,33343,U,33344,33345,33346,33347, +33349,33350,33352,33354,33356,33357,33358,33360,33361,33362,33363,33364,33365, +33366,33367,33369,33371,33372,33373,33374,33376,33377,33378,33379,33380,33381, +33382,33383,33385,33386,33387,33388,33389,33393,33397,33398,33399,33400,33403, +33404,33408,33409,33411,33413,33414,33415,33417,33420,33424,33427,33428,33429, +33430,33434,33435,33438,33440,33442,33443,33447,33458,33461,33462,33466,33467, +33468,33471,33472,33474,33475,33477,33478,33481,33488,33494,33497,33498,33501, +33506,33511,33512,33513,33514,33516,33517,33518,33520,33522,33523,33525,33526, +33528,U,33530,33532,33533,33534,33535,33536,33546,33547,33549,33552,33554, +33555,33558,33560,33561,33565,33566,33567,33568,33569,33570,33571,33572,33573, +33574,33577,33578,33582,33584,33586,33591,33595,33597,33598,33599,33601,33602, +33604,33605,33608,33610,33611,33612,33613,33614,33619,33621,33622,33623,33624, +33625,33629,33634,33648,33649,33650,33651,33652,33653,33654,33657,33658,33662, +33663,33664,33665,33666,33667,33668,33671,33672,33674,33675,33676,33677,33679, +33680,33681,33684,33685,33686,33687,33689,33690,33693,33695,33697,33698,33699, +33700,33701,33702,33703,33708,33709,33710,U,33711,33717,33723,33726,33727, +33730,33731,33732,33734,33736,33737,33739,33741,33742,33744,33745,33746,33747, +33749,33751,33753,33754,33755,33758,33762,33763,33764,33766,33767,33768,33771, +33772,33773,33774,33775,33779,33780,33781,33782,33783,33786,33787,33788,33790, +33791,33792,33794,33797,33799,33800,33801,33802,33808,33810,33811,33812,33813, +33814,33815,33817,33818,33819,33822,33823,33824,33825,33826,33827,33833,33834, +33835,33836,33837,33838,33839,33840,33842,33843,33844,33845,33846,33847,33849, +33850,33851,33854,33855,33856,33857,33858,33859,33860,33861,33863,33864,33865, +U,33866,33867,33868,33869,33870,33871,33872,33874,33875,33876,33877,33878, +33880,33885,33886,33887,33888,33890,33892,33893,33894,33895,33896,33898,33902, +33903,33904,33906,33908,33911,33913,33915,33916,33917,33918,33919,33920,33921, +33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,33941, +33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,33958, +33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,33974, +33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,33996, +33998,33999,34002,34004,34005,34007,U,34008,34009,34010,34011,34012,34014, +34017,34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034, +34035,34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049, +34050,34051,34052,34053,34054,34055,34056,34057,34058,34059,34061,34062,34063, +34064,34066,34068,34069,34070,34072,34073,34075,34076,34077,34078,34080,34082, +34083,34084,34085,34086,34087,34088,34089,34090,34093,34094,34095,34096,34097, +34098,34099,34100,34101,34102,34110,34111,34112,34113,34114,34116,34117,34118, +34119,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,U, +34135,34136,34138,34139,34140,34141,34143,34144,34145,34146,34147,34149,34150, +34151,34153,34154,34155,34156,34157,34158,34159,34160,34161,34163,34165,34166, +34167,34168,34172,34173,34175,34176,34177,34178,34179,34182,34184,34185,34186, +34187,34188,34189,34190,34192,34193,34194,34195,34196,34197,34198,34199,34200, +34201,34202,34205,34206,34207,34208,34209,34210,34211,34213,34214,34215,34217, +34219,34220,34221,34225,34226,34227,34228,34229,34230,34232,34234,34235,34236, +34237,34238,34239,34240,34242,34243,34244,34245,34246,34247,34248,34250,34251, +34252,34253,34254,34257,34258,U,34260,34262,34263,34264,34265,34266,34267, +34269,34270,34271,34272,34273,34274,34275,34277,34278,34279,34280,34282,34283, +34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296, +34297,34298,34300,34301,34302,34304,34305,34306,34307,34308,34310,34311,34312, +34313,34314,34315,34316,34317,34318,34319,34320,34322,34323,34324,34325,34327, +34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,34339,34340, +34341,34342,34344,34346,34347,34348,34349,34350,34351,34352,34353,34354,34355, +34356,34357,34358,34359,34361,34362,34363,34365,34366,34367,34368,U,34369, +34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34386,34387, +34389,34390,34391,34392,34393,34395,34396,34397,34399,34400,34401,34403,34404, +34405,34406,34407,34408,34409,34410,34413,34415,34416,34418,34419,34420,34421, +34422,34423,34424,34435,34436,34437,34438,34439,34440,34441,34446,34447,34448, +34449,34450,34452,34454,34455,34456,34457,34458,34459,34462,34463,34464,34465, +34466,34469,34470,34475,34477,34478,34482,34483,34487,34488,34489,34491,34492, +34493,34494,34495,34497,34498,34499,34501,34504,34508,34509,34514,34515,34517, +34518,34519,34522,34524,U,34525,34528,34529,34530,34531,34533,34534,34535, +34536,34538,34539,34540,34543,34549,34550,34551,34554,34555,34556,34557,34559, +34561,34564,34565,34566,34571,34572,34574,34575,34576,34577,34580,34582,34585, +34587,34589,34591,34592,34596,34598,34599,34600,34602,34603,34604,34605,34607, +34608,34610,34611,34613,34614,34616,34617,34618,34620,34621,34624,34625,34626, +34627,34628,34629,34630,34634,34635,34637,34639,34640,34641,34642,34644,34645, +34646,34648,34650,34651,34652,34653,34654,34655,34657,34658,34662,34663,34664, +34665,34666,34667,34668,34669,34671,34673,34674,34675,34677,U,34679,34680, +34681,34682,34687,34688,34689,34692,34694,34695,34697,34698,34700,34702,34703, +34704,34705,34706,34708,34709,34710,34712,34713,34714,34715,34716,34717,34718, +34720,34721,34722,34723,34724,34725,34726,34727,34729,34730,34734,34736,34737, +34738,34740,34742,34743,34744,34745,34747,34748,34750,34751,34753,34754,34755, +34756,34757,34759,34760,34761,34764,34765,34766,34767,34768,34772,34773,34774, +34775,34776,34777,34778,34780,34781,34782,34783,34785,34786,34787,34788,34790, +34791,34792,34793,34795,34796,34797,34799,34800,34801,34802,34803,34804,34805, +34806,34807,34808,U,34810,34811,34812,34813,34815,34816,34817,34818,34820, +34821,34822,34823,34824,34825,34827,34828,34829,34830,34831,34832,34833,34834, +34836,34839,34840,34841,34842,34844,34845,34846,34847,34848,34851,34852,34853, +34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34867, +34868,34869,34870,34871,34872,34874,34875,34877,34878,34879,34881,34882,34883, +34886,34887,34888,34889,34890,34891,34894,34895,34896,34897,34898,34899,34901, +34902,34904,34906,34907,34908,34909,34910,34911,34912,34918,34919,34922,34925, +34927,34929,34931,34932,34933,34934,34936,34937,34938,U,34939,34940,34944, +34947,34950,34951,34953,34954,34956,34958,34959,34960,34961,34963,34964,34965, +34967,34968,34969,34970,34971,34973,34974,34975,34976,34977,34979,34981,34982, +34983,34984,34985,34986,34988,34990,34991,34992,34994,34995,34996,34997,34998, +35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,35015,35016,35018, +35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,35035,35036,35037, +35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,35054,35055,35058, +35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,35076,35077,35078, +35079,35080,U,35081,35083,35084,35085,35086,35087,35089,35092,35093,35094, +35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,35111,35112, +35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,35128,35129,35130, +35131,35132,35133,35134,35135,35136,35138,35139,35141,35142,35143,35144,35145, +35146,35147,35148,35149,35150,35151,35152,35153,35154,35155,35156,35157,35158, +35159,35160,35161,35162,35163,35164,35165,35168,35169,35170,35171,35172,35173, +35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,35185,35186,35187, +35188,35189,35190,35191,35192,35193,35194,35196,U,35197,35198,35200,35202, +35204,35205,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217, +35218,35219,35220,35221,35222,35223,35224,35225,35226,35227,35228,35229,35230, +35231,35232,35233,35234,35235,35236,35237,35238,35239,35240,35241,35242,35243, +35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,35254,35255,35256, +35257,35258,35259,35260,35261,35262,35263,35264,35267,35277,35283,35284,35285, +35287,35288,35289,35291,35293,35295,35296,35297,35298,35300,35303,35304,35305, +35306,35308,35309,35310,35312,35313,35314,35316,35317,35318,35319,35320,35321, +35322,U,35323,35324,35325,35326,35327,35329,35330,35331,35332,35333,35334, +35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348, +35349,35350,35351,35352,35353,35354,35355,35356,35357,35358,35359,35360,35361, +35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,35372,35373,35374, +35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,35385,35386,35387, +35388,35389,35391,35392,35393,35394,35395,35396,35397,35398,35399,35401,35402, +35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,35413,35414,35415, +35416,35417,35418,35419,35420,35421,35422,U,35423,35424,35425,35426,35427, +35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,35439,35440, +35441,35442,35443,35444,35445,35446,35447,35448,35450,35451,35452,35453,35454, +35455,35456,35457,35458,35459,35460,35461,35462,35463,35464,35467,35468,35469, +35470,35471,35472,35473,35474,35476,35477,35478,35479,35480,35481,35482,35483, +35484,35485,35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496, +35497,35498,35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509, +35510,35511,35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522, +U,35523,35524,35525,35526,35527,35528,35529,35530,35531,35532,35533,35534, +35535,35536,35537,35538,35539,35540,35541,35542,35543,35544,35545,35546,35547, +35548,35549,35550,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560, +35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573, +35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586, +35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,35599,35600, +35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613, +35614,35615,35616,35617,35618,35619,U,35620,35621,35623,35624,35625,35626, +35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639, +35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652, +35653,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,35664,35665, +35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,35677,35678, +35679,35680,35681,35682,35683,35684,35685,35687,35688,35689,35690,35691,35693, +35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706, +35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,35718,U, +35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,35731, +35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,35756, +35761,35771,35783,35792,35818,35849,35870,35896,35897,35898,35899,35900,35901, +35902,35903,35904,35906,35907,35908,35909,35912,35914,35915,35917,35918,35919, +35920,35921,35922,35923,35924,35926,35927,35928,35929,35931,35932,35933,35934, +35935,35936,35939,35940,35941,35942,35943,35944,35945,35948,35949,35950,35951, +35952,35953,35954,35956,35957,35958,35959,35963,35964,35965,35966,35967,35968, +35969,35971,35972,35974,35975,U,35976,35979,35981,35982,35983,35984,35985, +35986,35987,35989,35990,35991,35993,35994,35995,35996,35997,35998,35999,36000, +36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,36011,36012,36013, +36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,36024,36025,36026, +36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,36037,36038,36039, +36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,36050,36051,36052, +36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,36063,36064,36065, +36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,36076,U,36077, +36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,36090, +36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,36102,36103, +36104,36105,36106,36107,36108,36109,36110,36111,36112,36113,36114,36115,36116, +36117,36118,36119,36120,36121,36122,36123,36124,36128,36177,36178,36183,36191, +36197,36200,36201,36202,36204,36206,36207,36209,36210,36216,36217,36218,36219, +36220,36221,36222,36223,36224,36226,36227,36230,36231,36232,36233,36236,36237, +36238,36239,36240,36242,36243,36245,36246,36247,36248,36249,36250,36251,36252, +36253,36254,36256,36257,U,36258,36260,36261,36262,36263,36264,36265,36266, +36267,36268,36269,36270,36271,36272,36274,36278,36279,36281,36283,36285,36288, +36289,36290,36293,36295,36296,36297,36298,36301,36304,36306,36307,36308,36309, +36312,36313,36316,36320,36321,36322,36325,36326,36327,36329,36333,36334,36336, +36337,36338,36340,36342,36348,36350,36351,36352,36353,36354,36355,36356,36358, +36359,36360,36363,36365,36366,36368,36369,36370,36371,36373,36374,36375,36376, +36377,36378,36379,36380,36384,36385,36388,36389,36390,36391,36392,36395,36397, +36400,36402,36403,36404,36406,36407,36408,36411,36412,36414,U,36415,36419, +36421,36422,36428,36429,36430,36431,36432,36435,36436,36437,36438,36439,36440, +36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,36455, +36456,36458,36459,36462,36465,36467,36469,36471,36472,36473,36474,36475,36477, +36478,36480,36482,36483,36484,36486,36488,36489,36490,36491,36492,36493,36494, +36497,36498,36499,36501,36502,36503,36504,36505,36506,36507,36509,36511,36512, +36513,36514,36515,36516,36517,36518,36519,36520,36521,36522,36525,36526,36528, +36529,36531,36532,36533,36534,36535,36536,36537,36539,36540,36541,36542,36543, +36544,36545,36546,U,36547,36548,36549,36550,36551,36552,36553,36554,36555, +36556,36557,36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569, +36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,36580,36581,36582, +36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,36595, +36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,36608, +36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,36621, +36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,36634, +36635,36636,36637,36638,36639,36640,36641,36642,36643,U,36644,36645,36646, +36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659, +36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672, +36673,36674,36675,36676,36677,36678,36679,36680,36681,36682,36683,36684,36685, +36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,36698, +36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,36709,36714,36736, +36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,36778,36780,36781, +36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,36796,36799,36800, +36803,36806,U,36809,36810,36811,36812,36813,36815,36818,36822,36823,36826, +36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,36858,36859, +36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,36889,36892,36899, +36900,36901,36903,36904,36905,36906,36907,36908,36912,36913,36914,36915,36916, +36919,36921,36922,36925,36927,36928,36931,36933,36934,36936,36937,36938,36939, +36940,36942,36948,36949,36950,36953,36954,36956,36957,36958,36959,36960,36961, +36964,36966,36967,36969,36970,36971,36972,36975,36976,36977,36978,36979,36982, +36983,36984,36985,36986,36987,36988,36990,36993,U,36996,36997,36998,36999, +37001,37002,37004,37005,37006,37007,37008,37010,37012,37014,37016,37018,37020, +37022,37023,37024,37028,37029,37031,37032,37033,37035,37037,37042,37047,37052, +37053,37055,37056,37058,37059,37062,37064,37065,37067,37068,37069,37074,37076, +37077,37078,37080,37081,37082,37086,37087,37088,37091,37092,37093,37097,37098, +37100,37102,37104,37105,37106,37107,37109,37110,37111,37113,37114,37115,37116, +37119,37120,37121,37123,37125,37126,37127,37128,37129,37130,37131,37132,37133, +37134,37135,37136,37137,37138,37139,37140,37141,37142,37143,37144,37146,37147, +37148,U,37149,37151,37152,37153,37156,37157,37158,37159,37160,37161,37162, +37163,37164,37165,37166,37168,37170,37171,37172,37173,37174,37175,37176,37178, +37179,37180,37181,37182,37183,37184,37185,37186,37188,37189,37191,37192,37201, +37203,37204,37205,37206,37208,37209,37211,37212,37215,37216,37222,37223,37224, +37227,37229,37235,37242,37243,37244,37248,37249,37250,37251,37252,37254,37256, +37258,37262,37263,37267,37268,37269,37270,37271,37272,37273,37276,37277,37278, +37279,37280,37281,37284,37285,37286,37287,37288,37289,37291,37292,37296,37297, +37298,37299,37302,37303,37304,37305,37307,U,37308,37309,37310,37311,37312, +37313,37314,37315,37316,37317,37318,37320,37323,37328,37330,37331,37332,37333, +37334,37335,37336,37337,37338,37339,37341,37342,37343,37344,37345,37346,37347, +37348,37349,37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360, +37361,37362,37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373, +37374,37375,37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386, +37387,37388,37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399, +37400,37401,37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412, +U,37413,37414,37415,37416,37417,37418,37419,37420,37421,37422,37423,37424, +37425,37426,37427,37428,37429,37430,37431,37432,37433,37434,37435,37436,37437, +37438,37439,37440,37441,37442,37443,37444,37445,37446,37447,37448,37449,37450, +37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463, +37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476, +37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489, +37490,37491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503, +37504,37505,37506,37507,37508,37509,U,37510,37511,37512,37513,37514,37515, +37516,37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529, +37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542, +37543,37544,37545,37546,37547,37548,37549,37551,37552,37553,37554,37555,37556, +37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,37568,37569, +37570,37571,37572,37573,37574,37575,37577,37578,37579,37580,37581,37582,37583, +37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,37595,37596, +37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,37608,U, +37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,37621, +37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,37634, +37635,37636,37637,37638,37639,37640,37641,37642,37643,37644,37645,37646,37647, +37648,37649,37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660, +37661,37662,37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673, +37674,37675,37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686, +37687,37688,37689,37690,37691,37692,37693,37695,37696,37697,37698,37699,37700, +37701,37702,37703,37704,37705,U,37706,37707,37708,37709,37710,37711,37712, +37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,37723,37724,37725, +37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,37736,37737,37739, +37740,37741,37742,37743,37744,37745,37746,37747,37748,37749,37750,37751,37752, +37753,37754,37755,37756,37757,37758,37759,37760,37761,37762,37763,37764,37765, +37766,37767,37768,37769,37770,37771,37772,37773,37774,37776,37777,37778,37779, +37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792, +37793,37794,37795,37796,37797,37798,37799,37800,37801,37802,37803,U,37804, +37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,37815,37816,37817, +37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,37828,37829,37830, +37831,37832,37833,37835,37836,37837,37838,37839,37840,37841,37842,37843,37844, +37845,37847,37848,37849,37850,37851,37852,37853,37854,37855,37856,37857,37858, +37859,37860,37861,37862,37863,37864,37865,37866,37867,37868,37869,37870,37871, +37872,37873,37874,37875,37876,37877,37878,37879,37880,37881,37882,37883,37884, +37885,37886,37887,37888,37889,37890,37891,37892,37893,37894,37895,37896,37897, +37898,37899,37900,37901,U,37902,37903,37904,37905,37906,37907,37908,37909, +37910,37911,37912,37913,37914,37915,37916,37917,37918,37919,37920,37921,37922, +37923,37924,37925,37926,37927,37928,37929,37930,37931,37932,37933,37934,37935, +37936,37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948, +37949,37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962, +37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975, +37976,37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988, +37989,37990,37991,37992,37993,37994,37996,37997,37998,37999,U,38000,38001, +38002,38003,38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014, +38015,38016,38017,38018,38019,38020,38033,38038,38040,38087,38095,38099,38100, +38106,38118,38139,38172,38176,38183,38195,38205,38211,38216,38219,38229,38234, +38240,38254,38260,38261,38263,38264,38265,38266,38267,38268,38269,38270,38272, +38273,38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285, +38286,38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298, +38299,38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311, +38312,38313,38314,U,38315,38316,38317,38318,38319,38320,38321,38322,38323, +38324,38325,38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336, +38337,38338,38339,38340,38341,38342,38343,38344,38345,38346,38347,38348,38349, +38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,38362, +38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375, +38380,38399,38407,38419,38424,38427,38430,38432,38435,38436,38437,38438,38439, +38440,38441,38443,38444,38445,38447,38448,38455,38456,38457,38458,38462,38465, +38467,38474,38478,38479,38481,38482,38483,38486,38487,U,38488,38489,38490, +38492,38493,38494,38496,38499,38501,38502,38507,38509,38510,38511,38512,38513, +38515,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531, +38532,38535,38537,38538,38540,38542,38545,38546,38547,38549,38550,38554,38555, +38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38568,38569,38570, +38571,38572,38573,38574,38575,38577,38578,38580,38581,38583,38584,38586,38587, +38591,38594,38595,38600,38602,38603,38608,38609,38611,38612,38614,38615,38616, +38617,38618,38619,38620,38621,38622,38623,38625,38626,38627,38628,38629,38630, +38631,38635,U,38636,38637,38638,38640,38641,38642,38644,38645,38648,38650, +38651,38652,38653,38655,38658,38659,38661,38666,38667,38668,38672,38673,38674, +38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,38689,38690,38691, +38692,38693,38694,38695,38696,38697,38699,38700,38702,38703,38705,38707,38708, +38709,38710,38711,38714,38715,38716,38717,38719,38720,38721,38722,38723,38724, +38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737, +38740,38741,38743,38744,38746,38748,38749,38751,38755,38756,38758,38759,38760, +38762,38763,38764,38765,38766,38767,38768,38769,U,38770,38773,38775,38776, +38777,38778,38779,38781,38782,38783,38784,38785,38786,38787,38788,38790,38791, +38792,38793,38794,38796,38798,38799,38800,38803,38805,38806,38807,38809,38810, +38811,38812,38813,38814,38815,38817,38818,38820,38821,38822,38823,38824,38825, +38826,38828,38830,38832,38833,38835,38837,38838,38839,38840,38841,38842,38843, +38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856, +38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869, +38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882, +38883,U,38884,38885,38888,38894,38895,38896,38897,38898,38900,38903,38904, +38905,38906,38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917, +38918,38919,38920,38921,38922,38923,38924,38925,38926,38927,38928,38929,38930, +38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,38943, +38944,38945,38946,38947,38948,38949,38950,38951,38952,38953,38954,38955,38956, +38957,38958,38959,38960,38961,38962,38963,38964,38965,38966,38967,38968,38969, +38970,38971,38972,38973,38974,38975,38976,38977,38978,38979,38980,38981,38982, +38983,38984,38985,38986,38987,38988,38989,U,38990,38991,38992,38993,38994, +38995,38996,38997,38998,38999,39000,39001,39002,39003,39004,39005,39006,39007, +39008,39009,39010,39011,39012,39013,39014,39015,39016,39017,39018,39019,39020, +39021,39022,39023,39024,39025,39026,39027,39028,39051,39054,39058,39061,39065, +39075,39080,39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091, +39092,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104, +39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117, +39119,39120,39124,39126,39127,39131,39132,39133,39136,39137,39138,39139,39140, +U,39141,39142,39145,39146,39147,39148,39149,39150,39151,39152,39153,39154, +39155,39156,39157,39158,39159,39160,39161,39162,39163,39164,39165,39166,39167, +39168,39169,39170,39171,39172,39173,39174,39175,39176,39177,39178,39179,39180, +39182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195, +39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208, +39209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222, +39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235, +39236,39237,39238,39239,39240,39241,U,39242,39243,39244,39245,39246,39247, +39248,39249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262, +39263,39264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299, +39305,39308,39310,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331, +39332,39334,39335,39337,39338,39339,39340,39341,39342,39343,39344,39345,39346, +39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,39358,39359, +39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,39371,39372, +39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,39384,U, +39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,39397, +39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,39410, +39411,39412,39413,39414,39415,39416,39417,39418,39419,39420,39421,39422,39423, +39424,39425,39426,39427,39428,39429,39430,39431,39432,39433,39434,39435,39436, +39437,39438,39439,39440,39441,39442,39443,39444,39445,39446,39447,39448,39449, +39450,39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462, +39463,39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475, +39476,39477,39478,39479,39480,U,39481,39482,39483,39484,39485,39486,39487, +39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500, +39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513, +39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,39526, +39527,39528,39529,39530,39531,39538,39555,39561,39565,39566,39572,39573,39577, +39590,39593,39594,39595,39596,39597,39598,39599,39602,39603,39604,39605,39609, +39611,39613,39614,39615,39619,39620,39622,39623,39624,39625,39626,39629,39630, +39631,39632,39634,39636,39637,39638,39639,39641,39642,39643,39644,U,39645, +39646,39648,39650,39651,39652,39653,39655,39656,39657,39658,39660,39662,39664, +39665,39666,39667,39668,39669,39670,39671,39672,39674,39676,39677,39678,39679, +39680,39681,39682,39684,39685,39686,39687,39689,39690,39691,39692,39693,39694, +39696,39697,39698,39700,39701,39702,39703,39704,39705,39706,39707,39708,39709, +39710,39712,39713,39714,39716,39717,39718,39719,39720,39721,39722,39723,39724, +39725,39726,39728,39729,39731,39732,39733,39734,39735,39736,39737,39738,39741, +39742,39743,39744,39750,39754,39755,39756,39758,39760,39762,39763,39765,39766, +39767,39768,39769,39770,U,39771,39772,39773,39774,39775,39776,39777,39778, +39779,39780,39781,39782,39783,39784,39785,39786,39787,39788,39789,39790,39791, +39792,39793,39794,39795,39796,39797,39798,39799,39800,39801,39802,39803,39804, +39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817, +39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830, +39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843, +39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856, +39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,U,39867,39868, +39869,39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881, +39882,39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894, +39895,39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907, +39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920, +39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933, +39934,39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946, +39947,39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959, +39960,39961,39962,U,39963,39964,39965,39966,39967,39968,39969,39970,39971, +39972,39973,39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984, +39985,39986,39987,39988,39989,39990,39991,39992,39993,39994,39995,39996,39997, +39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,40010, +40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,40023, +40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,40036, +40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,40049, +40050,40051,40052,40053,40054,40055,40056,40057,40058,U,40059,40061,40062, +40064,40067,40068,40073,40074,40076,40079,40083,40086,40087,40088,40089,40093, +40106,40108,40111,40121,40126,40127,40128,40129,40130,40136,40137,40145,40146, +40154,40155,40160,40161,40163,40164,40165,40166,40167,40168,40169,40170,40171, +40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,40184, +40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,40197, +40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,40210, +40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,40223, +40224,40225,U,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235, +40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248, +40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,40259,40260,40261, +40262,40263,40264,40265,40266,40267,40268,40269,40270,40271,40272,40273,40274, +40275,40276,40277,40278,40279,40280,40281,40282,40283,40284,40285,40286,40287, +40288,40289,40290,40291,40292,40293,40294,40295,40296,40297,40298,40299,40300, +40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,40311,40312,40313, +40314,40315,40316,40317,40318,40319,40320,40321,U,40322,40323,40324,40325, +40326,40327,40328,40329,40330,40331,40332,40333,40334,40335,40336,40337,40338, +40339,40340,40341,40342,40343,40344,40345,40346,40347,40348,40349,40350,40351, +40352,40353,40354,40355,40356,40357,40358,40359,40360,40361,40362,40363,40364, +40365,40366,40367,40368,40369,40370,40371,40372,40373,40374,40375,40376,40377, +40378,40379,40380,40381,40382,40383,40384,40385,40386,40387,40388,40389,40390, +40391,40392,40393,40394,40395,40396,40397,40398,40399,40400,40401,40402,40403, +40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416, +40417,U,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428, +40429,40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441, +40442,40443,40444,40445,40446,40447,40448,40449,40450,40451,40452,40453,40454, +40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,40466,40467, +40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,40484,40487, +40494,40496,40500,40507,40508,40512,40525,40528,40530,40531,40532,40534,40537, +40541,40543,40544,40545,40546,40549,40558,40559,40562,40564,40565,40566,40567, +40568,40569,40570,40571,40572,40573,40576,U,40577,40579,40580,40581,40582, +40585,40586,40588,40589,40590,40591,40592,40593,40596,40597,40598,40599,40600, +40601,40602,40603,40604,40606,40608,40609,40610,40611,40612,40613,40615,40616, +40617,40618,40619,40620,40621,40622,40623,40624,40625,40626,40627,40629,40630, +40631,40633,40634,40636,40639,40640,40641,40642,40643,40645,40646,40647,40648, +40650,40651,40652,40656,40658,40659,40661,40662,40663,40665,40666,40670,40673, +40675,40676,40678,40680,40683,40684,40685,40686,40688,40689,40690,40691,40692, +40693,40694,40695,40696,40698,40701,40703,40704,40705,40706,40707,40708,40709, +U,40710,40711,40712,40713,40714,40716,40719,40721,40722,40724,40725,40726, +40728,40730,40731,40732,40733,40734,40735,40737,40739,40740,40741,40742,40743, +40744,40745,40746,40747,40749,40750,40752,40753,40754,40755,40756,40757,40758, +40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,40777, +40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,40792, +40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805, +40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818, +40819,40820,40821,40822,40823,40824,U,40825,40826,40827,40828,40829,40830, +40833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855, +40856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975, +63985,64012,64013,64014,64015,64017,64019,64020,64024,64031,64032,64033,64035, +64036,64039,64040,64041, +}; + +static const struct dbcs_index gbkext_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{__gbkext_decmap+0,64,254},{__gbkext_decmap+191,64, +254},{__gbkext_decmap+382,64,254},{__gbkext_decmap+573,64,254},{ +__gbkext_decmap+764,64,254},{__gbkext_decmap+955,64,254},{__gbkext_decmap+1146 +,64,254},{__gbkext_decmap+1337,64,254},{__gbkext_decmap+1528,64,254},{ +__gbkext_decmap+1719,64,254},{__gbkext_decmap+1910,64,254},{__gbkext_decmap+ +2101,64,254},{__gbkext_decmap+2292,64,254},{__gbkext_decmap+2483,64,254},{ +__gbkext_decmap+2674,64,254},{__gbkext_decmap+2865,64,254},{__gbkext_decmap+ +3056,64,254},{__gbkext_decmap+3247,64,254},{__gbkext_decmap+3438,64,254},{ +__gbkext_decmap+3629,64,254},{__gbkext_decmap+3820,64,254},{__gbkext_decmap+ +4011,64,254},{__gbkext_decmap+4202,64,254},{__gbkext_decmap+4393,64,254},{ +__gbkext_decmap+4584,64,254},{__gbkext_decmap+4775,64,254},{__gbkext_decmap+ +4966,64,254},{__gbkext_decmap+5157,64,254},{__gbkext_decmap+5348,64,254},{ +__gbkext_decmap+5539,64,254},{__gbkext_decmap+5730,64,254},{__gbkext_decmap+ +5921,64,254},{__gbkext_decmap+6112,164,170},{__gbkext_decmap+6119,161,170},{0, +0,0},{0,0,0},{0,0,0},{__gbkext_decmap+6129,224,245},{0,0,0},{__gbkext_decmap+ +6151,64,192},{__gbkext_decmap+6280,64,150},{__gbkext_decmap+6367,64,160},{ +__gbkext_decmap+6464,64,160},{__gbkext_decmap+6561,64,160},{__gbkext_decmap+ +6658,64,160},{__gbkext_decmap+6755,64,160},{__gbkext_decmap+6852,64,160},{ +__gbkext_decmap+6949,64,160},{__gbkext_decmap+7046,64,160},{__gbkext_decmap+ +7143,64,160},{__gbkext_decmap+7240,64,160},{__gbkext_decmap+7337,64,160},{ +__gbkext_decmap+7434,64,160},{__gbkext_decmap+7531,64,160},{__gbkext_decmap+ +7628,64,160},{__gbkext_decmap+7725,64,160},{__gbkext_decmap+7822,64,160},{ +__gbkext_decmap+7919,64,160},{__gbkext_decmap+8016,64,160},{__gbkext_decmap+ +8113,64,160},{__gbkext_decmap+8210,64,160},{__gbkext_decmap+8307,64,160},{ +__gbkext_decmap+8404,64,160},{__gbkext_decmap+8501,64,160},{__gbkext_decmap+ +8598,64,160},{__gbkext_decmap+8695,64,160},{__gbkext_decmap+8792,64,160},{ +__gbkext_decmap+8889,64,160},{__gbkext_decmap+8986,64,160},{__gbkext_decmap+ +9083,64,160},{__gbkext_decmap+9180,64,160},{__gbkext_decmap+9277,64,160},{ +__gbkext_decmap+9374,64,160},{__gbkext_decmap+9471,64,160},{__gbkext_decmap+ +9568,64,160},{__gbkext_decmap+9665,64,160},{__gbkext_decmap+9762,64,160},{ +__gbkext_decmap+9859,64,160},{__gbkext_decmap+9956,64,160},{__gbkext_decmap+ +10053,64,160},{__gbkext_decmap+10150,64,160},{__gbkext_decmap+10247,64,160},{ +__gbkext_decmap+10344,64,160},{__gbkext_decmap+10441,64,160},{__gbkext_decmap+ +10538,64,160},{__gbkext_decmap+10635,64,160},{__gbkext_decmap+10732,64,160},{ +__gbkext_decmap+10829,64,160},{__gbkext_decmap+10926,64,160},{__gbkext_decmap+ +11023,64,160},{__gbkext_decmap+11120,64,160},{__gbkext_decmap+11217,64,160},{ +__gbkext_decmap+11314,64,160},{__gbkext_decmap+11411,64,160},{__gbkext_decmap+ +11508,64,160},{__gbkext_decmap+11605,64,160},{__gbkext_decmap+11702,64,160},{ +__gbkext_decmap+11799,64,160},{__gbkext_decmap+11896,64,160},{__gbkext_decmap+ +11993,64,160},{__gbkext_decmap+12090,64,160},{__gbkext_decmap+12187,64,160},{ +__gbkext_decmap+12284,64,160},{__gbkext_decmap+12381,64,160},{__gbkext_decmap+ +12478,64,160},{__gbkext_decmap+12575,64,160},{__gbkext_decmap+12672,64,160},{ +__gbkext_decmap+12769,64,160},{__gbkext_decmap+12866,64,160},{__gbkext_decmap+ +12963,64,160},{__gbkext_decmap+13060,64,160},{__gbkext_decmap+13157,64,160},{ +__gbkext_decmap+13254,64,160},{__gbkext_decmap+13351,64,160},{__gbkext_decmap+ +13448,64,160},{__gbkext_decmap+13545,64,160},{__gbkext_decmap+13642,64,160},{ +__gbkext_decmap+13739,64,160},{__gbkext_decmap+13836,64,160},{__gbkext_decmap+ +13933,64,160},{__gbkext_decmap+14030,64,160},{__gbkext_decmap+14127,64,160},{ +__gbkext_decmap+14224,64,160},{__gbkext_decmap+14321,64,160},{__gbkext_decmap+ +14418,64,160},{__gbkext_decmap+14515,64,79},{0,0,0}, +}; + +static const DBCHAR __gbcommon_encmap[23231] = { +8552,N,N,8556,8487,N,N,N,N,N,N,N,8547,8512,N,N,N,N,N,41380,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8513,N,N,N,N,N,N,N,N,10276,10274, +N,N,N,N,N,N,10280,10278,10298,N,10284,10282,N,N,N,N,10288,10286,N,N,N,8514,N, +10292,10290,N,10297,10273,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10277,N,N,N,N,N,N, +N,10279,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,43197,N,N,N,43198,N,N,N,N,10285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,10289,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10275, +N,10283,N,10287,N,10291,N,10293,N,10294,N,10295,N,10296,43195,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,43200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8486,N,8485, +43072,43073,N,N,N,N,N,N,N,N,N,N,N,N,N,43074,9761,9762,9763,9764,9765,9766, +9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,N,9778,9779,9780,9781, +9782,9783,9784,N,N,N,N,N,N,N,9793,9794,9795,9796,9797,9798,9799,9800,9801, +9802,9803,9804,9805,9806,9807,9808,9809,N,9810,9811,9812,9813,9814,9815,9816, +10023,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10017,10018,10019,10020,10021,10022,10024, +10025,10026,10027,10028,10029,10030,10031,10032,10033,10034,10035,10036,10037, +10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,10049,10065, +10066,10067,10068,10069,10070,10072,10073,10074,10075,10076,10077,10078,10079, +10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,10092, +10093,10094,10095,10096,10097,N,10071,43356,N,N,43075,41386,8490,8492,N,8494, +8495,N,N,8496,8497,N,N,N,N,N,N,N,43077,8493,N,N,N,N,N,N,N,N,N,8555,N,8548, +8549,N,43078,N,N,N,N,N,8569,8550,N,43079,N,N,N,43080,N,N,N,N,N,N,N,N,N,N,N,N, +8557,N,N,N,N,N,N,N,N,N,N,43353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +8817,8818,8819,8820,8821,8822,8823,8824,8825,8826,8827,8828,N,N,N,N,41633, +41634,41635,41636,41637,41638,41639,41640,41641,41642,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,8571,8572,8570,8573,N,N,43081,43082,43083,43084,8522,N,N, +N,N,N,N,8519,N,8518,N,N,N,43085,N,N,N,N,8524,N,N,8536,8542,43086,8527,N,N, +43087,N,8526,N,8516,8517,8521,8520,8530,N,N,8531,N,N,N,N,N,8544,8543,8515, +8523,N,N,N,N,N,8535,N,N,N,N,N,N,N,N,N,N,8534,N,N,N,8533,N,N,N,N,N,43088,N,N,N, +N,N,N,N,N,N,N,N,N,N,8537,8532,N,N,8540,8541,43089,43090,N,N,N,N,N,N,8538,8539, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +43154,N,N,N,8529,N,N,N,N,N,N,N,N,N,N,N,8525,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,43091,8528,8793,8794,8795,8796,8797,8798,8799,8800,8801,8802, +N,N,N,N,N,N,N,N,N,N,8773,8774,8775,8776,8777,8778,8779,8780,8781,8782,8783, +8784,8785,8786,8787,8788,8789,8790,8791,8792,8753,8754,8755,8756,8757,8758, +8759,8760,8761,8762,8763,8764,8765,8766,8767,8768,8769,8770,8771,8772,10532, +10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543,10544,10545, +10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557,10558, +10559,10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571, +10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584, +10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597, +10598,10599,10600,10601,10602,10603,10604,10605,10606,10607,N,N,N,N,43092, +43093,43094,43095,43096,43097,43098,43099,43100,43101,43102,43103,43104,43105, +43106,43107,43108,43109,43110,43111,43112,43113,43114,43115,43116,43117,43118, +43119,43120,43121,43122,43123,43124,43125,43126,43127,N,N,N,N,N,N,N,N,N,N,N,N, +N,43128,43129,43130,43131,43132,43133,43134,43136,43137,43138,43139,43140, +43141,43142,43143,N,N,N,43144,43145,43146,N,N,N,N,N,N,N,N,N,N,8566,8565,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,8568,8567,N,N,N,N,N,N,N,N,43147,43148,N,N,N,N,N,N,N, +N,8564,8563,N,N,N,8560,N,N,8562,8561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +43149,43150,43151,43152,8559,8558,N,N,43153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +8546,N,8545,8481,8482,8483,8488,N,8489,43365,43414,8500,8501,8502,8503,8504, +8505,8506,8507,8510,8511,43155,8574,8498,8499,8508,8509,N,N,N,N,N,43156,43157, +N,N,43328,43329,43330,43331,43332,43333,43334,43335,43336,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258, +9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273, +9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288, +9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303, +9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318, +9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,N,N,N,N,N,N, +N,43361,43362,43366,43367,N,N,9505,9506,9507,9508,9509,9510,9511,9512,9513, +9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528, +9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543, +9544,9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558, +9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573, +9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588, +9589,9590,N,N,N,N,8484,43360,43363,43364,10309,10310,10311,10312,10313,10314, +10315,10316,10317,10318,10319,10320,10321,10322,10323,10324,10325,10326,10327, +10328,10329,10330,10331,10332,10333,10334,10335,10336,10337,10338,10339,10340, +10341,10342,10343,10344,10345,8805,8806,8807,8808,8809,8810,8811,8812,8813, +8814,N,N,N,N,N,N,N,43354,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,43337,43338,43339,N,N,N,N,N,N,N,N,N,N,N,N,43340,43341,43342, +N,N,43343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +43344,N,N,N,N,N,N,N,N,N,43345,N,N,43346,43347,N,N,43348,21051,13857,33088, +18015,33089,33090,33091,19826,21833,18557,18767,20290,22562,12859,21355,33092, +22564,13171,33093,22312,18258,22567,19008,33094,18288,12667,21045,13396,13867, +19263,22569,33095,33096,33097,13866,33098,16701,20815,33099,18725,22573,33100, +14454,20798,25436,22096,33101,33102,14177,33103,13358,33104,16729,33105,22588, +33106,19816,13604,20010,22135,33107,16502,15961,22575,33108,33109,33110,17483, +33111,15939,33112,22577,17204,21093,33113,22062,20058,21799,14965,14118,16470, +33114,17977,17746,18247,33115,14676,33116,13131,21074,33117,33118,22591,15941, +18034,21042,20272,20327,33119,33120,33121,33122,19049,33123,33124,22592,33125, +33126,33127,33128,33129,33130,17010,16978,33131,18537,33132,33133,33134,33135, +33136,33137,33138,33139,33140,33141,18220,33142,33143,33144,33145,33146,33147, +33148,16715,33149,21352,21881,33150,19010,13950,22561,21338,16247,33152,21574, +15141,22593,20069,15918,33153,33154,22568,33155,20807,20521,33156,33157,33158, +22589,22895,19830,16186,33159,15675,14885,21088,12922,14944,17462,33160,20333, +15913,19748,16705,33161,33162,33163,18263,22897,33164,22900,33165,33166,33167, +33168,18507,22633,33169,33170,33171,21082,18994,18506,22636,22634,22598,15734, +17997,13168,33172,22635,15729,15721,33173,18516,13395,33174,33175,16984,33176, +12886,22352,19019,19323,21836,14390,20297,33177,33178,33179,22874,22640,18218, +33180,22638,33181,13434,16750,21076,33182,33183,22637,33184,21063,22639,17223, +33185,33186,33187,20854,33188,22105,22642,33189,22645,15486,15451,33190,33191, +33192,18510,33193,14173,33194,14146,33195,18035,33196,33197,33198,33199,33200, +33201,33202,22648,21057,33203,33204,20073,15423,14204,14117,20573,33205,33206, +33207,33208,33209,22106,21317,15215,15201,22641,33210,33211,18721,20016,13355, +33212,22643,33213,18763,22646,16983,22647,33214,33215,20017,22649,33216,33217, +33218,12846,14656,33219,22819,33220,12393,33221,16742,33222,18796,33223,19269, +33224,19270,22820,33225,33226,33227,33228,33229,13672,33230,33231,13611,33232, +33233,33234,33235,33236,33237,20027,13645,22305,22388,21331,33238,19557,33239, +14926,33240,22818,22876,21344,22653,14192,22391,22654,22650,22817,17507,33241, +33242,21302,22644,22877,33243,22651,33244,17765,33245,33246,16464,33247,33248, +20848,12379,33249,33250,15441,22822,33251,22821,33252,33253,33254,33255,22828, +22830,33256,22827,19001,33257,33258,33259,22825,22070,33260,33261,33262,13150, +22824,33263,16509,33264,19020,33265,22826,33266,22823,33267,33268,22832,33269, +33270,13873,33271,33272,33273,14633,33274,21056,33275,33276,20288,33277,33278, +16962,33344,15684,21868,12896,18248,16235,22829,33345,22831,33346,20074,14958, +33347,33348,33349,33350,33351,18262,33352,33353,33354,33355,33356,33357,33358, +33359,33360,12643,33361,33362,33363,13401,13933,22836,33364,33365,33366,33367, +16161,33368,33369,33370,22878,18254,16510,22840,33371,33372,33373,33374,33375, +19287,14205,33376,22837,33377,22839,12579,21345,22841,33378,20549,33379,22838, +33380,33381,22833,33382,22834,16681,22835,33383,33384,15475,20574,14377,33385, +15971,33386,22845,33387,33388,33389,33390,22842,33391,12339,33392,33393,33394, +22850,33395,33396,33397,33398,33399,33400,33401,33402,33403,33404,33405,33406, +33408,22852,12598,33409,22847,33410,33411,13625,33412,15987,33413,33414,33415, +19528,14962,21072,33416,22851,33417,33418,15720,33419,13099,33420,33421,33422, +22853,15979,33423,22854,22843,17503,33424,22846,22849,22848,33425,33426,33427, +33428,33429,33430,33431,33432,33433,33434,33435,21806,33436,22069,33437,18275, +33438,33439,33440,33441,22856,33442,33443,33444,15449,22858,33445,33446,33447, +22844,33448,22859,17963,33449,33450,33451,33452,33453,22857,33454,33455,33456, +33457,22390,33458,19747,33459,33460,33461,33462,33463,33464,33465,33466,15649, +33467,33468,33469,33470,33471,33472,22860,33473,33474,33475,33476,33477,33478, +33479,33480,33481,17724,19765,33482,33483,33484,22861,33485,33486,22855,13093, +16254,33487,33488,33489,33490,14389,33491,33492,16508,33493,33494,33495,33496, +12408,33497,33498,33499,33500,33501,33502,33503,33504,33505,33506,33507,33508, +33509,33510,33511,33512,33513,33514,33515,33516,33517,13430,33518,22862,33519, +22863,13346,22864,33520,33521,13407,33522,33523,33524,33525,33526,12353,33527, +33528,33529,33530,33531,33532,33533,22865,18741,33534,33600,33601,33602,33603, +33604,33605,33606,33607,33608,33609,33610,33611,33612,33613,33614,33615,33616, +33617,20337,33618,33619,33620,33621,33622,33623,22866,33624,33625,33626,16709, +33627,33628,33629,33630,33631,33632,33633,33634,33635,33636,33637,22870,18734, +33638,33639,33640,33641,22869,22868,22871,33642,33643,33644,33645,19291,33646, +15657,33647,33648,33649,33650,33651,17959,33652,33653,33654,33655,33656,33657, +33658,33659,33660,33661,22867,22872,33662,33664,33665,22873,33666,33667,33668, +33669,33670,33671,18533,33672,33673,33674,33675,33676,33677,33678,33679,33680, +33681,33682,33683,33684,33685,16476,33686,33687,33688,33689,33690,33691,33692, +33693,33694,33695,33696,33697,33698,33699,33700,33701,33702,33703,33704,33705, +33706,33707,33708,33709,33710,33711,33712,33713,33714,13945,22563,21578,33715, +21546,20566,13156,21847,33716,20296,14690,33717,16203,33718,17250,33719,33720, +33721,13906,33722,33723,19779,22894,22896,33724,33725,33726,13619,33727,13877, +33728,33729,33730,33731,33732,15908,33733,33734,18539,33735,33736,18475,33737, +33738,12363,14635,16761,22882,33739,16444,14642,33740,14680,20555,12664,18020, +15967,13668,22344,33741,20856,15462,19038,33742,33743,15421,22886,22631,33744, +33745,17498,33746,33747,14420,18493,33748,33749,12897,21593,33750,33751,33752, +33753,17200,33754,33755,17249,23074,18527,33756,20532,33757,15996,17705,33758, +33759,33760,14682,33761,23075,33762,21545,23076,33763,33764,33765,33766,33767, +22907,13868,33768,33769,14187,12665,22908,13157,15990,33770,16246,21041,16484, +33771,33772,33773,13875,22910,22909,33774,33775,15931,33776,33777,33778,18016, +33779,22332,23073,33780,16697,33781,13682,16744,33782,33783,15477,33784,13397, +33785,33786,33787,33788,33789,33790,33856,33857,33858,16733,33859,17533,33860, +33861,15416,14130,33862,33863,14191,33864,33865,33866,33867,33868,33869,22892, +33870,17982,33871,16173,15179,33872,33873,13642,33874,23369,20567,33875,19769, +12348,13174,15223,23370,14895,33876,21604,13622,13683,22614,18512,33877,33878, +14166,18256,22615,33879,16175,33880,33881,23355,22616,33882,33883,20556,15150, +33884,33885,33886,27454,16720,16757,21618,14421,13364,33887,13173,33888,33889, +18750,33890,33891,33892,17744,33893,33894,33895,17753,16507,33896,12656,33897, +22617,14670,33898,13629,33899,33900,22618,33901,33902,22086,19234,18479,18738, +13388,16204,33903,14708,33904,22619,22620,13927,15425,19562,33905,33906,33907, +33908,33909,33910,20343,33911,22621,18224,33912,33913,14672,15651,33914,33915, +19550,33916,17994,33917,33918,33920,33921,33922,22624,33923,22622,33924,33925, +22623,33926,33927,33928,12414,33929,15975,33930,18979,15476,33931,33932,33933, +33934,14385,33935,33936,14446,33937,33938,33939,33940,33941,33942,33943,33944, +33945,33946,22626,33947,15691,33948,22628,22627,33949,33950,33951,33952,33953, +17788,33954,33955,33956,33957,33958,33959,33960,22629,33961,33962,22630,33963, +33964,33965,33966,33967,33968,33969,16678,33970,18480,12396,14630,15443,20081, +23357,16723,33971,33972,33973,33974,13871,22138,17708,15705,23358,23359,33975, +33976,33977,16504,15906,16461,33978,33979,33980,33981,33982,33983,33984,33985, +33986,33987,23360,19014,33988,33989,33990,12842,33991,33992,33993,21314,33994, +17251,33995,20779,33996,33997,33998,33999,23362,34000,16469,34001,34002,34003, +23363,34004,16177,34005,34006,34007,34008,34009,34010,17468,34011,34012,34013, +34014,18266,34015,34016,34017,34018,34019,34020,34021,34022,34023,34024,34025, +23364,34026,34027,34028,34029,34030,34031,34032,34033,22888,18775,34034,34035, +34036,14644,20080,21576,34037,34038,34039,34040,12412,13394,34041,20569,34042, +34043,34044,34045,22889,34046,24139,22891,34112,34113,34114,34115,22576,15151, +12593,34116,13143,22606,34117,34118,21585,34119,34120,15667,16239,34121,20283, +34122,34123,22608,34124,34125,34126,14155,34127,34128,34129,22609,34130,34131, +34132,34133,34134,34135,34136,34137,34138,34139,17957,18296,21053,34140,34141, +22610,17508,34142,18990,34143,18215,34144,22566,34145,18813,20071,15196,12395, +34146,34147,34148,15146,20525,34149,12592,22372,22335,34150,13605,17012,17487, +34151,34152,12841,34153,12855,34154,12645,24370,21820,16168,16940,22613,16945, +34155,22612,20052,34156,23136,34157,20032,34158,34159,22580,17198,21281,20003, +34160,15412,18484,16977,34161,15981,20534,34162,23137,34163,34164,34165,34166, +18276,34167,34168,13095,34169,13938,19580,16506,34170,34171,16503,34172,20793, +20833,22599,34173,34174,34176,34177,34178,34179,34180,12894,34181,34182,16485, +34183,14961,34184,34185,22600,34186,21549,34187,34188,20321,22601,34189,22602, +20291,34190,13176,15943,34191,34192,34193,34194,22603,34195,34196,34197,34198, +34199,34200,34201,23372,34202,34203,34204,34205,18469,34206,34207,34208,20312, +34209,18558,12878,34210,34211,34212,34213,34214,21334,12902,15408,21329,19243, +14132,34215,34216,34217,14114,34218,34219,19045,34220,18465,19036,12644,20592, +34221,17745,34222,34223,34224,23365,13694,34225,34226,16218,14661,15972,16749, +34227,24374,24373,22075,15696,21849,12360,13859,16201,19496,24371,18999,21330, +34228,22607,21046,14917,19262,19518,34229,24375,13680,24372,34230,34231,34232, +21365,34233,13140,14455,34234,24378,34235,14927,15402,13685,34236,19756,17275, +14963,16500,19778,20338,24376,20293,34237,16960,24377,17008,34238,34239,34240, +15997,34241,16735,19788,21111,14157,24385,34242,24388,34243,34244,14193,12361, +13910,14164,34245,14892,19581,16212,19249,18036,34246,22056,24389,34247,20066, +13107,34248,34249,20092,13365,34250,20039,14960,34251,20065,34252,20797,34253, +34254,24384,34255,34256,13428,34257,13130,34258,14438,24379,34259,34260,34261, +34262,17477,34263,24380,24381,24382,17723,24383,24386,21553,24387,34264,18234, +20056,34265,34266,34267,34268,34269,17496,34270,24394,34271,24399,34272,22108, +34273,34274,34275,34276,34277,34278,34279,34280,24393,24410,20022,34281,14919, +24398,24392,17758,34282,34283,18795,14964,17276,34284,34285,15959,34286,24390, +34287,24397,34288,17752,34289,34290,34291,34292,21798,14925,34293,15948,21309, +14400,34294,22116,34295,24391,14654,16167,34296,34297,16764,24395,24396,34298, +24400,34299,34300,34301,34302,34368,24411,24421,34369,24407,24406,22345,24419, +24420,25963,21031,24402,34370,16169,34371,21595,34372,16200,24404,34373,34374, +34375,20300,34376,34377,24413,34378,20810,34379,24414,12327,17975,24403,34380, +14949,34381,13919,19803,14718,21589,34382,34383,24415,20332,12325,24423,24401, +20806,24405,24408,24409,24412,34384,15145,34385,24416,24417,34386,24418,24422, +24424,21300,34387,34388,34389,34390,34391,14439,17718,24426,18778,16680,17476, +34392,34393,16222,20344,34394,34395,34396,21852,24430,34397,34398,34399,34400, +34401,34402,12856,34403,14943,24428,34404,23361,34405,20836,34406,34407,34408, +34409,19316,13373,34410,12326,34411,34412,34413,34414,34415,24433,19526,24434, +34416,34417,24429,34418,34419,34420,34421,34422,34423,24425,34424,34425,34426, +34427,24427,34428,24431,24432,15165,34429,34430,24435,34432,34433,24436,34434, +15139,34435,19035,20008,24615,13098,34436,24614,34437,34438,34439,24609,34440, +34441,34442,34443,24446,34444,19801,24444,34445,24442,34446,16208,22340,34447, +18764,34448,34449,24440,12321,34450,34451,34452,34453,34454,24445,34455,34456, +34457,34458,24443,24610,34459,34460,34461,34462,34463,24616,34464,34465,34466, +34467,14152,34468,34469,17953,18742,16434,24437,34470,34471,17726,34472,22596, +24441,17526,34473,34474,34475,34476,34477,34478,24611,24612,24613,20517,34479, +34480,24628,19556,34481,24625,34482,16166,24623,20025,24619,18758,34483,34484, +16430,24622,14957,14896,24617,34485,34486,34487,24438,34488,24627,34489,34490, +24632,34491,34492,34493,13357,24633,34494,34495,20274,14920,34496,24624,34497, +34498,34499,34500,34501,34502,34503,20602,34504,34505,34506,34507,34508,34509, +34510,34511,34512,24620,34513,21627,34514,24439,34515,17767,34516,24621,34517, +21367,34518,24630,24631,34519,34520,34521,34522,34523,24644,20577,34524,34525, +34526,24636,34527,34528,24649,24650,34529,34530,34531,24638,24618,18724,24641, +34532,24626,34533,34534,34535,34536,34537,19016,24643,34538,24629,34539,20043, +34540,19267,24653,24646,24642,34541,24651,34542,24634,24639,24640,34543,34544, +24645,34545,34546,24647,24648,34547,24652,34548,24635,34549,34550,34551,34552, +34553,19284,24661,34554,24662,24658,34555,34556,34557,34558,34624,34625,24656, +15438,34626,34627,24657,34628,14402,22597,34629,34630,34631,34632,34633,34634, +34635,34636,20586,34637,34638,17007,34639,34640,24655,24637,34641,34642,34643, +24660,24659,34644,34645,24663,34646,34647,34648,34649,24668,24664,34650,34651, +34652,22134,13104,34653,22380,34654,19259,34655,34656,24666,34657,20091,34658, +34659,34660,14937,34661,34662,34663,34664,34665,34666,34667,34668,34669,34670, +34671,34672,24673,24669,21037,34673,34674,34675,34676,34677,24674,34678,34679, +24667,24665,24671,34680,34681,24672,34682,34683,34684,34685,34686,24670,34688, +24676,34689,34690,34691,18039,22572,21611,24678,19017,34692,34693,34694,34695, +24677,34696,34697,34698,34699,14401,34700,34701,34702,34703,24679,24680,34704, +34705,34706,34707,34708,34709,34710,34711,24681,24675,34712,34713,34714,34715, +34716,34717,34718,14911,19559,34719,34720,34721,24682,34722,34723,34724,34725, +34726,34727,34728,34729,34730,34731,34732,34733,34734,34735,34736,20345,34737, +34738,34739,34740,34741,34742,34743,34744,34745,34746,34747,24683,34748,34749, +34750,34751,34752,34753,34754,18498,34755,34756,34757,34758,15680,34759,34760, +34761,34762,34763,34764,34765,34766,34767,34768,34769,34770,34771,17490,34772, +34773,34774,34775,34776,34777,34778,34779,34780,24684,34781,34782,24685,34783, +34784,18292,19268,34785,24686,15192,22582,21106,24687,19781,34786,13914,34787, +34788,34789,34790,34791,34792,24689,34793,21552,34794,34795,16423,13393,34796, +34797,20007,24688,34798,34799,34800,24690,14668,34801,34802,14714,19772,24691, +34803,34804,34805,18004,24692,34806,21554,34807,18470,24694,24693,34808,34809, +34810,34811,34812,34813,34814,34880,34881,34882,34883,34884,34885,34886,34887, +34888,34889,24695,34890,34891,19777,34892,34893,34894,18981,34895,34896,34897, +34898,21594,23383,23385,34899,23384,14695,23388,23389,13656,34900,34901,23386, +34902,34903,34904,34905,34906,23387,13089,23391,34907,34908,15224,34909,22071, +34910,23392,34911,34912,34913,34914,15993,34915,34916,14139,34917,23376,19502, +16178,15157,22392,16211,34918,34919,34920,34921,34922,16233,34923,34924,15457, +19507,23390,12371,20075,14168,22329,17986,34925,34926,16420,34927,19513,34928, +23399,23393,17978,23395,34929,23400,34930,17783,34931,34932,34933,23402,34934, +34935,23401,16192,34936,34937,34938,23398,23397,34939,34940,34941,34942,34944, +13369,16428,16930,23394,23396,34945,34946,34947,34948,20557,23405,34949,34950, +34951,34952,34953,16477,23410,34954,34955,34956,34957,34958,34959,34960,13922, +34961,34962,34963,34964,23411,23378,14648,21547,23404,34965,16209,23408,34966, +23377,34967,13670,34968,23403,16229,34969,34970,34971,23406,34972,23409,34973, +34974,34975,23417,34976,34977,34978,34979,34980,34981,34982,34983,34984,14625, +12323,34985,34986,34987,34988,34989,34990,34991,17009,34992,34993,13127,23407, +34994,34995,23416,34996,18002,23412,34997,34998,23413,23415,23414,34999,35000, +23422,35001,21362,12858,35002,35003,35004,23421,35005,35006,35007,35008,35009, +35010,35011,35012,23588,35013,23419,35014,35015,35016,35017,23418,35018,35019, +35020,23420,17760,15225,35021,35022,23587,35023,35024,23589,35025,19523,35026, +35027,35028,13905,23872,35029,35030,35031,23585,35032,23586,35033,35034,35035, +18229,35036,35037,35038,13929,35039,35040,35041,23591,35042,35043,35044,35045, +23590,35046,23593,12580,35047,35048,13644,35049,35050,35051,35052,35053,16176, +35054,35055,35056,35057,35058,20831,35059,35060,35061,35062,13890,35063,35064, +35065,35066,35067,35068,35069,35070,35136,35137,35138,35139,35140,35141,23592, +35142,35143,35144,35145,35146,35147,35148,19322,27507,35149,35150,35151,19292, +35152,35153,19326,35154,35155,35156,19521,35157,35158,35159,35160,35161,18555, +35162,35163,35164,35165,35166,35167,23594,35168,35169,35170,35171,35172,19566, +23595,35173,35174,35175,35176,35177,35178,35179,35180,35181,35182,35183,35184, +35185,35186,35187,35188,35189,23379,35190,23599,23596,35191,15923,35192,19067, +35193,35194,35195,23597,35196,35197,35198,35200,35201,35202,35203,35204,18762, +17465,35205,35206,35207,35208,35209,18237,23598,35210,35211,35212,21622,20582, +35213,35214,35215,35216,35217,35218,35219,35220,17451,13909,35221,35222,35223, +35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,35234,35235,35236, +35237,35238,23380,35239,35240,35241,35242,12634,35243,35244,35245,23381,35246, +35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,23382,35257,35258, +35259,14910,35260,35261,35262,35263,35264,35265,35266,35267,35268,35269,35270, +35271,35272,35273,18496,35274,35275,35276,35277,35278,35279,19007,18505,35280, +22323,35281,18809,35282,35283,16199,35284,35285,14968,35286,35287,21052,35288, +35289,35290,35291,35292,35293,35294,35295,25146,35296,13350,35297,35298,12600, +35299,35300,35301,35302,35303,14388,35304,20292,35305,35306,35307,35308,22887, +20262,19810,35309,35310,22893,13920,35311,21049,35312,35313,14651,35314,35315, +35316,35317,25145,25143,35318,13427,35319,19564,19499,14194,35320,22578,20843, +14907,35321,18983,35322,35323,19767,35324,35325,21060,16228,15440,13921,35326, +24133,35392,35393,35394,35395,24134,23356,35396,20825,35397,35398,18022,17486, +14190,35399,14172,35400,35401,16252,22368,35402,18037,35403,35404,12604,24136, +15665,19543,24138,35405,24137,35406,35407,35408,35409,35410,13676,35411,18781, +35412,35413,12354,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423, +35424,35425,35426,17710,17707,35427,17484,35428,15465,19325,35429,35430,35431, +14915,35432,35433,35434,25977,18535,25978,19837,35435,22321,14398,17000,35436, +18513,35437,35438,25979,35439,35440,35441,35442,13898,15435,35443,35444,20861, +26145,35445,17262,35446,35447,35448,35449,26148,35450,35451,35452,35453,25982, +26149,19799,35454,35456,14145,25980,25981,26147,35457,35458,17501,26152,35459, +35460,26151,35461,35462,35463,35464,35465,35466,17219,35467,18014,35468,35469, +26154,35470,35471,35472,35473,35474,35475,35476,17463,35477,35478,35479,26146, +19004,35480,35481,35482,35483,15715,14659,26150,20565,20015,35484,35485,26153, +26160,35486,21030,35487,15658,26157,35488,35489,35490,35491,35492,26159,35493, +16465,35494,35495,21068,35496,35497,35498,15399,35499,35500,35501,35502,35503, +35504,35505,35506,35507,35508,35509,35510,26161,35511,21110,35512,35513,35514, +22347,35515,19838,35516,19806,16934,26155,26156,15679,26158,26163,35517,35518, +26162,35519,35520,35521,35522,26166,35523,26168,35524,35525,35526,35527,17519, +35528,35529,35530,17480,35531,35532,15978,18799,35533,35534,26167,35535,13936, +35536,35537,35538,17252,35539,35540,35541,35542,35543,35544,35545,21353,26164, +35546,26165,35547,18466,35548,35549,35550,35551,35552,26173,35553,35554,35555, +26169,35556,35557,35558,35559,35560,17989,35561,35562,19825,26171,35563,35564, +35565,35566,35567,35568,35569,35570,35571,35572,26172,35573,35574,35575,35576, +15209,35577,35578,35579,35580,35581,35582,35648,26174,35649,35650,35651,35652, +26170,35653,35654,16439,35655,35656,35657,35658,35659,35660,35661,35662,35663, +21284,26175,18804,26179,35664,35665,26180,35666,35667,35668,35669,20598,35670, +35671,35672,35673,35674,35675,35676,35677,35678,35679,35680,35681,35682,35683, +35684,35685,35686,35687,17213,35688,35689,35690,35691,35692,35693,35694,17220, +26178,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706, +35707,35708,26177,35709,35710,35712,35713,35714,35715,35716,26183,20273,35717, +27508,35718,35719,26186,35720,35721,35722,35723,35724,26181,35725,35726,15454, +18729,35727,35728,35729,35730,35731,35732,15413,35733,35734,20307,35735,35736, +35737,35738,35739,26184,35740,26185,35741,26190,35742,26192,35743,35744,35745, +26193,35746,35747,35748,26187,13653,35749,26188,35750,35751,26191,35752,35753, +17499,35754,26182,35755,35756,35757,35758,35759,26189,35760,35761,35762,35763, +35764,35765,35766,35767,35768,35769,35770,35771,35772,35773,35774,35775,35776, +35777,35778,35779,35780,35781,35782,26194,35783,35784,35785,35786,35787,35788, +35789,35790,35791,35792,35793,35794,26196,26195,35795,35796,35797,35798,35799, +35800,35801,35802,35803,35804,35805,35806,35807,35808,35809,35810,35811,35812, +35813,35814,35815,35816,35817,35818,35819,35820,26197,35821,22904,35822,35823, +26198,35824,35825,35826,35827,35828,35829,35830,35831,26199,35832,35833,35834, +35835,35836,35837,35838,35904,35905,35906,35907,35908,35909,35910,35911,22355, +26205,35912,26206,16215,21584,35913,22358,13414,19311,26202,22595,22350,20514, +35914,17231,35915,35916,26207,15422,14658,26203,20775,35917,35918,14882,16975, +35919,22571,35920,35921,35922,19051,25966,35923,26204,35924,14197,35925,35926, +35927,35928,18534,35929,35930,17525,35931,35932,25906,17534,35933,19324,25907, +21804,35934,21358,19032,12338,35935,19278,19818,35936,35937,14954,35938,35939, +35940,25909,35941,25908,35942,22362,14681,22118,13864,19824,21067,12582,18997, +35943,13160,18803,16205,20603,19026,25910,15170,35944,35945,35946,20316,14636, +35947,35948,35949,35950,21591,35951,35952,14886,20839,20348,15442,35953,25911, +18525,35954,35955,35956,16237,12662,19294,35957,35958,15429,35959,15428,21114, +17244,16220,35960,35961,35962,35963,14395,35964,35965,35966,17218,35968,14894, +21538,35969,35970,35971,35972,35973,35974,35975,35976,35977,18270,17455,12908, +35978,14673,35979,35980,25915,16712,35981,35982,21807,35983,35984,35985,35986, +35987,25916,35988,25918,35989,35990,35991,35992,35993,35994,35995,13415,13908, +19266,20784,13628,35996,35997,19033,35998,14178,35999,36000,18788,36001,15659, +36002,36003,20030,22384,36004,36005,36006,36007,20513,36008,18777,36009,36010, +13947,26200,15458,36011,13118,36012,18768,36013,26201,13090,36014,36015,36016, +36017,24140,36018,21320,24141,36019,21026,36020,36021,36022,36023,24142,36024, +36025,36026,36027,15949,36028,36029,24143,36030,36031,36032,18988,21116,13151, +25962,17505,15905,20018,17522,15958,17960,12899,36033,36034,15955,36035,36036, +18300,19563,15724,20061,36037,36038,19002,17985,25964,20540,36039,36040,36041, +21817,36042,36043,36044,25965,36045,36046,36047,36048,19060,36049,19776,16965, +36050,25967,36051,16964,25968,36052,36053,36054,36055,36056,36057,36058,25976, +19789,36059,18749,36060,36061,36062,36063,36064,36065,36066,21081,24872,36067, +36068,36069,36070,21356,36071,19306,18033,36072,36073,36074,36075,36076,24876, +36077,36078,36079,24871,24873,36080,36081,24874,24879,36082,36083,12909,36084, +24875,14426,24877,24878,24880,13626,24881,36085,36086,36087,36088,36089,24883, +24888,36090,36091,36092,36093,36094,20818,36160,24886,24885,16747,36161,36162, +36163,24887,36164,21568,36165,24882,36166,24890,12342,36167,36168,36169,36170, +24884,36171,16249,36172,24889,36173,36174,24891,36175,36176,36177,36178,36179, +36180,24894,36181,36182,36183,36184,36185,36186,24892,36187,36188,36189,36190, +36191,36192,22085,36193,36194,36195,36196,36197,36198,36199,20287,36200,36201, +24893,24895,16973,36202,13931,36203,21368,36204,36205,18253,36206,36207,14181, +36208,36209,36210,36211,36212,36213,36214,36215,36216,36217,15998,36218,36219, +36220,36221,36222,36224,24896,24897,36225,36226,24903,13159,36227,36228,36229, +36230,36231,36232,18025,36233,36234,36235,36236,36237,13406,36238,20802,36239, +36240,36241,36242,24904,36243,36244,24902,36245,36246,36247,36248,36249,24901, +36250,24899,24898,36251,12608,36252,36253,36254,21816,24900,36255,36256,36257, +36258,36259,24907,36260,36261,36262,36263,36264,36265,36266,36267,24908,24906, +36268,36269,36270,36271,36272,36273,36274,36275,28538,36276,36277,24915,24914, +18230,36278,36279,36280,36281,36282,36283,36284,36285,36286,36287,36288,24905, +36289,36290,24910,36291,24912,36292,36293,36294,36295,36296,36297,36298,36299, +36300,36301,36302,24916,36303,24913,24909,36304,36305,24911,36306,36307,36308, +36309,24917,36310,36311,36312,36313,36314,36315,36316,36317,36318,36319,36320, +36321,36322,24918,36323,36324,36325,36326,36327,36328,36329,36330,36331,36332, +36333,36334,36335,36336,36337,36338,36339,36340,36341,36342,36343,36344,24919, +36345,36346,36347,24920,36348,36349,36350,36416,36417,36418,36419,36420,36421, +36422,36423,36424,36425,36426,36427,36428,36429,36430,36431,36432,36433,36434, +36435,36436,36437,24922,36438,36439,36440,36441,36442,36443,36444,36445,36446, +36447,36448,36449,36450,24923,36451,36452,36453,36454,36455,36456,36457,20001, +36458,36459,36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470, +26461,36471,13352,22109,36472,36473,20786,13106,36474,36475,14628,22387,18249, +15966,14638,36476,20055,36477,36478,12910,23375,36480,15418,21073,19272,12365, +36481,36482,20335,36483,36484,36485,36486,36487,22883,15725,36488,36489,12626, +19024,12860,36490,19239,14123,36491,18982,36492,36493,36494,20259,36495,36496, +24696,21834,24699,36497,36498,24698,17729,19579,36499,16689,24697,22115,12847, +22084,13659,36500,36501,36502,36503,36504,36505,36506,36507,13432,22049,36508, +36509,36510,36511,36512,20271,12399,36513,36514,24700,36515,36516,36517,36518, +36519,24865,13091,36520,36521,24701,24702,17201,36522,36523,36524,36525,17245, +36526,24866,14201,36527,36528,36529,36530,36531,36532,15183,36533,36534,36535, +36536,36537,36538,36539,24867,17467,36540,36541,36542,36543,36544,24868,36545, +36546,24869,36547,36548,24870,13361,36549,36550,36551,36552,36553,36554,36555, +36556,36557,36558,36559,36560,36561,36562,36563,14409,17981,17514,36564,12834, +36565,20562,36566,26459,15171,21335,21316,36567,14691,25167,36568,36569,36570, +22319,36571,18284,12627,36572,36573,13362,25169,36574,36575,36576,20594,16942, +25168,36577,16226,21286,13655,25170,13674,36578,17261,14461,36579,14382,36580, +17747,14159,25172,36581,36582,36583,36584,25171,13896,22393,36585,36586,36587, +36588,36589,19749,36590,36591,36592,36593,36594,25176,36595,25174,19068,16181, +21305,25173,36596,36597,36598,36599,25175,36600,36601,36602,36603,36604,36605, +36606,36672,36673,36674,16686,16456,36675,36676,36677,36678,36679,36680,25179, +25178,16426,36681,36682,16718,36683,36684,36685,36686,25180,36687,36688,36689, +36690,36691,36692,36693,36694,36695,36696,36697,36698,25181,36699,25182,36700, +36701,36702,36703,36704,36705,36706,36707,36708,23368,36709,20819,19746,36710, +36711,15656,36712,36713,36714,24131,22565,16170,23373,21100,18042,17706,36715, +36716,36717,24132,36718,12631,24366,36719,36720,36721,19005,36722,24369,36723, +14637,36724,21117,36725,14373,14955,36726,36727,13146,36728,36729,36730,13660, +21829,36731,36732,36733,36734,17238,20306,15137,36736,25971,25970,36737,36738, +25972,36739,19812,36740,18549,36741,36742,36743,36744,36745,36746,36747,13615, +18239,36748,25974,36749,36750,36751,27696,36752,36753,36754,36755,36756,36757, +36758,36759,36760,36761,36762,36763,36764,36765,36766,25958,36767,14697,13617, +36768,16956,25960,25959,25961,36769,36770,36771,36772,21069,36773,36774,36775, +24938,20558,36776,19758,36777,20837,36778,36779,12874,12651,36780,12658,17773, +36781,36782,21827,21296,36783,24924,36784,36785,36786,24925,36787,21083,36788, +13113,12619,36789,36790,36791,19833,21879,24926,36792,15926,13437,36793,24927, +14940,24928,15154,16969,24929,36794,36795,36796,20588,36797,19773,36798,36799, +24930,36800,13635,17735,24931,36801,36802,24932,36803,36804,36805,36806,21369, +36807,36808,36809,36810,36811,36812,24933,36813,20781,36814,36815,24934,20002, +36816,36817,36818,36819,36820,36821,24935,36822,13634,36823,36824,36825,36826, +24936,15189,36827,36828,36829,36830,36831,20548,25184,12632,21092,36832,36833, +25185,36834,36835,15433,18508,36836,25187,27774,27773,24367,36837,36838,36839, +25186,22078,19836,17190,36840,36841,36842,25411,36843,36844,22098,25191,36845, +36846,25192,36847,36848,21319,36849,36850,25196,16236,36851,25197,25189,36852, +36853,13120,36854,36855,36856,17518,36857,36858,25198,36859,36860,20547,36861, +14966,25193,14174,15155,19500,19275,25188,25190,25194,25195,36862,36928,36929, +25207,36930,36931,25204,21621,25203,36932,36933,17709,36934,21882,17730,12864, +36935,36936,25199,36937,25202,16687,19260,36938,36939,13601,25209,36940,36941, +36942,15409,25201,20564,21561,25205,14678,25206,36943,36944,36945,18259,36946, +36947,36948,36949,36950,25200,36951,36952,36953,36954,36955,22364,27937,36956, +36957,25208,36958,27941,25214,19025,36959,36960,36961,36962,36963,36964,36965, +16693,36966,15184,36967,36968,16214,36969,14947,36970,36971,19233,36972,36973, +36974,27942,27939,36975,36976,27938,36977,36978,36979,36980,15190,27943,20596, +36981,36982,27940,14942,13943,25377,13874,19569,14631,36983,20258,18209,36984, +36985,16210,36986,36987,13937,36988,25210,25211,25213,25212,17493,25378,36989, +21313,36990,36992,36993,25383,18244,36994,36995,36996,36997,20260,36998,36999, +25385,14903,37000,37001,37002,37003,25384,37004,15194,37005,25379,37006,37007, +37008,25380,25386,37009,25382,37010,20082,21318,37011,37012,15164,37013,37014, +21571,37015,17530,37016,37017,27944,20604,25381,37018,17269,37019,25389,12591, +37020,25394,37021,37022,37023,15426,37024,37025,25388,13631,37026,37027,37028, +37029,37030,37031,37032,37033,18281,25392,37034,37035,37036,15914,19823,37037, +37038,37039,37040,37041,15219,37042,37043,37044,19560,37045,37046,25391,37047, +25393,37048,20263,25390,37049,20009,15197,37050,37051,37052,37053,37054,13675, +15973,12882,13133,37055,12601,25387,12881,13612,14687,13928,37056,37057,20331, +25399,37058,15180,37059,37060,18503,20554,37061,37062,37063,37064,37065,25400, +13166,37066,37067,37068,37069,27945,37070,21370,21348,37071,37072,37073,27946, +25401,21090,37074,37075,37076,37077,37078,25397,37079,37080,37081,37082,21342, +37083,37084,37085,37086,14416,25395,37087,37088,25398,14175,37089,25396,16418, +37090,37091,37092,25402,37093,37094,37095,37096,37097,37098,37099,37100,37101, +37102,37103,37104,37105,37106,37107,37108,37109,37110,37111,21560,37112,37113, +37114,37115,37116,37117,37118,37184,13384,37185,25403,37186,15173,37187,18807, +37188,37189,18789,37190,37191,37192,17469,37193,37194,37195,37196,37197,37198, +37199,27947,37200,37201,37202,37203,17021,37204,37205,37206,37207,15195,16174, +37208,37209,37210,37211,37212,37213,37214,20031,37215,37216,37217,37218,25404, +37219,16182,37220,37221,37222,37223,37224,37225,37226,37227,37228,37229,37230, +37231,37232,37233,37234,37235,37236,37237,37238,12655,37239,37240,21623,37241, +37242,37243,37244,37245,25406,37246,37248,37249,37250,37251,37252,37253,37254, +27949,37255,37256,37257,37258,37259,37260,37261,37262,37263,25407,14889,27948, +37264,37265,25405,37266,37267,37268,37269,37270,37271,37272,37273,37274,37275, +25408,37276,37277,37278,37279,37280,37281,14902,37282,37283,37284,13870,37285, +37286,37287,37288,37289,20536,37290,12355,27950,37291,37292,37293,37294,37295, +27951,16449,37296,25409,37297,37298,37299,37300,37301,37302,37303,37304,37305, +37306,37307,37308,37309,37310,37311,37312,37313,17715,37314,37315,37316,37317, +37318,37319,37320,37321,37322,37323,37324,37325,37326,37327,25410,37328,37329, +37330,37331,37332,37333,37334,37335,37336,23602,37337,37338,37339,37340,37341, +37342,27952,37343,14442,37344,20076,27175,20583,19065,18518,20279,13129,20050, +15716,37345,37346,25438,15218,27176,21821,37347,18013,27177,37348,37349,37350, +27178,37351,27180,27179,37352,27182,27181,37353,37354,37355,37356,15704,37357, +27183,37358,16958,37359,37360,37361,37362,13377,13431,37363,37364,15143,37365, +37366,37367,37368,37369,27750,27749,14143,19321,12642,37370,27751,37371,37372, +37373,18760,27752,27753,37374,19030,24144,12869,21626,37440,37441,17995,12359, +13426,18515,37442,37443,37444,19792,37445,37446,16184,37447,37448,37449,37450, +37451,37452,37453,16219,37454,37455,18212,22068,37456,16425,24145,18728,20847, +17700,12391,13110,18501,37457,37458,12386,37459,37460,14198,37461,37462,17786, +37463,37464,13939,37465,21842,13136,15420,37466,37467,37468,13101,37469,37470, +37471,37472,15985,12369,37473,37474,37475,37476,37477,37478,21078,19043,22309, +37479,19766,13878,16185,21851,37480,14375,17751,37481,37482,37483,24146,16217, +16981,18240,37484,15140,12584,37485,37486,17770,37487,37488,17787,19495,37489, +37490,37491,37492,12583,37493,37494,37495,13654,37496,37497,37498,17448,37499, +24147,20794,13161,37500,17266,37501,37502,14199,37504,22132,13603,12912,17460, +17513,16429,24148,37505,12392,17732,16736,37506,14677,37507,15964,19800,12366, +37508,19791,24150,15952,22334,24149,21840,12381,37509,37510,17506,37511,37512, +16931,15472,37513,21301,16441,17697,12838,21617,37514,37515,16424,19011,24151, +21884,37516,14640,37517,18477,19241,37518,24153,16189,37519,37520,37521,37522, +17972,22311,18992,17475,37523,13142,14674,37524,37525,37526,37527,22072,27260, +12340,37528,37529,37530,37531,16230,37532,37533,19572,37534,37535,37536,37537, +19802,37538,37539,37540,22079,16974,37541,20046,19490,20526,17491,13618,24152, +21877,15415,15187,37542,37543,12324,37544,17714,13420,37545,37546,37547,21873, +37548,37549,27261,37550,37551,37552,37553,37554,37555,24154,19750,37556,37557, +19820,37558,37559,37560,37561,20070,24156,37562,19761,16422,37563,37564,22333, +37565,24155,12358,14900,18771,17523,15976,37566,37567,37568,37569,12854,37570, +37571,37572,37573,37574,37575,37576,37577,16460,19312,37578,15473,15163,13623, +37579,37580,37581,17781,37582,24166,37583,37584,37585,24163,15965,37586,37587, +24159,37588,37589,37590,37591,13367,15709,37592,37593,24160,17517,37594,37595, +37596,37597,20294,37598,13664,37599,37600,37601,37602,13918,19034,13684,24165, +37603,21830,37604,24161,19533,18046,37605,17733,37606,37607,37608,21044,37609, +15986,37610,37611,37612,37613,37614,37615,37616,16979,37617,19517,13112,37618, +15699,37619,16216,19782,20826,13419,37620,24164,24157,24167,37621,27262,37622, +37623,16944,24162,37624,37625,22080,13607,37626,12916,37627,24168,37628,24178, +37629,37630,37696,37697,37698,24173,37699,24177,37700,37701,18528,37702,37703, +37704,22369,24175,17256,19553,37705,12901,37706,37707,37708,21054,37709,37710, +37711,37712,37713,37714,37715,24174,37716,24171,20053,37717,13351,37718,37719, +37720,37721,37722,16171,15934,37723,37724,15698,37725,37726,37727,37728,24169, +37729,21550,37730,24158,37731,24170,37732,37733,37734,37735,16447,37736,24172, +12915,14441,16935,37737,37738,15681,37739,37740,37741,37742,37743,24181,24184, +37744,37745,12843,13348,37746,37747,13418,18726,37748,37749,37750,37751,37752, +37753,24182,19281,37754,14435,37755,24183,24186,37756,37757,37758,37760,24185, +37761,37762,37763,19522,37764,12385,13422,37765,37766,37767,37768,37769,37770, +25914,37771,37772,37773,37774,37775,20527,37776,37777,12907,37778,27425,37779, +24180,37780,37781,18787,24179,12378,21025,12663,37782,19503,37783,37784,37785, +37786,37787,37788,37789,24176,37790,19236,37791,37792,37793,21802,37794,37795, +37796,37797,37798,24187,37799,37800,37801,37802,37803,37804,37805,37806,13405, +37807,17446,37808,37809,37810,24189,37811,37812,37813,37814,37815,37816,37817, +37818,37819,37820,17278,17441,24353,37821,37822,37823,37824,37825,37826,37827, +16716,37828,24188,15983,37829,17970,37830,37831,37832,37833,37834,37835,37836, +37837,37838,13125,18550,37839,37840,19258,24190,37841,37842,24356,37843,37844, +37845,37846,22322,37847,37848,37849,37850,37851,13111,37852,37853,37854,37855, +16707,37856,37857,18251,12837,13417,37858,22315,37859,37860,37861,37862,17516, +37863,24354,24355,37864,24357,37865,14899,37866,37867,37868,24358,37869,16478, +37870,37871,18755,37872,37873,37874,37875,37876,37877,37878,12889,18278,37879, +24359,37880,18268,37881,37882,37883,37884,24360,27426,37885,37886,37952,37953, +37954,19283,37955,37956,37957,24362,37958,24361,37959,12865,37960,37961,37962, +37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975, +37976,37977,37978,37979,37980,37981,37982,37983,37984,17738,37985,37986,37987, +37988,37989,37990,37991,37992,24363,37993,37994,37995,37996,37997,37998,37999, +38000,21596,38001,38002,38003,38004,38005,18497,38006,38007,38008,38009,38010, +38011,38012,38013,38014,38016,38017,38018,24364,38019,38020,38021,38022,38023, +15984,38024,38025,24365,22055,38026,38027,38028,38029,27191,27446,19029,38030, +22652,14404,38031,14629,38032,38033,14149,21886,38034,38035,38036,38037,38038, +14666,38039,38040,20519,29773,38041,38042,13648,38043,38044,17268,38045,15944, +38046,38047,38048,27447,12349,38049,38050,15692,38051,16690,38052,12630,13096, +38053,38054,38055,14418,18722,38056,38057,13912,38058,38059,38060,38061,27448, +15924,38062,38063,38064,19069,38065,18243,38066,21883,38067,38068,14195,38069, +38070,38071,38072,38073,38074,38075,38076,38077,38078,38079,38080,38081,38082, +38083,20036,38084,38085,38086,21803,12659,38087,38088,38089,27699,12383,38090, +27701,38091,38092,38093,13879,38094,16719,38095,30074,20529,38096,38097,21861, +38098,20051,38099,38100,15727,13154,38101,14379,38102,21814,38103,27965,38104, +13903,38105,19257,20546,38106,38107,38108,38109,38110,38111,38112,38113,14141, +38114,38115,27702,18985,38116,38117,38118,17748,38119,27705,27704,16963,27703, +38120,38121,38122,38123,20605,27706,38124,27707,22373,38125,38126,27708,38127, +38128,38129,27709,18028,38130,38131,38132,38133,38134,38135,38136,38137,20062, +38138,15432,38139,38140,18517,13609,15945,22076,21607,38141,38142,20782,20593, +27192,27193,27194,14901,38208,38209,38210,38211,18993,16245,38212,38213,19834, +38214,38215,38216,38217,38218,27200,38219,12346,27198,38220,38221,16421,38222, +38223,38224,27195,38225,12925,38226,17271,15208,38227,38228,38229,21079,20084, +27199,38230,38231,38232,27196,38233,38234,38235,27203,38236,20551,21299,38237, +38238,38239,38240,13370,38241,17217,22386,38242,38243,38244,38245,21841,38246, +19015,38247,27205,38248,38249,27204,27207,27206,38250,38251,38252,38253,38254, +22119,38255,20308,38256,38257,27211,38258,15182,38259,38260,38261,38262,38263, +38264,38265,15738,18766,38266,38267,27212,38268,38269,18745,20350,27210,21582, +27213,27215,38270,38272,19821,38273,38274,38275,38276,27209,38277,27214,38278, +38279,20078,38280,15198,38281,13119,38282,38283,38284,38285,38286,18005,15920, +20090,38287,38288,38289,18279,38290,15911,27216,38291,38292,22087,38293,38294, +38295,16704,38296,38297,38298,21597,38299,27217,38300,38301,20286,38302,38303, +38304,38305,27218,38306,38307,38308,38309,19054,38310,38311,38312,38313,17711, +12341,38314,38315,38316,38317,38318,27220,38319,38320,38321,38322,38323,38324, +38325,38326,38327,27219,29791,38328,38329,38330,38331,38332,17466,38333,38334, +38335,38336,38337,12585,38338,38339,38340,38341,25951,38342,38343,38344,38345, +27221,38346,38347,38348,38349,38350,38351,38352,38353,38354,38355,38356,38357, +38358,38359,38360,38361,38362,38363,38364,38365,38366,38367,38368,38369,38370, +38371,19055,38372,27222,27223,18008,38373,38374,38375,38376,38377,38378,38379, +38380,27224,38381,38382,27225,38383,38384,38385,38386,38387,38388,21563,38389, +18298,21047,14460,38390,38391,27202,38392,12892,38393,38394,17020,38395,21624, +19558,22382,38396,38397,38398,38464,38465,38466,38467,21570,21328,27459,17779, +38468,14206,38469,38470,27476,38471,38472,38473,19255,27486,38474,16458,38475, +38476,38477,19835,38478,13103,38479,18010,38480,38481,38482,38483,38484,38485, +27516,38486,17470,38487,20020,17449,12606,21629,38488,19061,38489,22124,38490, +38491,18003,13924,38492,38493,38494,38495,15226,38496,38497,20576,38498,38499, +18737,38500,21587,18472,38501,38502,14411,38503,26686,18748,38504,38505,26683, +38506,16494,20563,12868,13413,38507,26684,38508,38509,21832,38510,38511,38512, +38513,38514,13893,38515,26685,19064,14428,19573,38516,38517,38518,16436,38519, +38520,20846,26687,26690,38521,38522,14908,38523,12589,15708,38524,27197,26691, +38525,26694,38526,26699,38528,38529,38530,38531,26700,38532,19273,12389,38533, +15403,38534,38535,14649,38536,38537,26689,38538,19831,38539,26698,38540,38541, +38542,38543,20086,38544,38545,38546,38547,21869,38548,16726,26692,38549,17206, +38550,14715,22054,26696,38551,38552,38553,19040,21606,38554,26688,38555,26693, +26695,38556,18233,14179,38557,26697,38558,16221,26706,38559,38560,26711,38561, +26709,15452,15439,26715,38562,38563,38564,38565,38566,38567,38568,38569,26718, +38570,26714,12666,38571,38572,38573,38574,38575,38576,38577,38578,38579,38580, +12376,17459,14412,18018,18494,18529,38581,38582,38583,26703,26708,26710,38584, +14705,26712,22389,38585,17531,38586,26716,38587,38588,12905,38589,38590,38591, +26705,38592,38593,15469,38594,38595,16194,26701,22137,38596,16760,12913,38597, +38598,38599,38600,38601,38602,38603,38604,26719,38605,19009,26713,38606,38607, +38608,38609,21796,38610,12650,21819,26702,26704,13872,26707,38611,26717,16440, +38612,19063,38613,19240,38614,38615,18012,16501,38616,38617,38618,38619,38620, +26729,38621,38622,38623,20515,38624,38625,38626,38627,38628,38629,38630,26738, +22122,38631,38632,38633,38634,38635,38636,38637,26720,26721,38638,38639,38640, +20857,14923,14457,38641,38642,14449,21588,26735,38643,26734,26732,14704,19538, +26726,20006,16242,38644,12344,26737,26736,38645,22336,38646,26724,38647,19753, +18723,38648,15160,15707,26730,38649,38650,38651,38652,38653,38654,38720,38721, +38722,38723,26722,26723,26725,13621,26727,18245,26731,26733,15664,22318,38724, +26744,38725,38726,38727,38728,38729,38730,38731,38732,26741,38733,19760,26742, +38734,38735,38736,38737,38738,38739,38740,38741,38742,16698,38743,26728,38744, +17207,12400,38745,38746,38747,38748,38749,38750,38751,38752,26740,38753,38754, +38755,26743,38756,38757,38758,14627,38759,38760,38761,38762,38763,38764,38765, +38766,38767,38768,18770,38769,38770,38771,17230,20064,16486,38772,38773,38774, +38775,19315,38776,19549,20533,38777,38778,19041,38779,26739,38780,38781,38782, +38784,38785,38786,38787,38788,38789,38790,15468,38791,26745,38792,38793,38794, +38795,38796,38797,17246,38798,18021,38799,14711,38800,38801,38802,38803,12404, +38804,38805,22360,38806,38807,15404,38808,17775,38809,38810,38811,38812,38813, +19524,38814,38815,26918,38816,38817,38818,38819,38820,38821,38822,38823,38824, +38825,18733,38826,26914,16482,38827,38828,38829,16195,38830,38831,38832,26750, +14679,38833,26747,38834,38835,38836,38837,26916,38838,38839,38840,21070,38841, +38842,38843,38844,38845,26915,38846,22066,22325,38847,26919,38848,15671,38849, +38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,26748,26749, +38861,38862,38863,26913,38864,38865,38866,38867,38868,38869,38870,38871,19798, +38872,38873,21036,38874,38875,38876,26930,38877,38878,38879,38880,26921,38881, +38882,38883,13354,38884,13371,38885,38886,26923,38887,38888,38889,38890,38891, +38892,38893,38894,38895,38896,38897,38898,38899,38900,38901,38902,38903,20520, +38904,38905,26917,38906,38907,13182,38908,38909,26924,16483,38910,26922,38976, +38977,26937,38978,38979,26936,38980,38981,38982,38983,26926,38984,38985,26746, +38986,38987,26920,38988,38989,38990,38991,38992,16172,26929,26938,38993,38994, +16933,38995,38996,38997,26927,38998,14405,38999,26925,39000,21340,26932,26933, +26935,39001,39002,39003,26951,39004,39005,39006,39007,39008,39009,16454,26949, +39010,39011,26928,39012,39013,26939,12401,39014,39015,39016,39017,39018,39019, +39020,39021,39022,39023,26940,21797,39024,39025,26942,39026,26943,39027,39028, +39029,26945,39030,39031,16753,39032,39033,18486,39034,39035,39036,26941,39037, +39038,39040,39041,39042,26946,39043,39044,39045,39046,39047,39048,39049,39050, +26947,39051,26931,39052,26934,39053,15153,39054,39055,39056,26944,39057,39058, +39059,39060,39061,39062,15479,39063,39064,39065,26948,26950,39066,39067,39068, +39069,39070,39071,39072,39073,39074,39075,39076,39077,26954,39078,39079,39080, +39081,26958,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,12891, +39092,26952,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,14126, +39103,39104,39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,26955, +26956,39115,39116,39117,39118,39119,39120,21825,39121,17443,39122,39123,39124, +39125,39126,39127,26968,39128,14945,39129,39130,39131,39132,26953,39133,21283, +39134,39135,39136,26964,39137,39138,39139,39140,39141,39142,39143,26967,26960, +39144,39145,39146,39147,39148,26959,39149,39150,18241,39151,39152,39153,39154, +39155,39156,39157,39158,26962,39159,39160,39161,39162,39163,39164,39165,26969, +13128,39166,26963,39232,39233,39234,39235,39236,20336,39237,39238,39239,26957, +39240,39241,39242,39243,39244,39245,39246,39247,39248,39249,39250,13175,39251, +39252,39253,39254,39255,39256,39257,26966,39258,39259,26970,39260,39261,39262, +19508,39263,39264,39265,20269,39266,39267,39268,39269,39270,39271,39272,39273, +39274,26965,39275,26972,26971,39276,39277,39278,39279,39280,26974,39281,39282, +39283,39284,39285,39286,39287,39288,26961,39289,39290,39291,39292,39293,39294, +39296,39297,26973,39298,26975,17226,39299,39300,39301,39302,39303,39304,39305, +39306,39307,39308,39309,39310,39311,39312,39313,39314,39315,39316,39317,39318, +39319,39320,39321,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331, +39332,39333,39334,39335,39336,39337,39338,39339,39340,39341,39342,39343,39344, +39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357, +39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370, +39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383, +39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396, +39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409, +39410,39411,39412,39413,18231,13390,15158,20544,27683,39414,39415,17719,39416, +39417,39418,39419,39420,39421,39422,39488,39489,39490,21371,39491,39492,39493, +39494,27684,39495,27685,18011,39496,39497,39498,16238,39499,39500,39501,39502, +27686,39503,39504,27687,20522,39505,18232,39506,39507,14440,39508,39509,39510, +39511,39512,39513,39514,39515,39516,39517,39518,39519,27688,39520,39521,39522, +39523,39524,39525,39526,39527,22073,21885,13387,12861,20068,18023,39528,39529, +19809,39530,39531,39532,39533,39534,39535,39536,39537,39538,39539,39540,39541, +39542,39543,13429,39544,19264,15455,39545,39546,39547,39548,26978,26979,20842, +26981,39549,13433,26980,39550,20787,19042,12880,39552,26984,39553,39554,39555, +39556,26982,26983,39557,39558,22067,39559,39560,39561,26985,26986,39562,39563, +39564,39565,39566,26987,39567,39568,39569,39570,39571,39572,39573,39574,26988, +39575,39576,39577,39578,39579,39580,39581,39582,27695,17721,13902,39583,21107, +39584,39585,39586,39587,39588,39589,39590,13678,39591,15193,27697,39592,39593, +21091,39594,39595,39596,39597,39598,20067,39599,17464,39600,17215,39601,39602, +13886,22585,12616,12623,12625,17790,39603,12624,39604,17195,39605,39606,39607, +39608,39609,21809,39610,39611,39612,39613,39614,39615,39616,39617,27428,14913, +39618,39619,39620,19514,39621,39622,39623,27429,39624,27431,39625,39626,39627, +27432,39628,39629,39630,27430,39631,39632,39633,39634,39635,39636,39637,27433, +27435,27434,39638,39639,39640,39641,39642,27436,39643,19023,22581,17265,39644, +17189,18040,27437,17482,39645,27438,27439,27440,14165,39646,39647,39648,14202, +39649,27441,18274,39650,27443,39651,14884,20853,12337,27442,27444,39652,39653, +39654,13610,16968,18280,39655,27445,39656,19246,25439,39657,39658,21312,39659, +39660,39661,39662,22875,39663,39664,19745,22061,18291,39665,39666,39667,22880, +15203,39668,14906,25442,39669,39670,39671,39672,39673,20267,39674,39675,39676, +25440,18759,39677,14905,39678,39744,39745,20788,25441,18538,14639,15661,13144, +20059,39746,39747,19520,39748,39749,39750,25448,25449,19828,39751,39752,39753, +39754,39755,19501,39756,15411,39757,25450,39758,25451,39759,39760,20570,39761, +39762,39763,18043,14170,39764,39765,18271,21066,20054,39766,25444,25452,39767, +18802,13121,39768,39769,25447,39770,39771,18019,25445,39772,39773,27955,25446, +39774,39775,39776,39777,18739,39778,17766,39779,39780,39781,14645,39782,17211, +39783,25443,17725,16676,16985,12887,39784,25453,15142,17453,39785,25456,15962, +39786,39787,25467,25461,14931,39788,39789,39790,39791,14160,21325,39792,22094, +21843,14657,21812,20824,39793,39794,39795,39796,20537,18294,39797,39798,39799, +18474,12852,39800,17242,39801,39802,39803,25454,39804,39805,25468,25455,14120, +25463,25460,39806,39808,39809,14138,39810,39811,17698,39812,25462,17757,12840, +18044,39813,17504,39814,39815,22306,39816,16481,25465,39817,39818,25466,25469, +19497,25459,39819,21310,39820,12611,27956,25457,25458,39821,25464,20538,17987, +21619,25470,39822,39823,15712,39824,39825,25639,39826,39827,25638,39828,39829, +39830,20851,25635,39831,25641,39832,39833,39834,18551,39835,39836,39837,39838, +20276,39839,25640,25646,16997,39840,39841,13876,39842,39843,39844,39845,39846, +39847,15730,39848,25634,39849,39850,14953,25642,39851,39852,25644,39853,39854, +13949,22110,25650,39855,25645,39856,39857,39858,25633,39859,15214,19805,18210, +17737,39860,39861,16759,39862,25636,39863,18227,15660,15677,25637,39864,22343, +12898,39865,25643,15427,25647,39866,15211,25648,17704,25649,39867,39868,39869, +39870,21859,16163,39871,25658,39872,25655,39873,25659,39874,39875,25661,39876, +39877,18006,39878,39879,14918,16459,39880,39881,39882,14369,25652,39883,39884, +39885,39886,21537,39887,39888,14883,15742,39889,39890,39891,25660,39892,39893, +39894,39895,39896,19775,39897,39898,17529,39899,39900,20347,18790,39901,39902, +21311,39903,20305,39904,39905,25651,39906,25656,25657,19561,39907,39908,39909, +39910,39911,19534,39912,16468,25653,16688,25654,20048,39913,15169,13651,39914, +18547,15655,21831,18732,14370,25674,39915,39916,25676,20804,39917,39918,21050, +39919,39920,14893,39921,39922,14932,39923,39924,39925,39926,39927,39928,25667, +13677,39929,39930,39931,22349,25664,20349,25663,39932,39933,39934,16732,19530, +40000,40001,40002,40003,19047,40004,40005,40006,40007,17495,40008,19540,25672, +40009,40010,40011,25671,25665,40012,25668,13613,40013,40014,21337,40015,25670, +40016,40017,40018,40019,21113,13411,40020,15156,40021,40022,18798,40023,13374, +40024,40025,40026,15212,40027,20813,40028,19565,27957,40029,40030,40031,40032, +40033,40034,40035,40036,18277,40037,40038,40039,40040,21544,40041,25675,22357, +25666,40042,15653,25669,40043,40044,21350,40045,25673,18808,40046,40047,25662, +40048,40049,21349,40050,40051,18302,13897,40052,21628,12851,25687,40053,40054, +40055,20034,40056,25677,40057,20028,40058,14427,40059,40060,25686,40061,16202, +40062,40064,40065,21326,40066,17260,40067,40068,40069,40070,40071,40072,40073, +40074,17736,25688,40075,40076,40077,40078,40079,40080,40081,40082,19780,25679, +40083,40084,40085,40086,25684,25685,40087,14974,40088,20326,40089,40090,21823, +40091,40092,40093,25682,40094,40095,40096,40097,40098,40099,40100,40101,40102, +40103,40104,25680,40105,40106,25678,40107,40108,40109,40110,40111,40112,40113, +40114,40115,40116,40117,40118,40119,40120,40121,19813,18986,40122,40123,40124, +16419,40125,15654,25683,40126,40127,14408,40128,40129,40130,40131,40132,25703, +21556,40133,40134,40135,40136,40137,40138,40139,25691,40140,40141,40142,16751, +40143,40144,25705,40145,40146,21095,40147,40148,25695,40149,25696,40150,40151, +20266,40152,40153,40154,40155,19293,40156,25690,25681,40157,25701,40158,18524, +25699,40159,40160,17511,25698,40161,25697,40162,40163,40164,13180,25704,40165, +40166,40167,40168,13665,40169,40170,40171,22348,40172,40173,40174,25702,40175, +15148,40176,22354,19535,27512,40177,25700,40178,40179,14710,40180,40181,40182, +22093,25689,25692,17018,25694,40183,16971,16452,16976,40184,12661,19506,40185, +40186,40187,40188,40189,40190,40256,40257,40258,40259,13646,40260,40261,40262, +40263,25711,40264,40265,40266,40267,40268,40269,40270,40271,17967,40272,40273, +40274,18017,40275,40276,25717,40277,40278,40279,40280,40281,16937,40282,40283, +40284,16492,20829,25710,40285,40286,40287,40288,40289,40290,40291,40292,40293, +40294,17454,40295,40296,40297,25709,40298,40299,40300,40301,25718,25716,17022, +40302,25693,40303,25712,40304,19070,40305,21828,40306,40307,25713,40308,40309, +40310,40311,40312,40313,40314,20858,40315,40316,40317,40318,40320,40321,40322, +25707,25708,40323,40324,40325,25714,40326,20011,40327,40328,40329,40330,40331, +40332,40333,40334,40335,40336,17739,40337,40338,40339,18225,40340,16954,40341, +40342,40343,25706,40344,40345,40346,16714,40347,40348,40349,40350,40351,40352, +19510,13105,40353,40354,40355,25723,40356,25715,40357,40358,40359,25722,40360, +25725,40361,25724,40362,40363,40364,40365,40366,40367,40368,13134,40369,40370, +40371,13114,25719,40372,40373,25721,25720,17772,40374,40375,40376,40377,40378, +40379,40380,40381,40382,40383,40384,40385,40386,16445,40387,40388,40389,40390, +21608,40391,40392,40393,40394,40395,25890,40396,40397,40398,40399,40400,40401, +40402,40403,40404,40405,40406,12356,40407,40408,25892,40409,40410,25891,40411, +40412,40413,40414,40415,40416,15396,40417,25893,40418,40419,40420,40421,40422, +40423,25889,40424,40425,40426,40427,40428,40429,40430,25726,12660,40431,40432, +40433,40434,40435,40436,40437,40438,40439,40440,40441,25896,40442,25897,25894, +40443,40444,40445,40446,40512,40513,40514,40515,40516,40517,40518,40519,25895, +25898,40520,40521,40522,40523,40524,40525,40526,40527,40528,40529,40530,40531, +40532,40533,40534,40535,40536,40537,40538,40539,40540,40541,40542,40543,40544, +40545,40546,40547,40548,40549,40550,40551,40552,18009,40553,40554,40555,40556, +40557,40558,40559,40560,25899,25901,40561,40562,40563,40564,40565,40566,40567, +25900,40568,40569,40570,40571,40572,40573,40574,40576,40577,40578,40579,40580, +40581,40582,40583,40584,40585,25903,40586,40587,40588,25902,40589,40590,40591, +40592,40593,40594,40595,40596,40597,40598,40599,40600,40601,40602,40603,40604, +40605,40606,14688,40607,40608,25904,40609,40610,40611,40612,40613,40614,40615, +40616,40617,40618,40619,40620,40621,40622,25905,40623,40624,40625,40626,40627, +40628,40629,40630,40631,40632,40633,40634,15216,27745,17264,40635,13638,15186, +40636,40637,40638,40639,16745,21614,40640,15940,40641,40642,40643,22342,40644, +21590,12883,27710,40645,40646,40647,40648,27201,40649,40650,40651,16943,13366, +40652,40653,40654,20823,40655,40656,40657,13108,40658,18482,16187,27712,40659, +40660,22091,40661,40662,27711,27713,40663,40664,40665,40666,40667,40668,40669, +40670,40671,40672,40673,40674,40675,27717,15974,19519,17754,15932,40676,27718, +40677,12670,40678,40679,40680,27716,21800,13667,40681,27714,16694,13155,40682, +40683,27715,19256,16451,19582,40684,40685,40686,40687,16722,40688,27720,40689, +40690,40691,40692,40693,40694,40695,40696,40697,40698,40699,40700,40701,14950, +16467,40702,22130,40768,40769,40770,20812,40771,40772,40773,40774,16190,40775, +14131,18773,27719,15202,40776,19532,15741,18504,40777,20265,40778,40779,40780, +40781,40782,40783,40784,19817,40785,17771,40786,40787,40788,14185,40789,40790, +40791,40792,40793,40794,40795,40796,40797,40798,40799,20809,14904,40800,40801, +40802,40803,40804,27721,40805,40806,27722,40807,15168,27723,40808,27746,12602, +14169,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,40819,15673, +40820,40821,40822,40823,40824,40825,40826,40827,27724,20838,27725,40828,40829, +40830,40832,18491,40833,40834,40835,40836,40837,40838,40839,40840,40841,40842, +40843,40844,40845,40846,27729,40847,40848,40849,40850,27731,40851,15181,40852, +15461,40853,40854,40855,40856,40857,40858,40859,40860,40861,40862,40863,40864, +40865,27727,40866,18743,40867,40868,40869,40870,40871,17210,40872,27747,21845, +27728,40873,40874,40875,40876,40877,22131,40878,40879,40880,27730,27726,40881, +40882,40883,40884,27732,40885,27733,40886,40887,18751,40888,40889,40890,40891, +40892,40893,20264,40894,40895,40896,40897,40898,20572,40899,40900,40901,40902, +20780,40903,40904,40905,40906,18523,40907,40908,40909,27734,20085,40910,40911, +40912,40913,40914,19052,27738,40915,40916,40917,40918,40919,40920,40921,27737, +40922,40923,40924,12350,40925,40926,40927,40928,40929,40930,27735,40931,27736, +40932,40933,40934,27748,40935,40936,40937,40938,40939,40940,40941,40942,40943, +18492,40944,40945,40946,40947,40948,40949,40950,40951,40952,40953,16711,40954, +40955,40956,40957,40958,27740,20832,41024,41025,41026,41027,41028,41029,41030, +41031,41032,41033,27739,41034,41035,41036,41037,21615,41038,27741,41039,41040, +41041,41042,41043,41044,23366,41045,41046,41047,41048,41049,41050,41051,41052, +41053,41054,27742,41055,41056,41057,41058,41059,41060,41061,41062,41063,41064, +41065,41066,12588,41067,41068,41069,41070,41071,41072,41073,41074,41075,41076, +41077,41078,41079,41080,41081,41082,41083,41084,41085,41086,41088,41089,27743, +41090,41091,41092,41093,41094,41095,41096,41097,41098,41099,27744,41100,22310, +41101,17728,41102,41103,41104,27452,12334,41105,41106,41107,15988,14392,21039, +12374,13689,41108,22579,41109,19244,41110,25437,41111,41112,41113,41114,41115, +41116,41117,17964,12390,41118,41119,41120,17734,27449,41121,41122,41123,41124, +27450,41125,41126,41127,27451,41128,41129,20800,41130,17699,41131,27250,41132, +17458,41133,17461,16462,41134,41135,41136,27251,17473,41137,20079,41138,41139, +41140,41141,27248,27252,41142,41143,18812,41144,41145,18211,41146,41147,41148, +19544,20094,41149,41150,41151,27253,27254,20268,16487,41152,41153,27255,41154, +41155,41156,41157,41158,13887,27256,41159,27257,41160,27258,41161,41162,27259, +41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173,41174,27249, +41175,41176,41177,41178,41179,41180,41181,41182,41183,41184,41185,41186,18478, +24939,41187,14136,24940,41188,41189,41190,24941,41191,22324,24942,24943,21324, +41192,41193,41194,41195,41196,41197,41198,24945,16241,24944,13650,41199,41200, +41201,12599,41202,41203,41204,41205,24947,24946,41206,14972,41207,24948,41208, +41209,41210,41211,14647,41212,15953,41213,41214,43584,43585,17532,43586,14941, +15686,43587,43588,43589,43590,43591,43592,24949,24951,43593,43594,13888,20289, +18984,24950,21880,21372,24952,24956,24953,43595,43596,24954,16490,43597,24958, +25121,16455,43598,43599,43600,43601,24955,43602,24957,43603,43604,43605,43606, +43607,43608,25125,43609,43610,43611,16724,43612,43613,43614,43615,25123,43616, +25128,12926,25122,43617,43618,43619,17229,12866,25127,25126,43620,43621,25124, +25129,43622,43623,25131,43624,43625,43626,20553,22125,17192,25132,43627,20311, +43628,43629,25134,43630,43631,14959,43632,43633,26976,25133,25130,43634,43635, +43636,43637,15147,21555,43638,43639,43640,43641,43642,43643,43644,43645,43646, +43648,43649,43650,43651,25136,43652,43653,25135,43654,26977,43655,43656,43657, +43658,25137,43659,43660,43661,43662,43663,43664,43665,43666,25138,43667,43668, +43669,43670,43671,43672,43673,43674,43675,43676,43677,25139,19489,43678,25140, +43679,43680,43840,43841,43842,43843,43844,43845,43846,43847,43848,43849,43850, +43851,25141,43852,43853,43854,43855,43856,20606,43857,43858,16970,43859,21361, +43860,19829,43861,43862,26464,43863,43864,26465,43865,43866,43867,43868,15937, +43869,43870,43871,43872,17002,43873,43874,43875,26468,43876,43877,26467,43878, +43879,43880,43881,43882,43883,19814,43884,17205,43885,43886,26466,15159,20310, +43887,16737,26473,43888,43889,43890,26472,43891,43892,26484,12835,43893,43894, +43895,43896,26474,43897,26470,43898,43899,43900,43901,43902,26476,26475,18746, +43904,43905,21860,43906,26469,14121,26471,43907,43908,43909,43910,43911,43912, +43913,26478,43914,43915,43916,43917,26483,43918,22121,43919,43920,43921,43922, +26477,43923,26482,43924,26481,43925,43926,43927,12384,43928,43929,43930,43931, +26485,43932,43933,43934,43935,43936,44096,44097,44098,44099,44100,44101,44102, +44103,44104,44105,44106,18290,44107,16453,16493,44108,44109,16752,26480,44110, +44111,44112,44113,26486,19318,44114,44115,44116,44117,44118,44119,44120,44121, +44122,26658,26657,44123,44124,44125,44126,44127,44128,22337,44129,44130,26490, +26489,44131,26491,44132,26487,44133,26494,44134,26493,44135,26492,44136,44137, +16725,18265,17789,17731,44138,44139,44140,44141,44142,18285,44143,44144,44145, +44146,26659,44147,44148,44149,44150,44151,44152,44153,44154,44155,44156,44157, +44158,44160,44161,44162,44163,44164,44165,44166,26662,44167,26661,44168,26663, +14967,26488,26660,44169,18544,18730,44170,44171,44172,44173,44174,44175,44176, +44177,44178,44179,44180,44181,44182,26665,44183,44184,14693,44185,44186,44187, +44188,44189,20862,26664,44190,44191,44192,44352,44353,44354,26666,44355,26669, +26670,44356,16679,44357,44358,44359,26671,44360,44361,44362,26672,44363,44364, +26668,44365,26676,44366,44367,44368,44369,44370,44371,44372,44373,44374,44375, +44376,26667,44377,26673,44378,44379,44380,44381,44382,44383,44384,44385,26677, +26674,26675,44386,44387,44388,44389,44390,44391,44392,44393,44394,44395,44396, +44397,44398,44399,44400,44401,26679,44402,44403,44404,44405,44406,44407,44408, +44409,44410,44411,44412,44413,44414,44416,44417,44418,44419,44420,44421,44422, +44423,44424,44425,26678,44426,44427,44428,44429,44430,44431,44432,44433,44434, +14671,44435,28716,44436,28717,44437,17968,12394,18495,44438,19807,44439,44440, +44441,44442,44443,44444,44445,20045,27185,44446,44447,44448,44608,27186,44609, +17983,13385,44610,44611,44612,44613,44614,44615,44616,27187,44617,44618,44619, +44620,21863,44621,44622,44623,44624,44625,44626,44627,44628,23929,44629,27188, +44630,27189,44631,27190,44632,44633,44634,44635,14410,24368,18805,44636,19568, +44637,44638,18810,44639,44640,44641,44642,44643,18811,44644,44645,21315,19238, +44646,14374,28718,12610,44647,25912,19567,21321,15447,18794,44648,13671,44649, +17488,13673,44650,28206,15149,44651,44652,26462,44653,28207,44654,44655,44656, +44657,13097,44658,44659,28210,44660,44661,28209,15719,44662,28208,20023,44663, +44664,44665,44666,17743,44667,44668,44669,44670,16756,23374,28211,20595,44672, +44673,44674,44675,44676,44677,44678,44679,16980,18024,44680,44681,44682,14124, +44683,44684,44685,44686,44687,44688,44689,28212,44690,13163,44691,44692,44693, +15227,28213,44694,44695,44696,44697,44698,26460,44699,44700,44701,28214,44702, +44703,15662,44704,44864,44865,44866,29026,44867,44868,44869,19048,44870,21065, +28762,44871,28763,44872,28764,16710,44873,14445,15950,44874,44875,28766,44876, +17713,28765,20849,44877,28768,12364,15722,44878,44879,44880,44881,44882,21087, +28767,44883,13359,14184,28774,28773,17955,28769,28770,13379,44884,44885,28771, +21870,44886,44887,19547,15954,15410,44888,44889,44890,28776,28775,28772,12833, +44891,22050,21304,15927,18476,44892,44893,28778,44894,44895,44896,44897,20855, +44898,22092,14939,28777,44899,13883,44900,44901,19764,44902,44903,17958,44904, +44905,44906,16673,28779,28782,44907,28781,28784,28780,44908,15166,28783,44909, +44910,44911,44912,19509,28786,44913,44914,13141,44915,44916,44917,44918,12628, +44919,44920,28787,44921,44922,28788,28790,13409,44923,28785,44924,28791,44925, +44926,44928,44929,28794,44930,28792,44931,44932,44933,28789,44934,44935,44936, +44937,28797,44938,28793,28796,28798,44939,28961,44940,44941,44942,20033,28964, +44943,28963,44944,16758,28795,19037,44945,44946,13425,12657,19505,44947,28966, +44948,44949,28967,44950,44951,28972,21838,28969,44952,44953,18483,44954,44955, +44956,28962,44957,28971,28968,28965,44958,44959,28970,44960,45120,45121,45122, +45123,45124,45125,45126,12329,28973,45127,45128,45129,45130,45131,45132,28975, +45133,28977,45134,45135,45136,45137,45138,28976,45139,28974,45140,45141,45142, +45143,20770,45144,45145,45146,45147,45148,45149,45150,28978,45151,45152,45153, +28979,45154,45155,45156,45157,45158,45159,45160,45161,14703,45162,45163,13639, +45164,12375,12377,45165,45166,45167,21613,45168,13636,45169,15700,15178,28711, +45170,45171,14430,45172,45173,28712,45174,45175,12328,45176,28713,45177,45178, +19822,45179,45180,28714,45181,45182,45184,45185,45186,45187,45188,45189,45190, +45191,28715,45192,45193,45194,45195,45196,45197,45198,45199,45200,17956,45201, +45202,22117,29028,45203,29029,45204,45205,45206,45207,45208,45209,45210,45211, +45212,45213,17267,45214,45215,21339,45216,45376,22097,17768,45377,21295,45378, +21094,45379,45380,28225,12347,21813,20814,15456,14928,45381,16248,45382,14407, +13633,17740,45383,45384,18978,45385,45386,45387,17227,45388,45389,45390,45391, +45392,28226,45393,45394,45395,45396,45397,45398,45399,45400,17471,13858,45401, +28012,17188,45402,22065,45403,45404,45405,20320,28015,45406,45407,17742,45408, +13916,45409,45410,18977,45411,45412,28013,45413,45414,28016,28017,17212,45415, +16180,45416,28014,45417,45418,45419,45420,45421,45422,45423,45424,45425,45426, +45427,28020,28018,45428,45429,45430,45431,21862,17247,45432,28019,45433,45434, +45435,28022,45436,21795,20771,45437,45438,45440,28021,45441,17232,45442,45443, +45444,45445,45446,28023,16244,15980,28024,45447,19575,45448,20827,45449,45450, +45451,22341,21878,45452,28028,45453,45454,45455,28027,45456,45457,45458,45459, +45460,45461,45462,45463,28025,28026,45464,45465,45466,45467,45468,45469,45470, +45471,28029,15910,45472,45632,45633,45634,45635,19247,28193,13885,45636,28194, +17472,45637,28030,45638,45639,15710,12871,45640,45641,45642,45643,45644,45645, +45646,45647,45648,45649,45650,45651,13891,45652,45653,45654,28197,22586,28195, +28198,45655,45656,45657,17257,13170,45658,45659,45660,45661,45662,45663,28199, +28196,20281,45664,45665,28200,17015,45666,45667,45668,45669,45670,45671,45672, +45673,45674,45675,45676,45677,28201,28202,45678,24107,45679,45680,17971,45681, +18246,45682,22133,13641,45683,19250,45684,45685,45686,28203,45687,45688,19755, +45689,28204,45690,45691,45692,45693,45694,21808,45696,28205,45697,30276,45698, +45699,45700,45701,45702,45703,45704,45705,45706,45707,45708,45709,45710,23367, +45711,45712,45713,45714,45715,45716,45717,45718,45719,13347,45720,45721,45722, +17196,29030,45723,45724,45725,45726,45727,19000,21075,45728,22058,45888,28530, +45889,15960,45890,15683,28531,13900,12331,45891,45892,45893,45894,18991,45895, +45896,27958,45897,27959,45898,45899,45900,45901,20089,14127,16243,27960,17003, +18736,45902,45903,45904,45905,45906,45907,27961,45908,45909,18038,16179,45910, +45911,45912,27964,17784,45913,20816,45914,22313,27962,27963,45915,20834,45916, +27967,27968,45917,27972,45918,45919,45920,27976,45921,27974,27982,21864,45922, +27977,45923,45924,27975,27966,45925,45926,17769,45927,45928,45929,17990,45930, +45931,18793,21586,27969,27970,27971,27973,45932,16505,45933,13345,45934,45935, +45936,45937,14696,45938,27984,45939,45940,45941,45942,27985,45943,27978,45944, +27983,45945,20088,45946,45947,19254,27980,27981,45948,45949,45950,45952,45953, +20341,45954,45955,45956,45957,45958,45959,45960,45961,45962,45963,45964,45965, +27986,16754,21298,27979,18487,45966,45967,45968,45969,45970,45971,45972,45973, +15471,45974,45975,45976,45977,17776,45978,45979,45980,45981,45982,45983,45984, +46144,46145,46146,27990,46147,13679,46148,46149,16949,12333,19305,46150,46151, +12590,46152,27988,46153,46154,46155,19819,13666,46156,27989,27987,27991,46157, +46158,13690,46159,27992,46160,27993,46161,27996,46162,12620,46163,46164,46165, +46166,46167,46168,46169,46170,17782,15470,27994,19516,12906,46171,46172,46173, +46174,27995,46175,46176,46177,46178,17515,46179,46180,13381,46181,46182,46183, +12405,46184,46185,46186,27999,16474,13416,46187,46188,46189,46190,17741,46191, +46192,46193,27997,16196,46194,46195,46196,27998,46197,46198,46199,46200,46201, +46202,46203,46204,46205,46206,46208,46209,46210,46211,17445,46212,46213,46214, +28000,46215,46216,46217,46218,46219,28001,46220,28003,46221,46222,16727,46223, +46224,15175,46225,46226,46227,46228,46229,46230,15672,46231,46232,46233,28002, +46234,46235,46236,46237,46238,46239,46240,46400,46401,46402,46403,46404,46405, +28004,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415,28006,46416, +46417,46418,46419,46420,28005,46421,46422,46423,46424,46425,46426,46427,46428, +46429,46430,46431,46432,46433,46434,46435,28007,46436,46437,46438,46439,46440, +19006,27754,16497,46441,18791,46442,27755,18030,46443,46444,46445,46446,27756, +46447,18029,27757,46448,46449,46450,46451,46452,46453,46454,46455,46456,27760, +46457,46458,22374,27763,46459,46460,27761,27758,27759,22307,18801,19310,27764, +46461,27762,46462,46464,20329,46465,27766,17969,46466,46467,46468,46469,15424, +46470,27765,46471,46472,46473,46474,46475,46476,46477,13627,15222,46478,27767, +46479,46480,46481,46482,46483,22903,15739,46484,46485,16955,27768,46486,46487, +46488,46489,27769,46490,46491,46492,46493,14371,46494,46495,46496,46656,46657, +46658,46659,46660,46661,46662,27770,46663,46664,46665,46666,46667,46668,46669, +46670,46671,46672,46673,46674,27771,46675,46676,46677,46678,46679,46680,46681, +46682,46683,46684,46685,27772,46686,46687,46688,46689,46690,21357,22574,16491, +46691,18269,14924,46692,20579,19261,46693,19770,46694,46695,14417,46696,46697, +12668,46698,18287,46699,22102,46700,46701,46702,16198,17259,46703,46704,28533, +46705,46706,17240,46707,46708,46709,46710,46711,46712,22370,46713,46714,46715, +28535,13139,46716,18264,20845,46717,22088,46718,28536,46720,28534,46721,15229, +13126,46722,46723,46724,46725,46726,46727,46728,15701,46729,46730,21062,46731, +15200,46732,46733,20257,46734,28540,28539,46735,46736,28537,46737,46738,46739, +46740,13132,46741,18772,19248,46742,46743,46744,46745,46746,28542,46747,46748, +12382,46749,46750,22089,46751,46752,46912,28541,46913,13165,46914,46915,30293, +46916,46917,46918,46919,46920,46921,46922,46923,46924,46925,46926,46927,46928, +46929,46930,20040,46931,46932,46933,28706,46934,28705,46935,13630,15450,15228, +46936,14437,46937,46938,46939,46940,46941,46942,17474,46943,46944,46945,46946, +46947,46948,46949,46950,46951,46952,28707,46953,46954,46955,46956,46957,19307, +46958,46959,46960,46961,46962,46963,46964,46965,46966,46967,46968,46969,46970, +46971,46972,46973,46974,46976,46977,46978,46979,46980,46981,46982,28710,46983, +46984,46985,20776,46986,15935,18286,28982,28983,16213,46987,46988,46989,46990, +13353,28984,19771,46991,18260,21805,46992,28985,46993,28986,46994,46995,46996, +46997,18255,46998,46999,47000,21028,22095,47001,47002,28987,15697,13360,15933, +47003,47004,47005,13404,20049,47006,16223,28989,47007,47008,47168,47169,16250, +28988,47170,28991,47171,47172,47173,28990,28992,47174,47175,47176,47177,47178, +28993,47179,47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,16766, +47190,47191,47192,47193,47194,47195,47196,47197,47198,47199,47200,16674,47201, +47202,47203,47204,47205,47206,47207,47208,47209,47210,19066,47211,47212,21822, +47213,47214,47215,47216,15930,15929,21826,47217,47218,16162,47219,19759,28981, +47220,47221,47222,47223,47224,47225,15711,47226,13899,47227,47228,47229,47230, +47232,47233,47234,47235,47236,22129,29507,47237,47238,29508,47239,14413,47240, +47241,47242,29510,29511,47243,12362,47244,29509,47245,29513,19313,47246,47247, +47248,29515,47249,20518,47250,47251,12618,29512,47252,47253,47254,29519,47255, +13649,47256,47257,29527,47258,29522,47259,47260,47261,29524,29523,14203,47262, +12607,47263,29518,29514,13658,47264,29520,47424,47425,29521,47426,29525,47427, +47428,47429,47430,29517,47431,15459,47432,16765,47433,29526,47434,47435,47436, +47437,47438,47439,29530,47440,29516,47441,13640,47442,15726,29532,47443,47444, +14116,16240,22142,19762,47445,13424,47446,12895,47447,29528,47448,29529,18744, +47449,29533,47450,47451,29534,47452,29537,47453,47454,47455,47456,47457,47458, +47459,47460,47461,47462,47463,29535,47464,47465,29539,29538,47466,47467,29531, +47468,16234,47469,13167,47470,29536,47471,47472,18217,47473,15474,47474,47475, +47476,47477,29547,47478,47479,47480,47481,47482,47483,47484,14655,47485,47486, +29540,47488,47489,47490,12845,15230,47491,19299,47492,47493,47494,47495,29549, +29545,47496,47497,47498,14684,29550,47499,47500,47501,29541,29542,29546,16993, +29548,29551,29544,15485,47502,47503,47504,20324,47505,47506,29552,47507,47508, +47509,29543,47510,47511,47512,47513,47514,47515,47516,47517,29554,47518,47519, +47520,47680,22317,17962,47681,47682,47683,47684,29555,47685,47686,47687,47688, +29553,47689,16936,47690,47691,47692,47693,47694,14429,29557,47695,47696,29556, +47697,47698,47699,13403,47700,47701,47702,29558,29559,47703,47704,47705,29560, +47706,47707,47708,16442,47709,47710,16489,47711,47712,47713,47714,47715,17777, +47716,47717,47718,47719,29563,47720,29562,47721,47722,47723,47724,47725,47726, +47727,47728,13400,47729,47730,47731,29566,29561,47732,47733,29564,47734,47735, +47736,47737,47738,47739,29565,47740,47741,47742,47744,47745,47746,47747,47748, +29729,47749,47750,47751,47752,47753,47754,29731,15177,47755,47756,29730,47757, +47758,47759,47760,47761,47762,47763,47764,47765,47766,47767,47768,47769,29732, +47770,47771,47772,47773,47774,47775,12862,29734,29733,47776,47936,47937,47938, +47939,47940,47941,47942,47943,47944,47945,15406,47946,47947,47948,47949,47950, +47951,47952,47953,47954,47955,47956,47957,47958,47959,47960,47961,47962,47963, +47964,47965,47966,47967,47968,47969,47970,47971,47972,47973,47974,47975,47976, +47977,47978,47979,47980,47981,47982,17239,22881,47983,47984,47985,47986,47987, +47988,16480,29772,22353,47989,47990,47991,47992,47993,47994,47995,47996,47997, +47998,48000,14171,48001,48002,48003,48004,48005,48006,48007,29774,16675,48008, +48009,17993,48010,13398,21811,48011,48012,48013,29776,29775,29777,19290,48014, +48015,29778,48016,21569,22112,48017,48018,48019,48020,14176,48021,48022,48023, +16696,48024,48025,16699,29779,15916,48026,48027,48028,48029,48030,13410,48031, +48032,29780,29781,15915,48192,48193,29782,48194,48195,48196,29787,48197,29783, +29786,48198,14973,48199,29784,29785,48200,48201,48202,48203,48204,48205,48206, +14434,19527,29788,48207,12890,48208,48209,17235,48210,48211,21603,16183,48212, +48213,48214,48215,48216,48217,48218,29789,48219,48220,48221,48222,48223,48224, +17716,48225,48226,48227,48228,48229,48230,48231,48232,29801,48233,48234,20277, +48235,48236,48237,48238,48239,48240,48241,48242,48243,48244,48245,48246,48247, +48248,20041,48249,48250,48251,48252,48253,48254,48256,48257,48258,48259,48260, +48261,48262,48263,48264,48265,48266,48267,48268,48269,48270,19288,48271,19319, +48272,48273,48274,48275,15732,48276,48277,48278,22351,48279,48280,48281,16475, +48282,48283,48284,48285,48286,48287,48288,48448,48449,48450,48451,48452,48453, +48454,48455,48456,48457,48458,48459,48460,48461,48462,48463,48464,48465,48466, +48467,48468,48469,48470,48471,48472,48473,48474,48475,48476,48477,48478,48479, +48480,48481,48482,48483,48484,48485,48486,48487,48488,48489,48490,48491,48492, +48493,48494,48495,48496,48497,48498,48499,48500,48501,48502,20597,48503,48504, +48505,48506,48507,48508,48509,48510,29802,48512,48513,48514,48515,48516,48517, +48518,48519,48520,48521,48522,48523,48524,48525,48526,48527,48528,48529,48530, +48531,48532,48533,48534,48535,48536,48537,48538,48539,48540,48541,48542,48543, +48544,48704,48705,48706,48707,48708,48709,48710,48711,48712,48713,48714,48715, +48716,29803,48717,48718,48719,48720,48721,48722,48723,29804,48724,48725,48726, +48727,48728,48729,48730,48731,48732,48733,48734,48735,48736,48737,48738,48739, +48740,48741,48742,48743,48744,48745,48746,48747,48748,48749,48750,48751,48752, +48753,48754,48755,48756,48757,48758,48759,48760,48761,48762,48763,48764,48765, +48766,48768,48769,48770,48771,48772,48773,48774,48775,48776,48777,48778,48779, +48780,48781,48782,48783,48784,48785,48786,48787,48788,48789,48790,48791,48792, +48793,48794,48795,48796,48797,48798,48799,48800,48960,48961,48962,48963,48964, +48965,48966,48967,48968,48969,48970,48971,48972,48973,48974,48975,48976,48977, +48978,48979,48980,48981,48982,48983,48984,48985,48986,48987,48988,48989,48990, +48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,49001,49002,49003, +49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,49014,49015,49016, +49017,49018,49019,49020,49021,49022,49024,30563,49025,49026,49027,49028,49029, +14129,49030,49031,49032,49033,49034,29805,49035,49036,49037,49038,49039,49040, +49041,49042,49043,49044,49045,49046,49047,49048,49049,49050,49051,49052,49053, +49054,49055,49056,49216,49217,49218,49219,49220,49221,49222,49223,49224,49225, +49226,49227,49228,49229,49230,49231,49232,49233,49234,49235,49236,49237,49238, +49239,49240,49241,49242,49243,49244,49245,49246,49247,49248,49249,49250,49251, +22379,49252,49253,49254,49255,49256,49257,49258,49259,49260,49261,49262,49263, +49264,49265,49266,49267,49268,49269,49270,49271,49272,49273,49274,49275,29806, +49276,49277,49278,26233,15936,26234,14956,26235,20299,26236,21564,15414,26237, +26238,15437,18514,20019,26401,49280,13375,26402,18740,14425,17481,49281,22365, +16986,14167,22077,20038,14148,49282,49283,17702,26403,20319,26404,26405,26406, +16695,22377,18800,20280,22063,22101,26407,12397,26408,26409,18780,21103,15917, +26410,12403,18526,15713,26411,18502,49284,26412,15206,14456,20772,26413,16999, +15992,15690,19763,26414,26415,15982,20581,49285,19303,19536,15436,26416,15400, +20599,26417,49286,20600,26418,26419,13378,26420,26421,18814,20012,17248,26423, +12609,13169,49287,26424,26425,22363,21824,26426,16972,22330,26427,26428,26429, +15466,17253,16450,26430,26431,15401,49288,26432,26433,26422,13904,26434,49289, +26435,26436,15162,13662,16966,12640,26437,21557,26438,14399,26440,26439,14188, +49290,26441,12920,26442,26443,26444,26445,26446,26447,26448,21287,19317,26449, +26450,26451,26452,18761,26453,26454,26455,26456,26457,15689,26458,29502,49291, +14423,49292,18481,49293,49294,49295,49296,49297,49298,49299,29503,49300,29504, +29505,49301,49302,49303,49304,49305,49306,49307,49308,49309,49310,14686,19832, +49311,49312,22632,14897,49472,16990,28215,49473,14115,49474,49475,49476,49477, +28217,49478,28216,12373,49479,49480,49481,49482,49483,28219,21846,22383,49484, +49485,49486,22083,49487,49488,28221,19056,49489,28220,49490,49491,49492,49493, +28222,49494,49495,49496,49497,28224,49498,49499,28223,49500,49501,49502,49503, +49504,49505,49506,49507,20850,49508,18236,49509,17216,49510,49511,49512,49513, +49514,14433,49515,49516,49517,49518,49519,16743,49520,49521,29766,20575,29767, +49522,20315,49523,49524,18490,49525,49526,29768,49527,49528,49529,49530,49531, +49532,49533,29769,29770,49534,29771,49536,49537,49538,49539,49540,22906,14462, +49541,49542,25969,21360,49543,29792,49544,20044,49545,49546,49547,13153,49548, +49549,49550,49551,28980,49552,21102,49553,29793,49554,49555,49556,49557,49558, +20328,29794,49559,49560,18252,49561,49562,49563,49564,49565,49566,13652,13412, +29796,49567,49568,49728,29795,29797,49729,49730,29798,49731,49732,49733,49734, +29799,49735,14898,12351,49736,29800,49737,49738,49739,49740,49741,49742,49743, +14125,21101,49744,49745,49746,21035,16463,49747,16188,27427,21855,27208,49748, +49749,49750,49751,29043,13944,19235,49752,49753,17485,49754,29031,49755,29032, +14459,29033,14916,21573,12370,49756,49757,29034,49758,49759,49760,29035,49761, +29036,49762,49763,29037,29038,29039,29041,29040,17749,49764,49765,49766,49767, +49768,49769,29042,49770,13946,49771,29044,21038,24135,19274,49772,49773,13148, +49774,13602,49775,14626,49776,49777,17524,29045,49778,49779,29046,49780,49781, +49782,16708,16763,22064,29047,49783,49784,49785,49786,29048,49787,16682,49788, +49789,49790,17976,49792,15963,49793,49794,49795,49796,49797,49798,49799,49800, +49801,49802,49803,49804,49805,49806,29049,13391,49807,49808,49809,49810,49811, +49812,29050,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,49823, +49824,49984,27954,27953,49985,49986,19296,21086,49987,19265,21848,49988,18530, +49989,16479,15393,49990,49991,49992,49993,49994,49995,27457,49996,49997,20516, +49998,22114,49999,13895,14424,27456,14414,50000,27455,13094,14665,22059,50001, +14196,14154,50002,50003,50004,15463,14142,27462,50005,27463,12345,16207,50006, +27461,21373,50007,27464,50008,50009,27465,50010,50011,14158,50012,27458,27460, +18806,22103,21837,20530,27471,20024,27472,50013,13608,50014,50015,50016,50017, +50018,12595,27474,19493,50019,50020,50021,50022,50023,50024,50025,17750,27475, +50026,27473,17759,27470,18980,27477,12411,50027,50028,14970,50029,50030,22583, +29027,50031,27466,27467,27468,27469,27478,26176,27481,50032,16232,21064,27479, +27484,14444,27480,50033,15674,50034,20568,50035,12343,50036,27485,17500,50037, +50038,50039,50040,22060,50041,50042,50043,13408,50044,50045,17014,15417,50046, +50048,27482,27483,21600,18026,17492,27487,17703,22901,50049,12849,50050,27492, +50051,15685,50052,50053,50054,27490,50055,50056,50057,50058,50059,50060,50061, +50062,50063,50064,50065,50066,50067,27491,50068,50069,14380,50070,19793,27493, +50071,50072,50073,27489,50074,16691,50075,50076,50077,50078,50079,17954,50080, +50240,50241,50242,50243,50244,50245,19571,50246,27494,50247,16432,21048,27495, +50248,50249,50250,14383,14381,50251,27496,18235,19827,50252,50253,50254,27498, +27499,50255,50256,50257,50258,50259,27501,50260,50261,50262,50263,20552,50264, +27506,50265,27502,50266,50267,50268,27505,18553,50269,20860,27500,50270,50271, +27497,50272,50273,50274,50275,14393,20313,17509,27503,27504,19546,19784,12402, +50276,27510,50277,50278,50279,50280,50281,27509,50282,12850,50283,50284,50285, +50286,14432,50287,27511,50288,50289,50290,50291,50292,50293,12652,50294,50295, +19525,17444,20261,50296,50297,50298,50299,50300,27513,50301,50302,27682,50304, +17778,50305,27514,50306,50307,50308,50309,50310,50311,50312,50313,18757,50314, +50315,50316,50317,50318,50319,25183,27518,50320,50321,50322,50323,19790,27681, +12635,21303,50324,50325,21084,50326,50327,50328,27517,50329,27515,50330,50331, +50332,50333,50334,50335,50336,50496,50497,50498,50499,50500,50501,50502,50503, +50504,50505,50506,50507,50508,50509,50510,13116,50511,50512,50513,27184,50514, +50515,22356,50516,29739,13172,50517,50518,50519,50520,50521,22081,22082,50522, +50523,50524,50525,50526,50527,21865,15946,50528,29735,50529,21032,29736,29737, +50530,29738,15947,21343,50531,50532,50533,50534,50535,18784,18785,50536,50537, +29506,50538,19046,50539,19570,50540,50541,50542,50543,50544,50545,25142,19252, +50546,20072,22107,50547,29741,29742,29743,50548,50549,50550,50551,29746,50552, +14909,29747,12387,29744,50553,29745,15650,12885,50554,29750,29751,13926,12848, +20303,29748,13356,50555,29749,50556,50557,29752,50558,50560,50561,50562,50563, +29753,50564,50565,19751,50566,29754,50567,29755,50568,50569,50570,29756,50571, +50572,50573,50574,50575,50576,50577,50578,19282,50579,29757,50580,50581,50582, +50583,29758,50584,50585,50586,50587,50588,50589,50590,50591,29759,50592,50752, +50753,50754,50755,29790,16700,15464,50756,18731,20830,25973,50757,50758,50759, +50760,23603,21077,50761,50762,23604,12332,23605,50763,50764,15706,50765,23609, +50766,50767,50768,22594,50769,23607,21363,50770,18774,23610,23606,50771,23611, +17186,50772,50773,50774,50775,23612,23621,23613,50776,50777,20063,22053,50778, +23631,50779,23629,50780,50781,23634,15718,16939,50782,23608,23627,23630,23614, +14162,12357,23623,20542,23617,15144,50783,14140,23628,50784,50785,23622,23615, +18267,50786,50787,50788,20799,23616,50789,50790,23626,50791,50792,23632,50793, +50794,20013,23618,50795,23619,23624,23625,12884,23633,19285,50796,21559,23643, +23647,19494,23654,50797,17255,23644,50798,50799,16193,23641,50800,12410,14646, +23653,23635,50801,23620,23638,18548,16224,50802,50803,50804,50805,18747,50806, +50807,50808,12605,50809,21282,50810,50811,23642,50812,50813,23637,50814,17979, +50816,23646,50817,50818,50819,50820,50821,22338,17199,14134,18257,17193,23650, +23640,23659,23636,50822,50823,23645,50824,15909,23639,50825,23648,50826,50827, +23651,23652,50828,23672,50829,50830,23649,23842,23655,50831,50832,50833,50834, +50835,50836,50837,50838,50839,50840,15467,13380,50841,50842,17187,12903,23674, +50843,23666,50844,23663,50845,23676,23662,21104,12904,50846,18519,18531,23675, +50847,23661,50848,51008,51009,23671,51010,51011,23669,51012,51013,15907,23668, +51014,12893,51015,51016,51017,51018,51019,23667,15478,23656,15172,51020,16499, +51021,51022,51023,51024,51025,15444,23657,23658,51026,23665,23670,23673,13620, +51027,18521,15207,23678,23677,21291,23841,23843,23845,21105,23844,23846,23847, +21033,51028,51029,51030,51031,51032,51033,51034,14921,23849,51035,51036,23862, +23857,23860,51037,51038,51039,51040,51041,51042,51043,23856,17998,51044,51045, +16498,51046,51047,51048,51049,18735,51050,51051,51052,23660,23854,51053,51054, +51055,51056,23863,51057,51058,23664,23855,51059,23864,51060,23852,51061,51062, +51063,51064,51065,51066,51067,23865,23859,23853,17450,51068,51069,51070,51072, +23848,16435,16683,23850,23851,51073,23858,15217,23861,21288,23866,51074,23867, +17191,51075,51076,23890,23868,51077,51078,51079,23889,51080,14653,51081,51082, +15957,51083,15994,51084,51085,14922,51086,51087,51088,51089,23882,51090,23877, +51091,23871,51092,51093,51094,12875,23875,51095,23883,12836,23893,51096,51097, +51098,23870,51099,51100,51101,18000,23888,51102,51103,51104,51264,51265,23892, +16738,14150,51266,51267,51268,51269,51270,23886,23887,51271,51272,51273,23876, +51274,51275,51276,23869,51277,23885,19537,51278,23881,51279,51280,51281,51282, +23874,17224,17980,20014,23884,51283,23880,51284,51285,51286,51287,51288,51289, +23873,51290,51291,51292,23878,16988,51293,51294,51295,51296,51297,51298,21289, +21290,23891,20340,18552,51299,51300,51301,51302,51303,51304,51305,51306,23910, +51307,51308,51309,51310,51311,51312,23879,51313,51314,51315,23904,16996,51316, +51317,51318,51319,51320,51321,51322,51323,23905,51324,51325,51326,51328,51329, +51330,51331,51332,51333,51334,23895,51335,51336,51337,51338,51339,22136,51340, +23897,23896,14448,23894,51341,51342,51343,51344,17999,51345,13869,51346,51347, +51348,51349,51350,23906,51351,14969,21601,23911,51352,51353,51354,13392,51355, +23898,51356,16251,23907,51357,23903,51358,23901,51359,51360,51520,51521,51522, +51523,51524,13657,51525,51526,51527,51528,23899,23900,23902,51529,15663,23908, +51530,23909,51531,51532,51533,51534,51535,51536,51537,51538,23925,51539,17225, +51540,51541,19298,51542,51543,51544,51545,23922,51546,51547,51548,51549,51550, +51551,51552,51553,51554,51555,51556,51557,51558,22625,51559,51560,18001,51561, +23924,51562,51563,51564,21876,23923,23920,51565,51566,23916,51567,23919,51568, +23912,51569,51570,20590,51571,51572,51573,51574,18520,23918,51575,51576,23913, +51577,51578,23914,19314,51579,23917,51580,51581,12621,51582,51584,51585,51586, +51587,51588,16438,51589,15419,23921,51590,51591,23927,51592,23926,23915,51593, +51594,51595,51596,51597,17774,51598,51599,51600,23931,51601,51602,51603,51604, +51605,51606,51607,51608,51609,51610,51611,24100,51612,51613,24099,51614,51615, +51616,51776,51777,51778,51779,51780,51781,51782,51783,51784,23928,51785,51786, +51787,51788,17263,51789,17019,51790,51791,51792,21857,51793,51794,20021,51795, +51796,51797,51798,23933,51799,12876,51800,51801,51802,51803,51804,51805,51806, +51807,51808,17512,19039,51809,51810,51811,51812,51813,51814,51815,51816,51817, +51818,18238,23930,23932,23934,24098,12330,12622,51819,51820,51821,51822,51823, +24108,51824,51825,51826,51827,24102,15670,18543,51828,51829,51830,51831,51832, +51833,51834,51835,51836,51837,51838,24097,51840,51841,24101,51842,51843,51844, +51845,24105,51846,51847,51848,51849,51850,24104,51851,51852,51853,24103,51854, +51855,51856,51857,51858,51859,51860,51861,51862,24109,51863,21580,51864,51865, +51866,51867,24115,24106,24110,51868,51869,16473,51870,51871,51872,52032,52033, +12577,24118,52034,24113,52035,52036,52037,52038,52039,52040,52041,24114,52042, +52043,52044,52045,52046,52047,52048,52049,52050,52051,52052,20774,24117,52053, +52054,52055,52056,52057,52058,52059,24111,52060,52061,52062,24112,52063,20541, +52064,52065,52066,24116,19053,24121,52067,52068,52069,52070,52071,52072,24120, +52073,24119,52074,52075,52076,52077,52078,52079,52080,24123,52081,52082,52083, +52084,52085,52086,52087,15717,52088,52089,52090,52091,52092,12888,17258,52093, +52094,24122,52096,17722,52097,52098,52099,52100,52101,52102,24124,52103,52104, +52105,52106,52107,52108,52109,19545,52110,52111,52112,52113,14122,52114,52115, +52116,52117,52118,52119,52120,52121,52122,52123,52124,52125,52126,52127,52128, +52288,52289,21605,52290,52291,52292,24125,52293,52294,52295,52296,52297,24127, +52298,52299,52300,52301,52302,52303,52304,52305,52306,52307,52308,17442,52309, +52310,52311,52312,24129,52313,52314,52315,52316,52317,52318,52319,52320,52321, +52322,52323,52324,52325,52326,52327,52328,24126,52329,24128,52330,52331,52332, +52333,52334,52335,52336,52337,52338,52339,52340,52341,52342,52343,21818,52344, +52345,52346,24130,52347,52348,52349,52350,52352,52353,52354,52355,52356,52357, +52358,52359,52360,52361,52362,52363,29230,15138,16946,17712,16967,52364,52365, +29231,52366,52367,52368,52369,52370,20585,52371,52372,52373,21341,52374,52375, +52376,27453,52377,52378,52379,52380,52381,52382,52383,52384,13158,29232,52544, +29233,52545,52546,18989,52547,52548,52549,52550,52551,52552,52553,14951,29235, +29237,29236,19300,20282,29234,18996,21071,17004,52554,52555,52556,52557,52558, +52559,52560,20035,29240,12406,29239,52561,52562,52563,52564,52565,29246,52566, +12879,52567,52568,52569,52570,52571,52572,20801,29242,52573,52574,52575,52576, +52577,29244,21609,52578,52579,29243,29238,29247,29245,52580,29241,52581,52582, +29255,29252,29254,52583,52584,29258,29250,29248,52585,52586,52587,29253,52588, +52589,52590,52591,52592,22139,52593,52594,52595,29249,52596,18297,18783,52597, +29256,14662,13616,52598,52599,29251,29257,29264,29270,52600,52601,15191,52602, +52603,52604,29269,19804,52605,22123,52606,52608,29266,29268,52609,52610,52611, +52612,14450,52613,52614,52615,52616,29259,52617,52618,52619,29262,17017,52620, +21853,29260,29261,29263,29267,52621,52622,52623,29273,21308,52624,52625,52626, +52627,13930,52628,19057,52629,14180,29271,52630,52631,52632,29272,29274,29277, +29275,52633,52634,29276,52635,52636,52637,52638,20817,29265,52639,19785,52640, +20047,22057,52800,29283,52801,17243,52802,29280,52803,52804,16431,29292,29278, +52805,29281,52806,52807,52808,29288,52809,52810,52811,52812,29282,52813,52814, +29287,52815,52816,29286,52817,52818,29289,52819,52820,52821,29279,52822,52823, +29284,29290,52824,52825,52826,52827,52828,52829,52830,21292,29285,12917,52831, +52832,29298,52833,20523,52834,52835,52836,52837,29301,52838,52839,52840,15176, +52841,29305,52842,52843,52844,52845,52846,52847,29296,52848,52849,29302,29304, +29306,52850,52851,52852,52853,52854,52855,52856,52857,29299,52858,29297,52859, +52860,52861,14971,52862,13691,52864,52865,52866,52867,29295,29303,29293,29294, +52868,52869,52870,29291,29478,52871,29475,52872,52873,29474,52874,52875,29300, +52876,18522,52877,52878,52879,52880,52881,29307,52882,52883,52884,29477,52885, +52886,52887,52888,52889,52890,52891,17272,52892,52893,52894,52895,52896,53056, +53057,53058,29309,53059,53060,29479,29481,29476,53061,29308,53062,53063,53064, +29483,53065,29482,53066,53067,53068,53069,16989,53070,53071,29486,53072,53073, +29488,53074,53075,53076,53077,53078,29473,53079,53080,53081,29489,29484,53082, +53083,53084,53085,53086,29487,29310,29485,53087,53088,53089,53090,53091,53092, +53093,29490,53094,53095,53096,53097,29492,53098,53099,53100,53101,29480,53102, +53103,53104,53105,29491,53106,53107,53108,29493,53109,53110,53111,53112,53113, +53114,53115,53116,53117,53118,20535,53120,53121,53122,53123,29496,53124,53125, +53126,53127,22905,53128,53129,53130,53131,53132,53133,29497,53134,53135,53136, +53137,53138,53139,53140,53141,29495,53142,18532,29494,53143,53144,53145,53146, +29498,53147,53148,53149,53150,53151,29499,13376,53152,53312,53313,53314,53315, +53316,53317,53318,53319,53320,53321,53322,53323,53324,53325,28227,53326,53327, +53328,53329,53330,53331,29500,53332,53333,29501,53334,53335,53336,20778,53337, +53338,53339,29740,20550,53340,53341,53342,53343,53344,53345,20560,20828,53346, +53347,53348,53349,53350,53351,20302,53352,53353,15702,53354,20803,53355,53356, +53357,53358,53359,53360,53361,14946,24937,21058,28994,12857,53362,53363,12653, +28995,53364,18752,13124,53365,22898,53366,19237,53367,28996,53368,53369,53370, +53371,22100,53372,53373,53374,53376,53377,28997,29760,28998,53378,21548,28999, +53379,12352,29761,53380,53381,29762,53382,53383,13436,53384,17755,53385,53386, +53387,53388,19515,53389,53390,53391,20580,53392,53393,53394,53395,53396,19808, +53397,53398,53399,53400,53401,29000,53402,22899,53403,53404,53405,53406,53407, +53408,12603,53568,20270,53569,53570,53571,14372,53572,53573,53574,53575,53576, +29002,53577,53578,53579,53580,29003,53581,53582,53583,53584,12867,16721,53585, +53586,22320,29001,53587,53588,29004,53589,53590,53591,53592,29006,53593,53594, +53595,22902,53596,21089,21539,53597,53598,29763,18489,53599,53600,53601,53602, +53603,29764,53604,53605,29005,29007,16227,29008,53606,53607,29012,53608,53609, +53610,53611,53612,53613,53614,29014,29009,53615,18769,17761,53616,53617,53618, +16995,14716,53619,53620,29011,53621,29013,53622,53623,53624,14675,53625,53626, +53627,53628,53629,53630,53632,29019,53633,53634,53635,53636,53637,14934,53638, +12413,29017,53639,53640,53641,53642,53643,29016,29010,29018,53644,53645,53646, +53647,53648,29015,53649,53650,53651,18540,53652,53653,53654,53655,19786,29021, +53656,53657,53658,53659,25917,53660,53661,53662,29020,53663,29022,53664,53824, +53825,53826,53827,53828,53829,53830,53831,53832,29023,53833,53834,20325,53835, +53836,53837,53838,53839,53840,53841,53842,53843,53844,53845,53846,53847,53848, +53849,53850,53851,53852,53853,53854,53855,53856,53857,53858,53859,29765,15731, +53860,53861,53862,53863,53864,53865,29024,53866,53867,53868,53869,53870,53871, +53872,53873,53874,53875,53876,53877,53878,53879,53880,53881,53882,53883,53884, +53885,29025,53886,53888,53889,20087,53890,21034,53891,29051,53892,53893,14386, +53894,53895,53896,53897,53898,53899,53900,53901,53902,53903,53904,53905,53906, +53907,53908,53909,53910,53911,53912,53913,53914,53915,53916,53917,53918,53919, +53920,54080,54081,54082,54083,54084,54085,54086,54087,54088,54089,54090,54091, +54092,54093,54094,54095,54096,54097,54098,54099,54100,54101,54102,54103,54104, +54105,54106,54107,54108,54109,54110,15483,14683,54111,14694,17241,19027,27240, +16448,15989,27241,27242,27243,54112,27244,27245,27246,27247,15687,54113,54114, +54115,30075,54116,54117,54118,30077,54119,30078,54120,30076,54121,54122,54123, +54124,15714,54125,30241,13349,54126,54127,54128,54129,30242,54130,54131,54132, +30243,54133,54134,54135,27698,54136,54137,54138,54139,54140,54141,54142,54144, +54145,54146,54147,54148,20820,54149,54150,54151,54152,54153,54154,22890,54155, +54156,54157,54158,54159,54160,54161,54162,54163,54164,54165,54166,54167,54168, +54169,54170,54171,54172,54173,54174,54175,54176,54336,54337,54338,54339,54340, +54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,54352,54353, +54354,54355,54356,54357,54358,54359,54360,54361,54362,54363,54364,54365,54366, +54367,30244,54368,54369,54370,54371,54372,54373,54374,54375,54376,28218,54377, +54378,54379,54380,54381,54382,54383,54384,54385,54386,54387,54388,54389,54390, +54391,54392,54393,54394,54395,54396,54397,54398,54400,54401,54402,54403,54404, +54405,54406,54407,54408,54409,54410,54411,54412,54413,54414,54415,54416,54417, +54418,54419,54420,54421,54422,54423,54424,54425,21810,54426,54427,54428,54429, +54430,54431,54432,54592,54593,54594,54595,54596,54597,54598,54599,21374,19548, +54600,54601,54602,54603,54604,54605,54606,54607,19012,54608,54609,54610,54611, +54612,54613,54614,54615,54616,54617,54618,54619,54620,54621,54622,54623,54624, +54625,54626,54627,54628,54629,54630,54631,54632,54633,54634,54635,54636,54637, +54638,54639,54640,54641,54642,54643,54644,54645,54646,54647,54648,54649,54650, +54651,54652,54653,54654,54656,54657,54658,54659,54660,54661,54662,54663,54664, +54665,54666,54667,54668,54669,54670,54671,54672,54673,54674,54675,54676,54677, +54678,54679,54680,54681,54682,54683,54684,54685,54686,54687,54688,54848,54849, +54850,54851,54852,54853,54854,54855,54856,54857,54858,54859,54860,54861,54862, +54863,54864,54865,54866,54867,54868,54869,54870,54871,54872,54873,54874,54875, +54876,54877,54878,54879,54880,54881,54882,25920,54883,54884,54885,54886,54887, +54888,54889,54890,54891,54892,54893,54894,54895,54896,54897,54898,54899,54900, +54901,54902,54903,54904,54905,54906,54907,54908,54909,54910,54912,54913,30245, +54914,54915,54916,54917,54918,54919,54920,54921,54922,54923,54924,54925,54926, +54927,54928,54929,54930,54931,54932,54933,54934,54935,54936,54937,54938,54939, +54940,54941,54942,54943,54944,55104,55105,55106,55107,55108,55109,55110,55111, +55112,55113,55114,55115,55116,55117,55118,55119,55120,55121,55122,55123,55124, +55125,55126,55127,55128,55129,55130,55131,55132,55133,55134,55135,15919,55136, +55137,55138,55139,55140,17961,55141,55142,55143,55144,55145,55146,55147,55148, +55149,55150,55151,55152,55153,55154,55155,55156,55157,55158,55159,55160,55161, +55162,55163,55164,55165,55166,55168,55169,55170,55171,55172,55173,55174,55175, +55176,55177,55178,55179,55180,55181,55182,55183,55184,55185,55186,55187,55188, +55189,55190,55191,55192,23077,15430,13865,14396,18511,15397,23078,23079,19542, +18499,23080,18045,55193,20789,21097,20790,15431,55194,15666,15204,23081,23082, +20808,23083,20589,13935,16987,55195,19279,14189,18792,14147,15991,22052,23084, +23085,17984,22375,18998,55196,21801,19295,21871,23086,22111,13386,23088,23087, +55197,21099,23089,23090,23091,19028,23092,18987,23093,23094,13135,22127,23095, +15152,13614,23096,23097,14702,20783,21096,23098,14403,20330,12911,23099,23100, +55198,15723,20060,21359,23101,20083,23102,21333,15205,23103,19253,19280,23104, +18283,22126,23105,17717,13889,23106,14156,16206,23107,23108,19245,23109,13687, +23110,16706,22331,23111,19512,55199,21098,17457,23112,13693,15185,23113,20531, +23114,23115,20029,23116,23117,23118,12919,23121,23119,20840,23120,17237,23122, +55200,23123,23124,23125,20539,21029,12409,23126,18219,23127,15735,17185,23128, +23129,17277,19511,23130,23131,16446,18007,23132,23133,18228,23134,23135,14664, +55360,55361,55362,55363,55364,55365,55366,55367,55368,15213,55369,55370,55371, +55372,13881,29816,55373,29817,55374,55375,19811,55376,55377,55378,55379,55380, +55381,55382,55383,30009,55384,55385,55386,55387,27488,55388,55389,55390,55391, +55392,55393,20339,15167,55394,55395,55396,55397,55398,55399,55400,14912,21541, +55401,55402,55403,55404,55405,55406,55407,24921,55408,55409,55410,55411,30068, +12586,12914,55412,55413,55414,55415,55416,55417,55418,30069,55419,55420,30071, +55421,55422,55424,14929,30070,55425,17202,55426,55427,55428,55429,55430,55431, +55432,30073,55433,55434,55435,30072,55436,55437,55438,55439,55440,55441,55442, +55443,55444,55445,55446,55447,55448,55449,55450,55451,55452,55453,55454,55455, +55456,55616,55617,55618,55619,55620,55621,55622,55623,55624,55625,55626,55627, +55628,55629,55630,55631,55632,55633,55634,55635,55636,55637,55638,55639,55640, +55641,55642,55643,55644,55645,55646,55647,55648,55649,55650,55651,55652,55653, +55654,55655,55656,55657,55658,55659,55660,55661,55662,55663,55664,55665,55666, +55667,55668,55669,55670,55671,55672,55673,55674,55675,55676,55677,55678,55680, +55681,55682,55683,55684,55685,55686,55687,55688,55689,55690,55691,55692,55693, +55694,55695,55696,55697,55698,55699,55700,55701,55702,55703,55704,55705,55706, +55707,55708,55709,55710,55711,55712,55872,55873,55874,55875,55876,55877,55878, +55879,55880,55881,55882,55883,55884,55885,55886,12596,21866,14394,55887,14641, +12870,21616,20301,12380,21835,15221,22090,14135,19504,17974,12641,14650,22140, +14689,14113,15482,27226,27227,19577,14707,27228,13435,17203,14161,14936,27229, +21620,27230,15446,15199,27231,16734,16952,21599,22346,27232,27233,27236,27234, +27235,18782,14387,13892,27237,19050,18765,13389,55888,55889,25177,17762,27238, +16437,55890,22328,27239,22316,18556,22611,22605,21598,55891,21625,18756,21294, +14419,13152,55892,18786,29814,55893,55894,55895,14933,55896,29815,55897,55898, +22367,55899,55900,29809,14384,21844,14415,18032,55901,55902,55903,55904,55905, +55906,55907,55908,55909,13123,55910,55911,29810,13100,55912,55913,55914,55915, +21565,18295,55916,55917,55918,55919,55920,29812,55921,55922,29811,55923,55924, +55925,55926,55927,55928,55929,55930,55931,55932,19531,55933,55934,55936,18468, +55937,55938,55939,55940,55941,55942,55943,55944,55945,55946,55947,55948,55949, +29813,55950,22371,17727,30016,55951,55952,30011,55953,30019,55954,30018,55955, +22074,30017,55956,55957,55958,21566,30020,55959,30028,55960,55961,55962,55963, +12367,13688,55964,30025,30026,55965,17756,55966,55967,55968,56128,30021,30022, +56129,56130,30023,30027,56131,15968,30024,14458,56132,56133,56134,30032,30035, +56135,56136,56137,16231,56138,14706,30012,30029,56139,56140,16951,56141,56142, +56143,19576,56144,15481,56145,30030,30031,30033,13925,30034,56146,30037,56147, +56148,56149,56150,56151,56152,56153,30013,56154,56155,56156,30036,21307,56157, +13164,56158,56159,19492,56160,56161,56162,56163,30038,56164,56165,56166,56167, +56168,56169,56170,56171,30039,15969,30040,56172,56173,19551,30043,56174,56175, +56176,56177,56178,12872,22361,56179,30041,56180,30042,30044,56181,30050,56182, +56183,56184,30048,56185,56186,56187,30047,30045,56188,56189,30049,56190,56192, +30046,30052,30053,56193,19555,56194,56195,25919,13624,30051,30056,19491,56196, +56197,56198,56199,56200,30054,30055,56201,56202,56203,56204,56205,56206,30014, +56207,56208,56209,56210,56211,56212,56213,56214,56215,56216,56217,56218,12612, +56219,56220,30015,56221,56222,13637,12900,56223,30060,30057,56224,13911,56384, +30061,56385,30058,56386,56387,56388,56389,56390,30059,56391,56392,13402,56393, +21610,56394,56395,56396,30062,56397,13177,56398,56399,56400,56401,56402,56403, +56404,30063,30065,56405,56406,56407,30064,56408,56409,56410,56411,56412,56413, +56414,30066,56415,30067,56416,56417,56418,56419,56420,56421,56422,56423,56424, +56425,56426,56427,18797,14634,56428,56429,18299,56430,56431,13923,56432,56433, +56434,56435,56436,56437,56438,19529,56439,56440,56441,56442,56443,56444,56445, +56446,56448,56449,56450,56451,56452,56453,56454,56455,56456,56457,56458,27174, +56459,56460,56461,56462,56463,56464,56465,56466,56467,56468,56469,56470,56471, +56472,56473,56474,56475,56476,56477,56478,56479,56480,56640,56641,56642,56643, +56644,56645,56646,56647,56648,56649,56650,56651,56652,56653,56654,56655,56656, +56657,56658,56659,56660,56661,56662,56663,56664,56665,56666,56667,56668,56669, +56670,56671,56672,56673,56674,56675,56676,56677,56678,56679,56680,56681,56682, +56683,56684,56685,56686,56687,56688,56689,56690,56691,56692,56693,56694,56695, +56696,56697,56698,56699,56700,56701,56702,56704,56705,56706,56707,56708,56709, +56710,56711,56712,56713,56714,56715,56716,56717,56718,56719,56720,56721,56722, +56723,56724,56725,56726,56727,56728,56729,56730,56731,56732,56733,56734,56735, +56736,56896,56897,56898,56899,56900,56901,56902,56903,56904,56905,56906,56907, +56908,56909,56910,56911,56912,56913,56914,56915,56916,56917,56918,56919,56920, +56921,56922,56923,56924,56925,56926,56927,56928,13109,21630,14700,20601,56929, +26989,22314,26990,16982,18541,14948,26991,26992,26993,22113,26994,26995,26997, +26996,26998,26999,18273,27000,21592,27001,15694,56930,27002,27003,15695,27004, +14376,16702,27005,12594,15188,14709,27006,56931,27169,27170,27171,14200,15405, +56932,19044,24654,21551,20285,21815,27172,21854,27173,20545,14652,56933,13383, +12633,56934,56935,56936,16433,56937,56938,56939,56940,12646,12647,56941,12648, +56942,56943,56944,56945,13117,18536,56946,56947,56948,56949,25921,56950,56951, +12639,56952,56953,56954,16713,13423,56955,56956,18216,21336,56957,18041,20792, +56958,14717,17013,56960,56961,56962,56963,56964,21293,56965,21579,15740,56966, +25922,14133,25923,56967,56968,15161,21858,56969,15736,21558,20005,16684,13145, +56970,56971,19574,56972,25926,25924,25928,56973,25930,25927,13647,17992,56974, +13692,25925,56975,19062,56976,56977,25929,56978,56979,56980,17236,12613,15395, +56981,56982,56983,22327,56984,56985,19787,19277,19018,19539,25932,25931,17510, +56986,56987,20769,20791,25933,56988,25936,56989,19768,22128,25935,13661,56990, +19774,56991,25937,13882,56992,57152,19752,14692,57153,19013,13137,19289,21612, +25938,14186,57154,57155,57156,25934,57157,57158,57159,57160,57161,57162,25941, +13438,25942,57163,57164,57165,57166,57167,25939,25940,57168,21085,57169,57170, +16991,12614,57171,21346,57172,57173,13917,19308,57174,25943,57175,57176,21366, +57177,57178,57179,57180,57181,12649,57182,13940,25946,25944,25945,13632,57183, +57184,57185,21061,25948,57186,57187,25950,57188,57189,57190,57191,57192,57193, +25949,18226,57194,21027,57195,57196,25947,57197,57198,57199,57200,21602,21850, +57201,57202,57203,57204,57205,25952,22385,57206,57207,57208,57209,57210,57211, +57212,25953,57213,12636,20859,57214,25954,25956,57216,57217,57218,57219,25955, +57220,57221,25957,57222,57223,57224,57225,57226,21080,57227,13643,57228,26463, +57229,23157,57230,23160,57231,23158,57232,23159,57233,57234,57235,23162,20559, +17479,57236,57237,12398,57238,57239,57240,20528,57241,23161,57242,21322,14890, +23330,18289,57243,23164,23163,18779,23165,57244,23329,22366,23166,16730,57245, +57246,23333,57247,57248,21364,57408,57409,23335,23332,57410,23336,57411,57412, +15676,57413,57414,57415,16457,23331,23334,22051,57416,23337,57417,57418,57419, +23341,57420,57421,57422,23342,23340,14914,57423,57424,57425,16164,23339,57426, +57427,57428,23338,21575,12863,57429,57430,23343,57431,14713,57432,23344,57433, +57434,57435,57436,13115,57437,57438,57439,13606,57440,57441,57442,57443,13884, +23345,57444,57445,57446,13941,57447,23346,57448,57449,57450,57451,57452,57453, +57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,57466, +57467,12617,57468,57469,57470,57472,23348,57473,57474,57475,23347,23349,57476, +57477,57478,57479,57480,57481,57482,57483,57484,57485,57486,23351,57487,23350, +57488,57489,57490,57491,57492,57493,57494,23352,57495,57496,57497,57498,57499, +57500,57501,57502,57503,23353,57504,57664,23354,57665,57666,21327,29818,18293, +22339,17764,29820,29821,29819,57667,15942,57668,57669,57670,57671,20591,57672, +57673,14163,57674,57675,21581,19498,57676,57677,29986,29985,14888,29822,19286, +57678,57679,57680,29988,16466,57681,13162,57682,19754,29989,29987,15668,29992, +57683,29993,15693,17208,16225,19297,29994,57684,57685,57686,29990,29991,17520, +57687,57688,57689,57690,57691,29996,57692,13372,57693,22381,57694,13399,29995, +29998,57695,57696,29997,29999,20561,57697,57698,57699,57700,57701,57702,57703, +17233,18473,57704,57705,57706,57707,57708,57709,30000,30001,57710,57711,57712, +57713,57714,57715,30002,57716,57717,30003,30004,30005,57718,57719,57720,57721, +30007,30006,57722,57723,57724,57725,30008,57726,57728,57729,57730,57731,57732, +57733,57734,57735,57736,57737,57738,12873,57739,21332,19021,57740,16495,22104, +21040,16703,57741,15728,57742,57743,57744,57745,57746,57747,57748,57749,57750, +57751,14378,57752,57753,57754,57755,57756,57757,57758,57759,57760,57920,57921, +57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934, +57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947, +57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960, +57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973, +57974,57975,57976,57977,57978,57979,57980,57981,57982,57984,57985,57986,57987, +57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998,57999,58000, +58001,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011,58012,58013, +58014,58015,58016,58176,58177,58178,58179,58180,58181,58182,58183,58184,58185, +58186,58187,58188,58189,58190,58191,58192,58193,58194,58195,58196,58197,58198, +58199,58200,58201,58202,58203,58204,58205,58206,58207,58208,58209,58210,58211, +58212,58213,58214,58215,58216,58217,58218,58219,58220,58221,15480,58222,58223, +58224,58225,58226,58227,58228,58229,58230,58231,58232,58233,58234,58235,58236, +58237,58238,58240,58241,58242,58243,58244,58245,58246,58247,30278,58248,58249, +58250,58251,58252,58253,58254,58255,58256,58257,58258,58259,58260,58261,58262, +58263,58264,58265,58266,58267,58268,58269,58270,58271,58272,58432,58433,58434, +58435,58436,58437,30279,58438,58439,58440,58441,58442,58443,58444,58445,58446, +58447,58448,58449,58450,58451,58452,58453,58454,58455,58456,58457,58458,58459, +58460,58461,58462,30280,58463,58464,58465,58466,58467,58468,58469,58470,58471, +58472,58473,58474,58475,58476,58477,58478,58479,58480,58481,58482,58483,58484, +58485,58486,58487,58488,58489,58490,58491,58492,58493,58494,58496,58497,58498, +58499,58500,58501,58502,58503,58504,58505,58506,58507,58508,58509,58510,58511, +58512,58513,58514,58515,58516,58517,58518,58519,58520,58521,58522,58523,58524, +58525,58526,58527,58528,58688,58689,58690,58691,58692,58693,58694,58695,58696, +58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707,58708,58709, +58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720,58721,58722, +58723,58724,58725,58726,58727,58728,58729,58730,58731,58732,58733,58734,58735, +58736,58737,58738,58739,30281,58740,58741,58742,58743,58744,58745,58746,58747, +58748,58749,58750,58752,58753,58754,58755,58756,58757,58758,58759,58760,58761, +58762,58763,58764,58765,58766,58767,58768,58769,58770,58771,58772,58773,58774, +58775,58776,58777,58778,58779,58780,58781,58782,58783,30282,58784,58944,58945, +58946,58947,58948,58949,58950,58951,58952,58953,58954,58955,58956,58957,58958, +58959,58960,58961,58962,58963,58964,58965,58966,58967,58968,58969,58970,58971, +58972,58973,58974,58975,58976,58977,58978,30284,58979,58980,58981,58982,58983, +58984,58985,58986,58987,58988,58989,58990,58991,58992,58993,58994,58995,58996, +58997,58998,58999,59000,59001,59002,59003,59004,59005,59006,59008,59009,59010, +59011,59012,59013,59014,59015,59016,59017,59018,59019,59020,59021,59022,59023, +59024,59025,59026,59027,59028,59029,59030,59031,59032,59033,59034,59035,59036, +59037,30283,59038,59039,59040,59200,59201,59202,59203,59204,59205,59206,59207, +30569,59208,59209,59210,59211,59212,59213,59214,59215,59216,59217,59218,59219, +59220,59221,59222,59223,59224,59225,59226,59227,59228,59229,59230,59231,59232, +59233,59234,59235,59236,59237,59238,59239,59240,59241,59242,59243,59244,59245, +59246,59247,59248,59249,59250,59251,59252,59253,59254,59255,59256,59257,59258, +59259,59260,59261,59262,59264,59265,59266,59267,59268,59269,59270,59271,59272, +59273,59274,59275,59276,59277,59278,59279,59280,59281,59282,59283,59284,59285, +59286,59287,59288,59289,59290,59291,59292,59293,59294,59295,59296,59456,59457, +59458,59459,59460,59461,59462,59463,59464,59465,59466,59467,59468,59469,59470, +30285,59471,59472,59473,59474,59475,59476,59477,59478,59479,59480,59481,59482, +59483,59484,59485,59486,59487,59488,59489,59490,59491,59492,59493,59494,59495, +59496,59497,59498,59499,59500,59501,59502,59503,59504,59505,59506,59507,59508, +59509,59510,59511,59512,59513,59514,30286,59515,59516,59517,59518,59520,59521, +59522,59523,59524,59525,59526,59527,59528,59529,59530,59531,59532,59533,59534, +59535,59536,59537,59538,59539,59540,28228,28229,28230,21867,13860,28232,28231, +28233,28234,18213,28235,28236,59541,14128,13686,28237,28239,59542,28238,59543, +14406,28240,28241,28242,13915,13102,22099,17478,12597,14422,28243,28244,21567, +18261,15995,20057,14643,28246,28245,28248,28247,17701,28249,28250,18222,28251, +18223,28252,12839,28253,28254,28255,28256,28257,22378,28258,28259,15448,28260, +21323,19578,12844,16741,28261,18214,17197,59544,28262,28263,28264,28265,28266, +28267,28268,59545,28269,28270,28271,59546,59547,28272,28273,28274,28276,28275, +59548,28277,19757,16961,28278,28279,28280,21793,28281,20275,28282,28283,59549, +28284,28285,28449,28286,28450,14453,17274,28451,28452,15682,21055,12921,28453, +28454,28455,21112,28456,22141,28457,17996,59550,28458,28459,16692,28460,20346, +19320,28462,28461,13178,14712,28463,28464,20578,28465,28466,14182,20543,28467, +28468,28469,18545,19552,28470,28471,28472,28473,28474,21856,28475,13421,17194, +28476,59551,28477,28478,28479,59552,20093,28480,16992,13368,22326,15733,59712, +20295,28483,28481,28482,28484,13863,15484,15970,17228,28485,28486,59713,28487, +28495,28488,28489,28490,18242,28529,13901,28491,59714,28492,28493,13894,17214, +28494,59715,28496,28497,28498,21874,59716,28499,17527,59717,28500,17528,28501, +28502,14436,12407,28503,28504,28505,59718,28506,28507,28508,28509,59719,28510, +15925,28513,28511,28512,59720,28514,28515,16717,28516,28517,28518,28519,28520, +28521,28522,28523,28524,16472,59721,28525,16685,28526,28527,28528,59722,59723, +20322,59724,59725,59726,59727,59728,59729,59730,59731,13092,59732,59733,59734, +59735,59736,59737,59738,59739,59740,59741,59742,59743,59744,59745,59746,59747, +59748,59749,59750,59751,59752,59753,59754,59755,59756,59757,59758,59759,59760, +59761,59762,59763,59764,59765,59766,59767,59768,59769,59770,59771,59772,59773, +59774,59776,59777,59778,59779,59780,59781,59782,59783,59784,59785,59786,59787, +59788,59789,59790,59791,59792,59793,59794,59795,59796,59797,59798,59799,59800, +59801,59802,59803,59804,59805,59806,59807,59808,59968,59969,59970,59971,59972, +59973,59974,59975,59976,59977,59978,59979,59980,59981,59982,59983,59984,59985, +59986,59987,59988,59989,59990,59991,59992,59993,59994,59995,17221,25413,18753, +25414,59996,12629,20042,13363,18546,25415,20304,25416,15460,25417,25418,17222, +21794,17494,14699,20037,25419,17270,25420,59997,14119,14451,14930,25421,25422, +21572,25423,59998,25424,20811,25425,25426,25427,25428,20822,25429,12923,16443, +25430,59999,16427,25431,25432,25433,60000,25434,25435,60001,14391,23138,60002, +13907,60003,23140,23139,60004,60005,60006,60007,60008,60009,60010,23142,60011, +60012,60013,18542,60014,60015,23141,14144,20852,21109,21875,15703,60016,60017, +60018,60019,22376,23144,23143,60020,12322,19795,60021,23145,60022,14397,15434, +16957,16932,13122,23146,60023,16938,17456,15669,60024,60025,20318,60026,60027, +60028,23147,18754,60029,60030,60032,60033,60034,12637,60035,60036,60037,23148, +60038,13880,21562,60039,13181,60040,60041,23149,21577,20309,17763,60042,23150, +60043,60044,60045,60046,60047,23151,60048,23152,16746,19541,20317,60049,60050, +60051,60052,60053,60054,60055,60056,60057,60058,60059,60060,60061,21351,16929, +60062,23153,60063,60064,19301,60224,23154,60225,19302,21118,60226,60227,60228, +14452,60229,60230,23155,12335,20278,60231,60232,21839,60233,60234,60235,60236, +60237,60238,60239,60240,60241,60242,19309,60243,60244,60245,60246,60247,60248, +60249,60250,23156,60251,60252,25412,60253,60254,16677,60255,60256,30271,60257, +60258,30272,30273,17489,60259,18488,20835,60260,60261,20571,20805,15407,14669, +60262,28532,60263,60264,13382,21306,30274,13179,60265,60266,30275,60267,60268, +13681,60269,60270,60271,60272,60273,60274,60275,60276,60277,60278,30277,60279, +60280,60281,60282,60283,60284,60285,21354,30247,20777,60286,60288,60289,60290, +30249,60291,60292,60293,30248,60294,60295,16739,16471,60296,12578,60297,60298, +60299,60300,20077,60301,20584,30251,60302,60303,20342,60304,30250,21872,30252, +17209,60305,60306,60307,15220,30254,30253,60308,60309,60310,17502,60311,60312, +16728,60313,60314,60315,60316,60317,19242,60318,20284,60319,60320,60480,60481, +60482,60483,60484,60485,60486,60487,60488,30255,60489,60490,30256,60491,60492, +30257,60493,16950,60494,60495,60496,60497,60498,12372,17785,60499,60500,60501, +60502,30258,60503,60504,60505,60506,60507,60508,60509,60510,60511,60512,60513, +60514,60515,60516,60517,60518,60519,60520,60521,18272,30246,60522,60523,15928, +60524,60525,15922,60526,13669,60527,60528,14151,60529,16191,17234,17254,60530, +60531,22604,60532,60533,60534,14447,60535,60536,60537,60538,60539,60540,60541, +60542,60544,15737,20773,60545,12368,60546,60547,60548,60549,60550,30512,60551, +60552,60553,60554,60555,60556,60557,60558,30513,60559,60560,60561,60562,60563, +20524,60564,12336,60565,60566,60567,30514,30515,60568,30516,60569,60570,60571, +18250,60572,60573,60574,60575,60576,60736,60737,15951,60738,60739,30519,60740, +60741,60742,60743,60744,60745,60746,30518,60747,12638,60748,30517,60749,60750, +30520,60751,30521,60752,60753,60754,60755,60756,60757,60758,60759,60760,60761, +60762,60763,60764,60765,60766,60767,60768,60769,60770,60771,60772,60773,60774, +60775,60776,60777,60778,60779,60780,60781,60782,60783,60784,60785,60786,60787, +60788,60789,60790,60791,60792,60793,60794,60795,60796,60797,60798,60800,60801, +20004,18509,60802,14891,26680,26681,26682,15938,60803,60804,60805,60806,60807, +21108,60808,21583,18776,60809,60810,60811,60812,60813,60814,60815,60816,60817, +60818,60819,60820,60821,60822,60823,60824,60825,60826,60827,60828,60829,60830, +60831,60832,60992,60993,60994,60995,60996,60997,60998,60999,61000,61001,61002, +61003,61004,61005,61006,61007,61008,61009,61010,61011,61012,61013,61014,61015, +61016,61017,61018,61019,61020,61021,61022,61023,61024,61025,61026,61027,61028, +61029,61030,61031,61032,61033,61034,61035,61036,61037,61038,61039,61040,61041, +61042,61043,61044,61045,61046,61047,61048,61049,61050,61051,61052,61053,61054, +61056,61057,61058,61059,61060,61061,61062,61063,61064,61065,61066,61067,61068, +61069,61070,61071,61072,61073,61074,61075,61076,61077,61078,61079,61080,61081, +61082,61083,61084,61085,61086,61087,61088,61248,61249,61250,61251,61252,61253, +21043,13861,18282,29052,20334,19251,20587,26479,19815,14667,13913,29053,12388, +19276,29054,21540,16941,16748,17988,15921,29217,15445,61254,29218,29219,61255, +29220,21059,17973,61256,19783,29221,61257,21297,16197,19554,61258,29222,29223, +20821,13934,29224,29225,13663,29226,29227,61259,12924,29228,29229,18471,61260, +61261,61262,61263,61264,61265,61266,61267,61268,61269,61270,61271,61272,61273, +61274,61275,61276,61277,61278,61279,61280,61281,61282,61283,61284,61285,61286, +61287,61288,61289,61290,61291,61292,61293,61294,61295,61296,61297,14183,61298, +61299,27689,27690,27691,61300,27692,61301,61302,17966,27693,27694,61303,61304, +61305,14153,18995,61306,61307,61308,61309,61310,61312,61313,25144,30543,61314, +61315,61316,61317,61318,61319,61320,61321,61322,61323,61324,61325,61326,61327, +61328,61329,61330,61331,61332,61333,61334,61335,61336,61337,61338,61339,61340, +61341,61342,61343,61344,61504,61505,61506,61507,61508,30544,61509,61510,12877, +61511,61512,61513,61514,61515,61516,61517,61518,61519,61520,61521,61522,61523, +61524,61525,61526,61527,61528,61529,61530,61531,61532,61533,61534,61535,61536, +61537,61538,61539,30545,61540,61541,61542,61543,61544,61545,61546,61547,61548, +61549,61550,61551,61552,61553,61554,61555,61556,61557,61558,61559,61560,61561, +61562,61563,61564,61565,61566,61568,61569,61570,61571,61572,61573,61574,61575, +61576,61577,30547,30546,61578,61579,61580,61581,61582,61583,61584,61585,61586, +61587,61588,61589,61590,25147,61591,15394,61592,25148,25149,25150,25151,25152, +25153,14137,21115,15652,19022,12581,19271,61593,25154,13948,18500,25155,61594, +61595,15688,61596,12669,25156,61597,13942,25157,17497,61598,61599,25158,20314, +14685,25159,16417,61600,25160,12918,61760,25161,61761,16755,25162,25163,17016, +25164,25165,25166,19031,22584,22885,20323,61762,61763,61764,61765,61766,61767, +61768,61769,61770,61771,61772,28709,61773,61774,23600,61775,61776,61777,61778, +61779,61780,61781,61782,61783,61784,61785,61786,61787,61788,61789,61790,61791, +61792,61793,61794,61795,61796,61797,61798,61799,61800,61801,61802,61803,61804, +61805,61806,61807,61808,61809,61810,61811,61812,61813,61814,61815,61816,61817, +61818,61819,61820,61821,61822,61824,61825,61826,61827,61828,61829,61830,61831, +61832,61833,61834,61835,61836,61837,61838,61839,61840,61841,61842,61843,61844, +61845,61846,61847,61848,61849,61850,61851,61852,61853,61854,61855,61856,62016, +62017,62018,62019,62020,62021,62022,62023,62024,62025,62026,62027,62028,62029, +62030,62031,62032,62033,62034,62035,62036,62037,62038,62039,62040,62041,62042, +62043,62044,62045,62046,62047,62048,62049,62050,62051,62052,62053,62054,62055, +62056,62057,62058,62059,62060,62061,62062,62063,62064,62065,62066,62067,62068, +62069,62070,62071,62072,62073,62074,62075,62076,62077,62078,62080,62081,62082, +62083,62084,62085,62086,62087,62088,62089,62090,62091,62092,62093,62094,62095, +62096,62097,62098,62099,62100,62101,62102,62103,62104,62105,62106,62107,62108, +62109,62110,62111,62112,62272,62273,62274,62275,62276,62277,62278,62279,62280, +62281,62282,62283,62284,62285,62286,62287,62288,62289,17005,21542,19796,20785, +13147,18301,62290,12853,16959,26208,19003,26209,26210,15956,26211,22308,19797, +26213,15453,26212,26214,26215,17006,62291,15678,26216,16998,14887,26217,62292, +26218,13138,20841,62293,62294,16165,26219,18031,26220,26221,62295,62296,26222, +17965,26223,62297,18727,26224,26225,26226,25913,26227,26228,16994,26229,26230, +22120,26231,62298,26232,14663,62299,62300,62301,62302,62303,62304,62305,30523, +30522,62306,62307,62308,62309,30526,30524,14881,62310,30527,62311,30528,62312, +62313,62314,30530,30529,30532,62315,62316,30531,62317,62318,62319,62320,62321, +30533,30534,62322,62323,62324,62325,30535,62326,19304,62327,62328,62329,62330, +14431,62331,62332,62333,62334,62336,62337,30548,62338,30549,62339,62340,62341, +62342,30550,62343,62344,62345,62346,30552,62347,30554,62348,30551,62349,62350, +62351,62352,62353,62354,62355,62356,62357,30555,62358,30553,62359,62360,62361, +62362,62363,62364,62365,22359,62366,62367,62368,62528,30556,62529,62530,62531, +62532,62533,62534,30557,62535,62536,62537,30558,62538,62539,62540,62541,62542, +62543,62544,62545,62546,62547,62548,30559,62549,62550,62551,30560,62552,62553, +62554,62555,62556,62557,62558,62559,62560,62561,62562,23371,62563,62564,22570, +62565,62566,62567,62568,62569,62570,62571,62572,25975,14701,62573,62574,62575, +62576,16253,15210,30537,17991,30536,62577,30538,30540,30539,62578,62579,62580, +30541,62581,20026,62582,30542,62583,62584,17447,62585,62586,62587,62588,62589, +62590,62592,62593,62594,62595,62596,62597,62598,62599,62600,62601,62602,62603, +62604,62605,62606,62607,62608,62609,62610,62611,62612,62613,62614,62615,62616, +62617,62618,62619,62620,62621,62622,62623,62624,62784,62785,62786,62787,62788, +62789,62790,62791,62792,62793,62794,62795,62796,62797,62798,62799,62800,62801, +62802,62803,62804,62805,62806,62807,62808,62809,62810,62811,62812,62813,62814, +62815,62816,62817,62818,62819,62820,62821,62822,62823,62824,62825,62826,62827, +62828,62829,62830,62831,62832,62833,62834,62835,62836,62837,62838,62839,62840, +62841,62842,62843,62844,62845,62846,62848,62849,62850,62851,62852,62853,62854, +62855,62856,62857,62858,62859,62860,62861,62862,62863,62864,62865,62866,62867, +62868,62869,62870,62871,62872,62873,62874,62875,62876,62877,62878,62879,62880, +63040,63041,63042,63043,63044,63045,63046,63047,63048,63049,63050,63051,63052, +63053,63054,63055,63056,63057,63058,63059,63060,63061,63062,63063,63064,63065, +63066,63067,63068,63069,63070,63071,63072,63073,63074,63075,63076,63077,63078, +63079,63080,63081,63082,63083,63084,63085,63086,63087,63088,63089,63090,63091, +63092,63093,63094,63095,63096,63097,63098,63099,63100,63101,63102,63104,63105, +63106,63107,63108,63109,63110,63111,63112,63113,63114,63115,63116,63117,63118, +63119,63120,63121,63122,63123,63124,63125,63126,63127,63128,63129,63130,63131, +63132,63133,63134,63135,63136,63296,63297,63298,63299,63300,63301,63302,63303, +63304,63305,63306,63307,63308,63309,63310,63311,63312,63313,63314,63315,63316, +63317,63318,63319,63320,63321,63322,63323,63324,63325,63326,63327,63328,63329, +63330,63331,63332,63333,63334,63335,63336,63337,63338,63339,63340,63341,63342, +63343,63344,63345,63346,63347,63348,63349,63350,63351,63352,63353,63354,63355, +63356,63357,63358,63360,21347,63361,63362,30287,63363,16947,30288,63364,63365, +30289,30290,30291,30292,63366,63367,30294,63368,12587,30295,63369,30296,30297, +30298,63370,30299,30300,63371,63372,63373,63374,30301,30302,20298,63375,30303, +30304,30305,30306,30307,30308,16496,30309,30310,30311,30312,30313,63376,30314, +63377,30315,30316,63378,30317,30318,30319,30320,30321,30322,30323,30324,15912, +63379,30325,30326,30327,30328,63380,63381,63382,63383,63384,18554,30329,30330, +30331,30332,63385,63386,30333,30334,30497,30498,30499,30500,30501,63387,63388, +30502,30503,30504,12654,30505,30506,30507,63389,63390,30508,30509,16731,30510, +63391,63392,30511,63552,63553,63554,63555,63556,63557,63558,63559,63560,63561, +63562,63563,63564,63565,63566,63567,63568,63569,63570,63571,63572,63573,63574, +63575,63576,63577,63578,63579,63580,63581,63582,63583,63584,63585,63586,63587, +63588,63589,63590,63591,63592,63593,63594,63595,63596,63597,63598,63599,63600, +63601,63602,63603,63604,63605,63606,63607,63608,63609,63610,63611,63612,63613, +63614,63616,63617,63618,63619,63620,63621,63622,63623,63624,63625,63626,63627, +63628,63629,63630,63631,63632,63633,63634,63635,63636,63637,63638,63639,63640, +63641,63642,63643,63644,63645,63646,63647,63648,63808,63809,63810,63811,63812, +63813,63814,63815,63816,63817,63818,63819,63820,63821,63822,63823,63824,63825, +63826,63827,63828,63829,63830,63831,63832,63833,63834,63835,63836,63837,63838, +63839,63840,63841,63842,63843,63844,63845,63846,63847,63848,63849,63850,63851, +63852,63853,63854,63855,63856,63857,63858,63859,63860,63861,63862,63863,63864, +63865,63866,63867,63868,63869,63870,63872,63873,63874,63875,63876,63877,63878, +63879,63880,63881,63882,63883,63884,63885,63886,63887,63888,63889,63890,63891, +63892,63893,63894,63895,63896,63897,63898,63899,63900,63901,63902,63903,63904, +64064,64065,64066,64067,64068,64069,64070,64071,64072,64073,64074,64075,64076, +64077,64078,64079,64080,64081,64082,64083,64084,64085,64086,64087,64088,64089, +64090,64091,64092,64093,64094,64095,64096,64097,64098,64099,64100,64101,64102, +64103,64104,64105,64106,64107,64108,64109,64110,64111,64112,64113,64114,64115, +64116,64117,64118,64119,64120,64121,64122,64123,64124,64125,64126,64128,64129, +64130,64131,64132,64133,64134,64135,64136,64137,64138,64139,64140,64141,64142, +64143,64144,64145,64146,64147,64148,64149,64150,64151,64152,64153,64154,64155, +64156,64157,64158,64159,64160,64320,64321,64322,64323,64324,64325,64326,64327, +64328,64329,64330,64331,64332,64333,64334,64335,64336,64337,64338,64339,64340, +64341,64342,64343,64344,64345,64346,64347,17521,28719,15398,28720,17273,64348, +17720,20795,64349,28721,28722,28723,28724,28725,20796,64350,20844,64351,28727, +28726,21543,64352,19794,28728,28730,28729,28731,28732,64353,64354,14443,28733, +14952,64355,28734,28735,15977,28736,13932,28737,28738,28739,28740,18485,28741, +28742,64356,28743,17780,64357,28744,64358,64359,64360,28745,64361,28746,30525, +64362,28747,28748,28749,64363,28750,64364,64365,64366,64367,28751,14935,64368, +28752,28753,28754,28755,28756,28757,28758,28760,64369,64370,21285,28759,64371, +28761,64372,64373,64374,64375,64376,64377,64378,64379,64380,64381,30010,16953, +64382,64384,30564,64385,64386,64387,64388,30565,30566,64389,64390,30567,64391, +64392,64393,64394,64395,64396,30568,16948,64397,64398,64399,64400,64401,64402, +64403,64404,64405,30570,64406,30571,64407,64408,64409,64410,64411,64412,17011, +64413,64414,64415,64416,64576,64577,64578,64579,64580,64581,64582,64583,64584, +29808,64585,64586,64587,29807,64588,64589,17001,64590,30561,30562,64591,64592, +64593,64594,64595,15174,64596,64597,64598,64599,22884,64600,64601,64602,19058, +16488,28708,64603,14938,64604,64605,18221,64606,64607,64608,17452,64609,64610, +30572,30573,30574,64611,30576,30575,64612,30577,64613,64614,30580,64615,30579, +64616,30578,30581,64617,64618,64619,64620,30582,64621,64622,64623,64624,64625, +64626,64627,64628,64629,28009,64630,28010,28011,64631,30268,64632,64633,64634, +64635,64636,64637,64638,64640,64641,64642,64643,64644,30269,64645,30270,13862, +64646,22590,64647,64648,14660,64649,64650,64651,22587,64652,23601,64653,64654, +64655,64656,64657,64658,19059,64659,30583,64660,64661,64662,64663,64664,64665, +64666,64667,64668,30584,64669,64670,30585,64671,64672,64832,64833,64834,64835, +64836,30587,64837,30586,64838,12615,64839,30588,30589,64840,64841,64842,64843, +64844,30590,64845,64846,64847,64848,64849,64850,64851,64852,64853,64854,64855, +18027,27700,64856,64857,64858,64859,64860,64861,64862,64863,64864,64865,64866, +64867,64868,64869,64870,64871,64872,64873,64874,64875,64876,64877,64878,64879, +64880,64881,64882,64883,64884,64885,64886,64887,64888,64889,64890,64891,64892, +64893,64894,64896,64897,64898,64899,64900,64901,13149,30259,64902,64903,30260, +16740,30261,30262,30263,30264,30265,30266,18467,30267,64904,64905,64906,64907, +64908,64909,64910,64911,64912,64913,64914,64915,16762,14632,28008,64916,64917, +64918,14698,22879,64919,64920,64921,64922,64923,64924,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64925,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64927,N,N,N,N,N,N,N,N,N,64928, +65088,65089,65090,65091,N,65092,N,65093,65094,N,N,N,65095,N,N,N,N,N,N,65096, +65097,65098,N,65099,65100,N,N,65101,65102,65103,43349,42738,N,42740,42741, +42720,42721,42736,42737,42722,42723,42734,42735,42726,42727,42724,42725,42728, +42729,42730,42731,N,N,N,N,43368,43369,43370,43371,43372,43373,43374,43375, +43376,43377,N,43378,43379,43380,43381,N,43382,43383,43384,43385,43386,43387, +43388,43389,43390,43392,43393,43394,43395,43396,N,43397,43398,43399,43400, +8993,8994,8995,8551,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007, +9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,9022, +9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037, +9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052, +9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064,9065,9066,9067, +9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082, +9083,9084,9085,8491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8553,8554,43350,9086,43351,8996, +}; + +static const struct unim_index gbcommon_encmap[256] = { +{__gbcommon_encmap+0,164,252},{__gbcommon_encmap+89,1,220},{__gbcommon_encmap+ +309,81,217},{__gbcommon_encmap+446,145,201},{__gbcommon_encmap+503,1,81},{0,0, +0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gbcommon_encmap+584, +16,59},{__gbcommon_encmap+628,3,153},{__gbcommon_encmap+779,8,191},{ +__gbcommon_encmap+963,18,18},{__gbcommon_encmap+964,96,155},{__gbcommon_encmap ++1024,0,229},{__gbcommon_encmap+1254,5,66},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gbcommon_encmap+1316,0,254},{ +__gbcommon_encmap+1571,5,41},{__gbcommon_encmap+1608,32,163},{ +__gbcommon_encmap+1740,142,213},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{__gbcommon_encmap+1812,0,255},{__gbcommon_encmap+2068,0,255},{ +__gbcommon_encmap+2324,0,255},{__gbcommon_encmap+2580,0,255},{ +__gbcommon_encmap+2836,0,255},{__gbcommon_encmap+3092,0,255},{ +__gbcommon_encmap+3348,0,255},{__gbcommon_encmap+3604,0,255},{ +__gbcommon_encmap+3860,0,255},{__gbcommon_encmap+4116,0,255},{ +__gbcommon_encmap+4372,0,255},{__gbcommon_encmap+4628,0,255},{ +__gbcommon_encmap+4884,0,255},{__gbcommon_encmap+5140,0,255},{ +__gbcommon_encmap+5396,0,255},{__gbcommon_encmap+5652,0,255},{ +__gbcommon_encmap+5908,0,255},{__gbcommon_encmap+6164,0,255},{ +__gbcommon_encmap+6420,0,255},{__gbcommon_encmap+6676,0,255},{ +__gbcommon_encmap+6932,0,255},{__gbcommon_encmap+7188,0,255},{ +__gbcommon_encmap+7444,0,255},{__gbcommon_encmap+7700,0,255},{ +__gbcommon_encmap+7956,0,255},{__gbcommon_encmap+8212,0,255},{ +__gbcommon_encmap+8468,0,255},{__gbcommon_encmap+8724,0,255},{ +__gbcommon_encmap+8980,0,255},{__gbcommon_encmap+9236,0,255},{ +__gbcommon_encmap+9492,0,255},{__gbcommon_encmap+9748,0,255},{ +__gbcommon_encmap+10004,0,255},{__gbcommon_encmap+10260,0,255},{ +__gbcommon_encmap+10516,0,255},{__gbcommon_encmap+10772,0,255},{ +__gbcommon_encmap+11028,0,255},{__gbcommon_encmap+11284,0,255},{ +__gbcommon_encmap+11540,0,255},{__gbcommon_encmap+11796,0,255},{ +__gbcommon_encmap+12052,0,255},{__gbcommon_encmap+12308,0,255},{ +__gbcommon_encmap+12564,0,255},{__gbcommon_encmap+12820,0,255},{ +__gbcommon_encmap+13076,0,255},{__gbcommon_encmap+13332,0,255},{ +__gbcommon_encmap+13588,0,255},{__gbcommon_encmap+13844,0,255},{ +__gbcommon_encmap+14100,0,255},{__gbcommon_encmap+14356,0,255},{ +__gbcommon_encmap+14612,0,255},{__gbcommon_encmap+14868,0,255},{ +__gbcommon_encmap+15124,0,255},{__gbcommon_encmap+15380,0,255},{ +__gbcommon_encmap+15636,0,255},{__gbcommon_encmap+15892,0,255},{ +__gbcommon_encmap+16148,0,255},{__gbcommon_encmap+16404,0,255},{ +__gbcommon_encmap+16660,0,255},{__gbcommon_encmap+16916,0,255},{ +__gbcommon_encmap+17172,0,255},{__gbcommon_encmap+17428,0,255},{ +__gbcommon_encmap+17684,0,255},{__gbcommon_encmap+17940,0,255},{ +__gbcommon_encmap+18196,0,255},{__gbcommon_encmap+18452,0,255},{ +__gbcommon_encmap+18708,0,255},{__gbcommon_encmap+18964,0,255},{ +__gbcommon_encmap+19220,0,255},{__gbcommon_encmap+19476,0,255},{ +__gbcommon_encmap+19732,0,255},{__gbcommon_encmap+19988,0,255},{ +__gbcommon_encmap+20244,0,255},{__gbcommon_encmap+20500,0,255},{ +__gbcommon_encmap+20756,0,255},{__gbcommon_encmap+21012,0,255},{ +__gbcommon_encmap+21268,0,255},{__gbcommon_encmap+21524,0,255},{ +__gbcommon_encmap+21780,0,255},{__gbcommon_encmap+22036,0,255},{ +__gbcommon_encmap+22292,0,255},{__gbcommon_encmap+22548,0,165},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{__gbcommon_encmap+22714,44,241},{__gbcommon_encmap+22912,12,41},{0,0,0},{0, +0,0},{0,0,0},{__gbcommon_encmap+22942,48,107},{__gbcommon_encmap+23002,1,229}, +}; + +static const ucs2_t __gb18030ext_decmap[2729] = { +58566,58567,58568,58569,58570,58571,58572,58573,58574,58575,58576,58577,58578, +58579,58580,58581,58582,58583,58584,58585,58586,58587,58588,58589,58590,58591, +58592,58593,58594,58595,58596,58597,58598,58599,58600,58601,58602,58603,58604, +58605,58606,58607,58608,58609,58610,58611,58612,58613,58614,58615,58616,58617, +58618,58619,58620,58621,58622,58623,58624,58625,58626,58627,58628,U,58629, +58630,58631,58632,58633,58634,58635,58636,58637,58638,58639,58640,58641,58642, +58643,58644,58645,58646,58647,58648,58649,58650,58651,58652,58653,58654,58655, +58656,58657,58658,58659,58660,58661,58662,58663,58664,58665,58666,58667,58668, +58669,58670,58671,58672,58673,58674,58675,58676,58677,58678,58679,58680,58681, +58682,58683,58684,58685,58686,58687,58688,58689,58690,58691,58692,58693,58694, +58695,58696,58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707, +58708,58709,58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720, +58721,58722,58723,58724,U,58725,58726,58727,58728,58729,58730,58731,58732, +58733,58734,58735,58736,58737,58738,58739,58740,58741,58742,58743,58744,58745, +58746,58747,58748,58749,58750,58751,58752,58753,58754,58755,58756,58757,U,U,U, +U,U,U,U,U,U,U,59238,59239,59240,59241,59242,59243,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8364, +59245,U,U,U,U,U,U,U,U,U,U,59246,59247,U,U,U,U,U,U,U,U,U,U,U,U,59248,59249, +58758,58759,58760,58761,58762,58763,58764,58765,58766,58767,58768,58769,58770, +58771,58772,58773,58774,58775,58776,58777,58778,58779,58780,58781,58782,58783, +58784,58785,58786,58787,58788,58789,58790,58791,58792,58793,58794,58795,58796, +58797,58798,58799,58800,58801,58802,58803,58804,58805,58806,58807,58808,58809, +58810,58811,58812,58813,58814,58815,58816,58817,58818,58819,58820,U,58821, +58822,58823,58824,58825,58826,58827,58828,58829,58830,58831,58832,58833,58834, +58835,58836,58837,58838,58839,58840,58841,58842,58843,58844,58845,58846,58847, +58848,58849,58850,58851,58852,58853,58854,58855,58856,58857,58858,58859,58860, +58861,58862,58863,58864,58865,58866,58867,58868,58869,58870,58871,58872,58873, +58874,58875,58876,58877,58878,58879,58880,58881,58882,58883,58884,58885,58886, +58887,58888,58889,58890,58891,58892,58893,58894,58895,58896,58897,58898,58899, +58900,58901,58902,58903,58904,58905,58906,58907,58908,58909,58910,58911,58912, +58913,58914,58915,58916,U,58917,58918,58919,58920,58921,58922,58923,58924, +58925,58926,58927,58928,58929,58930,58931,58932,58933,58934,58935,58936,58937, +58938,58939,58940,58941,58942,58943,58944,58945,58946,58947,58948,58949,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,59250,59251,59252,59253,59254,59255,59256,59257,59258,59259,59260,58950, +58951,58952,58953,58954,58955,58956,58957,58958,58959,58960,58961,58962,58963, +58964,58965,58966,58967,58968,58969,58970,58971,58972,58973,58974,58975,58976, +58977,58978,58979,58980,58981,58982,58983,58984,58985,58986,58987,58988,58989, +58990,58991,58992,58993,58994,58995,58996,58997,58998,58999,59000,59001,59002, +59003,59004,59005,59006,59007,59008,59009,59010,59011,59012,U,59013,59014, +59015,59016,59017,59018,59019,59020,59021,59022,59023,59024,59025,59026,59027, +59028,59029,59030,59031,59032,59033,59034,59035,59036,59037,59038,59039,59040, +59041,59042,59043,59044,59045,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59261,59262,59263,59264,59265, +59266,59267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055, +59056,59057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068, +59069,59070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081, +59082,59083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094, +59095,59096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107, +59108,U,59109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119, +59120,59121,59122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132, +59133,59134,59135,59136,59137,59138,59139,59140,59141,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,59269,59270,59271,59272,59273,59274,59275,59276,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59277,59278,59279,59280,59281,59282, +59283,U,U,U,U,U,U,U,U,U,U,U,U,59284,59285,U,U,U,U,U,59286,U,U,59287,59288, +59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,59146,59147, +59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,59159,59160, +59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,59172,59173, +59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,59185,59186, +59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,59198,59199, +59200,59201,59202,59203,59204,U,59205,59206,59207,59208,59209,59210,59211, +59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,59224, +59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,59237, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59296,59297, +59298,59299,59300,59301,59302,59303,59304,59305,59306,59307,59308,59309,59310, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59311,59312, +59313,59314,59315,59316,59317,59318,59319,59320,59321,59322,59323,59324,59325, +59326,59327,59328,59329,59330,59331,59332,59333,59334,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59335,U,U,505,U,59337,59338,59339,59340,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,59341,59342, +59343,59344,59345,59346,59347,59348,59349,59350,59351,59352,59353,59354,59355, +59356,59357,59358,59359,59360,59361,59362,U,U,59363,U,59364,59365,59366,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +12350,12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283, +U,59380,59381,59382,59383,59384,59385,59386,59387,59388,59389,59390,59391, +59392,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,59393,59394,59395,59396,59397,59398,59399,59400,59401,59402,59403,59404, +59405,59406,59407,57344,57345,57346,57347,57348,57349,57350,57351,57352,57353, +57354,57355,57356,57357,57358,57359,57360,57361,57362,57363,57364,57365,57366, +57367,57368,57369,57370,57371,57372,57373,57374,57375,57376,57377,57378,57379, +57380,57381,57382,57383,57384,57385,57386,57387,57388,57389,57390,57391,57392, +57393,57394,57395,57396,57397,57398,57399,57400,57401,57402,57403,57404,57405, +57406,57407,57408,57409,57410,57411,57412,57413,57414,57415,57416,57417,57418, +57419,57420,57421,57422,57423,57424,57425,57426,57427,57428,57429,57430,57431, +57432,57433,57434,57435,57436,57437,57438,57439,57440,57441,57442,57443,57444, +57445,57446,57447,57448,57449,57450,57451,57452,57453,57454,57455,57456,57457, +57458,57459,57460,57461,57462,57463,57464,57465,57466,57467,57468,57469,57470, +57471,57472,57473,57474,57475,57476,57477,57478,57479,57480,57481,57482,57483, +57484,57485,57486,57487,57488,57489,57490,57491,57492,57493,57494,57495,57496, +57497,57498,57499,57500,57501,57502,57503,57504,57505,57506,57507,57508,57509, +57510,57511,57512,57513,57514,57515,57516,57517,57518,57519,57520,57521,57522, +57523,57524,57525,57526,57527,57528,57529,57530,57531,57532,57533,57534,57535, +57536,57537,57538,57539,57540,57541,57542,57543,57544,57545,57546,57547,57548, +57549,57550,57551,57552,57553,57554,57555,57556,57557,57558,57559,57560,57561, +57562,57563,57564,57565,57566,57567,57568,57569,57570,57571,57572,57573,57574, +57575,57576,57577,57578,57579,57580,57581,57582,57583,57584,57585,57586,57587, +57588,57589,57590,57591,57592,57593,57594,57595,57596,57597,57598,57599,57600, +57601,57602,57603,57604,57605,57606,57607,57608,57609,57610,57611,57612,57613, +57614,57615,57616,57617,57618,57619,57620,57621,57622,57623,57624,57625,57626, +57627,57628,57629,57630,57631,57632,57633,57634,57635,57636,57637,57638,57639, +57640,57641,57642,57643,57644,57645,57646,57647,57648,57649,57650,57651,57652, +57653,57654,57655,57656,57657,57658,57659,57660,57661,57662,57663,57664,57665, +57666,57667,57668,57669,57670,57671,57672,57673,57674,57675,57676,57677,57678, +57679,57680,57681,57682,57683,57684,57685,57686,57687,57688,57689,57690,57691, +57692,57693,57694,57695,57696,57697,57698,57699,57700,57701,57702,57703,57704, +57705,57706,57707,57708,57709,57710,57711,57712,57713,57714,57715,57716,57717, +57718,57719,57720,57721,57722,57723,57724,57725,57726,57727,57728,57729,57730, +57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,57741,57742,57743, +57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,57754,57755,57756, +57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,57767,57768,57769, +57770,57771,57772,57773,57774,57775,57776,57777,57778,57779,57780,57781,57782, +57783,57784,57785,57786,57787,57788,57789,57790,57791,57792,57793,57794,57795, +57796,57797,57798,57799,57800,57801,57802,57803,57804,57805,57806,57807,57808, +57809,57810,57811,57812,57813,57814,57815,57816,57817,57818,57819,57820,57821, +57822,57823,57824,57825,57826,57827,57828,57829,57830,57831,57832,57833,57834, +57835,57836,57837,57838,57839,57840,57841,57842,57843,57844,57845,57846,57847, +57848,57849,57850,57851,57852,57853,57854,57855,57856,57857,57858,57859,57860, +57861,57862,57863,57864,57865,57866,57867,57868,57869,57870,57871,57872,57873, +57874,57875,57876,57877,57878,57879,57880,57881,57882,57883,57884,57885,57886, +57887,57888,57889,57890,57891,57892,57893,57894,57895,57896,57897,57898,57899, +57900,57901,57902,57903,57904,57905,57906,57907,59408,59409,59410,59411,59412, +57908,57909,57910,57911,57912,57913,57914,57915,57916,57917,57918,57919,57920, +57921,57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933, +57934,57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946, +57947,57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959, +57960,57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972, +57973,57974,57975,57976,57977,57978,57979,57980,57981,57982,57983,57984,57985, +57986,57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998, +57999,58000,58001,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011, +58012,58013,58014,58015,58016,58017,58018,58019,58020,58021,58022,58023,58024, +58025,58026,58027,58028,58029,58030,58031,58032,58033,58034,58035,58036,58037, +58038,58039,58040,58041,58042,58043,58044,58045,58046,58047,58048,58049,58050, +58051,58052,58053,58054,58055,58056,58057,58058,58059,58060,58061,58062,58063, +58064,58065,58066,58067,58068,58069,58070,58071,58072,58073,58074,58075,58076, +58077,58078,58079,58080,58081,58082,58083,58084,58085,58086,58087,58088,58089, +58090,58091,58092,58093,58094,58095,58096,58097,58098,58099,58100,58101,58102, +58103,58104,58105,58106,58107,58108,58109,58110,58111,58112,58113,58114,58115, +58116,58117,58118,58119,58120,58121,58122,58123,58124,58125,58126,58127,58128, +58129,58130,58131,58132,58133,58134,58135,58136,58137,58138,58139,58140,58141, +58142,58143,58144,58145,58146,58147,58148,58149,58150,58151,58152,58153,58154, +58155,58156,58157,58158,58159,58160,58161,58162,58163,58164,58165,58166,58167, +58168,58169,58170,58171,58172,58173,58174,58175,58176,58177,58178,58179,58180, +58181,58182,58183,58184,58185,58186,58187,58188,58189,58190,58191,58192,58193, +58194,58195,58196,58197,58198,58199,58200,58201,58202,58203,58204,58205,58206, +58207,58208,58209,58210,58211,58212,58213,58214,58215,58216,58217,58218,58219, +58220,58221,58222,58223,58224,58225,58226,58227,58228,58229,58230,58231,58232, +58233,58234,58235,58236,58237,58238,58239,58240,58241,58242,58243,58244,58245, +58246,58247,58248,58249,58250,58251,58252,58253,58254,58255,58256,58257,58258, +58259,58260,58261,58262,58263,58264,58265,58266,58267,58268,58269,58270,58271, +58272,58273,58274,58275,58276,58277,58278,58279,58280,58281,58282,58283,58284, +58285,58286,58287,58288,58289,58290,58291,58292,58293,58294,58295,58296,58297, +58298,58299,58300,58301,58302,58303,58304,58305,58306,58307,58308,58309,58310, +58311,58312,58313,58314,58315,58316,58317,58318,58319,58320,58321,58322,58323, +58324,58325,58326,58327,58328,58329,58330,58331,58332,58333,58334,58335,58336, +58337,58338,58339,58340,58341,58342,58343,58344,58345,58346,58347,58348,58349, +58350,58351,58352,58353,58354,58355,58356,58357,58358,58359,58360,58361,58362, +58363,58364,58365,58366,58367,58368,58369,58370,58371,58372,58373,58374,58375, +58376,58377,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388, +58389,58390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401, +58402,58403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414, +58415,58416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427, +58428,58429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440, +58441,58442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453, +58454,58455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466, +58467,58468,58469,58470,58471,11905,59414,59415,59416,11908,13427,13383,11912, +11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,14815,14963, +14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,16735,11950, +17207,11955,11958,11959,59451,17329,17324,11963,17373,17622,18017,17996,59459, +U,18211,18217,18300,18317,11978,18759,18810,18813,18818,18819,18821,18822, +18847,18843,18871,18870,59476,59477,19619,19615,19616,19617,19575,19618,19731, +19732,19733,19734,19735,19736,19737,19886,59492,58472,58473,58474,58475,58476, +58477,58478,58479,58480,58481,58482,58483,58484,58485,58486,58487,58488,58489, +58490,58491,58492,58493,58494,58495,58496,58497,58498,58499,58500,58501,58502, +58503,58504,58505,58506,58507,58508,58509,58510,58511,58512,58513,58514,58515, +58516,58517,58518,58519,58520,58521,58522,58523,58524,58525,58526,58527,58528, +58529,58530,58531,58532,58533,58534,58535,58536,58537,58538,58539,58540,58541, +58542,58543,58544,58545,58546,58547,58548,58549,58550,58551,58552,58553,58554, +58555,58556,58557,58558,58559,58560,58561,58562,58563,58564,58565, +}; + +static const struct dbcs_index gb18030ext_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_decmap+0,64, +160},{__gb18030ext_decmap+97,64,254},{__gb18030ext_decmap+288,64,160},{ +__gb18030ext_decmap+385,64,254},{__gb18030ext_decmap+576,64,254},{ +__gb18030ext_decmap+767,64,254},{__gb18030ext_decmap+958,64,254},{ +__gb18030ext_decmap+1149,150,254},{__gb18030ext_decmap+1254,88,254},{ +__gb18030ext_decmap+1421,161,254},{__gb18030ext_decmap+1515,161,254},{ +__gb18030ext_decmap+1609,161,254},{__gb18030ext_decmap+1703,161,254},{ +__gb18030ext_decmap+1797,161,254},{__gb18030ext_decmap+1891,161,254},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__gb18030ext_decmap+1985,250,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_decmap ++1990,161,254},{__gb18030ext_decmap+2084,161,254},{__gb18030ext_decmap+2178, +161,254},{__gb18030ext_decmap+2272,161,254},{__gb18030ext_decmap+2366,161,254 +},{__gb18030ext_decmap+2460,161,254},{__gb18030ext_decmap+2554,80,254},{0,0,0 +}, +}; + +static const DBCHAR __gb18030ext_encmap[3227] = { +43199,41699,65104,N,N,65108,N,N,N,65111,N,N,65112,65117,N,N,N,N,N,N,N,N,N,N, +65118,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65131,N,N,65134,N,N,N,65137,N,N,N,N,65139, +N,N,65140,65141,N,N,N,65145,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65156,43402,43403, +43404,43405,43406,43407,43408,43409,43410,43411,43412,43413,43401,65110,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,65109,65114,65116,N,N,N,N,N,N,N,N,N,N,N,65115,65120,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65119,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65122,65125,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65123, +65124,65128,65129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,65130,65135,65136,65138,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65144,N,N,N,N,65143,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65146,65147,65149, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65148,65152,N,N,N,N,N,65153,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +65154,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65155,65157,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65158, +N,N,65159,N,N,N,N,65160,65161,N,65162,65163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,65165,N,N,N,65164,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65167, +65166,65174,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,65171,65172,65173,65175,65170,65176,65177,65178,65179,65180,65181, +65182,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65183, +43681,43682,43683,43684,43685,43686,43687,43688,43689,43690,43691,43692,43693, +43694,43695,43696,43697,43698,43699,43700,43701,43702,43703,43704,43705,43706, +43707,43708,43709,43710,43711,43712,43713,43714,43715,43716,43717,43718,43719, +43720,43721,43722,43723,43724,43725,43726,43727,43728,43729,43730,43731,43732, +43733,43734,43735,43736,43737,43738,43739,43740,43741,43742,43743,43744,43745, +43746,43747,43748,43749,43750,43751,43752,43753,43754,43755,43756,43757,43758, +43759,43760,43761,43762,43763,43764,43765,43766,43767,43768,43769,43770,43771, +43772,43773,43774,43937,43938,43939,43940,43941,43942,43943,43944,43945,43946, +43947,43948,43949,43950,43951,43952,43953,43954,43955,43956,43957,43958,43959, +43960,43961,43962,43963,43964,43965,43966,43967,43968,43969,43970,43971,43972, +43973,43974,43975,43976,43977,43978,43979,43980,43981,43982,43983,43984,43985, +43986,43987,43988,43989,43990,43991,43992,43993,43994,43995,43996,43997,43998, +43999,44000,44001,44002,44003,44004,44005,44006,44007,44008,44009,44010,44011, +44012,44013,44014,44015,44016,44017,44018,44019,44020,44021,44022,44023,44024, +44025,44026,44027,44028,44029,44030,44193,44194,44195,44196,44197,44198,44199, +44200,44201,44202,44203,44204,44205,44206,44207,44208,44209,44210,44211,44212, +44213,44214,44215,44216,44217,44218,44219,44220,44221,44222,44223,44224,44225, +44226,44227,44228,44229,44230,44231,44232,44233,44234,44235,44236,44237,44238, +44239,44240,44241,44242,44243,44244,44245,44246,44247,44248,44249,44250,44251, +44252,44253,44254,44255,44256,44257,44258,44259,44260,44261,44262,44263,44264, +44265,44266,44267,44268,44269,44270,44271,44272,44273,44274,44275,44276,44277, +44278,44279,44280,44281,44282,44283,44284,44285,44286,44449,44450,44451,44452, +44453,44454,44455,44456,44457,44458,44459,44460,44461,44462,44463,44464,44465, +44466,44467,44468,44469,44470,44471,44472,44473,44474,44475,44476,44477,44478, +44479,44480,44481,44482,44483,44484,44485,44486,44487,44488,44489,44490,44491, +44492,44493,44494,44495,44496,44497,44498,44499,44500,44501,44502,44503,44504, +44505,44506,44507,44508,44509,44510,44511,44512,44513,44514,44515,44516,44517, +44518,44519,44520,44521,44522,44523,44524,44525,44526,44527,44528,44529,44530, +44531,44532,44533,44534,44535,44536,44537,44538,44539,44540,44541,44542,44705, +44706,44707,44708,44709,44710,44711,44712,44713,44714,44715,44716,44717,44718, +44719,44720,44721,44722,44723,44724,44725,44726,44727,44728,44729,44730,44731, +44732,44733,44734,44735,44736,44737,44738,44739,44740,44741,44742,44743,44744, +44745,44746,44747,44748,44749,44750,44751,44752,44753,44754,44755,44756,44757, +44758,44759,44760,44761,44762,44763,44764,44765,44766,44767,44768,44769,44770, +44771,44772,44773,44774,44775,44776,44777,44778,44779,44780,44781,44782,44783, +44784,44785,44786,44787,44788,44789,44790,44791,44792,44793,44794,44795,44796, +44797,44798,44961,44962,44963,44964,44965,44966,44967,44968,44969,44970,44971, +44972,44973,44974,44975,44976,44977,44978,44979,44980,44981,44982,44983,44984, +44985,44986,44987,44988,44989,44990,44991,44992,44993,44994,44995,44996,44997, +44998,44999,45000,45001,45002,45003,45004,45005,45006,45007,45008,45009,45010, +45011,45012,45013,45014,45015,45016,45017,45018,45019,45020,45021,45022,45023, +45024,45025,45026,45027,45028,45029,45030,45031,45032,45033,45034,45035,45036, +45037,45038,45039,45040,45041,45042,45043,45044,45045,45046,45047,45048,45049, +45050,45051,45052,45053,45054,63649,63650,63651,63652,63653,63654,63655,63656, +63657,63658,63659,63660,63661,63662,63663,63664,63665,63666,63667,63668,63669, +63670,63671,63672,63673,63674,63675,63676,63677,63678,63679,63680,63681,63682, +63683,63684,63685,63686,63687,63688,63689,63690,63691,63692,63693,63694,63695, +63696,63697,63698,63699,63700,63701,63702,63703,63704,63705,63706,63707,63708, +63709,63710,63711,63712,63713,63714,63715,63716,63717,63718,63719,63720,63721, +63722,63723,63724,63725,63726,63727,63728,63729,63730,63731,63732,63733,63734, +63735,63736,63737,63738,63739,63740,63741,63742,63905,63906,63907,63908,63909, +63910,63911,63912,63913,63914,63915,63916,63917,63918,63919,63920,63921,63922, +63923,63924,63925,63926,63927,63928,63929,63930,63931,63932,63933,63934,63935, +63936,63937,63938,63939,63940,63941,63942,63943,63944,63945,63946,63947,63948, +63949,63950,63951,63952,63953,63954,63955,63956,63957,63958,63959,63960,63961, +63962,63963,63964,63965,63966,63967,63968,63969,63970,63971,63972,63973,63974, +63975,63976,63977,63978,63979,63980,63981,63982,63983,63984,63985,63986,63987, +63988,63989,63990,63991,63992,63993,63994,63995,63996,63997,63998,64161,64162, +64163,64164,64165,64166,64167,64168,64169,64170,64171,64172,64173,64174,64175, +64176,64177,64178,64179,64180,64181,64182,64183,64184,64185,64186,64187,64188, +64189,64190,64191,64192,64193,64194,64195,64196,64197,64198,64199,64200,64201, +64202,64203,64204,64205,64206,64207,64208,64209,64210,64211,64212,64213,64214, +64215,64216,64217,64218,64219,64220,64221,64222,64223,64224,64225,64226,64227, +64228,64229,64230,64231,64232,64233,64234,64235,64236,64237,64238,64239,64240, +64241,64242,64243,64244,64245,64246,64247,64248,64249,64250,64251,64252,64253, +64254,64417,64418,64419,64420,64421,64422,64423,64424,64425,64426,64427,64428, +64429,64430,64431,64432,64433,64434,64435,64436,64437,64438,64439,64440,64441, +64442,64443,64444,64445,64446,64447,64448,64449,64450,64451,64452,64453,64454, +64455,64456,64457,64458,64459,64460,64461,64462,64463,64464,64465,64466,64467, +64468,64469,64470,64471,64472,64473,64474,64475,64476,64477,64478,64479,64480, +64481,64482,64483,64484,64485,64486,64487,64488,64489,64490,64491,64492,64493, +64494,64495,64496,64497,64498,64499,64500,64501,64502,64503,64504,64505,64506, +64507,64508,64509,64510,64673,64674,64675,64676,64677,64678,64679,64680,64681, +64682,64683,64684,64685,64686,64687,64688,64689,64690,64691,64692,64693,64694, +64695,64696,64697,64698,64699,64700,64701,64702,64703,64704,64705,64706,64707, +64708,64709,64710,64711,64712,64713,64714,64715,64716,64717,64718,64719,64720, +64721,64722,64723,64724,64725,64726,64727,64728,64729,64730,64731,64732,64733, +64734,64735,64736,64737,64738,64739,64740,64741,64742,64743,64744,64745,64746, +64747,64748,64749,64750,64751,64752,64753,64754,64755,64756,64757,64758,64759, +64760,64761,64762,64763,64764,64765,64766,64929,64930,64931,64932,64933,64934, +64935,64936,64937,64938,64939,64940,64941,64942,64943,64944,64945,64946,64947, +64948,64949,64950,64951,64952,64953,64954,64955,64956,64957,64958,64959,64960, +64961,64962,64963,64964,64965,64966,64967,64968,64969,64970,64971,64972,64973, +64974,64975,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986, +64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999, +65000,65001,65002,65003,65004,65005,65006,65007,65008,65009,65010,65011,65012, +65013,65014,65015,65016,65017,65018,65019,65020,65021,65022,65185,65186,65187, +65188,65189,65190,65191,65192,65193,65194,65195,65196,65197,65198,65199,65200, +65201,65202,65203,65204,65205,65206,65207,65208,65209,65210,65211,65212,65213, +65214,65215,65216,65217,65218,65219,65220,65221,65222,65223,65224,65225,65226, +65227,65228,65229,65230,65231,65232,65233,65234,65235,65236,65237,65238,65239, +65240,65241,65242,65243,65244,65245,65246,65247,65248,65249,65250,65251,65252, +65253,65254,65255,65256,65257,65258,65259,65260,65261,65262,65263,65264,65265, +65266,65267,65268,65269,65270,65271,65272,65273,65274,65275,65276,65277,65278, +41280,41281,41282,41283,41284,41285,41286,41287,41288,41289,41290,41291,41292, +41293,41294,41295,41296,41297,41298,41299,41300,41301,41302,41303,41304,41305, +41306,41307,41308,41309,41310,41311,41312,41313,41314,41315,41316,41317,41318, +41319,41320,41321,41322,41323,41324,41325,41326,41327,41328,41329,41330,41331, +41332,41333,41334,41335,41336,41337,41338,41339,41340,41341,41342,41344,41345, +41346,41347,41348,41349,41350,41351,41352,41353,41354,41355,41356,41357,41358, +41359,41360,41361,41362,41363,41364,41365,41366,41367,41368,41369,41370,41371, +41372,41373,41374,41375,41376,41536,41537,41538,41539,41540,41541,41542,41543, +41544,41545,41546,41547,41548,41549,41550,41551,41552,41553,41554,41555,41556, +41557,41558,41559,41560,41561,41562,41563,41564,41565,41566,41567,41568,41569, +41570,41571,41572,41573,41574,41575,41576,41577,41578,41579,41580,41581,41582, +41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593,41594,41595, +41596,41597,41598,41600,41601,41602,41603,41604,41605,41606,41607,41608,41609, +41610,41611,41612,41613,41614,41615,41616,41617,41618,41619,41620,41621,41622, +41623,41624,41625,41626,41627,41628,41629,41630,41631,41632,41792,41793,41794, +41795,41796,41797,41798,41799,41800,41801,41802,41803,41804,41805,41806,41807, +41808,41809,41810,41811,41812,41813,41814,41815,41816,41817,41818,41819,41820, +41821,41822,41823,41824,41825,41826,41827,41828,41829,41830,41831,41832,41833, +41834,41835,41836,41837,41838,41839,41840,41841,41842,41843,41844,41845,41846, +41847,41848,41849,41850,41851,41852,41853,41854,41856,41857,41858,41859,41860, +41861,41862,41863,41864,41865,41866,41867,41868,41869,41870,41871,41872,41873, +41874,41875,41876,41877,41878,41879,41880,41881,41882,41883,41884,41885,41886, +41887,41888,42048,42049,42050,42051,42052,42053,42054,42055,42056,42057,42058, +42059,42060,42061,42062,42063,42064,42065,42066,42067,42068,42069,42070,42071, +42072,42073,42074,42075,42076,42077,42078,42079,42080,42081,42082,42083,42084, +42085,42086,42087,42088,42089,42090,42091,42092,42093,42094,42095,42096,42097, +42098,42099,42100,42101,42102,42103,42104,42105,42106,42107,42108,42109,42110, +42112,42113,42114,42115,42116,42117,42118,42119,42120,42121,42122,42123,42124, +42125,42126,42127,42128,42129,42130,42131,42132,42133,42134,42135,42136,42137, +42138,42139,42140,42141,42142,42143,42144,42304,42305,42306,42307,42308,42309, +42310,42311,42312,42313,42314,42315,42316,42317,42318,42319,42320,42321,42322, +42323,42324,42325,42326,42327,42328,42329,42330,42331,42332,42333,42334,42335, +42336,42337,42338,42339,42340,42341,42342,42343,42344,42345,42346,42347,42348, +42349,42350,42351,42352,42353,42354,42355,42356,42357,42358,42359,42360,42361, +42362,42363,42364,42365,42366,42368,42369,42370,42371,42372,42373,42374,42375, +42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,42386,42387,42388, +42389,42390,42391,42392,42393,42394,42395,42396,42397,42398,42399,42400,42560, +42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571,42572,42573, +42574,42575,42576,42577,42578,42579,42580,42581,42582,42583,42584,42585,42586, +42587,42588,42589,42590,42591,42592,42593,42594,42595,42596,42597,42598,42599, +42600,42601,42602,42603,42604,42605,42606,42607,42608,42609,42610,42611,42612, +42613,42614,42615,42616,42617,42618,42619,42620,42621,42622,42624,42625,42626, +42627,42628,42629,42630,42631,42632,42633,42634,42635,42636,42637,42638,42639, +42640,42641,42642,42643,42644,42645,42646,42647,42648,42649,42650,42651,42652, +42653,42654,42655,42656,42816,42817,42818,42819,42820,42821,42822,42823,42824, +42825,42826,42827,42828,42829,42830,42831,42832,42833,42834,42835,42836,42837, +42838,42839,42840,42841,42842,42843,42844,42845,42846,42847,42848,42849,42850, +42851,42852,42853,42854,42855,42856,42857,42858,42859,42860,42861,42862,42863, +42864,42865,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876, +42877,42878,42880,42881,42882,42883,42884,42885,42886,42887,42888,42889,42890, +42891,42892,42893,42894,42895,42896,42897,42898,42899,42900,42901,42902,42903, +42904,42905,42906,42907,42908,42909,42910,42911,42912,41643,41644,41645,41646, +41647,41648,N,41700,41711,41712,41725,41726,42228,42229,42230,42231,42232, +42233,42234,42235,42236,42237,42238,42487,42488,42489,42490,42491,42492,42493, +42494,42681,42682,42683,42684,42685,42686,42687,42688,42713,42714,42715,42716, +42717,42718,42719,42732,42733,42739,42742,42743,42744,42745,42746,42747,42748, +42749,42750,42946,42947,42948,42949,42950,42951,42952,42953,42954,42955,42956, +42957,42958,42959,42960,42994,42995,42996,42997,42998,42999,43000,43001,43002, +43003,43004,43005,43006,43158,43159,43160,43161,43162,43163,43164,43165,43166, +43167,43168,43196,N,43201,43202,43203,43204,43242,43243,43244,43245,43246, +43247,43248,43249,43250,43251,43252,43253,43254,43255,43256,43257,43258,43259, +43260,43261,43262,43352,43355,43357,43358,43359,N,N,N,N,N,N,N,N,N,N,N,N,N, +43415,43416,43417,43418,43419,43420,43421,43422,43423,43424,43425,43426,43427, +43504,43505,43506,43507,43508,43509,43510,43511,43512,43513,43514,43515,43516, +43517,43518,55290,55291,55292,55293,55294,N,65105,65106,65107,N,N,N,N,N,65113, +N,N,N,N,N,N,N,65121,N,N,N,N,65126,65127,N,N,N,N,65132,65133,N,N,N,N,N,N,N,N, +65142,N,N,N,N,N,N,N,65150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65168,65169,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,65184, +}; + +static const struct unim_index gb18030ext_encmap[256] = { +{0,0,0},{__gb18030ext_encmap+0,249,249},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+1,172,172 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+2,129,202},{ +__gb18030ext_encmap+76,240,251},{__gb18030ext_encmap+88,62,62},{0,0,0},{0,0,0 +},{0,0,0},{__gb18030ext_encmap+89,71,115},{__gb18030ext_encmap+134,158,158},{ +__gb18030ext_encmap+135,14,26},{0,0,0},{0,0,0},{__gb18030ext_encmap+148,24,223 +},{__gb18030ext_encmap+348,115,115},{__gb18030ext_encmap+349,78,78},{ +__gb18030ext_encmap+350,110,224},{0,0,0},{0,0,0},{0,0,0},{__gb18030ext_encmap+ +465,86,86},{__gb18030ext_encmap+466,95,95},{0,0,0},{__gb18030ext_encmap+467, +55,221},{__gb18030ext_encmap+634,214,214},{0,0,0},{__gb18030ext_encmap+635,76, +97},{__gb18030ext_encmap+657,35,141},{0,0,0},{__gb18030ext_encmap+764,71,183}, +{0,0,0},{0,0,0},{__gb18030ext_encmap+877,119,163},{__gb18030ext_encmap+922,19, +174},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{__gb18030ext_encmap+1078,0,255},{__gb18030ext_encmap+1334,0,255 +},{__gb18030ext_encmap+1590,0,255},{__gb18030ext_encmap+1846,0,255},{ +__gb18030ext_encmap+2102,0,255},{__gb18030ext_encmap+2358,0,255},{ +__gb18030ext_encmap+2614,0,255},{__gb18030ext_encmap+2870,0,255},{ +__gb18030ext_encmap+3126,0,100},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + + +static const struct _gb18030_to_unibmp_ranges { + Py_UCS4 first, last; + DBCHAR base; +} gb18030_to_unibmp_ranges[] = { +{128,163,0},{165,166,36},{169,175,38},{178,182,45},{184,214,50},{216,223,81},{ +226,231,89},{235,235,95},{238,241,96},{244,246,100},{248,248,103},{251,251,104 +},{253,256,105},{258,274,109},{276,282,126},{284,298,133},{300,323,148},{325, +327,172},{329,332,175},{334,362,179},{364,461,208},{463,463,306},{465,465,307 +},{467,467,308},{469,469,309},{471,471,310},{473,473,311},{475,475,312},{477, +504,313},{506,592,341},{594,608,428},{610,710,443},{712,712,544},{716,728,545 +},{730,912,558},{930,930,741},{938,944,742},{962,962,749},{970,1024,750},{1026 +,1039,805},{1104,1104,819},{1106,8207,820},{8209,8210,7922},{8215,8215,7924},{ +8218,8219,7925},{8222,8228,7927},{8231,8239,7934},{8241,8241,7943},{8244,8244, +7944},{8246,8250,7945},{8252,8363,7950},{8365,8450,8062},{8452,8452,8148},{ +8454,8456,8149},{8458,8469,8152},{8471,8480,8164},{8482,8543,8174},{8556,8559, +8236},{8570,8591,8240},{8596,8597,8262},{8602,8711,8264},{8713,8718,8374},{ +8720,8720,8380},{8722,8724,8381},{8726,8729,8384},{8731,8732,8388},{8737,8738, +8390},{8740,8740,8392},{8742,8742,8393},{8748,8749,8394},{8751,8755,8396},{ +8760,8764,8401},{8766,8775,8406},{8777,8779,8416},{8781,8785,8419},{8787,8799, +8424},{8802,8803,8437},{8808,8813,8439},{8816,8852,8445},{8854,8856,8482},{ +8858,8868,8485},{8870,8894,8496},{8896,8977,8521},{8979,9311,8603},{9322,9331, +8936},{9372,9471,8946},{9548,9551,9046},{9588,9600,9050},{9616,9618,9063},{ +9622,9631,9066},{9634,9649,9076},{9652,9659,9092},{9662,9669,9100},{9672,9674, +9108},{9676,9677,9111},{9680,9697,9113},{9702,9732,9131},{9735,9736,9162},{ +9738,9791,9164},{9793,9793,9218},{9795,11904,9219},{11906,11907,11329},{11909, +11911,11331},{11913,11914,11334},{11917,11926,11336},{11928,11942,11346},{ +11944,11945,11361},{11947,11949,11363},{11951,11954,11366},{11956,11957,11370 +},{11960,11962,11372},{11964,11977,11375},{11979,12271,11389},{12284,12287, +11682},{12292,12292,11686},{12312,12316,11687},{12319,12320,11692},{12330, +12349,11694},{12351,12352,11714},{12436,12442,11716},{12447,12448,11723},{ +12535,12539,11725},{12543,12548,11730},{12586,12831,11736},{12842,12848,11982 +},{12850,12962,11989},{12964,13197,12102},{13200,13211,12336},{13215,13216, +12348},{13218,13251,12350},{13253,13261,12384},{13263,13264,12393},{13267, +13268,12395},{13270,13382,12397},{13384,13426,12510},{13428,13725,12553},{ +13727,13837,12851},{13839,13849,12962},{13851,14615,12973},{14617,14701,13738 +},{14703,14798,13823},{14801,14814,13919},{14816,14962,13933},{14964,15181, +14080},{15183,15469,14298},{15471,15583,14585},{15585,16469,14698},{16471, +16734,15583},{16736,17206,15847},{17208,17323,16318},{17325,17328,16434},{ +17330,17372,16438},{17374,17621,16481},{17623,17995,16729},{17997,18016,17102 +},{18018,18210,17122},{18212,18216,17315},{18218,18299,17320},{18301,18316, +17402},{18318,18758,17418},{18760,18809,17859},{18811,18812,17909},{18814, +18817,17911},{18820,18820,17915},{18823,18842,17916},{18844,18846,17936},{ +18848,18869,17939},{18872,19574,17961},{19576,19614,18664},{19620,19730,18703 +},{19738,19885,18814},{19887,19967,18962},{40870,55295,19043},{59244,59244, +33469},{59336,59336,33470},{59367,59379,33471},{59413,59413,33484},{59417, +59421,33485},{59423,59429,33490},{59431,59434,33497},{59437,59440,33501},{ +59443,59450,33505},{59452,59458,33513},{59460,59475,33520},{59478,59491,33536 +},{59493,63787,33550},{63789,63864,37845},{63866,63892,37921},{63894,63974, +37948},{63976,63984,38029},{63986,64011,38038},{64016,64016,38064},{64018, +64018,38065},{64021,64023,38066},{64025,64030,38069},{64034,64034,38075},{ +64037,64038,38076},{64042,65071,38078},{65074,65074,39108},{65093,65096,39109 +},{65107,65107,39113},{65112,65112,39114},{65127,65127,39115},{65132,65280, +39116},{65375,65503,39265},{65510,65535,39394},{0,0,39420}}; diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_hk.h b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_hk.h index 1b1d70e7c17..f6069fb26ea 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_hk.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_hk.h @@ -1,2378 +1,2378 @@ -static const ucs2_t __big5hkscs_decmap[6219] = { -17392,19506,17923,17830,17784,29287,19831,17843,31921,19682,31941,15253,18230, -18244,19527,19520,17087,13847,29522,28299,28882,19543,41809,18255,17882,19589, -31852,19719,19108,18081,27427,29221,23124,6755,15878,16225,26189,22267,U, -32149,22813,35769,15860,38708,31727,23515,7518,23204,13861,40624,23249,23479, -23804,26478,34195,39237,29793,29853,12736,12737,12738,12739,12740,268,12741, -209,205,12742,12743,203,8168,12744,202,12745,12746,12747,12748,270,12749, -12750,256,193,461,192,274,201,282,200,332,211,465,210,U,7870,U,7872,202,257, -225,462,224,593,275,233,283,232,299,237,464,236,333,243,466,242,363,250,468, -249,470,472,474,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,476,252,U,7871,U,7873,234,609,9178,9179,41897,4421,U,25866,U,U,20029, -28381,40270,37343,U,U,30517,25745,20250,20264,20392,20822,20852,20892,20964, -21153,21160,21307,21326,21457,21464,22242,22768,22788,22791,22834,22836,23398, -23454,23455,23706,24198,24635,25993,26622,26628,26725,27982,28860,30005,32420, -32428,32442,32455,32463,32479,32518,32567,33402,33487,33647,35270,35774,35810, -36710,36711,36718,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,29713,31996,32205,26950,31433,21031,U,U,U,U,37260,30904,37214,32956,U, -36107,33014,2535,U,U,32927,40647,19661,40393,40460,19518,40438,28686,40458, -41267,13761,U,28314,33342,29977,U,18705,39532,39567,40857,31111,33900,7626, -1488,10982,20004,20097,20096,20103,20159,20203,20279,13388,20413,15944,20483, -20616,13437,13459,13477,20870,22789,20955,20988,20997,20105,21113,21136,21287, -13767,21417,13649,21424,13651,21442,21539,13677,13682,13953,21651,21667,21684, -21689,21712,21743,21784,21795,21800,13720,21823,13733,13759,21975,13765,32132, -21797,U,3138,3349,20779,21904,11462,14828,833,36422,19896,38117,16467,32958, -30586,11320,14900,18389,33117,27122,19946,25821,3452,4020,3285,4340,25741, -36478,3734,3083,3940,11433,33366,17619,U,3398,39501,33001,18420,20135,11458, -39602,14951,38388,16365,13574,21191,38868,30920,11588,40302,38933,U,17369, -24741,25780,21731,11596,11210,4215,14843,4207,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26330,26390,31136,25834,20562,3139,36456, -8609,35660,1841,U,18443,425,16378,22643,11661,U,17864,1276,24727,3916,3478, -21881,16571,17338,U,19124,10854,4253,33194,39157,3484,25465,14846,10101,36288, -22177,25724,15939,U,42497,3593,10959,11465,U,4296,14786,14738,14854,33435, -13688,24137,8391,22098,3889,11442,38688,13500,27709,20027,U,U,30068,11915, -8712,42587,36045,3706,3124,26652,32659,4303,10243,10553,13819,20963,3724,3981, -3754,16275,3888,3399,4431,3660,U,3755,2985,3400,4288,4413,16377,9878,25650, -4013,13300,30265,11214,3454,3455,11345,11349,14872,3736,4295,3886,42546,27472, -36050,36249,36042,38314,21708,33476,21945,U,40643,39974,39606,30558,11758, -28992,33133,33004,23580,25970,33076,14231,21343,32957,37302,3834,3599,3703, -3835,13789,19947,13833,3286,22191,10165,4297,3600,3704,4216,4424,33287,5205, -3705,20048,11684,23124,4125,4126,4341,4342,22428,3601,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30356,33485,4021,3707,20862,14083, -4022,4480,21208,41661,18906,6202,16759,33404,22681,21096,13850,22333,31666, -23400,18432,19244,40743,18919,39967,39821,23412,12605,22011,13810,22153,20008, -22786,7105,63608,38737,134,20059,20155,13630,23587,24401,24516,14586,25164, -25909,27514,27701,27706,28780,29227,20012,29357,18665,32594,31035,31993,32595, -25194,13505,U,25419,32770,32896,26130,26961,21341,34916,35265,30898,35744, -36125,38021,38264,38271,38376,36367,38886,39029,39118,39134,39267,38928,40060, -40479,40644,27503,63751,20023,135,38429,25143,38050,20539,28158,40051,40870, -15817,34959,16718,28791,23797,19232,20941,13657,23856,24866,35378,36775,37366, -29073,26393,29626,12929,41223,15499,6528,19216,30948,29698,20910,34575,16393, -27235,41658,16931,34319,2671,31274,39239,35562,38741,28749,21284,8318,37876, -30425,35299,40871,30685,20131,20464,20668,20015,20247,40872,21556,32139,22674, -22736,7606,24210,24217,24514,10002,25995,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13305,26905,27203,15459,27903,U,29184,17669, -29580,16091,18963,23317,29881,35715,23716,22165,31379,31724,31939,32364,33528, -34199,40873,34960,40874,36537,40875,36815,34143,39392,37409,40876,36281,5183, -16497,17058,23066,U,U,U,39016,26475,17014,22333,U,34262,18811,33471,28941, -19585,28020,23931,27413,28606,40877,40878,23446,40879,26343,32347,28247,31178, -15752,17603,12886,10134,17306,17718,U,23765,15130,35577,23672,15634,13649, -23928,40882,29015,17752,16620,7715,19575,14712,13386,420,27713,35532,20404, -569,22975,33132,38998,39162,24379,2975,U,8641,35181,16642,18107,36985,16135, -40883,41397,16632,14294,18167,27718,16764,34482,29695,17773,14548,21658,17761, -17691,19849,19579,19830,17898,16328,19215,13921,17630,17597,16877,23870,23880, -23894,15868,14351,23972,23993,14368,14392,24130,24253,24357,24451,14600,14612, -14655,14669,24791,24893,23781,14729,25015,25017,25039,14776,25132,25232,25317, -25368,14840,22193,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,14851,25570,25595,25607,25690,14923,25792,23829,22049,40863,14999, -25990,15037,26111,26195,15090,26258,15138,26390,15170,26532,26624,15192,26698, -26756,15218,15217,15227,26889,26947,29276,26980,27039,27013,15292,27094,15325, -27237,27252,27249,27266,15340,27289,15346,27307,27317,27348,27382,27521,27585, -27626,27765,27818,15563,27906,27910,27942,28033,15599,28068,28081,28181,28184, -28201,28294,35264,28347,28386,28378,40831,28392,28393,28452,28468,15686,16193, -28545,28606,15722,15733,29111,23705,15754,28716,15761,28752,28756,28783,28799, -28809,805,17345,13809,3800,16087,22462,28371,28990,22496,13902,27042,35817, -23412,31305,22753,38105,31333,31357,22956,31419,31408,31426,31427,29137,25741, -16842,31450,31453,31466,16879,21682,23553,31499,31573,31529,21262,23806,31650, -31599,33692,23476,27775,31696,33825,31634,U,23840,15789,23653,33938,31738,U, -31797,23745,31812,31875,18562,31910,26237,17784,31945,31943,31974,31860,31987, -31989,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -32359,17693,28228,32093,28374,29837,32137,32171,28981,32179,U,16471,24617, -32228,15635,32245,6137,32229,33645,U,24865,24922,32366,32402,17195,37996, -32295,32576,32577,32583,31030,25296,39393,32663,25425,32675,5729,104,17756, -14182,17667,33594,32762,25737,U,32776,32797,U,32815,41095,27843,32827,32828, -32865,10004,18825,26150,15843,26344,26405,32935,35400,33031,33050,22704,9974, -27775,25752,20408,25831,5258,33304,6238,27219,19045,19093,17530,33321,2829, -27218,15742,20473,5373,34018,33634,27402,18855,13616,6003,15864,33450,26907, -63892,16859,34123,33488,33562,3606,6068,14017,12669,13658,33403,33506,33560, -16011,28067,27397,27543,13774,15807,33565,21996,33669,17675,28069,33708,U, -33747,13438,28372,27223,34138,13462,28226,12015,33880,23524,33905,15827,17636, -27303,33866,15541,31064,U,27542,28279,28227,34014,U,33681,17568,33939,34020, -23697,16960,23744,17731,34100,23282,28313,17703,34163,17686,26559,34326,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34341,34363, -34241,28808,34306,5506,28877,63922,17770,34344,13896,6306,21495,29594,34430, -34673,41208,34798,11303,34737,34778,34831,22113,34412,26710,17935,34885,34886, -30176,15801,30180,34910,34972,18011,34996,34997,25537,35013,30583,30479,35207, -35210,U,U,35239,35260,35365,35303,31012,31421,35484,30611,37374,35472,31321, -31465,31546,16271,18195,31544,29052,35596,35615,21552,21861,35647,35660,35661, -35497,19066,35728,35739,35503,5855,17941,34895,35995,32084,32143,63956,14117, -32083,36054,32152,32189,36114,36099,6416,36059,28764,36113,19657,16080,36265, -32770,4116,18826,15228,33212,28940,31463,36525,36534,36547,37588,36633,36653, -33637,33810,36773,37635,41631,2640,36787,18730,35294,34109,15803,24312,12898, -36857,40980,34492,34049,8997,14720,28375,36919,34108,31422,36961,34156,34315, -37032,34579,37060,34534,37038,U,37223,15088,37289,37316,31916,35123,7817, -37390,27807,37441,37474,21945,U,35526,15515,35596,21979,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,3377,37676,37739,35553,35819, -28815,23235,35554,35557,18789,37444,35820,35897,35839,37747,37979,36540,38277, -38310,37926,38304,28662,17081,9850,34520,4732,15918,18911,27676,38523,38550, -16748,38563,28373,25050,38582,30965,35552,38589,21452,18849,27832,628,25616, -37039,37093,19153,6421,13066,38705,34370,38710,18959,17725,17797,19177,28789, -23361,38683,U,37333,38743,23370,37355,38751,37925,20688,12471,12476,38793, -38815,38833,38846,38848,38866,38880,21612,38894,29724,37939,U,38901,37917, -31098,19153,38964,38963,38987,39014,15118,29045,15697,1584,16732,22278,39114, -39095,39112,39111,19199,27943,5843,21936,39137,39142,39148,37752,39225,18985, -19314,38999,39173,39413,39436,39483,39440,39512,22309,14020,37041,39893,39648, -39650,39685,39668,19470,39700,39725,34304,20532,39732,27048,14531,12413,39760, -39744,40254,23109,6243,39822,16971,39938,39935,39948,40552,40404,40887,41362, -41387,41185,41251,41439,40318,40323,41268,40462,26760,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40388,8539,41363,41504,6459,41523, -40249,41145,41652,40592,40597,40606,40610,19764,40618,40623,17252,40641,15200, -14821,15645,20274,14270,35883,40706,40712,19350,37924,28066,40727,U,40761, -22175,22154,40773,39352,37003,38898,33919,40802,40809,31452,40846,29206,19390, -18805,18875,29047,18936,17224,19025,29598,35802,6394,31135,35198,36406,37737, -37875,35396,37612,37761,37835,35180,17593,29207,16107,30578,31299,28880,17523, -17400,29054,6127,28835,6334,13721,16071,6277,21551,6136,14114,5883,6201,14049, -6004,6353,24395,14115,5824,22363,18981,5118,4776,5062,5302,34051,13990,U, -33877,18836,29029,15921,21852,16123,28754,17652,14062,39325,28454,26617,14131, -15381,15847,22636,6434,26640,16471,14143,16609,16523,16655,27681,21707,22174, -26289,22162,4063,2984,3597,37830,35603,37788,20216,20779,14361,17462,20156, -1125,895,20299,20362,22097,23144,427,971,14745,778,1044,13365,20265,704,36531, -629,35546,524,20120,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,20685,20749,20386,20227,18958,16010,20290,20526,20588,20609,20428, -20453,20568,20732,U,U,U,U,28278,13717,15929,16063,28018,6276,16009,20904, -20931,1504,17629,1187,1170,1169,36218,35484,1806,21081,21156,2163,21217,U, -18042,29068,17292,3104,18860,4324,27089,3613,U,16094,29849,29716,29782,29592, -19342,19132,16525,21456,13700,29199,16585,21940,837,21709,3014,22301,37469, -38644,37734,22493,22413,22399,13886,22731,23193,35398,5882,5999,5904,23084, -22968,37519,23166,23247,23058,22854,6643,6241,17045,14069,27909,29763,23073, -24195,23169,35799,1043,37856,29836,4867,28933,18802,37896,35323,37821,14240, -23582,23710,24158,24136,6550,6524,15086,24269,23375,6403,6404,14081,6304, -14045,5886,14035,33066,35399,7610,13426,35240,24332,24334,6439,6059,23147, -5947,23364,34324,30205,34912,24702,10336,9771,24539,16056,9647,9662,37000, -28531,25024,62,70,9755,24985,24984,24693,11419,11527,18132,37197,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25713,18021,11114, -14889,11042,13392,39146,11896,25399,42075,25782,25393,25553,18915,11623,25252, -11425,25659,25963,26994,15348,12430,12973,18825,12971,21773,13024,6361,37951, -26318,12937,12723,15072,16784,21892,35618,21903,5884,21851,21541,30958,12547, -6186,12852,13412,12815,12674,17097,26254,27940,26219,19347,26160,30832,7659, -26211,13010,13025,26142,22642,14545,14394,14268,15257,14242,13310,29904,15254, -26511,17962,26806,26654,15300,27326,14435,14293,17543,27187,27218,27337,27397, -6418,25873,26776,27212,15319,27258,27479,16320,15514,37792,37618,35818,35531, -37513,32798,35292,37991,28069,28427,18924,U,16255,15759,28164,16444,23101, -28170,22599,27940,30786,28987,17178,17014,28913,29264,29319,29332,18319,18213, -20857,19108,1515,29818,16120,13919,19018,18711,24545,16134,16049,19167,35875, -16181,24743,16115,29900,29756,37767,29751,17567,28138,17745,30083,16227,19673, -19718,16216,30037,30323,42438,15129,29800,35532,18859,18830,15099,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15821,19022,16127, -18885,18675,37370,22322,37698,35555,6244,20703,21025,20967,30584,12850,30478, -30479,30587,18071,14209,14942,18672,29752,29851,16063,19130,19143,16584,19094, -25006,37639,21889,30750,30861,30856,30930,29648,31065,30529,22243,16654,U, -33942,31141,27181,16122,31290,31220,16750,5862,16690,37429,31217,3404,18828, -665,15802,5998,13719,21867,13680,13994,468,3085,31458,23129,9973,23215,23196, -23053,603,30960,23082,23494,31486,16889,31837,31853,16913,23475,24252,24230, -31949,18937,6064,31886,31868,31918,27314,32220,32263,32211,32590,25185,24924, -31560,32151,24194,17002,27509,2326,26582,78,13775,22468,25618,25592,18786, -32733,31527,2092,23273,23875,31500,24078,39398,34373,39523,27164,13375,14818, -18935,26029,39455,26016,33920,28967,27857,17642,33079,17410,32966,33033,33090, -26548,39107,27202,33378,33381,27217,33875,28071,34320,29211,23174,16767,6208, -23339,6305,23268,6360,34464,63932,15759,34861,29730,23042,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34926,20293,34951,35007,35046, -35173,35149,22147,35156,30597,30596,35829,35801,35740,35321,16045,33955,18165, -18127,14322,35389,35356,37960,24397,37419,17028,26068,28969,28868,6213,40301, -35999,36073,32220,22938,30659,23024,17262,14036,36394,36519,19465,36656,36682, -17140,27736,28603,8993,18587,28537,28299,6106,39913,14005,18735,37051,U,21873, -18694,37307,37892,35403,16482,35580,37927,35869,35899,34021,35371,38297,38311, -38295,38294,36148,29765,16066,18687,19010,17386,16103,12837,38543,36583,36454, -36453,16076,18925,19064,16366,29714,29803,16124,38721,37040,26695,18973,37011, -22495,U,37736,35209,35878,35631,25534,37562,23313,35689,18748,29689,16923, -38811,38769,39224,3878,24001,35781,19122,38943,38106,37622,38359,37349,17600, -35664,19047,35684,39132,35397,16128,37418,18725,33812,39227,39245,31494,15869, -39323,19311,39338,39516,35685,22728,27279,39457,23294,39471,39153,19344,39240, -39356,19389,19351,37757,22642,4866,22562,18872,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5352,30788,10015,15800,26821,15741, -37976,14631,24912,10113,10603,24839,40015,40019,40059,39989,39952,39807,39887, -40493,39839,41461,41214,40225,19630,16644,40472,19632,40204,41396,41197,41203, -39215,40357,33981,28178,28639,27522,34300,17715,28068,28292,28144,33824,34286, -28160,14295,24676,31202,13724,13888,18733,18910,15714,37851,37566,37704,703, -30905,37495,37965,20452,13376,36964,21853,30781,30804,30902,30795,5975,12745, -18753,13978,20338,28634,28633,U,28702,21524,16821,22459,22771,22410,40214, -22487,28980,13487,16812,29163,27712,20375,U,6069,35401,24844,23246,23051, -17084,17544,14124,19323,35324,37819,37816,6358,3869,33906,27840,5139,17146, -11302,17345,22932,15799,26433,32168,24923,24740,18873,18827,35322,37605,29666, -16105,29876,35683,6303,16097,19123,27352,29683,29691,16086,19006,19092,6105, -19046,935,5156,18917,29768,18710,28837,18806,37508,29670,37727,1278,37681, -35534,35350,37766,35815,21973,18741,35458,29035,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,18755,3327,22180,1562,3051,3256,21762, -31172,6138,32254,5826,19024,6226,17710,37889,14090,35520,18861,22960,6335, -6275,29828,23201,14050,15707,14000,37471,23161,35457,6242,37748,15565,2740, -19094,14730,20724,15721,15692,5020,29045,17147,33304,28175,37092,17643,27991, -32335,28775,27823,15574,16365,15917,28162,28428,15727,1013,30033,14012,13512, -18048,16090,18545,22980,37486,18750,36673,35868,27584,22546,22472,14038,5202, -28926,17250,19057,12259,4784,9149,26809,26983,5016,13541,31732,14047,35459, -14294,13306,19615,27162,13997,27831,33854,17631,17614,27942,27985,27778,28638, -28439,28937,33597,5946,33773,27776,28755,6107,22921,23170,6067,23137,23153, -6405,16892,14125,23023,5948,14023,29070,37776,26266,17061,23150,23083,17043, -27179,16121,30518,17499,17098,28957,16985,35297,20400,27944,23746,17614,32333, -17341,27148,16982,4868,28838,28979,17385,15781,27871,63525,19023,32357,23019, -23855,15859,24412,19037,6111,32164,33830,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21637,15098,13056,532,22398,2261,1561,16357, -8094,41654,28675,37211,23920,29583,31955,35417,37920,20424,32743,29389,29456, -31476,29496,29497,22262,29505,29512,16041,31512,36972,29173,18674,29665,33270, -16074,30476,16081,27810,22269,29721,29726,29727,16098,16112,16116,16122,29907, -16142,16211,30018,30061,30066,30093,16252,30152,30172,16320,30285,16343,30324, -16348,30330,20316,29064,22051,35200,22633,16413,30531,16441,26465,16453,13787, -30616,16490,16495,23646,30654,30667,22770,30744,28857,30748,16552,30777,30791, -30801,30822,33864,21813,31027,26627,31026,16643,16649,31121,31129,36795,31238, -36796,16743,31377,16818,31420,33401,16836,31439,31451,16847,20001,31586,31596, -31611,31762,31771,16992,17018,31867,31900,17036,31928,17044,31981,36755,28864, -3279,32207,32212,32208,32253,32686,32692,29343,17303,32800,32805,31545,32814, -32817,32852,15820,22452,28832,32951,33001,17389,33036,29482,33038,33042,30048, -33044,17409,15161,33110,33113,33114,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,17427,22586,33148,33156,17445,33171,17453,33189, -22511,33217,33252,33364,17551,33446,33398,33482,33496,33535,17584,33623,38505, -27018,33797,28917,33892,24803,33928,17668,33982,34017,34040,34064,34104,34130, -17723,34159,34160,34272,17783,34418,34450,34482,34543,38469,34699,17926,17943, -34990,35071,35108,35143,35217,31079,35369,35384,35476,35508,35921,36052,36082, -36124,18328,22623,36291,18413,20206,36410,21976,22356,36465,22005,36528,18487, -36558,36578,36580,36589,36594,36791,36801,36810,36812,36915,39364,18605,39136, -37395,18718,37416,37464,37483,37553,37550,37567,37603,37611,37619,37620,37629, -37699,37764,37805,18757,18769,40639,37911,21249,37917,37933,37950,18794,37972, -38009,38189,38306,18855,38388,38451,18917,26528,18980,38720,18997,38834,38850, -22100,19172,24808,39097,19225,39153,22596,39182,39193,20916,39196,39223,39234, -39261,39266,19312,39365,19357,39484,39695,31363,39785,39809,39901,39921,39924, -19565,39968,14191,7106,40265,39994,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,40702,22096,40339,40381,40384,40444,38134,36790, -40571,40620,40625,40637,40646,38108,40674,40689,40696,31432,40772,148,695,928, -26906,38083,22956,1239,22592,38081,14265,1493,1557,1654,5818,22359,29043,2754, -2765,3007,21610,63547,3019,21662,3067,3131,3155,3173,3196,24807,3213,22138, -3253,3293,3309,3439,3506,3528,26965,39983,34725,3588,3598,3799,3984,3885,3699, -23584,4028,24075,4188,4175,4214,26398,4219,4232,4246,13895,4287,4307,4399, -4411,21348,33965,4835,4981,4918,35713,5495,5657,6083,6087,20088,28859,6189, -6506,6701,6725,7210,7280,7340,7880,25283,7893,7957,29080,26709,8261,27113, -14024,8828,9175,9210,10026,10353,10575,33533,10599,10643,10965,35237,10984, -36768,11022,38840,11071,38983,39613,11340,U,11400,11447,23528,11528,11538, -11703,11669,11842,12148,12236,12339,12390,13087,13278,24497,26184,26303,31353, -13671,13811,U,18874,U,13850,14102,U,838,22709,26382,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26904,15015,30295,24546,15889,16057, -30206,8346,18640,19128,16665,35482,17134,17165,16443,17204,17302,19013,1482, -20946,1553,22943,7848,15294,15615,17412,17622,22408,18036,14747,18223,34280, -39369,14178,8643,35678,35662,U,18450,18683,18965,29193,19136,3192,22885,20133, -20358,1913,36570,20524,21135,22335,29041,21145,21529,16202,19111,21948,21574, -21614,27474,U,13427,21823,30258,21854,18200,21858,21862,22471,18751,22621, -20582,13563,13260,U,22787,18300,35144,23214,23433,23558,7568,22433,29009,U, -24834,31762,36950,25010,20378,35682,25602,25674,23899,27639,U,25732,6428, -35562,18934,25736,16367,25874,19392,26047,26293,10011,37989,22497,24981,23079, -63693,U,22201,17697,26364,20074,18740,38486,28047,27837,13848,35191,26521, -26734,25617,26718,U,26823,31554,37056,2577,26918,U,26937,31301,U,27130,39462, -27181,13919,25705,33,31107,27188,27483,23852,13593,U,27549,18128,27812,30011, -34917,28078,22710,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,14108,9613,28747,29133,15444,29312,29317,37505,8570,29323,37680,29414, -18896,27705,38047,29776,3832,34855,35061,10534,33907,6065,28344,18986,6176, -14756,14009,U,U,17727,26294,40109,39076,35139,30668,30808,22230,16607,5642, -14753,14127,33000,5061,29101,33638,31197,37288,U,19639,28847,35243,31229, -31242,31499,32102,16762,31555,31102,32777,28597,41695,27139,33560,21410,28167, -37823,26678,38749,33135,32803,27061,5101,12847,32840,23941,35888,32899,22293, -38947,35145,23979,18824,26046,27093,21458,19109,16257,15377,26422,32912,33012, -33070,8097,33103,33161,33199,33306,33542,33583,33674,13770,33896,34474,18682, -25574,35158,30728,37461,35256,17394,35303,17375,35304,35654,35796,23032,35849, -U,36805,37100,U,37136,37180,15863,37214,19146,36816,29327,22155,38119,38377, -38320,38328,38706,39121,39241,39274,39363,39464,39694,40282,40347,32415,40696, -40739,19620,38215,41619,29090,41727,19857,36882,42443,19868,3228,36798,21953, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36794, -9392,36793,19091,17673,32383,28502,27313,20202,13540,35628,30877,14138,36480, -6133,32804,35692,35737,31294,26287,15851,30293,15543,22069,22870,20122,24193, -25176,22207,3693,36366,23405,16008,19614,25566,U,6134,6267,25904,22061,23626, -21530,21265,15814,40344,19581,22050,22046,32585,24280,22901,15680,34672,19996, -4074,3401,14010,33047,40286,36120,30267,40005,30286,30649,37701,21554,33096, -33527,22053,33074,33816,32957,21994,31074,22083,21526,3741,13774,22021,22001, -26353,33506,13869,30004,22000,21946,21655,21874,3137,3222,24272,20808,3702, -11362,3746,40619,32090,21982,4213,25245,38765,21652,36045,29174,37238,25596, -25529,25598,21865,11075,40050,11955,20890,13535,3495,20903,21581,21790,21779, -30310,36397,26762,30129,32950,34820,34694,35015,33206,33820,4289,17644,29444, -18182,23440,33547,26771,22139,9972,32047,16803,32115,28368,29366,37232,4569, -37384,15612,42665,3756,3833,29286,7330,18254,20418,32761,4075,16634,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40029,25887,11680, -18675,18400,40316,4076,3594,U,30115,4077,U,24648,4487,29091,32398,40272,19994, -19972,13687,23309,27826,21351,13996,14812,21373,13989,17944,22682,19310,33325, -21579,22442,23189,2425,U,14930,9317,29556,40620,19721,39917,15614,40752,19547, -20393,38302,40926,33884,15798,29362,26547,14112,25390,32037,16119,15916,14890, -36872,21196,15988,13946,17897,1166,30272,23280,3766,30842,32558,22695,16575, -22140,39819,23924,30292,42036,40581,19681,U,14331,24857,12506,17394,U,22109, -4777,22439,18787,40454,21044,28846,13741,U,40316,31830,39737,22494,5996,23635, -25811,38096,25397,29028,34477,3368,27938,19170,3441,U,20990,7951,23950,38659, -7633,40577,36940,31519,39682,23761,31651,25192,25397,39679,31695,39722,31870, -U,31810,31878,39957,31740,39689,U,39963,18750,40794,21875,23491,20477,40600, -20466,21088,15878,21201,22375,20566,22967,24082,38856,40363,36700,21609,38836, -39232,38842,21292,24880,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,26924,21466,39946,40194,19515,38465,27008,20646,30022,5997, -39386,21107,U,37209,38529,37212,U,37201,36503,25471,27939,27338,22033,37262, -30074,25221,1020,29519,31856,23585,15613,U,18713,30422,39837,20010,3284,33726, -34882,U,23626,27072,U,22394,21023,24053,20174,27697,498,20281,21660,21722, -21146,36226,13822,U,13811,U,27474,37244,40869,39831,38958,39092,39610,40616, -40580,29050,31508,U,27642,34840,32632,U,22048,42570,36471,40787,U,36308,36431, -40476,36353,25218,33661,36392,36469,31443,19063,31294,30936,27882,35431,30215, -35418,40742,27854,34774,30147,41650,30803,63552,36108,29410,29553,35629,29442, -29937,36075,19131,34351,24506,34976,17591,U,6203,28165,U,35454,9499,U,24829, -30311,39639,40260,37742,39823,34805,U,U,36087,29484,38689,39856,13782,29362, -19463,31825,39242,24921,24921,19460,40598,24957,U,22367,24943,25254,25145,U, -14940,25058,21418,13301,25444,26626,13778,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23895,35778,36826,36409,U,20697,7494,30982, -21298,38456,3899,16485,U,30718,U,31938,24346,31962,31277,32870,32867,32077, -29957,29938,35220,33306,26380,32866,29830,32859,29936,33027,30500,35209,26572, -30035,28369,34729,34766,33224,34700,35401,36013,35651,30507,29944,34010,13877, -27058,36262,U,35241,U,28089,34753,16401,29927,15835,29046,24740,24988,15569,U, -24695,U,32625,35629,U,24809,19326,21024,15384,15559,24279,30294,21809,6468, -4862,39171,28124,28845,23745,25005,35343,13943,238,26694,20238,17762,23327, -25420,40784,40614,25195,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321, -9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,8560,8561,8562,8563,8564, -8565,8566,8567,8568,8569,20022,20031,20101,20128,20866,20886,20907,21241, -21304,21353,21430,22794,23424,24027,12083,24191,U,24400,24417,25908,U,30098,U, -36789,U,168,710,12541,12542,12445,12446,U,U,12293,12294,12295,12540,65339, -65341,10045,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363, -12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376, -12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389, -12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402, -12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415, -12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428, -12429,12430,12431,12432,12433,12434,12435,12449,12450,12451,12452,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12453,12454,12455, -12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468, -12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481, -12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494, -12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507, -12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520, -12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533, -12534,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052, -1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067, -1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081, -1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, -1097,1098,1099,1100,1101,1102,1103,8679,8632,8633,12751,204,20058,138,20994, -17553,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -40880,20872,40881,30215,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,65506,65508,65287,65282,12849,8470,8481,12443,12444, -11904,11908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943, -11946,11948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991, -11998,12003,U,U,U,643,592,603,596,629,339,248,331,650,618,30849,37561,35023, -22715,24658,31911,23290,9556,9574,9559,9568,9580,9571,9562,9577,9565,9554, -9572,9557,9566,9578,9569,9560,9575,9563,9555,9573,9558,9567,9579,9570,9561, -9576,9564,9553,9552,9581,9582,9584,9583,65517,1351,37595,1503,16325,34124, -17077,29679,20917,13897,18754,35300,37700,6619,33518,15560,30780,26436,25311, -18739,35242,672,27571,4869,20395,9453,20488,27945,31364,13824,19121,9491,U, -894,24484,896,839,28379,1055,U,20737,13434,20750,39020,14147,33814,18852,1159, -20832,13236,20842,3071,8444,741,9520,1422,12851,6531,23426,34685,1459,15513, -20914,20920,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,40244,20937,20943,20945,15580,20947,19110,20915,20962,21314,20973,33741, -26942,14125,24443,21003,21030,21052,21173,21079,21140,21177,21189,31765,34114, -21216,34317,27411,U,35550,21833,28377,16256,2388,16364,21299,U,3042,27851, -5926,26651,29653,24650,16042,14540,5864,29149,17570,21357,21364,34475,21374,U, -5526,5651,30694,21395,35483,21408,21419,21422,29607,22386,16217,29596,21441, -21445,27721,20041,22526,21465,15019,2959,21472,16363,11683,21494,3191,21523, -28793,21803,26199,27995,21613,27475,3444,21853,21647,21668,18342,5901,3805, -15796,3405,35260,9880,21831,19693,21551,29719,21894,21929,U,6359,16442,17746, -17461,26291,4276,22071,26317,12938,26276,26285,22093,22095,30961,22257,38791, -21502,22272,22255,22253,35686,13859,4687,22342,16805,27758,28811,22338,14001, -27774,22502,5142,22531,5204,17251,22566,19445,22620,22698,13665,22752,22748, -4668,22779,23551,22339,41296,17016,37843,13729,22815,26790,14019,28249,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5694,23076, -21843,5778,34053,22985,3406,27777,27946,6108,23001,6139,6066,28070,28017,6184, -5845,23033,28229,23211,23139,14054,18857,U,14088,23190,29797,23251,28577,9556, -15749,6417,14130,5816,24195,21200,23414,25992,23420,31246,16388,18525,516, -23509,24928,6708,22988,1445,23539,23453,19728,23557,6980,23571,29646,23572, -7333,27432,23625,18653,23685,23785,23791,23947,7673,7735,23824,23832,23878, -7844,23738,24023,33532,14381,18689,8265,8563,33415,14390,15298,24110,27274,U, -24186,17596,3283,21414,20151,U,21416,6001,24073,24308,33922,24313,24315,14496, -24316,26686,37915,24333,449,63636,15070,18606,4922,24378,26760,9168,U,9329, -24419,38845,28270,24434,37696,35382,24487,23990,15711,21072,8042,28920,9832, -37334,670,35369,24625,26245,6263,14691,15815,13881,22416,10164,31089,15936, -24734,U,24755,18818,18831,31315,29860,20705,23200,24932,33828,24898,63654, -28370,24961,20980,1622,24967,23466,16311,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,10335,25043,35741,39261,25040,14642,10624, -10433,24611,24924,25886,25483,280,25285,6000,25301,11789,25452,18911,14871, -25656,25592,5006,6140,U,28554,11830,38932,16524,22301,25825,25829,38011,14950, -25658,14935,25933,28438,18984,18979,25989,25965,25951,12414,26037,18752,19255, -26065,16600,6185,26080,26083,24543,13312,26136,12791,12792,26180,12708,12709, -26187,3701,26215,20966,26227,U,7741,12849,34292,12744,21267,30661,10487,39332, -26370,17308,18977,15147,27130,14274,U,26471,26466,16845,37101,26583,17641, -26658,28240,37436,26625,13286,28064,26717,13423,27105,27147,35551,26995,26819, -13773,26881,26880,15666,14849,13884,15232,26540,26977,35402,17148,26934,27032, -15265,969,33635,20624,27129,13913,8490,27205,14083,27293,15347,26545,27336, -37276,15373,27421,2339,24798,27445,27508,10189,28341,15067,949,6488,14144, -21537,15194,27617,16124,27612,27703,9355,18673,27473,27738,33318,27769,15804, -17605,15805,16804,18700,18688,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,15561,14053,15595,3378,39811,12793,9361,32655,26679,27941, -28065,28139,28054,27996,28284,28420,18815,16517,28274,34099,28532,20935,U,U, -33838,35617,U,15919,29779,16258,31180,28239,23185,12363,28664,14093,28573, -15920,28410,5271,16445,17749,37872,28484,28508,15694,28532,37232,15675,28575, -16708,28627,16529,16725,16441,16368,16308,16703,20959,16726,16727,16704,25053, -28747,28798,28839,28801,28876,28885,28886,28895,16644,15848,29108,29078,17015, -28971,28997,23176,29002,U,23708,17253,29007,37730,17089,28972,17498,18983, -18978,29114,35816,28861,29198,37954,29205,22801,37955,29220,37697,22021,29230, -29248,18804,26813,29269,29271,15957,12356,26637,28477,29314,U,29483,18467, -34859,18669,34820,29480,29486,29647,29610,3130,27182,29641,29769,16866,5863, -18980,26147,14021,18871,18829,18939,29687,29717,26883,18982,29753,1475,16087, -U,10413,29792,36530,29767,29668,29814,33721,29804,14128,29812,37873,27180, -29826,18771,19084,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,16735,19065,35727,23366,35843,6302,29896,6536,29966,U,29982,36569, -6731,23511,36524,37765,30029,30026,30055,30062,20354,16132,19731,30094,29789, -30110,30132,30210,30252,30289,30287,30319,30326,25589,30352,33263,14328,26897, -26894,30369,30373,30391,30412,28575,33890,20637,20861,7708,30494,30502,30528, -25775,21024,30552,12972,30639,35172,35176,5825,30708,U,4982,18962,26826,30895, -30919,30931,38565,31022,21984,30935,31028,30897,30220,36792,34948,35627,24707, -9756,31110,35072,26882,31104,22615,31133,31545,31036,31145,28202,28966,16040, -31174,37133,31188, -}; - -static const struct dbcs_index big5hkscs_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__big5hkscs_decmap+0,64,121},{__big5hkscs_decmap+58,64,170},{ -__big5hkscs_decmap+165,64,254},{__big5hkscs_decmap+356,64,254},{ -__big5hkscs_decmap+547,64,253},{__big5hkscs_decmap+737,64,254},{ -__big5hkscs_decmap+928,64,254},{__big5hkscs_decmap+1119,64,254},{ -__big5hkscs_decmap+1310,64,253},{__big5hkscs_decmap+1500,64,254},{ -__big5hkscs_decmap+1691,64,254},{__big5hkscs_decmap+1882,64,254},{ -__big5hkscs_decmap+2073,64,254},{__big5hkscs_decmap+2264,64,254},{ -__big5hkscs_decmap+2455,64,254},{__big5hkscs_decmap+2646,64,254},{ -__big5hkscs_decmap+2837,64,254},{__big5hkscs_decmap+3028,64,254},{ -__big5hkscs_decmap+3219,64,254},{__big5hkscs_decmap+3410,64,254},{ -__big5hkscs_decmap+3601,64,254},{__big5hkscs_decmap+3792,64,254},{ -__big5hkscs_decmap+3983,64,254},{__big5hkscs_decmap+4174,64,254},{ -__big5hkscs_decmap+4365,64,254},{__big5hkscs_decmap+4556,64,254},{0,0,0},{0,0, -0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_decmap+4747, -161,254},{__big5hkscs_decmap+4841,64,254},{__big5hkscs_decmap+5032,64,254},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__big5hkscs_decmap+5223,214,254},{__big5hkscs_decmap+5264,64,254},{ -__big5hkscs_decmap+5455,64,254},{__big5hkscs_decmap+5646,64,254},{ -__big5hkscs_decmap+5837,64,254},{__big5hkscs_decmap+6028,64,254},{0,0,0}, -}; - -static const unsigned char big5hkscs_phint_0[] = { -32,5,95,68,15,82,130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,44,4,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,4,0,0,0,0,0,0,0,0,0,0,0,0,1,22,0,15,0,0,0,0,0, -32,87,43,247,252,110,242,144,11,0,0,0,192,237,164,15,38,193,155,118,242,239, -222,251,250,247,15,50,68,175,254,239,5,0,0,0,224,251,71,128,193,2,0,132,100,4, -130,64,32,162,130,133,164,145,0,16,1,0,0,0,144,72,12,0,48,0,84,3,48,68,24,19, -53,137,38,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,64,0,32,43,153,32,16,99,40,36, -1,0,0,0,0,80,96,212,0,210,42,24,157,104,53,151,79,216,248,32,196,130,28,40,2, -0,0,0,0,214,81,10,224,0,129,134,22,67,196,53,17,55,96,230,122,109,5,12,61,0,0, -0,0,153,57,128,7,34,254,129,144,24,144,12,116,48,208,160,9,41,21,253,4,0,0,0, -0,223,128,64,8,8,176,219,196,96,237,118,125,249,29,228,211,133,166,205,5,0,0, -0,0,12,0,110,186,9,47,96,84,0,30,120,104,34,112,86,158,37,243,142,7,0,0,0,192, -94,44,188,155,223,93,108,109,4,67,96,54,74,96,216,62,7,196,200,1,0,0,0,160, -177,197,98,11,12,34,62,204,37,184,1,174,237,92,104,13,148,74,181,0,0,0,0,0, -244,3,18,17,16,68,2,53,144,235,14,153,7,209,202,5,130,161,160,0,0,0,0,52,24, -160,137,231,156,91,8,132,3,2,218,144,236,219,135,133,191,162,45,0,0,0,0,118, -58,118,98,130,148,24,1,24,125,254,141,87,39,19,210,91,55,25,12,0,0,0,0,110, -139,33,145,0,0,0,64,0,0,0,2,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0, -0,0,0,0,0,0,0,2,0,0,0,0,0,0,142,120,110,95,63,126,221,61,247,252,155,252,174, -210,255,143,107,1,0,0,0,192,159,255,234,186,186,93,188,115,159,250,216,214, -222,37,75,94,151,218,42,1,0,0,0,224,182,153,27,216,116,230,79,21,191,41,230, -255,38,117,109,227,255,155,82,0,0,0,0,80,96,126,111,153,169,80,14,0,128,16, -216,35,0,37,16,144,244,235,117,0,0,0,0,208,219,0,160,152,178,123,6,82,32,152, -22,200,61,9,0,0,1,0,0,0,0,0,0,0,4,40,200,34,0,2,0,0,16,32,130,80,64,48,1,0,16, -0,4,0,0,0,0,74,4,1,16,20,0,128,0,4,255,253,36, -}; - -static const unsigned char big5hkscs_phint_12130[] = { -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,128,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0, -}; - -static const unsigned char big5hkscs_phint_21924[] = { -0,0,0,0,0,26,172,248,250,90,192,250,51,0,0,0,0,0,129,0,160,156,130,144,9,1, -180,192,176,3,86,2,160,66,45,136,1,0,0,0,0,146,119,139,96,5,201,33,6,70,56,96, -72,192,180,36,222,132,224,192,36,0,0,0,0,205,80,197,52,192,40,162,173,124,153, -24,88,18,34,196,66,162,83,142,30,0,0,0,128,52,135,11,21,209,64,250,61,0,4,210, -5,72,8,22,230,28,165,0,8,0,0,0,192,45,22,20,128,24,58,212,25,136,28,138,4, -}; - -static const DBCHAR __big5hkscs_bmp_encmap[26401] = { -50904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34905,34903,N,N,N,N,N,N, -34909,34907,M,N,N,N,N,N,N,N,34913,34911,N,N,N,N,N,N,N,N,N,N,N,N,34922,34920,N, -N,N,N,N,N,34927,34925,M,N,34931,34929,N,N,N,N,34935,34933,N,N,N,N,51451,34939, -34937,N,34978,34902,34919,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34906,34924,N,N,N,N, -N,N,34908,34926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34928,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51452,34910,34932,N,N,N,N,N,51450,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34936,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,34904,34921,N,34930,34912,34934,N,34938,N,34940,N,34941,N,34942,N,34977, -51446,34923,N,N,51448,N,N,N,N,N,N,51447,N,N,N,N,N,34984,N,N,N,N,N,N,N,N,51454, -N,N,N,N,N,N,N,N,N,N,51449,N,N,N,N,N,N,N,N,N,N,N,N,N,51445,N,N,N,N,N,N,51453,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50905,51193,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -51187,51188,51189,51190,51191,51192,51194,51195,51196,51197,51198,51264,51265, -51266,51267,51268,51269,51270,51271,51272,51273,51274,51275,51276,51277,51278, -51279,51280,51281,51282,51283,51284,51285,51286,51287,51288,51289,51290,51292, -51293,51294,51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305, -51306,51307,51308,51309,51310,51311,51312,51313,51314,51315,51316,51317,N, -51291,34915,34980,34917,34982,51410,N,N,N,N,N,N,N,N,N,N,51411,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50869,50870, -50871,50872,50873,50874,50875,50876,50877,50878,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,51319,51320,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51318,34985,34986,50849,50850,50851, -50852,50853,50854,50855,50856,50857,50858,N,N,N,N,N,N,N,N,N,N,50859,50860, -50861,50862,50863,50864,50865,50866,50867,50868,63993,63992,63974,63983,63965, -63976,63985,63967,63980,63989,63971,63982,63991,63973,63977,63986,63968,63979, -63988,63970,63975,63984,63966,63981,63990,63972,63978,63987,63969,63994,63995, -63997,63996,50918,51414,N,N,N,51415,N,51416,51417,51418,N,51419,N,51420,51421, -N,N,N,N,N,N,N,51422,N,N,N,N,N,N,51423,51424,N,N,N,N,N,N,N,51425,N,51426,N,N, -51427,N,51428,N,51429,N,N,N,N,N,N,N,51430,N,N,N,N,N,51431,N,51432,N,N,N,N,N,N, -N,51433,N,N,N,51434,N,51435,51436,N,51437,N,N,N,N,N,N,51438,51439,N,N,N,N,N,N, -51440,N,N,N,N,51441,50893,50912,50913,50914,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,50919,50920,50921,50922,50923,50924,50925,50926,50927,50928,50929,50930, -50931,50932,50933,50934,50935,50936,50937,50938,50939,50940,50941,50942,51008, -51009,51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021, -51022,51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034, -51035,51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047, -51048,51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060, -51061,51062,51063,51064,51065,51066,N,N,N,N,N,N,N,51412,51413,50908,50909,N,N, -51067,51068,51069,51070,51105,51106,51107,51108,51109,51110,51111,51112,51113, -51114,51115,51116,51117,51118,51119,51120,51121,51122,51123,51124,51125,51126, -51127,51128,51129,51130,51131,51132,51133,51134,51135,51136,51137,51138,51139, -51140,51141,51142,51143,51144,51145,51146,51147,51148,51149,51150,51151,51152, -51153,51154,51155,51156,51157,51158,51159,51160,51161,51162,51163,51164,51165, -51166,51167,51168,51169,51170,51171,51172,51173,51174,51175,51176,51177,51178, -51179,51180,51181,51182,51183,51184,51185,51186,N,N,N,N,N,50915,50906,50907, -34880,34881,34882,34883,34884,34886,34889,34890,34893,34895,34896,34897,34898, -34900,34901,51321,51409,37495,N,N,N,N,N,N,N,N,N,N,38623,N,N,N,N,N,N,N,N,N, -36084,N,35285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37837,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,39903,N,N,N,N,N,N,64104,N,N,35290,36697,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,35291,N,N,36701,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35292,N,N,N,N,N, -N,N,N,N,38647,N,N,N,N,N,N,N,N,N,N,N,N,35546,N,N,N,N,35804,N,N,N,N,N,N,38875,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40531,N,N,N,N,40362,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,39914,35438,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35784, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35304,N,35306,N,N,N,N,N,35915,N,N,N,N,N,N, -N,64368,N,N,N,N,N,N,N,N,N,N,N,35309,N,N,38109,N,35310,N,N,N,N,40628,35539,N,N, -N,N,N,N,N,N,N,N,N,37595,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38107,35321,N,N,N, -N,N,N,N,N,64378,N,N,N,35323,N,N,N,N,N,N,N,40700,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,35324,N,35263,N,N,N,35326,N,35302,N,N,40262,N,N,N,40430,N,N,N,41086,N,N,N, -41064,N,N,N,N,39145,N,35688,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36349,35774, -40921,N,N,N,N,N,N,N,35563,N,N,40919,35690,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40028,N, -35761,N,N,N,N,N,N,N,N,64350,N,34672,N,N,N,N,N,N,N,40435,N,N,N,N,N,N,N,41168,N, -N,N,64614,N,N,N,N,37609,N,N,N,N,N,N,N,N,39660,36779,64072,N,N,N,N,36421,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,40047,N,36188,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,40670,N,N,N,N,N,N,35311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,38633,N,N,N,N,N,N,N,N,N,N,40635,N,N,N,N,38110,N,40632,N,N,N,38842,64357,N, -N,N,38358,N,N,N,40123,N,N,38874,N,N,N,N,36677,N,64381,37208,65124,N,38998, -39757,N,N,N,N,N,N,N,N,N,N,37723,38343,N,38887,N,N,N,N,N,N,37721,N,N,N,37365, -38840,N,N,64930,64438,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37626,37719,N,35750,N,N,N,N, -64441,N,38832,N,N,64964,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40097,N,N,N,N,N,37362, -37369,N,36849,N,N,N,N,N,N,38725,38995,N,N,65144,N,64449,37457,N,N,N,N,N,N, -40365,N,N,N,N,N,64876,N,N,64107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,39874,N,N,N,N,N,N,N,N,N,N,N,N,39547,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35680,N,N,N,N,N,N,N,N,37707, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39613,N,N,N,N,37303,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36171,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,38324,N,N,N,N,N,65221,N,N,40688,36196,N,N,N,N,N,N,N,N,N, -37481,N,N,N,N,N,N,36199,N,N,N,N,N,N,N,N,N,N,N,N,64490,N,N,N,N,N,N,N,N,64495,N, -36200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,37867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64578,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37222,N,N,N,N,N,N,N,N, -64205,N,N,N,N,37853,N,N,36178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,35788,36205,N,N,N,N,N,N,N,N,N,N,N,36206,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,38568,N,N,N,N,N,N,N,N,N,N,64678,N,N,N,N,N,N,N,N,N,N,N, -N,36207,N,N,N,N,N,N,N,N,N,N,N,N,N,36208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,64612,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36083,N,N,N,N,N,N,N,36960,N, -N,N,N,N,N,N,N,36212,38851,N,N,N,N,N,N,N,35536,N,N,N,N,N,N,37492,N,39870,N,N,N, -N,N,40136,N,N,40122,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36216,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40633,N,N,N,N,N,38234, -N,N,37300,N,N,N,N,N,N,35400,N,N,N,N,N,N,N,N,N,N,N,36221,N,N,35453,N,N,35522, -64842,N,36257,N,N,35537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64692,35655,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,37796,40666,N,N,N,N,N,N,N,N,N,35409,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,36262,N,N,N,N,N,N,40645,N,N,N,N,64708,N,N,N,N,41080,N, -38069,N,N,N,N,N,N,N,64706,35435,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36267,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64232,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36269,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64585,N,37825,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36975,N,36272,N,N,N,N,N,N,N,N,38014,37114,N,N,N,N,N,N,N,N,N,N, -38009,N,N,N,N,N,N,N,N,36274,N,N,N,N,N,N,N,N,64750,N,N,N,N,N,N,N,N,N,N,N,N,N, -39291,N,N,N,N,N,N,N,N,36276,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36279,N, -N,N,N,N,N,N,37299,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36283,36282,N,N,N,N,N,N,N,N, -36284,36932,N,N,N,64844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34635,37860,N, -N,37856,N,N,N,N,N,N,N,64851,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,36291,N,39864,N,N,N,64496,N,37865,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37878, -N,N,N,N,N,36293,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36298,N,N,N,N,N,36300,64861,37813, -64865,N,N,N,40184,N,N,N,37458,N,N,41192,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,40101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,36310,N,38848,N,N,N,41182,N,N,N,N,38866,N,N,N,N,N,64165,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,64931,N,N,N,36315,36074,36527,N,N,N,N,N,N,N,N,N,37301,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64841,N,N,N,N,N,N,N,N,64977,N,N,N,N,N,N,N, -N,N,N,36331,N,N,N,N,N,38854,N,64974,N,N,37116,N,N,N,N,N,N,N,N,N,N,N,N,N,64601, -N,N,38614,N,N,N,N,N,N,38853,36335,N,N,N,N,38871,N,N,N,N,N,36336,N,N,N,N,N,N,N, -38566,N,N,N,N,N,N,N,64447,N,N,36063,N,36339,N,N,N,N,37961,N,36341,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,39026,N,N,N,N,N,N,N,36459,N,N,N,N,N,N,64253,N,N,N,N, -N,N,N,N,N,N,36688,N,N,N,N,N,N,40396,64613,N,35908,N,N,39278,38049,N,N,N,N,N, -36707,N,N,N,N,N,N,N,41178,N,N,N,N,N,N,N,N,N,N,N,37459,65001,N,N,40373,N,N,N,N, -N,N,N,39033,34666,N,N,40285,N,N,N,N,36195,38505,40816,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,64618,N,N,35527,N,N,N,N,35287,N,N,N,N,N,N,N,N,N,N,N,N,65101,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40669,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,65275,39100,64204,N,N,38320,N,N,N,37988,N,N,N,N,N,N,37743,N,N,N,N,N,N, -38073,N,N,38380,N,N,N,N,37358,N,N,39107,N,38390,N,N,N,36861,39109,N,N,N,N, -38758,65134,N,N,38877,36010,N,N,37586,N,N,38753,39115,N,N,N,N,38384,N,38749,N, -37347,N,N,N,N,39116,N,N,37993,39117,N,N,N,N,N,39118,N,38396,N,N,38051,38498,N, -N,N,65206,N,37987,36167,N,N,N,N,N,N,39120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,39121,N,N,N,N,38005,64224,N,N,N,N,N,N,N,N,N,38002,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39126,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,35568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39129,N,N,N,N,N,N,N,36186,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,39131,N,N,N,N,39133,N,N,N,N,N,N,N,N,39080,N,N,N,N,N,N,N,35437,N,N,N,N,N, -N,N,N,N,N,N,35579,35502,64457,N,N,N,N,35933,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,39140,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39142,N,N,N,N, -N,N,N,N,N,N,N,39144,N,N,N,N,N,N,N,N,N,N,N,N,N,35405,N,N,N,37463,N,N,N,N,N,N,N, -N,N,N,38367,N,N,41132,N,N,N,N,39147,N,N,N,N,39148,N,36035,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,39156,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35512,N,N,N,40679,N,N,N,N, -N,N,N,N,38076,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64721,N,N,N,N,N,N,40134,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36170,N,40574,36164,39166,65000,N,N,N,N, -39232,N,N,N,N,38089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,38099,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39238,N,N,N,N,37056,N,38097,N,N,N, -N,N,N,N,N,N,N,N,N,N,36174,N,N,38259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37826,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39240,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,39243,N,N,N,N,N,36437,N,N,N,N,39246,N,N,N,N,N,N,N,N,N, -N,N,36606,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36191,N,36441,N,N,N,N,N,N,N,N,N, -38124,38127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35936,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36724,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,39253,N,N,N,N,N,N,N,N,N,38212,N,N,N,N,N,N,N,N,N,N,N,36043, -N,N,N,39254,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39257,N,N,N,N,N,N,N,39259,N,N,N, -N,N,N,N,N,N,N,N,N,N,36036,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64069,N,N,N, -37047,N,N,38723,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38349,N,N,N,N,N,N,38857,64848, -36537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38342,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39271,N,N, -36067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35513,N,N, -N,N,N,N,36348,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35446,N,N,N,N,N, -40273,N,N,N,N,N,N,N,N,N,N,N,N,N,39283,N,N,34624,N,40271,39290,38244,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,39329,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39333,N,N,N,N,N, -N,N,39335,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,36589,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39341,N,51326,N,N,N,N,N,N, -N,N,N,N,N,N,N,37998,36720,N,64208,N,N,N,N,N,N,N,N,N,N,N,N,N,39347,N,N,N,N,N,N, -41043,N,N,N,N,N,36190,N,N,38492,N,N,36064,N,64890,N,N,N,N,N,N,N,N,38910,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,37565,36189,38909,N,N,N,N,36708,N,N,N,N,64759,38242, -38861,40548,N,N,N,N,N,N,N,37452,36553,39356,N,N,N,N,40357,N,36692,N,N,N,N,N,N, -N,N,N,N,36732,N,N,N,N,36181,N,36514,N,N,N,N,N,N,N,N,N,36730,N,N,N,N,N,N,38830, -N,N,N,N,38600,N,N,36068,N,N,N,N,39363,N,37078,N,40126,N,N,N,36726,N,N,N,N,N,N, -N,N,N,N,N,N,N,38000,64331,N,N,64970,N,N,36079,N,N,N,36551,N,N,N,N,36180,41209, -N,N,N,N,N,N,N,36777,N,N,36177,N,N,N,N,N,N,N,N,N,39367,34628,N,N,N,N,N,N,N,N,N, -N,N,N,37079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -34627,N,N,N,N,N,N,N,N,N,N,N,N,34631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34648,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40671, -36185,34626,N,N,39374,N,N,N,N,N,N,N,N,36794,N,N,N,N,N,36843,N,39375,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36802,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37577,N,N,N,N,N,38876,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34653,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,36165,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38323,40057,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38322,N, -36172,36827,N,N,N,N,39907,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,34636,N,N,N,N,N,N,N,N,N,N,N,N,N,34637,N,N,N,N,N,N,N,N,N,40570,34647,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,39918,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39390,N,N,N, -N,N,N,N,N,N,N,N,N,N,64250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35410,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,39393,N,N,N,N,N,N,35431,35765,N,N,N,N,N,N,N,N,N,N,35500,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39401,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,64458,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38878,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38353,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,39413,64586,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,39849,N,N,N,N,N,N,N,N,N,N,N,N,64476,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,65110,N,N,N,N,N,40612,N,N,N,N,N,N,40265,38363,N,N,N,N,N,N,N,N,N,N,35269, -N,N,N,N,N,N,N,N,N,N,N,N,39416,N,N,N,N,N,N,38500,N,N,N,N,36949,N,N,38612,N,N,N, -N,N,N,N,38780,N,N,N,N,N,N,38477,N,38881,N,N,N,N,N,N,39496,N,N,N,N,N,N,N,N,N,N, -N,39497,N,65149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37034,N,N,N,N,39504,N,N,N,N, -N,N,N,37703,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36568,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37065,N,N,N,N,N,39509,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37052,N,N,N,N,N,39512,N,35768,37077,N,N,N,N,N,N,N,N,N,N,N,N,N,38465,N,N, -N,N,N,N,39514,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39516,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,38850,N,N,N,N,N,N,N,N,N,N,N,N,N,34652,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35515,N,N,N,39850,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37109,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,37189,35928,N,N,N,N,N,N,N,N,39523,N,N,N,N,N,N,35913,N,N,N,N,N,N,N,N, -N,N,N,35766,N,N,N,N,N,N,N,N,N,N,64719,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38507, -39534,N,37199,N,N,N,N,N,N,N,N,38726,N,N,41190,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37591,N,38517,N,N,37844,N,N,37307,38521,N,N,N,N,N,39536,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38520,37325,N,40010,41071,N,N,41066,N, -N,N,N,N,N,37215,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,34625,N,N,N,N,N,N,N,N,40869,N,N,35258,N,34639,N,N,N,N,N,N,34638,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,34645,N,N,N,40653,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39545,N,N,N,N,N,N,N,N,N,36082,N,N,N,36183,N,40398,N,N,N,36050,N,N,N,34649,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40307,N,N,N,N,N,N,N,N, -N,38585,N,38588,N,N,N,N,N,N,40145,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35255,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40686,34633,N,N,N,N,N,N,N,N,N,N, -64323,34651,N,40649,N,N,N,N,N,N,64467,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,36184,34630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36182,N,N,N,N,N,N,N, -40312,N,N,N,N,N,N,N,N,N,N,40315,40627,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,40626,N,40406,N,N,N,N,39247,N,N,35278,N,N,N,35776,N,40900,N,35796,N,N,35954, -N,N,N,N,N,N,50879,35833,N,N,N,N,N,35142,N,50880,N,N,N,N,N,N,N,N,N,64229,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,51323,35782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40023,N,N,N, -N,N,N,N,N,N,N,N,N,N,39675,N,N,N,N,N,N,N,35280,35279,N,N,N,50881,N,35281,N, -35298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37502,N,40378,N,N,N,N,N,50882,N,N,35951,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64504,N,N,N,35783,37483,N,N,35282,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,40911,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40361,35283,N,N,39394,N,N,N,N,N,N,N,N,N,37479,37540,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,35955,N,N,35150,N,N,N,N,N,N,N,N,N,N,N,N,N,35151,37496,N,N,N,N,N,N, -N,N,37302,N,N,N,N,35284,N,40914,N,N,N,N,N,N,N,N,37543,N,N,38306,N,N,N,N,N, -37486,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,38634,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37487,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37539,N,N,N,N,N,35152,N,N,64087,N,N,N,N,39014,N, -N,N,36088,N,N,N,N,N,N,N,N,35286,N,N,N,N,N,N,N,N,N,N,39090,N,N,N,37547,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38622,37548,N,N,N,N,N,N,N,N,N,N,35952,N, -40814,N,N,N,N,N,N,36594,N,N,N,40812,35288,N,N,N,N,64089,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37544,N,N,N,N,N,37219,N,N, -N,N,N,N,35904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40819,N, -37549,N,N,N,N,N,N,N,N,N,N,N,N,N,39913,N,N,N,N,N,37545,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,37546,N,N,N,N,N,N,35289,N,N,N,N,N,N,N,64854,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,40872,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35953, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37537,N,N,37091,N,N,N,N,N,N,N,N,41126,N,N,N,N, -N,38059,N,64626,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38852,N,N,N,N,N,N,N,37550, -64103,N,N,N,N,N,N,N,N,N,N,N,37538,64105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,37480,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35153,N,N,N,N,N,N,N,N,N,64111,N,N,N,N,N,N,N,N,N, -64113,N,N,N,N,N,N,N,N,N,35154,N,N,N,N,37978,N,N,N,N,N,N,N,N,50883,N,N,N,35293, -N,51362,N,N,N,N,N,N,N,N,N,N,N,N,N,50884,N,N,N,40530,N,35155,N,N,N,N,N,N,N,N,N, -N,40533,37562,N,N,50885,N,N,35931,N,N,N,64125,64168,39528,64071,N,N,64126,N,N, -N,N,N,N,N,N,N,N,37563,N,N,N,64950,N,64162,N,N,N,N,N,64163,N,64164,39860,64166, -N,N,N,N,N,N,N,35295,N,N,N,64987,N,N,64169,N,35156,N,N,N,N,N,N,N,N,64171,N,N,N, -N,N,N,64634,N,N,N,N,N,N,N,35296,N,40783,51325,N,N,35297,N,N,N,N,N,64176,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40909,41191,N,N,N,N,N,64177,35238,N,N,N,N,N,N, -N,N,N,N,N,N,40698,N,N,N,N,N,N,N,64178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,64180,N,37572,N,N,N,N,N,N,40815,N,N,N,N,N,N,N,35760,N,N,N,N,N,N,N, -N,N,N,40876,N,N,N,N,N,35299,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39891, -35300,N,N,N,64181,N,N,N,N,N,40917,N,N,N,N,N,N,35157,N,N,37573,N,N,N,35158,N,N, -N,N,N,N,N,N,N,N,N,N,64179,N,N,N,64182,N,N,N,N,N,N,N,N,N,N,N,64183,N,N,N,N,N,N, -40668,N,N,N,64452,40817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64186,37575,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50886,39500,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35944,N,N,35301,N,N,N,N,40829,N,N,N,N,N, -41129,64196,N,N,N,N,50887,N,N,35159,N,N,N,N,N,N,64170,N,N,N,N,N,N,N,N,N,N,N, -35160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35811,N,35681,N,N,N,N,39665,N,N,40631,N, -50888,N,N,N,64209,N,N,N,N,N,N,64210,N,N,N,N,N,N,N,N,40634,64212,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,64217,N,N,N,N,N,N,N,N,N,N,N,N,64219,N,40160,N,N,N, -64503,N,64506,35303,41082,64220,N,N,64221,N,35305,N,N,N,N,N,50889,N,N,N,N,N,N, -N,N,N,N,64226,35307,N,N,64227,N,N,N,N,N,N,37064,N,N,N,37594,35161,40181,N,N,N, -N,N,35162,64231,40866,N,N,N,N,N,64234,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,64237,36781,N,N,N,N,N,N,64345,64239,38639,N,40428,N,N,N,40394,N,N,N,N,N,N, -64877,N,35308,N,N,N,N,N,N,N,N,N,N,N,64324,N,N,40418,N,35957,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,40640,N,40534,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,40825,39623,N,N,64244,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,39073,N,N,N,N,N,N,N,N,N,64248,N,N,N,35312,40519,N,N,40439,N,N,N,N,40915, -N,39626,N,N,N,N,35313,64249,N,N,N,N,N,N,N,N,N,N,N,N,N,36442,N,35314,N,N,N,N, -35315,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37469,35665,37600,N,N,35316,N,N,N,N,N, -N,N,N,N,40916,N,N,N,N,N,N,N,N,35449,N,N,N,N,N,N,N,N,N,N,N,35317,38823,N,N,N,N, -N,N,N,N,N,N,37818,N,N,N,N,N,40536,N,N,N,N,35318,N,N,N,N,N,40535,N,N,N,N,35319, -N,35393,N,N,35320,N,N,64241,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35322,N,N,N, -N,N,N,N,64322,N,64191,N,N,N,N,N,N,N,N,N,64419,N,N,N,N,N,N,N,N,N,64247,N,N,N,N, -N,N,N,N,N,N,N,40526,N,38108,N,N,N,N,N,38362,40440,40810,N,N,N,N,N,35511,N,N,N, -N,N,N,N,N,N,N,N,N,64326,N,N,N,N,N,N,N,N,N,35398,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,64327,N,N,N,N,N,N,37192,N,N,N,37598,N,N,N,N,35667,40438,N, -39898,N,N,N,N,40318,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35325,39396,N,N, -N,N,N,40515,N,N,N,N,N,N,N,N,N,N,N,40425,N,36690,N,N,N,40437,40432,N,N,N,39399, -N,N,N,N,N,35773,40431,N,N,N,N,N,N,N,N,N,N,N,40887,N,N,N,N,N,N,N,N,N,N,N,N, -40400,N,40939,36265,40399,39137,N,40421,N,N,N,N,N,N,N,40392,N,N,N,N,N,N,N,N,N, -64335,N,N,N,N,N,N,N,N,N,N,N,40427,N,N,N,N,N,N,N,N,N,64340,N,64341,39586,N, -35542,N,39519,N,N,N,N,N,N,N,N,40693,N,N,N,36791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,39634,40554,40680,N,N,N,N,N,N,N,N,N,N,N,N,35775,37314,40290, -N,N,N,N,N,N,37472,N,N,N,N,N,N,N,N,N,N,N,37470,37313,N,35525,N,N,38819,N,N,N,N, -N,N,N,N,N,N,35692,N,36222,N,N,N,N,N,N,N,40020,N,N,N,N,N,40381,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,40133,N,N,N,N,N,N,N,N,N,N,N,35163,N,N,N,N,N,N,N,N, -N,N,64348,N,64347,N,64343,N,N,N,N,N,N,N,N,N,34661,N,39111,64346,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,40174,N,N,N,N,N,N,N,37602,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,38055,N,N,N,N,N,N,N,N,N,N,36044,N,39892,N,N,64356,64374,N,N, -64352,N,N,N,N,N,N,N,N,N,N,N,N,N,39397,N,N,39618,N,N,N,37371,N,N,N,41075,N,N,N, -N,N,N,N,40818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40908,N,N,N,39077,37608,N,N, -N,N,N,N,N,N,39868,N,38643,N,N,37607,N,N,64615,N,N,N,N,N,N,N,N,N,N,N,35709,N,N, -N,N,39924,N,N,N,N,N,40695,N,N,40641,N,N,N,N,N,N,N,N,N,39279,N,N,N,N,N,N,38641, -N,N,36417,N,N,N,N,N,38218,N,N,N,38886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38645,N,N,N, -N,N,37606,40770,N,N,N,N,N,N,N,64359,N,N,N,N,N,N,N,N,39337,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,64230,64361,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38885,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,38525,N,N,N,64364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39330,N,N,N,N,N, -39611,N,N,N,39525,N,N,37966,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64366,N,N, -39391,N,N,N,N,N,N,N,N,N,39139,N,N,37460,N,N,N,N,N,38523,35503,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35959,N,N,N,N,N,N,35759,40637,N,N, -N,N,N,N,N,N,N,N,N,N,40678,N,N,64367,N,N,N,N,N,36577,N,N,N,N,39805,40062,N,N,N, -N,63961,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37610,N,N,N,N,35960,N,N,N,N,N,N,N,N,N,N, -N,64370,N,N,N,64369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35164,N,39152,38642,N,N,N,N, -N,N,N,64372,35777,N,35165,35294,N,35166,N,N,50890,N,N,N,N,N,N,65090,N,N,N,N,N, -N,N,N,N,N,N,34664,N,64379,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35167,N,35168,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,39885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40403,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,38988,N,N,N,N,N,N,N,N,N,N,38738,N,N,N,N,N,38339,N,N,N,N, -39862,N,N,N,N,N,N,N,N,N,N,N,N,39609,N,N,N,38835,N,N,N,N,N,N,40820,37617,N,N,N, -N,N,N,36090,N,N,N,N,38879,N,N,N,N,64422,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64427,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39031,N,N,N,38996,38341,N,N,N,N,N,N,N,40277, -64434,38270,N,N,N,N,N,N,N,N,38722,N,38118,N,N,N,N,37621,N,N,N,N,N,N,N,36037,N, -N,N,N,N,N,37629,N,N,64418,N,N,40017,N,N,38121,39004,37616,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,37964,N,N,N,N,N,N,N,37227,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35704,N,N,N, -N,38114,N,N,N,N,N,N,N,38991,N,64437,N,N,N,N,37489,N,N,37733,N,N,39003,N,N, -38992,N,N,N,N,N,N,N,38844,N,N,N,N,37619,N,N,37696,38989,N,N,N,38258,N,65007,N, -N,N,N,N,N,N,N,64961,N,N,N,N,64442,N,N,37611,N,N,N,N,N,N,64627,38839,N,N,34671, -N,N,N,N,N,N,64436,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37031,N,N,N,N, -N,N,N,N,N,N,38721,37620,N,34674,N,64444,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38263, -N,N,N,N,N,N,N,N,N,N,N,40674,N,36728,N,N,N,N,N,N,N,63964,N,N,N,38514,40629,N,N, -N,38475,N,N,N,36012,N,N,N,N,N,N,N,N,N,41210,N,N,N,N,N,N,N,N,N,N,N,38261,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37082,N,N,37735,N,65188,N,N,N,37087,N,N,N, -N,37716,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35169,N,35764,N,N,N,N, -40384,N,N,N,N,N,N,36424,N,64453,N,N,N,N,N,64455,N,N,N,50891,N,64121,N,N,N,N,N, -N,N,N,N,N,N,N,N,40551,N,N,N,N,N,36057,N,N,N,N,N,N,64466,35170,35171,N,N,N,N,N, -N,N,N,N,N,64637,N,N,N,N,N,N,N,N,N,N,N,N,34675,N,N,N,N,N,N,N,N,N,N,N,40811,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64460,N,65198,N,N,N,34669,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,64465,N,N,N,N,N,N,N,N,N,N,N,64373,64468,N,N,N,N,N,N,N, -N,N,N,N,N,N,64470,64472,N,N,N,N,N,N,N,35677,N,37708,N,39650,N,N,35785,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64475,40905, -N,N,N,N,N,N,N,N,40772,N,N,N,N,N,N,N,N,N,N,39149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,36073,N,N,N,N,N,N,N,N,N,N,N,N,64477,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,36338,35172,N,65010,N,37709,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,64487,N,N,N,N,N,N,41202,39016,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40792,N,N,N,36070,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36211,N,N,N,64478,N,N,N,N,N, -64479,N,N,N,N,N,35912,N,N,N,N,N,N,34676,64483,N,N,N,N,36264,N,N,64484,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40053,N,N,39032,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36192,N,N,N,N,N,N,N,64485,N,36193,N,N,N,N,N,N,N,N,N,N,N,N,N,36194,41121,N,N,N, -40000,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39085,N,N,N,40682,N,N,N,36076,N, -N,36052,N,N,N,N,N,N,N,N,N,40171,N,N,N,N,N,64480,N,N,40785,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,36197,N,N,N,N,N,N,40177,N,N,N,N,N,N,N,N,N,N,64600,N,N, -36198,N,N,N,N,N,N,N,38484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64488,N,N, -N,50892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40910,64508,N,39652, -N,N,N,N,N,N,40821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64497, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36201,N,N,N,N,N,37711,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,37710,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,64500,N,N,N,N,50894,N,N,N,64451,N,N,35173,N,N,N,N,N,N,N,N,N,N,N,35962,N, -N,N,N,N,N,35963,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,36202,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37715,N,N,40443,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64509,N,N,N,36953,64576,N, -64577,64579,37729,64582,37730,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36203,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64588,36094,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,38328,N,N,50896,35786,N,N,N,N,N,N,N,N,N,N,39034,N,N,N,N,50897,N, -64593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64596,N,N,N,N,N,N,N,N,64175,N,N,N,N,N,N,N, -36204,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64097,N, -N,64599,N,N,N,N,N,N,N,N,N,39792,N,N,N,N,N,N,N,N,41041,N,N,N,N,N,N,N,35964,N, -35787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37742,N,N,N,64725,64681,N,N, -N,N,N,N,N,N,N,N,N,N,N,64609,N,N,N,N,N,N,N,N,N,35174,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,64203,N,N,N,N,N,N,N,63962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,37754,N,41184,N,N,N,N,N,N,37739,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64619,N,N,N,N,N,41180,N,N,37992,N,N,N,N,N,N, -N,N,N,N,N,64621,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,36209,N,N,N,N,N,N,64868,N,N,N,N,39354,N,N,N,39632,39521,41189,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41051,38572,N,N,N,N,38720,N,N,N,N,N,N,N,N,N,N,N, -N,40689,N,N,N,N,N,N,N,N,35917,N,N,N,N,N,N,N,N,N,N,N,N,N,40830,N,N,N,N,N,N,N,N, -N,N,N,N,36210,N,N,N,N,64630,N,N,N,N,N,N,N,N,N,N,N,N,N,38569,N,N,N,N,N,N,N,N, -41070,N,N,64682,N,N,N,64461,N,N,N,64628,N,N,N,N,N,N,N,N,N,N,41076,N,N,N,N,N,N, -N,N,N,N,N,N,N,41073,N,N,N,64633,N,N,N,N,N,64636,N,N,N,N,N,N,N,N,N,N,N,N,N, -40016,N,N,37753,37752,N,N,41181,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,36213,N,36214,N,N,N,N,N,N,37748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36215,64677, -N,N,64674,N,N,N,N,N,N,37059,N,N,N,N,N,N,N,41081,36217,N,N,N,N,N,N,N,N,N,N, -35836,N,41078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35789,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40794,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,40948,N,N,40890,N,N,N,N,N,N,N,N,N,N,36218,N,N,N,N,N,N,N,N,N,N,N,N, -40517,N,N,N,N,N,N,37808,N,41077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,39750,N,64686,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64688,N,N,N,N,N,N,N,N,N, -64081,N,N,N,N,N,36219,36220,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40662,N, -N,37804,N,N,N,40795,N,37801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41084,N,N,N,N,N,N,N,64690,N,N,N,N,N,N,N, -N,N,N,N,N,35521,N,N,N,N,N,40884,N,N,N,N,N,N,N,N,N,N,N,64684,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40524, -N,N,N,N,N,N,N,36805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37805,N,N,N,N,N,N,N,N,N,N,N, -N,40387,N,N,N,36258,N,N,N,40266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64694,N,N, -36259,40523,N,40525,36260,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35581,N,N,N,N,N,64693,N,64707,37810,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36261,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,37793,N,N,N,N,N,N,N,N,N,N,35526,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,35419,N,N,N,35149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,65236,N,N,N,N,35448,N,37803,N,N,N,N,N,N,N,N,N,36263,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,40773,N,N,N,N,N,N,N,N,N,35414,N,N,N,64703,N,N,N,64704,N,36582, -N,N,35492,35139,N,N,N,N,N,N,37875,N,N,N,N,N,N,N,N,N,N,N,N,64683,40610,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,40391,N,N,N,50898,35790,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,64709,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64715,N,N,N,N,N,N,N,N, -N,N,N,37811,N,64714,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64713,36268, -N,64454,35175,N,35966,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,64717,N,N,N,N,N,N,N,N,40179,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,64720,N,N,38331,N,N,N,N,N,N,N,N,N,N,N,64723,N,N,64724,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36270,64727,N,N,N,N,N,37851,N,N,N,N, -65123,N,N,N,N,N,N,N,N,N,N,N,N,37845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64730,N,N,N,39793,N,N,64733,N,34660,N,N,N,N,N,36271,N,N,N,64242,N,N,N,N,N,N,N, -N,N,N,N,37848,N,N,N,64735,N,N,N,37843,N,N,N,N,N,N,N,64737,N,N,N,N,N,N,N,N,N, -36470,N,N,N,N,N,N,N,64610,N,N,N,N,N,N,N,N,37841,N,N,N,36273,N,N,N,N,N,N,N, -39001,N,N,N,N,N,N,N,N,N,64338,N,N,N,N,N,N,N,N,64339,N,N,N,N,N,64333,N,N,40127, -N,N,N,N,N,N,N,N,39794,N,N,N,N,N,N,N,N,N,N,N,N,N,64336,37822,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36059,N,N,N,N,N,N,N,N,N,40433,64747,N,N,N,N,N,N, -N,N,N,41147,N,39806,N,N,N,N,N,N,N,36275,N,N,35922,N,N,N,N,39656,N,N,N,N,N,N, -36572,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40185,N,N,N,N,N,N,N,N,N,N,N,N,N,64080,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39143,64755,N,N,N,N, -64754,N,N,N,36042,N,N,34677,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,37861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39513,N,N,N,36277,N,N,N,N, -N,N,N,64845,N,N,N,N,64862,N,N,N,N,N,N,N,N,N,N,N,N,N,36733,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,38215,64758,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,37456,N,N,N,N,35176,36278,64763,41085,39164,35177,N,N, -N,N,N,N,N,N,65103,N,N,37462,N,N,N,N,N,N,N,N,N,N,64201,N,N,37864,N,N,N,64760,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40163,64937,N,N,N,N,N,N,64580,N,N,N,N,N,N, -N,N,38464,N,N,36280,N,N,N,N,N,N,N,N,N,N,39754,36793,N,N,N,N,N,N,64766,N,N,N,N, -N,N,N,35178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36281, -N,N,N,37246,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37876,N,N,N,N,N,N,N,N,N,N,N,N,N, -64380,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37863,N,N,38895,N,N,N,65098,N,N,N,N,N, -64837,N,38565,N,N,N,N,65248,64840,64839,65266,65130,N,N,N,N,N,36285,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,39841,36002,39607,36604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40865,N,N,N,N,N,N,N,N,N,64849,N,N,N,N,N,N,N,64173,N,N,N,N,36286,N,N,35236,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,39641,N,N,N,N,N,N,N,N,N,N,N,64846,N,N,36288,N,N,38896, -N,N,N,N,N,N,N,N,N,N,37812,64836,N,N,N,N,N,N,N,N,N,N,N,N,40871,N,N,N,N,36290,N, -N,N,N,39350,N,N,N,N,N,N,N,N,N,N,N,N,N,64850,N,N,N,N,N,N,36289,N,N,36422,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,41169,N,N,N,N,N,N,N,N,N,N,N,N,N,40906,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,37583,N,N,N,40180,36292,N,N,N,N,N,N,N,N,N,N,64833,N,N,N,N,N,N, -N,39756,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64855,64751,40158,N,N,N,N,N,N,N,64834, -39020,N,N,N,N,N,N,N,N,N,N,N,N,N,38905,N,38232,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39006,65147,38093,N,N,N,N,N,37870,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36003,N,64858, -N,N,N,N,N,N,37877,N,N,N,N,N,37871,36586,N,N,N,36699,N,N,N,N,N,N,N,N,N,N,N, -35934,N,36294,N,N,N,N,N,N,N,N,N,N,N,36296,N,N,36295,N,N,N,N,N,37879,N,N,N,N,N, -N,N,36297,N,N,N,N,N,N,N,64498,N,N,N,N,38512,N,N,N,N,N,N,N,N,N,36299,N,N,N, -64860,N,N,N,N,N,N,N,N,N,36709,N,N,N,36301,N,N,N,N,N,40360,38137,N,N,36302,N,N, -N,N,N,N,N,N,37866,N,N,N,N,N,N,N,N,N,64863,37872,40886,N,N,N,N,N,N,N,N,N,36303, -N,N,N,38755,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36304, -37873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64866,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,64869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,40923,N,N,N,N,37880,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35831,N,N,N,N,64870,N,N,N,N,N,35791,N,N,N,N,N,N,36305,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,36306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,64881,N,N,N,N,64879,N,N,N,N,N,N,N,N,36307,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40935,37053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40912,N,N,N,35792,N,64882, -N,40110,35793,N,N,35547,N,N,N,N,N,N,N,N,N,N,N,64228,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,38350,N,64886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64354,N,N,N,N,N,N,36308, -N,N,N,64888,N,N,N,N,N,36579,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36982,N,N,39110,N,N,N,N,N,N,N,36309,N,N,N,N,38865,N,N,40630,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64199,N,N,41026,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,39027,N,N,N,N,N,N,N,N,N,N,40956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,36005,36311,N,N,37627,36312,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,37967,N,36313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,35179,N,N,N,N,N,N,N,N,38862,N,N,N,64243,64942,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64431,37559,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36314,N,N,N,N,N,N,N,N,N,N,N,N,N,40026,N,N,N,N,N,N,64941,N,N,N,N,N,N,N,N,N,N,N, -N,N,36316,37956,N,N,N,N,N,N,N,N,N,N,N,36317,N,N,N,N,N,N,N,41174,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35905,38869,N,37962,N,N,N,N,N, -37965,N,N,N,N,38859,N,N,N,N,N,36318,N,N,36319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36320,65273,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,64960,64761,N,N,N,N,N,N,36061,N,64382,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,37555,N,N,N,N,N,64943,N,N,N,N,N,N,N,N,N,36321,N,N,N,N, -38355,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64872,N,N,40119,N,N,36323,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,64192,36325,64100,N,35143,N,N,N,N,36324,N,N,N,N,N,36327, -36328,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64967,64944,N,N,N,N,N,N,37957,38870,N,N, -N,N,N,N,N,N,N,64710,38980,N,N,N,N,N,N,N,N,N,N,N,N,36329,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,36330,N,N,N,N,N,N,N,N,65104,N,N,N,N,N,N,64972,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,40359,N,N,N,N,N,64973,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64975,N,N,N,N,38354,N,N,N,N,N,N,N,36333,N,N,N,N,N,N,N,N,64698,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,64965,N,64978,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40156,N,N,N,N,N,38351,N,N,36334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64980, -N,N,N,N,N,38636,38635,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37046,N,64963,39083,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38638, -N,N,N,N,N,N,N,N,N,N,N,N,N,36340,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64992,N,35943,N,N,36342,N,N,N,36343,N,N,N,N,N,N,N,36858,N,N,N,N, -N,N,N,N,N,N,38864,N,N,N,N,35794,N,N,36344,N,N,N,N,N,37081,N,35911,N,64240,N,N, -N,N,64993,36345,N,64995,N,N,N,N,N,N,N,36346,N,64355,N,N,N,37030,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,39280,N,N,37355,N,38768,39023,64994,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,39154,N,39676,35180,65021,N,N,39262,N,N,N,38333,N,N,N,N,N,N,N,64996, -N,N,N,37350,N,N,N,N,64997,64998,N,N,N,N,N,N,N,N,64999,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,37972,N,N,N,39352,N,N,N,N,N,N,N,N,38889,37702,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,39011,N,N,N,N,N,N,N,N,N,N,N,38332,N,65005,65015,N,N,N, -N,N,N,39024,38646,36521,N,N,N,N,N,37969,N,N,36419,N,35674,N,N,N,N,65006,N,N,N, -N,65008,N,N,N,N,65012,N,39925,N,N,N,N,N,36078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,38782,N,N,N,N,N,39893,N,39619,N,38856,41179,37328,N,N,40932,N,36829,N, -37353,N,N,N,N,N,N,N,N,N,39136,N,N,N,37578,N,38999,N,N,35921,N,N,N,N,65003,N, -39753,N,N,N,N,N,N,N,N,N,40310,40623,N,N,N,N,N,N,N,N,N,40140,N,N,N,N,N,N,65002, -N,N,36337,N,N,65019,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36435,N,N,N,N, -N,N,N,N,N,N,N,64207,N,N,N,N,N,N,N,N,N,N,N,N,N,38649,N,N,N,N,N,N,N,N,N,39103, -40521,36007,N,N,N,N,N,N,N,N,39882,N,N,N,N,65022,37596,N,N,N,N,N,65089,37324, -37346,N,N,N,N,N,N,N,N,N,N,N,N,65092,34655,N,N,N,N,N,35795,N,N,65095,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,65096,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37973,N,N,N,N, -65099,N,65100,N,N,N,N,36287,N,N,N,N,N,N,N,N,N,40568,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,65105,N,N,N,N,37974,N,N,N,N,N,N,N,40289,N,N,N,N, -37975,N,N,N,N,N,N,N,N,N,N,39270,N,N,N,N,N,N,N,N,N,N,N,N,N,35797,N,N,N,N,41065, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39092,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,41033,41036,N,40549,N,N,N,N,N,N,N,N,N,N,N,39093,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65112,N,39285,65107,41061,N,65113,N,N,N,N, -N,N,N,N,N,39095,39096,N,N,N,N,N,N,N,39098,N,N,N,N,N,N,39099,N,N,N,N,N,N,40892, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41034,N,N, -40647,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36009,N,N,39086,N,N,N,N,N, -N,N,N,37590,N,N,N,64225,N,37332,N,N,N,N,N,N,N,N,64222,N,N,65115,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,35923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65118,N,N,N,N,64471,65114, -38085,N,N,N,N,64202,N,N,N,N,N,N,N,N,N,N,N,39105,38748,N,65140,N,38771,N,N,N,N, -N,N,N,N,64070,N,N,N,38756,N,N,N,65128,N,38478,N,38757,35930,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,35233,38394,N,37588,65129,N,64325,N,39112,N,N,37103,N,39113,39114,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37997,38071,65132,N,N,37995,N,N,N, -N,N,N,37628,N,38379,N,65139,38766,65119,N,N,N,N,N,N,N,N,N,64957,N,N,37589,N,N, -N,N,N,N,65209,N,N,65137,34680,N,N,N,64443,N,N,38010,N,N,38395,65143,N,N,N,N,N, -N,N,65145,N,65141,N,N,N,37981,N,N,N,N,N,N,N,65148,N,N,N,N,N,N,N,N,N,37700, -36518,N,N,N,N,N,N,N,N,N,N,N,37587,N,38072,N,34681,N,N,N,N,N,N,64625,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,38750,N,N,N,N,36013,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65191,N,N, -N,37994,N,N,N,37859,N,N,39119,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41177,N,N, -N,N,N,N,N,N,41151,41037,41144,N,N,N,N,N,41166,41143,N,N,N,N,N,N,N,N,65193,N,N, -N,N,N,N,N,N,N,N,35267,N,N,N,N,65195,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40436,35181,N,N,N,N,N,40059,N,N,N,N,N,N,39122,N,N,N,40873,N,N,N,65202,N,N, -65201,N,N,N,38873,N,41156,N,38006,N,N,N,N,N,N,N,N,N,N,39288,N,N,N,N,N,N,65203, -N,N,N,N,N,39123,65204,N,N,N,39124,N,N,N,N,N,N,N,40889,N,N,N,N,N,N,N,N,38001,N, -N,N,N,N,N,N,N,N,39125,65208,N,N,N,50900,N,N,N,N,N,N,N,N,N,N,N,65210,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,40540,N,N,65211,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41028,N, -N,N,N,39127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39128,65212,N,N,N,N,40958,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65213,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,40413,N,N,N,N,40673,N,N,N,N,N,N,N,N,N,N,N,N,39130, -40415,65215,N,65214,N,N,40683,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40537,41052,N, -N,N,N,N,N,N,65216,N,N,N,38007,39132,N,65217,N,N,N,39134,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,65219,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65224,N,N,N,65225,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65226,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -65227,N,N,N,N,N,N,N,N,N,40898,N,N,35947,39108,N,38064,38065,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,65233,N,N,N,N,N,41153,N,65234,N,N,N,N,41165,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,65235,N,N,39141,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65238, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37348,N,N,N,N,36807,38062,N, -35407,38066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36820,N,N,N,N,39146, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65240,N,N,N,N,N,N,N,N,N,40416,N,N, -N,N,39150,N,N,N,N,38340,N,64744,N,N,N,N,N,39151,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,35950,N,N,N,N,N,N,N,N,64216,N,N,N,N,N,N,N,N,N,N,N,N,N,65244,N,N,N,N,N,N,N, -N,N,41134,40268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39153,N,N,N,39155,N,38081,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39157,N,N,64079,38626,N,N,N,N, -37968,N,38562,N,N,39158,N,N,N,38629,N,N,N,N,N,39159,N,41030,38627,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,39160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40676,N,N,N, -N,N,N,63958,N,N,N,N,N,N,38083,N,N,N,N,38082,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65249,N,65257,N,N,N,N,38628,N,35244,38619,N,N, -N,N,N,N,N,N,N,N,N,N,N,65250,N,N,N,N,N,N,N,N,N,N,38084,65251,N,N,N,65255,40955, -N,N,N,N,N,N,N,N,N,N,N,35929,N,N,N,N,N,N,N,N,N,37833,N,38120,64342,N,N,N,37061, -41128,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,65253,N,N,N,39165,39163,65256,N,36543,N,N,N,N,35800,65271,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36712,38086,N,N,N,N,N,N,N,N,40426,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,64617,N,N,N,N,N,N,N,N,N,N,N,N,40154,N,65267,N,N,40050, -N,N,65264,35273,N,N,N,N,N,N,N,N,N,39233,N,N,N,N,N,N,N,39234,N,N,N,65269,N, -37335,N,N,N,N,N,38092,N,N,N,65272,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,38824,N,65276,N,N,N,36062,N,64959,N,N,N,N,N,N,N,65278,N,N,N,N,N,N,N,N, -N,N,N,N,N,38609,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38101,N,N,38096,39236,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35939,N,N,41139,N,N, -N,N,N,N,N,N,N,N,N,N,38095,N,N,N,40954,N,N,N,N,37349,N,40042,N,N,N,36425,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36428,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,36429,N,N,N,N,N,39539,N,N,N,N,N,N,N,N,N,N,N,N,N,39239,N, -36017,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36432,N,N,N,N,N, -N,N,N,N,N,36431,39241,N,N,N,N,N,36433,36434,N,N,N,N,39602,35237,N,N,N,N,N, -39244,N,N,N,40952,N,N,N,N,N,N,36438,39245,37322,36439,N,N,N,N,38113,N,N,N,N, -36935,N,36824,36440,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38123,36444,38227,N, -N,N,N,N,N,N,40933,N,N,N,N,N,N,N,N,N,N,40790,N,N,N,N,N,N,N,38223,N,36446,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,39274,N,N,N,N,N,N,N,N,40036,40153,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,36445,N,N,N,N,N,N,N,N,N,N,N,N,39248,N,N,N,N,N,N,N,N,N,39249,N,N, -36450,N,N,N,N,N,N,N,N,N,N,N,39250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36456,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36449,40793,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40797,36454,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36018,N,N,N,N,N,N,N,N,N,N,N, -N,N,36462,N,40804,39251,N,N,64184,N,N,N,N,N,39252,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,36464,N,N,N,N,N,N,N,N,N,N,N,N,40801,N,36466,N,N,N,N,N,N, -N,N,N,N,N,N,41067,N,N,N,N,40768,N,N,N,N,N,N,38125,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,38126,N,N,40893,N,N,N,36475,N,N,N,N,N,N,39255,38135,N,40799,N,N,N,N,36467,N, -N,40802,N,N,N,N,N,N,N,38134,N,N,N,N,N,N,N,N,N,N,N,N,N,39256,N,N,N,N,N,N,N,N,N, -36469,63963,N,N,N,N,36978,N,38136,N,N,N,N,N,N,N,N,N,39258,N,N,N,N,N,N,N,N,N, -41136,36019,N,N,N,36473,N,36472,N,N,N,38131,N,N,N,N,N,39087,N,N,N,N,N,N,41138, -N,N,N,N,N,N,N,N,N,N,N,36474,N,N,N,N,N,N,39260,N,N,N,N,N,36476,N,36477,N,N,N, -35801,N,N,35234,40663,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,41142,N,N,N,N,N,N,N,N,N,N,N,N,40514,N,N,36516,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36519,N,35958,N,N,N,N,N,N,N,N,N,34663,N,38210,N,N,N,N,N,N,N,N,N,N,N,N,39037,N, -N,N,38741,N,N,36520,N,N,N,N,N,N,N,36522,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,35235,N,39264,39266,N,N,38140,39265,N,N,N,N,N,N,N,38138,N,N,N,N,N, -N,N,36526,36530,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36528,N,N,N,N,N,N,N,39267,38826, -38139,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36539,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,36060,N,N,N,N,N,N,N,N,N,39030,N,36513,N,N,N,N,36020,N, -36535,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40358,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40624, -N,N,N,36536,N,N,N,N,N,N,N,N,N,N,N,N,40304,N,N,N,N,35182,N,N,N,N,N,N,N,35183,N, -N,N,N,N,N,N,N,N,N,N,N,N,35184,N,N,N,N,N,N,N,N,N,N,N,N,35185,N,N,N,N,N,N,N, -35186,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35187,35188,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35189,N,N,N, -N,N,N,N,N,36540,36541,N,N,N,N,N,36542,N,40401,N,N,N,N,38141,N,N,N,35799,35802, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41186,N,N,N,N,N,N, -40937,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64936,N,N,N,35559,N,N,N, -36546,N,N,N,N,N,N,N,N,N,N,N,36548,N,N,N,N,N,N,N,N,N,N,39268,N,N,N,N,N,39269,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38222,N,N,N,N,N,N,N,N,N,39091,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36555,35807, -N,N,N,N,N,36558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36559,N,N,39272,N,N,N, -N,39273,N,N,N,N,N,N,N,N,39275,36561,N,39276,N,N,N,N,N,N,N,N,N,36564,36565,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39277,N,N,N,N,N,N,41150,N,N,N,N,N, -36566,41148,41141,N,N,41140,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35253,N,N,N, -N,N,N,N,36573,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40541,39281,N,N,N,N,35246,40424,N,N, -N,N,N,N,N,N,38245,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,39282,N,N,35676,N,N,N,N,N,N,N,N,N,35249,41152,N,N,N,36575,N,38246,N,N, -39284,N,39286,N,N,N,39287,N,39289,N,N,40410,N,N,36576,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37724,N,N,N,N,N,N,N,40422,N,35679,N,N,38243,N,N,N,N,N,N,N,N,N,N,38247,N, -N,N,N,N,40419,N,N,N,N,N,N,N,N,N,N,N,N,N,39292,N,N,39293,39294,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,36091,35675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39331,N,N,N,N,N,N,N, -39332,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39336,N,N,N,N,35518,N,N,N,N,N,N,N,N,N,N,N,40545,N,N,N,N,N,N,N,N,N,N,39338,N,N, -N,N,N,N,41160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39339,N,N, -N,N,N,N,N,N,N,N,65220,N,N,N,N,N,N,39106,36584,N,41146,N,N,N,N,N,N,N,N,N,N,N, -64887,N,N,36590,N,N,N,40639,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35266,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39340,N,N,N,N,N,N,N,N,N,N,N,N,N,38251,N,N,38252, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39343,N,N,39242,35190,36680,N,N,N,N,N,N,N,N,N, -N,N,64494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39342,N, -N,N,36603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36048,N,N,N,N,35666,N,N,N,N, -N,39344,N,N,N,N,35191,36673,N,N,N,N,N,N,N,39345,N,N,N,N,N,N,N,N,N,36681,N,N,N, -N,N,N,N,N,N,N,N,64077,N,N,N,N,N,N,N,N,40420,36021,N,N,N,64489,39764,N,39346, -40552,N,N,N,N,N,N,N,N,N,N,N,N,36682,N,36674,N,N,36689,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38982,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,39348,N,N,N,N,N,N,N,N,N,N,36597,64853,N,N,40141,N,N,N,N,N,N,N, -N,35192,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36691,N,N,N,N,N,N,N,N,N,N,N, -36719,N,N,N,N,N,N,N,N,N,N,36451,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36694,N,N,N,N,N, -N,N,N,N,N,N,N,65142,N,N,N,N,40902,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64172,N,N,N,N,N, -36696,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38984,39351,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,38501,N,64108,N,40423,N,N,N,40546,N,N,N,38604,36455,N,N, -64629,N,39038,N,N,N,N,N,N,N,64953,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38908,N,N,N,N, -N,N,N,N,N,39161,N,36710,N,N,N,N,N,N,N,N,38254,N,37445,N,N,36704,N,N,N,40657,N, -N,N,N,N,65229,N,39353,N,N,N,N,N,N,N,N,N,N,N,N,36706,38732,N,N,N,N,N,N,N,N,N,N, -N,N,37319,38239,N,N,N,N,N,N,N,39355,N,N,N,N,N,N,N,N,N,36461,36721,N,N,38091,N, -N,N,N,N,N,N,N,N,N,N,N,38321,N,N,N,N,N,N,N,N,N,39666,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,38595,39357,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41167,N, -N,N,36717,N,N,39358,36596,N,36722,38372,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39359,37442,N,64421,N,N,N,N,N,N,N,N,N,N,39360,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64948,36727,N,N,N,39361,N,N,N,N,N,N,N,N,N, -64185,N,N,N,N,N,N,N,N,36672,64068,N,N,N,N,N,39362,N,N,N,N,N,N,N,36700,N,N,N,N, -36029,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39364,39365,N,N,36731,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34678,N,N,N,36022,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36771,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36046,N,N,N,N,N,N,N,N,N,39366,N,N,N,N,N,N,N,N, -N,N,N,N,N,38605,N,N,N,N,N,N,N,N,N,N,N,N,N,38599,36773,N,N,N,N,N,N,N,N,N,N, -64187,N,35937,38256,N,N,N,37736,N,36734,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36778,N,N,N,N,N,N,41040,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37075,N,N,38230,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36792,N,N,N,N,N,39368,N,N,N,N,N,N,N,N,N,N,N,36783,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,39369,N,N,N,N,N,N,N,N,N,N,N,N,N,38265,N,N,N,N,N,N,N,N,N,N,N,N,40777, -N,N,N,N,39370,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39371,40405,36784,N,N, -N,N,N,N,N,N,N,N,N,64122,N,N,N,N,N,N,N,N,40543,N,N,N,N,39373,41161,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39643,N,N,N,41158,N,N,N,N,N,N,N,36788,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,41175,N,N,N,N,N,N,N,N,N,N,N,N,41159,N,N,N,N,N,N,N, -41027,N,N,N,36789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36786,N,N,N,N,N,N, -41057,40542,N,N,N,N,N,N,N,N,N,N,36790,N,N,N,N,N,N,N,N,40936,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,40114,N,N,N,N,N,38268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40903, -N,N,36795,36796,N,N,N,N,N,N,N,N,36844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36800,N, -37738,N,N,N,35812,40060,N,N,N,N,N,N,N,N,38305,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,65260,N,N,38307,N,N,N,N,N,N,N,35909,36024,N,N,N,N,N,N,N,N,N,N,N, -36801,N,N,N,41042,N,N,N,N,N,N,N,N,N,N,N,N,N,39376,N,N,N,N,N,36803,36804,N,N,N, -N,N,N,N,N,N,38308,N,N,N,N,N,36806,N,40544,N,N,N,N,N,N,N,63960,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,38309,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40115,N,N,N,N,N, -N,N,N,N,39377,65265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,39378,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40130,N,N,N,39379,N,N,N,N,N,38311,N,N,N,N,N,N,38313,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,38310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40029,N,N,N,N,N,N,N,N,39138,N,N, -N,N,N,N,36809,N,41154,36810,N,N,N,N,N,N,39380,N,N,41145,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,39768,N,36813,N,41172,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36814,N,N, -N,N,35813,N,N,N,N,35193,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,36816,38326,N,N,N,N,N,N,N,N,N,N,N,N,39382,N,38373,N,N,N,N,N,N,N,N,N, -N,N,N,39383,N,N,N,N,38325,N,N,N,N,N,N,N,N,N,N,N,41162,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40957,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,41048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36822,N,N,N,39384,N,N,N,N,N,N,N, -36819,N,N,N,N,N,N,N,N,N,N,N,N,36837,N,N,N,N,N,36841,N,N,N,N,39385,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36087,N,N,N,N,N,N,N,N,N,N,N,N,N,37500,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,40005,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36072,36830,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,36831,N,N,N,N,N,N,N,N,N,N,N,N,N,41035,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,36834,N,N,N,41164,N,N,N,N,N,N,N,N,36835,36836,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,39876,N,N,N,39932,N,N,N,N,N,N,38476,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,39670,N,36014,N,N,N,N,N,N,N,N,N,N,N,N,36839,N,N,N,N, -N,N,N,N,N,N,36840,N,N,N,N,35815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,35194,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,35195,39386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36845,N,N,N,38336,N,N,N,N,N,N,N,N,N,N,N,N,N,41163,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40520,N,N,N,N,N,N,39387,N,36851, -N,N,N,N,36857,N,N,N,N,N,N,N,N,N,N,N,N,N,38337,N,41038,N,N,N,N,N,N,39388,N,N,N, -N,41060,36855,N,N,N,N,N,N,N,35248,41032,N,N,N,N,36859,36854,N,N,N,N,N,40412,N, -N,N,39389,35816,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37569,N,N,N,N,N,N,N,40918,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41170,N,N,36928, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35524,N,N,39392,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,40944,40947,N,N,N,N,N,N,N,N,N,N,N,N,40383,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,40950,N,38344,N,N,40538,N,N,N,N,N,N,N,N,N,N,N,N, -39395,N,N,N,N,N,N,N,N,N,N,N,35402,N,N,N,N,N,N,N,N,40945,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,35495,N,N,N,N,N,N,N,N,39398,N,N,N,40951,N,40941,N,N, -N,N,N,N,35420,N,40366,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,38345,N,N,N,N,N,36936,N,N,39400,N,N,N,N,N,36937,N,N,36026, -N,N,37041,N,N,N,N,N,N,36938,N,N,N,N,N,N,N,N,N,N,39402,N,N,N,N,N,N,N,N,N,N,N, -39889,N,N,N,N,N,N,N,39403,N,39404,N,N,N,N,N,N,N,N,39405,N,N,N,N,39406,36940,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36941,N,N,38347,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,38882,N,N,N,N,N,N,N,N,38348,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40824,N,N, -N,N,N,N,N,N,N,35196,35197,N,N,N,N,N,N,35198,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39261,N,N,N,N,N,N,N,N,N,N,N,N,39770,N,N, -N,N,36944,N,35919,N,N,N,N,N,N,N,N,N,N,N,36948,N,50902,39592,39407,65259,40355, -40353,39235,39237,N,40317,N,N,39408,N,N,N,N,N,N,N,N,39409,N,39410,N,N,36028, -40288,N,N,N,N,N,N,N,N,N,41123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36955,40667,N,N,N,N,N,N,N,N,N,40313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39411,N,N,N,36962,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,40789,N,N,N,N,N,N,N,N,N,39929,N,N,N,N,N,N,N,N,N,N,36965,N,N, -38624,N,N,N,N,N,N,N,39102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36968,N,N,N, -N,N,36972,N,N,N,N,N,N,N,N,N,N,N,N,38360,N,N,N,N,N,N,N,N,36970,40882,N,N,N,N,N, -N,N,40878,N,N,40880,N,35245,N,N,N,N,N,N,N,N,36974,N,N,N,N,N,N,N,N,40561,N,N,N, -N,N,40522,N,N,N,N,N,40924,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35243,N,40888,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36976,N,N,N,N,N,N,N,N,N,N,N,N, -35683,N,N,N,N,38364,N,N,N,N,N,N,N,N,36977,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64606,N,N,N,N,N,N,N,N,35145,N,N,N,N,N,38491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35920,N,N,N,38054,N,N,N,36821,40563,N,N,N,N,N,36981,N,N,N,N,39415,N,N,N,N,N,N, -N,N,N,N,N,N,N,36031,N,N,N,N,N,N,39417,N,38499,38329,N,N,N,N,N,N,N,N,N,38100,N, -N,N,N,N,N,64762,N,N,N,N,36983,N,N,37035,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40269, -N,N,39418,N,N,N,N,37603,N,38843,N,N,36984,N,N,N,N,N,N,N,N,39419,N,N,38880,N,N, -N,N,N,N,N,N,38620,N,N,N,N,N,N,N,N,N,40104,N,N,38770,N,N,N,N,37952,N,N,N,N,N, -37618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39421,N,N, -39420,N,N,N,N,N,N,N,63959,38474,N,N,N,38616,39422,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36939,N,N,N,N,N,N,64065,N,N,N,N,N,N,N,39488,N,38747,N,N,N,N,N, -39489,37341,N,N,N,N,N,37884,39490,39491,N,38489,N,N,N,N,N,N,39492,36945,N,N,N, -38079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37026,N,N,N,40107,38774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64597,65093,38056,39493, -64075,40417,N,N,38617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38772,N,N, -65013,N,N,N,37605,N,38469,37338,N,37027,N,N,41055,N,N,N,N,37039,38847,N,N,N, -37196,N,N,N,N,38522,N,N,N,37342,N,N,39494,65200,38777,37996,N,N,N,N,N,N,N,N, -39000,N,N,N,N,N,N,N,N,N,N,N,37478,N,N,N,37883,N,N,N,N,N,N,N,N,N,N,N,N,39495,N, -N,N,N,N,N,N,N,N,N,38729,N,N,38728,N,37706,N,40162,N,N,N,N,N,N,37476,N,N,N,N, -37343,N,N,N,N,N,N,N,64377,N,N,N,N,N,N,N,38615,N,N,N,N,37699,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,64971,65146,N,37339,35946,38831,N,N,38365,N,N,N,37704,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,39499,N,N,N,64581,N,39501,N,N,N,N,N,N,37308,37090,37044,38369, -N,N,N,N,N,39502,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39503,N,N,N,65088,65091,N,N,N, -N,N,N,N,N,N,38621,N,N,N,N,N,N,39505,N,N,N,38567,N,N,37040,N,N,N,N,N,N,N,N,N, -40014,N,37955,N,N,N,N,36538,N,N,N,N,N,N,N,N,N,N,N,N,39506,N,64705,N,N,N,N,N,N, -N,N,N,35817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40111,N,N,35837, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39612,N,39608,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39598,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,39591,39507,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,40308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35818,N,N,N,N,N,N,35819,N,N,N,N,N,37042,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,38377,38376,N,38374,N,N,N,N,N,N,37045,N,39508,N,N,N, -37043,38375,N,N,35664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35820,N,N,N, -N,N,N,N,N,N,N,N,39510,35835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39511,N, -N,N,N,41130,N,N,N,N,N,N,N,N,40870,N,N,N,39372,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39349,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,37054,N,N,N,N,N,40879,N,N,N,N,N,N,N,N,N,N,N,N,N,38386,N,N,N,N,N,N,37055,N, -N,N,N,N,N,N,N,N,N,N,N,37057,N,65252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37060,N,N, -N,N,N,N,37063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37604,40786,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,37083,N,N,N,N,N,41062,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37074,N,N,34667,N,37076,N,N,N,N,N,N,N,N,N,39515,38397,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,35780,N,N,N,35942,N,37086,N,N,N,N,N,40164,N,37089,N,N,N,N,N,N,N,N,N,N,N, -N,N,40518,N,N,N,38481,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64344,N,37094, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38480,N,N,N,37095,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,37096,39517,N,40826,N,N,N,39772,N,40828,N,N,64594,37097,N,37098,N, -39518,N,N,N,N,N,40822,N,N,N,N,N,N,N,N,N,37099,N,N,N,N,N,N,N,N,N,N,N,N,N,37100, -N,N,N,N,N,35822,N,N,N,N,N,N,N,37102,N,N,N,37318,N,N,37106,64700,35444,N,N,N,N, -N,N,N,N,N,38487,N,N,N,40175,N,N,N,N,N,N,N,N,N,N,40927,N,N,N,N,37111,37110,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39774,N,N,N,37112,N,N,N,N,N,N,N,N,N,N,36092,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,37113,N,36041,N,N,N,64106,N,N,N,N,N,N,N,N,35823,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40928,N,N,37186,N,39522,N,N,N,N,N, -N,N,N,N,38249,N,N,N,37188,37187,N,37185,N,N,N,35824,N,N,N,N,N,N,N,N,N,N,N,N,N, -38496,N,35825,N,39414,37193,N,N,N,N,37194,N,N,N,N,N,37195,N,N,N,N,39524,N,N,N, -35519,39526,N,N,N,N,N,N,N,N,N,N,39527,N,N,39529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,39530,38482,37197,N,38502,N,N,N,N,40827,N,39531,N,N,N,N, -N,N,N,41068,N,N,38503,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39532,N,N,N,N,39533,35826, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38506,N,N,N,N,N,N,N,N,64746,N,N,N,N,N,38508,N, -N,N,N,N,N,N,N,N,N,N,N,N,37316,N,N,N,38519,N,N,N,N,N,N,N,39412,39535,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40875,N,N,N,N,N,36030,36545,N,N,N,N,38229,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,37202,37203,N,N,N,37205,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38237,N,38513,N,N,N,N,40045,N,N,N,N,N,N,N,N,38515,N,N,N,N,N,N,N,N,N,N,N,37204, -39537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37206,N,N,N,38509, -N,N,N,N,N,N,38231,N,N,N,N,N,N,N,N,35270,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,35434,N,N,N,35671,N,N,N,40929,N,N,39775,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41053,N,N,N,N,N,N,N,N,37211,N,37212,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37214,N,N,N,N,N,N,N,N,N,N,40796,40791,N,N,N,N,N, -N,40805,N,N,N,N,N,39538,N,N,N,N,37216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,40798,N,N,37217,N,N,N,N,N,N,37220,N,N,N,N,40769,N,N,N,N,N,N,37225,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,37224,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38578,N,39541,N,64933,N,N,N,N, -N,N,N,40681,N,35770,37229,41056,N,N,N,N,N,N,N,40926,N,N,N,N,N,40899,N,38581,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,38579,N,N,N,N,N,N,N,N,N,N,N,N,N,39542,N,N,N,N,N,N,N,N,N,N,N, -38357,N,N,N,40650,N,N,N,39543,N,N,39544,N,N,N,N,N,N,N,N,N,N,37232,37231,N,N,N, -N,N,N,N,40867,N,37233,N,N,N,38577,N,N,N,N,40803,N,N,N,N,N,40807,N,N,N,35769, -39546,N,N,N,N,N,35670,N,N,N,N,N,N,N,N,39642,N,N,N,N,N,38576,N,N,N,N,39550,N,N, -N,N,N,N,N,N,N,N,40414,N,N,N,N,N,N,N,N,N,38573,N,N,N,38574,N,N,N,N,N,N,N,N,N, -40609,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40528,N,N,N,N,N,N,N,N,38575, -35828,40868,N,N,N,N,N,N,N,N,N,38589,N,N,N,N,N,N,N,N,N,38644,N,N,N,N,N,N,N,N,N, -N,38584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64161,N,N,N,N,37287,N,N,N,N,N,N,N, -N,N,N,41054,N,N,N,N,39549,N,N,N,N,35144,N,40625,N,N,N,N,N,N,N,N,N,N,N,N,N, -40411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38335,35443,N,N,N,N,N,N,N,N,N,N,N,N,N,40702, -N,37242,N,N,N,N,37243,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39587,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,38594,N,N,N,N,N,40823,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39588,N, -N,39589,N,N,N,37281,N,N,N,N,35256,N,N,N,N,N,N,N,N,N,N,37235,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39590,35261,N, -35257,N,37245,N,N,N,N,N,N,N,N,N,38587,N,N,N,40946,N,N,35829,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,39593,N,N,N,N,N,40788,N,N,40931,40685,N,N,N,N,N,N,N,N,N,N,37290,N,N,N, -N,37291,41072,N,40813,N,N,N,N,N,37292,N,N,N,37293,N,N,N,41213,N,40930,N,37295, -40513,39594,N,N,37296,N,39595,N,N,N,N,N,N,N,N,N,N,N,39596,N,39498,N,37298,N,N, -35830,N,39597,35254,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39599, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,39600,N,N,N,N,N,N,39601,N,N,N,N,N,39585,37305,N,N, -N,N,N,37306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37310,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -41025,35767,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37312,N,N,N,N,N,N,N,N,N,N,39603, -37315,N,N,N,N,N,N,N,N,N,N,41212,N,N,40942,N,N,N,N,N,N,40809,N,N,N,N,N,N,N, -37320,N,N,N,N,N,N,37321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36326,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,37323,N,N,N,N,N,N,N,N,N,N,35272,N,N,N,N,N,36266,N,N,N,N, -N,40925,35907,35949,35956,36023,36025,36027,36032,36055,36056,36058,51361, -51363,36077,36168,35832,51408,N,N,N,N,51407,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50916,N, -50917,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,51405,N,51406,N,N,N,N,N,N,N,N,63998, -}; - -static const struct unim_index big5hkscs_bmp_encmap[256] = { -{__big5hkscs_bmp_encmap+0,168,252},{__big5hkscs_bmp_encmap+85,0,220},{ -__big5hkscs_bmp_encmap+306,80,198},{0,0,0},{__big5hkscs_bmp_encmap+425,1,81},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+506,190, -193},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+510,22,231},{0,0,0},{ -__big5hkscs_bmp_encmap+720,218,219},{__big5hkscs_bmp_encmap+722,96,125},{ -__big5hkscs_bmp_encmap+752,80,112},{0,0,0},{__big5hkscs_bmp_encmap+785,61,61}, -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+786, -128,227},{__big5hkscs_bmp_encmap+886,51,51},{__big5hkscs_bmp_encmap+887,5,254 -},{__big5hkscs_bmp_encmap+1137,192,207},{__big5hkscs_bmp_encmap+1153,49,49},{ -0,0,0},{__big5hkscs_bmp_encmap+1154,53,251},{__big5hkscs_bmp_encmap+1353,6,254 -},{__big5hkscs_bmp_encmap+1602,9,245},{__big5hkscs_bmp_encmap+1839,1,251},{ -__big5hkscs_bmp_encmap+2090,15,250},{__big5hkscs_bmp_encmap+2326,8,254},{ -__big5hkscs_bmp_encmap+2573,1,251},{__big5hkscs_bmp_encmap+2824,14,244},{ -__big5hkscs_bmp_encmap+3055,13,239},{__big5hkscs_bmp_encmap+3282,18,253},{ -__big5hkscs_bmp_encmap+3518,6,255},{__big5hkscs_bmp_encmap+3768,0,250},{ -__big5hkscs_bmp_encmap+4019,4,250},{__big5hkscs_bmp_encmap+4266,2,249},{ -__big5hkscs_bmp_encmap+4514,17,252},{__big5hkscs_bmp_encmap+4750,43,242},{ -__big5hkscs_bmp_encmap+4950,1,244},{__big5hkscs_bmp_encmap+5194,3,234},{ -__big5hkscs_bmp_encmap+5426,3,247},{__big5hkscs_bmp_encmap+5671,19,244},{ -__big5hkscs_bmp_encmap+5897,0,250},{__big5hkscs_bmp_encmap+6148,6,231},{ -__big5hkscs_bmp_encmap+6374,15,255},{__big5hkscs_bmp_encmap+6615,16,192},{ -__big5hkscs_bmp_encmap+6792,4,237},{__big5hkscs_bmp_encmap+7026,7,156},{ -__big5hkscs_bmp_encmap+7176,4,248},{__big5hkscs_bmp_encmap+7421,3,253},{ -__big5hkscs_bmp_encmap+7672,3,252},{__big5hkscs_bmp_encmap+7922,1,254},{ -__big5hkscs_bmp_encmap+8176,2,249},{__big5hkscs_bmp_encmap+8424,1,254},{ -__big5hkscs_bmp_encmap+8678,19,239},{__big5hkscs_bmp_encmap+8899,2,251},{ -__big5hkscs_bmp_encmap+9149,5,253},{__big5hkscs_bmp_encmap+9398,0,254},{ -__big5hkscs_bmp_encmap+9653,3,251},{__big5hkscs_bmp_encmap+9902,2,249},{ -__big5hkscs_bmp_encmap+10150,2,254},{__big5hkscs_bmp_encmap+10403,13,255},{ -__big5hkscs_bmp_encmap+10646,5,252},{__big5hkscs_bmp_encmap+10894,16,245},{ -__big5hkscs_bmp_encmap+11124,9,252},{__big5hkscs_bmp_encmap+11368,12,223},{ -__big5hkscs_bmp_encmap+11580,35,253},{__big5hkscs_bmp_encmap+11799,7,226},{ -__big5hkscs_bmp_encmap+12019,44,229},{__big5hkscs_bmp_encmap+12205,24,254},{ -__big5hkscs_bmp_encmap+12436,7,234},{__big5hkscs_bmp_encmap+12664,10,255},{ -__big5hkscs_bmp_encmap+12910,24,241},{__big5hkscs_bmp_encmap+13128,2,254},{ -__big5hkscs_bmp_encmap+13381,0,202},{__big5hkscs_bmp_encmap+13584,0,250},{ -__big5hkscs_bmp_encmap+13835,3,246},{__big5hkscs_bmp_encmap+14079,5,250},{ -__big5hkscs_bmp_encmap+14325,28,255},{__big5hkscs_bmp_encmap+14553,2,254},{ -__big5hkscs_bmp_encmap+14806,2,250},{__big5hkscs_bmp_encmap+15055,4,248},{ -__big5hkscs_bmp_encmap+15300,3,254},{__big5hkscs_bmp_encmap+15552,5,246},{ -__big5hkscs_bmp_encmap+15794,0,226},{__big5hkscs_bmp_encmap+16021,2,251},{ -__big5hkscs_bmp_encmap+16271,2,248},{__big5hkscs_bmp_encmap+16518,5,220},{ -__big5hkscs_bmp_encmap+16734,2,217},{__big5hkscs_bmp_encmap+16950,12,254},{ -__big5hkscs_bmp_encmap+17193,8,245},{__big5hkscs_bmp_encmap+17431,6,244},{ -__big5hkscs_bmp_encmap+17670,6,254},{__big5hkscs_bmp_encmap+17919,11,252},{ -__big5hkscs_bmp_encmap+18161,18,252},{__big5hkscs_bmp_encmap+18396,37,254},{ -__big5hkscs_bmp_encmap+18614,7,223},{__big5hkscs_bmp_encmap+18831,6,250},{ -__big5hkscs_bmp_encmap+19076,2,246},{__big5hkscs_bmp_encmap+19321,3,246},{ -__big5hkscs_bmp_encmap+19565,24,255},{__big5hkscs_bmp_encmap+19797,11,237},{ -__big5hkscs_bmp_encmap+20024,5,248},{__big5hkscs_bmp_encmap+20268,3,252},{ -__big5hkscs_bmp_encmap+20518,2,239},{__big5hkscs_bmp_encmap+20756,112,245},{ -__big5hkscs_bmp_encmap+20890,4,255},{__big5hkscs_bmp_encmap+21142,0,231},{ -__big5hkscs_bmp_encmap+21374,28,249},{__big5hkscs_bmp_encmap+21596,12,226},{ -__big5hkscs_bmp_encmap+21811,81,247},{__big5hkscs_bmp_encmap+21978,3,212},{ -__big5hkscs_bmp_encmap+22188,1,242},{__big5hkscs_bmp_encmap+22430,25,249},{ -__big5hkscs_bmp_encmap+22655,8,196},{__big5hkscs_bmp_encmap+22844,81,254},{ -__big5hkscs_bmp_encmap+23018,8,253},{__big5hkscs_bmp_encmap+23264,3,244},{ -__big5hkscs_bmp_encmap+23506,1,246},{__big5hkscs_bmp_encmap+23752,45,244},{ -__big5hkscs_bmp_encmap+23952,29,244},{__big5hkscs_bmp_encmap+24168,3,245},{ -__big5hkscs_bmp_encmap+24411,20,245},{__big5hkscs_bmp_encmap+24637,14,245},{ -__big5hkscs_bmp_encmap+24869,12,255},{__big5hkscs_bmp_encmap+25113,2,255},{ -__big5hkscs_bmp_encmap+25367,2,124},{__big5hkscs_bmp_encmap+25490,2,252},{ -__big5hkscs_bmp_encmap+25741,10,254},{__big5hkscs_bmp_encmap+25986,2,179},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{__big5hkscs_bmp_encmap+26164,7,7},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{__big5hkscs_bmp_encmap+26165,2,237}, -}; - -static const DBCHAR __big5hkscs_nonbmp_encmap[29306] = { -40049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37749,N,N,N,N,N, -N,N,37750,N,N,N,N,N,N,N,38216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,36550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35781,35834, -N,N,51324,N,N,N,N,N,N,N,N,N,39604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34894,34891, -51322,34888,N,N,N,34887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,41206,34885,N,34899,N,N,N,N,N,N,N,N,N,64685,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36085,N,N,N,N,35501,N,37490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,64583,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38111,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40913,64459,N,N,N,N,N,N,N,37501,N,N,N,N,N,N,N, -39076,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38119, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37067,37499,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38104,N,N,N,N,64607,N, -64084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39605,N,N,N,N,N,N,N,38618, -37497,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64116,37493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36347,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35401,N,N,N,37599,39804,64099,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,64096,37485,64098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39606,N,N,N,N,N,N,38763,N,N,N,N,N,N,N,N,N,N,N,N, -N,64874,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64852,N,37491,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38872,N,N,N,N, -N,N,40891,37698,37494,N,N,N,N,N,N,N,N,N,N,64101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,64110,N,N,N,N,N,N,40672,N,N,37568,37567,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,37566,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39610,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35507,N,38773,64064,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64118,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,64464,N,N,N,N,N,N,N,N,N,N,N,N,N,64123,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,65133,N,N,N,N,N,N,39859,N,N,N,N,N,35276,N,N,N,N,39614,N,N,N,N,N, -N,N,N,N,64066,37564,N,N,N,N,N,N,N,N,N,N,37980,39861,N,N,N,39615,N,N,N,39079, -38820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37117,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64635,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39616,37571,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39888,38224,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37574,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39078,38214,N,N,N,N,N,N,N,N,N,N,N,N,64867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64194,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40643,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35250,40038,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36947,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,35938,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,38849,N,N,N,N,N,N,N,N,N,N,N,N,N,39620,N,N,N,N,N,N,N,N,N,N,39621,36591,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,64233,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36160,N,N,N,N,N,N,N,N, -37474,35575,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39622,N,N,N,N,N,N,37601, -N,N,N,N,39625,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64198,N,N,N,N,N,N,N, -N,38821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39627,N,N,N,64114,35422,N,38112,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,37580,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35557, -N,N,N,N,N,65116,39628,N,N,N,N,N,40441,35395,35494,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,39629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,64238,39884,N,N,N,39631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39633,N,N,N,N,N,N, -N,N,40442,N,N,N,N,N,40316,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39635,N,N,38822,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39263,N,N,N,64502, -40901,35417,35691,N,N,N,N,N,N,39636,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39637,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,38818,35396,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40778,N,N,N,N,N,N,N,N,37025,64932,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35428, -35570,35576,40408,N,N,38102,64254,64423,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,39638,N,40781,N,N,64246,N,N,N,N,N,N,N,35415,N,35651, -35652,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35510,N,N,N,N,N,35520,N,N,N, -N,N,N,N,N,N,N,40532,N,N,N,N,N,N,N,N,N,N,39639,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,39640,39644,N,N,N,N,35530,40616,N,N,37475,39645,35685,35695,35710,N, -N,N,N,36675,N,N,N,N,N,N,37584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35572,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40382,N,N,N,N,N,39649,N,64734,40445,35686, -35696,35701,35556,35748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35565,N,N,N,N,N,N,N,N, -N,35421,N,35656,N,N,N,N,40429,N,N,N,N,40512,N,N,N,N,N,N,N,35567,35574,40566,N, -N,N,N,N,N,N,N,N,40675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,39646,36350,N,N,N,N,64252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,40113,40567,35684,35687,38731,N,N,N,N,N,N,N,N,38483,N,N,N,N,N,N,39648, -35658,N,35569,35543,N,N,N,N,N,N,N,N,N,41131,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35509,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35423,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35566,N,N,39647,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35582,N,N,N,N,N,N,35416, -35747,35751,N,N,N,N,N,39651,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,37473,N,N,N,N,N,N,N,N,N,N,40407,40573,40615,40619,36930,N,N, -N,N,N,N,N,N,35705,35706,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39654,N,N,N,N,N,N,N,N,N,N,N,N,39653, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35454,N,N,N,N,N,40516,39655,35452,35697,N, -N,39657,N,N,N,N,N,N,N,N,N,N,N,N,39658,N,N,N,N,N,N,N,N,N,N,N,N,N,39659,N,N,N,N, -N,N,35517,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64334,N,N,N,N,N,N,N,N,N, -N,39661,35577,40547,N,N,N,N,N,35657,35534,35694,N,N,N,N,N,35560,N,N,N,39662,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37582,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35418,35707, -35708,39663,N,N,N,N,N,N,N,N,N,N,N,39664,N,35578,N,N,N,N,N,N,N,35137,N,N,35698, -N,N,N,N,N,N,35571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35752,N,N,N,N,N,N,40622,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40562,64371, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64351,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37050,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37374,40694, -N,N,N,N,N,N,38893,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39667,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,41198,38524,37701,39022,64086,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39669,N,N, -N,64587,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39668,65246,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,64695,N,N,N,N,N,N,N,N,N,38897,N,N,N,38855,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40139, -37440,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,40168,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37373,38734,N,N,64360,N,N,N,N,N,N,N, -N,N,N,N,N,N,38764,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36034,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38888,N,64362,35700,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,36583,N,N,N,N,N,N,N,N,N,N,N,N,64968,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,37441,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38561,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,36595,39671,N,N,N,N,N,N,N,N,N,N,36774,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,64214,40135,N,N,N,N,N,N,N,N,64215,N,N,N,N,N,39672,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64417,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36549,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64420,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,64450,N,39617,N,N,N,N,N,37370,65243,38827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37191,N,64433,N,N,N,N,N,N,N,N,N,36842,N,N,N,N,N,N,38098,65121,64206,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,37613,37363,37830,N,37722,64251,N,N,37615,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38983,37734,38997,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38630,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40771,40874,38106,37614,64687,64507,N, -36601,37366,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37732,N,N,N,N,38133,40118,64429, -38990,36676,38653,N,N,N,N,N,N,N,N,N,N,N,N,N,39673,N,N,N,39674,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,38761,38356,38987,64426,N,N,39036,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,37354,N,N,N,N,N,40367,40389,N,37361,36529,38825,64428,64696,40121,N,N,N,N, -N,N,N,64432,64722,37835,N,N,39677,N,N,N,N,N,N,N,N,N,N,N,37364,35756,41045,N,N, -N,N,38260,N,N,N,N,38334,N,N,N,N,N,N,N,N,N,N,N,N,38829,N,N,N,N,N,N,N,N,N,N,N, -36585,N,N,37624,38846,37228,38058,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64611,N, -N,N,40390,N,N,N,N,N,N,N,38837,37560,37359,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,65190,38752,37720,38262,36780,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,37356,38836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37367,N,N,N,N, -38730,64329,38264,37820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,37334,37717,37718,38993,N,N,N,N,N,N,N,N,N,N,36856,64448,37874,N,N, -37072,N,N,N,N,N,N,40004,N,N,N,N,N,37461,N,N,N,N,37731,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,37285,N,N,N,N,N,N,N,N,41197,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,64875,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,37713,N,N,N,35927,N,N,64120,N,N,N,N,65192,N,N,N,N,N,N,N,N,N,N,N,N,N,37712, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64076,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37623,39744,N,N,N,N,N,N,64462,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,39745,N,N,N,N,N,65197,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,34657,64469,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35778,39548,39746,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39747,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40569,N,N,64473,N,N, -N,N,N,N,39748,41127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34670,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,39923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,35961,N,N,N,37726,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35275,N,N,N,N, -N,N,40787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37847,N,N,N,N,N,N, -N,N,N,N,N,N,N,64481,65232,N,N,N,N,N,N,36081,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,64482,N,N,N,N,N,64739,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,36980,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64486,N,N,N,39863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,39749,N,N,N,N,N,N,N,N,N,N,N,N,39751,40784,N,N,N,N,N,39752,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64603, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,39081,N,N,40189,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,34892,39755,N,N,N,64492,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35945,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39848,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35541,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64115,64857,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37282,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64493,N,N,N,N,N,N,40105,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35496,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36162,N,39875,35553,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39758,38352,N, -N,N,36959,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64590,N,N,N,N,N,N,39759,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39760,40646,N,N,N,N,N, -N,N,N,N,N,N,64592,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64883,N,N, -N,N,N,64935,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40354, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64088,64094,N,N,N,N,N,N,N,41049,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64446,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37744, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,37745,37751,65263,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37741,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64605,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,37048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35580,N, -64321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40555,38115,36578,35965,N,36567,N,N,N,N,N,N, -40013,N,N,N,38563,N,N,N,N,N,N,N,N,N,N,39761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35523,N,N,N,N,N,N,N,N,N,N,N,38570,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,64616,35693,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64871,35561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64673,37740,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,39762,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65136,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,64680,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64745,40116,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,35562,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39763,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39765,N,N,N,38571,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,64679,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39766,35516,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35531,N,N,N,N,N,39767,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,35277,N,39769,39771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37797,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39773,N,N, -N,40527,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37795,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35451,N,N,N,35650,38736,36787,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35408,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39776,N,N,N,N,35653,N,N,N,35654,N,N,N,N,N,N,N,N,N,N,N,N,40446,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39778,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,37755,N,N,N,N,N,37809,N,N,N,N,N,N,N,35424,N,N,N,N,N,N,N, -N,35544,N,N,N,N,39779,N,N,N,N,N,N,N,N,N,N,35433,N,N,N,35399,N,N,35532,37756, -39781,N,N,N,N,N,N,N,N,N,39782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35442,N,N,N,N,N,N,N,35450,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37807,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35504,N,N,N,N,N,N,N,39784, -N,N,N,N,N,N,N,N,N,N,40611,N,N,64236,35703,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39783,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35673,64689,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64699,N,N,N,N,N,N,N,N,N,N,N, -39785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37800,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35552,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,40529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36703,39786,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,39787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38892,39788,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,65102,N,N,N,N,N,N,64962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,39789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37223, -64716,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37092,N,N,N,N,37093,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40690,37834,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,35772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36678,N,N, -N,N,37839,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64731,64732,N,N,N,N,N,N,N,N,N,N,N,N,N,37824,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,64742,38631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64728,64729,64934,37838,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,38385,N,N,N,N,N,N,N,N,N,40169,N,64740,38063,64119,37836,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36065,N,N,N,N,N, -N,N,N,N,N,N,36954,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35924,N,N,N,N,N,N,N,37823,64337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,37817,65239,37815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37849,N,N,N,N,N,N,N,N,N,N,N,N,N,37819,37850, -39075,N,N,N,N,N,N,N,N,N,37073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39790,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64112,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39915,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39791,N,N,N,N,N,N,N,64764,N,N,N,N,N,N,N,N,N,N,N,N,N,35648,41083,N,N,N,36001, -38903,N,N,N,37858,64726,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38233,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,64832,N,N,37727,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,38898,40054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,36600,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36075,N,N,N,N,N,N,N,N,36679,N,N,N,N,N,N,N,N,N,N,N,N,39796,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37556,N, -N,N,37357,N,N,38610,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64838,36687,38217,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39797,64092,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,34641,N,N,39801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64843,N,N,N,38611,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,64856,N,N,N,N,N,37983,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,41205,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,37443,N,N,N,N,N,N,38906,N,N,N,N,N,N,N,N,N,N,N,N, -40409,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38900,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37453,64859,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,39802,N,N,N,N,N,N,N,N,N,40661,N,N,N,N,N,N,N,N,N,N,N,N,64174,N,40137,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,37464,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,36552,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,38068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37857,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37855,N,N,N,N,N,64752, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37868,38902,38607,37854,35535,39842,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,64873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37714,N,N,N,N,N,N, -N,N,N,N,N,39074,36071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64878, -36004,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64124,37882,36988,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,36711,N,40375,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41193, -64078,64929,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40564,40895,40651,39865,40404,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38841,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38267, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40658,38739,38564,36798,38105,36952,64889,64891,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36570,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36602,34658,N,N,N,N,N,N,N,N,N,N,39845,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,40665,38868,37051,64956,64966,37448,N,N,N,N,N,N,N, -37557,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,40385,37561,37542,36683,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39846,N,N,N,N,N,37558,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36416,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,40664,37982,39007,38094,37450,64880,37991,N,N,N,N,N,N,N, -N,N,N,N,36332,N,N,N,N,N,N,N,N,39896,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,34659,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37960,64193, -40183,64958,N,N,N,N,N,N,N,N,N,N,N,N,36826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64985,N,N,64638,N,N,N,N,N,N,N,N,37881,N,N, -N,N,64067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,64235,64195,38867,38393,40008,64984,41176,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64983,64330,39855,37963,64969, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36524,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64946,N,N, -N,N,N,37466,64701,37593,N,N,N,64981,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37597,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37465,N,N,N,N,N,N,N,N,N,N,36080, -38586,N,N,N,N,N,N,N,N,N,N,37467,N,N,N,N,N,N,N,N,N,39851,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64986,64990,N,N,N,64979,N, -N,N,N,N,N,N,N,N,35910,N,N,N,N,N,N,64982,64988,64989,N,N,N,N,37118,N,N,65185,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35757,N,N,40152,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40557,64892, -64353,N,N,N,N,N,N,38648,N,N,N,N,N,N,N,N,38640,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64756,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65120,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38994,38479,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37230,N,N,N, -N,N,N,N,N,N,N,39021,N,N,39012,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,37971,65004,64376,N,N,N,N,N,N,N,N,N,N,N,38330,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,39005,N,37625,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39002,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,34640,N,65014,N,N,N,N,N,N,N,37840,39010,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39853,N,N,N,N,N,N,N, -N,N,N,N,38735,39854,N,N,N,N,N,N,N,N,N,N,N,N,37970,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,39856,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37330,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38890,64363,37297,65011,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37579,N,N,N, -N,N,N,N,N,N,39857,N,N,N,N,N,64748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,39019,N,N,N,38737,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39025,38383,N,N,N,N,N,N,N,40691,N,N,N,N, -N,37352,39866,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64332,37482,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65016,39009,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,37351,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37869,38724,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,37345,N,N,64501,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39017,N,N,N,N, -35426,N,N,39867,36008,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,36471,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35506,40636,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37862,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37794,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37757,40550,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37977,N,N,N,N,N,N,N,N,N,39871,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,37976,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40613,39879,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,65108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,35798,N,N,N,N,N,N,38070,64884,39104,38053,N,N,N,N,N,N,N, -39880,N,N,N,38381,64894,64491,N,N,N,N,N,N,N,N,N,N,64893,N,N,N,N,N,N,N,N,N, -38767,37985,N,40897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38359,N,N,N, -64082,40024,N,N,N,N,N,N,N,N,N,40808,39911,64718,38632,64073,38817,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38221,40696,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,65097,37326,38769,N,N,N,N,36047,N,N,N,64945,N,N,64622,N,N,N,N,N, -40178,37816,36931,38745,38103,65126,38013,64623,N,N,N,N,37446,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64109,N,N,36599,N,64439,N,38012,37581,38834,N,N,N,N,N,N,N,N,N, -65125,38526,38744,39799,37327,N,N,N,N,N,N,N,N,N,38052,N,N,N,N,N,N,N,N,N,N, -40109,N,N,N,N,N,N,N,N,N,35755,N,N,N,38613,64691,N,N,N,37806,N,38765,N,N,N,N,N, -N,37958,38391,N,N,N,N,N,N,N,N,40006,38235,37329,38132,N,65127,37541,N,N,N, -65247,36011,N,39881,N,N,N,N,N,N,N,N,N,N,N,64749,65018,64712,65122,37372,65131, -65017,64711,37198,40120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38759,N,N,N, -38382,N,N,39858,N,N,N,N,37984,N,N,N,38050,39029,38828,37331,N,N,N,N,N,N,N,N,N, -N,N,39035,N,N,N,N,N,N,N,36587,38762,38494,N,N,N,N,N,N,N,N,N,38891,N,N,N,N,N, -40953,38392,65186,36838,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65150,N,N,N,N,N,N, -40356,38760,36588,38077,N,N,N,N,N,N,N,N,N,N,N,N,N,37979,40182,64167,39897,N,N, -N,N,N,N,N,N,N,64093,38486,38754,N,N,N,N,N,N,38074,41039,37592,N,N,N,39883,N,N, -N,N,N,N,38075,N,N,40287,N,N,N,N,N,N,37071,N,N,N,N,N,N,N,N,N,N,N,N,N,37989,N,N, -40780,N,N,N,N,N,N,37080,36187,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40638,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,64365,38346,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,40386,38904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36860,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38003, -38004,N,N,N,N,N,N,N,N,N,N,N,N,65207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35403,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35413,35689,35548,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35702,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39886,N,35432,41208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,39135,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,65205,N,N,N,39887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38651,N, -N,39931,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40654,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36581,N, -N,N,N,N,N,N,N,N,40571,39890,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,35493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,65230,35397,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,40444,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65231,35749,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35914,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,35564,N,N,64736,38061,65237,38060,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64602,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39894, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,35439,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35753,36447,N,N,40395,N, -64743,39895,N,N,N,N,N,N,N,N,N,N,N,37832,N,N,N,N,N,N,N,N,N,37360,36832,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39899,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37101,N,39900,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36179,41196,N,N,N, -39162,N,N,N,N,N,N,N,N,N,39904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37831,37449,38625,39906,N,N,N,39908,N,N,36833,39909,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38080,N,N,37827,N,N,N,N,N,N,N,N,N,N,37829,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36985,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38779,N,N,N,N,N, -36990,N,N,N,N,65254,65094,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,37488,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38312,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36016,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,38088,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39097,37184,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64702,N,N,N,N,N,N,N,37207,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35762,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64223,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,39910,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38467,36420,40015,65268, -N,N,N,N,N,39912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37852,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38511,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36426,39917,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37622,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40377,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,36430,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,64463,34656,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40642, -N,N,N,N,N,N,38117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39920,38116,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,38225,35771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39921,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,38128,36452,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38122,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36705,N,N,N,39780,36443,N,N,N,N, -39922,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40894,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40393,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36460,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36723,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,36015,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,36725,36465,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36448,36458,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,35916,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38226,38228, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40379,38211,37630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,38130,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38129,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41194,40402,41137,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37368, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37986,39844, -36525,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40621,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38608,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65262,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,35508,N,N,N,N,N,N,N,N,N,N,N,N,38743,35447,39927,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36533,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41069, -36534,38742,38208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,41203,38078,N,N,N,39930,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64991,40380,N,N,N,N,N,N,N, -N,38142,N,N,N,N,N,N,N,N,35803,41214,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,36544,40775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35806,41211,N,N,N,N, -36547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38473,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,65218,N,N,38220,39933,N,N,N,N,N,N,N,N,N,N,N,N,N,37068, -40032,38219,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39934,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,40003,N,N,N,40007,36556,N,N,N,36436,N,N,N,N,N,N,N,N,N,N,36580, -40009,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38238,N,N,N,N,N,N,N, -N,N,N,N,N,38236,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40011,35809,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,36569,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40372,N, -37471,N,N,N,40012,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,35489,N,N,N,N,N,N,N,N,N,N,N,N,N,36571,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,40022,35490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,38740,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40030,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40660,38248,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,41155,35558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,41207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40033,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64589,N,40539,N,N,N,N,N,N,N,N,40553,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40035,65223,N,N,65222,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40039,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,40041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,37221,N,N,N,N,N,N,N,N,N,N,N,N,40167,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,35412,N,N,N,N,N,N,N,40044,40046,65117,N,N,N,N,N,40051,N, -N,N,N,N,N,N,N,N,N,N,N,N,38250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38253,36592,36685,N, -N,N,N,36598,N,N,N,N,N,N,N,N,64188,N,36053,N,N,N,N,N,N,N,N,N,N,N,N,N,34654,N,N, -N,N,64474,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,35660,64885,39901,64245,N,N,N,N,N,N,N,40052,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,38213,N,N,N,N,N,N,N,N,N,N,N,N,38598,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,36714,36686,N,N,N,N,N,40056,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64085,N,N,N,N,N,N,N,N,N,N,N,N,38884,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,40001,37468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38650,36086,N,N,N,N,36173,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64358,36453,38985, -64424,38978,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40058,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38907,37066,N,N,N,N,40027,N,N,38733, -N,N,36563,N,N,N,N,N,N,N,N,N,N,N,N,N,38241,40779,40885,37842,64938,38976,37190, -39015,64090,64425,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,38977,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,36051,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,64765,64939,37309,36684,38601,36693,64430,38255,N,N, -N,N,N,N,40061,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,41200,N,N,N,N,N,N,N,N,N,N,N,N,N,37999,64940,N,N,N,N, -38603,38606,N,N,N,N,41046,N,40161,N,N,N,N,N,N,N,N,N,N,38596,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -36702,36716,36515,64435,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,64595,N,N,N,64947,N,N,N,N,36715,N,N,N,N,N,N,N,N,N,N, -N,N,38602,N,N,N,N,N,N,34643,N,N,N,N,N,N,N,N,N,N,N,N,N,36729,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,40559,41157,64632,36418,36698,37058,36517,36961,37455,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37747,64949,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,65228,N,64445,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36054, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38979,38597, -35260,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40099,N,N,N,N,N,N,37451,38986, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,36772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,41201,40699,40146,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,36775,N,N,N,N,34644,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64604,38981,N,N,36934,36049,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65274,38240,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,40776,37447,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37115,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,40100,38257,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,34629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40102,N,N,N,N, -40103,N,N,N,N,N,40106,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,40659,N,N,N,40560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40108,34642,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36782,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,36176,38269,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40112,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38838,N,41149,35551,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,36797,N,N,N,36799,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37737, -39847,51364,N,N,N,N,65258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,39905,N,N,N,N,N,N,35649,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,40374,41195,39843,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,35745,36808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,35148,39008,N,N,N,N,N,N,N,N,N,N,38087,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,35672,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38315,38314,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,40131,40132,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,40364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35814,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35441,36817,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,39381,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37108,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35491,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40142,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40148,40149,N,N,N,64456,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40371,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64624,N,N,N,N,N,36823,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39795,N,N,N,N,N,N,N,N,N,N,64091,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36818,36964,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39094, -38504,N,N,N,N,40150,N,N,N,N,N,N,N,N,N,N,N,N,39101,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36828,65270,36825,N,N,N,N,N,N,N,N,N,N,N,N,N, -38209,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,34668,N,N,N,N,38899,39928,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -34650,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34632,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34634,40556,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36850,36846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,40151,N,N,N,N,N,N,N,N,N,N,N,N,40558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35392,N, -N,N,N,N,N,N,N,N,N,36847,N,N,N,N,N,N,N,N,36852,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,38338,39018,N,38863,40677,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40572, -36929,N,N,N,N,N,N,40155,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37953,N,N,N,N, -40166,40368,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,40170,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40173,N,N,N,N,N,N,N,N,N,N,N,N, -40186,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,35682,35406,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40138,35430,N,N,N,N,N,N,N,N,N,N,40187,40188,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40190,N,N,N,N,N, -N,N,N,N,N,N,N,N,35411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40165,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40256,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40257,N,N,N,N,N,N,N,N,N,N,N,N,36933,35699, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38858,N,40258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,35425,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,35758,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35538,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,35746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40434, -40259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40159,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,40260,N,N,N,N,N,N,N,N,N,N,36554,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36942,N,N,N,N,N,N,N,36531,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,40949,N,N,N,N,N,N,N,N,N,N,N,N,40261,36943,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,40263,N,N,N,35274,N,N,N,N,N,N,40117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64510, -36958,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36963,36951,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36966,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,39872,N,N,N,N,N,N,N,N,N,N,N,64741,37218,N,N,N,N,N,N,N,N,N,N,36967,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36769,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,36770,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,40264,64211,N,N,N,N,N,N,36175,N,N,N,N,N,N,N,N,N,36957,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37049,N,N,N,N,N,N,N,N,N,N,N,N,N,36971, -35932,N,N,N,36969,65111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,65109,36979,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -39919,40176,N,N,N,N,N,N,N,N,N,N,N,N,40267,N,N,N,N,N,N,N,N,N,N,N,N,N,65241,N,N, -N,65242,N,N,N,37344,36163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37336,N,N,N,N,N,N,N, -N,N,N,38470,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37728, -N,64083,40147,N,N,N,N,N,N,N,N,N,N,N,N,40270,N,N,N,64320,N,N,N,36322,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37954,N,36950,N,N,39013,N,35948, -64074,N,N,40272,40274,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38319,38746,37705,38727, -41204,N,N,N,N,N,N,38776,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36815,N,N,N,64608,N,N,N,N, -N,N,N,N,35918,N,N,N,64598,N,N,N,N,N,N,N,N,N,N,N,N,N,37340,38497,37612,37725, -36574,38654,64847,38366,N,N,N,N,N,N,N,N,N,N,N,N,N,39088,41024,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38845,38781,38901, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39852,64218,37570,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38833,N,N,N,N,N,36987,N, -N,N,N,37886,38011,N,38775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64190,64835,37062, -37028,37032,38057,N,37033,N,N,N,N,35941,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38368,36989,N,N,N,N,N,N,37477,N,N,N,N,N,N,N,N,N,N,N,N,N,64954,37828,N,N,N,N,N, -N,N,N,65261,40363,41187,N,38472,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40275,N,N,N,N,N,35497,N,39877,N,38493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -38751,38495,38510,64349,N,N,N,N,N,40369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65187,N,N,N,N,N,N,N,N,N,40370,N,N,38318,64675,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34665,N,N,N,N,N,N,N,N, -41122,N,N,38485,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40276,N,N,37697,N,38317,37333,N,N, -N,N,N,N,N,N,N,N,N,N,38778,65020,36423,37885,37029,37036,N,N,N,N,N,N,N,N,38316, -N,N,N,N,N,N,N,N,N,37038,65189,N,N,N,N,N,40278,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,38883,38370,N,N,N,N,N,37990,N,N,38471,N,N,N,N,37304,N,N,N,N,40172,N,N,N,N, -N,N,N,N,37037,N,38371,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35663, -N,N,35555,N,N,N,N,35661,38378,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35662,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36033, -35821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,37337,N,N,41124,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,38389,38388,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40883,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,65199,N,N,N,N,N,65138,37498,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65196,N,N,N,N,N,N,N,N,N,N,N, -N,N,38387,40280,36166,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37746,N,N,37317,N,N,N,N,N,N, -N,38466,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37069,38398, -37209,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38860,37070,N,N,N,N,N,N,40281,64757,65277,N,N, -40283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,40284,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37758,N,N,N,N,N,N,N,N,N,N, -N,N,N,39084,N,N,40286,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64976,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64864,N, -N,N,N,N,N,N,N,N,N,N,40143,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37088,37107,N,N,39089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37104,N,N,N,N, -N,N,N,N,N,N,N,37821,N,N,N,N,N,N,N,N,38327,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40774,N,N,N,N,N,N,N,N,36427,38488,N,N,N,N,N,N,N,N,N,N,35404,N,40291,40655,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40293,N,N,N,N,N,N,N,40294,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40292,N,N,N,N,N,N,N,N,N,N,35436,35545,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40295, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,35440,35827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,40129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,40296,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37799,N,N,N,N,N,N,38516,N,N,N,N,N,N,N,N,36093,41199,N,37201,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38593,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34679,N,35940,38518,40297,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,64676,N,N,N,N,N,N,N,N,N,N,N,N,40298,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37454,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,40299,N,N,N,N,N,39873,40300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,35429,37213,N,N,N,N,N,N,N,N,40301,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37210,35906,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40128,37226,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,40302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,40614,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40397,N,N,40303,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35259,40697,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38580,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,37234,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -40648,N,N,N,34673,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35669,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,40305,40306,N,N,N,N,N,N,N,N,N,N,N,N,40652,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,37236,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,40656,36956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,36562,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37288,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37239,N,N,N,N,N,N,N,N,N,N,N, -38591,N,N,N,N,N,38592,N,N,N,N,36785,N,N,N,N,N,38583,35925,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37240,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35262, -37244,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64375,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37237,37283,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,37238,N,N,N,N,N,N,N,N,38590,36169,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37241,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,38582,37284,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -37286,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40309,N,N,N,N,N,N,N,N,N,N,N,36946,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41029,N,37289,N,39082,N,N,N,35935,N,N,35754,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40157,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40311,34646,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,35136,40684,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,37802,38008,N,N,N,N,40314,35529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35659,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40940,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -35554,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,40565,39028,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39624,N,N,N,N,41031, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35779,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64631,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40018,36605,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36776,N,N,N,N,N,N,N,N,N, -38266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36848, -}; - -static const struct unim_index big5hkscs_nonbmp_encmap[256] = { -{__big5hkscs_nonbmp_encmap+0,33,238},{__big5hkscs_nonbmp_encmap+206,12,242},{ -__big5hkscs_nonbmp_encmap+437,4,229},{__big5hkscs_nonbmp_encmap+663,10,252},{ -__big5hkscs_nonbmp_encmap+906,19,254},{__big5hkscs_nonbmp_encmap+1142,71,235}, -{__big5hkscs_nonbmp_encmap+1307,17,118},{__big5hkscs_nonbmp_encmap+1409,14,121 -},{__big5hkscs_nonbmp_encmap+1517,44,213},{__big5hkscs_nonbmp_encmap+1687,22, -231},{__big5hkscs_nonbmp_encmap+1897,17,205},{__big5hkscs_nonbmp_encmap+2086, -13,255},{__big5hkscs_nonbmp_encmap+2329,11,255},{__big5hkscs_nonbmp_encmap+ -2574,21,200},{__big5hkscs_nonbmp_encmap+2754,4,251},{__big5hkscs_nonbmp_encmap -+3002,29,237},{__big5hkscs_nonbmp_encmap+3211,20,246},{ -__big5hkscs_nonbmp_encmap+3438,47,217},{__big5hkscs_nonbmp_encmap+3609,60,254 -},{__big5hkscs_nonbmp_encmap+3804,2,254},{__big5hkscs_nonbmp_encmap+4057,19, -253},{__big5hkscs_nonbmp_encmap+4292,119,150},{__big5hkscs_nonbmp_encmap+4324, -10,254},{__big5hkscs_nonbmp_encmap+4569,13,252},{__big5hkscs_nonbmp_encmap+ -4809,32,250},{__big5hkscs_nonbmp_encmap+5028,3,243},{__big5hkscs_nonbmp_encmap -+5269,45,99},{__big5hkscs_nonbmp_encmap+5324,68,194},{ -__big5hkscs_nonbmp_encmap+5451,42,172},{__big5hkscs_nonbmp_encmap+5582,70,249 -},{__big5hkscs_nonbmp_encmap+5762,28,213},{__big5hkscs_nonbmp_encmap+5948,15, -232},{__big5hkscs_nonbmp_encmap+6166,69,252},{__big5hkscs_nonbmp_encmap+6350, -42,195},{__big5hkscs_nonbmp_encmap+6504,8,124},{__big5hkscs_nonbmp_encmap+6621 -,33,250},{__big5hkscs_nonbmp_encmap+6839,101,237},{__big5hkscs_nonbmp_encmap+ -6976,19,190},{__big5hkscs_nonbmp_encmap+7148,27,246},{ -__big5hkscs_nonbmp_encmap+7368,18,205},{__big5hkscs_nonbmp_encmap+7556,3,247}, -{__big5hkscs_nonbmp_encmap+7801,38,147},{__big5hkscs_nonbmp_encmap+7911,102, -232},{__big5hkscs_nonbmp_encmap+8042,14,206},{__big5hkscs_nonbmp_encmap+8235, -38,201},{__big5hkscs_nonbmp_encmap+8399,7,238},{__big5hkscs_nonbmp_encmap+8631 -,13,239},{__big5hkscs_nonbmp_encmap+8858,116,227},{__big5hkscs_nonbmp_encmap+ -8970,51,218},{__big5hkscs_nonbmp_encmap+9138,3,249},{__big5hkscs_nonbmp_encmap -+9385,15,225},{__big5hkscs_nonbmp_encmap+9596,0,254},{ -__big5hkscs_nonbmp_encmap+9851,0,229},{__big5hkscs_nonbmp_encmap+10081,25,243 -},{__big5hkscs_nonbmp_encmap+10300,0,238},{__big5hkscs_nonbmp_encmap+10539,3, -215},{__big5hkscs_nonbmp_encmap+10752,58,58},{__big5hkscs_nonbmp_encmap+10753, -194,194},{__big5hkscs_nonbmp_encmap+10754,167,250},{__big5hkscs_nonbmp_encmap+ -10838,26,90},{__big5hkscs_nonbmp_encmap+10903,99,255},{ -__big5hkscs_nonbmp_encmap+11060,64,248},{__big5hkscs_nonbmp_encmap+11245,6,252 -},{__big5hkscs_nonbmp_encmap+11492,53,240},{__big5hkscs_nonbmp_encmap+11680, -17,236},{__big5hkscs_nonbmp_encmap+11900,4,252},{__big5hkscs_nonbmp_encmap+ -12149,27,250},{__big5hkscs_nonbmp_encmap+12373,13,248},{ -__big5hkscs_nonbmp_encmap+12609,4,214},{__big5hkscs_nonbmp_encmap+12820,5,200 -},{__big5hkscs_nonbmp_encmap+13016,24,212},{__big5hkscs_nonbmp_encmap+13205,6, -224},{__big5hkscs_nonbmp_encmap+13424,18,255},{__big5hkscs_nonbmp_encmap+13662 -,0,251},{__big5hkscs_nonbmp_encmap+13914,14,233},{__big5hkscs_nonbmp_encmap+ -14134,15,245},{__big5hkscs_nonbmp_encmap+14365,9,217},{ -__big5hkscs_nonbmp_encmap+14574,6,235},{__big5hkscs_nonbmp_encmap+14804,59,167 -},{__big5hkscs_nonbmp_encmap+14913,14,194},{__big5hkscs_nonbmp_encmap+15094, -44,157},{__big5hkscs_nonbmp_encmap+15208,43,231},{__big5hkscs_nonbmp_encmap+ -15397,32,216},{__big5hkscs_nonbmp_encmap+15582,14,19},{ -__big5hkscs_nonbmp_encmap+15588,25,154},{__big5hkscs_nonbmp_encmap+15718,49, -224},{__big5hkscs_nonbmp_encmap+15894,5,246},{__big5hkscs_nonbmp_encmap+16136, -6,225},{__big5hkscs_nonbmp_encmap+16356,87,225},{__big5hkscs_nonbmp_encmap+ -16495,3,204},{__big5hkscs_nonbmp_encmap+16697,84,233},{ -__big5hkscs_nonbmp_encmap+16847,116,232},{__big5hkscs_nonbmp_encmap+16964,1, -254},{__big5hkscs_nonbmp_encmap+17218,32,67},{__big5hkscs_nonbmp_encmap+17254, -14,216},{__big5hkscs_nonbmp_encmap+17457,26,226},{__big5hkscs_nonbmp_encmap+ -17658,41,165},{__big5hkscs_nonbmp_encmap+17783,2,221},{ -__big5hkscs_nonbmp_encmap+18003,88,208},{__big5hkscs_nonbmp_encmap+18124,53, -248},{__big5hkscs_nonbmp_encmap+18320,2,152},{__big5hkscs_nonbmp_encmap+18471, -18,191},{__big5hkscs_nonbmp_encmap+18645,18,252},{__big5hkscs_nonbmp_encmap+ -18880,22,204},{__big5hkscs_nonbmp_encmap+19063,28,199},{ -__big5hkscs_nonbmp_encmap+19235,14,250},{__big5hkscs_nonbmp_encmap+19472,45,82 -},{__big5hkscs_nonbmp_encmap+19510,5,247},{__big5hkscs_nonbmp_encmap+19753,33, -209},{__big5hkscs_nonbmp_encmap+19930,34,240},{__big5hkscs_nonbmp_encmap+20137 -,0,215},{__big5hkscs_nonbmp_encmap+20353,38,223},{__big5hkscs_nonbmp_encmap+ -20539,14,248},{__big5hkscs_nonbmp_encmap+20774,9,205},{ -__big5hkscs_nonbmp_encmap+20971,27,230},{__big5hkscs_nonbmp_encmap+21175,82, -255},{__big5hkscs_nonbmp_encmap+21349,34,134},{__big5hkscs_nonbmp_encmap+21450 -,116,254},{__big5hkscs_nonbmp_encmap+21589,7,148},{__big5hkscs_nonbmp_encmap+ -21731,15,204},{__big5hkscs_nonbmp_encmap+21921,88,200},{ -__big5hkscs_nonbmp_encmap+22034,36,253},{__big5hkscs_nonbmp_encmap+22252,10, -244},{__big5hkscs_nonbmp_encmap+22487,6,244},{__big5hkscs_nonbmp_encmap+22726, -18,197},{__big5hkscs_nonbmp_encmap+22906,47,220},{__big5hkscs_nonbmp_encmap+ -23080,77,79},{__big5hkscs_nonbmp_encmap+23083,46,249},{ -__big5hkscs_nonbmp_encmap+23287,2,244},{__big5hkscs_nonbmp_encmap+23530,46,188 -},{__big5hkscs_nonbmp_encmap+23673,7,226},{__big5hkscs_nonbmp_encmap+23893,6, -138},{__big5hkscs_nonbmp_encmap+24026,18,130},{__big5hkscs_nonbmp_encmap+24139 -,1,244},{__big5hkscs_nonbmp_encmap+24383,0,230},{__big5hkscs_nonbmp_encmap+ -24614,15,19},{__big5hkscs_nonbmp_encmap+24619,4,43},{__big5hkscs_nonbmp_encmap -+24659,51,252},{__big5hkscs_nonbmp_encmap+24861,15,252},{ -__big5hkscs_nonbmp_encmap+25099,12,255},{__big5hkscs_nonbmp_encmap+25343,3,210 -},{__big5hkscs_nonbmp_encmap+25551,52,185},{__big5hkscs_nonbmp_encmap+25685, -15,231},{__big5hkscs_nonbmp_encmap+25902,197,197},{__big5hkscs_nonbmp_encmap+ -25903,121,237},{__big5hkscs_nonbmp_encmap+26020,13,235},{0,0,0},{0,0,0},{ -__big5hkscs_nonbmp_encmap+26243,29,231},{__big5hkscs_nonbmp_encmap+26446,158, -244},{0,0,0},{__big5hkscs_nonbmp_encmap+26533,32,212},{ -__big5hkscs_nonbmp_encmap+26714,16,250},{__big5hkscs_nonbmp_encmap+26949,3,201 -},{__big5hkscs_nonbmp_encmap+27148,40,77},{__big5hkscs_nonbmp_encmap+27186,5, -213},{__big5hkscs_nonbmp_encmap+27395,115,173},{__big5hkscs_nonbmp_encmap+ -27454,62,246},{__big5hkscs_nonbmp_encmap+27639,6,248},{ -__big5hkscs_nonbmp_encmap+27882,35,222},{__big5hkscs_nonbmp_encmap+28070,20, -254},{__big5hkscs_nonbmp_encmap+28305,7,245},{__big5hkscs_nonbmp_encmap+28544, -32,255},{__big5hkscs_nonbmp_encmap+28768,81,169},{__big5hkscs_nonbmp_encmap+ -28857,52,91},{__big5hkscs_nonbmp_encmap+28897,198,203},{ -__big5hkscs_nonbmp_encmap+28903,1,169},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__big5hkscs_nonbmp_encmap+29072,37,205},{__big5hkscs_nonbmp_encmap+29241,148, -212},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - +static const ucs2_t __big5hkscs_decmap[6219] = { +17392,19506,17923,17830,17784,29287,19831,17843,31921,19682,31941,15253,18230, +18244,19527,19520,17087,13847,29522,28299,28882,19543,41809,18255,17882,19589, +31852,19719,19108,18081,27427,29221,23124,6755,15878,16225,26189,22267,U, +32149,22813,35769,15860,38708,31727,23515,7518,23204,13861,40624,23249,23479, +23804,26478,34195,39237,29793,29853,12736,12737,12738,12739,12740,268,12741, +209,205,12742,12743,203,8168,12744,202,12745,12746,12747,12748,270,12749, +12750,256,193,461,192,274,201,282,200,332,211,465,210,U,7870,U,7872,202,257, +225,462,224,593,275,233,283,232,299,237,464,236,333,243,466,242,363,250,468, +249,470,472,474,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,476,252,U,7871,U,7873,234,609,9178,9179,41897,4421,U,25866,U,U,20029, +28381,40270,37343,U,U,30517,25745,20250,20264,20392,20822,20852,20892,20964, +21153,21160,21307,21326,21457,21464,22242,22768,22788,22791,22834,22836,23398, +23454,23455,23706,24198,24635,25993,26622,26628,26725,27982,28860,30005,32420, +32428,32442,32455,32463,32479,32518,32567,33402,33487,33647,35270,35774,35810, +36710,36711,36718,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,29713,31996,32205,26950,31433,21031,U,U,U,U,37260,30904,37214,32956,U, +36107,33014,2535,U,U,32927,40647,19661,40393,40460,19518,40438,28686,40458, +41267,13761,U,28314,33342,29977,U,18705,39532,39567,40857,31111,33900,7626, +1488,10982,20004,20097,20096,20103,20159,20203,20279,13388,20413,15944,20483, +20616,13437,13459,13477,20870,22789,20955,20988,20997,20105,21113,21136,21287, +13767,21417,13649,21424,13651,21442,21539,13677,13682,13953,21651,21667,21684, +21689,21712,21743,21784,21795,21800,13720,21823,13733,13759,21975,13765,32132, +21797,U,3138,3349,20779,21904,11462,14828,833,36422,19896,38117,16467,32958, +30586,11320,14900,18389,33117,27122,19946,25821,3452,4020,3285,4340,25741, +36478,3734,3083,3940,11433,33366,17619,U,3398,39501,33001,18420,20135,11458, +39602,14951,38388,16365,13574,21191,38868,30920,11588,40302,38933,U,17369, +24741,25780,21731,11596,11210,4215,14843,4207,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26330,26390,31136,25834,20562,3139,36456, +8609,35660,1841,U,18443,425,16378,22643,11661,U,17864,1276,24727,3916,3478, +21881,16571,17338,U,19124,10854,4253,33194,39157,3484,25465,14846,10101,36288, +22177,25724,15939,U,42497,3593,10959,11465,U,4296,14786,14738,14854,33435, +13688,24137,8391,22098,3889,11442,38688,13500,27709,20027,U,U,30068,11915, +8712,42587,36045,3706,3124,26652,32659,4303,10243,10553,13819,20963,3724,3981, +3754,16275,3888,3399,4431,3660,U,3755,2985,3400,4288,4413,16377,9878,25650, +4013,13300,30265,11214,3454,3455,11345,11349,14872,3736,4295,3886,42546,27472, +36050,36249,36042,38314,21708,33476,21945,U,40643,39974,39606,30558,11758, +28992,33133,33004,23580,25970,33076,14231,21343,32957,37302,3834,3599,3703, +3835,13789,19947,13833,3286,22191,10165,4297,3600,3704,4216,4424,33287,5205, +3705,20048,11684,23124,4125,4126,4341,4342,22428,3601,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30356,33485,4021,3707,20862,14083, +4022,4480,21208,41661,18906,6202,16759,33404,22681,21096,13850,22333,31666, +23400,18432,19244,40743,18919,39967,39821,23412,12605,22011,13810,22153,20008, +22786,7105,63608,38737,134,20059,20155,13630,23587,24401,24516,14586,25164, +25909,27514,27701,27706,28780,29227,20012,29357,18665,32594,31035,31993,32595, +25194,13505,U,25419,32770,32896,26130,26961,21341,34916,35265,30898,35744, +36125,38021,38264,38271,38376,36367,38886,39029,39118,39134,39267,38928,40060, +40479,40644,27503,63751,20023,135,38429,25143,38050,20539,28158,40051,40870, +15817,34959,16718,28791,23797,19232,20941,13657,23856,24866,35378,36775,37366, +29073,26393,29626,12929,41223,15499,6528,19216,30948,29698,20910,34575,16393, +27235,41658,16931,34319,2671,31274,39239,35562,38741,28749,21284,8318,37876, +30425,35299,40871,30685,20131,20464,20668,20015,20247,40872,21556,32139,22674, +22736,7606,24210,24217,24514,10002,25995,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13305,26905,27203,15459,27903,U,29184,17669, +29580,16091,18963,23317,29881,35715,23716,22165,31379,31724,31939,32364,33528, +34199,40873,34960,40874,36537,40875,36815,34143,39392,37409,40876,36281,5183, +16497,17058,23066,U,U,U,39016,26475,17014,22333,U,34262,18811,33471,28941, +19585,28020,23931,27413,28606,40877,40878,23446,40879,26343,32347,28247,31178, +15752,17603,12886,10134,17306,17718,U,23765,15130,35577,23672,15634,13649, +23928,40882,29015,17752,16620,7715,19575,14712,13386,420,27713,35532,20404, +569,22975,33132,38998,39162,24379,2975,U,8641,35181,16642,18107,36985,16135, +40883,41397,16632,14294,18167,27718,16764,34482,29695,17773,14548,21658,17761, +17691,19849,19579,19830,17898,16328,19215,13921,17630,17597,16877,23870,23880, +23894,15868,14351,23972,23993,14368,14392,24130,24253,24357,24451,14600,14612, +14655,14669,24791,24893,23781,14729,25015,25017,25039,14776,25132,25232,25317, +25368,14840,22193,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,14851,25570,25595,25607,25690,14923,25792,23829,22049,40863,14999, +25990,15037,26111,26195,15090,26258,15138,26390,15170,26532,26624,15192,26698, +26756,15218,15217,15227,26889,26947,29276,26980,27039,27013,15292,27094,15325, +27237,27252,27249,27266,15340,27289,15346,27307,27317,27348,27382,27521,27585, +27626,27765,27818,15563,27906,27910,27942,28033,15599,28068,28081,28181,28184, +28201,28294,35264,28347,28386,28378,40831,28392,28393,28452,28468,15686,16193, +28545,28606,15722,15733,29111,23705,15754,28716,15761,28752,28756,28783,28799, +28809,805,17345,13809,3800,16087,22462,28371,28990,22496,13902,27042,35817, +23412,31305,22753,38105,31333,31357,22956,31419,31408,31426,31427,29137,25741, +16842,31450,31453,31466,16879,21682,23553,31499,31573,31529,21262,23806,31650, +31599,33692,23476,27775,31696,33825,31634,U,23840,15789,23653,33938,31738,U, +31797,23745,31812,31875,18562,31910,26237,17784,31945,31943,31974,31860,31987, +31989,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +32359,17693,28228,32093,28374,29837,32137,32171,28981,32179,U,16471,24617, +32228,15635,32245,6137,32229,33645,U,24865,24922,32366,32402,17195,37996, +32295,32576,32577,32583,31030,25296,39393,32663,25425,32675,5729,104,17756, +14182,17667,33594,32762,25737,U,32776,32797,U,32815,41095,27843,32827,32828, +32865,10004,18825,26150,15843,26344,26405,32935,35400,33031,33050,22704,9974, +27775,25752,20408,25831,5258,33304,6238,27219,19045,19093,17530,33321,2829, +27218,15742,20473,5373,34018,33634,27402,18855,13616,6003,15864,33450,26907, +63892,16859,34123,33488,33562,3606,6068,14017,12669,13658,33403,33506,33560, +16011,28067,27397,27543,13774,15807,33565,21996,33669,17675,28069,33708,U, +33747,13438,28372,27223,34138,13462,28226,12015,33880,23524,33905,15827,17636, +27303,33866,15541,31064,U,27542,28279,28227,34014,U,33681,17568,33939,34020, +23697,16960,23744,17731,34100,23282,28313,17703,34163,17686,26559,34326,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34341,34363, +34241,28808,34306,5506,28877,63922,17770,34344,13896,6306,21495,29594,34430, +34673,41208,34798,11303,34737,34778,34831,22113,34412,26710,17935,34885,34886, +30176,15801,30180,34910,34972,18011,34996,34997,25537,35013,30583,30479,35207, +35210,U,U,35239,35260,35365,35303,31012,31421,35484,30611,37374,35472,31321, +31465,31546,16271,18195,31544,29052,35596,35615,21552,21861,35647,35660,35661, +35497,19066,35728,35739,35503,5855,17941,34895,35995,32084,32143,63956,14117, +32083,36054,32152,32189,36114,36099,6416,36059,28764,36113,19657,16080,36265, +32770,4116,18826,15228,33212,28940,31463,36525,36534,36547,37588,36633,36653, +33637,33810,36773,37635,41631,2640,36787,18730,35294,34109,15803,24312,12898, +36857,40980,34492,34049,8997,14720,28375,36919,34108,31422,36961,34156,34315, +37032,34579,37060,34534,37038,U,37223,15088,37289,37316,31916,35123,7817, +37390,27807,37441,37474,21945,U,35526,15515,35596,21979,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,3377,37676,37739,35553,35819, +28815,23235,35554,35557,18789,37444,35820,35897,35839,37747,37979,36540,38277, +38310,37926,38304,28662,17081,9850,34520,4732,15918,18911,27676,38523,38550, +16748,38563,28373,25050,38582,30965,35552,38589,21452,18849,27832,628,25616, +37039,37093,19153,6421,13066,38705,34370,38710,18959,17725,17797,19177,28789, +23361,38683,U,37333,38743,23370,37355,38751,37925,20688,12471,12476,38793, +38815,38833,38846,38848,38866,38880,21612,38894,29724,37939,U,38901,37917, +31098,19153,38964,38963,38987,39014,15118,29045,15697,1584,16732,22278,39114, +39095,39112,39111,19199,27943,5843,21936,39137,39142,39148,37752,39225,18985, +19314,38999,39173,39413,39436,39483,39440,39512,22309,14020,37041,39893,39648, +39650,39685,39668,19470,39700,39725,34304,20532,39732,27048,14531,12413,39760, +39744,40254,23109,6243,39822,16971,39938,39935,39948,40552,40404,40887,41362, +41387,41185,41251,41439,40318,40323,41268,40462,26760,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40388,8539,41363,41504,6459,41523, +40249,41145,41652,40592,40597,40606,40610,19764,40618,40623,17252,40641,15200, +14821,15645,20274,14270,35883,40706,40712,19350,37924,28066,40727,U,40761, +22175,22154,40773,39352,37003,38898,33919,40802,40809,31452,40846,29206,19390, +18805,18875,29047,18936,17224,19025,29598,35802,6394,31135,35198,36406,37737, +37875,35396,37612,37761,37835,35180,17593,29207,16107,30578,31299,28880,17523, +17400,29054,6127,28835,6334,13721,16071,6277,21551,6136,14114,5883,6201,14049, +6004,6353,24395,14115,5824,22363,18981,5118,4776,5062,5302,34051,13990,U, +33877,18836,29029,15921,21852,16123,28754,17652,14062,39325,28454,26617,14131, +15381,15847,22636,6434,26640,16471,14143,16609,16523,16655,27681,21707,22174, +26289,22162,4063,2984,3597,37830,35603,37788,20216,20779,14361,17462,20156, +1125,895,20299,20362,22097,23144,427,971,14745,778,1044,13365,20265,704,36531, +629,35546,524,20120,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,20685,20749,20386,20227,18958,16010,20290,20526,20588,20609,20428, +20453,20568,20732,U,U,U,U,28278,13717,15929,16063,28018,6276,16009,20904, +20931,1504,17629,1187,1170,1169,36218,35484,1806,21081,21156,2163,21217,U, +18042,29068,17292,3104,18860,4324,27089,3613,U,16094,29849,29716,29782,29592, +19342,19132,16525,21456,13700,29199,16585,21940,837,21709,3014,22301,37469, +38644,37734,22493,22413,22399,13886,22731,23193,35398,5882,5999,5904,23084, +22968,37519,23166,23247,23058,22854,6643,6241,17045,14069,27909,29763,23073, +24195,23169,35799,1043,37856,29836,4867,28933,18802,37896,35323,37821,14240, +23582,23710,24158,24136,6550,6524,15086,24269,23375,6403,6404,14081,6304, +14045,5886,14035,33066,35399,7610,13426,35240,24332,24334,6439,6059,23147, +5947,23364,34324,30205,34912,24702,10336,9771,24539,16056,9647,9662,37000, +28531,25024,62,70,9755,24985,24984,24693,11419,11527,18132,37197,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25713,18021,11114, +14889,11042,13392,39146,11896,25399,42075,25782,25393,25553,18915,11623,25252, +11425,25659,25963,26994,15348,12430,12973,18825,12971,21773,13024,6361,37951, +26318,12937,12723,15072,16784,21892,35618,21903,5884,21851,21541,30958,12547, +6186,12852,13412,12815,12674,17097,26254,27940,26219,19347,26160,30832,7659, +26211,13010,13025,26142,22642,14545,14394,14268,15257,14242,13310,29904,15254, +26511,17962,26806,26654,15300,27326,14435,14293,17543,27187,27218,27337,27397, +6418,25873,26776,27212,15319,27258,27479,16320,15514,37792,37618,35818,35531, +37513,32798,35292,37991,28069,28427,18924,U,16255,15759,28164,16444,23101, +28170,22599,27940,30786,28987,17178,17014,28913,29264,29319,29332,18319,18213, +20857,19108,1515,29818,16120,13919,19018,18711,24545,16134,16049,19167,35875, +16181,24743,16115,29900,29756,37767,29751,17567,28138,17745,30083,16227,19673, +19718,16216,30037,30323,42438,15129,29800,35532,18859,18830,15099,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15821,19022,16127, +18885,18675,37370,22322,37698,35555,6244,20703,21025,20967,30584,12850,30478, +30479,30587,18071,14209,14942,18672,29752,29851,16063,19130,19143,16584,19094, +25006,37639,21889,30750,30861,30856,30930,29648,31065,30529,22243,16654,U, +33942,31141,27181,16122,31290,31220,16750,5862,16690,37429,31217,3404,18828, +665,15802,5998,13719,21867,13680,13994,468,3085,31458,23129,9973,23215,23196, +23053,603,30960,23082,23494,31486,16889,31837,31853,16913,23475,24252,24230, +31949,18937,6064,31886,31868,31918,27314,32220,32263,32211,32590,25185,24924, +31560,32151,24194,17002,27509,2326,26582,78,13775,22468,25618,25592,18786, +32733,31527,2092,23273,23875,31500,24078,39398,34373,39523,27164,13375,14818, +18935,26029,39455,26016,33920,28967,27857,17642,33079,17410,32966,33033,33090, +26548,39107,27202,33378,33381,27217,33875,28071,34320,29211,23174,16767,6208, +23339,6305,23268,6360,34464,63932,15759,34861,29730,23042,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34926,20293,34951,35007,35046, +35173,35149,22147,35156,30597,30596,35829,35801,35740,35321,16045,33955,18165, +18127,14322,35389,35356,37960,24397,37419,17028,26068,28969,28868,6213,40301, +35999,36073,32220,22938,30659,23024,17262,14036,36394,36519,19465,36656,36682, +17140,27736,28603,8993,18587,28537,28299,6106,39913,14005,18735,37051,U,21873, +18694,37307,37892,35403,16482,35580,37927,35869,35899,34021,35371,38297,38311, +38295,38294,36148,29765,16066,18687,19010,17386,16103,12837,38543,36583,36454, +36453,16076,18925,19064,16366,29714,29803,16124,38721,37040,26695,18973,37011, +22495,U,37736,35209,35878,35631,25534,37562,23313,35689,18748,29689,16923, +38811,38769,39224,3878,24001,35781,19122,38943,38106,37622,38359,37349,17600, +35664,19047,35684,39132,35397,16128,37418,18725,33812,39227,39245,31494,15869, +39323,19311,39338,39516,35685,22728,27279,39457,23294,39471,39153,19344,39240, +39356,19389,19351,37757,22642,4866,22562,18872,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5352,30788,10015,15800,26821,15741, +37976,14631,24912,10113,10603,24839,40015,40019,40059,39989,39952,39807,39887, +40493,39839,41461,41214,40225,19630,16644,40472,19632,40204,41396,41197,41203, +39215,40357,33981,28178,28639,27522,34300,17715,28068,28292,28144,33824,34286, +28160,14295,24676,31202,13724,13888,18733,18910,15714,37851,37566,37704,703, +30905,37495,37965,20452,13376,36964,21853,30781,30804,30902,30795,5975,12745, +18753,13978,20338,28634,28633,U,28702,21524,16821,22459,22771,22410,40214, +22487,28980,13487,16812,29163,27712,20375,U,6069,35401,24844,23246,23051, +17084,17544,14124,19323,35324,37819,37816,6358,3869,33906,27840,5139,17146, +11302,17345,22932,15799,26433,32168,24923,24740,18873,18827,35322,37605,29666, +16105,29876,35683,6303,16097,19123,27352,29683,29691,16086,19006,19092,6105, +19046,935,5156,18917,29768,18710,28837,18806,37508,29670,37727,1278,37681, +35534,35350,37766,35815,21973,18741,35458,29035,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,18755,3327,22180,1562,3051,3256,21762, +31172,6138,32254,5826,19024,6226,17710,37889,14090,35520,18861,22960,6335, +6275,29828,23201,14050,15707,14000,37471,23161,35457,6242,37748,15565,2740, +19094,14730,20724,15721,15692,5020,29045,17147,33304,28175,37092,17643,27991, +32335,28775,27823,15574,16365,15917,28162,28428,15727,1013,30033,14012,13512, +18048,16090,18545,22980,37486,18750,36673,35868,27584,22546,22472,14038,5202, +28926,17250,19057,12259,4784,9149,26809,26983,5016,13541,31732,14047,35459, +14294,13306,19615,27162,13997,27831,33854,17631,17614,27942,27985,27778,28638, +28439,28937,33597,5946,33773,27776,28755,6107,22921,23170,6067,23137,23153, +6405,16892,14125,23023,5948,14023,29070,37776,26266,17061,23150,23083,17043, +27179,16121,30518,17499,17098,28957,16985,35297,20400,27944,23746,17614,32333, +17341,27148,16982,4868,28838,28979,17385,15781,27871,63525,19023,32357,23019, +23855,15859,24412,19037,6111,32164,33830,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21637,15098,13056,532,22398,2261,1561,16357, +8094,41654,28675,37211,23920,29583,31955,35417,37920,20424,32743,29389,29456, +31476,29496,29497,22262,29505,29512,16041,31512,36972,29173,18674,29665,33270, +16074,30476,16081,27810,22269,29721,29726,29727,16098,16112,16116,16122,29907, +16142,16211,30018,30061,30066,30093,16252,30152,30172,16320,30285,16343,30324, +16348,30330,20316,29064,22051,35200,22633,16413,30531,16441,26465,16453,13787, +30616,16490,16495,23646,30654,30667,22770,30744,28857,30748,16552,30777,30791, +30801,30822,33864,21813,31027,26627,31026,16643,16649,31121,31129,36795,31238, +36796,16743,31377,16818,31420,33401,16836,31439,31451,16847,20001,31586,31596, +31611,31762,31771,16992,17018,31867,31900,17036,31928,17044,31981,36755,28864, +3279,32207,32212,32208,32253,32686,32692,29343,17303,32800,32805,31545,32814, +32817,32852,15820,22452,28832,32951,33001,17389,33036,29482,33038,33042,30048, +33044,17409,15161,33110,33113,33114,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,17427,22586,33148,33156,17445,33171,17453,33189, +22511,33217,33252,33364,17551,33446,33398,33482,33496,33535,17584,33623,38505, +27018,33797,28917,33892,24803,33928,17668,33982,34017,34040,34064,34104,34130, +17723,34159,34160,34272,17783,34418,34450,34482,34543,38469,34699,17926,17943, +34990,35071,35108,35143,35217,31079,35369,35384,35476,35508,35921,36052,36082, +36124,18328,22623,36291,18413,20206,36410,21976,22356,36465,22005,36528,18487, +36558,36578,36580,36589,36594,36791,36801,36810,36812,36915,39364,18605,39136, +37395,18718,37416,37464,37483,37553,37550,37567,37603,37611,37619,37620,37629, +37699,37764,37805,18757,18769,40639,37911,21249,37917,37933,37950,18794,37972, +38009,38189,38306,18855,38388,38451,18917,26528,18980,38720,18997,38834,38850, +22100,19172,24808,39097,19225,39153,22596,39182,39193,20916,39196,39223,39234, +39261,39266,19312,39365,19357,39484,39695,31363,39785,39809,39901,39921,39924, +19565,39968,14191,7106,40265,39994,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,40702,22096,40339,40381,40384,40444,38134,36790, +40571,40620,40625,40637,40646,38108,40674,40689,40696,31432,40772,148,695,928, +26906,38083,22956,1239,22592,38081,14265,1493,1557,1654,5818,22359,29043,2754, +2765,3007,21610,63547,3019,21662,3067,3131,3155,3173,3196,24807,3213,22138, +3253,3293,3309,3439,3506,3528,26965,39983,34725,3588,3598,3799,3984,3885,3699, +23584,4028,24075,4188,4175,4214,26398,4219,4232,4246,13895,4287,4307,4399, +4411,21348,33965,4835,4981,4918,35713,5495,5657,6083,6087,20088,28859,6189, +6506,6701,6725,7210,7280,7340,7880,25283,7893,7957,29080,26709,8261,27113, +14024,8828,9175,9210,10026,10353,10575,33533,10599,10643,10965,35237,10984, +36768,11022,38840,11071,38983,39613,11340,U,11400,11447,23528,11528,11538, +11703,11669,11842,12148,12236,12339,12390,13087,13278,24497,26184,26303,31353, +13671,13811,U,18874,U,13850,14102,U,838,22709,26382,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26904,15015,30295,24546,15889,16057, +30206,8346,18640,19128,16665,35482,17134,17165,16443,17204,17302,19013,1482, +20946,1553,22943,7848,15294,15615,17412,17622,22408,18036,14747,18223,34280, +39369,14178,8643,35678,35662,U,18450,18683,18965,29193,19136,3192,22885,20133, +20358,1913,36570,20524,21135,22335,29041,21145,21529,16202,19111,21948,21574, +21614,27474,U,13427,21823,30258,21854,18200,21858,21862,22471,18751,22621, +20582,13563,13260,U,22787,18300,35144,23214,23433,23558,7568,22433,29009,U, +24834,31762,36950,25010,20378,35682,25602,25674,23899,27639,U,25732,6428, +35562,18934,25736,16367,25874,19392,26047,26293,10011,37989,22497,24981,23079, +63693,U,22201,17697,26364,20074,18740,38486,28047,27837,13848,35191,26521, +26734,25617,26718,U,26823,31554,37056,2577,26918,U,26937,31301,U,27130,39462, +27181,13919,25705,33,31107,27188,27483,23852,13593,U,27549,18128,27812,30011, +34917,28078,22710,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,14108,9613,28747,29133,15444,29312,29317,37505,8570,29323,37680,29414, +18896,27705,38047,29776,3832,34855,35061,10534,33907,6065,28344,18986,6176, +14756,14009,U,U,17727,26294,40109,39076,35139,30668,30808,22230,16607,5642, +14753,14127,33000,5061,29101,33638,31197,37288,U,19639,28847,35243,31229, +31242,31499,32102,16762,31555,31102,32777,28597,41695,27139,33560,21410,28167, +37823,26678,38749,33135,32803,27061,5101,12847,32840,23941,35888,32899,22293, +38947,35145,23979,18824,26046,27093,21458,19109,16257,15377,26422,32912,33012, +33070,8097,33103,33161,33199,33306,33542,33583,33674,13770,33896,34474,18682, +25574,35158,30728,37461,35256,17394,35303,17375,35304,35654,35796,23032,35849, +U,36805,37100,U,37136,37180,15863,37214,19146,36816,29327,22155,38119,38377, +38320,38328,38706,39121,39241,39274,39363,39464,39694,40282,40347,32415,40696, +40739,19620,38215,41619,29090,41727,19857,36882,42443,19868,3228,36798,21953, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36794, +9392,36793,19091,17673,32383,28502,27313,20202,13540,35628,30877,14138,36480, +6133,32804,35692,35737,31294,26287,15851,30293,15543,22069,22870,20122,24193, +25176,22207,3693,36366,23405,16008,19614,25566,U,6134,6267,25904,22061,23626, +21530,21265,15814,40344,19581,22050,22046,32585,24280,22901,15680,34672,19996, +4074,3401,14010,33047,40286,36120,30267,40005,30286,30649,37701,21554,33096, +33527,22053,33074,33816,32957,21994,31074,22083,21526,3741,13774,22021,22001, +26353,33506,13869,30004,22000,21946,21655,21874,3137,3222,24272,20808,3702, +11362,3746,40619,32090,21982,4213,25245,38765,21652,36045,29174,37238,25596, +25529,25598,21865,11075,40050,11955,20890,13535,3495,20903,21581,21790,21779, +30310,36397,26762,30129,32950,34820,34694,35015,33206,33820,4289,17644,29444, +18182,23440,33547,26771,22139,9972,32047,16803,32115,28368,29366,37232,4569, +37384,15612,42665,3756,3833,29286,7330,18254,20418,32761,4075,16634,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40029,25887,11680, +18675,18400,40316,4076,3594,U,30115,4077,U,24648,4487,29091,32398,40272,19994, +19972,13687,23309,27826,21351,13996,14812,21373,13989,17944,22682,19310,33325, +21579,22442,23189,2425,U,14930,9317,29556,40620,19721,39917,15614,40752,19547, +20393,38302,40926,33884,15798,29362,26547,14112,25390,32037,16119,15916,14890, +36872,21196,15988,13946,17897,1166,30272,23280,3766,30842,32558,22695,16575, +22140,39819,23924,30292,42036,40581,19681,U,14331,24857,12506,17394,U,22109, +4777,22439,18787,40454,21044,28846,13741,U,40316,31830,39737,22494,5996,23635, +25811,38096,25397,29028,34477,3368,27938,19170,3441,U,20990,7951,23950,38659, +7633,40577,36940,31519,39682,23761,31651,25192,25397,39679,31695,39722,31870, +U,31810,31878,39957,31740,39689,U,39963,18750,40794,21875,23491,20477,40600, +20466,21088,15878,21201,22375,20566,22967,24082,38856,40363,36700,21609,38836, +39232,38842,21292,24880,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,26924,21466,39946,40194,19515,38465,27008,20646,30022,5997, +39386,21107,U,37209,38529,37212,U,37201,36503,25471,27939,27338,22033,37262, +30074,25221,1020,29519,31856,23585,15613,U,18713,30422,39837,20010,3284,33726, +34882,U,23626,27072,U,22394,21023,24053,20174,27697,498,20281,21660,21722, +21146,36226,13822,U,13811,U,27474,37244,40869,39831,38958,39092,39610,40616, +40580,29050,31508,U,27642,34840,32632,U,22048,42570,36471,40787,U,36308,36431, +40476,36353,25218,33661,36392,36469,31443,19063,31294,30936,27882,35431,30215, +35418,40742,27854,34774,30147,41650,30803,63552,36108,29410,29553,35629,29442, +29937,36075,19131,34351,24506,34976,17591,U,6203,28165,U,35454,9499,U,24829, +30311,39639,40260,37742,39823,34805,U,U,36087,29484,38689,39856,13782,29362, +19463,31825,39242,24921,24921,19460,40598,24957,U,22367,24943,25254,25145,U, +14940,25058,21418,13301,25444,26626,13778,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23895,35778,36826,36409,U,20697,7494,30982, +21298,38456,3899,16485,U,30718,U,31938,24346,31962,31277,32870,32867,32077, +29957,29938,35220,33306,26380,32866,29830,32859,29936,33027,30500,35209,26572, +30035,28369,34729,34766,33224,34700,35401,36013,35651,30507,29944,34010,13877, +27058,36262,U,35241,U,28089,34753,16401,29927,15835,29046,24740,24988,15569,U, +24695,U,32625,35629,U,24809,19326,21024,15384,15559,24279,30294,21809,6468, +4862,39171,28124,28845,23745,25005,35343,13943,238,26694,20238,17762,23327, +25420,40784,40614,25195,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321, +9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,8560,8561,8562,8563,8564, +8565,8566,8567,8568,8569,20022,20031,20101,20128,20866,20886,20907,21241, +21304,21353,21430,22794,23424,24027,12083,24191,U,24400,24417,25908,U,30098,U, +36789,U,168,710,12541,12542,12445,12446,U,U,12293,12294,12295,12540,65339, +65341,10045,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363, +12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376, +12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389, +12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402, +12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415, +12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428, +12429,12430,12431,12432,12433,12434,12435,12449,12450,12451,12452,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12453,12454,12455, +12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468, +12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481, +12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494, +12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507, +12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520, +12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533, +12534,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052, +1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067, +1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081, +1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, +1097,1098,1099,1100,1101,1102,1103,8679,8632,8633,12751,204,20058,138,20994, +17553,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +40880,20872,40881,30215,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,65506,65508,65287,65282,12849,8470,8481,12443,12444, +11904,11908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943, +11946,11948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991, +11998,12003,U,U,U,643,592,603,596,629,339,248,331,650,618,30849,37561,35023, +22715,24658,31911,23290,9556,9574,9559,9568,9580,9571,9562,9577,9565,9554, +9572,9557,9566,9578,9569,9560,9575,9563,9555,9573,9558,9567,9579,9570,9561, +9576,9564,9553,9552,9581,9582,9584,9583,65517,1351,37595,1503,16325,34124, +17077,29679,20917,13897,18754,35300,37700,6619,33518,15560,30780,26436,25311, +18739,35242,672,27571,4869,20395,9453,20488,27945,31364,13824,19121,9491,U, +894,24484,896,839,28379,1055,U,20737,13434,20750,39020,14147,33814,18852,1159, +20832,13236,20842,3071,8444,741,9520,1422,12851,6531,23426,34685,1459,15513, +20914,20920,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,40244,20937,20943,20945,15580,20947,19110,20915,20962,21314,20973,33741, +26942,14125,24443,21003,21030,21052,21173,21079,21140,21177,21189,31765,34114, +21216,34317,27411,U,35550,21833,28377,16256,2388,16364,21299,U,3042,27851, +5926,26651,29653,24650,16042,14540,5864,29149,17570,21357,21364,34475,21374,U, +5526,5651,30694,21395,35483,21408,21419,21422,29607,22386,16217,29596,21441, +21445,27721,20041,22526,21465,15019,2959,21472,16363,11683,21494,3191,21523, +28793,21803,26199,27995,21613,27475,3444,21853,21647,21668,18342,5901,3805, +15796,3405,35260,9880,21831,19693,21551,29719,21894,21929,U,6359,16442,17746, +17461,26291,4276,22071,26317,12938,26276,26285,22093,22095,30961,22257,38791, +21502,22272,22255,22253,35686,13859,4687,22342,16805,27758,28811,22338,14001, +27774,22502,5142,22531,5204,17251,22566,19445,22620,22698,13665,22752,22748, +4668,22779,23551,22339,41296,17016,37843,13729,22815,26790,14019,28249,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5694,23076, +21843,5778,34053,22985,3406,27777,27946,6108,23001,6139,6066,28070,28017,6184, +5845,23033,28229,23211,23139,14054,18857,U,14088,23190,29797,23251,28577,9556, +15749,6417,14130,5816,24195,21200,23414,25992,23420,31246,16388,18525,516, +23509,24928,6708,22988,1445,23539,23453,19728,23557,6980,23571,29646,23572, +7333,27432,23625,18653,23685,23785,23791,23947,7673,7735,23824,23832,23878, +7844,23738,24023,33532,14381,18689,8265,8563,33415,14390,15298,24110,27274,U, +24186,17596,3283,21414,20151,U,21416,6001,24073,24308,33922,24313,24315,14496, +24316,26686,37915,24333,449,63636,15070,18606,4922,24378,26760,9168,U,9329, +24419,38845,28270,24434,37696,35382,24487,23990,15711,21072,8042,28920,9832, +37334,670,35369,24625,26245,6263,14691,15815,13881,22416,10164,31089,15936, +24734,U,24755,18818,18831,31315,29860,20705,23200,24932,33828,24898,63654, +28370,24961,20980,1622,24967,23466,16311,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,10335,25043,35741,39261,25040,14642,10624, +10433,24611,24924,25886,25483,280,25285,6000,25301,11789,25452,18911,14871, +25656,25592,5006,6140,U,28554,11830,38932,16524,22301,25825,25829,38011,14950, +25658,14935,25933,28438,18984,18979,25989,25965,25951,12414,26037,18752,19255, +26065,16600,6185,26080,26083,24543,13312,26136,12791,12792,26180,12708,12709, +26187,3701,26215,20966,26227,U,7741,12849,34292,12744,21267,30661,10487,39332, +26370,17308,18977,15147,27130,14274,U,26471,26466,16845,37101,26583,17641, +26658,28240,37436,26625,13286,28064,26717,13423,27105,27147,35551,26995,26819, +13773,26881,26880,15666,14849,13884,15232,26540,26977,35402,17148,26934,27032, +15265,969,33635,20624,27129,13913,8490,27205,14083,27293,15347,26545,27336, +37276,15373,27421,2339,24798,27445,27508,10189,28341,15067,949,6488,14144, +21537,15194,27617,16124,27612,27703,9355,18673,27473,27738,33318,27769,15804, +17605,15805,16804,18700,18688,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,15561,14053,15595,3378,39811,12793,9361,32655,26679,27941, +28065,28139,28054,27996,28284,28420,18815,16517,28274,34099,28532,20935,U,U, +33838,35617,U,15919,29779,16258,31180,28239,23185,12363,28664,14093,28573, +15920,28410,5271,16445,17749,37872,28484,28508,15694,28532,37232,15675,28575, +16708,28627,16529,16725,16441,16368,16308,16703,20959,16726,16727,16704,25053, +28747,28798,28839,28801,28876,28885,28886,28895,16644,15848,29108,29078,17015, +28971,28997,23176,29002,U,23708,17253,29007,37730,17089,28972,17498,18983, +18978,29114,35816,28861,29198,37954,29205,22801,37955,29220,37697,22021,29230, +29248,18804,26813,29269,29271,15957,12356,26637,28477,29314,U,29483,18467, +34859,18669,34820,29480,29486,29647,29610,3130,27182,29641,29769,16866,5863, +18980,26147,14021,18871,18829,18939,29687,29717,26883,18982,29753,1475,16087, +U,10413,29792,36530,29767,29668,29814,33721,29804,14128,29812,37873,27180, +29826,18771,19084,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,16735,19065,35727,23366,35843,6302,29896,6536,29966,U,29982,36569, +6731,23511,36524,37765,30029,30026,30055,30062,20354,16132,19731,30094,29789, +30110,30132,30210,30252,30289,30287,30319,30326,25589,30352,33263,14328,26897, +26894,30369,30373,30391,30412,28575,33890,20637,20861,7708,30494,30502,30528, +25775,21024,30552,12972,30639,35172,35176,5825,30708,U,4982,18962,26826,30895, +30919,30931,38565,31022,21984,30935,31028,30897,30220,36792,34948,35627,24707, +9756,31110,35072,26882,31104,22615,31133,31545,31036,31145,28202,28966,16040, +31174,37133,31188, +}; + +static const struct dbcs_index big5hkscs_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__big5hkscs_decmap+0,64,121},{__big5hkscs_decmap+58,64,170},{ +__big5hkscs_decmap+165,64,254},{__big5hkscs_decmap+356,64,254},{ +__big5hkscs_decmap+547,64,253},{__big5hkscs_decmap+737,64,254},{ +__big5hkscs_decmap+928,64,254},{__big5hkscs_decmap+1119,64,254},{ +__big5hkscs_decmap+1310,64,253},{__big5hkscs_decmap+1500,64,254},{ +__big5hkscs_decmap+1691,64,254},{__big5hkscs_decmap+1882,64,254},{ +__big5hkscs_decmap+2073,64,254},{__big5hkscs_decmap+2264,64,254},{ +__big5hkscs_decmap+2455,64,254},{__big5hkscs_decmap+2646,64,254},{ +__big5hkscs_decmap+2837,64,254},{__big5hkscs_decmap+3028,64,254},{ +__big5hkscs_decmap+3219,64,254},{__big5hkscs_decmap+3410,64,254},{ +__big5hkscs_decmap+3601,64,254},{__big5hkscs_decmap+3792,64,254},{ +__big5hkscs_decmap+3983,64,254},{__big5hkscs_decmap+4174,64,254},{ +__big5hkscs_decmap+4365,64,254},{__big5hkscs_decmap+4556,64,254},{0,0,0},{0,0, +0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_decmap+4747, +161,254},{__big5hkscs_decmap+4841,64,254},{__big5hkscs_decmap+5032,64,254},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__big5hkscs_decmap+5223,214,254},{__big5hkscs_decmap+5264,64,254},{ +__big5hkscs_decmap+5455,64,254},{__big5hkscs_decmap+5646,64,254},{ +__big5hkscs_decmap+5837,64,254},{__big5hkscs_decmap+6028,64,254},{0,0,0}, +}; + +static const unsigned char big5hkscs_phint_0[] = { +32,5,95,68,15,82,130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,44,4,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,4,0,0,0,0,0,0,0,0,0,0,0,0,1,22,0,15,0,0,0,0,0, +32,87,43,247,252,110,242,144,11,0,0,0,192,237,164,15,38,193,155,118,242,239, +222,251,250,247,15,50,68,175,254,239,5,0,0,0,224,251,71,128,193,2,0,132,100,4, +130,64,32,162,130,133,164,145,0,16,1,0,0,0,144,72,12,0,48,0,84,3,48,68,24,19, +53,137,38,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,64,0,32,43,153,32,16,99,40,36, +1,0,0,0,0,80,96,212,0,210,42,24,157,104,53,151,79,216,248,32,196,130,28,40,2, +0,0,0,0,214,81,10,224,0,129,134,22,67,196,53,17,55,96,230,122,109,5,12,61,0,0, +0,0,153,57,128,7,34,254,129,144,24,144,12,116,48,208,160,9,41,21,253,4,0,0,0, +0,223,128,64,8,8,176,219,196,96,237,118,125,249,29,228,211,133,166,205,5,0,0, +0,0,12,0,110,186,9,47,96,84,0,30,120,104,34,112,86,158,37,243,142,7,0,0,0,192, +94,44,188,155,223,93,108,109,4,67,96,54,74,96,216,62,7,196,200,1,0,0,0,160, +177,197,98,11,12,34,62,204,37,184,1,174,237,92,104,13,148,74,181,0,0,0,0,0, +244,3,18,17,16,68,2,53,144,235,14,153,7,209,202,5,130,161,160,0,0,0,0,52,24, +160,137,231,156,91,8,132,3,2,218,144,236,219,135,133,191,162,45,0,0,0,0,118, +58,118,98,130,148,24,1,24,125,254,141,87,39,19,210,91,55,25,12,0,0,0,0,110, +139,33,145,0,0,0,64,0,0,0,2,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,142,120,110,95,63,126,221,61,247,252,155,252,174, +210,255,143,107,1,0,0,0,192,159,255,234,186,186,93,188,115,159,250,216,214, +222,37,75,94,151,218,42,1,0,0,0,224,182,153,27,216,116,230,79,21,191,41,230, +255,38,117,109,227,255,155,82,0,0,0,0,80,96,126,111,153,169,80,14,0,128,16, +216,35,0,37,16,144,244,235,117,0,0,0,0,208,219,0,160,152,178,123,6,82,32,152, +22,200,61,9,0,0,1,0,0,0,0,0,0,0,4,40,200,34,0,2,0,0,16,32,130,80,64,48,1,0,16, +0,4,0,0,0,0,74,4,1,16,20,0,128,0,4,255,253,36, +}; + +static const unsigned char big5hkscs_phint_12130[] = { +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,128,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0, +}; + +static const unsigned char big5hkscs_phint_21924[] = { +0,0,0,0,0,26,172,248,250,90,192,250,51,0,0,0,0,0,129,0,160,156,130,144,9,1, +180,192,176,3,86,2,160,66,45,136,1,0,0,0,0,146,119,139,96,5,201,33,6,70,56,96, +72,192,180,36,222,132,224,192,36,0,0,0,0,205,80,197,52,192,40,162,173,124,153, +24,88,18,34,196,66,162,83,142,30,0,0,0,128,52,135,11,21,209,64,250,61,0,4,210, +5,72,8,22,230,28,165,0,8,0,0,0,192,45,22,20,128,24,58,212,25,136,28,138,4, +}; + +static const DBCHAR __big5hkscs_bmp_encmap[26401] = { +50904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34905,34903,N,N,N,N,N,N, +34909,34907,M,N,N,N,N,N,N,N,34913,34911,N,N,N,N,N,N,N,N,N,N,N,N,34922,34920,N, +N,N,N,N,N,34927,34925,M,N,34931,34929,N,N,N,N,34935,34933,N,N,N,N,51451,34939, +34937,N,34978,34902,34919,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34906,34924,N,N,N,N, +N,N,34908,34926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34928,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51452,34910,34932,N,N,N,N,N,51450,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34936,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,34904,34921,N,34930,34912,34934,N,34938,N,34940,N,34941,N,34942,N,34977, +51446,34923,N,N,51448,N,N,N,N,N,N,51447,N,N,N,N,N,34984,N,N,N,N,N,N,N,N,51454, +N,N,N,N,N,N,N,N,N,N,51449,N,N,N,N,N,N,N,N,N,N,N,N,N,51445,N,N,N,N,N,N,51453,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50905,51193,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +51187,51188,51189,51190,51191,51192,51194,51195,51196,51197,51198,51264,51265, +51266,51267,51268,51269,51270,51271,51272,51273,51274,51275,51276,51277,51278, +51279,51280,51281,51282,51283,51284,51285,51286,51287,51288,51289,51290,51292, +51293,51294,51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305, +51306,51307,51308,51309,51310,51311,51312,51313,51314,51315,51316,51317,N, +51291,34915,34980,34917,34982,51410,N,N,N,N,N,N,N,N,N,N,51411,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50869,50870, +50871,50872,50873,50874,50875,50876,50877,50878,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,51319,51320,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,51318,34985,34986,50849,50850,50851, +50852,50853,50854,50855,50856,50857,50858,N,N,N,N,N,N,N,N,N,N,50859,50860, +50861,50862,50863,50864,50865,50866,50867,50868,63993,63992,63974,63983,63965, +63976,63985,63967,63980,63989,63971,63982,63991,63973,63977,63986,63968,63979, +63988,63970,63975,63984,63966,63981,63990,63972,63978,63987,63969,63994,63995, +63997,63996,50918,51414,N,N,N,51415,N,51416,51417,51418,N,51419,N,51420,51421, +N,N,N,N,N,N,N,51422,N,N,N,N,N,N,51423,51424,N,N,N,N,N,N,N,51425,N,51426,N,N, +51427,N,51428,N,51429,N,N,N,N,N,N,N,51430,N,N,N,N,N,51431,N,51432,N,N,N,N,N,N, +N,51433,N,N,N,51434,N,51435,51436,N,51437,N,N,N,N,N,N,51438,51439,N,N,N,N,N,N, +51440,N,N,N,N,51441,50893,50912,50913,50914,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,50919,50920,50921,50922,50923,50924,50925,50926,50927,50928,50929,50930, +50931,50932,50933,50934,50935,50936,50937,50938,50939,50940,50941,50942,51008, +51009,51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021, +51022,51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034, +51035,51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047, +51048,51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060, +51061,51062,51063,51064,51065,51066,N,N,N,N,N,N,N,51412,51413,50908,50909,N,N, +51067,51068,51069,51070,51105,51106,51107,51108,51109,51110,51111,51112,51113, +51114,51115,51116,51117,51118,51119,51120,51121,51122,51123,51124,51125,51126, +51127,51128,51129,51130,51131,51132,51133,51134,51135,51136,51137,51138,51139, +51140,51141,51142,51143,51144,51145,51146,51147,51148,51149,51150,51151,51152, +51153,51154,51155,51156,51157,51158,51159,51160,51161,51162,51163,51164,51165, +51166,51167,51168,51169,51170,51171,51172,51173,51174,51175,51176,51177,51178, +51179,51180,51181,51182,51183,51184,51185,51186,N,N,N,N,N,50915,50906,50907, +34880,34881,34882,34883,34884,34886,34889,34890,34893,34895,34896,34897,34898, +34900,34901,51321,51409,37495,N,N,N,N,N,N,N,N,N,N,38623,N,N,N,N,N,N,N,N,N, +36084,N,35285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37837,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,39903,N,N,N,N,N,N,64104,N,N,35290,36697,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,35291,N,N,36701,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35292,N,N,N,N,N, +N,N,N,N,38647,N,N,N,N,N,N,N,N,N,N,N,N,35546,N,N,N,N,35804,N,N,N,N,N,N,38875,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40531,N,N,N,N,40362,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,39914,35438,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35784, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35304,N,35306,N,N,N,N,N,35915,N,N,N,N,N,N, +N,64368,N,N,N,N,N,N,N,N,N,N,N,35309,N,N,38109,N,35310,N,N,N,N,40628,35539,N,N, +N,N,N,N,N,N,N,N,N,37595,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38107,35321,N,N,N, +N,N,N,N,N,64378,N,N,N,35323,N,N,N,N,N,N,N,40700,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,35324,N,35263,N,N,N,35326,N,35302,N,N,40262,N,N,N,40430,N,N,N,41086,N,N,N, +41064,N,N,N,N,39145,N,35688,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36349,35774, +40921,N,N,N,N,N,N,N,35563,N,N,40919,35690,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40028,N, +35761,N,N,N,N,N,N,N,N,64350,N,34672,N,N,N,N,N,N,N,40435,N,N,N,N,N,N,N,41168,N, +N,N,64614,N,N,N,N,37609,N,N,N,N,N,N,N,N,39660,36779,64072,N,N,N,N,36421,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,40047,N,36188,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,40670,N,N,N,N,N,N,35311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,38633,N,N,N,N,N,N,N,N,N,N,40635,N,N,N,N,38110,N,40632,N,N,N,38842,64357,N, +N,N,38358,N,N,N,40123,N,N,38874,N,N,N,N,36677,N,64381,37208,65124,N,38998, +39757,N,N,N,N,N,N,N,N,N,N,37723,38343,N,38887,N,N,N,N,N,N,37721,N,N,N,37365, +38840,N,N,64930,64438,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37626,37719,N,35750,N,N,N,N, +64441,N,38832,N,N,64964,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40097,N,N,N,N,N,37362, +37369,N,36849,N,N,N,N,N,N,38725,38995,N,N,65144,N,64449,37457,N,N,N,N,N,N, +40365,N,N,N,N,N,64876,N,N,64107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,39874,N,N,N,N,N,N,N,N,N,N,N,N,39547,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35680,N,N,N,N,N,N,N,N,37707, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39613,N,N,N,N,37303,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36171,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,38324,N,N,N,N,N,65221,N,N,40688,36196,N,N,N,N,N,N,N,N,N, +37481,N,N,N,N,N,N,36199,N,N,N,N,N,N,N,N,N,N,N,N,64490,N,N,N,N,N,N,N,N,64495,N, +36200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,37867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64578,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37222,N,N,N,N,N,N,N,N, +64205,N,N,N,N,37853,N,N,36178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,35788,36205,N,N,N,N,N,N,N,N,N,N,N,36206,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,38568,N,N,N,N,N,N,N,N,N,N,64678,N,N,N,N,N,N,N,N,N,N,N, +N,36207,N,N,N,N,N,N,N,N,N,N,N,N,N,36208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,64612,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36083,N,N,N,N,N,N,N,36960,N, +N,N,N,N,N,N,N,36212,38851,N,N,N,N,N,N,N,35536,N,N,N,N,N,N,37492,N,39870,N,N,N, +N,N,40136,N,N,40122,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36216,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40633,N,N,N,N,N,38234, +N,N,37300,N,N,N,N,N,N,35400,N,N,N,N,N,N,N,N,N,N,N,36221,N,N,35453,N,N,35522, +64842,N,36257,N,N,35537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64692,35655,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,37796,40666,N,N,N,N,N,N,N,N,N,35409,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,36262,N,N,N,N,N,N,40645,N,N,N,N,64708,N,N,N,N,41080,N, +38069,N,N,N,N,N,N,N,64706,35435,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36267,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64232,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36269,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64585,N,37825,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36975,N,36272,N,N,N,N,N,N,N,N,38014,37114,N,N,N,N,N,N,N,N,N,N, +38009,N,N,N,N,N,N,N,N,36274,N,N,N,N,N,N,N,N,64750,N,N,N,N,N,N,N,N,N,N,N,N,N, +39291,N,N,N,N,N,N,N,N,36276,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36279,N, +N,N,N,N,N,N,37299,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36283,36282,N,N,N,N,N,N,N,N, +36284,36932,N,N,N,64844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34635,37860,N, +N,37856,N,N,N,N,N,N,N,64851,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,36291,N,39864,N,N,N,64496,N,37865,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37878, +N,N,N,N,N,36293,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36298,N,N,N,N,N,36300,64861,37813, +64865,N,N,N,40184,N,N,N,37458,N,N,41192,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,40101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35926,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,36310,N,38848,N,N,N,41182,N,N,N,N,38866,N,N,N,N,N,64165,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,64931,N,N,N,36315,36074,36527,N,N,N,N,N,N,N,N,N,37301,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64841,N,N,N,N,N,N,N,N,64977,N,N,N,N,N,N,N, +N,N,N,36331,N,N,N,N,N,38854,N,64974,N,N,37116,N,N,N,N,N,N,N,N,N,N,N,N,N,64601, +N,N,38614,N,N,N,N,N,N,38853,36335,N,N,N,N,38871,N,N,N,N,N,36336,N,N,N,N,N,N,N, +38566,N,N,N,N,N,N,N,64447,N,N,36063,N,36339,N,N,N,N,37961,N,36341,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,39026,N,N,N,N,N,N,N,36459,N,N,N,N,N,N,64253,N,N,N,N, +N,N,N,N,N,N,36688,N,N,N,N,N,N,40396,64613,N,35908,N,N,39278,38049,N,N,N,N,N, +36707,N,N,N,N,N,N,N,41178,N,N,N,N,N,N,N,N,N,N,N,37459,65001,N,N,40373,N,N,N,N, +N,N,N,39033,34666,N,N,40285,N,N,N,N,36195,38505,40816,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,64618,N,N,35527,N,N,N,N,35287,N,N,N,N,N,N,N,N,N,N,N,N,65101,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40669,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,65275,39100,64204,N,N,38320,N,N,N,37988,N,N,N,N,N,N,37743,N,N,N,N,N,N, +38073,N,N,38380,N,N,N,N,37358,N,N,39107,N,38390,N,N,N,36861,39109,N,N,N,N, +38758,65134,N,N,38877,36010,N,N,37586,N,N,38753,39115,N,N,N,N,38384,N,38749,N, +37347,N,N,N,N,39116,N,N,37993,39117,N,N,N,N,N,39118,N,38396,N,N,38051,38498,N, +N,N,65206,N,37987,36167,N,N,N,N,N,N,39120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,39121,N,N,N,N,38005,64224,N,N,N,N,N,N,N,N,N,38002,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39126,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,35568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39129,N,N,N,N,N,N,N,36186,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,39131,N,N,N,N,39133,N,N,N,N,N,N,N,N,39080,N,N,N,N,N,N,N,35437,N,N,N,N,N, +N,N,N,N,N,N,35579,35502,64457,N,N,N,N,35933,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,39140,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39142,N,N,N,N, +N,N,N,N,N,N,N,39144,N,N,N,N,N,N,N,N,N,N,N,N,N,35405,N,N,N,37463,N,N,N,N,N,N,N, +N,N,N,38367,N,N,41132,N,N,N,N,39147,N,N,N,N,39148,N,36035,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,39156,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35512,N,N,N,40679,N,N,N,N, +N,N,N,N,38076,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64721,N,N,N,N,N,N,40134,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36170,N,40574,36164,39166,65000,N,N,N,N, +39232,N,N,N,N,38089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,38099,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39238,N,N,N,N,37056,N,38097,N,N,N, +N,N,N,N,N,N,N,N,N,N,36174,N,N,38259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37826,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39240,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,39243,N,N,N,N,N,36437,N,N,N,N,39246,N,N,N,N,N,N,N,N,N, +N,N,36606,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36191,N,36441,N,N,N,N,N,N,N,N,N, +38124,38127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35936,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36724,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,39253,N,N,N,N,N,N,N,N,N,38212,N,N,N,N,N,N,N,N,N,N,N,36043, +N,N,N,39254,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39257,N,N,N,N,N,N,N,39259,N,N,N, +N,N,N,N,N,N,N,N,N,N,36036,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64069,N,N,N, +37047,N,N,38723,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38349,N,N,N,N,N,N,38857,64848, +36537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38342,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39271,N,N, +36067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35513,N,N, +N,N,N,N,36348,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35446,N,N,N,N,N, +40273,N,N,N,N,N,N,N,N,N,N,N,N,N,39283,N,N,34624,N,40271,39290,38244,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,39329,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39333,N,N,N,N,N, +N,N,39335,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,36589,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39341,N,51326,N,N,N,N,N,N, +N,N,N,N,N,N,N,37998,36720,N,64208,N,N,N,N,N,N,N,N,N,N,N,N,N,39347,N,N,N,N,N,N, +41043,N,N,N,N,N,36190,N,N,38492,N,N,36064,N,64890,N,N,N,N,N,N,N,N,38910,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,37565,36189,38909,N,N,N,N,36708,N,N,N,N,64759,38242, +38861,40548,N,N,N,N,N,N,N,37452,36553,39356,N,N,N,N,40357,N,36692,N,N,N,N,N,N, +N,N,N,N,36732,N,N,N,N,36181,N,36514,N,N,N,N,N,N,N,N,N,36730,N,N,N,N,N,N,38830, +N,N,N,N,38600,N,N,36068,N,N,N,N,39363,N,37078,N,40126,N,N,N,36726,N,N,N,N,N,N, +N,N,N,N,N,N,N,38000,64331,N,N,64970,N,N,36079,N,N,N,36551,N,N,N,N,36180,41209, +N,N,N,N,N,N,N,36777,N,N,36177,N,N,N,N,N,N,N,N,N,39367,34628,N,N,N,N,N,N,N,N,N, +N,N,N,37079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +34627,N,N,N,N,N,N,N,N,N,N,N,N,34631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34648,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40671, +36185,34626,N,N,39374,N,N,N,N,N,N,N,N,36794,N,N,N,N,N,36843,N,39375,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36802,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37577,N,N,N,N,N,38876,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34653,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,36165,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38323,40057,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38322,N, +36172,36827,N,N,N,N,39907,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,34636,N,N,N,N,N,N,N,N,N,N,N,N,N,34637,N,N,N,N,N,N,N,N,N,40570,34647,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,39918,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39390,N,N,N, +N,N,N,N,N,N,N,N,N,N,64250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35410,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,39393,N,N,N,N,N,N,35431,35765,N,N,N,N,N,N,N,N,N,N,35500,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39401,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,64458,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38878,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38353,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,39413,64586,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,39849,N,N,N,N,N,N,N,N,N,N,N,N,64476,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,65110,N,N,N,N,N,40612,N,N,N,N,N,N,40265,38363,N,N,N,N,N,N,N,N,N,N,35269, +N,N,N,N,N,N,N,N,N,N,N,N,39416,N,N,N,N,N,N,38500,N,N,N,N,36949,N,N,38612,N,N,N, +N,N,N,N,38780,N,N,N,N,N,N,38477,N,38881,N,N,N,N,N,N,39496,N,N,N,N,N,N,N,N,N,N, +N,39497,N,65149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37034,N,N,N,N,39504,N,N,N,N, +N,N,N,37703,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36568,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37065,N,N,N,N,N,39509,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37052,N,N,N,N,N,39512,N,35768,37077,N,N,N,N,N,N,N,N,N,N,N,N,N,38465,N,N, +N,N,N,N,39514,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39516,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,38850,N,N,N,N,N,N,N,N,N,N,N,N,N,34652,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35515,N,N,N,39850,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37109,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,37189,35928,N,N,N,N,N,N,N,N,39523,N,N,N,N,N,N,35913,N,N,N,N,N,N,N,N, +N,N,N,35766,N,N,N,N,N,N,N,N,N,N,64719,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38507, +39534,N,37199,N,N,N,N,N,N,N,N,38726,N,N,41190,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37591,N,38517,N,N,37844,N,N,37307,38521,N,N,N,N,N,39536,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38520,37325,N,40010,41071,N,N,41066,N, +N,N,N,N,N,37215,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,34625,N,N,N,N,N,N,N,N,40869,N,N,35258,N,34639,N,N,N,N,N,N,34638,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,34645,N,N,N,40653,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39545,N,N,N,N,N,N,N,N,N,36082,N,N,N,36183,N,40398,N,N,N,36050,N,N,N,34649,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40307,N,N,N,N,N,N,N,N, +N,38585,N,38588,N,N,N,N,N,N,40145,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35255,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40686,34633,N,N,N,N,N,N,N,N,N,N, +64323,34651,N,40649,N,N,N,N,N,N,64467,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,36184,34630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36182,N,N,N,N,N,N,N, +40312,N,N,N,N,N,N,N,N,N,N,40315,40627,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,40626,N,40406,N,N,N,N,39247,N,N,35278,N,N,N,35776,N,40900,N,35796,N,N,35954, +N,N,N,N,N,N,50879,35833,N,N,N,N,N,35142,N,50880,N,N,N,N,N,N,N,N,N,64229,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,51323,35782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40023,N,N,N, +N,N,N,N,N,N,N,N,N,N,39675,N,N,N,N,N,N,N,35280,35279,N,N,N,50881,N,35281,N, +35298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37502,N,40378,N,N,N,N,N,50882,N,N,35951,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64504,N,N,N,35783,37483,N,N,35282,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,40911,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40361,35283,N,N,39394,N,N,N,N,N,N,N,N,N,37479,37540,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,35955,N,N,35150,N,N,N,N,N,N,N,N,N,N,N,N,N,35151,37496,N,N,N,N,N,N, +N,N,37302,N,N,N,N,35284,N,40914,N,N,N,N,N,N,N,N,37543,N,N,38306,N,N,N,N,N, +37486,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,38634,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37487,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37539,N,N,N,N,N,35152,N,N,64087,N,N,N,N,39014,N, +N,N,36088,N,N,N,N,N,N,N,N,35286,N,N,N,N,N,N,N,N,N,N,39090,N,N,N,37547,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38622,37548,N,N,N,N,N,N,N,N,N,N,35952,N, +40814,N,N,N,N,N,N,36594,N,N,N,40812,35288,N,N,N,N,64089,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37544,N,N,N,N,N,37219,N,N, +N,N,N,N,35904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40819,N, +37549,N,N,N,N,N,N,N,N,N,N,N,N,N,39913,N,N,N,N,N,37545,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,37546,N,N,N,N,N,N,35289,N,N,N,N,N,N,N,64854,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,40872,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35953, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37537,N,N,37091,N,N,N,N,N,N,N,N,41126,N,N,N,N, +N,38059,N,64626,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38852,N,N,N,N,N,N,N,37550, +64103,N,N,N,N,N,N,N,N,N,N,N,37538,64105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,37480,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35153,N,N,N,N,N,N,N,N,N,64111,N,N,N,N,N,N,N,N,N, +64113,N,N,N,N,N,N,N,N,N,35154,N,N,N,N,37978,N,N,N,N,N,N,N,N,50883,N,N,N,35293, +N,51362,N,N,N,N,N,N,N,N,N,N,N,N,N,50884,N,N,N,40530,N,35155,N,N,N,N,N,N,N,N,N, +N,40533,37562,N,N,50885,N,N,35931,N,N,N,64125,64168,39528,64071,N,N,64126,N,N, +N,N,N,N,N,N,N,N,37563,N,N,N,64950,N,64162,N,N,N,N,N,64163,N,64164,39860,64166, +N,N,N,N,N,N,N,35295,N,N,N,64987,N,N,64169,N,35156,N,N,N,N,N,N,N,N,64171,N,N,N, +N,N,N,64634,N,N,N,N,N,N,N,35296,N,40783,51325,N,N,35297,N,N,N,N,N,64176,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40909,41191,N,N,N,N,N,64177,35238,N,N,N,N,N,N, +N,N,N,N,N,N,40698,N,N,N,N,N,N,N,64178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,64180,N,37572,N,N,N,N,N,N,40815,N,N,N,N,N,N,N,35760,N,N,N,N,N,N,N, +N,N,N,40876,N,N,N,N,N,35299,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39891, +35300,N,N,N,64181,N,N,N,N,N,40917,N,N,N,N,N,N,35157,N,N,37573,N,N,N,35158,N,N, +N,N,N,N,N,N,N,N,N,N,64179,N,N,N,64182,N,N,N,N,N,N,N,N,N,N,N,64183,N,N,N,N,N,N, +40668,N,N,N,64452,40817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64186,37575,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50886,39500,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35944,N,N,35301,N,N,N,N,40829,N,N,N,N,N, +41129,64196,N,N,N,N,50887,N,N,35159,N,N,N,N,N,N,64170,N,N,N,N,N,N,N,N,N,N,N, +35160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35811,N,35681,N,N,N,N,39665,N,N,40631,N, +50888,N,N,N,64209,N,N,N,N,N,N,64210,N,N,N,N,N,N,N,N,40634,64212,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,64217,N,N,N,N,N,N,N,N,N,N,N,N,64219,N,40160,N,N,N, +64503,N,64506,35303,41082,64220,N,N,64221,N,35305,N,N,N,N,N,50889,N,N,N,N,N,N, +N,N,N,N,64226,35307,N,N,64227,N,N,N,N,N,N,37064,N,N,N,37594,35161,40181,N,N,N, +N,N,35162,64231,40866,N,N,N,N,N,64234,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,64237,36781,N,N,N,N,N,N,64345,64239,38639,N,40428,N,N,N,40394,N,N,N,N,N,N, +64877,N,35308,N,N,N,N,N,N,N,N,N,N,N,64324,N,N,40418,N,35957,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,40640,N,40534,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,40825,39623,N,N,64244,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,39073,N,N,N,N,N,N,N,N,N,64248,N,N,N,35312,40519,N,N,40439,N,N,N,N,40915, +N,39626,N,N,N,N,35313,64249,N,N,N,N,N,N,N,N,N,N,N,N,N,36442,N,35314,N,N,N,N, +35315,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37469,35665,37600,N,N,35316,N,N,N,N,N, +N,N,N,N,40916,N,N,N,N,N,N,N,N,35449,N,N,N,N,N,N,N,N,N,N,N,35317,38823,N,N,N,N, +N,N,N,N,N,N,37818,N,N,N,N,N,40536,N,N,N,N,35318,N,N,N,N,N,40535,N,N,N,N,35319, +N,35393,N,N,35320,N,N,64241,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35322,N,N,N, +N,N,N,N,64322,N,64191,N,N,N,N,N,N,N,N,N,64419,N,N,N,N,N,N,N,N,N,64247,N,N,N,N, +N,N,N,N,N,N,N,40526,N,38108,N,N,N,N,N,38362,40440,40810,N,N,N,N,N,35511,N,N,N, +N,N,N,N,N,N,N,N,N,64326,N,N,N,N,N,N,N,N,N,35398,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,64327,N,N,N,N,N,N,37192,N,N,N,37598,N,N,N,N,35667,40438,N, +39898,N,N,N,N,40318,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35325,39396,N,N, +N,N,N,40515,N,N,N,N,N,N,N,N,N,N,N,40425,N,36690,N,N,N,40437,40432,N,N,N,39399, +N,N,N,N,N,35773,40431,N,N,N,N,N,N,N,N,N,N,N,40887,N,N,N,N,N,N,N,N,N,N,N,N, +40400,N,40939,36265,40399,39137,N,40421,N,N,N,N,N,N,N,40392,N,N,N,N,N,N,N,N,N, +64335,N,N,N,N,N,N,N,N,N,N,N,40427,N,N,N,N,N,N,N,N,N,64340,N,64341,39586,N, +35542,N,39519,N,N,N,N,N,N,N,N,40693,N,N,N,36791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,39634,40554,40680,N,N,N,N,N,N,N,N,N,N,N,N,35775,37314,40290, +N,N,N,N,N,N,37472,N,N,N,N,N,N,N,N,N,N,N,37470,37313,N,35525,N,N,38819,N,N,N,N, +N,N,N,N,N,N,35692,N,36222,N,N,N,N,N,N,N,40020,N,N,N,N,N,40381,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,40133,N,N,N,N,N,N,N,N,N,N,N,35163,N,N,N,N,N,N,N,N, +N,N,64348,N,64347,N,64343,N,N,N,N,N,N,N,N,N,34661,N,39111,64346,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,40174,N,N,N,N,N,N,N,37602,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,38055,N,N,N,N,N,N,N,N,N,N,36044,N,39892,N,N,64356,64374,N,N, +64352,N,N,N,N,N,N,N,N,N,N,N,N,N,39397,N,N,39618,N,N,N,37371,N,N,N,41075,N,N,N, +N,N,N,N,40818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40908,N,N,N,39077,37608,N,N, +N,N,N,N,N,N,39868,N,38643,N,N,37607,N,N,64615,N,N,N,N,N,N,N,N,N,N,N,35709,N,N, +N,N,39924,N,N,N,N,N,40695,N,N,40641,N,N,N,N,N,N,N,N,N,39279,N,N,N,N,N,N,38641, +N,N,36417,N,N,N,N,N,38218,N,N,N,38886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38645,N,N,N, +N,N,37606,40770,N,N,N,N,N,N,N,64359,N,N,N,N,N,N,N,N,39337,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,64230,64361,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38885,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,38525,N,N,N,64364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39330,N,N,N,N,N, +39611,N,N,N,39525,N,N,37966,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64366,N,N, +39391,N,N,N,N,N,N,N,N,N,39139,N,N,37460,N,N,N,N,N,38523,35503,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35959,N,N,N,N,N,N,35759,40637,N,N, +N,N,N,N,N,N,N,N,N,N,40678,N,N,64367,N,N,N,N,N,36577,N,N,N,N,39805,40062,N,N,N, +N,63961,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37610,N,N,N,N,35960,N,N,N,N,N,N,N,N,N,N, +N,64370,N,N,N,64369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35164,N,39152,38642,N,N,N,N, +N,N,N,64372,35777,N,35165,35294,N,35166,N,N,50890,N,N,N,N,N,N,65090,N,N,N,N,N, +N,N,N,N,N,N,34664,N,64379,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35167,N,35168,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,39885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40403,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,38988,N,N,N,N,N,N,N,N,N,N,38738,N,N,N,N,N,38339,N,N,N,N, +39862,N,N,N,N,N,N,N,N,N,N,N,N,39609,N,N,N,38835,N,N,N,N,N,N,40820,37617,N,N,N, +N,N,N,36090,N,N,N,N,38879,N,N,N,N,64422,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64427,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39031,N,N,N,38996,38341,N,N,N,N,N,N,N,40277, +64434,38270,N,N,N,N,N,N,N,N,38722,N,38118,N,N,N,N,37621,N,N,N,N,N,N,N,36037,N, +N,N,N,N,N,37629,N,N,64418,N,N,40017,N,N,38121,39004,37616,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,37964,N,N,N,N,N,N,N,37227,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35704,N,N,N, +N,38114,N,N,N,N,N,N,N,38991,N,64437,N,N,N,N,37489,N,N,37733,N,N,39003,N,N, +38992,N,N,N,N,N,N,N,38844,N,N,N,N,37619,N,N,37696,38989,N,N,N,38258,N,65007,N, +N,N,N,N,N,N,N,64961,N,N,N,N,64442,N,N,37611,N,N,N,N,N,N,64627,38839,N,N,34671, +N,N,N,N,N,N,64436,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37031,N,N,N,N, +N,N,N,N,N,N,38721,37620,N,34674,N,64444,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38263, +N,N,N,N,N,N,N,N,N,N,N,40674,N,36728,N,N,N,N,N,N,N,63964,N,N,N,38514,40629,N,N, +N,38475,N,N,N,36012,N,N,N,N,N,N,N,N,N,41210,N,N,N,N,N,N,N,N,N,N,N,38261,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37082,N,N,37735,N,65188,N,N,N,37087,N,N,N, +N,37716,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35169,N,35764,N,N,N,N, +40384,N,N,N,N,N,N,36424,N,64453,N,N,N,N,N,64455,N,N,N,50891,N,64121,N,N,N,N,N, +N,N,N,N,N,N,N,N,40551,N,N,N,N,N,36057,N,N,N,N,N,N,64466,35170,35171,N,N,N,N,N, +N,N,N,N,N,64637,N,N,N,N,N,N,N,N,N,N,N,N,34675,N,N,N,N,N,N,N,N,N,N,N,40811,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64460,N,65198,N,N,N,34669,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,64465,N,N,N,N,N,N,N,N,N,N,N,64373,64468,N,N,N,N,N,N,N, +N,N,N,N,N,N,64470,64472,N,N,N,N,N,N,N,35677,N,37708,N,39650,N,N,35785,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64475,40905, +N,N,N,N,N,N,N,N,40772,N,N,N,N,N,N,N,N,N,N,39149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,36073,N,N,N,N,N,N,N,N,N,N,N,N,64477,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,36338,35172,N,65010,N,37709,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,64487,N,N,N,N,N,N,41202,39016,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40792,N,N,N,36070,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36211,N,N,N,64478,N,N,N,N,N, +64479,N,N,N,N,N,35912,N,N,N,N,N,N,34676,64483,N,N,N,N,36264,N,N,64484,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40053,N,N,39032,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36192,N,N,N,N,N,N,N,64485,N,36193,N,N,N,N,N,N,N,N,N,N,N,N,N,36194,41121,N,N,N, +40000,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39085,N,N,N,40682,N,N,N,36076,N, +N,36052,N,N,N,N,N,N,N,N,N,40171,N,N,N,N,N,64480,N,N,40785,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,36197,N,N,N,N,N,N,40177,N,N,N,N,N,N,N,N,N,N,64600,N,N, +36198,N,N,N,N,N,N,N,38484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64488,N,N, +N,50892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40910,64508,N,39652, +N,N,N,N,N,N,40821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64497, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36201,N,N,N,N,N,37711,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,37710,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,64500,N,N,N,N,50894,N,N,N,64451,N,N,35173,N,N,N,N,N,N,N,N,N,N,N,35962,N, +N,N,N,N,N,35963,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,36202,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37715,N,N,40443,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64509,N,N,N,36953,64576,N, +64577,64579,37729,64582,37730,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36203,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64588,36094,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,38328,N,N,50896,35786,N,N,N,N,N,N,N,N,N,N,39034,N,N,N,N,50897,N, +64593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64596,N,N,N,N,N,N,N,N,64175,N,N,N,N,N,N,N, +36204,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64097,N, +N,64599,N,N,N,N,N,N,N,N,N,39792,N,N,N,N,N,N,N,N,41041,N,N,N,N,N,N,N,35964,N, +35787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37742,N,N,N,64725,64681,N,N, +N,N,N,N,N,N,N,N,N,N,N,64609,N,N,N,N,N,N,N,N,N,35174,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,64203,N,N,N,N,N,N,N,63962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,37754,N,41184,N,N,N,N,N,N,37739,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64619,N,N,N,N,N,41180,N,N,37992,N,N,N,N,N,N, +N,N,N,N,N,64621,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,36209,N,N,N,N,N,N,64868,N,N,N,N,39354,N,N,N,39632,39521,41189,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41051,38572,N,N,N,N,38720,N,N,N,N,N,N,N,N,N,N,N, +N,40689,N,N,N,N,N,N,N,N,35917,N,N,N,N,N,N,N,N,N,N,N,N,N,40830,N,N,N,N,N,N,N,N, +N,N,N,N,36210,N,N,N,N,64630,N,N,N,N,N,N,N,N,N,N,N,N,N,38569,N,N,N,N,N,N,N,N, +41070,N,N,64682,N,N,N,64461,N,N,N,64628,N,N,N,N,N,N,N,N,N,N,41076,N,N,N,N,N,N, +N,N,N,N,N,N,N,41073,N,N,N,64633,N,N,N,N,N,64636,N,N,N,N,N,N,N,N,N,N,N,N,N, +40016,N,N,37753,37752,N,N,41181,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,36213,N,36214,N,N,N,N,N,N,37748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36215,64677, +N,N,64674,N,N,N,N,N,N,37059,N,N,N,N,N,N,N,41081,36217,N,N,N,N,N,N,N,N,N,N, +35836,N,41078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35789,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40794,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,40948,N,N,40890,N,N,N,N,N,N,N,N,N,N,36218,N,N,N,N,N,N,N,N,N,N,N,N, +40517,N,N,N,N,N,N,37808,N,41077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,39750,N,64686,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64688,N,N,N,N,N,N,N,N,N, +64081,N,N,N,N,N,36219,36220,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40662,N, +N,37804,N,N,N,40795,N,37801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41084,N,N,N,N,N,N,N,64690,N,N,N,N,N,N,N, +N,N,N,N,N,35521,N,N,N,N,N,40884,N,N,N,N,N,N,N,N,N,N,N,64684,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40524, +N,N,N,N,N,N,N,36805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37805,N,N,N,N,N,N,N,N,N,N,N, +N,40387,N,N,N,36258,N,N,N,40266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64694,N,N, +36259,40523,N,40525,36260,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35581,N,N,N,N,N,64693,N,64707,37810,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36261,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,37793,N,N,N,N,N,N,N,N,N,N,35526,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,35419,N,N,N,35149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,65236,N,N,N,N,35448,N,37803,N,N,N,N,N,N,N,N,N,36263,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,40773,N,N,N,N,N,N,N,N,N,35414,N,N,N,64703,N,N,N,64704,N,36582, +N,N,35492,35139,N,N,N,N,N,N,37875,N,N,N,N,N,N,N,N,N,N,N,N,64683,40610,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,40391,N,N,N,50898,35790,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,64709,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64715,N,N,N,N,N,N,N,N, +N,N,N,37811,N,64714,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64713,36268, +N,64454,35175,N,35966,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,64717,N,N,N,N,N,N,N,N,40179,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,64720,N,N,38331,N,N,N,N,N,N,N,N,N,N,N,64723,N,N,64724,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36270,64727,N,N,N,N,N,37851,N,N,N,N, +65123,N,N,N,N,N,N,N,N,N,N,N,N,37845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64730,N,N,N,39793,N,N,64733,N,34660,N,N,N,N,N,36271,N,N,N,64242,N,N,N,N,N,N,N, +N,N,N,N,37848,N,N,N,64735,N,N,N,37843,N,N,N,N,N,N,N,64737,N,N,N,N,N,N,N,N,N, +36470,N,N,N,N,N,N,N,64610,N,N,N,N,N,N,N,N,37841,N,N,N,36273,N,N,N,N,N,N,N, +39001,N,N,N,N,N,N,N,N,N,64338,N,N,N,N,N,N,N,N,64339,N,N,N,N,N,64333,N,N,40127, +N,N,N,N,N,N,N,N,39794,N,N,N,N,N,N,N,N,N,N,N,N,N,64336,37822,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36059,N,N,N,N,N,N,N,N,N,40433,64747,N,N,N,N,N,N, +N,N,N,41147,N,39806,N,N,N,N,N,N,N,36275,N,N,35922,N,N,N,N,39656,N,N,N,N,N,N, +36572,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40185,N,N,N,N,N,N,N,N,N,N,N,N,N,64080,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39143,64755,N,N,N,N, +64754,N,N,N,36042,N,N,34677,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,37861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39513,N,N,N,36277,N,N,N,N, +N,N,N,64845,N,N,N,N,64862,N,N,N,N,N,N,N,N,N,N,N,N,N,36733,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,38215,64758,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,37456,N,N,N,N,35176,36278,64763,41085,39164,35177,N,N, +N,N,N,N,N,N,65103,N,N,37462,N,N,N,N,N,N,N,N,N,N,64201,N,N,37864,N,N,N,64760,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40163,64937,N,N,N,N,N,N,64580,N,N,N,N,N,N, +N,N,38464,N,N,36280,N,N,N,N,N,N,N,N,N,N,39754,36793,N,N,N,N,N,N,64766,N,N,N,N, +N,N,N,35178,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36281, +N,N,N,37246,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37876,N,N,N,N,N,N,N,N,N,N,N,N,N, +64380,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37863,N,N,38895,N,N,N,65098,N,N,N,N,N, +64837,N,38565,N,N,N,N,65248,64840,64839,65266,65130,N,N,N,N,N,36285,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,39841,36002,39607,36604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40865,N,N,N,N,N,N,N,N,N,64849,N,N,N,N,N,N,N,64173,N,N,N,N,36286,N,N,35236,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,39641,N,N,N,N,N,N,N,N,N,N,N,64846,N,N,36288,N,N,38896, +N,N,N,N,N,N,N,N,N,N,37812,64836,N,N,N,N,N,N,N,N,N,N,N,N,40871,N,N,N,N,36290,N, +N,N,N,39350,N,N,N,N,N,N,N,N,N,N,N,N,N,64850,N,N,N,N,N,N,36289,N,N,36422,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,41169,N,N,N,N,N,N,N,N,N,N,N,N,N,40906,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,37583,N,N,N,40180,36292,N,N,N,N,N,N,N,N,N,N,64833,N,N,N,N,N,N, +N,39756,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64855,64751,40158,N,N,N,N,N,N,N,64834, +39020,N,N,N,N,N,N,N,N,N,N,N,N,N,38905,N,38232,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39006,65147,38093,N,N,N,N,N,37870,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36003,N,64858, +N,N,N,N,N,N,37877,N,N,N,N,N,37871,36586,N,N,N,36699,N,N,N,N,N,N,N,N,N,N,N, +35934,N,36294,N,N,N,N,N,N,N,N,N,N,N,36296,N,N,36295,N,N,N,N,N,37879,N,N,N,N,N, +N,N,36297,N,N,N,N,N,N,N,64498,N,N,N,N,38512,N,N,N,N,N,N,N,N,N,36299,N,N,N, +64860,N,N,N,N,N,N,N,N,N,36709,N,N,N,36301,N,N,N,N,N,40360,38137,N,N,36302,N,N, +N,N,N,N,N,N,37866,N,N,N,N,N,N,N,N,N,64863,37872,40886,N,N,N,N,N,N,N,N,N,36303, +N,N,N,38755,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36304, +37873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64866,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,64869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,40923,N,N,N,N,37880,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35831,N,N,N,N,64870,N,N,N,N,N,35791,N,N,N,N,N,N,36305,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,36306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,64881,N,N,N,N,64879,N,N,N,N,N,N,N,N,36307,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40935,37053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40912,N,N,N,35792,N,64882, +N,40110,35793,N,N,35547,N,N,N,N,N,N,N,N,N,N,N,64228,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,38350,N,64886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64354,N,N,N,N,N,N,36308, +N,N,N,64888,N,N,N,N,N,36579,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36982,N,N,39110,N,N,N,N,N,N,N,36309,N,N,N,N,38865,N,N,40630,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64199,N,N,41026,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,39027,N,N,N,N,N,N,N,N,N,N,40956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,36005,36311,N,N,37627,36312,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,37967,N,36313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,35179,N,N,N,N,N,N,N,N,38862,N,N,N,64243,64942,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64431,37559,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36314,N,N,N,N,N,N,N,N,N,N,N,N,N,40026,N,N,N,N,N,N,64941,N,N,N,N,N,N,N,N,N,N,N, +N,N,36316,37956,N,N,N,N,N,N,N,N,N,N,N,36317,N,N,N,N,N,N,N,41174,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35905,38869,N,37962,N,N,N,N,N, +37965,N,N,N,N,38859,N,N,N,N,N,36318,N,N,36319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36320,65273,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,64960,64761,N,N,N,N,N,N,36061,N,64382,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,37555,N,N,N,N,N,64943,N,N,N,N,N,N,N,N,N,36321,N,N,N,N, +38355,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64872,N,N,40119,N,N,36323,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,64192,36325,64100,N,35143,N,N,N,N,36324,N,N,N,N,N,36327, +36328,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64967,64944,N,N,N,N,N,N,37957,38870,N,N, +N,N,N,N,N,N,N,64710,38980,N,N,N,N,N,N,N,N,N,N,N,N,36329,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,36330,N,N,N,N,N,N,N,N,65104,N,N,N,N,N,N,64972,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,40359,N,N,N,N,N,64973,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64975,N,N,N,N,38354,N,N,N,N,N,N,N,36333,N,N,N,N,N,N,N,N,64698,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,64965,N,64978,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40156,N,N,N,N,N,38351,N,N,36334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64980, +N,N,N,N,N,38636,38635,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37046,N,64963,39083,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38638, +N,N,N,N,N,N,N,N,N,N,N,N,N,36340,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64992,N,35943,N,N,36342,N,N,N,36343,N,N,N,N,N,N,N,36858,N,N,N,N, +N,N,N,N,N,N,38864,N,N,N,N,35794,N,N,36344,N,N,N,N,N,37081,N,35911,N,64240,N,N, +N,N,64993,36345,N,64995,N,N,N,N,N,N,N,36346,N,64355,N,N,N,37030,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,39280,N,N,37355,N,38768,39023,64994,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,39154,N,39676,35180,65021,N,N,39262,N,N,N,38333,N,N,N,N,N,N,N,64996, +N,N,N,37350,N,N,N,N,64997,64998,N,N,N,N,N,N,N,N,64999,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,37972,N,N,N,39352,N,N,N,N,N,N,N,N,38889,37702,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,39011,N,N,N,N,N,N,N,N,N,N,N,38332,N,65005,65015,N,N,N, +N,N,N,39024,38646,36521,N,N,N,N,N,37969,N,N,36419,N,35674,N,N,N,N,65006,N,N,N, +N,65008,N,N,N,N,65012,N,39925,N,N,N,N,N,36078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,38782,N,N,N,N,N,39893,N,39619,N,38856,41179,37328,N,N,40932,N,36829,N, +37353,N,N,N,N,N,N,N,N,N,39136,N,N,N,37578,N,38999,N,N,35921,N,N,N,N,65003,N, +39753,N,N,N,N,N,N,N,N,N,40310,40623,N,N,N,N,N,N,N,N,N,40140,N,N,N,N,N,N,65002, +N,N,36337,N,N,65019,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36435,N,N,N,N, +N,N,N,N,N,N,N,64207,N,N,N,N,N,N,N,N,N,N,N,N,N,38649,N,N,N,N,N,N,N,N,N,39103, +40521,36007,N,N,N,N,N,N,N,N,39882,N,N,N,N,65022,37596,N,N,N,N,N,65089,37324, +37346,N,N,N,N,N,N,N,N,N,N,N,N,65092,34655,N,N,N,N,N,35795,N,N,65095,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,65096,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37973,N,N,N,N, +65099,N,65100,N,N,N,N,36287,N,N,N,N,N,N,N,N,N,40568,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,65105,N,N,N,N,37974,N,N,N,N,N,N,N,40289,N,N,N,N, +37975,N,N,N,N,N,N,N,N,N,N,39270,N,N,N,N,N,N,N,N,N,N,N,N,N,35797,N,N,N,N,41065, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39092,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,41033,41036,N,40549,N,N,N,N,N,N,N,N,N,N,N,39093,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65112,N,39285,65107,41061,N,65113,N,N,N,N, +N,N,N,N,N,39095,39096,N,N,N,N,N,N,N,39098,N,N,N,N,N,N,39099,N,N,N,N,N,N,40892, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41034,N,N, +40647,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36009,N,N,39086,N,N,N,N,N, +N,N,N,37590,N,N,N,64225,N,37332,N,N,N,N,N,N,N,N,64222,N,N,65115,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,35923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65118,N,N,N,N,64471,65114, +38085,N,N,N,N,64202,N,N,N,N,N,N,N,N,N,N,N,39105,38748,N,65140,N,38771,N,N,N,N, +N,N,N,N,64070,N,N,N,38756,N,N,N,65128,N,38478,N,38757,35930,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,35233,38394,N,37588,65129,N,64325,N,39112,N,N,37103,N,39113,39114,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37997,38071,65132,N,N,37995,N,N,N, +N,N,N,37628,N,38379,N,65139,38766,65119,N,N,N,N,N,N,N,N,N,64957,N,N,37589,N,N, +N,N,N,N,65209,N,N,65137,34680,N,N,N,64443,N,N,38010,N,N,38395,65143,N,N,N,N,N, +N,N,65145,N,65141,N,N,N,37981,N,N,N,N,N,N,N,65148,N,N,N,N,N,N,N,N,N,37700, +36518,N,N,N,N,N,N,N,N,N,N,N,37587,N,38072,N,34681,N,N,N,N,N,N,64625,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,38750,N,N,N,N,36013,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65191,N,N, +N,37994,N,N,N,37859,N,N,39119,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41177,N,N, +N,N,N,N,N,N,41151,41037,41144,N,N,N,N,N,41166,41143,N,N,N,N,N,N,N,N,65193,N,N, +N,N,N,N,N,N,N,N,35267,N,N,N,N,65195,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40436,35181,N,N,N,N,N,40059,N,N,N,N,N,N,39122,N,N,N,40873,N,N,N,65202,N,N, +65201,N,N,N,38873,N,41156,N,38006,N,N,N,N,N,N,N,N,N,N,39288,N,N,N,N,N,N,65203, +N,N,N,N,N,39123,65204,N,N,N,39124,N,N,N,N,N,N,N,40889,N,N,N,N,N,N,N,N,38001,N, +N,N,N,N,N,N,N,N,39125,65208,N,N,N,50900,N,N,N,N,N,N,N,N,N,N,N,65210,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,40540,N,N,65211,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41028,N, +N,N,N,39127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39128,65212,N,N,N,N,40958,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65213,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,40413,N,N,N,N,40673,N,N,N,N,N,N,N,N,N,N,N,N,39130, +40415,65215,N,65214,N,N,40683,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40537,41052,N, +N,N,N,N,N,N,65216,N,N,N,38007,39132,N,65217,N,N,N,39134,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,65219,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65224,N,N,N,65225,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65226,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +65227,N,N,N,N,N,N,N,N,N,40898,N,N,35947,39108,N,38064,38065,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,65233,N,N,N,N,N,41153,N,65234,N,N,N,N,41165,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,65235,N,N,39141,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65238, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37348,N,N,N,N,36807,38062,N, +35407,38066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36820,N,N,N,N,39146, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65240,N,N,N,N,N,N,N,N,N,40416,N,N, +N,N,39150,N,N,N,N,38340,N,64744,N,N,N,N,N,39151,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,35950,N,N,N,N,N,N,N,N,64216,N,N,N,N,N,N,N,N,N,N,N,N,N,65244,N,N,N,N,N,N,N, +N,N,41134,40268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39153,N,N,N,39155,N,38081,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39157,N,N,64079,38626,N,N,N,N, +37968,N,38562,N,N,39158,N,N,N,38629,N,N,N,N,N,39159,N,41030,38627,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,39160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40676,N,N,N, +N,N,N,63958,N,N,N,N,N,N,38083,N,N,N,N,38082,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65249,N,65257,N,N,N,N,38628,N,35244,38619,N,N, +N,N,N,N,N,N,N,N,N,N,N,65250,N,N,N,N,N,N,N,N,N,N,38084,65251,N,N,N,65255,40955, +N,N,N,N,N,N,N,N,N,N,N,35929,N,N,N,N,N,N,N,N,N,37833,N,38120,64342,N,N,N,37061, +41128,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,65253,N,N,N,39165,39163,65256,N,36543,N,N,N,N,35800,65271,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36712,38086,N,N,N,N,N,N,N,N,40426,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,64617,N,N,N,N,N,N,N,N,N,N,N,N,40154,N,65267,N,N,40050, +N,N,65264,35273,N,N,N,N,N,N,N,N,N,39233,N,N,N,N,N,N,N,39234,N,N,N,65269,N, +37335,N,N,N,N,N,38092,N,N,N,65272,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,38824,N,65276,N,N,N,36062,N,64959,N,N,N,N,N,N,N,65278,N,N,N,N,N,N,N,N, +N,N,N,N,N,38609,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38101,N,N,38096,39236,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35939,N,N,41139,N,N, +N,N,N,N,N,N,N,N,N,N,38095,N,N,N,40954,N,N,N,N,37349,N,40042,N,N,N,36425,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36428,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,36429,N,N,N,N,N,39539,N,N,N,N,N,N,N,N,N,N,N,N,N,39239,N, +36017,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36432,N,N,N,N,N, +N,N,N,N,N,36431,39241,N,N,N,N,N,36433,36434,N,N,N,N,39602,35237,N,N,N,N,N, +39244,N,N,N,40952,N,N,N,N,N,N,36438,39245,37322,36439,N,N,N,N,38113,N,N,N,N, +36935,N,36824,36440,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38123,36444,38227,N, +N,N,N,N,N,N,40933,N,N,N,N,N,N,N,N,N,N,40790,N,N,N,N,N,N,N,38223,N,36446,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,39274,N,N,N,N,N,N,N,N,40036,40153,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,36445,N,N,N,N,N,N,N,N,N,N,N,N,39248,N,N,N,N,N,N,N,N,N,39249,N,N, +36450,N,N,N,N,N,N,N,N,N,N,N,39250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36456,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36449,40793,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40797,36454,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36018,N,N,N,N,N,N,N,N,N,N,N, +N,N,36462,N,40804,39251,N,N,64184,N,N,N,N,N,39252,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,36464,N,N,N,N,N,N,N,N,N,N,N,N,40801,N,36466,N,N,N,N,N,N, +N,N,N,N,N,N,41067,N,N,N,N,40768,N,N,N,N,N,N,38125,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,38126,N,N,40893,N,N,N,36475,N,N,N,N,N,N,39255,38135,N,40799,N,N,N,N,36467,N, +N,40802,N,N,N,N,N,N,N,38134,N,N,N,N,N,N,N,N,N,N,N,N,N,39256,N,N,N,N,N,N,N,N,N, +36469,63963,N,N,N,N,36978,N,38136,N,N,N,N,N,N,N,N,N,39258,N,N,N,N,N,N,N,N,N, +41136,36019,N,N,N,36473,N,36472,N,N,N,38131,N,N,N,N,N,39087,N,N,N,N,N,N,41138, +N,N,N,N,N,N,N,N,N,N,N,36474,N,N,N,N,N,N,39260,N,N,N,N,N,36476,N,36477,N,N,N, +35801,N,N,35234,40663,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,41142,N,N,N,N,N,N,N,N,N,N,N,N,40514,N,N,36516,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36519,N,35958,N,N,N,N,N,N,N,N,N,34663,N,38210,N,N,N,N,N,N,N,N,N,N,N,N,39037,N, +N,N,38741,N,N,36520,N,N,N,N,N,N,N,36522,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,35235,N,39264,39266,N,N,38140,39265,N,N,N,N,N,N,N,38138,N,N,N,N,N, +N,N,36526,36530,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36528,N,N,N,N,N,N,N,39267,38826, +38139,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36539,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,36060,N,N,N,N,N,N,N,N,N,39030,N,36513,N,N,N,N,36020,N, +36535,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40358,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40624, +N,N,N,36536,N,N,N,N,N,N,N,N,N,N,N,N,40304,N,N,N,N,35182,N,N,N,N,N,N,N,35183,N, +N,N,N,N,N,N,N,N,N,N,N,N,35184,N,N,N,N,N,N,N,N,N,N,N,N,35185,N,N,N,N,N,N,N, +35186,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35187,35188,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35189,N,N,N, +N,N,N,N,N,36540,36541,N,N,N,N,N,36542,N,40401,N,N,N,N,38141,N,N,N,35799,35802, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41186,N,N,N,N,N,N, +40937,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64936,N,N,N,35559,N,N,N, +36546,N,N,N,N,N,N,N,N,N,N,N,36548,N,N,N,N,N,N,N,N,N,N,39268,N,N,N,N,N,39269,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38222,N,N,N,N,N,N,N,N,N,39091,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36555,35807, +N,N,N,N,N,36558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36559,N,N,39272,N,N,N, +N,39273,N,N,N,N,N,N,N,N,39275,36561,N,39276,N,N,N,N,N,N,N,N,N,36564,36565,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39277,N,N,N,N,N,N,41150,N,N,N,N,N, +36566,41148,41141,N,N,41140,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35253,N,N,N, +N,N,N,N,36573,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40541,39281,N,N,N,N,35246,40424,N,N, +N,N,N,N,N,N,38245,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,39282,N,N,35676,N,N,N,N,N,N,N,N,N,35249,41152,N,N,N,36575,N,38246,N,N, +39284,N,39286,N,N,N,39287,N,39289,N,N,40410,N,N,36576,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37724,N,N,N,N,N,N,N,40422,N,35679,N,N,38243,N,N,N,N,N,N,N,N,N,N,38247,N, +N,N,N,N,40419,N,N,N,N,N,N,N,N,N,N,N,N,N,39292,N,N,39293,39294,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,36091,35675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39331,N,N,N,N,N,N,N, +39332,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39336,N,N,N,N,35518,N,N,N,N,N,N,N,N,N,N,N,40545,N,N,N,N,N,N,N,N,N,N,39338,N,N, +N,N,N,N,41160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39339,N,N, +N,N,N,N,N,N,N,N,65220,N,N,N,N,N,N,39106,36584,N,41146,N,N,N,N,N,N,N,N,N,N,N, +64887,N,N,36590,N,N,N,40639,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35266,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39340,N,N,N,N,N,N,N,N,N,N,N,N,N,38251,N,N,38252, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39343,N,N,39242,35190,36680,N,N,N,N,N,N,N,N,N, +N,N,64494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39342,N, +N,N,36603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36048,N,N,N,N,35666,N,N,N,N, +N,39344,N,N,N,N,35191,36673,N,N,N,N,N,N,N,39345,N,N,N,N,N,N,N,N,N,36681,N,N,N, +N,N,N,N,N,N,N,N,64077,N,N,N,N,N,N,N,N,40420,36021,N,N,N,64489,39764,N,39346, +40552,N,N,N,N,N,N,N,N,N,N,N,N,36682,N,36674,N,N,36689,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38982,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,39348,N,N,N,N,N,N,N,N,N,N,36597,64853,N,N,40141,N,N,N,N,N,N,N, +N,35192,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36691,N,N,N,N,N,N,N,N,N,N,N, +36719,N,N,N,N,N,N,N,N,N,N,36451,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36694,N,N,N,N,N, +N,N,N,N,N,N,N,65142,N,N,N,N,40902,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64172,N,N,N,N,N, +36696,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38984,39351,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,38501,N,64108,N,40423,N,N,N,40546,N,N,N,38604,36455,N,N, +64629,N,39038,N,N,N,N,N,N,N,64953,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38908,N,N,N,N, +N,N,N,N,N,39161,N,36710,N,N,N,N,N,N,N,N,38254,N,37445,N,N,36704,N,N,N,40657,N, +N,N,N,N,65229,N,39353,N,N,N,N,N,N,N,N,N,N,N,N,36706,38732,N,N,N,N,N,N,N,N,N,N, +N,N,37319,38239,N,N,N,N,N,N,N,39355,N,N,N,N,N,N,N,N,N,36461,36721,N,N,38091,N, +N,N,N,N,N,N,N,N,N,N,N,38321,N,N,N,N,N,N,N,N,N,39666,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,38595,39357,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41167,N, +N,N,36717,N,N,39358,36596,N,36722,38372,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39359,37442,N,64421,N,N,N,N,N,N,N,N,N,N,39360,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64948,36727,N,N,N,39361,N,N,N,N,N,N,N,N,N, +64185,N,N,N,N,N,N,N,N,36672,64068,N,N,N,N,N,39362,N,N,N,N,N,N,N,36700,N,N,N,N, +36029,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39364,39365,N,N,36731,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34678,N,N,N,36022,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36771,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36046,N,N,N,N,N,N,N,N,N,39366,N,N,N,N,N,N,N,N, +N,N,N,N,N,38605,N,N,N,N,N,N,N,N,N,N,N,N,N,38599,36773,N,N,N,N,N,N,N,N,N,N, +64187,N,35937,38256,N,N,N,37736,N,36734,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36778,N,N,N,N,N,N,41040,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37075,N,N,38230,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36792,N,N,N,N,N,39368,N,N,N,N,N,N,N,N,N,N,N,36783,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,39369,N,N,N,N,N,N,N,N,N,N,N,N,N,38265,N,N,N,N,N,N,N,N,N,N,N,N,40777, +N,N,N,N,39370,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39371,40405,36784,N,N, +N,N,N,N,N,N,N,N,N,64122,N,N,N,N,N,N,N,N,40543,N,N,N,N,39373,41161,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39643,N,N,N,41158,N,N,N,N,N,N,N,36788,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,41175,N,N,N,N,N,N,N,N,N,N,N,N,41159,N,N,N,N,N,N,N, +41027,N,N,N,36789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36786,N,N,N,N,N,N, +41057,40542,N,N,N,N,N,N,N,N,N,N,36790,N,N,N,N,N,N,N,N,40936,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,40114,N,N,N,N,N,38268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40903, +N,N,36795,36796,N,N,N,N,N,N,N,N,36844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36800,N, +37738,N,N,N,35812,40060,N,N,N,N,N,N,N,N,38305,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,65260,N,N,38307,N,N,N,N,N,N,N,35909,36024,N,N,N,N,N,N,N,N,N,N,N, +36801,N,N,N,41042,N,N,N,N,N,N,N,N,N,N,N,N,N,39376,N,N,N,N,N,36803,36804,N,N,N, +N,N,N,N,N,N,38308,N,N,N,N,N,36806,N,40544,N,N,N,N,N,N,N,63960,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,38309,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40115,N,N,N,N,N, +N,N,N,N,39377,65265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,39378,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40130,N,N,N,39379,N,N,N,N,N,38311,N,N,N,N,N,N,38313,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,38310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40029,N,N,N,N,N,N,N,N,39138,N,N, +N,N,N,N,36809,N,41154,36810,N,N,N,N,N,N,39380,N,N,41145,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,39768,N,36813,N,41172,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36814,N,N, +N,N,35813,N,N,N,N,35193,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,36816,38326,N,N,N,N,N,N,N,N,N,N,N,N,39382,N,38373,N,N,N,N,N,N,N,N,N, +N,N,N,39383,N,N,N,N,38325,N,N,N,N,N,N,N,N,N,N,N,41162,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40957,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,41048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36822,N,N,N,39384,N,N,N,N,N,N,N, +36819,N,N,N,N,N,N,N,N,N,N,N,N,36837,N,N,N,N,N,36841,N,N,N,N,39385,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36087,N,N,N,N,N,N,N,N,N,N,N,N,N,37500,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,40005,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36072,36830,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,36831,N,N,N,N,N,N,N,N,N,N,N,N,N,41035,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,36834,N,N,N,41164,N,N,N,N,N,N,N,N,36835,36836,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,39876,N,N,N,39932,N,N,N,N,N,N,38476,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,39670,N,36014,N,N,N,N,N,N,N,N,N,N,N,N,36839,N,N,N,N, +N,N,N,N,N,N,36840,N,N,N,N,35815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,35194,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,35195,39386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36845,N,N,N,38336,N,N,N,N,N,N,N,N,N,N,N,N,N,41163,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40520,N,N,N,N,N,N,39387,N,36851, +N,N,N,N,36857,N,N,N,N,N,N,N,N,N,N,N,N,N,38337,N,41038,N,N,N,N,N,N,39388,N,N,N, +N,41060,36855,N,N,N,N,N,N,N,35248,41032,N,N,N,N,36859,36854,N,N,N,N,N,40412,N, +N,N,39389,35816,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37569,N,N,N,N,N,N,N,40918,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41170,N,N,36928, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35524,N,N,39392,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,40944,40947,N,N,N,N,N,N,N,N,N,N,N,N,40383,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,40950,N,38344,N,N,40538,N,N,N,N,N,N,N,N,N,N,N,N, +39395,N,N,N,N,N,N,N,N,N,N,N,35402,N,N,N,N,N,N,N,N,40945,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,35495,N,N,N,N,N,N,N,N,39398,N,N,N,40951,N,40941,N,N, +N,N,N,N,35420,N,40366,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,38345,N,N,N,N,N,36936,N,N,39400,N,N,N,N,N,36937,N,N,36026, +N,N,37041,N,N,N,N,N,N,36938,N,N,N,N,N,N,N,N,N,N,39402,N,N,N,N,N,N,N,N,N,N,N, +39889,N,N,N,N,N,N,N,39403,N,39404,N,N,N,N,N,N,N,N,39405,N,N,N,N,39406,36940,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36941,N,N,38347,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,38882,N,N,N,N,N,N,N,N,38348,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40824,N,N, +N,N,N,N,N,N,N,35196,35197,N,N,N,N,N,N,35198,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39261,N,N,N,N,N,N,N,N,N,N,N,N,39770,N,N, +N,N,36944,N,35919,N,N,N,N,N,N,N,N,N,N,N,36948,N,50902,39592,39407,65259,40355, +40353,39235,39237,N,40317,N,N,39408,N,N,N,N,N,N,N,N,39409,N,39410,N,N,36028, +40288,N,N,N,N,N,N,N,N,N,41123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36955,40667,N,N,N,N,N,N,N,N,N,40313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39411,N,N,N,36962,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,40789,N,N,N,N,N,N,N,N,N,39929,N,N,N,N,N,N,N,N,N,N,36965,N,N, +38624,N,N,N,N,N,N,N,39102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36968,N,N,N, +N,N,36972,N,N,N,N,N,N,N,N,N,N,N,N,38360,N,N,N,N,N,N,N,N,36970,40882,N,N,N,N,N, +N,N,40878,N,N,40880,N,35245,N,N,N,N,N,N,N,N,36974,N,N,N,N,N,N,N,N,40561,N,N,N, +N,N,40522,N,N,N,N,N,40924,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35243,N,40888,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36976,N,N,N,N,N,N,N,N,N,N,N,N, +35683,N,N,N,N,38364,N,N,N,N,N,N,N,N,36977,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64606,N,N,N,N,N,N,N,N,35145,N,N,N,N,N,38491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35920,N,N,N,38054,N,N,N,36821,40563,N,N,N,N,N,36981,N,N,N,N,39415,N,N,N,N,N,N, +N,N,N,N,N,N,N,36031,N,N,N,N,N,N,39417,N,38499,38329,N,N,N,N,N,N,N,N,N,38100,N, +N,N,N,N,N,64762,N,N,N,N,36983,N,N,37035,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40269, +N,N,39418,N,N,N,N,37603,N,38843,N,N,36984,N,N,N,N,N,N,N,N,39419,N,N,38880,N,N, +N,N,N,N,N,N,38620,N,N,N,N,N,N,N,N,N,40104,N,N,38770,N,N,N,N,37952,N,N,N,N,N, +37618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39421,N,N, +39420,N,N,N,N,N,N,N,63959,38474,N,N,N,38616,39422,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36939,N,N,N,N,N,N,64065,N,N,N,N,N,N,N,39488,N,38747,N,N,N,N,N, +39489,37341,N,N,N,N,N,37884,39490,39491,N,38489,N,N,N,N,N,N,39492,36945,N,N,N, +38079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37026,N,N,N,40107,38774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64597,65093,38056,39493, +64075,40417,N,N,38617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38772,N,N, +65013,N,N,N,37605,N,38469,37338,N,37027,N,N,41055,N,N,N,N,37039,38847,N,N,N, +37196,N,N,N,N,38522,N,N,N,37342,N,N,39494,65200,38777,37996,N,N,N,N,N,N,N,N, +39000,N,N,N,N,N,N,N,N,N,N,N,37478,N,N,N,37883,N,N,N,N,N,N,N,N,N,N,N,N,39495,N, +N,N,N,N,N,N,N,N,N,38729,N,N,38728,N,37706,N,40162,N,N,N,N,N,N,37476,N,N,N,N, +37343,N,N,N,N,N,N,N,64377,N,N,N,N,N,N,N,38615,N,N,N,N,37699,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,64971,65146,N,37339,35946,38831,N,N,38365,N,N,N,37704,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,39499,N,N,N,64581,N,39501,N,N,N,N,N,N,37308,37090,37044,38369, +N,N,N,N,N,39502,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39503,N,N,N,65088,65091,N,N,N, +N,N,N,N,N,N,38621,N,N,N,N,N,N,39505,N,N,N,38567,N,N,37040,N,N,N,N,N,N,N,N,N, +40014,N,37955,N,N,N,N,36538,N,N,N,N,N,N,N,N,N,N,N,N,39506,N,64705,N,N,N,N,N,N, +N,N,N,35817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40111,N,N,35837, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39612,N,39608,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39598,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,39591,39507,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,40308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35818,N,N,N,N,N,N,35819,N,N,N,N,N,37042,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,38377,38376,N,38374,N,N,N,N,N,N,37045,N,39508,N,N,N, +37043,38375,N,N,35664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35820,N,N,N, +N,N,N,N,N,N,N,N,39510,35835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39511,N, +N,N,N,41130,N,N,N,N,N,N,N,N,40870,N,N,N,39372,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39349,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,37054,N,N,N,N,N,40879,N,N,N,N,N,N,N,N,N,N,N,N,N,38386,N,N,N,N,N,N,37055,N, +N,N,N,N,N,N,N,N,N,N,N,37057,N,65252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37060,N,N, +N,N,N,N,37063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37604,40786,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,37083,N,N,N,N,N,41062,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37074,N,N,34667,N,37076,N,N,N,N,N,N,N,N,N,39515,38397,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,35780,N,N,N,35942,N,37086,N,N,N,N,N,40164,N,37089,N,N,N,N,N,N,N,N,N,N,N, +N,N,40518,N,N,N,38481,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64344,N,37094, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38480,N,N,N,37095,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,37096,39517,N,40826,N,N,N,39772,N,40828,N,N,64594,37097,N,37098,N, +39518,N,N,N,N,N,40822,N,N,N,N,N,N,N,N,N,37099,N,N,N,N,N,N,N,N,N,N,N,N,N,37100, +N,N,N,N,N,35822,N,N,N,N,N,N,N,37102,N,N,N,37318,N,N,37106,64700,35444,N,N,N,N, +N,N,N,N,N,38487,N,N,N,40175,N,N,N,N,N,N,N,N,N,N,40927,N,N,N,N,37111,37110,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39774,N,N,N,37112,N,N,N,N,N,N,N,N,N,N,36092,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,37113,N,36041,N,N,N,64106,N,N,N,N,N,N,N,N,35823,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40928,N,N,37186,N,39522,N,N,N,N,N, +N,N,N,N,38249,N,N,N,37188,37187,N,37185,N,N,N,35824,N,N,N,N,N,N,N,N,N,N,N,N,N, +38496,N,35825,N,39414,37193,N,N,N,N,37194,N,N,N,N,N,37195,N,N,N,N,39524,N,N,N, +35519,39526,N,N,N,N,N,N,N,N,N,N,39527,N,N,39529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,39530,38482,37197,N,38502,N,N,N,N,40827,N,39531,N,N,N,N, +N,N,N,41068,N,N,38503,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39532,N,N,N,N,39533,35826, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38506,N,N,N,N,N,N,N,N,64746,N,N,N,N,N,38508,N, +N,N,N,N,N,N,N,N,N,N,N,N,37316,N,N,N,38519,N,N,N,N,N,N,N,39412,39535,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40875,N,N,N,N,N,36030,36545,N,N,N,N,38229,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,37202,37203,N,N,N,37205,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38237,N,38513,N,N,N,N,40045,N,N,N,N,N,N,N,N,38515,N,N,N,N,N,N,N,N,N,N,N,37204, +39537,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37206,N,N,N,38509, +N,N,N,N,N,N,38231,N,N,N,N,N,N,N,N,35270,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,35434,N,N,N,35671,N,N,N,40929,N,N,39775,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41053,N,N,N,N,N,N,N,N,37211,N,37212,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37214,N,N,N,N,N,N,N,N,N,N,40796,40791,N,N,N,N,N, +N,40805,N,N,N,N,N,39538,N,N,N,N,37216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,40798,N,N,37217,N,N,N,N,N,N,37220,N,N,N,N,40769,N,N,N,N,N,N,37225,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,37224,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38578,N,39541,N,64933,N,N,N,N, +N,N,N,40681,N,35770,37229,41056,N,N,N,N,N,N,N,40926,N,N,N,N,N,40899,N,38581,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,38579,N,N,N,N,N,N,N,N,N,N,N,N,N,39542,N,N,N,N,N,N,N,N,N,N,N, +38357,N,N,N,40650,N,N,N,39543,N,N,39544,N,N,N,N,N,N,N,N,N,N,37232,37231,N,N,N, +N,N,N,N,40867,N,37233,N,N,N,38577,N,N,N,N,40803,N,N,N,N,N,40807,N,N,N,35769, +39546,N,N,N,N,N,35670,N,N,N,N,N,N,N,N,39642,N,N,N,N,N,38576,N,N,N,N,39550,N,N, +N,N,N,N,N,N,N,N,40414,N,N,N,N,N,N,N,N,N,38573,N,N,N,38574,N,N,N,N,N,N,N,N,N, +40609,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40528,N,N,N,N,N,N,N,N,38575, +35828,40868,N,N,N,N,N,N,N,N,N,38589,N,N,N,N,N,N,N,N,N,38644,N,N,N,N,N,N,N,N,N, +N,38584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64161,N,N,N,N,37287,N,N,N,N,N,N,N, +N,N,N,41054,N,N,N,N,39549,N,N,N,N,35144,N,40625,N,N,N,N,N,N,N,N,N,N,N,N,N, +40411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38335,35443,N,N,N,N,N,N,N,N,N,N,N,N,N,40702, +N,37242,N,N,N,N,37243,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39587,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,38594,N,N,N,N,N,40823,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39588,N, +N,39589,N,N,N,37281,N,N,N,N,35256,N,N,N,N,N,N,N,N,N,N,37235,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39590,35261,N, +35257,N,37245,N,N,N,N,N,N,N,N,N,38587,N,N,N,40946,N,N,35829,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,39593,N,N,N,N,N,40788,N,N,40931,40685,N,N,N,N,N,N,N,N,N,N,37290,N,N,N, +N,37291,41072,N,40813,N,N,N,N,N,37292,N,N,N,37293,N,N,N,41213,N,40930,N,37295, +40513,39594,N,N,37296,N,39595,N,N,N,N,N,N,N,N,N,N,N,39596,N,39498,N,37298,N,N, +35830,N,39597,35254,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39599, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,39600,N,N,N,N,N,N,39601,N,N,N,N,N,39585,37305,N,N, +N,N,N,37306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37310,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +41025,35767,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37312,N,N,N,N,N,N,N,N,N,N,39603, +37315,N,N,N,N,N,N,N,N,N,N,41212,N,N,40942,N,N,N,N,N,N,40809,N,N,N,N,N,N,N, +37320,N,N,N,N,N,N,37321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36326,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,37323,N,N,N,N,N,N,N,N,N,N,35272,N,N,N,N,N,36266,N,N,N,N, +N,40925,35907,35949,35956,36023,36025,36027,36032,36055,36056,36058,51361, +51363,36077,36168,35832,51408,N,N,N,N,51407,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50916,N, +50917,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,51405,N,51406,N,N,N,N,N,N,N,N,63998, +}; + +static const struct unim_index big5hkscs_bmp_encmap[256] = { +{__big5hkscs_bmp_encmap+0,168,252},{__big5hkscs_bmp_encmap+85,0,220},{ +__big5hkscs_bmp_encmap+306,80,198},{0,0,0},{__big5hkscs_bmp_encmap+425,1,81},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+506,190, +193},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+510,22,231},{0,0,0},{ +__big5hkscs_bmp_encmap+720,218,219},{__big5hkscs_bmp_encmap+722,96,125},{ +__big5hkscs_bmp_encmap+752,80,112},{0,0,0},{__big5hkscs_bmp_encmap+785,61,61}, +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5hkscs_bmp_encmap+786, +128,227},{__big5hkscs_bmp_encmap+886,51,51},{__big5hkscs_bmp_encmap+887,5,254 +},{__big5hkscs_bmp_encmap+1137,192,207},{__big5hkscs_bmp_encmap+1153,49,49},{ +0,0,0},{__big5hkscs_bmp_encmap+1154,53,251},{__big5hkscs_bmp_encmap+1353,6,254 +},{__big5hkscs_bmp_encmap+1602,9,245},{__big5hkscs_bmp_encmap+1839,1,251},{ +__big5hkscs_bmp_encmap+2090,15,250},{__big5hkscs_bmp_encmap+2326,8,254},{ +__big5hkscs_bmp_encmap+2573,1,251},{__big5hkscs_bmp_encmap+2824,14,244},{ +__big5hkscs_bmp_encmap+3055,13,239},{__big5hkscs_bmp_encmap+3282,18,253},{ +__big5hkscs_bmp_encmap+3518,6,255},{__big5hkscs_bmp_encmap+3768,0,250},{ +__big5hkscs_bmp_encmap+4019,4,250},{__big5hkscs_bmp_encmap+4266,2,249},{ +__big5hkscs_bmp_encmap+4514,17,252},{__big5hkscs_bmp_encmap+4750,43,242},{ +__big5hkscs_bmp_encmap+4950,1,244},{__big5hkscs_bmp_encmap+5194,3,234},{ +__big5hkscs_bmp_encmap+5426,3,247},{__big5hkscs_bmp_encmap+5671,19,244},{ +__big5hkscs_bmp_encmap+5897,0,250},{__big5hkscs_bmp_encmap+6148,6,231},{ +__big5hkscs_bmp_encmap+6374,15,255},{__big5hkscs_bmp_encmap+6615,16,192},{ +__big5hkscs_bmp_encmap+6792,4,237},{__big5hkscs_bmp_encmap+7026,7,156},{ +__big5hkscs_bmp_encmap+7176,4,248},{__big5hkscs_bmp_encmap+7421,3,253},{ +__big5hkscs_bmp_encmap+7672,3,252},{__big5hkscs_bmp_encmap+7922,1,254},{ +__big5hkscs_bmp_encmap+8176,2,249},{__big5hkscs_bmp_encmap+8424,1,254},{ +__big5hkscs_bmp_encmap+8678,19,239},{__big5hkscs_bmp_encmap+8899,2,251},{ +__big5hkscs_bmp_encmap+9149,5,253},{__big5hkscs_bmp_encmap+9398,0,254},{ +__big5hkscs_bmp_encmap+9653,3,251},{__big5hkscs_bmp_encmap+9902,2,249},{ +__big5hkscs_bmp_encmap+10150,2,254},{__big5hkscs_bmp_encmap+10403,13,255},{ +__big5hkscs_bmp_encmap+10646,5,252},{__big5hkscs_bmp_encmap+10894,16,245},{ +__big5hkscs_bmp_encmap+11124,9,252},{__big5hkscs_bmp_encmap+11368,12,223},{ +__big5hkscs_bmp_encmap+11580,35,253},{__big5hkscs_bmp_encmap+11799,7,226},{ +__big5hkscs_bmp_encmap+12019,44,229},{__big5hkscs_bmp_encmap+12205,24,254},{ +__big5hkscs_bmp_encmap+12436,7,234},{__big5hkscs_bmp_encmap+12664,10,255},{ +__big5hkscs_bmp_encmap+12910,24,241},{__big5hkscs_bmp_encmap+13128,2,254},{ +__big5hkscs_bmp_encmap+13381,0,202},{__big5hkscs_bmp_encmap+13584,0,250},{ +__big5hkscs_bmp_encmap+13835,3,246},{__big5hkscs_bmp_encmap+14079,5,250},{ +__big5hkscs_bmp_encmap+14325,28,255},{__big5hkscs_bmp_encmap+14553,2,254},{ +__big5hkscs_bmp_encmap+14806,2,250},{__big5hkscs_bmp_encmap+15055,4,248},{ +__big5hkscs_bmp_encmap+15300,3,254},{__big5hkscs_bmp_encmap+15552,5,246},{ +__big5hkscs_bmp_encmap+15794,0,226},{__big5hkscs_bmp_encmap+16021,2,251},{ +__big5hkscs_bmp_encmap+16271,2,248},{__big5hkscs_bmp_encmap+16518,5,220},{ +__big5hkscs_bmp_encmap+16734,2,217},{__big5hkscs_bmp_encmap+16950,12,254},{ +__big5hkscs_bmp_encmap+17193,8,245},{__big5hkscs_bmp_encmap+17431,6,244},{ +__big5hkscs_bmp_encmap+17670,6,254},{__big5hkscs_bmp_encmap+17919,11,252},{ +__big5hkscs_bmp_encmap+18161,18,252},{__big5hkscs_bmp_encmap+18396,37,254},{ +__big5hkscs_bmp_encmap+18614,7,223},{__big5hkscs_bmp_encmap+18831,6,250},{ +__big5hkscs_bmp_encmap+19076,2,246},{__big5hkscs_bmp_encmap+19321,3,246},{ +__big5hkscs_bmp_encmap+19565,24,255},{__big5hkscs_bmp_encmap+19797,11,237},{ +__big5hkscs_bmp_encmap+20024,5,248},{__big5hkscs_bmp_encmap+20268,3,252},{ +__big5hkscs_bmp_encmap+20518,2,239},{__big5hkscs_bmp_encmap+20756,112,245},{ +__big5hkscs_bmp_encmap+20890,4,255},{__big5hkscs_bmp_encmap+21142,0,231},{ +__big5hkscs_bmp_encmap+21374,28,249},{__big5hkscs_bmp_encmap+21596,12,226},{ +__big5hkscs_bmp_encmap+21811,81,247},{__big5hkscs_bmp_encmap+21978,3,212},{ +__big5hkscs_bmp_encmap+22188,1,242},{__big5hkscs_bmp_encmap+22430,25,249},{ +__big5hkscs_bmp_encmap+22655,8,196},{__big5hkscs_bmp_encmap+22844,81,254},{ +__big5hkscs_bmp_encmap+23018,8,253},{__big5hkscs_bmp_encmap+23264,3,244},{ +__big5hkscs_bmp_encmap+23506,1,246},{__big5hkscs_bmp_encmap+23752,45,244},{ +__big5hkscs_bmp_encmap+23952,29,244},{__big5hkscs_bmp_encmap+24168,3,245},{ +__big5hkscs_bmp_encmap+24411,20,245},{__big5hkscs_bmp_encmap+24637,14,245},{ +__big5hkscs_bmp_encmap+24869,12,255},{__big5hkscs_bmp_encmap+25113,2,255},{ +__big5hkscs_bmp_encmap+25367,2,124},{__big5hkscs_bmp_encmap+25490,2,252},{ +__big5hkscs_bmp_encmap+25741,10,254},{__big5hkscs_bmp_encmap+25986,2,179},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{__big5hkscs_bmp_encmap+26164,7,7},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{__big5hkscs_bmp_encmap+26165,2,237}, +}; + +static const DBCHAR __big5hkscs_nonbmp_encmap[29306] = { +40049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37749,N,N,N,N,N, +N,N,37750,N,N,N,N,N,N,N,38216,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,36550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35781,35834, +N,N,51324,N,N,N,N,N,N,N,N,N,39604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34894,34891, +51322,34888,N,N,N,34887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,41206,34885,N,34899,N,N,N,N,N,N,N,N,N,64685,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36085,N,N,N,N,35501,N,37490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,64583,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38111,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40913,64459,N,N,N,N,N,N,N,37501,N,N,N,N,N,N,N, +39076,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38119, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37067,37499,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38104,N,N,N,N,64607,N, +64084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39605,N,N,N,N,N,N,N,38618, +37497,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64116,37493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36347,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35401,N,N,N,37599,39804,64099,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,64096,37485,64098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39606,N,N,N,N,N,N,38763,N,N,N,N,N,N,N,N,N,N,N,N, +N,64874,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64852,N,37491,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38872,N,N,N,N, +N,N,40891,37698,37494,N,N,N,N,N,N,N,N,N,N,64101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37484,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,64110,N,N,N,N,N,N,40672,N,N,37568,37567,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,37566,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39610,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35507,N,38773,64064,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64118,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,64464,N,N,N,N,N,N,N,N,N,N,N,N,N,64123,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,65133,N,N,N,N,N,N,39859,N,N,N,N,N,35276,N,N,N,N,39614,N,N,N,N,N, +N,N,N,N,64066,37564,N,N,N,N,N,N,N,N,N,N,37980,39861,N,N,N,39615,N,N,N,39079, +38820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37117,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64635,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39616,37571,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39888,38224,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37574,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39078,38214,N,N,N,N,N,N,N,N,N,N,N,N,64867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64194,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40643,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35250,40038,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36947,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,35938,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,38849,N,N,N,N,N,N,N,N,N,N,N,N,N,39620,N,N,N,N,N,N,N,N,N,N,39621,36591,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,64233,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36160,N,N,N,N,N,N,N,N, +37474,35575,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39622,N,N,N,N,N,N,37601, +N,N,N,N,39625,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64198,N,N,N,N,N,N,N, +N,38821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39627,N,N,N,64114,35422,N,38112,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,37580,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35557, +N,N,N,N,N,65116,39628,N,N,N,N,N,40441,35395,35494,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,39629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,64238,39884,N,N,N,39631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39633,N,N,N,N,N,N, +N,N,40442,N,N,N,N,N,40316,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39635,N,N,38822,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39263,N,N,N,64502, +40901,35417,35691,N,N,N,N,N,N,39636,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39637,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,38818,35396,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40778,N,N,N,N,N,N,N,N,37025,64932,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35428, +35570,35576,40408,N,N,38102,64254,64423,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,39638,N,40781,N,N,64246,N,N,N,N,N,N,N,35415,N,35651, +35652,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35510,N,N,N,N,N,35520,N,N,N, +N,N,N,N,N,N,N,40532,N,N,N,N,N,N,N,N,N,N,39639,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,39640,39644,N,N,N,N,35530,40616,N,N,37475,39645,35685,35695,35710,N, +N,N,N,36675,N,N,N,N,N,N,37584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35572,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40382,N,N,N,N,N,39649,N,64734,40445,35686, +35696,35701,35556,35748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35565,N,N,N,N,N,N,N,N, +N,35421,N,35656,N,N,N,N,40429,N,N,N,N,40512,N,N,N,N,N,N,N,35567,35574,40566,N, +N,N,N,N,N,N,N,N,40675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,39646,36350,N,N,N,N,64252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,40113,40567,35684,35687,38731,N,N,N,N,N,N,N,N,38483,N,N,N,N,N,N,39648, +35658,N,35569,35543,N,N,N,N,N,N,N,N,N,41131,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35509,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35423,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35566,N,N,39647,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35582,N,N,N,N,N,N,35416, +35747,35751,N,N,N,N,N,39651,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,37473,N,N,N,N,N,N,N,N,N,N,40407,40573,40615,40619,36930,N,N, +N,N,N,N,N,N,35705,35706,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39654,N,N,N,N,N,N,N,N,N,N,N,N,39653, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35454,N,N,N,N,N,40516,39655,35452,35697,N, +N,39657,N,N,N,N,N,N,N,N,N,N,N,N,39658,N,N,N,N,N,N,N,N,N,N,N,N,N,39659,N,N,N,N, +N,N,35517,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64334,N,N,N,N,N,N,N,N,N, +N,39661,35577,40547,N,N,N,N,N,35657,35534,35694,N,N,N,N,N,35560,N,N,N,39662,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37582,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35418,35707, +35708,39663,N,N,N,N,N,N,N,N,N,N,N,39664,N,35578,N,N,N,N,N,N,N,35137,N,N,35698, +N,N,N,N,N,N,35571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35752,N,N,N,N,N,N,40622,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40562,64371, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64351,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37050,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37374,40694, +N,N,N,N,N,N,38893,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39667,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,41198,38524,37701,39022,64086,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39669,N,N, +N,64587,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39668,65246,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,64695,N,N,N,N,N,N,N,N,N,38897,N,N,N,38855,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40139, +37440,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,40168,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37373,38734,N,N,64360,N,N,N,N,N,N,N, +N,N,N,N,N,N,38764,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36034,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38888,N,64362,35700,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,36583,N,N,N,N,N,N,N,N,N,N,N,N,64968,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,37441,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38561,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,36595,39671,N,N,N,N,N,N,N,N,N,N,36774,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,64214,40135,N,N,N,N,N,N,N,N,64215,N,N,N,N,N,39672,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64417,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36549,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64420,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,64450,N,39617,N,N,N,N,N,37370,65243,38827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37191,N,64433,N,N,N,N,N,N,N,N,N,36842,N,N,N,N,N,N,38098,65121,64206,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,37613,37363,37830,N,37722,64251,N,N,37615,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38983,37734,38997,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38630,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40771,40874,38106,37614,64687,64507,N, +36601,37366,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37732,N,N,N,N,38133,40118,64429, +38990,36676,38653,N,N,N,N,N,N,N,N,N,N,N,N,N,39673,N,N,N,39674,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,38761,38356,38987,64426,N,N,39036,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,37354,N,N,N,N,N,40367,40389,N,37361,36529,38825,64428,64696,40121,N,N,N,N, +N,N,N,64432,64722,37835,N,N,39677,N,N,N,N,N,N,N,N,N,N,N,37364,35756,41045,N,N, +N,N,38260,N,N,N,N,38334,N,N,N,N,N,N,N,N,N,N,N,N,38829,N,N,N,N,N,N,N,N,N,N,N, +36585,N,N,37624,38846,37228,38058,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64611,N, +N,N,40390,N,N,N,N,N,N,N,38837,37560,37359,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,65190,38752,37720,38262,36780,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,37356,38836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37367,N,N,N,N, +38730,64329,38264,37820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,37334,37717,37718,38993,N,N,N,N,N,N,N,N,N,N,36856,64448,37874,N,N, +37072,N,N,N,N,N,N,40004,N,N,N,N,N,37461,N,N,N,N,37731,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,37285,N,N,N,N,N,N,N,N,41197,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,64875,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,37713,N,N,N,35927,N,N,64120,N,N,N,N,65192,N,N,N,N,N,N,N,N,N,N,N,N,N,37712, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64076,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37623,39744,N,N,N,N,N,N,64462,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,39745,N,N,N,N,N,65197,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,34657,64469,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35778,39548,39746,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39747,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40569,N,N,64473,N,N, +N,N,N,N,39748,41127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34670,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,39923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,35961,N,N,N,37726,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35275,N,N,N,N, +N,N,40787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37847,N,N,N,N,N,N, +N,N,N,N,N,N,N,64481,65232,N,N,N,N,N,N,36081,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,64482,N,N,N,N,N,64739,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,36980,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64486,N,N,N,39863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,39749,N,N,N,N,N,N,N,N,N,N,N,N,39751,40784,N,N,N,N,N,39752,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64603, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,39081,N,N,40189,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,34892,39755,N,N,N,64492,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35945,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39848,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35541,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64115,64857,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37282,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64493,N,N,N,N,N,N,40105,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35496,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36162,N,39875,35553,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39758,38352,N, +N,N,36959,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64590,N,N,N,N,N,N,39759,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39760,40646,N,N,N,N,N, +N,N,N,N,N,N,64592,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64883,N,N, +N,N,N,64935,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40354, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64088,64094,N,N,N,N,N,N,N,41049,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64446,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37744, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,37745,37751,65263,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37741,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64605,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,37048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35580,N, +64321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40555,38115,36578,35965,N,36567,N,N,N,N,N,N, +40013,N,N,N,38563,N,N,N,N,N,N,N,N,N,N,39761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35523,N,N,N,N,N,N,N,N,N,N,N,38570,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,64616,35693,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64871,35561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64673,37740,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,39762,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65136,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,64680,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64745,40116,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,35562,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39763,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39765,N,N,N,38571,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,64679,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39766,35516,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35531,N,N,N,N,N,39767,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,35277,N,39769,39771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37797,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39773,N,N, +N,40527,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37795,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35451,N,N,N,35650,38736,36787,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35408,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39776,N,N,N,N,35653,N,N,N,35654,N,N,N,N,N,N,N,N,N,N,N,N,40446,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39778,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,37755,N,N,N,N,N,37809,N,N,N,N,N,N,N,35424,N,N,N,N,N,N,N, +N,35544,N,N,N,N,39779,N,N,N,N,N,N,N,N,N,N,35433,N,N,N,35399,N,N,35532,37756, +39781,N,N,N,N,N,N,N,N,N,39782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35442,N,N,N,N,N,N,N,35450,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37807,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35504,N,N,N,N,N,N,N,39784, +N,N,N,N,N,N,N,N,N,N,40611,N,N,64236,35703,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39783,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35673,64689,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64699,N,N,N,N,N,N,N,N,N,N,N, +39785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37800,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35552,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,40529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36703,39786,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,39787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38892,39788,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,65102,N,N,N,N,N,N,64962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,39789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37223, +64716,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37092,N,N,N,N,37093,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40690,37834,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,35772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36678,N,N, +N,N,37839,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64731,64732,N,N,N,N,N,N,N,N,N,N,N,N,N,37824,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,64742,38631,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64728,64729,64934,37838,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,38385,N,N,N,N,N,N,N,N,N,40169,N,64740,38063,64119,37836,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36065,N,N,N,N,N, +N,N,N,N,N,N,36954,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35924,N,N,N,N,N,N,N,37823,64337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,37817,65239,37815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37849,N,N,N,N,N,N,N,N,N,N,N,N,N,37819,37850, +39075,N,N,N,N,N,N,N,N,N,37073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39790,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64112,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39915,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39791,N,N,N,N,N,N,N,64764,N,N,N,N,N,N,N,N,N,N,N,N,N,35648,41083,N,N,N,36001, +38903,N,N,N,37858,64726,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38233,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,64832,N,N,37727,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,38898,40054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,36600,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36075,N,N,N,N,N,N,N,N,36679,N,N,N,N,N,N,N,N,N,N,N,N,39796,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37556,N, +N,N,37357,N,N,38610,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64838,36687,38217,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39797,64092,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,34641,N,N,39801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64843,N,N,N,38611,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,64856,N,N,N,N,N,37983,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,41205,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,37443,N,N,N,N,N,N,38906,N,N,N,N,N,N,N,N,N,N,N,N, +40409,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38900,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37453,64859,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,39802,N,N,N,N,N,N,N,N,N,40661,N,N,N,N,N,N,N,N,N,N,N,N,64174,N,40137,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,37464,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,36552,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,38068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37857,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37855,N,N,N,N,N,64752, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37868,38902,38607,37854,35535,39842,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,64873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37714,N,N,N,N,N,N, +N,N,N,N,N,39074,36071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64878, +36004,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64124,37882,36988,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,36711,N,40375,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41193, +64078,64929,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40564,40895,40651,39865,40404,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38841,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38267, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40658,38739,38564,36798,38105,36952,64889,64891,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36570,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36602,34658,N,N,N,N,N,N,N,N,N,N,39845,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,40665,38868,37051,64956,64966,37448,N,N,N,N,N,N,N, +37557,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,40385,37561,37542,36683,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39846,N,N,N,N,N,37558,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36416,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,40664,37982,39007,38094,37450,64880,37991,N,N,N,N,N,N,N, +N,N,N,N,36332,N,N,N,N,N,N,N,N,39896,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,34659,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37960,64193, +40183,64958,N,N,N,N,N,N,N,N,N,N,N,N,36826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64985,N,N,64638,N,N,N,N,N,N,N,N,37881,N,N, +N,N,64067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,64235,64195,38867,38393,40008,64984,41176,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64983,64330,39855,37963,64969, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36524,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64946,N,N, +N,N,N,37466,64701,37593,N,N,N,64981,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37597,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37465,N,N,N,N,N,N,N,N,N,N,36080, +38586,N,N,N,N,N,N,N,N,N,N,37467,N,N,N,N,N,N,N,N,N,39851,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64986,64990,N,N,N,64979,N, +N,N,N,N,N,N,N,N,35910,N,N,N,N,N,N,64982,64988,64989,N,N,N,N,37118,N,N,65185,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35757,N,N,40152,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40557,64892, +64353,N,N,N,N,N,N,38648,N,N,N,N,N,N,N,N,38640,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64756,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65120,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38994,38479,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37230,N,N,N, +N,N,N,N,N,N,N,39021,N,N,39012,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,37971,65004,64376,N,N,N,N,N,N,N,N,N,N,N,38330,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,39005,N,37625,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39002,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,34640,N,65014,N,N,N,N,N,N,N,37840,39010,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39853,N,N,N,N,N,N,N, +N,N,N,N,38735,39854,N,N,N,N,N,N,N,N,N,N,N,N,37970,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,39856,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37330,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38890,64363,37297,65011,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37579,N,N,N, +N,N,N,N,N,N,39857,N,N,N,N,N,64748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,39019,N,N,N,38737,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39025,38383,N,N,N,N,N,N,N,40691,N,N,N,N, +N,37352,39866,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64332,37482,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65016,39009,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,37351,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37869,38724,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,37345,N,N,64501,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39017,N,N,N,N, +35426,N,N,39867,36008,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,36471,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35506,40636,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37862,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37794,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37757,40550,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37977,N,N,N,N,N,N,N,N,N,39871,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,37976,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40613,39879,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,65108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,35798,N,N,N,N,N,N,38070,64884,39104,38053,N,N,N,N,N,N,N, +39880,N,N,N,38381,64894,64491,N,N,N,N,N,N,N,N,N,N,64893,N,N,N,N,N,N,N,N,N, +38767,37985,N,40897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38359,N,N,N, +64082,40024,N,N,N,N,N,N,N,N,N,40808,39911,64718,38632,64073,38817,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38221,40696,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,65097,37326,38769,N,N,N,N,36047,N,N,N,64945,N,N,64622,N,N,N,N,N, +40178,37816,36931,38745,38103,65126,38013,64623,N,N,N,N,37446,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64109,N,N,36599,N,64439,N,38012,37581,38834,N,N,N,N,N,N,N,N,N, +65125,38526,38744,39799,37327,N,N,N,N,N,N,N,N,N,38052,N,N,N,N,N,N,N,N,N,N, +40109,N,N,N,N,N,N,N,N,N,35755,N,N,N,38613,64691,N,N,N,37806,N,38765,N,N,N,N,N, +N,37958,38391,N,N,N,N,N,N,N,N,40006,38235,37329,38132,N,65127,37541,N,N,N, +65247,36011,N,39881,N,N,N,N,N,N,N,N,N,N,N,64749,65018,64712,65122,37372,65131, +65017,64711,37198,40120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38759,N,N,N, +38382,N,N,39858,N,N,N,N,37984,N,N,N,38050,39029,38828,37331,N,N,N,N,N,N,N,N,N, +N,N,39035,N,N,N,N,N,N,N,36587,38762,38494,N,N,N,N,N,N,N,N,N,38891,N,N,N,N,N, +40953,38392,65186,36838,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65150,N,N,N,N,N,N, +40356,38760,36588,38077,N,N,N,N,N,N,N,N,N,N,N,N,N,37979,40182,64167,39897,N,N, +N,N,N,N,N,N,N,64093,38486,38754,N,N,N,N,N,N,38074,41039,37592,N,N,N,39883,N,N, +N,N,N,N,38075,N,N,40287,N,N,N,N,N,N,37071,N,N,N,N,N,N,N,N,N,N,N,N,N,37989,N,N, +40780,N,N,N,N,N,N,37080,36187,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40638,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,64365,38346,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,40386,38904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36860,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38003, +38004,N,N,N,N,N,N,N,N,N,N,N,N,65207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35403,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35413,35689,35548,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35702,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39886,N,35432,41208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,39135,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,65205,N,N,N,39887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38651,N, +N,39931,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40654,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36581,N, +N,N,N,N,N,N,N,N,40571,39890,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,35493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,65230,35397,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,40444,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65231,35749,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35914,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,35564,N,N,64736,38061,65237,38060,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64602,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39894, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,35439,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35753,36447,N,N,40395,N, +64743,39895,N,N,N,N,N,N,N,N,N,N,N,37832,N,N,N,N,N,N,N,N,N,37360,36832,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39899,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37101,N,39900,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36179,41196,N,N,N, +39162,N,N,N,N,N,N,N,N,N,39904,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37831,37449,38625,39906,N,N,N,39908,N,N,36833,39909,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38080,N,N,37827,N,N,N,N,N,N,N,N,N,N,37829,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36985,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38779,N,N,N,N,N, +36990,N,N,N,N,65254,65094,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,37488,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38312,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36016,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,38088,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39097,37184,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64702,N,N,N,N,N,N,N,37207,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35762,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64223,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,39910,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38467,36420,40015,65268, +N,N,N,N,N,39912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37852,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38511,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36426,39917,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37622,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40377,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,36430,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,64463,34656,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40642, +N,N,N,N,N,N,38117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39920,38116,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,38225,35771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39921,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,38128,36452,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38122,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36705,N,N,N,39780,36443,N,N,N,N, +39922,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40894,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40393,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36460,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36723,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,36015,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,36725,36465,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36448,36458,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,35916,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38226,38228, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40379,38211,37630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,38130,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38129,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41194,40402,41137,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37368, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37986,39844, +36525,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40621,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38608,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65262,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,35508,N,N,N,N,N,N,N,N,N,N,N,N,38743,35447,39927,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36533,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41069, +36534,38742,38208,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,41203,38078,N,N,N,39930,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64991,40380,N,N,N,N,N,N,N, +N,38142,N,N,N,N,N,N,N,N,35803,41214,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,36544,40775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35806,41211,N,N,N,N, +36547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38473,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,65218,N,N,38220,39933,N,N,N,N,N,N,N,N,N,N,N,N,N,37068, +40032,38219,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39934,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40048,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,40003,N,N,N,40007,36556,N,N,N,36436,N,N,N,N,N,N,N,N,N,N,36580, +40009,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38238,N,N,N,N,N,N,N, +N,N,N,N,N,38236,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40011,35809,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,36569,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40372,N, +37471,N,N,N,40012,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,35489,N,N,N,N,N,N,N,N,N,N,N,N,N,36571,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,40022,35490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,38740,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40030,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40660,38248,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,41155,35558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,41207,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40033,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64589,N,40539,N,N,N,N,N,N,N,N,40553,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40035,65223,N,N,65222,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40039,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,40041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,37221,N,N,N,N,N,N,N,N,N,N,N,N,40167,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,35412,N,N,N,N,N,N,N,40044,40046,65117,N,N,N,N,N,40051,N, +N,N,N,N,N,N,N,N,N,N,N,N,38250,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38253,36592,36685,N, +N,N,N,36598,N,N,N,N,N,N,N,N,64188,N,36053,N,N,N,N,N,N,N,N,N,N,N,N,N,34654,N,N, +N,N,64474,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,35660,64885,39901,64245,N,N,N,N,N,N,N,40052,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,38213,N,N,N,N,N,N,N,N,N,N,N,N,38598,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,36714,36686,N,N,N,N,N,40056,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64085,N,N,N,N,N,N,N,N,N,N,N,N,38884,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,40001,37468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38650,36086,N,N,N,N,36173,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64358,36453,38985, +64424,38978,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40058,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38907,37066,N,N,N,N,40027,N,N,38733, +N,N,36563,N,N,N,N,N,N,N,N,N,N,N,N,N,38241,40779,40885,37842,64938,38976,37190, +39015,64090,64425,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,38977,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,36051,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,64765,64939,37309,36684,38601,36693,64430,38255,N,N, +N,N,N,N,40061,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,41200,N,N,N,N,N,N,N,N,N,N,N,N,N,37999,64940,N,N,N,N, +38603,38606,N,N,N,N,41046,N,40161,N,N,N,N,N,N,N,N,N,N,38596,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +36702,36716,36515,64435,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,64595,N,N,N,64947,N,N,N,N,36715,N,N,N,N,N,N,N,N,N,N, +N,N,38602,N,N,N,N,N,N,34643,N,N,N,N,N,N,N,N,N,N,N,N,N,36729,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,40559,41157,64632,36418,36698,37058,36517,36961,37455,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37747,64949,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,65228,N,64445,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36054, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38979,38597, +35260,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40099,N,N,N,N,N,N,37451,38986, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,36772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,41201,40699,40146,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,36775,N,N,N,N,34644,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64604,38981,N,N,36934,36049,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65274,38240,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,40776,37447,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37115,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,40100,38257,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,34629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40102,N,N,N,N, +40103,N,N,N,N,N,40106,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,40659,N,N,N,40560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40108,34642,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36782,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,36176,38269,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40112,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38838,N,41149,35551,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,36797,N,N,N,36799,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37737, +39847,51364,N,N,N,N,65258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,39905,N,N,N,N,N,N,35649,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,40374,41195,39843,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,35745,36808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,35148,39008,N,N,N,N,N,N,N,N,N,N,38087,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,35672,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38315,38314,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,40131,40132,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,40364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35814,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35441,36817,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,39381,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37108,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35491,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40142,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40148,40149,N,N,N,64456,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40371,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64624,N,N,N,N,N,36823,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39795,N,N,N,N,N,N,N,N,N,N,64091,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36818,36964,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39094, +38504,N,N,N,N,40150,N,N,N,N,N,N,N,N,N,N,N,N,39101,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36828,65270,36825,N,N,N,N,N,N,N,N,N,N,N,N,N, +38209,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,34668,N,N,N,N,38899,39928,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +34650,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34632,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34634,40556,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36850,36846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,40151,N,N,N,N,N,N,N,N,N,N,N,N,40558,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35392,N, +N,N,N,N,N,N,N,N,N,36847,N,N,N,N,N,N,N,N,36852,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,38338,39018,N,38863,40677,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40572, +36929,N,N,N,N,N,N,40155,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37953,N,N,N,N, +40166,40368,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,40170,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40173,N,N,N,N,N,N,N,N,N,N,N,N, +40186,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,35682,35406,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40138,35430,N,N,N,N,N,N,N,N,N,N,40187,40188,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40190,N,N,N,N,N, +N,N,N,N,N,N,N,N,35411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40165,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40256,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40257,N,N,N,N,N,N,N,N,N,N,N,N,36933,35699, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38858,N,40258,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,35425,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,35758,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35538,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,35746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40434, +40259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40159,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,40260,N,N,N,N,N,N,N,N,N,N,36554,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36942,N,N,N,N,N,N,N,36531,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,40949,N,N,N,N,N,N,N,N,N,N,N,N,40261,36943,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,40263,N,N,N,35274,N,N,N,N,N,N,40117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64510, +36958,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36963,36951,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36966,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,39872,N,N,N,N,N,N,N,N,N,N,N,64741,37218,N,N,N,N,N,N,N,N,N,N,36967,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36769,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,36770,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,40264,64211,N,N,N,N,N,N,36175,N,N,N,N,N,N,N,N,N,36957,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37049,N,N,N,N,N,N,N,N,N,N,N,N,N,36971, +35932,N,N,N,36969,65111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,65109,36979,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +39919,40176,N,N,N,N,N,N,N,N,N,N,N,N,40267,N,N,N,N,N,N,N,N,N,N,N,N,N,65241,N,N, +N,65242,N,N,N,37344,36163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37336,N,N,N,N,N,N,N, +N,N,N,38470,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37728, +N,64083,40147,N,N,N,N,N,N,N,N,N,N,N,N,40270,N,N,N,64320,N,N,N,36322,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37954,N,36950,N,N,39013,N,35948, +64074,N,N,40272,40274,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38319,38746,37705,38727, +41204,N,N,N,N,N,N,38776,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36815,N,N,N,64608,N,N,N,N, +N,N,N,N,35918,N,N,N,64598,N,N,N,N,N,N,N,N,N,N,N,N,N,37340,38497,37612,37725, +36574,38654,64847,38366,N,N,N,N,N,N,N,N,N,N,N,N,N,39088,41024,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38845,38781,38901, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39852,64218,37570,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38833,N,N,N,N,N,36987,N, +N,N,N,37886,38011,N,38775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64190,64835,37062, +37028,37032,38057,N,37033,N,N,N,N,35941,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38368,36989,N,N,N,N,N,N,37477,N,N,N,N,N,N,N,N,N,N,N,N,N,64954,37828,N,N,N,N,N, +N,N,N,65261,40363,41187,N,38472,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40275,N,N,N,N,N,35497,N,39877,N,38493,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +38751,38495,38510,64349,N,N,N,N,N,40369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65187,N,N,N,N,N,N,N,N,N,40370,N,N,38318,64675,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34665,N,N,N,N,N,N,N,N, +41122,N,N,38485,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40276,N,N,37697,N,38317,37333,N,N, +N,N,N,N,N,N,N,N,N,N,38778,65020,36423,37885,37029,37036,N,N,N,N,N,N,N,N,38316, +N,N,N,N,N,N,N,N,N,37038,65189,N,N,N,N,N,40278,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,38883,38370,N,N,N,N,N,37990,N,N,38471,N,N,N,N,37304,N,N,N,N,40172,N,N,N,N, +N,N,N,N,37037,N,38371,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35663, +N,N,35555,N,N,N,N,35661,38378,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35662,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36033, +35821,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,37337,N,N,41124,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,38389,38388,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40883,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,65199,N,N,N,N,N,65138,37498,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65196,N,N,N,N,N,N,N,N,N,N,N, +N,N,38387,40280,36166,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37746,N,N,37317,N,N,N,N,N,N, +N,38466,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37069,38398, +37209,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38860,37070,N,N,N,N,N,N,40281,64757,65277,N,N, +40283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,40284,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37758,N,N,N,N,N,N,N,N,N,N, +N,N,N,39084,N,N,40286,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64976,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64864,N, +N,N,N,N,N,N,N,N,N,N,40143,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37088,37107,N,N,39089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37104,N,N,N,N, +N,N,N,N,N,N,N,37821,N,N,N,N,N,N,N,N,38327,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40774,N,N,N,N,N,N,N,N,36427,38488,N,N,N,N,N,N,N,N,N,N,35404,N,40291,40655,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40293,N,N,N,N,N,N,N,40294,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38490,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40292,N,N,N,N,N,N,N,N,N,N,35436,35545,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40295, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,35440,35827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37200,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,40129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,40296,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37799,N,N,N,N,N,N,38516,N,N,N,N,N,N,N,N,36093,41199,N,37201,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38593,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34679,N,35940,38518,40297,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,64676,N,N,N,N,N,N,N,N,N,N,N,N,40298,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37454,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,40299,N,N,N,N,N,39873,40300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,35429,37213,N,N,N,N,N,N,N,N,40301,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37210,35906,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40128,37226,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,40302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,40614,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40397,N,N,40303,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35259,40697,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,38580,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,37234,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +40648,N,N,N,34673,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35669,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,40305,40306,N,N,N,N,N,N,N,N,N,N,N,N,40652,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,37236,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,40656,36956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,36562,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37288,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37239,N,N,N,N,N,N,N,N,N,N,N, +38591,N,N,N,N,N,38592,N,N,N,N,36785,N,N,N,N,N,38583,35925,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37240,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35262, +37244,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64375,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37237,37283,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,37238,N,N,N,N,N,N,N,N,38590,36169,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,37241,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,38582,37284,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +37286,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40309,N,N,N,N,N,N,N,N,N,N,N,36946,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41029,N,37289,N,39082,N,N,N,35935,N,N,35754,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40157,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40311,34646,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,35136,40684,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,37802,38008,N,N,N,N,40314,35529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35659,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40940,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +35554,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,40565,39028,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,39624,N,N,N,N,41031, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,35779,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64631,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,40018,36605,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36776,N,N,N,N,N,N,N,N,N, +38266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,36848, +}; + +static const struct unim_index big5hkscs_nonbmp_encmap[256] = { +{__big5hkscs_nonbmp_encmap+0,33,238},{__big5hkscs_nonbmp_encmap+206,12,242},{ +__big5hkscs_nonbmp_encmap+437,4,229},{__big5hkscs_nonbmp_encmap+663,10,252},{ +__big5hkscs_nonbmp_encmap+906,19,254},{__big5hkscs_nonbmp_encmap+1142,71,235}, +{__big5hkscs_nonbmp_encmap+1307,17,118},{__big5hkscs_nonbmp_encmap+1409,14,121 +},{__big5hkscs_nonbmp_encmap+1517,44,213},{__big5hkscs_nonbmp_encmap+1687,22, +231},{__big5hkscs_nonbmp_encmap+1897,17,205},{__big5hkscs_nonbmp_encmap+2086, +13,255},{__big5hkscs_nonbmp_encmap+2329,11,255},{__big5hkscs_nonbmp_encmap+ +2574,21,200},{__big5hkscs_nonbmp_encmap+2754,4,251},{__big5hkscs_nonbmp_encmap ++3002,29,237},{__big5hkscs_nonbmp_encmap+3211,20,246},{ +__big5hkscs_nonbmp_encmap+3438,47,217},{__big5hkscs_nonbmp_encmap+3609,60,254 +},{__big5hkscs_nonbmp_encmap+3804,2,254},{__big5hkscs_nonbmp_encmap+4057,19, +253},{__big5hkscs_nonbmp_encmap+4292,119,150},{__big5hkscs_nonbmp_encmap+4324, +10,254},{__big5hkscs_nonbmp_encmap+4569,13,252},{__big5hkscs_nonbmp_encmap+ +4809,32,250},{__big5hkscs_nonbmp_encmap+5028,3,243},{__big5hkscs_nonbmp_encmap ++5269,45,99},{__big5hkscs_nonbmp_encmap+5324,68,194},{ +__big5hkscs_nonbmp_encmap+5451,42,172},{__big5hkscs_nonbmp_encmap+5582,70,249 +},{__big5hkscs_nonbmp_encmap+5762,28,213},{__big5hkscs_nonbmp_encmap+5948,15, +232},{__big5hkscs_nonbmp_encmap+6166,69,252},{__big5hkscs_nonbmp_encmap+6350, +42,195},{__big5hkscs_nonbmp_encmap+6504,8,124},{__big5hkscs_nonbmp_encmap+6621 +,33,250},{__big5hkscs_nonbmp_encmap+6839,101,237},{__big5hkscs_nonbmp_encmap+ +6976,19,190},{__big5hkscs_nonbmp_encmap+7148,27,246},{ +__big5hkscs_nonbmp_encmap+7368,18,205},{__big5hkscs_nonbmp_encmap+7556,3,247}, +{__big5hkscs_nonbmp_encmap+7801,38,147},{__big5hkscs_nonbmp_encmap+7911,102, +232},{__big5hkscs_nonbmp_encmap+8042,14,206},{__big5hkscs_nonbmp_encmap+8235, +38,201},{__big5hkscs_nonbmp_encmap+8399,7,238},{__big5hkscs_nonbmp_encmap+8631 +,13,239},{__big5hkscs_nonbmp_encmap+8858,116,227},{__big5hkscs_nonbmp_encmap+ +8970,51,218},{__big5hkscs_nonbmp_encmap+9138,3,249},{__big5hkscs_nonbmp_encmap ++9385,15,225},{__big5hkscs_nonbmp_encmap+9596,0,254},{ +__big5hkscs_nonbmp_encmap+9851,0,229},{__big5hkscs_nonbmp_encmap+10081,25,243 +},{__big5hkscs_nonbmp_encmap+10300,0,238},{__big5hkscs_nonbmp_encmap+10539,3, +215},{__big5hkscs_nonbmp_encmap+10752,58,58},{__big5hkscs_nonbmp_encmap+10753, +194,194},{__big5hkscs_nonbmp_encmap+10754,167,250},{__big5hkscs_nonbmp_encmap+ +10838,26,90},{__big5hkscs_nonbmp_encmap+10903,99,255},{ +__big5hkscs_nonbmp_encmap+11060,64,248},{__big5hkscs_nonbmp_encmap+11245,6,252 +},{__big5hkscs_nonbmp_encmap+11492,53,240},{__big5hkscs_nonbmp_encmap+11680, +17,236},{__big5hkscs_nonbmp_encmap+11900,4,252},{__big5hkscs_nonbmp_encmap+ +12149,27,250},{__big5hkscs_nonbmp_encmap+12373,13,248},{ +__big5hkscs_nonbmp_encmap+12609,4,214},{__big5hkscs_nonbmp_encmap+12820,5,200 +},{__big5hkscs_nonbmp_encmap+13016,24,212},{__big5hkscs_nonbmp_encmap+13205,6, +224},{__big5hkscs_nonbmp_encmap+13424,18,255},{__big5hkscs_nonbmp_encmap+13662 +,0,251},{__big5hkscs_nonbmp_encmap+13914,14,233},{__big5hkscs_nonbmp_encmap+ +14134,15,245},{__big5hkscs_nonbmp_encmap+14365,9,217},{ +__big5hkscs_nonbmp_encmap+14574,6,235},{__big5hkscs_nonbmp_encmap+14804,59,167 +},{__big5hkscs_nonbmp_encmap+14913,14,194},{__big5hkscs_nonbmp_encmap+15094, +44,157},{__big5hkscs_nonbmp_encmap+15208,43,231},{__big5hkscs_nonbmp_encmap+ +15397,32,216},{__big5hkscs_nonbmp_encmap+15582,14,19},{ +__big5hkscs_nonbmp_encmap+15588,25,154},{__big5hkscs_nonbmp_encmap+15718,49, +224},{__big5hkscs_nonbmp_encmap+15894,5,246},{__big5hkscs_nonbmp_encmap+16136, +6,225},{__big5hkscs_nonbmp_encmap+16356,87,225},{__big5hkscs_nonbmp_encmap+ +16495,3,204},{__big5hkscs_nonbmp_encmap+16697,84,233},{ +__big5hkscs_nonbmp_encmap+16847,116,232},{__big5hkscs_nonbmp_encmap+16964,1, +254},{__big5hkscs_nonbmp_encmap+17218,32,67},{__big5hkscs_nonbmp_encmap+17254, +14,216},{__big5hkscs_nonbmp_encmap+17457,26,226},{__big5hkscs_nonbmp_encmap+ +17658,41,165},{__big5hkscs_nonbmp_encmap+17783,2,221},{ +__big5hkscs_nonbmp_encmap+18003,88,208},{__big5hkscs_nonbmp_encmap+18124,53, +248},{__big5hkscs_nonbmp_encmap+18320,2,152},{__big5hkscs_nonbmp_encmap+18471, +18,191},{__big5hkscs_nonbmp_encmap+18645,18,252},{__big5hkscs_nonbmp_encmap+ +18880,22,204},{__big5hkscs_nonbmp_encmap+19063,28,199},{ +__big5hkscs_nonbmp_encmap+19235,14,250},{__big5hkscs_nonbmp_encmap+19472,45,82 +},{__big5hkscs_nonbmp_encmap+19510,5,247},{__big5hkscs_nonbmp_encmap+19753,33, +209},{__big5hkscs_nonbmp_encmap+19930,34,240},{__big5hkscs_nonbmp_encmap+20137 +,0,215},{__big5hkscs_nonbmp_encmap+20353,38,223},{__big5hkscs_nonbmp_encmap+ +20539,14,248},{__big5hkscs_nonbmp_encmap+20774,9,205},{ +__big5hkscs_nonbmp_encmap+20971,27,230},{__big5hkscs_nonbmp_encmap+21175,82, +255},{__big5hkscs_nonbmp_encmap+21349,34,134},{__big5hkscs_nonbmp_encmap+21450 +,116,254},{__big5hkscs_nonbmp_encmap+21589,7,148},{__big5hkscs_nonbmp_encmap+ +21731,15,204},{__big5hkscs_nonbmp_encmap+21921,88,200},{ +__big5hkscs_nonbmp_encmap+22034,36,253},{__big5hkscs_nonbmp_encmap+22252,10, +244},{__big5hkscs_nonbmp_encmap+22487,6,244},{__big5hkscs_nonbmp_encmap+22726, +18,197},{__big5hkscs_nonbmp_encmap+22906,47,220},{__big5hkscs_nonbmp_encmap+ +23080,77,79},{__big5hkscs_nonbmp_encmap+23083,46,249},{ +__big5hkscs_nonbmp_encmap+23287,2,244},{__big5hkscs_nonbmp_encmap+23530,46,188 +},{__big5hkscs_nonbmp_encmap+23673,7,226},{__big5hkscs_nonbmp_encmap+23893,6, +138},{__big5hkscs_nonbmp_encmap+24026,18,130},{__big5hkscs_nonbmp_encmap+24139 +,1,244},{__big5hkscs_nonbmp_encmap+24383,0,230},{__big5hkscs_nonbmp_encmap+ +24614,15,19},{__big5hkscs_nonbmp_encmap+24619,4,43},{__big5hkscs_nonbmp_encmap ++24659,51,252},{__big5hkscs_nonbmp_encmap+24861,15,252},{ +__big5hkscs_nonbmp_encmap+25099,12,255},{__big5hkscs_nonbmp_encmap+25343,3,210 +},{__big5hkscs_nonbmp_encmap+25551,52,185},{__big5hkscs_nonbmp_encmap+25685, +15,231},{__big5hkscs_nonbmp_encmap+25902,197,197},{__big5hkscs_nonbmp_encmap+ +25903,121,237},{__big5hkscs_nonbmp_encmap+26020,13,235},{0,0,0},{0,0,0},{ +__big5hkscs_nonbmp_encmap+26243,29,231},{__big5hkscs_nonbmp_encmap+26446,158, +244},{0,0,0},{__big5hkscs_nonbmp_encmap+26533,32,212},{ +__big5hkscs_nonbmp_encmap+26714,16,250},{__big5hkscs_nonbmp_encmap+26949,3,201 +},{__big5hkscs_nonbmp_encmap+27148,40,77},{__big5hkscs_nonbmp_encmap+27186,5, +213},{__big5hkscs_nonbmp_encmap+27395,115,173},{__big5hkscs_nonbmp_encmap+ +27454,62,246},{__big5hkscs_nonbmp_encmap+27639,6,248},{ +__big5hkscs_nonbmp_encmap+27882,35,222},{__big5hkscs_nonbmp_encmap+28070,20, +254},{__big5hkscs_nonbmp_encmap+28305,7,245},{__big5hkscs_nonbmp_encmap+28544, +32,255},{__big5hkscs_nonbmp_encmap+28768,81,169},{__big5hkscs_nonbmp_encmap+ +28857,52,91},{__big5hkscs_nonbmp_encmap+28897,198,203},{ +__big5hkscs_nonbmp_encmap+28903,1,169},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__big5hkscs_nonbmp_encmap+29072,37,205},{__big5hkscs_nonbmp_encmap+29241,148, +212},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_jisx0213_pair.h b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_jisx0213_pair.h index c96f20142b7..1daf9fcbd04 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_jisx0213_pair.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_jisx0213_pair.h @@ -1,60 +1,60 @@ // AUTO-GENERATED FILE FROM genmap_japanese.py: DO NOT EDIT -#define JISX0213_ENCPAIRS 46 -#ifdef EXTERN_JISX0213_PAIR -static const struct widedbcs_index *jisx0213_pair_decmap; -static const struct pair_encodemap *jisx0213_pair_encmap; -#else -static const Py_UCS4 __jisx0213_pair_decmap[49] = { -810234010,810365082,810496154,810627226,810758298,816525466,816656538, -816787610,816918682,817049754,817574042,818163866,818426010,838283418, -15074048,U,U,U,39060224,39060225,42730240,42730241,39387904,39387905,39453440, -39453441,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,48825061,48562921, -}; - -static const struct widedbcs_index jisx0213_pair_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_pair_decmap -+0,119,123},{__jisx0213_pair_decmap+5,119,126},{__jisx0213_pair_decmap+13,120, -120},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_pair_decmap+14,68,102},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const struct pair_encodemap jisx0213_pair_encmap[JISX0213_ENCPAIRS] = { -{0x00e60000,0x295c},{0x00e60300,0x2b44},{0x02540000,0x2b38},{0x02540300,0x2b48 -},{0x02540301,0x2b49},{0x02590000,0x2b30},{0x02590300,0x2b4c},{0x02590301, -0x2b4d},{0x025a0000,0x2b43},{0x025a0300,0x2b4e},{0x025a0301,0x2b4f},{ -0x028c0000,0x2b37},{0x028c0300,0x2b4a},{0x028c0301,0x2b4b},{0x02e50000,0x2b60 -},{0x02e502e9,0x2b66},{0x02e90000,0x2b64},{0x02e902e5,0x2b65},{0x304b0000, -0x242b},{0x304b309a,0x2477},{0x304d0000,0x242d},{0x304d309a,0x2478},{ -0x304f0000,0x242f},{0x304f309a,0x2479},{0x30510000,0x2431},{0x3051309a,0x247a -},{0x30530000,0x2433},{0x3053309a,0x247b},{0x30ab0000,0x252b},{0x30ab309a, -0x2577},{0x30ad0000,0x252d},{0x30ad309a,0x2578},{0x30af0000,0x252f},{ -0x30af309a,0x2579},{0x30b10000,0x2531},{0x30b1309a,0x257a},{0x30b30000,0x2533 -},{0x30b3309a,0x257b},{0x30bb0000,0x253b},{0x30bb309a,0x257c},{0x30c40000, -0x2544},{0x30c4309a,0x257d},{0x30c80000,0x2548},{0x30c8309a,0x257e},{ -0x31f70000,0x2675},{0x31f7309a,0x2678}, -}; -#endif +#define JISX0213_ENCPAIRS 46 +#ifdef EXTERN_JISX0213_PAIR +static const struct widedbcs_index *jisx0213_pair_decmap; +static const struct pair_encodemap *jisx0213_pair_encmap; +#else +static const Py_UCS4 __jisx0213_pair_decmap[49] = { +810234010,810365082,810496154,810627226,810758298,816525466,816656538, +816787610,816918682,817049754,817574042,818163866,818426010,838283418, +15074048,U,U,U,39060224,39060225,42730240,42730241,39387904,39387905,39453440, +39453441,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,48825061,48562921, +}; + +static const struct widedbcs_index jisx0213_pair_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_pair_decmap ++0,119,123},{__jisx0213_pair_decmap+5,119,126},{__jisx0213_pair_decmap+13,120, +120},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_pair_decmap+14,68,102},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const struct pair_encodemap jisx0213_pair_encmap[JISX0213_ENCPAIRS] = { +{0x00e60000,0x295c},{0x00e60300,0x2b44},{0x02540000,0x2b38},{0x02540300,0x2b48 +},{0x02540301,0x2b49},{0x02590000,0x2b30},{0x02590300,0x2b4c},{0x02590301, +0x2b4d},{0x025a0000,0x2b43},{0x025a0300,0x2b4e},{0x025a0301,0x2b4f},{ +0x028c0000,0x2b37},{0x028c0300,0x2b4a},{0x028c0301,0x2b4b},{0x02e50000,0x2b60 +},{0x02e502e9,0x2b66},{0x02e90000,0x2b64},{0x02e902e5,0x2b65},{0x304b0000, +0x242b},{0x304b309a,0x2477},{0x304d0000,0x242d},{0x304d309a,0x2478},{ +0x304f0000,0x242f},{0x304f309a,0x2479},{0x30510000,0x2431},{0x3051309a,0x247a +},{0x30530000,0x2433},{0x3053309a,0x247b},{0x30ab0000,0x252b},{0x30ab309a, +0x2577},{0x30ad0000,0x252d},{0x30ad309a,0x2578},{0x30af0000,0x252f},{ +0x30af309a,0x2579},{0x30b10000,0x2531},{0x30b1309a,0x257a},{0x30b30000,0x2533 +},{0x30b3309a,0x257b},{0x30bb0000,0x253b},{0x30bb309a,0x257c},{0x30c40000, +0x2544},{0x30c4309a,0x257d},{0x30c80000,0x2548},{0x30c8309a,0x257e},{ +0x31f70000,0x2675},{0x31f7309a,0x2678}, +}; +#endif diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_jp.h b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_jp.h index 409aeae25c9..028c6787979 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_jp.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_jp.h @@ -1,4766 +1,4766 @@ // AUTO-GENERATED FILE FROM genmap_japanese.py: DO NOT EDIT -static const ucs2_t __jisx0208_decmap[6956] = { -12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180, -65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294, -12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221, -65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300, -12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310, -8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285, -65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651, -9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,U,U,U,U,U,U,U,U,U,U,U, -8712,8715,8838,8839,8834,8835,8746,8745,U,U,U,U,U,U,U,U,8743,8744,172,8658, -8660,8704,8707,U,U,U,U,U,U,U,U,U,U,U,8736,8869,8978,8706,8711,8801,8786,8810, -8811,8730,8765,8733,8757,8747,8748,U,U,U,U,U,U,U,8491,8240,9839,9837,9834, -8224,8225,182,U,U,U,U,9711,65296,65297,65298,65299,65300,65301,65302,65303, -65304,65305,U,U,U,U,U,U,U,65313,65314,65315,65316,65317,65318,65319,65320, -65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333, -65334,65335,65336,65337,65338,U,U,U,U,U,U,65345,65346,65347,65348,65349,65350, -65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363, -65364,65365,65366,65367,65368,65369,65370,12353,12354,12355,12356,12357,12358, -12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371, -12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384, -12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397, -12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410, -12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423, -12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,12449, -12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462, -12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475, -12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488, -12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501, -12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514, -12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527, -12528,12529,12530,12531,12532,12533,12534,913,914,915,916,917,918,919,920,921, -922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,U,U,U,U,U,U,U,U, -945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964, -965,966,967,968,969,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049, -1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064, -1065,1066,1067,1068,1069,1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,1073, -1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087, -1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102, -1103,9472,9474,9484,9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487, -9491,9499,9495,9507,9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520, -9509,9528,9538,20124,21782,23043,38463,21696,24859,25384,23030,36898,33909, -33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,26017,25201, -23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,24245,25353, -26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,22839,22996, -23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,32173,32239, -32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,37057,30959, -19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,21729,22240, -23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,21491,23431, -28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,22040,21764, -27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,38642,33615, -39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,29787,30408, -31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,35585,36234, -38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,25588,27839, -28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,37467,40219, -22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,27178,27431, -27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,23627,25014, -33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,21270,20206, -20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,31185,26247, -26524,26550,27468,27827,28779,29634,31117,31166,31292,31623,33457,33499,33540, -33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,20420,23784, -25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,20250,35299, -22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,25913,39745, -26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,35997,20977, -21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,35442,37799, -39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,24275,25313, -25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,37101,38307, -38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,26806,39949, -28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,19988,39993, -21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,40232,26658, -33541,33841,31909,21000,33477,29926,20094,20355,20896,23506,21002,21208,21223, -24059,21914,22570,23014,23436,23448,23515,24178,24185,24739,24863,24931,25022, -25563,25954,26577,26707,26874,27454,27475,27735,28450,28567,28485,29872,29976, -30435,30475,31487,31649,31777,32233,32566,32752,32925,33382,33694,35251,35532, -36011,36996,37969,38291,38289,38306,38501,38867,39208,33304,20024,21547,23736, -24012,29609,30284,30524,23721,32747,36107,38593,38929,38996,39000,20225,20238, -21361,21916,22120,22522,22855,23305,23492,23696,24076,24190,24524,25582,26426, -26071,26082,26399,26827,26820,27231,24112,27589,27671,27773,30079,31048,23395, -31232,32000,24509,35215,35352,36020,36215,36556,36637,39138,39438,39740,20096, -20605,20736,22931,23452,25135,25216,25836,27450,29344,30097,31047,32681,34811, -35516,35696,25516,33738,38816,21513,21507,21931,26708,27224,35440,30759,26485, -40653,21364,23458,33050,34384,36870,19992,20037,20167,20241,21450,21560,23470, -24339,24613,25937,26429,27714,27762,27875,28792,29699,31350,31406,31496,32026, -31998,32102,26087,29275,21435,23621,24040,25298,25312,25369,28192,34394,35377, -36317,37624,28417,31142,39770,20136,20139,20140,20379,20384,20689,20807,31478, -20849,20982,21332,21281,21375,21483,21932,22659,23777,24375,24394,24623,24656, -24685,25375,25945,27211,27841,29378,29421,30703,33016,33029,33288,34126,37111, -37857,38911,39255,39514,20208,20957,23597,26241,26989,23616,26354,26997,29577, -26704,31873,20677,21220,22343,24062,37670,26020,27427,27453,29748,31105,31165, -31563,32202,33465,33740,34943,35167,35641,36817,37329,21535,37504,20061,20534, -21477,21306,29399,29590,30697,33510,36527,39366,39368,39378,20855,24858,34398, -21936,31354,20598,23507,36935,38533,20018,27355,37351,23633,23624,25496,31391, -27795,38772,36705,31402,29066,38536,31874,26647,32368,26705,37740,21234,21531, -34219,35347,32676,36557,37089,21350,34952,31041,20418,20670,21009,20804,21843, -22317,29674,22411,22865,24418,24452,24693,24950,24935,25001,25522,25658,25964, -26223,26690,28179,30054,31293,31995,32076,32153,32331,32619,33550,33610,34509, -35336,35427,35686,36605,38938,40335,33464,36814,39912,21127,25119,25731,28608, -38553,26689,20625,27424,27770,28500,31348,32080,34880,35363,26376,20214,20537, -20518,20581,20860,21048,21091,21927,22287,22533,23244,24314,25010,25080,25331, -25458,26908,27177,29309,29356,29486,30740,30831,32121,30476,32937,35211,35609, -36066,36562,36963,37749,38522,38997,39443,40568,20803,21407,21427,24187,24358, -28187,28304,29572,29694,32067,33335,35328,35578,38480,20046,20491,21476,21628, -22266,22993,23396,24049,24235,24359,25144,25925,26543,28246,29392,31946,34996, -32929,32993,33776,34382,35463,36328,37431,38599,39015,40723,20116,20114,20237, -21320,21577,21566,23087,24460,24481,24735,26791,27278,29786,30849,35486,35492, -35703,37264,20062,39881,20132,20348,20399,20505,20502,20809,20844,21151,21177, -21246,21402,21475,21521,21518,21897,22353,22434,22909,23380,23389,23439,24037, -24039,24055,24184,24195,24218,24247,24344,24658,24908,25239,25304,25511,25915, -26114,26179,26356,26477,26657,26775,27083,27743,27946,28009,28207,28317,30002, -30343,30828,31295,31968,32005,32024,32094,32177,32789,32771,32943,32945,33108, -33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,37628, -38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,28640, -35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,28425, -33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,22718, -23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,20123, -20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,35039, -22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,25165, -25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,33756, -35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,27018, -32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,26613, -31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,25774, -25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,19977, -20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,34453, -35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,21496, -21490,21987,22235,22763,22987,22985,23039,23376,23629,24066,24107,24535,24605, -25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,31169, -31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,36039, -36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,26178, -27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,36766, -27728,40575,24335,35672,40235,31482,36600,23437,38635,19971,21489,22519,22833, -23241,23460,24713,28287,28422,30142,36074,23455,34048,31712,20594,26612,33437, -23649,34122,32286,33294,20889,23556,25448,36198,26012,29038,31038,32023,32773, -35613,36554,36974,34503,37034,20511,21242,23610,26451,28796,29237,37196,37320, -37675,33509,23490,24369,24825,20027,21462,23432,25163,26417,27530,29417,29664, -31278,33131,36259,37202,39318,20754,21463,21610,23551,25480,27193,32172,38656, -22234,21454,21608,23447,23601,24030,20462,24833,25342,27954,31168,31179,32066, -32333,32722,33261,33311,33936,34886,35186,35728,36468,36655,36913,37195,37228, -38598,37276,20160,20303,20805,21313,24467,25102,26580,27713,28171,29539,32294, -37325,37507,21460,22809,23487,28113,31069,32302,31899,22654,29087,20986,34899, -36848,20426,23803,26149,30636,31459,33308,39423,20934,24490,26092,26991,27529, -28147,28310,28516,30462,32020,24033,36981,37255,38918,20966,21021,25152,26257, -26329,28186,24246,32210,32626,26360,34223,34295,35576,21161,21465,22899,24207, -24464,24661,37604,38500,20663,20767,21213,21280,21319,21484,21736,21830,21809, -22039,22888,22974,23100,23477,23558,23567,23569,23578,24196,24202,24288,24432, -25215,25220,25307,25484,25463,26119,26124,26157,26230,26494,26786,27167,27189, -27836,28040,28169,28248,28988,28966,29031,30151,30465,30813,30977,31077,31216, -31456,31505,31911,32057,32918,33750,33931,34121,34909,35059,35359,35388,35412, -35443,35937,36062,37284,37478,37758,37912,38556,38808,19978,19976,19998,20055, -20887,21104,22478,22580,22732,23330,24120,24773,25854,26465,26454,27972,29366, -30067,31331,33976,35698,37304,37664,22065,22516,39166,25325,26893,27542,29165, -32340,32887,33394,35302,39135,34645,36785,23611,20280,20449,20405,21767,23072, -23517,23529,24515,24910,25391,26032,26187,26862,27035,28024,28145,30003,30137, -30495,31070,31206,32051,33251,33455,34218,35242,35386,36523,36763,36914,37341, -38663,20154,20161,20995,22645,22764,23563,29978,23613,33102,35338,36805,38499, -38765,31525,35535,38920,37218,22259,21416,36887,21561,22402,24101,25512,27700, -28810,30561,31883,32736,34928,36930,37204,37648,37656,38543,29790,39620,23815, -23913,25968,26530,36264,38619,25454,26441,26905,33733,38935,38592,35070,28548, -25722,23544,19990,28716,30045,26159,20932,21046,21218,22995,24449,24615,25104, -25919,25972,26143,26228,26866,26646,27491,28165,29298,29983,30427,31934,32854, -22768,35069,35199,35488,35475,35531,36893,37266,38738,38745,25993,31246,33030, -38587,24109,24796,25114,26021,26132,26512,30707,31309,31821,32318,33034,36012, -36196,36321,36447,30889,20999,25305,25509,25666,25240,35373,31363,31680,35500, -38634,32118,33292,34633,20185,20808,21315,21344,23459,23554,23574,24029,25126, -25159,25776,26643,26676,27849,27973,27927,26579,28508,29006,29053,26059,31359, -31661,32218,32330,32680,33146,33307,33337,34214,35438,36046,36341,36984,36983, -37549,37521,38275,39854,21069,21892,28472,28982,20840,31109,32341,33203,31950, -22092,22609,23720,25514,26366,26365,26970,29401,30095,30094,30990,31062,31199, -31895,32032,32068,34311,35380,38459,36961,40736,20711,21109,21452,21474,20489, -21930,22766,22863,29245,23435,23652,21277,24803,24819,25436,25475,25407,25531, -25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967, -32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783, -38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363, -24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966, -20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409, -21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534, -23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151, -33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261, -38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730, -35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890, -33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022, -22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829, -32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527, -20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933, -39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013, -20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376, -27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115, -24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522, -32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189, -25431,30452,26389,27784,29645,36035,37806,38515,27941,22684,26894,27084,36861, -37786,30171,36890,22618,26626,25524,27131,20291,28460,26584,36795,34086,32180, -37716,26943,28528,22378,22775,23340,32044,29226,21514,37347,40372,20141,20302, -20572,20597,21059,35998,21576,22564,23450,24093,24213,24237,24311,24351,24716, -25269,25402,25552,26799,27712,30855,31118,31243,32224,33351,35330,35558,36420, -36883,37048,37165,37336,40718,27877,25688,25826,25973,28404,30340,31515,36969, -37841,28346,21746,24505,25764,36685,36845,37444,20856,22635,22825,23637,24215, -28155,32399,29980,36028,36578,39003,28857,20253,27583,28593,30000,38651,20814, -21520,22581,22615,22956,23648,24466,26007,26460,28193,30331,33759,36077,36884, -37117,37709,30757,30778,21162,24230,22303,22900,24594,20498,20826,20908,20941, -20992,21776,22612,22616,22871,23445,23798,23947,24764,25237,25645,26481,26691, -26812,26847,30423,28120,28271,28059,28783,29128,24403,30168,31095,31561,31572, -31570,31958,32113,21040,33891,34153,34276,35342,35588,35910,36367,36867,36879, -37913,38518,38957,39472,38360,20685,21205,21516,22530,23566,24999,25758,27934, -30643,31461,33012,33796,36947,37509,23776,40199,21311,24471,24499,28060,29305, -30563,31167,31716,27602,29420,35501,26627,27233,20984,31361,26932,23626,40182, -33515,23493,37193,28702,22136,23663,24775,25958,27788,35930,36929,38931,21585, -26311,37389,22856,37027,20869,20045,20970,34201,35598,28760,25466,37707,26978, -39348,32260,30071,21335,26976,36575,38627,27741,20108,23612,24336,36841,21250, -36049,32905,34425,24319,26085,20083,20837,22914,23615,38894,20219,22922,24525, -35469,28641,31152,31074,23527,33905,29483,29105,24180,24565,25467,25754,29123, -31896,20035,24316,20043,22492,22178,24745,28611,32013,33021,33075,33215,36786, -35223,34468,24052,25226,25773,35207,26487,27874,27966,29750,30772,23110,32629, -33453,39340,20467,24259,25309,25490,25943,26479,30403,29260,32972,32954,36649, -37197,20493,22521,23186,26757,26995,29028,29437,36023,22770,36064,38506,36889, -34687,31204,30695,33833,20271,21093,21338,25293,26575,27850,30333,31636,31893, -33334,34180,36843,26333,28448,29190,32283,33707,39361,40614,20989,31665,30834, -31672,32903,31560,27368,24161,32908,30033,30048,20843,37474,28300,30330,37271, -39658,20240,32624,25244,31567,38309,40169,22138,22617,34532,38588,20276,21028, -21322,21453,21467,24070,25644,26001,26495,27710,27726,29256,29359,29677,30036, -32321,33324,34281,36009,31684,37318,29033,38930,39151,25405,26217,30058,30436, -30928,34115,34542,21290,21329,21542,22915,24199,24444,24754,25161,25209,25259, -26000,27604,27852,30130,30382,30865,31192,32203,32631,32933,34987,35513,36027, -36991,38750,39131,27147,31800,20633,23614,24494,26503,27608,29749,30473,32654, -40763,26570,31255,21305,30091,39661,24422,33181,33777,32920,24380,24517,30050, -31558,36924,26727,23019,23195,32016,30334,35628,20469,24426,27161,27703,28418, -29922,31080,34920,35413,35961,24287,25551,30149,31186,33495,37672,37618,33948, -34541,39981,21697,24428,25996,27996,28693,36007,36051,38971,25935,29942,19981, -20184,22496,22827,23142,23500,20904,24067,24220,24598,25206,25975,26023,26222, -28014,29238,31526,33104,33178,33433,35676,36000,36070,36212,38428,38468,20398, -25771,27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103, -24489,24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289, -39826,20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640, -25991,32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281, -38491,31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793, -29255,31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303, -37610,22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286, -27597,31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849, -24214,25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459, -33804,34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129, -20621,21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882, -32033,32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340, -22696,25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868, -26412,32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598, -21737,27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273, -26411,27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410, -39749,24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665, -30496,21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517, -21629,26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236, -38754,40634,25720,27169,33538,22916,23391,27611,29467,30450,32178,32791,33945, -20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,36016,21839,24758, -32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,30690,21380,24441, -32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,27833,30290,35565, -36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,25558,26377,26586, -28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,37109,38596,34701, -22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,23481,24248,25562, -25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,32650,32768,33865, -33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,27779,28020,32716, -32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,32097,33853,37226, -20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,23653,26446,26792, -29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,31435,33870,25504, -30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,40845,20406,24942, -26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,28092,29471,30274, -30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,32209,20523,21400, -26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,22593,28057,32047, -39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,33491,37428,38583, -38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,24265,24651,24976, -28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,27347,28809,36034, -36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,28431,29282,29436, -31725,32769,32894,34635,37070,20845,40595,31108,32907,37682,35542,20525,21644, -35441,27498,36036,33031,24785,26528,40434,20121,20120,39952,35435,34241,34152, -26880,28286,30871,33109,24332,19984,19989,20010,20017,20022,20028,20031,20034, -20054,20056,20098,20101,35947,20106,33298,24333,20110,20126,20127,20128,20130, -20144,20147,20150,20174,20173,20164,20166,20162,20183,20190,20205,20191,20215, -20233,20314,20272,20315,20317,20311,20295,20342,20360,20367,20376,20347,20329, -20336,20369,20335,20358,20374,20760,20436,20447,20430,20440,20443,20433,20442, -20432,20452,20453,20506,20520,20500,20522,20517,20485,20252,20470,20513,20521, -20524,20478,20463,20497,20486,20547,20551,26371,20565,20560,20552,20570,20566, -20588,20600,20608,20634,20613,20660,20658,20681,20682,20659,20674,20694,20702, -20709,20717,20707,20718,20729,20725,20745,20737,20738,20758,20757,20756,20762, -20769,20794,20791,20796,20795,20799,20800,20818,20812,20820,20834,31480,20841, -20842,20846,20864,20866,22232,20876,20873,20879,20881,20883,20885,20886,20900, -20902,20898,20905,20906,20907,20915,20913,20914,20912,20917,20925,20933,20937, -20955,20960,34389,20969,20973,20976,20981,20990,20996,21003,21012,21006,21031, -21034,21038,21043,21049,21071,21060,21067,21068,21086,21076,21098,21108,21097, -21107,21119,21117,21133,21140,21138,21105,21128,21137,36776,36775,21164,21165, -21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,21237,21240, -21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,21297,21299, -21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,22808,21371, -21367,21378,21398,21408,21414,21413,21422,21424,21430,21443,31762,38617,21471, -26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,21564,21550, -21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,21650,21627, -21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,21704,21672, -21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,21742,21741, -21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,21816,21811, -21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,21884,21891, -21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,22007,22038, -22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,22123,22116, -22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,22198,22196, -22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,22265,22272, -22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,22310,22327, -22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,22419,22432, -22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,22499,22539, -22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,22661,22713, -22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,22745,22744, -22757,22748,22756,22751,22767,22778,22777,22779,22780,22781,22786,22794,22800, -22811,26790,22821,22828,22829,22834,22840,22846,31442,22869,22864,22862,22874, -22872,22882,22880,22887,22892,22889,22904,22913,22941,20318,20395,22947,22962, -22982,23016,23004,22925,23001,23002,23077,23071,23057,23068,23049,23066,23104, -23148,23113,23093,23094,23138,23146,23194,23228,23230,23243,23234,23229,23267, -23255,23270,23273,23254,23290,23291,23308,23307,23318,23346,23248,23338,23350, -23358,23363,23365,23360,23377,23381,23386,23387,23397,23401,23408,23411,23413, -23416,25992,23418,23424,23427,23462,23480,23491,23495,23497,23508,23504,23524, -23526,23522,23518,23525,23531,23536,23542,23539,23557,23559,23560,23565,23571, -23584,23586,23592,23608,23609,23617,23622,23630,23635,23632,23631,23409,23660, -23662,20066,23670,23673,23692,23697,23700,22939,23723,23739,23734,23740,23735, -23749,23742,23751,23769,23785,23805,23802,23789,23948,23786,23819,23829,23831, -23900,23839,23835,23825,23828,23842,23834,23833,23832,23884,23890,23886,23883, -23916,23923,23926,23943,23940,23938,23970,23965,23980,23982,23997,23952,23991, -23996,24009,24013,24019,24018,24022,24027,24043,24050,24053,24075,24090,24089, -24081,24091,24118,24119,24132,24131,24128,24142,24151,24148,24159,24162,24164, -24135,24181,24182,24186,40636,24191,24224,24257,24258,24264,24272,24271,24278, -24291,24285,24282,24283,24290,24289,24296,24297,24300,24305,24307,24304,24308, -24312,24318,24323,24329,24413,24412,24331,24337,24342,24361,24365,24376,24385, -24392,24396,24398,24367,24401,24406,24407,24409,24417,24429,24435,24439,24451, -24450,24447,24458,24456,24465,24455,24478,24473,24472,24480,24488,24493,24508, -24534,24571,24548,24568,24561,24541,24755,24575,24609,24672,24601,24592,24617, -24590,24625,24603,24597,24619,24614,24591,24634,24666,24641,24682,24695,24671, -24650,24646,24653,24675,24643,24676,24642,24684,24683,24665,24705,24717,24807, -24707,24730,24708,24731,24726,24727,24722,24743,24715,24801,24760,24800,24787, -24756,24560,24765,24774,24757,24792,24909,24853,24838,24822,24823,24832,24820, -24826,24835,24865,24827,24817,24845,24846,24903,24894,24872,24871,24906,24895, -24892,24876,24884,24893,24898,24900,24947,24951,24920,24921,24922,24939,24948, -24943,24933,24945,24927,24925,24915,24949,24985,24982,24967,25004,24980,24986, -24970,24977,25003,25006,25036,25034,25033,25079,25032,25027,25030,25018,25035, -32633,25037,25062,25059,25078,25082,25076,25087,25085,25084,25086,25088,25096, -25097,25101,25100,25108,25115,25118,25121,25130,25134,25136,25138,25139,25153, -25166,25182,25187,25179,25184,25192,25212,25218,25225,25214,25234,25235,25238, -25300,25219,25236,25303,25297,25275,25295,25343,25286,25812,25288,25308,25292, -25290,25282,25287,25243,25289,25356,25326,25329,25383,25346,25352,25327,25333, -25424,25406,25421,25628,25423,25494,25486,25472,25515,25462,25507,25487,25481, -25503,25525,25451,25449,25534,25577,25536,25542,25571,25545,25554,25590,25540, -25622,25652,25606,25619,25638,25654,25885,25623,25640,25615,25703,25711,25718, -25678,25898,25749,25747,25765,25769,25736,25788,25818,25810,25797,25799,25787, -25816,25794,25841,25831,33289,25824,25825,25260,25827,25839,25900,25846,25844, -25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,25911, -25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,25986, -25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,26075, -26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,26140, -26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,26243, -26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,26296, -26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,26406, -26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,26467, -26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,26607, -26548,26604,26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,26566, -26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,26723, -26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,26805, -26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,26892, -26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,26863, -26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,27006, -26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,27054, -27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,27182, -27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,27122, -27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,27204, -27148,27250,27190,27256,27207,27234,27225,27238,27208,27192,27170,27280,27277, -27296,27268,27298,27299,27287,34327,27323,27331,27330,27320,27315,27308,27358, -27345,27359,27306,27354,27370,27387,27397,34326,27386,27410,27414,39729,27423, -27448,27447,30428,27449,39150,27463,27459,27465,27472,27481,27476,27483,27487, -27489,27512,27513,27519,27520,27524,27523,27533,27544,27541,27550,27556,27562, -27563,27567,27570,27569,27571,27575,27580,27590,27595,27603,27615,27628,27627, -27635,27631,40638,27656,27667,27668,27675,27684,27683,27742,27733,27746,27754, -27778,27789,27802,27777,27803,27774,27752,27763,27794,27792,27844,27889,27859, -27837,27863,27845,27869,27822,27825,27838,27834,27867,27887,27865,27882,27935, -34893,27958,27947,27965,27960,27929,27957,27955,27922,27916,28003,28051,28004, -27994,28025,27993,28046,28053,28644,28037,28153,28181,28170,28085,28103,28134, -28088,28102,28140,28126,28108,28136,28114,28101,28154,28121,28132,28117,28138, -28142,28205,28270,28206,28185,28274,28255,28222,28195,28267,28203,28278,28237, -28191,28227,28218,28238,28196,28415,28189,28216,28290,28330,28312,28361,28343, -28371,28349,28335,28356,28338,28372,28373,28303,28325,28354,28319,28481,28433, -28748,28396,28408,28414,28479,28402,28465,28399,28466,28364,28478,28435,28407, -28550,28538,28536,28545,28544,28527,28507,28659,28525,28546,28540,28504,28558, -28561,28610,28518,28595,28579,28577,28580,28601,28614,28586,28639,28629,28652, -28628,28632,28657,28654,28635,28681,28683,28666,28689,28673,28687,28670,28699, -28698,28532,28701,28696,28703,28720,28734,28722,28753,28771,28825,28818,28847, -28913,28844,28856,28851,28846,28895,28875,28893,28889,28937,28925,28956,28953, -29029,29013,29064,29030,29026,29004,29014,29036,29071,29179,29060,29077,29096, -29100,29143,29113,29118,29138,29129,29140,29134,29152,29164,29159,29173,29180, -29177,29183,29197,29200,29211,29224,29229,29228,29232,29234,29243,29244,29247, -29248,29254,29259,29272,29300,29310,29314,29313,29319,29330,29334,29346,29351, -29369,29362,29379,29382,29380,29390,29394,29410,29408,29409,29433,29431,20495, -29463,29450,29468,29462,29469,29492,29487,29481,29477,29502,29518,29519,40664, -29527,29546,29544,29552,29560,29557,29563,29562,29640,29619,29646,29627,29632, -29669,29678,29662,29858,29701,29807,29733,29688,29746,29754,29781,29759,29791, -29785,29761,29788,29801,29808,29795,29802,29814,29822,29835,29854,29863,29898, -29903,29908,29681,29920,29923,29927,29929,29934,29938,29936,29937,29944,29943, -29956,29955,29957,29964,29966,29965,29973,29971,29982,29990,29996,30012,30020, -30029,30026,30025,30043,30022,30042,30057,30052,30055,30059,30061,30072,30070, -30086,30087,30068,30090,30089,30082,30100,30106,30109,30117,30115,30146,30131, -30147,30133,30141,30136,30140,30129,30157,30154,30162,30169,30179,30174,30206, -30207,30204,30209,30192,30202,30194,30195,30219,30221,30217,30239,30247,30240, -30241,30242,30244,30260,30256,30267,30279,30280,30278,30300,30296,30305,30306, -30312,30313,30314,30311,30316,30320,30322,30326,30328,30332,30336,30339,30344, -30347,30350,30358,30355,30361,30362,30384,30388,30392,30393,30394,30402,30413, -30422,30418,30430,30433,30437,30439,30442,34351,30459,30472,30471,30468,30505, -30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565, -30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652, -30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014, -30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895, -30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964, -30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059, -31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189, -31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291, -31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368, -31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431, -31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472, -31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610, -31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598, -31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681, -31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751, -31763,31731,31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805, -31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861, -31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929, -31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990, -31994,32006,32002,32028,32021,32010,32069,32075,32046,32050,32063,32053,32070, -32115,32086,32078,32114,32104,32110,32079,32099,32147,32137,32091,32143,32125, -32155,32186,32174,32163,32181,32199,32189,32171,32317,32162,32175,32220,32184, -32159,32176,32216,32221,32228,32222,32251,32242,32225,32261,32266,32291,32289, -32274,32305,32287,32265,32267,32290,32326,32358,32315,32309,32313,32323,32311, -32306,32314,32359,32349,32342,32350,32345,32346,32377,32362,32361,32380,32379, -32387,32213,32381,36782,32383,32392,32393,32396,32402,32400,32403,32404,32406, -32398,32411,32412,32568,32570,32581,32588,32589,32590,32592,32593,32597,32596, -32600,32607,32608,32616,32617,32615,32632,32642,32646,32643,32648,32647,32652, -32660,32670,32669,32666,32675,32687,32690,32697,32686,32694,32696,35697,32709, -32710,32714,32725,32724,32737,32742,32745,32755,32761,39132,32774,32772,32779, -32786,32792,32793,32796,32801,32808,32831,32827,32842,32838,32850,32856,32858, -32863,32866,32872,32883,32882,32880,32886,32889,32893,32895,32900,32902,32901, -32923,32915,32922,32941,20880,32940,32987,32997,32985,32989,32964,32986,32982, -33033,33007,33009,33051,33065,33059,33071,33099,38539,33094,33086,33107,33105, -33020,33137,33134,33125,33126,33140,33155,33160,33162,33152,33154,33184,33173, -33188,33187,33119,33171,33193,33200,33205,33214,33208,33213,33216,33218,33210, -33225,33229,33233,33241,33240,33224,33242,33247,33248,33255,33274,33275,33278, -33281,33282,33285,33287,33290,33293,33296,33302,33321,33323,33336,33331,33344, -33369,33368,33373,33370,33375,33380,33378,33384,33386,33387,33326,33393,33399, -33400,33406,33421,33426,33451,33439,33467,33452,33505,33507,33503,33490,33524, -33523,33530,33683,33539,33531,33529,33502,33542,33500,33545,33497,33589,33588, -33558,33586,33585,33600,33593,33616,33605,33583,33579,33559,33560,33669,33690, -33706,33695,33698,33686,33571,33678,33671,33674,33660,33717,33651,33653,33696, -33673,33704,33780,33811,33771,33742,33789,33795,33752,33803,33729,33783,33799, -33760,33778,33805,33826,33824,33725,33848,34054,33787,33901,33834,33852,34138, -33924,33911,33899,33965,33902,33922,33897,33862,33836,33903,33913,33845,33994, -33890,33977,33983,33951,34009,33997,33979,34010,34000,33985,33990,34006,33953, -34081,34047,34036,34071,34072,34092,34079,34069,34068,34044,34112,34147,34136, -34120,34113,34306,34123,34133,34176,34212,34184,34193,34186,34216,34157,34196, -34203,34282,34183,34204,34167,34174,34192,34249,34234,34255,34233,34256,34261, -34269,34277,34268,34297,34314,34323,34315,34302,34298,34310,34338,34330,34352, -34367,34381,20053,34388,34399,34407,34417,34451,34467,34473,34474,34443,34444, -34486,34479,34500,34502,34480,34505,34851,34475,34516,34526,34537,34540,34527, -34523,34543,34578,34566,34568,34560,34563,34555,34577,34569,34573,34553,34570, -34612,34623,34615,34619,34597,34601,34586,34656,34655,34680,34636,34638,34676, -34647,34664,34670,34649,34643,34659,34666,34821,34722,34719,34690,34735,34763, -34749,34752,34768,38614,34731,34756,34739,34759,34758,34747,34799,34802,34784, -34831,34829,34814,34806,34807,34830,34770,34833,34838,34837,34850,34849,34865, -34870,34873,34855,34875,34884,34882,34898,34905,34910,34914,34923,34945,34942, -34974,34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980, -34992,35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060, -35048,35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140, -35131,35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188, -35191,35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250, -35258,35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344, -35340,35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436, -35426,35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533, -35522,35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547, -35596,35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646, -35624,35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695, -35700,35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903, -35912,35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978, -35981,35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022, -36040,36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111, -36109,36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249, -36290,36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323, -36348,36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426, -36423,36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466, -36476,36481,36487,36485,36484,36491,36490,36499,36497,36500,36505,36522,36513, -36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,36604,36603,36587, -36606,36618,36613,36629,36626,36633,36627,36636,36639,36635,36620,36646,36659, -36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,36700,36706,36707, -36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,36842,36847,36999, -36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,36875,36903,36918, -36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,36950,36952,36958, -36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,37001,37007,37032, -37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,37170,37168,37194, -37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,37282,37291,37295, -37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,37343,37345,37339, -37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,37463,37445,37449, -37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,37466,37583,37561, -37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,37690,37685,37691, -37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,37846,37847,37864, -37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,37891,37895,37904, -37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,37986,37982,37994, -37417,38000,38005,38007,38013,37978,38012,38014,38017,38015,38274,38279,38282, -38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,38329,38334,38346, -28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,38370,38433,38440, -38446,38447,38466,38476,38479,38475,38519,38492,38494,38493,38495,38502,38514, -38508,38541,38552,38549,38551,38570,38567,38577,38578,38576,38580,38582,38584, -38585,38606,38603,38601,38605,35149,38620,38669,38613,38649,38660,38662,38664, -38675,38670,38673,38671,38678,38681,38692,38698,38704,38713,38717,38718,38724, -38726,38728,38722,38729,38748,38752,38756,38758,38760,21202,38763,38769,38777, -38789,38780,38785,38778,38790,38795,38799,38800,38812,38824,38822,38819,38835, -38836,38851,38854,38856,38859,38876,38893,40783,38898,31455,38902,38901,38927, -38924,38968,38948,38945,38967,38973,38982,38991,38987,39019,39023,39024,39025, -39028,39027,39082,39087,39089,39094,39108,39107,39110,39145,39147,39171,39177, -39186,39188,39192,39201,39197,39198,39204,39200,39212,39214,39229,39230,39234, -39241,39237,39248,39243,39249,39250,39244,39253,39319,39320,39333,39341,39342, -39356,39391,39387,39389,39384,39377,39405,39406,39409,39410,39419,39416,39425, -39439,39429,39394,39449,39467,39479,39493,39490,39488,39491,39486,39509,39501, -39515,39511,39519,39522,39525,39524,39529,39531,39530,39597,39600,39612,39616, -39631,39633,39635,39636,39646,39647,39650,39651,39654,39663,39659,39662,39668, -39665,39671,39675,39686,39704,39706,39711,39714,39715,39717,39719,39720,39721, -39722,39726,39727,39730,39748,39747,39759,39757,39758,39761,39768,39796,39827, -39811,39825,39830,39831,39839,39840,39848,39860,39872,39882,39865,39878,39887, -39889,39890,39907,39906,39908,39892,39905,39994,39922,39921,39920,39957,39956, -39945,39955,39948,39942,39944,39954,39946,39940,39982,39963,39973,39972,39969, -39984,40007,39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176, -40201,40200,40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210, -40257,40255,40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329, -40327,40363,40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378, -40390,40399,40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478, -40565,40569,40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617, -40632,40618,40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672, -40677,40680,40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391, -40725,40737,40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807, -40812,40810,40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956, -29081, -}; - -static const struct dbcs_index jisx0208_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0208_decmap+0,33,126},{__jisx0208_decmap -+94,33,126},{__jisx0208_decmap+188,48,122},{__jisx0208_decmap+263,33,115},{ -__jisx0208_decmap+346,33,118},{__jisx0208_decmap+432,33,88},{__jisx0208_decmap -+488,33,113},{__jisx0208_decmap+569,33,64},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{__jisx0208_decmap+601,33,126},{__jisx0208_decmap+695,33, -126},{__jisx0208_decmap+789,33,126},{__jisx0208_decmap+883,33,126},{ -__jisx0208_decmap+977,33,126},{__jisx0208_decmap+1071,33,126},{ -__jisx0208_decmap+1165,33,126},{__jisx0208_decmap+1259,33,126},{ -__jisx0208_decmap+1353,33,126},{__jisx0208_decmap+1447,33,126},{ -__jisx0208_decmap+1541,33,126},{__jisx0208_decmap+1635,33,126},{ -__jisx0208_decmap+1729,33,126},{__jisx0208_decmap+1823,33,126},{ -__jisx0208_decmap+1917,33,126},{__jisx0208_decmap+2011,33,126},{ -__jisx0208_decmap+2105,33,126},{__jisx0208_decmap+2199,33,126},{ -__jisx0208_decmap+2293,33,126},{__jisx0208_decmap+2387,33,126},{ -__jisx0208_decmap+2481,33,126},{__jisx0208_decmap+2575,33,126},{ -__jisx0208_decmap+2669,33,126},{__jisx0208_decmap+2763,33,126},{ -__jisx0208_decmap+2857,33,126},{__jisx0208_decmap+2951,33,126},{ -__jisx0208_decmap+3045,33,126},{__jisx0208_decmap+3139,33,126},{ -__jisx0208_decmap+3233,33,126},{__jisx0208_decmap+3327,33,126},{ -__jisx0208_decmap+3421,33,126},{__jisx0208_decmap+3515,33,83},{ -__jisx0208_decmap+3566,33,126},{__jisx0208_decmap+3660,33,126},{ -__jisx0208_decmap+3754,33,126},{__jisx0208_decmap+3848,33,126},{ -__jisx0208_decmap+3942,33,126},{__jisx0208_decmap+4036,33,126},{ -__jisx0208_decmap+4130,33,126},{__jisx0208_decmap+4224,33,126},{ -__jisx0208_decmap+4318,33,126},{__jisx0208_decmap+4412,33,126},{ -__jisx0208_decmap+4506,33,126},{__jisx0208_decmap+4600,33,126},{ -__jisx0208_decmap+4694,33,126},{__jisx0208_decmap+4788,33,126},{ -__jisx0208_decmap+4882,33,126},{__jisx0208_decmap+4976,33,126},{ -__jisx0208_decmap+5070,33,126},{__jisx0208_decmap+5164,33,126},{ -__jisx0208_decmap+5258,33,126},{__jisx0208_decmap+5352,33,126},{ -__jisx0208_decmap+5446,33,126},{__jisx0208_decmap+5540,33,126},{ -__jisx0208_decmap+5634,33,126},{__jisx0208_decmap+5728,33,126},{ -__jisx0208_decmap+5822,33,126},{__jisx0208_decmap+5916,33,126},{ -__jisx0208_decmap+6010,33,126},{__jisx0208_decmap+6104,33,126},{ -__jisx0208_decmap+6198,33,126},{__jisx0208_decmap+6292,33,126},{ -__jisx0208_decmap+6386,33,126},{__jisx0208_decmap+6480,33,126},{ -__jisx0208_decmap+6574,33,126},{__jisx0208_decmap+6668,33,126},{ -__jisx0208_decmap+6762,33,126},{__jisx0208_decmap+6856,33,126},{ -__jisx0208_decmap+6950,33,38},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const ucs2_t __jisx0212_decmap[6179] = { -728,711,184,729,733,175,731,730,126,900,901,U,U,U,U,U,U,U,U,161,166,191,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,186,170, -169,174,8482,164,8470,902,904,905,906,938,U,908,U,910,939,U,911,U,U,U,U,940, -941,942,943,970,912,972,962,973,971,944,974,1026,1027,1028,1029,1030,1031, -1032,1033,1034,1035,1036,1038,1039,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115, -1116,1118,1119,198,272,U,294,U,306,U,321,319,U,330,216,338,U,358,222,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,230,273,240,295,305,307,312,322,320,329,331,248,339, -223,359,254,193,192,196,194,258,461,256,260,197,195,262,264,268,199,266,270, -201,200,203,202,282,278,274,280,U,284,286,290,288,292,205,204,207,206,463,304, -298,302,296,308,310,313,317,315,323,327,325,209,211,210,214,212,465,336,332, -213,340,344,342,346,348,352,350,356,354,218,217,220,219,364,467,368,362,370, -366,360,471,475,473,469,372,221,376,374,377,381,379,225,224,228,226,259,462, -257,261,229,227,263,265,269,231,267,271,233,232,235,234,283,279,275,281,501, -285,287,U,289,293,237,236,239,238,464,U,299,303,297,309,311,314,318,316,324, -328,326,241,243,242,246,244,466,337,333,245,341,345,343,347,349,353,351,357, -355,250,249,252,251,365,468,369,363,371,367,361,472,476,474,470,373,253,255, -375,378,382,380,19970,19972,19973,19980,19986,19999,20003,20004,20008,20011, -20014,20015,20016,20021,20032,20033,20036,20039,20049,20058,20060,20067,20072, -20073,20084,20085,20089,20095,20109,20118,20119,20125,20143,20153,20163,20176, -20186,20187,20192,20193,20194,20200,20207,20209,20211,20213,20221,20222,20223, -20224,20226,20227,20232,20235,20236,20242,20245,20246,20247,20249,20270,20273, -20320,20275,20277,20279,20281,20283,20286,20288,20290,20296,20297,20299,20300, -20306,20308,20310,20312,20319,20323,20330,20332,20334,20337,20343,20344,20345, -20346,20349,20350,20353,20354,20356,20357,20361,20362,20364,20366,20368,20370, -20371,20372,20375,20377,20378,20382,20383,20402,20407,20409,20411,20412,20413, -20414,20416,20417,20421,20422,20424,20425,20427,20428,20429,20431,20434,20444, -20448,20450,20464,20466,20476,20477,20479,20480,20481,20484,20487,20490,20492, -20494,20496,20499,20503,20504,20507,20508,20509,20510,20514,20519,20526,20528, -20530,20531,20533,20544,20545,20546,20549,20550,20554,20556,20558,20561,20562, -20563,20567,20569,20575,20576,20578,20579,20582,20583,20586,20589,20592,20593, -20539,20609,20611,20612,20614,20618,20622,20623,20624,20626,20627,20628,20630, -20635,20636,20638,20639,20640,20641,20642,20650,20655,20656,20665,20666,20669, -20672,20675,20676,20679,20684,20686,20688,20691,20692,20696,20700,20701,20703, -20706,20708,20710,20712,20713,20719,20721,20726,20730,20734,20739,20742,20743, -20744,20747,20748,20749,20750,20722,20752,20759,20761,20763,20764,20765,20766, -20771,20775,20776,20780,20781,20783,20785,20787,20788,20789,20792,20793,20802, -20810,20815,20819,20821,20823,20824,20831,20836,20838,20862,20867,20868,20875, -20878,20888,20893,20897,20899,20909,20920,20922,20924,20926,20927,20930,20936, -20943,20945,20946,20947,20949,20952,20958,20962,20965,20974,20978,20979,20980, -20983,20993,20994,20997,21010,21011,21013,21014,21016,21026,21032,21041,21042, -21045,21052,21061,21065,21077,21079,21080,21082,21084,21087,21088,21089,21094, -21102,21111,21112,21113,21120,21122,21125,21130,21132,21139,21141,21142,21143, -21144,21146,21148,21156,21157,21158,21159,21167,21168,21174,21175,21176,21178, -21179,21181,21184,21188,21190,21192,21196,21199,21201,21204,21206,21211,21212, -21217,21221,21224,21225,21226,21228,21232,21233,21236,21238,21239,21248,21251, -21258,21259,21260,21265,21267,21272,21275,21276,21278,21279,21285,21287,21288, -21289,21291,21292,21293,21296,21298,21301,21308,21309,21310,21314,21324,21323, -21337,21339,21345,21347,21349,21356,21357,21362,21369,21374,21379,21383,21384, -21390,21395,21396,21401,21405,21409,21412,21418,21419,21423,21426,21428,21429, -21431,21432,21434,21437,21440,21445,21455,21458,21459,21461,21466,21469,21470, -21472,21478,21479,21493,21506,21523,21530,21537,21543,21544,21546,21551,21553, -21556,21557,21571,21572,21575,21581,21583,21598,21602,21604,21606,21607,21609, -21611,21613,21614,21620,21631,21633,21635,21637,21640,21641,21645,21649,21653, -21654,21660,21663,21665,21670,21671,21673,21674,21677,21678,21681,21687,21689, -21690,21691,21695,21702,21706,21709,21710,21728,21738,21740,21743,21750,21756, -21758,21759,21760,21761,21765,21768,21769,21772,21773,21774,21781,21802,21803, -21810,21813,21814,21819,21820,21821,21825,21831,21833,21834,21837,21840,21841, -21848,21850,21851,21854,21856,21857,21860,21862,21887,21889,21890,21894,21896, -21902,21903,21905,21906,21907,21908,21911,21923,21924,21933,21938,21951,21953, -21955,21958,21961,21963,21964,21966,21969,21970,21971,21975,21976,21979,21982, -21986,21993,22006,22015,22021,22024,22026,22029,22030,22031,22032,22033,22034, -22041,22060,22064,22067,22069,22071,22073,22075,22076,22077,22079,22080,22081, -22083,22084,22086,22089,22091,22093,22095,22100,22110,22112,22113,22114,22115, -22118,22121,22125,22127,22129,22130,22133,22148,22149,22152,22155,22156,22165, -22169,22170,22173,22174,22175,22182,22183,22184,22185,22187,22188,22189,22193, -22195,22199,22206,22213,22217,22218,22219,22223,22224,22220,22221,22233,22236, -22237,22239,22241,22244,22245,22246,22247,22248,22257,22251,22253,22262,22263, -22273,22274,22279,22282,22284,22289,22293,22298,22299,22301,22304,22306,22307, -22308,22309,22313,22314,22316,22318,22319,22323,22324,22333,22334,22335,22341, -22342,22348,22349,22354,22370,22373,22375,22376,22379,22381,22382,22383,22384, -22385,22387,22388,22389,22391,22393,22394,22395,22396,22398,22401,22403,22412, -22420,22423,22425,22426,22428,22429,22430,22431,22433,22421,22439,22440,22441, -22444,22456,22461,22471,22472,22476,22479,22485,22493,22494,22500,22502,22503, -22505,22509,22512,22517,22518,22520,22525,22526,22527,22531,22532,22536,22537, -22497,22540,22541,22555,22558,22559,22560,22566,22567,22573,22578,22585,22591, -22601,22604,22605,22607,22608,22613,22623,22625,22628,22631,22632,22648,22652, -22655,22656,22657,22663,22664,22665,22666,22668,22669,22671,22672,22676,22678, -22685,22688,22689,22690,22694,22697,22705,22706,22724,22716,22722,22728,22733, -22734,22736,22738,22740,22742,22746,22749,22753,22754,22761,22771,22789,22790, -22795,22796,22802,22803,22804,34369,22813,22817,22819,22820,22824,22831,22832, -22835,22837,22838,22847,22851,22854,22866,22867,22873,22875,22877,22878,22879, -22881,22883,22891,22893,22895,22898,22901,22902,22905,22907,22908,22923,22924, -22926,22930,22933,22935,22943,22948,22951,22957,22958,22959,22960,22963,22967, -22970,22972,22977,22979,22980,22984,22986,22989,22994,23005,23006,23007,23011, -23012,23015,23022,23023,23025,23026,23028,23031,23040,23044,23052,23053,23054, -23058,23059,23070,23075,23076,23079,23080,23082,23085,23088,23108,23109,23111, -23112,23116,23120,23125,23134,23139,23141,23143,23149,23159,23162,23163,23166, -23179,23184,23187,23190,23193,23196,23198,23199,23200,23202,23207,23212,23217, -23218,23219,23221,23224,23226,23227,23231,23236,23238,23240,23247,23258,23260, -23264,23269,23274,23278,23285,23286,23293,23296,23297,23304,23319,23348,23321, -23323,23325,23329,23333,23341,23352,23361,23371,23372,23378,23382,23390,23400, -23406,23407,23420,23421,23422,23423,23425,23428,23430,23434,23438,23440,23441, -23443,23444,23446,23464,23465,23468,23469,23471,23473,23474,23479,23482,23484, -23488,23489,23501,23503,23510,23511,23512,23513,23514,23520,23535,23537,23540, -23549,23564,23575,23582,23583,23587,23590,23593,23595,23596,23598,23600,23602, -23605,23606,23641,23642,23644,23650,23651,23655,23656,23657,23661,23664,23668, -23669,23674,23675,23676,23677,23687,23688,23690,23695,23698,23709,23711,23712, -23714,23715,23718,23722,23730,23732,23733,23738,23753,23755,23762,23773,23767, -23790,23793,23794,23796,23809,23814,23821,23826,23851,23843,23844,23846,23847, -23857,23860,23865,23869,23871,23874,23875,23878,23880,23893,23889,23897,23882, -23903,23904,23905,23906,23908,23914,23917,23920,23929,23930,23934,23935,23937, -23939,23944,23946,23954,23955,23956,23957,23961,23963,23967,23968,23975,23979, -23984,23988,23992,23993,24003,24007,24011,24016,24014,24024,24025,24032,24036, -24041,24056,24057,24064,24071,24077,24082,24084,24085,24088,24095,24096,24110, -24104,24114,24117,24126,24139,24144,24137,24145,24150,24152,24155,24156,24158, -24168,24170,24171,24172,24173,24174,24176,24192,24203,24206,24226,24228,24229, -24232,24234,24236,24241,24243,24253,24254,24255,24262,24268,24267,24270,24273, -24274,24276,24277,24284,24286,24293,24299,24322,24326,24327,24328,24334,24345, -24348,24349,24353,24354,24355,24356,24360,24363,24364,24366,24368,24372,24374, -24379,24381,24383,24384,24388,24389,24391,24397,24400,24404,24408,24411,24416, -24419,24420,24423,24431,24434,24436,24437,24440,24442,24445,24446,24457,24461, -24463,24470,24476,24477,24482,24487,24491,24484,24492,24495,24496,24497,24504, -24516,24519,24520,24521,24523,24528,24529,24530,24531,24532,24542,24545,24546, -24552,24553,24554,24556,24557,24558,24559,24562,24563,24566,24570,24572,24583, -24586,24589,24595,24596,24599,24600,24602,24607,24612,24621,24627,24629,24640, -24647,24648,24649,24652,24657,24660,24662,24663,24669,24673,24679,24689,24702, -24703,24706,24710,24712,24714,24718,24721,24723,24725,24728,24733,24734,24738, -24740,24741,24744,24752,24753,24759,24763,24766,24770,24772,24776,24777,24778, -24779,24782,24783,24788,24789,24793,24795,24797,24798,24802,24805,24818,24821, -24824,24828,24829,24834,24839,24842,24844,24848,24849,24850,24851,24852,24854, -24855,24857,24860,24862,24866,24874,24875,24880,24881,24885,24886,24887,24889, -24897,24901,24902,24905,24926,24928,24940,24946,24952,24955,24956,24959,24960, -24961,24963,24964,24971,24973,24978,24979,24983,24984,24988,24989,24991,24992, -24997,25000,25002,25005,25016,25017,25020,25024,25025,25026,25038,25039,25045, -25052,25053,25054,25055,25057,25058,25063,25065,25061,25068,25069,25071,25089, -25091,25092,25095,25107,25109,25116,25120,25122,25123,25127,25129,25131,25145, -25149,25154,25155,25156,25158,25164,25168,25169,25170,25172,25174,25178,25180, -25188,25197,25199,25203,25210,25213,25229,25230,25231,25232,25254,25256,25267, -25270,25271,25274,25278,25279,25284,25294,25301,25302,25306,25322,25330,25332, -25340,25341,25347,25348,25354,25355,25357,25360,25363,25366,25368,25385,25386, -25389,25397,25398,25401,25404,25409,25410,25411,25412,25414,25418,25419,25422, -25426,25427,25428,25432,25435,25445,25446,25452,25453,25457,25460,25461,25464, -25468,25469,25471,25474,25476,25479,25482,25488,25492,25493,25497,25498,25502, -25508,25510,25517,25518,25519,25533,25537,25541,25544,25550,25553,25555,25556, -25557,25564,25568,25573,25578,25580,25586,25587,25589,25592,25593,25609,25610, -25616,25618,25620,25624,25630,25632,25634,25636,25637,25641,25642,25647,25648, -25653,25661,25663,25675,25679,25681,25682,25683,25684,25690,25691,25692,25693, -25695,25696,25697,25699,25709,25715,25716,25723,25725,25733,25735,25743,25744, -25745,25752,25753,25755,25757,25759,25761,25763,25766,25768,25772,25779,25789, -25790,25791,25796,25801,25802,25803,25804,25806,25808,25809,25813,25815,25828, -25829,25833,25834,25837,25840,25845,25847,25851,25855,25857,25860,25864,25865, -25866,25871,25875,25876,25878,25881,25883,25886,25887,25890,25894,25897,25902, -25905,25914,25916,25917,25923,25927,25929,25936,25938,25940,25951,25952,25959, -25963,25978,25981,25985,25989,25994,26002,26005,26008,26013,26016,26019,26022, -26030,26034,26035,26036,26047,26050,26056,26057,26062,26064,26068,26070,26072, -26079,26096,26098,26100,26101,26105,26110,26111,26112,26116,26120,26121,26125, -26129,26130,26133,26134,26141,26142,26145,26146,26147,26148,26150,26153,26154, -26155,26156,26158,26160,26161,26163,26169,26167,26176,26181,26182,26186,26188, -26193,26190,26199,26200,26201,26203,26204,26208,26209,26363,26218,26219,26220, -26238,26227,26229,26239,26231,26232,26233,26235,26240,26236,26251,26252,26253, -26256,26258,26265,26266,26267,26268,26271,26272,26276,26285,26289,26290,26293, -26299,26303,26304,26306,26307,26312,26316,26318,26319,26324,26331,26335,26344, -26347,26348,26350,26362,26373,26375,26382,26387,26393,26396,26400,26402,26419, -26430,26437,26439,26440,26444,26452,26453,26461,26470,26476,26478,26484,26486, -26491,26497,26500,26510,26511,26513,26515,26518,26520,26521,26523,26544,26545, -26546,26549,26555,26556,26557,26617,26560,26562,26563,26565,26568,26569,26578, -26583,26585,26588,26593,26598,26608,26610,26614,26615,26706,26644,26649,26653, -26655,26664,26663,26668,26669,26671,26672,26673,26675,26683,26687,26692,26693, -26698,26700,26709,26711,26712,26715,26731,26734,26735,26736,26737,26738,26741, -26745,26746,26747,26748,26754,26756,26758,26760,26774,26776,26778,26780,26785, -26787,26789,26793,26794,26798,26802,26811,26821,26824,26828,26831,26832,26833, -26835,26838,26841,26844,26845,26853,26856,26858,26859,26860,26861,26864,26865, -26869,26870,26875,26876,26877,26886,26889,26890,26896,26897,26899,26902,26903, -26929,26931,26933,26936,26939,26946,26949,26953,26958,26967,26971,26979,26980, -26981,26982,26984,26985,26988,26992,26993,26994,27002,27003,27007,27008,27021, -27026,27030,27032,27041,27045,27046,27048,27051,27053,27055,27063,27064,27066, -27068,27077,27080,27089,27094,27095,27106,27109,27118,27119,27121,27123,27125, -27134,27136,27137,27139,27151,27153,27157,27162,27165,27168,27172,27176,27184, -27186,27188,27191,27195,27198,27199,27205,27206,27209,27210,27214,27216,27217, -27218,27221,27222,27227,27236,27239,27242,27249,27251,27262,27265,27267,27270, -27271,27273,27275,27281,27291,27293,27294,27295,27301,27307,27311,27312,27313, -27316,27325,27326,27327,27334,27337,27336,27340,27344,27348,27349,27350,27356, -27357,27364,27367,27372,27376,27377,27378,27388,27389,27394,27395,27398,27399, -27401,27407,27408,27409,27415,27419,27422,27428,27432,27435,27436,27439,27445, -27446,27451,27455,27462,27466,27469,27474,27478,27480,27485,27488,27495,27499, -27502,27504,27509,27517,27518,27522,27525,27543,27547,27551,27552,27554,27555, -27560,27561,27564,27565,27566,27568,27576,27577,27581,27582,27587,27588,27593, -27596,27606,27610,27617,27619,27622,27623,27630,27633,27639,27641,27647,27650, -27652,27653,27657,27661,27662,27664,27666,27673,27679,27686,27687,27688,27692, -27694,27699,27701,27702,27706,27707,27711,27722,27723,27725,27727,27730,27732, -27737,27739,27740,27755,27757,27759,27764,27766,27768,27769,27771,27781,27782, -27783,27785,27796,27797,27799,27800,27804,27807,27824,27826,27828,27842,27846, -27853,27855,27856,27857,27858,27860,27862,27866,27868,27872,27879,27881,27883, -27884,27886,27890,27892,27908,27911,27914,27918,27919,27921,27923,27930,27942, -27943,27944,27751,27950,27951,27953,27961,27964,27967,27991,27998,27999,28001, -28005,28007,28015,28016,28028,28034,28039,28049,28050,28052,28054,28055,28056, -28074,28076,28084,28087,28089,28093,28095,28100,28104,28106,28110,28111,28118, -28123,28125,28127,28128,28130,28133,28137,28143,28144,28148,28150,28156,28160, -28164,28190,28194,28199,28210,28214,28217,28219,28220,28228,28229,28232,28233, -28235,28239,28241,28242,28243,28244,28247,28252,28253,28254,28258,28259,28264, -28275,28283,28285,28301,28307,28313,28320,28327,28333,28334,28337,28339,28347, -28351,28352,28353,28355,28359,28360,28362,28365,28366,28367,28395,28397,28398, -28409,28411,28413,28420,28424,28426,28428,28429,28438,28440,28442,28443,28454, -28457,28458,28463,28464,28467,28470,28475,28476,28461,28495,28497,28498,28499, -28503,28505,28506,28509,28510,28513,28514,28520,28524,28541,28542,28547,28551, -28552,28555,28556,28557,28560,28562,28563,28564,28566,28570,28575,28576,28581, -28582,28583,28584,28590,28591,28592,28597,28598,28604,28613,28615,28616,28618, -28634,28638,28648,28649,28656,28661,28665,28668,28669,28672,28677,28678,28679, -28685,28695,28704,28707,28719,28724,28727,28729,28732,28739,28740,28744,28745, -28746,28747,28756,28757,28765,28766,28750,28772,28773,28780,28782,28789,28790, -28798,28801,28805,28806,28820,28821,28822,28823,28824,28827,28836,28843,28848, -28849,28852,28855,28874,28881,28883,28884,28885,28886,28888,28892,28900,28922, -28931,28932,28933,28934,28935,28939,28940,28943,28958,28960,28971,28973,28975, -28976,28977,28984,28993,28997,28998,28999,29002,29003,29008,29010,29015,29018, -29020,29022,29024,29032,29049,29056,29061,29063,29068,29074,29082,29083,29088, -29090,29103,29104,29106,29107,29114,29119,29120,29121,29124,29131,29132,29139, -29142,29145,29146,29148,29176,29182,29184,29191,29192,29193,29203,29207,29210, -29213,29215,29220,29227,29231,29236,29240,29241,29249,29250,29251,29253,29262, -29263,29264,29267,29269,29270,29274,29276,29278,29280,29283,29288,29291,29294, -29295,29297,29303,29304,29307,29308,29311,29316,29321,29325,29326,29331,29339, -29352,29357,29358,29361,29364,29374,29377,29383,29385,29388,29397,29398,29400, -29407,29413,29427,29428,29434,29435,29438,29442,29444,29445,29447,29451,29453, -29458,29459,29464,29465,29470,29474,29476,29479,29480,29484,29489,29490,29493, -29498,29499,29501,29507,29517,29520,29522,29526,29528,29533,29534,29535,29536, -29542,29543,29545,29547,29548,29550,29551,29553,29559,29561,29564,29568,29569, -29571,29573,29574,29582,29584,29587,29589,29591,29592,29596,29598,29599,29600, -29602,29605,29606,29610,29611,29613,29621,29623,29625,29628,29629,29631,29637, -29638,29641,29643,29644,29647,29650,29651,29654,29657,29661,29665,29667,29670, -29671,29673,29684,29685,29687,29689,29690,29691,29693,29695,29696,29697,29700, -29703,29706,29713,29722,29723,29732,29734,29736,29737,29738,29739,29740,29741, -29742,29743,29744,29745,29753,29760,29763,29764,29766,29767,29771,29773,29777, -29778,29783,29789,29794,29798,29799,29800,29803,29805,29806,29809,29810,29824, -29825,29829,29830,29831,29833,29839,29840,29841,29842,29848,29849,29850,29852, -29855,29856,29857,29859,29862,29864,29865,29866,29867,29870,29871,29873,29874, -29877,29881,29883,29887,29896,29897,29900,29904,29907,29912,29914,29915,29918, -29919,29924,29928,29930,29931,29935,29940,29946,29947,29948,29951,29958,29970, -29974,29975,29984,29985,29988,29991,29993,29994,29999,30006,30009,30013,30014, -30015,30016,30019,30023,30024,30030,30032,30034,30039,30046,30047,30049,30063, -30065,30073,30074,30075,30076,30077,30078,30081,30085,30096,30098,30099,30101, -30105,30108,30114,30116,30132,30138,30143,30144,30145,30148,30150,30156,30158, -30159,30167,30172,30175,30176,30177,30180,30183,30188,30190,30191,30193,30201, -30208,30210,30211,30212,30215,30216,30218,30220,30223,30226,30227,30229,30230, -30233,30235,30236,30237,30238,30243,30245,30246,30249,30253,30258,30259,30261, -30264,30265,30266,30268,30282,30272,30273,30275,30276,30277,30281,30283,30293, -30297,30303,30308,30309,30317,30318,30319,30321,30324,30337,30341,30348,30349, -30357,30363,30364,30365,30367,30368,30370,30371,30372,30373,30374,30375,30376, -30378,30381,30397,30401,30405,30409,30411,30412,30414,30420,30425,30432,30438, -30440,30444,30448,30449,30454,30457,30460,30464,30470,30474,30478,30482,30484, -30485,30487,30489,30490,30492,30498,30504,30509,30510,30511,30516,30517,30518, -30521,30525,30526,30530,30533,30534,30538,30541,30542,30543,30546,30550,30551, -30556,30558,30559,30560,30562,30564,30567,30570,30572,30576,30578,30579,30580, -30586,30589,30592,30596,30604,30605,30612,30613,30614,30618,30623,30626,30631, -30634,30638,30639,30641,30645,30654,30659,30665,30673,30674,30677,30681,30686, -30687,30688,30692,30694,30698,30700,30704,30705,30708,30712,30715,30725,30726, -30729,30733,30734,30737,30749,30753,30754,30755,30765,30766,30768,30773,30775, -30787,30788,30791,30792,30796,30798,30802,30812,30814,30816,30817,30819,30820, -30824,30826,30830,30842,30846,30858,30863,30868,30872,30881,30877,30878,30879, -30884,30888,30892,30893,30896,30897,30898,30899,30907,30909,30911,30919,30920, -30921,30924,30926,30930,30931,30933,30934,30948,30939,30943,30944,30945,30950, -30954,30962,30963,30976,30966,30967,30970,30971,30975,30982,30988,30992,31002, -31004,31006,31007,31008,31013,31015,31017,31021,31025,31028,31029,31035,31037, -31039,31044,31045,31046,31050,31051,31055,31057,31060,31064,31067,31068,31079, -31081,31083,31090,31097,31099,31100,31102,31115,31116,31121,31123,31124,31125, -31126,31128,31131,31132,31137,31144,31145,31147,31151,31153,31156,31160,31163, -31170,31172,31175,31176,31178,31183,31188,31190,31194,31197,31198,31200,31202, -31205,31210,31211,31213,31217,31224,31228,31234,31235,31239,31241,31242,31244, -31249,31253,31259,31262,31265,31271,31275,31277,31279,31280,31284,31285,31288, -31289,31290,31300,31301,31303,31304,31308,31317,31318,31321,31324,31325,31327, -31328,31333,31335,31338,31341,31349,31352,31358,31360,31362,31365,31366,31370, -31371,31376,31377,31380,31390,31392,31395,31404,31411,31413,31417,31419,31420, -31430,31433,31436,31438,31441,31451,31464,31465,31467,31468,31473,31476,31483, -31485,31486,31495,31508,31519,31523,31527,31529,31530,31531,31533,31534,31535, -31536,31537,31540,31549,31551,31552,31553,31559,31566,31573,31584,31588,31590, -31593,31594,31597,31599,31602,31603,31607,31620,31625,31630,31632,31633,31638, -31643,31646,31648,31653,31660,31663,31664,31666,31669,31670,31674,31675,31676, -31677,31682,31685,31688,31690,31700,31702,31703,31705,31706,31707,31720,31722, -31730,31732,31733,31736,31737,31738,31740,31742,31745,31746,31747,31748,31750, -31753,31755,31756,31758,31759,31769,31771,31776,31781,31782,31784,31788,31793, -31795,31796,31798,31801,31802,31814,31818,31829,31825,31826,31827,31833,31834, -31835,31836,31837,31838,31841,31843,31847,31849,31853,31854,31856,31858,31865, -31868,31869,31878,31879,31887,31892,31902,31904,31910,31920,31926,31927,31930, -31931,31932,31935,31940,31943,31944,31945,31949,31951,31955,31956,31957,31959, -31961,31962,31965,31974,31977,31979,31989,32003,32007,32008,32009,32015,32017, -32018,32019,32022,32029,32030,32035,32038,32042,32045,32049,32060,32061,32062, -32064,32065,32071,32072,32077,32081,32083,32087,32089,32090,32092,32093,32101, -32103,32106,32112,32120,32122,32123,32127,32129,32130,32131,32133,32134,32136, -32139,32140,32141,32145,32150,32151,32157,32158,32166,32167,32170,32179,32182, -32183,32185,32194,32195,32196,32197,32198,32204,32205,32206,32215,32217,32256, -32226,32229,32230,32234,32235,32237,32241,32245,32246,32249,32250,32264,32272, -32273,32277,32279,32284,32285,32288,32295,32296,32300,32301,32303,32307,32310, -32319,32324,32325,32327,32334,32336,32338,32344,32351,32353,32354,32357,32363, -32366,32367,32371,32376,32382,32385,32390,32391,32394,32397,32401,32405,32408, -32410,32413,32414,32572,32571,32573,32574,32575,32579,32580,32583,32591,32594, -32595,32603,32604,32605,32609,32611,32612,32613,32614,32621,32625,32637,32638, -32639,32640,32651,32653,32655,32656,32657,32662,32663,32668,32673,32674,32678, -32682,32685,32692,32700,32703,32704,32707,32712,32718,32719,32731,32735,32739, -32741,32744,32748,32750,32751,32754,32762,32765,32766,32767,32775,32776,32778, -32781,32782,32783,32785,32787,32788,32790,32797,32798,32799,32800,32804,32806, -32812,32814,32816,32820,32821,32823,32825,32826,32828,32830,32832,32836,32864, -32868,32870,32877,32881,32885,32897,32904,32910,32924,32926,32934,32935,32939, -32952,32953,32968,32973,32975,32978,32980,32981,32983,32984,32992,33005,33006, -33008,33010,33011,33014,33017,33018,33022,33027,33035,33046,33047,33048,33052, -33054,33056,33060,33063,33068,33072,33077,33082,33084,33093,33095,33098,33100, -33106,33111,33120,33121,33127,33128,33129,33133,33135,33143,33153,33168,33156, -33157,33158,33163,33166,33174,33176,33179,33182,33186,33198,33202,33204,33211, -33227,33219,33221,33226,33230,33231,33237,33239,33243,33245,33246,33249,33252, -33259,33260,33264,33265,33266,33269,33270,33272,33273,33277,33279,33280,33283, -33295,33299,33300,33305,33306,33309,33313,33314,33320,33330,33332,33338,33347, -33348,33349,33350,33355,33358,33359,33361,33366,33372,33376,33379,33383,33389, -33396,33403,33405,33407,33408,33409,33411,33412,33415,33417,33418,33422,33425, -33428,33430,33432,33434,33435,33440,33441,33443,33444,33447,33448,33449,33450, -33454,33456,33458,33460,33463,33466,33468,33470,33471,33478,33488,33493,33498, -33504,33506,33508,33512,33514,33517,33519,33526,33527,33533,33534,33536,33537, -33543,33544,33546,33547,33620,33563,33565,33566,33567,33569,33570,33580,33581, -33582,33584,33587,33591,33594,33596,33597,33602,33603,33604,33607,33613,33614, -33617,33621,33622,33623,33648,33656,33661,33663,33664,33666,33668,33670,33677, -33682,33684,33685,33688,33689,33691,33692,33693,33702,33703,33705,33708,33726, -33727,33728,33735,33737,33743,33744,33745,33748,33757,33619,33768,33770,33782, -33784,33785,33788,33793,33798,33802,33807,33809,33813,33817,33709,33839,33849, -33861,33863,33864,33866,33869,33871,33873,33874,33878,33880,33881,33882,33884, -33888,33892,33893,33895,33898,33904,33907,33908,33910,33912,33916,33917,33921, -33925,33938,33939,33941,33950,33958,33960,33961,33962,33967,33969,33972,33978, -33981,33982,33984,33986,33991,33992,33996,33999,34003,34012,34023,34026,34031, -34032,34033,34034,34039,34098,34042,34043,34045,34050,34051,34055,34060,34062, -34064,34076,34078,34082,34083,34084,34085,34087,34090,34091,34095,34099,34100, -34102,34111,34118,34127,34128,34129,34130,34131,34134,34137,34140,34141,34142, -34143,34144,34145,34146,34148,34155,34159,34169,34170,34171,34173,34175,34177, -34181,34182,34185,34187,34188,34191,34195,34200,34205,34207,34208,34210,34213, -34215,34228,34230,34231,34232,34236,34237,34238,34239,34242,34247,34250,34251, -34254,34221,34264,34266,34271,34272,34278,34280,34285,34291,34294,34300,34303, -34304,34308,34309,34317,34318,34320,34321,34322,34328,34329,34331,34334,34337, -34343,34345,34358,34360,34362,34364,34365,34368,34370,34374,34386,34387,34390, -34391,34392,34393,34397,34400,34401,34402,34403,34404,34409,34412,34415,34421, -34422,34423,34426,34445,34449,34454,34456,34458,34460,34465,34470,34471,34472, -34477,34481,34483,34484,34485,34487,34488,34489,34495,34496,34497,34499,34501, -34513,34514,34517,34519,34522,34524,34528,34531,34533,34535,34440,34554,34556, -34557,34564,34565,34567,34571,34574,34575,34576,34579,34580,34585,34590,34591, -34593,34595,34600,34606,34607,34609,34610,34617,34618,34620,34621,34622,34624, -34627,34629,34637,34648,34653,34657,34660,34661,34671,34673,34674,34683,34691, -34692,34693,34694,34695,34696,34697,34699,34700,34704,34707,34709,34711,34712, -34713,34718,34720,34723,34727,34732,34733,34734,34737,34741,34750,34751,34753, -34760,34761,34762,34766,34773,34774,34777,34778,34780,34783,34786,34787,34788, -34794,34795,34797,34801,34803,34808,34810,34815,34817,34819,34822,34825,34826, -34827,34832,34841,34834,34835,34836,34840,34842,34843,34844,34846,34847,34856, -34861,34862,34864,34866,34869,34874,34876,34881,34883,34885,34888,34889,34890, -34891,34894,34897,34901,34902,34904,34906,34908,34911,34912,34916,34921,34929, -34937,34939,34944,34968,34970,34971,34972,34975,34976,34984,34986,35002,35005, -35006,35008,35018,35019,35020,35021,35022,35025,35026,35027,35035,35038,35047, -35055,35056,35057,35061,35063,35073,35078,35085,35086,35087,35093,35094,35096, -35097,35098,35100,35104,35110,35111,35112,35120,35121,35122,35125,35129,35130, -35134,35136,35138,35141,35142,35145,35151,35154,35159,35162,35163,35164,35169, -35170,35171,35179,35182,35184,35187,35189,35194,35195,35196,35197,35209,35213, -35216,35220,35221,35227,35228,35231,35232,35237,35248,35252,35253,35254,35255, -35260,35284,35285,35286,35287,35288,35301,35305,35307,35309,35313,35315,35318, -35321,35325,35327,35332,35333,35335,35343,35345,35346,35348,35349,35358,35360, -35362,35364,35366,35371,35372,35375,35381,35383,35389,35390,35392,35395,35397, -35399,35401,35405,35406,35411,35414,35415,35416,35420,35421,35425,35429,35431, -35445,35446,35447,35449,35450,35451,35454,35455,35456,35459,35462,35467,35471, -35472,35474,35478,35479,35481,35487,35495,35497,35502,35503,35507,35510,35511, -35515,35518,35523,35526,35528,35529,35530,35537,35539,35540,35541,35543,35549, -35551,35564,35568,35572,35573,35574,35580,35583,35589,35590,35595,35601,35612, -35614,35615,35594,35629,35632,35639,35644,35650,35651,35652,35653,35654,35656, -35666,35667,35668,35673,35661,35678,35683,35693,35702,35704,35705,35708,35710, -35713,35716,35717,35723,35725,35727,35732,35733,35740,35742,35743,35896,35897, -35901,35902,35909,35911,35913,35915,35919,35921,35923,35924,35927,35928,35931, -35933,35929,35939,35940,35942,35944,35945,35949,35955,35957,35958,35963,35966, -35974,35975,35979,35984,35986,35987,35993,35995,35996,36004,36025,36026,36037, -36038,36041,36043,36047,36054,36053,36057,36061,36065,36072,36076,36079,36080, -36082,36085,36087,36088,36094,36095,36097,36099,36105,36114,36119,36123,36197, -36201,36204,36206,36223,36226,36228,36232,36237,36240,36241,36245,36254,36255, -36256,36262,36267,36268,36271,36274,36277,36279,36281,36283,36288,36293,36294, -36295,36296,36298,36302,36305,36308,36309,36311,36313,36324,36325,36327,36332, -36336,36284,36337,36338,36340,36349,36353,36356,36357,36358,36363,36369,36372, -36374,36384,36385,36386,36387,36390,36391,36401,36403,36406,36407,36408,36409, -36413,36416,36417,36427,36429,36430,36431,36436,36443,36444,36445,36446,36449, -36450,36457,36460,36461,36463,36464,36465,36473,36474,36475,36482,36483,36489, -36496,36498,36501,36506,36507,36509,36510,36514,36519,36521,36525,36526,36531, -36533,36538,36539,36544,36545,36547,36548,36551,36559,36561,36564,36572,36584, -36590,36592,36593,36599,36601,36602,36589,36608,36610,36615,36616,36623,36624, -36630,36631,36632,36638,36640,36641,36643,36645,36647,36648,36652,36653,36654, -36660,36661,36662,36663,36666,36672,36673,36675,36679,36687,36689,36690,36691, -36692,36693,36696,36701,36702,36709,36765,36768,36769,36772,36773,36774,36789, -36790,36792,36798,36800,36801,36806,36810,36811,36813,36816,36818,36819,36821, -36832,36835,36836,36840,36846,36849,36853,36854,36859,36862,36866,36868,36872, -36876,36888,36891,36904,36905,36911,36906,36908,36909,36915,36916,36919,36927, -36931,36932,36940,36955,36957,36962,36966,36967,36972,36976,36980,36985,36997, -37000,37003,37004,37006,37008,37013,37015,37016,37017,37019,37024,37025,37026, -37029,37040,37042,37043,37044,37046,37053,37068,37054,37059,37060,37061,37063, -37064,37077,37079,37080,37081,37084,37085,37087,37093,37074,37110,37099,37103, -37104,37108,37118,37119,37120,37124,37125,37126,37128,37133,37136,37140,37142, -37143,37144,37146,37148,37150,37152,37157,37154,37155,37159,37161,37166,37167, -37169,37172,37174,37175,37177,37178,37180,37181,37187,37191,37192,37199,37203, -37207,37209,37210,37211,37217,37220,37223,37229,37236,37241,37242,37243,37249, -37251,37253,37254,37258,37262,37265,37267,37268,37269,37272,37278,37281,37286, -37288,37292,37293,37294,37296,37297,37298,37299,37302,37307,37308,37309,37311, -37314,37315,37317,37331,37332,37335,37337,37338,37342,37348,37349,37353,37354, -37356,37357,37358,37359,37360,37361,37367,37369,37371,37373,37376,37377,37380, -37381,37382,37383,37385,37386,37388,37392,37394,37395,37398,37400,37404,37405, -37411,37412,37413,37414,37416,37422,37423,37424,37427,37429,37430,37432,37433, -37434,37436,37438,37440,37442,37443,37446,37447,37450,37453,37454,37455,37457, -37464,37465,37468,37469,37472,37473,37477,37479,37480,37481,37486,37487,37488, -37493,37494,37495,37496,37497,37499,37500,37501,37503,37512,37513,37514,37517, -37518,37522,37527,37529,37535,37536,37540,37541,37543,37544,37547,37551,37554, -37558,37560,37562,37563,37564,37565,37567,37568,37569,37570,37571,37573,37574, -37575,37576,37579,37580,37581,37582,37584,37587,37589,37591,37592,37593,37596, -37597,37599,37600,37601,37603,37605,37607,37608,37612,37614,37616,37625,37627, -37631,37632,37634,37640,37645,37649,37652,37653,37660,37661,37662,37663,37665, -37668,37669,37671,37673,37674,37683,37684,37686,37687,37703,37704,37705,37712, -37713,37714,37717,37719,37720,37722,37726,37732,37733,37735,37737,37738,37741, -37743,37744,37745,37747,37748,37750,37754,37757,37759,37760,37761,37762,37768, -37770,37771,37773,37775,37778,37781,37784,37787,37790,37793,37795,37796,37798, -37800,37803,37812,37813,37814,37818,37801,37825,37828,37829,37830,37831,37833, -37834,37835,37836,37837,37843,37849,37852,37854,37855,37858,37862,37863,37881, -37879,37880,37882,37883,37885,37889,37890,37892,37896,37897,37901,37902,37903, -37909,37910,37911,37919,37934,37935,37937,37938,37939,37940,37947,37951,37949, -37955,37957,37960,37962,37964,37973,37977,37980,37983,37985,37987,37992,37995, -37997,37998,37999,38001,38002,38020,38019,38264,38265,38270,38276,38280,38284, -38285,38286,38301,38302,38303,38305,38310,38313,38315,38316,38324,38326,38330, -38333,38335,38342,38344,38345,38347,38352,38353,38354,38355,38361,38362,38365, -38366,38367,38368,38372,38374,38429,38430,38434,38436,38437,38438,38444,38449, -38451,38455,38456,38457,38458,38460,38461,38465,38482,38484,38486,38487,38488, -38497,38510,38516,38523,38524,38526,38527,38529,38530,38531,38532,38537,38545, -38550,38554,38557,38559,38564,38565,38566,38569,38574,38575,38579,38586,38602, -38610,23986,38616,38618,38621,38622,38623,38633,38639,38641,38650,38658,38659, -38661,38665,38682,38683,38685,38689,38690,38691,38696,38705,38707,38721,38723, -38730,38734,38735,38741,38743,38744,38746,38747,38755,38759,38762,38766,38771, -38774,38775,38776,38779,38781,38783,38784,38793,38805,38806,38807,38809,38810, -38814,38815,38818,38828,38830,38833,38834,38837,38838,38840,38841,38842,38844, -38846,38847,38849,38852,38853,38855,38857,38858,38860,38861,38862,38864,38865, -38868,38871,38872,38873,38877,38878,38880,38875,38881,38884,38895,38897,38900, -38903,38904,38906,38919,38922,38937,38925,38926,38932,38934,38940,38942,38944, -38947,38950,38955,38958,38959,38960,38962,38963,38965,38949,38974,38980,38983, -38986,38993,38994,38995,38998,38999,39001,39002,39010,39011,39013,39014,39018, -39020,39083,39085,39086,39088,39092,39095,39096,39098,39099,39103,39106,39109, -39112,39116,39137,39139,39141,39142,39143,39146,39155,39158,39170,39175,39176, -39185,39189,39190,39191,39194,39195,39196,39199,39202,39206,39207,39211,39217, -39218,39219,39220,39221,39225,39226,39227,39228,39232,39233,39238,39239,39240, -39245,39246,39252,39256,39257,39259,39260,39262,39263,39264,39323,39325,39327, -39334,39344,39345,39346,39349,39353,39354,39357,39359,39363,39369,39379,39380, -39385,39386,39388,39390,39399,39402,39403,39404,39408,39412,39413,39417,39421, -39422,39426,39427,39428,39435,39436,39440,39441,39446,39454,39456,39458,39459, -39460,39463,39469,39470,39475,39477,39478,39480,39495,39489,39492,39498,39499, -39500,39502,39505,39508,39510,39517,39594,39596,39598,39599,39602,39604,39605, -39606,39609,39611,39614,39615,39617,39619,39622,39624,39630,39632,39634,39637, -39638,39639,39643,39644,39648,39652,39653,39655,39657,39660,39666,39667,39669, -39673,39674,39677,39679,39680,39681,39682,39683,39684,39685,39688,39689,39691, -39692,39693,39694,39696,39698,39702,39705,39707,39708,39712,39718,39723,39725, -39731,39732,39733,39735,39737,39738,39741,39752,39755,39756,39765,39766,39767, -39771,39774,39777,39779,39781,39782,39784,39786,39787,39788,39789,39790,39795, -39797,39799,39800,39801,39807,39808,39812,39813,39814,39815,39817,39818,39819, -39821,39823,39824,39828,39834,39837,39838,39846,39847,39849,39852,39856,39857, -39858,39863,39864,39867,39868,39870,39871,39873,39879,39880,39886,39888,39895, -39896,39901,39903,39909,39911,39914,39915,39919,39923,39927,39928,39929,39930, -39933,39935,39936,39938,39947,39951,39953,39958,39960,39961,39962,39964,39966, -39970,39971,39974,39975,39976,39977,39978,39985,39989,39990,39991,39997,40001, -40003,40004,40005,40009,40010,40014,40015,40016,40019,40020,40022,40024,40027, -40029,40030,40031,40035,40041,40042,40028,40043,40040,40046,40048,40050,40053, -40055,40059,40166,40178,40183,40185,40203,40194,40209,40215,40216,40220,40221, -40222,40239,40240,40242,40243,40244,40250,40252,40261,40253,40258,40259,40263, -40266,40275,40276,40287,40291,40290,40293,40297,40298,40299,40304,40310,40311, -40315,40316,40318,40323,40324,40326,40330,40333,40334,40338,40339,40341,40342, -40343,40344,40353,40362,40364,40366,40369,40373,40377,40380,40383,40387,40391, -40393,40394,40404,40405,40406,40407,40410,40414,40415,40416,40421,40423,40425, -40427,40430,40432,40435,40436,40446,40458,40450,40455,40462,40464,40465,40466, -40469,40470,40473,40476,40477,40570,40571,40572,40576,40578,40579,40580,40581, -40583,40590,40591,40598,40600,40603,40606,40612,40616,40620,40622,40623,40624, -40627,40628,40629,40646,40648,40651,40661,40671,40676,40679,40684,40685,40686, -40688,40689,40690,40693,40696,40703,40706,40707,40713,40719,40720,40721,40722, -40724,40726,40727,40729,40730,40731,40735,40738,40742,40746,40747,40751,40753, -40754,40756,40759,40761,40762,40764,40765,40767,40769,40771,40772,40773,40774, -40775,40787,40789,40790,40791,40792,40794,40797,40798,40808,40809,40813,40814, -40815,40816,40817,40819,40821,40826,40829,40847,40848,40849,40850,40852,40854, -40855,40862,40865,40866,40867,40869, -}; - -static const struct dbcs_index jisx0212_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0212_decmap+0,47,113},{0,0,0},{ -0,0,0},{0,0,0},{__jisx0212_decmap+67,97,124},{__jisx0212_decmap+95,66,126},{0, -0,0},{__jisx0212_decmap+156,33,80},{__jisx0212_decmap+204,33,119},{ -__jisx0212_decmap+291,33,119},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__jisx0212_decmap+378,33,126},{__jisx0212_decmap+472,33,126},{ -__jisx0212_decmap+566,33,126},{__jisx0212_decmap+660,33,126},{ -__jisx0212_decmap+754,33,126},{__jisx0212_decmap+848,33,126},{ -__jisx0212_decmap+942,33,126},{__jisx0212_decmap+1036,33,126},{ -__jisx0212_decmap+1130,33,126},{__jisx0212_decmap+1224,33,126},{ -__jisx0212_decmap+1318,33,126},{__jisx0212_decmap+1412,33,126},{ -__jisx0212_decmap+1506,33,126},{__jisx0212_decmap+1600,33,126},{ -__jisx0212_decmap+1694,33,126},{__jisx0212_decmap+1788,33,126},{ -__jisx0212_decmap+1882,33,126},{__jisx0212_decmap+1976,33,126},{ -__jisx0212_decmap+2070,33,126},{__jisx0212_decmap+2164,33,126},{ -__jisx0212_decmap+2258,33,126},{__jisx0212_decmap+2352,33,126},{ -__jisx0212_decmap+2446,33,126},{__jisx0212_decmap+2540,33,126},{ -__jisx0212_decmap+2634,33,126},{__jisx0212_decmap+2728,33,126},{ -__jisx0212_decmap+2822,33,126},{__jisx0212_decmap+2916,33,126},{ -__jisx0212_decmap+3010,33,126},{__jisx0212_decmap+3104,33,126},{ -__jisx0212_decmap+3198,33,126},{__jisx0212_decmap+3292,33,126},{ -__jisx0212_decmap+3386,33,126},{__jisx0212_decmap+3480,33,126},{ -__jisx0212_decmap+3574,33,126},{__jisx0212_decmap+3668,33,126},{ -__jisx0212_decmap+3762,33,126},{__jisx0212_decmap+3856,33,126},{ -__jisx0212_decmap+3950,33,126},{__jisx0212_decmap+4044,33,126},{ -__jisx0212_decmap+4138,33,126},{__jisx0212_decmap+4232,33,126},{ -__jisx0212_decmap+4326,33,126},{__jisx0212_decmap+4420,33,126},{ -__jisx0212_decmap+4514,33,126},{__jisx0212_decmap+4608,33,126},{ -__jisx0212_decmap+4702,33,126},{__jisx0212_decmap+4796,33,126},{ -__jisx0212_decmap+4890,33,126},{__jisx0212_decmap+4984,33,126},{ -__jisx0212_decmap+5078,33,126},{__jisx0212_decmap+5172,33,126},{ -__jisx0212_decmap+5266,33,126},{__jisx0212_decmap+5360,33,126},{ -__jisx0212_decmap+5454,33,126},{__jisx0212_decmap+5548,33,126},{ -__jisx0212_decmap+5642,33,126},{__jisx0212_decmap+5736,33,126},{ -__jisx0212_decmap+5830,33,126},{__jisx0212_decmap+5924,33,126},{ -__jisx0212_decmap+6018,33,126},{__jisx0212_decmap+6112,33,99},{0,0,0},{0,0,0}, -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const DBCHAR __jisxcommon_encmap[22016] = { -8512,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41527, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41538, -8561,8562,41584,N,41539,8568,8495,41581,41580,N,8780,N,41582,41524,8555,8542, -N,N,8493,N,8825,N,41521,N,41579,N,N,N,N,41540,43554,43553,43556,43562,43555, -43561,43297,43566,43570,43569,43572,43571,43584,43583,43586,43585,N,43600, -43602,43601,43604,43608,43603,8543,43308,43619,43618,43621,43620,43634,43312, -43342,43810,43809,43812,43818,43811,43817,43329,43822,43826,43825,43828,43827, -43840,43839,43842,43841,43331,43856,43858,43857,43860,43864,43859,8544,43340, -43875,43874,43877,43876,43890,43344,43891,43559,43815,43557,43813,43560,43816, -43563,43819,43564,43820,43567,43823,43565,43821,43568,43824,43298,43330,43575, -43831,N,N,43574,43830,43576,43832,43573,43829,43578,43834,43579,43835,43581, -43837,43580,N,43582,43838,43300,43332,43591,43847,43589,43845,N,N,43590,43846, -43588,43333,43302,43334,43592,43848,43593,43849,43335,43594,43850,43596,43852, -43595,43851,43305,43337,43304,43336,43597,43853,43599,43855,43598,43854,43338, -43307,43339,43607,43863,N,N,43606,43862,43309,43341,43609,43865,43611,43867, -43610,43866,43612,43868,43613,43869,43615,43871,43614,43870,43617,43873,43616, -43872,43311,43343,43628,43884,43625,43881,43622,43878,43627,43883,43624,43880, -43626,43882,43633,43889,43636,43892,43635,43637,43893,43639,43895,43638,43894, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -43558,43814,43587,43843,43605,43861,43623,43879,43632,43888,43629,43885,43631, -43887,43630,43886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43833,41520, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41519,41522,41526,41525,N,41523,41528,41529, -42593,N,42594,42595,42596,N,42599,N,42601,42604,42614,9761,9762,9763,9764, -9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,N,9778,9779, -9780,9781,9782,9783,9784,42597,42602,42609,42610,42611,42612,42619,9793,9794, -9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809, -42616,9810,9811,9812,9813,9814,9815,9816,42613,42618,42615,42617,42620,10023, -42818,42819,42820,42821,42822,42823,42824,42825,42826,42827,42828,N,42829, -42830,10017,10018,10019,10020,10021,10022,10024,10025,10026,10027,10028,10029, -10030,10031,10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042, -10043,10044,10045,10046,10047,10048,10049,10065,10066,10067,10068,10069,10070, -10072,10073,10074,10075,10076,10077,10078,10079,10080,10081,10082,10083,10084, -10085,10086,10087,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097, -N,10071,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,N, -42877,42878,8510,N,N,N,N,8509,8514,N,8518,8519,N,N,8520,8521,N,N,8823,8824,N, -N,N,8517,8516,N,N,N,N,N,N,N,N,N,8819,N,8556,8557,N,N,N,N,N,N,N,8744,8558,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41585,N,N,N,N,N,N,N,N,N,N,N,41583,N,N,N,N,N,N, -N,N,8818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8747,8748,8746,8749,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8781,N,8782,8783,N,8799,8784,N,N,N, -8800,8762,N,N,8763,N,N,N,N,N,N,8541,N,N,N,N,N,N,N,8805,N,N,8807,8551,N,8796,N, -N,N,N,N,N,8778,8779,8769,8768,8809,8810,N,N,N,N,N,N,N,8552,8808,N,N,N,N,N,N,N, -8806,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8802,N,N,N,N,N,N,N,N,N,N,N,N,N, -8546,8801,N,N,N,N,8549,8550,N,N,8803,8804,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,8766,8767,N,N,8764,8765,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,8797,8798,10273,10284,10274,10285,N,N,N,N,N,N,N,N,10275,N,N,10286, -10276,N,N,10287,10278,N,N,10289,10277,N,N,10288,10279,10300,N,N,10295,N,N, -10290,10281,10302,N,N,10297,N,N,10292,10280,N,N,10296,10301,N,N,10291,10282,N, -N,10298,10303,N,N,10293,10283,N,N,10299,N,N,10304,N,N,N,N,N,N,N,N,10294,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,8739,8738,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8741,8740,N,N,N,N,N,N,N,N, -8743,8742,N,N,N,N,N,N,N,N,8737,8574,N,N,N,8571,N,N,8573,8572,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8830,8570,8569,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,8554,N,8553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8822,N,N,8821,N,8820,8481,8482,8483,8503,N, -8505,8506,8507,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8745,8750, -8524,8525,N,N,N,N,N,N,8513,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259, -9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274, -9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289, -9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304, -9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319, -9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,N,N,N,N,N,N,N, -8491,8492,8501,8502,N,N,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514, -9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529, -9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544, -9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559, -9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574, -9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589, -9590,N,N,N,N,8486,8508,8499,8500,12396,17274,45089,15415,45090,45091,N,19324, -15974,15152,15973,12860,45092,18772,19775,N,20514,12591,45093,N,13166,20515, -16420,21058,13654,19002,N,N,N,N,15975,45094,N,20030,N,45095,45096,N,19010,N, -45097,N,20516,45098,N,17254,45099,45100,45101,20517,13946,N,N,45102,20518,N, -13405,17200,N,15463,20519,N,N,20520,45103,45104,20521,18229,45105,13655,N, -45106,N,N,N,18231,N,18019,14403,19251,N,45107,N,N,N,26953,20522,15976,20523, -12853,45108,N,45109,13925,14448,19561,N,N,22054,45110,N,N,N,N,45111,45112,N,N, -N,N,N,N,N,19824,N,18045,45113,45114,N,N,N,45115,N,N,N,N,13349,45116,13621,N, -20524,N,N,20525,20027,N,19773,16744,20527,15222,18035,45117,20530,N,N,12606, -14431,N,14430,12390,45118,45119,20299,20298,N,14899,12321,45120,20531,20532, -20533,19252,20534,N,14450,12391,19314,N,13692,N,N,13693,13694,17506,20028, -45121,20535,N,N,20536,N,N,20537,N,N,45122,16205,N,N,N,N,N,15674,16206,20542, -45123,20540,N,20541,13656,N,N,14883,12912,N,20539,20538,18985,45124,N,N,N, -15174,15173,16958,20543,18773,16487,45125,45126,N,8504,20544,20546,45127, -45128,45129,16997,20065,12362,N,N,45130,N,N,N,N,20545,12862,45131,13892,45132, -17255,45133,N,45134,14191,20547,N,N,N,18212,N,45135,45136,45137,45138,13419, -45139,45140,N,N,N,N,45141,20548,12363,45142,45143,14432,13420,18810,18482, -13657,45144,N,N,45145,45146,45147,N,45148,12913,N,20583,17729,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,45149,18284,20550,45150,N,45152,18492,45153,20066,45154,16173, -45155,15175,45156,15223,12864,45157,N,45158,N,45159,17489,N,N,17186,20554, -45160,45161,N,45162,45163,12364,17507,15675,14900,19748,45164,16974,45165, -12863,45166,20553,45167,19774,20549,20551,14958,20552,21796,45168,45151,N,N, -45169,N,N,N,N,N,20560,45170,N,45171,N,45172,20563,20561,45173,N,12866,N,19003, -20555,45174,45175,45176,45177,20559,14451,45178,45179,15176,N,45180,45181, -13350,45182,45345,20564,N,20556,45346,45347,20067,45348,15224,45349,20557, -45350,20562,45351,45352,45353,N,20565,45354,20558,45355,45356,13857,N,12365, -45357,45358,13858,12865,N,N,N,N,N,N,N,N,N,21797,N,19321,18798,14452,N,N,45359, -N,N,16175,20023,45360,N,45361,N,45362,45363,45364,45365,19032,45366,45367, -14136,16933,12900,45368,45369,N,45370,45371,15699,45372,45373,45374,20569, -45375,20574,20572,45376,N,20567,N,N,16943,20570,N,20573,20571,45377,19037,N, -20568,45378,16174,45379,19315,20575,20576,N,N,N,N,N,N,N,N,15652,20589,45380,N, -45381,18256,N,18742,20584,N,19056,N,12854,N,45382,45383,20588,45384,45385, -45386,N,N,45387,20582,20591,45388,N,16722,45389,14404,45390,18268,45391,24647, -45392,20590,17757,45393,20579,N,14454,45394,45395,14453,20577,45396,45397, -45398,45399,15450,N,20585,45400,19055,17229,20581,14193,45401,20578,20586, -20580,20049,20587,20289,45402,N,45403,N,45404,45405,N,45406,13926,N,N,14192,N, -45430,N,N,N,N,45407,45408,45409,20592,N,45410,45411,20593,20597,12366,45412,N, -45413,N,45414,19024,20596,45415,45416,45417,N,20595,20599,45418,N,45419,20598, -N,17508,N,N,45420,45421,N,45422,45423,N,14194,45424,45425,N,N,45426,N,20600, -45427,N,N,45428,45429,15429,N,16934,17509,13942,N,20601,N,N,N,N,13622,N,N, -20602,45431,N,45432,45433,20604,45434,N,N,N,45435,N,N,19253,45436,45437,45438, -14182,45601,45602,45603,N,45604,N,15153,18551,20603,45605,45606,N,45607,45608, -45609,45610,45611,N,N,N,N,N,N,N,45612,N,14917,19779,N,45613,45614,N,20606, -20771,20605,14916,N,15741,N,45615,45616,N,N,45617,14137,N,45618,N,20772,45619, -45620,13903,N,45621,N,20769,20770,N,45622,17967,45623,16764,45624,13859,N, -45625,45626,19277,20773,N,45627,N,20029,N,45628,45629,20774,45630,N,N,45631, -20777,45632,20775,45633,16718,45634,45635,N,N,N,20776,20778,45636,N,45637, -45649,N,N,20780,45638,N,N,20779,45639,19016,N,N,45640,13623,20782,20783,45641, -12847,N,45642,45643,45644,20781,N,45645,45646,45647,45648,N,45650,N,15476,N, -20786,20785,20784,45651,20566,45652,20787,45653,45654,45655,45656,15742,N, -20788,N,45657,N,N,N,45658,45659,N,19749,N,45660,45661,N,45662,N,45663,19545, -45664,45665,45666,N,20790,45667,45668,20789,20792,20791,N,N,20793,20794,12404, -45669,14389,14139,15676,17275,13860,16488,14455,45670,14702,20796,19528,17734, -45671,15225,N,20795,45672,20797,45673,N,45674,45675,N,17758,N,13173,N,N,45676, -N,N,20798,N,45677,18046,45678,N,16692,20800,20801,18476,14456,20283,20802,N,N, -13862,N,N,N,19004,16950,13937,17717,N,N,N,14195,N,45679,N,20803,N,20804,45680, -45681,18018,12639,N,N,20807,14973,45682,20806,14918,45683,20808,26222,20809, -19265,20810,N,20811,20812,15977,45684,15436,N,N,N,45685,N,N,13351,45686,20815, -45687,20813,19517,20814,N,18778,20816,20817,20818,17759,45688,N,N,20822,20820, -20821,20819,14947,20823,19562,20068,45689,N,45690,N,45691,20824,45692,45693,N, -N,45694,N,16424,20825,15706,N,45857,20826,N,17276,20031,17760,N,45858,N,45859, -45860,45861,N,45862,21061,N,45863,N,N,20827,29733,13893,45864,N,20828,19294, -45865,N,N,45866,15720,17020,N,20830,18020,N,N,20831,45867,N,20832,13102,45868, -45869,45870,20833,13863,45871,17996,12666,15696,N,N,18465,20834,17761,45872, -45873,16207,20835,45874,18988,16474,13346,N,13353,20836,N,N,20838,N,N,14138, -45875,45876,20837,45877,45878,20083,45879,N,N,N,N,15721,N,N,N,N,45880,N,18493, -19020,N,20839,45881,19832,20840,N,N,N,20841,N,17790,45882,45883,20842,N,45884, -16425,14974,14196,20843,15177,14703,45885,N,N,N,N,N,N,17510,20845,45886,N, -16935,N,45887,14959,20846,20847,16688,N,20844,N,N,N,N,20849,45888,19254,45889, -45890,N,45891,14692,45892,N,20848,45893,45894,45895,N,14197,14942,18285,45896, -N,N,20852,20850,N,N,N,45897,18811,15978,20859,13156,20853,20851,16719,N,45898, -45899,45900,N,N,N,20855,N,20854,45901,N,45902,13124,N,45903,N,14176,20860, -20013,45904,N,45905,20856,N,N,N,20861,20858,45906,20857,45907,45908,45909, -45910,N,45911,20047,45912,N,N,14457,12867,N,N,20084,45913,45914,45915,45916,N, -15733,17752,14693,21026,21027,N,45917,45918,20069,N,N,20267,21029,45919,45920, -45921,14458,45922,45923,21028,45924,13103,N,45925,21030,N,19286,45926,17468, -45927,19750,45928,19033,N,N,45929,21031,N,45930,N,45931,28757,N,45932,17968, -45933,21032,13354,19507,N,45934,45935,15905,21033,19047,21037,45936,16426, -21034,13904,45937,21035,13355,45938,45939,45940,N,45941,N,N,N,45942,45943, -14126,21038,45944,21039,45945,45946,21040,21041,15451,N,N,N,14459,19550,45947, -19560,18039,45948,N,19057,21042,N,21043,N,45949,45950,46113,21045,N,21047, -21046,46114,N,46115,N,21048,12861,19276,46116,14972,21049,46117,46118,16729, -46119,46120,15906,13865,N,21050,N,46121,N,46122,46123,46124,18523,46125,46126, -46127,N,21051,46128,21052,46129,21053,N,46130,N,N,21054,18724,13928,12389, -46131,46132,46133,17983,21055,15677,46134,16489,N,21057,21056,15907,14433, -21059,18494,46136,46135,21060,N,N,N,18524,16948,17006,13864,N,N,18030,17201, -46137,18286,46138,19278,N,21062,N,16490,46139,N,46140,N,46141,14133,N,N,21063, -N,N,46142,46143,21064,12588,12405,13421,46144,16936,13649,19825,N,21067,12855, -46145,N,21066,N,N,46146,13866,N,N,21068,46147,19569,N,N,46148,46149,N,N,N,N,N, -46150,N,N,N,N,46151,46152,N,21069,N,20050,46153,14460,N,N,46154,N,14390,21070, -46155,N,N,46156,21072,21071,N,16223,12601,46157,46158,N,12638,21073,46159, -21074,N,46160,14391,46161,46162,21075,46163,46164,N,46165,13678,N,46166,N,N, -46167,N,15154,21076,N,46168,N,N,19316,14901,13658,19751,16720,18495,15485, -46169,N,N,46170,46171,15687,46172,15464,15477,N,15734,46173,18496,N,46174, -46175,21079,46176,12611,16721,14461,14405,13927,46177,46178,21083,17185,17022, -13867,15908,21084,21082,12868,16998,15416,15179,12582,N,46179,13168,14694, -15178,N,21085,21086,46180,13641,13126,N,N,N,14695,13640,17503,12581,17969, -19518,14625,19833,17735,14462,N,46181,N,N,N,N,N,N,46182,14127,N,21095,N,13923, -19274,46183,N,N,N,N,18525,46184,46185,21094,46186,13406,21089,21090,21092, -46187,N,46188,N,N,46189,46190,21093,N,13659,16225,N,18989,21091,21087,14435,N, -21088,N,20260,46191,46192,N,19058,46193,17512,14434,14704,N,N,46194,21096, -46195,N,18013,N,N,N,N,N,N,N,N,N,N,N,N,46196,21100,N,N,46197,N,46198,N,46199, -46200,15486,46201,15478,46202,N,46203,46204,N,21103,21101,N,19491,46205,21098, -21107,21102,N,N,N,21105,14406,19519,N,46206,21106,46369,N,46370,21108,46371, -21110,N,46372,46373,N,14960,20290,46374,21099,21097,21109,46375,21104,N,N, -46376,46377,N,N,N,N,N,46378,N,N,46379,N,46380,21112,N,21283,21114,46381,46382, -21118,46383,46384,21281,21115,46385,46386,21310,N,46387,14953,13105,N,N,N, -46388,21113,46389,46390,46391,21285,12406,21284,46392,12325,18762,21282,N, -21116,N,46393,21111,21117,14920,46394,N,N,46395,46396,N,N,N,N,N,N,N,N,N,21286, -N,N,N,N,N,N,N,46397,12407,21295,N,N,21287,21288,N,15909,19305,46398,N,46399, -21293,21292,46400,N,N,17711,N,N,N,46401,N,N,N,21294,N,46402,21291,46403,46404, -46405,46406,N,N,12596,46407,14902,16176,46408,46409,N,N,46410,46411,46412, -21289,17762,N,N,N,21290,46413,12322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -46414,46415,N,N,21300,19747,N,15911,46416,21306,N,46417,46418,N,21305,21296,N, -46419,46420,46421,16963,N,21297,46422,N,N,17007,21302,15910,46423,N,46424, -46425,N,21299,46426,N,19556,46427,46428,N,14140,N,N,21303,21304,46429,N,46430, -46431,21301,21307,46432,N,46433,46434,N,21298,46435,N,46436,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,21313,21318,N,21314,46437,21309,46438,46439,21319,16689, -N,46440,21321,46441,14626,21311,17277,N,N,46442,46443,N,46444,46445,46446, -46447,N,N,46448,21315,21308,13357,N,13422,13157,21316,21312,N,N,N,46449,46450, -N,N,14198,21322,21320,16723,13642,13868,46451,21317,N,13940,N,46452,N,N,N, -12612,N,N,N,N,N,N,N,N,46453,N,46454,N,46455,21326,21324,46456,21543,N,46457,N, -46458,46459,N,46460,N,N,46461,46462,46625,21329,N,N,46626,46627,N,21323,46628, -21327,N,46629,21325,N,N,46630,15180,21328,N,N,N,N,46631,N,N,N,N,N,N,N,N,N,N,N, -N,46632,21331,N,21336,N,N,N,21334,21333,46633,46634,17202,N,46635,12869,46636, -N,N,46637,46638,46639,46640,46641,46642,N,21330,N,21332,15912,12595,46643,N, -21335,N,N,N,N,N,N,N,N,N,N,N,N,N,12894,N,N,46644,N,N,21346,46645,15996,21342, -46646,21340,46647,21341,46648,21343,46649,N,46650,46651,46652,N,46653,46654, -46655,12605,46656,46657,N,46658,N,N,46659,N,46660,16697,46661,21337,46662, -21338,N,N,N,46663,N,N,N,N,N,N,13178,N,N,46664,N,46665,46666,46667,46668,21345, -N,46669,N,13423,46670,21348,21344,21347,46671,N,46672,N,46673,46674,N,18990, -46675,N,N,18005,N,18488,N,N,N,N,N,21350,N,N,N,46676,46677,21349,13125,46678,N, -21351,46679,46680,N,N,21354,N,N,N,N,21353,46681,N,N,N,46682,46683,N,N,46684, -46685,46686,21352,N,18233,N,N,21355,46687,46688,46689,46690,N,46691,46692, -46693,21356,N,N,46694,N,46695,21358,N,21357,46696,N,N,N,N,21360,N,46697,N, -21363,21361,21359,21362,N,46698,N,N,21364,46699,46700,46701,46704,46705,21365, -46702,46703,21366,N,21367,N,N,N,21368,20805,46706,15484,15181,46707,46708, -12915,46709,12408,46710,N,17220,46711,46712,46713,46714,46715,N,N,46717,N, -46718,21369,N,14884,46716,12367,16222,N,N,46881,46882,N,21370,14407,N,N,14705, -N,21372,21371,46883,46884,19040,21373,N,N,46885,21537,21374,46886,21538,46887, -21539,N,14199,N,46888,12640,21540,N,46889,21542,N,21541,N,46890,46891,21544, -46892,N,17754,46893,N,46894,46895,46896,46897,21545,12341,14943,46898,46899,N, -46900,14141,46901,46902,17231,N,N,46903,46904,N,N,21546,21547,N,N,21549,N, -46905,46906,46907,21550,N,14948,N,N,46908,46909,13905,N,N,19255,N,46910,46911, -21548,21551,14913,14627,46912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21555,46913,N,14885, -46914,17203,46915,46916,21552,17498,46917,N,46918,46919,46920,46921,46922,N, -46923,46924,46925,N,46926,N,46927,46928,46929,46930,N,46931,21556,N,46932, -16226,46933,N,N,N,N,21554,21557,N,14143,46934,N,N,N,N,N,N,21558,46935,46944,N, -46936,N,46937,46938,N,46939,46940,46941,46942,21559,46943,14628,13120,21561,N, -N,46945,46946,46947,21562,N,46948,N,N,N,21563,N,N,21560,N,N,N,N,46949,N,N,N,N, -46950,N,N,21553,N,N,21564,N,N,21565,46951,46952,N,N,19300,46953,N,15979,46954, -N,N,21567,21568,21566,46955,21570,N,N,N,N,N,18232,46956,46957,12392,18774, -46974,N,21571,46958,N,46959,46960,N,46961,N,N,N,46962,N,N,46963,N,N,N,15997, -46964,46965,15417,46966,18269,13424,N,14955,46967,46968,46969,19289,N,17970, -46970,46971,14200,16975,N,46972,46973,21569,21572,47137,47138,N,N,N,N,N,N,N, -16964,N,N,N,21573,N,47139,N,21574,47140,47141,47142,21576,N,N,17513,N,47143, -47144,N,N,13358,N,N,47145,N,29729,12641,19059,47146,N,15980,17736,N,N,N,47147, -14950,N,N,21582,N,47148,19005,20061,N,N,N,N,N,N,N,47149,12916,21578,47150, -47151,N,47152,47153,16698,21581,N,17763,47154,N,17737,17764,18489,17485,N,N,N, -14921,47155,N,47156,21577,N,47157,N,N,47158,47159,12662,N,17718,N,N,N,N,21579, -N,21575,N,N,16208,N,N,47160,21583,N,N,47161,N,15694,47162,47163,47164,N,13869, -N,21584,N,47165,47166,47167,47168,N,47169,47170,N,47171,47172,N,N,19048,47173, -N,47174,16765,N,N,N,N,17478,47175,N,21586,47176,47177,47178,N,N,N,47179,N, -19279,47180,N,21587,N,N,21592,N,N,47181,47182,18991,N,N,N,N,21591,21585,21588, -21590,47184,N,14886,N,N,19017,47185,N,47183,21593,N,17221,47186,N,12917,N, -15981,47187,47188,N,47189,21595,47190,21594,47191,14696,47192,21596,21598, -21597,47193,N,21600,47194,21589,21602,N,47195,47196,N,21601,21599,N,N,N,47197, -N,15182,16209,N,16724,21603,16444,12397,18276,47198,N,N,N,17499,N,21605,21604, -21606,21607,21608,21609,N,N,47199,47200,N,N,19025,21610,47201,47202,N,N,12870, -21611,N,47203,47204,47205,19772,13104,N,21065,15688,16959,21612,19563,47207,N, -N,N,47208,19508,47209,47210,21614,N,16999,47211,17719,16960,18775,21615,21616, -12667,47212,47213,15418,21617,47214,N,47215,47216,12368,21618,N,N,N,N,N,21619, -47217,N,N,N,47218,12642,N,47219,13425,18016,19060,N,N,N,N,21623,16725,21622, -14144,47220,47221,19291,21621,N,17765,21625,47222,21624,47223,N,47224,47225, -47226,21627,47227,21626,47228,N,12668,N,21628,15913,21630,17189,47229,21629, -47230,18995,47393,N,N,47394,15735,17755,47395,47396,N,21793,47397,N,47398, -47399,14629,N,N,N,21794,18209,18526,19537,N,N,N,N,N,18213,47400,47401,21803, -47402,N,N,N,47403,13624,N,47404,19781,47405,N,19503,N,22060,N,21795,N,47406,N, -N,N,21798,47407,16965,N,47408,19256,N,N,N,17738,47409,47410,47411,47412,N, -21799,47413,N,N,N,47414,N,19301,47415,14922,47416,N,15914,N,N,47417,N,47418, -47419,N,21800,N,47420,15184,47421,15183,N,47422,N,N,12345,14408,47423,16427, -12369,N,N,N,N,21804,21805,N,21802,47424,47425,47426,N,N,N,47427,47428,12600, -13359,47429,21801,N,19525,18737,N,N,47430,47431,N,47432,47433,N,47434,N,12328, -47435,N,N,N,12409,N,N,N,15185,47436,12370,N,12323,47437,N,N,N,N,21810,N,N, -47438,47439,47440,N,N,21808,47441,47442,N,N,N,N,19516,N,21811,N,21809,N,47443, -21807,16177,N,N,47444,47445,21806,N,47446,47447,19034,47448,N,N,47449,N,14436, -47450,N,N,N,N,21815,21816,N,N,N,N,N,15915,N,N,N,21812,20268,N,N,47451,47452, -18252,47453,47454,21814,N,N,47455,N,N,N,47456,N,N,N,N,47457,N,N,N,N,14887,N,N, -N,47458,N,N,N,21817,47459,N,47460,18776,47461,N,N,21818,N,21813,47462,N,N,N,N, -N,N,N,N,N,47463,N,N,47464,47465,N,N,47466,19515,N,N,N,N,N,N,N,N,N,N,N,47467,N, -N,N,N,47468,N,18270,47469,N,N,47470,N,N,47471,21819,18738,47472,N,47473,47474, -47475,N,47476,N,N,N,N,47477,N,N,N,N,47478,N,N,N,N,47479,47480,47481,N,47482,N, -N,47483,N,47484,47485,21820,21824,21821,47486,N,12871,21823,N,47649,N,47650,N, -47651,15419,N,21822,14201,N,N,47652,21836,N,N,N,N,N,21829,21826,N,N,47653,N, -47654,N,N,N,47655,17252,N,21825,N,47656,21827,N,N,21828,47657,N,N,N,47658,N,N, -N,N,N,N,47659,47660,N,N,N,21830,21831,N,47661,47662,47663,N,N,N,N,N,N,47664, -13426,N,21833,21832,N,N,N,N,N,N,N,N,N,21834,47665,N,47667,N,47668,N,47669,N,N, -N,47670,15982,N,N,47671,N,N,N,N,21837,N,17500,47672,N,N,12613,N,21835,N,47666, -N,21838,N,47673,N,N,N,N,N,21839,N,21842,47674,N,21840,N,21841,N,N,N,N,N,47675, -47676,N,N,N,15186,21843,47677,N,14630,21844,47678,15226,16952,N,21845,21846, -15194,14631,47679,19538,N,N,N,13608,14409,21847,13144,N,47680,21848,N,16953,N, -N,47681,47682,21849,22051,N,21850,N,21851,N,N,21852,N,21854,N,47683,47684, -47685,47686,21855,47687,N,21856,47688,17008,47689,12583,15465,12354,47690, -16727,13360,15413,47691,14632,47692,47693,N,47694,47695,17766,47696,15649, -13361,17256,17514,12344,13625,19061,N,15426,N,N,13650,16491,15420,19752,21857, -N,47697,47698,N,N,47699,47700,13660,47701,14923,47702,47703,13106,12643,15916, -12872,47704,21858,19782,47705,N,47706,N,N,15689,47707,47708,15460,21859,13427, -18002,19497,21860,N,21861,N,N,18777,47709,N,47710,21863,N,13352,13943,21862,N, -47711,47712,47713,47714,47715,13362,N,16178,21867,15137,47716,12873,21866,N, -21864,21868,21865,18219,23629,16179,N,21869,N,N,20032,47717,21870,47718,N, -21872,47719,17278,21871,N,16419,N,15227,N,N,47720,16976,15479,18805,16492,N, -15437,21873,15917,21874,21875,12371,16954,16210,47721,21876,17971,15918,N, -15919,N,21877,N,N,16493,47722,N,N,15920,N,N,N,47723,47724,21878,N,21879,47725, -19552,N,47726,N,21880,47727,N,47728,47729,13894,47730,N,47731,15650,47732,N,N, -47733,47734,N,21881,21882,15452,16172,18036,16212,18552,18210,13897,21883,N,N, -N,13679,21884,N,13950,N,17999,12848,N,15187,21885,22050,22049,13949,N,21886,N, -17720,N,N,N,47735,47736,N,47737,N,16944,N,17739,15432,47738,47739,16728,19834, -N,47740,47741,47742,N,N,22052,47905,22053,18006,47906,15155,N,N,47907,47908, -22055,N,N,22056,47909,47910,47911,47912,N,N,N,N,N,N,N,N,N,47913,47914,N,47915, -N,22057,N,N,47916,13428,22058,47917,N,22059,N,N,N,N,N,N,N,N,47918,N,47919, -47920,12844,47921,47922,N,N,47923,N,16699,13412,47924,22061,19496,N,N,N,N, -16978,47925,13145,47926,47927,22063,22065,13407,N,47928,22062,22064,N,22067,N, -N,N,N,N,N,22066,N,22068,N,47929,N,47930,N,N,N,N,N,N,47931,N,N,N,N,47933,N, -22069,N,N,N,47932,N,N,17981,13870,N,N,N,N,N,N,12901,22070,22075,N,N,22073, -47934,19063,19062,47935,47936,N,47937,N,17767,N,N,N,22072,15700,N,22071,47938, -N,N,N,N,47939,16242,N,N,N,22076,N,47940,14954,N,N,22082,47941,N,22083,22077, -13107,22078,22087,22086,22085,22081,N,N,N,22080,N,N,22084,47943,47944,N,47945, -47946,N,19064,N,47942,N,N,N,N,N,47947,N,N,47948,N,N,N,N,47949,N,N,N,47950,N, -47951,N,N,47952,47953,N,N,47954,N,47955,N,47959,22091,22088,N,22090,N,19826, -47957,22089,N,N,47956,N,N,N,47958,N,N,22079,N,N,47960,47961,47962,47963,N, -47964,N,N,N,N,16243,47965,N,22092,47966,N,14903,47967,N,N,22093,N,N,22094,N,N, -47968,47969,N,N,N,47970,47971,N,47972,22097,47973,22096,N,N,22095,47974,N, -47975,17768,22074,N,N,N,22103,N,47976,47977,47978,47979,N,N,N,47980,N,47981,N, -22099,N,47982,47983,N,22098,N,N,N,N,47984,N,N,N,47985,22100,N,22101,N,47986,N, -58996,N,47987,N,N,22104,47988,47989,20070,N,22105,22102,N,N,N,N,N,47990,N,N,N, -47991,N,22106,N,47992,13408,22107,47994,N,47993,N,22109,22108,N,N,22110,N, -47995,47996,N,22111,N,16494,15651,N,47997,15716,N,16739,47998,14633,14904, -14634,13680,48161,N,22112,N,N,14905,N,N,14410,22113,19494,18243,22114,N,14635, -48162,48163,N,13356,N,17191,13906,48164,N,15188,18779,N,N,18497,48165,N,N,N, -22115,13429,48166,N,N,N,22118,48167,N,48168,48169,17441,N,48170,22117,22116, -22119,N,17515,N,48171,48172,N,N,N,N,16227,N,N,48174,N,N,15189,N,16458,48173, -16979,13602,N,48175,17442,N,48176,22120,22121,15983,N,N,N,N,19257,48177,N, -22124,N,N,22123,22122,18813,N,22131,N,48180,N,48178,19290,N,22125,N,48179, -48181,N,N,22127,19307,48182,22126,48183,N,N,48184,48185,N,48186,22128,N,18472, -22129,19006,22130,N,N,N,48187,N,48188,48189,48190,48191,48192,N,48193,N,13363, -19007,18223,22132,22133,N,14636,13364,22134,14392,19780,19753,13430,22136, -48194,17443,N,14637,15921,N,N,18527,N,N,15922,48195,N,N,48196,15736,N,N,N,N,N, -17516,19065,17721,N,N,14638,N,18780,N,N,N,22137,N,48197,N,48198,48199,17753, -14914,48200,N,48201,14411,48202,17517,N,N,N,48203,N,48204,N,12355,15726,14639, -19783,N,N,N,N,48205,48206,48207,N,22138,22139,18257,N,N,48208,N,22140,20087, -20269,48210,48209,N,48211,22142,22141,48212,48213,13127,48214,48215,22305,N,N, -N,22308,22309,48216,22307,48217,18752,15923,22311,22310,22306,N,48218,N,N, -22312,22313,N,48219,22314,N,N,N,22317,22315,N,22316,22318,N,12644,17518,22319, -N,14202,12918,18230,N,22320,18043,19035,48220,22321,20270,N,48221,48222,48223, -22322,19008,22325,20513,20529,48224,15408,18037,22326,N,13661,17444,12410, -22327,18982,14640,48225,N,17232,48226,48227,N,17519,N,48228,48229,48230,48231, -19567,14393,14412,48232,22328,N,48233,48234,22329,48235,22335,48236,15461,N,N, -48237,17445,48238,13871,22330,N,N,48239,18731,48240,17222,48241,48242,22331,N, -N,48243,48244,N,48245,22332,N,13872,N,22333,48246,22334,N,48247,22336,N,17782, -48248,N,22337,22338,48249,22339,N,48250,22324,22323,N,N,48251,22340,14145, -48252,48253,N,18727,48254,N,14924,18743,17446,18763,22341,N,48417,15924,12614, -48418,22342,48419,48420,N,22343,48421,19570,48422,N,18528,48423,48424,22346, -12669,16428,22345,22344,14146,16980,N,22350,22348,48425,22347,20007,14437, -48426,N,48427,15737,22349,17740,15678,N,N,48428,17984,22353,22352,N,N,48429, -48430,22351,N,22354,14438,48431,N,48434,N,N,48432,22355,18812,15707,48433, -48435,22356,18553,48436,48437,48438,N,17985,17447,N,N,N,48439,17712,N,N,22357, -13611,N,N,N,N,N,16180,48440,18732,N,48441,48442,48443,N,48444,13431,18214,N,N, -48445,48446,48447,48448,48449,N,22358,15190,19258,19259,N,N,12670,22363,48450, -N,17257,48451,48452,N,22360,N,N,N,48453,48454,48455,12919,48456,48457,48458, -48459,22573,22362,48460,48461,N,18224,48462,N,22361,N,48463,22359,48464,14714, -N,22365,48465,N,N,48466,N,N,48467,22371,22377,22369,N,17756,48468,48469,22374, -18781,48470,48471,22368,48472,22373,20071,15191,N,48473,16981,22366,N,N,48474, -13662,22376,16429,12645,22370,12920,22375,N,48475,N,13873,N,22372,N,48476,N, -48477,N,N,N,N,22378,N,N,N,N,N,48478,22380,22390,22388,N,N,22385,48479,48480, -48481,22384,20088,48482,22386,N,N,13874,48483,14641,N,48484,15738,48485,48486, -N,22393,22379,N,N,48487,N,22383,22367,48488,12922,22387,22389,17233,N,48489, -14888,12856,22381,22392,22391,13875,N,16937,13158,48490,N,N,N,14147,N,22382,N, -N,N,N,N,N,48491,48492,N,22394,48493,22397,22561,N,48494,N,48495,15421,48496, -22567,17520,22395,48497,N,N,48498,22565,48499,12921,48500,22563,22564,48501,N, -22398,22562,N,48502,48503,14439,19754,N,48504,13365,48505,48506,12633,22566, -48507,18234,12333,N,N,N,N,N,48508,48509,18529,22364,22572,22576,19557,48510, -22569,N,N,48673,17769,22574,48674,N,N,N,48675,N,48676,15984,22575,18007,48677, -48678,48679,48680,N,N,48681,48682,N,20295,N,22571,48683,48684,N,N,22577,48685, -14715,48686,16459,48687,48688,12372,22570,22568,48689,16730,N,48690,N,22396, -15156,N,N,N,N,N,N,N,16966,22589,48691,16731,22584,48692,22581,22582,48693, -15462,22585,22588,48694,48695,22583,15653,48696,22586,N,N,22580,48697,19580, -19579,48698,N,48699,22590,22591,12373,48700,48701,48702,48703,48704,22579, -48705,48706,N,48707,13938,12326,48708,N,48709,13366,N,22587,48710,N,N,N,N, -22595,22594,N,48711,48712,22599,N,N,N,48713,48714,N,N,22600,48715,48716,48717, -N,48718,N,N,22598,22601,22593,22597,N,48719,22602,N,22603,48720,48721,22592, -15228,48722,22596,16982,14642,22578,16181,N,N,N,N,22616,N,19049,N,N,22606, -22607,22608,N,N,22615,48723,22614,48724,N,19325,13367,N,22612,N,14149,13108,N, -N,22609,48725,N,20024,22611,12374,22613,48726,22604,22610,22617,14148,22605, -48727,N,N,48728,48729,N,19805,48730,48731,48732,19755,48733,48734,N,N,22620,N, -N,22624,48735,N,48736,16766,N,20089,22625,48737,48738,22622,N,22619,48739, -48740,22618,22623,N,48741,48742,N,48743,48744,N,N,N,18992,48745,N,17972,48746, -14150,48747,22626,22621,48748,22627,N,N,N,14203,N,N,N,12849,N,48749,48750, -22635,N,48751,N,13368,N,48752,48753,48754,22633,N,N,22634,14889,22632,22630, -22629,22636,22628,22638,48755,48756,12923,N,N,N,N,48757,N,N,N,N,N,N,48758, -48759,48760,48761,N,48762,48763,22640,N,48766,22639,48764,N,48765,N,N,48929, -48930,N,48931,N,N,17448,N,22643,N,22641,22631,14204,N,22642,N,22646,22645, -22647,22644,22648,48932,N,48933,48934,N,N,48935,22649,22650,19050,N,22652, -22651,15679,N,16430,12902,12924,48936,22653,48937,12351,N,N,N,16460,22654, -48938,27715,22817,14177,48939,22818,48940,48941,N,N,16495,48942,N,48943,22819, -48944,N,N,22820,13626,22821,N,22822,22823,16983,N,N,N,14413,48945,N,19553,N, -48946,N,19260,15722,22824,48947,48948,48949,N,48950,16496,28221,18530,N,15466, -48951,14925,22825,N,48952,48953,48954,16967,48955,18983,48956,N,17009,N,48957, -22828,48958,N,22826,N,22829,N,N,22827,48959,N,N,N,22830,N,N,N,N,48960,18993, -48961,N,12343,N,48962,N,N,18782,N,N,18531,48963,N,22831,48964,22834,15925, -13627,N,22832,22839,15926,N,N,N,N,22833,18244,N,N,48965,48966,48967,48968, -19806,22835,22836,22840,17770,22837,14643,16478,N,N,22854,18484,N,17010,N,N,N, -N,N,N,N,48969,N,48970,N,N,18532,23085,N,N,N,N,19066,N,48971,N,17521,48972, -48973,N,19317,48974,22843,12833,17258,48975,48976,N,N,22852,N,48977,17204, -22846,22853,22848,22855,22851,N,22850,18287,48978,22844,12925,22842,13681, -17011,22838,48979,48980,22841,14644,16475,48981,15927,22849,18258,N,N,13682, -13128,N,N,N,N,N,N,N,N,48982,N,13159,16161,22857,22862,N,22858,48983,14205, -48984,22863,15138,14697,N,N,N,N,48985,48986,15654,22845,15229,22860,48987, -48988,N,N,15192,22861,12356,48989,48990,22856,48991,N,N,48992,17449,N,48993,N, -N,48994,N,48995,13683,N,N,N,N,N,13876,N,N,N,N,N,N,N,22859,12327,48996,48997, -14915,N,48998,N,16182,N,N,N,N,N,48999,49000,N,N,49001,17522,N,49002,18516, -22865,16734,N,49003,49004,49005,49006,N,49007,N,N,16938,49008,49009,15147, -22866,49010,22868,22864,N,49011,49012,49013,19041,N,17469,49014,N,N,49015, -16732,N,N,N,N,N,N,N,N,49016,49017,19067,15438,22880,N,22879,49018,49019,16248, -N,N,49020,14206,N,49021,49022,22873,15929,49185,N,18024,18225,49186,49187,N, -49188,22871,N,49189,16733,49190,N,N,49191,15480,22876,49192,N,15928,N,22870, -22875,49193,N,18259,N,49194,49195,22869,N,14113,49196,49197,13149,N,N,49198, -22877,20011,14926,17205,22874,49199,16476,49200,14645,16228,12646,16700,22872, -13637,49201,49202,49203,N,N,14151,N,17487,22878,N,N,N,N,N,16735,N,49204,22881, -N,22883,49205,N,16951,22889,49206,22884,N,49207,22886,N,N,N,N,49208,18753, -17523,49209,22887,49210,49211,49212,19756,N,N,N,19784,13369,49213,N,N,N,49214, -12334,N,22885,N,49215,N,N,N,22882,49216,N,49217,N,13432,N,N,N,49218,49219, -12647,49220,22888,N,49221,49222,19785,22892,N,N,49223,49224,N,N,16955,N,22899, -49225,N,49226,22893,49227,N,22890,22897,49228,N,N,N,22867,N,49229,N,49230,N, -49231,N,49232,49233,22894,N,22898,49234,49235,N,18498,17771,N,49236,49237,N,N, -N,22891,49238,22895,N,N,N,14152,N,N,49239,14961,49240,N,N,16477,N,N,N,N,N,N,N, -N,49241,N,N,22903,49242,N,49243,49244,49245,49246,N,N,N,17702,N,49247,49248, -49249,49250,N,49251,49252,49253,N,49254,N,N,N,22900,N,19296,N,N,N,49255,N, -22901,N,N,N,49256,49257,N,22902,N,19534,N,16418,49258,N,49259,N,N,N,N,N,14178, -N,49260,N,49261,22909,N,N,N,N,N,N,49262,49263,49264,15157,22906,N,22905,N,N, -49265,49266,18226,49267,N,49268,17973,49269,N,49270,N,49271,17713,22907,49272, -N,49273,22908,N,18799,49274,18245,15139,N,16497,N,19280,49275,N,N,N,N,N,13129, -N,23077,22910,49276,49277,49278,N,19786,23079,N,49441,23075,N,23076,N,49442, -49443,49444,49445,16736,49446,N,49447,49448,23074,N,22847,49449,N,49450,23078, -N,23073,N,N,N,N,N,23083,23084,17703,23086,49451,49452,15140,23081,N,49453, -49454,N,13628,49455,N,23087,49456,23080,23091,N,23090,49457,23089,49458,N,N, -23092,49459,N,23094,15985,49460,23093,49461,N,N,49462,23097,N,N,49463,49464, -49465,N,N,N,N,49466,N,N,N,49467,49468,N,49469,N,23095,49470,N,49471,23096, -22896,49472,49473,N,N,49474,23099,23098,N,49475,N,N,49476,22904,23100,23088,N, -49477,15193,N,49478,N,N,23101,23102,23104,23103,23105,12926,49479,14646,49480, -49481,19068,16431,N,N,N,49482,N,14414,N,49483,23107,49484,N,N,N,23110,N,18770, -49485,13663,49486,N,49487,23109,23108,18260,23111,13877,N,N,N,23113,23112, -49488,49489,N,13370,15158,N,N,18008,49490,N,N,N,49491,14153,N,N,N,16244,N, -23114,N,16432,17704,N,18783,23115,N,49492,N,N,49493,N,N,N,49494,23116,23117,N, -49495,N,19000,21853,16454,49496,N,18764,N,14936,N,18533,18499,49497,N,N,49498, -N,17741,49499,20033,N,23119,15440,49500,N,23120,49501,12342,N,49502,13908, -16461,49503,18784,N,N,N,23121,15170,17223,49504,15195,16183,N,49505,49506, -49507,N,N,23122,N,19069,N,N,12663,15196,N,49508,N,23125,49509,23123,23126, -20025,23124,N,49510,49511,N,16507,23127,N,49512,16946,49513,N,23128,N,49514,N, -49515,13434,49516,23130,N,23129,N,N,N,49517,23131,23132,13435,N,N,18044,17206, -13676,15197,16737,N,N,15708,12336,N,N,49518,23133,49519,N,49520,49521,N,N,N, -49522,12834,23137,N,N,49523,49524,49525,N,14647,23136,49526,N,14891,15930, -49527,49528,23135,N,15931,49529,19520,14890,N,49530,49531,12375,16462,49532, -49533,N,N,N,N,N,23142,49534,49697,16433,12615,49698,49699,49700,49701,15701, -49702,19302,14962,49703,49704,49705,49706,15932,49707,16423,49708,49709,N, -49710,23141,23139,23140,49712,N,49711,N,N,17259,N,N,23334,49713,23146,15230, -14648,23144,49714,49715,N,N,23145,49716,16184,49717,N,49719,23143,N,49718, -15151,N,N,N,N,49720,49721,49722,N,49723,49724,23148,23147,23152,49725,49726, -23153,N,23149,N,13090,23150,23151,18517,49728,49729,49730,N,18785,14154,23154, -N,N,49732,16434,49733,15933,49735,49736,49737,17234,49738,49740,N,49731,49734, -49739,13895,N,23155,23159,N,N,12875,23156,23158,N,49741,49742,49743,23157,N, -49744,15723,49745,N,N,N,17224,12357,23160,49746,49747,49748,49749,23161,N, -49750,49751,N,17450,N,49752,N,20081,N,N,N,N,15171,N,49753,19051,N,N,49754, -49755,N,19261,49756,N,N,23330,23163,N,49757,23166,N,23165,49758,49759,23162, -49760,49761,23329,N,N,18014,49762,23164,N,N,49763,N,49764,49765,N,N,N,N,49766, -N,23331,N,N,15724,23332,49767,19787,18296,N,49768,23333,N,N,N,N,N,23335,N, -49769,23336,N,49770,49771,N,49772,N,23337,N,13898,12616,14649,23338,N,23339, -15729,16738,49773,49727,21080,16702,16701,16984,14919,N,N,20594,N,49774,N, -49775,14190,19757,N,19070,N,18814,49776,23340,N,N,N,49777,14963,17471,23341, -20271,N,49778,N,19262,49779,17451,23342,13436,49780,N,49781,N,N,N,23343,23344, -19546,N,19492,19318,19292,15141,23346,N,N,15467,N,49782,19281,N,23348,23351, -23350,N,13433,N,N,13664,49783,23347,N,23349,N,N,N,49784,23352,49785,49786, -16249,N,N,49787,N,19835,12361,14944,16956,N,15453,49788,49789,15987,N,N,23355, -N,N,17742,49790,23353,16939,23354,15986,19549,23356,23357,19816,49953,N,N,N, -23362,N,49954,14650,49955,18261,23359,17772,23134,23138,49956,13647,49957, -18247,N,N,N,49958,23361,N,15934,18500,N,49959,N,N,49960,23367,N,18554,N,23358, -N,23364,23363,N,49961,49962,16463,49963,N,49964,N,19309,49965,20051,49966, -49967,19303,49968,12876,15198,N,N,20296,23366,16245,N,N,N,23365,N,N,23360,N,N, -N,N,N,14415,49969,49970,49971,23372,23370,49972,12877,23368,23374,23380,N, -49973,49974,49975,N,N,49977,16968,49978,49979,19009,49980,23382,N,49981,49982, -18722,N,N,N,23381,18288,19263,13371,49983,16503,15680,N,N,49984,17491,49985, -19758,N,49986,23377,23376,N,N,49987,23378,N,23375,N,49988,23383,N,23373,N,N, -23371,N,23379,23369,49989,17260,49990,19576,15430,14964,49991,49992,N,49976,N, -14906,N,N,19311,13121,17486,17994,12617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,16498, -49994,N,16436,14122,N,49995,N,N,N,49996,23385,49997,N,14651,13180,N,N,N,N, -49999,49998,23387,13172,23393,50000,50001,N,50002,50003,50004,23390,50005, -16499,N,N,N,13131,14892,N,50006,13130,14927,N,50007,23388,14181,14155,17773, -50008,50009,23386,N,12358,N,50010,N,50011,23389,23391,N,13901,14124,49993, -13372,13643,50012,N,50013,50014,23394,N,50015,14969,19313,N,15159,N,N,N,23395, -N,N,N,18736,N,N,N,50016,N,N,50017,50018,50019,50020,50021,N,23407,50022,12851, -23396,N,50023,50024,50025,50026,N,23413,23397,N,20034,50027,23404,50028,18271, -50029,N,50030,N,N,N,N,23412,N,23399,N,N,N,12340,23401,N,50031,14652,50032,N, -50033,23403,50034,23402,N,23398,23409,50035,15935,50036,N,50037,21613,14440, -19836,50038,50039,N,N,23400,50040,17524,13091,14893,50041,23392,N,23408,13153, -N,N,23406,23410,50042,17774,N,N,N,N,N,N,N,13438,50043,23602,N,50044,19529, -23415,13437,50045,23422,N,50046,50209,50210,19264,50211,23585,23587,50212, -23591,23417,50213,17194,N,50214,50215,N,17775,23595,23420,N,23592,N,50216,N, -23586,50217,N,50218,50219,50220,50221,16185,23596,50222,50223,16435,N,N,50224, -50225,N,N,23594,13373,50226,50227,50228,20304,23414,N,N,23590,12376,50229,N, -23416,50230,50231,19514,23421,16162,17479,23411,50232,50233,23589,50234,N,N, -50235,50236,N,16250,23599,13169,14369,N,N,N,N,23601,23418,23600,N,23593,23419, -N,23597,N,23598,N,N,N,N,N,23615,50237,N,50238,17998,50239,23588,N,50240,23611, -N,50241,N,23613,N,17496,N,N,50242,N,N,50243,N,N,N,50244,19788,N,N,N,50245,N,N, -N,N,18806,23608,16970,N,50246,N,23614,16703,50247,23605,23618,23617,N,18031, -23616,18026,50248,50249,50250,50251,N,50252,50253,23620,23607,50254,13896, -23610,15709,50255,50256,50257,18272,23612,13899,N,23604,23606,23603,50258, -50259,20272,13146,23609,50260,50261,23619,13109,N,N,N,N,N,N,N,14951,N,N,50262, -12637,N,N,23636,50263,N,20273,23639,50264,N,50265,N,N,16186,23638,N,N,N,23637, -50266,N,N,N,50267,50268,23634,50269,N,N,50270,N,50271,23622,50272,N,23651, -23621,N,23640,N,N,50273,50274,N,50275,23632,50276,N,23627,23624,N,23625,N, -23633,N,50277,N,29730,50278,N,23630,14653,17480,16740,23628,N,23623,50279,N, -23626,N,N,50280,50281,19789,19306,N,N,N,23631,23641,N,N,N,50282,N,N,50283,N, -23649,23642,N,N,23655,N,23653,50284,50285,N,50286,23648,50287,N,50288,N,N,N, -23647,N,17488,N,16741,50289,23645,50290,50291,23643,50292,N,23650,N,N,N,N, -23656,18549,23662,N,N,50293,N,50294,23657,23660,23654,50295,N,17268,N,18744, -50296,23644,N,50297,23652,15936,50298,19535,23672,23659,50299,N,N,N,50300, -14370,12835,13151,N,N,23635,N,50301,N,50302,N,50465,15937,23664,50466,23671, -15481,13170,50467,N,17198,50468,50469,N,N,N,N,23661,50470,50471,23666,23670, -50472,50473,13878,N,N,50474,N,50475,50476,50477,N,N,50478,50479,N,13644,23668, -N,50480,N,N,N,13601,N,17995,23667,N,50481,N,23669,50482,N,N,50483,N,N,N,N,N,N, -50484,23663,50485,N,N,N,N,23665,N,N,N,N,N,50486,13152,17225,50487,N,50488, -23676,N,50489,50490,N,50491,N,50492,N,23674,14441,N,23673,50493,N,N,N,N,N, -23841,N,N,N,50494,23384,50495,50496,50497,23675,N,23677,23678,N,50498,N,N,N,N, -23852,50499,23848,N,23405,50500,50501,50502,N,23847,50503,N,N,N,23846,N,N, -23843,N,50504,50505,50506,N,23658,23845,23844,N,N,50507,N,50509,50508,N,N, -50510,N,N,N,50511,23850,N,20262,50512,50513,50514,N,N,N,23853,13947,50515, -50516,23849,23851,N,N,N,N,50517,N,N,50518,18471,N,23854,N,50519,N,N,N,50520, -50521,50522,N,N,N,N,N,N,N,23858,23855,50523,50524,50525,50526,19827,23856, -50527,50528,N,50529,23646,N,N,N,N,50530,50531,50532,23859,N,N,N,23860,50533,N, -N,N,50534,N,12597,50535,23862,14183,15393,N,13909,50536,N,N,12836,50537,N,N, -50538,50539,N,N,50540,N,N,19807,N,N,50541,50542,23864,23863,23866,13629,50543, -N,13910,13374,50544,N,N,N,23869,N,N,50545,23868,N,23870,50546,N,12878,50547, -17207,N,23871,N,50548,13375,23873,N,50549,N,50550,23872,N,23874,N,50551,N, -23875,50552,23876,15199,16437,14881,N,18800,50553,N,19042,20292,50554,N,N, -50555,15221,50556,N,N,14928,20082,50557,N,N,23877,23878,N,15200,N,50558,50721, -23879,23880,N,50722,23882,23881,50723,19288,N,N,15710,15468,15172,N,23883,N,N, -N,N,N,N,N,23885,16163,50724,23884,N,N,50725,N,N,23886,50726,50727,N,50728, -50729,23887,N,N,N,50730,50731,23888,23889,50732,50733,50734,23890,50735,23892, -23891,23893,12837,17226,N,23894,50736,50737,15142,13132,23895,50738,50739, -17730,21580,N,N,50740,50741,13603,23896,N,N,50742,N,23897,50743,19052,19304,N, -N,N,17991,23898,18534,N,50744,N,18555,N,50745,19539,N,N,N,23899,N,50746,N, -50747,N,N,50748,50749,N,N,N,23901,23900,N,50750,23903,N,50751,N,23902,N,N,N, -50752,N,50753,N,N,N,N,N,50754,50755,N,50756,50757,N,N,23905,50758,N,N,N,50759, -50760,15201,50761,19505,50762,23906,23907,N,N,13604,N,50763,N,23908,N,N,N, -50764,N,N,N,23910,23909,N,50765,50766,50767,N,N,N,50768,N,50769,N,N,N,N,50770, -16229,50771,50772,18745,12618,N,50773,50774,N,N,18501,50775,17525,15681,13665, -N,N,N,N,N,N,N,50776,50777,N,50778,18502,50779,15406,N,50780,N,50781,23912,N, -13376,N,50782,12664,50783,50784,18034,23911,14654,17235,N,23913,N,N,N,N,50998, -23921,N,23914,50785,N,50786,N,50787,16961,N,13666,23922,50788,N,50789,N,50790, -50791,14184,50792,N,13605,23920,N,N,23918,23915,19808,N,50793,50794,50795, -17472,50796,N,N,18009,23916,N,N,23924,N,23923,14115,50797,50798,12845,50799, -50800,14907,23917,23919,50801,N,N,50802,N,19287,17012,N,N,N,N,N,N,N,N,19319,N, -N,23932,N,50803,23933,50804,12879,50805,N,N,N,18984,19581,24097,15395,15938, -23928,23934,12648,N,13879,50806,N,23925,23930,50807,N,N,16500,18289,N,18535, -50808,N,50809,50810,50811,50812,23927,50813,19233,50814,23929,N,24100,50977, -24098,50978,23931,N,N,50979,19234,18248,13667,N,17701,N,50980,17261,50981, -24101,50982,50983,N,50984,24099,16985,23926,50985,12619,50986,50987,N,N,50988, -N,N,50989,19790,24112,N,50990,50991,N,50992,24111,50993,N,N,N,16502,N,24108, -50994,19820,N,N,17974,24102,N,N,N,N,N,17477,50995,50996,50997,12620,14655, -24105,N,N,50999,51000,N,51001,15655,24110,N,24109,24104,N,24107,51002,N,13160, -51003,24106,18249,51004,N,20014,N,N,15988,16501,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,51005,N,24118,24116,N,18765,N,51006,51007,N,51008,N,24113,24115,51009, -12602,51010,N,14656,20274,N,13117,N,18786,51011,51012,N,N,N,19809,N,N,13092, -16187,24117,N,N,51013,N,N,N,N,N,51014,N,N,24122,N,51015,15939,N,N,N,19760,N, -24119,N,N,51016,51017,24114,51018,24120,51019,51020,51021,20062,N,17779,17986, -N,N,N,N,N,N,N,N,N,N,N,N,N,51022,N,51023,N,N,13110,N,N,12629,N,51024,24126,N, -51025,24129,51026,N,N,20035,51027,N,51028,19812,N,N,N,51029,24136,24130,24127, -51030,N,51031,20052,24133,N,51032,51033,N,15690,24135,N,N,24140,51034,N,17777, -24138,N,51035,N,51036,24132,51037,51038,17208,51039,N,24139,51040,24128,N, -24134,51041,24141,12412,24131,N,24142,51042,51043,16188,N,15711,51044,18981, -51045,14894,N,24123,24137,17722,51046,51047,N,N,N,51048,16438,N,13161,14929, -15940,24125,15682,N,N,N,N,N,N,N,14156,N,24124,N,N,N,24146,15725,14394,N,24161, -51049,24155,13684,17743,51050,24150,24159,12335,12594,51051,N,12857,N,24152, -16940,24143,24145,14657,N,N,51052,N,N,N,51053,N,24162,51054,24157,51055,51056, -N,24149,N,N,N,N,24156,51057,51058,N,N,51059,51060,19499,51061,N,24154,24158, -51062,N,51063,51064,51065,51066,N,14416,51067,15941,N,N,17209,51068,51069, -51070,24148,N,N,51233,51234,N,N,N,19759,51235,N,N,24151,N,N,24144,17778,N,N, -24147,51236,N,N,24153,N,N,N,N,51237,N,51238,20305,15422,19326,N,24163,N,N,N,N, -N,N,N,N,N,18478,51239,N,24175,14395,N,N,51240,N,N,15712,N,24165,51241,N,N, -20015,14658,N,24178,51242,N,12398,N,N,24176,N,51243,N,N,24164,N,N,51244,51245, -24170,N,51246,24172,51247,N,N,19791,24167,N,N,17710,51248,N,24169,N,51249, -51250,51251,24177,51252,24171,19527,N,51253,51254,24166,51255,15394,24190, -51256,51257,51258,N,13162,N,24168,24173,24174,N,N,N,N,N,N,N,17004,16986,N,N,N, -N,N,N,N,N,N,N,N,N,51259,24182,51260,51261,24188,N,N,24186,N,17705,N,N,24355, -24183,51262,N,51263,N,51264,24184,24160,13689,18746,N,51265,N,15423,N,51266, -14711,51267,N,51268,51269,N,20275,N,24180,N,24354,12649,16742,51270,N,51271,N, -51272,51273,N,N,N,N,18297,N,13377,20090,N,N,51274,N,N,51275,51276,19489,17490, -51283,N,51277,51278,24187,24189,51279,N,N,51280,N,16690,N,N,51281,51282,N, -24353,24185,N,24179,N,N,N,13379,N,N,N,N,N,N,N,N,N,51284,N,51285,51286,51287, -14185,N,N,51288,24367,51289,51290,24362,16504,51291,51292,13155,N,51293,51294, -N,15713,N,24371,N,51295,N,N,N,51296,24364,17452,24361,17497,N,N,N,24396,N,N,N, -24358,N,24357,N,24366,51297,51298,N,24360,24359,24365,51299,16417,N,24356, -51300,51301,N,N,51302,51303,51304,24368,N,51305,24369,51306,51307,51308,N, -51309,13378,N,N,51310,N,N,N,N,51311,51312,24374,N,24373,24375,51313,51314, -51315,51316,N,24378,N,N,N,51317,51318,51319,17731,N,24372,N,51320,51321,N,N, -24376,N,N,51322,N,N,N,14179,17017,24370,18235,N,51323,24377,51324,51325,N, -51326,N,N,N,N,N,N,N,N,N,24382,24380,N,N,24383,N,51489,24386,N,N,51490,24379, -14698,18216,N,N,24121,N,N,N,51491,51492,N,19828,24381,N,24385,17013,51493, -24384,N,24363,N,51494,28521,N,N,51495,24389,N,51496,51497,24393,51498,24391,N, -N,N,51499,51500,51501,N,24387,N,24388,N,51502,N,24392,N,24390,N,N,N,18766,N, -51503,24398,N,24395,24394,N,24397,18004,24399,51504,N,N,51505,N,N,17269,17005, -N,N,N,N,16421,N,N,51506,24400,N,24402,N,51507,N,N,51508,N,51509,N,N,51510,N, -24401,N,N,N,N,51511,51512,N,N,N,51513,51514,51515,51516,24181,N,51521,N,N, -24403,N,N,51517,51518,N,N,18023,N,N,N,N,51519,51520,N,N,N,N,24404,51522,51523, -N,N,N,N,N,12880,51524,N,51525,17780,13093,N,N,N,N,51526,51527,N,13668,N,N,N, -15454,14930,51528,N,N,51529,N,N,N,51530,51531,N,N,20263,16230,N,N,N,12650,N,N, -N,24406,N,51532,51533,51534,51535,51536,24405,N,51537,N,N,N,N,N,N,N,N,51538,N, -N,N,N,N,N,51539,24409,17210,24412,24407,51540,51541,N,24411,51542,N,N,51543, -24410,17728,12377,N,N,N,N,N,N,N,N,N,N,N,N,N,20085,N,51544,24414,N,N,N,12584,N, -51545,N,51546,51547,51548,51549,N,51550,24416,N,N,51551,24415,N,24413,N,N,N,N, -51552,N,N,N,N,N,N,N,N,N,N,N,N,24408,N,N,N,N,N,N,N,19235,51553,N,N,24418,51554, -51555,51556,51557,51558,N,24417,N,51559,51560,N,N,51561,N,N,N,N,12651,N,N,N,N, -24420,18994,N,24419,N,51562,N,51563,19509,N,N,N,N,15943,N,N,N,N,51564,N,51565, -N,51566,51567,51568,N,N,N,N,16691,N,51569,N,N,N,15942,N,N,N,N,51570,N,N,N, -51571,51572,51573,N,20091,51574,51575,24426,N,16505,N,51576,N,51577,N,N,24422, -24427,51578,N,12652,51579,N,51580,N,51581,N,51582,N,24425,N,18273,24421,24424, -15944,51745,18513,N,N,24428,N,15441,N,N,N,N,N,N,N,N,N,N,51746,N,N,N,16506,N,N, -51747,N,N,N,24431,51748,N,51749,24423,N,14119,N,51750,N,N,24429,N,N,51751,N, -19792,24432,N,N,N,29734,51752,51753,N,N,N,15695,51754,N,51755,N,N,N,N,N,24433, -N,N,N,24434,N,N,51756,51757,18222,51758,51759,N,N,N,N,N,24436,51760,N,N,N, -24437,51761,51762,51763,N,18227,51764,N,N,N,17781,24439,N,51765,51766,N,24441, -N,20053,N,24438,51767,24440,12653,51768,24435,N,51769,51770,N,51771,N,N,21339, -24442,N,N,N,N,16743,15160,24444,N,N,N,N,24443,16164,21081,N,N,N,N,N,N,24445,N, -N,51772,24609,N,24430,24446,N,51773,24610,51774,N,N,N,N,N,18298,51775,51776, -51777,N,N,N,24611,N,N,24612,N,N,51778,N,N,N,51779,N,N,51780,24613,N,51781,N, -51782,N,N,N,N,51783,N,N,N,24614,N,17502,51784,24616,24615,N,51785,24617,N, -24618,N,51786,15455,18787,N,51787,51788,19564,24619,24620,16726,15396,24621, -24622,51789,51790,51791,N,51792,24623,19026,18503,N,N,24624,18263,N,51793, -51794,51795,N,17453,51796,N,51797,51798,N,24625,12903,51799,13677,51800,19526, -51801,19510,51802,12852,20276,51803,N,N,N,19282,51804,18986,N,51805,N,N,51806, -51807,N,51808,16439,N,24626,N,N,51809,51810,17987,N,51811,51812,14371,24627, -51813,14932,24629,24628,N,51814,N,N,24630,N,51815,N,N,N,51816,51817,N,N,N, -24631,51818,N,N,24632,N,N,N,N,51819,N,N,N,N,13630,N,24633,N,N,N,N,24634,51820, -N,N,N,14372,51821,51822,18504,N,51823,24636,N,51824,N,15989,N,N,24635,N,N,N,N, -51825,N,N,51826,13880,24637,24639,N,24638,51827,N,51828,N,N,51829,N,24640,N, -14417,N,24641,N,N,51830,51831,13929,51832,16704,N,14717,N,N,N,51833,24643, -24644,24642,N,N,51834,N,N,N,15469,N,N,17992,13881,N,N,N,N,N,51835,51836,N,N, -24646,17196,24645,51837,51838,20277,18274,52001,52002,N,52003,52004,N,52005,N, -N,24649,52006,N,52007,N,N,N,N,52008,52009,N,N,24651,24648,52010,52011,N,19540, -24650,24652,52012,20036,N,N,52013,N,52014,24656,N,52015,52016,24655,17270, -18221,52017,N,14373,24654,N,52018,52019,N,24653,52020,19761,19762,N,N,52021, -52022,N,52023,24657,12654,N,N,N,52024,14710,15202,N,N,N,N,N,N,N,52025,24658, -24659,52026,N,52027,N,N,N,52028,24661,52029,N,N,N,N,52030,52031,52032,52033,N, -N,15683,N,N,52034,52035,24663,52036,24662,52037,52038,N,52039,52040,24664, -52041,13133,N,N,24666,N,52042,24665,52043,24668,24667,52044,N,N,N,52045,52046, -N,52047,14396,52048,52049,20008,N,13900,N,12838,N,N,52050,N,52051,N,N,52052,N, -52053,13930,52054,52055,N,N,N,52056,N,52057,52058,52059,N,52060,N,N,52061, -52062,N,N,13409,52063,52064,N,52065,N,N,N,N,20072,24670,N,52066,N,52067,N, -52068,N,24672,52069,52070,N,52071,24673,N,12881,N,N,52072,52073,N,24669,52074, -15161,52075,52076,17473,24671,52077,N,N,52078,52079,N,N,52080,N,N,52081,N,N,N, -52082,24676,N,15470,52083,N,52084,N,24674,52085,52086,N,52087,14142,N,N,18505, -24675,N,N,24702,N,N,52088,52089,N,52090,24681,52091,52092,52093,N,52094,14397, -52257,52258,52259,N,13669,52260,24678,19837,52261,N,20016,52262,N,N,N,N,N,N, -52263,N,N,N,N,N,N,N,N,52264,52265,N,N,N,N,N,N,17014,N,52266,24680,52267,N, -52268,52269,52270,52271,52272,52273,52274,52275,52276,52277,24682,20054,13911, -18556,18250,N,N,52278,24683,N,N,N,N,24685,52279,24688,N,52280,52281,N,52282, -52283,N,N,N,52284,N,52285,N,N,N,52286,52287,N,N,24684,N,52288,N,24687,14442, -12621,24689,52289,16240,24686,20060,N,52290,24692,29732,N,52291,52292,52293, -24690,24693,52294,N,52295,52296,24679,24691,52297,52298,14908,N,N,24694,N,N,N, -N,N,N,N,24695,N,52299,52300,N,19838,N,52301,52302,52303,N,52304,N,24696,N,N,N, -52305,52306,52307,52308,N,N,N,N,N,52309,52310,52311,N,52312,N,24697,52313, -52314,52315,24677,52316,N,N,52317,24698,52318,52319,52320,52321,N,N,52322, -52323,13380,52324,52325,N,N,52326,N,N,N,52327,N,52328,N,15397,N,52329,N,N,N,N, -N,N,N,N,52330,52331,24699,N,52332,N,N,24700,52333,N,N,52334,24701,N,N,N,52335, -N,52336,52337,12603,N,52338,52339,24865,N,18747,24866,52340,N,13348,24867, -52341,24868,52342,52343,N,N,24869,52344,24871,24872,24870,N,52345,N,18771, -24874,24873,N,52346,52347,52348,N,N,52349,24876,24875,24877,52350,N,N,N,N,N, -24878,24880,24879,N,N,14713,52513,24882,N,24881,52514,52515,13381,N,16211,N, -17724,N,24883,16440,52516,52517,N,15162,52518,12665,24884,52519,19793,52520, -52521,19043,24885,N,N,52522,17732,19763,14659,16189,N,N,52523,17227,21044, -52524,17454,12904,24886,52525,52526,52527,52528,N,N,52529,24887,N,24892,52530, -52531,24890,24889,23106,13094,24888,52532,12378,52533,18474,52534,N,18506,N,N, -52535,N,20017,24893,24891,17244,16422,52536,52537,18475,52538,18733,N,24895, -20012,14157,24896,N,24894,18518,24897,N,24898,N,52539,12379,52540,N,15990, -24903,N,24900,18029,24899,52541,52542,52543,52544,52545,52546,13606,N,52547, -24906,N,N,52548,24901,24902,N,24905,24904,18725,N,N,16706,16705,52549,13631, -52550,52551,24907,52552,N,N,N,52553,24908,N,52554,24909,N,N,N,N,52555,24911, -52556,24910,N,N,N,N,N,12630,N,N,N,N,N,24919,18536,24913,52557,24915,N,N,24917, -16190,52558,N,24918,24916,15424,52559,52560,52561,24912,24914,52562,18754, -52563,15945,N,N,24921,N,52564,24920,52565,52566,N,N,24922,N,15398,14895,N, -52567,17783,24923,N,17483,52568,N,24925,52569,52570,52571,20001,24924,52572,N, -N,52573,N,16745,N,N,52574,N,52575,52576,24930,52577,24932,24933,17236,N,N,N,N, -52578,24931,N,24928,N,24926,24927,52579,24929,52580,52581,52582,N,N,52583, -52584,24936,52585,24934,52586,24935,N,52587,N,N,52588,52589,N,52590,52591,N,N, -52592,N,52593,52594,52595,52596,24937,24939,24940,24941,52597,24942,52598, -52599,24938,N,52600,N,N,N,52601,N,N,24944,N,52602,52603,24943,52604,N,N,52605, -52606,52769,24945,52770,N,N,N,52772,52773,20037,52774,52775,52776,24948,24946, -24947,52777,52771,52778,13410,N,N,N,N,N,19582,N,N,52779,19018,N,24950,52780,N, -N,24949,N,N,52781,N,24951,24952,N,52782,52783,N,24956,24953,24954,24955,N, -24957,52784,52785,52786,24958,52787,25121,N,52788,N,25122,N,25123,N,18479, -17744,25124,18290,18740,N,25125,52789,N,25126,17706,52790,13095,14660,25127,N, -N,25128,52791,52792,25129,N,15145,N,N,25131,N,52793,25130,N,N,25132,25133, -52794,52795,52796,N,52797,52798,N,52799,52800,52801,52802,52803,52804,52805,N, -52806,N,N,52807,18537,N,25134,N,N,N,25135,N,N,29545,25136,25137,25138,N,N, -52808,N,15150,N,52809,25139,18262,N,52810,19295,N,12622,52811,12631,52812, -52813,25140,52814,N,N,N,25142,N,52815,N,25141,17776,N,52816,N,16441,23865,N, -25143,19521,52817,25144,N,13382,18519,25145,52818,25146,52819,N,25147,N,52820, -N,19548,N,52821,52822,19541,N,17470,N,52823,N,16746,52824,N,25149,52825,N, -15714,52826,15946,N,N,25152,N,52827,25151,25150,18557,52828,13383,14377,N, -52829,N,N,N,52830,N,52831,52832,N,52833,N,52834,52835,25158,52836,N,25155, -16191,19506,N,52837,N,25154,25156,25157,N,52838,25153,N,N,N,52839,52840,52841, -N,N,N,N,52842,52843,52844,25159,25160,52845,17455,N,13411,52846,52847,N,17253, -N,52848,N,N,52849,52850,25161,N,N,52851,N,N,52852,52853,52854,N,N,52855,N,N,N, -52856,52857,N,N,25162,25165,52858,N,52859,52860,52861,16231,52862,17988,53025, -25166,19283,53026,25163,N,53027,25164,53028,N,N,N,53029,N,53030,53031,53032,N, -N,N,N,25169,53033,N,N,53034,25168,25167,53035,N,N,N,53036,N,N,N,N,N,N,25171, -53037,53038,25170,N,N,25172,N,N,53039,53040,53041,N,N,N,53042,N,N,N,25174, -53043,25173,N,53044,N,N,19021,N,53045,N,N,53046,N,15702,20038,53047,53048, -25175,53049,N,17975,N,53050,25176,N,N,25177,N,25181,25179,25180,53051,25178,N, -N,N,53052,N,N,N,25182,N,53053,N,N,N,25183,N,N,N,53054,53055,N,N,53056,N,25184, -N,53057,25185,19511,25186,N,53058,53059,53060,N,19568,25187,53061,17230,53062, -18282,N,13931,53063,N,53064,17211,25188,13882,53065,53066,N,16464,53067,N,N,N, -53068,N,N,53069,25189,14909,N,N,53070,53071,N,N,53072,N,N,25190,53073,53074,N, -N,53075,25191,N,14374,14933,N,N,N,N,N,N,N,53076,N,N,25193,53077,53078,53079,N, -17750,14934,13646,N,N,N,N,N,53080,53081,N,53082,N,19236,N,18251,53083,N,53084, -N,N,17751,N,N,N,N,14684,N,N,N,53085,53086,25195,N,53087,53088,N,N,N,53089,N, -53090,N,N,N,53091,N,N,N,N,N,N,N,N,N,53092,15947,53093,N,53094,53095,N,53096, -53097,N,N,N,53098,N,53099,20018,14661,N,53100,14375,N,N,18467,N,25197,N,N,N,N, -N,53101,N,25199,N,53102,N,N,14443,N,N,N,N,25198,17526,N,N,53103,N,25201,13111, -25196,53104,N,18538,N,12592,53105,14956,N,20306,53106,N,25200,N,N,53108,53109, -53110,N,53107,N,25202,53111,N,N,19019,53112,16473,25204,N,53113,53114,N,25205, -53115,53116,53117,53118,N,25203,N,N,N,N,13134,53281,25211,53282,25210,53283,N, -15399,N,N,N,25212,25207,53284,53285,53286,25213,25208,53287,N,53288,N,18520, -25206,53289,53290,25209,53291,53292,N,N,N,25378,53294,N,N,N,53295,53296,53297, -N,N,53293,N,53298,25377,19297,N,53299,N,25214,N,N,12395,N,N,53300,53301,25380, -N,53303,53304,N,N,53305,53306,N,25379,N,53307,53302,15948,N,N,N,N,53308,25381, -N,N,N,N,53309,N,16707,N,53310,25383,25382,N,N,N,N,N,N,25384,53311,N,53312,N, -53313,53314,53315,N,N,N,N,53316,25192,53317,N,53318,25194,25386,25385,53319,N, -N,N,53320,N,N,53321,53322,N,N,N,N,15400,53323,20073,53324,15442,53325,25387, -14135,N,N,53326,53327,53328,13632,13607,15203,53329,53330,N,N,N,53331,19764, -53332,N,25393,53333,25392,16708,25389,53334,N,25391,53335,53336,15691,16192, -25390,25388,N,18218,N,N,15949,N,53337,18748,53338,N,53339,N,14935,N,N,N,N, -53340,N,N,N,N,17784,N,53341,25394,53342,53343,N,53344,25395,25417,13912,N,N, -20285,16693,N,N,N,N,25396,53345,53346,12882,17527,18977,N,53347,N,53348,53349, -53350,53351,N,53352,N,N,53353,53354,25397,N,N,N,53355,N,N,N,N,13690,25398, -53356,53357,25400,53358,N,N,25401,53359,18217,53360,N,25402,53361,N,N,N,53362, -25403,25404,53363,N,13913,12883,17989,15656,15204,53364,N,53365,N,N,53366, -53367,25405,53368,15657,N,N,N,53369,N,12874,18755,N,53370,25406,53371,N,18539, -N,53372,N,N,53373,53374,16709,53537,25409,53538,25410,18281,53539,16193,25407, -N,17249,53540,53541,25408,53542,N,N,15950,53543,N,N,N,N,N,N,53544,N,N,12380, -53545,13609,N,53546,53547,N,N,N,53548,25411,53549,53550,17528,53551,25412, -16455,N,N,53552,N,N,19501,53553,N,18723,25413,25414,17237,53554,20039,N,53555, -25416,25415,53556,N,N,N,N,N,53557,N,N,N,53558,N,53559,15471,53560,53561,25418, -12400,N,53562,53563,N,25421,53564,53565,53566,25419,12884,14158,25420,14662, -14706,N,19046,25422,53567,53568,19284,53569,53570,25424,N,N,53571,16465,12623, -12858,12332,N,N,N,N,53572,53573,25423,N,53574,N,N,53575,53576,N,53577,53578, -25425,25426,15991,N,53579,N,53580,N,25427,53581,13135,N,53582,N,N,25429,N,N,N, -14186,53583,13670,N,53584,25430,13941,N,N,25431,53585,16508,53586,17997,53587, -16480,14965,53588,53589,N,25432,N,53590,53591,N,N,N,N,53592,53593,17250,16747, -53594,25434,25436,25433,25435,N,N,N,N,N,53595,14114,53596,N,N,53597,N,N,N,N,N, -25437,14118,N,53598,N,13671,19794,25439,N,N,53599,N,53600,25440,N,N,53601, -12590,53602,53603,N,N,25443,N,N,N,13174,25442,25441,53604,25445,25438,53605, -25446,20009,53606,25447,53607,25448,N,53608,21620,25450,N,25449,N,N,N,25451, -25452,53609,20021,25453,N,28783,15951,25454,25455,15703,N,17976,25456,N,53610, -53611,17192,53612,53613,25457,N,17212,25458,53614,N,N,53615,N,13861,N,20799, -17245,15411,53616,N,53617,53618,13384,25459,N,25634,N,25462,53619,13672,N, -25461,25636,N,N,N,25460,N,15952,N,N,53620,N,N,N,25464,25465,N,17707,N,N,25466, -53621,13150,N,N,53622,N,16218,18788,53623,25468,53624,53625,53626,17000,53627, -53628,53629,53630,53793,N,25463,53794,25467,25469,N,N,14971,N,N,N,53795,N, -53796,53797,53798,N,N,N,25638,18734,53799,18470,17785,N,13914,25637,25635, -53800,18485,25470,17246,17787,N,17786,53801,14966,N,N,N,N,N,N,25656,N,N,53802, -N,N,N,53803,25640,53804,25642,N,53805,53806,N,25645,53807,25646,53808,25643, -25644,53809,53810,25641,25639,N,53811,N,N,25633,N,N,N,N,N,N,N,N,N,53812,N, -19023,12885,N,53813,N,25653,N,25650,53814,25655,53815,53816,25654,N,18291, -19495,53817,15163,25648,25657,25652,53818,25651,25647,53819,25649,53820,13385, -N,N,N,53821,N,N,N,N,17213,N,53822,16509,N,53823,53824,18466,53825,N,25662, -53826,53827,N,18468,N,53828,53829,53830,53831,N,N,16481,25659,53832,N,18511, -53833,25663,19027,53834,17243,53835,25658,25660,N,N,25661,N,N,N,N,53836,N, -53837,53838,N,53839,53840,53841,N,25664,N,N,15428,N,N,N,17990,25669,25668,N, -53842,25665,53843,N,N,20278,N,N,N,N,53844,25674,53845,53846,25678,25675,53847, -53848,53849,N,53850,N,53851,25671,53852,53853,53854,53855,N,53856,25672,N, -53857,N,53858,53859,25677,53860,53861,N,25666,21077,25673,25667,N,N,25676,N, -53862,N,53863,N,N,N,25682,53864,13386,N,25679,N,53865,53866,25680,53867,N, -25681,25684,53868,N,N,N,N,53869,N,53870,53871,N,53872,25683,18550,53873,53874, -N,N,25685,20092,19053,25690,N,N,25687,N,N,53875,N,N,N,53876,N,25686,16466,N, -25689,25691,53878,53879,53880,25688,53877,25695,N,25692,53881,53882,53883, -53884,53885,53886,25693,25670,54049,N,54050,25694,25696,N,54051,N,54052,N,N, -25697,54053,54054,N,54055,N,54056,19014,N,25698,N,N,N,54057,N,N,54058,54059, -19554,N,N,13902,14121,25699,N,N,54060,54061,N,18996,N,16232,N,19504,N,54062, -25700,N,20019,N,54063,18292,N,16710,18228,N,N,15693,N,N,54064,12352,54065, -25705,25703,N,25701,13345,54066,15953,25706,N,N,25704,N,25702,25710,N,54067, -25709,25708,25707,N,N,54068,54069,N,25711,54070,54071,54072,25712,16442,54073, -25713,N,25715,N,54074,25714,N,54075,54076,54077,14418,N,N,54078,16696,54079,N, -N,25717,54080,54081,54082,17788,54083,25716,54084,54085,N,25718,54086,18997, -16748,14663,N,25719,N,N,N,54087,20040,N,54088,N,54089,N,N,N,25721,N,N,25722,N, -25723,54090,25724,N,15205,N,25725,14159,N,N,13674,13610,N,25889,54091,19571, -14664,25726,54092,54093,54094,25892,19558,N,18236,N,54095,18739,54096,54097, -54098,15715,25891,54099,15443,14665,15206,13673,18998,25890,54100,54101,N, -16711,19266,14967,54102,N,N,54103,N,N,N,54104,15207,17501,54105,25895,20063, -14937,54106,25896,16194,N,25898,N,N,N,15954,14896,N,54107,54108,54109,25897, -54110,54111,15658,14398,16712,25893,25899,54112,54113,N,N,25894,14160,54114, -25902,25906,14187,54115,N,54116,N,N,25901,54117,N,54118,54119,25910,54120, -54121,14666,N,N,19821,12348,25907,N,54122,13675,54123,25904,N,54124,N,N,N, -25905,N,54125,17789,25903,25900,N,13096,16484,N,54126,14376,54127,54128,N, -25912,N,54129,N,54130,54131,54132,N,54133,54134,N,54135,25909,N,54136,54137, -54138,N,25911,N,54139,N,25908,N,N,54140,54141,N,14161,16947,25913,16750,54142, -54305,25926,N,N,25922,25916,N,N,54306,54307,N,N,54308,25920,15482,12381,25915, -25923,25927,14667,19542,54309,17494,25917,54310,54311,25925,54312,25914,17214, -N,25919,12349,19530,N,N,54313,54314,54315,54316,54317,25918,N,N,13915,18540, -54318,54319,54320,16749,N,20048,15727,N,N,25966,N,54321,25928,54322,16510,N, -25924,25929,25931,N,17529,25934,54324,N,25930,54325,54326,N,19028,13387,54327, -54328,19531,54329,N,12382,N,54330,25933,N,20093,54331,54332,N,N,54333,54334, -25932,54323,12655,N,N,18028,25935,N,N,54335,25942,25936,25943,N,N,N,N,54336, -54337,25939,N,N,54338,N,54339,N,N,N,18299,54340,54341,15434,25941,54342,25938, -25944,25937,N,N,15684,54343,54344,N,N,19237,54345,54346,15692,54347,N,25940, -25952,54348,N,25948,54349,25951,N,25949,25953,25947,N,25921,16467,54350,N, -18507,N,25950,54351,54352,25945,54353,N,N,16673,14162,N,15659,54354,N,54355,N, -54356,N,16165,16694,25956,N,54357,25958,25959,N,N,25955,25957,54358,N,54359, -54360,N,N,54361,25946,25954,N,25962,25961,54362,N,19322,54363,54364,14123,N,N, -54365,N,N,N,N,54366,25960,N,25964,25963,25967,54367,25969,N,54368,15164,25965, -N,N,54369,54370,25970,25971,54371,N,25972,54372,25978,17723,25974,54373,25973, -25975,25976,54374,25977,N,54375,N,54376,25979,25980,54377,54378,13388,N,25981, -N,25982,54380,54379,54381,54382,54383,N,N,N,54384,54385,26145,N,54386,N,N,N,N, -26146,26147,26148,54387,26149,26150,54388,54389,26152,26151,N,N,26153,N,N, -54390,54391,54392,N,26154,26155,54393,N,54394,54395,54396,54397,26158,26156, -26157,14945,14163,N,54398,17238,N,18483,54561,15728,N,N,18253,N,18541,26159, -22637,N,N,N,54562,54563,54564,54565,N,26160,26162,N,19813,26161,26164,26163,N, -19795,54566,26165,54567,18558,54568,54569,54570,N,N,26166,N,54571,54572,N,N, -26169,N,54573,26168,26167,N,N,54574,54575,26170,14130,N,54576,N,16674,13633, -54577,N,N,54578,26174,26171,N,N,26172,N,54579,N,26175,N,26176,26173,N,N,54580, -12585,N,54581,54582,12839,N,54583,N,26178,26179,N,54584,N,26180,N,19810,N, -54585,54586,N,N,15660,N,26182,26181,N,N,N,N,N,54587,N,N,N,54588,16233,26183,N, -54589,N,54590,26184,N,54591,26185,N,13413,54592,N,54593,54594,13389,N,54595, -26186,N,N,N,N,N,26187,54596,19293,19811,54597,54598,54599,19796,20279,N,14669, -26190,15444,26189,54600,54601,N,54602,26191,15401,54603,54604,54605,16977, -54606,26192,54607,54608,14668,54609,19543,26193,26194,N,N,26195,54610,54611, -54612,54613,26196,N,N,54614,N,54615,N,26197,N,N,N,54616,N,54617,N,54618,N,N, -15402,54619,54620,19565,54621,N,54622,54623,26199,54624,17215,54625,26198, -54626,N,N,N,54627,N,26201,N,N,N,26200,N,N,N,N,N,N,N,26202,N,N,N,16443,N,26203, -N,26204,N,N,N,19001,26205,54628,16751,26206,N,54629,N,54630,N,26207,N,N,N,N, -54631,N,20094,26210,54632,26209,26208,17456,54633,26211,16166,N,26212,N,N,N, -26213,20280,26214,N,54634,N,N,26215,26217,26216,18469,54635,18041,N,20286, -18473,N,54636,N,N,N,N,26219,N,N,15955,N,18730,N,26220,26218,54637,13390,54638, -N,N,14420,15208,N,N,18542,54639,54640,N,14378,19267,54641,26223,26221,N,14670, -N,14671,12393,N,14952,N,N,N,54642,54643,18265,N,N,N,N,N,N,N,N,12383,26228,N, -17216,N,54644,N,N,N,18264,54645,16987,54646,N,N,54647,N,54648,54649,26230, -54650,54651,26226,26229,26224,N,26227,19238,N,54652,14421,N,N,12413,26225,N,N, -N,N,N,N,N,54653,54654,26232,54817,26233,54818,54819,17977,N,54820,N,13883, -54821,54822,N,26406,18237,54823,15209,54824,N,13884,16456,20294,19502,26231, -16468,54825,N,N,N,N,N,N,N,N,N,N,54826,54827,54828,N,13651,26234,54829,N,54830, -N,54831,N,N,26236,54832,N,N,54833,N,26235,N,N,54834,N,N,26237,54835,17190,N, -18238,N,54836,N,N,N,17457,54837,N,54838,N,26403,N,N,N,N,N,N,54839,26402,54840, -N,N,54841,26238,54842,N,16213,N,18789,26405,54843,26404,14672,20307,N,54844,N, -N,N,N,N,N,N,26421,54845,54846,N,N,N,26409,26410,54847,54848,54849,N,15472,N, -54850,26408,54851,14712,26407,N,N,26411,N,N,54852,17458,18978,16675,N,N,N,N, -16988,26415,54853,26416,26412,54855,54856,54857,N,26413,N,26414,54858,N,N, -54859,14673,54854,N,N,26422,N,26418,54860,N,54861,N,18790,54862,19308,18728, -54863,N,26417,N,54864,26420,26419,N,N,N,19268,26423,N,N,N,N,54865,N,26424,N, -54866,16695,54867,26425,N,N,26427,N,26431,54868,N,26428,26426,18239,26429,N, -26430,54870,N,54871,12850,N,26437,26432,54872,54869,N,26433,54873,54874,N, -26434,N,16929,N,54875,N,54876,26436,26435,26438,54877,N,54878,54879,26439, -26440,54880,N,16195,54881,12905,N,26441,20055,N,15403,54882,54883,15661,N,N, -54884,54885,54886,15210,17239,54887,54888,N,54889,54890,26442,26443,12593, -54891,26444,54892,54893,26445,26446,54894,N,26447,N,26448,13885,23082,26449,N, -16485,26450,15435,54895,26451,N,20528,54896,54897,N,26452,19038,13404,54898, -54899,16676,15704,54900,18801,15662,N,54901,54902,N,N,N,N,N,54903,26453,14674, -26454,18508,N,26468,N,N,N,54904,26456,54905,16969,18293,14399,26455,16677, -54906,N,N,N,N,N,26457,N,N,54907,54908,54909,54910,17530,N,N,N,55073,N,N,55074, -55075,N,55076,N,N,N,N,55077,N,26459,26458,26461,N,55078,26460,N,26462,55079,N, -26464,55080,26463,N,13391,55081,26465,N,26466,26467,N,55082,14897,20041,N, -26469,16167,N,55083,N,12656,26470,26471,N,N,55084,N,55085,26472,55086,55087, -55088,N,55089,55090,N,N,55091,N,55092,55093,12402,N,26473,55094,N,N,55095, -26474,N,55096,N,55097,N,55098,18791,55099,55100,N,15431,N,26476,55101,55102,N, -55103,55104,13097,12338,55105,55106,55107,55108,26475,26478,18254,55109,16196, -55110,12886,55111,19239,55112,N,N,55113,14173,13916,55114,26477,55115,12906, -55116,55117,N,N,N,N,N,13347,55118,N,N,N,N,N,N,N,N,N,55119,12657,26482,20074, -16989,55120,N,18756,N,26494,55121,12887,26492,N,26490,26481,55122,26479,55123, -26480,55124,15459,13932,17271,55125,N,55126,18001,N,55127,N,55128,N,12625,N, -26484,26483,N,55129,55130,N,26489,26485,26488,N,55131,55132,55133,55134,19536, -26487,12888,13181,26491,55135,55136,26493,55137,55138,N,N,14164,N,N,N,N,N,N,N, -26659,26668,26669,N,N,55140,12331,55141,55142,55143,N,55144,55145,26676,N,N,N, -N,12401,N,N,26667,55146,55147,55148,26666,55149,26661,26660,55150,26658,26657, -17251,55151,17019,26663,55152,N,55153,55154,N,N,26662,N,55155,55156,55157, -26665,N,55158,N,16752,14165,N,N,55159,55160,12609,26664,55161,14675,55358, -55139,55162,55163,55164,16753,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -55165,N,N,26682,N,26683,N,12889,55166,N,N,12846,26680,55329,N,55330,55331,N, -55332,N,55333,26670,55334,26678,N,26685,26679,N,N,55335,26677,N,N,N,55336, -26486,55337,55338,26675,N,55339,55340,26671,55341,55342,55343,13392,26673, -26684,N,26674,N,N,N,55344,55345,26686,55346,26672,18300,55347,55372,N,N,N, -19817,N,N,N,26681,N,N,N,N,N,N,N,26703,55348,55349,55350,26695,N,N,N,16251,N, -55351,N,55352,13638,N,13917,N,26690,55353,55354,55355,N,12891,55356,N,15956,N, -26693,N,N,N,14938,55357,N,17745,26698,N,N,N,N,N,N,N,55359,19054,55360,26689,N, -N,N,12890,14422,18729,26699,N,26687,N,55361,26696,55362,55363,N,26706,55364, -26691,55365,N,26692,17978,N,55366,26697,N,N,55367,26694,19240,26700,12384, -55368,N,55369,N,26688,N,55370,N,N,N,55371,N,N,N,N,N,N,26702,N,26701,N,N,N,N,N, -N,18283,26708,N,26719,N,N,55373,N,13182,N,N,N,26722,N,N,26704,55374,N,N,26709, -19822,N,N,N,N,N,N,N,55375,26718,55376,55377,19797,55378,N,N,55379,20010,55380, -N,55381,55382,N,N,N,55383,17272,55384,55385,55386,13163,55387,N,N,N,55388, -18802,26724,17953,55389,55390,12337,55391,N,26717,55392,26713,16754,26707, -26715,26720,55393,18220,N,55394,55395,12330,55396,26712,55397,26721,18808,N, -55398,55399,N,N,N,55400,26716,N,26711,55401,N,N,N,N,N,15957,N,N,N,N,15663,N, -55402,55403,15404,55404,N,N,N,19544,N,N,18759,N,55405,26727,N,26736,N,N,N,N, -55406,N,55407,55408,55409,N,N,26714,N,55410,N,55411,13175,N,55412,N,N,N,15992, -26725,55413,26730,16755,55414,55415,26726,55416,26733,55417,N,17247,N,26734, -55418,55419,19798,26723,13112,55420,26729,N,55421,26732,19500,N,55422,N,N, -26735,N,N,26728,26731,N,55585,N,N,N,N,N,N,N,N,N,N,55586,N,N,55587,N,19241,N, -20257,55588,55589,55590,55591,N,26739,N,N,55592,N,N,55594,55595,26746,55596,N, -26738,15427,N,55597,55598,N,N,26705,55599,N,N,N,N,55600,N,55601,N,55602,19022, -N,19490,26745,26744,N,26740,26741,N,12598,N,55603,N,55604,26743,N,26737,55605, -55606,55607,55608,17493,55609,N,N,55610,55611,26742,12414,N,55612,N,N,55593, -55613,55614,16930,55615,N,N,N,N,N,N,19011,N,55616,26747,26913,N,18521,N,N, -55617,N,26750,15958,15433,26915,N,N,13886,55618,55619,55620,55621,55622,N, -26916,55623,18809,26749,55624,26710,N,55625,55626,55627,55628,55629,55630, -55631,26748,55632,N,N,N,20303,17954,18803,55633,N,26923,N,55634,N,N,N,N,N,N,N, -26929,N,55635,55636,55637,N,55638,26930,55639,26917,55640,N,N,18294,55641, -55642,26927,26919,55643,26921,55644,55645,N,N,55646,26931,26920,N,55647,26924, -N,N,12658,55648,18021,N,26925,26928,55649,N,55650,55651,N,55652,N,26918,55653, -16678,55654,26922,15143,16197,14128,19572,55668,19577,15730,N,N,N,N,55655,N, -55656,55657,55658,26935,26933,N,55659,55660,55661,55662,N,20302,55663,N,N,N,N, -55664,N,26932,55665,55666,N,19829,55667,26934,26936,N,N,N,N,26937,N,N,55669,N, -55670,N,26940,26938,N,55671,55672,N,N,N,17955,26939,55673,N,55674,18509,26926, -N,N,55675,N,N,N,N,N,55676,N,N,55677,15731,N,26941,26946,16756,55678,N,26945, -55841,55842,N,26914,N,55843,55844,26947,16713,N,N,26942,26944,N,55845,55846,N, -55847,55848,55849,26943,N,N,23857,23842,55850,55851,26949,55852,N,N,55853,N,N, -55854,26948,N,N,N,N,55855,N,55856,N,N,N,19830,N,25148,26950,N,N,N,N,N,55857,N, -55858,N,55859,N,55860,55861,N,26951,55862,47206,55863,N,N,N,55864,N,N,N,N,N,N, -26952,14423,N,13652,N,55865,55866,26954,20829,55867,55868,55869,55870,13685,N, -20026,55871,13939,26955,55872,55873,55874,55875,55876,N,N,26956,N,55877,N, -17262,55878,N,N,55879,N,26957,N,N,N,55880,55881,55882,N,18042,55883,12346,N,N, -N,N,N,N,N,N,N,N,N,N,55917,N,12899,26962,26963,55884,N,N,N,55885,N,26958,N, -15165,55886,N,55887,N,55888,N,55889,N,N,N,N,55890,N,26959,18242,N,55891,55892, -55893,26960,26961,26971,N,55894,N,26965,26968,55895,N,55896,55897,55898,26964, -55899,55900,55901,N,N,N,N,N,55902,55903,55904,N,55905,26966,55906,26967,15448, -N,26969,N,17217,N,14166,13122,N,N,55907,55908,N,26972,55909,N,55910,N,13119, -55911,26977,55912,N,26973,26976,55913,N,N,55914,18490,55915,N,55916,N,26974,N, -N,26975,18760,18522,26978,N,N,N,N,N,N,N,N,17021,26988,55918,26984,55919,55920, -12907,26982,N,19242,26983,55921,55922,26980,55923,26981,26986,26989,55924,N, -26987,55925,55926,55927,26985,26979,55928,55929,N,N,N,17240,55930,26996,N, -19498,N,55931,55932,N,55933,N,55934,N,26994,N,N,56097,26995,N,N,N,N,56098, -56099,N,56100,56101,N,26990,N,N,26992,N,56102,56103,26993,56104,56105,56106, -26991,56107,N,N,56108,N,56109,N,N,N,16486,N,20281,27000,56110,27001,N,N,N,N, -27169,N,16170,N,27003,56111,27006,N,N,N,56112,N,26998,26997,56113,N,27170, -56114,56115,12892,N,27004,N,27171,N,N,N,27005,56116,N,56117,56118,N,27002,N, -17459,N,26999,N,N,56119,N,N,N,18280,N,N,27175,56120,56121,56122,56123,56124, -56125,56126,N,56127,56128,19771,N,N,56129,N,N,56130,N,56131,N,56132,56133, -56134,N,N,N,N,56135,27174,56136,N,27173,56137,N,N,N,56138,N,N,N,27182,56139, -56140,56141,27176,N,56142,N,27184,N,56143,N,N,N,N,19814,27187,N,27178,56144, -56145,27179,56146,N,N,27183,N,27186,27185,56147,56148,56149,27177,N,N,56150,N, -27180,N,27197,N,N,56151,56152,N,N,56153,56154,N,56155,N,N,56156,27190,N,56157, -56158,56159,N,N,N,N,N,56160,56161,N,56162,N,27188,N,56163,27189,56164,N,N, -27194,27195,56165,13098,56166,13634,N,N,27193,56167,56168,N,56169,N,27172, -56170,N,N,56171,56172,56173,N,27192,27196,27191,56174,27198,56176,56177,56178, -27200,27199,N,56179,56175,56180,56181,56182,N,56183,56184,N,27202,27201,26970, -N,N,N,27206,56185,N,N,N,N,56186,56187,N,56188,27203,56189,N,N,56190,27204,N,N, -27205,56353,27207,56354,N,N,N,14188,56355,27209,56356,27208,56357,15664,N, -56358,56359,56360,56361,14676,24103,56362,N,N,56363,27210,15697,N,56364,56365, -13113,56366,27211,56367,12626,56368,15959,27212,56369,56370,14677,27213,12385, -56371,N,N,N,18749,56372,N,27214,N,N,N,N,16234,56373,27221,N,N,27218,N,17263,N, -56374,N,56375,N,27219,27216,13918,56376,27215,27222,N,N,N,N,N,14134,N,N,16990, -N,27228,N,N,N,N,27224,N,N,N,16949,27223,56377,27226,56378,56379,56380,N,27217, -56381,56382,N,27227,N,27229,N,N,N,56383,N,56384,18543,N,N,27225,N,27230,27232, -N,N,14419,27220,N,12353,N,N,56385,N,N,56386,56387,27231,56388,14939,20086, -27233,27234,16757,N,N,N,N,56389,56390,56391,56392,56393,20002,N,56394,56395, -56396,27235,19765,N,N,27236,27237,N,56397,19044,27238,56398,14912,N,20003,N,N, -N,N,N,56399,27243,N,N,N,N,N,N,56400,56401,56402,27244,15960,27242,56403,N, -56404,19815,27239,N,N,27241,16445,16254,56405,27240,N,27245,N,56406,18979,N,N, -27247,N,27246,56407,56408,56409,13164,N,19243,27248,N,56410,56411,N,56412, -56413,56414,N,56415,27260,27250,N,56416,N,N,N,N,27251,56417,56418,56419,N, -27252,27253,N,N,N,N,56420,56421,56422,N,N,56423,27257,N,27258,56424,56425, -27256,N,N,56426,N,56427,27254,56428,27249,27255,56429,56430,N,N,56431,N,N, -27259,28727,N,56432,N,N,56433,N,N,N,12840,56434,N,N,56435,56436,56437,N,27262, -13919,27261,56438,56439,56440,27426,N,27425,N,N,N,27428,56441,N,27427,56442, -27429,56443,N,15665,56444,27430,56445,N,27431,N,N,56446,56609,56610,56611, -27432,16446,N,19799,N,27433,N,N,18980,18246,27434,56612,27435,14379,N,56613,N, -13612,56614,N,N,27436,56615,56616,15211,18241,27437,N,13136,56617,56618,N,N, -56619,56620,27438,N,N,N,56621,27440,19831,N,27439,16198,N,27441,N,N,27442, -56622,N,27443,13393,56623,56624,56625,56626,N,N,27444,N,56627,27445,N,27446, -27447,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,13137,N,56628,56629,56630,56631,56632, -N,27448,N,27449,27450,N,N,N,N,N,12914,N,56633,16168,27451,N,56634,N,56635,N, -56636,N,N,N,56637,N,56638,27452,N,56639,N,27453,56640,N,N,N,56641,N,56642, -14400,N,17531,27454,56643,56644,N,56645,14167,N,16214,N,27457,N,17956,56646, -27456,56647,56648,14129,56649,56650,27455,17015,13613,N,N,27458,N,27459,56651, -15961,56652,N,56653,14189,56654,27460,56655,N,N,N,19244,56656,56657,16479,N, -56658,N,13686,N,19573,16714,56659,27461,56660,N,N,16199,17264,15962,56661, -56662,N,56663,27462,N,56664,N,56665,27465,56666,27466,56667,N,N,N,56668,56669, -N,14910,16962,27464,56670,15963,18750,56671,56672,56673,N,N,27463,56674,56675, -15212,N,12627,56676,27470,14168,N,56677,15214,56678,N,15213,N,20301,27469, -27468,16679,N,13645,20291,13114,15964,N,56679,56680,56681,N,56682,56683,56684, -27467,N,56685,56686,56687,N,27472,56688,27473,27471,56689,14424,N,19776,N, -56690,15215,18215,N,56691,56692,27476,56693,16448,N,17218,56694,56695,19766, -56696,27479,N,N,N,14444,56697,16447,27475,N,27480,14445,27477,27478,56698, -27474,56699,N,N,16482,17993,56700,56701,17199,N,12893,56702,N,N,56865,56866,N, -18544,N,56867,13635,N,56868,17460,N,N,27483,56869,27481,N,56870,17228,56871, -56872,56873,16449,13394,27482,N,16219,N,56874,20042,56875,56876,56877,20288, -56878,N,N,27484,27495,17461,56879,27494,56880,27491,27499,27492,N,27488,N, -17532,27487,N,N,N,27485,56881,19745,15216,N,56882,27489,N,27486,56883,56884, -56885,27493,15732,N,14401,N,56886,N,17018,56887,19269,12634,12386,N,17957, -56888,56889,27497,N,N,56895,56890,27496,N,18022,N,27501,56891,N,N,27490,N, -27500,27502,N,14380,27498,14678,56892,15445,56893,56894,27503,19800,N,N,N,N, -27506,N,27509,N,N,27507,18741,56896,N,N,56897,N,N,27504,N,N,N,56898,N,13920,N, -N,56899,N,27508,N,N,27510,56900,56901,56902,56903,56904,N,56905,27514,N,N, -27511,56910,27513,27512,N,N,56906,56907,56908,N,27515,N,15409,56909,27517, -27516,18792,N,56911,27681,N,N,N,56912,N,N,14169,N,N,N,N,27518,27682,56913,N, -27683,13636,26177,15993,N,27684,N,56914,14446,56915,56916,N,N,56917,27685, -56918,N,27686,56919,N,15166,56920,56921,N,N,N,N,23118,56922,27687,56923,27688, -56924,15666,N,27689,27690,56925,56926,27691,N,N,27692,27693,N,56927,N,56928, -56929,17195,56930,56931,27694,N,N,56932,56933,27696,N,27695,N,N,N,56934,17958, -56935,27697,56936,19245,56937,27698,N,27699,56938,27700,56939,N,56940,56941, -27701,N,56942,56943,56946,18010,56944,N,56945,N,N,N,15965,27702,56947,56948,N, -56949,N,56950,56951,14699,20526,27703,56952,N,N,N,N,N,56953,N,56954,56955,N, -27704,18751,27705,56956,27713,N,56957,N,N,N,27706,N,N,27708,56958,57121,N, -27707,27709,57122,19270,27710,27711,N,57123,N,57124,57125,27712,N,N,N,27714, -57126,N,57127,57128,13101,17511,N,18793,14946,14679,N,57129,N,N,18767,12895, -18510,27717,13395,16469,27716,27721,17273,19555,N,27719,27720,13614,N,27722, -18275,16991,57130,57131,18545,17725,27718,N,19271,12908,27724,20264,17474, -20293,57132,57133,15217,27723,57134,16945,57135,N,27740,16680,57136,N,18040,N, -18768,N,57138,57137,N,N,57139,27727,15167,15218,57140,15966,N,18277,57141, -14381,27726,27725,N,18794,N,57142,N,15425,N,57143,17746,N,57144,57145,N,57146, -N,N,57147,N,57148,57149,N,27729,27730,14680,27728,57150,57151,57152,N,57153, -27731,27732,N,27734,16931,57154,27733,13414,N,27736,N,27735,27737,N,57155, -27739,27741,N,27742,57156,N,N,N,57157,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,16470,57158,15439,27743,N,57159,N,13138,57160,27744, -57161,N,16758,27745,N,27746,18795,N,N,13615,N,N,N,N,N,N,N,57162,N,27747,57163, -N,57164,17462,N,N,57165,N,12635,N,N,57166,N,N,57167,57168,N,N,N,57169,N,N,N, -27748,N,N,N,N,57170,57171,57172,N,N,15473,N,N,57173,N,16246,N,N,57174,57175,N, -N,57176,N,N,57177,16941,N,57178,N,57179,N,57180,27751,57181,57199,N,27750,N, -57182,N,27749,N,N,57183,57184,57185,57186,N,57187,27757,27755,N,57188,27752,N, -57189,N,N,57190,57191,27754,57192,N,57193,27753,27756,N,13687,N,27760,N,16471, -N,27761,57194,57195,N,57196,14425,N,27758,27759,57197,N,N,20265,57198,57200, -57201,17463,57202,16681,N,N,N,N,N,N,27762,57203,N,27765,57204,N,N,57205,57206, -57207,N,27763,27764,19801,57208,N,N,N,17959,27768,57209,N,N,57210,N,57211,N,N, -N,N,N,N,27766,27767,27769,57212,57213,57214,57377,N,N,57378,57379,N,N,27945,N, -N,N,N,N,27772,57380,N,57381,27773,27771,57382,57383,57384,57385,N,N,N,57386,N, -N,57387,57388,27770,N,17533,N,N,27937,27941,27938,27774,57389,27939,57390, -57391,57392,27940,N,N,N,57393,27947,N,N,N,27942,N,57394,57395,57396,57397, -16472,27944,57398,57399,27946,27943,N,N,N,N,57400,N,N,57401,57402,N,57403, -57404,57405,27949,N,15667,N,27948,N,N,57406,57407,57408,27950,N,N,N,N,27951, -57409,57410,27954,27953,N,27952,N,57411,27956,27955,N,19574,N,N,57412,27958, -57413,27957,27959,57414,N,N,N,27960,57415,57416,N,57417,57418,N,N,27962,57419, -N,N,N,N,57420,N,57421,27961,16200,27963,57422,57423,13933,27964,27966,N,57424, -N,57425,N,N,N,N,57426,57427,N,N,27967,N,57428,57429,N,57430,57431,27968,27965, -57432,27969,N,15446,27970,13616,14131,N,57433,N,57434,14382,N,57435,N,N,N,N,N, -N,27971,57436,N,N,18032,N,N,17726,27972,N,N,N,N,57437,N,N,27975,N,57444,57438, -N,57439,57440,N,N,N,N,N,57441,15412,57442,57443,27974,27973,14170,27976,57445, -N,57446,13139,N,27978,N,57447,57448,14940,27977,N,27986,N,N,57449,57450,N, -27980,27982,19045,27979,57451,57452,57453,27981,N,27985,27983,13617,57454, -27984,57455,57456,N,57457,N,57458,27987,57459,57460,18266,20056,N,57461,57462, -57463,15668,N,N,N,27988,57464,57465,57466,57467,19746,27990,57468,27989,N,N, -27993,19777,57469,57470,27992,57633,13165,27991,27996,57634,N,27995,N,N,27994, -17714,27997,57635,N,57636,57637,57638,57639,57640,N,27998,57641,N,N,N,27999, -57642,57643,14700,N,14117,28000,28001,28002,57644,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -16201,28003,57645,15405,28004,57646,57647,N,28005,57648,57649,57650,21025, -20862,N,N,N,N,28006,25968,28007,17188,16171,18240,N,N,57651,57652,28008,57653, -N,19029,17492,14718,N,57654,17193,57655,57656,12586,N,19320,16215,57657,N,N,N, -57658,57659,N,57660,14174,N,57661,13921,57662,57663,19030,57664,N,N,N,N,28009, -N,N,N,N,N,57665,N,28011,57666,57667,28010,12896,N,57668,18038,28012,18295,N, -17715,57669,28013,15698,57670,N,N,28015,57671,57672,19522,28030,28017,28018, -57673,N,17481,57674,16992,16759,57675,17960,57676,28016,13653,N,57677,N,N, -28025,57678,28022,28197,17961,17248,28019,N,17534,17747,28020,28024,16224, -57679,18279,17484,57680,N,16450,28023,16942,16932,28021,12329,20258,N,N,N, -28026,57681,57682,57684,N,57685,57686,16993,57683,N,15669,16202,57687,57688, -28028,28027,57689,12399,28029,N,N,18735,N,28199,57690,N,18011,16235,57691, -57692,17241,N,13944,N,28198,19767,12607,57693,19031,12897,28193,28194,28195, -28196,17979,17187,12387,28200,N,28201,29731,N,57694,16957,57695,28202,N,12659, -16716,57696,14383,N,19802,57697,57698,28203,17708,N,N,57699,16760,15447,28204, -57700,N,28207,N,57701,15717,28205,16683,16682,57702,12388,N,20043,28209,N, -18546,28211,28210,28208,25444,13396,57703,N,28014,57704,28213,28212,57705, -57706,N,57707,28214,57708,19768,N,N,N,57709,N,57710,57711,57712,N,57713,N,N,N, -N,57714,57715,57716,18017,N,57717,19246,N,28215,N,15449,N,N,N,N,28216,57718, -28217,57719,57720,57721,28218,57722,N,17697,N,N,N,N,57723,57725,N,N,12394,N, -57726,57889,57890,N,57891,57892,N,14681,N,57724,N,20282,N,N,N,57901,N,N,57893, -N,57894,57895,57896,N,28222,57897,57898,N,57899,N,14132,28219,N,28220,57900,N, -N,18804,N,N,57903,N,13140,N,57904,57905,N,N,N,57906,19769,57902,13887,N,N,N,N, -N,17748,57907,57908,57909,N,28223,N,57910,57911,57912,N,57913,N,N,N,N,57914,N, -N,57915,N,28224,N,57916,N,57917,57918,57919,28225,57920,N,57921,N,57922,N, -57923,N,57925,57926,N,57924,N,57927,N,57928,N,N,N,17698,57929,57930,28227, -57931,28226,N,57932,N,57933,57934,N,57935,57936,N,57937,57938,N,N,N,N,N,57939, -N,N,N,57940,57941,18003,28228,15670,15456,18267,17265,57942,N,N,15474,57943, -16236,N,28229,57944,28230,57945,57946,57947,N,N,N,N,N,57948,16221,28231,57949, -28232,N,57950,N,28233,19823,N,15671,57951,N,N,N,N,28235,28234,57952,14682,N, -14707,15168,57953,57954,57955,N,N,N,N,N,57956,28238,57957,N,57958,57959,15718, -N,28237,57960,28236,N,17001,57961,N,14447,57962,16451,57963,57964,57965,N, -18480,57966,N,N,N,15673,N,57967,N,N,57968,28239,N,15967,N,57969,N,57970,N, -28242,28240,57971,57972,57973,28241,57974,57975,57976,57977,28244,28243,57978, -N,15994,N,28245,57979,57980,57981,N,57982,28246,28247,58145,58146,N,58147, -18512,14931,15457,28248,N,28249,20004,15685,19566,20044,28250,13922,N,58148, -58149,N,28251,58150,17699,58151,58152,28254,13176,16203,58153,28252,N,28253,N, -17504,58154,58155,19285,13948,N,58156,58157,N,58158,58159,58160,58161,58162, -58163,N,N,N,28256,28257,58164,N,58165,N,58166,28255,58167,N,28259,58168,58169, -N,N,58170,58171,58172,58173,N,58174,58175,N,58176,18015,13123,N,58177,28263, -58178,58179,28260,28262,58180,N,58181,N,N,N,58182,58183,28258,N,N,N,N,58184, -58185,58186,58187,N,58188,28495,N,N,28261,N,58189,58190,58191,N,N,58192,20075, -58193,58194,14426,58195,58196,58197,N,58198,N,58199,28271,58200,N,58201,58202, -17716,28266,58203,58204,28269,28267,58205,28272,N,58206,58207,58208,28273, -58209,N,N,N,N,N,28265,58210,58211,28278,12660,58212,58213,28264,N,58214,58215, -18477,N,28268,58216,15968,58217,58218,58219,N,N,N,N,58220,58221,58222,14683,N, -N,N,58223,58224,58225,58226,58227,N,58228,58229,58230,19272,58231,13924,N,N, -15686,N,17980,N,N,58232,58233,58234,N,N,58235,58236,N,N,16685,58237,28276,N, -28270,28275,58238,19523,58401,17464,28277,28274,N,N,58402,58403,N,N,N,58404, -58405,N,58406,58407,N,N,58408,N,16684,N,58409,N,N,58410,N,N,N,58411,28281, -58412,28280,58413,58414,58415,58416,N,58417,58418,58419,58420,58421,N,58422, -58423,58424,58425,N,N,58426,58427,58428,58429,28279,58430,N,19247,58431,N, -58432,N,58433,58434,58435,N,N,58436,58437,N,58438,58439,58440,N,58441,15739, -58442,N,58443,58444,28282,19039,N,58445,12628,58446,N,58447,N,18758,17266,N,N, -N,N,13688,58448,28284,58449,14685,N,N,58450,58451,N,58452,N,N,N,15148,N,58453, -N,N,N,N,58454,N,28283,16237,58455,N,N,58456,58457,N,N,16238,28449,28451,N, -58458,58459,58460,58461,15995,58462,28450,28452,58463,58464,13907,58465,18757, -58466,58467,15458,20259,N,28286,14968,N,N,20287,58468,58469,28454,58470,58471, -N,N,28453,28455,N,N,N,N,N,N,N,N,28285,N,N,58472,58473,58474,N,18025,N,17749,N, -N,58475,58476,58477,N,17495,58478,28460,58479,58480,N,58481,17219,28456,N, -58482,N,28457,N,N,N,58483,58484,N,58485,N,58486,58487,N,14125,58488,28459, -58489,58490,58491,N,58492,58493,14384,58494,N,N,N,58657,N,28458,58658,15969, -58659,58660,58661,58662,N,N,N,N,N,58663,N,58664,58665,13177,58666,N,58667,N,N, -58668,N,28464,58669,14911,16761,58670,N,17482,58671,N,N,58672,N,N,58673,N, -58674,58675,N,58676,13115,58677,58683,N,58678,28462,28463,17475,N,28461,N,N,N, -58679,58680,58681,N,N,28465,58682,N,N,N,N,N,N,58684,N,28471,58685,58686,58687, -58688,28474,58689,58690,58691,58692,58693,N,N,28473,17709,N,58694,N,N,28466, -28467,28470,58695,N,N,58696,28472,58697,58698,N,13888,58699,N,28475,28469, -58700,58701,28468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,58703,58704,58702,58705,58706,N, -58707,58708,58709,28479,58710,N,N,28480,58711,58712,N,N,N,58713,58714,58715, -28481,N,N,28478,28477,58716,58717,58718,15970,17962,28476,N,N,N,N,58719,N, -28485,N,N,N,N,N,N,N,N,N,28483,N,N,58720,58721,N,58722,58723,58724,58725,28484, -28482,N,17016,N,28486,58726,N,58728,N,58727,N,28487,N,58729,28489,58730,N,N, -58731,N,58732,N,58733,N,N,N,N,13397,28488,19578,N,58734,N,N,N,58735,28500, -28490,58736,N,28493,58737,28491,58738,28492,58739,N,N,N,N,58740,N,28494,58741, -N,58742,58743,58744,28496,58745,58746,N,N,28497,N,28498,N,N,N,N,28501,28499, -28502,28504,N,28503,N,58748,58747,17465,58749,58750,N,N,N,N,58913,N,19559,N, -28505,16686,58914,N,N,28506,58915,19012,28507,13099,58916,58917,58918,12604,N, -13399,N,13398,28508,N,28509,N,28510,28511,N,N,N,58919,58920,58921,28512,58922, -13400,13141,14686,18486,58923,28514,28513,58924,N,58925,58926,28515,N,N,N,N, -12636,N,58927,N,58928,N,N,28518,58929,28517,28516,58930,28519,58931,N,N,N, -28522,N,N,58932,12359,58933,58934,28520,58935,28524,28523,N,N,58936,58937, -58938,58939,28526,28525,28527,N,17966,58940,58941,N,28528,58942,58943,58944, -58945,28529,28531,N,58946,28530,58947,18796,58948,58949,N,N,28532,58950,N, -58951,58952,58953,N,28533,N,14949,N,58954,N,28534,28535,N,58955,19273,58956,N, -N,N,58957,58958,58959,58960,16715,58961,58962,N,12324,16971,58963,28536,N, -18797,N,N,N,N,N,N,28539,28537,14687,N,28538,14402,N,58964,N,58965,N,58966, -58967,58968,N,N,19013,28541,28705,28542,28706,N,58969,12577,16216,15740,13401, -28707,N,N,N,18278,N,28709,N,58970,N,12578,N,28708,17476,58971,20045,17963, -28540,20006,N,14385,58972,58973,19803,58974,58975,N,58976,58977,58978,58979, -13945,20020,N,14120,58980,16994,26401,N,28710,13100,16239,N,58981,N,N,13142, -28712,58982,28713,28711,14180,58983,14941,15971,58984,N,58985,12579,N,N,20057, -58986,58987,58988,28715,28206,58989,28714,N,N,N,58990,58991,28718,28716,28717, -58992,28719,N,28720,20076,28721,28722,58993,16457,18491,N,N,N,16253,13415,N,N, -19770,12909,15672,14427,N,28725,58994,28724,15219,28726,28723,N,N,15144,58995, -N,N,28730,27181,N,58997,21078,58998,16247,28728,58999,59000,59001,N,N,20005, -18033,N,N,N,N,12587,59002,16483,15414,N,N,N,59003,18999,59004,12608,N,N,N, -20077,19819,N,28731,59005,17733,15483,N,59006,59169,28732,59170,28733,16204, -28734,59171,20078,N,N,28729,28736,28738,N,28737,N,28735,N,N,28739,N,N,28740, -59172,59173,16762,59174,12898,N,N,59175,59176,59177,28741,N,N,19512,59178,N, -28742,N,N,N,N,N,28743,59179,20266,59180,N,N,N,N,23345,28744,N,N,N,28745,28746, -N,N,59181,28750,59182,28747,N,28748,N,28749,28751,59183,N,N,N,59184,59185,N,N, -16452,N,N,59186,19575,59187,59188,16453,59189,59190,28752,N,18547,N,28753, -29523,19532,59191,28754,N,28755,59192,28756,13143,59193,28758,N,16217,59194,N, -N,28759,N,59195,14116,N,59196,59197,59198,28760,28764,59199,28762,59200,N, -59201,59202,28763,N,N,13171,28761,28765,N,N,59203,N,28766,N,12360,N,28767, -28768,N,N,N,N,59204,59205,59206,15972,59207,59208,N,28769,N,59209,59210,13639, -N,59211,28772,N,N,28771,N,28770,N,N,27505,59212,19036,59213,N,N,59214,59215, -28773,28774,59216,59217,N,59218,59219,59220,N,59221,N,59222,59223,N,59224,N, -28775,59225,59226,28776,59227,28777,59228,59229,28778,59230,59231,59232,N, -59233,59234,N,13402,59235,N,N,59236,59237,59238,N,59242,28779,59239,59240,N, -59241,59243,N,N,59244,N,N,N,N,N,N,N,N,28780,18211,59245,N,59246,28782,12859, -59247,28785,28784,59248,59249,N,59250,12580,N,N,N,13889,19015,17466,14882,N, -14688,15719,59251,16220,N,59252,N,28787,59254,59255,28786,19778,13416,18514, -18012,59256,N,59257,16252,20046,59253,14171,N,59258,N,59259,N,59260,28790,N, -59261,28789,59432,59262,N,N,N,N,59425,19275,17964,59426,59427,59428,N,59429, -59430,12624,59431,N,28791,28788,N,N,18769,19818,28792,59433,N,N,N,N,N,59434,N, -28793,59435,N,N,59436,28795,17002,13147,13148,28794,N,59437,59438,59439,13417, -14386,59440,59441,13418,59442,59443,17727,N,N,20064,N,N,N,59444,59445,N,59446, -59447,14428,N,N,59448,28796,59449,N,N,28797,28798,28961,N,28963,28962,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,18807,N,28964,59450,N,59451,59452,28965,59453,28966,N,N,59454, -N,28967,59455,59456,N,59457,59458,N,N,N,59459,N,N,59460,28969,28968,59461, -28970,N,59462,N,N,N,59463,N,N,N,N,N,N,N,N,N,N,N,N,N,N,18548,26188,N,N,16169,N, -59464,13618,59465,N,59466,59467,59468,N,28971,59469,28972,N,21036,23867,18515, -N,N,12411,59470,12347,N,59471,N,N,N,N,N,15220,19248,15998,59472,28973,N,19551, -N,59473,59474,28974,19804,N,12610,N,N,N,15169,59475,28975,12910,28976,59476, -59477,59478,28977,N,59479,59480,59481,28979,28980,59482,28982,28978,59483,N, -28981,N,59484,59485,13403,N,N,59486,28983,N,28984,N,N,59487,59488,59489,59490, -59491,N,N,N,59492,59493,59494,59495,28985,28986,N,59496,59497,28987,N,N,28989, -59498,59499,59500,28988,N,28991,28994,59501,59502,N,28990,28992,28993,N,59503, -28995,N,13890,59504,59505,N,59506,59507,N,59508,59509,59510,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,15475,28996,28997,14689,N,59511,N,59512,N,59513,N,N,N,N,N,28998, -59514,N,13118,N,N,N,18255,28999,29000,N,59515,59516,59517,17242,18027,59518,N, -N,N,59681,59682,N,29001,59683,N,59684,N,18301,N,59685,16972,12632,13934,N, -13935,59686,N,N,N,N,N,N,17267,29006,13936,59687,59688,12911,N,N,29005,59689, -59690,29003,59691,29004,59692,29002,N,N,29016,N,N,N,N,59693,N,N,59694,59695, -59696,29007,29008,N,59697,29009,29010,N,59698,59699,N,N,29012,59700,N,29011,N, -59701,59702,15705,29013,59703,59704,59705,29015,N,N,N,N,N,59706,59707,N,13619, -29014,59708,59709,16763,14387,N,N,59710,N,N,29017,N,N,N,N,59711,N,59712,N, -59713,59714,59715,N,N,59716,16973,N,N,29018,N,59717,59718,N,17965,N,N,59719,N, -59720,59721,29019,59722,N,N,N,N,N,29024,N,29022,59724,29021,29023,59725,29020, -N,59723,N,N,59726,59727,59728,29026,59729,N,N,59730,N,N,59731,29025,59732, -29028,N,N,13891,29027,N,59733,N,29029,N,N,29030,N,29032,29031,N,N,N,29033, -29035,29034,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,14716,N,59734,N,59735, -29036,59736,59737,29037,N,59738,N,59739,59740,59741,N,13116,59742,N,59743, -29038,N,59744,59745,29039,59746,N,59747,16241,N,59748,N,59749,N,N,N,N,N,59750, -29040,59751,29041,59752,29042,29043,59753,59754,59755,14690,N,N,59756,59757,N, -29044,29045,59758,N,29046,29047,59759,59760,29048,59761,N,59762,18481,29050, -59763,18726,29051,29049,N,29053,59764,59765,29052,59766,N,29054,N,59767,59768, -29217,N,59769,N,59770,59771,59772,59773,59774,59937,59938,29218,N,59939,59940, -N,59941,59942,59943,59944,N,59945,N,59946,N,N,N,59947,N,29219,59948,29220, -59949,59950,N,N,29221,59951,N,29222,29223,N,29224,59952,29225,29226,29227, -29228,59953,N,59954,29229,29230,N,23861,29231,59955,59956,59957,N,59958,N, -59959,59960,25720,13620,59961,N,N,N,13089,14898,29233,29232,19493,N,N,59962,N, -N,59963,59964,29235,29236,29234,N,29237,N,N,19298,59965,59966,59967,29238,N, -13691,59968,N,N,59969,N,N,59970,N,59971,N,59972,59973,N,59974,N,59975,59976, -59977,59978,59979,20261,N,N,N,59980,29239,59981,N,59982,59983,59984,N,N,N,N,N, -59985,59986,N,N,29241,59987,59988,59989,59990,N,59991,59992,59993,N,59994, -12350,59995,59996,29242,18987,29240,59997,N,29243,29244,N,N,59998,N,N,59999, -60000,29245,29246,N,N,N,N,N,60001,60002,29247,60003,19310,15149,60004,14970, -16687,N,60005,60006,60007,N,29248,N,N,60008,60009,29251,N,60010,60011,N,60012, -60013,29249,60014,N,N,N,N,29252,60015,60016,14449,29250,N,N,N,60017,29253, -60018,29254,29255,N,29259,N,15146,60019,60020,N,N,16996,N,60021,N,60022,N, -29260,29257,29256,29258,60023,N,60024,14175,N,60025,60026,N,N,N,60027,29264, -29263,29262,60028,N,12339,N,60029,60030,60193,60194,N,N,60195,N,60196,60197,N, -60198,N,29274,N,29270,N,29271,29267,29273,60199,29269,13154,N,60200,20300, -60201,29272,29268,29266,29265,60202,N,60203,60204,60205,29276,60206,N,60207,N, -N,29279,60208,60209,29278,29277,60210,60211,60212,60213,60214,N,N,18761,29275, -12403,29280,60215,29282,N,N,60216,60217,60218,N,13167,29261,12599,N,60219, -29284,N,N,60220,N,60221,60222,60223,29283,29281,17197,60224,60225,N,N,N,60226, -60227,60228,N,19312,60229,60230,N,60231,20058,60232,N,29285,60233,60240,60234, -60235,60236,29286,N,N,60237,N,N,N,29287,60242,60238,60239,60241,N,N,60243,N, -60244,N,60245,N,N,60246,29288,60247,29289,N,N,60248,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,17467,60249,29290,N,18487,N,29295,29291,N,N,N, -29292,N,60250,19249,19524,N,18000,60251,N,60252,60254,29296,N,N,29297,17982, -29294,29293,N,60253,N,N,12842,N,N,60255,29305,N,N,29304,N,60256,60257,N,N, -12661,60258,60259,60260,29302,N,N,N,29301,N,N,29299,N,13179,N,29298,15410, -12841,N,N,60261,60262,N,60263,60264,60265,N,N,N,N,N,60266,14691,60267,60269, -29308,29307,N,29306,60270,60271,29303,60268,29309,60272,29310,N,60273,N,N,N,N, -N,29477,29476,N,60274,60275,N,N,N,N,29478,N,N,12589,29473,29474,60276,14708, -19513,60278,60277,29475,60279,N,N,N,60280,60281,60282,19250,N,N,29483,60283,N, -29479,N,N,N,60284,60285,N,N,29484,60286,60449,N,60450,N,N,N,N,60451,60452,N, -60453,29481,N,29480,60454,N,N,60455,60456,14172,N,N,60457,60458,N,60459,60460, -60461,60462,N,29485,N,N,N,N,N,N,60463,N,N,29486,N,N,N,N,29487,60464,29482, -60465,N,60466,29300,N,60467,29488,N,17505,60468,N,N,29492,60469,29493,29491, -60470,N,N,60471,N,29490,29496,60472,29489,N,29494,60473,N,60474,60475,N,N,N,N, -29495,N,N,N,29498,60476,60477,60478,60479,N,29497,60480,N,N,N,60481,60482, -60483,N,N,N,N,60484,29500,60485,N,60486,N,60487,N,29501,60488,29502,60489,N, -20297,60490,60491,N,N,N,29499,17003,14957,N,N,29503,60492,60494,N,N,N,N,60495, -N,N,60493,N,N,N,60496,N,60497,60498,60499,N,N,60500,60501,N,N,60502,29504, -29505,60503,60504,29506,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29507,N,N,14388,29508,60505,60506, -60507,29509,N,15407,60508,29510,60509,60510,60511,60512,N,60513,29511,N,N, -29512,29513,N,60514,60515,N,29516,29514,20284,N,29515,60516,20079,60517,N,N, -60518,N,29517,60519,20059,N,N,N,N,60520,29518,18302,N,60521,29519,29521,N, -60522,29522,60523,60524,60525,N,N,60526,60527,60528,N,N,29520,14701,19533, -19299,22135,N,23904,19323,N,N,N,N,12843,N,60529,N,60530,N,N,60531,29524,13648, -29525,29526,29527,N,14709,N,29528,60532,N,N,24660,19547,N,16995,29529,29531, -29530,60533,29532,N,N,N,60534,29533,N,60535,29534,N,N,N,60536,60537,60538, -29535,60539,60540,60541,N,29536,60542,29537,29538,60705,29539,N,29540,29541, -29542,N,60706,60707,60708,N,N,N,29543,29544,60709,N,N,N,N,17700,60710,60711, -60712,60713,14429,60714,29546,60715,60716,N,60717,60718,60719,N,N,N,60720, -16717,29547,60721,N,N,N,60722,N,N,N,60723,60724,29548,N,N,60725,N,60726,60727, -N,60728,N,N,60729,N,60730,60731,18721,60732,60733,29549,60734,N,60735,N,60736, -60737,60738,60739,60740,N,N,29550,25399,N,N,27738,28781,N,N,29551,60741,29552, -60742,60743,60744,60745,N,60746,N,N,60747,60748,29554,29555,29556,20080,29553, -N,N,29557,29558,60749,60750,29560,N,29559,60751,60752,60753,60754,60755,29562, -60756,N,60757,29563,29561,N,N,60758,N,N,60759,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -20022,N,60760,60761,60762,60763,N,60764,29564,60765,60766,N,N,N,N,29565,25428, -60767,N,29566,60768,60769,60770,N,60771,8490,N,8564,8560,8563,8565,N,8522, -8523,8566,8540,8484,N,8485,8511,9008,9009,9010,9011,9012,9013,9014,9015,9016, -9017,8487,8488,8547,8545,8548,8489,8567,9025,9026,9027,9028,9029,9030,9031, -9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,9046, -9047,9048,9049,9050,8526,N,8527,8496,8498,8494,9057,9058,9059,9060,9061,9062, -9063,9064,9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,9076,9077, -9078,9079,9080,9081,9082,8528,8515,8529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8497, -N,8559, -}; - -static const struct unim_index jisxcommon_encmap[256] = { -{__jisxcommon_encmap+0,92,255},{__jisxcommon_encmap+164,0,245},{ -__jisxcommon_encmap+410,199,221},{__jisxcommon_encmap+433,132,206},{ -__jisxcommon_encmap+508,1,95},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{__jisxcommon_encmap+603,16,59},{__jisxcommon_encmap+647,3,212},{ -__jisxcommon_encmap+857,0,165},{__jisxcommon_encmap+1023,18,18},{0,0,0},{ -__jisxcommon_encmap+1024,0,239},{__jisxcommon_encmap+1264,5,111},{0,0,0},{0,0, -0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__jisxcommon_encmap+1371,0,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisxcommon_encmap+1626,0,255},{ -__jisxcommon_encmap+1882,0,255},{__jisxcommon_encmap+2138,0,254},{ -__jisxcommon_encmap+2393,0,254},{__jisxcommon_encmap+2648,0,255},{ -__jisxcommon_encmap+2904,0,250},{__jisxcommon_encmap+3155,1,255},{ -__jisxcommon_encmap+3410,0,255},{__jisxcommon_encmap+3666,5,255},{ -__jisxcommon_encmap+3917,0,255},{__jisxcommon_encmap+4173,0,253},{ -__jisxcommon_encmap+4427,2,255},{__jisxcommon_encmap+4681,0,253},{ -__jisxcommon_encmap+4935,0,255},{__jisxcommon_encmap+5191,1,253},{ -__jisxcommon_encmap+5444,1,254},{__jisxcommon_encmap+5698,0,255},{ -__jisxcommon_encmap+5954,1,255},{__jisxcommon_encmap+6209,7,253},{ -__jisxcommon_encmap+6456,0,255},{__jisxcommon_encmap+6712,0,255},{ -__jisxcommon_encmap+6968,1,250},{__jisxcommon_encmap+7218,6,255},{ -__jisxcommon_encmap+7468,0,255},{__jisxcommon_encmap+7724,0,255},{ -__jisxcommon_encmap+7980,0,255},{__jisxcommon_encmap+8236,2,253},{ -__jisxcommon_encmap+8488,0,255},{__jisxcommon_encmap+8744,0,253},{ -__jisxcommon_encmap+8998,2,255},{__jisxcommon_encmap+9252,2,244},{ -__jisxcommon_encmap+9495,4,252},{__jisxcommon_encmap+9744,0,255},{ -__jisxcommon_encmap+10000,1,254},{__jisxcommon_encmap+10254,0,253},{ -__jisxcommon_encmap+10508,3,255},{__jisxcommon_encmap+10761,0,254},{ -__jisxcommon_encmap+11016,2,255},{__jisxcommon_encmap+11270,0,255},{ -__jisxcommon_encmap+11526,3,255},{__jisxcommon_encmap+11779,0,254},{ -__jisxcommon_encmap+12034,0,252},{__jisxcommon_encmap+12287,2,255},{ -__jisxcommon_encmap+12541,0,252},{__jisxcommon_encmap+12794,0,255},{ -__jisxcommon_encmap+13050,2,254},{__jisxcommon_encmap+13303,0,254},{ -__jisxcommon_encmap+13558,0,251},{__jisxcommon_encmap+13810,0,158},{ -__jisxcommon_encmap+13969,54,255},{__jisxcommon_encmap+14171,0,254},{ -__jisxcommon_encmap+14426,2,255},{__jisxcommon_encmap+14680,0,254},{ -__jisxcommon_encmap+14935,0,253},{__jisxcommon_encmap+15189,1,255},{ -__jisxcommon_encmap+15444,0,255},{__jisxcommon_encmap+15700,0,254},{ -__jisxcommon_encmap+15955,0,255},{__jisxcommon_encmap+16211,1,254},{ -__jisxcommon_encmap+16465,1,255},{__jisxcommon_encmap+16720,0,255},{ -__jisxcommon_encmap+16976,0,159},{__jisxcommon_encmap+17136,55,255},{ -__jisxcommon_encmap+17337,1,255},{__jisxcommon_encmap+17592,1,254},{ -__jisxcommon_encmap+17846,0,254},{__jisxcommon_encmap+18101,0,255},{ -__jisxcommon_encmap+18357,0,255},{__jisxcommon_encmap+18613,0,255},{ -__jisxcommon_encmap+18869,0,253},{__jisxcommon_encmap+19123,1,132},{ -__jisxcommon_encmap+19255,119,230},{__jisxcommon_encmap+19367,28,251},{ -__jisxcommon_encmap+19591,0,255},{__jisxcommon_encmap+19847,1,254},{ -__jisxcommon_encmap+20101,2,255},{__jisxcommon_encmap+20355,1,255},{ -__jisxcommon_encmap+20610,0,255},{__jisxcommon_encmap+20866,0,249},{ -__jisxcommon_encmap+21116,2,254},{__jisxcommon_encmap+21369,2,255},{ -__jisxcommon_encmap+21623,2,165},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0, -0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{__jisxcommon_encmap+21787,1,229}, -}; - -static const ucs2_t __cp932ext_decmap[969] = { -65340,65374,8741,65372,8230,8229,8216,8217,8220,8221,65288,65289,12308,12309, -65339,65341,65371,65373,12296,12297,12298,12299,12300,12301,12302,12303,12304, -12305,65291,65293,177,215,U,247,65309,8800,65308,65310,8806,8807,8734,8756, -9794,9792,176,8242,8243,8451,65509,65284,65504,65505,65285,65283,65286,65290, -65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660, -8251,12306,8594,8592,8593,8595,12307,U,U,U,U,U,U,U,U,U,U,U,8712,8715,8838, -8839,8834,8835,8746,8745,U,U,U,U,U,U,U,U,8743,8744,65506,9312,9313,9314,9315, -9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330, -9331,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,U,13129,13076,13090, -13133,13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115, -13212,13213,13214,13198,13199,13252,13217,U,U,U,U,U,U,U,U,13179,U,12317,12319, -8470,13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181, -13180,8786,8801,8747,8750,8721,8730,8869,8736,8735,8895,8757,8745,8746,32394, -35100,37704,37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193, -20220,20224,20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479, -20510,20550,20592,20546,20628,20724,20696,20810,20836,20893,20926,20972,21013, -21148,21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660, -21642,21673,21759,21894,22361,22373,22444,22472,22471,64015,U,64016,22686, -22706,22795,22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532, -23582,23718,23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353, -24372,24423,24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887, -24880,24984,25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121, -26158,26142,26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362, -26382,63785,26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032, -27106,27184,27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759, -27866,27908,28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199, -28220,28351,28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020, -28998,28999,64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654, -29667,29650,29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063, -30338,30364,30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024, -64024,64025,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072, -32092,32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782, -33864,33972,34131,34137,U,34155,64031,34224,64032,64033,34823,35061,35346, -35383,35449,35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214, -64035,36559,64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357, -37358,37348,37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433, -37479,37543,37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669, -37665,37627,64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880, -37937,37957,37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735, -38737,38741,38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797, -39794,39823,39857,39867,39936,40304,40299,64045,40473,40657,U,U,8560,8561, -8562,8563,8564,8565,8566,8567,8568,8569,65506,65508,65287,65282,8560,8561, -8562,8563,8564,8565,8566,8567,8568,8569,8544,8545,8546,8547,8548,8549,8550, -8551,8552,8553,65506,65508,65287,65282,12849,8470,8481,8757,32394,35100,37704, -37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193,20220,20224, -20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479,20510,20550, -20592,20546,20628,20724,20696,20810,U,20836,20893,20926,20972,21013,21148, -21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660,21642, -21673,21759,21894,22361,22373,22444,22472,22471,64015,64016,22686,22706,22795, -22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532,23582,23718, -23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353,24372,24423, -24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887,24880,24984, -25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121,26158,26142, -26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362,26382,63785, -26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032,27106,27184, -27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759,27866,27908, -28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199,28220,28351, -28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020,28998,28999, -64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654,29667,29650, -29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063,30338,30364, -30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024,64024,64025, -U,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072,32092, -32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782,33864, -33972,34131,34137,34155,64031,34224,64032,64033,34823,35061,35346,35383,35449, -35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214,64035,36559, -64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357,37358,37348, -37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433,37479,37543, -37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669,37665,37627, -64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880,37937,37957, -37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735,38737,38741, -38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797,39794,39823, -39857,39867,39936,40304,40299,64045,40473,40657, -}; - -static const struct dbcs_index cp932ext_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_decmap+0,95,202},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{__cp932ext_decmap+108,64,156},{0,0,0},{0,0,0},{0,0,0},{0,0, -0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{__cp932ext_decmap+201,64,252},{__cp932ext_decmap+390,64,252},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__cp932ext_decmap+579,64,252},{__cp932ext_decmap+768,64,252},{ -__cp932ext_decmap+957,64,75},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const DBCHAR __cp932ext_encmap[9686] = { -34690,N,N,N,N,N,N,N,N,N,N,34692,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -34644,34645,34646,34647,34648,34649,34650,34651,34652,34653,N,N,N,N,N,N,61167, -61168,61169,61170,61171,61172,61173,61174,61175,61176,34708,N,N,N,N,N,N,N,N,N, -N,N,N,N,34712,N,N,N,N,N,33121,N,N,N,N,N,N,N,N,34707,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,34713,34624,34625,34626,34627,34628,34629,34630, -34631,34632,34633,34634,34635,34636,34637,34638,34639,34640,34641,34642,34643, -34688,N,34689,34698,34699,N,N,N,N,N,N,34700,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,34693,34694,34695,34696,34697,34661,N,N,N,N,N,N,N,N,N, -34665,N,N,N,N,N,N,34656,N,N,N,34659,N,N,N,N,N,N,N,N,N,34657,34667,N,N,34666, -34660,N,N,N,34668,N,N,N,N,N,N,N,N,N,N,34662,N,N,N,N,34670,N,N,N,N,N,N,N,N,N,N, -N,N,N,34655,34669,N,N,34658,N,N,N,34663,N,N,N,N,N,34664,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34686,34703,34702,34701,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,34674,34675,N,N,N,N,N,N,N,N,N,N,N,N,34671,34672,34673, -N,N,34677,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -34676,N,N,N,N,N,N,N,N,34691,60748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,60749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60750, -60751,N,N,60752,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60753,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,60754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60756,N,N,N,N,N,N,N, -60755,N,60758,N,N,N,N,N,60757,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60741,N,N,N,60759,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,60762,60763,N,N,N,60761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,60760,N,60766,N,N,N,60764,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60765,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60767,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,60769,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,60768,60770,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60771,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,60772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,60773,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60774,60775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,60776,N,N,N,N,N,N,N,N,N,60777,N,N,N,N,N,N,N,N,61019,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,60778,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60779, -60780,N,N,N,N,N,N,60781,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,60782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,60783,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -60784,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60785,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -60786,60789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60788,N,N,N,N,N,N,N,N,N,N,N,N, -60790,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,60791,60792,60793,N,N,N,N,N,N,N,N,N,N,N,60794,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60795,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60797,60796,60801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,60802,60803,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,60804,N,N,N,N,N,N,N,60805,N,60806,N,N,N,N,N,60807,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,60808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -60809,60810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60811,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,60814,60815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60816,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,60817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60818,60819,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60822,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,60820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60823,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60824,60825,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60826,60827,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,60828,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60747,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60829,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60830,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60831,60832,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60833,N,N, -N,N,60834,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,60836,N,N,N,N,N,N,N,N,60835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60838, -60839,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60837,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60841,N, -N,N,N,N,N,60840,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60842,60843,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60844,60845,60846,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,60847,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60848,60849,60850,N,N,N,N,N, -N,N,N,60853,N,N,N,N,N,N,N,N,N,N,N,60851,N,N,N,N,N,N,N,N,60855,N,N,N,N,N,60856, -N,N,N,N,N,N,N,N,N,60854,N,N,60743,N,N,N,N,N,N,N,N,N,60852,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60858,N,60859,N,N,N,N,N,N,N,N,N,N,N,60857,N, -N,N,N,N,N,N,N,N,N,N,N,N,60861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,60862,N,N,N,N,N,N,60863,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,60864,N,N,N,N,N,N,N,N,N,N,N,N,60865,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,60866,60746,60867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60870,N,N,N,N,60872, -60873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60874,N,N,N,N,N,N, -N,N,N,N,N,N,N,60871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,60744,N,N,N,N,N,N,60875,60877,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60879,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60880,60881,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60883,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60882,N,N,N,N,N,N,N,60884,N,N,N,N,N,N,N, -N,N,N,60885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60886,N,60887,60888, -60889,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60890,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,60892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -60891,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,60893,60894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,60896,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60895,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,60897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60898,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60899,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60901,N,N,N,N,N,60900,N, -N,N,60902,60905,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60903,N,N,60906,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60904,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,60907,60908,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60909,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,60910,60911,N,60912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,60913,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60914,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60915,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,60742,60917,N,N,N,N,N,N,N,N,N,N,60916,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,60919,60920,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60918,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60922,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -60923,60924,N,N,N,N,N,N,N,N,N,N,N,N,60992,60993,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60995,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60996,N,N,N,N,N,N,N,N,N,N,N,60997, -N,N,N,N,N,N,N,N,61000,N,N,N,60998,N,N,N,N,N,N,N,N,N,N,N,N,60999,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,61002,61001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,61003,N,N,61005,61004,N,N,N,61006,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61007, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -61008,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61009,61010,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60812, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61011,61012,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61015,61013,N,61014,N,N,N,N,N,N,N,61016,61018, -61020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,61021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61022,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61023,61024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,61028,N,N,N,N,N,N,61030,61031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,61032,N,N,N,61034,61035,61037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61038, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61040,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,61039,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,61041,61042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60736,61043,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,61044,61046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61047,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61048,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61050,61051,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61052,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60740,61053,N,N,N,N, -N,61054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61056,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,61058,61061,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61062,60737,61063,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61064,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61066,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,61067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,61068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61070, -61071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,61072,61073,N,N,N,61074,61075,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,61076,61078,61081,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,61082,61084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -61085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61087,N,N,61086,N,N,N,61088,N,N,N, -N,N,61091,61092,N,N,N,N,N,N,N,61089,61090,61093,N,N,N,61095,N,N,N,N,N,61094,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -61102,61096,N,61098,N,N,N,61097,N,N,N,N,N,N,N,N,N,N,N,N,N,61099,N,N,61101,N,N, -N,N,N,N,N,61100,N,N,N,N,N,N,N,N,N,N,N,N,N,61103,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -61105,61106,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60739,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61104,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61110,N,N,61114,N,61112,N,61108,N,61109, -N,N,N,N,N,N,61113,N,N,N,N,N,N,61107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60745,N, -61117,N,N,N,61120,61122,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -61121,61119,N,N,61116,N,N,N,61115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,60738,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61124,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61125,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61126,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,61128,61129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61130,N,N,61131, -61132,61135,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61136,61137,N,N,N,N,N,N,N,61138, -N,N,N,N,N,N,N,61139,N,N,N,N,N,N,N,N,N,61140,N,61141,N,61142,N,N,N,61143,61144, -N,N,N,N,N,N,N,N,N,N,N,N,N,61145,61148,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61150,61151,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,61152,N,N,61153,61155,N,N,61154,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,61156,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,61157,N,N,N,N,N,N,N,N,N,61158,61159,61161,N,N,N,N,61160,61163,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61164,60868,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61133,60787,60798,60800,60821,60860,60876,60878, -60921,60994,61017,61025,61026,61027,61029,61033,61036,61045,61057,61059,61060, -61069,61077,61079,61080,61083,61111,61118,61134,61146,61147,61149,61162,61180, -N,N,N,N,61179,N,N,N,N,N,33148,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33119,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33169, -33170,33226,N,61178, -}; - -static const struct unim_index cp932ext_encmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_encmap+0,22,121},{__cp932ext_encmap -+100,17,191},{0,0,0},{__cp932ext_encmap+275,96,115},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__cp932ext_encmap+295,29,31},{0,0,0},{__cp932ext_encmap+298,49,168},{ -__cp932ext_encmap+418,3,205},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{__cp932ext_encmap+621,40,252},{__cp932ext_encmap+834,0,255},{ -__cp932ext_encmap+1090,30,244},{__cp932ext_encmap+1305,74,236},{ -__cp932ext_encmap+1468,21,219},{__cp932ext_encmap+1667,0,221},{ -__cp932ext_encmap+1889,138,255},{__cp932ext_encmap+2007,134,134},{0,0,0},{ -__cp932ext_encmap+2008,89,200},{__cp932ext_encmap+2120,158,178},{ -__cp932ext_encmap+2141,11,186},{0,0,0},{__cp932ext_encmap+2317,86,236},{ -__cp932ext_encmap+2468,30,245},{__cp932ext_encmap+2684,39,208},{0,0,0},{ -__cp932ext_encmap+2854,33,222},{__cp932ext_encmap+3044,93,242},{ -__cp932ext_encmap+3194,17,152},{__cp932ext_encmap+3330,19,166},{ -__cp932ext_encmap+3478,245,245},{__cp932ext_encmap+3479,96,206},{ -__cp932ext_encmap+3590,78,78},{__cp932ext_encmap+3591,0,251},{ -__cp932ext_encmap+3843,14,192},{__cp932ext_encmap+4022,1,207},{ -__cp932ext_encmap+4229,104,226},{__cp932ext_encmap+4352,48,228},{ -__cp932ext_encmap+4533,214,214},{__cp932ext_encmap+4534,63,218},{ -__cp932ext_encmap+4690,4,252},{__cp932ext_encmap+4939,39,191},{ -__cp932ext_encmap+5092,136,245},{__cp932ext_encmap+5202,5,187},{ -__cp932ext_encmap+5385,4,254},{__cp932ext_encmap+5636,177,190},{ -__cp932ext_encmap+5650,36,245},{__cp932ext_encmap+5860,7,159},{ -__cp932ext_encmap+6013,1,111},{__cp932ext_encmap+6124,130,166},{ -__cp932ext_encmap+6161,70,70},{__cp932ext_encmap+6162,33,122},{ -__cp932ext_encmap+6252,48,155},{__cp932ext_encmap+6360,209,235},{ -__cp932ext_encmap+6387,158,158},{0,0,0},{__cp932ext_encmap+6388,72,214},{ -__cp932ext_encmap+6531,82,138},{__cp932ext_encmap+6588,71,161},{0,0,0},{0,0,0 -},{0,0,0},{__cp932ext_encmap+6679,1,246},{__cp932ext_encmap+6925,72,220},{ -__cp932ext_encmap+7074,83,176},{0,0,0},{0,0,0},{__cp932ext_encmap+7168,7,245}, -{__cp932ext_encmap+7407,28,28},{__cp932ext_encmap+7408,18,246},{ -__cp932ext_encmap+7637,83,127},{__cp932ext_encmap+7682,240,244},{ -__cp932ext_encmap+7687,18,118},{__cp932ext_encmap+7788,207,207},{0,0,0},{ -__cp932ext_encmap+7789,103,222},{__cp932ext_encmap+7909,21,238},{ -__cp932ext_encmap+8127,6,255},{__cp932ext_encmap+8377,2,248},{ -__cp932ext_encmap+8624,49,72},{__cp932ext_encmap+8648,146,146},{ -__cp932ext_encmap+8649,157,175},{__cp932ext_encmap+8668,51,85},{ -__cp932ext_encmap+8703,87,101},{__cp932ext_encmap+8718,39,158},{ -__cp932ext_encmap+8838,78,220},{__cp932ext_encmap+8981,114,187},{ -__cp932ext_encmap+9055,0,0},{__cp932ext_encmap+9056,107,112},{ -__cp932ext_encmap+9062,25,209},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_encmap+9247 -,41,220},{__cp932ext_encmap+9427,14,45},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__cp932ext_encmap+9459,2,228}, -}; - -static const ucs2_t __jisx0213_1_bmp_decmap[2197] = { -65287,65282,65293,126,12339,12340,12341,12347,12348,12543,12447,U,U,U,U,U,U,U, -U,8836,8837,8842,8843,8713,8709,8965,8966,U,U,U,U,U,U,U,8853,8854,8855,8741, -8742,10629,10630,12312,12313,12310,12311,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8802, -8771,8773,8776,8822,8823,8596,U,U,U,U,U,U,U,U,9838,9835,9836,9833,9655,9654, -9665,9664,8599,8600,8598,8601,8644,8680,8678,8679,8681,10548,10549,U,U,U,U,U, -U,U,U,U,U,10687,9673,12349,65094,65093,9702,8226,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,8723,8501,8463,13259,8467,8487,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12448,8211,10746,10747,12363,U,12365,U,12367,U, -12369,U,12371,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12436,12437, -12438,12459,U,12461,U,12463,U,12465,U,12467,U,U,U,U,U,U,U,12475,U,U,U,U,U,U,U, -U,12484,U,U,U,12488,9828,9824,9826,9830,9825,9829,9831,9827,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,962,9461,9462,9463,9464,9465,9466,9467,9468, -9469,9470,9750,9751,12320,9742,9728,9729,9730,9731,9832,9649,12784,12785, -12786,12787,12788,12789,12790,12791,12792,12793,U,12794,12795,12796,12797, -12798,12799,9150,9151,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162, -9163,9164,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -12535,12536,12537,12538,8922,8923,8531,8532,8533,10003,8984,9251,9166,12881, -12882,12883,12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894, -12895,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988, -12989,12990,12991,U,U,U,U,U,U,U,U,9680,9681,9682,9683,8252,8263,8264,8265,461, -462,464,7742,7743,504,505,465,466,468,470,472,474,476,8364,160,161,164,166, -169,170,171,173,174,175,178,179,183,184,185,186,187,188,189,190,191,192,193, -194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212, -213,214,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232, -233,234,235,236,237,238,239,240,241,242,243,244,245,246,248,249,250,251,252, -253,254,255,256,298,362,274,332,257,299,363,275,333,260,728,321,317,346,352, -350,356,377,381,379,261,731,322,318,347,711,353,351,357,378,733,382,380,340, -258,313,262,268,280,282,270,323,327,336,344,366,368,354,341,259,314,263,269, -281,283,271,273,324,328,337,345,367,369,355,729,264,284,292,308,348,364,265, -285,293,309,349,365,625,651,638,643,658,620,622,633,648,598,627,637,642,656, -635,621,607,626,669,654,609,331,624,641,295,661,660,614,664,450,595,599,644, -608,403,339,338,616,649,600,629,601,604,606,592,623,650,612,652,596,593,594, -653,613,674,673,597,657,634,615,602,U,509,8048,8049,U,U,U,U,U,U,U,U,8050,8051, -865,712,716,720,721,774,8255,779,769,772,768,783,780,770,741,742,743,744,745, -U,U,805,812,825,796,799,800,776,829,809,815,734,804,816,828,820,797,798,792, -793,810,826,827,771,794,10102,10103,10104,10105,10106,10107,10108,10109,10110, -10111,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,8560,8561,8562,8563, -8564,8565,8566,8567,8568,8569,8570,8571,9424,9425,9426,9427,9428,9429,9430, -9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445, -9446,9447,9448,9449,13008,13009,13010,13011,13012,13013,13014,13015,13016, -13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13050,13033, -13029,13037,13036,U,U,U,U,U,U,U,U,U,8273,8258,9312,9313,9314,9315,9316,9317, -9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,8544, -8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,13129,13076,13090,13133, -13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115,13212, -13213,13214,13198,13199,13252,13217,8555,U,U,U,U,U,U,U,13179,12317,12319,8470, -13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181,13180, -U,U,U,8750,U,U,U,U,8735,8895,U,U,U,10070,9758,20465,U,13314,20008,20015,20016, -20109,20193,20221,20223,20227,20235,20320,20296,20297,20310,20319,20330,20332, -20350,20362,20372,20375,64048,20425,20448,20481,20482,20494,20504,20519,20526, -20544,20539,20545,20628,20684,20722,20688,20710,64049,20742,20739,20747,20766, -20789,20810,64050,20821,20823,13493,20893,20931,20938,20958,20962,20974,20993, -13531,21011,21013,21065,21079,21089,21139,21192,64051,21196,21200,21206,21211, -64052,21232,21243,21248,21255,21276,64053,21345,21347,21373,21395,21405,21426, -21522,21543,21581,21660,21611,21620,21631,21640,21654,21665,21673,21702,21759, -21774,21803,21813,21840,21854,21889,21894,21902,64054,21933,21966,64055,22024, -22030,22075,22089,22134,22118,64056,22127,22129,22130,22169,22174,22185,22188, -22195,22217,22218,22282,U,22305,22319,22323,22324,22384,22391,22396,22428, -64015,U,22456,22471,22472,22479,22500,22509,22517,22518,22527,22537,64016, -22625,22628,64057,22652,22665,22686,64058,22697,U,22738,22734,22740,22746, -22752,22761,22796,34369,22877,22893,22923,22930,22948,22979,22994,23005,23059, -23075,23143,23149,23159,23166,23172,23198,23207,23236,U,23321,23333,21085, -23361,23382,23421,23443,23512,23532,23570,23582,23587,23595,14221,23650,64059, -64060,U,23674,23695,23711,23715,23722,23738,23755,23760,23762,23796,U,14306, -23821,23847,64017,23878,23879,23891,23882,23917,23937,23968,23972,23975,23992, -24011,21534,22099,24034,24084,24088,24152,24158,24254,63784,24267,24313,24320, -24322,24327,24349,24355,24372,24374,24381,24384,24389,24404,24408,24420,24423, -24445,24457,24476,24487,24495,24501,24503,24521,24542,24545,24553,24589,24596, -24600,24627,24629,24647,64061,24733,24734,24779,24788,24789,24797,24824,24860, -24875,24880,24887,64062,24973,64063,25020,25017,64064,25122,25150,25155,25174, -25178,25199,25221,25284,25302,25340,25354,25368,25401,25411,25445,25468,25573, -25581,25589,25616,25620,25634,25721,25681,25696,25709,25806,25790,25791,25796, -25802,25808,25847,25851,25890,25897,64065,25959,26013,64066,26112,26121,26133, -26142,26170,26146,26148,26155,26160,26161,26163,26363,26184,26188,U,26201, -26202,26209,26213,26227,26231,26232,26253,64067,26272,26290,26299,26310,26312, -15138,26331,26344,26362,26387,63785,26419,26470,26439,26440,26491,26497,26515, -26520,26523,26555,26617,26560,26583,26620,26625,26706,26653,26668,26673,26715, -26738,26741,64068,26787,26789,26802,26824,26832,26856,26861,26864,26865,26876, -26890,26953,U,26933,26946,26967,26979,26980,26984,27008,64020,27045,27053, -27087,15286,15299,27106,27113,27114,27125,27126,27151,27157,U,27195,27198, -27205,27216,27222,27227,27243,27251,U,27273,27284,27293,27294,27301,27364, -27367,15375,63773,27419,27422,27436,27445,27462,27478,27488,27493,27495,27511, -27522,27561,27565,63856,27599,27606,27607,27647,27653,27664,27699,27737,27740, -27818,27764,27766,27781,27782,27800,27804,27899,27846,27860,27872,27883,27886, -U,27908,27918,27950,27953,27961,27967,27992,28005,64069,28034,28039,28041, -28052,28074,28076,28095,28100,28118,28122,28123,28125,28156,64070,28212,28228, -28252,28254,28331,28337,28353,28359,28366,28432,28442,64071,28458,28463,28467, -28497,28505,28510,28513,28514,28542,28552,28556,28557,28564,28576,28583,28598, -28604,28615,28618,28665,28656,28661,28677,28678,28712,28746,28765,28766,28750, -28772,28789,28805,28836,28843,28855,28884,28888,28900,28943,28971,28958,28960, -28974,28976,28998,28999,29009,64072,29010,29020,29024,29032,64021,29061,29063, -29074,29121,29114,29124,29182,29184,29205,29269,29270,15935,29325,29339,29374, -29376,29435,U,29479,29480,64022,29520,29542,29564,29589,29599,29600,29602, -29606,29611,29641,29647,29654,29657,29667,29673,29703,29706,29722,29723,64074, -29734,29736,29738,29739,29740,29742,29743,29744,29764,29766,29767,29771,29783, -29794,29803,29805,29830,29831,29833,29848,29852,29855,29859,29840,29862,29864, -29865,29877,29887,29896,29897,29914,29951,29953,29975,29999,30063,30073,30098, -16242,30158,30180,30208,30210,30216,30229,30230,30233,30238,30253,30261,30275, -30283,30308,30309,30317,30319,30321,30337,30363,30365,30366,30374,30378,30390, -30405,30412,30414,30420,30438,30449,30460,30474,30489,30516,30518,30534,30541, -30542,30556,30559,30562,30586,30592,30612,30634,30688,30765,30787,30798,30799, -30801,30824,30830,64075,30896,U,30893,30948,30962,30976,30967,31004,31022, -31025,31028,64076,64077,31045,31046,64078,64079,64080,31068,64081,64025,64026, -31097,64082,64083,64027,31128,31153,31160,31176,31178,U,31188,31198,31211, -31213,31235,64084,31289,31325,31341,64085,31365,31392,U,31411,31419,31438, -31467,31485,31506,31533,31547,31559,31566,31584,31597,31599,31602,31646,64086, -31703,31705,31745,31793,31774,31776,31795,31798,16996,U,31833,31853,31865, -31887,31892,31904,31932,31957,31961,31965,32007,32008,32019,32029,32035,32049, -32065,32072,32083,32092,32122,32131,32139,32160,32166,32194,32204,32214,32227, -64087,32296,32264,32273,32277,64089,32327,32338,32353,32394,32397,32583,64090, -32657,32663,32703,32718,32731,32735,32748,32750,32762,64091,32788,32806,32821, -32823,32828,32970,32983,32992,33011,33048,33098,33120,33127,33128,33133,33211, -33226,33231,33239,64092,17491,17499,33376,33396,U,33422,33441,33443,33444, -33449,33454,33463,33470,33471,33478,33493,33533,33534,33536,33537,33634,33570, -33581,33594,33603,33607,33617,33621,33661,33670,33682,33688,33703,33705,33727, -33728,33735,33743,33745,33761,33770,33793,33798,33802,64095,33864,33887,33904, -33907,33925,33950,33967,33972,33978,33984,33986,U,34098,34078,34083,34095, -34137,34148,64031,34221,34170,34188,34191,34210,34224,34251,34254,34285,34322, -34303,34308,34309,34320,U,34328,34345,34360,34391,34395,63798,34402,17821, -34412,34421,34456,34488,34554,34556,34557,34571,34673,34695,34696,34732,34733, -34741,17898,34774,34796,34822,34826,34832,34836,34847,34968,34986,35018,35022, -U,35061,35100,64096,35096,35097,35098,35111,35120,35122,35129,35136,35220, -64097,35284,35301,35318,35346,35349,35362,35383,35399,35406,35421,35425,35445, -35449,35495,35536,35551,35572,35574,64034,64098,64099,35654,35668,35673,35689, -35741,35913,35944,64100,36065,36084,36088,36094,64101,36114,36123,36271,36302, -36305,36311,36384,36387,36413,36464,36475,U,36544,18500,36602,36638,36653, -36662,36692,U,36774,36789,36836,36840,36846,36872,36909,64103,37000,37013, -37015,37017,37019,37026,37043,37054,37060,37061,37063,37079,37085,37086,37103, -37108,64038,37140,37141,37142,37154,37155,37159,37167,37169,37172,37181,37192, -37211,37251,37278,37292,37297,37308,37335,37371,37348,37349,37357,37361,37383, -37392,37432,37433,37434,37436,37440,37443,37455,37496,37512,37570,37579,37580, -37587,37600,37631,37636,37663,37665,37669,37704,37705,37706,37732,37733,37738, -37744,37787,37795,37818,37830,37854,37855,37892,37885,37939,37962,37987,37995, -38001,38002,38286,38303,38310,38313,38316,38326,38333,38347,38352,38355,18864, -38362,38366,38488,38532,63964,38557,38564,38565,38610,38622,64104,38633,38639, -38707,38715,38733,38734,38735,38746,38766,38771,38805,38830,38842,38849,38857, -38878,38875,38900,64105,38922,38942,38955,38960,64106,38994,38995,38998,38999, -39001,39002,63952,39013,39020,39098,39112,39143,39256,39326,39426,39427,39460, -39469,39470,39480,39498,39502,39506,39606,39617,39619,39630,39638,39673,39682, -39688,39712,19479,39725,39774,39801,39782,39794,39797,39812,39818,39823,39838, -39847,39873,39886,39909,39928,39933,39936,39971,40001,40015,40016,40019,40035, -40037,40055,40221,40222,40259,40263,40274,40291,40304,40316,40330,40342,40384, -40364,40380,40407,U,40423,40455,40469,40572,40606,40612,40620,40623,40628, -40629,40643,40657,40720,40761,40791,40848,40852,40855,40866,23032,23643,24183, -30246,32363, -}; - -static const struct dbcs_index jisx0213_1_bmp_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_bmp_decmap+0,47,125},{ -__jisx0213_1_bmp_decmap+79,33,126},{__jisx0213_1_bmp_decmap+173,43,118},{ -__jisx0213_1_bmp_decmap+249,43,72},{__jisx0213_1_bmp_decmap+279,57,126},{ -__jisx0213_1_bmp_decmap+349,66,126},{__jisx0213_1_bmp_decmap+410,65,124},{ -__jisx0213_1_bmp_decmap+470,33,126},{__jisx0213_1_bmp_decmap+564,33,126},{ -__jisx0213_1_bmp_decmap+658,33,126},{__jisx0213_1_bmp_decmap+752,33,126},{ -__jisx0213_1_bmp_decmap+846,33,126},{__jisx0213_1_bmp_decmap+940,33,126},{ -__jisx0213_1_bmp_decmap+1034,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_bmp_decmap+ -1128,85,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__jisx0213_1_bmp_decmap+1170,39,126},{__jisx0213_1_bmp_decmap+1258,33,126},{ -__jisx0213_1_bmp_decmap+1352,33,126},{__jisx0213_1_bmp_decmap+1446,33,126},{ -__jisx0213_1_bmp_decmap+1540,33,125},{__jisx0213_1_bmp_decmap+1633,33,126},{ -__jisx0213_1_bmp_decmap+1727,33,126},{__jisx0213_1_bmp_decmap+1821,33,126},{ -__jisx0213_1_bmp_decmap+1915,33,126},{__jisx0213_1_bmp_decmap+2009,33,126},{ -__jisx0213_1_bmp_decmap+2103,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const ucs2_t __jisx0213_2_bmp_decmap[2425] = { -19970,19983,19986,20009,20011,20014,20032,20039,20040,U,20049,13318,U,20058, -20073,20125,13356,13358,20153,20155,U,20156,20163,20168,20176,20203,20186, -20209,20213,20224,20246,20324,20279,20286,20308,20312,U,20343,20344,20346, -20349,20354,20357,20370,20378,20454,20402,20414,20421,20427,20431,20434,13418, -20466,20480,20496,20499,20508,20510,20514,13416,20546,20550,20558,20563,20567, -20579,20582,20586,20592,20643,20616,20626,20627,20629,20630,20636,20650,U, -20657,20666,20667,20676,20679,20723,U,20686,U,20692,20697,20705,20713,13458, -20744,U,20759,20763,U,20832,U,20851,20867,20875,13500,20888,20899,20909,13511, -20924,U,U,20979,20980,20994,21010,21014,U,21077,21084,21100,21111,21124,21122, -U,21144,U,21156,21158,21167,21178,21179,21194,13599,21201,U,21239,21258,21259, -21284,21301,21310,21314,U,U,21351,21356,21370,21412,21428,U,21431,21440,U, -13661,13662,21461,21466,13667,21492,21493,21589,21540,21544,13678,21571,21602, -21606,21612,21642,21645,21653,21664,21670,21677,21678,21687,21690,21695,21699, -U,21740,21743,21745,21747,21760,21761,21769,21820,21825,13734,21831,21834, -13736,21856,21857,21860,U,21885,21890,21896,21905,13765,21970,U,U,21951,21961, -21964,21969,21981,13786,21986,U,21993,22056,U,22023,22032,22064,22071,13812, -22077,22079,22080,22087,22110,22112,22125,13829,22152,22156,22165,22170,22173, -22184,22189,22194,22213,22221,22239,22248,22262,22263,U,22293,22307,U,22313,U, -22341,22342,22348,22349,U,22376,22383,22387,22388,22389,22395,U,U,22444,22426, -22429,22430,22440,22487,U,22476,U,U,22494,22502,22512,13898,22520,22523,22525, -22532,22558,22560,22567,22578,22585,U,22601,22604,22631,22666,22667,22669, -22671,22672,22676,22685,22698,22705,U,22723,22733,22754,22771,22772,22789, -22790,22795,22797,22804,22820,U,13969,22845,13977,22854,13974,U,22875,22879,U, -22901,22902,22908,22943,22958,22972,22984,22989,23006,23011,23012,23015,23022, -U,U,14031,23052,23053,23063,23079,23085,23125,23141,23162,23179,23196,23199, -23200,23202,23217,23219,23221,23226,23231,23258,23260,23264,23269,23280,23278, -23285,23296,23304,23319,23348,23341,23372,23378,23400,23407,23420,23423,23425, -23428,23446,23468,14177,23488,14178,23502,23510,14188,14187,23537,23549,14197, -23555,23593,23600,U,23647,23651,23655,23656,23657,23664,U,U,23676,U,U,23688, -23690,14273,U,U,23712,23714,23718,23719,U,23725,23733,U,23753,U,U,23814,23824, -23851,23837,23840,23844,23846,23857,23865,23874,14312,23905,23914,14324,23920, -U,14333,23944,14336,23954,23956,23959,23961,23984,23986,23988,U,23993,24017, -24023,24024,24032,U,24036,24041,14383,24064,14390,24082,24085,14400,24095, -24110,24126,24137,14428,24150,14433,24171,24172,24173,24174,U,24229,24234, -24236,24249,24255,24262,24274,24281,U,24317,24328,24334,24348,U,24350,24391, -24419,24434,24446,24463,24482,24484,24504,24516,14586,24519,24523,24530,24531, -24532,24546,24558,24559,24563,24572,14615,24599,24610,24612,14618,24652,24703, -24714,24725,24744,U,24752,24753,24766,24776,24793,24795,24814,24818,24821, -24848,24850,24851,24857,24862,24890,14703,24897,24902,24928,24956,U,24978, -24979,24983,24984,24997,25000,25005,U,25045,25053,25055,25077,U,25109,25123, -25129,25158,25164,25169,25170,25185,25188,25211,25197,25203,25241,25254,25301, -U,25341,25347,25357,25360,U,U,25394,25397,25403,25404,25409,25412,25422,U, -25433,U,U,25452,25476,25497,U,25492,25533,25591,25556,25557,25564,25568,25579, -25580,25586,25609,25630,25637,25641,25647,25690,25691,25693,25715,25725,25735, -25745,25757,25759,25803,25804,25813,25815,U,25828,25829,25855,25860,14958, -25871,25876,25878,14963,25886,25906,25924,25940,25963,25978,25985,25988,25989, -25994,26034,26037,26040,26047,26050,26057,26068,15062,26098,26105,26108,26116, -26120,26145,26154,26181,26193,26190,15082,U,26199,26203,26211,U,U,26218,26219, -26220,26221,26235,26240,26256,26258,26265,15118,26285,26289,26293,15130,26303, -15132,26348,15063,26369,26373,26386,U,26393,U,U,26444,26445,26452,26461,U,U,U, -26484,26486,U,26514,U,33635,26640,26544,26546,26563,26568,26578,26585,26587, -26608,26615,U,U,U,26648,26655,26669,U,26675,26683,26686,26692,26693,26697, -26700,26709,26711,15223,26731,26734,26746,26748,26754,26768,26774,15213,26776, -26777,26778,26780,26794,26795,26804,26811,26875,U,U,64019,26819,26821,26828, -26831,26838,26841,26852,26853,26860,26871,26883,26887,15239,15240,U,26939, -15245,26950,26985,26988,26994,27002,27007,27026,15268,27030,27032,27046,27056, -27063,27066,27068,27072,27089,27094,U,U,27184,U,U,27107,27118,27119,27123, -15309,27124,27134,27153,27162,27165,U,27186,27187,27188,27199,27206,27209, -27258,27214,27218,27236,U,27262,27267,27275,15344,27281,27295,27297,U,27307, -27325,27334,27348,27344,27356,27357,U,U,27372,27377,27378,27379,27389,U,27403, -27407,27408,27409,U,27415,15398,27439,27466,27480,27500,27509,27514,27521, -27547,27566,U,27581,27582,27591,27592,27593,27610,27622,27623,27630,27633, -27650,27658,27662,27701,27702,27706,U,27711,27725,27739,27757,27780,27785, -15555,27796,27797,27799,27821,27842,27856,15570,27862,27866,27868,27881,27884, -27885,U,27904,27914,27940,27942,27943,27751,27951,27964,27995,27998,28000, -28016,28032,28033,28042,28045,28049,28056,U,28183,U,U,U,28075,28078,28084, -28098,27956,28104,28110,28111,28112,28127,28137,28150,28214,28190,28194,28199, -15633,28210,28220,28232,28233,28235,28236,28239,28241,28243,28244,28247,28259, -15646,28307,28327,28340,28351,28355,28362,28377,28469,28395,28409,28411,28426, -28428,28440,28453,28470,28476,U,28498,28503,28506,28512,28520,28568,28541, -28560,28566,28606,28575,28581,28591,15716,28597,28616,28617,28634,28638,28649, -U,28668,28672,28679,28682,28707,U,28729,28730,28732,28739,28743,28747,15770, -28756,28773,28777,28780,28782,28790,28798,28801,28806,28821,28823,28859,U, -28831,28849,U,28908,28874,28881,28883,28892,28931,28932,28934,28935,28936, -28940,15808,28975,28977,29008,29002,29011,29022,15828,29078,29056,29083,29088, -29090,29102,29103,29107,U,29131,29139,29145,29148,29191,15877,64073,29227, -29236,29240,29241,20012,29250,29267,29271,29283,U,29294,29295,29304,29311, -29326,U,29357,29358,29360,29361,29377,15968,29388,15974,15976,29427,29434, -29447,29458,29464,29465,16003,29497,29484,29489,29491,29501,29522,16020,29547, -29548,U,29550,29551,29553,29559,29569,29573,29578,29588,29592,29596,29598, -29605,29608,29621,29623,29625,29628,29631,29637,29643,29665,29671,29689,29715, -29690,29697,29732,29745,29753,29779,29760,29763,29773,29778,29789,29809,29825, -29829,29832,U,29842,29847,29849,29856,29857,29861,29866,29867,29881,29883, -29882,29910,29912,29918,29935,29931,U,29946,U,29984,29988,29994,16215,U,30013, -30014,30016,30024,30030,30032,30034,30060,30066,30065,30074,30077,30078,30081, -U,30092,16245,30114,16247,30128,30135,30143,30144,30150,30159,30163,30173, -30175,30176,30183,30188,30190,30193,30201,30211,30232,30215,30223,16302,U, -30227,30235,30236,U,30245,30248,30268,30259,U,16329,30273,U,30281,30293,16343, -30318,30357,30364,30369,30368,30375,30376,30383,U,30409,U,30440,30444,U,30487, -30490,30509,30517,16441,U,U,30552,30560,30570,U,30578,30588,30589,U,16472, -30618,30623,30626,30628,30633,30686,30687,30692,30694,30698,30700,16531,30704, -30708,30715,U,30725,30726,30729,30733,30745,30753,30764,30791,30820,30826,U, -30858,30868,30884,30877,30878,30879,30907,30920,30924,30926,30933,30944,30945, -30950,30969,30970,30971,30974,U,30992,31003,31024,31013,31035,31050,31064, -31067,16645,31079,31090,31124,31125,31126,31131,31137,31145,31156,31163,31170, -31175,31180,31181,31190,16712,U,U,16719,31242,31249,31253,31259,31262,16739, -31277,31288,31303,31308,31318,31321,31324,31327,31328,31335,31338,31349,31352, -31362,31370,31376,31395,31404,U,16820,31417,31420,31422,16831,31436,31441, -31463,31464,31476,U,U,31495,U,31549,31527,31530,31534,31535,31537,16870,16883, -31615,31553,16878,31573,31609,31588,31590,31593,31603,U,16903,31632,31633, -31643,16910,31663,31669,31676,31685,31690,U,U,31700,31702,31706,31722,31728, -31747,31755,31758,31759,31782,31813,31818,31825,31831,31838,31841,31849,31854, -31855,31856,U,U,U,31910,U,31926,31927,31935,U,31940,U,31944,31949,U,31959,U, -31974,31979,U,31989,32003,32009,17094,32018,32030,U,U,32061,32062,32064,32071, -U,U,17110,32089,32090,32106,32112,17117,32127,U,32134,32136,32140,32151,U, -32157,32167,32170,32182,32183,32192,32215,32217,32230,32241,32249,17154,U, -64088,32272,32279,32285,32288,32295,32300,32325,32371,32373,32382,32390,32391, -17195,32401,32408,32410,17219,32572,32571,32574,32579,32580,32591,13505,U, -32594,U,32609,32611,32612,32621,32637,32638,U,32656,20859,U,32662,32668,32685, -U,32707,32719,32739,32741,32751,32754,32770,32778,32776,32782,32785,32790, -32804,32812,32816,32835,32870,32881,32885,32891,32921,32924,32932,32935,32952, -U,32965,32981,32984,32998,U,33037,33013,33019,17390,33077,33046,33054,17392, -33060,33063,33068,U,33085,17416,33129,17431,33153,17436,33156,33157,17442, -33176,33202,33217,33219,33238,33243,U,33252,U,33260,U,33277,33279,U,33284,U, -33305,33313,33314,U,33330,33332,33340,33350,33353,33349,U,33355,17526,33359, -17530,33367,U,33372,33379,U,64093,64094,33401,17553,33405,33407,33411,33418, -33427,33447,33448,33458,33460,33466,33468,33506,33512,33527,33543,33544,33548, -33620,33563,33565,33584,33596,33604,33623,17598,33663,17620,17587,33677,33684, -33685,33691,33693,33737,33744,33748,33757,33765,33785,33807,33809,33813,U, -33815,33849,33866,33871,33873,33874,33881,33882,33884,U,33893,33910,33912, -33916,33921,17677,34012,33943,33958,33982,17672,33998,33999,34003,U,34023, -34026,34031,34032,34033,34042,34045,34060,34075,34084,34085,34091,34100,34127, -34159,17701,17731,34110,34129,34131,34142,34145,34146,U,34171,34173,34175, -34177,34182,34195,34205,34207,34231,34236,34247,34250,34264,34265,34271,34273, -34278,34294,34304,34321,34334,34337,34340,34343,U,34361,34364,U,34368,64032, -34387,34390,34415,34423,34426,34439,34441,34445,34449,34460,34461,34472,64033, -34481,34483,34497,34499,34513,34517,34519,34531,34534,17848,34565,34567,34574, -34576,34579,34585,34591,34593,34595,34609,34618,34622,34624,34627,34641,34648, -34660,34661,34674,34684,U,U,34727,34697,34699,34707,34720,U,17893,34750,U, -34753,34766,34805,34783,U,34787,34789,34790,34794,34795,34797,34817,34819, -34827,34835,34856,34862,34866,34876,17935,34890,34904,34911,34916,U,U,34921,U, -34927,34976,35004,35005,35006,35008,35026,U,35025,35027,35035,35056,35057, -17985,35073,U,35127,U,35138,35141,35145,U,18021,35170,35200,35209,35216,35231, -35248,35255,35286,35288,35307,18081,35313,35315,35325,35327,18095,35345,35348, -U,35361,35381,35390,35397,35405,35416,35502,35472,35511,35518,35543,35580,U, -35594,35589,35597,35612,35615,35629,35651,18188,35665,35678,35702,35711,35713, -35723,35732,35733,35740,35742,35897,U,35901,U,U,35909,35911,35919,35924,35927, -35945,35949,35955,U,35987,35986,35993,18276,35995,36004,36054,36053,36057,U, -36080,36081,U,36105,36110,36204,36228,36245,36262,U,36294,36296,36313,36332, -36364,18429,36349,36358,U,36372,36374,36385,36386,36391,U,18454,36406,36409, -36427,36436,36450,36460,36461,36463,36504,36510,36526,36531,36533,36534,36539, -U,36561,36564,18510,36601,U,36608,36616,36631,36651,36672,36682,36696,U,36772, -36788,64102,36790,U,36801,36806,64036,36810,36813,36819,36821,36832,36849, -36853,36859,36866,36876,36919,U,36931,36932,36957,36997,37004,37008,38429, -37025,18613,37040,37046,37059,37064,U,37084,37087,U,37110,37106,37120,37099, -37118,37119,37124,37126,37144,37148,37150,37175,37177,37178,37190,37191,37207, -37209,37217,37220,37236,37241,37253,37262,37288,37294,37299,37302,37315,37316, -37338,U,U,37356,37358,37377,37386,37398,37399,U,37427,37442,37447,37450,37454, -37457,37462,37465,37472,37473,37477,37479,37480,U,U,37500,37501,37503,37513, -37517,37527,37529,37535,37543,37547,U,U,37554,37567,37568,37574,37582,37584, -37591,37593,37605,37607,37649,37623,37625,37627,37634,37645,37653,37661,37662, -37671,37673,U,U,37703,37713,37719,37722,37739,37745,37747,37793,U,U,37768, -37771,37775,37790,37877,U,U,37873,37825,37831,37852,37858,37863,37897,37903, -37910,37911,37883,37938,37940,37947,37957,U,U,37997,37999,38264,38265,38278, -38284,38285,U,38315,38324,U,38344,U,U,38444,38451,38452,U,38460,38465,38497,U, -38530,U,38554,U,18919,38569,38575,38579,38586,38589,18938,U,38616,38618,38621, -18948,38676,38691,18985,38710,38721,38727,38741,38743,38747,38762,U,U,38806, -38810,38814,38818,38833,38834,38846,38860,38865,38868,38872,38873,38881,38897, -38916,38925,38926,38932,38934,19132,U,38947,38962,38963,38949,38983,39014, -39083,39085,39088,U,39095,39096,39099,39100,39103,39106,39111,39115,39136,U, -39137,39139,39141,39146,39152,39153,39155,39176,19259,U,39190,39191,U,39194, -39195,39196,U,39217,39218,39219,39226,39227,39228,39232,39233,39238,39245, -39246,39260,39263,39264,39331,39334,39353,39357,39359,39363,39369,39380,39385, -39390,U,39408,39417,39420,39434,39441,39446,39450,39456,39473,39478,39492, -39500,39512,19394,39599,19402,39607,19410,39609,U,39622,39632,39634,39637, -19432,39644,39648,39653,39657,39683,39692,39696,39698,39702,39708,39723,39731, -39741,19488,39755,39779,39781,39787,39788,39795,39798,39799,39846,39852,39857, -U,U,39858,39864,39870,39879,39923,39896,39901,39911,39914,39915,39919,39918,U, -39930,U,39927,U,39958,39960,39961,39962,39965,39970,39975,39977,39978,U,39985, -39990,39991,40005,40028,U,40009,40010,U,40020,40024,40027,40029,40031,40041, -40042,40043,40045,40046,40048,40050,40053,40058,40166,40178,40203,40194,U, -40209,40215,40216,U,19652,U,40242,19665,40258,40266,40287,40290,U,40297,40299, -U,40307,40310,40311,40318,40324,40333,40345,40353,40383,40373,40377,40381, -40387,40391,40393,40406,40410,40415,40416,40419,40436,19719,40458,40450,40461, -40473,40476,40477,40571,U,40576,40581,40603,40616,U,40637,U,40671,40679,40686, -40703,40706,19831,40707,40727,40729,40751,40759,40762,40765,40769,40773,40774, -40787,40789,40792,U,40797,U,40809,U,40813,40816,40821, -}; - -static const struct dbcs_index jisx0213_2_bmp_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+0,34,126},{0,0,0},{ -__jisx0213_2_bmp_decmap+93,33,126},{__jisx0213_2_bmp_decmap+187,33,126},{ -__jisx0213_2_bmp_decmap+281,33,125},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+ -374,33,126},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+468,33,126},{ -__jisx0213_2_bmp_decmap+562,33,126},{__jisx0213_2_bmp_decmap+656,33,126},{ -__jisx0213_2_bmp_decmap+750,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__jisx0213_2_bmp_decmap+844,33,126},{__jisx0213_2_bmp_decmap+938,33,126},{ -__jisx0213_2_bmp_decmap+1032,33,126},{__jisx0213_2_bmp_decmap+1126,33,126},{ -__jisx0213_2_bmp_decmap+1220,34,126},{__jisx0213_2_bmp_decmap+1313,33,126},{ -__jisx0213_2_bmp_decmap+1407,33,126},{__jisx0213_2_bmp_decmap+1501,33,126},{ -__jisx0213_2_bmp_decmap+1595,33,125},{__jisx0213_2_bmp_decmap+1688,35,126},{ -__jisx0213_2_bmp_decmap+1780,33,126},{__jisx0213_2_bmp_decmap+1874,33,125},{ -__jisx0213_2_bmp_decmap+1967,34,125},{__jisx0213_2_bmp_decmap+2059,34,126},{ -__jisx0213_2_bmp_decmap+2152,33,126},{__jisx0213_2_bmp_decmap+2246,33,126},{ -__jisx0213_2_bmp_decmap+2340,33,117},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const DBCHAR __jisx0213_bmp_encmap[27287] = { -8754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10530, -10531,N,N,10532,N,10533,N,N,10534,10535,10536,N,10537,10538,10539,N,N,10540, -10541,N,N,N,10542,10543,10544,10545,10546,10547,10548,10549,10550,10551,10552, -10553,10554,10555,10556,10557,10558,10559,10560,10561,10562,10563,10564,10565, -10566,10567,10568,10569,10570,10571,10572,10573,N,10574,10575,10576,10577, -10578,10579,10580,10581,10582,10583,10584,10585,10586,10587,M,10589,10590, -10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602,10603, -10604,N,10605,10606,10607,10608,10609,10610,10611,10612,10613,10618,10810, -10825,10785,10796,10812,10827,10841,10847,N,N,10813,10828,10816,10831,N,10832, -10616,10621,N,N,N,N,10814,10829,10815,10830,10842,10848,N,N,N,N,N,N,10843, -10849,N,10877,N,N,10614,10619,N,N,N,N,N,N,N,N,10844,10850,N,N,N,10811,10826,N, -N,10788,10799,N,N,10787,10798,10817,10833,N,N,10818,10834,N,N,10874,10617, -10622,N,N,10819,10835,11051,11050,10809,10824,N,N,10820,10836,10789,10800, -10845,10851,10791,10803,10790,10802,10823,10839,10792,10804,N,N,N,N,10615, -10620,10846,10852,10821,10837,10822,10838,N,N,N,N,N,N,N,10793,10805,10795, -10808,10794,10807,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11049,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -11044,N,N,N,N,N,N,N,N,N,N,10351,10352,N,10353,10358,10359,N,10360,N,10361,N, -10362,N,10363,N,10364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -10356,10357,N,N,N,11077,11059,11065,11066,11045,M,11071,10862,11046,11054,M,M, -N,11057,N,11058,10869,11048,10873,N,N,11062,11068,11042,11074,11052,N,N,N, -10858,10868,10859,11060,10875,10853,10870,10863,N,11055,N,N,N,10860,11073, -10867,N,10864,10855,N,N,10876,10865,10856,11047,N,N,N,10861,11053,11061,10854, -M,11067,10872,N,10866,11072,10857,N,11041,10878,N,N,11043,N,N,N,N,10871,N,N,N, -11070,11069,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,10801,11091,N,N,N,11092,N,N,N,11093,11094,N,N,N,N,N,N,10786,10840,N, -10797,N,10806,11121,N,N,N,N,N,N,M,11105,11106,11107,M,11100,11098,11103,11133, -11099,N,11095,N,11117,N,N,11097,11102,N,N,11101,N,N,N,N,N,N,N,N,11128,11129, -11134,N,11114,11126,11127,11115,11116,N,N,N,11122,11111,N,N,N,11119,11130,N, -11112,N,N,11120,11123,N,N,N,11125,N,N,N,N,11113,11131,11132,11124,11118,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11090,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,9817,10354,10355,11078,11079,11088,11089,9084,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,9024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,10347,N,N,11096,N,N,11390,N,N,N,N,10348,10349,10350,N,N,N,N,N,N,N,11389,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,10529,9053,N,N,N,9055,N,N,11618,N,N,N,N,N,N,N,N,N,N,11620, -N,N,N,N,N,9056,N,N,N,N,N,N,N,N,N,N,N,N,N,9052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,10104,10105,10106,N,N,N,N,N,N,N,N,N,N,11573,11574, -11575,11576,11577,11578,11579,11580,11581,11582,11583,11607,N,N,N,N,11317, -11318,11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8817,N,8999,8997,8998,9000,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9001,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9003,9004, -9002,9005,8775,N,N,N,8774,N,N,N,N,N,N,N,N,N,9051,N,N,N,N,N,N,N,N,N,N,N,11640, -N,N,N,N,N,8788,8789,N,N,N,N,N,N,N,11635,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,8812,N,8813,N,N,8814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8811, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8815,8816,N,N,N,N,N,N,N,N,N,N,N,N,8770, -8771,N,N,N,N,8772,8773,N,N,N,N,N,N,N,N,N,8785,8786,8787,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11641,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10102,10103,8776,8777,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,10108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10050,10051,10052,10053,10054,10055, -10056,10057,10058,10059,10060,10061,10062,10063,10064,N,10110,10109,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11553,11554,11555,11556,11557,11558,11559, -11560,11561,11562,11563,11564,11565,11566,11567,11568,11569,11570,11571,11572, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,11329,11330,11331,11332,11333,11334,11335,11336, -11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349, -11350,11351,11352,11353,11354,N,11307,11308,11309,11310,11311,11312,11313, -11314,11315,11316,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9837,N,N, -N,N,8994,8993,N,N,N,N,N,N,N,N,8996,8995,N,N,N,N,N,N,N,9019,N,N,N,N,N,N,10343, -10344,10345,10346,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9023,9832,9833,9834, -9835,N,N,N,N,N,N,N,N,N,N,9831,N,N,N,N,N,N,N,9828,9829,N,N,N,N,N,N,11646,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9786,9789,9787,9792,9785,9790, -9788,9791,9836,8829,N,8827,8828,N,8826,10107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,11645,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,11297,11298,11299,11300,11301,11302,11303,11304,11305,11306,9006, -9007,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,8790,8791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9018,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,9085,9086,8794,8795,8792,8793,N,N,N,11616,N,11617,9830,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8755,8756,8757,N,N,N,N,N,8758,8759,9020,N,N,N, -N,N,N,N,N,N,N,N,N,N,M,N,M,N,M,N,M,N,M,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,9332,9333,9334,N,N,N,N,N,N,N,N,8761,9083,N,N,N,N,N,N,N,N,N,N,M,N,M, -N,M,N,M,N,M,N,N,N,N,N,N,N,M,N,N,N,N,N,N,N,N,M,N,N,N,M,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10098, -10099,10100,10101,N,N,N,N,8760,9838,9839,9840,9841,9842,9843,9844,M,9846,9847, -9849,9850,9851,9852,9853,9854,11626,11627,N,N,N,N,N,N,11628,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,10305,10306,10307,10308,10309,10310,10311,10312, -10313,10314,10315,10316,10317,10318,10319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,11621,11622,11623,11624,11625,N,N,N,N,N,N,N,N,10320, -10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333, -10334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11355,11356,11357,11358,11359,11360, -11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373, -11374,N,11377,N,N,N,11376,N,N,11379,11378,N,N,N,N,N,N,N,N,N,N,N,N,11375,11590, -N,N,N,N,N,N,N,N,N,11594,N,N,N,N,N,N,11585,N,N,N,11588,N,N,N,N,N,N,N,N,N,11586, -11596,N,N,11595,11589,N,N,N,11597,N,N,N,N,N,N,N,N,N,N,11591,N,N,N,N,11599,N,N, -N,N,N,N,N,N,N,N,N,N,N,11584,11598,N,N,11587,N,N,N,11592,N,N,N,N,N,11593,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11615,11631, -11630,11629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11603,11604,N,N,N,N,N,N,N,N,N,N,N,N, -11600,11601,11602,N,N,11606,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,11605,N,N,N,N,N,N,9054,N,11619,11811,N,N,N,41261,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41266,N,41267, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41310,N,41302,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41342,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11859,N,N,N,N,N,N,41771,N,N,N,N, -62568,N,N,N,N,N,41775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11867,41800,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41821,41822,N,N,N,N,41825,N,N,N,N,N,N,N, -N,N,N,41831,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42019,N,42022,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,42040,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42050,42058,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42105,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42303,N,N,N,N,42307,N,N,42305,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,42327,43043,43045,N,N,N,N,N,N,N,N,43049,43048,N,N,N,N,N, -N,N,N,43052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20319,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,43070,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,20335,N,N,N,N,N,43094,N,N,N,N,N,N,N,N,N,N,N,43097,N,N,N,N,N,N,N,N,43100, -43102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,43119,N,N,N,N,N,N,43121,N,N,N,N,N,N,N,N,N,43124,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43129,N,N,N,N,43131,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44091,44102,N,N,44106, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,44128,44379,N,N,N,N,44383,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -44401,44598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44412,44590,N,N,N,N,N,N,N,N,N, -N,N,44594,N,44596,N,N,N,N,N,30025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,44653,N,N,N,N,N,N,N,N,N,44645,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,44840,44841,N,N,N,N,44844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -44852,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30078,N,N,N,N,N,N,N,N,N,N,N,N,30241,N, -N,N,N,N,N,N,N,N,44872,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,44893,30266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44919,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -60987,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60994,61041,N,N,N,N,N,N,N,N,N,N,N,N,61054,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61248,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,61268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,61296,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61303,61480,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30566,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,61503,N,N,N,N,N,61505,N,61506,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,61513,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61520,61748,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30797,N,N,61766,N,61768,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,61788,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,61799,N,N,N,N,N,N,N,N,N,N,N,N,N,61804,61986,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61997,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -62009,62052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62068,N,N,N, -N,N,N,62071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62077,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62259,N,N,N,N,N,N, -N,N,N,N,62263,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,62279,N,N,N,N,N,N,N,62283,N,N,N,N,62280,62291,N,N,N,N,N,N,62295,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,31085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62507,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,62518,N,N,N,N,N,N,62523,62542,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62557,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,62561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62782,N,62786,62792,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,62794,N,N,N,N,62796,N,N,N,N,N,62799,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -31321,N,N,N,N,N,N,N,31322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -62828,N,N,N,62830,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62839,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63029,N,N,N,N,N,N,N,N, -N,N,63026,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63028,63065,N,N,N,N,63060, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63085,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31569,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63340,N,N,N,N,31584, -63524,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,63546,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,63555,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63566,N, -N,N,N,N,N,N,N,N,N,N,N,N,63571,63595,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63785,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63807,63817,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -31819,N,N,N,N,N,N,N,N,N,63836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64039,32088,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64362,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,64368,64373,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,64376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64567,64597,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64806,N,N,N,N,N,N,N,64808,N,N,N, -N,N,N,N,64810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64817,32318,N,N,N,N,N, -N,N,N,64831,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,65066,N,N,N,N,N,N,N,N,N,N,N,N,65069,65099,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65120,41250,N,N,N,N,N, -N,N,N,N,N,N,N,41251,N,N,41252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11812, -41253,N,41254,61486,N,41255,11813,11814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41256,N, -N,N,N,N,N,41257,41258,N,N,N,N,N,N,N,N,41260,N,N,N,N,N,N,N,N,41263,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,41264,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,11815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41265,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41268,N,41269,41271,N,N,N,N,N,N,41272,N,N,N,N, -41273,N,N,N,N,N,N,N,41274,N,N,N,N,N,N,N,N,N,41276,N,N,N,N,N,N,11816,N,N,N,N,N, -N,N,N,N,41275,N,N,N,N,N,41277,N,N,N,41278,N,N,N,N,N,N,N,11817,N,11818,41279,N, -N,11819,N,N,N,N,N,N,N,11820,N,N,N,N,N,N,N,N,N,N,41280,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41282,N,N,N,N,N,N,41283,N,N,N,N,N,N,N, -N,N,11822,11823,N,N,N,N,N,N,N,N,N,N,41284,N,11824,N,41285,N,N,N,N,N,N,11825, -11821,N,N,N,41281,N,N,N,N,N,11826,N,11827,N,N,N,N,N,N,N,N,N,N,41287,41288,N, -41289,N,N,41290,11828,N,N,N,41291,N,N,41292,N,N,N,N,11829,N,N,N,N,N,N,N,41293, -N,11830,N,N,11831,N,N,41294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -41296,N,N,N,N,N,N,N,N,N,N,N,41297,N,N,N,N,N,N,41298,N,N,N,11833,N,41299,N,N,N, -41300,N,N,41301,N,N,N,N,N,N,N,N,N,N,N,N,N,11834,N,N,N,N,N,41295,N,N,N,N,N,N,N, -N,N,N,11809,41303,41304,11835,11836,N,N,N,N,N,N,N,N,N,N,N,11837,N,41305,N,N, -41306,N,N,N,N,11838,N,N,N,41307,N,41308,N,N,N,41309,N,N,N,N,11839,N,N,N,N,N,N, -11840,N,N,N,N,N,N,N,N,N,N,N,N,11842,N,N,N,N,11841,11843,41311,N,N,N,41312,N,N, -N,N,N,N,N,41313,N,N,N,N,41314,N,N,N,41315,N,N,N,N,N,N,N,N,N,N,N,41316,N,N, -41317,N,N,N,41318,N,N,N,N,N,41319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,41321,N,N,N,N,N,N,N,N,N,41322,41323,11844,41324,41325,N,N,N,N,N,41326,N,N,N, -N,N,N,41320,N,N,N,N,N,N,41327,N,N,N,N,N,N,41329,N,N,N,N,N,N,N,N,41330,41331,N, -N,N,N,N,N,N,N,41332,N,N,41333,N,N,N,N,11845,N,41336,N,11847,N,N,N,41338,N,N,N, -N,41339,N,N,N,N,N,N,N,41340,N,N,N,N,11848,N,N,41341,N,N,N,N,N,N,N,N,11846, -41334,11851,N,N,11850,N,41761,N,N,11852,N,N,N,N,N,N,N,N,N,N,N,41763,N,N,N, -41764,N,N,11853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11854,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,11855,N,N,N,N,N,N,N,N,N,N,11857,N,11858,N,N,N,N,N, -N,N,N,41766,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41768,N,N,N,N,N,N,N,62580,N,N, -N,N,N,N,N,41769,N,N,N,N,N,N,N,41770,N,N,N,N,N,N,N,N,N,N,N,N,41772,N,N,N,N, -11860,N,N,N,N,N,41773,N,N,N,N,N,N,N,N,N,41774,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -41776,N,N,N,N,N,N,11861,N,N,N,N,N,N,11862,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,11863,N,N,N,11864,N,N,N,N,N,N,N,N,N,N,N,11865,N,N,N,N,41779,41780,11866, -41781,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41782,11868,N,11869,41783,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,11870,N,N,N,N,N,N,N,N,N,N,N,41785,N,11871,N,N,N,N,41786,12158,N,N,N, -11872,N,N,N,N,N,N,N,N,N,N,41787,N,N,N,N,N,N,N,N,N,N,41788,N,N,N,N,N,N,N,N,N,N, -41790,N,41789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11873,N,N,N,N,41792,N,N,N,N,N,N,N,N, -N,N,N,41794,N,41795,N,N,N,N,N,N,N,N,41796,N,N,N,N,N,N,N,N,N,N,41797,41798,N,N, -N,N,N,N,N,N,N,N,N,N,11874,N,41799,N,11876,N,N,N,11877,41801,N,N,N,N,11878,N,N, -N,N,11879,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11881,N,N,N,N,N,N,41803,N,N, -N,11882,11883,N,N,N,N,N,N,11884,N,N,41804,41805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,11885,N,N,N,N,N,N,N,41806,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41807,N,N,N,N,N,N, -N,N,41808,N,N,N,41809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,11887,N,11888,N,N,N,41812,N,N,N,N,41813,N,N,N,N,N,N,N,N,N,N,N,N,N,41814,N, -N,11889,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11890,N,N,N,N,N,N,N,N,N, -11891,N,N,N,N,N,N,41815,N,N,N,N,N,N,N,N,N,N,N,N,N,11892,N,41816,N,N,41818,N,N, -N,N,N,N,N,N,41819,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41823,N,N,N,N,41824, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41826,41827,11893,N,N,N,N,N, -N,N,N,N,N,N,20350,N,N,N,N,N,41829,N,N,11894,41830,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,41832,N,N,N,N,N,N,N,N,N,11895,N,N,N,N,N,N,N,41828,N,N, -N,N,N,N,N,N,N,N,N,N,41833,N,N,N,41834,N,N,N,N,11897,41835,N,N,N,N,N,N,N,11898, -N,N,N,N,N,N,N,N,N,N,11899,N,N,N,N,N,N,N,N,11900,N,41836,N,N,41837,N,N,N,N,N,N, -N,41838,11901,N,N,N,N,N,11896,N,N,N,41839,11902,N,N,N,N,41840,N,N,12065,N,N,N, -41841,41842,N,N,N,N,N,N,N,N,41843,N,N,41844,N,N,N,N,41845,N,N,N,41846,N,N, -12066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,41848,N,N,41849,N,41850,N,41851,N,N,N,N,N,N,N,N,N,N,N,12067,41852,41853,N,N, -N,N,N,N,N,41854,N,N,N,N,12068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,12069,N,N,N,N,N,N,N,N,N,12070,N,N,N,N,N,N,42017,N,N,N,N,42018,N,N,N,N, -N,42020,N,N,42021,N,N,N,N,N,12071,N,N,N,N,N,N,N,N,N,N,N,N,N,12072,N,42023, -42024,N,N,42025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42027,N,N,N, -12073,42028,N,N,N,12074,N,42029,N,N,N,N,N,12075,N,N,42030,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,12077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -42035,N,N,N,N,N,N,N,N,N,42036,N,N,42037,N,12078,N,N,42038,42032,N,N,N,N,N,N,N, -N,N,N,42039,N,N,N,N,42041,N,N,N,N,N,N,42043,42046,12080,N,N,N,N,N,12081,N, -42047,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42044,N,N,N,N,N,N,N,42048, -N,N,N,N,N,N,42049,N,N,N,12082,N,42051,N,42052,42053,N,N,N,N,N,N,42054,N,12083, -N,N,N,N,N,N,N,N,N,29735,N,N,N,N,N,N,N,N,N,N,42055,N,42056,N,N,N,N,N,12085,N,N, -N,N,N,N,42057,N,12087,N,12088,12089,N,N,N,12084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,42059,N,N,N,42060,N,N,N,N,N,N,N,N,42061,N,N,N,12090,42062,N,N,42063,12091, -N,N,N,N,N,N,N,N,N,42064,12092,N,N,12093,42065,N,N,N,N,42066,12094,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,42067,N,N,N,12095,12096,N,N,42068,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,42069,N,N,N,N,N,N,N,N,42070,N,N,N,N,N,N,N,N,N,N,N,N,N,42071,42072, -12097,N,N,N,N,N,N,N,N,N,N,42074,N,N,N,N,N,N,N,N,N,N,N,12099,N,42075,N,N,N,N,N, -42077,N,N,N,N,N,12100,N,N,N,12101,12102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42079, -42080,N,N,N,N,N,42081,42082,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,42084,N,N,N,N,N,N,42085,12103,N,N,42086,42087,42088,N,12104,N,N,N,42089, -12105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42093,N,12106, -42094,42095,N,N,N,N,N,N,N,N,N,42096,N,N,N,42092,N,N,N,N,N,N,N,N,N,N,N,12109,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,12110,12111,N,N,N,42099,N,N,12112,N,N,N,N,N,N,N, -42097,N,N,N,N,N,N,42102,N,N,N,N,N,12113,N,42103,N,N,N,N,N,N,12114,N,N,42104,N, -N,N,N,12115,12116,N,42106,N,N,42107,N,42108,N,12117,42109,N,N,N,N,12118,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42110,N,42273,N,N,N,N,N,N,42274,N,N,N,N,N,N, -N,N,N,N,42275,N,N,N,N,N,N,42276,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42278,N,N,42279, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,12120,N,N,12121,N,N,42280,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,12123,N,N,N,N,N,N,N,N,N,N,N,N,12124,42281,42282,N, -42283,N,42284,42285,N,N,N,42286,N,N,N,N,N,N,N,N,42287,12125,N,N,N,N,N,N,N,N,N, -N,12127,42288,N,N,N,N,N,N,42289,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42291,N,N,N, -N,N,N,N,N,N,42292,12130,N,N,N,12129,N,12131,N,N,N,N,N,12132,N,N,N,N,N,12133,N, -42293,N,N,N,N,N,N,12134,N,N,N,N,N,N,N,N,N,42294,42295,42296,42297,N,N,N,N, -42298,12135,42299,N,N,N,N,N,N,42300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42301,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42304,N,N,N,N,N,N,N,N,42306,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42309,N,12137,N,42310,N,N,N,N,N,N,N,N,N,N,N,N, -N,12138,N,N,N,N,N,N,N,42312,42313,N,N,N,N,N,42314,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -12139,N,N,N,N,N,N,12140,N,N,N,N,N,N,N,N,N,N,N,N,42315,N,N,N,N,12141,N,N,N,N,N, -N,N,N,N,42316,N,N,N,N,N,N,N,N,N,N,N,N,N,42317,N,N,N,N,N,N,12142,N,N,N,N,42318, -N,N,N,N,42319,N,N,N,N,12143,N,N,N,N,N,N,N,N,N,N,12144,42320,N,N,N,N,42321, -42322,N,N,42323,N,N,N,N,N,N,42324,N,N,N,N,N,N,N,N,N,32378,42328,42329,N,N,N,N, -N,12145,N,N,N,42330,N,N,N,N,N,N,N,N,N,N,N,12146,N,N,N,42331,N,N,N,N,N,42332,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -42333,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42334,N,12147,N,N,N,N,N,12148,N,N,N,N,N,N, -N,N,N,12149,N,N,42335,N,N,N,12150,N,N,N,N,N,12151,N,N,N,N,N,N,42336,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,42337,N,12152,42338,42339,N,42340,N,N,N,N,12153,N,N,N,N, -N,N,N,N,N,42341,N,42342,N,42343,N,N,N,N,42344,N,N,N,N,42345,N,N,N,N,12154,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42346,N,42347,N,N,N,42348,N,N,N,N,42349, -N,N,N,N,N,N,N,N,42351,N,42350,N,N,N,N,42352,42353,N,N,N,N,N,N,N,42354,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,42355,N,12156,N,N,N,N,N,N,N,N,N,N,N,12157,N,N,N,N,N,N,N, -42357,N,N,N,N,N,N,42356,N,N,N,N,N,N,N,N,N,N,N,N,20309,N,N,N,N,N,N,N,N,N,N, -42358,N,N,N,N,N,42359,N,N,N,20310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42360,N,N, -N,N,N,N,42361,N,N,N,N,N,N,N,N,N,N,N,N,42362,20311,N,42363,N,42364,N,N,42365,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,20312,N,N,43041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,43042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43044,N,N,N,N,N,N,N,N,N,N,N, -N,N,43046,N,N,N,N,N,N,N,43047,N,20313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -20314,N,N,N,N,43050,N,N,N,N,N,N,N,N,N,N,N,43051,43053,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,20315,N,N,N,N,N,N,N,N,N,N,N,20316,N,N,N,N,20317,N,N,N,N,N,43054,N,20318,N, -N,N,N,43055,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,32379,N,N,N,43057,N,N,20320,43058,N,N,N,43059,43060,43061,N, -N,N,N,N,N,43062,N,N,N,N,N,N,N,N,N,20324,N,43065,N,N,N,N,N,N,N,N,N,N,N,43068,N, -43069,N,N,N,N,20325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20326,43073,N,43074,20327,N, -N,43075,43076,N,N,20328,N,N,43078,N,N,N,N,N,N,N,43079,N,N,N,N,20329,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,43081,N,20330,N,N,N,N,20331,N,20332,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20333,43084,N,N,N,N,N,N,20336,N,N, -43085,N,N,N,N,N,N,N,N,N,N,N,N,43087,N,N,43088,N,N,N,43089,N,43090,20337,N,N,N, -43086,N,N,N,N,N,43091,N,N,N,N,N,N,N,43092,N,N,N,N,N,N,N,N,43093,N,N,N,20339, -20340,N,N,20342,N,N,N,N,N,N,N,N,20341,N,N,N,N,N,N,N,N,N,N,N,N,N,43095,N,N,N,N, -N,N,N,N,43096,N,N,20343,N,N,43098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20344,N,N,N, -N,N,N,43101,N,N,N,N,N,N,N,N,N,43103,N,43104,N,N,43105,N,43106,N,N,N,N,N,N, -20345,N,N,N,20346,N,N,20347,N,N,N,N,N,N,N,N,43107,N,43108,N,43109,N,N,N,20348, -43111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20349,N,N,N,N,N,43112,N,N,N,N,N,43113, -43114,N,N,N,N,N,N,N,43115,N,29736,N,43117,N,N,N,N,43118,43120,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,43122,N,29737,43123,N,N,29738,N,N,N,N,N,N,43125,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,43126,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43127,N,N,N,N,N,N,N,N,N,N, -43128,N,N,N,N,N,N,N,N,N,N,N,N,43130,N,29739,N,N,N,N,N,29740,N,N,N,N,N,N,N,N,N, -N,N,N,43132,43133,43134,44065,N,N,N,N,N,N,N,N,32380,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44067,N,N,N,N, -44068,N,44069,N,N,N,N,N,N,N,N,N,N,N,N,44070,N,N,N,N,29741,44071,N,N,N,N,N,N, -44072,N,N,N,N,29743,N,N,N,N,N,N,44073,N,N,N,N,N,N,44074,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29744,N,N,N,44076,29745,N,29746,N,N,N, -N,29747,44077,N,N,N,N,N,44078,N,N,N,N,N,N,N,N,N,N,N,N,N,44079,29748,44081,N,N, -N,N,29749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29750,N,29751,N,N,N,N,N,N,29752,N,N, -29753,N,N,N,N,29754,N,44082,N,N,N,N,N,N,N,N,N,N,N,N,29755,N,N,N,29756,N,N,N,N, -N,N,N,N,N,N,44083,29757,N,N,29758,N,N,N,N,N,N,N,N,N,N,44084,N,N,N,N,N,N,N,N,N, -N,29759,44085,N,N,N,N,N,N,N,N,N,N,29760,N,N,N,N,N,44086,N,N,N,N,N,N,N,N,N,N,N, -N,29761,N,N,N,N,N,44087,N,44088,N,N,29762,N,N,N,N,N,N,N,29763,N,N,N,N,N,29764, -N,29765,44089,N,N,N,N,N,N,N,N,N,N,N,44090,N,N,44092,N,29766,N,44093,N,N,N,N,N, -N,44094,44095,44096,N,N,N,N,N,N,N,N,N,29767,N,N,29768,44097,N,N,N,N,N,N,29769, -N,N,N,N,44098,44099,N,N,N,44100,N,N,N,N,N,N,N,N,44101,29770,N,N,N,N,N,N,29771, -N,N,44103,29772,N,N,N,N,N,N,N,N,N,44104,N,44105,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -29773,N,29774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29775,N,N,N,N,44107,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,44108,N,N,N,N,N,N,N,N,N,N,44109,N,N,N,N,N,N,N,N,N,N,44110,N,N,N,N, -N,N,N,29777,29778,N,N,N,N,N,N,N,N,N,44111,N,N,N,N,N,N,N,44113,44114,N,N,N,N,N, -N,N,N,N,N,N,N,44115,N,N,N,N,N,N,N,N,N,44116,N,N,29779,N,N,N,N,N,N,N,N,29780, -29781,N,N,N,44117,N,44118,N,29782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44119,N,N,N, -44120,N,N,44121,N,N,29783,44122,N,44123,44124,N,N,N,N,N,44125,N,N,29784,N, -44126,N,N,N,N,N,N,N,N,N,N,N,N,29785,N,N,N,N,29786,N,N,N,N,N,N,29787,N,N,44127, -N,N,N,N,N,N,44129,N,N,N,N,44130,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,44131,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44132,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,29789,N,N,N,N,44134,44135,N,N,N,44136,44137,N,N,N,N,N, -N,N,N,N,N,N,N,44138,N,N,44139,N,N,N,N,44140,N,N,N,N,N,N,N,N,N,N,N,29792,N,N, -29791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44142,N,N,N,N,N,N,N, -44143,N,44144,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44145,44147,N,N,N,N,N, -N,N,N,N,N,N,N,29794,44148,N,N,N,N,N,44149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,29795,N,N,N,N,29796,N,N,44150,N,N,N,N,N,44151,N,N,N,N,44152,44153,N,N,N, -29797,N,N,N,29798,N,N,N,N,N,N,44154,N,N,44155,N,N,N,N,N,N,N,N,44157,N,29799,N, -N,N,44158,N,N,N,N,N,N,N,44156,N,N,N,N,N,N,N,N,N,29800,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,44321,N,N,N,N,N,N,N,N,N,N,N,N,44322,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44323, -29802,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,29803,44325,44326,N,N,N,N,N,N,29804,N,N,44327,N,N,44328,N,N,N,N,N,N,N,29805, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44331,N,N,44332,N,N,N,29806, -N,44333,44334,N,N,N,N,44335,N,29807,44336,N,N,N,N,N,N,N,N,N,44337,N,N,N,N,N,N, -N,N,N,N,44339,N,N,N,N,N,N,N,N,N,N,N,29808,N,N,N,N,N,N,44342,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,29809,N,N,N,N,N,N,N,44343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44346,N,N, -N,N,44344,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,44347,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44349,44350,N,N,N,N,N,N, -44351,N,N,N,44352,N,N,N,N,29810,N,N,N,N,N,44353,44354,29811,N,N,N,N,44355,N,N, -29812,N,44348,44356,N,N,N,N,N,N,29813,N,N,N,29814,N,N,N,N,N,N,N,N,N,44357,N,N, -N,29815,N,N,44358,N,N,N,44359,N,N,N,N,N,44360,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29817,N,N,N,N,N,N,N,N,44361,44362,N,44363,N, -N,29818,N,N,N,N,N,N,N,N,N,N,N,N,29819,N,N,N,N,N,44364,N,N,N,N,N,29816,N,N,N, -44365,N,N,N,N,N,N,N,N,N,44366,N,N,N,N,N,N,N,N,N,44367,N,N,N,N,N,N,N,N,N,N,N, -44368,N,44369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -29821,29822,N,N,N,N,29985,N,N,N,N,N,29986,44370,44371,N,29820,N,29987,N,N,N,N, -44372,N,44373,N,N,N,N,N,N,N,N,N,N,N,N,44375,44376,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,29988,N,N,N,29989,N,N,N,44377,44378,N,N,N,N,N,N,N,N,N,N,44380,N,N,N,N, -44381,N,44382,N,N,N,N,N,N,N,44384,N,N,N,29990,N,N,N,N,N,N,29991,N,N,N,N,N,N,N, -N,44385,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -44387,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29993,N,N,N,44388,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,44389,N,N,N,N,N,N,44390,N,N,44391,44392,N,N,N,N,44393,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,29994,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44394,N,N, -44395,N,N,44396,N,N,N,N,N,N,44397,N,N,44398,N,N,N,N,N,N,44399,N,N,N,N,N,N,N,N, -N,N,44400,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44402,N,N, -N,N,N,N,44403,N,N,44404,29996,N,N,N,44405,N,N,N,44406,29997,N,N,N,N,N,N,N,N,N, -N,N,29998,N,N,N,N,N,N,N,N,29999,N,N,44407,30001,N,30002,N,N,N,N,N,44408,30003, -N,N,N,N,30004,30005,N,30006,N,N,N,N,N,N,30000,N,N,N,N,N,N,N,N,N,N,44409,N,N, -30008,N,N,N,30009,N,44411,N,N,44410,N,N,N,N,N,44414,N,30011,30012,44577,N,N,N, -N,N,30013,N,44578,N,30014,N,N,N,N,44581,44582,44583,44584,N,N,N,N,N,30015,N,N, -N,30016,30017,N,N,44585,N,N,N,N,44586,N,N,N,N,N,N,N,N,N,N,N,N,30018,N,N,44587, -N,44588,N,N,N,N,N,N,44589,N,N,N,N,N,N,30020,N,N,N,N,N,N,N,N,N,N,N,N,44591,N,N, -N,44592,30021,N,N,44593,N,N,N,N,N,30022,N,N,N,44595,N,N,N,N,N,N,30023,N,30024, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30026,N,N,N,N,N,N,N,N,N,N,N,N,30027,N,N,N, -44597,N,N,N,N,N,N,N,N,N,N,N,N,N,30028,30007,44599,N,N,N,44600,N,N,N,N,N,N,N,N, -N,N,N,N,44601,30029,N,N,N,N,N,44603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,30031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30033,30034,N,N,N,44606, -44607,N,N,N,N,N,N,44608,N,N,N,N,N,N,N,N,44609,N,N,N,N,N,N,N,N,30032,N,N,N,N,N, -N,N,N,N,N,N,N,N,44613,N,44614,N,N,N,N,30035,N,N,N,N,N,30036,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,44616,30037,N,N,N,N,30038,N,N,30039,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,44620,N,44621,N,N,N,N,N,N,N,N,30040,N,N,N,N,30042,N,N,44622,N,N,N, -N,44623,N,N,N,N,N,N,N,N,N,44624,N,N,N,N,30043,N,44625,N,44626,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,44627,N,N,N,N,N,N,44628,N,30041,N,N,30044,30045,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,44619,N,N,N,N,N,N,N,44632,N,N,N,N,30047,N,44633,N,N,N,N, -N,N,N,N,N,N,N,N,30048,44634,N,N,N,30049,N,44636,N,N,N,N,N,N,N,44637,N,N,44638, -N,N,N,N,N,44639,44640,N,N,N,44641,N,N,44642,N,N,N,N,N,30046,N,N,44643,N,44644, -N,N,N,30050,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44646,N,N,44647,N,N,N,30051,N,N, -30052,N,N,N,N,44648,N,44649,N,N,N,N,N,44650,N,N,N,N,N,N,N,N,N,N,N,N,N,44651,N, -N,N,N,N,44652,N,44654,44655,44656,N,44657,N,N,N,N,N,N,30054,N,30055,N,N,N,N, -44658,44659,N,N,N,N,N,N,30056,N,44660,N,N,N,N,N,N,44661,N,N,N,N,N,N,N,44666,N, -44667,N,N,30057,N,N,N,44668,N,N,44669,30058,N,N,N,N,N,44670,N,N,44833,N,N,N,N, -N,N,N,N,N,N,44834,44835,N,N,30059,N,N,N,44836,30060,N,N,30061,30062,N,N,N,N,N, -44837,N,N,N,44662,30063,44838,N,N,N,44839,N,N,30064,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30067,N,N,N,N,N, -44843,N,N,N,N,N,N,30068,N,N,N,44845,N,N,30065,N,N,N,N,N,N,N,N,N,N,N,N,N,30069, -N,N,N,N,N,N,N,N,N,N,N,30070,30071,N,N,N,30072,44846,N,N,44847,N,N,N,N,N,44848, -N,N,N,N,N,N,N,44849,N,N,N,N,44850,30073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -44851,N,N,N,44853,N,44854,N,N,N,N,N,N,N,N,N,N,N,N,30075,44855,N,N,N,N,N,N, -30076,N,N,44856,N,N,N,N,N,N,44857,N,N,44858,N,44859,N,N,N,44860,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,30077,N,44861,N,N,N,N,44862,N,N,N,N,N,N,N,N,N,N,N,30242,44868,N, -N,N,N,N,30243,30244,N,N,N,44869,44870,N,N,N,44871,44873,30245,30246,N,N,N,N,N, -N,N,44874,30247,N,44875,N,N,N,30248,N,N,N,N,44876,N,N,44877,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,44865,N,44879,44880,44881,N,N,N,N,N,N,30250,N,N,30251,44882, -N,N,N,N,N,30252,44883,N,N,44884,N,N,N,N,44886,N,30253,N,44887,N,N,N,30254,N,N, -N,N,30255,N,N,N,N,N,N,N,N,44888,N,N,N,N,N,N,30256,N,N,N,N,N,N,N,30257,N,N,N,N, -N,N,44885,N,N,N,44890,N,N,N,N,44891,N,N,N,N,N,30259,N,44892,N,N,N,N,N,44894,N, -N,30260,N,N,N,N,N,N,N,N,30261,30262,44895,N,44896,N,N,N,30263,N,N,N,N,N,44898, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44899,N,N,N,N,N,N,N,N,44900,N,N,N,N,N,N,N,N, -N,44902,N,N,N,44901,N,N,N,N,N,N,N,44903,44904,N,N,N,N,N,N,30264,N,N,30265,N,N, -N,N,44907,N,N,N,N,44908,44909,44910,N,N,N,N,N,N,N,N,N,44911,44913,N,N,N,44914, -44915,44916,N,N,N,N,N,44918,N,N,N,30268,N,N,30269,N,N,N,N,N,N,N,N,N,N,N,N,N, -30270,N,N,44920,N,N,N,N,N,30271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30272,N,N,N, -44921,N,N,N,N,N,N,N,N,N,N,N,30273,N,44922,N,N,N,N,N,N,N,30274,N,N,N,N,30275,N, -30276,N,N,N,N,44923,N,N,N,N,N,N,N,N,44924,N,30277,N,N,44925,N,N,N,N,N,N,44926, -30278,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60961,N,N,N,N,N,N,N,N,N, -N,N,N,N,30279,N,N,N,30280,60962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60964,60965,N,N,N, -N,N,N,N,N,60966,60967,60968,N,N,N,N,N,30282,N,N,N,N,N,N,30283,30284,N,N,60969, -N,N,N,N,N,N,N,N,N,N,N,60970,60971,N,N,N,N,N,N,60972,N,N,60973,N,N,N,N,N,N,N,N, -N,N,N,N,N,30285,60974,N,N,30286,N,N,N,N,60975,N,N,N,60976,N,30287,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30288,N,60977,60978,N, -N,N,60979,N,N,N,N,60981,N,N,N,N,N,N,N,N,N,N,N,N,N,60982,N,N,N,N,N,N,N,N,N,N,N, -30289,N,60983,30290,N,N,N,N,N,N,N,N,N,N,61007,N,N,N,N,N,60984,N,N,N,N,N,N, -30292,N,30293,N,N,N,N,N,N,N,N,N,N,N,N,N,60985,30294,30295,N,N,60986,N,N,N,N,N, -N,N,N,N,N,60988,60989,N,60990,30296,N,N,N,30297,N,N,N,N,N,N,N,N,N,N,N,N,N, -30291,N,N,60991,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60992,N,N,N,30299,N,N, -N,N,N,N,N,N,N,60993,N,N,N,30300,N,60995,N,N,N,60996,N,60997,N,N,N,30301,N,N,N, -N,N,N,N,N,60998,N,30302,60999,61000,30303,N,N,N,N,N,N,N,N,N,N,N,N,30298,61002, -N,N,N,30305,N,N,N,N,N,61003,N,N,N,30306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,61004,N,61005,61006,N,N,N,N,N,N,30307,61008,N,30308,N,N,61029,N,N,N,N, -30309,N,N,61009,N,N,30310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -30311,N,N,61010,N,N,61011,N,61012,N,N,N,N,30312,N,N,N,N,N,N,N,N,N,N,61013,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,61014,61015,30314,N,N,N,N,30315,N,30316,61016,N,N, -61017,N,N,N,61018,N,N,30317,N,N,N,61019,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -30318,61025,30319,N,61026,N,N,N,N,N,61027,N,N,N,N,N,N,N,N,N,N,30320,N,N,61028, -N,30321,N,N,N,61030,N,N,N,N,N,61031,61032,61033,N,N,N,N,N,30322,N,N,N,30323, -30324,N,30325,N,61034,N,N,N,N,N,N,N,N,N,61035,N,N,N,N,N,N,N,N,N,N,N,N,61036,N, -N,N,N,N,30326,61021,N,N,N,N,N,N,61038,N,N,N,61039,N,N,N,N,61040,N,N,N,N,N,N,N, -N,N,N,61042,N,30328,N,61037,N,N,N,N,N,61043,N,N,N,N,N,N,N,30329,N,N,N,61044, -61045,N,61046,61047,N,N,61048,N,61049,N,61050,61051,N,N,61052,N,N,N,N,30330,N, -30331,N,N,N,N,61053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61217,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,61218,N,N,N,30332,N,N,N,N,N,30333,N,N,61219,N,N,N,N,N,N,N,N,N,N,61220,N, -30334,N,61221,N,N,N,30497,N,N,61222,N,N,N,30498,N,N,N,N,N,N,N,N,N,N,61223,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61225,N,N,N,N,N,N,N,N,N,N,N,N,N,61226,N,61227, -61228,N,61229,N,N,N,30499,N,N,N,N,N,N,N,61230,N,30500,N,N,N,N,N,N,N,N,N,N, -61231,N,N,N,N,30502,N,N,N,N,30503,N,N,N,30504,N,61224,61232,N,N,N,N,N,61233,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30505,61235,N,N,N,N,61236,N,30506,61237, -N,N,N,30507,N,61238,30508,30509,N,N,N,N,N,61239,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,61241,30510,N,N,N,N,N,N,N,N,N,30511,N,N,N,30512,30513,N,N,61242,N,N, -N,30514,N,61243,N,61240,N,N,N,N,N,N,61245,30515,N,N,N,N,61246,N,30516,N,N,N,N, -N,N,N,61247,N,N,N,N,N,61249,30517,N,N,N,N,N,30518,N,61244,N,N,N,N,N,N,N,N, -30519,61250,61251,30520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61252,N,N,N,61253,N,N,N, -N,N,N,N,N,N,N,61254,N,N,N,N,N,N,30522,N,N,N,N,30523,N,N,N,30521,N,N,61256, -61257,N,N,N,N,30524,30525,61258,N,N,61259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,61260,N,N,N,N,30526,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61262,61263,N, -61264,N,N,N,N,N,N,61265,N,N,N,61266,N,N,30527,61267,N,N,30530,N,N,N,N,N,61269, -N,N,N,N,N,N,N,N,30528,30529,N,N,N,N,N,30531,61270,N,N,N,61271,N,N,61272,N, -61273,N,N,N,N,N,N,30532,61274,N,N,N,N,N,N,N,61275,N,N,61276,N,N,N,30533,61277, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,61278,N,61279,N,N,N,N,N,N,N,61282,N,N,N,N,30534,N, -N,N,N,N,N,30535,N,N,N,N,N,61283,N,N,N,N,N,30536,N,N,N,61280,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,61286,N,N,N,N,N,N,61287,N,61288,30537,N,N,N,30538,N,N,N,61289,N,N,N, -N,N,N,N,30539,N,N,N,N,N,N,N,61285,61290,61291,N,61292,61293,61294,N,N,N,61295, -N,N,30540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30542,N,30543,N,N,N,N,N,N,N,N,N,N,30541, -N,N,30544,61297,30545,61298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30546, -30547,N,N,61300,N,N,N,N,N,61299,30548,30550,61301,N,N,N,N,N,N,N,N,30551,N, -61302,N,30552,N,N,N,N,N,N,N,30553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,61305,N,N,N,N,30555,N,30556,N,N,N,N,N,N,N,N,N,N,30557,N,N,N,61304,N,N,N,N, -61306,N,N,N,N,61307,N,61308,N,N,N,N,N,N,N,N,N,N,N,61309,61310,N,N,N,61473,N,N, -N,N,N,N,30559,N,N,N,N,N,N,30558,N,N,30560,N,N,N,N,N,N,61475,N,N,N,N,N,N,N, -61476,N,N,N,N,N,61477,N,N,61478,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,30561,30562,N,N,N,N,N,N,61479,N,N,N,N,N,N,N,N,N,N,N,N,N, -30563,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61482,N,N,N,N,N,N,N,N,61483,N, -N,N,61484,61485,N,N,N,N,N,N,N,N,61487,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61488,N, -30564,30565,61489,N,N,N,N,N,N,N,N,N,N,N,61490,N,N,N,N,N,N,N,N,N,N,61492,61493, -N,N,N,N,N,N,N,N,61494,N,N,N,N,N,N,61495,N,N,N,N,N,N,N,N,N,N,N,N,N,30567,61496, -N,N,N,N,N,N,N,N,N,N,N,N,30568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61498,61499,N, -61500,61501,N,N,N,N,N,N,N,N,N,N,N,N,30569,N,30570,61502,N,N,N,N,N,N,N,N,N,N, -61504,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,61507,N,N,N,N,N,N,61508,30571,61509,N,N,N,N,N,N,N,N,N,N,61510,N,N,N,N,N, -61511,61512,N,N,N,N,N,N,N,N,N,N,N,N,N,30573,30574,N,N,N,61515,N,N,N,N,61516,N, -61517,N,N,N,N,N,61514,N,N,N,61518,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30576,N, -61519,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30577,N,N,N,N,61521,61522,N,61524, -61525,N,61526,N,N,N,N,N,61527,N,N,N,N,30578,N,N,N,N,61528,N,N,N,61529,N,N,N,N, -61530,N,N,N,N,N,N,N,N,N,61531,30579,N,N,61532,N,N,N,61533,N,61534,30580,30581, -N,30582,N,N,61535,30583,N,61536,N,N,30584,N,N,N,N,N,N,N,N,N,61537,N,61538,N, -61539,N,N,61540,N,N,61541,N,N,N,N,N,61542,N,N,N,30585,N,61543,N,N,N,30586,N,N, -N,N,N,N,30587,N,N,30588,N,N,N,N,N,N,N,61544,N,30589,N,N,N,61545,N,30590,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,61546,61548,61549,N,N,N,N,N,30753,N,N,30754,N,N,N,N,N, -N,N,N,61547,N,N,N,N,N,N,30755,30756,N,N,N,N,N,N,N,N,61550,N,30758,N,30759,N, -30760,30761,30762,N,30763,30764,30765,61551,N,N,N,N,N,N,N,61552,N,N,N,N,N,N, -61554,N,N,61555,30766,N,30767,30768,N,N,N,30769,N,61556,N,N,N,N,61557,61553,N, -N,N,30770,N,N,N,N,N,61558,N,N,N,N,30771,N,N,N,N,N,N,N,N,30772,N,30773,N,N,N, -61559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61560,N,N,N,61561,30774,30775,61562,30776, -N,N,N,N,N,N,30781,N,61564,N,N,N,N,61565,30777,61566,N,N,30778,N,N,30779,61729, -61730,N,30780,N,61731,30782,N,30783,30784,61732,61733,N,N,N,N,N,N,N,N,N,30785, -N,N,N,61734,61736,61735,N,N,N,30786,N,N,N,N,N,N,N,N,30787,30788,N,N,N,N,N,N,N, -N,N,N,N,N,61737,N,61738,N,30789,N,N,N,61739,N,N,N,N,N,N,N,N,N,N,N,N,61741,N,N, -N,61740,N,N,N,N,N,N,N,N,N,N,61743,N,N,N,N,30790,30791,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,30792,N,N,N,N,N,N,N,N,61745,N,N,N,61746,N,N,N,N,N,61747,N,N, -N,N,30793,N,N,N,N,N,N,N,N,N,N,N,N,N,61750,61751,N,61752,N,N,N,N,N,N,N,61753,N, -N,N,N,N,61754,N,61755,N,61756,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,61757,N,N,30794,N,61759,61758,N,N,N,N,N,N,30795,61760,N,N,61761,61762,N,N, -61763,N,N,N,N,N,N,N,N,N,N,61765,N,N,N,N,N,30796,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -61767,N,N,N,N,N,N,N,N,N,N,N,N,N,61769,N,N,N,N,N,N,61770,N,N,N,N,N,N,N,61771, -61772,N,N,N,N,N,61773,N,N,N,N,N,N,N,30798,61774,N,N,N,61775,N,N,N,N,N,N,N,N,N, -61776,N,61777,61778,N,N,N,30799,N,N,61779,N,N,N,N,61780,N,61781,N,N,61782,N,N, -N,N,N,N,N,61783,30800,N,30801,61784,N,N,N,61786,30802,N,N,N,N,N,N,61787,N,N,N, -61790,N,30803,30804,N,61785,30805,N,61791,61792,N,30806,N,N,N,N,N,N,61794, -32381,N,61795,N,N,N,N,30807,N,N,N,N,N,61797,N,30808,N,N,N,N,N,N,61796,N,N,N,N, -61800,N,30809,N,N,N,N,N,61802,N,30810,N,N,N,N,N,N,N,N,N,61803,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,30811,30812,N,N,N,N,N,N,N,30813,61805,30814,N,30815,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,30816,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61806,N,N,N,N,N, -30817,61807,30818,30819,N,61809,61808,N,N,N,N,30820,61810,61811,N,30821,N,N,N, -N,61812,N,N,N,N,N,N,30822,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30823,N,N,N,61814,N,N, -30824,N,30825,N,N,N,N,N,30826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30827,N,61816, -N,N,N,61817,N,N,N,N,30828,N,N,N,N,N,N,N,N,N,N,30829,30830,N,N,N,N,N,N,N,N,N,N, -N,N,61819,N,30831,61820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61821,N,N,N,N,N,N, -30832,61822,30833,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30834,N,N,N,N,N,N,30835,30836, -N,N,N,N,N,N,N,N,N,61989,N,N,N,30837,N,N,30838,61990,N,30839,N,N,N,N,N,N,N, -61991,N,N,N,N,N,N,N,61993,N,N,N,N,N,N,N,30840,N,61994,61995,N,N,30841,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30842,N,N,N,N,N,61998,N,N,N,N,61999,N,N,62000,N, -62001,N,N,N,N,62002,30843,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62003,62004,30844,N,N,N, -62005,N,62006,N,N,N,62007,N,62008,N,N,N,62010,N,N,N,62011,N,N,N,N,N,N,62012, -62014,62015,N,N,62016,N,N,N,62017,N,N,N,N,N,N,N,N,N,N,N,62018,N,N,N,N,N,N,N, -62019,N,N,N,N,N,N,N,N,N,N,62020,30845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,31009,N,N,N,62021,N,N,N,N,N,N,31010,31011,N,31012,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,62022,N,N,N,31013,N,62023,N,N,N,31014,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,62025,N,N,N,N,N,N,N,N,N,62026,N,N,N,N,N,N,N,N,62028, -62029,62030,N,N,N,N,62027,N,N,N,N,N,N,N,N,31018,N,N,31016,N,N,N,N,N,N,N,N,N,N, -62031,N,N,N,N,N,N,N,N,N,N,N,N,62032,N,N,N,62033,N,62034,N,N,N,N,N,N,62035,N,N, -N,N,N,N,N,N,N,N,62036,62037,N,N,31019,N,62038,N,N,N,N,N,N,N,N,N,N,N,31020,N,N, -N,N,31022,N,62039,62040,62041,N,N,62042,31021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -62044,N,N,N,N,N,N,N,N,N,N,62045,31023,N,N,N,N,N,N,N,N,62047,N,N,N,N,N,N,N,N, -31024,N,62046,31025,N,N,31026,N,N,N,N,N,N,62048,N,N,N,N,N,N,N,N,N,31029,31030, -N,N,N,62049,N,N,N,N,N,N,N,N,N,N,N,N,N,62050,N,N,62051,31034,N,N,N,N,N,N,N,N,N, -N,62053,N,N,N,N,N,N,N,N,N,N,62054,N,N,N,N,N,N,31038,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,62055,62056,62057,N,31042,N,N,62058,N,N,N,N,N,62059, -N,N,N,N,N,N,N,62060,N,N,N,N,N,N,N,31043,N,N,62061,N,N,N,31044,N,N,62062,N,N,N, -N,N,N,62063,N,N,N,N,62064,31045,N,31046,N,62065,62066,N,N,N,N,N,N,31048,N, -62067,N,N,N,N,N,N,N,31049,N,N,N,N,N,N,N,N,N,N,N,N,31050,N,31051,31052,N,N,N,N, -N,N,62072,N,N,N,N,N,N,62073,N,N,N,62074,N,N,N,N,N,62075,N,N,62076,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,62078,N,N,N,N,N,N,N,N,N,N,62241,31054,N,N,N,N,N,N,N,N,N,N,N,N, -N,62242,N,N,N,N,62243,N,N,N,N,N,N,N,N,N,62244,N,N,62245,N,N,62246,31055,N, -62247,62248,N,N,N,N,N,N,62249,N,N,62250,N,N,31056,N,N,N,N,N,N,N,62251,N,N, -62252,N,N,N,N,N,N,N,N,N,62253,N,N,31058,N,N,N,N,62254,N,N,N,N,N,62255,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,31059,N,N,62256,N,N,N,N,N,N,N,N,62257,N,N,N,N,N,N,31061, -N,N,N,N,N,62260,N,31062,62261,N,62262,N,N,N,N,N,N,N,N,N,N,N,N,N,62264,N,31063, -N,N,62265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62266,62267,N,N,31064,N,N, -N,N,N,N,N,N,62268,N,N,N,N,N,N,N,N,31065,62271,N,N,N,N,N,N,N,N,N,N,31066,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62274,N,N,62275,N,N,31067,62276,62277,N, -62278,N,N,N,N,N,N,N,N,N,31068,N,62273,N,N,N,62282,N,N,N,N,N,31069,N,N,N,N,N,N, -31070,N,N,N,N,N,N,62284,N,N,N,N,N,N,N,N,N,N,31071,N,N,N,62286,N,62287,N,N, -62288,N,N,N,31072,N,31073,N,N,31074,62289,N,N,N,N,N,62285,N,N,N,N,N,62281,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,62292,62293,N,N,N,N,N,N,N,N,N,62294,N,N,31075,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,62296,N,N,N,N,N,62297,N,N,N,N,N,N,62298,N,N,N,N,N, -N,N,N,62299,N,N,N,N,62300,N,N,N,N,N,N,N,N,N,62303,N,62304,31077,N,31078,62305, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62306,N,N,N,N,N,62307,31079,N,62308,N,N,N,N,N,N, -N,62309,N,N,62310,62311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31081,N,31082,N,N,N,N,N, -62312,N,N,N,N,N,N,N,N,N,N,31080,N,31083,N,N,31084,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -62313,N,N,N,N,62314,N,N,N,N,N,N,62315,N,N,N,N,N,62316,N,31087,N,N,N,N,62317,N, -N,62318,N,N,N,N,N,N,N,62319,N,N,N,31088,62320,62321,62322,N,N,N,N,N,N,N,N, -31089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31090,N,N,N,N,31091,N,N,N,N,N, -N,N,N,N,N,N,31092,N,N,N,N,N,62326,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62328,62329,N, -N,N,N,31093,N,N,62330,N,N,N,N,62332,N,N,N,62334,N,N,N,N,62497,N,N,N,N,N,N,N, -31094,N,62499,N,31095,N,N,N,31096,N,N,N,N,N,N,N,N,62501,N,N,N,N,62502,N,N,N,N, -N,N,N,N,N,62504,62505,N,N,N,31097,31098,62506,N,N,N,N,N,N,N,N,62508,31099,N,N, -N,N,N,N,N,N,N,31100,62509,N,N,N,N,31101,N,N,N,N,N,N,N,N,N,N,N,N,N,31102,N,N,N, -N,N,N,N,N,N,N,N,62512,62513,N,62514,31265,N,N,N,N,N,62515,31266,N,N,N,N,N,N,N, -N,N,N,31267,N,N,N,N,N,62519,62520,N,31268,N,N,N,N,N,N,N,N,N,N,N,N,N,62521,N,N, -N,N,N,62522,N,N,N,N,N,N,N,N,N,31269,N,N,N,N,62524,N,N,N,31270,N,N,62526,N, -62527,N,N,31271,62528,N,N,N,N,N,N,N,N,N,N,62529,N,N,N,N,N,62531,N,N,31272,N,N, -N,N,N,31273,62532,N,N,62533,N,N,N,N,N,N,N,N,N,N,N,62534,62535,N,N,N,N,N,N,N,N, -62536,N,31274,N,N,N,N,N,N,N,N,N,31275,N,N,N,N,N,N,N,N,N,31276,62537,N,62538,N, -N,N,N,N,N,N,N,N,31277,N,N,62539,N,N,N,N,N,N,N,N,N,N,62540,N,N,N,N,N,N,N,62541, -31280,N,N,N,N,N,N,N,62545,31281,N,N,N,31282,N,62546,N,N,N,N,N,62547,N,N,62548, -N,N,N,N,N,N,62549,31279,N,N,N,62550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,62551,N,31284,N,N,N,N,N,N,N,N,N,N,31285,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -31286,N,N,N,N,N,N,N,N,N,32382,N,N,N,N,N,N,N,62552,N,62553,N,N,N,N,N,N,N,N, -62554,N,N,N,N,N,N,N,62555,62556,N,N,31287,N,N,31288,N,N,N,62558,N,N,N,N,N,N, -62559,N,62560,62563,62562,N,62564,N,N,N,N,62565,62566,N,N,31289,N,N,N,N,N,N,N, -62567,N,N,62570,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62572,N,62573,62574,N,N,N,N,N,N,N, -N,62575,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62576,62577,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,62579,31291,N,N,N,N,62582,31292,N,N,N,N,62583,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,62584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31293,N,N,N,62586,N,N,N,N,N,N,N, -N,N,N,31294,62587,N,N,N,N,N,N,N,N,N,N,N,31295,N,N,N,31296,N,N,N,62588,N,62589, -N,N,N,N,N,N,31297,N,31298,62590,N,N,62753,N,N,N,N,N,N,N,31299,62754,N,N,N,N,N, -62756,N,62755,N,N,N,62757,N,N,62758,N,N,31301,N,62759,N,N,N,N,N,N,N,N,N,N,N,N, -N,62760,N,31302,N,N,N,N,N,62761,N,N,N,62762,N,N,N,N,31303,N,31304,N,N,N,N, -31305,N,N,N,N,N,N,62763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,62764,N,N,N,N,N,N,N,N,N,N,62765,N,N,N,62766,N,N,N,N,N,62767,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62768,N,N,62769,N,N,N,N, -N,N,N,62770,N,N,62771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62772,N,N,N,N,N,N,N,N,N, -N,N,N,62774,N,N,N,N,31306,N,N,N,N,N,N,N,N,N,N,62775,N,31307,62776,N,N,N,N,N,N, -N,31308,N,N,N,N,N,62777,N,N,N,N,N,N,N,N,N,N,N,N,31309,N,62780,N,N,N,N,N,62781, -62779,N,N,N,N,N,N,N,N,62784,N,31310,N,N,N,N,N,62785,N,N,N,N,N,62787,N,N,62788, -N,N,N,N,62789,N,N,N,N,N,N,N,N,62783,N,N,N,N,N,N,N,62791,N,N,N,N,N,N,N,N,N,N,N, -N,31311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31312,N,N,N,N,N,N,31313, -31314,62793,N,N,N,31315,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62795,N,N,62797, -62798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62800,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,62801,N,N,N,N,N,N,N,N,31316,N,N,N,N,N,62802,N,62803,N,N,N, -N,N,N,31317,N,N,N,N,31318,N,N,N,N,N,N,62804,31319,N,N,N,62805,N,N,N,N,N,N,N,N, -62807,N,N,N,N,N,N,N,62809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62811,N,62812,62814, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62816,N,N,N,N,N,N,N,62817,62818,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,62820,N,62821,N,N,N,N,N,N,N,62822,N,N,N,N,N,N,N,N, -62825,62823,N,N,62824,N,62827,N,N,N,62829,N,N,N,N,N,N,N,62831,N,N,N,N,62833,N, -N,N,31323,N,N,62834,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31324,N,N,N,N,62838,N,N,N, -62840,N,62841,N,N,N,62842,N,N,N,N,N,N,62843,N,N,N,31326,N,N,N,N,62844,N,N,N,N, -N,N,N,N,N,N,N,N,N,31327,N,31328,31329,N,N,62845,62846,31330,N,N,N,N,31331,N,N, -N,63009,N,63010,N,N,31332,N,N,63011,N,63012,N,31333,31334,N,N,N,N,N,N,31335,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,31336,N,N,N,N,N,N,N,N,N,N,N,N,63013,N,N,N,N,N,63014, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,63015,N,N,N,N,N,31337,31338,31339,31340,N,N,N,N,N, -63016,63017,N,N,N,63018,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63020,N,63021,N,N,N,N, -31342,N,N,N,N,N,N,N,N,N,N,31343,N,N,63022,N,N,N,N,N,N,N,N,N,31344,N,63023,N,N, -N,N,N,N,31345,63024,N,N,31346,N,N,N,N,N,N,N,N,N,31347,N,N,63019,31348,N,63025, -N,N,N,N,N,N,N,N,N,N,31341,44618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,31349,N,63027,N,N,N,N,N,N,31350,N,N,N,N,N,N,63030,N,N,N,N,31351,N,63031, -63032,N,N,31352,N,N,63033,N,63034,N,N,N,N,N,N,N,N,N,31353,N,31354,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31355,31356,N,N,N,N,N,N,31357,N,63035,N,N,N,N,N, -31358,63036,31521,N,N,63037,N,N,N,N,N,N,N,N,63038,N,N,N,31522,N,N,N,63039,N,N, -N,N,31523,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63040,31524,N,N,N,N,31525,N,N,N,31526,N, -N,N,N,63041,N,63042,N,N,N,63043,N,63045,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,63046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31528,N,63047,N, -N,N,N,63048,N,63049,63050,N,N,N,N,N,N,63051,63052,N,63053,N,N,31529,N,N,N,N,N, -63055,N,N,N,N,N,N,N,N,N,N,31530,N,N,31531,N,N,63056,N,63057,N,N,N,63058,N,N,N, -N,63059,N,N,N,31532,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63062,N,N,N,N,N,N,31533, -N,N,N,N,N,N,N,63063,N,N,N,N,N,N,N,N,31534,N,N,N,N,31535,N,N,N,N,N,31536,N,N,N, -63064,N,31537,N,31538,N,N,N,N,N,N,N,N,N,N,N,63066,63067,N,N,N,63068,N,N,N,N,N, -N,N,N,63061,N,N,N,N,N,N,N,N,N,N,63070,N,N,63071,N,N,N,N,63072,63073,63074,N,N, -N,N,N,N,N,N,63075,N,N,63076,63077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63078,N,N,31541, -N,N,N,N,31542,63079,63080,N,N,N,N,N,63081,N,N,N,31543,N,N,31540,N,63082,N,N,N, -N,N,N,N,N,N,63087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63083,N,63088,N,63089,N,N,N, -N,N,31544,N,N,N,N,63090,N,N,63091,63092,N,31545,N,N,N,N,N,N,N,N,N,N,63084,N,N, -N,N,N,N,N,N,N,N,31548,63094,N,63095,N,63096,N,63097,N,N,N,N,63098,N,N,N,N,N, -31549,N,N,31550,N,N,N,63099,N,N,N,N,N,N,N,N,N,63100,N,63101,N,N,31551,N,N,N,N, -N,N,N,N,N,N,31547,N,N,31552,N,N,N,N,N,N,63267,N,N,N,N,63268,N,N,N,N,N,N,N,N,N, -N,63269,N,N,63270,31553,N,N,31554,N,N,N,N,N,N,N,N,N,63271,63272,N,N,N,N,N, -63273,N,63274,N,N,N,N,63275,N,N,N,N,N,N,31555,N,N,N,N,N,N,N,N,63276,N,N,N,N,N, -N,N,N,31557,63277,N,N,N,31558,31559,N,N,N,N,N,N,N,N,N,N,31560,63278,31556,N,N, -N,N,N,31562,N,N,N,N,N,63279,N,N,63280,N,N,63281,N,N,63282,N,31563,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,31564,63284,N,N,63285,N,N,N,63287,12136,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,63289,N,N,63290,31565,N,N,N,31566,N,N,N,N,N,N,31568,N,N,N,N,N,N,N, -N,N,31570,N,N,63291,N,N,N,N,N,31571,N,63292,N,N,63293,N,N,N,N,N,N,N,N,N,N,N,N, -63294,N,63295,N,N,N,63296,N,N,N,63297,N,N,N,N,N,N,31572,N,N,N,63298,63299,N,N, -N,N,N,N,N,N,N,N,63300,N,N,N,N,N,N,N,N,63302,N,63303,N,N,N,N,31573,N,N,N,N,N,N, -N,N,63304,N,63305,N,N,N,N,N,N,N,N,N,N,N,N,N,63306,N,N,N,63307,N,63308,N,N,N,N, -N,N,N,N,N,N,N,63309,N,N,63310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31574,N, -31575,31576,63312,N,63313,N,N,N,31577,N,N,63314,N,63315,N,N,63316,N,N,N,N,N, -63317,N,N,N,N,N,63318,N,63319,N,63320,N,N,N,N,N,N,N,N,N,N,N,N,N,63321,N,N,N,N, -N,N,N,N,63322,N,N,N,63323,N,63324,N,N,63325,N,N,N,N,N,N,N,N,N,N,N,N,N,63326,N, -N,N,N,N,N,63327,N,N,N,N,N,N,N,N,N,N,N,63328,63329,N,N,N,N,N,N,N,N,N,N,N,31578, -63330,N,N,N,N,N,N,N,N,N,63331,N,N,N,N,N,N,N,N,N,N,31579,31580,63335,N,63336,N, -N,N,N,N,N,N,63337,N,N,N,N,N,N,N,N,N,N,N,N,63338,N,N,N,N,N,N,63334,N,N,N,N, -31581,31582,N,N,N,N,N,N,N,31583,N,N,N,N,N,N,N,N,63341,N,N,63343,N,N,N,N,N,N,N, -N,N,N,N,N,63344,N,N,N,N,N,N,N,31585,N,N,N,N,N,N,N,N,63346,N,N,N,63348,N,63349, -63350,N,N,N,63351,63352,31586,63353,N,N,N,N,N,N,N,63345,63354,N,63355,N,N, -31587,N,N,N,31588,63356,N,N,N,N,31589,N,N,63357,31590,N,N,N,N,N,N,N,N,N,N, -31591,N,N,N,N,N,N,N,N,63358,N,N,N,N,N,63521,N,N,N,63522,N,N,N,N,N,N,N,N,N, -63523,N,N,N,N,N,N,N,N,N,N,N,N,N,63525,N,N,N,N,N,N,N,N,N,N,N,N,N,63526,N,N,N,N, -N,N,63527,N,N,N,N,63528,N,N,N,N,63531,N,N,N,N,N,63533,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31592,N,N,N,N,N,N,N, -63534,N,N,N,N,N,N,N,N,N,31593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63535,63536, -63537,N,63538,N,N,N,N,N,N,N,N,N,31594,N,N,N,31595,N,N,63541,63539,63542,N,N,N, -N,N,N,N,63543,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63544,63545,N,N,N,31597, -63547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31600,31601,31602,N,31598,N, -N,N,N,N,N,N,N,N,N,31603,N,N,N,N,N,N,N,N,31604,N,31605,N,N,N,N,63549,N,31606,N, -N,N,N,N,N,31607,N,63551,N,N,63552,N,N,N,63553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,63556,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,63557,N,N,N,N,N,N,N,N,63558,N,N,N,N,N,N,63559,N,N,N,31608,N,N,N,N,N,N,N,N,N, -N,63560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63561,N,N,N,N,N,N,63562,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31610,N,63563,N,63564,N,N,N,N,N,N,N, -N,N,N,N,N,31611,N,N,N,N,N,63565,N,N,N,N,N,63567,N,63568,N,N,31612,N,N,N,N,N,N, -63569,N,63570,63572,31613,N,63573,31614,N,N,N,N,N,N,N,N,N,N,N,63575,31777,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63576,N,31778,N,N,N,N,N,N,63577,N,N,N,N,N,N, -63578,N,31779,N,N,N,N,N,63579,31780,N,N,N,N,N,N,N,N,N,63580,N,N,N,N,31781,N,N, -N,31782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31783,N,N,N,31784,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63582,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,31785,N,N,N,N,N,N,63581,N,N,N,N,N,N,N,N,63583,N,N,N,N,N,N,63584,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,31786,N,N,N,N,N,N,63585,N,N,N,N,N,N,N,31787,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,31788,N,31789,N,N,N,N,N,63586,63589,N,N,N,N,63588, -N,N,63590,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63591,N,N,63592,N,N,N,N,N,N,N,N,N,N,N,N, -N,63593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63594,N,N,31793,N,N,N,N,N,N, -N,N,N,N,63596,N,N,31794,N,N,N,N,31795,N,N,N,N,63597,N,N,N,N,N,N,N,N,N,N,31796, -N,N,N,N,N,N,N,N,N,N,N,N,63598,N,N,N,N,N,N,N,N,63599,N,63600,N,N,N,N,N,N,N,N,N, -63601,N,N,N,N,N,N,N,N,63602,63603,N,N,N,N,N,N,63604,31797,63605,63606,N,N,N, -63608,N,N,N,N,N,N,N,63611,N,63612,N,31798,N,N,N,N,N,63613,N,N,N,N,63614,N,N, -63777,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31799,63778,N,N,N,63779,N,N,N,N,N,63780, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63783,63782,N,N,N, -N,N,63784,N,63786,N,N,N,N,N,N,N,N,63787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63789,63788,N,N, -63790,N,N,N,N,N,N,N,31801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63792,63793,N,N,31802,N, -N,N,31803,N,N,N,N,N,31804,63795,N,N,N,N,63796,N,N,N,31806,N,N,N,N,N,N,N,N, -31807,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,63797,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63798,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,63799,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63800,N,N,N,N,N,N, -N,N,31808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63802,N,63803,N,N,N,N,N, -31809,N,N,31810,N,N,N,N,N,31811,N,63804,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -63805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63808,63809,N,N,N,N,N,63806,N,N,N,N,N,N, -N,63811,N,63812,N,N,N,N,N,N,N,N,N,31812,63813,63814,31813,N,N,N,63815,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,63818,N,N,63819,N,N,N,31814,N,N,N,N,N,N,N,N,N,N,N,N,N, -63820,N,N,N,N,N,N,N,N,63821,N,N,N,N,N,N,N,N,N,N,N,N,N,63822,N,N,N,N,N,N,N,N,N, -63823,63824,N,63825,31815,N,N,N,N,N,N,N,N,N,N,31816,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63826,N,N,N,N,N,63827,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,63828,N,N,N,N,63829,N,63830,63831,N,N,N,N,63832,N,N,N,N,31818,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,63834,N,N,63835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63837,31820,63839,N,N,N,N,N,N,N,63840,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,63841,N,N,N,N,N,N,31821,N,N,N,N,N,N,N,N,N,N,N,N,63842,N, -31822,N,N,N,N,N,N,N,N,31823,N,N,N,N,N,N,N,N,N,63843,N,N,N,N,N,N,N,N,N,63844,N, -N,N,N,N,N,N,N,N,31824,N,N,N,63845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,63847,N,31826,N,N,N,N,N,N,N,N,N,N,N,N,N,63848, -31827,63850,N,N,N,N,N,N,N,N,N,N,63852,N,N,N,N,63853,N,N,N,63855,N,N,63856,N,N, -N,N,N,63857,N,63858,N,N,N,N,N,N,N,N,N,N,63859,N,N,N,31828,N,N,N,31829,N,N,N,N, -N,31830,N,N,63860,N,N,N,63861,N,N,N,N,N,63862,63863,N,N,N,N,N,31831,N,N,N, -63864,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31832,N, -N,N,N,N,N,N,N,N,63865,N,N,N,N,N,N,N,N,N,N,N,63867,63868,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,63869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64034,N,N,31834,N,N,N,64035,N,N,N,64036,N,N,N, -N,31835,N,31836,N,31837,N,31838,N,N,N,N,N,64038,31839,N,N,N,N,N,N,N,N,N,N,N,N, -N,64040,N,N,31840,N,N,64041,N,N,N,N,N,N,N,31841,N,N,N,N,64042,31842,31843,N, -31844,64043,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31845,N,N,N,N,64045,31846,31847,64046, -N,N,N,N,N,N,N,N,N,N,N,64051,N,N,N,31848,N,N,64049,N,31849,N,64048,N,N,N,N,N,N, -N,64052,64053,64050,N,N,N,64054,N,64055,N,N,N,N,N,N,N,N,N,N,N,N,N,31851,31852, -31853,N,64056,N,N,N,64057,N,64058,N,N,N,31854,31855,N,N,N,31856,N,N,N,N,N,N,N, -31857,N,31858,N,N,31859,N,N,64059,N,64060,64061,N,N,31860,N,N,N,N,N,N,N,N, -64062,64063,31861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64064,N,64065,N,31862,N,N,N,N,N, -64066,N,N,64067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64068,N,N,N,N,64069,N,N,N,N,N,N, -N,N,N,31863,N,64070,N,N,N,N,N,N,N,N,64071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31864, -N,N,N,N,N,N,N,N,N,64072,N,N,N,31865,N,64073,N,N,31866,N,64074,N,N,64075,N,N,N, -N,N,31867,N,N,N,N,N,N,64076,64077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31868,N, -N,64078,N,N,N,N,N,N,N,N,N,31870,32033,N,N,N,N,N,N,64081,32034,64082,N,N,32035, -N,N,N,N,N,N,N,N,N,31869,64083,N,N,N,N,N,32036,N,N,64084,N,N,N,N,N,32037,N,N,N, -N,N,64085,64086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64088,N, -N,N,N,32038,32039,32040,N,32041,N,N,N,32042,N,64089,32043,N,N,N,64090,N,N, -64091,N,N,N,64092,32044,N,64093,N,N,N,N,64094,N,N,64095,N,N,N,N,N,N,64096, -64097,N,N,N,64098,N,64099,64100,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32045,N,N,N, -64103,64104,N,64105,N,N,N,N,N,N,N,N,32046,64106,N,N,N,64107,N,N,N,N,N,N,N,N,N, -64108,N,64109,N,N,N,N,N,64110,N,N,N,N,N,N,N,64111,N,N,N,64112,N,N,N,N,N,N, -64115,N,N,N,N,N,N,N,N,N,N,N,N,64116,64117,N,32047,N,N,N,64118,N,N,N,N,32048, -32049,N,64119,N,64120,N,N,32050,N,N,N,64121,N,64122,N,N,N,N,N,N,32051,N,N,N,N, -64123,N,64124,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64290,N,64291,N,64292,N,N,N,32052, -64293,N,32053,N,N,N,N,N,N,N,N,64294,N,N,N,64125,N,N,N,64295,N,N,N,N,N,N,N, -64296,64297,32054,N,32055,N,N,N,32056,N,64298,N,64299,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64302,32057,32058,32059,N,N,N,N,N,N,64303,N, -N,N,N,N,64304,N,N,64305,N,N,N,N,N,N,N,N,N,32060,32061,N,N,N,N,32062,64306,N,N, -N,N,32063,64307,N,64308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64312,N,N, -64313,N,N,N,64314,N,N,N,N,N,N,N,N,N,N,N,32064,N,N,64315,N,N,64309,N,32065,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32066,N,N,N,N,N,N,64320,N,N,N,N,32067, -64321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64322,N,32068,32069,N,N,64323,N, -N,N,N,64324,N,N,N,N,N,N,N,N,N,64319,N,N,N,64316,N,N,N,N,N,64329,N,32071,32070, -N,N,N,N,64325,N,N,N,N,N,64326,N,N,N,N,N,N,64327,64328,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,64330,32072,64331,N,N,N,N,N,N,64332,N,N,N,N,N,N,N, -N,N,64333,N,N,N,N,32073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32074, -N,N,N,N,N,N,N,32075,N,64336,N,64337,N,32076,32077,64338,64339,N,N,N,N,N,N,N,N, -N,N,N,N,64340,N,N,N,N,N,64341,64342,32078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -32079,N,N,N,N,N,N,32080,N,N,32081,N,64344,32082,N,N,N,N,N,N,N,64345,N,32083,N, -N,N,N,N,N,32084,N,N,N,N,N,N,N,N,N,N,64347,N,N,32085,N,N,N,N,32086,N,N,32087,N, -N,N,N,N,N,32089,N,N,N,32090,64037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64350,N,N,N,N,N, -N,64351,64352,N,N,N,N,N,N,N,64354,N,N,N,N,64355,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,32091,N,N,N,N,N,N,N,N,64356,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,64358,N,32092,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,64360,N,N,32094,N,N,N,N,N,N,32095,32096,N,N,N,64363,N,N,N,N,N,64364,N,N, -N,64365,N,N,N,N,N,N,64366,N,N,64367,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -32097,N,N,N,N,N,64370,N,64371,N,N,64372,32098,N,N,N,N,N,N,N,N,N,N,32100,N,N,N, -N,N,32101,64374,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64375,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,32102,N,N,64377,N,N,N,N,32103,N,N,N,N,N,64378,N,N,N,N,N,64379,N,N,N,N,N, -32104,32105,32106,N,N,N,N,N,64380,N,64381,N,N,32107,64382,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,64545,N,N,N,32108,N,N,N,N,32109,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,32110,64548,N,N,N,64549,N,N,N,64550,N,N,N,64551,N, -N,N,N,N,N,N,N,N,N,N,32111,N,N,64552,64553,N,N,N,N,N,N,N,32112,N,N,N,64554,N,N, -32113,N,N,N,N,N,N,N,32114,N,N,64555,N,N,N,N,64556,N,N,64557,N,N,N,64558,64559, -N,32116,N,N,32115,N,N,64560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64561,N,N,32117, -64562,N,N,N,N,N,32119,N,N,64563,64564,N,N,N,N,N,64565,N,64566,N,N,N,N,N,N,N, -32120,N,N,N,N,64569,N,64572,N,N,N,N,N,32121,N,N,N,N,32122,N,64570,64571,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64573,N,N,N,N,N,N,N,N,N,N,32124,32125,N,N, -32126,32289,N,32290,32291,N,N,N,N,N,N,N,N,N,N,32293,64574,N,N,N,N,N,32294,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64575,N,64576,N,N,64577,N,N,N,N,N,N, -64579,64580,N,32295,64581,64582,N,N,64583,N,N,64584,N,N,N,N,64585,32296,N,N, -64586,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64587,64589,N,64590,N,64591,N, -32297,N,N,64592,N,N,N,N,N,64593,64594,N,64595,64596,N,N,N,N,N,N,N,N,N,N,N,N,N, -64599,64600,N,N,64602,64603,64604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64606,64607,64608,N,N,N,N,N,N,64609,64610,64611,N,N,N,64612,64613,N,N,N,N, -64614,N,N,N,N,N,N,64615,64616,N,N,N,N,N,N,N,N,N,32298,N,N,N,64617,N,N,64618, -64619,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32299,N,N,N,N,64620,N,N, -64621,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64622,N,N,N,64623,N,64624,N,N,N, -64625,N,N,N,N,N,64626,N,N,N,N,N,N,N,N,N,N,64627,N,N,N,N,64628,N,N,N,N,64629,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64631,N,N,N,N,N,N,N,N,64632,N,N,64633,32300, -32301,N,N,N,N,N,N,64634,N,N,N,N,N,N,64635,N,N,N,N,64636,N,N,N,64637,N,N,N,N,N, -64638,N,N,N,32302,N,N,N,N,N,N,N,N,32303,32304,N,N,64801,N,N,N,N,64802,N,32305, -N,N,N,N,N,N,N,N,N,N,N,64803,N,N,N,N,N,32306,N,64804,N,32307,N,N,N,32308,N,N,N, -N,N,64805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,64807,N,N,N,N,N,N,32309,64809,N,64811,N,N,N,N,N,N,N, -32310,N,32311,N,N,64813,N,N,N,N,N,N,N,32312,N,64814,N,64815,N,N,64816,32313,N, -N,N,N,N,64818,N,N,N,64819,N,N,N,N,64820,N,N,N,64821,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,32314,32315,64822,N,N,N,N,32316,N,N,N,64823,N,N,N,64824,N,64825,N,N,N, -64826,N,N,N,N,N,64827,N,N,N,32317,N,N,N,N,N,N,N,N,N,N,64828,N,32319,N,N,N,N,N, -64829,N,N,N,N,N,N,N,N,N,64830,N,N,N,N,N,N,N,N,N,N,N,N,N,64832,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,32320,N,N,N,N,64833,N,64834,32322,N,N,N,N,64835,64836,N,N, -N,N,N,32323,64837,N,32324,64838,64839,N,32321,N,N,N,N,N,N,N,N,N,N,32325,N,N,N, -N,N,32326,N,N,N,N,32327,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32328,N,N,N,N,N,N,N,64840, -32329,N,N,N,N,64841,N,N,N,N,64842,64845,N,N,N,N,N,64846,N,N,N,N,N,64847,N,N, -32330,N,N,N,N,N,64848,N,N,N,N,N,N,32331,N,N,N,N,N,N,N,N,N,64850,N,N,N,N,64851, -N,N,N,N,N,N,N,32332,N,64852,N,N,64853,64854,N,N,64856,64855,N,N,N,64849,N,N,N, -64860,32333,N,64858,N,N,32334,32335,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64862,N,64863,64864,64865,N,N,64866,N,N,N,N,64867,32336,N,N,N,64868,N,64869, -64870,N,N,N,N,N,N,64872,N,N,N,N,64873,64874,N,N,N,N,N,N,N,N,N,32337,N,N,N, -64875,N,N,N,64878,64879,N,N,N,N,32338,32339,N,N,32340,64881,N,N,N,64882,N,N, -64883,64876,64884,N,64885,N,N,N,32341,N,32342,N,N,N,64886,64887,64888,N,64889, -64890,N,64891,N,64892,N,N,64893,N,32343,N,N,64894,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65057,N,N,N,N,N,N,N,N,N,N,N,65058,65060,N,N,N,N, -N,N,N,N,65059,N,N,N,N,N,65062,N,N,N,N,N,65063,65064,N,N,N,N,32344,32345,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65070, -32346,N,N,N,32347,N,N,65071,N,N,N,N,N,N,N,32348,N,N,N,N,N,N,N,N,N,N,N,N,65072, -N,N,65073,32349,N,N,N,N,N,65075,N,65076,N,N,N,N,32350,N,N,65078,N,N,65079, -65080,N,N,N,N,32351,N,65081,N,N,N,N,N,65082,N,N,N,N,N,32352,N,N,65083,N,N,N,N, -N,N,N,N,32353,N,N,65084,N,N,N,N,N,N,N,65085,N,N,N,N,N,N,N,N,N,N,32355,N,N,N,N, -N,N,N,N,65087,N,N,N,65088,N,N,32356,65089,N,65086,32354,N,N,65090,N,N,N,65091, -N,65092,N,N,N,N,N,N,N,N,N,N,N,N,65093,32357,N,N,65094,N,N,N,N,65095,65096,N,N, -65097,N,N,N,32359,N,N,N,N,N,N,N,N,N,N,N,N,65098,65101,N,N,N,N,32360,N,N,65100, -N,N,65102,N,N,N,N,N,N,N,32361,N,N,N,65103,N,N,65104,65105,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,65106,32362,N,N,N,65108,N,N,N,N,65109,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,65110,N,N,32363,N,N,N,N,N,32364,N,N,N,65111,N,N,N,32365,N,N,32366, -N,N,N,N,32367,32368,N,N,N,N,N,N,N,65113,N,N,N,N,N,32369,N,N,N,N,N,N,N,N,N,N,N, -N,N,32370,N,N,N,N,N,N,N,N,N,N,N,N,N,65115,N,N,N,N,N,N,N,65116,N,N,N,N,N,N, -65117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65118,65119,65121,N,N,N,N,N,N,N,N,N,N,N, -N,32371,N,N,N,N,N,N,65122,N,65123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -65124,N,N,N,N,N,N,N,65125,N,32372,65126,N,N,65127,N,N,N,65128,N,N,N,65129, -65130,N,N,N,N,N,N,N,N,N,N,N,N,65131,N,65132,N,32373,65133,N,N,N,N,65135,N,N,N, -N,N,N,N,N,N,N,N,65137,N,N,N,65139,N,N,65140,N,N,N,N,65141,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32374,N,N,N,32375,N,N,32376,N,N,N,N,N,N,N,N,N, -N,32377,30267,N,N,N,N,N,N,N,N,N,N,29742,30030,N,N,N,N,N,N,N,N,N,N,N,N,31567,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -32292,N,N,N,N,N,N,N,N,N,N,N,32093,12107,12119,20338,N,44665,30074,30554,30575, -N,N,31036,31037,31041,N,N,N,31546,63288,63301,31790,N,63854,N,31850,N,N,N,N,N, -N,N,N,N,11832,11849,11856,11875,11880,11886,12076,12079,12086,12122,12126, -20321,20322,29776,29788,29790,29793,29992,29995,30019,30053,30313,30327,30501, -30549,61481,30757,31015,31027,31028,31031,31032,31033,31035,31039,31040,31053, -31057,31076,31278,62544,31283,31290,31300,31320,62836,62837,31527,31599,31609, -31791,31792,31800,31805,63849,31833,32099,32118,32123,9022,9021,8752,N,N,N,N, -8751,N,N,N,N,N,8753, -}; - -static const struct unim_index jisx0213_bmp_encmap[256] = { -{__jisx0213_bmp_encmap+0,126,255},{__jisx0213_bmp_encmap+130,0,253},{ -__jisx0213_bmp_encmap+384,80,233},{__jisx0213_bmp_encmap+538,0,194},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+733,62,63 -},{__jisx0213_bmp_encmap+735,112,115},{__jisx0213_bmp_encmap+739,19,172},{ -__jisx0213_bmp_encmap+893,15,233},{__jisx0213_bmp_encmap+1112,5,219},{ -__jisx0213_bmp_encmap+1327,5,206},{__jisx0213_bmp_encmap+1529,35,254},{ -__jisx0213_bmp_encmap+1749,177,230},{__jisx0213_bmp_encmap+1803,0,110},{ -__jisx0213_bmp_encmap+1914,19,127},{0,0,0},{__jisx0213_bmp_encmap+2023,52,251 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+2223, -22,255},{__jisx0213_bmp_encmap+2457,240,255},{__jisx0213_bmp_encmap+2473,49, -250},{__jisx0213_bmp_encmap+2675,3,205},{__jisx0213_bmp_encmap+2878,2,219},{ -__jisx0213_bmp_encmap+3096,31,244},{__jisx0213_bmp_encmap+3310,5,207},{ -__jisx0213_bmp_encmap+3513,97,253},{__jisx0213_bmp_encmap+3670,0,250},{ -__jisx0213_bmp_encmap+3921,23,111},{__jisx0213_bmp_encmap+4010,110,234},{ -__jisx0213_bmp_encmap+4135,14,240},{__jisx0213_bmp_encmap+4362,15,210},{ -__jisx0213_bmp_encmap+4558,17,212},{__jisx0213_bmp_encmap+4754,5,148},{ -__jisx0213_bmp_encmap+4898,87,215},{__jisx0213_bmp_encmap+5027,57,147},{ -__jisx0213_bmp_encmap+5118,5,243},{__jisx0213_bmp_encmap+5357,7,221},{ -__jisx0213_bmp_encmap+5572,2,240},{__jisx0213_bmp_encmap+5811,8,212},{ -__jisx0213_bmp_encmap+6016,8,234},{__jisx0213_bmp_encmap+6243,15,175},{ -__jisx0213_bmp_encmap+6404,12,253},{__jisx0213_bmp_encmap+6646,22,181},{ -__jisx0213_bmp_encmap+6806,176,250},{__jisx0213_bmp_encmap+6881,4,188},{ -__jisx0213_bmp_encmap+7066,59,232},{__jisx0213_bmp_encmap+7240,23,209},{ -__jisx0213_bmp_encmap+7427,7,119},{__jisx0213_bmp_encmap+7540,2,255},{ -__jisx0213_bmp_encmap+7794,0,242},{__jisx0213_bmp_encmap+8037,0,243},{ -__jisx0213_bmp_encmap+8281,3,244},{__jisx0213_bmp_encmap+8523,1,251},{ -__jisx0213_bmp_encmap+8774,0,245},{__jisx0213_bmp_encmap+9020,18,255},{ -__jisx0213_bmp_encmap+9258,0,233},{__jisx0213_bmp_encmap+9492,7,247},{ -__jisx0213_bmp_encmap+9733,10,255},{__jisx0213_bmp_encmap+9979,4,244},{ -__jisx0213_bmp_encmap+10220,5,248},{__jisx0213_bmp_encmap+10464,12,245},{ -__jisx0213_bmp_encmap+10698,0,253},{__jisx0213_bmp_encmap+10952,3,244},{ -__jisx0213_bmp_encmap+11194,6,233},{__jisx0213_bmp_encmap+11422,0,253},{ -__jisx0213_bmp_encmap+11676,0,252},{__jisx0213_bmp_encmap+11929,13,248},{ -__jisx0213_bmp_encmap+12165,16,245},{__jisx0213_bmp_encmap+12395,21,253},{ -__jisx0213_bmp_encmap+12628,3,247},{__jisx0213_bmp_encmap+12873,9,255},{ -__jisx0213_bmp_encmap+13120,4,252},{__jisx0213_bmp_encmap+13369,0,251},{ -__jisx0213_bmp_encmap+13621,1,252},{__jisx0213_bmp_encmap+13873,1,252},{ -__jisx0213_bmp_encmap+14125,3,254},{__jisx0213_bmp_encmap+14377,15,253},{ -__jisx0213_bmp_encmap+14616,11,255},{__jisx0213_bmp_encmap+14861,2,251},{ -__jisx0213_bmp_encmap+15111,0,252},{__jisx0213_bmp_encmap+15364,23,251},{ -__jisx0213_bmp_encmap+15593,10,252},{__jisx0213_bmp_encmap+15836,0,236},{ -__jisx0213_bmp_encmap+16073,3,254},{__jisx0213_bmp_encmap+16325,0,251},{ -__jisx0213_bmp_encmap+16577,7,250},{__jisx0213_bmp_encmap+16821,1,255},{ -__jisx0213_bmp_encmap+17076,1,249},{__jisx0213_bmp_encmap+17325,0,252},{ -__jisx0213_bmp_encmap+17578,10,251},{__jisx0213_bmp_encmap+17820,5,254},{ -__jisx0213_bmp_encmap+18070,0,237},{__jisx0213_bmp_encmap+18308,3,253},{ -__jisx0213_bmp_encmap+18559,7,240},{__jisx0213_bmp_encmap+18793,1,245},{ -__jisx0213_bmp_encmap+19038,3,249},{__jisx0213_bmp_encmap+19285,8,154},{ -__jisx0213_bmp_encmap+19432,59,250},{__jisx0213_bmp_encmap+19624,2,251},{ -__jisx0213_bmp_encmap+19874,13,255},{__jisx0213_bmp_encmap+20117,4,254},{ -__jisx0213_bmp_encmap+20368,0,249},{__jisx0213_bmp_encmap+20618,1,253},{ -__jisx0213_bmp_encmap+20871,12,255},{__jisx0213_bmp_encmap+21115,0,253},{ -__jisx0213_bmp_encmap+21369,5,245},{__jisx0213_bmp_encmap+21610,1,245},{ -__jisx0213_bmp_encmap+21855,1,255},{__jisx0213_bmp_encmap+22110,17,252},{ -__jisx0213_bmp_encmap+22346,5,158},{__jisx0213_bmp_encmap+22500,57,254},{ -__jisx0213_bmp_encmap+22698,9,253},{__jisx0213_bmp_encmap+22943,6,250},{ -__jisx0213_bmp_encmap+23188,0,251},{__jisx0213_bmp_encmap+23440,2,255},{ -__jisx0213_bmp_encmap+23694,0,251},{__jisx0213_bmp_encmap+23946,1,255},{ -__jisx0213_bmp_encmap+24201,2,253},{__jisx0213_bmp_encmap+24453,4,114},{ -__jisx0213_bmp_encmap+24564,120,222},{__jisx0213_bmp_encmap+24667,29,239},{ -__jisx0213_bmp_encmap+24878,20,244},{__jisx0213_bmp_encmap+25103,4,243},{ -__jisx0213_bmp_encmap+25343,8,252},{__jisx0213_bmp_encmap+25588,2,249},{ -__jisx0213_bmp_encmap+25836,2,253},{__jisx0213_bmp_encmap+26088,0,242},{ -__jisx0213_bmp_encmap+26331,2,244},{__jisx0213_bmp_encmap+26574,2,255},{ -__jisx0213_bmp_encmap+26828,2,162},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+26989 -,29,220},{__jisx0213_bmp_encmap+27181,15,106},{0,0,0},{0,0,0},{0,0,0},{ -__jisx0213_bmp_encmap+27273,69,70},{__jisx0213_bmp_encmap+27275,2,13}, -}; - -static const ucs2_t __jisx0213_1_emp_decmap[340] = { -11,4669,U,U,U,U,U,U,U,U,U,4891,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5230,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,6333,2975,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,5812,U,U,U,U,U,U,U,U,U,U,7732,12740,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -13764,14143,U,U,U,U,U,U,U,U,14179,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15614,18417,21646,21774,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22385,U,U,U,U,U,U,U,U,U,U,U, -U,22980,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23969,27391,28224,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28916,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30340,33399,U,U,U,U,U,U,U,33741,41360, -}; - -static const struct dbcs_index jisx0213_1_emp_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__jisx0213_1_emp_decmap+0,34,34},{__jisx0213_1_emp_decmap+1,66,123},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{__jisx0213_1_emp_decmap+59,84,110},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_emp_decmap+86,58,114},{ -__jisx0213_1_emp_decmap+143,41,96},{__jisx0213_1_emp_decmap+199,108,108},{ -__jisx0213_1_emp_decmap+200,126,126},{__jisx0213_1_emp_decmap+201,41,110},{ -__jisx0213_1_emp_decmap+271,93,93},{__jisx0213_1_emp_decmap+272,51,108},{ -__jisx0213_1_emp_decmap+330,73,81},{0,0,0},{__jisx0213_1_emp_decmap+339,102, -102},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const ucs2_t __jisx0213_2_emp_decmap[2053] = { -137,U,U,U,U,U,U,U,U,U,162,U,U,164,U,U,U,U,U,U,U,418,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,531,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,811,U,U,U,U,U,U,897,U,881,1017,U,U,1098,U,1289,U,U,U,U,U,U,U,U,U, -1494,1576,U,U,U,U,U,1871,U,U,U,U,U,U,2055,U,2106,U,U,U,U,U,U,U,U,2233,U,U,U,U, -U,U,U,2428,2461,U,U,U,U,U,2771,U,U,2845,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,3397,3553,U,U,U,U,U,U,3733,3693,U,U,U,U,U,U,U,3684,U,U,3935,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,4609,U,U,4693,U,4731,U,U,U, -U,4724,U,U,U,U,U,U,4836,4823,U,U,U,U,U,U,4861,U,4918,4932,5060,U,U,U,U,U,U,U, -U,U,U,U,U,5229,U,U,U,U,U,U,U,U,U,U,U,5591,U,U,U,U,U,27689,U,U,5703,U,U,U,U,U, -U,U,U,U,U,U,U,U,5894,5954,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,6595,7254,U,U,U,U,U,U,7469,7493,U,7544,7522,U,U,U, -7585,7580,U,U,U,U,7570,U,U,7607,U,7648,7731,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -7966,U,U,U,U,U,U,U,U,U,U,8054,U,U,U,U,U,8186,8571,U,U,U,U,U,U,U,U,8990,U,U,U, -U,9133,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,9971,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,10331,U,U,U,U,U,U,U,10411,U,U,U,U,10639, -10936,U,U,U,U,11087,11088,U,U,U,U,U,U,U,11078,U,11293,11174,U,U,U,11300,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,11745,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12739,12789,12726,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13170,U,13267,13266,U,U,U,U,13264,13284, -13269,U,U,13274,U,13279,U,U,U,U,U,U,U,U,U,U,U,13386,13393,13387,U,U,U,13413,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13540,13658,13716,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13881,13895,U,13880,13882,U,U,U,U,U,U,U,U,U,U, -14108,U,U,U,U,U,U,U,U,U,U,14092,U,U,U,U,U,U,U,14180,U,U,U,U,U,U,U,14335,14311, -U,U,U,U,U,14372,U,U,U,U,14397,15000,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15487,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15616,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -15680,U,15866,15865,15827,16254,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,16534, -U,U,U,U,U,16643,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,16838,U,U,16894,17340,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,17961,U,U,U,U,U,18085,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,18582,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19021,19286,U,19311,U,U,U,U,19478,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,19732,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19982,U,U, -U,20023,U,U,U,U,20074,U,U,20107,U,U,U,U,U,U,U,U,U,U,U,20554,U,20565,U,U,20770, -20905,U,20965,20941,U,U,U,21022,U,U,U,21068,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -21550,U,U,U,U,U,U,U,U,U,U,21721,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21927,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22441,22452,22996,U,U,U,U,U,U,U, -U,U,U,23268,23267,U,23281,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23474,U,U,U,U,U,U, -U,U,U,U,23627,23652,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24110,24150,24165, -U,24162,U,U,U,24280,U,24258,24296,U,24355,U,U,24412,U,U,U,U,U,U,24544,24532,U, -U,U,U,24588,24571,U,U,U,U,U,U,U,24599,U,U,U,U,24672,U,U,U,U,U,U,U,U,U,U,U,U, -24813,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25200,U,25222,U,U,U,U, -U,U,25420,U,U,15630,U,U,U,25602,26238,U,U,U,U,26288,U,U,U,U,U,U,U,U,U,U,U, -26397,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26845,U,26858,U,26961,U,U,26991,U,27101,U, -U,U,27166,U,U,U,U,U,U,27224,U,U,U,U,U,27276,U,U,27319,27763,U,U,U,U,U,U,U,U,U, -27869,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28261,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,28564,U,U,U,U,U,U,U,U,28664,28662,28663,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,28941,U,U,28985,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29659,29658,U,U,U,U,U,29694,U,U,29712,U,U,U,U, -29769,30229,30228,U,30257,U,U,U,U,U,U,U,30355,U,U,U,U,U,U,U,30478,U,30499,U,U, -U,30546,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31109,U,U,U,U,U,U,U,U,U,U,U,U, -31364,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31667,U,31678,31687,31928,U,U,U,U, -U,U,U,U,U,32160,U,U,32272,U,U,U,U,U,U,32695,U,U,U,U,U,U,U,U,32906,U,U,U,U,U, -32955,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33410,U,U,U,U,33523,U,U,U,U,U,U,U,33804, -U,U,U,U,33877,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34155,U,U,U,34248,34249,U,U,U,U,U,U, -U,U,U,U,34519,U,U,34554,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,35145,35142,U,U,U,U,U,U,35179,U,U,U,U,U,U,U,U,U,U,U,U,U,35207,35208,U, -U,U,U,U,U,U,U,U,U,35258,35259,U,U,U,U,U,U,U,U,U,U,U,35358,35369,U,U,U,U,U,U,U, -U,U,U,35441,35395,U,U,U,U,U,U,U,U,35481,35533,U,U,U,U,U,35556,35549,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,35777,35823,U,U,U,U,U,U,U,36112,U,U,36209,U,36347,36383,U, -U,U,36406,U,U,U,36489,U,36587,U,36658,U,U,U,U,U,U,U,36856,37536,37553,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38032,U,U,U,U,U,U,U,U,U,38351,U,U,U,U,U,U,U,U, -U,38527,U,U,U,U,U,U,U,U,U,38640,U,U,38681,U,U,U,38736,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,39110,39538,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,40411,40509,U,U,U,U,U,U,U,U,U,U,U,U,40469,U,40586,U,40521,U, -U,U,U,U,U,U,U,U,40644,U,U,U,U,U,40681,U,U,40667,40910,U,U,U,41007,U,40986,U,U, -U,U,U,U,41209,U,U,41090,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,8728,U,U,U,U,41868,U,42039,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,42481,U, -42498,U,42522,U,U,U,42674, -}; - -static const struct dbcs_index jisx0213_2_emp_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+0,33,121},{0,0,0},{ -__jisx0213_2_emp_decmap+89,34,119},{__jisx0213_2_emp_decmap+175,42,117},{ -__jisx0213_2_emp_decmap+251,37,126},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+ -341,48,108},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+402,34,114},{ -__jisx0213_2_emp_decmap+483,36,125},{__jisx0213_2_emp_decmap+573,35,120},{ -__jisx0213_2_emp_decmap+659,42,117},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -__jisx0213_2_emp_decmap+735,35,96},{__jisx0213_2_emp_decmap+797,50,100},{ -__jisx0213_2_emp_decmap+848,34,123},{__jisx0213_2_emp_decmap+938,46,122},{ -__jisx0213_2_emp_decmap+1015,33,118},{__jisx0213_2_emp_decmap+1101,50,125},{ -__jisx0213_2_emp_decmap+1177,34,121},{__jisx0213_2_emp_decmap+1265,53,115},{ -__jisx0213_2_emp_decmap+1328,68,126},{__jisx0213_2_emp_decmap+1387,33,115},{ -__jisx0213_2_emp_decmap+1470,41,122},{__jisx0213_2_emp_decmap+1552,37,126},{ -__jisx0213_2_emp_decmap+1642,33,126},{__jisx0213_2_emp_decmap+1736,33,113},{ -__jisx0213_2_emp_decmap+1817,34,118},{__jisx0213_2_emp_decmap+1902,44,112},{ -__jisx0213_2_emp_decmap+1971,37,118},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const DBCHAR __jisx0213_emp_encmap[8787] = { -11810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,41249,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -41259,N,41262,41270,41286,41328,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,41337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41335,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41762,41765,41767, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,41777,41778,41784,41791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41793,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,41802,41810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,41811,41817,41820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20308,41847,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42026,42042,N,N,N, -N,N,N,N,N,42034,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,42033,42045,42073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -12098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42076,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42083,N,N,N,N,N,N,42078,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,42091,N,N,N,N,N,N,N,N,N,N,N,N,42090,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,42098,12108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,42100,N,N,N,N,N,N,N,N,N,N,N,N,N,42101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42277,42290, -12128,42302,42311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -20323,42325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42326,12155,42366,43056, -43063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43064,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,43066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43077,N,N,N,N,N, -N,N,N,N,43072,N,N,N,N,43071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43080,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -43082,43083,20334,43099,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43110,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -43116,44066,65107,44075,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -44080,44112,44133,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,44141,44146,44324,44338,N,N,N,N,N,N,N,N,44329,44330,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,44341,44340,N,N,N,N,N,N,44345,44374,44580,N,N,N,N,N,N,N,N,N,N,N,N, -44413,30010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44579,44602,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44610, -N,44605,44604,N,44612,N,N,N,N,44615,N,N,N,N,44617,N,N,N,N,44611,44629,44631,N, -N,N,N,N,44630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44635,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -44663,44664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44842,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30066, -44866,44863,44867,N,N,N,N,N,N,N,N,N,N,N,N,44864,44889,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,44878,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,30249,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -30258,44897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44906,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,44905,44912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44917, -60963,60980,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30304,61001,N,N,N,N,N,N,N,N,N,N,N,N,N,62581,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,61020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,61024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,61023,61022,61234,61255,61261,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61284, -61474,61491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,61497,30572,61523,61563,61742,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,61744,61749,61764,61789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61793,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -61798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61801, -61813,N,N,N,N,N,N,N,N,N,N,61815,61818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61985, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61988,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61987,61992,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61996, -62013,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62024,31017,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62043,31047,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,62069,N,N,N,N,N,N,N,N,N,N,62070,31060,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -62258,62270,62269,N,N,N,N,N,N,N,N,N,N,N,N,62272,62290,62301,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62302,31086,62323,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62324,N,N,N,N,N,N,N,N,N,N,N, -62327,N,N,62325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62333,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,62331,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62498,62500,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,62503,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,62511,N,N,N,N,N,N,N,N,N,N,N,62510,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62517,62516,N,N,N,N,N,N,N,N,N,N,62525,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62530,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62543,62569,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,62571,62578,62585,62773,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62778,62790,62806,N,N, -N,N,N,N,N,N,N,N,N,N,62808,62810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,62813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,62815,62819,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62826,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,62832,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,62835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,31325,42308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,63044,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63054, -31539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -63069,63093,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63265,63266,63102,31561, -63283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,63286,63333,63332,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,63339,63342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63347, -63530,63529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63532,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,31596,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63540,63548,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,63550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63554,63574,63587,63607,N,N,N,N,N,N,N,N,N,N, -63609,N,N,N,N,N,N,N,N,63610,63781,63791,63794,63801,63810,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -63816,31817,N,N,N,N,N,N,N,N,N,N,63833,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,63838,31825,63846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63851,63866,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -63870,64033,64044,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,64047,64080,N,N,64079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,64087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64101,64102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64113,64114,64126,N,N,N,N,N,N,N,N,N,N,64289,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64301,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64300,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64310, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,64311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64318,N,N,N,N,N,N, -64317,64334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,64335,64343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64346, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64348,64349,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,64353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64357,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64359,64361,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,64369,64546,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64547,64568,64578, -64588,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64598,64601,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64605,64630,64812,64843,64857,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64844, -N,N,N,N,N,N,N,N,N,N,N,64861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -64859,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,64880,N,N,N,N,N,N,N,N,N,N,N,N,N,64877,65061,65067,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,65065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65074,32358,65112,65114,65134, -65136,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65138,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65142, -}; - -static const struct unim_index jisx0213_emp_encmap[256] = { -{__jisx0213_emp_encmap+0,11,164},{__jisx0213_emp_encmap+154,162,162},{ -__jisx0213_emp_encmap+155,19,19},{__jisx0213_emp_encmap+156,43,249},{ -__jisx0213_emp_encmap+363,74,74},{__jisx0213_emp_encmap+364,9,214},{ -__jisx0213_emp_encmap+570,40,40},{__jisx0213_emp_encmap+571,79,79},{ -__jisx0213_emp_encmap+572,7,185},{__jisx0213_emp_encmap+751,124,157},{ -__jisx0213_emp_encmap+785,211,211},{__jisx0213_emp_encmap+786,29,159},{0,0,0}, -{__jisx0213_emp_encmap+917,69,225},{__jisx0213_emp_encmap+1074,100,149},{ -__jisx0213_emp_encmap+1124,95,95},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+1125, -1,253},{__jisx0213_emp_encmap+1378,27,196},{__jisx0213_emp_encmap+1548,109,110 -},{__jisx0213_emp_encmap+1550,215,215},{__jisx0213_emp_encmap+1551,71,180},{ -__jisx0213_emp_encmap+1661,6,66},{__jisx0213_emp_encmap+1722,189,189},{ -__jisx0213_emp_encmap+1723,195,195},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+ -1724,86,86},{__jisx0213_emp_encmap+1725,45,224},{__jisx0213_emp_encmap+1905, -51,52},{__jisx0213_emp_encmap+1907,30,250},{0,0,0},{__jisx0213_emp_encmap+2128 -,123,123},{__jisx0213_emp_encmap+2129,24,24},{__jisx0213_emp_encmap+2130,30, -173},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+2274,243,243},{0,0,0},{ -__jisx0213_emp_encmap+2275,91,171},{__jisx0213_emp_encmap+2356,143,143},{ -__jisx0213_emp_encmap+2357,184,184},{__jisx0213_emp_encmap+2358,70,166},{ -__jisx0213_emp_encmap+2455,29,36},{__jisx0213_emp_encmap+2463,225,225},{0,0,0 -},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+2464,182,245},{0,0,0},{ -__jisx0213_emp_encmap+2528,114,228},{__jisx0213_emp_encmap+2643,74,228},{ -__jisx0213_emp_encmap+2798,90,196},{__jisx0213_emp_encmap+2905,56,71},{ -__jisx0213_emp_encmap+2921,12,255},{__jisx0213_emp_encmap+3165,36,61},{0,0,0}, -{__jisx0213_emp_encmap+3191,152,152},{0,0,0},{__jisx0213_emp_encmap+3192,127, -254},{__jisx0213_emp_encmap+3320,0,250},{0,0,0},{__jisx0213_emp_encmap+3571, -126,126},{__jisx0213_emp_encmap+3572,150,150},{__jisx0213_emp_encmap+3573,3, -254},{0,0,0},{__jisx0213_emp_encmap+3825,188,188},{0,0,0},{0,0,0},{ -__jisx0213_emp_encmap+3826,41,165},{__jisx0213_emp_encmap+3951,241,241},{ -__jisx0213_emp_encmap+3952,150,150},{0,0,0},{__jisx0213_emp_encmap+3953,77,77 -},{__jisx0213_emp_encmap+3954,86,111},{__jisx0213_emp_encmap+3980,22,22},{ -__jisx0213_emp_encmap+3981,20,20},{__jisx0213_emp_encmap+3982,14,139},{0,0,0}, -{__jisx0213_emp_encmap+4108,74,85},{__jisx0213_emp_encmap+4120,34,229},{ -__jisx0213_emp_encmap+4316,30,76},{0,0,0},{__jisx0213_emp_encmap+4363,46,217}, -{__jisx0213_emp_encmap+4535,14,167},{0,0,0},{__jisx0213_emp_encmap+4689,113, -180},{0,0,0},{__jisx0213_emp_encmap+4757,196,212},{__jisx0213_emp_encmap+4774, -227,241},{__jisx0213_emp_encmap+4789,178,178},{__jisx0213_emp_encmap+4790,75, -100},{__jisx0213_emp_encmap+4816,161,161},{__jisx0213_emp_encmap+4817,46,232}, -{__jisx0213_emp_encmap+5004,35,251},{__jisx0213_emp_encmap+5221,12,237},{0,0,0 -},{__jisx0213_emp_encmap+5447,112,134},{__jisx0213_emp_encmap+5470,76,76},{ -__jisx0213_emp_encmap+5471,2,2},{0,0,0},{__jisx0213_emp_encmap+5472,126,176},{ -__jisx0213_emp_encmap+5523,29,29},{__jisx0213_emp_encmap+5524,221,234},{ -__jisx0213_emp_encmap+5538,81,221},{__jisx0213_emp_encmap+5679,30,255},{0,0,0 -},{__jisx0213_emp_encmap+5905,41,221},{0,0,0},{__jisx0213_emp_encmap+6086,64, -101},{__jisx0213_emp_encmap+6124,148,248},{__jisx0213_emp_encmap+6225,244,244 -},{__jisx0213_emp_encmap+6226,13,57},{0,0,0},{__jisx0213_emp_encmap+6271,218, -254},{__jisx0213_emp_encmap+6308,16,73},{0,0,0},{__jisx0213_emp_encmap+6366, -20,147},{__jisx0213_emp_encmap+6494,14,82},{0,0,0},{__jisx0213_emp_encmap+6563 -,133,133},{__jisx0213_emp_encmap+6564,132,132},{__jisx0213_emp_encmap+6565, -179,199},{__jisx0213_emp_encmap+6586,184,184},{__jisx0213_emp_encmap+6587,160, -160},{__jisx0213_emp_encmap+6588,16,16},{__jisx0213_emp_encmap+6589,183,183},{ -__jisx0213_emp_encmap+6590,138,187},{0,0,0},{__jisx0213_emp_encmap+6640,119, -243},{__jisx0213_emp_encmap+6765,205,205},{__jisx0213_emp_encmap+6766,12,85},{ -__jisx0213_emp_encmap+6840,107,201},{__jisx0213_emp_encmap+6935,215,250},{0,0, -0},{0,0,0},{__jisx0213_emp_encmap+6971,70,187},{__jisx0213_emp_encmap+7089,30, -228},{__jisx0213_emp_encmap+7288,193,239},{0,0,0},{__jisx0213_emp_encmap+7335, -16,251},{__jisx0213_emp_encmap+7571,31,235},{__jisx0213_emp_encmap+7776,50,248 -},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+7975,160,177},{0,0,0},{ -__jisx0213_emp_encmap+7993,144,144},{__jisx0213_emp_encmap+7994,207,207},{ -__jisx0213_emp_encmap+7995,127,240},{__jisx0213_emp_encmap+8109,25,80},{ -__jisx0213_emp_encmap+8165,198,198},{0,0,0},{__jisx0213_emp_encmap+8166,114, -114},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+8167,219,219},{ -__jisx0213_emp_encmap+8168,21,233},{__jisx0213_emp_encmap+8381,206,206},{ -__jisx0213_emp_encmap+8382,26,249},{__jisx0213_emp_encmap+8606,144,144},{0,0,0 -},{__jisx0213_emp_encmap+8607,140,140},{__jisx0213_emp_encmap+8608,55,55},{ -__jisx0213_emp_encmap+8609,241,241},{__jisx0213_emp_encmap+8610,2,178},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0}, -}; - +static const ucs2_t __jisx0208_decmap[6956] = { +12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180, +65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294, +12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221, +65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300, +12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310, +8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285, +65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651, +9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,U,U,U,U,U,U,U,U,U,U,U, +8712,8715,8838,8839,8834,8835,8746,8745,U,U,U,U,U,U,U,U,8743,8744,172,8658, +8660,8704,8707,U,U,U,U,U,U,U,U,U,U,U,8736,8869,8978,8706,8711,8801,8786,8810, +8811,8730,8765,8733,8757,8747,8748,U,U,U,U,U,U,U,8491,8240,9839,9837,9834, +8224,8225,182,U,U,U,U,9711,65296,65297,65298,65299,65300,65301,65302,65303, +65304,65305,U,U,U,U,U,U,U,65313,65314,65315,65316,65317,65318,65319,65320, +65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333, +65334,65335,65336,65337,65338,U,U,U,U,U,U,65345,65346,65347,65348,65349,65350, +65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363, +65364,65365,65366,65367,65368,65369,65370,12353,12354,12355,12356,12357,12358, +12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371, +12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384, +12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397, +12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410, +12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423, +12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,12449, +12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462, +12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475, +12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488, +12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501, +12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514, +12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527, +12528,12529,12530,12531,12532,12533,12534,913,914,915,916,917,918,919,920,921, +922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,U,U,U,U,U,U,U,U, +945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964, +965,966,967,968,969,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049, +1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064, +1065,1066,1067,1068,1069,1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,1073, +1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087, +1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102, +1103,9472,9474,9484,9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487, +9491,9499,9495,9507,9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520, +9509,9528,9538,20124,21782,23043,38463,21696,24859,25384,23030,36898,33909, +33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,26017,25201, +23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,24245,25353, +26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,22839,22996, +23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,32173,32239, +32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,37057,30959, +19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,21729,22240, +23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,21491,23431, +28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,22040,21764, +27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,38642,33615, +39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,29787,30408, +31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,35585,36234, +38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,25588,27839, +28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,37467,40219, +22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,27178,27431, +27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,23627,25014, +33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,21270,20206, +20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,31185,26247, +26524,26550,27468,27827,28779,29634,31117,31166,31292,31623,33457,33499,33540, +33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,20420,23784, +25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,20250,35299, +22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,25913,39745, +26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,35997,20977, +21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,35442,37799, +39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,24275,25313, +25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,37101,38307, +38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,26806,39949, +28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,19988,39993, +21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,40232,26658, +33541,33841,31909,21000,33477,29926,20094,20355,20896,23506,21002,21208,21223, +24059,21914,22570,23014,23436,23448,23515,24178,24185,24739,24863,24931,25022, +25563,25954,26577,26707,26874,27454,27475,27735,28450,28567,28485,29872,29976, +30435,30475,31487,31649,31777,32233,32566,32752,32925,33382,33694,35251,35532, +36011,36996,37969,38291,38289,38306,38501,38867,39208,33304,20024,21547,23736, +24012,29609,30284,30524,23721,32747,36107,38593,38929,38996,39000,20225,20238, +21361,21916,22120,22522,22855,23305,23492,23696,24076,24190,24524,25582,26426, +26071,26082,26399,26827,26820,27231,24112,27589,27671,27773,30079,31048,23395, +31232,32000,24509,35215,35352,36020,36215,36556,36637,39138,39438,39740,20096, +20605,20736,22931,23452,25135,25216,25836,27450,29344,30097,31047,32681,34811, +35516,35696,25516,33738,38816,21513,21507,21931,26708,27224,35440,30759,26485, +40653,21364,23458,33050,34384,36870,19992,20037,20167,20241,21450,21560,23470, +24339,24613,25937,26429,27714,27762,27875,28792,29699,31350,31406,31496,32026, +31998,32102,26087,29275,21435,23621,24040,25298,25312,25369,28192,34394,35377, +36317,37624,28417,31142,39770,20136,20139,20140,20379,20384,20689,20807,31478, +20849,20982,21332,21281,21375,21483,21932,22659,23777,24375,24394,24623,24656, +24685,25375,25945,27211,27841,29378,29421,30703,33016,33029,33288,34126,37111, +37857,38911,39255,39514,20208,20957,23597,26241,26989,23616,26354,26997,29577, +26704,31873,20677,21220,22343,24062,37670,26020,27427,27453,29748,31105,31165, +31563,32202,33465,33740,34943,35167,35641,36817,37329,21535,37504,20061,20534, +21477,21306,29399,29590,30697,33510,36527,39366,39368,39378,20855,24858,34398, +21936,31354,20598,23507,36935,38533,20018,27355,37351,23633,23624,25496,31391, +27795,38772,36705,31402,29066,38536,31874,26647,32368,26705,37740,21234,21531, +34219,35347,32676,36557,37089,21350,34952,31041,20418,20670,21009,20804,21843, +22317,29674,22411,22865,24418,24452,24693,24950,24935,25001,25522,25658,25964, +26223,26690,28179,30054,31293,31995,32076,32153,32331,32619,33550,33610,34509, +35336,35427,35686,36605,38938,40335,33464,36814,39912,21127,25119,25731,28608, +38553,26689,20625,27424,27770,28500,31348,32080,34880,35363,26376,20214,20537, +20518,20581,20860,21048,21091,21927,22287,22533,23244,24314,25010,25080,25331, +25458,26908,27177,29309,29356,29486,30740,30831,32121,30476,32937,35211,35609, +36066,36562,36963,37749,38522,38997,39443,40568,20803,21407,21427,24187,24358, +28187,28304,29572,29694,32067,33335,35328,35578,38480,20046,20491,21476,21628, +22266,22993,23396,24049,24235,24359,25144,25925,26543,28246,29392,31946,34996, +32929,32993,33776,34382,35463,36328,37431,38599,39015,40723,20116,20114,20237, +21320,21577,21566,23087,24460,24481,24735,26791,27278,29786,30849,35486,35492, +35703,37264,20062,39881,20132,20348,20399,20505,20502,20809,20844,21151,21177, +21246,21402,21475,21521,21518,21897,22353,22434,22909,23380,23389,23439,24037, +24039,24055,24184,24195,24218,24247,24344,24658,24908,25239,25304,25511,25915, +26114,26179,26356,26477,26657,26775,27083,27743,27946,28009,28207,28317,30002, +30343,30828,31295,31968,32005,32024,32094,32177,32789,32771,32943,32945,33108, +33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,37628, +38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,28640, +35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,28425, +33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,22718, +23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,20123, +20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,35039, +22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,25165, +25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,33756, +35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,27018, +32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,26613, +31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,25774, +25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,19977, +20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,34453, +35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,21496, +21490,21987,22235,22763,22987,22985,23039,23376,23629,24066,24107,24535,24605, +25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,31169, +31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,36039, +36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,26178, +27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,36766, +27728,40575,24335,35672,40235,31482,36600,23437,38635,19971,21489,22519,22833, +23241,23460,24713,28287,28422,30142,36074,23455,34048,31712,20594,26612,33437, +23649,34122,32286,33294,20889,23556,25448,36198,26012,29038,31038,32023,32773, +35613,36554,36974,34503,37034,20511,21242,23610,26451,28796,29237,37196,37320, +37675,33509,23490,24369,24825,20027,21462,23432,25163,26417,27530,29417,29664, +31278,33131,36259,37202,39318,20754,21463,21610,23551,25480,27193,32172,38656, +22234,21454,21608,23447,23601,24030,20462,24833,25342,27954,31168,31179,32066, +32333,32722,33261,33311,33936,34886,35186,35728,36468,36655,36913,37195,37228, +38598,37276,20160,20303,20805,21313,24467,25102,26580,27713,28171,29539,32294, +37325,37507,21460,22809,23487,28113,31069,32302,31899,22654,29087,20986,34899, +36848,20426,23803,26149,30636,31459,33308,39423,20934,24490,26092,26991,27529, +28147,28310,28516,30462,32020,24033,36981,37255,38918,20966,21021,25152,26257, +26329,28186,24246,32210,32626,26360,34223,34295,35576,21161,21465,22899,24207, +24464,24661,37604,38500,20663,20767,21213,21280,21319,21484,21736,21830,21809, +22039,22888,22974,23100,23477,23558,23567,23569,23578,24196,24202,24288,24432, +25215,25220,25307,25484,25463,26119,26124,26157,26230,26494,26786,27167,27189, +27836,28040,28169,28248,28988,28966,29031,30151,30465,30813,30977,31077,31216, +31456,31505,31911,32057,32918,33750,33931,34121,34909,35059,35359,35388,35412, +35443,35937,36062,37284,37478,37758,37912,38556,38808,19978,19976,19998,20055, +20887,21104,22478,22580,22732,23330,24120,24773,25854,26465,26454,27972,29366, +30067,31331,33976,35698,37304,37664,22065,22516,39166,25325,26893,27542,29165, +32340,32887,33394,35302,39135,34645,36785,23611,20280,20449,20405,21767,23072, +23517,23529,24515,24910,25391,26032,26187,26862,27035,28024,28145,30003,30137, +30495,31070,31206,32051,33251,33455,34218,35242,35386,36523,36763,36914,37341, +38663,20154,20161,20995,22645,22764,23563,29978,23613,33102,35338,36805,38499, +38765,31525,35535,38920,37218,22259,21416,36887,21561,22402,24101,25512,27700, +28810,30561,31883,32736,34928,36930,37204,37648,37656,38543,29790,39620,23815, +23913,25968,26530,36264,38619,25454,26441,26905,33733,38935,38592,35070,28548, +25722,23544,19990,28716,30045,26159,20932,21046,21218,22995,24449,24615,25104, +25919,25972,26143,26228,26866,26646,27491,28165,29298,29983,30427,31934,32854, +22768,35069,35199,35488,35475,35531,36893,37266,38738,38745,25993,31246,33030, +38587,24109,24796,25114,26021,26132,26512,30707,31309,31821,32318,33034,36012, +36196,36321,36447,30889,20999,25305,25509,25666,25240,35373,31363,31680,35500, +38634,32118,33292,34633,20185,20808,21315,21344,23459,23554,23574,24029,25126, +25159,25776,26643,26676,27849,27973,27927,26579,28508,29006,29053,26059,31359, +31661,32218,32330,32680,33146,33307,33337,34214,35438,36046,36341,36984,36983, +37549,37521,38275,39854,21069,21892,28472,28982,20840,31109,32341,33203,31950, +22092,22609,23720,25514,26366,26365,26970,29401,30095,30094,30990,31062,31199, +31895,32032,32068,34311,35380,38459,36961,40736,20711,21109,21452,21474,20489, +21930,22766,22863,29245,23435,23652,21277,24803,24819,25436,25475,25407,25531, +25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967, +32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783, +38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363, +24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966, +20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409, +21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534, +23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151, +33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261, +38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730, +35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890, +33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022, +22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829, +32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527, +20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933, +39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013, +20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376, +27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115, +24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522, +32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189, +25431,30452,26389,27784,29645,36035,37806,38515,27941,22684,26894,27084,36861, +37786,30171,36890,22618,26626,25524,27131,20291,28460,26584,36795,34086,32180, +37716,26943,28528,22378,22775,23340,32044,29226,21514,37347,40372,20141,20302, +20572,20597,21059,35998,21576,22564,23450,24093,24213,24237,24311,24351,24716, +25269,25402,25552,26799,27712,30855,31118,31243,32224,33351,35330,35558,36420, +36883,37048,37165,37336,40718,27877,25688,25826,25973,28404,30340,31515,36969, +37841,28346,21746,24505,25764,36685,36845,37444,20856,22635,22825,23637,24215, +28155,32399,29980,36028,36578,39003,28857,20253,27583,28593,30000,38651,20814, +21520,22581,22615,22956,23648,24466,26007,26460,28193,30331,33759,36077,36884, +37117,37709,30757,30778,21162,24230,22303,22900,24594,20498,20826,20908,20941, +20992,21776,22612,22616,22871,23445,23798,23947,24764,25237,25645,26481,26691, +26812,26847,30423,28120,28271,28059,28783,29128,24403,30168,31095,31561,31572, +31570,31958,32113,21040,33891,34153,34276,35342,35588,35910,36367,36867,36879, +37913,38518,38957,39472,38360,20685,21205,21516,22530,23566,24999,25758,27934, +30643,31461,33012,33796,36947,37509,23776,40199,21311,24471,24499,28060,29305, +30563,31167,31716,27602,29420,35501,26627,27233,20984,31361,26932,23626,40182, +33515,23493,37193,28702,22136,23663,24775,25958,27788,35930,36929,38931,21585, +26311,37389,22856,37027,20869,20045,20970,34201,35598,28760,25466,37707,26978, +39348,32260,30071,21335,26976,36575,38627,27741,20108,23612,24336,36841,21250, +36049,32905,34425,24319,26085,20083,20837,22914,23615,38894,20219,22922,24525, +35469,28641,31152,31074,23527,33905,29483,29105,24180,24565,25467,25754,29123, +31896,20035,24316,20043,22492,22178,24745,28611,32013,33021,33075,33215,36786, +35223,34468,24052,25226,25773,35207,26487,27874,27966,29750,30772,23110,32629, +33453,39340,20467,24259,25309,25490,25943,26479,30403,29260,32972,32954,36649, +37197,20493,22521,23186,26757,26995,29028,29437,36023,22770,36064,38506,36889, +34687,31204,30695,33833,20271,21093,21338,25293,26575,27850,30333,31636,31893, +33334,34180,36843,26333,28448,29190,32283,33707,39361,40614,20989,31665,30834, +31672,32903,31560,27368,24161,32908,30033,30048,20843,37474,28300,30330,37271, +39658,20240,32624,25244,31567,38309,40169,22138,22617,34532,38588,20276,21028, +21322,21453,21467,24070,25644,26001,26495,27710,27726,29256,29359,29677,30036, +32321,33324,34281,36009,31684,37318,29033,38930,39151,25405,26217,30058,30436, +30928,34115,34542,21290,21329,21542,22915,24199,24444,24754,25161,25209,25259, +26000,27604,27852,30130,30382,30865,31192,32203,32631,32933,34987,35513,36027, +36991,38750,39131,27147,31800,20633,23614,24494,26503,27608,29749,30473,32654, +40763,26570,31255,21305,30091,39661,24422,33181,33777,32920,24380,24517,30050, +31558,36924,26727,23019,23195,32016,30334,35628,20469,24426,27161,27703,28418, +29922,31080,34920,35413,35961,24287,25551,30149,31186,33495,37672,37618,33948, +34541,39981,21697,24428,25996,27996,28693,36007,36051,38971,25935,29942,19981, +20184,22496,22827,23142,23500,20904,24067,24220,24598,25206,25975,26023,26222, +28014,29238,31526,33104,33178,33433,35676,36000,36070,36212,38428,38468,20398, +25771,27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103, +24489,24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289, +39826,20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640, +25991,32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281, +38491,31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793, +29255,31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303, +37610,22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286, +27597,31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849, +24214,25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459, +33804,34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129, +20621,21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882, +32033,32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340, +22696,25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868, +26412,32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598, +21737,27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273, +26411,27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410, +39749,24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665, +30496,21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517, +21629,26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236, +38754,40634,25720,27169,33538,22916,23391,27611,29467,30450,32178,32791,33945, +20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,36016,21839,24758, +32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,30690,21380,24441, +32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,27833,30290,35565, +36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,25558,26377,26586, +28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,37109,38596,34701, +22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,23481,24248,25562, +25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,32650,32768,33865, +33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,27779,28020,32716, +32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,32097,33853,37226, +20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,23653,26446,26792, +29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,31435,33870,25504, +30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,40845,20406,24942, +26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,28092,29471,30274, +30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,32209,20523,21400, +26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,22593,28057,32047, +39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,33491,37428,38583, +38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,24265,24651,24976, +28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,27347,28809,36034, +36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,28431,29282,29436, +31725,32769,32894,34635,37070,20845,40595,31108,32907,37682,35542,20525,21644, +35441,27498,36036,33031,24785,26528,40434,20121,20120,39952,35435,34241,34152, +26880,28286,30871,33109,24332,19984,19989,20010,20017,20022,20028,20031,20034, +20054,20056,20098,20101,35947,20106,33298,24333,20110,20126,20127,20128,20130, +20144,20147,20150,20174,20173,20164,20166,20162,20183,20190,20205,20191,20215, +20233,20314,20272,20315,20317,20311,20295,20342,20360,20367,20376,20347,20329, +20336,20369,20335,20358,20374,20760,20436,20447,20430,20440,20443,20433,20442, +20432,20452,20453,20506,20520,20500,20522,20517,20485,20252,20470,20513,20521, +20524,20478,20463,20497,20486,20547,20551,26371,20565,20560,20552,20570,20566, +20588,20600,20608,20634,20613,20660,20658,20681,20682,20659,20674,20694,20702, +20709,20717,20707,20718,20729,20725,20745,20737,20738,20758,20757,20756,20762, +20769,20794,20791,20796,20795,20799,20800,20818,20812,20820,20834,31480,20841, +20842,20846,20864,20866,22232,20876,20873,20879,20881,20883,20885,20886,20900, +20902,20898,20905,20906,20907,20915,20913,20914,20912,20917,20925,20933,20937, +20955,20960,34389,20969,20973,20976,20981,20990,20996,21003,21012,21006,21031, +21034,21038,21043,21049,21071,21060,21067,21068,21086,21076,21098,21108,21097, +21107,21119,21117,21133,21140,21138,21105,21128,21137,36776,36775,21164,21165, +21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,21237,21240, +21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,21297,21299, +21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,22808,21371, +21367,21378,21398,21408,21414,21413,21422,21424,21430,21443,31762,38617,21471, +26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,21564,21550, +21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,21650,21627, +21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,21704,21672, +21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,21742,21741, +21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,21816,21811, +21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,21884,21891, +21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,22007,22038, +22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,22123,22116, +22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,22198,22196, +22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,22265,22272, +22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,22310,22327, +22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,22419,22432, +22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,22499,22539, +22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,22661,22713, +22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,22745,22744, +22757,22748,22756,22751,22767,22778,22777,22779,22780,22781,22786,22794,22800, +22811,26790,22821,22828,22829,22834,22840,22846,31442,22869,22864,22862,22874, +22872,22882,22880,22887,22892,22889,22904,22913,22941,20318,20395,22947,22962, +22982,23016,23004,22925,23001,23002,23077,23071,23057,23068,23049,23066,23104, +23148,23113,23093,23094,23138,23146,23194,23228,23230,23243,23234,23229,23267, +23255,23270,23273,23254,23290,23291,23308,23307,23318,23346,23248,23338,23350, +23358,23363,23365,23360,23377,23381,23386,23387,23397,23401,23408,23411,23413, +23416,25992,23418,23424,23427,23462,23480,23491,23495,23497,23508,23504,23524, +23526,23522,23518,23525,23531,23536,23542,23539,23557,23559,23560,23565,23571, +23584,23586,23592,23608,23609,23617,23622,23630,23635,23632,23631,23409,23660, +23662,20066,23670,23673,23692,23697,23700,22939,23723,23739,23734,23740,23735, +23749,23742,23751,23769,23785,23805,23802,23789,23948,23786,23819,23829,23831, +23900,23839,23835,23825,23828,23842,23834,23833,23832,23884,23890,23886,23883, +23916,23923,23926,23943,23940,23938,23970,23965,23980,23982,23997,23952,23991, +23996,24009,24013,24019,24018,24022,24027,24043,24050,24053,24075,24090,24089, +24081,24091,24118,24119,24132,24131,24128,24142,24151,24148,24159,24162,24164, +24135,24181,24182,24186,40636,24191,24224,24257,24258,24264,24272,24271,24278, +24291,24285,24282,24283,24290,24289,24296,24297,24300,24305,24307,24304,24308, +24312,24318,24323,24329,24413,24412,24331,24337,24342,24361,24365,24376,24385, +24392,24396,24398,24367,24401,24406,24407,24409,24417,24429,24435,24439,24451, +24450,24447,24458,24456,24465,24455,24478,24473,24472,24480,24488,24493,24508, +24534,24571,24548,24568,24561,24541,24755,24575,24609,24672,24601,24592,24617, +24590,24625,24603,24597,24619,24614,24591,24634,24666,24641,24682,24695,24671, +24650,24646,24653,24675,24643,24676,24642,24684,24683,24665,24705,24717,24807, +24707,24730,24708,24731,24726,24727,24722,24743,24715,24801,24760,24800,24787, +24756,24560,24765,24774,24757,24792,24909,24853,24838,24822,24823,24832,24820, +24826,24835,24865,24827,24817,24845,24846,24903,24894,24872,24871,24906,24895, +24892,24876,24884,24893,24898,24900,24947,24951,24920,24921,24922,24939,24948, +24943,24933,24945,24927,24925,24915,24949,24985,24982,24967,25004,24980,24986, +24970,24977,25003,25006,25036,25034,25033,25079,25032,25027,25030,25018,25035, +32633,25037,25062,25059,25078,25082,25076,25087,25085,25084,25086,25088,25096, +25097,25101,25100,25108,25115,25118,25121,25130,25134,25136,25138,25139,25153, +25166,25182,25187,25179,25184,25192,25212,25218,25225,25214,25234,25235,25238, +25300,25219,25236,25303,25297,25275,25295,25343,25286,25812,25288,25308,25292, +25290,25282,25287,25243,25289,25356,25326,25329,25383,25346,25352,25327,25333, +25424,25406,25421,25628,25423,25494,25486,25472,25515,25462,25507,25487,25481, +25503,25525,25451,25449,25534,25577,25536,25542,25571,25545,25554,25590,25540, +25622,25652,25606,25619,25638,25654,25885,25623,25640,25615,25703,25711,25718, +25678,25898,25749,25747,25765,25769,25736,25788,25818,25810,25797,25799,25787, +25816,25794,25841,25831,33289,25824,25825,25260,25827,25839,25900,25846,25844, +25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,25911, +25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,25986, +25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,26075, +26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,26140, +26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,26243, +26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,26296, +26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,26406, +26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,26467, +26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,26607, +26548,26604,26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,26566, +26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,26723, +26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,26805, +26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,26892, +26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,26863, +26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,27006, +26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,27054, +27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,27182, +27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,27122, +27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,27204, +27148,27250,27190,27256,27207,27234,27225,27238,27208,27192,27170,27280,27277, +27296,27268,27298,27299,27287,34327,27323,27331,27330,27320,27315,27308,27358, +27345,27359,27306,27354,27370,27387,27397,34326,27386,27410,27414,39729,27423, +27448,27447,30428,27449,39150,27463,27459,27465,27472,27481,27476,27483,27487, +27489,27512,27513,27519,27520,27524,27523,27533,27544,27541,27550,27556,27562, +27563,27567,27570,27569,27571,27575,27580,27590,27595,27603,27615,27628,27627, +27635,27631,40638,27656,27667,27668,27675,27684,27683,27742,27733,27746,27754, +27778,27789,27802,27777,27803,27774,27752,27763,27794,27792,27844,27889,27859, +27837,27863,27845,27869,27822,27825,27838,27834,27867,27887,27865,27882,27935, +34893,27958,27947,27965,27960,27929,27957,27955,27922,27916,28003,28051,28004, +27994,28025,27993,28046,28053,28644,28037,28153,28181,28170,28085,28103,28134, +28088,28102,28140,28126,28108,28136,28114,28101,28154,28121,28132,28117,28138, +28142,28205,28270,28206,28185,28274,28255,28222,28195,28267,28203,28278,28237, +28191,28227,28218,28238,28196,28415,28189,28216,28290,28330,28312,28361,28343, +28371,28349,28335,28356,28338,28372,28373,28303,28325,28354,28319,28481,28433, +28748,28396,28408,28414,28479,28402,28465,28399,28466,28364,28478,28435,28407, +28550,28538,28536,28545,28544,28527,28507,28659,28525,28546,28540,28504,28558, +28561,28610,28518,28595,28579,28577,28580,28601,28614,28586,28639,28629,28652, +28628,28632,28657,28654,28635,28681,28683,28666,28689,28673,28687,28670,28699, +28698,28532,28701,28696,28703,28720,28734,28722,28753,28771,28825,28818,28847, +28913,28844,28856,28851,28846,28895,28875,28893,28889,28937,28925,28956,28953, +29029,29013,29064,29030,29026,29004,29014,29036,29071,29179,29060,29077,29096, +29100,29143,29113,29118,29138,29129,29140,29134,29152,29164,29159,29173,29180, +29177,29183,29197,29200,29211,29224,29229,29228,29232,29234,29243,29244,29247, +29248,29254,29259,29272,29300,29310,29314,29313,29319,29330,29334,29346,29351, +29369,29362,29379,29382,29380,29390,29394,29410,29408,29409,29433,29431,20495, +29463,29450,29468,29462,29469,29492,29487,29481,29477,29502,29518,29519,40664, +29527,29546,29544,29552,29560,29557,29563,29562,29640,29619,29646,29627,29632, +29669,29678,29662,29858,29701,29807,29733,29688,29746,29754,29781,29759,29791, +29785,29761,29788,29801,29808,29795,29802,29814,29822,29835,29854,29863,29898, +29903,29908,29681,29920,29923,29927,29929,29934,29938,29936,29937,29944,29943, +29956,29955,29957,29964,29966,29965,29973,29971,29982,29990,29996,30012,30020, +30029,30026,30025,30043,30022,30042,30057,30052,30055,30059,30061,30072,30070, +30086,30087,30068,30090,30089,30082,30100,30106,30109,30117,30115,30146,30131, +30147,30133,30141,30136,30140,30129,30157,30154,30162,30169,30179,30174,30206, +30207,30204,30209,30192,30202,30194,30195,30219,30221,30217,30239,30247,30240, +30241,30242,30244,30260,30256,30267,30279,30280,30278,30300,30296,30305,30306, +30312,30313,30314,30311,30316,30320,30322,30326,30328,30332,30336,30339,30344, +30347,30350,30358,30355,30361,30362,30384,30388,30392,30393,30394,30402,30413, +30422,30418,30430,30433,30437,30439,30442,34351,30459,30472,30471,30468,30505, +30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565, +30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652, +30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014, +30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895, +30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964, +30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059, +31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189, +31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291, +31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368, +31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431, +31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472, +31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610, +31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598, +31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681, +31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751, +31763,31731,31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805, +31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861, +31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929, +31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990, +31994,32006,32002,32028,32021,32010,32069,32075,32046,32050,32063,32053,32070, +32115,32086,32078,32114,32104,32110,32079,32099,32147,32137,32091,32143,32125, +32155,32186,32174,32163,32181,32199,32189,32171,32317,32162,32175,32220,32184, +32159,32176,32216,32221,32228,32222,32251,32242,32225,32261,32266,32291,32289, +32274,32305,32287,32265,32267,32290,32326,32358,32315,32309,32313,32323,32311, +32306,32314,32359,32349,32342,32350,32345,32346,32377,32362,32361,32380,32379, +32387,32213,32381,36782,32383,32392,32393,32396,32402,32400,32403,32404,32406, +32398,32411,32412,32568,32570,32581,32588,32589,32590,32592,32593,32597,32596, +32600,32607,32608,32616,32617,32615,32632,32642,32646,32643,32648,32647,32652, +32660,32670,32669,32666,32675,32687,32690,32697,32686,32694,32696,35697,32709, +32710,32714,32725,32724,32737,32742,32745,32755,32761,39132,32774,32772,32779, +32786,32792,32793,32796,32801,32808,32831,32827,32842,32838,32850,32856,32858, +32863,32866,32872,32883,32882,32880,32886,32889,32893,32895,32900,32902,32901, +32923,32915,32922,32941,20880,32940,32987,32997,32985,32989,32964,32986,32982, +33033,33007,33009,33051,33065,33059,33071,33099,38539,33094,33086,33107,33105, +33020,33137,33134,33125,33126,33140,33155,33160,33162,33152,33154,33184,33173, +33188,33187,33119,33171,33193,33200,33205,33214,33208,33213,33216,33218,33210, +33225,33229,33233,33241,33240,33224,33242,33247,33248,33255,33274,33275,33278, +33281,33282,33285,33287,33290,33293,33296,33302,33321,33323,33336,33331,33344, +33369,33368,33373,33370,33375,33380,33378,33384,33386,33387,33326,33393,33399, +33400,33406,33421,33426,33451,33439,33467,33452,33505,33507,33503,33490,33524, +33523,33530,33683,33539,33531,33529,33502,33542,33500,33545,33497,33589,33588, +33558,33586,33585,33600,33593,33616,33605,33583,33579,33559,33560,33669,33690, +33706,33695,33698,33686,33571,33678,33671,33674,33660,33717,33651,33653,33696, +33673,33704,33780,33811,33771,33742,33789,33795,33752,33803,33729,33783,33799, +33760,33778,33805,33826,33824,33725,33848,34054,33787,33901,33834,33852,34138, +33924,33911,33899,33965,33902,33922,33897,33862,33836,33903,33913,33845,33994, +33890,33977,33983,33951,34009,33997,33979,34010,34000,33985,33990,34006,33953, +34081,34047,34036,34071,34072,34092,34079,34069,34068,34044,34112,34147,34136, +34120,34113,34306,34123,34133,34176,34212,34184,34193,34186,34216,34157,34196, +34203,34282,34183,34204,34167,34174,34192,34249,34234,34255,34233,34256,34261, +34269,34277,34268,34297,34314,34323,34315,34302,34298,34310,34338,34330,34352, +34367,34381,20053,34388,34399,34407,34417,34451,34467,34473,34474,34443,34444, +34486,34479,34500,34502,34480,34505,34851,34475,34516,34526,34537,34540,34527, +34523,34543,34578,34566,34568,34560,34563,34555,34577,34569,34573,34553,34570, +34612,34623,34615,34619,34597,34601,34586,34656,34655,34680,34636,34638,34676, +34647,34664,34670,34649,34643,34659,34666,34821,34722,34719,34690,34735,34763, +34749,34752,34768,38614,34731,34756,34739,34759,34758,34747,34799,34802,34784, +34831,34829,34814,34806,34807,34830,34770,34833,34838,34837,34850,34849,34865, +34870,34873,34855,34875,34884,34882,34898,34905,34910,34914,34923,34945,34942, +34974,34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980, +34992,35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060, +35048,35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140, +35131,35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188, +35191,35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250, +35258,35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344, +35340,35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436, +35426,35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533, +35522,35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547, +35596,35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646, +35624,35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695, +35700,35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903, +35912,35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978, +35981,35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022, +36040,36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111, +36109,36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249, +36290,36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323, +36348,36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426, +36423,36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466, +36476,36481,36487,36485,36484,36491,36490,36499,36497,36500,36505,36522,36513, +36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,36604,36603,36587, +36606,36618,36613,36629,36626,36633,36627,36636,36639,36635,36620,36646,36659, +36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,36700,36706,36707, +36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,36842,36847,36999, +36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,36875,36903,36918, +36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,36950,36952,36958, +36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,37001,37007,37032, +37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,37170,37168,37194, +37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,37282,37291,37295, +37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,37343,37345,37339, +37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,37463,37445,37449, +37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,37466,37583,37561, +37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,37690,37685,37691, +37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,37846,37847,37864, +37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,37891,37895,37904, +37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,37986,37982,37994, +37417,38000,38005,38007,38013,37978,38012,38014,38017,38015,38274,38279,38282, +38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,38329,38334,38346, +28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,38370,38433,38440, +38446,38447,38466,38476,38479,38475,38519,38492,38494,38493,38495,38502,38514, +38508,38541,38552,38549,38551,38570,38567,38577,38578,38576,38580,38582,38584, +38585,38606,38603,38601,38605,35149,38620,38669,38613,38649,38660,38662,38664, +38675,38670,38673,38671,38678,38681,38692,38698,38704,38713,38717,38718,38724, +38726,38728,38722,38729,38748,38752,38756,38758,38760,21202,38763,38769,38777, +38789,38780,38785,38778,38790,38795,38799,38800,38812,38824,38822,38819,38835, +38836,38851,38854,38856,38859,38876,38893,40783,38898,31455,38902,38901,38927, +38924,38968,38948,38945,38967,38973,38982,38991,38987,39019,39023,39024,39025, +39028,39027,39082,39087,39089,39094,39108,39107,39110,39145,39147,39171,39177, +39186,39188,39192,39201,39197,39198,39204,39200,39212,39214,39229,39230,39234, +39241,39237,39248,39243,39249,39250,39244,39253,39319,39320,39333,39341,39342, +39356,39391,39387,39389,39384,39377,39405,39406,39409,39410,39419,39416,39425, +39439,39429,39394,39449,39467,39479,39493,39490,39488,39491,39486,39509,39501, +39515,39511,39519,39522,39525,39524,39529,39531,39530,39597,39600,39612,39616, +39631,39633,39635,39636,39646,39647,39650,39651,39654,39663,39659,39662,39668, +39665,39671,39675,39686,39704,39706,39711,39714,39715,39717,39719,39720,39721, +39722,39726,39727,39730,39748,39747,39759,39757,39758,39761,39768,39796,39827, +39811,39825,39830,39831,39839,39840,39848,39860,39872,39882,39865,39878,39887, +39889,39890,39907,39906,39908,39892,39905,39994,39922,39921,39920,39957,39956, +39945,39955,39948,39942,39944,39954,39946,39940,39982,39963,39973,39972,39969, +39984,40007,39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176, +40201,40200,40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210, +40257,40255,40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329, +40327,40363,40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378, +40390,40399,40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478, +40565,40569,40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617, +40632,40618,40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672, +40677,40680,40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391, +40725,40737,40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807, +40812,40810,40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956, +29081, +}; + +static const struct dbcs_index jisx0208_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0208_decmap+0,33,126},{__jisx0208_decmap ++94,33,126},{__jisx0208_decmap+188,48,122},{__jisx0208_decmap+263,33,115},{ +__jisx0208_decmap+346,33,118},{__jisx0208_decmap+432,33,88},{__jisx0208_decmap ++488,33,113},{__jisx0208_decmap+569,33,64},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{__jisx0208_decmap+601,33,126},{__jisx0208_decmap+695,33, +126},{__jisx0208_decmap+789,33,126},{__jisx0208_decmap+883,33,126},{ +__jisx0208_decmap+977,33,126},{__jisx0208_decmap+1071,33,126},{ +__jisx0208_decmap+1165,33,126},{__jisx0208_decmap+1259,33,126},{ +__jisx0208_decmap+1353,33,126},{__jisx0208_decmap+1447,33,126},{ +__jisx0208_decmap+1541,33,126},{__jisx0208_decmap+1635,33,126},{ +__jisx0208_decmap+1729,33,126},{__jisx0208_decmap+1823,33,126},{ +__jisx0208_decmap+1917,33,126},{__jisx0208_decmap+2011,33,126},{ +__jisx0208_decmap+2105,33,126},{__jisx0208_decmap+2199,33,126},{ +__jisx0208_decmap+2293,33,126},{__jisx0208_decmap+2387,33,126},{ +__jisx0208_decmap+2481,33,126},{__jisx0208_decmap+2575,33,126},{ +__jisx0208_decmap+2669,33,126},{__jisx0208_decmap+2763,33,126},{ +__jisx0208_decmap+2857,33,126},{__jisx0208_decmap+2951,33,126},{ +__jisx0208_decmap+3045,33,126},{__jisx0208_decmap+3139,33,126},{ +__jisx0208_decmap+3233,33,126},{__jisx0208_decmap+3327,33,126},{ +__jisx0208_decmap+3421,33,126},{__jisx0208_decmap+3515,33,83},{ +__jisx0208_decmap+3566,33,126},{__jisx0208_decmap+3660,33,126},{ +__jisx0208_decmap+3754,33,126},{__jisx0208_decmap+3848,33,126},{ +__jisx0208_decmap+3942,33,126},{__jisx0208_decmap+4036,33,126},{ +__jisx0208_decmap+4130,33,126},{__jisx0208_decmap+4224,33,126},{ +__jisx0208_decmap+4318,33,126},{__jisx0208_decmap+4412,33,126},{ +__jisx0208_decmap+4506,33,126},{__jisx0208_decmap+4600,33,126},{ +__jisx0208_decmap+4694,33,126},{__jisx0208_decmap+4788,33,126},{ +__jisx0208_decmap+4882,33,126},{__jisx0208_decmap+4976,33,126},{ +__jisx0208_decmap+5070,33,126},{__jisx0208_decmap+5164,33,126},{ +__jisx0208_decmap+5258,33,126},{__jisx0208_decmap+5352,33,126},{ +__jisx0208_decmap+5446,33,126},{__jisx0208_decmap+5540,33,126},{ +__jisx0208_decmap+5634,33,126},{__jisx0208_decmap+5728,33,126},{ +__jisx0208_decmap+5822,33,126},{__jisx0208_decmap+5916,33,126},{ +__jisx0208_decmap+6010,33,126},{__jisx0208_decmap+6104,33,126},{ +__jisx0208_decmap+6198,33,126},{__jisx0208_decmap+6292,33,126},{ +__jisx0208_decmap+6386,33,126},{__jisx0208_decmap+6480,33,126},{ +__jisx0208_decmap+6574,33,126},{__jisx0208_decmap+6668,33,126},{ +__jisx0208_decmap+6762,33,126},{__jisx0208_decmap+6856,33,126},{ +__jisx0208_decmap+6950,33,38},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const ucs2_t __jisx0212_decmap[6179] = { +728,711,184,729,733,175,731,730,126,900,901,U,U,U,U,U,U,U,U,161,166,191,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,186,170, +169,174,8482,164,8470,902,904,905,906,938,U,908,U,910,939,U,911,U,U,U,U,940, +941,942,943,970,912,972,962,973,971,944,974,1026,1027,1028,1029,1030,1031, +1032,1033,1034,1035,1036,1038,1039,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115, +1116,1118,1119,198,272,U,294,U,306,U,321,319,U,330,216,338,U,358,222,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,230,273,240,295,305,307,312,322,320,329,331,248,339, +223,359,254,193,192,196,194,258,461,256,260,197,195,262,264,268,199,266,270, +201,200,203,202,282,278,274,280,U,284,286,290,288,292,205,204,207,206,463,304, +298,302,296,308,310,313,317,315,323,327,325,209,211,210,214,212,465,336,332, +213,340,344,342,346,348,352,350,356,354,218,217,220,219,364,467,368,362,370, +366,360,471,475,473,469,372,221,376,374,377,381,379,225,224,228,226,259,462, +257,261,229,227,263,265,269,231,267,271,233,232,235,234,283,279,275,281,501, +285,287,U,289,293,237,236,239,238,464,U,299,303,297,309,311,314,318,316,324, +328,326,241,243,242,246,244,466,337,333,245,341,345,343,347,349,353,351,357, +355,250,249,252,251,365,468,369,363,371,367,361,472,476,474,470,373,253,255, +375,378,382,380,19970,19972,19973,19980,19986,19999,20003,20004,20008,20011, +20014,20015,20016,20021,20032,20033,20036,20039,20049,20058,20060,20067,20072, +20073,20084,20085,20089,20095,20109,20118,20119,20125,20143,20153,20163,20176, +20186,20187,20192,20193,20194,20200,20207,20209,20211,20213,20221,20222,20223, +20224,20226,20227,20232,20235,20236,20242,20245,20246,20247,20249,20270,20273, +20320,20275,20277,20279,20281,20283,20286,20288,20290,20296,20297,20299,20300, +20306,20308,20310,20312,20319,20323,20330,20332,20334,20337,20343,20344,20345, +20346,20349,20350,20353,20354,20356,20357,20361,20362,20364,20366,20368,20370, +20371,20372,20375,20377,20378,20382,20383,20402,20407,20409,20411,20412,20413, +20414,20416,20417,20421,20422,20424,20425,20427,20428,20429,20431,20434,20444, +20448,20450,20464,20466,20476,20477,20479,20480,20481,20484,20487,20490,20492, +20494,20496,20499,20503,20504,20507,20508,20509,20510,20514,20519,20526,20528, +20530,20531,20533,20544,20545,20546,20549,20550,20554,20556,20558,20561,20562, +20563,20567,20569,20575,20576,20578,20579,20582,20583,20586,20589,20592,20593, +20539,20609,20611,20612,20614,20618,20622,20623,20624,20626,20627,20628,20630, +20635,20636,20638,20639,20640,20641,20642,20650,20655,20656,20665,20666,20669, +20672,20675,20676,20679,20684,20686,20688,20691,20692,20696,20700,20701,20703, +20706,20708,20710,20712,20713,20719,20721,20726,20730,20734,20739,20742,20743, +20744,20747,20748,20749,20750,20722,20752,20759,20761,20763,20764,20765,20766, +20771,20775,20776,20780,20781,20783,20785,20787,20788,20789,20792,20793,20802, +20810,20815,20819,20821,20823,20824,20831,20836,20838,20862,20867,20868,20875, +20878,20888,20893,20897,20899,20909,20920,20922,20924,20926,20927,20930,20936, +20943,20945,20946,20947,20949,20952,20958,20962,20965,20974,20978,20979,20980, +20983,20993,20994,20997,21010,21011,21013,21014,21016,21026,21032,21041,21042, +21045,21052,21061,21065,21077,21079,21080,21082,21084,21087,21088,21089,21094, +21102,21111,21112,21113,21120,21122,21125,21130,21132,21139,21141,21142,21143, +21144,21146,21148,21156,21157,21158,21159,21167,21168,21174,21175,21176,21178, +21179,21181,21184,21188,21190,21192,21196,21199,21201,21204,21206,21211,21212, +21217,21221,21224,21225,21226,21228,21232,21233,21236,21238,21239,21248,21251, +21258,21259,21260,21265,21267,21272,21275,21276,21278,21279,21285,21287,21288, +21289,21291,21292,21293,21296,21298,21301,21308,21309,21310,21314,21324,21323, +21337,21339,21345,21347,21349,21356,21357,21362,21369,21374,21379,21383,21384, +21390,21395,21396,21401,21405,21409,21412,21418,21419,21423,21426,21428,21429, +21431,21432,21434,21437,21440,21445,21455,21458,21459,21461,21466,21469,21470, +21472,21478,21479,21493,21506,21523,21530,21537,21543,21544,21546,21551,21553, +21556,21557,21571,21572,21575,21581,21583,21598,21602,21604,21606,21607,21609, +21611,21613,21614,21620,21631,21633,21635,21637,21640,21641,21645,21649,21653, +21654,21660,21663,21665,21670,21671,21673,21674,21677,21678,21681,21687,21689, +21690,21691,21695,21702,21706,21709,21710,21728,21738,21740,21743,21750,21756, +21758,21759,21760,21761,21765,21768,21769,21772,21773,21774,21781,21802,21803, +21810,21813,21814,21819,21820,21821,21825,21831,21833,21834,21837,21840,21841, +21848,21850,21851,21854,21856,21857,21860,21862,21887,21889,21890,21894,21896, +21902,21903,21905,21906,21907,21908,21911,21923,21924,21933,21938,21951,21953, +21955,21958,21961,21963,21964,21966,21969,21970,21971,21975,21976,21979,21982, +21986,21993,22006,22015,22021,22024,22026,22029,22030,22031,22032,22033,22034, +22041,22060,22064,22067,22069,22071,22073,22075,22076,22077,22079,22080,22081, +22083,22084,22086,22089,22091,22093,22095,22100,22110,22112,22113,22114,22115, +22118,22121,22125,22127,22129,22130,22133,22148,22149,22152,22155,22156,22165, +22169,22170,22173,22174,22175,22182,22183,22184,22185,22187,22188,22189,22193, +22195,22199,22206,22213,22217,22218,22219,22223,22224,22220,22221,22233,22236, +22237,22239,22241,22244,22245,22246,22247,22248,22257,22251,22253,22262,22263, +22273,22274,22279,22282,22284,22289,22293,22298,22299,22301,22304,22306,22307, +22308,22309,22313,22314,22316,22318,22319,22323,22324,22333,22334,22335,22341, +22342,22348,22349,22354,22370,22373,22375,22376,22379,22381,22382,22383,22384, +22385,22387,22388,22389,22391,22393,22394,22395,22396,22398,22401,22403,22412, +22420,22423,22425,22426,22428,22429,22430,22431,22433,22421,22439,22440,22441, +22444,22456,22461,22471,22472,22476,22479,22485,22493,22494,22500,22502,22503, +22505,22509,22512,22517,22518,22520,22525,22526,22527,22531,22532,22536,22537, +22497,22540,22541,22555,22558,22559,22560,22566,22567,22573,22578,22585,22591, +22601,22604,22605,22607,22608,22613,22623,22625,22628,22631,22632,22648,22652, +22655,22656,22657,22663,22664,22665,22666,22668,22669,22671,22672,22676,22678, +22685,22688,22689,22690,22694,22697,22705,22706,22724,22716,22722,22728,22733, +22734,22736,22738,22740,22742,22746,22749,22753,22754,22761,22771,22789,22790, +22795,22796,22802,22803,22804,34369,22813,22817,22819,22820,22824,22831,22832, +22835,22837,22838,22847,22851,22854,22866,22867,22873,22875,22877,22878,22879, +22881,22883,22891,22893,22895,22898,22901,22902,22905,22907,22908,22923,22924, +22926,22930,22933,22935,22943,22948,22951,22957,22958,22959,22960,22963,22967, +22970,22972,22977,22979,22980,22984,22986,22989,22994,23005,23006,23007,23011, +23012,23015,23022,23023,23025,23026,23028,23031,23040,23044,23052,23053,23054, +23058,23059,23070,23075,23076,23079,23080,23082,23085,23088,23108,23109,23111, +23112,23116,23120,23125,23134,23139,23141,23143,23149,23159,23162,23163,23166, +23179,23184,23187,23190,23193,23196,23198,23199,23200,23202,23207,23212,23217, +23218,23219,23221,23224,23226,23227,23231,23236,23238,23240,23247,23258,23260, +23264,23269,23274,23278,23285,23286,23293,23296,23297,23304,23319,23348,23321, +23323,23325,23329,23333,23341,23352,23361,23371,23372,23378,23382,23390,23400, +23406,23407,23420,23421,23422,23423,23425,23428,23430,23434,23438,23440,23441, +23443,23444,23446,23464,23465,23468,23469,23471,23473,23474,23479,23482,23484, +23488,23489,23501,23503,23510,23511,23512,23513,23514,23520,23535,23537,23540, +23549,23564,23575,23582,23583,23587,23590,23593,23595,23596,23598,23600,23602, +23605,23606,23641,23642,23644,23650,23651,23655,23656,23657,23661,23664,23668, +23669,23674,23675,23676,23677,23687,23688,23690,23695,23698,23709,23711,23712, +23714,23715,23718,23722,23730,23732,23733,23738,23753,23755,23762,23773,23767, +23790,23793,23794,23796,23809,23814,23821,23826,23851,23843,23844,23846,23847, +23857,23860,23865,23869,23871,23874,23875,23878,23880,23893,23889,23897,23882, +23903,23904,23905,23906,23908,23914,23917,23920,23929,23930,23934,23935,23937, +23939,23944,23946,23954,23955,23956,23957,23961,23963,23967,23968,23975,23979, +23984,23988,23992,23993,24003,24007,24011,24016,24014,24024,24025,24032,24036, +24041,24056,24057,24064,24071,24077,24082,24084,24085,24088,24095,24096,24110, +24104,24114,24117,24126,24139,24144,24137,24145,24150,24152,24155,24156,24158, +24168,24170,24171,24172,24173,24174,24176,24192,24203,24206,24226,24228,24229, +24232,24234,24236,24241,24243,24253,24254,24255,24262,24268,24267,24270,24273, +24274,24276,24277,24284,24286,24293,24299,24322,24326,24327,24328,24334,24345, +24348,24349,24353,24354,24355,24356,24360,24363,24364,24366,24368,24372,24374, +24379,24381,24383,24384,24388,24389,24391,24397,24400,24404,24408,24411,24416, +24419,24420,24423,24431,24434,24436,24437,24440,24442,24445,24446,24457,24461, +24463,24470,24476,24477,24482,24487,24491,24484,24492,24495,24496,24497,24504, +24516,24519,24520,24521,24523,24528,24529,24530,24531,24532,24542,24545,24546, +24552,24553,24554,24556,24557,24558,24559,24562,24563,24566,24570,24572,24583, +24586,24589,24595,24596,24599,24600,24602,24607,24612,24621,24627,24629,24640, +24647,24648,24649,24652,24657,24660,24662,24663,24669,24673,24679,24689,24702, +24703,24706,24710,24712,24714,24718,24721,24723,24725,24728,24733,24734,24738, +24740,24741,24744,24752,24753,24759,24763,24766,24770,24772,24776,24777,24778, +24779,24782,24783,24788,24789,24793,24795,24797,24798,24802,24805,24818,24821, +24824,24828,24829,24834,24839,24842,24844,24848,24849,24850,24851,24852,24854, +24855,24857,24860,24862,24866,24874,24875,24880,24881,24885,24886,24887,24889, +24897,24901,24902,24905,24926,24928,24940,24946,24952,24955,24956,24959,24960, +24961,24963,24964,24971,24973,24978,24979,24983,24984,24988,24989,24991,24992, +24997,25000,25002,25005,25016,25017,25020,25024,25025,25026,25038,25039,25045, +25052,25053,25054,25055,25057,25058,25063,25065,25061,25068,25069,25071,25089, +25091,25092,25095,25107,25109,25116,25120,25122,25123,25127,25129,25131,25145, +25149,25154,25155,25156,25158,25164,25168,25169,25170,25172,25174,25178,25180, +25188,25197,25199,25203,25210,25213,25229,25230,25231,25232,25254,25256,25267, +25270,25271,25274,25278,25279,25284,25294,25301,25302,25306,25322,25330,25332, +25340,25341,25347,25348,25354,25355,25357,25360,25363,25366,25368,25385,25386, +25389,25397,25398,25401,25404,25409,25410,25411,25412,25414,25418,25419,25422, +25426,25427,25428,25432,25435,25445,25446,25452,25453,25457,25460,25461,25464, +25468,25469,25471,25474,25476,25479,25482,25488,25492,25493,25497,25498,25502, +25508,25510,25517,25518,25519,25533,25537,25541,25544,25550,25553,25555,25556, +25557,25564,25568,25573,25578,25580,25586,25587,25589,25592,25593,25609,25610, +25616,25618,25620,25624,25630,25632,25634,25636,25637,25641,25642,25647,25648, +25653,25661,25663,25675,25679,25681,25682,25683,25684,25690,25691,25692,25693, +25695,25696,25697,25699,25709,25715,25716,25723,25725,25733,25735,25743,25744, +25745,25752,25753,25755,25757,25759,25761,25763,25766,25768,25772,25779,25789, +25790,25791,25796,25801,25802,25803,25804,25806,25808,25809,25813,25815,25828, +25829,25833,25834,25837,25840,25845,25847,25851,25855,25857,25860,25864,25865, +25866,25871,25875,25876,25878,25881,25883,25886,25887,25890,25894,25897,25902, +25905,25914,25916,25917,25923,25927,25929,25936,25938,25940,25951,25952,25959, +25963,25978,25981,25985,25989,25994,26002,26005,26008,26013,26016,26019,26022, +26030,26034,26035,26036,26047,26050,26056,26057,26062,26064,26068,26070,26072, +26079,26096,26098,26100,26101,26105,26110,26111,26112,26116,26120,26121,26125, +26129,26130,26133,26134,26141,26142,26145,26146,26147,26148,26150,26153,26154, +26155,26156,26158,26160,26161,26163,26169,26167,26176,26181,26182,26186,26188, +26193,26190,26199,26200,26201,26203,26204,26208,26209,26363,26218,26219,26220, +26238,26227,26229,26239,26231,26232,26233,26235,26240,26236,26251,26252,26253, +26256,26258,26265,26266,26267,26268,26271,26272,26276,26285,26289,26290,26293, +26299,26303,26304,26306,26307,26312,26316,26318,26319,26324,26331,26335,26344, +26347,26348,26350,26362,26373,26375,26382,26387,26393,26396,26400,26402,26419, +26430,26437,26439,26440,26444,26452,26453,26461,26470,26476,26478,26484,26486, +26491,26497,26500,26510,26511,26513,26515,26518,26520,26521,26523,26544,26545, +26546,26549,26555,26556,26557,26617,26560,26562,26563,26565,26568,26569,26578, +26583,26585,26588,26593,26598,26608,26610,26614,26615,26706,26644,26649,26653, +26655,26664,26663,26668,26669,26671,26672,26673,26675,26683,26687,26692,26693, +26698,26700,26709,26711,26712,26715,26731,26734,26735,26736,26737,26738,26741, +26745,26746,26747,26748,26754,26756,26758,26760,26774,26776,26778,26780,26785, +26787,26789,26793,26794,26798,26802,26811,26821,26824,26828,26831,26832,26833, +26835,26838,26841,26844,26845,26853,26856,26858,26859,26860,26861,26864,26865, +26869,26870,26875,26876,26877,26886,26889,26890,26896,26897,26899,26902,26903, +26929,26931,26933,26936,26939,26946,26949,26953,26958,26967,26971,26979,26980, +26981,26982,26984,26985,26988,26992,26993,26994,27002,27003,27007,27008,27021, +27026,27030,27032,27041,27045,27046,27048,27051,27053,27055,27063,27064,27066, +27068,27077,27080,27089,27094,27095,27106,27109,27118,27119,27121,27123,27125, +27134,27136,27137,27139,27151,27153,27157,27162,27165,27168,27172,27176,27184, +27186,27188,27191,27195,27198,27199,27205,27206,27209,27210,27214,27216,27217, +27218,27221,27222,27227,27236,27239,27242,27249,27251,27262,27265,27267,27270, +27271,27273,27275,27281,27291,27293,27294,27295,27301,27307,27311,27312,27313, +27316,27325,27326,27327,27334,27337,27336,27340,27344,27348,27349,27350,27356, +27357,27364,27367,27372,27376,27377,27378,27388,27389,27394,27395,27398,27399, +27401,27407,27408,27409,27415,27419,27422,27428,27432,27435,27436,27439,27445, +27446,27451,27455,27462,27466,27469,27474,27478,27480,27485,27488,27495,27499, +27502,27504,27509,27517,27518,27522,27525,27543,27547,27551,27552,27554,27555, +27560,27561,27564,27565,27566,27568,27576,27577,27581,27582,27587,27588,27593, +27596,27606,27610,27617,27619,27622,27623,27630,27633,27639,27641,27647,27650, +27652,27653,27657,27661,27662,27664,27666,27673,27679,27686,27687,27688,27692, +27694,27699,27701,27702,27706,27707,27711,27722,27723,27725,27727,27730,27732, +27737,27739,27740,27755,27757,27759,27764,27766,27768,27769,27771,27781,27782, +27783,27785,27796,27797,27799,27800,27804,27807,27824,27826,27828,27842,27846, +27853,27855,27856,27857,27858,27860,27862,27866,27868,27872,27879,27881,27883, +27884,27886,27890,27892,27908,27911,27914,27918,27919,27921,27923,27930,27942, +27943,27944,27751,27950,27951,27953,27961,27964,27967,27991,27998,27999,28001, +28005,28007,28015,28016,28028,28034,28039,28049,28050,28052,28054,28055,28056, +28074,28076,28084,28087,28089,28093,28095,28100,28104,28106,28110,28111,28118, +28123,28125,28127,28128,28130,28133,28137,28143,28144,28148,28150,28156,28160, +28164,28190,28194,28199,28210,28214,28217,28219,28220,28228,28229,28232,28233, +28235,28239,28241,28242,28243,28244,28247,28252,28253,28254,28258,28259,28264, +28275,28283,28285,28301,28307,28313,28320,28327,28333,28334,28337,28339,28347, +28351,28352,28353,28355,28359,28360,28362,28365,28366,28367,28395,28397,28398, +28409,28411,28413,28420,28424,28426,28428,28429,28438,28440,28442,28443,28454, +28457,28458,28463,28464,28467,28470,28475,28476,28461,28495,28497,28498,28499, +28503,28505,28506,28509,28510,28513,28514,28520,28524,28541,28542,28547,28551, +28552,28555,28556,28557,28560,28562,28563,28564,28566,28570,28575,28576,28581, +28582,28583,28584,28590,28591,28592,28597,28598,28604,28613,28615,28616,28618, +28634,28638,28648,28649,28656,28661,28665,28668,28669,28672,28677,28678,28679, +28685,28695,28704,28707,28719,28724,28727,28729,28732,28739,28740,28744,28745, +28746,28747,28756,28757,28765,28766,28750,28772,28773,28780,28782,28789,28790, +28798,28801,28805,28806,28820,28821,28822,28823,28824,28827,28836,28843,28848, +28849,28852,28855,28874,28881,28883,28884,28885,28886,28888,28892,28900,28922, +28931,28932,28933,28934,28935,28939,28940,28943,28958,28960,28971,28973,28975, +28976,28977,28984,28993,28997,28998,28999,29002,29003,29008,29010,29015,29018, +29020,29022,29024,29032,29049,29056,29061,29063,29068,29074,29082,29083,29088, +29090,29103,29104,29106,29107,29114,29119,29120,29121,29124,29131,29132,29139, +29142,29145,29146,29148,29176,29182,29184,29191,29192,29193,29203,29207,29210, +29213,29215,29220,29227,29231,29236,29240,29241,29249,29250,29251,29253,29262, +29263,29264,29267,29269,29270,29274,29276,29278,29280,29283,29288,29291,29294, +29295,29297,29303,29304,29307,29308,29311,29316,29321,29325,29326,29331,29339, +29352,29357,29358,29361,29364,29374,29377,29383,29385,29388,29397,29398,29400, +29407,29413,29427,29428,29434,29435,29438,29442,29444,29445,29447,29451,29453, +29458,29459,29464,29465,29470,29474,29476,29479,29480,29484,29489,29490,29493, +29498,29499,29501,29507,29517,29520,29522,29526,29528,29533,29534,29535,29536, +29542,29543,29545,29547,29548,29550,29551,29553,29559,29561,29564,29568,29569, +29571,29573,29574,29582,29584,29587,29589,29591,29592,29596,29598,29599,29600, +29602,29605,29606,29610,29611,29613,29621,29623,29625,29628,29629,29631,29637, +29638,29641,29643,29644,29647,29650,29651,29654,29657,29661,29665,29667,29670, +29671,29673,29684,29685,29687,29689,29690,29691,29693,29695,29696,29697,29700, +29703,29706,29713,29722,29723,29732,29734,29736,29737,29738,29739,29740,29741, +29742,29743,29744,29745,29753,29760,29763,29764,29766,29767,29771,29773,29777, +29778,29783,29789,29794,29798,29799,29800,29803,29805,29806,29809,29810,29824, +29825,29829,29830,29831,29833,29839,29840,29841,29842,29848,29849,29850,29852, +29855,29856,29857,29859,29862,29864,29865,29866,29867,29870,29871,29873,29874, +29877,29881,29883,29887,29896,29897,29900,29904,29907,29912,29914,29915,29918, +29919,29924,29928,29930,29931,29935,29940,29946,29947,29948,29951,29958,29970, +29974,29975,29984,29985,29988,29991,29993,29994,29999,30006,30009,30013,30014, +30015,30016,30019,30023,30024,30030,30032,30034,30039,30046,30047,30049,30063, +30065,30073,30074,30075,30076,30077,30078,30081,30085,30096,30098,30099,30101, +30105,30108,30114,30116,30132,30138,30143,30144,30145,30148,30150,30156,30158, +30159,30167,30172,30175,30176,30177,30180,30183,30188,30190,30191,30193,30201, +30208,30210,30211,30212,30215,30216,30218,30220,30223,30226,30227,30229,30230, +30233,30235,30236,30237,30238,30243,30245,30246,30249,30253,30258,30259,30261, +30264,30265,30266,30268,30282,30272,30273,30275,30276,30277,30281,30283,30293, +30297,30303,30308,30309,30317,30318,30319,30321,30324,30337,30341,30348,30349, +30357,30363,30364,30365,30367,30368,30370,30371,30372,30373,30374,30375,30376, +30378,30381,30397,30401,30405,30409,30411,30412,30414,30420,30425,30432,30438, +30440,30444,30448,30449,30454,30457,30460,30464,30470,30474,30478,30482,30484, +30485,30487,30489,30490,30492,30498,30504,30509,30510,30511,30516,30517,30518, +30521,30525,30526,30530,30533,30534,30538,30541,30542,30543,30546,30550,30551, +30556,30558,30559,30560,30562,30564,30567,30570,30572,30576,30578,30579,30580, +30586,30589,30592,30596,30604,30605,30612,30613,30614,30618,30623,30626,30631, +30634,30638,30639,30641,30645,30654,30659,30665,30673,30674,30677,30681,30686, +30687,30688,30692,30694,30698,30700,30704,30705,30708,30712,30715,30725,30726, +30729,30733,30734,30737,30749,30753,30754,30755,30765,30766,30768,30773,30775, +30787,30788,30791,30792,30796,30798,30802,30812,30814,30816,30817,30819,30820, +30824,30826,30830,30842,30846,30858,30863,30868,30872,30881,30877,30878,30879, +30884,30888,30892,30893,30896,30897,30898,30899,30907,30909,30911,30919,30920, +30921,30924,30926,30930,30931,30933,30934,30948,30939,30943,30944,30945,30950, +30954,30962,30963,30976,30966,30967,30970,30971,30975,30982,30988,30992,31002, +31004,31006,31007,31008,31013,31015,31017,31021,31025,31028,31029,31035,31037, +31039,31044,31045,31046,31050,31051,31055,31057,31060,31064,31067,31068,31079, +31081,31083,31090,31097,31099,31100,31102,31115,31116,31121,31123,31124,31125, +31126,31128,31131,31132,31137,31144,31145,31147,31151,31153,31156,31160,31163, +31170,31172,31175,31176,31178,31183,31188,31190,31194,31197,31198,31200,31202, +31205,31210,31211,31213,31217,31224,31228,31234,31235,31239,31241,31242,31244, +31249,31253,31259,31262,31265,31271,31275,31277,31279,31280,31284,31285,31288, +31289,31290,31300,31301,31303,31304,31308,31317,31318,31321,31324,31325,31327, +31328,31333,31335,31338,31341,31349,31352,31358,31360,31362,31365,31366,31370, +31371,31376,31377,31380,31390,31392,31395,31404,31411,31413,31417,31419,31420, +31430,31433,31436,31438,31441,31451,31464,31465,31467,31468,31473,31476,31483, +31485,31486,31495,31508,31519,31523,31527,31529,31530,31531,31533,31534,31535, +31536,31537,31540,31549,31551,31552,31553,31559,31566,31573,31584,31588,31590, +31593,31594,31597,31599,31602,31603,31607,31620,31625,31630,31632,31633,31638, +31643,31646,31648,31653,31660,31663,31664,31666,31669,31670,31674,31675,31676, +31677,31682,31685,31688,31690,31700,31702,31703,31705,31706,31707,31720,31722, +31730,31732,31733,31736,31737,31738,31740,31742,31745,31746,31747,31748,31750, +31753,31755,31756,31758,31759,31769,31771,31776,31781,31782,31784,31788,31793, +31795,31796,31798,31801,31802,31814,31818,31829,31825,31826,31827,31833,31834, +31835,31836,31837,31838,31841,31843,31847,31849,31853,31854,31856,31858,31865, +31868,31869,31878,31879,31887,31892,31902,31904,31910,31920,31926,31927,31930, +31931,31932,31935,31940,31943,31944,31945,31949,31951,31955,31956,31957,31959, +31961,31962,31965,31974,31977,31979,31989,32003,32007,32008,32009,32015,32017, +32018,32019,32022,32029,32030,32035,32038,32042,32045,32049,32060,32061,32062, +32064,32065,32071,32072,32077,32081,32083,32087,32089,32090,32092,32093,32101, +32103,32106,32112,32120,32122,32123,32127,32129,32130,32131,32133,32134,32136, +32139,32140,32141,32145,32150,32151,32157,32158,32166,32167,32170,32179,32182, +32183,32185,32194,32195,32196,32197,32198,32204,32205,32206,32215,32217,32256, +32226,32229,32230,32234,32235,32237,32241,32245,32246,32249,32250,32264,32272, +32273,32277,32279,32284,32285,32288,32295,32296,32300,32301,32303,32307,32310, +32319,32324,32325,32327,32334,32336,32338,32344,32351,32353,32354,32357,32363, +32366,32367,32371,32376,32382,32385,32390,32391,32394,32397,32401,32405,32408, +32410,32413,32414,32572,32571,32573,32574,32575,32579,32580,32583,32591,32594, +32595,32603,32604,32605,32609,32611,32612,32613,32614,32621,32625,32637,32638, +32639,32640,32651,32653,32655,32656,32657,32662,32663,32668,32673,32674,32678, +32682,32685,32692,32700,32703,32704,32707,32712,32718,32719,32731,32735,32739, +32741,32744,32748,32750,32751,32754,32762,32765,32766,32767,32775,32776,32778, +32781,32782,32783,32785,32787,32788,32790,32797,32798,32799,32800,32804,32806, +32812,32814,32816,32820,32821,32823,32825,32826,32828,32830,32832,32836,32864, +32868,32870,32877,32881,32885,32897,32904,32910,32924,32926,32934,32935,32939, +32952,32953,32968,32973,32975,32978,32980,32981,32983,32984,32992,33005,33006, +33008,33010,33011,33014,33017,33018,33022,33027,33035,33046,33047,33048,33052, +33054,33056,33060,33063,33068,33072,33077,33082,33084,33093,33095,33098,33100, +33106,33111,33120,33121,33127,33128,33129,33133,33135,33143,33153,33168,33156, +33157,33158,33163,33166,33174,33176,33179,33182,33186,33198,33202,33204,33211, +33227,33219,33221,33226,33230,33231,33237,33239,33243,33245,33246,33249,33252, +33259,33260,33264,33265,33266,33269,33270,33272,33273,33277,33279,33280,33283, +33295,33299,33300,33305,33306,33309,33313,33314,33320,33330,33332,33338,33347, +33348,33349,33350,33355,33358,33359,33361,33366,33372,33376,33379,33383,33389, +33396,33403,33405,33407,33408,33409,33411,33412,33415,33417,33418,33422,33425, +33428,33430,33432,33434,33435,33440,33441,33443,33444,33447,33448,33449,33450, +33454,33456,33458,33460,33463,33466,33468,33470,33471,33478,33488,33493,33498, +33504,33506,33508,33512,33514,33517,33519,33526,33527,33533,33534,33536,33537, +33543,33544,33546,33547,33620,33563,33565,33566,33567,33569,33570,33580,33581, +33582,33584,33587,33591,33594,33596,33597,33602,33603,33604,33607,33613,33614, +33617,33621,33622,33623,33648,33656,33661,33663,33664,33666,33668,33670,33677, +33682,33684,33685,33688,33689,33691,33692,33693,33702,33703,33705,33708,33726, +33727,33728,33735,33737,33743,33744,33745,33748,33757,33619,33768,33770,33782, +33784,33785,33788,33793,33798,33802,33807,33809,33813,33817,33709,33839,33849, +33861,33863,33864,33866,33869,33871,33873,33874,33878,33880,33881,33882,33884, +33888,33892,33893,33895,33898,33904,33907,33908,33910,33912,33916,33917,33921, +33925,33938,33939,33941,33950,33958,33960,33961,33962,33967,33969,33972,33978, +33981,33982,33984,33986,33991,33992,33996,33999,34003,34012,34023,34026,34031, +34032,34033,34034,34039,34098,34042,34043,34045,34050,34051,34055,34060,34062, +34064,34076,34078,34082,34083,34084,34085,34087,34090,34091,34095,34099,34100, +34102,34111,34118,34127,34128,34129,34130,34131,34134,34137,34140,34141,34142, +34143,34144,34145,34146,34148,34155,34159,34169,34170,34171,34173,34175,34177, +34181,34182,34185,34187,34188,34191,34195,34200,34205,34207,34208,34210,34213, +34215,34228,34230,34231,34232,34236,34237,34238,34239,34242,34247,34250,34251, +34254,34221,34264,34266,34271,34272,34278,34280,34285,34291,34294,34300,34303, +34304,34308,34309,34317,34318,34320,34321,34322,34328,34329,34331,34334,34337, +34343,34345,34358,34360,34362,34364,34365,34368,34370,34374,34386,34387,34390, +34391,34392,34393,34397,34400,34401,34402,34403,34404,34409,34412,34415,34421, +34422,34423,34426,34445,34449,34454,34456,34458,34460,34465,34470,34471,34472, +34477,34481,34483,34484,34485,34487,34488,34489,34495,34496,34497,34499,34501, +34513,34514,34517,34519,34522,34524,34528,34531,34533,34535,34440,34554,34556, +34557,34564,34565,34567,34571,34574,34575,34576,34579,34580,34585,34590,34591, +34593,34595,34600,34606,34607,34609,34610,34617,34618,34620,34621,34622,34624, +34627,34629,34637,34648,34653,34657,34660,34661,34671,34673,34674,34683,34691, +34692,34693,34694,34695,34696,34697,34699,34700,34704,34707,34709,34711,34712, +34713,34718,34720,34723,34727,34732,34733,34734,34737,34741,34750,34751,34753, +34760,34761,34762,34766,34773,34774,34777,34778,34780,34783,34786,34787,34788, +34794,34795,34797,34801,34803,34808,34810,34815,34817,34819,34822,34825,34826, +34827,34832,34841,34834,34835,34836,34840,34842,34843,34844,34846,34847,34856, +34861,34862,34864,34866,34869,34874,34876,34881,34883,34885,34888,34889,34890, +34891,34894,34897,34901,34902,34904,34906,34908,34911,34912,34916,34921,34929, +34937,34939,34944,34968,34970,34971,34972,34975,34976,34984,34986,35002,35005, +35006,35008,35018,35019,35020,35021,35022,35025,35026,35027,35035,35038,35047, +35055,35056,35057,35061,35063,35073,35078,35085,35086,35087,35093,35094,35096, +35097,35098,35100,35104,35110,35111,35112,35120,35121,35122,35125,35129,35130, +35134,35136,35138,35141,35142,35145,35151,35154,35159,35162,35163,35164,35169, +35170,35171,35179,35182,35184,35187,35189,35194,35195,35196,35197,35209,35213, +35216,35220,35221,35227,35228,35231,35232,35237,35248,35252,35253,35254,35255, +35260,35284,35285,35286,35287,35288,35301,35305,35307,35309,35313,35315,35318, +35321,35325,35327,35332,35333,35335,35343,35345,35346,35348,35349,35358,35360, +35362,35364,35366,35371,35372,35375,35381,35383,35389,35390,35392,35395,35397, +35399,35401,35405,35406,35411,35414,35415,35416,35420,35421,35425,35429,35431, +35445,35446,35447,35449,35450,35451,35454,35455,35456,35459,35462,35467,35471, +35472,35474,35478,35479,35481,35487,35495,35497,35502,35503,35507,35510,35511, +35515,35518,35523,35526,35528,35529,35530,35537,35539,35540,35541,35543,35549, +35551,35564,35568,35572,35573,35574,35580,35583,35589,35590,35595,35601,35612, +35614,35615,35594,35629,35632,35639,35644,35650,35651,35652,35653,35654,35656, +35666,35667,35668,35673,35661,35678,35683,35693,35702,35704,35705,35708,35710, +35713,35716,35717,35723,35725,35727,35732,35733,35740,35742,35743,35896,35897, +35901,35902,35909,35911,35913,35915,35919,35921,35923,35924,35927,35928,35931, +35933,35929,35939,35940,35942,35944,35945,35949,35955,35957,35958,35963,35966, +35974,35975,35979,35984,35986,35987,35993,35995,35996,36004,36025,36026,36037, +36038,36041,36043,36047,36054,36053,36057,36061,36065,36072,36076,36079,36080, +36082,36085,36087,36088,36094,36095,36097,36099,36105,36114,36119,36123,36197, +36201,36204,36206,36223,36226,36228,36232,36237,36240,36241,36245,36254,36255, +36256,36262,36267,36268,36271,36274,36277,36279,36281,36283,36288,36293,36294, +36295,36296,36298,36302,36305,36308,36309,36311,36313,36324,36325,36327,36332, +36336,36284,36337,36338,36340,36349,36353,36356,36357,36358,36363,36369,36372, +36374,36384,36385,36386,36387,36390,36391,36401,36403,36406,36407,36408,36409, +36413,36416,36417,36427,36429,36430,36431,36436,36443,36444,36445,36446,36449, +36450,36457,36460,36461,36463,36464,36465,36473,36474,36475,36482,36483,36489, +36496,36498,36501,36506,36507,36509,36510,36514,36519,36521,36525,36526,36531, +36533,36538,36539,36544,36545,36547,36548,36551,36559,36561,36564,36572,36584, +36590,36592,36593,36599,36601,36602,36589,36608,36610,36615,36616,36623,36624, +36630,36631,36632,36638,36640,36641,36643,36645,36647,36648,36652,36653,36654, +36660,36661,36662,36663,36666,36672,36673,36675,36679,36687,36689,36690,36691, +36692,36693,36696,36701,36702,36709,36765,36768,36769,36772,36773,36774,36789, +36790,36792,36798,36800,36801,36806,36810,36811,36813,36816,36818,36819,36821, +36832,36835,36836,36840,36846,36849,36853,36854,36859,36862,36866,36868,36872, +36876,36888,36891,36904,36905,36911,36906,36908,36909,36915,36916,36919,36927, +36931,36932,36940,36955,36957,36962,36966,36967,36972,36976,36980,36985,36997, +37000,37003,37004,37006,37008,37013,37015,37016,37017,37019,37024,37025,37026, +37029,37040,37042,37043,37044,37046,37053,37068,37054,37059,37060,37061,37063, +37064,37077,37079,37080,37081,37084,37085,37087,37093,37074,37110,37099,37103, +37104,37108,37118,37119,37120,37124,37125,37126,37128,37133,37136,37140,37142, +37143,37144,37146,37148,37150,37152,37157,37154,37155,37159,37161,37166,37167, +37169,37172,37174,37175,37177,37178,37180,37181,37187,37191,37192,37199,37203, +37207,37209,37210,37211,37217,37220,37223,37229,37236,37241,37242,37243,37249, +37251,37253,37254,37258,37262,37265,37267,37268,37269,37272,37278,37281,37286, +37288,37292,37293,37294,37296,37297,37298,37299,37302,37307,37308,37309,37311, +37314,37315,37317,37331,37332,37335,37337,37338,37342,37348,37349,37353,37354, +37356,37357,37358,37359,37360,37361,37367,37369,37371,37373,37376,37377,37380, +37381,37382,37383,37385,37386,37388,37392,37394,37395,37398,37400,37404,37405, +37411,37412,37413,37414,37416,37422,37423,37424,37427,37429,37430,37432,37433, +37434,37436,37438,37440,37442,37443,37446,37447,37450,37453,37454,37455,37457, +37464,37465,37468,37469,37472,37473,37477,37479,37480,37481,37486,37487,37488, +37493,37494,37495,37496,37497,37499,37500,37501,37503,37512,37513,37514,37517, +37518,37522,37527,37529,37535,37536,37540,37541,37543,37544,37547,37551,37554, +37558,37560,37562,37563,37564,37565,37567,37568,37569,37570,37571,37573,37574, +37575,37576,37579,37580,37581,37582,37584,37587,37589,37591,37592,37593,37596, +37597,37599,37600,37601,37603,37605,37607,37608,37612,37614,37616,37625,37627, +37631,37632,37634,37640,37645,37649,37652,37653,37660,37661,37662,37663,37665, +37668,37669,37671,37673,37674,37683,37684,37686,37687,37703,37704,37705,37712, +37713,37714,37717,37719,37720,37722,37726,37732,37733,37735,37737,37738,37741, +37743,37744,37745,37747,37748,37750,37754,37757,37759,37760,37761,37762,37768, +37770,37771,37773,37775,37778,37781,37784,37787,37790,37793,37795,37796,37798, +37800,37803,37812,37813,37814,37818,37801,37825,37828,37829,37830,37831,37833, +37834,37835,37836,37837,37843,37849,37852,37854,37855,37858,37862,37863,37881, +37879,37880,37882,37883,37885,37889,37890,37892,37896,37897,37901,37902,37903, +37909,37910,37911,37919,37934,37935,37937,37938,37939,37940,37947,37951,37949, +37955,37957,37960,37962,37964,37973,37977,37980,37983,37985,37987,37992,37995, +37997,37998,37999,38001,38002,38020,38019,38264,38265,38270,38276,38280,38284, +38285,38286,38301,38302,38303,38305,38310,38313,38315,38316,38324,38326,38330, +38333,38335,38342,38344,38345,38347,38352,38353,38354,38355,38361,38362,38365, +38366,38367,38368,38372,38374,38429,38430,38434,38436,38437,38438,38444,38449, +38451,38455,38456,38457,38458,38460,38461,38465,38482,38484,38486,38487,38488, +38497,38510,38516,38523,38524,38526,38527,38529,38530,38531,38532,38537,38545, +38550,38554,38557,38559,38564,38565,38566,38569,38574,38575,38579,38586,38602, +38610,23986,38616,38618,38621,38622,38623,38633,38639,38641,38650,38658,38659, +38661,38665,38682,38683,38685,38689,38690,38691,38696,38705,38707,38721,38723, +38730,38734,38735,38741,38743,38744,38746,38747,38755,38759,38762,38766,38771, +38774,38775,38776,38779,38781,38783,38784,38793,38805,38806,38807,38809,38810, +38814,38815,38818,38828,38830,38833,38834,38837,38838,38840,38841,38842,38844, +38846,38847,38849,38852,38853,38855,38857,38858,38860,38861,38862,38864,38865, +38868,38871,38872,38873,38877,38878,38880,38875,38881,38884,38895,38897,38900, +38903,38904,38906,38919,38922,38937,38925,38926,38932,38934,38940,38942,38944, +38947,38950,38955,38958,38959,38960,38962,38963,38965,38949,38974,38980,38983, +38986,38993,38994,38995,38998,38999,39001,39002,39010,39011,39013,39014,39018, +39020,39083,39085,39086,39088,39092,39095,39096,39098,39099,39103,39106,39109, +39112,39116,39137,39139,39141,39142,39143,39146,39155,39158,39170,39175,39176, +39185,39189,39190,39191,39194,39195,39196,39199,39202,39206,39207,39211,39217, +39218,39219,39220,39221,39225,39226,39227,39228,39232,39233,39238,39239,39240, +39245,39246,39252,39256,39257,39259,39260,39262,39263,39264,39323,39325,39327, +39334,39344,39345,39346,39349,39353,39354,39357,39359,39363,39369,39379,39380, +39385,39386,39388,39390,39399,39402,39403,39404,39408,39412,39413,39417,39421, +39422,39426,39427,39428,39435,39436,39440,39441,39446,39454,39456,39458,39459, +39460,39463,39469,39470,39475,39477,39478,39480,39495,39489,39492,39498,39499, +39500,39502,39505,39508,39510,39517,39594,39596,39598,39599,39602,39604,39605, +39606,39609,39611,39614,39615,39617,39619,39622,39624,39630,39632,39634,39637, +39638,39639,39643,39644,39648,39652,39653,39655,39657,39660,39666,39667,39669, +39673,39674,39677,39679,39680,39681,39682,39683,39684,39685,39688,39689,39691, +39692,39693,39694,39696,39698,39702,39705,39707,39708,39712,39718,39723,39725, +39731,39732,39733,39735,39737,39738,39741,39752,39755,39756,39765,39766,39767, +39771,39774,39777,39779,39781,39782,39784,39786,39787,39788,39789,39790,39795, +39797,39799,39800,39801,39807,39808,39812,39813,39814,39815,39817,39818,39819, +39821,39823,39824,39828,39834,39837,39838,39846,39847,39849,39852,39856,39857, +39858,39863,39864,39867,39868,39870,39871,39873,39879,39880,39886,39888,39895, +39896,39901,39903,39909,39911,39914,39915,39919,39923,39927,39928,39929,39930, +39933,39935,39936,39938,39947,39951,39953,39958,39960,39961,39962,39964,39966, +39970,39971,39974,39975,39976,39977,39978,39985,39989,39990,39991,39997,40001, +40003,40004,40005,40009,40010,40014,40015,40016,40019,40020,40022,40024,40027, +40029,40030,40031,40035,40041,40042,40028,40043,40040,40046,40048,40050,40053, +40055,40059,40166,40178,40183,40185,40203,40194,40209,40215,40216,40220,40221, +40222,40239,40240,40242,40243,40244,40250,40252,40261,40253,40258,40259,40263, +40266,40275,40276,40287,40291,40290,40293,40297,40298,40299,40304,40310,40311, +40315,40316,40318,40323,40324,40326,40330,40333,40334,40338,40339,40341,40342, +40343,40344,40353,40362,40364,40366,40369,40373,40377,40380,40383,40387,40391, +40393,40394,40404,40405,40406,40407,40410,40414,40415,40416,40421,40423,40425, +40427,40430,40432,40435,40436,40446,40458,40450,40455,40462,40464,40465,40466, +40469,40470,40473,40476,40477,40570,40571,40572,40576,40578,40579,40580,40581, +40583,40590,40591,40598,40600,40603,40606,40612,40616,40620,40622,40623,40624, +40627,40628,40629,40646,40648,40651,40661,40671,40676,40679,40684,40685,40686, +40688,40689,40690,40693,40696,40703,40706,40707,40713,40719,40720,40721,40722, +40724,40726,40727,40729,40730,40731,40735,40738,40742,40746,40747,40751,40753, +40754,40756,40759,40761,40762,40764,40765,40767,40769,40771,40772,40773,40774, +40775,40787,40789,40790,40791,40792,40794,40797,40798,40808,40809,40813,40814, +40815,40816,40817,40819,40821,40826,40829,40847,40848,40849,40850,40852,40854, +40855,40862,40865,40866,40867,40869, +}; + +static const struct dbcs_index jisx0212_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0212_decmap+0,47,113},{0,0,0},{ +0,0,0},{0,0,0},{__jisx0212_decmap+67,97,124},{__jisx0212_decmap+95,66,126},{0, +0,0},{__jisx0212_decmap+156,33,80},{__jisx0212_decmap+204,33,119},{ +__jisx0212_decmap+291,33,119},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__jisx0212_decmap+378,33,126},{__jisx0212_decmap+472,33,126},{ +__jisx0212_decmap+566,33,126},{__jisx0212_decmap+660,33,126},{ +__jisx0212_decmap+754,33,126},{__jisx0212_decmap+848,33,126},{ +__jisx0212_decmap+942,33,126},{__jisx0212_decmap+1036,33,126},{ +__jisx0212_decmap+1130,33,126},{__jisx0212_decmap+1224,33,126},{ +__jisx0212_decmap+1318,33,126},{__jisx0212_decmap+1412,33,126},{ +__jisx0212_decmap+1506,33,126},{__jisx0212_decmap+1600,33,126},{ +__jisx0212_decmap+1694,33,126},{__jisx0212_decmap+1788,33,126},{ +__jisx0212_decmap+1882,33,126},{__jisx0212_decmap+1976,33,126},{ +__jisx0212_decmap+2070,33,126},{__jisx0212_decmap+2164,33,126},{ +__jisx0212_decmap+2258,33,126},{__jisx0212_decmap+2352,33,126},{ +__jisx0212_decmap+2446,33,126},{__jisx0212_decmap+2540,33,126},{ +__jisx0212_decmap+2634,33,126},{__jisx0212_decmap+2728,33,126},{ +__jisx0212_decmap+2822,33,126},{__jisx0212_decmap+2916,33,126},{ +__jisx0212_decmap+3010,33,126},{__jisx0212_decmap+3104,33,126},{ +__jisx0212_decmap+3198,33,126},{__jisx0212_decmap+3292,33,126},{ +__jisx0212_decmap+3386,33,126},{__jisx0212_decmap+3480,33,126},{ +__jisx0212_decmap+3574,33,126},{__jisx0212_decmap+3668,33,126},{ +__jisx0212_decmap+3762,33,126},{__jisx0212_decmap+3856,33,126},{ +__jisx0212_decmap+3950,33,126},{__jisx0212_decmap+4044,33,126},{ +__jisx0212_decmap+4138,33,126},{__jisx0212_decmap+4232,33,126},{ +__jisx0212_decmap+4326,33,126},{__jisx0212_decmap+4420,33,126},{ +__jisx0212_decmap+4514,33,126},{__jisx0212_decmap+4608,33,126},{ +__jisx0212_decmap+4702,33,126},{__jisx0212_decmap+4796,33,126},{ +__jisx0212_decmap+4890,33,126},{__jisx0212_decmap+4984,33,126},{ +__jisx0212_decmap+5078,33,126},{__jisx0212_decmap+5172,33,126},{ +__jisx0212_decmap+5266,33,126},{__jisx0212_decmap+5360,33,126},{ +__jisx0212_decmap+5454,33,126},{__jisx0212_decmap+5548,33,126},{ +__jisx0212_decmap+5642,33,126},{__jisx0212_decmap+5736,33,126},{ +__jisx0212_decmap+5830,33,126},{__jisx0212_decmap+5924,33,126},{ +__jisx0212_decmap+6018,33,126},{__jisx0212_decmap+6112,33,99},{0,0,0},{0,0,0}, +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const DBCHAR __jisxcommon_encmap[22016] = { +8512,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41527, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41538, +8561,8562,41584,N,41539,8568,8495,41581,41580,N,8780,N,41582,41524,8555,8542, +N,N,8493,N,8825,N,41521,N,41579,N,N,N,N,41540,43554,43553,43556,43562,43555, +43561,43297,43566,43570,43569,43572,43571,43584,43583,43586,43585,N,43600, +43602,43601,43604,43608,43603,8543,43308,43619,43618,43621,43620,43634,43312, +43342,43810,43809,43812,43818,43811,43817,43329,43822,43826,43825,43828,43827, +43840,43839,43842,43841,43331,43856,43858,43857,43860,43864,43859,8544,43340, +43875,43874,43877,43876,43890,43344,43891,43559,43815,43557,43813,43560,43816, +43563,43819,43564,43820,43567,43823,43565,43821,43568,43824,43298,43330,43575, +43831,N,N,43574,43830,43576,43832,43573,43829,43578,43834,43579,43835,43581, +43837,43580,N,43582,43838,43300,43332,43591,43847,43589,43845,N,N,43590,43846, +43588,43333,43302,43334,43592,43848,43593,43849,43335,43594,43850,43596,43852, +43595,43851,43305,43337,43304,43336,43597,43853,43599,43855,43598,43854,43338, +43307,43339,43607,43863,N,N,43606,43862,43309,43341,43609,43865,43611,43867, +43610,43866,43612,43868,43613,43869,43615,43871,43614,43870,43617,43873,43616, +43872,43311,43343,43628,43884,43625,43881,43622,43878,43627,43883,43624,43880, +43626,43882,43633,43889,43636,43892,43635,43637,43893,43639,43895,43638,43894, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +43558,43814,43587,43843,43605,43861,43623,43879,43632,43888,43629,43885,43631, +43887,43630,43886,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43833,41520, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41519,41522,41526,41525,N,41523,41528,41529, +42593,N,42594,42595,42596,N,42599,N,42601,42604,42614,9761,9762,9763,9764, +9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,N,9778,9779, +9780,9781,9782,9783,9784,42597,42602,42609,42610,42611,42612,42619,9793,9794, +9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809, +42616,9810,9811,9812,9813,9814,9815,9816,42613,42618,42615,42617,42620,10023, +42818,42819,42820,42821,42822,42823,42824,42825,42826,42827,42828,N,42829, +42830,10017,10018,10019,10020,10021,10022,10024,10025,10026,10027,10028,10029, +10030,10031,10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042, +10043,10044,10045,10046,10047,10048,10049,10065,10066,10067,10068,10069,10070, +10072,10073,10074,10075,10076,10077,10078,10079,10080,10081,10082,10083,10084, +10085,10086,10087,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097, +N,10071,42866,42867,42868,42869,42870,42871,42872,42873,42874,42875,42876,N, +42877,42878,8510,N,N,N,N,8509,8514,N,8518,8519,N,N,8520,8521,N,N,8823,8824,N, +N,N,8517,8516,N,N,N,N,N,N,N,N,N,8819,N,8556,8557,N,N,N,N,N,N,N,8744,8558,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41585,N,N,N,N,N,N,N,N,N,N,N,41583,N,N,N,N,N,N, +N,N,8818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8747,8748,8746,8749,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8781,N,8782,8783,N,8799,8784,N,N,N, +8800,8762,N,N,8763,N,N,N,N,N,N,8541,N,N,N,N,N,N,N,8805,N,N,8807,8551,N,8796,N, +N,N,N,N,N,8778,8779,8769,8768,8809,8810,N,N,N,N,N,N,N,8552,8808,N,N,N,N,N,N,N, +8806,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8802,N,N,N,N,N,N,N,N,N,N,N,N,N, +8546,8801,N,N,N,N,8549,8550,N,N,8803,8804,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,8766,8767,N,N,8764,8765,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,8797,8798,10273,10284,10274,10285,N,N,N,N,N,N,N,N,10275,N,N,10286, +10276,N,N,10287,10278,N,N,10289,10277,N,N,10288,10279,10300,N,N,10295,N,N, +10290,10281,10302,N,N,10297,N,N,10292,10280,N,N,10296,10301,N,N,10291,10282,N, +N,10298,10303,N,N,10293,10283,N,N,10299,N,N,10304,N,N,N,N,N,N,N,N,10294,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,8739,8738,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8741,8740,N,N,N,N,N,N,N,N, +8743,8742,N,N,N,N,N,N,N,N,8737,8574,N,N,N,8571,N,N,8573,8572,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8830,8570,8569,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,8554,N,8553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8822,N,N,8821,N,8820,8481,8482,8483,8503,N, +8505,8506,8507,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8745,8750, +8524,8525,N,N,N,N,N,N,8513,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259, +9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274, +9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289, +9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304, +9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319, +9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,N,N,N,N,N,N,N, +8491,8492,8501,8502,N,N,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514, +9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529, +9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544, +9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559, +9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574, +9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589, +9590,N,N,N,N,8486,8508,8499,8500,12396,17274,45089,15415,45090,45091,N,19324, +15974,15152,15973,12860,45092,18772,19775,N,20514,12591,45093,N,13166,20515, +16420,21058,13654,19002,N,N,N,N,15975,45094,N,20030,N,45095,45096,N,19010,N, +45097,N,20516,45098,N,17254,45099,45100,45101,20517,13946,N,N,45102,20518,N, +13405,17200,N,15463,20519,N,N,20520,45103,45104,20521,18229,45105,13655,N, +45106,N,N,N,18231,N,18019,14403,19251,N,45107,N,N,N,26953,20522,15976,20523, +12853,45108,N,45109,13925,14448,19561,N,N,22054,45110,N,N,N,N,45111,45112,N,N, +N,N,N,N,N,19824,N,18045,45113,45114,N,N,N,45115,N,N,N,N,13349,45116,13621,N, +20524,N,N,20525,20027,N,19773,16744,20527,15222,18035,45117,20530,N,N,12606, +14431,N,14430,12390,45118,45119,20299,20298,N,14899,12321,45120,20531,20532, +20533,19252,20534,N,14450,12391,19314,N,13692,N,N,13693,13694,17506,20028, +45121,20535,N,N,20536,N,N,20537,N,N,45122,16205,N,N,N,N,N,15674,16206,20542, +45123,20540,N,20541,13656,N,N,14883,12912,N,20539,20538,18985,45124,N,N,N, +15174,15173,16958,20543,18773,16487,45125,45126,N,8504,20544,20546,45127, +45128,45129,16997,20065,12362,N,N,45130,N,N,N,N,20545,12862,45131,13892,45132, +17255,45133,N,45134,14191,20547,N,N,N,18212,N,45135,45136,45137,45138,13419, +45139,45140,N,N,N,N,45141,20548,12363,45142,45143,14432,13420,18810,18482, +13657,45144,N,N,45145,45146,45147,N,45148,12913,N,20583,17729,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,45149,18284,20550,45150,N,45152,18492,45153,20066,45154,16173, +45155,15175,45156,15223,12864,45157,N,45158,N,45159,17489,N,N,17186,20554, +45160,45161,N,45162,45163,12364,17507,15675,14900,19748,45164,16974,45165, +12863,45166,20553,45167,19774,20549,20551,14958,20552,21796,45168,45151,N,N, +45169,N,N,N,N,N,20560,45170,N,45171,N,45172,20563,20561,45173,N,12866,N,19003, +20555,45174,45175,45176,45177,20559,14451,45178,45179,15176,N,45180,45181, +13350,45182,45345,20564,N,20556,45346,45347,20067,45348,15224,45349,20557, +45350,20562,45351,45352,45353,N,20565,45354,20558,45355,45356,13857,N,12365, +45357,45358,13858,12865,N,N,N,N,N,N,N,N,N,21797,N,19321,18798,14452,N,N,45359, +N,N,16175,20023,45360,N,45361,N,45362,45363,45364,45365,19032,45366,45367, +14136,16933,12900,45368,45369,N,45370,45371,15699,45372,45373,45374,20569, +45375,20574,20572,45376,N,20567,N,N,16943,20570,N,20573,20571,45377,19037,N, +20568,45378,16174,45379,19315,20575,20576,N,N,N,N,N,N,N,N,15652,20589,45380,N, +45381,18256,N,18742,20584,N,19056,N,12854,N,45382,45383,20588,45384,45385, +45386,N,N,45387,20582,20591,45388,N,16722,45389,14404,45390,18268,45391,24647, +45392,20590,17757,45393,20579,N,14454,45394,45395,14453,20577,45396,45397, +45398,45399,15450,N,20585,45400,19055,17229,20581,14193,45401,20578,20586, +20580,20049,20587,20289,45402,N,45403,N,45404,45405,N,45406,13926,N,N,14192,N, +45430,N,N,N,N,45407,45408,45409,20592,N,45410,45411,20593,20597,12366,45412,N, +45413,N,45414,19024,20596,45415,45416,45417,N,20595,20599,45418,N,45419,20598, +N,17508,N,N,45420,45421,N,45422,45423,N,14194,45424,45425,N,N,45426,N,20600, +45427,N,N,45428,45429,15429,N,16934,17509,13942,N,20601,N,N,N,N,13622,N,N, +20602,45431,N,45432,45433,20604,45434,N,N,N,45435,N,N,19253,45436,45437,45438, +14182,45601,45602,45603,N,45604,N,15153,18551,20603,45605,45606,N,45607,45608, +45609,45610,45611,N,N,N,N,N,N,N,45612,N,14917,19779,N,45613,45614,N,20606, +20771,20605,14916,N,15741,N,45615,45616,N,N,45617,14137,N,45618,N,20772,45619, +45620,13903,N,45621,N,20769,20770,N,45622,17967,45623,16764,45624,13859,N, +45625,45626,19277,20773,N,45627,N,20029,N,45628,45629,20774,45630,N,N,45631, +20777,45632,20775,45633,16718,45634,45635,N,N,N,20776,20778,45636,N,45637, +45649,N,N,20780,45638,N,N,20779,45639,19016,N,N,45640,13623,20782,20783,45641, +12847,N,45642,45643,45644,20781,N,45645,45646,45647,45648,N,45650,N,15476,N, +20786,20785,20784,45651,20566,45652,20787,45653,45654,45655,45656,15742,N, +20788,N,45657,N,N,N,45658,45659,N,19749,N,45660,45661,N,45662,N,45663,19545, +45664,45665,45666,N,20790,45667,45668,20789,20792,20791,N,N,20793,20794,12404, +45669,14389,14139,15676,17275,13860,16488,14455,45670,14702,20796,19528,17734, +45671,15225,N,20795,45672,20797,45673,N,45674,45675,N,17758,N,13173,N,N,45676, +N,N,20798,N,45677,18046,45678,N,16692,20800,20801,18476,14456,20283,20802,N,N, +13862,N,N,N,19004,16950,13937,17717,N,N,N,14195,N,45679,N,20803,N,20804,45680, +45681,18018,12639,N,N,20807,14973,45682,20806,14918,45683,20808,26222,20809, +19265,20810,N,20811,20812,15977,45684,15436,N,N,N,45685,N,N,13351,45686,20815, +45687,20813,19517,20814,N,18778,20816,20817,20818,17759,45688,N,N,20822,20820, +20821,20819,14947,20823,19562,20068,45689,N,45690,N,45691,20824,45692,45693,N, +N,45694,N,16424,20825,15706,N,45857,20826,N,17276,20031,17760,N,45858,N,45859, +45860,45861,N,45862,21061,N,45863,N,N,20827,29733,13893,45864,N,20828,19294, +45865,N,N,45866,15720,17020,N,20830,18020,N,N,20831,45867,N,20832,13102,45868, +45869,45870,20833,13863,45871,17996,12666,15696,N,N,18465,20834,17761,45872, +45873,16207,20835,45874,18988,16474,13346,N,13353,20836,N,N,20838,N,N,14138, +45875,45876,20837,45877,45878,20083,45879,N,N,N,N,15721,N,N,N,N,45880,N,18493, +19020,N,20839,45881,19832,20840,N,N,N,20841,N,17790,45882,45883,20842,N,45884, +16425,14974,14196,20843,15177,14703,45885,N,N,N,N,N,N,17510,20845,45886,N, +16935,N,45887,14959,20846,20847,16688,N,20844,N,N,N,N,20849,45888,19254,45889, +45890,N,45891,14692,45892,N,20848,45893,45894,45895,N,14197,14942,18285,45896, +N,N,20852,20850,N,N,N,45897,18811,15978,20859,13156,20853,20851,16719,N,45898, +45899,45900,N,N,N,20855,N,20854,45901,N,45902,13124,N,45903,N,14176,20860, +20013,45904,N,45905,20856,N,N,N,20861,20858,45906,20857,45907,45908,45909, +45910,N,45911,20047,45912,N,N,14457,12867,N,N,20084,45913,45914,45915,45916,N, +15733,17752,14693,21026,21027,N,45917,45918,20069,N,N,20267,21029,45919,45920, +45921,14458,45922,45923,21028,45924,13103,N,45925,21030,N,19286,45926,17468, +45927,19750,45928,19033,N,N,45929,21031,N,45930,N,45931,28757,N,45932,17968, +45933,21032,13354,19507,N,45934,45935,15905,21033,19047,21037,45936,16426, +21034,13904,45937,21035,13355,45938,45939,45940,N,45941,N,N,N,45942,45943, +14126,21038,45944,21039,45945,45946,21040,21041,15451,N,N,N,14459,19550,45947, +19560,18039,45948,N,19057,21042,N,21043,N,45949,45950,46113,21045,N,21047, +21046,46114,N,46115,N,21048,12861,19276,46116,14972,21049,46117,46118,16729, +46119,46120,15906,13865,N,21050,N,46121,N,46122,46123,46124,18523,46125,46126, +46127,N,21051,46128,21052,46129,21053,N,46130,N,N,21054,18724,13928,12389, +46131,46132,46133,17983,21055,15677,46134,16489,N,21057,21056,15907,14433, +21059,18494,46136,46135,21060,N,N,N,18524,16948,17006,13864,N,N,18030,17201, +46137,18286,46138,19278,N,21062,N,16490,46139,N,46140,N,46141,14133,N,N,21063, +N,N,46142,46143,21064,12588,12405,13421,46144,16936,13649,19825,N,21067,12855, +46145,N,21066,N,N,46146,13866,N,N,21068,46147,19569,N,N,46148,46149,N,N,N,N,N, +46150,N,N,N,N,46151,46152,N,21069,N,20050,46153,14460,N,N,46154,N,14390,21070, +46155,N,N,46156,21072,21071,N,16223,12601,46157,46158,N,12638,21073,46159, +21074,N,46160,14391,46161,46162,21075,46163,46164,N,46165,13678,N,46166,N,N, +46167,N,15154,21076,N,46168,N,N,19316,14901,13658,19751,16720,18495,15485, +46169,N,N,46170,46171,15687,46172,15464,15477,N,15734,46173,18496,N,46174, +46175,21079,46176,12611,16721,14461,14405,13927,46177,46178,21083,17185,17022, +13867,15908,21084,21082,12868,16998,15416,15179,12582,N,46179,13168,14694, +15178,N,21085,21086,46180,13641,13126,N,N,N,14695,13640,17503,12581,17969, +19518,14625,19833,17735,14462,N,46181,N,N,N,N,N,N,46182,14127,N,21095,N,13923, +19274,46183,N,N,N,N,18525,46184,46185,21094,46186,13406,21089,21090,21092, +46187,N,46188,N,N,46189,46190,21093,N,13659,16225,N,18989,21091,21087,14435,N, +21088,N,20260,46191,46192,N,19058,46193,17512,14434,14704,N,N,46194,21096, +46195,N,18013,N,N,N,N,N,N,N,N,N,N,N,N,46196,21100,N,N,46197,N,46198,N,46199, +46200,15486,46201,15478,46202,N,46203,46204,N,21103,21101,N,19491,46205,21098, +21107,21102,N,N,N,21105,14406,19519,N,46206,21106,46369,N,46370,21108,46371, +21110,N,46372,46373,N,14960,20290,46374,21099,21097,21109,46375,21104,N,N, +46376,46377,N,N,N,N,N,46378,N,N,46379,N,46380,21112,N,21283,21114,46381,46382, +21118,46383,46384,21281,21115,46385,46386,21310,N,46387,14953,13105,N,N,N, +46388,21113,46389,46390,46391,21285,12406,21284,46392,12325,18762,21282,N, +21116,N,46393,21111,21117,14920,46394,N,N,46395,46396,N,N,N,N,N,N,N,N,N,21286, +N,N,N,N,N,N,N,46397,12407,21295,N,N,21287,21288,N,15909,19305,46398,N,46399, +21293,21292,46400,N,N,17711,N,N,N,46401,N,N,N,21294,N,46402,21291,46403,46404, +46405,46406,N,N,12596,46407,14902,16176,46408,46409,N,N,46410,46411,46412, +21289,17762,N,N,N,21290,46413,12322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +46414,46415,N,N,21300,19747,N,15911,46416,21306,N,46417,46418,N,21305,21296,N, +46419,46420,46421,16963,N,21297,46422,N,N,17007,21302,15910,46423,N,46424, +46425,N,21299,46426,N,19556,46427,46428,N,14140,N,N,21303,21304,46429,N,46430, +46431,21301,21307,46432,N,46433,46434,N,21298,46435,N,46436,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,21313,21318,N,21314,46437,21309,46438,46439,21319,16689, +N,46440,21321,46441,14626,21311,17277,N,N,46442,46443,N,46444,46445,46446, +46447,N,N,46448,21315,21308,13357,N,13422,13157,21316,21312,N,N,N,46449,46450, +N,N,14198,21322,21320,16723,13642,13868,46451,21317,N,13940,N,46452,N,N,N, +12612,N,N,N,N,N,N,N,N,46453,N,46454,N,46455,21326,21324,46456,21543,N,46457,N, +46458,46459,N,46460,N,N,46461,46462,46625,21329,N,N,46626,46627,N,21323,46628, +21327,N,46629,21325,N,N,46630,15180,21328,N,N,N,N,46631,N,N,N,N,N,N,N,N,N,N,N, +N,46632,21331,N,21336,N,N,N,21334,21333,46633,46634,17202,N,46635,12869,46636, +N,N,46637,46638,46639,46640,46641,46642,N,21330,N,21332,15912,12595,46643,N, +21335,N,N,N,N,N,N,N,N,N,N,N,N,N,12894,N,N,46644,N,N,21346,46645,15996,21342, +46646,21340,46647,21341,46648,21343,46649,N,46650,46651,46652,N,46653,46654, +46655,12605,46656,46657,N,46658,N,N,46659,N,46660,16697,46661,21337,46662, +21338,N,N,N,46663,N,N,N,N,N,N,13178,N,N,46664,N,46665,46666,46667,46668,21345, +N,46669,N,13423,46670,21348,21344,21347,46671,N,46672,N,46673,46674,N,18990, +46675,N,N,18005,N,18488,N,N,N,N,N,21350,N,N,N,46676,46677,21349,13125,46678,N, +21351,46679,46680,N,N,21354,N,N,N,N,21353,46681,N,N,N,46682,46683,N,N,46684, +46685,46686,21352,N,18233,N,N,21355,46687,46688,46689,46690,N,46691,46692, +46693,21356,N,N,46694,N,46695,21358,N,21357,46696,N,N,N,N,21360,N,46697,N, +21363,21361,21359,21362,N,46698,N,N,21364,46699,46700,46701,46704,46705,21365, +46702,46703,21366,N,21367,N,N,N,21368,20805,46706,15484,15181,46707,46708, +12915,46709,12408,46710,N,17220,46711,46712,46713,46714,46715,N,N,46717,N, +46718,21369,N,14884,46716,12367,16222,N,N,46881,46882,N,21370,14407,N,N,14705, +N,21372,21371,46883,46884,19040,21373,N,N,46885,21537,21374,46886,21538,46887, +21539,N,14199,N,46888,12640,21540,N,46889,21542,N,21541,N,46890,46891,21544, +46892,N,17754,46893,N,46894,46895,46896,46897,21545,12341,14943,46898,46899,N, +46900,14141,46901,46902,17231,N,N,46903,46904,N,N,21546,21547,N,N,21549,N, +46905,46906,46907,21550,N,14948,N,N,46908,46909,13905,N,N,19255,N,46910,46911, +21548,21551,14913,14627,46912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21555,46913,N,14885, +46914,17203,46915,46916,21552,17498,46917,N,46918,46919,46920,46921,46922,N, +46923,46924,46925,N,46926,N,46927,46928,46929,46930,N,46931,21556,N,46932, +16226,46933,N,N,N,N,21554,21557,N,14143,46934,N,N,N,N,N,N,21558,46935,46944,N, +46936,N,46937,46938,N,46939,46940,46941,46942,21559,46943,14628,13120,21561,N, +N,46945,46946,46947,21562,N,46948,N,N,N,21563,N,N,21560,N,N,N,N,46949,N,N,N,N, +46950,N,N,21553,N,N,21564,N,N,21565,46951,46952,N,N,19300,46953,N,15979,46954, +N,N,21567,21568,21566,46955,21570,N,N,N,N,N,18232,46956,46957,12392,18774, +46974,N,21571,46958,N,46959,46960,N,46961,N,N,N,46962,N,N,46963,N,N,N,15997, +46964,46965,15417,46966,18269,13424,N,14955,46967,46968,46969,19289,N,17970, +46970,46971,14200,16975,N,46972,46973,21569,21572,47137,47138,N,N,N,N,N,N,N, +16964,N,N,N,21573,N,47139,N,21574,47140,47141,47142,21576,N,N,17513,N,47143, +47144,N,N,13358,N,N,47145,N,29729,12641,19059,47146,N,15980,17736,N,N,N,47147, +14950,N,N,21582,N,47148,19005,20061,N,N,N,N,N,N,N,47149,12916,21578,47150, +47151,N,47152,47153,16698,21581,N,17763,47154,N,17737,17764,18489,17485,N,N,N, +14921,47155,N,47156,21577,N,47157,N,N,47158,47159,12662,N,17718,N,N,N,N,21579, +N,21575,N,N,16208,N,N,47160,21583,N,N,47161,N,15694,47162,47163,47164,N,13869, +N,21584,N,47165,47166,47167,47168,N,47169,47170,N,47171,47172,N,N,19048,47173, +N,47174,16765,N,N,N,N,17478,47175,N,21586,47176,47177,47178,N,N,N,47179,N, +19279,47180,N,21587,N,N,21592,N,N,47181,47182,18991,N,N,N,N,21591,21585,21588, +21590,47184,N,14886,N,N,19017,47185,N,47183,21593,N,17221,47186,N,12917,N, +15981,47187,47188,N,47189,21595,47190,21594,47191,14696,47192,21596,21598, +21597,47193,N,21600,47194,21589,21602,N,47195,47196,N,21601,21599,N,N,N,47197, +N,15182,16209,N,16724,21603,16444,12397,18276,47198,N,N,N,17499,N,21605,21604, +21606,21607,21608,21609,N,N,47199,47200,N,N,19025,21610,47201,47202,N,N,12870, +21611,N,47203,47204,47205,19772,13104,N,21065,15688,16959,21612,19563,47207,N, +N,N,47208,19508,47209,47210,21614,N,16999,47211,17719,16960,18775,21615,21616, +12667,47212,47213,15418,21617,47214,N,47215,47216,12368,21618,N,N,N,N,N,21619, +47217,N,N,N,47218,12642,N,47219,13425,18016,19060,N,N,N,N,21623,16725,21622, +14144,47220,47221,19291,21621,N,17765,21625,47222,21624,47223,N,47224,47225, +47226,21627,47227,21626,47228,N,12668,N,21628,15913,21630,17189,47229,21629, +47230,18995,47393,N,N,47394,15735,17755,47395,47396,N,21793,47397,N,47398, +47399,14629,N,N,N,21794,18209,18526,19537,N,N,N,N,N,18213,47400,47401,21803, +47402,N,N,N,47403,13624,N,47404,19781,47405,N,19503,N,22060,N,21795,N,47406,N, +N,N,21798,47407,16965,N,47408,19256,N,N,N,17738,47409,47410,47411,47412,N, +21799,47413,N,N,N,47414,N,19301,47415,14922,47416,N,15914,N,N,47417,N,47418, +47419,N,21800,N,47420,15184,47421,15183,N,47422,N,N,12345,14408,47423,16427, +12369,N,N,N,N,21804,21805,N,21802,47424,47425,47426,N,N,N,47427,47428,12600, +13359,47429,21801,N,19525,18737,N,N,47430,47431,N,47432,47433,N,47434,N,12328, +47435,N,N,N,12409,N,N,N,15185,47436,12370,N,12323,47437,N,N,N,N,21810,N,N, +47438,47439,47440,N,N,21808,47441,47442,N,N,N,N,19516,N,21811,N,21809,N,47443, +21807,16177,N,N,47444,47445,21806,N,47446,47447,19034,47448,N,N,47449,N,14436, +47450,N,N,N,N,21815,21816,N,N,N,N,N,15915,N,N,N,21812,20268,N,N,47451,47452, +18252,47453,47454,21814,N,N,47455,N,N,N,47456,N,N,N,N,47457,N,N,N,N,14887,N,N, +N,47458,N,N,N,21817,47459,N,47460,18776,47461,N,N,21818,N,21813,47462,N,N,N,N, +N,N,N,N,N,47463,N,N,47464,47465,N,N,47466,19515,N,N,N,N,N,N,N,N,N,N,N,47467,N, +N,N,N,47468,N,18270,47469,N,N,47470,N,N,47471,21819,18738,47472,N,47473,47474, +47475,N,47476,N,N,N,N,47477,N,N,N,N,47478,N,N,N,N,47479,47480,47481,N,47482,N, +N,47483,N,47484,47485,21820,21824,21821,47486,N,12871,21823,N,47649,N,47650,N, +47651,15419,N,21822,14201,N,N,47652,21836,N,N,N,N,N,21829,21826,N,N,47653,N, +47654,N,N,N,47655,17252,N,21825,N,47656,21827,N,N,21828,47657,N,N,N,47658,N,N, +N,N,N,N,47659,47660,N,N,N,21830,21831,N,47661,47662,47663,N,N,N,N,N,N,47664, +13426,N,21833,21832,N,N,N,N,N,N,N,N,N,21834,47665,N,47667,N,47668,N,47669,N,N, +N,47670,15982,N,N,47671,N,N,N,N,21837,N,17500,47672,N,N,12613,N,21835,N,47666, +N,21838,N,47673,N,N,N,N,N,21839,N,21842,47674,N,21840,N,21841,N,N,N,N,N,47675, +47676,N,N,N,15186,21843,47677,N,14630,21844,47678,15226,16952,N,21845,21846, +15194,14631,47679,19538,N,N,N,13608,14409,21847,13144,N,47680,21848,N,16953,N, +N,47681,47682,21849,22051,N,21850,N,21851,N,N,21852,N,21854,N,47683,47684, +47685,47686,21855,47687,N,21856,47688,17008,47689,12583,15465,12354,47690, +16727,13360,15413,47691,14632,47692,47693,N,47694,47695,17766,47696,15649, +13361,17256,17514,12344,13625,19061,N,15426,N,N,13650,16491,15420,19752,21857, +N,47697,47698,N,N,47699,47700,13660,47701,14923,47702,47703,13106,12643,15916, +12872,47704,21858,19782,47705,N,47706,N,N,15689,47707,47708,15460,21859,13427, +18002,19497,21860,N,21861,N,N,18777,47709,N,47710,21863,N,13352,13943,21862,N, +47711,47712,47713,47714,47715,13362,N,16178,21867,15137,47716,12873,21866,N, +21864,21868,21865,18219,23629,16179,N,21869,N,N,20032,47717,21870,47718,N, +21872,47719,17278,21871,N,16419,N,15227,N,N,47720,16976,15479,18805,16492,N, +15437,21873,15917,21874,21875,12371,16954,16210,47721,21876,17971,15918,N, +15919,N,21877,N,N,16493,47722,N,N,15920,N,N,N,47723,47724,21878,N,21879,47725, +19552,N,47726,N,21880,47727,N,47728,47729,13894,47730,N,47731,15650,47732,N,N, +47733,47734,N,21881,21882,15452,16172,18036,16212,18552,18210,13897,21883,N,N, +N,13679,21884,N,13950,N,17999,12848,N,15187,21885,22050,22049,13949,N,21886,N, +17720,N,N,N,47735,47736,N,47737,N,16944,N,17739,15432,47738,47739,16728,19834, +N,47740,47741,47742,N,N,22052,47905,22053,18006,47906,15155,N,N,47907,47908, +22055,N,N,22056,47909,47910,47911,47912,N,N,N,N,N,N,N,N,N,47913,47914,N,47915, +N,22057,N,N,47916,13428,22058,47917,N,22059,N,N,N,N,N,N,N,N,47918,N,47919, +47920,12844,47921,47922,N,N,47923,N,16699,13412,47924,22061,19496,N,N,N,N, +16978,47925,13145,47926,47927,22063,22065,13407,N,47928,22062,22064,N,22067,N, +N,N,N,N,N,22066,N,22068,N,47929,N,47930,N,N,N,N,N,N,47931,N,N,N,N,47933,N, +22069,N,N,N,47932,N,N,17981,13870,N,N,N,N,N,N,12901,22070,22075,N,N,22073, +47934,19063,19062,47935,47936,N,47937,N,17767,N,N,N,22072,15700,N,22071,47938, +N,N,N,N,47939,16242,N,N,N,22076,N,47940,14954,N,N,22082,47941,N,22083,22077, +13107,22078,22087,22086,22085,22081,N,N,N,22080,N,N,22084,47943,47944,N,47945, +47946,N,19064,N,47942,N,N,N,N,N,47947,N,N,47948,N,N,N,N,47949,N,N,N,47950,N, +47951,N,N,47952,47953,N,N,47954,N,47955,N,47959,22091,22088,N,22090,N,19826, +47957,22089,N,N,47956,N,N,N,47958,N,N,22079,N,N,47960,47961,47962,47963,N, +47964,N,N,N,N,16243,47965,N,22092,47966,N,14903,47967,N,N,22093,N,N,22094,N,N, +47968,47969,N,N,N,47970,47971,N,47972,22097,47973,22096,N,N,22095,47974,N, +47975,17768,22074,N,N,N,22103,N,47976,47977,47978,47979,N,N,N,47980,N,47981,N, +22099,N,47982,47983,N,22098,N,N,N,N,47984,N,N,N,47985,22100,N,22101,N,47986,N, +58996,N,47987,N,N,22104,47988,47989,20070,N,22105,22102,N,N,N,N,N,47990,N,N,N, +47991,N,22106,N,47992,13408,22107,47994,N,47993,N,22109,22108,N,N,22110,N, +47995,47996,N,22111,N,16494,15651,N,47997,15716,N,16739,47998,14633,14904, +14634,13680,48161,N,22112,N,N,14905,N,N,14410,22113,19494,18243,22114,N,14635, +48162,48163,N,13356,N,17191,13906,48164,N,15188,18779,N,N,18497,48165,N,N,N, +22115,13429,48166,N,N,N,22118,48167,N,48168,48169,17441,N,48170,22117,22116, +22119,N,17515,N,48171,48172,N,N,N,N,16227,N,N,48174,N,N,15189,N,16458,48173, +16979,13602,N,48175,17442,N,48176,22120,22121,15983,N,N,N,N,19257,48177,N, +22124,N,N,22123,22122,18813,N,22131,N,48180,N,48178,19290,N,22125,N,48179, +48181,N,N,22127,19307,48182,22126,48183,N,N,48184,48185,N,48186,22128,N,18472, +22129,19006,22130,N,N,N,48187,N,48188,48189,48190,48191,48192,N,48193,N,13363, +19007,18223,22132,22133,N,14636,13364,22134,14392,19780,19753,13430,22136, +48194,17443,N,14637,15921,N,N,18527,N,N,15922,48195,N,N,48196,15736,N,N,N,N,N, +17516,19065,17721,N,N,14638,N,18780,N,N,N,22137,N,48197,N,48198,48199,17753, +14914,48200,N,48201,14411,48202,17517,N,N,N,48203,N,48204,N,12355,15726,14639, +19783,N,N,N,N,48205,48206,48207,N,22138,22139,18257,N,N,48208,N,22140,20087, +20269,48210,48209,N,48211,22142,22141,48212,48213,13127,48214,48215,22305,N,N, +N,22308,22309,48216,22307,48217,18752,15923,22311,22310,22306,N,48218,N,N, +22312,22313,N,48219,22314,N,N,N,22317,22315,N,22316,22318,N,12644,17518,22319, +N,14202,12918,18230,N,22320,18043,19035,48220,22321,20270,N,48221,48222,48223, +22322,19008,22325,20513,20529,48224,15408,18037,22326,N,13661,17444,12410, +22327,18982,14640,48225,N,17232,48226,48227,N,17519,N,48228,48229,48230,48231, +19567,14393,14412,48232,22328,N,48233,48234,22329,48235,22335,48236,15461,N,N, +48237,17445,48238,13871,22330,N,N,48239,18731,48240,17222,48241,48242,22331,N, +N,48243,48244,N,48245,22332,N,13872,N,22333,48246,22334,N,48247,22336,N,17782, +48248,N,22337,22338,48249,22339,N,48250,22324,22323,N,N,48251,22340,14145, +48252,48253,N,18727,48254,N,14924,18743,17446,18763,22341,N,48417,15924,12614, +48418,22342,48419,48420,N,22343,48421,19570,48422,N,18528,48423,48424,22346, +12669,16428,22345,22344,14146,16980,N,22350,22348,48425,22347,20007,14437, +48426,N,48427,15737,22349,17740,15678,N,N,48428,17984,22353,22352,N,N,48429, +48430,22351,N,22354,14438,48431,N,48434,N,N,48432,22355,18812,15707,48433, +48435,22356,18553,48436,48437,48438,N,17985,17447,N,N,N,48439,17712,N,N,22357, +13611,N,N,N,N,N,16180,48440,18732,N,48441,48442,48443,N,48444,13431,18214,N,N, +48445,48446,48447,48448,48449,N,22358,15190,19258,19259,N,N,12670,22363,48450, +N,17257,48451,48452,N,22360,N,N,N,48453,48454,48455,12919,48456,48457,48458, +48459,22573,22362,48460,48461,N,18224,48462,N,22361,N,48463,22359,48464,14714, +N,22365,48465,N,N,48466,N,N,48467,22371,22377,22369,N,17756,48468,48469,22374, +18781,48470,48471,22368,48472,22373,20071,15191,N,48473,16981,22366,N,N,48474, +13662,22376,16429,12645,22370,12920,22375,N,48475,N,13873,N,22372,N,48476,N, +48477,N,N,N,N,22378,N,N,N,N,N,48478,22380,22390,22388,N,N,22385,48479,48480, +48481,22384,20088,48482,22386,N,N,13874,48483,14641,N,48484,15738,48485,48486, +N,22393,22379,N,N,48487,N,22383,22367,48488,12922,22387,22389,17233,N,48489, +14888,12856,22381,22392,22391,13875,N,16937,13158,48490,N,N,N,14147,N,22382,N, +N,N,N,N,N,48491,48492,N,22394,48493,22397,22561,N,48494,N,48495,15421,48496, +22567,17520,22395,48497,N,N,48498,22565,48499,12921,48500,22563,22564,48501,N, +22398,22562,N,48502,48503,14439,19754,N,48504,13365,48505,48506,12633,22566, +48507,18234,12333,N,N,N,N,N,48508,48509,18529,22364,22572,22576,19557,48510, +22569,N,N,48673,17769,22574,48674,N,N,N,48675,N,48676,15984,22575,18007,48677, +48678,48679,48680,N,N,48681,48682,N,20295,N,22571,48683,48684,N,N,22577,48685, +14715,48686,16459,48687,48688,12372,22570,22568,48689,16730,N,48690,N,22396, +15156,N,N,N,N,N,N,N,16966,22589,48691,16731,22584,48692,22581,22582,48693, +15462,22585,22588,48694,48695,22583,15653,48696,22586,N,N,22580,48697,19580, +19579,48698,N,48699,22590,22591,12373,48700,48701,48702,48703,48704,22579, +48705,48706,N,48707,13938,12326,48708,N,48709,13366,N,22587,48710,N,N,N,N, +22595,22594,N,48711,48712,22599,N,N,N,48713,48714,N,N,22600,48715,48716,48717, +N,48718,N,N,22598,22601,22593,22597,N,48719,22602,N,22603,48720,48721,22592, +15228,48722,22596,16982,14642,22578,16181,N,N,N,N,22616,N,19049,N,N,22606, +22607,22608,N,N,22615,48723,22614,48724,N,19325,13367,N,22612,N,14149,13108,N, +N,22609,48725,N,20024,22611,12374,22613,48726,22604,22610,22617,14148,22605, +48727,N,N,48728,48729,N,19805,48730,48731,48732,19755,48733,48734,N,N,22620,N, +N,22624,48735,N,48736,16766,N,20089,22625,48737,48738,22622,N,22619,48739, +48740,22618,22623,N,48741,48742,N,48743,48744,N,N,N,18992,48745,N,17972,48746, +14150,48747,22626,22621,48748,22627,N,N,N,14203,N,N,N,12849,N,48749,48750, +22635,N,48751,N,13368,N,48752,48753,48754,22633,N,N,22634,14889,22632,22630, +22629,22636,22628,22638,48755,48756,12923,N,N,N,N,48757,N,N,N,N,N,N,48758, +48759,48760,48761,N,48762,48763,22640,N,48766,22639,48764,N,48765,N,N,48929, +48930,N,48931,N,N,17448,N,22643,N,22641,22631,14204,N,22642,N,22646,22645, +22647,22644,22648,48932,N,48933,48934,N,N,48935,22649,22650,19050,N,22652, +22651,15679,N,16430,12902,12924,48936,22653,48937,12351,N,N,N,16460,22654, +48938,27715,22817,14177,48939,22818,48940,48941,N,N,16495,48942,N,48943,22819, +48944,N,N,22820,13626,22821,N,22822,22823,16983,N,N,N,14413,48945,N,19553,N, +48946,N,19260,15722,22824,48947,48948,48949,N,48950,16496,28221,18530,N,15466, +48951,14925,22825,N,48952,48953,48954,16967,48955,18983,48956,N,17009,N,48957, +22828,48958,N,22826,N,22829,N,N,22827,48959,N,N,N,22830,N,N,N,N,48960,18993, +48961,N,12343,N,48962,N,N,18782,N,N,18531,48963,N,22831,48964,22834,15925, +13627,N,22832,22839,15926,N,N,N,N,22833,18244,N,N,48965,48966,48967,48968, +19806,22835,22836,22840,17770,22837,14643,16478,N,N,22854,18484,N,17010,N,N,N, +N,N,N,N,48969,N,48970,N,N,18532,23085,N,N,N,N,19066,N,48971,N,17521,48972, +48973,N,19317,48974,22843,12833,17258,48975,48976,N,N,22852,N,48977,17204, +22846,22853,22848,22855,22851,N,22850,18287,48978,22844,12925,22842,13681, +17011,22838,48979,48980,22841,14644,16475,48981,15927,22849,18258,N,N,13682, +13128,N,N,N,N,N,N,N,N,48982,N,13159,16161,22857,22862,N,22858,48983,14205, +48984,22863,15138,14697,N,N,N,N,48985,48986,15654,22845,15229,22860,48987, +48988,N,N,15192,22861,12356,48989,48990,22856,48991,N,N,48992,17449,N,48993,N, +N,48994,N,48995,13683,N,N,N,N,N,13876,N,N,N,N,N,N,N,22859,12327,48996,48997, +14915,N,48998,N,16182,N,N,N,N,N,48999,49000,N,N,49001,17522,N,49002,18516, +22865,16734,N,49003,49004,49005,49006,N,49007,N,N,16938,49008,49009,15147, +22866,49010,22868,22864,N,49011,49012,49013,19041,N,17469,49014,N,N,49015, +16732,N,N,N,N,N,N,N,N,49016,49017,19067,15438,22880,N,22879,49018,49019,16248, +N,N,49020,14206,N,49021,49022,22873,15929,49185,N,18024,18225,49186,49187,N, +49188,22871,N,49189,16733,49190,N,N,49191,15480,22876,49192,N,15928,N,22870, +22875,49193,N,18259,N,49194,49195,22869,N,14113,49196,49197,13149,N,N,49198, +22877,20011,14926,17205,22874,49199,16476,49200,14645,16228,12646,16700,22872, +13637,49201,49202,49203,N,N,14151,N,17487,22878,N,N,N,N,N,16735,N,49204,22881, +N,22883,49205,N,16951,22889,49206,22884,N,49207,22886,N,N,N,N,49208,18753, +17523,49209,22887,49210,49211,49212,19756,N,N,N,19784,13369,49213,N,N,N,49214, +12334,N,22885,N,49215,N,N,N,22882,49216,N,49217,N,13432,N,N,N,49218,49219, +12647,49220,22888,N,49221,49222,19785,22892,N,N,49223,49224,N,N,16955,N,22899, +49225,N,49226,22893,49227,N,22890,22897,49228,N,N,N,22867,N,49229,N,49230,N, +49231,N,49232,49233,22894,N,22898,49234,49235,N,18498,17771,N,49236,49237,N,N, +N,22891,49238,22895,N,N,N,14152,N,N,49239,14961,49240,N,N,16477,N,N,N,N,N,N,N, +N,49241,N,N,22903,49242,N,49243,49244,49245,49246,N,N,N,17702,N,49247,49248, +49249,49250,N,49251,49252,49253,N,49254,N,N,N,22900,N,19296,N,N,N,49255,N, +22901,N,N,N,49256,49257,N,22902,N,19534,N,16418,49258,N,49259,N,N,N,N,N,14178, +N,49260,N,49261,22909,N,N,N,N,N,N,49262,49263,49264,15157,22906,N,22905,N,N, +49265,49266,18226,49267,N,49268,17973,49269,N,49270,N,49271,17713,22907,49272, +N,49273,22908,N,18799,49274,18245,15139,N,16497,N,19280,49275,N,N,N,N,N,13129, +N,23077,22910,49276,49277,49278,N,19786,23079,N,49441,23075,N,23076,N,49442, +49443,49444,49445,16736,49446,N,49447,49448,23074,N,22847,49449,N,49450,23078, +N,23073,N,N,N,N,N,23083,23084,17703,23086,49451,49452,15140,23081,N,49453, +49454,N,13628,49455,N,23087,49456,23080,23091,N,23090,49457,23089,49458,N,N, +23092,49459,N,23094,15985,49460,23093,49461,N,N,49462,23097,N,N,49463,49464, +49465,N,N,N,N,49466,N,N,N,49467,49468,N,49469,N,23095,49470,N,49471,23096, +22896,49472,49473,N,N,49474,23099,23098,N,49475,N,N,49476,22904,23100,23088,N, +49477,15193,N,49478,N,N,23101,23102,23104,23103,23105,12926,49479,14646,49480, +49481,19068,16431,N,N,N,49482,N,14414,N,49483,23107,49484,N,N,N,23110,N,18770, +49485,13663,49486,N,49487,23109,23108,18260,23111,13877,N,N,N,23113,23112, +49488,49489,N,13370,15158,N,N,18008,49490,N,N,N,49491,14153,N,N,N,16244,N, +23114,N,16432,17704,N,18783,23115,N,49492,N,N,49493,N,N,N,49494,23116,23117,N, +49495,N,19000,21853,16454,49496,N,18764,N,14936,N,18533,18499,49497,N,N,49498, +N,17741,49499,20033,N,23119,15440,49500,N,23120,49501,12342,N,49502,13908, +16461,49503,18784,N,N,N,23121,15170,17223,49504,15195,16183,N,49505,49506, +49507,N,N,23122,N,19069,N,N,12663,15196,N,49508,N,23125,49509,23123,23126, +20025,23124,N,49510,49511,N,16507,23127,N,49512,16946,49513,N,23128,N,49514,N, +49515,13434,49516,23130,N,23129,N,N,N,49517,23131,23132,13435,N,N,18044,17206, +13676,15197,16737,N,N,15708,12336,N,N,49518,23133,49519,N,49520,49521,N,N,N, +49522,12834,23137,N,N,49523,49524,49525,N,14647,23136,49526,N,14891,15930, +49527,49528,23135,N,15931,49529,19520,14890,N,49530,49531,12375,16462,49532, +49533,N,N,N,N,N,23142,49534,49697,16433,12615,49698,49699,49700,49701,15701, +49702,19302,14962,49703,49704,49705,49706,15932,49707,16423,49708,49709,N, +49710,23141,23139,23140,49712,N,49711,N,N,17259,N,N,23334,49713,23146,15230, +14648,23144,49714,49715,N,N,23145,49716,16184,49717,N,49719,23143,N,49718, +15151,N,N,N,N,49720,49721,49722,N,49723,49724,23148,23147,23152,49725,49726, +23153,N,23149,N,13090,23150,23151,18517,49728,49729,49730,N,18785,14154,23154, +N,N,49732,16434,49733,15933,49735,49736,49737,17234,49738,49740,N,49731,49734, +49739,13895,N,23155,23159,N,N,12875,23156,23158,N,49741,49742,49743,23157,N, +49744,15723,49745,N,N,N,17224,12357,23160,49746,49747,49748,49749,23161,N, +49750,49751,N,17450,N,49752,N,20081,N,N,N,N,15171,N,49753,19051,N,N,49754, +49755,N,19261,49756,N,N,23330,23163,N,49757,23166,N,23165,49758,49759,23162, +49760,49761,23329,N,N,18014,49762,23164,N,N,49763,N,49764,49765,N,N,N,N,49766, +N,23331,N,N,15724,23332,49767,19787,18296,N,49768,23333,N,N,N,N,N,23335,N, +49769,23336,N,49770,49771,N,49772,N,23337,N,13898,12616,14649,23338,N,23339, +15729,16738,49773,49727,21080,16702,16701,16984,14919,N,N,20594,N,49774,N, +49775,14190,19757,N,19070,N,18814,49776,23340,N,N,N,49777,14963,17471,23341, +20271,N,49778,N,19262,49779,17451,23342,13436,49780,N,49781,N,N,N,23343,23344, +19546,N,19492,19318,19292,15141,23346,N,N,15467,N,49782,19281,N,23348,23351, +23350,N,13433,N,N,13664,49783,23347,N,23349,N,N,N,49784,23352,49785,49786, +16249,N,N,49787,N,19835,12361,14944,16956,N,15453,49788,49789,15987,N,N,23355, +N,N,17742,49790,23353,16939,23354,15986,19549,23356,23357,19816,49953,N,N,N, +23362,N,49954,14650,49955,18261,23359,17772,23134,23138,49956,13647,49957, +18247,N,N,N,49958,23361,N,15934,18500,N,49959,N,N,49960,23367,N,18554,N,23358, +N,23364,23363,N,49961,49962,16463,49963,N,49964,N,19309,49965,20051,49966, +49967,19303,49968,12876,15198,N,N,20296,23366,16245,N,N,N,23365,N,N,23360,N,N, +N,N,N,14415,49969,49970,49971,23372,23370,49972,12877,23368,23374,23380,N, +49973,49974,49975,N,N,49977,16968,49978,49979,19009,49980,23382,N,49981,49982, +18722,N,N,N,23381,18288,19263,13371,49983,16503,15680,N,N,49984,17491,49985, +19758,N,49986,23377,23376,N,N,49987,23378,N,23375,N,49988,23383,N,23373,N,N, +23371,N,23379,23369,49989,17260,49990,19576,15430,14964,49991,49992,N,49976,N, +14906,N,N,19311,13121,17486,17994,12617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,16498, +49994,N,16436,14122,N,49995,N,N,N,49996,23385,49997,N,14651,13180,N,N,N,N, +49999,49998,23387,13172,23393,50000,50001,N,50002,50003,50004,23390,50005, +16499,N,N,N,13131,14892,N,50006,13130,14927,N,50007,23388,14181,14155,17773, +50008,50009,23386,N,12358,N,50010,N,50011,23389,23391,N,13901,14124,49993, +13372,13643,50012,N,50013,50014,23394,N,50015,14969,19313,N,15159,N,N,N,23395, +N,N,N,18736,N,N,N,50016,N,N,50017,50018,50019,50020,50021,N,23407,50022,12851, +23396,N,50023,50024,50025,50026,N,23413,23397,N,20034,50027,23404,50028,18271, +50029,N,50030,N,N,N,N,23412,N,23399,N,N,N,12340,23401,N,50031,14652,50032,N, +50033,23403,50034,23402,N,23398,23409,50035,15935,50036,N,50037,21613,14440, +19836,50038,50039,N,N,23400,50040,17524,13091,14893,50041,23392,N,23408,13153, +N,N,23406,23410,50042,17774,N,N,N,N,N,N,N,13438,50043,23602,N,50044,19529, +23415,13437,50045,23422,N,50046,50209,50210,19264,50211,23585,23587,50212, +23591,23417,50213,17194,N,50214,50215,N,17775,23595,23420,N,23592,N,50216,N, +23586,50217,N,50218,50219,50220,50221,16185,23596,50222,50223,16435,N,N,50224, +50225,N,N,23594,13373,50226,50227,50228,20304,23414,N,N,23590,12376,50229,N, +23416,50230,50231,19514,23421,16162,17479,23411,50232,50233,23589,50234,N,N, +50235,50236,N,16250,23599,13169,14369,N,N,N,N,23601,23418,23600,N,23593,23419, +N,23597,N,23598,N,N,N,N,N,23615,50237,N,50238,17998,50239,23588,N,50240,23611, +N,50241,N,23613,N,17496,N,N,50242,N,N,50243,N,N,N,50244,19788,N,N,N,50245,N,N, +N,N,18806,23608,16970,N,50246,N,23614,16703,50247,23605,23618,23617,N,18031, +23616,18026,50248,50249,50250,50251,N,50252,50253,23620,23607,50254,13896, +23610,15709,50255,50256,50257,18272,23612,13899,N,23604,23606,23603,50258, +50259,20272,13146,23609,50260,50261,23619,13109,N,N,N,N,N,N,N,14951,N,N,50262, +12637,N,N,23636,50263,N,20273,23639,50264,N,50265,N,N,16186,23638,N,N,N,23637, +50266,N,N,N,50267,50268,23634,50269,N,N,50270,N,50271,23622,50272,N,23651, +23621,N,23640,N,N,50273,50274,N,50275,23632,50276,N,23627,23624,N,23625,N, +23633,N,50277,N,29730,50278,N,23630,14653,17480,16740,23628,N,23623,50279,N, +23626,N,N,50280,50281,19789,19306,N,N,N,23631,23641,N,N,N,50282,N,N,50283,N, +23649,23642,N,N,23655,N,23653,50284,50285,N,50286,23648,50287,N,50288,N,N,N, +23647,N,17488,N,16741,50289,23645,50290,50291,23643,50292,N,23650,N,N,N,N, +23656,18549,23662,N,N,50293,N,50294,23657,23660,23654,50295,N,17268,N,18744, +50296,23644,N,50297,23652,15936,50298,19535,23672,23659,50299,N,N,N,50300, +14370,12835,13151,N,N,23635,N,50301,N,50302,N,50465,15937,23664,50466,23671, +15481,13170,50467,N,17198,50468,50469,N,N,N,N,23661,50470,50471,23666,23670, +50472,50473,13878,N,N,50474,N,50475,50476,50477,N,N,50478,50479,N,13644,23668, +N,50480,N,N,N,13601,N,17995,23667,N,50481,N,23669,50482,N,N,50483,N,N,N,N,N,N, +50484,23663,50485,N,N,N,N,23665,N,N,N,N,N,50486,13152,17225,50487,N,50488, +23676,N,50489,50490,N,50491,N,50492,N,23674,14441,N,23673,50493,N,N,N,N,N, +23841,N,N,N,50494,23384,50495,50496,50497,23675,N,23677,23678,N,50498,N,N,N,N, +23852,50499,23848,N,23405,50500,50501,50502,N,23847,50503,N,N,N,23846,N,N, +23843,N,50504,50505,50506,N,23658,23845,23844,N,N,50507,N,50509,50508,N,N, +50510,N,N,N,50511,23850,N,20262,50512,50513,50514,N,N,N,23853,13947,50515, +50516,23849,23851,N,N,N,N,50517,N,N,50518,18471,N,23854,N,50519,N,N,N,50520, +50521,50522,N,N,N,N,N,N,N,23858,23855,50523,50524,50525,50526,19827,23856, +50527,50528,N,50529,23646,N,N,N,N,50530,50531,50532,23859,N,N,N,23860,50533,N, +N,N,50534,N,12597,50535,23862,14183,15393,N,13909,50536,N,N,12836,50537,N,N, +50538,50539,N,N,50540,N,N,19807,N,N,50541,50542,23864,23863,23866,13629,50543, +N,13910,13374,50544,N,N,N,23869,N,N,50545,23868,N,23870,50546,N,12878,50547, +17207,N,23871,N,50548,13375,23873,N,50549,N,50550,23872,N,23874,N,50551,N, +23875,50552,23876,15199,16437,14881,N,18800,50553,N,19042,20292,50554,N,N, +50555,15221,50556,N,N,14928,20082,50557,N,N,23877,23878,N,15200,N,50558,50721, +23879,23880,N,50722,23882,23881,50723,19288,N,N,15710,15468,15172,N,23883,N,N, +N,N,N,N,N,23885,16163,50724,23884,N,N,50725,N,N,23886,50726,50727,N,50728, +50729,23887,N,N,N,50730,50731,23888,23889,50732,50733,50734,23890,50735,23892, +23891,23893,12837,17226,N,23894,50736,50737,15142,13132,23895,50738,50739, +17730,21580,N,N,50740,50741,13603,23896,N,N,50742,N,23897,50743,19052,19304,N, +N,N,17991,23898,18534,N,50744,N,18555,N,50745,19539,N,N,N,23899,N,50746,N, +50747,N,N,50748,50749,N,N,N,23901,23900,N,50750,23903,N,50751,N,23902,N,N,N, +50752,N,50753,N,N,N,N,N,50754,50755,N,50756,50757,N,N,23905,50758,N,N,N,50759, +50760,15201,50761,19505,50762,23906,23907,N,N,13604,N,50763,N,23908,N,N,N, +50764,N,N,N,23910,23909,N,50765,50766,50767,N,N,N,50768,N,50769,N,N,N,N,50770, +16229,50771,50772,18745,12618,N,50773,50774,N,N,18501,50775,17525,15681,13665, +N,N,N,N,N,N,N,50776,50777,N,50778,18502,50779,15406,N,50780,N,50781,23912,N, +13376,N,50782,12664,50783,50784,18034,23911,14654,17235,N,23913,N,N,N,N,50998, +23921,N,23914,50785,N,50786,N,50787,16961,N,13666,23922,50788,N,50789,N,50790, +50791,14184,50792,N,13605,23920,N,N,23918,23915,19808,N,50793,50794,50795, +17472,50796,N,N,18009,23916,N,N,23924,N,23923,14115,50797,50798,12845,50799, +50800,14907,23917,23919,50801,N,N,50802,N,19287,17012,N,N,N,N,N,N,N,N,19319,N, +N,23932,N,50803,23933,50804,12879,50805,N,N,N,18984,19581,24097,15395,15938, +23928,23934,12648,N,13879,50806,N,23925,23930,50807,N,N,16500,18289,N,18535, +50808,N,50809,50810,50811,50812,23927,50813,19233,50814,23929,N,24100,50977, +24098,50978,23931,N,N,50979,19234,18248,13667,N,17701,N,50980,17261,50981, +24101,50982,50983,N,50984,24099,16985,23926,50985,12619,50986,50987,N,N,50988, +N,N,50989,19790,24112,N,50990,50991,N,50992,24111,50993,N,N,N,16502,N,24108, +50994,19820,N,N,17974,24102,N,N,N,N,N,17477,50995,50996,50997,12620,14655, +24105,N,N,50999,51000,N,51001,15655,24110,N,24109,24104,N,24107,51002,N,13160, +51003,24106,18249,51004,N,20014,N,N,15988,16501,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,51005,N,24118,24116,N,18765,N,51006,51007,N,51008,N,24113,24115,51009, +12602,51010,N,14656,20274,N,13117,N,18786,51011,51012,N,N,N,19809,N,N,13092, +16187,24117,N,N,51013,N,N,N,N,N,51014,N,N,24122,N,51015,15939,N,N,N,19760,N, +24119,N,N,51016,51017,24114,51018,24120,51019,51020,51021,20062,N,17779,17986, +N,N,N,N,N,N,N,N,N,N,N,N,N,51022,N,51023,N,N,13110,N,N,12629,N,51024,24126,N, +51025,24129,51026,N,N,20035,51027,N,51028,19812,N,N,N,51029,24136,24130,24127, +51030,N,51031,20052,24133,N,51032,51033,N,15690,24135,N,N,24140,51034,N,17777, +24138,N,51035,N,51036,24132,51037,51038,17208,51039,N,24139,51040,24128,N, +24134,51041,24141,12412,24131,N,24142,51042,51043,16188,N,15711,51044,18981, +51045,14894,N,24123,24137,17722,51046,51047,N,N,N,51048,16438,N,13161,14929, +15940,24125,15682,N,N,N,N,N,N,N,14156,N,24124,N,N,N,24146,15725,14394,N,24161, +51049,24155,13684,17743,51050,24150,24159,12335,12594,51051,N,12857,N,24152, +16940,24143,24145,14657,N,N,51052,N,N,N,51053,N,24162,51054,24157,51055,51056, +N,24149,N,N,N,N,24156,51057,51058,N,N,51059,51060,19499,51061,N,24154,24158, +51062,N,51063,51064,51065,51066,N,14416,51067,15941,N,N,17209,51068,51069, +51070,24148,N,N,51233,51234,N,N,N,19759,51235,N,N,24151,N,N,24144,17778,N,N, +24147,51236,N,N,24153,N,N,N,N,51237,N,51238,20305,15422,19326,N,24163,N,N,N,N, +N,N,N,N,N,18478,51239,N,24175,14395,N,N,51240,N,N,15712,N,24165,51241,N,N, +20015,14658,N,24178,51242,N,12398,N,N,24176,N,51243,N,N,24164,N,N,51244,51245, +24170,N,51246,24172,51247,N,N,19791,24167,N,N,17710,51248,N,24169,N,51249, +51250,51251,24177,51252,24171,19527,N,51253,51254,24166,51255,15394,24190, +51256,51257,51258,N,13162,N,24168,24173,24174,N,N,N,N,N,N,N,17004,16986,N,N,N, +N,N,N,N,N,N,N,N,N,51259,24182,51260,51261,24188,N,N,24186,N,17705,N,N,24355, +24183,51262,N,51263,N,51264,24184,24160,13689,18746,N,51265,N,15423,N,51266, +14711,51267,N,51268,51269,N,20275,N,24180,N,24354,12649,16742,51270,N,51271,N, +51272,51273,N,N,N,N,18297,N,13377,20090,N,N,51274,N,N,51275,51276,19489,17490, +51283,N,51277,51278,24187,24189,51279,N,N,51280,N,16690,N,N,51281,51282,N, +24353,24185,N,24179,N,N,N,13379,N,N,N,N,N,N,N,N,N,51284,N,51285,51286,51287, +14185,N,N,51288,24367,51289,51290,24362,16504,51291,51292,13155,N,51293,51294, +N,15713,N,24371,N,51295,N,N,N,51296,24364,17452,24361,17497,N,N,N,24396,N,N,N, +24358,N,24357,N,24366,51297,51298,N,24360,24359,24365,51299,16417,N,24356, +51300,51301,N,N,51302,51303,51304,24368,N,51305,24369,51306,51307,51308,N, +51309,13378,N,N,51310,N,N,N,N,51311,51312,24374,N,24373,24375,51313,51314, +51315,51316,N,24378,N,N,N,51317,51318,51319,17731,N,24372,N,51320,51321,N,N, +24376,N,N,51322,N,N,N,14179,17017,24370,18235,N,51323,24377,51324,51325,N, +51326,N,N,N,N,N,N,N,N,N,24382,24380,N,N,24383,N,51489,24386,N,N,51490,24379, +14698,18216,N,N,24121,N,N,N,51491,51492,N,19828,24381,N,24385,17013,51493, +24384,N,24363,N,51494,28521,N,N,51495,24389,N,51496,51497,24393,51498,24391,N, +N,N,51499,51500,51501,N,24387,N,24388,N,51502,N,24392,N,24390,N,N,N,18766,N, +51503,24398,N,24395,24394,N,24397,18004,24399,51504,N,N,51505,N,N,17269,17005, +N,N,N,N,16421,N,N,51506,24400,N,24402,N,51507,N,N,51508,N,51509,N,N,51510,N, +24401,N,N,N,N,51511,51512,N,N,N,51513,51514,51515,51516,24181,N,51521,N,N, +24403,N,N,51517,51518,N,N,18023,N,N,N,N,51519,51520,N,N,N,N,24404,51522,51523, +N,N,N,N,N,12880,51524,N,51525,17780,13093,N,N,N,N,51526,51527,N,13668,N,N,N, +15454,14930,51528,N,N,51529,N,N,N,51530,51531,N,N,20263,16230,N,N,N,12650,N,N, +N,24406,N,51532,51533,51534,51535,51536,24405,N,51537,N,N,N,N,N,N,N,N,51538,N, +N,N,N,N,N,51539,24409,17210,24412,24407,51540,51541,N,24411,51542,N,N,51543, +24410,17728,12377,N,N,N,N,N,N,N,N,N,N,N,N,N,20085,N,51544,24414,N,N,N,12584,N, +51545,N,51546,51547,51548,51549,N,51550,24416,N,N,51551,24415,N,24413,N,N,N,N, +51552,N,N,N,N,N,N,N,N,N,N,N,N,24408,N,N,N,N,N,N,N,19235,51553,N,N,24418,51554, +51555,51556,51557,51558,N,24417,N,51559,51560,N,N,51561,N,N,N,N,12651,N,N,N,N, +24420,18994,N,24419,N,51562,N,51563,19509,N,N,N,N,15943,N,N,N,N,51564,N,51565, +N,51566,51567,51568,N,N,N,N,16691,N,51569,N,N,N,15942,N,N,N,N,51570,N,N,N, +51571,51572,51573,N,20091,51574,51575,24426,N,16505,N,51576,N,51577,N,N,24422, +24427,51578,N,12652,51579,N,51580,N,51581,N,51582,N,24425,N,18273,24421,24424, +15944,51745,18513,N,N,24428,N,15441,N,N,N,N,N,N,N,N,N,N,51746,N,N,N,16506,N,N, +51747,N,N,N,24431,51748,N,51749,24423,N,14119,N,51750,N,N,24429,N,N,51751,N, +19792,24432,N,N,N,29734,51752,51753,N,N,N,15695,51754,N,51755,N,N,N,N,N,24433, +N,N,N,24434,N,N,51756,51757,18222,51758,51759,N,N,N,N,N,24436,51760,N,N,N, +24437,51761,51762,51763,N,18227,51764,N,N,N,17781,24439,N,51765,51766,N,24441, +N,20053,N,24438,51767,24440,12653,51768,24435,N,51769,51770,N,51771,N,N,21339, +24442,N,N,N,N,16743,15160,24444,N,N,N,N,24443,16164,21081,N,N,N,N,N,N,24445,N, +N,51772,24609,N,24430,24446,N,51773,24610,51774,N,N,N,N,N,18298,51775,51776, +51777,N,N,N,24611,N,N,24612,N,N,51778,N,N,N,51779,N,N,51780,24613,N,51781,N, +51782,N,N,N,N,51783,N,N,N,24614,N,17502,51784,24616,24615,N,51785,24617,N, +24618,N,51786,15455,18787,N,51787,51788,19564,24619,24620,16726,15396,24621, +24622,51789,51790,51791,N,51792,24623,19026,18503,N,N,24624,18263,N,51793, +51794,51795,N,17453,51796,N,51797,51798,N,24625,12903,51799,13677,51800,19526, +51801,19510,51802,12852,20276,51803,N,N,N,19282,51804,18986,N,51805,N,N,51806, +51807,N,51808,16439,N,24626,N,N,51809,51810,17987,N,51811,51812,14371,24627, +51813,14932,24629,24628,N,51814,N,N,24630,N,51815,N,N,N,51816,51817,N,N,N, +24631,51818,N,N,24632,N,N,N,N,51819,N,N,N,N,13630,N,24633,N,N,N,N,24634,51820, +N,N,N,14372,51821,51822,18504,N,51823,24636,N,51824,N,15989,N,N,24635,N,N,N,N, +51825,N,N,51826,13880,24637,24639,N,24638,51827,N,51828,N,N,51829,N,24640,N, +14417,N,24641,N,N,51830,51831,13929,51832,16704,N,14717,N,N,N,51833,24643, +24644,24642,N,N,51834,N,N,N,15469,N,N,17992,13881,N,N,N,N,N,51835,51836,N,N, +24646,17196,24645,51837,51838,20277,18274,52001,52002,N,52003,52004,N,52005,N, +N,24649,52006,N,52007,N,N,N,N,52008,52009,N,N,24651,24648,52010,52011,N,19540, +24650,24652,52012,20036,N,N,52013,N,52014,24656,N,52015,52016,24655,17270, +18221,52017,N,14373,24654,N,52018,52019,N,24653,52020,19761,19762,N,N,52021, +52022,N,52023,24657,12654,N,N,N,52024,14710,15202,N,N,N,N,N,N,N,52025,24658, +24659,52026,N,52027,N,N,N,52028,24661,52029,N,N,N,N,52030,52031,52032,52033,N, +N,15683,N,N,52034,52035,24663,52036,24662,52037,52038,N,52039,52040,24664, +52041,13133,N,N,24666,N,52042,24665,52043,24668,24667,52044,N,N,N,52045,52046, +N,52047,14396,52048,52049,20008,N,13900,N,12838,N,N,52050,N,52051,N,N,52052,N, +52053,13930,52054,52055,N,N,N,52056,N,52057,52058,52059,N,52060,N,N,52061, +52062,N,N,13409,52063,52064,N,52065,N,N,N,N,20072,24670,N,52066,N,52067,N, +52068,N,24672,52069,52070,N,52071,24673,N,12881,N,N,52072,52073,N,24669,52074, +15161,52075,52076,17473,24671,52077,N,N,52078,52079,N,N,52080,N,N,52081,N,N,N, +52082,24676,N,15470,52083,N,52084,N,24674,52085,52086,N,52087,14142,N,N,18505, +24675,N,N,24702,N,N,52088,52089,N,52090,24681,52091,52092,52093,N,52094,14397, +52257,52258,52259,N,13669,52260,24678,19837,52261,N,20016,52262,N,N,N,N,N,N, +52263,N,N,N,N,N,N,N,N,52264,52265,N,N,N,N,N,N,17014,N,52266,24680,52267,N, +52268,52269,52270,52271,52272,52273,52274,52275,52276,52277,24682,20054,13911, +18556,18250,N,N,52278,24683,N,N,N,N,24685,52279,24688,N,52280,52281,N,52282, +52283,N,N,N,52284,N,52285,N,N,N,52286,52287,N,N,24684,N,52288,N,24687,14442, +12621,24689,52289,16240,24686,20060,N,52290,24692,29732,N,52291,52292,52293, +24690,24693,52294,N,52295,52296,24679,24691,52297,52298,14908,N,N,24694,N,N,N, +N,N,N,N,24695,N,52299,52300,N,19838,N,52301,52302,52303,N,52304,N,24696,N,N,N, +52305,52306,52307,52308,N,N,N,N,N,52309,52310,52311,N,52312,N,24697,52313, +52314,52315,24677,52316,N,N,52317,24698,52318,52319,52320,52321,N,N,52322, +52323,13380,52324,52325,N,N,52326,N,N,N,52327,N,52328,N,15397,N,52329,N,N,N,N, +N,N,N,N,52330,52331,24699,N,52332,N,N,24700,52333,N,N,52334,24701,N,N,N,52335, +N,52336,52337,12603,N,52338,52339,24865,N,18747,24866,52340,N,13348,24867, +52341,24868,52342,52343,N,N,24869,52344,24871,24872,24870,N,52345,N,18771, +24874,24873,N,52346,52347,52348,N,N,52349,24876,24875,24877,52350,N,N,N,N,N, +24878,24880,24879,N,N,14713,52513,24882,N,24881,52514,52515,13381,N,16211,N, +17724,N,24883,16440,52516,52517,N,15162,52518,12665,24884,52519,19793,52520, +52521,19043,24885,N,N,52522,17732,19763,14659,16189,N,N,52523,17227,21044, +52524,17454,12904,24886,52525,52526,52527,52528,N,N,52529,24887,N,24892,52530, +52531,24890,24889,23106,13094,24888,52532,12378,52533,18474,52534,N,18506,N,N, +52535,N,20017,24893,24891,17244,16422,52536,52537,18475,52538,18733,N,24895, +20012,14157,24896,N,24894,18518,24897,N,24898,N,52539,12379,52540,N,15990, +24903,N,24900,18029,24899,52541,52542,52543,52544,52545,52546,13606,N,52547, +24906,N,N,52548,24901,24902,N,24905,24904,18725,N,N,16706,16705,52549,13631, +52550,52551,24907,52552,N,N,N,52553,24908,N,52554,24909,N,N,N,N,52555,24911, +52556,24910,N,N,N,N,N,12630,N,N,N,N,N,24919,18536,24913,52557,24915,N,N,24917, +16190,52558,N,24918,24916,15424,52559,52560,52561,24912,24914,52562,18754, +52563,15945,N,N,24921,N,52564,24920,52565,52566,N,N,24922,N,15398,14895,N, +52567,17783,24923,N,17483,52568,N,24925,52569,52570,52571,20001,24924,52572,N, +N,52573,N,16745,N,N,52574,N,52575,52576,24930,52577,24932,24933,17236,N,N,N,N, +52578,24931,N,24928,N,24926,24927,52579,24929,52580,52581,52582,N,N,52583, +52584,24936,52585,24934,52586,24935,N,52587,N,N,52588,52589,N,52590,52591,N,N, +52592,N,52593,52594,52595,52596,24937,24939,24940,24941,52597,24942,52598, +52599,24938,N,52600,N,N,N,52601,N,N,24944,N,52602,52603,24943,52604,N,N,52605, +52606,52769,24945,52770,N,N,N,52772,52773,20037,52774,52775,52776,24948,24946, +24947,52777,52771,52778,13410,N,N,N,N,N,19582,N,N,52779,19018,N,24950,52780,N, +N,24949,N,N,52781,N,24951,24952,N,52782,52783,N,24956,24953,24954,24955,N, +24957,52784,52785,52786,24958,52787,25121,N,52788,N,25122,N,25123,N,18479, +17744,25124,18290,18740,N,25125,52789,N,25126,17706,52790,13095,14660,25127,N, +N,25128,52791,52792,25129,N,15145,N,N,25131,N,52793,25130,N,N,25132,25133, +52794,52795,52796,N,52797,52798,N,52799,52800,52801,52802,52803,52804,52805,N, +52806,N,N,52807,18537,N,25134,N,N,N,25135,N,N,29545,25136,25137,25138,N,N, +52808,N,15150,N,52809,25139,18262,N,52810,19295,N,12622,52811,12631,52812, +52813,25140,52814,N,N,N,25142,N,52815,N,25141,17776,N,52816,N,16441,23865,N, +25143,19521,52817,25144,N,13382,18519,25145,52818,25146,52819,N,25147,N,52820, +N,19548,N,52821,52822,19541,N,17470,N,52823,N,16746,52824,N,25149,52825,N, +15714,52826,15946,N,N,25152,N,52827,25151,25150,18557,52828,13383,14377,N, +52829,N,N,N,52830,N,52831,52832,N,52833,N,52834,52835,25158,52836,N,25155, +16191,19506,N,52837,N,25154,25156,25157,N,52838,25153,N,N,N,52839,52840,52841, +N,N,N,N,52842,52843,52844,25159,25160,52845,17455,N,13411,52846,52847,N,17253, +N,52848,N,N,52849,52850,25161,N,N,52851,N,N,52852,52853,52854,N,N,52855,N,N,N, +52856,52857,N,N,25162,25165,52858,N,52859,52860,52861,16231,52862,17988,53025, +25166,19283,53026,25163,N,53027,25164,53028,N,N,N,53029,N,53030,53031,53032,N, +N,N,N,25169,53033,N,N,53034,25168,25167,53035,N,N,N,53036,N,N,N,N,N,N,25171, +53037,53038,25170,N,N,25172,N,N,53039,53040,53041,N,N,N,53042,N,N,N,25174, +53043,25173,N,53044,N,N,19021,N,53045,N,N,53046,N,15702,20038,53047,53048, +25175,53049,N,17975,N,53050,25176,N,N,25177,N,25181,25179,25180,53051,25178,N, +N,N,53052,N,N,N,25182,N,53053,N,N,N,25183,N,N,N,53054,53055,N,N,53056,N,25184, +N,53057,25185,19511,25186,N,53058,53059,53060,N,19568,25187,53061,17230,53062, +18282,N,13931,53063,N,53064,17211,25188,13882,53065,53066,N,16464,53067,N,N,N, +53068,N,N,53069,25189,14909,N,N,53070,53071,N,N,53072,N,N,25190,53073,53074,N, +N,53075,25191,N,14374,14933,N,N,N,N,N,N,N,53076,N,N,25193,53077,53078,53079,N, +17750,14934,13646,N,N,N,N,N,53080,53081,N,53082,N,19236,N,18251,53083,N,53084, +N,N,17751,N,N,N,N,14684,N,N,N,53085,53086,25195,N,53087,53088,N,N,N,53089,N, +53090,N,N,N,53091,N,N,N,N,N,N,N,N,N,53092,15947,53093,N,53094,53095,N,53096, +53097,N,N,N,53098,N,53099,20018,14661,N,53100,14375,N,N,18467,N,25197,N,N,N,N, +N,53101,N,25199,N,53102,N,N,14443,N,N,N,N,25198,17526,N,N,53103,N,25201,13111, +25196,53104,N,18538,N,12592,53105,14956,N,20306,53106,N,25200,N,N,53108,53109, +53110,N,53107,N,25202,53111,N,N,19019,53112,16473,25204,N,53113,53114,N,25205, +53115,53116,53117,53118,N,25203,N,N,N,N,13134,53281,25211,53282,25210,53283,N, +15399,N,N,N,25212,25207,53284,53285,53286,25213,25208,53287,N,53288,N,18520, +25206,53289,53290,25209,53291,53292,N,N,N,25378,53294,N,N,N,53295,53296,53297, +N,N,53293,N,53298,25377,19297,N,53299,N,25214,N,N,12395,N,N,53300,53301,25380, +N,53303,53304,N,N,53305,53306,N,25379,N,53307,53302,15948,N,N,N,N,53308,25381, +N,N,N,N,53309,N,16707,N,53310,25383,25382,N,N,N,N,N,N,25384,53311,N,53312,N, +53313,53314,53315,N,N,N,N,53316,25192,53317,N,53318,25194,25386,25385,53319,N, +N,N,53320,N,N,53321,53322,N,N,N,N,15400,53323,20073,53324,15442,53325,25387, +14135,N,N,53326,53327,53328,13632,13607,15203,53329,53330,N,N,N,53331,19764, +53332,N,25393,53333,25392,16708,25389,53334,N,25391,53335,53336,15691,16192, +25390,25388,N,18218,N,N,15949,N,53337,18748,53338,N,53339,N,14935,N,N,N,N, +53340,N,N,N,N,17784,N,53341,25394,53342,53343,N,53344,25395,25417,13912,N,N, +20285,16693,N,N,N,N,25396,53345,53346,12882,17527,18977,N,53347,N,53348,53349, +53350,53351,N,53352,N,N,53353,53354,25397,N,N,N,53355,N,N,N,N,13690,25398, +53356,53357,25400,53358,N,N,25401,53359,18217,53360,N,25402,53361,N,N,N,53362, +25403,25404,53363,N,13913,12883,17989,15656,15204,53364,N,53365,N,N,53366, +53367,25405,53368,15657,N,N,N,53369,N,12874,18755,N,53370,25406,53371,N,18539, +N,53372,N,N,53373,53374,16709,53537,25409,53538,25410,18281,53539,16193,25407, +N,17249,53540,53541,25408,53542,N,N,15950,53543,N,N,N,N,N,N,53544,N,N,12380, +53545,13609,N,53546,53547,N,N,N,53548,25411,53549,53550,17528,53551,25412, +16455,N,N,53552,N,N,19501,53553,N,18723,25413,25414,17237,53554,20039,N,53555, +25416,25415,53556,N,N,N,N,N,53557,N,N,N,53558,N,53559,15471,53560,53561,25418, +12400,N,53562,53563,N,25421,53564,53565,53566,25419,12884,14158,25420,14662, +14706,N,19046,25422,53567,53568,19284,53569,53570,25424,N,N,53571,16465,12623, +12858,12332,N,N,N,N,53572,53573,25423,N,53574,N,N,53575,53576,N,53577,53578, +25425,25426,15991,N,53579,N,53580,N,25427,53581,13135,N,53582,N,N,25429,N,N,N, +14186,53583,13670,N,53584,25430,13941,N,N,25431,53585,16508,53586,17997,53587, +16480,14965,53588,53589,N,25432,N,53590,53591,N,N,N,N,53592,53593,17250,16747, +53594,25434,25436,25433,25435,N,N,N,N,N,53595,14114,53596,N,N,53597,N,N,N,N,N, +25437,14118,N,53598,N,13671,19794,25439,N,N,53599,N,53600,25440,N,N,53601, +12590,53602,53603,N,N,25443,N,N,N,13174,25442,25441,53604,25445,25438,53605, +25446,20009,53606,25447,53607,25448,N,53608,21620,25450,N,25449,N,N,N,25451, +25452,53609,20021,25453,N,28783,15951,25454,25455,15703,N,17976,25456,N,53610, +53611,17192,53612,53613,25457,N,17212,25458,53614,N,N,53615,N,13861,N,20799, +17245,15411,53616,N,53617,53618,13384,25459,N,25634,N,25462,53619,13672,N, +25461,25636,N,N,N,25460,N,15952,N,N,53620,N,N,N,25464,25465,N,17707,N,N,25466, +53621,13150,N,N,53622,N,16218,18788,53623,25468,53624,53625,53626,17000,53627, +53628,53629,53630,53793,N,25463,53794,25467,25469,N,N,14971,N,N,N,53795,N, +53796,53797,53798,N,N,N,25638,18734,53799,18470,17785,N,13914,25637,25635, +53800,18485,25470,17246,17787,N,17786,53801,14966,N,N,N,N,N,N,25656,N,N,53802, +N,N,N,53803,25640,53804,25642,N,53805,53806,N,25645,53807,25646,53808,25643, +25644,53809,53810,25641,25639,N,53811,N,N,25633,N,N,N,N,N,N,N,N,N,53812,N, +19023,12885,N,53813,N,25653,N,25650,53814,25655,53815,53816,25654,N,18291, +19495,53817,15163,25648,25657,25652,53818,25651,25647,53819,25649,53820,13385, +N,N,N,53821,N,N,N,N,17213,N,53822,16509,N,53823,53824,18466,53825,N,25662, +53826,53827,N,18468,N,53828,53829,53830,53831,N,N,16481,25659,53832,N,18511, +53833,25663,19027,53834,17243,53835,25658,25660,N,N,25661,N,N,N,N,53836,N, +53837,53838,N,53839,53840,53841,N,25664,N,N,15428,N,N,N,17990,25669,25668,N, +53842,25665,53843,N,N,20278,N,N,N,N,53844,25674,53845,53846,25678,25675,53847, +53848,53849,N,53850,N,53851,25671,53852,53853,53854,53855,N,53856,25672,N, +53857,N,53858,53859,25677,53860,53861,N,25666,21077,25673,25667,N,N,25676,N, +53862,N,53863,N,N,N,25682,53864,13386,N,25679,N,53865,53866,25680,53867,N, +25681,25684,53868,N,N,N,N,53869,N,53870,53871,N,53872,25683,18550,53873,53874, +N,N,25685,20092,19053,25690,N,N,25687,N,N,53875,N,N,N,53876,N,25686,16466,N, +25689,25691,53878,53879,53880,25688,53877,25695,N,25692,53881,53882,53883, +53884,53885,53886,25693,25670,54049,N,54050,25694,25696,N,54051,N,54052,N,N, +25697,54053,54054,N,54055,N,54056,19014,N,25698,N,N,N,54057,N,N,54058,54059, +19554,N,N,13902,14121,25699,N,N,54060,54061,N,18996,N,16232,N,19504,N,54062, +25700,N,20019,N,54063,18292,N,16710,18228,N,N,15693,N,N,54064,12352,54065, +25705,25703,N,25701,13345,54066,15953,25706,N,N,25704,N,25702,25710,N,54067, +25709,25708,25707,N,N,54068,54069,N,25711,54070,54071,54072,25712,16442,54073, +25713,N,25715,N,54074,25714,N,54075,54076,54077,14418,N,N,54078,16696,54079,N, +N,25717,54080,54081,54082,17788,54083,25716,54084,54085,N,25718,54086,18997, +16748,14663,N,25719,N,N,N,54087,20040,N,54088,N,54089,N,N,N,25721,N,N,25722,N, +25723,54090,25724,N,15205,N,25725,14159,N,N,13674,13610,N,25889,54091,19571, +14664,25726,54092,54093,54094,25892,19558,N,18236,N,54095,18739,54096,54097, +54098,15715,25891,54099,15443,14665,15206,13673,18998,25890,54100,54101,N, +16711,19266,14967,54102,N,N,54103,N,N,N,54104,15207,17501,54105,25895,20063, +14937,54106,25896,16194,N,25898,N,N,N,15954,14896,N,54107,54108,54109,25897, +54110,54111,15658,14398,16712,25893,25899,54112,54113,N,N,25894,14160,54114, +25902,25906,14187,54115,N,54116,N,N,25901,54117,N,54118,54119,25910,54120, +54121,14666,N,N,19821,12348,25907,N,54122,13675,54123,25904,N,54124,N,N,N, +25905,N,54125,17789,25903,25900,N,13096,16484,N,54126,14376,54127,54128,N, +25912,N,54129,N,54130,54131,54132,N,54133,54134,N,54135,25909,N,54136,54137, +54138,N,25911,N,54139,N,25908,N,N,54140,54141,N,14161,16947,25913,16750,54142, +54305,25926,N,N,25922,25916,N,N,54306,54307,N,N,54308,25920,15482,12381,25915, +25923,25927,14667,19542,54309,17494,25917,54310,54311,25925,54312,25914,17214, +N,25919,12349,19530,N,N,54313,54314,54315,54316,54317,25918,N,N,13915,18540, +54318,54319,54320,16749,N,20048,15727,N,N,25966,N,54321,25928,54322,16510,N, +25924,25929,25931,N,17529,25934,54324,N,25930,54325,54326,N,19028,13387,54327, +54328,19531,54329,N,12382,N,54330,25933,N,20093,54331,54332,N,N,54333,54334, +25932,54323,12655,N,N,18028,25935,N,N,54335,25942,25936,25943,N,N,N,N,54336, +54337,25939,N,N,54338,N,54339,N,N,N,18299,54340,54341,15434,25941,54342,25938, +25944,25937,N,N,15684,54343,54344,N,N,19237,54345,54346,15692,54347,N,25940, +25952,54348,N,25948,54349,25951,N,25949,25953,25947,N,25921,16467,54350,N, +18507,N,25950,54351,54352,25945,54353,N,N,16673,14162,N,15659,54354,N,54355,N, +54356,N,16165,16694,25956,N,54357,25958,25959,N,N,25955,25957,54358,N,54359, +54360,N,N,54361,25946,25954,N,25962,25961,54362,N,19322,54363,54364,14123,N,N, +54365,N,N,N,N,54366,25960,N,25964,25963,25967,54367,25969,N,54368,15164,25965, +N,N,54369,54370,25970,25971,54371,N,25972,54372,25978,17723,25974,54373,25973, +25975,25976,54374,25977,N,54375,N,54376,25979,25980,54377,54378,13388,N,25981, +N,25982,54380,54379,54381,54382,54383,N,N,N,54384,54385,26145,N,54386,N,N,N,N, +26146,26147,26148,54387,26149,26150,54388,54389,26152,26151,N,N,26153,N,N, +54390,54391,54392,N,26154,26155,54393,N,54394,54395,54396,54397,26158,26156, +26157,14945,14163,N,54398,17238,N,18483,54561,15728,N,N,18253,N,18541,26159, +22637,N,N,N,54562,54563,54564,54565,N,26160,26162,N,19813,26161,26164,26163,N, +19795,54566,26165,54567,18558,54568,54569,54570,N,N,26166,N,54571,54572,N,N, +26169,N,54573,26168,26167,N,N,54574,54575,26170,14130,N,54576,N,16674,13633, +54577,N,N,54578,26174,26171,N,N,26172,N,54579,N,26175,N,26176,26173,N,N,54580, +12585,N,54581,54582,12839,N,54583,N,26178,26179,N,54584,N,26180,N,19810,N, +54585,54586,N,N,15660,N,26182,26181,N,N,N,N,N,54587,N,N,N,54588,16233,26183,N, +54589,N,54590,26184,N,54591,26185,N,13413,54592,N,54593,54594,13389,N,54595, +26186,N,N,N,N,N,26187,54596,19293,19811,54597,54598,54599,19796,20279,N,14669, +26190,15444,26189,54600,54601,N,54602,26191,15401,54603,54604,54605,16977, +54606,26192,54607,54608,14668,54609,19543,26193,26194,N,N,26195,54610,54611, +54612,54613,26196,N,N,54614,N,54615,N,26197,N,N,N,54616,N,54617,N,54618,N,N, +15402,54619,54620,19565,54621,N,54622,54623,26199,54624,17215,54625,26198, +54626,N,N,N,54627,N,26201,N,N,N,26200,N,N,N,N,N,N,N,26202,N,N,N,16443,N,26203, +N,26204,N,N,N,19001,26205,54628,16751,26206,N,54629,N,54630,N,26207,N,N,N,N, +54631,N,20094,26210,54632,26209,26208,17456,54633,26211,16166,N,26212,N,N,N, +26213,20280,26214,N,54634,N,N,26215,26217,26216,18469,54635,18041,N,20286, +18473,N,54636,N,N,N,N,26219,N,N,15955,N,18730,N,26220,26218,54637,13390,54638, +N,N,14420,15208,N,N,18542,54639,54640,N,14378,19267,54641,26223,26221,N,14670, +N,14671,12393,N,14952,N,N,N,54642,54643,18265,N,N,N,N,N,N,N,N,12383,26228,N, +17216,N,54644,N,N,N,18264,54645,16987,54646,N,N,54647,N,54648,54649,26230, +54650,54651,26226,26229,26224,N,26227,19238,N,54652,14421,N,N,12413,26225,N,N, +N,N,N,N,N,54653,54654,26232,54817,26233,54818,54819,17977,N,54820,N,13883, +54821,54822,N,26406,18237,54823,15209,54824,N,13884,16456,20294,19502,26231, +16468,54825,N,N,N,N,N,N,N,N,N,N,54826,54827,54828,N,13651,26234,54829,N,54830, +N,54831,N,N,26236,54832,N,N,54833,N,26235,N,N,54834,N,N,26237,54835,17190,N, +18238,N,54836,N,N,N,17457,54837,N,54838,N,26403,N,N,N,N,N,N,54839,26402,54840, +N,N,54841,26238,54842,N,16213,N,18789,26405,54843,26404,14672,20307,N,54844,N, +N,N,N,N,N,N,26421,54845,54846,N,N,N,26409,26410,54847,54848,54849,N,15472,N, +54850,26408,54851,14712,26407,N,N,26411,N,N,54852,17458,18978,16675,N,N,N,N, +16988,26415,54853,26416,26412,54855,54856,54857,N,26413,N,26414,54858,N,N, +54859,14673,54854,N,N,26422,N,26418,54860,N,54861,N,18790,54862,19308,18728, +54863,N,26417,N,54864,26420,26419,N,N,N,19268,26423,N,N,N,N,54865,N,26424,N, +54866,16695,54867,26425,N,N,26427,N,26431,54868,N,26428,26426,18239,26429,N, +26430,54870,N,54871,12850,N,26437,26432,54872,54869,N,26433,54873,54874,N, +26434,N,16929,N,54875,N,54876,26436,26435,26438,54877,N,54878,54879,26439, +26440,54880,N,16195,54881,12905,N,26441,20055,N,15403,54882,54883,15661,N,N, +54884,54885,54886,15210,17239,54887,54888,N,54889,54890,26442,26443,12593, +54891,26444,54892,54893,26445,26446,54894,N,26447,N,26448,13885,23082,26449,N, +16485,26450,15435,54895,26451,N,20528,54896,54897,N,26452,19038,13404,54898, +54899,16676,15704,54900,18801,15662,N,54901,54902,N,N,N,N,N,54903,26453,14674, +26454,18508,N,26468,N,N,N,54904,26456,54905,16969,18293,14399,26455,16677, +54906,N,N,N,N,N,26457,N,N,54907,54908,54909,54910,17530,N,N,N,55073,N,N,55074, +55075,N,55076,N,N,N,N,55077,N,26459,26458,26461,N,55078,26460,N,26462,55079,N, +26464,55080,26463,N,13391,55081,26465,N,26466,26467,N,55082,14897,20041,N, +26469,16167,N,55083,N,12656,26470,26471,N,N,55084,N,55085,26472,55086,55087, +55088,N,55089,55090,N,N,55091,N,55092,55093,12402,N,26473,55094,N,N,55095, +26474,N,55096,N,55097,N,55098,18791,55099,55100,N,15431,N,26476,55101,55102,N, +55103,55104,13097,12338,55105,55106,55107,55108,26475,26478,18254,55109,16196, +55110,12886,55111,19239,55112,N,N,55113,14173,13916,55114,26477,55115,12906, +55116,55117,N,N,N,N,N,13347,55118,N,N,N,N,N,N,N,N,N,55119,12657,26482,20074, +16989,55120,N,18756,N,26494,55121,12887,26492,N,26490,26481,55122,26479,55123, +26480,55124,15459,13932,17271,55125,N,55126,18001,N,55127,N,55128,N,12625,N, +26484,26483,N,55129,55130,N,26489,26485,26488,N,55131,55132,55133,55134,19536, +26487,12888,13181,26491,55135,55136,26493,55137,55138,N,N,14164,N,N,N,N,N,N,N, +26659,26668,26669,N,N,55140,12331,55141,55142,55143,N,55144,55145,26676,N,N,N, +N,12401,N,N,26667,55146,55147,55148,26666,55149,26661,26660,55150,26658,26657, +17251,55151,17019,26663,55152,N,55153,55154,N,N,26662,N,55155,55156,55157, +26665,N,55158,N,16752,14165,N,N,55159,55160,12609,26664,55161,14675,55358, +55139,55162,55163,55164,16753,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +55165,N,N,26682,N,26683,N,12889,55166,N,N,12846,26680,55329,N,55330,55331,N, +55332,N,55333,26670,55334,26678,N,26685,26679,N,N,55335,26677,N,N,N,55336, +26486,55337,55338,26675,N,55339,55340,26671,55341,55342,55343,13392,26673, +26684,N,26674,N,N,N,55344,55345,26686,55346,26672,18300,55347,55372,N,N,N, +19817,N,N,N,26681,N,N,N,N,N,N,N,26703,55348,55349,55350,26695,N,N,N,16251,N, +55351,N,55352,13638,N,13917,N,26690,55353,55354,55355,N,12891,55356,N,15956,N, +26693,N,N,N,14938,55357,N,17745,26698,N,N,N,N,N,N,N,55359,19054,55360,26689,N, +N,N,12890,14422,18729,26699,N,26687,N,55361,26696,55362,55363,N,26706,55364, +26691,55365,N,26692,17978,N,55366,26697,N,N,55367,26694,19240,26700,12384, +55368,N,55369,N,26688,N,55370,N,N,N,55371,N,N,N,N,N,N,26702,N,26701,N,N,N,N,N, +N,18283,26708,N,26719,N,N,55373,N,13182,N,N,N,26722,N,N,26704,55374,N,N,26709, +19822,N,N,N,N,N,N,N,55375,26718,55376,55377,19797,55378,N,N,55379,20010,55380, +N,55381,55382,N,N,N,55383,17272,55384,55385,55386,13163,55387,N,N,N,55388, +18802,26724,17953,55389,55390,12337,55391,N,26717,55392,26713,16754,26707, +26715,26720,55393,18220,N,55394,55395,12330,55396,26712,55397,26721,18808,N, +55398,55399,N,N,N,55400,26716,N,26711,55401,N,N,N,N,N,15957,N,N,N,N,15663,N, +55402,55403,15404,55404,N,N,N,19544,N,N,18759,N,55405,26727,N,26736,N,N,N,N, +55406,N,55407,55408,55409,N,N,26714,N,55410,N,55411,13175,N,55412,N,N,N,15992, +26725,55413,26730,16755,55414,55415,26726,55416,26733,55417,N,17247,N,26734, +55418,55419,19798,26723,13112,55420,26729,N,55421,26732,19500,N,55422,N,N, +26735,N,N,26728,26731,N,55585,N,N,N,N,N,N,N,N,N,N,55586,N,N,55587,N,19241,N, +20257,55588,55589,55590,55591,N,26739,N,N,55592,N,N,55594,55595,26746,55596,N, +26738,15427,N,55597,55598,N,N,26705,55599,N,N,N,N,55600,N,55601,N,55602,19022, +N,19490,26745,26744,N,26740,26741,N,12598,N,55603,N,55604,26743,N,26737,55605, +55606,55607,55608,17493,55609,N,N,55610,55611,26742,12414,N,55612,N,N,55593, +55613,55614,16930,55615,N,N,N,N,N,N,19011,N,55616,26747,26913,N,18521,N,N, +55617,N,26750,15958,15433,26915,N,N,13886,55618,55619,55620,55621,55622,N, +26916,55623,18809,26749,55624,26710,N,55625,55626,55627,55628,55629,55630, +55631,26748,55632,N,N,N,20303,17954,18803,55633,N,26923,N,55634,N,N,N,N,N,N,N, +26929,N,55635,55636,55637,N,55638,26930,55639,26917,55640,N,N,18294,55641, +55642,26927,26919,55643,26921,55644,55645,N,N,55646,26931,26920,N,55647,26924, +N,N,12658,55648,18021,N,26925,26928,55649,N,55650,55651,N,55652,N,26918,55653, +16678,55654,26922,15143,16197,14128,19572,55668,19577,15730,N,N,N,N,55655,N, +55656,55657,55658,26935,26933,N,55659,55660,55661,55662,N,20302,55663,N,N,N,N, +55664,N,26932,55665,55666,N,19829,55667,26934,26936,N,N,N,N,26937,N,N,55669,N, +55670,N,26940,26938,N,55671,55672,N,N,N,17955,26939,55673,N,55674,18509,26926, +N,N,55675,N,N,N,N,N,55676,N,N,55677,15731,N,26941,26946,16756,55678,N,26945, +55841,55842,N,26914,N,55843,55844,26947,16713,N,N,26942,26944,N,55845,55846,N, +55847,55848,55849,26943,N,N,23857,23842,55850,55851,26949,55852,N,N,55853,N,N, +55854,26948,N,N,N,N,55855,N,55856,N,N,N,19830,N,25148,26950,N,N,N,N,N,55857,N, +55858,N,55859,N,55860,55861,N,26951,55862,47206,55863,N,N,N,55864,N,N,N,N,N,N, +26952,14423,N,13652,N,55865,55866,26954,20829,55867,55868,55869,55870,13685,N, +20026,55871,13939,26955,55872,55873,55874,55875,55876,N,N,26956,N,55877,N, +17262,55878,N,N,55879,N,26957,N,N,N,55880,55881,55882,N,18042,55883,12346,N,N, +N,N,N,N,N,N,N,N,N,N,55917,N,12899,26962,26963,55884,N,N,N,55885,N,26958,N, +15165,55886,N,55887,N,55888,N,55889,N,N,N,N,55890,N,26959,18242,N,55891,55892, +55893,26960,26961,26971,N,55894,N,26965,26968,55895,N,55896,55897,55898,26964, +55899,55900,55901,N,N,N,N,N,55902,55903,55904,N,55905,26966,55906,26967,15448, +N,26969,N,17217,N,14166,13122,N,N,55907,55908,N,26972,55909,N,55910,N,13119, +55911,26977,55912,N,26973,26976,55913,N,N,55914,18490,55915,N,55916,N,26974,N, +N,26975,18760,18522,26978,N,N,N,N,N,N,N,N,17021,26988,55918,26984,55919,55920, +12907,26982,N,19242,26983,55921,55922,26980,55923,26981,26986,26989,55924,N, +26987,55925,55926,55927,26985,26979,55928,55929,N,N,N,17240,55930,26996,N, +19498,N,55931,55932,N,55933,N,55934,N,26994,N,N,56097,26995,N,N,N,N,56098, +56099,N,56100,56101,N,26990,N,N,26992,N,56102,56103,26993,56104,56105,56106, +26991,56107,N,N,56108,N,56109,N,N,N,16486,N,20281,27000,56110,27001,N,N,N,N, +27169,N,16170,N,27003,56111,27006,N,N,N,56112,N,26998,26997,56113,N,27170, +56114,56115,12892,N,27004,N,27171,N,N,N,27005,56116,N,56117,56118,N,27002,N, +17459,N,26999,N,N,56119,N,N,N,18280,N,N,27175,56120,56121,56122,56123,56124, +56125,56126,N,56127,56128,19771,N,N,56129,N,N,56130,N,56131,N,56132,56133, +56134,N,N,N,N,56135,27174,56136,N,27173,56137,N,N,N,56138,N,N,N,27182,56139, +56140,56141,27176,N,56142,N,27184,N,56143,N,N,N,N,19814,27187,N,27178,56144, +56145,27179,56146,N,N,27183,N,27186,27185,56147,56148,56149,27177,N,N,56150,N, +27180,N,27197,N,N,56151,56152,N,N,56153,56154,N,56155,N,N,56156,27190,N,56157, +56158,56159,N,N,N,N,N,56160,56161,N,56162,N,27188,N,56163,27189,56164,N,N, +27194,27195,56165,13098,56166,13634,N,N,27193,56167,56168,N,56169,N,27172, +56170,N,N,56171,56172,56173,N,27192,27196,27191,56174,27198,56176,56177,56178, +27200,27199,N,56179,56175,56180,56181,56182,N,56183,56184,N,27202,27201,26970, +N,N,N,27206,56185,N,N,N,N,56186,56187,N,56188,27203,56189,N,N,56190,27204,N,N, +27205,56353,27207,56354,N,N,N,14188,56355,27209,56356,27208,56357,15664,N, +56358,56359,56360,56361,14676,24103,56362,N,N,56363,27210,15697,N,56364,56365, +13113,56366,27211,56367,12626,56368,15959,27212,56369,56370,14677,27213,12385, +56371,N,N,N,18749,56372,N,27214,N,N,N,N,16234,56373,27221,N,N,27218,N,17263,N, +56374,N,56375,N,27219,27216,13918,56376,27215,27222,N,N,N,N,N,14134,N,N,16990, +N,27228,N,N,N,N,27224,N,N,N,16949,27223,56377,27226,56378,56379,56380,N,27217, +56381,56382,N,27227,N,27229,N,N,N,56383,N,56384,18543,N,N,27225,N,27230,27232, +N,N,14419,27220,N,12353,N,N,56385,N,N,56386,56387,27231,56388,14939,20086, +27233,27234,16757,N,N,N,N,56389,56390,56391,56392,56393,20002,N,56394,56395, +56396,27235,19765,N,N,27236,27237,N,56397,19044,27238,56398,14912,N,20003,N,N, +N,N,N,56399,27243,N,N,N,N,N,N,56400,56401,56402,27244,15960,27242,56403,N, +56404,19815,27239,N,N,27241,16445,16254,56405,27240,N,27245,N,56406,18979,N,N, +27247,N,27246,56407,56408,56409,13164,N,19243,27248,N,56410,56411,N,56412, +56413,56414,N,56415,27260,27250,N,56416,N,N,N,N,27251,56417,56418,56419,N, +27252,27253,N,N,N,N,56420,56421,56422,N,N,56423,27257,N,27258,56424,56425, +27256,N,N,56426,N,56427,27254,56428,27249,27255,56429,56430,N,N,56431,N,N, +27259,28727,N,56432,N,N,56433,N,N,N,12840,56434,N,N,56435,56436,56437,N,27262, +13919,27261,56438,56439,56440,27426,N,27425,N,N,N,27428,56441,N,27427,56442, +27429,56443,N,15665,56444,27430,56445,N,27431,N,N,56446,56609,56610,56611, +27432,16446,N,19799,N,27433,N,N,18980,18246,27434,56612,27435,14379,N,56613,N, +13612,56614,N,N,27436,56615,56616,15211,18241,27437,N,13136,56617,56618,N,N, +56619,56620,27438,N,N,N,56621,27440,19831,N,27439,16198,N,27441,N,N,27442, +56622,N,27443,13393,56623,56624,56625,56626,N,N,27444,N,56627,27445,N,27446, +27447,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,13137,N,56628,56629,56630,56631,56632, +N,27448,N,27449,27450,N,N,N,N,N,12914,N,56633,16168,27451,N,56634,N,56635,N, +56636,N,N,N,56637,N,56638,27452,N,56639,N,27453,56640,N,N,N,56641,N,56642, +14400,N,17531,27454,56643,56644,N,56645,14167,N,16214,N,27457,N,17956,56646, +27456,56647,56648,14129,56649,56650,27455,17015,13613,N,N,27458,N,27459,56651, +15961,56652,N,56653,14189,56654,27460,56655,N,N,N,19244,56656,56657,16479,N, +56658,N,13686,N,19573,16714,56659,27461,56660,N,N,16199,17264,15962,56661, +56662,N,56663,27462,N,56664,N,56665,27465,56666,27466,56667,N,N,N,56668,56669, +N,14910,16962,27464,56670,15963,18750,56671,56672,56673,N,N,27463,56674,56675, +15212,N,12627,56676,27470,14168,N,56677,15214,56678,N,15213,N,20301,27469, +27468,16679,N,13645,20291,13114,15964,N,56679,56680,56681,N,56682,56683,56684, +27467,N,56685,56686,56687,N,27472,56688,27473,27471,56689,14424,N,19776,N, +56690,15215,18215,N,56691,56692,27476,56693,16448,N,17218,56694,56695,19766, +56696,27479,N,N,N,14444,56697,16447,27475,N,27480,14445,27477,27478,56698, +27474,56699,N,N,16482,17993,56700,56701,17199,N,12893,56702,N,N,56865,56866,N, +18544,N,56867,13635,N,56868,17460,N,N,27483,56869,27481,N,56870,17228,56871, +56872,56873,16449,13394,27482,N,16219,N,56874,20042,56875,56876,56877,20288, +56878,N,N,27484,27495,17461,56879,27494,56880,27491,27499,27492,N,27488,N, +17532,27487,N,N,N,27485,56881,19745,15216,N,56882,27489,N,27486,56883,56884, +56885,27493,15732,N,14401,N,56886,N,17018,56887,19269,12634,12386,N,17957, +56888,56889,27497,N,N,56895,56890,27496,N,18022,N,27501,56891,N,N,27490,N, +27500,27502,N,14380,27498,14678,56892,15445,56893,56894,27503,19800,N,N,N,N, +27506,N,27509,N,N,27507,18741,56896,N,N,56897,N,N,27504,N,N,N,56898,N,13920,N, +N,56899,N,27508,N,N,27510,56900,56901,56902,56903,56904,N,56905,27514,N,N, +27511,56910,27513,27512,N,N,56906,56907,56908,N,27515,N,15409,56909,27517, +27516,18792,N,56911,27681,N,N,N,56912,N,N,14169,N,N,N,N,27518,27682,56913,N, +27683,13636,26177,15993,N,27684,N,56914,14446,56915,56916,N,N,56917,27685, +56918,N,27686,56919,N,15166,56920,56921,N,N,N,N,23118,56922,27687,56923,27688, +56924,15666,N,27689,27690,56925,56926,27691,N,N,27692,27693,N,56927,N,56928, +56929,17195,56930,56931,27694,N,N,56932,56933,27696,N,27695,N,N,N,56934,17958, +56935,27697,56936,19245,56937,27698,N,27699,56938,27700,56939,N,56940,56941, +27701,N,56942,56943,56946,18010,56944,N,56945,N,N,N,15965,27702,56947,56948,N, +56949,N,56950,56951,14699,20526,27703,56952,N,N,N,N,N,56953,N,56954,56955,N, +27704,18751,27705,56956,27713,N,56957,N,N,N,27706,N,N,27708,56958,57121,N, +27707,27709,57122,19270,27710,27711,N,57123,N,57124,57125,27712,N,N,N,27714, +57126,N,57127,57128,13101,17511,N,18793,14946,14679,N,57129,N,N,18767,12895, +18510,27717,13395,16469,27716,27721,17273,19555,N,27719,27720,13614,N,27722, +18275,16991,57130,57131,18545,17725,27718,N,19271,12908,27724,20264,17474, +20293,57132,57133,15217,27723,57134,16945,57135,N,27740,16680,57136,N,18040,N, +18768,N,57138,57137,N,N,57139,27727,15167,15218,57140,15966,N,18277,57141, +14381,27726,27725,N,18794,N,57142,N,15425,N,57143,17746,N,57144,57145,N,57146, +N,N,57147,N,57148,57149,N,27729,27730,14680,27728,57150,57151,57152,N,57153, +27731,27732,N,27734,16931,57154,27733,13414,N,27736,N,27735,27737,N,57155, +27739,27741,N,27742,57156,N,N,N,57157,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,16470,57158,15439,27743,N,57159,N,13138,57160,27744, +57161,N,16758,27745,N,27746,18795,N,N,13615,N,N,N,N,N,N,N,57162,N,27747,57163, +N,57164,17462,N,N,57165,N,12635,N,N,57166,N,N,57167,57168,N,N,N,57169,N,N,N, +27748,N,N,N,N,57170,57171,57172,N,N,15473,N,N,57173,N,16246,N,N,57174,57175,N, +N,57176,N,N,57177,16941,N,57178,N,57179,N,57180,27751,57181,57199,N,27750,N, +57182,N,27749,N,N,57183,57184,57185,57186,N,57187,27757,27755,N,57188,27752,N, +57189,N,N,57190,57191,27754,57192,N,57193,27753,27756,N,13687,N,27760,N,16471, +N,27761,57194,57195,N,57196,14425,N,27758,27759,57197,N,N,20265,57198,57200, +57201,17463,57202,16681,N,N,N,N,N,N,27762,57203,N,27765,57204,N,N,57205,57206, +57207,N,27763,27764,19801,57208,N,N,N,17959,27768,57209,N,N,57210,N,57211,N,N, +N,N,N,N,27766,27767,27769,57212,57213,57214,57377,N,N,57378,57379,N,N,27945,N, +N,N,N,N,27772,57380,N,57381,27773,27771,57382,57383,57384,57385,N,N,N,57386,N, +N,57387,57388,27770,N,17533,N,N,27937,27941,27938,27774,57389,27939,57390, +57391,57392,27940,N,N,N,57393,27947,N,N,N,27942,N,57394,57395,57396,57397, +16472,27944,57398,57399,27946,27943,N,N,N,N,57400,N,N,57401,57402,N,57403, +57404,57405,27949,N,15667,N,27948,N,N,57406,57407,57408,27950,N,N,N,N,27951, +57409,57410,27954,27953,N,27952,N,57411,27956,27955,N,19574,N,N,57412,27958, +57413,27957,27959,57414,N,N,N,27960,57415,57416,N,57417,57418,N,N,27962,57419, +N,N,N,N,57420,N,57421,27961,16200,27963,57422,57423,13933,27964,27966,N,57424, +N,57425,N,N,N,N,57426,57427,N,N,27967,N,57428,57429,N,57430,57431,27968,27965, +57432,27969,N,15446,27970,13616,14131,N,57433,N,57434,14382,N,57435,N,N,N,N,N, +N,27971,57436,N,N,18032,N,N,17726,27972,N,N,N,N,57437,N,N,27975,N,57444,57438, +N,57439,57440,N,N,N,N,N,57441,15412,57442,57443,27974,27973,14170,27976,57445, +N,57446,13139,N,27978,N,57447,57448,14940,27977,N,27986,N,N,57449,57450,N, +27980,27982,19045,27979,57451,57452,57453,27981,N,27985,27983,13617,57454, +27984,57455,57456,N,57457,N,57458,27987,57459,57460,18266,20056,N,57461,57462, +57463,15668,N,N,N,27988,57464,57465,57466,57467,19746,27990,57468,27989,N,N, +27993,19777,57469,57470,27992,57633,13165,27991,27996,57634,N,27995,N,N,27994, +17714,27997,57635,N,57636,57637,57638,57639,57640,N,27998,57641,N,N,N,27999, +57642,57643,14700,N,14117,28000,28001,28002,57644,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +16201,28003,57645,15405,28004,57646,57647,N,28005,57648,57649,57650,21025, +20862,N,N,N,N,28006,25968,28007,17188,16171,18240,N,N,57651,57652,28008,57653, +N,19029,17492,14718,N,57654,17193,57655,57656,12586,N,19320,16215,57657,N,N,N, +57658,57659,N,57660,14174,N,57661,13921,57662,57663,19030,57664,N,N,N,N,28009, +N,N,N,N,N,57665,N,28011,57666,57667,28010,12896,N,57668,18038,28012,18295,N, +17715,57669,28013,15698,57670,N,N,28015,57671,57672,19522,28030,28017,28018, +57673,N,17481,57674,16992,16759,57675,17960,57676,28016,13653,N,57677,N,N, +28025,57678,28022,28197,17961,17248,28019,N,17534,17747,28020,28024,16224, +57679,18279,17484,57680,N,16450,28023,16942,16932,28021,12329,20258,N,N,N, +28026,57681,57682,57684,N,57685,57686,16993,57683,N,15669,16202,57687,57688, +28028,28027,57689,12399,28029,N,N,18735,N,28199,57690,N,18011,16235,57691, +57692,17241,N,13944,N,28198,19767,12607,57693,19031,12897,28193,28194,28195, +28196,17979,17187,12387,28200,N,28201,29731,N,57694,16957,57695,28202,N,12659, +16716,57696,14383,N,19802,57697,57698,28203,17708,N,N,57699,16760,15447,28204, +57700,N,28207,N,57701,15717,28205,16683,16682,57702,12388,N,20043,28209,N, +18546,28211,28210,28208,25444,13396,57703,N,28014,57704,28213,28212,57705, +57706,N,57707,28214,57708,19768,N,N,N,57709,N,57710,57711,57712,N,57713,N,N,N, +N,57714,57715,57716,18017,N,57717,19246,N,28215,N,15449,N,N,N,N,28216,57718, +28217,57719,57720,57721,28218,57722,N,17697,N,N,N,N,57723,57725,N,N,12394,N, +57726,57889,57890,N,57891,57892,N,14681,N,57724,N,20282,N,N,N,57901,N,N,57893, +N,57894,57895,57896,N,28222,57897,57898,N,57899,N,14132,28219,N,28220,57900,N, +N,18804,N,N,57903,N,13140,N,57904,57905,N,N,N,57906,19769,57902,13887,N,N,N,N, +N,17748,57907,57908,57909,N,28223,N,57910,57911,57912,N,57913,N,N,N,N,57914,N, +N,57915,N,28224,N,57916,N,57917,57918,57919,28225,57920,N,57921,N,57922,N, +57923,N,57925,57926,N,57924,N,57927,N,57928,N,N,N,17698,57929,57930,28227, +57931,28226,N,57932,N,57933,57934,N,57935,57936,N,57937,57938,N,N,N,N,N,57939, +N,N,N,57940,57941,18003,28228,15670,15456,18267,17265,57942,N,N,15474,57943, +16236,N,28229,57944,28230,57945,57946,57947,N,N,N,N,N,57948,16221,28231,57949, +28232,N,57950,N,28233,19823,N,15671,57951,N,N,N,N,28235,28234,57952,14682,N, +14707,15168,57953,57954,57955,N,N,N,N,N,57956,28238,57957,N,57958,57959,15718, +N,28237,57960,28236,N,17001,57961,N,14447,57962,16451,57963,57964,57965,N, +18480,57966,N,N,N,15673,N,57967,N,N,57968,28239,N,15967,N,57969,N,57970,N, +28242,28240,57971,57972,57973,28241,57974,57975,57976,57977,28244,28243,57978, +N,15994,N,28245,57979,57980,57981,N,57982,28246,28247,58145,58146,N,58147, +18512,14931,15457,28248,N,28249,20004,15685,19566,20044,28250,13922,N,58148, +58149,N,28251,58150,17699,58151,58152,28254,13176,16203,58153,28252,N,28253,N, +17504,58154,58155,19285,13948,N,58156,58157,N,58158,58159,58160,58161,58162, +58163,N,N,N,28256,28257,58164,N,58165,N,58166,28255,58167,N,28259,58168,58169, +N,N,58170,58171,58172,58173,N,58174,58175,N,58176,18015,13123,N,58177,28263, +58178,58179,28260,28262,58180,N,58181,N,N,N,58182,58183,28258,N,N,N,N,58184, +58185,58186,58187,N,58188,28495,N,N,28261,N,58189,58190,58191,N,N,58192,20075, +58193,58194,14426,58195,58196,58197,N,58198,N,58199,28271,58200,N,58201,58202, +17716,28266,58203,58204,28269,28267,58205,28272,N,58206,58207,58208,28273, +58209,N,N,N,N,N,28265,58210,58211,28278,12660,58212,58213,28264,N,58214,58215, +18477,N,28268,58216,15968,58217,58218,58219,N,N,N,N,58220,58221,58222,14683,N, +N,N,58223,58224,58225,58226,58227,N,58228,58229,58230,19272,58231,13924,N,N, +15686,N,17980,N,N,58232,58233,58234,N,N,58235,58236,N,N,16685,58237,28276,N, +28270,28275,58238,19523,58401,17464,28277,28274,N,N,58402,58403,N,N,N,58404, +58405,N,58406,58407,N,N,58408,N,16684,N,58409,N,N,58410,N,N,N,58411,28281, +58412,28280,58413,58414,58415,58416,N,58417,58418,58419,58420,58421,N,58422, +58423,58424,58425,N,N,58426,58427,58428,58429,28279,58430,N,19247,58431,N, +58432,N,58433,58434,58435,N,N,58436,58437,N,58438,58439,58440,N,58441,15739, +58442,N,58443,58444,28282,19039,N,58445,12628,58446,N,58447,N,18758,17266,N,N, +N,N,13688,58448,28284,58449,14685,N,N,58450,58451,N,58452,N,N,N,15148,N,58453, +N,N,N,N,58454,N,28283,16237,58455,N,N,58456,58457,N,N,16238,28449,28451,N, +58458,58459,58460,58461,15995,58462,28450,28452,58463,58464,13907,58465,18757, +58466,58467,15458,20259,N,28286,14968,N,N,20287,58468,58469,28454,58470,58471, +N,N,28453,28455,N,N,N,N,N,N,N,N,28285,N,N,58472,58473,58474,N,18025,N,17749,N, +N,58475,58476,58477,N,17495,58478,28460,58479,58480,N,58481,17219,28456,N, +58482,N,28457,N,N,N,58483,58484,N,58485,N,58486,58487,N,14125,58488,28459, +58489,58490,58491,N,58492,58493,14384,58494,N,N,N,58657,N,28458,58658,15969, +58659,58660,58661,58662,N,N,N,N,N,58663,N,58664,58665,13177,58666,N,58667,N,N, +58668,N,28464,58669,14911,16761,58670,N,17482,58671,N,N,58672,N,N,58673,N, +58674,58675,N,58676,13115,58677,58683,N,58678,28462,28463,17475,N,28461,N,N,N, +58679,58680,58681,N,N,28465,58682,N,N,N,N,N,N,58684,N,28471,58685,58686,58687, +58688,28474,58689,58690,58691,58692,58693,N,N,28473,17709,N,58694,N,N,28466, +28467,28470,58695,N,N,58696,28472,58697,58698,N,13888,58699,N,28475,28469, +58700,58701,28468,N,N,N,N,N,N,N,N,N,N,N,N,N,N,58703,58704,58702,58705,58706,N, +58707,58708,58709,28479,58710,N,N,28480,58711,58712,N,N,N,58713,58714,58715, +28481,N,N,28478,28477,58716,58717,58718,15970,17962,28476,N,N,N,N,58719,N, +28485,N,N,N,N,N,N,N,N,N,28483,N,N,58720,58721,N,58722,58723,58724,58725,28484, +28482,N,17016,N,28486,58726,N,58728,N,58727,N,28487,N,58729,28489,58730,N,N, +58731,N,58732,N,58733,N,N,N,N,13397,28488,19578,N,58734,N,N,N,58735,28500, +28490,58736,N,28493,58737,28491,58738,28492,58739,N,N,N,N,58740,N,28494,58741, +N,58742,58743,58744,28496,58745,58746,N,N,28497,N,28498,N,N,N,N,28501,28499, +28502,28504,N,28503,N,58748,58747,17465,58749,58750,N,N,N,N,58913,N,19559,N, +28505,16686,58914,N,N,28506,58915,19012,28507,13099,58916,58917,58918,12604,N, +13399,N,13398,28508,N,28509,N,28510,28511,N,N,N,58919,58920,58921,28512,58922, +13400,13141,14686,18486,58923,28514,28513,58924,N,58925,58926,28515,N,N,N,N, +12636,N,58927,N,58928,N,N,28518,58929,28517,28516,58930,28519,58931,N,N,N, +28522,N,N,58932,12359,58933,58934,28520,58935,28524,28523,N,N,58936,58937, +58938,58939,28526,28525,28527,N,17966,58940,58941,N,28528,58942,58943,58944, +58945,28529,28531,N,58946,28530,58947,18796,58948,58949,N,N,28532,58950,N, +58951,58952,58953,N,28533,N,14949,N,58954,N,28534,28535,N,58955,19273,58956,N, +N,N,58957,58958,58959,58960,16715,58961,58962,N,12324,16971,58963,28536,N, +18797,N,N,N,N,N,N,28539,28537,14687,N,28538,14402,N,58964,N,58965,N,58966, +58967,58968,N,N,19013,28541,28705,28542,28706,N,58969,12577,16216,15740,13401, +28707,N,N,N,18278,N,28709,N,58970,N,12578,N,28708,17476,58971,20045,17963, +28540,20006,N,14385,58972,58973,19803,58974,58975,N,58976,58977,58978,58979, +13945,20020,N,14120,58980,16994,26401,N,28710,13100,16239,N,58981,N,N,13142, +28712,58982,28713,28711,14180,58983,14941,15971,58984,N,58985,12579,N,N,20057, +58986,58987,58988,28715,28206,58989,28714,N,N,N,58990,58991,28718,28716,28717, +58992,28719,N,28720,20076,28721,28722,58993,16457,18491,N,N,N,16253,13415,N,N, +19770,12909,15672,14427,N,28725,58994,28724,15219,28726,28723,N,N,15144,58995, +N,N,28730,27181,N,58997,21078,58998,16247,28728,58999,59000,59001,N,N,20005, +18033,N,N,N,N,12587,59002,16483,15414,N,N,N,59003,18999,59004,12608,N,N,N, +20077,19819,N,28731,59005,17733,15483,N,59006,59169,28732,59170,28733,16204, +28734,59171,20078,N,N,28729,28736,28738,N,28737,N,28735,N,N,28739,N,N,28740, +59172,59173,16762,59174,12898,N,N,59175,59176,59177,28741,N,N,19512,59178,N, +28742,N,N,N,N,N,28743,59179,20266,59180,N,N,N,N,23345,28744,N,N,N,28745,28746, +N,N,59181,28750,59182,28747,N,28748,N,28749,28751,59183,N,N,N,59184,59185,N,N, +16452,N,N,59186,19575,59187,59188,16453,59189,59190,28752,N,18547,N,28753, +29523,19532,59191,28754,N,28755,59192,28756,13143,59193,28758,N,16217,59194,N, +N,28759,N,59195,14116,N,59196,59197,59198,28760,28764,59199,28762,59200,N, +59201,59202,28763,N,N,13171,28761,28765,N,N,59203,N,28766,N,12360,N,28767, +28768,N,N,N,N,59204,59205,59206,15972,59207,59208,N,28769,N,59209,59210,13639, +N,59211,28772,N,N,28771,N,28770,N,N,27505,59212,19036,59213,N,N,59214,59215, +28773,28774,59216,59217,N,59218,59219,59220,N,59221,N,59222,59223,N,59224,N, +28775,59225,59226,28776,59227,28777,59228,59229,28778,59230,59231,59232,N, +59233,59234,N,13402,59235,N,N,59236,59237,59238,N,59242,28779,59239,59240,N, +59241,59243,N,N,59244,N,N,N,N,N,N,N,N,28780,18211,59245,N,59246,28782,12859, +59247,28785,28784,59248,59249,N,59250,12580,N,N,N,13889,19015,17466,14882,N, +14688,15719,59251,16220,N,59252,N,28787,59254,59255,28786,19778,13416,18514, +18012,59256,N,59257,16252,20046,59253,14171,N,59258,N,59259,N,59260,28790,N, +59261,28789,59432,59262,N,N,N,N,59425,19275,17964,59426,59427,59428,N,59429, +59430,12624,59431,N,28791,28788,N,N,18769,19818,28792,59433,N,N,N,N,N,59434,N, +28793,59435,N,N,59436,28795,17002,13147,13148,28794,N,59437,59438,59439,13417, +14386,59440,59441,13418,59442,59443,17727,N,N,20064,N,N,N,59444,59445,N,59446, +59447,14428,N,N,59448,28796,59449,N,N,28797,28798,28961,N,28963,28962,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,18807,N,28964,59450,N,59451,59452,28965,59453,28966,N,N,59454, +N,28967,59455,59456,N,59457,59458,N,N,N,59459,N,N,59460,28969,28968,59461, +28970,N,59462,N,N,N,59463,N,N,N,N,N,N,N,N,N,N,N,N,N,N,18548,26188,N,N,16169,N, +59464,13618,59465,N,59466,59467,59468,N,28971,59469,28972,N,21036,23867,18515, +N,N,12411,59470,12347,N,59471,N,N,N,N,N,15220,19248,15998,59472,28973,N,19551, +N,59473,59474,28974,19804,N,12610,N,N,N,15169,59475,28975,12910,28976,59476, +59477,59478,28977,N,59479,59480,59481,28979,28980,59482,28982,28978,59483,N, +28981,N,59484,59485,13403,N,N,59486,28983,N,28984,N,N,59487,59488,59489,59490, +59491,N,N,N,59492,59493,59494,59495,28985,28986,N,59496,59497,28987,N,N,28989, +59498,59499,59500,28988,N,28991,28994,59501,59502,N,28990,28992,28993,N,59503, +28995,N,13890,59504,59505,N,59506,59507,N,59508,59509,59510,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,15475,28996,28997,14689,N,59511,N,59512,N,59513,N,N,N,N,N,28998, +59514,N,13118,N,N,N,18255,28999,29000,N,59515,59516,59517,17242,18027,59518,N, +N,N,59681,59682,N,29001,59683,N,59684,N,18301,N,59685,16972,12632,13934,N, +13935,59686,N,N,N,N,N,N,17267,29006,13936,59687,59688,12911,N,N,29005,59689, +59690,29003,59691,29004,59692,29002,N,N,29016,N,N,N,N,59693,N,N,59694,59695, +59696,29007,29008,N,59697,29009,29010,N,59698,59699,N,N,29012,59700,N,29011,N, +59701,59702,15705,29013,59703,59704,59705,29015,N,N,N,N,N,59706,59707,N,13619, +29014,59708,59709,16763,14387,N,N,59710,N,N,29017,N,N,N,N,59711,N,59712,N, +59713,59714,59715,N,N,59716,16973,N,N,29018,N,59717,59718,N,17965,N,N,59719,N, +59720,59721,29019,59722,N,N,N,N,N,29024,N,29022,59724,29021,29023,59725,29020, +N,59723,N,N,59726,59727,59728,29026,59729,N,N,59730,N,N,59731,29025,59732, +29028,N,N,13891,29027,N,59733,N,29029,N,N,29030,N,29032,29031,N,N,N,29033, +29035,29034,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,14716,N,59734,N,59735, +29036,59736,59737,29037,N,59738,N,59739,59740,59741,N,13116,59742,N,59743, +29038,N,59744,59745,29039,59746,N,59747,16241,N,59748,N,59749,N,N,N,N,N,59750, +29040,59751,29041,59752,29042,29043,59753,59754,59755,14690,N,N,59756,59757,N, +29044,29045,59758,N,29046,29047,59759,59760,29048,59761,N,59762,18481,29050, +59763,18726,29051,29049,N,29053,59764,59765,29052,59766,N,29054,N,59767,59768, +29217,N,59769,N,59770,59771,59772,59773,59774,59937,59938,29218,N,59939,59940, +N,59941,59942,59943,59944,N,59945,N,59946,N,N,N,59947,N,29219,59948,29220, +59949,59950,N,N,29221,59951,N,29222,29223,N,29224,59952,29225,29226,29227, +29228,59953,N,59954,29229,29230,N,23861,29231,59955,59956,59957,N,59958,N, +59959,59960,25720,13620,59961,N,N,N,13089,14898,29233,29232,19493,N,N,59962,N, +N,59963,59964,29235,29236,29234,N,29237,N,N,19298,59965,59966,59967,29238,N, +13691,59968,N,N,59969,N,N,59970,N,59971,N,59972,59973,N,59974,N,59975,59976, +59977,59978,59979,20261,N,N,N,59980,29239,59981,N,59982,59983,59984,N,N,N,N,N, +59985,59986,N,N,29241,59987,59988,59989,59990,N,59991,59992,59993,N,59994, +12350,59995,59996,29242,18987,29240,59997,N,29243,29244,N,N,59998,N,N,59999, +60000,29245,29246,N,N,N,N,N,60001,60002,29247,60003,19310,15149,60004,14970, +16687,N,60005,60006,60007,N,29248,N,N,60008,60009,29251,N,60010,60011,N,60012, +60013,29249,60014,N,N,N,N,29252,60015,60016,14449,29250,N,N,N,60017,29253, +60018,29254,29255,N,29259,N,15146,60019,60020,N,N,16996,N,60021,N,60022,N, +29260,29257,29256,29258,60023,N,60024,14175,N,60025,60026,N,N,N,60027,29264, +29263,29262,60028,N,12339,N,60029,60030,60193,60194,N,N,60195,N,60196,60197,N, +60198,N,29274,N,29270,N,29271,29267,29273,60199,29269,13154,N,60200,20300, +60201,29272,29268,29266,29265,60202,N,60203,60204,60205,29276,60206,N,60207,N, +N,29279,60208,60209,29278,29277,60210,60211,60212,60213,60214,N,N,18761,29275, +12403,29280,60215,29282,N,N,60216,60217,60218,N,13167,29261,12599,N,60219, +29284,N,N,60220,N,60221,60222,60223,29283,29281,17197,60224,60225,N,N,N,60226, +60227,60228,N,19312,60229,60230,N,60231,20058,60232,N,29285,60233,60240,60234, +60235,60236,29286,N,N,60237,N,N,N,29287,60242,60238,60239,60241,N,N,60243,N, +60244,N,60245,N,N,60246,29288,60247,29289,N,N,60248,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,17467,60249,29290,N,18487,N,29295,29291,N,N,N, +29292,N,60250,19249,19524,N,18000,60251,N,60252,60254,29296,N,N,29297,17982, +29294,29293,N,60253,N,N,12842,N,N,60255,29305,N,N,29304,N,60256,60257,N,N, +12661,60258,60259,60260,29302,N,N,N,29301,N,N,29299,N,13179,N,29298,15410, +12841,N,N,60261,60262,N,60263,60264,60265,N,N,N,N,N,60266,14691,60267,60269, +29308,29307,N,29306,60270,60271,29303,60268,29309,60272,29310,N,60273,N,N,N,N, +N,29477,29476,N,60274,60275,N,N,N,N,29478,N,N,12589,29473,29474,60276,14708, +19513,60278,60277,29475,60279,N,N,N,60280,60281,60282,19250,N,N,29483,60283,N, +29479,N,N,N,60284,60285,N,N,29484,60286,60449,N,60450,N,N,N,N,60451,60452,N, +60453,29481,N,29480,60454,N,N,60455,60456,14172,N,N,60457,60458,N,60459,60460, +60461,60462,N,29485,N,N,N,N,N,N,60463,N,N,29486,N,N,N,N,29487,60464,29482, +60465,N,60466,29300,N,60467,29488,N,17505,60468,N,N,29492,60469,29493,29491, +60470,N,N,60471,N,29490,29496,60472,29489,N,29494,60473,N,60474,60475,N,N,N,N, +29495,N,N,N,29498,60476,60477,60478,60479,N,29497,60480,N,N,N,60481,60482, +60483,N,N,N,N,60484,29500,60485,N,60486,N,60487,N,29501,60488,29502,60489,N, +20297,60490,60491,N,N,N,29499,17003,14957,N,N,29503,60492,60494,N,N,N,N,60495, +N,N,60493,N,N,N,60496,N,60497,60498,60499,N,N,60500,60501,N,N,60502,29504, +29505,60503,60504,29506,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29507,N,N,14388,29508,60505,60506, +60507,29509,N,15407,60508,29510,60509,60510,60511,60512,N,60513,29511,N,N, +29512,29513,N,60514,60515,N,29516,29514,20284,N,29515,60516,20079,60517,N,N, +60518,N,29517,60519,20059,N,N,N,N,60520,29518,18302,N,60521,29519,29521,N, +60522,29522,60523,60524,60525,N,N,60526,60527,60528,N,N,29520,14701,19533, +19299,22135,N,23904,19323,N,N,N,N,12843,N,60529,N,60530,N,N,60531,29524,13648, +29525,29526,29527,N,14709,N,29528,60532,N,N,24660,19547,N,16995,29529,29531, +29530,60533,29532,N,N,N,60534,29533,N,60535,29534,N,N,N,60536,60537,60538, +29535,60539,60540,60541,N,29536,60542,29537,29538,60705,29539,N,29540,29541, +29542,N,60706,60707,60708,N,N,N,29543,29544,60709,N,N,N,N,17700,60710,60711, +60712,60713,14429,60714,29546,60715,60716,N,60717,60718,60719,N,N,N,60720, +16717,29547,60721,N,N,N,60722,N,N,N,60723,60724,29548,N,N,60725,N,60726,60727, +N,60728,N,N,60729,N,60730,60731,18721,60732,60733,29549,60734,N,60735,N,60736, +60737,60738,60739,60740,N,N,29550,25399,N,N,27738,28781,N,N,29551,60741,29552, +60742,60743,60744,60745,N,60746,N,N,60747,60748,29554,29555,29556,20080,29553, +N,N,29557,29558,60749,60750,29560,N,29559,60751,60752,60753,60754,60755,29562, +60756,N,60757,29563,29561,N,N,60758,N,N,60759,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +20022,N,60760,60761,60762,60763,N,60764,29564,60765,60766,N,N,N,N,29565,25428, +60767,N,29566,60768,60769,60770,N,60771,8490,N,8564,8560,8563,8565,N,8522, +8523,8566,8540,8484,N,8485,8511,9008,9009,9010,9011,9012,9013,9014,9015,9016, +9017,8487,8488,8547,8545,8548,8489,8567,9025,9026,9027,9028,9029,9030,9031, +9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,9046, +9047,9048,9049,9050,8526,N,8527,8496,8498,8494,9057,9058,9059,9060,9061,9062, +9063,9064,9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,9076,9077, +9078,9079,9080,9081,9082,8528,8515,8529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8497, +N,8559, +}; + +static const struct unim_index jisxcommon_encmap[256] = { +{__jisxcommon_encmap+0,92,255},{__jisxcommon_encmap+164,0,245},{ +__jisxcommon_encmap+410,199,221},{__jisxcommon_encmap+433,132,206},{ +__jisxcommon_encmap+508,1,95},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{__jisxcommon_encmap+603,16,59},{__jisxcommon_encmap+647,3,212},{ +__jisxcommon_encmap+857,0,165},{__jisxcommon_encmap+1023,18,18},{0,0,0},{ +__jisxcommon_encmap+1024,0,239},{__jisxcommon_encmap+1264,5,111},{0,0,0},{0,0, +0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__jisxcommon_encmap+1371,0,254},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisxcommon_encmap+1626,0,255},{ +__jisxcommon_encmap+1882,0,255},{__jisxcommon_encmap+2138,0,254},{ +__jisxcommon_encmap+2393,0,254},{__jisxcommon_encmap+2648,0,255},{ +__jisxcommon_encmap+2904,0,250},{__jisxcommon_encmap+3155,1,255},{ +__jisxcommon_encmap+3410,0,255},{__jisxcommon_encmap+3666,5,255},{ +__jisxcommon_encmap+3917,0,255},{__jisxcommon_encmap+4173,0,253},{ +__jisxcommon_encmap+4427,2,255},{__jisxcommon_encmap+4681,0,253},{ +__jisxcommon_encmap+4935,0,255},{__jisxcommon_encmap+5191,1,253},{ +__jisxcommon_encmap+5444,1,254},{__jisxcommon_encmap+5698,0,255},{ +__jisxcommon_encmap+5954,1,255},{__jisxcommon_encmap+6209,7,253},{ +__jisxcommon_encmap+6456,0,255},{__jisxcommon_encmap+6712,0,255},{ +__jisxcommon_encmap+6968,1,250},{__jisxcommon_encmap+7218,6,255},{ +__jisxcommon_encmap+7468,0,255},{__jisxcommon_encmap+7724,0,255},{ +__jisxcommon_encmap+7980,0,255},{__jisxcommon_encmap+8236,2,253},{ +__jisxcommon_encmap+8488,0,255},{__jisxcommon_encmap+8744,0,253},{ +__jisxcommon_encmap+8998,2,255},{__jisxcommon_encmap+9252,2,244},{ +__jisxcommon_encmap+9495,4,252},{__jisxcommon_encmap+9744,0,255},{ +__jisxcommon_encmap+10000,1,254},{__jisxcommon_encmap+10254,0,253},{ +__jisxcommon_encmap+10508,3,255},{__jisxcommon_encmap+10761,0,254},{ +__jisxcommon_encmap+11016,2,255},{__jisxcommon_encmap+11270,0,255},{ +__jisxcommon_encmap+11526,3,255},{__jisxcommon_encmap+11779,0,254},{ +__jisxcommon_encmap+12034,0,252},{__jisxcommon_encmap+12287,2,255},{ +__jisxcommon_encmap+12541,0,252},{__jisxcommon_encmap+12794,0,255},{ +__jisxcommon_encmap+13050,2,254},{__jisxcommon_encmap+13303,0,254},{ +__jisxcommon_encmap+13558,0,251},{__jisxcommon_encmap+13810,0,158},{ +__jisxcommon_encmap+13969,54,255},{__jisxcommon_encmap+14171,0,254},{ +__jisxcommon_encmap+14426,2,255},{__jisxcommon_encmap+14680,0,254},{ +__jisxcommon_encmap+14935,0,253},{__jisxcommon_encmap+15189,1,255},{ +__jisxcommon_encmap+15444,0,255},{__jisxcommon_encmap+15700,0,254},{ +__jisxcommon_encmap+15955,0,255},{__jisxcommon_encmap+16211,1,254},{ +__jisxcommon_encmap+16465,1,255},{__jisxcommon_encmap+16720,0,255},{ +__jisxcommon_encmap+16976,0,159},{__jisxcommon_encmap+17136,55,255},{ +__jisxcommon_encmap+17337,1,255},{__jisxcommon_encmap+17592,1,254},{ +__jisxcommon_encmap+17846,0,254},{__jisxcommon_encmap+18101,0,255},{ +__jisxcommon_encmap+18357,0,255},{__jisxcommon_encmap+18613,0,255},{ +__jisxcommon_encmap+18869,0,253},{__jisxcommon_encmap+19123,1,132},{ +__jisxcommon_encmap+19255,119,230},{__jisxcommon_encmap+19367,28,251},{ +__jisxcommon_encmap+19591,0,255},{__jisxcommon_encmap+19847,1,254},{ +__jisxcommon_encmap+20101,2,255},{__jisxcommon_encmap+20355,1,255},{ +__jisxcommon_encmap+20610,0,255},{__jisxcommon_encmap+20866,0,249},{ +__jisxcommon_encmap+21116,2,254},{__jisxcommon_encmap+21369,2,255},{ +__jisxcommon_encmap+21623,2,165},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0, +0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{__jisxcommon_encmap+21787,1,229}, +}; + +static const ucs2_t __cp932ext_decmap[969] = { +65340,65374,8741,65372,8230,8229,8216,8217,8220,8221,65288,65289,12308,12309, +65339,65341,65371,65373,12296,12297,12298,12299,12300,12301,12302,12303,12304, +12305,65291,65293,177,215,U,247,65309,8800,65308,65310,8806,8807,8734,8756, +9794,9792,176,8242,8243,8451,65509,65284,65504,65505,65285,65283,65286,65290, +65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660, +8251,12306,8594,8592,8593,8595,12307,U,U,U,U,U,U,U,U,U,U,U,8712,8715,8838, +8839,8834,8835,8746,8745,U,U,U,U,U,U,U,U,8743,8744,65506,9312,9313,9314,9315, +9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330, +9331,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,U,13129,13076,13090, +13133,13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115, +13212,13213,13214,13198,13199,13252,13217,U,U,U,U,U,U,U,U,13179,U,12317,12319, +8470,13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181, +13180,8786,8801,8747,8750,8721,8730,8869,8736,8735,8895,8757,8745,8746,32394, +35100,37704,37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193, +20220,20224,20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479, +20510,20550,20592,20546,20628,20724,20696,20810,20836,20893,20926,20972,21013, +21148,21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660, +21642,21673,21759,21894,22361,22373,22444,22472,22471,64015,U,64016,22686, +22706,22795,22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532, +23582,23718,23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353, +24372,24423,24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887, +24880,24984,25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121, +26158,26142,26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362, +26382,63785,26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032, +27106,27184,27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759, +27866,27908,28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199, +28220,28351,28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020, +28998,28999,64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654, +29667,29650,29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063, +30338,30364,30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024, +64024,64025,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072, +32092,32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782, +33864,33972,34131,34137,U,34155,64031,34224,64032,64033,34823,35061,35346, +35383,35449,35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214, +64035,36559,64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357, +37358,37348,37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433, +37479,37543,37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669, +37665,37627,64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880, +37937,37957,37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735, +38737,38741,38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797, +39794,39823,39857,39867,39936,40304,40299,64045,40473,40657,U,U,8560,8561, +8562,8563,8564,8565,8566,8567,8568,8569,65506,65508,65287,65282,8560,8561, +8562,8563,8564,8565,8566,8567,8568,8569,8544,8545,8546,8547,8548,8549,8550, +8551,8552,8553,65506,65508,65287,65282,12849,8470,8481,8757,32394,35100,37704, +37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193,20220,20224, +20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479,20510,20550, +20592,20546,20628,20724,20696,20810,U,20836,20893,20926,20972,21013,21148, +21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660,21642, +21673,21759,21894,22361,22373,22444,22472,22471,64015,64016,22686,22706,22795, +22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532,23582,23718, +23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353,24372,24423, +24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887,24880,24984, +25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121,26158,26142, +26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362,26382,63785, +26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032,27106,27184, +27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759,27866,27908, +28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199,28220,28351, +28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020,28998,28999, +64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654,29667,29650, +29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063,30338,30364, +30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024,64024,64025, +U,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072,32092, +32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782,33864, +33972,34131,34137,34155,64031,34224,64032,64033,34823,35061,35346,35383,35449, +35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214,64035,36559, +64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357,37358,37348, +37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433,37479,37543, +37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669,37665,37627, +64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880,37937,37957, +37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735,38737,38741, +38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797,39794,39823, +39857,39867,39936,40304,40299,64045,40473,40657, +}; + +static const struct dbcs_index cp932ext_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_decmap+0,95,202},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{__cp932ext_decmap+108,64,156},{0,0,0},{0,0,0},{0,0,0},{0,0, +0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{__cp932ext_decmap+201,64,252},{__cp932ext_decmap+390,64,252},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__cp932ext_decmap+579,64,252},{__cp932ext_decmap+768,64,252},{ +__cp932ext_decmap+957,64,75},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const DBCHAR __cp932ext_encmap[9686] = { +34690,N,N,N,N,N,N,N,N,N,N,34692,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +34644,34645,34646,34647,34648,34649,34650,34651,34652,34653,N,N,N,N,N,N,61167, +61168,61169,61170,61171,61172,61173,61174,61175,61176,34708,N,N,N,N,N,N,N,N,N, +N,N,N,N,34712,N,N,N,N,N,33121,N,N,N,N,N,N,N,N,34707,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,34713,34624,34625,34626,34627,34628,34629,34630, +34631,34632,34633,34634,34635,34636,34637,34638,34639,34640,34641,34642,34643, +34688,N,34689,34698,34699,N,N,N,N,N,N,34700,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,34693,34694,34695,34696,34697,34661,N,N,N,N,N,N,N,N,N, +34665,N,N,N,N,N,N,34656,N,N,N,34659,N,N,N,N,N,N,N,N,N,34657,34667,N,N,34666, +34660,N,N,N,34668,N,N,N,N,N,N,N,N,N,N,34662,N,N,N,N,34670,N,N,N,N,N,N,N,N,N,N, +N,N,N,34655,34669,N,N,34658,N,N,N,34663,N,N,N,N,N,34664,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,34686,34703,34702,34701,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,34674,34675,N,N,N,N,N,N,N,N,N,N,N,N,34671,34672,34673, +N,N,34677,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +34676,N,N,N,N,N,N,N,N,34691,60748,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,60749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60750, +60751,N,N,60752,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60753,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,60754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60756,N,N,N,N,N,N,N, +60755,N,60758,N,N,N,N,N,60757,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60741,N,N,N,60759,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,60762,60763,N,N,N,60761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,60760,N,60766,N,N,N,60764,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60765,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60767,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,60769,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,60768,60770,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60771,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,60772,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,60773,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60774,60775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,60776,N,N,N,N,N,N,N,N,N,60777,N,N,N,N,N,N,N,N,61019,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,60778,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60779, +60780,N,N,N,N,N,N,60781,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,60782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,60783,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +60784,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60785,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +60786,60789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60788,N,N,N,N,N,N,N,N,N,N,N,N, +60790,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,60791,60792,60793,N,N,N,N,N,N,N,N,N,N,N,60794,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60795,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60797,60796,60801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,60802,60803,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,60804,N,N,N,N,N,N,N,60805,N,60806,N,N,N,N,N,60807,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,60808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +60809,60810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60811,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,60814,60815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60816,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,60817,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60818,60819,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60822,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,60820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60823,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60824,60825,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60826,60827,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,60828,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60747,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60829,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60830,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60831,60832,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60833,N,N, +N,N,60834,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,60836,N,N,N,N,N,N,N,N,60835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60838, +60839,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60837,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60841,N, +N,N,N,N,N,60840,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60842,60843,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60844,60845,60846,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,60847,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60848,60849,60850,N,N,N,N,N, +N,N,N,60853,N,N,N,N,N,N,N,N,N,N,N,60851,N,N,N,N,N,N,N,N,60855,N,N,N,N,N,60856, +N,N,N,N,N,N,N,N,N,60854,N,N,60743,N,N,N,N,N,N,N,N,N,60852,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60858,N,60859,N,N,N,N,N,N,N,N,N,N,N,60857,N, +N,N,N,N,N,N,N,N,N,N,N,N,60861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,60862,N,N,N,N,N,N,60863,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,60864,N,N,N,N,N,N,N,N,N,N,N,N,60865,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,60866,60746,60867,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60870,N,N,N,N,60872, +60873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60874,N,N,N,N,N,N, +N,N,N,N,N,N,N,60871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,60744,N,N,N,N,N,N,60875,60877,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60879,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60880,60881,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60883,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60882,N,N,N,N,N,N,N,60884,N,N,N,N,N,N,N, +N,N,N,60885,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60886,N,60887,60888, +60889,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60890,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,60892,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +60891,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,60893,60894,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,60896,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60895,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,60897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60898,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60899,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60901,N,N,N,N,N,60900,N, +N,N,60902,60905,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60903,N,N,60906,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60904,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,60907,60908,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60909,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,60910,60911,N,60912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,60913,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60914,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60915,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,60742,60917,N,N,N,N,N,N,N,N,N,N,60916,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,60919,60920,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60918,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60922,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +60923,60924,N,N,N,N,N,N,N,N,N,N,N,N,60992,60993,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60995,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60996,N,N,N,N,N,N,N,N,N,N,N,60997, +N,N,N,N,N,N,N,N,61000,N,N,N,60998,N,N,N,N,N,N,N,N,N,N,N,N,60999,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,61002,61001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,61003,N,N,61005,61004,N,N,N,61006,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61007, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +61008,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61009,61010,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60812, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61011,61012,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61015,61013,N,61014,N,N,N,N,N,N,N,61016,61018, +61020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,61021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61022,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61023,61024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,61028,N,N,N,N,N,N,61030,61031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,61032,N,N,N,61034,61035,61037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61038, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61040,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,61039,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,61041,61042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60736,61043,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,61044,61046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61047,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61048,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61049,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61050,61051,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61052,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60740,61053,N,N,N,N, +N,61054,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61056,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,61058,61061,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61062,60737,61063,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61064,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61066,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,61067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,61068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61070, +61071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,61072,61073,N,N,N,61074,61075,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,61076,61078,61081,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,61082,61084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +61085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61087,N,N,61086,N,N,N,61088,N,N,N, +N,N,61091,61092,N,N,N,N,N,N,N,61089,61090,61093,N,N,N,61095,N,N,N,N,N,61094,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +61102,61096,N,61098,N,N,N,61097,N,N,N,N,N,N,N,N,N,N,N,N,N,61099,N,N,61101,N,N, +N,N,N,N,N,61100,N,N,N,N,N,N,N,N,N,N,N,N,N,61103,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +61105,61106,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60739,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61104,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61110,N,N,61114,N,61112,N,61108,N,61109, +N,N,N,N,N,N,61113,N,N,N,N,N,N,61107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60745,N, +61117,N,N,N,61120,61122,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +61121,61119,N,N,61116,N,N,N,61115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,60738,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61124,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61125,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61126,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61127,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,61128,61129,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61130,N,N,61131, +61132,61135,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61136,61137,N,N,N,N,N,N,N,61138, +N,N,N,N,N,N,N,61139,N,N,N,N,N,N,N,N,N,61140,N,61141,N,61142,N,N,N,61143,61144, +N,N,N,N,N,N,N,N,N,N,N,N,N,61145,61148,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61150,61151,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,61152,N,N,61153,61155,N,N,61154,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,61156,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,61157,N,N,N,N,N,N,N,N,N,61158,61159,61161,N,N,N,N,61160,61163,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61164,60868,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61133,60787,60798,60800,60821,60860,60876,60878, +60921,60994,61017,61025,61026,61027,61029,61033,61036,61045,61057,61059,61060, +61069,61077,61079,61080,61083,61111,61118,61134,61146,61147,61149,61162,61180, +N,N,N,N,61179,N,N,N,N,N,33148,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33119,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33120,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,33169, +33170,33226,N,61178, +}; + +static const struct unim_index cp932ext_encmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_encmap+0,22,121},{__cp932ext_encmap ++100,17,191},{0,0,0},{__cp932ext_encmap+275,96,115},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__cp932ext_encmap+295,29,31},{0,0,0},{__cp932ext_encmap+298,49,168},{ +__cp932ext_encmap+418,3,205},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{__cp932ext_encmap+621,40,252},{__cp932ext_encmap+834,0,255},{ +__cp932ext_encmap+1090,30,244},{__cp932ext_encmap+1305,74,236},{ +__cp932ext_encmap+1468,21,219},{__cp932ext_encmap+1667,0,221},{ +__cp932ext_encmap+1889,138,255},{__cp932ext_encmap+2007,134,134},{0,0,0},{ +__cp932ext_encmap+2008,89,200},{__cp932ext_encmap+2120,158,178},{ +__cp932ext_encmap+2141,11,186},{0,0,0},{__cp932ext_encmap+2317,86,236},{ +__cp932ext_encmap+2468,30,245},{__cp932ext_encmap+2684,39,208},{0,0,0},{ +__cp932ext_encmap+2854,33,222},{__cp932ext_encmap+3044,93,242},{ +__cp932ext_encmap+3194,17,152},{__cp932ext_encmap+3330,19,166},{ +__cp932ext_encmap+3478,245,245},{__cp932ext_encmap+3479,96,206},{ +__cp932ext_encmap+3590,78,78},{__cp932ext_encmap+3591,0,251},{ +__cp932ext_encmap+3843,14,192},{__cp932ext_encmap+4022,1,207},{ +__cp932ext_encmap+4229,104,226},{__cp932ext_encmap+4352,48,228},{ +__cp932ext_encmap+4533,214,214},{__cp932ext_encmap+4534,63,218},{ +__cp932ext_encmap+4690,4,252},{__cp932ext_encmap+4939,39,191},{ +__cp932ext_encmap+5092,136,245},{__cp932ext_encmap+5202,5,187},{ +__cp932ext_encmap+5385,4,254},{__cp932ext_encmap+5636,177,190},{ +__cp932ext_encmap+5650,36,245},{__cp932ext_encmap+5860,7,159},{ +__cp932ext_encmap+6013,1,111},{__cp932ext_encmap+6124,130,166},{ +__cp932ext_encmap+6161,70,70},{__cp932ext_encmap+6162,33,122},{ +__cp932ext_encmap+6252,48,155},{__cp932ext_encmap+6360,209,235},{ +__cp932ext_encmap+6387,158,158},{0,0,0},{__cp932ext_encmap+6388,72,214},{ +__cp932ext_encmap+6531,82,138},{__cp932ext_encmap+6588,71,161},{0,0,0},{0,0,0 +},{0,0,0},{__cp932ext_encmap+6679,1,246},{__cp932ext_encmap+6925,72,220},{ +__cp932ext_encmap+7074,83,176},{0,0,0},{0,0,0},{__cp932ext_encmap+7168,7,245}, +{__cp932ext_encmap+7407,28,28},{__cp932ext_encmap+7408,18,246},{ +__cp932ext_encmap+7637,83,127},{__cp932ext_encmap+7682,240,244},{ +__cp932ext_encmap+7687,18,118},{__cp932ext_encmap+7788,207,207},{0,0,0},{ +__cp932ext_encmap+7789,103,222},{__cp932ext_encmap+7909,21,238},{ +__cp932ext_encmap+8127,6,255},{__cp932ext_encmap+8377,2,248},{ +__cp932ext_encmap+8624,49,72},{__cp932ext_encmap+8648,146,146},{ +__cp932ext_encmap+8649,157,175},{__cp932ext_encmap+8668,51,85},{ +__cp932ext_encmap+8703,87,101},{__cp932ext_encmap+8718,39,158},{ +__cp932ext_encmap+8838,78,220},{__cp932ext_encmap+8981,114,187},{ +__cp932ext_encmap+9055,0,0},{__cp932ext_encmap+9056,107,112},{ +__cp932ext_encmap+9062,25,209},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp932ext_encmap+9247 +,41,220},{__cp932ext_encmap+9427,14,45},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__cp932ext_encmap+9459,2,228}, +}; + +static const ucs2_t __jisx0213_1_bmp_decmap[2197] = { +65287,65282,65293,126,12339,12340,12341,12347,12348,12543,12447,U,U,U,U,U,U,U, +U,8836,8837,8842,8843,8713,8709,8965,8966,U,U,U,U,U,U,U,8853,8854,8855,8741, +8742,10629,10630,12312,12313,12310,12311,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8802, +8771,8773,8776,8822,8823,8596,U,U,U,U,U,U,U,U,9838,9835,9836,9833,9655,9654, +9665,9664,8599,8600,8598,8601,8644,8680,8678,8679,8681,10548,10549,U,U,U,U,U, +U,U,U,U,U,10687,9673,12349,65094,65093,9702,8226,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,8723,8501,8463,13259,8467,8487,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12448,8211,10746,10747,12363,U,12365,U,12367,U, +12369,U,12371,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12436,12437, +12438,12459,U,12461,U,12463,U,12465,U,12467,U,U,U,U,U,U,U,12475,U,U,U,U,U,U,U, +U,12484,U,U,U,12488,9828,9824,9826,9830,9825,9829,9831,9827,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,962,9461,9462,9463,9464,9465,9466,9467,9468, +9469,9470,9750,9751,12320,9742,9728,9729,9730,9731,9832,9649,12784,12785, +12786,12787,12788,12789,12790,12791,12792,12793,U,12794,12795,12796,12797, +12798,12799,9150,9151,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162, +9163,9164,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +12535,12536,12537,12538,8922,8923,8531,8532,8533,10003,8984,9251,9166,12881, +12882,12883,12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894, +12895,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988, +12989,12990,12991,U,U,U,U,U,U,U,U,9680,9681,9682,9683,8252,8263,8264,8265,461, +462,464,7742,7743,504,505,465,466,468,470,472,474,476,8364,160,161,164,166, +169,170,171,173,174,175,178,179,183,184,185,186,187,188,189,190,191,192,193, +194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212, +213,214,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232, +233,234,235,236,237,238,239,240,241,242,243,244,245,246,248,249,250,251,252, +253,254,255,256,298,362,274,332,257,299,363,275,333,260,728,321,317,346,352, +350,356,377,381,379,261,731,322,318,347,711,353,351,357,378,733,382,380,340, +258,313,262,268,280,282,270,323,327,336,344,366,368,354,341,259,314,263,269, +281,283,271,273,324,328,337,345,367,369,355,729,264,284,292,308,348,364,265, +285,293,309,349,365,625,651,638,643,658,620,622,633,648,598,627,637,642,656, +635,621,607,626,669,654,609,331,624,641,295,661,660,614,664,450,595,599,644, +608,403,339,338,616,649,600,629,601,604,606,592,623,650,612,652,596,593,594, +653,613,674,673,597,657,634,615,602,U,509,8048,8049,U,U,U,U,U,U,U,U,8050,8051, +865,712,716,720,721,774,8255,779,769,772,768,783,780,770,741,742,743,744,745, +U,U,805,812,825,796,799,800,776,829,809,815,734,804,816,828,820,797,798,792, +793,810,826,827,771,794,10102,10103,10104,10105,10106,10107,10108,10109,10110, +10111,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,8560,8561,8562,8563, +8564,8565,8566,8567,8568,8569,8570,8571,9424,9425,9426,9427,9428,9429,9430, +9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445, +9446,9447,9448,9449,13008,13009,13010,13011,13012,13013,13014,13015,13016, +13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13050,13033, +13029,13037,13036,U,U,U,U,U,U,U,U,U,8273,8258,9312,9313,9314,9315,9316,9317, +9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,8544, +8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,13129,13076,13090,13133, +13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115,13212, +13213,13214,13198,13199,13252,13217,8555,U,U,U,U,U,U,U,13179,12317,12319,8470, +13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181,13180, +U,U,U,8750,U,U,U,U,8735,8895,U,U,U,10070,9758,20465,U,13314,20008,20015,20016, +20109,20193,20221,20223,20227,20235,20320,20296,20297,20310,20319,20330,20332, +20350,20362,20372,20375,64048,20425,20448,20481,20482,20494,20504,20519,20526, +20544,20539,20545,20628,20684,20722,20688,20710,64049,20742,20739,20747,20766, +20789,20810,64050,20821,20823,13493,20893,20931,20938,20958,20962,20974,20993, +13531,21011,21013,21065,21079,21089,21139,21192,64051,21196,21200,21206,21211, +64052,21232,21243,21248,21255,21276,64053,21345,21347,21373,21395,21405,21426, +21522,21543,21581,21660,21611,21620,21631,21640,21654,21665,21673,21702,21759, +21774,21803,21813,21840,21854,21889,21894,21902,64054,21933,21966,64055,22024, +22030,22075,22089,22134,22118,64056,22127,22129,22130,22169,22174,22185,22188, +22195,22217,22218,22282,U,22305,22319,22323,22324,22384,22391,22396,22428, +64015,U,22456,22471,22472,22479,22500,22509,22517,22518,22527,22537,64016, +22625,22628,64057,22652,22665,22686,64058,22697,U,22738,22734,22740,22746, +22752,22761,22796,34369,22877,22893,22923,22930,22948,22979,22994,23005,23059, +23075,23143,23149,23159,23166,23172,23198,23207,23236,U,23321,23333,21085, +23361,23382,23421,23443,23512,23532,23570,23582,23587,23595,14221,23650,64059, +64060,U,23674,23695,23711,23715,23722,23738,23755,23760,23762,23796,U,14306, +23821,23847,64017,23878,23879,23891,23882,23917,23937,23968,23972,23975,23992, +24011,21534,22099,24034,24084,24088,24152,24158,24254,63784,24267,24313,24320, +24322,24327,24349,24355,24372,24374,24381,24384,24389,24404,24408,24420,24423, +24445,24457,24476,24487,24495,24501,24503,24521,24542,24545,24553,24589,24596, +24600,24627,24629,24647,64061,24733,24734,24779,24788,24789,24797,24824,24860, +24875,24880,24887,64062,24973,64063,25020,25017,64064,25122,25150,25155,25174, +25178,25199,25221,25284,25302,25340,25354,25368,25401,25411,25445,25468,25573, +25581,25589,25616,25620,25634,25721,25681,25696,25709,25806,25790,25791,25796, +25802,25808,25847,25851,25890,25897,64065,25959,26013,64066,26112,26121,26133, +26142,26170,26146,26148,26155,26160,26161,26163,26363,26184,26188,U,26201, +26202,26209,26213,26227,26231,26232,26253,64067,26272,26290,26299,26310,26312, +15138,26331,26344,26362,26387,63785,26419,26470,26439,26440,26491,26497,26515, +26520,26523,26555,26617,26560,26583,26620,26625,26706,26653,26668,26673,26715, +26738,26741,64068,26787,26789,26802,26824,26832,26856,26861,26864,26865,26876, +26890,26953,U,26933,26946,26967,26979,26980,26984,27008,64020,27045,27053, +27087,15286,15299,27106,27113,27114,27125,27126,27151,27157,U,27195,27198, +27205,27216,27222,27227,27243,27251,U,27273,27284,27293,27294,27301,27364, +27367,15375,63773,27419,27422,27436,27445,27462,27478,27488,27493,27495,27511, +27522,27561,27565,63856,27599,27606,27607,27647,27653,27664,27699,27737,27740, +27818,27764,27766,27781,27782,27800,27804,27899,27846,27860,27872,27883,27886, +U,27908,27918,27950,27953,27961,27967,27992,28005,64069,28034,28039,28041, +28052,28074,28076,28095,28100,28118,28122,28123,28125,28156,64070,28212,28228, +28252,28254,28331,28337,28353,28359,28366,28432,28442,64071,28458,28463,28467, +28497,28505,28510,28513,28514,28542,28552,28556,28557,28564,28576,28583,28598, +28604,28615,28618,28665,28656,28661,28677,28678,28712,28746,28765,28766,28750, +28772,28789,28805,28836,28843,28855,28884,28888,28900,28943,28971,28958,28960, +28974,28976,28998,28999,29009,64072,29010,29020,29024,29032,64021,29061,29063, +29074,29121,29114,29124,29182,29184,29205,29269,29270,15935,29325,29339,29374, +29376,29435,U,29479,29480,64022,29520,29542,29564,29589,29599,29600,29602, +29606,29611,29641,29647,29654,29657,29667,29673,29703,29706,29722,29723,64074, +29734,29736,29738,29739,29740,29742,29743,29744,29764,29766,29767,29771,29783, +29794,29803,29805,29830,29831,29833,29848,29852,29855,29859,29840,29862,29864, +29865,29877,29887,29896,29897,29914,29951,29953,29975,29999,30063,30073,30098, +16242,30158,30180,30208,30210,30216,30229,30230,30233,30238,30253,30261,30275, +30283,30308,30309,30317,30319,30321,30337,30363,30365,30366,30374,30378,30390, +30405,30412,30414,30420,30438,30449,30460,30474,30489,30516,30518,30534,30541, +30542,30556,30559,30562,30586,30592,30612,30634,30688,30765,30787,30798,30799, +30801,30824,30830,64075,30896,U,30893,30948,30962,30976,30967,31004,31022, +31025,31028,64076,64077,31045,31046,64078,64079,64080,31068,64081,64025,64026, +31097,64082,64083,64027,31128,31153,31160,31176,31178,U,31188,31198,31211, +31213,31235,64084,31289,31325,31341,64085,31365,31392,U,31411,31419,31438, +31467,31485,31506,31533,31547,31559,31566,31584,31597,31599,31602,31646,64086, +31703,31705,31745,31793,31774,31776,31795,31798,16996,U,31833,31853,31865, +31887,31892,31904,31932,31957,31961,31965,32007,32008,32019,32029,32035,32049, +32065,32072,32083,32092,32122,32131,32139,32160,32166,32194,32204,32214,32227, +64087,32296,32264,32273,32277,64089,32327,32338,32353,32394,32397,32583,64090, +32657,32663,32703,32718,32731,32735,32748,32750,32762,64091,32788,32806,32821, +32823,32828,32970,32983,32992,33011,33048,33098,33120,33127,33128,33133,33211, +33226,33231,33239,64092,17491,17499,33376,33396,U,33422,33441,33443,33444, +33449,33454,33463,33470,33471,33478,33493,33533,33534,33536,33537,33634,33570, +33581,33594,33603,33607,33617,33621,33661,33670,33682,33688,33703,33705,33727, +33728,33735,33743,33745,33761,33770,33793,33798,33802,64095,33864,33887,33904, +33907,33925,33950,33967,33972,33978,33984,33986,U,34098,34078,34083,34095, +34137,34148,64031,34221,34170,34188,34191,34210,34224,34251,34254,34285,34322, +34303,34308,34309,34320,U,34328,34345,34360,34391,34395,63798,34402,17821, +34412,34421,34456,34488,34554,34556,34557,34571,34673,34695,34696,34732,34733, +34741,17898,34774,34796,34822,34826,34832,34836,34847,34968,34986,35018,35022, +U,35061,35100,64096,35096,35097,35098,35111,35120,35122,35129,35136,35220, +64097,35284,35301,35318,35346,35349,35362,35383,35399,35406,35421,35425,35445, +35449,35495,35536,35551,35572,35574,64034,64098,64099,35654,35668,35673,35689, +35741,35913,35944,64100,36065,36084,36088,36094,64101,36114,36123,36271,36302, +36305,36311,36384,36387,36413,36464,36475,U,36544,18500,36602,36638,36653, +36662,36692,U,36774,36789,36836,36840,36846,36872,36909,64103,37000,37013, +37015,37017,37019,37026,37043,37054,37060,37061,37063,37079,37085,37086,37103, +37108,64038,37140,37141,37142,37154,37155,37159,37167,37169,37172,37181,37192, +37211,37251,37278,37292,37297,37308,37335,37371,37348,37349,37357,37361,37383, +37392,37432,37433,37434,37436,37440,37443,37455,37496,37512,37570,37579,37580, +37587,37600,37631,37636,37663,37665,37669,37704,37705,37706,37732,37733,37738, +37744,37787,37795,37818,37830,37854,37855,37892,37885,37939,37962,37987,37995, +38001,38002,38286,38303,38310,38313,38316,38326,38333,38347,38352,38355,18864, +38362,38366,38488,38532,63964,38557,38564,38565,38610,38622,64104,38633,38639, +38707,38715,38733,38734,38735,38746,38766,38771,38805,38830,38842,38849,38857, +38878,38875,38900,64105,38922,38942,38955,38960,64106,38994,38995,38998,38999, +39001,39002,63952,39013,39020,39098,39112,39143,39256,39326,39426,39427,39460, +39469,39470,39480,39498,39502,39506,39606,39617,39619,39630,39638,39673,39682, +39688,39712,19479,39725,39774,39801,39782,39794,39797,39812,39818,39823,39838, +39847,39873,39886,39909,39928,39933,39936,39971,40001,40015,40016,40019,40035, +40037,40055,40221,40222,40259,40263,40274,40291,40304,40316,40330,40342,40384, +40364,40380,40407,U,40423,40455,40469,40572,40606,40612,40620,40623,40628, +40629,40643,40657,40720,40761,40791,40848,40852,40855,40866,23032,23643,24183, +30246,32363, +}; + +static const struct dbcs_index jisx0213_1_bmp_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_bmp_decmap+0,47,125},{ +__jisx0213_1_bmp_decmap+79,33,126},{__jisx0213_1_bmp_decmap+173,43,118},{ +__jisx0213_1_bmp_decmap+249,43,72},{__jisx0213_1_bmp_decmap+279,57,126},{ +__jisx0213_1_bmp_decmap+349,66,126},{__jisx0213_1_bmp_decmap+410,65,124},{ +__jisx0213_1_bmp_decmap+470,33,126},{__jisx0213_1_bmp_decmap+564,33,126},{ +__jisx0213_1_bmp_decmap+658,33,126},{__jisx0213_1_bmp_decmap+752,33,126},{ +__jisx0213_1_bmp_decmap+846,33,126},{__jisx0213_1_bmp_decmap+940,33,126},{ +__jisx0213_1_bmp_decmap+1034,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_bmp_decmap+ +1128,85,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__jisx0213_1_bmp_decmap+1170,39,126},{__jisx0213_1_bmp_decmap+1258,33,126},{ +__jisx0213_1_bmp_decmap+1352,33,126},{__jisx0213_1_bmp_decmap+1446,33,126},{ +__jisx0213_1_bmp_decmap+1540,33,125},{__jisx0213_1_bmp_decmap+1633,33,126},{ +__jisx0213_1_bmp_decmap+1727,33,126},{__jisx0213_1_bmp_decmap+1821,33,126},{ +__jisx0213_1_bmp_decmap+1915,33,126},{__jisx0213_1_bmp_decmap+2009,33,126},{ +__jisx0213_1_bmp_decmap+2103,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const ucs2_t __jisx0213_2_bmp_decmap[2425] = { +19970,19983,19986,20009,20011,20014,20032,20039,20040,U,20049,13318,U,20058, +20073,20125,13356,13358,20153,20155,U,20156,20163,20168,20176,20203,20186, +20209,20213,20224,20246,20324,20279,20286,20308,20312,U,20343,20344,20346, +20349,20354,20357,20370,20378,20454,20402,20414,20421,20427,20431,20434,13418, +20466,20480,20496,20499,20508,20510,20514,13416,20546,20550,20558,20563,20567, +20579,20582,20586,20592,20643,20616,20626,20627,20629,20630,20636,20650,U, +20657,20666,20667,20676,20679,20723,U,20686,U,20692,20697,20705,20713,13458, +20744,U,20759,20763,U,20832,U,20851,20867,20875,13500,20888,20899,20909,13511, +20924,U,U,20979,20980,20994,21010,21014,U,21077,21084,21100,21111,21124,21122, +U,21144,U,21156,21158,21167,21178,21179,21194,13599,21201,U,21239,21258,21259, +21284,21301,21310,21314,U,U,21351,21356,21370,21412,21428,U,21431,21440,U, +13661,13662,21461,21466,13667,21492,21493,21589,21540,21544,13678,21571,21602, +21606,21612,21642,21645,21653,21664,21670,21677,21678,21687,21690,21695,21699, +U,21740,21743,21745,21747,21760,21761,21769,21820,21825,13734,21831,21834, +13736,21856,21857,21860,U,21885,21890,21896,21905,13765,21970,U,U,21951,21961, +21964,21969,21981,13786,21986,U,21993,22056,U,22023,22032,22064,22071,13812, +22077,22079,22080,22087,22110,22112,22125,13829,22152,22156,22165,22170,22173, +22184,22189,22194,22213,22221,22239,22248,22262,22263,U,22293,22307,U,22313,U, +22341,22342,22348,22349,U,22376,22383,22387,22388,22389,22395,U,U,22444,22426, +22429,22430,22440,22487,U,22476,U,U,22494,22502,22512,13898,22520,22523,22525, +22532,22558,22560,22567,22578,22585,U,22601,22604,22631,22666,22667,22669, +22671,22672,22676,22685,22698,22705,U,22723,22733,22754,22771,22772,22789, +22790,22795,22797,22804,22820,U,13969,22845,13977,22854,13974,U,22875,22879,U, +22901,22902,22908,22943,22958,22972,22984,22989,23006,23011,23012,23015,23022, +U,U,14031,23052,23053,23063,23079,23085,23125,23141,23162,23179,23196,23199, +23200,23202,23217,23219,23221,23226,23231,23258,23260,23264,23269,23280,23278, +23285,23296,23304,23319,23348,23341,23372,23378,23400,23407,23420,23423,23425, +23428,23446,23468,14177,23488,14178,23502,23510,14188,14187,23537,23549,14197, +23555,23593,23600,U,23647,23651,23655,23656,23657,23664,U,U,23676,U,U,23688, +23690,14273,U,U,23712,23714,23718,23719,U,23725,23733,U,23753,U,U,23814,23824, +23851,23837,23840,23844,23846,23857,23865,23874,14312,23905,23914,14324,23920, +U,14333,23944,14336,23954,23956,23959,23961,23984,23986,23988,U,23993,24017, +24023,24024,24032,U,24036,24041,14383,24064,14390,24082,24085,14400,24095, +24110,24126,24137,14428,24150,14433,24171,24172,24173,24174,U,24229,24234, +24236,24249,24255,24262,24274,24281,U,24317,24328,24334,24348,U,24350,24391, +24419,24434,24446,24463,24482,24484,24504,24516,14586,24519,24523,24530,24531, +24532,24546,24558,24559,24563,24572,14615,24599,24610,24612,14618,24652,24703, +24714,24725,24744,U,24752,24753,24766,24776,24793,24795,24814,24818,24821, +24848,24850,24851,24857,24862,24890,14703,24897,24902,24928,24956,U,24978, +24979,24983,24984,24997,25000,25005,U,25045,25053,25055,25077,U,25109,25123, +25129,25158,25164,25169,25170,25185,25188,25211,25197,25203,25241,25254,25301, +U,25341,25347,25357,25360,U,U,25394,25397,25403,25404,25409,25412,25422,U, +25433,U,U,25452,25476,25497,U,25492,25533,25591,25556,25557,25564,25568,25579, +25580,25586,25609,25630,25637,25641,25647,25690,25691,25693,25715,25725,25735, +25745,25757,25759,25803,25804,25813,25815,U,25828,25829,25855,25860,14958, +25871,25876,25878,14963,25886,25906,25924,25940,25963,25978,25985,25988,25989, +25994,26034,26037,26040,26047,26050,26057,26068,15062,26098,26105,26108,26116, +26120,26145,26154,26181,26193,26190,15082,U,26199,26203,26211,U,U,26218,26219, +26220,26221,26235,26240,26256,26258,26265,15118,26285,26289,26293,15130,26303, +15132,26348,15063,26369,26373,26386,U,26393,U,U,26444,26445,26452,26461,U,U,U, +26484,26486,U,26514,U,33635,26640,26544,26546,26563,26568,26578,26585,26587, +26608,26615,U,U,U,26648,26655,26669,U,26675,26683,26686,26692,26693,26697, +26700,26709,26711,15223,26731,26734,26746,26748,26754,26768,26774,15213,26776, +26777,26778,26780,26794,26795,26804,26811,26875,U,U,64019,26819,26821,26828, +26831,26838,26841,26852,26853,26860,26871,26883,26887,15239,15240,U,26939, +15245,26950,26985,26988,26994,27002,27007,27026,15268,27030,27032,27046,27056, +27063,27066,27068,27072,27089,27094,U,U,27184,U,U,27107,27118,27119,27123, +15309,27124,27134,27153,27162,27165,U,27186,27187,27188,27199,27206,27209, +27258,27214,27218,27236,U,27262,27267,27275,15344,27281,27295,27297,U,27307, +27325,27334,27348,27344,27356,27357,U,U,27372,27377,27378,27379,27389,U,27403, +27407,27408,27409,U,27415,15398,27439,27466,27480,27500,27509,27514,27521, +27547,27566,U,27581,27582,27591,27592,27593,27610,27622,27623,27630,27633, +27650,27658,27662,27701,27702,27706,U,27711,27725,27739,27757,27780,27785, +15555,27796,27797,27799,27821,27842,27856,15570,27862,27866,27868,27881,27884, +27885,U,27904,27914,27940,27942,27943,27751,27951,27964,27995,27998,28000, +28016,28032,28033,28042,28045,28049,28056,U,28183,U,U,U,28075,28078,28084, +28098,27956,28104,28110,28111,28112,28127,28137,28150,28214,28190,28194,28199, +15633,28210,28220,28232,28233,28235,28236,28239,28241,28243,28244,28247,28259, +15646,28307,28327,28340,28351,28355,28362,28377,28469,28395,28409,28411,28426, +28428,28440,28453,28470,28476,U,28498,28503,28506,28512,28520,28568,28541, +28560,28566,28606,28575,28581,28591,15716,28597,28616,28617,28634,28638,28649, +U,28668,28672,28679,28682,28707,U,28729,28730,28732,28739,28743,28747,15770, +28756,28773,28777,28780,28782,28790,28798,28801,28806,28821,28823,28859,U, +28831,28849,U,28908,28874,28881,28883,28892,28931,28932,28934,28935,28936, +28940,15808,28975,28977,29008,29002,29011,29022,15828,29078,29056,29083,29088, +29090,29102,29103,29107,U,29131,29139,29145,29148,29191,15877,64073,29227, +29236,29240,29241,20012,29250,29267,29271,29283,U,29294,29295,29304,29311, +29326,U,29357,29358,29360,29361,29377,15968,29388,15974,15976,29427,29434, +29447,29458,29464,29465,16003,29497,29484,29489,29491,29501,29522,16020,29547, +29548,U,29550,29551,29553,29559,29569,29573,29578,29588,29592,29596,29598, +29605,29608,29621,29623,29625,29628,29631,29637,29643,29665,29671,29689,29715, +29690,29697,29732,29745,29753,29779,29760,29763,29773,29778,29789,29809,29825, +29829,29832,U,29842,29847,29849,29856,29857,29861,29866,29867,29881,29883, +29882,29910,29912,29918,29935,29931,U,29946,U,29984,29988,29994,16215,U,30013, +30014,30016,30024,30030,30032,30034,30060,30066,30065,30074,30077,30078,30081, +U,30092,16245,30114,16247,30128,30135,30143,30144,30150,30159,30163,30173, +30175,30176,30183,30188,30190,30193,30201,30211,30232,30215,30223,16302,U, +30227,30235,30236,U,30245,30248,30268,30259,U,16329,30273,U,30281,30293,16343, +30318,30357,30364,30369,30368,30375,30376,30383,U,30409,U,30440,30444,U,30487, +30490,30509,30517,16441,U,U,30552,30560,30570,U,30578,30588,30589,U,16472, +30618,30623,30626,30628,30633,30686,30687,30692,30694,30698,30700,16531,30704, +30708,30715,U,30725,30726,30729,30733,30745,30753,30764,30791,30820,30826,U, +30858,30868,30884,30877,30878,30879,30907,30920,30924,30926,30933,30944,30945, +30950,30969,30970,30971,30974,U,30992,31003,31024,31013,31035,31050,31064, +31067,16645,31079,31090,31124,31125,31126,31131,31137,31145,31156,31163,31170, +31175,31180,31181,31190,16712,U,U,16719,31242,31249,31253,31259,31262,16739, +31277,31288,31303,31308,31318,31321,31324,31327,31328,31335,31338,31349,31352, +31362,31370,31376,31395,31404,U,16820,31417,31420,31422,16831,31436,31441, +31463,31464,31476,U,U,31495,U,31549,31527,31530,31534,31535,31537,16870,16883, +31615,31553,16878,31573,31609,31588,31590,31593,31603,U,16903,31632,31633, +31643,16910,31663,31669,31676,31685,31690,U,U,31700,31702,31706,31722,31728, +31747,31755,31758,31759,31782,31813,31818,31825,31831,31838,31841,31849,31854, +31855,31856,U,U,U,31910,U,31926,31927,31935,U,31940,U,31944,31949,U,31959,U, +31974,31979,U,31989,32003,32009,17094,32018,32030,U,U,32061,32062,32064,32071, +U,U,17110,32089,32090,32106,32112,17117,32127,U,32134,32136,32140,32151,U, +32157,32167,32170,32182,32183,32192,32215,32217,32230,32241,32249,17154,U, +64088,32272,32279,32285,32288,32295,32300,32325,32371,32373,32382,32390,32391, +17195,32401,32408,32410,17219,32572,32571,32574,32579,32580,32591,13505,U, +32594,U,32609,32611,32612,32621,32637,32638,U,32656,20859,U,32662,32668,32685, +U,32707,32719,32739,32741,32751,32754,32770,32778,32776,32782,32785,32790, +32804,32812,32816,32835,32870,32881,32885,32891,32921,32924,32932,32935,32952, +U,32965,32981,32984,32998,U,33037,33013,33019,17390,33077,33046,33054,17392, +33060,33063,33068,U,33085,17416,33129,17431,33153,17436,33156,33157,17442, +33176,33202,33217,33219,33238,33243,U,33252,U,33260,U,33277,33279,U,33284,U, +33305,33313,33314,U,33330,33332,33340,33350,33353,33349,U,33355,17526,33359, +17530,33367,U,33372,33379,U,64093,64094,33401,17553,33405,33407,33411,33418, +33427,33447,33448,33458,33460,33466,33468,33506,33512,33527,33543,33544,33548, +33620,33563,33565,33584,33596,33604,33623,17598,33663,17620,17587,33677,33684, +33685,33691,33693,33737,33744,33748,33757,33765,33785,33807,33809,33813,U, +33815,33849,33866,33871,33873,33874,33881,33882,33884,U,33893,33910,33912, +33916,33921,17677,34012,33943,33958,33982,17672,33998,33999,34003,U,34023, +34026,34031,34032,34033,34042,34045,34060,34075,34084,34085,34091,34100,34127, +34159,17701,17731,34110,34129,34131,34142,34145,34146,U,34171,34173,34175, +34177,34182,34195,34205,34207,34231,34236,34247,34250,34264,34265,34271,34273, +34278,34294,34304,34321,34334,34337,34340,34343,U,34361,34364,U,34368,64032, +34387,34390,34415,34423,34426,34439,34441,34445,34449,34460,34461,34472,64033, +34481,34483,34497,34499,34513,34517,34519,34531,34534,17848,34565,34567,34574, +34576,34579,34585,34591,34593,34595,34609,34618,34622,34624,34627,34641,34648, +34660,34661,34674,34684,U,U,34727,34697,34699,34707,34720,U,17893,34750,U, +34753,34766,34805,34783,U,34787,34789,34790,34794,34795,34797,34817,34819, +34827,34835,34856,34862,34866,34876,17935,34890,34904,34911,34916,U,U,34921,U, +34927,34976,35004,35005,35006,35008,35026,U,35025,35027,35035,35056,35057, +17985,35073,U,35127,U,35138,35141,35145,U,18021,35170,35200,35209,35216,35231, +35248,35255,35286,35288,35307,18081,35313,35315,35325,35327,18095,35345,35348, +U,35361,35381,35390,35397,35405,35416,35502,35472,35511,35518,35543,35580,U, +35594,35589,35597,35612,35615,35629,35651,18188,35665,35678,35702,35711,35713, +35723,35732,35733,35740,35742,35897,U,35901,U,U,35909,35911,35919,35924,35927, +35945,35949,35955,U,35987,35986,35993,18276,35995,36004,36054,36053,36057,U, +36080,36081,U,36105,36110,36204,36228,36245,36262,U,36294,36296,36313,36332, +36364,18429,36349,36358,U,36372,36374,36385,36386,36391,U,18454,36406,36409, +36427,36436,36450,36460,36461,36463,36504,36510,36526,36531,36533,36534,36539, +U,36561,36564,18510,36601,U,36608,36616,36631,36651,36672,36682,36696,U,36772, +36788,64102,36790,U,36801,36806,64036,36810,36813,36819,36821,36832,36849, +36853,36859,36866,36876,36919,U,36931,36932,36957,36997,37004,37008,38429, +37025,18613,37040,37046,37059,37064,U,37084,37087,U,37110,37106,37120,37099, +37118,37119,37124,37126,37144,37148,37150,37175,37177,37178,37190,37191,37207, +37209,37217,37220,37236,37241,37253,37262,37288,37294,37299,37302,37315,37316, +37338,U,U,37356,37358,37377,37386,37398,37399,U,37427,37442,37447,37450,37454, +37457,37462,37465,37472,37473,37477,37479,37480,U,U,37500,37501,37503,37513, +37517,37527,37529,37535,37543,37547,U,U,37554,37567,37568,37574,37582,37584, +37591,37593,37605,37607,37649,37623,37625,37627,37634,37645,37653,37661,37662, +37671,37673,U,U,37703,37713,37719,37722,37739,37745,37747,37793,U,U,37768, +37771,37775,37790,37877,U,U,37873,37825,37831,37852,37858,37863,37897,37903, +37910,37911,37883,37938,37940,37947,37957,U,U,37997,37999,38264,38265,38278, +38284,38285,U,38315,38324,U,38344,U,U,38444,38451,38452,U,38460,38465,38497,U, +38530,U,38554,U,18919,38569,38575,38579,38586,38589,18938,U,38616,38618,38621, +18948,38676,38691,18985,38710,38721,38727,38741,38743,38747,38762,U,U,38806, +38810,38814,38818,38833,38834,38846,38860,38865,38868,38872,38873,38881,38897, +38916,38925,38926,38932,38934,19132,U,38947,38962,38963,38949,38983,39014, +39083,39085,39088,U,39095,39096,39099,39100,39103,39106,39111,39115,39136,U, +39137,39139,39141,39146,39152,39153,39155,39176,19259,U,39190,39191,U,39194, +39195,39196,U,39217,39218,39219,39226,39227,39228,39232,39233,39238,39245, +39246,39260,39263,39264,39331,39334,39353,39357,39359,39363,39369,39380,39385, +39390,U,39408,39417,39420,39434,39441,39446,39450,39456,39473,39478,39492, +39500,39512,19394,39599,19402,39607,19410,39609,U,39622,39632,39634,39637, +19432,39644,39648,39653,39657,39683,39692,39696,39698,39702,39708,39723,39731, +39741,19488,39755,39779,39781,39787,39788,39795,39798,39799,39846,39852,39857, +U,U,39858,39864,39870,39879,39923,39896,39901,39911,39914,39915,39919,39918,U, +39930,U,39927,U,39958,39960,39961,39962,39965,39970,39975,39977,39978,U,39985, +39990,39991,40005,40028,U,40009,40010,U,40020,40024,40027,40029,40031,40041, +40042,40043,40045,40046,40048,40050,40053,40058,40166,40178,40203,40194,U, +40209,40215,40216,U,19652,U,40242,19665,40258,40266,40287,40290,U,40297,40299, +U,40307,40310,40311,40318,40324,40333,40345,40353,40383,40373,40377,40381, +40387,40391,40393,40406,40410,40415,40416,40419,40436,19719,40458,40450,40461, +40473,40476,40477,40571,U,40576,40581,40603,40616,U,40637,U,40671,40679,40686, +40703,40706,19831,40707,40727,40729,40751,40759,40762,40765,40769,40773,40774, +40787,40789,40792,U,40797,U,40809,U,40813,40816,40821, +}; + +static const struct dbcs_index jisx0213_2_bmp_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+0,34,126},{0,0,0},{ +__jisx0213_2_bmp_decmap+93,33,126},{__jisx0213_2_bmp_decmap+187,33,126},{ +__jisx0213_2_bmp_decmap+281,33,125},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+ +374,33,126},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_bmp_decmap+468,33,126},{ +__jisx0213_2_bmp_decmap+562,33,126},{__jisx0213_2_bmp_decmap+656,33,126},{ +__jisx0213_2_bmp_decmap+750,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__jisx0213_2_bmp_decmap+844,33,126},{__jisx0213_2_bmp_decmap+938,33,126},{ +__jisx0213_2_bmp_decmap+1032,33,126},{__jisx0213_2_bmp_decmap+1126,33,126},{ +__jisx0213_2_bmp_decmap+1220,34,126},{__jisx0213_2_bmp_decmap+1313,33,126},{ +__jisx0213_2_bmp_decmap+1407,33,126},{__jisx0213_2_bmp_decmap+1501,33,126},{ +__jisx0213_2_bmp_decmap+1595,33,125},{__jisx0213_2_bmp_decmap+1688,35,126},{ +__jisx0213_2_bmp_decmap+1780,33,126},{__jisx0213_2_bmp_decmap+1874,33,125},{ +__jisx0213_2_bmp_decmap+1967,34,125},{__jisx0213_2_bmp_decmap+2059,34,126},{ +__jisx0213_2_bmp_decmap+2152,33,126},{__jisx0213_2_bmp_decmap+2246,33,126},{ +__jisx0213_2_bmp_decmap+2340,33,117},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const DBCHAR __jisx0213_bmp_encmap[27287] = { +8754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10530, +10531,N,N,10532,N,10533,N,N,10534,10535,10536,N,10537,10538,10539,N,N,10540, +10541,N,N,N,10542,10543,10544,10545,10546,10547,10548,10549,10550,10551,10552, +10553,10554,10555,10556,10557,10558,10559,10560,10561,10562,10563,10564,10565, +10566,10567,10568,10569,10570,10571,10572,10573,N,10574,10575,10576,10577, +10578,10579,10580,10581,10582,10583,10584,10585,10586,10587,M,10589,10590, +10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602,10603, +10604,N,10605,10606,10607,10608,10609,10610,10611,10612,10613,10618,10810, +10825,10785,10796,10812,10827,10841,10847,N,N,10813,10828,10816,10831,N,10832, +10616,10621,N,N,N,N,10814,10829,10815,10830,10842,10848,N,N,N,N,N,N,10843, +10849,N,10877,N,N,10614,10619,N,N,N,N,N,N,N,N,10844,10850,N,N,N,10811,10826,N, +N,10788,10799,N,N,10787,10798,10817,10833,N,N,10818,10834,N,N,10874,10617, +10622,N,N,10819,10835,11051,11050,10809,10824,N,N,10820,10836,10789,10800, +10845,10851,10791,10803,10790,10802,10823,10839,10792,10804,N,N,N,N,10615, +10620,10846,10852,10821,10837,10822,10838,N,N,N,N,N,N,N,10793,10805,10795, +10808,10794,10807,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11049,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +11044,N,N,N,N,N,N,N,N,N,N,10351,10352,N,10353,10358,10359,N,10360,N,10361,N, +10362,N,10363,N,10364,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +10356,10357,N,N,N,11077,11059,11065,11066,11045,M,11071,10862,11046,11054,M,M, +N,11057,N,11058,10869,11048,10873,N,N,11062,11068,11042,11074,11052,N,N,N, +10858,10868,10859,11060,10875,10853,10870,10863,N,11055,N,N,N,10860,11073, +10867,N,10864,10855,N,N,10876,10865,10856,11047,N,N,N,10861,11053,11061,10854, +M,11067,10872,N,10866,11072,10857,N,11041,10878,N,N,11043,N,N,N,N,10871,N,N,N, +11070,11069,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,10801,11091,N,N,N,11092,N,N,N,11093,11094,N,N,N,N,N,N,10786,10840,N, +10797,N,10806,11121,N,N,N,N,N,N,M,11105,11106,11107,M,11100,11098,11103,11133, +11099,N,11095,N,11117,N,N,11097,11102,N,N,11101,N,N,N,N,N,N,N,N,11128,11129, +11134,N,11114,11126,11127,11115,11116,N,N,N,11122,11111,N,N,N,11119,11130,N, +11112,N,N,11120,11123,N,N,N,11125,N,N,N,N,11113,11131,11132,11124,11118,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11090,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,9817,10354,10355,11078,11079,11088,11089,9084,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,9024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,10347,N,N,11096,N,N,11390,N,N,N,N,10348,10349,10350,N,N,N,N,N,N,N,11389,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,10529,9053,N,N,N,9055,N,N,11618,N,N,N,N,N,N,N,N,N,N,11620, +N,N,N,N,N,9056,N,N,N,N,N,N,N,N,N,N,N,N,N,9052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,10104,10105,10106,N,N,N,N,N,N,N,N,N,N,11573,11574, +11575,11576,11577,11578,11579,11580,11581,11582,11583,11607,N,N,N,N,11317, +11318,11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8817,N,8999,8997,8998,9000,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9001,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9003,9004, +9002,9005,8775,N,N,N,8774,N,N,N,N,N,N,N,N,N,9051,N,N,N,N,N,N,N,N,N,N,N,11640, +N,N,N,N,N,8788,8789,N,N,N,N,N,N,N,11635,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,8812,N,8813,N,N,8814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8811, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8815,8816,N,N,N,N,N,N,N,N,N,N,N,N,8770, +8771,N,N,N,N,8772,8773,N,N,N,N,N,N,N,N,N,8785,8786,8787,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11641,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10102,10103,8776,8777,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,10108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10050,10051,10052,10053,10054,10055, +10056,10057,10058,10059,10060,10061,10062,10063,10064,N,10110,10109,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11553,11554,11555,11556,11557,11558,11559, +11560,11561,11562,11563,11564,11565,11566,11567,11568,11569,11570,11571,11572, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,11329,11330,11331,11332,11333,11334,11335,11336, +11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,11348,11349, +11350,11351,11352,11353,11354,N,11307,11308,11309,11310,11311,11312,11313, +11314,11315,11316,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9837,N,N, +N,N,8994,8993,N,N,N,N,N,N,N,N,8996,8995,N,N,N,N,N,N,N,9019,N,N,N,N,N,N,10343, +10344,10345,10346,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9023,9832,9833,9834, +9835,N,N,N,N,N,N,N,N,N,N,9831,N,N,N,N,N,N,N,9828,9829,N,N,N,N,N,N,11646,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9786,9789,9787,9792,9785,9790, +9788,9791,9836,8829,N,8827,8828,N,8826,10107,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,11645,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,11297,11298,11299,11300,11301,11302,11303,11304,11305,11306,9006, +9007,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,8790,8791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,9018,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,9085,9086,8794,8795,8792,8793,N,N,N,11616,N,11617,9830,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8755,8756,8757,N,N,N,N,N,8758,8759,9020,N,N,N, +N,N,N,N,N,N,N,N,N,N,M,N,M,N,M,N,M,N,M,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,9332,9333,9334,N,N,N,N,N,N,N,N,8761,9083,N,N,N,N,N,N,N,N,N,N,M,N,M, +N,M,N,M,N,M,N,N,N,N,N,N,N,M,N,N,N,N,N,N,N,N,M,N,N,N,M,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10098, +10099,10100,10101,N,N,N,N,8760,9838,9839,9840,9841,9842,9843,9844,M,9846,9847, +9849,9850,9851,9852,9853,9854,11626,11627,N,N,N,N,N,N,11628,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,10305,10306,10307,10308,10309,10310,10311,10312, +10313,10314,10315,10316,10317,10318,10319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,11621,11622,11623,11624,11625,N,N,N,N,N,N,N,N,10320, +10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333, +10334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11355,11356,11357,11358,11359,11360, +11361,11362,11363,11364,11365,11366,11367,11368,11369,11370,11371,11372,11373, +11374,N,11377,N,N,N,11376,N,N,11379,11378,N,N,N,N,N,N,N,N,N,N,N,N,11375,11590, +N,N,N,N,N,N,N,N,N,11594,N,N,N,N,N,N,11585,N,N,N,11588,N,N,N,N,N,N,N,N,N,11586, +11596,N,N,11595,11589,N,N,N,11597,N,N,N,N,N,N,N,N,N,N,11591,N,N,N,N,11599,N,N, +N,N,N,N,N,N,N,N,N,N,N,11584,11598,N,N,11587,N,N,N,11592,N,N,N,N,N,11593,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11615,11631, +11630,11629,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11603,11604,N,N,N,N,N,N,N,N,N,N,N,N, +11600,11601,11602,N,N,11606,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,11605,N,N,N,N,N,N,9054,N,11619,11811,N,N,N,41261,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41266,N,41267, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41310,N,41302,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41342,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11859,N,N,N,N,N,N,41771,N,N,N,N, +62568,N,N,N,N,N,41775,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11867,41800,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41821,41822,N,N,N,N,41825,N,N,N,N,N,N,N, +N,N,N,41831,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42019,N,42022,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,42040,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42050,42058,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42105,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42303,N,N,N,N,42307,N,N,42305,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,42327,43043,43045,N,N,N,N,N,N,N,N,43049,43048,N,N,N,N,N, +N,N,N,43052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20319,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,43070,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,20335,N,N,N,N,N,43094,N,N,N,N,N,N,N,N,N,N,N,43097,N,N,N,N,N,N,N,N,43100, +43102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,43119,N,N,N,N,N,N,43121,N,N,N,N,N,N,N,N,N,43124,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43129,N,N,N,N,43131,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44091,44102,N,N,44106, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,44128,44379,N,N,N,N,44383,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +44401,44598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44412,44590,N,N,N,N,N,N,N,N,N, +N,N,44594,N,44596,N,N,N,N,N,30025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,44653,N,N,N,N,N,N,N,N,N,44645,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,44840,44841,N,N,N,N,44844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +44852,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30078,N,N,N,N,N,N,N,N,N,N,N,N,30241,N, +N,N,N,N,N,N,N,N,44872,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,44893,30266,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44919,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +60987,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60994,61041,N,N,N,N,N,N,N,N,N,N,N,N,61054,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61248,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,61268,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,61296,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61303,61480,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30566,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,61503,N,N,N,N,N,61505,N,61506,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,61513,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61520,61748,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30797,N,N,61766,N,61768,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,61788,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,61799,N,N,N,N,N,N,N,N,N,N,N,N,N,61804,61986,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61997,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +62009,62052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62068,N,N,N, +N,N,N,62071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62077,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62259,N,N,N,N,N,N, +N,N,N,N,62263,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,62279,N,N,N,N,N,N,N,62283,N,N,N,N,62280,62291,N,N,N,N,N,N,62295,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,31085,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62507,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,62518,N,N,N,N,N,N,62523,62542,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62557,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,62561,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62782,N,62786,62792,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,62794,N,N,N,N,62796,N,N,N,N,N,62799,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +31321,N,N,N,N,N,N,N,31322,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +62828,N,N,N,62830,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62839,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63029,N,N,N,N,N,N,N,N, +N,N,63026,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63028,63065,N,N,N,N,63060, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63085,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31569,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63340,N,N,N,N,31584, +63524,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,63546,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,63555,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63566,N, +N,N,N,N,N,N,N,N,N,N,N,N,63571,63595,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63785,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63807,63817,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +31819,N,N,N,N,N,N,N,N,N,63836,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64039,32088,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64362,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,64368,64373,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,64376,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64567,64597,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64806,N,N,N,N,N,N,N,64808,N,N,N, +N,N,N,N,64810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64817,32318,N,N,N,N,N, +N,N,N,64831,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,65066,N,N,N,N,N,N,N,N,N,N,N,N,65069,65099,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65120,41250,N,N,N,N,N, +N,N,N,N,N,N,N,41251,N,N,41252,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11812, +41253,N,41254,61486,N,41255,11813,11814,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41256,N, +N,N,N,N,N,41257,41258,N,N,N,N,N,N,N,N,41260,N,N,N,N,N,N,N,N,41263,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,41264,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,11815,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41265,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41268,N,41269,41271,N,N,N,N,N,N,41272,N,N,N,N, +41273,N,N,N,N,N,N,N,41274,N,N,N,N,N,N,N,N,N,41276,N,N,N,N,N,N,11816,N,N,N,N,N, +N,N,N,N,41275,N,N,N,N,N,41277,N,N,N,41278,N,N,N,N,N,N,N,11817,N,11818,41279,N, +N,11819,N,N,N,N,N,N,N,11820,N,N,N,N,N,N,N,N,N,N,41280,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41282,N,N,N,N,N,N,41283,N,N,N,N,N,N,N, +N,N,11822,11823,N,N,N,N,N,N,N,N,N,N,41284,N,11824,N,41285,N,N,N,N,N,N,11825, +11821,N,N,N,41281,N,N,N,N,N,11826,N,11827,N,N,N,N,N,N,N,N,N,N,41287,41288,N, +41289,N,N,41290,11828,N,N,N,41291,N,N,41292,N,N,N,N,11829,N,N,N,N,N,N,N,41293, +N,11830,N,N,11831,N,N,41294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +41296,N,N,N,N,N,N,N,N,N,N,N,41297,N,N,N,N,N,N,41298,N,N,N,11833,N,41299,N,N,N, +41300,N,N,41301,N,N,N,N,N,N,N,N,N,N,N,N,N,11834,N,N,N,N,N,41295,N,N,N,N,N,N,N, +N,N,N,11809,41303,41304,11835,11836,N,N,N,N,N,N,N,N,N,N,N,11837,N,41305,N,N, +41306,N,N,N,N,11838,N,N,N,41307,N,41308,N,N,N,41309,N,N,N,N,11839,N,N,N,N,N,N, +11840,N,N,N,N,N,N,N,N,N,N,N,N,11842,N,N,N,N,11841,11843,41311,N,N,N,41312,N,N, +N,N,N,N,N,41313,N,N,N,N,41314,N,N,N,41315,N,N,N,N,N,N,N,N,N,N,N,41316,N,N, +41317,N,N,N,41318,N,N,N,N,N,41319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,41321,N,N,N,N,N,N,N,N,N,41322,41323,11844,41324,41325,N,N,N,N,N,41326,N,N,N, +N,N,N,41320,N,N,N,N,N,N,41327,N,N,N,N,N,N,41329,N,N,N,N,N,N,N,N,41330,41331,N, +N,N,N,N,N,N,N,41332,N,N,41333,N,N,N,N,11845,N,41336,N,11847,N,N,N,41338,N,N,N, +N,41339,N,N,N,N,N,N,N,41340,N,N,N,N,11848,N,N,41341,N,N,N,N,N,N,N,N,11846, +41334,11851,N,N,11850,N,41761,N,N,11852,N,N,N,N,N,N,N,N,N,N,N,41763,N,N,N, +41764,N,N,11853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11854,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,11855,N,N,N,N,N,N,N,N,N,N,11857,N,11858,N,N,N,N,N, +N,N,N,41766,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41768,N,N,N,N,N,N,N,62580,N,N, +N,N,N,N,N,41769,N,N,N,N,N,N,N,41770,N,N,N,N,N,N,N,N,N,N,N,N,41772,N,N,N,N, +11860,N,N,N,N,N,41773,N,N,N,N,N,N,N,N,N,41774,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +41776,N,N,N,N,N,N,11861,N,N,N,N,N,N,11862,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,11863,N,N,N,11864,N,N,N,N,N,N,N,N,N,N,N,11865,N,N,N,N,41779,41780,11866, +41781,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41782,11868,N,11869,41783,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,11870,N,N,N,N,N,N,N,N,N,N,N,41785,N,11871,N,N,N,N,41786,12158,N,N,N, +11872,N,N,N,N,N,N,N,N,N,N,41787,N,N,N,N,N,N,N,N,N,N,41788,N,N,N,N,N,N,N,N,N,N, +41790,N,41789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11873,N,N,N,N,41792,N,N,N,N,N,N,N,N, +N,N,N,41794,N,41795,N,N,N,N,N,N,N,N,41796,N,N,N,N,N,N,N,N,N,N,41797,41798,N,N, +N,N,N,N,N,N,N,N,N,N,11874,N,41799,N,11876,N,N,N,11877,41801,N,N,N,N,11878,N,N, +N,N,11879,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11881,N,N,N,N,N,N,41803,N,N, +N,11882,11883,N,N,N,N,N,N,11884,N,N,41804,41805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,11885,N,N,N,N,N,N,N,41806,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41807,N,N,N,N,N,N, +N,N,41808,N,N,N,41809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,11887,N,11888,N,N,N,41812,N,N,N,N,41813,N,N,N,N,N,N,N,N,N,N,N,N,N,41814,N, +N,11889,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11890,N,N,N,N,N,N,N,N,N, +11891,N,N,N,N,N,N,41815,N,N,N,N,N,N,N,N,N,N,N,N,N,11892,N,41816,N,N,41818,N,N, +N,N,N,N,N,N,41819,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41823,N,N,N,N,41824, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41826,41827,11893,N,N,N,N,N, +N,N,N,N,N,N,20350,N,N,N,N,N,41829,N,N,11894,41830,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,41832,N,N,N,N,N,N,N,N,N,11895,N,N,N,N,N,N,N,41828,N,N, +N,N,N,N,N,N,N,N,N,N,41833,N,N,N,41834,N,N,N,N,11897,41835,N,N,N,N,N,N,N,11898, +N,N,N,N,N,N,N,N,N,N,11899,N,N,N,N,N,N,N,N,11900,N,41836,N,N,41837,N,N,N,N,N,N, +N,41838,11901,N,N,N,N,N,11896,N,N,N,41839,11902,N,N,N,N,41840,N,N,12065,N,N,N, +41841,41842,N,N,N,N,N,N,N,N,41843,N,N,41844,N,N,N,N,41845,N,N,N,41846,N,N, +12066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,41848,N,N,41849,N,41850,N,41851,N,N,N,N,N,N,N,N,N,N,N,12067,41852,41853,N,N, +N,N,N,N,N,41854,N,N,N,N,12068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,12069,N,N,N,N,N,N,N,N,N,12070,N,N,N,N,N,N,42017,N,N,N,N,42018,N,N,N,N, +N,42020,N,N,42021,N,N,N,N,N,12071,N,N,N,N,N,N,N,N,N,N,N,N,N,12072,N,42023, +42024,N,N,42025,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42027,N,N,N, +12073,42028,N,N,N,12074,N,42029,N,N,N,N,N,12075,N,N,42030,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,12077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +42035,N,N,N,N,N,N,N,N,N,42036,N,N,42037,N,12078,N,N,42038,42032,N,N,N,N,N,N,N, +N,N,N,42039,N,N,N,N,42041,N,N,N,N,N,N,42043,42046,12080,N,N,N,N,N,12081,N, +42047,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42044,N,N,N,N,N,N,N,42048, +N,N,N,N,N,N,42049,N,N,N,12082,N,42051,N,42052,42053,N,N,N,N,N,N,42054,N,12083, +N,N,N,N,N,N,N,N,N,29735,N,N,N,N,N,N,N,N,N,N,42055,N,42056,N,N,N,N,N,12085,N,N, +N,N,N,N,42057,N,12087,N,12088,12089,N,N,N,12084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,42059,N,N,N,42060,N,N,N,N,N,N,N,N,42061,N,N,N,12090,42062,N,N,42063,12091, +N,N,N,N,N,N,N,N,N,42064,12092,N,N,12093,42065,N,N,N,N,42066,12094,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,42067,N,N,N,12095,12096,N,N,42068,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,42069,N,N,N,N,N,N,N,N,42070,N,N,N,N,N,N,N,N,N,N,N,N,N,42071,42072, +12097,N,N,N,N,N,N,N,N,N,N,42074,N,N,N,N,N,N,N,N,N,N,N,12099,N,42075,N,N,N,N,N, +42077,N,N,N,N,N,12100,N,N,N,12101,12102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42079, +42080,N,N,N,N,N,42081,42082,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,42084,N,N,N,N,N,N,42085,12103,N,N,42086,42087,42088,N,12104,N,N,N,42089, +12105,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42093,N,12106, +42094,42095,N,N,N,N,N,N,N,N,N,42096,N,N,N,42092,N,N,N,N,N,N,N,N,N,N,N,12109,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,12110,12111,N,N,N,42099,N,N,12112,N,N,N,N,N,N,N, +42097,N,N,N,N,N,N,42102,N,N,N,N,N,12113,N,42103,N,N,N,N,N,N,12114,N,N,42104,N, +N,N,N,12115,12116,N,42106,N,N,42107,N,42108,N,12117,42109,N,N,N,N,12118,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42110,N,42273,N,N,N,N,N,N,42274,N,N,N,N,N,N, +N,N,N,N,42275,N,N,N,N,N,N,42276,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42278,N,N,42279, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,12120,N,N,12121,N,N,42280,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,12123,N,N,N,N,N,N,N,N,N,N,N,N,12124,42281,42282,N, +42283,N,42284,42285,N,N,N,42286,N,N,N,N,N,N,N,N,42287,12125,N,N,N,N,N,N,N,N,N, +N,12127,42288,N,N,N,N,N,N,42289,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42291,N,N,N, +N,N,N,N,N,N,42292,12130,N,N,N,12129,N,12131,N,N,N,N,N,12132,N,N,N,N,N,12133,N, +42293,N,N,N,N,N,N,12134,N,N,N,N,N,N,N,N,N,42294,42295,42296,42297,N,N,N,N, +42298,12135,42299,N,N,N,N,N,N,42300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42301,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42304,N,N,N,N,N,N,N,N,42306,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42309,N,12137,N,42310,N,N,N,N,N,N,N,N,N,N,N,N, +N,12138,N,N,N,N,N,N,N,42312,42313,N,N,N,N,N,42314,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +12139,N,N,N,N,N,N,12140,N,N,N,N,N,N,N,N,N,N,N,N,42315,N,N,N,N,12141,N,N,N,N,N, +N,N,N,N,42316,N,N,N,N,N,N,N,N,N,N,N,N,N,42317,N,N,N,N,N,N,12142,N,N,N,N,42318, +N,N,N,N,42319,N,N,N,N,12143,N,N,N,N,N,N,N,N,N,N,12144,42320,N,N,N,N,42321, +42322,N,N,42323,N,N,N,N,N,N,42324,N,N,N,N,N,N,N,N,N,32378,42328,42329,N,N,N,N, +N,12145,N,N,N,42330,N,N,N,N,N,N,N,N,N,N,N,12146,N,N,N,42331,N,N,N,N,N,42332,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +42333,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42334,N,12147,N,N,N,N,N,12148,N,N,N,N,N,N, +N,N,N,12149,N,N,42335,N,N,N,12150,N,N,N,N,N,12151,N,N,N,N,N,N,42336,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,42337,N,12152,42338,42339,N,42340,N,N,N,N,12153,N,N,N,N, +N,N,N,N,N,42341,N,42342,N,42343,N,N,N,N,42344,N,N,N,N,42345,N,N,N,N,12154,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42346,N,42347,N,N,N,42348,N,N,N,N,42349, +N,N,N,N,N,N,N,N,42351,N,42350,N,N,N,N,42352,42353,N,N,N,N,N,N,N,42354,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,42355,N,12156,N,N,N,N,N,N,N,N,N,N,N,12157,N,N,N,N,N,N,N, +42357,N,N,N,N,N,N,42356,N,N,N,N,N,N,N,N,N,N,N,N,20309,N,N,N,N,N,N,N,N,N,N, +42358,N,N,N,N,N,42359,N,N,N,20310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42360,N,N, +N,N,N,N,42361,N,N,N,N,N,N,N,N,N,N,N,N,42362,20311,N,42363,N,42364,N,N,42365,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,20312,N,N,43041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,43042,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43044,N,N,N,N,N,N,N,N,N,N,N, +N,N,43046,N,N,N,N,N,N,N,43047,N,20313,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +20314,N,N,N,N,43050,N,N,N,N,N,N,N,N,N,N,N,43051,43053,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,20315,N,N,N,N,N,N,N,N,N,N,N,20316,N,N,N,N,20317,N,N,N,N,N,43054,N,20318,N, +N,N,N,43055,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,32379,N,N,N,43057,N,N,20320,43058,N,N,N,43059,43060,43061,N, +N,N,N,N,N,43062,N,N,N,N,N,N,N,N,N,20324,N,43065,N,N,N,N,N,N,N,N,N,N,N,43068,N, +43069,N,N,N,N,20325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20326,43073,N,43074,20327,N, +N,43075,43076,N,N,20328,N,N,43078,N,N,N,N,N,N,N,43079,N,N,N,N,20329,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,43081,N,20330,N,N,N,N,20331,N,20332,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20333,43084,N,N,N,N,N,N,20336,N,N, +43085,N,N,N,N,N,N,N,N,N,N,N,N,43087,N,N,43088,N,N,N,43089,N,43090,20337,N,N,N, +43086,N,N,N,N,N,43091,N,N,N,N,N,N,N,43092,N,N,N,N,N,N,N,N,43093,N,N,N,20339, +20340,N,N,20342,N,N,N,N,N,N,N,N,20341,N,N,N,N,N,N,N,N,N,N,N,N,N,43095,N,N,N,N, +N,N,N,N,43096,N,N,20343,N,N,43098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20344,N,N,N, +N,N,N,43101,N,N,N,N,N,N,N,N,N,43103,N,43104,N,N,43105,N,43106,N,N,N,N,N,N, +20345,N,N,N,20346,N,N,20347,N,N,N,N,N,N,N,N,43107,N,43108,N,43109,N,N,N,20348, +43111,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20349,N,N,N,N,N,43112,N,N,N,N,N,43113, +43114,N,N,N,N,N,N,N,43115,N,29736,N,43117,N,N,N,N,43118,43120,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,43122,N,29737,43123,N,N,29738,N,N,N,N,N,N,43125,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,43126,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43127,N,N,N,N,N,N,N,N,N,N, +43128,N,N,N,N,N,N,N,N,N,N,N,N,43130,N,29739,N,N,N,N,N,29740,N,N,N,N,N,N,N,N,N, +N,N,N,43132,43133,43134,44065,N,N,N,N,N,N,N,N,32380,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44067,N,N,N,N, +44068,N,44069,N,N,N,N,N,N,N,N,N,N,N,N,44070,N,N,N,N,29741,44071,N,N,N,N,N,N, +44072,N,N,N,N,29743,N,N,N,N,N,N,44073,N,N,N,N,N,N,44074,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29744,N,N,N,44076,29745,N,29746,N,N,N, +N,29747,44077,N,N,N,N,N,44078,N,N,N,N,N,N,N,N,N,N,N,N,N,44079,29748,44081,N,N, +N,N,29749,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29750,N,29751,N,N,N,N,N,N,29752,N,N, +29753,N,N,N,N,29754,N,44082,N,N,N,N,N,N,N,N,N,N,N,N,29755,N,N,N,29756,N,N,N,N, +N,N,N,N,N,N,44083,29757,N,N,29758,N,N,N,N,N,N,N,N,N,N,44084,N,N,N,N,N,N,N,N,N, +N,29759,44085,N,N,N,N,N,N,N,N,N,N,29760,N,N,N,N,N,44086,N,N,N,N,N,N,N,N,N,N,N, +N,29761,N,N,N,N,N,44087,N,44088,N,N,29762,N,N,N,N,N,N,N,29763,N,N,N,N,N,29764, +N,29765,44089,N,N,N,N,N,N,N,N,N,N,N,44090,N,N,44092,N,29766,N,44093,N,N,N,N,N, +N,44094,44095,44096,N,N,N,N,N,N,N,N,N,29767,N,N,29768,44097,N,N,N,N,N,N,29769, +N,N,N,N,44098,44099,N,N,N,44100,N,N,N,N,N,N,N,N,44101,29770,N,N,N,N,N,N,29771, +N,N,44103,29772,N,N,N,N,N,N,N,N,N,44104,N,44105,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +29773,N,29774,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29775,N,N,N,N,44107,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,44108,N,N,N,N,N,N,N,N,N,N,44109,N,N,N,N,N,N,N,N,N,N,44110,N,N,N,N, +N,N,N,29777,29778,N,N,N,N,N,N,N,N,N,44111,N,N,N,N,N,N,N,44113,44114,N,N,N,N,N, +N,N,N,N,N,N,N,44115,N,N,N,N,N,N,N,N,N,44116,N,N,29779,N,N,N,N,N,N,N,N,29780, +29781,N,N,N,44117,N,44118,N,29782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44119,N,N,N, +44120,N,N,44121,N,N,29783,44122,N,44123,44124,N,N,N,N,N,44125,N,N,29784,N, +44126,N,N,N,N,N,N,N,N,N,N,N,N,29785,N,N,N,N,29786,N,N,N,N,N,N,29787,N,N,44127, +N,N,N,N,N,N,44129,N,N,N,N,44130,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,44131,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44132,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,29789,N,N,N,N,44134,44135,N,N,N,44136,44137,N,N,N,N,N, +N,N,N,N,N,N,N,44138,N,N,44139,N,N,N,N,44140,N,N,N,N,N,N,N,N,N,N,N,29792,N,N, +29791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44142,N,N,N,N,N,N,N, +44143,N,44144,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44145,44147,N,N,N,N,N, +N,N,N,N,N,N,N,29794,44148,N,N,N,N,N,44149,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,29795,N,N,N,N,29796,N,N,44150,N,N,N,N,N,44151,N,N,N,N,44152,44153,N,N,N, +29797,N,N,N,29798,N,N,N,N,N,N,44154,N,N,44155,N,N,N,N,N,N,N,N,44157,N,29799,N, +N,N,44158,N,N,N,N,N,N,N,44156,N,N,N,N,N,N,N,N,N,29800,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,44321,N,N,N,N,N,N,N,N,N,N,N,N,44322,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44323, +29802,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,29803,44325,44326,N,N,N,N,N,N,29804,N,N,44327,N,N,44328,N,N,N,N,N,N,N,29805, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44331,N,N,44332,N,N,N,29806, +N,44333,44334,N,N,N,N,44335,N,29807,44336,N,N,N,N,N,N,N,N,N,44337,N,N,N,N,N,N, +N,N,N,N,44339,N,N,N,N,N,N,N,N,N,N,N,29808,N,N,N,N,N,N,44342,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,29809,N,N,N,N,N,N,N,44343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44346,N,N, +N,N,44344,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,44347,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44349,44350,N,N,N,N,N,N, +44351,N,N,N,44352,N,N,N,N,29810,N,N,N,N,N,44353,44354,29811,N,N,N,N,44355,N,N, +29812,N,44348,44356,N,N,N,N,N,N,29813,N,N,N,29814,N,N,N,N,N,N,N,N,N,44357,N,N, +N,29815,N,N,44358,N,N,N,44359,N,N,N,N,N,44360,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29817,N,N,N,N,N,N,N,N,44361,44362,N,44363,N, +N,29818,N,N,N,N,N,N,N,N,N,N,N,N,29819,N,N,N,N,N,44364,N,N,N,N,N,29816,N,N,N, +44365,N,N,N,N,N,N,N,N,N,44366,N,N,N,N,N,N,N,N,N,44367,N,N,N,N,N,N,N,N,N,N,N, +44368,N,44369,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +29821,29822,N,N,N,N,29985,N,N,N,N,N,29986,44370,44371,N,29820,N,29987,N,N,N,N, +44372,N,44373,N,N,N,N,N,N,N,N,N,N,N,N,44375,44376,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,29988,N,N,N,29989,N,N,N,44377,44378,N,N,N,N,N,N,N,N,N,N,44380,N,N,N,N, +44381,N,44382,N,N,N,N,N,N,N,44384,N,N,N,29990,N,N,N,N,N,N,29991,N,N,N,N,N,N,N, +N,44385,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +44387,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29993,N,N,N,44388,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,44389,N,N,N,N,N,N,44390,N,N,44391,44392,N,N,N,N,44393,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,29994,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44394,N,N, +44395,N,N,44396,N,N,N,N,N,N,44397,N,N,44398,N,N,N,N,N,N,44399,N,N,N,N,N,N,N,N, +N,N,44400,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44402,N,N, +N,N,N,N,44403,N,N,44404,29996,N,N,N,44405,N,N,N,44406,29997,N,N,N,N,N,N,N,N,N, +N,N,29998,N,N,N,N,N,N,N,N,29999,N,N,44407,30001,N,30002,N,N,N,N,N,44408,30003, +N,N,N,N,30004,30005,N,30006,N,N,N,N,N,N,30000,N,N,N,N,N,N,N,N,N,N,44409,N,N, +30008,N,N,N,30009,N,44411,N,N,44410,N,N,N,N,N,44414,N,30011,30012,44577,N,N,N, +N,N,30013,N,44578,N,30014,N,N,N,N,44581,44582,44583,44584,N,N,N,N,N,30015,N,N, +N,30016,30017,N,N,44585,N,N,N,N,44586,N,N,N,N,N,N,N,N,N,N,N,N,30018,N,N,44587, +N,44588,N,N,N,N,N,N,44589,N,N,N,N,N,N,30020,N,N,N,N,N,N,N,N,N,N,N,N,44591,N,N, +N,44592,30021,N,N,44593,N,N,N,N,N,30022,N,N,N,44595,N,N,N,N,N,N,30023,N,30024, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30026,N,N,N,N,N,N,N,N,N,N,N,N,30027,N,N,N, +44597,N,N,N,N,N,N,N,N,N,N,N,N,N,30028,30007,44599,N,N,N,44600,N,N,N,N,N,N,N,N, +N,N,N,N,44601,30029,N,N,N,N,N,44603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,30031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30033,30034,N,N,N,44606, +44607,N,N,N,N,N,N,44608,N,N,N,N,N,N,N,N,44609,N,N,N,N,N,N,N,N,30032,N,N,N,N,N, +N,N,N,N,N,N,N,N,44613,N,44614,N,N,N,N,30035,N,N,N,N,N,30036,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,44616,30037,N,N,N,N,30038,N,N,30039,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,44620,N,44621,N,N,N,N,N,N,N,N,30040,N,N,N,N,30042,N,N,44622,N,N,N, +N,44623,N,N,N,N,N,N,N,N,N,44624,N,N,N,N,30043,N,44625,N,44626,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,44627,N,N,N,N,N,N,44628,N,30041,N,N,30044,30045,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,44619,N,N,N,N,N,N,N,44632,N,N,N,N,30047,N,44633,N,N,N,N, +N,N,N,N,N,N,N,N,30048,44634,N,N,N,30049,N,44636,N,N,N,N,N,N,N,44637,N,N,44638, +N,N,N,N,N,44639,44640,N,N,N,44641,N,N,44642,N,N,N,N,N,30046,N,N,44643,N,44644, +N,N,N,30050,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44646,N,N,44647,N,N,N,30051,N,N, +30052,N,N,N,N,44648,N,44649,N,N,N,N,N,44650,N,N,N,N,N,N,N,N,N,N,N,N,N,44651,N, +N,N,N,N,44652,N,44654,44655,44656,N,44657,N,N,N,N,N,N,30054,N,30055,N,N,N,N, +44658,44659,N,N,N,N,N,N,30056,N,44660,N,N,N,N,N,N,44661,N,N,N,N,N,N,N,44666,N, +44667,N,N,30057,N,N,N,44668,N,N,44669,30058,N,N,N,N,N,44670,N,N,44833,N,N,N,N, +N,N,N,N,N,N,44834,44835,N,N,30059,N,N,N,44836,30060,N,N,30061,30062,N,N,N,N,N, +44837,N,N,N,44662,30063,44838,N,N,N,44839,N,N,30064,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30067,N,N,N,N,N, +44843,N,N,N,N,N,N,30068,N,N,N,44845,N,N,30065,N,N,N,N,N,N,N,N,N,N,N,N,N,30069, +N,N,N,N,N,N,N,N,N,N,N,30070,30071,N,N,N,30072,44846,N,N,44847,N,N,N,N,N,44848, +N,N,N,N,N,N,N,44849,N,N,N,N,44850,30073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +44851,N,N,N,44853,N,44854,N,N,N,N,N,N,N,N,N,N,N,N,30075,44855,N,N,N,N,N,N, +30076,N,N,44856,N,N,N,N,N,N,44857,N,N,44858,N,44859,N,N,N,44860,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,30077,N,44861,N,N,N,N,44862,N,N,N,N,N,N,N,N,N,N,N,30242,44868,N, +N,N,N,N,30243,30244,N,N,N,44869,44870,N,N,N,44871,44873,30245,30246,N,N,N,N,N, +N,N,44874,30247,N,44875,N,N,N,30248,N,N,N,N,44876,N,N,44877,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,44865,N,44879,44880,44881,N,N,N,N,N,N,30250,N,N,30251,44882, +N,N,N,N,N,30252,44883,N,N,44884,N,N,N,N,44886,N,30253,N,44887,N,N,N,30254,N,N, +N,N,30255,N,N,N,N,N,N,N,N,44888,N,N,N,N,N,N,30256,N,N,N,N,N,N,N,30257,N,N,N,N, +N,N,44885,N,N,N,44890,N,N,N,N,44891,N,N,N,N,N,30259,N,44892,N,N,N,N,N,44894,N, +N,30260,N,N,N,N,N,N,N,N,30261,30262,44895,N,44896,N,N,N,30263,N,N,N,N,N,44898, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44899,N,N,N,N,N,N,N,N,44900,N,N,N,N,N,N,N,N, +N,44902,N,N,N,44901,N,N,N,N,N,N,N,44903,44904,N,N,N,N,N,N,30264,N,N,30265,N,N, +N,N,44907,N,N,N,N,44908,44909,44910,N,N,N,N,N,N,N,N,N,44911,44913,N,N,N,44914, +44915,44916,N,N,N,N,N,44918,N,N,N,30268,N,N,30269,N,N,N,N,N,N,N,N,N,N,N,N,N, +30270,N,N,44920,N,N,N,N,N,30271,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30272,N,N,N, +44921,N,N,N,N,N,N,N,N,N,N,N,30273,N,44922,N,N,N,N,N,N,N,30274,N,N,N,N,30275,N, +30276,N,N,N,N,44923,N,N,N,N,N,N,N,N,44924,N,30277,N,N,44925,N,N,N,N,N,N,44926, +30278,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60961,N,N,N,N,N,N,N,N,N, +N,N,N,N,30279,N,N,N,30280,60962,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60964,60965,N,N,N, +N,N,N,N,N,60966,60967,60968,N,N,N,N,N,30282,N,N,N,N,N,N,30283,30284,N,N,60969, +N,N,N,N,N,N,N,N,N,N,N,60970,60971,N,N,N,N,N,N,60972,N,N,60973,N,N,N,N,N,N,N,N, +N,N,N,N,N,30285,60974,N,N,30286,N,N,N,N,60975,N,N,N,60976,N,30287,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30288,N,60977,60978,N, +N,N,60979,N,N,N,N,60981,N,N,N,N,N,N,N,N,N,N,N,N,N,60982,N,N,N,N,N,N,N,N,N,N,N, +30289,N,60983,30290,N,N,N,N,N,N,N,N,N,N,61007,N,N,N,N,N,60984,N,N,N,N,N,N, +30292,N,30293,N,N,N,N,N,N,N,N,N,N,N,N,N,60985,30294,30295,N,N,60986,N,N,N,N,N, +N,N,N,N,N,60988,60989,N,60990,30296,N,N,N,30297,N,N,N,N,N,N,N,N,N,N,N,N,N, +30291,N,N,60991,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,60992,N,N,N,30299,N,N, +N,N,N,N,N,N,N,60993,N,N,N,30300,N,60995,N,N,N,60996,N,60997,N,N,N,30301,N,N,N, +N,N,N,N,N,60998,N,30302,60999,61000,30303,N,N,N,N,N,N,N,N,N,N,N,N,30298,61002, +N,N,N,30305,N,N,N,N,N,61003,N,N,N,30306,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,61004,N,61005,61006,N,N,N,N,N,N,30307,61008,N,30308,N,N,61029,N,N,N,N, +30309,N,N,61009,N,N,30310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +30311,N,N,61010,N,N,61011,N,61012,N,N,N,N,30312,N,N,N,N,N,N,N,N,N,N,61013,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,61014,61015,30314,N,N,N,N,30315,N,30316,61016,N,N, +61017,N,N,N,61018,N,N,30317,N,N,N,61019,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +30318,61025,30319,N,61026,N,N,N,N,N,61027,N,N,N,N,N,N,N,N,N,N,30320,N,N,61028, +N,30321,N,N,N,61030,N,N,N,N,N,61031,61032,61033,N,N,N,N,N,30322,N,N,N,30323, +30324,N,30325,N,61034,N,N,N,N,N,N,N,N,N,61035,N,N,N,N,N,N,N,N,N,N,N,N,61036,N, +N,N,N,N,30326,61021,N,N,N,N,N,N,61038,N,N,N,61039,N,N,N,N,61040,N,N,N,N,N,N,N, +N,N,N,61042,N,30328,N,61037,N,N,N,N,N,61043,N,N,N,N,N,N,N,30329,N,N,N,61044, +61045,N,61046,61047,N,N,61048,N,61049,N,61050,61051,N,N,61052,N,N,N,N,30330,N, +30331,N,N,N,N,61053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61217,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,61218,N,N,N,30332,N,N,N,N,N,30333,N,N,61219,N,N,N,N,N,N,N,N,N,N,61220,N, +30334,N,61221,N,N,N,30497,N,N,61222,N,N,N,30498,N,N,N,N,N,N,N,N,N,N,61223,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61225,N,N,N,N,N,N,N,N,N,N,N,N,N,61226,N,61227, +61228,N,61229,N,N,N,30499,N,N,N,N,N,N,N,61230,N,30500,N,N,N,N,N,N,N,N,N,N, +61231,N,N,N,N,30502,N,N,N,N,30503,N,N,N,30504,N,61224,61232,N,N,N,N,N,61233,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30505,61235,N,N,N,N,61236,N,30506,61237, +N,N,N,30507,N,61238,30508,30509,N,N,N,N,N,61239,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,61241,30510,N,N,N,N,N,N,N,N,N,30511,N,N,N,30512,30513,N,N,61242,N,N, +N,30514,N,61243,N,61240,N,N,N,N,N,N,61245,30515,N,N,N,N,61246,N,30516,N,N,N,N, +N,N,N,61247,N,N,N,N,N,61249,30517,N,N,N,N,N,30518,N,61244,N,N,N,N,N,N,N,N, +30519,61250,61251,30520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61252,N,N,N,61253,N,N,N, +N,N,N,N,N,N,N,61254,N,N,N,N,N,N,30522,N,N,N,N,30523,N,N,N,30521,N,N,61256, +61257,N,N,N,N,30524,30525,61258,N,N,61259,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,61260,N,N,N,N,30526,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61262,61263,N, +61264,N,N,N,N,N,N,61265,N,N,N,61266,N,N,30527,61267,N,N,30530,N,N,N,N,N,61269, +N,N,N,N,N,N,N,N,30528,30529,N,N,N,N,N,30531,61270,N,N,N,61271,N,N,61272,N, +61273,N,N,N,N,N,N,30532,61274,N,N,N,N,N,N,N,61275,N,N,61276,N,N,N,30533,61277, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,61278,N,61279,N,N,N,N,N,N,N,61282,N,N,N,N,30534,N, +N,N,N,N,N,30535,N,N,N,N,N,61283,N,N,N,N,N,30536,N,N,N,61280,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,61286,N,N,N,N,N,N,61287,N,61288,30537,N,N,N,30538,N,N,N,61289,N,N,N, +N,N,N,N,30539,N,N,N,N,N,N,N,61285,61290,61291,N,61292,61293,61294,N,N,N,61295, +N,N,30540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30542,N,30543,N,N,N,N,N,N,N,N,N,N,30541, +N,N,30544,61297,30545,61298,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30546, +30547,N,N,61300,N,N,N,N,N,61299,30548,30550,61301,N,N,N,N,N,N,N,N,30551,N, +61302,N,30552,N,N,N,N,N,N,N,30553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,61305,N,N,N,N,30555,N,30556,N,N,N,N,N,N,N,N,N,N,30557,N,N,N,61304,N,N,N,N, +61306,N,N,N,N,61307,N,61308,N,N,N,N,N,N,N,N,N,N,N,61309,61310,N,N,N,61473,N,N, +N,N,N,N,30559,N,N,N,N,N,N,30558,N,N,30560,N,N,N,N,N,N,61475,N,N,N,N,N,N,N, +61476,N,N,N,N,N,61477,N,N,61478,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,30561,30562,N,N,N,N,N,N,61479,N,N,N,N,N,N,N,N,N,N,N,N,N, +30563,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61482,N,N,N,N,N,N,N,N,61483,N, +N,N,61484,61485,N,N,N,N,N,N,N,N,61487,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61488,N, +30564,30565,61489,N,N,N,N,N,N,N,N,N,N,N,61490,N,N,N,N,N,N,N,N,N,N,61492,61493, +N,N,N,N,N,N,N,N,61494,N,N,N,N,N,N,61495,N,N,N,N,N,N,N,N,N,N,N,N,N,30567,61496, +N,N,N,N,N,N,N,N,N,N,N,N,30568,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61498,61499,N, +61500,61501,N,N,N,N,N,N,N,N,N,N,N,N,30569,N,30570,61502,N,N,N,N,N,N,N,N,N,N, +61504,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,61507,N,N,N,N,N,N,61508,30571,61509,N,N,N,N,N,N,N,N,N,N,61510,N,N,N,N,N, +61511,61512,N,N,N,N,N,N,N,N,N,N,N,N,N,30573,30574,N,N,N,61515,N,N,N,N,61516,N, +61517,N,N,N,N,N,61514,N,N,N,61518,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30576,N, +61519,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30577,N,N,N,N,61521,61522,N,61524, +61525,N,61526,N,N,N,N,N,61527,N,N,N,N,30578,N,N,N,N,61528,N,N,N,61529,N,N,N,N, +61530,N,N,N,N,N,N,N,N,N,61531,30579,N,N,61532,N,N,N,61533,N,61534,30580,30581, +N,30582,N,N,61535,30583,N,61536,N,N,30584,N,N,N,N,N,N,N,N,N,61537,N,61538,N, +61539,N,N,61540,N,N,61541,N,N,N,N,N,61542,N,N,N,30585,N,61543,N,N,N,30586,N,N, +N,N,N,N,30587,N,N,30588,N,N,N,N,N,N,N,61544,N,30589,N,N,N,61545,N,30590,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,61546,61548,61549,N,N,N,N,N,30753,N,N,30754,N,N,N,N,N, +N,N,N,61547,N,N,N,N,N,N,30755,30756,N,N,N,N,N,N,N,N,61550,N,30758,N,30759,N, +30760,30761,30762,N,30763,30764,30765,61551,N,N,N,N,N,N,N,61552,N,N,N,N,N,N, +61554,N,N,61555,30766,N,30767,30768,N,N,N,30769,N,61556,N,N,N,N,61557,61553,N, +N,N,30770,N,N,N,N,N,61558,N,N,N,N,30771,N,N,N,N,N,N,N,N,30772,N,30773,N,N,N, +61559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61560,N,N,N,61561,30774,30775,61562,30776, +N,N,N,N,N,N,30781,N,61564,N,N,N,N,61565,30777,61566,N,N,30778,N,N,30779,61729, +61730,N,30780,N,61731,30782,N,30783,30784,61732,61733,N,N,N,N,N,N,N,N,N,30785, +N,N,N,61734,61736,61735,N,N,N,30786,N,N,N,N,N,N,N,N,30787,30788,N,N,N,N,N,N,N, +N,N,N,N,N,61737,N,61738,N,30789,N,N,N,61739,N,N,N,N,N,N,N,N,N,N,N,N,61741,N,N, +N,61740,N,N,N,N,N,N,N,N,N,N,61743,N,N,N,N,30790,30791,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,30792,N,N,N,N,N,N,N,N,61745,N,N,N,61746,N,N,N,N,N,61747,N,N, +N,N,30793,N,N,N,N,N,N,N,N,N,N,N,N,N,61750,61751,N,61752,N,N,N,N,N,N,N,61753,N, +N,N,N,N,61754,N,61755,N,61756,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,61757,N,N,30794,N,61759,61758,N,N,N,N,N,N,30795,61760,N,N,61761,61762,N,N, +61763,N,N,N,N,N,N,N,N,N,N,61765,N,N,N,N,N,30796,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +61767,N,N,N,N,N,N,N,N,N,N,N,N,N,61769,N,N,N,N,N,N,61770,N,N,N,N,N,N,N,61771, +61772,N,N,N,N,N,61773,N,N,N,N,N,N,N,30798,61774,N,N,N,61775,N,N,N,N,N,N,N,N,N, +61776,N,61777,61778,N,N,N,30799,N,N,61779,N,N,N,N,61780,N,61781,N,N,61782,N,N, +N,N,N,N,N,61783,30800,N,30801,61784,N,N,N,61786,30802,N,N,N,N,N,N,61787,N,N,N, +61790,N,30803,30804,N,61785,30805,N,61791,61792,N,30806,N,N,N,N,N,N,61794, +32381,N,61795,N,N,N,N,30807,N,N,N,N,N,61797,N,30808,N,N,N,N,N,N,61796,N,N,N,N, +61800,N,30809,N,N,N,N,N,61802,N,30810,N,N,N,N,N,N,N,N,N,61803,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,30811,30812,N,N,N,N,N,N,N,30813,61805,30814,N,30815,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,30816,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61806,N,N,N,N,N, +30817,61807,30818,30819,N,61809,61808,N,N,N,N,30820,61810,61811,N,30821,N,N,N, +N,61812,N,N,N,N,N,N,30822,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30823,N,N,N,61814,N,N, +30824,N,30825,N,N,N,N,N,30826,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30827,N,61816, +N,N,N,61817,N,N,N,N,30828,N,N,N,N,N,N,N,N,N,N,30829,30830,N,N,N,N,N,N,N,N,N,N, +N,N,61819,N,30831,61820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61821,N,N,N,N,N,N, +30832,61822,30833,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30834,N,N,N,N,N,N,30835,30836, +N,N,N,N,N,N,N,N,N,61989,N,N,N,30837,N,N,30838,61990,N,30839,N,N,N,N,N,N,N, +61991,N,N,N,N,N,N,N,61993,N,N,N,N,N,N,N,30840,N,61994,61995,N,N,30841,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30842,N,N,N,N,N,61998,N,N,N,N,61999,N,N,62000,N, +62001,N,N,N,N,62002,30843,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62003,62004,30844,N,N,N, +62005,N,62006,N,N,N,62007,N,62008,N,N,N,62010,N,N,N,62011,N,N,N,N,N,N,62012, +62014,62015,N,N,62016,N,N,N,62017,N,N,N,N,N,N,N,N,N,N,N,62018,N,N,N,N,N,N,N, +62019,N,N,N,N,N,N,N,N,N,N,62020,30845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,31009,N,N,N,62021,N,N,N,N,N,N,31010,31011,N,31012,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,62022,N,N,N,31013,N,62023,N,N,N,31014,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,62025,N,N,N,N,N,N,N,N,N,62026,N,N,N,N,N,N,N,N,62028, +62029,62030,N,N,N,N,62027,N,N,N,N,N,N,N,N,31018,N,N,31016,N,N,N,N,N,N,N,N,N,N, +62031,N,N,N,N,N,N,N,N,N,N,N,N,62032,N,N,N,62033,N,62034,N,N,N,N,N,N,62035,N,N, +N,N,N,N,N,N,N,N,62036,62037,N,N,31019,N,62038,N,N,N,N,N,N,N,N,N,N,N,31020,N,N, +N,N,31022,N,62039,62040,62041,N,N,62042,31021,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +62044,N,N,N,N,N,N,N,N,N,N,62045,31023,N,N,N,N,N,N,N,N,62047,N,N,N,N,N,N,N,N, +31024,N,62046,31025,N,N,31026,N,N,N,N,N,N,62048,N,N,N,N,N,N,N,N,N,31029,31030, +N,N,N,62049,N,N,N,N,N,N,N,N,N,N,N,N,N,62050,N,N,62051,31034,N,N,N,N,N,N,N,N,N, +N,62053,N,N,N,N,N,N,N,N,N,N,62054,N,N,N,N,N,N,31038,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,62055,62056,62057,N,31042,N,N,62058,N,N,N,N,N,62059, +N,N,N,N,N,N,N,62060,N,N,N,N,N,N,N,31043,N,N,62061,N,N,N,31044,N,N,62062,N,N,N, +N,N,N,62063,N,N,N,N,62064,31045,N,31046,N,62065,62066,N,N,N,N,N,N,31048,N, +62067,N,N,N,N,N,N,N,31049,N,N,N,N,N,N,N,N,N,N,N,N,31050,N,31051,31052,N,N,N,N, +N,N,62072,N,N,N,N,N,N,62073,N,N,N,62074,N,N,N,N,N,62075,N,N,62076,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,62078,N,N,N,N,N,N,N,N,N,N,62241,31054,N,N,N,N,N,N,N,N,N,N,N,N, +N,62242,N,N,N,N,62243,N,N,N,N,N,N,N,N,N,62244,N,N,62245,N,N,62246,31055,N, +62247,62248,N,N,N,N,N,N,62249,N,N,62250,N,N,31056,N,N,N,N,N,N,N,62251,N,N, +62252,N,N,N,N,N,N,N,N,N,62253,N,N,31058,N,N,N,N,62254,N,N,N,N,N,62255,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,31059,N,N,62256,N,N,N,N,N,N,N,N,62257,N,N,N,N,N,N,31061, +N,N,N,N,N,62260,N,31062,62261,N,62262,N,N,N,N,N,N,N,N,N,N,N,N,N,62264,N,31063, +N,N,62265,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62266,62267,N,N,31064,N,N, +N,N,N,N,N,N,62268,N,N,N,N,N,N,N,N,31065,62271,N,N,N,N,N,N,N,N,N,N,31066,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62274,N,N,62275,N,N,31067,62276,62277,N, +62278,N,N,N,N,N,N,N,N,N,31068,N,62273,N,N,N,62282,N,N,N,N,N,31069,N,N,N,N,N,N, +31070,N,N,N,N,N,N,62284,N,N,N,N,N,N,N,N,N,N,31071,N,N,N,62286,N,62287,N,N, +62288,N,N,N,31072,N,31073,N,N,31074,62289,N,N,N,N,N,62285,N,N,N,N,N,62281,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,62292,62293,N,N,N,N,N,N,N,N,N,62294,N,N,31075,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,62296,N,N,N,N,N,62297,N,N,N,N,N,N,62298,N,N,N,N,N, +N,N,N,62299,N,N,N,N,62300,N,N,N,N,N,N,N,N,N,62303,N,62304,31077,N,31078,62305, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62306,N,N,N,N,N,62307,31079,N,62308,N,N,N,N,N,N, +N,62309,N,N,62310,62311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31081,N,31082,N,N,N,N,N, +62312,N,N,N,N,N,N,N,N,N,N,31080,N,31083,N,N,31084,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +62313,N,N,N,N,62314,N,N,N,N,N,N,62315,N,N,N,N,N,62316,N,31087,N,N,N,N,62317,N, +N,62318,N,N,N,N,N,N,N,62319,N,N,N,31088,62320,62321,62322,N,N,N,N,N,N,N,N, +31089,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31090,N,N,N,N,31091,N,N,N,N,N, +N,N,N,N,N,N,31092,N,N,N,N,N,62326,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62328,62329,N, +N,N,N,31093,N,N,62330,N,N,N,N,62332,N,N,N,62334,N,N,N,N,62497,N,N,N,N,N,N,N, +31094,N,62499,N,31095,N,N,N,31096,N,N,N,N,N,N,N,N,62501,N,N,N,N,62502,N,N,N,N, +N,N,N,N,N,62504,62505,N,N,N,31097,31098,62506,N,N,N,N,N,N,N,N,62508,31099,N,N, +N,N,N,N,N,N,N,31100,62509,N,N,N,N,31101,N,N,N,N,N,N,N,N,N,N,N,N,N,31102,N,N,N, +N,N,N,N,N,N,N,N,62512,62513,N,62514,31265,N,N,N,N,N,62515,31266,N,N,N,N,N,N,N, +N,N,N,31267,N,N,N,N,N,62519,62520,N,31268,N,N,N,N,N,N,N,N,N,N,N,N,N,62521,N,N, +N,N,N,62522,N,N,N,N,N,N,N,N,N,31269,N,N,N,N,62524,N,N,N,31270,N,N,62526,N, +62527,N,N,31271,62528,N,N,N,N,N,N,N,N,N,N,62529,N,N,N,N,N,62531,N,N,31272,N,N, +N,N,N,31273,62532,N,N,62533,N,N,N,N,N,N,N,N,N,N,N,62534,62535,N,N,N,N,N,N,N,N, +62536,N,31274,N,N,N,N,N,N,N,N,N,31275,N,N,N,N,N,N,N,N,N,31276,62537,N,62538,N, +N,N,N,N,N,N,N,N,31277,N,N,62539,N,N,N,N,N,N,N,N,N,N,62540,N,N,N,N,N,N,N,62541, +31280,N,N,N,N,N,N,N,62545,31281,N,N,N,31282,N,62546,N,N,N,N,N,62547,N,N,62548, +N,N,N,N,N,N,62549,31279,N,N,N,62550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,62551,N,31284,N,N,N,N,N,N,N,N,N,N,31285,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +31286,N,N,N,N,N,N,N,N,N,32382,N,N,N,N,N,N,N,62552,N,62553,N,N,N,N,N,N,N,N, +62554,N,N,N,N,N,N,N,62555,62556,N,N,31287,N,N,31288,N,N,N,62558,N,N,N,N,N,N, +62559,N,62560,62563,62562,N,62564,N,N,N,N,62565,62566,N,N,31289,N,N,N,N,N,N,N, +62567,N,N,62570,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62572,N,62573,62574,N,N,N,N,N,N,N, +N,62575,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62576,62577,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,62579,31291,N,N,N,N,62582,31292,N,N,N,N,62583,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,62584,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31293,N,N,N,62586,N,N,N,N,N,N,N, +N,N,N,31294,62587,N,N,N,N,N,N,N,N,N,N,N,31295,N,N,N,31296,N,N,N,62588,N,62589, +N,N,N,N,N,N,31297,N,31298,62590,N,N,62753,N,N,N,N,N,N,N,31299,62754,N,N,N,N,N, +62756,N,62755,N,N,N,62757,N,N,62758,N,N,31301,N,62759,N,N,N,N,N,N,N,N,N,N,N,N, +N,62760,N,31302,N,N,N,N,N,62761,N,N,N,62762,N,N,N,N,31303,N,31304,N,N,N,N, +31305,N,N,N,N,N,N,62763,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,62764,N,N,N,N,N,N,N,N,N,N,62765,N,N,N,62766,N,N,N,N,N,62767,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62768,N,N,62769,N,N,N,N, +N,N,N,62770,N,N,62771,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62772,N,N,N,N,N,N,N,N,N, +N,N,N,62774,N,N,N,N,31306,N,N,N,N,N,N,N,N,N,N,62775,N,31307,62776,N,N,N,N,N,N, +N,31308,N,N,N,N,N,62777,N,N,N,N,N,N,N,N,N,N,N,N,31309,N,62780,N,N,N,N,N,62781, +62779,N,N,N,N,N,N,N,N,62784,N,31310,N,N,N,N,N,62785,N,N,N,N,N,62787,N,N,62788, +N,N,N,N,62789,N,N,N,N,N,N,N,N,62783,N,N,N,N,N,N,N,62791,N,N,N,N,N,N,N,N,N,N,N, +N,31311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31312,N,N,N,N,N,N,31313, +31314,62793,N,N,N,31315,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62795,N,N,62797, +62798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62800,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,62801,N,N,N,N,N,N,N,N,31316,N,N,N,N,N,62802,N,62803,N,N,N, +N,N,N,31317,N,N,N,N,31318,N,N,N,N,N,N,62804,31319,N,N,N,62805,N,N,N,N,N,N,N,N, +62807,N,N,N,N,N,N,N,62809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62811,N,62812,62814, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62816,N,N,N,N,N,N,N,62817,62818,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,62820,N,62821,N,N,N,N,N,N,N,62822,N,N,N,N,N,N,N,N, +62825,62823,N,N,62824,N,62827,N,N,N,62829,N,N,N,N,N,N,N,62831,N,N,N,N,62833,N, +N,N,31323,N,N,62834,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31324,N,N,N,N,62838,N,N,N, +62840,N,62841,N,N,N,62842,N,N,N,N,N,N,62843,N,N,N,31326,N,N,N,N,62844,N,N,N,N, +N,N,N,N,N,N,N,N,N,31327,N,31328,31329,N,N,62845,62846,31330,N,N,N,N,31331,N,N, +N,63009,N,63010,N,N,31332,N,N,63011,N,63012,N,31333,31334,N,N,N,N,N,N,31335,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,31336,N,N,N,N,N,N,N,N,N,N,N,N,63013,N,N,N,N,N,63014, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,63015,N,N,N,N,N,31337,31338,31339,31340,N,N,N,N,N, +63016,63017,N,N,N,63018,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63020,N,63021,N,N,N,N, +31342,N,N,N,N,N,N,N,N,N,N,31343,N,N,63022,N,N,N,N,N,N,N,N,N,31344,N,63023,N,N, +N,N,N,N,31345,63024,N,N,31346,N,N,N,N,N,N,N,N,N,31347,N,N,63019,31348,N,63025, +N,N,N,N,N,N,N,N,N,N,31341,44618,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,31349,N,63027,N,N,N,N,N,N,31350,N,N,N,N,N,N,63030,N,N,N,N,31351,N,63031, +63032,N,N,31352,N,N,63033,N,63034,N,N,N,N,N,N,N,N,N,31353,N,31354,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31355,31356,N,N,N,N,N,N,31357,N,63035,N,N,N,N,N, +31358,63036,31521,N,N,63037,N,N,N,N,N,N,N,N,63038,N,N,N,31522,N,N,N,63039,N,N, +N,N,31523,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63040,31524,N,N,N,N,31525,N,N,N,31526,N, +N,N,N,63041,N,63042,N,N,N,63043,N,63045,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,63046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31528,N,63047,N, +N,N,N,63048,N,63049,63050,N,N,N,N,N,N,63051,63052,N,63053,N,N,31529,N,N,N,N,N, +63055,N,N,N,N,N,N,N,N,N,N,31530,N,N,31531,N,N,63056,N,63057,N,N,N,63058,N,N,N, +N,63059,N,N,N,31532,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63062,N,N,N,N,N,N,31533, +N,N,N,N,N,N,N,63063,N,N,N,N,N,N,N,N,31534,N,N,N,N,31535,N,N,N,N,N,31536,N,N,N, +63064,N,31537,N,31538,N,N,N,N,N,N,N,N,N,N,N,63066,63067,N,N,N,63068,N,N,N,N,N, +N,N,N,63061,N,N,N,N,N,N,N,N,N,N,63070,N,N,63071,N,N,N,N,63072,63073,63074,N,N, +N,N,N,N,N,N,63075,N,N,63076,63077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63078,N,N,31541, +N,N,N,N,31542,63079,63080,N,N,N,N,N,63081,N,N,N,31543,N,N,31540,N,63082,N,N,N, +N,N,N,N,N,N,63087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63083,N,63088,N,63089,N,N,N, +N,N,31544,N,N,N,N,63090,N,N,63091,63092,N,31545,N,N,N,N,N,N,N,N,N,N,63084,N,N, +N,N,N,N,N,N,N,N,31548,63094,N,63095,N,63096,N,63097,N,N,N,N,63098,N,N,N,N,N, +31549,N,N,31550,N,N,N,63099,N,N,N,N,N,N,N,N,N,63100,N,63101,N,N,31551,N,N,N,N, +N,N,N,N,N,N,31547,N,N,31552,N,N,N,N,N,N,63267,N,N,N,N,63268,N,N,N,N,N,N,N,N,N, +N,63269,N,N,63270,31553,N,N,31554,N,N,N,N,N,N,N,N,N,63271,63272,N,N,N,N,N, +63273,N,63274,N,N,N,N,63275,N,N,N,N,N,N,31555,N,N,N,N,N,N,N,N,63276,N,N,N,N,N, +N,N,N,31557,63277,N,N,N,31558,31559,N,N,N,N,N,N,N,N,N,N,31560,63278,31556,N,N, +N,N,N,31562,N,N,N,N,N,63279,N,N,63280,N,N,63281,N,N,63282,N,31563,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,31564,63284,N,N,63285,N,N,N,63287,12136,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,63289,N,N,63290,31565,N,N,N,31566,N,N,N,N,N,N,31568,N,N,N,N,N,N,N, +N,N,31570,N,N,63291,N,N,N,N,N,31571,N,63292,N,N,63293,N,N,N,N,N,N,N,N,N,N,N,N, +63294,N,63295,N,N,N,63296,N,N,N,63297,N,N,N,N,N,N,31572,N,N,N,63298,63299,N,N, +N,N,N,N,N,N,N,N,63300,N,N,N,N,N,N,N,N,63302,N,63303,N,N,N,N,31573,N,N,N,N,N,N, +N,N,63304,N,63305,N,N,N,N,N,N,N,N,N,N,N,N,N,63306,N,N,N,63307,N,63308,N,N,N,N, +N,N,N,N,N,N,N,63309,N,N,63310,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31574,N, +31575,31576,63312,N,63313,N,N,N,31577,N,N,63314,N,63315,N,N,63316,N,N,N,N,N, +63317,N,N,N,N,N,63318,N,63319,N,63320,N,N,N,N,N,N,N,N,N,N,N,N,N,63321,N,N,N,N, +N,N,N,N,63322,N,N,N,63323,N,63324,N,N,63325,N,N,N,N,N,N,N,N,N,N,N,N,N,63326,N, +N,N,N,N,N,63327,N,N,N,N,N,N,N,N,N,N,N,63328,63329,N,N,N,N,N,N,N,N,N,N,N,31578, +63330,N,N,N,N,N,N,N,N,N,63331,N,N,N,N,N,N,N,N,N,N,31579,31580,63335,N,63336,N, +N,N,N,N,N,N,63337,N,N,N,N,N,N,N,N,N,N,N,N,63338,N,N,N,N,N,N,63334,N,N,N,N, +31581,31582,N,N,N,N,N,N,N,31583,N,N,N,N,N,N,N,N,63341,N,N,63343,N,N,N,N,N,N,N, +N,N,N,N,N,63344,N,N,N,N,N,N,N,31585,N,N,N,N,N,N,N,N,63346,N,N,N,63348,N,63349, +63350,N,N,N,63351,63352,31586,63353,N,N,N,N,N,N,N,63345,63354,N,63355,N,N, +31587,N,N,N,31588,63356,N,N,N,N,31589,N,N,63357,31590,N,N,N,N,N,N,N,N,N,N, +31591,N,N,N,N,N,N,N,N,63358,N,N,N,N,N,63521,N,N,N,63522,N,N,N,N,N,N,N,N,N, +63523,N,N,N,N,N,N,N,N,N,N,N,N,N,63525,N,N,N,N,N,N,N,N,N,N,N,N,N,63526,N,N,N,N, +N,N,63527,N,N,N,N,63528,N,N,N,N,63531,N,N,N,N,N,63533,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31592,N,N,N,N,N,N,N, +63534,N,N,N,N,N,N,N,N,N,31593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63535,63536, +63537,N,63538,N,N,N,N,N,N,N,N,N,31594,N,N,N,31595,N,N,63541,63539,63542,N,N,N, +N,N,N,N,63543,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63544,63545,N,N,N,31597, +63547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31600,31601,31602,N,31598,N, +N,N,N,N,N,N,N,N,N,31603,N,N,N,N,N,N,N,N,31604,N,31605,N,N,N,N,63549,N,31606,N, +N,N,N,N,N,31607,N,63551,N,N,63552,N,N,N,63553,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,63556,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,63557,N,N,N,N,N,N,N,N,63558,N,N,N,N,N,N,63559,N,N,N,31608,N,N,N,N,N,N,N,N,N, +N,63560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63561,N,N,N,N,N,N,63562,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31610,N,63563,N,63564,N,N,N,N,N,N,N, +N,N,N,N,N,31611,N,N,N,N,N,63565,N,N,N,N,N,63567,N,63568,N,N,31612,N,N,N,N,N,N, +63569,N,63570,63572,31613,N,63573,31614,N,N,N,N,N,N,N,N,N,N,N,63575,31777,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63576,N,31778,N,N,N,N,N,N,63577,N,N,N,N,N,N, +63578,N,31779,N,N,N,N,N,63579,31780,N,N,N,N,N,N,N,N,N,63580,N,N,N,N,31781,N,N, +N,31782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31783,N,N,N,31784,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63582,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,31785,N,N,N,N,N,N,63581,N,N,N,N,N,N,N,N,63583,N,N,N,N,N,N,63584,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,31786,N,N,N,N,N,N,63585,N,N,N,N,N,N,N,31787,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,31788,N,31789,N,N,N,N,N,63586,63589,N,N,N,N,63588, +N,N,63590,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63591,N,N,63592,N,N,N,N,N,N,N,N,N,N,N,N, +N,63593,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63594,N,N,31793,N,N,N,N,N,N, +N,N,N,N,63596,N,N,31794,N,N,N,N,31795,N,N,N,N,63597,N,N,N,N,N,N,N,N,N,N,31796, +N,N,N,N,N,N,N,N,N,N,N,N,63598,N,N,N,N,N,N,N,N,63599,N,63600,N,N,N,N,N,N,N,N,N, +63601,N,N,N,N,N,N,N,N,63602,63603,N,N,N,N,N,N,63604,31797,63605,63606,N,N,N, +63608,N,N,N,N,N,N,N,63611,N,63612,N,31798,N,N,N,N,N,63613,N,N,N,N,63614,N,N, +63777,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31799,63778,N,N,N,63779,N,N,N,N,N,63780, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63783,63782,N,N,N, +N,N,63784,N,63786,N,N,N,N,N,N,N,N,63787,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63789,63788,N,N, +63790,N,N,N,N,N,N,N,31801,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63792,63793,N,N,31802,N, +N,N,31803,N,N,N,N,N,31804,63795,N,N,N,N,63796,N,N,N,31806,N,N,N,N,N,N,N,N, +31807,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,63797,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63798,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,63799,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63800,N,N,N,N,N,N, +N,N,31808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63802,N,63803,N,N,N,N,N, +31809,N,N,31810,N,N,N,N,N,31811,N,63804,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +63805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63808,63809,N,N,N,N,N,63806,N,N,N,N,N,N, +N,63811,N,63812,N,N,N,N,N,N,N,N,N,31812,63813,63814,31813,N,N,N,63815,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,63818,N,N,63819,N,N,N,31814,N,N,N,N,N,N,N,N,N,N,N,N,N, +63820,N,N,N,N,N,N,N,N,63821,N,N,N,N,N,N,N,N,N,N,N,N,N,63822,N,N,N,N,N,N,N,N,N, +63823,63824,N,63825,31815,N,N,N,N,N,N,N,N,N,N,31816,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63826,N,N,N,N,N,63827,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,63828,N,N,N,N,63829,N,63830,63831,N,N,N,N,63832,N,N,N,N,31818,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,63834,N,N,63835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63837,31820,63839,N,N,N,N,N,N,N,63840,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,63841,N,N,N,N,N,N,31821,N,N,N,N,N,N,N,N,N,N,N,N,63842,N, +31822,N,N,N,N,N,N,N,N,31823,N,N,N,N,N,N,N,N,N,63843,N,N,N,N,N,N,N,N,N,63844,N, +N,N,N,N,N,N,N,N,31824,N,N,N,63845,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,63847,N,31826,N,N,N,N,N,N,N,N,N,N,N,N,N,63848, +31827,63850,N,N,N,N,N,N,N,N,N,N,63852,N,N,N,N,63853,N,N,N,63855,N,N,63856,N,N, +N,N,N,63857,N,63858,N,N,N,N,N,N,N,N,N,N,63859,N,N,N,31828,N,N,N,31829,N,N,N,N, +N,31830,N,N,63860,N,N,N,63861,N,N,N,N,N,63862,63863,N,N,N,N,N,31831,N,N,N, +63864,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31832,N, +N,N,N,N,N,N,N,N,63865,N,N,N,N,N,N,N,N,N,N,N,63867,63868,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,63869,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64034,N,N,31834,N,N,N,64035,N,N,N,64036,N,N,N, +N,31835,N,31836,N,31837,N,31838,N,N,N,N,N,64038,31839,N,N,N,N,N,N,N,N,N,N,N,N, +N,64040,N,N,31840,N,N,64041,N,N,N,N,N,N,N,31841,N,N,N,N,64042,31842,31843,N, +31844,64043,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31845,N,N,N,N,64045,31846,31847,64046, +N,N,N,N,N,N,N,N,N,N,N,64051,N,N,N,31848,N,N,64049,N,31849,N,64048,N,N,N,N,N,N, +N,64052,64053,64050,N,N,N,64054,N,64055,N,N,N,N,N,N,N,N,N,N,N,N,N,31851,31852, +31853,N,64056,N,N,N,64057,N,64058,N,N,N,31854,31855,N,N,N,31856,N,N,N,N,N,N,N, +31857,N,31858,N,N,31859,N,N,64059,N,64060,64061,N,N,31860,N,N,N,N,N,N,N,N, +64062,64063,31861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64064,N,64065,N,31862,N,N,N,N,N, +64066,N,N,64067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64068,N,N,N,N,64069,N,N,N,N,N,N, +N,N,N,31863,N,64070,N,N,N,N,N,N,N,N,64071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31864, +N,N,N,N,N,N,N,N,N,64072,N,N,N,31865,N,64073,N,N,31866,N,64074,N,N,64075,N,N,N, +N,N,31867,N,N,N,N,N,N,64076,64077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31868,N, +N,64078,N,N,N,N,N,N,N,N,N,31870,32033,N,N,N,N,N,N,64081,32034,64082,N,N,32035, +N,N,N,N,N,N,N,N,N,31869,64083,N,N,N,N,N,32036,N,N,64084,N,N,N,N,N,32037,N,N,N, +N,N,64085,64086,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64088,N, +N,N,N,32038,32039,32040,N,32041,N,N,N,32042,N,64089,32043,N,N,N,64090,N,N, +64091,N,N,N,64092,32044,N,64093,N,N,N,N,64094,N,N,64095,N,N,N,N,N,N,64096, +64097,N,N,N,64098,N,64099,64100,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32045,N,N,N, +64103,64104,N,64105,N,N,N,N,N,N,N,N,32046,64106,N,N,N,64107,N,N,N,N,N,N,N,N,N, +64108,N,64109,N,N,N,N,N,64110,N,N,N,N,N,N,N,64111,N,N,N,64112,N,N,N,N,N,N, +64115,N,N,N,N,N,N,N,N,N,N,N,N,64116,64117,N,32047,N,N,N,64118,N,N,N,N,32048, +32049,N,64119,N,64120,N,N,32050,N,N,N,64121,N,64122,N,N,N,N,N,N,32051,N,N,N,N, +64123,N,64124,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64290,N,64291,N,64292,N,N,N,32052, +64293,N,32053,N,N,N,N,N,N,N,N,64294,N,N,N,64125,N,N,N,64295,N,N,N,N,N,N,N, +64296,64297,32054,N,32055,N,N,N,32056,N,64298,N,64299,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64302,32057,32058,32059,N,N,N,N,N,N,64303,N, +N,N,N,N,64304,N,N,64305,N,N,N,N,N,N,N,N,N,32060,32061,N,N,N,N,32062,64306,N,N, +N,N,32063,64307,N,64308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64312,N,N, +64313,N,N,N,64314,N,N,N,N,N,N,N,N,N,N,N,32064,N,N,64315,N,N,64309,N,32065,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32066,N,N,N,N,N,N,64320,N,N,N,N,32067, +64321,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64322,N,32068,32069,N,N,64323,N, +N,N,N,64324,N,N,N,N,N,N,N,N,N,64319,N,N,N,64316,N,N,N,N,N,64329,N,32071,32070, +N,N,N,N,64325,N,N,N,N,N,64326,N,N,N,N,N,N,64327,64328,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,64330,32072,64331,N,N,N,N,N,N,64332,N,N,N,N,N,N,N, +N,N,64333,N,N,N,N,32073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32074, +N,N,N,N,N,N,N,32075,N,64336,N,64337,N,32076,32077,64338,64339,N,N,N,N,N,N,N,N, +N,N,N,N,64340,N,N,N,N,N,64341,64342,32078,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +32079,N,N,N,N,N,N,32080,N,N,32081,N,64344,32082,N,N,N,N,N,N,N,64345,N,32083,N, +N,N,N,N,N,32084,N,N,N,N,N,N,N,N,N,N,64347,N,N,32085,N,N,N,N,32086,N,N,32087,N, +N,N,N,N,N,32089,N,N,N,32090,64037,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64350,N,N,N,N,N, +N,64351,64352,N,N,N,N,N,N,N,64354,N,N,N,N,64355,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,32091,N,N,N,N,N,N,N,N,64356,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,64358,N,32092,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,64360,N,N,32094,N,N,N,N,N,N,32095,32096,N,N,N,64363,N,N,N,N,N,64364,N,N, +N,64365,N,N,N,N,N,N,64366,N,N,64367,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +32097,N,N,N,N,N,64370,N,64371,N,N,64372,32098,N,N,N,N,N,N,N,N,N,N,32100,N,N,N, +N,N,32101,64374,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64375,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,32102,N,N,64377,N,N,N,N,32103,N,N,N,N,N,64378,N,N,N,N,N,64379,N,N,N,N,N, +32104,32105,32106,N,N,N,N,N,64380,N,64381,N,N,32107,64382,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,64545,N,N,N,32108,N,N,N,N,32109,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,32110,64548,N,N,N,64549,N,N,N,64550,N,N,N,64551,N, +N,N,N,N,N,N,N,N,N,N,32111,N,N,64552,64553,N,N,N,N,N,N,N,32112,N,N,N,64554,N,N, +32113,N,N,N,N,N,N,N,32114,N,N,64555,N,N,N,N,64556,N,N,64557,N,N,N,64558,64559, +N,32116,N,N,32115,N,N,64560,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64561,N,N,32117, +64562,N,N,N,N,N,32119,N,N,64563,64564,N,N,N,N,N,64565,N,64566,N,N,N,N,N,N,N, +32120,N,N,N,N,64569,N,64572,N,N,N,N,N,32121,N,N,N,N,32122,N,64570,64571,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64573,N,N,N,N,N,N,N,N,N,N,32124,32125,N,N, +32126,32289,N,32290,32291,N,N,N,N,N,N,N,N,N,N,32293,64574,N,N,N,N,N,32294,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64575,N,64576,N,N,64577,N,N,N,N,N,N, +64579,64580,N,32295,64581,64582,N,N,64583,N,N,64584,N,N,N,N,64585,32296,N,N, +64586,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64587,64589,N,64590,N,64591,N, +32297,N,N,64592,N,N,N,N,N,64593,64594,N,64595,64596,N,N,N,N,N,N,N,N,N,N,N,N,N, +64599,64600,N,N,64602,64603,64604,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64606,64607,64608,N,N,N,N,N,N,64609,64610,64611,N,N,N,64612,64613,N,N,N,N, +64614,N,N,N,N,N,N,64615,64616,N,N,N,N,N,N,N,N,N,32298,N,N,N,64617,N,N,64618, +64619,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32299,N,N,N,N,64620,N,N, +64621,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64622,N,N,N,64623,N,64624,N,N,N, +64625,N,N,N,N,N,64626,N,N,N,N,N,N,N,N,N,N,64627,N,N,N,N,64628,N,N,N,N,64629,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64631,N,N,N,N,N,N,N,N,64632,N,N,64633,32300, +32301,N,N,N,N,N,N,64634,N,N,N,N,N,N,64635,N,N,N,N,64636,N,N,N,64637,N,N,N,N,N, +64638,N,N,N,32302,N,N,N,N,N,N,N,N,32303,32304,N,N,64801,N,N,N,N,64802,N,32305, +N,N,N,N,N,N,N,N,N,N,N,64803,N,N,N,N,N,32306,N,64804,N,32307,N,N,N,32308,N,N,N, +N,N,64805,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,64807,N,N,N,N,N,N,32309,64809,N,64811,N,N,N,N,N,N,N, +32310,N,32311,N,N,64813,N,N,N,N,N,N,N,32312,N,64814,N,64815,N,N,64816,32313,N, +N,N,N,N,64818,N,N,N,64819,N,N,N,N,64820,N,N,N,64821,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,32314,32315,64822,N,N,N,N,32316,N,N,N,64823,N,N,N,64824,N,64825,N,N,N, +64826,N,N,N,N,N,64827,N,N,N,32317,N,N,N,N,N,N,N,N,N,N,64828,N,32319,N,N,N,N,N, +64829,N,N,N,N,N,N,N,N,N,64830,N,N,N,N,N,N,N,N,N,N,N,N,N,64832,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,32320,N,N,N,N,64833,N,64834,32322,N,N,N,N,64835,64836,N,N, +N,N,N,32323,64837,N,32324,64838,64839,N,32321,N,N,N,N,N,N,N,N,N,N,32325,N,N,N, +N,N,32326,N,N,N,N,32327,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32328,N,N,N,N,N,N,N,64840, +32329,N,N,N,N,64841,N,N,N,N,64842,64845,N,N,N,N,N,64846,N,N,N,N,N,64847,N,N, +32330,N,N,N,N,N,64848,N,N,N,N,N,N,32331,N,N,N,N,N,N,N,N,N,64850,N,N,N,N,64851, +N,N,N,N,N,N,N,32332,N,64852,N,N,64853,64854,N,N,64856,64855,N,N,N,64849,N,N,N, +64860,32333,N,64858,N,N,32334,32335,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64862,N,64863,64864,64865,N,N,64866,N,N,N,N,64867,32336,N,N,N,64868,N,64869, +64870,N,N,N,N,N,N,64872,N,N,N,N,64873,64874,N,N,N,N,N,N,N,N,N,32337,N,N,N, +64875,N,N,N,64878,64879,N,N,N,N,32338,32339,N,N,32340,64881,N,N,N,64882,N,N, +64883,64876,64884,N,64885,N,N,N,32341,N,32342,N,N,N,64886,64887,64888,N,64889, +64890,N,64891,N,64892,N,N,64893,N,32343,N,N,64894,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65057,N,N,N,N,N,N,N,N,N,N,N,65058,65060,N,N,N,N, +N,N,N,N,65059,N,N,N,N,N,65062,N,N,N,N,N,65063,65064,N,N,N,N,32344,32345,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65068,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65070, +32346,N,N,N,32347,N,N,65071,N,N,N,N,N,N,N,32348,N,N,N,N,N,N,N,N,N,N,N,N,65072, +N,N,65073,32349,N,N,N,N,N,65075,N,65076,N,N,N,N,32350,N,N,65078,N,N,65079, +65080,N,N,N,N,32351,N,65081,N,N,N,N,N,65082,N,N,N,N,N,32352,N,N,65083,N,N,N,N, +N,N,N,N,32353,N,N,65084,N,N,N,N,N,N,N,65085,N,N,N,N,N,N,N,N,N,N,32355,N,N,N,N, +N,N,N,N,65087,N,N,N,65088,N,N,32356,65089,N,65086,32354,N,N,65090,N,N,N,65091, +N,65092,N,N,N,N,N,N,N,N,N,N,N,N,65093,32357,N,N,65094,N,N,N,N,65095,65096,N,N, +65097,N,N,N,32359,N,N,N,N,N,N,N,N,N,N,N,N,65098,65101,N,N,N,N,32360,N,N,65100, +N,N,65102,N,N,N,N,N,N,N,32361,N,N,N,65103,N,N,65104,65105,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,65106,32362,N,N,N,65108,N,N,N,N,65109,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,65110,N,N,32363,N,N,N,N,N,32364,N,N,N,65111,N,N,N,32365,N,N,32366, +N,N,N,N,32367,32368,N,N,N,N,N,N,N,65113,N,N,N,N,N,32369,N,N,N,N,N,N,N,N,N,N,N, +N,N,32370,N,N,N,N,N,N,N,N,N,N,N,N,N,65115,N,N,N,N,N,N,N,65116,N,N,N,N,N,N, +65117,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65118,65119,65121,N,N,N,N,N,N,N,N,N,N,N, +N,32371,N,N,N,N,N,N,65122,N,65123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +65124,N,N,N,N,N,N,N,65125,N,32372,65126,N,N,65127,N,N,N,65128,N,N,N,65129, +65130,N,N,N,N,N,N,N,N,N,N,N,N,65131,N,65132,N,32373,65133,N,N,N,N,65135,N,N,N, +N,N,N,N,N,N,N,N,65137,N,N,N,65139,N,N,65140,N,N,N,N,65141,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32374,N,N,N,32375,N,N,32376,N,N,N,N,N,N,N,N,N, +N,32377,30267,N,N,N,N,N,N,N,N,N,N,29742,30030,N,N,N,N,N,N,N,N,N,N,N,N,31567,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +32292,N,N,N,N,N,N,N,N,N,N,N,32093,12107,12119,20338,N,44665,30074,30554,30575, +N,N,31036,31037,31041,N,N,N,31546,63288,63301,31790,N,63854,N,31850,N,N,N,N,N, +N,N,N,N,11832,11849,11856,11875,11880,11886,12076,12079,12086,12122,12126, +20321,20322,29776,29788,29790,29793,29992,29995,30019,30053,30313,30327,30501, +30549,61481,30757,31015,31027,31028,31031,31032,31033,31035,31039,31040,31053, +31057,31076,31278,62544,31283,31290,31300,31320,62836,62837,31527,31599,31609, +31791,31792,31800,31805,63849,31833,32099,32118,32123,9022,9021,8752,N,N,N,N, +8751,N,N,N,N,N,8753, +}; + +static const struct unim_index jisx0213_bmp_encmap[256] = { +{__jisx0213_bmp_encmap+0,126,255},{__jisx0213_bmp_encmap+130,0,253},{ +__jisx0213_bmp_encmap+384,80,233},{__jisx0213_bmp_encmap+538,0,194},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+733,62,63 +},{__jisx0213_bmp_encmap+735,112,115},{__jisx0213_bmp_encmap+739,19,172},{ +__jisx0213_bmp_encmap+893,15,233},{__jisx0213_bmp_encmap+1112,5,219},{ +__jisx0213_bmp_encmap+1327,5,206},{__jisx0213_bmp_encmap+1529,35,254},{ +__jisx0213_bmp_encmap+1749,177,230},{__jisx0213_bmp_encmap+1803,0,110},{ +__jisx0213_bmp_encmap+1914,19,127},{0,0,0},{__jisx0213_bmp_encmap+2023,52,251 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+2223, +22,255},{__jisx0213_bmp_encmap+2457,240,255},{__jisx0213_bmp_encmap+2473,49, +250},{__jisx0213_bmp_encmap+2675,3,205},{__jisx0213_bmp_encmap+2878,2,219},{ +__jisx0213_bmp_encmap+3096,31,244},{__jisx0213_bmp_encmap+3310,5,207},{ +__jisx0213_bmp_encmap+3513,97,253},{__jisx0213_bmp_encmap+3670,0,250},{ +__jisx0213_bmp_encmap+3921,23,111},{__jisx0213_bmp_encmap+4010,110,234},{ +__jisx0213_bmp_encmap+4135,14,240},{__jisx0213_bmp_encmap+4362,15,210},{ +__jisx0213_bmp_encmap+4558,17,212},{__jisx0213_bmp_encmap+4754,5,148},{ +__jisx0213_bmp_encmap+4898,87,215},{__jisx0213_bmp_encmap+5027,57,147},{ +__jisx0213_bmp_encmap+5118,5,243},{__jisx0213_bmp_encmap+5357,7,221},{ +__jisx0213_bmp_encmap+5572,2,240},{__jisx0213_bmp_encmap+5811,8,212},{ +__jisx0213_bmp_encmap+6016,8,234},{__jisx0213_bmp_encmap+6243,15,175},{ +__jisx0213_bmp_encmap+6404,12,253},{__jisx0213_bmp_encmap+6646,22,181},{ +__jisx0213_bmp_encmap+6806,176,250},{__jisx0213_bmp_encmap+6881,4,188},{ +__jisx0213_bmp_encmap+7066,59,232},{__jisx0213_bmp_encmap+7240,23,209},{ +__jisx0213_bmp_encmap+7427,7,119},{__jisx0213_bmp_encmap+7540,2,255},{ +__jisx0213_bmp_encmap+7794,0,242},{__jisx0213_bmp_encmap+8037,0,243},{ +__jisx0213_bmp_encmap+8281,3,244},{__jisx0213_bmp_encmap+8523,1,251},{ +__jisx0213_bmp_encmap+8774,0,245},{__jisx0213_bmp_encmap+9020,18,255},{ +__jisx0213_bmp_encmap+9258,0,233},{__jisx0213_bmp_encmap+9492,7,247},{ +__jisx0213_bmp_encmap+9733,10,255},{__jisx0213_bmp_encmap+9979,4,244},{ +__jisx0213_bmp_encmap+10220,5,248},{__jisx0213_bmp_encmap+10464,12,245},{ +__jisx0213_bmp_encmap+10698,0,253},{__jisx0213_bmp_encmap+10952,3,244},{ +__jisx0213_bmp_encmap+11194,6,233},{__jisx0213_bmp_encmap+11422,0,253},{ +__jisx0213_bmp_encmap+11676,0,252},{__jisx0213_bmp_encmap+11929,13,248},{ +__jisx0213_bmp_encmap+12165,16,245},{__jisx0213_bmp_encmap+12395,21,253},{ +__jisx0213_bmp_encmap+12628,3,247},{__jisx0213_bmp_encmap+12873,9,255},{ +__jisx0213_bmp_encmap+13120,4,252},{__jisx0213_bmp_encmap+13369,0,251},{ +__jisx0213_bmp_encmap+13621,1,252},{__jisx0213_bmp_encmap+13873,1,252},{ +__jisx0213_bmp_encmap+14125,3,254},{__jisx0213_bmp_encmap+14377,15,253},{ +__jisx0213_bmp_encmap+14616,11,255},{__jisx0213_bmp_encmap+14861,2,251},{ +__jisx0213_bmp_encmap+15111,0,252},{__jisx0213_bmp_encmap+15364,23,251},{ +__jisx0213_bmp_encmap+15593,10,252},{__jisx0213_bmp_encmap+15836,0,236},{ +__jisx0213_bmp_encmap+16073,3,254},{__jisx0213_bmp_encmap+16325,0,251},{ +__jisx0213_bmp_encmap+16577,7,250},{__jisx0213_bmp_encmap+16821,1,255},{ +__jisx0213_bmp_encmap+17076,1,249},{__jisx0213_bmp_encmap+17325,0,252},{ +__jisx0213_bmp_encmap+17578,10,251},{__jisx0213_bmp_encmap+17820,5,254},{ +__jisx0213_bmp_encmap+18070,0,237},{__jisx0213_bmp_encmap+18308,3,253},{ +__jisx0213_bmp_encmap+18559,7,240},{__jisx0213_bmp_encmap+18793,1,245},{ +__jisx0213_bmp_encmap+19038,3,249},{__jisx0213_bmp_encmap+19285,8,154},{ +__jisx0213_bmp_encmap+19432,59,250},{__jisx0213_bmp_encmap+19624,2,251},{ +__jisx0213_bmp_encmap+19874,13,255},{__jisx0213_bmp_encmap+20117,4,254},{ +__jisx0213_bmp_encmap+20368,0,249},{__jisx0213_bmp_encmap+20618,1,253},{ +__jisx0213_bmp_encmap+20871,12,255},{__jisx0213_bmp_encmap+21115,0,253},{ +__jisx0213_bmp_encmap+21369,5,245},{__jisx0213_bmp_encmap+21610,1,245},{ +__jisx0213_bmp_encmap+21855,1,255},{__jisx0213_bmp_encmap+22110,17,252},{ +__jisx0213_bmp_encmap+22346,5,158},{__jisx0213_bmp_encmap+22500,57,254},{ +__jisx0213_bmp_encmap+22698,9,253},{__jisx0213_bmp_encmap+22943,6,250},{ +__jisx0213_bmp_encmap+23188,0,251},{__jisx0213_bmp_encmap+23440,2,255},{ +__jisx0213_bmp_encmap+23694,0,251},{__jisx0213_bmp_encmap+23946,1,255},{ +__jisx0213_bmp_encmap+24201,2,253},{__jisx0213_bmp_encmap+24453,4,114},{ +__jisx0213_bmp_encmap+24564,120,222},{__jisx0213_bmp_encmap+24667,29,239},{ +__jisx0213_bmp_encmap+24878,20,244},{__jisx0213_bmp_encmap+25103,4,243},{ +__jisx0213_bmp_encmap+25343,8,252},{__jisx0213_bmp_encmap+25588,2,249},{ +__jisx0213_bmp_encmap+25836,2,253},{__jisx0213_bmp_encmap+26088,0,242},{ +__jisx0213_bmp_encmap+26331,2,244},{__jisx0213_bmp_encmap+26574,2,255},{ +__jisx0213_bmp_encmap+26828,2,162},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_bmp_encmap+26989 +,29,220},{__jisx0213_bmp_encmap+27181,15,106},{0,0,0},{0,0,0},{0,0,0},{ +__jisx0213_bmp_encmap+27273,69,70},{__jisx0213_bmp_encmap+27275,2,13}, +}; + +static const ucs2_t __jisx0213_1_emp_decmap[340] = { +11,4669,U,U,U,U,U,U,U,U,U,4891,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,5230,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,6333,2975,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,5812,U,U,U,U,U,U,U,U,U,U,7732,12740,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +13764,14143,U,U,U,U,U,U,U,U,14179,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15614,18417,21646,21774,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22385,U,U,U,U,U,U,U,U,U,U,U, +U,22980,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23969,27391,28224,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28916,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30340,33399,U,U,U,U,U,U,U,33741,41360, +}; + +static const struct dbcs_index jisx0213_1_emp_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__jisx0213_1_emp_decmap+0,34,34},{__jisx0213_1_emp_decmap+1,66,123},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{__jisx0213_1_emp_decmap+59,84,110},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_1_emp_decmap+86,58,114},{ +__jisx0213_1_emp_decmap+143,41,96},{__jisx0213_1_emp_decmap+199,108,108},{ +__jisx0213_1_emp_decmap+200,126,126},{__jisx0213_1_emp_decmap+201,41,110},{ +__jisx0213_1_emp_decmap+271,93,93},{__jisx0213_1_emp_decmap+272,51,108},{ +__jisx0213_1_emp_decmap+330,73,81},{0,0,0},{__jisx0213_1_emp_decmap+339,102, +102},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const ucs2_t __jisx0213_2_emp_decmap[2053] = { +137,U,U,U,U,U,U,U,U,U,162,U,U,164,U,U,U,U,U,U,U,418,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,531,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,811,U,U,U,U,U,U,897,U,881,1017,U,U,1098,U,1289,U,U,U,U,U,U,U,U,U, +1494,1576,U,U,U,U,U,1871,U,U,U,U,U,U,2055,U,2106,U,U,U,U,U,U,U,U,2233,U,U,U,U, +U,U,U,2428,2461,U,U,U,U,U,2771,U,U,2845,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,3397,3553,U,U,U,U,U,U,3733,3693,U,U,U,U,U,U,U,3684,U,U,3935,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,4609,U,U,4693,U,4731,U,U,U, +U,4724,U,U,U,U,U,U,4836,4823,U,U,U,U,U,U,4861,U,4918,4932,5060,U,U,U,U,U,U,U, +U,U,U,U,U,5229,U,U,U,U,U,U,U,U,U,U,U,5591,U,U,U,U,U,27689,U,U,5703,U,U,U,U,U, +U,U,U,U,U,U,U,U,5894,5954,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,6595,7254,U,U,U,U,U,U,7469,7493,U,7544,7522,U,U,U, +7585,7580,U,U,U,U,7570,U,U,7607,U,7648,7731,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +7966,U,U,U,U,U,U,U,U,U,U,8054,U,U,U,U,U,8186,8571,U,U,U,U,U,U,U,U,8990,U,U,U, +U,9133,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,9971,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,10331,U,U,U,U,U,U,U,10411,U,U,U,U,10639, +10936,U,U,U,U,11087,11088,U,U,U,U,U,U,U,11078,U,11293,11174,U,U,U,11300,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,11745,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12739,12789,12726,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13170,U,13267,13266,U,U,U,U,13264,13284, +13269,U,U,13274,U,13279,U,U,U,U,U,U,U,U,U,U,U,13386,13393,13387,U,U,U,13413,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13540,13658,13716,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,13881,13895,U,13880,13882,U,U,U,U,U,U,U,U,U,U, +14108,U,U,U,U,U,U,U,U,U,U,14092,U,U,U,U,U,U,U,14180,U,U,U,U,U,U,U,14335,14311, +U,U,U,U,U,14372,U,U,U,U,14397,15000,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15487,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,15616,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +15680,U,15866,15865,15827,16254,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,16534, +U,U,U,U,U,16643,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,16838,U,U,16894,17340,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,17961,U,U,U,U,U,18085,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,18582,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19021,19286,U,19311,U,U,U,U,19478,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,19732,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19982,U,U, +U,20023,U,U,U,U,20074,U,U,20107,U,U,U,U,U,U,U,U,U,U,U,20554,U,20565,U,U,20770, +20905,U,20965,20941,U,U,U,21022,U,U,U,21068,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +21550,U,U,U,U,U,U,U,U,U,U,21721,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21927,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22441,22452,22996,U,U,U,U,U,U,U, +U,U,U,23268,23267,U,23281,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23474,U,U,U,U,U,U, +U,U,U,U,23627,23652,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24110,24150,24165, +U,24162,U,U,U,24280,U,24258,24296,U,24355,U,U,24412,U,U,U,U,U,U,24544,24532,U, +U,U,U,24588,24571,U,U,U,U,U,U,U,24599,U,U,U,U,24672,U,U,U,U,U,U,U,U,U,U,U,U, +24813,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25200,U,25222,U,U,U,U, +U,U,25420,U,U,15630,U,U,U,25602,26238,U,U,U,U,26288,U,U,U,U,U,U,U,U,U,U,U, +26397,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26845,U,26858,U,26961,U,U,26991,U,27101,U, +U,U,27166,U,U,U,U,U,U,27224,U,U,U,U,U,27276,U,U,27319,27763,U,U,U,U,U,U,U,U,U, +27869,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28261,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,28564,U,U,U,U,U,U,U,U,28664,28662,28663,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,28941,U,U,28985,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29659,29658,U,U,U,U,U,29694,U,U,29712,U,U,U,U, +29769,30229,30228,U,30257,U,U,U,U,U,U,U,30355,U,U,U,U,U,U,U,30478,U,30499,U,U, +U,30546,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31109,U,U,U,U,U,U,U,U,U,U,U,U, +31364,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31667,U,31678,31687,31928,U,U,U,U, +U,U,U,U,U,32160,U,U,32272,U,U,U,U,U,U,32695,U,U,U,U,U,U,U,U,32906,U,U,U,U,U, +32955,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33410,U,U,U,U,33523,U,U,U,U,U,U,U,33804, +U,U,U,U,33877,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34155,U,U,U,34248,34249,U,U,U,U,U,U, +U,U,U,U,34519,U,U,34554,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,35145,35142,U,U,U,U,U,U,35179,U,U,U,U,U,U,U,U,U,U,U,U,U,35207,35208,U, +U,U,U,U,U,U,U,U,U,35258,35259,U,U,U,U,U,U,U,U,U,U,U,35358,35369,U,U,U,U,U,U,U, +U,U,U,35441,35395,U,U,U,U,U,U,U,U,35481,35533,U,U,U,U,U,35556,35549,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,35777,35823,U,U,U,U,U,U,U,36112,U,U,36209,U,36347,36383,U, +U,U,36406,U,U,U,36489,U,36587,U,36658,U,U,U,U,U,U,U,36856,37536,37553,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38032,U,U,U,U,U,U,U,U,U,38351,U,U,U,U,U,U,U,U, +U,38527,U,U,U,U,U,U,U,U,U,38640,U,U,38681,U,U,U,38736,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,39110,39538,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,40411,40509,U,U,U,U,U,U,U,U,U,U,U,U,40469,U,40586,U,40521,U, +U,U,U,U,U,U,U,U,40644,U,U,U,U,U,40681,U,U,40667,40910,U,U,U,41007,U,40986,U,U, +U,U,U,U,41209,U,U,41090,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,8728,U,U,U,U,41868,U,42039,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,42481,U, +42498,U,42522,U,U,U,42674, +}; + +static const struct dbcs_index jisx0213_2_emp_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+0,33,121},{0,0,0},{ +__jisx0213_2_emp_decmap+89,34,119},{__jisx0213_2_emp_decmap+175,42,117},{ +__jisx0213_2_emp_decmap+251,37,126},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+ +341,48,108},{0,0,0},{0,0,0},{0,0,0},{__jisx0213_2_emp_decmap+402,34,114},{ +__jisx0213_2_emp_decmap+483,36,125},{__jisx0213_2_emp_decmap+573,35,120},{ +__jisx0213_2_emp_decmap+659,42,117},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +__jisx0213_2_emp_decmap+735,35,96},{__jisx0213_2_emp_decmap+797,50,100},{ +__jisx0213_2_emp_decmap+848,34,123},{__jisx0213_2_emp_decmap+938,46,122},{ +__jisx0213_2_emp_decmap+1015,33,118},{__jisx0213_2_emp_decmap+1101,50,125},{ +__jisx0213_2_emp_decmap+1177,34,121},{__jisx0213_2_emp_decmap+1265,53,115},{ +__jisx0213_2_emp_decmap+1328,68,126},{__jisx0213_2_emp_decmap+1387,33,115},{ +__jisx0213_2_emp_decmap+1470,41,122},{__jisx0213_2_emp_decmap+1552,37,126},{ +__jisx0213_2_emp_decmap+1642,33,126},{__jisx0213_2_emp_decmap+1736,33,113},{ +__jisx0213_2_emp_decmap+1817,34,118},{__jisx0213_2_emp_decmap+1902,44,112},{ +__jisx0213_2_emp_decmap+1971,37,118},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const DBCHAR __jisx0213_emp_encmap[8787] = { +11810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,41249,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +41259,N,41262,41270,41286,41328,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,41337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41335,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41762,41765,41767, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,41777,41778,41784,41791,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41793,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,41802,41810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,41811,41817,41820,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20308,41847,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42026,42042,N,N,N, +N,N,N,N,N,42034,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,42033,42045,42073,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +12098,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42076,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42083,N,N,N,N,N,N,42078,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,42091,N,N,N,N,N,N,N,N,N,N,N,N,42090,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,42098,12108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,42100,N,N,N,N,N,N,N,N,N,N,N,N,N,42101,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42277,42290, +12128,42302,42311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +20323,42325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,42326,12155,42366,43056, +43063,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43064,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43067,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,43066,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43077,N,N,N,N,N, +N,N,N,N,43072,N,N,N,N,43071,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43080,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +43082,43083,20334,43099,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43110,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +43116,44066,65107,44075,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +44080,44112,44133,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,44141,44146,44324,44338,N,N,N,N,N,N,N,N,44329,44330,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,44341,44340,N,N,N,N,N,N,44345,44374,44580,N,N,N,N,N,N,N,N,N,N,N,N, +44413,30010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44579,44602,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44610, +N,44605,44604,N,44612,N,N,N,N,44615,N,N,N,N,44617,N,N,N,N,44611,44629,44631,N, +N,N,N,N,44630,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44635,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +44663,44664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44842,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30066, +44866,44863,44867,N,N,N,N,N,N,N,N,N,N,N,N,44864,44889,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,44878,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,30249,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +30258,44897,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44906,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,44905,44912,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44917, +60963,60980,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30304,61001,N,N,N,N,N,N,N,N,N,N,N,N,N,62581,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,61020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,61024,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,61023,61022,61234,61255,61261,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61284, +61474,61491,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,61497,30572,61523,61563,61742,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,61744,61749,61764,61789,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61793,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +61798,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61801, +61813,N,N,N,N,N,N,N,N,N,N,61815,61818,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61985, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61988,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61987,61992,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,61996, +62013,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62024,31017,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62043,31047,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,62069,N,N,N,N,N,N,N,N,N,N,62070,31060,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +62258,62270,62269,N,N,N,N,N,N,N,N,N,N,N,N,62272,62290,62301,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62302,31086,62323,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62324,N,N,N,N,N,N,N,N,N,N,N, +62327,N,N,62325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62333,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,62331,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62498,62500,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,62503,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,62511,N,N,N,N,N,N,N,N,N,N,N,62510,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62517,62516,N,N,N,N,N,N,N,N,N,N,62525,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62530,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62543,62569,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,62571,62578,62585,62773,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62778,62790,62806,N,N, +N,N,N,N,N,N,N,N,N,N,62808,62810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,62813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,62815,62819,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,62826,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,62832,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,62835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,31325,42308,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,63044,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63054, +31539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +63069,63093,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63265,63266,63102,31561, +63283,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,63286,63333,63332,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,63339,63342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63347, +63530,63529,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63532,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,31596,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63540,63548,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,63550,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63554,63574,63587,63607,N,N,N,N,N,N,N,N,N,N, +63609,N,N,N,N,N,N,N,N,63610,63781,63791,63794,63801,63810,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +63816,31817,N,N,N,N,N,N,N,N,N,N,63833,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,63838,31825,63846,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,63851,63866,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +63870,64033,64044,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,64047,64080,N,N,64079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,64087,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64101,64102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64113,64114,64126,N,N,N,N,N,N,N,N,N,N,64289,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64301,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64300,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64310, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,64311,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64318,N,N,N,N,N,N, +64317,64334,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,64335,64343,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64346, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64348,64349,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,64353,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64357,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64359,64361,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,64369,64546,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64547,64568,64578, +64588,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64598,64601,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64605,64630,64812,64843,64857,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64844, +N,N,N,N,N,N,N,N,N,N,N,64861,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +64859,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,64871,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,64880,N,N,N,N,N,N,N,N,N,N,N,N,N,64877,65061,65067,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,65065,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65077,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65074,32358,65112,65114,65134, +65136,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65138,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,65142, +}; + +static const struct unim_index jisx0213_emp_encmap[256] = { +{__jisx0213_emp_encmap+0,11,164},{__jisx0213_emp_encmap+154,162,162},{ +__jisx0213_emp_encmap+155,19,19},{__jisx0213_emp_encmap+156,43,249},{ +__jisx0213_emp_encmap+363,74,74},{__jisx0213_emp_encmap+364,9,214},{ +__jisx0213_emp_encmap+570,40,40},{__jisx0213_emp_encmap+571,79,79},{ +__jisx0213_emp_encmap+572,7,185},{__jisx0213_emp_encmap+751,124,157},{ +__jisx0213_emp_encmap+785,211,211},{__jisx0213_emp_encmap+786,29,159},{0,0,0}, +{__jisx0213_emp_encmap+917,69,225},{__jisx0213_emp_encmap+1074,100,149},{ +__jisx0213_emp_encmap+1124,95,95},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+1125, +1,253},{__jisx0213_emp_encmap+1378,27,196},{__jisx0213_emp_encmap+1548,109,110 +},{__jisx0213_emp_encmap+1550,215,215},{__jisx0213_emp_encmap+1551,71,180},{ +__jisx0213_emp_encmap+1661,6,66},{__jisx0213_emp_encmap+1722,189,189},{ +__jisx0213_emp_encmap+1723,195,195},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+ +1724,86,86},{__jisx0213_emp_encmap+1725,45,224},{__jisx0213_emp_encmap+1905, +51,52},{__jisx0213_emp_encmap+1907,30,250},{0,0,0},{__jisx0213_emp_encmap+2128 +,123,123},{__jisx0213_emp_encmap+2129,24,24},{__jisx0213_emp_encmap+2130,30, +173},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+2274,243,243},{0,0,0},{ +__jisx0213_emp_encmap+2275,91,171},{__jisx0213_emp_encmap+2356,143,143},{ +__jisx0213_emp_encmap+2357,184,184},{__jisx0213_emp_encmap+2358,70,166},{ +__jisx0213_emp_encmap+2455,29,36},{__jisx0213_emp_encmap+2463,225,225},{0,0,0 +},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+2464,182,245},{0,0,0},{ +__jisx0213_emp_encmap+2528,114,228},{__jisx0213_emp_encmap+2643,74,228},{ +__jisx0213_emp_encmap+2798,90,196},{__jisx0213_emp_encmap+2905,56,71},{ +__jisx0213_emp_encmap+2921,12,255},{__jisx0213_emp_encmap+3165,36,61},{0,0,0}, +{__jisx0213_emp_encmap+3191,152,152},{0,0,0},{__jisx0213_emp_encmap+3192,127, +254},{__jisx0213_emp_encmap+3320,0,250},{0,0,0},{__jisx0213_emp_encmap+3571, +126,126},{__jisx0213_emp_encmap+3572,150,150},{__jisx0213_emp_encmap+3573,3, +254},{0,0,0},{__jisx0213_emp_encmap+3825,188,188},{0,0,0},{0,0,0},{ +__jisx0213_emp_encmap+3826,41,165},{__jisx0213_emp_encmap+3951,241,241},{ +__jisx0213_emp_encmap+3952,150,150},{0,0,0},{__jisx0213_emp_encmap+3953,77,77 +},{__jisx0213_emp_encmap+3954,86,111},{__jisx0213_emp_encmap+3980,22,22},{ +__jisx0213_emp_encmap+3981,20,20},{__jisx0213_emp_encmap+3982,14,139},{0,0,0}, +{__jisx0213_emp_encmap+4108,74,85},{__jisx0213_emp_encmap+4120,34,229},{ +__jisx0213_emp_encmap+4316,30,76},{0,0,0},{__jisx0213_emp_encmap+4363,46,217}, +{__jisx0213_emp_encmap+4535,14,167},{0,0,0},{__jisx0213_emp_encmap+4689,113, +180},{0,0,0},{__jisx0213_emp_encmap+4757,196,212},{__jisx0213_emp_encmap+4774, +227,241},{__jisx0213_emp_encmap+4789,178,178},{__jisx0213_emp_encmap+4790,75, +100},{__jisx0213_emp_encmap+4816,161,161},{__jisx0213_emp_encmap+4817,46,232}, +{__jisx0213_emp_encmap+5004,35,251},{__jisx0213_emp_encmap+5221,12,237},{0,0,0 +},{__jisx0213_emp_encmap+5447,112,134},{__jisx0213_emp_encmap+5470,76,76},{ +__jisx0213_emp_encmap+5471,2,2},{0,0,0},{__jisx0213_emp_encmap+5472,126,176},{ +__jisx0213_emp_encmap+5523,29,29},{__jisx0213_emp_encmap+5524,221,234},{ +__jisx0213_emp_encmap+5538,81,221},{__jisx0213_emp_encmap+5679,30,255},{0,0,0 +},{__jisx0213_emp_encmap+5905,41,221},{0,0,0},{__jisx0213_emp_encmap+6086,64, +101},{__jisx0213_emp_encmap+6124,148,248},{__jisx0213_emp_encmap+6225,244,244 +},{__jisx0213_emp_encmap+6226,13,57},{0,0,0},{__jisx0213_emp_encmap+6271,218, +254},{__jisx0213_emp_encmap+6308,16,73},{0,0,0},{__jisx0213_emp_encmap+6366, +20,147},{__jisx0213_emp_encmap+6494,14,82},{0,0,0},{__jisx0213_emp_encmap+6563 +,133,133},{__jisx0213_emp_encmap+6564,132,132},{__jisx0213_emp_encmap+6565, +179,199},{__jisx0213_emp_encmap+6586,184,184},{__jisx0213_emp_encmap+6587,160, +160},{__jisx0213_emp_encmap+6588,16,16},{__jisx0213_emp_encmap+6589,183,183},{ +__jisx0213_emp_encmap+6590,138,187},{0,0,0},{__jisx0213_emp_encmap+6640,119, +243},{__jisx0213_emp_encmap+6765,205,205},{__jisx0213_emp_encmap+6766,12,85},{ +__jisx0213_emp_encmap+6840,107,201},{__jisx0213_emp_encmap+6935,215,250},{0,0, +0},{0,0,0},{__jisx0213_emp_encmap+6971,70,187},{__jisx0213_emp_encmap+7089,30, +228},{__jisx0213_emp_encmap+7288,193,239},{0,0,0},{__jisx0213_emp_encmap+7335, +16,251},{__jisx0213_emp_encmap+7571,31,235},{__jisx0213_emp_encmap+7776,50,248 +},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+7975,160,177},{0,0,0},{ +__jisx0213_emp_encmap+7993,144,144},{__jisx0213_emp_encmap+7994,207,207},{ +__jisx0213_emp_encmap+7995,127,240},{__jisx0213_emp_encmap+8109,25,80},{ +__jisx0213_emp_encmap+8165,198,198},{0,0,0},{__jisx0213_emp_encmap+8166,114, +114},{0,0,0},{0,0,0},{__jisx0213_emp_encmap+8167,219,219},{ +__jisx0213_emp_encmap+8168,21,233},{__jisx0213_emp_encmap+8381,206,206},{ +__jisx0213_emp_encmap+8382,26,249},{__jisx0213_emp_encmap+8606,144,144},{0,0,0 +},{__jisx0213_emp_encmap+8607,140,140},{__jisx0213_emp_encmap+8608,55,55},{ +__jisx0213_emp_encmap+8609,241,241},{__jisx0213_emp_encmap+8610,2,178},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0}, +}; + diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_kr.h b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_kr.h index bb59acccc1e..10b7fc3d45e 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_kr.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_kr.h @@ -1,3253 +1,3253 @@ // AUTO-GENERATED FILE FROM genmap_korean.py: DO NOT EDIT -static const ucs2_t __ksx1001_decmap[8264] = { -12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217, -8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304, -12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504, -65505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733, -9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595, -8596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834, -8835,8746,8745,8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730, -729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828, -9824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639, -9638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600, -9837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174, -65281,65282,65283,65284,65285,65286,65287,65288,65289,65290,65291,65292,65293, -65294,65295,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65306, -65307,65308,65309,65310,65311,65312,65313,65314,65315,65316,65317,65318,65319, -65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332, -65333,65334,65335,65336,65337,65338,65339,65510,65341,65342,65343,65344,65345, -65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358, -65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371, -65372,65373,65507,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602, -12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615, -12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628, -12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641, -12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654, -12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667, -12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680, -12681,12682,12683,12684,12685,12686,8560,8561,8562,8563,8564,8565,8566,8567, -8568,8569,U,U,U,U,U,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,U,U,U,U, -U,U,U,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931, -932,933,934,935,936,937,U,U,U,U,U,U,U,U,945,946,947,948,949,950,951,952,953, -954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,9472,9474,9484, -9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507, -9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,9490, -9489,9498,9497,9494,9493,9486,9485,9502,9503,9505,9506,9510,9511,9513,9514, -9517,9518,9521,9522,9525,9526,9529,9530,9533,9534,9536,9537,9539,9540,9541, -9542,9543,9544,9545,9546,13205,13206,13207,8467,13208,13252,13219,13220,13221, -13222,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13258,13197, -13198,13199,13263,13192,13193,13256,13223,13224,13232,13233,13234,13235,13236, -13237,13238,13239,13240,13241,13184,13185,13186,13187,13188,13242,13243,13244, -13245,13246,13247,13200,13201,13202,13203,13204,8486,13248,13249,13194,13195, -13196,13270,13253,13229,13230,13231,13275,13225,13226,13227,13228,13277,13264, -13267,13251,13257,13276,13254,198,208,170,294,U,306,U,319,321,216,338,186,222, -358,330,U,12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906, -12907,12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919, -12920,12921,12922,12923,9424,9425,9426,9427,9428,9429,9430,9431,9432,9433, -9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446,9447,9448, -9449,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325, -9326,189,8531,8532,188,190,8539,8540,8541,8542,230,273,240,295,305,307,312, -320,322,248,339,223,254,359,331,329,12800,12801,12802,12803,12804,12805,12806, -12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819, -12820,12821,12822,12823,12824,12825,12826,12827,9372,9373,9374,9375,9376,9377, -9378,9379,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392, -9393,9394,9395,9396,9397,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341, -9342,9343,9344,9345,9346,185,178,179,8308,8319,8321,8322,8323,8324,12353, -12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366, -12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379, -12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392, -12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405, -12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418, -12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431, -12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457, -12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470, -12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483, -12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496, -12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509, -12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522, -12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,1040, -1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054, -1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069, -1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,1073,1074,1075,1076,1077,1105, -1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092, -1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,44032,44033,44036, -44039,44040,44041,44042,44048,44049,44050,44051,44052,44053,44054,44055,44057, -44058,44059,44060,44061,44064,44068,44076,44077,44079,44080,44081,44088,44089, -44092,44096,44107,44109,44116,44120,44124,44144,44145,44148,44151,44152,44154, -44160,44161,44163,44164,44165,44166,44169,44170,44171,44172,44176,44180,44188, -44189,44191,44192,44193,44200,44201,44202,44204,44207,44208,44216,44217,44219, -44220,44221,44225,44228,44232,44236,44245,44247,44256,44257,44260,44263,44264, -44266,44268,44271,44272,44273,44275,44277,44278,44284,44285,44288,44292,44294, -44300,44301,44303,44305,44312,44316,44320,44329,44332,44333,44340,44341,44344, -44348,44356,44357,44359,44361,44368,44372,44376,44385,44387,44396,44397,44400, -44403,44404,44405,44406,44411,44412,44413,44415,44417,44418,44424,44425,44428, -44432,44444,44445,44452,44471,44480,44481,44484,44488,44496,44497,44499,44508, -44512,44516,44536,44537,44540,44543,44544,44545,44552,44553,44555,44557,44564, -44592,44593,44596,44599,44600,44602,44608,44609,44611,44613,44614,44618,44620, -44621,44622,44624,44628,44630,44636,44637,44639,44640,44641,44645,44648,44649, -44652,44656,44664,44665,44667,44668,44669,44676,44677,44684,44732,44733,44734, -44736,44740,44748,44749,44751,44752,44753,44760,44761,44764,44776,44779,44781, -44788,44792,44796,44807,44808,44813,44816,44844,44845,44848,44850,44852,44860, -44861,44863,44865,44866,44867,44872,44873,44880,44892,44893,44900,44901,44921, -44928,44932,44936,44944,44945,44949,44956,44984,44985,44988,44992,44999,45000, -45001,45003,45005,45006,45012,45020,45032,45033,45040,45041,45044,45048,45056, -45057,45060,45068,45072,45076,45084,45085,45096,45124,45125,45128,45130,45132, -45134,45139,45140,45141,45143,45145,45149,45180,45181,45184,45188,45196,45197, -45199,45201,45208,45209,45210,45212,45215,45216,45217,45218,45224,45225,45227, -45228,45229,45230,45231,45233,45235,45236,45237,45240,45244,45252,45253,45255, -45256,45257,45264,45265,45268,45272,45280,45285,45320,45321,45323,45324,45328, -45330,45331,45336,45337,45339,45340,45341,45347,45348,45349,45352,45356,45364, -45365,45367,45368,45369,45376,45377,45380,45384,45392,45393,45396,45397,45400, -45404,45408,45432,45433,45436,45440,45442,45448,45449,45451,45453,45458,45459, -45460,45464,45468,45480,45516,45520,45524,45532,45533,45535,45544,45545,45548, -45552,45561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591,45593, -45600,45620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700,45701, -45705,45712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734,45738, -45740,45744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789,45794, -45796,45797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813,45815, -45816,45817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843,45844, -45845,45852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925,45927, -45929,45931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957,45964, -45968,45972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030,46032, -46036,46037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104,46108, -46112,46120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179,46181, -46188,46208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276,46280, -46288,46293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321,46328, -46356,46357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384,46385, -46388,46392,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420,46428, -46429,46431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513,46515, -46516,46517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545,46552, -46572,46608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748,46749, -46752,46756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853,46888, -46889,46892,46895,46896,46904,46905,46907,46916,46920,46924,46932,46933,46944, -46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,46988,46989,46991, -46992,46993,46994,46998,46999,47000,47001,47004,47008,47016,47017,47019,47020, -47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,47100,47101,47103, -47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,47133,47140,47141, -47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,47187,47196,47197, -47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,47280,47284,47288, -47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,47336,47337,47340, -47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,47424,47428,47436, -47439,47441,47448,47449,47452,47456,47464,47465,47467,47469,47476,47477,47480, -47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,47536,47540,47548, -47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,47570,47576,47577, -47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,47605,47607,47608, -47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,47682,47688,47689, -47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,47719,47720,47721, -47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,47785,47787,47788, -47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,47868,47872,47876, -47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,47926,47928,47931, -47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,47956,47960,47969, -47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,48064,48068,48072, -48080,48083,48120,48121,48124,48127,48128,48130,48136,48137,48139,48140,48141, -48143,48145,48148,48149,48150,48151,48152,48155,48156,48157,48158,48159,48164, -48165,48167,48169,48173,48176,48177,48180,48184,48192,48193,48195,48196,48197, -48201,48204,48205,48208,48221,48260,48261,48264,48267,48268,48270,48276,48277, -48279,48281,48282,48288,48289,48292,48295,48296,48304,48305,48307,48308,48309, -48316,48317,48320,48324,48333,48335,48336,48337,48341,48344,48348,48372,48373, -48374,48376,48380,48388,48389,48391,48393,48400,48404,48420,48428,48448,48456, -48457,48460,48464,48472,48473,48484,48488,48512,48513,48516,48519,48520,48521, -48522,48528,48529,48531,48533,48537,48538,48540,48548,48560,48568,48596,48597, -48600,48604,48617,48624,48628,48632,48640,48643,48645,48652,48653,48656,48660, -48668,48669,48671,48708,48709,48712,48716,48718,48724,48725,48727,48729,48730, -48731,48736,48737,48740,48744,48746,48752,48753,48755,48756,48757,48763,48764, -48765,48768,48772,48780,48781,48783,48784,48785,48792,48793,48808,48848,48849, -48852,48855,48856,48864,48867,48868,48869,48876,48897,48904,48905,48920,48921, -48923,48924,48925,48960,48961,48964,48968,48976,48977,48981,49044,49072,49093, -49100,49101,49104,49108,49116,49119,49121,49212,49233,49240,49244,49248,49256, -49257,49296,49297,49300,49304,49312,49313,49315,49317,49324,49325,49327,49328, -49331,49332,49333,49334,49340,49341,49343,49344,49345,49349,49352,49353,49356, -49360,49368,49369,49371,49372,49373,49380,49381,49384,49388,49396,49397,49399, -49401,49408,49412,49416,49424,49429,49436,49437,49438,49439,49440,49443,49444, -49446,49447,49452,49453,49455,49456,49457,49462,49464,49465,49468,49472,49480, -49481,49483,49484,49485,49492,49493,49496,49500,49508,49509,49511,49512,49513, -49520,49524,49528,49541,49548,49549,49550,49552,49556,49558,49564,49565,49567, -49569,49573,49576,49577,49580,49584,49597,49604,49608,49612,49620,49623,49624, -49632,49636,49640,49648,49649,49651,49660,49661,49664,49668,49676,49677,49679, -49681,49688,49689,49692,49695,49696,49704,49705,49707,49709,49711,49713,49714, -49716,49736,49744,49745,49748,49752,49760,49765,49772,49773,49776,49780,49788, -49789,49791,49793,49800,49801,49808,49816,49819,49821,49828,49829,49832,49836, -49837,49844,49845,49847,49849,49884,49885,49888,49891,49892,49899,49900,49901, -49903,49905,49910,49912,49913,49915,49916,49920,49928,49929,49932,49933,49939, -49940,49941,49944,49948,49956,49957,49960,49961,49989,50024,50025,50028,50032, -50034,50040,50041,50044,50045,50052,50056,50060,50112,50136,50137,50140,50143, -50144,50146,50152,50153,50157,50164,50165,50168,50184,50192,50212,50220,50224, -50228,50236,50237,50248,50276,50277,50280,50284,50292,50293,50297,50304,50324, -50332,50360,50364,50409,50416,50417,50420,50424,50426,50431,50432,50433,50444, -50448,50452,50460,50472,50473,50476,50480,50488,50489,50491,50493,50500,50501, -50504,50505,50506,50508,50509,50510,50515,50516,50517,50519,50520,50521,50525, -50526,50528,50529,50532,50536,50544,50545,50547,50548,50549,50556,50557,50560, -50564,50567,50572,50573,50575,50577,50581,50583,50584,50588,50592,50601,50612, -50613,50616,50617,50619,50620,50621,50622,50628,50629,50630,50631,50632,50633, -50634,50636,50638,50640,50641,50644,50648,50656,50657,50659,50661,50668,50669, -50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,50693,50694, -50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,50732,50733, -50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,50760,50768, -50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,50809,50812, -50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,50855,50857, -50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,50893,50896, -50900,50908,50909,50912,50913,50920,50921,50924,50928,50936,50937,50941,50948, -50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,50992,50993, -50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,51025,51026, -51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,51061,51064, -51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,51088,51089, -51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,51116,51117, -51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,51152,51160, -51165,51172,51176,51180,51200,51201,51204,51208,51210,51216,51217,51219,51221, -51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,51264,51272, -51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,51331,51333, -51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,51389,51396, -51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,51453,51456, -51460,51461,51462,51468,51469,51471,51473,51480,51500,51508,51536,51537,51540, -51544,51552,51553,51555,51564,51568,51572,51580,51592,51593,51596,51600,51608, -51609,51611,51613,51648,51649,51652,51655,51656,51658,51664,51665,51667,51669, -51670,51673,51674,51676,51677,51680,51682,51684,51687,51692,51693,51695,51696, -51697,51704,51705,51708,51712,51720,51721,51723,51724,51725,51732,51736,51753, -51788,51789,51792,51796,51804,51805,51807,51808,51809,51816,51837,51844,51864, -51900,51901,51904,51908,51916,51917,51919,51921,51923,51928,51929,51936,51948, -51956,51976,51984,51988,51992,52000,52001,52033,52040,52041,52044,52048,52056, -52057,52061,52068,52088,52089,52124,52152,52180,52196,52199,52201,52236,52237, -52240,52244,52252,52253,52257,52258,52263,52264,52265,52268,52270,52272,52280, -52281,52283,52284,52285,52286,52292,52293,52296,52300,52308,52309,52311,52312, -52313,52320,52324,52326,52328,52336,52341,52376,52377,52380,52384,52392,52393, -52395,52396,52397,52404,52405,52408,52412,52420,52421,52423,52425,52432,52436, -52452,52460,52464,52481,52488,52489,52492,52496,52504,52505,52507,52509,52516, -52520,52524,52537,52572,52576,52580,52588,52589,52591,52593,52600,52616,52628, -52629,52632,52636,52644,52645,52647,52649,52656,52676,52684,52688,52712,52716, -52720,52728,52729,52731,52733,52740,52744,52748,52756,52761,52768,52769,52772, -52776,52784,52785,52787,52789,52824,52825,52828,52831,52832,52833,52840,52841, -52843,52845,52852,52853,52856,52860,52868,52869,52871,52873,52880,52881,52884, -52888,52896,52897,52899,52900,52901,52908,52909,52929,52964,52965,52968,52971, -52972,52980,52981,52983,52984,52985,52992,52993,52996,53000,53008,53009,53011, -53013,53020,53024,53028,53036,53037,53039,53040,53041,53048,53076,53077,53080, -53084,53092,53093,53095,53097,53104,53105,53108,53112,53120,53125,53132,53153, -53160,53168,53188,53216,53217,53220,53224,53232,53233,53235,53237,53244,53248, -53252,53265,53272,53293,53300,53301,53304,53308,53316,53317,53319,53321,53328, -53332,53336,53344,53356,53357,53360,53364,53372,53373,53377,53412,53413,53416, -53420,53428,53429,53431,53433,53440,53441,53444,53448,53449,53456,53457,53459, -53460,53461,53468,53469,53472,53476,53484,53485,53487,53488,53489,53496,53517, -53552,53553,53556,53560,53562,53568,53569,53571,53572,53573,53580,53581,53584, -53588,53596,53597,53599,53601,53608,53612,53628,53636,53640,53664,53665,53668, -53672,53680,53681,53683,53685,53690,53692,53696,53720,53748,53752,53767,53769, -53776,53804,53805,53808,53812,53820,53821,53823,53825,53832,53852,53860,53888, -53889,53892,53896,53904,53905,53909,53916,53920,53924,53932,53937,53944,53945, -53948,53951,53952,53954,53960,53961,53963,53972,53976,53980,53988,53989,54000, -54001,54004,54008,54016,54017,54019,54021,54028,54029,54030,54032,54036,54038, -54044,54045,54047,54048,54049,54053,54056,54057,54060,54064,54072,54073,54075, -54076,54077,54084,54085,54140,54141,54144,54148,54156,54157,54159,54160,54161, -54168,54169,54172,54176,54184,54185,54187,54189,54196,54200,54204,54212,54213, -54216,54217,54224,54232,54241,54243,54252,54253,54256,54260,54268,54269,54271, -54273,54280,54301,54336,54340,54364,54368,54372,54381,54383,54392,54393,54396, -54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484,54492, -54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549,54551, -54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624,54629, -54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664,54665, -54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756,54757, -54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801,54803, -54804,54805,54812,54816,54820,54829,54840,54841,54844,54848,54853,54856,54857, -54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900,54915, -54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969,54971, -54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024,55029, -55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083,55085, -55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127,55128, -55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169,55176, -55177,55180,55184,55192,55193,55195,55197,20285,20339,20551,20729,21152,21487, -21621,21733,22025,23233,23478,26247,26550,26551,26607,27468,29634,30146,31292, -33499,33540,34903,34952,35382,36040,36303,36603,36838,39381,21051,21364,21508, -24682,24932,27580,29647,33050,35258,35282,38307,20355,21002,22718,22904,23014, -24178,24185,25031,25536,26438,26604,26751,28567,30286,30475,30965,31240,31487, -31777,32925,33390,33393,35563,38291,20075,21917,26359,28212,30883,31469,33883, -35088,34638,38824,21208,22350,22570,23884,24863,25022,25121,25954,26577,27204, -28187,29976,30131,30435,30640,32058,37039,37969,37970,40853,21283,23724,30002, -32987,37440,38296,21083,22536,23004,23713,23831,24247,24378,24394,24951,27743, -30074,30086,31968,32115,32177,32652,33108,33313,34193,35137,35611,37628,38477, -40007,20171,20215,20491,20977,22607,24887,24894,24936,25913,27114,28433,30117, -30342,30422,31623,33445,33995,63744,37799,38283,21888,23458,22353,63745,31923, -32697,37301,20520,21435,23621,24040,25298,25454,25818,25831,28192,28844,31067, -36317,36382,63746,36989,37445,37624,20094,20214,20581,24062,24314,24838,26967, -33137,34388,36423,37749,39467,20062,20625,26480,26688,20745,21133,21138,27298, -30652,37392,40660,21163,24623,36850,20552,25001,25581,25802,26684,27268,28608, -33160,35233,38548,22533,29309,29356,29956,32121,32365,32937,35211,35700,36963, -40273,25225,27770,28500,32080,32570,35363,20860,24906,31645,35609,37463,37772, -20140,20435,20510,20670,20742,21185,21197,21375,22384,22659,24218,24465,24950, -25004,25806,25964,26223,26299,26356,26775,28039,28805,28913,29855,29861,29898, -30169,30828,30956,31455,31478,32069,32147,32789,32831,33051,33686,35686,36629, -36885,37857,38915,38968,39514,39912,20418,21843,22586,22865,23395,23622,24760, -25106,26690,26800,26856,28330,30028,30328,30926,31293,31995,32363,32380,35336, -35489,35903,38542,40388,21476,21481,21578,21617,22266,22993,23396,23611,24235, -25335,25911,25925,25970,26272,26543,27073,27837,30204,30352,30590,31295,32660, -32771,32929,33167,33510,33533,33776,34241,34865,34996,35493,63747,36764,37678, -38599,39015,39640,40723,21741,26011,26354,26767,31296,35895,40288,22256,22372, -23825,26118,26801,26829,28414,29736,34974,39908,27752,63748,39592,20379,20844, -20849,21151,23380,24037,24656,24685,25329,25511,25915,29657,31354,34467,36002, -38799,20018,23521,25096,26524,29916,31185,33747,35463,35506,36328,36942,37707, -38982,24275,27112,34303,37101,63749,20896,23448,23532,24931,26874,27454,28748, -29743,29912,31649,32592,33733,35264,36011,38364,39208,21038,24669,25324,36866, -20362,20809,21281,22745,24291,26336,27960,28826,29378,29654,31568,33009,37979, -21350,25499,32619,20054,20608,22602,22750,24618,24871,25296,27088,39745,23439, -32024,32945,36703,20132,20689,21676,21932,23308,23968,24039,25898,25934,26657, -27211,29409,30350,30703,32094,32761,33184,34126,34527,36611,36686,37066,39171, -39509,39851,19992,20037,20061,20167,20465,20855,21246,21312,21475,21477,21646, -22036,22389,22434,23495,23943,24272,25084,25304,25937,26552,26601,27083,27472, -27590,27628,27714,28317,28792,29399,29590,29699,30655,30697,31350,32127,32777, -33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,37476,37558,39378, -39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,21531,31384,32676, -35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,31406,33422,36524, -20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,21413,29527,34152, -36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,27512,36020,39740, -63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,31998,33909,35215, -36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,27224,20811,21067, -21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,26681,27135,29822, -31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,25810,26129,27278, -29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,21450,24613,25201, -27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,20864,21980,22120, -22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,24190,24524,25216, -26071,26083,26398,26399,26462,26827,26820,27231,27450,27683,27773,27778,28103, -29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,31047,31048,31098, -31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,36215,37665,37668, -39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,26708,37329,21931, -20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,63760,63761,63762, -63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,63771,63772,26262, -63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,26511,26976,28275, -63778,30007,63779,63780,63781,32013,63782,63783,34930,22218,23064,63784,63785, -63786,63787,63788,20035,63789,20839,22856,26608,32784,63790,22899,24180,25754, -31178,24565,24684,25288,25467,23527,23511,21162,63791,22900,24361,24594,63792, -63793,63794,29785,63795,63796,63797,63798,63799,63800,39377,63801,63802,63803, -63804,63805,63806,63807,63808,63809,63810,63811,28611,63812,63813,33215,36786, -24817,63814,63815,33126,63816,63817,23615,63818,63819,63820,63821,63822,63823, -63824,63825,23273,35365,26491,32016,63826,63827,63828,63829,63830,63831,33021, -63832,63833,23612,27877,21311,28346,22810,33590,20025,20150,20294,21934,22296, -22727,24406,26039,26086,27264,27573,28237,30701,31471,31774,32222,34507,34962, -37170,37723,25787,28606,29562,30136,36948,21846,22349,25018,25812,26311,28129, -28251,28525,28601,30192,32835,33213,34113,35203,35527,35674,37663,27795,30035, -31572,36367,36957,21776,22530,22616,24162,25095,25758,26848,30070,31958,34739, -40680,20195,22408,22382,22823,23565,23729,24118,24453,25140,25825,29619,33274, -34955,36024,38538,40667,23429,24503,24755,20498,20992,21040,22294,22581,22615, -23566,23648,23798,23947,24230,24466,24764,25361,25481,25623,26691,26873,27330, -28120,28193,28372,28644,29182,30428,30585,31153,31291,33796,35241,36077,36339, -36424,36867,36884,36947,37117,37709,38518,38876,27602,28678,29272,29346,29544, -30563,31167,31716,32411,35712,22697,24775,25958,26109,26302,27788,28958,29129, -35930,38931,20077,31361,20189,20908,20941,21205,21516,24999,26481,26704,26847, -27934,28540,30140,30643,31461,33012,33891,37509,20828,26007,26460,26515,30168, -31431,33651,63834,35910,36887,38957,23663,33216,33434,36929,36975,37389,24471, -23965,27225,29128,30331,31561,34276,35588,37159,39472,21895,25078,63835,30313, -32645,34367,34746,35064,37007,63836,27931,28889,29662,32097,33853,63837,37226, -39409,63838,20098,21365,27396,27410,28734,29211,34349,40478,21068,36771,23888, -25829,25900,27414,28651,31811,32412,34253,35172,35261,25289,33240,34847,24266, -26391,28010,29436,29701,29807,34690,37086,20358,23821,24480,33802,20919,25504, -30053,20142,20486,20841,20937,26753,27153,31918,31921,31975,33391,35538,36635, -37327,20406,20791,21237,21570,24300,24942,25150,26053,27354,28670,31018,34268, -34851,38317,39522,39530,40599,40654,21147,26310,27511,28701,31019,36706,38722, -24976,25088,25891,28451,29001,29833,32244,32879,34030,36646,36899,37706,20925, -21015,21155,27916,28872,35010,24265,25986,27566,28610,31806,29557,20196,20278, -22265,63839,23738,23994,24604,29618,31533,32666,32718,32838,36894,37428,38646, -38728,38936,40801,20363,28583,31150,37300,38583,21214,63840,25736,25796,27347, -28510,28696,29200,30439,32769,34310,34396,36335,36613,38706,39791,40442,40565, -30860,31103,32160,33737,37636,40575,40595,35542,22751,24324,26407,28711,29903, -31840,32894,20769,28712,29282,30922,36034,36058,36084,38647,20102,20698,23534, -24278,26009,29134,30274,30637,32842,34044,36988,39719,40845,22744,23105,23650, -27155,28122,28431,30267,32047,32311,34078,35128,37860,38475,21129,26066,26611, -27060,27969,28316,28687,29705,29792,30041,30244,30827,35628,39006,20845,25134, -38520,20374,20523,23833,28138,32184,36650,24459,24900,26647,63841,38534,21202, -32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,21519,21774, -23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,31852,32633, -32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,29848,34298, -36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,31435,31520,31890, -25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,33180,33707, -37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,28459,28771, -30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,33545,35178, -38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,36638,37017, -22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,36067,36993, -39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,33804,20906, -35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,40629,28357, -34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,33986,34719, -37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,25721,26286, -26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,33541,35584, -35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,22818,26406, -33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,33495,37672, -21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,28961,29687, -30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,20497,21006, -21563,21839,25991,27766,32010,32011,32862,34442,38272,38639,21247,27797,29289, -21619,23194,23614,23883,24396,24494,26410,26806,26979,28220,28228,30473,31859, -32654,34183,35598,36855,38753,40692,23735,24758,24845,25003,25935,26107,26108, -27665,27887,29599,29641,32225,38292,23494,34588,35600,21085,21338,25293,25615, -25778,26420,27192,27850,29632,29854,31636,31893,32283,33162,33334,34180,36843, -38649,39361,20276,21322,21453,21467,25292,25644,25856,26001,27075,27886,28504, -29677,30036,30242,30436,30460,30928,30971,31020,32070,33324,34784,36820,38930, -39151,21187,25300,25765,28196,28497,30332,36299,37297,37474,39662,39747,20515, -20621,22346,22952,23592,24135,24439,25151,25918,26041,26049,26121,26507,27036, -28354,30917,32033,32938,33152,33323,33459,33953,34444,35370,35607,37030,38450, -40848,20493,20467,63843,22521,24472,25308,25490,26479,28227,28953,30403,32972, -32986,35060,35061,35097,36064,36649,37197,38506,20271,20336,24091,26575,26658, -30333,30334,39748,24161,27146,29033,29140,30058,63844,32321,34115,34281,39132, -20240,31567,32624,38309,20961,24070,26805,27710,27726,27867,29359,31684,33539, -27861,29754,20731,21128,22721,25816,27287,29863,30294,30887,34327,38370,38713, -63845,21342,24321,35722,36776,36783,37002,21029,30629,40009,40712,19993,20482, -20853,23643,24183,26142,26170,26564,26821,28851,29953,30149,31177,31453,36647, -39200,39432,20445,22561,22577,23542,26222,27493,27921,28282,28541,29668,29995, -33769,35036,35091,35676,36628,20239,20693,21264,21340,23443,24489,26381,31119, -33145,33583,34068,35079,35206,36665,36667,39333,39954,26412,20086,20472,22857, -23553,23791,23792,25447,26834,28925,29090,29739,32299,34028,34562,36898,37586, -40179,19981,20184,20463,20613,21078,21103,21542,21648,22496,22827,23142,23386, -23413,23500,24220,63846,25206,25975,26023,28014,28325,29238,31526,31807,32566, -33104,33105,33178,33344,33433,33705,35331,36000,36070,36091,36212,36282,37096, -37340,38428,38468,39385,40167,21271,20998,21545,22132,22707,22868,22894,24575, -24996,25198,26128,27774,28954,30406,31881,31966,32027,33452,36033,38640,63847, -20315,24343,24447,25282,23849,26379,26842,30844,32323,40300,19989,20633,21269, -21290,21329,22915,23138,24199,24754,24970,25161,25209,26000,26503,27047,27604, -27606,27607,27608,27832,63848,29749,30202,30738,30865,31189,31192,31875,32203, -32737,32933,33086,33218,33778,34586,35048,35513,35692,36027,37145,38750,39131, -40763,22188,23338,24428,25996,27315,27567,27996,28657,28693,29277,29613,36007, -36051,38971,24977,27703,32856,39425,20045,20107,20123,20181,20282,20284,20351, -20447,20735,21490,21496,21766,21987,22235,22763,22882,23057,23531,23546,23556, -24051,24107,24473,24605,25448,26012,26031,26614,26619,26797,27515,27801,27863, -28195,28681,29509,30722,31038,31040,31072,31169,31721,32023,32114,32902,33293, -33678,34001,34503,35039,35408,35422,35613,36060,36198,36781,37034,39164,39391, -40605,21066,63849,26388,63850,20632,21034,23665,25955,27733,29642,29987,30109, -31639,33948,37240,38704,20087,25746,27578,29022,34217,19977,63851,26441,26862, -28183,33439,34072,34923,25591,28545,37394,39087,19978,20663,20687,20767,21830, -21930,22039,23360,23577,23776,24120,24202,24224,24258,24819,26705,27233,28248, -29245,29248,29376,30456,31077,31665,32724,35059,35316,35443,35937,36062,38684, -22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,63853,31513, -22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,26329,26360, -26646,26866,29312,29790,31598,32110,32214,32626,32997,33298,34223,35199,35475, -36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,27728,28101, -28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,23459,25159, -25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,32341,32680, -33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,39854,21352, -23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,40807,21089, -26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,22478,22995, -23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,32854,32882, -33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,36016,21484, -22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,27836,28040, -28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,32032,32057, -34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,23660,26463, -28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,39137,29575, -23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,30862,37782, -34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,23744,24101, -24833,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,28465,29159, -29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,32172,32353, -32670,33065,33585,33936,34010,34282,34966,35504,35728,36664,36930,36995,37228, -37526,37561,38539,38567,38568,38614,38656,38920,39318,39635,39706,21460,22654, -22809,23408,23487,28113,28506,29087,29729,29881,32901,33789,24033,24455,24490, -24642,26092,26642,26991,27219,27529,27957,28147,29667,30462,30636,31565,32020, -33059,33308,33600,34036,34147,35426,35524,37255,37662,38918,39348,25100,34899, -36848,37477,23815,23847,23913,29791,33181,34664,28629,25342,32722,35126,35186, -19998,20056,20711,21213,21319,25215,26119,32361,34821,38494,20365,21273,22070, -22987,23204,23608,23630,23629,24066,24337,24643,26045,26159,26178,26558,26612, -29468,30690,31034,32709,33940,33997,35222,35430,35433,35553,35925,35962,22516, -23508,24335,24687,25325,26893,27542,28252,29060,31698,34645,35672,36606,39135, -39166,20280,20353,20449,21627,23072,23480,24892,26032,26216,29180,30003,31070, -32051,33102,33251,33688,34218,34254,34563,35338,36523,36763,63857,36805,22833, -23460,23526,24713,23529,23563,24515,27777,63858,28145,28683,29978,33455,35574, -20160,21313,63859,38617,27663,20126,20420,20818,21854,23077,23784,25105,29273, -33469,33706,34558,34905,35357,38463,38597,39187,40201,40285,22538,23731,23997, -24132,24801,24853,25569,27138,28197,37122,37716,38990,39952,40823,23433,23736, -25353,26191,26696,30524,38593,38797,38996,39839,26017,35585,36555,38332,21813, -23721,24022,24245,26263,30284,33780,38343,22739,25276,29390,40232,20208,22830, -24591,26171,27523,31207,40230,21395,21696,22467,23830,24859,26326,28079,30861, -33406,38552,38724,21380,25212,25494,28082,32266,33099,38989,27387,32588,40367, -40474,20063,20539,20918,22812,24825,25590,26928,29242,32822,63860,37326,24369, -63861,63862,32004,33509,33903,33979,34277,36493,63863,20335,63864,63865,22756, -23363,24665,25562,25880,25965,26264,63866,26954,27171,27915,28673,29036,30162, -30221,31155,31344,63867,32650,63868,35140,63869,35731,37312,38525,63870,39178, -22276,24481,26044,28417,30208,31142,35486,39341,39770,40812,20740,25014,25233, -27277,33222,20547,22576,24422,28937,35328,35578,23420,34326,20474,20796,22196, -22852,25513,28153,23978,26989,20870,20104,20313,63871,63872,63873,22914,63874, -63875,27487,27741,63876,29877,30998,63877,33287,33349,33593,36671,36701,63878, -39192,63879,63880,63881,20134,63882,22495,24441,26131,63883,63884,30123,32377, -35695,63885,36870,39515,22181,22567,23032,23071,23476,63886,24310,63887,63888, -25424,25403,63889,26941,27783,27839,28046,28051,28149,28436,63890,28895,28982, -29017,63891,29123,29141,63892,30799,30831,63893,31605,32227,63894,32303,63895, -34893,36575,63896,63897,63898,37467,63899,40182,63900,63901,63902,24709,28037, -63903,29105,63904,63905,38321,21421,63906,63907,63908,26579,63909,28814,28976, -29744,33398,33490,63910,38331,39653,40573,26308,63911,29121,33865,63912,63913, -22603,63914,63915,23992,24433,63916,26144,26254,27001,27054,27704,27891,28214, -28481,28634,28699,28719,29008,29151,29552,63917,29787,63918,29908,30408,31310, -32403,63919,63920,33521,35424,36814,63921,37704,63922,38681,63923,63924,20034, -20522,63925,21000,21473,26355,27757,28618,29450,30591,31330,33454,34269,34306, -63926,35028,35427,35709,35947,63927,37555,63928,38675,38928,20116,20237,20425, -20658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,63929,25034, -25942,26111,26212,26791,27738,28595,28879,29100,29522,31613,34568,35492,39986, -40711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,34314,20800, -22725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,31401,31402, -33253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,29715,29740, -30871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,26106,26505, -27754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,63930,63931, -20709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,25622,25747, -25854,63934,26332,63935,27208,63936,29183,29796,63937,31368,31407,32327,32350, -32768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,27442,28020, -32287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,24898,27029, -28044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,37780,37854, -63940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,24858,24962, -26100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,34261,34398, -36802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,26671,29020, -31286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,34131,36939, -38549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,22291,22290, -22435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,29232,29503, -29783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,37470,20301, -20553,20702,21361,22285,22996,23041,23561,24944,26256,28205,29234,29771,32239, -32963,33806,33894,34111,34655,34907,35096,35586,36949,38859,39759,20083,20369, -20754,20842,63943,21807,21929,23418,23461,24188,24189,24254,24736,24799,24840, -24841,25540,25912,26377,63944,26580,26586,63945,26977,26978,27833,27943,63946, -28216,63947,28641,29494,29495,63948,29788,30001,63949,30290,63950,63951,32173, -33278,33848,35029,35480,35547,35565,36400,36418,36938,36926,36986,37193,37321, -37742,63952,63953,22537,63954,27603,32905,32946,63955,63956,20801,22891,23609, -63957,63958,28516,29607,32996,36103,63959,37399,38287,63960,63961,63962,63963, -32895,25102,28700,32104,34701,63964,22432,24681,24903,27575,35518,37504,38577, -20057,21535,28139,34093,38512,38899,39150,25558,27875,37009,20957,25033,33210, -40441,20381,20506,20736,23452,24847,25087,25836,26885,27589,30097,30691,32681, -33380,34191,34811,34915,35516,35696,37291,20108,20197,20234,63965,63966,22839, -23016,63967,24050,24347,24411,24609,63968,63969,63970,63971,29246,29669,63972, -30064,30157,63973,31227,63974,32780,32819,32900,33505,33617,63975,63976,36029, -36019,36999,63977,63978,39156,39180,63979,63980,28727,30410,32714,32716,32764, -35610,20154,20161,20995,21360,63981,21693,22240,23035,23493,24341,24525,28270, -63982,63983,32106,33589,63984,34451,35469,63985,38765,38775,63986,63987,19968, -20314,20350,22777,26085,28322,36920,37808,39353,20219,22764,22922,23001,24641, -63988,63989,31252,63990,33615,36035,20837,21316,63991,63992,63993,20173,21097, -23381,33471,20180,21050,21672,22985,23039,23376,23383,23388,24675,24904,28363, -28825,29038,29574,29943,30133,30913,32043,32773,33258,33576,34071,34249,35566, -36039,38604,20316,21242,22204,26027,26152,28796,28856,29237,32189,33421,37196, -38592,40306,23409,26855,27544,28538,30430,23697,26283,28507,31668,31786,34870, -38620,19976,20183,21280,22580,22715,22767,22892,23559,24115,24196,24373,25484, -26290,26454,27167,27299,27404,28479,29254,63994,29520,29835,31456,31911,33144, -33247,33255,33674,33900,34083,34196,34255,35037,36115,37292,38263,38556,20877, -21705,22312,23472,25165,26448,26685,26771,28221,28371,28797,32289,35009,36001, -36617,40779,40782,29229,31631,35533,37658,20295,20302,20786,21632,22992,24213, -25269,26485,26990,27159,27822,28186,29401,29482,30141,31672,32053,33511,33785, -33879,34295,35419,36015,36487,36889,37048,38606,40799,21219,21514,23265,23490, -25688,25973,28404,29380,63995,30340,31309,31515,31821,32318,32735,33659,35627, -36042,36196,36321,36447,36842,36857,36969,37841,20291,20346,20659,20840,20856, -21069,21098,22625,22652,22880,23560,23637,24283,24731,25136,26643,27583,27656, -28593,29006,29728,30000,30008,30033,30322,31564,31627,31661,31686,32399,35438, -36670,36681,37439,37523,37666,37931,38651,39002,39019,39198,20999,25130,25240, -27993,30308,31434,31680,32118,21344,23742,24215,28472,28857,31896,38673,39822, -40670,25509,25722,34678,19969,20117,20141,20572,20597,21576,22979,23450,24128, -24237,24311,24449,24773,25402,25919,25972,26060,26230,26232,26622,26984,27273, -27491,27712,28096,28136,28191,28254,28702,28833,29582,29693,30010,30555,30855, -31118,31243,31357,31934,32142,33351,35330,35562,35998,37165,37194,37336,37478, -37580,37664,38662,38742,38748,38914,40718,21046,21137,21884,22564,24093,24351, -24716,25552,26799,28639,31085,31532,33229,34234,35069,35576,36420,37261,38500, -38555,38717,38988,40778,20430,20806,20939,21161,22066,24340,24427,25514,25805, -26089,26177,26362,26361,26397,26781,26839,27133,28437,28526,29031,29157,29226, -29866,30522,31062,31066,31199,31264,31381,31895,31967,32068,32368,32903,34299, -34468,35412,35519,36249,36481,36896,36973,37347,38459,38613,40165,26063,31751, -36275,37827,23384,23562,21330,25305,29469,20519,23447,24478,24752,24939,26837, -28121,29742,31278,32066,32156,32305,33131,36394,36405,37758,37912,20304,22352, -24038,24231,25387,32618,20027,20303,20367,20570,23005,32964,21610,21608,22014, -22863,23449,24030,24282,26205,26417,26609,26666,27880,27954,28234,28557,28855, -29664,30087,31820,32002,32044,32162,33311,34523,35387,35461,36208,36490,36659, -36913,37198,37202,37956,39376,31481,31909,20426,20737,20934,22472,23535,23803, -26201,27197,27994,28310,28652,28940,30063,31459,34850,36897,36981,38603,39423, -33537,20013,20210,34886,37325,21373,27355,26987,27713,33914,22686,24974,26366, -25327,28893,29969,30151,32338,33976,35657,36104,20043,21482,21675,22320,22336, -24535,25345,25351,25711,25903,26088,26234,26525,26547,27490,27744,27802,28460, -30693,30757,31049,31063,32025,32930,33026,33267,33437,33463,34584,35468,63996, -36100,36286,36978,30452,31257,31287,32340,32887,21767,21972,22645,25391,25634, -26185,26187,26733,27035,27524,27941,28337,29645,29800,29857,30043,30137,30433, -30494,30603,31206,32265,32285,33275,34095,34967,35386,36049,36587,36784,36914, -37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,29894,30142,31209, -31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,28503,32221,36655, -37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,23919,24046,27425, -27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,31364,37679,38015, -40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,32408,35738,36106, -38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,22649,24920,24921, -25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,24288,24432,24884, -25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,33081,33369,33750, -33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,34081,37319,37365, -20874,26613,31574,36012,20932,22971,24765,34389,20508,63999,21076,23610,24957, -25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,20191,21315,21912, -22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,36368,36983,37351, -38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,36639,36685,37941, -20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,22558,22974,24086, -25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,32893,33729,35531, -38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,36958,39636,21021, -21119,21736,24980,25220,25307,26786,26898,26970,27189,28818,28966,30813,30977, -30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,37218,37259,37294, -20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,21474,22618,23541, -24740,24961,25696,32317,32880,34085,37507,25774,20652,23828,26368,22684,25277, -25512,26894,27000,27166,28267,30394,31179,33467,33833,35535,36264,36861,37138, -37195,37276,37648,37656,37786,38619,39478,39949,19985,30044,31069,31482,31569, -31689,32302,33988,36441,36468,36600,36880,26149,26943,29763,20986,26414,40668, -20805,24544,27798,34802,34909,34935,24756,33205,33795,36101,21462,21561,22068, -23094,23601,28810,32736,32858,33030,33261,36259,37257,39519,40434,20596,20164, -21408,24827,28204,23652,20360,20516,21988,23769,24159,24677,26772,27835,28100, -29118,30164,30196,30305,31258,31305,32199,32251,32622,33268,34473,36636,38601, -39347,40786,21063,21189,39149,35242,19971,26578,28422,20405,23522,26517,27784, -28024,29723,30759,37341,37756,34756,31204,31281,24555,20182,21668,21822,22702, -22949,24816,25171,25302,26422,26965,33333,38464,39345,39389,20524,21331,21828, -22396,64001,25176,64002,25826,26219,26589,28609,28655,29730,29752,35351,37944, -21585,22022,22374,24392,24986,27470,28760,28845,32187,35477,22890,33067,25506, -30472,32829,36010,22612,25645,27067,23445,24081,28271,64003,34153,20812,21488, -22826,24608,24907,27526,27760,27888,31518,32974,33492,36294,37040,39089,64004, -25799,28580,25745,25860,20814,21520,22303,35342,24927,26742,64005,30171,31570, -32113,36890,22534,27084,33151,35114,36864,38969,20600,22871,22956,25237,36879, -39722,24925,29305,38358,22369,23110,24052,25226,25773,25850,26487,27874,27966, -29228,29750,30772,32631,33453,36315,38935,21028,22338,26495,29256,29923,36009, -36774,37393,38442,20843,21485,25420,20329,21764,24726,25943,27803,28031,29260, -29437,31255,35207,35997,24429,28558,28921,33192,24846,20415,20559,25153,29255, -31687,32232,32745,36941,38829,39449,36022,22378,24179,26544,33805,35413,21536, -23318,24163,24290,24330,25987,32954,34109,38281,38491,20296,21253,21261,21263, -21638,21754,22275,24067,24598,25243,25265,25429,64006,27873,28006,30129,30770, -32990,33071,33502,33889,33970,34957,35090,36875,37610,39165,39825,24133,26292, -26333,28689,29190,64007,20469,21117,24426,24915,26451,27161,28418,29922,31080, -34920,35961,39111,39108,39491,21697,31263,26963,35575,35914,39080,39342,24444, -25259,30130,30382,34987,36991,38466,21305,24380,24517,27852,29644,30050,30091, -31558,33534,39325,20047,36924,19979,20309,21414,22799,24264,26160,27827,29781, -33655,34662,36032,36944,38686,39957,22737,23416,34384,35604,40372,23506,24680, -24717,26097,27735,28450,28579,28698,32597,32752,38289,38290,38480,38867,21106, -36676,20989,21547,21688,21859,21898,27323,28085,32216,33382,37532,38519,40569, -21512,21704,30418,34532,38308,38356,38492,20130,20233,23022,23270,24055,24658, -25239,26477,26689,27782,28207,32568,32923,33322,64008,64009,38917,20133,20565, -21683,22419,22874,23401,23475,25032,26999,28023,28707,34809,35299,35442,35559, -36994,39405,39608,21182,26680,20502,24184,26447,33607,34892,20139,21521,22190, -29670,37141,38911,39177,39255,39321,22099,22687,34395,35377,25010,27382,29563, -36562,27463,38570,39511,22869,29184,36203,38761,20436,23796,24358,25080,26203, -27883,28843,29572,29625,29694,30505,30541,32067,32098,32291,33335,34898,64010, -36066,37449,39023,23377,31348,34880,38913,23244,20448,21332,22846,23805,25406, -28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,24418,27842, -28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,37026,37795, -39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,20114,21628, -22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,28111,28246, -28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,31946,32286, -32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,39013,24785, -25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,21700,24344, -27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,27194,28779, -30069,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,25899,30906, -30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,26707,28185, -29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,20976,24140, -24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,28514,29004, -29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,24315,24458, -24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,33214,33588, -34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,25928,25989, -26313,26783,28045,28102,29243,32948,37237,39501,20399,20505,21402,21518,21564, -21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,22734,28932, -29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,21913,27585, -24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,30054,34407, -24676,35662,40440,20807,20982,21256,27958,33016,40657,26133,27427,28824,30165, -21507,23673,32007,35350,27424,27453,27462,21560,24688,27965,32725,33288,20694, -20958,21916,22123,22221,23020,23305,24076,24985,24984,25137,26206,26342,29081, -29113,29114,29351,31143,31232,32690,35440, -}; - -static const struct dbcs_index ksx1001_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{__ksx1001_decmap+0,33,126},{__ksx1001_decmap+ -94,33,103},{__ksx1001_decmap+165,33,126},{__ksx1001_decmap+259,33,126},{ -__ksx1001_decmap+353,33,120},{__ksx1001_decmap+441,33,100},{__ksx1001_decmap+ -509,33,111},{__ksx1001_decmap+588,33,126},{__ksx1001_decmap+682,33,126},{ -__ksx1001_decmap+776,33,115},{__ksx1001_decmap+859,33,118},{__ksx1001_decmap+ -945,33,113},{0,0,0},{0,0,0},{0,0,0},{__ksx1001_decmap+1026,33,126},{ -__ksx1001_decmap+1120,33,126},{__ksx1001_decmap+1214,33,126},{__ksx1001_decmap -+1308,33,126},{__ksx1001_decmap+1402,33,126},{__ksx1001_decmap+1496,33,126},{ -__ksx1001_decmap+1590,33,126},{__ksx1001_decmap+1684,33,126},{__ksx1001_decmap -+1778,33,126},{__ksx1001_decmap+1872,33,126},{__ksx1001_decmap+1966,33,126},{ -__ksx1001_decmap+2060,33,126},{__ksx1001_decmap+2154,33,126},{__ksx1001_decmap -+2248,33,126},{__ksx1001_decmap+2342,33,126},{__ksx1001_decmap+2436,33,126},{ -__ksx1001_decmap+2530,33,126},{__ksx1001_decmap+2624,33,126},{__ksx1001_decmap -+2718,33,126},{__ksx1001_decmap+2812,33,126},{__ksx1001_decmap+2906,33,126},{ -__ksx1001_decmap+3000,33,126},{__ksx1001_decmap+3094,33,126},{__ksx1001_decmap -+3188,33,126},{__ksx1001_decmap+3282,33,126},{0,0,0},{__ksx1001_decmap+3376, -33,126},{__ksx1001_decmap+3470,33,126},{__ksx1001_decmap+3564,33,126},{ -__ksx1001_decmap+3658,33,126},{__ksx1001_decmap+3752,33,126},{__ksx1001_decmap -+3846,33,126},{__ksx1001_decmap+3940,33,126},{__ksx1001_decmap+4034,33,126},{ -__ksx1001_decmap+4128,33,126},{__ksx1001_decmap+4222,33,126},{__ksx1001_decmap -+4316,33,126},{__ksx1001_decmap+4410,33,126},{__ksx1001_decmap+4504,33,126},{ -__ksx1001_decmap+4598,33,126},{__ksx1001_decmap+4692,33,126},{__ksx1001_decmap -+4786,33,126},{__ksx1001_decmap+4880,33,126},{__ksx1001_decmap+4974,33,126},{ -__ksx1001_decmap+5068,33,126},{__ksx1001_decmap+5162,33,126},{__ksx1001_decmap -+5256,33,126},{__ksx1001_decmap+5350,33,126},{__ksx1001_decmap+5444,33,126},{ -__ksx1001_decmap+5538,33,126},{__ksx1001_decmap+5632,33,126},{__ksx1001_decmap -+5726,33,126},{__ksx1001_decmap+5820,33,126},{__ksx1001_decmap+5914,33,126},{ -__ksx1001_decmap+6008,33,126},{__ksx1001_decmap+6102,33,126},{__ksx1001_decmap -+6196,33,126},{__ksx1001_decmap+6290,33,126},{__ksx1001_decmap+6384,33,126},{ -__ksx1001_decmap+6478,33,126},{__ksx1001_decmap+6572,33,126},{__ksx1001_decmap -+6666,33,126},{__ksx1001_decmap+6760,33,126},{__ksx1001_decmap+6854,33,126},{ -__ksx1001_decmap+6948,33,126},{__ksx1001_decmap+7042,33,126},{__ksx1001_decmap -+7136,33,126},{__ksx1001_decmap+7230,33,126},{__ksx1001_decmap+7324,33,126},{ -__ksx1001_decmap+7418,33,126},{__ksx1001_decmap+7512,33,126},{__ksx1001_decmap -+7606,33,126},{__ksx1001_decmap+7700,33,126},{__ksx1001_decmap+7794,33,126},{ -__ksx1001_decmap+7888,33,126},{__ksx1001_decmap+7982,33,126},{__ksx1001_decmap -+8076,33,126},{__ksx1001_decmap+8170,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -}, -}; - -static const ucs2_t __cp949ext_decmap[9650] = { -44034,44035,44037,44038,44043,44044,44045,44046,44047,44056,44062,44063,44065, -44066,44067,44069,44070,44071,44072,44073,44074,44075,44078,44082,44083,44084, -U,U,U,U,U,U,44085,44086,44087,44090,44091,44093,44094,44095,44097,44098,44099, -44100,44101,44102,44103,44104,44105,44106,44108,44110,44111,44112,44113,44114, -44115,44117,U,U,U,U,U,U,44118,44119,44121,44122,44123,44125,44126,44127,44128, -44129,44130,44131,44132,44133,44134,44135,44136,44137,44138,44139,44140,44141, -44142,44143,44146,44147,44149,44150,44153,44155,44156,44157,44158,44159,44162, -44167,44168,44173,44174,44175,44177,44178,44179,44181,44182,44183,44184,44185, -44186,44187,44190,44194,44195,44196,44197,44198,44199,44203,44205,44206,44209, -44210,44211,44212,44213,44214,44215,44218,44222,44223,44224,44226,44227,44229, -44230,44231,44233,44234,44235,44237,44238,44239,44240,44241,44242,44243,44244, -44246,44248,44249,44250,44251,44252,44253,44254,44255,44258,44259,44261,44262, -44265,44267,44269,44270,44274,44276,44279,44280,44281,44282,44283,44286,44287, -44289,44290,44291,44293,44295,44296,44297,44298,44299,44302,44304,44306,44307, -44308,44309,44310,44311,44313,44314,44315,44317,44318,44319,44321,44322,44323, -44324,44325,44326,44327,44328,44330,44331,44334,44335,44336,44337,44338,44339, -U,U,U,U,U,U,44342,44343,44345,44346,44347,44349,44350,44351,44352,44353,44354, -44355,44358,44360,44362,44363,44364,44365,44366,44367,44369,44370,44371,44373, -44374,44375,U,U,U,U,U,U,44377,44378,44379,44380,44381,44382,44383,44384,44386, -44388,44389,44390,44391,44392,44393,44394,44395,44398,44399,44401,44402,44407, -44408,44409,44410,44414,44416,44419,44420,44421,44422,44423,44426,44427,44429, -44430,44431,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,44443, -44446,44447,44448,44449,44450,44451,44453,44454,44455,44456,44457,44458,44459, -44460,44461,44462,44463,44464,44465,44466,44467,44468,44469,44470,44472,44473, -44474,44475,44476,44477,44478,44479,44482,44483,44485,44486,44487,44489,44490, -44491,44492,44493,44494,44495,44498,44500,44501,44502,44503,44504,44505,44506, -44507,44509,44510,44511,44513,44514,44515,44517,44518,44519,44520,44521,44522, -44523,44524,44525,44526,44527,44528,44529,44530,44531,44532,44533,44534,44535, -44538,44539,44541,44542,44546,44547,44548,44549,44550,44551,44554,44556,44558, -44559,44560,44561,44562,44563,44565,44566,44567,44568,44569,44570,44571,44572, -U,U,U,U,U,U,44573,44574,44575,44576,44577,44578,44579,44580,44581,44582,44583, -44584,44585,44586,44587,44588,44589,44590,44591,44594,44595,44597,44598,44601, -44603,44604,U,U,U,U,U,U,44605,44606,44607,44610,44612,44615,44616,44617,44619, -44623,44625,44626,44627,44629,44631,44632,44633,44634,44635,44638,44642,44643, -44644,44646,44647,44650,44651,44653,44654,44655,44657,44658,44659,44660,44661, -44662,44663,44666,44670,44671,44672,44673,44674,44675,44678,44679,44680,44681, -44682,44683,44685,44686,44687,44688,44689,44690,44691,44692,44693,44694,44695, -44696,44697,44698,44699,44700,44701,44702,44703,44704,44705,44706,44707,44708, -44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,44719,44720,44721, -44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,44735,44737,44738, -44739,44741,44742,44743,44744,44745,44746,44747,44750,44754,44755,44756,44757, -44758,44759,44762,44763,44765,44766,44767,44768,44769,44770,44771,44772,44773, -44774,44775,44777,44778,44780,44782,44783,44784,44785,44786,44787,44789,44790, -44791,44793,44794,44795,44797,44798,44799,44800,44801,44802,44803,44804,44805, -U,U,U,U,U,U,44806,44809,44810,44811,44812,44814,44815,44817,44818,44819,44820, -44821,44822,44823,44824,44825,44826,44827,44828,44829,44830,44831,44832,44833, -44834,44835,U,U,U,U,U,U,44836,44837,44838,44839,44840,44841,44842,44843,44846, -44847,44849,44851,44853,44854,44855,44856,44857,44858,44859,44862,44864,44868, -44869,44870,44871,44874,44875,44876,44877,44878,44879,44881,44882,44883,44884, -44885,44886,44887,44888,44889,44890,44891,44894,44895,44896,44897,44898,44899, -44902,44903,44904,44905,44906,44907,44908,44909,44910,44911,44912,44913,44914, -44915,44916,44917,44918,44919,44920,44922,44923,44924,44925,44926,44927,44929, -44930,44931,44933,44934,44935,44937,44938,44939,44940,44941,44942,44943,44946, -44947,44948,44950,44951,44952,44953,44954,44955,44957,44958,44959,44960,44961, -44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,44972,44973,44974, -44975,44976,44977,44978,44979,44980,44981,44982,44983,44986,44987,44989,44990, -44991,44993,44994,44995,44996,44997,44998,45002,45004,45007,45008,45009,45010, -45011,45013,45014,45015,45016,45017,45018,45019,45021,45022,45023,45024,45025, -U,U,U,U,U,U,45026,45027,45028,45029,45030,45031,45034,45035,45036,45037,45038, -45039,45042,45043,45045,45046,45047,45049,45050,45051,45052,45053,45054,45055, -45058,45059,U,U,U,U,U,U,45061,45062,45063,45064,45065,45066,45067,45069,45070, -45071,45073,45074,45075,45077,45078,45079,45080,45081,45082,45083,45086,45087, -45088,45089,45090,45091,45092,45093,45094,45095,45097,45098,45099,45100,45101, -45102,45103,45104,45105,45106,45107,45108,45109,45110,45111,45112,45113,45114, -45115,45116,45117,45118,45119,45120,45121,45122,45123,45126,45127,45129,45131, -45133,45135,45136,45137,45138,45142,45144,45146,45147,45148,45150,45151,45152, -45153,45154,45155,45156,45157,45158,45159,45160,45161,45162,45163,45164,45165, -45166,45167,45168,45169,45170,45171,45172,45173,45174,45175,45176,45177,45178, -45179,45182,45183,45185,45186,45187,45189,45190,45191,45192,45193,45194,45195, -45198,45200,45202,45203,45204,45205,45206,45207,45211,45213,45214,45219,45220, -45221,45222,45223,45226,45232,45234,45238,45239,45241,45242,45243,45245,45246, -45247,45248,45249,45250,45251,45254,45258,45259,45260,45261,45262,45263,45266, -U,U,U,U,U,U,45267,45269,45270,45271,45273,45274,45275,45276,45277,45278,45279, -45281,45282,45283,45284,45286,45287,45288,45289,45290,45291,45292,45293,45294, -45295,45296,U,U,U,U,U,U,45297,45298,45299,45300,45301,45302,45303,45304,45305, -45306,45307,45308,45309,45310,45311,45312,45313,45314,45315,45316,45317,45318, -45319,45322,45325,45326,45327,45329,45332,45333,45334,45335,45338,45342,45343, -45344,45345,45346,45350,45351,45353,45354,45355,45357,45358,45359,45360,45361, -45362,45363,45366,45370,45371,45372,45373,45374,45375,45378,45379,45381,45382, -45383,45385,45386,45387,45388,45389,45390,45391,45394,45395,45398,45399,45401, -45402,45403,45405,45406,45407,45409,45410,45411,45412,45413,45414,45415,45416, -45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,45427,45428,45429, -45430,45431,45434,45435,45437,45438,45439,45441,45443,45444,45445,45446,45447, -45450,45452,45454,45455,45456,45457,45461,45462,45463,45465,45466,45467,45469, -45470,45471,45472,45473,45474,45475,45476,45477,45478,45479,45481,45482,45483, -45484,45485,45486,45487,45488,45489,45490,45491,45492,45493,45494,45495,45496, -U,U,U,U,U,U,45497,45498,45499,45500,45501,45502,45503,45504,45505,45506,45507, -45508,45509,45510,45511,45512,45513,45514,45515,45517,45518,45519,45521,45522, -45523,45525,U,U,U,U,U,U,45526,45527,45528,45529,45530,45531,45534,45536,45537, -45538,45539,45540,45541,45542,45543,45546,45547,45549,45550,45551,45553,45554, -45555,45556,45557,45558,45559,45560,45562,45564,45566,45567,45568,45569,45570, -45571,45574,45575,45577,45578,45581,45582,45583,45584,45585,45586,45587,45590, -45592,45594,45595,45596,45597,45598,45599,45601,45602,45603,45604,45605,45606, -45607,45608,45609,45610,45611,45612,45613,45614,45615,45616,45617,45618,45619, -45621,45622,45623,45624,45625,45626,45627,45629,45630,45631,45632,45633,45634, -45635,45636,45637,45638,45639,45640,45641,45642,45643,45644,45645,45646,45647, -45648,45649,45650,45651,45652,45653,45654,45655,45657,45658,45659,45661,45662, -45663,45665,45666,45667,45668,45669,45670,45671,45674,45675,45676,45677,45678, -45679,45680,45681,45682,45683,45686,45687,45688,45689,45690,45691,45693,45694, -45695,45696,45697,45698,45699,45702,45703,45704,45706,45707,45708,45709,45710, -U,U,U,U,U,U,45711,45714,45715,45717,45718,45719,45723,45724,45725,45726,45727, -45730,45732,45735,45736,45737,45739,45741,45742,45743,45745,45746,45747,45749, -45750,45751,U,U,U,U,U,U,45752,45753,45754,45755,45756,45757,45758,45759,45760, -45761,45762,45763,45764,45765,45766,45767,45770,45771,45773,45774,45775,45777, -45779,45780,45781,45782,45783,45786,45788,45790,45791,45792,45793,45795,45799, -45801,45802,45808,45809,45810,45814,45820,45821,45822,45826,45827,45829,45830, -45831,45833,45834,45835,45836,45837,45838,45839,45842,45846,45847,45848,45849, -45850,45851,45853,45854,45855,45856,45857,45858,45859,45860,45861,45862,45863, -45864,45865,45866,45867,45868,45869,45870,45871,45872,45873,45874,45875,45876, -45877,45878,45879,45880,45881,45882,45883,45884,45885,45886,45887,45888,45889, -45890,45891,45892,45893,45894,45895,45896,45897,45898,45899,45900,45901,45902, -45903,45904,45905,45906,45907,45911,45913,45914,45917,45920,45921,45922,45923, -45926,45928,45930,45932,45933,45935,45938,45939,45941,45942,45943,45945,45946, -45947,45948,45949,45950,45951,45954,45958,45959,45960,45961,45962,45963,45965, -U,U,U,U,U,U,45966,45967,45969,45970,45971,45973,45974,45975,45976,45977,45978, -45979,45980,45981,45982,45983,45986,45987,45988,45989,45990,45991,45993,45994, -45995,45997,U,U,U,U,U,U,45998,45999,46000,46001,46002,46003,46004,46005,46006, -46007,46008,46009,46010,46011,46012,46013,46014,46015,46016,46017,46018,46019, -46022,46023,46025,46026,46029,46031,46033,46034,46035,46038,46040,46042,46044, -46046,46047,46049,46050,46051,46053,46054,46055,46057,46058,46059,46060,46061, -46062,46063,46064,46065,46066,46067,46068,46069,46070,46071,46072,46073,46074, -46075,46077,46078,46079,46080,46081,46082,46083,46084,46085,46086,46087,46088, -46089,46090,46091,46092,46093,46094,46095,46097,46098,46099,46100,46101,46102, -46103,46105,46106,46107,46109,46110,46111,46113,46114,46115,46116,46117,46118, -46119,46122,46124,46125,46126,46127,46128,46129,46130,46131,46133,46134,46135, -46136,46137,46138,46139,46140,46141,46142,46143,46144,46145,46146,46147,46148, -46149,46150,46151,46152,46153,46154,46155,46156,46157,46158,46159,46162,46163, -46165,46166,46167,46169,46170,46171,46172,46173,46174,46175,46178,46180,46182, -U,U,U,U,U,U,46183,46184,46185,46186,46187,46189,46190,46191,46192,46193,46194, -46195,46196,46197,46198,46199,46200,46201,46202,46203,46204,46205,46206,46207, -46209,46210,U,U,U,U,U,U,46211,46212,46213,46214,46215,46217,46218,46219,46220, -46221,46222,46223,46224,46225,46226,46227,46228,46229,46230,46231,46232,46233, -46234,46235,46236,46238,46239,46240,46241,46242,46243,46245,46246,46247,46249, -46250,46251,46253,46254,46255,46256,46257,46258,46259,46260,46262,46264,46266, -46267,46268,46269,46270,46271,46273,46274,46275,46277,46278,46279,46281,46282, -46283,46284,46285,46286,46287,46289,46290,46291,46292,46294,46295,46296,46297, -46298,46299,46302,46303,46305,46306,46309,46311,46312,46313,46314,46315,46318, -46320,46322,46323,46324,46325,46326,46327,46329,46330,46331,46332,46333,46334, -46335,46336,46337,46338,46339,46340,46341,46342,46343,46344,46345,46346,46347, -46348,46349,46350,46351,46352,46353,46354,46355,46358,46359,46361,46362,46365, -46366,46367,46368,46369,46370,46371,46374,46379,46380,46381,46382,46383,46386, -46387,46389,46390,46391,46393,46394,46395,46396,46397,46398,46399,46402,46406, -U,U,U,U,U,U,46407,46408,46409,46410,46414,46415,46417,46418,46419,46421,46422, -46423,46424,46425,46426,46427,46430,46434,46435,46436,46437,46438,46439,46440, -46441,46442,U,U,U,U,U,U,46443,46444,46445,46446,46447,46448,46449,46450,46451, -46452,46453,46454,46455,46456,46457,46458,46459,46460,46461,46462,46463,46464, -46465,46466,46467,46468,46469,46470,46471,46472,46473,46474,46475,46476,46477, -46478,46479,46480,46481,46482,46483,46484,46485,46486,46487,46488,46489,46490, -46491,46492,46493,46494,46495,46498,46499,46501,46502,46503,46505,46508,46509, -46510,46511,46514,46518,46519,46520,46521,46522,46526,46527,46529,46530,46531, -46533,46534,46535,46536,46537,46538,46539,46542,46546,46547,46548,46549,46550, -46551,46553,46554,46555,46556,46557,46558,46559,46560,46561,46562,46563,46564, -46565,46566,46567,46568,46569,46570,46571,46573,46574,46575,46576,46577,46578, -46579,46580,46581,46582,46583,46584,46585,46586,46587,46588,46589,46590,46591, -46592,46593,46594,46595,46596,46597,46598,46599,46600,46601,46602,46603,46604, -46605,46606,46607,46610,46611,46613,46614,46615,46617,46618,46619,46620,46621, -U,U,U,U,U,U,46622,46623,46624,46625,46626,46627,46628,46630,46631,46632,46633, -46634,46635,46637,46638,46639,46640,46641,46642,46643,46645,46646,46647,46648, -46649,46650,U,U,U,U,U,U,46651,46652,46653,46654,46655,46656,46657,46658,46659, -46660,46661,46662,46663,46665,46666,46667,46668,46669,46670,46671,46672,46673, -46674,46675,46676,46677,46678,46679,46680,46681,46682,46683,46684,46685,46686, -46687,46688,46689,46690,46691,46693,46694,46695,46697,46698,46699,46700,46701, -46702,46703,46704,46705,46706,46707,46708,46709,46710,46711,46712,46713,46714, -46715,46716,46717,46718,46719,46720,46721,46722,46723,46724,46725,46726,46727, -46728,46729,46730,46731,46732,46733,46734,46735,46736,46737,46738,46739,46740, -46741,46742,46743,46744,46745,46746,46747,46750,46751,46753,46754,46755,46757, -46758,46759,46760,46761,46762,46765,46766,46767,46768,46770,46771,46772,46773, -46774,46775,46776,46777,46778,46779,46780,46781,46782,46783,46784,46785,46786, -46787,46788,46789,46790,46791,46792,46793,46794,46795,46796,46797,46798,46799, -46800,46801,46802,46803,46805,46806,46807,46808,46809,46810,46811,46812,46813, -U,U,U,U,U,U,46814,46815,46816,46817,46818,46819,46820,46821,46822,46823,46824, -46825,46826,46827,46828,46829,46830,46831,46833,46834,46835,46837,46838,46839, -46841,46842,U,U,U,U,U,U,46843,46844,46845,46846,46847,46850,46851,46852,46854, -46855,46856,46857,46858,46859,46860,46861,46862,46863,46864,46865,46866,46867, -46868,46869,46870,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880, -46881,46882,46883,46884,46885,46886,46887,46890,46891,46893,46894,46897,46898, -46899,46900,46901,46902,46903,46906,46908,46909,46910,46911,46912,46913,46914, -46915,46917,46918,46919,46921,46922,46923,46925,46926,46927,46928,46929,46930, -46931,46934,46935,46936,46937,46938,46939,46940,46941,46942,46943,46945,46946, -46947,46949,46950,46951,46953,46954,46955,46956,46957,46958,46959,46962,46964, -46966,46967,46968,46969,46970,46971,46974,46975,46977,46978,46979,46981,46982, -46983,46984,46985,46986,46987,46990,46995,46996,46997,47002,47003,47005,47006, -47007,47009,47010,47011,47012,47013,47014,47015,47018,47022,47023,47024,47025, -47026,47027,47030,47031,47033,47034,47035,47036,47037,47038,47039,47040,47041, -U,U,U,U,U,U,47042,47043,47044,47045,47046,47048,47050,47051,47052,47053,47054, -47055,47056,47057,47058,47059,47060,47061,47062,47063,47064,47065,47066,47067, -47068,47069,U,U,U,U,U,U,47070,47071,47072,47073,47074,47075,47076,47077,47078, -47079,47080,47081,47082,47083,47086,47087,47089,47090,47091,47093,47094,47095, -47096,47097,47098,47099,47102,47106,47107,47108,47109,47110,47114,47115,47117, -47118,47119,47121,47122,47123,47124,47125,47126,47127,47130,47132,47134,47135, -47136,47137,47138,47139,47142,47143,47145,47146,47147,47149,47150,47151,47152, -47153,47154,47155,47158,47162,47163,47164,47165,47166,47167,47169,47170,47171, -47173,47174,47175,47176,47177,47178,47179,47180,47181,47182,47183,47184,47186, -47188,47189,47190,47191,47192,47193,47194,47195,47198,47199,47201,47202,47203, -47205,47206,47207,47208,47209,47210,47211,47214,47216,47218,47219,47220,47221, -47222,47223,47225,47226,47227,47229,47230,47231,47232,47233,47234,47235,47236, -47237,47238,47239,47240,47241,47242,47243,47244,47246,47247,47248,47249,47250, -47251,47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263, -U,U,U,U,U,U,47264,47265,47266,47267,47268,47269,47270,47271,47273,47274,47275, -47276,47277,47278,47279,47281,47282,47283,47285,47286,47287,47289,47290,47291, -47292,47293,U,U,U,U,U,U,47294,47295,47298,47300,47302,47303,47304,47305,47306, -47307,47309,47310,47311,47313,47314,47315,47317,47318,47319,47320,47321,47322, -47323,47324,47326,47328,47330,47331,47332,47333,47334,47335,47338,47339,47341, -47342,47343,47345,47346,47347,47348,47349,47350,47351,47354,47356,47358,47359, -47360,47361,47362,47363,47365,47366,47367,47368,47369,47370,47371,47372,47373, -47374,47375,47376,47377,47378,47379,47380,47381,47382,47383,47385,47386,47387, -47388,47389,47390,47391,47393,47394,47395,47396,47397,47398,47399,47400,47401, -47402,47403,47404,47405,47406,47407,47408,47409,47410,47411,47412,47413,47414, -47415,47416,47417,47418,47419,47422,47423,47425,47426,47427,47429,47430,47431, -47432,47433,47434,47435,47437,47438,47440,47442,47443,47444,47445,47446,47447, -47450,47451,47453,47454,47455,47457,47458,47459,47460,47461,47462,47463,47466, -47468,47470,47471,47472,47473,47474,47475,47478,47479,47481,47482,47483,47485, -U,U,U,U,U,U,47486,47487,47488,47489,47490,47491,47494,47496,47499,47500,47503, -47504,47505,47506,47507,47508,47509,47510,47511,47512,47513,47514,47515,47516, -47517,47518,U,U,U,U,U,U,47519,47520,47521,47522,47523,47524,47525,47526,47527, -47528,47529,47530,47531,47534,47535,47537,47538,47539,47541,47542,47543,47544, -47545,47546,47547,47550,47552,47554,47555,47556,47557,47558,47559,47562,47563, -47565,47571,47572,47573,47574,47575,47578,47580,47583,47584,47586,47590,47591, -47593,47594,47595,47597,47598,47599,47600,47601,47602,47603,47606,47611,47612, -47613,47614,47615,47618,47619,47620,47621,47622,47623,47625,47626,47627,47628, -47629,47630,47631,47632,47633,47634,47635,47636,47638,47639,47640,47641,47642, -47643,47644,47645,47646,47647,47648,47649,47650,47651,47652,47653,47654,47655, -47656,47657,47658,47659,47660,47661,47662,47663,47664,47665,47666,47667,47668, -47669,47670,47671,47674,47675,47677,47678,47679,47681,47683,47684,47685,47686, -47687,47690,47692,47695,47696,47697,47698,47702,47703,47705,47706,47707,47709, -47710,47711,47712,47713,47714,47715,47718,47722,47723,47724,47725,47726,47727, -U,U,U,U,U,U,47730,47731,47733,47734,47735,47737,47738,47739,47740,47741,47742, -47743,47744,47745,47746,47750,47752,47753,47754,47755,47757,47758,47759,47760, -47761,47762,U,U,U,U,U,U,47763,47764,47765,47766,47767,47768,47769,47770,47771, -47772,47773,47774,47775,47776,47777,47778,47779,47780,47781,47782,47783,47786, -47789,47790,47791,47793,47795,47796,47797,47798,47799,47802,47804,47806,47807, -47808,47809,47810,47811,47813,47814,47815,47817,47818,47819,47820,47821,47822, -47823,47824,47825,47826,47827,47828,47829,47830,47831,47834,47835,47836,47837, -47838,47839,47840,47841,47842,47843,47844,47845,47846,47847,47848,47849,47850, -47851,47852,47853,47854,47855,47856,47857,47858,47859,47860,47861,47862,47863, -47864,47865,47866,47867,47869,47870,47871,47873,47874,47875,47877,47878,47879, -47880,47881,47882,47883,47884,47886,47888,47890,47891,47892,47893,47894,47895, -47897,47898,47899,47901,47902,47903,47905,47906,47907,47908,47909,47910,47911, -47912,47914,47916,47917,47918,47919,47920,47921,47922,47923,47927,47929,47930, -47935,47936,47937,47938,47939,47942,47944,47946,47947,47948,47950,47953,47954, -U,U,U,U,U,U,47955,47957,47958,47959,47961,47962,47963,47964,47965,47966,47967, -47968,47970,47972,47973,47974,47975,47976,47977,47978,47979,47981,47982,47983, -47984,47985,U,U,U,U,U,U,47986,47987,47988,47989,47990,47991,47992,47993,47994, -47995,47996,47997,47998,47999,48000,48001,48002,48003,48004,48005,48006,48007, -48009,48010,48011,48013,48014,48015,48017,48018,48019,48020,48021,48022,48023, -48024,48025,48026,48027,48028,48029,48030,48031,48032,48033,48034,48035,48037, -48038,48039,48041,48042,48043,48045,48046,48047,48048,48049,48050,48051,48053, -48054,48056,48057,48058,48059,48060,48061,48062,48063,48065,48066,48067,48069, -48070,48071,48073,48074,48075,48076,48077,48078,48079,48081,48082,48084,48085, -48086,48087,48088,48089,48090,48091,48092,48093,48094,48095,48096,48097,48098, -48099,48100,48101,48102,48103,48104,48105,48106,48107,48108,48109,48110,48111, -48112,48113,48114,48115,48116,48117,48118,48119,48122,48123,48125,48126,48129, -48131,48132,48133,48134,48135,48138,48142,48144,48146,48147,48153,48154,48160, -48161,48162,48163,48166,48168,48170,48171,48172,48174,48175,48178,48179,48181, -U,U,U,U,U,U,48182,48183,48185,48186,48187,48188,48189,48190,48191,48194,48198, -48199,48200,48202,48203,48206,48207,48209,48210,48211,48212,48213,48214,48215, -48216,48217,U,U,U,U,U,U,48218,48219,48220,48222,48223,48224,48225,48226,48227, -48228,48229,48230,48231,48232,48233,48234,48235,48236,48237,48238,48239,48240, -48241,48242,48243,48244,48245,48246,48247,48248,48249,48250,48251,48252,48253, -48254,48255,48256,48257,48258,48259,48262,48263,48265,48266,48269,48271,48272, -48273,48274,48275,48278,48280,48283,48284,48285,48286,48287,48290,48291,48293, -48294,48297,48298,48299,48300,48301,48302,48303,48306,48310,48311,48312,48313, -48314,48315,48318,48319,48321,48322,48323,48325,48326,48327,48328,48329,48330, -48331,48332,48334,48338,48339,48340,48342,48343,48345,48346,48347,48349,48350, -48351,48352,48353,48354,48355,48356,48357,48358,48359,48360,48361,48362,48363, -48364,48365,48366,48367,48368,48369,48370,48371,48375,48377,48378,48379,48381, -48382,48383,48384,48385,48386,48387,48390,48392,48394,48395,48396,48397,48398, -48399,48401,48402,48403,48405,48406,48407,48408,48409,48410,48411,48412,48413, -U,U,U,U,U,U,48414,48415,48416,48417,48418,48419,48421,48422,48423,48424,48425, -48426,48427,48429,48430,48431,48432,48433,48434,48435,48436,48437,48438,48439, -48440,48441,U,U,U,U,U,U,48442,48443,48444,48445,48446,48447,48449,48450,48451, -48452,48453,48454,48455,48458,48459,48461,48462,48463,48465,48466,48467,48468, -48469,48470,48471,48474,48475,48476,48477,48478,48479,48480,48481,48482,48483, -48485,48486,48487,48489,48490,48491,48492,48493,48494,48495,48496,48497,48498, -48499,48500,48501,48502,48503,48504,48505,48506,48507,48508,48509,48510,48511, -48514,48515,48517,48518,48523,48524,48525,48526,48527,48530,48532,48534,48535, -48536,48539,48541,48542,48543,48544,48545,48546,48547,48549,48550,48551,48552, -48553,48554,48555,48556,48557,48558,48559,48561,48562,48563,48564,48565,48566, -48567,48569,48570,48571,48572,48573,48574,48575,48576,48577,48578,48579,48580, -48581,48582,48583,48584,48585,48586,48587,48588,48589,48590,48591,48592,48593, -48594,48595,48598,48599,48601,48602,48603,48605,48606,48607,48608,48609,48610, -48611,48612,48613,48614,48615,48616,48618,48619,48620,48621,48622,48623,48625, -U,U,U,U,U,U,48626,48627,48629,48630,48631,48633,48634,48635,48636,48637,48638, -48639,48641,48642,48644,48646,48647,48648,48649,48650,48651,48654,48655,48657, -48658,48659,U,U,U,U,U,U,48661,48662,48663,48664,48665,48666,48667,48670,48672, -48673,48674,48675,48676,48677,48678,48679,48680,48681,48682,48683,48684,48685, -48686,48687,48688,48689,48690,48691,48692,48693,48694,48695,48696,48697,48698, -48699,48700,48701,48702,48703,48704,48705,48706,48707,48710,48711,48713,48714, -48715,48717,48719,48720,48721,48722,48723,48726,48728,48732,48733,48734,48735, -48738,48739,48741,48742,48743,48745,48747,48748,48749,48750,48751,48754,48758, -48759,48760,48761,48762,48766,48767,48769,48770,48771,48773,48774,48775,48776, -48777,48778,48779,48782,48786,48787,48788,48789,48790,48791,48794,48795,48796, -48797,48798,48799,48800,48801,48802,48803,48804,48805,48806,48807,48809,48810, -48811,48812,48813,48814,48815,48816,48817,48818,48819,48820,48821,48822,48823, -48824,48825,48826,48827,48828,48829,48830,48831,48832,48833,48834,48835,48836, -48837,48838,48839,48840,48841,48842,48843,48844,48845,48846,48847,48850,48851, -U,U,U,U,U,U,48853,48854,48857,48858,48859,48860,48861,48862,48863,48865,48866, -48870,48871,48872,48873,48874,48875,48877,48878,48879,48880,48881,48882,48883, -48884,48885,U,U,U,U,U,U,48886,48887,48888,48889,48890,48891,48892,48893,48894, -48895,48896,48898,48899,48900,48901,48902,48903,48906,48907,48908,48909,48910, -48911,48912,48913,48914,48915,48916,48917,48918,48919,48922,48926,48927,48928, -48929,48930,48931,48932,48933,48934,48935,48936,48937,48938,48939,48940,48941, -48942,48943,48944,48945,48946,48947,48948,48949,48950,48951,48952,48953,48954, -48955,48956,48957,48958,48959,48962,48963,48965,48966,48967,48969,48970,48971, -48972,48973,48974,48975,48978,48979,48980,48982,48983,48984,48985,48986,48987, -48988,48989,48990,48991,48992,48993,48994,48995,48996,48997,48998,48999,49000, -49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,49012,49013, -49014,49015,49016,49017,49018,49019,49020,49021,49022,49023,49024,49025,49026, -49027,49028,49029,49030,49031,49032,49033,49034,49035,49036,49037,49038,49039, -49040,49041,49042,49043,49045,49046,49047,49048,49049,49050,49051,49052,49053, -U,U,U,U,U,U,49054,49055,49056,49057,49058,49059,49060,49061,49062,49063,49064, -49065,49066,49067,49068,49069,49070,49071,49073,49074,49075,49076,49077,49078, -49079,49080,U,U,U,U,U,U,49081,49082,49083,49084,49085,49086,49087,49088,49089, -49090,49091,49092,49094,49095,49096,49097,49098,49099,49102,49103,49105,49106, -49107,49109,49110,49111,49112,49113,49114,49115,49117,49118,49120,49122,49123, -49124,49125,49126,49127,49128,49129,49130,49131,49132,49133,49134,49135,49136, -49137,49138,49139,49140,49141,49142,49143,49144,49145,49146,49147,49148,49149, -49150,49151,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49162, -49163,49164,49165,49166,49167,49168,49169,49170,49171,49172,49173,49174,49175, -49176,49177,49178,49179,49180,49181,49182,49183,49184,49185,49186,49187,49188, -49189,49190,49191,49192,49193,49194,49195,49196,49197,49198,49199,49200,49201, -49202,49203,49204,49205,49206,49207,49208,49209,49210,49211,49213,49214,49215, -49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,49226,49227,49228, -49229,49230,49231,49232,49234,49235,49236,49237,49238,49239,49241,49242,49243, -U,U,U,U,U,U,49245,49246,49247,49249,49250,49251,49252,49253,49254,49255,49258, -49259,49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271, -49272,49273,U,U,U,U,U,U,49274,49275,49276,49277,49278,49279,49280,49281,49282, -49283,49284,49285,49286,49287,49288,49289,49290,49291,49292,49293,49294,49295, -49298,49299,49301,49302,49303,49305,49306,49307,49308,49309,49310,49311,49314, -49316,49318,49319,49320,49321,49322,49323,49326,49329,49330,49335,49336,49337, -49338,49339,49342,49346,49347,49348,49350,49351,49354,49355,49357,49358,49359, -49361,49362,49363,49364,49365,49366,49367,49370,49374,49375,49376,49377,49378, -49379,49382,49383,49385,49386,49387,49389,49390,49391,49392,49393,49394,49395, -49398,49400,49402,49403,49404,49405,49406,49407,49409,49410,49411,49413,49414, -49415,49417,49418,49419,49420,49421,49422,49423,49425,49426,49427,49428,49430, -49431,49432,49433,49434,49435,49441,49442,49445,49448,49449,49450,49451,49454, -49458,49459,49460,49461,49463,49466,49467,49469,49470,49471,49473,49474,49475, -49476,49477,49478,49479,49482,49486,49487,49488,49489,49490,49491,49494,49495, -U,U,U,U,U,U,49497,49498,49499,49501,49502,49503,49504,49505,49506,49507,49510, -49514,49515,49516,49517,49518,49519,49521,49522,49523,49525,49526,49527,49529, -49530,49531,U,U,U,U,U,U,49532,49533,49534,49535,49536,49537,49538,49539,49540, -49542,49543,49544,49545,49546,49547,49551,49553,49554,49555,49557,49559,49560, -49561,49562,49563,49566,49568,49570,49571,49572,49574,49575,49578,49579,49581, -49582,49583,49585,49586,49587,49588,49589,49590,49591,49592,49593,49594,49595, -49596,49598,49599,49600,49601,49602,49603,49605,49606,49607,49609,49610,49611, -49613,49614,49615,49616,49617,49618,49619,49621,49622,49625,49626,49627,49628, -49629,49630,49631,49633,49634,49635,49637,49638,49639,49641,49642,49643,49644, -49645,49646,49647,49650,49652,49653,49654,49655,49656,49657,49658,49659,49662, -49663,49665,49666,49667,49669,49670,49671,49672,49673,49674,49675,49678,49680, -49682,49683,49684,49685,49686,49687,49690,49691,49693,49694,49697,49698,49699, -49700,49701,49702,49703,49706,49708,49710,49712,49715,49717,49718,49719,49720, -49721,49722,49723,49724,49725,49726,49727,49728,49729,49730,49731,49732,49733, -U,U,U,U,U,U,49734,49735,49737,49738,49739,49740,49741,49742,49743,49746,49747, -49749,49750,49751,49753,49754,49755,49756,49757,49758,49759,49761,49762,49763, -49764,49766,U,U,U,U,U,U,49767,49768,49769,49770,49771,49774,49775,49777,49778, -49779,49781,49782,49783,49784,49785,49786,49787,49790,49792,49794,49795,49796, -49797,49798,49799,49802,49803,49804,49805,49806,49807,49809,49810,49811,49812, -49813,49814,49815,49817,49818,49820,49822,49823,49824,49825,49826,49827,49830, -49831,49833,49834,49835,49838,49839,49840,49841,49842,49843,49846,49848,49850, -49851,49852,49853,49854,49855,49856,49857,49858,49859,49860,49861,49862,49863, -49864,49865,49866,49867,49868,49869,49870,49871,49872,49873,49874,49875,49876, -49877,49878,49879,49880,49881,49882,49883,49886,49887,49889,49890,49893,49894, -49895,49896,49897,49898,49902,49904,49906,49907,49908,49909,49911,49914,49917, -49918,49919,49921,49922,49923,49924,49925,49926,49927,49930,49931,49934,49935, -49936,49937,49938,49942,49943,49945,49946,49947,49949,49950,49951,49952,49953, -49954,49955,49958,49959,49962,49963,49964,49965,49966,49967,49968,49969,49970, -U,U,U,U,U,U,49971,49972,49973,49974,49975,49976,49977,49978,49979,49980,49981, -49982,49983,49984,49985,49986,49987,49988,49990,49991,49992,49993,49994,49995, -49996,49997,U,U,U,U,U,U,49998,49999,50000,50001,50002,50003,50004,50005,50006, -50007,50008,50009,50010,50011,50012,50013,50014,50015,50016,50017,50018,50019, -50020,50021,50022,50023,50026,50027,50029,50030,50031,50033,50035,50036,50037, -50038,50039,50042,50043,50046,50047,50048,50049,50050,50051,50053,50054,50055, -50057,50058,50059,50061,50062,50063,50064,50065,50066,50067,50068,50069,50070, -50071,50072,50073,50074,50075,50076,50077,50078,50079,50080,50081,50082,50083, -50084,50085,50086,50087,50088,50089,50090,50091,50092,50093,50094,50095,50096, -50097,50098,50099,50100,50101,50102,50103,50104,50105,50106,50107,50108,50109, -50110,50111,50113,50114,50115,50116,50117,50118,50119,50120,50121,50122,50123, -50124,50125,50126,50127,50128,50129,50130,50131,50132,50133,50134,50135,50138, -50139,50141,50142,50145,50147,50148,50149,50150,50151,50154,50155,50156,50158, -50159,50160,50161,50162,50163,50166,50167,50169,50170,50171,50172,50173,50174, -U,U,U,U,U,U,50175,50176,50177,50178,50179,50180,50181,50182,50183,50185,50186, -50187,50188,50189,50190,50191,50193,50194,50195,50196,50197,50198,50199,50200, -50201,50202,U,U,U,U,U,U,50203,50204,50205,50206,50207,50208,50209,50210,50211, -50213,50214,50215,50216,50217,50218,50219,50221,50222,50223,50225,50226,50227, -50229,50230,50231,50232,50233,50234,50235,50238,50239,50240,50241,50242,50243, -50244,50245,50246,50247,50249,50250,50251,50252,50253,50254,50255,50256,50257, -50258,50259,50260,50261,50262,50263,50264,50265,50266,50267,50268,50269,50270, -50271,50272,50273,50274,50275,50278,50279,50281,50282,50283,50285,50286,50287, -50288,50289,50290,50291,50294,50295,50296,50298,50299,50300,50301,50302,50303, -50305,50306,50307,50308,50309,50310,50311,50312,50313,50314,50315,50316,50317, -50318,50319,50320,50321,50322,50323,50325,50326,50327,50328,50329,50330,50331, -50333,50334,50335,50336,50337,50338,50339,50340,50341,50342,50343,50344,50345, -50346,50347,50348,50349,50350,50351,50352,50353,50354,50355,50356,50357,50358, -50359,50361,50362,50363,50365,50366,50367,50368,50369,50370,50371,50372,50373, -U,U,U,U,U,U,50374,50375,50376,50377,50378,50379,50380,50381,50382,50383,50384, -50385,50386,50387,50388,50389,50390,50391,50392,50393,50394,50395,50396,50397, -50398,50399,U,U,U,U,U,U,50400,50401,50402,50403,50404,50405,50406,50407,50408, -50410,50411,50412,50413,50414,50415,50418,50419,50421,50422,50423,50425,50427, -50428,50429,50430,50434,50435,50436,50437,50438,50439,50440,50441,50442,50443, -50445,50446,50447,50449,50450,50451,50453,50454,50455,50456,50457,50458,50459, -50461,50462,50463,50464,50465,50466,50467,50468,50469,50470,50471,50474,50475, -50477,50478,50479,50481,50482,50483,50484,50485,50486,50487,50490,50492,50494, -50495,50496,50497,50498,50499,50502,50503,50507,50511,50512,50513,50514,50518, -50522,50523,50524,50527,50530,50531,50533,50534,50535,50537,50538,50539,50540, -50541,50542,50543,50546,50550,50551,50552,50553,50554,50555,50558,50559,50561, -50562,50563,50565,50566,50568,50569,50570,50571,50574,50576,50578,50579,50580, -50582,50585,50586,50587,50589,50590,50591,50593,50594,50595,50596,50597,50598, -50599,50600,50602,50603,50604,50605,50606,50607,50608,50609,50610,50611,50614, -U,U,U,U,U,U,50615,50618,50623,50624,50625,50626,50627,50635,50637,50639,50642, -50643,50645,50646,50647,50649,50650,50651,50652,50653,50654,50655,50658,50660, -50662,50663,U,U,U,U,U,U,50664,50665,50666,50667,50671,50673,50674,50675,50677, -50680,50681,50682,50683,50690,50691,50692,50697,50698,50699,50701,50702,50703, -50705,50706,50707,50708,50709,50710,50711,50714,50717,50718,50719,50720,50721, -50722,50723,50726,50727,50729,50730,50731,50735,50737,50738,50742,50744,50746, -50748,50749,50750,50751,50754,50755,50757,50758,50759,50761,50762,50763,50764, -50765,50766,50767,50770,50774,50775,50776,50777,50778,50779,50782,50783,50785, -50786,50787,50788,50789,50790,50791,50792,50793,50794,50795,50797,50798,50800, -50802,50803,50804,50805,50806,50807,50810,50811,50813,50814,50815,50817,50818, -50819,50820,50821,50822,50823,50826,50828,50830,50831,50832,50833,50834,50835, -50838,50839,50841,50842,50843,50845,50846,50847,50848,50849,50850,50851,50854, -50856,50858,50859,50860,50861,50862,50863,50866,50867,50869,50870,50871,50875, -50876,50877,50878,50879,50882,50884,50886,50887,50888,50889,50890,50891,50894, -U,U,U,U,U,U,50895,50897,50898,50899,50901,50902,50903,50904,50905,50906,50907, -50910,50911,50914,50915,50916,50917,50918,50919,50922,50923,50925,50926,50927, -50929,50930,U,U,U,U,U,U,50931,50932,50933,50934,50935,50938,50939,50940,50942, -50943,50944,50945,50946,50947,50950,50951,50953,50954,50955,50957,50958,50959, -50960,50961,50962,50963,50966,50968,50970,50971,50972,50973,50974,50975,50978, -50979,50981,50982,50983,50985,50986,50987,50988,50989,50990,50991,50994,50996, -50998,51000,51001,51002,51003,51006,51007,51009,51010,51011,51013,51014,51015, -51016,51017,51019,51022,51024,51033,51034,51035,51037,51038,51039,51041,51042, -51043,51044,51045,51046,51047,51049,51050,51052,51053,51054,51055,51056,51057, -51058,51059,51062,51063,51065,51066,51067,51071,51072,51073,51074,51078,51083, -51084,51085,51087,51090,51091,51093,51097,51099,51100,51101,51102,51103,51106, -51111,51112,51113,51114,51115,51118,51119,51121,51122,51123,51125,51126,51127, -51128,51129,51130,51131,51134,51138,51139,51140,51141,51142,51143,51146,51147, -51149,51151,51153,51154,51155,51156,51157,51158,51159,51161,51162,51163,51164, -U,U,U,U,U,U,51166,51167,51168,51169,51170,51171,51173,51174,51175,51177,51178, -51179,51181,51182,51183,51184,51185,51186,51187,51188,51189,51190,51191,51192, -51193,51194,U,U,U,U,U,U,51195,51196,51197,51198,51199,51202,51203,51205,51206, -51207,51209,51211,51212,51213,51214,51215,51218,51220,51223,51224,51225,51226, -51227,51230,51231,51233,51234,51235,51237,51238,51239,51240,51241,51242,51243, -51246,51248,51250,51251,51252,51253,51254,51255,51257,51258,51259,51261,51262, -51263,51265,51266,51267,51268,51269,51270,51271,51274,51275,51278,51279,51280, -51281,51282,51283,51285,51286,51287,51288,51289,51290,51291,51292,51293,51294, -51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305,51306,51307, -51308,51309,51310,51311,51314,51315,51317,51318,51319,51321,51323,51324,51325, -51326,51327,51330,51332,51336,51337,51338,51342,51343,51344,51345,51346,51347, -51349,51350,51351,51352,51353,51354,51355,51356,51358,51360,51362,51363,51364, -51365,51366,51367,51369,51370,51371,51372,51373,51374,51375,51376,51377,51378, -51379,51380,51381,51382,51383,51384,51385,51386,51387,51390,51391,51392,51393, -U,U,U,U,U,U,51394,51395,51397,51398,51399,51401,51402,51403,51405,51406,51407, -51408,51409,51410,51411,51414,51416,51418,51419,51420,51421,51422,51423,51426, -51427,51429,U,U,U,U,U,U,51430,51431,51432,51433,51434,51435,51436,51437,51438, -51439,51440,51441,51442,51443,51444,51446,51447,51448,51449,51450,51451,51454, -51455,51457,51458,51459,51463,51464,51465,51466,51467,51470,51472,51474,51475, -51476,51477,51478,51479,51481,51482,51483,51484,51485,51486,51487,51488,51489, -51490,51491,51492,51493,51494,51495,51496,51497,51498,51499,U,U,U,U,U,U,51501, -51502,51503,51504,51505,51506,51507,51509,51510,51511,51512,51513,51514,51515, -51516,51517,51518,51519,51520,51521,51522,51523,51524,51525,51526,51527,U,U,U, -U,U,U,51528,51529,51530,51531,51532,51533,51534,51535,51538,51539,51541,51542, -51543,51545,51546,51547,51548,51549,51550,51551,51554,51556,51557,51558,51559, -51560,51561,51562,51563,51565,51566,51567,51569,51570,51571,51573,51574,51575, -51576,51577,51578,51579,51581,51582,51583,51584,51585,51586,51587,51588,51589, -51590,51591,51594,51595,51597,51598,51599,U,U,U,U,U,U,51601,51602,51603,51604, -51605,51606,51607,51610,51612,51614,51615,51616,51617,51618,51619,51620,51621, -51622,51623,51624,51625,51626,51627,51628,51629,51630,U,U,U,U,U,U,51631,51632, -51633,51634,51635,51636,51637,51638,51639,51640,51641,51642,51643,51644,51645, -51646,51647,51650,51651,51653,51654,51657,51659,51660,51661,51662,51663,51666, -51668,51671,51672,51675,51678,51679,51681,51683,51685,51686,51688,51689,51690, -51691,51694,51698,51699,51700,51701,51702,51703,51706,51707,51709,51710,51711, -51713,51714,51715,51716,U,U,U,U,U,U,51717,51718,51719,51722,51726,51727,51728, -51729,51730,51731,51733,51734,51735,51737,51738,51739,51740,51741,51742,51743, -51744,51745,51746,51747,51748,51749,U,U,U,U,U,U,51750,51751,51752,51754,51755, -51756,51757,51758,51759,51760,51761,51762,51763,51764,51765,51766,51767,51768, -51769,51770,51771,51772,51773,51774,51775,51776,51777,51778,51779,51780,51781, -51782,51783,51784,51785,51786,51787,51790,51791,51793,51794,51795,51797,51798, -51799,51800,51801,51802,51803,51806,51810,51811,51812,51813,51814,51815,51817, -51818,U,U,U,U,U,U,51819,51820,51821,51822,51823,51824,51825,51826,51827,51828, -51829,51830,51831,51832,51833,51834,51835,51836,51838,51839,51840,51841,51842, -51843,51845,51846,U,U,U,U,U,U,51847,51848,51849,51850,51851,51852,51853,51854, -51855,51856,51857,51858,51859,51860,51861,51862,51863,51865,51866,51867,51868, -51869,51870,51871,51872,51873,51874,51875,51876,51877,51878,51879,51880,51881, -51882,51883,51884,51885,51886,51887,51888,51889,51890,51891,51892,51893,51894, -51895,51896,51897,51898,51899,51902,51903,51905,51906,51907,51909,U,U,U,U,U,U, -51910,51911,51912,51913,51914,51915,51918,51920,51922,51924,51925,51926,51927, -51930,51931,51932,51933,51934,51935,51937,51938,51939,51940,51941,51942,51943, -U,U,U,U,U,U,51944,51945,51946,51947,51949,51950,51951,51952,51953,51954,51955, -51957,51958,51959,51960,51961,51962,51963,51964,51965,51966,51967,51968,51969, -51970,51971,51972,51973,51974,51975,51977,51978,51979,51980,51981,51982,51983, -51985,51986,51987,51989,51990,51991,51993,51994,51995,51996,51997,51998,51999, -52002,52003,52004,52005,52006,52007,52008,52009,U,U,U,U,U,U,52010,52011,52012, -52013,52014,52015,52016,52017,52018,52019,52020,52021,52022,52023,52024,52025, -52026,52027,52028,52029,52030,52031,52032,52034,52035,52036,U,U,U,U,U,U,52037, -52038,52039,52042,52043,52045,52046,52047,52049,52050,52051,52052,52053,52054, -52055,52058,52059,52060,52062,52063,52064,52065,52066,52067,52069,52070,52071, -52072,52073,52074,52075,52076,52077,52078,52079,52080,52081,52082,52083,52084, -52085,52086,52087,52090,52091,52092,52093,52094,52095,52096,52097,52098,52099, -52100,52101,52102,52103,52104,U,U,U,U,U,U,52105,52106,52107,52108,52109,52110, -52111,52112,52113,52114,52115,52116,52117,52118,52119,52120,52121,52122,52123, -52125,52126,52127,52128,52129,52130,52131,U,U,U,U,U,U,52132,52133,52134,52135, -52136,52137,52138,52139,52140,52141,52142,52143,52144,52145,52146,52147,52148, -52149,52150,52151,52153,52154,52155,52156,52157,52158,52159,52160,52161,52162, -52163,52164,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174,52175, -52176,52177,52178,52179,52181,52182,52183,52184,52185,52186,52187,52188,52189, -52190,52191,U,U,U,U,U,U,52192,52193,52194,52195,52197,52198,52200,52202,52203, -52204,52205,52206,52207,52208,52209,52210,52211,52212,52213,52214,52215,52216, -52217,52218,52219,52220,U,U,U,U,U,U,52221,52222,52223,52224,52225,52226,52227, -52228,52229,52230,52231,52232,52233,52234,52235,52238,52239,52241,52242,52243, -52245,52246,52247,52248,52249,52250,52251,52254,52255,52256,52259,52260,52261, -52262,52266,52267,52269,52271,52273,52274,52275,52276,52277,52278,52279,52282, -52287,52288,52289,52290,52291,52294,52295,52297,52298,52299,52301,52302,U,U,U, -U,U,U,52303,52304,52305,52306,52307,52310,52314,52315,52316,52317,52318,52319, -52321,52322,52323,52325,52327,52329,52330,52331,52332,52333,52334,52335,52337, -52338,U,U,U,U,U,U,52339,52340,52342,52343,52344,52345,52346,52347,52348,52349, -52350,52351,52352,52353,52354,52355,52356,52357,52358,52359,52360,52361,52362, -52363,52364,52365,52366,52367,52368,52369,52370,52371,52372,52373,52374,52375, -52378,52379,52381,52382,52383,52385,52386,52387,52388,52389,52390,52391,52394, -52398,52399,52400,52401,52402,52403,52406,52407,52409,U,U,U,U,U,U,52410,52411, -52413,52414,52415,52416,52417,52418,52419,52422,52424,52426,52427,52428,52429, -52430,52431,52433,52434,52435,52437,52438,52439,52440,52441,52442,U,U,U,U,U,U, -52443,52444,52445,52446,52447,52448,52449,52450,52451,52453,52454,52455,52456, -52457,52458,52459,52461,52462,52463,52465,52466,52467,52468,52469,52470,52471, -52472,52473,52474,52475,52476,52477,52478,52479,52480,52482,52483,52484,52485, -52486,52487,52490,52491,52493,52494,52495,52497,52498,52499,52500,52501,52502, -52503,52506,52508,52510,52511,52512,U,U,U,U,U,U,52513,52514,52515,52517,52518, -52519,52521,52522,52523,52525,52526,52527,52528,52529,52530,52531,52532,52533, -52534,52535,52536,52538,52539,52540,52541,52542,U,U,U,U,U,U,52543,52544,52545, -52546,52547,52548,52549,52550,52551,52552,52553,52554,52555,52556,52557,52558, -52559,52560,52561,52562,52563,52564,52565,52566,52567,52568,52569,52570,52571, -52573,52574,52575,52577,52578,52579,52581,52582,52583,52584,52585,52586,52587, -52590,52592,52594,52595,52596,52597,52598,52599,52601,52602,52603,52604,52605, -52606,52607,52608,U,U,U,U,U,U,52609,52610,52611,52612,52613,52614,52615,52617, -52618,52619,52620,52621,52622,52623,52624,52625,52626,52627,52630,52631,52633, -52634,52635,52637,52638,52639,U,U,U,U,U,U,52640,52641,52642,52643,52646,52648, -52650,52651,52652,52653,52654,52655,52657,52658,52659,52660,52661,52662,52663, -52664,52665,52666,52667,52668,52669,52670,52671,52672,52673,52674,52675,52677, -52678,52679,52680,52681,52682,52683,52685,52686,52687,52689,52690,52691,52692, -52693,52694,52695,52696,52697,52698,52699,52700,52701,52702,52703,52704,52705, -U,U,U,U,U,U,52706,52707,52708,52709,52710,52711,52713,52714,52715,52717,52718, -52719,52721,52722,52723,52724,52725,52726,52727,52730,52732,52734,52735,52736, -52737,52738,U,U,U,U,U,U,52739,52741,52742,52743,52745,52746,52747,52749,52750, -52751,52752,52753,52754,52755,52757,52758,52759,52760,52762,52763,52764,52765, -52766,52767,52770,52771,52773,52774,52775,52777,52778,52779,52780,52781,52782, -52783,52786,52788,52790,52791,52792,52793,52794,52795,52796,52797,52798,52799, -52800,52801,52802,52803,52804,52805,52806,52807,52808,52809,U,U,U,U,U,U,52810, -52811,52812,52813,52814,52815,52816,52817,52818,52819,52820,52821,52822,52823, -52826,52827,52829,52830,52834,52835,52836,52837,52838,52839,52842,52844,U,U,U, -U,U,U,52846,52847,52848,52849,52850,52851,52854,52855,52857,52858,52859,52861, -52862,52863,52864,52865,52866,52867,52870,52872,52874,52875,52876,52877,52878, -52879,52882,52883,52885,52886,52887,52889,52890,52891,52892,52893,52894,52895, -52898,52902,52903,52904,52905,52906,52907,52910,52911,52912,52913,52914,52915, -52916,52917,52918,52919,52920,52921,52922,U,U,U,U,U,U,52923,52924,52925,52926, -52927,52928,52930,52931,52932,52933,52934,52935,52936,52937,52938,52939,52940, -52941,52942,52943,52944,52945,52946,52947,52948,52949,U,U,U,U,U,U,52950,52951, -52952,52953,52954,52955,52956,52957,52958,52959,52960,52961,52962,52963,52966, -52967,52969,52970,52973,52974,52975,52976,52977,52978,52979,52982,52986,52987, -52988,52989,52990,52991,52994,52995,52997,52998,52999,53001,53002,53003,53004, -53005,53006,53007,53010,53012,53014,53015,53016,53017,53018,53019,53021,53022, -53023,53025,53026,53027,U,U,U,U,U,U,53029,53030,53031,53032,53033,53034,53035, -53038,53042,53043,53044,53045,53046,53047,53049,53050,53051,53052,53053,53054, -53055,53056,53057,53058,53059,53060,U,U,U,U,U,U,53061,53062,53063,53064,53065, -53066,53067,53068,53069,53070,53071,53072,53073,53074,53075,53078,53079,53081, -53082,53083,53085,53086,53087,53088,53089,53090,53091,53094,53096,53098,53099, -53100,53101,53102,53103,53106,53107,53109,53110,53111,53113,53114,53115,53116, -53117,53118,53119,53121,53122,53123,53124,53126,53127,53128,53129,53130,53131, -53133,U,U,U,U,U,U,53134,53135,53136,53137,53138,53139,53140,53141,53142,53143, -53144,53145,53146,53147,53148,53149,53150,53151,53152,53154,53155,53156,53157, -53158,53159,53161,U,U,U,U,U,U,53162,53163,53164,53165,53166,53167,53169,53170, -53171,53172,53173,53174,53175,53176,53177,53178,53179,53180,53181,53182,53183, -53184,53185,53186,53187,53189,53190,53191,53192,53193,53194,53195,53196,53197, -53198,53199,53200,53201,53202,53203,53204,53205,53206,53207,53208,53209,53210, -53211,53212,53213,53214,53215,53218,53219,53221,53222,53223,53225,U,U,U,U,U,U, -53226,53227,53228,53229,53230,53231,53234,53236,53238,53239,53240,53241,53242, -53243,53245,53246,53247,53249,53250,53251,53253,53254,53255,53256,53257,53258, -U,U,U,U,U,U,53259,53260,53261,53262,53263,53264,53266,53267,53268,53269,53270, -53271,53273,53274,53275,53276,53277,53278,53279,53280,53281,53282,53283,53284, -53285,53286,53287,53288,53289,53290,53291,53292,53294,53295,53296,53297,53298, -53299,53302,53303,53305,53306,53307,53309,53310,53311,53312,53313,53314,53315, -53318,53320,53322,53323,53324,53325,53326,53327,U,U,U,U,U,U,53329,53330,53331, -53333,53334,53335,53337,53338,53339,53340,53341,53342,53343,53345,53346,53347, -53348,53349,53350,53351,53352,53353,53354,53355,53358,53359,U,U,U,U,U,U,53361, -53362,53363,53365,53366,53367,53368,53369,53370,53371,53374,53375,53376,53378, -53379,53380,53381,53382,53383,53384,53385,53386,53387,53388,53389,53390,53391, -53392,53393,53394,53395,53396,53397,53398,53399,53400,53401,53402,53403,53404, -53405,53406,53407,53408,53409,53410,53411,53414,53415,53417,53418,53419,53421, -53422,53423,53424,53425,53426,U,U,U,U,U,U,53427,53430,53432,53434,53435,53436, -53437,53438,53439,53442,53443,53445,53446,53447,53450,53451,53452,53453,53454, -53455,53458,53462,53463,53464,53465,53466,U,U,U,U,U,U,53467,53470,53471,53473, -53474,53475,53477,53478,53479,53480,53481,53482,53483,53486,53490,53491,53492, -53493,53494,53495,53497,53498,53499,53500,53501,53502,53503,53504,53505,53506, -53507,53508,53509,53510,53511,53512,53513,53514,53515,53516,53518,53519,53520, -53521,53522,53523,53524,53525,53526,53527,53528,53529,53530,53531,53532,53533, -53534,53535,U,U,U,U,U,U,53536,53537,53538,53539,53540,53541,53542,53543,53544, -53545,53546,53547,53548,53549,53550,53551,53554,53555,53557,53558,53559,53561, -53563,53564,53565,53566,U,U,U,U,U,U,53567,53570,53574,53575,53576,53577,53578, -53579,53582,53583,53585,53586,53587,53589,53590,53591,53592,53593,53594,53595, -53598,53600,53602,53603,53604,53605,53606,53607,53609,53610,53611,53613,53614, -53615,53616,53617,53618,53619,53620,53621,53622,53623,53624,53625,53626,53627, -53629,53630,53631,53632,53633,53634,53635,53637,53638,53639,53641,53642,U,U,U, -U,U,U,53643,53644,53645,53646,53647,53648,53649,53650,53651,53652,53653,53654, -53655,53656,53657,53658,53659,53660,53661,53662,53663,53666,53667,53669,53670, -53671,U,U,U,U,U,U,53673,53674,53675,53676,53677,53678,53679,53682,53684,53686, -53687,53688,53689,53691,53693,53694,53695,53697,53698,53699,53700,53701,53702, -53703,53704,53705,53706,53707,53708,53709,53710,53711,53712,53713,53714,53715, -53716,53717,53718,53719,53721,53722,53723,53724,53725,53726,53727,53728,53729, -53730,53731,53732,53733,53734,53735,53736,53737,53738,U,U,U,U,U,U,53739,53740, -53741,53742,53743,53744,53745,53746,53747,53749,53750,53751,53753,53754,53755, -53756,53757,53758,53759,53760,53761,53762,53763,53764,53765,53766,U,U,U,U,U,U, -53768,53770,53771,53772,53773,53774,53775,53777,53778,53779,53780,53781,53782, -53783,53784,53785,53786,53787,53788,53789,53790,53791,53792,53793,53794,53795, -53796,53797,53798,53799,53800,53801,53802,53803,53806,53807,53809,53810,53811, -53813,53814,53815,53816,53817,53818,53819,53822,53824,53826,53827,53828,53829, -53830,53831,53833,53834,53835,53836,U,U,U,U,U,U,53837,53838,53839,53840,53841, -53842,53843,53844,53845,53846,53847,53848,53849,53850,53851,53853,53854,53855, -53856,53857,53858,53859,53861,53862,53863,53864,U,U,U,U,U,U,53865,53866,53867, -53868,53869,53870,53871,53872,53873,53874,53875,53876,53877,53878,53879,53880, -53881,53882,53883,53884,53885,53886,53887,53890,53891,53893,53894,53895,53897, -53898,53899,53900,53901,53902,53903,53906,53907,53908,53910,53911,53912,53913, -53914,53915,53917,53918,53919,53921,53922,53923,53925,53926,53927,53928,53929, -53930,53931,53933,U,U,U,U,U,U,53934,53935,53936,53938,53939,53940,53941,53942, -53943,53946,53947,53949,53950,53953,53955,53956,53957,53958,53959,53962,53964, -53965,53966,53967,53968,53969,U,U,U,U,U,U,53970,53971,53973,53974,53975,53977, -53978,53979,53981,53982,53983,53984,53985,53986,53987,53990,53991,53992,53993, -53994,53995,53996,53997,53998,53999,54002,54003,54005,54006,54007,54009,54010, -54011,54012,54013,54014,54015,54018,54020,54022,54023,54024,54025,54026,54027, -54031,54033,54034,54035,54037,54039,54040,54041,54042,54043,54046,54050,54051, -U,U,U,U,U,U,54052,54054,54055,54058,54059,54061,54062,54063,54065,54066,54067, -54068,54069,54070,54071,54074,54078,54079,54080,54081,54082,54083,54086,54087, -54088,54089,U,U,U,U,U,U,54090,54091,54092,54093,54094,54095,54096,54097,54098, -54099,54100,54101,54102,54103,54104,54105,54106,54107,54108,54109,54110,54111, -54112,54113,54114,54115,54116,54117,54118,54119,54120,54121,54122,54123,54124, -54125,54126,54127,54128,54129,54130,54131,54132,54133,54134,54135,54136,54137, -54138,54139,54142,54143,54145,54146,54147,54149,54150,54151,U,U,U,U,U,U,54152, -54153,54154,54155,54158,54162,54163,54164,54165,54166,54167,54170,54171,54173, -54174,54175,54177,54178,54179,54180,54181,54182,54183,54186,54188,54190,U,U,U, -U,U,U,54191,54192,54193,54194,54195,54197,54198,54199,54201,54202,54203,54205, -54206,54207,54208,54209,54210,54211,54214,54215,54218,54219,54220,54221,54222, -54223,54225,54226,54227,54228,54229,54230,54231,54233,54234,54235,54236,54237, -54238,54239,54240,54242,54244,54245,54246,54247,54248,54249,54250,54251,54254, -54255,54257,54258,54259,54261,54262,54263,U,U,U,U,U,U,54264,54265,54266,54267, -54270,54272,54274,54275,54276,54277,54278,54279,54281,54282,54283,54284,54285, -54286,54287,54288,54289,54290,54291,54292,54293,54294,U,U,U,U,U,U,54295,54296, -54297,54298,54299,54300,54302,54303,54304,54305,54306,54307,54308,54309,54310, -54311,54312,54313,54314,54315,54316,54317,54318,54319,54320,54321,54322,54323, -54324,54325,54326,54327,54328,54329,54330,54331,54332,54333,54334,54335,54337, -54338,54339,54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351, -54352,54353,54354,54355,U,U,U,U,U,U,54356,54357,54358,54359,54360,54361,54362, -54363,54365,54366,54367,54369,54370,54371,54373,54374,54375,54376,54377,54378, -54379,54380,54382,54384,54385,54386,U,U,U,U,U,U,54387,54388,54389,54390,54391, -54394,54395,54397,54398,54401,54403,54404,54405,54406,54407,54410,54412,54414, -54415,54416,54417,54418,54419,54421,54422,54423,54424,54425,54426,54427,54428, -54429,54430,54431,54432,54433,54434,54435,54436,54437,54438,54439,54440,54442, -54443,54444,54445,54446,54447,54448,54449,54450,54451,54452,54453,54454,54455, -54456,U,U,U,U,U,U,54457,54458,54459,54460,54461,54462,54463,54464,54465,54466, -54467,54468,54469,54470,54471,54472,54473,54474,54475,54477,54478,54479,54481, -54482,54483,54485,U,U,U,U,U,U,54486,54487,54488,54489,54490,54491,54493,54494, -54496,54497,54498,54499,54500,54501,54502,54503,54505,54506,54507,54509,54510, -54511,54513,54514,54515,54516,54517,54518,54519,54521,54522,54524,54526,54527, -54528,54529,54530,54531,54533,54534,54535,54537,54538,54539,54541,54542,54543, -54544,54545,54546,54547,54550,54552,54553,54554,54555,54556,54557,U,U,U,U,U,U, -54558,54559,54560,54561,54562,54563,54564,54565,54566,54567,54568,54569,54570, -54571,54572,54573,54574,54575,54576,54577,54578,54579,54580,54581,54582,54583, -U,U,U,U,U,U,54584,54585,54586,54587,54590,54591,54593,54594,54595,54597,54598, -54599,54600,54601,54602,54603,54606,54608,54610,54611,54612,54613,54614,54615, -54618,54619,54621,54622,54623,54625,54626,54627,54628,54630,54631,54634,54636, -54638,54639,54640,54641,54642,54643,54646,54647,54649,54650,54651,54653,54654, -54655,54656,54657,54658,54659,54662,54666,54667,U,U,U,U,U,U,54668,54669,54670, -54671,54673,54674,54675,54676,54677,54678,54679,54680,54681,54682,54683,54684, -54685,54686,54687,54688,54689,54690,54691,54692,54694,54695,U,U,U,U,U,U,54696, -54697,54698,54699,54700,54701,54702,54703,54704,54705,54706,54707,54708,54709, -54710,54711,54712,54713,54714,54715,54716,54717,54718,54719,54720,54721,54722, -54723,54724,54725,54726,54727,54730,54731,54733,54734,54735,54737,54739,54740, -54741,54742,54743,54746,54748,54750,54751,54752,54753,54754,54755,54758,54759, -54761,54762,54763,54765,54766,U,U,U,U,U,U,54767,54768,54769,54770,54771,54774, -54776,54778,54779,54780,54781,54782,54783,54786,54787,54789,54790,54791,54793, -54794,54795,54796,54797,54798,54799,54802,U,U,U,U,U,U,54806,54807,54808,54809, -54810,54811,54813,54814,54815,54817,54818,54819,54821,54822,54823,54824,54825, -54826,54827,54828,54830,54831,54832,54833,54834,54835,54836,54837,54838,54839, -54842,54843,54845,54846,54847,54849,54850,54851,54852,54854,54855,54858,54860, -54862,54863,54864,54866,54867,54870,54871,54873,54874,54875,54877,54878,54879, -54880,54881,U,U,U,U,U,U,54882,54883,54884,54885,54886,54888,54890,54891,54892, -54893,54894,54895,54898,54899,54901,54902,54903,54904,54905,54906,54907,54908, -54909,54910,54911,54912,U,U,U,U,U,U,54913,54914,54916,54918,54919,54920,54921, -54922,54923,54926,54927,54929,54930,54931,54933,54934,54935,54936,54937,54938, -54939,54940,54942,54944,54946,54947,54948,54949,54950,54951,54953,54954,54955, -54957,54958,54959,54961,54962,54963,54964,54965,54966,54967,54968,54970,54972, -54973,54974,54975,54976,54977,54978,54979,54982,54983,54985,54986,54987,U,U,U, -U,U,U,54989,54990,54991,54992,54994,54995,54997,54998,55000,55002,55003,55004, -55005,55006,55007,55009,55010,55011,55013,55014,55015,55017,55018,55019,55020, -55021,U,U,U,U,U,U,55022,55023,55025,55026,55027,55028,55030,55031,55032,55033, -55034,55035,55038,55039,55041,55042,55043,55045,55046,55047,55048,55049,55050, -55051,55052,55053,55054,55055,55056,55058,55059,55060,55061,55062,55063,55066, -55067,55069,55070,55071,55073,55074,55075,55076,55077,55078,55079,55082,55084, -55086,55087,55088,55089,55090,55091,55094,55095,55097,U,U,U,U,U,U,55098,55099, -55101,55102,55103,55104,55105,55106,55107,55109,55110,55112,55114,55115,55116, -55117,55118,55119,55122,55123,55125,55130,55131,55132,55133,55134,U,U,U,U,U,U, -55135,55138,55140,55142,55143,55144,55146,55147,55149,55150,55151,55153,55154, -55155,55157,55158,55159,55160,55161,55162,55163,55166,55167,55168,55170,55171, -55172,55173,55174,55175,55178,55179,55181,55182,55183,55185,55186,55187,55188, -55189,55190,55191,55194,55196,55198,55199,55200,55201,55202,55203, -}; - -static const struct dbcs_index cp949ext_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{__cp949ext_decmap+0,65,254},{__cp949ext_decmap+190, -65,254},{__cp949ext_decmap+380,65,254},{__cp949ext_decmap+570,65,254},{ -__cp949ext_decmap+760,65,254},{__cp949ext_decmap+950,65,254},{ -__cp949ext_decmap+1140,65,254},{__cp949ext_decmap+1330,65,254},{ -__cp949ext_decmap+1520,65,254},{__cp949ext_decmap+1710,65,254},{ -__cp949ext_decmap+1900,65,254},{__cp949ext_decmap+2090,65,254},{ -__cp949ext_decmap+2280,65,254},{__cp949ext_decmap+2470,65,254},{ -__cp949ext_decmap+2660,65,254},{__cp949ext_decmap+2850,65,254},{ -__cp949ext_decmap+3040,65,254},{__cp949ext_decmap+3230,65,254},{ -__cp949ext_decmap+3420,65,254},{__cp949ext_decmap+3610,65,254},{ -__cp949ext_decmap+3800,65,254},{__cp949ext_decmap+3990,65,254},{ -__cp949ext_decmap+4180,65,254},{__cp949ext_decmap+4370,65,254},{ -__cp949ext_decmap+4560,65,254},{__cp949ext_decmap+4750,65,254},{ -__cp949ext_decmap+4940,65,254},{__cp949ext_decmap+5130,65,254},{ -__cp949ext_decmap+5320,65,254},{__cp949ext_decmap+5510,65,254},{ -__cp949ext_decmap+5700,65,254},{__cp949ext_decmap+5890,65,254},{ -__cp949ext_decmap+6080,65,160},{__cp949ext_decmap+6176,65,160},{ -__cp949ext_decmap+6272,65,160},{__cp949ext_decmap+6368,65,160},{ -__cp949ext_decmap+6464,65,160},{__cp949ext_decmap+6560,65,160},{ -__cp949ext_decmap+6656,65,160},{__cp949ext_decmap+6752,65,160},{ -__cp949ext_decmap+6848,65,160},{__cp949ext_decmap+6944,65,160},{ -__cp949ext_decmap+7040,65,160},{__cp949ext_decmap+7136,65,160},{ -__cp949ext_decmap+7232,65,160},{__cp949ext_decmap+7328,65,160},{ -__cp949ext_decmap+7424,65,160},{__cp949ext_decmap+7520,65,160},{ -__cp949ext_decmap+7616,65,160},{__cp949ext_decmap+7712,65,160},{ -__cp949ext_decmap+7808,65,160},{__cp949ext_decmap+7904,65,160},{ -__cp949ext_decmap+8000,65,160},{__cp949ext_decmap+8096,65,160},{ -__cp949ext_decmap+8192,65,160},{__cp949ext_decmap+8288,65,160},{ -__cp949ext_decmap+8384,65,160},{__cp949ext_decmap+8480,65,160},{ -__cp949ext_decmap+8576,65,160},{__cp949ext_decmap+8672,65,160},{ -__cp949ext_decmap+8768,65,160},{__cp949ext_decmap+8864,65,160},{ -__cp949ext_decmap+8960,65,160},{__cp949ext_decmap+9056,65,160},{ -__cp949ext_decmap+9152,65,160},{__cp949ext_decmap+9248,65,160},{ -__cp949ext_decmap+9344,65,160},{__cp949ext_decmap+9440,65,160},{ -__cp949ext_decmap+9536,65,160},{__cp949ext_decmap+9632,65,82},{0,0,0},{0,0,0}, -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const DBCHAR __cp949_encmap[33133] = { -8750,N,N,8756,N,N,8535,8487,N,10275,N,N,8489,8807,N,8518,8510,10615,10616, -8741,N,8786,8484,8748,10614,10284,N,10361,10358,10362,8751,N,N,N,N,N,N,10273, -N,N,N,N,N,N,N,N,N,10274,N,N,N,N,N,N,8511,10282,N,N,N,N,N,10285,10540,N,N,N,N, -N,N,10529,N,N,N,N,N,N,N,N,N,10531,N,N,N,N,N,N,8512,10538,N,N,N,N,N,10541, -10530,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10276,10532,N,N,N,N,N,N,N,N,N, -10533,10278,10534,N,N,N,N,10535,N,N,N,N,N,N,10280,10536,10281,10537,N,N,N,N,N, -N,10544,10287,10543,N,N,N,N,N,N,10283,10539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,10286,10542,8743,N,N,N,N,N,N,N,N,8752,N,N,N,N,N,N,N,8744,8747,8746,8749,N, -8745,9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550, -9551,9552,9553,N,9554,9555,9556,9557,9558,9559,9560,N,N,N,N,N,N,N,9569,9570, -9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,N, -9586,9587,9588,9589,9590,9591,9592,11303,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11297, -11298,11299,11300,11301,11302,11304,11305,11306,11307,11308,11309,11310,11311, -11312,11313,11314,11315,11316,11317,11318,11319,11320,11321,11322,11323,11324, -11325,11326,11327,11328,11329,11345,11346,11347,11348,11349,11350,11352,11353, -11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365,11366, -11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,N,11351, -8490,N,N,8494,8495,N,N,8496,8497,N,N,8787,8788,N,N,N,8485,8486,N,N,N,N,N,N,N, -N,N,8758,N,8519,8520,N,N,N,N,N,N,N,8536,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -10617,N,N,N,N,N,N,N,N,N,N,10618,N,10619,10620,10621,10622,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8806,8521,N,N,N,N,N, -8757,N,N,N,N,N,N,N,N,N,10020,N,N,8800,N,N,N,N,N,N,N,N,N,N,8805,8802,N,N,N, -10073,N,N,N,N,8522,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,10359,10360,N,N,N,N,N,N,10363,10364,10365,10366,N,9520, -9521,9522,9523,9524,9525,9526,9527,9528,9529,N,N,N,N,N,N,9505,9506,9507,9508, -9509,9510,9511,9512,9513,9514,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -8551,8552,8550,8553,8554,8789,8792,8790,8793,8791,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,8737,N,8738,8739,N,8531,8740,N,N,N,8532,8564,N,N,8565,N,N,N,8755,N,8754, -N,N,N,N,N,N,N,N,8558,N,N,8560,8516,N,8528,N,N,N,N,8491,N,8572,8573,8571,8570, -8562,8563,N,8753,N,N,N,N,N,8517,8561,N,N,N,N,N,N,8493,8559,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,8534,N,N,N,N,N,N,N,N,N,N,N,N,N,8513,8533,N,N,8514,8515, -N,N,N,N,8556,8557,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8568,8569,N,N, -8566,8567,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8769,N,N,N,N,N,N,N,N,N,N,N,8529, -8530,10343,10344,10345,10346,10347,10348,10349,10350,10351,10352,10353,10354, -10355,10356,10357,N,N,N,N,N,10599,10600,10601,10602,10603,10604,10605,10606, -10607,10608,10609,10610,10611,10612,10613,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582, -10583,10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595, -10596,10597,10598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10317, -10318,10319,10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330, -10331,10332,10333,10334,10335,10336,10337,10338,10339,10340,10341,10342,9761, -9772,9762,9773,N,N,N,N,N,N,N,N,9763,9800,9799,9774,9764,9794,9793,9775,9766, -9798,9797,9777,9765,9796,9795,9776,9767,9788,9801,9802,9783,9803,9804,9778, -9769,9790,9805,9806,9785,9807,9808,9780,9768,9809,9810,9784,9789,9811,9812, -9779,9770,9813,9814,9786,9791,9815,9816,9781,9771,9817,9818,9787,9819,9820, -9792,9821,9822,9823,9824,9825,9826,9827,9828,9782,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8774,N,N,N,N,N,N,N,N,N,N,N,N,N,8545,8544,N, -8771,8775,8776,8779,8778,8777,8780,N,N,N,N,N,N,N,N,8547,8546,N,N,8762,8761,N, -N,N,N,8549,8548,N,N,8760,8759,N,N,N,N,8543,8542,8770,N,N,8539,N,N,8541,8540, -8772,8773,8538,8537,N,N,N,N,N,N,N,8783,8782,N,N,N,N,N,N,N,N,N,N,N,N,8784,N, -8785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8527,N, -8526,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8764,8765,N, -8768,8763,8766,N,8767,8781,8795,8796,N,8797,8794,8481,8482,8483,8488,N,N,N,N, -8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,N,8555,8498,8499,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796,10797, -10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810, -10811,10812,10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823, -10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,10836, -10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847,10848,10849, -10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860,10861,10862, -10863,10864,10865,10866,10867,N,N,N,N,N,N,N,N,N,N,N,N,N,11041,11042,11043, -11044,11045,11046,11047,11048,11049,11050,11051,11052,11053,11054,11055,11056, -11057,11058,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069, -11070,11071,11072,11073,11074,11075,11076,11077,11078,11079,11080,11081,11082, -11083,11084,11085,11086,11087,11088,11089,11090,11091,11092,11093,11094,11095, -11096,11097,11098,11099,11100,11101,11102,11103,11104,11105,11106,11107,11108, -11109,11110,11111,11112,11113,11114,11115,11116,11117,11118,11119,11120,11121, -11122,11123,11124,11125,11126,9249,9250,9251,9252,9253,9254,9255,9256,9257, -9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272, -9273,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287, -9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302, -9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317, -9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332, -9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,10545,10546,10547,10548, -10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,10559,10560,10561, -10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,10572,8799,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10289,10290,10291,10292, -10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303,10304,10305, -10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,N,N,N,8798, -10057,10058,10059,10060,10061,N,N,N,10042,10043,10076,10077,10078,10038,10039, -10040,10068,10069,10070,10071,10072,10017,10018,10019,10021,10027,10028,10029, -10030,10031,10032,10033,10034,10035,10036,10023,10024,10025,10026,10045,10046, -10085,10086,10087,10088,10081,10082,10083,10047,10048,10049,10050,10051,10052, -10053,10054,10055,10056,10062,10063,10064,10065,10066,10067,10074,10075,8803, -10092,10022,10080,10095,8801,10044,10093,10037,N,N,N,N,10041,10090,N,N,10091, -N,N,10079,N,8804,N,N,10084,10094,10089,27753,28491,N,30290,N,N,N,22578,27995, -24370,24382,31035,N,23668,N,N,N,30052,N,N,29478,23904,24870,N,20088,23600,N,N, -N,N,25386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29033,N,N,N,N,19834,N,N,N,N,N,31791, -21281,N,28971,N,N,N,N,N,N,26449,21036,N,20089,N,N,N,N,N,29053,N,24127,31546, -31033,N,N,N,N,N,N,20050,N,25387,27488,N,N,N,20090,19319,25893,N,N,N,N,N,N,N,N, -N,N,N,19041,N,21580,N,N,N,N,N,27233,N,N,23651,24365,N,N,N,N,N,N,19307,N,N,N, -21807,N,N,N,22133,N,25976,N,N,24128,27683,N,26957,N,27175,26998,31547,N,26473, -28492,N,N,20582,N,N,24129,N,N,25644,N,N,22604,31089,N,20063,31268,26162,N, -31355,N,N,31293,19528,28493,21845,N,N,N,N,N,N,N,21282,N,N,N,27729,N,N,N,N,N, -25639,27730,N,N,30257,N,N,20091,N,N,20561,19263,N,27940,N,N,N,N,N,N,27944, -24130,30306,27996,23669,24633,N,N,N,21582,N,29749,N,N,N,21339,22069,27684,N,N, -N,N,N,N,N,N,N,N,25702,N,29034,N,N,N,19308,19264,N,N,N,27762,20586,N,N,N,N,N,N, -N,31090,27685,20575,N,26474,20587,23633,23401,32076,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23383,N,N,N,N,23137,N,22070,N,25439,N,24131,N, -24132,18977,N,N,N,N,N,28268,N,N,21283,28215,30799,N,N,N,N,27208,28216,28972, -28965,26958,N,N,N,31036,N,N,N,25977,27754,23894,27970,N,N,N,N,N,N,N,N,N,N,N,N, -30757,N,N,N,N,N,25914,23384,N,N,18978,N,N,20813,N,N,N,28269,N,N,N,27755,24133, -N,25440,N,19017,29289,N,21838,N,30262,N,20034,22087,N,25396,N,28973,N,27234,N, -N,N,N,22338,N,29479,N,N,19818,N,27502,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22834, -32037,N,N,N,N,N,30293,21858,N,N,N,N,N,N,N,N,30773,N,N,19573,30005,25645,N,N,N, -N,26475,29013,N,N,N,28731,N,N,26933,N,19529,31317,N,N,24916,N,N,22358,N,N, -23617,N,24134,31343,25441,N,N,N,N,N,N,N,N,N,N,N,N,24947,23670,N,20092,N,23364, -N,30833,N,N,23652,N,25967,23601,N,N,N,21846,N,N,29530,N,19265,N,23363,N,N,N, -22906,21358,N,N,N,31288,N,N,32038,27503,N,29734,N,19530,29480,N,29531,N,23335, -30263,N,20326,28786,19290,N,26450,22339,30320,26718,N,N,N,N,N,N,N,N,N,N,N,N,N, -25894,N,N,N,N,N,N,N,25959,N,N,N,18979,19495,27209,N,N,N,N,N,30774,N,N,N,N,N, -31269,N,N,N,N,28974,N,28494,N,N,N,N,N,N,N,N,19309,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -30256,28495,26959,N,30558,N,N,N,N,N,N,N,20051,N,N,N,N,23671,N,N,N,N,N,N,N, -23336,N,N,N,19320,N,N,N,N,N,N,24353,23905,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -30026,26934,N,N,N,N,26476,28270,N,29552,N,24383,N,N,N,N,N,N,19531,N,N,N,N,N,N, -20545,N,N,N,29778,24634,N,N,N,N,24384,N,20064,N,N,N,23634,32106,N,N,N,22134,N, -N,N,27210,N,N,N,N,N,N,26729,N,25388,N,N,N,N,N,29520,N,N,N,N,N,N,N,N,N,N,N, -18980,N,23416,N,N,N,24135,27504,29014,N,N,25954,N,19532,N,N,19323,N,N,N,N,N,N, -N,N,27235,N,N,N,N,N,N,N,N,N,N,N,N,24385,N,22125,N,N,N,N,N,N,N,N,26960,N,N,N,N, -N,N,N,28217,N,N,N,N,21859,N,N,20819,N,25968,N,N,N,26676,27459,N,27178,31356, -30070,28732,32084,24635,20035,N,20538,30522,22643,30541,N,N,N,25646,N,N,N,N,N, -N,N,N,N,21599,N,N,N,N,N,20583,N,N,27773,N,21038,28271,21847,27236,30754,19819, -22335,31537,N,N,19820,N,N,N,23602,20588,20093,28272,N,N,N,19522,N,N,N,20589,N, -N,N,N,N,25975,N,N,N,29564,N,N,28194,N,N,N,N,22835,N,N,22644,N,26935,N,N,N,N,N, -N,N,N,20014,N,N,N,N,22818,N,N,N,N,22641,N,21583,N,N,N,N,N,N,N,N,N,25895,21842, -N,N,N,N,N,22057,N,N,N,N,N,N,29730,N,29015,N,N,21848,N,28733,22352,21584,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,22351,27498,32107,N,N,23405,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -31813,19266,N,N,N,N,32085,N,29768,26730,30067,N,N,31070,21359,N,N,27731,N,N, -23874,28471,26452,N,19018,N,N,N,22907,N,N,31357,N,N,N,N,N,22058,N,N,N,N,N, -29816,N,N,N,N,N,N,30583,23596,N,N,N,22359,24354,N,N,N,20030,N,21360,N,N,N,N,N, -28708,24940,20327,29515,27945,19006,N,N,N,N,N,N,N,29807,N,N,N,30286,N,N,24187, -20539,21815,28273,N,N,N,N,N,N,29736,N,23672,N,N,N,N,19239,N,23118,N,N,N,24678, -N,N,N,N,N,N,N,27941,28274,N,N,N,N,23673,N,N,31068,N,N,29532,N,N,N,N,N,N,N, -30834,N,29817,N,N,N,31857,N,N,N,20540,23417,22321,N,N,N,19324,N,N,N,28709, -19325,N,N,N,N,N,N,N,N,21876,N,N,N,19821,18981,N,N,22059,20546,N,N,N,N,28734, -21053,19492,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31286,N,N,19533,N,23162,N, -30287,N,26936,N,22645,N,N,N,19534,N,N,N,N,22349,N,N,21585,26989,N,19051,22882, -N,32050,N,25389,22092,22836,N,N,24871,28243,20547,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -32051,N,21860,N,N,20328,N,27971,20530,N,N,20094,23080,30800,N,N,32086,N,N,N,N, -30801,N,30802,23635,N,N,N,N,23906,31609,23873,N,25397,N,N,N,N,N,N,27997,20036, -N,19233,N,N,N,N,N,N,23907,N,N,N,N,31837,N,N,N,N,N,N,N,N,N,31023,N,N,N,N,N, -21115,20257,25640,N,29750,27774,N,N,25390,26477,32065,23138,N,N,22579,N,N,N, -23908,28783,30321,31344,N,N,20853,N,N,23119,N,23636,N,23590,N,28479,N,N,N,N,N, -20047,N,24665,N,N,N,N,N,N,22870,27732,27211,N,N,19007,21808,N,20329,N,N,N,N,N, -29037,N,19535,N,N,N,N,25720,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25709,N,N,N,N,22360,N, -32039,N,N,N,N,27179,30258,N,N,N,N,20336,31037,N,N,N,N,N,N,26228,N,N,N,N,N,N,N, -N,N,N,N,N,N,19291,N,N,N,N,N,N,N,29521,N,N,N,N,26961,29481,20576,26962,N,23139, -N,N,N,N,N,N,25170,N,30242,24948,N,N,N,23140,N,N,N,N,N,26453,30015,20258,19759, -20259,N,N,N,19760,29054,20515,24879,30755,N,18982,30523,29290,24136,26963,N,N, -N,N,24137,32094,19008,N,N,N,31082,20814,28244,N,21586,22819,32040,22361,30542, -31294,N,N,N,N,N,N,N,N,N,20310,N,22384,N,27489,30789,N,N,N,N,N,23674,N,N,23875, -N,31071,N,N,N,N,N,N,N,26479,N,N,N,N,32101,30243,N,22908,32041,N,26478,N,N,N, -21861,N,N,N,N,N,28496,N,19761,N,N,N,N,N,N,30498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,28978,N,28977,N,N,N,N,N,N,19762,N,23083,N,18983,N,N,N,N,N,25442, -31548,22820,N,N,28218,N,N,N,N,N,30803,N,N,N,N,N,31610,N,20260,N,23675,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30307,N,N,N,27946,N,N,29217,20065,N,N,N,N,N,N, -31270,N,N,N,N,31072,N,N,N,N,27734,N,N,25710,31009,N,N,31599,N,N,N,31083,28195, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27180,N,N,N,18984,N,N,29818,N,N, -N,N,19798,31862,N,N,N,29769,N,N,N,N,N,N,N,30804,30758,N,24138,29254,N,N,N,N,N, -N,22362,N,21328,N,N,N,N,N,N,N,N,N,N,N,22597,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,27238,N,29533,N,N,N,25690,N,N,N,N,N,N,N,N,30308,N,N,N,N,N,30322,N,24386,N,N, -N,N,N,N,N,N,22909,N,N,N,19574,N,N,21306,N,N,N,N,N,N,N,25647,N,N,N,N,31073,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28710,N,N,N,19283,N,N,N,24636,N, -29770,21626,N,32042,31074,N,N,N,N,N,N,N,N,N,N,N,N,N,29751,32066,31792,N,32108, -19042,N,N,N,N,N,N,N,N,N,32061,N,27239,24387,20818,20066,N,21284,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32043,N,24416,N,N,N,N,N,N,N,N,N,N,N,N,29255,N,N, -N,N,N,26480,N,20590,N,N,29482,N,N,N,24139,30264,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,24949,28979,30499,N,N,18985,N,N,N,N,N,N,N,N,N,N,20261,N,N, -24388,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24880,N,N,28735,N,30244,N, -25398,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31302,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20591,N,N,32109,N,N,N,N,N,N,N,N,23876,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,31863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,26175,N,N,N,N,N,N,24109,N,31295,N,N,N,N,N,25969,N,N,N,N,N,N,N, -27972,N,N,N,N,N,N,N,N,N,N,N,N,N,21029,N,N,32110,N,N,N,30006,N,N,N,N,N,N,N,N, -24950,24140,N,N,31838,N,27735,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19805,N,N,N,N,N,N, -N,N,22071,19763,30805,25944,N,N,N,20330,N,N,20304,N,27212,N,N,N,N,27182,27181, -N,N,21361,N,21285,N,N,N,N,N,N,30543,N,N,N,N,N,N,N,N,28196,N,N,N,N,20516,N,N, -29218,N,N,N,N,N,N,N,N,N,N,20592,N,N,N,N,29219,N,30584,N,N,N,N,20531,N,N,23337, -N,N,21307,19052,N,28966,19285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30567,N,N,19806,N, -30500,N,N,N,30784,N,N,N,21341,N,19536,N,N,N,N,20262,N,N,N,N,N,N,30323,N,N,N,N, -N,24951,N,N,N,N,N,21340,N,N,31358,N,N,N,N,N,N,N,31271,N,N,N,N,N,N,N,N,N,N,N,N, -27481,N,20263,27183,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,25711,N,N,N,26937,29016,N,N,22616,N,N,24690,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,26164,23676,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29553,N,N,N,25424,N,N,29307,N, -23366,20593,N,20594,20316,N,21329,N,N,19505,30552,N,19240,27452,25662,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29788,N,N,23618,N,N,28711,N,N,26176,N,N,19053,N, -N,N,N,26731,25960,23619,N,N,27998,21362,N,N,N,N,19575,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,20052,26411,N,N,N,19267,N,24881,N,N,30514,N,N,21363,21330,N,30016,N,N,N, -24413,N,N,28275,26481,N,32052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29256,N,N,N, -29522,N,N,28276,N,25171,N,N,N,N,19537,N,24426,N,N,N,26938,N,N,N,N,N,N,N,N,N, -22871,N,N,N,N,N,N,N,N,30029,N,29042,31303,N,N,N,N,N,N,N,N,22904,21570,N,N,N,N, -30309,N,N,N,N,23877,N,N,N,N,N,N,26482,27999,N,N,19019,N,N,23418,N,N,N,26677,N, -21286,N,N,N,N,N,N,32053,N,N,31049,N,25698,N,31549,N,N,22308,20037,N,N,N,N, -20053,22118,N,N,N,N,25917,N,N,N,N,N,N,24141,27763,N,N,28000,N,N,N,N,N,N,N,N,N, -27756,31550,24427,N,24952,31038,N,N,N,N,20595,24618,26722,N,N,25172,21117,N, -25896,N,N,N,N,N,22867,N,N,N,N,21342,N,29752,30524,23677,N,26732,25703,N,N, -25463,N,N,N,N,N,27688,N,N,N,N,N,N,31345,N,N,N,N,N,25970,N,N,20596,21039,23653, -N,N,N,N,20517,28980,31793,19576,N,N,23878,31313,N,30559,N,N,31272,N,N,N,N,N, -28277,N,24142,N,N,N,N,26483,N,N,30508,27460,28001,24619,23879,N,N,N,N,21043, -21055,N,N,N,19020,N,N,N,N,31551,N,N,N,N,25981,23909,22605,N,N,N,N,N,27764,N,N, -N,N,N,N,N,N,20597,N,N,26733,20562,N,22872,N,N,N,N,N,N,N,N,N,N,N,30310,N,N, -23338,N,N,N,30560,N,N,N,N,N,N,N,N,N,N,N,N,22617,N,29731,N,N,29789,N,N,N,N, -28497,N,N,22837,N,N,27947,N,25399,N,N,N,N,28219,19764,N,24691,27213,N,N,N,N, -27765,26734,N,19241,28975,N,N,N,N,N,N,N,N,19021,N,27689,N,29291,N,32111,N, -31091,N,N,N,N,N,N,N,N,N,26177,N,N,27736,N,N,N,27948,27214,N,26719,N,N,N,N,N,N, -N,N,N,N,N,N,N,24143,N,N,N,N,N,N,21030,N,N,26484,20822,N,N,26178,25443,N,N,N,N, -25648,N,N,N,22580,N,N,N,N,N,N,N,N,N,N,N,N,30245,N,N,N,N,N,29534,N,N,N,N,22309, -N,N,N,N,30568,N,N,26694,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31590,N,N,N,N,N,N,N, -23910,N,N,N,23678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,22618,N,N,N,N,N,N,N,23084,27184,N,N,N,N,N,N,N,N, -25400,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,18986,24953,N, -27185,N,N,N,N,29292,N,N,31342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28245,N, -N,N,N,31092,N,N,21100,31611,N,N,N,32112,N,24637,20067,N,N,N,N,N,N,N,N,N,30790, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24110,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,24389,N,N,25918,N,N,N,N,N,N,N,N,N,N,N,N,27949,31338,N,N,19822,27942,N, -27950,28781,N,23841,N,27951,31864,N,22635,N,N,N,19577,19765,N,N,N,N,31273,N, -24925,N,N,N,N,25173,27983,N,N,N,23842,N,N,31050,N,27240,N,25965,N,N,N,N,N,N,N, -N,21355,N,26964,24954,25676,N,24932,26695,N,N,20059,N,N,N,23637,N,30517,31859, -28787,20015,28981,28498,26696,27505,N,N,N,N,N,19284,24638,25464,27241,31794,N, -N,N,N,N,24692,N,20320,N,28197,N,N,31274,26179,24882,18987,N,25444,26939,N,N,N, -N,N,25174,29554,N,28246,27186,20598,27737,23115,20264,N,N,N,N,23843,N,N,N, -22619,N,31054,26965,25425,N,N,21052,N,N,N,N,N,N,22572,29516,N,19835,30294,N, -26485,26735,25465,21051,29555,25467,N,24144,20016,N,22135,29017,N,N,N,N,N, -30017,23620,N,30011,N,24145,23654,N,N,24146,N,N,28002,28278,27215,28782,25468, -N,21343,21364,24883,N,24884,N,N,N,N,29779,N,N,24390,N,N,N,N,N,N,N,N,N,N,26966, -N,N,N,23339,N,N,N,N,N,N,N,N,30246,N,N,N,N,N,N,25401,27461,29737,19766,21113,N, -23085,21091,20305,N,N,N,N,19292,19578,N,20317,N,N,26665,N,25403,25402,N,N, -24666,N,N,N,28279,N,N,N,N,N,23603,N,N,N,N,21365,N,22310,N,30261,22363,N,N,N,N, -N,N,24917,N,N,21610,N,24355,N,N,N,N,N,N,N,32095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,20599,27988,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19242,N,N,N,N,N,N,N, -25691,N,24955,19234,N,N,N,N,21344,N,25663,N,31552,N,23102,25677,N,22073,N,N,N, -28480,N,24956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30265,N,N,N,N,N, -N,24391,N,N,N,N,N,N,N,25649,N,N,N,N,N,N,23655,23656,N,N,N,31318,N,21366,N,N,N, -N,29018,N,31346,25213,N,N,N,N,N,21839,20600,N,N,19807,N,N,30027,N,25712,19243, -N,22340,N,N,N,N,N,N,N,N,N,N,N,N,N,25214,N,23898,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23086,19054,N,N,N,21817,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25377,N,N,26723,N,N,29483,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,20265,N,N,N,21367,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -21617,N,N,20068,N,26738,N,N,N,N,N,N,N,25973,N,N,N,N,N,N,N,N,N,N,N,N,N,26414,N, -22074,N,24428,25664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26724,N,N,N,N,22581,N,N,N, -25692,N,N,N,N,N,N,29753,28982,N,N,25182,24885,N,N,19823,28967,20069,19293,N,N, -22883,N,N,29484,N,N,20601,27691,24147,30569,N,N,31093,N,N,N,N,N,24926,19310, -25404,30806,N,N,23406,N,N,N,N,N,32113,N,N,N,N,30518,N,N,N,N,29790,N,N,29293,N, -23385,N,28712,N,N,N,N,N,N,N,24957,N,N,N,N,N,24148,N,24620,N,N,N,N,N,28003,N,N, -21345,N,24392,N,N,N,N,22838,N,32044,28499,N,N,N,25665,30827,N,23340,N,N,N,N, -31814,N,N,N,N,N,N,N,N,22573,N,N,N,N,N,N,N,N,N,30266,N,23391,21331,30791,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,19022,30785,21044,N,N,23604,31289,19023,N,31795,27242, -27243,20602,N,N,N,N,N,28004,N,N,23911,N,N,24393,N,N,N,N,24429,N,N,N,N,N,28220, -N,28481,N,N,19538,N,23844,N,N,N,24394,N,N,N,N,N,21368,28968,N,N,N,19767,N, -28500,N,N,N,N,N,N,N,25693,24430,19244,26940,N,N,N,N,N,27244,N,N,N,24395,N,N,N, -N,N,31039,22063,21830,N,N,N,N,N,20266,N,N,20009,N,N,22136,N,N,N,28983,28280,N, -N,N,22873,29535,N,30792,20038,N,N,N,N,N,N,N,N,21862,N,N,N,N,N,N,29798,N,N, -26181,28501,N,N,19311,31839,23591,N,N,22119,N,N,N,N,N,30793,N,N,N,N,25426,N, -25405,N,20321,28736,27738,N,23895,31600,N,N,27692,N,N,N,28713,N,N,N,N,N,N, -31319,31553,N,21056,N,N,N,N,N,N,N,25904,N,N,N,28005,N,N,N,N,19245,N,31024,N,N, -N,N,N,N,N,N,N,N,N,30501,N,19246,N,23087,N,22582,N,N,N,N,N,N,N,21287,31538,N, -32068,N,27693,N,N,N,N,N,N,31521,N,N,N,25961,26990,N,29556,30835,28737,24111, -30768,N,N,29536,26415,N,N,N,N,N,23341,N,26165,N,N,31016,N,N,23896,26713,28502, -N,N,N,21346,N,25183,N,N,31840,22344,32045,N,N,N,24431,19539,21369,N,N,N,N, -21616,23367,24149,N,N,N,N,28788,N,21840,25945,N,N,N,N,N,N,31815,23638,25184,N, -N,N,23088,N,N,N,N,N,N,29475,N,21356,N,29771,N,N,N,32069,N,N,N,N,N,25469,N, -31025,N,N,N,N,N,N,20603,27739,N,N,N,N,N,N,N,N,30012,29220,22606,22607,N,N,N,N, -N,N,30071,N,N,N,N,N,N,N,N,N,N,30305,N,N,N,N,N,N,N,N,N,21047,N,N,N,N,N,N,N, -31596,N,23880,25704,N,N,21057,N,N,N,30807,N,N,N,N,N,22075,24150,N,N,30525, -27694,N,N,N,20577,N,24693,27187,N,20054,N,N,N,N,19493,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,27766,25185,25406,N,N,N,N,N,N,N,N,N,31816,N,N,19824,N,31094,N,N, -24432,N,N,N,25919,N,N,N,20031,N,N,N,N,31841,27952,32081,30267,N,N,31055,27482, -19009,N,21048,19825,N,25427,32102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -26221,N,N,N,25466,N,N,28714,31056,N,N,N,N,N,N,31842,N,30759,N,N,N,24933,28281, -N,N,N,26486,27245,N,N,31796,30018,N,N,22364,N,N,N,N,N,N,N,N,28789,N,23912, -21357,30076,N,23103,N,19579,N,N,N,21370,29732,N,N,N,N,N,N,N,28503,N,21571,N,N, -N,N,N,N,N,N,N,31587,N,N,N,N,N,N,N,N,31597,N,24621,N,N,27246,31539,25666,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,30311,21085,N,24396,N,N,31817,N,N,25897,24694,30259, -24958,N,N,N,N,19312,N,27247,27248,N,N,N,23104,30772,27506,N,N,N,N,N,25667,N,N, -N,N,26967,25713,N,N,N,19055,N,N,N,N,N,N,N,20055,N,N,N,N,N,N,N,N,31818,N,N,N, -29537,N,N,19268,N,N,N,N,25445,N,19269,27188,N,N,26941,N,22345,N,N,27483,27953, -N,19523,30526,31819,N,N,N,N,N,N,30836,N,22839,N,N,29523,29524,N,N,N,30564,N, -30545,N,N,22583,20017,19010,N,N,31540,19270,N,N,28790,N,N,21863,N,27216,N,N,N, -N,N,19540,19247,N,N,N,N,N,29738,26927,N,N,30019,26968,N,N,N,N,N,N,N,23913,N,N, -N,29043,N,21883,24123,N,N,29819,N,N,N,32115,32114,30502,N,N,N,N,N,N,N,N,N, -23881,N,N,21587,N,19496,N,23105,19541,N,22884,N,N,N,31306,N,N,N,25955,N,N,N, -21308,N,N,N,19056,N,N,N,N,20548,N,N,N,19024,31275,27499,26488,22885,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20823,N,N,N,N,N,N,N,N,N,N,N,29476,N, -N,N,21627,31843,31320,N,29525,N,20267,N,N,27507,21884,N,N,N,N,N,N,21332,19836, -N,22886,N,25209,25121,27476,N,24695,25650,19580,N,N,N,31588,N,N,N,29739,N,N,N, -N,20541,N,19057,N,N,N,N,N,N,N,N,28472,N,N,N,22336,N,28282,32116,N,N,21347,N, -31554,N,N,N,N,N,N,N,21864,23342,24886,30775,N,N,N,N,N,24639,31555,23914,N, -25122,N,28198,N,N,N,N,N,30312,N,N,N,N,30325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,23882,N,N,20578,N,N,N,N,23846,N,N,23915,N,N,25721,N,N,25391,20604,N,N, -N,29820,N,N,N,N,19516,30570,N,N,N,N,N,N,25956,24433,N,N,30561,N,31095,28473,N, -N,30808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31017,N,N,N,N,N,30809,N,N,N,28221,N,N,N, -22598,N,N,25699,30030,N,N,N,N,23897,N,N,N,N,22887,21049,21827,N,N,23141,23120, -N,20825,20056,N,19294,29740,23163,N,30313,26739,20268,28784,N,29821,23368,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,20032,25428,20815,29045,N,19826,N,20331,N,N,N,19768, -N,N,N,N,N,N,25382,20826,29221,N,N,N,N,N,29222,N,25678,N,N,N,N,N,N,N,21371,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28969,N,N,N,29257,N,N,N,N,N,N,N, -N,N,N,28504,26185,N,22584,31347,N,N,N,N,N,N,N,N,N,N,29493,N,N,30756,N,N,20851, -26184,N,N,N,N,30810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23657,24151,N,N,N,N,N, -19295,N,N,N,20332,N,N,N,N,29791,N,N,20852,21050,N,N,N,24434,N,N,N,24887,N,N,N, -N,25123,21372,N,N,28006,N,N,N,N,N,23369,N,N,N,25722,N,20318,N,N,20048,N,N,N,N, -21843,29557,30510,N,N,28488,N,19827,30031,25971,28738,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,19025,N,N,N,27249,N,20518,N,N,N,N,N,N,N,N,22874,28715,N,N,N, -N,N,27495,N,N,N,25920,31797,N,N,N,N,N,25668,N,N,N,N,N,N,N,N,N,N,N,19497,32070, -N,N,N,N,N,27189,N,25898,24378,24927,N,23121,N,N,N,N,24888,N,26740,21373,N,N,N, -N,25124,N,N,N,N,N,29258,N,N,N,N,N,N,N,N,N,23142,30515,N,N,N,N,N,N,N,N,N,N,N,N, -32077,N,N,N,29494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28247,N,N, -N,N,N,N,N,30020,N,N,N,N,N,N,N,N,22564,N,N,N,N,N,29223,N,N,N,N,N,N,N,N,22840, -22841,28489,N,N,N,N,N,N,N,N,N,N,N,N,N,22094,N,N,N,N,N,N,N,N,30539,24366,26741, -N,N,N,N,N,N,21045,N,N,N,21333,N,N,N,N,N,29772,23164,N,N,N,N,N,22888,N,30571, -30025,N,29500,N,23122,N,N,N,N,N,N,N,N,21301,N,N,N,N,N,26678,N,N,22095,29754,N, -30537,N,N,19498,N,N,28739,19542,N,N,N,20563,N,21309,N,N,N,23419,N,19296,N,N,N, -N,N,N,21348,30327,N,N,21818,29517,19297,N,N,N,N,27508,N,N,N,N,N,29741,N,31786, -N,N,N,N,N,30572,N,N,N,26742,23143,N,N,N,30540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,25921,N,N,N,N,24686,N,N,N,N,N,21885,N,N,N,N,N,N,20070,31787,21819,N,N, -29224,N,N,N,N,N,N,25125,19769,27250,19271,N,19828,N,N,23343,28505,N,N,N,N,N, -19770,N,N,31865,N,N,N,N,24435,20071,23106,N,20269,N,N,N,N,26489,30760,N,N,N,N, -N,N,29538,N,N,N,19058,24356,N,N,21572,N,N,N,N,N,19543,25922,N,N,N,N,19771,N, -28506,28248,N,23847,25126,N,N,N,N,N,24640,N,N,N,22064,30794,N,31866,N,22910,N, -N,N,N,24112,N,N,N,23916,23144,N,N,N,N,N,21600,N,22137,N,19799,24152,N,N,29304, -N,25686,N,N,20549,29742,N,23848,N,N,N,27973,29526,N,N,24153,25446,N,N,N,N,N,N, -21288,N,23344,N,N,25946,25407,N,N,N,23345,N,N,N,21865,N,N,N,N,N,24641,28507,N, -N,28777,N,N,22322,N,N,N,N,20605,N,N,N,N,N,N,N,N,22889,N,N,20606,N,27757,21289, -N,29225,28740,N,N,25186,26991,N,N,N,31057,N,N,26969,N,N,N,N,N,26714,23107, -23108,21573,N,26490,19808,25392,N,23346,31556,N,29539,N,22821,31591,23883, -20564,N,26166,24622,32090,N,N,N,N,N,N,N,N,23605,24696,26417,N,N,N,N,30064,N, -22620,27974,N,N,N,N,24889,N,25408,31040,26992,N,N,22875,N,29540,N,N,N,23606, -25705,N,N,N,N,N,28741,25409,31820,31821,N,N,N,N,29259,N,29260,N,N,N,25679,N,N, -N,N,N,N,N,N,N,29019,N,31321,N,28984,32117,24697,N,N,N,N,26491,31799,31844, -31557,25447,22585,N,30328,N,N,23621,19544,N,N,N,24623,29799,N,28508,20348, -28509,N,29226,N,N,N,N,N,N,N,N,N,32062,N,N,18988,32059,32071,N,N,N,N,26418,N, -27217,24436,N,N,N,N,20844,25694,25923,N,N,N,N,22822,N,N,19772,N,29541,N,N,N,N, -N,N,N,N,27989,N,N,22842,N,N,N,28007,31541,30828,N,N,N,N,24679,N,19545,N,N, -21574,N,N,N,N,N,26405,N,21877,21310,N,31867,N,N,N,N,N,N,N,N,N,N,N,N,25714,N,N, -24437,N,N,26744,30829,N,N,20039,N,N,N,N,N,32118,N,N,N,N,N,N,N,N,N,26712,N, -19800,26454,19546,N,N,19043,24438,28743,28742,N,22586,N,29044,29808,30028,N,N, -31845,N,N,N,N,27205,27251,N,23899,N,23639,N,N,N,N,N,N,24189,29305,N,21831,N,N, -N,22608,N,28744,20769,20770,N,N,N,N,N,N,22868,22120,22858,N,23089,22599,23650, -29518,30068,N,N,28985,N,N,23123,N,30314,N,N,N,20341,N,N,32046,N,N,N,N,N,N,N,N, -19026,N,N,24372,N,N,N,N,22365,31290,28199,30013,N,30837,N,N,28008,N,N,N,N,N, -21601,N,20771,24918,N,N,N,N,N,N,N,N,N,N,N,N,N,31096,N,23370,19321,21588,N, -22876,N,28222,N,30573,N,N,N,21102,N,N,24934,30585,N,N,N,N,N,N,N,23917,N,26715, -N,23347,N,N,N,20855,24624,N,N,21602,N,30295,N,22393,N,N,22621,N,19837,29227,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19773,30786,N,N,29228,N,N,18989,18990,20270,N, -N,N,N,N,25410,N,N,N,N,N,23607,N,N,N,N,N,N,N,N,N,N,23386,22843,19059,30291, -26232,27253,N,N,N,N,N,27254,N,N,30329,N,N,N,N,N,N,N,N,N,N,N,20271,N,N,19027,N, -N,18991,21040,28986,N,22323,25411,29565,24154,N,N,N,N,24155,N,N,28510,25187, -28283,N,N,24439,22346,N,N,N,N,N,N,N,N,N,20072,23387,N,N,N,N,N,N,N,28987,N,N,N, -N,26993,N,N,N,N,N,N,N,N,31287,20550,N,N,19499,28200,N,N,19322,31097,19581, -21374,N,N,N,N,25680,N,N,N,N,N,29294,N,21589,24397,N,31800,20816,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29261,N,N,N,N,N,N,N,N,30546,N,N,N,N,N,N,N,N, -19028,N,21849,N,N,N,22622,N,N,N,N,N,N,N,N,N,19801,N,N,N,28201,30268,N,N,19547, -N,N,N,N,N,28745,N,31868,N,26697,29822,N,N,N,N,26492,22366,N,N,N,N,24156,N, -28716,19582,19809,N,24890,N,23407,23090,N,N,N,N,N,N,N,N,N,N,N,N,N,20773,23608, -N,N,N,22646,N,20772,N,19810,N,N,N,N,23658,N,N,28791,N,28746,20542,N,23900,N,N, -N,N,21590,21334,N,N,N,N,N,N,27984,19745,N,N,N,N,N,24373,N,N,N,24440,N,N,N,N,N, -N,21537,20018,26698,N,N,N,N,27509,N,N,N,N,N,N,N,25429,30032,N,N,N,29985,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22823,N,N,N,N,N,N,N,N,25899,N,N,N,N,N,N,N,N, -N,N,N,N,26187,N,30065,N,N,N,N,N,N,N,N,N,N,25925,N,N,N,N,N,N,N,N,31011,24667, -30315,N,19313,N,22890,29986,N,N,N,22353,N,20856,27256,27257,23091,N,N,N,N, -28511,N,N,29039,N,25974,28223,25188,N,N,N,N,N,20543,N,31276,30033,26419,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26942,N,N,N,N,N,29262,23348,N, -N,N,N,N,N,N,N,31822,N,23918,N,N,N,N,N,N,26420,N,N,N,N,N,22324,N,N,N,N,N,N, -30516,N,N,N,N,N,19774,N,23145,N,N,N,N,N,N,N,20272,30553,29542,N,N,20057,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20010,N,19272,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,20519,N,28747,N,20551,25669,N,N,N,N,N,N,N,23392,N,N,N,N,N,N,21850,N, -22311,N,N,N,28224,N,30838,N,N,N,N,30034,28009,N,22844,N,25926,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,29987,N,N,23124,25127,31612,N,N,29020,N,N,N,N,N,N,19060,N,N, -N,26746,N,N,20073,N,N,N,N,N,N,27000,25189,N,N,N,N,20537,21618,N,N,N,N,N,20774, -N,24398,N,N,N,N,N,N,N,N,N,31860,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21290, -N,N,N,19500,N,N,N,N,28512,N,N,N,25957,20565,N,N,N,N,N,N,N,N,23420,N,N,N,N, -31846,N,N,N,N,N,19326,28010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24113,N,N,N,N,N,N,N, -31075,N,N,N,N,N,N,21538,20342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22096,N,N,N,N,N,N, -21866,29038,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31307,N,N,N,N, -25889,21809,N,N,N,N,N,20333,N,28011,N,N,N,N,N,21810,N,N,N,21820,N,N,N,N,N,N,N, -N,N,32098,29485,N,32091,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26928,N,N,N,N,N,N,N,20775, -N,N,32099,20019,N,N,N,N,N,N,N,32100,31310,N,N,N,N,18992,N,30503,N,20273,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,26146,N,31798,29229,28513,29486,23622,22891,N,N,N,26720, -N,N,N,N,N,N,N,24872,N,N,N,N,21878,20349,N,N,24157,N,N,N,22865,N,N,N,25706, -29263,N,30527,N,N,25190,25128,N,N,N,N,N,N,N,N,N,N,N,25430,N,27985,N,N,N,N,N, -27001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22065,24114,N,N,24680,N,N,21291,N,27484,N, -N,24367,N,19011,N,N,28284,N,32067,N,N,N,27510,20274,N,N,N,N,22892,N,22845,N, -22623,N,N,21560,27454,23919,N,23920,23921,23922,N,N,22846,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,31558,20275,28285,N,N,N,N,N,N,25643,N,23109,N,22636,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,20776,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25129,N,N,24124,26421,N,N, -N,N,N,23408,N,28514,29040,20276,N,N,N,N,N,N,N,N,N,N,N,23409,N,24625,N,N,N,N, -24357,N,31058,N,N,26493,N,N,26147,31601,19248,29230,N,N,N,N,N,N,N,19815,N, -26716,N,N,26455,N,N,30528,N,20579,N,N,N,23073,N,N,N,19517,N,N,20777,23884,N,N, -25470,20778,26666,N,27190,31098,26188,30296,N,N,N,21575,N,N,N,22859,N,22866, -21323,22647,23081,30072,N,N,24158,29231,30761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -22600,N,N,28225,N,N,N,N,31041,N,N,N,N,23923,27258,N,30269,24891,19775,29780, -26189,N,31823,31522,N,24668,N,N,N,N,29755,23125,N,31026,N,N,N,N,N,N,31602,N, -23414,N,24159,N,N,N,23410,N,N,N,N,N,30812,30574,27496,N,21114,N,N,28988,N,N, -31322,N,N,23146,23110,30529,N,N,26422,25927,22060,N,N,N,N,23623,N,N,N,N,N, -24873,N,25130,N,21798,N,N,21591,N,N,N,N,N,N,29264,N,27259,N,24669,31603,N,N,N, -N,N,N,N,28989,N,N,25191,32087,N,20040,27191,N,31808,N,32103,30575,N,N,22325,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28474,29021,N,24115,N,N,N,N,N,N, -26699,N,N,30813,N,N,31559,21832,N,22367,N,23849,N,N,N,N,N,26929,N,N,31277, -30297,31348,N,N,N,N,N,30762,N,N,N,N,N,26222,N,19548,24892,24687,N,N,26943, -31869,26190,N,N,24919,N,26191,N,29809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,25715,N,N,25723,N,N,31076,N,N,N,N,N,N,N,N,N,N,28515,N,N,20334,30270, -24626,31870,20779,N,N,N,22394,N,N,N,31560,N,25175,N,N,N,N,N,N,21539,28792, -22312,N,N,N,24935,N,N,21311,N,N,N,N,N,N,28516,N,22341,27490,N,N,31847,N,N, -25634,N,25192,N,26192,N,31592,29800,25972,29756,29781,24374,N,31801,28226, -19061,N,N,N,28517,19298,21540,N,24160,23165,25670,26686,N,N,N,N,24670,30260, -27218,N,31099,N,N,24642,N,19044,N,26423,N,27261,N,22877,N,23092,28202,31593,N, -N,N,N,23371,23093,N,N,N,N,N,28990,N,N,21292,N,N,N,N,N,N,N,N,31561,N,24399,N,N, -21312,25431,N,28518,31824,N,N,N,N,N,N,N,26944,N,N,N,30035,N,N,27740,30519,N,N, -27192,20857,N,N,N,N,N,N,23624,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27193, -N,N,N,N,N,29022,N,N,N,N,N,22326,20277,N,22824,N,N,27758,N,N,23850,N,N,N,N, -19746,26670,N,N,N,24893,N,29265,N,N,N,N,26945,N,N,N,21116,N,N,N,N,N,N,N,23349, -N,29543,22654,N,N,N,31825,N,27954,29743,N,31523,N,N,31809,N,28203,21541,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29810,N,N,N,N,28249,N,N,N,31562, -N,N,N,N,N,19811,22587,25947,30839,N,N,N,30292,N,N,N,N,N,N,N,N,22313,N,19273,N, -N,26193,28748,N,N,N,N,N,N,N,N,N,N,22574,N,31059,21886,N,N,N,N,N,N,N,22588, -29232,N,N,N,N,25131,29544,N,N,N,N,N,28482,N,N,N,N,N,N,28012,N,26424,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,23166,N,N,19518,N,N,29308,23147,N,25176,27990,N,N,22097, -24627,N,N,31826,N,27464,N,N,N,N,N,N,N,N,21313,28749,N,20343,N,N,N,N,N,N,N,N,N, -27986,N,21592,23625,22385,N,N,24379,N,N,29477,N,N,N,29773,N,N,N,N,28991,30769, -N,27002,N,N,N,31563,N,N,19029,N,N,N,N,N,N,N,N,N,N,N,31060,30538,N,N,22088,N,N, -N,N,N,N,31848,29501,N,28286,N,26494,N,N,N,N,N,21314,N,N,N,N,21302,N,19501, -30330,22066,21080,N,N,N,N,N,N,26456,N,N,N,N,N,N,N,N,N,N,25381,N,N,N,N,26425,N, -N,N,N,28717,31564,27425,N,N,21542,N,N,N,N,31565,N,21821,29023,N,N,30331,N, -24116,N,N,N,N,N,N,N,N,N,N,N,N,21867,25928,N,N,N,31524,21561,N,N,24161,N,25635, -N,N,N,22327,N,30830,N,N,N,24117,N,N,22098,N,31061,26426,27477,21879,28519, -24894,N,N,N,31278,N,N,N,22121,22126,N,N,N,N,N,N,26427,N,N,N,N,N,N,N,27723,N,N, -N,N,N,N,21811,N,N,N,N,N,N,N,N,N,N,N,N,N,20020,N,N,N,31525,24942,N,N,N,N,N,N, -30504,N,N,N,N,31566,N,N,N,N,N,22589,N,N,N,N,N,N,N,31613,N,N,N,N,31849,N,N,N,N, -N,N,N,20278,N,N,N,27975,28204,N,N,N,N,N,N,N,19549,N,N,N,N,30247,N,N,N,26234,N, -N,N,29988,N,N,N,N,N,32092,27955,20041,N,N,N,N,N,N,28520,N,N,24895,N,N,N,N,N,N, -31323,19299,30505,N,31526,N,N,N,23609,N,N,N,28992,27976,28483,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,22061,N,N,32078,N,N,N,26657,N,N,N,N,N,N,N,N,31604,21799,N,N,N, -29046,N,26195,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19550,N,N,N,N,N,N,N,30770,N,N, -N,23659,32054,N,N,N,N,25962,N,N,29024,N,N,N,N,N,N,N,N,N,N,N,N,23372,23885,N,N, -N,21576,N,N,22893,N,N,N,N,29989,N,N,N,N,N,N,N,N,N,26235,N,N,N,N,N,26196,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,32072,N,22049,32063,N,31827,N,28449,N,26428,N,N,N,N, -N,20846,N,N,26197,N,N,26994,N,24368,N,N,N,N,N,22624,31802,32047,28750,N,23393, -N,N,25929,N,27956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24643,N,N,N,N,N,N,25432,N,N,N,N, -27003,27176,N,N,N,N,32055,N,N,31527,N,26946,N,N,N,N,32119,N,N,N,N,N,25177,N,N, -23660,N,N,N,N,N,N,N,N,N,26658,N,N,N,N,26224,N,N,N,N,N,N,N,32120,32121,N,N,N, -30271,N,N,26407,N,26199,N,N,N,N,21619,21577,N,N,N,N,22138,N,22386,N,24896,N, -23394,26200,N,N,N,N,N,N,N,N,N,26429,N,N,N,N,N,28751,29502,25132,N,N,N,N,N, -30007,24688,N,N,N,N,N,N,N,N,N,N,N,N,32056,25448,N,21543,26748,31314,N,N,N,N,N, -30831,N,N,N,N,N,N,N,N,N,22099,N,N,N,N,N,N,N,N,N,N,21812,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,28752,N,30576,28211,N,N,27194,N,27219,N,N,27977,23851,N,N,N,25900,32033, -N,24400,27699,N,24401,N,N,N,N,N,28013,30776,30586,N,N,N,30763,N,N,N,N,N,29792, -N,N,N,N,N,21562,25651,N,26970,N,24118,N,22847,N,22848,22127,N,N,N,N,22860,N, -23082,N,N,N,N,N,N,N,N,24421,N,N,N,N,N,N,30565,N,N,N,19506,N,N,24441,22368,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21563,N,N,N,N, -32122,N,N,N,N,19507,N,N,23411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24402,N,20042,N, -28250,N,N,N,N,N,N,N,N,N,25700,N,31567,N,N,N,N,N,N,20279,N,28227,N,N,N,N,N,N,N, -20074,N,N,N,N,N,N,N,25133,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22369,31349,N,N,21833, -30764,26457,N,N,N,N,N,N,N,N,N,N,N,29545,N,N,N,N,22637,25412,28785,N,N,N,N,N,N, -N,26725,N,N,N,24698,28228,22878,N,N,N,N,N,N,N,N,N,N,27426,27427,N,N,N,N,N,N, -31810,27195,N,N,N,N,26667,24162,N,N,N,N,N,N,N,N,N,N,28015,N,26659,N,N,N,N, -20337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21564,N,31850,N,N,N,N,N,26430,N,31858,N, -N,22068,N,N,25134,N,21303,31308,N,N,N,N,N,N,N,N,31324,N,27957,24931,N,26668,N, -26717,N,N,28521,N,N,N,N,N,29757,N,20280,26971,20780,N,N,N,N,N,N,23111,N,N,N,N, -N,N,N,27465,N,26700,N,N,N,24119,N,N,N,N,22076,21349,N,N,N,N,N,31325,N,N,N,N,N, -N,23126,N,18993,N,N,N,N,N,N,23112,24358,N,31027,29266,N,19012,N,N,N,N,N,N, -20043,N,N,19829,N,N,N,32048,21800,N,28993,N,N,25193,23626,27700,31296,N,N, -31528,20520,N,N,23148,N,N,N,N,N,N,N,N,N,22894,N,24699,N,N,N,28522,31326,24644, -N,20281,N,21834,22370,25135,N,22328,N,N,N,N,N,N,N,N,N,26701,N,N,N,N,N,N,N, -30298,N,N,N,N,28450,25178,30332,N,N,31568,20781,N,19812,N,20782,23661,26702,N, -28793,20021,26236,N,N,22395,20566,23925,30577,N,30333,N,23415,N,N,N,N,31594, -26972,22849,N,30066,24645,N,N,N,N,N,N,27220,N,N,N,N,N,N,N,N,N,31042,N,27196,N, -21061,31569,26432,27429,N,24442,25378,22329,N,26947,N,26749,26671,N,N,29267, -31529,22565,N,N,N,N,21835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20552,N,N,N,20783,22371, -N,N,N,24646,N,22050,N,28016,N,N,N,N,N,N,N,N,N,N,N,N,22387,N,N,N,31828,N,23127, -19551,N,29268,N,20784,N,19552,N,23421,29503,N,28753,N,N,N,N,N,31803,N,25136,N, -N,26149,N,N,N,25179,N,N,N,24414,N,24647,N,N,N,N,N,N,29295,N,N,N,19553,N,N,N,N, -22122,N,N,N,N,26434,N,N,N,20022,N,29504,N,19838,N,N,N,31570,N,30840,30587,N,N, -26687,N,N,N,N,N,N,N,26679,N,N,N,N,N,N,N,N,27958,23610,N,N,19508,N,N,N,N,N,N,N, -N,N,N,N,N,29047,N,N,N,26680,N,N,19062,N,25636,29782,N,N,N,24422,N,N,N,24359,N, -24423,24897,N,26948,N,N,23627,26949,N,N,N,28451,27430,19235,25449,N,N,N,20859, -28452,N,28523,N,N,N,N,N,N,N,N,N,N,N,N,20532,N,N,N,N,19747,N,N,26726,N,28453,N, -21324,23149,N,N,N,N,22330,N,29269,30053,22895,N,N,N,N,31028,N,N,21844,32079,N, -N,N,23395,N,N,N,N,29025,27702,N,N,N,N,31614,21335,N,20785,N,19249,N,N,N,N, -20786,N,N,N,N,N,N,19250,28994,N,N,29793,31029,N,N,24899,24898,N,27511,N,N,N,N, -N,N,N,N,N,N,N,24360,N,N,N,N,N,N,N,19274,N,N,N,N,N,26169,N,N,N,N,N,30814,31018, -19063,N,27959,N,N,21304,29270,N,N,21593,28229,29296,N,N,N,18994,N,N,23611,N, -29048,N,N,N,N,N,27703,N,N,N,N,25930,N,30272,32093,N,N,21603,19554,N,30548,N,N, -N,N,N,N,22373,N,N,N,N,N,N,N,N,N,N,N,N,N,21315,N,22566,N,30273,N,N,N,N,N,23926, -N,19776,25948,N,N,N,N,N,N,N,N,N,N,N,N,25931,N,N,N,N,N,N,N,N,N,N,N,24900,N,N,N, -N,N,26672,29744,29546,23150,N,22331,N,25137,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,22314,N,N,N,N,N,N,22139,N,N,N,N,N,N,N,N,N,25695,N,19030,N,N,N,27432,N,N, -N,23422,N,N,N,N,N,N,N,N,N,N,30274,N,N,28475,N,N,N,N,21629,N,N,24648,N,N,N, -26681,N,28454,N,N,N,N,N,19748,N,N,21620,23329,23388,23389,N,N,N,N,N,28252,N, -19275,31829,N,N,N,N,N,N,20075,N,19777,N,N,31571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,31019,N,N,N,N,N,N,N,N,N,N,N,30036,N,N,N,N,22825,N,N, -26973,23373,N,N,23886,N,26435,N,27724,N,N,N,N,N,N,N,31084,N,N,N,19276,N,N,N,N, -24700,21544,N,27987,22639,N,29271,N,19064,23151,N,N,22100,N,N,N,N,N,N,22861,N, -N,N,22638,N,29249,N,N,N,24403,N,N,N,23152,N,25194,24701,N,N,22648,N,N,N,30511, -23094,N,19031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29272,N,22649,N,N,N,N,N,N,N, -N,31327,N,N,N,N,N,N,N,N,N,N,N,N,N,20335,22850,N,28754,N,25681,N,N,N,29495,N,N, -N,N,N,N,N,N,N,N,N,N,31328,N,N,N,N,N,N,N,N,N,N,N,N,N,28524,N,N,N,N,N,25138,N, -21565,N,N,22862,N,N,N,N,29794,N,N,N,N,N,N,N,N,N,N,N,N,N,21545,N,N,N,N,19778, -26458,N,N,N,N,N,N,N,N,N,N,N,29273,N,N,N,N,N,22826,N,N,N,N,N,N,N,N,N,N,N,N, -22590,N,N,N,N,N,N,23597,N,N,N,N,N,N,25195,22140,N,N,19065,N,N,21594,N,N,N,N,N, -N,N,29783,19489,N,N,20282,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30008, -N,N,N,22851,20584,N,N,N,N,N,25413,27512,N,29233,N,N,N,20283,N,N,N,21293,26721, -20076,N,N,N,24628,24163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23927,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,29234,29558,30299,N,N,N,N,22398,N,N,N,N,N,30815,N,30578,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,20521,N,N,N,N,N,N,N,N,N,26202,N,N,N,N,N,N,N,N,N,N, -N,N,N,29990,N,N,N,N,N,N,N,N,N,N,N,N,N,22332,19555,N,N,26203,N,N,N,N,N,N,N,N,N, -N,N,N,23901,N,N,N,N,20787,N,N,N,N,N,28525,N,N,N,N,22110,25716,24943,N,N,23928, -N,N,N,N,N,26703,N,N,N,N,N,N,N,N,N,N,N,19045,N,N,N,23585,N,24629,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,31788,31789,22567,N,N,N,N,27960,N,N,N,23350,N,N,N,N,22128, -29487,N,N,19749,N,23153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22568,N, -N,N,19556,N,N,20788,N,N,N,N,N,19032,N,N,N,N,N,23154,29991,N,N,N,N,N,N,N,N,N,N, -N,N,29992,N,N,N,N,N,N,N,26150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21868, -21880,23155,N,N,N,N,N,N,N,N,N,N,N,N,N,25414,N,N,N,24164,N,24165,20789,N,N,N,N, -N,20790,20791,29235,N,N,N,N,N,N,26974,N,N,N,N,N,28755,29236,N,N,28756,19300, -31572,30054,25450,N,24166,N,N,N,N,24404,N,N,30841,N,N,N,N,28718,N,N,N,N,N,N,N, -N,N,N,N,N,20792,N,N,N,N,22111,N,20567,N,N,N,N,N,N,N,N,N,N,N,31777,28526,23640, -N,26975,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25949,32123,N,N,24649,N,N,N, -22089,N,N,21546,N,25932,N,N,N,N,N,26976,N,N,N,20568,31778,21566,25139,24167,N, -N,N,N,N,N,N,23612,21046,30037,N,N,N,N,N,20001,29993,N,N,23929,N,N,23930,N,N,N, -N,N,N,28757,N,N,N,N,30303,N,29274,25707,N,29297,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,27705,32124,N,N,N,N,24874,N,N,19033,N,N,28527,N,29994,N,N,N,N,N,N,27769,N, -N,30765,N,29250,30275,N,22354,N,N,31010,28758,N,N,N,N,N,N,N,N,N,N,N,N,N,28794, -N,N,30304,N,N,N,N,26995,29251,N,N,N,21547,18995,19750,N,19779,19802,N,N,N,N,N, -22863,N,N,30276,N,N,N,28253,26436,N,N,N,N,N,N,N,N,25140,N,N,N,N,N,N,N,N,N, -24418,26459,N,N,N,N,N,N,26673,N,31790,N,N,N,N,25933,N,N,N,31339,N,20284,N,N, -20322,19830,N,N,28528,N,29758,N,21581,N,N,29496,N,N,N,26913,N,N,N,N,N,N,N,N,N, -29298,29547,N,28759,N,N,20311,N,N,N,N,N,N,20319,N,N,N,N,N,N,N,N,N,26688,26689, -N,N,N,20323,26914,N,N,N,N,N,N,N,N,N,N,20522,N,N,N,N,N,N,N,N,N,29505,20523,N, -21604,N,N,28476,22561,N,N,N,N,N,N,N,N,N,N,N,22879,N,29527,N,N,N,23613,N,19557, -28017,N,N,29026,N,21595,N,N,N,N,25141,N,N,19046,N,21294,N,N,N,N,N,N,19558,N,N, -29011,30055,N,N,N,N,19034,31598,N,24901,N,N,N,N,N,N,N,24425,N,28254,N,N,30530, -N,22562,N,N,N,N,N,23852,N,N,N,N,N,28719,22077,N,N,N,N,N,N,N,N,N,N,N,24875,N,N, -N,N,N,N,N,N,N,N,N,N,31030,N,N,21621,N,20553,28455,25196,N,23402,20044,30056, -30549,N,21325,N,29566,N,N,N,N,N,N,N,N,N,20533,N,N,N,N,N,N,N,N,N,N,N,24702,N, -24443,N,N,N,N,N,N,26205,N,N,N,N,N,N,N,26660,N,N,N,N,N,N,N,N,N,19277,N,N,N, -28456,N,N,N,28212,N,N,N,N,23128,20793,N,24361,N,N,29488,N,N,19524,N,N,N,20023, -N,N,N,N,N,N,N,N,N,N,N,28457,N,N,N,24405,N,N,27991,N,N,N,28230,N,N,N,N,N,N,N, -28477,31830,N,N,23412,N,28458,30777,N,30057,N,N,N,N,N,N,N,N,25433,N,N,N,N,N,N, -N,N,N,N,N,N,N,24902,N,N,N,21567,N,N,N,N,24168,28778,N,N,N,N,N,N,N,N,N,N,29506, -N,N,N,N,N,N,N,N,N,N,N,21295,N,N,19035,N,N,N,N,N,31831,N,N,27992,24903,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,29784,22067,23853,N,N,N,21822,N,N,N,N,N,N,N,N,28995, -28255,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22123,N,N,N,29785,N,N,N,N,N,N,N, -22374,N,N,N,N,N,N,23095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23931,N,N,N,N,N,23887,N, -N,N,N,N,N,N,N,22563,N,N,23129,N,28760,28484,N,N,N,N,N,N,24920,N,N,N,N,N,29012, -N,28018,N,N,N,N,N,N,21851,N,N,21852,29508,19287,N,N,N,N,N,25142,N,N,N,N,28529, -N,N,N,N,N,N,N,N,N,N,N,31573,N,N,N,N,N,N,N,N,N,N,N,21336,N,N,N,N,N,N,N,23888, -28761,19251,N,N,N,N,N,N,21853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19751,N,N, -20524,20794,N,28996,N,25907,31605,26977,32096,31804,N,23074,23075,N,21025,N,N, -21103,N,N,N,25197,N,N,24169,20060,29237,20580,23889,N,N,N,N,24904,23351,24419, -N,N,N,N,N,N,N,N,27961,28997,N,29519,22315,24876,N,N,25451,N,28231,N,N,N,24905, -19066,N,N,N,N,N,N,N,28795,31329,28762,19559,23156,N,N,N,N,N,N,N,N,N,19519,N,N, -N,N,N,N,N,N,N,N,N,N,N,20077,N,N,21801,31330,N,N,N,20581,N,27478,N,27743,N,N,N, -24444,N,N,30550,24170,19252,N,N,28478,N,N,19509,N,N,N,N,N,20285,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,28530,25143,N,N,N,19560,N,N,N,N,N,N,N,N,28796,N,N,N,22112,N, -28998,N,N,N,N,N,N,N,N,N,25144,27435,N,N,N,19253,22609,N,29774,29559,N,N,22342, -N,20795,30506,N,27978,22355,22650,N,N,N,N,N,N,N,30277,N,N,20812,23932,N,N,N,N, -N,N,N,N,N,N,24445,N,31077,N,24650,N,N,29309,21296,N,29811,23113,N,26206,N,N,N, -N,30778,26704,N,N,22651,N,N,27221,N,N,N,N,22051,N,N,N,N,N,N,30278,29275,25724, -N,N,N,N,N,N,N,N,N,N,26674,N,N,N,N,N,23130,N,29276,31574,26930,N,28205,N,31331, -N,N,N,N,N,N,N,23662,N,N,30058,26208,N,28797,N,N,N,N,N,22316,N,N,N,N,N,30021, -28256,N,N,23397,N,23902,N,N,22896,26915,N,N,N,N,N,N,N,N,N,N,29049,N,29252, -24651,N,N,N,N,N,N,N,N,26916,N,N,25145,N,N,N,N,N,N,N,25393,31851,19752,N,19510, -N,N,28763,N,N,N,N,N,N,N,N,26170,N,N,19753,N,N,N,N,N,29507,N,N,N,N,N,N,N,N,N, -24921,N,N,28459,N,N,N,26437,N,N,24681,N,29509,N,N,21568,21823,23854,N,31100,N, -19520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25890,N,N,N,20024,N,N,N,22610,31062,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28970,20049,N,N,30279,N,23403,N,24446,N, -N,22625,N,30579,N,22375,N,N,N,N,N,N,N,N,N,N,N,21630,N,N,20796,N,25935,N,19254, -N,23096,N,N,N,N,N,19780,N,N,N,N,N,22078,N,N,N,25146,N,N,N,N,N,20312,N,N,N, -24652,27513,N,N,N,N,N,N,N,N,32125,N,N,N,N,N,22376,19288,N,N,N,26978,N,N,N, -26682,N,N,N,25415,N,N,N,N,27725,N,27726,N,22079,N,N,N,25383,N,24406,32104,N,N, -N,N,N,N,N,N,N,28257,30248,23933,N,N,N,N,N,N,N,30779,N,26705,N,N,N,N,31063,N,N, -N,N,N,N,N,N,20078,N,N,27727,26917,22101,N,19781,N,27962,20797,N,N,20286,N,N, -27707,N,N,N,21041,N,N,N,N,19561,N,22852,27004,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,20798,N,N,N,N,N,27708,N,N,25901,N,N,N,N,N,N,30512,N,19562,N,N,N,21316, -N,N,22080,N,N,N,22141,N,N,N,N,N,N,N,N,N,N,N,24865,N,24125,N,30249,N,N,N,23076, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22052,30022,N,24866,26950,N,N,N,29253,N,N,N,N, -N,29801,22124,27475,N,N,N,N,27709,25180,24171,28764,N,27455,N,22350,20799,N,N, -N,N,N,N,N,N,N,29995,N,N,N,N,31101,N,19036,N,N,N,19782,29238,N,N,23934,N,N,N, -19511,23352,N,N,N,N,20585,N,20061,27456,N,32034,N,N,N,N,N,30795,N,N,N,N,N,N,N, -N,27222,28976,N,N,N,N,N,N,N,23374,N,30531,N,N,N,N,N,N,N,N,N,N,N,23375,19236,N, -N,30816,N,N,31575,N,N,27466,24609,N,N,N,N,N,N,N,N,N,N,N,20045,N,N,21596,N,N,N, -32088,N,N,N,N,21110,29239,N,N,31350,30250,31351,22630,N,29745,N,N,N,N,N,N,N,N, -N,N,N,N,N,26706,N,19013,19563,N,N,N,N,N,N,N,25198,N,N,N,N,N,25147,N,30509,N,N, -N,30817,N,N,N,N,N,N,N,N,N,29548,N,N,N,N,24097,N,N,N,N,N,N,N,N,N,N,N,N,25725,N, -N,25452,N,23855,23856,N,N,19255,26707,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24867, -21088,N,N,N,N,28798,N,N,N,N,26918,19314,N,N,N,N,N,N,28019,23641,24653,N,N,N,N, -30554,23353,N,N,N,N,N,N,N,19502,N,23131,N,N,N,N,19783,N,N,N,N,N,N,N,N,N,N, -23857,N,22575,25379,N,N,20079,N,N,29299,N,N,N,N,30771,N,N,N,N,N,N,N,N,N,N, -24654,N,30077,N,N,N,N,27500,N,N,21317,31852,21083,21611,N,24098,N,N,N,25958,N, -N,N,N,N,N,28720,N,N,N,N,N,N,N,N,N,N,21828,N,N,N,N,N,N,28020,N,N,N,25453,N, -26690,N,28021,22396,N,27963,N,N,30251,N,N,N,N,N,29240,30280,N,N,N,N,N,21350, -29277,20287,N,27436,20288,N,26152,32105,N,20289,N,24671,24172,N,N,N,N,24610,N, -N,N,N,N,N,N,N,29759,25199,N,22897,28999,N,19256,N,N,N,N,N,N,N,N,31102,23354, -23157,N,N,N,N,N,N,N,N,30316,23132,31332,N,24655,N,N,N,N,N,N,23858,N,N,N,N, -26153,N,28531,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29549,N,N,N,N,N,N,N,N,N,N, -27514,N,31078,N,N,N,N,N,N,N,19037,21854,N,19038,24420,N,N,N,26237,N,29996,N,N, -N,N,N,25717,N,N,N,N,N,N,N,N,N,N,N,N,26979,N,27979,20324,N,N,N,22611,N,N,N,N,N, -N,23859,21612,N,N,29241,N,24375,N,N,N,N,N,19278,31576,N,N,20569,N,N,23890, -30580,26460,25637,N,31779,N,23355,N,N,N,29242,27005,20554,N,30038,22853,25652, -N,27943,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27197,26238,N,30532,29997,N,22880,N, -N,N,18996,N,N,30818,20290,N,27710,N,N,N,25908,19784,28232,N,N,N,N,N,N,N,N,N, -26440,N,N,N,N,N,N,N,N,N,N,N,19785,31031,29032,22898,23413,18997,22854,N,N,N, -22601,N,N,N,N,N,N,N,N,N,N,N,N,N,22827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27964,N, -N,22612,N,N,N,23642,N,25148,N,N,31853,27744,21118,N,26951,26154,N,N,N,N,N,N, -25200,N,N,N,N,N,N,31291,N,29998,31530,N,N,N,N,27771,N,27711,31832,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21605,N,N,N,31043,N,N,N, -28258,N,N,N,N,N,N,N,N,N,N,N,N,N,22377,28022,N,N,N,24173,N,N,N,N,N,N,N,19564,N, -25454,N,N,N,N,N,26708,N,N,N,31352,N,N,N,N,N,N,23860,25653,22576,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,22613,N,N,N,29802,N,N,N,20025,N,N,N,22113,20306,N,20534,N, -N,N,N,N,N,20002,N,N,29550,N,N,N,N,N,29560,N,N,N,N,N,N,N,N,N,N,N,N,23628,N, -20555,N,N,N,31780,19786,22356,24099,N,25696,N,N,N,N,28233,N,N,N,25181,30078, -21548,N,N,N,N,N,21841,N,22640,30787,27223,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,30039,N,N,22591,N,N,N,N,32064,N,N,N,N,N,N,27437,N,N,N,N,21802, -N,N,N,N,N,N,N,N,N,N,N,26408,N,N,N,N,N,N,N,N,N,N,N,N,N,28234,N,N,N,19047,N,N,N, -N,N,30819,N,21597,N,N,27224,N,N,N,N,31577,28023,N,N,25909,N,N,N,N,N,20525,N,N, -N,N,29041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25149,N,N,N,25416,N,N,N,N, -22869,N,N,24362,N,N,N,N,23356,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30820,N,N,N,N,N, -29050,N,N,25910,29551,N,N,31578,24928,N,22828,N,30059,N,24630,N,N,26952,N, -19279,N,25417,N,N,N,24174,N,N,N,N,N,N,N,N,25150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,23663,N,22053,N,N,N,N,N,25201,N,N,N,N,N,N,N,22142,22817,N,22592,23643,N,N, -27965,24376,N,27173,N,N,N,22317,N,N,29561,N,28024,N,30023,N,N,N,N,N,N,24906, -27491,N,29278,N,N,N,N,N,N,N,N,N,N,N,N,N,30796,N,27225,N,21318,N,23398,N,N,N,N, -N,29999,N,N,N,N,20080,N,N,N,N,27006,N,N,N,N,N,31542,N,N,N,N,N,N,N,N,N,25202,N, -N,N,N,20338,30521,22899,N,N,24907,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -23133,N,N,23097,N,N,N,N,N,N,N,27515,N,19257,N,N,28025,N,N,N,N,N,N,24672,N,N,N, -N,N,N,N,N,N,N,29760,N,32060,24369,25455,N,N,N,N,24611,32057,N,N,N,N,N,N,N,N,N, -28721,N,N,N,N,N,N,19787,N,N,N,N,N,N,N,27966,N,N,N,21824,25456,28026,N,N,N,N,N, -26980,N,N,N,N,N,N,21869,26461,N,N,N,N,N,N,21622,25911,N,N,N,23399,25151,N,N,N, -N,N,N,N,N,N,N,N,N,28235,N,N,22388,28765,N,N,N,20011,26462,N,N,N,22102,24908,N, -N,26675,N,N,N,N,N,N,N,N,N,N,N,25966,23586,N,N,24656,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,21813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21793,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,31579,N,31051,N,N,N,19315,29733,N,N,N,N,N,31304,22103,N,26981,31580,N,N, -N,N,N,N,N,32080,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31606,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,23077,N,23357,N,N,N,N,N,N,27746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19831, -28766,N,N,N,N,30281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -24175,N,N,N,21297,N,N,N,N,N,N,N,N,31854,N,N,N,N,26691,N,29000,N,N,N,20081,N,N, -N,N,31085,N,N,N,N,N,N,N,N,29300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25654,30009,N, -23664,25457,N,N,N,N,26661,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29243,N,24100,N,23116, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,19049,N,N,N,N,N,N,25434,N,31833,N,N,N,N,N,N,N,27226,N,N,N, -N,N,N,31044,N,25380,N,N,N,N,N,N,N,N,N,N,N,31581,N,28490,N,26692,N,N,N,N,N,N,N, -N,N,21836,N,N,N,N,N,N,N,N,N,N,27479,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22829,N, -N,31531,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21337,N,N,N,N,N,N,21794,N,N,N,N,N,N,N, -N,N,30302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23158,N,N,N,N, -N,N,N,N,N,N,N,24657,N,N,26920,N,N,30073,N,N,N,N,N,N,31279,N,27516,N,N,24682, -25394,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21829,N,N,29027,21870, -N,N,N,N,N,N,N,N,N,N,N,N,N,19788,N,N,N,N,27993,N,N,N,N,22593,N,N,N,N,31340,N,N, -N,N,N,29035,N,N,N,N,N,31292,26210,N,N,N,N,31333,25210,N,N,N,18998,N,25655,N, -27227,N,30074,N,N,N,31532,20291,27517,N,N,N,N,30842,N,N,24377,N,N,N,N,24945,N, -21028,N,N,N,N,30075,N,N,N,N,N,N,20570,20571,N,27198,22833,N,N,N,N,N,18999,N,N, -21351,N,30821,N,N,N,N,21298,N,N,N,25152,29279,N,N,N,N,N,N,19813,N,N,N,N,N,N,N, -N,N,N,N,N,31020,N,N,N,N,N,N,N,N,19789,N,N,N,N,N,N,N,N,N,N,N,N,28206,22062,N,N, -N,N,N,N,N,N,N,N,N,N,22378,N,N,N,N,26464,27438,N,N,N,20313,N,N,23629,28027,N, -24176,N,22379,N,N,N,N,N,N,24101,N,N,N,N,N,N,N,N,N,N,24407,23376,23377,N,N, -21795,N,N,N,N,28722,23644,N,N,N,N,N,N,N,N,19048,N,30822,23630,N,N,N,N,27228, -23378,N,N,N,N,N,N,N,N,N,N,N,26931,N,N,N,N,30555,N,N,N,N,N,N,N,N,N,N,N,25384,N, -22318,N,N,24673,N,N,N,N,N,19258,N,N,25937,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,20572,N,N,N,N,21825,N,N,N,N,N,22602,N,N,N,N,N,N,N,25385,N,N,N, -N,N,N,N,N,N,N,N,N,24612,N,26921,N,21319,N,N,23645,30766,N,N,N,19512,N,N,N, -20526,N,N,N,22642,N,N,25418,N,N,N,N,N,N,N,N,N,N,19503,N,N,N,N,N,N,N,21549, -30289,N,N,N,N,N,N,N,20556,N,N,N,N,N,N,N,19014,N,N,21826,N,N,20026,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,19015,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31280,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,24408,N,N,N,30010,25963,N,28532,23861,N,N,N,N,19754,N, -25458,N,31607,N,30544,N,N,N,N,32058,N,N,32097,30334,20800,N,N,26693,N,25656,N, -24936,N,N,N,19521,N,21101,N,N,N,N,23358,N,N,24674,N,N,N,31305,N,N,24909,N, -19000,N,N,N,29280,29001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24177,N,N,N, -28767,30788,N,N,N,N,N,28236,N,N,24178,N,26441,N,25203,26465,N,N,25419,N,N, -25420,N,N,N,20344,28460,N,32126,31781,31281,24409,N,24658,N,N,N,29786,N,N,N,N, -N,N,N,N,N,N,N,29002,N,20003,N,N,N,N,29244,27747,N,N,N,N,N,24613,N,30507,N,N, -27439,N,N,N,N,N,25950,N,24868,19755,N,22900,26662,19790,24937,N,31855,N,24675, -N,N,N,N,N,25153,N,20004,N,N,N,N,N,N,24102,N,N,27518,N,27485,28768,N,N,29787,N, -25204,N,N,21320,N,N,N,29803,N,28213,N,30040,N,N,21855,N,N,N,22117,N,N,N,N, -27440,29795,N,N,N,N,25421,N,N,N,N,29812,31282,N,N,28533,19039,N,27441,27967,N, -N,32073,N,N,N,N,25638,31012,28723,N,25964,N,N,N,20839,22855,25687,27229,N, -21623,N,N,N,N,N,N,N,N,N,23098,N,23117,N,N,N,31052,N,24922,23359,N,19525,27728, -19259,N,24179,N,N,26922,N,N,N,N,N,N,N,22856,N,N,28259,22333,N,N,N,N,N,N,20292, -N,N,N,N,N,20557,N,N,N,N,N,N,N,31782,N,N,N,N,N,N,N,29051,N,N,N,N,32082,20801,N, -N,N,N,N,N,N,N,25435,N,21321,N,23631,N,N,N,N,N,N,N,N,N,19565,N,N,N,N,N,24103,N, -N,26171,27681,N,N,N,19513,N,N,31582,N,N,N,N,N,26466,N,N,21569,N,N,N,N,N,N,N,N, -N,23592,N,N,N,N,N,25154,N,29528,25939,N,N,29529,N,N,N,29510,19803,N,N,N,N,N,N, -N,19756,N,31811,N,N,N,N,21607,N,20802,N,31013,N,26709,N,N,N,N,N,N,N,N,25422,N, -N,N,N,21578,N,N,N,N,N,N,24410,N,N,N,N,N,N,N,N,31583,26467,N,N,N,N,N,N,N,N,N,N, -N,N,N,30843,25423,N,N,N,N,N,N,N,30000,N,N,N,N,N,N,N,22631,N,22857,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,30767,28534,N,23862,28207,19832,N,N,N,N,24120,31783,30588, -30513,20027,29729,N,N,28237,24878,N,N,27715,20350,N,30783,22626,21352,N,N, -24104,29796,27714,N,22901,31045,23891,22129,27772,31856,N,N,27968,19001,N, -28260,N,N,N,N,N,N,29281,N,24121,N,N,N,N,N,N,22130,N,24180,N,24411,N,23379,N, -31335,22627,29761,N,23863,N,N,N,29301,N,N,21550,N,N,N,N,N,N,22131,N,N,N,N,N,N, -23864,20293,24415,29246,30241,N,27467,29052,N,29511,N,N,24683,N,N,N,N,N,28028, -N,N,24923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,28261,N,24181,N,N,N,N,31315,N,N,N,N,29003,N,N,20527,23865,N,N,20803,N, -N,N,N,N,N,N,N,N,N,N,N,N,30001,N,N,N,N,27206,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28769, -N,N,N,N,N,N,N,N,N,30252,N,N,N,N,30041,N,N,N,N,N,N,N,N,N,N,28779,N,N,N,N,N,N, -23866,N,N,N,29247,N,N,N,N,N,N,N,30533,N,N,N,N,23330,29302,N,N,19002,N,N,N,N,N, -N,N,N,N,N,N,30581,N,19301,N,N,N,28262,N,24659,N,N,N,N,20005,N,N,N,N,N,N,22104, -N,N,N,21551,26953,N,N,N,N,21326,29762,N,N,N,N,N,N,N,N,N,N,N,N,N,19302,N,N,N,N, -N,N,N,N,N,N,N,28961,N,N,N,N,N,27442,N,N,N,N,28962,N,N,N,N,N,N,N,N,N,N,N,N, -27443,N,28724,N,N,19316,21552,29490,31543,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30060,N, -N,N,N,N,28263,29746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30061,N,20339,N,N,N, -N,N,N,N,N,N,N,28770,N,N,N,N,N,28238,N,N,29004,N,N,25912,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22389,25459,20325,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,20294,N,N,N,N,N,N,N,N,N,29491,25688,20345,20314,N,N,N,N,31309,N,N, -N,N,N,N,N,N,N,N,N,N,26211,N,N,N,N,N,N,N,N,N,N,N,29282,N,N,N,N,N,N,N,N,N,N,N,N, -30062,N,N,19003,N,N,25436,20082,N,22105,N,N,N,28208,N,N,N,N,N,N,N,N,29797, -22594,23632,19566,N,N,N,N,N,21856,30282,32074,22614,29775,N,N,N,N,N,N,22054, -23614,N,23380,22343,N,N,N,N,29310,N,N,N,29005,N,N,N,N,25155,23646,N,23647,N,N, -28461,26155,N,N,N,N,31069,27199,N,N,N,28462,N,N,N,29776,20083,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,26156,N,20062,N,N,21881,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25460, -19792,N,N,N,N,N,N,21816,N,N,30589,N,23593,N,N,N,N,24182,N,23594,29283,26932, -21084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26982,N,N,25462,N,N,N,N,N,N,N,N,26442,N,N, -20558,N,N,23159,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19004,N,N,N,28264,23134,N, -29303,N,N,25211,N,19494,N,N,N,N,23099,N,28265,N,N,N,30042,30556,24938,20033, -21553,N,32049,26173,N,31533,N,N,30823,N,24910,N,30562,30063,20295,N,N,21554, -19567,N,21608,N,28239,30551,N,N,24614,22081,24924,28771,29028,23665,22055,N,N, -N,N,N,N,N,N,N,N,29813,N,N,29006,29284,N,N,20528,N,N,27759,N,N,N,31034,N,27445, -N,N,21613,25156,N,N,N,N,26983,N,N,27444,27169,N,30780,20006,N,31046,31834,N, -21555,21305,27230,N,N,N,26923,N,N,24929,21327,29814,N,27200,24911,N,19514,N,N, -N,N,N,28266,N,N,N,28772,29492,21614,N,N,29248,N,N,29029,N,29763,24660,N,27446, -N,22305,19304,N,31021,26925,22628,31283,25157,31805,N,N,27716,22577,N,23595,N, -N,N,N,21796,N,27497,N,N,N,26683,N,N,N,22615,N,N,N,N,N,N,N,N,31534,20833,N,N, -23360,N,30014,N,24183,N,N,N,N,19067,30534,20296,N,N,N,24912,N,N,28240,N,N,N,N, -N,N,N,N,26996,N,N,N,N,N,N,N,N,20084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -21837,N,N,20315,N,N,N,N,N,N,23867,N,N,N,N,20012,N,N,N,N,N,N,N,26984,N,N,N,N,N, -N,N,21556,25671,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30043,N,N,31297,N,N,N,24105,N,N, -N,N,N,N,N,N,N,N,N,N,N,21624,N,N,N,N,N,28535,N,N,N,N,21299,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,27447,28536,30044,27980,23381,29007,N,N,N,29008,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,30002,N,N,N,N,N,N,22830,21804,N,25158,N,N,N,N,N,N,N,N, -32035,N,31589,24363,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25205,N,30253,N,30003,N,28725, -N,N,N,N,24869,N,N,N,N,N,N,N,N,N,30045,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27682,28029, -N,30004,31544,N,23331,N,N,22090,19289,N,N,N,N,N,N,N,N,N,N,25940,N,N,N,N,N,N, -29562,N,27448,N,24631,22380,29036,25903,21857,22381,20817,N,N,N,N,N,24946, -28537,N,N,N,23868,30300,N,N,N,N,N,28773,N,N,N,29764,N,N,26985,N,N,N,N,N,N,N,N, -N,N,29563,21615,N,N,19490,30590,24380,N,N,N,N,27469,N,N,N,N,N,N,20535,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22082,N,N,N,N,N,26669,N,N,N,N,28463,19237,N, -N,N,N,19305,N,N,N,31336,N,N,N,N,N,N,N,N,N,N,N,N,N,19526,N,N,N,26215,N,N,27207, -N,N,N,23332,N,20297,25212,28538,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,27486,N,N,30024,N,21598,N,N,N,N,N,N,N,N,N,N,N,24661,N,28464,N,N,25159,N, -22831,N,N,N,31079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26469,N,N,20298, -24913,N,25160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28539,N,N,31353,N,N,23666,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24615,N,N,N,N,N,30824,N,N,N,N,N,N,N,N,N,N,N,N, -N,19306,N,N,N,19260,22114,N,N,N,N,N,N,N,N,N,N,N,30046,N,N,N,N,N,N,N,30047,N, -28214,N,N,N,25206,21322,28540,20804,28465,N,20805,N,20574,N,22881,N,N,24632,N, -N,19793,29497,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26444,N,22056, -20007,N,21557,N,N,N,N,N,N,25672,N,N,N,N,N,N,21300,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,27449,N,N,N,N,N,N,19317,N,N,N,N,N,N,30301,N,28963,N,N,N,N,N,N,N,N,N,N, -N,N,N,19527,N,N,N,N,N,N,N,26954,N,24944,N,N,N,30048,N,N,N,N,N,N,N,N,31535,N,N, -N,19281,N,N,N,N,31584,29285,N,N,27760,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -28780,N,N,N,N,N,N,N,N,N,N,N,N,N,28267,N,N,N,N,N,N,N,N,N,N,N,N,26955,N,N,19568, -N,N,22319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29473,31861,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,28964,N,N,N,N,N,N,N,N,N,N,N,N,24662,N,N,N,N,N,28466,N,N,N,N,N, -N,N,N,N,29777,N,N,30497,N,N,N,N,N,N,N,N,N,N,N,29009,N,N,N,N,N,N,N,N,N,N,N,N, -19068,19069,N,N,N,N,N,N,N,N,20046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,29512,N,29498,28030,N,N,N,N,N,N,N,N,23078,N,N,24684,N,N, -N,N,N,30797,N,19282,N,N,N,27470,N,31064,31065,19040,23114,N,N,N,19238,N,N,N,N, -N,N,N,N,N,N,19016,31086,23404,N,N,20529,N,N,N,N,21871,N,N,N,26227,N,N,N,N,N,N, -N,N,N,26402,25689,N,N,N,N,N,N,N,N,N,N,25697,N,N,31812,N,N,N,N,N,N,N,N,N,31087, -20340,30566,N,N,N,N,N,20028,N,N,N,N,29765,23587,23869,N,N,N,N,29766,N,N,N,N,N, -N,N,N,30753,N,N,N,26710,N,N,N,23361,N,N,N,N,N,N,N,N,28774,N,N,N,25657,30317,N, -31022,N,23870,N,N,N,N,N,N,22320,22632,19261,N,N,31066,N,N,N,N,N,N,N,N,N,N, -30798,31088,24685,25395,29747,N,N,27202,29286,28726,N,N,N,N,N,23382,N,N,N,N,N, -27492,N,N,29287,N,22357,21558,31080,22337,N,N,N,N,25941,N,N,N,N,N,N,N,26986, -22348,N,N,N,21353,25161,N,31835,19757,N,N,N,N,N,19504,27170,N,N,25718,20544,N, -28727,28193,N,N,N,N,N,N,22390,N,N,N,25162,25163,N,31311,N,N,N,N,N,N,27487,N,N, -N,N,N,22091,N,N,N,29748,N,N,N,N,27981,25682,N,N,27177,25658,29474,19794,N, -30283,N,29030,27969,26684,28241,N,N,N,N,N,N,28775,25164,N,N,25642,N,30049, -27994,N,N,N,N,N,22382,20849,N,N,N,N,26987,26988,24676,N,N,N,N,23079,23892,N, -27171,N,N,N,22083,22132,N,23135,N,28467,25165,N,N,N,N,N,28541,29288,N,N,N,N,N, -N,N,N,N,28485,N,26471,N,N,22397,N,N,26446,N,N,24412,N,31047,N,N,N,N,N,N,N,N, -22902,N,N,N,N,N,N,N,N,24364,N,22106,N,N,N,N,N,N,23588,N,N,N,28728,N,N,N,N, -21882,N,25719,N,N,N,22084,N,N,N,N,N,N,N,N,29804,N,N,N,N,28542,N,N,N,N,N,28705, -N,24106,N,N,23100,22652,N,N,N,N,N,N,31316,N,N,N,27749,N,N,N,N,N,N,31784,N,N, -27750,N,N,22603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31545,N,25683,N,19833,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,20307,N,N,N,N,N,N,N,19050,N,N,20308,N,30781,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29767,N,N,N,N,27231,N,N,N,N,N,N,N,31067, -N,N,N,N,N,N,N,N,21559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27493,N,N, -24914,N,N,N,N,27172,N,N,N,31298,31585,31341,28706,19569,N,31267,25207,N,25166, -N,26997,N,24939,N,N,N,26472,26711,23160,21579,N,N,N,30582,22085,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,21609,N,N,31354,N,N,N,N,N,N,N,19570,30557,N,24122,N, -N,N,N,N,N,N,N,N,N,20008,N,N,N,N,N,28729,25726,25673,N,N,N,N,N,25684,N,N,N, -27203,N,28468,N,N,N,22334,N,N,N,N,N,N,31586,N,19795,N,N,N,28469,N,N,N,31337,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31014,N,N,N,N,N,N,24381,N,30535,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,30845,N,N,30844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -24107,23400,N,N,25437,N,24930,20806,N,N,N,N,N,N,N,N,N,N,30288,27494,23161,N,N, -N,N,27719,N,N,N,N,N,N,N,24184,30825,25438,20085,N,N,N,N,N,31299,25943,N,27720, -N,N,N,29513,N,N,25659,N,N,N,N,26158,N,N,N,N,N,28470,N,23615,N,N,N,N,N,N,N, -20029,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22595,N,N,N, -20559,N,20346,29514,24663,N,N,N,20807,26926,N,26685,N,N,31300,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25167,N,N,31301,N,N,N,31032,N,N,N,N,N,N,N,23648, -N,N,31536,N,N,N,22569,25951,31015,N,N,30318,N,30284,25208,N,N,N,N,27761,N,N,N, -N,N,N,N,23136,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29010,21068,20299,N,N,19005,N,N,N, -23871,N,N,N,30319,N,24185,N,N,N,N,N,N,N,N,N,N,N,N,N,31284,N,N,N,21805,N,N,N,N, -N,N,N,N,N,N,N,N,N,29031,24126,N,N,N,N,N,N,23616,N,N,N,N,N,20808,20809,N,N,N,N, -N,N,N,N,N,30782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19318,N,N,N,N,21625,N,N,N,N, -N,30050,24915,N,N,N,N,N,N,N,N,22633,N,N,30846,N,20300,N,N,N,N,N,N,N,32036,N,N, -N,N,N,N,N,20086,N,31312,N,N,19571,26174,N,N,N,30254,N,N,21872,N,N,20810,N,N,N, -31806,21873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19817,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,31285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25168, -29815,N,N,N,19796,N,N,N,N,N,N,N,N,N,N,N,N,26403,N,N,N,N,N,N,N,N,23333,25169,N, -N,N,N,N,N,N,N,N,N,N,N,22306,N,N,30563,N,N,N,N,N,N,27174,N,N,N,N,N,N,N,N,N,N, -20513,N,N,N,N,20058,31595,23334,23390,22629,N,N,N,N,N,N,N,N,N,27232,N,N,N,N, -22570,N,N,N,N,N,25952,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22107,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28486,N,N,30826,N,N,N,N,N,N, -N,N,N,N,N,N,N,25685,N,N,N,N,N,N,N,N,N,N,N,20087,N,N,24664,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22383,N,N,N,N,N,N,N,N,N,N,N,N,29805,N,N,N,N,N, -N,N,N,N,N,N,N,N,19814,N,N,N,19572,30051,N,N,25674,N,23649,N,N,31048,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,31807,N,N,N,N,N,N,N,N,N,N,N,N,26663,N,N,N,N,N,N,N,N,22596, -N,N,N,N,N,N,N,N,N,N,N,19262,N,23598,N,N,N,N,N,N,N,N,N,N,N,N,N,22391,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28776,N,23872,N,20301,N,N,N,N,N,N,N,N,N, -23667,22832,N,26217,25660,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27204,N,N,N,N,N,N, -N,N,N,N,25708,N,25701,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31608,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,19515,N,N,N,N,N,N,N,N,N,N,N,25661,N,N,19804,22903, -N,N,N,N,N,N,N,N,N,N,23903,N,N,N,N,N,27982,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22864, -N,N,N,N,N,25891,N,N,N,N,31053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19758,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,20302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,30255,N,N,N,N,N,32083,27501,22108,25892,N,N,N,21814,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22109, -N,N,N,31081,N,N,N,26404,N,22115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20811, -22116,N,N,N,21874,N,N,N,N,N,24186,N,22392,N,N,N,N,N,22634,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,20309,22653,N,N,N,N,N,22571,N,N,32075,N,N,N,N,31836,N,N,N,N,N,N,N,N,N, -24616,21875,N,N,32089,N,N,19491,N,N,N,22905,N,N,21354,30069,N,28487,N,N,N,N,N, -N,N,N,N,21338,N,N,N,N,N,N,N,N,N,N,N,23101,26664,23599,N,N,N,N,N,28707,N,N,N,N, -19797,N,N,N,N,N,N,N,N,N,N,N,N,24617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,24108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28730,28209,N,N,28210,N,N,N,30285, -N,N,N,N,N,N,N,N,N,N,N,N,28242,N,22086,N,N,N,N,N,24677,N,N,29499,N,25953,N,N,N, -N,N,N,N,N,N,N,25675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22307,N,N,23362, -N,N,N,N,19070,N,N,N,N,N,N,20303,12321,12322,33089,33090,12323,33091,33092, -12324,12325,12326,12327,33093,33094,33095,33096,33097,12328,12329,12330,12331, -12332,12333,12334,12335,33098,12336,12337,12338,12339,12340,33099,33100,12341, -33101,33102,33103,12342,33104,33105,33106,33107,33108,33109,33110,12343,12344, -33111,12345,12346,12347,33112,33113,33114,33121,33122,33123,12348,12349,33124, -33125,12350,33126,33127,33128,12351,33129,33130,33131,33132,33133,33134,33135, -33136,33137,33138,12352,33139,12353,33140,33141,33142,33143,33144,33145,12354, -33146,33153,33154,12355,33155,33156,33157,12356,33158,33159,33160,33161,33162, -33163,33164,33165,33166,33167,33168,33169,33170,33171,33172,33173,33174,33175, -33176,12357,12358,33177,33178,12359,33179,33180,12360,12361,33181,12362,33182, -33183,33184,33185,33186,12363,12364,33187,12365,12366,12367,12368,33188,33189, -12369,12370,12371,12372,33190,33191,33192,12373,33193,33194,33195,12374,33196, -33197,33198,33199,33200,33201,33202,12375,12376,33203,12377,12378,12379,33204, -33205,33206,33207,33208,33209,12380,12381,12382,33210,12383,33211,33212,12384, -12385,33213,33214,33215,33216,33217,33218,33219,12386,12387,33220,12388,12389, -12390,33221,33222,33223,12391,33224,33225,12392,33226,33227,33228,12393,33229, -33230,33231,12394,33232,33233,33234,33235,33236,33237,33238,33239,12395,33240, -12396,33241,33242,33243,33244,33245,33246,33247,33248,12397,12398,33249,33250, -12399,33251,33252,12400,12401,33253,12402,33254,12403,33255,33256,12404,12405, -12406,33257,12407,33258,12408,12409,33259,33260,33261,33262,33263,12410,12411, -33264,33265,12412,33266,33267,33268,12413,33269,12414,33270,33271,33272,33273, -33274,12577,12578,33275,12579,33276,12580,33277,33278,33345,33346,33347,33348, -12581,33349,33350,33351,12582,33352,33353,33354,12583,33355,33356,33357,33358, -33359,33360,33361,33362,12584,33363,33364,12585,12586,33365,33366,33367,33368, -33369,33370,12587,12588,33377,33378,12589,33379,33380,33381,12590,33382,33383, -33384,33385,33386,33387,33388,12591,12592,33389,12593,33390,12594,33391,33392, -33393,33394,33395,33396,12595,33397,33398,33399,12596,33400,33401,33402,12597, -33409,33410,33411,33412,33413,33414,33415,33416,12598,33417,12599,33418,33419, -33420,33421,33422,33423,33424,33425,12600,12601,33426,33427,12602,33428,33429, -12603,12604,12605,12606,33430,33431,33432,33433,12607,12608,12609,33434,12610, -33435,12611,12612,33436,33437,33438,33439,33440,12613,12614,33441,33442,12615, -33443,33444,33445,12616,33446,33447,33448,33449,33450,33451,33452,33453,33454, -33455,33456,12617,12618,33457,33458,33459,33460,33461,33462,12619,33463,33464, -33465,33466,33467,33468,33469,33470,33471,33472,33473,33474,33475,33476,33477, -33478,33479,33480,12620,33481,33482,33483,33484,33485,33486,33487,33488,12621, -12622,33489,33490,12623,33491,33492,33493,12624,33494,33495,33496,33497,33498, -33499,33500,12625,12626,33501,12627,33502,33503,33504,33505,33506,33507,33508, -33509,12628,33510,33511,33512,12629,33513,33514,33515,12630,33516,33517,33518, -33519,33520,33521,33522,33523,33524,33525,33526,33527,33528,33529,33530,33531, -33532,33533,33534,12631,12632,33601,33602,12633,33603,33604,12634,12635,12636, -33605,33606,33607,33608,33609,33610,12637,12638,33611,12639,33612,12640,33613, -33614,33615,33616,33617,33618,12641,33619,33620,33621,33622,33623,33624,33625, -33626,33633,33634,33635,33636,33637,33638,33639,33640,33641,33642,33643,33644, -33645,33646,33647,33648,33649,33650,33651,12642,12643,33652,33653,12644,33654, -33655,12645,12646,33656,12647,33657,33658,33665,33666,33667,12648,12649,33668, -12650,33669,12651,12652,33670,33671,33672,12653,33673,12654,12655,12656,33674, -12657,33675,33676,33677,12658,33678,12659,33679,33680,33681,33682,33683,12660, -12661,33684,12662,12663,12664,33685,33686,33687,12665,33688,33689,12666,12667, -33690,33691,12668,33692,33693,33694,12669,33695,33696,33697,33698,33699,33700, -33701,12670,12833,33702,12834,12835,12836,33703,33704,33705,33706,33707,33708, -12837,12838,33709,33710,33711,33712,33713,33714,12839,33715,33716,33717,33718, -33719,33720,33721,33722,33723,33724,33725,33726,33727,33728,33729,33730,33731, -33732,33733,33734,33735,33736,33737,33738,33739,33740,33741,33742,33743,33744, -33745,33746,33747,33748,33749,33750,33751,33752,33753,33754,33755,33756,33757, -33758,33759,33760,33761,12840,12841,12842,33762,12843,33763,33764,33765,12844, -33766,33767,33768,33769,33770,33771,33772,12845,12846,33773,12847,12848,12849, -33774,33775,33776,33777,33778,33779,12850,12851,33780,33781,12852,33782,33783, -33784,33785,33786,33787,33788,33789,33790,33857,33858,12853,33859,33860,12854, -33861,12855,33862,33863,33864,33865,33866,33867,12856,33868,33869,33870,12857, -33871,33872,33873,12858,33874,33875,33876,33877,33878,33879,33880,33881,33882, -33889,12859,12860,33890,33891,33892,33893,12861,33894,33895,12862,33896,33897, -33898,33899,33900,33901,33902,33903,33904,33905,33906,33907,33908,33909,33910, -33911,33912,33913,33914,33921,33922,33923,33924,33925,33926,33927,33928,12863, -12864,33929,33930,12865,33931,12866,33932,12867,33933,33934,33935,33936,33937, -33938,33939,12868,12869,33940,12870,33941,12871,12872,12873,33942,33943,33944, -33945,12874,12875,33946,33947,33948,33949,33950,33951,12876,33952,33953,33954, -33955,33956,33957,33958,33959,33960,33961,33962,12877,12878,33963,33964,33965, -33966,33967,33968,12879,12880,33969,33970,33971,33972,33973,33974,33975,33976, -33977,33978,33979,33980,33981,33982,33983,33984,33985,33986,33987,12881,33988, -33989,33990,33991,33992,33993,12882,33994,33995,33996,12883,33997,33998,33999, -12884,34000,34001,34002,34003,34004,34005,34006,12885,12886,34007,34008,34009, -12887,34010,34011,34012,34013,34014,34015,12888,34016,34017,34018,34019,34020, -34021,34022,34023,34024,34025,34026,34027,34028,34029,34030,34031,34032,34033, -34034,34035,34036,34037,34038,34039,34040,34041,34042,12889,12890,34043,34044, -12891,34045,34046,34113,12892,34114,34115,34116,34117,34118,34119,12893,12894, -12895,34120,12896,34121,12897,12898,34122,34123,34124,34125,34126,12899,34127, -34128,34129,34130,34131,34132,34133,12900,34134,34135,34136,34137,34138,34145, -34146,34147,34148,34149,34150,12901,12902,34151,34152,34153,34154,34155,34156, -12903,12904,34157,34158,12905,34159,34160,34161,12906,34162,34163,34164,34165, -34166,34167,34168,12907,12908,34169,34170,12909,34177,34178,34179,34180,34181, -34182,34183,12910,34184,34185,34186,12911,34187,34188,34189,12912,34190,34191, -34192,34193,34194,34195,34196,12913,12914,34197,34198,34199,34200,34201,34202, -34203,34204,34205,34206,12915,34207,34208,34209,34210,34211,34212,34213,34214, -34215,34216,34217,34218,34219,34220,34221,34222,34223,34224,34225,34226,34227, -34228,34229,34230,34231,34232,34233,12916,12917,34234,34235,12918,34236,12919, -34237,12920,34238,12921,34239,34240,34241,34242,12922,12923,12924,34243,12925, -34244,12926,34245,34246,34247,13089,34248,34249,34250,34251,34252,34253,34254, -34255,34256,34257,34258,34259,34260,34261,34262,34263,34264,34265,34266,34267, -34268,34269,34270,34271,34272,34273,34274,34275,34276,34277,13090,13091,34278, -34279,13092,34280,34281,34282,13093,34283,34284,34285,34286,34287,34288,34289, -13094,13095,34290,13096,34291,13097,34292,34293,34294,34295,34296,34297,13098, -13099,13100,34298,13101,34299,34300,13102,13103,13104,13105,34301,34302,34369, -34370,34371,13106,13107,34372,13108,13109,13110,13111,13112,34373,13113,34374, -13114,13115,13116,34375,34376,13117,34377,34378,34379,13118,34380,34381,34382, -34383,34384,34385,34386,13119,13120,34387,13121,13122,13123,34388,34389,34390, -34391,34392,34393,13124,13125,34394,34401,13126,34402,34403,34404,13127,34405, -34406,34407,34408,34409,34410,34411,13128,34412,34413,34414,34415,13129,34416, -34417,34418,34419,34420,34421,34422,34423,34424,34425,34426,34433,34434,34435, -34436,34437,34438,34439,34440,34441,34442,34443,34444,34445,34446,34447,34448, -34449,34450,34451,34452,34453,34454,34455,13130,13131,34456,13132,13133,34457, -34458,34459,13134,34460,13135,13136,34461,34462,34463,34464,13137,13138,34465, -13139,13140,13141,34466,34467,34468,34469,34470,13142,13143,13144,34471,34472, -13145,34473,34474,34475,13146,34476,34477,34478,34479,34480,34481,34482,13147, -13148,34483,13149,13150,13151,34484,34485,34486,34487,34488,34489,13152,13153, -34490,34491,13154,34492,34493,34494,13155,34495,34496,34497,34498,34499,34500, -34501,13156,13157,34502,34503,13158,13159,34504,34505,13160,34506,34507,34508, -13161,34509,34510,34511,13162,34512,34513,34514,34515,34516,34517,34518,34519, -34520,34521,34522,34523,34524,34525,34526,34527,34528,34529,34530,34531,34532, -34533,34534,13163,13164,34535,34536,13165,34537,34538,34539,13166,34540,13167, -34541,34542,34543,34544,34545,13168,13169,34546,13170,34547,13171,34548,34549, -34550,34551,13172,13173,13174,34552,34553,34554,13175,34555,34556,34557,13176, -34558,34625,34626,34627,34628,34629,34630,34631,34632,34633,34634,13177,34635, -34636,34637,34638,34639,34640,34641,34642,34643,34644,34645,34646,34647,34648, -34649,34650,34657,34658,34659,34660,34661,34662,34663,34664,34665,34666,34667, -34668,34669,34670,34671,34672,34673,34674,34675,13178,34676,34677,34678,13179, -34679,34680,34681,13180,34682,34689,34690,34691,34692,34693,34694,13181,13182, -34695,13345,34696,34697,34698,34699,34700,34701,34702,34703,13346,13347,34704, -34705,13348,34706,34707,34708,13349,34709,34710,34711,34712,34713,34714,34715, -34716,13350,34717,13351,34718,13352,34719,34720,34721,34722,34723,34724,13353, -13354,34725,34726,13355,34727,34728,13356,13357,34729,34730,34731,34732,34733, -34734,34735,13358,13359,34736,13360,34737,13361,34738,34739,34740,34741,34742, -34743,13362,34744,34745,34746,34747,34748,34749,34750,34751,34752,34753,34754, -34755,34756,34757,34758,34759,34760,34761,34762,13363,34763,34764,34765,34766, -34767,34768,34769,13364,34770,34771,34772,34773,34774,34775,34776,34777,34778, -34779,34780,34781,34782,34783,34784,34785,34786,34787,34788,34789,34790,34791, -34792,34793,34794,34795,34796,13365,34797,34798,34799,13366,34800,34801,34802, -13367,34803,34804,34805,34806,34807,34808,34809,13368,13369,34810,34811,34812, -34813,34814,34881,34882,34883,34884,34885,13370,13371,34886,34887,34888,34889, -34890,34891,13372,34892,34893,34894,34895,34896,34897,34898,13373,13374,34899, -34900,34901,13375,34902,34903,34904,34905,34906,34913,13376,13377,34914,34915, -13378,34916,34917,34918,13379,13380,13381,34919,34920,34921,34922,34923,13382, -13383,34924,13384,34925,13385,13386,34926,34927,34928,13387,34929,13388,34930, -34931,34932,13389,34933,34934,34935,13390,34936,34937,34938,34945,34946,34947, -34948,34949,34950,34951,34952,34953,34954,34955,34956,34957,34958,34959,34960, -13391,13392,34961,34962,13393,34963,34964,34965,13394,34966,13395,34967,34968, -34969,34970,34971,13396,13397,34972,13398,34973,13399,34974,34975,34976,34977, -13400,34978,13401,13402,13403,34979,13404,34980,34981,13405,13406,13407,13408, -13409,34982,34983,34984,13410,13411,13412,34985,13413,13414,13415,13416,13417, -34986,34987,34988,13418,13419,13420,34989,34990,13421,34991,34992,34993,13422, -34994,34995,34996,34997,34998,34999,35000,13423,13424,35001,13425,13426,13427, -35002,35003,35004,35005,35006,35007,13428,35008,35009,35010,35011,35012,35013, -35014,35015,35016,35017,35018,35019,35020,35021,35022,35023,35024,35025,35026, -35027,35028,35029,35030,35031,35032,35033,35034,35035,35036,35037,35038,35039, -35040,35041,35042,35043,35044,35045,35046,35047,35048,35049,35050,35051,35052, -35053,35054,35055,35056,35057,35058,35059,35060,35061,35062,13429,13430,13431, -35063,13432,35064,35065,13433,13434,35066,13435,13436,35067,35068,35069,35070, -13437,13438,35137,13601,35138,13602,35139,13603,35140,35141,13604,35142,13605, -13606,35143,35144,13607,35145,35146,35147,13608,35148,35149,35150,35151,35152, -35153,35154,13609,13610,35155,13611,13612,13613,35156,35157,35158,35159,35160, -35161,13614,35162,35169,35170,13615,35171,35172,35173,13616,35174,35175,35176, -35177,35178,35179,35180,35181,35182,35183,35184,13617,13618,35185,35186,35187, -35188,35189,35190,13619,35191,35192,35193,13620,35194,35201,35202,35203,35204, -35205,35206,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217, -35218,35219,35220,35221,35222,13621,13622,35223,35224,13623,35225,35226,13624, -13625,35227,13626,35228,13627,35229,35230,35231,13628,13629,35232,13630,35233, -13631,35234,13632,35235,13633,35236,35237,13634,35238,35239,35240,13635,35241, -35242,35243,13636,35244,35245,35246,35247,35248,35249,35250,35251,35252,35253, -35254,35255,35256,35257,35258,35259,35260,35261,35262,13637,35263,35264,35265, -35266,35267,35268,35269,35270,35271,35272,35273,35274,35275,35276,35277,35278, -35279,35280,35281,13638,35282,35283,35284,35285,35286,35287,35288,13639,35289, -35290,35291,13640,35292,35293,35294,13641,35295,35296,35297,35298,35299,35300, -35301,13642,13643,35302,13644,35303,35304,35305,35306,35307,35308,35309,35310, -13645,35311,35312,35313,35314,35315,35316,35317,35318,35319,35320,35321,35322, -35323,35324,35325,35326,35393,35394,35395,35396,35397,35398,35399,35400,35401, -35402,35403,13646,13647,35404,35405,13648,35406,35407,35408,13649,35409,35410, -35411,35412,35413,35414,35415,13650,13651,35416,13652,35417,13653,35418,35425, -35426,35427,35428,35429,13654,35430,35431,35432,35433,35434,35435,35436,35437, -35438,35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,13655,35449, -35450,35457,35458,35459,35460,35461,13656,35462,35463,35464,35465,35466,35467, -35468,35469,35470,35471,35472,35473,35474,35475,35476,35477,35478,35479,35480, -35481,13657,35482,35483,35484,35485,35486,35487,13658,35488,35489,35490,13659, -35491,35492,35493,13660,35494,35495,35496,35497,35498,35499,35500,35501,13661, -35502,13662,35503,13663,35504,35505,35506,35507,35508,35509,13664,35510,35511, -35512,13665,35513,35514,35515,13666,35516,35517,35518,35519,35520,35521,35522, -13667,35523,35524,35525,35526,13668,35527,35528,35529,35530,35531,35532,13669, -13670,35533,35534,13671,35535,35536,13672,13673,35537,13674,35538,35539,35540, -35541,35542,13675,13676,35543,13677,35544,13678,35545,35546,35547,35548,35549, -35550,13679,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,35561, -35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,35574, -35575,35576,35577,13680,13681,35578,35579,13682,35580,35581,13683,13684,35582, -35649,35650,35651,35652,35653,35654,13685,13686,35655,13687,13688,13689,13690, -35656,35657,35658,35659,35660,13691,13692,35661,35662,13693,35663,35664,35665, -13694,35666,35667,35668,35669,35670,35671,35672,13857,13858,35673,13859,13860, -13861,35674,35681,35682,35683,35684,13862,13863,13864,35685,35686,13865,35687, -35688,35689,13866,35690,35691,35692,35693,35694,35695,35696,13867,13868,35697, -13869,13870,13871,35698,35699,35700,35701,35702,35703,35704,35705,35706,35713, -35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,35725,35726, -35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,35738,35739, -35740,35741,35742,35743,35744,35745,35746,35747,35748,35749,35750,35751,35752, -35753,35754,35755,35756,35757,35758,35759,35760,35761,35762,35763,35764,35765, -13872,13873,35766,35767,13874,35768,35769,35770,13875,35771,13876,13877,35772, -35773,35774,35775,13878,13879,35776,13880,13881,13882,35777,35778,35779,35780, -35781,13883,13884,13885,35782,35783,13886,35784,35785,35786,13887,35787,35788, -35789,35790,35791,35792,35793,13888,13889,35794,13890,13891,13892,35795,35796, -35797,35798,35799,35800,13893,35801,35802,35803,35804,35805,35806,35807,35808, -35809,35810,35811,35812,35813,35814,35815,35816,35817,35818,35819,13894,35820, -35821,35822,35823,35824,35825,35826,35827,35828,35829,35830,35831,35832,35833, -35834,35835,35836,35837,35838,35905,35906,35907,35908,35909,35910,35911,35912, -35913,35914,35915,35916,35917,35918,35919,35920,13895,13896,35921,35922,13897, -35923,35924,35925,13898,35926,35927,35928,35929,35930,35937,35938,35939,35940, -35941,35942,35943,13899,35944,35945,35946,35947,35948,35949,13900,35950,35951, -35952,35953,35954,35955,35956,13901,35957,35958,35959,35960,35961,35962,35969, -35970,35971,35972,35973,35974,35975,35976,35977,35978,35979,35980,35981,13902, -35982,35983,35984,35985,35986,35987,35988,35989,35990,35991,35992,35993,35994, -35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,36005,36006,36007, -36008,13903,36009,36010,36011,13904,36012,36013,36014,36015,36016,36017,36018, -36019,36020,36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031, -36032,36033,36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044, -36045,36046,36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057, -36058,36059,36060,36061,36062,13905,13906,36063,36064,13907,36065,36066,36067, -13908,36068,36069,36070,36071,36072,36073,13909,13910,36074,36075,36076,36077, -13911,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089, -36090,36091,36092,36093,36094,36161,36162,36163,36164,36165,36166,36167,36168, -36169,36170,36171,36172,36173,36174,36175,36176,36177,13912,36178,36179,36180, -36181,36182,36183,36184,36185,36186,36193,36194,36195,36196,36197,36198,36199, -36200,36201,36202,36203,36204,36205,36206,36207,36208,36209,36210,13913,36211, -36212,36213,13914,36214,36215,36216,13915,36217,36218,36225,36226,36227,36228, -36229,13916,13917,36230,36231,36232,13918,36233,36234,36235,36236,36237,36238, -36239,36240,36241,36242,36243,36244,36245,36246,36247,36248,36249,36250,36251, -36252,36253,36254,36255,36256,36257,36258,36259,36260,36261,36262,36263,36264, -36265,36266,13919,13920,36267,36268,13921,36269,36270,13922,13923,36271,36272, -36273,36274,36275,36276,36277,13924,13925,36278,13926,36279,36280,36281,36282, -36283,36284,36285,36286,13927,36287,36288,36289,13928,36290,36291,36292,13929, -36293,36294,36295,36296,36297,36298,36299,13930,13931,36300,36301,36302,36303, -36304,36305,36306,36307,36308,36309,13932,36310,36311,36312,13933,36313,36314, -36315,13934,36316,36317,36318,36319,36320,36321,36322,13935,13936,36323,13937, -36324,13938,36325,36326,36327,36328,36329,36330,13939,13940,36331,36332,13941, -36333,36334,36335,13942,36336,36337,36338,36339,36340,36341,36342,13943,13944, -36343,13945,13946,13947,13948,36344,36345,36346,13949,13950,14113,14114,36347, -36348,14115,36349,36350,36417,14116,36418,36419,36420,36421,36422,36423,36424, -14117,14118,36425,14119,14120,14121,36426,36427,36428,36429,36430,36431,14122, -14123,36432,36433,14124,36434,36435,36436,36437,36438,36439,36440,36441,36442, -36449,36450,36451,36452,36453,14125,36454,14126,36455,36456,36457,36458,36459, -36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,36471,36472, -36473,36474,36481,36482,36483,36484,36485,36486,36487,36488,36489,36490,36491, -36492,36493,36494,14127,14128,36495,36496,14129,36497,36498,36499,14130,36500, -36501,36502,36503,36504,36505,36506,14131,14132,36507,14133,14134,14135,36508, -36509,36510,36511,36512,14136,14137,14138,36513,36514,14139,36515,36516,36517, -14140,36518,36519,36520,36521,36522,36523,36524,14141,14142,36525,14143,36526, -14144,36527,36528,36529,36530,36531,36532,14145,14146,36533,36534,14147,36535, -36536,36537,14148,36538,36539,36540,36541,36542,36543,36544,14149,14150,36545, -14151,14152,14153,36546,36547,36548,36549,36550,36551,14154,36552,36553,36554, -14155,36555,36556,36557,36558,36559,36560,36561,36562,36563,36564,36565,36566, -14156,36567,14157,36568,36569,36570,36571,36572,36573,36574,36575,14158,14159, -36576,36577,14160,36578,36579,36580,14161,36581,36582,36583,36584,36585,36586, -36587,14162,14163,36588,14164,36589,14165,36590,36591,36592,36593,36594,36595, -14166,36596,36597,36598,14167,36599,36600,36601,36602,36603,36604,36605,36606, -36673,36674,36675,36676,36677,36678,36679,36680,14168,36681,36682,36683,36684, -36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697, -36698,36705,36706,36707,36708,36709,36710,36711,36712,14169,36713,36714,36715, -36716,36717,36718,36719,14170,36720,36721,36722,14171,36723,36724,36725,14172, -36726,36727,36728,36729,36730,36737,36738,14173,14174,36739,14175,36740,14176, -36741,36742,36743,36744,36745,36746,14177,36747,36748,36749,14178,36750,36751, -36752,14179,36753,36754,36755,36756,36757,36758,36759,36760,14180,36761,14181, -36762,14182,36763,36764,36765,36766,36767,36768,14183,14184,36769,36770,14185, -36771,36772,36773,14186,36774,36775,36776,36777,36778,36779,36780,14187,14188, -36781,14189,36782,14190,36783,36784,36785,36786,36787,36788,14191,36789,36790, -36791,36792,36793,36794,36795,36796,36797,36798,36799,36800,36801,36802,36803, -36804,36805,36806,36807,14192,36808,36809,36810,36811,36812,36813,36814,14193, -36815,36816,36817,36818,36819,36820,36821,36822,36823,36824,36825,36826,36827, -36828,36829,36830,36831,36832,36833,36834,36835,36836,36837,36838,36839,36840, -36841,14194,14195,36842,36843,14196,36844,36845,36846,14197,36847,36848,36849, -36850,36851,36852,36853,14198,36854,36855,14199,36856,14200,36857,36858,36859, -36860,36861,36862,14201,14202,36929,36930,14203,36931,36932,36933,14204,36934, -36935,36936,36937,36938,36939,36940,14205,14206,36941,14369,36942,14370,36943, -36944,36945,36946,36947,36948,14371,14372,36949,36950,14373,36951,36952,36953, -14374,36954,36961,36962,36963,36964,36965,36966,14375,14376,36967,14377,36968, -14378,14379,36969,36970,14380,14381,36971,36972,36973,36974,36975,36976,36977, -36978,36979,36980,36981,36982,36983,36984,36985,36986,36993,36994,36995,36996, -36997,36998,36999,37000,37001,37002,37003,37004,37005,14382,14383,37006,37007, -14384,37008,37009,37010,14385,37011,37012,37013,37014,37015,37016,37017,14386, -14387,37018,14388,37019,14389,37020,37021,37022,37023,37024,37025,14390,14391, -37026,37027,14392,37028,14393,14394,14395,14396,14397,37029,37030,37031,37032, -37033,14398,14399,37034,14400,37035,14401,14402,37036,37037,14403,37038,14404, -14405,14406,37039,37040,14407,37041,37042,37043,14408,37044,37045,37046,37047, -37048,37049,37050,14409,14410,37051,14411,14412,14413,14414,37052,37053,37054, -37055,37056,14415,14416,37057,37058,37059,37060,37061,37062,14417,37063,37064, -37065,37066,37067,37068,37069,37070,37071,37072,37073,37074,14418,37075,37076, -37077,37078,37079,37080,37081,37082,37083,37084,37085,37086,37087,37088,37089, -37090,37091,37092,37093,37094,37095,37096,37097,37098,37099,37100,37101,37102, -37103,37104,37105,37106,37107,37108,14419,14420,37109,37110,14421,37111,37112, -37113,14422,37114,14423,37115,37116,37117,37118,37185,14424,14425,37186,14426, -37187,14427,14428,37188,37189,37190,37191,14429,14430,14431,37192,37193,14432, -37194,37195,37196,14433,37197,37198,37199,37200,37201,37202,37203,14434,14435, -37204,14436,14437,14438,37205,37206,37207,37208,37209,37210,14439,14440,37217, -37218,14441,37219,37220,37221,14442,37222,37223,37224,37225,37226,37227,37228, -37229,37230,37231,14443,14444,14445,37232,14446,37233,37234,37235,37236,14447, -37237,37238,37239,37240,37241,37242,37249,37250,37251,37252,37253,37254,37255, -37256,37257,37258,37259,37260,37261,37262,37263,37264,37265,37266,37267,37268, -37269,14448,14449,37270,14450,14451,37271,37272,37273,14452,37274,14453,37275, -37276,37277,37278,37279,14454,14455,37280,14456,37281,14457,37282,37283,37284, -37285,37286,37287,14458,37288,37289,37290,14459,37291,37292,37293,37294,37295, -37296,37297,37298,37299,37300,37301,37302,37303,37304,37305,14460,14461,37306, -37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,37318,37319, -37320,37321,37322,37323,37324,37325,37326,37327,37328,37329,37330,37331,37332, -37333,37334,37335,37336,37337,37338,37339,14462,37340,37341,37342,14625,37343, -37344,37345,14626,37346,37347,37348,37349,37350,37351,37352,37353,14627,37354, -14628,37355,14629,37356,37357,37358,37359,37360,37361,14630,37362,37363,37364, -14631,37365,37366,37367,14632,37368,37369,37370,37371,37372,37373,37374,37441, -14633,37442,14634,37443,37444,37445,37446,37447,37448,37449,37450,14635,14636, -14637,37451,14638,37452,37453,14639,14640,14641,14642,37454,37455,37456,37457, -37458,14643,14644,37459,14645,37460,14646,37461,37462,37463,14647,37464,14648, -14649,37465,37466,37473,14650,37474,37475,37476,14651,37477,37478,37479,37480, -37481,37482,37483,37484,14652,37485,14653,37486,37487,37488,37489,37490,37491, -37492,37493,14654,37494,37495,37496,37497,37498,37505,37506,37507,37508,37509, -37510,37511,37512,37513,37514,37515,37516,37517,37518,37519,37520,37521,37522, -37523,37524,37525,37526,14655,37527,37528,37529,14656,37530,37531,37532,14657, -37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,37544,37545, -37546,37547,37548,37549,37550,37551,14658,37552,37553,37554,14659,37555,37556, -37557,14660,37558,37559,37560,37561,37562,37563,37564,14661,37565,37566,14662, -37567,37568,37569,37570,37571,37572,37573,37574,14663,37575,37576,37577,14664, -37578,37579,37580,14665,37581,37582,37583,37584,37585,37586,37587,14666,37588, -37589,14667,37590,37591,37592,37593,37594,37595,37596,37597,37598,37599,37600, -37601,37602,37603,37604,37605,37606,37607,37608,37609,37610,37611,37612,37613, -37614,37615,37616,37617,37618,37619,37620,37621,37622,37623,37624,37625,14668, -14669,37626,37627,14670,37628,37629,14671,14672,37630,14673,37697,37698,37699, -37700,37701,14674,14675,37702,14676,14677,14678,37703,14679,37704,14680,37705, -37706,14681,14682,14683,14684,14685,37707,37708,14686,14687,14688,14689,14690, -37709,37710,37711,37712,14691,14692,37713,14693,37714,14694,37715,37716,37717, -14695,37718,37719,14696,14697,37720,37721,14698,37722,37729,37730,14699,37731, -37732,37733,37734,37735,37736,37737,14700,14701,37738,14702,14703,14704,37739, -37740,37741,14705,37742,37743,14706,14707,37744,37745,14708,37746,37747,37748, -37749,37750,37751,37752,37753,37754,37761,37762,37763,14709,37764,37765,37766, -37767,37768,37769,37770,37771,37772,37773,37774,37775,37776,37777,37778,37779, -37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792, -37793,37794,37795,37796,37797,37798,37799,37800,37801,14710,14711,37802,37803, -14712,37804,37805,14713,14714,37806,14715,37807,37808,37809,37810,37811,14716, -14717,37812,14718,37813,14881,14882,37814,37815,37816,37817,37818,14883,14884, -37819,37820,14885,37821,37822,14886,14887,37823,37824,37825,37826,37827,37828, -37829,14888,14889,37830,14890,14891,14892,37831,37832,37833,37834,37835,37836, -14893,14894,37837,37838,14895,37839,37840,37841,14896,37842,37843,37844,37845, -37846,37847,37848,37849,14897,37850,14898,14899,14900,37851,37852,37853,14901, -37854,37855,14902,37856,37857,37858,14903,37859,37860,37861,37862,37863,37864, -37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877, -37878,37879,37880,37881,14904,14905,14906,37882,14907,37883,37884,37885,14908, -37886,37953,37954,37955,37956,37957,37958,14909,14910,37959,14911,37960,14912, -37961,37962,37963,37964,37965,37966,14913,37967,37968,37969,14914,37970,37971, -37972,37973,37974,37975,37976,37977,37978,37985,37986,37987,37988,37989,37990, -14915,37991,37992,37993,37994,37995,37996,37997,14916,37998,37999,38000,38001, -38002,38003,38004,38005,38006,38007,38008,38009,38010,38017,38018,38019,38020, -38021,38022,14917,38023,38024,38025,38026,38027,38028,38029,14918,14919,38030, -38031,14920,38032,38033,38034,14921,38035,38036,38037,38038,38039,38040,38041, -14922,14923,38042,38043,38044,38045,38046,38047,38048,38049,38050,38051,14924, -38052,38053,38054,14925,38055,38056,38057,38058,38059,38060,38061,38062,38063, -38064,38065,38066,38067,38068,38069,38070,38071,38072,38073,38074,38075,38076, -38077,14926,14927,38078,38079,14928,38080,38081,14929,14930,14931,14932,38082, -38083,38084,38085,38086,14933,14934,38087,14935,38088,14936,38089,38090,38091, -14937,14938,38092,14939,38093,38094,38095,38096,38097,38098,38099,14940,38100, -38101,38102,38103,38104,38105,38106,38107,38108,38109,38110,14941,38111,38112, -38113,38114,38115,38116,38117,14942,38118,38119,38120,38121,38122,38123,38124, -38125,38126,38127,38128,38129,38130,38131,38132,38133,38134,38135,38136,38137, -38138,38139,38140,38141,38142,38209,38210,14943,14944,38211,38212,14945,38213, -38214,38215,14946,38216,38217,38218,38219,38220,38221,38222,38223,38224,38225, -38226,38227,14947,38228,38229,38230,38231,38232,38233,14948,38234,38241,38242, -14949,38243,38244,38245,14950,38246,38247,38248,38249,38250,38251,38252,14951, -38253,38254,14952,38255,14953,38256,38257,38258,38259,38260,38261,14954,14955, -38262,38263,14956,38264,38265,38266,14957,38273,38274,38275,38276,38277,38278, -38279,14958,14959,38280,14960,38281,38282,38283,38284,38285,38286,38287,38288, -38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,38300,38301, -38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,38313,38314, -38315,38316,14961,14962,38317,38318,14963,38319,38320,38321,14964,38322,14965, -38323,38324,38325,38326,38327,14966,14967,38328,14968,38329,14969,14970,14971, -38330,38331,38332,38333,14972,14973,38334,38335,14974,38336,38337,38338,15137, -38339,15138,38340,38341,38342,38343,38344,15139,15140,38345,15141,15142,15143, -38346,38347,38348,38349,38350,15144,15145,15146,38351,38352,15147,38353,38354, -38355,15148,38356,38357,38358,38359,38360,38361,38362,15149,15150,38363,15151, -15152,15153,38364,38365,38366,38367,38368,38369,15154,15155,38370,38371,38372, -38373,38374,38375,38376,38377,38378,38379,38380,38381,38382,38383,15156,38384, -38385,38386,38387,38388,38389,38390,38391,38392,38393,38394,38395,38396,38397, -38398,38465,38466,38467,38468,38469,38470,38471,38472,38473,38474,38475,38476, -38477,38478,38479,38480,38481,38482,38483,38484,38485,38486,38487,38488,15157, -15158,38489,38490,15159,38497,38498,15160,15161,38499,38500,38501,38502,38503, -38504,38505,15162,38506,38507,15163,15164,15165,38508,38509,38510,38511,38512, -38513,15166,38514,38515,38516,38517,38518,38519,38520,38521,38522,38529,38530, -38531,38532,38533,38534,38535,38536,38537,38538,38539,15167,38540,38541,38542, -38543,38544,38545,15168,15169,38546,38547,38548,38549,38550,38551,38552,38553, -38554,38555,38556,38557,38558,38559,15170,15171,38560,15172,15173,15174,38561, -38562,38563,38564,38565,38566,38567,38568,38569,38570,38571,38572,38573,38574, -38575,38576,38577,38578,38579,38580,38581,38582,38583,38584,38585,38586,38587, -38588,38589,38590,38591,38592,38593,38594,15175,15176,38595,38596,15177,38597, -38598,38599,15178,38600,38601,38602,38603,38604,38605,38606,15179,15180,38607, -38608,38609,15181,38610,38611,38612,38613,38614,38615,38616,38617,38618,38619, -38620,38621,38622,38623,38624,38625,38626,38627,38628,38629,38630,38631,38632, -38633,38634,38635,38636,38637,38638,38639,38640,38641,38642,38643,38644,38645, -38646,38647,38648,38649,38650,38651,38652,38653,38654,38721,38722,38723,38724, -38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737, -15182,38738,38739,38740,38741,38742,38743,38744,38745,38746,38753,38754,38755, -38756,38757,38758,38759,38760,38761,38762,38763,38764,38765,38766,38767,38768, -38769,38770,15183,38771,38772,38773,38774,38775,38776,38777,38778,38785,38786, -38787,38788,38789,38790,38791,38792,38793,38794,38795,38796,15184,38797,38798, -38799,38800,38801,38802,15185,15186,38803,38804,15187,38805,38806,38807,15188, -38808,38809,38810,38811,38812,38813,38814,15189,38815,38816,15190,38817,15191, -38818,38819,38820,38821,38822,38823,38824,38825,38826,38827,38828,38829,38830, -38831,38832,38833,38834,38835,38836,38837,38838,38839,38840,38841,38842,38843, -38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856, -38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869, -38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882, -38883,38884,38885,38886,38887,38888,38889,38890,38891,38892,38893,38894,38895, -38896,38897,38898,38899,38900,38901,38902,38903,38904,38905,38906,38907,15192, -38908,38909,38910,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986, -38987,38988,38989,38990,38991,38992,38993,15193,38994,38995,38996,38997,38998, -38999,15194,39000,39001,39002,15195,39009,39010,39011,15196,39012,39013,39014, -39015,39016,39017,39018,15197,15198,39019,39020,39021,39022,39023,39024,39025, -39026,39027,39028,39029,39030,39031,39032,39033,39034,39041,39042,39043,39044, -39045,39046,39047,39048,39049,39050,39051,39052,39053,39054,39055,39056,39057, -39058,39059,39060,39061,39062,15199,15200,39063,39064,15201,39065,39066,39067, -15202,39068,39069,39070,39071,39072,39073,39074,15203,15204,39075,15205,39076, -15206,39077,39078,39079,39080,39081,39082,15207,15208,39083,15209,15210,39084, -39085,15211,15212,15213,15214,39086,39087,39088,39089,39090,15215,15216,39091, -15217,15218,15219,39092,39093,39094,15220,39095,39096,15221,15222,39097,39098, -15223,39099,39100,39101,15224,39102,39103,39104,39105,39106,39107,39108,15225, -15226,39109,15227,15228,15229,39110,39111,39112,39113,39114,39115,15230,15393, -39116,39117,15394,39118,39119,39120,15395,39121,39122,39123,39124,39125,39126, -39127,15396,15397,39128,15398,39129,15399,39130,39131,39132,39133,39134,39135, -15400,39136,39137,39138,15401,39139,39140,39141,15402,39142,39143,39144,39145, -39146,39147,39148,15403,39149,39150,39151,39152,15404,39153,39154,39155,39156, -39157,39158,15405,15406,15407,15408,15409,39159,39160,15410,15411,39161,15412, -15413,39162,39163,39164,39165,15414,15415,39166,15416,15417,15418,39233,39234, -39235,39236,15419,39237,15420,15421,39238,39239,15422,39240,39241,39242,15423, -39243,39244,39245,39246,39247,39248,39249,15424,15425,39250,15426,15427,15428, -39251,39252,39253,39254,39255,39256,15429,15430,39257,39258,15431,39265,39266, -39267,15432,39268,39269,39270,39271,39272,39273,39274,15433,15434,39275,15435, -15436,15437,39276,39277,39278,39279,39280,39281,15438,39282,39283,39284,15439, -39285,39286,39287,15440,39288,39289,39290,39297,39298,39299,39300,39301,39302, -39303,39304,39305,15441,39306,39307,39308,39309,39310,39311,15442,15443,15444, -39312,15445,39313,39314,39315,15446,39316,15447,39317,39318,39319,39320,39321, -15448,15449,39322,15450,39323,15451,39324,39325,39326,15452,39327,39328,15453, -15454,39329,39330,15455,39331,39332,39333,15456,39334,39335,39336,39337,39338, -39339,39340,39341,39342,39343,39344,39345,15457,39346,39347,39348,39349,39350, -39351,15458,39352,39353,39354,15459,39355,39356,39357,15460,39358,39359,39360, -39361,39362,39363,39364,15461,39365,39366,15462,15463,39367,39368,39369,39370, -39371,39372,39373,15464,39374,39375,39376,15465,39377,39378,39379,15466,39380, -39381,39382,39383,39384,39385,39386,15467,15468,39387,15469,39388,39389,39390, -39391,39392,39393,39394,39395,15470,15471,39396,39397,15472,39398,39399,39400, -15473,39401,39402,39403,39404,39405,39406,39407,15474,15475,39408,15476,39409, -15477,39410,39411,39412,39413,39414,39415,15478,15479,39416,39417,15480,39418, -39419,15481,15482,39420,39421,39422,39489,39490,39491,39492,15483,15484,39493, -15485,39494,15486,39495,15649,39496,15650,15651,39497,15652,39498,39499,39500, -39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513, -39514,39521,39522,15653,39523,39524,39525,39526,39527,39528,39529,15654,15655, -39530,39531,15656,39532,39533,39534,15657,39535,39536,39537,39538,39539,39540, -39541,15658,39542,39543,39544,39545,15659,39546,39553,39554,39555,39556,39557, -15660,15661,39558,39559,15662,39560,39561,39562,15663,39563,39564,39565,39566, -39567,39568,39569,15664,15665,39570,15666,39571,15667,39572,39573,39574,39575, -39576,39577,15668,15669,39578,39579,39580,39581,39582,39583,15670,39584,39585, -39586,39587,39588,39589,39590,15671,39591,39592,15672,39593,15673,39594,39595, -39596,39597,39598,39599,15674,15675,39600,39601,15676,39602,39603,39604,15677, -15678,39605,39606,39607,39608,39609,39610,15679,15680,39611,15681,39612,15682, -39613,39614,39615,39616,39617,39618,39619,39620,39621,39622,39623,39624,39625, -39626,39627,39628,39629,39630,39631,39632,39633,39634,39635,39636,39637,39638, -39639,39640,39641,39642,39643,39644,39645,39646,15683,15684,39647,39648,15685, -39649,39650,15686,15687,39651,39652,39653,39654,39655,39656,15688,15689,15690, -39657,15691,39658,15692,39659,39660,39661,39662,15693,39663,15694,15695,39664, -15696,15697,39665,39666,39667,15698,39668,39669,39670,39671,39672,39673,39674, -15699,15700,39675,39676,15701,15702,39677,39678,39745,39746,39747,15703,15704, -15705,39748,39749,15706,39750,39751,39752,15707,39753,39754,39755,39756,39757, -39758,39759,15708,15709,39760,39761,15710,15711,39762,39763,39764,39765,39766, -39767,39768,39769,39770,39777,39778,39779,39780,39781,39782,39783,39784,39785, -39786,39787,39788,39789,39790,39791,39792,39793,39794,15712,39795,39796,39797, -39798,39799,39800,39801,39802,39809,39810,39811,39812,39813,39814,39815,39816, -39817,39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829, -39830,39831,39832,39833,39834,15713,15714,39835,39836,15715,39837,39838,39839, -15716,39840,15717,39841,39842,39843,39844,39845,15718,15719,39846,39847,15720, -15721,39848,39849,39850,39851,39852,39853,15722,39854,39855,39856,15723,39857, -39858,39859,15724,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869, -39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882, -39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895, -39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,39908, -39909,39910,15725,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920, -39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933, -15726,15727,39934,40001,15728,40002,40003,15729,15730,40004,15731,40005,40006, -40007,40008,40009,15732,15733,40010,40011,40012,15734,40013,40014,40015,40016, -40017,40018,15735,15736,40019,40020,15737,40021,40022,40023,40024,40025,40026, -40033,40034,40035,40036,40037,40038,40039,40040,40041,15738,40042,40043,40044, -40045,40046,40047,40048,15739,40049,40050,40051,40052,40053,40054,40055,40056, -40057,40058,40065,40066,40067,40068,40069,40070,40071,40072,40073,15740,40074, -40075,40076,40077,40078,40079,40080,15741,40081,40082,40083,15742,40084,40085, -40086,15905,40087,40088,40089,40090,40091,40092,40093,15906,15907,40094,40095, -40096,40097,40098,40099,40100,40101,40102,40103,15908,40104,40105,40106,40107, -40108,40109,40110,40111,40112,40113,40114,40115,40116,40117,40118,40119,40120, -40121,40122,40123,40124,40125,40126,40127,40128,40129,40130,15909,15910,40131, -40132,15911,40133,40134,40135,15912,40136,40137,40138,40139,40140,40141,40142, -15913,15914,40143,40144,40145,15915,40146,40147,40148,40149,40150,40151,15916, -40152,40153,40154,40155,40156,40157,40158,40159,40160,40161,40162,40163,40164, -40165,40166,40167,40168,40169,40170,15917,40171,40172,40173,40174,40175,40176, -40177,15918,40178,40179,40180,40181,40182,40183,40184,40185,40186,40187,40188, -40189,40190,40257,40258,40259,40260,40261,40262,40263,40264,40265,40266,40267, -40268,40269,40270,15919,40271,40272,40273,15920,40274,40275,40276,40277,40278, -40279,40280,40281,40282,40289,40290,40291,40292,40293,40294,40295,40296,40297, -40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,40309,40310, -40311,40312,40313,40314,40321,40322,40323,40324,40325,40326,40327,40328,40329, -15921,40330,40331,40332,40333,40334,40335,15922,15923,40336,40337,15924,40338, -40339,40340,15925,40341,15926,40342,40343,40344,40345,15927,15928,15929,40346, -40347,40348,40349,40350,40351,40352,40353,40354,40355,15930,40356,40357,40358, -15931,40359,40360,40361,15932,40362,40363,40364,40365,40366,40367,40368,15933, -40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,15934,15935, -40380,40381,15936,40382,40383,40384,15937,40385,40386,40387,40388,40389,40390, -40391,15938,15939,40392,15940,40393,15941,40394,40395,40396,40397,40398,40399, -15942,15943,40400,40401,15944,15945,15946,40402,15947,15948,15949,40403,40404, -40405,40406,15950,15951,15952,40407,15953,15954,15955,40408,40409,40410,15956, -15957,40411,15958,15959,40412,40413,15960,40414,40415,40416,15961,40417,40418, -40419,40420,40421,40422,40423,15962,15963,40424,15964,15965,15966,40425,40426, -40427,40428,40429,40430,15967,15968,40431,40432,15969,40433,40434,40435,15970, -40436,40437,15971,40438,40439,40440,40441,15972,15973,40442,15974,40443,15975, -40444,40445,40446,15976,40513,15977,15978,40514,40515,40516,15979,40517,40518, -40519,15980,40520,40521,40522,40523,40524,40525,40526,40527,15981,40528,40529, -40530,40531,40532,40533,40534,40535,40536,40537,15982,15983,40538,40545,15984, -15985,40546,15986,15987,15988,15989,40547,40548,40549,40550,40551,15990,15991, -15992,15993,15994,15995,15996,40552,15997,40553,15998,40554,16161,16162,40555, -40556,16163,40557,40558,40559,16164,40560,40561,40562,40563,40564,40565,40566, -16165,16166,40567,16167,40568,16168,40569,40570,40577,40578,40579,40580,16169, -16170,16171,40581,16172,40582,40583,40584,16173,40585,16174,16175,40586,40587, -40588,40589,16176,16177,16178,16179,16180,16181,40590,40591,40592,16182,16183, -16184,16185,40593,40594,40595,16186,40596,40597,40598,16187,40599,40600,40601, -40602,40603,40604,40605,16188,16189,40606,16190,16191,40607,40608,40609,40610, -40611,40612,40613,16192,16193,40614,40615,16194,40616,40617,40618,16195,16196, -16197,40619,16198,40620,40621,16199,16200,16201,40622,16202,40623,16203,40624, -16204,40625,40626,40627,40628,16205,16206,40629,40630,16207,40631,40632,40633, -16208,40634,40635,40636,40637,40638,40639,40640,16209,16210,40641,16211,16212, -16213,40642,40643,40644,40645,40646,40647,16214,16215,40648,40649,16216,40650, -40651,40652,40653,40654,40655,40656,40657,40658,40659,40660,16217,40661,40662, -16218,40663,16219,40664,40665,40666,40667,40668,40669,16220,16221,40670,40671, -16222,40672,40673,40674,16223,40675,40676,40677,40678,40679,40680,40681,16224, -16225,40682,16226,40683,16227,40684,40685,40686,40687,40688,40689,16228,16229, -40690,40691,16230,40692,40693,40694,16231,40695,40696,40697,40698,40699,40700, -40701,16232,16233,40702,16234,40769,16235,40770,40771,40772,40773,40774,40775, -16236,16237,40776,40777,16238,40778,40779,40780,16239,16240,16241,40781,40782, -40783,40784,40785,16242,16243,40786,16244,40787,16245,40788,40789,40790,40791, -40792,40793,16246,16247,40794,40801,16248,40802,40803,40804,16249,40805,40806, -40807,40808,40809,40810,40811,16250,16251,40812,40813,16252,16253,40814,40815, -40816,40817,40818,40819,16254,16417,40820,40821,16418,40822,40823,40824,16419, -40825,40826,40833,40834,40835,40836,40837,16420,16421,40838,40839,40840,16422, -40841,40842,40843,40844,40845,40846,16423,16424,40847,40848,16425,40849,40850, -40851,16426,40852,40853,40854,40855,40856,40857,40858,16427,16428,40859,16429, -40860,16430,40861,40862,40863,40864,40865,40866,16431,16432,40867,40868,16433, -40869,40870,40871,16434,40872,40873,40874,40875,40876,40877,40878,16435,16436, -40879,16437,40880,16438,40881,16439,40882,40883,40884,40885,16440,16441,40886, -40887,16442,40888,40889,40890,16443,40891,40892,40893,40894,40895,16444,40896, -16445,16446,40897,16447,40898,16448,16449,16450,16451,16452,16453,16454,16455, -40899,40900,40901,16456,40902,40903,40904,16457,40905,40906,40907,40908,40909, -40910,40911,16458,40912,40913,16459,40914,40915,40916,40917,40918,40919,40920, -40921,16460,16461,40922,40923,16462,40924,40925,40926,16463,16464,16465,40927, -40928,40929,40930,16466,16467,16468,40931,16469,16470,16471,16472,40932,40933, -40934,16473,40935,16474,16475,40936,40937,16476,40938,16477,16478,16479,40939, -16480,40940,40941,40942,40943,40944,16481,16482,40945,16483,16484,16485,16486, -40946,40947,40948,40949,40950,16487,16488,40951,40952,16489,40953,40954,40955, -16490,40956,40957,40958,41025,41026,41027,41028,16491,16492,41029,16493,16494, -16495,41030,41031,41032,41033,41034,41035,16496,16497,41036,41037,16498,41038, -16499,41039,16500,41040,41041,41042,41043,41044,41045,41046,16501,41047,41048, -41049,41050,16502,41057,41058,41059,41060,41061,41062,16503,41063,41064,41065, -16504,41066,41067,41068,16505,41069,41070,41071,41072,41073,41074,41075,41076, -41077,41078,41079,41080,41081,41082,41089,41090,41091,41092,41093,16506,16507, -41094,41095,16508,41096,41097,41098,16509,41099,16510,41100,41101,41102,41103, -41104,16673,16674,41105,16675,41106,16676,16677,41107,41108,41109,41110,41111, -16678,16679,41112,41113,16680,41114,41115,41116,16681,41117,41118,41119,41120, -41121,41122,41123,16682,16683,41124,16684,41125,16685,41126,41127,41128,41129, -41130,41131,16686,41132,41133,41134,16687,41135,41136,41137,16688,41138,41139, -41140,41141,41142,41143,41144,16689,16690,41145,41146,16691,16692,41147,41148, -41149,41150,41151,41152,16693,41153,41154,41155,41156,41157,41158,41159,41160, -41161,41162,41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173, -41174,41175,41176,41177,41178,41179,16694,16695,41180,41181,16696,41182,41183, -41184,16697,41185,16698,41186,41187,41188,41189,41190,16699,16700,41191,16701, -41192,16702,16703,16704,41193,41194,41195,16705,16706,16707,41196,41197,41198, -41199,41200,41201,16708,41202,41203,41204,41205,41206,41207,41208,41209,16709, -41210,16710,41211,16711,41212,41213,41214,41281,41282,41283,16712,41284,41285, -41286,41287,41288,41289,41290,41291,41292,41293,41294,41295,41296,41297,41298, -41299,41300,41301,41302,16713,16714,41303,41304,41305,41306,41313,41314,16715, -41315,41316,41317,16716,41318,41319,41320,16717,41321,41322,41323,41324,41325, -41326,41327,16718,16719,41328,16720,41329,16721,41330,41331,41332,41333,41334, -41335,16722,16723,41336,41337,16724,41338,41345,41346,41347,41348,41349,41350, -41351,41352,41353,41354,41355,41356,41357,41358,41359,16725,41360,41361,41362, -41363,41364,41365,16726,16727,41366,41367,16728,41368,41369,41370,16729,16730, -16731,41371,41372,41373,41374,41375,16732,16733,41376,16734,41537,16735,41538, -41539,41540,41541,41542,41543,16736,41544,41545,41546,41547,41548,41549,41550, -41551,41552,41553,41554,41555,41556,41557,41558,41559,41560,41561,41562,16737, -41569,41570,41571,41572,41573,41574,41575,16738,41576,41577,41578,41579,41580, -41581,41582,41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593, -41594,41601,41602,41603,41604,41605,41606,41607,41608,16739,16740,41609,41610, -16741,41611,41612,41613,16742,41614,41615,41616,41617,41618,41619,41620,16743, -16744,41621,16745,41622,41623,41624,41625,41626,41627,41628,41629,16746,41630, -41631,41632,16747,41793,41794,41795,16748,41796,41797,41798,41799,41800,41801, -41802,16749,41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,41813, -16750,16751,41814,41815,16752,41816,41817,41818,16753,41825,41826,41827,41828, -41829,41830,41831,16754,16755,41832,16756,41833,16757,41834,41835,41836,41837, -41838,41839,41840,41841,41842,41843,41844,41845,41846,41847,41848,41849,41850, -41857,41858,41859,41860,41861,41862,41863,41864,41865,41866,41867,41868,41869, -41870,41871,41872,41873,16758,16759,41874,41875,16760,41876,41877,16761,16762, -41878,16763,41879,41880,41881,41882,41883,16764,16765,41884,16766,41885,16929, -16930,41886,41887,16931,16932,41888,16933,16934,42049,42050,16935,42051,16936, -42052,16937,42053,42054,16938,42055,42056,42057,42058,16939,16940,42059,16941, -16942,16943,42060,42061,42062,42063,42064,42065,16944,16945,42066,42067,16946, -42068,42069,42070,16947,42071,42072,42073,42074,42081,42082,42083,16948,16949, -42084,16950,16951,16952,42085,42086,42087,42088,42089,42090,16953,42091,42092, -42093,16954,42094,42095,42096,42097,42098,42099,42100,42101,42102,42103,42104, -42105,42106,42113,42114,42115,16955,42116,42117,42118,42119,42120,42121,42122, -42123,42124,42125,42126,42127,42128,42129,42130,42131,42132,42133,42134,42135, -42136,42137,42138,42139,42140,42141,42142,42143,42144,42305,42306,42307,42308, -42309,16956,16957,42310,42311,16958,42312,42313,42314,16959,42315,42316,42317, -42318,42319,42320,42321,16960,16961,42322,16962,16963,16964,42323,42324,42325, -42326,42327,42328,16965,42329,42330,42337,42338,42339,42340,42341,42342,42343, -42344,42345,42346,42347,42348,42349,42350,42351,42352,42353,42354,16966,42355, -42356,42357,42358,42359,42360,16967,42361,42362,42369,42370,42371,42372,42373, -42374,42375,42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,16968, -42386,42387,42388,42389,42390,42391,42392,42393,42394,42395,42396,42397,42398, -42399,42400,42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571, -42572,42573,42574,42575,42576,42577,42578,42579,42580,16969,16970,42581,42582, -16971,42583,42584,42585,16972,42586,42593,42594,42595,42596,42597,42598,16973, -16974,42599,16975,42600,16976,42601,16977,42602,42603,42604,42605,16978,16979, -42606,42607,42608,42609,42610,42611,16980,42612,42613,42614,42615,42616,42617, -42618,42625,42626,42627,42628,16981,42629,42630,42631,42632,42633,42634,42635, -16982,42636,42637,42638,42639,42640,42641,42642,42643,42644,42645,42646,42647, -42648,42649,42650,42651,42652,42653,42654,16983,42655,42656,42817,42818,42819, -42820,42821,16984,42822,42823,42824,16985,42825,42826,42827,16986,42828,42829, -42830,42831,42832,42833,42834,16987,16988,42835,42836,42837,42838,42839,42840, -42841,42842,42849,42850,42851,42852,42853,42854,42855,42856,42857,42858,42859, -42860,42861,42862,42863,42864,42865,42866,42867,42868,42869,42870,42871,16989, -42872,42873,42874,42881,42882,42883,16990,16991,42884,42885,16992,42886,42887, -42888,16993,42889,42890,42891,42892,42893,42894,42895,16994,16995,42896,42897, -42898,16996,42899,42900,42901,42902,42903,42904,16997,42905,42906,42907,42908, -42909,42910,42911,42912,43073,43074,43075,43076,43077,43078,43079,43080,43081, -43082,43083,16998,16999,43084,43085,43086,43087,43088,43089,43090,43091,43092, -43093,43094,43095,43096,43097,43098,43105,43106,43107,43108,43109,43110,43111, -43112,43113,43114,43115,43116,43117,43118,43119,43120,43121,43122,43123,17000, -43124,43125,43126,43127,43128,43129,43130,43137,43138,43139,43140,43141,43142, -43143,43144,43145,43146,43147,43148,43149,43150,43151,43152,43153,43154,43155, -43156,17001,43157,43158,43159,43160,43161,43162,43163,43164,43165,43166,43167, -43168,43329,43330,43331,43332,43333,43334,43335,43336,43337,43338,43339,43340, -43341,43342,43343,17002,43344,43345,43346,43347,43348,43349,43350,43351,43352, -43353,43354,43361,43362,43363,43364,17003,43365,43366,17004,43367,17005,43368, -43369,43370,43371,43372,43373,43374,43375,43376,43377,43378,43379,43380,43381, -43382,43383,43384,43385,43386,43393,43394,43395,43396,43397,43398,43399,43400, -43401,43402,43403,43404,43405,43406,43407,17006,17007,43408,43409,17008,43410, -43411,43412,17009,43413,43414,43415,43416,43417,43418,43419,17010,17011,43420, -43421,43422,17012,17013,43423,43424,43585,43586,17014,17015,17016,43587,43588, -17017,43589,17018,43590,17019,43591,43592,43593,43594,43595,43596,43597,17020, -17021,43598,17022,17185,17186,17187,43599,43600,43601,43602,43603,17188,17189, -43604,43605,17190,43606,43607,43608,17191,43609,43610,43617,43618,43619,43620, -43621,17192,17193,43622,17194,17195,17196,43623,43624,43625,43626,43627,43628, -17197,43629,43630,43631,17198,43632,17199,43633,17200,43634,43635,43636,43637, -43638,43639,43640,17201,43641,43642,43649,43650,17202,43651,43652,43653,43654, -43655,43656,43657,43658,43659,43660,43661,43662,43663,43664,43665,43666,43667, -43668,43669,43670,43671,43672,43673,43674,43675,43676,43677,43678,43679,43680, -43841,43842,43843,43844,17203,17204,43845,43846,17205,43847,43848,43849,17206, -43850,43851,43852,43853,43854,43855,43856,17207,17208,43857,17209,17210,17211, -43858,43859,43860,43861,43862,43863,17212,17213,43864,43865,17214,43866,43873, -43874,17215,43875,43876,43877,43878,43879,43880,43881,17216,17217,43882,17218, -43883,17219,43884,43885,43886,43887,43888,43889,17220,43890,43891,43892,17221, -43893,43894,43895,43896,43897,43898,43905,43906,43907,43908,43909,43910,43911, -43912,43913,17222,43914,43915,43916,43917,43918,43919,43920,17223,43921,43922, -43923,17224,43924,43925,43926,43927,43928,43929,43930,43931,43932,43933,43934, -43935,43936,44097,44098,44099,17225,44100,44101,44102,44103,44104,44105,17226, -17227,44106,44107,17228,44108,44109,44110,17229,44111,44112,44113,44114,44115, -44116,44117,17230,17231,44118,17232,44119,17233,44120,44121,44122,44129,44130, -44131,17234,44132,44133,44134,17235,44135,44136,44137,17236,44138,44139,44140, -44141,44142,44143,44144,44145,44146,44147,44148,44149,17237,44150,44151,44152, -44153,44154,44161,44162,44163,44164,44165,44166,44167,44168,44169,44170,44171, -44172,44173,44174,44175,44176,44177,44178,44179,44180,44181,44182,44183,44184, -44185,44186,44187,44188,44189,17238,44190,44191,44192,17239,44353,44354,44355, -17240,44356,44357,44358,44359,44360,44361,44362,17241,17242,44363,17243,44364, -17244,44365,44366,44367,44368,44369,44370,17245,44371,44372,44373,44374,44375, -44376,44377,44378,44385,44386,44387,44388,44389,44390,44391,17246,44392,44393, -44394,44395,44396,44397,44398,44399,44400,44401,44402,17247,17248,44403,44404, -17249,44405,44406,44407,17250,44408,44409,44410,44417,44418,44419,44420,17251, -17252,44421,17253,44422,17254,44423,44424,44425,44426,44427,44428,17255,44429, -44430,44431,44432,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442, -44443,44444,44445,44446,44447,17256,44448,44609,44610,44611,44612,44613,44614, -17257,44615,44616,44617,17258,44618,44619,44620,44621,44622,44623,44624,44625, -44626,44627,44628,44629,44630,44631,44632,44633,44634,44641,44642,44643,44644, -44645,44646,17259,44647,44648,44649,17260,44650,44651,44652,17261,44653,44654, -44655,44656,44657,44658,44659,17262,17263,44660,17264,44661,17265,44662,44663, -44664,44665,44666,44673,17266,44674,44675,44676,17267,44677,44678,44679,17268, -44680,44681,44682,44683,44684,44685,44686,17269,44687,44688,44689,44690,17270, -44691,44692,44693,44694,44695,44696,17271,17272,44697,44698,17273,44699,44700, -44701,17274,44702,44703,44704,44865,44866,44867,44868,17275,17276,44869,17277, -44870,17278,44871,44872,44873,44874,44875,44876,44877,44878,44879,44880,44881, -44882,44883,44884,44885,44886,44887,44888,44889,44890,44897,44898,44899,44900, -44901,44902,44903,44904,44905,44906,44907,44908,44909,44910,17441,17442,44911, -44912,17443,44913,44914,17444,17445,17446,44915,44916,44917,44918,44919,44920, -17447,17448,44921,17449,44922,17450,44929,44930,44931,44932,44933,44934,17451, -17452,44935,44936,17453,44937,44938,44939,17454,44940,44941,44942,44943,44944, -44945,44946,17455,17456,44947,17457,44948,17458,44949,44950,44951,44952,44953, -44954,17459,17460,44955,44956,17461,44957,44958,44959,17462,44960,45121,45122, -45123,45124,45125,45126,17463,17464,45127,17465,17466,17467,45128,45129,45130, -45131,45132,45133,17468,17469,45134,45135,45136,45137,45138,45139,45140,45141, -45142,45143,45144,45145,45146,45153,45154,45155,45156,45157,45158,17470,45159, -45160,45161,45162,45163,45164,45165,45166,45167,45168,45169,45170,45171,45172, -45173,45174,45175,45176,45177,45178,45185,45186,45187,45188,45189,45190,45191, -45192,45193,45194,45195,45196,45197,45198,17471,17472,45199,45200,17473,45201, -45202,17474,17475,45203,45204,45205,45206,45207,45208,45209,17476,17477,45210, -17478,17479,17480,45211,45212,45213,45214,45215,45216,17481,17482,45377,45378, -17483,45379,45380,45381,17484,45382,45383,45384,45385,45386,45387,45388,17485, -17486,45389,17487,45390,17488,45391,45392,45393,45394,45395,45396,17489,45397, -45398,45399,17490,45400,45401,45402,17491,45409,45410,45411,45412,45413,45414, -45415,17492,17493,45416,17494,17495,17496,45417,45418,45419,45420,45421,45422, -17497,45423,45424,45425,45426,45427,45428,45429,45430,45431,45432,45433,45434, -45441,45442,45443,45444,45445,45446,45447,45448,45449,45450,45451,45452,45453, -45454,45455,17498,17499,45456,45457,17500,45458,45459,45460,17501,45461,45462, -45463,45464,45465,45466,45467,17502,17503,45468,17504,45469,17505,45470,45471, -45472,45633,45634,45635,17506,17507,45636,45637,17508,45638,45639,45640,17509, -45641,45642,45643,45644,45645,45646,45647,17510,45648,45649,45650,45651,17511, -45652,45653,45654,45655,45656,45657,17512,45658,45665,45666,45667,45668,45669, -45670,45671,45672,45673,45674,45675,45676,45677,45678,45679,45680,45681,45682, -45683,17513,45684,45685,45686,45687,45688,45689,17514,45690,45697,45698,45699, -45700,45701,45702,17515,45703,45704,45705,45706,45707,45708,45709,45710,45711, -45712,45713,45714,45715,45716,45717,45718,45719,45720,45721,17516,45722,45723, -45724,45725,45726,45727,45728,45889,45890,45891,45892,45893,45894,45895,45896, -45897,45898,45899,45900,45901,45902,45903,45904,45905,45906,45907,45908,17517, -17518,45909,45910,17519,45911,45912,45913,17520,45914,45921,45922,45923,45924, -45925,45926,17521,17522,45927,17523,45928,17524,45929,45930,45931,45932,45933, -45934,17525,45935,45936,45937,17526,45938,45939,45940,17527,45941,45942,45943, -45944,45945,45946,45953,45954,45955,45956,45957,45958,17528,45959,45960,45961, -45962,45963,45964,17529,45965,45966,45967,45968,45969,45970,45971,45972,45973, -45974,45975,45976,45977,45978,45979,45980,45981,45982,45983,45984,17530,46145, -46146,46147,46148,46149,46150,17531,17532,46151,46152,17533,46153,46154,46155, -17534,46156,46157,46158,46159,46160,46161,46162,17697,17698,46163,17699,46164, -17700,46165,46166,46167,46168,46169,46170,17701,46177,46178,46179,17702,46180, -46181,46182,17703,46183,46184,46185,46186,46187,46188,46189,17704,46190,46191, -46192,46193,46194,46195,46196,46197,46198,46199,46200,17705,17706,46201,46202, -17707,46209,46210,46211,17708,46212,46213,46214,46215,46216,46217,46218,17709, -17710,46219,46220,46221,17711,46222,46223,46224,46225,46226,46227,46228,46229, -46230,46231,46232,46233,46234,46235,46236,46237,46238,46239,46240,46401,46402, -46403,46404,46405,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415, -17712,17713,46416,46417,17714,46418,46419,46420,17715,46421,46422,46423,46424, -46425,46426,46433,17716,17717,46434,17718,46435,17719,46436,46437,46438,46439, -46440,46441,17720,17721,46442,46443,17722,46444,46445,46446,17723,17724,46447, -46448,46449,46450,46451,46452,17725,17726,46453,17727,17728,17729,46454,46455, -46456,46457,46458,46465,17730,17731,46466,46467,17732,46468,46469,46470,17733, -46471,46472,46473,46474,46475,46476,46477,17734,17735,46478,17736,17737,17738, -46479,46480,46481,46482,46483,46484,17739,46485,46486,46487,46488,46489,46490, -46491,46492,46493,46494,46495,46496,46657,46658,46659,46660,46661,46662,46663, -46664,17740,46665,46666,46667,46668,46669,46670,46671,46672,46673,46674,46675, -46676,46677,46678,46679,46680,46681,46682,46689,46690,46691,46692,46693,46694, -46695,46696,46697,46698,46699,46700,46701,46702,46703,46704,17741,17742,46705, -46706,17743,46707,46708,46709,17744,46710,17745,46711,46712,46713,46714,46721, -17746,17747,46722,17748,17749,17750,46723,46724,46725,46726,46727,46728,17751, -17752,46729,46730,17753,46731,46732,46733,17754,46734,46735,46736,46737,46738, -46739,46740,17755,17756,46741,17757,46742,17758,46743,46744,46745,46746,46747, -46748,17759,46749,46750,46751,17760,46752,46913,46914,46915,46916,46917,46918, -46919,46920,46921,46922,46923,46924,46925,46926,17761,46927,46928,46929,46930, -46931,46932,46933,17762,46934,46935,46936,17763,46937,46938,46945,46946,46947, -46948,46949,46950,46951,46952,46953,46954,46955,46956,46957,46958,46959,46960, -46961,46962,46963,46964,46965,17764,17765,46966,46967,17766,46968,46969,46970, -17767,46977,46978,46979,46980,46981,46982,46983,17768,17769,46984,17770,46985, -17771,46986,46987,46988,46989,17772,46990,17773,46991,46992,46993,17774,46994, -46995,46996,46997,46998,46999,47000,47001,47002,47003,47004,47005,47006,47007, -47008,47169,47170,47171,47172,47173,47174,47175,47176,17775,47177,47178,47179, -47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,47190,47191,47192, -47193,47194,47201,47202,47203,47204,47205,47206,47207,47208,47209,17776,47210, -47211,47212,17777,47213,47214,47215,47216,47217,47218,47219,47220,47221,47222, -47223,47224,47225,47226,17778,47233,17779,47234,47235,47236,47237,47238,47239, -17780,47240,47241,47242,47243,47244,47245,47246,47247,47248,47249,47250,47251, -47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,47264, -47425,47426,17781,17782,47427,47428,17783,47429,47430,47431,17784,47432,47433, -47434,47435,47436,47437,47438,17785,17786,47439,17787,47440,17788,47441,47442, -47443,47444,47445,47446,17789,47447,47448,47449,47450,47457,47458,47459,47460, -47461,47462,47463,47464,47465,47466,47467,47468,47469,47470,47471,17790,47472, -47473,47474,47475,47476,47477,47478,17953,47479,47480,47481,47482,47489,47490, -47491,47492,47493,47494,47495,47496,47497,47498,47499,47500,47501,47502,47503, -47504,47505,47506,47507,47508,47509,47510,47511,17954,17955,47512,47513,17956, -47514,47515,47516,17957,47517,47518,47519,47520,47681,47682,47683,17958,17959, -47684,47685,47686,17960,47687,47688,47689,47690,47691,47692,17961,47693,47694, -47695,17962,47696,47697,47698,17963,47699,47700,47701,47702,47703,47704,47705, -17964,47706,47713,47714,47715,17965,47716,47717,47718,47719,47720,47721,17966, -17967,47722,47723,17968,47724,47725,17969,17970,47726,17971,47727,47728,47729, -47730,47731,17972,17973,47732,17974,47733,47734,47735,47736,47737,47738,47745, -47746,17975,47747,47748,47749,17976,47750,47751,47752,17977,47753,47754,47755, -47756,47757,47758,47759,17978,17979,47760,47761,47762,47763,47764,47765,47766, -47767,47768,47769,17980,17981,47770,47771,17982,47772,47773,47774,17983,47775, -47776,47937,47938,47939,47940,47941,17984,17985,47942,17986,47943,17987,47944, -47945,47946,47947,47948,47949,17988,17989,17990,47950,17991,47951,47952,47953, -17992,47954,17993,47955,47956,47957,47958,47959,17994,17995,47960,17996,17997, -17998,47961,47962,47969,17999,47970,47971,18000,18001,47972,47973,18002,47974, -47975,47976,18003,47977,47978,47979,47980,47981,47982,47983,18004,18005,47984, -18006,18007,18008,47985,47986,47987,47988,47989,47990,18009,18010,47991,47992, -47993,47994,48001,48002,48003,48004,48005,48006,48007,48008,48009,48010,48011, -48012,48013,48014,48015,48016,48017,48018,48019,48020,48021,48022,48023,48024, -48025,48026,48027,48028,48029,48030,48031,48032,48193,48194,48195,48196,48197, -48198,48199,48200,48201,48202,48203,48204,48205,48206,48207,48208,48209,48210, -18011,18012,48211,48212,18013,48213,48214,48215,18014,48216,48217,48218,48225, -48226,48227,48228,18015,18016,48229,18017,18018,18019,48230,48231,48232,48233, -48234,48235,18020,18021,48236,48237,18022,48238,48239,48240,18023,48241,48242, -48243,48244,48245,48246,48247,18024,18025,48248,18026,48249,18027,48250,48257, -48258,48259,48260,48261,18028,48262,48263,48264,18029,48265,48266,48267,18030, -48268,48269,48270,48271,48272,48273,48274,18031,18032,48275,48276,18033,18034, -48277,48278,48279,48280,48281,48282,18035,48283,48284,48285,48286,48287,48288, -48449,18036,48450,48451,48452,48453,48454,48455,48456,48457,18037,48458,18038, -48459,48460,48461,48462,48463,48464,48465,48466,18039,18040,48467,48468,18041, -48469,48470,48471,18042,48472,48473,48474,48481,48482,48483,48484,18043,18044, -48485,18045,48486,18046,48487,48488,48489,48490,48491,48492,18209,48493,48494, -48495,48496,48497,48498,48499,48500,48501,48502,48503,48504,48505,48506,48513, -48514,48515,48516,48517,48518,18210,48519,48520,48521,48522,48523,48524,48525, -48526,48527,48528,48529,48530,48531,48532,48533,48534,48535,48536,48537,48538, -48539,48540,48541,48542,48543,48544,48705,48706,48707,48708,48709,48710,48711, -48712,18211,48713,48714,48715,18212,48716,48717,48718,48719,48720,48721,48722, -48723,48724,48725,48726,48727,48728,48729,48730,48737,48738,48739,48740,48741, -48742,48743,48744,18213,48745,48746,48747,18214,48748,48749,48750,18215,48751, -48752,48753,48754,48755,48756,48757,48758,18216,48759,18217,48760,48761,48762, -48769,48770,48771,48772,48773,18218,18219,48774,48775,18220,48776,48777,18221, -18222,48778,18223,48779,48780,48781,48782,48783,18224,18225,48784,18226,48785, -18227,48786,48787,48788,48789,48790,48791,18228,48792,48793,48794,48795,48796, -48797,48798,48799,48800,48961,48962,48963,48964,48965,48966,48967,48968,48969, -48970,48971,18229,48972,48973,48974,48975,48976,48977,48978,48979,48980,48981, -48982,48983,48984,48985,48986,48993,48994,48995,48996,48997,48998,48999,49000, -49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,18230,49012, -49013,49014,18231,49015,49016,49017,18232,49018,49025,49026,49027,49028,49029, -49030,18233,49031,49032,18234,49033,49034,49035,49036,49037,49038,49039,49040, -18235,49041,49042,49043,18236,49044,49045,49046,18237,49047,49048,49049,49050, -49051,49052,49053,18238,49054,49055,18239,49056,18240,49217,49218,49219,49220, -49221,49222,18241,49223,49224,49225,18242,49226,49227,49228,18243,49229,49230, -49231,49232,49233,49234,49235,18244,18245,49236,18246,49237,49238,49239,49240, -49241,49242,49249,49250,49251,49252,49253,49254,49255,49256,49257,49258,49259, -49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,49272, -49273,49274,49281,49282,49283,49284,18247,18248,49285,49286,18249,49287,49288, -49289,18250,49290,49291,49292,49293,49294,49295,49296,18251,18252,49297,18253, -49298,18254,49299,49300,49301,49302,49303,49304,18255,18256,49305,49306,18257, -49307,49308,49309,18258,49310,49311,49312,49473,18259,49474,49475,18260,18261, -49476,18262,49477,18263,49478,49479,49480,49481,49482,49483,18264,18265,49484, -49485,18266,49486,49487,49488,18267,49489,49490,49491,49492,49493,49494,49495, -18268,18269,49496,18270,18271,18272,49497,49498,49505,49506,49507,49508,18273, -49509,49510,49511,49512,49513,49514,49515,49516,49517,49518,49519,49520,49521, -49522,49523,49524,49525,49526,49527,49528,18274,49529,49530,49537,49538,49539, -49540,49541,49542,49543,49544,49545,49546,49547,49548,49549,49550,49551,49552, -49553,49554,49555,49556,49557,49558,49559,49560,49561,49562,49563,49564,49565, -49566,49567,49568,18275,18276,49729,49730,18277,49731,49732,49733,18278,49734, -18279,49735,49736,49737,49738,49739,18280,18281,49740,18282,49741,18283,49742, -49743,49744,49745,49746,49747,18284,18285,49748,49749,18286,49750,49751,49752, -18287,49753,49754,49761,49762,49763,49764,49765,18288,18289,49766,18290,49767, -18291,49768,49769,49770,49771,49772,49773,18292,18293,49774,49775,18294,49776, -49777,49778,18295,49779,49780,49781,49782,49783,49784,49785,18296,18297,49786, -18298,18299,18300,49793,49794,49795,49796,49797,49798,18301,49799,49800,49801, -18302,49802,49803,49804,18465,49805,49806,49807,49808,49809,49810,49811,49812, -18466,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,18467,18468, -49823,49824,18469,49985,49986,49987,18470,49988,49989,49990,49991,18471,49992, -49993,18472,18473,49994,18474,49995,18475,49996,49997,49998,18476,49999,50000, -18477,18478,50001,50002,18479,50003,50004,50005,18480,50006,50007,50008,50009, -50010,50017,50018,50019,50020,50021,18481,50022,18482,50023,50024,50025,50026, -50027,50028,18483,18484,50029,50030,18485,50031,50032,50033,50034,50035,50036, -50037,50038,50039,50040,50041,50042,50049,50050,18486,50051,18487,50052,50053, -50054,50055,50056,50057,18488,18489,50058,50059,18490,50060,50061,50062,18491, -50063,50064,50065,50066,50067,50068,50069,50070,18492,50071,18493,50072,18494, -50073,50074,50075,50076,50077,50078,18495,50079,50080,50241,18496,50242,50243, -50244,18497,50245,50246,50247,50248,50249,50250,50251,50252,18498,50253,18499, -50254,50255,50256,50257,50258,50259,50260,50261,18500,18501,50262,50263,18502, -50264,50265,50266,18503,50273,50274,50275,50276,18504,50277,50278,18505,50279, -50280,18506,50281,18507,50282,50283,50284,50285,50286,50287,18508,50288,50289, -50290,18509,50291,50292,50293,18510,50294,50295,50296,50297,50298,50305,50306, -18511,50307,50308,50309,50310,18512,50311,50312,50313,50314,50315,50316,18513, -18514,50317,50318,18515,50319,50320,50321,18516,50322,50323,50324,50325,50326, -50327,50328,50329,50330,50331,50332,50333,18517,50334,50335,50336,50497,50498, -50499,18518,18519,50500,50501,18520,50502,50503,50504,18521,50505,50506,50507, -50508,50509,50510,50511,18522,18523,50512,18524,50513,18525,50514,50515,50516, -50517,50518,50519,18526,18527,50520,50521,18528,50522,50529,50530,18529,50531, -50532,50533,50534,50535,50536,50537,18530,50538,50539,18531,50540,18532,50541, -50542,50543,50544,50545,50546,18533,18534,50547,50548,18535,50549,18536,18537, -18538,18539,50550,50551,50552,50553,50554,50561,18540,18541,50562,18542,50563, -18543,50564,50565,50566,18544,50567,50568,18545,50569,50570,50571,18546,50572, -50573,50574,18547,50575,50576,50577,50578,50579,50580,50581,18548,18549,50582, -50583,50584,18550,50585,50586,50587,50588,50589,50590,18551,18552,50591,50592, -18553,50753,50754,50755,18554,50756,50757,50758,50759,50760,50761,50762,18555, -18556,50763,18557,50764,18558,50765,50766,50767,50768,50769,50770,19280,19286, -19303,19791,19816,20013,20347,20514,20536,20560,20573,20820,20821,20824,20827, -20828,20829,20830,20831,20832,20834,20835,20836,20837,20838,20840,20841,20842, -20843,20845,20847,20848,20850,20854,20858,20860,20861,20862,21026,21027,21031, -21032,21033,21034,21035,21037,21042,21054,21058,21059,21060,21062,21063,21064, -21065,21066,21067,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078, -21079,21081,21082,21086,21087,21089,21090,21092,21093,21094,21095,21096,21097, -21098,21099,21104,21105,21106,21107,21108,21109,21111,21112,21606,21628,21797, -21803,21806,22072,22093,22347,22372,23365,23396,23589,23845,23893,23924,24188, -24190,24371,24417,24424,24689,24877,24941,25461,25633,25641,25902,25905,25906, -25913,25915,25916,25924,25934,25936,25938,25942,25978,25979,25980,25982,26145, -26148,26151,26157,26159,26160,26161,26163,26167,26168,26172,26180,26182,26183, -26186,26194,26198,26201,26204,26207,26209,26212,26213,26214,26216,26218,26219, -26220,26223,26225,26226,26229,26230,26231,26233,26401,26406,26409,26410,26412, -26413,26416,26431,26433,26438,26439,26443,26445,26447,26448,26451,26463,26468, -26470,26487,26727,26728,26736,26737,26743,26745,26747,26750,26919,26924,26956, -26999,27201,27237,27252,27255,27260,27262,27428,27431,27433,27434,27450,27451, -27453,27457,27458,27462,27463,27468,27471,27472,27473,27474,27480,27686,27687, -27690,27695,27696,27697,27698,27701,27704,27706,27712,27713,27717,27718,27721, -27722,27733,27741,27742,27745,27748,27751,27752,27767,27768,27770,27937,27938, -27939,28014,28251,29245,29306,29489,29735,29806,30324,30326,30520,30536,30547, -30811,30832,31265,31266,31334,31785,8993,8994,8995,8996,8997,8998,8999,9000, -9001,9002,9003,9004,9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015, -9016,9017,9018,9019,9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030, -9031,9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045, -9046,9047,9048,9049,9050,9051,8492,9053,9054,9055,9056,9057,9058,9059,9060, -9061,9062,9063,9064,9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075, -9076,9077,9078,9079,9080,9081,9082,9083,9084,9085,8742,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,8523,8524,8574,9086,N,8525,9052, -}; - -static const struct unim_index cp949_encmap[256] = { -{__cp949_encmap+0,161,254},{__cp949_encmap+94,17,103},{__cp949_encmap+181,199, -221},{__cp949_encmap+204,145,201},{__cp949_encmap+261,1,81},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+342,21,172},{ -__cp949_encmap+494,3,212},{__cp949_encmap+704,0,165},{__cp949_encmap+870,18,18 -},{__cp949_encmap+871,96,233},{__cp949_encmap+1009,0,209},{__cp949_encmap+1219 -,5,109},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{__cp949_encmap+1324,0,246},{__cp949_encmap+1571,49,142},{__cp949_encmap+ -1665,0,127},{__cp949_encmap+1793,128,221},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{__cp949_encmap+1887,0,251},{__cp949_encmap+2139,1,250},{ -__cp949_encmap+2389,2,255},{__cp949_encmap+2643,0,253},{__cp949_encmap+2897,0, -255},{__cp949_encmap+3153,5,248},{__cp949_encmap+3397,3,250},{__cp949_encmap+ -3645,4,254},{__cp949_encmap+3896,6,250},{__cp949_encmap+4141,3,252},{ -__cp949_encmap+4391,0,253},{__cp949_encmap+4645,15,255},{__cp949_encmap+4886, -1,233},{__cp949_encmap+5119,5,250},{__cp949_encmap+5365,1,253},{__cp949_encmap -+5618,7,254},{__cp949_encmap+5866,2,251},{__cp949_encmap+6116,1,255},{ -__cp949_encmap+6371,15,251},{__cp949_encmap+6608,1,255},{__cp949_encmap+6863, -0,255},{__cp949_encmap+7119,1,247},{__cp949_encmap+7366,13,254},{ -__cp949_encmap+7608,0,255},{__cp949_encmap+7864,6,255},{__cp949_encmap+8114,0, -254},{__cp949_encmap+8369,18,250},{__cp949_encmap+8602,0,255},{__cp949_encmap+ -8858,2,251},{__cp949_encmap+9108,4,236},{__cp949_encmap+9341,8,243},{ -__cp949_encmap+9577,11,251},{__cp949_encmap+9818,23,255},{__cp949_encmap+10051 -,1,254},{__cp949_encmap+10305,1,253},{__cp949_encmap+10558,4,255},{ -__cp949_encmap+10810,0,253},{__cp949_encmap+11064,10,254},{__cp949_encmap+ -11309,1,247},{__cp949_encmap+11556,1,252},{__cp949_encmap+11808,0,254},{ -__cp949_encmap+12063,1,243},{__cp949_encmap+12306,2,251},{__cp949_encmap+12556 -,1,251},{__cp949_encmap+12807,0,255},{__cp949_encmap+13063,15,233},{ -__cp949_encmap+13282,7,254},{__cp949_encmap+13530,0,251},{__cp949_encmap+13782 -,9,156},{__cp949_encmap+13930,54,252},{__cp949_encmap+14129,0,253},{ -__cp949_encmap+14383,2,254},{__cp949_encmap+14636,5,254},{__cp949_encmap+14886 -,1,253},{__cp949_encmap+15139,3,252},{__cp949_encmap+15389,17,255},{ -__cp949_encmap+15628,2,254},{__cp949_encmap+15881,0,254},{__cp949_encmap+16136 -,5,253},{__cp949_encmap+16385,7,248},{__cp949_encmap+16627,0,254},{ -__cp949_encmap+16882,0,154},{__cp949_encmap+17037,55,253},{__cp949_encmap+ -17236,4,243},{__cp949_encmap+17476,10,254},{__cp949_encmap+17721,3,253},{ -__cp949_encmap+17972,0,253},{__cp949_encmap+18226,2,245},{__cp949_encmap+18470 -,13,252},{__cp949_encmap+18710,4,246},{__cp949_encmap+18953,4,127},{ -__cp949_encmap+19077,119,226},{__cp949_encmap+19185,28,251},{__cp949_encmap+ -19409,0,255},{__cp949_encmap+19665,0,254},{__cp949_encmap+19920,3,255},{ -__cp949_encmap+20173,1,238},{__cp949_encmap+20411,26,232},{__cp949_encmap+ -20618,13,246},{__cp949_encmap+20852,9,250},{__cp949_encmap+21094,26,244},{ -__cp949_encmap+21313,7,156},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+21463,0,255},{ -__cp949_encmap+21719,0,255},{__cp949_encmap+21975,0,255},{__cp949_encmap+22231 -,0,255},{__cp949_encmap+22487,0,255},{__cp949_encmap+22743,0,255},{ -__cp949_encmap+22999,0,255},{__cp949_encmap+23255,0,255},{__cp949_encmap+23511 -,0,255},{__cp949_encmap+23767,0,255},{__cp949_encmap+24023,0,255},{ -__cp949_encmap+24279,0,255},{__cp949_encmap+24535,0,255},{__cp949_encmap+24791 -,0,255},{__cp949_encmap+25047,0,255},{__cp949_encmap+25303,0,255},{ -__cp949_encmap+25559,0,255},{__cp949_encmap+25815,0,255},{__cp949_encmap+26071 -,0,255},{__cp949_encmap+26327,0,255},{__cp949_encmap+26583,0,255},{ -__cp949_encmap+26839,0,255},{__cp949_encmap+27095,0,255},{__cp949_encmap+27351 -,0,255},{__cp949_encmap+27607,0,255},{__cp949_encmap+27863,0,255},{ -__cp949_encmap+28119,0,255},{__cp949_encmap+28375,0,255},{__cp949_encmap+28631 -,0,255},{__cp949_encmap+28887,0,255},{__cp949_encmap+29143,0,255},{ -__cp949_encmap+29399,0,255},{__cp949_encmap+29655,0,255},{__cp949_encmap+29911 -,0,255},{__cp949_encmap+30167,0,255},{__cp949_encmap+30423,0,255},{ -__cp949_encmap+30679,0,255},{__cp949_encmap+30935,0,255},{__cp949_encmap+31191 -,0,255},{__cp949_encmap+31447,0,255},{__cp949_encmap+31703,0,255},{ -__cp949_encmap+31959,0,255},{__cp949_encmap+32215,0,255},{__cp949_encmap+32471 -,0,163},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+32635,0,255},{ -__cp949_encmap+32891,0,11},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+ -32903,1,230}, -}; +static const ucs2_t __ksx1001_decmap[8264] = { +12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217, +8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304, +12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504, +65505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733, +9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595, +8596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834, +8835,8746,8745,8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730, +729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828, +9824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639, +9638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600, +9837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174, +65281,65282,65283,65284,65285,65286,65287,65288,65289,65290,65291,65292,65293, +65294,65295,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65306, +65307,65308,65309,65310,65311,65312,65313,65314,65315,65316,65317,65318,65319, +65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332, +65333,65334,65335,65336,65337,65338,65339,65510,65341,65342,65343,65344,65345, +65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358, +65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371, +65372,65373,65507,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602, +12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615, +12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628, +12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641, +12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654, +12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667, +12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680, +12681,12682,12683,12684,12685,12686,8560,8561,8562,8563,8564,8565,8566,8567, +8568,8569,U,U,U,U,U,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,U,U,U,U, +U,U,U,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931, +932,933,934,935,936,937,U,U,U,U,U,U,U,U,945,946,947,948,949,950,951,952,953, +954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,9472,9474,9484, +9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507, +9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,9490, +9489,9498,9497,9494,9493,9486,9485,9502,9503,9505,9506,9510,9511,9513,9514, +9517,9518,9521,9522,9525,9526,9529,9530,9533,9534,9536,9537,9539,9540,9541, +9542,9543,9544,9545,9546,13205,13206,13207,8467,13208,13252,13219,13220,13221, +13222,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13258,13197, +13198,13199,13263,13192,13193,13256,13223,13224,13232,13233,13234,13235,13236, +13237,13238,13239,13240,13241,13184,13185,13186,13187,13188,13242,13243,13244, +13245,13246,13247,13200,13201,13202,13203,13204,8486,13248,13249,13194,13195, +13196,13270,13253,13229,13230,13231,13275,13225,13226,13227,13228,13277,13264, +13267,13251,13257,13276,13254,198,208,170,294,U,306,U,319,321,216,338,186,222, +358,330,U,12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906, +12907,12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919, +12920,12921,12922,12923,9424,9425,9426,9427,9428,9429,9430,9431,9432,9433, +9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446,9447,9448, +9449,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325, +9326,189,8531,8532,188,190,8539,8540,8541,8542,230,273,240,295,305,307,312, +320,322,248,339,223,254,359,331,329,12800,12801,12802,12803,12804,12805,12806, +12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819, +12820,12821,12822,12823,12824,12825,12826,12827,9372,9373,9374,9375,9376,9377, +9378,9379,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392, +9393,9394,9395,9396,9397,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341, +9342,9343,9344,9345,9346,185,178,179,8308,8319,8321,8322,8323,8324,12353, +12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366, +12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379, +12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392, +12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405, +12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418, +12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431, +12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457, +12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470, +12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483, +12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496, +12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509, +12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522, +12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,1040, +1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054, +1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069, +1070,1071,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,1072,1073,1074,1075,1076,1077,1105, +1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092, +1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,44032,44033,44036, +44039,44040,44041,44042,44048,44049,44050,44051,44052,44053,44054,44055,44057, +44058,44059,44060,44061,44064,44068,44076,44077,44079,44080,44081,44088,44089, +44092,44096,44107,44109,44116,44120,44124,44144,44145,44148,44151,44152,44154, +44160,44161,44163,44164,44165,44166,44169,44170,44171,44172,44176,44180,44188, +44189,44191,44192,44193,44200,44201,44202,44204,44207,44208,44216,44217,44219, +44220,44221,44225,44228,44232,44236,44245,44247,44256,44257,44260,44263,44264, +44266,44268,44271,44272,44273,44275,44277,44278,44284,44285,44288,44292,44294, +44300,44301,44303,44305,44312,44316,44320,44329,44332,44333,44340,44341,44344, +44348,44356,44357,44359,44361,44368,44372,44376,44385,44387,44396,44397,44400, +44403,44404,44405,44406,44411,44412,44413,44415,44417,44418,44424,44425,44428, +44432,44444,44445,44452,44471,44480,44481,44484,44488,44496,44497,44499,44508, +44512,44516,44536,44537,44540,44543,44544,44545,44552,44553,44555,44557,44564, +44592,44593,44596,44599,44600,44602,44608,44609,44611,44613,44614,44618,44620, +44621,44622,44624,44628,44630,44636,44637,44639,44640,44641,44645,44648,44649, +44652,44656,44664,44665,44667,44668,44669,44676,44677,44684,44732,44733,44734, +44736,44740,44748,44749,44751,44752,44753,44760,44761,44764,44776,44779,44781, +44788,44792,44796,44807,44808,44813,44816,44844,44845,44848,44850,44852,44860, +44861,44863,44865,44866,44867,44872,44873,44880,44892,44893,44900,44901,44921, +44928,44932,44936,44944,44945,44949,44956,44984,44985,44988,44992,44999,45000, +45001,45003,45005,45006,45012,45020,45032,45033,45040,45041,45044,45048,45056, +45057,45060,45068,45072,45076,45084,45085,45096,45124,45125,45128,45130,45132, +45134,45139,45140,45141,45143,45145,45149,45180,45181,45184,45188,45196,45197, +45199,45201,45208,45209,45210,45212,45215,45216,45217,45218,45224,45225,45227, +45228,45229,45230,45231,45233,45235,45236,45237,45240,45244,45252,45253,45255, +45256,45257,45264,45265,45268,45272,45280,45285,45320,45321,45323,45324,45328, +45330,45331,45336,45337,45339,45340,45341,45347,45348,45349,45352,45356,45364, +45365,45367,45368,45369,45376,45377,45380,45384,45392,45393,45396,45397,45400, +45404,45408,45432,45433,45436,45440,45442,45448,45449,45451,45453,45458,45459, +45460,45464,45468,45480,45516,45520,45524,45532,45533,45535,45544,45545,45548, +45552,45561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591,45593, +45600,45620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700,45701, +45705,45712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734,45738, +45740,45744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789,45794, +45796,45797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813,45815, +45816,45817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843,45844, +45845,45852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925,45927, +45929,45931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957,45964, +45968,45972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030,46032, +46036,46037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104,46108, +46112,46120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179,46181, +46188,46208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276,46280, +46288,46293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321,46328, +46356,46357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384,46385, +46388,46392,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420,46428, +46429,46431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513,46515, +46516,46517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545,46552, +46572,46608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748,46749, +46752,46756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853,46888, +46889,46892,46895,46896,46904,46905,46907,46916,46920,46924,46932,46933,46944, +46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,46988,46989,46991, +46992,46993,46994,46998,46999,47000,47001,47004,47008,47016,47017,47019,47020, +47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,47100,47101,47103, +47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,47133,47140,47141, +47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,47187,47196,47197, +47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,47280,47284,47288, +47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,47336,47337,47340, +47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,47424,47428,47436, +47439,47441,47448,47449,47452,47456,47464,47465,47467,47469,47476,47477,47480, +47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,47536,47540,47548, +47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,47570,47576,47577, +47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,47605,47607,47608, +47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,47682,47688,47689, +47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,47719,47720,47721, +47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,47785,47787,47788, +47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,47868,47872,47876, +47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,47926,47928,47931, +47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,47956,47960,47969, +47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,48064,48068,48072, +48080,48083,48120,48121,48124,48127,48128,48130,48136,48137,48139,48140,48141, +48143,48145,48148,48149,48150,48151,48152,48155,48156,48157,48158,48159,48164, +48165,48167,48169,48173,48176,48177,48180,48184,48192,48193,48195,48196,48197, +48201,48204,48205,48208,48221,48260,48261,48264,48267,48268,48270,48276,48277, +48279,48281,48282,48288,48289,48292,48295,48296,48304,48305,48307,48308,48309, +48316,48317,48320,48324,48333,48335,48336,48337,48341,48344,48348,48372,48373, +48374,48376,48380,48388,48389,48391,48393,48400,48404,48420,48428,48448,48456, +48457,48460,48464,48472,48473,48484,48488,48512,48513,48516,48519,48520,48521, +48522,48528,48529,48531,48533,48537,48538,48540,48548,48560,48568,48596,48597, +48600,48604,48617,48624,48628,48632,48640,48643,48645,48652,48653,48656,48660, +48668,48669,48671,48708,48709,48712,48716,48718,48724,48725,48727,48729,48730, +48731,48736,48737,48740,48744,48746,48752,48753,48755,48756,48757,48763,48764, +48765,48768,48772,48780,48781,48783,48784,48785,48792,48793,48808,48848,48849, +48852,48855,48856,48864,48867,48868,48869,48876,48897,48904,48905,48920,48921, +48923,48924,48925,48960,48961,48964,48968,48976,48977,48981,49044,49072,49093, +49100,49101,49104,49108,49116,49119,49121,49212,49233,49240,49244,49248,49256, +49257,49296,49297,49300,49304,49312,49313,49315,49317,49324,49325,49327,49328, +49331,49332,49333,49334,49340,49341,49343,49344,49345,49349,49352,49353,49356, +49360,49368,49369,49371,49372,49373,49380,49381,49384,49388,49396,49397,49399, +49401,49408,49412,49416,49424,49429,49436,49437,49438,49439,49440,49443,49444, +49446,49447,49452,49453,49455,49456,49457,49462,49464,49465,49468,49472,49480, +49481,49483,49484,49485,49492,49493,49496,49500,49508,49509,49511,49512,49513, +49520,49524,49528,49541,49548,49549,49550,49552,49556,49558,49564,49565,49567, +49569,49573,49576,49577,49580,49584,49597,49604,49608,49612,49620,49623,49624, +49632,49636,49640,49648,49649,49651,49660,49661,49664,49668,49676,49677,49679, +49681,49688,49689,49692,49695,49696,49704,49705,49707,49709,49711,49713,49714, +49716,49736,49744,49745,49748,49752,49760,49765,49772,49773,49776,49780,49788, +49789,49791,49793,49800,49801,49808,49816,49819,49821,49828,49829,49832,49836, +49837,49844,49845,49847,49849,49884,49885,49888,49891,49892,49899,49900,49901, +49903,49905,49910,49912,49913,49915,49916,49920,49928,49929,49932,49933,49939, +49940,49941,49944,49948,49956,49957,49960,49961,49989,50024,50025,50028,50032, +50034,50040,50041,50044,50045,50052,50056,50060,50112,50136,50137,50140,50143, +50144,50146,50152,50153,50157,50164,50165,50168,50184,50192,50212,50220,50224, +50228,50236,50237,50248,50276,50277,50280,50284,50292,50293,50297,50304,50324, +50332,50360,50364,50409,50416,50417,50420,50424,50426,50431,50432,50433,50444, +50448,50452,50460,50472,50473,50476,50480,50488,50489,50491,50493,50500,50501, +50504,50505,50506,50508,50509,50510,50515,50516,50517,50519,50520,50521,50525, +50526,50528,50529,50532,50536,50544,50545,50547,50548,50549,50556,50557,50560, +50564,50567,50572,50573,50575,50577,50581,50583,50584,50588,50592,50601,50612, +50613,50616,50617,50619,50620,50621,50622,50628,50629,50630,50631,50632,50633, +50634,50636,50638,50640,50641,50644,50648,50656,50657,50659,50661,50668,50669, +50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,50693,50694, +50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,50732,50733, +50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,50760,50768, +50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,50809,50812, +50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,50855,50857, +50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,50893,50896, +50900,50908,50909,50912,50913,50920,50921,50924,50928,50936,50937,50941,50948, +50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,50992,50993, +50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,51025,51026, +51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,51061,51064, +51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,51088,51089, +51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,51116,51117, +51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,51152,51160, +51165,51172,51176,51180,51200,51201,51204,51208,51210,51216,51217,51219,51221, +51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,51264,51272, +51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,51331,51333, +51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,51389,51396, +51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,51453,51456, +51460,51461,51462,51468,51469,51471,51473,51480,51500,51508,51536,51537,51540, +51544,51552,51553,51555,51564,51568,51572,51580,51592,51593,51596,51600,51608, +51609,51611,51613,51648,51649,51652,51655,51656,51658,51664,51665,51667,51669, +51670,51673,51674,51676,51677,51680,51682,51684,51687,51692,51693,51695,51696, +51697,51704,51705,51708,51712,51720,51721,51723,51724,51725,51732,51736,51753, +51788,51789,51792,51796,51804,51805,51807,51808,51809,51816,51837,51844,51864, +51900,51901,51904,51908,51916,51917,51919,51921,51923,51928,51929,51936,51948, +51956,51976,51984,51988,51992,52000,52001,52033,52040,52041,52044,52048,52056, +52057,52061,52068,52088,52089,52124,52152,52180,52196,52199,52201,52236,52237, +52240,52244,52252,52253,52257,52258,52263,52264,52265,52268,52270,52272,52280, +52281,52283,52284,52285,52286,52292,52293,52296,52300,52308,52309,52311,52312, +52313,52320,52324,52326,52328,52336,52341,52376,52377,52380,52384,52392,52393, +52395,52396,52397,52404,52405,52408,52412,52420,52421,52423,52425,52432,52436, +52452,52460,52464,52481,52488,52489,52492,52496,52504,52505,52507,52509,52516, +52520,52524,52537,52572,52576,52580,52588,52589,52591,52593,52600,52616,52628, +52629,52632,52636,52644,52645,52647,52649,52656,52676,52684,52688,52712,52716, +52720,52728,52729,52731,52733,52740,52744,52748,52756,52761,52768,52769,52772, +52776,52784,52785,52787,52789,52824,52825,52828,52831,52832,52833,52840,52841, +52843,52845,52852,52853,52856,52860,52868,52869,52871,52873,52880,52881,52884, +52888,52896,52897,52899,52900,52901,52908,52909,52929,52964,52965,52968,52971, +52972,52980,52981,52983,52984,52985,52992,52993,52996,53000,53008,53009,53011, +53013,53020,53024,53028,53036,53037,53039,53040,53041,53048,53076,53077,53080, +53084,53092,53093,53095,53097,53104,53105,53108,53112,53120,53125,53132,53153, +53160,53168,53188,53216,53217,53220,53224,53232,53233,53235,53237,53244,53248, +53252,53265,53272,53293,53300,53301,53304,53308,53316,53317,53319,53321,53328, +53332,53336,53344,53356,53357,53360,53364,53372,53373,53377,53412,53413,53416, +53420,53428,53429,53431,53433,53440,53441,53444,53448,53449,53456,53457,53459, +53460,53461,53468,53469,53472,53476,53484,53485,53487,53488,53489,53496,53517, +53552,53553,53556,53560,53562,53568,53569,53571,53572,53573,53580,53581,53584, +53588,53596,53597,53599,53601,53608,53612,53628,53636,53640,53664,53665,53668, +53672,53680,53681,53683,53685,53690,53692,53696,53720,53748,53752,53767,53769, +53776,53804,53805,53808,53812,53820,53821,53823,53825,53832,53852,53860,53888, +53889,53892,53896,53904,53905,53909,53916,53920,53924,53932,53937,53944,53945, +53948,53951,53952,53954,53960,53961,53963,53972,53976,53980,53988,53989,54000, +54001,54004,54008,54016,54017,54019,54021,54028,54029,54030,54032,54036,54038, +54044,54045,54047,54048,54049,54053,54056,54057,54060,54064,54072,54073,54075, +54076,54077,54084,54085,54140,54141,54144,54148,54156,54157,54159,54160,54161, +54168,54169,54172,54176,54184,54185,54187,54189,54196,54200,54204,54212,54213, +54216,54217,54224,54232,54241,54243,54252,54253,54256,54260,54268,54269,54271, +54273,54280,54301,54336,54340,54364,54368,54372,54381,54383,54392,54393,54396, +54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484,54492, +54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549,54551, +54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624,54629, +54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664,54665, +54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756,54757, +54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801,54803, +54804,54805,54812,54816,54820,54829,54840,54841,54844,54848,54853,54856,54857, +54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900,54915, +54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969,54971, +54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024,55029, +55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083,55085, +55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127,55128, +55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169,55176, +55177,55180,55184,55192,55193,55195,55197,20285,20339,20551,20729,21152,21487, +21621,21733,22025,23233,23478,26247,26550,26551,26607,27468,29634,30146,31292, +33499,33540,34903,34952,35382,36040,36303,36603,36838,39381,21051,21364,21508, +24682,24932,27580,29647,33050,35258,35282,38307,20355,21002,22718,22904,23014, +24178,24185,25031,25536,26438,26604,26751,28567,30286,30475,30965,31240,31487, +31777,32925,33390,33393,35563,38291,20075,21917,26359,28212,30883,31469,33883, +35088,34638,38824,21208,22350,22570,23884,24863,25022,25121,25954,26577,27204, +28187,29976,30131,30435,30640,32058,37039,37969,37970,40853,21283,23724,30002, +32987,37440,38296,21083,22536,23004,23713,23831,24247,24378,24394,24951,27743, +30074,30086,31968,32115,32177,32652,33108,33313,34193,35137,35611,37628,38477, +40007,20171,20215,20491,20977,22607,24887,24894,24936,25913,27114,28433,30117, +30342,30422,31623,33445,33995,63744,37799,38283,21888,23458,22353,63745,31923, +32697,37301,20520,21435,23621,24040,25298,25454,25818,25831,28192,28844,31067, +36317,36382,63746,36989,37445,37624,20094,20214,20581,24062,24314,24838,26967, +33137,34388,36423,37749,39467,20062,20625,26480,26688,20745,21133,21138,27298, +30652,37392,40660,21163,24623,36850,20552,25001,25581,25802,26684,27268,28608, +33160,35233,38548,22533,29309,29356,29956,32121,32365,32937,35211,35700,36963, +40273,25225,27770,28500,32080,32570,35363,20860,24906,31645,35609,37463,37772, +20140,20435,20510,20670,20742,21185,21197,21375,22384,22659,24218,24465,24950, +25004,25806,25964,26223,26299,26356,26775,28039,28805,28913,29855,29861,29898, +30169,30828,30956,31455,31478,32069,32147,32789,32831,33051,33686,35686,36629, +36885,37857,38915,38968,39514,39912,20418,21843,22586,22865,23395,23622,24760, +25106,26690,26800,26856,28330,30028,30328,30926,31293,31995,32363,32380,35336, +35489,35903,38542,40388,21476,21481,21578,21617,22266,22993,23396,23611,24235, +25335,25911,25925,25970,26272,26543,27073,27837,30204,30352,30590,31295,32660, +32771,32929,33167,33510,33533,33776,34241,34865,34996,35493,63747,36764,37678, +38599,39015,39640,40723,21741,26011,26354,26767,31296,35895,40288,22256,22372, +23825,26118,26801,26829,28414,29736,34974,39908,27752,63748,39592,20379,20844, +20849,21151,23380,24037,24656,24685,25329,25511,25915,29657,31354,34467,36002, +38799,20018,23521,25096,26524,29916,31185,33747,35463,35506,36328,36942,37707, +38982,24275,27112,34303,37101,63749,20896,23448,23532,24931,26874,27454,28748, +29743,29912,31649,32592,33733,35264,36011,38364,39208,21038,24669,25324,36866, +20362,20809,21281,22745,24291,26336,27960,28826,29378,29654,31568,33009,37979, +21350,25499,32619,20054,20608,22602,22750,24618,24871,25296,27088,39745,23439, +32024,32945,36703,20132,20689,21676,21932,23308,23968,24039,25898,25934,26657, +27211,29409,30350,30703,32094,32761,33184,34126,34527,36611,36686,37066,39171, +39509,39851,19992,20037,20061,20167,20465,20855,21246,21312,21475,21477,21646, +22036,22389,22434,23495,23943,24272,25084,25304,25937,26552,26601,27083,27472, +27590,27628,27714,28317,28792,29399,29590,29699,30655,30697,31350,32127,32777, +33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,37476,37558,39378, +39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,21531,31384,32676, +35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,31406,33422,36524, +20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,21413,29527,34152, +36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,27512,36020,39740, +63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,31998,33909,35215, +36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,27224,20811,21067, +21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,26681,27135,29822, +31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,25810,26129,27278, +29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,21450,24613,25201, +27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,20864,21980,22120, +22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,24190,24524,25216, +26071,26083,26398,26399,26462,26827,26820,27231,27450,27683,27773,27778,28103, +29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,31047,31048,31098, +31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,36215,37665,37668, +39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,26708,37329,21931, +20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,63760,63761,63762, +63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,63771,63772,26262, +63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,26511,26976,28275, +63778,30007,63779,63780,63781,32013,63782,63783,34930,22218,23064,63784,63785, +63786,63787,63788,20035,63789,20839,22856,26608,32784,63790,22899,24180,25754, +31178,24565,24684,25288,25467,23527,23511,21162,63791,22900,24361,24594,63792, +63793,63794,29785,63795,63796,63797,63798,63799,63800,39377,63801,63802,63803, +63804,63805,63806,63807,63808,63809,63810,63811,28611,63812,63813,33215,36786, +24817,63814,63815,33126,63816,63817,23615,63818,63819,63820,63821,63822,63823, +63824,63825,23273,35365,26491,32016,63826,63827,63828,63829,63830,63831,33021, +63832,63833,23612,27877,21311,28346,22810,33590,20025,20150,20294,21934,22296, +22727,24406,26039,26086,27264,27573,28237,30701,31471,31774,32222,34507,34962, +37170,37723,25787,28606,29562,30136,36948,21846,22349,25018,25812,26311,28129, +28251,28525,28601,30192,32835,33213,34113,35203,35527,35674,37663,27795,30035, +31572,36367,36957,21776,22530,22616,24162,25095,25758,26848,30070,31958,34739, +40680,20195,22408,22382,22823,23565,23729,24118,24453,25140,25825,29619,33274, +34955,36024,38538,40667,23429,24503,24755,20498,20992,21040,22294,22581,22615, +23566,23648,23798,23947,24230,24466,24764,25361,25481,25623,26691,26873,27330, +28120,28193,28372,28644,29182,30428,30585,31153,31291,33796,35241,36077,36339, +36424,36867,36884,36947,37117,37709,38518,38876,27602,28678,29272,29346,29544, +30563,31167,31716,32411,35712,22697,24775,25958,26109,26302,27788,28958,29129, +35930,38931,20077,31361,20189,20908,20941,21205,21516,24999,26481,26704,26847, +27934,28540,30140,30643,31461,33012,33891,37509,20828,26007,26460,26515,30168, +31431,33651,63834,35910,36887,38957,23663,33216,33434,36929,36975,37389,24471, +23965,27225,29128,30331,31561,34276,35588,37159,39472,21895,25078,63835,30313, +32645,34367,34746,35064,37007,63836,27931,28889,29662,32097,33853,63837,37226, +39409,63838,20098,21365,27396,27410,28734,29211,34349,40478,21068,36771,23888, +25829,25900,27414,28651,31811,32412,34253,35172,35261,25289,33240,34847,24266, +26391,28010,29436,29701,29807,34690,37086,20358,23821,24480,33802,20919,25504, +30053,20142,20486,20841,20937,26753,27153,31918,31921,31975,33391,35538,36635, +37327,20406,20791,21237,21570,24300,24942,25150,26053,27354,28670,31018,34268, +34851,38317,39522,39530,40599,40654,21147,26310,27511,28701,31019,36706,38722, +24976,25088,25891,28451,29001,29833,32244,32879,34030,36646,36899,37706,20925, +21015,21155,27916,28872,35010,24265,25986,27566,28610,31806,29557,20196,20278, +22265,63839,23738,23994,24604,29618,31533,32666,32718,32838,36894,37428,38646, +38728,38936,40801,20363,28583,31150,37300,38583,21214,63840,25736,25796,27347, +28510,28696,29200,30439,32769,34310,34396,36335,36613,38706,39791,40442,40565, +30860,31103,32160,33737,37636,40575,40595,35542,22751,24324,26407,28711,29903, +31840,32894,20769,28712,29282,30922,36034,36058,36084,38647,20102,20698,23534, +24278,26009,29134,30274,30637,32842,34044,36988,39719,40845,22744,23105,23650, +27155,28122,28431,30267,32047,32311,34078,35128,37860,38475,21129,26066,26611, +27060,27969,28316,28687,29705,29792,30041,30244,30827,35628,39006,20845,25134, +38520,20374,20523,23833,28138,32184,36650,24459,24900,26647,63841,38534,21202, +32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,21519,21774, +23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,31852,32633, +32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,29848,34298, +36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,31435,31520,31890, +25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,33180,33707, +37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,28459,28771, +30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,33545,35178, +38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,36638,37017, +22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,36067,36993, +39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,33804,20906, +35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,40629,28357, +34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,33986,34719, +37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,25721,26286, +26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,33541,35584, +35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,22818,26406, +33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,33495,37672, +21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,28961,29687, +30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,20497,21006, +21563,21839,25991,27766,32010,32011,32862,34442,38272,38639,21247,27797,29289, +21619,23194,23614,23883,24396,24494,26410,26806,26979,28220,28228,30473,31859, +32654,34183,35598,36855,38753,40692,23735,24758,24845,25003,25935,26107,26108, +27665,27887,29599,29641,32225,38292,23494,34588,35600,21085,21338,25293,25615, +25778,26420,27192,27850,29632,29854,31636,31893,32283,33162,33334,34180,36843, +38649,39361,20276,21322,21453,21467,25292,25644,25856,26001,27075,27886,28504, +29677,30036,30242,30436,30460,30928,30971,31020,32070,33324,34784,36820,38930, +39151,21187,25300,25765,28196,28497,30332,36299,37297,37474,39662,39747,20515, +20621,22346,22952,23592,24135,24439,25151,25918,26041,26049,26121,26507,27036, +28354,30917,32033,32938,33152,33323,33459,33953,34444,35370,35607,37030,38450, +40848,20493,20467,63843,22521,24472,25308,25490,26479,28227,28953,30403,32972, +32986,35060,35061,35097,36064,36649,37197,38506,20271,20336,24091,26575,26658, +30333,30334,39748,24161,27146,29033,29140,30058,63844,32321,34115,34281,39132, +20240,31567,32624,38309,20961,24070,26805,27710,27726,27867,29359,31684,33539, +27861,29754,20731,21128,22721,25816,27287,29863,30294,30887,34327,38370,38713, +63845,21342,24321,35722,36776,36783,37002,21029,30629,40009,40712,19993,20482, +20853,23643,24183,26142,26170,26564,26821,28851,29953,30149,31177,31453,36647, +39200,39432,20445,22561,22577,23542,26222,27493,27921,28282,28541,29668,29995, +33769,35036,35091,35676,36628,20239,20693,21264,21340,23443,24489,26381,31119, +33145,33583,34068,35079,35206,36665,36667,39333,39954,26412,20086,20472,22857, +23553,23791,23792,25447,26834,28925,29090,29739,32299,34028,34562,36898,37586, +40179,19981,20184,20463,20613,21078,21103,21542,21648,22496,22827,23142,23386, +23413,23500,24220,63846,25206,25975,26023,28014,28325,29238,31526,31807,32566, +33104,33105,33178,33344,33433,33705,35331,36000,36070,36091,36212,36282,37096, +37340,38428,38468,39385,40167,21271,20998,21545,22132,22707,22868,22894,24575, +24996,25198,26128,27774,28954,30406,31881,31966,32027,33452,36033,38640,63847, +20315,24343,24447,25282,23849,26379,26842,30844,32323,40300,19989,20633,21269, +21290,21329,22915,23138,24199,24754,24970,25161,25209,26000,26503,27047,27604, +27606,27607,27608,27832,63848,29749,30202,30738,30865,31189,31192,31875,32203, +32737,32933,33086,33218,33778,34586,35048,35513,35692,36027,37145,38750,39131, +40763,22188,23338,24428,25996,27315,27567,27996,28657,28693,29277,29613,36007, +36051,38971,24977,27703,32856,39425,20045,20107,20123,20181,20282,20284,20351, +20447,20735,21490,21496,21766,21987,22235,22763,22882,23057,23531,23546,23556, +24051,24107,24473,24605,25448,26012,26031,26614,26619,26797,27515,27801,27863, +28195,28681,29509,30722,31038,31040,31072,31169,31721,32023,32114,32902,33293, +33678,34001,34503,35039,35408,35422,35613,36060,36198,36781,37034,39164,39391, +40605,21066,63849,26388,63850,20632,21034,23665,25955,27733,29642,29987,30109, +31639,33948,37240,38704,20087,25746,27578,29022,34217,19977,63851,26441,26862, +28183,33439,34072,34923,25591,28545,37394,39087,19978,20663,20687,20767,21830, +21930,22039,23360,23577,23776,24120,24202,24224,24258,24819,26705,27233,28248, +29245,29248,29376,30456,31077,31665,32724,35059,35316,35443,35937,36062,38684, +22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,63853,31513, +22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,26329,26360, +26646,26866,29312,29790,31598,32110,32214,32626,32997,33298,34223,35199,35475, +36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,27728,28101, +28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,23459,25159, +25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,32341,32680, +33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,39854,21352, +23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,40807,21089, +26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,22478,22995, +23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,32854,32882, +33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,36016,21484, +22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,27836,28040, +28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,32032,32057, +34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,23660,26463, +28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,39137,29575, +23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,30862,37782, +34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,23744,24101, +24833,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,28465,29159, +29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,32172,32353, +32670,33065,33585,33936,34010,34282,34966,35504,35728,36664,36930,36995,37228, +37526,37561,38539,38567,38568,38614,38656,38920,39318,39635,39706,21460,22654, +22809,23408,23487,28113,28506,29087,29729,29881,32901,33789,24033,24455,24490, +24642,26092,26642,26991,27219,27529,27957,28147,29667,30462,30636,31565,32020, +33059,33308,33600,34036,34147,35426,35524,37255,37662,38918,39348,25100,34899, +36848,37477,23815,23847,23913,29791,33181,34664,28629,25342,32722,35126,35186, +19998,20056,20711,21213,21319,25215,26119,32361,34821,38494,20365,21273,22070, +22987,23204,23608,23630,23629,24066,24337,24643,26045,26159,26178,26558,26612, +29468,30690,31034,32709,33940,33997,35222,35430,35433,35553,35925,35962,22516, +23508,24335,24687,25325,26893,27542,28252,29060,31698,34645,35672,36606,39135, +39166,20280,20353,20449,21627,23072,23480,24892,26032,26216,29180,30003,31070, +32051,33102,33251,33688,34218,34254,34563,35338,36523,36763,63857,36805,22833, +23460,23526,24713,23529,23563,24515,27777,63858,28145,28683,29978,33455,35574, +20160,21313,63859,38617,27663,20126,20420,20818,21854,23077,23784,25105,29273, +33469,33706,34558,34905,35357,38463,38597,39187,40201,40285,22538,23731,23997, +24132,24801,24853,25569,27138,28197,37122,37716,38990,39952,40823,23433,23736, +25353,26191,26696,30524,38593,38797,38996,39839,26017,35585,36555,38332,21813, +23721,24022,24245,26263,30284,33780,38343,22739,25276,29390,40232,20208,22830, +24591,26171,27523,31207,40230,21395,21696,22467,23830,24859,26326,28079,30861, +33406,38552,38724,21380,25212,25494,28082,32266,33099,38989,27387,32588,40367, +40474,20063,20539,20918,22812,24825,25590,26928,29242,32822,63860,37326,24369, +63861,63862,32004,33509,33903,33979,34277,36493,63863,20335,63864,63865,22756, +23363,24665,25562,25880,25965,26264,63866,26954,27171,27915,28673,29036,30162, +30221,31155,31344,63867,32650,63868,35140,63869,35731,37312,38525,63870,39178, +22276,24481,26044,28417,30208,31142,35486,39341,39770,40812,20740,25014,25233, +27277,33222,20547,22576,24422,28937,35328,35578,23420,34326,20474,20796,22196, +22852,25513,28153,23978,26989,20870,20104,20313,63871,63872,63873,22914,63874, +63875,27487,27741,63876,29877,30998,63877,33287,33349,33593,36671,36701,63878, +39192,63879,63880,63881,20134,63882,22495,24441,26131,63883,63884,30123,32377, +35695,63885,36870,39515,22181,22567,23032,23071,23476,63886,24310,63887,63888, +25424,25403,63889,26941,27783,27839,28046,28051,28149,28436,63890,28895,28982, +29017,63891,29123,29141,63892,30799,30831,63893,31605,32227,63894,32303,63895, +34893,36575,63896,63897,63898,37467,63899,40182,63900,63901,63902,24709,28037, +63903,29105,63904,63905,38321,21421,63906,63907,63908,26579,63909,28814,28976, +29744,33398,33490,63910,38331,39653,40573,26308,63911,29121,33865,63912,63913, +22603,63914,63915,23992,24433,63916,26144,26254,27001,27054,27704,27891,28214, +28481,28634,28699,28719,29008,29151,29552,63917,29787,63918,29908,30408,31310, +32403,63919,63920,33521,35424,36814,63921,37704,63922,38681,63923,63924,20034, +20522,63925,21000,21473,26355,27757,28618,29450,30591,31330,33454,34269,34306, +63926,35028,35427,35709,35947,63927,37555,63928,38675,38928,20116,20237,20425, +20658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,63929,25034, +25942,26111,26212,26791,27738,28595,28879,29100,29522,31613,34568,35492,39986, +40711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,34314,20800, +22725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,31401,31402, +33253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,29715,29740, +30871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,26106,26505, +27754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,63930,63931, +20709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,25622,25747, +25854,63934,26332,63935,27208,63936,29183,29796,63937,31368,31407,32327,32350, +32768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,27442,28020, +32287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,24898,27029, +28044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,37780,37854, +63940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,24858,24962, +26100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,34261,34398, +36802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,26671,29020, +31286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,34131,36939, +38549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,22291,22290, +22435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,29232,29503, +29783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,37470,20301, +20553,20702,21361,22285,22996,23041,23561,24944,26256,28205,29234,29771,32239, +32963,33806,33894,34111,34655,34907,35096,35586,36949,38859,39759,20083,20369, +20754,20842,63943,21807,21929,23418,23461,24188,24189,24254,24736,24799,24840, +24841,25540,25912,26377,63944,26580,26586,63945,26977,26978,27833,27943,63946, +28216,63947,28641,29494,29495,63948,29788,30001,63949,30290,63950,63951,32173, +33278,33848,35029,35480,35547,35565,36400,36418,36938,36926,36986,37193,37321, +37742,63952,63953,22537,63954,27603,32905,32946,63955,63956,20801,22891,23609, +63957,63958,28516,29607,32996,36103,63959,37399,38287,63960,63961,63962,63963, +32895,25102,28700,32104,34701,63964,22432,24681,24903,27575,35518,37504,38577, +20057,21535,28139,34093,38512,38899,39150,25558,27875,37009,20957,25033,33210, +40441,20381,20506,20736,23452,24847,25087,25836,26885,27589,30097,30691,32681, +33380,34191,34811,34915,35516,35696,37291,20108,20197,20234,63965,63966,22839, +23016,63967,24050,24347,24411,24609,63968,63969,63970,63971,29246,29669,63972, +30064,30157,63973,31227,63974,32780,32819,32900,33505,33617,63975,63976,36029, +36019,36999,63977,63978,39156,39180,63979,63980,28727,30410,32714,32716,32764, +35610,20154,20161,20995,21360,63981,21693,22240,23035,23493,24341,24525,28270, +63982,63983,32106,33589,63984,34451,35469,63985,38765,38775,63986,63987,19968, +20314,20350,22777,26085,28322,36920,37808,39353,20219,22764,22922,23001,24641, +63988,63989,31252,63990,33615,36035,20837,21316,63991,63992,63993,20173,21097, +23381,33471,20180,21050,21672,22985,23039,23376,23383,23388,24675,24904,28363, +28825,29038,29574,29943,30133,30913,32043,32773,33258,33576,34071,34249,35566, +36039,38604,20316,21242,22204,26027,26152,28796,28856,29237,32189,33421,37196, +38592,40306,23409,26855,27544,28538,30430,23697,26283,28507,31668,31786,34870, +38620,19976,20183,21280,22580,22715,22767,22892,23559,24115,24196,24373,25484, +26290,26454,27167,27299,27404,28479,29254,63994,29520,29835,31456,31911,33144, +33247,33255,33674,33900,34083,34196,34255,35037,36115,37292,38263,38556,20877, +21705,22312,23472,25165,26448,26685,26771,28221,28371,28797,32289,35009,36001, +36617,40779,40782,29229,31631,35533,37658,20295,20302,20786,21632,22992,24213, +25269,26485,26990,27159,27822,28186,29401,29482,30141,31672,32053,33511,33785, +33879,34295,35419,36015,36487,36889,37048,38606,40799,21219,21514,23265,23490, +25688,25973,28404,29380,63995,30340,31309,31515,31821,32318,32735,33659,35627, +36042,36196,36321,36447,36842,36857,36969,37841,20291,20346,20659,20840,20856, +21069,21098,22625,22652,22880,23560,23637,24283,24731,25136,26643,27583,27656, +28593,29006,29728,30000,30008,30033,30322,31564,31627,31661,31686,32399,35438, +36670,36681,37439,37523,37666,37931,38651,39002,39019,39198,20999,25130,25240, +27993,30308,31434,31680,32118,21344,23742,24215,28472,28857,31896,38673,39822, +40670,25509,25722,34678,19969,20117,20141,20572,20597,21576,22979,23450,24128, +24237,24311,24449,24773,25402,25919,25972,26060,26230,26232,26622,26984,27273, +27491,27712,28096,28136,28191,28254,28702,28833,29582,29693,30010,30555,30855, +31118,31243,31357,31934,32142,33351,35330,35562,35998,37165,37194,37336,37478, +37580,37664,38662,38742,38748,38914,40718,21046,21137,21884,22564,24093,24351, +24716,25552,26799,28639,31085,31532,33229,34234,35069,35576,36420,37261,38500, +38555,38717,38988,40778,20430,20806,20939,21161,22066,24340,24427,25514,25805, +26089,26177,26362,26361,26397,26781,26839,27133,28437,28526,29031,29157,29226, +29866,30522,31062,31066,31199,31264,31381,31895,31967,32068,32368,32903,34299, +34468,35412,35519,36249,36481,36896,36973,37347,38459,38613,40165,26063,31751, +36275,37827,23384,23562,21330,25305,29469,20519,23447,24478,24752,24939,26837, +28121,29742,31278,32066,32156,32305,33131,36394,36405,37758,37912,20304,22352, +24038,24231,25387,32618,20027,20303,20367,20570,23005,32964,21610,21608,22014, +22863,23449,24030,24282,26205,26417,26609,26666,27880,27954,28234,28557,28855, +29664,30087,31820,32002,32044,32162,33311,34523,35387,35461,36208,36490,36659, +36913,37198,37202,37956,39376,31481,31909,20426,20737,20934,22472,23535,23803, +26201,27197,27994,28310,28652,28940,30063,31459,34850,36897,36981,38603,39423, +33537,20013,20210,34886,37325,21373,27355,26987,27713,33914,22686,24974,26366, +25327,28893,29969,30151,32338,33976,35657,36104,20043,21482,21675,22320,22336, +24535,25345,25351,25711,25903,26088,26234,26525,26547,27490,27744,27802,28460, +30693,30757,31049,31063,32025,32930,33026,33267,33437,33463,34584,35468,63996, +36100,36286,36978,30452,31257,31287,32340,32887,21767,21972,22645,25391,25634, +26185,26187,26733,27035,27524,27941,28337,29645,29800,29857,30043,30137,30433, +30494,30603,31206,32265,32285,33275,34095,34967,35386,36049,36587,36784,36914, +37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,29894,30142,31209, +31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,28503,32221,36655, +37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,23919,24046,27425, +27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,31364,37679,38015, +40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,32408,35738,36106, +38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,22649,24920,24921, +25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,24288,24432,24884, +25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,33081,33369,33750, +33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,34081,37319,37365, +20874,26613,31574,36012,20932,22971,24765,34389,20508,63999,21076,23610,24957, +25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,20191,21315,21912, +22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,36368,36983,37351, +38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,36639,36685,37941, +20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,22558,22974,24086, +25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,32893,33729,35531, +38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,36958,39636,21021, +21119,21736,24980,25220,25307,26786,26898,26970,27189,28818,28966,30813,30977, +30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,37218,37259,37294, +20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,21474,22618,23541, +24740,24961,25696,32317,32880,34085,37507,25774,20652,23828,26368,22684,25277, +25512,26894,27000,27166,28267,30394,31179,33467,33833,35535,36264,36861,37138, +37195,37276,37648,37656,37786,38619,39478,39949,19985,30044,31069,31482,31569, +31689,32302,33988,36441,36468,36600,36880,26149,26943,29763,20986,26414,40668, +20805,24544,27798,34802,34909,34935,24756,33205,33795,36101,21462,21561,22068, +23094,23601,28810,32736,32858,33030,33261,36259,37257,39519,40434,20596,20164, +21408,24827,28204,23652,20360,20516,21988,23769,24159,24677,26772,27835,28100, +29118,30164,30196,30305,31258,31305,32199,32251,32622,33268,34473,36636,38601, +39347,40786,21063,21189,39149,35242,19971,26578,28422,20405,23522,26517,27784, +28024,29723,30759,37341,37756,34756,31204,31281,24555,20182,21668,21822,22702, +22949,24816,25171,25302,26422,26965,33333,38464,39345,39389,20524,21331,21828, +22396,64001,25176,64002,25826,26219,26589,28609,28655,29730,29752,35351,37944, +21585,22022,22374,24392,24986,27470,28760,28845,32187,35477,22890,33067,25506, +30472,32829,36010,22612,25645,27067,23445,24081,28271,64003,34153,20812,21488, +22826,24608,24907,27526,27760,27888,31518,32974,33492,36294,37040,39089,64004, +25799,28580,25745,25860,20814,21520,22303,35342,24927,26742,64005,30171,31570, +32113,36890,22534,27084,33151,35114,36864,38969,20600,22871,22956,25237,36879, +39722,24925,29305,38358,22369,23110,24052,25226,25773,25850,26487,27874,27966, +29228,29750,30772,32631,33453,36315,38935,21028,22338,26495,29256,29923,36009, +36774,37393,38442,20843,21485,25420,20329,21764,24726,25943,27803,28031,29260, +29437,31255,35207,35997,24429,28558,28921,33192,24846,20415,20559,25153,29255, +31687,32232,32745,36941,38829,39449,36022,22378,24179,26544,33805,35413,21536, +23318,24163,24290,24330,25987,32954,34109,38281,38491,20296,21253,21261,21263, +21638,21754,22275,24067,24598,25243,25265,25429,64006,27873,28006,30129,30770, +32990,33071,33502,33889,33970,34957,35090,36875,37610,39165,39825,24133,26292, +26333,28689,29190,64007,20469,21117,24426,24915,26451,27161,28418,29922,31080, +34920,35961,39111,39108,39491,21697,31263,26963,35575,35914,39080,39342,24444, +25259,30130,30382,34987,36991,38466,21305,24380,24517,27852,29644,30050,30091, +31558,33534,39325,20047,36924,19979,20309,21414,22799,24264,26160,27827,29781, +33655,34662,36032,36944,38686,39957,22737,23416,34384,35604,40372,23506,24680, +24717,26097,27735,28450,28579,28698,32597,32752,38289,38290,38480,38867,21106, +36676,20989,21547,21688,21859,21898,27323,28085,32216,33382,37532,38519,40569, +21512,21704,30418,34532,38308,38356,38492,20130,20233,23022,23270,24055,24658, +25239,26477,26689,27782,28207,32568,32923,33322,64008,64009,38917,20133,20565, +21683,22419,22874,23401,23475,25032,26999,28023,28707,34809,35299,35442,35559, +36994,39405,39608,21182,26680,20502,24184,26447,33607,34892,20139,21521,22190, +29670,37141,38911,39177,39255,39321,22099,22687,34395,35377,25010,27382,29563, +36562,27463,38570,39511,22869,29184,36203,38761,20436,23796,24358,25080,26203, +27883,28843,29572,29625,29694,30505,30541,32067,32098,32291,33335,34898,64010, +36066,37449,39023,23377,31348,34880,38913,23244,20448,21332,22846,23805,25406, +28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,24418,27842, +28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,37026,37795, +39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,20114,21628, +22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,28111,28246, +28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,31946,32286, +32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,39013,24785, +25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,21700,24344, +27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,27194,28779, +30069,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,25899,30906, +30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,26707,28185, +29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,20976,24140, +24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,28514,29004, +29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,24315,24458, +24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,33214,33588, +34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,25928,25989, +26313,26783,28045,28102,29243,32948,37237,39501,20399,20505,21402,21518,21564, +21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,22734,28932, +29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,21913,27585, +24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,30054,34407, +24676,35662,40440,20807,20982,21256,27958,33016,40657,26133,27427,28824,30165, +21507,23673,32007,35350,27424,27453,27462,21560,24688,27965,32725,33288,20694, +20958,21916,22123,22221,23020,23305,24076,24985,24984,25137,26206,26342,29081, +29113,29114,29351,31143,31232,32690,35440, +}; + +static const struct dbcs_index ksx1001_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{__ksx1001_decmap+0,33,126},{__ksx1001_decmap+ +94,33,103},{__ksx1001_decmap+165,33,126},{__ksx1001_decmap+259,33,126},{ +__ksx1001_decmap+353,33,120},{__ksx1001_decmap+441,33,100},{__ksx1001_decmap+ +509,33,111},{__ksx1001_decmap+588,33,126},{__ksx1001_decmap+682,33,126},{ +__ksx1001_decmap+776,33,115},{__ksx1001_decmap+859,33,118},{__ksx1001_decmap+ +945,33,113},{0,0,0},{0,0,0},{0,0,0},{__ksx1001_decmap+1026,33,126},{ +__ksx1001_decmap+1120,33,126},{__ksx1001_decmap+1214,33,126},{__ksx1001_decmap ++1308,33,126},{__ksx1001_decmap+1402,33,126},{__ksx1001_decmap+1496,33,126},{ +__ksx1001_decmap+1590,33,126},{__ksx1001_decmap+1684,33,126},{__ksx1001_decmap ++1778,33,126},{__ksx1001_decmap+1872,33,126},{__ksx1001_decmap+1966,33,126},{ +__ksx1001_decmap+2060,33,126},{__ksx1001_decmap+2154,33,126},{__ksx1001_decmap ++2248,33,126},{__ksx1001_decmap+2342,33,126},{__ksx1001_decmap+2436,33,126},{ +__ksx1001_decmap+2530,33,126},{__ksx1001_decmap+2624,33,126},{__ksx1001_decmap ++2718,33,126},{__ksx1001_decmap+2812,33,126},{__ksx1001_decmap+2906,33,126},{ +__ksx1001_decmap+3000,33,126},{__ksx1001_decmap+3094,33,126},{__ksx1001_decmap ++3188,33,126},{__ksx1001_decmap+3282,33,126},{0,0,0},{__ksx1001_decmap+3376, +33,126},{__ksx1001_decmap+3470,33,126},{__ksx1001_decmap+3564,33,126},{ +__ksx1001_decmap+3658,33,126},{__ksx1001_decmap+3752,33,126},{__ksx1001_decmap ++3846,33,126},{__ksx1001_decmap+3940,33,126},{__ksx1001_decmap+4034,33,126},{ +__ksx1001_decmap+4128,33,126},{__ksx1001_decmap+4222,33,126},{__ksx1001_decmap ++4316,33,126},{__ksx1001_decmap+4410,33,126},{__ksx1001_decmap+4504,33,126},{ +__ksx1001_decmap+4598,33,126},{__ksx1001_decmap+4692,33,126},{__ksx1001_decmap ++4786,33,126},{__ksx1001_decmap+4880,33,126},{__ksx1001_decmap+4974,33,126},{ +__ksx1001_decmap+5068,33,126},{__ksx1001_decmap+5162,33,126},{__ksx1001_decmap ++5256,33,126},{__ksx1001_decmap+5350,33,126},{__ksx1001_decmap+5444,33,126},{ +__ksx1001_decmap+5538,33,126},{__ksx1001_decmap+5632,33,126},{__ksx1001_decmap ++5726,33,126},{__ksx1001_decmap+5820,33,126},{__ksx1001_decmap+5914,33,126},{ +__ksx1001_decmap+6008,33,126},{__ksx1001_decmap+6102,33,126},{__ksx1001_decmap ++6196,33,126},{__ksx1001_decmap+6290,33,126},{__ksx1001_decmap+6384,33,126},{ +__ksx1001_decmap+6478,33,126},{__ksx1001_decmap+6572,33,126},{__ksx1001_decmap ++6666,33,126},{__ksx1001_decmap+6760,33,126},{__ksx1001_decmap+6854,33,126},{ +__ksx1001_decmap+6948,33,126},{__ksx1001_decmap+7042,33,126},{__ksx1001_decmap ++7136,33,126},{__ksx1001_decmap+7230,33,126},{__ksx1001_decmap+7324,33,126},{ +__ksx1001_decmap+7418,33,126},{__ksx1001_decmap+7512,33,126},{__ksx1001_decmap ++7606,33,126},{__ksx1001_decmap+7700,33,126},{__ksx1001_decmap+7794,33,126},{ +__ksx1001_decmap+7888,33,126},{__ksx1001_decmap+7982,33,126},{__ksx1001_decmap ++8076,33,126},{__ksx1001_decmap+8170,33,126},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +}, +}; + +static const ucs2_t __cp949ext_decmap[9650] = { +44034,44035,44037,44038,44043,44044,44045,44046,44047,44056,44062,44063,44065, +44066,44067,44069,44070,44071,44072,44073,44074,44075,44078,44082,44083,44084, +U,U,U,U,U,U,44085,44086,44087,44090,44091,44093,44094,44095,44097,44098,44099, +44100,44101,44102,44103,44104,44105,44106,44108,44110,44111,44112,44113,44114, +44115,44117,U,U,U,U,U,U,44118,44119,44121,44122,44123,44125,44126,44127,44128, +44129,44130,44131,44132,44133,44134,44135,44136,44137,44138,44139,44140,44141, +44142,44143,44146,44147,44149,44150,44153,44155,44156,44157,44158,44159,44162, +44167,44168,44173,44174,44175,44177,44178,44179,44181,44182,44183,44184,44185, +44186,44187,44190,44194,44195,44196,44197,44198,44199,44203,44205,44206,44209, +44210,44211,44212,44213,44214,44215,44218,44222,44223,44224,44226,44227,44229, +44230,44231,44233,44234,44235,44237,44238,44239,44240,44241,44242,44243,44244, +44246,44248,44249,44250,44251,44252,44253,44254,44255,44258,44259,44261,44262, +44265,44267,44269,44270,44274,44276,44279,44280,44281,44282,44283,44286,44287, +44289,44290,44291,44293,44295,44296,44297,44298,44299,44302,44304,44306,44307, +44308,44309,44310,44311,44313,44314,44315,44317,44318,44319,44321,44322,44323, +44324,44325,44326,44327,44328,44330,44331,44334,44335,44336,44337,44338,44339, +U,U,U,U,U,U,44342,44343,44345,44346,44347,44349,44350,44351,44352,44353,44354, +44355,44358,44360,44362,44363,44364,44365,44366,44367,44369,44370,44371,44373, +44374,44375,U,U,U,U,U,U,44377,44378,44379,44380,44381,44382,44383,44384,44386, +44388,44389,44390,44391,44392,44393,44394,44395,44398,44399,44401,44402,44407, +44408,44409,44410,44414,44416,44419,44420,44421,44422,44423,44426,44427,44429, +44430,44431,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,44443, +44446,44447,44448,44449,44450,44451,44453,44454,44455,44456,44457,44458,44459, +44460,44461,44462,44463,44464,44465,44466,44467,44468,44469,44470,44472,44473, +44474,44475,44476,44477,44478,44479,44482,44483,44485,44486,44487,44489,44490, +44491,44492,44493,44494,44495,44498,44500,44501,44502,44503,44504,44505,44506, +44507,44509,44510,44511,44513,44514,44515,44517,44518,44519,44520,44521,44522, +44523,44524,44525,44526,44527,44528,44529,44530,44531,44532,44533,44534,44535, +44538,44539,44541,44542,44546,44547,44548,44549,44550,44551,44554,44556,44558, +44559,44560,44561,44562,44563,44565,44566,44567,44568,44569,44570,44571,44572, +U,U,U,U,U,U,44573,44574,44575,44576,44577,44578,44579,44580,44581,44582,44583, +44584,44585,44586,44587,44588,44589,44590,44591,44594,44595,44597,44598,44601, +44603,44604,U,U,U,U,U,U,44605,44606,44607,44610,44612,44615,44616,44617,44619, +44623,44625,44626,44627,44629,44631,44632,44633,44634,44635,44638,44642,44643, +44644,44646,44647,44650,44651,44653,44654,44655,44657,44658,44659,44660,44661, +44662,44663,44666,44670,44671,44672,44673,44674,44675,44678,44679,44680,44681, +44682,44683,44685,44686,44687,44688,44689,44690,44691,44692,44693,44694,44695, +44696,44697,44698,44699,44700,44701,44702,44703,44704,44705,44706,44707,44708, +44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,44719,44720,44721, +44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,44735,44737,44738, +44739,44741,44742,44743,44744,44745,44746,44747,44750,44754,44755,44756,44757, +44758,44759,44762,44763,44765,44766,44767,44768,44769,44770,44771,44772,44773, +44774,44775,44777,44778,44780,44782,44783,44784,44785,44786,44787,44789,44790, +44791,44793,44794,44795,44797,44798,44799,44800,44801,44802,44803,44804,44805, +U,U,U,U,U,U,44806,44809,44810,44811,44812,44814,44815,44817,44818,44819,44820, +44821,44822,44823,44824,44825,44826,44827,44828,44829,44830,44831,44832,44833, +44834,44835,U,U,U,U,U,U,44836,44837,44838,44839,44840,44841,44842,44843,44846, +44847,44849,44851,44853,44854,44855,44856,44857,44858,44859,44862,44864,44868, +44869,44870,44871,44874,44875,44876,44877,44878,44879,44881,44882,44883,44884, +44885,44886,44887,44888,44889,44890,44891,44894,44895,44896,44897,44898,44899, +44902,44903,44904,44905,44906,44907,44908,44909,44910,44911,44912,44913,44914, +44915,44916,44917,44918,44919,44920,44922,44923,44924,44925,44926,44927,44929, +44930,44931,44933,44934,44935,44937,44938,44939,44940,44941,44942,44943,44946, +44947,44948,44950,44951,44952,44953,44954,44955,44957,44958,44959,44960,44961, +44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,44972,44973,44974, +44975,44976,44977,44978,44979,44980,44981,44982,44983,44986,44987,44989,44990, +44991,44993,44994,44995,44996,44997,44998,45002,45004,45007,45008,45009,45010, +45011,45013,45014,45015,45016,45017,45018,45019,45021,45022,45023,45024,45025, +U,U,U,U,U,U,45026,45027,45028,45029,45030,45031,45034,45035,45036,45037,45038, +45039,45042,45043,45045,45046,45047,45049,45050,45051,45052,45053,45054,45055, +45058,45059,U,U,U,U,U,U,45061,45062,45063,45064,45065,45066,45067,45069,45070, +45071,45073,45074,45075,45077,45078,45079,45080,45081,45082,45083,45086,45087, +45088,45089,45090,45091,45092,45093,45094,45095,45097,45098,45099,45100,45101, +45102,45103,45104,45105,45106,45107,45108,45109,45110,45111,45112,45113,45114, +45115,45116,45117,45118,45119,45120,45121,45122,45123,45126,45127,45129,45131, +45133,45135,45136,45137,45138,45142,45144,45146,45147,45148,45150,45151,45152, +45153,45154,45155,45156,45157,45158,45159,45160,45161,45162,45163,45164,45165, +45166,45167,45168,45169,45170,45171,45172,45173,45174,45175,45176,45177,45178, +45179,45182,45183,45185,45186,45187,45189,45190,45191,45192,45193,45194,45195, +45198,45200,45202,45203,45204,45205,45206,45207,45211,45213,45214,45219,45220, +45221,45222,45223,45226,45232,45234,45238,45239,45241,45242,45243,45245,45246, +45247,45248,45249,45250,45251,45254,45258,45259,45260,45261,45262,45263,45266, +U,U,U,U,U,U,45267,45269,45270,45271,45273,45274,45275,45276,45277,45278,45279, +45281,45282,45283,45284,45286,45287,45288,45289,45290,45291,45292,45293,45294, +45295,45296,U,U,U,U,U,U,45297,45298,45299,45300,45301,45302,45303,45304,45305, +45306,45307,45308,45309,45310,45311,45312,45313,45314,45315,45316,45317,45318, +45319,45322,45325,45326,45327,45329,45332,45333,45334,45335,45338,45342,45343, +45344,45345,45346,45350,45351,45353,45354,45355,45357,45358,45359,45360,45361, +45362,45363,45366,45370,45371,45372,45373,45374,45375,45378,45379,45381,45382, +45383,45385,45386,45387,45388,45389,45390,45391,45394,45395,45398,45399,45401, +45402,45403,45405,45406,45407,45409,45410,45411,45412,45413,45414,45415,45416, +45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,45427,45428,45429, +45430,45431,45434,45435,45437,45438,45439,45441,45443,45444,45445,45446,45447, +45450,45452,45454,45455,45456,45457,45461,45462,45463,45465,45466,45467,45469, +45470,45471,45472,45473,45474,45475,45476,45477,45478,45479,45481,45482,45483, +45484,45485,45486,45487,45488,45489,45490,45491,45492,45493,45494,45495,45496, +U,U,U,U,U,U,45497,45498,45499,45500,45501,45502,45503,45504,45505,45506,45507, +45508,45509,45510,45511,45512,45513,45514,45515,45517,45518,45519,45521,45522, +45523,45525,U,U,U,U,U,U,45526,45527,45528,45529,45530,45531,45534,45536,45537, +45538,45539,45540,45541,45542,45543,45546,45547,45549,45550,45551,45553,45554, +45555,45556,45557,45558,45559,45560,45562,45564,45566,45567,45568,45569,45570, +45571,45574,45575,45577,45578,45581,45582,45583,45584,45585,45586,45587,45590, +45592,45594,45595,45596,45597,45598,45599,45601,45602,45603,45604,45605,45606, +45607,45608,45609,45610,45611,45612,45613,45614,45615,45616,45617,45618,45619, +45621,45622,45623,45624,45625,45626,45627,45629,45630,45631,45632,45633,45634, +45635,45636,45637,45638,45639,45640,45641,45642,45643,45644,45645,45646,45647, +45648,45649,45650,45651,45652,45653,45654,45655,45657,45658,45659,45661,45662, +45663,45665,45666,45667,45668,45669,45670,45671,45674,45675,45676,45677,45678, +45679,45680,45681,45682,45683,45686,45687,45688,45689,45690,45691,45693,45694, +45695,45696,45697,45698,45699,45702,45703,45704,45706,45707,45708,45709,45710, +U,U,U,U,U,U,45711,45714,45715,45717,45718,45719,45723,45724,45725,45726,45727, +45730,45732,45735,45736,45737,45739,45741,45742,45743,45745,45746,45747,45749, +45750,45751,U,U,U,U,U,U,45752,45753,45754,45755,45756,45757,45758,45759,45760, +45761,45762,45763,45764,45765,45766,45767,45770,45771,45773,45774,45775,45777, +45779,45780,45781,45782,45783,45786,45788,45790,45791,45792,45793,45795,45799, +45801,45802,45808,45809,45810,45814,45820,45821,45822,45826,45827,45829,45830, +45831,45833,45834,45835,45836,45837,45838,45839,45842,45846,45847,45848,45849, +45850,45851,45853,45854,45855,45856,45857,45858,45859,45860,45861,45862,45863, +45864,45865,45866,45867,45868,45869,45870,45871,45872,45873,45874,45875,45876, +45877,45878,45879,45880,45881,45882,45883,45884,45885,45886,45887,45888,45889, +45890,45891,45892,45893,45894,45895,45896,45897,45898,45899,45900,45901,45902, +45903,45904,45905,45906,45907,45911,45913,45914,45917,45920,45921,45922,45923, +45926,45928,45930,45932,45933,45935,45938,45939,45941,45942,45943,45945,45946, +45947,45948,45949,45950,45951,45954,45958,45959,45960,45961,45962,45963,45965, +U,U,U,U,U,U,45966,45967,45969,45970,45971,45973,45974,45975,45976,45977,45978, +45979,45980,45981,45982,45983,45986,45987,45988,45989,45990,45991,45993,45994, +45995,45997,U,U,U,U,U,U,45998,45999,46000,46001,46002,46003,46004,46005,46006, +46007,46008,46009,46010,46011,46012,46013,46014,46015,46016,46017,46018,46019, +46022,46023,46025,46026,46029,46031,46033,46034,46035,46038,46040,46042,46044, +46046,46047,46049,46050,46051,46053,46054,46055,46057,46058,46059,46060,46061, +46062,46063,46064,46065,46066,46067,46068,46069,46070,46071,46072,46073,46074, +46075,46077,46078,46079,46080,46081,46082,46083,46084,46085,46086,46087,46088, +46089,46090,46091,46092,46093,46094,46095,46097,46098,46099,46100,46101,46102, +46103,46105,46106,46107,46109,46110,46111,46113,46114,46115,46116,46117,46118, +46119,46122,46124,46125,46126,46127,46128,46129,46130,46131,46133,46134,46135, +46136,46137,46138,46139,46140,46141,46142,46143,46144,46145,46146,46147,46148, +46149,46150,46151,46152,46153,46154,46155,46156,46157,46158,46159,46162,46163, +46165,46166,46167,46169,46170,46171,46172,46173,46174,46175,46178,46180,46182, +U,U,U,U,U,U,46183,46184,46185,46186,46187,46189,46190,46191,46192,46193,46194, +46195,46196,46197,46198,46199,46200,46201,46202,46203,46204,46205,46206,46207, +46209,46210,U,U,U,U,U,U,46211,46212,46213,46214,46215,46217,46218,46219,46220, +46221,46222,46223,46224,46225,46226,46227,46228,46229,46230,46231,46232,46233, +46234,46235,46236,46238,46239,46240,46241,46242,46243,46245,46246,46247,46249, +46250,46251,46253,46254,46255,46256,46257,46258,46259,46260,46262,46264,46266, +46267,46268,46269,46270,46271,46273,46274,46275,46277,46278,46279,46281,46282, +46283,46284,46285,46286,46287,46289,46290,46291,46292,46294,46295,46296,46297, +46298,46299,46302,46303,46305,46306,46309,46311,46312,46313,46314,46315,46318, +46320,46322,46323,46324,46325,46326,46327,46329,46330,46331,46332,46333,46334, +46335,46336,46337,46338,46339,46340,46341,46342,46343,46344,46345,46346,46347, +46348,46349,46350,46351,46352,46353,46354,46355,46358,46359,46361,46362,46365, +46366,46367,46368,46369,46370,46371,46374,46379,46380,46381,46382,46383,46386, +46387,46389,46390,46391,46393,46394,46395,46396,46397,46398,46399,46402,46406, +U,U,U,U,U,U,46407,46408,46409,46410,46414,46415,46417,46418,46419,46421,46422, +46423,46424,46425,46426,46427,46430,46434,46435,46436,46437,46438,46439,46440, +46441,46442,U,U,U,U,U,U,46443,46444,46445,46446,46447,46448,46449,46450,46451, +46452,46453,46454,46455,46456,46457,46458,46459,46460,46461,46462,46463,46464, +46465,46466,46467,46468,46469,46470,46471,46472,46473,46474,46475,46476,46477, +46478,46479,46480,46481,46482,46483,46484,46485,46486,46487,46488,46489,46490, +46491,46492,46493,46494,46495,46498,46499,46501,46502,46503,46505,46508,46509, +46510,46511,46514,46518,46519,46520,46521,46522,46526,46527,46529,46530,46531, +46533,46534,46535,46536,46537,46538,46539,46542,46546,46547,46548,46549,46550, +46551,46553,46554,46555,46556,46557,46558,46559,46560,46561,46562,46563,46564, +46565,46566,46567,46568,46569,46570,46571,46573,46574,46575,46576,46577,46578, +46579,46580,46581,46582,46583,46584,46585,46586,46587,46588,46589,46590,46591, +46592,46593,46594,46595,46596,46597,46598,46599,46600,46601,46602,46603,46604, +46605,46606,46607,46610,46611,46613,46614,46615,46617,46618,46619,46620,46621, +U,U,U,U,U,U,46622,46623,46624,46625,46626,46627,46628,46630,46631,46632,46633, +46634,46635,46637,46638,46639,46640,46641,46642,46643,46645,46646,46647,46648, +46649,46650,U,U,U,U,U,U,46651,46652,46653,46654,46655,46656,46657,46658,46659, +46660,46661,46662,46663,46665,46666,46667,46668,46669,46670,46671,46672,46673, +46674,46675,46676,46677,46678,46679,46680,46681,46682,46683,46684,46685,46686, +46687,46688,46689,46690,46691,46693,46694,46695,46697,46698,46699,46700,46701, +46702,46703,46704,46705,46706,46707,46708,46709,46710,46711,46712,46713,46714, +46715,46716,46717,46718,46719,46720,46721,46722,46723,46724,46725,46726,46727, +46728,46729,46730,46731,46732,46733,46734,46735,46736,46737,46738,46739,46740, +46741,46742,46743,46744,46745,46746,46747,46750,46751,46753,46754,46755,46757, +46758,46759,46760,46761,46762,46765,46766,46767,46768,46770,46771,46772,46773, +46774,46775,46776,46777,46778,46779,46780,46781,46782,46783,46784,46785,46786, +46787,46788,46789,46790,46791,46792,46793,46794,46795,46796,46797,46798,46799, +46800,46801,46802,46803,46805,46806,46807,46808,46809,46810,46811,46812,46813, +U,U,U,U,U,U,46814,46815,46816,46817,46818,46819,46820,46821,46822,46823,46824, +46825,46826,46827,46828,46829,46830,46831,46833,46834,46835,46837,46838,46839, +46841,46842,U,U,U,U,U,U,46843,46844,46845,46846,46847,46850,46851,46852,46854, +46855,46856,46857,46858,46859,46860,46861,46862,46863,46864,46865,46866,46867, +46868,46869,46870,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880, +46881,46882,46883,46884,46885,46886,46887,46890,46891,46893,46894,46897,46898, +46899,46900,46901,46902,46903,46906,46908,46909,46910,46911,46912,46913,46914, +46915,46917,46918,46919,46921,46922,46923,46925,46926,46927,46928,46929,46930, +46931,46934,46935,46936,46937,46938,46939,46940,46941,46942,46943,46945,46946, +46947,46949,46950,46951,46953,46954,46955,46956,46957,46958,46959,46962,46964, +46966,46967,46968,46969,46970,46971,46974,46975,46977,46978,46979,46981,46982, +46983,46984,46985,46986,46987,46990,46995,46996,46997,47002,47003,47005,47006, +47007,47009,47010,47011,47012,47013,47014,47015,47018,47022,47023,47024,47025, +47026,47027,47030,47031,47033,47034,47035,47036,47037,47038,47039,47040,47041, +U,U,U,U,U,U,47042,47043,47044,47045,47046,47048,47050,47051,47052,47053,47054, +47055,47056,47057,47058,47059,47060,47061,47062,47063,47064,47065,47066,47067, +47068,47069,U,U,U,U,U,U,47070,47071,47072,47073,47074,47075,47076,47077,47078, +47079,47080,47081,47082,47083,47086,47087,47089,47090,47091,47093,47094,47095, +47096,47097,47098,47099,47102,47106,47107,47108,47109,47110,47114,47115,47117, +47118,47119,47121,47122,47123,47124,47125,47126,47127,47130,47132,47134,47135, +47136,47137,47138,47139,47142,47143,47145,47146,47147,47149,47150,47151,47152, +47153,47154,47155,47158,47162,47163,47164,47165,47166,47167,47169,47170,47171, +47173,47174,47175,47176,47177,47178,47179,47180,47181,47182,47183,47184,47186, +47188,47189,47190,47191,47192,47193,47194,47195,47198,47199,47201,47202,47203, +47205,47206,47207,47208,47209,47210,47211,47214,47216,47218,47219,47220,47221, +47222,47223,47225,47226,47227,47229,47230,47231,47232,47233,47234,47235,47236, +47237,47238,47239,47240,47241,47242,47243,47244,47246,47247,47248,47249,47250, +47251,47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263, +U,U,U,U,U,U,47264,47265,47266,47267,47268,47269,47270,47271,47273,47274,47275, +47276,47277,47278,47279,47281,47282,47283,47285,47286,47287,47289,47290,47291, +47292,47293,U,U,U,U,U,U,47294,47295,47298,47300,47302,47303,47304,47305,47306, +47307,47309,47310,47311,47313,47314,47315,47317,47318,47319,47320,47321,47322, +47323,47324,47326,47328,47330,47331,47332,47333,47334,47335,47338,47339,47341, +47342,47343,47345,47346,47347,47348,47349,47350,47351,47354,47356,47358,47359, +47360,47361,47362,47363,47365,47366,47367,47368,47369,47370,47371,47372,47373, +47374,47375,47376,47377,47378,47379,47380,47381,47382,47383,47385,47386,47387, +47388,47389,47390,47391,47393,47394,47395,47396,47397,47398,47399,47400,47401, +47402,47403,47404,47405,47406,47407,47408,47409,47410,47411,47412,47413,47414, +47415,47416,47417,47418,47419,47422,47423,47425,47426,47427,47429,47430,47431, +47432,47433,47434,47435,47437,47438,47440,47442,47443,47444,47445,47446,47447, +47450,47451,47453,47454,47455,47457,47458,47459,47460,47461,47462,47463,47466, +47468,47470,47471,47472,47473,47474,47475,47478,47479,47481,47482,47483,47485, +U,U,U,U,U,U,47486,47487,47488,47489,47490,47491,47494,47496,47499,47500,47503, +47504,47505,47506,47507,47508,47509,47510,47511,47512,47513,47514,47515,47516, +47517,47518,U,U,U,U,U,U,47519,47520,47521,47522,47523,47524,47525,47526,47527, +47528,47529,47530,47531,47534,47535,47537,47538,47539,47541,47542,47543,47544, +47545,47546,47547,47550,47552,47554,47555,47556,47557,47558,47559,47562,47563, +47565,47571,47572,47573,47574,47575,47578,47580,47583,47584,47586,47590,47591, +47593,47594,47595,47597,47598,47599,47600,47601,47602,47603,47606,47611,47612, +47613,47614,47615,47618,47619,47620,47621,47622,47623,47625,47626,47627,47628, +47629,47630,47631,47632,47633,47634,47635,47636,47638,47639,47640,47641,47642, +47643,47644,47645,47646,47647,47648,47649,47650,47651,47652,47653,47654,47655, +47656,47657,47658,47659,47660,47661,47662,47663,47664,47665,47666,47667,47668, +47669,47670,47671,47674,47675,47677,47678,47679,47681,47683,47684,47685,47686, +47687,47690,47692,47695,47696,47697,47698,47702,47703,47705,47706,47707,47709, +47710,47711,47712,47713,47714,47715,47718,47722,47723,47724,47725,47726,47727, +U,U,U,U,U,U,47730,47731,47733,47734,47735,47737,47738,47739,47740,47741,47742, +47743,47744,47745,47746,47750,47752,47753,47754,47755,47757,47758,47759,47760, +47761,47762,U,U,U,U,U,U,47763,47764,47765,47766,47767,47768,47769,47770,47771, +47772,47773,47774,47775,47776,47777,47778,47779,47780,47781,47782,47783,47786, +47789,47790,47791,47793,47795,47796,47797,47798,47799,47802,47804,47806,47807, +47808,47809,47810,47811,47813,47814,47815,47817,47818,47819,47820,47821,47822, +47823,47824,47825,47826,47827,47828,47829,47830,47831,47834,47835,47836,47837, +47838,47839,47840,47841,47842,47843,47844,47845,47846,47847,47848,47849,47850, +47851,47852,47853,47854,47855,47856,47857,47858,47859,47860,47861,47862,47863, +47864,47865,47866,47867,47869,47870,47871,47873,47874,47875,47877,47878,47879, +47880,47881,47882,47883,47884,47886,47888,47890,47891,47892,47893,47894,47895, +47897,47898,47899,47901,47902,47903,47905,47906,47907,47908,47909,47910,47911, +47912,47914,47916,47917,47918,47919,47920,47921,47922,47923,47927,47929,47930, +47935,47936,47937,47938,47939,47942,47944,47946,47947,47948,47950,47953,47954, +U,U,U,U,U,U,47955,47957,47958,47959,47961,47962,47963,47964,47965,47966,47967, +47968,47970,47972,47973,47974,47975,47976,47977,47978,47979,47981,47982,47983, +47984,47985,U,U,U,U,U,U,47986,47987,47988,47989,47990,47991,47992,47993,47994, +47995,47996,47997,47998,47999,48000,48001,48002,48003,48004,48005,48006,48007, +48009,48010,48011,48013,48014,48015,48017,48018,48019,48020,48021,48022,48023, +48024,48025,48026,48027,48028,48029,48030,48031,48032,48033,48034,48035,48037, +48038,48039,48041,48042,48043,48045,48046,48047,48048,48049,48050,48051,48053, +48054,48056,48057,48058,48059,48060,48061,48062,48063,48065,48066,48067,48069, +48070,48071,48073,48074,48075,48076,48077,48078,48079,48081,48082,48084,48085, +48086,48087,48088,48089,48090,48091,48092,48093,48094,48095,48096,48097,48098, +48099,48100,48101,48102,48103,48104,48105,48106,48107,48108,48109,48110,48111, +48112,48113,48114,48115,48116,48117,48118,48119,48122,48123,48125,48126,48129, +48131,48132,48133,48134,48135,48138,48142,48144,48146,48147,48153,48154,48160, +48161,48162,48163,48166,48168,48170,48171,48172,48174,48175,48178,48179,48181, +U,U,U,U,U,U,48182,48183,48185,48186,48187,48188,48189,48190,48191,48194,48198, +48199,48200,48202,48203,48206,48207,48209,48210,48211,48212,48213,48214,48215, +48216,48217,U,U,U,U,U,U,48218,48219,48220,48222,48223,48224,48225,48226,48227, +48228,48229,48230,48231,48232,48233,48234,48235,48236,48237,48238,48239,48240, +48241,48242,48243,48244,48245,48246,48247,48248,48249,48250,48251,48252,48253, +48254,48255,48256,48257,48258,48259,48262,48263,48265,48266,48269,48271,48272, +48273,48274,48275,48278,48280,48283,48284,48285,48286,48287,48290,48291,48293, +48294,48297,48298,48299,48300,48301,48302,48303,48306,48310,48311,48312,48313, +48314,48315,48318,48319,48321,48322,48323,48325,48326,48327,48328,48329,48330, +48331,48332,48334,48338,48339,48340,48342,48343,48345,48346,48347,48349,48350, +48351,48352,48353,48354,48355,48356,48357,48358,48359,48360,48361,48362,48363, +48364,48365,48366,48367,48368,48369,48370,48371,48375,48377,48378,48379,48381, +48382,48383,48384,48385,48386,48387,48390,48392,48394,48395,48396,48397,48398, +48399,48401,48402,48403,48405,48406,48407,48408,48409,48410,48411,48412,48413, +U,U,U,U,U,U,48414,48415,48416,48417,48418,48419,48421,48422,48423,48424,48425, +48426,48427,48429,48430,48431,48432,48433,48434,48435,48436,48437,48438,48439, +48440,48441,U,U,U,U,U,U,48442,48443,48444,48445,48446,48447,48449,48450,48451, +48452,48453,48454,48455,48458,48459,48461,48462,48463,48465,48466,48467,48468, +48469,48470,48471,48474,48475,48476,48477,48478,48479,48480,48481,48482,48483, +48485,48486,48487,48489,48490,48491,48492,48493,48494,48495,48496,48497,48498, +48499,48500,48501,48502,48503,48504,48505,48506,48507,48508,48509,48510,48511, +48514,48515,48517,48518,48523,48524,48525,48526,48527,48530,48532,48534,48535, +48536,48539,48541,48542,48543,48544,48545,48546,48547,48549,48550,48551,48552, +48553,48554,48555,48556,48557,48558,48559,48561,48562,48563,48564,48565,48566, +48567,48569,48570,48571,48572,48573,48574,48575,48576,48577,48578,48579,48580, +48581,48582,48583,48584,48585,48586,48587,48588,48589,48590,48591,48592,48593, +48594,48595,48598,48599,48601,48602,48603,48605,48606,48607,48608,48609,48610, +48611,48612,48613,48614,48615,48616,48618,48619,48620,48621,48622,48623,48625, +U,U,U,U,U,U,48626,48627,48629,48630,48631,48633,48634,48635,48636,48637,48638, +48639,48641,48642,48644,48646,48647,48648,48649,48650,48651,48654,48655,48657, +48658,48659,U,U,U,U,U,U,48661,48662,48663,48664,48665,48666,48667,48670,48672, +48673,48674,48675,48676,48677,48678,48679,48680,48681,48682,48683,48684,48685, +48686,48687,48688,48689,48690,48691,48692,48693,48694,48695,48696,48697,48698, +48699,48700,48701,48702,48703,48704,48705,48706,48707,48710,48711,48713,48714, +48715,48717,48719,48720,48721,48722,48723,48726,48728,48732,48733,48734,48735, +48738,48739,48741,48742,48743,48745,48747,48748,48749,48750,48751,48754,48758, +48759,48760,48761,48762,48766,48767,48769,48770,48771,48773,48774,48775,48776, +48777,48778,48779,48782,48786,48787,48788,48789,48790,48791,48794,48795,48796, +48797,48798,48799,48800,48801,48802,48803,48804,48805,48806,48807,48809,48810, +48811,48812,48813,48814,48815,48816,48817,48818,48819,48820,48821,48822,48823, +48824,48825,48826,48827,48828,48829,48830,48831,48832,48833,48834,48835,48836, +48837,48838,48839,48840,48841,48842,48843,48844,48845,48846,48847,48850,48851, +U,U,U,U,U,U,48853,48854,48857,48858,48859,48860,48861,48862,48863,48865,48866, +48870,48871,48872,48873,48874,48875,48877,48878,48879,48880,48881,48882,48883, +48884,48885,U,U,U,U,U,U,48886,48887,48888,48889,48890,48891,48892,48893,48894, +48895,48896,48898,48899,48900,48901,48902,48903,48906,48907,48908,48909,48910, +48911,48912,48913,48914,48915,48916,48917,48918,48919,48922,48926,48927,48928, +48929,48930,48931,48932,48933,48934,48935,48936,48937,48938,48939,48940,48941, +48942,48943,48944,48945,48946,48947,48948,48949,48950,48951,48952,48953,48954, +48955,48956,48957,48958,48959,48962,48963,48965,48966,48967,48969,48970,48971, +48972,48973,48974,48975,48978,48979,48980,48982,48983,48984,48985,48986,48987, +48988,48989,48990,48991,48992,48993,48994,48995,48996,48997,48998,48999,49000, +49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,49012,49013, +49014,49015,49016,49017,49018,49019,49020,49021,49022,49023,49024,49025,49026, +49027,49028,49029,49030,49031,49032,49033,49034,49035,49036,49037,49038,49039, +49040,49041,49042,49043,49045,49046,49047,49048,49049,49050,49051,49052,49053, +U,U,U,U,U,U,49054,49055,49056,49057,49058,49059,49060,49061,49062,49063,49064, +49065,49066,49067,49068,49069,49070,49071,49073,49074,49075,49076,49077,49078, +49079,49080,U,U,U,U,U,U,49081,49082,49083,49084,49085,49086,49087,49088,49089, +49090,49091,49092,49094,49095,49096,49097,49098,49099,49102,49103,49105,49106, +49107,49109,49110,49111,49112,49113,49114,49115,49117,49118,49120,49122,49123, +49124,49125,49126,49127,49128,49129,49130,49131,49132,49133,49134,49135,49136, +49137,49138,49139,49140,49141,49142,49143,49144,49145,49146,49147,49148,49149, +49150,49151,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49162, +49163,49164,49165,49166,49167,49168,49169,49170,49171,49172,49173,49174,49175, +49176,49177,49178,49179,49180,49181,49182,49183,49184,49185,49186,49187,49188, +49189,49190,49191,49192,49193,49194,49195,49196,49197,49198,49199,49200,49201, +49202,49203,49204,49205,49206,49207,49208,49209,49210,49211,49213,49214,49215, +49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,49226,49227,49228, +49229,49230,49231,49232,49234,49235,49236,49237,49238,49239,49241,49242,49243, +U,U,U,U,U,U,49245,49246,49247,49249,49250,49251,49252,49253,49254,49255,49258, +49259,49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271, +49272,49273,U,U,U,U,U,U,49274,49275,49276,49277,49278,49279,49280,49281,49282, +49283,49284,49285,49286,49287,49288,49289,49290,49291,49292,49293,49294,49295, +49298,49299,49301,49302,49303,49305,49306,49307,49308,49309,49310,49311,49314, +49316,49318,49319,49320,49321,49322,49323,49326,49329,49330,49335,49336,49337, +49338,49339,49342,49346,49347,49348,49350,49351,49354,49355,49357,49358,49359, +49361,49362,49363,49364,49365,49366,49367,49370,49374,49375,49376,49377,49378, +49379,49382,49383,49385,49386,49387,49389,49390,49391,49392,49393,49394,49395, +49398,49400,49402,49403,49404,49405,49406,49407,49409,49410,49411,49413,49414, +49415,49417,49418,49419,49420,49421,49422,49423,49425,49426,49427,49428,49430, +49431,49432,49433,49434,49435,49441,49442,49445,49448,49449,49450,49451,49454, +49458,49459,49460,49461,49463,49466,49467,49469,49470,49471,49473,49474,49475, +49476,49477,49478,49479,49482,49486,49487,49488,49489,49490,49491,49494,49495, +U,U,U,U,U,U,49497,49498,49499,49501,49502,49503,49504,49505,49506,49507,49510, +49514,49515,49516,49517,49518,49519,49521,49522,49523,49525,49526,49527,49529, +49530,49531,U,U,U,U,U,U,49532,49533,49534,49535,49536,49537,49538,49539,49540, +49542,49543,49544,49545,49546,49547,49551,49553,49554,49555,49557,49559,49560, +49561,49562,49563,49566,49568,49570,49571,49572,49574,49575,49578,49579,49581, +49582,49583,49585,49586,49587,49588,49589,49590,49591,49592,49593,49594,49595, +49596,49598,49599,49600,49601,49602,49603,49605,49606,49607,49609,49610,49611, +49613,49614,49615,49616,49617,49618,49619,49621,49622,49625,49626,49627,49628, +49629,49630,49631,49633,49634,49635,49637,49638,49639,49641,49642,49643,49644, +49645,49646,49647,49650,49652,49653,49654,49655,49656,49657,49658,49659,49662, +49663,49665,49666,49667,49669,49670,49671,49672,49673,49674,49675,49678,49680, +49682,49683,49684,49685,49686,49687,49690,49691,49693,49694,49697,49698,49699, +49700,49701,49702,49703,49706,49708,49710,49712,49715,49717,49718,49719,49720, +49721,49722,49723,49724,49725,49726,49727,49728,49729,49730,49731,49732,49733, +U,U,U,U,U,U,49734,49735,49737,49738,49739,49740,49741,49742,49743,49746,49747, +49749,49750,49751,49753,49754,49755,49756,49757,49758,49759,49761,49762,49763, +49764,49766,U,U,U,U,U,U,49767,49768,49769,49770,49771,49774,49775,49777,49778, +49779,49781,49782,49783,49784,49785,49786,49787,49790,49792,49794,49795,49796, +49797,49798,49799,49802,49803,49804,49805,49806,49807,49809,49810,49811,49812, +49813,49814,49815,49817,49818,49820,49822,49823,49824,49825,49826,49827,49830, +49831,49833,49834,49835,49838,49839,49840,49841,49842,49843,49846,49848,49850, +49851,49852,49853,49854,49855,49856,49857,49858,49859,49860,49861,49862,49863, +49864,49865,49866,49867,49868,49869,49870,49871,49872,49873,49874,49875,49876, +49877,49878,49879,49880,49881,49882,49883,49886,49887,49889,49890,49893,49894, +49895,49896,49897,49898,49902,49904,49906,49907,49908,49909,49911,49914,49917, +49918,49919,49921,49922,49923,49924,49925,49926,49927,49930,49931,49934,49935, +49936,49937,49938,49942,49943,49945,49946,49947,49949,49950,49951,49952,49953, +49954,49955,49958,49959,49962,49963,49964,49965,49966,49967,49968,49969,49970, +U,U,U,U,U,U,49971,49972,49973,49974,49975,49976,49977,49978,49979,49980,49981, +49982,49983,49984,49985,49986,49987,49988,49990,49991,49992,49993,49994,49995, +49996,49997,U,U,U,U,U,U,49998,49999,50000,50001,50002,50003,50004,50005,50006, +50007,50008,50009,50010,50011,50012,50013,50014,50015,50016,50017,50018,50019, +50020,50021,50022,50023,50026,50027,50029,50030,50031,50033,50035,50036,50037, +50038,50039,50042,50043,50046,50047,50048,50049,50050,50051,50053,50054,50055, +50057,50058,50059,50061,50062,50063,50064,50065,50066,50067,50068,50069,50070, +50071,50072,50073,50074,50075,50076,50077,50078,50079,50080,50081,50082,50083, +50084,50085,50086,50087,50088,50089,50090,50091,50092,50093,50094,50095,50096, +50097,50098,50099,50100,50101,50102,50103,50104,50105,50106,50107,50108,50109, +50110,50111,50113,50114,50115,50116,50117,50118,50119,50120,50121,50122,50123, +50124,50125,50126,50127,50128,50129,50130,50131,50132,50133,50134,50135,50138, +50139,50141,50142,50145,50147,50148,50149,50150,50151,50154,50155,50156,50158, +50159,50160,50161,50162,50163,50166,50167,50169,50170,50171,50172,50173,50174, +U,U,U,U,U,U,50175,50176,50177,50178,50179,50180,50181,50182,50183,50185,50186, +50187,50188,50189,50190,50191,50193,50194,50195,50196,50197,50198,50199,50200, +50201,50202,U,U,U,U,U,U,50203,50204,50205,50206,50207,50208,50209,50210,50211, +50213,50214,50215,50216,50217,50218,50219,50221,50222,50223,50225,50226,50227, +50229,50230,50231,50232,50233,50234,50235,50238,50239,50240,50241,50242,50243, +50244,50245,50246,50247,50249,50250,50251,50252,50253,50254,50255,50256,50257, +50258,50259,50260,50261,50262,50263,50264,50265,50266,50267,50268,50269,50270, +50271,50272,50273,50274,50275,50278,50279,50281,50282,50283,50285,50286,50287, +50288,50289,50290,50291,50294,50295,50296,50298,50299,50300,50301,50302,50303, +50305,50306,50307,50308,50309,50310,50311,50312,50313,50314,50315,50316,50317, +50318,50319,50320,50321,50322,50323,50325,50326,50327,50328,50329,50330,50331, +50333,50334,50335,50336,50337,50338,50339,50340,50341,50342,50343,50344,50345, +50346,50347,50348,50349,50350,50351,50352,50353,50354,50355,50356,50357,50358, +50359,50361,50362,50363,50365,50366,50367,50368,50369,50370,50371,50372,50373, +U,U,U,U,U,U,50374,50375,50376,50377,50378,50379,50380,50381,50382,50383,50384, +50385,50386,50387,50388,50389,50390,50391,50392,50393,50394,50395,50396,50397, +50398,50399,U,U,U,U,U,U,50400,50401,50402,50403,50404,50405,50406,50407,50408, +50410,50411,50412,50413,50414,50415,50418,50419,50421,50422,50423,50425,50427, +50428,50429,50430,50434,50435,50436,50437,50438,50439,50440,50441,50442,50443, +50445,50446,50447,50449,50450,50451,50453,50454,50455,50456,50457,50458,50459, +50461,50462,50463,50464,50465,50466,50467,50468,50469,50470,50471,50474,50475, +50477,50478,50479,50481,50482,50483,50484,50485,50486,50487,50490,50492,50494, +50495,50496,50497,50498,50499,50502,50503,50507,50511,50512,50513,50514,50518, +50522,50523,50524,50527,50530,50531,50533,50534,50535,50537,50538,50539,50540, +50541,50542,50543,50546,50550,50551,50552,50553,50554,50555,50558,50559,50561, +50562,50563,50565,50566,50568,50569,50570,50571,50574,50576,50578,50579,50580, +50582,50585,50586,50587,50589,50590,50591,50593,50594,50595,50596,50597,50598, +50599,50600,50602,50603,50604,50605,50606,50607,50608,50609,50610,50611,50614, +U,U,U,U,U,U,50615,50618,50623,50624,50625,50626,50627,50635,50637,50639,50642, +50643,50645,50646,50647,50649,50650,50651,50652,50653,50654,50655,50658,50660, +50662,50663,U,U,U,U,U,U,50664,50665,50666,50667,50671,50673,50674,50675,50677, +50680,50681,50682,50683,50690,50691,50692,50697,50698,50699,50701,50702,50703, +50705,50706,50707,50708,50709,50710,50711,50714,50717,50718,50719,50720,50721, +50722,50723,50726,50727,50729,50730,50731,50735,50737,50738,50742,50744,50746, +50748,50749,50750,50751,50754,50755,50757,50758,50759,50761,50762,50763,50764, +50765,50766,50767,50770,50774,50775,50776,50777,50778,50779,50782,50783,50785, +50786,50787,50788,50789,50790,50791,50792,50793,50794,50795,50797,50798,50800, +50802,50803,50804,50805,50806,50807,50810,50811,50813,50814,50815,50817,50818, +50819,50820,50821,50822,50823,50826,50828,50830,50831,50832,50833,50834,50835, +50838,50839,50841,50842,50843,50845,50846,50847,50848,50849,50850,50851,50854, +50856,50858,50859,50860,50861,50862,50863,50866,50867,50869,50870,50871,50875, +50876,50877,50878,50879,50882,50884,50886,50887,50888,50889,50890,50891,50894, +U,U,U,U,U,U,50895,50897,50898,50899,50901,50902,50903,50904,50905,50906,50907, +50910,50911,50914,50915,50916,50917,50918,50919,50922,50923,50925,50926,50927, +50929,50930,U,U,U,U,U,U,50931,50932,50933,50934,50935,50938,50939,50940,50942, +50943,50944,50945,50946,50947,50950,50951,50953,50954,50955,50957,50958,50959, +50960,50961,50962,50963,50966,50968,50970,50971,50972,50973,50974,50975,50978, +50979,50981,50982,50983,50985,50986,50987,50988,50989,50990,50991,50994,50996, +50998,51000,51001,51002,51003,51006,51007,51009,51010,51011,51013,51014,51015, +51016,51017,51019,51022,51024,51033,51034,51035,51037,51038,51039,51041,51042, +51043,51044,51045,51046,51047,51049,51050,51052,51053,51054,51055,51056,51057, +51058,51059,51062,51063,51065,51066,51067,51071,51072,51073,51074,51078,51083, +51084,51085,51087,51090,51091,51093,51097,51099,51100,51101,51102,51103,51106, +51111,51112,51113,51114,51115,51118,51119,51121,51122,51123,51125,51126,51127, +51128,51129,51130,51131,51134,51138,51139,51140,51141,51142,51143,51146,51147, +51149,51151,51153,51154,51155,51156,51157,51158,51159,51161,51162,51163,51164, +U,U,U,U,U,U,51166,51167,51168,51169,51170,51171,51173,51174,51175,51177,51178, +51179,51181,51182,51183,51184,51185,51186,51187,51188,51189,51190,51191,51192, +51193,51194,U,U,U,U,U,U,51195,51196,51197,51198,51199,51202,51203,51205,51206, +51207,51209,51211,51212,51213,51214,51215,51218,51220,51223,51224,51225,51226, +51227,51230,51231,51233,51234,51235,51237,51238,51239,51240,51241,51242,51243, +51246,51248,51250,51251,51252,51253,51254,51255,51257,51258,51259,51261,51262, +51263,51265,51266,51267,51268,51269,51270,51271,51274,51275,51278,51279,51280, +51281,51282,51283,51285,51286,51287,51288,51289,51290,51291,51292,51293,51294, +51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305,51306,51307, +51308,51309,51310,51311,51314,51315,51317,51318,51319,51321,51323,51324,51325, +51326,51327,51330,51332,51336,51337,51338,51342,51343,51344,51345,51346,51347, +51349,51350,51351,51352,51353,51354,51355,51356,51358,51360,51362,51363,51364, +51365,51366,51367,51369,51370,51371,51372,51373,51374,51375,51376,51377,51378, +51379,51380,51381,51382,51383,51384,51385,51386,51387,51390,51391,51392,51393, +U,U,U,U,U,U,51394,51395,51397,51398,51399,51401,51402,51403,51405,51406,51407, +51408,51409,51410,51411,51414,51416,51418,51419,51420,51421,51422,51423,51426, +51427,51429,U,U,U,U,U,U,51430,51431,51432,51433,51434,51435,51436,51437,51438, +51439,51440,51441,51442,51443,51444,51446,51447,51448,51449,51450,51451,51454, +51455,51457,51458,51459,51463,51464,51465,51466,51467,51470,51472,51474,51475, +51476,51477,51478,51479,51481,51482,51483,51484,51485,51486,51487,51488,51489, +51490,51491,51492,51493,51494,51495,51496,51497,51498,51499,U,U,U,U,U,U,51501, +51502,51503,51504,51505,51506,51507,51509,51510,51511,51512,51513,51514,51515, +51516,51517,51518,51519,51520,51521,51522,51523,51524,51525,51526,51527,U,U,U, +U,U,U,51528,51529,51530,51531,51532,51533,51534,51535,51538,51539,51541,51542, +51543,51545,51546,51547,51548,51549,51550,51551,51554,51556,51557,51558,51559, +51560,51561,51562,51563,51565,51566,51567,51569,51570,51571,51573,51574,51575, +51576,51577,51578,51579,51581,51582,51583,51584,51585,51586,51587,51588,51589, +51590,51591,51594,51595,51597,51598,51599,U,U,U,U,U,U,51601,51602,51603,51604, +51605,51606,51607,51610,51612,51614,51615,51616,51617,51618,51619,51620,51621, +51622,51623,51624,51625,51626,51627,51628,51629,51630,U,U,U,U,U,U,51631,51632, +51633,51634,51635,51636,51637,51638,51639,51640,51641,51642,51643,51644,51645, +51646,51647,51650,51651,51653,51654,51657,51659,51660,51661,51662,51663,51666, +51668,51671,51672,51675,51678,51679,51681,51683,51685,51686,51688,51689,51690, +51691,51694,51698,51699,51700,51701,51702,51703,51706,51707,51709,51710,51711, +51713,51714,51715,51716,U,U,U,U,U,U,51717,51718,51719,51722,51726,51727,51728, +51729,51730,51731,51733,51734,51735,51737,51738,51739,51740,51741,51742,51743, +51744,51745,51746,51747,51748,51749,U,U,U,U,U,U,51750,51751,51752,51754,51755, +51756,51757,51758,51759,51760,51761,51762,51763,51764,51765,51766,51767,51768, +51769,51770,51771,51772,51773,51774,51775,51776,51777,51778,51779,51780,51781, +51782,51783,51784,51785,51786,51787,51790,51791,51793,51794,51795,51797,51798, +51799,51800,51801,51802,51803,51806,51810,51811,51812,51813,51814,51815,51817, +51818,U,U,U,U,U,U,51819,51820,51821,51822,51823,51824,51825,51826,51827,51828, +51829,51830,51831,51832,51833,51834,51835,51836,51838,51839,51840,51841,51842, +51843,51845,51846,U,U,U,U,U,U,51847,51848,51849,51850,51851,51852,51853,51854, +51855,51856,51857,51858,51859,51860,51861,51862,51863,51865,51866,51867,51868, +51869,51870,51871,51872,51873,51874,51875,51876,51877,51878,51879,51880,51881, +51882,51883,51884,51885,51886,51887,51888,51889,51890,51891,51892,51893,51894, +51895,51896,51897,51898,51899,51902,51903,51905,51906,51907,51909,U,U,U,U,U,U, +51910,51911,51912,51913,51914,51915,51918,51920,51922,51924,51925,51926,51927, +51930,51931,51932,51933,51934,51935,51937,51938,51939,51940,51941,51942,51943, +U,U,U,U,U,U,51944,51945,51946,51947,51949,51950,51951,51952,51953,51954,51955, +51957,51958,51959,51960,51961,51962,51963,51964,51965,51966,51967,51968,51969, +51970,51971,51972,51973,51974,51975,51977,51978,51979,51980,51981,51982,51983, +51985,51986,51987,51989,51990,51991,51993,51994,51995,51996,51997,51998,51999, +52002,52003,52004,52005,52006,52007,52008,52009,U,U,U,U,U,U,52010,52011,52012, +52013,52014,52015,52016,52017,52018,52019,52020,52021,52022,52023,52024,52025, +52026,52027,52028,52029,52030,52031,52032,52034,52035,52036,U,U,U,U,U,U,52037, +52038,52039,52042,52043,52045,52046,52047,52049,52050,52051,52052,52053,52054, +52055,52058,52059,52060,52062,52063,52064,52065,52066,52067,52069,52070,52071, +52072,52073,52074,52075,52076,52077,52078,52079,52080,52081,52082,52083,52084, +52085,52086,52087,52090,52091,52092,52093,52094,52095,52096,52097,52098,52099, +52100,52101,52102,52103,52104,U,U,U,U,U,U,52105,52106,52107,52108,52109,52110, +52111,52112,52113,52114,52115,52116,52117,52118,52119,52120,52121,52122,52123, +52125,52126,52127,52128,52129,52130,52131,U,U,U,U,U,U,52132,52133,52134,52135, +52136,52137,52138,52139,52140,52141,52142,52143,52144,52145,52146,52147,52148, +52149,52150,52151,52153,52154,52155,52156,52157,52158,52159,52160,52161,52162, +52163,52164,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174,52175, +52176,52177,52178,52179,52181,52182,52183,52184,52185,52186,52187,52188,52189, +52190,52191,U,U,U,U,U,U,52192,52193,52194,52195,52197,52198,52200,52202,52203, +52204,52205,52206,52207,52208,52209,52210,52211,52212,52213,52214,52215,52216, +52217,52218,52219,52220,U,U,U,U,U,U,52221,52222,52223,52224,52225,52226,52227, +52228,52229,52230,52231,52232,52233,52234,52235,52238,52239,52241,52242,52243, +52245,52246,52247,52248,52249,52250,52251,52254,52255,52256,52259,52260,52261, +52262,52266,52267,52269,52271,52273,52274,52275,52276,52277,52278,52279,52282, +52287,52288,52289,52290,52291,52294,52295,52297,52298,52299,52301,52302,U,U,U, +U,U,U,52303,52304,52305,52306,52307,52310,52314,52315,52316,52317,52318,52319, +52321,52322,52323,52325,52327,52329,52330,52331,52332,52333,52334,52335,52337, +52338,U,U,U,U,U,U,52339,52340,52342,52343,52344,52345,52346,52347,52348,52349, +52350,52351,52352,52353,52354,52355,52356,52357,52358,52359,52360,52361,52362, +52363,52364,52365,52366,52367,52368,52369,52370,52371,52372,52373,52374,52375, +52378,52379,52381,52382,52383,52385,52386,52387,52388,52389,52390,52391,52394, +52398,52399,52400,52401,52402,52403,52406,52407,52409,U,U,U,U,U,U,52410,52411, +52413,52414,52415,52416,52417,52418,52419,52422,52424,52426,52427,52428,52429, +52430,52431,52433,52434,52435,52437,52438,52439,52440,52441,52442,U,U,U,U,U,U, +52443,52444,52445,52446,52447,52448,52449,52450,52451,52453,52454,52455,52456, +52457,52458,52459,52461,52462,52463,52465,52466,52467,52468,52469,52470,52471, +52472,52473,52474,52475,52476,52477,52478,52479,52480,52482,52483,52484,52485, +52486,52487,52490,52491,52493,52494,52495,52497,52498,52499,52500,52501,52502, +52503,52506,52508,52510,52511,52512,U,U,U,U,U,U,52513,52514,52515,52517,52518, +52519,52521,52522,52523,52525,52526,52527,52528,52529,52530,52531,52532,52533, +52534,52535,52536,52538,52539,52540,52541,52542,U,U,U,U,U,U,52543,52544,52545, +52546,52547,52548,52549,52550,52551,52552,52553,52554,52555,52556,52557,52558, +52559,52560,52561,52562,52563,52564,52565,52566,52567,52568,52569,52570,52571, +52573,52574,52575,52577,52578,52579,52581,52582,52583,52584,52585,52586,52587, +52590,52592,52594,52595,52596,52597,52598,52599,52601,52602,52603,52604,52605, +52606,52607,52608,U,U,U,U,U,U,52609,52610,52611,52612,52613,52614,52615,52617, +52618,52619,52620,52621,52622,52623,52624,52625,52626,52627,52630,52631,52633, +52634,52635,52637,52638,52639,U,U,U,U,U,U,52640,52641,52642,52643,52646,52648, +52650,52651,52652,52653,52654,52655,52657,52658,52659,52660,52661,52662,52663, +52664,52665,52666,52667,52668,52669,52670,52671,52672,52673,52674,52675,52677, +52678,52679,52680,52681,52682,52683,52685,52686,52687,52689,52690,52691,52692, +52693,52694,52695,52696,52697,52698,52699,52700,52701,52702,52703,52704,52705, +U,U,U,U,U,U,52706,52707,52708,52709,52710,52711,52713,52714,52715,52717,52718, +52719,52721,52722,52723,52724,52725,52726,52727,52730,52732,52734,52735,52736, +52737,52738,U,U,U,U,U,U,52739,52741,52742,52743,52745,52746,52747,52749,52750, +52751,52752,52753,52754,52755,52757,52758,52759,52760,52762,52763,52764,52765, +52766,52767,52770,52771,52773,52774,52775,52777,52778,52779,52780,52781,52782, +52783,52786,52788,52790,52791,52792,52793,52794,52795,52796,52797,52798,52799, +52800,52801,52802,52803,52804,52805,52806,52807,52808,52809,U,U,U,U,U,U,52810, +52811,52812,52813,52814,52815,52816,52817,52818,52819,52820,52821,52822,52823, +52826,52827,52829,52830,52834,52835,52836,52837,52838,52839,52842,52844,U,U,U, +U,U,U,52846,52847,52848,52849,52850,52851,52854,52855,52857,52858,52859,52861, +52862,52863,52864,52865,52866,52867,52870,52872,52874,52875,52876,52877,52878, +52879,52882,52883,52885,52886,52887,52889,52890,52891,52892,52893,52894,52895, +52898,52902,52903,52904,52905,52906,52907,52910,52911,52912,52913,52914,52915, +52916,52917,52918,52919,52920,52921,52922,U,U,U,U,U,U,52923,52924,52925,52926, +52927,52928,52930,52931,52932,52933,52934,52935,52936,52937,52938,52939,52940, +52941,52942,52943,52944,52945,52946,52947,52948,52949,U,U,U,U,U,U,52950,52951, +52952,52953,52954,52955,52956,52957,52958,52959,52960,52961,52962,52963,52966, +52967,52969,52970,52973,52974,52975,52976,52977,52978,52979,52982,52986,52987, +52988,52989,52990,52991,52994,52995,52997,52998,52999,53001,53002,53003,53004, +53005,53006,53007,53010,53012,53014,53015,53016,53017,53018,53019,53021,53022, +53023,53025,53026,53027,U,U,U,U,U,U,53029,53030,53031,53032,53033,53034,53035, +53038,53042,53043,53044,53045,53046,53047,53049,53050,53051,53052,53053,53054, +53055,53056,53057,53058,53059,53060,U,U,U,U,U,U,53061,53062,53063,53064,53065, +53066,53067,53068,53069,53070,53071,53072,53073,53074,53075,53078,53079,53081, +53082,53083,53085,53086,53087,53088,53089,53090,53091,53094,53096,53098,53099, +53100,53101,53102,53103,53106,53107,53109,53110,53111,53113,53114,53115,53116, +53117,53118,53119,53121,53122,53123,53124,53126,53127,53128,53129,53130,53131, +53133,U,U,U,U,U,U,53134,53135,53136,53137,53138,53139,53140,53141,53142,53143, +53144,53145,53146,53147,53148,53149,53150,53151,53152,53154,53155,53156,53157, +53158,53159,53161,U,U,U,U,U,U,53162,53163,53164,53165,53166,53167,53169,53170, +53171,53172,53173,53174,53175,53176,53177,53178,53179,53180,53181,53182,53183, +53184,53185,53186,53187,53189,53190,53191,53192,53193,53194,53195,53196,53197, +53198,53199,53200,53201,53202,53203,53204,53205,53206,53207,53208,53209,53210, +53211,53212,53213,53214,53215,53218,53219,53221,53222,53223,53225,U,U,U,U,U,U, +53226,53227,53228,53229,53230,53231,53234,53236,53238,53239,53240,53241,53242, +53243,53245,53246,53247,53249,53250,53251,53253,53254,53255,53256,53257,53258, +U,U,U,U,U,U,53259,53260,53261,53262,53263,53264,53266,53267,53268,53269,53270, +53271,53273,53274,53275,53276,53277,53278,53279,53280,53281,53282,53283,53284, +53285,53286,53287,53288,53289,53290,53291,53292,53294,53295,53296,53297,53298, +53299,53302,53303,53305,53306,53307,53309,53310,53311,53312,53313,53314,53315, +53318,53320,53322,53323,53324,53325,53326,53327,U,U,U,U,U,U,53329,53330,53331, +53333,53334,53335,53337,53338,53339,53340,53341,53342,53343,53345,53346,53347, +53348,53349,53350,53351,53352,53353,53354,53355,53358,53359,U,U,U,U,U,U,53361, +53362,53363,53365,53366,53367,53368,53369,53370,53371,53374,53375,53376,53378, +53379,53380,53381,53382,53383,53384,53385,53386,53387,53388,53389,53390,53391, +53392,53393,53394,53395,53396,53397,53398,53399,53400,53401,53402,53403,53404, +53405,53406,53407,53408,53409,53410,53411,53414,53415,53417,53418,53419,53421, +53422,53423,53424,53425,53426,U,U,U,U,U,U,53427,53430,53432,53434,53435,53436, +53437,53438,53439,53442,53443,53445,53446,53447,53450,53451,53452,53453,53454, +53455,53458,53462,53463,53464,53465,53466,U,U,U,U,U,U,53467,53470,53471,53473, +53474,53475,53477,53478,53479,53480,53481,53482,53483,53486,53490,53491,53492, +53493,53494,53495,53497,53498,53499,53500,53501,53502,53503,53504,53505,53506, +53507,53508,53509,53510,53511,53512,53513,53514,53515,53516,53518,53519,53520, +53521,53522,53523,53524,53525,53526,53527,53528,53529,53530,53531,53532,53533, +53534,53535,U,U,U,U,U,U,53536,53537,53538,53539,53540,53541,53542,53543,53544, +53545,53546,53547,53548,53549,53550,53551,53554,53555,53557,53558,53559,53561, +53563,53564,53565,53566,U,U,U,U,U,U,53567,53570,53574,53575,53576,53577,53578, +53579,53582,53583,53585,53586,53587,53589,53590,53591,53592,53593,53594,53595, +53598,53600,53602,53603,53604,53605,53606,53607,53609,53610,53611,53613,53614, +53615,53616,53617,53618,53619,53620,53621,53622,53623,53624,53625,53626,53627, +53629,53630,53631,53632,53633,53634,53635,53637,53638,53639,53641,53642,U,U,U, +U,U,U,53643,53644,53645,53646,53647,53648,53649,53650,53651,53652,53653,53654, +53655,53656,53657,53658,53659,53660,53661,53662,53663,53666,53667,53669,53670, +53671,U,U,U,U,U,U,53673,53674,53675,53676,53677,53678,53679,53682,53684,53686, +53687,53688,53689,53691,53693,53694,53695,53697,53698,53699,53700,53701,53702, +53703,53704,53705,53706,53707,53708,53709,53710,53711,53712,53713,53714,53715, +53716,53717,53718,53719,53721,53722,53723,53724,53725,53726,53727,53728,53729, +53730,53731,53732,53733,53734,53735,53736,53737,53738,U,U,U,U,U,U,53739,53740, +53741,53742,53743,53744,53745,53746,53747,53749,53750,53751,53753,53754,53755, +53756,53757,53758,53759,53760,53761,53762,53763,53764,53765,53766,U,U,U,U,U,U, +53768,53770,53771,53772,53773,53774,53775,53777,53778,53779,53780,53781,53782, +53783,53784,53785,53786,53787,53788,53789,53790,53791,53792,53793,53794,53795, +53796,53797,53798,53799,53800,53801,53802,53803,53806,53807,53809,53810,53811, +53813,53814,53815,53816,53817,53818,53819,53822,53824,53826,53827,53828,53829, +53830,53831,53833,53834,53835,53836,U,U,U,U,U,U,53837,53838,53839,53840,53841, +53842,53843,53844,53845,53846,53847,53848,53849,53850,53851,53853,53854,53855, +53856,53857,53858,53859,53861,53862,53863,53864,U,U,U,U,U,U,53865,53866,53867, +53868,53869,53870,53871,53872,53873,53874,53875,53876,53877,53878,53879,53880, +53881,53882,53883,53884,53885,53886,53887,53890,53891,53893,53894,53895,53897, +53898,53899,53900,53901,53902,53903,53906,53907,53908,53910,53911,53912,53913, +53914,53915,53917,53918,53919,53921,53922,53923,53925,53926,53927,53928,53929, +53930,53931,53933,U,U,U,U,U,U,53934,53935,53936,53938,53939,53940,53941,53942, +53943,53946,53947,53949,53950,53953,53955,53956,53957,53958,53959,53962,53964, +53965,53966,53967,53968,53969,U,U,U,U,U,U,53970,53971,53973,53974,53975,53977, +53978,53979,53981,53982,53983,53984,53985,53986,53987,53990,53991,53992,53993, +53994,53995,53996,53997,53998,53999,54002,54003,54005,54006,54007,54009,54010, +54011,54012,54013,54014,54015,54018,54020,54022,54023,54024,54025,54026,54027, +54031,54033,54034,54035,54037,54039,54040,54041,54042,54043,54046,54050,54051, +U,U,U,U,U,U,54052,54054,54055,54058,54059,54061,54062,54063,54065,54066,54067, +54068,54069,54070,54071,54074,54078,54079,54080,54081,54082,54083,54086,54087, +54088,54089,U,U,U,U,U,U,54090,54091,54092,54093,54094,54095,54096,54097,54098, +54099,54100,54101,54102,54103,54104,54105,54106,54107,54108,54109,54110,54111, +54112,54113,54114,54115,54116,54117,54118,54119,54120,54121,54122,54123,54124, +54125,54126,54127,54128,54129,54130,54131,54132,54133,54134,54135,54136,54137, +54138,54139,54142,54143,54145,54146,54147,54149,54150,54151,U,U,U,U,U,U,54152, +54153,54154,54155,54158,54162,54163,54164,54165,54166,54167,54170,54171,54173, +54174,54175,54177,54178,54179,54180,54181,54182,54183,54186,54188,54190,U,U,U, +U,U,U,54191,54192,54193,54194,54195,54197,54198,54199,54201,54202,54203,54205, +54206,54207,54208,54209,54210,54211,54214,54215,54218,54219,54220,54221,54222, +54223,54225,54226,54227,54228,54229,54230,54231,54233,54234,54235,54236,54237, +54238,54239,54240,54242,54244,54245,54246,54247,54248,54249,54250,54251,54254, +54255,54257,54258,54259,54261,54262,54263,U,U,U,U,U,U,54264,54265,54266,54267, +54270,54272,54274,54275,54276,54277,54278,54279,54281,54282,54283,54284,54285, +54286,54287,54288,54289,54290,54291,54292,54293,54294,U,U,U,U,U,U,54295,54296, +54297,54298,54299,54300,54302,54303,54304,54305,54306,54307,54308,54309,54310, +54311,54312,54313,54314,54315,54316,54317,54318,54319,54320,54321,54322,54323, +54324,54325,54326,54327,54328,54329,54330,54331,54332,54333,54334,54335,54337, +54338,54339,54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351, +54352,54353,54354,54355,U,U,U,U,U,U,54356,54357,54358,54359,54360,54361,54362, +54363,54365,54366,54367,54369,54370,54371,54373,54374,54375,54376,54377,54378, +54379,54380,54382,54384,54385,54386,U,U,U,U,U,U,54387,54388,54389,54390,54391, +54394,54395,54397,54398,54401,54403,54404,54405,54406,54407,54410,54412,54414, +54415,54416,54417,54418,54419,54421,54422,54423,54424,54425,54426,54427,54428, +54429,54430,54431,54432,54433,54434,54435,54436,54437,54438,54439,54440,54442, +54443,54444,54445,54446,54447,54448,54449,54450,54451,54452,54453,54454,54455, +54456,U,U,U,U,U,U,54457,54458,54459,54460,54461,54462,54463,54464,54465,54466, +54467,54468,54469,54470,54471,54472,54473,54474,54475,54477,54478,54479,54481, +54482,54483,54485,U,U,U,U,U,U,54486,54487,54488,54489,54490,54491,54493,54494, +54496,54497,54498,54499,54500,54501,54502,54503,54505,54506,54507,54509,54510, +54511,54513,54514,54515,54516,54517,54518,54519,54521,54522,54524,54526,54527, +54528,54529,54530,54531,54533,54534,54535,54537,54538,54539,54541,54542,54543, +54544,54545,54546,54547,54550,54552,54553,54554,54555,54556,54557,U,U,U,U,U,U, +54558,54559,54560,54561,54562,54563,54564,54565,54566,54567,54568,54569,54570, +54571,54572,54573,54574,54575,54576,54577,54578,54579,54580,54581,54582,54583, +U,U,U,U,U,U,54584,54585,54586,54587,54590,54591,54593,54594,54595,54597,54598, +54599,54600,54601,54602,54603,54606,54608,54610,54611,54612,54613,54614,54615, +54618,54619,54621,54622,54623,54625,54626,54627,54628,54630,54631,54634,54636, +54638,54639,54640,54641,54642,54643,54646,54647,54649,54650,54651,54653,54654, +54655,54656,54657,54658,54659,54662,54666,54667,U,U,U,U,U,U,54668,54669,54670, +54671,54673,54674,54675,54676,54677,54678,54679,54680,54681,54682,54683,54684, +54685,54686,54687,54688,54689,54690,54691,54692,54694,54695,U,U,U,U,U,U,54696, +54697,54698,54699,54700,54701,54702,54703,54704,54705,54706,54707,54708,54709, +54710,54711,54712,54713,54714,54715,54716,54717,54718,54719,54720,54721,54722, +54723,54724,54725,54726,54727,54730,54731,54733,54734,54735,54737,54739,54740, +54741,54742,54743,54746,54748,54750,54751,54752,54753,54754,54755,54758,54759, +54761,54762,54763,54765,54766,U,U,U,U,U,U,54767,54768,54769,54770,54771,54774, +54776,54778,54779,54780,54781,54782,54783,54786,54787,54789,54790,54791,54793, +54794,54795,54796,54797,54798,54799,54802,U,U,U,U,U,U,54806,54807,54808,54809, +54810,54811,54813,54814,54815,54817,54818,54819,54821,54822,54823,54824,54825, +54826,54827,54828,54830,54831,54832,54833,54834,54835,54836,54837,54838,54839, +54842,54843,54845,54846,54847,54849,54850,54851,54852,54854,54855,54858,54860, +54862,54863,54864,54866,54867,54870,54871,54873,54874,54875,54877,54878,54879, +54880,54881,U,U,U,U,U,U,54882,54883,54884,54885,54886,54888,54890,54891,54892, +54893,54894,54895,54898,54899,54901,54902,54903,54904,54905,54906,54907,54908, +54909,54910,54911,54912,U,U,U,U,U,U,54913,54914,54916,54918,54919,54920,54921, +54922,54923,54926,54927,54929,54930,54931,54933,54934,54935,54936,54937,54938, +54939,54940,54942,54944,54946,54947,54948,54949,54950,54951,54953,54954,54955, +54957,54958,54959,54961,54962,54963,54964,54965,54966,54967,54968,54970,54972, +54973,54974,54975,54976,54977,54978,54979,54982,54983,54985,54986,54987,U,U,U, +U,U,U,54989,54990,54991,54992,54994,54995,54997,54998,55000,55002,55003,55004, +55005,55006,55007,55009,55010,55011,55013,55014,55015,55017,55018,55019,55020, +55021,U,U,U,U,U,U,55022,55023,55025,55026,55027,55028,55030,55031,55032,55033, +55034,55035,55038,55039,55041,55042,55043,55045,55046,55047,55048,55049,55050, +55051,55052,55053,55054,55055,55056,55058,55059,55060,55061,55062,55063,55066, +55067,55069,55070,55071,55073,55074,55075,55076,55077,55078,55079,55082,55084, +55086,55087,55088,55089,55090,55091,55094,55095,55097,U,U,U,U,U,U,55098,55099, +55101,55102,55103,55104,55105,55106,55107,55109,55110,55112,55114,55115,55116, +55117,55118,55119,55122,55123,55125,55130,55131,55132,55133,55134,U,U,U,U,U,U, +55135,55138,55140,55142,55143,55144,55146,55147,55149,55150,55151,55153,55154, +55155,55157,55158,55159,55160,55161,55162,55163,55166,55167,55168,55170,55171, +55172,55173,55174,55175,55178,55179,55181,55182,55183,55185,55186,55187,55188, +55189,55190,55191,55194,55196,55198,55199,55200,55201,55202,55203, +}; + +static const struct dbcs_index cp949ext_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{__cp949ext_decmap+0,65,254},{__cp949ext_decmap+190, +65,254},{__cp949ext_decmap+380,65,254},{__cp949ext_decmap+570,65,254},{ +__cp949ext_decmap+760,65,254},{__cp949ext_decmap+950,65,254},{ +__cp949ext_decmap+1140,65,254},{__cp949ext_decmap+1330,65,254},{ +__cp949ext_decmap+1520,65,254},{__cp949ext_decmap+1710,65,254},{ +__cp949ext_decmap+1900,65,254},{__cp949ext_decmap+2090,65,254},{ +__cp949ext_decmap+2280,65,254},{__cp949ext_decmap+2470,65,254},{ +__cp949ext_decmap+2660,65,254},{__cp949ext_decmap+2850,65,254},{ +__cp949ext_decmap+3040,65,254},{__cp949ext_decmap+3230,65,254},{ +__cp949ext_decmap+3420,65,254},{__cp949ext_decmap+3610,65,254},{ +__cp949ext_decmap+3800,65,254},{__cp949ext_decmap+3990,65,254},{ +__cp949ext_decmap+4180,65,254},{__cp949ext_decmap+4370,65,254},{ +__cp949ext_decmap+4560,65,254},{__cp949ext_decmap+4750,65,254},{ +__cp949ext_decmap+4940,65,254},{__cp949ext_decmap+5130,65,254},{ +__cp949ext_decmap+5320,65,254},{__cp949ext_decmap+5510,65,254},{ +__cp949ext_decmap+5700,65,254},{__cp949ext_decmap+5890,65,254},{ +__cp949ext_decmap+6080,65,160},{__cp949ext_decmap+6176,65,160},{ +__cp949ext_decmap+6272,65,160},{__cp949ext_decmap+6368,65,160},{ +__cp949ext_decmap+6464,65,160},{__cp949ext_decmap+6560,65,160},{ +__cp949ext_decmap+6656,65,160},{__cp949ext_decmap+6752,65,160},{ +__cp949ext_decmap+6848,65,160},{__cp949ext_decmap+6944,65,160},{ +__cp949ext_decmap+7040,65,160},{__cp949ext_decmap+7136,65,160},{ +__cp949ext_decmap+7232,65,160},{__cp949ext_decmap+7328,65,160},{ +__cp949ext_decmap+7424,65,160},{__cp949ext_decmap+7520,65,160},{ +__cp949ext_decmap+7616,65,160},{__cp949ext_decmap+7712,65,160},{ +__cp949ext_decmap+7808,65,160},{__cp949ext_decmap+7904,65,160},{ +__cp949ext_decmap+8000,65,160},{__cp949ext_decmap+8096,65,160},{ +__cp949ext_decmap+8192,65,160},{__cp949ext_decmap+8288,65,160},{ +__cp949ext_decmap+8384,65,160},{__cp949ext_decmap+8480,65,160},{ +__cp949ext_decmap+8576,65,160},{__cp949ext_decmap+8672,65,160},{ +__cp949ext_decmap+8768,65,160},{__cp949ext_decmap+8864,65,160},{ +__cp949ext_decmap+8960,65,160},{__cp949ext_decmap+9056,65,160},{ +__cp949ext_decmap+9152,65,160},{__cp949ext_decmap+9248,65,160},{ +__cp949ext_decmap+9344,65,160},{__cp949ext_decmap+9440,65,160},{ +__cp949ext_decmap+9536,65,160},{__cp949ext_decmap+9632,65,82},{0,0,0},{0,0,0}, +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const DBCHAR __cp949_encmap[33133] = { +8750,N,N,8756,N,N,8535,8487,N,10275,N,N,8489,8807,N,8518,8510,10615,10616, +8741,N,8786,8484,8748,10614,10284,N,10361,10358,10362,8751,N,N,N,N,N,N,10273, +N,N,N,N,N,N,N,N,N,10274,N,N,N,N,N,N,8511,10282,N,N,N,N,N,10285,10540,N,N,N,N, +N,N,10529,N,N,N,N,N,N,N,N,N,10531,N,N,N,N,N,N,8512,10538,N,N,N,N,N,10541, +10530,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10276,10532,N,N,N,N,N,N,N,N,N, +10533,10278,10534,N,N,N,N,10535,N,N,N,N,N,N,10280,10536,10281,10537,N,N,N,N,N, +N,10544,10287,10543,N,N,N,N,N,N,10283,10539,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,10286,10542,8743,N,N,N,N,N,N,N,N,8752,N,N,N,N,N,N,N,8744,8747,8746,8749,N, +8745,9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550, +9551,9552,9553,N,9554,9555,9556,9557,9558,9559,9560,N,N,N,N,N,N,N,9569,9570, +9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,N, +9586,9587,9588,9589,9590,9591,9592,11303,N,N,N,N,N,N,N,N,N,N,N,N,N,N,11297, +11298,11299,11300,11301,11302,11304,11305,11306,11307,11308,11309,11310,11311, +11312,11313,11314,11315,11316,11317,11318,11319,11320,11321,11322,11323,11324, +11325,11326,11327,11328,11329,11345,11346,11347,11348,11349,11350,11352,11353, +11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365,11366, +11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,N,11351, +8490,N,N,8494,8495,N,N,8496,8497,N,N,8787,8788,N,N,N,8485,8486,N,N,N,N,N,N,N, +N,N,8758,N,8519,8520,N,N,N,N,N,N,N,8536,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +10617,N,N,N,N,N,N,N,N,N,N,10618,N,10619,10620,10621,10622,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8806,8521,N,N,N,N,N, +8757,N,N,N,N,N,N,N,N,N,10020,N,N,8800,N,N,N,N,N,N,N,N,N,N,8805,8802,N,N,N, +10073,N,N,N,N,8522,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,10359,10360,N,N,N,N,N,N,10363,10364,10365,10366,N,9520, +9521,9522,9523,9524,9525,9526,9527,9528,9529,N,N,N,N,N,N,9505,9506,9507,9508, +9509,9510,9511,9512,9513,9514,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +8551,8552,8550,8553,8554,8789,8792,8790,8793,8791,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,8737,N,8738,8739,N,8531,8740,N,N,N,8532,8564,N,N,8565,N,N,N,8755,N,8754, +N,N,N,N,N,N,N,N,8558,N,N,8560,8516,N,8528,N,N,N,N,8491,N,8572,8573,8571,8570, +8562,8563,N,8753,N,N,N,N,N,8517,8561,N,N,N,N,N,N,8493,8559,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,8534,N,N,N,N,N,N,N,N,N,N,N,N,N,8513,8533,N,N,8514,8515, +N,N,N,N,8556,8557,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8568,8569,N,N, +8566,8567,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8769,N,N,N,N,N,N,N,N,N,N,N,8529, +8530,10343,10344,10345,10346,10347,10348,10349,10350,10351,10352,10353,10354, +10355,10356,10357,N,N,N,N,N,10599,10600,10601,10602,10603,10604,10605,10606, +10607,10608,10609,10610,10611,10612,10613,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582, +10583,10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595, +10596,10597,10598,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10317, +10318,10319,10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330, +10331,10332,10333,10334,10335,10336,10337,10338,10339,10340,10341,10342,9761, +9772,9762,9773,N,N,N,N,N,N,N,N,9763,9800,9799,9774,9764,9794,9793,9775,9766, +9798,9797,9777,9765,9796,9795,9776,9767,9788,9801,9802,9783,9803,9804,9778, +9769,9790,9805,9806,9785,9807,9808,9780,9768,9809,9810,9784,9789,9811,9812, +9779,9770,9813,9814,9786,9791,9815,9816,9781,9771,9817,9818,9787,9819,9820, +9792,9821,9822,9823,9824,9825,9826,9827,9828,9782,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8774,N,N,N,N,N,N,N,N,N,N,N,N,N,8545,8544,N, +8771,8775,8776,8779,8778,8777,8780,N,N,N,N,N,N,N,N,8547,8546,N,N,8762,8761,N, +N,N,N,8549,8548,N,N,8760,8759,N,N,N,N,8543,8542,8770,N,N,8539,N,N,8541,8540, +8772,8773,8538,8537,N,N,N,N,N,N,N,8783,8782,N,N,N,N,N,N,N,N,N,N,N,N,8784,N, +8785,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8527,N, +8526,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,8764,8765,N, +8768,8763,8766,N,8767,8781,8795,8796,N,8797,8794,8481,8482,8483,8488,N,N,N,N, +8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,N,8555,8498,8499,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796,10797, +10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810, +10811,10812,10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823, +10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,10836, +10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847,10848,10849, +10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860,10861,10862, +10863,10864,10865,10866,10867,N,N,N,N,N,N,N,N,N,N,N,N,N,11041,11042,11043, +11044,11045,11046,11047,11048,11049,11050,11051,11052,11053,11054,11055,11056, +11057,11058,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069, +11070,11071,11072,11073,11074,11075,11076,11077,11078,11079,11080,11081,11082, +11083,11084,11085,11086,11087,11088,11089,11090,11091,11092,11093,11094,11095, +11096,11097,11098,11099,11100,11101,11102,11103,11104,11105,11106,11107,11108, +11109,11110,11111,11112,11113,11114,11115,11116,11117,11118,11119,11120,11121, +11122,11123,11124,11125,11126,9249,9250,9251,9252,9253,9254,9255,9256,9257, +9258,9259,9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272, +9273,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287, +9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302, +9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317, +9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332, +9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,10545,10546,10547,10548, +10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,10559,10560,10561, +10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,10572,8799,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,10289,10290,10291,10292, +10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303,10304,10305, +10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,N,N,N,8798, +10057,10058,10059,10060,10061,N,N,N,10042,10043,10076,10077,10078,10038,10039, +10040,10068,10069,10070,10071,10072,10017,10018,10019,10021,10027,10028,10029, +10030,10031,10032,10033,10034,10035,10036,10023,10024,10025,10026,10045,10046, +10085,10086,10087,10088,10081,10082,10083,10047,10048,10049,10050,10051,10052, +10053,10054,10055,10056,10062,10063,10064,10065,10066,10067,10074,10075,8803, +10092,10022,10080,10095,8801,10044,10093,10037,N,N,N,N,10041,10090,N,N,10091, +N,N,10079,N,8804,N,N,10084,10094,10089,27753,28491,N,30290,N,N,N,22578,27995, +24370,24382,31035,N,23668,N,N,N,30052,N,N,29478,23904,24870,N,20088,23600,N,N, +N,N,25386,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29033,N,N,N,N,19834,N,N,N,N,N,31791, +21281,N,28971,N,N,N,N,N,N,26449,21036,N,20089,N,N,N,N,N,29053,N,24127,31546, +31033,N,N,N,N,N,N,20050,N,25387,27488,N,N,N,20090,19319,25893,N,N,N,N,N,N,N,N, +N,N,N,19041,N,21580,N,N,N,N,N,27233,N,N,23651,24365,N,N,N,N,N,N,19307,N,N,N, +21807,N,N,N,22133,N,25976,N,N,24128,27683,N,26957,N,27175,26998,31547,N,26473, +28492,N,N,20582,N,N,24129,N,N,25644,N,N,22604,31089,N,20063,31268,26162,N, +31355,N,N,31293,19528,28493,21845,N,N,N,N,N,N,N,21282,N,N,N,27729,N,N,N,N,N, +25639,27730,N,N,30257,N,N,20091,N,N,20561,19263,N,27940,N,N,N,N,N,N,27944, +24130,30306,27996,23669,24633,N,N,N,21582,N,29749,N,N,N,21339,22069,27684,N,N, +N,N,N,N,N,N,N,N,25702,N,29034,N,N,N,19308,19264,N,N,N,27762,20586,N,N,N,N,N,N, +N,31090,27685,20575,N,26474,20587,23633,23401,32076,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23383,N,N,N,N,23137,N,22070,N,25439,N,24131,N, +24132,18977,N,N,N,N,N,28268,N,N,21283,28215,30799,N,N,N,N,27208,28216,28972, +28965,26958,N,N,N,31036,N,N,N,25977,27754,23894,27970,N,N,N,N,N,N,N,N,N,N,N,N, +30757,N,N,N,N,N,25914,23384,N,N,18978,N,N,20813,N,N,N,28269,N,N,N,27755,24133, +N,25440,N,19017,29289,N,21838,N,30262,N,20034,22087,N,25396,N,28973,N,27234,N, +N,N,N,22338,N,29479,N,N,19818,N,27502,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22834, +32037,N,N,N,N,N,30293,21858,N,N,N,N,N,N,N,N,30773,N,N,19573,30005,25645,N,N,N, +N,26475,29013,N,N,N,28731,N,N,26933,N,19529,31317,N,N,24916,N,N,22358,N,N, +23617,N,24134,31343,25441,N,N,N,N,N,N,N,N,N,N,N,N,24947,23670,N,20092,N,23364, +N,30833,N,N,23652,N,25967,23601,N,N,N,21846,N,N,29530,N,19265,N,23363,N,N,N, +22906,21358,N,N,N,31288,N,N,32038,27503,N,29734,N,19530,29480,N,29531,N,23335, +30263,N,20326,28786,19290,N,26450,22339,30320,26718,N,N,N,N,N,N,N,N,N,N,N,N,N, +25894,N,N,N,N,N,N,N,25959,N,N,N,18979,19495,27209,N,N,N,N,N,30774,N,N,N,N,N, +31269,N,N,N,N,28974,N,28494,N,N,N,N,N,N,N,N,19309,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +30256,28495,26959,N,30558,N,N,N,N,N,N,N,20051,N,N,N,N,23671,N,N,N,N,N,N,N, +23336,N,N,N,19320,N,N,N,N,N,N,24353,23905,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +30026,26934,N,N,N,N,26476,28270,N,29552,N,24383,N,N,N,N,N,N,19531,N,N,N,N,N,N, +20545,N,N,N,29778,24634,N,N,N,N,24384,N,20064,N,N,N,23634,32106,N,N,N,22134,N, +N,N,27210,N,N,N,N,N,N,26729,N,25388,N,N,N,N,N,29520,N,N,N,N,N,N,N,N,N,N,N, +18980,N,23416,N,N,N,24135,27504,29014,N,N,25954,N,19532,N,N,19323,N,N,N,N,N,N, +N,N,27235,N,N,N,N,N,N,N,N,N,N,N,N,24385,N,22125,N,N,N,N,N,N,N,N,26960,N,N,N,N, +N,N,N,28217,N,N,N,N,21859,N,N,20819,N,25968,N,N,N,26676,27459,N,27178,31356, +30070,28732,32084,24635,20035,N,20538,30522,22643,30541,N,N,N,25646,N,N,N,N,N, +N,N,N,N,21599,N,N,N,N,N,20583,N,N,27773,N,21038,28271,21847,27236,30754,19819, +22335,31537,N,N,19820,N,N,N,23602,20588,20093,28272,N,N,N,19522,N,N,N,20589,N, +N,N,N,N,25975,N,N,N,29564,N,N,28194,N,N,N,N,22835,N,N,22644,N,26935,N,N,N,N,N, +N,N,N,20014,N,N,N,N,22818,N,N,N,N,22641,N,21583,N,N,N,N,N,N,N,N,N,25895,21842, +N,N,N,N,N,22057,N,N,N,N,N,N,29730,N,29015,N,N,21848,N,28733,22352,21584,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,22351,27498,32107,N,N,23405,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +31813,19266,N,N,N,N,32085,N,29768,26730,30067,N,N,31070,21359,N,N,27731,N,N, +23874,28471,26452,N,19018,N,N,N,22907,N,N,31357,N,N,N,N,N,22058,N,N,N,N,N, +29816,N,N,N,N,N,N,30583,23596,N,N,N,22359,24354,N,N,N,20030,N,21360,N,N,N,N,N, +28708,24940,20327,29515,27945,19006,N,N,N,N,N,N,N,29807,N,N,N,30286,N,N,24187, +20539,21815,28273,N,N,N,N,N,N,29736,N,23672,N,N,N,N,19239,N,23118,N,N,N,24678, +N,N,N,N,N,N,N,27941,28274,N,N,N,N,23673,N,N,31068,N,N,29532,N,N,N,N,N,N,N, +30834,N,29817,N,N,N,31857,N,N,N,20540,23417,22321,N,N,N,19324,N,N,N,28709, +19325,N,N,N,N,N,N,N,N,21876,N,N,N,19821,18981,N,N,22059,20546,N,N,N,N,28734, +21053,19492,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31286,N,N,19533,N,23162,N, +30287,N,26936,N,22645,N,N,N,19534,N,N,N,N,22349,N,N,21585,26989,N,19051,22882, +N,32050,N,25389,22092,22836,N,N,24871,28243,20547,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +32051,N,21860,N,N,20328,N,27971,20530,N,N,20094,23080,30800,N,N,32086,N,N,N,N, +30801,N,30802,23635,N,N,N,N,23906,31609,23873,N,25397,N,N,N,N,N,N,27997,20036, +N,19233,N,N,N,N,N,N,23907,N,N,N,N,31837,N,N,N,N,N,N,N,N,N,31023,N,N,N,N,N, +21115,20257,25640,N,29750,27774,N,N,25390,26477,32065,23138,N,N,22579,N,N,N, +23908,28783,30321,31344,N,N,20853,N,N,23119,N,23636,N,23590,N,28479,N,N,N,N,N, +20047,N,24665,N,N,N,N,N,N,22870,27732,27211,N,N,19007,21808,N,20329,N,N,N,N,N, +29037,N,19535,N,N,N,N,25720,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25709,N,N,N,N,22360,N, +32039,N,N,N,N,27179,30258,N,N,N,N,20336,31037,N,N,N,N,N,N,26228,N,N,N,N,N,N,N, +N,N,N,N,N,N,19291,N,N,N,N,N,N,N,29521,N,N,N,N,26961,29481,20576,26962,N,23139, +N,N,N,N,N,N,25170,N,30242,24948,N,N,N,23140,N,N,N,N,N,26453,30015,20258,19759, +20259,N,N,N,19760,29054,20515,24879,30755,N,18982,30523,29290,24136,26963,N,N, +N,N,24137,32094,19008,N,N,N,31082,20814,28244,N,21586,22819,32040,22361,30542, +31294,N,N,N,N,N,N,N,N,N,20310,N,22384,N,27489,30789,N,N,N,N,N,23674,N,N,23875, +N,31071,N,N,N,N,N,N,N,26479,N,N,N,N,32101,30243,N,22908,32041,N,26478,N,N,N, +21861,N,N,N,N,N,28496,N,19761,N,N,N,N,N,N,30498,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,28978,N,28977,N,N,N,N,N,N,19762,N,23083,N,18983,N,N,N,N,N,25442, +31548,22820,N,N,28218,N,N,N,N,N,30803,N,N,N,N,N,31610,N,20260,N,23675,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30307,N,N,N,27946,N,N,29217,20065,N,N,N,N,N,N, +31270,N,N,N,N,31072,N,N,N,N,27734,N,N,25710,31009,N,N,31599,N,N,N,31083,28195, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27180,N,N,N,18984,N,N,29818,N,N, +N,N,19798,31862,N,N,N,29769,N,N,N,N,N,N,N,30804,30758,N,24138,29254,N,N,N,N,N, +N,22362,N,21328,N,N,N,N,N,N,N,N,N,N,N,22597,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,27238,N,29533,N,N,N,25690,N,N,N,N,N,N,N,N,30308,N,N,N,N,N,30322,N,24386,N,N, +N,N,N,N,N,N,22909,N,N,N,19574,N,N,21306,N,N,N,N,N,N,N,25647,N,N,N,N,31073,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28710,N,N,N,19283,N,N,N,24636,N, +29770,21626,N,32042,31074,N,N,N,N,N,N,N,N,N,N,N,N,N,29751,32066,31792,N,32108, +19042,N,N,N,N,N,N,N,N,N,32061,N,27239,24387,20818,20066,N,21284,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,32043,N,24416,N,N,N,N,N,N,N,N,N,N,N,N,29255,N,N, +N,N,N,26480,N,20590,N,N,29482,N,N,N,24139,30264,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,24949,28979,30499,N,N,18985,N,N,N,N,N,N,N,N,N,N,20261,N,N, +24388,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24880,N,N,28735,N,30244,N, +25398,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31302,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20591,N,N,32109,N,N,N,N,N,N,N,N,23876,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,31863,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,26175,N,N,N,N,N,N,24109,N,31295,N,N,N,N,N,25969,N,N,N,N,N,N,N, +27972,N,N,N,N,N,N,N,N,N,N,N,N,N,21029,N,N,32110,N,N,N,30006,N,N,N,N,N,N,N,N, +24950,24140,N,N,31838,N,27735,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19805,N,N,N,N,N,N, +N,N,22071,19763,30805,25944,N,N,N,20330,N,N,20304,N,27212,N,N,N,N,27182,27181, +N,N,21361,N,21285,N,N,N,N,N,N,30543,N,N,N,N,N,N,N,N,28196,N,N,N,N,20516,N,N, +29218,N,N,N,N,N,N,N,N,N,N,20592,N,N,N,N,29219,N,30584,N,N,N,N,20531,N,N,23337, +N,N,21307,19052,N,28966,19285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30567,N,N,19806,N, +30500,N,N,N,30784,N,N,N,21341,N,19536,N,N,N,N,20262,N,N,N,N,N,N,30323,N,N,N,N, +N,24951,N,N,N,N,N,21340,N,N,31358,N,N,N,N,N,N,N,31271,N,N,N,N,N,N,N,N,N,N,N,N, +27481,N,20263,27183,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,25711,N,N,N,26937,29016,N,N,22616,N,N,24690,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,26164,23676,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29553,N,N,N,25424,N,N,29307,N, +23366,20593,N,20594,20316,N,21329,N,N,19505,30552,N,19240,27452,25662,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29788,N,N,23618,N,N,28711,N,N,26176,N,N,19053,N, +N,N,N,26731,25960,23619,N,N,27998,21362,N,N,N,N,19575,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,20052,26411,N,N,N,19267,N,24881,N,N,30514,N,N,21363,21330,N,30016,N,N,N, +24413,N,N,28275,26481,N,32052,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29256,N,N,N, +29522,N,N,28276,N,25171,N,N,N,N,19537,N,24426,N,N,N,26938,N,N,N,N,N,N,N,N,N, +22871,N,N,N,N,N,N,N,N,30029,N,29042,31303,N,N,N,N,N,N,N,N,22904,21570,N,N,N,N, +30309,N,N,N,N,23877,N,N,N,N,N,N,26482,27999,N,N,19019,N,N,23418,N,N,N,26677,N, +21286,N,N,N,N,N,N,32053,N,N,31049,N,25698,N,31549,N,N,22308,20037,N,N,N,N, +20053,22118,N,N,N,N,25917,N,N,N,N,N,N,24141,27763,N,N,28000,N,N,N,N,N,N,N,N,N, +27756,31550,24427,N,24952,31038,N,N,N,N,20595,24618,26722,N,N,25172,21117,N, +25896,N,N,N,N,N,22867,N,N,N,N,21342,N,29752,30524,23677,N,26732,25703,N,N, +25463,N,N,N,N,N,27688,N,N,N,N,N,N,31345,N,N,N,N,N,25970,N,N,20596,21039,23653, +N,N,N,N,20517,28980,31793,19576,N,N,23878,31313,N,30559,N,N,31272,N,N,N,N,N, +28277,N,24142,N,N,N,N,26483,N,N,30508,27460,28001,24619,23879,N,N,N,N,21043, +21055,N,N,N,19020,N,N,N,N,31551,N,N,N,N,25981,23909,22605,N,N,N,N,N,27764,N,N, +N,N,N,N,N,N,20597,N,N,26733,20562,N,22872,N,N,N,N,N,N,N,N,N,N,N,30310,N,N, +23338,N,N,N,30560,N,N,N,N,N,N,N,N,N,N,N,N,22617,N,29731,N,N,29789,N,N,N,N, +28497,N,N,22837,N,N,27947,N,25399,N,N,N,N,28219,19764,N,24691,27213,N,N,N,N, +27765,26734,N,19241,28975,N,N,N,N,N,N,N,N,19021,N,27689,N,29291,N,32111,N, +31091,N,N,N,N,N,N,N,N,N,26177,N,N,27736,N,N,N,27948,27214,N,26719,N,N,N,N,N,N, +N,N,N,N,N,N,N,24143,N,N,N,N,N,N,21030,N,N,26484,20822,N,N,26178,25443,N,N,N,N, +25648,N,N,N,22580,N,N,N,N,N,N,N,N,N,N,N,N,30245,N,N,N,N,N,29534,N,N,N,N,22309, +N,N,N,N,30568,N,N,26694,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31590,N,N,N,N,N,N,N, +23910,N,N,N,23678,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,22618,N,N,N,N,N,N,N,23084,27184,N,N,N,N,N,N,N,N, +25400,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,18986,24953,N, +27185,N,N,N,N,29292,N,N,31342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28245,N, +N,N,N,31092,N,N,21100,31611,N,N,N,32112,N,24637,20067,N,N,N,N,N,N,N,N,N,30790, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24110,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,24389,N,N,25918,N,N,N,N,N,N,N,N,N,N,N,N,27949,31338,N,N,19822,27942,N, +27950,28781,N,23841,N,27951,31864,N,22635,N,N,N,19577,19765,N,N,N,N,31273,N, +24925,N,N,N,N,25173,27983,N,N,N,23842,N,N,31050,N,27240,N,25965,N,N,N,N,N,N,N, +N,21355,N,26964,24954,25676,N,24932,26695,N,N,20059,N,N,N,23637,N,30517,31859, +28787,20015,28981,28498,26696,27505,N,N,N,N,N,19284,24638,25464,27241,31794,N, +N,N,N,N,24692,N,20320,N,28197,N,N,31274,26179,24882,18987,N,25444,26939,N,N,N, +N,N,25174,29554,N,28246,27186,20598,27737,23115,20264,N,N,N,N,23843,N,N,N, +22619,N,31054,26965,25425,N,N,21052,N,N,N,N,N,N,22572,29516,N,19835,30294,N, +26485,26735,25465,21051,29555,25467,N,24144,20016,N,22135,29017,N,N,N,N,N, +30017,23620,N,30011,N,24145,23654,N,N,24146,N,N,28002,28278,27215,28782,25468, +N,21343,21364,24883,N,24884,N,N,N,N,29779,N,N,24390,N,N,N,N,N,N,N,N,N,N,26966, +N,N,N,23339,N,N,N,N,N,N,N,N,30246,N,N,N,N,N,N,25401,27461,29737,19766,21113,N, +23085,21091,20305,N,N,N,N,19292,19578,N,20317,N,N,26665,N,25403,25402,N,N, +24666,N,N,N,28279,N,N,N,N,N,23603,N,N,N,N,21365,N,22310,N,30261,22363,N,N,N,N, +N,N,24917,N,N,21610,N,24355,N,N,N,N,N,N,N,32095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,20599,27988,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19242,N,N,N,N,N,N,N, +25691,N,24955,19234,N,N,N,N,21344,N,25663,N,31552,N,23102,25677,N,22073,N,N,N, +28480,N,24956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30265,N,N,N,N,N, +N,24391,N,N,N,N,N,N,N,25649,N,N,N,N,N,N,23655,23656,N,N,N,31318,N,21366,N,N,N, +N,29018,N,31346,25213,N,N,N,N,N,21839,20600,N,N,19807,N,N,30027,N,25712,19243, +N,22340,N,N,N,N,N,N,N,N,N,N,N,N,N,25214,N,23898,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23086,19054,N,N,N,21817,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25377,N,N,26723,N,N,29483,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,20265,N,N,N,21367,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +21617,N,N,20068,N,26738,N,N,N,N,N,N,N,25973,N,N,N,N,N,N,N,N,N,N,N,N,N,26414,N, +22074,N,24428,25664,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26724,N,N,N,N,22581,N,N,N, +25692,N,N,N,N,N,N,29753,28982,N,N,25182,24885,N,N,19823,28967,20069,19293,N,N, +22883,N,N,29484,N,N,20601,27691,24147,30569,N,N,31093,N,N,N,N,N,24926,19310, +25404,30806,N,N,23406,N,N,N,N,N,32113,N,N,N,N,30518,N,N,N,N,29790,N,N,29293,N, +23385,N,28712,N,N,N,N,N,N,N,24957,N,N,N,N,N,24148,N,24620,N,N,N,N,N,28003,N,N, +21345,N,24392,N,N,N,N,22838,N,32044,28499,N,N,N,25665,30827,N,23340,N,N,N,N, +31814,N,N,N,N,N,N,N,N,22573,N,N,N,N,N,N,N,N,N,30266,N,23391,21331,30791,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,19022,30785,21044,N,N,23604,31289,19023,N,31795,27242, +27243,20602,N,N,N,N,N,28004,N,N,23911,N,N,24393,N,N,N,N,24429,N,N,N,N,N,28220, +N,28481,N,N,19538,N,23844,N,N,N,24394,N,N,N,N,N,21368,28968,N,N,N,19767,N, +28500,N,N,N,N,N,N,N,25693,24430,19244,26940,N,N,N,N,N,27244,N,N,N,24395,N,N,N, +N,N,31039,22063,21830,N,N,N,N,N,20266,N,N,20009,N,N,22136,N,N,N,28983,28280,N, +N,N,22873,29535,N,30792,20038,N,N,N,N,N,N,N,N,21862,N,N,N,N,N,N,29798,N,N, +26181,28501,N,N,19311,31839,23591,N,N,22119,N,N,N,N,N,30793,N,N,N,N,25426,N, +25405,N,20321,28736,27738,N,23895,31600,N,N,27692,N,N,N,28713,N,N,N,N,N,N, +31319,31553,N,21056,N,N,N,N,N,N,N,25904,N,N,N,28005,N,N,N,N,19245,N,31024,N,N, +N,N,N,N,N,N,N,N,N,30501,N,19246,N,23087,N,22582,N,N,N,N,N,N,N,21287,31538,N, +32068,N,27693,N,N,N,N,N,N,31521,N,N,N,25961,26990,N,29556,30835,28737,24111, +30768,N,N,29536,26415,N,N,N,N,N,23341,N,26165,N,N,31016,N,N,23896,26713,28502, +N,N,N,21346,N,25183,N,N,31840,22344,32045,N,N,N,24431,19539,21369,N,N,N,N, +21616,23367,24149,N,N,N,N,28788,N,21840,25945,N,N,N,N,N,N,31815,23638,25184,N, +N,N,23088,N,N,N,N,N,N,29475,N,21356,N,29771,N,N,N,32069,N,N,N,N,N,25469,N, +31025,N,N,N,N,N,N,20603,27739,N,N,N,N,N,N,N,N,30012,29220,22606,22607,N,N,N,N, +N,N,30071,N,N,N,N,N,N,N,N,N,N,30305,N,N,N,N,N,N,N,N,N,21047,N,N,N,N,N,N,N, +31596,N,23880,25704,N,N,21057,N,N,N,30807,N,N,N,N,N,22075,24150,N,N,30525, +27694,N,N,N,20577,N,24693,27187,N,20054,N,N,N,N,19493,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,27766,25185,25406,N,N,N,N,N,N,N,N,N,31816,N,N,19824,N,31094,N,N, +24432,N,N,N,25919,N,N,N,20031,N,N,N,N,31841,27952,32081,30267,N,N,31055,27482, +19009,N,21048,19825,N,25427,32102,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +26221,N,N,N,25466,N,N,28714,31056,N,N,N,N,N,N,31842,N,30759,N,N,N,24933,28281, +N,N,N,26486,27245,N,N,31796,30018,N,N,22364,N,N,N,N,N,N,N,N,28789,N,23912, +21357,30076,N,23103,N,19579,N,N,N,21370,29732,N,N,N,N,N,N,N,28503,N,21571,N,N, +N,N,N,N,N,N,N,31587,N,N,N,N,N,N,N,N,31597,N,24621,N,N,27246,31539,25666,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,30311,21085,N,24396,N,N,31817,N,N,25897,24694,30259, +24958,N,N,N,N,19312,N,27247,27248,N,N,N,23104,30772,27506,N,N,N,N,N,25667,N,N, +N,N,26967,25713,N,N,N,19055,N,N,N,N,N,N,N,20055,N,N,N,N,N,N,N,N,31818,N,N,N, +29537,N,N,19268,N,N,N,N,25445,N,19269,27188,N,N,26941,N,22345,N,N,27483,27953, +N,19523,30526,31819,N,N,N,N,N,N,30836,N,22839,N,N,29523,29524,N,N,N,30564,N, +30545,N,N,22583,20017,19010,N,N,31540,19270,N,N,28790,N,N,21863,N,27216,N,N,N, +N,N,19540,19247,N,N,N,N,N,29738,26927,N,N,30019,26968,N,N,N,N,N,N,N,23913,N,N, +N,29043,N,21883,24123,N,N,29819,N,N,N,32115,32114,30502,N,N,N,N,N,N,N,N,N, +23881,N,N,21587,N,19496,N,23105,19541,N,22884,N,N,N,31306,N,N,N,25955,N,N,N, +21308,N,N,N,19056,N,N,N,N,20548,N,N,N,19024,31275,27499,26488,22885,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20823,N,N,N,N,N,N,N,N,N,N,N,29476,N, +N,N,21627,31843,31320,N,29525,N,20267,N,N,27507,21884,N,N,N,N,N,N,21332,19836, +N,22886,N,25209,25121,27476,N,24695,25650,19580,N,N,N,31588,N,N,N,29739,N,N,N, +N,20541,N,19057,N,N,N,N,N,N,N,N,28472,N,N,N,22336,N,28282,32116,N,N,21347,N, +31554,N,N,N,N,N,N,N,21864,23342,24886,30775,N,N,N,N,N,24639,31555,23914,N, +25122,N,28198,N,N,N,N,N,30312,N,N,N,N,30325,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,23882,N,N,20578,N,N,N,N,23846,N,N,23915,N,N,25721,N,N,25391,20604,N,N, +N,29820,N,N,N,N,19516,30570,N,N,N,N,N,N,25956,24433,N,N,30561,N,31095,28473,N, +N,30808,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31017,N,N,N,N,N,30809,N,N,N,28221,N,N,N, +22598,N,N,25699,30030,N,N,N,N,23897,N,N,N,N,22887,21049,21827,N,N,23141,23120, +N,20825,20056,N,19294,29740,23163,N,30313,26739,20268,28784,N,29821,23368,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,20032,25428,20815,29045,N,19826,N,20331,N,N,N,19768, +N,N,N,N,N,N,25382,20826,29221,N,N,N,N,N,29222,N,25678,N,N,N,N,N,N,N,21371,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28969,N,N,N,29257,N,N,N,N,N,N,N, +N,N,N,28504,26185,N,22584,31347,N,N,N,N,N,N,N,N,N,N,29493,N,N,30756,N,N,20851, +26184,N,N,N,N,30810,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23657,24151,N,N,N,N,N, +19295,N,N,N,20332,N,N,N,N,29791,N,N,20852,21050,N,N,N,24434,N,N,N,24887,N,N,N, +N,25123,21372,N,N,28006,N,N,N,N,N,23369,N,N,N,25722,N,20318,N,N,20048,N,N,N,N, +21843,29557,30510,N,N,28488,N,19827,30031,25971,28738,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,19025,N,N,N,27249,N,20518,N,N,N,N,N,N,N,N,22874,28715,N,N,N, +N,N,27495,N,N,N,25920,31797,N,N,N,N,N,25668,N,N,N,N,N,N,N,N,N,N,N,19497,32070, +N,N,N,N,N,27189,N,25898,24378,24927,N,23121,N,N,N,N,24888,N,26740,21373,N,N,N, +N,25124,N,N,N,N,N,29258,N,N,N,N,N,N,N,N,N,23142,30515,N,N,N,N,N,N,N,N,N,N,N,N, +32077,N,N,N,29494,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28247,N,N, +N,N,N,N,N,30020,N,N,N,N,N,N,N,N,22564,N,N,N,N,N,29223,N,N,N,N,N,N,N,N,22840, +22841,28489,N,N,N,N,N,N,N,N,N,N,N,N,N,22094,N,N,N,N,N,N,N,N,30539,24366,26741, +N,N,N,N,N,N,21045,N,N,N,21333,N,N,N,N,N,29772,23164,N,N,N,N,N,22888,N,30571, +30025,N,29500,N,23122,N,N,N,N,N,N,N,N,21301,N,N,N,N,N,26678,N,N,22095,29754,N, +30537,N,N,19498,N,N,28739,19542,N,N,N,20563,N,21309,N,N,N,23419,N,19296,N,N,N, +N,N,N,21348,30327,N,N,21818,29517,19297,N,N,N,N,27508,N,N,N,N,N,29741,N,31786, +N,N,N,N,N,30572,N,N,N,26742,23143,N,N,N,30540,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,25921,N,N,N,N,24686,N,N,N,N,N,21885,N,N,N,N,N,N,20070,31787,21819,N,N, +29224,N,N,N,N,N,N,25125,19769,27250,19271,N,19828,N,N,23343,28505,N,N,N,N,N, +19770,N,N,31865,N,N,N,N,24435,20071,23106,N,20269,N,N,N,N,26489,30760,N,N,N,N, +N,N,29538,N,N,N,19058,24356,N,N,21572,N,N,N,N,N,19543,25922,N,N,N,N,19771,N, +28506,28248,N,23847,25126,N,N,N,N,N,24640,N,N,N,22064,30794,N,31866,N,22910,N, +N,N,N,24112,N,N,N,23916,23144,N,N,N,N,N,21600,N,22137,N,19799,24152,N,N,29304, +N,25686,N,N,20549,29742,N,23848,N,N,N,27973,29526,N,N,24153,25446,N,N,N,N,N,N, +21288,N,23344,N,N,25946,25407,N,N,N,23345,N,N,N,21865,N,N,N,N,N,24641,28507,N, +N,28777,N,N,22322,N,N,N,N,20605,N,N,N,N,N,N,N,N,22889,N,N,20606,N,27757,21289, +N,29225,28740,N,N,25186,26991,N,N,N,31057,N,N,26969,N,N,N,N,N,26714,23107, +23108,21573,N,26490,19808,25392,N,23346,31556,N,29539,N,22821,31591,23883, +20564,N,26166,24622,32090,N,N,N,N,N,N,N,N,23605,24696,26417,N,N,N,N,30064,N, +22620,27974,N,N,N,N,24889,N,25408,31040,26992,N,N,22875,N,29540,N,N,N,23606, +25705,N,N,N,N,N,28741,25409,31820,31821,N,N,N,N,29259,N,29260,N,N,N,25679,N,N, +N,N,N,N,N,N,N,29019,N,31321,N,28984,32117,24697,N,N,N,N,26491,31799,31844, +31557,25447,22585,N,30328,N,N,23621,19544,N,N,N,24623,29799,N,28508,20348, +28509,N,29226,N,N,N,N,N,N,N,N,N,32062,N,N,18988,32059,32071,N,N,N,N,26418,N, +27217,24436,N,N,N,N,20844,25694,25923,N,N,N,N,22822,N,N,19772,N,29541,N,N,N,N, +N,N,N,N,27989,N,N,22842,N,N,N,28007,31541,30828,N,N,N,N,24679,N,19545,N,N, +21574,N,N,N,N,N,26405,N,21877,21310,N,31867,N,N,N,N,N,N,N,N,N,N,N,N,25714,N,N, +24437,N,N,26744,30829,N,N,20039,N,N,N,N,N,32118,N,N,N,N,N,N,N,N,N,26712,N, +19800,26454,19546,N,N,19043,24438,28743,28742,N,22586,N,29044,29808,30028,N,N, +31845,N,N,N,N,27205,27251,N,23899,N,23639,N,N,N,N,N,N,24189,29305,N,21831,N,N, +N,22608,N,28744,20769,20770,N,N,N,N,N,N,22868,22120,22858,N,23089,22599,23650, +29518,30068,N,N,28985,N,N,23123,N,30314,N,N,N,20341,N,N,32046,N,N,N,N,N,N,N,N, +19026,N,N,24372,N,N,N,N,22365,31290,28199,30013,N,30837,N,N,28008,N,N,N,N,N, +21601,N,20771,24918,N,N,N,N,N,N,N,N,N,N,N,N,N,31096,N,23370,19321,21588,N, +22876,N,28222,N,30573,N,N,N,21102,N,N,24934,30585,N,N,N,N,N,N,N,23917,N,26715, +N,23347,N,N,N,20855,24624,N,N,21602,N,30295,N,22393,N,N,22621,N,19837,29227,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19773,30786,N,N,29228,N,N,18989,18990,20270,N, +N,N,N,N,25410,N,N,N,N,N,23607,N,N,N,N,N,N,N,N,N,N,23386,22843,19059,30291, +26232,27253,N,N,N,N,N,27254,N,N,30329,N,N,N,N,N,N,N,N,N,N,N,20271,N,N,19027,N, +N,18991,21040,28986,N,22323,25411,29565,24154,N,N,N,N,24155,N,N,28510,25187, +28283,N,N,24439,22346,N,N,N,N,N,N,N,N,N,20072,23387,N,N,N,N,N,N,N,28987,N,N,N, +N,26993,N,N,N,N,N,N,N,N,31287,20550,N,N,19499,28200,N,N,19322,31097,19581, +21374,N,N,N,N,25680,N,N,N,N,N,29294,N,21589,24397,N,31800,20816,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29261,N,N,N,N,N,N,N,N,30546,N,N,N,N,N,N,N,N, +19028,N,21849,N,N,N,22622,N,N,N,N,N,N,N,N,N,19801,N,N,N,28201,30268,N,N,19547, +N,N,N,N,N,28745,N,31868,N,26697,29822,N,N,N,N,26492,22366,N,N,N,N,24156,N, +28716,19582,19809,N,24890,N,23407,23090,N,N,N,N,N,N,N,N,N,N,N,N,N,20773,23608, +N,N,N,22646,N,20772,N,19810,N,N,N,N,23658,N,N,28791,N,28746,20542,N,23900,N,N, +N,N,21590,21334,N,N,N,N,N,N,27984,19745,N,N,N,N,N,24373,N,N,N,24440,N,N,N,N,N, +N,21537,20018,26698,N,N,N,N,27509,N,N,N,N,N,N,N,25429,30032,N,N,N,29985,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22823,N,N,N,N,N,N,N,N,25899,N,N,N,N,N,N,N,N, +N,N,N,N,26187,N,30065,N,N,N,N,N,N,N,N,N,N,25925,N,N,N,N,N,N,N,N,31011,24667, +30315,N,19313,N,22890,29986,N,N,N,22353,N,20856,27256,27257,23091,N,N,N,N, +28511,N,N,29039,N,25974,28223,25188,N,N,N,N,N,20543,N,31276,30033,26419,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26942,N,N,N,N,N,29262,23348,N, +N,N,N,N,N,N,N,31822,N,23918,N,N,N,N,N,N,26420,N,N,N,N,N,22324,N,N,N,N,N,N, +30516,N,N,N,N,N,19774,N,23145,N,N,N,N,N,N,N,20272,30553,29542,N,N,20057,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20010,N,19272,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,20519,N,28747,N,20551,25669,N,N,N,N,N,N,N,23392,N,N,N,N,N,N,21850,N, +22311,N,N,N,28224,N,30838,N,N,N,N,30034,28009,N,22844,N,25926,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,29987,N,N,23124,25127,31612,N,N,29020,N,N,N,N,N,N,19060,N,N, +N,26746,N,N,20073,N,N,N,N,N,N,27000,25189,N,N,N,N,20537,21618,N,N,N,N,N,20774, +N,24398,N,N,N,N,N,N,N,N,N,31860,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21290, +N,N,N,19500,N,N,N,N,28512,N,N,N,25957,20565,N,N,N,N,N,N,N,N,23420,N,N,N,N, +31846,N,N,N,N,N,19326,28010,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24113,N,N,N,N,N,N,N, +31075,N,N,N,N,N,N,21538,20342,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22096,N,N,N,N,N,N, +21866,29038,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31307,N,N,N,N, +25889,21809,N,N,N,N,N,20333,N,28011,N,N,N,N,N,21810,N,N,N,21820,N,N,N,N,N,N,N, +N,N,32098,29485,N,32091,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26928,N,N,N,N,N,N,N,20775, +N,N,32099,20019,N,N,N,N,N,N,N,32100,31310,N,N,N,N,18992,N,30503,N,20273,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,26146,N,31798,29229,28513,29486,23622,22891,N,N,N,26720, +N,N,N,N,N,N,N,24872,N,N,N,N,21878,20349,N,N,24157,N,N,N,22865,N,N,N,25706, +29263,N,30527,N,N,25190,25128,N,N,N,N,N,N,N,N,N,N,N,25430,N,27985,N,N,N,N,N, +27001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22065,24114,N,N,24680,N,N,21291,N,27484,N, +N,24367,N,19011,N,N,28284,N,32067,N,N,N,27510,20274,N,N,N,N,22892,N,22845,N, +22623,N,N,21560,27454,23919,N,23920,23921,23922,N,N,22846,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,31558,20275,28285,N,N,N,N,N,N,25643,N,23109,N,22636,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,20776,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25129,N,N,24124,26421,N,N, +N,N,N,23408,N,28514,29040,20276,N,N,N,N,N,N,N,N,N,N,N,23409,N,24625,N,N,N,N, +24357,N,31058,N,N,26493,N,N,26147,31601,19248,29230,N,N,N,N,N,N,N,19815,N, +26716,N,N,26455,N,N,30528,N,20579,N,N,N,23073,N,N,N,19517,N,N,20777,23884,N,N, +25470,20778,26666,N,27190,31098,26188,30296,N,N,N,21575,N,N,N,22859,N,22866, +21323,22647,23081,30072,N,N,24158,29231,30761,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +22600,N,N,28225,N,N,N,N,31041,N,N,N,N,23923,27258,N,30269,24891,19775,29780, +26189,N,31823,31522,N,24668,N,N,N,N,29755,23125,N,31026,N,N,N,N,N,N,31602,N, +23414,N,24159,N,N,N,23410,N,N,N,N,N,30812,30574,27496,N,21114,N,N,28988,N,N, +31322,N,N,23146,23110,30529,N,N,26422,25927,22060,N,N,N,N,23623,N,N,N,N,N, +24873,N,25130,N,21798,N,N,21591,N,N,N,N,N,N,29264,N,27259,N,24669,31603,N,N,N, +N,N,N,N,28989,N,N,25191,32087,N,20040,27191,N,31808,N,32103,30575,N,N,22325,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28474,29021,N,24115,N,N,N,N,N,N, +26699,N,N,30813,N,N,31559,21832,N,22367,N,23849,N,N,N,N,N,26929,N,N,31277, +30297,31348,N,N,N,N,N,30762,N,N,N,N,N,26222,N,19548,24892,24687,N,N,26943, +31869,26190,N,N,24919,N,26191,N,29809,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,25715,N,N,25723,N,N,31076,N,N,N,N,N,N,N,N,N,N,28515,N,N,20334,30270, +24626,31870,20779,N,N,N,22394,N,N,N,31560,N,25175,N,N,N,N,N,N,21539,28792, +22312,N,N,N,24935,N,N,21311,N,N,N,N,N,N,28516,N,22341,27490,N,N,31847,N,N, +25634,N,25192,N,26192,N,31592,29800,25972,29756,29781,24374,N,31801,28226, +19061,N,N,N,28517,19298,21540,N,24160,23165,25670,26686,N,N,N,N,24670,30260, +27218,N,31099,N,N,24642,N,19044,N,26423,N,27261,N,22877,N,23092,28202,31593,N, +N,N,N,23371,23093,N,N,N,N,N,28990,N,N,21292,N,N,N,N,N,N,N,N,31561,N,24399,N,N, +21312,25431,N,28518,31824,N,N,N,N,N,N,N,26944,N,N,N,30035,N,N,27740,30519,N,N, +27192,20857,N,N,N,N,N,N,23624,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27193, +N,N,N,N,N,29022,N,N,N,N,N,22326,20277,N,22824,N,N,27758,N,N,23850,N,N,N,N, +19746,26670,N,N,N,24893,N,29265,N,N,N,N,26945,N,N,N,21116,N,N,N,N,N,N,N,23349, +N,29543,22654,N,N,N,31825,N,27954,29743,N,31523,N,N,31809,N,28203,21541,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29810,N,N,N,N,28249,N,N,N,31562, +N,N,N,N,N,19811,22587,25947,30839,N,N,N,30292,N,N,N,N,N,N,N,N,22313,N,19273,N, +N,26193,28748,N,N,N,N,N,N,N,N,N,N,22574,N,31059,21886,N,N,N,N,N,N,N,22588, +29232,N,N,N,N,25131,29544,N,N,N,N,N,28482,N,N,N,N,N,N,28012,N,26424,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,23166,N,N,19518,N,N,29308,23147,N,25176,27990,N,N,22097, +24627,N,N,31826,N,27464,N,N,N,N,N,N,N,N,21313,28749,N,20343,N,N,N,N,N,N,N,N,N, +27986,N,21592,23625,22385,N,N,24379,N,N,29477,N,N,N,29773,N,N,N,N,28991,30769, +N,27002,N,N,N,31563,N,N,19029,N,N,N,N,N,N,N,N,N,N,N,31060,30538,N,N,22088,N,N, +N,N,N,N,31848,29501,N,28286,N,26494,N,N,N,N,N,21314,N,N,N,N,21302,N,19501, +30330,22066,21080,N,N,N,N,N,N,26456,N,N,N,N,N,N,N,N,N,N,25381,N,N,N,N,26425,N, +N,N,N,28717,31564,27425,N,N,21542,N,N,N,N,31565,N,21821,29023,N,N,30331,N, +24116,N,N,N,N,N,N,N,N,N,N,N,N,21867,25928,N,N,N,31524,21561,N,N,24161,N,25635, +N,N,N,22327,N,30830,N,N,N,24117,N,N,22098,N,31061,26426,27477,21879,28519, +24894,N,N,N,31278,N,N,N,22121,22126,N,N,N,N,N,N,26427,N,N,N,N,N,N,N,27723,N,N, +N,N,N,N,21811,N,N,N,N,N,N,N,N,N,N,N,N,N,20020,N,N,N,31525,24942,N,N,N,N,N,N, +30504,N,N,N,N,31566,N,N,N,N,N,22589,N,N,N,N,N,N,N,31613,N,N,N,N,31849,N,N,N,N, +N,N,N,20278,N,N,N,27975,28204,N,N,N,N,N,N,N,19549,N,N,N,N,30247,N,N,N,26234,N, +N,N,29988,N,N,N,N,N,32092,27955,20041,N,N,N,N,N,N,28520,N,N,24895,N,N,N,N,N,N, +31323,19299,30505,N,31526,N,N,N,23609,N,N,N,28992,27976,28483,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,22061,N,N,32078,N,N,N,26657,N,N,N,N,N,N,N,N,31604,21799,N,N,N, +29046,N,26195,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19550,N,N,N,N,N,N,N,30770,N,N, +N,23659,32054,N,N,N,N,25962,N,N,29024,N,N,N,N,N,N,N,N,N,N,N,N,23372,23885,N,N, +N,21576,N,N,22893,N,N,N,N,29989,N,N,N,N,N,N,N,N,N,26235,N,N,N,N,N,26196,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,32072,N,22049,32063,N,31827,N,28449,N,26428,N,N,N,N, +N,20846,N,N,26197,N,N,26994,N,24368,N,N,N,N,N,22624,31802,32047,28750,N,23393, +N,N,25929,N,27956,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24643,N,N,N,N,N,N,25432,N,N,N,N, +27003,27176,N,N,N,N,32055,N,N,31527,N,26946,N,N,N,N,32119,N,N,N,N,N,25177,N,N, +23660,N,N,N,N,N,N,N,N,N,26658,N,N,N,N,26224,N,N,N,N,N,N,N,32120,32121,N,N,N, +30271,N,N,26407,N,26199,N,N,N,N,21619,21577,N,N,N,N,22138,N,22386,N,24896,N, +23394,26200,N,N,N,N,N,N,N,N,N,26429,N,N,N,N,N,28751,29502,25132,N,N,N,N,N, +30007,24688,N,N,N,N,N,N,N,N,N,N,N,N,32056,25448,N,21543,26748,31314,N,N,N,N,N, +30831,N,N,N,N,N,N,N,N,N,22099,N,N,N,N,N,N,N,N,N,N,21812,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,28752,N,30576,28211,N,N,27194,N,27219,N,N,27977,23851,N,N,N,25900,32033, +N,24400,27699,N,24401,N,N,N,N,N,28013,30776,30586,N,N,N,30763,N,N,N,N,N,29792, +N,N,N,N,N,21562,25651,N,26970,N,24118,N,22847,N,22848,22127,N,N,N,N,22860,N, +23082,N,N,N,N,N,N,N,N,24421,N,N,N,N,N,N,30565,N,N,N,19506,N,N,24441,22368,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21563,N,N,N,N, +32122,N,N,N,N,19507,N,N,23411,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24402,N,20042,N, +28250,N,N,N,N,N,N,N,N,N,25700,N,31567,N,N,N,N,N,N,20279,N,28227,N,N,N,N,N,N,N, +20074,N,N,N,N,N,N,N,25133,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22369,31349,N,N,21833, +30764,26457,N,N,N,N,N,N,N,N,N,N,N,29545,N,N,N,N,22637,25412,28785,N,N,N,N,N,N, +N,26725,N,N,N,24698,28228,22878,N,N,N,N,N,N,N,N,N,N,27426,27427,N,N,N,N,N,N, +31810,27195,N,N,N,N,26667,24162,N,N,N,N,N,N,N,N,N,N,28015,N,26659,N,N,N,N, +20337,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21564,N,31850,N,N,N,N,N,26430,N,31858,N, +N,22068,N,N,25134,N,21303,31308,N,N,N,N,N,N,N,N,31324,N,27957,24931,N,26668,N, +26717,N,N,28521,N,N,N,N,N,29757,N,20280,26971,20780,N,N,N,N,N,N,23111,N,N,N,N, +N,N,N,27465,N,26700,N,N,N,24119,N,N,N,N,22076,21349,N,N,N,N,N,31325,N,N,N,N,N, +N,23126,N,18993,N,N,N,N,N,N,23112,24358,N,31027,29266,N,19012,N,N,N,N,N,N, +20043,N,N,19829,N,N,N,32048,21800,N,28993,N,N,25193,23626,27700,31296,N,N, +31528,20520,N,N,23148,N,N,N,N,N,N,N,N,N,22894,N,24699,N,N,N,28522,31326,24644, +N,20281,N,21834,22370,25135,N,22328,N,N,N,N,N,N,N,N,N,26701,N,N,N,N,N,N,N, +30298,N,N,N,N,28450,25178,30332,N,N,31568,20781,N,19812,N,20782,23661,26702,N, +28793,20021,26236,N,N,22395,20566,23925,30577,N,30333,N,23415,N,N,N,N,31594, +26972,22849,N,30066,24645,N,N,N,N,N,N,27220,N,N,N,N,N,N,N,N,N,31042,N,27196,N, +21061,31569,26432,27429,N,24442,25378,22329,N,26947,N,26749,26671,N,N,29267, +31529,22565,N,N,N,N,21835,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20552,N,N,N,20783,22371, +N,N,N,24646,N,22050,N,28016,N,N,N,N,N,N,N,N,N,N,N,N,22387,N,N,N,31828,N,23127, +19551,N,29268,N,20784,N,19552,N,23421,29503,N,28753,N,N,N,N,N,31803,N,25136,N, +N,26149,N,N,N,25179,N,N,N,24414,N,24647,N,N,N,N,N,N,29295,N,N,N,19553,N,N,N,N, +22122,N,N,N,N,26434,N,N,N,20022,N,29504,N,19838,N,N,N,31570,N,30840,30587,N,N, +26687,N,N,N,N,N,N,N,26679,N,N,N,N,N,N,N,N,27958,23610,N,N,19508,N,N,N,N,N,N,N, +N,N,N,N,N,29047,N,N,N,26680,N,N,19062,N,25636,29782,N,N,N,24422,N,N,N,24359,N, +24423,24897,N,26948,N,N,23627,26949,N,N,N,28451,27430,19235,25449,N,N,N,20859, +28452,N,28523,N,N,N,N,N,N,N,N,N,N,N,N,20532,N,N,N,N,19747,N,N,26726,N,28453,N, +21324,23149,N,N,N,N,22330,N,29269,30053,22895,N,N,N,N,31028,N,N,21844,32079,N, +N,N,23395,N,N,N,N,29025,27702,N,N,N,N,31614,21335,N,20785,N,19249,N,N,N,N, +20786,N,N,N,N,N,N,19250,28994,N,N,29793,31029,N,N,24899,24898,N,27511,N,N,N,N, +N,N,N,N,N,N,N,24360,N,N,N,N,N,N,N,19274,N,N,N,N,N,26169,N,N,N,N,N,30814,31018, +19063,N,27959,N,N,21304,29270,N,N,21593,28229,29296,N,N,N,18994,N,N,23611,N, +29048,N,N,N,N,N,27703,N,N,N,N,25930,N,30272,32093,N,N,21603,19554,N,30548,N,N, +N,N,N,N,22373,N,N,N,N,N,N,N,N,N,N,N,N,N,21315,N,22566,N,30273,N,N,N,N,N,23926, +N,19776,25948,N,N,N,N,N,N,N,N,N,N,N,N,25931,N,N,N,N,N,N,N,N,N,N,N,24900,N,N,N, +N,N,26672,29744,29546,23150,N,22331,N,25137,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,22314,N,N,N,N,N,N,22139,N,N,N,N,N,N,N,N,N,25695,N,19030,N,N,N,27432,N,N, +N,23422,N,N,N,N,N,N,N,N,N,N,30274,N,N,28475,N,N,N,N,21629,N,N,24648,N,N,N, +26681,N,28454,N,N,N,N,N,19748,N,N,21620,23329,23388,23389,N,N,N,N,N,28252,N, +19275,31829,N,N,N,N,N,N,20075,N,19777,N,N,31571,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,31019,N,N,N,N,N,N,N,N,N,N,N,30036,N,N,N,N,22825,N,N, +26973,23373,N,N,23886,N,26435,N,27724,N,N,N,N,N,N,N,31084,N,N,N,19276,N,N,N,N, +24700,21544,N,27987,22639,N,29271,N,19064,23151,N,N,22100,N,N,N,N,N,N,22861,N, +N,N,22638,N,29249,N,N,N,24403,N,N,N,23152,N,25194,24701,N,N,22648,N,N,N,30511, +23094,N,19031,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29272,N,22649,N,N,N,N,N,N,N, +N,31327,N,N,N,N,N,N,N,N,N,N,N,N,N,20335,22850,N,28754,N,25681,N,N,N,29495,N,N, +N,N,N,N,N,N,N,N,N,N,31328,N,N,N,N,N,N,N,N,N,N,N,N,N,28524,N,N,N,N,N,25138,N, +21565,N,N,22862,N,N,N,N,29794,N,N,N,N,N,N,N,N,N,N,N,N,N,21545,N,N,N,N,19778, +26458,N,N,N,N,N,N,N,N,N,N,N,29273,N,N,N,N,N,22826,N,N,N,N,N,N,N,N,N,N,N,N, +22590,N,N,N,N,N,N,23597,N,N,N,N,N,N,25195,22140,N,N,19065,N,N,21594,N,N,N,N,N, +N,N,29783,19489,N,N,20282,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30008, +N,N,N,22851,20584,N,N,N,N,N,25413,27512,N,29233,N,N,N,20283,N,N,N,21293,26721, +20076,N,N,N,24628,24163,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23927,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,29234,29558,30299,N,N,N,N,22398,N,N,N,N,N,30815,N,30578,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,20521,N,N,N,N,N,N,N,N,N,26202,N,N,N,N,N,N,N,N,N,N, +N,N,N,29990,N,N,N,N,N,N,N,N,N,N,N,N,N,22332,19555,N,N,26203,N,N,N,N,N,N,N,N,N, +N,N,N,23901,N,N,N,N,20787,N,N,N,N,N,28525,N,N,N,N,22110,25716,24943,N,N,23928, +N,N,N,N,N,26703,N,N,N,N,N,N,N,N,N,N,N,19045,N,N,N,23585,N,24629,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,31788,31789,22567,N,N,N,N,27960,N,N,N,23350,N,N,N,N,22128, +29487,N,N,19749,N,23153,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22568,N, +N,N,19556,N,N,20788,N,N,N,N,N,19032,N,N,N,N,N,23154,29991,N,N,N,N,N,N,N,N,N,N, +N,N,29992,N,N,N,N,N,N,N,26150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21868, +21880,23155,N,N,N,N,N,N,N,N,N,N,N,N,N,25414,N,N,N,24164,N,24165,20789,N,N,N,N, +N,20790,20791,29235,N,N,N,N,N,N,26974,N,N,N,N,N,28755,29236,N,N,28756,19300, +31572,30054,25450,N,24166,N,N,N,N,24404,N,N,30841,N,N,N,N,28718,N,N,N,N,N,N,N, +N,N,N,N,N,20792,N,N,N,N,22111,N,20567,N,N,N,N,N,N,N,N,N,N,N,31777,28526,23640, +N,26975,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25949,32123,N,N,24649,N,N,N, +22089,N,N,21546,N,25932,N,N,N,N,N,26976,N,N,N,20568,31778,21566,25139,24167,N, +N,N,N,N,N,N,23612,21046,30037,N,N,N,N,N,20001,29993,N,N,23929,N,N,23930,N,N,N, +N,N,N,28757,N,N,N,N,30303,N,29274,25707,N,29297,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,27705,32124,N,N,N,N,24874,N,N,19033,N,N,28527,N,29994,N,N,N,N,N,N,27769,N, +N,30765,N,29250,30275,N,22354,N,N,31010,28758,N,N,N,N,N,N,N,N,N,N,N,N,N,28794, +N,N,30304,N,N,N,N,26995,29251,N,N,N,21547,18995,19750,N,19779,19802,N,N,N,N,N, +22863,N,N,30276,N,N,N,28253,26436,N,N,N,N,N,N,N,N,25140,N,N,N,N,N,N,N,N,N, +24418,26459,N,N,N,N,N,N,26673,N,31790,N,N,N,N,25933,N,N,N,31339,N,20284,N,N, +20322,19830,N,N,28528,N,29758,N,21581,N,N,29496,N,N,N,26913,N,N,N,N,N,N,N,N,N, +29298,29547,N,28759,N,N,20311,N,N,N,N,N,N,20319,N,N,N,N,N,N,N,N,N,26688,26689, +N,N,N,20323,26914,N,N,N,N,N,N,N,N,N,N,20522,N,N,N,N,N,N,N,N,N,29505,20523,N, +21604,N,N,28476,22561,N,N,N,N,N,N,N,N,N,N,N,22879,N,29527,N,N,N,23613,N,19557, +28017,N,N,29026,N,21595,N,N,N,N,25141,N,N,19046,N,21294,N,N,N,N,N,N,19558,N,N, +29011,30055,N,N,N,N,19034,31598,N,24901,N,N,N,N,N,N,N,24425,N,28254,N,N,30530, +N,22562,N,N,N,N,N,23852,N,N,N,N,N,28719,22077,N,N,N,N,N,N,N,N,N,N,N,24875,N,N, +N,N,N,N,N,N,N,N,N,N,31030,N,N,21621,N,20553,28455,25196,N,23402,20044,30056, +30549,N,21325,N,29566,N,N,N,N,N,N,N,N,N,20533,N,N,N,N,N,N,N,N,N,N,N,24702,N, +24443,N,N,N,N,N,N,26205,N,N,N,N,N,N,N,26660,N,N,N,N,N,N,N,N,N,19277,N,N,N, +28456,N,N,N,28212,N,N,N,N,23128,20793,N,24361,N,N,29488,N,N,19524,N,N,N,20023, +N,N,N,N,N,N,N,N,N,N,N,28457,N,N,N,24405,N,N,27991,N,N,N,28230,N,N,N,N,N,N,N, +28477,31830,N,N,23412,N,28458,30777,N,30057,N,N,N,N,N,N,N,N,25433,N,N,N,N,N,N, +N,N,N,N,N,N,N,24902,N,N,N,21567,N,N,N,N,24168,28778,N,N,N,N,N,N,N,N,N,N,29506, +N,N,N,N,N,N,N,N,N,N,N,21295,N,N,19035,N,N,N,N,N,31831,N,N,27992,24903,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,29784,22067,23853,N,N,N,21822,N,N,N,N,N,N,N,N,28995, +28255,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22123,N,N,N,29785,N,N,N,N,N,N,N, +22374,N,N,N,N,N,N,23095,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23931,N,N,N,N,N,23887,N, +N,N,N,N,N,N,N,22563,N,N,23129,N,28760,28484,N,N,N,N,N,N,24920,N,N,N,N,N,29012, +N,28018,N,N,N,N,N,N,21851,N,N,21852,29508,19287,N,N,N,N,N,25142,N,N,N,N,28529, +N,N,N,N,N,N,N,N,N,N,N,31573,N,N,N,N,N,N,N,N,N,N,N,21336,N,N,N,N,N,N,N,23888, +28761,19251,N,N,N,N,N,N,21853,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19751,N,N, +20524,20794,N,28996,N,25907,31605,26977,32096,31804,N,23074,23075,N,21025,N,N, +21103,N,N,N,25197,N,N,24169,20060,29237,20580,23889,N,N,N,N,24904,23351,24419, +N,N,N,N,N,N,N,N,27961,28997,N,29519,22315,24876,N,N,25451,N,28231,N,N,N,24905, +19066,N,N,N,N,N,N,N,28795,31329,28762,19559,23156,N,N,N,N,N,N,N,N,N,19519,N,N, +N,N,N,N,N,N,N,N,N,N,N,20077,N,N,21801,31330,N,N,N,20581,N,27478,N,27743,N,N,N, +24444,N,N,30550,24170,19252,N,N,28478,N,N,19509,N,N,N,N,N,20285,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,28530,25143,N,N,N,19560,N,N,N,N,N,N,N,N,28796,N,N,N,22112,N, +28998,N,N,N,N,N,N,N,N,N,25144,27435,N,N,N,19253,22609,N,29774,29559,N,N,22342, +N,20795,30506,N,27978,22355,22650,N,N,N,N,N,N,N,30277,N,N,20812,23932,N,N,N,N, +N,N,N,N,N,N,24445,N,31077,N,24650,N,N,29309,21296,N,29811,23113,N,26206,N,N,N, +N,30778,26704,N,N,22651,N,N,27221,N,N,N,N,22051,N,N,N,N,N,N,30278,29275,25724, +N,N,N,N,N,N,N,N,N,N,26674,N,N,N,N,N,23130,N,29276,31574,26930,N,28205,N,31331, +N,N,N,N,N,N,N,23662,N,N,30058,26208,N,28797,N,N,N,N,N,22316,N,N,N,N,N,30021, +28256,N,N,23397,N,23902,N,N,22896,26915,N,N,N,N,N,N,N,N,N,N,29049,N,29252, +24651,N,N,N,N,N,N,N,N,26916,N,N,25145,N,N,N,N,N,N,N,25393,31851,19752,N,19510, +N,N,28763,N,N,N,N,N,N,N,N,26170,N,N,19753,N,N,N,N,N,29507,N,N,N,N,N,N,N,N,N, +24921,N,N,28459,N,N,N,26437,N,N,24681,N,29509,N,N,21568,21823,23854,N,31100,N, +19520,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25890,N,N,N,20024,N,N,N,22610,31062,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28970,20049,N,N,30279,N,23403,N,24446,N, +N,22625,N,30579,N,22375,N,N,N,N,N,N,N,N,N,N,N,21630,N,N,20796,N,25935,N,19254, +N,23096,N,N,N,N,N,19780,N,N,N,N,N,22078,N,N,N,25146,N,N,N,N,N,20312,N,N,N, +24652,27513,N,N,N,N,N,N,N,N,32125,N,N,N,N,N,22376,19288,N,N,N,26978,N,N,N, +26682,N,N,N,25415,N,N,N,N,27725,N,27726,N,22079,N,N,N,25383,N,24406,32104,N,N, +N,N,N,N,N,N,N,28257,30248,23933,N,N,N,N,N,N,N,30779,N,26705,N,N,N,N,31063,N,N, +N,N,N,N,N,N,20078,N,N,27727,26917,22101,N,19781,N,27962,20797,N,N,20286,N,N, +27707,N,N,N,21041,N,N,N,N,19561,N,22852,27004,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,20798,N,N,N,N,N,27708,N,N,25901,N,N,N,N,N,N,30512,N,19562,N,N,N,21316, +N,N,22080,N,N,N,22141,N,N,N,N,N,N,N,N,N,N,N,24865,N,24125,N,30249,N,N,N,23076, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22052,30022,N,24866,26950,N,N,N,29253,N,N,N,N, +N,29801,22124,27475,N,N,N,N,27709,25180,24171,28764,N,27455,N,22350,20799,N,N, +N,N,N,N,N,N,N,29995,N,N,N,N,31101,N,19036,N,N,N,19782,29238,N,N,23934,N,N,N, +19511,23352,N,N,N,N,20585,N,20061,27456,N,32034,N,N,N,N,N,30795,N,N,N,N,N,N,N, +N,27222,28976,N,N,N,N,N,N,N,23374,N,30531,N,N,N,N,N,N,N,N,N,N,N,23375,19236,N, +N,30816,N,N,31575,N,N,27466,24609,N,N,N,N,N,N,N,N,N,N,N,20045,N,N,21596,N,N,N, +32088,N,N,N,N,21110,29239,N,N,31350,30250,31351,22630,N,29745,N,N,N,N,N,N,N,N, +N,N,N,N,N,26706,N,19013,19563,N,N,N,N,N,N,N,25198,N,N,N,N,N,25147,N,30509,N,N, +N,30817,N,N,N,N,N,N,N,N,N,29548,N,N,N,N,24097,N,N,N,N,N,N,N,N,N,N,N,N,25725,N, +N,25452,N,23855,23856,N,N,19255,26707,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24867, +21088,N,N,N,N,28798,N,N,N,N,26918,19314,N,N,N,N,N,N,28019,23641,24653,N,N,N,N, +30554,23353,N,N,N,N,N,N,N,19502,N,23131,N,N,N,N,19783,N,N,N,N,N,N,N,N,N,N, +23857,N,22575,25379,N,N,20079,N,N,29299,N,N,N,N,30771,N,N,N,N,N,N,N,N,N,N, +24654,N,30077,N,N,N,N,27500,N,N,21317,31852,21083,21611,N,24098,N,N,N,25958,N, +N,N,N,N,N,28720,N,N,N,N,N,N,N,N,N,N,21828,N,N,N,N,N,N,28020,N,N,N,25453,N, +26690,N,28021,22396,N,27963,N,N,30251,N,N,N,N,N,29240,30280,N,N,N,N,N,21350, +29277,20287,N,27436,20288,N,26152,32105,N,20289,N,24671,24172,N,N,N,N,24610,N, +N,N,N,N,N,N,N,29759,25199,N,22897,28999,N,19256,N,N,N,N,N,N,N,N,31102,23354, +23157,N,N,N,N,N,N,N,N,30316,23132,31332,N,24655,N,N,N,N,N,N,23858,N,N,N,N, +26153,N,28531,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29549,N,N,N,N,N,N,N,N,N,N, +27514,N,31078,N,N,N,N,N,N,N,19037,21854,N,19038,24420,N,N,N,26237,N,29996,N,N, +N,N,N,25717,N,N,N,N,N,N,N,N,N,N,N,N,26979,N,27979,20324,N,N,N,22611,N,N,N,N,N, +N,23859,21612,N,N,29241,N,24375,N,N,N,N,N,19278,31576,N,N,20569,N,N,23890, +30580,26460,25637,N,31779,N,23355,N,N,N,29242,27005,20554,N,30038,22853,25652, +N,27943,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27197,26238,N,30532,29997,N,22880,N, +N,N,18996,N,N,30818,20290,N,27710,N,N,N,25908,19784,28232,N,N,N,N,N,N,N,N,N, +26440,N,N,N,N,N,N,N,N,N,N,N,19785,31031,29032,22898,23413,18997,22854,N,N,N, +22601,N,N,N,N,N,N,N,N,N,N,N,N,N,22827,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27964,N, +N,22612,N,N,N,23642,N,25148,N,N,31853,27744,21118,N,26951,26154,N,N,N,N,N,N, +25200,N,N,N,N,N,N,31291,N,29998,31530,N,N,N,N,27771,N,27711,31832,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21605,N,N,N,31043,N,N,N, +28258,N,N,N,N,N,N,N,N,N,N,N,N,N,22377,28022,N,N,N,24173,N,N,N,N,N,N,N,19564,N, +25454,N,N,N,N,N,26708,N,N,N,31352,N,N,N,N,N,N,23860,25653,22576,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,22613,N,N,N,29802,N,N,N,20025,N,N,N,22113,20306,N,20534,N, +N,N,N,N,N,20002,N,N,29550,N,N,N,N,N,29560,N,N,N,N,N,N,N,N,N,N,N,N,23628,N, +20555,N,N,N,31780,19786,22356,24099,N,25696,N,N,N,N,28233,N,N,N,25181,30078, +21548,N,N,N,N,N,21841,N,22640,30787,27223,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,30039,N,N,22591,N,N,N,N,32064,N,N,N,N,N,N,27437,N,N,N,N,21802, +N,N,N,N,N,N,N,N,N,N,N,26408,N,N,N,N,N,N,N,N,N,N,N,N,N,28234,N,N,N,19047,N,N,N, +N,N,30819,N,21597,N,N,27224,N,N,N,N,31577,28023,N,N,25909,N,N,N,N,N,20525,N,N, +N,N,29041,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25149,N,N,N,25416,N,N,N,N, +22869,N,N,24362,N,N,N,N,23356,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30820,N,N,N,N,N, +29050,N,N,25910,29551,N,N,31578,24928,N,22828,N,30059,N,24630,N,N,26952,N, +19279,N,25417,N,N,N,24174,N,N,N,N,N,N,N,N,25150,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,23663,N,22053,N,N,N,N,N,25201,N,N,N,N,N,N,N,22142,22817,N,22592,23643,N,N, +27965,24376,N,27173,N,N,N,22317,N,N,29561,N,28024,N,30023,N,N,N,N,N,N,24906, +27491,N,29278,N,N,N,N,N,N,N,N,N,N,N,N,N,30796,N,27225,N,21318,N,23398,N,N,N,N, +N,29999,N,N,N,N,20080,N,N,N,N,27006,N,N,N,N,N,31542,N,N,N,N,N,N,N,N,N,25202,N, +N,N,N,20338,30521,22899,N,N,24907,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +23133,N,N,23097,N,N,N,N,N,N,N,27515,N,19257,N,N,28025,N,N,N,N,N,N,24672,N,N,N, +N,N,N,N,N,N,N,29760,N,32060,24369,25455,N,N,N,N,24611,32057,N,N,N,N,N,N,N,N,N, +28721,N,N,N,N,N,N,19787,N,N,N,N,N,N,N,27966,N,N,N,21824,25456,28026,N,N,N,N,N, +26980,N,N,N,N,N,N,21869,26461,N,N,N,N,N,N,21622,25911,N,N,N,23399,25151,N,N,N, +N,N,N,N,N,N,N,N,N,28235,N,N,22388,28765,N,N,N,20011,26462,N,N,N,22102,24908,N, +N,26675,N,N,N,N,N,N,N,N,N,N,N,25966,23586,N,N,24656,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,21813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21793,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,31579,N,31051,N,N,N,19315,29733,N,N,N,N,N,31304,22103,N,26981,31580,N,N, +N,N,N,N,N,32080,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31606,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,23077,N,23357,N,N,N,N,N,N,27746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19831, +28766,N,N,N,N,30281,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +24175,N,N,N,21297,N,N,N,N,N,N,N,N,31854,N,N,N,N,26691,N,29000,N,N,N,20081,N,N, +N,N,31085,N,N,N,N,N,N,N,N,29300,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25654,30009,N, +23664,25457,N,N,N,N,26661,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29243,N,24100,N,23116, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,19049,N,N,N,N,N,N,25434,N,31833,N,N,N,N,N,N,N,27226,N,N,N, +N,N,N,31044,N,25380,N,N,N,N,N,N,N,N,N,N,N,31581,N,28490,N,26692,N,N,N,N,N,N,N, +N,N,21836,N,N,N,N,N,N,N,N,N,N,27479,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22829,N, +N,31531,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21337,N,N,N,N,N,N,21794,N,N,N,N,N,N,N, +N,N,30302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,23158,N,N,N,N, +N,N,N,N,N,N,N,24657,N,N,26920,N,N,30073,N,N,N,N,N,N,31279,N,27516,N,N,24682, +25394,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,21829,N,N,29027,21870, +N,N,N,N,N,N,N,N,N,N,N,N,N,19788,N,N,N,N,27993,N,N,N,N,22593,N,N,N,N,31340,N,N, +N,N,N,29035,N,N,N,N,N,31292,26210,N,N,N,N,31333,25210,N,N,N,18998,N,25655,N, +27227,N,30074,N,N,N,31532,20291,27517,N,N,N,N,30842,N,N,24377,N,N,N,N,24945,N, +21028,N,N,N,N,30075,N,N,N,N,N,N,20570,20571,N,27198,22833,N,N,N,N,N,18999,N,N, +21351,N,30821,N,N,N,N,21298,N,N,N,25152,29279,N,N,N,N,N,N,19813,N,N,N,N,N,N,N, +N,N,N,N,N,31020,N,N,N,N,N,N,N,N,19789,N,N,N,N,N,N,N,N,N,N,N,N,28206,22062,N,N, +N,N,N,N,N,N,N,N,N,N,22378,N,N,N,N,26464,27438,N,N,N,20313,N,N,23629,28027,N, +24176,N,22379,N,N,N,N,N,N,24101,N,N,N,N,N,N,N,N,N,N,24407,23376,23377,N,N, +21795,N,N,N,N,28722,23644,N,N,N,N,N,N,N,N,19048,N,30822,23630,N,N,N,N,27228, +23378,N,N,N,N,N,N,N,N,N,N,N,26931,N,N,N,N,30555,N,N,N,N,N,N,N,N,N,N,N,25384,N, +22318,N,N,24673,N,N,N,N,N,19258,N,N,25937,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,20572,N,N,N,N,21825,N,N,N,N,N,22602,N,N,N,N,N,N,N,25385,N,N,N, +N,N,N,N,N,N,N,N,N,24612,N,26921,N,21319,N,N,23645,30766,N,N,N,19512,N,N,N, +20526,N,N,N,22642,N,N,25418,N,N,N,N,N,N,N,N,N,N,19503,N,N,N,N,N,N,N,21549, +30289,N,N,N,N,N,N,N,20556,N,N,N,N,N,N,N,19014,N,N,21826,N,N,20026,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,19015,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31280,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,24408,N,N,N,30010,25963,N,28532,23861,N,N,N,N,19754,N, +25458,N,31607,N,30544,N,N,N,N,32058,N,N,32097,30334,20800,N,N,26693,N,25656,N, +24936,N,N,N,19521,N,21101,N,N,N,N,23358,N,N,24674,N,N,N,31305,N,N,24909,N, +19000,N,N,N,29280,29001,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24177,N,N,N, +28767,30788,N,N,N,N,N,28236,N,N,24178,N,26441,N,25203,26465,N,N,25419,N,N, +25420,N,N,N,20344,28460,N,32126,31781,31281,24409,N,24658,N,N,N,29786,N,N,N,N, +N,N,N,N,N,N,N,29002,N,20003,N,N,N,N,29244,27747,N,N,N,N,N,24613,N,30507,N,N, +27439,N,N,N,N,N,25950,N,24868,19755,N,22900,26662,19790,24937,N,31855,N,24675, +N,N,N,N,N,25153,N,20004,N,N,N,N,N,N,24102,N,N,27518,N,27485,28768,N,N,29787,N, +25204,N,N,21320,N,N,N,29803,N,28213,N,30040,N,N,21855,N,N,N,22117,N,N,N,N, +27440,29795,N,N,N,N,25421,N,N,N,N,29812,31282,N,N,28533,19039,N,27441,27967,N, +N,32073,N,N,N,N,25638,31012,28723,N,25964,N,N,N,20839,22855,25687,27229,N, +21623,N,N,N,N,N,N,N,N,N,23098,N,23117,N,N,N,31052,N,24922,23359,N,19525,27728, +19259,N,24179,N,N,26922,N,N,N,N,N,N,N,22856,N,N,28259,22333,N,N,N,N,N,N,20292, +N,N,N,N,N,20557,N,N,N,N,N,N,N,31782,N,N,N,N,N,N,N,29051,N,N,N,N,32082,20801,N, +N,N,N,N,N,N,N,25435,N,21321,N,23631,N,N,N,N,N,N,N,N,N,19565,N,N,N,N,N,24103,N, +N,26171,27681,N,N,N,19513,N,N,31582,N,N,N,N,N,26466,N,N,21569,N,N,N,N,N,N,N,N, +N,23592,N,N,N,N,N,25154,N,29528,25939,N,N,29529,N,N,N,29510,19803,N,N,N,N,N,N, +N,19756,N,31811,N,N,N,N,21607,N,20802,N,31013,N,26709,N,N,N,N,N,N,N,N,25422,N, +N,N,N,21578,N,N,N,N,N,N,24410,N,N,N,N,N,N,N,N,31583,26467,N,N,N,N,N,N,N,N,N,N, +N,N,N,30843,25423,N,N,N,N,N,N,N,30000,N,N,N,N,N,N,N,22631,N,22857,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,30767,28534,N,23862,28207,19832,N,N,N,N,24120,31783,30588, +30513,20027,29729,N,N,28237,24878,N,N,27715,20350,N,30783,22626,21352,N,N, +24104,29796,27714,N,22901,31045,23891,22129,27772,31856,N,N,27968,19001,N, +28260,N,N,N,N,N,N,29281,N,24121,N,N,N,N,N,N,22130,N,24180,N,24411,N,23379,N, +31335,22627,29761,N,23863,N,N,N,29301,N,N,21550,N,N,N,N,N,N,22131,N,N,N,N,N,N, +23864,20293,24415,29246,30241,N,27467,29052,N,29511,N,N,24683,N,N,N,N,N,28028, +N,N,24923,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,28261,N,24181,N,N,N,N,31315,N,N,N,N,29003,N,N,20527,23865,N,N,20803,N, +N,N,N,N,N,N,N,N,N,N,N,N,30001,N,N,N,N,27206,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28769, +N,N,N,N,N,N,N,N,N,30252,N,N,N,N,30041,N,N,N,N,N,N,N,N,N,N,28779,N,N,N,N,N,N, +23866,N,N,N,29247,N,N,N,N,N,N,N,30533,N,N,N,N,23330,29302,N,N,19002,N,N,N,N,N, +N,N,N,N,N,N,30581,N,19301,N,N,N,28262,N,24659,N,N,N,N,20005,N,N,N,N,N,N,22104, +N,N,N,21551,26953,N,N,N,N,21326,29762,N,N,N,N,N,N,N,N,N,N,N,N,N,19302,N,N,N,N, +N,N,N,N,N,N,N,28961,N,N,N,N,N,27442,N,N,N,N,28962,N,N,N,N,N,N,N,N,N,N,N,N, +27443,N,28724,N,N,19316,21552,29490,31543,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30060,N, +N,N,N,N,28263,29746,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30061,N,20339,N,N,N, +N,N,N,N,N,N,N,28770,N,N,N,N,N,28238,N,N,29004,N,N,25912,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22389,25459,20325,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,20294,N,N,N,N,N,N,N,N,N,29491,25688,20345,20314,N,N,N,N,31309,N,N, +N,N,N,N,N,N,N,N,N,N,26211,N,N,N,N,N,N,N,N,N,N,N,29282,N,N,N,N,N,N,N,N,N,N,N,N, +30062,N,N,19003,N,N,25436,20082,N,22105,N,N,N,28208,N,N,N,N,N,N,N,N,29797, +22594,23632,19566,N,N,N,N,N,21856,30282,32074,22614,29775,N,N,N,N,N,N,22054, +23614,N,23380,22343,N,N,N,N,29310,N,N,N,29005,N,N,N,N,25155,23646,N,23647,N,N, +28461,26155,N,N,N,N,31069,27199,N,N,N,28462,N,N,N,29776,20083,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,26156,N,20062,N,N,21881,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25460, +19792,N,N,N,N,N,N,21816,N,N,30589,N,23593,N,N,N,N,24182,N,23594,29283,26932, +21084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26982,N,N,25462,N,N,N,N,N,N,N,N,26442,N,N, +20558,N,N,23159,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19004,N,N,N,28264,23134,N, +29303,N,N,25211,N,19494,N,N,N,N,23099,N,28265,N,N,N,30042,30556,24938,20033, +21553,N,32049,26173,N,31533,N,N,30823,N,24910,N,30562,30063,20295,N,N,21554, +19567,N,21608,N,28239,30551,N,N,24614,22081,24924,28771,29028,23665,22055,N,N, +N,N,N,N,N,N,N,N,29813,N,N,29006,29284,N,N,20528,N,N,27759,N,N,N,31034,N,27445, +N,N,21613,25156,N,N,N,N,26983,N,N,27444,27169,N,30780,20006,N,31046,31834,N, +21555,21305,27230,N,N,N,26923,N,N,24929,21327,29814,N,27200,24911,N,19514,N,N, +N,N,N,28266,N,N,N,28772,29492,21614,N,N,29248,N,N,29029,N,29763,24660,N,27446, +N,22305,19304,N,31021,26925,22628,31283,25157,31805,N,N,27716,22577,N,23595,N, +N,N,N,21796,N,27497,N,N,N,26683,N,N,N,22615,N,N,N,N,N,N,N,N,31534,20833,N,N, +23360,N,30014,N,24183,N,N,N,N,19067,30534,20296,N,N,N,24912,N,N,28240,N,N,N,N, +N,N,N,N,26996,N,N,N,N,N,N,N,N,20084,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +21837,N,N,20315,N,N,N,N,N,N,23867,N,N,N,N,20012,N,N,N,N,N,N,N,26984,N,N,N,N,N, +N,N,21556,25671,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,30043,N,N,31297,N,N,N,24105,N,N, +N,N,N,N,N,N,N,N,N,N,N,21624,N,N,N,N,N,28535,N,N,N,N,21299,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,27447,28536,30044,27980,23381,29007,N,N,N,29008,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,30002,N,N,N,N,N,N,22830,21804,N,25158,N,N,N,N,N,N,N,N, +32035,N,31589,24363,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25205,N,30253,N,30003,N,28725, +N,N,N,N,24869,N,N,N,N,N,N,N,N,N,30045,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27682,28029, +N,30004,31544,N,23331,N,N,22090,19289,N,N,N,N,N,N,N,N,N,N,25940,N,N,N,N,N,N, +29562,N,27448,N,24631,22380,29036,25903,21857,22381,20817,N,N,N,N,N,24946, +28537,N,N,N,23868,30300,N,N,N,N,N,28773,N,N,N,29764,N,N,26985,N,N,N,N,N,N,N,N, +N,N,29563,21615,N,N,19490,30590,24380,N,N,N,N,27469,N,N,N,N,N,N,20535,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22082,N,N,N,N,N,26669,N,N,N,N,28463,19237,N, +N,N,N,19305,N,N,N,31336,N,N,N,N,N,N,N,N,N,N,N,N,N,19526,N,N,N,26215,N,N,27207, +N,N,N,23332,N,20297,25212,28538,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,27486,N,N,30024,N,21598,N,N,N,N,N,N,N,N,N,N,N,24661,N,28464,N,N,25159,N, +22831,N,N,N,31079,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26469,N,N,20298, +24913,N,25160,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28539,N,N,31353,N,N,23666,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,24615,N,N,N,N,N,30824,N,N,N,N,N,N,N,N,N,N,N,N, +N,19306,N,N,N,19260,22114,N,N,N,N,N,N,N,N,N,N,N,30046,N,N,N,N,N,N,N,30047,N, +28214,N,N,N,25206,21322,28540,20804,28465,N,20805,N,20574,N,22881,N,N,24632,N, +N,19793,29497,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,26444,N,22056, +20007,N,21557,N,N,N,N,N,N,25672,N,N,N,N,N,N,21300,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,27449,N,N,N,N,N,N,19317,N,N,N,N,N,N,30301,N,28963,N,N,N,N,N,N,N,N,N,N, +N,N,N,19527,N,N,N,N,N,N,N,26954,N,24944,N,N,N,30048,N,N,N,N,N,N,N,N,31535,N,N, +N,19281,N,N,N,N,31584,29285,N,N,27760,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +28780,N,N,N,N,N,N,N,N,N,N,N,N,N,28267,N,N,N,N,N,N,N,N,N,N,N,N,26955,N,N,19568, +N,N,22319,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29473,31861,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,28964,N,N,N,N,N,N,N,N,N,N,N,N,24662,N,N,N,N,N,28466,N,N,N,N,N, +N,N,N,N,29777,N,N,30497,N,N,N,N,N,N,N,N,N,N,N,29009,N,N,N,N,N,N,N,N,N,N,N,N, +19068,19069,N,N,N,N,N,N,N,N,20046,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,29512,N,29498,28030,N,N,N,N,N,N,N,N,23078,N,N,24684,N,N, +N,N,N,30797,N,19282,N,N,N,27470,N,31064,31065,19040,23114,N,N,N,19238,N,N,N,N, +N,N,N,N,N,N,19016,31086,23404,N,N,20529,N,N,N,N,21871,N,N,N,26227,N,N,N,N,N,N, +N,N,N,26402,25689,N,N,N,N,N,N,N,N,N,N,25697,N,N,31812,N,N,N,N,N,N,N,N,N,31087, +20340,30566,N,N,N,N,N,20028,N,N,N,N,29765,23587,23869,N,N,N,N,29766,N,N,N,N,N, +N,N,N,30753,N,N,N,26710,N,N,N,23361,N,N,N,N,N,N,N,N,28774,N,N,N,25657,30317,N, +31022,N,23870,N,N,N,N,N,N,22320,22632,19261,N,N,31066,N,N,N,N,N,N,N,N,N,N, +30798,31088,24685,25395,29747,N,N,27202,29286,28726,N,N,N,N,N,23382,N,N,N,N,N, +27492,N,N,29287,N,22357,21558,31080,22337,N,N,N,N,25941,N,N,N,N,N,N,N,26986, +22348,N,N,N,21353,25161,N,31835,19757,N,N,N,N,N,19504,27170,N,N,25718,20544,N, +28727,28193,N,N,N,N,N,N,22390,N,N,N,25162,25163,N,31311,N,N,N,N,N,N,27487,N,N, +N,N,N,22091,N,N,N,29748,N,N,N,N,27981,25682,N,N,27177,25658,29474,19794,N, +30283,N,29030,27969,26684,28241,N,N,N,N,N,N,28775,25164,N,N,25642,N,30049, +27994,N,N,N,N,N,22382,20849,N,N,N,N,26987,26988,24676,N,N,N,N,23079,23892,N, +27171,N,N,N,22083,22132,N,23135,N,28467,25165,N,N,N,N,N,28541,29288,N,N,N,N,N, +N,N,N,N,28485,N,26471,N,N,22397,N,N,26446,N,N,24412,N,31047,N,N,N,N,N,N,N,N, +22902,N,N,N,N,N,N,N,N,24364,N,22106,N,N,N,N,N,N,23588,N,N,N,28728,N,N,N,N, +21882,N,25719,N,N,N,22084,N,N,N,N,N,N,N,N,29804,N,N,N,N,28542,N,N,N,N,N,28705, +N,24106,N,N,23100,22652,N,N,N,N,N,N,31316,N,N,N,27749,N,N,N,N,N,N,31784,N,N, +27750,N,N,22603,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31545,N,25683,N,19833,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,20307,N,N,N,N,N,N,N,19050,N,N,20308,N,30781,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29767,N,N,N,N,27231,N,N,N,N,N,N,N,31067, +N,N,N,N,N,N,N,N,21559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27493,N,N, +24914,N,N,N,N,27172,N,N,N,31298,31585,31341,28706,19569,N,31267,25207,N,25166, +N,26997,N,24939,N,N,N,26472,26711,23160,21579,N,N,N,30582,22085,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,21609,N,N,31354,N,N,N,N,N,N,N,19570,30557,N,24122,N, +N,N,N,N,N,N,N,N,N,20008,N,N,N,N,N,28729,25726,25673,N,N,N,N,N,25684,N,N,N, +27203,N,28468,N,N,N,22334,N,N,N,N,N,N,31586,N,19795,N,N,N,28469,N,N,N,31337,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31014,N,N,N,N,N,N,24381,N,30535,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,30845,N,N,30844,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +24107,23400,N,N,25437,N,24930,20806,N,N,N,N,N,N,N,N,N,N,30288,27494,23161,N,N, +N,N,27719,N,N,N,N,N,N,N,24184,30825,25438,20085,N,N,N,N,N,31299,25943,N,27720, +N,N,N,29513,N,N,25659,N,N,N,N,26158,N,N,N,N,N,28470,N,23615,N,N,N,N,N,N,N, +20029,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22595,N,N,N, +20559,N,20346,29514,24663,N,N,N,20807,26926,N,26685,N,N,31300,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25167,N,N,31301,N,N,N,31032,N,N,N,N,N,N,N,23648, +N,N,31536,N,N,N,22569,25951,31015,N,N,30318,N,30284,25208,N,N,N,N,27761,N,N,N, +N,N,N,N,23136,N,N,N,N,N,N,N,N,N,N,N,N,N,N,29010,21068,20299,N,N,19005,N,N,N, +23871,N,N,N,30319,N,24185,N,N,N,N,N,N,N,N,N,N,N,N,N,31284,N,N,N,21805,N,N,N,N, +N,N,N,N,N,N,N,N,N,29031,24126,N,N,N,N,N,N,23616,N,N,N,N,N,20808,20809,N,N,N,N, +N,N,N,N,N,30782,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19318,N,N,N,N,21625,N,N,N,N, +N,30050,24915,N,N,N,N,N,N,N,N,22633,N,N,30846,N,20300,N,N,N,N,N,N,N,32036,N,N, +N,N,N,N,N,20086,N,31312,N,N,19571,26174,N,N,N,30254,N,N,21872,N,N,20810,N,N,N, +31806,21873,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19817,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,31285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,25168, +29815,N,N,N,19796,N,N,N,N,N,N,N,N,N,N,N,N,26403,N,N,N,N,N,N,N,N,23333,25169,N, +N,N,N,N,N,N,N,N,N,N,N,22306,N,N,30563,N,N,N,N,N,N,27174,N,N,N,N,N,N,N,N,N,N, +20513,N,N,N,N,20058,31595,23334,23390,22629,N,N,N,N,N,N,N,N,N,27232,N,N,N,N, +22570,N,N,N,N,N,25952,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22107,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28486,N,N,30826,N,N,N,N,N,N, +N,N,N,N,N,N,N,25685,N,N,N,N,N,N,N,N,N,N,N,20087,N,N,24664,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22383,N,N,N,N,N,N,N,N,N,N,N,N,29805,N,N,N,N,N, +N,N,N,N,N,N,N,N,19814,N,N,N,19572,30051,N,N,25674,N,23649,N,N,31048,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,31807,N,N,N,N,N,N,N,N,N,N,N,N,26663,N,N,N,N,N,N,N,N,22596, +N,N,N,N,N,N,N,N,N,N,N,19262,N,23598,N,N,N,N,N,N,N,N,N,N,N,N,N,22391,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28776,N,23872,N,20301,N,N,N,N,N,N,N,N,N, +23667,22832,N,26217,25660,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,27204,N,N,N,N,N,N, +N,N,N,N,25708,N,25701,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,31608,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,19515,N,N,N,N,N,N,N,N,N,N,N,25661,N,N,19804,22903, +N,N,N,N,N,N,N,N,N,N,23903,N,N,N,N,N,27982,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22864, +N,N,N,N,N,25891,N,N,N,N,31053,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,19758,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,20302,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,30255,N,N,N,N,N,32083,27501,22108,25892,N,N,N,21814,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22109, +N,N,N,31081,N,N,N,26404,N,22115,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,20811, +22116,N,N,N,21874,N,N,N,N,N,24186,N,22392,N,N,N,N,N,22634,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,20309,22653,N,N,N,N,N,22571,N,N,32075,N,N,N,N,31836,N,N,N,N,N,N,N,N,N, +24616,21875,N,N,32089,N,N,19491,N,N,N,22905,N,N,21354,30069,N,28487,N,N,N,N,N, +N,N,N,N,21338,N,N,N,N,N,N,N,N,N,N,N,23101,26664,23599,N,N,N,N,N,28707,N,N,N,N, +19797,N,N,N,N,N,N,N,N,N,N,N,N,24617,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,24108,N,N,N,N,N,N,N,N,N,N,N,N,N,N,28730,28209,N,N,28210,N,N,N,30285, +N,N,N,N,N,N,N,N,N,N,N,N,28242,N,22086,N,N,N,N,N,24677,N,N,29499,N,25953,N,N,N, +N,N,N,N,N,N,N,25675,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,22307,N,N,23362, +N,N,N,N,19070,N,N,N,N,N,N,20303,12321,12322,33089,33090,12323,33091,33092, +12324,12325,12326,12327,33093,33094,33095,33096,33097,12328,12329,12330,12331, +12332,12333,12334,12335,33098,12336,12337,12338,12339,12340,33099,33100,12341, +33101,33102,33103,12342,33104,33105,33106,33107,33108,33109,33110,12343,12344, +33111,12345,12346,12347,33112,33113,33114,33121,33122,33123,12348,12349,33124, +33125,12350,33126,33127,33128,12351,33129,33130,33131,33132,33133,33134,33135, +33136,33137,33138,12352,33139,12353,33140,33141,33142,33143,33144,33145,12354, +33146,33153,33154,12355,33155,33156,33157,12356,33158,33159,33160,33161,33162, +33163,33164,33165,33166,33167,33168,33169,33170,33171,33172,33173,33174,33175, +33176,12357,12358,33177,33178,12359,33179,33180,12360,12361,33181,12362,33182, +33183,33184,33185,33186,12363,12364,33187,12365,12366,12367,12368,33188,33189, +12369,12370,12371,12372,33190,33191,33192,12373,33193,33194,33195,12374,33196, +33197,33198,33199,33200,33201,33202,12375,12376,33203,12377,12378,12379,33204, +33205,33206,33207,33208,33209,12380,12381,12382,33210,12383,33211,33212,12384, +12385,33213,33214,33215,33216,33217,33218,33219,12386,12387,33220,12388,12389, +12390,33221,33222,33223,12391,33224,33225,12392,33226,33227,33228,12393,33229, +33230,33231,12394,33232,33233,33234,33235,33236,33237,33238,33239,12395,33240, +12396,33241,33242,33243,33244,33245,33246,33247,33248,12397,12398,33249,33250, +12399,33251,33252,12400,12401,33253,12402,33254,12403,33255,33256,12404,12405, +12406,33257,12407,33258,12408,12409,33259,33260,33261,33262,33263,12410,12411, +33264,33265,12412,33266,33267,33268,12413,33269,12414,33270,33271,33272,33273, +33274,12577,12578,33275,12579,33276,12580,33277,33278,33345,33346,33347,33348, +12581,33349,33350,33351,12582,33352,33353,33354,12583,33355,33356,33357,33358, +33359,33360,33361,33362,12584,33363,33364,12585,12586,33365,33366,33367,33368, +33369,33370,12587,12588,33377,33378,12589,33379,33380,33381,12590,33382,33383, +33384,33385,33386,33387,33388,12591,12592,33389,12593,33390,12594,33391,33392, +33393,33394,33395,33396,12595,33397,33398,33399,12596,33400,33401,33402,12597, +33409,33410,33411,33412,33413,33414,33415,33416,12598,33417,12599,33418,33419, +33420,33421,33422,33423,33424,33425,12600,12601,33426,33427,12602,33428,33429, +12603,12604,12605,12606,33430,33431,33432,33433,12607,12608,12609,33434,12610, +33435,12611,12612,33436,33437,33438,33439,33440,12613,12614,33441,33442,12615, +33443,33444,33445,12616,33446,33447,33448,33449,33450,33451,33452,33453,33454, +33455,33456,12617,12618,33457,33458,33459,33460,33461,33462,12619,33463,33464, +33465,33466,33467,33468,33469,33470,33471,33472,33473,33474,33475,33476,33477, +33478,33479,33480,12620,33481,33482,33483,33484,33485,33486,33487,33488,12621, +12622,33489,33490,12623,33491,33492,33493,12624,33494,33495,33496,33497,33498, +33499,33500,12625,12626,33501,12627,33502,33503,33504,33505,33506,33507,33508, +33509,12628,33510,33511,33512,12629,33513,33514,33515,12630,33516,33517,33518, +33519,33520,33521,33522,33523,33524,33525,33526,33527,33528,33529,33530,33531, +33532,33533,33534,12631,12632,33601,33602,12633,33603,33604,12634,12635,12636, +33605,33606,33607,33608,33609,33610,12637,12638,33611,12639,33612,12640,33613, +33614,33615,33616,33617,33618,12641,33619,33620,33621,33622,33623,33624,33625, +33626,33633,33634,33635,33636,33637,33638,33639,33640,33641,33642,33643,33644, +33645,33646,33647,33648,33649,33650,33651,12642,12643,33652,33653,12644,33654, +33655,12645,12646,33656,12647,33657,33658,33665,33666,33667,12648,12649,33668, +12650,33669,12651,12652,33670,33671,33672,12653,33673,12654,12655,12656,33674, +12657,33675,33676,33677,12658,33678,12659,33679,33680,33681,33682,33683,12660, +12661,33684,12662,12663,12664,33685,33686,33687,12665,33688,33689,12666,12667, +33690,33691,12668,33692,33693,33694,12669,33695,33696,33697,33698,33699,33700, +33701,12670,12833,33702,12834,12835,12836,33703,33704,33705,33706,33707,33708, +12837,12838,33709,33710,33711,33712,33713,33714,12839,33715,33716,33717,33718, +33719,33720,33721,33722,33723,33724,33725,33726,33727,33728,33729,33730,33731, +33732,33733,33734,33735,33736,33737,33738,33739,33740,33741,33742,33743,33744, +33745,33746,33747,33748,33749,33750,33751,33752,33753,33754,33755,33756,33757, +33758,33759,33760,33761,12840,12841,12842,33762,12843,33763,33764,33765,12844, +33766,33767,33768,33769,33770,33771,33772,12845,12846,33773,12847,12848,12849, +33774,33775,33776,33777,33778,33779,12850,12851,33780,33781,12852,33782,33783, +33784,33785,33786,33787,33788,33789,33790,33857,33858,12853,33859,33860,12854, +33861,12855,33862,33863,33864,33865,33866,33867,12856,33868,33869,33870,12857, +33871,33872,33873,12858,33874,33875,33876,33877,33878,33879,33880,33881,33882, +33889,12859,12860,33890,33891,33892,33893,12861,33894,33895,12862,33896,33897, +33898,33899,33900,33901,33902,33903,33904,33905,33906,33907,33908,33909,33910, +33911,33912,33913,33914,33921,33922,33923,33924,33925,33926,33927,33928,12863, +12864,33929,33930,12865,33931,12866,33932,12867,33933,33934,33935,33936,33937, +33938,33939,12868,12869,33940,12870,33941,12871,12872,12873,33942,33943,33944, +33945,12874,12875,33946,33947,33948,33949,33950,33951,12876,33952,33953,33954, +33955,33956,33957,33958,33959,33960,33961,33962,12877,12878,33963,33964,33965, +33966,33967,33968,12879,12880,33969,33970,33971,33972,33973,33974,33975,33976, +33977,33978,33979,33980,33981,33982,33983,33984,33985,33986,33987,12881,33988, +33989,33990,33991,33992,33993,12882,33994,33995,33996,12883,33997,33998,33999, +12884,34000,34001,34002,34003,34004,34005,34006,12885,12886,34007,34008,34009, +12887,34010,34011,34012,34013,34014,34015,12888,34016,34017,34018,34019,34020, +34021,34022,34023,34024,34025,34026,34027,34028,34029,34030,34031,34032,34033, +34034,34035,34036,34037,34038,34039,34040,34041,34042,12889,12890,34043,34044, +12891,34045,34046,34113,12892,34114,34115,34116,34117,34118,34119,12893,12894, +12895,34120,12896,34121,12897,12898,34122,34123,34124,34125,34126,12899,34127, +34128,34129,34130,34131,34132,34133,12900,34134,34135,34136,34137,34138,34145, +34146,34147,34148,34149,34150,12901,12902,34151,34152,34153,34154,34155,34156, +12903,12904,34157,34158,12905,34159,34160,34161,12906,34162,34163,34164,34165, +34166,34167,34168,12907,12908,34169,34170,12909,34177,34178,34179,34180,34181, +34182,34183,12910,34184,34185,34186,12911,34187,34188,34189,12912,34190,34191, +34192,34193,34194,34195,34196,12913,12914,34197,34198,34199,34200,34201,34202, +34203,34204,34205,34206,12915,34207,34208,34209,34210,34211,34212,34213,34214, +34215,34216,34217,34218,34219,34220,34221,34222,34223,34224,34225,34226,34227, +34228,34229,34230,34231,34232,34233,12916,12917,34234,34235,12918,34236,12919, +34237,12920,34238,12921,34239,34240,34241,34242,12922,12923,12924,34243,12925, +34244,12926,34245,34246,34247,13089,34248,34249,34250,34251,34252,34253,34254, +34255,34256,34257,34258,34259,34260,34261,34262,34263,34264,34265,34266,34267, +34268,34269,34270,34271,34272,34273,34274,34275,34276,34277,13090,13091,34278, +34279,13092,34280,34281,34282,13093,34283,34284,34285,34286,34287,34288,34289, +13094,13095,34290,13096,34291,13097,34292,34293,34294,34295,34296,34297,13098, +13099,13100,34298,13101,34299,34300,13102,13103,13104,13105,34301,34302,34369, +34370,34371,13106,13107,34372,13108,13109,13110,13111,13112,34373,13113,34374, +13114,13115,13116,34375,34376,13117,34377,34378,34379,13118,34380,34381,34382, +34383,34384,34385,34386,13119,13120,34387,13121,13122,13123,34388,34389,34390, +34391,34392,34393,13124,13125,34394,34401,13126,34402,34403,34404,13127,34405, +34406,34407,34408,34409,34410,34411,13128,34412,34413,34414,34415,13129,34416, +34417,34418,34419,34420,34421,34422,34423,34424,34425,34426,34433,34434,34435, +34436,34437,34438,34439,34440,34441,34442,34443,34444,34445,34446,34447,34448, +34449,34450,34451,34452,34453,34454,34455,13130,13131,34456,13132,13133,34457, +34458,34459,13134,34460,13135,13136,34461,34462,34463,34464,13137,13138,34465, +13139,13140,13141,34466,34467,34468,34469,34470,13142,13143,13144,34471,34472, +13145,34473,34474,34475,13146,34476,34477,34478,34479,34480,34481,34482,13147, +13148,34483,13149,13150,13151,34484,34485,34486,34487,34488,34489,13152,13153, +34490,34491,13154,34492,34493,34494,13155,34495,34496,34497,34498,34499,34500, +34501,13156,13157,34502,34503,13158,13159,34504,34505,13160,34506,34507,34508, +13161,34509,34510,34511,13162,34512,34513,34514,34515,34516,34517,34518,34519, +34520,34521,34522,34523,34524,34525,34526,34527,34528,34529,34530,34531,34532, +34533,34534,13163,13164,34535,34536,13165,34537,34538,34539,13166,34540,13167, +34541,34542,34543,34544,34545,13168,13169,34546,13170,34547,13171,34548,34549, +34550,34551,13172,13173,13174,34552,34553,34554,13175,34555,34556,34557,13176, +34558,34625,34626,34627,34628,34629,34630,34631,34632,34633,34634,13177,34635, +34636,34637,34638,34639,34640,34641,34642,34643,34644,34645,34646,34647,34648, +34649,34650,34657,34658,34659,34660,34661,34662,34663,34664,34665,34666,34667, +34668,34669,34670,34671,34672,34673,34674,34675,13178,34676,34677,34678,13179, +34679,34680,34681,13180,34682,34689,34690,34691,34692,34693,34694,13181,13182, +34695,13345,34696,34697,34698,34699,34700,34701,34702,34703,13346,13347,34704, +34705,13348,34706,34707,34708,13349,34709,34710,34711,34712,34713,34714,34715, +34716,13350,34717,13351,34718,13352,34719,34720,34721,34722,34723,34724,13353, +13354,34725,34726,13355,34727,34728,13356,13357,34729,34730,34731,34732,34733, +34734,34735,13358,13359,34736,13360,34737,13361,34738,34739,34740,34741,34742, +34743,13362,34744,34745,34746,34747,34748,34749,34750,34751,34752,34753,34754, +34755,34756,34757,34758,34759,34760,34761,34762,13363,34763,34764,34765,34766, +34767,34768,34769,13364,34770,34771,34772,34773,34774,34775,34776,34777,34778, +34779,34780,34781,34782,34783,34784,34785,34786,34787,34788,34789,34790,34791, +34792,34793,34794,34795,34796,13365,34797,34798,34799,13366,34800,34801,34802, +13367,34803,34804,34805,34806,34807,34808,34809,13368,13369,34810,34811,34812, +34813,34814,34881,34882,34883,34884,34885,13370,13371,34886,34887,34888,34889, +34890,34891,13372,34892,34893,34894,34895,34896,34897,34898,13373,13374,34899, +34900,34901,13375,34902,34903,34904,34905,34906,34913,13376,13377,34914,34915, +13378,34916,34917,34918,13379,13380,13381,34919,34920,34921,34922,34923,13382, +13383,34924,13384,34925,13385,13386,34926,34927,34928,13387,34929,13388,34930, +34931,34932,13389,34933,34934,34935,13390,34936,34937,34938,34945,34946,34947, +34948,34949,34950,34951,34952,34953,34954,34955,34956,34957,34958,34959,34960, +13391,13392,34961,34962,13393,34963,34964,34965,13394,34966,13395,34967,34968, +34969,34970,34971,13396,13397,34972,13398,34973,13399,34974,34975,34976,34977, +13400,34978,13401,13402,13403,34979,13404,34980,34981,13405,13406,13407,13408, +13409,34982,34983,34984,13410,13411,13412,34985,13413,13414,13415,13416,13417, +34986,34987,34988,13418,13419,13420,34989,34990,13421,34991,34992,34993,13422, +34994,34995,34996,34997,34998,34999,35000,13423,13424,35001,13425,13426,13427, +35002,35003,35004,35005,35006,35007,13428,35008,35009,35010,35011,35012,35013, +35014,35015,35016,35017,35018,35019,35020,35021,35022,35023,35024,35025,35026, +35027,35028,35029,35030,35031,35032,35033,35034,35035,35036,35037,35038,35039, +35040,35041,35042,35043,35044,35045,35046,35047,35048,35049,35050,35051,35052, +35053,35054,35055,35056,35057,35058,35059,35060,35061,35062,13429,13430,13431, +35063,13432,35064,35065,13433,13434,35066,13435,13436,35067,35068,35069,35070, +13437,13438,35137,13601,35138,13602,35139,13603,35140,35141,13604,35142,13605, +13606,35143,35144,13607,35145,35146,35147,13608,35148,35149,35150,35151,35152, +35153,35154,13609,13610,35155,13611,13612,13613,35156,35157,35158,35159,35160, +35161,13614,35162,35169,35170,13615,35171,35172,35173,13616,35174,35175,35176, +35177,35178,35179,35180,35181,35182,35183,35184,13617,13618,35185,35186,35187, +35188,35189,35190,13619,35191,35192,35193,13620,35194,35201,35202,35203,35204, +35205,35206,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217, +35218,35219,35220,35221,35222,13621,13622,35223,35224,13623,35225,35226,13624, +13625,35227,13626,35228,13627,35229,35230,35231,13628,13629,35232,13630,35233, +13631,35234,13632,35235,13633,35236,35237,13634,35238,35239,35240,13635,35241, +35242,35243,13636,35244,35245,35246,35247,35248,35249,35250,35251,35252,35253, +35254,35255,35256,35257,35258,35259,35260,35261,35262,13637,35263,35264,35265, +35266,35267,35268,35269,35270,35271,35272,35273,35274,35275,35276,35277,35278, +35279,35280,35281,13638,35282,35283,35284,35285,35286,35287,35288,13639,35289, +35290,35291,13640,35292,35293,35294,13641,35295,35296,35297,35298,35299,35300, +35301,13642,13643,35302,13644,35303,35304,35305,35306,35307,35308,35309,35310, +13645,35311,35312,35313,35314,35315,35316,35317,35318,35319,35320,35321,35322, +35323,35324,35325,35326,35393,35394,35395,35396,35397,35398,35399,35400,35401, +35402,35403,13646,13647,35404,35405,13648,35406,35407,35408,13649,35409,35410, +35411,35412,35413,35414,35415,13650,13651,35416,13652,35417,13653,35418,35425, +35426,35427,35428,35429,13654,35430,35431,35432,35433,35434,35435,35436,35437, +35438,35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,13655,35449, +35450,35457,35458,35459,35460,35461,13656,35462,35463,35464,35465,35466,35467, +35468,35469,35470,35471,35472,35473,35474,35475,35476,35477,35478,35479,35480, +35481,13657,35482,35483,35484,35485,35486,35487,13658,35488,35489,35490,13659, +35491,35492,35493,13660,35494,35495,35496,35497,35498,35499,35500,35501,13661, +35502,13662,35503,13663,35504,35505,35506,35507,35508,35509,13664,35510,35511, +35512,13665,35513,35514,35515,13666,35516,35517,35518,35519,35520,35521,35522, +13667,35523,35524,35525,35526,13668,35527,35528,35529,35530,35531,35532,13669, +13670,35533,35534,13671,35535,35536,13672,13673,35537,13674,35538,35539,35540, +35541,35542,13675,13676,35543,13677,35544,13678,35545,35546,35547,35548,35549, +35550,13679,35551,35552,35553,35554,35555,35556,35557,35558,35559,35560,35561, +35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,35574, +35575,35576,35577,13680,13681,35578,35579,13682,35580,35581,13683,13684,35582, +35649,35650,35651,35652,35653,35654,13685,13686,35655,13687,13688,13689,13690, +35656,35657,35658,35659,35660,13691,13692,35661,35662,13693,35663,35664,35665, +13694,35666,35667,35668,35669,35670,35671,35672,13857,13858,35673,13859,13860, +13861,35674,35681,35682,35683,35684,13862,13863,13864,35685,35686,13865,35687, +35688,35689,13866,35690,35691,35692,35693,35694,35695,35696,13867,13868,35697, +13869,13870,13871,35698,35699,35700,35701,35702,35703,35704,35705,35706,35713, +35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,35725,35726, +35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,35738,35739, +35740,35741,35742,35743,35744,35745,35746,35747,35748,35749,35750,35751,35752, +35753,35754,35755,35756,35757,35758,35759,35760,35761,35762,35763,35764,35765, +13872,13873,35766,35767,13874,35768,35769,35770,13875,35771,13876,13877,35772, +35773,35774,35775,13878,13879,35776,13880,13881,13882,35777,35778,35779,35780, +35781,13883,13884,13885,35782,35783,13886,35784,35785,35786,13887,35787,35788, +35789,35790,35791,35792,35793,13888,13889,35794,13890,13891,13892,35795,35796, +35797,35798,35799,35800,13893,35801,35802,35803,35804,35805,35806,35807,35808, +35809,35810,35811,35812,35813,35814,35815,35816,35817,35818,35819,13894,35820, +35821,35822,35823,35824,35825,35826,35827,35828,35829,35830,35831,35832,35833, +35834,35835,35836,35837,35838,35905,35906,35907,35908,35909,35910,35911,35912, +35913,35914,35915,35916,35917,35918,35919,35920,13895,13896,35921,35922,13897, +35923,35924,35925,13898,35926,35927,35928,35929,35930,35937,35938,35939,35940, +35941,35942,35943,13899,35944,35945,35946,35947,35948,35949,13900,35950,35951, +35952,35953,35954,35955,35956,13901,35957,35958,35959,35960,35961,35962,35969, +35970,35971,35972,35973,35974,35975,35976,35977,35978,35979,35980,35981,13902, +35982,35983,35984,35985,35986,35987,35988,35989,35990,35991,35992,35993,35994, +35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,36005,36006,36007, +36008,13903,36009,36010,36011,13904,36012,36013,36014,36015,36016,36017,36018, +36019,36020,36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031, +36032,36033,36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044, +36045,36046,36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057, +36058,36059,36060,36061,36062,13905,13906,36063,36064,13907,36065,36066,36067, +13908,36068,36069,36070,36071,36072,36073,13909,13910,36074,36075,36076,36077, +13911,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089, +36090,36091,36092,36093,36094,36161,36162,36163,36164,36165,36166,36167,36168, +36169,36170,36171,36172,36173,36174,36175,36176,36177,13912,36178,36179,36180, +36181,36182,36183,36184,36185,36186,36193,36194,36195,36196,36197,36198,36199, +36200,36201,36202,36203,36204,36205,36206,36207,36208,36209,36210,13913,36211, +36212,36213,13914,36214,36215,36216,13915,36217,36218,36225,36226,36227,36228, +36229,13916,13917,36230,36231,36232,13918,36233,36234,36235,36236,36237,36238, +36239,36240,36241,36242,36243,36244,36245,36246,36247,36248,36249,36250,36251, +36252,36253,36254,36255,36256,36257,36258,36259,36260,36261,36262,36263,36264, +36265,36266,13919,13920,36267,36268,13921,36269,36270,13922,13923,36271,36272, +36273,36274,36275,36276,36277,13924,13925,36278,13926,36279,36280,36281,36282, +36283,36284,36285,36286,13927,36287,36288,36289,13928,36290,36291,36292,13929, +36293,36294,36295,36296,36297,36298,36299,13930,13931,36300,36301,36302,36303, +36304,36305,36306,36307,36308,36309,13932,36310,36311,36312,13933,36313,36314, +36315,13934,36316,36317,36318,36319,36320,36321,36322,13935,13936,36323,13937, +36324,13938,36325,36326,36327,36328,36329,36330,13939,13940,36331,36332,13941, +36333,36334,36335,13942,36336,36337,36338,36339,36340,36341,36342,13943,13944, +36343,13945,13946,13947,13948,36344,36345,36346,13949,13950,14113,14114,36347, +36348,14115,36349,36350,36417,14116,36418,36419,36420,36421,36422,36423,36424, +14117,14118,36425,14119,14120,14121,36426,36427,36428,36429,36430,36431,14122, +14123,36432,36433,14124,36434,36435,36436,36437,36438,36439,36440,36441,36442, +36449,36450,36451,36452,36453,14125,36454,14126,36455,36456,36457,36458,36459, +36460,36461,36462,36463,36464,36465,36466,36467,36468,36469,36470,36471,36472, +36473,36474,36481,36482,36483,36484,36485,36486,36487,36488,36489,36490,36491, +36492,36493,36494,14127,14128,36495,36496,14129,36497,36498,36499,14130,36500, +36501,36502,36503,36504,36505,36506,14131,14132,36507,14133,14134,14135,36508, +36509,36510,36511,36512,14136,14137,14138,36513,36514,14139,36515,36516,36517, +14140,36518,36519,36520,36521,36522,36523,36524,14141,14142,36525,14143,36526, +14144,36527,36528,36529,36530,36531,36532,14145,14146,36533,36534,14147,36535, +36536,36537,14148,36538,36539,36540,36541,36542,36543,36544,14149,14150,36545, +14151,14152,14153,36546,36547,36548,36549,36550,36551,14154,36552,36553,36554, +14155,36555,36556,36557,36558,36559,36560,36561,36562,36563,36564,36565,36566, +14156,36567,14157,36568,36569,36570,36571,36572,36573,36574,36575,14158,14159, +36576,36577,14160,36578,36579,36580,14161,36581,36582,36583,36584,36585,36586, +36587,14162,14163,36588,14164,36589,14165,36590,36591,36592,36593,36594,36595, +14166,36596,36597,36598,14167,36599,36600,36601,36602,36603,36604,36605,36606, +36673,36674,36675,36676,36677,36678,36679,36680,14168,36681,36682,36683,36684, +36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697, +36698,36705,36706,36707,36708,36709,36710,36711,36712,14169,36713,36714,36715, +36716,36717,36718,36719,14170,36720,36721,36722,14171,36723,36724,36725,14172, +36726,36727,36728,36729,36730,36737,36738,14173,14174,36739,14175,36740,14176, +36741,36742,36743,36744,36745,36746,14177,36747,36748,36749,14178,36750,36751, +36752,14179,36753,36754,36755,36756,36757,36758,36759,36760,14180,36761,14181, +36762,14182,36763,36764,36765,36766,36767,36768,14183,14184,36769,36770,14185, +36771,36772,36773,14186,36774,36775,36776,36777,36778,36779,36780,14187,14188, +36781,14189,36782,14190,36783,36784,36785,36786,36787,36788,14191,36789,36790, +36791,36792,36793,36794,36795,36796,36797,36798,36799,36800,36801,36802,36803, +36804,36805,36806,36807,14192,36808,36809,36810,36811,36812,36813,36814,14193, +36815,36816,36817,36818,36819,36820,36821,36822,36823,36824,36825,36826,36827, +36828,36829,36830,36831,36832,36833,36834,36835,36836,36837,36838,36839,36840, +36841,14194,14195,36842,36843,14196,36844,36845,36846,14197,36847,36848,36849, +36850,36851,36852,36853,14198,36854,36855,14199,36856,14200,36857,36858,36859, +36860,36861,36862,14201,14202,36929,36930,14203,36931,36932,36933,14204,36934, +36935,36936,36937,36938,36939,36940,14205,14206,36941,14369,36942,14370,36943, +36944,36945,36946,36947,36948,14371,14372,36949,36950,14373,36951,36952,36953, +14374,36954,36961,36962,36963,36964,36965,36966,14375,14376,36967,14377,36968, +14378,14379,36969,36970,14380,14381,36971,36972,36973,36974,36975,36976,36977, +36978,36979,36980,36981,36982,36983,36984,36985,36986,36993,36994,36995,36996, +36997,36998,36999,37000,37001,37002,37003,37004,37005,14382,14383,37006,37007, +14384,37008,37009,37010,14385,37011,37012,37013,37014,37015,37016,37017,14386, +14387,37018,14388,37019,14389,37020,37021,37022,37023,37024,37025,14390,14391, +37026,37027,14392,37028,14393,14394,14395,14396,14397,37029,37030,37031,37032, +37033,14398,14399,37034,14400,37035,14401,14402,37036,37037,14403,37038,14404, +14405,14406,37039,37040,14407,37041,37042,37043,14408,37044,37045,37046,37047, +37048,37049,37050,14409,14410,37051,14411,14412,14413,14414,37052,37053,37054, +37055,37056,14415,14416,37057,37058,37059,37060,37061,37062,14417,37063,37064, +37065,37066,37067,37068,37069,37070,37071,37072,37073,37074,14418,37075,37076, +37077,37078,37079,37080,37081,37082,37083,37084,37085,37086,37087,37088,37089, +37090,37091,37092,37093,37094,37095,37096,37097,37098,37099,37100,37101,37102, +37103,37104,37105,37106,37107,37108,14419,14420,37109,37110,14421,37111,37112, +37113,14422,37114,14423,37115,37116,37117,37118,37185,14424,14425,37186,14426, +37187,14427,14428,37188,37189,37190,37191,14429,14430,14431,37192,37193,14432, +37194,37195,37196,14433,37197,37198,37199,37200,37201,37202,37203,14434,14435, +37204,14436,14437,14438,37205,37206,37207,37208,37209,37210,14439,14440,37217, +37218,14441,37219,37220,37221,14442,37222,37223,37224,37225,37226,37227,37228, +37229,37230,37231,14443,14444,14445,37232,14446,37233,37234,37235,37236,14447, +37237,37238,37239,37240,37241,37242,37249,37250,37251,37252,37253,37254,37255, +37256,37257,37258,37259,37260,37261,37262,37263,37264,37265,37266,37267,37268, +37269,14448,14449,37270,14450,14451,37271,37272,37273,14452,37274,14453,37275, +37276,37277,37278,37279,14454,14455,37280,14456,37281,14457,37282,37283,37284, +37285,37286,37287,14458,37288,37289,37290,14459,37291,37292,37293,37294,37295, +37296,37297,37298,37299,37300,37301,37302,37303,37304,37305,14460,14461,37306, +37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,37318,37319, +37320,37321,37322,37323,37324,37325,37326,37327,37328,37329,37330,37331,37332, +37333,37334,37335,37336,37337,37338,37339,14462,37340,37341,37342,14625,37343, +37344,37345,14626,37346,37347,37348,37349,37350,37351,37352,37353,14627,37354, +14628,37355,14629,37356,37357,37358,37359,37360,37361,14630,37362,37363,37364, +14631,37365,37366,37367,14632,37368,37369,37370,37371,37372,37373,37374,37441, +14633,37442,14634,37443,37444,37445,37446,37447,37448,37449,37450,14635,14636, +14637,37451,14638,37452,37453,14639,14640,14641,14642,37454,37455,37456,37457, +37458,14643,14644,37459,14645,37460,14646,37461,37462,37463,14647,37464,14648, +14649,37465,37466,37473,14650,37474,37475,37476,14651,37477,37478,37479,37480, +37481,37482,37483,37484,14652,37485,14653,37486,37487,37488,37489,37490,37491, +37492,37493,14654,37494,37495,37496,37497,37498,37505,37506,37507,37508,37509, +37510,37511,37512,37513,37514,37515,37516,37517,37518,37519,37520,37521,37522, +37523,37524,37525,37526,14655,37527,37528,37529,14656,37530,37531,37532,14657, +37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,37544,37545, +37546,37547,37548,37549,37550,37551,14658,37552,37553,37554,14659,37555,37556, +37557,14660,37558,37559,37560,37561,37562,37563,37564,14661,37565,37566,14662, +37567,37568,37569,37570,37571,37572,37573,37574,14663,37575,37576,37577,14664, +37578,37579,37580,14665,37581,37582,37583,37584,37585,37586,37587,14666,37588, +37589,14667,37590,37591,37592,37593,37594,37595,37596,37597,37598,37599,37600, +37601,37602,37603,37604,37605,37606,37607,37608,37609,37610,37611,37612,37613, +37614,37615,37616,37617,37618,37619,37620,37621,37622,37623,37624,37625,14668, +14669,37626,37627,14670,37628,37629,14671,14672,37630,14673,37697,37698,37699, +37700,37701,14674,14675,37702,14676,14677,14678,37703,14679,37704,14680,37705, +37706,14681,14682,14683,14684,14685,37707,37708,14686,14687,14688,14689,14690, +37709,37710,37711,37712,14691,14692,37713,14693,37714,14694,37715,37716,37717, +14695,37718,37719,14696,14697,37720,37721,14698,37722,37729,37730,14699,37731, +37732,37733,37734,37735,37736,37737,14700,14701,37738,14702,14703,14704,37739, +37740,37741,14705,37742,37743,14706,14707,37744,37745,14708,37746,37747,37748, +37749,37750,37751,37752,37753,37754,37761,37762,37763,14709,37764,37765,37766, +37767,37768,37769,37770,37771,37772,37773,37774,37775,37776,37777,37778,37779, +37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792, +37793,37794,37795,37796,37797,37798,37799,37800,37801,14710,14711,37802,37803, +14712,37804,37805,14713,14714,37806,14715,37807,37808,37809,37810,37811,14716, +14717,37812,14718,37813,14881,14882,37814,37815,37816,37817,37818,14883,14884, +37819,37820,14885,37821,37822,14886,14887,37823,37824,37825,37826,37827,37828, +37829,14888,14889,37830,14890,14891,14892,37831,37832,37833,37834,37835,37836, +14893,14894,37837,37838,14895,37839,37840,37841,14896,37842,37843,37844,37845, +37846,37847,37848,37849,14897,37850,14898,14899,14900,37851,37852,37853,14901, +37854,37855,14902,37856,37857,37858,14903,37859,37860,37861,37862,37863,37864, +37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877, +37878,37879,37880,37881,14904,14905,14906,37882,14907,37883,37884,37885,14908, +37886,37953,37954,37955,37956,37957,37958,14909,14910,37959,14911,37960,14912, +37961,37962,37963,37964,37965,37966,14913,37967,37968,37969,14914,37970,37971, +37972,37973,37974,37975,37976,37977,37978,37985,37986,37987,37988,37989,37990, +14915,37991,37992,37993,37994,37995,37996,37997,14916,37998,37999,38000,38001, +38002,38003,38004,38005,38006,38007,38008,38009,38010,38017,38018,38019,38020, +38021,38022,14917,38023,38024,38025,38026,38027,38028,38029,14918,14919,38030, +38031,14920,38032,38033,38034,14921,38035,38036,38037,38038,38039,38040,38041, +14922,14923,38042,38043,38044,38045,38046,38047,38048,38049,38050,38051,14924, +38052,38053,38054,14925,38055,38056,38057,38058,38059,38060,38061,38062,38063, +38064,38065,38066,38067,38068,38069,38070,38071,38072,38073,38074,38075,38076, +38077,14926,14927,38078,38079,14928,38080,38081,14929,14930,14931,14932,38082, +38083,38084,38085,38086,14933,14934,38087,14935,38088,14936,38089,38090,38091, +14937,14938,38092,14939,38093,38094,38095,38096,38097,38098,38099,14940,38100, +38101,38102,38103,38104,38105,38106,38107,38108,38109,38110,14941,38111,38112, +38113,38114,38115,38116,38117,14942,38118,38119,38120,38121,38122,38123,38124, +38125,38126,38127,38128,38129,38130,38131,38132,38133,38134,38135,38136,38137, +38138,38139,38140,38141,38142,38209,38210,14943,14944,38211,38212,14945,38213, +38214,38215,14946,38216,38217,38218,38219,38220,38221,38222,38223,38224,38225, +38226,38227,14947,38228,38229,38230,38231,38232,38233,14948,38234,38241,38242, +14949,38243,38244,38245,14950,38246,38247,38248,38249,38250,38251,38252,14951, +38253,38254,14952,38255,14953,38256,38257,38258,38259,38260,38261,14954,14955, +38262,38263,14956,38264,38265,38266,14957,38273,38274,38275,38276,38277,38278, +38279,14958,14959,38280,14960,38281,38282,38283,38284,38285,38286,38287,38288, +38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,38300,38301, +38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,38313,38314, +38315,38316,14961,14962,38317,38318,14963,38319,38320,38321,14964,38322,14965, +38323,38324,38325,38326,38327,14966,14967,38328,14968,38329,14969,14970,14971, +38330,38331,38332,38333,14972,14973,38334,38335,14974,38336,38337,38338,15137, +38339,15138,38340,38341,38342,38343,38344,15139,15140,38345,15141,15142,15143, +38346,38347,38348,38349,38350,15144,15145,15146,38351,38352,15147,38353,38354, +38355,15148,38356,38357,38358,38359,38360,38361,38362,15149,15150,38363,15151, +15152,15153,38364,38365,38366,38367,38368,38369,15154,15155,38370,38371,38372, +38373,38374,38375,38376,38377,38378,38379,38380,38381,38382,38383,15156,38384, +38385,38386,38387,38388,38389,38390,38391,38392,38393,38394,38395,38396,38397, +38398,38465,38466,38467,38468,38469,38470,38471,38472,38473,38474,38475,38476, +38477,38478,38479,38480,38481,38482,38483,38484,38485,38486,38487,38488,15157, +15158,38489,38490,15159,38497,38498,15160,15161,38499,38500,38501,38502,38503, +38504,38505,15162,38506,38507,15163,15164,15165,38508,38509,38510,38511,38512, +38513,15166,38514,38515,38516,38517,38518,38519,38520,38521,38522,38529,38530, +38531,38532,38533,38534,38535,38536,38537,38538,38539,15167,38540,38541,38542, +38543,38544,38545,15168,15169,38546,38547,38548,38549,38550,38551,38552,38553, +38554,38555,38556,38557,38558,38559,15170,15171,38560,15172,15173,15174,38561, +38562,38563,38564,38565,38566,38567,38568,38569,38570,38571,38572,38573,38574, +38575,38576,38577,38578,38579,38580,38581,38582,38583,38584,38585,38586,38587, +38588,38589,38590,38591,38592,38593,38594,15175,15176,38595,38596,15177,38597, +38598,38599,15178,38600,38601,38602,38603,38604,38605,38606,15179,15180,38607, +38608,38609,15181,38610,38611,38612,38613,38614,38615,38616,38617,38618,38619, +38620,38621,38622,38623,38624,38625,38626,38627,38628,38629,38630,38631,38632, +38633,38634,38635,38636,38637,38638,38639,38640,38641,38642,38643,38644,38645, +38646,38647,38648,38649,38650,38651,38652,38653,38654,38721,38722,38723,38724, +38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737, +15182,38738,38739,38740,38741,38742,38743,38744,38745,38746,38753,38754,38755, +38756,38757,38758,38759,38760,38761,38762,38763,38764,38765,38766,38767,38768, +38769,38770,15183,38771,38772,38773,38774,38775,38776,38777,38778,38785,38786, +38787,38788,38789,38790,38791,38792,38793,38794,38795,38796,15184,38797,38798, +38799,38800,38801,38802,15185,15186,38803,38804,15187,38805,38806,38807,15188, +38808,38809,38810,38811,38812,38813,38814,15189,38815,38816,15190,38817,15191, +38818,38819,38820,38821,38822,38823,38824,38825,38826,38827,38828,38829,38830, +38831,38832,38833,38834,38835,38836,38837,38838,38839,38840,38841,38842,38843, +38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856, +38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869, +38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882, +38883,38884,38885,38886,38887,38888,38889,38890,38891,38892,38893,38894,38895, +38896,38897,38898,38899,38900,38901,38902,38903,38904,38905,38906,38907,15192, +38908,38909,38910,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986, +38987,38988,38989,38990,38991,38992,38993,15193,38994,38995,38996,38997,38998, +38999,15194,39000,39001,39002,15195,39009,39010,39011,15196,39012,39013,39014, +39015,39016,39017,39018,15197,15198,39019,39020,39021,39022,39023,39024,39025, +39026,39027,39028,39029,39030,39031,39032,39033,39034,39041,39042,39043,39044, +39045,39046,39047,39048,39049,39050,39051,39052,39053,39054,39055,39056,39057, +39058,39059,39060,39061,39062,15199,15200,39063,39064,15201,39065,39066,39067, +15202,39068,39069,39070,39071,39072,39073,39074,15203,15204,39075,15205,39076, +15206,39077,39078,39079,39080,39081,39082,15207,15208,39083,15209,15210,39084, +39085,15211,15212,15213,15214,39086,39087,39088,39089,39090,15215,15216,39091, +15217,15218,15219,39092,39093,39094,15220,39095,39096,15221,15222,39097,39098, +15223,39099,39100,39101,15224,39102,39103,39104,39105,39106,39107,39108,15225, +15226,39109,15227,15228,15229,39110,39111,39112,39113,39114,39115,15230,15393, +39116,39117,15394,39118,39119,39120,15395,39121,39122,39123,39124,39125,39126, +39127,15396,15397,39128,15398,39129,15399,39130,39131,39132,39133,39134,39135, +15400,39136,39137,39138,15401,39139,39140,39141,15402,39142,39143,39144,39145, +39146,39147,39148,15403,39149,39150,39151,39152,15404,39153,39154,39155,39156, +39157,39158,15405,15406,15407,15408,15409,39159,39160,15410,15411,39161,15412, +15413,39162,39163,39164,39165,15414,15415,39166,15416,15417,15418,39233,39234, +39235,39236,15419,39237,15420,15421,39238,39239,15422,39240,39241,39242,15423, +39243,39244,39245,39246,39247,39248,39249,15424,15425,39250,15426,15427,15428, +39251,39252,39253,39254,39255,39256,15429,15430,39257,39258,15431,39265,39266, +39267,15432,39268,39269,39270,39271,39272,39273,39274,15433,15434,39275,15435, +15436,15437,39276,39277,39278,39279,39280,39281,15438,39282,39283,39284,15439, +39285,39286,39287,15440,39288,39289,39290,39297,39298,39299,39300,39301,39302, +39303,39304,39305,15441,39306,39307,39308,39309,39310,39311,15442,15443,15444, +39312,15445,39313,39314,39315,15446,39316,15447,39317,39318,39319,39320,39321, +15448,15449,39322,15450,39323,15451,39324,39325,39326,15452,39327,39328,15453, +15454,39329,39330,15455,39331,39332,39333,15456,39334,39335,39336,39337,39338, +39339,39340,39341,39342,39343,39344,39345,15457,39346,39347,39348,39349,39350, +39351,15458,39352,39353,39354,15459,39355,39356,39357,15460,39358,39359,39360, +39361,39362,39363,39364,15461,39365,39366,15462,15463,39367,39368,39369,39370, +39371,39372,39373,15464,39374,39375,39376,15465,39377,39378,39379,15466,39380, +39381,39382,39383,39384,39385,39386,15467,15468,39387,15469,39388,39389,39390, +39391,39392,39393,39394,39395,15470,15471,39396,39397,15472,39398,39399,39400, +15473,39401,39402,39403,39404,39405,39406,39407,15474,15475,39408,15476,39409, +15477,39410,39411,39412,39413,39414,39415,15478,15479,39416,39417,15480,39418, +39419,15481,15482,39420,39421,39422,39489,39490,39491,39492,15483,15484,39493, +15485,39494,15486,39495,15649,39496,15650,15651,39497,15652,39498,39499,39500, +39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513, +39514,39521,39522,15653,39523,39524,39525,39526,39527,39528,39529,15654,15655, +39530,39531,15656,39532,39533,39534,15657,39535,39536,39537,39538,39539,39540, +39541,15658,39542,39543,39544,39545,15659,39546,39553,39554,39555,39556,39557, +15660,15661,39558,39559,15662,39560,39561,39562,15663,39563,39564,39565,39566, +39567,39568,39569,15664,15665,39570,15666,39571,15667,39572,39573,39574,39575, +39576,39577,15668,15669,39578,39579,39580,39581,39582,39583,15670,39584,39585, +39586,39587,39588,39589,39590,15671,39591,39592,15672,39593,15673,39594,39595, +39596,39597,39598,39599,15674,15675,39600,39601,15676,39602,39603,39604,15677, +15678,39605,39606,39607,39608,39609,39610,15679,15680,39611,15681,39612,15682, +39613,39614,39615,39616,39617,39618,39619,39620,39621,39622,39623,39624,39625, +39626,39627,39628,39629,39630,39631,39632,39633,39634,39635,39636,39637,39638, +39639,39640,39641,39642,39643,39644,39645,39646,15683,15684,39647,39648,15685, +39649,39650,15686,15687,39651,39652,39653,39654,39655,39656,15688,15689,15690, +39657,15691,39658,15692,39659,39660,39661,39662,15693,39663,15694,15695,39664, +15696,15697,39665,39666,39667,15698,39668,39669,39670,39671,39672,39673,39674, +15699,15700,39675,39676,15701,15702,39677,39678,39745,39746,39747,15703,15704, +15705,39748,39749,15706,39750,39751,39752,15707,39753,39754,39755,39756,39757, +39758,39759,15708,15709,39760,39761,15710,15711,39762,39763,39764,39765,39766, +39767,39768,39769,39770,39777,39778,39779,39780,39781,39782,39783,39784,39785, +39786,39787,39788,39789,39790,39791,39792,39793,39794,15712,39795,39796,39797, +39798,39799,39800,39801,39802,39809,39810,39811,39812,39813,39814,39815,39816, +39817,39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829, +39830,39831,39832,39833,39834,15713,15714,39835,39836,15715,39837,39838,39839, +15716,39840,15717,39841,39842,39843,39844,39845,15718,15719,39846,39847,15720, +15721,39848,39849,39850,39851,39852,39853,15722,39854,39855,39856,15723,39857, +39858,39859,15724,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869, +39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882, +39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895, +39896,39897,39898,39899,39900,39901,39902,39903,39904,39905,39906,39907,39908, +39909,39910,15725,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920, +39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933, +15726,15727,39934,40001,15728,40002,40003,15729,15730,40004,15731,40005,40006, +40007,40008,40009,15732,15733,40010,40011,40012,15734,40013,40014,40015,40016, +40017,40018,15735,15736,40019,40020,15737,40021,40022,40023,40024,40025,40026, +40033,40034,40035,40036,40037,40038,40039,40040,40041,15738,40042,40043,40044, +40045,40046,40047,40048,15739,40049,40050,40051,40052,40053,40054,40055,40056, +40057,40058,40065,40066,40067,40068,40069,40070,40071,40072,40073,15740,40074, +40075,40076,40077,40078,40079,40080,15741,40081,40082,40083,15742,40084,40085, +40086,15905,40087,40088,40089,40090,40091,40092,40093,15906,15907,40094,40095, +40096,40097,40098,40099,40100,40101,40102,40103,15908,40104,40105,40106,40107, +40108,40109,40110,40111,40112,40113,40114,40115,40116,40117,40118,40119,40120, +40121,40122,40123,40124,40125,40126,40127,40128,40129,40130,15909,15910,40131, +40132,15911,40133,40134,40135,15912,40136,40137,40138,40139,40140,40141,40142, +15913,15914,40143,40144,40145,15915,40146,40147,40148,40149,40150,40151,15916, +40152,40153,40154,40155,40156,40157,40158,40159,40160,40161,40162,40163,40164, +40165,40166,40167,40168,40169,40170,15917,40171,40172,40173,40174,40175,40176, +40177,15918,40178,40179,40180,40181,40182,40183,40184,40185,40186,40187,40188, +40189,40190,40257,40258,40259,40260,40261,40262,40263,40264,40265,40266,40267, +40268,40269,40270,15919,40271,40272,40273,15920,40274,40275,40276,40277,40278, +40279,40280,40281,40282,40289,40290,40291,40292,40293,40294,40295,40296,40297, +40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,40309,40310, +40311,40312,40313,40314,40321,40322,40323,40324,40325,40326,40327,40328,40329, +15921,40330,40331,40332,40333,40334,40335,15922,15923,40336,40337,15924,40338, +40339,40340,15925,40341,15926,40342,40343,40344,40345,15927,15928,15929,40346, +40347,40348,40349,40350,40351,40352,40353,40354,40355,15930,40356,40357,40358, +15931,40359,40360,40361,15932,40362,40363,40364,40365,40366,40367,40368,15933, +40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,15934,15935, +40380,40381,15936,40382,40383,40384,15937,40385,40386,40387,40388,40389,40390, +40391,15938,15939,40392,15940,40393,15941,40394,40395,40396,40397,40398,40399, +15942,15943,40400,40401,15944,15945,15946,40402,15947,15948,15949,40403,40404, +40405,40406,15950,15951,15952,40407,15953,15954,15955,40408,40409,40410,15956, +15957,40411,15958,15959,40412,40413,15960,40414,40415,40416,15961,40417,40418, +40419,40420,40421,40422,40423,15962,15963,40424,15964,15965,15966,40425,40426, +40427,40428,40429,40430,15967,15968,40431,40432,15969,40433,40434,40435,15970, +40436,40437,15971,40438,40439,40440,40441,15972,15973,40442,15974,40443,15975, +40444,40445,40446,15976,40513,15977,15978,40514,40515,40516,15979,40517,40518, +40519,15980,40520,40521,40522,40523,40524,40525,40526,40527,15981,40528,40529, +40530,40531,40532,40533,40534,40535,40536,40537,15982,15983,40538,40545,15984, +15985,40546,15986,15987,15988,15989,40547,40548,40549,40550,40551,15990,15991, +15992,15993,15994,15995,15996,40552,15997,40553,15998,40554,16161,16162,40555, +40556,16163,40557,40558,40559,16164,40560,40561,40562,40563,40564,40565,40566, +16165,16166,40567,16167,40568,16168,40569,40570,40577,40578,40579,40580,16169, +16170,16171,40581,16172,40582,40583,40584,16173,40585,16174,16175,40586,40587, +40588,40589,16176,16177,16178,16179,16180,16181,40590,40591,40592,16182,16183, +16184,16185,40593,40594,40595,16186,40596,40597,40598,16187,40599,40600,40601, +40602,40603,40604,40605,16188,16189,40606,16190,16191,40607,40608,40609,40610, +40611,40612,40613,16192,16193,40614,40615,16194,40616,40617,40618,16195,16196, +16197,40619,16198,40620,40621,16199,16200,16201,40622,16202,40623,16203,40624, +16204,40625,40626,40627,40628,16205,16206,40629,40630,16207,40631,40632,40633, +16208,40634,40635,40636,40637,40638,40639,40640,16209,16210,40641,16211,16212, +16213,40642,40643,40644,40645,40646,40647,16214,16215,40648,40649,16216,40650, +40651,40652,40653,40654,40655,40656,40657,40658,40659,40660,16217,40661,40662, +16218,40663,16219,40664,40665,40666,40667,40668,40669,16220,16221,40670,40671, +16222,40672,40673,40674,16223,40675,40676,40677,40678,40679,40680,40681,16224, +16225,40682,16226,40683,16227,40684,40685,40686,40687,40688,40689,16228,16229, +40690,40691,16230,40692,40693,40694,16231,40695,40696,40697,40698,40699,40700, +40701,16232,16233,40702,16234,40769,16235,40770,40771,40772,40773,40774,40775, +16236,16237,40776,40777,16238,40778,40779,40780,16239,16240,16241,40781,40782, +40783,40784,40785,16242,16243,40786,16244,40787,16245,40788,40789,40790,40791, +40792,40793,16246,16247,40794,40801,16248,40802,40803,40804,16249,40805,40806, +40807,40808,40809,40810,40811,16250,16251,40812,40813,16252,16253,40814,40815, +40816,40817,40818,40819,16254,16417,40820,40821,16418,40822,40823,40824,16419, +40825,40826,40833,40834,40835,40836,40837,16420,16421,40838,40839,40840,16422, +40841,40842,40843,40844,40845,40846,16423,16424,40847,40848,16425,40849,40850, +40851,16426,40852,40853,40854,40855,40856,40857,40858,16427,16428,40859,16429, +40860,16430,40861,40862,40863,40864,40865,40866,16431,16432,40867,40868,16433, +40869,40870,40871,16434,40872,40873,40874,40875,40876,40877,40878,16435,16436, +40879,16437,40880,16438,40881,16439,40882,40883,40884,40885,16440,16441,40886, +40887,16442,40888,40889,40890,16443,40891,40892,40893,40894,40895,16444,40896, +16445,16446,40897,16447,40898,16448,16449,16450,16451,16452,16453,16454,16455, +40899,40900,40901,16456,40902,40903,40904,16457,40905,40906,40907,40908,40909, +40910,40911,16458,40912,40913,16459,40914,40915,40916,40917,40918,40919,40920, +40921,16460,16461,40922,40923,16462,40924,40925,40926,16463,16464,16465,40927, +40928,40929,40930,16466,16467,16468,40931,16469,16470,16471,16472,40932,40933, +40934,16473,40935,16474,16475,40936,40937,16476,40938,16477,16478,16479,40939, +16480,40940,40941,40942,40943,40944,16481,16482,40945,16483,16484,16485,16486, +40946,40947,40948,40949,40950,16487,16488,40951,40952,16489,40953,40954,40955, +16490,40956,40957,40958,41025,41026,41027,41028,16491,16492,41029,16493,16494, +16495,41030,41031,41032,41033,41034,41035,16496,16497,41036,41037,16498,41038, +16499,41039,16500,41040,41041,41042,41043,41044,41045,41046,16501,41047,41048, +41049,41050,16502,41057,41058,41059,41060,41061,41062,16503,41063,41064,41065, +16504,41066,41067,41068,16505,41069,41070,41071,41072,41073,41074,41075,41076, +41077,41078,41079,41080,41081,41082,41089,41090,41091,41092,41093,16506,16507, +41094,41095,16508,41096,41097,41098,16509,41099,16510,41100,41101,41102,41103, +41104,16673,16674,41105,16675,41106,16676,16677,41107,41108,41109,41110,41111, +16678,16679,41112,41113,16680,41114,41115,41116,16681,41117,41118,41119,41120, +41121,41122,41123,16682,16683,41124,16684,41125,16685,41126,41127,41128,41129, +41130,41131,16686,41132,41133,41134,16687,41135,41136,41137,16688,41138,41139, +41140,41141,41142,41143,41144,16689,16690,41145,41146,16691,16692,41147,41148, +41149,41150,41151,41152,16693,41153,41154,41155,41156,41157,41158,41159,41160, +41161,41162,41163,41164,41165,41166,41167,41168,41169,41170,41171,41172,41173, +41174,41175,41176,41177,41178,41179,16694,16695,41180,41181,16696,41182,41183, +41184,16697,41185,16698,41186,41187,41188,41189,41190,16699,16700,41191,16701, +41192,16702,16703,16704,41193,41194,41195,16705,16706,16707,41196,41197,41198, +41199,41200,41201,16708,41202,41203,41204,41205,41206,41207,41208,41209,16709, +41210,16710,41211,16711,41212,41213,41214,41281,41282,41283,16712,41284,41285, +41286,41287,41288,41289,41290,41291,41292,41293,41294,41295,41296,41297,41298, +41299,41300,41301,41302,16713,16714,41303,41304,41305,41306,41313,41314,16715, +41315,41316,41317,16716,41318,41319,41320,16717,41321,41322,41323,41324,41325, +41326,41327,16718,16719,41328,16720,41329,16721,41330,41331,41332,41333,41334, +41335,16722,16723,41336,41337,16724,41338,41345,41346,41347,41348,41349,41350, +41351,41352,41353,41354,41355,41356,41357,41358,41359,16725,41360,41361,41362, +41363,41364,41365,16726,16727,41366,41367,16728,41368,41369,41370,16729,16730, +16731,41371,41372,41373,41374,41375,16732,16733,41376,16734,41537,16735,41538, +41539,41540,41541,41542,41543,16736,41544,41545,41546,41547,41548,41549,41550, +41551,41552,41553,41554,41555,41556,41557,41558,41559,41560,41561,41562,16737, +41569,41570,41571,41572,41573,41574,41575,16738,41576,41577,41578,41579,41580, +41581,41582,41583,41584,41585,41586,41587,41588,41589,41590,41591,41592,41593, +41594,41601,41602,41603,41604,41605,41606,41607,41608,16739,16740,41609,41610, +16741,41611,41612,41613,16742,41614,41615,41616,41617,41618,41619,41620,16743, +16744,41621,16745,41622,41623,41624,41625,41626,41627,41628,41629,16746,41630, +41631,41632,16747,41793,41794,41795,16748,41796,41797,41798,41799,41800,41801, +41802,16749,41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,41813, +16750,16751,41814,41815,16752,41816,41817,41818,16753,41825,41826,41827,41828, +41829,41830,41831,16754,16755,41832,16756,41833,16757,41834,41835,41836,41837, +41838,41839,41840,41841,41842,41843,41844,41845,41846,41847,41848,41849,41850, +41857,41858,41859,41860,41861,41862,41863,41864,41865,41866,41867,41868,41869, +41870,41871,41872,41873,16758,16759,41874,41875,16760,41876,41877,16761,16762, +41878,16763,41879,41880,41881,41882,41883,16764,16765,41884,16766,41885,16929, +16930,41886,41887,16931,16932,41888,16933,16934,42049,42050,16935,42051,16936, +42052,16937,42053,42054,16938,42055,42056,42057,42058,16939,16940,42059,16941, +16942,16943,42060,42061,42062,42063,42064,42065,16944,16945,42066,42067,16946, +42068,42069,42070,16947,42071,42072,42073,42074,42081,42082,42083,16948,16949, +42084,16950,16951,16952,42085,42086,42087,42088,42089,42090,16953,42091,42092, +42093,16954,42094,42095,42096,42097,42098,42099,42100,42101,42102,42103,42104, +42105,42106,42113,42114,42115,16955,42116,42117,42118,42119,42120,42121,42122, +42123,42124,42125,42126,42127,42128,42129,42130,42131,42132,42133,42134,42135, +42136,42137,42138,42139,42140,42141,42142,42143,42144,42305,42306,42307,42308, +42309,16956,16957,42310,42311,16958,42312,42313,42314,16959,42315,42316,42317, +42318,42319,42320,42321,16960,16961,42322,16962,16963,16964,42323,42324,42325, +42326,42327,42328,16965,42329,42330,42337,42338,42339,42340,42341,42342,42343, +42344,42345,42346,42347,42348,42349,42350,42351,42352,42353,42354,16966,42355, +42356,42357,42358,42359,42360,16967,42361,42362,42369,42370,42371,42372,42373, +42374,42375,42376,42377,42378,42379,42380,42381,42382,42383,42384,42385,16968, +42386,42387,42388,42389,42390,42391,42392,42393,42394,42395,42396,42397,42398, +42399,42400,42561,42562,42563,42564,42565,42566,42567,42568,42569,42570,42571, +42572,42573,42574,42575,42576,42577,42578,42579,42580,16969,16970,42581,42582, +16971,42583,42584,42585,16972,42586,42593,42594,42595,42596,42597,42598,16973, +16974,42599,16975,42600,16976,42601,16977,42602,42603,42604,42605,16978,16979, +42606,42607,42608,42609,42610,42611,16980,42612,42613,42614,42615,42616,42617, +42618,42625,42626,42627,42628,16981,42629,42630,42631,42632,42633,42634,42635, +16982,42636,42637,42638,42639,42640,42641,42642,42643,42644,42645,42646,42647, +42648,42649,42650,42651,42652,42653,42654,16983,42655,42656,42817,42818,42819, +42820,42821,16984,42822,42823,42824,16985,42825,42826,42827,16986,42828,42829, +42830,42831,42832,42833,42834,16987,16988,42835,42836,42837,42838,42839,42840, +42841,42842,42849,42850,42851,42852,42853,42854,42855,42856,42857,42858,42859, +42860,42861,42862,42863,42864,42865,42866,42867,42868,42869,42870,42871,16989, +42872,42873,42874,42881,42882,42883,16990,16991,42884,42885,16992,42886,42887, +42888,16993,42889,42890,42891,42892,42893,42894,42895,16994,16995,42896,42897, +42898,16996,42899,42900,42901,42902,42903,42904,16997,42905,42906,42907,42908, +42909,42910,42911,42912,43073,43074,43075,43076,43077,43078,43079,43080,43081, +43082,43083,16998,16999,43084,43085,43086,43087,43088,43089,43090,43091,43092, +43093,43094,43095,43096,43097,43098,43105,43106,43107,43108,43109,43110,43111, +43112,43113,43114,43115,43116,43117,43118,43119,43120,43121,43122,43123,17000, +43124,43125,43126,43127,43128,43129,43130,43137,43138,43139,43140,43141,43142, +43143,43144,43145,43146,43147,43148,43149,43150,43151,43152,43153,43154,43155, +43156,17001,43157,43158,43159,43160,43161,43162,43163,43164,43165,43166,43167, +43168,43329,43330,43331,43332,43333,43334,43335,43336,43337,43338,43339,43340, +43341,43342,43343,17002,43344,43345,43346,43347,43348,43349,43350,43351,43352, +43353,43354,43361,43362,43363,43364,17003,43365,43366,17004,43367,17005,43368, +43369,43370,43371,43372,43373,43374,43375,43376,43377,43378,43379,43380,43381, +43382,43383,43384,43385,43386,43393,43394,43395,43396,43397,43398,43399,43400, +43401,43402,43403,43404,43405,43406,43407,17006,17007,43408,43409,17008,43410, +43411,43412,17009,43413,43414,43415,43416,43417,43418,43419,17010,17011,43420, +43421,43422,17012,17013,43423,43424,43585,43586,17014,17015,17016,43587,43588, +17017,43589,17018,43590,17019,43591,43592,43593,43594,43595,43596,43597,17020, +17021,43598,17022,17185,17186,17187,43599,43600,43601,43602,43603,17188,17189, +43604,43605,17190,43606,43607,43608,17191,43609,43610,43617,43618,43619,43620, +43621,17192,17193,43622,17194,17195,17196,43623,43624,43625,43626,43627,43628, +17197,43629,43630,43631,17198,43632,17199,43633,17200,43634,43635,43636,43637, +43638,43639,43640,17201,43641,43642,43649,43650,17202,43651,43652,43653,43654, +43655,43656,43657,43658,43659,43660,43661,43662,43663,43664,43665,43666,43667, +43668,43669,43670,43671,43672,43673,43674,43675,43676,43677,43678,43679,43680, +43841,43842,43843,43844,17203,17204,43845,43846,17205,43847,43848,43849,17206, +43850,43851,43852,43853,43854,43855,43856,17207,17208,43857,17209,17210,17211, +43858,43859,43860,43861,43862,43863,17212,17213,43864,43865,17214,43866,43873, +43874,17215,43875,43876,43877,43878,43879,43880,43881,17216,17217,43882,17218, +43883,17219,43884,43885,43886,43887,43888,43889,17220,43890,43891,43892,17221, +43893,43894,43895,43896,43897,43898,43905,43906,43907,43908,43909,43910,43911, +43912,43913,17222,43914,43915,43916,43917,43918,43919,43920,17223,43921,43922, +43923,17224,43924,43925,43926,43927,43928,43929,43930,43931,43932,43933,43934, +43935,43936,44097,44098,44099,17225,44100,44101,44102,44103,44104,44105,17226, +17227,44106,44107,17228,44108,44109,44110,17229,44111,44112,44113,44114,44115, +44116,44117,17230,17231,44118,17232,44119,17233,44120,44121,44122,44129,44130, +44131,17234,44132,44133,44134,17235,44135,44136,44137,17236,44138,44139,44140, +44141,44142,44143,44144,44145,44146,44147,44148,44149,17237,44150,44151,44152, +44153,44154,44161,44162,44163,44164,44165,44166,44167,44168,44169,44170,44171, +44172,44173,44174,44175,44176,44177,44178,44179,44180,44181,44182,44183,44184, +44185,44186,44187,44188,44189,17238,44190,44191,44192,17239,44353,44354,44355, +17240,44356,44357,44358,44359,44360,44361,44362,17241,17242,44363,17243,44364, +17244,44365,44366,44367,44368,44369,44370,17245,44371,44372,44373,44374,44375, +44376,44377,44378,44385,44386,44387,44388,44389,44390,44391,17246,44392,44393, +44394,44395,44396,44397,44398,44399,44400,44401,44402,17247,17248,44403,44404, +17249,44405,44406,44407,17250,44408,44409,44410,44417,44418,44419,44420,17251, +17252,44421,17253,44422,17254,44423,44424,44425,44426,44427,44428,17255,44429, +44430,44431,44432,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442, +44443,44444,44445,44446,44447,17256,44448,44609,44610,44611,44612,44613,44614, +17257,44615,44616,44617,17258,44618,44619,44620,44621,44622,44623,44624,44625, +44626,44627,44628,44629,44630,44631,44632,44633,44634,44641,44642,44643,44644, +44645,44646,17259,44647,44648,44649,17260,44650,44651,44652,17261,44653,44654, +44655,44656,44657,44658,44659,17262,17263,44660,17264,44661,17265,44662,44663, +44664,44665,44666,44673,17266,44674,44675,44676,17267,44677,44678,44679,17268, +44680,44681,44682,44683,44684,44685,44686,17269,44687,44688,44689,44690,17270, +44691,44692,44693,44694,44695,44696,17271,17272,44697,44698,17273,44699,44700, +44701,17274,44702,44703,44704,44865,44866,44867,44868,17275,17276,44869,17277, +44870,17278,44871,44872,44873,44874,44875,44876,44877,44878,44879,44880,44881, +44882,44883,44884,44885,44886,44887,44888,44889,44890,44897,44898,44899,44900, +44901,44902,44903,44904,44905,44906,44907,44908,44909,44910,17441,17442,44911, +44912,17443,44913,44914,17444,17445,17446,44915,44916,44917,44918,44919,44920, +17447,17448,44921,17449,44922,17450,44929,44930,44931,44932,44933,44934,17451, +17452,44935,44936,17453,44937,44938,44939,17454,44940,44941,44942,44943,44944, +44945,44946,17455,17456,44947,17457,44948,17458,44949,44950,44951,44952,44953, +44954,17459,17460,44955,44956,17461,44957,44958,44959,17462,44960,45121,45122, +45123,45124,45125,45126,17463,17464,45127,17465,17466,17467,45128,45129,45130, +45131,45132,45133,17468,17469,45134,45135,45136,45137,45138,45139,45140,45141, +45142,45143,45144,45145,45146,45153,45154,45155,45156,45157,45158,17470,45159, +45160,45161,45162,45163,45164,45165,45166,45167,45168,45169,45170,45171,45172, +45173,45174,45175,45176,45177,45178,45185,45186,45187,45188,45189,45190,45191, +45192,45193,45194,45195,45196,45197,45198,17471,17472,45199,45200,17473,45201, +45202,17474,17475,45203,45204,45205,45206,45207,45208,45209,17476,17477,45210, +17478,17479,17480,45211,45212,45213,45214,45215,45216,17481,17482,45377,45378, +17483,45379,45380,45381,17484,45382,45383,45384,45385,45386,45387,45388,17485, +17486,45389,17487,45390,17488,45391,45392,45393,45394,45395,45396,17489,45397, +45398,45399,17490,45400,45401,45402,17491,45409,45410,45411,45412,45413,45414, +45415,17492,17493,45416,17494,17495,17496,45417,45418,45419,45420,45421,45422, +17497,45423,45424,45425,45426,45427,45428,45429,45430,45431,45432,45433,45434, +45441,45442,45443,45444,45445,45446,45447,45448,45449,45450,45451,45452,45453, +45454,45455,17498,17499,45456,45457,17500,45458,45459,45460,17501,45461,45462, +45463,45464,45465,45466,45467,17502,17503,45468,17504,45469,17505,45470,45471, +45472,45633,45634,45635,17506,17507,45636,45637,17508,45638,45639,45640,17509, +45641,45642,45643,45644,45645,45646,45647,17510,45648,45649,45650,45651,17511, +45652,45653,45654,45655,45656,45657,17512,45658,45665,45666,45667,45668,45669, +45670,45671,45672,45673,45674,45675,45676,45677,45678,45679,45680,45681,45682, +45683,17513,45684,45685,45686,45687,45688,45689,17514,45690,45697,45698,45699, +45700,45701,45702,17515,45703,45704,45705,45706,45707,45708,45709,45710,45711, +45712,45713,45714,45715,45716,45717,45718,45719,45720,45721,17516,45722,45723, +45724,45725,45726,45727,45728,45889,45890,45891,45892,45893,45894,45895,45896, +45897,45898,45899,45900,45901,45902,45903,45904,45905,45906,45907,45908,17517, +17518,45909,45910,17519,45911,45912,45913,17520,45914,45921,45922,45923,45924, +45925,45926,17521,17522,45927,17523,45928,17524,45929,45930,45931,45932,45933, +45934,17525,45935,45936,45937,17526,45938,45939,45940,17527,45941,45942,45943, +45944,45945,45946,45953,45954,45955,45956,45957,45958,17528,45959,45960,45961, +45962,45963,45964,17529,45965,45966,45967,45968,45969,45970,45971,45972,45973, +45974,45975,45976,45977,45978,45979,45980,45981,45982,45983,45984,17530,46145, +46146,46147,46148,46149,46150,17531,17532,46151,46152,17533,46153,46154,46155, +17534,46156,46157,46158,46159,46160,46161,46162,17697,17698,46163,17699,46164, +17700,46165,46166,46167,46168,46169,46170,17701,46177,46178,46179,17702,46180, +46181,46182,17703,46183,46184,46185,46186,46187,46188,46189,17704,46190,46191, +46192,46193,46194,46195,46196,46197,46198,46199,46200,17705,17706,46201,46202, +17707,46209,46210,46211,17708,46212,46213,46214,46215,46216,46217,46218,17709, +17710,46219,46220,46221,17711,46222,46223,46224,46225,46226,46227,46228,46229, +46230,46231,46232,46233,46234,46235,46236,46237,46238,46239,46240,46401,46402, +46403,46404,46405,46406,46407,46408,46409,46410,46411,46412,46413,46414,46415, +17712,17713,46416,46417,17714,46418,46419,46420,17715,46421,46422,46423,46424, +46425,46426,46433,17716,17717,46434,17718,46435,17719,46436,46437,46438,46439, +46440,46441,17720,17721,46442,46443,17722,46444,46445,46446,17723,17724,46447, +46448,46449,46450,46451,46452,17725,17726,46453,17727,17728,17729,46454,46455, +46456,46457,46458,46465,17730,17731,46466,46467,17732,46468,46469,46470,17733, +46471,46472,46473,46474,46475,46476,46477,17734,17735,46478,17736,17737,17738, +46479,46480,46481,46482,46483,46484,17739,46485,46486,46487,46488,46489,46490, +46491,46492,46493,46494,46495,46496,46657,46658,46659,46660,46661,46662,46663, +46664,17740,46665,46666,46667,46668,46669,46670,46671,46672,46673,46674,46675, +46676,46677,46678,46679,46680,46681,46682,46689,46690,46691,46692,46693,46694, +46695,46696,46697,46698,46699,46700,46701,46702,46703,46704,17741,17742,46705, +46706,17743,46707,46708,46709,17744,46710,17745,46711,46712,46713,46714,46721, +17746,17747,46722,17748,17749,17750,46723,46724,46725,46726,46727,46728,17751, +17752,46729,46730,17753,46731,46732,46733,17754,46734,46735,46736,46737,46738, +46739,46740,17755,17756,46741,17757,46742,17758,46743,46744,46745,46746,46747, +46748,17759,46749,46750,46751,17760,46752,46913,46914,46915,46916,46917,46918, +46919,46920,46921,46922,46923,46924,46925,46926,17761,46927,46928,46929,46930, +46931,46932,46933,17762,46934,46935,46936,17763,46937,46938,46945,46946,46947, +46948,46949,46950,46951,46952,46953,46954,46955,46956,46957,46958,46959,46960, +46961,46962,46963,46964,46965,17764,17765,46966,46967,17766,46968,46969,46970, +17767,46977,46978,46979,46980,46981,46982,46983,17768,17769,46984,17770,46985, +17771,46986,46987,46988,46989,17772,46990,17773,46991,46992,46993,17774,46994, +46995,46996,46997,46998,46999,47000,47001,47002,47003,47004,47005,47006,47007, +47008,47169,47170,47171,47172,47173,47174,47175,47176,17775,47177,47178,47179, +47180,47181,47182,47183,47184,47185,47186,47187,47188,47189,47190,47191,47192, +47193,47194,47201,47202,47203,47204,47205,47206,47207,47208,47209,17776,47210, +47211,47212,17777,47213,47214,47215,47216,47217,47218,47219,47220,47221,47222, +47223,47224,47225,47226,17778,47233,17779,47234,47235,47236,47237,47238,47239, +17780,47240,47241,47242,47243,47244,47245,47246,47247,47248,47249,47250,47251, +47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,47264, +47425,47426,17781,17782,47427,47428,17783,47429,47430,47431,17784,47432,47433, +47434,47435,47436,47437,47438,17785,17786,47439,17787,47440,17788,47441,47442, +47443,47444,47445,47446,17789,47447,47448,47449,47450,47457,47458,47459,47460, +47461,47462,47463,47464,47465,47466,47467,47468,47469,47470,47471,17790,47472, +47473,47474,47475,47476,47477,47478,17953,47479,47480,47481,47482,47489,47490, +47491,47492,47493,47494,47495,47496,47497,47498,47499,47500,47501,47502,47503, +47504,47505,47506,47507,47508,47509,47510,47511,17954,17955,47512,47513,17956, +47514,47515,47516,17957,47517,47518,47519,47520,47681,47682,47683,17958,17959, +47684,47685,47686,17960,47687,47688,47689,47690,47691,47692,17961,47693,47694, +47695,17962,47696,47697,47698,17963,47699,47700,47701,47702,47703,47704,47705, +17964,47706,47713,47714,47715,17965,47716,47717,47718,47719,47720,47721,17966, +17967,47722,47723,17968,47724,47725,17969,17970,47726,17971,47727,47728,47729, +47730,47731,17972,17973,47732,17974,47733,47734,47735,47736,47737,47738,47745, +47746,17975,47747,47748,47749,17976,47750,47751,47752,17977,47753,47754,47755, +47756,47757,47758,47759,17978,17979,47760,47761,47762,47763,47764,47765,47766, +47767,47768,47769,17980,17981,47770,47771,17982,47772,47773,47774,17983,47775, +47776,47937,47938,47939,47940,47941,17984,17985,47942,17986,47943,17987,47944, +47945,47946,47947,47948,47949,17988,17989,17990,47950,17991,47951,47952,47953, +17992,47954,17993,47955,47956,47957,47958,47959,17994,17995,47960,17996,17997, +17998,47961,47962,47969,17999,47970,47971,18000,18001,47972,47973,18002,47974, +47975,47976,18003,47977,47978,47979,47980,47981,47982,47983,18004,18005,47984, +18006,18007,18008,47985,47986,47987,47988,47989,47990,18009,18010,47991,47992, +47993,47994,48001,48002,48003,48004,48005,48006,48007,48008,48009,48010,48011, +48012,48013,48014,48015,48016,48017,48018,48019,48020,48021,48022,48023,48024, +48025,48026,48027,48028,48029,48030,48031,48032,48193,48194,48195,48196,48197, +48198,48199,48200,48201,48202,48203,48204,48205,48206,48207,48208,48209,48210, +18011,18012,48211,48212,18013,48213,48214,48215,18014,48216,48217,48218,48225, +48226,48227,48228,18015,18016,48229,18017,18018,18019,48230,48231,48232,48233, +48234,48235,18020,18021,48236,48237,18022,48238,48239,48240,18023,48241,48242, +48243,48244,48245,48246,48247,18024,18025,48248,18026,48249,18027,48250,48257, +48258,48259,48260,48261,18028,48262,48263,48264,18029,48265,48266,48267,18030, +48268,48269,48270,48271,48272,48273,48274,18031,18032,48275,48276,18033,18034, +48277,48278,48279,48280,48281,48282,18035,48283,48284,48285,48286,48287,48288, +48449,18036,48450,48451,48452,48453,48454,48455,48456,48457,18037,48458,18038, +48459,48460,48461,48462,48463,48464,48465,48466,18039,18040,48467,48468,18041, +48469,48470,48471,18042,48472,48473,48474,48481,48482,48483,48484,18043,18044, +48485,18045,48486,18046,48487,48488,48489,48490,48491,48492,18209,48493,48494, +48495,48496,48497,48498,48499,48500,48501,48502,48503,48504,48505,48506,48513, +48514,48515,48516,48517,48518,18210,48519,48520,48521,48522,48523,48524,48525, +48526,48527,48528,48529,48530,48531,48532,48533,48534,48535,48536,48537,48538, +48539,48540,48541,48542,48543,48544,48705,48706,48707,48708,48709,48710,48711, +48712,18211,48713,48714,48715,18212,48716,48717,48718,48719,48720,48721,48722, +48723,48724,48725,48726,48727,48728,48729,48730,48737,48738,48739,48740,48741, +48742,48743,48744,18213,48745,48746,48747,18214,48748,48749,48750,18215,48751, +48752,48753,48754,48755,48756,48757,48758,18216,48759,18217,48760,48761,48762, +48769,48770,48771,48772,48773,18218,18219,48774,48775,18220,48776,48777,18221, +18222,48778,18223,48779,48780,48781,48782,48783,18224,18225,48784,18226,48785, +18227,48786,48787,48788,48789,48790,48791,18228,48792,48793,48794,48795,48796, +48797,48798,48799,48800,48961,48962,48963,48964,48965,48966,48967,48968,48969, +48970,48971,18229,48972,48973,48974,48975,48976,48977,48978,48979,48980,48981, +48982,48983,48984,48985,48986,48993,48994,48995,48996,48997,48998,48999,49000, +49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,18230,49012, +49013,49014,18231,49015,49016,49017,18232,49018,49025,49026,49027,49028,49029, +49030,18233,49031,49032,18234,49033,49034,49035,49036,49037,49038,49039,49040, +18235,49041,49042,49043,18236,49044,49045,49046,18237,49047,49048,49049,49050, +49051,49052,49053,18238,49054,49055,18239,49056,18240,49217,49218,49219,49220, +49221,49222,18241,49223,49224,49225,18242,49226,49227,49228,18243,49229,49230, +49231,49232,49233,49234,49235,18244,18245,49236,18246,49237,49238,49239,49240, +49241,49242,49249,49250,49251,49252,49253,49254,49255,49256,49257,49258,49259, +49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,49272, +49273,49274,49281,49282,49283,49284,18247,18248,49285,49286,18249,49287,49288, +49289,18250,49290,49291,49292,49293,49294,49295,49296,18251,18252,49297,18253, +49298,18254,49299,49300,49301,49302,49303,49304,18255,18256,49305,49306,18257, +49307,49308,49309,18258,49310,49311,49312,49473,18259,49474,49475,18260,18261, +49476,18262,49477,18263,49478,49479,49480,49481,49482,49483,18264,18265,49484, +49485,18266,49486,49487,49488,18267,49489,49490,49491,49492,49493,49494,49495, +18268,18269,49496,18270,18271,18272,49497,49498,49505,49506,49507,49508,18273, +49509,49510,49511,49512,49513,49514,49515,49516,49517,49518,49519,49520,49521, +49522,49523,49524,49525,49526,49527,49528,18274,49529,49530,49537,49538,49539, +49540,49541,49542,49543,49544,49545,49546,49547,49548,49549,49550,49551,49552, +49553,49554,49555,49556,49557,49558,49559,49560,49561,49562,49563,49564,49565, +49566,49567,49568,18275,18276,49729,49730,18277,49731,49732,49733,18278,49734, +18279,49735,49736,49737,49738,49739,18280,18281,49740,18282,49741,18283,49742, +49743,49744,49745,49746,49747,18284,18285,49748,49749,18286,49750,49751,49752, +18287,49753,49754,49761,49762,49763,49764,49765,18288,18289,49766,18290,49767, +18291,49768,49769,49770,49771,49772,49773,18292,18293,49774,49775,18294,49776, +49777,49778,18295,49779,49780,49781,49782,49783,49784,49785,18296,18297,49786, +18298,18299,18300,49793,49794,49795,49796,49797,49798,18301,49799,49800,49801, +18302,49802,49803,49804,18465,49805,49806,49807,49808,49809,49810,49811,49812, +18466,49813,49814,49815,49816,49817,49818,49819,49820,49821,49822,18467,18468, +49823,49824,18469,49985,49986,49987,18470,49988,49989,49990,49991,18471,49992, +49993,18472,18473,49994,18474,49995,18475,49996,49997,49998,18476,49999,50000, +18477,18478,50001,50002,18479,50003,50004,50005,18480,50006,50007,50008,50009, +50010,50017,50018,50019,50020,50021,18481,50022,18482,50023,50024,50025,50026, +50027,50028,18483,18484,50029,50030,18485,50031,50032,50033,50034,50035,50036, +50037,50038,50039,50040,50041,50042,50049,50050,18486,50051,18487,50052,50053, +50054,50055,50056,50057,18488,18489,50058,50059,18490,50060,50061,50062,18491, +50063,50064,50065,50066,50067,50068,50069,50070,18492,50071,18493,50072,18494, +50073,50074,50075,50076,50077,50078,18495,50079,50080,50241,18496,50242,50243, +50244,18497,50245,50246,50247,50248,50249,50250,50251,50252,18498,50253,18499, +50254,50255,50256,50257,50258,50259,50260,50261,18500,18501,50262,50263,18502, +50264,50265,50266,18503,50273,50274,50275,50276,18504,50277,50278,18505,50279, +50280,18506,50281,18507,50282,50283,50284,50285,50286,50287,18508,50288,50289, +50290,18509,50291,50292,50293,18510,50294,50295,50296,50297,50298,50305,50306, +18511,50307,50308,50309,50310,18512,50311,50312,50313,50314,50315,50316,18513, +18514,50317,50318,18515,50319,50320,50321,18516,50322,50323,50324,50325,50326, +50327,50328,50329,50330,50331,50332,50333,18517,50334,50335,50336,50497,50498, +50499,18518,18519,50500,50501,18520,50502,50503,50504,18521,50505,50506,50507, +50508,50509,50510,50511,18522,18523,50512,18524,50513,18525,50514,50515,50516, +50517,50518,50519,18526,18527,50520,50521,18528,50522,50529,50530,18529,50531, +50532,50533,50534,50535,50536,50537,18530,50538,50539,18531,50540,18532,50541, +50542,50543,50544,50545,50546,18533,18534,50547,50548,18535,50549,18536,18537, +18538,18539,50550,50551,50552,50553,50554,50561,18540,18541,50562,18542,50563, +18543,50564,50565,50566,18544,50567,50568,18545,50569,50570,50571,18546,50572, +50573,50574,18547,50575,50576,50577,50578,50579,50580,50581,18548,18549,50582, +50583,50584,18550,50585,50586,50587,50588,50589,50590,18551,18552,50591,50592, +18553,50753,50754,50755,18554,50756,50757,50758,50759,50760,50761,50762,18555, +18556,50763,18557,50764,18558,50765,50766,50767,50768,50769,50770,19280,19286, +19303,19791,19816,20013,20347,20514,20536,20560,20573,20820,20821,20824,20827, +20828,20829,20830,20831,20832,20834,20835,20836,20837,20838,20840,20841,20842, +20843,20845,20847,20848,20850,20854,20858,20860,20861,20862,21026,21027,21031, +21032,21033,21034,21035,21037,21042,21054,21058,21059,21060,21062,21063,21064, +21065,21066,21067,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078, +21079,21081,21082,21086,21087,21089,21090,21092,21093,21094,21095,21096,21097, +21098,21099,21104,21105,21106,21107,21108,21109,21111,21112,21606,21628,21797, +21803,21806,22072,22093,22347,22372,23365,23396,23589,23845,23893,23924,24188, +24190,24371,24417,24424,24689,24877,24941,25461,25633,25641,25902,25905,25906, +25913,25915,25916,25924,25934,25936,25938,25942,25978,25979,25980,25982,26145, +26148,26151,26157,26159,26160,26161,26163,26167,26168,26172,26180,26182,26183, +26186,26194,26198,26201,26204,26207,26209,26212,26213,26214,26216,26218,26219, +26220,26223,26225,26226,26229,26230,26231,26233,26401,26406,26409,26410,26412, +26413,26416,26431,26433,26438,26439,26443,26445,26447,26448,26451,26463,26468, +26470,26487,26727,26728,26736,26737,26743,26745,26747,26750,26919,26924,26956, +26999,27201,27237,27252,27255,27260,27262,27428,27431,27433,27434,27450,27451, +27453,27457,27458,27462,27463,27468,27471,27472,27473,27474,27480,27686,27687, +27690,27695,27696,27697,27698,27701,27704,27706,27712,27713,27717,27718,27721, +27722,27733,27741,27742,27745,27748,27751,27752,27767,27768,27770,27937,27938, +27939,28014,28251,29245,29306,29489,29735,29806,30324,30326,30520,30536,30547, +30811,30832,31265,31266,31334,31785,8993,8994,8995,8996,8997,8998,8999,9000, +9001,9002,9003,9004,9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015, +9016,9017,9018,9019,9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030, +9031,9032,9033,9034,9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045, +9046,9047,9048,9049,9050,9051,8492,9053,9054,9055,9056,9057,9058,9059,9060, +9061,9062,9063,9064,9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075, +9076,9077,9078,9079,9080,9081,9082,9083,9084,9085,8742,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,8523,8524,8574,9086,N,8525,9052, +}; + +static const struct unim_index cp949_encmap[256] = { +{__cp949_encmap+0,161,254},{__cp949_encmap+94,17,103},{__cp949_encmap+181,199, +221},{__cp949_encmap+204,145,201},{__cp949_encmap+261,1,81},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+342,21,172},{ +__cp949_encmap+494,3,212},{__cp949_encmap+704,0,165},{__cp949_encmap+870,18,18 +},{__cp949_encmap+871,96,233},{__cp949_encmap+1009,0,209},{__cp949_encmap+1219 +,5,109},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{__cp949_encmap+1324,0,246},{__cp949_encmap+1571,49,142},{__cp949_encmap+ +1665,0,127},{__cp949_encmap+1793,128,221},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{__cp949_encmap+1887,0,251},{__cp949_encmap+2139,1,250},{ +__cp949_encmap+2389,2,255},{__cp949_encmap+2643,0,253},{__cp949_encmap+2897,0, +255},{__cp949_encmap+3153,5,248},{__cp949_encmap+3397,3,250},{__cp949_encmap+ +3645,4,254},{__cp949_encmap+3896,6,250},{__cp949_encmap+4141,3,252},{ +__cp949_encmap+4391,0,253},{__cp949_encmap+4645,15,255},{__cp949_encmap+4886, +1,233},{__cp949_encmap+5119,5,250},{__cp949_encmap+5365,1,253},{__cp949_encmap ++5618,7,254},{__cp949_encmap+5866,2,251},{__cp949_encmap+6116,1,255},{ +__cp949_encmap+6371,15,251},{__cp949_encmap+6608,1,255},{__cp949_encmap+6863, +0,255},{__cp949_encmap+7119,1,247},{__cp949_encmap+7366,13,254},{ +__cp949_encmap+7608,0,255},{__cp949_encmap+7864,6,255},{__cp949_encmap+8114,0, +254},{__cp949_encmap+8369,18,250},{__cp949_encmap+8602,0,255},{__cp949_encmap+ +8858,2,251},{__cp949_encmap+9108,4,236},{__cp949_encmap+9341,8,243},{ +__cp949_encmap+9577,11,251},{__cp949_encmap+9818,23,255},{__cp949_encmap+10051 +,1,254},{__cp949_encmap+10305,1,253},{__cp949_encmap+10558,4,255},{ +__cp949_encmap+10810,0,253},{__cp949_encmap+11064,10,254},{__cp949_encmap+ +11309,1,247},{__cp949_encmap+11556,1,252},{__cp949_encmap+11808,0,254},{ +__cp949_encmap+12063,1,243},{__cp949_encmap+12306,2,251},{__cp949_encmap+12556 +,1,251},{__cp949_encmap+12807,0,255},{__cp949_encmap+13063,15,233},{ +__cp949_encmap+13282,7,254},{__cp949_encmap+13530,0,251},{__cp949_encmap+13782 +,9,156},{__cp949_encmap+13930,54,252},{__cp949_encmap+14129,0,253},{ +__cp949_encmap+14383,2,254},{__cp949_encmap+14636,5,254},{__cp949_encmap+14886 +,1,253},{__cp949_encmap+15139,3,252},{__cp949_encmap+15389,17,255},{ +__cp949_encmap+15628,2,254},{__cp949_encmap+15881,0,254},{__cp949_encmap+16136 +,5,253},{__cp949_encmap+16385,7,248},{__cp949_encmap+16627,0,254},{ +__cp949_encmap+16882,0,154},{__cp949_encmap+17037,55,253},{__cp949_encmap+ +17236,4,243},{__cp949_encmap+17476,10,254},{__cp949_encmap+17721,3,253},{ +__cp949_encmap+17972,0,253},{__cp949_encmap+18226,2,245},{__cp949_encmap+18470 +,13,252},{__cp949_encmap+18710,4,246},{__cp949_encmap+18953,4,127},{ +__cp949_encmap+19077,119,226},{__cp949_encmap+19185,28,251},{__cp949_encmap+ +19409,0,255},{__cp949_encmap+19665,0,254},{__cp949_encmap+19920,3,255},{ +__cp949_encmap+20173,1,238},{__cp949_encmap+20411,26,232},{__cp949_encmap+ +20618,13,246},{__cp949_encmap+20852,9,250},{__cp949_encmap+21094,26,244},{ +__cp949_encmap+21313,7,156},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+21463,0,255},{ +__cp949_encmap+21719,0,255},{__cp949_encmap+21975,0,255},{__cp949_encmap+22231 +,0,255},{__cp949_encmap+22487,0,255},{__cp949_encmap+22743,0,255},{ +__cp949_encmap+22999,0,255},{__cp949_encmap+23255,0,255},{__cp949_encmap+23511 +,0,255},{__cp949_encmap+23767,0,255},{__cp949_encmap+24023,0,255},{ +__cp949_encmap+24279,0,255},{__cp949_encmap+24535,0,255},{__cp949_encmap+24791 +,0,255},{__cp949_encmap+25047,0,255},{__cp949_encmap+25303,0,255},{ +__cp949_encmap+25559,0,255},{__cp949_encmap+25815,0,255},{__cp949_encmap+26071 +,0,255},{__cp949_encmap+26327,0,255},{__cp949_encmap+26583,0,255},{ +__cp949_encmap+26839,0,255},{__cp949_encmap+27095,0,255},{__cp949_encmap+27351 +,0,255},{__cp949_encmap+27607,0,255},{__cp949_encmap+27863,0,255},{ +__cp949_encmap+28119,0,255},{__cp949_encmap+28375,0,255},{__cp949_encmap+28631 +,0,255},{__cp949_encmap+28887,0,255},{__cp949_encmap+29143,0,255},{ +__cp949_encmap+29399,0,255},{__cp949_encmap+29655,0,255},{__cp949_encmap+29911 +,0,255},{__cp949_encmap+30167,0,255},{__cp949_encmap+30423,0,255},{ +__cp949_encmap+30679,0,255},{__cp949_encmap+30935,0,255},{__cp949_encmap+31191 +,0,255},{__cp949_encmap+31447,0,255},{__cp949_encmap+31703,0,255},{ +__cp949_encmap+31959,0,255},{__cp949_encmap+32215,0,255},{__cp949_encmap+32471 +,0,163},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+32635,0,255},{ +__cp949_encmap+32891,0,11},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp949_encmap+ +32903,1,230}, +}; diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_tw.h b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_tw.h index ec3f9f7468e..72b1a25e96a 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/mappings_tw.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/mappings_tw.h @@ -1,2633 +1,2633 @@ -static const ucs2_t __big5_decmap[16702] = { -12288,65292,12289,12290,65294,8226,65307,65306,65311,65281,65072,8230,8229, -65104,65380,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075, -9588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309, -65081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087, -65088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,65115,65116,65117, -65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,167, -12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,12963, -8453,8254,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,65120, -65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,8734,8786, -8801,65122,65123,65124,65125,65126,8764,8745,8746,8869,8736,8735,8895,13266, -13265,8747,8750,8757,8756,9792,9794,9793,9737,8593,8595,8592,8594,8598,8599, -8601,8600,8741,8739,65295,65340,65295,65340,65284,165,12306,162,163,65285, -65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,13217,13198, -13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,31950,9601, -9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,9609,9532, -9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,9582,9584,9583,9552, -9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,65297,65298,65299, -65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,8548,8549,8550,8551, -8552,8553,12321,12322,12323,12324,12325,12326,12327,12328,12329,21313,21316, -21317,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324, -65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337, -65338,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356, -65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369, -65370,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931, -932,933,934,935,936,937,945,946,947,948,949,950,951,952,953,954,955,956,957, -958,959,960,961,963,964,965,966,967,968,969,12549,12550,12551,12552,12553, -12554,12555,12556,12557,12558,12559,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,12560,12561,12562,12563,12564,12565,12566,12567, -12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580, -12581,12582,12583,12584,12585,729,713,714,711,715,19968,20057,19969,19971, -20035,20061,20102,20108,20154,20799,20837,20843,20960,20992,20993,21147,21269, -21313,21340,21448,19977,19979,19976,19978,20011,20024,20961,20037,20040,20063, -20062,20110,20129,20800,20995,21242,21315,21449,21475,22303,22763,22805,22823, -22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,24037,24049,24050, -24051,24062,24178,24318,24331,24339,25165,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19985,19984,19981,20013,20016,20025,20043, -23609,20104,20113,20117,20114,20116,20130,20161,20160,20163,20166,20167,20173, -20170,20171,20164,20803,20801,20839,20845,20846,20844,20887,20982,20998,20999, -21000,21243,21246,21247,21270,21305,21320,21319,21317,21342,21380,21451,21450, -21453,22764,22825,22827,22826,22829,23380,23569,23588,23610,23663,24052,24187, -24319,24340,24341,24515,25096,25142,25163,25166,25903,25991,26007,26020,26041, -26085,26352,26376,26408,27424,27490,27513,27595,27604,27611,27663,27700,28779, -29226,29238,29243,29255,29273,29275,29356,29579,19993,19990,19989,19988,19992, -20027,20045,20047,20046,20197,20184,20180,20181,20182,20183,20195,20196,20185, -20190,20805,20804,20873,20874,20908,20985,20986,20984,21002,21152,21151,21253, -21254,21271,21277,20191,21322,21321,21345,21344,21359,21358,21435,21487,21476, -21491,21484,21486,21481,21480,21500,21496,21493,21483,21478,21482,21490,21489, -21488,21477,21485,21499,22235,22234,22806,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22830,22833,22900,22902,23381,23427,23612, -24040,24039,24038,24066,24067,24179,24188,24321,24344,24343,24517,25098,25171, -25172,25170,25169,26021,26086,26414,26412,26410,26411,26413,27491,27597,27665, -27664,27704,27713,27712,27710,29359,29572,29577,29916,29926,29976,29983,29992, -29993,30000,30001,30002,30003,30091,30333,30382,30399,30446,30683,30690,30707, -31034,31166,31348,31435,19998,19999,20050,20051,20073,20121,20132,20134,20133, -20223,20233,20249,20234,20245,20237,20240,20241,20239,20210,20214,20219,20208, -20211,20221,20225,20235,20809,20807,20806,20808,20840,20849,20877,20912,21015, -21009,21010,21006,21014,21155,21256,21281,21280,21360,21361,21513,21519,21516, -21514,21520,21505,21515,21508,21521,21517,21512,21507,21518,21510,21522,22240, -22238,22237,22323,22320,22312,22317,22316,22319,22313,22809,22810,22839,22840, -22916,22904,22915,22909,22905,22914,22913,23383,23384,23431,23432,23429,23433, -23546,23574,23673,24030,24070,24182,24180,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24335,24347,24537,24534,25102,25100,25101, -25104,25187,25179,25176,25910,26089,26088,26092,26093,26354,26355,26377,26429, -26420,26417,26421,27425,27492,27515,27670,27741,27735,27737,27743,27744,27728, -27733,27745,27739,27725,27726,28784,29279,29277,30334,31481,31859,31992,32566, -32650,32701,32769,32771,32780,32786,32819,32895,32905,32907,32908,33251,33258, -33267,33276,33292,33307,33311,33390,33394,33406,34411,34880,34892,34915,35199, -38433,20018,20136,20301,20303,20295,20311,20318,20276,20315,20309,20272,20304, -20305,20285,20282,20280,20291,20308,20284,20294,20323,20316,20320,20271,20302, -20278,20313,20317,20296,20314,20812,20811,20813,20853,20918,20919,21029,21028, -21033,21034,21032,21163,21161,21162,21164,21283,21363,21365,21533,21549,21534, -21566,21542,21582,21543,21574,21571,21555,21576,21570,21531,21545,21578,21561, -21563,21560,21550,21557,21558,21536,21564,21568,21553,21547,21535,21548,22250, -22256,22244,22251,22346,22353,22336,22349,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22343,22350,22334,22352,22351,22331,22767, -22846,22941,22930,22952,22942,22947,22937,22934,22925,22948,22931,22922,22949, -23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,23614,23696, -23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,24420,24418, -24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,25105,25220, -25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,25234,25199, -25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,26463,26446, -26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,27493,27599, -27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,27760,27788, -27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,27796,27800, -27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,29996,29995, -30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,32918,32915, -32925,32920,32923,32922,32946,33391,33426,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33419,33421,35211,35282,35328,35895,35910, -35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,36806,36805,36804, -24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,38446,38449,38442, -38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,20381,20365,20339, -20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,20347,20374,20350, -20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,20925,20989,21051, -21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,21332,21331,21329, -21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,21624,21653,21632, -21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,21658,21602,21608, -21643,21629,21646,22266,22403,22391,22378,22377,22369,22374,22372,22396,22812, -22857,22855,22856,22852,22868,22974,22971,22996,22969,22958,22993,22982,22992, -22989,22987,22995,22986,22959,22963,22994,22981,23391,23396,23395,23447,23450, -23448,23452,23449,23451,23578,23624,23621,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23622,23735,23713,23736,23721,23723,23729, -23731,24088,24090,24086,24085,24091,24081,24184,24218,24215,24220,24213,24214, -24310,24358,24359,24361,24448,24449,24447,24444,24541,24544,24573,24565,24575, -24591,24596,24623,24629,24598,24618,24597,24609,24615,24617,24619,24603,25110, -25109,25151,25150,25152,25215,25289,25292,25284,25279,25282,25273,25298,25307, -25259,25299,25300,25291,25288,25256,25277,25276,25296,25305,25287,25293,25269, -25306,25265,25304,25302,25303,25286,25260,25294,25918,26023,26044,26106,26132, -26131,26124,26118,26114,26126,26112,26127,26133,26122,26119,26381,26379,26477, -26507,26517,26481,26524,26483,26487,26503,26525,26519,26479,26480,26495,26505, -26494,26512,26485,26522,26515,26492,26474,26482,27427,27494,27495,27519,27667, -27675,27875,27880,27891,27825,27852,27877,27827,27837,27838,27836,27874,27819, -27861,27859,27832,27844,27833,27841,27822,27863,27845,27889,27839,27835,27873, -27867,27850,27820,27887,27868,27862,27872,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28821,28814,28818,28810,28825,29228,29229, -29240,29256,29287,29289,29376,29390,29401,29399,29392,29609,29608,29599,29611, -29605,30013,30109,30105,30106,30340,30402,30450,30452,30693,30717,31038,31040, -31041,31177,31176,31354,31353,31482,31998,32596,32652,32651,32773,32954,32933, -32930,32945,32929,32939,32937,32948,32938,32943,33253,33278,33293,33459,33437, -33433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470, -33463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046, -37319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738, -38750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419, -20406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407, -20823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193, -21187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688, -21670,21683,21703,21698,21693,21674,21697,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21700,21704,21679,21675,21681,21691,21673, -21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,22865, -22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,23014, -23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,23627, -23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,24421, -24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,24616, -24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,25366, -25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,25332, -25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,26143, -26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,26613, -26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,26585, -26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,27954, -27946,27969,27941,27916,27953,27934,27927,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27963,27965,27966,27958,27931,27893,27961, -27943,27960,27945,27950,27957,27918,27947,28843,28858,28851,28844,28847,28845, -28856,28846,28836,29232,29298,29295,29300,29417,29408,29409,29623,29642,29627, -29618,29645,29632,29619,29978,29997,30031,30028,30030,30027,30123,30116,30117, -30114,30115,30328,30342,30343,30344,30408,30406,30403,30405,30465,30457,30456, -30473,30475,30462,30460,30471,30684,30722,30740,30732,30733,31046,31049,31048, -31047,31161,31162,31185,31186,31179,31359,31361,31487,31485,31869,32002,32005, -32000,32009,32007,32004,32006,32568,32654,32703,32772,32784,32781,32785,32822, -32982,32997,32986,32963,32964,32972,32993,32987,32974,32990,32996,32989,33268, -33314,33511,33539,33541,33507,33499,33510,33540,33509,33538,33545,33490,33495, -33521,33537,33500,33492,33489,33502,33491,33503,33519,33542,34384,34425,34427, -34426,34893,34923,35201,35284,35336,35330,35331,35998,36000,36212,36211,36276, -36557,36556,36848,36838,36834,36842,36837,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36845,36843,36836,36840,37066,37070,37057, -37059,37195,37194,37325,38274,38480,38475,38476,38477,38754,38761,38859,38893, -38899,38913,39080,39131,39135,39318,39321,20056,20147,20492,20493,20515,20463, -20518,20517,20472,20521,20502,20486,20540,20511,20506,20498,20497,20474,20480, -20500,20520,20465,20513,20491,20505,20504,20467,20462,20525,20522,20478,20523, -20489,20860,20900,20901,20898,20941,20940,20934,20939,21078,21084,21076,21083, -21085,21290,21375,21407,21405,21471,21736,21776,21761,21815,21756,21733,21746, -21766,21754,21780,21737,21741,21729,21769,21742,21738,21734,21799,21767,21757, -21775,22275,22276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057, -23064,23068,23071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403, -23640,23472,23475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632, -23789,23805,23803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235, -24237,24231,24369,24466,24465,24464,24665,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24675,24677,24656,24661,24685,24681,24687, -24708,24735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422, -25406,25391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384, -25421,25420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188, -26181,26177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690, -26708,26665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666, -26693,26643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888, -28010,28053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994, -28020,28009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872, -28879,29241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664, -29674,29662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141, -30140,30137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504, -30697,30768,30759,30776,30749,30772,30775,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30757,30765,30752,30751,30770,31061,31056, -31072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209, -31192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034, -32020,32016,32021,32026,32028,32013,32025,32027,32570,32607,32660,32709,32705, -32774,32792,32789,32793,32791,32829,32831,33009,33026,33008,33029,33005,33012, -33030,33016,33011,33032,33021,33034,33020,33007,33261,33260,33280,33296,33322, -33323,33320,33324,33467,33579,33618,33620,33610,33592,33616,33609,33589,33588, -33615,33586,33593,33590,33559,33600,33585,33576,33603,34388,34442,34474,34451, -34468,34473,34444,34467,34460,34928,34935,34945,34946,34941,34937,35352,35344, -35342,35340,35349,35338,35351,35347,35350,35343,35345,35912,35962,35961,36001, -36002,36215,36524,36562,36564,36559,36785,36865,36870,36855,36864,36858,36852, -36867,36861,36869,36856,37013,37089,37085,37090,37202,37197,37196,37336,37341, -37335,37340,37337,38275,38498,38499,38497,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38491,38493,38500,38488,38494,38587,39138, -39340,39592,39640,39717,39730,39740,20094,20602,20605,20572,20551,20547,20556, -20570,20553,20581,20598,20558,20565,20597,20596,20599,20559,20495,20591,20589, -20828,20885,20976,21098,21103,21202,21209,21208,21205,21264,21263,21273,21311, -21312,21310,21443,26364,21830,21866,21862,21828,21854,21857,21827,21834,21809, -21846,21839,21845,21807,21860,21816,21806,21852,21804,21859,21811,21825,21847, -22280,22283,22281,22495,22533,22538,22534,22496,22500,22522,22530,22581,22519, -22521,22816,22882,23094,23105,23113,23142,23146,23104,23100,23138,23130,23110, -23114,23408,23495,23493,23492,23490,23487,23494,23561,23560,23559,23648,23644, -23645,23815,23814,23822,23835,23830,23842,23825,23849,23828,23833,23844,23847, -23831,24034,24120,24118,24115,24119,24247,24248,24246,24245,24254,24373,24375, -24407,24428,24425,24427,24471,24473,24478,24472,24481,24480,24476,24703,24739, -24713,24736,24744,24779,24756,24806,24765,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24773,24763,24757,24796,24764,24792,24789, -24774,24799,24760,24794,24775,25114,25115,25160,25504,25511,25458,25494,25506, -25509,25463,25447,25496,25514,25457,25513,25481,25475,25499,25451,25512,25476, -25480,25497,25505,25516,25490,25487,25472,25467,25449,25448,25466,25949,25942, -25937,25945,25943,21855,25935,25944,25941,25940,26012,26011,26028,26063,26059, -26060,26062,26205,26202,26212,26216,26214,26206,26361,21207,26395,26753,26799, -26786,26771,26805,26751,26742,26801,26791,26775,26800,26755,26820,26797,26758, -26757,26772,26781,26792,26783,26785,26754,27442,27578,27627,27628,27691,28046, -28092,28147,28121,28082,28129,28108,28132,28155,28154,28165,28103,28107,28079, -28113,28078,28126,28153,28088,28151,28149,28101,28114,28186,28085,28122,28139, -28120,28138,28145,28142,28136,28102,28100,28074,28140,28095,28134,28921,28937, -28938,28925,28911,29245,29309,29313,29468,29467,29462,29459,29465,29575,29701, -29706,29699,29702,29694,29709,29920,29942,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29943,29980,29986,30053,30054,30050,30064, -30095,30164,30165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524, -30518,30520,30522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520, -31528,31515,31532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113, -32046,32057,32060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670, -32666,32716,32718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072, -33060,33282,33333,33335,33334,33337,33678,33694,33688,33656,33698,33686,33725, -33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,34389,24426, -34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,34974,34952, -34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,35377,35373, -35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,36199,36198, -36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,36880,36885, -36894,36896,36879,36898,36886,36891,36884,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37096,37101,37117,37207,37326,37365,37350, -37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,38516,38518,38519, -38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,40565,40575,40613, -40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,26368,20977,21106, -21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,21927,21884,21898, -21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,21934,21919,21822, -21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,22575,22570,22580, -22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,23194,23167,23186, -23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,23601,23884,23888, -23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,24258,24260,24380, -24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,24867,24826,24853, -24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,25119,25161,25507, -25484,25551,25536,25577,25545,25542,25549,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25554,25571,25552,25569,25558,25581,25582, -25462,25588,25578,25563,25682,25562,25593,25950,25958,25954,25955,26001,26000, -26031,26222,26224,26228,26230,26223,26257,26234,26238,26231,26366,26367,26399, -26397,26874,26837,26848,26840,26839,26885,26847,26869,26862,26855,26873,26834, -26866,26851,26827,26829,26893,26898,26894,26825,26842,26990,26875,27454,27450, -27453,27544,27542,27580,27631,27694,27695,27692,28207,28216,28244,28193,28210, -28263,28234,28192,28197,28195,28187,28251,28248,28196,28246,28270,28205,28198, -28271,28212,28237,28218,28204,28227,28189,28222,28363,28297,28185,28238,28259, -28228,28274,28265,28255,28953,28954,28966,28976,28961,28982,29038,28956,29260, -29316,29312,29494,29477,29492,29481,29754,29738,29747,29730,29733,29749,29750, -29748,29743,29723,29734,29736,29989,29990,30059,30058,30178,30171,30179,30169, -30168,30174,30176,30331,30332,30358,30355,30388,30428,30543,30701,30813,30828, -30831,31245,31240,31243,31237,31232,31384,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31383,31382,31461,31459,31561,31574,31558, -31568,31570,31572,31565,31563,31567,31569,31903,31909,32094,32080,32104,32085, -32043,32110,32114,32097,32102,32098,32112,32115,21892,32724,32725,32779,32850, -32901,33109,33108,33099,33105,33102,33081,33094,33086,33100,33107,33140,33298, -33308,33769,33795,33784,33805,33760,33733,33803,33729,33775,33777,33780,33879, -33802,33776,33804,33740,33789,33778,33738,33848,33806,33796,33756,33799,33748, -33759,34395,34527,34521,34541,34516,34523,34532,34512,34526,34903,35009,35010, -34993,35203,35222,35387,35424,35413,35422,35388,35393,35412,35419,35408,35398, -35380,35386,35382,35414,35937,35970,36015,36028,36019,36029,36033,36027,36032, -36020,36023,36022,36031,36024,36234,36229,36225,36302,36317,36299,36314,36305, -36300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918, -37122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389, -37392,37383,37393,38292,38287,38283,38289,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38291,38290,38286,38538,38542,38539,38525, -38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,38860, -38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,40653, -40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,20679, -21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,21990, -21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,21961, -22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,22626, -22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,23913, -23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,24863, -24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,24845, -24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,25628, -25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,26248, -26262,26244,26264,26253,26371,27028,26989,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26970,26999,26976,26964,26997,26928,27010, -26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,27506,27584, -27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,28357,28325, -28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,28340,29006, -29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,28998,29032, -29014,29242,29266,29495,29509,29503,29502,29807,29786,29781,29791,29790,29761, -29759,29785,29787,29788,30070,30072,30208,30192,30209,30194,30193,30202,30207, -30196,30195,30430,30431,30555,30571,30566,30558,30563,30585,30570,30572,30556, -30565,30568,30562,30702,30862,30896,30871,30872,30860,30857,30844,30865,30867, -30847,31098,31103,31105,33836,31165,31260,31258,31264,31252,31263,31262,31391, -31392,31607,31680,31584,31598,31591,31921,31923,31925,32147,32121,32145,32129, -32143,32091,32622,32617,32618,32626,32681,32680,32676,32854,32856,32902,32900, -33137,33136,33144,33125,33134,33139,33131,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33145,33146,33126,33285,33351,33922,33911, -33853,33841,33909,33894,33899,33865,33900,33883,33852,33845,33889,33891,33897, -33901,33862,34398,34396,34399,34553,34579,34568,34567,34560,34558,34555,34562, -34563,34566,34570,34905,35039,35028,35033,35036,35032,35037,35041,35018,35029, -35026,35228,35299,35435,35442,35443,35430,35433,35440,35463,35452,35427,35488, -35441,35461,35437,35426,35438,35436,35449,35451,35390,35432,35938,35978,35977, -36042,36039,36040,36036,36018,36035,36034,36037,36321,36319,36328,36335,36339, -36346,36330,36324,36326,36530,36611,36617,36606,36618,36767,36786,36939,36938, -36947,36930,36948,36924,36949,36944,36935,36943,36942,36941,36945,36926,36929, -37138,37143,37228,37226,37225,37321,37431,37463,37432,37437,37440,37438,37467, -37451,37476,37457,37428,37449,37453,37445,37433,37439,37466,38296,38552,38548, -38549,38605,38603,38601,38602,38647,38651,38649,38646,38742,38772,38774,38928, -38929,38931,38922,38930,38924,39164,39156,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39165,39166,39347,39345,39348,39649,40169, -40578,40718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689, -20721,20686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039, -22013,22036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296, -22294,22645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820, -22890,22889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521, -23525,23526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149, -24151,24148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930, -24931,24927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722, -25681,25703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036, -27048,27029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085, -27053,27084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404, -28457,28478,28448,28460,28431,28418,28450,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28415,28399,28422,28465,28472,28466,28451, -28437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053, -29066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805, -29956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561, -30913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401, -31469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620, -31929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177, -32186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735, -32862,32858,32903,33104,33152,33167,33160,33162,33151,33154,33255,33274,33287, -33300,33310,33355,33993,33983,33990,33988,33945,33950,33970,33948,33995,33976, -33984,34003,33936,33980,34001,33994,34623,34588,34619,34594,34597,34612,34584, -34645,34615,34601,35059,35074,35060,35065,35064,35069,35048,35098,35055,35494, -35468,35486,35491,35469,35489,35475,35492,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35498,35493,35496,35480,35473,35482,35495, -35946,35981,35980,36051,36049,36050,36203,36249,36245,36348,36628,36626,36629, -36627,36771,36960,36952,36956,36963,36953,36958,36962,36957,36955,37145,37144, -37150,37237,37240,37239,37236,37496,37504,37509,37528,37526,37499,37523,37532, -37544,37500,37521,38305,38312,38313,38307,38309,38308,38553,38556,38555,38604, -38610,38656,38780,38789,38902,38935,38936,39087,39089,39171,39173,39180,39177, -39361,39599,39600,39654,39745,39746,40180,40182,40179,40636,40763,40778,20740, -20736,20731,20725,20729,20738,20744,20745,20741,20956,21127,21128,21129,21133, -21130,21232,21426,22062,22075,22073,22066,22079,22068,22057,22099,22094,22103, -22132,22070,22063,22064,22656,22687,22686,22707,22684,22702,22697,22694,22893, -23305,23291,23307,23285,23308,23304,23534,23532,23529,23531,23652,23653,23965, -23956,24162,24159,24161,24290,24282,24287,24285,24291,24288,24392,24433,24503, -24501,24950,24935,24942,24925,24917,24962,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24956,24944,24939,24958,24999,24976,25003, -24974,25004,24986,24996,24980,25006,25134,25705,25711,25721,25758,25778,25736, -25744,25776,25765,25747,25749,25769,25746,25774,25773,25771,25754,25772,25753, -25762,25779,25973,25975,25976,26286,26283,26292,26289,27171,27167,27112,27137, -27166,27161,27133,27169,27155,27146,27123,27138,27141,27117,27153,27472,27470, -27556,27589,27590,28479,28540,28548,28497,28518,28500,28550,28525,28507,28536, -28526,28558,28538,28528,28516,28567,28504,28373,28527,28512,28511,29087,29100, -29105,29096,29270,29339,29518,29527,29801,29835,29827,29822,29824,30079,30240, -30249,30239,30244,30246,30241,30242,30362,30394,30436,30606,30599,30604,30609, -30603,30923,30917,30906,30922,30910,30933,30908,30928,31295,31292,31296,31293, -31287,31291,31407,31406,31661,31665,31684,31668,31686,31687,31681,31648,31692, -31946,32224,32244,32239,32251,32216,32236,32221,32232,32227,32218,32222,32233, -32158,32217,32242,32249,32629,32631,32687,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32745,32806,33179,33180,33181,33184,33178, -33176,34071,34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028, -34085,34047,34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636, -34643,34907,34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524, -35477,35531,35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547, -35916,35918,35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074, -36065,36205,36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382, -36538,36637,36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968, -36973,36983,37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559, -37610,37548,37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660, -38662,38663,38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187, -39186,39192,39389,39376,39391,39387,39377,39381,39378,39385,39607,39662,39663, -39719,39749,39748,39799,39791,40198,40201,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40195,40617,40638,40654,22696,40786,20754, -20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,22105,22123,22137, -22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,22134,22721,22718, -22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,24977,25001,24970, -25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,25788,25818,25796, -25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,26297,26308,26311, -26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,27233,27211,27207, -27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,28580,28609,28583, -28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,29138,29128,29141, -29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,29855,29854,29922, -29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,30629,30952,30938, -30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,31761,31689,31716, -31707,31713,31721,31718,31957,31958,32266,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32273,32264,32283,32291,32286,32285,32265, -32272,32633,32690,32752,32753,32750,32808,33203,33193,33192,33275,33288,33368, -33369,34122,34137,34120,34152,34153,34115,34121,34157,34154,34142,34691,34719, -34718,34722,34701,34913,35114,35122,35109,35115,35105,35242,35238,35558,35578, -35563,35569,35584,35548,35559,35566,35582,35585,35586,35575,35565,35571,35574, -35580,35947,35949,35987,36084,36420,36401,36404,36418,36409,36405,36667,36655, -36664,36659,36776,36774,36981,36980,36984,36978,36988,36986,37172,37266,37664, -37686,37624,37683,37679,37666,37628,37675,37636,37658,37648,37670,37665,37653, -37678,37657,38331,38567,38568,38570,38613,38670,38673,38678,38669,38675,38671, -38747,38748,38758,38808,38960,38968,38971,38967,38957,38969,38948,39184,39208, -39198,39195,39201,39194,39405,39394,39409,39608,39612,39675,39661,39720,39825, -40213,40227,40230,40232,40210,40219,40664,40660,40845,40860,20778,20767,20769, -20786,21237,22158,22144,22160,22149,22151,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22159,22741,22739,22737,22734,23344,23338, -23332,23418,23607,23656,23996,23994,23997,23992,24171,24396,24509,25033,25026, -25031,25062,25035,25138,25140,25806,25802,25816,25824,25840,25830,25836,25841, -25826,25837,25986,25987,26329,26326,27264,27284,27268,27298,27292,27355,27299, -27262,27287,27280,27296,27484,27566,27610,27656,28632,28657,28639,28640,28635, -28644,28651,28655,28544,28652,28641,28649,28629,28654,28656,29159,29151,29166, -29158,29157,29165,29164,29172,29152,29237,29254,29552,29554,29865,29872,29862, -29864,30278,30274,30284,30442,30643,30634,30640,30636,30631,30637,30703,30967, -30970,30964,30959,30977,31143,31146,31319,31423,31751,31757,31742,31735,31756, -31712,31968,31964,31966,31970,31967,31961,31965,32302,32318,32326,32311,32306, -32323,32299,32317,32305,32325,32321,32308,32313,32328,32309,32319,32303,32580, -32755,32764,32881,32882,32880,32879,32883,33222,33219,33210,33218,33216,33215, -33213,33225,33214,33256,33289,33393,34218,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34180,34174,34204,34193,34196,34223,34203, -34183,34216,34186,34407,34752,34769,34739,34770,34758,34731,34747,34746,34760, -34763,35131,35126,35140,35128,35133,35244,35598,35607,35609,35611,35594,35616, -35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,36425, -36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,36994, -36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,37656, -37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,38584, -38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,39850, -39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,22165, -22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,25851, -25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,27487, -27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,29176, -29559,29557,29863,29887,29973,30294,30296,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30290,30653,30655,30651,30652,30990,31150, -31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,31975,32340, -32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,33229,33231, -33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,34796,34802, -34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,36451,36454, -36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,37328,37780, -37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,38358,38352, -38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,38989,38991, -38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,39683,39686, -39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,40672,40725, -40748,20787,22181,22750,22751,22754,23541,40848,24300,25074,25079,25078,25077, -25856,25871,26336,26333,27365,27357,27354,27347,28699,28703,28712,28698,28701, -28693,28696,29190,29197,29272,29346,29560,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29562,29885,29898,29923,30087,30086,30303, -30305,30663,31001,31153,31339,31337,31806,31807,31800,31805,31799,31808,32363, -32365,32377,32361,32362,32645,32371,32694,32697,32696,33240,34281,34269,34282, -34261,34276,34277,34295,34811,34821,34829,34809,34814,35168,35167,35158,35166, -35649,35676,35672,35657,35674,35662,35663,35654,35673,36104,36106,36476,36466, -36487,36470,36460,36474,36468,36692,36686,36781,37002,37003,37297,37294,37857, -37841,37855,37827,37832,37852,37853,37846,37858,37837,37848,37860,37847,37864, -38364,38580,38627,38698,38695,38753,38876,38907,39006,39000,39003,39100,39237, -39241,39446,39449,39693,39912,39911,39894,39899,40329,40289,40306,40298,40300, -40594,40599,40595,40628,21240,22184,22199,22198,22196,22204,22756,23360,23363, -23421,23542,24009,25080,25082,25880,25876,25881,26342,26407,27372,28734,28720, -28722,29200,29563,29903,30306,30309,31014,31018,31020,31019,31431,31478,31820, -31811,31821,31983,31984,36782,32381,32380,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32386,32588,32768,33242,33382,34299,34297, -34321,34298,34310,34315,34311,34314,34836,34837,35172,35258,35320,35696,35692, -35686,35695,35679,35691,36111,36109,36489,36481,36485,36482,37300,37323,37912, -37891,37885,38369,38704,39108,39250,39249,39336,39467,39472,39479,39477,39955, -39949,40569,40629,40680,40751,40799,40803,40801,20791,20792,22209,22208,22210, -22804,23660,24013,25084,25086,25885,25884,26005,26345,27387,27396,27386,27570, -28748,29211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349, -34330,34851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490, -36493,36491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370, -38712,38713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764, -39761,39981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807, -20796,20795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489, -28753,28760,29568,29924,30090,30318,30316,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31155,31840,31839,32894,32893,33247,35186, -35183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717, -38718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995, -40403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348, -27408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865, -35722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635, -39636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321, -30322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312, -37994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572, -40573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313, -38002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522, -39525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015, -40474,29224,39530,39729,40475,40478,31858,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12542,12445,12446,12293,12353,12354,12355, -12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368, -12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381, -12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394, -12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407, -12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420, -12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433, -12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459, -12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472, -12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485, -12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498, -12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511, -12512,12513,12514,12515,12516,12517,12518,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12519,12520,12521,12522,12523,12524,12525, -12526,12527,12528,12529,12530,12531,12532,12533,12534,1044,1045,1025,1046, -1047,1048,1049,1050,1051,1052,1059,1060,1061,1062,1063,1064,1065,1066,1067, -1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081, -1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, -1097,1098,1099,1100,1101,1102,1103,9312,9313,9314,9315,9316,9317,9318,9319, -9320,9321,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,20034,20060,20981, -21274,21378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982, -20014,20115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568, -24063,26081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189, -20186,21004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668, -23667,24068,24192,24194,24521,25097,25168,27669,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27702,27715,27711,27707,29358,29360, -29578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232, -20253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158, -21282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908, -22917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,23678,24031, -24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,25185,25190, -25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,26426,26431, -26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,28785,29278, -29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,33407,34381, -35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,20283,20322, -20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,20287,20321, -20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,21391,21552, -21559,21546,21588,21573,21529,21532,21541,21528,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21565,21583,21569,21544,21540,21575, -22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,22848,22950,22936, -22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,23592,23594,23693, -23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,24074,24078,24203, -24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,24528,24557,24552, -24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,24564,25146,25219, -25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,25224,25207,25213, -25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,26457,26453,26444, -26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,27755,27780,27787, -27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,27763,27749,27771, -27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,29381,29589,29591, -29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,32917,32921,32912, -32914,32924,33424,33423,33413,33422,33425,33427,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33418,33411,33412,35960,36809,36799, -37023,37025,37029,37022,37031,37024,38448,38440,38447,38445,20019,20376,20348, -20357,20349,20352,20359,20342,20340,20361,20356,20343,20300,20375,20330,20378, -20345,20353,20344,20368,20380,20372,20382,20370,20354,20373,20331,20334,20894, -20924,20926,21045,21042,21043,21062,21041,21180,21258,21259,21308,21394,21396, -21639,21631,21633,21649,21634,21640,21611,21626,21630,21605,21612,21620,21606, -21645,21615,21601,21600,21656,21603,21607,21604,22263,22265,22383,22386,22381, -22379,22385,22384,22390,22400,22389,22395,22387,22388,22370,22376,22397,22796, -22853,22965,22970,22991,22990,22962,22988,22977,22966,22972,22979,22998,22961, -22973,22976,22984,22964,22983,23394,23397,23443,23445,23620,23623,23726,23716, -23712,23733,23727,23720,23724,23711,23715,23725,23714,23722,23719,23709,23717, -23734,23728,23718,24087,24084,24089,24360,24354,24355,24356,24404,24450,24446, -24445,24542,24549,24621,24614,24601,24626,24587,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24628,24586,24599,24627,24602,24606, -24620,24610,24589,24592,24622,24595,24593,24588,24585,24604,25108,25149,25261, -25268,25297,25278,25258,25270,25290,25262,25267,25263,25275,25257,25264,25272, -25917,26024,26043,26121,26108,26116,26130,26120,26107,26115,26123,26125,26117, -26109,26129,26128,26358,26378,26501,26476,26510,26514,26486,26491,26520,26502, -26500,26484,26509,26508,26490,26527,26513,26521,26499,26493,26497,26488,26489, -26516,27429,27520,27518,27614,27677,27795,27884,27883,27886,27865,27830,27860, -27821,27879,27831,27856,27842,27834,27843,27846,27885,27890,27858,27869,27828, -27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857, -28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398, -29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606, -29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451, -30449,30448,30453,30712,30716,30713,30715,30714,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30711,31042,31039,31173,31352,31355, -31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,33472, -33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,33441, -33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,36811, -36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,38460, -38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,20411, -20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,21309, -21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,21687, -21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,21680, -22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,22437, -22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,23037, -23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,23021, -23464,23628,23760,23768,23756,23767,23755,23771,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23774,23770,23753,23751,23754,23766, -23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,24099,24096, -24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,24631,24633, -24660,24690,24670,24645,24659,24647,24649,24667,24652,24640,24642,24671,24612, -24644,24664,24678,24686,25154,25155,25295,25357,25355,25333,25358,25347,25323, -25337,25359,25356,25336,25334,25344,25363,25364,25338,25365,25339,25328,25921, -25923,26026,26047,26166,26145,26162,26165,26140,26150,26146,26163,26155,26170, -26141,26164,26169,26158,26383,26384,26561,26610,26568,26554,26588,26555,26616, -26584,26560,26551,26565,26603,26596,26591,26549,26573,26547,26615,26614,26606, -26595,26562,26553,26574,26599,26608,26546,26620,26566,26605,26572,26542,26598, -26587,26618,26569,26570,26563,26602,26571,27432,27522,27524,27574,27606,27608, -27616,27680,27681,27944,27956,27949,27935,27964,27967,27922,27914,27866,27955, -27908,27929,27962,27930,27921,27904,27933,27970,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27905,27928,27959,27907,27919,27968, -27911,27936,27948,27912,27938,27913,27920,28855,28831,28862,28849,28848,28833, -28852,28853,28841,29249,29257,29258,29292,29296,29299,29294,29386,29412,29416, -29419,29407,29418,29414,29411,29573,29644,29634,29640,29637,29625,29622,29621, -29620,29675,29631,29639,29630,29635,29638,29624,29643,29932,29934,29998,30023, -30024,30119,30122,30329,30404,30472,30467,30468,30469,30474,30455,30459,30458, -30695,30696,30726,30737,30738,30725,30736,30735,30734,30729,30723,30739,31050, -31052,31051,31045,31044,31189,31181,31183,31190,31182,31360,31358,31441,31488, -31489,31866,31864,31865,31871,31872,31873,32003,32008,32001,32600,32657,32653, -32702,32775,32782,32783,32788,32823,32984,32967,32992,32977,32968,32962,32976, -32965,32995,32985,32988,32970,32981,32969,32975,32983,32998,32973,33279,33313, -33428,33497,33534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516, -33505,33522,33525,33548,33531,33526,33520,33514,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33508,33504,33530,33523,33517,34423, -34420,34428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835, -36833,36846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332, -37331,38484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528, -20507,20469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533, -20527,20529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082, -21074,21086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735, -21747,21732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751, -21752,21728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470, -22461,22460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062, -23085,23086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555, -23638,23636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238, -24234,24236,24371,24368,24423,24669,24666,24679,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24641,24738,24712,24704,24722,24705, -24733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430, -25388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396, -25432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930, -25926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650, -26697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671, -26702,26692,26676,26653,26642,26644,26662,26664,26670,26701,26682,26661,26656, -27436,27439,27437,27441,27444,27501,32898,27528,27622,27620,27624,27619,27618, -27623,27685,28026,28003,28004,28022,27917,28001,28050,27992,28002,28013,28015, -28049,28045,28143,28031,28038,27998,28007,28000,28055,28016,28028,27999,28034, -28056,27951,28008,28043,28030,28032,28036,27926,28035,28027,28029,28021,28048, -28892,28883,28881,28893,28875,32569,28898,28887,28882,28894,28896,28884,28877, -28869,28870,28871,28890,28878,28897,29250,29304,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29303,29302,29440,29434,29428,29438, -29430,29427,29435,29441,29651,29657,29669,29654,29628,29671,29667,29673,29660, -29650,29659,29652,29661,29658,29655,29656,29672,29918,29919,29940,29941,29985, -30043,30047,30128,30145,30139,30148,30144,30143,30134,30138,30346,30409,30493, -30491,30480,30483,30482,30499,30481,30485,30489,30490,30498,30503,30755,30764, -30754,30773,30767,30760,30766,30763,30753,30761,30771,30762,30769,31060,31067, -31055,31068,31059,31058,31057,31211,31212,31200,31214,31213,31210,31196,31198, -31197,31366,31369,31365,31371,31372,31370,31367,31448,31504,31492,31507,31493, -31503,31496,31498,31502,31497,31506,31876,31889,31882,31884,31880,31885,31877, -32030,32029,32017,32014,32024,32022,32019,32031,32018,32015,32012,32604,32609, -32606,32608,32605,32603,32662,32658,32707,32706,32704,32790,32830,32825,33018, -33010,33017,33013,33025,33019,33024,33281,33327,33317,33587,33581,33604,33561, -33617,33573,33622,33599,33601,33574,33564,33570,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33602,33614,33563,33578,33544,33596, -33613,33558,33572,33568,33591,33583,33577,33607,33605,33612,33619,33566,33580, -33611,33575,33608,34387,34386,34466,34472,34454,34445,34449,34462,34439,34455, -34438,34443,34458,34437,34469,34457,34465,34471,34453,34456,34446,34461,34448, -34452,34883,34884,34925,34933,34934,34930,34944,34929,34943,34927,34947,34942, -34932,34940,35346,35911,35927,35963,36004,36003,36214,36216,36277,36279,36278, -36561,36563,36862,36853,36866,36863,36859,36868,36860,36854,37078,37088,37081, -37082,37091,37087,37093,37080,37083,37079,37084,37092,37200,37198,37199,37333, -37346,37338,38492,38495,38588,39139,39647,39727,20095,20592,20586,20577,20574, -20576,20563,20555,20573,20594,20552,20557,20545,20571,20554,20578,20501,20549, -20575,20585,20587,20579,20580,20550,20544,20590,20595,20567,20561,20944,21099, -21101,21100,21102,21206,21203,21293,21404,21877,21878,21820,21837,21840,21812, -21802,21841,21858,21814,21813,21808,21842,21829,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21772,21810,21861,21838,21817,21832, -21805,21819,21824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528, -22509,22525,22536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508, -22497,22542,22524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876, -23136,23128,23125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123, -23140,23127,23107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116, -23152,23145,23111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838, -23819,23837,23834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843, -23839,23854,24126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470, -24479,24714,24720,24710,24766,24752,24762,24787,24788,24783,24804,24793,24797, -24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,25482,25474, -25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,25454,25519, -25461,25500,25453,25518,25468,25508,25403,25503,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25464,25477,25473,25489,25485,25456, -25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,26759,26768,26780, -26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,26740,26802,26767, -26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,26774,26763,26784, -26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,27447,27448,27537, -27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,28076,28137,28130, -28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,28124,28125,28123, -28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,28112,28146,28115, -28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,28940,28912,28932, -28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,28930,28942,29310, -29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,29439,29455,29470, -29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,29692,29695,29708, -29707,29684,29704,30052,30051,30158,30162,30159,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30155,30156,30161,30160,30351,30345, -30419,30521,30511,30509,30513,30514,30516,30515,30525,30501,30523,30517,30792, -30802,30793,30797,30794,30796,30758,30789,30800,31076,31079,31081,31082,31075, -31083,31073,31163,31226,31224,31222,31223,31375,31380,31376,31541,31559,31540, -31525,31536,31522,31524,31539,31512,31530,31517,31537,31531,31533,31535,31538, -31544,31514,31523,31892,31896,31894,31907,32053,32061,32056,32054,32058,32069, -32044,32041,32065,32071,32062,32063,32074,32059,32040,32611,32661,32668,32669, -32667,32714,32715,32717,32720,32721,32711,32719,32713,32799,32798,32795,32839, -32835,32840,33048,33061,33049,33051,33069,33055,33068,33054,33057,33045,33063, -33053,33058,33297,33336,33331,33338,33332,33330,33396,33680,33699,33704,33677, -33658,33651,33700,33652,33679,33665,33685,33689,33653,33684,33705,33661,33667, -33676,33693,33691,33706,33675,33662,33701,33711,33672,33687,33712,33663,33702, -33671,33710,33654,33690,34393,34390,34495,34487,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34498,34497,34501,34490,34480,34504, -34489,34483,34488,34508,34484,34491,34492,34499,34493,34494,34898,34953,34965, -34984,34978,34986,34970,34961,34977,34975,34968,34983,34969,34971,34967,34980, -34988,34956,34963,34958,35202,35286,35289,35285,35376,35367,35372,35358,35897, -35899,35932,35933,35965,36005,36221,36219,36217,36284,36290,36281,36287,36289, -36568,36574,36573,36572,36567,36576,36577,36900,36875,36881,36892,36876,36897, -37103,37098,37104,37108,37106,37107,37076,37099,37100,37097,37206,37208,37210, -37203,37205,37356,37364,37361,37363,37368,37348,37369,37354,37355,37367,37352, -37358,38266,38278,38280,38524,38509,38507,38513,38511,38591,38762,38916,39141, -39319,20635,20629,20628,20638,20619,20643,20611,20620,20622,20637,20584,20636, -20626,20610,20615,20831,20948,21266,21265,21412,21415,21905,21928,21925,21933, -21879,22085,21922,21907,21896,21903,21941,21889,21923,21906,21924,21885,21900, -21926,21887,21909,21921,21902,22284,22569,22583,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22553,22558,22567,22563,22568,22517, -22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,22587, -22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,23189, -23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,23183, -23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,23875, -23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,23857, -23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,24408, -24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,24854, -24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,24836, -24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,25546, -25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,25555, -25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,25948, -25960,25957,25996,26013,26014,26030,26064,26066,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26236,26220,26235,26240,26225,26233, -26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,26895,26838, -26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,26992,26804, -26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,26903,26830, -26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,26823,27449, -27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,27696,28156, -28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,28225,28253, -28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,28252,28257, -28209,28200,28256,28273,28267,28217,28194,28208,28243,28261,28199,28280,28260, -28279,28245,28281,28242,28262,28213,28214,28250,28960,28958,28975,28923,28974, -28977,28963,28965,28962,28978,28959,28968,28986,28955,29259,29274,29320,29321, -29318,29317,29323,29458,29451,29488,29474,29489,29491,29479,29490,29485,29478, -29475,29493,29452,29742,29740,29744,29739,29718,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29722,29729,29741,29745,29732,29731, -29725,29737,29728,29746,29947,29999,30063,30060,30183,30170,30177,30182,30173, -30175,30180,30167,30357,30354,30426,30534,30535,30532,30541,30533,30538,30542, -30539,30540,30686,30700,30816,30820,30821,30812,30829,30833,30826,30830,30832, -30825,30824,30814,30818,31092,31091,31090,31088,31234,31242,31235,31244,31236, -31385,31462,31460,31562,31547,31556,31560,31564,31566,31552,31576,31557,31906, -31902,31912,31905,32088,32111,32099,32083,32086,32103,32106,32079,32109,32092, -32107,32082,32084,32105,32081,32095,32078,32574,32575,32613,32614,32674,32672, -32673,32727,32849,32847,32848,33022,32980,33091,33098,33106,33103,33095,33085, -33101,33082,33254,33262,33271,33272,33273,33284,33340,33341,33343,33397,33595, -33743,33785,33827,33728,33768,33810,33767,33764,33788,33782,33808,33734,33736, -33771,33763,33727,33793,33757,33765,33752,33791,33761,33739,33742,33750,33781, -33737,33801,33807,33758,33809,33798,33730,33779,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33749,33786,33735,33745,33770,33811, -33731,33772,33774,33732,33787,33751,33762,33819,33755,33790,34520,34530,34534, -34515,34531,34522,34538,34525,34539,34524,34540,34537,34519,34536,34513,34888, -34902,34901,35002,35031,35001,35000,35008,35006,34998,35004,34999,35005,34994, -35073,35017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392, -35415,35416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968, -36026,36030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310, -36316,36303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590, -36581,36597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911, -37126,37164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123, -37217,37220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388, -37376,37394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381, -37398,38267,38285,38284,38288,38535,38526,38536,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38537,38531,38528,38594,38600,38595, -38641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150, -20669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657, -20683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968, -21963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986, -21974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601, -22639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236, -23243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242, -23220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882, -23909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139, -24261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901, -24886,24882,24878,24902,24879,24911,24873,24896,25120,37224,25123,25125,25124, -25541,25585,25579,25616,25618,25609,25632,25636,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25651,25667,25631,25621,25624,25657, -25655,25634,25635,25612,25638,25648,25640,25665,25653,25647,25610,25626,25664, -25637,25639,25611,25575,25627,25646,25633,25614,25967,26002,26067,26246,26252, -26261,26256,26251,26250,26265,26260,26232,26400,26982,26975,26936,26958,26978, -26993,26943,26949,26986,26937,26946,26967,26969,27002,26952,26953,26933,26988, -26931,26941,26981,26864,27000,26932,26985,26944,26991,26948,26998,26968,26945, -26996,26956,26939,26955,26935,26972,26959,26961,26930,26962,26927,27003,26940, -27462,27461,27459,27458,27464,27457,27547,64013,27643,27644,27641,27639,27640, -28315,28374,28360,28303,28352,28319,28307,28308,28320,28337,28345,28358,28370, -28349,28353,28318,28361,28343,28336,28365,28326,28367,28338,28350,28355,28380, -28376,28313,28306,28302,28301,28324,28321,28351,28339,28368,28362,28311,28334, -28323,28999,29012,29010,29027,29024,28993,29021,29026,29042,29048,29034,29025, -28994,29016,28995,29003,29040,29023,29008,29011,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28996,29005,29018,29263,29325,29324, -29329,29328,29326,29500,29506,29499,29498,29504,29514,29513,29764,29770,29771, -29778,29777,29783,29760,29775,29776,29774,29762,29766,29773,29780,29921,29951, -29950,29949,29981,30073,30071,27011,30191,30223,30211,30199,30206,30204,30201, -30200,30224,30203,30198,30189,30197,30205,30361,30389,30429,30549,30559,30560, -30546,30550,30554,30569,30567,30548,30553,30573,30688,30855,30874,30868,30863, -30852,30869,30853,30854,30881,30851,30841,30873,30848,30870,30843,31100,31106, -31101,31097,31249,31256,31257,31250,31255,31253,31266,31251,31259,31248,31395, -31394,31390,31467,31590,31588,31597,31604,31593,31602,31589,31603,31601,31600, -31585,31608,31606,31587,31922,31924,31919,32136,32134,32128,32141,32127,32133, -32122,32142,32123,32131,32124,32140,32148,32132,32125,32146,32621,32619,32615, -32616,32620,32678,32677,32679,32731,32732,32801,33124,33120,33143,33116,33129, -33115,33122,33138,26401,33118,33142,33127,33135,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33092,33121,33309,33353,33348,33344, -33346,33349,34033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926, -33895,33840,33869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850, -33844,33914,33859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887, -33904,33849,33870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896, -33918,33860,33835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518, -34549,34637,34552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022, -35038,35035,35034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298, -35292,35302,35446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457, -35444,35450,35900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200, -36201,36241,36236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332, -36337,36334,36304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609, -36608,36613,36615,36616,36610,36619,36946,36927,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36932,36937,36925,37136,37133,37135, -37137,37142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427, -37477,37470,37507,37422,37450,37446,37485,37484,37455,37472,37479,37487,37430, -37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,37462,37426,38303, -38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,38648,38645,38771, -38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,39346,39344,39349, -39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,20695,20712,20723, -20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,20952,21120,21121, -21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,22044,22017,22035, -22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,22662,22657,22655, -22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,22676,22671,22782, -22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,23266,23264,23259, -23276,23262,23261,23257,23272,23263,23415,23520,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23523,23651,23938,23936,23933,23942, -23930,23937,23927,23946,23945,23944,23934,23932,23949,23929,23935,24152,24153, -24147,24280,24273,24279,24270,24284,24277,24281,24274,24276,24388,24387,24431, -24502,24876,24872,24897,24926,24945,24947,24914,24915,24946,24940,24960,24948, -24916,24954,24923,24933,24891,24938,24929,24918,25129,25127,25131,25643,25677, -25691,25693,25716,25718,25714,25715,25725,25717,25702,25766,25678,25730,25694, -25692,25675,25683,25696,25680,25727,25663,25708,25707,25689,25701,25719,25971, -26016,26273,26272,26271,26373,26372,26402,27057,27062,27081,27040,27086,27030, -27056,27052,27068,27025,27033,27022,27047,27021,27049,27070,27055,27071,27076, -27069,27044,27092,27065,27082,27034,27087,27059,27027,27050,27041,27038,27097, -27031,27024,27074,27061,27045,27078,27466,27469,27467,27550,27551,27552,27587, -27588,27646,28366,28405,28401,28419,28453,28408,28471,28411,28462,28425,28494, -28441,28442,28455,28440,28475,28434,28397,28426,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28470,28531,28409,28398,28461,28480, -28464,28476,28469,28395,28423,28430,28483,28421,28413,28406,28473,28444,28412, -28474,28447,28429,28446,28424,28449,29063,29072,29065,29056,29061,29058,29071, -29051,29062,29057,29079,29252,29267,29335,29333,29331,29507,29517,29521,29516, -29794,29811,29809,29813,29810,29799,29806,29952,29954,29955,30077,30096,30230, -30216,30220,30229,30225,30218,30228,30392,30593,30588,30597,30594,30574,30592, -30575,30590,30595,30898,30890,30900,30893,30888,30846,30891,30878,30885,30880, -30892,30882,30884,31128,31114,31115,31126,31125,31124,31123,31127,31112,31122, -31120,31275,31306,31280,31279,31272,31270,31400,31403,31404,31470,31624,31644, -31626,31633,31632,31638,31629,31628,31643,31630,31621,31640,21124,31641,31652, -31618,31931,31935,31932,31930,32167,32183,32194,32163,32170,32193,32192,32197, -32157,32206,32196,32198,32203,32204,32175,32185,32150,32188,32159,32166,32174, -32169,32161,32201,32627,32738,32739,32741,32734,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32804,32861,32860,33161,33158,33155, -33159,33165,33164,33163,33301,33943,33956,33953,33951,33978,33998,33986,33964, -33966,33963,33977,33972,33985,33997,33962,33946,33969,34000,33949,33959,33979, -33954,33940,33991,33996,33947,33961,33967,33960,34006,33944,33974,33999,33952, -34007,34004,34002,34011,33968,33937,34401,34611,34595,34600,34667,34624,34606, -34590,34593,34585,34587,34627,34604,34625,34622,34630,34592,34610,34602,34605, -34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,34577, -35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,35051, -35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,35478, -35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,36362, -36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,37148, -37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,37541, -37540,37494,37531,37498,37536,37524,37546,37517,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37542,37530,37547,37497,37527,37503, -37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,37516,37529, -37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,38781,38778, -38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,39085,39086, -39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,39367,39601, -39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,20735,20739, -20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,21132,21233, -21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,22080,22067, -22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,22691,22703, -22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,23298,23289, -23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,23957,23968, -23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,24289,24393, -24498,24971,24963,24953,25009,25008,24994,24969,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24987,24979,25007,25005,24991,24978, -25002,24993,24973,24934,25011,25133,25710,25712,25750,25760,25733,25751,25756, -25743,25739,25738,25740,25763,25759,25704,25777,25752,25974,25978,25977,25979, -26034,26035,26293,26288,26281,26290,26295,26282,26287,27136,27142,27159,27109, -27128,27157,27121,27108,27168,27135,27116,27106,27163,27165,27134,27175,27122, -27118,27156,27127,27111,27200,27144,27110,27131,27149,27132,27115,27145,27140, -27160,27173,27151,27126,27174,27143,27124,27158,27473,27557,27555,27554,27558, -27649,27648,27647,27650,28481,28454,28542,28551,28614,28562,28557,28553,28556, -28514,28495,28549,28506,28566,28534,28524,28546,28501,28530,28498,28496,28503, -28564,28563,28509,28416,28513,28523,28541,28519,28560,28499,28555,28521,28543, -28565,28515,28535,28522,28539,29106,29103,29083,29104,29088,29082,29097,29109, -29085,29093,29086,29092,29089,29098,29084,29095,29107,29336,29338,29528,29522, -29534,29535,29536,29533,29531,29537,29530,29529,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29538,29831,29833,29834,29830,29825, -29821,29829,29832,29820,29817,29960,29959,30078,30245,30238,30233,30237,30236, -30243,30234,30248,30235,30364,30365,30366,30363,30605,30607,30601,30600,30925, -30907,30927,30924,30929,30926,30932,30920,30915,30916,30921,31130,31137,31136, -31132,31138,31131,27510,31289,31410,31412,31411,31671,31691,31678,31660,31694, -31663,31673,31690,31669,31941,31944,31948,31947,32247,32219,32234,32231,32215, -32225,32259,32250,32230,32246,32241,32240,32238,32223,32630,32684,32688,32685, -32749,32747,32746,32748,32742,32744,32868,32871,33187,33183,33182,33173,33186, -33177,33175,33302,33359,33363,33362,33360,33358,33361,34084,34107,34063,34048, -34089,34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060, -34036,34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046, -34088,34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031, -34041,34072,34080,34096,34059,34073,34095,34402,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34646,34659,34660,34679,34785,34675, -34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655, -34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665, -34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081, -35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541, -35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983, -36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387, -36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376, -36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979, -36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254, -37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617, -37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606, -37581,37589,37577,37600,37598,37607,37585,37587,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37557,37601,37574,37556,38268,38316, -38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,38792, -38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,39162, -39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,39382, -39384,39371,39383,39372,39603,39660,39659,39667,39666,39665,39750,39747,39783, -39796,39793,39782,39798,39797,39792,39784,39780,39788,40188,40186,40189,40191, -40183,40199,40192,40185,40187,40200,40197,40196,40579,40659,40719,40720,20764, -20755,20759,20762,20753,20958,21300,21473,22128,22112,22126,22131,22118,22115, -22125,22130,22110,22135,22300,22299,22728,22717,22729,22719,22714,22722,22716, -22726,23319,23321,23323,23329,23316,23315,23312,23318,23336,23322,23328,23326, -23535,23980,23985,23977,23975,23989,23984,23982,23978,23976,23986,23981,23983, -23988,24167,24168,24166,24175,24297,24295,24294,24296,24293,24395,24508,24989, -25000,24982,25029,25012,25030,25025,25036,25018,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25023,25016,24972,25815,25814,25808, -25807,25801,25789,25737,25795,25819,25843,25817,25907,25983,25980,26018,26312, -26302,26304,26314,26315,26319,26301,26299,26298,26316,26403,27188,27238,27209, -27239,27186,27240,27198,27229,27245,27254,27227,27217,27176,27226,27195,27199, -27201,27242,27236,27216,27215,27220,27247,27241,27232,27196,27230,27222,27221, -27213,27214,27206,27477,27476,27478,27559,27562,27563,27592,27591,27652,27651, -27654,28589,28619,28579,28615,28604,28622,28616,28510,28612,28605,28574,28618, -28584,28676,28581,28590,28602,28588,28586,28623,28607,28600,28578,28617,28587, -28621,28591,28594,28592,29125,29122,29119,29112,29142,29120,29121,29131,29140, -29130,29127,29135,29117,29144,29116,29126,29146,29147,29341,29342,29545,29542, -29543,29548,29541,29547,29546,29823,29850,29856,29844,29842,29845,29857,29963, -30080,30255,30253,30257,30269,30259,30268,30261,30258,30256,30395,30438,30618, -30621,30625,30620,30619,30626,30627,30613,30617,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30615,30941,30953,30949,30954,30942, -30947,30939,30945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416, -31413,31409,31415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700, -31722,31714,31708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289, -32279,32268,32287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278, -32269,32276,32293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876, -33201,33190,33198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266, -33365,33366,33367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148, -34113,34146,34116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133, -34151,34144,34188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703, -34711,34707,34706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705, -34717,34692,34708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121, -35106,35113,35107,35119,35116,35103,35313,35552,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35554,35570,35572,35573,35549,35604, -35556,35551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984, -36085,36078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416, -36421,36406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665, -36663,36660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265, -37261,37263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667, -37650,37633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623, -37684,37634,37668,37631,37673,37689,37685,37674,37652,37644,37643,37630,37641, -37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,38325,38333,38569, -38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,38959,38962,39204, -39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,39402,39401,39399, -39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,39813,39815,39804, -39806,39803,39810,39827,39826,39824,39802,39829,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39805,39816,40229,40215,40224,40222, -40212,40233,40221,40216,40226,40208,40217,40223,40584,40582,40583,40622,40621, -40661,40662,40698,40722,40765,20774,20773,20770,20772,20768,20777,21236,22163, -22156,22157,22150,22148,22147,22142,22146,22143,22145,22742,22740,22735,22738, -23341,23333,23346,23331,23340,23335,23334,23343,23342,23419,23537,23538,23991, -24172,24170,24510,24507,25027,25013,25020,25063,25056,25061,25060,25064,25054, -25839,25833,25827,25835,25828,25832,25985,25984,26038,26074,26322,27277,27286, -27265,27301,27273,27295,27291,27297,27294,27271,27283,27278,27285,27267,27304, -27300,27281,27263,27302,27290,27269,27276,27282,27483,27565,27657,28620,28585, -28660,28628,28643,28636,28653,28647,28646,28638,28658,28637,28642,28648,29153, -29169,29160,29170,29156,29168,29154,29555,29550,29551,29847,29874,29867,29840, -29866,29869,29873,29861,29871,29968,29969,29970,29967,30084,30275,30280,30281, -30279,30372,30441,30645,30635,30642,30647,30646,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30644,30641,30632,30704,30963,30973, -30978,30971,30972,30962,30981,30969,30974,30980,31147,31144,31324,31323,31318, -31320,31316,31322,31422,31424,31425,31749,31759,31730,31744,31743,31739,31758, -31732,31755,31731,31746,31753,31747,31745,31736,31741,31750,31728,31729,31760, -31754,31976,32301,32316,32322,32307,38984,32312,32298,32329,32320,32327,32297, -32332,32304,32315,32310,32324,32314,32581,32639,32638,32637,32756,32754,32812, -33211,33220,33228,33226,33221,33223,33212,33257,33371,33370,33372,34179,34176, -34191,34215,34197,34208,34187,34211,34171,34212,34202,34206,34167,34172,34185, -34209,34170,34168,34135,34190,34198,34182,34189,34201,34205,34177,34210,34178, -34184,34181,34169,34166,34200,34192,34207,34408,34750,34730,34733,34757,34736, -34732,34745,34741,34748,34734,34761,34755,34754,34764,34743,34735,34756,34762, -34740,34742,34751,34744,34749,34782,34738,35125,35123,35132,35134,35137,35154, -35127,35138,35245,35247,35246,35314,35315,35614,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35608,35606,35601,35589,35595,35618, -35599,35602,35605,35591,35597,35592,35590,35612,35603,35610,35919,35952,35954, -35953,35951,35989,35988,36089,36207,36430,36429,36435,36432,36428,36423,36675, -36672,36997,36990,37176,37274,37282,37275,37273,37279,37281,37277,37280,37793, -37763,37807,37732,37718,37703,37756,37720,37724,37750,37705,37712,37713,37728, -37741,37775,37708,37738,37753,37719,37717,37714,37711,37745,37751,37755,37729, -37726,37731,37735,37760,37710,37721,38343,38336,38345,38339,38341,38327,38574, -38576,38572,38688,38687,38680,38685,38681,38810,38817,38812,38814,38813,38869, -38868,38897,38977,38980,38986,38985,38981,38979,39205,39211,39212,39210,39219, -39218,39215,39213,39217,39216,39320,39331,39329,39426,39418,39412,39415,39417, -39416,39414,39419,39421,39422,39420,39427,39614,39678,39677,39681,39676,39752, -39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,40243, -40257,40295,40246,40238,40239,40241,40248,40240,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40261,40258,40259,40254,40247,40256, -40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,40740,40739, -40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,22169,22896, -23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,25066,25072, -25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,26075,26330, -26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,27316,27309, -27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,28672,28667, -28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,29888,29877, -29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,30291,30295, -30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,30992,30994, -30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,31782,31784, -31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,32352,32343, -32339,32693,32691,32759,32760,32885,33233,33234,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33232,33375,33374,34228,34246,34240, -34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,34248,34245,34225, -34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,34779,34795,34794, -34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,34724,34775,34777, -34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,35153,35145,35626, -35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,35621,35639,35622, -35638,35630,35620,35643,35645,35642,35906,35957,35993,35992,35991,36094,36100, -36098,36096,36444,36450,36448,36439,36438,36446,36453,36455,36443,36442,36449, -36445,36457,36436,36678,36679,36680,36683,37160,37178,37179,37182,37288,37285, -37287,37295,37290,37813,37772,37778,37815,37787,37789,37769,37799,37774,37802, -37790,37798,37781,37768,37785,37791,37773,37809,37777,37810,37796,37800,37812, -37795,37797,38354,38355,38353,38579,38615,38618,24002,38623,38616,38621,38691, -38690,38693,38828,38830,38824,38827,38820,38826,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38818,38821,38871,38873,38870,38872, -38906,38992,38993,38994,39096,39233,39228,39226,39439,39435,39433,39437,39428, -39441,39434,39429,39431,39430,39616,39644,39688,39684,39685,39721,39733,39754, -39756,39755,39879,39878,39875,39871,39873,39861,39864,39891,39862,39876,39865, -39869,40284,40275,40271,40266,40283,40267,40281,40278,40268,40279,40274,40276, -40287,40280,40282,40590,40588,40671,40705,40704,40726,40741,40747,40746,40745, -40744,40780,40789,20788,20789,21142,21239,21428,22187,22189,22182,22183,22186, -22188,22746,22749,22747,22802,23357,23358,23359,24003,24176,24511,25083,25863, -25872,25869,25865,25868,25870,25988,26078,26077,26334,27367,27360,27340,27345, -27353,27339,27359,27356,27344,27371,27343,27341,27358,27488,27568,27660,28697, -28711,28704,28694,28715,28705,28706,28707,28713,28695,28708,28700,28714,29196, -29194,29191,29186,29189,29349,29350,29348,29347,29345,29899,29893,29879,29891, -29974,30304,30665,30666,30660,30705,31005,31003,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31009,31004,30999,31006,31152,31335, -31336,31795,31804,31801,31788,31803,31980,31978,32374,32373,32376,32368,32375, -32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888, -33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263, -34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274, -34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826, -34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254, -35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666, -35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461, -36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184, -37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849, -37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269, -38362,38363,38625,38697,38699,38700,38696,38694,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38835,38839,38838,38877,38878,38879, -39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,39335, -39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,39444, -39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,39906, -39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,40330, -40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,40304, -40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,40640, -40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,22755, -23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,26079, -26344,26339,26340,27379,27376,27370,27368,27385,27377,27374,27375,28732,28725, -28719,28727,28724,28721,28738,28728,28735,28730,28729,28736,28731,28723,28737, -29203,29204,29352,29565,29564,29882,30379,30378,30398,30445,30668,30670,30671, -30669,30706,31013,31011,31015,31016,31012,31017,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31154,31342,31340,31341,31479,31817, -31816,31818,31815,31813,31982,32379,32382,32385,32384,32698,32767,32889,33243, -33241,33291,33384,33385,34338,34303,34305,34302,34331,34304,34294,34308,34313, -34309,34316,34301,34841,34832,34833,34839,34835,34838,35171,35174,35257,35319, -35680,35690,35677,35688,35683,35685,35687,35693,36270,36486,36488,36484,36697, -36694,36695,36693,36696,36698,37005,37187,37185,37303,37301,37298,37299,37899, -37907,37883,37920,37903,37908,37886,37909,37904,37928,37913,37901,37877,37888, -37879,37895,37902,37910,37906,37882,37897,37880,37898,37887,37884,37900,37878, -37905,37894,38366,38368,38367,38702,38703,38841,38843,38909,38910,39008,39010, -39011,39007,39105,39106,39248,39246,39257,39244,39243,39251,39474,39476,39473, -39468,39466,39478,39465,39470,39480,39469,39623,39626,39622,39696,39698,39697, -39947,39944,39927,39941,39954,39928,40000,39943,39950,39942,39959,39956,39945, -40351,40345,40356,40349,40338,40344,40336,40347,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40352,40340,40348,40362,40343,40353, -40346,40354,40360,40350,40355,40383,40361,40342,40358,40359,40601,40603,40602, -40677,40676,40679,40678,40752,40750,40795,40800,40798,40797,40793,40849,20794, -20793,21144,21143,22211,22205,22206,23368,23367,24011,24015,24305,25085,25883, -27394,27388,27395,27384,27392,28739,28740,28746,28744,28745,28741,28742,29213, -29210,29209,29566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394, -32391,32392,32395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335, -34339,34332,34329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843, -34848,34852,34844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653, -35706,35707,36112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189, -37305,37951,37947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952, -37937,38373,38372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256, -39254,39481,39485,39494,39492,39490,39489,39482,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39487,39629,39701,39703,39704,39702, -39738,39762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374, -40380,40385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378, -40364,40392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685, -40731,40728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897, -23371,23372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661, -28757,28758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317, -30381,31029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401, -32591,32647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854, -34858,34853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117, -36501,36500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962, -37963,37967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252, -39259,39502,39507,39508,39500,39503,39496,39498,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39497,39506,39504,39632,39705,39723, -39739,39766,39765,40006,40008,39999,40004,39993,39987,40001,39996,39991,39988, -39986,39997,39990,40411,40402,40414,40410,40395,40400,40412,40401,40415,40425, -40409,40408,40406,40437,40405,40413,40630,40688,40757,40755,40754,40770,40811, -40853,40866,20797,21145,22760,22759,22898,23373,24024,34863,24399,25089,25091, -25092,25897,25893,26006,26347,27409,27410,27407,27594,28763,28762,29218,29570, -29569,29571,30320,30676,31847,31846,32405,33388,34362,34368,34361,34364,34353, -34363,34366,34864,34866,34862,34867,35190,35188,35187,35326,35724,35726,35723, -35720,35909,36121,36504,36708,36707,37308,37986,37973,37981,37975,37982,38852, -38853,38912,39510,39513,39710,39711,39712,40018,40024,40016,40010,40013,40011, -40021,40025,40012,40014,40443,40439,40431,40419,40427,40440,40420,40438,40417, -40430,40422,40434,40432,40418,40428,40436,40435,40424,40429,40642,40656,40690, -40691,40710,40732,40760,40759,40758,40771,40783,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40817,40816,40814,40815,22227,22221, -23374,23661,25901,26349,26350,27411,28767,28769,28765,28768,29219,29915,29925, -30677,31032,31159,31158,31850,32407,32649,33389,34371,34872,34871,34869,34891, -35732,35733,36510,36511,36512,36509,37310,37309,37314,37995,37992,37993,38629, -38726,38723,38727,38855,38885,39518,39637,39769,40035,40039,40038,40034,40030, -40032,40450,40446,40455,40451,40454,40453,40448,40449,40457,40447,40445,40452, -40608,40734,40774,40820,40821,40822,22228,25902,26040,27416,27417,27415,27418, -28770,29222,29354,30680,30681,31033,31849,31851,31990,32410,32408,32411,32409, -33248,33249,34374,34375,34376,35193,35194,35196,35195,35327,35736,35737,36517, -36516,36515,37998,37997,37999,38001,38003,38729,39026,39263,40040,40046,40045, -40459,40461,40464,40463,40466,40465,40609,40693,40713,40775,40824,40827,40826, -40825,22302,28774,31855,34876,36274,36518,37315,38004,38008,38006,38005,39520, -40052,40051,40049,40053,40468,40467,40694,40714,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40868,28776,28773,31991,34410,34878, -34877,34879,35742,35996,36521,36553,38731,39027,39028,39116,39265,39339,39524, -39526,39527,39716,40469,40471,40776,25095,27422,29223,34380,36520,38018,38016, -38017,39529,39528,39726,40473,29225,34379,35743,38019,40057,40631,30325,39531, -40058,40477,28777,28778,40612,40830,40777,40856, -}; - -static const struct dbcs_index big5_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_decmap+0,64,254},{ -__big5_decmap+191,64,254},{__big5_decmap+382,64,191},{__big5_decmap+510,64,254 -},{__big5_decmap+701,64,254},{__big5_decmap+892,64,254},{__big5_decmap+1083, -64,254},{__big5_decmap+1274,64,254},{__big5_decmap+1465,64,254},{__big5_decmap -+1656,64,254},{__big5_decmap+1847,64,254},{__big5_decmap+2038,64,254},{ -__big5_decmap+2229,64,254},{__big5_decmap+2420,64,254},{__big5_decmap+2611,64, -254},{__big5_decmap+2802,64,254},{__big5_decmap+2993,64,254},{__big5_decmap+ -3184,64,254},{__big5_decmap+3375,64,254},{__big5_decmap+3566,64,254},{ -__big5_decmap+3757,64,254},{__big5_decmap+3948,64,254},{__big5_decmap+4139,64, -254},{__big5_decmap+4330,64,254},{__big5_decmap+4521,64,254},{__big5_decmap+ -4712,64,254},{__big5_decmap+4903,64,254},{__big5_decmap+5094,64,254},{ -__big5_decmap+5285,64,254},{__big5_decmap+5476,64,254},{__big5_decmap+5667,64, -254},{__big5_decmap+5858,64,254},{__big5_decmap+6049,64,254},{__big5_decmap+ -6240,64,254},{__big5_decmap+6431,64,254},{__big5_decmap+6622,64,254},{ -__big5_decmap+6813,64,254},{__big5_decmap+7004,64,254},{__big5_decmap+7195,64, -252},{0,0,0},{__big5_decmap+7384,64,254},{__big5_decmap+7575,64,254},{ -__big5_decmap+7766,64,254},{__big5_decmap+7957,64,254},{__big5_decmap+8148,64, -254},{__big5_decmap+8339,64,254},{__big5_decmap+8530,64,254},{__big5_decmap+ -8721,64,254},{__big5_decmap+8912,64,254},{__big5_decmap+9103,64,254},{ -__big5_decmap+9294,64,254},{__big5_decmap+9485,64,254},{__big5_decmap+9676,64, -254},{__big5_decmap+9867,64,254},{__big5_decmap+10058,64,254},{__big5_decmap+ -10249,64,254},{__big5_decmap+10440,64,254},{__big5_decmap+10631,64,254},{ -__big5_decmap+10822,64,254},{__big5_decmap+11013,64,254},{__big5_decmap+11204, -64,254},{__big5_decmap+11395,64,254},{__big5_decmap+11586,64,254},{ -__big5_decmap+11777,64,254},{__big5_decmap+11968,64,254},{__big5_decmap+12159, -64,254},{__big5_decmap+12350,64,254},{__big5_decmap+12541,64,254},{ -__big5_decmap+12732,64,254},{__big5_decmap+12923,64,254},{__big5_decmap+13114, -64,254},{__big5_decmap+13305,64,254},{__big5_decmap+13496,64,254},{ -__big5_decmap+13687,64,254},{__big5_decmap+13878,64,254},{__big5_decmap+14069, -64,254},{__big5_decmap+14260,64,254},{__big5_decmap+14451,64,254},{ -__big5_decmap+14642,64,254},{__big5_decmap+14833,64,254},{__big5_decmap+15024, -64,254},{__big5_decmap+15215,64,254},{__big5_decmap+15406,64,254},{ -__big5_decmap+15597,64,254},{__big5_decmap+15788,64,254},{__big5_decmap+15979, -64,254},{__big5_decmap+16170,64,254},{__big5_decmap+16361,64,254},{ -__big5_decmap+16552,64,213},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const DBCHAR __big5_encmap[21764] = { -41542,41543,N,41540,N,41393,N,N,N,N,N,N,N,N,41560,41427,N,N,N,N,N,41296,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41425,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41426,41918,N,41916,41917,41919, -N,41413,N,N,N,N,N,N,N,N,N,N,N,41915,41796,41797,41798,41799,41800,41801,41802, -41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,N,41813,41814, -41815,41816,41817,41818,41819,N,N,N,N,N,N,N,41820,41821,41822,41823,41824, -41825,41826,41827,41828,41829,41830,41831,41832,41833,41834,41835,41836,N, -41837,41838,41839,41840,41841,41842,41843,51123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,51121,51122,51124,51125,51126,51127,51128,51129,51130,N,N,N,N,N,N,51131, -51132,51133,51134,51135,51136,51137,51138,51139,51140,51141,51142,51143,51144, -51145,51146,51147,51148,51149,51151,51152,51153,51154,51155,51156,51157,51158, -51159,51160,51161,51162,51163,51164,51165,51166,51167,51168,51169,51170,51171, -51172,51173,51174,51175,51176,N,51150,41302,41304,N,N,N,41381,41382,N,N,41383, -41384,N,N,N,N,41285,N,N,41292,41291,N,N,N,N,N,N,N,N,N,N,N,41388,N,N,41387,N,N, -N,N,N,41392,N,N,41410,41546,N,41409,N,N,N,41547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41657,41658, -41659,41660,41661,41662,41663,41664,41665,41666,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41462,41460,41463,41461,N,N, -41464,41465,41467,41466,41428,N,N,N,41435,41448,41447,N,N,41469,N,41468,N,N,N, -41444,41445,41452,N,N,41453,N,N,N,N,N,41455,41454,N,N,N,N,N,N,41443,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41436,N,N,N,N,N,N,N,N,N,N,N,N,N,41434,41437,N, -N,N,N,41432,41433,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41446,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41449,51177,51178,51179,51180,51181, -51182,51183,51184,51185,51186,N,N,N,N,N,N,N,N,N,N,51187,51188,51189,51190, -51191,51192,51193,51194,51195,51196,41591,N,41592,N,N,N,N,N,N,N,N,N,41594,N,N, -N,41595,N,N,N,41596,N,N,N,41597,N,N,N,41589,N,N,N,N,N,N,N,41588,N,N,N,N,N,N,N, -41587,N,N,N,N,N,N,N,41586,N,N,N,N,N,N,N,41585,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,41636,N,N,N,N,N,N,N,N,N,N,N,N,N,41637,N,N,41639,N,N,N,N,N,N,N,N,41638,N, -N,41598,41633,41635,41634,41644,41645,41646,41306,N,N,N,N,N,N,N,N,N,N,N,N, -41570,41571,41572,41573,41574,41575,41576,41577,41584,41583,41582,41581,41580, -41579,41578,N,N,N,N,41590,41593,N,N,N,N,N,N,N,N,N,N,41405,41404,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,41398,41397,N,N,N,N,N,N,N,N,41407,41406,N,N,N,N,N,N,N,N, -41403,41402,N,N,N,41395,N,N,41399,41396,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -41640,41641,41643,41642,41401,41400,N,N,41459,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -41456,41458,41457,41280,41282,41283,41394,N,50852,N,N,41329,41330,41325,41326, -41333,41334,41337,41338,41321,41322,41541,N,41317,41318,N,N,N,N,N,N,N,41385, -41386,N,N,41667,41668,41669,41670,41671,41672,41673,41674,41675,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50853,50854,50855,50856,50857,50858,50859, -50860,50861,50862,50863,50864,50865,50866,50867,50868,50869,50870,50871,50872, -50873,50874,50875,50876,50877,50878,50879,50880,50881,50882,50883,50884,50885, -50886,50887,50888,50889,50890,50891,50892,50893,50894,50895,50896,50897,50898, -50899,50900,50901,50902,50903,50904,50905,50906,50907,50908,50909,50910,50911, -50912,50913,50914,50915,50916,50917,50918,50919,50920,50921,50922,50923,50924, -50925,50926,50927,50928,50929,50930,50931,50932,50933,50934,50935,N,N,N,N,N,N, -N,N,N,50850,50851,N,N,50936,50937,50938,50939,50940,50941,50942,51008,51009, -51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,51022, -51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,51035, -51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,51048, -51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,51061, -51062,51063,51064,51065,51066,51067,51068,51069,51070,51105,51106,51107,51108, -51109,51110,51111,51112,51113,51114,51115,51116,51117,51118,51119,51120,N,N,N, -N,N,N,N,50849,41844,41845,41846,41847,41848,41849,41850,41851,41852,41853, -41854,41889,41890,41891,41892,41893,41894,41895,41896,41897,41898,41899,41900, -41901,41902,41903,41904,41905,41906,41907,41908,41909,41910,41911,41912,41913, -41914,41408,41557,41558,N,N,N,N,N,N,N,N,N,N,N,N,41552,41553,41554,N,N,41556,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41559,N,N,N, -N,N,N,N,N,N,41555,N,N,41451,41450,N,N,41551,42048,42050,N,42051,N,N,N,51525, -42070,42068,42071,42069,51526,42147,51535,51533,42146,42145,N,N,42306,42305, -42304,N,42307,42238,N,N,N,N,42464,42465,N,N,N,N,N,N,43203,N,N,N,N,42072,N, -42148,51536,N,42149,51555,42730,52145,N,N,N,N,42073,42150,N,42308,51556,N,N,N, -N,N,51520,42052,N,42075,N,51527,42076,N,N,42151,N,42309,42311,42310,N,N,42466, -42467,N,N,43204,N,44476,42049,N,N,51521,42053,42078,42077,N,N,N,N,N,N,N,N,N, -42468,N,N,N,N,N,N,N,N,N,43205,N,N,N,N,N,N,N,N,N,N,45230,54347,N,N,46787,56497, -56498,N,42054,N,42153,N,N,43206,42055,51528,42079,N,N,42154,42156,51537,42157, -42155,N,N,N,42469,N,43207,N,N,43208,43845,N,42080,42158,N,42470,42472,42471,N, -42731,N,N,43209,43210,43846,43847,N,N,N,N,44477,N,N,56499,N,N,63190,42056,N,N, -N,N,N,42160,42159,51538,42161,42167,N,42162,42163,51540,51539,42165,42166,N, -42164,N,N,N,N,N,N,42314,42315,42316,42317,42313,42320,51562,N,51558,51561, -42321,42337,N,51560,N,42318,42319,42312,N,N,51557,51559,N,N,N,N,N,N,42485, -51632,42482,42486,51642,51630,42483,51634,N,N,N,42484,N,42487,N,42473,51633, -42488,51637,N,51641,51638,N,N,51635,42474,42476,42489,N,42478,51627,42481, -42479,42480,51643,51640,51631,42477,N,N,51628,42475,N,N,N,51636,N,N,N,N,51639, -N,N,N,N,N,N,N,N,N,51629,51814,N,42818,42740,N,N,51815,42737,N,42820,N,42745,N, -42744,51803,42748,42743,51808,51816,N,51812,N,42746,N,N,42749,42734,42823, -51805,N,N,52157,42732,42819,42733,42741,42742,51810,51806,42747,42739,51802, -42735,51813,42821,42824,42738,42816,42822,42736,51811,42817,51817,51804,42750, -51807,N,N,51809,N,43224,52159,52171,43216,N,52172,43211,43221,N,N,43214,52153, -43222,52152,52156,52163,52161,43230,43225,52147,52149,43227,43215,52150,52162, -52169,43220,52155,52148,43219,52151,43223,52154,N,43218,N,43213,N,43228,52164, -43229,52168,N,52166,52170,43226,52158,52146,N,52160,43217,52165,43212,52167,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,43862,43850,N,N,52704,52712,N,43849,43857,43869,N, -52718,52716,52711,N,N,N,43851,52717,52707,43865,43856,43864,52702,N,52714,N, -52705,43860,52706,N,52701,43867,43854,43863,43853,N,52703,52708,N,52715,43861, -43858,52710,43866,52713,52709,43855,43868,43859,43852,43848,N,N,N,N,N,N,N,N,N, -N,52719,N,44503,44481,N,44497,N,44502,53456,53455,53460,53461,44484,N,44493,N, -N,N,44506,44494,N,N,N,N,53449,44487,53450,N,44508,N,44499,44478,44479,53469, -45247,N,44492,44491,53451,44495,54363,44486,53462,44501,44500,44490,53454, -53463,N,53448,44489,53464,44498,53452,44480,N,44483,44482,53465,44496,44485, -44505,44507,53459,44504,N,53467,53453,53468,N,53457,N,53466,N,53458,N,N,N,N, -44488,N,N,N,54371,54359,N,45235,N,54364,54370,45234,54357,45238,54361,54354, -45236,54358,45241,45246,N,54375,N,54353,N,45242,N,54374,N,N,45237,54360,45233, -54355,54351,54365,54352,54350,54362,54368,54369,45239,N,N,55387,54366,54349, -54367,N,45249,54372,45248,54348,N,54356,54373,45244,45243,45240,45245,N,N, -45231,N,N,45232,N,N,46024,N,55390,55383,N,46021,N,55391,N,N,N,55381,55384, -46020,55385,N,N,46023,55389,N,55379,55378,46025,N,46026,46022,46027,55377, -55388,55386,55380,N,N,N,46019,55382,N,N,N,N,N,N,N,N,46794,46788,56503,46797, -56509,56512,46790,46791,56506,46789,56515,46795,56516,N,56511,46796,N,56500, -46793,56501,N,56510,56508,N,56504,46792,56502,46798,56507,56514,56505,56513,N, -N,47542,47539,N,47540,N,57593,57585,47538,47535,57586,N,N,47537,57589,N,57591, -N,N,57598,N,N,57597,57592,47534,57584,47532,57587,47543,57590,N,57594,47536, -47533,57596,57595,47541,N,57588,N,48120,58604,N,58601,48121,N,48119,N,58608, -58605,58598,48118,N,48122,58599,48117,48125,58602,58603,48123,48124,58609, -58606,58607,N,N,N,48810,59640,48807,59637,48809,48811,N,59638,48808,N,59639,N, -59636,N,N,49270,60605,49271,60603,N,60604,60602,60601,N,N,60606,49269,N,N, -61368,61369,N,58600,61367,49272,50015,61931,61932,N,50391,50392,62913,62912, -50540,50539,63440,N,42057,42081,42169,N,42168,42323,42322,42492,42491,42493, -42490,N,42826,42825,42827,N,N,N,N,43232,N,43231,43233,N,43870,N,41561,53470, -41562,45250,41564,41563,55392,N,41565,47544,41566,N,42058,N,42170,42494,43234, -N,42059,42173,42171,42172,N,N,42560,N,N,N,42828,43236,43235,43237,N,N,N,44509, -N,N,N,48812,N,N,N,N,N,N,51534,N,42324,42325,N,N,42561,N,51818,N,43872,43871, -53472,53471,45251,N,42174,51541,N,N,N,N,N,52173,N,43873,N,44512,N,44510,44511, -N,N,N,N,48813,N,42326,N,N,N,42562,51644,N,N,N,N,42829,42830,N,51819,N,N,52174, -43238,52175,N,N,N,N,N,53474,53475,44515,N,53476,N,53473,44516,44514,44513, -53477,N,54376,N,N,N,55393,N,N,56517,57664,N,N,N,48126,48814,59641,N,42060, -42074,N,N,N,N,N,N,N,N,N,N,N,N,N,N,45252,46029,N,47545,N,51522,42175,N,42329, -42327,42328,N,N,43239,42061,42062,N,42082,N,N,42176,42177,42178,51646,42330,N, -51563,N,42566,N,51647,42564,42565,51645,N,N,42567,42563,N,N,N,N,51820,43756, -51821,N,N,51822,N,N,42832,42831,N,N,42835,42833,42834,N,N,N,43245,N,43244, -52180,52177,52178,N,52176,43246,43242,43241,N,43243,43240,N,N,N,N,N,43247,N, -43875,52720,N,52179,43880,N,52721,43876,43879,43878,43877,43874,N,N,N,53480,N, -44519,53483,44517,N,N,N,53479,44520,44518,44521,53481,53482,N,53478,53484,N,N, -N,N,N,N,46033,45253,54377,54379,54378,54380,45254,N,N,46030,N,46031,46032,N, -46800,56519,N,56518,56520,56521,46801,N,46799,57665,57666,47547,47546,58202,N, -N,48192,48193,48194,48196,58610,58611,48195,N,N,N,48815,N,48816,N,N,61933, -62915,62914,63441,N,42063,N,N,N,42332,42331,N,N,42568,N,N,51648,N,N,42837, -42838,42836,42839,51823,51824,N,N,N,N,N,N,N,N,N,N,N,N,43249,52181,N,43248,N, -52722,43884,52723,43883,N,N,N,43881,N,43882,N,N,N,53485,N,N,N,N,45255,54382,N, -45258,54381,45541,45257,45256,N,46036,N,46035,46034,46802,N,N,46805,46806, -46804,N,46803,N,N,57667,N,57668,N,N,N,58613,48197,58612,N,48817,60607,49273,N, -61934,50261,N,42083,42179,51542,N,42180,42181,42333,42334,N,42569,51825,52182, -52183,N,43885,53486,45260,45259,55395,55394,N,N,42064,42182,42335,N,45261, -51523,N,51564,42336,N,51650,42571,42570,51649,42840,N,N,N,N,N,N,44522,N,N, -54383,N,46807,57669,47548,N,N,59642,N,N,62461,N,42183,N,N,52184,52724,45264, -45262,45263,42065,N,42084,41677,42186,N,42185,42184,42339,42338,N,51565,51651, -N,N,N,43253,43250,43252,43251,N,N,43886,N,N,46037,N,42066,N,42187,N,42341, -42340,N,51826,N,N,43254,N,N,N,N,N,51543,N,42343,42342,42572,42573,51827,42841, -N,42842,N,43255,43256,43257,N,43887,52725,N,N,44523,N,N,51524,N,42188,N,N,N,N, -N,51652,N,N,N,51828,51829,N,N,52185,N,52186,N,52727,52726,52729,52728,43888,N, -54384,44525,53487,44524,N,N,N,N,55396,46038,N,55397,N,N,N,N,57670,47549,N,N,N, -N,48198,N,61935,N,N,N,N,51544,N,42344,N,N,N,N,N,N,N,45265,N,N,N,N,42067,42085, -42190,42189,N,42191,N,N,N,N,N,N,43259,N,43258,43260,N,N,N,43889,N,N,N,44526,N, -59643,49743,42086,42346,42361,42356,N,42351,42350,42357,42355,42348,42362, -42349,42345,42360,42359,42358,42347,N,42354,N,N,42353,N,N,42363,42352,42579,N, -42585,42581,N,42587,51653,42584,42574,42577,42580,42576,42583,42586,42575, -42578,42582,42588,N,N,N,N,N,51838,51835,N,42855,51836,42843,42845,42869,42864, -N,N,N,51877,51837,42847,42849,51876,42856,51832,42868,42870,42844,42861,N, -51830,42867,N,42852,N,42862,42863,51831,42860,42858,N,42859,42865,51873,42846, -N,42866,51875,42854,42851,N,51834,42850,51878,42853,N,42857,N,N,N,42848,51874, -N,N,N,N,51833,N,N,N,N,N,N,N,N,N,N,N,52203,52202,43343,52205,52207,52196,52199, -52206,43344,N,N,52193,52197,N,N,52201,52809,43339,52813,43261,52198,43262, -43340,43333,43329,N,52194,43332,43337,43346,52195,52188,43331,52189,52191,N, -43334,N,43336,52187,52192,N,N,43345,43341,52200,43347,N,43338,52190,43335,N,N, -43330,43328,N,52204,N,43342,N,N,N,N,N,52808,52731,52811,N,N,52733,43896,43944, -43892,43943,43901,43940,43890,52732,52803,43939,52815,43941,N,43897,N,N,52805, -52802,43895,N,52730,43942,52810,43900,52812,43945,43891,43902,43899,52800, -43937,52806,52807,43898,43938,43894,N,N,N,N,43893,52734,N,N,N,N,N,N,52804,N,N, -N,N,N,N,N,52814,N,53572,44539,53489,N,53494,44532,44608,53492,44527,44537, -44542,53499,N,44538,44541,N,N,53502,44533,53493,N,N,N,53570,53571,N,44535, -53569,44531,44611,N,53496,44529,N,53574,53497,53501,44534,44610,53498,44540, -53568,53575,54433,N,53573,44612,44528,53500,53491,N,44536,N,N,53490,N,N,53495, -N,N,N,N,N,N,N,N,N,N,N,53488,44609,N,N,54391,N,45284,54439,45282,45279,54396, -45275,54434,45286,54390,54395,54394,44530,45281,54437,N,54440,54387,N,46056,N, -54441,45287,N,45273,45270,54398,45267,N,54438,N,45274,54442,N,54388,54436, -45277,54389,54392,54397,N,N,45278,45276,45288,N,N,N,N,45283,N,45271,45522,N, -45272,54393,45285,45280,54435,45269,N,N,N,45268,N,N,N,N,N,N,N,N,N,N,54385, -54386,55402,N,N,N,46039,46042,55413,46062,55416,46040,55409,46046,46052,46525, -N,N,46050,55406,46063,46043,46051,55414,56535,55419,55407,N,55398,55411,55405, -46049,55417,N,N,46045,46065,46058,N,46047,46044,N,46055,N,55418,55404,55410, -55412,55400,55415,46041,55399,N,46048,46064,46060,55401,46054,N,N,46061,46057, -46053,N,55408,N,N,N,N,N,46059,N,N,N,56533,56529,N,56544,56522,56531,46821, -46822,46814,56540,46824,56527,56526,56524,56542,46812,56536,56525,46815,56534, -46810,56530,56537,56539,N,N,56543,46819,56523,46813,56528,N,46808,N,46820, -56538,46816,46817,46823,46811,41567,46809,56532,N,N,N,N,N,46818,N,N,56541,N,N, -N,47565,47560,N,57685,57681,N,57675,47554,47550,57684,47551,57678,57680,N, -57683,N,47556,N,47563,47557,N,N,57673,47558,47559,57676,47564,N,57674,57679, -47555,57672,47561,47553,N,N,N,47552,57677,57682,N,47562,N,N,N,N,N,N,N,57671,N, -48205,58695,N,58692,N,48199,48211,48212,N,48202,58690,48204,58617,48210,N, -58694,48201,58696,48200,N,58691,58693,48203,58689,58618,58615,N,N,55403,58621, -N,58614,58620,58619,N,58616,N,48207,N,N,N,N,48206,N,N,N,48208,58622,48818, -58688,N,N,N,59717,N,59645,N,48830,59714,48822,48826,59713,N,48825,48821,48824, -48819,48829,59715,59646,48828,59644,48827,59716,59712,48209,N,48831,59718, -48823,48820,N,N,N,N,60614,60616,49275,60617,60615,60613,60612,49277,60611, -49278,N,N,N,N,60609,60610,49274,49313,49276,N,N,60608,N,49744,N,61372,61370, -61375,61373,N,61371,61374,N,N,N,N,N,N,N,50016,61938,61939,50262,N,61940,61936, -61941,61937,49745,N,N,N,62462,62529,50265,62528,50264,50263,N,N,N,N,50266, -62917,62918,N,50394,50393,50395,62916,N,63192,63191,N,50541,50543,50542,63193, -50632,63654,N,N,N,50673,N,63653,63726,N,N,51529,N,N,42365,42364,N,42591,42590, -51655,42589,51654,N,N,42873,51881,N,51880,N,N,42871,42874,N,N,51879,N,42872,N, -N,N,N,N,N,52208,N,52209,43348,N,N,N,N,43946,53576,53577,44613,44614,N,N,54444, -45289,45291,54443,45290,55420,46066,N,N,N,N,46825,46826,56545,N,47567,N,47566, -N,58697,59720,59719,N,63851,42087,51545,N,51566,51567,N,N,N,N,42594,42598, -51657,N,42596,42595,51656,42597,42593,N,N,42592,51658,N,N,N,N,N,N,42918,N,N, -42915,N,42877,51882,N,N,N,51883,N,42913,N,51885,42875,51886,51884,42878,42914, -42917,42916,42876,51887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43353,52222,N,43355,N, -43354,N,52288,43352,43351,52213,N,52212,N,52210,52215,52214,52211,52220,52221, -52218,52216,43350,N,N,N,52219,43356,52289,N,N,52217,N,43947,43349,N,N,N,N,N,N, -N,43948,52820,N,N,52826,N,N,N,43954,52824,52830,N,52821,52825,52827,52829, -52823,N,52822,52817,52818,43949,N,43951,43950,52819,52828,N,N,N,N,N,N,N,N, -43953,N,N,N,N,N,N,52816,53587,N,53586,53591,53582,N,53585,53584,N,53588,N, -53592,44615,44618,N,N,53583,53589,N,N,N,44617,53578,N,43952,54458,53590,N, -53581,N,44616,53580,N,N,N,N,N,N,54449,N,N,45292,45296,54465,54447,54461,45297, -54463,N,54469,N,54473,N,N,54464,54452,54460,N,54474,54472,54462,54457,54450, -55462,54448,45301,54455,45302,45298,54445,54467,54453,54451,54470,45299,N, -54476,45293,45295,54459,54454,44619,45294,54456,54471,54475,54466,N,54468,N,N, -N,54446,N,N,N,N,55457,N,55466,55465,46074,55458,N,46075,46073,N,55460,46070, -55464,N,55459,55461,55421,46068,N,55474,55473,55470,46067,46071,46072,53579, -55467,46069,45300,55469,55422,55472,55471,N,55475,N,56559,N,55468,N,N,N,N,N,N, -N,N,55463,56551,46836,46839,46834,56550,56554,56549,N,46828,46838,56546,46832, -56553,N,46830,46829,56556,46831,56558,N,56555,46827,N,N,N,46837,56560,56548, -56557,N,N,56547,N,N,46833,N,46835,N,56552,N,56561,N,N,57693,47568,57699,N,N, -47573,57695,57702,57687,47575,47569,57692,48213,57691,57700,47570,N,47574, -57690,57696,57701,57686,47572,57694,N,N,57698,57704,57688,57697,N,47571,57703, -N,N,N,57689,N,N,N,48217,58699,48215,48214,58701,58706,N,58702,N,58705,48220,N, -48805,48219,N,58698,58704,N,48218,58703,N,58700,N,48216,N,N,N,N,N,N,59725,N, -59727,59722,48833,59724,N,48832,59726,N,N,48835,59728,48834,59721,59723,N,N,N, -N,49317,60620,N,49316,60621,49315,60619,49314,60618,N,49747,49746,61942,61944, -N,61943,50017,50018,N,N,50019,62530,50267,N,N,63443,63442,50674,N,42088,42192, -N,N,42919,N,N,N,N,52831,N,N,N,N,46076,46077,N,56562,47576,57705,58707,51546,N, -N,51888,N,N,N,N,N,52290,52832,53593,44620,N,N,61945,N,50396,42089,42366,51568, -N,42599,42600,N,43357,N,N,N,45303,N,47578,N,47579,47577,N,42090,N,42193,42195, -42194,51547,42196,42401,51569,N,42402,N,N,N,N,N,42601,42602,N,N,N,51659,N, -42920,N,51889,N,N,N,43361,52291,N,43359,43360,43358,53594,N,N,N,43958,43957, -43959,43956,N,52833,43362,43955,N,44621,44622,N,44623,N,54477,N,N,N,46078, -55476,45304,N,N,N,N,46840,N,47581,47580,57706,N,48221,48836,N,61376,63194, -63444,42091,42403,N,42404,51665,42604,42607,N,51663,51661,42606,51664,51666, -51660,42609,42608,42605,42603,51662,N,N,N,N,42931,N,N,42928,51894,51897,51896, -N,42922,42930,N,N,42927,51893,51891,42926,N,N,N,42921,42924,N,51892,51899, -51895,42925,42929,42932,51890,51898,42923,N,N,N,N,N,43367,43375,N,52303,52296, -43376,52307,52292,52299,N,N,43366,52293,43364,52300,52304,43363,N,52305,52298, -N,52301,N,43378,43369,52308,52306,N,43374,43372,52297,43371,52295,52294,43370, -43368,43377,43373,43365,N,52302,N,43961,N,43968,52847,43960,52839,52835,N, -52851,52834,N,43963,52844,43966,43969,N,43964,52848,43967,N,44630,52854,52836, -N,N,52838,52845,52849,52853,52850,52843,52846,N,N,52840,43971,52842,52841, -52852,43962,52837,43970,N,43965,N,N,N,N,N,44636,53602,N,44635,N,N,53600,N, -44624,N,44629,N,53599,53596,53601,44625,53595,N,44628,44626,N,53603,44627, -44631,N,N,44632,N,44634,N,N,N,44633,N,N,N,53597,53598,N,N,N,N,53604,N,54484, -45305,55490,54483,54502,N,N,45376,N,54500,N,45310,45306,54509,54493,54496,N, -45379,54506,54498,45307,45380,N,54503,54501,N,N,54486,54507,54495,54490,N, -54480,54508,54492,54479,N,45378,54497,54510,54494,54482,54487,54478,N,45377,N, -54491,54488,45308,54481,N,54505,45309,N,54489,54485,N,N,54504,N,N,N,N,N,N, -46144,55483,N,55480,55497,55485,55498,N,46146,N,N,N,55494,55491,N,N,N,N,N, -55492,55495,55499,N,54499,55501,56647,N,46147,55502,55478,55488,N,55493,N,N, -46145,46148,55500,55503,55482,55479,N,N,55481,N,N,55486,55484,46149,N,55496,N, -N,55487,N,55489,55477,56570,56568,46914,46912,56643,56569,56644,56640,56567, -56646,56566,56573,46846,46845,46844,56571,56641,46841,46913,N,56564,N,56574, -56563,56572,46842,56642,56565,46843,56645,N,N,N,N,N,N,N,57710,47586,47585, -47587,57722,57712,57718,57707,57721,57720,57724,57717,47582,57716,47588,N, -57709,47583,N,57723,47584,57711,57714,57719,57713,57708,N,N,N,N,57715,58709, -48225,58712,58711,58714,58716,N,48223,N,58710,N,58708,58717,58715,58713,N, -58719,N,58718,48227,48222,N,48224,48226,N,N,58720,59735,N,N,59734,59733,N, -59736,59729,N,59730,59738,59731,N,48837,59740,N,59739,59732,N,60625,49320, -60623,60628,60627,59737,N,49319,N,60626,60622,60630,60629,49318,N,60624,N, -48838,N,N,N,49748,N,N,N,61377,61946,61947,61948,50268,N,N,50269,N,62531,N, -62920,62919,N,N,63195,63196,63445,63655,N,42092,42093,N,42094,42197,42405, -51667,42610,42611,N,42935,42936,42934,42933,N,43379,N,N,52309,43381,43380, -52310,N,N,N,43972,N,44637,53605,N,54512,N,45381,46151,54511,46150,N,47589,N, -57725,48839,N,49321,60631,N,50270,N,50544,N,51570,N,42406,51571,42614,N,42612, -42613,42615,N,42938,42937,N,51900,42939,N,N,51901,52311,N,52312,N,43382,43384, -43386,43383,43387,43385,N,N,N,N,N,43976,43973,43975,43977,43974,53606,52855,N, -N,N,53608,53607,44643,N,44639,N,N,44640,44642,44644,44641,N,44646,44645,N,N,N, -N,N,45386,54514,54513,45385,N,45384,45383,45387,45382,N,N,55509,55506,46153, -55505,55510,N,46155,55508,46152,46154,55507,N,56648,N,56649,56650,N,N,N,N, -47590,47598,57726,47592,47596,57761,47597,47593,47594,47591,47595,48230,55504, -48231,48229,N,48228,59741,48840,60632,60633,N,N,50020,50271,N,42095,N,42616, -43978,N,53609,44647,N,N,45390,45389,45388,46156,46157,55511,47599,48841,42096, -51548,42198,51572,N,N,51668,42617,N,N,N,43388,N,N,N,N,56651,N,N,42097,N,42199, -51669,N,N,51902,N,51903,N,42940,N,N,N,55512,46158,N,56652,N,N,N,49322,42098, -42152,42200,51573,42407,N,42944,42943,42941,42942,N,N,52313,43390,43425,52314, -43389,N,N,43982,52856,43981,43979,43980,44650,44648,N,N,53611,44649,53610,N, -44638,54515,N,N,45392,45393,N,N,45391,N,47600,57762,48232,48233,N,58721,49323, -61378,61379,N,50397,63656,51531,42201,N,42099,N,51575,51574,N,N,N,N,42618, -51671,51672,51670,N,51673,N,N,N,N,N,N,N,51911,N,51906,51908,51910,51907,42948, -51904,N,51905,42945,42946,51909,51912,42947,51913,N,N,N,N,N,N,N,52328,N,52322, -52317,43427,52325,52323,52316,52329,52332,52327,52320,43429,52326,43430,52321, -52324,52315,52319,52331,43431,N,43432,N,52318,52330,43426,43428,N,N,N,N,N,N,N, -N,N,N,N,N,N,52907,52900,52906,52899,52901,52861,52859,N,52908,52905,52857,N, -43984,52903,52904,N,52902,52860,52858,43983,52898,52862,N,N,52897,52909,N,N,N, -N,N,N,N,N,44655,N,44654,N,53612,44651,53614,N,44656,53615,N,N,44659,N,44657, -53616,52910,53618,N,44653,N,44652,N,53613,53617,44658,N,N,N,N,45395,45394,N,N, -N,54517,54521,54523,45396,54526,N,45400,54593,N,45402,N,45398,45406,N,45403, -54519,45397,N,54518,54516,54595,54520,N,45399,54594,45404,54525,54524,45405, -54522,45401,N,N,N,N,54596,N,54592,55527,55534,55523,46161,55519,55535,55513, -55532,55530,55524,N,55533,55526,N,55518,55536,55516,55529,55514,N,55537,N, -46162,N,55531,56655,55517,46159,N,55521,N,46160,55520,55525,N,N,55522,N,N,N, -55528,N,N,N,N,56659,N,N,N,56662,56654,N,56656,N,56661,56660,46915,N,55515, -56658,N,N,46916,N,56653,56657,N,N,N,N,57769,N,57776,57767,N,57774,57765,57773, -57777,57764,57768,57763,N,47601,N,57766,47602,57772,57771,57770,N,N,57775,N,N, -N,N,58725,58727,48235,58728,N,58723,N,58722,58732,N,58730,48234,58733,58724, -58729,58731,58726,N,N,N,N,59745,59750,59744,59749,N,59742,59752,59748,59753, -59747,59743,59751,N,59754,59746,N,60634,49327,N,49325,N,49324,49326,N,N,61380, -N,61810,61949,N,N,62532,62533,N,50272,N,62921,N,50398,N,62922,N,63198,50546,N, -50545,63197,50633,N,63446,N,N,N,N,42100,42619,51674,51914,43189,45407,N,N, -42101,42410,42409,42408,N,N,42949,N,N,44660,N,56663,42102,42103,42104,42202,N, -N,43985,N,52911,N,N,N,46163,42105,51549,42411,42412,51576,N,42620,N,N,N,51915, -N,42950,N,51916,N,N,43438,N,N,52334,43436,43435,52333,43433,52335,43434,43437, -N,43986,N,43988,52915,52912,52913,52914,52916,43987,N,N,53620,53619,N,44662,N, -44661,N,N,N,N,N,45410,54598,N,45409,45411,45408,N,N,N,N,46165,54597,N,46166, -55539,N,46167,55538,46164,N,N,N,N,56666,56668,46917,56667,56665,56664,N,N,N, -57780,47607,47605,N,47606,57778,57779,N,47603,58737,58735,N,48237,58736,48238, -48236,47604,N,N,59757,59755,59756,58734,60636,49328,60635,61381,61382,59758, -61950,N,42106,42413,42622,51675,42621,N,43439,46918,N,42203,42414,43989,46168, -N,51577,N,51578,N,51676,N,N,42952,51920,51918,42953,51917,51919,51921,N,42951, -N,N,N,N,N,43443,43444,43441,N,N,43440,52920,43442,N,N,N,43990,N,52919,52921, -52918,52922,43991,44665,53621,N,53623,44663,53624,44664,53622,N,52917,54599, -54602,54603,54600,45415,45414,45412,45413,54601,N,N,N,N,45416,N,N,46170,46171, -N,46172,56669,56671,56673,46920,46919,46169,56672,56670,N,57784,N,N,57782, -57788,47608,57789,57786,47609,57783,57781,57787,48240,58739,57785,48242,58740, -48241,48244,58741,48239,48243,N,59763,59761,59760,59762,59759,N,N,50022,N, -62534,62535,N,62923,63199,50773,N,N,43445,42954,N,N,43992,N,N,N,42107,42204, -42415,51677,N,42955,51922,N,52923,43993,N,47610,42108,N,N,N,42657,N,N,46921, -42109,42205,42206,N,42417,42416,N,51678,42658,N,51923,N,42956,N,N,52337,52338, -52339,N,43446,43447,52336,43448,N,N,N,43994,52924,N,53626,44666,N,53625,N, -45417,54604,45418,54605,N,N,N,46173,N,N,N,56674,N,N,57791,57790,N,47611,N, -48245,58742,48842,59764,49329,N,50547,63448,N,N,N,N,52340,N,52925,45419,55540, -46922,N,N,N,49749,N,N,N,N,42958,N,42957,43995,N,53627,N,45421,45891,45422, -45420,46174,N,57792,47612,48246,N,51532,51679,N,51925,42959,51924,42960,N,N, -43452,52343,52342,43451,43449,43450,52341,N,N,43997,52926,44000,43996,44002, -43998,43999,44001,N,N,N,44669,44668,44667,N,N,N,54607,45423,45426,45424,N, -54606,45429,N,45425,54608,45428,45427,N,N,N,55542,55541,N,46177,46175,46176, -55543,46923,56676,46924,56675,N,N,58743,N,N,48248,57793,48247,N,47613,N,60638, -59765,49330,60637,62016,62536,62537,N,42207,N,42418,N,N,N,51579,N,N,42962, -42964,N,51682,51928,51927,51926,N,51681,51680,42660,42963,42961,42659,N,N,N, -43453,52344,N,43454,51933,N,51935,51934,52345,N,N,51930,N,42968,42966,N,51929, -51931,51937,N,42965,N,51932,51941,43456,N,51938,42967,N,51936,51939,N,43455,N, -43457,51940,N,N,N,N,N,N,N,N,52399,52386,52350,52398,52393,44007,43458,52394, -52397,44003,52396,43459,43464,43462,52387,N,52348,52389,43469,52400,44004, -52390,N,44005,43465,52392,N,52941,44006,52347,43466,44008,43467,43463,43468, -52391,52346,52395,43460,N,N,52349,52388,52385,43461,N,52927,N,52928,N,N,N,N,N, -N,52938,53665,52939,44014,52942,52932,44013,52934,N,52935,N,N,52937,44009,N,N, -44707,N,N,52933,52929,44708,N,N,52943,44670,53629,52936,N,53628,52931,52940,N, -N,44012,44705,44018,44706,52944,53630,44011,44710,44017,44016,44015,44709, -52945,44711,44010,N,52930,N,N,N,N,N,N,N,N,N,N,N,N,45430,53668,53670,N,53672, -44712,44718,54611,53676,53667,45432,54609,N,44717,44715,53678,N,54610,N,53669, -N,44716,53673,44719,53675,N,N,44714,53674,53677,53671,N,44713,45433,N,53666, -45431,N,N,N,N,45434,N,N,N,N,N,N,N,54613,54622,46180,N,45436,45475,46181,54624, -45482,55545,54614,45474,45477,45438,54612,54626,54629,55625,N,54627,55549, -45473,45480,45484,54621,55544,54625,45435,55546,54628,55548,54617,N,46178,N, -54615,54616,45479,N,N,45478,54619,45483,54623,45476,54620,N,45481,46182,46179, -55547,N,54618,N,45437,N,N,N,N,N,N,N,N,N,46187,46191,55616,46929,46189,55620, -46193,56677,55622,46931,46185,46188,55623,N,55624,55630,46195,46932,N,55626, -55631,55619,46942,N,46933,46194,55617,55632,N,46941,46192,46926,55629,N,46196, -55621,55550,46186,55618,N,55627,N,46925,46930,46183,55628,N,46928,N,N,N,46184, -N,N,N,46940,57795,56688,N,56680,57794,N,56684,56686,N,N,56683,N,46939,N,56682, -46943,N,N,N,57810,N,N,46938,47680,56689,57796,N,N,46936,56681,56685,47614, -46927,56678,56679,47681,46935,46937,46934,56687,N,N,57800,57801,57806,48253, -57813,N,47687,N,47686,57808,N,48252,57797,47685,N,57812,47683,47684,N,57809, -58794,48250,46190,N,57811,48291,57803,N,48251,N,48290,57798,57802,57799,57805, -47688,48249,47682,N,58746,57807,N,48289,N,48292,N,57804,N,48254,58745,N,N,N,N, -N,58750,48846,58744,59811,58793,48296,N,48294,48844,58790,58786,48300,N,59768, -N,N,N,48298,58785,N,59766,N,58789,N,58792,58749,N,48299,N,N,48293,59767,48845, -58791,48295,48297,58788,48301,58787,58748,58747,48843,58795,59770,60640,48848, -N,59810,N,59774,N,60641,N,48849,59809,N,59772,49332,60639,N,59769,59771,49333, -48851,49331,48850,49335,59773,48847,N,N,N,N,N,N,N,N,61391,N,61383,N,N,N,N,N, -60647,61384,60643,N,N,49750,60645,60644,49334,60642,60646,61392,61388,61390,N, -61385,61386,N,61389,61387,50023,N,N,50026,50025,50024,50273,62538,50274,62017, -50399,62924,50400,50548,50634,63449,N,63450,63451,N,N,63930,42208,51580,42419, -N,42662,42663,42661,N,42664,42970,42969,N,52401,43471,43470,N,N,53679,45485, -45486,N,N,N,46197,56690,46944,46945,56692,56694,56693,N,57815,N,57814,47689, -57816,N,58796,48302,N,48852,N,49336,49751,49337,N,42209,N,N,N,51942,N,N,52402, -43473,43472,43474,44019,52946,52947,N,N,53680,44720,45487,46198,55633,42210,N, -42110,42211,N,51581,42423,42422,42420,42421,N,N,N,42667,51689,51691,42666, -51683,N,51684,N,51690,51686,51688,42665,51685,51692,51687,N,N,N,N,N,N,42977, -42986,42984,51952,51949,51957,42982,51958,N,42975,51955,N,42981,51951,51950, -42979,51956,42980,43475,42974,51953,N,51943,42971,N,42990,51948,51954,42976, -42978,N,51944,N,51945,51946,N,42989,42983,42988,51947,42987,42973,42972,42985, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43489,52414,52407,43484,43503,52403,52410,52412, -52415,43498,N,52411,52404,43496,52408,N,52416,43481,N,52413,43491,43490,52406, -43479,N,N,43480,N,43478,N,43502,43494,43488,43476,52409,43487,43477,43495, -43504,52948,43492,52405,43482,43485,43486,N,43500,43501,43499,43493,43497, -43483,44020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,52954,44097,44024,44026,44096,52966, -44029,53681,44721,44099,52951,52959,44030,52958,52955,52963,52965,44023,44027, -44098,44723,52960,44025,44101,52953,N,N,N,44028,44722,44022,N,52950,52957, -52949,52952,52956,53682,44100,N,52961,52962,52964,44021,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,44737,53694,44735,44736,53684,53700,N,44726,N,N,54630,53702,53696, -N,53687,N,53705,53690,44732,54653,53693,44734,44725,N,53707,53695,44728,53688, -53685,53686,44729,53701,53708,44731,53692,53691,44739,44738,44724,44730,44733, -53704,N,N,53698,44727,53683,53706,53697,53699,53703,N,N,N,N,N,N,N,N,N,N,54631, -N,45495,45515,45514,N,45503,N,54649,54645,54642,54694,45498,45490,N,N,54647, -46248,45494,54689,N,45516,45513,54651,54634,N,N,45512,54691,54633,45501,45505, -54690,N,54643,45506,45500,54632,N,46200,54693,54641,45511,54644,54692,45510,N, -55634,N,45491,54639,45496,45507,N,45502,54648,54638,54636,54654,45488,45508, -45492,46199,54652,45493,N,45489,45504,45499,45497,54640,45509,54637,54650, -54646,55636,55635,N,N,N,N,N,N,N,N,N,N,N,54635,55652,N,46202,N,55658,55641, -55655,56695,46205,55659,55662,46204,55644,55661,55660,46206,55637,46201,46243, -N,46241,55657,N,55647,46245,55664,55656,55665,46253,46251,55654,55653,N,55651, -55645,46244,N,46242,53689,55638,N,56759,55639,46203,46250,56697,N,46246,46247, -55640,55663,56696,55648,55643,46249,55649,55646,N,N,46254,46960,N,N,56700, -56753,56758,56746,46956,56763,46953,56698,N,56699,46946,46955,56740,46958, -46959,56741,N,56754,56760,46954,N,46948,56739,56701,56762,56744,56745,56702, -56756,56747,56757,56749,N,46949,57817,46952,46950,56761,56752,56748,N,N,56737, -47699,56751,46957,56743,N,56742,N,N,N,46951,46947,57838,56755,56750,N,56738,N, -N,N,N,N,N,N,57833,N,57818,57829,N,57836,47697,46252,57834,47692,N,N,N,47691, -57841,N,57819,57832,57820,57831,47695,57835,55650,N,N,N,57842,57827,47698, -58810,48303,N,57840,57839,47700,58797,48304,58798,N,57823,57824,57821,57826, -57822,57843,47694,48305,47696,47701,N,57825,N,57837,N,N,57830,N,N,58801,N, -47690,48308,59818,58806,58805,58807,N,N,58804,48309,N,48315,48312,N,48313, -58799,58802,58812,48321,48319,N,58803,55642,48306,58809,58800,N,48322,58808, -47693,48311,57828,N,N,48314,N,48318,48320,48317,48316,N,48310,58811,48307, -48323,N,N,N,N,N,N,N,48856,48857,59817,48866,48863,N,48854,48861,59819,48859, -48853,N,48860,N,59816,49339,48855,N,48862,49338,59815,59814,N,48864,N,48865,N, -59813,59812,49340,59822,48858,59820,N,N,N,N,49341,N,49346,60650,60652,N,49343, -N,60653,60649,N,60651,49344,49347,N,60648,49342,49345,49753,59821,49752,N,N, -49758,61396,N,49756,49757,61399,61395,49754,61393,50027,61397,N,61398,61394,N, -49755,62018,N,62021,N,N,62022,62020,62023,50028,62019,N,N,62542,50276,62541, -62540,62539,50275,50277,N,62925,50402,50401,N,N,63201,63200,63203,50635,50549, -63453,63202,N,N,63452,50637,50636,50675,63657,63727,42212,N,N,55666,59823,N,N, -42668,51959,42993,42991,N,42992,N,52417,43505,44102,N,52967,N,52968,N,44103, -53710,N,44740,44741,53709,N,N,N,N,45523,N,45519,N,54695,45526,45525,45518, -45521,45524,45520,N,N,55670,45517,46255,N,N,N,46257,46258,55669,55672,46256, -55667,55671,N,55668,N,46961,N,N,56764,N,N,47702,57844,48867,48324,58813,48325, -48326,58815,58814,58816,59825,N,N,59824,60655,60654,49348,49349,62024,N,N, -42213,N,N,N,N,55673,N,N,N,46260,46259,56765,N,61400,50403,63454,42214,N,44742, -N,45528,45527,55674,55675,46962,57845,47703,59826,N,42215,42424,N,43506,52418, -N,52969,44104,45529,N,55676,46261,46963,N,58817,58818,N,N,60656,49759,63728, -42216,N,52419,43507,44105,N,52970,N,44743,53714,53712,53713,44744,53711,N,N,N, -N,45531,45532,54696,45533,45530,55677,N,55678,56766,N,N,47705,47704,N,N,60657, -61401,N,62026,62025,62543,N,51550,44106,N,N,42217,42425,N,42670,42669,N,N, -42671,42672,51694,51693,51960,42994,51963,51962,51961,51964,N,N,N,N,43508, -52425,52421,52430,43515,N,43513,52426,52422,52429,43512,43584,52424,52420, -43518,52427,43511,52428,43514,43516,52432,52431,52423,43510,43509,43517,N,N,N, -N,N,N,52975,52981,N,44112,44109,52972,52977,N,44115,44107,52976,44110,44113,N, -N,52979,N,44108,52984,44111,N,44114,52973,52978,52982,52974,52971,N,N,52983, -52980,N,N,N,N,N,N,44752,44745,44748,N,44751,N,53717,N,44746,53715,N,44750,N,N, -44747,N,53718,44749,N,N,N,N,N,N,54700,45535,54699,54701,45534,45539,53716,N, -54698,54702,N,45536,54697,45538,N,45537,N,55719,N,55714,N,46262,46266,46263, -55717,55720,N,46264,N,46265,46270,56775,55718,46268,55715,55713,N,46269,N, -55716,N,N,N,46969,N,56767,46966,46967,46965,56772,56771,56768,46971,N,N,56770, -46267,N,N,56774,56769,46968,46964,46970,56773,N,N,N,47708,N,57848,57847,57846, -47706,N,N,N,N,N,47707,58821,58824,48328,N,N,48327,58825,58820,48330,58822,N, -48329,58819,N,58823,48873,48870,59835,59834,N,59833,59828,N,59829,N,N,N,48871, -N,48868,48872,59827,48869,59830,59831,59836,N,N,59832,N,N,60658,N,N,N,49351,N, -61404,49350,61402,61403,49760,50030,62027,N,50029,N,N,62545,62546,N,50278,N, -62544,50404,N,63455,50638,63658,63659,N,42218,N,42673,42674,42995,N,52433, -44116,44753,45540,N,N,45266,N,46271,46272,46028,55721,N,46972,57850,57849,N,N, -42219,42675,52434,43586,N,43585,N,52985,52986,N,53719,53720,44754,44755,N, -44756,54703,N,N,45542,N,46274,N,46273,56776,57210,57851,59837,N,N,49761,50279, -42220,N,42428,42429,42427,42430,42426,N,N,42678,N,51702,42677,42679,N,N,51697, -51696,51699,51698,51701,42676,51695,51700,N,N,N,N,N,51965,43005,51966,52035, -43004,N,52039,52034,52037,42997,42998,42999,43000,N,43072,N,52033,43002,43073, -N,52032,52038,N,43001,52036,43003,42996,43006,N,N,N,N,N,N,N,N,N,43607,N,52436, -43587,N,43597,43598,43590,43608,43592,52444,43603,52439,43593,52454,52455, -52447,52440,43606,52452,43601,43599,N,52453,N,52451,52443,52435,52442,43594,N, -43600,N,43588,52446,52445,52437,N,43602,52449,52438,43605,52456,43589,N,43596, -52441,52450,43604,N,43591,43595,N,52448,N,N,N,N,N,N,N,N,N,N,N,N,N,N,53083, -44124,44137,N,53078,53068,44130,53066,44123,53061,44133,53074,52990,53057,N,N, -N,N,53060,52987,53073,53089,44128,53062,53080,N,52989,53087,53088,53091,53082, -53067,53075,44134,44121,44129,44141,44118,44120,N,N,N,53059,44138,44131,53085, -53056,44140,44135,53065,N,N,44139,53072,53064,44132,53084,53076,N,44126,53090, -53063,44122,53081,53071,44127,53077,44119,52988,44136,44771,44125,53070,53069, -53058,N,53086,N,53079,N,N,44117,53740,44778,53741,N,53729,44767,44779,N,53722, -N,53731,53739,N,53721,53748,44757,N,N,N,53747,53742,N,53743,44765,44776,53733, -N,53734,53744,53735,N,53730,53724,53725,53738,53732,N,N,44758,44762,53746, -53726,44774,44770,N,N,44773,44780,44763,44775,53737,44777,44760,N,44759,53723, -N,53727,44768,53745,53736,53728,44772,44769,N,44761,44764,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,54724,N,54708,54709,54713,N,54728,54725,N,54718,54717, -45549,54721,54736,54704,N,54737,54723,54741,54729,45548,54727,45543,45564, -45554,N,45558,45557,54705,N,54734,54740,54732,54739,N,N,54720,54706,54738, -54722,45546,45559,N,54731,45552,N,N,N,54730,54707,45560,N,45562,54733,45563, -45545,54714,54735,N,N,45551,45561,54716,54726,54711,54715,45556,54710,45544, -45553,45550,54719,44766,55744,45547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,45555,N,55747, -55769,55758,46294,N,46289,55741,46290,55757,N,55750,55763,46286,55723,55765, -46276,55731,46279,46278,N,46295,N,55725,55759,55760,46281,46277,55739,N,46288, -55734,N,55761,46284,55753,55766,55728,55733,55727,N,46283,55746,56798,55729, -46287,55738,55762,46282,55735,55732,55749,46285,46275,46297,55752,55751,55724, -46280,55764,55740,55742,N,55755,55754,55722,46291,46293,55730,55737,55745, -46292,55736,55748,55767,N,55756,N,N,N,N,N,N,N,N,N,N,N,N,N,55768,N,N,N,N,55726, -N,N,N,N,56818,47014,N,56816,56795,56800,56793,N,56812,56779,56786,N,56810, -56820,56796,N,56783,56802,56807,56787,N,56804,56784,N,N,56791,56792,47016, -56811,56809,N,56780,56814,N,56815,56817,47020,47012,N,54712,56788,56806,56789, -47009,47025,56813,47023,47019,56778,47011,N,56781,47024,N,56797,56777,N,47017, -56801,56785,47018,56794,46974,46296,56803,55743,56782,N,N,56808,47013,56805, -47010,56799,47021,56790,56819,N,N,N,N,N,N,47015,57030,N,N,47022,N,N,N,N,N,N, -57930,57928,N,57950,57926,N,57944,46973,47711,57922,57949,N,57927,57941,47716, -47709,N,57947,N,57920,57946,N,47727,57937,57953,47725,57929,47710,57931,57945, -47719,57924,47723,47713,57933,57923,57852,N,57943,47720,57952,57853,47717,N, -57939,N,47718,57925,57936,57932,57934,N,47712,57951,47726,57935,N,57954,N,N, -57854,57940,47715,47724,47722,57921,57942,47721,N,N,47714,57938,N,N,N,N,57948, -N,N,N,N,N,N,N,N,58837,N,58833,58829,58849,58846,48333,N,N,58853,58836,48344, -58843,N,N,58832,58842,48341,58862,N,58859,58845,58830,N,N,58850,58852,48337, -58840,58835,58826,48334,48342,N,58855,48343,58827,58861,58848,58854,48340,N,N, -58851,N,58858,N,48345,N,48339,58844,58831,58863,58828,58856,48336,N,58838,N, -58839,48335,48332,58834,48338,N,48331,N,58857,58860,58841,59850,N,N,N,N,N,N,N, -N,N,59842,N,59838,48886,N,N,48875,48880,48876,59852,59863,48874,59844,59853, -58847,59854,N,N,48881,N,59869,48885,48888,59840,N,48884,N,59867,59868,59858, -59857,59849,N,N,59859,59866,59865,N,48879,48877,59851,59848,N,59845,59864, -48887,59862,48883,48882,N,59856,N,59839,59841,59843,59861,59855,48878,N,59846, -N,59860,N,N,N,N,N,N,59847,N,N,N,N,N,N,N,49359,60741,49352,60661,N,60737,49354, -60744,N,60668,N,60663,N,N,60745,60659,60670,N,49361,60740,60746,60669,49353, -60736,60660,49360,N,N,60743,60665,49356,N,60667,60664,49362,60666,49355,49358, -60739,60662,60742,N,60738,N,N,N,49763,61415,49768,49769,N,N,N,49762,61414,N, -61411,61412,49766,61406,61410,49765,N,61407,N,N,N,N,49767,49764,N,61405,61409, -61413,N,N,N,62033,62030,62039,N,62038,62036,62031,N,50034,N,N,N,N,N,62032, -50033,49357,62035,50032,62040,62034,62029,61408,N,N,N,50031,N,62028,62550,N, -62549,62037,50280,N,62553,62554,62548,62552,N,62547,N,N,N,N,62929,62551,50407, -50405,62927,62930,N,62926,62928,50406,N,N,N,63205,63206,50550,63204,N,N,N, -63458,50639,63456,63457,63660,N,N,50774,63731,63729,63730,63732,N,N,N,63931,N, -42221,42680,N,43609,N,52457,N,N,53092,N,N,N,53749,53751,N,53750,N,53752,45565, -54743,53753,N,54742,54744,54745,55770,46299,55771,55773,46300,46298,55772,N, -56826,56824,56823,N,56822,56821,47026,56825,47728,57955,57957,47729,57956, -48347,N,48346,58864,N,N,59871,59870,59872,N,N,48889,N,60747,49363,N,61416, -49770,62041,50551,42222,42431,42681,43074,43610,43611,N,N,44142,N,N,53754,N,N, -N,N,47027,N,N,N,59089,48890,49771,42223,N,42682,N,N,52459,43612,52458,N,53093, -44143,53094,N,44144,N,53756,44782,44781,N,54750,54748,54749,54747,N,54746,N,N, -55774,55777,46302,55775,46301,55776,N,56827,N,N,57958,57959,57960,N,58867, -58866,48348,58865,58868,59873,N,N,59874,59875,N,60748,49364,49772,62042,N, -50408,51551,N,44145,53095,44783,N,N,45566,N,46303,55778,N,47029,47028,N,N, -57961,57962,48349,48350,59877,59876,61417,63459,42224,51552,42432,N,43075, -52040,N,44146,47030,42225,N,53096,44147,53097,N,49365,42226,N,N,52460,N,53098, -N,53826,53825,53758,N,53757,53827,53824,N,N,45632,45633,N,N,46304,55779,N, -55780,55781,N,N,N,56897,56898,56896,N,56829,56830,47031,57963,58871,58870, -58869,58872,59879,59878,48891,59880,N,49366,60749,N,61418,62043,63207,N,42227, -42434,42433,N,43613,51553,51582,42683,N,51703,52041,52042,43614,N,52461,N, -44148,53099,53100,N,44784,44788,53828,44787,44785,44786,N,54751,45634,46307,N, -46305,46306,55782,N,N,47730,42228,N,51617,N,42435,N,N,51620,N,N,42438,51619, -42437,42436,43076,51618,N,N,51704,N,N,N,51708,51710,51776,42693,42694,51707, -42689,N,51705,N,51709,42690,N,42685,N,42686,N,42692,51706,42684,43077,42687, -42688,42691,N,N,N,52059,52057,52044,43089,52051,43084,52045,N,52053,N,52050, -43087,52049,43094,52058,43096,N,43098,N,52043,N,43085,52060,N,43092,43095,N, -52549,43079,43102,43093,52046,43082,43097,52054,43080,43081,52547,52047,43088, -43099,52061,52048,43086,N,43091,52462,43100,52055,43090,N,43101,43078,52052, -43083,52056,52548,N,N,N,N,N,N,N,N,N,N,N,N,N,43626,43642,52469,43633,N,52555, -43618,N,43621,52546,N,52467,52471,43629,43631,52474,43638,43624,43622,43623, -43637,52551,43632,52473,52475,43630,43635,52476,52554,N,44149,43641,N,43619, -52553,N,52557,52472,52559,52544,43628,52468,43627,43645,43634,N,52466,53109, -43640,43644,52545,52550,N,43646,43639,43625,43615,N,43620,N,52470,43616,52558, -N,52464,52463,52477,52465,43643,44789,43636,52478,43617,N,44198,N,N,N,52556, -53116,53153,N,53156,53111,N,N,53159,53162,53164,53108,44150,44155,53833,44205, -53157,53165,53115,53107,N,N,N,53860,44158,53154,53112,53114,44197,N,53117, -44157,53104,53160,N,53163,N,N,44154,N,44200,53101,44202,44152,44206,53161, -53103,44203,53854,52552,44156,44151,53110,53102,44204,44196,53155,44201,44199, -53113,44193,53105,44194,44195,53106,53158,44153,53118,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,53836,44797,44867,N,N,N,53845,53851,53847,53834,53837,53830, -53831,44874,44794,53846,53855,44869,44790,N,44864,53838,44866,53839,53849,N,N, -N,44868,53864,53832,44796,44795,44872,53829,53862,53850,53863,53857,53843, -53858,N,53852,53861,53859,44873,53844,44793,44792,44865,44871,53856,44870, -53841,45635,N,53865,53840,53835,44798,44875,44791,N,53848,53853,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,45669,54753,54757,N,45650,45648,N,N,45639,54755,54754, -45659,N,54760,45653,N,54778,54855,45636,54775,54768,45671,54752,N,54780,N, -45668,45656,45667,45646,54764,54782,54774,45647,45641,54853,N,54781,54848, -45649,45657,54850,54762,54779,54767,54852,45662,45638,45660,54772,54770,54771, -45651,54766,54765,45640,54759,54854,45642,54769,45672,N,45666,54758,45663, -45661,45670,54776,45665,53842,54777,45664,54849,45637,54773,45655,54761,45654, -N,45652,45644,45643,55783,54851,54763,N,N,55804,N,45645,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,46401,45658,46318,55798,46332,N,55786,46315,46311,55881,46317, -46321,46316,46325,55885,55876,N,N,55793,46330,46324,55805,46308,55882,55875, -46312,55799,46327,55893,55894,N,46309,55880,46329,55803,55789,55790,46333, -55794,55801,55795,N,46331,46404,55791,55784,55785,N,55787,46314,55800,N,46328, -46402,N,N,55802,55891,55883,46310,55889,46322,N,46320,N,55895,46319,55873, -55796,55806,46407,55877,55874,55792,46403,55887,55884,55892,46313,55872,46406, -N,55879,N,N,46323,46326,N,55878,46405,55797,54756,N,N,55888,55886,55890,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,55788,46400,N,N,N,56929,56928,56902,47037,N,56927,56905, -56906,N,47047,56936,47042,56926,N,56899,47048,47038,56914,56904,56907,56931, -47032,56938,56930,47041,56919,47052,N,N,47051,47045,N,N,56937,47033,56917, -56908,56921,56933,47053,N,47035,56916,N,56909,47044,N,47043,56912,56922,56932, -56903,56913,47036,56923,47049,47040,56910,47039,56901,56915,56935,46334,47792, -56918,57964,56920,56934,47046,56911,47034,47050,48368,56900,N,56925,N,N,N, -56924,N,N,N,N,N,N,N,N,N,N,N,N,N,N,58026,47789,57981,58020,47778,N,57966,47791, -N,47735,57965,58032,47793,57969,58019,N,57971,58035,58031,47733,47777,58963, -47790,47741,57967,N,58030,47779,58027,58040,57973,57982,N,N,58038,58028,47740, -N,N,57980,47734,47732,47784,N,N,57978,57975,57976,N,58034,N,58039,58037,47738, -58041,47742,47783,N,57968,58874,57977,N,47736,47788,47785,47739,58021,57972, -47786,58023,47780,47782,47731,N,58025,58017,57970,47781,58033,58036,57979, -58024,N,47737,48351,58022,58873,N,58029,N,N,N,N,N,N,N,N,N,N,57974,58948,58958, -48354,58957,58969,48356,58955,N,58959,48367,N,58950,48359,N,58962,59888,48371, -48370,58964,58947,58974,48365,N,48355,58967,N,58971,58976,58965,58953,48358, -48361,48369,48364,N,58956,58018,N,N,58952,58975,48360,N,48363,58977,48352, -58966,58875,58972,49375,N,58954,N,48353,58949,48357,58876,47787,58945,N,58970, -58946,58944,48362,N,58968,N,58878,58961,58960,58973,58951,48366,N,N,N,N,N,N, -59891,N,48969,48894,59968,59883,48961,59895,48968,48963,59893,60751,59899, -59970,59898,59881,59896,59972,59974,48893,59973,48964,48970,N,48967,N,59902, -48966,59897,N,59885,59890,N,59901,48965,48962,48892,48960,59889,N,58877,59884, -59887,59969,59892,59882,60750,59971,59886,59900,N,N,N,N,60753,49379,N,N,49367, -N,N,49371,60755,60761,60759,49369,49370,49377,60762,60754,49372,N,60758,60757, -60763,49378,N,49373,49376,60756,49380,49374,49381,49368,60760,N,60752,N,N, -61431,N,N,49777,61428,61430,N,49775,61426,61427,61422,N,N,59894,61423,49776, -61419,N,49773,61432,49774,61420,61421,61425,49779,N,49778,N,N,61424,50040, -62047,62053,50041,62044,50038,50035,62055,50039,N,50036,62046,62049,62050, -62051,62054,N,61429,62045,50037,62052,62056,62048,N,N,N,62557,50282,62560, -50283,62568,62559,62556,N,62558,62562,62565,62564,62567,62555,N,50281,62563, -62566,62569,62561,62931,62932,62936,62937,N,62934,62935,62933,N,50409,N,N,N,N, -50552,63211,N,N,63208,63209,63210,50553,N,63461,63460,N,63663,50676,63661, -63664,63662,63733,50775,50789,63907,63852,N,63906,63952,63953,42229,N,N,N,N, -42695,51777,N,N,52062,N,43103,N,43106,N,52063,N,43104,43105,N,N,N,N,52568, -52570,52565,52562,52564,N,N,N,43684,N,N,N,43682,N,N,52566,43683,52563,52560, -43681,52567,N,52561,43685,52569,N,N,N,N,53167,N,53171,N,N,44215,N,N,N,N,53174, -N,44207,44210,44212,44214,44211,53170,53169,N,44209,53172,53173,N,53166,44213, -N,44208,N,N,N,53168,N,N,N,N,N,N,53879,53880,53881,44880,N,44876,53870,N,53878, -53883,44881,N,53868,53874,53867,53877,N,N,53873,44877,44879,53882,N,53866, -53869,53875,N,53876,53884,53872,N,44878,N,N,N,N,N,N,N,N,N,N,45677,54862,N,N, -54864,54860,N,54872,54858,54871,45673,54856,55899,54866,45676,N,54867,54870,N, -54874,N,54863,N,54868,N,N,45674,45675,54873,54861,54857,54875,N,54865,N,N, -54869,N,N,N,54859,N,46408,46409,55909,46415,N,55897,55906,55896,46412,55904, -55902,N,55903,46410,N,55907,N,N,N,N,N,55900,55898,46411,55901,55905,N,N,N, -46413,N,N,N,55908,N,N,N,N,N,N,56944,56951,56953,56993,N,47066,56939,N,47058,N, -56954,47063,56994,47054,N,56957,N,56941,56958,56940,N,47068,N,56952,47055, -56995,N,47060,56945,47065,56956,56943,56950,56946,56942,47057,47064,47062, -47059,47067,47056,56949,N,47061,N,46414,N,56955,N,56947,N,N,N,N,N,56948,N,N, -58049,N,47796,N,N,58045,58051,58047,N,47798,58046,58050,58042,N,58044,47797,N, -N,N,N,58048,58043,N,47799,N,47794,N,N,58052,N,47795,58983,58980,58992,58986, -58988,48372,58982,58990,N,N,58989,58987,N,58993,48375,58984,58991,N,48373,N,N, -58979,58981,48374,58978,58994,N,58985,N,N,59978,48977,N,N,59989,59987,48971, -59977,59980,59981,59976,48981,48982,59975,59990,59985,48975,48972,59984,59982, -N,N,48978,59986,48973,N,48974,N,59983,48976,59979,N,59988,48979,59991,59992, -48980,N,N,49383,49390,60764,60770,N,60768,49386,49385,49382,60766,N,N,N,49388, -49387,49384,N,60769,60765,60767,N,49389,N,N,N,49783,61435,N,49780,49781,61437, -49782,61434,61433,62060,61436,N,62061,50042,62059,N,N,62058,N,62057,50043,N,N, -50284,N,N,62570,62571,N,N,N,N,62940,62939,50410,N,62938,63212,63213,N,N,63462, -63665,N,N,63734,63932,50809,63942,42230,N,43686,43687,N,N,44216,N,N,N,N,49391, -42231,N,43688,44882,47069,42232,N,45678,47800,51554,N,53175,53885,N,58053,N, -49392,42233,43689,53176,53177,55910,46416,N,N,56996,N,N,47070,58054,N,N,48376, -N,50044,42234,55911,42235,N,42697,51778,42696,43109,43108,43107,52064,N,N,N, -43690,N,43691,52571,N,53178,N,53181,44218,53179,N,44217,53180,44219,N,53922, -53921,53886,44883,N,54877,54878,45679,54876,54879,46418,45680,N,N,46417,55915, -55914,N,55912,55913,N,55916,56998,56997,57001,N,57000,56999,47801,58057,N, -58056,47802,58055,58995,N,58996,48377,N,59993,59994,N,N,62066,50045,62065, -62064,62062,62063,50411,62572,63214,63735,N,42236,N,51621,42439,51622,N,N,N, -51779,51780,N,N,N,N,52070,N,N,52066,N,52065,43692,52069,43111,52067,43110, -52071,52068,N,N,52575,53182,52573,52580,N,43693,N,43696,52581,52577,N,52578,N, -52572,43695,52574,43694,52579,N,52576,N,N,53186,44221,44222,N,53189,53183,N, -53188,N,53184,44220,53187,53185,N,N,N,N,N,N,N,53928,53925,N,53927,44888,44887, -44885,53924,53929,44884,44886,53926,54887,53923,53930,N,N,N,N,N,54882,54886,N, -54885,55918,55929,N,N,54888,N,54883,55917,45684,N,N,45683,54881,54884,45685,N, -45682,45681,54880,54889,N,N,N,55920,55927,N,46420,55926,55923,N,46422,N,N,N, -55925,N,N,55919,55921,55924,55922,46421,55928,46419,47071,N,N,57005,57004, -57002,N,47074,47073,57006,N,57003,58058,47803,47072,N,N,N,57008,57007,N,58061, -58059,48378,N,47804,58060,58998,N,N,N,N,48379,58997,59006,59005,59003,N,59002, -58999,59000,59001,59004,59041,N,N,59999,59996,59997,48983,59995,60001,60000, -59998,N,60772,60773,49393,N,49394,60771,N,49785,61438,49784,50046,N,50081, -50285,62574,62573,62941,63215,50554,63464,63463,63465,42440,53190,44889,45686, -54890,42441,51623,42237,N,N,51781,N,N,N,52076,52074,52075,52072,43112,52073,N, -N,N,N,N,52589,N,43699,52587,52583,52586,N,52582,43701,52585,N,43698,43697,N, -43700,52588,52584,N,N,N,N,44226,44229,53198,53197,53196,44223,53205,53195,N, -44225,53935,N,53202,53200,44228,N,53192,53203,N,53194,53204,53201,53193,N, -44224,53206,53191,44227,N,N,N,N,53940,53931,53942,N,53934,53945,53946,53932, -53944,53941,53939,53943,44895,N,44893,N,N,53937,N,53933,N,53936,53947,53938, -44894,53199,N,44890,44892,N,N,N,N,N,54904,54893,54891,N,54892,N,54899,N,54900, -54896,45691,54901,54898,54895,N,45689,54894,45687,45690,54897,54905,44891, -45688,54903,54902,45692,N,N,N,N,N,N,N,N,55934,N,N,N,55969,46432,N,55975,N,N, -55977,55970,46426,55974,55973,46427,46433,N,46434,55976,46424,55933,55931, -55971,55930,46431,55932,55972,55978,46425,46430,46428,46429,N,N,N,46423,N,N,N, -N,47081,57015,47080,57019,N,57009,N,57020,N,N,N,57010,57011,N,57021,57018, -57016,57017,57013,57012,N,57022,47077,N,57014,N,47082,47076,47083,47084,N, -47079,47078,N,N,58062,47806,47805,N,N,58067,N,48380,47807,N,N,47809,58068, -47075,47808,58064,58066,58063,N,58065,N,N,N,59051,N,N,59050,59047,48448,60002, -48449,59046,N,48382,N,59048,59045,59042,59049,59043,59044,48381,N,N,N,N,60777, -N,60006,N,60005,60007,N,60774,48986,N,60003,N,48984,N,48988,48987,60004,60008, -N,48985,N,60781,49397,49786,49398,49395,60778,60776,N,60779,N,60782,49396, -60780,60775,N,N,61506,61509,62069,61504,N,62575,61510,N,50082,61508,49787, -61505,61507,61511,62070,N,62068,N,N,N,N,50083,62067,N,N,N,50286,N,N,N,N,50413, -63217,50412,63219,63216,63218,50640,63666,42442,52590,53948,53949,45693,57023, -48989,50084,50555,63667,42443,N,52591,41568,N,N,53207,N,53208,N,N,N,N,N,53950, -53951,45694,45729,N,N,N,55979,N,57026,57025,57024,58069,N,58070,58071,47810,N, -N,59053,59052,N,N,60009,48990,48991,N,60786,60783,60784,60785,61513,61512, -49788,62071,62942,42444,N,44230,N,45730,57027,N,42445,N,53952,45731,N,N,46435, -46436,N,42446,42447,51782,43114,43113,44231,53209,55980,42448,42449,42450, -42451,N,N,N,43115,43116,52078,52077,N,N,43702,52594,52592,52593,N,N,N,N,N,N, -53210,53211,N,N,44235,44233,N,44234,44232,N,N,N,N,44896,N,N,N,N,44900,44899, -53953,44898,44897,N,53954,N,N,45734,54907,54906,45732,45733,N,N,N,46438,46437, -55982,N,N,55981,45735,N,N,N,N,N,47085,57029,47086,57028,N,N,N,58072,59054, -48450,60010,N,N,N,60787,N,50086,50085,N,N,50556,42452,52595,N,N,45736,58073, -47811,N,N,52079,52080,N,N,52596,43704,43705,N,N,43703,N,N,N,N,44239,44240, -44237,44238,N,53212,N,N,53213,44236,N,N,N,N,53955,N,44904,44905,N,45739,53961, -N,44910,44908,53962,53957,44907,44906,44901,53960,53959,53956,44909,N,53958, -44902,N,44903,N,N,45740,54945,54946,45741,54908,54910,54948,54947,54909,N, -45737,45738,N,55990,46443,46442,55984,46440,N,55987,46444,55988,46445,55985, -46439,46441,55989,N,55986,55983,N,N,N,N,N,57042,N,57031,47088,47091,47090, -47095,47094,57043,57041,57034,57038,57037,47092,57040,57036,57044,57035,47093, -47087,47089,N,57033,N,N,N,N,58075,47815,58079,47814,58076,47813,N,57032,57039, -58078,N,47816,58080,58077,58074,N,N,59057,59061,59063,59059,59058,59056,48453, -48451,48456,48457,59060,48454,59055,48455,47812,59062,48452,N,N,N,60012,N, -60011,60019,60013,60018,60015,48992,60017,N,N,48993,N,48994,N,60016,60014,N,N, -N,N,49400,60788,N,N,49399,60791,60789,60790,N,N,49401,N,N,N,61517,N,49825, -61518,N,N,49789,61519,49790,61516,61520,N,61514,N,N,50087,62072,50088,50287,N, -61515,50288,N,N,N,50414,62943,N,50558,63220,50557,N,63466,50677,50678,N,N, -63948,N,N,44241,53214,N,46446,46447,42453,42698,51783,N,52081,43117,N,43706,N, -44242,44243,44244,54950,53963,44911,N,N,45742,54949,N,N,55992,46449,N,55991, -46448,N,N,57045,48458,59067,59064,59065,59066,N,N,N,N,N,60792,N,61521,N,N,N, -62577,62576,N,63221,42454,52597,44912,N,N,N,46450,57046,N,N,58081,N,48459, -60020,N,61522,62578,42455,N,N,43707,44247,53215,44248,44246,N,44245,53964, -44913,N,N,44914,44915,N,N,N,45744,54951,45743,N,N,N,N,N,55993,45745,46451, -57047,47096,47097,N,47817,N,47818,48460,48996,60021,48995,N,60793,49402,N, -61523,62579,42456,43118,52600,52599,43708,52598,43709,52601,N,53221,44251, -44250,53223,53222,44255,N,44254,44249,N,53217,53218,53219,N,44256,53216,44252, -53220,44253,N,N,N,N,53967,53971,53969,53968,N,53972,N,N,N,53973,53974,53966,N, -53965,N,44917,44918,N,53975,53970,N,54960,N,53976,44919,44916,N,N,N,54954,N, -54953,N,54955,54956,54958,54957,54962,45749,45746,45750,54952,45751,54961, -45748,54959,45747,N,N,N,N,N,55996,55998,55994,55995,N,N,55999,56001,56002, -55997,56000,46452,N,N,57051,N,57056,57048,57052,N,N,57057,57053,47098,47171,N, -47101,57049,57050,47822,47174,47102,N,47172,47100,57055,47173,57054,47169, -47099,47170,57058,58086,58088,N,N,N,N,N,N,N,N,N,47168,N,N,58083,47820,58089, -47821,58087,58082,58085,58090,47819,58084,N,48462,59071,59070,N,48465,48463, -59068,48461,59069,N,48464,N,N,N,60029,N,60065,N,60030,60022,60026,60025,60023, -48998,48999,48997,60024,60027,60028,N,49000,N,49472,60835,N,49404,60795,49406, -49473,N,N,49405,60834,60796,49403,60833,60794,60798,60797,N,N,61525,49828, -49829,49826,N,49827,N,N,61524,N,62075,N,N,50089,N,62073,62074,N,62580,62583, -62581,62582,62944,N,N,50415,63467,63668,N,50679,63736,63737,50790,42457,44257, -N,56003,N,57059,N,42458,43119,N,43710,N,53224,53225,44920,N,N,56004,46453, -47175,49474,60836,62076,62584,42459,N,N,N,52641,52602,52604,52606,52605,52603, -43711,44258,53234,N,53229,53226,N,N,53233,N,N,44260,44261,53232,53231,53230, -53227,53228,53235,44259,N,N,N,N,N,N,N,N,44924,N,44964,44963,53985,53979,53977, -N,44961,54969,44922,53982,53986,53988,53984,53978,44962,53983,53981,44921, -53989,44965,53987,44925,53980,N,44926,44923,N,N,N,N,N,N,N,N,N,N,45753,N,54970, -N,N,54963,54965,54967,N,54968,54966,45754,N,54971,N,54964,N,N,N,N,N,N,N,N,N, -56008,46454,56016,N,56005,N,56017,N,56006,56007,N,N,56015,56014,56011,45752, -46455,56009,56012,46456,56013,56010,N,N,N,N,N,N,N,57070,N,57074,47182,N,58096, -47185,57072,N,N,57069,57064,57066,57067,57060,N,47181,N,N,47180,N,47176,57063, -N,47183,N,47184,57062,57065,57073,47178,47179,57071,57061,N,N,N,58098,47824, -58100,57068,58102,47828,58103,58099,N,47825,58095,47827,58092,58097,58101, -58094,N,N,47177,N,58091,47826,58093,N,N,N,N,N,48468,59073,48472,N,48470,N,N, -47823,N,59080,59081,48467,N,N,59079,59082,48469,48466,59075,59072,59077,59074, -48473,59076,N,N,59078,48471,N,N,N,N,49002,60072,N,60066,60070,60076,60077, -60073,60074,60071,N,60068,N,49004,49001,60067,60069,N,49003,60075,N,49478,N,N, -60842,60837,49477,N,N,49475,N,60844,49476,60840,60841,60838,60845,61526,49479, -60839,N,60846,60843,N,N,N,61530,N,N,61527,N,49830,N,61531,61533,61532,61528, -61529,N,N,62115,N,50090,N,62078,62114,62077,62116,N,N,62113,N,62586,62589, -62585,50289,62587,62588,62590,50290,50292,50291,62945,N,62947,N,62946,N,N,N, -63222,N,N,63669,63738,42460,N,N,52082,43712,52643,43713,43714,52642,N,53240, -53239,44262,44265,44264,44263,53236,53238,53237,N,N,53992,44967,53996,53995, -53994,53990,44966,44970,44973,N,N,44974,53991,53993,44972,44971,44969,44968, -54978,N,54976,54972,45755,N,54973,45756,54974,54975,54977,N,45757,N,N,56021,N, -56020,56019,56018,N,N,N,N,57078,47186,N,57075,57077,N,47187,N,47188,57076,N,N, -N,N,N,58177,N,58105,58106,N,47831,47829,47830,58179,N,58178,58110,58109,58108, -58107,58176,58104,N,59083,59088,59086,N,N,N,59085,59084,59087,N,60078,N,49005, -49480,60848,N,49481,60847,61535,61534,49831,N,62117,50091,62625,50593,63223,N, -63671,63670,51624,44266,44267,54979,N,47190,42461,43122,43121,43120,N,N,N, -52644,N,N,43716,43715,N,44270,N,53242,53245,53243,N,44268,44269,N,N,53241, -53244,N,44981,N,N,N,54003,54005,54004,44978,53999,N,N,44976,44975,N,44979, -44977,N,44980,54002,53997,53998,54001,54000,N,N,N,N,N,N,N,54982,54983,54981,N, -54980,45758,46461,N,56022,56024,56026,46460,N,N,46458,N,56023,46459,56025, -46457,N,N,57153,57079,57082,57086,47194,57084,N,57083,57080,57081,47192,57152, -47191,N,47196,47195,47193,N,57085,N,N,N,58185,N,58184,N,N,58180,N,N,47832, -58183,58182,47833,N,N,N,N,N,48478,N,59090,N,48479,48475,48477,N,48474,48476,N, -N,N,60079,N,49008,60081,60080,N,58181,49010,49009,49006,49007,N,N,N,N,N,60853, -N,60851,49482,60852,N,60854,60850,60849,N,N,61536,49834,49832,49833,N,N,N,N, -62118,62119,50093,N,50092,62627,62628,62626,N,63224,63225,N,N,42462,51784, -43123,N,52645,43718,43717,52646,N,N,53312,44271,53246,44272,N,N,44982,54008, -54006,54012,44983,54007,54011,54009,54010,N,N,54984,54986,N,45759,N,54985, -45760,46498,46497,46462,56027,N,N,N,N,57156,47197,47198,N,57155,57154,N,N,N,N, -58186,47835,47834,58187,58188,N,48481,48480,N,60085,59091,59093,59092,60084, -60082,60086,60083,N,49011,N,N,N,60855,49483,60856,60857,N,N,49835,49836,N, -50293,N,N,50641,42463,N,N,N,N,N,53313,N,N,N,N,N,N,54013,44984,N,N,N,N,N,46010, -46009,N,N,46500,56029,46499,56028,N,N,N,N,57157,N,47836,58189,47837,N,N,N,N,N, -N,50294,62629,N,42699,43719,52647,N,44274,N,44273,53314,53315,N,N,54080,54082, -44985,N,54084,54087,54085,N,N,N,54086,54083,54014,44986,54088,54081,N,N,N,N, -54995,45766,55004,45763,N,54997,45767,N,45761,N,54992,55005,54993,54990,45765, -N,45762,N,54996,54999,45764,55000,45768,55001,54991,54998,55002,54994,54989, -54987,N,N,55003,N,N,56031,N,N,N,N,56036,N,N,N,56032,56038,46503,54988,56033, -46501,56030,46508,56034,46507,56035,46509,46504,46510,46505,N,46506,N,46502,N, -56037,N,N,N,N,N,N,N,47201,57168,N,57171,57159,57164,57158,47203,N,57162,N,N,N, -57160,47202,N,57167,57166,57163,57165,57161,47841,57170,47199,57169,N,N,N,N,N, -N,N,N,N,58205,N,47848,58200,N,47847,58190,N,58192,47840,58197,58196,58199, -47845,58194,58193,N,N,47844,47839,58195,47842,58201,58203,N,58198,58191,47843, -N,N,48489,47838,N,N,58204,N,N,N,N,N,N,N,59097,48482,N,59099,N,48483,N,N,48485, -59102,N,59094,47846,59100,N,N,N,N,59096,N,47200,48488,N,N,48484,N,48486,48487, -N,49014,59101,59095,48490,N,59098,N,N,N,N,N,60096,60091,N,N,60101,49012,60093, -49016,60099,60090,60087,60102,49489,49017,60098,60088,49015,60092,49019,60089, -60094,49018,60097,60100,N,N,N,N,60875,60876,60860,60867,60865,N,N,49487,60872, -60095,N,60863,N,60873,49486,60862,60861,60871,60868,60870,N,60858,60874,49484, -N,60869,60878,60866,49488,49485,60864,60859,60877,49013,N,N,N,N,N,N,N,61539,N, -N,61537,61543,49840,61541,61540,49842,61546,49841,N,61547,61544,49838,61545, -61538,49839,49837,62123,61542,N,N,61548,N,N,62120,N,N,N,50098,50096,62122,N, -62124,62121,50097,50094,50095,50099,N,N,50296,N,62634,N,62633,62631,62630, -62632,N,50295,50297,N,N,50416,N,N,62949,62948,N,N,63226,N,63228,63230,63229, -63227,N,N,50595,50594,N,N,50643,50642,50644,63469,63468,N,63739,63672,63740, -50776,N,50777,63853,N,N,50814,42700,N,52648,N,N,53317,53318,53316,N,N,44275,N, -53319,53320,53321,N,N,54089,54095,N,N,54093,44987,54091,N,54092,54094,N,N,N, -54090,45769,N,55006,45771,55008,45770,55007,N,N,N,N,N,56040,46511,N,56042, -56039,55009,N,46512,N,N,56041,N,N,N,N,N,N,57174,N,47204,57172,47205,57173, -47206,N,N,N,47849,58209,58206,58208,47850,47851,58207,N,N,N,N,N,59103,N,N, -59104,N,48491,59106,59105,N,41569,N,60106,60107,60103,N,60104,49020,49021, -60105,N,49495,N,N,49491,49496,49492,49494,49490,N,49493,N,N,N,N,49843,60879,N, -62126,N,62125,N,62635,50298,50299,63297,62950,N,63296,N,63741,63908,42701,N,N, -43124,N,52649,43720,44278,53324,44276,53322,44281,44277,44282,44280,53323, -44279,44991,44990,54106,44999,54099,54105,44995,54098,54104,54102,44994,44996, -54101,44989,54100,45000,44997,45001,44998,54097,54096,54103,44992,44988,44993, -N,N,N,N,N,55024,55017,N,46517,55016,N,45775,45782,45779,45785,45784,45780,N, -55010,55013,N,55012,45776,55014,55023,45777,55011,55020,55021,45778,55018, -45783,45773,45781,55015,45772,55019,N,N,55022,N,N,N,56059,56050,46514,56057, -56054,56046,56055,46516,56047,N,56043,N,N,47212,56052,N,46513,56058,N,46520, -46522,56045,N,N,46521,56048,46515,56056,56049,56053,N,56051,46518,56044,46523, -45774,46519,46524,N,N,N,N,N,47208,57181,57183,57185,57189,N,57179,57177,47210, -N,57184,57188,57180,57176,N,57175,N,N,N,57186,57178,57182,47211,N,47209,57190, -47207,57187,N,58226,N,N,N,N,N,47854,58218,48504,58228,47857,58232,47863,58213, -N,N,58229,58210,N,58231,58214,N,47870,47867,58230,58224,47853,47861,47860,N, -47859,47865,N,58211,47866,58225,47862,47852,58227,47855,47856,47864,58216, -58215,58212,N,58220,58217,58221,47869,N,58233,47858,58222,58223,N,58219,N,N,N, -47868,N,N,N,N,59111,48496,48505,48501,59108,N,48498,48502,59120,48492,59112,N, -48500,N,N,59115,59110,48499,48503,59109,N,48497,N,59119,48494,59118,59117, -48506,58738,48493,N,59116,59107,N,48507,59114,48495,59113,N,N,N,N,49058,49063, -49022,60120,60111,60123,60115,60121,49064,49057,60108,60114,60124,60117,60122, -60110,N,N,60118,49059,60116,49062,49061,60112,60113,60109,60119,49060,60126, -60125,N,N,N,60890,60886,49503,N,60880,49497,49513,60892,49505,49501,60883, -49508,49511,60894,49500,60885,49509,60896,60893,60881,49504,49498,49512,60888, -49507,60882,49502,60895,49506,49499,60889,49510,60887,N,N,60891,N,N,N,61550, -61556,49849,61559,49844,49845,61551,61558,61553,49850,49847,N,61549,N,49846, -61555,61557,49848,61554,61552,N,N,N,N,62136,50103,50104,50100,N,50101,N,62132, -62130,N,62134,50106,62135,62128,62127,62131,62129,50102,62133,62636,50302, -50301,62637,N,62639,62638,50337,N,N,N,62955,62952,62953,N,62951,62954,50418, -62956,N,50417,N,63298,N,50645,50647,63470,50646,63673,63808,63810,63742,63809, -50796,42702,N,44283,53871,45002,N,N,45786,56060,56061,N,N,N,60127,49514,60897, -N,N,49851,N,62138,62137,50338,62957,N,63299,50680,51785,N,N,43721,43125,N,N, -53325,N,N,54112,54107,54111,54109,45003,54110,54108,N,55025,N,56062,56128, -57193,57194,47214,47215,57192,57195,57191,47213,N,47936,N,47216,58234,N,48508, -59121,48509,N,49065,60130,60128,60129,60900,60899,60898,N,N,N,62139,N,50105, -62140,63300,50681,63674,42703,43723,43722,53327,44284,N,N,53326,54114,N,45004, -55026,54113,N,N,N,45788,55029,55027,55028,45787,N,56130,56131,56129,N,47219, -57197,57196,57198,47218,47217,N,N,59122,59124,N,48510,59123,60131,49066,61561, -N,61560,50107,62141,50109,50108,62640,62958,50419,42704,53328,44285,54117, -45006,54116,54115,N,45005,N,55035,N,55037,55030,55031,45789,55032,45790,55036, -55033,55034,45791,N,46526,46527,N,56132,N,N,N,57199,57200,N,58238,47939,47937, -47938,58235,58236,N,58237,59129,N,59130,48545,59127,59126,59128,59125,49069, -60132,49067,49068,60902,49515,60901,61352,N,61562,61563,49852,N,49853,49516, -62142,62143,62641,50339,42705,N,42706,44286,43724,45007,53329,N,N,N,46528, -42707,44353,53330,53331,44352,44354,42708,N,53332,45009,54118,45011,45008, -45010,N,55105,45792,N,55104,55038,N,57201,N,N,58273,N,48546,N,49070,60134, -60133,N,60903,N,N,N,62959,N,N,42709,52083,52650,44355,53333,N,54120,N,N,N, -45012,54119,45013,N,N,N,55107,N,N,45794,55106,55108,N,45793,N,N,N,N,56134, -56135,56133,46529,N,N,N,47220,N,47221,N,47941,N,58275,58274,47940,N,N,N,N,N, -59131,N,N,59132,N,N,N,N,60135,N,N,49520,49519,49517,49518,49521,N,61564,49855, -49854,62144,62642,N,N,N,50597,50596,42710,N,N,53755,N,47223,46530,47222,47942, -N,42711,51625,42712,42713,N,N,52651,52086,N,52087,43127,N,52084,43126,N,43129, -52085,43131,43130,52088,43128,N,N,N,43729,43727,52653,N,43726,N,N,N,43731, -43733,43730,N,52656,52652,43734,N,43728,43132,N,43732,52655,N,N,52654,N,43725, -N,N,N,N,N,N,N,53339,44359,44360,53341,N,53335,53338,53347,53345,N,44361,53351, -44364,53348,53340,53337,N,N,56137,53346,44356,53349,53334,53343,44358,44363, -53344,44367,44365,N,53336,44362,N,53342,44366,44357,53350,N,N,N,N,N,N,45018,N, -45027,45016,45014,54122,45022,45019,54124,N,N,45021,54123,54121,54126,45026, -45024,56136,54127,54125,45015,N,N,45017,45020,N,45023,N,45025,N,N,N,N,N,N,N,N, -N,N,55118,45796,N,55109,55111,N,55112,N,55120,55116,55114,N,55117,55121,45797, -45801,55110,N,55119,N,45799,N,45798,55115,55113,N,45795,45800,N,N,N,N,N,N,N,N, -46536,56145,N,N,56143,46538,N,N,N,N,56138,57249,N,46537,56142,N,N,56139,46533, -46539,56144,46535,56141,47943,46534,56140,46540,46532,46531,N,N,N,N,N,57207, -57205,N,57211,N,57203,57250,57208,N,57202,47227,47267,57213,N,57206,N,47230,N, -N,47228,57214,47225,47224,57209,47229,46541,N,57212,57204,47226,47265,47266,N, -N,N,N,47948,47944,N,47949,58278,N,N,58277,58279,47946,58276,47947,58282,58281, -58280,N,47945,N,N,N,N,N,59201,N,59204,48552,59203,48551,48547,48548,48549, -59200,59134,48550,N,59202,59133,N,N,60137,60147,49073,49072,N,60141,60143,N, -60138,N,60142,60136,60145,49071,60144,60140,N,60146,N,60139,49524,60904,60910, -49528,49530,49527,49526,N,49525,49523,60905,60908,49522,60909,N,49529,60907,N, -60906,49856,N,49857,61601,61565,61566,N,N,62146,N,62145,50110,62644,50340, -62643,N,62960,63301,50598,63811,63812,50648,42714,N,43735,56146,47950,49531, -60911,42715,N,45029,45028,56147,N,N,N,60148,42716,44368,N,N,56148,56149,56150, -47951,49074,42717,N,43736,53352,45030,54128,45802,N,56151,47268,N,47952,49075, -49532,49858,62645,42718,43737,N,N,45031,55122,46542,N,47953,58283,59205,N,N,N, -N,42719,46543,57251,47954,42720,52657,53353,44369,N,N,54130,N,N,45034,N,45032, -45033,45035,N,N,54129,N,N,55127,55124,55126,45803,45805,45804,55123,45806, -55125,N,56152,56153,N,56154,57254,N,57255,N,57253,57256,N,47269,N,57252,N, -47955,N,N,59210,59206,59209,59211,59208,59207,N,60149,60150,60151,49076,49077, -60913,60912,60914,N,61603,61602,N,62148,N,62149,62147,N,50341,N,62646,62647,N, -63302,63471,63675,42721,43133,N,49533,42722,N,55128,56155,N,50753,51786,N,N,N, -51787,51789,42723,51790,51788,N,N,52130,52131,52091,N,N,N,N,52129,43169,N, -43170,52092,52090,52089,52093,43134,52094,53354,N,N,N,52662,43740,52661,52663, -N,43739,52668,43743,52658,52672,52678,43750,52675,43747,N,52665,52671,52673,N, -52660,43746,43741,52666,43748,43751,43745,N,43738,52670,52664,52677,43753, -43749,43744,52669,45036,52667,43742,43752,N,52659,N,52674,52676,N,N,N,N,N,N,N, -N,N,N,N,N,N,44386,44380,44388,44385,53361,53364,44381,N,53355,N,44374,44384,N, -44387,44389,53410,53367,N,44373,53409,44377,44375,44370,53359,N,53374,53363, -53366,53413,N,44390,53373,44382,53368,53412,53365,53369,53372,N,N,53357,53411, -53371,N,N,53356,53360,44383,44378,44371,44376,44372,44391,53358,54181,44379,N, -N,53370,52801,N,N,N,N,N,N,N,N,54184,45050,N,54134,N,54179,54141,N,54194,N, -54186,N,54142,N,54185,54136,54140,54197,45053,54189,54180,45037,54195,54132,N, -54188,N,45052,45047,54131,45045,45044,45049,54187,45041,45048,53362,56156, -54182,N,N,54138,45051,54139,54177,45054,54133,54191,N,54190,54198,45043,45040, -54196,54192,54183,54178,45046,45042,54135,45038,54193,45039,N,54137,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,55134,55136,55141,55161,45820, -45810,N,55133,45821,45822,55144,55151,55157,N,55138,N,55145,N,N,45888,55159, -55154,45818,45816,55150,55146,55132,45807,55137,55129,N,45815,45817,55142, -55139,45812,55155,45809,55140,55162,55148,N,55147,45808,N,45819,N,45811,55130, -55135,55152,55158,45889,55131,55143,55149,45814,N,N,55160,55153,55156,N,N,N,N, -N,N,N,N,N,N,N,N,45813,N,56172,56160,46551,56189,56231,56234,46549,56168,56227, -56169,56183,46562,56179,46559,N,56180,56157,N,56228,N,N,46568,56225,56181, -56236,56176,57288,N,56239,46566,56174,56186,46569,46548,56178,56237,56171, -56164,56175,N,56163,56161,46544,56229,56170,56232,N,56233,46552,46557,46553, -46561,56190,46554,56182,56166,N,46546,56158,56226,56235,56165,46560,56240, -56177,56173,N,46545,46565,N,56188,46567,N,56184,46556,46550,46558,46547,46564, -56185,56167,56187,56162,56230,N,N,N,N,N,N,N,56238,N,N,N,N,N,N,N,56159,N,N,N,N, -N,57287,N,57309,47189,57292,N,57290,57269,47273,57285,57305,57281,47281,57304, -57279,46563,57295,57280,57302,47280,47272,N,57258,57266,N,57291,57283,57308, -57286,47286,57303,N,47277,N,57289,57297,57270,57296,N,57313,57265,57298,N, -57311,N,57259,46555,N,57273,57272,47279,N,57276,57278,57293,57310,47282,N, -47283,N,57264,47275,57268,57306,47284,N,47276,47278,47285,57312,57299,57294,N, -N,57275,57274,47274,57260,47271,57284,57261,57282,N,N,57271,57307,N,N,N,47270, -N,N,N,57267,N,N,N,N,N,N,57263,57301,57262,47968,58323,N,N,58306,N,N,58284, -58314,47960,58299,58309,47963,58302,47961,58287,58317,58286,58305,N,58285,N,N, -58303,58312,58310,58298,58293,58291,N,58292,58311,58322,58300,47962,N,58295,N, -58315,N,47965,58294,58288,58304,47969,N,N,47957,47966,58296,58290,N,47959, -57300,47958,58307,N,47956,47971,47964,58308,58297,58289,58316,58301,47970, -58320,47967,58319,N,58313,58318,N,N,N,58321,N,N,N,N,N,N,N,N,N,N,N,59251,59252, -59239,59238,59234,48564,N,48556,59254,59253,57257,59231,59235,59229,N,59248, -59233,N,59255,59226,59224,59236,59246,59241,48566,59215,N,59245,N,N,N,48567, -57277,59227,59218,59221,59259,59228,59219,59217,59214,N,48560,59237,48559, -48563,59232,59240,48553,59256,59260,48555,N,59223,59243,59247,59220,59257, -48562,N,48561,59212,48565,59250,59222,59242,59216,59230,59225,48557,48558, -59244,59261,59258,59249,N,N,N,N,N,N,N,N,N,59213,N,48554,60233,N,60224,60227,N, -49083,60229,60153,60225,60231,49080,49084,49078,N,N,60155,60236,N,N,60230,N, -60156,60245,60239,60152,60998,60158,49079,N,60234,N,60244,49087,N,60241,60157, -60228,60232,60226,60246,60243,60240,49081,49082,49086,60154,60247,49085,60237, -N,N,60235,N,N,N,60238,61011,60992,60997,61010,60996,60923,60993,N,49570,N, -60916,61005,61007,60915,49569,61009,61001,49576,61008,60994,49578,60921,60242, -61002,60999,60917,61013,49572,N,N,49573,60919,61000,N,61012,61003,60925,49575, -49571,61004,60926,61014,60920,60995,61006,60922,60924,N,49867,60918,49577, -49860,49534,N,N,N,N,49574,49864,61619,N,61609,61604,61610,61620,61624,61623, -49866,49865,N,N,61611,61625,61614,61606,N,61608,61607,61613,61618,61605,61612, -61617,49863,N,61615,N,49861,61616,49859,49862,62165,61621,N,N,50114,N,62157, -62161,62153,62156,N,62164,50112,62169,62162,N,62154,62170,62163,50115,50116, -62167,N,62155,50111,50113,62150,62158,62152,N,62168,62166,62151,62159,N,N,N, -62654,50117,62160,50343,50345,50342,N,62659,62651,62649,62653,62650,N,N,62655, -62657,50346,50348,N,62656,50349,50347,62658,N,N,N,N,50344,N,N,N,N,N,50420, -62961,62967,50422,62652,62966,N,62973,62964,62971,62970,62648,62965,61622, -62974,62963,62968,N,62972,62962,N,63306,50421,62969,N,N,63476,63307,63305, -63303,63304,63308,N,50649,63474,63472,63477,63475,N,63478,50650,63473,N,N, -63676,N,N,63813,63814,63815,N,N,63943,63933,51791,43754,N,44392,N,54200,54199, -45120,45890,55164,N,N,55163,N,46570,47288,N,47287,47289,N,58324,59262,60248, -60250,60249,N,49579,61015,61626,63909,42724,N,52681,52682,52680,52679,43755,N, -53417,53415,N,N,53414,N,44393,44395,44394,53416,N,N,N,N,N,N,N,N,54212,54209, -54207,N,N,45121,54210,45126,54204,54219,N,54221,54205,N,45123,54222,54217, -54203,54208,54218,54214,54211,N,45128,54220,54206,N,N,54215,54201,45127,45124, -54213,N,54216,54202,45125,45122,N,N,N,N,45900,55205,45899,N,55208,55211,45896, -45894,55166,55209,55207,55204,55212,55213,55215,55216,55165,45893,55202,55201, -55214,45895,55203,45897,45892,55206,45901,N,45898,55210,N,N,N,46577,56255,N, -56244,46574,N,57319,56253,56241,46572,56246,46575,56250,56248,46578,46571,N,N, -56242,56245,46576,N,56243,N,56254,56252,56247,56249,56251,46573,N,N,N,N,N,N,N, -57320,57326,57316,57322,47290,57318,47296,N,N,47295,47294,57325,47297,47298, -57315,57328,47299,47293,47292,57324,47300,57314,57317,57327,57323,N,N,58356, -58345,47291,N,N,N,N,47978,58333,58354,58334,47973,N,58331,N,58340,58332,47975, -58326,58353,47976,58350,58351,58327,47981,58342,N,58336,58343,58330,N,58355, -58347,58341,58325,47977,58348,N,47980,58352,N,58346,47974,58344,N,58338,47972, -58329,58337,58349,58335,N,N,58339,N,N,N,N,N,48577,57321,59314,59323,59313, -59309,59306,48578,59304,47979,59297,48576,59303,48575,59308,59305,59321,59316, -59310,59315,48571,59307,59326,59298,59299,59322,48572,59327,48574,59328,59312, -58328,59318,59311,59320,59317,N,N,N,59302,48569,59325,48570,59300,48573,60260, -59319,59324,N,N,N,N,N,60257,48568,49088,60267,60263,N,60261,60256,60271,N,N,N, -49092,N,60252,60264,60265,60255,60254,60268,N,60258,60253,60259,N,60270,60251, -60269,60266,49090,49089,N,N,49091,60262,61643,N,N,N,N,N,61017,49585,61021, -61018,61025,61031,61020,N,61040,49582,61034,61023,61035,61030,61037,61022, -49587,49586,61024,61038,61016,61036,49580,N,61028,61027,61032,61019,49584,N, -49588,61026,61033,49589,61029,N,N,N,N,49581,49583,61639,61637,N,N,61644,61641, -61645,N,61630,61638,61649,61039,61634,49871,59301,61629,61642,61636,61633, -61628,61627,61648,N,61632,61631,49869,61640,N,49868,N,N,49870,61635,61647,N, -62174,62175,N,50121,62172,50118,62180,N,50122,62182,62171,61646,62184,62173,N, -50119,62179,N,62181,62176,62183,62178,62177,50120,N,N,62661,62662,N,62664, -50350,50351,62665,62663,N,62660,N,63042,63045,63041,N,50426,63043,50425,50424, -50423,63044,63313,63311,N,63310,63040,63312,63046,63309,N,63481,63447,63479, -50651,63480,63482,N,63679,50682,63678,63677,50683,N,50778,63854,63911,63910, -63912,42725,53418,N,54223,54224,N,N,N,56256,N,63047,63680,42726,44396,53419,N, -N,N,55217,45902,N,56258,56257,46579,N,47301,59329,48579,N,48580,N,N,N,49093, -50684,42727,N,N,N,53420,43757,53422,53421,44397,N,54225,N,54232,45129,54230, -54228,N,54235,54226,54227,45130,N,45134,N,N,54236,45133,54234,54231,54229, -45131,45132,54233,N,N,N,N,45904,55218,N,45909,55234,45908,55236,N,N,55224, -45906,55235,N,55219,45907,55231,55227,55229,55223,55230,N,N,45903,55226,N, -55225,55221,N,55232,N,N,55228,55220,N,55222,45905,55233,N,N,N,N,46582,56269,N, -N,N,56265,56267,56262,56261,56259,N,56266,56268,56264,N,56263,46580,46581,N,N, -N,N,N,N,56271,47309,57330,57336,57331,57332,N,57337,N,47311,N,47303,47310, -57329,56260,47306,47304,57335,57334,47305,47307,57333,47302,N,47308,N,N,N,N,N, -58358,47988,N,N,58434,58433,N,58363,47990,58432,58359,58360,47982,47984,N, -58365,58357,47986,47985,58361,58366,58364,47987,58362,56270,47983,N,N,59330, -59337,48582,N,59341,48586,59333,59331,N,59340,N,48581,59339,48583,48584,59332, -48585,59338,59334,59335,59336,47989,N,N,N,60272,60284,N,49098,60279,60281,N, -49096,60273,60277,N,60280,49094,49097,60283,60275,60276,60282,60274,60278, -49095,61042,N,61041,49591,61047,49593,N,N,49590,61043,49594,61044,N,N,61045, -61048,N,49592,N,61654,N,N,61657,N,61651,61653,N,N,61652,61655,61656,61046, -61650,N,N,50125,62188,62191,62193,62186,62187,62190,62192,50126,50124,50123, -62189,62185,62666,50352,N,62667,N,N,63049,50427,63051,50428,63048,63050,50600, -N,63314,50599,63485,63484,N,63483,N,N,63816,63817,63819,63818,N,51792,42728,N, -44398,55237,46583,N,57338,49872,N,62194,N,N,43171,N,N,N,45911,N,N,N,45910,N, -56272,46584,56274,56273,N,N,57339,47312,58435,58438,58437,N,58436,59342,59344, -59343,N,49100,N,N,N,49099,N,49595,61049,61051,61050,N,N,49873,N,N,N,62196, -62195,N,62668,50353,N,N,50429,63316,63315,50779,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,43172,53423,44399,55240,55238,N,N,55239,56276,56277,57411,56275,N,57340, -57409,57408,57410,47313,57342,57341,57412,N,58441,58439,N,58440,59347,59345,N, -N,59346,60285,61052,61053,49874,N,62197,62669,50354,N,63052,63317,50601,N, -63486,63820,43173,N,44401,44402,53424,N,N,53425,44400,N,45140,N,45138,N,45137, -45144,45136,45145,54237,45142,N,45139,45143,45141,45135,N,N,45919,N,45913, -55244,45918,N,N,45920,45914,N,45915,N,55242,N,N,45912,N,55243,45917,N,N,55241, -45916,N,N,46660,N,46662,N,N,56280,46661,46585,46589,N,47332,57417,56282,46590, -N,N,56285,56286,46659,N,56288,N,56290,N,56291,56279,56278,56292,46658,56289, -56287,N,46656,46587,46663,56283,56284,56281,N,46657,N,N,46588,N,46586,57416, -47327,47322,N,N,47317,N,47333,47318,N,47314,47329,47326,47328,N,47319,47324, -47315,47316,57424,57421,57413,57418,N,47330,57425,47331,47321,N,N,57415,N, -57423,57419,57422,57420,47325,57414,47320,N,N,N,58444,47992,47995,N,58446,N, -48037,58445,47997,N,48591,58447,N,48036,58443,48038,N,N,N,47993,N,47323,47996, -N,47994,47998,48034,47991,48039,48035,N,48033,58442,N,N,N,N,48598,N,48594,N,N, -N,48601,N,59350,48602,59362,59355,48587,59363,59357,48597,59358,N,48596,59361, -48590,59359,59349,48589,60330,48595,N,48592,N,48600,N,59348,N,59352,48588, -59351,59353,59354,48599,59356,59360,59364,N,48603,49106,60325,60331,60328, -60286,60332,60321,N,60327,N,49101,49107,60333,N,N,49103,N,49113,49108,60335, -60329,49104,60322,49114,60323,60324,49115,49112,48593,N,49102,60336,49116,N, -49109,60334,49105,49110,49111,N,49603,61092,61101,61098,61100,N,49600,61093,N, -61099,49596,61095,49604,61091,61096,61103,60326,61097,61090,49597,61089,49598, -61104,49599,61102,49602,61054,N,49601,N,61094,61660,61674,61669,61671,61659, -49875,N,61658,49878,49877,N,61673,61665,61662,61668,N,61661,N,61663,61672, -61670,N,49876,61677,61675,61666,61676,61667,N,62201,50127,62273,N,N,63055, -50134,61664,62199,50130,62200,62205,N,N,50132,50133,62198,62272,62274,62202, -62204,62206,62203,62275,50129,50135,50131,N,50128,62672,N,50359,62670,N,N, -62674,N,62675,50357,62676,62673,N,62671,50360,50356,62677,N,50358,50355,N,N,N, -50430,N,N,50496,63054,63053,63056,63057,N,50497,63318,63323,50602,N,63320,N, -63319,63322,63321,N,63555,N,50652,63554,63552,N,63553,N,N,N,50686,50685,63681, -63682,50752,N,63821,63822,50791,N,50797,N,63913,63944,43174,N,55245,N,55246, -57426,58448,59365,49606,N,49605,61678,62276,N,63556,43175,54238,45146,45921, -57428,57427,48604,59366,48605,61105,49879,N,N,N,50806,43176,52683,54239,N,N, -45922,N,55247,55248,N,56293,N,46664,47334,N,57430,57429,57431,N,58449,58450, -48040,49117,48606,49118,N,61109,61106,61108,61107,49607,N,61679,62278,62277, -52132,45148,45147,54240,N,55249,N,N,56295,56294,46665,N,57433,57434,57432,N,N, -47336,47335,N,48042,48041,N,59367,60339,60337,60338,49119,61111,61110,N,61682, -61681,61680,62279,N,63914,43177,44403,N,44404,45149,45150,54242,54241,55250,N, -45928,45926,45923,45927,45925,45924,N,N,46666,56298,N,47341,46668,46673,56300, -46675,46674,46677,56299,56296,46671,46667,46669,56297,46676,46672,46670,47343, -47342,47340,47344,N,47338,47339,N,47337,N,57435,N,N,58452,N,48044,48045,48043, -N,58451,N,58453,N,59370,59372,N,48615,59373,48608,59369,48607,48617,48613, -48614,48610,59368,48609,59374,59371,N,48616,N,48611,48612,60341,N,60343,60342, -N,60344,49120,60340,N,N,49611,61112,49608,49612,49610,49609,61683,61686,N, -61685,N,61684,49880,62280,62281,50136,62282,50137,N,N,50362,N,50361,63058,N,N, -50498,63059,63324,50603,50604,N,63557,N,50754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43178,N,45930,45929,57436,57437,N,48046, -60345,48618,60346,61113,43179,N,53426,44406,44405,N,54243,45151,54244,55253,N, -55252,N,55251,N,N,56302,46680,N,N,56301,46679,N,N,N,56303,46678,N,57439,57442, -57440,57441,57445,57438,57446,57443,57444,48048,58454,N,N,48047,N,59378,59376, -N,N,48619,59375,59377,N,48620,N,60347,N,60348,49613,N,62284,62286,62283,62285, -62678,63060,N,N,63855,43180,44407,54245,54247,54246,N,55256,45932,N,55254,N, -45931,55257,N,55258,55255,N,N,56315,46688,56307,56313,N,N,46683,46686,56306, -46681,56310,57452,46685,N,56305,N,56311,56308,56314,56304,56312,46684,46687, -56309,46682,N,47346,57448,47345,57455,57454,47352,N,47353,57456,47347,57453, -47351,57458,57449,N,57451,47348,57447,57450,57457,47349,57459,N,N,N,N,N,47350, -N,48049,58459,58465,58457,58466,N,58456,58461,58467,58464,58463,58462,N,58455, -58460,N,N,58458,N,48625,48622,59387,59457,59459,59456,59384,59386,59461,59458, -59388,59462,59385,59460,48623,48629,48627,59379,48628,48624,59380,59382,59381, -59389,59390,N,48626,N,48621,N,N,59383,N,60358,49122,N,60349,49123,49126,60354, -N,60351,49125,N,N,60355,60356,60350,60359,60352,60357,49124,N,49121,60353,N, -61119,49616,49614,49617,49615,61118,61115,61114,N,61117,N,N,61116,61765,49886, -61691,61690,N,49881,61761,61760,61687,61763,61692,49885,61689,61762,61688, -49882,49884,61693,49883,61694,N,61764,62290,N,50142,62287,N,62291,N,N,50139, -62289,50144,N,50141,N,62288,N,50143,62292,50138,N,N,N,N,50364,50366,N,62681, -50365,62679,50140,62680,50363,50499,50501,63062,50500,63061,N,63329,50605, -63328,50606,63326,63325,63330,63331,63558,N,63327,N,N,63686,63683,63684,63685, -50780,N,63825,63824,63823,63856,N,63934,63915,50798,43181,45152,N,N,N,N,N, -47354,N,N,N,N,N,N,N,48630,N,N,60360,N,N,49887,N,62293,N,N,N,N,N,N,63916,43182, -43758,44409,44408,N,45155,N,54248,45153,54249,45154,N,N,55263,55259,N,N,45933, -55262,55261,55260,45934,55264,55265,N,N,N,56387,56385,56389,56390,56396,N, -56392,56394,N,56386,56316,N,56393,N,N,56395,56388,56391,56317,46690,56384, -56318,46689,46691,N,47357,57461,57463,57462,57467,47355,N,57464,57460,57465, -57466,47356,47358,57468,N,58471,58470,N,58468,58469,48051,48053,48050,48052, -59469,59470,59465,N,59466,48632,48637,48631,48638,48633,59467,N,N,59468,59464, -48704,48635,N,N,48634,48636,N,59463,N,60362,49128,N,N,60364,49130,60367,60363, -60361,60366,49129,60365,N,49127,N,N,49619,49622,61121,N,49620,61120,49618, -49621,61766,61767,61768,49888,N,61769,N,49889,50146,62296,62297,62295,62294, -62298,50145,62685,62683,62684,62686,62682,62687,63064,N,63065,63063,50502, -63332,50607,63333,63560,63559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43183,46692,N,N, -47424,N,N,N,48054,N,N,49132,N,49131,N,N,N,N,50147,50300,50503,43184,45156, -47425,N,62299,N,N,N,N,N,N,N,N,N,N,52134,N,N,43185,N,43188,43187,43186,N,N, -52133,N,52685,N,52687,43759,N,N,43761,52684,52686,43760,52689,52688,52690,N,N, -N,N,N,N,N,N,53430,53428,44412,53427,44451,44414,44411,N,44452,N,44413,44450,N, -44449,53429,N,44410,N,N,N,45162,54251,54257,45159,45166,N,45161,54254,54256, -45164,54250,54253,45160,45157,54252,45163,54255,45165,45158,N,N,N,N,55267, -55270,45936,N,45946,45942,55268,N,N,45950,45943,45948,45938,N,45935,45937, -45949,55269,45941,45944,45940,45945,55271,45947,45939,55266,N,N,N,N,N,N,N,N, -56397,46693,56399,N,46695,46697,N,56398,46694,46698,N,46696,N,N,N,47431,57507, -47439,57470,N,47440,47429,N,57505,N,N,47434,N,57506,47427,47426,N,47437,47436, -47435,47433,47438,57469,47428,47430,47432,N,N,48056,48059,N,48063,48057,48062, -48060,N,48055,N,48061,48058,N,N,N,59474,48707,48705,N,59475,N,48708,48706, -59473,59472,N,49136,59471,49134,49133,60368,48709,49135,60369,49138,60370, -49137,49624,61123,49623,49628,49626,49627,49891,49625,61122,60371,49890,49892, -N,50148,50149,N,62688,N,50654,50653,43190,N,N,51797,45167,N,51794,51795,51793, -N,51796,N,N,52138,52135,52140,52136,43191,43194,N,52137,43193,52139,N,N,43192, -N,N,N,N,52693,52695,43764,52691,52694,52692,43762,43765,N,43763,N,N,N,N,53432, -53436,53433,N,44455,N,44456,N,53435,N,53437,53439,N,44453,53438,N,N,44454,N,N, -N,N,N,55278,53434,54258,54267,54265,54260,54261,54266,54268,45169,N,54263, -54259,45168,45170,54262,54269,54264,N,N,45985,55281,55273,55279,55280,45986,N, -55272,55274,53431,55276,55277,55275,46700,N,N,N,56406,60372,56407,56404,45987, -46702,56403,56409,56408,46699,56412,56402,56411,56400,56410,56405,46701,N, -57514,N,57509,57515,57510,57508,57511,47441,N,57513,N,57512,47442,48065,48064, -58478,58481,58473,58477,48066,58476,58474,58480,58475,58472,58479,N,59481, -48712,61770,59478,59479,59477,56401,48711,59482,59476,48710,48713,59480,60373, -49139,60374,60375,N,61124,49629,61771,61772,N,N,61773,62301,62300,62690,N, -62689,63067,63068,63066,63334,50608,43195,44458,44457,45173,45172,54336,54337, -54270,N,45171,55285,N,55286,55282,45988,55283,N,55284,N,N,N,N,56415,56417, -56413,56416,46703,56414,46704,N,N,56691,47445,47444,N,47443,N,57516,57517,N,N, -58483,58485,48070,48067,N,48069,48068,58484,58482,N,N,N,N,N,59489,59486,59487, -48717,59488,59483,59484,48714,N,48715,59485,48716,N,60379,N,60380,60377,60378, -49140,60376,N,N,N,N,N,61128,61125,61127,49632,61131,49631,61129,61132,61130, -61126,49630,N,61775,N,61776,61774,N,61778,49893,49894,62303,50151,61777,62302, -50150,62693,62694,50367,62692,N,62691,N,63069,50504,N,63561,63688,63687,N, -50755,50781,63689,63857,N,50799,43196,43766,N,47446,N,50368,43197,44459,45989, -46705,49895,43767,N,53441,53440,54338,N,45176,45174,45178,54340,N,45177,45175, -N,N,N,N,54339,45992,55292,N,45991,45993,55362,45995,55294,55360,55287,45994, -55363,N,N,55289,N,55290,55288,45990,N,55361,55291,55293,N,N,N,56429,N,56428, -56426,56418,56433,56421,56431,56438,56430,46713,N,46709,56419,N,56425,46711,N, -56424,46712,46714,56427,N,46706,46707,56439,56437,N,56436,56422,N,56434,N, -46710,N,N,N,N,46708,56435,56420,56423,56432,N,N,N,N,N,58554,57527,N,57520, -57539,57548,57523,47457,N,57536,47447,47449,47461,57521,N,N,47450,47452,47462, -47451,N,N,N,N,47460,57529,N,57518,47458,57528,47454,57546,47459,57544,57532, -57542,47456,57519,57545,57540,N,57547,47448,N,N,47463,47453,N,N,57525,N,57533, -57537,N,57541,47455,57524,57522,57534,N,N,N,N,57531,57530,N,57535,57538,N, -57543,N,N,N,58488,N,48071,58532,58490,48076,48080,58541,58549,58534,48072,N, -58538,57526,N,48073,58545,58550,58542,N,58544,58553,58546,58494,58537,N,N, -48081,N,48077,58492,58539,48075,58533,48074,58547,58530,58489,48078,58552,N,N, -58491,58543,58540,58535,58487,58486,58529,58548,48079,58551,58493,58531,48722, -N,N,N,N,N,48730,48725,59556,59553,59495,48720,N,N,N,48719,48726,N,N,N,59493, -48724,59505,59491,59492,48718,59555,48728,59508,59513,59507,60398,59503,59511, -59509,59496,59490,59517,48727,59518,N,59512,N,59501,59499,59494,N,N,N,59502, -59515,59498,59514,59554,N,N,48723,N,59510,59516,59506,59500,48721,N,N,N,58536, -59504,48729,59497,N,N,N,N,N,60404,49143,60403,60400,60484,49147,N,60481,60408, -60483,60393,60406,N,49149,N,60385,N,60383,60482,N,60480,60414,60397,60396, -60386,49216,N,60392,60402,60413,49219,60485,N,49640,49221,49150,60390,N,60399, -60382,60384,49141,49218,49146,60391,60407,60401,49217,60381,49635,60409,60412, -49148,N,60395,49220,49145,N,N,N,49144,60405,60411,49142,N,60388,60410,N,N, -60389,N,N,N,N,N,N,N,N,N,60394,61138,N,61143,49637,49639,61149,49633,61164, -61155,61144,61145,61154,N,49646,61153,61137,61152,61140,61165,49645,49643, -61141,N,61160,N,61146,61159,N,61161,61136,49638,N,61162,N,N,61150,N,49642, -61147,N,N,49644,61156,N,N,N,49636,61142,61157,N,61151,60387,61158,61139,N, -49641,N,61163,N,49634,61134,N,N,N,N,61792,61785,49897,N,61780,61795,61787, -61148,N,61797,61781,N,49896,61791,49898,49906,49904,61793,49905,61783,N,61784, -61789,61794,N,61133,49899,61802,61799,61803,61790,61786,61800,62314,61788,N, -49902,N,49901,61135,49903,61796,61798,49900,61801,61779,N,61782,N,N,N,N,N,N,N, -N,62323,N,62307,50155,62321,N,N,62305,50156,N,62316,N,62312,50161,62322,62306, -62309,50153,62324,N,62317,62320,50159,50164,50162,62313,62308,N,50157,50158, -62304,50154,N,50152,50160,62319,50163,N,62315,62325,50165,N,N,N,62311,N,62318, -N,N,N,N,N,N,62707,62786,62709,62716,62310,62714,62697,62784,50371,62701,62718, -62708,N,N,50370,N,N,62788,62710,N,62715,62717,62695,62785,62706,62711,62699, -62703,62787,62713,62696,62700,62702,62712,N,50369,62705,N,N,N,N,N,N,62698,N,N, -N,N,N,N,N,62704,63073,63078,50511,63080,N,50505,N,63076,63082,50510,50506,N, -50507,63072,63079,50509,63077,50508,63071,63075,63074,N,63070,63081,N,N,N, -50609,63341,63344,63340,63342,63343,63337,63338,63335,N,N,63339,63336,50610, -50611,N,N,63563,N,63565,N,N,N,N,N,63564,63566,N,50656,N,63562,50655,50657,N,N, -N,63691,63692,50756,63690,N,63827,63826,63828,50783,63829,50782,63830,63858, -63861,63860,50792,63859,N,N,N,50802,50800,50801,50807,63936,63937,63935,63945, -43768,N,N,55364,56440,59557,62326,N,N,43769,N,44460,45179,N,N,55365,N,55366, -45996,N,46717,56442,56441,46755,46716,56443,46718,46754,46753,46715,N,N,N, -47464,N,N,57552,57550,N,57551,57549,N,48082,N,48085,48087,48086,N,N,48083, -48084,N,59559,59558,48731,59560,N,59561,48732,N,N,N,60493,60491,61171,N,60489, -60490,49222,60486,60494,60488,60492,61167,N,N,61169,N,61170,49651,61166,49650, -61168,49647,49648,49649,60487,N,N,49909,61806,61804,61805,49907,49910,49908,N, -N,N,62327,62328,50166,N,62789,62791,62790,50372,50512,63085,63084,63083,43770, -N,51626,N,51800,42729,51798,51801,51799,N,N,N,52142,N,43201,N,43202,52144, -43199,52143,52141,43200,43198,N,N,N,N,N,N,52696,52699,43773,52698,52697,N, -43772,43771,N,43840,52700,43774,N,N,N,N,N,53446,44462,44463,44464,53447,53443, -44461,53444,N,53445,53442,N,N,N,45220,N,N,45217,54341,45218,45221,54342,N, -45182,45180,45181,45219,N,N,N,N,N,45997,55369,46005,55368,N,55371,46001,55370, -46763,45999,46002,45998,46003,46004,46000,N,N,N,55367,46759,56445,N,56483,N,N, -56482,46764,46760,46761,56444,56446,56481,46756,46758,N,46762,46757,N,N,57555, -57553,57554,47466,47467,N,57556,47465,48088,N,48090,48089,N,58555,N,N,58556, -59563,N,59562,N,N,49223,49224,60495,49225,N,61174,N,61172,N,61173,49652,N, -61807,50167,N,N,N,49653,43841,N,45222,54343,N,N,55372,46006,46765,56484,56486, -46767,46766,46768,46769,56485,47470,47471,47469,48091,47468,57557,N,N,N,48092, -59564,60496,49226,49654,61808,61812,49913,61809,49914,49912,61813,49915,61811, -N,62329,49911,50168,N,63693,N,N,43842,46008,46007,N,N,N,N,46770,56488,56487, -46771,N,N,57561,47475,47472,57560,47474,57558,47473,N,57559,N,58557,48093,N, -59567,N,48733,59565,48734,48735,59566,48736,N,60497,N,49230,49227,49232,60499, -49228,60498,49231,N,N,49229,N,61177,61179,N,N,49655,61178,49656,61176,61175,N, -61815,61814,49916,61816,62334,50170,62333,62330,50169,62331,62332,N,62792, -62793,50373,N,50515,N,N,63086,N,N,50513,50514,63087,N,N,50612,50613,63345,N,N, -50757,63695,50759,N,63694,63696,50758,63831,N,63917,N,N,N,N,N,N,43843,N,N,N, -47476,N,58558,N,59568,49233,49234,N,43844,N,48737,50171,44465,N,N,N,49235,N, -50658,44466,55373,N,56489,N,56491,N,56490,N,57565,57562,47477,N,47478,57563, -57564,N,58560,58565,48094,58559,58561,58568,58563,58567,58564,58562,58566, -48095,N,N,59571,N,59569,48739,N,48738,59570,48740,N,N,N,N,60502,N,N,60501, -49236,60500,61180,N,61182,61249,61248,N,49657,61181,61857,49917,61821,61858, -49918,N,61819,N,61822,61820,61817,49984,61818,N,N,N,N,62369,N,N,62371,62370,N, -62794,N,62795,N,N,N,63088,N,50615,N,50614,63567,63568,50760,63697,N,50793,N, -44467,46772,58570,58569,59573,59572,N,N,49658,61251,61250,61861,61859,61862, -61860,N,N,50172,62372,62373,62374,N,63089,N,63346,N,63698,N,N,N,N,N,N,N,44468, -N,N,60503,61252,N,44469,N,N,48096,N,60504,49985,61863,50173,N,62796,62797, -50516,63569,44470,46011,46012,55374,46773,46774,56492,46775,N,47482,N,47484, -57567,57568,57566,47479,47480,47483,47481,N,N,58571,48097,48098,N,N,59580, -48743,59575,59574,N,59579,48741,N,N,49243,N,59576,59581,59578,59577,N,48742,N, -49241,N,60506,49237,N,60507,N,N,60505,N,49240,49238,49242,N,49239,N,N,N,N,N, -61253,N,61258,61254,61257,49659,N,60884,61256,61255,N,49988,49986,49989,49987, -61864,61865,61866,49990,N,N,N,62378,50240,62376,N,50241,62375,62377,50174, -62801,62798,N,62799,62800,63090,50518,N,50517,N,63348,63347,50616,N,N,N,50659, -50761,50784,63832,63918,63919,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44471,56493,N,N,57569, -58572,58573,48099,N,48100,59582,48744,N,N,49660,N,61867,N,49991,62381,50242, -62380,62382,62379,63093,62802,62803,N,50374,N,63092,N,N,63091,N,63349,63920,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,44472,N,N,N,44473,N,N,45223,54344,N,55375,N,46776,N, -46779,46777,56494,N,46781,N,46778,N,N,46780,N,47486,N,57570,N,N,57571,59584,N, -47485,47521,47522,58575,N,58574,48101,N,48102,N,58576,59583,48104,48745,N, -48103,N,N,N,49244,59585,48747,48746,59586,59589,59587,59588,48748,N,49249, -49247,N,N,49246,60509,N,49248,N,N,60508,61259,N,60510,49245,60511,61262,61260, -61261,61266,49995,61265,61268,61267,61264,61263,N,49661,N,N,N,N,61870,N,61869, -49994,49992,49993,N,61868,N,62385,N,50243,N,62384,62383,50244,N,62808,62807,N, -62805,N,62804,50376,50375,62809,63350,50617,63095,50519,63094,62806,N,63351, -50660,N,50785,63833,N,63921,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44474,55376,61269,44475, -N,N,58578,58577,60512,N,N,61271,N,61270,N,49996,62386,62387,50377,N,N,63922, -45224,46783,46782,57572,57574,47524,57573,47523,47525,57575,N,N,N,58580,58582, -58581,N,58584,N,N,N,48105,58583,58579,N,N,N,58585,N,59596,N,59599,59601,59591, -59595,59592,48750,48753,48755,59593,59594,48754,59597,59600,59598,48756,N, -48752,59590,48749,N,48751,N,N,49251,60518,60516,60515,N,60521,N,60520,60519,N, -60514,49250,60513,N,60517,49252,N,N,61274,N,61278,61275,61277,61276,61273, -61279,61282,61280,61281,49728,49662,61272,61283,61875,61878,61880,61879,N, -61873,61877,61872,N,61874,49997,61871,N,61876,N,N,62400,62389,50245,N,N,50246, -62388,62393,62399,62391,62398,N,62395,N,62394,62397,62392,62390,N,62396,N, -62816,62814,50378,62813,62819,62817,N,50379,62812,62810,N,62811,50381,62815, -50380,62818,63096,63102,N,N,63097,50523,63137,50522,63101,63100,50521,63099, -50520,63098,N,63357,63393,63358,N,63355,50619,63352,63356,63395,N,63394,63353, -63354,50618,63570,50663,N,63571,50661,50662,N,N,63699,50762,63862,N,50794,N, -63923,50795,63924,63925,63939,63938,50810,63949,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,45225,N,N,57577,N,57576,N,48106,48107,58586,N,59602,60524,N,N, -48757,49253,60522,N,60525,49254,N,61284,60523,61881,49998,62401,N,N,N,62822, -62820,N,N,62821,N,N,63138,N,50524,63396,50666,50620,50664,50665,63700,50786,N, -45226,N,N,N,61882,N,N,54345,N,47526,N,58587,N,N,48108,58588,N,N,N,59604,59603, -49256,48758,48759,N,59607,59606,59605,N,N,60526,60529,N,60528,60527,49255, -61288,61286,61285,61287,N,49999,61884,61885,50000,N,61883,N,62403,62402,62405, -50247,62404,N,62823,62825,62824,N,N,63139,63142,63140,63141,63397,50621,N,N,N, -63572,63573,63574,N,50763,50787,63926,45227,N,48760,49257,61886,N,63398,N,N, -63940,54346,N,50811,45228,60530,N,61887,N,62406,N,N,63143,63399,45229,N,58589, -58590,N,48109,48110,59609,48762,48761,59608,N,61289,N,61888,61890,61889,50003, -50002,50001,N,50526,63144,N,50525,63401,63400,N,50764,63701,46013,57578,N,N,N, -58593,58591,58592,N,N,59618,N,59613,59610,59617,N,N,N,59619,N,N,48764,59616, -59612,N,N,59611,59615,59614,48763,N,N,60541,60536,60534,60577,60535,N,60531,N, -60537,N,N,60532,61298,60533,60578,N,N,N,N,N,N,N,60540,49258,60539,60538,N, -60542,N,N,N,N,61290,61293,N,N,61292,N,61300,61295,61299,N,61297,61296,61294,N, -61291,N,49731,49730,N,49732,49729,61301,N,N,N,N,N,61896,61899,N,61897,61901,N, -N,N,61902,N,61894,50008,61895,N,61893,61900,N,61892,61891,50007,50005,50004,N, -N,N,N,N,N,N,N,61898,62415,62421,50250,62416,N,62419,62423,50251,62418,N,62410, -N,62409,62422,62413,N,62411,62420,62412,50249,50248,N,62407,62408,62417,N,N,N, -62414,N,N,N,N,N,N,62828,62831,N,N,N,N,50006,62829,62835,62833,62827,62838,N, -62826,N,50383,62834,N,N,N,62830,50382,62837,N,N,62836,N,N,N,N,63147,63146,N,N, -N,63153,N,63149,63152,50528,N,N,63150,63151,N,63145,63148,50527,N,N,N,50623, -63412,63407,63411,N,63414,63410,N,63406,N,50625,63409,63413,50624,63404,62832, -63408,N,N,63405,N,63402,N,63403,50622,63578,63580,63583,63579,63584,N,63577,N, -63575,N,50667,63581,50669,50668,63576,63582,N,N,N,N,63706,50765,63707,N,63705, -63702,N,N,63704,63703,63834,N,N,N,N,63836,63835,N,N,63865,N,63864,63863,63866, -N,50803,50804,63946,63950,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,46014,56495,57581,N,47527,57579,N,N,57580,N,N,N,58594,58595,48113,48111, -58596,48112,59624,N,59627,59621,59628,59620,59622,N,59623,59626,N,N,48801, -59631,59630,48765,59625,59629,48766,N,N,N,N,N,N,60588,N,49263,N,60583,49259,N, -60580,60586,60589,N,49264,N,60585,60582,60590,60581,N,60587,49260,N,60579, -49261,N,49262,60584,N,N,N,61353,61306,61307,61310,61308,N,61302,N,N,61305, -61349,61309,N,N,49733,N,61351,61348,49734,61350,61303,61346,61347,N,61345,N,N, -N,N,61906,61908,61911,N,N,61905,N,50009,61913,61904,61914,N,61910,61912,61916, -61909,61917,61907,61903,50010,N,61915,50011,50253,N,N,N,N,N,61304,62449,62440, -50255,62436,50256,N,N,62445,62439,62429,50254,62442,62437,62438,N,62424,62431, -62446,N,62443,N,62435,N,62447,62430,62425,62444,N,62427,62441,62432,62448, -62428,50252,62426,62433,62434,N,N,N,62845,N,62843,N,62882,N,62894,62885,62844, -62840,62887,62846,62883,62842,62890,62839,62881,62886,62888,62891,62841,N, -62895,62896,62889,62893,62884,N,63169,63172,N,50529,N,63171,63176,63174,50530, -63165,63155,63154,50532,63167,63168,63164,63156,N,63161,62892,N,63157,50531, -63163,N,63162,N,63158,63170,N,63159,63419,63173,63175,63166,63160,63420,63422, -63416,50626,N,63429,63427,50627,63426,63425,63418,63415,63421,63430,63417, -63423,N,63593,63598,63588,63591,50670,63595,N,63602,63424,N,63589,63599,63603, -63594,63587,63597,N,63596,63601,63600,63428,63592,63586,63590,50766,50767, -63585,N,63718,63709,63717,63714,63715,63708,63711,63719,63713,63712,63710,N, -63716,N,63837,N,63838,N,63840,63839,63842,63841,63868,63867,63927,N,63928,N, -63941,50808,50812,N,63951,50813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,46015,N,N,N,50384,63177,N, -50768,50769,N,46016,57582,N,47528,59632,N,N,60592,60593,60591,61355,61354, -49735,61919,61356,61918,N,N,62451,50257,50259,62450,N,N,50258,N,62897,62899, -62898,63178,50533,N,50671,63720,63843,N,N,63954,46017,N,58597,N,48802,N,N,N, -60595,60594,N,61357,N,N,N,50260,50385,63431,63947,N,N,N,46018,48114,N,48803,N, -62452,N,63604,46784,N,N,N,N,61358,N,N,N,50788,46785,48804,49736,63605,46786,N, -59633,49266,60596,60597,N,49265,N,61359,49740,49738,49739,49737,61920,50012,N, -N,N,62901,62900,62903,62902,50386,N,N,63179,N,63181,63180,50534,63432,N,63606, -63607,50672,63844,63869,50805,N,56496,60598,61360,62453,57583,N,61361,61922, -61921,N,N,N,N,63608,50770,N,63845,63870,N,N,N,47529,59634,59635,N,60599,47530, -N,50013,61923,N,63183,50535,63184,63182,63609,N,63721,N,47531,N,61364,61363, -61362,61924,N,N,61928,61927,61926,61925,50014,62454,62905,50387,62904,63185, -63435,63434,50628,63433,63612,63611,63610,N,N,48115,N,60600,49741,N,62455, -62456,63436,63613,N,N,63722,63846,63929,63956,48116,49742,61929,62457,63186, -63614,N,N,48806,N,61365,61930,62458,62459,62460,62910,N,62906,50536,62909, -62908,50388,62907,50390,N,50389,63188,63187,50537,50538,N,N,50630,63437,50629, -N,63651,63652,63650,63649,50772,N,63723,63724,63725,50771,63847,63850,63849, -63848,N,N,63955,N,N,N,N,N,N,N,N,N,N,N,N,N,N,49267,N,N,50021,62911,63189,N, -50631,63438,N,N,63957,N,N,N,49268,N,N,N,61366,N,63439,N,63905,51530,56828, -41290,41303,N,41305,41307,41311,41312,41315,41316,41319,41320,41323,41324, -41327,41328,41331,41332,41335,41336,41339,41340,N,N,N,N,41414,41415,41418, -41419,41416,41417,41308,41293,N,41295,N,41297,41298,41299,41300,N,41341,41342, -41377,41378,41379,41380,41420,41421,41422,41438,41439,41440,41441,41442,N,N, -41548,41549,41550,41289,N,41389,41539,41544,41390,N,41309,41310,41391,41423, -41281,41424,41284,41537,41647,41648,41649,41650,41651,41652,41653,41654,41655, -41656,41287,41286,41429,41431,41430,41288,41545,41679,41680,41681,41682,41683, -41684,41685,41686,41687,41688,41689,41690,41691,41692,41693,41694,41695,41696, -41697,41698,41699,41700,41701,41702,41703,41704,N,41538,N,N,41412,N,41705, -41706,41707,41708,41709,41710,41711,41712,41713,41714,41715,41716,41717,41718, -41719,41720,41721,41722,41723,41724,41725,41726,41792,41793,41794,41795,41313, -41301,41314,N,N,N,N,N,N,41294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41411, -}; - -static const struct unim_index big5_encmap[256] = { -{__big5_encmap+0,162,247},{0,0,0},{__big5_encmap+86,199,217},{__big5_encmap+ -105,145,201},{__big5_encmap+162,1,81},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{__big5_encmap+243,19,62},{__big5_encmap+287,3,153},{ -__big5_encmap+438,26,191},{0,0,0},{__big5_encmap+604,96,125},{__big5_encmap+ -634,0,229},{__big5_encmap+864,5,66},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+926,0,254},{__big5_encmap+1181, -5,41},{__big5_encmap+1218,163,163},{__big5_encmap+1219,142,213},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+1291,0,255},{ -__big5_encmap+1547,0,254},{__big5_encmap+1802,0,255},{__big5_encmap+2058,0,253 -},{__big5_encmap+2312,0,255},{__big5_encmap+2568,5,252},{__big5_encmap+2816,1, -255},{__big5_encmap+3071,1,255},{__big5_encmap+3326,0,255},{__big5_encmap+3582 -,1,253},{__big5_encmap+3835,0,255},{__big5_encmap+4091,3,255},{__big5_encmap+ -4344,0,255},{__big5_encmap+4600,1,250},{__big5_encmap+4850,1,255},{ -__big5_encmap+5105,0,255},{__big5_encmap+5361,2,255},{__big5_encmap+5615,1,255 -},{__big5_encmap+5870,0,255},{__big5_encmap+6126,0,255},{__big5_encmap+6382,0, -255},{__big5_encmap+6638,0,249},{__big5_encmap+6888,6,255},{__big5_encmap+7138 -,0,253},{__big5_encmap+7392,0,255},{__big5_encmap+7648,0,255},{__big5_encmap+ -7904,18,253},{__big5_encmap+8140,4,255},{__big5_encmap+8392,0,252},{ -__big5_encmap+8645,0,255},{__big5_encmap+8901,0,249},{__big5_encmap+9151,0,253 -},{__big5_encmap+9405,0,255},{__big5_encmap+9661,0,255},{__big5_encmap+9917,0, -255},{__big5_encmap+10173,0,255},{__big5_encmap+10429,1,255},{__big5_encmap+ -10684,0,255},{__big5_encmap+10940,0,255},{__big5_encmap+11196,0,255},{ -__big5_encmap+11452,0,254},{__big5_encmap+11707,1,253},{__big5_encmap+11960,2, -255},{__big5_encmap+12214,1,251},{__big5_encmap+12465,0,255},{__big5_encmap+ -12721,0,255},{__big5_encmap+12977,0,254},{__big5_encmap+13232,0,251},{ -__big5_encmap+13484,3,156},{__big5_encmap+13638,54,255},{__big5_encmap+13840, -0,254},{__big5_encmap+14095,0,255},{__big5_encmap+14351,0,254},{__big5_encmap+ -14606,0,255},{__big5_encmap+14862,1,255},{__big5_encmap+15117,0,255},{ -__big5_encmap+15373,0,254},{__big5_encmap+15628,0,255},{__big5_encmap+15884,0, -254},{__big5_encmap+16139,1,255},{__big5_encmap+16394,0,255},{__big5_encmap+ -16650,0,159},{__big5_encmap+16810,55,254},{__big5_encmap+17010,0,255},{ -__big5_encmap+17266,0,255},{__big5_encmap+17522,0,255},{__big5_encmap+17778,0, -255},{__big5_encmap+18034,0,255},{__big5_encmap+18290,0,255},{__big5_encmap+ -18546,0,255},{__big5_encmap+18802,0,131},{__big5_encmap+18934,119,229},{ -__big5_encmap+19045,28,255},{__big5_encmap+19273,0,255},{__big5_encmap+19529, -0,254},{__big5_encmap+19784,0,255},{__big5_encmap+20040,1,254},{__big5_encmap+ -20294,1,253},{__big5_encmap+20547,5,255},{__big5_encmap+20798,0,255},{ -__big5_encmap+21054,0,255},{__big5_encmap+21310,0,164},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{__big5_encmap+21475,12,13},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+21477,48, -107},{__big5_encmap+21537,1,227}, -}; - -static const ucs2_t __cp950ext_decmap[224] = { -8231,U,U,U,U,U,U,U,U,65105,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,U,U,U,U,U,175,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, -U,U,U,U,U,U,U,65374,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8853,8857,8725,65128,U,65509, -U,65504,65505,8364,30849,37561,35023,22715,24658,31911,23290,9556,9574,9559, -9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,9575,9563, -9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,9584,9583, -9619, -}; - -static const struct dbcs_index cp950ext_decmap[256] = { -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_decmap+0,69,243 -},{__cp950ext_decmap+175,65,71},{__cp950ext_decmap+182,225,225},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_decmap+183,214,254 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -}; - -static const DBCHAR __cp950ext_encmap[581] = { -41410,41285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41953,41537,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -41458,N,N,N,41459,63992,63974,63983,63965,63976,63985,63967,63980,63989,63971, -63982,63991,63973,N,63986,63968,N,63988,63970,63975,63984,63966,63981,63990, -63972,N,63987,63969,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,63998,63961,63964,63962,63958,63963,63960,63959,41294,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41538,41470,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41536,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41443,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, -N,N,N,41542,41543,N,N,N,41540, -}; - -static const struct unim_index cp950ext_encmap[256] = { -{__cp950ext_encmap+0,175,175},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, -{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+1,39,172},{0, -0,0},{__cp950ext_encmap+135,21,153},{0,0,0},{0,0,0},{__cp950ext_encmap+268,81, -147},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{__cp950ext_encmap+335,187,187},{0,0,0},{__cp950ext_encmap+ -336,250,250},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+337, -82,82},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+338,129,129},{0,0,0},{ -0,0,0},{0,0,0},{__cp950ext_encmap+339,167,167},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+ -340,207,207},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{__cp950ext_encmap+341,185,185},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ -0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 -},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, -0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+342,81,104},{ -__cp950ext_encmap+366,15,229}, -}; +static const ucs2_t __big5_decmap[16702] = { +12288,65292,12289,12290,65294,8226,65307,65306,65311,65281,65072,8230,8229, +65104,65380,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075, +9588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309, +65081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087, +65088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,65115,65116,65117, +65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,167, +12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,12963, +8453,8254,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,65120, +65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,8734,8786, +8801,65122,65123,65124,65125,65126,8764,8745,8746,8869,8736,8735,8895,13266, +13265,8747,8750,8757,8756,9792,9794,9793,9737,8593,8595,8592,8594,8598,8599, +8601,8600,8741,8739,65295,65340,65295,65340,65284,165,12306,162,163,65285, +65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,13217,13198, +13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,31950,9601, +9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,9609,9532, +9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,9582,9584,9583,9552, +9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,65297,65298,65299, +65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,8548,8549,8550,8551, +8552,8553,12321,12322,12323,12324,12325,12326,12327,12328,12329,21313,21316, +21317,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324, +65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337, +65338,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356, +65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369, +65370,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931, +932,933,934,935,936,937,945,946,947,948,949,950,951,952,953,954,955,956,957, +958,959,960,961,963,964,965,966,967,968,969,12549,12550,12551,12552,12553, +12554,12555,12556,12557,12558,12559,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,12560,12561,12562,12563,12564,12565,12566,12567, +12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580, +12581,12582,12583,12584,12585,729,713,714,711,715,19968,20057,19969,19971, +20035,20061,20102,20108,20154,20799,20837,20843,20960,20992,20993,21147,21269, +21313,21340,21448,19977,19979,19976,19978,20011,20024,20961,20037,20040,20063, +20062,20110,20129,20800,20995,21242,21315,21449,21475,22303,22763,22805,22823, +22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,24037,24049,24050, +24051,24062,24178,24318,24331,24339,25165,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,19985,19984,19981,20013,20016,20025,20043, +23609,20104,20113,20117,20114,20116,20130,20161,20160,20163,20166,20167,20173, +20170,20171,20164,20803,20801,20839,20845,20846,20844,20887,20982,20998,20999, +21000,21243,21246,21247,21270,21305,21320,21319,21317,21342,21380,21451,21450, +21453,22764,22825,22827,22826,22829,23380,23569,23588,23610,23663,24052,24187, +24319,24340,24341,24515,25096,25142,25163,25166,25903,25991,26007,26020,26041, +26085,26352,26376,26408,27424,27490,27513,27595,27604,27611,27663,27700,28779, +29226,29238,29243,29255,29273,29275,29356,29579,19993,19990,19989,19988,19992, +20027,20045,20047,20046,20197,20184,20180,20181,20182,20183,20195,20196,20185, +20190,20805,20804,20873,20874,20908,20985,20986,20984,21002,21152,21151,21253, +21254,21271,21277,20191,21322,21321,21345,21344,21359,21358,21435,21487,21476, +21491,21484,21486,21481,21480,21500,21496,21493,21483,21478,21482,21490,21489, +21488,21477,21485,21499,22235,22234,22806,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22830,22833,22900,22902,23381,23427,23612, +24040,24039,24038,24066,24067,24179,24188,24321,24344,24343,24517,25098,25171, +25172,25170,25169,26021,26086,26414,26412,26410,26411,26413,27491,27597,27665, +27664,27704,27713,27712,27710,29359,29572,29577,29916,29926,29976,29983,29992, +29993,30000,30001,30002,30003,30091,30333,30382,30399,30446,30683,30690,30707, +31034,31166,31348,31435,19998,19999,20050,20051,20073,20121,20132,20134,20133, +20223,20233,20249,20234,20245,20237,20240,20241,20239,20210,20214,20219,20208, +20211,20221,20225,20235,20809,20807,20806,20808,20840,20849,20877,20912,21015, +21009,21010,21006,21014,21155,21256,21281,21280,21360,21361,21513,21519,21516, +21514,21520,21505,21515,21508,21521,21517,21512,21507,21518,21510,21522,22240, +22238,22237,22323,22320,22312,22317,22316,22319,22313,22809,22810,22839,22840, +22916,22904,22915,22909,22905,22914,22913,23383,23384,23431,23432,23429,23433, +23546,23574,23673,24030,24070,24182,24180,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24335,24347,24537,24534,25102,25100,25101, +25104,25187,25179,25176,25910,26089,26088,26092,26093,26354,26355,26377,26429, +26420,26417,26421,27425,27492,27515,27670,27741,27735,27737,27743,27744,27728, +27733,27745,27739,27725,27726,28784,29279,29277,30334,31481,31859,31992,32566, +32650,32701,32769,32771,32780,32786,32819,32895,32905,32907,32908,33251,33258, +33267,33276,33292,33307,33311,33390,33394,33406,34411,34880,34892,34915,35199, +38433,20018,20136,20301,20303,20295,20311,20318,20276,20315,20309,20272,20304, +20305,20285,20282,20280,20291,20308,20284,20294,20323,20316,20320,20271,20302, +20278,20313,20317,20296,20314,20812,20811,20813,20853,20918,20919,21029,21028, +21033,21034,21032,21163,21161,21162,21164,21283,21363,21365,21533,21549,21534, +21566,21542,21582,21543,21574,21571,21555,21576,21570,21531,21545,21578,21561, +21563,21560,21550,21557,21558,21536,21564,21568,21553,21547,21535,21548,22250, +22256,22244,22251,22346,22353,22336,22349,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22343,22350,22334,22352,22351,22331,22767, +22846,22941,22930,22952,22942,22947,22937,22934,22925,22948,22931,22922,22949, +23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,23614,23696, +23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,24420,24418, +24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,25105,25220, +25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,25234,25199, +25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,26463,26446, +26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,27493,27599, +27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,27760,27788, +27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,27796,27800, +27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,29996,29995, +30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,32918,32915, +32925,32920,32923,32922,32946,33391,33426,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33419,33421,35211,35282,35328,35895,35910, +35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,36806,36805,36804, +24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,38446,38449,38442, +38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,20381,20365,20339, +20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,20347,20374,20350, +20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,20925,20989,21051, +21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,21332,21331,21329, +21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,21624,21653,21632, +21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,21658,21602,21608, +21643,21629,21646,22266,22403,22391,22378,22377,22369,22374,22372,22396,22812, +22857,22855,22856,22852,22868,22974,22971,22996,22969,22958,22993,22982,22992, +22989,22987,22995,22986,22959,22963,22994,22981,23391,23396,23395,23447,23450, +23448,23452,23449,23451,23578,23624,23621,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23622,23735,23713,23736,23721,23723,23729, +23731,24088,24090,24086,24085,24091,24081,24184,24218,24215,24220,24213,24214, +24310,24358,24359,24361,24448,24449,24447,24444,24541,24544,24573,24565,24575, +24591,24596,24623,24629,24598,24618,24597,24609,24615,24617,24619,24603,25110, +25109,25151,25150,25152,25215,25289,25292,25284,25279,25282,25273,25298,25307, +25259,25299,25300,25291,25288,25256,25277,25276,25296,25305,25287,25293,25269, +25306,25265,25304,25302,25303,25286,25260,25294,25918,26023,26044,26106,26132, +26131,26124,26118,26114,26126,26112,26127,26133,26122,26119,26381,26379,26477, +26507,26517,26481,26524,26483,26487,26503,26525,26519,26479,26480,26495,26505, +26494,26512,26485,26522,26515,26492,26474,26482,27427,27494,27495,27519,27667, +27675,27875,27880,27891,27825,27852,27877,27827,27837,27838,27836,27874,27819, +27861,27859,27832,27844,27833,27841,27822,27863,27845,27889,27839,27835,27873, +27867,27850,27820,27887,27868,27862,27872,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28821,28814,28818,28810,28825,29228,29229, +29240,29256,29287,29289,29376,29390,29401,29399,29392,29609,29608,29599,29611, +29605,30013,30109,30105,30106,30340,30402,30450,30452,30693,30717,31038,31040, +31041,31177,31176,31354,31353,31482,31998,32596,32652,32651,32773,32954,32933, +32930,32945,32929,32939,32937,32948,32938,32943,33253,33278,33293,33459,33437, +33433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470, +33463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046, +37319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738, +38750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419, +20406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407, +20823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193, +21187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688, +21670,21683,21703,21698,21693,21674,21697,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21700,21704,21679,21675,21681,21691,21673, +21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,22865, +22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,23014, +23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,23627, +23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,24421, +24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,24616, +24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,25366, +25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,25332, +25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,26143, +26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,26613, +26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,26585, +26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,27954, +27946,27969,27941,27916,27953,27934,27927,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27963,27965,27966,27958,27931,27893,27961, +27943,27960,27945,27950,27957,27918,27947,28843,28858,28851,28844,28847,28845, +28856,28846,28836,29232,29298,29295,29300,29417,29408,29409,29623,29642,29627, +29618,29645,29632,29619,29978,29997,30031,30028,30030,30027,30123,30116,30117, +30114,30115,30328,30342,30343,30344,30408,30406,30403,30405,30465,30457,30456, +30473,30475,30462,30460,30471,30684,30722,30740,30732,30733,31046,31049,31048, +31047,31161,31162,31185,31186,31179,31359,31361,31487,31485,31869,32002,32005, +32000,32009,32007,32004,32006,32568,32654,32703,32772,32784,32781,32785,32822, +32982,32997,32986,32963,32964,32972,32993,32987,32974,32990,32996,32989,33268, +33314,33511,33539,33541,33507,33499,33510,33540,33509,33538,33545,33490,33495, +33521,33537,33500,33492,33489,33502,33491,33503,33519,33542,34384,34425,34427, +34426,34893,34923,35201,35284,35336,35330,35331,35998,36000,36212,36211,36276, +36557,36556,36848,36838,36834,36842,36837,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36845,36843,36836,36840,37066,37070,37057, +37059,37195,37194,37325,38274,38480,38475,38476,38477,38754,38761,38859,38893, +38899,38913,39080,39131,39135,39318,39321,20056,20147,20492,20493,20515,20463, +20518,20517,20472,20521,20502,20486,20540,20511,20506,20498,20497,20474,20480, +20500,20520,20465,20513,20491,20505,20504,20467,20462,20525,20522,20478,20523, +20489,20860,20900,20901,20898,20941,20940,20934,20939,21078,21084,21076,21083, +21085,21290,21375,21407,21405,21471,21736,21776,21761,21815,21756,21733,21746, +21766,21754,21780,21737,21741,21729,21769,21742,21738,21734,21799,21767,21757, +21775,22275,22276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057, +23064,23068,23071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403, +23640,23472,23475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632, +23789,23805,23803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235, +24237,24231,24369,24466,24465,24464,24665,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24675,24677,24656,24661,24685,24681,24687, +24708,24735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422, +25406,25391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384, +25421,25420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188, +26181,26177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690, +26708,26665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666, +26693,26643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888, +28010,28053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994, +28020,28009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872, +28879,29241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664, +29674,29662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141, +30140,30137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504, +30697,30768,30759,30776,30749,30772,30775,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30757,30765,30752,30751,30770,31061,31056, +31072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209, +31192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034, +32020,32016,32021,32026,32028,32013,32025,32027,32570,32607,32660,32709,32705, +32774,32792,32789,32793,32791,32829,32831,33009,33026,33008,33029,33005,33012, +33030,33016,33011,33032,33021,33034,33020,33007,33261,33260,33280,33296,33322, +33323,33320,33324,33467,33579,33618,33620,33610,33592,33616,33609,33589,33588, +33615,33586,33593,33590,33559,33600,33585,33576,33603,34388,34442,34474,34451, +34468,34473,34444,34467,34460,34928,34935,34945,34946,34941,34937,35352,35344, +35342,35340,35349,35338,35351,35347,35350,35343,35345,35912,35962,35961,36001, +36002,36215,36524,36562,36564,36559,36785,36865,36870,36855,36864,36858,36852, +36867,36861,36869,36856,37013,37089,37085,37090,37202,37197,37196,37336,37341, +37335,37340,37337,38275,38498,38499,38497,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38491,38493,38500,38488,38494,38587,39138, +39340,39592,39640,39717,39730,39740,20094,20602,20605,20572,20551,20547,20556, +20570,20553,20581,20598,20558,20565,20597,20596,20599,20559,20495,20591,20589, +20828,20885,20976,21098,21103,21202,21209,21208,21205,21264,21263,21273,21311, +21312,21310,21443,26364,21830,21866,21862,21828,21854,21857,21827,21834,21809, +21846,21839,21845,21807,21860,21816,21806,21852,21804,21859,21811,21825,21847, +22280,22283,22281,22495,22533,22538,22534,22496,22500,22522,22530,22581,22519, +22521,22816,22882,23094,23105,23113,23142,23146,23104,23100,23138,23130,23110, +23114,23408,23495,23493,23492,23490,23487,23494,23561,23560,23559,23648,23644, +23645,23815,23814,23822,23835,23830,23842,23825,23849,23828,23833,23844,23847, +23831,24034,24120,24118,24115,24119,24247,24248,24246,24245,24254,24373,24375, +24407,24428,24425,24427,24471,24473,24478,24472,24481,24480,24476,24703,24739, +24713,24736,24744,24779,24756,24806,24765,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24773,24763,24757,24796,24764,24792,24789, +24774,24799,24760,24794,24775,25114,25115,25160,25504,25511,25458,25494,25506, +25509,25463,25447,25496,25514,25457,25513,25481,25475,25499,25451,25512,25476, +25480,25497,25505,25516,25490,25487,25472,25467,25449,25448,25466,25949,25942, +25937,25945,25943,21855,25935,25944,25941,25940,26012,26011,26028,26063,26059, +26060,26062,26205,26202,26212,26216,26214,26206,26361,21207,26395,26753,26799, +26786,26771,26805,26751,26742,26801,26791,26775,26800,26755,26820,26797,26758, +26757,26772,26781,26792,26783,26785,26754,27442,27578,27627,27628,27691,28046, +28092,28147,28121,28082,28129,28108,28132,28155,28154,28165,28103,28107,28079, +28113,28078,28126,28153,28088,28151,28149,28101,28114,28186,28085,28122,28139, +28120,28138,28145,28142,28136,28102,28100,28074,28140,28095,28134,28921,28937, +28938,28925,28911,29245,29309,29313,29468,29467,29462,29459,29465,29575,29701, +29706,29699,29702,29694,29709,29920,29942,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29943,29980,29986,30053,30054,30050,30064, +30095,30164,30165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524, +30518,30520,30522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520, +31528,31515,31532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113, +32046,32057,32060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670, +32666,32716,32718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072, +33060,33282,33333,33335,33334,33337,33678,33694,33688,33656,33698,33686,33725, +33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,34389,24426, +34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,34974,34952, +34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,35377,35373, +35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,36199,36198, +36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,36880,36885, +36894,36896,36879,36898,36886,36891,36884,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37096,37101,37117,37207,37326,37365,37350, +37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,38516,38518,38519, +38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,40565,40575,40613, +40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,26368,20977,21106, +21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,21927,21884,21898, +21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,21934,21919,21822, +21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,22575,22570,22580, +22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,23194,23167,23186, +23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,23601,23884,23888, +23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,24258,24260,24380, +24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,24867,24826,24853, +24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,25119,25161,25507, +25484,25551,25536,25577,25545,25542,25549,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25554,25571,25552,25569,25558,25581,25582, +25462,25588,25578,25563,25682,25562,25593,25950,25958,25954,25955,26001,26000, +26031,26222,26224,26228,26230,26223,26257,26234,26238,26231,26366,26367,26399, +26397,26874,26837,26848,26840,26839,26885,26847,26869,26862,26855,26873,26834, +26866,26851,26827,26829,26893,26898,26894,26825,26842,26990,26875,27454,27450, +27453,27544,27542,27580,27631,27694,27695,27692,28207,28216,28244,28193,28210, +28263,28234,28192,28197,28195,28187,28251,28248,28196,28246,28270,28205,28198, +28271,28212,28237,28218,28204,28227,28189,28222,28363,28297,28185,28238,28259, +28228,28274,28265,28255,28953,28954,28966,28976,28961,28982,29038,28956,29260, +29316,29312,29494,29477,29492,29481,29754,29738,29747,29730,29733,29749,29750, +29748,29743,29723,29734,29736,29989,29990,30059,30058,30178,30171,30179,30169, +30168,30174,30176,30331,30332,30358,30355,30388,30428,30543,30701,30813,30828, +30831,31245,31240,31243,31237,31232,31384,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31383,31382,31461,31459,31561,31574,31558, +31568,31570,31572,31565,31563,31567,31569,31903,31909,32094,32080,32104,32085, +32043,32110,32114,32097,32102,32098,32112,32115,21892,32724,32725,32779,32850, +32901,33109,33108,33099,33105,33102,33081,33094,33086,33100,33107,33140,33298, +33308,33769,33795,33784,33805,33760,33733,33803,33729,33775,33777,33780,33879, +33802,33776,33804,33740,33789,33778,33738,33848,33806,33796,33756,33799,33748, +33759,34395,34527,34521,34541,34516,34523,34532,34512,34526,34903,35009,35010, +34993,35203,35222,35387,35424,35413,35422,35388,35393,35412,35419,35408,35398, +35380,35386,35382,35414,35937,35970,36015,36028,36019,36029,36033,36027,36032, +36020,36023,36022,36031,36024,36234,36229,36225,36302,36317,36299,36314,36305, +36300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918, +37122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389, +37392,37383,37393,38292,38287,38283,38289,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38291,38290,38286,38538,38542,38539,38525, +38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,38860, +38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,40653, +40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,20679, +21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,21990, +21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,21961, +22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,22626, +22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,23913, +23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,24863, +24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,24845, +24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,25628, +25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,26248, +26262,26244,26264,26253,26371,27028,26989,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26970,26999,26976,26964,26997,26928,27010, +26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,27506,27584, +27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,28357,28325, +28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,28340,29006, +29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,28998,29032, +29014,29242,29266,29495,29509,29503,29502,29807,29786,29781,29791,29790,29761, +29759,29785,29787,29788,30070,30072,30208,30192,30209,30194,30193,30202,30207, +30196,30195,30430,30431,30555,30571,30566,30558,30563,30585,30570,30572,30556, +30565,30568,30562,30702,30862,30896,30871,30872,30860,30857,30844,30865,30867, +30847,31098,31103,31105,33836,31165,31260,31258,31264,31252,31263,31262,31391, +31392,31607,31680,31584,31598,31591,31921,31923,31925,32147,32121,32145,32129, +32143,32091,32622,32617,32618,32626,32681,32680,32676,32854,32856,32902,32900, +33137,33136,33144,33125,33134,33139,33131,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33145,33146,33126,33285,33351,33922,33911, +33853,33841,33909,33894,33899,33865,33900,33883,33852,33845,33889,33891,33897, +33901,33862,34398,34396,34399,34553,34579,34568,34567,34560,34558,34555,34562, +34563,34566,34570,34905,35039,35028,35033,35036,35032,35037,35041,35018,35029, +35026,35228,35299,35435,35442,35443,35430,35433,35440,35463,35452,35427,35488, +35441,35461,35437,35426,35438,35436,35449,35451,35390,35432,35938,35978,35977, +36042,36039,36040,36036,36018,36035,36034,36037,36321,36319,36328,36335,36339, +36346,36330,36324,36326,36530,36611,36617,36606,36618,36767,36786,36939,36938, +36947,36930,36948,36924,36949,36944,36935,36943,36942,36941,36945,36926,36929, +37138,37143,37228,37226,37225,37321,37431,37463,37432,37437,37440,37438,37467, +37451,37476,37457,37428,37449,37453,37445,37433,37439,37466,38296,38552,38548, +38549,38605,38603,38601,38602,38647,38651,38649,38646,38742,38772,38774,38928, +38929,38931,38922,38930,38924,39164,39156,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39165,39166,39347,39345,39348,39649,40169, +40578,40718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689, +20721,20686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039, +22013,22036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296, +22294,22645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820, +22890,22889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521, +23525,23526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149, +24151,24148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930, +24931,24927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722, +25681,25703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036, +27048,27029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085, +27053,27084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404, +28457,28478,28448,28460,28431,28418,28450,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28415,28399,28422,28465,28472,28466,28451, +28437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053, +29066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805, +29956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561, +30913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401, +31469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620, +31929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177, +32186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735, +32862,32858,32903,33104,33152,33167,33160,33162,33151,33154,33255,33274,33287, +33300,33310,33355,33993,33983,33990,33988,33945,33950,33970,33948,33995,33976, +33984,34003,33936,33980,34001,33994,34623,34588,34619,34594,34597,34612,34584, +34645,34615,34601,35059,35074,35060,35065,35064,35069,35048,35098,35055,35494, +35468,35486,35491,35469,35489,35475,35492,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35498,35493,35496,35480,35473,35482,35495, +35946,35981,35980,36051,36049,36050,36203,36249,36245,36348,36628,36626,36629, +36627,36771,36960,36952,36956,36963,36953,36958,36962,36957,36955,37145,37144, +37150,37237,37240,37239,37236,37496,37504,37509,37528,37526,37499,37523,37532, +37544,37500,37521,38305,38312,38313,38307,38309,38308,38553,38556,38555,38604, +38610,38656,38780,38789,38902,38935,38936,39087,39089,39171,39173,39180,39177, +39361,39599,39600,39654,39745,39746,40180,40182,40179,40636,40763,40778,20740, +20736,20731,20725,20729,20738,20744,20745,20741,20956,21127,21128,21129,21133, +21130,21232,21426,22062,22075,22073,22066,22079,22068,22057,22099,22094,22103, +22132,22070,22063,22064,22656,22687,22686,22707,22684,22702,22697,22694,22893, +23305,23291,23307,23285,23308,23304,23534,23532,23529,23531,23652,23653,23965, +23956,24162,24159,24161,24290,24282,24287,24285,24291,24288,24392,24433,24503, +24501,24950,24935,24942,24925,24917,24962,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24956,24944,24939,24958,24999,24976,25003, +24974,25004,24986,24996,24980,25006,25134,25705,25711,25721,25758,25778,25736, +25744,25776,25765,25747,25749,25769,25746,25774,25773,25771,25754,25772,25753, +25762,25779,25973,25975,25976,26286,26283,26292,26289,27171,27167,27112,27137, +27166,27161,27133,27169,27155,27146,27123,27138,27141,27117,27153,27472,27470, +27556,27589,27590,28479,28540,28548,28497,28518,28500,28550,28525,28507,28536, +28526,28558,28538,28528,28516,28567,28504,28373,28527,28512,28511,29087,29100, +29105,29096,29270,29339,29518,29527,29801,29835,29827,29822,29824,30079,30240, +30249,30239,30244,30246,30241,30242,30362,30394,30436,30606,30599,30604,30609, +30603,30923,30917,30906,30922,30910,30933,30908,30928,31295,31292,31296,31293, +31287,31291,31407,31406,31661,31665,31684,31668,31686,31687,31681,31648,31692, +31946,32224,32244,32239,32251,32216,32236,32221,32232,32227,32218,32222,32233, +32158,32217,32242,32249,32629,32631,32687,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32745,32806,33179,33180,33181,33184,33178, +33176,34071,34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028, +34085,34047,34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636, +34643,34907,34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524, +35477,35531,35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547, +35916,35918,35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074, +36065,36205,36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382, +36538,36637,36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968, +36973,36983,37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559, +37610,37548,37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660, +38662,38663,38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187, +39186,39192,39389,39376,39391,39387,39377,39381,39378,39385,39607,39662,39663, +39719,39749,39748,39799,39791,40198,40201,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40195,40617,40638,40654,22696,40786,20754, +20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,22105,22123,22137, +22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,22134,22721,22718, +22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,24977,25001,24970, +25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,25788,25818,25796, +25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,26297,26308,26311, +26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,27233,27211,27207, +27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,28580,28609,28583, +28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,29138,29128,29141, +29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,29855,29854,29922, +29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,30629,30952,30938, +30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,31761,31689,31716, +31707,31713,31721,31718,31957,31958,32266,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32273,32264,32283,32291,32286,32285,32265, +32272,32633,32690,32752,32753,32750,32808,33203,33193,33192,33275,33288,33368, +33369,34122,34137,34120,34152,34153,34115,34121,34157,34154,34142,34691,34719, +34718,34722,34701,34913,35114,35122,35109,35115,35105,35242,35238,35558,35578, +35563,35569,35584,35548,35559,35566,35582,35585,35586,35575,35565,35571,35574, +35580,35947,35949,35987,36084,36420,36401,36404,36418,36409,36405,36667,36655, +36664,36659,36776,36774,36981,36980,36984,36978,36988,36986,37172,37266,37664, +37686,37624,37683,37679,37666,37628,37675,37636,37658,37648,37670,37665,37653, +37678,37657,38331,38567,38568,38570,38613,38670,38673,38678,38669,38675,38671, +38747,38748,38758,38808,38960,38968,38971,38967,38957,38969,38948,39184,39208, +39198,39195,39201,39194,39405,39394,39409,39608,39612,39675,39661,39720,39825, +40213,40227,40230,40232,40210,40219,40664,40660,40845,40860,20778,20767,20769, +20786,21237,22158,22144,22160,22149,22151,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22159,22741,22739,22737,22734,23344,23338, +23332,23418,23607,23656,23996,23994,23997,23992,24171,24396,24509,25033,25026, +25031,25062,25035,25138,25140,25806,25802,25816,25824,25840,25830,25836,25841, +25826,25837,25986,25987,26329,26326,27264,27284,27268,27298,27292,27355,27299, +27262,27287,27280,27296,27484,27566,27610,27656,28632,28657,28639,28640,28635, +28644,28651,28655,28544,28652,28641,28649,28629,28654,28656,29159,29151,29166, +29158,29157,29165,29164,29172,29152,29237,29254,29552,29554,29865,29872,29862, +29864,30278,30274,30284,30442,30643,30634,30640,30636,30631,30637,30703,30967, +30970,30964,30959,30977,31143,31146,31319,31423,31751,31757,31742,31735,31756, +31712,31968,31964,31966,31970,31967,31961,31965,32302,32318,32326,32311,32306, +32323,32299,32317,32305,32325,32321,32308,32313,32328,32309,32319,32303,32580, +32755,32764,32881,32882,32880,32879,32883,33222,33219,33210,33218,33216,33215, +33213,33225,33214,33256,33289,33393,34218,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34180,34174,34204,34193,34196,34223,34203, +34183,34216,34186,34407,34752,34769,34739,34770,34758,34731,34747,34746,34760, +34763,35131,35126,35140,35128,35133,35244,35598,35607,35609,35611,35594,35616, +35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,36425, +36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,36994, +36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,37656, +37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,38584, +38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,39850, +39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,22165, +22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,25851, +25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,27487, +27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,29176, +29559,29557,29863,29887,29973,30294,30296,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30290,30653,30655,30651,30652,30990,31150, +31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,31975,32340, +32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,33229,33231, +33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,34796,34802, +34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,36451,36454, +36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,37328,37780, +37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,38358,38352, +38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,38989,38991, +38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,39683,39686, +39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,40672,40725, +40748,20787,22181,22750,22751,22754,23541,40848,24300,25074,25079,25078,25077, +25856,25871,26336,26333,27365,27357,27354,27347,28699,28703,28712,28698,28701, +28693,28696,29190,29197,29272,29346,29560,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29562,29885,29898,29923,30087,30086,30303, +30305,30663,31001,31153,31339,31337,31806,31807,31800,31805,31799,31808,32363, +32365,32377,32361,32362,32645,32371,32694,32697,32696,33240,34281,34269,34282, +34261,34276,34277,34295,34811,34821,34829,34809,34814,35168,35167,35158,35166, +35649,35676,35672,35657,35674,35662,35663,35654,35673,36104,36106,36476,36466, +36487,36470,36460,36474,36468,36692,36686,36781,37002,37003,37297,37294,37857, +37841,37855,37827,37832,37852,37853,37846,37858,37837,37848,37860,37847,37864, +38364,38580,38627,38698,38695,38753,38876,38907,39006,39000,39003,39100,39237, +39241,39446,39449,39693,39912,39911,39894,39899,40329,40289,40306,40298,40300, +40594,40599,40595,40628,21240,22184,22199,22198,22196,22204,22756,23360,23363, +23421,23542,24009,25080,25082,25880,25876,25881,26342,26407,27372,28734,28720, +28722,29200,29563,29903,30306,30309,31014,31018,31020,31019,31431,31478,31820, +31811,31821,31983,31984,36782,32381,32380,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32386,32588,32768,33242,33382,34299,34297, +34321,34298,34310,34315,34311,34314,34836,34837,35172,35258,35320,35696,35692, +35686,35695,35679,35691,36111,36109,36489,36481,36485,36482,37300,37323,37912, +37891,37885,38369,38704,39108,39250,39249,39336,39467,39472,39479,39477,39955, +39949,40569,40629,40680,40751,40799,40803,40801,20791,20792,22209,22208,22210, +22804,23660,24013,25084,25086,25885,25884,26005,26345,27387,27396,27386,27570, +28748,29211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349, +34330,34851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490, +36493,36491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370, +38712,38713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764, +39761,39981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807, +20796,20795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489, +28753,28760,29568,29924,30090,30318,30316,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31155,31840,31839,32894,32893,33247,35186, +35183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717, +38718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995, +40403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348, +27408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865, +35722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635, +39636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321, +30322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312, +37994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572, +40573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313, +38002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522, +39525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015, +40474,29224,39530,39729,40475,40478,31858,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12542,12445,12446,12293,12353,12354,12355, +12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368, +12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381, +12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394, +12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407, +12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420, +12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433, +12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459, +12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472, +12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485, +12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498, +12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511, +12512,12513,12514,12515,12516,12517,12518,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,12519,12520,12521,12522,12523,12524,12525, +12526,12527,12528,12529,12530,12531,12532,12533,12534,1044,1045,1025,1046, +1047,1048,1049,1050,1051,1052,1059,1060,1061,1062,1063,1064,1065,1066,1067, +1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081, +1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, +1097,1098,1099,1100,1101,1102,1103,9312,9313,9314,9315,9316,9317,9318,9319, +9320,9321,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,20034,20060,20981, +21274,21378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982, +20014,20115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568, +24063,26081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189, +20186,21004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668, +23667,24068,24192,24194,24521,25097,25168,27669,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27702,27715,27711,27707,29358,29360, +29578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232, +20253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158, +21282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908, +22917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,23678,24031, +24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,25185,25190, +25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,26426,26431, +26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,28785,29278, +29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,33407,34381, +35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,20283,20322, +20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,20287,20321, +20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,21391,21552, +21559,21546,21588,21573,21529,21532,21541,21528,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21565,21583,21569,21544,21540,21575, +22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,22848,22950,22936, +22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,23592,23594,23693, +23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,24074,24078,24203, +24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,24528,24557,24552, +24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,24564,25146,25219, +25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,25224,25207,25213, +25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,26457,26453,26444, +26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,27755,27780,27787, +27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,27763,27749,27771, +27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,29381,29589,29591, +29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,32917,32921,32912, +32914,32924,33424,33423,33413,33422,33425,33427,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33418,33411,33412,35960,36809,36799, +37023,37025,37029,37022,37031,37024,38448,38440,38447,38445,20019,20376,20348, +20357,20349,20352,20359,20342,20340,20361,20356,20343,20300,20375,20330,20378, +20345,20353,20344,20368,20380,20372,20382,20370,20354,20373,20331,20334,20894, +20924,20926,21045,21042,21043,21062,21041,21180,21258,21259,21308,21394,21396, +21639,21631,21633,21649,21634,21640,21611,21626,21630,21605,21612,21620,21606, +21645,21615,21601,21600,21656,21603,21607,21604,22263,22265,22383,22386,22381, +22379,22385,22384,22390,22400,22389,22395,22387,22388,22370,22376,22397,22796, +22853,22965,22970,22991,22990,22962,22988,22977,22966,22972,22979,22998,22961, +22973,22976,22984,22964,22983,23394,23397,23443,23445,23620,23623,23726,23716, +23712,23733,23727,23720,23724,23711,23715,23725,23714,23722,23719,23709,23717, +23734,23728,23718,24087,24084,24089,24360,24354,24355,24356,24404,24450,24446, +24445,24542,24549,24621,24614,24601,24626,24587,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24628,24586,24599,24627,24602,24606, +24620,24610,24589,24592,24622,24595,24593,24588,24585,24604,25108,25149,25261, +25268,25297,25278,25258,25270,25290,25262,25267,25263,25275,25257,25264,25272, +25917,26024,26043,26121,26108,26116,26130,26120,26107,26115,26123,26125,26117, +26109,26129,26128,26358,26378,26501,26476,26510,26514,26486,26491,26520,26502, +26500,26484,26509,26508,26490,26527,26513,26521,26499,26493,26497,26488,26489, +26516,27429,27520,27518,27614,27677,27795,27884,27883,27886,27865,27830,27860, +27821,27879,27831,27856,27842,27834,27843,27846,27885,27890,27858,27869,27828, +27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857, +28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398, +29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606, +29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451, +30449,30448,30453,30712,30716,30713,30715,30714,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30711,31042,31039,31173,31352,31355, +31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,33472, +33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,33441, +33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,36811, +36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,38460, +38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,20411, +20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,21309, +21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,21687, +21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,21680, +22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,22437, +22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,23037, +23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,23021, +23464,23628,23760,23768,23756,23767,23755,23771,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23774,23770,23753,23751,23754,23766, +23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,24099,24096, +24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,24631,24633, +24660,24690,24670,24645,24659,24647,24649,24667,24652,24640,24642,24671,24612, +24644,24664,24678,24686,25154,25155,25295,25357,25355,25333,25358,25347,25323, +25337,25359,25356,25336,25334,25344,25363,25364,25338,25365,25339,25328,25921, +25923,26026,26047,26166,26145,26162,26165,26140,26150,26146,26163,26155,26170, +26141,26164,26169,26158,26383,26384,26561,26610,26568,26554,26588,26555,26616, +26584,26560,26551,26565,26603,26596,26591,26549,26573,26547,26615,26614,26606, +26595,26562,26553,26574,26599,26608,26546,26620,26566,26605,26572,26542,26598, +26587,26618,26569,26570,26563,26602,26571,27432,27522,27524,27574,27606,27608, +27616,27680,27681,27944,27956,27949,27935,27964,27967,27922,27914,27866,27955, +27908,27929,27962,27930,27921,27904,27933,27970,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,27905,27928,27959,27907,27919,27968, +27911,27936,27948,27912,27938,27913,27920,28855,28831,28862,28849,28848,28833, +28852,28853,28841,29249,29257,29258,29292,29296,29299,29294,29386,29412,29416, +29419,29407,29418,29414,29411,29573,29644,29634,29640,29637,29625,29622,29621, +29620,29675,29631,29639,29630,29635,29638,29624,29643,29932,29934,29998,30023, +30024,30119,30122,30329,30404,30472,30467,30468,30469,30474,30455,30459,30458, +30695,30696,30726,30737,30738,30725,30736,30735,30734,30729,30723,30739,31050, +31052,31051,31045,31044,31189,31181,31183,31190,31182,31360,31358,31441,31488, +31489,31866,31864,31865,31871,31872,31873,32003,32008,32001,32600,32657,32653, +32702,32775,32782,32783,32788,32823,32984,32967,32992,32977,32968,32962,32976, +32965,32995,32985,32988,32970,32981,32969,32975,32983,32998,32973,33279,33313, +33428,33497,33534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516, +33505,33522,33525,33548,33531,33526,33520,33514,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33508,33504,33530,33523,33517,34423, +34420,34428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835, +36833,36846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332, +37331,38484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528, +20507,20469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533, +20527,20529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082, +21074,21086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735, +21747,21732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751, +21752,21728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470, +22461,22460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062, +23085,23086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555, +23638,23636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238, +24234,24236,24371,24368,24423,24669,24666,24679,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24641,24738,24712,24704,24722,24705, +24733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430, +25388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396, +25432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930, +25926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650, +26697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671, +26702,26692,26676,26653,26642,26644,26662,26664,26670,26701,26682,26661,26656, +27436,27439,27437,27441,27444,27501,32898,27528,27622,27620,27624,27619,27618, +27623,27685,28026,28003,28004,28022,27917,28001,28050,27992,28002,28013,28015, +28049,28045,28143,28031,28038,27998,28007,28000,28055,28016,28028,27999,28034, +28056,27951,28008,28043,28030,28032,28036,27926,28035,28027,28029,28021,28048, +28892,28883,28881,28893,28875,32569,28898,28887,28882,28894,28896,28884,28877, +28869,28870,28871,28890,28878,28897,29250,29304,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29303,29302,29440,29434,29428,29438, +29430,29427,29435,29441,29651,29657,29669,29654,29628,29671,29667,29673,29660, +29650,29659,29652,29661,29658,29655,29656,29672,29918,29919,29940,29941,29985, +30043,30047,30128,30145,30139,30148,30144,30143,30134,30138,30346,30409,30493, +30491,30480,30483,30482,30499,30481,30485,30489,30490,30498,30503,30755,30764, +30754,30773,30767,30760,30766,30763,30753,30761,30771,30762,30769,31060,31067, +31055,31068,31059,31058,31057,31211,31212,31200,31214,31213,31210,31196,31198, +31197,31366,31369,31365,31371,31372,31370,31367,31448,31504,31492,31507,31493, +31503,31496,31498,31502,31497,31506,31876,31889,31882,31884,31880,31885,31877, +32030,32029,32017,32014,32024,32022,32019,32031,32018,32015,32012,32604,32609, +32606,32608,32605,32603,32662,32658,32707,32706,32704,32790,32830,32825,33018, +33010,33017,33013,33025,33019,33024,33281,33327,33317,33587,33581,33604,33561, +33617,33573,33622,33599,33601,33574,33564,33570,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33602,33614,33563,33578,33544,33596, +33613,33558,33572,33568,33591,33583,33577,33607,33605,33612,33619,33566,33580, +33611,33575,33608,34387,34386,34466,34472,34454,34445,34449,34462,34439,34455, +34438,34443,34458,34437,34469,34457,34465,34471,34453,34456,34446,34461,34448, +34452,34883,34884,34925,34933,34934,34930,34944,34929,34943,34927,34947,34942, +34932,34940,35346,35911,35927,35963,36004,36003,36214,36216,36277,36279,36278, +36561,36563,36862,36853,36866,36863,36859,36868,36860,36854,37078,37088,37081, +37082,37091,37087,37093,37080,37083,37079,37084,37092,37200,37198,37199,37333, +37346,37338,38492,38495,38588,39139,39647,39727,20095,20592,20586,20577,20574, +20576,20563,20555,20573,20594,20552,20557,20545,20571,20554,20578,20501,20549, +20575,20585,20587,20579,20580,20550,20544,20590,20595,20567,20561,20944,21099, +21101,21100,21102,21206,21203,21293,21404,21877,21878,21820,21837,21840,21812, +21802,21841,21858,21814,21813,21808,21842,21829,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,21772,21810,21861,21838,21817,21832, +21805,21819,21824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528, +22509,22525,22536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508, +22497,22542,22524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876, +23136,23128,23125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123, +23140,23127,23107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116, +23152,23145,23111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838, +23819,23837,23834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843, +23839,23854,24126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470, +24479,24714,24720,24710,24766,24752,24762,24787,24788,24783,24804,24793,24797, +24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,25482,25474, +25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,25454,25519, +25461,25500,25453,25518,25468,25508,25403,25503,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25464,25477,25473,25489,25485,25456, +25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,26759,26768,26780, +26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,26740,26802,26767, +26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,26774,26763,26784, +26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,27447,27448,27537, +27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,28076,28137,28130, +28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,28124,28125,28123, +28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,28112,28146,28115, +28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,28940,28912,28932, +28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,28930,28942,29310, +29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,29439,29455,29470, +29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,29692,29695,29708, +29707,29684,29704,30052,30051,30158,30162,30159,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30155,30156,30161,30160,30351,30345, +30419,30521,30511,30509,30513,30514,30516,30515,30525,30501,30523,30517,30792, +30802,30793,30797,30794,30796,30758,30789,30800,31076,31079,31081,31082,31075, +31083,31073,31163,31226,31224,31222,31223,31375,31380,31376,31541,31559,31540, +31525,31536,31522,31524,31539,31512,31530,31517,31537,31531,31533,31535,31538, +31544,31514,31523,31892,31896,31894,31907,32053,32061,32056,32054,32058,32069, +32044,32041,32065,32071,32062,32063,32074,32059,32040,32611,32661,32668,32669, +32667,32714,32715,32717,32720,32721,32711,32719,32713,32799,32798,32795,32839, +32835,32840,33048,33061,33049,33051,33069,33055,33068,33054,33057,33045,33063, +33053,33058,33297,33336,33331,33338,33332,33330,33396,33680,33699,33704,33677, +33658,33651,33700,33652,33679,33665,33685,33689,33653,33684,33705,33661,33667, +33676,33693,33691,33706,33675,33662,33701,33711,33672,33687,33712,33663,33702, +33671,33710,33654,33690,34393,34390,34495,34487,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34498,34497,34501,34490,34480,34504, +34489,34483,34488,34508,34484,34491,34492,34499,34493,34494,34898,34953,34965, +34984,34978,34986,34970,34961,34977,34975,34968,34983,34969,34971,34967,34980, +34988,34956,34963,34958,35202,35286,35289,35285,35376,35367,35372,35358,35897, +35899,35932,35933,35965,36005,36221,36219,36217,36284,36290,36281,36287,36289, +36568,36574,36573,36572,36567,36576,36577,36900,36875,36881,36892,36876,36897, +37103,37098,37104,37108,37106,37107,37076,37099,37100,37097,37206,37208,37210, +37203,37205,37356,37364,37361,37363,37368,37348,37369,37354,37355,37367,37352, +37358,38266,38278,38280,38524,38509,38507,38513,38511,38591,38762,38916,39141, +39319,20635,20629,20628,20638,20619,20643,20611,20620,20622,20637,20584,20636, +20626,20610,20615,20831,20948,21266,21265,21412,21415,21905,21928,21925,21933, +21879,22085,21922,21907,21896,21903,21941,21889,21923,21906,21924,21885,21900, +21926,21887,21909,21921,21902,22284,22569,22583,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,22553,22558,22567,22563,22568,22517, +22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,22587, +22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,23189, +23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,23183, +23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,23875, +23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,23857, +23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,24408, +24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,24854, +24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,24836, +24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,25546, +25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,25555, +25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,25948, +25960,25957,25996,26013,26014,26030,26064,26066,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,26236,26220,26235,26240,26225,26233, +26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,26895,26838, +26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,26992,26804, +26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,26903,26830, +26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,26823,27449, +27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,27696,28156, +28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,28225,28253, +28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,28252,28257, +28209,28200,28256,28273,28267,28217,28194,28208,28243,28261,28199,28280,28260, +28279,28245,28281,28242,28262,28213,28214,28250,28960,28958,28975,28923,28974, +28977,28963,28965,28962,28978,28959,28968,28986,28955,29259,29274,29320,29321, +29318,29317,29323,29458,29451,29488,29474,29489,29491,29479,29490,29485,29478, +29475,29493,29452,29742,29740,29744,29739,29718,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29722,29729,29741,29745,29732,29731, +29725,29737,29728,29746,29947,29999,30063,30060,30183,30170,30177,30182,30173, +30175,30180,30167,30357,30354,30426,30534,30535,30532,30541,30533,30538,30542, +30539,30540,30686,30700,30816,30820,30821,30812,30829,30833,30826,30830,30832, +30825,30824,30814,30818,31092,31091,31090,31088,31234,31242,31235,31244,31236, +31385,31462,31460,31562,31547,31556,31560,31564,31566,31552,31576,31557,31906, +31902,31912,31905,32088,32111,32099,32083,32086,32103,32106,32079,32109,32092, +32107,32082,32084,32105,32081,32095,32078,32574,32575,32613,32614,32674,32672, +32673,32727,32849,32847,32848,33022,32980,33091,33098,33106,33103,33095,33085, +33101,33082,33254,33262,33271,33272,33273,33284,33340,33341,33343,33397,33595, +33743,33785,33827,33728,33768,33810,33767,33764,33788,33782,33808,33734,33736, +33771,33763,33727,33793,33757,33765,33752,33791,33761,33739,33742,33750,33781, +33737,33801,33807,33758,33809,33798,33730,33779,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33749,33786,33735,33745,33770,33811, +33731,33772,33774,33732,33787,33751,33762,33819,33755,33790,34520,34530,34534, +34515,34531,34522,34538,34525,34539,34524,34540,34537,34519,34536,34513,34888, +34902,34901,35002,35031,35001,35000,35008,35006,34998,35004,34999,35005,34994, +35073,35017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392, +35415,35416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968, +36026,36030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310, +36316,36303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590, +36581,36597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911, +37126,37164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123, +37217,37220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388, +37376,37394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381, +37398,38267,38285,38284,38288,38535,38526,38536,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38537,38531,38528,38594,38600,38595, +38641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150, +20669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657, +20683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968, +21963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986, +21974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601, +22639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236, +23243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242, +23220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882, +23909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139, +24261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901, +24886,24882,24878,24902,24879,24911,24873,24896,25120,37224,25123,25125,25124, +25541,25585,25579,25616,25618,25609,25632,25636,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25651,25667,25631,25621,25624,25657, +25655,25634,25635,25612,25638,25648,25640,25665,25653,25647,25610,25626,25664, +25637,25639,25611,25575,25627,25646,25633,25614,25967,26002,26067,26246,26252, +26261,26256,26251,26250,26265,26260,26232,26400,26982,26975,26936,26958,26978, +26993,26943,26949,26986,26937,26946,26967,26969,27002,26952,26953,26933,26988, +26931,26941,26981,26864,27000,26932,26985,26944,26991,26948,26998,26968,26945, +26996,26956,26939,26955,26935,26972,26959,26961,26930,26962,26927,27003,26940, +27462,27461,27459,27458,27464,27457,27547,64013,27643,27644,27641,27639,27640, +28315,28374,28360,28303,28352,28319,28307,28308,28320,28337,28345,28358,28370, +28349,28353,28318,28361,28343,28336,28365,28326,28367,28338,28350,28355,28380, +28376,28313,28306,28302,28301,28324,28321,28351,28339,28368,28362,28311,28334, +28323,28999,29012,29010,29027,29024,28993,29021,29026,29042,29048,29034,29025, +28994,29016,28995,29003,29040,29023,29008,29011,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28996,29005,29018,29263,29325,29324, +29329,29328,29326,29500,29506,29499,29498,29504,29514,29513,29764,29770,29771, +29778,29777,29783,29760,29775,29776,29774,29762,29766,29773,29780,29921,29951, +29950,29949,29981,30073,30071,27011,30191,30223,30211,30199,30206,30204,30201, +30200,30224,30203,30198,30189,30197,30205,30361,30389,30429,30549,30559,30560, +30546,30550,30554,30569,30567,30548,30553,30573,30688,30855,30874,30868,30863, +30852,30869,30853,30854,30881,30851,30841,30873,30848,30870,30843,31100,31106, +31101,31097,31249,31256,31257,31250,31255,31253,31266,31251,31259,31248,31395, +31394,31390,31467,31590,31588,31597,31604,31593,31602,31589,31603,31601,31600, +31585,31608,31606,31587,31922,31924,31919,32136,32134,32128,32141,32127,32133, +32122,32142,32123,32131,32124,32140,32148,32132,32125,32146,32621,32619,32615, +32616,32620,32678,32677,32679,32731,32732,32801,33124,33120,33143,33116,33129, +33115,33122,33138,26401,33118,33142,33127,33135,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33092,33121,33309,33353,33348,33344, +33346,33349,34033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926, +33895,33840,33869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850, +33844,33914,33859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887, +33904,33849,33870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896, +33918,33860,33835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518, +34549,34637,34552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022, +35038,35035,35034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298, +35292,35302,35446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457, +35444,35450,35900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200, +36201,36241,36236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332, +36337,36334,36304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609, +36608,36613,36615,36616,36610,36619,36946,36927,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,36932,36937,36925,37136,37133,37135, +37137,37142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427, +37477,37470,37507,37422,37450,37446,37485,37484,37455,37472,37479,37487,37430, +37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,37462,37426,38303, +38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,38648,38645,38771, +38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,39346,39344,39349, +39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,20695,20712,20723, +20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,20952,21120,21121, +21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,22044,22017,22035, +22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,22662,22657,22655, +22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,22676,22671,22782, +22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,23266,23264,23259, +23276,23262,23261,23257,23272,23263,23415,23520,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,23523,23651,23938,23936,23933,23942, +23930,23937,23927,23946,23945,23944,23934,23932,23949,23929,23935,24152,24153, +24147,24280,24273,24279,24270,24284,24277,24281,24274,24276,24388,24387,24431, +24502,24876,24872,24897,24926,24945,24947,24914,24915,24946,24940,24960,24948, +24916,24954,24923,24933,24891,24938,24929,24918,25129,25127,25131,25643,25677, +25691,25693,25716,25718,25714,25715,25725,25717,25702,25766,25678,25730,25694, +25692,25675,25683,25696,25680,25727,25663,25708,25707,25689,25701,25719,25971, +26016,26273,26272,26271,26373,26372,26402,27057,27062,27081,27040,27086,27030, +27056,27052,27068,27025,27033,27022,27047,27021,27049,27070,27055,27071,27076, +27069,27044,27092,27065,27082,27034,27087,27059,27027,27050,27041,27038,27097, +27031,27024,27074,27061,27045,27078,27466,27469,27467,27550,27551,27552,27587, +27588,27646,28366,28405,28401,28419,28453,28408,28471,28411,28462,28425,28494, +28441,28442,28455,28440,28475,28434,28397,28426,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,28470,28531,28409,28398,28461,28480, +28464,28476,28469,28395,28423,28430,28483,28421,28413,28406,28473,28444,28412, +28474,28447,28429,28446,28424,28449,29063,29072,29065,29056,29061,29058,29071, +29051,29062,29057,29079,29252,29267,29335,29333,29331,29507,29517,29521,29516, +29794,29811,29809,29813,29810,29799,29806,29952,29954,29955,30077,30096,30230, +30216,30220,30229,30225,30218,30228,30392,30593,30588,30597,30594,30574,30592, +30575,30590,30595,30898,30890,30900,30893,30888,30846,30891,30878,30885,30880, +30892,30882,30884,31128,31114,31115,31126,31125,31124,31123,31127,31112,31122, +31120,31275,31306,31280,31279,31272,31270,31400,31403,31404,31470,31624,31644, +31626,31633,31632,31638,31629,31628,31643,31630,31621,31640,21124,31641,31652, +31618,31931,31935,31932,31930,32167,32183,32194,32163,32170,32193,32192,32197, +32157,32206,32196,32198,32203,32204,32175,32185,32150,32188,32159,32166,32174, +32169,32161,32201,32627,32738,32739,32741,32734,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,32804,32861,32860,33161,33158,33155, +33159,33165,33164,33163,33301,33943,33956,33953,33951,33978,33998,33986,33964, +33966,33963,33977,33972,33985,33997,33962,33946,33969,34000,33949,33959,33979, +33954,33940,33991,33996,33947,33961,33967,33960,34006,33944,33974,33999,33952, +34007,34004,34002,34011,33968,33937,34401,34611,34595,34600,34667,34624,34606, +34590,34593,34585,34587,34627,34604,34625,34622,34630,34592,34610,34602,34605, +34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,34577, +35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,35051, +35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,35478, +35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,36362, +36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,37148, +37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,37541, +37540,37494,37531,37498,37536,37524,37546,37517,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37542,37530,37547,37497,37527,37503, +37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,37516,37529, +37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,38781,38778, +38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,39085,39086, +39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,39367,39601, +39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,20735,20739, +20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,21132,21233, +21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,22080,22067, +22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,22691,22703, +22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,23298,23289, +23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,23957,23968, +23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,24289,24393, +24498,24971,24963,24953,25009,25008,24994,24969,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,24987,24979,25007,25005,24991,24978, +25002,24993,24973,24934,25011,25133,25710,25712,25750,25760,25733,25751,25756, +25743,25739,25738,25740,25763,25759,25704,25777,25752,25974,25978,25977,25979, +26034,26035,26293,26288,26281,26290,26295,26282,26287,27136,27142,27159,27109, +27128,27157,27121,27108,27168,27135,27116,27106,27163,27165,27134,27175,27122, +27118,27156,27127,27111,27200,27144,27110,27131,27149,27132,27115,27145,27140, +27160,27173,27151,27126,27174,27143,27124,27158,27473,27557,27555,27554,27558, +27649,27648,27647,27650,28481,28454,28542,28551,28614,28562,28557,28553,28556, +28514,28495,28549,28506,28566,28534,28524,28546,28501,28530,28498,28496,28503, +28564,28563,28509,28416,28513,28523,28541,28519,28560,28499,28555,28521,28543, +28565,28515,28535,28522,28539,29106,29103,29083,29104,29088,29082,29097,29109, +29085,29093,29086,29092,29089,29098,29084,29095,29107,29336,29338,29528,29522, +29534,29535,29536,29533,29531,29537,29530,29529,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,29538,29831,29833,29834,29830,29825, +29821,29829,29832,29820,29817,29960,29959,30078,30245,30238,30233,30237,30236, +30243,30234,30248,30235,30364,30365,30366,30363,30605,30607,30601,30600,30925, +30907,30927,30924,30929,30926,30932,30920,30915,30916,30921,31130,31137,31136, +31132,31138,31131,27510,31289,31410,31412,31411,31671,31691,31678,31660,31694, +31663,31673,31690,31669,31941,31944,31948,31947,32247,32219,32234,32231,32215, +32225,32259,32250,32230,32246,32241,32240,32238,32223,32630,32684,32688,32685, +32749,32747,32746,32748,32742,32744,32868,32871,33187,33183,33182,33173,33186, +33177,33175,33302,33359,33363,33362,33360,33358,33361,34084,34107,34063,34048, +34089,34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060, +34036,34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046, +34088,34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031, +34041,34072,34080,34096,34059,34073,34095,34402,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,34646,34659,34660,34679,34785,34675, +34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655, +34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665, +34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081, +35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541, +35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983, +36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387, +36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376, +36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979, +36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254, +37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617, +37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606, +37581,37589,37577,37600,37598,37607,37585,37587,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,37557,37601,37574,37556,38268,38316, +38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,38792, +38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,39162, +39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,39382, +39384,39371,39383,39372,39603,39660,39659,39667,39666,39665,39750,39747,39783, +39796,39793,39782,39798,39797,39792,39784,39780,39788,40188,40186,40189,40191, +40183,40199,40192,40185,40187,40200,40197,40196,40579,40659,40719,40720,20764, +20755,20759,20762,20753,20958,21300,21473,22128,22112,22126,22131,22118,22115, +22125,22130,22110,22135,22300,22299,22728,22717,22729,22719,22714,22722,22716, +22726,23319,23321,23323,23329,23316,23315,23312,23318,23336,23322,23328,23326, +23535,23980,23985,23977,23975,23989,23984,23982,23978,23976,23986,23981,23983, +23988,24167,24168,24166,24175,24297,24295,24294,24296,24293,24395,24508,24989, +25000,24982,25029,25012,25030,25025,25036,25018,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,25023,25016,24972,25815,25814,25808, +25807,25801,25789,25737,25795,25819,25843,25817,25907,25983,25980,26018,26312, +26302,26304,26314,26315,26319,26301,26299,26298,26316,26403,27188,27238,27209, +27239,27186,27240,27198,27229,27245,27254,27227,27217,27176,27226,27195,27199, +27201,27242,27236,27216,27215,27220,27247,27241,27232,27196,27230,27222,27221, +27213,27214,27206,27477,27476,27478,27559,27562,27563,27592,27591,27652,27651, +27654,28589,28619,28579,28615,28604,28622,28616,28510,28612,28605,28574,28618, +28584,28676,28581,28590,28602,28588,28586,28623,28607,28600,28578,28617,28587, +28621,28591,28594,28592,29125,29122,29119,29112,29142,29120,29121,29131,29140, +29130,29127,29135,29117,29144,29116,29126,29146,29147,29341,29342,29545,29542, +29543,29548,29541,29547,29546,29823,29850,29856,29844,29842,29845,29857,29963, +30080,30255,30253,30257,30269,30259,30268,30261,30258,30256,30395,30438,30618, +30621,30625,30620,30619,30626,30627,30613,30617,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30615,30941,30953,30949,30954,30942, +30947,30939,30945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416, +31413,31409,31415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700, +31722,31714,31708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289, +32279,32268,32287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278, +32269,32276,32293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876, +33201,33190,33198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266, +33365,33366,33367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148, +34113,34146,34116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133, +34151,34144,34188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703, +34711,34707,34706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705, +34717,34692,34708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121, +35106,35113,35107,35119,35116,35103,35313,35552,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35554,35570,35572,35573,35549,35604, +35556,35551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984, +36085,36078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416, +36421,36406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665, +36663,36660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265, +37261,37263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667, +37650,37633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623, +37684,37634,37668,37631,37673,37689,37685,37674,37652,37644,37643,37630,37641, +37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,38325,38333,38569, +38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,38959,38962,39204, +39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,39402,39401,39399, +39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,39813,39815,39804, +39806,39803,39810,39827,39826,39824,39802,39829,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39805,39816,40229,40215,40224,40222, +40212,40233,40221,40216,40226,40208,40217,40223,40584,40582,40583,40622,40621, +40661,40662,40698,40722,40765,20774,20773,20770,20772,20768,20777,21236,22163, +22156,22157,22150,22148,22147,22142,22146,22143,22145,22742,22740,22735,22738, +23341,23333,23346,23331,23340,23335,23334,23343,23342,23419,23537,23538,23991, +24172,24170,24510,24507,25027,25013,25020,25063,25056,25061,25060,25064,25054, +25839,25833,25827,25835,25828,25832,25985,25984,26038,26074,26322,27277,27286, +27265,27301,27273,27295,27291,27297,27294,27271,27283,27278,27285,27267,27304, +27300,27281,27263,27302,27290,27269,27276,27282,27483,27565,27657,28620,28585, +28660,28628,28643,28636,28653,28647,28646,28638,28658,28637,28642,28648,29153, +29169,29160,29170,29156,29168,29154,29555,29550,29551,29847,29874,29867,29840, +29866,29869,29873,29861,29871,29968,29969,29970,29967,30084,30275,30280,30281, +30279,30372,30441,30645,30635,30642,30647,30646,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,30644,30641,30632,30704,30963,30973, +30978,30971,30972,30962,30981,30969,30974,30980,31147,31144,31324,31323,31318, +31320,31316,31322,31422,31424,31425,31749,31759,31730,31744,31743,31739,31758, +31732,31755,31731,31746,31753,31747,31745,31736,31741,31750,31728,31729,31760, +31754,31976,32301,32316,32322,32307,38984,32312,32298,32329,32320,32327,32297, +32332,32304,32315,32310,32324,32314,32581,32639,32638,32637,32756,32754,32812, +33211,33220,33228,33226,33221,33223,33212,33257,33371,33370,33372,34179,34176, +34191,34215,34197,34208,34187,34211,34171,34212,34202,34206,34167,34172,34185, +34209,34170,34168,34135,34190,34198,34182,34189,34201,34205,34177,34210,34178, +34184,34181,34169,34166,34200,34192,34207,34408,34750,34730,34733,34757,34736, +34732,34745,34741,34748,34734,34761,34755,34754,34764,34743,34735,34756,34762, +34740,34742,34751,34744,34749,34782,34738,35125,35123,35132,35134,35137,35154, +35127,35138,35245,35247,35246,35314,35315,35614,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,35608,35606,35601,35589,35595,35618, +35599,35602,35605,35591,35597,35592,35590,35612,35603,35610,35919,35952,35954, +35953,35951,35989,35988,36089,36207,36430,36429,36435,36432,36428,36423,36675, +36672,36997,36990,37176,37274,37282,37275,37273,37279,37281,37277,37280,37793, +37763,37807,37732,37718,37703,37756,37720,37724,37750,37705,37712,37713,37728, +37741,37775,37708,37738,37753,37719,37717,37714,37711,37745,37751,37755,37729, +37726,37731,37735,37760,37710,37721,38343,38336,38345,38339,38341,38327,38574, +38576,38572,38688,38687,38680,38685,38681,38810,38817,38812,38814,38813,38869, +38868,38897,38977,38980,38986,38985,38981,38979,39205,39211,39212,39210,39219, +39218,39215,39213,39217,39216,39320,39331,39329,39426,39418,39412,39415,39417, +39416,39414,39419,39421,39422,39420,39427,39614,39678,39677,39681,39676,39752, +39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,40243, +40257,40295,40246,40238,40239,40241,40248,40240,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40261,40258,40259,40254,40247,40256, +40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,40740,40739, +40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,22169,22896, +23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,25066,25072, +25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,26075,26330, +26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,27316,27309, +27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,28672,28667, +28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,29888,29877, +29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,30291,30295, +30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,30992,30994, +30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,31782,31784, +31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,32352,32343, +32339,32693,32691,32759,32760,32885,33233,33234,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,33232,33375,33374,34228,34246,34240, +34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,34248,34245,34225, +34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,34779,34795,34794, +34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,34724,34775,34777, +34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,35153,35145,35626, +35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,35621,35639,35622, +35638,35630,35620,35643,35645,35642,35906,35957,35993,35992,35991,36094,36100, +36098,36096,36444,36450,36448,36439,36438,36446,36453,36455,36443,36442,36449, +36445,36457,36436,36678,36679,36680,36683,37160,37178,37179,37182,37288,37285, +37287,37295,37290,37813,37772,37778,37815,37787,37789,37769,37799,37774,37802, +37790,37798,37781,37768,37785,37791,37773,37809,37777,37810,37796,37800,37812, +37795,37797,38354,38355,38353,38579,38615,38618,24002,38623,38616,38621,38691, +38690,38693,38828,38830,38824,38827,38820,38826,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38818,38821,38871,38873,38870,38872, +38906,38992,38993,38994,39096,39233,39228,39226,39439,39435,39433,39437,39428, +39441,39434,39429,39431,39430,39616,39644,39688,39684,39685,39721,39733,39754, +39756,39755,39879,39878,39875,39871,39873,39861,39864,39891,39862,39876,39865, +39869,40284,40275,40271,40266,40283,40267,40281,40278,40268,40279,40274,40276, +40287,40280,40282,40590,40588,40671,40705,40704,40726,40741,40747,40746,40745, +40744,40780,40789,20788,20789,21142,21239,21428,22187,22189,22182,22183,22186, +22188,22746,22749,22747,22802,23357,23358,23359,24003,24176,24511,25083,25863, +25872,25869,25865,25868,25870,25988,26078,26077,26334,27367,27360,27340,27345, +27353,27339,27359,27356,27344,27371,27343,27341,27358,27488,27568,27660,28697, +28711,28704,28694,28715,28705,28706,28707,28713,28695,28708,28700,28714,29196, +29194,29191,29186,29189,29349,29350,29348,29347,29345,29899,29893,29879,29891, +29974,30304,30665,30666,30660,30705,31005,31003,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31009,31004,30999,31006,31152,31335, +31336,31795,31804,31801,31788,31803,31980,31978,32374,32373,32376,32368,32375, +32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888, +33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263, +34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274, +34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826, +34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254, +35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666, +35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461, +36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184, +37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849, +37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269, +38362,38363,38625,38697,38699,38700,38696,38694,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,38835,38839,38838,38877,38878,38879, +39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,39335, +39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,39444, +39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,39906, +39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,40330, +40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,40304, +40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,40640, +40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,22755, +23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,26079, +26344,26339,26340,27379,27376,27370,27368,27385,27377,27374,27375,28732,28725, +28719,28727,28724,28721,28738,28728,28735,28730,28729,28736,28731,28723,28737, +29203,29204,29352,29565,29564,29882,30379,30378,30398,30445,30668,30670,30671, +30669,30706,31013,31011,31015,31016,31012,31017,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,31154,31342,31340,31341,31479,31817, +31816,31818,31815,31813,31982,32379,32382,32385,32384,32698,32767,32889,33243, +33241,33291,33384,33385,34338,34303,34305,34302,34331,34304,34294,34308,34313, +34309,34316,34301,34841,34832,34833,34839,34835,34838,35171,35174,35257,35319, +35680,35690,35677,35688,35683,35685,35687,35693,36270,36486,36488,36484,36697, +36694,36695,36693,36696,36698,37005,37187,37185,37303,37301,37298,37299,37899, +37907,37883,37920,37903,37908,37886,37909,37904,37928,37913,37901,37877,37888, +37879,37895,37902,37910,37906,37882,37897,37880,37898,37887,37884,37900,37878, +37905,37894,38366,38368,38367,38702,38703,38841,38843,38909,38910,39008,39010, +39011,39007,39105,39106,39248,39246,39257,39244,39243,39251,39474,39476,39473, +39468,39466,39478,39465,39470,39480,39469,39623,39626,39622,39696,39698,39697, +39947,39944,39927,39941,39954,39928,40000,39943,39950,39942,39959,39956,39945, +40351,40345,40356,40349,40338,40344,40336,40347,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40352,40340,40348,40362,40343,40353, +40346,40354,40360,40350,40355,40383,40361,40342,40358,40359,40601,40603,40602, +40677,40676,40679,40678,40752,40750,40795,40800,40798,40797,40793,40849,20794, +20793,21144,21143,22211,22205,22206,23368,23367,24011,24015,24305,25085,25883, +27394,27388,27395,27384,27392,28739,28740,28746,28744,28745,28741,28742,29213, +29210,29209,29566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394, +32391,32392,32395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335, +34339,34332,34329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843, +34848,34852,34844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653, +35706,35707,36112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189, +37305,37951,37947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952, +37937,38373,38372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256, +39254,39481,39485,39494,39492,39490,39489,39482,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39487,39629,39701,39703,39704,39702, +39738,39762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374, +40380,40385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378, +40364,40392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685, +40731,40728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897, +23371,23372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661, +28757,28758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317, +30381,31029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401, +32591,32647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854, +34858,34853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117, +36501,36500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962, +37963,37967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252, +39259,39502,39507,39508,39500,39503,39496,39498,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,39497,39506,39504,39632,39705,39723, +39739,39766,39765,40006,40008,39999,40004,39993,39987,40001,39996,39991,39988, +39986,39997,39990,40411,40402,40414,40410,40395,40400,40412,40401,40415,40425, +40409,40408,40406,40437,40405,40413,40630,40688,40757,40755,40754,40770,40811, +40853,40866,20797,21145,22760,22759,22898,23373,24024,34863,24399,25089,25091, +25092,25897,25893,26006,26347,27409,27410,27407,27594,28763,28762,29218,29570, +29569,29571,30320,30676,31847,31846,32405,33388,34362,34368,34361,34364,34353, +34363,34366,34864,34866,34862,34867,35190,35188,35187,35326,35724,35726,35723, +35720,35909,36121,36504,36708,36707,37308,37986,37973,37981,37975,37982,38852, +38853,38912,39510,39513,39710,39711,39712,40018,40024,40016,40010,40013,40011, +40021,40025,40012,40014,40443,40439,40431,40419,40427,40440,40420,40438,40417, +40430,40422,40434,40432,40418,40428,40436,40435,40424,40429,40642,40656,40690, +40691,40710,40732,40760,40759,40758,40771,40783,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40817,40816,40814,40815,22227,22221, +23374,23661,25901,26349,26350,27411,28767,28769,28765,28768,29219,29915,29925, +30677,31032,31159,31158,31850,32407,32649,33389,34371,34872,34871,34869,34891, +35732,35733,36510,36511,36512,36509,37310,37309,37314,37995,37992,37993,38629, +38726,38723,38727,38855,38885,39518,39637,39769,40035,40039,40038,40034,40030, +40032,40450,40446,40455,40451,40454,40453,40448,40449,40457,40447,40445,40452, +40608,40734,40774,40820,40821,40822,22228,25902,26040,27416,27417,27415,27418, +28770,29222,29354,30680,30681,31033,31849,31851,31990,32410,32408,32411,32409, +33248,33249,34374,34375,34376,35193,35194,35196,35195,35327,35736,35737,36517, +36516,36515,37998,37997,37999,38001,38003,38729,39026,39263,40040,40046,40045, +40459,40461,40464,40463,40466,40465,40609,40693,40713,40775,40824,40827,40826, +40825,22302,28774,31855,34876,36274,36518,37315,38004,38008,38006,38005,39520, +40052,40051,40049,40053,40468,40467,40694,40714,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,40868,28776,28773,31991,34410,34878, +34877,34879,35742,35996,36521,36553,38731,39027,39028,39116,39265,39339,39524, +39526,39527,39716,40469,40471,40776,25095,27422,29223,34380,36520,38018,38016, +38017,39529,39528,39726,40473,29225,34379,35743,38019,40057,40631,30325,39531, +40058,40477,28777,28778,40612,40830,40777,40856, +}; + +static const struct dbcs_index big5_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_decmap+0,64,254},{ +__big5_decmap+191,64,254},{__big5_decmap+382,64,191},{__big5_decmap+510,64,254 +},{__big5_decmap+701,64,254},{__big5_decmap+892,64,254},{__big5_decmap+1083, +64,254},{__big5_decmap+1274,64,254},{__big5_decmap+1465,64,254},{__big5_decmap ++1656,64,254},{__big5_decmap+1847,64,254},{__big5_decmap+2038,64,254},{ +__big5_decmap+2229,64,254},{__big5_decmap+2420,64,254},{__big5_decmap+2611,64, +254},{__big5_decmap+2802,64,254},{__big5_decmap+2993,64,254},{__big5_decmap+ +3184,64,254},{__big5_decmap+3375,64,254},{__big5_decmap+3566,64,254},{ +__big5_decmap+3757,64,254},{__big5_decmap+3948,64,254},{__big5_decmap+4139,64, +254},{__big5_decmap+4330,64,254},{__big5_decmap+4521,64,254},{__big5_decmap+ +4712,64,254},{__big5_decmap+4903,64,254},{__big5_decmap+5094,64,254},{ +__big5_decmap+5285,64,254},{__big5_decmap+5476,64,254},{__big5_decmap+5667,64, +254},{__big5_decmap+5858,64,254},{__big5_decmap+6049,64,254},{__big5_decmap+ +6240,64,254},{__big5_decmap+6431,64,254},{__big5_decmap+6622,64,254},{ +__big5_decmap+6813,64,254},{__big5_decmap+7004,64,254},{__big5_decmap+7195,64, +252},{0,0,0},{__big5_decmap+7384,64,254},{__big5_decmap+7575,64,254},{ +__big5_decmap+7766,64,254},{__big5_decmap+7957,64,254},{__big5_decmap+8148,64, +254},{__big5_decmap+8339,64,254},{__big5_decmap+8530,64,254},{__big5_decmap+ +8721,64,254},{__big5_decmap+8912,64,254},{__big5_decmap+9103,64,254},{ +__big5_decmap+9294,64,254},{__big5_decmap+9485,64,254},{__big5_decmap+9676,64, +254},{__big5_decmap+9867,64,254},{__big5_decmap+10058,64,254},{__big5_decmap+ +10249,64,254},{__big5_decmap+10440,64,254},{__big5_decmap+10631,64,254},{ +__big5_decmap+10822,64,254},{__big5_decmap+11013,64,254},{__big5_decmap+11204, +64,254},{__big5_decmap+11395,64,254},{__big5_decmap+11586,64,254},{ +__big5_decmap+11777,64,254},{__big5_decmap+11968,64,254},{__big5_decmap+12159, +64,254},{__big5_decmap+12350,64,254},{__big5_decmap+12541,64,254},{ +__big5_decmap+12732,64,254},{__big5_decmap+12923,64,254},{__big5_decmap+13114, +64,254},{__big5_decmap+13305,64,254},{__big5_decmap+13496,64,254},{ +__big5_decmap+13687,64,254},{__big5_decmap+13878,64,254},{__big5_decmap+14069, +64,254},{__big5_decmap+14260,64,254},{__big5_decmap+14451,64,254},{ +__big5_decmap+14642,64,254},{__big5_decmap+14833,64,254},{__big5_decmap+15024, +64,254},{__big5_decmap+15215,64,254},{__big5_decmap+15406,64,254},{ +__big5_decmap+15597,64,254},{__big5_decmap+15788,64,254},{__big5_decmap+15979, +64,254},{__big5_decmap+16170,64,254},{__big5_decmap+16361,64,254},{ +__big5_decmap+16552,64,213},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const DBCHAR __big5_encmap[21764] = { +41542,41543,N,41540,N,41393,N,N,N,N,N,N,N,N,41560,41427,N,N,N,N,N,41296,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41425,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41426,41918,N,41916,41917,41919, +N,41413,N,N,N,N,N,N,N,N,N,N,N,41915,41796,41797,41798,41799,41800,41801,41802, +41803,41804,41805,41806,41807,41808,41809,41810,41811,41812,N,41813,41814, +41815,41816,41817,41818,41819,N,N,N,N,N,N,N,41820,41821,41822,41823,41824, +41825,41826,41827,41828,41829,41830,41831,41832,41833,41834,41835,41836,N, +41837,41838,41839,41840,41841,41842,41843,51123,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,51121,51122,51124,51125,51126,51127,51128,51129,51130,N,N,N,N,N,N,51131, +51132,51133,51134,51135,51136,51137,51138,51139,51140,51141,51142,51143,51144, +51145,51146,51147,51148,51149,51151,51152,51153,51154,51155,51156,51157,51158, +51159,51160,51161,51162,51163,51164,51165,51166,51167,51168,51169,51170,51171, +51172,51173,51174,51175,51176,N,51150,41302,41304,N,N,N,41381,41382,N,N,41383, +41384,N,N,N,N,41285,N,N,41292,41291,N,N,N,N,N,N,N,N,N,N,N,41388,N,N,41387,N,N, +N,N,N,41392,N,N,41410,41546,N,41409,N,N,N,41547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41657,41658, +41659,41660,41661,41662,41663,41664,41665,41666,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41462,41460,41463,41461,N,N, +41464,41465,41467,41466,41428,N,N,N,41435,41448,41447,N,N,41469,N,41468,N,N,N, +41444,41445,41452,N,N,41453,N,N,N,N,N,41455,41454,N,N,N,N,N,N,41443,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41436,N,N,N,N,N,N,N,N,N,N,N,N,N,41434,41437,N, +N,N,N,41432,41433,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41446,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41449,51177,51178,51179,51180,51181, +51182,51183,51184,51185,51186,N,N,N,N,N,N,N,N,N,N,51187,51188,51189,51190, +51191,51192,51193,51194,51195,51196,41591,N,41592,N,N,N,N,N,N,N,N,N,41594,N,N, +N,41595,N,N,N,41596,N,N,N,41597,N,N,N,41589,N,N,N,N,N,N,N,41588,N,N,N,N,N,N,N, +41587,N,N,N,N,N,N,N,41586,N,N,N,N,N,N,N,41585,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,41636,N,N,N,N,N,N,N,N,N,N,N,N,N,41637,N,N,41639,N,N,N,N,N,N,N,N,41638,N, +N,41598,41633,41635,41634,41644,41645,41646,41306,N,N,N,N,N,N,N,N,N,N,N,N, +41570,41571,41572,41573,41574,41575,41576,41577,41584,41583,41582,41581,41580, +41579,41578,N,N,N,N,41590,41593,N,N,N,N,N,N,N,N,N,N,41405,41404,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,41398,41397,N,N,N,N,N,N,N,N,41407,41406,N,N,N,N,N,N,N,N, +41403,41402,N,N,N,41395,N,N,41399,41396,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +41640,41641,41643,41642,41401,41400,N,N,41459,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +41456,41458,41457,41280,41282,41283,41394,N,50852,N,N,41329,41330,41325,41326, +41333,41334,41337,41338,41321,41322,41541,N,41317,41318,N,N,N,N,N,N,N,41385, +41386,N,N,41667,41668,41669,41670,41671,41672,41673,41674,41675,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,50853,50854,50855,50856,50857,50858,50859, +50860,50861,50862,50863,50864,50865,50866,50867,50868,50869,50870,50871,50872, +50873,50874,50875,50876,50877,50878,50879,50880,50881,50882,50883,50884,50885, +50886,50887,50888,50889,50890,50891,50892,50893,50894,50895,50896,50897,50898, +50899,50900,50901,50902,50903,50904,50905,50906,50907,50908,50909,50910,50911, +50912,50913,50914,50915,50916,50917,50918,50919,50920,50921,50922,50923,50924, +50925,50926,50927,50928,50929,50930,50931,50932,50933,50934,50935,N,N,N,N,N,N, +N,N,N,50850,50851,N,N,50936,50937,50938,50939,50940,50941,50942,51008,51009, +51010,51011,51012,51013,51014,51015,51016,51017,51018,51019,51020,51021,51022, +51023,51024,51025,51026,51027,51028,51029,51030,51031,51032,51033,51034,51035, +51036,51037,51038,51039,51040,51041,51042,51043,51044,51045,51046,51047,51048, +51049,51050,51051,51052,51053,51054,51055,51056,51057,51058,51059,51060,51061, +51062,51063,51064,51065,51066,51067,51068,51069,51070,51105,51106,51107,51108, +51109,51110,51111,51112,51113,51114,51115,51116,51117,51118,51119,51120,N,N,N, +N,N,N,N,50849,41844,41845,41846,41847,41848,41849,41850,41851,41852,41853, +41854,41889,41890,41891,41892,41893,41894,41895,41896,41897,41898,41899,41900, +41901,41902,41903,41904,41905,41906,41907,41908,41909,41910,41911,41912,41913, +41914,41408,41557,41558,N,N,N,N,N,N,N,N,N,N,N,N,41552,41553,41554,N,N,41556,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41559,N,N,N, +N,N,N,N,N,N,41555,N,N,41451,41450,N,N,41551,42048,42050,N,42051,N,N,N,51525, +42070,42068,42071,42069,51526,42147,51535,51533,42146,42145,N,N,42306,42305, +42304,N,42307,42238,N,N,N,N,42464,42465,N,N,N,N,N,N,43203,N,N,N,N,42072,N, +42148,51536,N,42149,51555,42730,52145,N,N,N,N,42073,42150,N,42308,51556,N,N,N, +N,N,51520,42052,N,42075,N,51527,42076,N,N,42151,N,42309,42311,42310,N,N,42466, +42467,N,N,43204,N,44476,42049,N,N,51521,42053,42078,42077,N,N,N,N,N,N,N,N,N, +42468,N,N,N,N,N,N,N,N,N,43205,N,N,N,N,N,N,N,N,N,N,45230,54347,N,N,46787,56497, +56498,N,42054,N,42153,N,N,43206,42055,51528,42079,N,N,42154,42156,51537,42157, +42155,N,N,N,42469,N,43207,N,N,43208,43845,N,42080,42158,N,42470,42472,42471,N, +42731,N,N,43209,43210,43846,43847,N,N,N,N,44477,N,N,56499,N,N,63190,42056,N,N, +N,N,N,42160,42159,51538,42161,42167,N,42162,42163,51540,51539,42165,42166,N, +42164,N,N,N,N,N,N,42314,42315,42316,42317,42313,42320,51562,N,51558,51561, +42321,42337,N,51560,N,42318,42319,42312,N,N,51557,51559,N,N,N,N,N,N,42485, +51632,42482,42486,51642,51630,42483,51634,N,N,N,42484,N,42487,N,42473,51633, +42488,51637,N,51641,51638,N,N,51635,42474,42476,42489,N,42478,51627,42481, +42479,42480,51643,51640,51631,42477,N,N,51628,42475,N,N,N,51636,N,N,N,N,51639, +N,N,N,N,N,N,N,N,N,51629,51814,N,42818,42740,N,N,51815,42737,N,42820,N,42745,N, +42744,51803,42748,42743,51808,51816,N,51812,N,42746,N,N,42749,42734,42823, +51805,N,N,52157,42732,42819,42733,42741,42742,51810,51806,42747,42739,51802, +42735,51813,42821,42824,42738,42816,42822,42736,51811,42817,51817,51804,42750, +51807,N,N,51809,N,43224,52159,52171,43216,N,52172,43211,43221,N,N,43214,52153, +43222,52152,52156,52163,52161,43230,43225,52147,52149,43227,43215,52150,52162, +52169,43220,52155,52148,43219,52151,43223,52154,N,43218,N,43213,N,43228,52164, +43229,52168,N,52166,52170,43226,52158,52146,N,52160,43217,52165,43212,52167,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,43862,43850,N,N,52704,52712,N,43849,43857,43869,N, +52718,52716,52711,N,N,N,43851,52717,52707,43865,43856,43864,52702,N,52714,N, +52705,43860,52706,N,52701,43867,43854,43863,43853,N,52703,52708,N,52715,43861, +43858,52710,43866,52713,52709,43855,43868,43859,43852,43848,N,N,N,N,N,N,N,N,N, +N,52719,N,44503,44481,N,44497,N,44502,53456,53455,53460,53461,44484,N,44493,N, +N,N,44506,44494,N,N,N,N,53449,44487,53450,N,44508,N,44499,44478,44479,53469, +45247,N,44492,44491,53451,44495,54363,44486,53462,44501,44500,44490,53454, +53463,N,53448,44489,53464,44498,53452,44480,N,44483,44482,53465,44496,44485, +44505,44507,53459,44504,N,53467,53453,53468,N,53457,N,53466,N,53458,N,N,N,N, +44488,N,N,N,54371,54359,N,45235,N,54364,54370,45234,54357,45238,54361,54354, +45236,54358,45241,45246,N,54375,N,54353,N,45242,N,54374,N,N,45237,54360,45233, +54355,54351,54365,54352,54350,54362,54368,54369,45239,N,N,55387,54366,54349, +54367,N,45249,54372,45248,54348,N,54356,54373,45244,45243,45240,45245,N,N, +45231,N,N,45232,N,N,46024,N,55390,55383,N,46021,N,55391,N,N,N,55381,55384, +46020,55385,N,N,46023,55389,N,55379,55378,46025,N,46026,46022,46027,55377, +55388,55386,55380,N,N,N,46019,55382,N,N,N,N,N,N,N,N,46794,46788,56503,46797, +56509,56512,46790,46791,56506,46789,56515,46795,56516,N,56511,46796,N,56500, +46793,56501,N,56510,56508,N,56504,46792,56502,46798,56507,56514,56505,56513,N, +N,47542,47539,N,47540,N,57593,57585,47538,47535,57586,N,N,47537,57589,N,57591, +N,N,57598,N,N,57597,57592,47534,57584,47532,57587,47543,57590,N,57594,47536, +47533,57596,57595,47541,N,57588,N,48120,58604,N,58601,48121,N,48119,N,58608, +58605,58598,48118,N,48122,58599,48117,48125,58602,58603,48123,48124,58609, +58606,58607,N,N,N,48810,59640,48807,59637,48809,48811,N,59638,48808,N,59639,N, +59636,N,N,49270,60605,49271,60603,N,60604,60602,60601,N,N,60606,49269,N,N, +61368,61369,N,58600,61367,49272,50015,61931,61932,N,50391,50392,62913,62912, +50540,50539,63440,N,42057,42081,42169,N,42168,42323,42322,42492,42491,42493, +42490,N,42826,42825,42827,N,N,N,N,43232,N,43231,43233,N,43870,N,41561,53470, +41562,45250,41564,41563,55392,N,41565,47544,41566,N,42058,N,42170,42494,43234, +N,42059,42173,42171,42172,N,N,42560,N,N,N,42828,43236,43235,43237,N,N,N,44509, +N,N,N,48812,N,N,N,N,N,N,51534,N,42324,42325,N,N,42561,N,51818,N,43872,43871, +53472,53471,45251,N,42174,51541,N,N,N,N,N,52173,N,43873,N,44512,N,44510,44511, +N,N,N,N,48813,N,42326,N,N,N,42562,51644,N,N,N,N,42829,42830,N,51819,N,N,52174, +43238,52175,N,N,N,N,N,53474,53475,44515,N,53476,N,53473,44516,44514,44513, +53477,N,54376,N,N,N,55393,N,N,56517,57664,N,N,N,48126,48814,59641,N,42060, +42074,N,N,N,N,N,N,N,N,N,N,N,N,N,N,45252,46029,N,47545,N,51522,42175,N,42329, +42327,42328,N,N,43239,42061,42062,N,42082,N,N,42176,42177,42178,51646,42330,N, +51563,N,42566,N,51647,42564,42565,51645,N,N,42567,42563,N,N,N,N,51820,43756, +51821,N,N,51822,N,N,42832,42831,N,N,42835,42833,42834,N,N,N,43245,N,43244, +52180,52177,52178,N,52176,43246,43242,43241,N,43243,43240,N,N,N,N,N,43247,N, +43875,52720,N,52179,43880,N,52721,43876,43879,43878,43877,43874,N,N,N,53480,N, +44519,53483,44517,N,N,N,53479,44520,44518,44521,53481,53482,N,53478,53484,N,N, +N,N,N,N,46033,45253,54377,54379,54378,54380,45254,N,N,46030,N,46031,46032,N, +46800,56519,N,56518,56520,56521,46801,N,46799,57665,57666,47547,47546,58202,N, +N,48192,48193,48194,48196,58610,58611,48195,N,N,N,48815,N,48816,N,N,61933, +62915,62914,63441,N,42063,N,N,N,42332,42331,N,N,42568,N,N,51648,N,N,42837, +42838,42836,42839,51823,51824,N,N,N,N,N,N,N,N,N,N,N,N,43249,52181,N,43248,N, +52722,43884,52723,43883,N,N,N,43881,N,43882,N,N,N,53485,N,N,N,N,45255,54382,N, +45258,54381,45541,45257,45256,N,46036,N,46035,46034,46802,N,N,46805,46806, +46804,N,46803,N,N,57667,N,57668,N,N,N,58613,48197,58612,N,48817,60607,49273,N, +61934,50261,N,42083,42179,51542,N,42180,42181,42333,42334,N,42569,51825,52182, +52183,N,43885,53486,45260,45259,55395,55394,N,N,42064,42182,42335,N,45261, +51523,N,51564,42336,N,51650,42571,42570,51649,42840,N,N,N,N,N,N,44522,N,N, +54383,N,46807,57669,47548,N,N,59642,N,N,62461,N,42183,N,N,52184,52724,45264, +45262,45263,42065,N,42084,41677,42186,N,42185,42184,42339,42338,N,51565,51651, +N,N,N,43253,43250,43252,43251,N,N,43886,N,N,46037,N,42066,N,42187,N,42341, +42340,N,51826,N,N,43254,N,N,N,N,N,51543,N,42343,42342,42572,42573,51827,42841, +N,42842,N,43255,43256,43257,N,43887,52725,N,N,44523,N,N,51524,N,42188,N,N,N,N, +N,51652,N,N,N,51828,51829,N,N,52185,N,52186,N,52727,52726,52729,52728,43888,N, +54384,44525,53487,44524,N,N,N,N,55396,46038,N,55397,N,N,N,N,57670,47549,N,N,N, +N,48198,N,61935,N,N,N,N,51544,N,42344,N,N,N,N,N,N,N,45265,N,N,N,N,42067,42085, +42190,42189,N,42191,N,N,N,N,N,N,43259,N,43258,43260,N,N,N,43889,N,N,N,44526,N, +59643,49743,42086,42346,42361,42356,N,42351,42350,42357,42355,42348,42362, +42349,42345,42360,42359,42358,42347,N,42354,N,N,42353,N,N,42363,42352,42579,N, +42585,42581,N,42587,51653,42584,42574,42577,42580,42576,42583,42586,42575, +42578,42582,42588,N,N,N,N,N,51838,51835,N,42855,51836,42843,42845,42869,42864, +N,N,N,51877,51837,42847,42849,51876,42856,51832,42868,42870,42844,42861,N, +51830,42867,N,42852,N,42862,42863,51831,42860,42858,N,42859,42865,51873,42846, +N,42866,51875,42854,42851,N,51834,42850,51878,42853,N,42857,N,N,N,42848,51874, +N,N,N,N,51833,N,N,N,N,N,N,N,N,N,N,N,52203,52202,43343,52205,52207,52196,52199, +52206,43344,N,N,52193,52197,N,N,52201,52809,43339,52813,43261,52198,43262, +43340,43333,43329,N,52194,43332,43337,43346,52195,52188,43331,52189,52191,N, +43334,N,43336,52187,52192,N,N,43345,43341,52200,43347,N,43338,52190,43335,N,N, +43330,43328,N,52204,N,43342,N,N,N,N,N,52808,52731,52811,N,N,52733,43896,43944, +43892,43943,43901,43940,43890,52732,52803,43939,52815,43941,N,43897,N,N,52805, +52802,43895,N,52730,43942,52810,43900,52812,43945,43891,43902,43899,52800, +43937,52806,52807,43898,43938,43894,N,N,N,N,43893,52734,N,N,N,N,N,N,52804,N,N, +N,N,N,N,N,52814,N,53572,44539,53489,N,53494,44532,44608,53492,44527,44537, +44542,53499,N,44538,44541,N,N,53502,44533,53493,N,N,N,53570,53571,N,44535, +53569,44531,44611,N,53496,44529,N,53574,53497,53501,44534,44610,53498,44540, +53568,53575,54433,N,53573,44612,44528,53500,53491,N,44536,N,N,53490,N,N,53495, +N,N,N,N,N,N,N,N,N,N,N,53488,44609,N,N,54391,N,45284,54439,45282,45279,54396, +45275,54434,45286,54390,54395,54394,44530,45281,54437,N,54440,54387,N,46056,N, +54441,45287,N,45273,45270,54398,45267,N,54438,N,45274,54442,N,54388,54436, +45277,54389,54392,54397,N,N,45278,45276,45288,N,N,N,N,45283,N,45271,45522,N, +45272,54393,45285,45280,54435,45269,N,N,N,45268,N,N,N,N,N,N,N,N,N,N,54385, +54386,55402,N,N,N,46039,46042,55413,46062,55416,46040,55409,46046,46052,46525, +N,N,46050,55406,46063,46043,46051,55414,56535,55419,55407,N,55398,55411,55405, +46049,55417,N,N,46045,46065,46058,N,46047,46044,N,46055,N,55418,55404,55410, +55412,55400,55415,46041,55399,N,46048,46064,46060,55401,46054,N,N,46061,46057, +46053,N,55408,N,N,N,N,N,46059,N,N,N,56533,56529,N,56544,56522,56531,46821, +46822,46814,56540,46824,56527,56526,56524,56542,46812,56536,56525,46815,56534, +46810,56530,56537,56539,N,N,56543,46819,56523,46813,56528,N,46808,N,46820, +56538,46816,46817,46823,46811,41567,46809,56532,N,N,N,N,N,46818,N,N,56541,N,N, +N,47565,47560,N,57685,57681,N,57675,47554,47550,57684,47551,57678,57680,N, +57683,N,47556,N,47563,47557,N,N,57673,47558,47559,57676,47564,N,57674,57679, +47555,57672,47561,47553,N,N,N,47552,57677,57682,N,47562,N,N,N,N,N,N,N,57671,N, +48205,58695,N,58692,N,48199,48211,48212,N,48202,58690,48204,58617,48210,N, +58694,48201,58696,48200,N,58691,58693,48203,58689,58618,58615,N,N,55403,58621, +N,58614,58620,58619,N,58616,N,48207,N,N,N,N,48206,N,N,N,48208,58622,48818, +58688,N,N,N,59717,N,59645,N,48830,59714,48822,48826,59713,N,48825,48821,48824, +48819,48829,59715,59646,48828,59644,48827,59716,59712,48209,N,48831,59718, +48823,48820,N,N,N,N,60614,60616,49275,60617,60615,60613,60612,49277,60611, +49278,N,N,N,N,60609,60610,49274,49313,49276,N,N,60608,N,49744,N,61372,61370, +61375,61373,N,61371,61374,N,N,N,N,N,N,N,50016,61938,61939,50262,N,61940,61936, +61941,61937,49745,N,N,N,62462,62529,50265,62528,50264,50263,N,N,N,N,50266, +62917,62918,N,50394,50393,50395,62916,N,63192,63191,N,50541,50543,50542,63193, +50632,63654,N,N,N,50673,N,63653,63726,N,N,51529,N,N,42365,42364,N,42591,42590, +51655,42589,51654,N,N,42873,51881,N,51880,N,N,42871,42874,N,N,51879,N,42872,N, +N,N,N,N,N,52208,N,52209,43348,N,N,N,N,43946,53576,53577,44613,44614,N,N,54444, +45289,45291,54443,45290,55420,46066,N,N,N,N,46825,46826,56545,N,47567,N,47566, +N,58697,59720,59719,N,63851,42087,51545,N,51566,51567,N,N,N,N,42594,42598, +51657,N,42596,42595,51656,42597,42593,N,N,42592,51658,N,N,N,N,N,N,42918,N,N, +42915,N,42877,51882,N,N,N,51883,N,42913,N,51885,42875,51886,51884,42878,42914, +42917,42916,42876,51887,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43353,52222,N,43355,N, +43354,N,52288,43352,43351,52213,N,52212,N,52210,52215,52214,52211,52220,52221, +52218,52216,43350,N,N,N,52219,43356,52289,N,N,52217,N,43947,43349,N,N,N,N,N,N, +N,43948,52820,N,N,52826,N,N,N,43954,52824,52830,N,52821,52825,52827,52829, +52823,N,52822,52817,52818,43949,N,43951,43950,52819,52828,N,N,N,N,N,N,N,N, +43953,N,N,N,N,N,N,52816,53587,N,53586,53591,53582,N,53585,53584,N,53588,N, +53592,44615,44618,N,N,53583,53589,N,N,N,44617,53578,N,43952,54458,53590,N, +53581,N,44616,53580,N,N,N,N,N,N,54449,N,N,45292,45296,54465,54447,54461,45297, +54463,N,54469,N,54473,N,N,54464,54452,54460,N,54474,54472,54462,54457,54450, +55462,54448,45301,54455,45302,45298,54445,54467,54453,54451,54470,45299,N, +54476,45293,45295,54459,54454,44619,45294,54456,54471,54475,54466,N,54468,N,N, +N,54446,N,N,N,N,55457,N,55466,55465,46074,55458,N,46075,46073,N,55460,46070, +55464,N,55459,55461,55421,46068,N,55474,55473,55470,46067,46071,46072,53579, +55467,46069,45300,55469,55422,55472,55471,N,55475,N,56559,N,55468,N,N,N,N,N,N, +N,N,55463,56551,46836,46839,46834,56550,56554,56549,N,46828,46838,56546,46832, +56553,N,46830,46829,56556,46831,56558,N,56555,46827,N,N,N,46837,56560,56548, +56557,N,N,56547,N,N,46833,N,46835,N,56552,N,56561,N,N,57693,47568,57699,N,N, +47573,57695,57702,57687,47575,47569,57692,48213,57691,57700,47570,N,47574, +57690,57696,57701,57686,47572,57694,N,N,57698,57704,57688,57697,N,47571,57703, +N,N,N,57689,N,N,N,48217,58699,48215,48214,58701,58706,N,58702,N,58705,48220,N, +48805,48219,N,58698,58704,N,48218,58703,N,58700,N,48216,N,N,N,N,N,N,59725,N, +59727,59722,48833,59724,N,48832,59726,N,N,48835,59728,48834,59721,59723,N,N,N, +N,49317,60620,N,49316,60621,49315,60619,49314,60618,N,49747,49746,61942,61944, +N,61943,50017,50018,N,N,50019,62530,50267,N,N,63443,63442,50674,N,42088,42192, +N,N,42919,N,N,N,N,52831,N,N,N,N,46076,46077,N,56562,47576,57705,58707,51546,N, +N,51888,N,N,N,N,N,52290,52832,53593,44620,N,N,61945,N,50396,42089,42366,51568, +N,42599,42600,N,43357,N,N,N,45303,N,47578,N,47579,47577,N,42090,N,42193,42195, +42194,51547,42196,42401,51569,N,42402,N,N,N,N,N,42601,42602,N,N,N,51659,N, +42920,N,51889,N,N,N,43361,52291,N,43359,43360,43358,53594,N,N,N,43958,43957, +43959,43956,N,52833,43362,43955,N,44621,44622,N,44623,N,54477,N,N,N,46078, +55476,45304,N,N,N,N,46840,N,47581,47580,57706,N,48221,48836,N,61376,63194, +63444,42091,42403,N,42404,51665,42604,42607,N,51663,51661,42606,51664,51666, +51660,42609,42608,42605,42603,51662,N,N,N,N,42931,N,N,42928,51894,51897,51896, +N,42922,42930,N,N,42927,51893,51891,42926,N,N,N,42921,42924,N,51892,51899, +51895,42925,42929,42932,51890,51898,42923,N,N,N,N,N,43367,43375,N,52303,52296, +43376,52307,52292,52299,N,N,43366,52293,43364,52300,52304,43363,N,52305,52298, +N,52301,N,43378,43369,52308,52306,N,43374,43372,52297,43371,52295,52294,43370, +43368,43377,43373,43365,N,52302,N,43961,N,43968,52847,43960,52839,52835,N, +52851,52834,N,43963,52844,43966,43969,N,43964,52848,43967,N,44630,52854,52836, +N,N,52838,52845,52849,52853,52850,52843,52846,N,N,52840,43971,52842,52841, +52852,43962,52837,43970,N,43965,N,N,N,N,N,44636,53602,N,44635,N,N,53600,N, +44624,N,44629,N,53599,53596,53601,44625,53595,N,44628,44626,N,53603,44627, +44631,N,N,44632,N,44634,N,N,N,44633,N,N,N,53597,53598,N,N,N,N,53604,N,54484, +45305,55490,54483,54502,N,N,45376,N,54500,N,45310,45306,54509,54493,54496,N, +45379,54506,54498,45307,45380,N,54503,54501,N,N,54486,54507,54495,54490,N, +54480,54508,54492,54479,N,45378,54497,54510,54494,54482,54487,54478,N,45377,N, +54491,54488,45308,54481,N,54505,45309,N,54489,54485,N,N,54504,N,N,N,N,N,N, +46144,55483,N,55480,55497,55485,55498,N,46146,N,N,N,55494,55491,N,N,N,N,N, +55492,55495,55499,N,54499,55501,56647,N,46147,55502,55478,55488,N,55493,N,N, +46145,46148,55500,55503,55482,55479,N,N,55481,N,N,55486,55484,46149,N,55496,N, +N,55487,N,55489,55477,56570,56568,46914,46912,56643,56569,56644,56640,56567, +56646,56566,56573,46846,46845,46844,56571,56641,46841,46913,N,56564,N,56574, +56563,56572,46842,56642,56565,46843,56645,N,N,N,N,N,N,N,57710,47586,47585, +47587,57722,57712,57718,57707,57721,57720,57724,57717,47582,57716,47588,N, +57709,47583,N,57723,47584,57711,57714,57719,57713,57708,N,N,N,N,57715,58709, +48225,58712,58711,58714,58716,N,48223,N,58710,N,58708,58717,58715,58713,N, +58719,N,58718,48227,48222,N,48224,48226,N,N,58720,59735,N,N,59734,59733,N, +59736,59729,N,59730,59738,59731,N,48837,59740,N,59739,59732,N,60625,49320, +60623,60628,60627,59737,N,49319,N,60626,60622,60630,60629,49318,N,60624,N, +48838,N,N,N,49748,N,N,N,61377,61946,61947,61948,50268,N,N,50269,N,62531,N, +62920,62919,N,N,63195,63196,63445,63655,N,42092,42093,N,42094,42197,42405, +51667,42610,42611,N,42935,42936,42934,42933,N,43379,N,N,52309,43381,43380, +52310,N,N,N,43972,N,44637,53605,N,54512,N,45381,46151,54511,46150,N,47589,N, +57725,48839,N,49321,60631,N,50270,N,50544,N,51570,N,42406,51571,42614,N,42612, +42613,42615,N,42938,42937,N,51900,42939,N,N,51901,52311,N,52312,N,43382,43384, +43386,43383,43387,43385,N,N,N,N,N,43976,43973,43975,43977,43974,53606,52855,N, +N,N,53608,53607,44643,N,44639,N,N,44640,44642,44644,44641,N,44646,44645,N,N,N, +N,N,45386,54514,54513,45385,N,45384,45383,45387,45382,N,N,55509,55506,46153, +55505,55510,N,46155,55508,46152,46154,55507,N,56648,N,56649,56650,N,N,N,N, +47590,47598,57726,47592,47596,57761,47597,47593,47594,47591,47595,48230,55504, +48231,48229,N,48228,59741,48840,60632,60633,N,N,50020,50271,N,42095,N,42616, +43978,N,53609,44647,N,N,45390,45389,45388,46156,46157,55511,47599,48841,42096, +51548,42198,51572,N,N,51668,42617,N,N,N,43388,N,N,N,N,56651,N,N,42097,N,42199, +51669,N,N,51902,N,51903,N,42940,N,N,N,55512,46158,N,56652,N,N,N,49322,42098, +42152,42200,51573,42407,N,42944,42943,42941,42942,N,N,52313,43390,43425,52314, +43389,N,N,43982,52856,43981,43979,43980,44650,44648,N,N,53611,44649,53610,N, +44638,54515,N,N,45392,45393,N,N,45391,N,47600,57762,48232,48233,N,58721,49323, +61378,61379,N,50397,63656,51531,42201,N,42099,N,51575,51574,N,N,N,N,42618, +51671,51672,51670,N,51673,N,N,N,N,N,N,N,51911,N,51906,51908,51910,51907,42948, +51904,N,51905,42945,42946,51909,51912,42947,51913,N,N,N,N,N,N,N,52328,N,52322, +52317,43427,52325,52323,52316,52329,52332,52327,52320,43429,52326,43430,52321, +52324,52315,52319,52331,43431,N,43432,N,52318,52330,43426,43428,N,N,N,N,N,N,N, +N,N,N,N,N,N,52907,52900,52906,52899,52901,52861,52859,N,52908,52905,52857,N, +43984,52903,52904,N,52902,52860,52858,43983,52898,52862,N,N,52897,52909,N,N,N, +N,N,N,N,N,44655,N,44654,N,53612,44651,53614,N,44656,53615,N,N,44659,N,44657, +53616,52910,53618,N,44653,N,44652,N,53613,53617,44658,N,N,N,N,45395,45394,N,N, +N,54517,54521,54523,45396,54526,N,45400,54593,N,45402,N,45398,45406,N,45403, +54519,45397,N,54518,54516,54595,54520,N,45399,54594,45404,54525,54524,45405, +54522,45401,N,N,N,N,54596,N,54592,55527,55534,55523,46161,55519,55535,55513, +55532,55530,55524,N,55533,55526,N,55518,55536,55516,55529,55514,N,55537,N, +46162,N,55531,56655,55517,46159,N,55521,N,46160,55520,55525,N,N,55522,N,N,N, +55528,N,N,N,N,56659,N,N,N,56662,56654,N,56656,N,56661,56660,46915,N,55515, +56658,N,N,46916,N,56653,56657,N,N,N,N,57769,N,57776,57767,N,57774,57765,57773, +57777,57764,57768,57763,N,47601,N,57766,47602,57772,57771,57770,N,N,57775,N,N, +N,N,58725,58727,48235,58728,N,58723,N,58722,58732,N,58730,48234,58733,58724, +58729,58731,58726,N,N,N,N,59745,59750,59744,59749,N,59742,59752,59748,59753, +59747,59743,59751,N,59754,59746,N,60634,49327,N,49325,N,49324,49326,N,N,61380, +N,61810,61949,N,N,62532,62533,N,50272,N,62921,N,50398,N,62922,N,63198,50546,N, +50545,63197,50633,N,63446,N,N,N,N,42100,42619,51674,51914,43189,45407,N,N, +42101,42410,42409,42408,N,N,42949,N,N,44660,N,56663,42102,42103,42104,42202,N, +N,43985,N,52911,N,N,N,46163,42105,51549,42411,42412,51576,N,42620,N,N,N,51915, +N,42950,N,51916,N,N,43438,N,N,52334,43436,43435,52333,43433,52335,43434,43437, +N,43986,N,43988,52915,52912,52913,52914,52916,43987,N,N,53620,53619,N,44662,N, +44661,N,N,N,N,N,45410,54598,N,45409,45411,45408,N,N,N,N,46165,54597,N,46166, +55539,N,46167,55538,46164,N,N,N,N,56666,56668,46917,56667,56665,56664,N,N,N, +57780,47607,47605,N,47606,57778,57779,N,47603,58737,58735,N,48237,58736,48238, +48236,47604,N,N,59757,59755,59756,58734,60636,49328,60635,61381,61382,59758, +61950,N,42106,42413,42622,51675,42621,N,43439,46918,N,42203,42414,43989,46168, +N,51577,N,51578,N,51676,N,N,42952,51920,51918,42953,51917,51919,51921,N,42951, +N,N,N,N,N,43443,43444,43441,N,N,43440,52920,43442,N,N,N,43990,N,52919,52921, +52918,52922,43991,44665,53621,N,53623,44663,53624,44664,53622,N,52917,54599, +54602,54603,54600,45415,45414,45412,45413,54601,N,N,N,N,45416,N,N,46170,46171, +N,46172,56669,56671,56673,46920,46919,46169,56672,56670,N,57784,N,N,57782, +57788,47608,57789,57786,47609,57783,57781,57787,48240,58739,57785,48242,58740, +48241,48244,58741,48239,48243,N,59763,59761,59760,59762,59759,N,N,50022,N, +62534,62535,N,62923,63199,50773,N,N,43445,42954,N,N,43992,N,N,N,42107,42204, +42415,51677,N,42955,51922,N,52923,43993,N,47610,42108,N,N,N,42657,N,N,46921, +42109,42205,42206,N,42417,42416,N,51678,42658,N,51923,N,42956,N,N,52337,52338, +52339,N,43446,43447,52336,43448,N,N,N,43994,52924,N,53626,44666,N,53625,N, +45417,54604,45418,54605,N,N,N,46173,N,N,N,56674,N,N,57791,57790,N,47611,N, +48245,58742,48842,59764,49329,N,50547,63448,N,N,N,N,52340,N,52925,45419,55540, +46922,N,N,N,49749,N,N,N,N,42958,N,42957,43995,N,53627,N,45421,45891,45422, +45420,46174,N,57792,47612,48246,N,51532,51679,N,51925,42959,51924,42960,N,N, +43452,52343,52342,43451,43449,43450,52341,N,N,43997,52926,44000,43996,44002, +43998,43999,44001,N,N,N,44669,44668,44667,N,N,N,54607,45423,45426,45424,N, +54606,45429,N,45425,54608,45428,45427,N,N,N,55542,55541,N,46177,46175,46176, +55543,46923,56676,46924,56675,N,N,58743,N,N,48248,57793,48247,N,47613,N,60638, +59765,49330,60637,62016,62536,62537,N,42207,N,42418,N,N,N,51579,N,N,42962, +42964,N,51682,51928,51927,51926,N,51681,51680,42660,42963,42961,42659,N,N,N, +43453,52344,N,43454,51933,N,51935,51934,52345,N,N,51930,N,42968,42966,N,51929, +51931,51937,N,42965,N,51932,51941,43456,N,51938,42967,N,51936,51939,N,43455,N, +43457,51940,N,N,N,N,N,N,N,N,52399,52386,52350,52398,52393,44007,43458,52394, +52397,44003,52396,43459,43464,43462,52387,N,52348,52389,43469,52400,44004, +52390,N,44005,43465,52392,N,52941,44006,52347,43466,44008,43467,43463,43468, +52391,52346,52395,43460,N,N,52349,52388,52385,43461,N,52927,N,52928,N,N,N,N,N, +N,52938,53665,52939,44014,52942,52932,44013,52934,N,52935,N,N,52937,44009,N,N, +44707,N,N,52933,52929,44708,N,N,52943,44670,53629,52936,N,53628,52931,52940,N, +N,44012,44705,44018,44706,52944,53630,44011,44710,44017,44016,44015,44709, +52945,44711,44010,N,52930,N,N,N,N,N,N,N,N,N,N,N,N,45430,53668,53670,N,53672, +44712,44718,54611,53676,53667,45432,54609,N,44717,44715,53678,N,54610,N,53669, +N,44716,53673,44719,53675,N,N,44714,53674,53677,53671,N,44713,45433,N,53666, +45431,N,N,N,N,45434,N,N,N,N,N,N,N,54613,54622,46180,N,45436,45475,46181,54624, +45482,55545,54614,45474,45477,45438,54612,54626,54629,55625,N,54627,55549, +45473,45480,45484,54621,55544,54625,45435,55546,54628,55548,54617,N,46178,N, +54615,54616,45479,N,N,45478,54619,45483,54623,45476,54620,N,45481,46182,46179, +55547,N,54618,N,45437,N,N,N,N,N,N,N,N,N,46187,46191,55616,46929,46189,55620, +46193,56677,55622,46931,46185,46188,55623,N,55624,55630,46195,46932,N,55626, +55631,55619,46942,N,46933,46194,55617,55632,N,46941,46192,46926,55629,N,46196, +55621,55550,46186,55618,N,55627,N,46925,46930,46183,55628,N,46928,N,N,N,46184, +N,N,N,46940,57795,56688,N,56680,57794,N,56684,56686,N,N,56683,N,46939,N,56682, +46943,N,N,N,57810,N,N,46938,47680,56689,57796,N,N,46936,56681,56685,47614, +46927,56678,56679,47681,46935,46937,46934,56687,N,N,57800,57801,57806,48253, +57813,N,47687,N,47686,57808,N,48252,57797,47685,N,57812,47683,47684,N,57809, +58794,48250,46190,N,57811,48291,57803,N,48251,N,48290,57798,57802,57799,57805, +47688,48249,47682,N,58746,57807,N,48289,N,48292,N,57804,N,48254,58745,N,N,N,N, +N,58750,48846,58744,59811,58793,48296,N,48294,48844,58790,58786,48300,N,59768, +N,N,N,48298,58785,N,59766,N,58789,N,58792,58749,N,48299,N,N,48293,59767,48845, +58791,48295,48297,58788,48301,58787,58748,58747,48843,58795,59770,60640,48848, +N,59810,N,59774,N,60641,N,48849,59809,N,59772,49332,60639,N,59769,59771,49333, +48851,49331,48850,49335,59773,48847,N,N,N,N,N,N,N,N,61391,N,61383,N,N,N,N,N, +60647,61384,60643,N,N,49750,60645,60644,49334,60642,60646,61392,61388,61390,N, +61385,61386,N,61389,61387,50023,N,N,50026,50025,50024,50273,62538,50274,62017, +50399,62924,50400,50548,50634,63449,N,63450,63451,N,N,63930,42208,51580,42419, +N,42662,42663,42661,N,42664,42970,42969,N,52401,43471,43470,N,N,53679,45485, +45486,N,N,N,46197,56690,46944,46945,56692,56694,56693,N,57815,N,57814,47689, +57816,N,58796,48302,N,48852,N,49336,49751,49337,N,42209,N,N,N,51942,N,N,52402, +43473,43472,43474,44019,52946,52947,N,N,53680,44720,45487,46198,55633,42210,N, +42110,42211,N,51581,42423,42422,42420,42421,N,N,N,42667,51689,51691,42666, +51683,N,51684,N,51690,51686,51688,42665,51685,51692,51687,N,N,N,N,N,N,42977, +42986,42984,51952,51949,51957,42982,51958,N,42975,51955,N,42981,51951,51950, +42979,51956,42980,43475,42974,51953,N,51943,42971,N,42990,51948,51954,42976, +42978,N,51944,N,51945,51946,N,42989,42983,42988,51947,42987,42973,42972,42985, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43489,52414,52407,43484,43503,52403,52410,52412, +52415,43498,N,52411,52404,43496,52408,N,52416,43481,N,52413,43491,43490,52406, +43479,N,N,43480,N,43478,N,43502,43494,43488,43476,52409,43487,43477,43495, +43504,52948,43492,52405,43482,43485,43486,N,43500,43501,43499,43493,43497, +43483,44020,N,N,N,N,N,N,N,N,N,N,N,N,N,N,52954,44097,44024,44026,44096,52966, +44029,53681,44721,44099,52951,52959,44030,52958,52955,52963,52965,44023,44027, +44098,44723,52960,44025,44101,52953,N,N,N,44028,44722,44022,N,52950,52957, +52949,52952,52956,53682,44100,N,52961,52962,52964,44021,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,44737,53694,44735,44736,53684,53700,N,44726,N,N,54630,53702,53696, +N,53687,N,53705,53690,44732,54653,53693,44734,44725,N,53707,53695,44728,53688, +53685,53686,44729,53701,53708,44731,53692,53691,44739,44738,44724,44730,44733, +53704,N,N,53698,44727,53683,53706,53697,53699,53703,N,N,N,N,N,N,N,N,N,N,54631, +N,45495,45515,45514,N,45503,N,54649,54645,54642,54694,45498,45490,N,N,54647, +46248,45494,54689,N,45516,45513,54651,54634,N,N,45512,54691,54633,45501,45505, +54690,N,54643,45506,45500,54632,N,46200,54693,54641,45511,54644,54692,45510,N, +55634,N,45491,54639,45496,45507,N,45502,54648,54638,54636,54654,45488,45508, +45492,46199,54652,45493,N,45489,45504,45499,45497,54640,45509,54637,54650, +54646,55636,55635,N,N,N,N,N,N,N,N,N,N,N,54635,55652,N,46202,N,55658,55641, +55655,56695,46205,55659,55662,46204,55644,55661,55660,46206,55637,46201,46243, +N,46241,55657,N,55647,46245,55664,55656,55665,46253,46251,55654,55653,N,55651, +55645,46244,N,46242,53689,55638,N,56759,55639,46203,46250,56697,N,46246,46247, +55640,55663,56696,55648,55643,46249,55649,55646,N,N,46254,46960,N,N,56700, +56753,56758,56746,46956,56763,46953,56698,N,56699,46946,46955,56740,46958, +46959,56741,N,56754,56760,46954,N,46948,56739,56701,56762,56744,56745,56702, +56756,56747,56757,56749,N,46949,57817,46952,46950,56761,56752,56748,N,N,56737, +47699,56751,46957,56743,N,56742,N,N,N,46951,46947,57838,56755,56750,N,56738,N, +N,N,N,N,N,N,57833,N,57818,57829,N,57836,47697,46252,57834,47692,N,N,N,47691, +57841,N,57819,57832,57820,57831,47695,57835,55650,N,N,N,57842,57827,47698, +58810,48303,N,57840,57839,47700,58797,48304,58798,N,57823,57824,57821,57826, +57822,57843,47694,48305,47696,47701,N,57825,N,57837,N,N,57830,N,N,58801,N, +47690,48308,59818,58806,58805,58807,N,N,58804,48309,N,48315,48312,N,48313, +58799,58802,58812,48321,48319,N,58803,55642,48306,58809,58800,N,48322,58808, +47693,48311,57828,N,N,48314,N,48318,48320,48317,48316,N,48310,58811,48307, +48323,N,N,N,N,N,N,N,48856,48857,59817,48866,48863,N,48854,48861,59819,48859, +48853,N,48860,N,59816,49339,48855,N,48862,49338,59815,59814,N,48864,N,48865,N, +59813,59812,49340,59822,48858,59820,N,N,N,N,49341,N,49346,60650,60652,N,49343, +N,60653,60649,N,60651,49344,49347,N,60648,49342,49345,49753,59821,49752,N,N, +49758,61396,N,49756,49757,61399,61395,49754,61393,50027,61397,N,61398,61394,N, +49755,62018,N,62021,N,N,62022,62020,62023,50028,62019,N,N,62542,50276,62541, +62540,62539,50275,50277,N,62925,50402,50401,N,N,63201,63200,63203,50635,50549, +63453,63202,N,N,63452,50637,50636,50675,63657,63727,42212,N,N,55666,59823,N,N, +42668,51959,42993,42991,N,42992,N,52417,43505,44102,N,52967,N,52968,N,44103, +53710,N,44740,44741,53709,N,N,N,N,45523,N,45519,N,54695,45526,45525,45518, +45521,45524,45520,N,N,55670,45517,46255,N,N,N,46257,46258,55669,55672,46256, +55667,55671,N,55668,N,46961,N,N,56764,N,N,47702,57844,48867,48324,58813,48325, +48326,58815,58814,58816,59825,N,N,59824,60655,60654,49348,49349,62024,N,N, +42213,N,N,N,N,55673,N,N,N,46260,46259,56765,N,61400,50403,63454,42214,N,44742, +N,45528,45527,55674,55675,46962,57845,47703,59826,N,42215,42424,N,43506,52418, +N,52969,44104,45529,N,55676,46261,46963,N,58817,58818,N,N,60656,49759,63728, +42216,N,52419,43507,44105,N,52970,N,44743,53714,53712,53713,44744,53711,N,N,N, +N,45531,45532,54696,45533,45530,55677,N,55678,56766,N,N,47705,47704,N,N,60657, +61401,N,62026,62025,62543,N,51550,44106,N,N,42217,42425,N,42670,42669,N,N, +42671,42672,51694,51693,51960,42994,51963,51962,51961,51964,N,N,N,N,43508, +52425,52421,52430,43515,N,43513,52426,52422,52429,43512,43584,52424,52420, +43518,52427,43511,52428,43514,43516,52432,52431,52423,43510,43509,43517,N,N,N, +N,N,N,52975,52981,N,44112,44109,52972,52977,N,44115,44107,52976,44110,44113,N, +N,52979,N,44108,52984,44111,N,44114,52973,52978,52982,52974,52971,N,N,52983, +52980,N,N,N,N,N,N,44752,44745,44748,N,44751,N,53717,N,44746,53715,N,44750,N,N, +44747,N,53718,44749,N,N,N,N,N,N,54700,45535,54699,54701,45534,45539,53716,N, +54698,54702,N,45536,54697,45538,N,45537,N,55719,N,55714,N,46262,46266,46263, +55717,55720,N,46264,N,46265,46270,56775,55718,46268,55715,55713,N,46269,N, +55716,N,N,N,46969,N,56767,46966,46967,46965,56772,56771,56768,46971,N,N,56770, +46267,N,N,56774,56769,46968,46964,46970,56773,N,N,N,47708,N,57848,57847,57846, +47706,N,N,N,N,N,47707,58821,58824,48328,N,N,48327,58825,58820,48330,58822,N, +48329,58819,N,58823,48873,48870,59835,59834,N,59833,59828,N,59829,N,N,N,48871, +N,48868,48872,59827,48869,59830,59831,59836,N,N,59832,N,N,60658,N,N,N,49351,N, +61404,49350,61402,61403,49760,50030,62027,N,50029,N,N,62545,62546,N,50278,N, +62544,50404,N,63455,50638,63658,63659,N,42218,N,42673,42674,42995,N,52433, +44116,44753,45540,N,N,45266,N,46271,46272,46028,55721,N,46972,57850,57849,N,N, +42219,42675,52434,43586,N,43585,N,52985,52986,N,53719,53720,44754,44755,N, +44756,54703,N,N,45542,N,46274,N,46273,56776,57210,57851,59837,N,N,49761,50279, +42220,N,42428,42429,42427,42430,42426,N,N,42678,N,51702,42677,42679,N,N,51697, +51696,51699,51698,51701,42676,51695,51700,N,N,N,N,N,51965,43005,51966,52035, +43004,N,52039,52034,52037,42997,42998,42999,43000,N,43072,N,52033,43002,43073, +N,52032,52038,N,43001,52036,43003,42996,43006,N,N,N,N,N,N,N,N,N,43607,N,52436, +43587,N,43597,43598,43590,43608,43592,52444,43603,52439,43593,52454,52455, +52447,52440,43606,52452,43601,43599,N,52453,N,52451,52443,52435,52442,43594,N, +43600,N,43588,52446,52445,52437,N,43602,52449,52438,43605,52456,43589,N,43596, +52441,52450,43604,N,43591,43595,N,52448,N,N,N,N,N,N,N,N,N,N,N,N,N,N,53083, +44124,44137,N,53078,53068,44130,53066,44123,53061,44133,53074,52990,53057,N,N, +N,N,53060,52987,53073,53089,44128,53062,53080,N,52989,53087,53088,53091,53082, +53067,53075,44134,44121,44129,44141,44118,44120,N,N,N,53059,44138,44131,53085, +53056,44140,44135,53065,N,N,44139,53072,53064,44132,53084,53076,N,44126,53090, +53063,44122,53081,53071,44127,53077,44119,52988,44136,44771,44125,53070,53069, +53058,N,53086,N,53079,N,N,44117,53740,44778,53741,N,53729,44767,44779,N,53722, +N,53731,53739,N,53721,53748,44757,N,N,N,53747,53742,N,53743,44765,44776,53733, +N,53734,53744,53735,N,53730,53724,53725,53738,53732,N,N,44758,44762,53746, +53726,44774,44770,N,N,44773,44780,44763,44775,53737,44777,44760,N,44759,53723, +N,53727,44768,53745,53736,53728,44772,44769,N,44761,44764,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,54724,N,54708,54709,54713,N,54728,54725,N,54718,54717, +45549,54721,54736,54704,N,54737,54723,54741,54729,45548,54727,45543,45564, +45554,N,45558,45557,54705,N,54734,54740,54732,54739,N,N,54720,54706,54738, +54722,45546,45559,N,54731,45552,N,N,N,54730,54707,45560,N,45562,54733,45563, +45545,54714,54735,N,N,45551,45561,54716,54726,54711,54715,45556,54710,45544, +45553,45550,54719,44766,55744,45547,N,N,N,N,N,N,N,N,N,N,N,N,N,N,45555,N,55747, +55769,55758,46294,N,46289,55741,46290,55757,N,55750,55763,46286,55723,55765, +46276,55731,46279,46278,N,46295,N,55725,55759,55760,46281,46277,55739,N,46288, +55734,N,55761,46284,55753,55766,55728,55733,55727,N,46283,55746,56798,55729, +46287,55738,55762,46282,55735,55732,55749,46285,46275,46297,55752,55751,55724, +46280,55764,55740,55742,N,55755,55754,55722,46291,46293,55730,55737,55745, +46292,55736,55748,55767,N,55756,N,N,N,N,N,N,N,N,N,N,N,N,N,55768,N,N,N,N,55726, +N,N,N,N,56818,47014,N,56816,56795,56800,56793,N,56812,56779,56786,N,56810, +56820,56796,N,56783,56802,56807,56787,N,56804,56784,N,N,56791,56792,47016, +56811,56809,N,56780,56814,N,56815,56817,47020,47012,N,54712,56788,56806,56789, +47009,47025,56813,47023,47019,56778,47011,N,56781,47024,N,56797,56777,N,47017, +56801,56785,47018,56794,46974,46296,56803,55743,56782,N,N,56808,47013,56805, +47010,56799,47021,56790,56819,N,N,N,N,N,N,47015,57030,N,N,47022,N,N,N,N,N,N, +57930,57928,N,57950,57926,N,57944,46973,47711,57922,57949,N,57927,57941,47716, +47709,N,57947,N,57920,57946,N,47727,57937,57953,47725,57929,47710,57931,57945, +47719,57924,47723,47713,57933,57923,57852,N,57943,47720,57952,57853,47717,N, +57939,N,47718,57925,57936,57932,57934,N,47712,57951,47726,57935,N,57954,N,N, +57854,57940,47715,47724,47722,57921,57942,47721,N,N,47714,57938,N,N,N,N,57948, +N,N,N,N,N,N,N,N,58837,N,58833,58829,58849,58846,48333,N,N,58853,58836,48344, +58843,N,N,58832,58842,48341,58862,N,58859,58845,58830,N,N,58850,58852,48337, +58840,58835,58826,48334,48342,N,58855,48343,58827,58861,58848,58854,48340,N,N, +58851,N,58858,N,48345,N,48339,58844,58831,58863,58828,58856,48336,N,58838,N, +58839,48335,48332,58834,48338,N,48331,N,58857,58860,58841,59850,N,N,N,N,N,N,N, +N,N,59842,N,59838,48886,N,N,48875,48880,48876,59852,59863,48874,59844,59853, +58847,59854,N,N,48881,N,59869,48885,48888,59840,N,48884,N,59867,59868,59858, +59857,59849,N,N,59859,59866,59865,N,48879,48877,59851,59848,N,59845,59864, +48887,59862,48883,48882,N,59856,N,59839,59841,59843,59861,59855,48878,N,59846, +N,59860,N,N,N,N,N,N,59847,N,N,N,N,N,N,N,49359,60741,49352,60661,N,60737,49354, +60744,N,60668,N,60663,N,N,60745,60659,60670,N,49361,60740,60746,60669,49353, +60736,60660,49360,N,N,60743,60665,49356,N,60667,60664,49362,60666,49355,49358, +60739,60662,60742,N,60738,N,N,N,49763,61415,49768,49769,N,N,N,49762,61414,N, +61411,61412,49766,61406,61410,49765,N,61407,N,N,N,N,49767,49764,N,61405,61409, +61413,N,N,N,62033,62030,62039,N,62038,62036,62031,N,50034,N,N,N,N,N,62032, +50033,49357,62035,50032,62040,62034,62029,61408,N,N,N,50031,N,62028,62550,N, +62549,62037,50280,N,62553,62554,62548,62552,N,62547,N,N,N,N,62929,62551,50407, +50405,62927,62930,N,62926,62928,50406,N,N,N,63205,63206,50550,63204,N,N,N, +63458,50639,63456,63457,63660,N,N,50774,63731,63729,63730,63732,N,N,N,63931,N, +42221,42680,N,43609,N,52457,N,N,53092,N,N,N,53749,53751,N,53750,N,53752,45565, +54743,53753,N,54742,54744,54745,55770,46299,55771,55773,46300,46298,55772,N, +56826,56824,56823,N,56822,56821,47026,56825,47728,57955,57957,47729,57956, +48347,N,48346,58864,N,N,59871,59870,59872,N,N,48889,N,60747,49363,N,61416, +49770,62041,50551,42222,42431,42681,43074,43610,43611,N,N,44142,N,N,53754,N,N, +N,N,47027,N,N,N,59089,48890,49771,42223,N,42682,N,N,52459,43612,52458,N,53093, +44143,53094,N,44144,N,53756,44782,44781,N,54750,54748,54749,54747,N,54746,N,N, +55774,55777,46302,55775,46301,55776,N,56827,N,N,57958,57959,57960,N,58867, +58866,48348,58865,58868,59873,N,N,59874,59875,N,60748,49364,49772,62042,N, +50408,51551,N,44145,53095,44783,N,N,45566,N,46303,55778,N,47029,47028,N,N, +57961,57962,48349,48350,59877,59876,61417,63459,42224,51552,42432,N,43075, +52040,N,44146,47030,42225,N,53096,44147,53097,N,49365,42226,N,N,52460,N,53098, +N,53826,53825,53758,N,53757,53827,53824,N,N,45632,45633,N,N,46304,55779,N, +55780,55781,N,N,N,56897,56898,56896,N,56829,56830,47031,57963,58871,58870, +58869,58872,59879,59878,48891,59880,N,49366,60749,N,61418,62043,63207,N,42227, +42434,42433,N,43613,51553,51582,42683,N,51703,52041,52042,43614,N,52461,N, +44148,53099,53100,N,44784,44788,53828,44787,44785,44786,N,54751,45634,46307,N, +46305,46306,55782,N,N,47730,42228,N,51617,N,42435,N,N,51620,N,N,42438,51619, +42437,42436,43076,51618,N,N,51704,N,N,N,51708,51710,51776,42693,42694,51707, +42689,N,51705,N,51709,42690,N,42685,N,42686,N,42692,51706,42684,43077,42687, +42688,42691,N,N,N,52059,52057,52044,43089,52051,43084,52045,N,52053,N,52050, +43087,52049,43094,52058,43096,N,43098,N,52043,N,43085,52060,N,43092,43095,N, +52549,43079,43102,43093,52046,43082,43097,52054,43080,43081,52547,52047,43088, +43099,52061,52048,43086,N,43091,52462,43100,52055,43090,N,43101,43078,52052, +43083,52056,52548,N,N,N,N,N,N,N,N,N,N,N,N,N,43626,43642,52469,43633,N,52555, +43618,N,43621,52546,N,52467,52471,43629,43631,52474,43638,43624,43622,43623, +43637,52551,43632,52473,52475,43630,43635,52476,52554,N,44149,43641,N,43619, +52553,N,52557,52472,52559,52544,43628,52468,43627,43645,43634,N,52466,53109, +43640,43644,52545,52550,N,43646,43639,43625,43615,N,43620,N,52470,43616,52558, +N,52464,52463,52477,52465,43643,44789,43636,52478,43617,N,44198,N,N,N,52556, +53116,53153,N,53156,53111,N,N,53159,53162,53164,53108,44150,44155,53833,44205, +53157,53165,53115,53107,N,N,N,53860,44158,53154,53112,53114,44197,N,53117, +44157,53104,53160,N,53163,N,N,44154,N,44200,53101,44202,44152,44206,53161, +53103,44203,53854,52552,44156,44151,53110,53102,44204,44196,53155,44201,44199, +53113,44193,53105,44194,44195,53106,53158,44153,53118,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,53836,44797,44867,N,N,N,53845,53851,53847,53834,53837,53830, +53831,44874,44794,53846,53855,44869,44790,N,44864,53838,44866,53839,53849,N,N, +N,44868,53864,53832,44796,44795,44872,53829,53862,53850,53863,53857,53843, +53858,N,53852,53861,53859,44873,53844,44793,44792,44865,44871,53856,44870, +53841,45635,N,53865,53840,53835,44798,44875,44791,N,53848,53853,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,45669,54753,54757,N,45650,45648,N,N,45639,54755,54754, +45659,N,54760,45653,N,54778,54855,45636,54775,54768,45671,54752,N,54780,N, +45668,45656,45667,45646,54764,54782,54774,45647,45641,54853,N,54781,54848, +45649,45657,54850,54762,54779,54767,54852,45662,45638,45660,54772,54770,54771, +45651,54766,54765,45640,54759,54854,45642,54769,45672,N,45666,54758,45663, +45661,45670,54776,45665,53842,54777,45664,54849,45637,54773,45655,54761,45654, +N,45652,45644,45643,55783,54851,54763,N,N,55804,N,45645,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,46401,45658,46318,55798,46332,N,55786,46315,46311,55881,46317, +46321,46316,46325,55885,55876,N,N,55793,46330,46324,55805,46308,55882,55875, +46312,55799,46327,55893,55894,N,46309,55880,46329,55803,55789,55790,46333, +55794,55801,55795,N,46331,46404,55791,55784,55785,N,55787,46314,55800,N,46328, +46402,N,N,55802,55891,55883,46310,55889,46322,N,46320,N,55895,46319,55873, +55796,55806,46407,55877,55874,55792,46403,55887,55884,55892,46313,55872,46406, +N,55879,N,N,46323,46326,N,55878,46405,55797,54756,N,N,55888,55886,55890,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,55788,46400,N,N,N,56929,56928,56902,47037,N,56927,56905, +56906,N,47047,56936,47042,56926,N,56899,47048,47038,56914,56904,56907,56931, +47032,56938,56930,47041,56919,47052,N,N,47051,47045,N,N,56937,47033,56917, +56908,56921,56933,47053,N,47035,56916,N,56909,47044,N,47043,56912,56922,56932, +56903,56913,47036,56923,47049,47040,56910,47039,56901,56915,56935,46334,47792, +56918,57964,56920,56934,47046,56911,47034,47050,48368,56900,N,56925,N,N,N, +56924,N,N,N,N,N,N,N,N,N,N,N,N,N,N,58026,47789,57981,58020,47778,N,57966,47791, +N,47735,57965,58032,47793,57969,58019,N,57971,58035,58031,47733,47777,58963, +47790,47741,57967,N,58030,47779,58027,58040,57973,57982,N,N,58038,58028,47740, +N,N,57980,47734,47732,47784,N,N,57978,57975,57976,N,58034,N,58039,58037,47738, +58041,47742,47783,N,57968,58874,57977,N,47736,47788,47785,47739,58021,57972, +47786,58023,47780,47782,47731,N,58025,58017,57970,47781,58033,58036,57979, +58024,N,47737,48351,58022,58873,N,58029,N,N,N,N,N,N,N,N,N,N,57974,58948,58958, +48354,58957,58969,48356,58955,N,58959,48367,N,58950,48359,N,58962,59888,48371, +48370,58964,58947,58974,48365,N,48355,58967,N,58971,58976,58965,58953,48358, +48361,48369,48364,N,58956,58018,N,N,58952,58975,48360,N,48363,58977,48352, +58966,58875,58972,49375,N,58954,N,48353,58949,48357,58876,47787,58945,N,58970, +58946,58944,48362,N,58968,N,58878,58961,58960,58973,58951,48366,N,N,N,N,N,N, +59891,N,48969,48894,59968,59883,48961,59895,48968,48963,59893,60751,59899, +59970,59898,59881,59896,59972,59974,48893,59973,48964,48970,N,48967,N,59902, +48966,59897,N,59885,59890,N,59901,48965,48962,48892,48960,59889,N,58877,59884, +59887,59969,59892,59882,60750,59971,59886,59900,N,N,N,N,60753,49379,N,N,49367, +N,N,49371,60755,60761,60759,49369,49370,49377,60762,60754,49372,N,60758,60757, +60763,49378,N,49373,49376,60756,49380,49374,49381,49368,60760,N,60752,N,N, +61431,N,N,49777,61428,61430,N,49775,61426,61427,61422,N,N,59894,61423,49776, +61419,N,49773,61432,49774,61420,61421,61425,49779,N,49778,N,N,61424,50040, +62047,62053,50041,62044,50038,50035,62055,50039,N,50036,62046,62049,62050, +62051,62054,N,61429,62045,50037,62052,62056,62048,N,N,N,62557,50282,62560, +50283,62568,62559,62556,N,62558,62562,62565,62564,62567,62555,N,50281,62563, +62566,62569,62561,62931,62932,62936,62937,N,62934,62935,62933,N,50409,N,N,N,N, +50552,63211,N,N,63208,63209,63210,50553,N,63461,63460,N,63663,50676,63661, +63664,63662,63733,50775,50789,63907,63852,N,63906,63952,63953,42229,N,N,N,N, +42695,51777,N,N,52062,N,43103,N,43106,N,52063,N,43104,43105,N,N,N,N,52568, +52570,52565,52562,52564,N,N,N,43684,N,N,N,43682,N,N,52566,43683,52563,52560, +43681,52567,N,52561,43685,52569,N,N,N,N,53167,N,53171,N,N,44215,N,N,N,N,53174, +N,44207,44210,44212,44214,44211,53170,53169,N,44209,53172,53173,N,53166,44213, +N,44208,N,N,N,53168,N,N,N,N,N,N,53879,53880,53881,44880,N,44876,53870,N,53878, +53883,44881,N,53868,53874,53867,53877,N,N,53873,44877,44879,53882,N,53866, +53869,53875,N,53876,53884,53872,N,44878,N,N,N,N,N,N,N,N,N,N,45677,54862,N,N, +54864,54860,N,54872,54858,54871,45673,54856,55899,54866,45676,N,54867,54870,N, +54874,N,54863,N,54868,N,N,45674,45675,54873,54861,54857,54875,N,54865,N,N, +54869,N,N,N,54859,N,46408,46409,55909,46415,N,55897,55906,55896,46412,55904, +55902,N,55903,46410,N,55907,N,N,N,N,N,55900,55898,46411,55901,55905,N,N,N, +46413,N,N,N,55908,N,N,N,N,N,N,56944,56951,56953,56993,N,47066,56939,N,47058,N, +56954,47063,56994,47054,N,56957,N,56941,56958,56940,N,47068,N,56952,47055, +56995,N,47060,56945,47065,56956,56943,56950,56946,56942,47057,47064,47062, +47059,47067,47056,56949,N,47061,N,46414,N,56955,N,56947,N,N,N,N,N,56948,N,N, +58049,N,47796,N,N,58045,58051,58047,N,47798,58046,58050,58042,N,58044,47797,N, +N,N,N,58048,58043,N,47799,N,47794,N,N,58052,N,47795,58983,58980,58992,58986, +58988,48372,58982,58990,N,N,58989,58987,N,58993,48375,58984,58991,N,48373,N,N, +58979,58981,48374,58978,58994,N,58985,N,N,59978,48977,N,N,59989,59987,48971, +59977,59980,59981,59976,48981,48982,59975,59990,59985,48975,48972,59984,59982, +N,N,48978,59986,48973,N,48974,N,59983,48976,59979,N,59988,48979,59991,59992, +48980,N,N,49383,49390,60764,60770,N,60768,49386,49385,49382,60766,N,N,N,49388, +49387,49384,N,60769,60765,60767,N,49389,N,N,N,49783,61435,N,49780,49781,61437, +49782,61434,61433,62060,61436,N,62061,50042,62059,N,N,62058,N,62057,50043,N,N, +50284,N,N,62570,62571,N,N,N,N,62940,62939,50410,N,62938,63212,63213,N,N,63462, +63665,N,N,63734,63932,50809,63942,42230,N,43686,43687,N,N,44216,N,N,N,N,49391, +42231,N,43688,44882,47069,42232,N,45678,47800,51554,N,53175,53885,N,58053,N, +49392,42233,43689,53176,53177,55910,46416,N,N,56996,N,N,47070,58054,N,N,48376, +N,50044,42234,55911,42235,N,42697,51778,42696,43109,43108,43107,52064,N,N,N, +43690,N,43691,52571,N,53178,N,53181,44218,53179,N,44217,53180,44219,N,53922, +53921,53886,44883,N,54877,54878,45679,54876,54879,46418,45680,N,N,46417,55915, +55914,N,55912,55913,N,55916,56998,56997,57001,N,57000,56999,47801,58057,N, +58056,47802,58055,58995,N,58996,48377,N,59993,59994,N,N,62066,50045,62065, +62064,62062,62063,50411,62572,63214,63735,N,42236,N,51621,42439,51622,N,N,N, +51779,51780,N,N,N,N,52070,N,N,52066,N,52065,43692,52069,43111,52067,43110, +52071,52068,N,N,52575,53182,52573,52580,N,43693,N,43696,52581,52577,N,52578,N, +52572,43695,52574,43694,52579,N,52576,N,N,53186,44221,44222,N,53189,53183,N, +53188,N,53184,44220,53187,53185,N,N,N,N,N,N,N,53928,53925,N,53927,44888,44887, +44885,53924,53929,44884,44886,53926,54887,53923,53930,N,N,N,N,N,54882,54886,N, +54885,55918,55929,N,N,54888,N,54883,55917,45684,N,N,45683,54881,54884,45685,N, +45682,45681,54880,54889,N,N,N,55920,55927,N,46420,55926,55923,N,46422,N,N,N, +55925,N,N,55919,55921,55924,55922,46421,55928,46419,47071,N,N,57005,57004, +57002,N,47074,47073,57006,N,57003,58058,47803,47072,N,N,N,57008,57007,N,58061, +58059,48378,N,47804,58060,58998,N,N,N,N,48379,58997,59006,59005,59003,N,59002, +58999,59000,59001,59004,59041,N,N,59999,59996,59997,48983,59995,60001,60000, +59998,N,60772,60773,49393,N,49394,60771,N,49785,61438,49784,50046,N,50081, +50285,62574,62573,62941,63215,50554,63464,63463,63465,42440,53190,44889,45686, +54890,42441,51623,42237,N,N,51781,N,N,N,52076,52074,52075,52072,43112,52073,N, +N,N,N,N,52589,N,43699,52587,52583,52586,N,52582,43701,52585,N,43698,43697,N, +43700,52588,52584,N,N,N,N,44226,44229,53198,53197,53196,44223,53205,53195,N, +44225,53935,N,53202,53200,44228,N,53192,53203,N,53194,53204,53201,53193,N, +44224,53206,53191,44227,N,N,N,N,53940,53931,53942,N,53934,53945,53946,53932, +53944,53941,53939,53943,44895,N,44893,N,N,53937,N,53933,N,53936,53947,53938, +44894,53199,N,44890,44892,N,N,N,N,N,54904,54893,54891,N,54892,N,54899,N,54900, +54896,45691,54901,54898,54895,N,45689,54894,45687,45690,54897,54905,44891, +45688,54903,54902,45692,N,N,N,N,N,N,N,N,55934,N,N,N,55969,46432,N,55975,N,N, +55977,55970,46426,55974,55973,46427,46433,N,46434,55976,46424,55933,55931, +55971,55930,46431,55932,55972,55978,46425,46430,46428,46429,N,N,N,46423,N,N,N, +N,47081,57015,47080,57019,N,57009,N,57020,N,N,N,57010,57011,N,57021,57018, +57016,57017,57013,57012,N,57022,47077,N,57014,N,47082,47076,47083,47084,N, +47079,47078,N,N,58062,47806,47805,N,N,58067,N,48380,47807,N,N,47809,58068, +47075,47808,58064,58066,58063,N,58065,N,N,N,59051,N,N,59050,59047,48448,60002, +48449,59046,N,48382,N,59048,59045,59042,59049,59043,59044,48381,N,N,N,N,60777, +N,60006,N,60005,60007,N,60774,48986,N,60003,N,48984,N,48988,48987,60004,60008, +N,48985,N,60781,49397,49786,49398,49395,60778,60776,N,60779,N,60782,49396, +60780,60775,N,N,61506,61509,62069,61504,N,62575,61510,N,50082,61508,49787, +61505,61507,61511,62070,N,62068,N,N,N,N,50083,62067,N,N,N,50286,N,N,N,N,50413, +63217,50412,63219,63216,63218,50640,63666,42442,52590,53948,53949,45693,57023, +48989,50084,50555,63667,42443,N,52591,41568,N,N,53207,N,53208,N,N,N,N,N,53950, +53951,45694,45729,N,N,N,55979,N,57026,57025,57024,58069,N,58070,58071,47810,N, +N,59053,59052,N,N,60009,48990,48991,N,60786,60783,60784,60785,61513,61512, +49788,62071,62942,42444,N,44230,N,45730,57027,N,42445,N,53952,45731,N,N,46435, +46436,N,42446,42447,51782,43114,43113,44231,53209,55980,42448,42449,42450, +42451,N,N,N,43115,43116,52078,52077,N,N,43702,52594,52592,52593,N,N,N,N,N,N, +53210,53211,N,N,44235,44233,N,44234,44232,N,N,N,N,44896,N,N,N,N,44900,44899, +53953,44898,44897,N,53954,N,N,45734,54907,54906,45732,45733,N,N,N,46438,46437, +55982,N,N,55981,45735,N,N,N,N,N,47085,57029,47086,57028,N,N,N,58072,59054, +48450,60010,N,N,N,60787,N,50086,50085,N,N,50556,42452,52595,N,N,45736,58073, +47811,N,N,52079,52080,N,N,52596,43704,43705,N,N,43703,N,N,N,N,44239,44240, +44237,44238,N,53212,N,N,53213,44236,N,N,N,N,53955,N,44904,44905,N,45739,53961, +N,44910,44908,53962,53957,44907,44906,44901,53960,53959,53956,44909,N,53958, +44902,N,44903,N,N,45740,54945,54946,45741,54908,54910,54948,54947,54909,N, +45737,45738,N,55990,46443,46442,55984,46440,N,55987,46444,55988,46445,55985, +46439,46441,55989,N,55986,55983,N,N,N,N,N,57042,N,57031,47088,47091,47090, +47095,47094,57043,57041,57034,57038,57037,47092,57040,57036,57044,57035,47093, +47087,47089,N,57033,N,N,N,N,58075,47815,58079,47814,58076,47813,N,57032,57039, +58078,N,47816,58080,58077,58074,N,N,59057,59061,59063,59059,59058,59056,48453, +48451,48456,48457,59060,48454,59055,48455,47812,59062,48452,N,N,N,60012,N, +60011,60019,60013,60018,60015,48992,60017,N,N,48993,N,48994,N,60016,60014,N,N, +N,N,49400,60788,N,N,49399,60791,60789,60790,N,N,49401,N,N,N,61517,N,49825, +61518,N,N,49789,61519,49790,61516,61520,N,61514,N,N,50087,62072,50088,50287,N, +61515,50288,N,N,N,50414,62943,N,50558,63220,50557,N,63466,50677,50678,N,N, +63948,N,N,44241,53214,N,46446,46447,42453,42698,51783,N,52081,43117,N,43706,N, +44242,44243,44244,54950,53963,44911,N,N,45742,54949,N,N,55992,46449,N,55991, +46448,N,N,57045,48458,59067,59064,59065,59066,N,N,N,N,N,60792,N,61521,N,N,N, +62577,62576,N,63221,42454,52597,44912,N,N,N,46450,57046,N,N,58081,N,48459, +60020,N,61522,62578,42455,N,N,43707,44247,53215,44248,44246,N,44245,53964, +44913,N,N,44914,44915,N,N,N,45744,54951,45743,N,N,N,N,N,55993,45745,46451, +57047,47096,47097,N,47817,N,47818,48460,48996,60021,48995,N,60793,49402,N, +61523,62579,42456,43118,52600,52599,43708,52598,43709,52601,N,53221,44251, +44250,53223,53222,44255,N,44254,44249,N,53217,53218,53219,N,44256,53216,44252, +53220,44253,N,N,N,N,53967,53971,53969,53968,N,53972,N,N,N,53973,53974,53966,N, +53965,N,44917,44918,N,53975,53970,N,54960,N,53976,44919,44916,N,N,N,54954,N, +54953,N,54955,54956,54958,54957,54962,45749,45746,45750,54952,45751,54961, +45748,54959,45747,N,N,N,N,N,55996,55998,55994,55995,N,N,55999,56001,56002, +55997,56000,46452,N,N,57051,N,57056,57048,57052,N,N,57057,57053,47098,47171,N, +47101,57049,57050,47822,47174,47102,N,47172,47100,57055,47173,57054,47169, +47099,47170,57058,58086,58088,N,N,N,N,N,N,N,N,N,47168,N,N,58083,47820,58089, +47821,58087,58082,58085,58090,47819,58084,N,48462,59071,59070,N,48465,48463, +59068,48461,59069,N,48464,N,N,N,60029,N,60065,N,60030,60022,60026,60025,60023, +48998,48999,48997,60024,60027,60028,N,49000,N,49472,60835,N,49404,60795,49406, +49473,N,N,49405,60834,60796,49403,60833,60794,60798,60797,N,N,61525,49828, +49829,49826,N,49827,N,N,61524,N,62075,N,N,50089,N,62073,62074,N,62580,62583, +62581,62582,62944,N,N,50415,63467,63668,N,50679,63736,63737,50790,42457,44257, +N,56003,N,57059,N,42458,43119,N,43710,N,53224,53225,44920,N,N,56004,46453, +47175,49474,60836,62076,62584,42459,N,N,N,52641,52602,52604,52606,52605,52603, +43711,44258,53234,N,53229,53226,N,N,53233,N,N,44260,44261,53232,53231,53230, +53227,53228,53235,44259,N,N,N,N,N,N,N,N,44924,N,44964,44963,53985,53979,53977, +N,44961,54969,44922,53982,53986,53988,53984,53978,44962,53983,53981,44921, +53989,44965,53987,44925,53980,N,44926,44923,N,N,N,N,N,N,N,N,N,N,45753,N,54970, +N,N,54963,54965,54967,N,54968,54966,45754,N,54971,N,54964,N,N,N,N,N,N,N,N,N, +56008,46454,56016,N,56005,N,56017,N,56006,56007,N,N,56015,56014,56011,45752, +46455,56009,56012,46456,56013,56010,N,N,N,N,N,N,N,57070,N,57074,47182,N,58096, +47185,57072,N,N,57069,57064,57066,57067,57060,N,47181,N,N,47180,N,47176,57063, +N,47183,N,47184,57062,57065,57073,47178,47179,57071,57061,N,N,N,58098,47824, +58100,57068,58102,47828,58103,58099,N,47825,58095,47827,58092,58097,58101, +58094,N,N,47177,N,58091,47826,58093,N,N,N,N,N,48468,59073,48472,N,48470,N,N, +47823,N,59080,59081,48467,N,N,59079,59082,48469,48466,59075,59072,59077,59074, +48473,59076,N,N,59078,48471,N,N,N,N,49002,60072,N,60066,60070,60076,60077, +60073,60074,60071,N,60068,N,49004,49001,60067,60069,N,49003,60075,N,49478,N,N, +60842,60837,49477,N,N,49475,N,60844,49476,60840,60841,60838,60845,61526,49479, +60839,N,60846,60843,N,N,N,61530,N,N,61527,N,49830,N,61531,61533,61532,61528, +61529,N,N,62115,N,50090,N,62078,62114,62077,62116,N,N,62113,N,62586,62589, +62585,50289,62587,62588,62590,50290,50292,50291,62945,N,62947,N,62946,N,N,N, +63222,N,N,63669,63738,42460,N,N,52082,43712,52643,43713,43714,52642,N,53240, +53239,44262,44265,44264,44263,53236,53238,53237,N,N,53992,44967,53996,53995, +53994,53990,44966,44970,44973,N,N,44974,53991,53993,44972,44971,44969,44968, +54978,N,54976,54972,45755,N,54973,45756,54974,54975,54977,N,45757,N,N,56021,N, +56020,56019,56018,N,N,N,N,57078,47186,N,57075,57077,N,47187,N,47188,57076,N,N, +N,N,N,58177,N,58105,58106,N,47831,47829,47830,58179,N,58178,58110,58109,58108, +58107,58176,58104,N,59083,59088,59086,N,N,N,59085,59084,59087,N,60078,N,49005, +49480,60848,N,49481,60847,61535,61534,49831,N,62117,50091,62625,50593,63223,N, +63671,63670,51624,44266,44267,54979,N,47190,42461,43122,43121,43120,N,N,N, +52644,N,N,43716,43715,N,44270,N,53242,53245,53243,N,44268,44269,N,N,53241, +53244,N,44981,N,N,N,54003,54005,54004,44978,53999,N,N,44976,44975,N,44979, +44977,N,44980,54002,53997,53998,54001,54000,N,N,N,N,N,N,N,54982,54983,54981,N, +54980,45758,46461,N,56022,56024,56026,46460,N,N,46458,N,56023,46459,56025, +46457,N,N,57153,57079,57082,57086,47194,57084,N,57083,57080,57081,47192,57152, +47191,N,47196,47195,47193,N,57085,N,N,N,58185,N,58184,N,N,58180,N,N,47832, +58183,58182,47833,N,N,N,N,N,48478,N,59090,N,48479,48475,48477,N,48474,48476,N, +N,N,60079,N,49008,60081,60080,N,58181,49010,49009,49006,49007,N,N,N,N,N,60853, +N,60851,49482,60852,N,60854,60850,60849,N,N,61536,49834,49832,49833,N,N,N,N, +62118,62119,50093,N,50092,62627,62628,62626,N,63224,63225,N,N,42462,51784, +43123,N,52645,43718,43717,52646,N,N,53312,44271,53246,44272,N,N,44982,54008, +54006,54012,44983,54007,54011,54009,54010,N,N,54984,54986,N,45759,N,54985, +45760,46498,46497,46462,56027,N,N,N,N,57156,47197,47198,N,57155,57154,N,N,N,N, +58186,47835,47834,58187,58188,N,48481,48480,N,60085,59091,59093,59092,60084, +60082,60086,60083,N,49011,N,N,N,60855,49483,60856,60857,N,N,49835,49836,N, +50293,N,N,50641,42463,N,N,N,N,N,53313,N,N,N,N,N,N,54013,44984,N,N,N,N,N,46010, +46009,N,N,46500,56029,46499,56028,N,N,N,N,57157,N,47836,58189,47837,N,N,N,N,N, +N,50294,62629,N,42699,43719,52647,N,44274,N,44273,53314,53315,N,N,54080,54082, +44985,N,54084,54087,54085,N,N,N,54086,54083,54014,44986,54088,54081,N,N,N,N, +54995,45766,55004,45763,N,54997,45767,N,45761,N,54992,55005,54993,54990,45765, +N,45762,N,54996,54999,45764,55000,45768,55001,54991,54998,55002,54994,54989, +54987,N,N,55003,N,N,56031,N,N,N,N,56036,N,N,N,56032,56038,46503,54988,56033, +46501,56030,46508,56034,46507,56035,46509,46504,46510,46505,N,46506,N,46502,N, +56037,N,N,N,N,N,N,N,47201,57168,N,57171,57159,57164,57158,47203,N,57162,N,N,N, +57160,47202,N,57167,57166,57163,57165,57161,47841,57170,47199,57169,N,N,N,N,N, +N,N,N,N,58205,N,47848,58200,N,47847,58190,N,58192,47840,58197,58196,58199, +47845,58194,58193,N,N,47844,47839,58195,47842,58201,58203,N,58198,58191,47843, +N,N,48489,47838,N,N,58204,N,N,N,N,N,N,N,59097,48482,N,59099,N,48483,N,N,48485, +59102,N,59094,47846,59100,N,N,N,N,59096,N,47200,48488,N,N,48484,N,48486,48487, +N,49014,59101,59095,48490,N,59098,N,N,N,N,N,60096,60091,N,N,60101,49012,60093, +49016,60099,60090,60087,60102,49489,49017,60098,60088,49015,60092,49019,60089, +60094,49018,60097,60100,N,N,N,N,60875,60876,60860,60867,60865,N,N,49487,60872, +60095,N,60863,N,60873,49486,60862,60861,60871,60868,60870,N,60858,60874,49484, +N,60869,60878,60866,49488,49485,60864,60859,60877,49013,N,N,N,N,N,N,N,61539,N, +N,61537,61543,49840,61541,61540,49842,61546,49841,N,61547,61544,49838,61545, +61538,49839,49837,62123,61542,N,N,61548,N,N,62120,N,N,N,50098,50096,62122,N, +62124,62121,50097,50094,50095,50099,N,N,50296,N,62634,N,62633,62631,62630, +62632,N,50295,50297,N,N,50416,N,N,62949,62948,N,N,63226,N,63228,63230,63229, +63227,N,N,50595,50594,N,N,50643,50642,50644,63469,63468,N,63739,63672,63740, +50776,N,50777,63853,N,N,50814,42700,N,52648,N,N,53317,53318,53316,N,N,44275,N, +53319,53320,53321,N,N,54089,54095,N,N,54093,44987,54091,N,54092,54094,N,N,N, +54090,45769,N,55006,45771,55008,45770,55007,N,N,N,N,N,56040,46511,N,56042, +56039,55009,N,46512,N,N,56041,N,N,N,N,N,N,57174,N,47204,57172,47205,57173, +47206,N,N,N,47849,58209,58206,58208,47850,47851,58207,N,N,N,N,N,59103,N,N, +59104,N,48491,59106,59105,N,41569,N,60106,60107,60103,N,60104,49020,49021, +60105,N,49495,N,N,49491,49496,49492,49494,49490,N,49493,N,N,N,N,49843,60879,N, +62126,N,62125,N,62635,50298,50299,63297,62950,N,63296,N,63741,63908,42701,N,N, +43124,N,52649,43720,44278,53324,44276,53322,44281,44277,44282,44280,53323, +44279,44991,44990,54106,44999,54099,54105,44995,54098,54104,54102,44994,44996, +54101,44989,54100,45000,44997,45001,44998,54097,54096,54103,44992,44988,44993, +N,N,N,N,N,55024,55017,N,46517,55016,N,45775,45782,45779,45785,45784,45780,N, +55010,55013,N,55012,45776,55014,55023,45777,55011,55020,55021,45778,55018, +45783,45773,45781,55015,45772,55019,N,N,55022,N,N,N,56059,56050,46514,56057, +56054,56046,56055,46516,56047,N,56043,N,N,47212,56052,N,46513,56058,N,46520, +46522,56045,N,N,46521,56048,46515,56056,56049,56053,N,56051,46518,56044,46523, +45774,46519,46524,N,N,N,N,N,47208,57181,57183,57185,57189,N,57179,57177,47210, +N,57184,57188,57180,57176,N,57175,N,N,N,57186,57178,57182,47211,N,47209,57190, +47207,57187,N,58226,N,N,N,N,N,47854,58218,48504,58228,47857,58232,47863,58213, +N,N,58229,58210,N,58231,58214,N,47870,47867,58230,58224,47853,47861,47860,N, +47859,47865,N,58211,47866,58225,47862,47852,58227,47855,47856,47864,58216, +58215,58212,N,58220,58217,58221,47869,N,58233,47858,58222,58223,N,58219,N,N,N, +47868,N,N,N,N,59111,48496,48505,48501,59108,N,48498,48502,59120,48492,59112,N, +48500,N,N,59115,59110,48499,48503,59109,N,48497,N,59119,48494,59118,59117, +48506,58738,48493,N,59116,59107,N,48507,59114,48495,59113,N,N,N,N,49058,49063, +49022,60120,60111,60123,60115,60121,49064,49057,60108,60114,60124,60117,60122, +60110,N,N,60118,49059,60116,49062,49061,60112,60113,60109,60119,49060,60126, +60125,N,N,N,60890,60886,49503,N,60880,49497,49513,60892,49505,49501,60883, +49508,49511,60894,49500,60885,49509,60896,60893,60881,49504,49498,49512,60888, +49507,60882,49502,60895,49506,49499,60889,49510,60887,N,N,60891,N,N,N,61550, +61556,49849,61559,49844,49845,61551,61558,61553,49850,49847,N,61549,N,49846, +61555,61557,49848,61554,61552,N,N,N,N,62136,50103,50104,50100,N,50101,N,62132, +62130,N,62134,50106,62135,62128,62127,62131,62129,50102,62133,62636,50302, +50301,62637,N,62639,62638,50337,N,N,N,62955,62952,62953,N,62951,62954,50418, +62956,N,50417,N,63298,N,50645,50647,63470,50646,63673,63808,63810,63742,63809, +50796,42702,N,44283,53871,45002,N,N,45786,56060,56061,N,N,N,60127,49514,60897, +N,N,49851,N,62138,62137,50338,62957,N,63299,50680,51785,N,N,43721,43125,N,N, +53325,N,N,54112,54107,54111,54109,45003,54110,54108,N,55025,N,56062,56128, +57193,57194,47214,47215,57192,57195,57191,47213,N,47936,N,47216,58234,N,48508, +59121,48509,N,49065,60130,60128,60129,60900,60899,60898,N,N,N,62139,N,50105, +62140,63300,50681,63674,42703,43723,43722,53327,44284,N,N,53326,54114,N,45004, +55026,54113,N,N,N,45788,55029,55027,55028,45787,N,56130,56131,56129,N,47219, +57197,57196,57198,47218,47217,N,N,59122,59124,N,48510,59123,60131,49066,61561, +N,61560,50107,62141,50109,50108,62640,62958,50419,42704,53328,44285,54117, +45006,54116,54115,N,45005,N,55035,N,55037,55030,55031,45789,55032,45790,55036, +55033,55034,45791,N,46526,46527,N,56132,N,N,N,57199,57200,N,58238,47939,47937, +47938,58235,58236,N,58237,59129,N,59130,48545,59127,59126,59128,59125,49069, +60132,49067,49068,60902,49515,60901,61352,N,61562,61563,49852,N,49853,49516, +62142,62143,62641,50339,42705,N,42706,44286,43724,45007,53329,N,N,N,46528, +42707,44353,53330,53331,44352,44354,42708,N,53332,45009,54118,45011,45008, +45010,N,55105,45792,N,55104,55038,N,57201,N,N,58273,N,48546,N,49070,60134, +60133,N,60903,N,N,N,62959,N,N,42709,52083,52650,44355,53333,N,54120,N,N,N, +45012,54119,45013,N,N,N,55107,N,N,45794,55106,55108,N,45793,N,N,N,N,56134, +56135,56133,46529,N,N,N,47220,N,47221,N,47941,N,58275,58274,47940,N,N,N,N,N, +59131,N,N,59132,N,N,N,N,60135,N,N,49520,49519,49517,49518,49521,N,61564,49855, +49854,62144,62642,N,N,N,50597,50596,42710,N,N,53755,N,47223,46530,47222,47942, +N,42711,51625,42712,42713,N,N,52651,52086,N,52087,43127,N,52084,43126,N,43129, +52085,43131,43130,52088,43128,N,N,N,43729,43727,52653,N,43726,N,N,N,43731, +43733,43730,N,52656,52652,43734,N,43728,43132,N,43732,52655,N,N,52654,N,43725, +N,N,N,N,N,N,N,53339,44359,44360,53341,N,53335,53338,53347,53345,N,44361,53351, +44364,53348,53340,53337,N,N,56137,53346,44356,53349,53334,53343,44358,44363, +53344,44367,44365,N,53336,44362,N,53342,44366,44357,53350,N,N,N,N,N,N,45018,N, +45027,45016,45014,54122,45022,45019,54124,N,N,45021,54123,54121,54126,45026, +45024,56136,54127,54125,45015,N,N,45017,45020,N,45023,N,45025,N,N,N,N,N,N,N,N, +N,N,55118,45796,N,55109,55111,N,55112,N,55120,55116,55114,N,55117,55121,45797, +45801,55110,N,55119,N,45799,N,45798,55115,55113,N,45795,45800,N,N,N,N,N,N,N,N, +46536,56145,N,N,56143,46538,N,N,N,N,56138,57249,N,46537,56142,N,N,56139,46533, +46539,56144,46535,56141,47943,46534,56140,46540,46532,46531,N,N,N,N,N,57207, +57205,N,57211,N,57203,57250,57208,N,57202,47227,47267,57213,N,57206,N,47230,N, +N,47228,57214,47225,47224,57209,47229,46541,N,57212,57204,47226,47265,47266,N, +N,N,N,47948,47944,N,47949,58278,N,N,58277,58279,47946,58276,47947,58282,58281, +58280,N,47945,N,N,N,N,N,59201,N,59204,48552,59203,48551,48547,48548,48549, +59200,59134,48550,N,59202,59133,N,N,60137,60147,49073,49072,N,60141,60143,N, +60138,N,60142,60136,60145,49071,60144,60140,N,60146,N,60139,49524,60904,60910, +49528,49530,49527,49526,N,49525,49523,60905,60908,49522,60909,N,49529,60907,N, +60906,49856,N,49857,61601,61565,61566,N,N,62146,N,62145,50110,62644,50340, +62643,N,62960,63301,50598,63811,63812,50648,42714,N,43735,56146,47950,49531, +60911,42715,N,45029,45028,56147,N,N,N,60148,42716,44368,N,N,56148,56149,56150, +47951,49074,42717,N,43736,53352,45030,54128,45802,N,56151,47268,N,47952,49075, +49532,49858,62645,42718,43737,N,N,45031,55122,46542,N,47953,58283,59205,N,N,N, +N,42719,46543,57251,47954,42720,52657,53353,44369,N,N,54130,N,N,45034,N,45032, +45033,45035,N,N,54129,N,N,55127,55124,55126,45803,45805,45804,55123,45806, +55125,N,56152,56153,N,56154,57254,N,57255,N,57253,57256,N,47269,N,57252,N, +47955,N,N,59210,59206,59209,59211,59208,59207,N,60149,60150,60151,49076,49077, +60913,60912,60914,N,61603,61602,N,62148,N,62149,62147,N,50341,N,62646,62647,N, +63302,63471,63675,42721,43133,N,49533,42722,N,55128,56155,N,50753,51786,N,N,N, +51787,51789,42723,51790,51788,N,N,52130,52131,52091,N,N,N,N,52129,43169,N, +43170,52092,52090,52089,52093,43134,52094,53354,N,N,N,52662,43740,52661,52663, +N,43739,52668,43743,52658,52672,52678,43750,52675,43747,N,52665,52671,52673,N, +52660,43746,43741,52666,43748,43751,43745,N,43738,52670,52664,52677,43753, +43749,43744,52669,45036,52667,43742,43752,N,52659,N,52674,52676,N,N,N,N,N,N,N, +N,N,N,N,N,N,44386,44380,44388,44385,53361,53364,44381,N,53355,N,44374,44384,N, +44387,44389,53410,53367,N,44373,53409,44377,44375,44370,53359,N,53374,53363, +53366,53413,N,44390,53373,44382,53368,53412,53365,53369,53372,N,N,53357,53411, +53371,N,N,53356,53360,44383,44378,44371,44376,44372,44391,53358,54181,44379,N, +N,53370,52801,N,N,N,N,N,N,N,N,54184,45050,N,54134,N,54179,54141,N,54194,N, +54186,N,54142,N,54185,54136,54140,54197,45053,54189,54180,45037,54195,54132,N, +54188,N,45052,45047,54131,45045,45044,45049,54187,45041,45048,53362,56156, +54182,N,N,54138,45051,54139,54177,45054,54133,54191,N,54190,54198,45043,45040, +54196,54192,54183,54178,45046,45042,54135,45038,54193,45039,N,54137,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,55134,55136,55141,55161,45820, +45810,N,55133,45821,45822,55144,55151,55157,N,55138,N,55145,N,N,45888,55159, +55154,45818,45816,55150,55146,55132,45807,55137,55129,N,45815,45817,55142, +55139,45812,55155,45809,55140,55162,55148,N,55147,45808,N,45819,N,45811,55130, +55135,55152,55158,45889,55131,55143,55149,45814,N,N,55160,55153,55156,N,N,N,N, +N,N,N,N,N,N,N,N,45813,N,56172,56160,46551,56189,56231,56234,46549,56168,56227, +56169,56183,46562,56179,46559,N,56180,56157,N,56228,N,N,46568,56225,56181, +56236,56176,57288,N,56239,46566,56174,56186,46569,46548,56178,56237,56171, +56164,56175,N,56163,56161,46544,56229,56170,56232,N,56233,46552,46557,46553, +46561,56190,46554,56182,56166,N,46546,56158,56226,56235,56165,46560,56240, +56177,56173,N,46545,46565,N,56188,46567,N,56184,46556,46550,46558,46547,46564, +56185,56167,56187,56162,56230,N,N,N,N,N,N,N,56238,N,N,N,N,N,N,N,56159,N,N,N,N, +N,57287,N,57309,47189,57292,N,57290,57269,47273,57285,57305,57281,47281,57304, +57279,46563,57295,57280,57302,47280,47272,N,57258,57266,N,57291,57283,57308, +57286,47286,57303,N,47277,N,57289,57297,57270,57296,N,57313,57265,57298,N, +57311,N,57259,46555,N,57273,57272,47279,N,57276,57278,57293,57310,47282,N, +47283,N,57264,47275,57268,57306,47284,N,47276,47278,47285,57312,57299,57294,N, +N,57275,57274,47274,57260,47271,57284,57261,57282,N,N,57271,57307,N,N,N,47270, +N,N,N,57267,N,N,N,N,N,N,57263,57301,57262,47968,58323,N,N,58306,N,N,58284, +58314,47960,58299,58309,47963,58302,47961,58287,58317,58286,58305,N,58285,N,N, +58303,58312,58310,58298,58293,58291,N,58292,58311,58322,58300,47962,N,58295,N, +58315,N,47965,58294,58288,58304,47969,N,N,47957,47966,58296,58290,N,47959, +57300,47958,58307,N,47956,47971,47964,58308,58297,58289,58316,58301,47970, +58320,47967,58319,N,58313,58318,N,N,N,58321,N,N,N,N,N,N,N,N,N,N,N,59251,59252, +59239,59238,59234,48564,N,48556,59254,59253,57257,59231,59235,59229,N,59248, +59233,N,59255,59226,59224,59236,59246,59241,48566,59215,N,59245,N,N,N,48567, +57277,59227,59218,59221,59259,59228,59219,59217,59214,N,48560,59237,48559, +48563,59232,59240,48553,59256,59260,48555,N,59223,59243,59247,59220,59257, +48562,N,48561,59212,48565,59250,59222,59242,59216,59230,59225,48557,48558, +59244,59261,59258,59249,N,N,N,N,N,N,N,N,N,59213,N,48554,60233,N,60224,60227,N, +49083,60229,60153,60225,60231,49080,49084,49078,N,N,60155,60236,N,N,60230,N, +60156,60245,60239,60152,60998,60158,49079,N,60234,N,60244,49087,N,60241,60157, +60228,60232,60226,60246,60243,60240,49081,49082,49086,60154,60247,49085,60237, +N,N,60235,N,N,N,60238,61011,60992,60997,61010,60996,60923,60993,N,49570,N, +60916,61005,61007,60915,49569,61009,61001,49576,61008,60994,49578,60921,60242, +61002,60999,60917,61013,49572,N,N,49573,60919,61000,N,61012,61003,60925,49575, +49571,61004,60926,61014,60920,60995,61006,60922,60924,N,49867,60918,49577, +49860,49534,N,N,N,N,49574,49864,61619,N,61609,61604,61610,61620,61624,61623, +49866,49865,N,N,61611,61625,61614,61606,N,61608,61607,61613,61618,61605,61612, +61617,49863,N,61615,N,49861,61616,49859,49862,62165,61621,N,N,50114,N,62157, +62161,62153,62156,N,62164,50112,62169,62162,N,62154,62170,62163,50115,50116, +62167,N,62155,50111,50113,62150,62158,62152,N,62168,62166,62151,62159,N,N,N, +62654,50117,62160,50343,50345,50342,N,62659,62651,62649,62653,62650,N,N,62655, +62657,50346,50348,N,62656,50349,50347,62658,N,N,N,N,50344,N,N,N,N,N,50420, +62961,62967,50422,62652,62966,N,62973,62964,62971,62970,62648,62965,61622, +62974,62963,62968,N,62972,62962,N,63306,50421,62969,N,N,63476,63307,63305, +63303,63304,63308,N,50649,63474,63472,63477,63475,N,63478,50650,63473,N,N, +63676,N,N,63813,63814,63815,N,N,63943,63933,51791,43754,N,44392,N,54200,54199, +45120,45890,55164,N,N,55163,N,46570,47288,N,47287,47289,N,58324,59262,60248, +60250,60249,N,49579,61015,61626,63909,42724,N,52681,52682,52680,52679,43755,N, +53417,53415,N,N,53414,N,44393,44395,44394,53416,N,N,N,N,N,N,N,N,54212,54209, +54207,N,N,45121,54210,45126,54204,54219,N,54221,54205,N,45123,54222,54217, +54203,54208,54218,54214,54211,N,45128,54220,54206,N,N,54215,54201,45127,45124, +54213,N,54216,54202,45125,45122,N,N,N,N,45900,55205,45899,N,55208,55211,45896, +45894,55166,55209,55207,55204,55212,55213,55215,55216,55165,45893,55202,55201, +55214,45895,55203,45897,45892,55206,45901,N,45898,55210,N,N,N,46577,56255,N, +56244,46574,N,57319,56253,56241,46572,56246,46575,56250,56248,46578,46571,N,N, +56242,56245,46576,N,56243,N,56254,56252,56247,56249,56251,46573,N,N,N,N,N,N,N, +57320,57326,57316,57322,47290,57318,47296,N,N,47295,47294,57325,47297,47298, +57315,57328,47299,47293,47292,57324,47300,57314,57317,57327,57323,N,N,58356, +58345,47291,N,N,N,N,47978,58333,58354,58334,47973,N,58331,N,58340,58332,47975, +58326,58353,47976,58350,58351,58327,47981,58342,N,58336,58343,58330,N,58355, +58347,58341,58325,47977,58348,N,47980,58352,N,58346,47974,58344,N,58338,47972, +58329,58337,58349,58335,N,N,58339,N,N,N,N,N,48577,57321,59314,59323,59313, +59309,59306,48578,59304,47979,59297,48576,59303,48575,59308,59305,59321,59316, +59310,59315,48571,59307,59326,59298,59299,59322,48572,59327,48574,59328,59312, +58328,59318,59311,59320,59317,N,N,N,59302,48569,59325,48570,59300,48573,60260, +59319,59324,N,N,N,N,N,60257,48568,49088,60267,60263,N,60261,60256,60271,N,N,N, +49092,N,60252,60264,60265,60255,60254,60268,N,60258,60253,60259,N,60270,60251, +60269,60266,49090,49089,N,N,49091,60262,61643,N,N,N,N,N,61017,49585,61021, +61018,61025,61031,61020,N,61040,49582,61034,61023,61035,61030,61037,61022, +49587,49586,61024,61038,61016,61036,49580,N,61028,61027,61032,61019,49584,N, +49588,61026,61033,49589,61029,N,N,N,N,49581,49583,61639,61637,N,N,61644,61641, +61645,N,61630,61638,61649,61039,61634,49871,59301,61629,61642,61636,61633, +61628,61627,61648,N,61632,61631,49869,61640,N,49868,N,N,49870,61635,61647,N, +62174,62175,N,50121,62172,50118,62180,N,50122,62182,62171,61646,62184,62173,N, +50119,62179,N,62181,62176,62183,62178,62177,50120,N,N,62661,62662,N,62664, +50350,50351,62665,62663,N,62660,N,63042,63045,63041,N,50426,63043,50425,50424, +50423,63044,63313,63311,N,63310,63040,63312,63046,63309,N,63481,63447,63479, +50651,63480,63482,N,63679,50682,63678,63677,50683,N,50778,63854,63911,63910, +63912,42725,53418,N,54223,54224,N,N,N,56256,N,63047,63680,42726,44396,53419,N, +N,N,55217,45902,N,56258,56257,46579,N,47301,59329,48579,N,48580,N,N,N,49093, +50684,42727,N,N,N,53420,43757,53422,53421,44397,N,54225,N,54232,45129,54230, +54228,N,54235,54226,54227,45130,N,45134,N,N,54236,45133,54234,54231,54229, +45131,45132,54233,N,N,N,N,45904,55218,N,45909,55234,45908,55236,N,N,55224, +45906,55235,N,55219,45907,55231,55227,55229,55223,55230,N,N,45903,55226,N, +55225,55221,N,55232,N,N,55228,55220,N,55222,45905,55233,N,N,N,N,46582,56269,N, +N,N,56265,56267,56262,56261,56259,N,56266,56268,56264,N,56263,46580,46581,N,N, +N,N,N,N,56271,47309,57330,57336,57331,57332,N,57337,N,47311,N,47303,47310, +57329,56260,47306,47304,57335,57334,47305,47307,57333,47302,N,47308,N,N,N,N,N, +58358,47988,N,N,58434,58433,N,58363,47990,58432,58359,58360,47982,47984,N, +58365,58357,47986,47985,58361,58366,58364,47987,58362,56270,47983,N,N,59330, +59337,48582,N,59341,48586,59333,59331,N,59340,N,48581,59339,48583,48584,59332, +48585,59338,59334,59335,59336,47989,N,N,N,60272,60284,N,49098,60279,60281,N, +49096,60273,60277,N,60280,49094,49097,60283,60275,60276,60282,60274,60278, +49095,61042,N,61041,49591,61047,49593,N,N,49590,61043,49594,61044,N,N,61045, +61048,N,49592,N,61654,N,N,61657,N,61651,61653,N,N,61652,61655,61656,61046, +61650,N,N,50125,62188,62191,62193,62186,62187,62190,62192,50126,50124,50123, +62189,62185,62666,50352,N,62667,N,N,63049,50427,63051,50428,63048,63050,50600, +N,63314,50599,63485,63484,N,63483,N,N,63816,63817,63819,63818,N,51792,42728,N, +44398,55237,46583,N,57338,49872,N,62194,N,N,43171,N,N,N,45911,N,N,N,45910,N, +56272,46584,56274,56273,N,N,57339,47312,58435,58438,58437,N,58436,59342,59344, +59343,N,49100,N,N,N,49099,N,49595,61049,61051,61050,N,N,49873,N,N,N,62196, +62195,N,62668,50353,N,N,50429,63316,63315,50779,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,43172,53423,44399,55240,55238,N,N,55239,56276,56277,57411,56275,N,57340, +57409,57408,57410,47313,57342,57341,57412,N,58441,58439,N,58440,59347,59345,N, +N,59346,60285,61052,61053,49874,N,62197,62669,50354,N,63052,63317,50601,N, +63486,63820,43173,N,44401,44402,53424,N,N,53425,44400,N,45140,N,45138,N,45137, +45144,45136,45145,54237,45142,N,45139,45143,45141,45135,N,N,45919,N,45913, +55244,45918,N,N,45920,45914,N,45915,N,55242,N,N,45912,N,55243,45917,N,N,55241, +45916,N,N,46660,N,46662,N,N,56280,46661,46585,46589,N,47332,57417,56282,46590, +N,N,56285,56286,46659,N,56288,N,56290,N,56291,56279,56278,56292,46658,56289, +56287,N,46656,46587,46663,56283,56284,56281,N,46657,N,N,46588,N,46586,57416, +47327,47322,N,N,47317,N,47333,47318,N,47314,47329,47326,47328,N,47319,47324, +47315,47316,57424,57421,57413,57418,N,47330,57425,47331,47321,N,N,57415,N, +57423,57419,57422,57420,47325,57414,47320,N,N,N,58444,47992,47995,N,58446,N, +48037,58445,47997,N,48591,58447,N,48036,58443,48038,N,N,N,47993,N,47323,47996, +N,47994,47998,48034,47991,48039,48035,N,48033,58442,N,N,N,N,48598,N,48594,N,N, +N,48601,N,59350,48602,59362,59355,48587,59363,59357,48597,59358,N,48596,59361, +48590,59359,59349,48589,60330,48595,N,48592,N,48600,N,59348,N,59352,48588, +59351,59353,59354,48599,59356,59360,59364,N,48603,49106,60325,60331,60328, +60286,60332,60321,N,60327,N,49101,49107,60333,N,N,49103,N,49113,49108,60335, +60329,49104,60322,49114,60323,60324,49115,49112,48593,N,49102,60336,49116,N, +49109,60334,49105,49110,49111,N,49603,61092,61101,61098,61100,N,49600,61093,N, +61099,49596,61095,49604,61091,61096,61103,60326,61097,61090,49597,61089,49598, +61104,49599,61102,49602,61054,N,49601,N,61094,61660,61674,61669,61671,61659, +49875,N,61658,49878,49877,N,61673,61665,61662,61668,N,61661,N,61663,61672, +61670,N,49876,61677,61675,61666,61676,61667,N,62201,50127,62273,N,N,63055, +50134,61664,62199,50130,62200,62205,N,N,50132,50133,62198,62272,62274,62202, +62204,62206,62203,62275,50129,50135,50131,N,50128,62672,N,50359,62670,N,N, +62674,N,62675,50357,62676,62673,N,62671,50360,50356,62677,N,50358,50355,N,N,N, +50430,N,N,50496,63054,63053,63056,63057,N,50497,63318,63323,50602,N,63320,N, +63319,63322,63321,N,63555,N,50652,63554,63552,N,63553,N,N,N,50686,50685,63681, +63682,50752,N,63821,63822,50791,N,50797,N,63913,63944,43174,N,55245,N,55246, +57426,58448,59365,49606,N,49605,61678,62276,N,63556,43175,54238,45146,45921, +57428,57427,48604,59366,48605,61105,49879,N,N,N,50806,43176,52683,54239,N,N, +45922,N,55247,55248,N,56293,N,46664,47334,N,57430,57429,57431,N,58449,58450, +48040,49117,48606,49118,N,61109,61106,61108,61107,49607,N,61679,62278,62277, +52132,45148,45147,54240,N,55249,N,N,56295,56294,46665,N,57433,57434,57432,N,N, +47336,47335,N,48042,48041,N,59367,60339,60337,60338,49119,61111,61110,N,61682, +61681,61680,62279,N,63914,43177,44403,N,44404,45149,45150,54242,54241,55250,N, +45928,45926,45923,45927,45925,45924,N,N,46666,56298,N,47341,46668,46673,56300, +46675,46674,46677,56299,56296,46671,46667,46669,56297,46676,46672,46670,47343, +47342,47340,47344,N,47338,47339,N,47337,N,57435,N,N,58452,N,48044,48045,48043, +N,58451,N,58453,N,59370,59372,N,48615,59373,48608,59369,48607,48617,48613, +48614,48610,59368,48609,59374,59371,N,48616,N,48611,48612,60341,N,60343,60342, +N,60344,49120,60340,N,N,49611,61112,49608,49612,49610,49609,61683,61686,N, +61685,N,61684,49880,62280,62281,50136,62282,50137,N,N,50362,N,50361,63058,N,N, +50498,63059,63324,50603,50604,N,63557,N,50754,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43178,N,45930,45929,57436,57437,N,48046, +60345,48618,60346,61113,43179,N,53426,44406,44405,N,54243,45151,54244,55253,N, +55252,N,55251,N,N,56302,46680,N,N,56301,46679,N,N,N,56303,46678,N,57439,57442, +57440,57441,57445,57438,57446,57443,57444,48048,58454,N,N,48047,N,59378,59376, +N,N,48619,59375,59377,N,48620,N,60347,N,60348,49613,N,62284,62286,62283,62285, +62678,63060,N,N,63855,43180,44407,54245,54247,54246,N,55256,45932,N,55254,N, +45931,55257,N,55258,55255,N,N,56315,46688,56307,56313,N,N,46683,46686,56306, +46681,56310,57452,46685,N,56305,N,56311,56308,56314,56304,56312,46684,46687, +56309,46682,N,47346,57448,47345,57455,57454,47352,N,47353,57456,47347,57453, +47351,57458,57449,N,57451,47348,57447,57450,57457,47349,57459,N,N,N,N,N,47350, +N,48049,58459,58465,58457,58466,N,58456,58461,58467,58464,58463,58462,N,58455, +58460,N,N,58458,N,48625,48622,59387,59457,59459,59456,59384,59386,59461,59458, +59388,59462,59385,59460,48623,48629,48627,59379,48628,48624,59380,59382,59381, +59389,59390,N,48626,N,48621,N,N,59383,N,60358,49122,N,60349,49123,49126,60354, +N,60351,49125,N,N,60355,60356,60350,60359,60352,60357,49124,N,49121,60353,N, +61119,49616,49614,49617,49615,61118,61115,61114,N,61117,N,N,61116,61765,49886, +61691,61690,N,49881,61761,61760,61687,61763,61692,49885,61689,61762,61688, +49882,49884,61693,49883,61694,N,61764,62290,N,50142,62287,N,62291,N,N,50139, +62289,50144,N,50141,N,62288,N,50143,62292,50138,N,N,N,N,50364,50366,N,62681, +50365,62679,50140,62680,50363,50499,50501,63062,50500,63061,N,63329,50605, +63328,50606,63326,63325,63330,63331,63558,N,63327,N,N,63686,63683,63684,63685, +50780,N,63825,63824,63823,63856,N,63934,63915,50798,43181,45152,N,N,N,N,N, +47354,N,N,N,N,N,N,N,48630,N,N,60360,N,N,49887,N,62293,N,N,N,N,N,N,63916,43182, +43758,44409,44408,N,45155,N,54248,45153,54249,45154,N,N,55263,55259,N,N,45933, +55262,55261,55260,45934,55264,55265,N,N,N,56387,56385,56389,56390,56396,N, +56392,56394,N,56386,56316,N,56393,N,N,56395,56388,56391,56317,46690,56384, +56318,46689,46691,N,47357,57461,57463,57462,57467,47355,N,57464,57460,57465, +57466,47356,47358,57468,N,58471,58470,N,58468,58469,48051,48053,48050,48052, +59469,59470,59465,N,59466,48632,48637,48631,48638,48633,59467,N,N,59468,59464, +48704,48635,N,N,48634,48636,N,59463,N,60362,49128,N,N,60364,49130,60367,60363, +60361,60366,49129,60365,N,49127,N,N,49619,49622,61121,N,49620,61120,49618, +49621,61766,61767,61768,49888,N,61769,N,49889,50146,62296,62297,62295,62294, +62298,50145,62685,62683,62684,62686,62682,62687,63064,N,63065,63063,50502, +63332,50607,63333,63560,63559,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,43183,46692,N,N, +47424,N,N,N,48054,N,N,49132,N,49131,N,N,N,N,50147,50300,50503,43184,45156, +47425,N,62299,N,N,N,N,N,N,N,N,N,N,52134,N,N,43185,N,43188,43187,43186,N,N, +52133,N,52685,N,52687,43759,N,N,43761,52684,52686,43760,52689,52688,52690,N,N, +N,N,N,N,N,N,53430,53428,44412,53427,44451,44414,44411,N,44452,N,44413,44450,N, +44449,53429,N,44410,N,N,N,45162,54251,54257,45159,45166,N,45161,54254,54256, +45164,54250,54253,45160,45157,54252,45163,54255,45165,45158,N,N,N,N,55267, +55270,45936,N,45946,45942,55268,N,N,45950,45943,45948,45938,N,45935,45937, +45949,55269,45941,45944,45940,45945,55271,45947,45939,55266,N,N,N,N,N,N,N,N, +56397,46693,56399,N,46695,46697,N,56398,46694,46698,N,46696,N,N,N,47431,57507, +47439,57470,N,47440,47429,N,57505,N,N,47434,N,57506,47427,47426,N,47437,47436, +47435,47433,47438,57469,47428,47430,47432,N,N,48056,48059,N,48063,48057,48062, +48060,N,48055,N,48061,48058,N,N,N,59474,48707,48705,N,59475,N,48708,48706, +59473,59472,N,49136,59471,49134,49133,60368,48709,49135,60369,49138,60370, +49137,49624,61123,49623,49628,49626,49627,49891,49625,61122,60371,49890,49892, +N,50148,50149,N,62688,N,50654,50653,43190,N,N,51797,45167,N,51794,51795,51793, +N,51796,N,N,52138,52135,52140,52136,43191,43194,N,52137,43193,52139,N,N,43192, +N,N,N,N,52693,52695,43764,52691,52694,52692,43762,43765,N,43763,N,N,N,N,53432, +53436,53433,N,44455,N,44456,N,53435,N,53437,53439,N,44453,53438,N,N,44454,N,N, +N,N,N,55278,53434,54258,54267,54265,54260,54261,54266,54268,45169,N,54263, +54259,45168,45170,54262,54269,54264,N,N,45985,55281,55273,55279,55280,45986,N, +55272,55274,53431,55276,55277,55275,46700,N,N,N,56406,60372,56407,56404,45987, +46702,56403,56409,56408,46699,56412,56402,56411,56400,56410,56405,46701,N, +57514,N,57509,57515,57510,57508,57511,47441,N,57513,N,57512,47442,48065,48064, +58478,58481,58473,58477,48066,58476,58474,58480,58475,58472,58479,N,59481, +48712,61770,59478,59479,59477,56401,48711,59482,59476,48710,48713,59480,60373, +49139,60374,60375,N,61124,49629,61771,61772,N,N,61773,62301,62300,62690,N, +62689,63067,63068,63066,63334,50608,43195,44458,44457,45173,45172,54336,54337, +54270,N,45171,55285,N,55286,55282,45988,55283,N,55284,N,N,N,N,56415,56417, +56413,56416,46703,56414,46704,N,N,56691,47445,47444,N,47443,N,57516,57517,N,N, +58483,58485,48070,48067,N,48069,48068,58484,58482,N,N,N,N,N,59489,59486,59487, +48717,59488,59483,59484,48714,N,48715,59485,48716,N,60379,N,60380,60377,60378, +49140,60376,N,N,N,N,N,61128,61125,61127,49632,61131,49631,61129,61132,61130, +61126,49630,N,61775,N,61776,61774,N,61778,49893,49894,62303,50151,61777,62302, +50150,62693,62694,50367,62692,N,62691,N,63069,50504,N,63561,63688,63687,N, +50755,50781,63689,63857,N,50799,43196,43766,N,47446,N,50368,43197,44459,45989, +46705,49895,43767,N,53441,53440,54338,N,45176,45174,45178,54340,N,45177,45175, +N,N,N,N,54339,45992,55292,N,45991,45993,55362,45995,55294,55360,55287,45994, +55363,N,N,55289,N,55290,55288,45990,N,55361,55291,55293,N,N,N,56429,N,56428, +56426,56418,56433,56421,56431,56438,56430,46713,N,46709,56419,N,56425,46711,N, +56424,46712,46714,56427,N,46706,46707,56439,56437,N,56436,56422,N,56434,N, +46710,N,N,N,N,46708,56435,56420,56423,56432,N,N,N,N,N,58554,57527,N,57520, +57539,57548,57523,47457,N,57536,47447,47449,47461,57521,N,N,47450,47452,47462, +47451,N,N,N,N,47460,57529,N,57518,47458,57528,47454,57546,47459,57544,57532, +57542,47456,57519,57545,57540,N,57547,47448,N,N,47463,47453,N,N,57525,N,57533, +57537,N,57541,47455,57524,57522,57534,N,N,N,N,57531,57530,N,57535,57538,N, +57543,N,N,N,58488,N,48071,58532,58490,48076,48080,58541,58549,58534,48072,N, +58538,57526,N,48073,58545,58550,58542,N,58544,58553,58546,58494,58537,N,N, +48081,N,48077,58492,58539,48075,58533,48074,58547,58530,58489,48078,58552,N,N, +58491,58543,58540,58535,58487,58486,58529,58548,48079,58551,58493,58531,48722, +N,N,N,N,N,48730,48725,59556,59553,59495,48720,N,N,N,48719,48726,N,N,N,59493, +48724,59505,59491,59492,48718,59555,48728,59508,59513,59507,60398,59503,59511, +59509,59496,59490,59517,48727,59518,N,59512,N,59501,59499,59494,N,N,N,59502, +59515,59498,59514,59554,N,N,48723,N,59510,59516,59506,59500,48721,N,N,N,58536, +59504,48729,59497,N,N,N,N,N,60404,49143,60403,60400,60484,49147,N,60481,60408, +60483,60393,60406,N,49149,N,60385,N,60383,60482,N,60480,60414,60397,60396, +60386,49216,N,60392,60402,60413,49219,60485,N,49640,49221,49150,60390,N,60399, +60382,60384,49141,49218,49146,60391,60407,60401,49217,60381,49635,60409,60412, +49148,N,60395,49220,49145,N,N,N,49144,60405,60411,49142,N,60388,60410,N,N, +60389,N,N,N,N,N,N,N,N,N,60394,61138,N,61143,49637,49639,61149,49633,61164, +61155,61144,61145,61154,N,49646,61153,61137,61152,61140,61165,49645,49643, +61141,N,61160,N,61146,61159,N,61161,61136,49638,N,61162,N,N,61150,N,49642, +61147,N,N,49644,61156,N,N,N,49636,61142,61157,N,61151,60387,61158,61139,N, +49641,N,61163,N,49634,61134,N,N,N,N,61792,61785,49897,N,61780,61795,61787, +61148,N,61797,61781,N,49896,61791,49898,49906,49904,61793,49905,61783,N,61784, +61789,61794,N,61133,49899,61802,61799,61803,61790,61786,61800,62314,61788,N, +49902,N,49901,61135,49903,61796,61798,49900,61801,61779,N,61782,N,N,N,N,N,N,N, +N,62323,N,62307,50155,62321,N,N,62305,50156,N,62316,N,62312,50161,62322,62306, +62309,50153,62324,N,62317,62320,50159,50164,50162,62313,62308,N,50157,50158, +62304,50154,N,50152,50160,62319,50163,N,62315,62325,50165,N,N,N,62311,N,62318, +N,N,N,N,N,N,62707,62786,62709,62716,62310,62714,62697,62784,50371,62701,62718, +62708,N,N,50370,N,N,62788,62710,N,62715,62717,62695,62785,62706,62711,62699, +62703,62787,62713,62696,62700,62702,62712,N,50369,62705,N,N,N,N,N,N,62698,N,N, +N,N,N,N,N,62704,63073,63078,50511,63080,N,50505,N,63076,63082,50510,50506,N, +50507,63072,63079,50509,63077,50508,63071,63075,63074,N,63070,63081,N,N,N, +50609,63341,63344,63340,63342,63343,63337,63338,63335,N,N,63339,63336,50610, +50611,N,N,63563,N,63565,N,N,N,N,N,63564,63566,N,50656,N,63562,50655,50657,N,N, +N,63691,63692,50756,63690,N,63827,63826,63828,50783,63829,50782,63830,63858, +63861,63860,50792,63859,N,N,N,50802,50800,50801,50807,63936,63937,63935,63945, +43768,N,N,55364,56440,59557,62326,N,N,43769,N,44460,45179,N,N,55365,N,55366, +45996,N,46717,56442,56441,46755,46716,56443,46718,46754,46753,46715,N,N,N, +47464,N,N,57552,57550,N,57551,57549,N,48082,N,48085,48087,48086,N,N,48083, +48084,N,59559,59558,48731,59560,N,59561,48732,N,N,N,60493,60491,61171,N,60489, +60490,49222,60486,60494,60488,60492,61167,N,N,61169,N,61170,49651,61166,49650, +61168,49647,49648,49649,60487,N,N,49909,61806,61804,61805,49907,49910,49908,N, +N,N,62327,62328,50166,N,62789,62791,62790,50372,50512,63085,63084,63083,43770, +N,51626,N,51800,42729,51798,51801,51799,N,N,N,52142,N,43201,N,43202,52144, +43199,52143,52141,43200,43198,N,N,N,N,N,N,52696,52699,43773,52698,52697,N, +43772,43771,N,43840,52700,43774,N,N,N,N,N,53446,44462,44463,44464,53447,53443, +44461,53444,N,53445,53442,N,N,N,45220,N,N,45217,54341,45218,45221,54342,N, +45182,45180,45181,45219,N,N,N,N,N,45997,55369,46005,55368,N,55371,46001,55370, +46763,45999,46002,45998,46003,46004,46000,N,N,N,55367,46759,56445,N,56483,N,N, +56482,46764,46760,46761,56444,56446,56481,46756,46758,N,46762,46757,N,N,57555, +57553,57554,47466,47467,N,57556,47465,48088,N,48090,48089,N,58555,N,N,58556, +59563,N,59562,N,N,49223,49224,60495,49225,N,61174,N,61172,N,61173,49652,N, +61807,50167,N,N,N,49653,43841,N,45222,54343,N,N,55372,46006,46765,56484,56486, +46767,46766,46768,46769,56485,47470,47471,47469,48091,47468,57557,N,N,N,48092, +59564,60496,49226,49654,61808,61812,49913,61809,49914,49912,61813,49915,61811, +N,62329,49911,50168,N,63693,N,N,43842,46008,46007,N,N,N,N,46770,56488,56487, +46771,N,N,57561,47475,47472,57560,47474,57558,47473,N,57559,N,58557,48093,N, +59567,N,48733,59565,48734,48735,59566,48736,N,60497,N,49230,49227,49232,60499, +49228,60498,49231,N,N,49229,N,61177,61179,N,N,49655,61178,49656,61176,61175,N, +61815,61814,49916,61816,62334,50170,62333,62330,50169,62331,62332,N,62792, +62793,50373,N,50515,N,N,63086,N,N,50513,50514,63087,N,N,50612,50613,63345,N,N, +50757,63695,50759,N,63694,63696,50758,63831,N,63917,N,N,N,N,N,N,43843,N,N,N, +47476,N,58558,N,59568,49233,49234,N,43844,N,48737,50171,44465,N,N,N,49235,N, +50658,44466,55373,N,56489,N,56491,N,56490,N,57565,57562,47477,N,47478,57563, +57564,N,58560,58565,48094,58559,58561,58568,58563,58567,58564,58562,58566, +48095,N,N,59571,N,59569,48739,N,48738,59570,48740,N,N,N,N,60502,N,N,60501, +49236,60500,61180,N,61182,61249,61248,N,49657,61181,61857,49917,61821,61858, +49918,N,61819,N,61822,61820,61817,49984,61818,N,N,N,N,62369,N,N,62371,62370,N, +62794,N,62795,N,N,N,63088,N,50615,N,50614,63567,63568,50760,63697,N,50793,N, +44467,46772,58570,58569,59573,59572,N,N,49658,61251,61250,61861,61859,61862, +61860,N,N,50172,62372,62373,62374,N,63089,N,63346,N,63698,N,N,N,N,N,N,N,44468, +N,N,60503,61252,N,44469,N,N,48096,N,60504,49985,61863,50173,N,62796,62797, +50516,63569,44470,46011,46012,55374,46773,46774,56492,46775,N,47482,N,47484, +57567,57568,57566,47479,47480,47483,47481,N,N,58571,48097,48098,N,N,59580, +48743,59575,59574,N,59579,48741,N,N,49243,N,59576,59581,59578,59577,N,48742,N, +49241,N,60506,49237,N,60507,N,N,60505,N,49240,49238,49242,N,49239,N,N,N,N,N, +61253,N,61258,61254,61257,49659,N,60884,61256,61255,N,49988,49986,49989,49987, +61864,61865,61866,49990,N,N,N,62378,50240,62376,N,50241,62375,62377,50174, +62801,62798,N,62799,62800,63090,50518,N,50517,N,63348,63347,50616,N,N,N,50659, +50761,50784,63832,63918,63919,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44471,56493,N,N,57569, +58572,58573,48099,N,48100,59582,48744,N,N,49660,N,61867,N,49991,62381,50242, +62380,62382,62379,63093,62802,62803,N,50374,N,63092,N,N,63091,N,63349,63920,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,44472,N,N,N,44473,N,N,45223,54344,N,55375,N,46776,N, +46779,46777,56494,N,46781,N,46778,N,N,46780,N,47486,N,57570,N,N,57571,59584,N, +47485,47521,47522,58575,N,58574,48101,N,48102,N,58576,59583,48104,48745,N, +48103,N,N,N,49244,59585,48747,48746,59586,59589,59587,59588,48748,N,49249, +49247,N,N,49246,60509,N,49248,N,N,60508,61259,N,60510,49245,60511,61262,61260, +61261,61266,49995,61265,61268,61267,61264,61263,N,49661,N,N,N,N,61870,N,61869, +49994,49992,49993,N,61868,N,62385,N,50243,N,62384,62383,50244,N,62808,62807,N, +62805,N,62804,50376,50375,62809,63350,50617,63095,50519,63094,62806,N,63351, +50660,N,50785,63833,N,63921,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,44474,55376,61269,44475, +N,N,58578,58577,60512,N,N,61271,N,61270,N,49996,62386,62387,50377,N,N,63922, +45224,46783,46782,57572,57574,47524,57573,47523,47525,57575,N,N,N,58580,58582, +58581,N,58584,N,N,N,48105,58583,58579,N,N,N,58585,N,59596,N,59599,59601,59591, +59595,59592,48750,48753,48755,59593,59594,48754,59597,59600,59598,48756,N, +48752,59590,48749,N,48751,N,N,49251,60518,60516,60515,N,60521,N,60520,60519,N, +60514,49250,60513,N,60517,49252,N,N,61274,N,61278,61275,61277,61276,61273, +61279,61282,61280,61281,49728,49662,61272,61283,61875,61878,61880,61879,N, +61873,61877,61872,N,61874,49997,61871,N,61876,N,N,62400,62389,50245,N,N,50246, +62388,62393,62399,62391,62398,N,62395,N,62394,62397,62392,62390,N,62396,N, +62816,62814,50378,62813,62819,62817,N,50379,62812,62810,N,62811,50381,62815, +50380,62818,63096,63102,N,N,63097,50523,63137,50522,63101,63100,50521,63099, +50520,63098,N,63357,63393,63358,N,63355,50619,63352,63356,63395,N,63394,63353, +63354,50618,63570,50663,N,63571,50661,50662,N,N,63699,50762,63862,N,50794,N, +63923,50795,63924,63925,63939,63938,50810,63949,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,45225,N,N,57577,N,57576,N,48106,48107,58586,N,59602,60524,N,N, +48757,49253,60522,N,60525,49254,N,61284,60523,61881,49998,62401,N,N,N,62822, +62820,N,N,62821,N,N,63138,N,50524,63396,50666,50620,50664,50665,63700,50786,N, +45226,N,N,N,61882,N,N,54345,N,47526,N,58587,N,N,48108,58588,N,N,N,59604,59603, +49256,48758,48759,N,59607,59606,59605,N,N,60526,60529,N,60528,60527,49255, +61288,61286,61285,61287,N,49999,61884,61885,50000,N,61883,N,62403,62402,62405, +50247,62404,N,62823,62825,62824,N,N,63139,63142,63140,63141,63397,50621,N,N,N, +63572,63573,63574,N,50763,50787,63926,45227,N,48760,49257,61886,N,63398,N,N, +63940,54346,N,50811,45228,60530,N,61887,N,62406,N,N,63143,63399,45229,N,58589, +58590,N,48109,48110,59609,48762,48761,59608,N,61289,N,61888,61890,61889,50003, +50002,50001,N,50526,63144,N,50525,63401,63400,N,50764,63701,46013,57578,N,N,N, +58593,58591,58592,N,N,59618,N,59613,59610,59617,N,N,N,59619,N,N,48764,59616, +59612,N,N,59611,59615,59614,48763,N,N,60541,60536,60534,60577,60535,N,60531,N, +60537,N,N,60532,61298,60533,60578,N,N,N,N,N,N,N,60540,49258,60539,60538,N, +60542,N,N,N,N,61290,61293,N,N,61292,N,61300,61295,61299,N,61297,61296,61294,N, +61291,N,49731,49730,N,49732,49729,61301,N,N,N,N,N,61896,61899,N,61897,61901,N, +N,N,61902,N,61894,50008,61895,N,61893,61900,N,61892,61891,50007,50005,50004,N, +N,N,N,N,N,N,N,61898,62415,62421,50250,62416,N,62419,62423,50251,62418,N,62410, +N,62409,62422,62413,N,62411,62420,62412,50249,50248,N,62407,62408,62417,N,N,N, +62414,N,N,N,N,N,N,62828,62831,N,N,N,N,50006,62829,62835,62833,62827,62838,N, +62826,N,50383,62834,N,N,N,62830,50382,62837,N,N,62836,N,N,N,N,63147,63146,N,N, +N,63153,N,63149,63152,50528,N,N,63150,63151,N,63145,63148,50527,N,N,N,50623, +63412,63407,63411,N,63414,63410,N,63406,N,50625,63409,63413,50624,63404,62832, +63408,N,N,63405,N,63402,N,63403,50622,63578,63580,63583,63579,63584,N,63577,N, +63575,N,50667,63581,50669,50668,63576,63582,N,N,N,N,63706,50765,63707,N,63705, +63702,N,N,63704,63703,63834,N,N,N,N,63836,63835,N,N,63865,N,63864,63863,63866, +N,50803,50804,63946,63950,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,46014,56495,57581,N,47527,57579,N,N,57580,N,N,N,58594,58595,48113,48111, +58596,48112,59624,N,59627,59621,59628,59620,59622,N,59623,59626,N,N,48801, +59631,59630,48765,59625,59629,48766,N,N,N,N,N,N,60588,N,49263,N,60583,49259,N, +60580,60586,60589,N,49264,N,60585,60582,60590,60581,N,60587,49260,N,60579, +49261,N,49262,60584,N,N,N,61353,61306,61307,61310,61308,N,61302,N,N,61305, +61349,61309,N,N,49733,N,61351,61348,49734,61350,61303,61346,61347,N,61345,N,N, +N,N,61906,61908,61911,N,N,61905,N,50009,61913,61904,61914,N,61910,61912,61916, +61909,61917,61907,61903,50010,N,61915,50011,50253,N,N,N,N,N,61304,62449,62440, +50255,62436,50256,N,N,62445,62439,62429,50254,62442,62437,62438,N,62424,62431, +62446,N,62443,N,62435,N,62447,62430,62425,62444,N,62427,62441,62432,62448, +62428,50252,62426,62433,62434,N,N,N,62845,N,62843,N,62882,N,62894,62885,62844, +62840,62887,62846,62883,62842,62890,62839,62881,62886,62888,62891,62841,N, +62895,62896,62889,62893,62884,N,63169,63172,N,50529,N,63171,63176,63174,50530, +63165,63155,63154,50532,63167,63168,63164,63156,N,63161,62892,N,63157,50531, +63163,N,63162,N,63158,63170,N,63159,63419,63173,63175,63166,63160,63420,63422, +63416,50626,N,63429,63427,50627,63426,63425,63418,63415,63421,63430,63417, +63423,N,63593,63598,63588,63591,50670,63595,N,63602,63424,N,63589,63599,63603, +63594,63587,63597,N,63596,63601,63600,63428,63592,63586,63590,50766,50767, +63585,N,63718,63709,63717,63714,63715,63708,63711,63719,63713,63712,63710,N, +63716,N,63837,N,63838,N,63840,63839,63842,63841,63868,63867,63927,N,63928,N, +63941,50808,50812,N,63951,50813,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,46015,N,N,N,50384,63177,N, +50768,50769,N,46016,57582,N,47528,59632,N,N,60592,60593,60591,61355,61354, +49735,61919,61356,61918,N,N,62451,50257,50259,62450,N,N,50258,N,62897,62899, +62898,63178,50533,N,50671,63720,63843,N,N,63954,46017,N,58597,N,48802,N,N,N, +60595,60594,N,61357,N,N,N,50260,50385,63431,63947,N,N,N,46018,48114,N,48803,N, +62452,N,63604,46784,N,N,N,N,61358,N,N,N,50788,46785,48804,49736,63605,46786,N, +59633,49266,60596,60597,N,49265,N,61359,49740,49738,49739,49737,61920,50012,N, +N,N,62901,62900,62903,62902,50386,N,N,63179,N,63181,63180,50534,63432,N,63606, +63607,50672,63844,63869,50805,N,56496,60598,61360,62453,57583,N,61361,61922, +61921,N,N,N,N,63608,50770,N,63845,63870,N,N,N,47529,59634,59635,N,60599,47530, +N,50013,61923,N,63183,50535,63184,63182,63609,N,63721,N,47531,N,61364,61363, +61362,61924,N,N,61928,61927,61926,61925,50014,62454,62905,50387,62904,63185, +63435,63434,50628,63433,63612,63611,63610,N,N,48115,N,60600,49741,N,62455, +62456,63436,63613,N,N,63722,63846,63929,63956,48116,49742,61929,62457,63186, +63614,N,N,48806,N,61365,61930,62458,62459,62460,62910,N,62906,50536,62909, +62908,50388,62907,50390,N,50389,63188,63187,50537,50538,N,N,50630,63437,50629, +N,63651,63652,63650,63649,50772,N,63723,63724,63725,50771,63847,63850,63849, +63848,N,N,63955,N,N,N,N,N,N,N,N,N,N,N,N,N,N,49267,N,N,50021,62911,63189,N, +50631,63438,N,N,63957,N,N,N,49268,N,N,N,61366,N,63439,N,63905,51530,56828, +41290,41303,N,41305,41307,41311,41312,41315,41316,41319,41320,41323,41324, +41327,41328,41331,41332,41335,41336,41339,41340,N,N,N,N,41414,41415,41418, +41419,41416,41417,41308,41293,N,41295,N,41297,41298,41299,41300,N,41341,41342, +41377,41378,41379,41380,41420,41421,41422,41438,41439,41440,41441,41442,N,N, +41548,41549,41550,41289,N,41389,41539,41544,41390,N,41309,41310,41391,41423, +41281,41424,41284,41537,41647,41648,41649,41650,41651,41652,41653,41654,41655, +41656,41287,41286,41429,41431,41430,41288,41545,41679,41680,41681,41682,41683, +41684,41685,41686,41687,41688,41689,41690,41691,41692,41693,41694,41695,41696, +41697,41698,41699,41700,41701,41702,41703,41704,N,41538,N,N,41412,N,41705, +41706,41707,41708,41709,41710,41711,41712,41713,41714,41715,41716,41717,41718, +41719,41720,41721,41722,41723,41724,41725,41726,41792,41793,41794,41795,41313, +41301,41314,N,N,N,N,N,N,41294,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41411, +}; + +static const struct unim_index big5_encmap[256] = { +{__big5_encmap+0,162,247},{0,0,0},{__big5_encmap+86,199,217},{__big5_encmap+ +105,145,201},{__big5_encmap+162,1,81},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{__big5_encmap+243,19,62},{__big5_encmap+287,3,153},{ +__big5_encmap+438,26,191},{0,0,0},{__big5_encmap+604,96,125},{__big5_encmap+ +634,0,229},{__big5_encmap+864,5,66},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+926,0,254},{__big5_encmap+1181, +5,41},{__big5_encmap+1218,163,163},{__big5_encmap+1219,142,213},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+1291,0,255},{ +__big5_encmap+1547,0,254},{__big5_encmap+1802,0,255},{__big5_encmap+2058,0,253 +},{__big5_encmap+2312,0,255},{__big5_encmap+2568,5,252},{__big5_encmap+2816,1, +255},{__big5_encmap+3071,1,255},{__big5_encmap+3326,0,255},{__big5_encmap+3582 +,1,253},{__big5_encmap+3835,0,255},{__big5_encmap+4091,3,255},{__big5_encmap+ +4344,0,255},{__big5_encmap+4600,1,250},{__big5_encmap+4850,1,255},{ +__big5_encmap+5105,0,255},{__big5_encmap+5361,2,255},{__big5_encmap+5615,1,255 +},{__big5_encmap+5870,0,255},{__big5_encmap+6126,0,255},{__big5_encmap+6382,0, +255},{__big5_encmap+6638,0,249},{__big5_encmap+6888,6,255},{__big5_encmap+7138 +,0,253},{__big5_encmap+7392,0,255},{__big5_encmap+7648,0,255},{__big5_encmap+ +7904,18,253},{__big5_encmap+8140,4,255},{__big5_encmap+8392,0,252},{ +__big5_encmap+8645,0,255},{__big5_encmap+8901,0,249},{__big5_encmap+9151,0,253 +},{__big5_encmap+9405,0,255},{__big5_encmap+9661,0,255},{__big5_encmap+9917,0, +255},{__big5_encmap+10173,0,255},{__big5_encmap+10429,1,255},{__big5_encmap+ +10684,0,255},{__big5_encmap+10940,0,255},{__big5_encmap+11196,0,255},{ +__big5_encmap+11452,0,254},{__big5_encmap+11707,1,253},{__big5_encmap+11960,2, +255},{__big5_encmap+12214,1,251},{__big5_encmap+12465,0,255},{__big5_encmap+ +12721,0,255},{__big5_encmap+12977,0,254},{__big5_encmap+13232,0,251},{ +__big5_encmap+13484,3,156},{__big5_encmap+13638,54,255},{__big5_encmap+13840, +0,254},{__big5_encmap+14095,0,255},{__big5_encmap+14351,0,254},{__big5_encmap+ +14606,0,255},{__big5_encmap+14862,1,255},{__big5_encmap+15117,0,255},{ +__big5_encmap+15373,0,254},{__big5_encmap+15628,0,255},{__big5_encmap+15884,0, +254},{__big5_encmap+16139,1,255},{__big5_encmap+16394,0,255},{__big5_encmap+ +16650,0,159},{__big5_encmap+16810,55,254},{__big5_encmap+17010,0,255},{ +__big5_encmap+17266,0,255},{__big5_encmap+17522,0,255},{__big5_encmap+17778,0, +255},{__big5_encmap+18034,0,255},{__big5_encmap+18290,0,255},{__big5_encmap+ +18546,0,255},{__big5_encmap+18802,0,131},{__big5_encmap+18934,119,229},{ +__big5_encmap+19045,28,255},{__big5_encmap+19273,0,255},{__big5_encmap+19529, +0,254},{__big5_encmap+19784,0,255},{__big5_encmap+20040,1,254},{__big5_encmap+ +20294,1,253},{__big5_encmap+20547,5,255},{__big5_encmap+20798,0,255},{ +__big5_encmap+21054,0,255},{__big5_encmap+21310,0,164},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{__big5_encmap+21475,12,13},{0,0,0},{0,0,0},{0,0,0},{__big5_encmap+21477,48, +107},{__big5_encmap+21537,1,227}, +}; + +static const ucs2_t __cp950ext_decmap[224] = { +8231,U,U,U,U,U,U,U,U,65105,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,U,U,U,U,U,175,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U,U, +U,U,U,U,U,U,U,65374,U,U,U,U,U,U,U,U,U,U,U,U,U,U,8853,8857,8725,65128,U,65509, +U,65504,65505,8364,30849,37561,35023,22715,24658,31911,23290,9556,9574,9559, +9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,9575,9563, +9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,9584,9583, +9619, +}; + +static const struct dbcs_index cp950ext_decmap[256] = { +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_decmap+0,69,243 +},{__cp950ext_decmap+175,65,71},{__cp950ext_decmap+182,225,225},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_decmap+183,214,254 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +}; + +static const DBCHAR __cp950ext_encmap[581] = { +41410,41285,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41953,41537,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +41458,N,N,N,41459,63992,63974,63983,63965,63976,63985,63967,63980,63989,63971, +63982,63991,63973,N,63986,63968,N,63988,63970,63975,63984,63966,63981,63990, +63972,N,63987,63969,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,63998,63961,63964,63962,63958,63963,63960,63959,41294,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41538,41470,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41536,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,41443,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N, +N,N,N,41542,41543,N,N,N,41540, +}; + +static const struct unim_index cp950ext_encmap[256] = { +{__cp950ext_encmap+0,175,175},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, +{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+1,39,172},{0, +0,0},{__cp950ext_encmap+135,21,153},{0,0,0},{0,0,0},{__cp950ext_encmap+268,81, +147},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{__cp950ext_encmap+335,187,187},{0,0,0},{__cp950ext_encmap+ +336,250,250},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+337, +82,82},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+338,129,129},{0,0,0},{ +0,0,0},{0,0,0},{__cp950ext_encmap+339,167,167},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+ +340,207,207},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{__cp950ext_encmap+341,185,185},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{ +0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0 +},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0, +0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+342,81,104},{ +__cp950ext_encmap+366,15,229}, +}; diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c index 86402768b6e..0fdde556843 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c @@ -1,2088 +1,2088 @@ -/* - * multibytecodec.c: Common Multibyte Codec Implementation - * - * Written by Hye-Shik Chang - */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" +/* + * multibytecodec.c: Common Multibyte Codec Implementation + * + * Written by Hye-Shik Chang + */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include "structmember.h" // PyMemberDef -#include "multibytecodec.h" -#include "clinic/multibytecodec.c.h" - -/*[clinic input] -module _multibytecodec -class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6ad689546cbb5450]*/ - -typedef struct { - PyObject *inobj; - Py_ssize_t inpos, inlen; - unsigned char *outbuf, *outbuf_end; - PyObject *excobj, *outobj; -} MultibyteEncodeBuffer; - -typedef struct { - const unsigned char *inbuf, *inbuf_top, *inbuf_end; - PyObject *excobj; - _PyUnicodeWriter writer; -} MultibyteDecodeBuffer; - -static char *incnewkwarglist[] = {"errors", NULL}; -static char *streamkwarglist[] = {"stream", "errors", NULL}; - -static PyObject *multibytecodec_encode(MultibyteCodec *, - MultibyteCodec_State *, PyObject *, Py_ssize_t *, - PyObject *, int); - -#define MBENC_RESET MBENC_MAX<<1 /* reset after an encoding session */ - -_Py_IDENTIFIER(write); - -static PyObject * -make_tuple(PyObject *object, Py_ssize_t len) -{ - PyObject *v, *w; - - if (object == NULL) - return NULL; - - v = PyTuple_New(2); - if (v == NULL) { - Py_DECREF(object); - return NULL; - } - PyTuple_SET_ITEM(v, 0, object); - - w = PyLong_FromSsize_t(len); - if (w == NULL) { - Py_DECREF(v); - return NULL; - } - PyTuple_SET_ITEM(v, 1, w); - - return v; -} - -static PyObject * -internal_error_callback(const char *errors) -{ - if (errors == NULL || strcmp(errors, "strict") == 0) - return ERROR_STRICT; - else if (strcmp(errors, "ignore") == 0) - return ERROR_IGNORE; - else if (strcmp(errors, "replace") == 0) - return ERROR_REPLACE; - else - return PyUnicode_FromString(errors); -} - -static PyObject * -call_error_callback(PyObject *errors, PyObject *exc) -{ +#include "multibytecodec.h" +#include "clinic/multibytecodec.c.h" + +/*[clinic input] +module _multibytecodec +class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6ad689546cbb5450]*/ + +typedef struct { + PyObject *inobj; + Py_ssize_t inpos, inlen; + unsigned char *outbuf, *outbuf_end; + PyObject *excobj, *outobj; +} MultibyteEncodeBuffer; + +typedef struct { + const unsigned char *inbuf, *inbuf_top, *inbuf_end; + PyObject *excobj; + _PyUnicodeWriter writer; +} MultibyteDecodeBuffer; + +static char *incnewkwarglist[] = {"errors", NULL}; +static char *streamkwarglist[] = {"stream", "errors", NULL}; + +static PyObject *multibytecodec_encode(MultibyteCodec *, + MultibyteCodec_State *, PyObject *, Py_ssize_t *, + PyObject *, int); + +#define MBENC_RESET MBENC_MAX<<1 /* reset after an encoding session */ + +_Py_IDENTIFIER(write); + +static PyObject * +make_tuple(PyObject *object, Py_ssize_t len) +{ + PyObject *v, *w; + + if (object == NULL) + return NULL; + + v = PyTuple_New(2); + if (v == NULL) { + Py_DECREF(object); + return NULL; + } + PyTuple_SET_ITEM(v, 0, object); + + w = PyLong_FromSsize_t(len); + if (w == NULL) { + Py_DECREF(v); + return NULL; + } + PyTuple_SET_ITEM(v, 1, w); + + return v; +} + +static PyObject * +internal_error_callback(const char *errors) +{ + if (errors == NULL || strcmp(errors, "strict") == 0) + return ERROR_STRICT; + else if (strcmp(errors, "ignore") == 0) + return ERROR_IGNORE; + else if (strcmp(errors, "replace") == 0) + return ERROR_REPLACE; + else + return PyUnicode_FromString(errors); +} + +static PyObject * +call_error_callback(PyObject *errors, PyObject *exc) +{ PyObject *cb, *r; - const char *str; - - assert(PyUnicode_Check(errors)); - str = PyUnicode_AsUTF8(errors); - if (str == NULL) - return NULL; - cb = PyCodec_LookupError(str); - if (cb == NULL) - return NULL; - + const char *str; + + assert(PyUnicode_Check(errors)); + str = PyUnicode_AsUTF8(errors); + if (str == NULL) + return NULL; + cb = PyCodec_LookupError(str); + if (cb == NULL) + return NULL; + r = PyObject_CallOneArg(cb, exc); - Py_DECREF(cb); - return r; -} - -static PyObject * -codecctx_errors_get(MultibyteStatefulCodecContext *self, void *Py_UNUSED(ignored)) -{ - const char *errors; - - if (self->errors == ERROR_STRICT) - errors = "strict"; - else if (self->errors == ERROR_IGNORE) - errors = "ignore"; - else if (self->errors == ERROR_REPLACE) - errors = "replace"; - else { - Py_INCREF(self->errors); - return self->errors; - } - - return PyUnicode_FromString(errors); -} - -static int -codecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value, - void *closure) -{ - PyObject *cb; - const char *str; - - if (value == NULL) { - PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); - return -1; - } - if (!PyUnicode_Check(value)) { - PyErr_SetString(PyExc_TypeError, "errors must be a string"); - return -1; - } - - str = PyUnicode_AsUTF8(value); - if (str == NULL) - return -1; - - cb = internal_error_callback(str); - if (cb == NULL) - return -1; - - ERROR_DECREF(self->errors); - self->errors = cb; - return 0; -} - -/* This getset handlers list is used by all the stateful codec objects */ -static PyGetSetDef codecctx_getsets[] = { - {"errors", (getter)codecctx_errors_get, - (setter)codecctx_errors_set, - PyDoc_STR("how to treat errors")}, - {NULL,} -}; - -static int -expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) -{ - Py_ssize_t orgpos, orgsize, incsize; - - orgpos = (Py_ssize_t)((char *)buf->outbuf - - PyBytes_AS_STRING(buf->outobj)); - orgsize = PyBytes_GET_SIZE(buf->outobj); - incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize); - - if (orgsize > PY_SSIZE_T_MAX - incsize) { - PyErr_NoMemory(); - return -1; - } - - if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1) - return -1; - - buf->outbuf = (unsigned char *)PyBytes_AS_STRING(buf->outobj) +orgpos; - buf->outbuf_end = (unsigned char *)PyBytes_AS_STRING(buf->outobj) - + PyBytes_GET_SIZE(buf->outobj); - - return 0; -} -#define REQUIRE_ENCODEBUFFER(buf, s) do { \ - if ((s) < 0 || (s) > (buf)->outbuf_end - (buf)->outbuf) \ - if (expand_encodebuffer(buf, s) == -1) \ - goto errorexit; \ -} while(0) - - -/** - * MultibyteCodec object - */ - -static int -multibytecodec_encerror(MultibyteCodec *codec, - MultibyteCodec_State *state, - MultibyteEncodeBuffer *buf, - PyObject *errors, Py_ssize_t e) -{ - PyObject *retobj = NULL, *retstr = NULL, *tobj; - Py_ssize_t retstrsize, newpos; - Py_ssize_t esize, start, end; - const char *reason; - - if (e > 0) { - reason = "illegal multibyte sequence"; - esize = e; - } - else { - switch (e) { - case MBERR_TOOSMALL: - REQUIRE_ENCODEBUFFER(buf, -1); - return 0; /* retry it */ - case MBERR_TOOFEW: - reason = "incomplete multibyte sequence"; - esize = (Py_ssize_t)buf->inpos; - break; - case MBERR_INTERNAL: - PyErr_SetString(PyExc_RuntimeError, - "internal codec error"); - return -1; - default: - PyErr_SetString(PyExc_RuntimeError, - "unknown runtime error"); - return -1; - } - } - - if (errors == ERROR_REPLACE) { - PyObject *replchar; - Py_ssize_t r; - Py_ssize_t inpos; - int kind; + Py_DECREF(cb); + return r; +} + +static PyObject * +codecctx_errors_get(MultibyteStatefulCodecContext *self, void *Py_UNUSED(ignored)) +{ + const char *errors; + + if (self->errors == ERROR_STRICT) + errors = "strict"; + else if (self->errors == ERROR_IGNORE) + errors = "ignore"; + else if (self->errors == ERROR_REPLACE) + errors = "replace"; + else { + Py_INCREF(self->errors); + return self->errors; + } + + return PyUnicode_FromString(errors); +} + +static int +codecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value, + void *closure) +{ + PyObject *cb; + const char *str; + + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); + return -1; + } + if (!PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, "errors must be a string"); + return -1; + } + + str = PyUnicode_AsUTF8(value); + if (str == NULL) + return -1; + + cb = internal_error_callback(str); + if (cb == NULL) + return -1; + + ERROR_DECREF(self->errors); + self->errors = cb; + return 0; +} + +/* This getset handlers list is used by all the stateful codec objects */ +static PyGetSetDef codecctx_getsets[] = { + {"errors", (getter)codecctx_errors_get, + (setter)codecctx_errors_set, + PyDoc_STR("how to treat errors")}, + {NULL,} +}; + +static int +expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) +{ + Py_ssize_t orgpos, orgsize, incsize; + + orgpos = (Py_ssize_t)((char *)buf->outbuf - + PyBytes_AS_STRING(buf->outobj)); + orgsize = PyBytes_GET_SIZE(buf->outobj); + incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize); + + if (orgsize > PY_SSIZE_T_MAX - incsize) { + PyErr_NoMemory(); + return -1; + } + + if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1) + return -1; + + buf->outbuf = (unsigned char *)PyBytes_AS_STRING(buf->outobj) +orgpos; + buf->outbuf_end = (unsigned char *)PyBytes_AS_STRING(buf->outobj) + + PyBytes_GET_SIZE(buf->outobj); + + return 0; +} +#define REQUIRE_ENCODEBUFFER(buf, s) do { \ + if ((s) < 0 || (s) > (buf)->outbuf_end - (buf)->outbuf) \ + if (expand_encodebuffer(buf, s) == -1) \ + goto errorexit; \ +} while(0) + + +/** + * MultibyteCodec object + */ + +static int +multibytecodec_encerror(MultibyteCodec *codec, + MultibyteCodec_State *state, + MultibyteEncodeBuffer *buf, + PyObject *errors, Py_ssize_t e) +{ + PyObject *retobj = NULL, *retstr = NULL, *tobj; + Py_ssize_t retstrsize, newpos; + Py_ssize_t esize, start, end; + const char *reason; + + if (e > 0) { + reason = "illegal multibyte sequence"; + esize = e; + } + else { + switch (e) { + case MBERR_TOOSMALL: + REQUIRE_ENCODEBUFFER(buf, -1); + return 0; /* retry it */ + case MBERR_TOOFEW: + reason = "incomplete multibyte sequence"; + esize = (Py_ssize_t)buf->inpos; + break; + case MBERR_INTERNAL: + PyErr_SetString(PyExc_RuntimeError, + "internal codec error"); + return -1; + default: + PyErr_SetString(PyExc_RuntimeError, + "unknown runtime error"); + return -1; + } + } + + if (errors == ERROR_REPLACE) { + PyObject *replchar; + Py_ssize_t r; + Py_ssize_t inpos; + int kind; const void *data; - - replchar = PyUnicode_FromOrdinal('?'); - if (replchar == NULL) - goto errorexit; - kind = PyUnicode_KIND(replchar); - data = PyUnicode_DATA(replchar); - - inpos = 0; - for (;;) { - Py_ssize_t outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf); - - r = codec->encode(state, codec->config, - kind, data, &inpos, 1, - &buf->outbuf, outleft, 0); - if (r == MBERR_TOOSMALL) { - REQUIRE_ENCODEBUFFER(buf, -1); - continue; - } - else - break; - } - - Py_DECREF(replchar); - - if (r != 0) { - REQUIRE_ENCODEBUFFER(buf, 1); - *buf->outbuf++ = '?'; - } - } - if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { - buf->inpos += esize; - return 0; - } - - start = (Py_ssize_t)buf->inpos; - end = start + esize; - - /* use cached exception object if available */ - if (buf->excobj == NULL) { - buf->excobj = PyObject_CallFunction(PyExc_UnicodeEncodeError, - "sOnns", - codec->encoding, buf->inobj, - start, end, reason); - if (buf->excobj == NULL) - goto errorexit; - } - else - if (PyUnicodeEncodeError_SetStart(buf->excobj, start) != 0 || - PyUnicodeEncodeError_SetEnd(buf->excobj, end) != 0 || - PyUnicodeEncodeError_SetReason(buf->excobj, reason) != 0) - goto errorexit; - - if (errors == ERROR_STRICT) { - PyCodec_StrictErrors(buf->excobj); - goto errorexit; - } - - retobj = call_error_callback(errors, buf->excobj); - if (retobj == NULL) - goto errorexit; - - if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || - (!PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) && !PyBytes_Check(tobj)) || - !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { - PyErr_SetString(PyExc_TypeError, - "encoding error handler must return " - "(str, int) tuple"); - goto errorexit; - } - - if (PyUnicode_Check(tobj)) { - Py_ssize_t inpos; - - retstr = multibytecodec_encode(codec, state, tobj, - &inpos, ERROR_STRICT, - MBENC_FLUSH); - if (retstr == NULL) - goto errorexit; - } - else { - Py_INCREF(tobj); - retstr = tobj; - } - - assert(PyBytes_Check(retstr)); - retstrsize = PyBytes_GET_SIZE(retstr); - if (retstrsize > 0) { - REQUIRE_ENCODEBUFFER(buf, retstrsize); - memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize); - buf->outbuf += retstrsize; - } - - newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); - if (newpos < 0 && !PyErr_Occurred()) - newpos += (Py_ssize_t)buf->inlen; - if (newpos < 0 || newpos > buf->inlen) { - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, - "position %zd from error handler out of bounds", - newpos); - goto errorexit; - } - buf->inpos = newpos; - - Py_DECREF(retobj); - Py_DECREF(retstr); - return 0; - -errorexit: - Py_XDECREF(retobj); - Py_XDECREF(retstr); - return -1; -} - -static int -multibytecodec_decerror(MultibyteCodec *codec, - MultibyteCodec_State *state, - MultibyteDecodeBuffer *buf, - PyObject *errors, Py_ssize_t e) -{ - PyObject *retobj = NULL, *retuni = NULL; - Py_ssize_t newpos; - const char *reason; - Py_ssize_t esize, start, end; - - if (e > 0) { - reason = "illegal multibyte sequence"; - esize = e; - } - else { - switch (e) { - case MBERR_TOOSMALL: - return 0; /* retry it */ - case MBERR_TOOFEW: - reason = "incomplete multibyte sequence"; - esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); - break; - case MBERR_INTERNAL: - PyErr_SetString(PyExc_RuntimeError, - "internal codec error"); - return -1; - case MBERR_EXCEPTION: - return -1; - default: - PyErr_SetString(PyExc_RuntimeError, - "unknown runtime error"); - return -1; - } - } - - if (errors == ERROR_REPLACE) { - if (_PyUnicodeWriter_WriteChar(&buf->writer, - Py_UNICODE_REPLACEMENT_CHARACTER) < 0) - goto errorexit; - } - if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { - buf->inbuf += esize; - return 0; - } - - start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top); - end = start + esize; - - /* use cached exception object if available */ - if (buf->excobj == NULL) { - buf->excobj = PyUnicodeDecodeError_Create(codec->encoding, - (const char *)buf->inbuf_top, - (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top), - start, end, reason); - if (buf->excobj == NULL) - goto errorexit; - } - else - if (PyUnicodeDecodeError_SetStart(buf->excobj, start) || - PyUnicodeDecodeError_SetEnd(buf->excobj, end) || - PyUnicodeDecodeError_SetReason(buf->excobj, reason)) - goto errorexit; - - if (errors == ERROR_STRICT) { - PyCodec_StrictErrors(buf->excobj); - goto errorexit; - } - - retobj = call_error_callback(errors, buf->excobj); - if (retobj == NULL) - goto errorexit; - - if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || - !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) || - !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { - PyErr_SetString(PyExc_TypeError, - "decoding error handler must return " - "(str, int) tuple"); - goto errorexit; - } - - if (_PyUnicodeWriter_WriteStr(&buf->writer, retuni) < 0) - goto errorexit; - - newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); - if (newpos < 0 && !PyErr_Occurred()) - newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top); - if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) { - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, - "position %zd from error handler out of bounds", - newpos); - goto errorexit; - } - buf->inbuf = buf->inbuf_top + newpos; - Py_DECREF(retobj); - return 0; - -errorexit: - Py_XDECREF(retobj); - return -1; -} - -static PyObject * -multibytecodec_encode(MultibyteCodec *codec, - MultibyteCodec_State *state, - PyObject *text, Py_ssize_t *inpos_t, - PyObject *errors, int flags) -{ - MultibyteEncodeBuffer buf; - Py_ssize_t finalsize, r = 0; - Py_ssize_t datalen; - int kind; + + replchar = PyUnicode_FromOrdinal('?'); + if (replchar == NULL) + goto errorexit; + kind = PyUnicode_KIND(replchar); + data = PyUnicode_DATA(replchar); + + inpos = 0; + for (;;) { + Py_ssize_t outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf); + + r = codec->encode(state, codec->config, + kind, data, &inpos, 1, + &buf->outbuf, outleft, 0); + if (r == MBERR_TOOSMALL) { + REQUIRE_ENCODEBUFFER(buf, -1); + continue; + } + else + break; + } + + Py_DECREF(replchar); + + if (r != 0) { + REQUIRE_ENCODEBUFFER(buf, 1); + *buf->outbuf++ = '?'; + } + } + if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { + buf->inpos += esize; + return 0; + } + + start = (Py_ssize_t)buf->inpos; + end = start + esize; + + /* use cached exception object if available */ + if (buf->excobj == NULL) { + buf->excobj = PyObject_CallFunction(PyExc_UnicodeEncodeError, + "sOnns", + codec->encoding, buf->inobj, + start, end, reason); + if (buf->excobj == NULL) + goto errorexit; + } + else + if (PyUnicodeEncodeError_SetStart(buf->excobj, start) != 0 || + PyUnicodeEncodeError_SetEnd(buf->excobj, end) != 0 || + PyUnicodeEncodeError_SetReason(buf->excobj, reason) != 0) + goto errorexit; + + if (errors == ERROR_STRICT) { + PyCodec_StrictErrors(buf->excobj); + goto errorexit; + } + + retobj = call_error_callback(errors, buf->excobj); + if (retobj == NULL) + goto errorexit; + + if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || + (!PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) && !PyBytes_Check(tobj)) || + !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { + PyErr_SetString(PyExc_TypeError, + "encoding error handler must return " + "(str, int) tuple"); + goto errorexit; + } + + if (PyUnicode_Check(tobj)) { + Py_ssize_t inpos; + + retstr = multibytecodec_encode(codec, state, tobj, + &inpos, ERROR_STRICT, + MBENC_FLUSH); + if (retstr == NULL) + goto errorexit; + } + else { + Py_INCREF(tobj); + retstr = tobj; + } + + assert(PyBytes_Check(retstr)); + retstrsize = PyBytes_GET_SIZE(retstr); + if (retstrsize > 0) { + REQUIRE_ENCODEBUFFER(buf, retstrsize); + memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize); + buf->outbuf += retstrsize; + } + + newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); + if (newpos < 0 && !PyErr_Occurred()) + newpos += (Py_ssize_t)buf->inlen; + if (newpos < 0 || newpos > buf->inlen) { + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, + "position %zd from error handler out of bounds", + newpos); + goto errorexit; + } + buf->inpos = newpos; + + Py_DECREF(retobj); + Py_DECREF(retstr); + return 0; + +errorexit: + Py_XDECREF(retobj); + Py_XDECREF(retstr); + return -1; +} + +static int +multibytecodec_decerror(MultibyteCodec *codec, + MultibyteCodec_State *state, + MultibyteDecodeBuffer *buf, + PyObject *errors, Py_ssize_t e) +{ + PyObject *retobj = NULL, *retuni = NULL; + Py_ssize_t newpos; + const char *reason; + Py_ssize_t esize, start, end; + + if (e > 0) { + reason = "illegal multibyte sequence"; + esize = e; + } + else { + switch (e) { + case MBERR_TOOSMALL: + return 0; /* retry it */ + case MBERR_TOOFEW: + reason = "incomplete multibyte sequence"; + esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); + break; + case MBERR_INTERNAL: + PyErr_SetString(PyExc_RuntimeError, + "internal codec error"); + return -1; + case MBERR_EXCEPTION: + return -1; + default: + PyErr_SetString(PyExc_RuntimeError, + "unknown runtime error"); + return -1; + } + } + + if (errors == ERROR_REPLACE) { + if (_PyUnicodeWriter_WriteChar(&buf->writer, + Py_UNICODE_REPLACEMENT_CHARACTER) < 0) + goto errorexit; + } + if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { + buf->inbuf += esize; + return 0; + } + + start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top); + end = start + esize; + + /* use cached exception object if available */ + if (buf->excobj == NULL) { + buf->excobj = PyUnicodeDecodeError_Create(codec->encoding, + (const char *)buf->inbuf_top, + (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top), + start, end, reason); + if (buf->excobj == NULL) + goto errorexit; + } + else + if (PyUnicodeDecodeError_SetStart(buf->excobj, start) || + PyUnicodeDecodeError_SetEnd(buf->excobj, end) || + PyUnicodeDecodeError_SetReason(buf->excobj, reason)) + goto errorexit; + + if (errors == ERROR_STRICT) { + PyCodec_StrictErrors(buf->excobj); + goto errorexit; + } + + retobj = call_error_callback(errors, buf->excobj); + if (retobj == NULL) + goto errorexit; + + if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || + !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) || + !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { + PyErr_SetString(PyExc_TypeError, + "decoding error handler must return " + "(str, int) tuple"); + goto errorexit; + } + + if (_PyUnicodeWriter_WriteStr(&buf->writer, retuni) < 0) + goto errorexit; + + newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); + if (newpos < 0 && !PyErr_Occurred()) + newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top); + if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) { + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, + "position %zd from error handler out of bounds", + newpos); + goto errorexit; + } + buf->inbuf = buf->inbuf_top + newpos; + Py_DECREF(retobj); + return 0; + +errorexit: + Py_XDECREF(retobj); + return -1; +} + +static PyObject * +multibytecodec_encode(MultibyteCodec *codec, + MultibyteCodec_State *state, + PyObject *text, Py_ssize_t *inpos_t, + PyObject *errors, int flags) +{ + MultibyteEncodeBuffer buf; + Py_ssize_t finalsize, r = 0; + Py_ssize_t datalen; + int kind; const void *data; - - if (PyUnicode_READY(text) < 0) - return NULL; - datalen = PyUnicode_GET_LENGTH(text); - - if (datalen == 0 && !(flags & MBENC_RESET)) - return PyBytes_FromStringAndSize(NULL, 0); - - buf.excobj = NULL; - buf.outobj = NULL; - buf.inobj = text; /* borrowed reference */ - buf.inpos = 0; - buf.inlen = datalen; - kind = PyUnicode_KIND(buf.inobj); - data = PyUnicode_DATA(buf.inobj); - - if (datalen > (PY_SSIZE_T_MAX - 16) / 2) { - PyErr_NoMemory(); - goto errorexit; - } - - buf.outobj = PyBytes_FromStringAndSize(NULL, datalen * 2 + 16); - if (buf.outobj == NULL) - goto errorexit; - buf.outbuf = (unsigned char *)PyBytes_AS_STRING(buf.outobj); - buf.outbuf_end = buf.outbuf + PyBytes_GET_SIZE(buf.outobj); - - while (buf.inpos < buf.inlen) { - /* we don't reuse inleft and outleft here. - * error callbacks can relocate the cursor anywhere on buffer*/ - Py_ssize_t outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); - - r = codec->encode(state, codec->config, - kind, data, - &buf.inpos, buf.inlen, - &buf.outbuf, outleft, flags); - if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH))) - break; - else if (multibytecodec_encerror(codec, state, &buf, errors,r)) - goto errorexit; - else if (r == MBERR_TOOFEW) - break; - } - - if (codec->encreset != NULL && (flags & MBENC_RESET)) - for (;;) { - Py_ssize_t outleft; - - outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); - r = codec->encreset(state, codec->config, &buf.outbuf, - outleft); - if (r == 0) - break; - else if (multibytecodec_encerror(codec, state, - &buf, errors, r)) - goto errorexit; - } - - finalsize = (Py_ssize_t)((char *)buf.outbuf - - PyBytes_AS_STRING(buf.outobj)); - - if (finalsize != PyBytes_GET_SIZE(buf.outobj)) - if (_PyBytes_Resize(&buf.outobj, finalsize) == -1) - goto errorexit; - - if (inpos_t) - *inpos_t = buf.inpos; - Py_XDECREF(buf.excobj); - return buf.outobj; - -errorexit: - Py_XDECREF(buf.excobj); - Py_XDECREF(buf.outobj); - return NULL; -} - -/*[clinic input] -_multibytecodec.MultibyteCodec.encode - - input: object - errors: str(accept={str, NoneType}) = None - -Return an encoded string version of `input'. - -'errors' may be given to set a different error handling scheme. Default is -'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible -values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name -registered with codecs.register_error that can handle UnicodeEncodeErrors. -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, - PyObject *input, - const char *errors) -/*[clinic end generated code: output=7b26652045ba56a9 input=606d0e128a577bae]*/ -{ - MultibyteCodec_State state; - PyObject *errorcb, *r, *ucvt; - Py_ssize_t datalen; - - if (PyUnicode_Check(input)) - ucvt = NULL; - else { - input = ucvt = PyObject_Str(input); - if (input == NULL) - return NULL; - else if (!PyUnicode_Check(input)) { - PyErr_SetString(PyExc_TypeError, - "couldn't convert the object to unicode."); - Py_DECREF(ucvt); - return NULL; - } - } - - if (PyUnicode_READY(input) < 0) { - Py_XDECREF(ucvt); - return NULL; - } - datalen = PyUnicode_GET_LENGTH(input); - - errorcb = internal_error_callback(errors); - if (errorcb == NULL) { - Py_XDECREF(ucvt); - return NULL; - } - - if (self->codec->encinit != NULL && - self->codec->encinit(&state, self->codec->config) != 0) - goto errorexit; - r = multibytecodec_encode(self->codec, &state, - input, NULL, errorcb, - MBENC_FLUSH | MBENC_RESET); - if (r == NULL) - goto errorexit; - - ERROR_DECREF(errorcb); - Py_XDECREF(ucvt); - return make_tuple(r, datalen); - -errorexit: - ERROR_DECREF(errorcb); - Py_XDECREF(ucvt); - return NULL; -} - -/*[clinic input] -_multibytecodec.MultibyteCodec.decode - - input: Py_buffer + + if (PyUnicode_READY(text) < 0) + return NULL; + datalen = PyUnicode_GET_LENGTH(text); + + if (datalen == 0 && !(flags & MBENC_RESET)) + return PyBytes_FromStringAndSize(NULL, 0); + + buf.excobj = NULL; + buf.outobj = NULL; + buf.inobj = text; /* borrowed reference */ + buf.inpos = 0; + buf.inlen = datalen; + kind = PyUnicode_KIND(buf.inobj); + data = PyUnicode_DATA(buf.inobj); + + if (datalen > (PY_SSIZE_T_MAX - 16) / 2) { + PyErr_NoMemory(); + goto errorexit; + } + + buf.outobj = PyBytes_FromStringAndSize(NULL, datalen * 2 + 16); + if (buf.outobj == NULL) + goto errorexit; + buf.outbuf = (unsigned char *)PyBytes_AS_STRING(buf.outobj); + buf.outbuf_end = buf.outbuf + PyBytes_GET_SIZE(buf.outobj); + + while (buf.inpos < buf.inlen) { + /* we don't reuse inleft and outleft here. + * error callbacks can relocate the cursor anywhere on buffer*/ + Py_ssize_t outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); + + r = codec->encode(state, codec->config, + kind, data, + &buf.inpos, buf.inlen, + &buf.outbuf, outleft, flags); + if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH))) + break; + else if (multibytecodec_encerror(codec, state, &buf, errors,r)) + goto errorexit; + else if (r == MBERR_TOOFEW) + break; + } + + if (codec->encreset != NULL && (flags & MBENC_RESET)) + for (;;) { + Py_ssize_t outleft; + + outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); + r = codec->encreset(state, codec->config, &buf.outbuf, + outleft); + if (r == 0) + break; + else if (multibytecodec_encerror(codec, state, + &buf, errors, r)) + goto errorexit; + } + + finalsize = (Py_ssize_t)((char *)buf.outbuf - + PyBytes_AS_STRING(buf.outobj)); + + if (finalsize != PyBytes_GET_SIZE(buf.outobj)) + if (_PyBytes_Resize(&buf.outobj, finalsize) == -1) + goto errorexit; + + if (inpos_t) + *inpos_t = buf.inpos; + Py_XDECREF(buf.excobj); + return buf.outobj; + +errorexit: + Py_XDECREF(buf.excobj); + Py_XDECREF(buf.outobj); + return NULL; +} + +/*[clinic input] +_multibytecodec.MultibyteCodec.encode + + input: object errors: str(accept={str, NoneType}) = None - -Decodes 'input'. - -'errors' may be given to set a different error handling scheme. Default is -'strict' meaning that encoding errors raise a UnicodeDecodeError. Other possible -values are 'ignore' and 'replace' as well as any other name registered with -codecs.register_error that is able to handle UnicodeDecodeErrors." -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, - Py_buffer *input, - const char *errors) -/*[clinic end generated code: output=ff419f65bad6cc77 input=e0c78fc7ab190def]*/ -{ - MultibyteCodec_State state; - MultibyteDecodeBuffer buf; - PyObject *errorcb, *res; - const char *data; - Py_ssize_t datalen; - - data = input->buf; - datalen = input->len; - - errorcb = internal_error_callback(errors); - if (errorcb == NULL) { - return NULL; - } - - if (datalen == 0) { - ERROR_DECREF(errorcb); - return make_tuple(PyUnicode_New(0, 0), 0); - } - - _PyUnicodeWriter_Init(&buf.writer); - buf.writer.min_length = datalen; - buf.excobj = NULL; - buf.inbuf = buf.inbuf_top = (unsigned char *)data; - buf.inbuf_end = buf.inbuf_top + datalen; - - if (self->codec->decinit != NULL && - self->codec->decinit(&state, self->codec->config) != 0) - goto errorexit; - - while (buf.inbuf < buf.inbuf_end) { - Py_ssize_t inleft, r; - - inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf); - - r = self->codec->decode(&state, self->codec->config, - &buf.inbuf, inleft, &buf.writer); - if (r == 0) - break; - else if (multibytecodec_decerror(self->codec, &state, - &buf, errorcb, r)) - goto errorexit; - } - - res = _PyUnicodeWriter_Finish(&buf.writer); - if (res == NULL) - goto errorexit; - - Py_XDECREF(buf.excobj); - ERROR_DECREF(errorcb); - return make_tuple(res, datalen); - -errorexit: - ERROR_DECREF(errorcb); - Py_XDECREF(buf.excobj); - _PyUnicodeWriter_Dealloc(&buf.writer); - - return NULL; -} - -static struct PyMethodDef multibytecodec_methods[] = { - _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF - _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF - {NULL, NULL}, -}; - -static void -multibytecodec_dealloc(MultibyteCodecObject *self) -{ - PyObject_Del(self); -} - -static PyTypeObject MultibyteCodec_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteCodec", /* tp_name */ - sizeof(MultibyteCodecObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)multibytecodec_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - multibytecodec_methods, /* tp_methods */ -}; - - -/** - * Utility functions for stateful codec mechanism - */ - -#define STATEFUL_DCTX(o) ((MultibyteStatefulDecoderContext *)(o)) -#define STATEFUL_ECTX(o) ((MultibyteStatefulEncoderContext *)(o)) - -static PyObject * -encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, - PyObject *unistr, int final) -{ - PyObject *ucvt, *r = NULL; - PyObject *inbuf = NULL; - Py_ssize_t inpos, datalen; - PyObject *origpending = NULL; - - if (PyUnicode_Check(unistr)) - ucvt = NULL; - else { - unistr = ucvt = PyObject_Str(unistr); - if (unistr == NULL) - return NULL; - else if (!PyUnicode_Check(unistr)) { - PyErr_SetString(PyExc_TypeError, - "couldn't convert the object to str."); - Py_DECREF(ucvt); - return NULL; - } - } - - if (ctx->pending) { - PyObject *inbuf_tmp; - - Py_INCREF(ctx->pending); - origpending = ctx->pending; - - Py_INCREF(ctx->pending); - inbuf_tmp = ctx->pending; - PyUnicode_Append(&inbuf_tmp, unistr); - if (inbuf_tmp == NULL) - goto errorexit; - Py_CLEAR(ctx->pending); - inbuf = inbuf_tmp; - } - else { - origpending = NULL; - - Py_INCREF(unistr); - inbuf = unistr; - } - if (PyUnicode_READY(inbuf) < 0) - goto errorexit; - inpos = 0; - datalen = PyUnicode_GET_LENGTH(inbuf); - - r = multibytecodec_encode(ctx->codec, &ctx->state, - inbuf, &inpos, - ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0); - if (r == NULL) { - /* recover the original pending buffer */ - Py_XSETREF(ctx->pending, origpending); - origpending = NULL; - goto errorexit; - } - Py_XDECREF(origpending); - - if (inpos < datalen) { - if (datalen - inpos > MAXENCPENDING) { - /* normal codecs can't reach here */ - PyErr_SetString(PyExc_UnicodeError, - "pending buffer overflow"); - goto errorexit; - } - ctx->pending = PyUnicode_Substring(inbuf, inpos, datalen); - if (ctx->pending == NULL) { - /* normal codecs can't reach here */ - goto errorexit; - } - } - - Py_DECREF(inbuf); - Py_XDECREF(ucvt); - return r; - -errorexit: - Py_XDECREF(r); - Py_XDECREF(ucvt); - Py_XDECREF(origpending); - Py_XDECREF(inbuf); - return NULL; -} - -static int -decoder_append_pending(MultibyteStatefulDecoderContext *ctx, - MultibyteDecodeBuffer *buf) -{ - Py_ssize_t npendings; - - npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); - if (npendings + ctx->pendingsize > MAXDECPENDING || - npendings > PY_SSIZE_T_MAX - ctx->pendingsize) { - PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow"); - return -1; - } - memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings); - ctx->pendingsize += npendings; - return 0; -} - -static int -decoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data, - Py_ssize_t size) -{ - buf->inbuf = buf->inbuf_top = (const unsigned char *)data; - buf->inbuf_end = buf->inbuf_top + size; - buf->writer.min_length += size; - return 0; -} - -static int -decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, - MultibyteDecodeBuffer *buf) -{ - while (buf->inbuf < buf->inbuf_end) { - Py_ssize_t inleft; - Py_ssize_t r; - - inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); - - r = ctx->codec->decode(&ctx->state, ctx->codec->config, - &buf->inbuf, inleft, &buf->writer); - if (r == 0 || r == MBERR_TOOFEW) - break; - else if (multibytecodec_decerror(ctx->codec, &ctx->state, - buf, ctx->errors, r)) - return -1; - } - return 0; -} - - -/*[clinic input] - class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/ - -/*[clinic input] -_multibytecodec.MultibyteIncrementalEncoder.encode - - input: object - final: bool(accept={int}) = False -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, - PyObject *input, - int final) -/*[clinic end generated code: output=123361b6c505e2c1 input=093a1ddbb2fc6721]*/ -{ - return encoder_encode_stateful(STATEFUL_ECTX(self), input, final); -} - -/*[clinic input] -_multibytecodec.MultibyteIncrementalEncoder.getstate -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteIncrementalEncoder_getstate_impl(MultibyteIncrementalEncoderObject *self) -/*[clinic end generated code: output=9794a5ace70d7048 input=4a2a82874ffa40bb]*/ -{ - /* state made up of 1 byte for buffer size, up to MAXENCPENDING*4 bytes - for UTF-8 encoded buffer (each character can use up to 4 - bytes), and required bytes for MultibyteCodec_State.c. A byte - array is used to avoid different compilers generating different - values for the same state, e.g. as a result of struct padding. - */ - unsigned char statebytes[1 + MAXENCPENDING*4 + sizeof(self->state.c)]; - Py_ssize_t statesize; - const char *pendingbuffer = NULL; - Py_ssize_t pendingsize; - - if (self->pending != NULL) { - pendingbuffer = PyUnicode_AsUTF8AndSize(self->pending, &pendingsize); - if (pendingbuffer == NULL) { - return NULL; - } - if (pendingsize > MAXENCPENDING*4) { - PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); - return NULL; - } - statebytes[0] = (unsigned char)pendingsize; - memcpy(statebytes + 1, pendingbuffer, pendingsize); - statesize = 1 + pendingsize; - } else { - statebytes[0] = 0; - statesize = 1; - } - memcpy(statebytes+statesize, self->state.c, - sizeof(self->state.c)); - statesize += sizeof(self->state.c); - - return (PyObject *)_PyLong_FromByteArray(statebytes, statesize, - 1 /* little-endian */ , - 0 /* unsigned */ ); -} - -/*[clinic input] -_multibytecodec.MultibyteIncrementalEncoder.setstate - state as statelong: object(type='PyLongObject *', subclass_of='&PyLong_Type') - / -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEncoderObject *self, - PyLongObject *statelong) -/*[clinic end generated code: output=4e5e98ac1f4039ca input=c80fb5830d4d2f76]*/ -{ - PyObject *pending = NULL; - unsigned char statebytes[1 + MAXENCPENDING*4 + sizeof(self->state.c)]; - - if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes), - 1 /* little-endian */ , - 0 /* unsigned */ ) < 0) { - goto errorexit; - } - - if (statebytes[0] > MAXENCPENDING*4) { - PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); - return NULL; - } - - pending = PyUnicode_DecodeUTF8((const char *)statebytes+1, - statebytes[0], "strict"); - if (pending == NULL) { - goto errorexit; - } - - Py_CLEAR(self->pending); - self->pending = pending; - memcpy(self->state.c, statebytes+1+statebytes[0], - sizeof(self->state.c)); - - Py_RETURN_NONE; - -errorexit: - Py_XDECREF(pending); - return NULL; -} - -/*[clinic input] -_multibytecodec.MultibyteIncrementalEncoder.reset -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self) -/*[clinic end generated code: output=b4125d8f537a253f input=930f06760707b6ea]*/ -{ - /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */ - unsigned char buffer[4], *outbuf; - Py_ssize_t r; - if (self->codec->encreset != NULL) { - outbuf = buffer; - r = self->codec->encreset(&self->state, self->codec->config, - &outbuf, sizeof(buffer)); - if (r != 0) - return NULL; - } - Py_CLEAR(self->pending); - Py_RETURN_NONE; -} - -static struct PyMethodDef mbiencoder_methods[] = { - _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF - _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_GETSTATE_METHODDEF - _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_SETSTATE_METHODDEF - _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF - {NULL, NULL}, -}; - -static PyObject * -mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - MultibyteIncrementalEncoderObject *self; - PyObject *codec = NULL; - char *errors = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder", - incnewkwarglist, &errors)) - return NULL; - - self = (MultibyteIncrementalEncoderObject *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - codec = PyObject_GetAttrString((PyObject *)type, "codec"); - if (codec == NULL) - goto errorexit; - if (!MultibyteCodec_Check(codec)) { - PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); - goto errorexit; - } - - self->codec = ((MultibyteCodecObject *)codec)->codec; - self->pending = NULL; - self->errors = internal_error_callback(errors); - if (self->errors == NULL) - goto errorexit; - if (self->codec->encinit != NULL && - self->codec->encinit(&self->state, self->codec->config) != 0) - goto errorexit; - - Py_DECREF(codec); - return (PyObject *)self; - -errorexit: - Py_XDECREF(self); - Py_XDECREF(codec); - return NULL; -} - -static int -mbiencoder_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - return 0; -} - -static int -mbiencoder_traverse(MultibyteIncrementalEncoderObject *self, - visitproc visit, void *arg) -{ - if (ERROR_ISCUSTOM(self->errors)) - Py_VISIT(self->errors); - return 0; -} - -static void -mbiencoder_dealloc(MultibyteIncrementalEncoderObject *self) -{ - PyObject_GC_UnTrack(self); - ERROR_DECREF(self->errors); - Py_CLEAR(self->pending); - Py_TYPE(self)->tp_free(self); -} - -static PyTypeObject MultibyteIncrementalEncoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteIncrementalEncoder", /* tp_name */ - sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbiencoder_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)mbiencoder_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbiencoder_methods, /* tp_methods */ - 0, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbiencoder_init, /* tp_init */ - 0, /* tp_alloc */ - mbiencoder_new, /* tp_new */ -}; - - -/*[clinic input] - class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "&MultibyteIncrementalDecoder_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f6003faaf2cea692]*/ - -/*[clinic input] -_multibytecodec.MultibyteIncrementalDecoder.decode - - input: Py_buffer - final: bool(accept={int}) = False -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, - Py_buffer *input, - int final) -/*[clinic end generated code: output=b9b9090e8a9ce2ba input=c9132b24d503eb1d]*/ -{ - MultibyteDecodeBuffer buf; - char *data, *wdata = NULL; - Py_ssize_t wsize, size, origpending; - PyObject *res; - - data = input->buf; - size = input->len; - - _PyUnicodeWriter_Init(&buf.writer); - buf.excobj = NULL; - origpending = self->pendingsize; - - if (self->pendingsize == 0) { - wsize = size; - wdata = data; - } - else { - if (size > PY_SSIZE_T_MAX - self->pendingsize) { - PyErr_NoMemory(); - goto errorexit; - } - wsize = size + self->pendingsize; - wdata = PyMem_Malloc(wsize); - if (wdata == NULL) { - PyErr_NoMemory(); - goto errorexit; - } - memcpy(wdata, self->pending, self->pendingsize); - memcpy(wdata + self->pendingsize, data, size); - self->pendingsize = 0; - } - - if (decoder_prepare_buffer(&buf, wdata, wsize) != 0) - goto errorexit; - - if (decoder_feed_buffer(STATEFUL_DCTX(self), &buf)) - goto errorexit; - - if (final && buf.inbuf < buf.inbuf_end) { - if (multibytecodec_decerror(self->codec, &self->state, - &buf, self->errors, MBERR_TOOFEW)) { - /* recover the original pending buffer */ - memcpy(self->pending, wdata, origpending); - self->pendingsize = origpending; - goto errorexit; - } - } - - if (buf.inbuf < buf.inbuf_end) { /* pending sequence still exists */ - if (decoder_append_pending(STATEFUL_DCTX(self), &buf) != 0) - goto errorexit; - } - - res = _PyUnicodeWriter_Finish(&buf.writer); - if (res == NULL) - goto errorexit; - - if (wdata != data) - PyMem_Del(wdata); - Py_XDECREF(buf.excobj); - return res; - -errorexit: - if (wdata != NULL && wdata != data) - PyMem_Del(wdata); - Py_XDECREF(buf.excobj); - _PyUnicodeWriter_Dealloc(&buf.writer); - return NULL; -} - -/*[clinic input] -_multibytecodec.MultibyteIncrementalDecoder.getstate -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteIncrementalDecoder_getstate_impl(MultibyteIncrementalDecoderObject *self) -/*[clinic end generated code: output=255009c4713b7f82 input=4006aa49bddbaa75]*/ -{ - PyObject *buffer; - PyObject *statelong; - - buffer = PyBytes_FromStringAndSize((const char *)self->pending, - self->pendingsize); - if (buffer == NULL) { - return NULL; - } - - statelong = (PyObject *)_PyLong_FromByteArray(self->state.c, - sizeof(self->state.c), - 1 /* little-endian */ , - 0 /* unsigned */ ); - if (statelong == NULL) { - Py_DECREF(buffer); - return NULL; - } - - return Py_BuildValue("NN", buffer, statelong); -} - -/*[clinic input] -_multibytecodec.MultibyteIncrementalDecoder.setstate - state: object(subclass_of='&PyTuple_Type') - / -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteIncrementalDecoder_setstate_impl(MultibyteIncrementalDecoderObject *self, - PyObject *state) -/*[clinic end generated code: output=106b2fbca3e2dcc2 input=e5d794e8baba1a47]*/ -{ - PyObject *buffer; - PyLongObject *statelong; - Py_ssize_t buffersize; - const char *bufferstr; - unsigned char statebytes[8]; - - if (!PyArg_ParseTuple(state, "SO!;setstate(): illegal state argument", - &buffer, &PyLong_Type, &statelong)) - { - return NULL; - } - - if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes), - 1 /* little-endian */ , - 0 /* unsigned */ ) < 0) { - return NULL; - } - - buffersize = PyBytes_Size(buffer); - if (buffersize == -1) { - return NULL; - } - - if (buffersize > MAXDECPENDING) { - PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); - return NULL; - } - - bufferstr = PyBytes_AsString(buffer); - if (bufferstr == NULL) { - return NULL; - } - self->pendingsize = buffersize; - memcpy(self->pending, bufferstr, self->pendingsize); - memcpy(self->state.c, statebytes, sizeof(statebytes)); - - Py_RETURN_NONE; -} - -/*[clinic input] -_multibytecodec.MultibyteIncrementalDecoder.reset -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self) -/*[clinic end generated code: output=da423b1782c23ed1 input=3b63b3be85b2fb45]*/ -{ - if (self->codec->decreset != NULL && - self->codec->decreset(&self->state, self->codec->config) != 0) - return NULL; - self->pendingsize = 0; - - Py_RETURN_NONE; -} - -static struct PyMethodDef mbidecoder_methods[] = { - _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF - _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_GETSTATE_METHODDEF - _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_SETSTATE_METHODDEF - _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF - {NULL, NULL}, -}; - -static PyObject * -mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - MultibyteIncrementalDecoderObject *self; - PyObject *codec = NULL; - char *errors = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder", - incnewkwarglist, &errors)) - return NULL; - - self = (MultibyteIncrementalDecoderObject *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - codec = PyObject_GetAttrString((PyObject *)type, "codec"); - if (codec == NULL) - goto errorexit; - if (!MultibyteCodec_Check(codec)) { - PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); - goto errorexit; - } - - self->codec = ((MultibyteCodecObject *)codec)->codec; - self->pendingsize = 0; - self->errors = internal_error_callback(errors); - if (self->errors == NULL) - goto errorexit; - if (self->codec->decinit != NULL && - self->codec->decinit(&self->state, self->codec->config) != 0) - goto errorexit; - - Py_DECREF(codec); - return (PyObject *)self; - -errorexit: - Py_XDECREF(self); - Py_XDECREF(codec); - return NULL; -} - -static int -mbidecoder_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - return 0; -} - -static int -mbidecoder_traverse(MultibyteIncrementalDecoderObject *self, - visitproc visit, void *arg) -{ - if (ERROR_ISCUSTOM(self->errors)) - Py_VISIT(self->errors); - return 0; -} - -static void -mbidecoder_dealloc(MultibyteIncrementalDecoderObject *self) -{ - PyObject_GC_UnTrack(self); - ERROR_DECREF(self->errors); - Py_TYPE(self)->tp_free(self); -} - -static PyTypeObject MultibyteIncrementalDecoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteIncrementalDecoder", /* tp_name */ - sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbidecoder_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)mbidecoder_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbidecoder_methods, /* tp_methods */ - 0, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbidecoder_init, /* tp_init */ - 0, /* tp_alloc */ - mbidecoder_new, /* tp_new */ -}; - - -/*[clinic input] - class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "MultibyteStreamReader_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d323634b74976f09]*/ - -static PyObject * -mbstreamreader_iread(MultibyteStreamReaderObject *self, - const char *method, Py_ssize_t sizehint) -{ - MultibyteDecodeBuffer buf; - PyObject *cres, *res; - Py_ssize_t rsize; - - if (sizehint == 0) - return PyUnicode_New(0, 0); - - _PyUnicodeWriter_Init(&buf.writer); - buf.excobj = NULL; - cres = NULL; - - for (;;) { - int endoffile; - - if (sizehint < 0) - cres = PyObject_CallMethod(self->stream, - method, NULL); - else - cres = PyObject_CallMethod(self->stream, - method, "i", sizehint); - if (cres == NULL) - goto errorexit; - - if (!PyBytes_Check(cres)) { - PyErr_Format(PyExc_TypeError, - "stream function returned a " - "non-bytes object (%.100s)", - Py_TYPE(cres)->tp_name); - goto errorexit; - } - - endoffile = (PyBytes_GET_SIZE(cres) == 0); - - if (self->pendingsize > 0) { - PyObject *ctr; - char *ctrdata; - - if (PyBytes_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) { - PyErr_NoMemory(); - goto errorexit; - } - rsize = PyBytes_GET_SIZE(cres) + self->pendingsize; - ctr = PyBytes_FromStringAndSize(NULL, rsize); - if (ctr == NULL) - goto errorexit; - ctrdata = PyBytes_AS_STRING(ctr); - memcpy(ctrdata, self->pending, self->pendingsize); - memcpy(ctrdata + self->pendingsize, - PyBytes_AS_STRING(cres), - PyBytes_GET_SIZE(cres)); - Py_DECREF(cres); - cres = ctr; - self->pendingsize = 0; - } - - rsize = PyBytes_GET_SIZE(cres); - if (decoder_prepare_buffer(&buf, PyBytes_AS_STRING(cres), - rsize) != 0) - goto errorexit; - - if (rsize > 0 && decoder_feed_buffer( - (MultibyteStatefulDecoderContext *)self, &buf)) - goto errorexit; - - if (endoffile || sizehint < 0) { - if (buf.inbuf < buf.inbuf_end && - multibytecodec_decerror(self->codec, &self->state, - &buf, self->errors, MBERR_TOOFEW)) - goto errorexit; - } - - if (buf.inbuf < buf.inbuf_end) { /* pending sequence exists */ - if (decoder_append_pending(STATEFUL_DCTX(self), - &buf) != 0) - goto errorexit; - } - - Py_DECREF(cres); - cres = NULL; - - if (sizehint < 0 || buf.writer.pos != 0 || rsize == 0) - break; - - sizehint = 1; /* read 1 more byte and retry */ - } - - res = _PyUnicodeWriter_Finish(&buf.writer); - if (res == NULL) - goto errorexit; - - Py_XDECREF(cres); - Py_XDECREF(buf.excobj); - return res; - -errorexit: - Py_XDECREF(cres); - Py_XDECREF(buf.excobj); - _PyUnicodeWriter_Dealloc(&buf.writer); - return NULL; -} - -/*[clinic input] - _multibytecodec.MultibyteStreamReader.read - - sizeobj: object = None - / -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, - PyObject *sizeobj) -/*[clinic end generated code: output=35621eb75355d5b8 input=015b0d3ff2fca485]*/ -{ - Py_ssize_t size; - - if (sizeobj == Py_None) - size = -1; - else if (PyLong_Check(sizeobj)) - size = PyLong_AsSsize_t(sizeobj); - else { - PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); - return NULL; - } - - if (size == -1 && PyErr_Occurred()) - return NULL; - - return mbstreamreader_iread(self, "read", size); -} - -/*[clinic input] - _multibytecodec.MultibyteStreamReader.readline - - sizeobj: object = None - / + +Return an encoded string version of `input'. + +'errors' may be given to set a different error handling scheme. Default is +'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible +values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name +registered with codecs.register_error that can handle UnicodeEncodeErrors. +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, + PyObject *input, + const char *errors) +/*[clinic end generated code: output=7b26652045ba56a9 input=606d0e128a577bae]*/ +{ + MultibyteCodec_State state; + PyObject *errorcb, *r, *ucvt; + Py_ssize_t datalen; + + if (PyUnicode_Check(input)) + ucvt = NULL; + else { + input = ucvt = PyObject_Str(input); + if (input == NULL) + return NULL; + else if (!PyUnicode_Check(input)) { + PyErr_SetString(PyExc_TypeError, + "couldn't convert the object to unicode."); + Py_DECREF(ucvt); + return NULL; + } + } + + if (PyUnicode_READY(input) < 0) { + Py_XDECREF(ucvt); + return NULL; + } + datalen = PyUnicode_GET_LENGTH(input); + + errorcb = internal_error_callback(errors); + if (errorcb == NULL) { + Py_XDECREF(ucvt); + return NULL; + } + + if (self->codec->encinit != NULL && + self->codec->encinit(&state, self->codec->config) != 0) + goto errorexit; + r = multibytecodec_encode(self->codec, &state, + input, NULL, errorcb, + MBENC_FLUSH | MBENC_RESET); + if (r == NULL) + goto errorexit; + + ERROR_DECREF(errorcb); + Py_XDECREF(ucvt); + return make_tuple(r, datalen); + +errorexit: + ERROR_DECREF(errorcb); + Py_XDECREF(ucvt); + return NULL; +} + +/*[clinic input] +_multibytecodec.MultibyteCodec.decode + + input: Py_buffer + errors: str(accept={str, NoneType}) = None + +Decodes 'input'. + +'errors' may be given to set a different error handling scheme. Default is +'strict' meaning that encoding errors raise a UnicodeDecodeError. Other possible +values are 'ignore' and 'replace' as well as any other name registered with +codecs.register_error that is able to handle UnicodeDecodeErrors." +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, + Py_buffer *input, + const char *errors) +/*[clinic end generated code: output=ff419f65bad6cc77 input=e0c78fc7ab190def]*/ +{ + MultibyteCodec_State state; + MultibyteDecodeBuffer buf; + PyObject *errorcb, *res; + const char *data; + Py_ssize_t datalen; + + data = input->buf; + datalen = input->len; + + errorcb = internal_error_callback(errors); + if (errorcb == NULL) { + return NULL; + } + + if (datalen == 0) { + ERROR_DECREF(errorcb); + return make_tuple(PyUnicode_New(0, 0), 0); + } + + _PyUnicodeWriter_Init(&buf.writer); + buf.writer.min_length = datalen; + buf.excobj = NULL; + buf.inbuf = buf.inbuf_top = (unsigned char *)data; + buf.inbuf_end = buf.inbuf_top + datalen; + + if (self->codec->decinit != NULL && + self->codec->decinit(&state, self->codec->config) != 0) + goto errorexit; + + while (buf.inbuf < buf.inbuf_end) { + Py_ssize_t inleft, r; + + inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf); + + r = self->codec->decode(&state, self->codec->config, + &buf.inbuf, inleft, &buf.writer); + if (r == 0) + break; + else if (multibytecodec_decerror(self->codec, &state, + &buf, errorcb, r)) + goto errorexit; + } + + res = _PyUnicodeWriter_Finish(&buf.writer); + if (res == NULL) + goto errorexit; + + Py_XDECREF(buf.excobj); + ERROR_DECREF(errorcb); + return make_tuple(res, datalen); + +errorexit: + ERROR_DECREF(errorcb); + Py_XDECREF(buf.excobj); + _PyUnicodeWriter_Dealloc(&buf.writer); + + return NULL; +} + +static struct PyMethodDef multibytecodec_methods[] = { + _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF + {NULL, NULL}, +}; + +static void +multibytecodec_dealloc(MultibyteCodecObject *self) +{ + PyObject_Del(self); +} + +static PyTypeObject MultibyteCodec_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MultibyteCodec", /* tp_name */ + sizeof(MultibyteCodecObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)multibytecodec_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iterext */ + multibytecodec_methods, /* tp_methods */ +}; + + +/** + * Utility functions for stateful codec mechanism + */ + +#define STATEFUL_DCTX(o) ((MultibyteStatefulDecoderContext *)(o)) +#define STATEFUL_ECTX(o) ((MultibyteStatefulEncoderContext *)(o)) + +static PyObject * +encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, + PyObject *unistr, int final) +{ + PyObject *ucvt, *r = NULL; + PyObject *inbuf = NULL; + Py_ssize_t inpos, datalen; + PyObject *origpending = NULL; + + if (PyUnicode_Check(unistr)) + ucvt = NULL; + else { + unistr = ucvt = PyObject_Str(unistr); + if (unistr == NULL) + return NULL; + else if (!PyUnicode_Check(unistr)) { + PyErr_SetString(PyExc_TypeError, + "couldn't convert the object to str."); + Py_DECREF(ucvt); + return NULL; + } + } + + if (ctx->pending) { + PyObject *inbuf_tmp; + + Py_INCREF(ctx->pending); + origpending = ctx->pending; + + Py_INCREF(ctx->pending); + inbuf_tmp = ctx->pending; + PyUnicode_Append(&inbuf_tmp, unistr); + if (inbuf_tmp == NULL) + goto errorexit; + Py_CLEAR(ctx->pending); + inbuf = inbuf_tmp; + } + else { + origpending = NULL; + + Py_INCREF(unistr); + inbuf = unistr; + } + if (PyUnicode_READY(inbuf) < 0) + goto errorexit; + inpos = 0; + datalen = PyUnicode_GET_LENGTH(inbuf); + + r = multibytecodec_encode(ctx->codec, &ctx->state, + inbuf, &inpos, + ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0); + if (r == NULL) { + /* recover the original pending buffer */ + Py_XSETREF(ctx->pending, origpending); + origpending = NULL; + goto errorexit; + } + Py_XDECREF(origpending); + + if (inpos < datalen) { + if (datalen - inpos > MAXENCPENDING) { + /* normal codecs can't reach here */ + PyErr_SetString(PyExc_UnicodeError, + "pending buffer overflow"); + goto errorexit; + } + ctx->pending = PyUnicode_Substring(inbuf, inpos, datalen); + if (ctx->pending == NULL) { + /* normal codecs can't reach here */ + goto errorexit; + } + } + + Py_DECREF(inbuf); + Py_XDECREF(ucvt); + return r; + +errorexit: + Py_XDECREF(r); + Py_XDECREF(ucvt); + Py_XDECREF(origpending); + Py_XDECREF(inbuf); + return NULL; +} + +static int +decoder_append_pending(MultibyteStatefulDecoderContext *ctx, + MultibyteDecodeBuffer *buf) +{ + Py_ssize_t npendings; + + npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); + if (npendings + ctx->pendingsize > MAXDECPENDING || + npendings > PY_SSIZE_T_MAX - ctx->pendingsize) { + PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow"); + return -1; + } + memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings); + ctx->pendingsize += npendings; + return 0; +} + +static int +decoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data, + Py_ssize_t size) +{ + buf->inbuf = buf->inbuf_top = (const unsigned char *)data; + buf->inbuf_end = buf->inbuf_top + size; + buf->writer.min_length += size; + return 0; +} + +static int +decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, + MultibyteDecodeBuffer *buf) +{ + while (buf->inbuf < buf->inbuf_end) { + Py_ssize_t inleft; + Py_ssize_t r; + + inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); + + r = ctx->codec->decode(&ctx->state, ctx->codec->config, + &buf->inbuf, inleft, &buf->writer); + if (r == 0 || r == MBERR_TOOFEW) + break; + else if (multibytecodec_decerror(ctx->codec, &ctx->state, + buf, ctx->errors, r)) + return -1; + } + return 0; +} + + +/*[clinic input] + class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/ + +/*[clinic input] +_multibytecodec.MultibyteIncrementalEncoder.encode + + input: object + final: bool(accept={int}) = False +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, + PyObject *input, + int final) +/*[clinic end generated code: output=123361b6c505e2c1 input=093a1ddbb2fc6721]*/ +{ + return encoder_encode_stateful(STATEFUL_ECTX(self), input, final); +} + +/*[clinic input] +_multibytecodec.MultibyteIncrementalEncoder.getstate [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, - PyObject *sizeobj) -/*[clinic end generated code: output=4fbfaae1ed457a11 input=41ccc64f9bb0cec3]*/ +_multibytecodec_MultibyteIncrementalEncoder_getstate_impl(MultibyteIncrementalEncoderObject *self) +/*[clinic end generated code: output=9794a5ace70d7048 input=4a2a82874ffa40bb]*/ { - Py_ssize_t size; + /* state made up of 1 byte for buffer size, up to MAXENCPENDING*4 bytes + for UTF-8 encoded buffer (each character can use up to 4 + bytes), and required bytes for MultibyteCodec_State.c. A byte + array is used to avoid different compilers generating different + values for the same state, e.g. as a result of struct padding. + */ + unsigned char statebytes[1 + MAXENCPENDING*4 + sizeof(self->state.c)]; + Py_ssize_t statesize; + const char *pendingbuffer = NULL; + Py_ssize_t pendingsize; - if (sizeobj == Py_None) - size = -1; - else if (PyLong_Check(sizeobj)) - size = PyLong_AsSsize_t(sizeobj); - else { - PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); - return NULL; + if (self->pending != NULL) { + pendingbuffer = PyUnicode_AsUTF8AndSize(self->pending, &pendingsize); + if (pendingbuffer == NULL) { + return NULL; + } + if (pendingsize > MAXENCPENDING*4) { + PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); + return NULL; + } + statebytes[0] = (unsigned char)pendingsize; + memcpy(statebytes + 1, pendingbuffer, pendingsize); + statesize = 1 + pendingsize; + } else { + statebytes[0] = 0; + statesize = 1; } + memcpy(statebytes+statesize, self->state.c, + sizeof(self->state.c)); + statesize += sizeof(self->state.c); - if (size == -1 && PyErr_Occurred()) - return NULL; - - return mbstreamreader_iread(self, "readline", size); + return (PyObject *)_PyLong_FromByteArray(statebytes, statesize, + 1 /* little-endian */ , + 0 /* unsigned */ ); } /*[clinic input] - _multibytecodec.MultibyteStreamReader.readlines - - sizehintobj: object = None +_multibytecodec.MultibyteIncrementalEncoder.setstate + state as statelong: object(type='PyLongObject *', subclass_of='&PyLong_Type') / [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, - PyObject *sizehintobj) -/*[clinic end generated code: output=e7c4310768ed2ad4 input=54932f5d4d88e880]*/ +_multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEncoderObject *self, + PyLongObject *statelong) +/*[clinic end generated code: output=4e5e98ac1f4039ca input=c80fb5830d4d2f76]*/ { - PyObject *r, *sr; - Py_ssize_t sizehint; + PyObject *pending = NULL; + unsigned char statebytes[1 + MAXENCPENDING*4 + sizeof(self->state.c)]; - if (sizehintobj == Py_None) - sizehint = -1; - else if (PyLong_Check(sizehintobj)) - sizehint = PyLong_AsSsize_t(sizehintobj); - else { - PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); - return NULL; + if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes), + 1 /* little-endian */ , + 0 /* unsigned */ ) < 0) { + goto errorexit; } - if (sizehint == -1 && PyErr_Occurred()) - return NULL; - - r = mbstreamreader_iread(self, "read", sizehint); - if (r == NULL) - return NULL; - - sr = PyUnicode_Splitlines(r, 1); - Py_DECREF(r); - return sr; -} - -/*[clinic input] - _multibytecodec.MultibyteStreamReader.reset -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self) -/*[clinic end generated code: output=138490370a680abc input=5d4140db84b5e1e2]*/ -{ - if (self->codec->decreset != NULL && - self->codec->decreset(&self->state, self->codec->config) != 0) - return NULL; - self->pendingsize = 0; - - Py_RETURN_NONE; -} - -static struct PyMethodDef mbstreamreader_methods[] = { - _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF - _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF - _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF - _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF - {NULL, NULL}, -}; - -static PyMemberDef mbstreamreader_members[] = { - {"stream", T_OBJECT, - offsetof(MultibyteStreamReaderObject, stream), - READONLY, NULL}, - {NULL,} -}; - -static PyObject * -mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - MultibyteStreamReaderObject *self; - PyObject *stream, *codec = NULL; - char *errors = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader", - streamkwarglist, &stream, &errors)) - return NULL; - - self = (MultibyteStreamReaderObject *)type->tp_alloc(type, 0); - if (self == NULL) + if (statebytes[0] > MAXENCPENDING*4) { + PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); return NULL; + } - codec = PyObject_GetAttrString((PyObject *)type, "codec"); - if (codec == NULL) - goto errorexit; - if (!MultibyteCodec_Check(codec)) { - PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + pending = PyUnicode_DecodeUTF8((const char *)statebytes+1, + statebytes[0], "strict"); + if (pending == NULL) { goto errorexit; } - self->codec = ((MultibyteCodecObject *)codec)->codec; - self->stream = stream; - Py_INCREF(stream); - self->pendingsize = 0; - self->errors = internal_error_callback(errors); - if (self->errors == NULL) - goto errorexit; - if (self->codec->decinit != NULL && - self->codec->decinit(&self->state, self->codec->config) != 0) - goto errorexit; + Py_CLEAR(self->pending); + self->pending = pending; + memcpy(self->state.c, statebytes+1+statebytes[0], + sizeof(self->state.c)); - Py_DECREF(codec); - return (PyObject *)self; + Py_RETURN_NONE; errorexit: - Py_XDECREF(self); - Py_XDECREF(codec); + Py_XDECREF(pending); return NULL; } -static int -mbstreamreader_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - return 0; -} - -static int -mbstreamreader_traverse(MultibyteStreamReaderObject *self, - visitproc visit, void *arg) -{ - if (ERROR_ISCUSTOM(self->errors)) - Py_VISIT(self->errors); - Py_VISIT(self->stream); - return 0; -} - -static void -mbstreamreader_dealloc(MultibyteStreamReaderObject *self) -{ - PyObject_GC_UnTrack(self); - ERROR_DECREF(self->errors); - Py_XDECREF(self->stream); - Py_TYPE(self)->tp_free(self); -} - -static PyTypeObject MultibyteStreamReader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteStreamReader", /* tp_name */ - sizeof(MultibyteStreamReaderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbstreamreader_dealloc, /* tp_dealloc */ +/*[clinic input] +_multibytecodec.MultibyteIncrementalEncoder.reset +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self) +/*[clinic end generated code: output=b4125d8f537a253f input=930f06760707b6ea]*/ +{ + /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */ + unsigned char buffer[4], *outbuf; + Py_ssize_t r; + if (self->codec->encreset != NULL) { + outbuf = buffer; + r = self->codec->encreset(&self->state, self->codec->config, + &outbuf, sizeof(buffer)); + if (r != 0) + return NULL; + } + Py_CLEAR(self->pending); + Py_RETURN_NONE; +} + +static struct PyMethodDef mbiencoder_methods[] = { + _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_GETSTATE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_SETSTATE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF + {NULL, NULL}, +}; + +static PyObject * +mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + MultibyteIncrementalEncoderObject *self; + PyObject *codec = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder", + incnewkwarglist, &errors)) + return NULL; + + self = (MultibyteIncrementalEncoderObject *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + codec = PyObject_GetAttrString((PyObject *)type, "codec"); + if (codec == NULL) + goto errorexit; + if (!MultibyteCodec_Check(codec)) { + PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + goto errorexit; + } + + self->codec = ((MultibyteCodecObject *)codec)->codec; + self->pending = NULL; + self->errors = internal_error_callback(errors); + if (self->errors == NULL) + goto errorexit; + if (self->codec->encinit != NULL && + self->codec->encinit(&self->state, self->codec->config) != 0) + goto errorexit; + + Py_DECREF(codec); + return (PyObject *)self; + +errorexit: + Py_XDECREF(self); + Py_XDECREF(codec); + return NULL; +} + +static int +mbiencoder_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + return 0; +} + +static int +mbiencoder_traverse(MultibyteIncrementalEncoderObject *self, + visitproc visit, void *arg) +{ + if (ERROR_ISCUSTOM(self->errors)) + Py_VISIT(self->errors); + return 0; +} + +static void +mbiencoder_dealloc(MultibyteIncrementalEncoderObject *self) +{ + PyObject_GC_UnTrack(self); + ERROR_DECREF(self->errors); + Py_CLEAR(self->pending); + Py_TYPE(self)->tp_free(self); +} + +static PyTypeObject MultibyteIncrementalEncoder_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MultibyteIncrementalEncoder", /* tp_name */ + sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)mbiencoder_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)mbstreamreader_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbstreamreader_methods, /* tp_methods */ - mbstreamreader_members, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbstreamreader_init, /* tp_init */ - 0, /* tp_alloc */ - mbstreamreader_new, /* tp_new */ -}; - - -/*[clinic input] - class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "&MultibyteStreamWriter_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cde22780a215d6ac]*/ - -static int -mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, - PyObject *unistr) -{ - PyObject *str, *wr; - - str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0); - if (str == NULL) - return -1; - - wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, str); - Py_DECREF(str); - if (wr == NULL) - return -1; - - Py_DECREF(wr); - return 0; -} - -/*[clinic input] - _multibytecodec.MultibyteStreamWriter.write - - strobj: object - / -[clinic start generated code]*/ - -static PyObject * -_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, - PyObject *strobj) -/*[clinic end generated code: output=e13ae841c895251e input=551dc4c018c10a2b]*/ -{ - if (mbstreamwriter_iwrite(self, strobj)) - return NULL; - else - Py_RETURN_NONE; -} - -/*[clinic input] - _multibytecodec.MultibyteStreamWriter.writelines - - lines: object - / + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)mbiencoder_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iterext */ + mbiencoder_methods, /* tp_methods */ + 0, /* tp_members */ + codecctx_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + mbiencoder_init, /* tp_init */ + 0, /* tp_alloc */ + mbiencoder_new, /* tp_new */ +}; + + +/*[clinic input] + class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "&MultibyteIncrementalDecoder_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f6003faaf2cea692]*/ + +/*[clinic input] +_multibytecodec.MultibyteIncrementalDecoder.decode + + input: Py_buffer + final: bool(accept={int}) = False +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, + Py_buffer *input, + int final) +/*[clinic end generated code: output=b9b9090e8a9ce2ba input=c9132b24d503eb1d]*/ +{ + MultibyteDecodeBuffer buf; + char *data, *wdata = NULL; + Py_ssize_t wsize, size, origpending; + PyObject *res; + + data = input->buf; + size = input->len; + + _PyUnicodeWriter_Init(&buf.writer); + buf.excobj = NULL; + origpending = self->pendingsize; + + if (self->pendingsize == 0) { + wsize = size; + wdata = data; + } + else { + if (size > PY_SSIZE_T_MAX - self->pendingsize) { + PyErr_NoMemory(); + goto errorexit; + } + wsize = size + self->pendingsize; + wdata = PyMem_Malloc(wsize); + if (wdata == NULL) { + PyErr_NoMemory(); + goto errorexit; + } + memcpy(wdata, self->pending, self->pendingsize); + memcpy(wdata + self->pendingsize, data, size); + self->pendingsize = 0; + } + + if (decoder_prepare_buffer(&buf, wdata, wsize) != 0) + goto errorexit; + + if (decoder_feed_buffer(STATEFUL_DCTX(self), &buf)) + goto errorexit; + + if (final && buf.inbuf < buf.inbuf_end) { + if (multibytecodec_decerror(self->codec, &self->state, + &buf, self->errors, MBERR_TOOFEW)) { + /* recover the original pending buffer */ + memcpy(self->pending, wdata, origpending); + self->pendingsize = origpending; + goto errorexit; + } + } + + if (buf.inbuf < buf.inbuf_end) { /* pending sequence still exists */ + if (decoder_append_pending(STATEFUL_DCTX(self), &buf) != 0) + goto errorexit; + } + + res = _PyUnicodeWriter_Finish(&buf.writer); + if (res == NULL) + goto errorexit; + + if (wdata != data) + PyMem_Del(wdata); + Py_XDECREF(buf.excobj); + return res; + +errorexit: + if (wdata != NULL && wdata != data) + PyMem_Del(wdata); + Py_XDECREF(buf.excobj); + _PyUnicodeWriter_Dealloc(&buf.writer); + return NULL; +} + +/*[clinic input] +_multibytecodec.MultibyteIncrementalDecoder.getstate [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, - PyObject *lines) -/*[clinic end generated code: output=e5c4285ac8e7d522 input=57797fe7008d4e96]*/ +_multibytecodec_MultibyteIncrementalDecoder_getstate_impl(MultibyteIncrementalDecoderObject *self) +/*[clinic end generated code: output=255009c4713b7f82 input=4006aa49bddbaa75]*/ { - PyObject *strobj; - int i, r; + PyObject *buffer; + PyObject *statelong; - if (!PySequence_Check(lines)) { - PyErr_SetString(PyExc_TypeError, - "arg must be a sequence object"); + buffer = PyBytes_FromStringAndSize((const char *)self->pending, + self->pendingsize); + if (buffer == NULL) { return NULL; } - for (i = 0; i < PySequence_Length(lines); i++) { - /* length can be changed even within this loop */ - strobj = PySequence_GetItem(lines, i); - if (strobj == NULL) - return NULL; - - r = mbstreamwriter_iwrite(self, strobj); - Py_DECREF(strobj); - if (r == -1) - return NULL; - } - /* PySequence_Length() can fail */ - if (PyErr_Occurred()) + statelong = (PyObject *)_PyLong_FromByteArray(self->state.c, + sizeof(self->state.c), + 1 /* little-endian */ , + 0 /* unsigned */ ); + if (statelong == NULL) { + Py_DECREF(buffer); return NULL; + } - Py_RETURN_NONE; + return Py_BuildValue("NN", buffer, statelong); } /*[clinic input] - _multibytecodec.MultibyteStreamWriter.reset +_multibytecodec.MultibyteIncrementalDecoder.setstate + state: object(subclass_of='&PyTuple_Type') + / [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self) -/*[clinic end generated code: output=8f54a4d9b03db5ff input=b56dbcbaf35cc10c]*/ +_multibytecodec_MultibyteIncrementalDecoder_setstate_impl(MultibyteIncrementalDecoderObject *self, + PyObject *state) +/*[clinic end generated code: output=106b2fbca3e2dcc2 input=e5d794e8baba1a47]*/ { - PyObject *pwrt; - - if (!self->pending) - Py_RETURN_NONE; + PyObject *buffer; + PyLongObject *statelong; + Py_ssize_t buffersize; + const char *bufferstr; + unsigned char statebytes[8]; - pwrt = multibytecodec_encode(self->codec, &self->state, - self->pending, NULL, self->errors, - MBENC_FLUSH | MBENC_RESET); - /* some pending buffer can be truncated when UnicodeEncodeError is - * raised on 'strict' mode. but, 'reset' method is designed to - * reset the pending buffer or states so failed string sequence - * ought to be missed */ - Py_CLEAR(self->pending); - if (pwrt == NULL) + if (!PyArg_ParseTuple(state, "SO!;setstate(): illegal state argument", + &buffer, &PyLong_Type, &statelong)) + { return NULL; - - assert(PyBytes_Check(pwrt)); - if (PyBytes_Size(pwrt) > 0) { - PyObject *wr; - - wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, pwrt); - if (wr == NULL) { - Py_DECREF(pwrt); - return NULL; - } } - Py_DECREF(pwrt); - - Py_RETURN_NONE; -} -static PyObject * -mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - MultibyteStreamWriterObject *self; - PyObject *stream, *codec = NULL; - char *errors = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter", - streamkwarglist, &stream, &errors)) - return NULL; - - self = (MultibyteStreamWriterObject *)type->tp_alloc(type, 0); - if (self == NULL) + if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes), + 1 /* little-endian */ , + 0 /* unsigned */ ) < 0) { return NULL; - - codec = PyObject_GetAttrString((PyObject *)type, "codec"); - if (codec == NULL) - goto errorexit; - if (!MultibyteCodec_Check(codec)) { - PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); - goto errorexit; } - self->codec = ((MultibyteCodecObject *)codec)->codec; - self->stream = stream; - Py_INCREF(stream); - self->pending = NULL; - self->errors = internal_error_callback(errors); - if (self->errors == NULL) - goto errorexit; - if (self->codec->encinit != NULL && - self->codec->encinit(&self->state, self->codec->config) != 0) - goto errorexit; - - Py_DECREF(codec); - return (PyObject *)self; - -errorexit: - Py_XDECREF(self); - Py_XDECREF(codec); - return NULL; -} - -static int -mbstreamwriter_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - return 0; -} - -static int -mbstreamwriter_traverse(MultibyteStreamWriterObject *self, - visitproc visit, void *arg) -{ - if (ERROR_ISCUSTOM(self->errors)) - Py_VISIT(self->errors); - Py_VISIT(self->stream); - return 0; -} - -static void -mbstreamwriter_dealloc(MultibyteStreamWriterObject *self) -{ - PyObject_GC_UnTrack(self); - ERROR_DECREF(self->errors); - Py_XDECREF(self->stream); - Py_TYPE(self)->tp_free(self); -} - -static struct PyMethodDef mbstreamwriter_methods[] = { - _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF - _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF - _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF - {NULL, NULL}, -}; - -static PyMemberDef mbstreamwriter_members[] = { - {"stream", T_OBJECT, - offsetof(MultibyteStreamWriterObject, stream), - READONLY, NULL}, - {NULL,} -}; - -static PyTypeObject MultibyteStreamWriter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteStreamWriter", /* tp_name */ - sizeof(MultibyteStreamWriterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbstreamwriter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)mbstreamwriter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbstreamwriter_methods, /* tp_methods */ - mbstreamwriter_members, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbstreamwriter_init, /* tp_init */ - 0, /* tp_alloc */ - mbstreamwriter_new, /* tp_new */ -}; - - -/*[clinic input] -_multibytecodec.__create_codec - - arg: object - / -[clinic start generated code]*/ - -static PyObject * -_multibytecodec___create_codec(PyObject *module, PyObject *arg) -/*[clinic end generated code: output=cfa3dce8260e809d input=6840b2a6b183fcfa]*/ -{ - MultibyteCodecObject *self; - MultibyteCodec *codec; - - if (!PyCapsule_IsValid(arg, PyMultibyteCodec_CAPSULE_NAME)) { - PyErr_SetString(PyExc_ValueError, "argument type invalid"); + buffersize = PyBytes_Size(buffer); + if (buffersize == -1) { return NULL; } - codec = PyCapsule_GetPointer(arg, PyMultibyteCodec_CAPSULE_NAME); - if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) + if (buffersize > MAXDECPENDING) { + PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); return NULL; + } - self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type); - if (self == NULL) + bufferstr = PyBytes_AsString(buffer); + if (bufferstr == NULL) { return NULL; - self->codec = codec; + } + self->pendingsize = buffersize; + memcpy(self->pending, bufferstr, self->pendingsize); + memcpy(self->state.c, statebytes, sizeof(statebytes)); - return (PyObject *)self; + Py_RETURN_NONE; } -static struct PyMethodDef __methods[] = { - _MULTIBYTECODEC___CREATE_CODEC_METHODDEF - {NULL, NULL}, -}; - - -static struct PyModuleDef _multibytecodecmodule = { - PyModuleDef_HEAD_INIT, - "_multibytecodec", - NULL, - -1, - __methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__multibytecodec(void) -{ - PyObject *m; - PyTypeObject *typelist[] = { - &MultibyteIncrementalEncoder_Type, - &MultibyteIncrementalDecoder_Type, - &MultibyteStreamReader_Type, +/*[clinic input] +_multibytecodec.MultibyteIncrementalDecoder.reset +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self) +/*[clinic end generated code: output=da423b1782c23ed1 input=3b63b3be85b2fb45]*/ +{ + if (self->codec->decreset != NULL && + self->codec->decreset(&self->state, self->codec->config) != 0) + return NULL; + self->pendingsize = 0; + + Py_RETURN_NONE; +} + +static struct PyMethodDef mbidecoder_methods[] = { + _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_GETSTATE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_SETSTATE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF + {NULL, NULL}, +}; + +static PyObject * +mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + MultibyteIncrementalDecoderObject *self; + PyObject *codec = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder", + incnewkwarglist, &errors)) + return NULL; + + self = (MultibyteIncrementalDecoderObject *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + codec = PyObject_GetAttrString((PyObject *)type, "codec"); + if (codec == NULL) + goto errorexit; + if (!MultibyteCodec_Check(codec)) { + PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + goto errorexit; + } + + self->codec = ((MultibyteCodecObject *)codec)->codec; + self->pendingsize = 0; + self->errors = internal_error_callback(errors); + if (self->errors == NULL) + goto errorexit; + if (self->codec->decinit != NULL && + self->codec->decinit(&self->state, self->codec->config) != 0) + goto errorexit; + + Py_DECREF(codec); + return (PyObject *)self; + +errorexit: + Py_XDECREF(self); + Py_XDECREF(codec); + return NULL; +} + +static int +mbidecoder_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + return 0; +} + +static int +mbidecoder_traverse(MultibyteIncrementalDecoderObject *self, + visitproc visit, void *arg) +{ + if (ERROR_ISCUSTOM(self->errors)) + Py_VISIT(self->errors); + return 0; +} + +static void +mbidecoder_dealloc(MultibyteIncrementalDecoderObject *self) +{ + PyObject_GC_UnTrack(self); + ERROR_DECREF(self->errors); + Py_TYPE(self)->tp_free(self); +} + +static PyTypeObject MultibyteIncrementalDecoder_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MultibyteIncrementalDecoder", /* tp_name */ + sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)mbidecoder_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)mbidecoder_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iterext */ + mbidecoder_methods, /* tp_methods */ + 0, /* tp_members */ + codecctx_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + mbidecoder_init, /* tp_init */ + 0, /* tp_alloc */ + mbidecoder_new, /* tp_new */ +}; + + +/*[clinic input] + class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "MultibyteStreamReader_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d323634b74976f09]*/ + +static PyObject * +mbstreamreader_iread(MultibyteStreamReaderObject *self, + const char *method, Py_ssize_t sizehint) +{ + MultibyteDecodeBuffer buf; + PyObject *cres, *res; + Py_ssize_t rsize; + + if (sizehint == 0) + return PyUnicode_New(0, 0); + + _PyUnicodeWriter_Init(&buf.writer); + buf.excobj = NULL; + cres = NULL; + + for (;;) { + int endoffile; + + if (sizehint < 0) + cres = PyObject_CallMethod(self->stream, + method, NULL); + else + cres = PyObject_CallMethod(self->stream, + method, "i", sizehint); + if (cres == NULL) + goto errorexit; + + if (!PyBytes_Check(cres)) { + PyErr_Format(PyExc_TypeError, + "stream function returned a " + "non-bytes object (%.100s)", + Py_TYPE(cres)->tp_name); + goto errorexit; + } + + endoffile = (PyBytes_GET_SIZE(cres) == 0); + + if (self->pendingsize > 0) { + PyObject *ctr; + char *ctrdata; + + if (PyBytes_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) { + PyErr_NoMemory(); + goto errorexit; + } + rsize = PyBytes_GET_SIZE(cres) + self->pendingsize; + ctr = PyBytes_FromStringAndSize(NULL, rsize); + if (ctr == NULL) + goto errorexit; + ctrdata = PyBytes_AS_STRING(ctr); + memcpy(ctrdata, self->pending, self->pendingsize); + memcpy(ctrdata + self->pendingsize, + PyBytes_AS_STRING(cres), + PyBytes_GET_SIZE(cres)); + Py_DECREF(cres); + cres = ctr; + self->pendingsize = 0; + } + + rsize = PyBytes_GET_SIZE(cres); + if (decoder_prepare_buffer(&buf, PyBytes_AS_STRING(cres), + rsize) != 0) + goto errorexit; + + if (rsize > 0 && decoder_feed_buffer( + (MultibyteStatefulDecoderContext *)self, &buf)) + goto errorexit; + + if (endoffile || sizehint < 0) { + if (buf.inbuf < buf.inbuf_end && + multibytecodec_decerror(self->codec, &self->state, + &buf, self->errors, MBERR_TOOFEW)) + goto errorexit; + } + + if (buf.inbuf < buf.inbuf_end) { /* pending sequence exists */ + if (decoder_append_pending(STATEFUL_DCTX(self), + &buf) != 0) + goto errorexit; + } + + Py_DECREF(cres); + cres = NULL; + + if (sizehint < 0 || buf.writer.pos != 0 || rsize == 0) + break; + + sizehint = 1; /* read 1 more byte and retry */ + } + + res = _PyUnicodeWriter_Finish(&buf.writer); + if (res == NULL) + goto errorexit; + + Py_XDECREF(cres); + Py_XDECREF(buf.excobj); + return res; + +errorexit: + Py_XDECREF(cres); + Py_XDECREF(buf.excobj); + _PyUnicodeWriter_Dealloc(&buf.writer); + return NULL; +} + +/*[clinic input] + _multibytecodec.MultibyteStreamReader.read + + sizeobj: object = None + / +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, + PyObject *sizeobj) +/*[clinic end generated code: output=35621eb75355d5b8 input=015b0d3ff2fca485]*/ +{ + Py_ssize_t size; + + if (sizeobj == Py_None) + size = -1; + else if (PyLong_Check(sizeobj)) + size = PyLong_AsSsize_t(sizeobj); + else { + PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); + return NULL; + } + + if (size == -1 && PyErr_Occurred()) + return NULL; + + return mbstreamreader_iread(self, "read", size); +} + +/*[clinic input] + _multibytecodec.MultibyteStreamReader.readline + + sizeobj: object = None + / +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, + PyObject *sizeobj) +/*[clinic end generated code: output=4fbfaae1ed457a11 input=41ccc64f9bb0cec3]*/ +{ + Py_ssize_t size; + + if (sizeobj == Py_None) + size = -1; + else if (PyLong_Check(sizeobj)) + size = PyLong_AsSsize_t(sizeobj); + else { + PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); + return NULL; + } + + if (size == -1 && PyErr_Occurred()) + return NULL; + + return mbstreamreader_iread(self, "readline", size); +} + +/*[clinic input] + _multibytecodec.MultibyteStreamReader.readlines + + sizehintobj: object = None + / +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, + PyObject *sizehintobj) +/*[clinic end generated code: output=e7c4310768ed2ad4 input=54932f5d4d88e880]*/ +{ + PyObject *r, *sr; + Py_ssize_t sizehint; + + if (sizehintobj == Py_None) + sizehint = -1; + else if (PyLong_Check(sizehintobj)) + sizehint = PyLong_AsSsize_t(sizehintobj); + else { + PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); + return NULL; + } + + if (sizehint == -1 && PyErr_Occurred()) + return NULL; + + r = mbstreamreader_iread(self, "read", sizehint); + if (r == NULL) + return NULL; + + sr = PyUnicode_Splitlines(r, 1); + Py_DECREF(r); + return sr; +} + +/*[clinic input] + _multibytecodec.MultibyteStreamReader.reset +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self) +/*[clinic end generated code: output=138490370a680abc input=5d4140db84b5e1e2]*/ +{ + if (self->codec->decreset != NULL && + self->codec->decreset(&self->state, self->codec->config) != 0) + return NULL; + self->pendingsize = 0; + + Py_RETURN_NONE; +} + +static struct PyMethodDef mbstreamreader_methods[] = { + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF + {NULL, NULL}, +}; + +static PyMemberDef mbstreamreader_members[] = { + {"stream", T_OBJECT, + offsetof(MultibyteStreamReaderObject, stream), + READONLY, NULL}, + {NULL,} +}; + +static PyObject * +mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + MultibyteStreamReaderObject *self; + PyObject *stream, *codec = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader", + streamkwarglist, &stream, &errors)) + return NULL; + + self = (MultibyteStreamReaderObject *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + codec = PyObject_GetAttrString((PyObject *)type, "codec"); + if (codec == NULL) + goto errorexit; + if (!MultibyteCodec_Check(codec)) { + PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + goto errorexit; + } + + self->codec = ((MultibyteCodecObject *)codec)->codec; + self->stream = stream; + Py_INCREF(stream); + self->pendingsize = 0; + self->errors = internal_error_callback(errors); + if (self->errors == NULL) + goto errorexit; + if (self->codec->decinit != NULL && + self->codec->decinit(&self->state, self->codec->config) != 0) + goto errorexit; + + Py_DECREF(codec); + return (PyObject *)self; + +errorexit: + Py_XDECREF(self); + Py_XDECREF(codec); + return NULL; +} + +static int +mbstreamreader_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + return 0; +} + +static int +mbstreamreader_traverse(MultibyteStreamReaderObject *self, + visitproc visit, void *arg) +{ + if (ERROR_ISCUSTOM(self->errors)) + Py_VISIT(self->errors); + Py_VISIT(self->stream); + return 0; +} + +static void +mbstreamreader_dealloc(MultibyteStreamReaderObject *self) +{ + PyObject_GC_UnTrack(self); + ERROR_DECREF(self->errors); + Py_XDECREF(self->stream); + Py_TYPE(self)->tp_free(self); +} + +static PyTypeObject MultibyteStreamReader_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MultibyteStreamReader", /* tp_name */ + sizeof(MultibyteStreamReaderObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)mbstreamreader_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)mbstreamreader_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iterext */ + mbstreamreader_methods, /* tp_methods */ + mbstreamreader_members, /* tp_members */ + codecctx_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + mbstreamreader_init, /* tp_init */ + 0, /* tp_alloc */ + mbstreamreader_new, /* tp_new */ +}; + + +/*[clinic input] + class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "&MultibyteStreamWriter_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cde22780a215d6ac]*/ + +static int +mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, + PyObject *unistr) +{ + PyObject *str, *wr; + + str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0); + if (str == NULL) + return -1; + + wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, str); + Py_DECREF(str); + if (wr == NULL) + return -1; + + Py_DECREF(wr); + return 0; +} + +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.write + + strobj: object + / +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, + PyObject *strobj) +/*[clinic end generated code: output=e13ae841c895251e input=551dc4c018c10a2b]*/ +{ + if (mbstreamwriter_iwrite(self, strobj)) + return NULL; + else + Py_RETURN_NONE; +} + +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.writelines + + lines: object + / +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, + PyObject *lines) +/*[clinic end generated code: output=e5c4285ac8e7d522 input=57797fe7008d4e96]*/ +{ + PyObject *strobj; + int i, r; + + if (!PySequence_Check(lines)) { + PyErr_SetString(PyExc_TypeError, + "arg must be a sequence object"); + return NULL; + } + + for (i = 0; i < PySequence_Length(lines); i++) { + /* length can be changed even within this loop */ + strobj = PySequence_GetItem(lines, i); + if (strobj == NULL) + return NULL; + + r = mbstreamwriter_iwrite(self, strobj); + Py_DECREF(strobj); + if (r == -1) + return NULL; + } + /* PySequence_Length() can fail */ + if (PyErr_Occurred()) + return NULL; + + Py_RETURN_NONE; +} + +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.reset +[clinic start generated code]*/ + +static PyObject * +_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self) +/*[clinic end generated code: output=8f54a4d9b03db5ff input=b56dbcbaf35cc10c]*/ +{ + PyObject *pwrt; + + if (!self->pending) + Py_RETURN_NONE; + + pwrt = multibytecodec_encode(self->codec, &self->state, + self->pending, NULL, self->errors, + MBENC_FLUSH | MBENC_RESET); + /* some pending buffer can be truncated when UnicodeEncodeError is + * raised on 'strict' mode. but, 'reset' method is designed to + * reset the pending buffer or states so failed string sequence + * ought to be missed */ + Py_CLEAR(self->pending); + if (pwrt == NULL) + return NULL; + + assert(PyBytes_Check(pwrt)); + if (PyBytes_Size(pwrt) > 0) { + PyObject *wr; + + wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, pwrt); + if (wr == NULL) { + Py_DECREF(pwrt); + return NULL; + } + } + Py_DECREF(pwrt); + + Py_RETURN_NONE; +} + +static PyObject * +mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + MultibyteStreamWriterObject *self; + PyObject *stream, *codec = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter", + streamkwarglist, &stream, &errors)) + return NULL; + + self = (MultibyteStreamWriterObject *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + codec = PyObject_GetAttrString((PyObject *)type, "codec"); + if (codec == NULL) + goto errorexit; + if (!MultibyteCodec_Check(codec)) { + PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + goto errorexit; + } + + self->codec = ((MultibyteCodecObject *)codec)->codec; + self->stream = stream; + Py_INCREF(stream); + self->pending = NULL; + self->errors = internal_error_callback(errors); + if (self->errors == NULL) + goto errorexit; + if (self->codec->encinit != NULL && + self->codec->encinit(&self->state, self->codec->config) != 0) + goto errorexit; + + Py_DECREF(codec); + return (PyObject *)self; + +errorexit: + Py_XDECREF(self); + Py_XDECREF(codec); + return NULL; +} + +static int +mbstreamwriter_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + return 0; +} + +static int +mbstreamwriter_traverse(MultibyteStreamWriterObject *self, + visitproc visit, void *arg) +{ + if (ERROR_ISCUSTOM(self->errors)) + Py_VISIT(self->errors); + Py_VISIT(self->stream); + return 0; +} + +static void +mbstreamwriter_dealloc(MultibyteStreamWriterObject *self) +{ + PyObject_GC_UnTrack(self); + ERROR_DECREF(self->errors); + Py_XDECREF(self->stream); + Py_TYPE(self)->tp_free(self); +} + +static struct PyMethodDef mbstreamwriter_methods[] = { + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF + {NULL, NULL}, +}; + +static PyMemberDef mbstreamwriter_members[] = { + {"stream", T_OBJECT, + offsetof(MultibyteStreamWriterObject, stream), + READONLY, NULL}, + {NULL,} +}; + +static PyTypeObject MultibyteStreamWriter_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MultibyteStreamWriter", /* tp_name */ + sizeof(MultibyteStreamWriterObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)mbstreamwriter_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)mbstreamwriter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iterext */ + mbstreamwriter_methods, /* tp_methods */ + mbstreamwriter_members, /* tp_members */ + codecctx_getsets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + mbstreamwriter_init, /* tp_init */ + 0, /* tp_alloc */ + mbstreamwriter_new, /* tp_new */ +}; + + +/*[clinic input] +_multibytecodec.__create_codec + + arg: object + / +[clinic start generated code]*/ + +static PyObject * +_multibytecodec___create_codec(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=cfa3dce8260e809d input=6840b2a6b183fcfa]*/ +{ + MultibyteCodecObject *self; + MultibyteCodec *codec; + + if (!PyCapsule_IsValid(arg, PyMultibyteCodec_CAPSULE_NAME)) { + PyErr_SetString(PyExc_ValueError, "argument type invalid"); + return NULL; + } + + codec = PyCapsule_GetPointer(arg, PyMultibyteCodec_CAPSULE_NAME); + if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) + return NULL; + + self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type); + if (self == NULL) + return NULL; + self->codec = codec; + + return (PyObject *)self; +} + +static struct PyMethodDef __methods[] = { + _MULTIBYTECODEC___CREATE_CODEC_METHODDEF + {NULL, NULL}, +}; + + +static struct PyModuleDef _multibytecodecmodule = { + PyModuleDef_HEAD_INIT, + "_multibytecodec", + NULL, + -1, + __methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__multibytecodec(void) +{ + PyObject *m; + PyTypeObject *typelist[] = { + &MultibyteIncrementalEncoder_Type, + &MultibyteIncrementalDecoder_Type, + &MultibyteStreamReader_Type, &MultibyteStreamWriter_Type - }; - - if (PyType_Ready(&MultibyteCodec_Type) < 0) - return NULL; - - m = PyModule_Create(&_multibytecodecmodule); - if (m == NULL) - return NULL; - + }; + + if (PyType_Ready(&MultibyteCodec_Type) < 0) + return NULL; + + m = PyModule_Create(&_multibytecodecmodule); + if (m == NULL) + return NULL; + for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { if (PyModule_AddType(m, typelist[i]) < 0) { - return NULL; + return NULL; } - } - - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; - } - return m; -} + } + + if (PyErr_Occurred()) { + Py_DECREF(m); + m = NULL; + } + return m; +} diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h index 59468210b97..927cd5fc432 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h @@ -1,21 +1,21 @@ -/* - * multibytecodec.h: Common Multibyte Codec Implementation - * - * Written by Hye-Shik Chang - */ - -#ifndef _PYTHON_MULTIBYTECODEC_H_ -#define _PYTHON_MULTIBYTECODEC_H_ -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef uint16_t -typedef uint16_t ucs2_t, DBCHAR; -#else -typedef unsigned short ucs2_t, DBCHAR; -#endif - +/* + * multibytecodec.h: Common Multibyte Codec Implementation + * + * Written by Hye-Shik Chang + */ + +#ifndef _PYTHON_MULTIBYTECODEC_H_ +#define _PYTHON_MULTIBYTECODEC_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef uint16_t +typedef uint16_t ucs2_t, DBCHAR; +#else +typedef unsigned short ucs2_t, DBCHAR; +#endif + /* * A struct that provides 8 bytes of state for multibyte * codecs. Codecs are free to use this how they want. Note: if you @@ -24,116 +24,116 @@ typedef unsigned short ucs2_t, DBCHAR; * getstate doesn't differ between little and big endian CPUs. */ typedef struct { - unsigned char c[8]; -} MultibyteCodec_State; - -typedef int (*mbcodec_init)(const void *config); -typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state, - const void *config, + unsigned char c[8]; +} MultibyteCodec_State; + +typedef int (*mbcodec_init)(const void *config); +typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state, + const void *config, int kind, const void *data, - Py_ssize_t *inpos, Py_ssize_t inlen, - unsigned char **outbuf, Py_ssize_t outleft, - int flags); -typedef int (*mbencodeinit_func)(MultibyteCodec_State *state, - const void *config); -typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state, - const void *config, - unsigned char **outbuf, Py_ssize_t outleft); -typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state, - const void *config, - const unsigned char **inbuf, Py_ssize_t inleft, - _PyUnicodeWriter *writer); -typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state, - const void *config); -typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state, - const void *config); - -typedef struct { - const char *encoding; - const void *config; - mbcodec_init codecinit; - mbencode_func encode; - mbencodeinit_func encinit; - mbencodereset_func encreset; - mbdecode_func decode; - mbdecodeinit_func decinit; - mbdecodereset_func decreset; -} MultibyteCodec; - -typedef struct { - PyObject_HEAD - MultibyteCodec *codec; -} MultibyteCodecObject; - + Py_ssize_t *inpos, Py_ssize_t inlen, + unsigned char **outbuf, Py_ssize_t outleft, + int flags); +typedef int (*mbencodeinit_func)(MultibyteCodec_State *state, + const void *config); +typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state, + const void *config, + unsigned char **outbuf, Py_ssize_t outleft); +typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state, + const void *config, + const unsigned char **inbuf, Py_ssize_t inleft, + _PyUnicodeWriter *writer); +typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state, + const void *config); +typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state, + const void *config); + +typedef struct { + const char *encoding; + const void *config; + mbcodec_init codecinit; + mbencode_func encode; + mbencodeinit_func encinit; + mbencodereset_func encreset; + mbdecode_func decode; + mbdecodeinit_func decinit; + mbdecodereset_func decreset; +} MultibyteCodec; + +typedef struct { + PyObject_HEAD + MultibyteCodec *codec; +} MultibyteCodecObject; + #define MultibyteCodec_Check(op) Py_IS_TYPE((op), &MultibyteCodec_Type) - -#define _MultibyteStatefulCodec_HEAD \ - PyObject_HEAD \ - MultibyteCodec *codec; \ - MultibyteCodec_State state; \ - PyObject *errors; -typedef struct { - _MultibyteStatefulCodec_HEAD -} MultibyteStatefulCodecContext; - -#define MAXENCPENDING 2 -#define _MultibyteStatefulEncoder_HEAD \ - _MultibyteStatefulCodec_HEAD \ - PyObject *pending; -typedef struct { - _MultibyteStatefulEncoder_HEAD -} MultibyteStatefulEncoderContext; - -#define MAXDECPENDING 8 -#define _MultibyteStatefulDecoder_HEAD \ - _MultibyteStatefulCodec_HEAD \ - unsigned char pending[MAXDECPENDING]; \ - Py_ssize_t pendingsize; -typedef struct { - _MultibyteStatefulDecoder_HEAD -} MultibyteStatefulDecoderContext; - -typedef struct { - _MultibyteStatefulEncoder_HEAD -} MultibyteIncrementalEncoderObject; - -typedef struct { - _MultibyteStatefulDecoder_HEAD -} MultibyteIncrementalDecoderObject; - -typedef struct { - _MultibyteStatefulDecoder_HEAD - PyObject *stream; -} MultibyteStreamReaderObject; - -typedef struct { - _MultibyteStatefulEncoder_HEAD - PyObject *stream; -} MultibyteStreamWriterObject; - -/* positive values for illegal sequences */ -#define MBERR_TOOSMALL (-1) /* insufficient output buffer space */ -#define MBERR_TOOFEW (-2) /* incomplete input buffer */ -#define MBERR_INTERNAL (-3) /* internal runtime error */ -#define MBERR_EXCEPTION (-4) /* an exception has been raised */ - -#define ERROR_STRICT (PyObject *)(1) -#define ERROR_IGNORE (PyObject *)(2) -#define ERROR_REPLACE (PyObject *)(3) -#define ERROR_ISCUSTOM(p) ((p) < ERROR_STRICT || ERROR_REPLACE < (p)) -#define ERROR_DECREF(p) \ - do { \ - if (p != NULL && ERROR_ISCUSTOM(p)) \ - Py_DECREF(p); \ - } while (0); - -#define MBENC_FLUSH 0x0001 /* encode all characters encodable */ -#define MBENC_MAX MBENC_FLUSH - -#define PyMultibyteCodec_CAPSULE_NAME "multibytecodec.__map_*" - - -#ifdef __cplusplus -} -#endif -#endif + +#define _MultibyteStatefulCodec_HEAD \ + PyObject_HEAD \ + MultibyteCodec *codec; \ + MultibyteCodec_State state; \ + PyObject *errors; +typedef struct { + _MultibyteStatefulCodec_HEAD +} MultibyteStatefulCodecContext; + +#define MAXENCPENDING 2 +#define _MultibyteStatefulEncoder_HEAD \ + _MultibyteStatefulCodec_HEAD \ + PyObject *pending; +typedef struct { + _MultibyteStatefulEncoder_HEAD +} MultibyteStatefulEncoderContext; + +#define MAXDECPENDING 8 +#define _MultibyteStatefulDecoder_HEAD \ + _MultibyteStatefulCodec_HEAD \ + unsigned char pending[MAXDECPENDING]; \ + Py_ssize_t pendingsize; +typedef struct { + _MultibyteStatefulDecoder_HEAD +} MultibyteStatefulDecoderContext; + +typedef struct { + _MultibyteStatefulEncoder_HEAD +} MultibyteIncrementalEncoderObject; + +typedef struct { + _MultibyteStatefulDecoder_HEAD +} MultibyteIncrementalDecoderObject; + +typedef struct { + _MultibyteStatefulDecoder_HEAD + PyObject *stream; +} MultibyteStreamReaderObject; + +typedef struct { + _MultibyteStatefulEncoder_HEAD + PyObject *stream; +} MultibyteStreamWriterObject; + +/* positive values for illegal sequences */ +#define MBERR_TOOSMALL (-1) /* insufficient output buffer space */ +#define MBERR_TOOFEW (-2) /* incomplete input buffer */ +#define MBERR_INTERNAL (-3) /* internal runtime error */ +#define MBERR_EXCEPTION (-4) /* an exception has been raised */ + +#define ERROR_STRICT (PyObject *)(1) +#define ERROR_IGNORE (PyObject *)(2) +#define ERROR_REPLACE (PyObject *)(3) +#define ERROR_ISCUSTOM(p) ((p) < ERROR_STRICT || ERROR_REPLACE < (p)) +#define ERROR_DECREF(p) \ + do { \ + if (p != NULL && ERROR_ISCUSTOM(p)) \ + Py_DECREF(p); \ + } while (0); + +#define MBENC_FLUSH 0x0001 /* encode all characters encodable */ +#define MBENC_MAX MBENC_FLUSH + +#define PyMultibyteCodec_CAPSULE_NAME "multibytecodec.__map_*" + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/contrib/tools/python3/src/Modules/clinic/_abc.c.h b/contrib/tools/python3/src/Modules/clinic/_abc.c.h index 62c6552ba64..ff7faf100f8 100644 --- a/contrib/tools/python3/src/Modules/clinic/_abc.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_abc.c.h @@ -1,162 +1,162 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_abc__reset_registry__doc__, -"_reset_registry($module, self, /)\n" -"--\n" -"\n" -"Internal ABC helper to reset registry of a given class.\n" -"\n" -"Should be only used by refleak.py"); - -#define _ABC__RESET_REGISTRY_METHODDEF \ - {"_reset_registry", (PyCFunction)_abc__reset_registry, METH_O, _abc__reset_registry__doc__}, - -PyDoc_STRVAR(_abc__reset_caches__doc__, -"_reset_caches($module, self, /)\n" -"--\n" -"\n" -"Internal ABC helper to reset both caches of a given class.\n" -"\n" -"Should be only used by refleak.py"); - -#define _ABC__RESET_CACHES_METHODDEF \ - {"_reset_caches", (PyCFunction)_abc__reset_caches, METH_O, _abc__reset_caches__doc__}, - -PyDoc_STRVAR(_abc__get_dump__doc__, -"_get_dump($module, self, /)\n" -"--\n" -"\n" -"Internal ABC helper for cache and registry debugging.\n" -"\n" -"Return shallow copies of registry, of both caches, and\n" -"negative cache version. Don\'t call this function directly,\n" -"instead use ABC._dump_registry() for a nice repr."); - -#define _ABC__GET_DUMP_METHODDEF \ - {"_get_dump", (PyCFunction)_abc__get_dump, METH_O, _abc__get_dump__doc__}, - -PyDoc_STRVAR(_abc__abc_init__doc__, -"_abc_init($module, self, /)\n" -"--\n" -"\n" -"Internal ABC helper for class set-up. Should be never used outside abc module."); - -#define _ABC__ABC_INIT_METHODDEF \ - {"_abc_init", (PyCFunction)_abc__abc_init, METH_O, _abc__abc_init__doc__}, - -PyDoc_STRVAR(_abc__abc_register__doc__, -"_abc_register($module, self, subclass, /)\n" -"--\n" -"\n" -"Internal ABC helper for subclasss registration. Should be never used outside abc module."); - -#define _ABC__ABC_REGISTER_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_abc__reset_registry__doc__, +"_reset_registry($module, self, /)\n" +"--\n" +"\n" +"Internal ABC helper to reset registry of a given class.\n" +"\n" +"Should be only used by refleak.py"); + +#define _ABC__RESET_REGISTRY_METHODDEF \ + {"_reset_registry", (PyCFunction)_abc__reset_registry, METH_O, _abc__reset_registry__doc__}, + +PyDoc_STRVAR(_abc__reset_caches__doc__, +"_reset_caches($module, self, /)\n" +"--\n" +"\n" +"Internal ABC helper to reset both caches of a given class.\n" +"\n" +"Should be only used by refleak.py"); + +#define _ABC__RESET_CACHES_METHODDEF \ + {"_reset_caches", (PyCFunction)_abc__reset_caches, METH_O, _abc__reset_caches__doc__}, + +PyDoc_STRVAR(_abc__get_dump__doc__, +"_get_dump($module, self, /)\n" +"--\n" +"\n" +"Internal ABC helper for cache and registry debugging.\n" +"\n" +"Return shallow copies of registry, of both caches, and\n" +"negative cache version. Don\'t call this function directly,\n" +"instead use ABC._dump_registry() for a nice repr."); + +#define _ABC__GET_DUMP_METHODDEF \ + {"_get_dump", (PyCFunction)_abc__get_dump, METH_O, _abc__get_dump__doc__}, + +PyDoc_STRVAR(_abc__abc_init__doc__, +"_abc_init($module, self, /)\n" +"--\n" +"\n" +"Internal ABC helper for class set-up. Should be never used outside abc module."); + +#define _ABC__ABC_INIT_METHODDEF \ + {"_abc_init", (PyCFunction)_abc__abc_init, METH_O, _abc__abc_init__doc__}, + +PyDoc_STRVAR(_abc__abc_register__doc__, +"_abc_register($module, self, subclass, /)\n" +"--\n" +"\n" +"Internal ABC helper for subclasss registration. Should be never used outside abc module."); + +#define _ABC__ABC_REGISTER_METHODDEF \ {"_abc_register", (PyCFunction)(void(*)(void))_abc__abc_register, METH_FASTCALL, _abc__abc_register__doc__}, - -static PyObject * -_abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass); - -static PyObject * -_abc__abc_register(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *self; - PyObject *subclass; - + +static PyObject * +_abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass); + +static PyObject * +_abc__abc_register(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *self; + PyObject *subclass; + if (!_PyArg_CheckPositional("_abc_register", nargs, 2, 2)) { - goto exit; - } + goto exit; + } self = args[0]; subclass = args[1]; - return_value = _abc__abc_register_impl(module, self, subclass); - -exit: - return return_value; -} - -PyDoc_STRVAR(_abc__abc_instancecheck__doc__, -"_abc_instancecheck($module, self, instance, /)\n" -"--\n" -"\n" -"Internal ABC helper for instance checks. Should be never used outside abc module."); - -#define _ABC__ABC_INSTANCECHECK_METHODDEF \ + return_value = _abc__abc_register_impl(module, self, subclass); + +exit: + return return_value; +} + +PyDoc_STRVAR(_abc__abc_instancecheck__doc__, +"_abc_instancecheck($module, self, instance, /)\n" +"--\n" +"\n" +"Internal ABC helper for instance checks. Should be never used outside abc module."); + +#define _ABC__ABC_INSTANCECHECK_METHODDEF \ {"_abc_instancecheck", (PyCFunction)(void(*)(void))_abc__abc_instancecheck, METH_FASTCALL, _abc__abc_instancecheck__doc__}, - -static PyObject * -_abc__abc_instancecheck_impl(PyObject *module, PyObject *self, - PyObject *instance); - -static PyObject * -_abc__abc_instancecheck(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *self; - PyObject *instance; - + +static PyObject * +_abc__abc_instancecheck_impl(PyObject *module, PyObject *self, + PyObject *instance); + +static PyObject * +_abc__abc_instancecheck(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *self; + PyObject *instance; + if (!_PyArg_CheckPositional("_abc_instancecheck", nargs, 2, 2)) { - goto exit; - } + goto exit; + } self = args[0]; instance = args[1]; - return_value = _abc__abc_instancecheck_impl(module, self, instance); - -exit: - return return_value; -} - -PyDoc_STRVAR(_abc__abc_subclasscheck__doc__, -"_abc_subclasscheck($module, self, subclass, /)\n" -"--\n" -"\n" -"Internal ABC helper for subclasss checks. Should be never used outside abc module."); - -#define _ABC__ABC_SUBCLASSCHECK_METHODDEF \ + return_value = _abc__abc_instancecheck_impl(module, self, instance); + +exit: + return return_value; +} + +PyDoc_STRVAR(_abc__abc_subclasscheck__doc__, +"_abc_subclasscheck($module, self, subclass, /)\n" +"--\n" +"\n" +"Internal ABC helper for subclasss checks. Should be never used outside abc module."); + +#define _ABC__ABC_SUBCLASSCHECK_METHODDEF \ {"_abc_subclasscheck", (PyCFunction)(void(*)(void))_abc__abc_subclasscheck, METH_FASTCALL, _abc__abc_subclasscheck__doc__}, - -static PyObject * -_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, - PyObject *subclass); - -static PyObject * -_abc__abc_subclasscheck(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *self; - PyObject *subclass; - + +static PyObject * +_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, + PyObject *subclass); + +static PyObject * +_abc__abc_subclasscheck(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *self; + PyObject *subclass; + if (!_PyArg_CheckPositional("_abc_subclasscheck", nargs, 2, 2)) { - goto exit; - } + goto exit; + } self = args[0]; subclass = args[1]; - return_value = _abc__abc_subclasscheck_impl(module, self, subclass); - -exit: - return return_value; -} - -PyDoc_STRVAR(_abc_get_cache_token__doc__, -"get_cache_token($module, /)\n" -"--\n" -"\n" -"Returns the current ABC cache token.\n" -"\n" -"The token is an opaque object (supporting equality testing) identifying the\n" -"current version of the ABC cache for virtual subclasses. The token changes\n" -"with every call to register() on any ABC."); - -#define _ABC_GET_CACHE_TOKEN_METHODDEF \ - {"get_cache_token", (PyCFunction)_abc_get_cache_token, METH_NOARGS, _abc_get_cache_token__doc__}, - -static PyObject * -_abc_get_cache_token_impl(PyObject *module); - -static PyObject * -_abc_get_cache_token(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _abc_get_cache_token_impl(module); -} + return_value = _abc__abc_subclasscheck_impl(module, self, subclass); + +exit: + return return_value; +} + +PyDoc_STRVAR(_abc_get_cache_token__doc__, +"get_cache_token($module, /)\n" +"--\n" +"\n" +"Returns the current ABC cache token.\n" +"\n" +"The token is an opaque object (supporting equality testing) identifying the\n" +"current version of the ABC cache for virtual subclasses. The token changes\n" +"with every call to register() on any ABC."); + +#define _ABC_GET_CACHE_TOKEN_METHODDEF \ + {"get_cache_token", (PyCFunction)_abc_get_cache_token, METH_NOARGS, _abc_get_cache_token__doc__}, + +static PyObject * +_abc_get_cache_token_impl(PyObject *module); + +static PyObject * +_abc_get_cache_token(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _abc_get_cache_token_impl(module); +} /*[clinic end generated code: output=2544b4b5ae50a089 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_asynciomodule.c.h b/contrib/tools/python3/src/Modules/clinic/_asynciomodule.c.h index a071efc1e2b..cb26e12e7bc 100644 --- a/contrib/tools/python3/src/Modules/clinic/_asynciomodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_asynciomodule.c.h @@ -1,197 +1,197 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_asyncio_Future___init____doc__, -"Future(*, loop=None)\n" -"--\n" -"\n" -"This class is *almost* compatible with concurrent.futures.Future.\n" -"\n" -" Differences:\n" -"\n" -" - result() and exception() do not take a timeout argument and\n" -" raise an exception when the future isn\'t done yet.\n" -"\n" -" - Callbacks registered with add_done_callback() are always called\n" -" via the event loop\'s call_soon_threadsafe().\n" -"\n" -" - This class is not compatible with the wait() and as_completed()\n" -" methods in the concurrent.futures package."); - -static int -_asyncio_Future___init___impl(FutureObj *self, PyObject *loop); - -static int -_asyncio_Future___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"loop", NULL}; +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_asyncio_Future___init____doc__, +"Future(*, loop=None)\n" +"--\n" +"\n" +"This class is *almost* compatible with concurrent.futures.Future.\n" +"\n" +" Differences:\n" +"\n" +" - result() and exception() do not take a timeout argument and\n" +" raise an exception when the future isn\'t done yet.\n" +"\n" +" - Callbacks registered with add_done_callback() are always called\n" +" via the event loop\'s call_soon_threadsafe().\n" +"\n" +" - This class is not compatible with the wait() and as_completed()\n" +" methods in the concurrent.futures package."); + +static int +_asyncio_Future___init___impl(FutureObj *self, PyObject *loop); + +static int +_asyncio_Future___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"loop", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "Future", 0}; PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *loop = Py_None; - + PyObject *loop = Py_None; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 0, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_kwonly; } loop = fastargs[0]; skip_optional_kwonly: - return_value = _asyncio_Future___init___impl((FutureObj *)self, loop); - -exit: - return return_value; -} - -PyDoc_STRVAR(_asyncio_Future_result__doc__, -"result($self, /)\n" -"--\n" -"\n" -"Return the result this future represents.\n" -"\n" -"If the future has been cancelled, raises CancelledError. If the\n" -"future\'s result isn\'t yet available, raises InvalidStateError. If\n" -"the future is done and has an exception set, this exception is raised."); - -#define _ASYNCIO_FUTURE_RESULT_METHODDEF \ - {"result", (PyCFunction)_asyncio_Future_result, METH_NOARGS, _asyncio_Future_result__doc__}, - -static PyObject * -_asyncio_Future_result_impl(FutureObj *self); - -static PyObject * -_asyncio_Future_result(FutureObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Future_result_impl(self); -} - -PyDoc_STRVAR(_asyncio_Future_exception__doc__, -"exception($self, /)\n" -"--\n" -"\n" -"Return the exception that was set on this future.\n" -"\n" -"The exception (or None if no exception was set) is returned only if\n" -"the future is done. If the future has been cancelled, raises\n" -"CancelledError. If the future isn\'t done yet, raises\n" -"InvalidStateError."); - -#define _ASYNCIO_FUTURE_EXCEPTION_METHODDEF \ - {"exception", (PyCFunction)_asyncio_Future_exception, METH_NOARGS, _asyncio_Future_exception__doc__}, - -static PyObject * -_asyncio_Future_exception_impl(FutureObj *self); - -static PyObject * -_asyncio_Future_exception(FutureObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Future_exception_impl(self); -} - -PyDoc_STRVAR(_asyncio_Future_set_result__doc__, -"set_result($self, result, /)\n" -"--\n" -"\n" -"Mark the future done and set its result.\n" -"\n" -"If the future is already done when this method is called, raises\n" -"InvalidStateError."); - -#define _ASYNCIO_FUTURE_SET_RESULT_METHODDEF \ - {"set_result", (PyCFunction)_asyncio_Future_set_result, METH_O, _asyncio_Future_set_result__doc__}, - -PyDoc_STRVAR(_asyncio_Future_set_exception__doc__, -"set_exception($self, exception, /)\n" -"--\n" -"\n" -"Mark the future done and set an exception.\n" -"\n" -"If the future is already done when this method is called, raises\n" -"InvalidStateError."); - -#define _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF \ - {"set_exception", (PyCFunction)_asyncio_Future_set_exception, METH_O, _asyncio_Future_set_exception__doc__}, - -PyDoc_STRVAR(_asyncio_Future_add_done_callback__doc__, + return_value = _asyncio_Future___init___impl((FutureObj *)self, loop); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio_Future_result__doc__, +"result($self, /)\n" +"--\n" +"\n" +"Return the result this future represents.\n" +"\n" +"If the future has been cancelled, raises CancelledError. If the\n" +"future\'s result isn\'t yet available, raises InvalidStateError. If\n" +"the future is done and has an exception set, this exception is raised."); + +#define _ASYNCIO_FUTURE_RESULT_METHODDEF \ + {"result", (PyCFunction)_asyncio_Future_result, METH_NOARGS, _asyncio_Future_result__doc__}, + +static PyObject * +_asyncio_Future_result_impl(FutureObj *self); + +static PyObject * +_asyncio_Future_result(FutureObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Future_result_impl(self); +} + +PyDoc_STRVAR(_asyncio_Future_exception__doc__, +"exception($self, /)\n" +"--\n" +"\n" +"Return the exception that was set on this future.\n" +"\n" +"The exception (or None if no exception was set) is returned only if\n" +"the future is done. If the future has been cancelled, raises\n" +"CancelledError. If the future isn\'t done yet, raises\n" +"InvalidStateError."); + +#define _ASYNCIO_FUTURE_EXCEPTION_METHODDEF \ + {"exception", (PyCFunction)_asyncio_Future_exception, METH_NOARGS, _asyncio_Future_exception__doc__}, + +static PyObject * +_asyncio_Future_exception_impl(FutureObj *self); + +static PyObject * +_asyncio_Future_exception(FutureObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Future_exception_impl(self); +} + +PyDoc_STRVAR(_asyncio_Future_set_result__doc__, +"set_result($self, result, /)\n" +"--\n" +"\n" +"Mark the future done and set its result.\n" +"\n" +"If the future is already done when this method is called, raises\n" +"InvalidStateError."); + +#define _ASYNCIO_FUTURE_SET_RESULT_METHODDEF \ + {"set_result", (PyCFunction)_asyncio_Future_set_result, METH_O, _asyncio_Future_set_result__doc__}, + +PyDoc_STRVAR(_asyncio_Future_set_exception__doc__, +"set_exception($self, exception, /)\n" +"--\n" +"\n" +"Mark the future done and set an exception.\n" +"\n" +"If the future is already done when this method is called, raises\n" +"InvalidStateError."); + +#define _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF \ + {"set_exception", (PyCFunction)_asyncio_Future_set_exception, METH_O, _asyncio_Future_set_exception__doc__}, + +PyDoc_STRVAR(_asyncio_Future_add_done_callback__doc__, "add_done_callback($self, fn, /, *, context=)\n" -"--\n" -"\n" -"Add a callback to be run when the future becomes done.\n" -"\n" -"The callback is called with a single argument - the future object. If\n" -"the future is already done when this is called, the callback is\n" -"scheduled with call_soon."); - -#define _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF \ +"--\n" +"\n" +"Add a callback to be run when the future becomes done.\n" +"\n" +"The callback is called with a single argument - the future object. If\n" +"the future is already done when this is called, the callback is\n" +"scheduled with call_soon."); + +#define _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF \ {"add_done_callback", (PyCFunction)(void(*)(void))_asyncio_Future_add_done_callback, METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_add_done_callback__doc__}, - -static PyObject * -_asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn, - PyObject *context); - -static PyObject * -_asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "context", NULL}; + +static PyObject * +_asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn, + PyObject *context); + +static PyObject * +_asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "context", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "add_done_callback", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *fn; - PyObject *context = NULL; - + PyObject *fn; + PyObject *context = NULL; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } fn = args[0]; if (!noptargs) { goto skip_optional_kwonly; } context = args[1]; skip_optional_kwonly: - return_value = _asyncio_Future_add_done_callback_impl(self, fn, context); - -exit: - return return_value; -} - -PyDoc_STRVAR(_asyncio_Future_remove_done_callback__doc__, -"remove_done_callback($self, fn, /)\n" -"--\n" -"\n" -"Remove all instances of a callback from the \"call when done\" list.\n" -"\n" -"Returns the number of callbacks removed."); - -#define _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF \ - {"remove_done_callback", (PyCFunction)_asyncio_Future_remove_done_callback, METH_O, _asyncio_Future_remove_done_callback__doc__}, - -PyDoc_STRVAR(_asyncio_Future_cancel__doc__, + return_value = _asyncio_Future_add_done_callback_impl(self, fn, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio_Future_remove_done_callback__doc__, +"remove_done_callback($self, fn, /)\n" +"--\n" +"\n" +"Remove all instances of a callback from the \"call when done\" list.\n" +"\n" +"Returns the number of callbacks removed."); + +#define _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF \ + {"remove_done_callback", (PyCFunction)_asyncio_Future_remove_done_callback, METH_O, _asyncio_Future_remove_done_callback__doc__}, + +PyDoc_STRVAR(_asyncio_Future_cancel__doc__, "cancel($self, /, msg=None)\n" -"--\n" -"\n" -"Cancel the future and schedule callbacks.\n" -"\n" -"If the future is already done or cancelled, return False. Otherwise,\n" -"change the future\'s state to cancelled, schedule the callbacks and\n" -"return True."); - -#define _ASYNCIO_FUTURE_CANCEL_METHODDEF \ +"--\n" +"\n" +"Cancel the future and schedule callbacks.\n" +"\n" +"If the future is already done or cancelled, return False. Otherwise,\n" +"change the future\'s state to cancelled, schedule the callbacks and\n" +"return True."); + +#define _ASYNCIO_FUTURE_CANCEL_METHODDEF \ {"cancel", (PyCFunction)(void(*)(void))_asyncio_Future_cancel, METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_cancel__doc__}, - -static PyObject * + +static PyObject * _asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg); - -static PyObject * + +static PyObject * _asyncio_Future_cancel(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ +{ PyObject *return_value = NULL; static const char * const _keywords[] = {"msg", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "cancel", 0}; @@ -212,65 +212,65 @@ skip_optional_pos: exit: return return_value; -} - -PyDoc_STRVAR(_asyncio_Future_cancelled__doc__, -"cancelled($self, /)\n" -"--\n" -"\n" -"Return True if the future was cancelled."); - -#define _ASYNCIO_FUTURE_CANCELLED_METHODDEF \ - {"cancelled", (PyCFunction)_asyncio_Future_cancelled, METH_NOARGS, _asyncio_Future_cancelled__doc__}, - -static PyObject * -_asyncio_Future_cancelled_impl(FutureObj *self); - -static PyObject * -_asyncio_Future_cancelled(FutureObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Future_cancelled_impl(self); -} - -PyDoc_STRVAR(_asyncio_Future_done__doc__, -"done($self, /)\n" -"--\n" -"\n" -"Return True if the future is done.\n" -"\n" -"Done means either that a result / exception are available, or that the\n" -"future was cancelled."); - -#define _ASYNCIO_FUTURE_DONE_METHODDEF \ - {"done", (PyCFunction)_asyncio_Future_done, METH_NOARGS, _asyncio_Future_done__doc__}, - -static PyObject * -_asyncio_Future_done_impl(FutureObj *self); - -static PyObject * -_asyncio_Future_done(FutureObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Future_done_impl(self); -} - -PyDoc_STRVAR(_asyncio_Future_get_loop__doc__, -"get_loop($self, /)\n" -"--\n" -"\n" -"Return the event loop the Future is bound to."); - -#define _ASYNCIO_FUTURE_GET_LOOP_METHODDEF \ - {"get_loop", (PyCFunction)_asyncio_Future_get_loop, METH_NOARGS, _asyncio_Future_get_loop__doc__}, - -static PyObject * -_asyncio_Future_get_loop_impl(FutureObj *self); - -static PyObject * -_asyncio_Future_get_loop(FutureObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Future_get_loop_impl(self); -} - +} + +PyDoc_STRVAR(_asyncio_Future_cancelled__doc__, +"cancelled($self, /)\n" +"--\n" +"\n" +"Return True if the future was cancelled."); + +#define _ASYNCIO_FUTURE_CANCELLED_METHODDEF \ + {"cancelled", (PyCFunction)_asyncio_Future_cancelled, METH_NOARGS, _asyncio_Future_cancelled__doc__}, + +static PyObject * +_asyncio_Future_cancelled_impl(FutureObj *self); + +static PyObject * +_asyncio_Future_cancelled(FutureObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Future_cancelled_impl(self); +} + +PyDoc_STRVAR(_asyncio_Future_done__doc__, +"done($self, /)\n" +"--\n" +"\n" +"Return True if the future is done.\n" +"\n" +"Done means either that a result / exception are available, or that the\n" +"future was cancelled."); + +#define _ASYNCIO_FUTURE_DONE_METHODDEF \ + {"done", (PyCFunction)_asyncio_Future_done, METH_NOARGS, _asyncio_Future_done__doc__}, + +static PyObject * +_asyncio_Future_done_impl(FutureObj *self); + +static PyObject * +_asyncio_Future_done(FutureObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Future_done_impl(self); +} + +PyDoc_STRVAR(_asyncio_Future_get_loop__doc__, +"get_loop($self, /)\n" +"--\n" +"\n" +"Return the event loop the Future is bound to."); + +#define _ASYNCIO_FUTURE_GET_LOOP_METHODDEF \ + {"get_loop", (PyCFunction)_asyncio_Future_get_loop, METH_NOARGS, _asyncio_Future_get_loop__doc__}, + +static PyObject * +_asyncio_Future_get_loop_impl(FutureObj *self); + +static PyObject * +_asyncio_Future_get_loop(FutureObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Future_get_loop_impl(self); +} + PyDoc_STRVAR(_asyncio_Future__make_cancelled_error__doc__, "_make_cancelled_error($self, /)\n" "--\n" @@ -292,51 +292,51 @@ _asyncio_Future__make_cancelled_error(FutureObj *self, PyObject *Py_UNUSED(ignor return _asyncio_Future__make_cancelled_error_impl(self); } -PyDoc_STRVAR(_asyncio_Future__repr_info__doc__, -"_repr_info($self, /)\n" -"--\n" -"\n"); - -#define _ASYNCIO_FUTURE__REPR_INFO_METHODDEF \ - {"_repr_info", (PyCFunction)_asyncio_Future__repr_info, METH_NOARGS, _asyncio_Future__repr_info__doc__}, - -static PyObject * -_asyncio_Future__repr_info_impl(FutureObj *self); - -static PyObject * -_asyncio_Future__repr_info(FutureObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Future__repr_info_impl(self); -} - -PyDoc_STRVAR(_asyncio_Task___init____doc__, +PyDoc_STRVAR(_asyncio_Future__repr_info__doc__, +"_repr_info($self, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_FUTURE__REPR_INFO_METHODDEF \ + {"_repr_info", (PyCFunction)_asyncio_Future__repr_info, METH_NOARGS, _asyncio_Future__repr_info__doc__}, + +static PyObject * +_asyncio_Future__repr_info_impl(FutureObj *self); + +static PyObject * +_asyncio_Future__repr_info(FutureObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Future__repr_info_impl(self); +} + +PyDoc_STRVAR(_asyncio_Task___init____doc__, "Task(coro, *, loop=None, name=None)\n" -"--\n" -"\n" -"A coroutine wrapped in a Future."); - -static int +"--\n" +"\n" +"A coroutine wrapped in a Future."); + +static int _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, PyObject *name); - -static int -_asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; + +static int +_asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; static const char * const _keywords[] = {"coro", "loop", "name", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "Task", 0}; PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *coro; - PyObject *loop = Py_None; + PyObject *coro; + PyObject *loop = Py_None; PyObject *name = Py_None; - + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } coro = fastargs[0]; if (!noptargs) { goto skip_optional_kwonly; @@ -350,81 +350,81 @@ _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) name = fastargs[2]; skip_optional_kwonly: return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name); - -exit: - return return_value; -} - + +exit: + return return_value; +} + PyDoc_STRVAR(_asyncio_Task__make_cancelled_error__doc__, "_make_cancelled_error($self, /)\n" -"--\n" -"\n" +"--\n" +"\n" "Create the CancelledError to raise if the Task is cancelled.\n" -"\n" +"\n" "This should only be called once when handling a cancellation since\n" "it erases the context exception value."); - + #define _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF \ {"_make_cancelled_error", (PyCFunction)_asyncio_Task__make_cancelled_error, METH_NOARGS, _asyncio_Task__make_cancelled_error__doc__}, - -static PyObject * + +static PyObject * _asyncio_Task__make_cancelled_error_impl(TaskObj *self); - -static PyObject * + +static PyObject * _asyncio_Task__make_cancelled_error(TaskObj *self, PyObject *Py_UNUSED(ignored)) -{ +{ return _asyncio_Task__make_cancelled_error_impl(self); -} - -PyDoc_STRVAR(_asyncio_Task__repr_info__doc__, -"_repr_info($self, /)\n" -"--\n" -"\n"); - -#define _ASYNCIO_TASK__REPR_INFO_METHODDEF \ - {"_repr_info", (PyCFunction)_asyncio_Task__repr_info, METH_NOARGS, _asyncio_Task__repr_info__doc__}, - -static PyObject * -_asyncio_Task__repr_info_impl(TaskObj *self); - -static PyObject * -_asyncio_Task__repr_info(TaskObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Task__repr_info_impl(self); -} - -PyDoc_STRVAR(_asyncio_Task_cancel__doc__, +} + +PyDoc_STRVAR(_asyncio_Task__repr_info__doc__, +"_repr_info($self, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_TASK__REPR_INFO_METHODDEF \ + {"_repr_info", (PyCFunction)_asyncio_Task__repr_info, METH_NOARGS, _asyncio_Task__repr_info__doc__}, + +static PyObject * +_asyncio_Task__repr_info_impl(TaskObj *self); + +static PyObject * +_asyncio_Task__repr_info(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task__repr_info_impl(self); +} + +PyDoc_STRVAR(_asyncio_Task_cancel__doc__, "cancel($self, /, msg=None)\n" -"--\n" -"\n" -"Request that this task cancel itself.\n" -"\n" -"This arranges for a CancelledError to be thrown into the\n" -"wrapped coroutine on the next cycle through the event loop.\n" -"The coroutine then has a chance to clean up or even deny\n" -"the request using try/except/finally.\n" -"\n" -"Unlike Future.cancel, this does not guarantee that the\n" -"task will be cancelled: the exception might be caught and\n" -"acted upon, delaying cancellation of the task or preventing\n" -"cancellation completely. The task may also return a value or\n" -"raise a different exception.\n" -"\n" -"Immediately after this method is called, Task.cancelled() will\n" -"not return True (unless the task was already cancelled). A\n" -"task will be marked as cancelled when the wrapped coroutine\n" -"terminates with a CancelledError exception (even if cancel()\n" -"was not called)."); - -#define _ASYNCIO_TASK_CANCEL_METHODDEF \ +"--\n" +"\n" +"Request that this task cancel itself.\n" +"\n" +"This arranges for a CancelledError to be thrown into the\n" +"wrapped coroutine on the next cycle through the event loop.\n" +"The coroutine then has a chance to clean up or even deny\n" +"the request using try/except/finally.\n" +"\n" +"Unlike Future.cancel, this does not guarantee that the\n" +"task will be cancelled: the exception might be caught and\n" +"acted upon, delaying cancellation of the task or preventing\n" +"cancellation completely. The task may also return a value or\n" +"raise a different exception.\n" +"\n" +"Immediately after this method is called, Task.cancelled() will\n" +"not return True (unless the task was already cancelled). A\n" +"task will be marked as cancelled when the wrapped coroutine\n" +"terminates with a CancelledError exception (even if cancel()\n" +"was not called)."); + +#define _ASYNCIO_TASK_CANCEL_METHODDEF \ {"cancel", (PyCFunction)(void(*)(void))_asyncio_Task_cancel, METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_cancel__doc__}, - -static PyObject * + +static PyObject * _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg); - -static PyObject * + +static PyObject * _asyncio_Task_cancel(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ +{ PyObject *return_value = NULL; static const char * const _keywords[] = {"msg", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "cancel", 0}; @@ -445,97 +445,97 @@ skip_optional_pos: exit: return return_value; -} - -PyDoc_STRVAR(_asyncio_Task_get_stack__doc__, -"get_stack($self, /, *, limit=None)\n" -"--\n" -"\n" -"Return the list of stack frames for this task\'s coroutine.\n" -"\n" -"If the coroutine is not done, this returns the stack where it is\n" -"suspended. If the coroutine has completed successfully or was\n" -"cancelled, this returns an empty list. If the coroutine was\n" -"terminated by an exception, this returns the list of traceback\n" -"frames.\n" -"\n" -"The frames are always ordered from oldest to newest.\n" -"\n" -"The optional limit gives the maximum number of frames to\n" -"return; by default all available frames are returned. Its\n" -"meaning differs depending on whether a stack or a traceback is\n" -"returned: the newest frames of a stack are returned, but the\n" -"oldest frames of a traceback are returned. (This matches the\n" -"behavior of the traceback module.)\n" -"\n" -"For reasons beyond our control, only one stack frame is\n" -"returned for a suspended coroutine."); - -#define _ASYNCIO_TASK_GET_STACK_METHODDEF \ +} + +PyDoc_STRVAR(_asyncio_Task_get_stack__doc__, +"get_stack($self, /, *, limit=None)\n" +"--\n" +"\n" +"Return the list of stack frames for this task\'s coroutine.\n" +"\n" +"If the coroutine is not done, this returns the stack where it is\n" +"suspended. If the coroutine has completed successfully or was\n" +"cancelled, this returns an empty list. If the coroutine was\n" +"terminated by an exception, this returns the list of traceback\n" +"frames.\n" +"\n" +"The frames are always ordered from oldest to newest.\n" +"\n" +"The optional limit gives the maximum number of frames to\n" +"return; by default all available frames are returned. Its\n" +"meaning differs depending on whether a stack or a traceback is\n" +"returned: the newest frames of a stack are returned, but the\n" +"oldest frames of a traceback are returned. (This matches the\n" +"behavior of the traceback module.)\n" +"\n" +"For reasons beyond our control, only one stack frame is\n" +"returned for a suspended coroutine."); + +#define _ASYNCIO_TASK_GET_STACK_METHODDEF \ {"get_stack", (PyCFunction)(void(*)(void))_asyncio_Task_get_stack, METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_get_stack__doc__}, - -static PyObject * -_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit); - -static PyObject * -_asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"limit", NULL}; + +static PyObject * +_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit); + +static PyObject * +_asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"limit", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "get_stack", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *limit = Py_None; - + PyObject *limit = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_kwonly; } limit = args[0]; skip_optional_kwonly: - return_value = _asyncio_Task_get_stack_impl(self, limit); - -exit: - return return_value; -} - -PyDoc_STRVAR(_asyncio_Task_print_stack__doc__, -"print_stack($self, /, *, limit=None, file=None)\n" -"--\n" -"\n" -"Print the stack or traceback for this task\'s coroutine.\n" -"\n" -"This produces output similar to that of the traceback module,\n" -"for the frames retrieved by get_stack(). The limit argument\n" -"is passed to get_stack(). The file argument is an I/O stream\n" -"to which the output is written; by default output is written\n" -"to sys.stderr."); - -#define _ASYNCIO_TASK_PRINT_STACK_METHODDEF \ + return_value = _asyncio_Task_get_stack_impl(self, limit); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio_Task_print_stack__doc__, +"print_stack($self, /, *, limit=None, file=None)\n" +"--\n" +"\n" +"Print the stack or traceback for this task\'s coroutine.\n" +"\n" +"This produces output similar to that of the traceback module,\n" +"for the frames retrieved by get_stack(). The limit argument\n" +"is passed to get_stack(). The file argument is an I/O stream\n" +"to which the output is written; by default output is written\n" +"to sys.stderr."); + +#define _ASYNCIO_TASK_PRINT_STACK_METHODDEF \ {"print_stack", (PyCFunction)(void(*)(void))_asyncio_Task_print_stack, METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_print_stack__doc__}, - -static PyObject * -_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, - PyObject *file); - -static PyObject * -_asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"limit", "file", NULL}; + +static PyObject * +_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, + PyObject *file); + +static PyObject * +_asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"limit", "file", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "print_stack", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *limit = Py_None; - PyObject *file = Py_None; - + PyObject *limit = Py_None; + PyObject *file = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_kwonly; } @@ -547,28 +547,28 @@ _asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs } file = args[1]; skip_optional_kwonly: - return_value = _asyncio_Task_print_stack_impl(self, limit, file); - -exit: - return return_value; -} - -PyDoc_STRVAR(_asyncio_Task_set_result__doc__, -"set_result($self, result, /)\n" -"--\n" -"\n"); - -#define _ASYNCIO_TASK_SET_RESULT_METHODDEF \ - {"set_result", (PyCFunction)_asyncio_Task_set_result, METH_O, _asyncio_Task_set_result__doc__}, - -PyDoc_STRVAR(_asyncio_Task_set_exception__doc__, -"set_exception($self, exception, /)\n" -"--\n" -"\n"); - -#define _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF \ - {"set_exception", (PyCFunction)_asyncio_Task_set_exception, METH_O, _asyncio_Task_set_exception__doc__}, - + return_value = _asyncio_Task_print_stack_impl(self, limit, file); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio_Task_set_result__doc__, +"set_result($self, result, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_TASK_SET_RESULT_METHODDEF \ + {"set_result", (PyCFunction)_asyncio_Task_set_result, METH_O, _asyncio_Task_set_result__doc__}, + +PyDoc_STRVAR(_asyncio_Task_set_exception__doc__, +"set_exception($self, exception, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF \ + {"set_exception", (PyCFunction)_asyncio_Task_set_exception, METH_O, _asyncio_Task_set_exception__doc__}, + PyDoc_STRVAR(_asyncio_Task_get_coro__doc__, "get_coro($self, /)\n" "--\n" @@ -611,225 +611,225 @@ PyDoc_STRVAR(_asyncio_Task_set_name__doc__, #define _ASYNCIO_TASK_SET_NAME_METHODDEF \ {"set_name", (PyCFunction)_asyncio_Task_set_name, METH_O, _asyncio_Task_set_name__doc__}, -PyDoc_STRVAR(_asyncio__get_running_loop__doc__, -"_get_running_loop($module, /)\n" -"--\n" -"\n" -"Return the running event loop or None.\n" -"\n" -"This is a low-level function intended to be used by event loops.\n" -"This function is thread-specific."); - -#define _ASYNCIO__GET_RUNNING_LOOP_METHODDEF \ - {"_get_running_loop", (PyCFunction)_asyncio__get_running_loop, METH_NOARGS, _asyncio__get_running_loop__doc__}, - -static PyObject * -_asyncio__get_running_loop_impl(PyObject *module); - -static PyObject * -_asyncio__get_running_loop(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio__get_running_loop_impl(module); -} - -PyDoc_STRVAR(_asyncio__set_running_loop__doc__, -"_set_running_loop($module, loop, /)\n" -"--\n" -"\n" -"Set the running event loop.\n" -"\n" -"This is a low-level function intended to be used by event loops.\n" -"This function is thread-specific."); - -#define _ASYNCIO__SET_RUNNING_LOOP_METHODDEF \ - {"_set_running_loop", (PyCFunction)_asyncio__set_running_loop, METH_O, _asyncio__set_running_loop__doc__}, - -PyDoc_STRVAR(_asyncio_get_event_loop__doc__, -"get_event_loop($module, /)\n" -"--\n" -"\n" -"Return an asyncio event loop.\n" -"\n" -"When called from a coroutine or a callback (e.g. scheduled with\n" -"call_soon or similar API), this function will always return the\n" -"running event loop.\n" -"\n" -"If there is no running event loop set, the function will return\n" -"the result of `get_event_loop_policy().get_event_loop()` call."); - -#define _ASYNCIO_GET_EVENT_LOOP_METHODDEF \ - {"get_event_loop", (PyCFunction)_asyncio_get_event_loop, METH_NOARGS, _asyncio_get_event_loop__doc__}, - -static PyObject * -_asyncio_get_event_loop_impl(PyObject *module); - -static PyObject * -_asyncio_get_event_loop(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_get_event_loop_impl(module); -} - -PyDoc_STRVAR(_asyncio_get_running_loop__doc__, -"get_running_loop($module, /)\n" -"--\n" -"\n" -"Return the running event loop. Raise a RuntimeError if there is none.\n" -"\n" -"This function is thread-specific."); - -#define _ASYNCIO_GET_RUNNING_LOOP_METHODDEF \ - {"get_running_loop", (PyCFunction)_asyncio_get_running_loop, METH_NOARGS, _asyncio_get_running_loop__doc__}, - -static PyObject * -_asyncio_get_running_loop_impl(PyObject *module); - -static PyObject * -_asyncio_get_running_loop(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_get_running_loop_impl(module); -} - -PyDoc_STRVAR(_asyncio__register_task__doc__, -"_register_task($module, /, task)\n" -"--\n" -"\n" -"Register a new task in asyncio as executed by loop.\n" -"\n" -"Returns None."); - -#define _ASYNCIO__REGISTER_TASK_METHODDEF \ +PyDoc_STRVAR(_asyncio__get_running_loop__doc__, +"_get_running_loop($module, /)\n" +"--\n" +"\n" +"Return the running event loop or None.\n" +"\n" +"This is a low-level function intended to be used by event loops.\n" +"This function is thread-specific."); + +#define _ASYNCIO__GET_RUNNING_LOOP_METHODDEF \ + {"_get_running_loop", (PyCFunction)_asyncio__get_running_loop, METH_NOARGS, _asyncio__get_running_loop__doc__}, + +static PyObject * +_asyncio__get_running_loop_impl(PyObject *module); + +static PyObject * +_asyncio__get_running_loop(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio__get_running_loop_impl(module); +} + +PyDoc_STRVAR(_asyncio__set_running_loop__doc__, +"_set_running_loop($module, loop, /)\n" +"--\n" +"\n" +"Set the running event loop.\n" +"\n" +"This is a low-level function intended to be used by event loops.\n" +"This function is thread-specific."); + +#define _ASYNCIO__SET_RUNNING_LOOP_METHODDEF \ + {"_set_running_loop", (PyCFunction)_asyncio__set_running_loop, METH_O, _asyncio__set_running_loop__doc__}, + +PyDoc_STRVAR(_asyncio_get_event_loop__doc__, +"get_event_loop($module, /)\n" +"--\n" +"\n" +"Return an asyncio event loop.\n" +"\n" +"When called from a coroutine or a callback (e.g. scheduled with\n" +"call_soon or similar API), this function will always return the\n" +"running event loop.\n" +"\n" +"If there is no running event loop set, the function will return\n" +"the result of `get_event_loop_policy().get_event_loop()` call."); + +#define _ASYNCIO_GET_EVENT_LOOP_METHODDEF \ + {"get_event_loop", (PyCFunction)_asyncio_get_event_loop, METH_NOARGS, _asyncio_get_event_loop__doc__}, + +static PyObject * +_asyncio_get_event_loop_impl(PyObject *module); + +static PyObject * +_asyncio_get_event_loop(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_get_event_loop_impl(module); +} + +PyDoc_STRVAR(_asyncio_get_running_loop__doc__, +"get_running_loop($module, /)\n" +"--\n" +"\n" +"Return the running event loop. Raise a RuntimeError if there is none.\n" +"\n" +"This function is thread-specific."); + +#define _ASYNCIO_GET_RUNNING_LOOP_METHODDEF \ + {"get_running_loop", (PyCFunction)_asyncio_get_running_loop, METH_NOARGS, _asyncio_get_running_loop__doc__}, + +static PyObject * +_asyncio_get_running_loop_impl(PyObject *module); + +static PyObject * +_asyncio_get_running_loop(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_get_running_loop_impl(module); +} + +PyDoc_STRVAR(_asyncio__register_task__doc__, +"_register_task($module, /, task)\n" +"--\n" +"\n" +"Register a new task in asyncio as executed by loop.\n" +"\n" +"Returns None."); + +#define _ASYNCIO__REGISTER_TASK_METHODDEF \ {"_register_task", (PyCFunction)(void(*)(void))_asyncio__register_task, METH_FASTCALL|METH_KEYWORDS, _asyncio__register_task__doc__}, - -static PyObject * -_asyncio__register_task_impl(PyObject *module, PyObject *task); - -static PyObject * -_asyncio__register_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"task", NULL}; + +static PyObject * +_asyncio__register_task_impl(PyObject *module, PyObject *task); + +static PyObject * +_asyncio__register_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"task", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "_register_task", 0}; PyObject *argsbuf[1]; - PyObject *task; - + PyObject *task; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } task = args[0]; - return_value = _asyncio__register_task_impl(module, task); - -exit: - return return_value; -} - -PyDoc_STRVAR(_asyncio__unregister_task__doc__, -"_unregister_task($module, /, task)\n" -"--\n" -"\n" -"Unregister a task.\n" -"\n" -"Returns None."); - -#define _ASYNCIO__UNREGISTER_TASK_METHODDEF \ + return_value = _asyncio__register_task_impl(module, task); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio__unregister_task__doc__, +"_unregister_task($module, /, task)\n" +"--\n" +"\n" +"Unregister a task.\n" +"\n" +"Returns None."); + +#define _ASYNCIO__UNREGISTER_TASK_METHODDEF \ {"_unregister_task", (PyCFunction)(void(*)(void))_asyncio__unregister_task, METH_FASTCALL|METH_KEYWORDS, _asyncio__unregister_task__doc__}, - -static PyObject * -_asyncio__unregister_task_impl(PyObject *module, PyObject *task); - -static PyObject * -_asyncio__unregister_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"task", NULL}; + +static PyObject * +_asyncio__unregister_task_impl(PyObject *module, PyObject *task); + +static PyObject * +_asyncio__unregister_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"task", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "_unregister_task", 0}; PyObject *argsbuf[1]; - PyObject *task; - + PyObject *task; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } task = args[0]; - return_value = _asyncio__unregister_task_impl(module, task); - -exit: - return return_value; -} - -PyDoc_STRVAR(_asyncio__enter_task__doc__, -"_enter_task($module, /, loop, task)\n" -"--\n" -"\n" -"Enter into task execution or resume suspended task.\n" -"\n" -"Task belongs to loop.\n" -"\n" -"Returns None."); - -#define _ASYNCIO__ENTER_TASK_METHODDEF \ + return_value = _asyncio__unregister_task_impl(module, task); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio__enter_task__doc__, +"_enter_task($module, /, loop, task)\n" +"--\n" +"\n" +"Enter into task execution or resume suspended task.\n" +"\n" +"Task belongs to loop.\n" +"\n" +"Returns None."); + +#define _ASYNCIO__ENTER_TASK_METHODDEF \ {"_enter_task", (PyCFunction)(void(*)(void))_asyncio__enter_task, METH_FASTCALL|METH_KEYWORDS, _asyncio__enter_task__doc__}, - -static PyObject * -_asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task); - -static PyObject * -_asyncio__enter_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"loop", "task", NULL}; + +static PyObject * +_asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task); + +static PyObject * +_asyncio__enter_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"loop", "task", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "_enter_task", 0}; PyObject *argsbuf[2]; - PyObject *loop; - PyObject *task; - + PyObject *loop; + PyObject *task; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } loop = args[0]; task = args[1]; - return_value = _asyncio__enter_task_impl(module, loop, task); - -exit: - return return_value; -} - -PyDoc_STRVAR(_asyncio__leave_task__doc__, -"_leave_task($module, /, loop, task)\n" -"--\n" -"\n" -"Leave task execution or suspend a task.\n" -"\n" -"Task belongs to loop.\n" -"\n" -"Returns None."); - -#define _ASYNCIO__LEAVE_TASK_METHODDEF \ + return_value = _asyncio__enter_task_impl(module, loop, task); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio__leave_task__doc__, +"_leave_task($module, /, loop, task)\n" +"--\n" +"\n" +"Leave task execution or suspend a task.\n" +"\n" +"Task belongs to loop.\n" +"\n" +"Returns None."); + +#define _ASYNCIO__LEAVE_TASK_METHODDEF \ {"_leave_task", (PyCFunction)(void(*)(void))_asyncio__leave_task, METH_FASTCALL|METH_KEYWORDS, _asyncio__leave_task__doc__}, - -static PyObject * -_asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task); - -static PyObject * -_asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"loop", "task", NULL}; + +static PyObject * +_asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task); + +static PyObject * +_asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"loop", "task", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "_leave_task", 0}; PyObject *argsbuf[2]; - PyObject *loop; - PyObject *task; - + PyObject *loop; + PyObject *task; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } loop = args[0]; task = args[1]; - return_value = _asyncio__leave_task_impl(module, loop, task); - -exit: - return return_value; -} + return_value = _asyncio__leave_task_impl(module, loop, task); + +exit: + return return_value; +} /*[clinic end generated code: output=d0fc522bcbff9d61 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_bz2module.c.h b/contrib/tools/python3/src/Modules/clinic/_bz2module.c.h index 0eb6280d6e0..6c889c0cdf0 100644 --- a/contrib/tools/python3/src/Modules/clinic/_bz2module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_bz2module.c.h @@ -1,97 +1,97 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__, -"compress($self, data, /)\n" -"--\n" -"\n" -"Provide data to the compressor object.\n" -"\n" -"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n" -"\n" -"When you have finished providing data to the compressor, call the\n" -"flush() method to finish the compression process."); - -#define _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)_bz2_BZ2Compressor_compress, METH_O, _bz2_BZ2Compressor_compress__doc__}, - -static PyObject * -_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data); - -static PyObject * -_bz2_BZ2Compressor_compress(BZ2Compressor *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__, +"compress($self, data, /)\n" +"--\n" +"\n" +"Provide data to the compressor object.\n" +"\n" +"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n" +"\n" +"When you have finished providing data to the compressor, call the\n" +"flush() method to finish the compression process."); + +#define _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF \ + {"compress", (PyCFunction)_bz2_BZ2Compressor_compress, METH_O, _bz2_BZ2Compressor_compress__doc__}, + +static PyObject * +_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data); + +static PyObject * +_bz2_BZ2Compressor_compress(BZ2Compressor *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&data, 'C')) { _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); goto exit; } - return_value = _bz2_BZ2Compressor_compress_impl(self, &data); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_bz2_BZ2Compressor_flush__doc__, -"flush($self, /)\n" -"--\n" -"\n" -"Finish the compression process.\n" -"\n" -"Returns the compressed data left in internal buffers.\n" -"\n" -"The compressor object may not be used after this method is called."); - -#define _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF \ - {"flush", (PyCFunction)_bz2_BZ2Compressor_flush, METH_NOARGS, _bz2_BZ2Compressor_flush__doc__}, - -static PyObject * -_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self); - -static PyObject * -_bz2_BZ2Compressor_flush(BZ2Compressor *self, PyObject *Py_UNUSED(ignored)) -{ - return _bz2_BZ2Compressor_flush_impl(self); -} - -PyDoc_STRVAR(_bz2_BZ2Compressor___init____doc__, -"BZ2Compressor(compresslevel=9, /)\n" -"--\n" -"\n" -"Create a compressor object for compressing data incrementally.\n" -"\n" -" compresslevel\n" -" Compression level, as a number between 1 and 9.\n" -"\n" -"For one-shot compression, use the compress() function instead."); - -static int -_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel); - -static int -_bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - int compresslevel = 9; - + return_value = _bz2_BZ2Compressor_compress_impl(self, &data); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_bz2_BZ2Compressor_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n" +"Finish the compression process.\n" +"\n" +"Returns the compressed data left in internal buffers.\n" +"\n" +"The compressor object may not be used after this method is called."); + +#define _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_bz2_BZ2Compressor_flush, METH_NOARGS, _bz2_BZ2Compressor_flush__doc__}, + +static PyObject * +_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self); + +static PyObject * +_bz2_BZ2Compressor_flush(BZ2Compressor *self, PyObject *Py_UNUSED(ignored)) +{ + return _bz2_BZ2Compressor_flush_impl(self); +} + +PyDoc_STRVAR(_bz2_BZ2Compressor___init____doc__, +"BZ2Compressor(compresslevel=9, /)\n" +"--\n" +"\n" +"Create a compressor object for compressing data incrementally.\n" +"\n" +" compresslevel\n" +" Compression level, as a number between 1 and 9.\n" +"\n" +"For one-shot compression, use the compress() function instead."); + +static int +_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel); + +static int +_bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + int compresslevel = 9; + if (Py_IS_TYPE(self, &BZ2Compressor_Type) && - !_PyArg_NoKeywords("BZ2Compressor", kwargs)) { - goto exit; - } + !_PyArg_NoKeywords("BZ2Compressor", kwargs)) { + goto exit; + } if (!_PyArg_CheckPositional("BZ2Compressor", PyTuple_GET_SIZE(args), 0, 1)) { - goto exit; - } + goto exit; + } if (PyTuple_GET_SIZE(args) < 1) { goto skip_optional; } @@ -105,53 +105,53 @@ _bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto exit; } skip_optional: - return_value = _bz2_BZ2Compressor___init___impl((BZ2Compressor *)self, compresslevel); - -exit: - return return_value; -} - -PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__, -"decompress($self, /, data, max_length=-1)\n" -"--\n" -"\n" -"Decompress *data*, returning uncompressed data as bytes.\n" -"\n" -"If *max_length* is nonnegative, returns at most *max_length* bytes of\n" -"decompressed data. If this limit is reached and further output can be\n" -"produced, *self.needs_input* will be set to ``False``. In this case, the next\n" -"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n" -"\n" -"If all of the input data was decompressed and returned (either because this\n" -"was less than *max_length* bytes, or because *max_length* was negative),\n" -"*self.needs_input* will be set to True.\n" -"\n" -"Attempting to decompress data after the end of stream is reached raises an\n" -"EOFError. Any data found after the end of the stream is ignored and saved in\n" -"the unused_data attribute."); - -#define _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF \ + return_value = _bz2_BZ2Compressor___init___impl((BZ2Compressor *)self, compresslevel); + +exit: + return return_value; +} + +PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__, +"decompress($self, /, data, max_length=-1)\n" +"--\n" +"\n" +"Decompress *data*, returning uncompressed data as bytes.\n" +"\n" +"If *max_length* is nonnegative, returns at most *max_length* bytes of\n" +"decompressed data. If this limit is reached and further output can be\n" +"produced, *self.needs_input* will be set to ``False``. In this case, the next\n" +"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n" +"\n" +"If all of the input data was decompressed and returned (either because this\n" +"was less than *max_length* bytes, or because *max_length* was negative),\n" +"*self.needs_input* will be set to True.\n" +"\n" +"Attempting to decompress data after the end of stream is reached raises an\n" +"EOFError. Any data found after the end of the stream is ignored and saved in\n" +"the unused_data attribute."); + +#define _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF \ {"decompress", (PyCFunction)(void(*)(void))_bz2_BZ2Decompressor_decompress, METH_FASTCALL|METH_KEYWORDS, _bz2_BZ2Decompressor_decompress__doc__}, - -static PyObject * -_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, - Py_ssize_t max_length); - -static PyObject * -_bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"data", "max_length", NULL}; + +static PyObject * +_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, + Py_ssize_t max_length); + +static PyObject * +_bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"data", "max_length", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - Py_ssize_t max_length = -1; - + Py_buffer data = {NULL, NULL}; + Py_ssize_t max_length = -1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -180,44 +180,44 @@ _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py max_length = ival; } skip_optional_pos: - return_value = _bz2_BZ2Decompressor_decompress_impl(self, &data, max_length); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_bz2_BZ2Decompressor___init____doc__, -"BZ2Decompressor()\n" -"--\n" -"\n" -"Create a decompressor object for decompressing data incrementally.\n" -"\n" -"For one-shot decompression, use the decompress() function instead."); - -static int -_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self); - -static int -_bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - + return_value = _bz2_BZ2Decompressor_decompress_impl(self, &data, max_length); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_bz2_BZ2Decompressor___init____doc__, +"BZ2Decompressor()\n" +"--\n" +"\n" +"Create a decompressor object for decompressing data incrementally.\n" +"\n" +"For one-shot decompression, use the decompress() function instead."); + +static int +_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self); + +static int +_bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + if (Py_IS_TYPE(self, &BZ2Decompressor_Type) && - !_PyArg_NoPositional("BZ2Decompressor", args)) { - goto exit; - } + !_PyArg_NoPositional("BZ2Decompressor", args)) { + goto exit; + } if (Py_IS_TYPE(self, &BZ2Decompressor_Type) && - !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { - goto exit; - } - return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self); - -exit: - return return_value; -} + !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { + goto exit; + } + return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self); + +exit: + return return_value; +} /*[clinic end generated code: output=3f3f1e788fe28ee1 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_codecsmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_codecsmodule.c.h index 7ddc36de8a7..e838f335225 100644 --- a/contrib/tools/python3/src/Modules/clinic/_codecsmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_codecsmodule.c.h @@ -1,42 +1,42 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_codecs_register__doc__, -"register($module, search_function, /)\n" -"--\n" -"\n" -"Register a codec search function.\n" -"\n" -"Search functions are expected to take one argument, the encoding name in\n" -"all lower case letters, and either return None, or a tuple of functions\n" -"(encoder, decoder, stream_reader, stream_writer) (or a CodecInfo object)."); - -#define _CODECS_REGISTER_METHODDEF \ - {"register", (PyCFunction)_codecs_register, METH_O, _codecs_register__doc__}, - -PyDoc_STRVAR(_codecs_lookup__doc__, -"lookup($module, encoding, /)\n" -"--\n" -"\n" -"Looks up a codec tuple in the Python codec registry and returns a CodecInfo object."); - -#define _CODECS_LOOKUP_METHODDEF \ - {"lookup", (PyCFunction)_codecs_lookup, METH_O, _codecs_lookup__doc__}, - -static PyObject * -_codecs_lookup_impl(PyObject *module, const char *encoding); - -static PyObject * -_codecs_lookup(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *encoding; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_codecs_register__doc__, +"register($module, search_function, /)\n" +"--\n" +"\n" +"Register a codec search function.\n" +"\n" +"Search functions are expected to take one argument, the encoding name in\n" +"all lower case letters, and either return None, or a tuple of functions\n" +"(encoder, decoder, stream_reader, stream_writer) (or a CodecInfo object)."); + +#define _CODECS_REGISTER_METHODDEF \ + {"register", (PyCFunction)_codecs_register, METH_O, _codecs_register__doc__}, + +PyDoc_STRVAR(_codecs_lookup__doc__, +"lookup($module, encoding, /)\n" +"--\n" +"\n" +"Looks up a codec tuple in the Python codec registry and returns a CodecInfo object."); + +#define _CODECS_LOOKUP_METHODDEF \ + {"lookup", (PyCFunction)_codecs_lookup, METH_O, _codecs_lookup__doc__}, + +static PyObject * +_codecs_lookup_impl(PyObject *module, const char *encoding); + +static PyObject * +_codecs_lookup(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *encoding; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("lookup", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t encoding_length; encoding = PyUnicode_AsUTF8AndSize(arg, &encoding_length); if (encoding == NULL) { @@ -46,47 +46,47 @@ _codecs_lookup(PyObject *module, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _codecs_lookup_impl(module, encoding); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_encode__doc__, -"encode($module, /, obj, encoding=\'utf-8\', errors=\'strict\')\n" -"--\n" -"\n" -"Encodes obj using the codec registered for encoding.\n" -"\n" -"The default encoding is \'utf-8\'. errors may be given to set a\n" -"different error handling scheme. Default is \'strict\' meaning that encoding\n" -"errors raise a ValueError. Other possible values are \'ignore\', \'replace\'\n" -"and \'backslashreplace\' as well as any other name registered with\n" -"codecs.register_error that can handle ValueErrors."); - -#define _CODECS_ENCODE_METHODDEF \ + return_value = _codecs_lookup_impl(module, encoding); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_encode__doc__, +"encode($module, /, obj, encoding=\'utf-8\', errors=\'strict\')\n" +"--\n" +"\n" +"Encodes obj using the codec registered for encoding.\n" +"\n" +"The default encoding is \'utf-8\'. errors may be given to set a\n" +"different error handling scheme. Default is \'strict\' meaning that encoding\n" +"errors raise a ValueError. Other possible values are \'ignore\', \'replace\'\n" +"and \'backslashreplace\' as well as any other name registered with\n" +"codecs.register_error that can handle ValueErrors."); + +#define _CODECS_ENCODE_METHODDEF \ {"encode", (PyCFunction)(void(*)(void))_codecs_encode, METH_FASTCALL|METH_KEYWORDS, _codecs_encode__doc__}, - -static PyObject * -_codecs_encode_impl(PyObject *module, PyObject *obj, const char *encoding, - const char *errors); - -static PyObject * -_codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; + +static PyObject * +_codecs_encode_impl(PyObject *module, PyObject *obj, const char *encoding, + const char *errors); + +static PyObject * +_codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *obj; - const char *encoding = NULL; - const char *errors = NULL; - + PyObject *obj; + const char *encoding = NULL; + const char *errors = NULL; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } obj = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -123,47 +123,47 @@ _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje goto exit; } skip_optional_pos: - return_value = _codecs_encode_impl(module, obj, encoding, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_decode__doc__, -"decode($module, /, obj, encoding=\'utf-8\', errors=\'strict\')\n" -"--\n" -"\n" -"Decodes obj using the codec registered for encoding.\n" -"\n" -"Default encoding is \'utf-8\'. errors may be given to set a\n" -"different error handling scheme. Default is \'strict\' meaning that encoding\n" -"errors raise a ValueError. Other possible values are \'ignore\', \'replace\'\n" -"and \'backslashreplace\' as well as any other name registered with\n" -"codecs.register_error that can handle ValueErrors."); - -#define _CODECS_DECODE_METHODDEF \ + return_value = _codecs_encode_impl(module, obj, encoding, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_decode__doc__, +"decode($module, /, obj, encoding=\'utf-8\', errors=\'strict\')\n" +"--\n" +"\n" +"Decodes obj using the codec registered for encoding.\n" +"\n" +"Default encoding is \'utf-8\'. errors may be given to set a\n" +"different error handling scheme. Default is \'strict\' meaning that encoding\n" +"errors raise a ValueError. Other possible values are \'ignore\', \'replace\'\n" +"and \'backslashreplace\' as well as any other name registered with\n" +"codecs.register_error that can handle ValueErrors."); + +#define _CODECS_DECODE_METHODDEF \ {"decode", (PyCFunction)(void(*)(void))_codecs_decode, METH_FASTCALL|METH_KEYWORDS, _codecs_decode__doc__}, - -static PyObject * -_codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding, - const char *errors); - -static PyObject * -_codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; + +static PyObject * +_codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding, + const char *errors); + +static PyObject * +_codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *obj; - const char *encoding = NULL; - const char *errors = NULL; - + PyObject *obj; + const char *encoding = NULL; + const char *errors = NULL; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } obj = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -200,34 +200,34 @@ _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje goto exit; } skip_optional_pos: - return_value = _codecs_decode_impl(module, obj, encoding, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs__forget_codec__doc__, -"_forget_codec($module, encoding, /)\n" -"--\n" -"\n" -"Purge the named codec from the internal codec lookup cache"); - -#define _CODECS__FORGET_CODEC_METHODDEF \ - {"_forget_codec", (PyCFunction)_codecs__forget_codec, METH_O, _codecs__forget_codec__doc__}, - -static PyObject * -_codecs__forget_codec_impl(PyObject *module, const char *encoding); - -static PyObject * -_codecs__forget_codec(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *encoding; - + return_value = _codecs_decode_impl(module, obj, encoding, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs__forget_codec__doc__, +"_forget_codec($module, encoding, /)\n" +"--\n" +"\n" +"Purge the named codec from the internal codec lookup cache"); + +#define _CODECS__FORGET_CODEC_METHODDEF \ + {"_forget_codec", (PyCFunction)_codecs__forget_codec, METH_O, _codecs__forget_codec__doc__}, + +static PyObject * +_codecs__forget_codec_impl(PyObject *module, const char *encoding); + +static PyObject * +_codecs__forget_codec(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *encoding; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("_forget_codec", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t encoding_length; encoding = PyUnicode_AsUTF8AndSize(arg, &encoding_length); if (encoding == NULL) { @@ -237,34 +237,34 @@ _codecs__forget_codec(PyObject *module, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _codecs__forget_codec_impl(module, encoding); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_escape_decode__doc__, -"escape_decode($module, data, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_ESCAPE_DECODE_METHODDEF \ + return_value = _codecs__forget_codec_impl(module, encoding); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_escape_decode__doc__, +"escape_decode($module, data, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_ESCAPE_DECODE_METHODDEF \ {"escape_decode", (PyCFunction)(void(*)(void))_codecs_escape_decode, METH_FASTCALL, _codecs_escape_decode__doc__}, - -static PyObject * -_codecs_escape_decode_impl(PyObject *module, Py_buffer *data, - const char *errors); - -static PyObject * -_codecs_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - + +static PyObject * +_codecs_escape_decode_impl(PyObject *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + if (!_PyArg_CheckPositional("escape_decode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyUnicode_Check(args[0])) { Py_ssize_t len; const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); @@ -304,43 +304,43 @@ _codecs_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_escape_decode_impl(module, &data, errors); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_escape_encode__doc__, -"escape_encode($module, data, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_ESCAPE_ENCODE_METHODDEF \ + return_value = _codecs_escape_decode_impl(module, &data, errors); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_escape_encode__doc__, +"escape_encode($module, data, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_ESCAPE_ENCODE_METHODDEF \ {"escape_encode", (PyCFunction)(void(*)(void))_codecs_escape_encode, METH_FASTCALL, _codecs_escape_encode__doc__}, - -static PyObject * -_codecs_escape_encode_impl(PyObject *module, PyObject *data, - const char *errors); - -static PyObject * -_codecs_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *data; - const char *errors = NULL; - + +static PyObject * +_codecs_escape_encode_impl(PyObject *module, PyObject *data, + const char *errors); + +static PyObject * +_codecs_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *data; + const char *errors = NULL; + if (!_PyArg_CheckPositional("escape_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyBytes_Check(args[0])) { _PyArg_BadArgument("escape_encode", "argument 1", "bytes", args[0]); - goto exit; - } + goto exit; + } data = args[0]; if (nargs < 2) { goto skip_optional; @@ -365,34 +365,34 @@ _codecs_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } skip_optional: return_value = _codecs_escape_encode_impl(module, data, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_7_decode__doc__, -"utf_7_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_7_DECODE_METHODDEF \ + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_7_decode__doc__, +"utf_7_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_7_DECODE_METHODDEF \ {"utf_7_decode", (PyCFunction)(void(*)(void))_codecs_utf_7_decode, METH_FASTCALL, _codecs_utf_7_decode__doc__}, - -static PyObject * -_codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("utf_7_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -434,40 +434,40 @@ _codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_utf_7_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_8_decode__doc__, -"utf_8_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_8_DECODE_METHODDEF \ + return_value = _codecs_utf_7_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_8_decode__doc__, +"utf_8_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_8_DECODE_METHODDEF \ {"utf_8_decode", (PyCFunction)(void(*)(void))_codecs_utf_8_decode, METH_FASTCALL, _codecs_utf_8_decode__doc__}, - -static PyObject * -_codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("utf_8_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -509,40 +509,40 @@ _codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_utf_8_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_16_decode__doc__, -"utf_16_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_16_DECODE_METHODDEF \ + return_value = _codecs_utf_8_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_16_decode__doc__, +"utf_16_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_16_DECODE_METHODDEF \ {"utf_16_decode", (PyCFunction)(void(*)(void))_codecs_utf_16_decode, METH_FASTCALL, _codecs_utf_16_decode__doc__}, - -static PyObject * -_codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("utf_16_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -584,40 +584,40 @@ _codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_utf_16_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_16_le_decode__doc__, -"utf_16_le_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_16_LE_DECODE_METHODDEF \ + return_value = _codecs_utf_16_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_16_le_decode__doc__, +"utf_16_le_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_16_LE_DECODE_METHODDEF \ {"utf_16_le_decode", (PyCFunction)(void(*)(void))_codecs_utf_16_le_decode, METH_FASTCALL, _codecs_utf_16_le_decode__doc__}, - -static PyObject * -_codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("utf_16_le_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -659,40 +659,40 @@ _codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_16_le_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_16_be_decode__doc__, -"utf_16_be_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_16_BE_DECODE_METHODDEF \ + return_value = _codecs_utf_16_le_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_16_be_decode__doc__, +"utf_16_be_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_16_BE_DECODE_METHODDEF \ {"utf_16_be_decode", (PyCFunction)(void(*)(void))_codecs_utf_16_be_decode, METH_FASTCALL, _codecs_utf_16_be_decode__doc__}, - -static PyObject * -_codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("utf_16_be_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -734,42 +734,42 @@ _codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_16_be_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_16_ex_decode__doc__, -"utf_16_ex_decode($module, data, errors=None, byteorder=0, final=False,\n" -" /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_16_EX_DECODE_METHODDEF \ + return_value = _codecs_utf_16_be_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_16_ex_decode__doc__, +"utf_16_ex_decode($module, data, errors=None, byteorder=0, final=False,\n" +" /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_16_EX_DECODE_METHODDEF \ {"utf_16_ex_decode", (PyCFunction)(void(*)(void))_codecs_utf_16_ex_decode, METH_FASTCALL, _codecs_utf_16_ex_decode__doc__}, - -static PyObject * -_codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int byteorder, int final); - -static PyObject * -_codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int byteorder = 0; - int final = 0; - + +static PyObject * +_codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int byteorder, int final); + +static PyObject * +_codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int byteorder = 0; + int final = 0; + if (!_PyArg_CheckPositional("utf_16_ex_decode", nargs, 1, 4)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -823,40 +823,40 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_16_ex_decode_impl(module, &data, errors, byteorder, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_32_decode__doc__, -"utf_32_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_32_DECODE_METHODDEF \ + return_value = _codecs_utf_16_ex_decode_impl(module, &data, errors, byteorder, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_32_decode__doc__, +"utf_32_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_32_DECODE_METHODDEF \ {"utf_32_decode", (PyCFunction)(void(*)(void))_codecs_utf_32_decode, METH_FASTCALL, _codecs_utf_32_decode__doc__}, - -static PyObject * -_codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("utf_32_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -898,40 +898,40 @@ _codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_utf_32_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_32_le_decode__doc__, -"utf_32_le_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_32_LE_DECODE_METHODDEF \ + return_value = _codecs_utf_32_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_32_le_decode__doc__, +"utf_32_le_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_32_LE_DECODE_METHODDEF \ {"utf_32_le_decode", (PyCFunction)(void(*)(void))_codecs_utf_32_le_decode, METH_FASTCALL, _codecs_utf_32_le_decode__doc__}, - -static PyObject * -_codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("utf_32_le_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -973,40 +973,40 @@ _codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_32_le_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_32_be_decode__doc__, -"utf_32_be_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_32_BE_DECODE_METHODDEF \ + return_value = _codecs_utf_32_le_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_32_be_decode__doc__, +"utf_32_be_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_32_BE_DECODE_METHODDEF \ {"utf_32_be_decode", (PyCFunction)(void(*)(void))_codecs_utf_32_be_decode, METH_FASTCALL, _codecs_utf_32_be_decode__doc__}, - -static PyObject * -_codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("utf_32_be_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1048,42 +1048,42 @@ _codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_32_be_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_32_ex_decode__doc__, -"utf_32_ex_decode($module, data, errors=None, byteorder=0, final=False,\n" -" /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_32_EX_DECODE_METHODDEF \ + return_value = _codecs_utf_32_be_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_32_ex_decode__doc__, +"utf_32_ex_decode($module, data, errors=None, byteorder=0, final=False,\n" +" /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_32_EX_DECODE_METHODDEF \ {"utf_32_ex_decode", (PyCFunction)(void(*)(void))_codecs_utf_32_ex_decode, METH_FASTCALL, _codecs_utf_32_ex_decode__doc__}, - -static PyObject * -_codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int byteorder, int final); - -static PyObject * -_codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int byteorder = 0; - int final = 0; - + +static PyObject * +_codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int byteorder, int final); + +static PyObject * +_codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int byteorder = 0; + int final = 0; + if (!_PyArg_CheckPositional("utf_32_ex_decode", nargs, 1, 4)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1137,40 +1137,40 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_32_ex_decode_impl(module, &data, errors, byteorder, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_unicode_escape_decode__doc__, + return_value = _codecs_utf_32_ex_decode_impl(module, &data, errors, byteorder, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_unicode_escape_decode__doc__, "unicode_escape_decode($module, data, errors=None, final=True, /)\n" -"--\n" -"\n"); - -#define _CODECS_UNICODE_ESCAPE_DECODE_METHODDEF \ +"--\n" +"\n"); + +#define _CODECS_UNICODE_ESCAPE_DECODE_METHODDEF \ {"unicode_escape_decode", (PyCFunction)(void(*)(void))_codecs_unicode_escape_decode, METH_FASTCALL, _codecs_unicode_escape_decode__doc__}, - -static PyObject * -_codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, + +static PyObject * +_codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final); - -static PyObject * -_codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; + +static PyObject * +_codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; int final = 1; - + if (!_PyArg_CheckPositional("unicode_escape_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyUnicode_Check(args[0])) { Py_ssize_t len; const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); @@ -1223,39 +1223,39 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_ } skip_optional: return_value = _codecs_unicode_escape_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_raw_unicode_escape_decode__doc__, + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_raw_unicode_escape_decode__doc__, "raw_unicode_escape_decode($module, data, errors=None, final=True, /)\n" -"--\n" -"\n"); - -#define _CODECS_RAW_UNICODE_ESCAPE_DECODE_METHODDEF \ +"--\n" +"\n"); + +#define _CODECS_RAW_UNICODE_ESCAPE_DECODE_METHODDEF \ {"raw_unicode_escape_decode", (PyCFunction)(void(*)(void))_codecs_raw_unicode_escape_decode, METH_FASTCALL, _codecs_raw_unicode_escape_decode__doc__}, - -static PyObject * -_codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, + +static PyObject * +_codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final); - -static PyObject * -_codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; + +static PyObject * +_codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; int final = 1; - + if (!_PyArg_CheckPositional("raw_unicode_escape_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyUnicode_Check(args[0])) { Py_ssize_t len; const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); @@ -1308,38 +1308,38 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ss } skip_optional: return_value = _codecs_raw_unicode_escape_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_latin_1_decode__doc__, -"latin_1_decode($module, data, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_LATIN_1_DECODE_METHODDEF \ + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_latin_1_decode__doc__, +"latin_1_decode($module, data, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_LATIN_1_DECODE_METHODDEF \ {"latin_1_decode", (PyCFunction)(void(*)(void))_codecs_latin_1_decode, METH_FASTCALL, _codecs_latin_1_decode__doc__}, - -static PyObject * -_codecs_latin_1_decode_impl(PyObject *module, Py_buffer *data, - const char *errors); - -static PyObject * -_codecs_latin_1_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - + +static PyObject * +_codecs_latin_1_decode_impl(PyObject *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_latin_1_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + if (!_PyArg_CheckPositional("latin_1_decode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1369,39 +1369,39 @@ _codecs_latin_1_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } skip_optional: - return_value = _codecs_latin_1_decode_impl(module, &data, errors); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_ascii_decode__doc__, -"ascii_decode($module, data, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_ASCII_DECODE_METHODDEF \ + return_value = _codecs_latin_1_decode_impl(module, &data, errors); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_ascii_decode__doc__, +"ascii_decode($module, data, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_ASCII_DECODE_METHODDEF \ {"ascii_decode", (PyCFunction)(void(*)(void))_codecs_ascii_decode, METH_FASTCALL, _codecs_ascii_decode__doc__}, - -static PyObject * -_codecs_ascii_decode_impl(PyObject *module, Py_buffer *data, - const char *errors); - -static PyObject * -_codecs_ascii_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - + +static PyObject * +_codecs_ascii_decode_impl(PyObject *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_ascii_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + if (!_PyArg_CheckPositional("ascii_decode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1431,40 +1431,40 @@ _codecs_ascii_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_ascii_decode_impl(module, &data, errors); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_charmap_decode__doc__, -"charmap_decode($module, data, errors=None, mapping=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_CHARMAP_DECODE_METHODDEF \ + return_value = _codecs_ascii_decode_impl(module, &data, errors); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_charmap_decode__doc__, +"charmap_decode($module, data, errors=None, mapping=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_CHARMAP_DECODE_METHODDEF \ {"charmap_decode", (PyCFunction)(void(*)(void))_codecs_charmap_decode, METH_FASTCALL, _codecs_charmap_decode__doc__}, - -static PyObject * -_codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, PyObject *mapping); - -static PyObject * -_codecs_charmap_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; + +static PyObject * +_codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, PyObject *mapping); + +static PyObject * +_codecs_charmap_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; PyObject *mapping = Py_None; - + if (!_PyArg_CheckPositional("charmap_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1498,42 +1498,42 @@ _codecs_charmap_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs } mapping = args[2]; skip_optional: - return_value = _codecs_charmap_decode_impl(module, &data, errors, mapping); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_codecs_mbcs_decode__doc__, -"mbcs_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_MBCS_DECODE_METHODDEF \ + return_value = _codecs_charmap_decode_impl(module, &data, errors, mapping); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_codecs_mbcs_decode__doc__, +"mbcs_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_MBCS_DECODE_METHODDEF \ {"mbcs_decode", (PyCFunction)(void(*)(void))_codecs_mbcs_decode, METH_FASTCALL, _codecs_mbcs_decode__doc__}, - -static PyObject * -_codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("mbcs_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1575,44 +1575,44 @@ _codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_mbcs_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_codecs_oem_decode__doc__, -"oem_decode($module, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_OEM_DECODE_METHODDEF \ + return_value = _codecs_mbcs_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_codecs_oem_decode__doc__, +"oem_decode($module, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_OEM_DECODE_METHODDEF \ {"oem_decode", (PyCFunction)(void(*)(void))_codecs_oem_decode, METH_FASTCALL, _codecs_oem_decode__doc__}, - -static PyObject * -_codecs_oem_decode_impl(PyObject *module, Py_buffer *data, - const char *errors, int final); - -static PyObject * -_codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_oem_decode_impl(PyObject *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("oem_decode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1654,45 +1654,45 @@ _codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_oem_decode_impl(module, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_codecs_code_page_decode__doc__, -"code_page_decode($module, codepage, data, errors=None, final=False, /)\n" -"--\n" -"\n"); - -#define _CODECS_CODE_PAGE_DECODE_METHODDEF \ + return_value = _codecs_oem_decode_impl(module, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_codecs_code_page_decode__doc__, +"code_page_decode($module, codepage, data, errors=None, final=False, /)\n" +"--\n" +"\n"); + +#define _CODECS_CODE_PAGE_DECODE_METHODDEF \ {"code_page_decode", (PyCFunction)(void(*)(void))_codecs_code_page_decode, METH_FASTCALL, _codecs_code_page_decode__doc__}, - -static PyObject * -_codecs_code_page_decode_impl(PyObject *module, int codepage, - Py_buffer *data, const char *errors, int final); - -static PyObject * -_codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int codepage; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - int final = 0; - + +static PyObject * +_codecs_code_page_decode_impl(PyObject *module, int codepage, + Py_buffer *data, const char *errors, int final); + +static PyObject * +_codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int codepage; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + if (!_PyArg_CheckPositional("code_page_decode", nargs, 2, 4)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -1743,41 +1743,41 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_code_page_decode_impl(module, codepage, &data, errors, final); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -PyDoc_STRVAR(_codecs_readbuffer_encode__doc__, -"readbuffer_encode($module, data, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_READBUFFER_ENCODE_METHODDEF \ + return_value = _codecs_code_page_decode_impl(module, codepage, &data, errors, final); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +PyDoc_STRVAR(_codecs_readbuffer_encode__doc__, +"readbuffer_encode($module, data, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_READBUFFER_ENCODE_METHODDEF \ {"readbuffer_encode", (PyCFunction)(void(*)(void))_codecs_readbuffer_encode, METH_FASTCALL, _codecs_readbuffer_encode__doc__}, - -static PyObject * -_codecs_readbuffer_encode_impl(PyObject *module, Py_buffer *data, - const char *errors); - -static PyObject * -_codecs_readbuffer_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - const char *errors = NULL; - + +static PyObject * +_codecs_readbuffer_encode_impl(PyObject *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_readbuffer_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + if (!_PyArg_CheckPositional("readbuffer_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyUnicode_Check(args[0])) { Py_ssize_t len; const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); @@ -1817,39 +1817,39 @@ _codecs_readbuffer_encode(PyObject *module, PyObject *const *args, Py_ssize_t na goto exit; } skip_optional: - return_value = _codecs_readbuffer_encode_impl(module, &data, errors); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_7_encode__doc__, -"utf_7_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_7_ENCODE_METHODDEF \ + return_value = _codecs_readbuffer_encode_impl(module, &data, errors); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_7_encode__doc__, +"utf_7_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_7_ENCODE_METHODDEF \ {"utf_7_encode", (PyCFunction)(void(*)(void))_codecs_utf_7_encode, METH_FASTCALL, _codecs_utf_7_encode__doc__}, - -static PyObject * -_codecs_utf_7_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_utf_7_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_utf_7_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_7_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("utf_7_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("utf_7_encode", "argument 1", "str", args[0]); goto exit; @@ -1880,34 +1880,34 @@ _codecs_utf_7_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_utf_7_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_8_encode__doc__, -"utf_8_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_8_ENCODE_METHODDEF \ + return_value = _codecs_utf_7_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_8_encode__doc__, +"utf_8_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_8_ENCODE_METHODDEF \ {"utf_8_encode", (PyCFunction)(void(*)(void))_codecs_utf_8_encode, METH_FASTCALL, _codecs_utf_8_encode__doc__}, - -static PyObject * -_codecs_utf_8_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_utf_8_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_utf_8_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_8_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("utf_8_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("utf_8_encode", "argument 1", "str", args[0]); goto exit; @@ -1938,35 +1938,35 @@ _codecs_utf_8_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_utf_8_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_16_encode__doc__, -"utf_16_encode($module, str, errors=None, byteorder=0, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_16_ENCODE_METHODDEF \ + return_value = _codecs_utf_8_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_16_encode__doc__, +"utf_16_encode($module, str, errors=None, byteorder=0, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_16_ENCODE_METHODDEF \ {"utf_16_encode", (PyCFunction)(void(*)(void))_codecs_utf_16_encode, METH_FASTCALL, _codecs_utf_16_encode__doc__}, - -static PyObject * -_codecs_utf_16_encode_impl(PyObject *module, PyObject *str, - const char *errors, int byteorder); - -static PyObject * -_codecs_utf_16_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - int byteorder = 0; - + +static PyObject * +_codecs_utf_16_encode_impl(PyObject *module, PyObject *str, + const char *errors, int byteorder); + +static PyObject * +_codecs_utf_16_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + int byteorder = 0; + if (!_PyArg_CheckPositional("utf_16_encode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("utf_16_encode", "argument 1", "str", args[0]); goto exit; @@ -2009,34 +2009,34 @@ _codecs_utf_16_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_utf_16_encode_impl(module, str, errors, byteorder); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_16_le_encode__doc__, -"utf_16_le_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_16_LE_ENCODE_METHODDEF \ + return_value = _codecs_utf_16_encode_impl(module, str, errors, byteorder); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_16_le_encode__doc__, +"utf_16_le_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_16_LE_ENCODE_METHODDEF \ {"utf_16_le_encode", (PyCFunction)(void(*)(void))_codecs_utf_16_le_encode, METH_FASTCALL, _codecs_utf_16_le_encode__doc__}, - -static PyObject * -_codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_utf_16_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_16_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("utf_16_le_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("utf_16_le_encode", "argument 1", "str", args[0]); goto exit; @@ -2067,34 +2067,34 @@ _codecs_utf_16_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_16_le_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_16_be_encode__doc__, -"utf_16_be_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_16_BE_ENCODE_METHODDEF \ + return_value = _codecs_utf_16_le_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_16_be_encode__doc__, +"utf_16_be_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_16_BE_ENCODE_METHODDEF \ {"utf_16_be_encode", (PyCFunction)(void(*)(void))_codecs_utf_16_be_encode, METH_FASTCALL, _codecs_utf_16_be_encode__doc__}, - -static PyObject * -_codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_utf_16_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_16_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("utf_16_be_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("utf_16_be_encode", "argument 1", "str", args[0]); goto exit; @@ -2125,35 +2125,35 @@ _codecs_utf_16_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_16_be_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_32_encode__doc__, -"utf_32_encode($module, str, errors=None, byteorder=0, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_32_ENCODE_METHODDEF \ + return_value = _codecs_utf_16_be_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_32_encode__doc__, +"utf_32_encode($module, str, errors=None, byteorder=0, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_32_ENCODE_METHODDEF \ {"utf_32_encode", (PyCFunction)(void(*)(void))_codecs_utf_32_encode, METH_FASTCALL, _codecs_utf_32_encode__doc__}, - -static PyObject * -_codecs_utf_32_encode_impl(PyObject *module, PyObject *str, - const char *errors, int byteorder); - -static PyObject * -_codecs_utf_32_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - int byteorder = 0; - + +static PyObject * +_codecs_utf_32_encode_impl(PyObject *module, PyObject *str, + const char *errors, int byteorder); + +static PyObject * +_codecs_utf_32_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + int byteorder = 0; + if (!_PyArg_CheckPositional("utf_32_encode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("utf_32_encode", "argument 1", "str", args[0]); goto exit; @@ -2196,34 +2196,34 @@ _codecs_utf_32_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_utf_32_encode_impl(module, str, errors, byteorder); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_32_le_encode__doc__, -"utf_32_le_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_32_LE_ENCODE_METHODDEF \ + return_value = _codecs_utf_32_encode_impl(module, str, errors, byteorder); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_32_le_encode__doc__, +"utf_32_le_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_32_LE_ENCODE_METHODDEF \ {"utf_32_le_encode", (PyCFunction)(void(*)(void))_codecs_utf_32_le_encode, METH_FASTCALL, _codecs_utf_32_le_encode__doc__}, - -static PyObject * -_codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_utf_32_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_32_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("utf_32_le_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("utf_32_le_encode", "argument 1", "str", args[0]); goto exit; @@ -2254,34 +2254,34 @@ _codecs_utf_32_le_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_32_le_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_utf_32_be_encode__doc__, -"utf_32_be_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_UTF_32_BE_ENCODE_METHODDEF \ + return_value = _codecs_utf_32_le_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_utf_32_be_encode__doc__, +"utf_32_be_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UTF_32_BE_ENCODE_METHODDEF \ {"utf_32_be_encode", (PyCFunction)(void(*)(void))_codecs_utf_32_be_encode, METH_FASTCALL, _codecs_utf_32_be_encode__doc__}, - -static PyObject * -_codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_utf_32_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_32_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("utf_32_be_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("utf_32_be_encode", "argument 1", "str", args[0]); goto exit; @@ -2312,34 +2312,34 @@ _codecs_utf_32_be_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_utf_32_be_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_unicode_escape_encode__doc__, -"unicode_escape_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_UNICODE_ESCAPE_ENCODE_METHODDEF \ + return_value = _codecs_utf_32_be_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_unicode_escape_encode__doc__, +"unicode_escape_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UNICODE_ESCAPE_ENCODE_METHODDEF \ {"unicode_escape_encode", (PyCFunction)(void(*)(void))_codecs_unicode_escape_encode, METH_FASTCALL, _codecs_unicode_escape_encode__doc__}, - -static PyObject * -_codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("unicode_escape_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("unicode_escape_encode", "argument 1", "str", args[0]); goto exit; @@ -2370,34 +2370,34 @@ _codecs_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_ goto exit; } skip_optional: - return_value = _codecs_unicode_escape_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_raw_unicode_escape_encode__doc__, -"raw_unicode_escape_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_RAW_UNICODE_ESCAPE_ENCODE_METHODDEF \ + return_value = _codecs_unicode_escape_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_raw_unicode_escape_encode__doc__, +"raw_unicode_escape_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_RAW_UNICODE_ESCAPE_ENCODE_METHODDEF \ {"raw_unicode_escape_encode", (PyCFunction)(void(*)(void))_codecs_raw_unicode_escape_encode, METH_FASTCALL, _codecs_raw_unicode_escape_encode__doc__}, - -static PyObject * -_codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_raw_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_raw_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("raw_unicode_escape_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("raw_unicode_escape_encode", "argument 1", "str", args[0]); goto exit; @@ -2428,34 +2428,34 @@ _codecs_raw_unicode_escape_encode(PyObject *module, PyObject *const *args, Py_ss goto exit; } skip_optional: - return_value = _codecs_raw_unicode_escape_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_latin_1_encode__doc__, -"latin_1_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_LATIN_1_ENCODE_METHODDEF \ + return_value = _codecs_raw_unicode_escape_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_latin_1_encode__doc__, +"latin_1_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_LATIN_1_ENCODE_METHODDEF \ {"latin_1_encode", (PyCFunction)(void(*)(void))_codecs_latin_1_encode, METH_FASTCALL, _codecs_latin_1_encode__doc__}, - -static PyObject * -_codecs_latin_1_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_latin_1_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_latin_1_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_latin_1_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("latin_1_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("latin_1_encode", "argument 1", "str", args[0]); goto exit; @@ -2486,34 +2486,34 @@ _codecs_latin_1_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } skip_optional: - return_value = _codecs_latin_1_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_ascii_encode__doc__, -"ascii_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_ASCII_ENCODE_METHODDEF \ + return_value = _codecs_latin_1_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_ascii_encode__doc__, +"ascii_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_ASCII_ENCODE_METHODDEF \ {"ascii_encode", (PyCFunction)(void(*)(void))_codecs_ascii_encode, METH_FASTCALL, _codecs_ascii_encode__doc__}, - -static PyObject * -_codecs_ascii_encode_impl(PyObject *module, PyObject *str, - const char *errors); - -static PyObject * -_codecs_ascii_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_ascii_encode_impl(PyObject *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_ascii_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("ascii_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("ascii_encode", "argument 1", "str", args[0]); goto exit; @@ -2544,35 +2544,35 @@ _codecs_ascii_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_ascii_encode_impl(module, str, errors); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_charmap_encode__doc__, -"charmap_encode($module, str, errors=None, mapping=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_CHARMAP_ENCODE_METHODDEF \ + return_value = _codecs_ascii_encode_impl(module, str, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_charmap_encode__doc__, +"charmap_encode($module, str, errors=None, mapping=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_CHARMAP_ENCODE_METHODDEF \ {"charmap_encode", (PyCFunction)(void(*)(void))_codecs_charmap_encode, METH_FASTCALL, _codecs_charmap_encode__doc__}, - -static PyObject * -_codecs_charmap_encode_impl(PyObject *module, PyObject *str, - const char *errors, PyObject *mapping); - -static PyObject * -_codecs_charmap_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; + +static PyObject * +_codecs_charmap_encode_impl(PyObject *module, PyObject *str, + const char *errors, PyObject *mapping); + +static PyObject * +_codecs_charmap_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; PyObject *mapping = Py_None; - + if (!_PyArg_CheckPositional("charmap_encode", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("charmap_encode", "argument 1", "str", args[0]); goto exit; @@ -2607,66 +2607,66 @@ _codecs_charmap_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs } mapping = args[2]; skip_optional: - return_value = _codecs_charmap_encode_impl(module, str, errors, mapping); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_charmap_build__doc__, -"charmap_build($module, map, /)\n" -"--\n" -"\n"); - -#define _CODECS_CHARMAP_BUILD_METHODDEF \ - {"charmap_build", (PyCFunction)_codecs_charmap_build, METH_O, _codecs_charmap_build__doc__}, - -static PyObject * -_codecs_charmap_build_impl(PyObject *module, PyObject *map); - -static PyObject * -_codecs_charmap_build(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *map; - + return_value = _codecs_charmap_encode_impl(module, str, errors, mapping); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_charmap_build__doc__, +"charmap_build($module, map, /)\n" +"--\n" +"\n"); + +#define _CODECS_CHARMAP_BUILD_METHODDEF \ + {"charmap_build", (PyCFunction)_codecs_charmap_build, METH_O, _codecs_charmap_build__doc__}, + +static PyObject * +_codecs_charmap_build_impl(PyObject *module, PyObject *map); + +static PyObject * +_codecs_charmap_build(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *map; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("charmap_build", "argument", "str", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg) == -1) { goto exit; } map = arg; - return_value = _codecs_charmap_build_impl(module, map); - -exit: - return return_value; -} - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_codecs_mbcs_encode__doc__, -"mbcs_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_MBCS_ENCODE_METHODDEF \ + return_value = _codecs_charmap_build_impl(module, map); + +exit: + return return_value; +} + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_codecs_mbcs_encode__doc__, +"mbcs_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_MBCS_ENCODE_METHODDEF \ {"mbcs_encode", (PyCFunction)(void(*)(void))_codecs_mbcs_encode, METH_FASTCALL, _codecs_mbcs_encode__doc__}, - -static PyObject * -_codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors); - -static PyObject * -_codecs_mbcs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors); + +static PyObject * +_codecs_mbcs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("mbcs_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("mbcs_encode", "argument 1", "str", args[0]); goto exit; @@ -2697,37 +2697,37 @@ _codecs_mbcs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_mbcs_encode_impl(module, str, errors); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_codecs_oem_encode__doc__, -"oem_encode($module, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_OEM_ENCODE_METHODDEF \ + return_value = _codecs_mbcs_encode_impl(module, str, errors); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_codecs_oem_encode__doc__, +"oem_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_OEM_ENCODE_METHODDEF \ {"oem_encode", (PyCFunction)(void(*)(void))_codecs_oem_encode, METH_FASTCALL, _codecs_oem_encode__doc__}, - -static PyObject * -_codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors); - -static PyObject * -_codecs_oem_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors); + +static PyObject * +_codecs_oem_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("oem_encode", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("oem_encode", "argument 1", "str", args[0]); goto exit; @@ -2758,39 +2758,39 @@ _codecs_oem_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _codecs_oem_encode_impl(module, str, errors); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_codecs_code_page_encode__doc__, -"code_page_encode($module, code_page, str, errors=None, /)\n" -"--\n" -"\n"); - -#define _CODECS_CODE_PAGE_ENCODE_METHODDEF \ + return_value = _codecs_oem_encode_impl(module, str, errors); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(_codecs_code_page_encode__doc__, +"code_page_encode($module, code_page, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_CODE_PAGE_ENCODE_METHODDEF \ {"code_page_encode", (PyCFunction)(void(*)(void))_codecs_code_page_encode, METH_FASTCALL, _codecs_code_page_encode__doc__}, - -static PyObject * -_codecs_code_page_encode_impl(PyObject *module, int code_page, PyObject *str, - const char *errors); - -static PyObject * -_codecs_code_page_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int code_page; - PyObject *str; - const char *errors = NULL; - + +static PyObject * +_codecs_code_page_encode_impl(PyObject *module, int code_page, PyObject *str, + const char *errors); + +static PyObject * +_codecs_code_page_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int code_page; + PyObject *str; + const char *errors = NULL; + if (!_PyArg_CheckPositional("code_page_encode", nargs, 2, 3)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -2830,41 +2830,41 @@ _codecs_code_page_encode(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _codecs_code_page_encode_impl(module, code_page, str, errors); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -PyDoc_STRVAR(_codecs_register_error__doc__, -"register_error($module, errors, handler, /)\n" -"--\n" -"\n" -"Register the specified error handler under the name errors.\n" -"\n" -"handler must be a callable object, that will be called with an exception\n" -"instance containing information about the location of the encoding/decoding\n" -"error and must return a (replacement, new position) tuple."); - -#define _CODECS_REGISTER_ERROR_METHODDEF \ + return_value = _codecs_code_page_encode_impl(module, code_page, str, errors); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +PyDoc_STRVAR(_codecs_register_error__doc__, +"register_error($module, errors, handler, /)\n" +"--\n" +"\n" +"Register the specified error handler under the name errors.\n" +"\n" +"handler must be a callable object, that will be called with an exception\n" +"instance containing information about the location of the encoding/decoding\n" +"error and must return a (replacement, new position) tuple."); + +#define _CODECS_REGISTER_ERROR_METHODDEF \ {"register_error", (PyCFunction)(void(*)(void))_codecs_register_error, METH_FASTCALL, _codecs_register_error__doc__}, - -static PyObject * -_codecs_register_error_impl(PyObject *module, const char *errors, - PyObject *handler); - -static PyObject * -_codecs_register_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *errors; - PyObject *handler; - + +static PyObject * +_codecs_register_error_impl(PyObject *module, const char *errors, + PyObject *handler); + +static PyObject * +_codecs_register_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *errors; + PyObject *handler; + if (!_PyArg_CheckPositional("register_error", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("register_error", "argument 1", "str", args[0]); goto exit; @@ -2879,37 +2879,37 @@ _codecs_register_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs goto exit; } handler = args[1]; - return_value = _codecs_register_error_impl(module, errors, handler); - -exit: - return return_value; -} - -PyDoc_STRVAR(_codecs_lookup_error__doc__, -"lookup_error($module, name, /)\n" -"--\n" -"\n" -"lookup_error(errors) -> handler\n" -"\n" -"Return the error handler for the specified error handling name or raise a\n" -"LookupError, if no handler exists under this name."); - -#define _CODECS_LOOKUP_ERROR_METHODDEF \ - {"lookup_error", (PyCFunction)_codecs_lookup_error, METH_O, _codecs_lookup_error__doc__}, - -static PyObject * -_codecs_lookup_error_impl(PyObject *module, const char *name); - -static PyObject * -_codecs_lookup_error(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *name; - + return_value = _codecs_register_error_impl(module, errors, handler); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_lookup_error__doc__, +"lookup_error($module, name, /)\n" +"--\n" +"\n" +"lookup_error(errors) -> handler\n" +"\n" +"Return the error handler for the specified error handling name or raise a\n" +"LookupError, if no handler exists under this name."); + +#define _CODECS_LOOKUP_ERROR_METHODDEF \ + {"lookup_error", (PyCFunction)_codecs_lookup_error, METH_O, _codecs_lookup_error__doc__}, + +static PyObject * +_codecs_lookup_error_impl(PyObject *module, const char *name); + +static PyObject * +_codecs_lookup_error(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *name; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("lookup_error", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t name_length; name = PyUnicode_AsUTF8AndSize(arg, &name_length); if (name == NULL) { @@ -2919,33 +2919,33 @@ _codecs_lookup_error(PyObject *module, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _codecs_lookup_error_impl(module, name); - -exit: - return return_value; -} - -#ifndef _CODECS_MBCS_DECODE_METHODDEF - #define _CODECS_MBCS_DECODE_METHODDEF -#endif /* !defined(_CODECS_MBCS_DECODE_METHODDEF) */ - -#ifndef _CODECS_OEM_DECODE_METHODDEF - #define _CODECS_OEM_DECODE_METHODDEF -#endif /* !defined(_CODECS_OEM_DECODE_METHODDEF) */ - -#ifndef _CODECS_CODE_PAGE_DECODE_METHODDEF - #define _CODECS_CODE_PAGE_DECODE_METHODDEF -#endif /* !defined(_CODECS_CODE_PAGE_DECODE_METHODDEF) */ - -#ifndef _CODECS_MBCS_ENCODE_METHODDEF - #define _CODECS_MBCS_ENCODE_METHODDEF -#endif /* !defined(_CODECS_MBCS_ENCODE_METHODDEF) */ - -#ifndef _CODECS_OEM_ENCODE_METHODDEF - #define _CODECS_OEM_ENCODE_METHODDEF -#endif /* !defined(_CODECS_OEM_ENCODE_METHODDEF) */ - -#ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF - #define _CODECS_CODE_PAGE_ENCODE_METHODDEF -#endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ + return_value = _codecs_lookup_error_impl(module, name); + +exit: + return return_value; +} + +#ifndef _CODECS_MBCS_DECODE_METHODDEF + #define _CODECS_MBCS_DECODE_METHODDEF +#endif /* !defined(_CODECS_MBCS_DECODE_METHODDEF) */ + +#ifndef _CODECS_OEM_DECODE_METHODDEF + #define _CODECS_OEM_DECODE_METHODDEF +#endif /* !defined(_CODECS_OEM_DECODE_METHODDEF) */ + +#ifndef _CODECS_CODE_PAGE_DECODE_METHODDEF + #define _CODECS_CODE_PAGE_DECODE_METHODDEF +#endif /* !defined(_CODECS_CODE_PAGE_DECODE_METHODDEF) */ + +#ifndef _CODECS_MBCS_ENCODE_METHODDEF + #define _CODECS_MBCS_ENCODE_METHODDEF +#endif /* !defined(_CODECS_MBCS_ENCODE_METHODDEF) */ + +#ifndef _CODECS_OEM_ENCODE_METHODDEF + #define _CODECS_OEM_ENCODE_METHODDEF +#endif /* !defined(_CODECS_OEM_ENCODE_METHODDEF) */ + +#ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF + #define _CODECS_CODE_PAGE_ENCODE_METHODDEF +#endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ /*[clinic end generated code: output=eed7dc9312baf252 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_contextvarsmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_contextvarsmodule.c.h index b1885e41c35..28504d9d5ae 100644 --- a/contrib/tools/python3/src/Modules/clinic/_contextvarsmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_contextvarsmodule.c.h @@ -1,21 +1,21 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_contextvars_copy_context__doc__, -"copy_context($module, /)\n" -"--\n" -"\n"); - -#define _CONTEXTVARS_COPY_CONTEXT_METHODDEF \ - {"copy_context", (PyCFunction)_contextvars_copy_context, METH_NOARGS, _contextvars_copy_context__doc__}, - -static PyObject * -_contextvars_copy_context_impl(PyObject *module); - -static PyObject * -_contextvars_copy_context(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _contextvars_copy_context_impl(module); -} -/*[clinic end generated code: output=26e07024451baf52 input=a9049054013a1b77]*/ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_contextvars_copy_context__doc__, +"copy_context($module, /)\n" +"--\n" +"\n"); + +#define _CONTEXTVARS_COPY_CONTEXT_METHODDEF \ + {"copy_context", (PyCFunction)_contextvars_copy_context, METH_NOARGS, _contextvars_copy_context__doc__}, + +static PyObject * +_contextvars_copy_context_impl(PyObject *module); + +static PyObject * +_contextvars_copy_context(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _contextvars_copy_context_impl(module); +} +/*[clinic end generated code: output=26e07024451baf52 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_cryptmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_cryptmodule.c.h index ea91d7c130b..a3646431591 100644 --- a/contrib/tools/python3/src/Modules/clinic/_cryptmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_cryptmodule.c.h @@ -1,34 +1,34 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(crypt_crypt__doc__, -"crypt($module, word, salt, /)\n" -"--\n" -"\n" -"Hash a *word* with the given *salt* and return the hashed password.\n" -"\n" -"*word* will usually be a user\'s password. *salt* (either a random 2 or 16\n" -"character string, possibly prefixed with $digit$ to indicate the method)\n" -"will be used to perturb the encryption algorithm and produce distinct\n" -"results for a given *word*."); - -#define CRYPT_CRYPT_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(crypt_crypt__doc__, +"crypt($module, word, salt, /)\n" +"--\n" +"\n" +"Hash a *word* with the given *salt* and return the hashed password.\n" +"\n" +"*word* will usually be a user\'s password. *salt* (either a random 2 or 16\n" +"character string, possibly prefixed with $digit$ to indicate the method)\n" +"will be used to perturb the encryption algorithm and produce distinct\n" +"results for a given *word*."); + +#define CRYPT_CRYPT_METHODDEF \ {"crypt", (PyCFunction)(void(*)(void))crypt_crypt, METH_FASTCALL, crypt_crypt__doc__}, - -static PyObject * -crypt_crypt_impl(PyObject *module, const char *word, const char *salt); - -static PyObject * -crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *word; - const char *salt; - + +static PyObject * +crypt_crypt_impl(PyObject *module, const char *word, const char *salt); + +static PyObject * +crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *word; + const char *salt; + if (!_PyArg_CheckPositional("crypt", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("crypt", "argument 1", "str", args[0]); goto exit; @@ -55,9 +55,9 @@ crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = crypt_crypt_impl(module, word, salt); - -exit: - return return_value; -} + return_value = crypt_crypt_impl(module, word, salt); + +exit: + return return_value; +} /*[clinic end generated code: output=549de0d43b030126 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_cursesmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_cursesmodule.c.h index 66ffcdfdb3f..236f42ee4ba 100644 --- a/contrib/tools/python3/src/Modules/clinic/_cursesmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_cursesmodule.c.h @@ -1,78 +1,78 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - +/*[clinic input] +preserve +[clinic start generated code]*/ + PyDoc_STRVAR(_curses_window_addch__doc__, "addch([y, x,] ch, [attr=_curses.A_NORMAL])\n" "Paint the character.\n" -"\n" -" y\n" -" Y-coordinate.\n" -" x\n" -" X-coordinate.\n" -" ch\n" -" Character to add.\n" -" attr\n" -" Attributes for the character.\n" -"\n" -"Paint character ch at (y, x) with attributes attr,\n" -"overwriting any character previously painted at that location.\n" -"By default, the character position and attributes are the\n" -"current settings for the window object."); - +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" ch\n" +" Character to add.\n" +" attr\n" +" Attributes for the character.\n" +"\n" +"Paint character ch at (y, x) with attributes attr,\n" +"overwriting any character previously painted at that location.\n" +"By default, the character position and attributes are the\n" +"current settings for the window object."); + #define _CURSES_WINDOW_ADDCH_METHODDEF \ {"addch", (PyCFunction)_curses_window_addch, METH_VARARGS, _curses_window_addch__doc__}, - -static PyObject * + +static PyObject * _curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, int x, PyObject *ch, int group_right_1, long attr); - -static PyObject * + +static PyObject * _curses_window_addch(PyCursesWindowObject *self, PyObject *args) -{ - PyObject *return_value = NULL; - int group_left_1 = 0; - int y = 0; - int x = 0; - PyObject *ch; - int group_right_1 = 0; +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int group_right_1 = 0; long attr = A_NORMAL; - - switch (PyTuple_GET_SIZE(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O:addch", &ch)) { - goto exit; - } - break; - case 2: - if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) { - goto exit; - } - group_right_1 = 1; - break; - case 3: - if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) { - goto exit; - } - group_left_1 = 1; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) { - goto exit; - } - group_right_1 = 1; - group_left_1 = 1; - break; - default: + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:addch", &ch)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: PyErr_SetString(PyExc_TypeError, "_curses.window.addch requires 1 to 4 arguments"); - goto exit; - } + goto exit; + } return_value = _curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); - -exit: - return return_value; -} + +exit: + return return_value; +} PyDoc_STRVAR(_curses_window_addstr__doc__, "addstr([y, x,] str, [attr])\n" diff --git a/contrib/tools/python3/src/Modules/clinic/_datetimemodule.c.h b/contrib/tools/python3/src/Modules/clinic/_datetimemodule.c.h index 973a4ea0253..ad35f863f48 100644 --- a/contrib/tools/python3/src/Modules/clinic/_datetimemodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_datetimemodule.c.h @@ -1,7 +1,7 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - +/*[clinic input] +preserve +[clinic start generated code]*/ + PyDoc_STRVAR(datetime_date_fromtimestamp__doc__, "fromtimestamp($type, timestamp, /)\n" "--\n" @@ -68,45 +68,45 @@ exit: return return_value; } -PyDoc_STRVAR(datetime_datetime_now__doc__, -"now($type, /, tz=None)\n" -"--\n" -"\n" -"Returns new datetime object representing current time local to tz.\n" -"\n" -" tz\n" -" Timezone object.\n" -"\n" -"If no tz is specified, uses local timezone."); - -#define DATETIME_DATETIME_NOW_METHODDEF \ +PyDoc_STRVAR(datetime_datetime_now__doc__, +"now($type, /, tz=None)\n" +"--\n" +"\n" +"Returns new datetime object representing current time local to tz.\n" +"\n" +" tz\n" +" Timezone object.\n" +"\n" +"If no tz is specified, uses local timezone."); + +#define DATETIME_DATETIME_NOW_METHODDEF \ {"now", (PyCFunction)(void(*)(void))datetime_datetime_now, METH_FASTCALL|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__}, - -static PyObject * -datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz); - -static PyObject * -datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"tz", NULL}; + +static PyObject * +datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz); + +static PyObject * +datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"tz", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "now", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *tz = Py_None; - + PyObject *tz = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } tz = args[0]; skip_optional_pos: - return_value = datetime_datetime_now_impl(type, tz); - -exit: - return return_value; -} + return_value = datetime_datetime_now_impl(type, tz); + +exit: + return return_value; +} /*[clinic end generated code: output=5e17549f29a439a5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_dbmmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_dbmmodule.c.h index a7d73508506..5e8aa57c31d 100644 --- a/contrib/tools/python3/src/Modules/clinic/_dbmmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_dbmmodule.c.h @@ -1,140 +1,140 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_dbm_dbm_close__doc__, -"close($self, /)\n" -"--\n" -"\n" -"Close the database."); - -#define _DBM_DBM_CLOSE_METHODDEF \ - {"close", (PyCFunction)_dbm_dbm_close, METH_NOARGS, _dbm_dbm_close__doc__}, - -static PyObject * -_dbm_dbm_close_impl(dbmobject *self); - -static PyObject * -_dbm_dbm_close(dbmobject *self, PyObject *Py_UNUSED(ignored)) -{ - return _dbm_dbm_close_impl(self); -} - -PyDoc_STRVAR(_dbm_dbm_keys__doc__, -"keys($self, /)\n" -"--\n" -"\n" -"Return a list of all keys in the database."); - -#define _DBM_DBM_KEYS_METHODDEF \ - {"keys", (PyCFunction)_dbm_dbm_keys, METH_NOARGS, _dbm_dbm_keys__doc__}, - -static PyObject * -_dbm_dbm_keys_impl(dbmobject *self); - -static PyObject * -_dbm_dbm_keys(dbmobject *self, PyObject *Py_UNUSED(ignored)) -{ - return _dbm_dbm_keys_impl(self); -} - -PyDoc_STRVAR(_dbm_dbm_get__doc__, -"get($self, key, default=None, /)\n" -"--\n" -"\n" -"Return the value for key if present, otherwise default."); - -#define _DBM_DBM_GET_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_dbm_dbm_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the database."); + +#define _DBM_DBM_CLOSE_METHODDEF \ + {"close", (PyCFunction)_dbm_dbm_close, METH_NOARGS, _dbm_dbm_close__doc__}, + +static PyObject * +_dbm_dbm_close_impl(dbmobject *self); + +static PyObject * +_dbm_dbm_close(dbmobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _dbm_dbm_close_impl(self); +} + +PyDoc_STRVAR(_dbm_dbm_keys__doc__, +"keys($self, /)\n" +"--\n" +"\n" +"Return a list of all keys in the database."); + +#define _DBM_DBM_KEYS_METHODDEF \ + {"keys", (PyCFunction)_dbm_dbm_keys, METH_NOARGS, _dbm_dbm_keys__doc__}, + +static PyObject * +_dbm_dbm_keys_impl(dbmobject *self); + +static PyObject * +_dbm_dbm_keys(dbmobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _dbm_dbm_keys_impl(self); +} + +PyDoc_STRVAR(_dbm_dbm_get__doc__, +"get($self, key, default=None, /)\n" +"--\n" +"\n" +"Return the value for key if present, otherwise default."); + +#define _DBM_DBM_GET_METHODDEF \ {"get", (PyCFunction)(void(*)(void))_dbm_dbm_get, METH_FASTCALL, _dbm_dbm_get__doc__}, - -static PyObject * -_dbm_dbm_get_impl(dbmobject *self, const char *key, - Py_ssize_clean_t key_length, PyObject *default_value); - -static PyObject * -_dbm_dbm_get(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *key; - Py_ssize_clean_t key_length; - PyObject *default_value = Py_None; - - if (!_PyArg_ParseStack(args, nargs, "s#|O:get", - &key, &key_length, &default_value)) { - goto exit; - } - return_value = _dbm_dbm_get_impl(self, key, key_length, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_dbm_dbm_setdefault__doc__, -"setdefault($self, key, default=b\'\', /)\n" -"--\n" -"\n" -"Return the value for key if present, otherwise default.\n" -"\n" -"If key is not in the database, it is inserted with default as the value."); - -#define _DBM_DBM_SETDEFAULT_METHODDEF \ + +static PyObject * +_dbm_dbm_get_impl(dbmobject *self, const char *key, + Py_ssize_clean_t key_length, PyObject *default_value); + +static PyObject * +_dbm_dbm_get(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *key; + Py_ssize_clean_t key_length; + PyObject *default_value = Py_None; + + if (!_PyArg_ParseStack(args, nargs, "s#|O:get", + &key, &key_length, &default_value)) { + goto exit; + } + return_value = _dbm_dbm_get_impl(self, key, key_length, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_dbm_dbm_setdefault__doc__, +"setdefault($self, key, default=b\'\', /)\n" +"--\n" +"\n" +"Return the value for key if present, otherwise default.\n" +"\n" +"If key is not in the database, it is inserted with default as the value."); + +#define _DBM_DBM_SETDEFAULT_METHODDEF \ {"setdefault", (PyCFunction)(void(*)(void))_dbm_dbm_setdefault, METH_FASTCALL, _dbm_dbm_setdefault__doc__}, - -static PyObject * -_dbm_dbm_setdefault_impl(dbmobject *self, const char *key, - Py_ssize_clean_t key_length, - PyObject *default_value); - -static PyObject * -_dbm_dbm_setdefault(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *key; - Py_ssize_clean_t key_length; - PyObject *default_value = NULL; - - if (!_PyArg_ParseStack(args, nargs, "s#|O:setdefault", - &key, &key_length, &default_value)) { - goto exit; - } - return_value = _dbm_dbm_setdefault_impl(self, key, key_length, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(dbmopen__doc__, -"open($module, filename, flags=\'r\', mode=0o666, /)\n" -"--\n" -"\n" -"Return a database object.\n" -"\n" -" filename\n" -" The filename to open.\n" -" flags\n" -" How to open the file. \"r\" for reading, \"w\" for writing, etc.\n" -" mode\n" -" If creating a new file, the mode bits for the new file\n" -" (e.g. os.O_RDWR)."); - -#define DBMOPEN_METHODDEF \ + +static PyObject * +_dbm_dbm_setdefault_impl(dbmobject *self, const char *key, + Py_ssize_clean_t key_length, + PyObject *default_value); + +static PyObject * +_dbm_dbm_setdefault(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *key; + Py_ssize_clean_t key_length; + PyObject *default_value = NULL; + + if (!_PyArg_ParseStack(args, nargs, "s#|O:setdefault", + &key, &key_length, &default_value)) { + goto exit; + } + return_value = _dbm_dbm_setdefault_impl(self, key, key_length, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(dbmopen__doc__, +"open($module, filename, flags=\'r\', mode=0o666, /)\n" +"--\n" +"\n" +"Return a database object.\n" +"\n" +" filename\n" +" The filename to open.\n" +" flags\n" +" How to open the file. \"r\" for reading, \"w\" for writing, etc.\n" +" mode\n" +" If creating a new file, the mode bits for the new file\n" +" (e.g. os.O_RDWR)."); + +#define DBMOPEN_METHODDEF \ {"open", (PyCFunction)(void(*)(void))dbmopen, METH_FASTCALL, dbmopen__doc__}, - -static PyObject * -dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, - int mode); - -static PyObject * -dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *filename; - const char *flags = "r"; - int mode = 438; - + +static PyObject * +dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, + int mode); + +static PyObject * +dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *filename; + const char *flags = "r"; + int mode = 438; + if (!_PyArg_CheckPositional("open", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("open", "argument 1", "str", args[0]); goto exit; @@ -172,9 +172,9 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = dbmopen_impl(module, filename, flags, mode); - -exit: - return return_value; -} + return_value = dbmopen_impl(module, filename, flags, mode); + +exit: + return return_value; +} /*[clinic end generated code: output=7ced103488cbca7a input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_elementtree.c.h b/contrib/tools/python3/src/Modules/clinic/_elementtree.c.h index 825416f4a39..71da7c35dbe 100644 --- a/contrib/tools/python3/src/Modules/clinic/_elementtree.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_elementtree.c.h @@ -1,225 +1,225 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_elementtree_Element_append__doc__, -"append($self, subelement, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_APPEND_METHODDEF \ - {"append", (PyCFunction)_elementtree_Element_append, METH_O, _elementtree_Element_append__doc__}, - -static PyObject * -_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement); - -static PyObject * -_elementtree_Element_append(ElementObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *subelement; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_elementtree_Element_append__doc__, +"append($self, subelement, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_APPEND_METHODDEF \ + {"append", (PyCFunction)_elementtree_Element_append, METH_O, _elementtree_Element_append__doc__}, + +static PyObject * +_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement); + +static PyObject * +_elementtree_Element_append(ElementObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *subelement; + if (!PyObject_TypeCheck(arg, &Element_Type)) { _PyArg_BadArgument("append", "argument", (&Element_Type)->tp_name, arg); - goto exit; - } + goto exit; + } subelement = arg; - return_value = _elementtree_Element_append_impl(self, subelement); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_clear__doc__, -"clear($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF \ - {"clear", (PyCFunction)_elementtree_Element_clear, METH_NOARGS, _elementtree_Element_clear__doc__}, - -static PyObject * -_elementtree_Element_clear_impl(ElementObject *self); - -static PyObject * -_elementtree_Element_clear(ElementObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_Element_clear_impl(self); -} - -PyDoc_STRVAR(_elementtree_Element___copy____doc__, -"__copy__($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT___COPY___METHODDEF \ - {"__copy__", (PyCFunction)_elementtree_Element___copy__, METH_NOARGS, _elementtree_Element___copy____doc__}, - -static PyObject * -_elementtree_Element___copy___impl(ElementObject *self); - -static PyObject * -_elementtree_Element___copy__(ElementObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_Element___copy___impl(self); -} - -PyDoc_STRVAR(_elementtree_Element___deepcopy____doc__, -"__deepcopy__($self, memo, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)_elementtree_Element___deepcopy__, METH_O, _elementtree_Element___deepcopy____doc__}, - -static PyObject * -_elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo); - -static PyObject * -_elementtree_Element___deepcopy__(ElementObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *memo; - + return_value = _elementtree_Element_append_impl(self, subelement); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF \ + {"clear", (PyCFunction)_elementtree_Element_clear, METH_NOARGS, _elementtree_Element_clear__doc__}, + +static PyObject * +_elementtree_Element_clear_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_clear(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_clear_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___COPY___METHODDEF \ + {"__copy__", (PyCFunction)_elementtree_Element___copy__, METH_NOARGS, _elementtree_Element___copy____doc__}, + +static PyObject * +_elementtree_Element___copy___impl(ElementObject *self); + +static PyObject * +_elementtree_Element___copy__(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element___copy___impl(self); +} + +PyDoc_STRVAR(_elementtree_Element___deepcopy____doc__, +"__deepcopy__($self, memo, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)_elementtree_Element___deepcopy__, METH_O, _elementtree_Element___deepcopy____doc__}, + +static PyObject * +_elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo); + +static PyObject * +_elementtree_Element___deepcopy__(ElementObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *memo; + if (!PyDict_Check(arg)) { _PyArg_BadArgument("__deepcopy__", "argument", "dict", arg); - goto exit; - } + goto exit; + } memo = arg; - return_value = _elementtree_Element___deepcopy___impl(self, memo); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element___sizeof____doc__, -"__sizeof__($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF \ - {"__sizeof__", (PyCFunction)_elementtree_Element___sizeof__, METH_NOARGS, _elementtree_Element___sizeof____doc__}, - -static Py_ssize_t -_elementtree_Element___sizeof___impl(ElementObject *self); - -static PyObject * -_elementtree_Element___sizeof__(ElementObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = _elementtree_Element___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element___getstate____doc__, -"__getstate__($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF \ - {"__getstate__", (PyCFunction)_elementtree_Element___getstate__, METH_NOARGS, _elementtree_Element___getstate____doc__}, - -static PyObject * -_elementtree_Element___getstate___impl(ElementObject *self); - -static PyObject * -_elementtree_Element___getstate__(ElementObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_Element___getstate___impl(self); -} - -PyDoc_STRVAR(_elementtree_Element___setstate____doc__, -"__setstate__($self, state, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF \ - {"__setstate__", (PyCFunction)_elementtree_Element___setstate__, METH_O, _elementtree_Element___setstate____doc__}, - -PyDoc_STRVAR(_elementtree_Element_extend__doc__, -"extend($self, elements, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF \ - {"extend", (PyCFunction)_elementtree_Element_extend, METH_O, _elementtree_Element_extend__doc__}, - -PyDoc_STRVAR(_elementtree_Element_find__doc__, -"find($self, /, path, namespaces=None)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_FIND_METHODDEF \ + return_value = _elementtree_Element___deepcopy___impl(self, memo); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_elementtree_Element___sizeof__, METH_NOARGS, _elementtree_Element___sizeof____doc__}, + +static Py_ssize_t +_elementtree_Element___sizeof___impl(ElementObject *self); + +static PyObject * +_elementtree_Element___sizeof__(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _elementtree_Element___sizeof___impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element___getstate____doc__, +"__getstate__($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF \ + {"__getstate__", (PyCFunction)_elementtree_Element___getstate__, METH_NOARGS, _elementtree_Element___getstate____doc__}, + +static PyObject * +_elementtree_Element___getstate___impl(ElementObject *self); + +static PyObject * +_elementtree_Element___getstate__(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element___getstate___impl(self); +} + +PyDoc_STRVAR(_elementtree_Element___setstate____doc__, +"__setstate__($self, state, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF \ + {"__setstate__", (PyCFunction)_elementtree_Element___setstate__, METH_O, _elementtree_Element___setstate____doc__}, + +PyDoc_STRVAR(_elementtree_Element_extend__doc__, +"extend($self, elements, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF \ + {"extend", (PyCFunction)_elementtree_Element_extend, METH_O, _elementtree_Element_extend__doc__}, + +PyDoc_STRVAR(_elementtree_Element_find__doc__, +"find($self, /, path, namespaces=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_FIND_METHODDEF \ {"find", (PyCFunction)(void(*)(void))_elementtree_Element_find, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_find__doc__}, - -static PyObject * -_elementtree_Element_find_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); - -static PyObject * -_elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "namespaces", NULL}; + +static PyObject * +_elementtree_Element_find_impl(ElementObject *self, PyObject *path, + PyObject *namespaces); + +static PyObject * +_elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "namespaces", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "find", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *path; - PyObject *namespaces = Py_None; - + PyObject *path; + PyObject *namespaces = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } path = args[0]; if (!noptargs) { goto skip_optional_pos; } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_find_impl(self, path, namespaces); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_findtext__doc__, -"findtext($self, /, path, default=None, namespaces=None)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF \ + return_value = _elementtree_Element_find_impl(self, path, namespaces); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_findtext__doc__, +"findtext($self, /, path, default=None, namespaces=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF \ {"findtext", (PyCFunction)(void(*)(void))_elementtree_Element_findtext, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findtext__doc__}, - -static PyObject * -_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, - PyObject *default_value, - PyObject *namespaces); - -static PyObject * -_elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "default", "namespaces", NULL}; + +static PyObject * +_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, + PyObject *default_value, + PyObject *namespaces); + +static PyObject * +_elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "default", "namespaces", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "findtext", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *path; - PyObject *default_value = Py_None; - PyObject *namespaces = Py_None; - + PyObject *path; + PyObject *default_value = Py_None; + PyObject *namespaces = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } path = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -232,204 +232,204 @@ _elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssi } namespaces = args[2]; skip_optional_pos: - return_value = _elementtree_Element_findtext_impl(self, path, default_value, namespaces); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_findall__doc__, -"findall($self, /, path, namespaces=None)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF \ + return_value = _elementtree_Element_findtext_impl(self, path, default_value, namespaces); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_findall__doc__, +"findall($self, /, path, namespaces=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF \ {"findall", (PyCFunction)(void(*)(void))_elementtree_Element_findall, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findall__doc__}, - -static PyObject * -_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); - -static PyObject * -_elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "namespaces", NULL}; + +static PyObject * +_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, + PyObject *namespaces); + +static PyObject * +_elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "namespaces", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "findall", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *path; - PyObject *namespaces = Py_None; - + PyObject *path; + PyObject *namespaces = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } path = args[0]; if (!noptargs) { goto skip_optional_pos; } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_findall_impl(self, path, namespaces); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_iterfind__doc__, -"iterfind($self, /, path, namespaces=None)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF \ + return_value = _elementtree_Element_findall_impl(self, path, namespaces); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_iterfind__doc__, +"iterfind($self, /, path, namespaces=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF \ {"iterfind", (PyCFunction)(void(*)(void))_elementtree_Element_iterfind, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iterfind__doc__}, - -static PyObject * -_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); - -static PyObject * -_elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "namespaces", NULL}; + +static PyObject * +_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, + PyObject *namespaces); + +static PyObject * +_elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "namespaces", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "iterfind", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *path; - PyObject *namespaces = Py_None; - + PyObject *path; + PyObject *namespaces = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } path = args[0]; if (!noptargs) { goto skip_optional_pos; } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_iterfind_impl(self, path, namespaces); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_get__doc__, -"get($self, /, key, default=None)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_GET_METHODDEF \ + return_value = _elementtree_Element_iterfind_impl(self, path, namespaces); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_get__doc__, +"get($self, /, key, default=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_GET_METHODDEF \ {"get", (PyCFunction)(void(*)(void))_elementtree_Element_get, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_get__doc__}, - -static PyObject * -_elementtree_Element_get_impl(ElementObject *self, PyObject *key, - PyObject *default_value); - -static PyObject * -_elementtree_Element_get(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"key", "default", NULL}; + +static PyObject * +_elementtree_Element_get_impl(ElementObject *self, PyObject *key, + PyObject *default_value); + +static PyObject * +_elementtree_Element_get(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"key", "default", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *key; - PyObject *default_value = Py_None; - + PyObject *key; + PyObject *default_value = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } key = args[0]; if (!noptargs) { goto skip_optional_pos; } default_value = args[1]; skip_optional_pos: - return_value = _elementtree_Element_get_impl(self, key, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_iter__doc__, -"iter($self, /, tag=None)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_ITER_METHODDEF \ + return_value = _elementtree_Element_get_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_iter__doc__, +"iter($self, /, tag=None)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITER_METHODDEF \ {"iter", (PyCFunction)(void(*)(void))_elementtree_Element_iter, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iter__doc__}, - -static PyObject * -_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag); - -static PyObject * -_elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"tag", NULL}; + +static PyObject * +_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag); + +static PyObject * +_elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"tag", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "iter", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *tag = Py_None; - + PyObject *tag = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } tag = args[0]; skip_optional_pos: - return_value = _elementtree_Element_iter_impl(self, tag); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_itertext__doc__, -"itertext($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF \ - {"itertext", (PyCFunction)_elementtree_Element_itertext, METH_NOARGS, _elementtree_Element_itertext__doc__}, - -static PyObject * -_elementtree_Element_itertext_impl(ElementObject *self); - -static PyObject * -_elementtree_Element_itertext(ElementObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_Element_itertext_impl(self); -} - -PyDoc_STRVAR(_elementtree_Element_insert__doc__, -"insert($self, index, subelement, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_INSERT_METHODDEF \ + return_value = _elementtree_Element_iter_impl(self, tag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_itertext__doc__, +"itertext($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF \ + {"itertext", (PyCFunction)_elementtree_Element_itertext, METH_NOARGS, _elementtree_Element_itertext__doc__}, + +static PyObject * +_elementtree_Element_itertext_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_itertext(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_itertext_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element_insert__doc__, +"insert($self, index, subelement, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_INSERT_METHODDEF \ {"insert", (PyCFunction)(void(*)(void))_elementtree_Element_insert, METH_FASTCALL, _elementtree_Element_insert__doc__}, - -static PyObject * -_elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, - PyObject *subelement); - -static PyObject * -_elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t index; - PyObject *subelement; - + +static PyObject * +_elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, + PyObject *subelement); + +static PyObject * +_elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t index; + PyObject *subelement; + if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -452,149 +452,149 @@ _elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize goto exit; } subelement = args[1]; - return_value = _elementtree_Element_insert_impl(self, index, subelement); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_items__doc__, -"items($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF \ - {"items", (PyCFunction)_elementtree_Element_items, METH_NOARGS, _elementtree_Element_items__doc__}, - -static PyObject * -_elementtree_Element_items_impl(ElementObject *self); - -static PyObject * -_elementtree_Element_items(ElementObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_Element_items_impl(self); -} - -PyDoc_STRVAR(_elementtree_Element_keys__doc__, -"keys($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_KEYS_METHODDEF \ - {"keys", (PyCFunction)_elementtree_Element_keys, METH_NOARGS, _elementtree_Element_keys__doc__}, - -static PyObject * -_elementtree_Element_keys_impl(ElementObject *self); - -static PyObject * -_elementtree_Element_keys(ElementObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_Element_keys_impl(self); -} - -PyDoc_STRVAR(_elementtree_Element_makeelement__doc__, -"makeelement($self, tag, attrib, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF \ + return_value = _elementtree_Element_insert_impl(self, index, subelement); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_items__doc__, +"items($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF \ + {"items", (PyCFunction)_elementtree_Element_items, METH_NOARGS, _elementtree_Element_items__doc__}, + +static PyObject * +_elementtree_Element_items_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_items(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_items_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element_keys__doc__, +"keys($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_KEYS_METHODDEF \ + {"keys", (PyCFunction)_elementtree_Element_keys, METH_NOARGS, _elementtree_Element_keys__doc__}, + +static PyObject * +_elementtree_Element_keys_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_keys(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_keys_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element_makeelement__doc__, +"makeelement($self, tag, attrib, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF \ {"makeelement", (PyCFunction)(void(*)(void))_elementtree_Element_makeelement, METH_FASTCALL, _elementtree_Element_makeelement__doc__}, - -static PyObject * -_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, - PyObject *attrib); - -static PyObject * -_elementtree_Element_makeelement(ElementObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *tag; - PyObject *attrib; - + +static PyObject * +_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, + PyObject *attrib); + +static PyObject * +_elementtree_Element_makeelement(ElementObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *tag; + PyObject *attrib; + if (!_PyArg_CheckPositional("makeelement", nargs, 2, 2)) { - goto exit; - } + goto exit; + } tag = args[0]; if (!PyDict_Check(args[1])) { _PyArg_BadArgument("makeelement", "argument 2", "dict", args[1]); goto exit; } attrib = args[1]; - return_value = _elementtree_Element_makeelement_impl(self, tag, attrib); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_remove__doc__, -"remove($self, subelement, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF \ - {"remove", (PyCFunction)_elementtree_Element_remove, METH_O, _elementtree_Element_remove__doc__}, - -static PyObject * -_elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement); - -static PyObject * -_elementtree_Element_remove(ElementObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *subelement; - + return_value = _elementtree_Element_makeelement_impl(self, tag, attrib); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_remove__doc__, +"remove($self, subelement, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF \ + {"remove", (PyCFunction)_elementtree_Element_remove, METH_O, _elementtree_Element_remove__doc__}, + +static PyObject * +_elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement); + +static PyObject * +_elementtree_Element_remove(ElementObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *subelement; + if (!PyObject_TypeCheck(arg, &Element_Type)) { _PyArg_BadArgument("remove", "argument", (&Element_Type)->tp_name, arg); - goto exit; - } + goto exit; + } subelement = arg; - return_value = _elementtree_Element_remove_impl(self, subelement); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_Element_set__doc__, -"set($self, key, value, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_ELEMENT_SET_METHODDEF \ + return_value = _elementtree_Element_remove_impl(self, subelement); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_set__doc__, +"set($self, key, value, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_SET_METHODDEF \ {"set", (PyCFunction)(void(*)(void))_elementtree_Element_set, METH_FASTCALL, _elementtree_Element_set__doc__}, - -static PyObject * -_elementtree_Element_set_impl(ElementObject *self, PyObject *key, - PyObject *value); - -static PyObject * -_elementtree_Element_set(ElementObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *key; - PyObject *value; - + +static PyObject * +_elementtree_Element_set_impl(ElementObject *self, PyObject *key, + PyObject *value); + +static PyObject * +_elementtree_Element_set(ElementObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *value; + if (!_PyArg_CheckPositional("set", nargs, 2, 2)) { - goto exit; - } + goto exit; + } key = args[0]; value = args[1]; - return_value = _elementtree_Element_set_impl(self, key, value); - -exit: - return return_value; -} - -static int -_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, + return_value = _elementtree_Element_set_impl(self, key, value); + +exit: + return return_value; +} + +static int +_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, PyObject *element_factory, PyObject *comment_factory, PyObject *pi_factory, int insert_comments, int insert_pis); - -static int -_elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; + +static int +_elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; static const char * const _keywords[] = {"element_factory", "comment_factory", "pi_factory", "insert_comments", "insert_pis", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "TreeBuilder", 0}; PyObject *argsbuf[5]; @@ -606,11 +606,11 @@ _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwar PyObject *pi_factory = Py_None; int insert_comments = 0; int insert_pis = 0; - + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -651,11 +651,11 @@ skip_optional_pos: } skip_optional_kwonly: return_value = _elementtree_TreeBuilder___init___impl((TreeBuilderObject *)self, element_factory, comment_factory, pi_factory, insert_comments, insert_pis); - -exit: - return return_value; -} - + +exit: + return return_value; +} + PyDoc_STRVAR(_elementtree__set_factories__doc__, "_set_factories($module, comment_factory, pi_factory, /)\n" "--\n" @@ -689,22 +689,22 @@ exit: return return_value; } -PyDoc_STRVAR(_elementtree_TreeBuilder_data__doc__, -"data($self, data, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF \ - {"data", (PyCFunction)_elementtree_TreeBuilder_data, METH_O, _elementtree_TreeBuilder_data__doc__}, - -PyDoc_STRVAR(_elementtree_TreeBuilder_end__doc__, -"end($self, tag, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_TREEBUILDER_END_METHODDEF \ - {"end", (PyCFunction)_elementtree_TreeBuilder_end, METH_O, _elementtree_TreeBuilder_end__doc__}, - +PyDoc_STRVAR(_elementtree_TreeBuilder_data__doc__, +"data($self, data, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF \ + {"data", (PyCFunction)_elementtree_TreeBuilder_data, METH_O, _elementtree_TreeBuilder_data__doc__}, + +PyDoc_STRVAR(_elementtree_TreeBuilder_end__doc__, +"end($self, tag, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_END_METHODDEF \ + {"end", (PyCFunction)_elementtree_TreeBuilder_end, METH_O, _elementtree_TreeBuilder_end__doc__}, + PyDoc_STRVAR(_elementtree_TreeBuilder_comment__doc__, "comment($self, text, /)\n" "--\n" @@ -747,78 +747,78 @@ exit: return return_value; } -PyDoc_STRVAR(_elementtree_TreeBuilder_close__doc__, -"close($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF \ - {"close", (PyCFunction)_elementtree_TreeBuilder_close, METH_NOARGS, _elementtree_TreeBuilder_close__doc__}, - -static PyObject * -_elementtree_TreeBuilder_close_impl(TreeBuilderObject *self); - -static PyObject * -_elementtree_TreeBuilder_close(TreeBuilderObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_TreeBuilder_close_impl(self); -} - -PyDoc_STRVAR(_elementtree_TreeBuilder_start__doc__, +PyDoc_STRVAR(_elementtree_TreeBuilder_close__doc__, +"close($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF \ + {"close", (PyCFunction)_elementtree_TreeBuilder_close, METH_NOARGS, _elementtree_TreeBuilder_close__doc__}, + +static PyObject * +_elementtree_TreeBuilder_close_impl(TreeBuilderObject *self); + +static PyObject * +_elementtree_TreeBuilder_close(TreeBuilderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_TreeBuilder_close_impl(self); +} + +PyDoc_STRVAR(_elementtree_TreeBuilder_start__doc__, "start($self, tag, attrs, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_TREEBUILDER_START_METHODDEF \ +"--\n" +"\n"); + +#define _ELEMENTTREE_TREEBUILDER_START_METHODDEF \ {"start", (PyCFunction)(void(*)(void))_elementtree_TreeBuilder_start, METH_FASTCALL, _elementtree_TreeBuilder_start__doc__}, - -static PyObject * -_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, - PyObject *attrs); - -static PyObject * -_elementtree_TreeBuilder_start(TreeBuilderObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *tag; + +static PyObject * +_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, + PyObject *attrs); + +static PyObject * +_elementtree_TreeBuilder_start(TreeBuilderObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *tag; PyObject *attrs; - + if (!_PyArg_CheckPositional("start", nargs, 2, 2)) { - goto exit; - } + goto exit; + } tag = args[0]; if (!PyDict_Check(args[1])) { _PyArg_BadArgument("start", "argument 2", "dict", args[1]); goto exit; } attrs = args[1]; - return_value = _elementtree_TreeBuilder_start_impl(self, tag, attrs); - -exit: - return return_value; -} - -static int + return_value = _elementtree_TreeBuilder_start_impl(self, tag, attrs); + +exit: + return return_value; +} + +static int _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, const char *encoding); - -static int -_elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; + +static int +_elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; static const char * const _keywords[] = {"target", "encoding", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "XMLParser", 0}; PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *target = NULL; - const char *encoding = NULL; - + PyObject *target = NULL; + const char *encoding = NULL; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 0, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_kwonly; } @@ -848,76 +848,76 @@ _elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs } skip_optional_kwonly: return_value = _elementtree_XMLParser___init___impl((XMLParserObject *)self, target, encoding); - -exit: - return return_value; -} - -PyDoc_STRVAR(_elementtree_XMLParser_close__doc__, -"close($self, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF \ - {"close", (PyCFunction)_elementtree_XMLParser_close, METH_NOARGS, _elementtree_XMLParser_close__doc__}, - -static PyObject * -_elementtree_XMLParser_close_impl(XMLParserObject *self); - -static PyObject * -_elementtree_XMLParser_close(XMLParserObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _elementtree_XMLParser_close_impl(self); -} - -PyDoc_STRVAR(_elementtree_XMLParser_feed__doc__, -"feed($self, data, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_XMLPARSER_FEED_METHODDEF \ - {"feed", (PyCFunction)_elementtree_XMLParser_feed, METH_O, _elementtree_XMLParser_feed__doc__}, - -PyDoc_STRVAR(_elementtree_XMLParser__parse_whole__doc__, -"_parse_whole($self, file, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF \ - {"_parse_whole", (PyCFunction)_elementtree_XMLParser__parse_whole, METH_O, _elementtree_XMLParser__parse_whole__doc__}, - -PyDoc_STRVAR(_elementtree_XMLParser__setevents__doc__, -"_setevents($self, events_queue, events_to_report=None, /)\n" -"--\n" -"\n"); - -#define _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF \ + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_XMLParser_close__doc__, +"close($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF \ + {"close", (PyCFunction)_elementtree_XMLParser_close, METH_NOARGS, _elementtree_XMLParser_close__doc__}, + +static PyObject * +_elementtree_XMLParser_close_impl(XMLParserObject *self); + +static PyObject * +_elementtree_XMLParser_close(XMLParserObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_XMLParser_close_impl(self); +} + +PyDoc_STRVAR(_elementtree_XMLParser_feed__doc__, +"feed($self, data, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER_FEED_METHODDEF \ + {"feed", (PyCFunction)_elementtree_XMLParser_feed, METH_O, _elementtree_XMLParser_feed__doc__}, + +PyDoc_STRVAR(_elementtree_XMLParser__parse_whole__doc__, +"_parse_whole($self, file, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF \ + {"_parse_whole", (PyCFunction)_elementtree_XMLParser__parse_whole, METH_O, _elementtree_XMLParser__parse_whole__doc__}, + +PyDoc_STRVAR(_elementtree_XMLParser__setevents__doc__, +"_setevents($self, events_queue, events_to_report=None, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF \ {"_setevents", (PyCFunction)(void(*)(void))_elementtree_XMLParser__setevents, METH_FASTCALL, _elementtree_XMLParser__setevents__doc__}, - -static PyObject * -_elementtree_XMLParser__setevents_impl(XMLParserObject *self, - PyObject *events_queue, - PyObject *events_to_report); - -static PyObject * -_elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *events_queue; - PyObject *events_to_report = Py_None; - + +static PyObject * +_elementtree_XMLParser__setevents_impl(XMLParserObject *self, + PyObject *events_queue, + PyObject *events_to_report); + +static PyObject * +_elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *events_queue; + PyObject *events_to_report = Py_None; + if (!_PyArg_CheckPositional("_setevents", nargs, 1, 2)) { - goto exit; - } + goto exit; + } events_queue = args[0]; if (nargs < 2) { goto skip_optional; } events_to_report = args[1]; skip_optional: - return_value = _elementtree_XMLParser__setevents_impl(self, events_queue, events_to_report); - -exit: - return return_value; -} + return_value = _elementtree_XMLParser__setevents_impl(self, events_queue, events_to_report); + +exit: + return return_value; +} /*[clinic end generated code: output=b7f6a32462fc42a9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_gdbmmodule.c.h b/contrib/tools/python3/src/Modules/clinic/_gdbmmodule.c.h index 552bf6ed88e..204433b500e 100644 --- a/contrib/tools/python3/src/Modules/clinic/_gdbmmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_gdbmmodule.c.h @@ -1,261 +1,261 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_gdbm_gdbm_get__doc__, -"get($self, key, default=None, /)\n" -"--\n" -"\n" -"Get the value for key, or default if not present."); - -#define _GDBM_GDBM_GET_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_gdbm_gdbm_get__doc__, +"get($self, key, default=None, /)\n" +"--\n" +"\n" +"Get the value for key, or default if not present."); + +#define _GDBM_GDBM_GET_METHODDEF \ {"get", (PyCFunction)(void(*)(void))_gdbm_gdbm_get, METH_FASTCALL, _gdbm_gdbm_get__doc__}, - -static PyObject * -_gdbm_gdbm_get_impl(dbmobject *self, PyObject *key, PyObject *default_value); - -static PyObject * -_gdbm_gdbm_get(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *key; - PyObject *default_value = Py_None; - + +static PyObject * +_gdbm_gdbm_get_impl(dbmobject *self, PyObject *key, PyObject *default_value); + +static PyObject * +_gdbm_gdbm_get(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *default_value = Py_None; + if (!_PyArg_CheckPositional("get", nargs, 1, 2)) { - goto exit; - } + goto exit; + } key = args[0]; if (nargs < 2) { goto skip_optional; } default_value = args[1]; skip_optional: - return_value = _gdbm_gdbm_get_impl(self, key, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_gdbm_gdbm_setdefault__doc__, -"setdefault($self, key, default=None, /)\n" -"--\n" -"\n" -"Get value for key, or set it to default and return default if not present."); - -#define _GDBM_GDBM_SETDEFAULT_METHODDEF \ + return_value = _gdbm_gdbm_get_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_gdbm_gdbm_setdefault__doc__, +"setdefault($self, key, default=None, /)\n" +"--\n" +"\n" +"Get value for key, or set it to default and return default if not present."); + +#define _GDBM_GDBM_SETDEFAULT_METHODDEF \ {"setdefault", (PyCFunction)(void(*)(void))_gdbm_gdbm_setdefault, METH_FASTCALL, _gdbm_gdbm_setdefault__doc__}, - -static PyObject * -_gdbm_gdbm_setdefault_impl(dbmobject *self, PyObject *key, - PyObject *default_value); - -static PyObject * -_gdbm_gdbm_setdefault(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *key; - PyObject *default_value = Py_None; - + +static PyObject * +_gdbm_gdbm_setdefault_impl(dbmobject *self, PyObject *key, + PyObject *default_value); + +static PyObject * +_gdbm_gdbm_setdefault(dbmobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *default_value = Py_None; + if (!_PyArg_CheckPositional("setdefault", nargs, 1, 2)) { - goto exit; - } + goto exit; + } key = args[0]; if (nargs < 2) { goto skip_optional; } default_value = args[1]; skip_optional: - return_value = _gdbm_gdbm_setdefault_impl(self, key, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_gdbm_gdbm_close__doc__, -"close($self, /)\n" -"--\n" -"\n" -"Close the database."); - -#define _GDBM_GDBM_CLOSE_METHODDEF \ - {"close", (PyCFunction)_gdbm_gdbm_close, METH_NOARGS, _gdbm_gdbm_close__doc__}, - -static PyObject * -_gdbm_gdbm_close_impl(dbmobject *self); - -static PyObject * -_gdbm_gdbm_close(dbmobject *self, PyObject *Py_UNUSED(ignored)) -{ - return _gdbm_gdbm_close_impl(self); -} - -PyDoc_STRVAR(_gdbm_gdbm_keys__doc__, -"keys($self, /)\n" -"--\n" -"\n" -"Get a list of all keys in the database."); - -#define _GDBM_GDBM_KEYS_METHODDEF \ - {"keys", (PyCFunction)_gdbm_gdbm_keys, METH_NOARGS, _gdbm_gdbm_keys__doc__}, - -static PyObject * -_gdbm_gdbm_keys_impl(dbmobject *self); - -static PyObject * -_gdbm_gdbm_keys(dbmobject *self, PyObject *Py_UNUSED(ignored)) -{ - return _gdbm_gdbm_keys_impl(self); -} - -PyDoc_STRVAR(_gdbm_gdbm_firstkey__doc__, -"firstkey($self, /)\n" -"--\n" -"\n" -"Return the starting key for the traversal.\n" -"\n" -"It\'s possible to loop over every key in the database using this method\n" -"and the nextkey() method. The traversal is ordered by GDBM\'s internal\n" -"hash values, and won\'t be sorted by the key values."); - -#define _GDBM_GDBM_FIRSTKEY_METHODDEF \ - {"firstkey", (PyCFunction)_gdbm_gdbm_firstkey, METH_NOARGS, _gdbm_gdbm_firstkey__doc__}, - -static PyObject * -_gdbm_gdbm_firstkey_impl(dbmobject *self); - -static PyObject * -_gdbm_gdbm_firstkey(dbmobject *self, PyObject *Py_UNUSED(ignored)) -{ - return _gdbm_gdbm_firstkey_impl(self); -} - -PyDoc_STRVAR(_gdbm_gdbm_nextkey__doc__, -"nextkey($self, key, /)\n" -"--\n" -"\n" -"Returns the key that follows key in the traversal.\n" -"\n" -"The following code prints every key in the database db, without having\n" -"to create a list in memory that contains them all:\n" -"\n" -" k = db.firstkey()\n" + return_value = _gdbm_gdbm_setdefault_impl(self, key, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_gdbm_gdbm_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the database."); + +#define _GDBM_GDBM_CLOSE_METHODDEF \ + {"close", (PyCFunction)_gdbm_gdbm_close, METH_NOARGS, _gdbm_gdbm_close__doc__}, + +static PyObject * +_gdbm_gdbm_close_impl(dbmobject *self); + +static PyObject * +_gdbm_gdbm_close(dbmobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _gdbm_gdbm_close_impl(self); +} + +PyDoc_STRVAR(_gdbm_gdbm_keys__doc__, +"keys($self, /)\n" +"--\n" +"\n" +"Get a list of all keys in the database."); + +#define _GDBM_GDBM_KEYS_METHODDEF \ + {"keys", (PyCFunction)_gdbm_gdbm_keys, METH_NOARGS, _gdbm_gdbm_keys__doc__}, + +static PyObject * +_gdbm_gdbm_keys_impl(dbmobject *self); + +static PyObject * +_gdbm_gdbm_keys(dbmobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _gdbm_gdbm_keys_impl(self); +} + +PyDoc_STRVAR(_gdbm_gdbm_firstkey__doc__, +"firstkey($self, /)\n" +"--\n" +"\n" +"Return the starting key for the traversal.\n" +"\n" +"It\'s possible to loop over every key in the database using this method\n" +"and the nextkey() method. The traversal is ordered by GDBM\'s internal\n" +"hash values, and won\'t be sorted by the key values."); + +#define _GDBM_GDBM_FIRSTKEY_METHODDEF \ + {"firstkey", (PyCFunction)_gdbm_gdbm_firstkey, METH_NOARGS, _gdbm_gdbm_firstkey__doc__}, + +static PyObject * +_gdbm_gdbm_firstkey_impl(dbmobject *self); + +static PyObject * +_gdbm_gdbm_firstkey(dbmobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _gdbm_gdbm_firstkey_impl(self); +} + +PyDoc_STRVAR(_gdbm_gdbm_nextkey__doc__, +"nextkey($self, key, /)\n" +"--\n" +"\n" +"Returns the key that follows key in the traversal.\n" +"\n" +"The following code prints every key in the database db, without having\n" +"to create a list in memory that contains them all:\n" +"\n" +" k = db.firstkey()\n" " while k is not None:\n" -" print(k)\n" -" k = db.nextkey(k)"); - -#define _GDBM_GDBM_NEXTKEY_METHODDEF \ - {"nextkey", (PyCFunction)_gdbm_gdbm_nextkey, METH_O, _gdbm_gdbm_nextkey__doc__}, - -static PyObject * -_gdbm_gdbm_nextkey_impl(dbmobject *self, const char *key, - Py_ssize_clean_t key_length); - -static PyObject * -_gdbm_gdbm_nextkey(dbmobject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *key; - Py_ssize_clean_t key_length; - - if (!PyArg_Parse(arg, "s#:nextkey", &key, &key_length)) { - goto exit; - } - return_value = _gdbm_gdbm_nextkey_impl(self, key, key_length); - -exit: - return return_value; -} - -PyDoc_STRVAR(_gdbm_gdbm_reorganize__doc__, -"reorganize($self, /)\n" -"--\n" -"\n" -"Reorganize the database.\n" -"\n" -"If you have carried out a lot of deletions and would like to shrink\n" -"the space used by the GDBM file, this routine will reorganize the\n" -"database. GDBM will not shorten the length of a database file except\n" -"by using this reorganization; otherwise, deleted file space will be\n" -"kept and reused as new (key,value) pairs are added."); - -#define _GDBM_GDBM_REORGANIZE_METHODDEF \ - {"reorganize", (PyCFunction)_gdbm_gdbm_reorganize, METH_NOARGS, _gdbm_gdbm_reorganize__doc__}, - -static PyObject * -_gdbm_gdbm_reorganize_impl(dbmobject *self); - -static PyObject * -_gdbm_gdbm_reorganize(dbmobject *self, PyObject *Py_UNUSED(ignored)) -{ - return _gdbm_gdbm_reorganize_impl(self); -} - -PyDoc_STRVAR(_gdbm_gdbm_sync__doc__, -"sync($self, /)\n" -"--\n" -"\n" -"Flush the database to the disk file.\n" -"\n" -"When the database has been opened in fast mode, this method forces\n" -"any unwritten data to be written to the disk."); - -#define _GDBM_GDBM_SYNC_METHODDEF \ - {"sync", (PyCFunction)_gdbm_gdbm_sync, METH_NOARGS, _gdbm_gdbm_sync__doc__}, - -static PyObject * -_gdbm_gdbm_sync_impl(dbmobject *self); - -static PyObject * -_gdbm_gdbm_sync(dbmobject *self, PyObject *Py_UNUSED(ignored)) -{ - return _gdbm_gdbm_sync_impl(self); -} - -PyDoc_STRVAR(dbmopen__doc__, -"open($module, filename, flags=\'r\', mode=0o666, /)\n" -"--\n" -"\n" -"Open a dbm database and return a dbm object.\n" -"\n" -"The filename argument is the name of the database file.\n" -"\n" -"The optional flags argument can be \'r\' (to open an existing database\n" -"for reading only -- default), \'w\' (to open an existing database for\n" -"reading and writing), \'c\' (which creates the database if it doesn\'t\n" -"exist), or \'n\' (which always creates a new empty database).\n" -"\n" -"Some versions of gdbm support additional flags which must be\n" -"appended to one of the flags described above. The module constant\n" -"\'open_flags\' is a string of valid additional flags. The \'f\' flag\n" -"opens the database in fast mode; altered data will not automatically\n" -"be written to the disk after every change. This results in faster\n" -"writes to the database, but may result in an inconsistent database\n" -"if the program crashes while the database is still open. Use the\n" -"sync() method to force any unwritten data to be written to the disk.\n" -"The \'s\' flag causes all database operations to be synchronized to\n" -"disk. The \'u\' flag disables locking of the database file.\n" -"\n" -"The optional mode argument is the Unix mode of the file, used only\n" -"when the database has to be created. It defaults to octal 0o666."); - -#define DBMOPEN_METHODDEF \ +" print(k)\n" +" k = db.nextkey(k)"); + +#define _GDBM_GDBM_NEXTKEY_METHODDEF \ + {"nextkey", (PyCFunction)_gdbm_gdbm_nextkey, METH_O, _gdbm_gdbm_nextkey__doc__}, + +static PyObject * +_gdbm_gdbm_nextkey_impl(dbmobject *self, const char *key, + Py_ssize_clean_t key_length); + +static PyObject * +_gdbm_gdbm_nextkey(dbmobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *key; + Py_ssize_clean_t key_length; + + if (!PyArg_Parse(arg, "s#:nextkey", &key, &key_length)) { + goto exit; + } + return_value = _gdbm_gdbm_nextkey_impl(self, key, key_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(_gdbm_gdbm_reorganize__doc__, +"reorganize($self, /)\n" +"--\n" +"\n" +"Reorganize the database.\n" +"\n" +"If you have carried out a lot of deletions and would like to shrink\n" +"the space used by the GDBM file, this routine will reorganize the\n" +"database. GDBM will not shorten the length of a database file except\n" +"by using this reorganization; otherwise, deleted file space will be\n" +"kept and reused as new (key,value) pairs are added."); + +#define _GDBM_GDBM_REORGANIZE_METHODDEF \ + {"reorganize", (PyCFunction)_gdbm_gdbm_reorganize, METH_NOARGS, _gdbm_gdbm_reorganize__doc__}, + +static PyObject * +_gdbm_gdbm_reorganize_impl(dbmobject *self); + +static PyObject * +_gdbm_gdbm_reorganize(dbmobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _gdbm_gdbm_reorganize_impl(self); +} + +PyDoc_STRVAR(_gdbm_gdbm_sync__doc__, +"sync($self, /)\n" +"--\n" +"\n" +"Flush the database to the disk file.\n" +"\n" +"When the database has been opened in fast mode, this method forces\n" +"any unwritten data to be written to the disk."); + +#define _GDBM_GDBM_SYNC_METHODDEF \ + {"sync", (PyCFunction)_gdbm_gdbm_sync, METH_NOARGS, _gdbm_gdbm_sync__doc__}, + +static PyObject * +_gdbm_gdbm_sync_impl(dbmobject *self); + +static PyObject * +_gdbm_gdbm_sync(dbmobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _gdbm_gdbm_sync_impl(self); +} + +PyDoc_STRVAR(dbmopen__doc__, +"open($module, filename, flags=\'r\', mode=0o666, /)\n" +"--\n" +"\n" +"Open a dbm database and return a dbm object.\n" +"\n" +"The filename argument is the name of the database file.\n" +"\n" +"The optional flags argument can be \'r\' (to open an existing database\n" +"for reading only -- default), \'w\' (to open an existing database for\n" +"reading and writing), \'c\' (which creates the database if it doesn\'t\n" +"exist), or \'n\' (which always creates a new empty database).\n" +"\n" +"Some versions of gdbm support additional flags which must be\n" +"appended to one of the flags described above. The module constant\n" +"\'open_flags\' is a string of valid additional flags. The \'f\' flag\n" +"opens the database in fast mode; altered data will not automatically\n" +"be written to the disk after every change. This results in faster\n" +"writes to the database, but may result in an inconsistent database\n" +"if the program crashes while the database is still open. Use the\n" +"sync() method to force any unwritten data to be written to the disk.\n" +"The \'s\' flag causes all database operations to be synchronized to\n" +"disk. The \'u\' flag disables locking of the database file.\n" +"\n" +"The optional mode argument is the Unix mode of the file, used only\n" +"when the database has to be created. It defaults to octal 0o666."); + +#define DBMOPEN_METHODDEF \ {"open", (PyCFunction)(void(*)(void))dbmopen, METH_FASTCALL, dbmopen__doc__}, - -static PyObject * -dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, - int mode); - -static PyObject * -dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *filename; - const char *flags = "r"; - int mode = 438; - + +static PyObject * +dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, + int mode); + +static PyObject * +dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *filename; + const char *flags = "r"; + int mode = 438; + if (!_PyArg_CheckPositional("open", nargs, 1, 3)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("open", "argument 1", "str", args[0]); goto exit; @@ -293,9 +293,9 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = dbmopen_impl(module, filename, flags, mode); - -exit: - return return_value; -} + return_value = dbmopen_impl(module, filename, flags, mode); + +exit: + return return_value; +} /*[clinic end generated code: output=f48d6e8d4c8a3465 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_hashopenssl.c.h b/contrib/tools/python3/src/Modules/clinic/_hashopenssl.c.h index 68aa765e529..5974eca9499 100644 --- a/contrib/tools/python3/src/Modules/clinic/_hashopenssl.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_hashopenssl.c.h @@ -1,7 +1,7 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - +/*[clinic input] +preserve +[clinic start generated code]*/ + PyDoc_STRVAR(EVP_copy__doc__, "copy($self, /)\n" "--\n" @@ -965,43 +965,43 @@ exit: return return_value; } -#if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) - -PyDoc_STRVAR(_hashlib_scrypt__doc__, -"scrypt($module, /, password, *, salt=None, n=None, r=None, p=None,\n" -" maxmem=0, dklen=64)\n" -"--\n" -"\n" -"scrypt password-based key derivation function."); - -#define _HASHLIB_SCRYPT_METHODDEF \ +#if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) + +PyDoc_STRVAR(_hashlib_scrypt__doc__, +"scrypt($module, /, password, *, salt=None, n=None, r=None, p=None,\n" +" maxmem=0, dklen=64)\n" +"--\n" +"\n" +"scrypt password-based key derivation function."); + +#define _HASHLIB_SCRYPT_METHODDEF \ {"scrypt", (PyCFunction)(void(*)(void))_hashlib_scrypt, METH_FASTCALL|METH_KEYWORDS, _hashlib_scrypt__doc__}, - -static PyObject * -_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, - PyObject *n_obj, PyObject *r_obj, PyObject *p_obj, - long maxmem, long dklen); - -static PyObject * -_hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"password", "salt", "n", "r", "p", "maxmem", "dklen", NULL}; + +static PyObject * +_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, + PyObject *n_obj, PyObject *r_obj, PyObject *p_obj, + long maxmem, long dklen); + +static PyObject * +_hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"password", "salt", "n", "r", "p", "maxmem", "dklen", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "scrypt", 0}; PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer password = {NULL, NULL}; - Py_buffer salt = {NULL, NULL}; - PyObject *n_obj = Py_None; - PyObject *r_obj = Py_None; - PyObject *p_obj = Py_None; - long maxmem = 0; - long dklen = 64; - + Py_buffer password = {NULL, NULL}; + Py_buffer salt = {NULL, NULL}; + PyObject *n_obj = Py_None; + PyObject *r_obj = Py_None; + PyObject *p_obj = Py_None; + long maxmem = 0; + long dklen = 64; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &password, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1078,51 +1078,51 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } skip_optional_kwonly: - return_value = _hashlib_scrypt_impl(module, &password, &salt, n_obj, r_obj, p_obj, maxmem, dklen); - -exit: - /* Cleanup for password */ - if (password.obj) { - PyBuffer_Release(&password); - } - /* Cleanup for salt */ - if (salt.obj) { - PyBuffer_Release(&salt); - } - - return return_value; -} - -#endif /* (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) */ - + return_value = _hashlib_scrypt_impl(module, &password, &salt, n_obj, r_obj, p_obj, maxmem, dklen); + +exit: + /* Cleanup for password */ + if (password.obj) { + PyBuffer_Release(&password); + } + /* Cleanup for salt */ + if (salt.obj) { + PyBuffer_Release(&salt); + } + + return return_value; +} + +#endif /* (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) */ + PyDoc_STRVAR(_hashlib_hmac_singleshot__doc__, -"hmac_digest($module, /, key, msg, digest)\n" -"--\n" -"\n" -"Single-shot HMAC."); - +"hmac_digest($module, /, key, msg, digest)\n" +"--\n" +"\n" +"Single-shot HMAC."); + #define _HASHLIB_HMAC_SINGLESHOT_METHODDEF \ {"hmac_digest", (PyCFunction)(void(*)(void))_hashlib_hmac_singleshot, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_singleshot__doc__}, - -static PyObject * + +static PyObject * _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, Py_buffer *msg, const char *digest); - -static PyObject * + +static PyObject * _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"key", "msg", "digest", NULL}; +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"key", "msg", "digest", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "hmac_digest", 0}; PyObject *argsbuf[3]; - Py_buffer key = {NULL, NULL}; - Py_buffer msg = {NULL, NULL}; - const char *digest; - + Py_buffer key = {NULL, NULL}; + Py_buffer msg = {NULL, NULL}; + const char *digest; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1151,20 +1151,20 @@ _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nar goto exit; } return_value = _hashlib_hmac_singleshot_impl(module, &key, &msg, digest); - -exit: - /* Cleanup for key */ - if (key.obj) { - PyBuffer_Release(&key); - } - /* Cleanup for msg */ - if (msg.obj) { - PyBuffer_Release(&msg); - } - - return return_value; -} - + +exit: + /* Cleanup for key */ + if (key.obj) { + PyBuffer_Release(&key); + } + /* Cleanup for msg */ + if (msg.obj) { + PyBuffer_Release(&msg); + } + + return return_value; +} + PyDoc_STRVAR(_hashlib_hmac_new__doc__, "hmac_new($module, /, key, msg=b\'\', digestmod=None)\n" "--\n" @@ -1435,9 +1435,9 @@ exit: #define _HASHLIB_OPENSSL_SHAKE_256_METHODDEF #endif /* !defined(_HASHLIB_OPENSSL_SHAKE_256_METHODDEF) */ -#ifndef _HASHLIB_SCRYPT_METHODDEF - #define _HASHLIB_SCRYPT_METHODDEF -#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ +#ifndef _HASHLIB_SCRYPT_METHODDEF + #define _HASHLIB_SCRYPT_METHODDEF +#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ #ifndef _HASHLIB_GET_FIPS_MODE_METHODDEF #define _HASHLIB_GET_FIPS_MODE_METHODDEF diff --git a/contrib/tools/python3/src/Modules/clinic/_lzmamodule.c.h b/contrib/tools/python3/src/Modules/clinic/_lzmamodule.c.h index 82ef4d517d8..8116419f029 100644 --- a/contrib/tools/python3/src/Modules/clinic/_lzmamodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_lzmamodule.c.h @@ -1,111 +1,111 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__, -"compress($self, data, /)\n" -"--\n" -"\n" -"Provide data to the compressor object.\n" -"\n" -"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n" -"\n" -"When you have finished providing data to the compressor, call the\n" -"flush() method to finish the compression process."); - -#define _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)_lzma_LZMACompressor_compress, METH_O, _lzma_LZMACompressor_compress__doc__}, - -static PyObject * -_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data); - -static PyObject * -_lzma_LZMACompressor_compress(Compressor *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__, +"compress($self, data, /)\n" +"--\n" +"\n" +"Provide data to the compressor object.\n" +"\n" +"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n" +"\n" +"When you have finished providing data to the compressor, call the\n" +"flush() method to finish the compression process."); + +#define _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF \ + {"compress", (PyCFunction)_lzma_LZMACompressor_compress, METH_O, _lzma_LZMACompressor_compress__doc__}, + +static PyObject * +_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data); + +static PyObject * +_lzma_LZMACompressor_compress(Compressor *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&data, 'C')) { _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); goto exit; } - return_value = _lzma_LZMACompressor_compress_impl(self, &data); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_lzma_LZMACompressor_flush__doc__, -"flush($self, /)\n" -"--\n" -"\n" -"Finish the compression process.\n" -"\n" -"Returns the compressed data left in internal buffers.\n" -"\n" -"The compressor object may not be used after this method is called."); - -#define _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF \ - {"flush", (PyCFunction)_lzma_LZMACompressor_flush, METH_NOARGS, _lzma_LZMACompressor_flush__doc__}, - -static PyObject * -_lzma_LZMACompressor_flush_impl(Compressor *self); - -static PyObject * -_lzma_LZMACompressor_flush(Compressor *self, PyObject *Py_UNUSED(ignored)) -{ - return _lzma_LZMACompressor_flush_impl(self); -} - -PyDoc_STRVAR(_lzma_LZMADecompressor_decompress__doc__, -"decompress($self, /, data, max_length=-1)\n" -"--\n" -"\n" -"Decompress *data*, returning uncompressed data as bytes.\n" -"\n" -"If *max_length* is nonnegative, returns at most *max_length* bytes of\n" -"decompressed data. If this limit is reached and further output can be\n" -"produced, *self.needs_input* will be set to ``False``. In this case, the next\n" -"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n" -"\n" -"If all of the input data was decompressed and returned (either because this\n" -"was less than *max_length* bytes, or because *max_length* was negative),\n" -"*self.needs_input* will be set to True.\n" -"\n" -"Attempting to decompress data after the end of stream is reached raises an\n" -"EOFError. Any data found after the end of the stream is ignored and saved in\n" -"the unused_data attribute."); - -#define _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF \ + return_value = _lzma_LZMACompressor_compress_impl(self, &data); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_lzma_LZMACompressor_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n" +"Finish the compression process.\n" +"\n" +"Returns the compressed data left in internal buffers.\n" +"\n" +"The compressor object may not be used after this method is called."); + +#define _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_lzma_LZMACompressor_flush, METH_NOARGS, _lzma_LZMACompressor_flush__doc__}, + +static PyObject * +_lzma_LZMACompressor_flush_impl(Compressor *self); + +static PyObject * +_lzma_LZMACompressor_flush(Compressor *self, PyObject *Py_UNUSED(ignored)) +{ + return _lzma_LZMACompressor_flush_impl(self); +} + +PyDoc_STRVAR(_lzma_LZMADecompressor_decompress__doc__, +"decompress($self, /, data, max_length=-1)\n" +"--\n" +"\n" +"Decompress *data*, returning uncompressed data as bytes.\n" +"\n" +"If *max_length* is nonnegative, returns at most *max_length* bytes of\n" +"decompressed data. If this limit is reached and further output can be\n" +"produced, *self.needs_input* will be set to ``False``. In this case, the next\n" +"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n" +"\n" +"If all of the input data was decompressed and returned (either because this\n" +"was less than *max_length* bytes, or because *max_length* was negative),\n" +"*self.needs_input* will be set to True.\n" +"\n" +"Attempting to decompress data after the end of stream is reached raises an\n" +"EOFError. Any data found after the end of the stream is ignored and saved in\n" +"the unused_data attribute."); + +#define _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF \ {"decompress", (PyCFunction)(void(*)(void))_lzma_LZMADecompressor_decompress, METH_FASTCALL|METH_KEYWORDS, _lzma_LZMADecompressor_decompress__doc__}, - -static PyObject * -_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, - Py_ssize_t max_length); - -static PyObject * -_lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"data", "max_length", NULL}; + +static PyObject * +_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, + Py_ssize_t max_length); + +static PyObject * +_lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"data", "max_length", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - Py_ssize_t max_length = -1; - + Py_buffer data = {NULL, NULL}; + Py_ssize_t max_length = -1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -134,62 +134,62 @@ _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ max_length = ival; } skip_optional_pos: - return_value = _lzma_LZMADecompressor_decompress_impl(self, &data, max_length); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__, -"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n" -"--\n" -"\n" -"Create a decompressor object for decompressing data incrementally.\n" -"\n" -" format\n" -" Specifies the container format of the input stream. If this is\n" -" FORMAT_AUTO (the default), the decompressor will automatically detect\n" -" whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with\n" -" FORMAT_RAW cannot be autodetected.\n" -" memlimit\n" -" Limit the amount of memory used by the decompressor. This will cause\n" -" decompression to fail if the input cannot be decompressed within the\n" -" given limit.\n" -" filters\n" -" A custom filter chain. This argument is required for FORMAT_RAW, and\n" -" not accepted with any other format. When provided, this should be a\n" -" sequence of dicts, each indicating the ID and options for a single\n" -" filter.\n" -"\n" -"For one-shot decompression, use the decompress() function instead."); - -static int -_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, - PyObject *memlimit, PyObject *filters); - -static int -_lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"format", "memlimit", "filters", NULL}; + return_value = _lzma_LZMADecompressor_decompress_impl(self, &data, max_length); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__, +"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n" +"--\n" +"\n" +"Create a decompressor object for decompressing data incrementally.\n" +"\n" +" format\n" +" Specifies the container format of the input stream. If this is\n" +" FORMAT_AUTO (the default), the decompressor will automatically detect\n" +" whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with\n" +" FORMAT_RAW cannot be autodetected.\n" +" memlimit\n" +" Limit the amount of memory used by the decompressor. This will cause\n" +" decompression to fail if the input cannot be decompressed within the\n" +" given limit.\n" +" filters\n" +" A custom filter chain. This argument is required for FORMAT_RAW, and\n" +" not accepted with any other format. When provided, this should be a\n" +" sequence of dicts, each indicating the ID and options for a single\n" +" filter.\n" +"\n" +"For one-shot decompression, use the decompress() function instead."); + +static int +_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, + PyObject *memlimit, PyObject *filters); + +static int +_lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"format", "memlimit", "filters", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "LZMADecompressor", 0}; PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - int format = FORMAT_AUTO; - PyObject *memlimit = Py_None; - PyObject *filters = Py_None; - + int format = FORMAT_AUTO; + PyObject *memlimit = Py_None; + PyObject *filters = Py_None; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 3, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -215,105 +215,105 @@ _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs } filters = fastargs[2]; skip_optional_pos: - return_value = _lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters); - -exit: - return return_value; -} - -PyDoc_STRVAR(_lzma_is_check_supported__doc__, -"is_check_supported($module, check_id, /)\n" -"--\n" -"\n" -"Test whether the given integrity check is supported.\n" -"\n" -"Always returns True for CHECK_NONE and CHECK_CRC32."); - -#define _LZMA_IS_CHECK_SUPPORTED_METHODDEF \ - {"is_check_supported", (PyCFunction)_lzma_is_check_supported, METH_O, _lzma_is_check_supported__doc__}, - -static PyObject * -_lzma_is_check_supported_impl(PyObject *module, int check_id); - -static PyObject * -_lzma_is_check_supported(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int check_id; - + return_value = _lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lzma_is_check_supported__doc__, +"is_check_supported($module, check_id, /)\n" +"--\n" +"\n" +"Test whether the given integrity check is supported.\n" +"\n" +"Always returns True for CHECK_NONE and CHECK_CRC32."); + +#define _LZMA_IS_CHECK_SUPPORTED_METHODDEF \ + {"is_check_supported", (PyCFunction)_lzma_is_check_supported, METH_O, _lzma_is_check_supported__doc__}, + +static PyObject * +_lzma_is_check_supported_impl(PyObject *module, int check_id); + +static PyObject * +_lzma_is_check_supported(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int check_id; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } check_id = _PyLong_AsInt(arg); if (check_id == -1 && PyErr_Occurred()) { goto exit; } - return_value = _lzma_is_check_supported_impl(module, check_id); - -exit: - return return_value; -} - -PyDoc_STRVAR(_lzma__encode_filter_properties__doc__, -"_encode_filter_properties($module, filter, /)\n" -"--\n" -"\n" -"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n" -"\n" -"The result does not include the filter ID itself, only the options."); - -#define _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF \ - {"_encode_filter_properties", (PyCFunction)_lzma__encode_filter_properties, METH_O, _lzma__encode_filter_properties__doc__}, - -static PyObject * -_lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter); - -static PyObject * -_lzma__encode_filter_properties(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL}; - + return_value = _lzma_is_check_supported_impl(module, check_id); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lzma__encode_filter_properties__doc__, +"_encode_filter_properties($module, filter, /)\n" +"--\n" +"\n" +"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n" +"\n" +"The result does not include the filter ID itself, only the options."); + +#define _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF \ + {"_encode_filter_properties", (PyCFunction)_lzma__encode_filter_properties, METH_O, _lzma__encode_filter_properties__doc__}, + +static PyObject * +_lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter); + +static PyObject * +_lzma__encode_filter_properties(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL}; + if (!lzma_filter_converter(arg, &filter)) { - goto exit; - } - return_value = _lzma__encode_filter_properties_impl(module, filter); - -exit: - /* Cleanup for filter */ - if (filter.id != LZMA_VLI_UNKNOWN) - PyMem_Free(filter.options); - - return return_value; -} - -PyDoc_STRVAR(_lzma__decode_filter_properties__doc__, -"_decode_filter_properties($module, filter_id, encoded_props, /)\n" -"--\n" -"\n" -"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n" -"\n" -"The result does not include the filter ID itself, only the options."); - -#define _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF \ + goto exit; + } + return_value = _lzma__encode_filter_properties_impl(module, filter); + +exit: + /* Cleanup for filter */ + if (filter.id != LZMA_VLI_UNKNOWN) + PyMem_Free(filter.options); + + return return_value; +} + +PyDoc_STRVAR(_lzma__decode_filter_properties__doc__, +"_decode_filter_properties($module, filter_id, encoded_props, /)\n" +"--\n" +"\n" +"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n" +"\n" +"The result does not include the filter ID itself, only the options."); + +#define _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF \ {"_decode_filter_properties", (PyCFunction)(void(*)(void))_lzma__decode_filter_properties, METH_FASTCALL, _lzma__decode_filter_properties__doc__}, - -static PyObject * -_lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id, - Py_buffer *encoded_props); - -static PyObject * -_lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - lzma_vli filter_id; - Py_buffer encoded_props = {NULL, NULL}; - + +static PyObject * +_lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id, + Py_buffer *encoded_props); + +static PyObject * +_lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + lzma_vli filter_id; + Py_buffer encoded_props = {NULL, NULL}; + if (!_PyArg_CheckPositional("_decode_filter_properties", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!lzma_vli_converter(args[0], &filter_id)) { goto exit; } @@ -324,14 +324,14 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz _PyArg_BadArgument("_decode_filter_properties", "argument 2", "contiguous buffer", args[1]); goto exit; } - return_value = _lzma__decode_filter_properties_impl(module, filter_id, &encoded_props); - -exit: - /* Cleanup for encoded_props */ - if (encoded_props.obj) { - PyBuffer_Release(&encoded_props); - } - - return return_value; -} + return_value = _lzma__decode_filter_properties_impl(module, filter_id, &encoded_props); + +exit: + /* Cleanup for encoded_props */ + if (encoded_props.obj) { + PyBuffer_Release(&encoded_props); + } + + return return_value; +} /*[clinic end generated code: output=f7477a10e86a717d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_opcode.c.h b/contrib/tools/python3/src/Modules/clinic/_opcode.c.h index 777701ff140..11b67db1327 100644 --- a/contrib/tools/python3/src/Modules/clinic/_opcode.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_opcode.c.h @@ -1,37 +1,37 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_opcode_stack_effect__doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_opcode_stack_effect__doc__, "stack_effect($module, opcode, oparg=None, /, *, jump=None)\n" -"--\n" -"\n" -"Compute the stack effect of the opcode."); - -#define _OPCODE_STACK_EFFECT_METHODDEF \ +"--\n" +"\n" +"Compute the stack effect of the opcode."); + +#define _OPCODE_STACK_EFFECT_METHODDEF \ {"stack_effect", (PyCFunction)(void(*)(void))_opcode_stack_effect, METH_FASTCALL|METH_KEYWORDS, _opcode_stack_effect__doc__}, - -static int + +static int _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, PyObject *jump); - -static PyObject * + +static PyObject * _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"", "", "jump", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "stack_effect", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - int opcode; - PyObject *oparg = Py_None; + int opcode; + PyObject *oparg = Py_None; PyObject *jump = Py_None; - int _return_value; - + int _return_value; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -53,12 +53,12 @@ skip_optional_posonly: jump = args[2]; skip_optional_kwonly: _return_value = _opcode_stack_effect_impl(module, opcode, oparg, jump); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} /*[clinic end generated code: output=7bc08f2835b2cf89 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_operator.c.h b/contrib/tools/python3/src/Modules/clinic/_operator.c.h index 0e39f3b77ad..968acba5106 100644 --- a/contrib/tools/python3/src/Modules/clinic/_operator.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_operator.c.h @@ -1,1425 +1,1425 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_operator_truth__doc__, -"truth($module, a, /)\n" -"--\n" -"\n" -"Return True if a is true, False otherwise."); - -#define _OPERATOR_TRUTH_METHODDEF \ - {"truth", (PyCFunction)_operator_truth, METH_O, _operator_truth__doc__}, - -static int -_operator_truth_impl(PyObject *module, PyObject *a); - -static PyObject * -_operator_truth(PyObject *module, PyObject *a) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = _operator_truth_impl(module, a); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_add__doc__, -"add($module, a, b, /)\n" -"--\n" -"\n" -"Same as a + b."); - -#define _OPERATOR_ADD_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_operator_truth__doc__, +"truth($module, a, /)\n" +"--\n" +"\n" +"Return True if a is true, False otherwise."); + +#define _OPERATOR_TRUTH_METHODDEF \ + {"truth", (PyCFunction)_operator_truth, METH_O, _operator_truth__doc__}, + +static int +_operator_truth_impl(PyObject *module, PyObject *a); + +static PyObject * +_operator_truth(PyObject *module, PyObject *a) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _operator_truth_impl(module, a); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_add__doc__, +"add($module, a, b, /)\n" +"--\n" +"\n" +"Same as a + b."); + +#define _OPERATOR_ADD_METHODDEF \ {"add", (PyCFunction)(void(*)(void))_operator_add, METH_FASTCALL, _operator_add__doc__}, - -static PyObject * -_operator_add_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_add_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("add", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_add_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_sub__doc__, -"sub($module, a, b, /)\n" -"--\n" -"\n" -"Same as a - b."); - -#define _OPERATOR_SUB_METHODDEF \ + return_value = _operator_add_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_sub__doc__, +"sub($module, a, b, /)\n" +"--\n" +"\n" +"Same as a - b."); + +#define _OPERATOR_SUB_METHODDEF \ {"sub", (PyCFunction)(void(*)(void))_operator_sub, METH_FASTCALL, _operator_sub__doc__}, - -static PyObject * -_operator_sub_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_sub(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_sub_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_sub(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("sub", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_sub_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_mul__doc__, -"mul($module, a, b, /)\n" -"--\n" -"\n" -"Same as a * b."); - -#define _OPERATOR_MUL_METHODDEF \ + return_value = _operator_sub_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_mul__doc__, +"mul($module, a, b, /)\n" +"--\n" +"\n" +"Same as a * b."); + +#define _OPERATOR_MUL_METHODDEF \ {"mul", (PyCFunction)(void(*)(void))_operator_mul, METH_FASTCALL, _operator_mul__doc__}, - -static PyObject * -_operator_mul_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_mul_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("mul", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_mul_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_matmul__doc__, -"matmul($module, a, b, /)\n" -"--\n" -"\n" -"Same as a @ b."); - -#define _OPERATOR_MATMUL_METHODDEF \ + return_value = _operator_mul_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_matmul__doc__, +"matmul($module, a, b, /)\n" +"--\n" +"\n" +"Same as a @ b."); + +#define _OPERATOR_MATMUL_METHODDEF \ {"matmul", (PyCFunction)(void(*)(void))_operator_matmul, METH_FASTCALL, _operator_matmul__doc__}, - -static PyObject * -_operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_matmul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_matmul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("matmul", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_matmul_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_floordiv__doc__, -"floordiv($module, a, b, /)\n" -"--\n" -"\n" -"Same as a // b."); - -#define _OPERATOR_FLOORDIV_METHODDEF \ + return_value = _operator_matmul_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_floordiv__doc__, +"floordiv($module, a, b, /)\n" +"--\n" +"\n" +"Same as a // b."); + +#define _OPERATOR_FLOORDIV_METHODDEF \ {"floordiv", (PyCFunction)(void(*)(void))_operator_floordiv, METH_FASTCALL, _operator_floordiv__doc__}, - -static PyObject * -_operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_floordiv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_floordiv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("floordiv", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_floordiv_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_truediv__doc__, -"truediv($module, a, b, /)\n" -"--\n" -"\n" -"Same as a / b."); - -#define _OPERATOR_TRUEDIV_METHODDEF \ + return_value = _operator_floordiv_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_truediv__doc__, +"truediv($module, a, b, /)\n" +"--\n" +"\n" +"Same as a / b."); + +#define _OPERATOR_TRUEDIV_METHODDEF \ {"truediv", (PyCFunction)(void(*)(void))_operator_truediv, METH_FASTCALL, _operator_truediv__doc__}, - -static PyObject * -_operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_truediv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_truediv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("truediv", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_truediv_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_mod__doc__, -"mod($module, a, b, /)\n" -"--\n" -"\n" -"Same as a % b."); - -#define _OPERATOR_MOD_METHODDEF \ + return_value = _operator_truediv_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_mod__doc__, +"mod($module, a, b, /)\n" +"--\n" +"\n" +"Same as a % b."); + +#define _OPERATOR_MOD_METHODDEF \ {"mod", (PyCFunction)(void(*)(void))_operator_mod, METH_FASTCALL, _operator_mod__doc__}, - -static PyObject * -_operator_mod_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_mod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_mod_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_mod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("mod", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_mod_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_neg__doc__, -"neg($module, a, /)\n" -"--\n" -"\n" -"Same as -a."); - -#define _OPERATOR_NEG_METHODDEF \ - {"neg", (PyCFunction)_operator_neg, METH_O, _operator_neg__doc__}, - -PyDoc_STRVAR(_operator_pos__doc__, -"pos($module, a, /)\n" -"--\n" -"\n" -"Same as +a."); - -#define _OPERATOR_POS_METHODDEF \ - {"pos", (PyCFunction)_operator_pos, METH_O, _operator_pos__doc__}, - -PyDoc_STRVAR(_operator_abs__doc__, -"abs($module, a, /)\n" -"--\n" -"\n" -"Same as abs(a)."); - -#define _OPERATOR_ABS_METHODDEF \ - {"abs", (PyCFunction)_operator_abs, METH_O, _operator_abs__doc__}, - -PyDoc_STRVAR(_operator_inv__doc__, -"inv($module, a, /)\n" -"--\n" -"\n" -"Same as ~a."); - -#define _OPERATOR_INV_METHODDEF \ - {"inv", (PyCFunction)_operator_inv, METH_O, _operator_inv__doc__}, - -PyDoc_STRVAR(_operator_invert__doc__, -"invert($module, a, /)\n" -"--\n" -"\n" -"Same as ~a."); - -#define _OPERATOR_INVERT_METHODDEF \ - {"invert", (PyCFunction)_operator_invert, METH_O, _operator_invert__doc__}, - -PyDoc_STRVAR(_operator_lshift__doc__, -"lshift($module, a, b, /)\n" -"--\n" -"\n" -"Same as a << b."); - -#define _OPERATOR_LSHIFT_METHODDEF \ + return_value = _operator_mod_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_neg__doc__, +"neg($module, a, /)\n" +"--\n" +"\n" +"Same as -a."); + +#define _OPERATOR_NEG_METHODDEF \ + {"neg", (PyCFunction)_operator_neg, METH_O, _operator_neg__doc__}, + +PyDoc_STRVAR(_operator_pos__doc__, +"pos($module, a, /)\n" +"--\n" +"\n" +"Same as +a."); + +#define _OPERATOR_POS_METHODDEF \ + {"pos", (PyCFunction)_operator_pos, METH_O, _operator_pos__doc__}, + +PyDoc_STRVAR(_operator_abs__doc__, +"abs($module, a, /)\n" +"--\n" +"\n" +"Same as abs(a)."); + +#define _OPERATOR_ABS_METHODDEF \ + {"abs", (PyCFunction)_operator_abs, METH_O, _operator_abs__doc__}, + +PyDoc_STRVAR(_operator_inv__doc__, +"inv($module, a, /)\n" +"--\n" +"\n" +"Same as ~a."); + +#define _OPERATOR_INV_METHODDEF \ + {"inv", (PyCFunction)_operator_inv, METH_O, _operator_inv__doc__}, + +PyDoc_STRVAR(_operator_invert__doc__, +"invert($module, a, /)\n" +"--\n" +"\n" +"Same as ~a."); + +#define _OPERATOR_INVERT_METHODDEF \ + {"invert", (PyCFunction)_operator_invert, METH_O, _operator_invert__doc__}, + +PyDoc_STRVAR(_operator_lshift__doc__, +"lshift($module, a, b, /)\n" +"--\n" +"\n" +"Same as a << b."); + +#define _OPERATOR_LSHIFT_METHODDEF \ {"lshift", (PyCFunction)(void(*)(void))_operator_lshift, METH_FASTCALL, _operator_lshift__doc__}, - -static PyObject * -_operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_lshift(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_lshift(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("lshift", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_lshift_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_rshift__doc__, -"rshift($module, a, b, /)\n" -"--\n" -"\n" -"Same as a >> b."); - -#define _OPERATOR_RSHIFT_METHODDEF \ + return_value = _operator_lshift_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_rshift__doc__, +"rshift($module, a, b, /)\n" +"--\n" +"\n" +"Same as a >> b."); + +#define _OPERATOR_RSHIFT_METHODDEF \ {"rshift", (PyCFunction)(void(*)(void))_operator_rshift, METH_FASTCALL, _operator_rshift__doc__}, - -static PyObject * -_operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_rshift(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_rshift(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("rshift", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_rshift_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_not___doc__, -"not_($module, a, /)\n" -"--\n" -"\n" -"Same as not a."); - -#define _OPERATOR_NOT__METHODDEF \ - {"not_", (PyCFunction)_operator_not_, METH_O, _operator_not___doc__}, - -static int -_operator_not__impl(PyObject *module, PyObject *a); - -static PyObject * -_operator_not_(PyObject *module, PyObject *a) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = _operator_not__impl(module, a); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_and___doc__, -"and_($module, a, b, /)\n" -"--\n" -"\n" -"Same as a & b."); - -#define _OPERATOR_AND__METHODDEF \ + return_value = _operator_rshift_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_not___doc__, +"not_($module, a, /)\n" +"--\n" +"\n" +"Same as not a."); + +#define _OPERATOR_NOT__METHODDEF \ + {"not_", (PyCFunction)_operator_not_, METH_O, _operator_not___doc__}, + +static int +_operator_not__impl(PyObject *module, PyObject *a); + +static PyObject * +_operator_not_(PyObject *module, PyObject *a) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _operator_not__impl(module, a); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_and___doc__, +"and_($module, a, b, /)\n" +"--\n" +"\n" +"Same as a & b."); + +#define _OPERATOR_AND__METHODDEF \ {"and_", (PyCFunction)(void(*)(void))_operator_and_, METH_FASTCALL, _operator_and___doc__}, - -static PyObject * -_operator_and__impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_and_(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_and__impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_and_(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("and_", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_and__impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_xor__doc__, -"xor($module, a, b, /)\n" -"--\n" -"\n" -"Same as a ^ b."); - -#define _OPERATOR_XOR_METHODDEF \ + return_value = _operator_and__impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_xor__doc__, +"xor($module, a, b, /)\n" +"--\n" +"\n" +"Same as a ^ b."); + +#define _OPERATOR_XOR_METHODDEF \ {"xor", (PyCFunction)(void(*)(void))_operator_xor, METH_FASTCALL, _operator_xor__doc__}, - -static PyObject * -_operator_xor_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_xor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_xor_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_xor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("xor", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_xor_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_or___doc__, -"or_($module, a, b, /)\n" -"--\n" -"\n" -"Same as a | b."); - -#define _OPERATOR_OR__METHODDEF \ + return_value = _operator_xor_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_or___doc__, +"or_($module, a, b, /)\n" +"--\n" +"\n" +"Same as a | b."); + +#define _OPERATOR_OR__METHODDEF \ {"or_", (PyCFunction)(void(*)(void))_operator_or_, METH_FASTCALL, _operator_or___doc__}, - -static PyObject * -_operator_or__impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_or_(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_or__impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_or_(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("or_", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_or__impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_iadd__doc__, -"iadd($module, a, b, /)\n" -"--\n" -"\n" -"Same as a += b."); - -#define _OPERATOR_IADD_METHODDEF \ + return_value = _operator_or__impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_iadd__doc__, +"iadd($module, a, b, /)\n" +"--\n" +"\n" +"Same as a += b."); + +#define _OPERATOR_IADD_METHODDEF \ {"iadd", (PyCFunction)(void(*)(void))_operator_iadd, METH_FASTCALL, _operator_iadd__doc__}, - -static PyObject * -_operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_iadd(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_iadd(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("iadd", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_iadd_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_isub__doc__, -"isub($module, a, b, /)\n" -"--\n" -"\n" -"Same as a -= b."); - -#define _OPERATOR_ISUB_METHODDEF \ + return_value = _operator_iadd_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_isub__doc__, +"isub($module, a, b, /)\n" +"--\n" +"\n" +"Same as a -= b."); + +#define _OPERATOR_ISUB_METHODDEF \ {"isub", (PyCFunction)(void(*)(void))_operator_isub, METH_FASTCALL, _operator_isub__doc__}, - -static PyObject * -_operator_isub_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_isub(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_isub_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_isub(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("isub", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_isub_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_imul__doc__, -"imul($module, a, b, /)\n" -"--\n" -"\n" -"Same as a *= b."); - -#define _OPERATOR_IMUL_METHODDEF \ + return_value = _operator_isub_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_imul__doc__, +"imul($module, a, b, /)\n" +"--\n" +"\n" +"Same as a *= b."); + +#define _OPERATOR_IMUL_METHODDEF \ {"imul", (PyCFunction)(void(*)(void))_operator_imul, METH_FASTCALL, _operator_imul__doc__}, - -static PyObject * -_operator_imul_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_imul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_imul_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_imul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("imul", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_imul_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_imatmul__doc__, -"imatmul($module, a, b, /)\n" -"--\n" -"\n" -"Same as a @= b."); - -#define _OPERATOR_IMATMUL_METHODDEF \ + return_value = _operator_imul_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_imatmul__doc__, +"imatmul($module, a, b, /)\n" +"--\n" +"\n" +"Same as a @= b."); + +#define _OPERATOR_IMATMUL_METHODDEF \ {"imatmul", (PyCFunction)(void(*)(void))_operator_imatmul, METH_FASTCALL, _operator_imatmul__doc__}, - -static PyObject * -_operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_imatmul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_imatmul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("imatmul", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_imatmul_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_ifloordiv__doc__, -"ifloordiv($module, a, b, /)\n" -"--\n" -"\n" -"Same as a //= b."); - -#define _OPERATOR_IFLOORDIV_METHODDEF \ + return_value = _operator_imatmul_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_ifloordiv__doc__, +"ifloordiv($module, a, b, /)\n" +"--\n" +"\n" +"Same as a //= b."); + +#define _OPERATOR_IFLOORDIV_METHODDEF \ {"ifloordiv", (PyCFunction)(void(*)(void))_operator_ifloordiv, METH_FASTCALL, _operator_ifloordiv__doc__}, - -static PyObject * -_operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_ifloordiv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_ifloordiv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("ifloordiv", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_ifloordiv_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_itruediv__doc__, -"itruediv($module, a, b, /)\n" -"--\n" -"\n" -"Same as a /= b."); - -#define _OPERATOR_ITRUEDIV_METHODDEF \ + return_value = _operator_ifloordiv_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_itruediv__doc__, +"itruediv($module, a, b, /)\n" +"--\n" +"\n" +"Same as a /= b."); + +#define _OPERATOR_ITRUEDIV_METHODDEF \ {"itruediv", (PyCFunction)(void(*)(void))_operator_itruediv, METH_FASTCALL, _operator_itruediv__doc__}, - -static PyObject * -_operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_itruediv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_itruediv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("itruediv", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_itruediv_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_imod__doc__, -"imod($module, a, b, /)\n" -"--\n" -"\n" -"Same as a %= b."); - -#define _OPERATOR_IMOD_METHODDEF \ + return_value = _operator_itruediv_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_imod__doc__, +"imod($module, a, b, /)\n" +"--\n" +"\n" +"Same as a %= b."); + +#define _OPERATOR_IMOD_METHODDEF \ {"imod", (PyCFunction)(void(*)(void))_operator_imod, METH_FASTCALL, _operator_imod__doc__}, - -static PyObject * -_operator_imod_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_imod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_imod_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_imod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("imod", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_imod_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_ilshift__doc__, -"ilshift($module, a, b, /)\n" -"--\n" -"\n" -"Same as a <<= b."); - -#define _OPERATOR_ILSHIFT_METHODDEF \ + return_value = _operator_imod_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_ilshift__doc__, +"ilshift($module, a, b, /)\n" +"--\n" +"\n" +"Same as a <<= b."); + +#define _OPERATOR_ILSHIFT_METHODDEF \ {"ilshift", (PyCFunction)(void(*)(void))_operator_ilshift, METH_FASTCALL, _operator_ilshift__doc__}, - -static PyObject * -_operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_ilshift(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_ilshift(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("ilshift", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_ilshift_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_irshift__doc__, -"irshift($module, a, b, /)\n" -"--\n" -"\n" -"Same as a >>= b."); - -#define _OPERATOR_IRSHIFT_METHODDEF \ + return_value = _operator_ilshift_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_irshift__doc__, +"irshift($module, a, b, /)\n" +"--\n" +"\n" +"Same as a >>= b."); + +#define _OPERATOR_IRSHIFT_METHODDEF \ {"irshift", (PyCFunction)(void(*)(void))_operator_irshift, METH_FASTCALL, _operator_irshift__doc__}, - -static PyObject * -_operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_irshift(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_irshift(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("irshift", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_irshift_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_iand__doc__, -"iand($module, a, b, /)\n" -"--\n" -"\n" -"Same as a &= b."); - -#define _OPERATOR_IAND_METHODDEF \ + return_value = _operator_irshift_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_iand__doc__, +"iand($module, a, b, /)\n" +"--\n" +"\n" +"Same as a &= b."); + +#define _OPERATOR_IAND_METHODDEF \ {"iand", (PyCFunction)(void(*)(void))_operator_iand, METH_FASTCALL, _operator_iand__doc__}, - -static PyObject * -_operator_iand_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_iand(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_iand_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_iand(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("iand", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_iand_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_ixor__doc__, -"ixor($module, a, b, /)\n" -"--\n" -"\n" -"Same as a ^= b."); - -#define _OPERATOR_IXOR_METHODDEF \ + return_value = _operator_iand_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_ixor__doc__, +"ixor($module, a, b, /)\n" +"--\n" +"\n" +"Same as a ^= b."); + +#define _OPERATOR_IXOR_METHODDEF \ {"ixor", (PyCFunction)(void(*)(void))_operator_ixor, METH_FASTCALL, _operator_ixor__doc__}, - -static PyObject * -_operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_ixor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_ixor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("ixor", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_ixor_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_ior__doc__, -"ior($module, a, b, /)\n" -"--\n" -"\n" -"Same as a |= b."); - -#define _OPERATOR_IOR_METHODDEF \ + return_value = _operator_ixor_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_ior__doc__, +"ior($module, a, b, /)\n" +"--\n" +"\n" +"Same as a |= b."); + +#define _OPERATOR_IOR_METHODDEF \ {"ior", (PyCFunction)(void(*)(void))_operator_ior, METH_FASTCALL, _operator_ior__doc__}, - -static PyObject * -_operator_ior_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_ior(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_ior_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_ior(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("ior", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_ior_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_concat__doc__, -"concat($module, a, b, /)\n" -"--\n" -"\n" -"Same as a + b, for a and b sequences."); - -#define _OPERATOR_CONCAT_METHODDEF \ + return_value = _operator_ior_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_concat__doc__, +"concat($module, a, b, /)\n" +"--\n" +"\n" +"Same as a + b, for a and b sequences."); + +#define _OPERATOR_CONCAT_METHODDEF \ {"concat", (PyCFunction)(void(*)(void))_operator_concat, METH_FASTCALL, _operator_concat__doc__}, - -static PyObject * -_operator_concat_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_concat(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_concat_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_concat(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("concat", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_concat_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_iconcat__doc__, -"iconcat($module, a, b, /)\n" -"--\n" -"\n" -"Same as a += b, for a and b sequences."); - -#define _OPERATOR_ICONCAT_METHODDEF \ + return_value = _operator_concat_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_iconcat__doc__, +"iconcat($module, a, b, /)\n" +"--\n" +"\n" +"Same as a += b, for a and b sequences."); + +#define _OPERATOR_ICONCAT_METHODDEF \ {"iconcat", (PyCFunction)(void(*)(void))_operator_iconcat, METH_FASTCALL, _operator_iconcat__doc__}, - -static PyObject * -_operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_iconcat(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_iconcat(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("iconcat", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_iconcat_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_contains__doc__, -"contains($module, a, b, /)\n" -"--\n" -"\n" -"Same as b in a (note reversed operands)."); - -#define _OPERATOR_CONTAINS_METHODDEF \ + return_value = _operator_iconcat_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_contains__doc__, +"contains($module, a, b, /)\n" +"--\n" +"\n" +"Same as b in a (note reversed operands)."); + +#define _OPERATOR_CONTAINS_METHODDEF \ {"contains", (PyCFunction)(void(*)(void))_operator_contains, METH_FASTCALL, _operator_contains__doc__}, - -static int -_operator_contains_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_contains(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - int _return_value; - + +static int +_operator_contains_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_contains(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + int _return_value; + if (!_PyArg_CheckPositional("contains", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - _return_value = _operator_contains_impl(module, a, b); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_indexOf__doc__, -"indexOf($module, a, b, /)\n" -"--\n" -"\n" -"Return the first index of b in a."); - -#define _OPERATOR_INDEXOF_METHODDEF \ + _return_value = _operator_contains_impl(module, a, b); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_indexOf__doc__, +"indexOf($module, a, b, /)\n" +"--\n" +"\n" +"Return the first index of b in a."); + +#define _OPERATOR_INDEXOF_METHODDEF \ {"indexOf", (PyCFunction)(void(*)(void))_operator_indexOf, METH_FASTCALL, _operator_indexOf__doc__}, - -static Py_ssize_t -_operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_indexOf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - Py_ssize_t _return_value; - + +static Py_ssize_t +_operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_indexOf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + Py_ssize_t _return_value; + if (!_PyArg_CheckPositional("indexOf", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - _return_value = _operator_indexOf_impl(module, a, b); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_countOf__doc__, -"countOf($module, a, b, /)\n" -"--\n" -"\n" + _return_value = _operator_indexOf_impl(module, a, b); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_countOf__doc__, +"countOf($module, a, b, /)\n" +"--\n" +"\n" "Return the number of items in a which are, or which equal, b."); - -#define _OPERATOR_COUNTOF_METHODDEF \ + +#define _OPERATOR_COUNTOF_METHODDEF \ {"countOf", (PyCFunction)(void(*)(void))_operator_countOf, METH_FASTCALL, _operator_countOf__doc__}, - -static Py_ssize_t -_operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_countOf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - Py_ssize_t _return_value; - + +static Py_ssize_t +_operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_countOf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + Py_ssize_t _return_value; + if (!_PyArg_CheckPositional("countOf", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - _return_value = _operator_countOf_impl(module, a, b); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_getitem__doc__, -"getitem($module, a, b, /)\n" -"--\n" -"\n" -"Same as a[b]."); - -#define _OPERATOR_GETITEM_METHODDEF \ + _return_value = _operator_countOf_impl(module, a, b); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_getitem__doc__, +"getitem($module, a, b, /)\n" +"--\n" +"\n" +"Same as a[b]."); + +#define _OPERATOR_GETITEM_METHODDEF \ {"getitem", (PyCFunction)(void(*)(void))_operator_getitem, METH_FASTCALL, _operator_getitem__doc__}, - -static PyObject * -_operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_getitem(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_getitem(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("getitem", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_getitem_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_setitem__doc__, -"setitem($module, a, b, c, /)\n" -"--\n" -"\n" -"Same as a[b] = c."); - -#define _OPERATOR_SETITEM_METHODDEF \ + return_value = _operator_getitem_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_setitem__doc__, +"setitem($module, a, b, c, /)\n" +"--\n" +"\n" +"Same as a[b] = c."); + +#define _OPERATOR_SETITEM_METHODDEF \ {"setitem", (PyCFunction)(void(*)(void))_operator_setitem, METH_FASTCALL, _operator_setitem__doc__}, - -static PyObject * -_operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *c); - -static PyObject * -_operator_setitem(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - PyObject *c; - + +static PyObject * +_operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +static PyObject * +_operator_setitem(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + PyObject *c; + if (!_PyArg_CheckPositional("setitem", nargs, 3, 3)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; c = args[2]; - return_value = _operator_setitem_impl(module, a, b, c); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_delitem__doc__, -"delitem($module, a, b, /)\n" -"--\n" -"\n" -"Same as del a[b]."); - -#define _OPERATOR_DELITEM_METHODDEF \ + return_value = _operator_setitem_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_delitem__doc__, +"delitem($module, a, b, /)\n" +"--\n" +"\n" +"Same as del a[b]."); + +#define _OPERATOR_DELITEM_METHODDEF \ {"delitem", (PyCFunction)(void(*)(void))_operator_delitem, METH_FASTCALL, _operator_delitem__doc__}, - -static PyObject * -_operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_delitem(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_delitem(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("delitem", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_delitem_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_eq__doc__, -"eq($module, a, b, /)\n" -"--\n" -"\n" -"Same as a == b."); - -#define _OPERATOR_EQ_METHODDEF \ + return_value = _operator_delitem_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_eq__doc__, +"eq($module, a, b, /)\n" +"--\n" +"\n" +"Same as a == b."); + +#define _OPERATOR_EQ_METHODDEF \ {"eq", (PyCFunction)(void(*)(void))_operator_eq, METH_FASTCALL, _operator_eq__doc__}, - -static PyObject * -_operator_eq_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_eq(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_eq_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_eq(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("eq", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_eq_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_ne__doc__, -"ne($module, a, b, /)\n" -"--\n" -"\n" -"Same as a != b."); - -#define _OPERATOR_NE_METHODDEF \ + return_value = _operator_eq_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_ne__doc__, +"ne($module, a, b, /)\n" +"--\n" +"\n" +"Same as a != b."); + +#define _OPERATOR_NE_METHODDEF \ {"ne", (PyCFunction)(void(*)(void))_operator_ne, METH_FASTCALL, _operator_ne__doc__}, - -static PyObject * -_operator_ne_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_ne(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_ne_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_ne(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("ne", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_ne_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_lt__doc__, -"lt($module, a, b, /)\n" -"--\n" -"\n" -"Same as a < b."); - -#define _OPERATOR_LT_METHODDEF \ + return_value = _operator_ne_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_lt__doc__, +"lt($module, a, b, /)\n" +"--\n" +"\n" +"Same as a < b."); + +#define _OPERATOR_LT_METHODDEF \ {"lt", (PyCFunction)(void(*)(void))_operator_lt, METH_FASTCALL, _operator_lt__doc__}, - -static PyObject * -_operator_lt_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_lt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_lt_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_lt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("lt", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_lt_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_le__doc__, -"le($module, a, b, /)\n" -"--\n" -"\n" -"Same as a <= b."); - -#define _OPERATOR_LE_METHODDEF \ + return_value = _operator_lt_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_le__doc__, +"le($module, a, b, /)\n" +"--\n" +"\n" +"Same as a <= b."); + +#define _OPERATOR_LE_METHODDEF \ {"le", (PyCFunction)(void(*)(void))_operator_le, METH_FASTCALL, _operator_le__doc__}, - -static PyObject * -_operator_le_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_le(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_le_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_le(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("le", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_le_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_gt__doc__, -"gt($module, a, b, /)\n" -"--\n" -"\n" -"Same as a > b."); - -#define _OPERATOR_GT_METHODDEF \ + return_value = _operator_le_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_gt__doc__, +"gt($module, a, b, /)\n" +"--\n" +"\n" +"Same as a > b."); + +#define _OPERATOR_GT_METHODDEF \ {"gt", (PyCFunction)(void(*)(void))_operator_gt, METH_FASTCALL, _operator_gt__doc__}, - -static PyObject * -_operator_gt_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_gt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_gt_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_gt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("gt", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_gt_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_ge__doc__, -"ge($module, a, b, /)\n" -"--\n" -"\n" -"Same as a >= b."); - -#define _OPERATOR_GE_METHODDEF \ + return_value = _operator_gt_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_ge__doc__, +"ge($module, a, b, /)\n" +"--\n" +"\n" +"Same as a >= b."); + +#define _OPERATOR_GE_METHODDEF \ {"ge", (PyCFunction)(void(*)(void))_operator_ge, METH_FASTCALL, _operator_ge__doc__}, - -static PyObject * -_operator_ge_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_ge(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_ge_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_ge(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("ge", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_ge_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_pow__doc__, -"pow($module, a, b, /)\n" -"--\n" -"\n" -"Same as a ** b."); - -#define _OPERATOR_POW_METHODDEF \ + return_value = _operator_ge_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_pow__doc__, +"pow($module, a, b, /)\n" +"--\n" +"\n" +"Same as a ** b."); + +#define _OPERATOR_POW_METHODDEF \ {"pow", (PyCFunction)(void(*)(void))_operator_pow, METH_FASTCALL, _operator_pow__doc__}, - -static PyObject * -_operator_pow_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_pow_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_pow_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_ipow__doc__, -"ipow($module, a, b, /)\n" -"--\n" -"\n" -"Same as a **= b."); - -#define _OPERATOR_IPOW_METHODDEF \ + return_value = _operator_pow_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_ipow__doc__, +"ipow($module, a, b, /)\n" +"--\n" +"\n" +"Same as a **= b."); + +#define _OPERATOR_IPOW_METHODDEF \ {"ipow", (PyCFunction)(void(*)(void))_operator_ipow, METH_FASTCALL, _operator_ipow__doc__}, - -static PyObject * -_operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_ipow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_ipow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("ipow", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_ipow_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_index__doc__, -"index($module, a, /)\n" -"--\n" -"\n" -"Same as a.__index__()"); - -#define _OPERATOR_INDEX_METHODDEF \ - {"index", (PyCFunction)_operator_index, METH_O, _operator_index__doc__}, - -PyDoc_STRVAR(_operator_is___doc__, -"is_($module, a, b, /)\n" -"--\n" -"\n" -"Same as a is b."); - -#define _OPERATOR_IS__METHODDEF \ + return_value = _operator_ipow_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_index__doc__, +"index($module, a, /)\n" +"--\n" +"\n" +"Same as a.__index__()"); + +#define _OPERATOR_INDEX_METHODDEF \ + {"index", (PyCFunction)_operator_index, METH_O, _operator_index__doc__}, + +PyDoc_STRVAR(_operator_is___doc__, +"is_($module, a, b, /)\n" +"--\n" +"\n" +"Same as a is b."); + +#define _OPERATOR_IS__METHODDEF \ {"is_", (PyCFunction)(void(*)(void))_operator_is_, METH_FASTCALL, _operator_is___doc__}, - -static PyObject * -_operator_is__impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_is_(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_is__impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_is_(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("is_", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_is__impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_is_not__doc__, -"is_not($module, a, b, /)\n" -"--\n" -"\n" -"Same as a is not b."); - -#define _OPERATOR_IS_NOT_METHODDEF \ + return_value = _operator_is__impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_is_not__doc__, +"is_not($module, a, b, /)\n" +"--\n" +"\n" +"Same as a is not b."); + +#define _OPERATOR_IS_NOT_METHODDEF \ {"is_not", (PyCFunction)(void(*)(void))_operator_is_not, METH_FASTCALL, _operator_is_not__doc__}, - -static PyObject * -_operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator_is_not(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator_is_not(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("is_not", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator_is_not_impl(module, a, b); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator_length_hint__doc__, -"length_hint($module, obj, default=0, /)\n" -"--\n" -"\n" -"Return an estimate of the number of items in obj.\n" -"\n" -"This is useful for presizing containers when building from an iterable.\n" -"\n" -"If the object supports len(), the result will be exact.\n" -"Otherwise, it may over- or under-estimate by an arbitrary amount.\n" -"The result will be an integer >= 0."); - -#define _OPERATOR_LENGTH_HINT_METHODDEF \ + return_value = _operator_is_not_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator_length_hint__doc__, +"length_hint($module, obj, default=0, /)\n" +"--\n" +"\n" +"Return an estimate of the number of items in obj.\n" +"\n" +"This is useful for presizing containers when building from an iterable.\n" +"\n" +"If the object supports len(), the result will be exact.\n" +"Otherwise, it may over- or under-estimate by an arbitrary amount.\n" +"The result will be an integer >= 0."); + +#define _OPERATOR_LENGTH_HINT_METHODDEF \ {"length_hint", (PyCFunction)(void(*)(void))_operator_length_hint, METH_FASTCALL, _operator_length_hint__doc__}, - -static Py_ssize_t -_operator_length_hint_impl(PyObject *module, PyObject *obj, - Py_ssize_t default_value); - -static PyObject * -_operator_length_hint(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *obj; - Py_ssize_t default_value = 0; - Py_ssize_t _return_value; - + +static Py_ssize_t +_operator_length_hint_impl(PyObject *module, PyObject *obj, + Py_ssize_t default_value); + +static PyObject * +_operator_length_hint(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *obj; + Py_ssize_t default_value = 0; + Py_ssize_t _return_value; + if (!_PyArg_CheckPositional("length_hint", nargs, 1, 2)) { - goto exit; - } + goto exit; + } obj = args[0]; if (nargs < 2) { goto skip_optional; @@ -1442,53 +1442,53 @@ _operator_length_hint(PyObject *module, PyObject *const *args, Py_ssize_t nargs) default_value = ival; } skip_optional: - _return_value = _operator_length_hint_impl(module, obj, default_value); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_operator__compare_digest__doc__, -"_compare_digest($module, a, b, /)\n" -"--\n" -"\n" -"Return \'a == b\'.\n" -"\n" -"This function uses an approach designed to prevent\n" -"timing analysis, making it appropriate for cryptography.\n" -"\n" -"a and b must both be of the same type: either str (ASCII only),\n" -"or any bytes-like object.\n" -"\n" -"Note: If a and b are of different lengths, or if an error occurs,\n" -"a timing attack could theoretically reveal information about the\n" -"types and lengths of a and b--but not their values."); - -#define _OPERATOR__COMPARE_DIGEST_METHODDEF \ + _return_value = _operator_length_hint_impl(module, obj, default_value); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_operator__compare_digest__doc__, +"_compare_digest($module, a, b, /)\n" +"--\n" +"\n" +"Return \'a == b\'.\n" +"\n" +"This function uses an approach designed to prevent\n" +"timing analysis, making it appropriate for cryptography.\n" +"\n" +"a and b must both be of the same type: either str (ASCII only),\n" +"or any bytes-like object.\n" +"\n" +"Note: If a and b are of different lengths, or if an error occurs,\n" +"a timing attack could theoretically reveal information about the\n" +"types and lengths of a and b--but not their values."); + +#define _OPERATOR__COMPARE_DIGEST_METHODDEF \ {"_compare_digest", (PyCFunction)(void(*)(void))_operator__compare_digest, METH_FASTCALL, _operator__compare_digest__doc__}, - -static PyObject * -_operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b); - -static PyObject * -_operator__compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *a; - PyObject *b; - + +static PyObject * +_operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +_operator__compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + if (!_PyArg_CheckPositional("_compare_digest", nargs, 2, 2)) { - goto exit; - } + goto exit; + } a = args[0]; b = args[1]; - return_value = _operator__compare_digest_impl(module, a, b); - -exit: - return return_value; -} + return_value = _operator__compare_digest_impl(module, a, b); + +exit: + return return_value; +} /*[clinic end generated code: output=ed2bc172e42320d8 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_pickle.c.h b/contrib/tools/python3/src/Modules/clinic/_pickle.c.h index 136524b6a71..f8038867cb6 100644 --- a/contrib/tools/python3/src/Modules/clinic/_pickle.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_pickle.c.h @@ -1,89 +1,89 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, -"clear_memo($self, /)\n" -"--\n" -"\n" -"Clears the pickler\'s \"memo\".\n" -"\n" -"The memo is the data structure that remembers which objects the\n" -"pickler has already seen, so that shared or recursive objects are\n" -"pickled by reference and not by value. This method is useful when\n" -"re-using picklers."); - -#define _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF \ - {"clear_memo", (PyCFunction)_pickle_Pickler_clear_memo, METH_NOARGS, _pickle_Pickler_clear_memo__doc__}, - -static PyObject * -_pickle_Pickler_clear_memo_impl(PicklerObject *self); - -static PyObject * -_pickle_Pickler_clear_memo(PicklerObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _pickle_Pickler_clear_memo_impl(self); -} - -PyDoc_STRVAR(_pickle_Pickler_dump__doc__, -"dump($self, obj, /)\n" -"--\n" -"\n" -"Write a pickled representation of the given object to the open file."); - -#define _PICKLE_PICKLER_DUMP_METHODDEF \ - {"dump", (PyCFunction)_pickle_Pickler_dump, METH_O, _pickle_Pickler_dump__doc__}, - -PyDoc_STRVAR(_pickle_Pickler___sizeof____doc__, -"__sizeof__($self, /)\n" -"--\n" -"\n" -"Returns size in memory, in bytes."); - -#define _PICKLE_PICKLER___SIZEOF___METHODDEF \ - {"__sizeof__", (PyCFunction)_pickle_Pickler___sizeof__, METH_NOARGS, _pickle_Pickler___sizeof____doc__}, - -static Py_ssize_t -_pickle_Pickler___sizeof___impl(PicklerObject *self); - -static PyObject * -_pickle_Pickler___sizeof__(PicklerObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = _pickle_Pickler___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_pickle_Pickler___init____doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, +"clear_memo($self, /)\n" +"--\n" +"\n" +"Clears the pickler\'s \"memo\".\n" +"\n" +"The memo is the data structure that remembers which objects the\n" +"pickler has already seen, so that shared or recursive objects are\n" +"pickled by reference and not by value. This method is useful when\n" +"re-using picklers."); + +#define _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF \ + {"clear_memo", (PyCFunction)_pickle_Pickler_clear_memo, METH_NOARGS, _pickle_Pickler_clear_memo__doc__}, + +static PyObject * +_pickle_Pickler_clear_memo_impl(PicklerObject *self); + +static PyObject * +_pickle_Pickler_clear_memo(PicklerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_Pickler_clear_memo_impl(self); +} + +PyDoc_STRVAR(_pickle_Pickler_dump__doc__, +"dump($self, obj, /)\n" +"--\n" +"\n" +"Write a pickled representation of the given object to the open file."); + +#define _PICKLE_PICKLER_DUMP_METHODDEF \ + {"dump", (PyCFunction)_pickle_Pickler_dump, METH_O, _pickle_Pickler_dump__doc__}, + +PyDoc_STRVAR(_pickle_Pickler___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns size in memory, in bytes."); + +#define _PICKLE_PICKLER___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_pickle_Pickler___sizeof__, METH_NOARGS, _pickle_Pickler___sizeof____doc__}, + +static Py_ssize_t +_pickle_Pickler___sizeof___impl(PicklerObject *self); + +static PyObject * +_pickle_Pickler___sizeof__(PicklerObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _pickle_Pickler___sizeof___impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_Pickler___init____doc__, "Pickler(file, protocol=None, fix_imports=True, buffer_callback=None)\n" -"--\n" -"\n" -"This takes a binary file for writing a pickle data stream.\n" -"\n" -"The optional *protocol* argument tells the pickler to use the given\n" +"--\n" +"\n" +"This takes a binary file for writing a pickle data stream.\n" +"\n" +"The optional *protocol* argument tells the pickler to use the given\n" "protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default\n" "protocol is 4. It was introduced in Python 3.4, and is incompatible\n" "with previous versions.\n" -"\n" -"Specifying a negative protocol version selects the highest protocol\n" -"version supported. The higher the protocol used, the more recent the\n" -"version of Python needed to read the pickle produced.\n" -"\n" -"The *file* argument must have a write() method that accepts a single\n" -"bytes argument. It can thus be a file object opened for binary\n" -"writing, an io.BytesIO instance, or any other custom object that meets\n" -"this interface.\n" -"\n" -"If *fix_imports* is True and protocol is less than 3, pickle will try\n" -"to map the new Python 3 names to the old module names used in Python\n" +"\n" +"Specifying a negative protocol version selects the highest protocol\n" +"version supported. The higher the protocol used, the more recent the\n" +"version of Python needed to read the pickle produced.\n" +"\n" +"The *file* argument must have a write() method that accepts a single\n" +"bytes argument. It can thus be a file object opened for binary\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" +"this interface.\n" +"\n" +"If *fix_imports* is True and protocol is less than 3, pickle will try\n" +"to map the new Python 3 names to the old module names used in Python\n" "2, so that the pickle data stream is readable with Python 2.\n" "\n" "If *buffer_callback* is None (the default), buffer views are\n" @@ -96,31 +96,31 @@ PyDoc_STRVAR(_pickle_Pickler___init____doc__, "\n" "It is an error if *buffer_callback* is not None and *protocol*\n" "is None or smaller than 5."); - -static int -_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, + +static int +_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports, PyObject *buffer_callback); - -static int -_pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; + +static int +_pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; static const char * const _keywords[] = {"file", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "Pickler", 0}; PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *file; + PyObject *file; PyObject *protocol = Py_None; - int fix_imports = 1; + int fix_imports = 1; PyObject *buffer_callback = Py_None; - + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 4, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } file = fastargs[0]; if (!noptargs) { goto skip_optional_pos; @@ -143,205 +143,205 @@ _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) buffer_callback = fastargs[3]; skip_optional_pos: return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports, buffer_callback); - -exit: - return return_value; -} - -PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__, -"clear($self, /)\n" -"--\n" -"\n" -"Remove all items from memo."); - -#define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \ - {"clear", (PyCFunction)_pickle_PicklerMemoProxy_clear, METH_NOARGS, _pickle_PicklerMemoProxy_clear__doc__}, - -static PyObject * -_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self); - -static PyObject * -_pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _pickle_PicklerMemoProxy_clear_impl(self); -} - -PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Copy the memo to a new object."); - -#define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \ - {"copy", (PyCFunction)_pickle_PicklerMemoProxy_copy, METH_NOARGS, _pickle_PicklerMemoProxy_copy__doc__}, - -static PyObject * -_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self); - -static PyObject * -_pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _pickle_PicklerMemoProxy_copy_impl(self); -} - -PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__, -"__reduce__($self, /)\n" -"--\n" -"\n" -"Implement pickle support."); - -#define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)_pickle_PicklerMemoProxy___reduce__, METH_NOARGS, _pickle_PicklerMemoProxy___reduce____doc__}, - -static PyObject * -_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self); - -static PyObject * -_pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _pickle_PicklerMemoProxy___reduce___impl(self); -} - -PyDoc_STRVAR(_pickle_Unpickler_load__doc__, -"load($self, /)\n" -"--\n" -"\n" -"Load a pickle.\n" -"\n" -"Read a pickled object representation from the open file object given\n" -"in the constructor, and return the reconstituted object hierarchy\n" -"specified therein."); - -#define _PICKLE_UNPICKLER_LOAD_METHODDEF \ - {"load", (PyCFunction)_pickle_Unpickler_load, METH_NOARGS, _pickle_Unpickler_load__doc__}, - -static PyObject * -_pickle_Unpickler_load_impl(UnpicklerObject *self); - -static PyObject * -_pickle_Unpickler_load(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _pickle_Unpickler_load_impl(self); -} - -PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, -"find_class($self, module_name, global_name, /)\n" -"--\n" -"\n" -"Return an object from a specified module.\n" -"\n" -"If necessary, the module will be imported. Subclasses may override\n" -"this method (e.g. to restrict unpickling of arbitrary classes and\n" -"functions).\n" -"\n" -"This method is called whenever a class or a function object is\n" -"needed. Both arguments passed are str objects."); - -#define _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF \ + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from memo."); + +#define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \ + {"clear", (PyCFunction)_pickle_PicklerMemoProxy_clear, METH_NOARGS, _pickle_PicklerMemoProxy_clear__doc__}, + +static PyObject * +_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self); + +static PyObject * +_pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_PicklerMemoProxy_clear_impl(self); +} + +PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Copy the memo to a new object."); + +#define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \ + {"copy", (PyCFunction)_pickle_PicklerMemoProxy_copy, METH_NOARGS, _pickle_PicklerMemoProxy_copy__doc__}, + +static PyObject * +_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self); + +static PyObject * +_pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_PicklerMemoProxy_copy_impl(self); +} + +PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Implement pickle support."); + +#define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)_pickle_PicklerMemoProxy___reduce__, METH_NOARGS, _pickle_PicklerMemoProxy___reduce____doc__}, + +static PyObject * +_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self); + +static PyObject * +_pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_PicklerMemoProxy___reduce___impl(self); +} + +PyDoc_STRVAR(_pickle_Unpickler_load__doc__, +"load($self, /)\n" +"--\n" +"\n" +"Load a pickle.\n" +"\n" +"Read a pickled object representation from the open file object given\n" +"in the constructor, and return the reconstituted object hierarchy\n" +"specified therein."); + +#define _PICKLE_UNPICKLER_LOAD_METHODDEF \ + {"load", (PyCFunction)_pickle_Unpickler_load, METH_NOARGS, _pickle_Unpickler_load__doc__}, + +static PyObject * +_pickle_Unpickler_load_impl(UnpicklerObject *self); + +static PyObject * +_pickle_Unpickler_load(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_Unpickler_load_impl(self); +} + +PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, +"find_class($self, module_name, global_name, /)\n" +"--\n" +"\n" +"Return an object from a specified module.\n" +"\n" +"If necessary, the module will be imported. Subclasses may override\n" +"this method (e.g. to restrict unpickling of arbitrary classes and\n" +"functions).\n" +"\n" +"This method is called whenever a class or a function object is\n" +"needed. Both arguments passed are str objects."); + +#define _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF \ {"find_class", (PyCFunction)(void(*)(void))_pickle_Unpickler_find_class, METH_FASTCALL, _pickle_Unpickler_find_class__doc__}, - -static PyObject * -_pickle_Unpickler_find_class_impl(UnpicklerObject *self, - PyObject *module_name, - PyObject *global_name); - -static PyObject * -_pickle_Unpickler_find_class(UnpicklerObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *module_name; - PyObject *global_name; - + +static PyObject * +_pickle_Unpickler_find_class_impl(UnpicklerObject *self, + PyObject *module_name, + PyObject *global_name); + +static PyObject * +_pickle_Unpickler_find_class(UnpicklerObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *module_name; + PyObject *global_name; + if (!_PyArg_CheckPositional("find_class", nargs, 2, 2)) { - goto exit; - } + goto exit; + } module_name = args[0]; global_name = args[1]; - return_value = _pickle_Unpickler_find_class_impl(self, module_name, global_name); - -exit: - return return_value; -} - -PyDoc_STRVAR(_pickle_Unpickler___sizeof____doc__, -"__sizeof__($self, /)\n" -"--\n" -"\n" -"Returns size in memory, in bytes."); - -#define _PICKLE_UNPICKLER___SIZEOF___METHODDEF \ - {"__sizeof__", (PyCFunction)_pickle_Unpickler___sizeof__, METH_NOARGS, _pickle_Unpickler___sizeof____doc__}, - -static Py_ssize_t -_pickle_Unpickler___sizeof___impl(UnpicklerObject *self); - -static PyObject * -_pickle_Unpickler___sizeof__(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = _pickle_Unpickler___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_pickle_Unpickler___init____doc__, + return_value = _pickle_Unpickler_find_class_impl(self, module_name, global_name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_Unpickler___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns size in memory, in bytes."); + +#define _PICKLE_UNPICKLER___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_pickle_Unpickler___sizeof__, METH_NOARGS, _pickle_Unpickler___sizeof____doc__}, + +static Py_ssize_t +_pickle_Unpickler___sizeof___impl(UnpicklerObject *self); + +static PyObject * +_pickle_Unpickler___sizeof__(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _pickle_Unpickler___sizeof___impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_Unpickler___init____doc__, "Unpickler(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\',\n" " buffers=())\n" -"--\n" -"\n" -"This takes a binary file for reading a pickle data stream.\n" -"\n" -"The protocol version of the pickle is detected automatically, so no\n" -"protocol argument is needed. Bytes past the pickled object\'s\n" -"representation are ignored.\n" -"\n" -"The argument *file* must have two methods, a read() method that takes\n" -"an integer argument, and a readline() method that requires no\n" -"arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, an io.BytesIO object, or any\n" -"other custom object that meets this interface.\n" -"\n" -"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" -"which are used to control compatibility support for pickle stream\n" -"generated by Python 2. If *fix_imports* is True, pickle will try to\n" -"map the old Python 2 names to the new names used in Python 3. The\n" -"*encoding* and *errors* tell pickle how to decode 8-bit string\n" -"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" -"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" -"string instances as bytes objects."); - -static int -_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, - int fix_imports, const char *encoding, +"--\n" +"\n" +"This takes a binary file for reading a pickle data stream.\n" +"\n" +"The protocol version of the pickle is detected automatically, so no\n" +"protocol argument is needed. Bytes past the pickled object\'s\n" +"representation are ignored.\n" +"\n" +"The argument *file* must have two methods, a read() method that takes\n" +"an integer argument, and a readline() method that requires no\n" +"arguments. Both methods should return bytes. Thus *file* can be a\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" +"other custom object that meets this interface.\n" +"\n" +"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" +"which are used to control compatibility support for pickle stream\n" +"generated by Python 2. If *fix_imports* is True, pickle will try to\n" +"map the old Python 2 names to the new names used in Python 3. The\n" +"*encoding* and *errors* tell pickle how to decode 8-bit string\n" +"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" +"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" +"string instances as bytes objects."); + +static int +_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, + int fix_imports, const char *encoding, const char *errors, PyObject *buffers); - -static int -_pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; + +static int +_pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "Unpickler", 0}; PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - PyObject *file; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; + PyObject *file; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; PyObject *buffers = NULL; - + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } file = fastargs[0]; if (!noptargs) { goto skip_optional_kwonly; @@ -394,123 +394,123 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) buffers = fastargs[4]; skip_optional_kwonly: return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors, buffers); - -exit: - return return_value; -} - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__, -"clear($self, /)\n" -"--\n" -"\n" -"Remove all items from memo."); - -#define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \ - {"clear", (PyCFunction)_pickle_UnpicklerMemoProxy_clear, METH_NOARGS, _pickle_UnpicklerMemoProxy_clear__doc__}, - -static PyObject * -_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self); - -static PyObject * -_pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _pickle_UnpicklerMemoProxy_clear_impl(self); -} - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Copy the memo to a new object."); - -#define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \ - {"copy", (PyCFunction)_pickle_UnpicklerMemoProxy_copy, METH_NOARGS, _pickle_UnpicklerMemoProxy_copy__doc__}, - -static PyObject * -_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self); - -static PyObject * -_pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _pickle_UnpicklerMemoProxy_copy_impl(self); -} - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__, -"__reduce__($self, /)\n" -"--\n" -"\n" -"Implement pickling support."); - -#define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)_pickle_UnpicklerMemoProxy___reduce__, METH_NOARGS, _pickle_UnpicklerMemoProxy___reduce____doc__}, - -static PyObject * -_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self); - -static PyObject * -_pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _pickle_UnpicklerMemoProxy___reduce___impl(self); -} - -PyDoc_STRVAR(_pickle_dump__doc__, + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from memo."); + +#define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \ + {"clear", (PyCFunction)_pickle_UnpicklerMemoProxy_clear, METH_NOARGS, _pickle_UnpicklerMemoProxy_clear__doc__}, + +static PyObject * +_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self); + +static PyObject * +_pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_UnpicklerMemoProxy_clear_impl(self); +} + +PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Copy the memo to a new object."); + +#define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \ + {"copy", (PyCFunction)_pickle_UnpicklerMemoProxy_copy, METH_NOARGS, _pickle_UnpicklerMemoProxy_copy__doc__}, + +static PyObject * +_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self); + +static PyObject * +_pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_UnpicklerMemoProxy_copy_impl(self); +} + +PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Implement pickling support."); + +#define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)_pickle_UnpicklerMemoProxy___reduce__, METH_NOARGS, _pickle_UnpicklerMemoProxy___reduce____doc__}, + +static PyObject * +_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self); + +static PyObject * +_pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_UnpicklerMemoProxy___reduce___impl(self); +} + +PyDoc_STRVAR(_pickle_dump__doc__, "dump($module, /, obj, file, protocol=None, *, fix_imports=True,\n" " buffer_callback=None)\n" -"--\n" -"\n" -"Write a pickled representation of obj to the open file object file.\n" -"\n" -"This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may\n" -"be more efficient.\n" -"\n" -"The optional *protocol* argument tells the pickler to use the given\n" +"--\n" +"\n" +"Write a pickled representation of obj to the open file object file.\n" +"\n" +"This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may\n" +"be more efficient.\n" +"\n" +"The optional *protocol* argument tells the pickler to use the given\n" "protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default\n" "protocol is 4. It was introduced in Python 3.4, and is incompatible\n" "with previous versions.\n" -"\n" -"Specifying a negative protocol version selects the highest protocol\n" -"version supported. The higher the protocol used, the more recent the\n" -"version of Python needed to read the pickle produced.\n" -"\n" -"The *file* argument must have a write() method that accepts a single\n" -"bytes argument. It can thus be a file object opened for binary\n" -"writing, an io.BytesIO instance, or any other custom object that meets\n" -"this interface.\n" -"\n" -"If *fix_imports* is True and protocol is less than 3, pickle will try\n" -"to map the new Python 3 names to the old module names used in Python\n" +"\n" +"Specifying a negative protocol version selects the highest protocol\n" +"version supported. The higher the protocol used, the more recent the\n" +"version of Python needed to read the pickle produced.\n" +"\n" +"The *file* argument must have a write() method that accepts a single\n" +"bytes argument. It can thus be a file object opened for binary\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" +"this interface.\n" +"\n" +"If *fix_imports* is True and protocol is less than 3, pickle will try\n" +"to map the new Python 3 names to the old module names used in Python\n" "2, so that the pickle data stream is readable with Python 2.\n" "\n" "If *buffer_callback* is None (the default), buffer views are serialized\n" "into *file* as part of the pickle stream. It is an error if\n" "*buffer_callback* is not None and *protocol* is None or smaller than 5."); - -#define _PICKLE_DUMP_METHODDEF \ + +#define _PICKLE_DUMP_METHODDEF \ {"dump", (PyCFunction)(void(*)(void))_pickle_dump, METH_FASTCALL|METH_KEYWORDS, _pickle_dump__doc__}, - -static PyObject * -_pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, + +static PyObject * +_pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports, PyObject *buffer_callback); - -static PyObject * -_pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"obj", "file", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "dump", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - PyObject *obj; - PyObject *file; + PyObject *obj; + PyObject *file; PyObject *protocol = Py_None; - int fix_imports = 1; + int fix_imports = 1; PyObject *buffer_callback = Py_None; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } obj = args[0]; file = args[1]; if (!noptargs) { @@ -538,59 +538,59 @@ skip_optional_pos: buffer_callback = args[4]; skip_optional_kwonly: return_value = _pickle_dump_impl(module, obj, file, protocol, fix_imports, buffer_callback); - -exit: - return return_value; -} - -PyDoc_STRVAR(_pickle_dumps__doc__, + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_dumps__doc__, "dumps($module, /, obj, protocol=None, *, fix_imports=True,\n" " buffer_callback=None)\n" -"--\n" -"\n" -"Return the pickled representation of the object as a bytes object.\n" -"\n" -"The optional *protocol* argument tells the pickler to use the given\n" +"--\n" +"\n" +"Return the pickled representation of the object as a bytes object.\n" +"\n" +"The optional *protocol* argument tells the pickler to use the given\n" "protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default\n" "protocol is 4. It was introduced in Python 3.4, and is incompatible\n" "with previous versions.\n" -"\n" -"Specifying a negative protocol version selects the highest protocol\n" -"version supported. The higher the protocol used, the more recent the\n" -"version of Python needed to read the pickle produced.\n" -"\n" -"If *fix_imports* is True and *protocol* is less than 3, pickle will\n" -"try to map the new Python 3 names to the old module names used in\n" +"\n" +"Specifying a negative protocol version selects the highest protocol\n" +"version supported. The higher the protocol used, the more recent the\n" +"version of Python needed to read the pickle produced.\n" +"\n" +"If *fix_imports* is True and *protocol* is less than 3, pickle will\n" +"try to map the new Python 3 names to the old module names used in\n" "Python 2, so that the pickle data stream is readable with Python 2.\n" "\n" "If *buffer_callback* is None (the default), buffer views are serialized\n" "into *file* as part of the pickle stream. It is an error if\n" "*buffer_callback* is not None and *protocol* is None or smaller than 5."); - -#define _PICKLE_DUMPS_METHODDEF \ + +#define _PICKLE_DUMPS_METHODDEF \ {"dumps", (PyCFunction)(void(*)(void))_pickle_dumps, METH_FASTCALL|METH_KEYWORDS, _pickle_dumps__doc__}, - -static PyObject * -_pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, + +static PyObject * +_pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, int fix_imports, PyObject *buffer_callback); - -static PyObject * -_pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"obj", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "dumps", 0}; PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *obj; + PyObject *obj; PyObject *protocol = Py_None; - int fix_imports = 1; + int fix_imports = 1; PyObject *buffer_callback = Py_None; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } obj = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -617,66 +617,66 @@ skip_optional_pos: buffer_callback = args[3]; skip_optional_kwonly: return_value = _pickle_dumps_impl(module, obj, protocol, fix_imports, buffer_callback); - -exit: - return return_value; -} - -PyDoc_STRVAR(_pickle_load__doc__, -"load($module, /, file, *, fix_imports=True, encoding=\'ASCII\',\n" + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_load__doc__, +"load($module, /, file, *, fix_imports=True, encoding=\'ASCII\',\n" " errors=\'strict\', buffers=())\n" -"--\n" -"\n" -"Read and return an object from the pickle data stored in a file.\n" -"\n" -"This is equivalent to ``Unpickler(file).load()``, but may be more\n" -"efficient.\n" -"\n" -"The protocol version of the pickle is detected automatically, so no\n" -"protocol argument is needed. Bytes past the pickled object\'s\n" -"representation are ignored.\n" -"\n" -"The argument *file* must have two methods, a read() method that takes\n" -"an integer argument, and a readline() method that requires no\n" -"arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, an io.BytesIO object, or any\n" -"other custom object that meets this interface.\n" -"\n" -"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" -"which are used to control compatibility support for pickle stream\n" -"generated by Python 2. If *fix_imports* is True, pickle will try to\n" -"map the old Python 2 names to the new names used in Python 3. The\n" -"*encoding* and *errors* tell pickle how to decode 8-bit string\n" -"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" -"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" -"string instances as bytes objects."); - -#define _PICKLE_LOAD_METHODDEF \ +"--\n" +"\n" +"Read and return an object from the pickle data stored in a file.\n" +"\n" +"This is equivalent to ``Unpickler(file).load()``, but may be more\n" +"efficient.\n" +"\n" +"The protocol version of the pickle is detected automatically, so no\n" +"protocol argument is needed. Bytes past the pickled object\'s\n" +"representation are ignored.\n" +"\n" +"The argument *file* must have two methods, a read() method that takes\n" +"an integer argument, and a readline() method that requires no\n" +"arguments. Both methods should return bytes. Thus *file* can be a\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" +"other custom object that meets this interface.\n" +"\n" +"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" +"which are used to control compatibility support for pickle stream\n" +"generated by Python 2. If *fix_imports* is True, pickle will try to\n" +"map the old Python 2 names to the new names used in Python 3. The\n" +"*encoding* and *errors* tell pickle how to decode 8-bit string\n" +"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" +"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" +"string instances as bytes objects."); + +#define _PICKLE_LOAD_METHODDEF \ {"load", (PyCFunction)(void(*)(void))_pickle_load, METH_FASTCALL|METH_KEYWORDS, _pickle_load__doc__}, - -static PyObject * -_pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, + +static PyObject * +_pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, const char *encoding, const char *errors, PyObject *buffers); - -static PyObject * -_pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "load", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *file; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; + PyObject *file; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; PyObject *buffers = NULL; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } file = args[0]; if (!noptargs) { goto skip_optional_kwonly; @@ -729,57 +729,57 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject buffers = args[4]; skip_optional_kwonly: return_value = _pickle_load_impl(module, file, fix_imports, encoding, errors, buffers); - -exit: - return return_value; -} - -PyDoc_STRVAR(_pickle_loads__doc__, + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_loads__doc__, "loads($module, data, /, *, fix_imports=True, encoding=\'ASCII\',\n" " errors=\'strict\', buffers=())\n" -"--\n" -"\n" -"Read and return an object from the given pickle data.\n" -"\n" -"The protocol version of the pickle is detected automatically, so no\n" -"protocol argument is needed. Bytes past the pickled object\'s\n" -"representation are ignored.\n" -"\n" -"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" -"which are used to control compatibility support for pickle stream\n" -"generated by Python 2. If *fix_imports* is True, pickle will try to\n" -"map the old Python 2 names to the new names used in Python 3. The\n" -"*encoding* and *errors* tell pickle how to decode 8-bit string\n" -"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" -"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" -"string instances as bytes objects."); - -#define _PICKLE_LOADS_METHODDEF \ +"--\n" +"\n" +"Read and return an object from the given pickle data.\n" +"\n" +"The protocol version of the pickle is detected automatically, so no\n" +"protocol argument is needed. Bytes past the pickled object\'s\n" +"representation are ignored.\n" +"\n" +"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" +"which are used to control compatibility support for pickle stream\n" +"generated by Python 2. If *fix_imports* is True, pickle will try to\n" +"map the old Python 2 names to the new names used in Python 3. The\n" +"*encoding* and *errors* tell pickle how to decode 8-bit string\n" +"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" +"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" +"string instances as bytes objects."); + +#define _PICKLE_LOADS_METHODDEF \ {"loads", (PyCFunction)(void(*)(void))_pickle_loads, METH_FASTCALL|METH_KEYWORDS, _pickle_loads__doc__}, - -static PyObject * -_pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, + +static PyObject * +_pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, const char *encoding, const char *errors, PyObject *buffers); - -static PyObject * -_pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "loads", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *data; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; + PyObject *data; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; PyObject *buffers = NULL; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } data = args[0]; if (!noptargs) { goto skip_optional_kwonly; @@ -832,8 +832,8 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec buffers = args[4]; skip_optional_kwonly: return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors, buffers); - -exit: - return return_value; -} + +exit: + return return_value; +} /*[clinic end generated code: output=324aad69644beda2 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_queuemodule.c.h b/contrib/tools/python3/src/Modules/clinic/_queuemodule.c.h index c25eacf08bc..afcf069209e 100644 --- a/contrib/tools/python3/src/Modules/clinic/_queuemodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_queuemodule.c.h @@ -1,67 +1,67 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(simplequeue_new__doc__, -"SimpleQueue()\n" -"--\n" -"\n" -"Simple, unbounded, reentrant FIFO queue."); - -static PyObject * -simplequeue_new_impl(PyTypeObject *type); - -static PyObject * -simplequeue_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - - if ((type == &PySimpleQueueType) && - !_PyArg_NoPositional("SimpleQueue", args)) { - goto exit; - } - if ((type == &PySimpleQueueType) && - !_PyArg_NoKeywords("SimpleQueue", kwargs)) { - goto exit; - } - return_value = simplequeue_new_impl(type); - -exit: - return return_value; -} - -PyDoc_STRVAR(_queue_SimpleQueue_put__doc__, -"put($self, /, item, block=True, timeout=None)\n" -"--\n" -"\n" -"Put the item on the queue.\n" -"\n" -"The optional \'block\' and \'timeout\' arguments are ignored, as this method\n" -"never blocks. They are provided for compatibility with the Queue class."); - -#define _QUEUE_SIMPLEQUEUE_PUT_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(simplequeue_new__doc__, +"SimpleQueue()\n" +"--\n" +"\n" +"Simple, unbounded, reentrant FIFO queue."); + +static PyObject * +simplequeue_new_impl(PyTypeObject *type); + +static PyObject * +simplequeue_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + + if ((type == &PySimpleQueueType) && + !_PyArg_NoPositional("SimpleQueue", args)) { + goto exit; + } + if ((type == &PySimpleQueueType) && + !_PyArg_NoKeywords("SimpleQueue", kwargs)) { + goto exit; + } + return_value = simplequeue_new_impl(type); + +exit: + return return_value; +} + +PyDoc_STRVAR(_queue_SimpleQueue_put__doc__, +"put($self, /, item, block=True, timeout=None)\n" +"--\n" +"\n" +"Put the item on the queue.\n" +"\n" +"The optional \'block\' and \'timeout\' arguments are ignored, as this method\n" +"never blocks. They are provided for compatibility with the Queue class."); + +#define _QUEUE_SIMPLEQUEUE_PUT_METHODDEF \ {"put", (PyCFunction)(void(*)(void))_queue_SimpleQueue_put, METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_put__doc__}, - -static PyObject * -_queue_SimpleQueue_put_impl(simplequeueobject *self, PyObject *item, - int block, PyObject *timeout); - -static PyObject * -_queue_SimpleQueue_put(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"item", "block", "timeout", NULL}; + +static PyObject * +_queue_SimpleQueue_put_impl(simplequeueobject *self, PyObject *item, + int block, PyObject *timeout); + +static PyObject * +_queue_SimpleQueue_put(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"item", "block", "timeout", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "put", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *item; - int block = 1; - PyObject *timeout = Py_None; - + PyObject *item; + int block = 1; + PyObject *timeout = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } item = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -77,83 +77,83 @@ _queue_SimpleQueue_put(simplequeueobject *self, PyObject *const *args, Py_ssize_ } timeout = args[2]; skip_optional_pos: - return_value = _queue_SimpleQueue_put_impl(self, item, block, timeout); - -exit: - return return_value; -} - -PyDoc_STRVAR(_queue_SimpleQueue_put_nowait__doc__, -"put_nowait($self, /, item)\n" -"--\n" -"\n" -"Put an item into the queue without blocking.\n" -"\n" -"This is exactly equivalent to `put(item)` and is only provided\n" -"for compatibility with the Queue class."); - -#define _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF \ + return_value = _queue_SimpleQueue_put_impl(self, item, block, timeout); + +exit: + return return_value; +} + +PyDoc_STRVAR(_queue_SimpleQueue_put_nowait__doc__, +"put_nowait($self, /, item)\n" +"--\n" +"\n" +"Put an item into the queue without blocking.\n" +"\n" +"This is exactly equivalent to `put(item)` and is only provided\n" +"for compatibility with the Queue class."); + +#define _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF \ {"put_nowait", (PyCFunction)(void(*)(void))_queue_SimpleQueue_put_nowait, METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_put_nowait__doc__}, - -static PyObject * -_queue_SimpleQueue_put_nowait_impl(simplequeueobject *self, PyObject *item); - -static PyObject * -_queue_SimpleQueue_put_nowait(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"item", NULL}; + +static PyObject * +_queue_SimpleQueue_put_nowait_impl(simplequeueobject *self, PyObject *item); + +static PyObject * +_queue_SimpleQueue_put_nowait(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"item", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "put_nowait", 0}; PyObject *argsbuf[1]; - PyObject *item; - + PyObject *item; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } item = args[0]; - return_value = _queue_SimpleQueue_put_nowait_impl(self, item); - -exit: - return return_value; -} - -PyDoc_STRVAR(_queue_SimpleQueue_get__doc__, -"get($self, /, block=True, timeout=None)\n" -"--\n" -"\n" -"Remove and return an item from the queue.\n" -"\n" -"If optional args \'block\' is true and \'timeout\' is None (the default),\n" -"block if necessary until an item is available. If \'timeout\' is\n" -"a non-negative number, it blocks at most \'timeout\' seconds and raises\n" -"the Empty exception if no item was available within that time.\n" -"Otherwise (\'block\' is false), return an item if one is immediately\n" -"available, else raise the Empty exception (\'timeout\' is ignored\n" -"in that case)."); - -#define _QUEUE_SIMPLEQUEUE_GET_METHODDEF \ + return_value = _queue_SimpleQueue_put_nowait_impl(self, item); + +exit: + return return_value; +} + +PyDoc_STRVAR(_queue_SimpleQueue_get__doc__, +"get($self, /, block=True, timeout=None)\n" +"--\n" +"\n" +"Remove and return an item from the queue.\n" +"\n" +"If optional args \'block\' is true and \'timeout\' is None (the default),\n" +"block if necessary until an item is available. If \'timeout\' is\n" +"a non-negative number, it blocks at most \'timeout\' seconds and raises\n" +"the Empty exception if no item was available within that time.\n" +"Otherwise (\'block\' is false), return an item if one is immediately\n" +"available, else raise the Empty exception (\'timeout\' is ignored\n" +"in that case)."); + +#define _QUEUE_SIMPLEQUEUE_GET_METHODDEF \ {"get", (PyCFunction)(void(*)(void))_queue_SimpleQueue_get, METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_get__doc__}, - -static PyObject * -_queue_SimpleQueue_get_impl(simplequeueobject *self, int block, - PyObject *timeout); - -static PyObject * -_queue_SimpleQueue_get(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"block", "timeout", NULL}; + +static PyObject * +_queue_SimpleQueue_get_impl(simplequeueobject *self, int block, + PyObject *timeout); + +static PyObject * +_queue_SimpleQueue_get(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"block", "timeout", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - int block = 1; - PyObject *timeout = Py_None; - + int block = 1; + PyObject *timeout = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -168,86 +168,86 @@ _queue_SimpleQueue_get(simplequeueobject *self, PyObject *const *args, Py_ssize_ } timeout = args[1]; skip_optional_pos: - return_value = _queue_SimpleQueue_get_impl(self, block, timeout); - -exit: - return return_value; -} - -PyDoc_STRVAR(_queue_SimpleQueue_get_nowait__doc__, -"get_nowait($self, /)\n" -"--\n" -"\n" -"Remove and return an item from the queue without blocking.\n" -"\n" -"Only get an item if one is immediately available. Otherwise\n" -"raise the Empty exception."); - -#define _QUEUE_SIMPLEQUEUE_GET_NOWAIT_METHODDEF \ - {"get_nowait", (PyCFunction)_queue_SimpleQueue_get_nowait, METH_NOARGS, _queue_SimpleQueue_get_nowait__doc__}, - -static PyObject * -_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self); - -static PyObject * -_queue_SimpleQueue_get_nowait(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) -{ - return _queue_SimpleQueue_get_nowait_impl(self); -} - -PyDoc_STRVAR(_queue_SimpleQueue_empty__doc__, -"empty($self, /)\n" -"--\n" -"\n" -"Return True if the queue is empty, False otherwise (not reliable!)."); - -#define _QUEUE_SIMPLEQUEUE_EMPTY_METHODDEF \ - {"empty", (PyCFunction)_queue_SimpleQueue_empty, METH_NOARGS, _queue_SimpleQueue_empty__doc__}, - -static int -_queue_SimpleQueue_empty_impl(simplequeueobject *self); - -static PyObject * -_queue_SimpleQueue_empty(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = _queue_SimpleQueue_empty_impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_queue_SimpleQueue_qsize__doc__, -"qsize($self, /)\n" -"--\n" -"\n" -"Return the approximate size of the queue (not reliable!)."); - -#define _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF \ - {"qsize", (PyCFunction)_queue_SimpleQueue_qsize, METH_NOARGS, _queue_SimpleQueue_qsize__doc__}, - -static Py_ssize_t -_queue_SimpleQueue_qsize_impl(simplequeueobject *self); - -static PyObject * -_queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = _queue_SimpleQueue_qsize_impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} + return_value = _queue_SimpleQueue_get_impl(self, block, timeout); + +exit: + return return_value; +} + +PyDoc_STRVAR(_queue_SimpleQueue_get_nowait__doc__, +"get_nowait($self, /)\n" +"--\n" +"\n" +"Remove and return an item from the queue without blocking.\n" +"\n" +"Only get an item if one is immediately available. Otherwise\n" +"raise the Empty exception."); + +#define _QUEUE_SIMPLEQUEUE_GET_NOWAIT_METHODDEF \ + {"get_nowait", (PyCFunction)_queue_SimpleQueue_get_nowait, METH_NOARGS, _queue_SimpleQueue_get_nowait__doc__}, + +static PyObject * +_queue_SimpleQueue_get_nowait_impl(simplequeueobject *self); + +static PyObject * +_queue_SimpleQueue_get_nowait(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _queue_SimpleQueue_get_nowait_impl(self); +} + +PyDoc_STRVAR(_queue_SimpleQueue_empty__doc__, +"empty($self, /)\n" +"--\n" +"\n" +"Return True if the queue is empty, False otherwise (not reliable!)."); + +#define _QUEUE_SIMPLEQUEUE_EMPTY_METHODDEF \ + {"empty", (PyCFunction)_queue_SimpleQueue_empty, METH_NOARGS, _queue_SimpleQueue_empty__doc__}, + +static int +_queue_SimpleQueue_empty_impl(simplequeueobject *self); + +static PyObject * +_queue_SimpleQueue_empty(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _queue_SimpleQueue_empty_impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_queue_SimpleQueue_qsize__doc__, +"qsize($self, /)\n" +"--\n" +"\n" +"Return the approximate size of the queue (not reliable!)."); + +#define _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF \ + {"qsize", (PyCFunction)_queue_SimpleQueue_qsize, METH_NOARGS, _queue_SimpleQueue_qsize__doc__}, + +static Py_ssize_t +_queue_SimpleQueue_qsize_impl(simplequeueobject *self); + +static PyObject * +_queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _queue_SimpleQueue_qsize_impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} /*[clinic end generated code: output=b4717e2974cbc909 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_sre.c.h b/contrib/tools/python3/src/Modules/clinic/_sre.c.h index d398a8504ba..d213fdb9e0e 100644 --- a/contrib/tools/python3/src/Modules/clinic/_sre.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_sre.c.h @@ -1,211 +1,211 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_sre_getcodesize__doc__, -"getcodesize($module, /)\n" -"--\n" -"\n"); - -#define _SRE_GETCODESIZE_METHODDEF \ - {"getcodesize", (PyCFunction)_sre_getcodesize, METH_NOARGS, _sre_getcodesize__doc__}, - -static int -_sre_getcodesize_impl(PyObject *module); - -static PyObject * -_sre_getcodesize(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = _sre_getcodesize_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_ascii_iscased__doc__, -"ascii_iscased($module, character, /)\n" -"--\n" -"\n"); - -#define _SRE_ASCII_ISCASED_METHODDEF \ - {"ascii_iscased", (PyCFunction)_sre_ascii_iscased, METH_O, _sre_ascii_iscased__doc__}, - -static int -_sre_ascii_iscased_impl(PyObject *module, int character); - -static PyObject * -_sre_ascii_iscased(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int character; - int _return_value; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_sre_getcodesize__doc__, +"getcodesize($module, /)\n" +"--\n" +"\n"); + +#define _SRE_GETCODESIZE_METHODDEF \ + {"getcodesize", (PyCFunction)_sre_getcodesize, METH_NOARGS, _sre_getcodesize__doc__}, + +static int +_sre_getcodesize_impl(PyObject *module); + +static PyObject * +_sre_getcodesize(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _sre_getcodesize_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_ascii_iscased__doc__, +"ascii_iscased($module, character, /)\n" +"--\n" +"\n"); + +#define _SRE_ASCII_ISCASED_METHODDEF \ + {"ascii_iscased", (PyCFunction)_sre_ascii_iscased, METH_O, _sre_ascii_iscased__doc__}, + +static int +_sre_ascii_iscased_impl(PyObject *module, int character); + +static PyObject * +_sre_ascii_iscased(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int character; + int _return_value; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } character = _PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; } - _return_value = _sre_ascii_iscased_impl(module, character); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_unicode_iscased__doc__, -"unicode_iscased($module, character, /)\n" -"--\n" -"\n"); - -#define _SRE_UNICODE_ISCASED_METHODDEF \ - {"unicode_iscased", (PyCFunction)_sre_unicode_iscased, METH_O, _sre_unicode_iscased__doc__}, - -static int -_sre_unicode_iscased_impl(PyObject *module, int character); - -static PyObject * -_sre_unicode_iscased(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int character; - int _return_value; - + _return_value = _sre_ascii_iscased_impl(module, character); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_unicode_iscased__doc__, +"unicode_iscased($module, character, /)\n" +"--\n" +"\n"); + +#define _SRE_UNICODE_ISCASED_METHODDEF \ + {"unicode_iscased", (PyCFunction)_sre_unicode_iscased, METH_O, _sre_unicode_iscased__doc__}, + +static int +_sre_unicode_iscased_impl(PyObject *module, int character); + +static PyObject * +_sre_unicode_iscased(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int character; + int _return_value; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } character = _PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; } - _return_value = _sre_unicode_iscased_impl(module, character); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_ascii_tolower__doc__, -"ascii_tolower($module, character, /)\n" -"--\n" -"\n"); - -#define _SRE_ASCII_TOLOWER_METHODDEF \ - {"ascii_tolower", (PyCFunction)_sre_ascii_tolower, METH_O, _sre_ascii_tolower__doc__}, - -static int -_sre_ascii_tolower_impl(PyObject *module, int character); - -static PyObject * -_sre_ascii_tolower(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int character; - int _return_value; - + _return_value = _sre_unicode_iscased_impl(module, character); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_ascii_tolower__doc__, +"ascii_tolower($module, character, /)\n" +"--\n" +"\n"); + +#define _SRE_ASCII_TOLOWER_METHODDEF \ + {"ascii_tolower", (PyCFunction)_sre_ascii_tolower, METH_O, _sre_ascii_tolower__doc__}, + +static int +_sre_ascii_tolower_impl(PyObject *module, int character); + +static PyObject * +_sre_ascii_tolower(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int character; + int _return_value; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } character = _PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; } - _return_value = _sre_ascii_tolower_impl(module, character); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_unicode_tolower__doc__, -"unicode_tolower($module, character, /)\n" -"--\n" -"\n"); - -#define _SRE_UNICODE_TOLOWER_METHODDEF \ - {"unicode_tolower", (PyCFunction)_sre_unicode_tolower, METH_O, _sre_unicode_tolower__doc__}, - -static int -_sre_unicode_tolower_impl(PyObject *module, int character); - -static PyObject * -_sre_unicode_tolower(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int character; - int _return_value; - + _return_value = _sre_ascii_tolower_impl(module, character); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_unicode_tolower__doc__, +"unicode_tolower($module, character, /)\n" +"--\n" +"\n"); + +#define _SRE_UNICODE_TOLOWER_METHODDEF \ + {"unicode_tolower", (PyCFunction)_sre_unicode_tolower, METH_O, _sre_unicode_tolower__doc__}, + +static int +_sre_unicode_tolower_impl(PyObject *module, int character); + +static PyObject * +_sre_unicode_tolower(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int character; + int _return_value; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } character = _PyLong_AsInt(arg); if (character == -1 && PyErr_Occurred()) { goto exit; } - _return_value = _sre_unicode_tolower_impl(module, character); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_match__doc__, -"match($self, /, string, pos=0, endpos=sys.maxsize)\n" -"--\n" -"\n" -"Matches zero or more characters at the beginning of the string."); - -#define _SRE_SRE_PATTERN_MATCH_METHODDEF \ + _return_value = _sre_unicode_tolower_impl(module, character); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_match__doc__, +"match($self, /, string, pos=0, endpos=sys.maxsize)\n" +"--\n" +"\n" +"Matches zero or more characters at the beginning of the string."); + +#define _SRE_SRE_PATTERN_MATCH_METHODDEF \ {"match", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_match, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_match__doc__}, - -static PyObject * -_sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); - -static PyObject * -_sre_SRE_Pattern_match(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; + +static PyObject * +_sre_SRE_Pattern_match_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos); + +static PyObject * +_sre_SRE_Pattern_match(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "match", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *string; - Py_ssize_t pos = 0; - Py_ssize_t endpos = PY_SSIZE_T_MAX; - + PyObject *string; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } string = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -250,41 +250,41 @@ _sre_SRE_Pattern_match(PatternObject *self, PyObject *const *args, Py_ssize_t na endpos = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_match_impl(self, string, pos, endpos); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_fullmatch__doc__, -"fullmatch($self, /, string, pos=0, endpos=sys.maxsize)\n" -"--\n" -"\n" -"Matches against all of the string."); - -#define _SRE_SRE_PATTERN_FULLMATCH_METHODDEF \ + return_value = _sre_SRE_Pattern_match_impl(self, string, pos, endpos); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_fullmatch__doc__, +"fullmatch($self, /, string, pos=0, endpos=sys.maxsize)\n" +"--\n" +"\n" +"Matches against all of the string."); + +#define _SRE_SRE_PATTERN_FULLMATCH_METHODDEF \ {"fullmatch", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_fullmatch, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_fullmatch__doc__}, - -static PyObject * -_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); - -static PyObject * -_sre_SRE_Pattern_fullmatch(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; + +static PyObject * +_sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos); + +static PyObject * +_sre_SRE_Pattern_fullmatch(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "fullmatch", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *string; - Py_ssize_t pos = 0; - Py_ssize_t endpos = PY_SSIZE_T_MAX; - + PyObject *string; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } string = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -329,43 +329,43 @@ _sre_SRE_Pattern_fullmatch(PatternObject *self, PyObject *const *args, Py_ssize_ endpos = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_fullmatch_impl(self, string, pos, endpos); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_search__doc__, -"search($self, /, string, pos=0, endpos=sys.maxsize)\n" -"--\n" -"\n" -"Scan through string looking for a match, and return a corresponding match object instance.\n" -"\n" -"Return None if no position in the string matches."); - -#define _SRE_SRE_PATTERN_SEARCH_METHODDEF \ + return_value = _sre_SRE_Pattern_fullmatch_impl(self, string, pos, endpos); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_search__doc__, +"search($self, /, string, pos=0, endpos=sys.maxsize)\n" +"--\n" +"\n" +"Scan through string looking for a match, and return a corresponding match object instance.\n" +"\n" +"Return None if no position in the string matches."); + +#define _SRE_SRE_PATTERN_SEARCH_METHODDEF \ {"search", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_search, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_search__doc__}, - -static PyObject * -_sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); - -static PyObject * -_sre_SRE_Pattern_search(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; + +static PyObject * +_sre_SRE_Pattern_search_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos); + +static PyObject * +_sre_SRE_Pattern_search(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "search", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *string; - Py_ssize_t pos = 0; - Py_ssize_t endpos = PY_SSIZE_T_MAX; - + PyObject *string; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } string = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -410,41 +410,41 @@ _sre_SRE_Pattern_search(PatternObject *self, PyObject *const *args, Py_ssize_t n endpos = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_search_impl(self, string, pos, endpos); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_findall__doc__, -"findall($self, /, string, pos=0, endpos=sys.maxsize)\n" -"--\n" -"\n" -"Return a list of all non-overlapping matches of pattern in string."); - -#define _SRE_SRE_PATTERN_FINDALL_METHODDEF \ + return_value = _sre_SRE_Pattern_search_impl(self, string, pos, endpos); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_findall__doc__, +"findall($self, /, string, pos=0, endpos=sys.maxsize)\n" +"--\n" +"\n" +"Return a list of all non-overlapping matches of pattern in string."); + +#define _SRE_SRE_PATTERN_FINDALL_METHODDEF \ {"findall", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_findall, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_findall__doc__}, - -static PyObject * -_sre_SRE_Pattern_findall_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); - -static PyObject * -_sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; + +static PyObject * +_sre_SRE_Pattern_findall_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos); + +static PyObject * +_sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "findall", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *string; - Py_ssize_t pos = 0; - Py_ssize_t endpos = PY_SSIZE_T_MAX; - + PyObject *string; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } string = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -489,43 +489,43 @@ _sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t endpos = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_findall_impl(self, string, pos, endpos); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_finditer__doc__, -"finditer($self, /, string, pos=0, endpos=sys.maxsize)\n" -"--\n" -"\n" -"Return an iterator over all non-overlapping matches for the RE pattern in string.\n" -"\n" -"For each match, the iterator returns a match object."); - -#define _SRE_SRE_PATTERN_FINDITER_METHODDEF \ + return_value = _sre_SRE_Pattern_findall_impl(self, string, pos, endpos); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_finditer__doc__, +"finditer($self, /, string, pos=0, endpos=sys.maxsize)\n" +"--\n" +"\n" +"Return an iterator over all non-overlapping matches for the RE pattern in string.\n" +"\n" +"For each match, the iterator returns a match object."); + +#define _SRE_SRE_PATTERN_FINDITER_METHODDEF \ {"finditer", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_finditer, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_finditer__doc__}, - -static PyObject * -_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); - -static PyObject * -_sre_SRE_Pattern_finditer(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; + +static PyObject * +_sre_SRE_Pattern_finditer_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos); + +static PyObject * +_sre_SRE_Pattern_finditer(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "finditer", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *string; - Py_ssize_t pos = 0; - Py_ssize_t endpos = PY_SSIZE_T_MAX; - + PyObject *string; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } string = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -570,40 +570,40 @@ _sre_SRE_Pattern_finditer(PatternObject *self, PyObject *const *args, Py_ssize_t endpos = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_finditer_impl(self, string, pos, endpos); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_scanner__doc__, -"scanner($self, /, string, pos=0, endpos=sys.maxsize)\n" -"--\n" -"\n"); - -#define _SRE_SRE_PATTERN_SCANNER_METHODDEF \ + return_value = _sre_SRE_Pattern_finditer_impl(self, string, pos, endpos); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_scanner__doc__, +"scanner($self, /, string, pos=0, endpos=sys.maxsize)\n" +"--\n" +"\n"); + +#define _SRE_SRE_PATTERN_SCANNER_METHODDEF \ {"scanner", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_scanner, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_scanner__doc__}, - -static PyObject * -_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyObject *string, - Py_ssize_t pos, Py_ssize_t endpos); - -static PyObject * -_sre_SRE_Pattern_scanner(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; + +static PyObject * +_sre_SRE_Pattern_scanner_impl(PatternObject *self, PyObject *string, + Py_ssize_t pos, Py_ssize_t endpos); + +static PyObject * +_sre_SRE_Pattern_scanner(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "scanner", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *string; - Py_ssize_t pos = 0; - Py_ssize_t endpos = PY_SSIZE_T_MAX; - + PyObject *string; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } string = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -648,40 +648,40 @@ _sre_SRE_Pattern_scanner(PatternObject *self, PyObject *const *args, Py_ssize_t endpos = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_scanner_impl(self, string, pos, endpos); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_split__doc__, -"split($self, /, string, maxsplit=0)\n" -"--\n" -"\n" -"Split string by the occurrences of pattern."); - -#define _SRE_SRE_PATTERN_SPLIT_METHODDEF \ + return_value = _sre_SRE_Pattern_scanner_impl(self, string, pos, endpos); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_split__doc__, +"split($self, /, string, maxsplit=0)\n" +"--\n" +"\n" +"Split string by the occurrences of pattern."); + +#define _SRE_SRE_PATTERN_SPLIT_METHODDEF \ {"split", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_split, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_split__doc__}, - -static PyObject * -_sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string, - Py_ssize_t maxsplit); - -static PyObject * -_sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "maxsplit", NULL}; + +static PyObject * +_sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string, + Py_ssize_t maxsplit); + +static PyObject * +_sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"string", "maxsplit", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *string; - Py_ssize_t maxsplit = 0; - + PyObject *string; + Py_ssize_t maxsplit = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } string = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -704,41 +704,41 @@ _sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t na maxsplit = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_split_impl(self, string, maxsplit); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_sub__doc__, -"sub($self, /, repl, string, count=0)\n" -"--\n" -"\n" -"Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl."); - -#define _SRE_SRE_PATTERN_SUB_METHODDEF \ + return_value = _sre_SRE_Pattern_split_impl(self, string, maxsplit); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_sub__doc__, +"sub($self, /, repl, string, count=0)\n" +"--\n" +"\n" +"Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl."); + +#define _SRE_SRE_PATTERN_SUB_METHODDEF \ {"sub", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_sub, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_sub__doc__}, - -static PyObject * -_sre_SRE_Pattern_sub_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count); - -static PyObject * -_sre_SRE_Pattern_sub(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"repl", "string", "count", NULL}; + +static PyObject * +_sre_SRE_Pattern_sub_impl(PatternObject *self, PyObject *repl, + PyObject *string, Py_ssize_t count); + +static PyObject * +_sre_SRE_Pattern_sub(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"repl", "string", "count", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "sub", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - PyObject *repl; - PyObject *string; - Py_ssize_t count = 0; - + PyObject *repl; + PyObject *string; + Py_ssize_t count = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } repl = args[0]; string = args[1]; if (!noptargs) { @@ -762,41 +762,41 @@ _sre_SRE_Pattern_sub(PatternObject *self, PyObject *const *args, Py_ssize_t narg count = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_sub_impl(self, repl, string, count); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern_subn__doc__, -"subn($self, /, repl, string, count=0)\n" -"--\n" -"\n" -"Return the tuple (new_string, number_of_subs_made) found by replacing the leftmost non-overlapping occurrences of pattern with the replacement repl."); - -#define _SRE_SRE_PATTERN_SUBN_METHODDEF \ + return_value = _sre_SRE_Pattern_sub_impl(self, repl, string, count); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_subn__doc__, +"subn($self, /, repl, string, count=0)\n" +"--\n" +"\n" +"Return the tuple (new_string, number_of_subs_made) found by replacing the leftmost non-overlapping occurrences of pattern with the replacement repl."); + +#define _SRE_SRE_PATTERN_SUBN_METHODDEF \ {"subn", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_subn, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_subn__doc__}, - -static PyObject * -_sre_SRE_Pattern_subn_impl(PatternObject *self, PyObject *repl, - PyObject *string, Py_ssize_t count); - -static PyObject * -_sre_SRE_Pattern_subn(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"repl", "string", "count", NULL}; + +static PyObject * +_sre_SRE_Pattern_subn_impl(PatternObject *self, PyObject *repl, + PyObject *string, Py_ssize_t count); + +static PyObject * +_sre_SRE_Pattern_subn(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"repl", "string", "count", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "subn", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - PyObject *repl; - PyObject *string; - Py_ssize_t count = 0; - + PyObject *repl; + PyObject *string; + Py_ssize_t count = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } repl = args[0]; string = args[1]; if (!noptargs) { @@ -820,69 +820,69 @@ _sre_SRE_Pattern_subn(PatternObject *self, PyObject *const *args, Py_ssize_t nar count = ival; } skip_optional_pos: - return_value = _sre_SRE_Pattern_subn_impl(self, repl, string, count); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Pattern___copy____doc__, -"__copy__($self, /)\n" -"--\n" -"\n"); - -#define _SRE_SRE_PATTERN___COPY___METHODDEF \ - {"__copy__", (PyCFunction)_sre_SRE_Pattern___copy__, METH_NOARGS, _sre_SRE_Pattern___copy____doc__}, - -static PyObject * -_sre_SRE_Pattern___copy___impl(PatternObject *self); - -static PyObject * -_sre_SRE_Pattern___copy__(PatternObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _sre_SRE_Pattern___copy___impl(self); -} - -PyDoc_STRVAR(_sre_SRE_Pattern___deepcopy____doc__, -"__deepcopy__($self, memo, /)\n" -"--\n" -"\n"); - -#define _SRE_SRE_PATTERN___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)_sre_SRE_Pattern___deepcopy__, METH_O, _sre_SRE_Pattern___deepcopy____doc__}, - -PyDoc_STRVAR(_sre_compile__doc__, -"compile($module, /, pattern, flags, code, groups, groupindex,\n" -" indexgroup)\n" -"--\n" -"\n"); - -#define _SRE_COMPILE_METHODDEF \ + return_value = _sre_SRE_Pattern_subn_impl(self, repl, string, count); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n"); + +#define _SRE_SRE_PATTERN___COPY___METHODDEF \ + {"__copy__", (PyCFunction)_sre_SRE_Pattern___copy__, METH_NOARGS, _sre_SRE_Pattern___copy____doc__}, + +static PyObject * +_sre_SRE_Pattern___copy___impl(PatternObject *self); + +static PyObject * +_sre_SRE_Pattern___copy__(PatternObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _sre_SRE_Pattern___copy___impl(self); +} + +PyDoc_STRVAR(_sre_SRE_Pattern___deepcopy____doc__, +"__deepcopy__($self, memo, /)\n" +"--\n" +"\n"); + +#define _SRE_SRE_PATTERN___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)_sre_SRE_Pattern___deepcopy__, METH_O, _sre_SRE_Pattern___deepcopy____doc__}, + +PyDoc_STRVAR(_sre_compile__doc__, +"compile($module, /, pattern, flags, code, groups, groupindex,\n" +" indexgroup)\n" +"--\n" +"\n"); + +#define _SRE_COMPILE_METHODDEF \ {"compile", (PyCFunction)(void(*)(void))_sre_compile, METH_FASTCALL|METH_KEYWORDS, _sre_compile__doc__}, - -static PyObject * -_sre_compile_impl(PyObject *module, PyObject *pattern, int flags, - PyObject *code, Py_ssize_t groups, PyObject *groupindex, - PyObject *indexgroup); - -static PyObject * -_sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; + +static PyObject * +_sre_compile_impl(PyObject *module, PyObject *pattern, int flags, + PyObject *code, Py_ssize_t groups, PyObject *groupindex, + PyObject *indexgroup); + +static PyObject * +_sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; PyObject *argsbuf[6]; - PyObject *pattern; - int flags; - PyObject *code; - Py_ssize_t groups; - PyObject *groupindex; - PyObject *indexgroup; - + PyObject *pattern; + int flags; + PyObject *code; + Py_ssize_t groups; + PyObject *groupindex; + PyObject *indexgroup; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 6, 6, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } pattern = args[0]; if (PyFloat_Check(args[1])) { PyErr_SetString(PyExc_TypeError, @@ -925,286 +925,286 @@ _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } indexgroup = args[5]; - return_value = _sre_compile_impl(module, pattern, flags, code, groups, groupindex, indexgroup); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Match_expand__doc__, -"expand($self, /, template)\n" -"--\n" -"\n" -"Return the string obtained by doing backslash substitution on the string template, as done by the sub() method."); - -#define _SRE_SRE_MATCH_EXPAND_METHODDEF \ + return_value = _sre_compile_impl(module, pattern, flags, code, groups, groupindex, indexgroup); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Match_expand__doc__, +"expand($self, /, template)\n" +"--\n" +"\n" +"Return the string obtained by doing backslash substitution on the string template, as done by the sub() method."); + +#define _SRE_SRE_MATCH_EXPAND_METHODDEF \ {"expand", (PyCFunction)(void(*)(void))_sre_SRE_Match_expand, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_expand__doc__}, - -static PyObject * -_sre_SRE_Match_expand_impl(MatchObject *self, PyObject *template); - -static PyObject * -_sre_SRE_Match_expand(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"template", NULL}; + +static PyObject * +_sre_SRE_Match_expand_impl(MatchObject *self, PyObject *template); + +static PyObject * +_sre_SRE_Match_expand(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"template", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "expand", 0}; PyObject *argsbuf[1]; - PyObject *template; - + PyObject *template; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } template = args[0]; - return_value = _sre_SRE_Match_expand_impl(self, template); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Match_groups__doc__, -"groups($self, /, default=None)\n" -"--\n" -"\n" -"Return a tuple containing all the subgroups of the match, from 1.\n" -"\n" -" default\n" -" Is used for groups that did not participate in the match."); - -#define _SRE_SRE_MATCH_GROUPS_METHODDEF \ + return_value = _sre_SRE_Match_expand_impl(self, template); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Match_groups__doc__, +"groups($self, /, default=None)\n" +"--\n" +"\n" +"Return a tuple containing all the subgroups of the match, from 1.\n" +"\n" +" default\n" +" Is used for groups that did not participate in the match."); + +#define _SRE_SRE_MATCH_GROUPS_METHODDEF \ {"groups", (PyCFunction)(void(*)(void))_sre_SRE_Match_groups, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_groups__doc__}, - -static PyObject * -_sre_SRE_Match_groups_impl(MatchObject *self, PyObject *default_value); - -static PyObject * -_sre_SRE_Match_groups(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"default", NULL}; + +static PyObject * +_sre_SRE_Match_groups_impl(MatchObject *self, PyObject *default_value); + +static PyObject * +_sre_SRE_Match_groups(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"default", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "groups", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *default_value = Py_None; - + PyObject *default_value = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } default_value = args[0]; skip_optional_pos: - return_value = _sre_SRE_Match_groups_impl(self, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Match_groupdict__doc__, -"groupdict($self, /, default=None)\n" -"--\n" -"\n" -"Return a dictionary containing all the named subgroups of the match, keyed by the subgroup name.\n" -"\n" -" default\n" -" Is used for groups that did not participate in the match."); - -#define _SRE_SRE_MATCH_GROUPDICT_METHODDEF \ + return_value = _sre_SRE_Match_groups_impl(self, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Match_groupdict__doc__, +"groupdict($self, /, default=None)\n" +"--\n" +"\n" +"Return a dictionary containing all the named subgroups of the match, keyed by the subgroup name.\n" +"\n" +" default\n" +" Is used for groups that did not participate in the match."); + +#define _SRE_SRE_MATCH_GROUPDICT_METHODDEF \ {"groupdict", (PyCFunction)(void(*)(void))_sre_SRE_Match_groupdict, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_groupdict__doc__}, - -static PyObject * -_sre_SRE_Match_groupdict_impl(MatchObject *self, PyObject *default_value); - -static PyObject * -_sre_SRE_Match_groupdict(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"default", NULL}; + +static PyObject * +_sre_SRE_Match_groupdict_impl(MatchObject *self, PyObject *default_value); + +static PyObject * +_sre_SRE_Match_groupdict(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"default", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "groupdict", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *default_value = Py_None; - + PyObject *default_value = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } default_value = args[0]; skip_optional_pos: - return_value = _sre_SRE_Match_groupdict_impl(self, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Match_start__doc__, -"start($self, group=0, /)\n" -"--\n" -"\n" -"Return index of the start of the substring matched by group."); - -#define _SRE_SRE_MATCH_START_METHODDEF \ + return_value = _sre_SRE_Match_groupdict_impl(self, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Match_start__doc__, +"start($self, group=0, /)\n" +"--\n" +"\n" +"Return index of the start of the substring matched by group."); + +#define _SRE_SRE_MATCH_START_METHODDEF \ {"start", (PyCFunction)(void(*)(void))_sre_SRE_Match_start, METH_FASTCALL, _sre_SRE_Match_start__doc__}, - -static Py_ssize_t -_sre_SRE_Match_start_impl(MatchObject *self, PyObject *group); - -static PyObject * -_sre_SRE_Match_start(MatchObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *group = NULL; - Py_ssize_t _return_value; - + +static Py_ssize_t +_sre_SRE_Match_start_impl(MatchObject *self, PyObject *group); + +static PyObject * +_sre_SRE_Match_start(MatchObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *group = NULL; + Py_ssize_t _return_value; + if (!_PyArg_CheckPositional("start", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } group = args[0]; skip_optional: - _return_value = _sre_SRE_Match_start_impl(self, group); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Match_end__doc__, -"end($self, group=0, /)\n" -"--\n" -"\n" -"Return index of the end of the substring matched by group."); - -#define _SRE_SRE_MATCH_END_METHODDEF \ + _return_value = _sre_SRE_Match_start_impl(self, group); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Match_end__doc__, +"end($self, group=0, /)\n" +"--\n" +"\n" +"Return index of the end of the substring matched by group."); + +#define _SRE_SRE_MATCH_END_METHODDEF \ {"end", (PyCFunction)(void(*)(void))_sre_SRE_Match_end, METH_FASTCALL, _sre_SRE_Match_end__doc__}, - -static Py_ssize_t -_sre_SRE_Match_end_impl(MatchObject *self, PyObject *group); - -static PyObject * -_sre_SRE_Match_end(MatchObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *group = NULL; - Py_ssize_t _return_value; - + +static Py_ssize_t +_sre_SRE_Match_end_impl(MatchObject *self, PyObject *group); + +static PyObject * +_sre_SRE_Match_end(MatchObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *group = NULL; + Py_ssize_t _return_value; + if (!_PyArg_CheckPositional("end", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } group = args[0]; skip_optional: - _return_value = _sre_SRE_Match_end_impl(self, group); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Match_span__doc__, -"span($self, group=0, /)\n" -"--\n" -"\n" -"For match object m, return the 2-tuple (m.start(group), m.end(group))."); - -#define _SRE_SRE_MATCH_SPAN_METHODDEF \ + _return_value = _sre_SRE_Match_end_impl(self, group); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Match_span__doc__, +"span($self, group=0, /)\n" +"--\n" +"\n" +"For match object m, return the 2-tuple (m.start(group), m.end(group))."); + +#define _SRE_SRE_MATCH_SPAN_METHODDEF \ {"span", (PyCFunction)(void(*)(void))_sre_SRE_Match_span, METH_FASTCALL, _sre_SRE_Match_span__doc__}, - -static PyObject * -_sre_SRE_Match_span_impl(MatchObject *self, PyObject *group); - -static PyObject * -_sre_SRE_Match_span(MatchObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *group = NULL; - + +static PyObject * +_sre_SRE_Match_span_impl(MatchObject *self, PyObject *group); + +static PyObject * +_sre_SRE_Match_span(MatchObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *group = NULL; + if (!_PyArg_CheckPositional("span", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } group = args[0]; skip_optional: - return_value = _sre_SRE_Match_span_impl(self, group); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sre_SRE_Match___copy____doc__, -"__copy__($self, /)\n" -"--\n" -"\n"); - -#define _SRE_SRE_MATCH___COPY___METHODDEF \ - {"__copy__", (PyCFunction)_sre_SRE_Match___copy__, METH_NOARGS, _sre_SRE_Match___copy____doc__}, - -static PyObject * -_sre_SRE_Match___copy___impl(MatchObject *self); - -static PyObject * -_sre_SRE_Match___copy__(MatchObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _sre_SRE_Match___copy___impl(self); -} - -PyDoc_STRVAR(_sre_SRE_Match___deepcopy____doc__, -"__deepcopy__($self, memo, /)\n" -"--\n" -"\n"); - -#define _SRE_SRE_MATCH___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)_sre_SRE_Match___deepcopy__, METH_O, _sre_SRE_Match___deepcopy____doc__}, - -PyDoc_STRVAR(_sre_SRE_Scanner_match__doc__, -"match($self, /)\n" -"--\n" -"\n"); - -#define _SRE_SRE_SCANNER_MATCH_METHODDEF \ - {"match", (PyCFunction)_sre_SRE_Scanner_match, METH_NOARGS, _sre_SRE_Scanner_match__doc__}, - -static PyObject * -_sre_SRE_Scanner_match_impl(ScannerObject *self); - -static PyObject * -_sre_SRE_Scanner_match(ScannerObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _sre_SRE_Scanner_match_impl(self); -} - -PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, -"search($self, /)\n" -"--\n" -"\n"); - -#define _SRE_SRE_SCANNER_SEARCH_METHODDEF \ - {"search", (PyCFunction)_sre_SRE_Scanner_search, METH_NOARGS, _sre_SRE_Scanner_search__doc__}, - -static PyObject * -_sre_SRE_Scanner_search_impl(ScannerObject *self); - -static PyObject * -_sre_SRE_Scanner_search(ScannerObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _sre_SRE_Scanner_search_impl(self); -} + return_value = _sre_SRE_Match_span_impl(self, group); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Match___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n"); + +#define _SRE_SRE_MATCH___COPY___METHODDEF \ + {"__copy__", (PyCFunction)_sre_SRE_Match___copy__, METH_NOARGS, _sre_SRE_Match___copy____doc__}, + +static PyObject * +_sre_SRE_Match___copy___impl(MatchObject *self); + +static PyObject * +_sre_SRE_Match___copy__(MatchObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _sre_SRE_Match___copy___impl(self); +} + +PyDoc_STRVAR(_sre_SRE_Match___deepcopy____doc__, +"__deepcopy__($self, memo, /)\n" +"--\n" +"\n"); + +#define _SRE_SRE_MATCH___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)_sre_SRE_Match___deepcopy__, METH_O, _sre_SRE_Match___deepcopy____doc__}, + +PyDoc_STRVAR(_sre_SRE_Scanner_match__doc__, +"match($self, /)\n" +"--\n" +"\n"); + +#define _SRE_SRE_SCANNER_MATCH_METHODDEF \ + {"match", (PyCFunction)_sre_SRE_Scanner_match, METH_NOARGS, _sre_SRE_Scanner_match__doc__}, + +static PyObject * +_sre_SRE_Scanner_match_impl(ScannerObject *self); + +static PyObject * +_sre_SRE_Scanner_match(ScannerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _sre_SRE_Scanner_match_impl(self); +} + +PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, +"search($self, /)\n" +"--\n" +"\n"); + +#define _SRE_SRE_SCANNER_SEARCH_METHODDEF \ + {"search", (PyCFunction)_sre_SRE_Scanner_search, METH_NOARGS, _sre_SRE_Scanner_search__doc__}, + +static PyObject * +_sre_SRE_Scanner_search_impl(ScannerObject *self); + +static PyObject * +_sre_SRE_Scanner_search(ScannerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _sre_SRE_Scanner_search_impl(self); +} /*[clinic end generated code: output=1adeddce58ae284c input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_ssl.c.h b/contrib/tools/python3/src/Modules/clinic/_ssl.c.h index ce8669ae212..361bb3240fa 100644 --- a/contrib/tools/python3/src/Modules/clinic/_ssl.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_ssl.c.h @@ -1,79 +1,79 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, -"do_handshake($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLSOCKET_DO_HANDSHAKE_METHODDEF \ - {"do_handshake", (PyCFunction)_ssl__SSLSocket_do_handshake, METH_NOARGS, _ssl__SSLSocket_do_handshake__doc__}, - -static PyObject * -_ssl__SSLSocket_do_handshake_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_do_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_do_handshake_impl(self); -} - -PyDoc_STRVAR(_ssl__test_decode_cert__doc__, -"_test_decode_cert($module, path, /)\n" -"--\n" -"\n"); - -#define _SSL__TEST_DECODE_CERT_METHODDEF \ - {"_test_decode_cert", (PyCFunction)_ssl__test_decode_cert, METH_O, _ssl__test_decode_cert__doc__}, - -static PyObject * -_ssl__test_decode_cert_impl(PyObject *module, PyObject *path); - -static PyObject * -_ssl__test_decode_cert(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *path; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, +"do_handshake($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_DO_HANDSHAKE_METHODDEF \ + {"do_handshake", (PyCFunction)_ssl__SSLSocket_do_handshake, METH_NOARGS, _ssl__SSLSocket_do_handshake__doc__}, + +static PyObject * +_ssl__SSLSocket_do_handshake_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_do_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_do_handshake_impl(self); +} + +PyDoc_STRVAR(_ssl__test_decode_cert__doc__, +"_test_decode_cert($module, path, /)\n" +"--\n" +"\n"); + +#define _SSL__TEST_DECODE_CERT_METHODDEF \ + {"_test_decode_cert", (PyCFunction)_ssl__test_decode_cert, METH_O, _ssl__test_decode_cert__doc__}, + +static PyObject * +_ssl__test_decode_cert_impl(PyObject *module, PyObject *path); + +static PyObject * +_ssl__test_decode_cert(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *path; + if (!PyUnicode_FSConverter(arg, &path)) { - goto exit; - } - return_value = _ssl__test_decode_cert_impl(module, path); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLSocket_getpeercert__doc__, -"getpeercert($self, der=False, /)\n" -"--\n" -"\n" -"Returns the certificate for the peer.\n" -"\n" -"If no certificate was provided, returns None. If a certificate was\n" -"provided, but not validated, returns an empty dictionary. Otherwise\n" -"returns a dict containing information about the peer certificate.\n" -"\n" -"If the optional argument is True, returns a DER-encoded copy of the\n" -"peer certificate, or None if no certificate was provided. This will\n" -"return the certificate even if it wasn\'t validated."); - -#define _SSL__SSLSOCKET_GETPEERCERT_METHODDEF \ + goto exit; + } + return_value = _ssl__test_decode_cert_impl(module, path); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_getpeercert__doc__, +"getpeercert($self, der=False, /)\n" +"--\n" +"\n" +"Returns the certificate for the peer.\n" +"\n" +"If no certificate was provided, returns None. If a certificate was\n" +"provided, but not validated, returns an empty dictionary. Otherwise\n" +"returns a dict containing information about the peer certificate.\n" +"\n" +"If the optional argument is True, returns a DER-encoded copy of the\n" +"peer certificate, or None if no certificate was provided. This will\n" +"return the certificate even if it wasn\'t validated."); + +#define _SSL__SSLSOCKET_GETPEERCERT_METHODDEF \ {"getpeercert", (PyCFunction)(void(*)(void))_ssl__SSLSocket_getpeercert, METH_FASTCALL, _ssl__SSLSocket_getpeercert__doc__}, - -static PyObject * -_ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode); - -static PyObject * -_ssl__SSLSocket_getpeercert(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int binary_mode = 0; - + +static PyObject * +_ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode); + +static PyObject * +_ssl__SSLSocket_getpeercert(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int binary_mode = 0; + if (!_PyArg_CheckPositional("getpeercert", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -82,273 +82,273 @@ _ssl__SSLSocket_getpeercert(PySSLSocket *self, PyObject *const *args, Py_ssize_t goto exit; } skip_optional: - return_value = _ssl__SSLSocket_getpeercert_impl(self, binary_mode); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLSocket_shared_ciphers__doc__, -"shared_ciphers($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF \ - {"shared_ciphers", (PyCFunction)_ssl__SSLSocket_shared_ciphers, METH_NOARGS, _ssl__SSLSocket_shared_ciphers__doc__}, - -static PyObject * -_ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_shared_ciphers(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_shared_ciphers_impl(self); -} - -PyDoc_STRVAR(_ssl__SSLSocket_cipher__doc__, -"cipher($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLSOCKET_CIPHER_METHODDEF \ - {"cipher", (PyCFunction)_ssl__SSLSocket_cipher, METH_NOARGS, _ssl__SSLSocket_cipher__doc__}, - -static PyObject * -_ssl__SSLSocket_cipher_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_cipher(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_cipher_impl(self); -} - -PyDoc_STRVAR(_ssl__SSLSocket_version__doc__, -"version($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLSOCKET_VERSION_METHODDEF \ - {"version", (PyCFunction)_ssl__SSLSocket_version, METH_NOARGS, _ssl__SSLSocket_version__doc__}, - -static PyObject * -_ssl__SSLSocket_version_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_version(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_version_impl(self); -} - -#if (HAVE_NPN) - -PyDoc_STRVAR(_ssl__SSLSocket_selected_npn_protocol__doc__, -"selected_npn_protocol($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF \ - {"selected_npn_protocol", (PyCFunction)_ssl__SSLSocket_selected_npn_protocol, METH_NOARGS, _ssl__SSLSocket_selected_npn_protocol__doc__}, - -static PyObject * -_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_selected_npn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_selected_npn_protocol_impl(self); -} - -#endif /* (HAVE_NPN) */ - -#if (HAVE_ALPN) - -PyDoc_STRVAR(_ssl__SSLSocket_selected_alpn_protocol__doc__, -"selected_alpn_protocol($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF \ - {"selected_alpn_protocol", (PyCFunction)_ssl__SSLSocket_selected_alpn_protocol, METH_NOARGS, _ssl__SSLSocket_selected_alpn_protocol__doc__}, - -static PyObject * -_ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_selected_alpn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_selected_alpn_protocol_impl(self); -} - -#endif /* (HAVE_ALPN) */ - -PyDoc_STRVAR(_ssl__SSLSocket_compression__doc__, -"compression($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLSOCKET_COMPRESSION_METHODDEF \ - {"compression", (PyCFunction)_ssl__SSLSocket_compression, METH_NOARGS, _ssl__SSLSocket_compression__doc__}, - -static PyObject * -_ssl__SSLSocket_compression_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_compression(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_compression_impl(self); -} - -PyDoc_STRVAR(_ssl__SSLSocket_write__doc__, -"write($self, b, /)\n" -"--\n" -"\n" -"Writes the bytes-like object b into the SSL object.\n" -"\n" -"Returns the number of bytes written."); - -#define _SSL__SSLSOCKET_WRITE_METHODDEF \ - {"write", (PyCFunction)_ssl__SSLSocket_write, METH_O, _ssl__SSLSocket_write__doc__}, - -static PyObject * -_ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b); - -static PyObject * -_ssl__SSLSocket_write(PySSLSocket *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer b = {NULL, NULL}; - + return_value = _ssl__SSLSocket_getpeercert_impl(self, binary_mode); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_shared_ciphers__doc__, +"shared_ciphers($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF \ + {"shared_ciphers", (PyCFunction)_ssl__SSLSocket_shared_ciphers, METH_NOARGS, _ssl__SSLSocket_shared_ciphers__doc__}, + +static PyObject * +_ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_shared_ciphers(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_shared_ciphers_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_cipher__doc__, +"cipher($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_CIPHER_METHODDEF \ + {"cipher", (PyCFunction)_ssl__SSLSocket_cipher, METH_NOARGS, _ssl__SSLSocket_cipher__doc__}, + +static PyObject * +_ssl__SSLSocket_cipher_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_cipher(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_cipher_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_version__doc__, +"version($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_VERSION_METHODDEF \ + {"version", (PyCFunction)_ssl__SSLSocket_version, METH_NOARGS, _ssl__SSLSocket_version__doc__}, + +static PyObject * +_ssl__SSLSocket_version_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_version(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_version_impl(self); +} + +#if (HAVE_NPN) + +PyDoc_STRVAR(_ssl__SSLSocket_selected_npn_protocol__doc__, +"selected_npn_protocol($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF \ + {"selected_npn_protocol", (PyCFunction)_ssl__SSLSocket_selected_npn_protocol, METH_NOARGS, _ssl__SSLSocket_selected_npn_protocol__doc__}, + +static PyObject * +_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_selected_npn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_selected_npn_protocol_impl(self); +} + +#endif /* (HAVE_NPN) */ + +#if (HAVE_ALPN) + +PyDoc_STRVAR(_ssl__SSLSocket_selected_alpn_protocol__doc__, +"selected_alpn_protocol($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF \ + {"selected_alpn_protocol", (PyCFunction)_ssl__SSLSocket_selected_alpn_protocol, METH_NOARGS, _ssl__SSLSocket_selected_alpn_protocol__doc__}, + +static PyObject * +_ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_selected_alpn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_selected_alpn_protocol_impl(self); +} + +#endif /* (HAVE_ALPN) */ + +PyDoc_STRVAR(_ssl__SSLSocket_compression__doc__, +"compression($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLSOCKET_COMPRESSION_METHODDEF \ + {"compression", (PyCFunction)_ssl__SSLSocket_compression, METH_NOARGS, _ssl__SSLSocket_compression__doc__}, + +static PyObject * +_ssl__SSLSocket_compression_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_compression(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_compression_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_write__doc__, +"write($self, b, /)\n" +"--\n" +"\n" +"Writes the bytes-like object b into the SSL object.\n" +"\n" +"Returns the number of bytes written."); + +#define _SSL__SSLSOCKET_WRITE_METHODDEF \ + {"write", (PyCFunction)_ssl__SSLSocket_write, METH_O, _ssl__SSLSocket_write__doc__}, + +static PyObject * +_ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b); + +static PyObject * +_ssl__SSLSocket_write(PySSLSocket *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer b = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&b, 'C')) { _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } - return_value = _ssl__SSLSocket_write_impl(self, &b); - -exit: - /* Cleanup for b */ - if (b.obj) { - PyBuffer_Release(&b); - } - - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLSocket_pending__doc__, -"pending($self, /)\n" -"--\n" -"\n" -"Returns the number of already decrypted bytes available for read, pending on the connection."); - -#define _SSL__SSLSOCKET_PENDING_METHODDEF \ - {"pending", (PyCFunction)_ssl__SSLSocket_pending, METH_NOARGS, _ssl__SSLSocket_pending__doc__}, - -static PyObject * -_ssl__SSLSocket_pending_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_pending(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_pending_impl(self); -} - -PyDoc_STRVAR(_ssl__SSLSocket_read__doc__, -"read(size, [buffer])\n" -"Read up to size bytes from the SSL socket."); - -#define _SSL__SSLSOCKET_READ_METHODDEF \ - {"read", (PyCFunction)_ssl__SSLSocket_read, METH_VARARGS, _ssl__SSLSocket_read__doc__}, - -static PyObject * -_ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, - Py_buffer *buffer); - -static PyObject * -_ssl__SSLSocket_read(PySSLSocket *self, PyObject *args) -{ - PyObject *return_value = NULL; - int len; - int group_right_1 = 0; - Py_buffer buffer = {NULL, NULL}; - - switch (PyTuple_GET_SIZE(args)) { - case 1: - if (!PyArg_ParseTuple(args, "i:read", &len)) { - goto exit; - } - break; - case 2: - if (!PyArg_ParseTuple(args, "iw*:read", &len, &buffer)) { - goto exit; - } - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "_ssl._SSLSocket.read requires 1 to 2 arguments"); - goto exit; - } - return_value = _ssl__SSLSocket_read_impl(self, len, group_right_1, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLSocket_shutdown__doc__, -"shutdown($self, /)\n" -"--\n" -"\n" -"Does the SSL shutdown handshake with the remote end."); - -#define _SSL__SSLSOCKET_SHUTDOWN_METHODDEF \ - {"shutdown", (PyCFunction)_ssl__SSLSocket_shutdown, METH_NOARGS, _ssl__SSLSocket_shutdown__doc__}, - -static PyObject * -_ssl__SSLSocket_shutdown_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_shutdown(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_shutdown_impl(self); -} - -PyDoc_STRVAR(_ssl__SSLSocket_get_channel_binding__doc__, -"get_channel_binding($self, /, cb_type=\'tls-unique\')\n" -"--\n" -"\n" -"Get channel binding data for current connection.\n" -"\n" -"Raise ValueError if the requested `cb_type` is not supported. Return bytes\n" -"of the data or None if the data is not available (e.g. before the handshake).\n" -"Only \'tls-unique\' channel binding data from RFC 5929 is supported."); - -#define _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF \ + return_value = _ssl__SSLSocket_write_impl(self, &b); + +exit: + /* Cleanup for b */ + if (b.obj) { + PyBuffer_Release(&b); + } + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_pending__doc__, +"pending($self, /)\n" +"--\n" +"\n" +"Returns the number of already decrypted bytes available for read, pending on the connection."); + +#define _SSL__SSLSOCKET_PENDING_METHODDEF \ + {"pending", (PyCFunction)_ssl__SSLSocket_pending, METH_NOARGS, _ssl__SSLSocket_pending__doc__}, + +static PyObject * +_ssl__SSLSocket_pending_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_pending(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_pending_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_read__doc__, +"read(size, [buffer])\n" +"Read up to size bytes from the SSL socket."); + +#define _SSL__SSLSOCKET_READ_METHODDEF \ + {"read", (PyCFunction)_ssl__SSLSocket_read, METH_VARARGS, _ssl__SSLSocket_read__doc__}, + +static PyObject * +_ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, + Py_buffer *buffer); + +static PyObject * +_ssl__SSLSocket_read(PySSLSocket *self, PyObject *args) +{ + PyObject *return_value = NULL; + int len; + int group_right_1 = 0; + Py_buffer buffer = {NULL, NULL}; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "i:read", &len)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "iw*:read", &len, &buffer)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_ssl._SSLSocket.read requires 1 to 2 arguments"); + goto exit; + } + return_value = _ssl__SSLSocket_read_impl(self, len, group_right_1, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_shutdown__doc__, +"shutdown($self, /)\n" +"--\n" +"\n" +"Does the SSL shutdown handshake with the remote end."); + +#define _SSL__SSLSOCKET_SHUTDOWN_METHODDEF \ + {"shutdown", (PyCFunction)_ssl__SSLSocket_shutdown, METH_NOARGS, _ssl__SSLSocket_shutdown__doc__}, + +static PyObject * +_ssl__SSLSocket_shutdown_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_shutdown(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_shutdown_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLSocket_get_channel_binding__doc__, +"get_channel_binding($self, /, cb_type=\'tls-unique\')\n" +"--\n" +"\n" +"Get channel binding data for current connection.\n" +"\n" +"Raise ValueError if the requested `cb_type` is not supported. Return bytes\n" +"of the data or None if the data is not available (e.g. before the handshake).\n" +"Only \'tls-unique\' channel binding data from RFC 5929 is supported."); + +#define _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF \ {"get_channel_binding", (PyCFunction)(void(*)(void))_ssl__SSLSocket_get_channel_binding, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLSocket_get_channel_binding__doc__}, - -static PyObject * -_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, - const char *cb_type); - -static PyObject * -_ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"cb_type", NULL}; + +static PyObject * +_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, + const char *cb_type); + +static PyObject * +_ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"cb_type", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "get_channel_binding", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - const char *cb_type = "tls-unique"; - + const char *cb_type = "tls-unique"; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -366,46 +366,46 @@ _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py goto exit; } skip_optional_pos: - return_value = _ssl__SSLSocket_get_channel_binding_impl(self, cb_type); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLSocket_verify_client_post_handshake__doc__, -"verify_client_post_handshake($self, /)\n" -"--\n" -"\n" -"Initiate TLS 1.3 post-handshake authentication"); - -#define _SSL__SSLSOCKET_VERIFY_CLIENT_POST_HANDSHAKE_METHODDEF \ - {"verify_client_post_handshake", (PyCFunction)_ssl__SSLSocket_verify_client_post_handshake, METH_NOARGS, _ssl__SSLSocket_verify_client_post_handshake__doc__}, - -static PyObject * -_ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self); - -static PyObject * -_ssl__SSLSocket_verify_client_post_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLSocket_verify_client_post_handshake_impl(self); -} - -static PyObject * -_ssl__SSLContext_impl(PyTypeObject *type, int proto_version); - -static PyObject * -_ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - int proto_version; - - if ((type == &PySSLContext_Type) && - !_PyArg_NoKeywords("_SSLContext", kwargs)) { - goto exit; - } + return_value = _ssl__SSLSocket_get_channel_binding_impl(self, cb_type); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_verify_client_post_handshake__doc__, +"verify_client_post_handshake($self, /)\n" +"--\n" +"\n" +"Initiate TLS 1.3 post-handshake authentication"); + +#define _SSL__SSLSOCKET_VERIFY_CLIENT_POST_HANDSHAKE_METHODDEF \ + {"verify_client_post_handshake", (PyCFunction)_ssl__SSLSocket_verify_client_post_handshake, METH_NOARGS, _ssl__SSLSocket_verify_client_post_handshake__doc__}, + +static PyObject * +_ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_verify_client_post_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_verify_client_post_handshake_impl(self); +} + +static PyObject * +_ssl__SSLContext_impl(PyTypeObject *type, int proto_version); + +static PyObject * +_ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + int proto_version; + + if ((type == &PySSLContext_Type) && + !_PyArg_NoKeywords("_SSLContext", kwargs)) { + goto exit; + } if (!_PyArg_CheckPositional("_SSLContext", PyTuple_GET_SIZE(args), 1, 1)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(PyTuple_GET_ITEM(args, 0))) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -415,33 +415,33 @@ _ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (proto_version == -1 && PyErr_Occurred()) { goto exit; } - return_value = _ssl__SSLContext_impl(type, proto_version); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLContext_set_ciphers__doc__, -"set_ciphers($self, cipherlist, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF \ - {"set_ciphers", (PyCFunction)_ssl__SSLContext_set_ciphers, METH_O, _ssl__SSLContext_set_ciphers__doc__}, - -static PyObject * -_ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist); - -static PyObject * -_ssl__SSLContext_set_ciphers(PySSLContext *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *cipherlist; - + return_value = _ssl__SSLContext_impl(type, proto_version); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_set_ciphers__doc__, +"set_ciphers($self, cipherlist, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF \ + {"set_ciphers", (PyCFunction)_ssl__SSLContext_set_ciphers, METH_O, _ssl__SSLContext_set_ciphers__doc__}, + +static PyObject * +_ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist); + +static PyObject * +_ssl__SSLContext_set_ciphers(PySSLContext *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *cipherlist; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("set_ciphers", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t cipherlist_length; cipherlist = PyUnicode_AsUTF8AndSize(arg, &cipherlist_length); if (cipherlist == NULL) { @@ -451,133 +451,133 @@ _ssl__SSLContext_set_ciphers(PySSLContext *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _ssl__SSLContext_set_ciphers_impl(self, cipherlist); - -exit: - return return_value; -} - -#if (OPENSSL_VERSION_NUMBER >= 0x10002000UL) - -PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__, -"get_ciphers($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF \ - {"get_ciphers", (PyCFunction)_ssl__SSLContext_get_ciphers, METH_NOARGS, _ssl__SSLContext_get_ciphers__doc__}, - -static PyObject * -_ssl__SSLContext_get_ciphers_impl(PySSLContext *self); - -static PyObject * -_ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLContext_get_ciphers_impl(self); -} - -#endif /* (OPENSSL_VERSION_NUMBER >= 0x10002000UL) */ - -PyDoc_STRVAR(_ssl__SSLContext__set_npn_protocols__doc__, -"_set_npn_protocols($self, protos, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF \ - {"_set_npn_protocols", (PyCFunction)_ssl__SSLContext__set_npn_protocols, METH_O, _ssl__SSLContext__set_npn_protocols__doc__}, - -static PyObject * -_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, - Py_buffer *protos); - -static PyObject * -_ssl__SSLContext__set_npn_protocols(PySSLContext *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer protos = {NULL, NULL}; - + return_value = _ssl__SSLContext_set_ciphers_impl(self, cipherlist); + +exit: + return return_value; +} + +#if (OPENSSL_VERSION_NUMBER >= 0x10002000UL) + +PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__, +"get_ciphers($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF \ + {"get_ciphers", (PyCFunction)_ssl__SSLContext_get_ciphers, METH_NOARGS, _ssl__SSLContext_get_ciphers__doc__}, + +static PyObject * +_ssl__SSLContext_get_ciphers_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLContext_get_ciphers_impl(self); +} + +#endif /* (OPENSSL_VERSION_NUMBER >= 0x10002000UL) */ + +PyDoc_STRVAR(_ssl__SSLContext__set_npn_protocols__doc__, +"_set_npn_protocols($self, protos, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF \ + {"_set_npn_protocols", (PyCFunction)_ssl__SSLContext__set_npn_protocols, METH_O, _ssl__SSLContext__set_npn_protocols__doc__}, + +static PyObject * +_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, + Py_buffer *protos); + +static PyObject * +_ssl__SSLContext__set_npn_protocols(PySSLContext *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer protos = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&protos, 'C')) { _PyArg_BadArgument("_set_npn_protocols", "argument", "contiguous buffer", arg); goto exit; } - return_value = _ssl__SSLContext__set_npn_protocols_impl(self, &protos); - -exit: - /* Cleanup for protos */ - if (protos.obj) { - PyBuffer_Release(&protos); - } - - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, -"_set_alpn_protocols($self, protos, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF \ - {"_set_alpn_protocols", (PyCFunction)_ssl__SSLContext__set_alpn_protocols, METH_O, _ssl__SSLContext__set_alpn_protocols__doc__}, - -static PyObject * -_ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, - Py_buffer *protos); - -static PyObject * -_ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer protos = {NULL, NULL}; - + return_value = _ssl__SSLContext__set_npn_protocols_impl(self, &protos); + +exit: + /* Cleanup for protos */ + if (protos.obj) { + PyBuffer_Release(&protos); + } + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, +"_set_alpn_protocols($self, protos, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF \ + {"_set_alpn_protocols", (PyCFunction)_ssl__SSLContext__set_alpn_protocols, METH_O, _ssl__SSLContext__set_alpn_protocols__doc__}, + +static PyObject * +_ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, + Py_buffer *protos); + +static PyObject * +_ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer protos = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&protos, 'C')) { _PyArg_BadArgument("_set_alpn_protocols", "argument", "contiguous buffer", arg); goto exit; } - return_value = _ssl__SSLContext__set_alpn_protocols_impl(self, &protos); - -exit: - /* Cleanup for protos */ - if (protos.obj) { - PyBuffer_Release(&protos); - } - - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLContext_load_cert_chain__doc__, -"load_cert_chain($self, /, certfile, keyfile=None, password=None)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF \ + return_value = _ssl__SSLContext__set_alpn_protocols_impl(self, &protos); + +exit: + /* Cleanup for protos */ + if (protos.obj) { + PyBuffer_Release(&protos); + } + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_load_cert_chain__doc__, +"load_cert_chain($self, /, certfile, keyfile=None, password=None)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF \ {"load_cert_chain", (PyCFunction)(void(*)(void))_ssl__SSLContext_load_cert_chain, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_load_cert_chain__doc__}, - -static PyObject * -_ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, - PyObject *keyfile, PyObject *password); - -static PyObject * -_ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"certfile", "keyfile", "password", NULL}; + +static PyObject * +_ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, + PyObject *keyfile, PyObject *password); + +static PyObject * +_ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"certfile", "keyfile", "password", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "load_cert_chain", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *certfile; + PyObject *certfile; PyObject *keyfile = Py_None; PyObject *password = Py_None; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } certfile = args[0]; if (!noptargs) { goto skip_optional_pos; @@ -590,42 +590,42 @@ _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_s } password = args[2]; skip_optional_pos: - return_value = _ssl__SSLContext_load_cert_chain_impl(self, certfile, keyfile, password); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLContext_load_verify_locations__doc__, -"load_verify_locations($self, /, cafile=None, capath=None, cadata=None)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_LOAD_VERIFY_LOCATIONS_METHODDEF \ + return_value = _ssl__SSLContext_load_cert_chain_impl(self, certfile, keyfile, password); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_load_verify_locations__doc__, +"load_verify_locations($self, /, cafile=None, capath=None, cadata=None)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_LOAD_VERIFY_LOCATIONS_METHODDEF \ {"load_verify_locations", (PyCFunction)(void(*)(void))_ssl__SSLContext_load_verify_locations, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_load_verify_locations__doc__}, - -static PyObject * -_ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, - PyObject *cafile, - PyObject *capath, - PyObject *cadata); - -static PyObject * -_ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"cafile", "capath", "cadata", NULL}; + +static PyObject * +_ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, + PyObject *cafile, + PyObject *capath, + PyObject *cadata); + +static PyObject * +_ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"cafile", "capath", "cadata", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "load_verify_locations", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *cafile = Py_None; PyObject *capath = Py_None; PyObject *cadata = Py_None; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -643,52 +643,52 @@ _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args } cadata = args[2]; skip_optional_pos: - return_value = _ssl__SSLContext_load_verify_locations_impl(self, cafile, capath, cadata); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLContext_load_dh_params__doc__, -"load_dh_params($self, path, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF \ - {"load_dh_params", (PyCFunction)_ssl__SSLContext_load_dh_params, METH_O, _ssl__SSLContext_load_dh_params__doc__}, - -PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__, -"_wrap_socket($self, /, sock, server_side, server_hostname=None, *,\n" -" owner=None, session=None)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT__WRAP_SOCKET_METHODDEF \ + return_value = _ssl__SSLContext_load_verify_locations_impl(self, cafile, capath, cadata); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_load_dh_params__doc__, +"load_dh_params($self, path, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF \ + {"load_dh_params", (PyCFunction)_ssl__SSLContext_load_dh_params, METH_O, _ssl__SSLContext_load_dh_params__doc__}, + +PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__, +"_wrap_socket($self, /, sock, server_side, server_hostname=None, *,\n" +" owner=None, session=None)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT__WRAP_SOCKET_METHODDEF \ {"_wrap_socket", (PyCFunction)(void(*)(void))_ssl__SSLContext__wrap_socket, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext__wrap_socket__doc__}, - -static PyObject * -_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, - int server_side, PyObject *hostname_obj, - PyObject *owner, PyObject *session); - -static PyObject * -_ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"sock", "server_side", "server_hostname", "owner", "session", NULL}; + +static PyObject * +_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, + int server_side, PyObject *hostname_obj, + PyObject *owner, PyObject *session); + +static PyObject * +_ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sock", "server_side", "server_hostname", "owner", "session", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "_wrap_socket", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - PyObject *sock; - int server_side; - PyObject *hostname_obj = Py_None; - PyObject *owner = Py_None; - PyObject *session = Py_None; - + PyObject *sock; + int server_side; + PyObject *hostname_obj = Py_None; + PyObject *owner = Py_None; + PyObject *session = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!PyObject_TypeCheck(args[0], PySocketModule.Sock_Type)) { _PyArg_BadArgument("_wrap_socket", "argument 'sock'", (PySocketModule.Sock_Type)->tp_name, args[0]); goto exit; @@ -724,46 +724,46 @@ skip_optional_pos: } session = args[4]; skip_optional_kwonly: - return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj, owner, session); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__, -"_wrap_bio($self, /, incoming, outgoing, server_side,\n" -" server_hostname=None, *, owner=None, session=None)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF \ + return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj, owner, session); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__, +"_wrap_bio($self, /, incoming, outgoing, server_side,\n" +" server_hostname=None, *, owner=None, session=None)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF \ {"_wrap_bio", (PyCFunction)(void(*)(void))_ssl__SSLContext__wrap_bio, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext__wrap_bio__doc__}, - -static PyObject * -_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, - PySSLMemoryBIO *outgoing, int server_side, - PyObject *hostname_obj, PyObject *owner, - PyObject *session); - -static PyObject * -_ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", "owner", "session", NULL}; + +static PyObject * +_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, + PySSLMemoryBIO *outgoing, int server_side, + PyObject *hostname_obj, PyObject *owner, + PyObject *session); + +static PyObject * +_ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", "owner", "session", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "_wrap_bio", 0}; PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - PySSLMemoryBIO *incoming; - PySSLMemoryBIO *outgoing; - int server_side; - PyObject *hostname_obj = Py_None; - PyObject *owner = Py_None; - PyObject *session = Py_None; - + PySSLMemoryBIO *incoming; + PySSLMemoryBIO *outgoing; + int server_side; + PyObject *hostname_obj = Py_None; + PyObject *owner = Py_None; + PyObject *session = Py_None; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 4, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!PyObject_TypeCheck(args[0], &PySSLMemoryBIO_Type)) { _PyArg_BadArgument("_wrap_bio", "argument 'incoming'", (&PySSLMemoryBIO_Type)->tp_name, args[0]); goto exit; @@ -804,114 +804,114 @@ skip_optional_pos: } session = args[5]; skip_optional_kwonly: - return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj, owner, session); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl__SSLContext_session_stats__doc__, -"session_stats($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_SESSION_STATS_METHODDEF \ - {"session_stats", (PyCFunction)_ssl__SSLContext_session_stats, METH_NOARGS, _ssl__SSLContext_session_stats__doc__}, - -static PyObject * -_ssl__SSLContext_session_stats_impl(PySSLContext *self); - -static PyObject * -_ssl__SSLContext_session_stats(PySSLContext *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLContext_session_stats_impl(self); -} - -PyDoc_STRVAR(_ssl__SSLContext_set_default_verify_paths__doc__, -"set_default_verify_paths($self, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_SET_DEFAULT_VERIFY_PATHS_METHODDEF \ - {"set_default_verify_paths", (PyCFunction)_ssl__SSLContext_set_default_verify_paths, METH_NOARGS, _ssl__SSLContext_set_default_verify_paths__doc__}, - -static PyObject * -_ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self); - -static PyObject * -_ssl__SSLContext_set_default_verify_paths(PySSLContext *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLContext_set_default_verify_paths_impl(self); -} - -#if !defined(OPENSSL_NO_ECDH) - -PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, -"set_ecdh_curve($self, name, /)\n" -"--\n" -"\n"); - -#define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF \ - {"set_ecdh_curve", (PyCFunction)_ssl__SSLContext_set_ecdh_curve, METH_O, _ssl__SSLContext_set_ecdh_curve__doc__}, - -#endif /* !defined(OPENSSL_NO_ECDH) */ - -PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__, -"cert_store_stats($self, /)\n" -"--\n" -"\n" -"Returns quantities of loaded X.509 certificates.\n" -"\n" -"X.509 certificates with a CA extension and certificate revocation lists\n" -"inside the context\'s cert store.\n" -"\n" -"NOTE: Certificates in a capath directory aren\'t loaded unless they have\n" -"been used at least once."); - -#define _SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF \ - {"cert_store_stats", (PyCFunction)_ssl__SSLContext_cert_store_stats, METH_NOARGS, _ssl__SSLContext_cert_store_stats__doc__}, - -static PyObject * -_ssl__SSLContext_cert_store_stats_impl(PySSLContext *self); - -static PyObject * -_ssl__SSLContext_cert_store_stats(PySSLContext *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl__SSLContext_cert_store_stats_impl(self); -} - -PyDoc_STRVAR(_ssl__SSLContext_get_ca_certs__doc__, -"get_ca_certs($self, /, binary_form=False)\n" -"--\n" -"\n" -"Returns a list of dicts with information of loaded CA certs.\n" -"\n" -"If the optional argument is True, returns a DER-encoded copy of the CA\n" -"certificate.\n" -"\n" -"NOTE: Certificates in a capath directory aren\'t loaded unless they have\n" -"been used at least once."); - -#define _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF \ + return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj, owner, session); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_session_stats__doc__, +"session_stats($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SESSION_STATS_METHODDEF \ + {"session_stats", (PyCFunction)_ssl__SSLContext_session_stats, METH_NOARGS, _ssl__SSLContext_session_stats__doc__}, + +static PyObject * +_ssl__SSLContext_session_stats_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_session_stats(PySSLContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLContext_session_stats_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLContext_set_default_verify_paths__doc__, +"set_default_verify_paths($self, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SET_DEFAULT_VERIFY_PATHS_METHODDEF \ + {"set_default_verify_paths", (PyCFunction)_ssl__SSLContext_set_default_verify_paths, METH_NOARGS, _ssl__SSLContext_set_default_verify_paths__doc__}, + +static PyObject * +_ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_set_default_verify_paths(PySSLContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLContext_set_default_verify_paths_impl(self); +} + +#if !defined(OPENSSL_NO_ECDH) + +PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, +"set_ecdh_curve($self, name, /)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF \ + {"set_ecdh_curve", (PyCFunction)_ssl__SSLContext_set_ecdh_curve, METH_O, _ssl__SSLContext_set_ecdh_curve__doc__}, + +#endif /* !defined(OPENSSL_NO_ECDH) */ + +PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__, +"cert_store_stats($self, /)\n" +"--\n" +"\n" +"Returns quantities of loaded X.509 certificates.\n" +"\n" +"X.509 certificates with a CA extension and certificate revocation lists\n" +"inside the context\'s cert store.\n" +"\n" +"NOTE: Certificates in a capath directory aren\'t loaded unless they have\n" +"been used at least once."); + +#define _SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF \ + {"cert_store_stats", (PyCFunction)_ssl__SSLContext_cert_store_stats, METH_NOARGS, _ssl__SSLContext_cert_store_stats__doc__}, + +static PyObject * +_ssl__SSLContext_cert_store_stats_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_cert_store_stats(PySSLContext *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLContext_cert_store_stats_impl(self); +} + +PyDoc_STRVAR(_ssl__SSLContext_get_ca_certs__doc__, +"get_ca_certs($self, /, binary_form=False)\n" +"--\n" +"\n" +"Returns a list of dicts with information of loaded CA certs.\n" +"\n" +"If the optional argument is True, returns a DER-encoded copy of the CA\n" +"certificate.\n" +"\n" +"NOTE: Certificates in a capath directory aren\'t loaded unless they have\n" +"been used at least once."); + +#define _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF \ {"get_ca_certs", (PyCFunction)(void(*)(void))_ssl__SSLContext_get_ca_certs, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_get_ca_certs__doc__}, - -static PyObject * -_ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form); - -static PyObject * -_ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"binary_form", NULL}; + +static PyObject * +_ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form); + +static PyObject * +_ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"binary_form", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "get_ca_certs", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - int binary_form = 0; - + int binary_form = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -920,60 +920,60 @@ _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssiz goto exit; } skip_optional_pos: - return_value = _ssl__SSLContext_get_ca_certs_impl(self, binary_form); - -exit: - return return_value; -} - -static PyObject * -_ssl_MemoryBIO_impl(PyTypeObject *type); - -static PyObject * -_ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - - if ((type == &PySSLMemoryBIO_Type) && - !_PyArg_NoPositional("MemoryBIO", args)) { - goto exit; - } - if ((type == &PySSLMemoryBIO_Type) && - !_PyArg_NoKeywords("MemoryBIO", kwargs)) { - goto exit; - } - return_value = _ssl_MemoryBIO_impl(type); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl_MemoryBIO_read__doc__, -"read($self, size=-1, /)\n" -"--\n" -"\n" -"Read up to size bytes from the memory BIO.\n" -"\n" -"If size is not specified, read the entire buffer.\n" -"If the return value is an empty bytes instance, this means either\n" -"EOF or that no data is available. Use the \"eof\" property to\n" -"distinguish between the two."); - -#define _SSL_MEMORYBIO_READ_METHODDEF \ + return_value = _ssl__SSLContext_get_ca_certs_impl(self, binary_form); + +exit: + return return_value; +} + +static PyObject * +_ssl_MemoryBIO_impl(PyTypeObject *type); + +static PyObject * +_ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + + if ((type == &PySSLMemoryBIO_Type) && + !_PyArg_NoPositional("MemoryBIO", args)) { + goto exit; + } + if ((type == &PySSLMemoryBIO_Type) && + !_PyArg_NoKeywords("MemoryBIO", kwargs)) { + goto exit; + } + return_value = _ssl_MemoryBIO_impl(type); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl_MemoryBIO_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n" +"Read up to size bytes from the memory BIO.\n" +"\n" +"If size is not specified, read the entire buffer.\n" +"If the return value is an empty bytes instance, this means either\n" +"EOF or that no data is available. Use the \"eof\" property to\n" +"distinguish between the two."); + +#define _SSL_MEMORYBIO_READ_METHODDEF \ {"read", (PyCFunction)(void(*)(void))_ssl_MemoryBIO_read, METH_FASTCALL, _ssl_MemoryBIO_read__doc__}, - -static PyObject * -_ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len); - -static PyObject * -_ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int len = -1; - + +static PyObject * +_ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len); + +static PyObject * +_ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int len = -1; + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -987,95 +987,95 @@ _ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *const *args, Py_ssize_t narg goto exit; } skip_optional: - return_value = _ssl_MemoryBIO_read_impl(self, len); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl_MemoryBIO_write__doc__, -"write($self, b, /)\n" -"--\n" -"\n" -"Writes the bytes b into the memory BIO.\n" -"\n" -"Returns the number of bytes written."); - -#define _SSL_MEMORYBIO_WRITE_METHODDEF \ - {"write", (PyCFunction)_ssl_MemoryBIO_write, METH_O, _ssl_MemoryBIO_write__doc__}, - -static PyObject * -_ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b); - -static PyObject * -_ssl_MemoryBIO_write(PySSLMemoryBIO *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer b = {NULL, NULL}; - + return_value = _ssl_MemoryBIO_read_impl(self, len); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl_MemoryBIO_write__doc__, +"write($self, b, /)\n" +"--\n" +"\n" +"Writes the bytes b into the memory BIO.\n" +"\n" +"Returns the number of bytes written."); + +#define _SSL_MEMORYBIO_WRITE_METHODDEF \ + {"write", (PyCFunction)_ssl_MemoryBIO_write, METH_O, _ssl_MemoryBIO_write__doc__}, + +static PyObject * +_ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b); + +static PyObject * +_ssl_MemoryBIO_write(PySSLMemoryBIO *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer b = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&b, 'C')) { _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); goto exit; } - return_value = _ssl_MemoryBIO_write_impl(self, &b); - -exit: - /* Cleanup for b */ - if (b.obj) { - PyBuffer_Release(&b); - } - - return return_value; -} - -PyDoc_STRVAR(_ssl_MemoryBIO_write_eof__doc__, -"write_eof($self, /)\n" -"--\n" -"\n" -"Write an EOF marker to the memory BIO.\n" -"\n" -"When all data has been read, the \"eof\" property will be True."); - -#define _SSL_MEMORYBIO_WRITE_EOF_METHODDEF \ - {"write_eof", (PyCFunction)_ssl_MemoryBIO_write_eof, METH_NOARGS, _ssl_MemoryBIO_write_eof__doc__}, - -static PyObject * -_ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self); - -static PyObject * -_ssl_MemoryBIO_write_eof(PySSLMemoryBIO *self, PyObject *Py_UNUSED(ignored)) -{ - return _ssl_MemoryBIO_write_eof_impl(self); -} - -PyDoc_STRVAR(_ssl_RAND_add__doc__, -"RAND_add($module, string, entropy, /)\n" -"--\n" -"\n" -"Mix string into the OpenSSL PRNG state.\n" -"\n" -"entropy (a float) is a lower bound on the entropy contained in\n" -"string. See RFC 4086."); - -#define _SSL_RAND_ADD_METHODDEF \ + return_value = _ssl_MemoryBIO_write_impl(self, &b); + +exit: + /* Cleanup for b */ + if (b.obj) { + PyBuffer_Release(&b); + } + + return return_value; +} + +PyDoc_STRVAR(_ssl_MemoryBIO_write_eof__doc__, +"write_eof($self, /)\n" +"--\n" +"\n" +"Write an EOF marker to the memory BIO.\n" +"\n" +"When all data has been read, the \"eof\" property will be True."); + +#define _SSL_MEMORYBIO_WRITE_EOF_METHODDEF \ + {"write_eof", (PyCFunction)_ssl_MemoryBIO_write_eof, METH_NOARGS, _ssl_MemoryBIO_write_eof__doc__}, + +static PyObject * +_ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self); + +static PyObject * +_ssl_MemoryBIO_write_eof(PySSLMemoryBIO *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl_MemoryBIO_write_eof_impl(self); +} + +PyDoc_STRVAR(_ssl_RAND_add__doc__, +"RAND_add($module, string, entropy, /)\n" +"--\n" +"\n" +"Mix string into the OpenSSL PRNG state.\n" +"\n" +"entropy (a float) is a lower bound on the entropy contained in\n" +"string. See RFC 4086."); + +#define _SSL_RAND_ADD_METHODDEF \ {"RAND_add", (PyCFunction)(void(*)(void))_ssl_RAND_add, METH_FASTCALL, _ssl_RAND_add__doc__}, - -static PyObject * -_ssl_RAND_add_impl(PyObject *module, Py_buffer *view, double entropy); - -static PyObject * -_ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer view = {NULL, NULL}; - double entropy; - + +static PyObject * +_ssl_RAND_add_impl(PyObject *module, Py_buffer *view, double entropy); + +static PyObject * +_ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer view = {NULL, NULL}; + double entropy; + if (!_PyArg_CheckPositional("RAND_add", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyUnicode_Check(args[0])) { Py_ssize_t len; const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); @@ -1103,191 +1103,191 @@ _ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - return_value = _ssl_RAND_add_impl(module, &view, entropy); - -exit: - /* Cleanup for view */ - if (view.obj) { - PyBuffer_Release(&view); - } - - return return_value; -} - -PyDoc_STRVAR(_ssl_RAND_bytes__doc__, -"RAND_bytes($module, n, /)\n" -"--\n" -"\n" -"Generate n cryptographically strong pseudo-random bytes."); - -#define _SSL_RAND_BYTES_METHODDEF \ - {"RAND_bytes", (PyCFunction)_ssl_RAND_bytes, METH_O, _ssl_RAND_bytes__doc__}, - -static PyObject * -_ssl_RAND_bytes_impl(PyObject *module, int n); - -static PyObject * -_ssl_RAND_bytes(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int n; - + return_value = _ssl_RAND_add_impl(module, &view, entropy); + +exit: + /* Cleanup for view */ + if (view.obj) { + PyBuffer_Release(&view); + } + + return return_value; +} + +PyDoc_STRVAR(_ssl_RAND_bytes__doc__, +"RAND_bytes($module, n, /)\n" +"--\n" +"\n" +"Generate n cryptographically strong pseudo-random bytes."); + +#define _SSL_RAND_BYTES_METHODDEF \ + {"RAND_bytes", (PyCFunction)_ssl_RAND_bytes, METH_O, _ssl_RAND_bytes__doc__}, + +static PyObject * +_ssl_RAND_bytes_impl(PyObject *module, int n); + +static PyObject * +_ssl_RAND_bytes(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int n; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } n = _PyLong_AsInt(arg); if (n == -1 && PyErr_Occurred()) { goto exit; } - return_value = _ssl_RAND_bytes_impl(module, n); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl_RAND_pseudo_bytes__doc__, -"RAND_pseudo_bytes($module, n, /)\n" -"--\n" -"\n" -"Generate n pseudo-random bytes.\n" -"\n" -"Return a pair (bytes, is_cryptographic). is_cryptographic is True\n" -"if the bytes generated are cryptographically strong."); - -#define _SSL_RAND_PSEUDO_BYTES_METHODDEF \ - {"RAND_pseudo_bytes", (PyCFunction)_ssl_RAND_pseudo_bytes, METH_O, _ssl_RAND_pseudo_bytes__doc__}, - -static PyObject * -_ssl_RAND_pseudo_bytes_impl(PyObject *module, int n); - -static PyObject * -_ssl_RAND_pseudo_bytes(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int n; - + return_value = _ssl_RAND_bytes_impl(module, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl_RAND_pseudo_bytes__doc__, +"RAND_pseudo_bytes($module, n, /)\n" +"--\n" +"\n" +"Generate n pseudo-random bytes.\n" +"\n" +"Return a pair (bytes, is_cryptographic). is_cryptographic is True\n" +"if the bytes generated are cryptographically strong."); + +#define _SSL_RAND_PSEUDO_BYTES_METHODDEF \ + {"RAND_pseudo_bytes", (PyCFunction)_ssl_RAND_pseudo_bytes, METH_O, _ssl_RAND_pseudo_bytes__doc__}, + +static PyObject * +_ssl_RAND_pseudo_bytes_impl(PyObject *module, int n); + +static PyObject * +_ssl_RAND_pseudo_bytes(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int n; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } n = _PyLong_AsInt(arg); if (n == -1 && PyErr_Occurred()) { goto exit; } - return_value = _ssl_RAND_pseudo_bytes_impl(module, n); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl_RAND_status__doc__, -"RAND_status($module, /)\n" -"--\n" -"\n" -"Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n" -"\n" -"It is necessary to seed the PRNG with RAND_add() on some platforms before\n" -"using the ssl() function."); - -#define _SSL_RAND_STATUS_METHODDEF \ - {"RAND_status", (PyCFunction)_ssl_RAND_status, METH_NOARGS, _ssl_RAND_status__doc__}, - -static PyObject * -_ssl_RAND_status_impl(PyObject *module); - -static PyObject * -_ssl_RAND_status(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _ssl_RAND_status_impl(module); -} - -#if !defined(OPENSSL_NO_EGD) - -PyDoc_STRVAR(_ssl_RAND_egd__doc__, -"RAND_egd($module, path, /)\n" -"--\n" -"\n" -"Queries the entropy gather daemon (EGD) on the socket named by \'path\'.\n" -"\n" -"Returns number of bytes read. Raises SSLError if connection to EGD\n" -"fails or if it does not provide enough data to seed PRNG."); - -#define _SSL_RAND_EGD_METHODDEF \ - {"RAND_egd", (PyCFunction)_ssl_RAND_egd, METH_O, _ssl_RAND_egd__doc__}, - -static PyObject * -_ssl_RAND_egd_impl(PyObject *module, PyObject *path); - -static PyObject * -_ssl_RAND_egd(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *path; - + return_value = _ssl_RAND_pseudo_bytes_impl(module, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl_RAND_status__doc__, +"RAND_status($module, /)\n" +"--\n" +"\n" +"Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n" +"\n" +"It is necessary to seed the PRNG with RAND_add() on some platforms before\n" +"using the ssl() function."); + +#define _SSL_RAND_STATUS_METHODDEF \ + {"RAND_status", (PyCFunction)_ssl_RAND_status, METH_NOARGS, _ssl_RAND_status__doc__}, + +static PyObject * +_ssl_RAND_status_impl(PyObject *module); + +static PyObject * +_ssl_RAND_status(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _ssl_RAND_status_impl(module); +} + +#if !defined(OPENSSL_NO_EGD) + +PyDoc_STRVAR(_ssl_RAND_egd__doc__, +"RAND_egd($module, path, /)\n" +"--\n" +"\n" +"Queries the entropy gather daemon (EGD) on the socket named by \'path\'.\n" +"\n" +"Returns number of bytes read. Raises SSLError if connection to EGD\n" +"fails or if it does not provide enough data to seed PRNG."); + +#define _SSL_RAND_EGD_METHODDEF \ + {"RAND_egd", (PyCFunction)_ssl_RAND_egd, METH_O, _ssl_RAND_egd__doc__}, + +static PyObject * +_ssl_RAND_egd_impl(PyObject *module, PyObject *path); + +static PyObject * +_ssl_RAND_egd(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *path; + if (!PyUnicode_FSConverter(arg, &path)) { - goto exit; - } - return_value = _ssl_RAND_egd_impl(module, path); - -exit: - return return_value; -} - -#endif /* !defined(OPENSSL_NO_EGD) */ - -PyDoc_STRVAR(_ssl_get_default_verify_paths__doc__, -"get_default_verify_paths($module, /)\n" -"--\n" -"\n" -"Return search paths and environment vars that are used by SSLContext\'s set_default_verify_paths() to load default CAs.\n" -"\n" -"The values are \'cert_file_env\', \'cert_file\', \'cert_dir_env\', \'cert_dir\'."); - -#define _SSL_GET_DEFAULT_VERIFY_PATHS_METHODDEF \ - {"get_default_verify_paths", (PyCFunction)_ssl_get_default_verify_paths, METH_NOARGS, _ssl_get_default_verify_paths__doc__}, - -static PyObject * -_ssl_get_default_verify_paths_impl(PyObject *module); - -static PyObject * -_ssl_get_default_verify_paths(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _ssl_get_default_verify_paths_impl(module); -} - -PyDoc_STRVAR(_ssl_txt2obj__doc__, -"txt2obj($module, /, txt, name=False)\n" -"--\n" -"\n" -"Lookup NID, short name, long name and OID of an ASN1_OBJECT.\n" -"\n" -"By default objects are looked up by OID. With name=True short and\n" -"long name are also matched."); - -#define _SSL_TXT2OBJ_METHODDEF \ + goto exit; + } + return_value = _ssl_RAND_egd_impl(module, path); + +exit: + return return_value; +} + +#endif /* !defined(OPENSSL_NO_EGD) */ + +PyDoc_STRVAR(_ssl_get_default_verify_paths__doc__, +"get_default_verify_paths($module, /)\n" +"--\n" +"\n" +"Return search paths and environment vars that are used by SSLContext\'s set_default_verify_paths() to load default CAs.\n" +"\n" +"The values are \'cert_file_env\', \'cert_file\', \'cert_dir_env\', \'cert_dir\'."); + +#define _SSL_GET_DEFAULT_VERIFY_PATHS_METHODDEF \ + {"get_default_verify_paths", (PyCFunction)_ssl_get_default_verify_paths, METH_NOARGS, _ssl_get_default_verify_paths__doc__}, + +static PyObject * +_ssl_get_default_verify_paths_impl(PyObject *module); + +static PyObject * +_ssl_get_default_verify_paths(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _ssl_get_default_verify_paths_impl(module); +} + +PyDoc_STRVAR(_ssl_txt2obj__doc__, +"txt2obj($module, /, txt, name=False)\n" +"--\n" +"\n" +"Lookup NID, short name, long name and OID of an ASN1_OBJECT.\n" +"\n" +"By default objects are looked up by OID. With name=True short and\n" +"long name are also matched."); + +#define _SSL_TXT2OBJ_METHODDEF \ {"txt2obj", (PyCFunction)(void(*)(void))_ssl_txt2obj, METH_FASTCALL|METH_KEYWORDS, _ssl_txt2obj__doc__}, - -static PyObject * -_ssl_txt2obj_impl(PyObject *module, const char *txt, int name); - -static PyObject * -_ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"txt", "name", NULL}; + +static PyObject * +_ssl_txt2obj_impl(PyObject *module, const char *txt, int name); + +static PyObject * +_ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"txt", "name", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "txt2obj", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - const char *txt; - int name = 0; - + const char *txt; + int name = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("txt2obj", "argument 'txt'", "str", args[0]); goto exit; @@ -1309,78 +1309,78 @@ _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } skip_optional_pos: - return_value = _ssl_txt2obj_impl(module, txt, name); - -exit: - return return_value; -} - -PyDoc_STRVAR(_ssl_nid2obj__doc__, -"nid2obj($module, nid, /)\n" -"--\n" -"\n" -"Lookup NID, short name, long name and OID of an ASN1_OBJECT by NID."); - -#define _SSL_NID2OBJ_METHODDEF \ - {"nid2obj", (PyCFunction)_ssl_nid2obj, METH_O, _ssl_nid2obj__doc__}, - -static PyObject * -_ssl_nid2obj_impl(PyObject *module, int nid); - -static PyObject * -_ssl_nid2obj(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int nid; - + return_value = _ssl_txt2obj_impl(module, txt, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl_nid2obj__doc__, +"nid2obj($module, nid, /)\n" +"--\n" +"\n" +"Lookup NID, short name, long name and OID of an ASN1_OBJECT by NID."); + +#define _SSL_NID2OBJ_METHODDEF \ + {"nid2obj", (PyCFunction)_ssl_nid2obj, METH_O, _ssl_nid2obj__doc__}, + +static PyObject * +_ssl_nid2obj_impl(PyObject *module, int nid); + +static PyObject * +_ssl_nid2obj(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int nid; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } nid = _PyLong_AsInt(arg); if (nid == -1 && PyErr_Occurred()) { goto exit; } - return_value = _ssl_nid2obj_impl(module, nid); - -exit: - return return_value; -} - -#if defined(_MSC_VER) - -PyDoc_STRVAR(_ssl_enum_certificates__doc__, -"enum_certificates($module, /, store_name)\n" -"--\n" -"\n" -"Retrieve certificates from Windows\' cert store.\n" -"\n" -"store_name may be one of \'CA\', \'ROOT\' or \'MY\'. The system may provide\n" -"more cert storages, too. The function returns a list of (bytes,\n" -"encoding_type, trust) tuples. The encoding_type flag can be interpreted\n" -"with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either\n" -"a set of OIDs or the boolean True."); - -#define _SSL_ENUM_CERTIFICATES_METHODDEF \ + return_value = _ssl_nid2obj_impl(module, nid); + +exit: + return return_value; +} + +#if defined(_MSC_VER) + +PyDoc_STRVAR(_ssl_enum_certificates__doc__, +"enum_certificates($module, /, store_name)\n" +"--\n" +"\n" +"Retrieve certificates from Windows\' cert store.\n" +"\n" +"store_name may be one of \'CA\', \'ROOT\' or \'MY\'. The system may provide\n" +"more cert storages, too. The function returns a list of (bytes,\n" +"encoding_type, trust) tuples. The encoding_type flag can be interpreted\n" +"with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either\n" +"a set of OIDs or the boolean True."); + +#define _SSL_ENUM_CERTIFICATES_METHODDEF \ {"enum_certificates", (PyCFunction)(void(*)(void))_ssl_enum_certificates, METH_FASTCALL|METH_KEYWORDS, _ssl_enum_certificates__doc__}, - -static PyObject * -_ssl_enum_certificates_impl(PyObject *module, const char *store_name); - -static PyObject * -_ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"store_name", NULL}; + +static PyObject * +_ssl_enum_certificates_impl(PyObject *module, const char *store_name); + +static PyObject * +_ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"store_name", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "enum_certificates", 0}; PyObject *argsbuf[1]; - const char *store_name; - + const char *store_name; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("enum_certificates", "argument 'store_name'", "str", args[0]); goto exit; @@ -1394,46 +1394,46 @@ _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _ssl_enum_certificates_impl(module, store_name); - -exit: - return return_value; -} - -#endif /* defined(_MSC_VER) */ - -#if defined(_MSC_VER) - -PyDoc_STRVAR(_ssl_enum_crls__doc__, -"enum_crls($module, /, store_name)\n" -"--\n" -"\n" -"Retrieve CRLs from Windows\' cert store.\n" -"\n" -"store_name may be one of \'CA\', \'ROOT\' or \'MY\'. The system may provide\n" -"more cert storages, too. The function returns a list of (bytes,\n" -"encoding_type) tuples. The encoding_type flag can be interpreted with\n" -"X509_ASN_ENCODING or PKCS_7_ASN_ENCODING."); - -#define _SSL_ENUM_CRLS_METHODDEF \ + return_value = _ssl_enum_certificates_impl(module, store_name); + +exit: + return return_value; +} + +#endif /* defined(_MSC_VER) */ + +#if defined(_MSC_VER) + +PyDoc_STRVAR(_ssl_enum_crls__doc__, +"enum_crls($module, /, store_name)\n" +"--\n" +"\n" +"Retrieve CRLs from Windows\' cert store.\n" +"\n" +"store_name may be one of \'CA\', \'ROOT\' or \'MY\'. The system may provide\n" +"more cert storages, too. The function returns a list of (bytes,\n" +"encoding_type) tuples. The encoding_type flag can be interpreted with\n" +"X509_ASN_ENCODING or PKCS_7_ASN_ENCODING."); + +#define _SSL_ENUM_CRLS_METHODDEF \ {"enum_crls", (PyCFunction)(void(*)(void))_ssl_enum_crls, METH_FASTCALL|METH_KEYWORDS, _ssl_enum_crls__doc__}, - -static PyObject * -_ssl_enum_crls_impl(PyObject *module, const char *store_name); - -static PyObject * -_ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"store_name", NULL}; + +static PyObject * +_ssl_enum_crls_impl(PyObject *module, const char *store_name); + +static PyObject * +_ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"store_name", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "enum_crls", 0}; PyObject *argsbuf[1]; - const char *store_name; - + const char *store_name; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("enum_crls", "argument 'store_name'", "str", args[0]); goto exit; @@ -1447,39 +1447,39 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _ssl_enum_crls_impl(module, store_name); - -exit: - return return_value; -} - -#endif /* defined(_MSC_VER) */ - -#ifndef _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF - #define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF -#endif /* !defined(_SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF) */ - -#ifndef _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF - #define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF -#endif /* !defined(_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF) */ - -#ifndef _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF - #define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF -#endif /* !defined(_SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF) */ - -#ifndef _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF - #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF -#endif /* !defined(_SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF) */ - -#ifndef _SSL_RAND_EGD_METHODDEF - #define _SSL_RAND_EGD_METHODDEF -#endif /* !defined(_SSL_RAND_EGD_METHODDEF) */ - -#ifndef _SSL_ENUM_CERTIFICATES_METHODDEF - #define _SSL_ENUM_CERTIFICATES_METHODDEF -#endif /* !defined(_SSL_ENUM_CERTIFICATES_METHODDEF) */ - -#ifndef _SSL_ENUM_CRLS_METHODDEF - #define _SSL_ENUM_CRLS_METHODDEF -#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ + return_value = _ssl_enum_crls_impl(module, store_name); + +exit: + return return_value; +} + +#endif /* defined(_MSC_VER) */ + +#ifndef _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF + #define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF +#endif /* !defined(_SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF) */ + +#ifndef _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF + #define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF +#endif /* !defined(_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF) */ + +#ifndef _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF + #define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF +#endif /* !defined(_SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF) */ + +#ifndef _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF + #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF +#endif /* !defined(_SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF) */ + +#ifndef _SSL_RAND_EGD_METHODDEF + #define _SSL_RAND_EGD_METHODDEF +#endif /* !defined(_SSL_RAND_EGD_METHODDEF) */ + +#ifndef _SSL_ENUM_CERTIFICATES_METHODDEF + #define _SSL_ENUM_CERTIFICATES_METHODDEF +#endif /* !defined(_SSL_ENUM_CERTIFICATES_METHODDEF) */ + +#ifndef _SSL_ENUM_CRLS_METHODDEF + #define _SSL_ENUM_CRLS_METHODDEF +#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ /*[clinic end generated code: output=a4aeb3f92a091c64 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_struct.c.h b/contrib/tools/python3/src/Modules/clinic/_struct.c.h index 36c4b4046cd..dd0df47e5a7 100644 --- a/contrib/tools/python3/src/Modules/clinic/_struct.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_struct.c.h @@ -1,119 +1,119 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(Struct___init____doc__, -"Struct(format)\n" -"--\n" -"\n" -"Create a compiled struct object.\n" -"\n" -"Return a new Struct object which writes and reads binary data according to\n" -"the format string.\n" -"\n" -"See help(struct) for more on format strings."); - -static int -Struct___init___impl(PyStructObject *self, PyObject *format); - -static int -Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - static const char * const _keywords[] = {"format", NULL}; +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(Struct___init____doc__, +"Struct(format)\n" +"--\n" +"\n" +"Create a compiled struct object.\n" +"\n" +"Return a new Struct object which writes and reads binary data according to\n" +"the format string.\n" +"\n" +"See help(struct) for more on format strings."); + +static int +Struct___init___impl(PyStructObject *self, PyObject *format); + +static int +Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static const char * const _keywords[] = {"format", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "Struct", 0}; PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); - PyObject *format; - + PyObject *format; + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); if (!fastargs) { - goto exit; - } + goto exit; + } format = fastargs[0]; - return_value = Struct___init___impl((PyStructObject *)self, format); - -exit: - return return_value; -} - -PyDoc_STRVAR(Struct_unpack__doc__, -"unpack($self, buffer, /)\n" -"--\n" -"\n" -"Return a tuple containing unpacked values.\n" -"\n" -"Unpack according to the format string Struct.format. The buffer\'s size\n" -"in bytes must be Struct.size.\n" -"\n" -"See help(struct) for more on format strings."); - -#define STRUCT_UNPACK_METHODDEF \ - {"unpack", (PyCFunction)Struct_unpack, METH_O, Struct_unpack__doc__}, - -static PyObject * -Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer); - -static PyObject * -Struct_unpack(PyStructObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + return_value = Struct___init___impl((PyStructObject *)self, format); + +exit: + return return_value; +} + +PyDoc_STRVAR(Struct_unpack__doc__, +"unpack($self, buffer, /)\n" +"--\n" +"\n" +"Return a tuple containing unpacked values.\n" +"\n" +"Unpack according to the format string Struct.format. The buffer\'s size\n" +"in bytes must be Struct.size.\n" +"\n" +"See help(struct) for more on format strings."); + +#define STRUCT_UNPACK_METHODDEF \ + {"unpack", (PyCFunction)Struct_unpack, METH_O, Struct_unpack__doc__}, + +static PyObject * +Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer); + +static PyObject * +Struct_unpack(PyStructObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("unpack", "argument", "contiguous buffer", arg); goto exit; } - return_value = Struct_unpack_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(Struct_unpack_from__doc__, -"unpack_from($self, /, buffer, offset=0)\n" -"--\n" -"\n" -"Return a tuple containing unpacked values.\n" -"\n" -"Values are unpacked according to the format string Struct.format.\n" -"\n" + return_value = Struct_unpack_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(Struct_unpack_from__doc__, +"unpack_from($self, /, buffer, offset=0)\n" +"--\n" +"\n" +"Return a tuple containing unpacked values.\n" +"\n" +"Values are unpacked according to the format string Struct.format.\n" +"\n" "The buffer\'s size in bytes, starting at position offset, must be\n" "at least Struct.size.\n" -"\n" -"See help(struct) for more on format strings."); - -#define STRUCT_UNPACK_FROM_METHODDEF \ +"\n" +"See help(struct) for more on format strings."); + +#define STRUCT_UNPACK_FROM_METHODDEF \ {"unpack_from", (PyCFunction)(void(*)(void))Struct_unpack_from, METH_FASTCALL|METH_KEYWORDS, Struct_unpack_from__doc__}, - -static PyObject * -Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, - Py_ssize_t offset); - -static PyObject * -Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"buffer", "offset", NULL}; + +static PyObject * +Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, + Py_ssize_t offset); + +static PyObject * +Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"buffer", "offset", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "unpack_from", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer buffer = {NULL, NULL}; - Py_ssize_t offset = 0; - + Py_buffer buffer = {NULL, NULL}; + Py_ssize_t offset = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &buffer, PyBUF_SIMPLE) != 0) { goto exit; } @@ -142,110 +142,110 @@ Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs offset = ival; } skip_optional_pos: - return_value = Struct_unpack_from_impl(self, &buffer, offset); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(Struct_iter_unpack__doc__, -"iter_unpack($self, buffer, /)\n" -"--\n" -"\n" -"Return an iterator yielding tuples.\n" -"\n" -"Tuples are unpacked from the given bytes source, like a repeated\n" -"invocation of unpack_from().\n" -"\n" -"Requires that the bytes length be a multiple of the struct size."); - -#define STRUCT_ITER_UNPACK_METHODDEF \ - {"iter_unpack", (PyCFunction)Struct_iter_unpack, METH_O, Struct_iter_unpack__doc__}, - -PyDoc_STRVAR(_clearcache__doc__, -"_clearcache($module, /)\n" -"--\n" -"\n" -"Clear the internal cache."); - -#define _CLEARCACHE_METHODDEF \ - {"_clearcache", (PyCFunction)_clearcache, METH_NOARGS, _clearcache__doc__}, - -static PyObject * -_clearcache_impl(PyObject *module); - -static PyObject * -_clearcache(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _clearcache_impl(module); -} - -PyDoc_STRVAR(calcsize__doc__, -"calcsize($module, format, /)\n" -"--\n" -"\n" -"Return size in bytes of the struct described by the format string."); - -#define CALCSIZE_METHODDEF \ - {"calcsize", (PyCFunction)calcsize, METH_O, calcsize__doc__}, - -static Py_ssize_t -calcsize_impl(PyObject *module, PyStructObject *s_object); - -static PyObject * -calcsize(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyStructObject *s_object = NULL; - Py_ssize_t _return_value; - + return_value = Struct_unpack_from_impl(self, &buffer, offset); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(Struct_iter_unpack__doc__, +"iter_unpack($self, buffer, /)\n" +"--\n" +"\n" +"Return an iterator yielding tuples.\n" +"\n" +"Tuples are unpacked from the given bytes source, like a repeated\n" +"invocation of unpack_from().\n" +"\n" +"Requires that the bytes length be a multiple of the struct size."); + +#define STRUCT_ITER_UNPACK_METHODDEF \ + {"iter_unpack", (PyCFunction)Struct_iter_unpack, METH_O, Struct_iter_unpack__doc__}, + +PyDoc_STRVAR(_clearcache__doc__, +"_clearcache($module, /)\n" +"--\n" +"\n" +"Clear the internal cache."); + +#define _CLEARCACHE_METHODDEF \ + {"_clearcache", (PyCFunction)_clearcache, METH_NOARGS, _clearcache__doc__}, + +static PyObject * +_clearcache_impl(PyObject *module); + +static PyObject * +_clearcache(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _clearcache_impl(module); +} + +PyDoc_STRVAR(calcsize__doc__, +"calcsize($module, format, /)\n" +"--\n" +"\n" +"Return size in bytes of the struct described by the format string."); + +#define CALCSIZE_METHODDEF \ + {"calcsize", (PyCFunction)calcsize, METH_O, calcsize__doc__}, + +static Py_ssize_t +calcsize_impl(PyObject *module, PyStructObject *s_object); + +static PyObject * +calcsize(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyStructObject *s_object = NULL; + Py_ssize_t _return_value; + if (!cache_struct_converter(arg, &s_object)) { - goto exit; - } - _return_value = calcsize_impl(module, s_object); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - /* Cleanup for s_object */ - Py_XDECREF(s_object); - - return return_value; -} - -PyDoc_STRVAR(unpack__doc__, -"unpack($module, format, buffer, /)\n" -"--\n" -"\n" -"Return a tuple containing values unpacked according to the format string.\n" -"\n" -"The buffer\'s size in bytes must be calcsize(format).\n" -"\n" -"See help(struct) for more on format strings."); - -#define UNPACK_METHODDEF \ + goto exit; + } + _return_value = calcsize_impl(module, s_object); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + /* Cleanup for s_object */ + Py_XDECREF(s_object); + + return return_value; +} + +PyDoc_STRVAR(unpack__doc__, +"unpack($module, format, buffer, /)\n" +"--\n" +"\n" +"Return a tuple containing values unpacked according to the format string.\n" +"\n" +"The buffer\'s size in bytes must be calcsize(format).\n" +"\n" +"See help(struct) for more on format strings."); + +#define UNPACK_METHODDEF \ {"unpack", (PyCFunction)(void(*)(void))unpack, METH_FASTCALL, unpack__doc__}, - -static PyObject * -unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer); - -static PyObject * -unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyStructObject *s_object = NULL; - Py_buffer buffer = {NULL, NULL}; - + +static PyObject * +unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer); + +static PyObject * +unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyStructObject *s_object = NULL; + Py_buffer buffer = {NULL, NULL}; + if (!_PyArg_CheckPositional("unpack", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!cache_struct_converter(args[0], &s_object)) { goto exit; } @@ -256,52 +256,52 @@ unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("unpack", "argument 2", "contiguous buffer", args[1]); goto exit; } - return_value = unpack_impl(module, s_object, &buffer); - -exit: - /* Cleanup for s_object */ - Py_XDECREF(s_object); - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(unpack_from__doc__, -"unpack_from($module, format, /, buffer, offset=0)\n" -"--\n" -"\n" -"Return a tuple containing values unpacked according to the format string.\n" -"\n" -"The buffer\'s size, minus offset, must be at least calcsize(format).\n" -"\n" -"See help(struct) for more on format strings."); - -#define UNPACK_FROM_METHODDEF \ + return_value = unpack_impl(module, s_object, &buffer); + +exit: + /* Cleanup for s_object */ + Py_XDECREF(s_object); + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(unpack_from__doc__, +"unpack_from($module, format, /, buffer, offset=0)\n" +"--\n" +"\n" +"Return a tuple containing values unpacked according to the format string.\n" +"\n" +"The buffer\'s size, minus offset, must be at least calcsize(format).\n" +"\n" +"See help(struct) for more on format strings."); + +#define UNPACK_FROM_METHODDEF \ {"unpack_from", (PyCFunction)(void(*)(void))unpack_from, METH_FASTCALL|METH_KEYWORDS, unpack_from__doc__}, - -static PyObject * -unpack_from_impl(PyObject *module, PyStructObject *s_object, - Py_buffer *buffer, Py_ssize_t offset); - -static PyObject * -unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "buffer", "offset", NULL}; + +static PyObject * +unpack_from_impl(PyObject *module, PyStructObject *s_object, + Py_buffer *buffer, Py_ssize_t offset); + +static PyObject * +unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "buffer", "offset", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "unpack_from", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - PyStructObject *s_object = NULL; - Py_buffer buffer = {NULL, NULL}; - Py_ssize_t offset = 0; - + PyStructObject *s_object = NULL; + Py_buffer buffer = {NULL, NULL}; + Py_ssize_t offset = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!cache_struct_converter(args[0], &s_object)) { goto exit; } @@ -333,57 +333,57 @@ unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject offset = ival; } skip_optional_pos: - return_value = unpack_from_impl(module, s_object, &buffer, offset); - -exit: - /* Cleanup for s_object */ - Py_XDECREF(s_object); - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(iter_unpack__doc__, -"iter_unpack($module, format, buffer, /)\n" -"--\n" -"\n" -"Return an iterator yielding tuples unpacked from the given bytes.\n" -"\n" -"The bytes are unpacked according to the format string, like\n" -"a repeated invocation of unpack_from().\n" -"\n" -"Requires that the bytes length be a multiple of the format struct size."); - -#define ITER_UNPACK_METHODDEF \ + return_value = unpack_from_impl(module, s_object, &buffer, offset); + +exit: + /* Cleanup for s_object */ + Py_XDECREF(s_object); + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(iter_unpack__doc__, +"iter_unpack($module, format, buffer, /)\n" +"--\n" +"\n" +"Return an iterator yielding tuples unpacked from the given bytes.\n" +"\n" +"The bytes are unpacked according to the format string, like\n" +"a repeated invocation of unpack_from().\n" +"\n" +"Requires that the bytes length be a multiple of the format struct size."); + +#define ITER_UNPACK_METHODDEF \ {"iter_unpack", (PyCFunction)(void(*)(void))iter_unpack, METH_FASTCALL, iter_unpack__doc__}, - -static PyObject * -iter_unpack_impl(PyObject *module, PyStructObject *s_object, - PyObject *buffer); - -static PyObject * -iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyStructObject *s_object = NULL; - PyObject *buffer; - + +static PyObject * +iter_unpack_impl(PyObject *module, PyStructObject *s_object, + PyObject *buffer); + +static PyObject * +iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyStructObject *s_object = NULL; + PyObject *buffer; + if (!_PyArg_CheckPositional("iter_unpack", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!cache_struct_converter(args[0], &s_object)) { goto exit; } buffer = args[1]; - return_value = iter_unpack_impl(module, s_object, buffer); - -exit: - /* Cleanup for s_object */ - Py_XDECREF(s_object); - - return return_value; -} + return_value = iter_unpack_impl(module, s_object, buffer); + +exit: + /* Cleanup for s_object */ + Py_XDECREF(s_object); + + return return_value; +} /*[clinic end generated code: output=6a6228cfc4b7099c input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_tkinter.c.h b/contrib/tools/python3/src/Modules/clinic/_tkinter.c.h index 73c3faeaf96..2dad35e8305 100644 --- a/contrib/tools/python3/src/Modules/clinic/_tkinter.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_tkinter.c.h @@ -1,28 +1,28 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_tkinter_tkapp_eval__doc__, -"eval($self, script, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_EVAL_METHODDEF \ - {"eval", (PyCFunction)_tkinter_tkapp_eval, METH_O, _tkinter_tkapp_eval__doc__}, - -static PyObject * -_tkinter_tkapp_eval_impl(TkappObject *self, const char *script); - -static PyObject * -_tkinter_tkapp_eval(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *script; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_tkinter_tkapp_eval__doc__, +"eval($self, script, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_EVAL_METHODDEF \ + {"eval", (PyCFunction)_tkinter_tkapp_eval, METH_O, _tkinter_tkapp_eval__doc__}, + +static PyObject * +_tkinter_tkapp_eval_impl(TkappObject *self, const char *script); + +static PyObject * +_tkinter_tkapp_eval(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *script; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("eval", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t script_length; script = PyUnicode_AsUTF8AndSize(arg, &script_length); if (script == NULL) { @@ -32,33 +32,33 @@ _tkinter_tkapp_eval(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_eval_impl(self, script); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_evalfile__doc__, -"evalfile($self, fileName, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_EVALFILE_METHODDEF \ - {"evalfile", (PyCFunction)_tkinter_tkapp_evalfile, METH_O, _tkinter_tkapp_evalfile__doc__}, - -static PyObject * -_tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName); - -static PyObject * -_tkinter_tkapp_evalfile(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *fileName; - + return_value = _tkinter_tkapp_eval_impl(self, script); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_evalfile__doc__, +"evalfile($self, fileName, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_EVALFILE_METHODDEF \ + {"evalfile", (PyCFunction)_tkinter_tkapp_evalfile, METH_O, _tkinter_tkapp_evalfile__doc__}, + +static PyObject * +_tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName); + +static PyObject * +_tkinter_tkapp_evalfile(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *fileName; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("evalfile", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t fileName_length; fileName = PyUnicode_AsUTF8AndSize(arg, &fileName_length); if (fileName == NULL) { @@ -68,33 +68,33 @@ _tkinter_tkapp_evalfile(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_evalfile_impl(self, fileName); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_record__doc__, -"record($self, script, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_RECORD_METHODDEF \ - {"record", (PyCFunction)_tkinter_tkapp_record, METH_O, _tkinter_tkapp_record__doc__}, - -static PyObject * -_tkinter_tkapp_record_impl(TkappObject *self, const char *script); - -static PyObject * -_tkinter_tkapp_record(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *script; - + return_value = _tkinter_tkapp_evalfile_impl(self, fileName); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_record__doc__, +"record($self, script, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_RECORD_METHODDEF \ + {"record", (PyCFunction)_tkinter_tkapp_record, METH_O, _tkinter_tkapp_record__doc__}, + +static PyObject * +_tkinter_tkapp_record_impl(TkappObject *self, const char *script); + +static PyObject * +_tkinter_tkapp_record(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *script; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("record", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t script_length; script = PyUnicode_AsUTF8AndSize(arg, &script_length); if (script == NULL) { @@ -104,33 +104,33 @@ _tkinter_tkapp_record(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_record_impl(self, script); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_adderrorinfo__doc__, -"adderrorinfo($self, msg, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_ADDERRORINFO_METHODDEF \ - {"adderrorinfo", (PyCFunction)_tkinter_tkapp_adderrorinfo, METH_O, _tkinter_tkapp_adderrorinfo__doc__}, - -static PyObject * -_tkinter_tkapp_adderrorinfo_impl(TkappObject *self, const char *msg); - -static PyObject * -_tkinter_tkapp_adderrorinfo(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *msg; - + return_value = _tkinter_tkapp_record_impl(self, script); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_adderrorinfo__doc__, +"adderrorinfo($self, msg, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_ADDERRORINFO_METHODDEF \ + {"adderrorinfo", (PyCFunction)_tkinter_tkapp_adderrorinfo, METH_O, _tkinter_tkapp_adderrorinfo__doc__}, + +static PyObject * +_tkinter_tkapp_adderrorinfo_impl(TkappObject *self, const char *msg); + +static PyObject * +_tkinter_tkapp_adderrorinfo(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *msg; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("adderrorinfo", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t msg_length; msg = PyUnicode_AsUTF8AndSize(arg, &msg_length); if (msg == NULL) { @@ -140,57 +140,57 @@ _tkinter_tkapp_adderrorinfo(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_adderrorinfo_impl(self, msg); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_getint__doc__, -"getint($self, arg, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_GETINT_METHODDEF \ - {"getint", (PyCFunction)_tkinter_tkapp_getint, METH_O, _tkinter_tkapp_getint__doc__}, - -PyDoc_STRVAR(_tkinter_tkapp_getdouble__doc__, -"getdouble($self, arg, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_GETDOUBLE_METHODDEF \ - {"getdouble", (PyCFunction)_tkinter_tkapp_getdouble, METH_O, _tkinter_tkapp_getdouble__doc__}, - -PyDoc_STRVAR(_tkinter_tkapp_getboolean__doc__, -"getboolean($self, arg, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_GETBOOLEAN_METHODDEF \ - {"getboolean", (PyCFunction)_tkinter_tkapp_getboolean, METH_O, _tkinter_tkapp_getboolean__doc__}, - -PyDoc_STRVAR(_tkinter_tkapp_exprstring__doc__, -"exprstring($self, s, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_EXPRSTRING_METHODDEF \ - {"exprstring", (PyCFunction)_tkinter_tkapp_exprstring, METH_O, _tkinter_tkapp_exprstring__doc__}, - -static PyObject * -_tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s); - -static PyObject * -_tkinter_tkapp_exprstring(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *s; - + return_value = _tkinter_tkapp_adderrorinfo_impl(self, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_getint__doc__, +"getint($self, arg, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_GETINT_METHODDEF \ + {"getint", (PyCFunction)_tkinter_tkapp_getint, METH_O, _tkinter_tkapp_getint__doc__}, + +PyDoc_STRVAR(_tkinter_tkapp_getdouble__doc__, +"getdouble($self, arg, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_GETDOUBLE_METHODDEF \ + {"getdouble", (PyCFunction)_tkinter_tkapp_getdouble, METH_O, _tkinter_tkapp_getdouble__doc__}, + +PyDoc_STRVAR(_tkinter_tkapp_getboolean__doc__, +"getboolean($self, arg, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_GETBOOLEAN_METHODDEF \ + {"getboolean", (PyCFunction)_tkinter_tkapp_getboolean, METH_O, _tkinter_tkapp_getboolean__doc__}, + +PyDoc_STRVAR(_tkinter_tkapp_exprstring__doc__, +"exprstring($self, s, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_EXPRSTRING_METHODDEF \ + {"exprstring", (PyCFunction)_tkinter_tkapp_exprstring, METH_O, _tkinter_tkapp_exprstring__doc__}, + +static PyObject * +_tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s); + +static PyObject * +_tkinter_tkapp_exprstring(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *s; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("exprstring", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t s_length; s = PyUnicode_AsUTF8AndSize(arg, &s_length); if (s == NULL) { @@ -200,33 +200,33 @@ _tkinter_tkapp_exprstring(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_exprstring_impl(self, s); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_exprlong__doc__, -"exprlong($self, s, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_EXPRLONG_METHODDEF \ - {"exprlong", (PyCFunction)_tkinter_tkapp_exprlong, METH_O, _tkinter_tkapp_exprlong__doc__}, - -static PyObject * -_tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s); - -static PyObject * -_tkinter_tkapp_exprlong(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *s; - + return_value = _tkinter_tkapp_exprstring_impl(self, s); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_exprlong__doc__, +"exprlong($self, s, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_EXPRLONG_METHODDEF \ + {"exprlong", (PyCFunction)_tkinter_tkapp_exprlong, METH_O, _tkinter_tkapp_exprlong__doc__}, + +static PyObject * +_tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s); + +static PyObject * +_tkinter_tkapp_exprlong(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *s; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("exprlong", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t s_length; s = PyUnicode_AsUTF8AndSize(arg, &s_length); if (s == NULL) { @@ -236,33 +236,33 @@ _tkinter_tkapp_exprlong(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_exprlong_impl(self, s); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_exprdouble__doc__, -"exprdouble($self, s, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_EXPRDOUBLE_METHODDEF \ - {"exprdouble", (PyCFunction)_tkinter_tkapp_exprdouble, METH_O, _tkinter_tkapp_exprdouble__doc__}, - -static PyObject * -_tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s); - -static PyObject * -_tkinter_tkapp_exprdouble(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *s; - + return_value = _tkinter_tkapp_exprlong_impl(self, s); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_exprdouble__doc__, +"exprdouble($self, s, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_EXPRDOUBLE_METHODDEF \ + {"exprdouble", (PyCFunction)_tkinter_tkapp_exprdouble, METH_O, _tkinter_tkapp_exprdouble__doc__}, + +static PyObject * +_tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s); + +static PyObject * +_tkinter_tkapp_exprdouble(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *s; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("exprdouble", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t s_length; s = PyUnicode_AsUTF8AndSize(arg, &s_length); if (s == NULL) { @@ -272,33 +272,33 @@ _tkinter_tkapp_exprdouble(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_exprdouble_impl(self, s); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_exprboolean__doc__, -"exprboolean($self, s, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_EXPRBOOLEAN_METHODDEF \ - {"exprboolean", (PyCFunction)_tkinter_tkapp_exprboolean, METH_O, _tkinter_tkapp_exprboolean__doc__}, - -static PyObject * -_tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s); - -static PyObject * -_tkinter_tkapp_exprboolean(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *s; - + return_value = _tkinter_tkapp_exprdouble_impl(self, s); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_exprboolean__doc__, +"exprboolean($self, s, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_EXPRBOOLEAN_METHODDEF \ + {"exprboolean", (PyCFunction)_tkinter_tkapp_exprboolean, METH_O, _tkinter_tkapp_exprboolean__doc__}, + +static PyObject * +_tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s); + +static PyObject * +_tkinter_tkapp_exprboolean(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *s; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("exprboolean", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t s_length; s = PyUnicode_AsUTF8AndSize(arg, &s_length); if (s == NULL) { @@ -308,50 +308,50 @@ _tkinter_tkapp_exprboolean(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_exprboolean_impl(self, s); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_splitlist__doc__, -"splitlist($self, arg, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_SPLITLIST_METHODDEF \ - {"splitlist", (PyCFunction)_tkinter_tkapp_splitlist, METH_O, _tkinter_tkapp_splitlist__doc__}, - -PyDoc_STRVAR(_tkinter_tkapp_split__doc__, -"split($self, arg, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_SPLIT_METHODDEF \ - {"split", (PyCFunction)_tkinter_tkapp_split, METH_O, _tkinter_tkapp_split__doc__}, - -PyDoc_STRVAR(_tkinter_tkapp_createcommand__doc__, -"createcommand($self, name, func, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_CREATECOMMAND_METHODDEF \ + return_value = _tkinter_tkapp_exprboolean_impl(self, s); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_splitlist__doc__, +"splitlist($self, arg, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_SPLITLIST_METHODDEF \ + {"splitlist", (PyCFunction)_tkinter_tkapp_splitlist, METH_O, _tkinter_tkapp_splitlist__doc__}, + +PyDoc_STRVAR(_tkinter_tkapp_split__doc__, +"split($self, arg, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_SPLIT_METHODDEF \ + {"split", (PyCFunction)_tkinter_tkapp_split, METH_O, _tkinter_tkapp_split__doc__}, + +PyDoc_STRVAR(_tkinter_tkapp_createcommand__doc__, +"createcommand($self, name, func, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_CREATECOMMAND_METHODDEF \ {"createcommand", (PyCFunction)(void(*)(void))_tkinter_tkapp_createcommand, METH_FASTCALL, _tkinter_tkapp_createcommand__doc__}, - -static PyObject * -_tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, - PyObject *func); - -static PyObject * -_tkinter_tkapp_createcommand(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *name; - PyObject *func; - + +static PyObject * +_tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, + PyObject *func); + +static PyObject * +_tkinter_tkapp_createcommand(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *name; + PyObject *func; + if (!_PyArg_CheckPositional("createcommand", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("createcommand", "argument 1", "str", args[0]); goto exit; @@ -366,33 +366,33 @@ _tkinter_tkapp_createcommand(TkappObject *self, PyObject *const *args, Py_ssize_ goto exit; } func = args[1]; - return_value = _tkinter_tkapp_createcommand_impl(self, name, func); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_deletecommand__doc__, -"deletecommand($self, name, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_DELETECOMMAND_METHODDEF \ - {"deletecommand", (PyCFunction)_tkinter_tkapp_deletecommand, METH_O, _tkinter_tkapp_deletecommand__doc__}, - -static PyObject * -_tkinter_tkapp_deletecommand_impl(TkappObject *self, const char *name); - -static PyObject * -_tkinter_tkapp_deletecommand(TkappObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *name; - + return_value = _tkinter_tkapp_createcommand_impl(self, name, func); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_deletecommand__doc__, +"deletecommand($self, name, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_DELETECOMMAND_METHODDEF \ + {"deletecommand", (PyCFunction)_tkinter_tkapp_deletecommand, METH_O, _tkinter_tkapp_deletecommand__doc__}, + +static PyObject * +_tkinter_tkapp_deletecommand_impl(TkappObject *self, const char *name); + +static PyObject * +_tkinter_tkapp_deletecommand(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *name; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("deletecommand", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t name_length; name = PyUnicode_AsUTF8AndSize(arg, &name_length); if (name == NULL) { @@ -402,37 +402,37 @@ _tkinter_tkapp_deletecommand(TkappObject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _tkinter_tkapp_deletecommand_impl(self, name); - -exit: - return return_value; -} - -#if defined(HAVE_CREATEFILEHANDLER) - -PyDoc_STRVAR(_tkinter_tkapp_createfilehandler__doc__, -"createfilehandler($self, file, mask, func, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF \ + return_value = _tkinter_tkapp_deletecommand_impl(self, name); + +exit: + return return_value; +} + +#if defined(HAVE_CREATEFILEHANDLER) + +PyDoc_STRVAR(_tkinter_tkapp_createfilehandler__doc__, +"createfilehandler($self, file, mask, func, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF \ {"createfilehandler", (PyCFunction)(void(*)(void))_tkinter_tkapp_createfilehandler, METH_FASTCALL, _tkinter_tkapp_createfilehandler__doc__}, - -static PyObject * -_tkinter_tkapp_createfilehandler_impl(TkappObject *self, PyObject *file, - int mask, PyObject *func); - -static PyObject * -_tkinter_tkapp_createfilehandler(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *file; - int mask; - PyObject *func; - + +static PyObject * +_tkinter_tkapp_createfilehandler_impl(TkappObject *self, PyObject *file, + int mask, PyObject *func); + +static PyObject * +_tkinter_tkapp_createfilehandler(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *file; + int mask; + PyObject *func; + if (!_PyArg_CheckPositional("createfilehandler", nargs, 3, 3)) { - goto exit; - } + goto exit; + } file = args[0]; if (PyFloat_Check(args[1])) { PyErr_SetString(PyExc_TypeError, @@ -444,65 +444,65 @@ _tkinter_tkapp_createfilehandler(TkappObject *self, PyObject *const *args, Py_ss goto exit; } func = args[2]; - return_value = _tkinter_tkapp_createfilehandler_impl(self, file, mask, func); - -exit: - return return_value; -} - -#endif /* defined(HAVE_CREATEFILEHANDLER) */ - -#if defined(HAVE_CREATEFILEHANDLER) - -PyDoc_STRVAR(_tkinter_tkapp_deletefilehandler__doc__, -"deletefilehandler($self, file, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF \ - {"deletefilehandler", (PyCFunction)_tkinter_tkapp_deletefilehandler, METH_O, _tkinter_tkapp_deletefilehandler__doc__}, - -#endif /* defined(HAVE_CREATEFILEHANDLER) */ - -PyDoc_STRVAR(_tkinter_tktimertoken_deletetimerhandler__doc__, -"deletetimerhandler($self, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKTIMERTOKEN_DELETETIMERHANDLER_METHODDEF \ - {"deletetimerhandler", (PyCFunction)_tkinter_tktimertoken_deletetimerhandler, METH_NOARGS, _tkinter_tktimertoken_deletetimerhandler__doc__}, - -static PyObject * -_tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self); - -static PyObject * -_tkinter_tktimertoken_deletetimerhandler(TkttObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _tkinter_tktimertoken_deletetimerhandler_impl(self); -} - -PyDoc_STRVAR(_tkinter_tkapp_createtimerhandler__doc__, -"createtimerhandler($self, milliseconds, func, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_CREATETIMERHANDLER_METHODDEF \ + return_value = _tkinter_tkapp_createfilehandler_impl(self, file, mask, func); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CREATEFILEHANDLER) */ + +#if defined(HAVE_CREATEFILEHANDLER) + +PyDoc_STRVAR(_tkinter_tkapp_deletefilehandler__doc__, +"deletefilehandler($self, file, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF \ + {"deletefilehandler", (PyCFunction)_tkinter_tkapp_deletefilehandler, METH_O, _tkinter_tkapp_deletefilehandler__doc__}, + +#endif /* defined(HAVE_CREATEFILEHANDLER) */ + +PyDoc_STRVAR(_tkinter_tktimertoken_deletetimerhandler__doc__, +"deletetimerhandler($self, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKTIMERTOKEN_DELETETIMERHANDLER_METHODDEF \ + {"deletetimerhandler", (PyCFunction)_tkinter_tktimertoken_deletetimerhandler, METH_NOARGS, _tkinter_tktimertoken_deletetimerhandler__doc__}, + +static PyObject * +_tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self); + +static PyObject * +_tkinter_tktimertoken_deletetimerhandler(TkttObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _tkinter_tktimertoken_deletetimerhandler_impl(self); +} + +PyDoc_STRVAR(_tkinter_tkapp_createtimerhandler__doc__, +"createtimerhandler($self, milliseconds, func, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_CREATETIMERHANDLER_METHODDEF \ {"createtimerhandler", (PyCFunction)(void(*)(void))_tkinter_tkapp_createtimerhandler, METH_FASTCALL, _tkinter_tkapp_createtimerhandler__doc__}, - -static PyObject * -_tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds, - PyObject *func); - -static PyObject * -_tkinter_tkapp_createtimerhandler(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int milliseconds; - PyObject *func; - + +static PyObject * +_tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds, + PyObject *func); + +static PyObject * +_tkinter_tkapp_createtimerhandler(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int milliseconds; + PyObject *func; + if (!_PyArg_CheckPositional("createtimerhandler", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -513,32 +513,32 @@ _tkinter_tkapp_createtimerhandler(TkappObject *self, PyObject *const *args, Py_s goto exit; } func = args[1]; - return_value = _tkinter_tkapp_createtimerhandler_impl(self, milliseconds, func); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_mainloop__doc__, -"mainloop($self, threshold=0, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_MAINLOOP_METHODDEF \ + return_value = _tkinter_tkapp_createtimerhandler_impl(self, milliseconds, func); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_mainloop__doc__, +"mainloop($self, threshold=0, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_MAINLOOP_METHODDEF \ {"mainloop", (PyCFunction)(void(*)(void))_tkinter_tkapp_mainloop, METH_FASTCALL, _tkinter_tkapp_mainloop__doc__}, - -static PyObject * -_tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold); - -static PyObject * -_tkinter_tkapp_mainloop(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int threshold = 0; - + +static PyObject * +_tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold); + +static PyObject * +_tkinter_tkapp_mainloop(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int threshold = 0; + if (!_PyArg_CheckPositional("mainloop", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -552,32 +552,32 @@ _tkinter_tkapp_mainloop(TkappObject *self, PyObject *const *args, Py_ssize_t nar goto exit; } skip_optional: - return_value = _tkinter_tkapp_mainloop_impl(self, threshold); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_dooneevent__doc__, -"dooneevent($self, flags=0, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_DOONEEVENT_METHODDEF \ + return_value = _tkinter_tkapp_mainloop_impl(self, threshold); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_dooneevent__doc__, +"dooneevent($self, flags=0, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_DOONEEVENT_METHODDEF \ {"dooneevent", (PyCFunction)(void(*)(void))_tkinter_tkapp_dooneevent, METH_FASTCALL, _tkinter_tkapp_dooneevent__doc__}, - -static PyObject * -_tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags); - -static PyObject * -_tkinter_tkapp_dooneevent(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int flags = 0; - + +static PyObject * +_tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags); + +static PyObject * +_tkinter_tkapp_dooneevent(TkappObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flags = 0; + if (!_PyArg_CheckPositional("dooneevent", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -591,128 +591,128 @@ _tkinter_tkapp_dooneevent(TkappObject *self, PyObject *const *args, Py_ssize_t n goto exit; } skip_optional: - return_value = _tkinter_tkapp_dooneevent_impl(self, flags); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_tkapp_quit__doc__, -"quit($self, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_QUIT_METHODDEF \ - {"quit", (PyCFunction)_tkinter_tkapp_quit, METH_NOARGS, _tkinter_tkapp_quit__doc__}, - -static PyObject * -_tkinter_tkapp_quit_impl(TkappObject *self); - -static PyObject * -_tkinter_tkapp_quit(TkappObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _tkinter_tkapp_quit_impl(self); -} - -PyDoc_STRVAR(_tkinter_tkapp_interpaddr__doc__, -"interpaddr($self, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_INTERPADDR_METHODDEF \ - {"interpaddr", (PyCFunction)_tkinter_tkapp_interpaddr, METH_NOARGS, _tkinter_tkapp_interpaddr__doc__}, - -static PyObject * -_tkinter_tkapp_interpaddr_impl(TkappObject *self); - -static PyObject * -_tkinter_tkapp_interpaddr(TkappObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _tkinter_tkapp_interpaddr_impl(self); -} - -PyDoc_STRVAR(_tkinter_tkapp_loadtk__doc__, -"loadtk($self, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_LOADTK_METHODDEF \ - {"loadtk", (PyCFunction)_tkinter_tkapp_loadtk, METH_NOARGS, _tkinter_tkapp_loadtk__doc__}, - -static PyObject * -_tkinter_tkapp_loadtk_impl(TkappObject *self); - -static PyObject * -_tkinter_tkapp_loadtk(TkappObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _tkinter_tkapp_loadtk_impl(self); -} - -PyDoc_STRVAR(_tkinter_tkapp_willdispatch__doc__, -"willdispatch($self, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_WILLDISPATCH_METHODDEF \ - {"willdispatch", (PyCFunction)_tkinter_tkapp_willdispatch, METH_NOARGS, _tkinter_tkapp_willdispatch__doc__}, - -static PyObject * -_tkinter_tkapp_willdispatch_impl(TkappObject *self); - -static PyObject * -_tkinter_tkapp_willdispatch(TkappObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _tkinter_tkapp_willdispatch_impl(self); -} - -PyDoc_STRVAR(_tkinter__flatten__doc__, -"_flatten($module, item, /)\n" -"--\n" -"\n"); - -#define _TKINTER__FLATTEN_METHODDEF \ - {"_flatten", (PyCFunction)_tkinter__flatten, METH_O, _tkinter__flatten__doc__}, - -PyDoc_STRVAR(_tkinter_create__doc__, + return_value = _tkinter_tkapp_dooneevent_impl(self, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_quit__doc__, +"quit($self, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_QUIT_METHODDEF \ + {"quit", (PyCFunction)_tkinter_tkapp_quit, METH_NOARGS, _tkinter_tkapp_quit__doc__}, + +static PyObject * +_tkinter_tkapp_quit_impl(TkappObject *self); + +static PyObject * +_tkinter_tkapp_quit(TkappObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _tkinter_tkapp_quit_impl(self); +} + +PyDoc_STRVAR(_tkinter_tkapp_interpaddr__doc__, +"interpaddr($self, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_INTERPADDR_METHODDEF \ + {"interpaddr", (PyCFunction)_tkinter_tkapp_interpaddr, METH_NOARGS, _tkinter_tkapp_interpaddr__doc__}, + +static PyObject * +_tkinter_tkapp_interpaddr_impl(TkappObject *self); + +static PyObject * +_tkinter_tkapp_interpaddr(TkappObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _tkinter_tkapp_interpaddr_impl(self); +} + +PyDoc_STRVAR(_tkinter_tkapp_loadtk__doc__, +"loadtk($self, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_LOADTK_METHODDEF \ + {"loadtk", (PyCFunction)_tkinter_tkapp_loadtk, METH_NOARGS, _tkinter_tkapp_loadtk__doc__}, + +static PyObject * +_tkinter_tkapp_loadtk_impl(TkappObject *self); + +static PyObject * +_tkinter_tkapp_loadtk(TkappObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _tkinter_tkapp_loadtk_impl(self); +} + +PyDoc_STRVAR(_tkinter_tkapp_willdispatch__doc__, +"willdispatch($self, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_WILLDISPATCH_METHODDEF \ + {"willdispatch", (PyCFunction)_tkinter_tkapp_willdispatch, METH_NOARGS, _tkinter_tkapp_willdispatch__doc__}, + +static PyObject * +_tkinter_tkapp_willdispatch_impl(TkappObject *self); + +static PyObject * +_tkinter_tkapp_willdispatch(TkappObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _tkinter_tkapp_willdispatch_impl(self); +} + +PyDoc_STRVAR(_tkinter__flatten__doc__, +"_flatten($module, item, /)\n" +"--\n" +"\n"); + +#define _TKINTER__FLATTEN_METHODDEF \ + {"_flatten", (PyCFunction)_tkinter__flatten, METH_O, _tkinter__flatten__doc__}, + +PyDoc_STRVAR(_tkinter_create__doc__, "create($module, screenName=None, baseName=\'\', className=\'Tk\',\n" -" interactive=False, wantobjects=False, wantTk=True, sync=False,\n" -" use=None, /)\n" -"--\n" -"\n" -"\n" -"\n" -" wantTk\n" -" if false, then Tk_Init() doesn\'t get called\n" -" sync\n" -" if true, then pass -sync to wish\n" -" use\n" -" if not None, then pass -use to wish"); - -#define _TKINTER_CREATE_METHODDEF \ +" interactive=False, wantobjects=False, wantTk=True, sync=False,\n" +" use=None, /)\n" +"--\n" +"\n" +"\n" +"\n" +" wantTk\n" +" if false, then Tk_Init() doesn\'t get called\n" +" sync\n" +" if true, then pass -sync to wish\n" +" use\n" +" if not None, then pass -use to wish"); + +#define _TKINTER_CREATE_METHODDEF \ {"create", (PyCFunction)(void(*)(void))_tkinter_create, METH_FASTCALL, _tkinter_create__doc__}, - -static PyObject * -_tkinter_create_impl(PyObject *module, const char *screenName, - const char *baseName, const char *className, - int interactive, int wantobjects, int wantTk, int sync, - const char *use); - -static PyObject * -_tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *screenName = NULL; + +static PyObject * +_tkinter_create_impl(PyObject *module, const char *screenName, + const char *baseName, const char *className, + int interactive, int wantobjects, int wantTk, int sync, + const char *use); + +static PyObject * +_tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *screenName = NULL; const char *baseName = ""; - const char *className = "Tk"; - int interactive = 0; - int wantobjects = 0; - int wantTk = 1; - int sync = 0; - const char *use = NULL; - + const char *className = "Tk"; + int interactive = 0; + int wantobjects = 0; + int wantTk = 1; + int sync = 0; + const char *use = NULL; + if (!_PyArg_CheckPositional("create", nargs, 0, 8)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -836,80 +836,80 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _tkinter_create_impl(module, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_setbusywaitinterval__doc__, -"setbusywaitinterval($module, new_val, /)\n" -"--\n" -"\n" -"Set the busy-wait interval in milliseconds between successive calls to Tcl_DoOneEvent in a threaded Python interpreter.\n" -"\n" -"It should be set to a divisor of the maximum time between frames in an animation."); - -#define _TKINTER_SETBUSYWAITINTERVAL_METHODDEF \ - {"setbusywaitinterval", (PyCFunction)_tkinter_setbusywaitinterval, METH_O, _tkinter_setbusywaitinterval__doc__}, - -static PyObject * -_tkinter_setbusywaitinterval_impl(PyObject *module, int new_val); - -static PyObject * -_tkinter_setbusywaitinterval(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int new_val; - + return_value = _tkinter_create_impl(module, screenName, baseName, className, interactive, wantobjects, wantTk, sync, use); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_setbusywaitinterval__doc__, +"setbusywaitinterval($module, new_val, /)\n" +"--\n" +"\n" +"Set the busy-wait interval in milliseconds between successive calls to Tcl_DoOneEvent in a threaded Python interpreter.\n" +"\n" +"It should be set to a divisor of the maximum time between frames in an animation."); + +#define _TKINTER_SETBUSYWAITINTERVAL_METHODDEF \ + {"setbusywaitinterval", (PyCFunction)_tkinter_setbusywaitinterval, METH_O, _tkinter_setbusywaitinterval__doc__}, + +static PyObject * +_tkinter_setbusywaitinterval_impl(PyObject *module, int new_val); + +static PyObject * +_tkinter_setbusywaitinterval(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int new_val; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } new_val = _PyLong_AsInt(arg); if (new_val == -1 && PyErr_Occurred()) { goto exit; } - return_value = _tkinter_setbusywaitinterval_impl(module, new_val); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tkinter_getbusywaitinterval__doc__, -"getbusywaitinterval($module, /)\n" -"--\n" -"\n" -"Return the current busy-wait interval between successive calls to Tcl_DoOneEvent in a threaded Python interpreter."); - -#define _TKINTER_GETBUSYWAITINTERVAL_METHODDEF \ - {"getbusywaitinterval", (PyCFunction)_tkinter_getbusywaitinterval, METH_NOARGS, _tkinter_getbusywaitinterval__doc__}, - -static int -_tkinter_getbusywaitinterval_impl(PyObject *module); - -static PyObject * -_tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = _tkinter_getbusywaitinterval_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -#ifndef _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF - #define _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF -#endif /* !defined(_TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF) */ - -#ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF - #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF -#endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ + return_value = _tkinter_setbusywaitinterval_impl(module, new_val); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_getbusywaitinterval__doc__, +"getbusywaitinterval($module, /)\n" +"--\n" +"\n" +"Return the current busy-wait interval between successive calls to Tcl_DoOneEvent in a threaded Python interpreter."); + +#define _TKINTER_GETBUSYWAITINTERVAL_METHODDEF \ + {"getbusywaitinterval", (PyCFunction)_tkinter_getbusywaitinterval, METH_NOARGS, _tkinter_getbusywaitinterval__doc__}, + +static int +_tkinter_getbusywaitinterval_impl(PyObject *module); + +static PyObject * +_tkinter_getbusywaitinterval(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _tkinter_getbusywaitinterval_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#ifndef _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF + #define _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF +#endif /* !defined(_TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF) */ + +#ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF + #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF +#endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ /*[clinic end generated code: output=492b8b833fe54bc9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_tracemalloc.c.h b/contrib/tools/python3/src/Modules/clinic/_tracemalloc.c.h index 049cacd8326..ce460502d89 100644 --- a/contrib/tools/python3/src/Modules/clinic/_tracemalloc.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_tracemalloc.c.h @@ -1,103 +1,103 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_tracemalloc_is_tracing__doc__, -"is_tracing($module, /)\n" -"--\n" -"\n" -"Return True if the tracemalloc module is tracing Python memory allocations."); - -#define _TRACEMALLOC_IS_TRACING_METHODDEF \ - {"is_tracing", (PyCFunction)_tracemalloc_is_tracing, METH_NOARGS, _tracemalloc_is_tracing__doc__}, - -static PyObject * -_tracemalloc_is_tracing_impl(PyObject *module); - -static PyObject * -_tracemalloc_is_tracing(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _tracemalloc_is_tracing_impl(module); -} - -PyDoc_STRVAR(_tracemalloc_clear_traces__doc__, -"clear_traces($module, /)\n" -"--\n" -"\n" -"Clear traces of memory blocks allocated by Python."); - -#define _TRACEMALLOC_CLEAR_TRACES_METHODDEF \ - {"clear_traces", (PyCFunction)_tracemalloc_clear_traces, METH_NOARGS, _tracemalloc_clear_traces__doc__}, - -static PyObject * -_tracemalloc_clear_traces_impl(PyObject *module); - -static PyObject * -_tracemalloc_clear_traces(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _tracemalloc_clear_traces_impl(module); -} - -PyDoc_STRVAR(_tracemalloc__get_traces__doc__, -"_get_traces($module, /)\n" -"--\n" -"\n" -"Get traces of all memory blocks allocated by Python.\n" -"\n" -"Return a list of (size: int, traceback: tuple) tuples.\n" -"traceback is a tuple of (filename: str, lineno: int) tuples.\n" -"\n" -"Return an empty list if the tracemalloc module is disabled."); - -#define _TRACEMALLOC__GET_TRACES_METHODDEF \ - {"_get_traces", (PyCFunction)_tracemalloc__get_traces, METH_NOARGS, _tracemalloc__get_traces__doc__}, - -static PyObject * -_tracemalloc__get_traces_impl(PyObject *module); - -static PyObject * -_tracemalloc__get_traces(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _tracemalloc__get_traces_impl(module); -} - -PyDoc_STRVAR(_tracemalloc__get_object_traceback__doc__, -"_get_object_traceback($module, obj, /)\n" -"--\n" -"\n" -"Get the traceback where the Python object obj was allocated.\n" -"\n" -"Return a tuple of (filename: str, lineno: int) tuples.\n" -"Return None if the tracemalloc module is disabled or did not\n" -"trace the allocation of the object."); - -#define _TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF \ - {"_get_object_traceback", (PyCFunction)_tracemalloc__get_object_traceback, METH_O, _tracemalloc__get_object_traceback__doc__}, - -PyDoc_STRVAR(_tracemalloc_start__doc__, -"start($module, nframe=1, /)\n" -"--\n" -"\n" -"Start tracing Python memory allocations.\n" -"\n" -"Also set the maximum number of frames stored in the traceback of a\n" -"trace to nframe."); - -#define _TRACEMALLOC_START_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_tracemalloc_is_tracing__doc__, +"is_tracing($module, /)\n" +"--\n" +"\n" +"Return True if the tracemalloc module is tracing Python memory allocations."); + +#define _TRACEMALLOC_IS_TRACING_METHODDEF \ + {"is_tracing", (PyCFunction)_tracemalloc_is_tracing, METH_NOARGS, _tracemalloc_is_tracing__doc__}, + +static PyObject * +_tracemalloc_is_tracing_impl(PyObject *module); + +static PyObject * +_tracemalloc_is_tracing(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _tracemalloc_is_tracing_impl(module); +} + +PyDoc_STRVAR(_tracemalloc_clear_traces__doc__, +"clear_traces($module, /)\n" +"--\n" +"\n" +"Clear traces of memory blocks allocated by Python."); + +#define _TRACEMALLOC_CLEAR_TRACES_METHODDEF \ + {"clear_traces", (PyCFunction)_tracemalloc_clear_traces, METH_NOARGS, _tracemalloc_clear_traces__doc__}, + +static PyObject * +_tracemalloc_clear_traces_impl(PyObject *module); + +static PyObject * +_tracemalloc_clear_traces(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _tracemalloc_clear_traces_impl(module); +} + +PyDoc_STRVAR(_tracemalloc__get_traces__doc__, +"_get_traces($module, /)\n" +"--\n" +"\n" +"Get traces of all memory blocks allocated by Python.\n" +"\n" +"Return a list of (size: int, traceback: tuple) tuples.\n" +"traceback is a tuple of (filename: str, lineno: int) tuples.\n" +"\n" +"Return an empty list if the tracemalloc module is disabled."); + +#define _TRACEMALLOC__GET_TRACES_METHODDEF \ + {"_get_traces", (PyCFunction)_tracemalloc__get_traces, METH_NOARGS, _tracemalloc__get_traces__doc__}, + +static PyObject * +_tracemalloc__get_traces_impl(PyObject *module); + +static PyObject * +_tracemalloc__get_traces(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _tracemalloc__get_traces_impl(module); +} + +PyDoc_STRVAR(_tracemalloc__get_object_traceback__doc__, +"_get_object_traceback($module, obj, /)\n" +"--\n" +"\n" +"Get the traceback where the Python object obj was allocated.\n" +"\n" +"Return a tuple of (filename: str, lineno: int) tuples.\n" +"Return None if the tracemalloc module is disabled or did not\n" +"trace the allocation of the object."); + +#define _TRACEMALLOC__GET_OBJECT_TRACEBACK_METHODDEF \ + {"_get_object_traceback", (PyCFunction)_tracemalloc__get_object_traceback, METH_O, _tracemalloc__get_object_traceback__doc__}, + +PyDoc_STRVAR(_tracemalloc_start__doc__, +"start($module, nframe=1, /)\n" +"--\n" +"\n" +"Start tracing Python memory allocations.\n" +"\n" +"Also set the maximum number of frames stored in the traceback of a\n" +"trace to nframe."); + +#define _TRACEMALLOC_START_METHODDEF \ {"start", (PyCFunction)(void(*)(void))_tracemalloc_start, METH_FASTCALL, _tracemalloc_start__doc__}, - -static PyObject * -_tracemalloc_start_impl(PyObject *module, int nframe); - -static PyObject * -_tracemalloc_start(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int nframe = 1; - + +static PyObject * +_tracemalloc_start_impl(PyObject *module, int nframe); + +static PyObject * +_tracemalloc_start(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nframe = 1; + if (!_PyArg_CheckPositional("start", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -111,92 +111,92 @@ _tracemalloc_start(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = _tracemalloc_start_impl(module, nframe); - -exit: - return return_value; -} - -PyDoc_STRVAR(_tracemalloc_stop__doc__, -"stop($module, /)\n" -"--\n" -"\n" -"Stop tracing Python memory allocations.\n" -"\n" -"Also clear traces of memory blocks allocated by Python."); - -#define _TRACEMALLOC_STOP_METHODDEF \ - {"stop", (PyCFunction)_tracemalloc_stop, METH_NOARGS, _tracemalloc_stop__doc__}, - -static PyObject * -_tracemalloc_stop_impl(PyObject *module); - -static PyObject * -_tracemalloc_stop(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _tracemalloc_stop_impl(module); -} - -PyDoc_STRVAR(_tracemalloc_get_traceback_limit__doc__, -"get_traceback_limit($module, /)\n" -"--\n" -"\n" -"Get the maximum number of frames stored in the traceback of a trace.\n" -"\n" -"By default, a trace of an allocated memory block only stores\n" -"the most recent frame: the limit is 1."); - -#define _TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF \ - {"get_traceback_limit", (PyCFunction)_tracemalloc_get_traceback_limit, METH_NOARGS, _tracemalloc_get_traceback_limit__doc__}, - -static PyObject * -_tracemalloc_get_traceback_limit_impl(PyObject *module); - -static PyObject * -_tracemalloc_get_traceback_limit(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _tracemalloc_get_traceback_limit_impl(module); -} - -PyDoc_STRVAR(_tracemalloc_get_tracemalloc_memory__doc__, -"get_tracemalloc_memory($module, /)\n" -"--\n" -"\n" -"Get the memory usage in bytes of the tracemalloc module.\n" -"\n" -"This memory is used internally to trace memory allocations."); - -#define _TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF \ - {"get_tracemalloc_memory", (PyCFunction)_tracemalloc_get_tracemalloc_memory, METH_NOARGS, _tracemalloc_get_tracemalloc_memory__doc__}, - -static PyObject * -_tracemalloc_get_tracemalloc_memory_impl(PyObject *module); - -static PyObject * -_tracemalloc_get_tracemalloc_memory(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _tracemalloc_get_tracemalloc_memory_impl(module); -} - -PyDoc_STRVAR(_tracemalloc_get_traced_memory__doc__, -"get_traced_memory($module, /)\n" -"--\n" -"\n" -"Get the current size and peak size of memory blocks traced by tracemalloc.\n" -"\n" -"Returns a tuple: (current: int, peak: int)."); - -#define _TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF \ - {"get_traced_memory", (PyCFunction)_tracemalloc_get_traced_memory, METH_NOARGS, _tracemalloc_get_traced_memory__doc__}, - -static PyObject * -_tracemalloc_get_traced_memory_impl(PyObject *module); - -static PyObject * -_tracemalloc_get_traced_memory(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _tracemalloc_get_traced_memory_impl(module); -} + return_value = _tracemalloc_start_impl(module, nframe); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tracemalloc_stop__doc__, +"stop($module, /)\n" +"--\n" +"\n" +"Stop tracing Python memory allocations.\n" +"\n" +"Also clear traces of memory blocks allocated by Python."); + +#define _TRACEMALLOC_STOP_METHODDEF \ + {"stop", (PyCFunction)_tracemalloc_stop, METH_NOARGS, _tracemalloc_stop__doc__}, + +static PyObject * +_tracemalloc_stop_impl(PyObject *module); + +static PyObject * +_tracemalloc_stop(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _tracemalloc_stop_impl(module); +} + +PyDoc_STRVAR(_tracemalloc_get_traceback_limit__doc__, +"get_traceback_limit($module, /)\n" +"--\n" +"\n" +"Get the maximum number of frames stored in the traceback of a trace.\n" +"\n" +"By default, a trace of an allocated memory block only stores\n" +"the most recent frame: the limit is 1."); + +#define _TRACEMALLOC_GET_TRACEBACK_LIMIT_METHODDEF \ + {"get_traceback_limit", (PyCFunction)_tracemalloc_get_traceback_limit, METH_NOARGS, _tracemalloc_get_traceback_limit__doc__}, + +static PyObject * +_tracemalloc_get_traceback_limit_impl(PyObject *module); + +static PyObject * +_tracemalloc_get_traceback_limit(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _tracemalloc_get_traceback_limit_impl(module); +} + +PyDoc_STRVAR(_tracemalloc_get_tracemalloc_memory__doc__, +"get_tracemalloc_memory($module, /)\n" +"--\n" +"\n" +"Get the memory usage in bytes of the tracemalloc module.\n" +"\n" +"This memory is used internally to trace memory allocations."); + +#define _TRACEMALLOC_GET_TRACEMALLOC_MEMORY_METHODDEF \ + {"get_tracemalloc_memory", (PyCFunction)_tracemalloc_get_tracemalloc_memory, METH_NOARGS, _tracemalloc_get_tracemalloc_memory__doc__}, + +static PyObject * +_tracemalloc_get_tracemalloc_memory_impl(PyObject *module); + +static PyObject * +_tracemalloc_get_tracemalloc_memory(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _tracemalloc_get_tracemalloc_memory_impl(module); +} + +PyDoc_STRVAR(_tracemalloc_get_traced_memory__doc__, +"get_traced_memory($module, /)\n" +"--\n" +"\n" +"Get the current size and peak size of memory blocks traced by tracemalloc.\n" +"\n" +"Returns a tuple: (current: int, peak: int)."); + +#define _TRACEMALLOC_GET_TRACED_MEMORY_METHODDEF \ + {"get_traced_memory", (PyCFunction)_tracemalloc_get_traced_memory, METH_NOARGS, _tracemalloc_get_traced_memory__doc__}, + +static PyObject * +_tracemalloc_get_traced_memory_impl(PyObject *module); + +static PyObject * +_tracemalloc_get_traced_memory(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _tracemalloc_get_traced_memory_impl(module); +} PyDoc_STRVAR(_tracemalloc_reset_peak__doc__, "reset_peak($module, /)\n" diff --git a/contrib/tools/python3/src/Modules/clinic/_weakref.c.h b/contrib/tools/python3/src/Modules/clinic/_weakref.c.h index c3a908fa6a1..af84a90fdd0 100644 --- a/contrib/tools/python3/src/Modules/clinic/_weakref.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_weakref.c.h @@ -1,67 +1,67 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_weakref_getweakrefcount__doc__, -"getweakrefcount($module, object, /)\n" -"--\n" -"\n" -"Return the number of weak references to \'object\'."); - -#define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \ - {"getweakrefcount", (PyCFunction)_weakref_getweakrefcount, METH_O, _weakref_getweakrefcount__doc__}, - -static Py_ssize_t -_weakref_getweakrefcount_impl(PyObject *module, PyObject *object); - -static PyObject * -_weakref_getweakrefcount(PyObject *module, PyObject *object) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = _weakref_getweakrefcount_impl(module, object); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_weakref__remove_dead_weakref__doc__, -"_remove_dead_weakref($module, dct, key, /)\n" -"--\n" -"\n" -"Atomically remove key from dict if it points to a dead weakref."); - -#define _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_weakref_getweakrefcount__doc__, +"getweakrefcount($module, object, /)\n" +"--\n" +"\n" +"Return the number of weak references to \'object\'."); + +#define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \ + {"getweakrefcount", (PyCFunction)_weakref_getweakrefcount, METH_O, _weakref_getweakrefcount__doc__}, + +static Py_ssize_t +_weakref_getweakrefcount_impl(PyObject *module, PyObject *object); + +static PyObject * +_weakref_getweakrefcount(PyObject *module, PyObject *object) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _weakref_getweakrefcount_impl(module, object); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_weakref__remove_dead_weakref__doc__, +"_remove_dead_weakref($module, dct, key, /)\n" +"--\n" +"\n" +"Atomically remove key from dict if it points to a dead weakref."); + +#define _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF \ {"_remove_dead_weakref", (PyCFunction)(void(*)(void))_weakref__remove_dead_weakref, METH_FASTCALL, _weakref__remove_dead_weakref__doc__}, - -static PyObject * -_weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, - PyObject *key); - -static PyObject * -_weakref__remove_dead_weakref(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *dct; - PyObject *key; - + +static PyObject * +_weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, + PyObject *key); + +static PyObject * +_weakref__remove_dead_weakref(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *dct; + PyObject *key; + if (!_PyArg_CheckPositional("_remove_dead_weakref", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!PyDict_Check(args[0])) { _PyArg_BadArgument("_remove_dead_weakref", "argument 1", "dict", args[0]); goto exit; } dct = args[0]; key = args[1]; - return_value = _weakref__remove_dead_weakref_impl(module, dct, key); - -exit: - return return_value; -} + return_value = _weakref__remove_dead_weakref_impl(module, dct, key); + +exit: + return return_value; +} /*[clinic end generated code: output=c543dc2cd6ece975 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/_winapi.c.h b/contrib/tools/python3/src/Modules/clinic/_winapi.c.h index e21f2bc2b6f..4ddb520410f 100644 --- a/contrib/tools/python3/src/Modules/clinic/_winapi.c.h +++ b/contrib/tools/python3/src/Modules/clinic/_winapi.c.h @@ -1,611 +1,205 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_winapi_Overlapped_GetOverlappedResult__doc__, -"GetOverlappedResult($self, wait, /)\n" -"--\n" -"\n"); - -#define _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF \ - {"GetOverlappedResult", (PyCFunction)_winapi_Overlapped_GetOverlappedResult, METH_O, _winapi_Overlapped_GetOverlappedResult__doc__}, - -static PyObject * -_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait); - -static PyObject * -_winapi_Overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int wait; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_winapi_Overlapped_GetOverlappedResult__doc__, +"GetOverlappedResult($self, wait, /)\n" +"--\n" +"\n"); + +#define _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF \ + {"GetOverlappedResult", (PyCFunction)_winapi_Overlapped_GetOverlappedResult, METH_O, _winapi_Overlapped_GetOverlappedResult__doc__}, + +static PyObject * +_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait); + +static PyObject * +_winapi_Overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int wait; + wait = PyObject_IsTrue(arg); if (wait < 0) { - goto exit; - } - return_value = _winapi_Overlapped_GetOverlappedResult_impl(self, wait); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_Overlapped_getbuffer__doc__, -"getbuffer($self, /)\n" -"--\n" -"\n"); - -#define _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF \ - {"getbuffer", (PyCFunction)_winapi_Overlapped_getbuffer, METH_NOARGS, _winapi_Overlapped_getbuffer__doc__}, - -static PyObject * -_winapi_Overlapped_getbuffer_impl(OverlappedObject *self); - -static PyObject * -_winapi_Overlapped_getbuffer(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _winapi_Overlapped_getbuffer_impl(self); -} - -PyDoc_STRVAR(_winapi_Overlapped_cancel__doc__, -"cancel($self, /)\n" -"--\n" -"\n"); - -#define _WINAPI_OVERLAPPED_CANCEL_METHODDEF \ - {"cancel", (PyCFunction)_winapi_Overlapped_cancel, METH_NOARGS, _winapi_Overlapped_cancel__doc__}, - -static PyObject * -_winapi_Overlapped_cancel_impl(OverlappedObject *self); - -static PyObject * -_winapi_Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _winapi_Overlapped_cancel_impl(self); -} - -PyDoc_STRVAR(_winapi_CloseHandle__doc__, -"CloseHandle($module, handle, /)\n" -"--\n" -"\n" -"Close handle."); - -#define _WINAPI_CLOSEHANDLE_METHODDEF \ - {"CloseHandle", (PyCFunction)_winapi_CloseHandle, METH_O, _winapi_CloseHandle__doc__}, - -static PyObject * -_winapi_CloseHandle_impl(PyObject *module, HANDLE handle); - -static PyObject * -_winapi_CloseHandle(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - HANDLE handle; - - if (!PyArg_Parse(arg, "" F_HANDLE ":CloseHandle", &handle)) { - goto exit; - } - return_value = _winapi_CloseHandle_impl(module, handle); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_ConnectNamedPipe__doc__, -"ConnectNamedPipe($module, /, handle, overlapped=False)\n" -"--\n" -"\n"); - -#define _WINAPI_CONNECTNAMEDPIPE_METHODDEF \ + goto exit; + } + return_value = _winapi_Overlapped_GetOverlappedResult_impl(self, wait); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_Overlapped_getbuffer__doc__, +"getbuffer($self, /)\n" +"--\n" +"\n"); + +#define _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF \ + {"getbuffer", (PyCFunction)_winapi_Overlapped_getbuffer, METH_NOARGS, _winapi_Overlapped_getbuffer__doc__}, + +static PyObject * +_winapi_Overlapped_getbuffer_impl(OverlappedObject *self); + +static PyObject * +_winapi_Overlapped_getbuffer(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _winapi_Overlapped_getbuffer_impl(self); +} + +PyDoc_STRVAR(_winapi_Overlapped_cancel__doc__, +"cancel($self, /)\n" +"--\n" +"\n"); + +#define _WINAPI_OVERLAPPED_CANCEL_METHODDEF \ + {"cancel", (PyCFunction)_winapi_Overlapped_cancel, METH_NOARGS, _winapi_Overlapped_cancel__doc__}, + +static PyObject * +_winapi_Overlapped_cancel_impl(OverlappedObject *self); + +static PyObject * +_winapi_Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _winapi_Overlapped_cancel_impl(self); +} + +PyDoc_STRVAR(_winapi_CloseHandle__doc__, +"CloseHandle($module, handle, /)\n" +"--\n" +"\n" +"Close handle."); + +#define _WINAPI_CLOSEHANDLE_METHODDEF \ + {"CloseHandle", (PyCFunction)_winapi_CloseHandle, METH_O, _winapi_CloseHandle__doc__}, + +static PyObject * +_winapi_CloseHandle_impl(PyObject *module, HANDLE handle); + +static PyObject * +_winapi_CloseHandle(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE handle; + + if (!PyArg_Parse(arg, "" F_HANDLE ":CloseHandle", &handle)) { + goto exit; + } + return_value = _winapi_CloseHandle_impl(module, handle); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_ConnectNamedPipe__doc__, +"ConnectNamedPipe($module, /, handle, overlapped=False)\n" +"--\n" +"\n"); + +#define _WINAPI_CONNECTNAMEDPIPE_METHODDEF \ {"ConnectNamedPipe", (PyCFunction)(void(*)(void))_winapi_ConnectNamedPipe, METH_FASTCALL|METH_KEYWORDS, _winapi_ConnectNamedPipe__doc__}, - -static PyObject * -_winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, - int use_overlapped); - -static PyObject * -_winapi_ConnectNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"handle", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "|i:ConnectNamedPipe", _keywords, 0}; - HANDLE handle; - int use_overlapped = 0; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &handle, &use_overlapped)) { - goto exit; - } - return_value = _winapi_ConnectNamedPipe_impl(module, handle, use_overlapped); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_CreateFile__doc__, -"CreateFile($module, file_name, desired_access, share_mode,\n" -" security_attributes, creation_disposition,\n" -" flags_and_attributes, template_file, /)\n" -"--\n" -"\n"); - -#define _WINAPI_CREATEFILE_METHODDEF \ + +static PyObject * +_winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, + int use_overlapped); + +static PyObject * +_winapi_ConnectNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"handle", "overlapped", NULL}; + static _PyArg_Parser _parser = {"" F_HANDLE "|i:ConnectNamedPipe", _keywords, 0}; + HANDLE handle; + int use_overlapped = 0; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &handle, &use_overlapped)) { + goto exit; + } + return_value = _winapi_ConnectNamedPipe_impl(module, handle, use_overlapped); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_CreateFile__doc__, +"CreateFile($module, file_name, desired_access, share_mode,\n" +" security_attributes, creation_disposition,\n" +" flags_and_attributes, template_file, /)\n" +"--\n" +"\n"); + +#define _WINAPI_CREATEFILE_METHODDEF \ {"CreateFile", (PyCFunction)(void(*)(void))_winapi_CreateFile, METH_FASTCALL, _winapi_CreateFile__doc__}, - -static HANDLE -_winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name, - DWORD desired_access, DWORD share_mode, - LPSECURITY_ATTRIBUTES security_attributes, - DWORD creation_disposition, - DWORD flags_and_attributes, HANDLE template_file); - -static PyObject * -_winapi_CreateFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - LPCTSTR file_name; - DWORD desired_access; - DWORD share_mode; - LPSECURITY_ATTRIBUTES security_attributes; - DWORD creation_disposition; - DWORD flags_and_attributes; - HANDLE template_file; - HANDLE _return_value; - - if (!_PyArg_ParseStack(args, nargs, "skk" F_POINTER "kk" F_HANDLE ":CreateFile", - &file_name, &desired_access, &share_mode, &security_attributes, &creation_disposition, &flags_and_attributes, &template_file)) { - goto exit; - } - _return_value = _winapi_CreateFile_impl(module, file_name, desired_access, share_mode, security_attributes, creation_disposition, flags_and_attributes, template_file); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { - goto exit; - } - if (_return_value == NULL) { - Py_RETURN_NONE; - } - return_value = HANDLE_TO_PYNUM(_return_value); - -exit: - return return_value; -} - + +static HANDLE +_winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name, + DWORD desired_access, DWORD share_mode, + LPSECURITY_ATTRIBUTES security_attributes, + DWORD creation_disposition, + DWORD flags_and_attributes, HANDLE template_file); + +static PyObject * +_winapi_CreateFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + LPCTSTR file_name; + DWORD desired_access; + DWORD share_mode; + LPSECURITY_ATTRIBUTES security_attributes; + DWORD creation_disposition; + DWORD flags_and_attributes; + HANDLE template_file; + HANDLE _return_value; + + if (!_PyArg_ParseStack(args, nargs, "skk" F_POINTER "kk" F_HANDLE ":CreateFile", + &file_name, &desired_access, &share_mode, &security_attributes, &creation_disposition, &flags_and_attributes, &template_file)) { + goto exit; + } + _return_value = _winapi_CreateFile_impl(module, file_name, desired_access, share_mode, security_attributes, creation_disposition, flags_and_attributes, template_file); + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { + goto exit; + } + if (_return_value == NULL) { + Py_RETURN_NONE; + } + return_value = HANDLE_TO_PYNUM(_return_value); + +exit: + return return_value; +} + PyDoc_STRVAR(_winapi_CreateFileMapping__doc__, "CreateFileMapping($module, file_handle, security_attributes, protect,\n" -" max_size_high, max_size_low, name, /)\n" -"--\n" -"\n"); - -#define _WINAPI_CREATEFILEMAPPING_METHODDEF \ - {"CreateFileMapping", (PyCFunction)(void(*)(void))_winapi_CreateFileMapping, METH_FASTCALL, _winapi_CreateFileMapping__doc__}, - -static HANDLE -_winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle, - LPSECURITY_ATTRIBUTES security_attributes, - DWORD protect, DWORD max_size_high, - DWORD max_size_low, LPCWSTR name); - -static PyObject * -_winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - HANDLE file_handle; - LPSECURITY_ATTRIBUTES security_attributes; - DWORD protect; - DWORD max_size_high; - DWORD max_size_low; - LPCWSTR name; - HANDLE _return_value; - - if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_POINTER "kkku:CreateFileMapping", - &file_handle, &security_attributes, &protect, &max_size_high, &max_size_low, &name)) { - goto exit; - } - _return_value = _winapi_CreateFileMapping_impl(module, file_handle, security_attributes, protect, max_size_high, max_size_low, name); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { - goto exit; - } - if (_return_value == NULL) { - Py_RETURN_NONE; - } - return_value = HANDLE_TO_PYNUM(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_CreateJunction__doc__, -"CreateJunction($module, src_path, dst_path, /)\n" -"--\n" -"\n"); - -#define _WINAPI_CREATEJUNCTION_METHODDEF \ - {"CreateJunction", (PyCFunction)(void(*)(void))_winapi_CreateJunction, METH_FASTCALL, _winapi_CreateJunction__doc__}, - -static PyObject * -_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, - LPWSTR dst_path); - -static PyObject * -_winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - LPWSTR src_path; - LPWSTR dst_path; - - if (!_PyArg_ParseStack(args, nargs, "uu:CreateJunction", - &src_path, &dst_path)) { - goto exit; - } - return_value = _winapi_CreateJunction_impl(module, src_path, dst_path); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_CreateNamedPipe__doc__, -"CreateNamedPipe($module, name, open_mode, pipe_mode, max_instances,\n" -" out_buffer_size, in_buffer_size, default_timeout,\n" -" security_attributes, /)\n" -"--\n" -"\n"); - -#define _WINAPI_CREATENAMEDPIPE_METHODDEF \ - {"CreateNamedPipe", (PyCFunction)(void(*)(void))_winapi_CreateNamedPipe, METH_FASTCALL, _winapi_CreateNamedPipe__doc__}, - -static HANDLE -_winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode, - DWORD pipe_mode, DWORD max_instances, - DWORD out_buffer_size, DWORD in_buffer_size, - DWORD default_timeout, - LPSECURITY_ATTRIBUTES security_attributes); - -static PyObject * -_winapi_CreateNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - LPCTSTR name; - DWORD open_mode; - DWORD pipe_mode; - DWORD max_instances; - DWORD out_buffer_size; - DWORD in_buffer_size; - DWORD default_timeout; - LPSECURITY_ATTRIBUTES security_attributes; - HANDLE _return_value; - - if (!_PyArg_ParseStack(args, nargs, "skkkkkk" F_POINTER ":CreateNamedPipe", - &name, &open_mode, &pipe_mode, &max_instances, &out_buffer_size, &in_buffer_size, &default_timeout, &security_attributes)) { - goto exit; - } - _return_value = _winapi_CreateNamedPipe_impl(module, name, open_mode, pipe_mode, max_instances, out_buffer_size, in_buffer_size, default_timeout, security_attributes); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { - goto exit; - } - if (_return_value == NULL) { - Py_RETURN_NONE; - } - return_value = HANDLE_TO_PYNUM(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_CreatePipe__doc__, -"CreatePipe($module, pipe_attrs, size, /)\n" -"--\n" -"\n" -"Create an anonymous pipe.\n" -"\n" -" pipe_attrs\n" -" Ignored internally, can be None.\n" -"\n" -"Returns a 2-tuple of handles, to the read and write ends of the pipe."); - -#define _WINAPI_CREATEPIPE_METHODDEF \ - {"CreatePipe", (PyCFunction)(void(*)(void))_winapi_CreatePipe, METH_FASTCALL, _winapi_CreatePipe__doc__}, - -static PyObject * -_winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size); - -static PyObject * -_winapi_CreatePipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *pipe_attrs; - DWORD size; - - if (!_PyArg_ParseStack(args, nargs, "Ok:CreatePipe", - &pipe_attrs, &size)) { - goto exit; - } - return_value = _winapi_CreatePipe_impl(module, pipe_attrs, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_CreateProcess__doc__, -"CreateProcess($module, application_name, command_line, proc_attrs,\n" -" thread_attrs, inherit_handles, creation_flags,\n" -" env_mapping, current_directory, startup_info, /)\n" -"--\n" -"\n" -"Create a new process and its primary thread.\n" -"\n" -" command_line\n" -" Can be str or None\n" -" proc_attrs\n" -" Ignored internally, can be None.\n" -" thread_attrs\n" -" Ignored internally, can be None.\n" -"\n" -"The return value is a tuple of the process handle, thread handle,\n" -"process ID, and thread ID."); - -#define _WINAPI_CREATEPROCESS_METHODDEF \ - {"CreateProcess", (PyCFunction)(void(*)(void))_winapi_CreateProcess, METH_FASTCALL, _winapi_CreateProcess__doc__}, - -static PyObject * -_winapi_CreateProcess_impl(PyObject *module, - const Py_UNICODE *application_name, - PyObject *command_line, PyObject *proc_attrs, - PyObject *thread_attrs, BOOL inherit_handles, - DWORD creation_flags, PyObject *env_mapping, - const Py_UNICODE *current_directory, - PyObject *startup_info); - -static PyObject * -_winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const Py_UNICODE *application_name; - PyObject *command_line; - PyObject *proc_attrs; - PyObject *thread_attrs; - BOOL inherit_handles; - DWORD creation_flags; - PyObject *env_mapping; - const Py_UNICODE *current_directory; - PyObject *startup_info; - - if (!_PyArg_ParseStack(args, nargs, "ZOOOikOZO:CreateProcess", - &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, ¤t_directory, &startup_info)) { - goto exit; - } - return_value = _winapi_CreateProcess_impl(module, application_name, command_line, proc_attrs, thread_attrs, inherit_handles, creation_flags, env_mapping, current_directory, startup_info); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_DuplicateHandle__doc__, -"DuplicateHandle($module, source_process_handle, source_handle,\n" -" target_process_handle, desired_access, inherit_handle,\n" -" options=0, /)\n" -"--\n" -"\n" -"Return a duplicate handle object.\n" -"\n" -"The duplicate handle refers to the same object as the original\n" -"handle. Therefore, any changes to the object are reflected\n" -"through both handles."); - -#define _WINAPI_DUPLICATEHANDLE_METHODDEF \ - {"DuplicateHandle", (PyCFunction)(void(*)(void))_winapi_DuplicateHandle, METH_FASTCALL, _winapi_DuplicateHandle__doc__}, - -static HANDLE -_winapi_DuplicateHandle_impl(PyObject *module, HANDLE source_process_handle, - HANDLE source_handle, - HANDLE target_process_handle, - DWORD desired_access, BOOL inherit_handle, - DWORD options); - -static PyObject * -_winapi_DuplicateHandle(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - HANDLE source_process_handle; - HANDLE source_handle; - HANDLE target_process_handle; - DWORD desired_access; - BOOL inherit_handle; - DWORD options = 0; - HANDLE _return_value; - - if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_HANDLE "" F_HANDLE "ki|k:DuplicateHandle", - &source_process_handle, &source_handle, &target_process_handle, &desired_access, &inherit_handle, &options)) { - goto exit; - } - _return_value = _winapi_DuplicateHandle_impl(module, source_process_handle, source_handle, target_process_handle, desired_access, inherit_handle, options); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { - goto exit; - } - if (_return_value == NULL) { - Py_RETURN_NONE; - } - return_value = HANDLE_TO_PYNUM(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_ExitProcess__doc__, -"ExitProcess($module, ExitCode, /)\n" -"--\n" -"\n"); - -#define _WINAPI_EXITPROCESS_METHODDEF \ - {"ExitProcess", (PyCFunction)_winapi_ExitProcess, METH_O, _winapi_ExitProcess__doc__}, - -static PyObject * -_winapi_ExitProcess_impl(PyObject *module, UINT ExitCode); - -static PyObject * -_winapi_ExitProcess(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - UINT ExitCode; - - if (!PyArg_Parse(arg, "I:ExitProcess", &ExitCode)) { - goto exit; - } - return_value = _winapi_ExitProcess_impl(module, ExitCode); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_GetCurrentProcess__doc__, -"GetCurrentProcess($module, /)\n" -"--\n" -"\n" -"Return a handle object for the current process."); - -#define _WINAPI_GETCURRENTPROCESS_METHODDEF \ - {"GetCurrentProcess", (PyCFunction)_winapi_GetCurrentProcess, METH_NOARGS, _winapi_GetCurrentProcess__doc__}, - -static HANDLE -_winapi_GetCurrentProcess_impl(PyObject *module); - -static PyObject * -_winapi_GetCurrentProcess(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - HANDLE _return_value; - - _return_value = _winapi_GetCurrentProcess_impl(module); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { - goto exit; - } - if (_return_value == NULL) { - Py_RETURN_NONE; - } - return_value = HANDLE_TO_PYNUM(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_GetExitCodeProcess__doc__, -"GetExitCodeProcess($module, process, /)\n" -"--\n" -"\n" -"Return the termination status of the specified process."); - -#define _WINAPI_GETEXITCODEPROCESS_METHODDEF \ - {"GetExitCodeProcess", (PyCFunction)_winapi_GetExitCodeProcess, METH_O, _winapi_GetExitCodeProcess__doc__}, - -static DWORD -_winapi_GetExitCodeProcess_impl(PyObject *module, HANDLE process); - -static PyObject * -_winapi_GetExitCodeProcess(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - HANDLE process; - DWORD _return_value; - - if (!PyArg_Parse(arg, "" F_HANDLE ":GetExitCodeProcess", &process)) { - goto exit; - } - _return_value = _winapi_GetExitCodeProcess_impl(module, process); - if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { - goto exit; - } - return_value = Py_BuildValue("k", _return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_GetLastError__doc__, -"GetLastError($module, /)\n" +" max_size_high, max_size_low, name, /)\n" "--\n" "\n"); -#define _WINAPI_GETLASTERROR_METHODDEF \ - {"GetLastError", (PyCFunction)_winapi_GetLastError, METH_NOARGS, _winapi_GetLastError__doc__}, - -static DWORD -_winapi_GetLastError_impl(PyObject *module); - -static PyObject * -_winapi_GetLastError(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - DWORD _return_value; - - _return_value = _winapi_GetLastError_impl(module); - if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { - goto exit; - } - return_value = Py_BuildValue("k", _return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_GetModuleFileName__doc__, -"GetModuleFileName($module, module_handle, /)\n" -"--\n" -"\n" -"Return the fully-qualified path for the file that contains module.\n" -"\n" -"The module must have been loaded by the current process.\n" -"\n" -"The module parameter should be a handle to the loaded module\n" -"whose path is being requested. If this parameter is 0,\n" -"GetModuleFileName retrieves the path of the executable file\n" -"of the current process."); - -#define _WINAPI_GETMODULEFILENAME_METHODDEF \ - {"GetModuleFileName", (PyCFunction)_winapi_GetModuleFileName, METH_O, _winapi_GetModuleFileName__doc__}, - -static PyObject * -_winapi_GetModuleFileName_impl(PyObject *module, HMODULE module_handle); - -static PyObject * -_winapi_GetModuleFileName(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - HMODULE module_handle; - - if (!PyArg_Parse(arg, "" F_HANDLE ":GetModuleFileName", &module_handle)) { - goto exit; - } - return_value = _winapi_GetModuleFileName_impl(module, module_handle); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_GetStdHandle__doc__, -"GetStdHandle($module, std_handle, /)\n" -"--\n" -"\n" -"Return a handle to the specified standard device.\n" -"\n" -" std_handle\n" -" One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE.\n" -"\n" -"The integer associated with the handle object is returned."); - -#define _WINAPI_GETSTDHANDLE_METHODDEF \ - {"GetStdHandle", (PyCFunction)_winapi_GetStdHandle, METH_O, _winapi_GetStdHandle__doc__}, +#define _WINAPI_CREATEFILEMAPPING_METHODDEF \ + {"CreateFileMapping", (PyCFunction)(void(*)(void))_winapi_CreateFileMapping, METH_FASTCALL, _winapi_CreateFileMapping__doc__}, static HANDLE -_winapi_GetStdHandle_impl(PyObject *module, DWORD std_handle); +_winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle, + LPSECURITY_ATTRIBUTES security_attributes, + DWORD protect, DWORD max_size_high, + DWORD max_size_low, LPCWSTR name); static PyObject * -_winapi_GetStdHandle(PyObject *module, PyObject *arg) +_winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - DWORD std_handle; + HANDLE file_handle; + LPSECURITY_ATTRIBUTES security_attributes; + DWORD protect; + DWORD max_size_high; + DWORD max_size_low; + LPCWSTR name; HANDLE _return_value; - if (!PyArg_Parse(arg, "k:GetStdHandle", &std_handle)) { + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_POINTER "kkku:CreateFileMapping", + &file_handle, &security_attributes, &protect, &max_size_high, &max_size_low, &name)) { goto exit; } - _return_value = _winapi_GetStdHandle_impl(module, std_handle); + _return_value = _winapi_CreateFileMapping_impl(module, file_handle, security_attributes, protect, max_size_high, max_size_low, name); if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { goto exit; } @@ -618,34 +212,440 @@ exit: return return_value; } -PyDoc_STRVAR(_winapi_GetVersion__doc__, -"GetVersion($module, /)\n" -"--\n" -"\n" -"Return the version number of the current operating system."); - -#define _WINAPI_GETVERSION_METHODDEF \ - {"GetVersion", (PyCFunction)_winapi_GetVersion, METH_NOARGS, _winapi_GetVersion__doc__}, - -static long -_winapi_GetVersion_impl(PyObject *module); - -static PyObject * -_winapi_GetVersion(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - long _return_value; - - _return_value = _winapi_GetVersion_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong(_return_value); - -exit: - return return_value; -} - +PyDoc_STRVAR(_winapi_CreateJunction__doc__, +"CreateJunction($module, src_path, dst_path, /)\n" +"--\n" +"\n"); + +#define _WINAPI_CREATEJUNCTION_METHODDEF \ + {"CreateJunction", (PyCFunction)(void(*)(void))_winapi_CreateJunction, METH_FASTCALL, _winapi_CreateJunction__doc__}, + +static PyObject * +_winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, + LPWSTR dst_path); + +static PyObject * +_winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + LPWSTR src_path; + LPWSTR dst_path; + + if (!_PyArg_ParseStack(args, nargs, "uu:CreateJunction", + &src_path, &dst_path)) { + goto exit; + } + return_value = _winapi_CreateJunction_impl(module, src_path, dst_path); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_CreateNamedPipe__doc__, +"CreateNamedPipe($module, name, open_mode, pipe_mode, max_instances,\n" +" out_buffer_size, in_buffer_size, default_timeout,\n" +" security_attributes, /)\n" +"--\n" +"\n"); + +#define _WINAPI_CREATENAMEDPIPE_METHODDEF \ + {"CreateNamedPipe", (PyCFunction)(void(*)(void))_winapi_CreateNamedPipe, METH_FASTCALL, _winapi_CreateNamedPipe__doc__}, + +static HANDLE +_winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode, + DWORD pipe_mode, DWORD max_instances, + DWORD out_buffer_size, DWORD in_buffer_size, + DWORD default_timeout, + LPSECURITY_ATTRIBUTES security_attributes); + +static PyObject * +_winapi_CreateNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + LPCTSTR name; + DWORD open_mode; + DWORD pipe_mode; + DWORD max_instances; + DWORD out_buffer_size; + DWORD in_buffer_size; + DWORD default_timeout; + LPSECURITY_ATTRIBUTES security_attributes; + HANDLE _return_value; + + if (!_PyArg_ParseStack(args, nargs, "skkkkkk" F_POINTER ":CreateNamedPipe", + &name, &open_mode, &pipe_mode, &max_instances, &out_buffer_size, &in_buffer_size, &default_timeout, &security_attributes)) { + goto exit; + } + _return_value = _winapi_CreateNamedPipe_impl(module, name, open_mode, pipe_mode, max_instances, out_buffer_size, in_buffer_size, default_timeout, security_attributes); + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { + goto exit; + } + if (_return_value == NULL) { + Py_RETURN_NONE; + } + return_value = HANDLE_TO_PYNUM(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_CreatePipe__doc__, +"CreatePipe($module, pipe_attrs, size, /)\n" +"--\n" +"\n" +"Create an anonymous pipe.\n" +"\n" +" pipe_attrs\n" +" Ignored internally, can be None.\n" +"\n" +"Returns a 2-tuple of handles, to the read and write ends of the pipe."); + +#define _WINAPI_CREATEPIPE_METHODDEF \ + {"CreatePipe", (PyCFunction)(void(*)(void))_winapi_CreatePipe, METH_FASTCALL, _winapi_CreatePipe__doc__}, + +static PyObject * +_winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size); + +static PyObject * +_winapi_CreatePipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *pipe_attrs; + DWORD size; + + if (!_PyArg_ParseStack(args, nargs, "Ok:CreatePipe", + &pipe_attrs, &size)) { + goto exit; + } + return_value = _winapi_CreatePipe_impl(module, pipe_attrs, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_CreateProcess__doc__, +"CreateProcess($module, application_name, command_line, proc_attrs,\n" +" thread_attrs, inherit_handles, creation_flags,\n" +" env_mapping, current_directory, startup_info, /)\n" +"--\n" +"\n" +"Create a new process and its primary thread.\n" +"\n" +" command_line\n" +" Can be str or None\n" +" proc_attrs\n" +" Ignored internally, can be None.\n" +" thread_attrs\n" +" Ignored internally, can be None.\n" +"\n" +"The return value is a tuple of the process handle, thread handle,\n" +"process ID, and thread ID."); + +#define _WINAPI_CREATEPROCESS_METHODDEF \ + {"CreateProcess", (PyCFunction)(void(*)(void))_winapi_CreateProcess, METH_FASTCALL, _winapi_CreateProcess__doc__}, + +static PyObject * +_winapi_CreateProcess_impl(PyObject *module, + const Py_UNICODE *application_name, + PyObject *command_line, PyObject *proc_attrs, + PyObject *thread_attrs, BOOL inherit_handles, + DWORD creation_flags, PyObject *env_mapping, + const Py_UNICODE *current_directory, + PyObject *startup_info); + +static PyObject * +_winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const Py_UNICODE *application_name; + PyObject *command_line; + PyObject *proc_attrs; + PyObject *thread_attrs; + BOOL inherit_handles; + DWORD creation_flags; + PyObject *env_mapping; + const Py_UNICODE *current_directory; + PyObject *startup_info; + + if (!_PyArg_ParseStack(args, nargs, "ZOOOikOZO:CreateProcess", + &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, ¤t_directory, &startup_info)) { + goto exit; + } + return_value = _winapi_CreateProcess_impl(module, application_name, command_line, proc_attrs, thread_attrs, inherit_handles, creation_flags, env_mapping, current_directory, startup_info); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_DuplicateHandle__doc__, +"DuplicateHandle($module, source_process_handle, source_handle,\n" +" target_process_handle, desired_access, inherit_handle,\n" +" options=0, /)\n" +"--\n" +"\n" +"Return a duplicate handle object.\n" +"\n" +"The duplicate handle refers to the same object as the original\n" +"handle. Therefore, any changes to the object are reflected\n" +"through both handles."); + +#define _WINAPI_DUPLICATEHANDLE_METHODDEF \ + {"DuplicateHandle", (PyCFunction)(void(*)(void))_winapi_DuplicateHandle, METH_FASTCALL, _winapi_DuplicateHandle__doc__}, + +static HANDLE +_winapi_DuplicateHandle_impl(PyObject *module, HANDLE source_process_handle, + HANDLE source_handle, + HANDLE target_process_handle, + DWORD desired_access, BOOL inherit_handle, + DWORD options); + +static PyObject * +_winapi_DuplicateHandle(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE source_process_handle; + HANDLE source_handle; + HANDLE target_process_handle; + DWORD desired_access; + BOOL inherit_handle; + DWORD options = 0; + HANDLE _return_value; + + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_HANDLE "" F_HANDLE "ki|k:DuplicateHandle", + &source_process_handle, &source_handle, &target_process_handle, &desired_access, &inherit_handle, &options)) { + goto exit; + } + _return_value = _winapi_DuplicateHandle_impl(module, source_process_handle, source_handle, target_process_handle, desired_access, inherit_handle, options); + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { + goto exit; + } + if (_return_value == NULL) { + Py_RETURN_NONE; + } + return_value = HANDLE_TO_PYNUM(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_ExitProcess__doc__, +"ExitProcess($module, ExitCode, /)\n" +"--\n" +"\n"); + +#define _WINAPI_EXITPROCESS_METHODDEF \ + {"ExitProcess", (PyCFunction)_winapi_ExitProcess, METH_O, _winapi_ExitProcess__doc__}, + +static PyObject * +_winapi_ExitProcess_impl(PyObject *module, UINT ExitCode); + +static PyObject * +_winapi_ExitProcess(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + UINT ExitCode; + + if (!PyArg_Parse(arg, "I:ExitProcess", &ExitCode)) { + goto exit; + } + return_value = _winapi_ExitProcess_impl(module, ExitCode); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_GetCurrentProcess__doc__, +"GetCurrentProcess($module, /)\n" +"--\n" +"\n" +"Return a handle object for the current process."); + +#define _WINAPI_GETCURRENTPROCESS_METHODDEF \ + {"GetCurrentProcess", (PyCFunction)_winapi_GetCurrentProcess, METH_NOARGS, _winapi_GetCurrentProcess__doc__}, + +static HANDLE +_winapi_GetCurrentProcess_impl(PyObject *module); + +static PyObject * +_winapi_GetCurrentProcess(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + HANDLE _return_value; + + _return_value = _winapi_GetCurrentProcess_impl(module); + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { + goto exit; + } + if (_return_value == NULL) { + Py_RETURN_NONE; + } + return_value = HANDLE_TO_PYNUM(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_GetExitCodeProcess__doc__, +"GetExitCodeProcess($module, process, /)\n" +"--\n" +"\n" +"Return the termination status of the specified process."); + +#define _WINAPI_GETEXITCODEPROCESS_METHODDEF \ + {"GetExitCodeProcess", (PyCFunction)_winapi_GetExitCodeProcess, METH_O, _winapi_GetExitCodeProcess__doc__}, + +static DWORD +_winapi_GetExitCodeProcess_impl(PyObject *module, HANDLE process); + +static PyObject * +_winapi_GetExitCodeProcess(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HANDLE process; + DWORD _return_value; + + if (!PyArg_Parse(arg, "" F_HANDLE ":GetExitCodeProcess", &process)) { + goto exit; + } + _return_value = _winapi_GetExitCodeProcess_impl(module, process); + if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { + goto exit; + } + return_value = Py_BuildValue("k", _return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_GetLastError__doc__, +"GetLastError($module, /)\n" +"--\n" +"\n"); + +#define _WINAPI_GETLASTERROR_METHODDEF \ + {"GetLastError", (PyCFunction)_winapi_GetLastError, METH_NOARGS, _winapi_GetLastError__doc__}, + +static DWORD +_winapi_GetLastError_impl(PyObject *module); + +static PyObject * +_winapi_GetLastError(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + DWORD _return_value; + + _return_value = _winapi_GetLastError_impl(module); + if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { + goto exit; + } + return_value = Py_BuildValue("k", _return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_GetModuleFileName__doc__, +"GetModuleFileName($module, module_handle, /)\n" +"--\n" +"\n" +"Return the fully-qualified path for the file that contains module.\n" +"\n" +"The module must have been loaded by the current process.\n" +"\n" +"The module parameter should be a handle to the loaded module\n" +"whose path is being requested. If this parameter is 0,\n" +"GetModuleFileName retrieves the path of the executable file\n" +"of the current process."); + +#define _WINAPI_GETMODULEFILENAME_METHODDEF \ + {"GetModuleFileName", (PyCFunction)_winapi_GetModuleFileName, METH_O, _winapi_GetModuleFileName__doc__}, + +static PyObject * +_winapi_GetModuleFileName_impl(PyObject *module, HMODULE module_handle); + +static PyObject * +_winapi_GetModuleFileName(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HMODULE module_handle; + + if (!PyArg_Parse(arg, "" F_HANDLE ":GetModuleFileName", &module_handle)) { + goto exit; + } + return_value = _winapi_GetModuleFileName_impl(module, module_handle); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_GetStdHandle__doc__, +"GetStdHandle($module, std_handle, /)\n" +"--\n" +"\n" +"Return a handle to the specified standard device.\n" +"\n" +" std_handle\n" +" One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE.\n" +"\n" +"The integer associated with the handle object is returned."); + +#define _WINAPI_GETSTDHANDLE_METHODDEF \ + {"GetStdHandle", (PyCFunction)_winapi_GetStdHandle, METH_O, _winapi_GetStdHandle__doc__}, + +static HANDLE +_winapi_GetStdHandle_impl(PyObject *module, DWORD std_handle); + +static PyObject * +_winapi_GetStdHandle(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + DWORD std_handle; + HANDLE _return_value; + + if (!PyArg_Parse(arg, "k:GetStdHandle", &std_handle)) { + goto exit; + } + _return_value = _winapi_GetStdHandle_impl(module, std_handle); + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { + goto exit; + } + if (_return_value == NULL) { + Py_RETURN_NONE; + } + return_value = HANDLE_TO_PYNUM(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_GetVersion__doc__, +"GetVersion($module, /)\n" +"--\n" +"\n" +"Return the version number of the current operating system."); + +#define _WINAPI_GETVERSION_METHODDEF \ + {"GetVersion", (PyCFunction)_winapi_GetVersion, METH_NOARGS, _winapi_GetVersion__doc__}, + +static long +_winapi_GetVersion_impl(PyObject *module); + +static PyObject * +_winapi_GetVersion(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + long _return_value; + + _return_value = _winapi_GetVersion_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + PyDoc_STRVAR(_winapi_MapViewOfFile__doc__, "MapViewOfFile($module, file_map, desired_access, file_offset_high,\n" " file_offset_low, number_bytes, /)\n" @@ -723,168 +723,168 @@ exit: return return_value; } -PyDoc_STRVAR(_winapi_OpenProcess__doc__, -"OpenProcess($module, desired_access, inherit_handle, process_id, /)\n" -"--\n" -"\n"); - -#define _WINAPI_OPENPROCESS_METHODDEF \ +PyDoc_STRVAR(_winapi_OpenProcess__doc__, +"OpenProcess($module, desired_access, inherit_handle, process_id, /)\n" +"--\n" +"\n"); + +#define _WINAPI_OPENPROCESS_METHODDEF \ {"OpenProcess", (PyCFunction)(void(*)(void))_winapi_OpenProcess, METH_FASTCALL, _winapi_OpenProcess__doc__}, - -static HANDLE -_winapi_OpenProcess_impl(PyObject *module, DWORD desired_access, - BOOL inherit_handle, DWORD process_id); - -static PyObject * -_winapi_OpenProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - DWORD desired_access; - BOOL inherit_handle; - DWORD process_id; - HANDLE _return_value; - - if (!_PyArg_ParseStack(args, nargs, "kik:OpenProcess", - &desired_access, &inherit_handle, &process_id)) { - goto exit; - } - _return_value = _winapi_OpenProcess_impl(module, desired_access, inherit_handle, process_id); - if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { - goto exit; - } - if (_return_value == NULL) { - Py_RETURN_NONE; - } - return_value = HANDLE_TO_PYNUM(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_PeekNamedPipe__doc__, -"PeekNamedPipe($module, handle, size=0, /)\n" -"--\n" -"\n"); - -#define _WINAPI_PEEKNAMEDPIPE_METHODDEF \ + +static HANDLE +_winapi_OpenProcess_impl(PyObject *module, DWORD desired_access, + BOOL inherit_handle, DWORD process_id); + +static PyObject * +_winapi_OpenProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + DWORD desired_access; + BOOL inherit_handle; + DWORD process_id; + HANDLE _return_value; + + if (!_PyArg_ParseStack(args, nargs, "kik:OpenProcess", + &desired_access, &inherit_handle, &process_id)) { + goto exit; + } + _return_value = _winapi_OpenProcess_impl(module, desired_access, inherit_handle, process_id); + if ((_return_value == INVALID_HANDLE_VALUE) && PyErr_Occurred()) { + goto exit; + } + if (_return_value == NULL) { + Py_RETURN_NONE; + } + return_value = HANDLE_TO_PYNUM(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_PeekNamedPipe__doc__, +"PeekNamedPipe($module, handle, size=0, /)\n" +"--\n" +"\n"); + +#define _WINAPI_PEEKNAMEDPIPE_METHODDEF \ {"PeekNamedPipe", (PyCFunction)(void(*)(void))_winapi_PeekNamedPipe, METH_FASTCALL, _winapi_PeekNamedPipe__doc__}, - -static PyObject * -_winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size); - -static PyObject * -_winapi_PeekNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - HANDLE handle; - int size = 0; - - if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "|i:PeekNamedPipe", - &handle, &size)) { - goto exit; - } - return_value = _winapi_PeekNamedPipe_impl(module, handle, size); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_ReadFile__doc__, -"ReadFile($module, /, handle, size, overlapped=False)\n" -"--\n" -"\n"); - -#define _WINAPI_READFILE_METHODDEF \ + +static PyObject * +_winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size); + +static PyObject * +_winapi_PeekNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + int size = 0; + + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "|i:PeekNamedPipe", + &handle, &size)) { + goto exit; + } + return_value = _winapi_PeekNamedPipe_impl(module, handle, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_ReadFile__doc__, +"ReadFile($module, /, handle, size, overlapped=False)\n" +"--\n" +"\n"); + +#define _WINAPI_READFILE_METHODDEF \ {"ReadFile", (PyCFunction)(void(*)(void))_winapi_ReadFile, METH_FASTCALL|METH_KEYWORDS, _winapi_ReadFile__doc__}, - -static PyObject * -_winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, - int use_overlapped); - -static PyObject * -_winapi_ReadFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"handle", "size", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "k|i:ReadFile", _keywords, 0}; - HANDLE handle; - DWORD size; - int use_overlapped = 0; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &handle, &size, &use_overlapped)) { - goto exit; - } - return_value = _winapi_ReadFile_impl(module, handle, size, use_overlapped); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_SetNamedPipeHandleState__doc__, -"SetNamedPipeHandleState($module, named_pipe, mode,\n" -" max_collection_count, collect_data_timeout, /)\n" -"--\n" -"\n"); - -#define _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF \ + +static PyObject * +_winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, + int use_overlapped); + +static PyObject * +_winapi_ReadFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"handle", "size", "overlapped", NULL}; + static _PyArg_Parser _parser = {"" F_HANDLE "k|i:ReadFile", _keywords, 0}; + HANDLE handle; + DWORD size; + int use_overlapped = 0; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &handle, &size, &use_overlapped)) { + goto exit; + } + return_value = _winapi_ReadFile_impl(module, handle, size, use_overlapped); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_SetNamedPipeHandleState__doc__, +"SetNamedPipeHandleState($module, named_pipe, mode,\n" +" max_collection_count, collect_data_timeout, /)\n" +"--\n" +"\n"); + +#define _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF \ {"SetNamedPipeHandleState", (PyCFunction)(void(*)(void))_winapi_SetNamedPipeHandleState, METH_FASTCALL, _winapi_SetNamedPipeHandleState__doc__}, - -static PyObject * -_winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe, - PyObject *mode, - PyObject *max_collection_count, - PyObject *collect_data_timeout); - -static PyObject * -_winapi_SetNamedPipeHandleState(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - HANDLE named_pipe; - PyObject *mode; - PyObject *max_collection_count; - PyObject *collect_data_timeout; - - if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "OOO:SetNamedPipeHandleState", - &named_pipe, &mode, &max_collection_count, &collect_data_timeout)) { - goto exit; - } - return_value = _winapi_SetNamedPipeHandleState_impl(module, named_pipe, mode, max_collection_count, collect_data_timeout); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_TerminateProcess__doc__, -"TerminateProcess($module, handle, exit_code, /)\n" -"--\n" -"\n" -"Terminate the specified process and all of its threads."); - -#define _WINAPI_TERMINATEPROCESS_METHODDEF \ + +static PyObject * +_winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe, + PyObject *mode, + PyObject *max_collection_count, + PyObject *collect_data_timeout); + +static PyObject * +_winapi_SetNamedPipeHandleState(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE named_pipe; + PyObject *mode; + PyObject *max_collection_count; + PyObject *collect_data_timeout; + + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "OOO:SetNamedPipeHandleState", + &named_pipe, &mode, &max_collection_count, &collect_data_timeout)) { + goto exit; + } + return_value = _winapi_SetNamedPipeHandleState_impl(module, named_pipe, mode, max_collection_count, collect_data_timeout); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_TerminateProcess__doc__, +"TerminateProcess($module, handle, exit_code, /)\n" +"--\n" +"\n" +"Terminate the specified process and all of its threads."); + +#define _WINAPI_TERMINATEPROCESS_METHODDEF \ {"TerminateProcess", (PyCFunction)(void(*)(void))_winapi_TerminateProcess, METH_FASTCALL, _winapi_TerminateProcess__doc__}, - -static PyObject * -_winapi_TerminateProcess_impl(PyObject *module, HANDLE handle, - UINT exit_code); - -static PyObject * -_winapi_TerminateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - HANDLE handle; - UINT exit_code; - - if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "I:TerminateProcess", - &handle, &exit_code)) { - goto exit; - } - return_value = _winapi_TerminateProcess_impl(module, handle, exit_code); - -exit: - return return_value; -} - + +static PyObject * +_winapi_TerminateProcess_impl(PyObject *module, HANDLE handle, + UINT exit_code); + +static PyObject * +_winapi_TerminateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + UINT exit_code; + + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "I:TerminateProcess", + &handle, &exit_code)) { + goto exit; + } + return_value = _winapi_TerminateProcess_impl(module, handle, exit_code); + +exit: + return return_value; +} + PyDoc_STRVAR(_winapi_VirtualQuerySize__doc__, "VirtualQuerySize($module, address, /)\n" "--\n" @@ -916,185 +916,185 @@ exit: return return_value; } -PyDoc_STRVAR(_winapi_WaitNamedPipe__doc__, -"WaitNamedPipe($module, name, timeout, /)\n" -"--\n" -"\n"); - -#define _WINAPI_WAITNAMEDPIPE_METHODDEF \ +PyDoc_STRVAR(_winapi_WaitNamedPipe__doc__, +"WaitNamedPipe($module, name, timeout, /)\n" +"--\n" +"\n"); + +#define _WINAPI_WAITNAMEDPIPE_METHODDEF \ {"WaitNamedPipe", (PyCFunction)(void(*)(void))_winapi_WaitNamedPipe, METH_FASTCALL, _winapi_WaitNamedPipe__doc__}, - -static PyObject * -_winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout); - -static PyObject * -_winapi_WaitNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - LPCTSTR name; - DWORD timeout; - - if (!_PyArg_ParseStack(args, nargs, "sk:WaitNamedPipe", - &name, &timeout)) { - goto exit; - } - return_value = _winapi_WaitNamedPipe_impl(module, name, timeout); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_WaitForMultipleObjects__doc__, -"WaitForMultipleObjects($module, handle_seq, wait_flag,\n" -" milliseconds=_winapi.INFINITE, /)\n" -"--\n" -"\n"); - -#define _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF \ + +static PyObject * +_winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout); + +static PyObject * +_winapi_WaitNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + LPCTSTR name; + DWORD timeout; + + if (!_PyArg_ParseStack(args, nargs, "sk:WaitNamedPipe", + &name, &timeout)) { + goto exit; + } + return_value = _winapi_WaitNamedPipe_impl(module, name, timeout); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_WaitForMultipleObjects__doc__, +"WaitForMultipleObjects($module, handle_seq, wait_flag,\n" +" milliseconds=_winapi.INFINITE, /)\n" +"--\n" +"\n"); + +#define _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF \ {"WaitForMultipleObjects", (PyCFunction)(void(*)(void))_winapi_WaitForMultipleObjects, METH_FASTCALL, _winapi_WaitForMultipleObjects__doc__}, - -static PyObject * -_winapi_WaitForMultipleObjects_impl(PyObject *module, PyObject *handle_seq, - BOOL wait_flag, DWORD milliseconds); - -static PyObject * -_winapi_WaitForMultipleObjects(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *handle_seq; - BOOL wait_flag; - DWORD milliseconds = INFINITE; - - if (!_PyArg_ParseStack(args, nargs, "Oi|k:WaitForMultipleObjects", - &handle_seq, &wait_flag, &milliseconds)) { - goto exit; - } - return_value = _winapi_WaitForMultipleObjects_impl(module, handle_seq, wait_flag, milliseconds); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_WaitForSingleObject__doc__, -"WaitForSingleObject($module, handle, milliseconds, /)\n" -"--\n" -"\n" -"Wait for a single object.\n" -"\n" -"Wait until the specified object is in the signaled state or\n" -"the time-out interval elapses. The timeout value is specified\n" -"in milliseconds."); - -#define _WINAPI_WAITFORSINGLEOBJECT_METHODDEF \ + +static PyObject * +_winapi_WaitForMultipleObjects_impl(PyObject *module, PyObject *handle_seq, + BOOL wait_flag, DWORD milliseconds); + +static PyObject * +_winapi_WaitForMultipleObjects(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *handle_seq; + BOOL wait_flag; + DWORD milliseconds = INFINITE; + + if (!_PyArg_ParseStack(args, nargs, "Oi|k:WaitForMultipleObjects", + &handle_seq, &wait_flag, &milliseconds)) { + goto exit; + } + return_value = _winapi_WaitForMultipleObjects_impl(module, handle_seq, wait_flag, milliseconds); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_WaitForSingleObject__doc__, +"WaitForSingleObject($module, handle, milliseconds, /)\n" +"--\n" +"\n" +"Wait for a single object.\n" +"\n" +"Wait until the specified object is in the signaled state or\n" +"the time-out interval elapses. The timeout value is specified\n" +"in milliseconds."); + +#define _WINAPI_WAITFORSINGLEOBJECT_METHODDEF \ {"WaitForSingleObject", (PyCFunction)(void(*)(void))_winapi_WaitForSingleObject, METH_FASTCALL, _winapi_WaitForSingleObject__doc__}, - -static long -_winapi_WaitForSingleObject_impl(PyObject *module, HANDLE handle, - DWORD milliseconds); - -static PyObject * -_winapi_WaitForSingleObject(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - HANDLE handle; - DWORD milliseconds; - long _return_value; - - if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "k:WaitForSingleObject", - &handle, &milliseconds)) { - goto exit; - } - _return_value = _winapi_WaitForSingleObject_impl(module, handle, milliseconds); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_WriteFile__doc__, -"WriteFile($module, /, handle, buffer, overlapped=False)\n" -"--\n" -"\n"); - -#define _WINAPI_WRITEFILE_METHODDEF \ + +static long +_winapi_WaitForSingleObject_impl(PyObject *module, HANDLE handle, + DWORD milliseconds); + +static PyObject * +_winapi_WaitForSingleObject(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + DWORD milliseconds; + long _return_value; + + if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "k:WaitForSingleObject", + &handle, &milliseconds)) { + goto exit; + } + _return_value = _winapi_WaitForSingleObject_impl(module, handle, milliseconds); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_WriteFile__doc__, +"WriteFile($module, /, handle, buffer, overlapped=False)\n" +"--\n" +"\n"); + +#define _WINAPI_WRITEFILE_METHODDEF \ {"WriteFile", (PyCFunction)(void(*)(void))_winapi_WriteFile, METH_FASTCALL|METH_KEYWORDS, _winapi_WriteFile__doc__}, - -static PyObject * -_winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, - int use_overlapped); - -static PyObject * -_winapi_WriteFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"handle", "buffer", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "O|i:WriteFile", _keywords, 0}; - HANDLE handle; - PyObject *buffer; - int use_overlapped = 0; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &handle, &buffer, &use_overlapped)) { - goto exit; - } - return_value = _winapi_WriteFile_impl(module, handle, buffer, use_overlapped); - -exit: - return return_value; -} - -PyDoc_STRVAR(_winapi_GetACP__doc__, -"GetACP($module, /)\n" -"--\n" -"\n" -"Get the current Windows ANSI code page identifier."); - -#define _WINAPI_GETACP_METHODDEF \ - {"GetACP", (PyCFunction)_winapi_GetACP, METH_NOARGS, _winapi_GetACP__doc__}, - -static PyObject * -_winapi_GetACP_impl(PyObject *module); - -static PyObject * -_winapi_GetACP(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return _winapi_GetACP_impl(module); -} - -PyDoc_STRVAR(_winapi_GetFileType__doc__, -"GetFileType($module, /, handle)\n" -"--\n" -"\n"); - -#define _WINAPI_GETFILETYPE_METHODDEF \ + +static PyObject * +_winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, + int use_overlapped); + +static PyObject * +_winapi_WriteFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"handle", "buffer", "overlapped", NULL}; + static _PyArg_Parser _parser = {"" F_HANDLE "O|i:WriteFile", _keywords, 0}; + HANDLE handle; + PyObject *buffer; + int use_overlapped = 0; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &handle, &buffer, &use_overlapped)) { + goto exit; + } + return_value = _winapi_WriteFile_impl(module, handle, buffer, use_overlapped); + +exit: + return return_value; +} + +PyDoc_STRVAR(_winapi_GetACP__doc__, +"GetACP($module, /)\n" +"--\n" +"\n" +"Get the current Windows ANSI code page identifier."); + +#define _WINAPI_GETACP_METHODDEF \ + {"GetACP", (PyCFunction)_winapi_GetACP, METH_NOARGS, _winapi_GetACP__doc__}, + +static PyObject * +_winapi_GetACP_impl(PyObject *module); + +static PyObject * +_winapi_GetACP(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _winapi_GetACP_impl(module); +} + +PyDoc_STRVAR(_winapi_GetFileType__doc__, +"GetFileType($module, /, handle)\n" +"--\n" +"\n"); + +#define _WINAPI_GETFILETYPE_METHODDEF \ {"GetFileType", (PyCFunction)(void(*)(void))_winapi_GetFileType, METH_FASTCALL|METH_KEYWORDS, _winapi_GetFileType__doc__}, - -static DWORD -_winapi_GetFileType_impl(PyObject *module, HANDLE handle); - -static PyObject * -_winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"handle", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE ":GetFileType", _keywords, 0}; - HANDLE handle; - DWORD _return_value; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &handle)) { - goto exit; - } - _return_value = _winapi_GetFileType_impl(module, handle); - if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { - goto exit; - } - return_value = Py_BuildValue("k", _return_value); - -exit: - return return_value; -} + +static DWORD +_winapi_GetFileType_impl(PyObject *module, HANDLE handle); + +static PyObject * +_winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"handle", NULL}; + static _PyArg_Parser _parser = {"" F_HANDLE ":GetFileType", _keywords, 0}; + HANDLE handle; + DWORD _return_value; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &handle)) { + goto exit; + } + _return_value = _winapi_GetFileType_impl(module, handle); + if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { + goto exit; + } + return_value = Py_BuildValue("k", _return_value); + +exit: + return return_value; +} /*[clinic end generated code: output=f3897898ea1da99d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/arraymodule.c.h b/contrib/tools/python3/src/Modules/clinic/arraymodule.c.h index 005c7ffce4d..ad697b91de4 100644 --- a/contrib/tools/python3/src/Modules/clinic/arraymodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/arraymodule.c.h @@ -1,84 +1,84 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(array_array___copy____doc__, -"__copy__($self, /)\n" -"--\n" -"\n" -"Return a copy of the array."); - -#define ARRAY_ARRAY___COPY___METHODDEF \ - {"__copy__", (PyCFunction)array_array___copy__, METH_NOARGS, array_array___copy____doc__}, - -static PyObject * -array_array___copy___impl(arrayobject *self); - -static PyObject * -array_array___copy__(arrayobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_array___copy___impl(self); -} - -PyDoc_STRVAR(array_array___deepcopy____doc__, -"__deepcopy__($self, unused, /)\n" -"--\n" -"\n" -"Return a copy of the array."); - -#define ARRAY_ARRAY___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)array_array___deepcopy__, METH_O, array_array___deepcopy____doc__}, - -PyDoc_STRVAR(array_array_count__doc__, -"count($self, v, /)\n" -"--\n" -"\n" -"Return number of occurrences of v in the array."); - -#define ARRAY_ARRAY_COUNT_METHODDEF \ - {"count", (PyCFunction)array_array_count, METH_O, array_array_count__doc__}, - -PyDoc_STRVAR(array_array_index__doc__, -"index($self, v, /)\n" -"--\n" -"\n" -"Return index of first occurrence of v in the array."); - -#define ARRAY_ARRAY_INDEX_METHODDEF \ - {"index", (PyCFunction)array_array_index, METH_O, array_array_index__doc__}, - -PyDoc_STRVAR(array_array_remove__doc__, -"remove($self, v, /)\n" -"--\n" -"\n" -"Remove the first occurrence of v in the array."); - -#define ARRAY_ARRAY_REMOVE_METHODDEF \ - {"remove", (PyCFunction)array_array_remove, METH_O, array_array_remove__doc__}, - -PyDoc_STRVAR(array_array_pop__doc__, -"pop($self, i=-1, /)\n" -"--\n" -"\n" -"Return the i-th element and delete it from the array.\n" -"\n" -"i defaults to -1."); - -#define ARRAY_ARRAY_POP_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(array_array___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n" +"Return a copy of the array."); + +#define ARRAY_ARRAY___COPY___METHODDEF \ + {"__copy__", (PyCFunction)array_array___copy__, METH_NOARGS, array_array___copy____doc__}, + +static PyObject * +array_array___copy___impl(arrayobject *self); + +static PyObject * +array_array___copy__(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array___copy___impl(self); +} + +PyDoc_STRVAR(array_array___deepcopy____doc__, +"__deepcopy__($self, unused, /)\n" +"--\n" +"\n" +"Return a copy of the array."); + +#define ARRAY_ARRAY___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)array_array___deepcopy__, METH_O, array_array___deepcopy____doc__}, + +PyDoc_STRVAR(array_array_count__doc__, +"count($self, v, /)\n" +"--\n" +"\n" +"Return number of occurrences of v in the array."); + +#define ARRAY_ARRAY_COUNT_METHODDEF \ + {"count", (PyCFunction)array_array_count, METH_O, array_array_count__doc__}, + +PyDoc_STRVAR(array_array_index__doc__, +"index($self, v, /)\n" +"--\n" +"\n" +"Return index of first occurrence of v in the array."); + +#define ARRAY_ARRAY_INDEX_METHODDEF \ + {"index", (PyCFunction)array_array_index, METH_O, array_array_index__doc__}, + +PyDoc_STRVAR(array_array_remove__doc__, +"remove($self, v, /)\n" +"--\n" +"\n" +"Remove the first occurrence of v in the array."); + +#define ARRAY_ARRAY_REMOVE_METHODDEF \ + {"remove", (PyCFunction)array_array_remove, METH_O, array_array_remove__doc__}, + +PyDoc_STRVAR(array_array_pop__doc__, +"pop($self, i=-1, /)\n" +"--\n" +"\n" +"Return the i-th element and delete it from the array.\n" +"\n" +"i defaults to -1."); + +#define ARRAY_ARRAY_POP_METHODDEF \ {"pop", (PyCFunction)(void(*)(void))array_array_pop, METH_FASTCALL, array_array_pop__doc__}, - -static PyObject * -array_array_pop_impl(arrayobject *self, Py_ssize_t i); - -static PyObject * -array_array_pop(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t i = -1; - + +static PyObject * +array_array_pop_impl(arrayobject *self, Py_ssize_t i); + +static PyObject * +array_array_pop(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t i = -1; + if (!_PyArg_CheckPositional("pop", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -100,43 +100,43 @@ array_array_pop(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) i = ival; } skip_optional: - return_value = array_array_pop_impl(self, i); - -exit: - return return_value; -} - -PyDoc_STRVAR(array_array_extend__doc__, -"extend($self, bb, /)\n" -"--\n" -"\n" -"Append items to the end of the array."); - -#define ARRAY_ARRAY_EXTEND_METHODDEF \ - {"extend", (PyCFunction)array_array_extend, METH_O, array_array_extend__doc__}, - -PyDoc_STRVAR(array_array_insert__doc__, -"insert($self, i, v, /)\n" -"--\n" -"\n" -"Insert a new item v into the array before position i."); - -#define ARRAY_ARRAY_INSERT_METHODDEF \ + return_value = array_array_pop_impl(self, i); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array_extend__doc__, +"extend($self, bb, /)\n" +"--\n" +"\n" +"Append items to the end of the array."); + +#define ARRAY_ARRAY_EXTEND_METHODDEF \ + {"extend", (PyCFunction)array_array_extend, METH_O, array_array_extend__doc__}, + +PyDoc_STRVAR(array_array_insert__doc__, +"insert($self, i, v, /)\n" +"--\n" +"\n" +"Insert a new item v into the array before position i."); + +#define ARRAY_ARRAY_INSERT_METHODDEF \ {"insert", (PyCFunction)(void(*)(void))array_array_insert, METH_FASTCALL, array_array_insert__doc__}, - -static PyObject * -array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v); - -static PyObject * -array_array_insert(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t i; - PyObject *v; - + +static PyObject * +array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v); + +static PyObject * +array_array_insert(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t i; + PyObject *v; + if (!_PyArg_CheckPositional("insert", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -155,103 +155,103 @@ array_array_insert(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) i = ival; } v = args[1]; - return_value = array_array_insert_impl(self, i, v); - -exit: - return return_value; -} - -PyDoc_STRVAR(array_array_buffer_info__doc__, -"buffer_info($self, /)\n" -"--\n" -"\n" -"Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array\'s contents.\n" -"\n" -"The length should be multiplied by the itemsize attribute to calculate\n" -"the buffer length in bytes."); - -#define ARRAY_ARRAY_BUFFER_INFO_METHODDEF \ - {"buffer_info", (PyCFunction)array_array_buffer_info, METH_NOARGS, array_array_buffer_info__doc__}, - -static PyObject * -array_array_buffer_info_impl(arrayobject *self); - -static PyObject * -array_array_buffer_info(arrayobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_array_buffer_info_impl(self); -} - -PyDoc_STRVAR(array_array_append__doc__, -"append($self, v, /)\n" -"--\n" -"\n" -"Append new value v to the end of the array."); - -#define ARRAY_ARRAY_APPEND_METHODDEF \ - {"append", (PyCFunction)array_array_append, METH_O, array_array_append__doc__}, - -PyDoc_STRVAR(array_array_byteswap__doc__, -"byteswap($self, /)\n" -"--\n" -"\n" -"Byteswap all items of the array.\n" -"\n" -"If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is\n" -"raised."); - -#define ARRAY_ARRAY_BYTESWAP_METHODDEF \ - {"byteswap", (PyCFunction)array_array_byteswap, METH_NOARGS, array_array_byteswap__doc__}, - -static PyObject * -array_array_byteswap_impl(arrayobject *self); - -static PyObject * -array_array_byteswap(arrayobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_array_byteswap_impl(self); -} - -PyDoc_STRVAR(array_array_reverse__doc__, -"reverse($self, /)\n" -"--\n" -"\n" -"Reverse the order of the items in the array."); - -#define ARRAY_ARRAY_REVERSE_METHODDEF \ - {"reverse", (PyCFunction)array_array_reverse, METH_NOARGS, array_array_reverse__doc__}, - -static PyObject * -array_array_reverse_impl(arrayobject *self); - -static PyObject * -array_array_reverse(arrayobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_array_reverse_impl(self); -} - -PyDoc_STRVAR(array_array_fromfile__doc__, -"fromfile($self, f, n, /)\n" -"--\n" -"\n" -"Read n objects from the file object f and append them to the end of the array."); - -#define ARRAY_ARRAY_FROMFILE_METHODDEF \ + return_value = array_array_insert_impl(self, i, v); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array_buffer_info__doc__, +"buffer_info($self, /)\n" +"--\n" +"\n" +"Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array\'s contents.\n" +"\n" +"The length should be multiplied by the itemsize attribute to calculate\n" +"the buffer length in bytes."); + +#define ARRAY_ARRAY_BUFFER_INFO_METHODDEF \ + {"buffer_info", (PyCFunction)array_array_buffer_info, METH_NOARGS, array_array_buffer_info__doc__}, + +static PyObject * +array_array_buffer_info_impl(arrayobject *self); + +static PyObject * +array_array_buffer_info(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_buffer_info_impl(self); +} + +PyDoc_STRVAR(array_array_append__doc__, +"append($self, v, /)\n" +"--\n" +"\n" +"Append new value v to the end of the array."); + +#define ARRAY_ARRAY_APPEND_METHODDEF \ + {"append", (PyCFunction)array_array_append, METH_O, array_array_append__doc__}, + +PyDoc_STRVAR(array_array_byteswap__doc__, +"byteswap($self, /)\n" +"--\n" +"\n" +"Byteswap all items of the array.\n" +"\n" +"If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is\n" +"raised."); + +#define ARRAY_ARRAY_BYTESWAP_METHODDEF \ + {"byteswap", (PyCFunction)array_array_byteswap, METH_NOARGS, array_array_byteswap__doc__}, + +static PyObject * +array_array_byteswap_impl(arrayobject *self); + +static PyObject * +array_array_byteswap(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_byteswap_impl(self); +} + +PyDoc_STRVAR(array_array_reverse__doc__, +"reverse($self, /)\n" +"--\n" +"\n" +"Reverse the order of the items in the array."); + +#define ARRAY_ARRAY_REVERSE_METHODDEF \ + {"reverse", (PyCFunction)array_array_reverse, METH_NOARGS, array_array_reverse__doc__}, + +static PyObject * +array_array_reverse_impl(arrayobject *self); + +static PyObject * +array_array_reverse(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_reverse_impl(self); +} + +PyDoc_STRVAR(array_array_fromfile__doc__, +"fromfile($self, f, n, /)\n" +"--\n" +"\n" +"Read n objects from the file object f and append them to the end of the array."); + +#define ARRAY_ARRAY_FROMFILE_METHODDEF \ {"fromfile", (PyCFunction)(void(*)(void))array_array_fromfile, METH_FASTCALL, array_array_fromfile__doc__}, - -static PyObject * -array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n); - -static PyObject * -array_array_fromfile(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *f; - Py_ssize_t n; - + +static PyObject * +array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n); + +static PyObject * +array_array_fromfile(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *f; + Py_ssize_t n; + if (!_PyArg_CheckPositional("fromfile", nargs, 2, 2)) { - goto exit; - } + goto exit; + } f = args[0]; if (PyFloat_Check(args[1])) { PyErr_SetString(PyExc_TypeError, @@ -270,206 +270,206 @@ array_array_fromfile(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) } n = ival; } - return_value = array_array_fromfile_impl(self, f, n); - -exit: - return return_value; -} - -PyDoc_STRVAR(array_array_tofile__doc__, -"tofile($self, f, /)\n" -"--\n" -"\n" -"Write all items (as machine values) to the file object f."); - -#define ARRAY_ARRAY_TOFILE_METHODDEF \ - {"tofile", (PyCFunction)array_array_tofile, METH_O, array_array_tofile__doc__}, - -PyDoc_STRVAR(array_array_fromlist__doc__, -"fromlist($self, list, /)\n" -"--\n" -"\n" -"Append items to array from list."); - -#define ARRAY_ARRAY_FROMLIST_METHODDEF \ - {"fromlist", (PyCFunction)array_array_fromlist, METH_O, array_array_fromlist__doc__}, - -PyDoc_STRVAR(array_array_tolist__doc__, -"tolist($self, /)\n" -"--\n" -"\n" -"Convert array to an ordinary list with the same items."); - -#define ARRAY_ARRAY_TOLIST_METHODDEF \ - {"tolist", (PyCFunction)array_array_tolist, METH_NOARGS, array_array_tolist__doc__}, - -static PyObject * -array_array_tolist_impl(arrayobject *self); - -static PyObject * -array_array_tolist(arrayobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_array_tolist_impl(self); -} - -PyDoc_STRVAR(array_array_frombytes__doc__, -"frombytes($self, buffer, /)\n" -"--\n" -"\n" + return_value = array_array_fromfile_impl(self, f, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array_tofile__doc__, +"tofile($self, f, /)\n" +"--\n" +"\n" +"Write all items (as machine values) to the file object f."); + +#define ARRAY_ARRAY_TOFILE_METHODDEF \ + {"tofile", (PyCFunction)array_array_tofile, METH_O, array_array_tofile__doc__}, + +PyDoc_STRVAR(array_array_fromlist__doc__, +"fromlist($self, list, /)\n" +"--\n" +"\n" +"Append items to array from list."); + +#define ARRAY_ARRAY_FROMLIST_METHODDEF \ + {"fromlist", (PyCFunction)array_array_fromlist, METH_O, array_array_fromlist__doc__}, + +PyDoc_STRVAR(array_array_tolist__doc__, +"tolist($self, /)\n" +"--\n" +"\n" +"Convert array to an ordinary list with the same items."); + +#define ARRAY_ARRAY_TOLIST_METHODDEF \ + {"tolist", (PyCFunction)array_array_tolist, METH_NOARGS, array_array_tolist__doc__}, + +static PyObject * +array_array_tolist_impl(arrayobject *self); + +static PyObject * +array_array_tolist(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_tolist_impl(self); +} + +PyDoc_STRVAR(array_array_frombytes__doc__, +"frombytes($self, buffer, /)\n" +"--\n" +"\n" "Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method."); - -#define ARRAY_ARRAY_FROMBYTES_METHODDEF \ - {"frombytes", (PyCFunction)array_array_frombytes, METH_O, array_array_frombytes__doc__}, - -static PyObject * -array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer); - -static PyObject * -array_array_frombytes(arrayobject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer buffer = {NULL, NULL}; - + +#define ARRAY_ARRAY_FROMBYTES_METHODDEF \ + {"frombytes", (PyCFunction)array_array_frombytes, METH_O, array_array_frombytes__doc__}, + +static PyObject * +array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer); + +static PyObject * +array_array_frombytes(arrayobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&buffer, 'C')) { _PyArg_BadArgument("frombytes", "argument", "contiguous buffer", arg); goto exit; } - return_value = array_array_frombytes_impl(self, &buffer); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); - } - - return return_value; -} - -PyDoc_STRVAR(array_array_tobytes__doc__, -"tobytes($self, /)\n" -"--\n" -"\n" -"Convert the array to an array of machine values and return the bytes representation."); - -#define ARRAY_ARRAY_TOBYTES_METHODDEF \ - {"tobytes", (PyCFunction)array_array_tobytes, METH_NOARGS, array_array_tobytes__doc__}, - -static PyObject * -array_array_tobytes_impl(arrayobject *self); - -static PyObject * -array_array_tobytes(arrayobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_array_tobytes_impl(self); -} - -PyDoc_STRVAR(array_array_fromunicode__doc__, -"fromunicode($self, ustr, /)\n" -"--\n" -"\n" -"Extends this array with data from the unicode string ustr.\n" -"\n" -"The array must be a unicode type array; otherwise a ValueError is raised.\n" -"Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of\n" -"some other type."); - -#define ARRAY_ARRAY_FROMUNICODE_METHODDEF \ - {"fromunicode", (PyCFunction)array_array_fromunicode, METH_O, array_array_fromunicode__doc__}, - -static PyObject * + return_value = array_array_frombytes_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +PyDoc_STRVAR(array_array_tobytes__doc__, +"tobytes($self, /)\n" +"--\n" +"\n" +"Convert the array to an array of machine values and return the bytes representation."); + +#define ARRAY_ARRAY_TOBYTES_METHODDEF \ + {"tobytes", (PyCFunction)array_array_tobytes, METH_NOARGS, array_array_tobytes__doc__}, + +static PyObject * +array_array_tobytes_impl(arrayobject *self); + +static PyObject * +array_array_tobytes(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_tobytes_impl(self); +} + +PyDoc_STRVAR(array_array_fromunicode__doc__, +"fromunicode($self, ustr, /)\n" +"--\n" +"\n" +"Extends this array with data from the unicode string ustr.\n" +"\n" +"The array must be a unicode type array; otherwise a ValueError is raised.\n" +"Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of\n" +"some other type."); + +#define ARRAY_ARRAY_FROMUNICODE_METHODDEF \ + {"fromunicode", (PyCFunction)array_array_fromunicode, METH_O, array_array_fromunicode__doc__}, + +static PyObject * array_array_fromunicode_impl(arrayobject *self, PyObject *ustr); - -static PyObject * -array_array_fromunicode(arrayobject *self, PyObject *arg) -{ - PyObject *return_value = NULL; + +static PyObject * +array_array_fromunicode(arrayobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; PyObject *ustr; - + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("fromunicode", "argument", "str", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg) == -1) { goto exit; } ustr = arg; return_value = array_array_fromunicode_impl(self, ustr); - -exit: - return return_value; -} - -PyDoc_STRVAR(array_array_tounicode__doc__, -"tounicode($self, /)\n" -"--\n" -"\n" -"Extends this array with data from the unicode string ustr.\n" -"\n" -"Convert the array to a unicode string. The array must be a unicode type array;\n" -"otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a\n" -"unicode string from an array of some other type."); - -#define ARRAY_ARRAY_TOUNICODE_METHODDEF \ - {"tounicode", (PyCFunction)array_array_tounicode, METH_NOARGS, array_array_tounicode__doc__}, - -static PyObject * -array_array_tounicode_impl(arrayobject *self); - -static PyObject * -array_array_tounicode(arrayobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_array_tounicode_impl(self); -} - -PyDoc_STRVAR(array_array___sizeof____doc__, -"__sizeof__($self, /)\n" -"--\n" -"\n" -"Size of the array in memory, in bytes."); - -#define ARRAY_ARRAY___SIZEOF___METHODDEF \ - {"__sizeof__", (PyCFunction)array_array___sizeof__, METH_NOARGS, array_array___sizeof____doc__}, - -static PyObject * -array_array___sizeof___impl(arrayobject *self); - -static PyObject * -array_array___sizeof__(arrayobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_array___sizeof___impl(self); -} - -PyDoc_STRVAR(array__array_reconstructor__doc__, -"_array_reconstructor($module, arraytype, typecode, mformat_code, items,\n" -" /)\n" -"--\n" -"\n" -"Internal. Used for pickling support."); - -#define ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF \ + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array_tounicode__doc__, +"tounicode($self, /)\n" +"--\n" +"\n" +"Extends this array with data from the unicode string ustr.\n" +"\n" +"Convert the array to a unicode string. The array must be a unicode type array;\n" +"otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a\n" +"unicode string from an array of some other type."); + +#define ARRAY_ARRAY_TOUNICODE_METHODDEF \ + {"tounicode", (PyCFunction)array_array_tounicode, METH_NOARGS, array_array_tounicode__doc__}, + +static PyObject * +array_array_tounicode_impl(arrayobject *self); + +static PyObject * +array_array_tounicode(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_tounicode_impl(self); +} + +PyDoc_STRVAR(array_array___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Size of the array in memory, in bytes."); + +#define ARRAY_ARRAY___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)array_array___sizeof__, METH_NOARGS, array_array___sizeof____doc__}, + +static PyObject * +array_array___sizeof___impl(arrayobject *self); + +static PyObject * +array_array___sizeof__(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array___sizeof___impl(self); +} + +PyDoc_STRVAR(array__array_reconstructor__doc__, +"_array_reconstructor($module, arraytype, typecode, mformat_code, items,\n" +" /)\n" +"--\n" +"\n" +"Internal. Used for pickling support."); + +#define ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF \ {"_array_reconstructor", (PyCFunction)(void(*)(void))array__array_reconstructor, METH_FASTCALL, array__array_reconstructor__doc__}, - -static PyObject * -array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, - int typecode, - enum machine_format_code mformat_code, - PyObject *items); - -static PyObject * -array__array_reconstructor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyTypeObject *arraytype; - int typecode; - enum machine_format_code mformat_code; - PyObject *items; - + +static PyObject * +array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, + int typecode, + enum machine_format_code mformat_code, + PyObject *items); + +static PyObject * +array__array_reconstructor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyTypeObject *arraytype; + int typecode; + enum machine_format_code mformat_code; + PyObject *items; + if (!_PyArg_CheckPositional("_array_reconstructor", nargs, 4, 4)) { - goto exit; - } + goto exit; + } arraytype = (PyTypeObject *)args[0]; if (!PyUnicode_Check(args[1])) { _PyArg_BadArgument("_array_reconstructor", "argument 2", "a unicode character", args[1]); @@ -493,45 +493,45 @@ array__array_reconstructor(PyObject *module, PyObject *const *args, Py_ssize_t n goto exit; } items = args[3]; - return_value = array__array_reconstructor_impl(module, arraytype, typecode, mformat_code, items); - -exit: - return return_value; -} - -PyDoc_STRVAR(array_array___reduce_ex____doc__, -"__reduce_ex__($self, value, /)\n" -"--\n" -"\n" -"Return state information for pickling."); - -#define ARRAY_ARRAY___REDUCE_EX___METHODDEF \ - {"__reduce_ex__", (PyCFunction)array_array___reduce_ex__, METH_O, array_array___reduce_ex____doc__}, - -PyDoc_STRVAR(array_arrayiterator___reduce____doc__, -"__reduce__($self, /)\n" -"--\n" -"\n" -"Return state information for pickling."); - -#define ARRAY_ARRAYITERATOR___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)array_arrayiterator___reduce__, METH_NOARGS, array_arrayiterator___reduce____doc__}, - -static PyObject * -array_arrayiterator___reduce___impl(arrayiterobject *self); - -static PyObject * -array_arrayiterator___reduce__(arrayiterobject *self, PyObject *Py_UNUSED(ignored)) -{ - return array_arrayiterator___reduce___impl(self); -} - -PyDoc_STRVAR(array_arrayiterator___setstate____doc__, -"__setstate__($self, state, /)\n" -"--\n" -"\n" -"Set state information for unpickling."); - -#define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ - {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, + return_value = array__array_reconstructor_impl(module, arraytype, typecode, mformat_code, items); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array___reduce_ex____doc__, +"__reduce_ex__($self, value, /)\n" +"--\n" +"\n" +"Return state information for pickling."); + +#define ARRAY_ARRAY___REDUCE_EX___METHODDEF \ + {"__reduce_ex__", (PyCFunction)array_array___reduce_ex__, METH_O, array_array___reduce_ex____doc__}, + +PyDoc_STRVAR(array_arrayiterator___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Return state information for pickling."); + +#define ARRAY_ARRAYITERATOR___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)array_arrayiterator___reduce__, METH_NOARGS, array_arrayiterator___reduce____doc__}, + +static PyObject * +array_arrayiterator___reduce___impl(arrayiterobject *self); + +static PyObject * +array_arrayiterator___reduce__(arrayiterobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_arrayiterator___reduce___impl(self); +} + +PyDoc_STRVAR(array_arrayiterator___setstate____doc__, +"__setstate__($self, state, /)\n" +"--\n" +"\n" +"Set state information for unpickling."); + +#define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ + {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, /*[clinic end generated code: output=485e848d1f3d05e7 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/audioop.c.h b/contrib/tools/python3/src/Modules/clinic/audioop.c.h index 8745533eeb6..6b338c260b0 100644 --- a/contrib/tools/python3/src/Modules/clinic/audioop.c.h +++ b/contrib/tools/python3/src/Modules/clinic/audioop.c.h @@ -1,31 +1,31 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(audioop_getsample__doc__, -"getsample($module, fragment, width, index, /)\n" -"--\n" -"\n" -"Return the value of sample index from the fragment."); - -#define AUDIOOP_GETSAMPLE_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(audioop_getsample__doc__, +"getsample($module, fragment, width, index, /)\n" +"--\n" +"\n" +"Return the value of sample index from the fragment."); + +#define AUDIOOP_GETSAMPLE_METHODDEF \ {"getsample", (PyCFunction)(void(*)(void))audioop_getsample, METH_FASTCALL, audioop_getsample__doc__}, - -static PyObject * -audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width, - Py_ssize_t index); - -static PyObject * -audioop_getsample(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - Py_ssize_t index; - + +static PyObject * +audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width, + Py_ssize_t index); + +static PyObject * +audioop_getsample(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + Py_ssize_t index; + if (!_PyArg_CheckPositional("getsample", nargs, 3, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -59,39 +59,39 @@ audioop_getsample(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } index = ival; } - return_value = audioop_getsample_impl(module, &fragment, width, index); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_max__doc__, -"max($module, fragment, width, /)\n" -"--\n" -"\n" -"Return the maximum of the absolute value of all samples in a fragment."); - -#define AUDIOOP_MAX_METHODDEF \ + return_value = audioop_getsample_impl(module, &fragment, width, index); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_max__doc__, +"max($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the maximum of the absolute value of all samples in a fragment."); + +#define AUDIOOP_MAX_METHODDEF \ {"max", (PyCFunction)(void(*)(void))audioop_max, METH_FASTCALL, audioop_max__doc__}, - -static PyObject * -audioop_max_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_max_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("max", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -108,39 +108,39 @@ audioop_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_max_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_minmax__doc__, -"minmax($module, fragment, width, /)\n" -"--\n" -"\n" -"Return the minimum and maximum values of all samples in the sound fragment."); - -#define AUDIOOP_MINMAX_METHODDEF \ + return_value = audioop_max_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_minmax__doc__, +"minmax($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the minimum and maximum values of all samples in the sound fragment."); + +#define AUDIOOP_MINMAX_METHODDEF \ {"minmax", (PyCFunction)(void(*)(void))audioop_minmax, METH_FASTCALL, audioop_minmax__doc__}, - -static PyObject * -audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_minmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_minmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("minmax", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -157,39 +157,39 @@ audioop_minmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_minmax_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_avg__doc__, -"avg($module, fragment, width, /)\n" -"--\n" -"\n" -"Return the average over all samples in the fragment."); - -#define AUDIOOP_AVG_METHODDEF \ + return_value = audioop_minmax_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_avg__doc__, +"avg($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the average over all samples in the fragment."); + +#define AUDIOOP_AVG_METHODDEF \ {"avg", (PyCFunction)(void(*)(void))audioop_avg, METH_FASTCALL, audioop_avg__doc__}, - -static PyObject * -audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_avg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_avg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("avg", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -206,39 +206,39 @@ audioop_avg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_avg_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_rms__doc__, -"rms($module, fragment, width, /)\n" -"--\n" -"\n" -"Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n)."); - -#define AUDIOOP_RMS_METHODDEF \ + return_value = audioop_avg_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_rms__doc__, +"rms($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n)."); + +#define AUDIOOP_RMS_METHODDEF \ {"rms", (PyCFunction)(void(*)(void))audioop_rms, METH_FASTCALL, audioop_rms__doc__}, - -static PyObject * -audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_rms(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_rms(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("rms", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -255,40 +255,40 @@ audioop_rms(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_rms_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_findfit__doc__, -"findfit($module, fragment, reference, /)\n" -"--\n" -"\n" -"Try to match reference as well as possible to a portion of fragment."); - -#define AUDIOOP_FINDFIT_METHODDEF \ + return_value = audioop_rms_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_findfit__doc__, +"findfit($module, fragment, reference, /)\n" +"--\n" +"\n" +"Try to match reference as well as possible to a portion of fragment."); + +#define AUDIOOP_FINDFIT_METHODDEF \ {"findfit", (PyCFunction)(void(*)(void))audioop_findfit, METH_FASTCALL, audioop_findfit__doc__}, - -static PyObject * -audioop_findfit_impl(PyObject *module, Py_buffer *fragment, - Py_buffer *reference); - -static PyObject * -audioop_findfit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - Py_buffer reference = {NULL, NULL}; - + +static PyObject * +audioop_findfit_impl(PyObject *module, Py_buffer *fragment, + Py_buffer *reference); + +static PyObject * +audioop_findfit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_buffer reference = {NULL, NULL}; + if (!_PyArg_CheckPositional("findfit", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -303,44 +303,44 @@ audioop_findfit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("findfit", "argument 2", "contiguous buffer", args[1]); goto exit; } - return_value = audioop_findfit_impl(module, &fragment, &reference); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - /* Cleanup for reference */ - if (reference.obj) { - PyBuffer_Release(&reference); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_findfactor__doc__, -"findfactor($module, fragment, reference, /)\n" -"--\n" -"\n" -"Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal."); - -#define AUDIOOP_FINDFACTOR_METHODDEF \ + return_value = audioop_findfit_impl(module, &fragment, &reference); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + /* Cleanup for reference */ + if (reference.obj) { + PyBuffer_Release(&reference); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_findfactor__doc__, +"findfactor($module, fragment, reference, /)\n" +"--\n" +"\n" +"Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal."); + +#define AUDIOOP_FINDFACTOR_METHODDEF \ {"findfactor", (PyCFunction)(void(*)(void))audioop_findfactor, METH_FASTCALL, audioop_findfactor__doc__}, - -static PyObject * -audioop_findfactor_impl(PyObject *module, Py_buffer *fragment, - Py_buffer *reference); - -static PyObject * -audioop_findfactor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - Py_buffer reference = {NULL, NULL}; - + +static PyObject * +audioop_findfactor_impl(PyObject *module, Py_buffer *fragment, + Py_buffer *reference); + +static PyObject * +audioop_findfactor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_buffer reference = {NULL, NULL}; + if (!_PyArg_CheckPositional("findfactor", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -355,44 +355,44 @@ audioop_findfactor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("findfactor", "argument 2", "contiguous buffer", args[1]); goto exit; } - return_value = audioop_findfactor_impl(module, &fragment, &reference); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - /* Cleanup for reference */ - if (reference.obj) { - PyBuffer_Release(&reference); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_findmax__doc__, -"findmax($module, fragment, length, /)\n" -"--\n" -"\n" -"Search fragment for a slice of specified number of samples with maximum energy."); - -#define AUDIOOP_FINDMAX_METHODDEF \ + return_value = audioop_findfactor_impl(module, &fragment, &reference); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + /* Cleanup for reference */ + if (reference.obj) { + PyBuffer_Release(&reference); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_findmax__doc__, +"findmax($module, fragment, length, /)\n" +"--\n" +"\n" +"Search fragment for a slice of specified number of samples with maximum energy."); + +#define AUDIOOP_FINDMAX_METHODDEF \ {"findmax", (PyCFunction)(void(*)(void))audioop_findmax, METH_FASTCALL, audioop_findmax__doc__}, - -static PyObject * -audioop_findmax_impl(PyObject *module, Py_buffer *fragment, - Py_ssize_t length); - -static PyObject * -audioop_findmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - Py_ssize_t length; - + +static PyObject * +audioop_findmax_impl(PyObject *module, Py_buffer *fragment, + Py_ssize_t length); + +static PyObject * +audioop_findmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_ssize_t length; + if (!_PyArg_CheckPositional("findmax", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -417,39 +417,39 @@ audioop_findmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } length = ival; } - return_value = audioop_findmax_impl(module, &fragment, length); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_avgpp__doc__, -"avgpp($module, fragment, width, /)\n" -"--\n" -"\n" -"Return the average peak-peak value over all samples in the fragment."); - -#define AUDIOOP_AVGPP_METHODDEF \ + return_value = audioop_findmax_impl(module, &fragment, length); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_avgpp__doc__, +"avgpp($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the average peak-peak value over all samples in the fragment."); + +#define AUDIOOP_AVGPP_METHODDEF \ {"avgpp", (PyCFunction)(void(*)(void))audioop_avgpp, METH_FASTCALL, audioop_avgpp__doc__}, - -static PyObject * -audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_avgpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_avgpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("avgpp", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -466,39 +466,39 @@ audioop_avgpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_avgpp_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_maxpp__doc__, -"maxpp($module, fragment, width, /)\n" -"--\n" -"\n" -"Return the maximum peak-peak value in the sound fragment."); - -#define AUDIOOP_MAXPP_METHODDEF \ + return_value = audioop_avgpp_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_maxpp__doc__, +"maxpp($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the maximum peak-peak value in the sound fragment."); + +#define AUDIOOP_MAXPP_METHODDEF \ {"maxpp", (PyCFunction)(void(*)(void))audioop_maxpp, METH_FASTCALL, audioop_maxpp__doc__}, - -static PyObject * -audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_maxpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_maxpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("maxpp", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -515,39 +515,39 @@ audioop_maxpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_maxpp_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_cross__doc__, -"cross($module, fragment, width, /)\n" -"--\n" -"\n" -"Return the number of zero crossings in the fragment passed as an argument."); - -#define AUDIOOP_CROSS_METHODDEF \ + return_value = audioop_maxpp_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_cross__doc__, +"cross($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the number of zero crossings in the fragment passed as an argument."); + +#define AUDIOOP_CROSS_METHODDEF \ {"cross", (PyCFunction)(void(*)(void))audioop_cross, METH_FASTCALL, audioop_cross__doc__}, - -static PyObject * -audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_cross(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_cross(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("cross", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -564,41 +564,41 @@ audioop_cross(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_cross_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_mul__doc__, -"mul($module, fragment, width, factor, /)\n" -"--\n" -"\n" -"Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor."); - -#define AUDIOOP_MUL_METHODDEF \ + return_value = audioop_cross_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_mul__doc__, +"mul($module, fragment, width, factor, /)\n" +"--\n" +"\n" +"Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor."); + +#define AUDIOOP_MUL_METHODDEF \ {"mul", (PyCFunction)(void(*)(void))audioop_mul, METH_FASTCALL, audioop_mul__doc__}, - -static PyObject * -audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, - double factor); - -static PyObject * -audioop_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - double factor; - + +static PyObject * +audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, + double factor); + +static PyObject * +audioop_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double factor; + if (!_PyArg_CheckPositional("mul", nargs, 3, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -625,42 +625,42 @@ audioop_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - return_value = audioop_mul_impl(module, &fragment, width, factor); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_tomono__doc__, -"tomono($module, fragment, width, lfactor, rfactor, /)\n" -"--\n" -"\n" -"Convert a stereo fragment to a mono fragment."); - -#define AUDIOOP_TOMONO_METHODDEF \ + return_value = audioop_mul_impl(module, &fragment, width, factor); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_tomono__doc__, +"tomono($module, fragment, width, lfactor, rfactor, /)\n" +"--\n" +"\n" +"Convert a stereo fragment to a mono fragment."); + +#define AUDIOOP_TOMONO_METHODDEF \ {"tomono", (PyCFunction)(void(*)(void))audioop_tomono, METH_FASTCALL, audioop_tomono__doc__}, - -static PyObject * -audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, - double lfactor, double rfactor); - -static PyObject * -audioop_tomono(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - double lfactor; - double rfactor; - + +static PyObject * +audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, + double lfactor, double rfactor); + +static PyObject * +audioop_tomono(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double lfactor; + double rfactor; + if (!_PyArg_CheckPositional("tomono", nargs, 4, 4)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -697,42 +697,42 @@ audioop_tomono(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - return_value = audioop_tomono_impl(module, &fragment, width, lfactor, rfactor); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_tostereo__doc__, -"tostereo($module, fragment, width, lfactor, rfactor, /)\n" -"--\n" -"\n" -"Generate a stereo fragment from a mono fragment."); - -#define AUDIOOP_TOSTEREO_METHODDEF \ + return_value = audioop_tomono_impl(module, &fragment, width, lfactor, rfactor); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_tostereo__doc__, +"tostereo($module, fragment, width, lfactor, rfactor, /)\n" +"--\n" +"\n" +"Generate a stereo fragment from a mono fragment."); + +#define AUDIOOP_TOSTEREO_METHODDEF \ {"tostereo", (PyCFunction)(void(*)(void))audioop_tostereo, METH_FASTCALL, audioop_tostereo__doc__}, - -static PyObject * -audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, - double lfactor, double rfactor); - -static PyObject * -audioop_tostereo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - double lfactor; - double rfactor; - + +static PyObject * +audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, + double lfactor, double rfactor); + +static PyObject * +audioop_tostereo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double lfactor; + double rfactor; + if (!_PyArg_CheckPositional("tostereo", nargs, 4, 4)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -769,41 +769,41 @@ audioop_tostereo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - return_value = audioop_tostereo_impl(module, &fragment, width, lfactor, rfactor); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_add__doc__, -"add($module, fragment1, fragment2, width, /)\n" -"--\n" -"\n" -"Return a fragment which is the addition of the two samples passed as parameters."); - -#define AUDIOOP_ADD_METHODDEF \ + return_value = audioop_tostereo_impl(module, &fragment, width, lfactor, rfactor); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_add__doc__, +"add($module, fragment1, fragment2, width, /)\n" +"--\n" +"\n" +"Return a fragment which is the addition of the two samples passed as parameters."); + +#define AUDIOOP_ADD_METHODDEF \ {"add", (PyCFunction)(void(*)(void))audioop_add, METH_FASTCALL, audioop_add__doc__}, - -static PyObject * -audioop_add_impl(PyObject *module, Py_buffer *fragment1, - Py_buffer *fragment2, int width); - -static PyObject * -audioop_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment1 = {NULL, NULL}; - Py_buffer fragment2 = {NULL, NULL}; - int width; - + +static PyObject * +audioop_add_impl(PyObject *module, Py_buffer *fragment1, + Py_buffer *fragment2, int width); + +static PyObject * +audioop_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment1 = {NULL, NULL}; + Py_buffer fragment2 = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("add", nargs, 3, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment1, PyBUF_SIMPLE) != 0) { goto exit; } @@ -827,44 +827,44 @@ audioop_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_add_impl(module, &fragment1, &fragment2, width); - -exit: - /* Cleanup for fragment1 */ - if (fragment1.obj) { - PyBuffer_Release(&fragment1); - } - /* Cleanup for fragment2 */ - if (fragment2.obj) { - PyBuffer_Release(&fragment2); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_bias__doc__, -"bias($module, fragment, width, bias, /)\n" -"--\n" -"\n" -"Return a fragment that is the original fragment with a bias added to each sample."); - -#define AUDIOOP_BIAS_METHODDEF \ + return_value = audioop_add_impl(module, &fragment1, &fragment2, width); + +exit: + /* Cleanup for fragment1 */ + if (fragment1.obj) { + PyBuffer_Release(&fragment1); + } + /* Cleanup for fragment2 */ + if (fragment2.obj) { + PyBuffer_Release(&fragment2); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_bias__doc__, +"bias($module, fragment, width, bias, /)\n" +"--\n" +"\n" +"Return a fragment that is the original fragment with a bias added to each sample."); + +#define AUDIOOP_BIAS_METHODDEF \ {"bias", (PyCFunction)(void(*)(void))audioop_bias, METH_FASTCALL, audioop_bias__doc__}, - -static PyObject * -audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias); - -static PyObject * -audioop_bias(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - int bias; - + +static PyObject * +audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias); + +static PyObject * +audioop_bias(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + int bias; + if (!_PyArg_CheckPositional("bias", nargs, 3, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -890,39 +890,39 @@ audioop_bias(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (bias == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_bias_impl(module, &fragment, width, bias); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_reverse__doc__, -"reverse($module, fragment, width, /)\n" -"--\n" -"\n" -"Reverse the samples in a fragment and returns the modified fragment."); - -#define AUDIOOP_REVERSE_METHODDEF \ + return_value = audioop_bias_impl(module, &fragment, width, bias); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_reverse__doc__, +"reverse($module, fragment, width, /)\n" +"--\n" +"\n" +"Reverse the samples in a fragment and returns the modified fragment."); + +#define AUDIOOP_REVERSE_METHODDEF \ {"reverse", (PyCFunction)(void(*)(void))audioop_reverse, METH_FASTCALL, audioop_reverse__doc__}, - -static PyObject * -audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_reverse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_reverse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("reverse", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -939,39 +939,39 @@ audioop_reverse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_reverse_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_byteswap__doc__, -"byteswap($module, fragment, width, /)\n" -"--\n" -"\n" -"Convert big-endian samples to little-endian and vice versa."); - -#define AUDIOOP_BYTESWAP_METHODDEF \ + return_value = audioop_reverse_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_byteswap__doc__, +"byteswap($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert big-endian samples to little-endian and vice versa."); + +#define AUDIOOP_BYTESWAP_METHODDEF \ {"byteswap", (PyCFunction)(void(*)(void))audioop_byteswap, METH_FASTCALL, audioop_byteswap__doc__}, - -static PyObject * -audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_byteswap(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_byteswap(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("byteswap", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -988,41 +988,41 @@ audioop_byteswap(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_byteswap_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_lin2lin__doc__, -"lin2lin($module, fragment, width, newwidth, /)\n" -"--\n" -"\n" -"Convert samples between 1-, 2-, 3- and 4-byte formats."); - -#define AUDIOOP_LIN2LIN_METHODDEF \ + return_value = audioop_byteswap_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_lin2lin__doc__, +"lin2lin($module, fragment, width, newwidth, /)\n" +"--\n" +"\n" +"Convert samples between 1-, 2-, 3- and 4-byte formats."); + +#define AUDIOOP_LIN2LIN_METHODDEF \ {"lin2lin", (PyCFunction)(void(*)(void))audioop_lin2lin, METH_FASTCALL, audioop_lin2lin__doc__}, - -static PyObject * -audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width, - int newwidth); - -static PyObject * -audioop_lin2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - int newwidth; - + +static PyObject * +audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width, + int newwidth); + +static PyObject * +audioop_lin2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + int newwidth; + if (!_PyArg_CheckPositional("lin2lin", nargs, 3, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1048,48 +1048,48 @@ audioop_lin2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (newwidth == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_lin2lin_impl(module, &fragment, width, newwidth); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_ratecv__doc__, -"ratecv($module, fragment, width, nchannels, inrate, outrate, state,\n" -" weightA=1, weightB=0, /)\n" -"--\n" -"\n" -"Convert the frame rate of the input fragment."); - -#define AUDIOOP_RATECV_METHODDEF \ + return_value = audioop_lin2lin_impl(module, &fragment, width, newwidth); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_ratecv__doc__, +"ratecv($module, fragment, width, nchannels, inrate, outrate, state,\n" +" weightA=1, weightB=0, /)\n" +"--\n" +"\n" +"Convert the frame rate of the input fragment."); + +#define AUDIOOP_RATECV_METHODDEF \ {"ratecv", (PyCFunction)(void(*)(void))audioop_ratecv, METH_FASTCALL, audioop_ratecv__doc__}, - -static PyObject * -audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, - int nchannels, int inrate, int outrate, PyObject *state, - int weightA, int weightB); - -static PyObject * -audioop_ratecv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - int nchannels; - int inrate; - int outrate; - PyObject *state; - int weightA = 1; - int weightB = 0; - + +static PyObject * +audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, + int nchannels, int inrate, int outrate, PyObject *state, + int weightA, int weightB); + +static PyObject * +audioop_ratecv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + int nchannels; + int inrate; + int outrate; + PyObject *state; + int weightA = 1; + int weightB = 0; + if (!_PyArg_CheckPositional("ratecv", nargs, 6, 8)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1159,39 +1159,39 @@ audioop_ratecv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = audioop_ratecv_impl(module, &fragment, width, nchannels, inrate, outrate, state, weightA, weightB); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_lin2ulaw__doc__, -"lin2ulaw($module, fragment, width, /)\n" -"--\n" -"\n" -"Convert samples in the audio fragment to u-LAW encoding."); - -#define AUDIOOP_LIN2ULAW_METHODDEF \ + return_value = audioop_ratecv_impl(module, &fragment, width, nchannels, inrate, outrate, state, weightA, weightB); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_lin2ulaw__doc__, +"lin2ulaw($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert samples in the audio fragment to u-LAW encoding."); + +#define AUDIOOP_LIN2ULAW_METHODDEF \ {"lin2ulaw", (PyCFunction)(void(*)(void))audioop_lin2ulaw, METH_FASTCALL, audioop_lin2ulaw__doc__}, - -static PyObject * -audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_lin2ulaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_lin2ulaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("lin2ulaw", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1208,39 +1208,39 @@ audioop_lin2ulaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_lin2ulaw_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_ulaw2lin__doc__, -"ulaw2lin($module, fragment, width, /)\n" -"--\n" -"\n" -"Convert sound fragments in u-LAW encoding to linearly encoded sound fragments."); - -#define AUDIOOP_ULAW2LIN_METHODDEF \ + return_value = audioop_lin2ulaw_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_ulaw2lin__doc__, +"ulaw2lin($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert sound fragments in u-LAW encoding to linearly encoded sound fragments."); + +#define AUDIOOP_ULAW2LIN_METHODDEF \ {"ulaw2lin", (PyCFunction)(void(*)(void))audioop_ulaw2lin, METH_FASTCALL, audioop_ulaw2lin__doc__}, - -static PyObject * -audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_ulaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_ulaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("ulaw2lin", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1257,39 +1257,39 @@ audioop_ulaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_ulaw2lin_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_lin2alaw__doc__, -"lin2alaw($module, fragment, width, /)\n" -"--\n" -"\n" -"Convert samples in the audio fragment to a-LAW encoding."); - -#define AUDIOOP_LIN2ALAW_METHODDEF \ + return_value = audioop_ulaw2lin_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_lin2alaw__doc__, +"lin2alaw($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert samples in the audio fragment to a-LAW encoding."); + +#define AUDIOOP_LIN2ALAW_METHODDEF \ {"lin2alaw", (PyCFunction)(void(*)(void))audioop_lin2alaw, METH_FASTCALL, audioop_lin2alaw__doc__}, - -static PyObject * -audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_lin2alaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_lin2alaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("lin2alaw", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1306,39 +1306,39 @@ audioop_lin2alaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_lin2alaw_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_alaw2lin__doc__, -"alaw2lin($module, fragment, width, /)\n" -"--\n" -"\n" -"Convert sound fragments in a-LAW encoding to linearly encoded sound fragments."); - -#define AUDIOOP_ALAW2LIN_METHODDEF \ + return_value = audioop_lin2alaw_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_alaw2lin__doc__, +"alaw2lin($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert sound fragments in a-LAW encoding to linearly encoded sound fragments."); + +#define AUDIOOP_ALAW2LIN_METHODDEF \ {"alaw2lin", (PyCFunction)(void(*)(void))audioop_alaw2lin, METH_FASTCALL, audioop_alaw2lin__doc__}, - -static PyObject * -audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width); - -static PyObject * -audioop_alaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - + +static PyObject * +audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_alaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + if (!_PyArg_CheckPositional("alaw2lin", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1355,41 +1355,41 @@ audioop_alaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (width == -1 && PyErr_Occurred()) { goto exit; } - return_value = audioop_alaw2lin_impl(module, &fragment, width); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_lin2adpcm__doc__, -"lin2adpcm($module, fragment, width, state, /)\n" -"--\n" -"\n" -"Convert samples to 4 bit Intel/DVI ADPCM encoding."); - -#define AUDIOOP_LIN2ADPCM_METHODDEF \ + return_value = audioop_alaw2lin_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_lin2adpcm__doc__, +"lin2adpcm($module, fragment, width, state, /)\n" +"--\n" +"\n" +"Convert samples to 4 bit Intel/DVI ADPCM encoding."); + +#define AUDIOOP_LIN2ADPCM_METHODDEF \ {"lin2adpcm", (PyCFunction)(void(*)(void))audioop_lin2adpcm, METH_FASTCALL, audioop_lin2adpcm__doc__}, - -static PyObject * -audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, - PyObject *state); - -static PyObject * -audioop_lin2adpcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - PyObject *state; - + +static PyObject * +audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, + PyObject *state); + +static PyObject * +audioop_lin2adpcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + PyObject *state; + if (!_PyArg_CheckPositional("lin2adpcm", nargs, 3, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1407,41 +1407,41 @@ audioop_lin2adpcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } state = args[2]; - return_value = audioop_lin2adpcm_impl(module, &fragment, width, state); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} - -PyDoc_STRVAR(audioop_adpcm2lin__doc__, -"adpcm2lin($module, fragment, width, state, /)\n" -"--\n" -"\n" -"Decode an Intel/DVI ADPCM coded fragment to a linear fragment."); - -#define AUDIOOP_ADPCM2LIN_METHODDEF \ + return_value = audioop_lin2adpcm_impl(module, &fragment, width, state); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} + +PyDoc_STRVAR(audioop_adpcm2lin__doc__, +"adpcm2lin($module, fragment, width, state, /)\n" +"--\n" +"\n" +"Decode an Intel/DVI ADPCM coded fragment to a linear fragment."); + +#define AUDIOOP_ADPCM2LIN_METHODDEF \ {"adpcm2lin", (PyCFunction)(void(*)(void))audioop_adpcm2lin, METH_FASTCALL, audioop_adpcm2lin__doc__}, - -static PyObject * -audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, - PyObject *state); - -static PyObject * -audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer fragment = {NULL, NULL}; - int width; - PyObject *state; - + +static PyObject * +audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, + PyObject *state); + +static PyObject * +audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + PyObject *state; + if (!_PyArg_CheckPositional("adpcm2lin", nargs, 3, 3)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } @@ -1459,14 +1459,14 @@ audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } state = args[2]; - return_value = audioop_adpcm2lin_impl(module, &fragment, width, state); - -exit: - /* Cleanup for fragment */ - if (fragment.obj) { - PyBuffer_Release(&fragment); - } - - return return_value; -} + return_value = audioop_adpcm2lin_impl(module, &fragment, width, state); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) { + PyBuffer_Release(&fragment); + } + + return return_value; +} /*[clinic end generated code: output=6b4f2c597f295abc input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/binascii.c.h b/contrib/tools/python3/src/Modules/clinic/binascii.c.h index 4d02c72c472..bcc554366b5 100644 --- a/contrib/tools/python3/src/Modules/clinic/binascii.c.h +++ b/contrib/tools/python3/src/Modules/clinic/binascii.c.h @@ -1,65 +1,65 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(binascii_a2b_uu__doc__, -"a2b_uu($module, data, /)\n" -"--\n" -"\n" -"Decode a line of uuencoded data."); - -#define BINASCII_A2B_UU_METHODDEF \ - {"a2b_uu", (PyCFunction)binascii_a2b_uu, METH_O, binascii_a2b_uu__doc__}, - -static PyObject * -binascii_a2b_uu_impl(PyObject *module, Py_buffer *data); - -static PyObject * -binascii_a2b_uu(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(binascii_a2b_uu__doc__, +"a2b_uu($module, data, /)\n" +"--\n" +"\n" +"Decode a line of uuencoded data."); + +#define BINASCII_A2B_UU_METHODDEF \ + {"a2b_uu", (PyCFunction)binascii_a2b_uu, METH_O, binascii_a2b_uu__doc__}, + +static PyObject * +binascii_a2b_uu_impl(PyObject *module, Py_buffer *data); + +static PyObject * +binascii_a2b_uu(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (!ascii_buffer_converter(arg, &data)) { - goto exit; - } - return_value = binascii_a2b_uu_impl(module, &data); - -exit: - /* Cleanup for data */ - if (data.obj) - PyBuffer_Release(&data); - - return return_value; -} - -PyDoc_STRVAR(binascii_b2a_uu__doc__, -"b2a_uu($module, data, /, *, backtick=False)\n" -"--\n" -"\n" -"Uuencode line of data."); - -#define BINASCII_B2A_UU_METHODDEF \ + goto exit; + } + return_value = binascii_a2b_uu_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_uu__doc__, +"b2a_uu($module, data, /, *, backtick=False)\n" +"--\n" +"\n" +"Uuencode line of data."); + +#define BINASCII_B2A_UU_METHODDEF \ {"b2a_uu", (PyCFunction)(void(*)(void))binascii_b2a_uu, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_uu__doc__}, - -static PyObject * -binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick); - -static PyObject * -binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "backtick", NULL}; + +static PyObject * +binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick); + +static PyObject * +binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "backtick", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "b2a_uu", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - int backtick = 0; - + Py_buffer data = {NULL, NULL}; + int backtick = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -80,75 +80,75 @@ binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } skip_optional_kwonly: - return_value = binascii_b2a_uu_impl(module, &data, backtick); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_a2b_base64__doc__, -"a2b_base64($module, data, /)\n" -"--\n" -"\n" -"Decode a line of base64 data."); - -#define BINASCII_A2B_BASE64_METHODDEF \ - {"a2b_base64", (PyCFunction)binascii_a2b_base64, METH_O, binascii_a2b_base64__doc__}, - -static PyObject * -binascii_a2b_base64_impl(PyObject *module, Py_buffer *data); - -static PyObject * -binascii_a2b_base64(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - + return_value = binascii_b2a_uu_impl(module, &data, backtick); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_base64__doc__, +"a2b_base64($module, data, /)\n" +"--\n" +"\n" +"Decode a line of base64 data."); + +#define BINASCII_A2B_BASE64_METHODDEF \ + {"a2b_base64", (PyCFunction)binascii_a2b_base64, METH_O, binascii_a2b_base64__doc__}, + +static PyObject * +binascii_a2b_base64_impl(PyObject *module, Py_buffer *data); + +static PyObject * +binascii_a2b_base64(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (!ascii_buffer_converter(arg, &data)) { - goto exit; - } - return_value = binascii_a2b_base64_impl(module, &data); - -exit: - /* Cleanup for data */ - if (data.obj) - PyBuffer_Release(&data); - - return return_value; -} - -PyDoc_STRVAR(binascii_b2a_base64__doc__, -"b2a_base64($module, data, /, *, newline=True)\n" -"--\n" -"\n" -"Base64-code line of data."); - -#define BINASCII_B2A_BASE64_METHODDEF \ + goto exit; + } + return_value = binascii_a2b_base64_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_base64__doc__, +"b2a_base64($module, data, /, *, newline=True)\n" +"--\n" +"\n" +"Base64-code line of data."); + +#define BINASCII_B2A_BASE64_METHODDEF \ {"b2a_base64", (PyCFunction)(void(*)(void))binascii_b2a_base64, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_base64__doc__}, - -static PyObject * -binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline); - -static PyObject * -binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "newline", NULL}; + +static PyObject * +binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline); + +static PyObject * +binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "newline", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "b2a_base64", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - int newline = 1; - + Py_buffer data = {NULL, NULL}; + int newline = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -169,178 +169,178 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P goto exit; } skip_optional_kwonly: - return_value = binascii_b2a_base64_impl(module, &data, newline); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_a2b_hqx__doc__, -"a2b_hqx($module, data, /)\n" -"--\n" -"\n" -"Decode .hqx coding."); - -#define BINASCII_A2B_HQX_METHODDEF \ - {"a2b_hqx", (PyCFunction)binascii_a2b_hqx, METH_O, binascii_a2b_hqx__doc__}, - -static PyObject * -binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data); - -static PyObject * -binascii_a2b_hqx(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - + return_value = binascii_b2a_base64_impl(module, &data, newline); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_hqx__doc__, +"a2b_hqx($module, data, /)\n" +"--\n" +"\n" +"Decode .hqx coding."); + +#define BINASCII_A2B_HQX_METHODDEF \ + {"a2b_hqx", (PyCFunction)binascii_a2b_hqx, METH_O, binascii_a2b_hqx__doc__}, + +static PyObject * +binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data); + +static PyObject * +binascii_a2b_hqx(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (!ascii_buffer_converter(arg, &data)) { - goto exit; - } - return_value = binascii_a2b_hqx_impl(module, &data); - -exit: - /* Cleanup for data */ - if (data.obj) - PyBuffer_Release(&data); - - return return_value; -} - -PyDoc_STRVAR(binascii_rlecode_hqx__doc__, -"rlecode_hqx($module, data, /)\n" -"--\n" -"\n" -"Binhex RLE-code binary data."); - -#define BINASCII_RLECODE_HQX_METHODDEF \ - {"rlecode_hqx", (PyCFunction)binascii_rlecode_hqx, METH_O, binascii_rlecode_hqx__doc__}, - -static PyObject * -binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data); - -static PyObject * -binascii_rlecode_hqx(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - + goto exit; + } + return_value = binascii_a2b_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_rlecode_hqx__doc__, +"rlecode_hqx($module, data, /)\n" +"--\n" +"\n" +"Binhex RLE-code binary data."); + +#define BINASCII_RLECODE_HQX_METHODDEF \ + {"rlecode_hqx", (PyCFunction)binascii_rlecode_hqx, METH_O, binascii_rlecode_hqx__doc__}, + +static PyObject * +binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data); + +static PyObject * +binascii_rlecode_hqx(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&data, 'C')) { _PyArg_BadArgument("rlecode_hqx", "argument", "contiguous buffer", arg); goto exit; } - return_value = binascii_rlecode_hqx_impl(module, &data); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_b2a_hqx__doc__, -"b2a_hqx($module, data, /)\n" -"--\n" -"\n" -"Encode .hqx data."); - -#define BINASCII_B2A_HQX_METHODDEF \ - {"b2a_hqx", (PyCFunction)binascii_b2a_hqx, METH_O, binascii_b2a_hqx__doc__}, - -static PyObject * -binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data); - -static PyObject * -binascii_b2a_hqx(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - + return_value = binascii_rlecode_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_hqx__doc__, +"b2a_hqx($module, data, /)\n" +"--\n" +"\n" +"Encode .hqx data."); + +#define BINASCII_B2A_HQX_METHODDEF \ + {"b2a_hqx", (PyCFunction)binascii_b2a_hqx, METH_O, binascii_b2a_hqx__doc__}, + +static PyObject * +binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data); + +static PyObject * +binascii_b2a_hqx(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&data, 'C')) { _PyArg_BadArgument("b2a_hqx", "argument", "contiguous buffer", arg); goto exit; } - return_value = binascii_b2a_hqx_impl(module, &data); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_rledecode_hqx__doc__, -"rledecode_hqx($module, data, /)\n" -"--\n" -"\n" -"Decode hexbin RLE-coded string."); - -#define BINASCII_RLEDECODE_HQX_METHODDEF \ - {"rledecode_hqx", (PyCFunction)binascii_rledecode_hqx, METH_O, binascii_rledecode_hqx__doc__}, - -static PyObject * -binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data); - -static PyObject * -binascii_rledecode_hqx(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - + return_value = binascii_b2a_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_rledecode_hqx__doc__, +"rledecode_hqx($module, data, /)\n" +"--\n" +"\n" +"Decode hexbin RLE-coded string."); + +#define BINASCII_RLEDECODE_HQX_METHODDEF \ + {"rledecode_hqx", (PyCFunction)binascii_rledecode_hqx, METH_O, binascii_rledecode_hqx__doc__}, + +static PyObject * +binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data); + +static PyObject * +binascii_rledecode_hqx(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&data, 'C')) { _PyArg_BadArgument("rledecode_hqx", "argument", "contiguous buffer", arg); goto exit; } - return_value = binascii_rledecode_hqx_impl(module, &data); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_crc_hqx__doc__, -"crc_hqx($module, data, crc, /)\n" -"--\n" -"\n" -"Compute CRC-CCITT incrementally."); - -#define BINASCII_CRC_HQX_METHODDEF \ + return_value = binascii_rledecode_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_crc_hqx__doc__, +"crc_hqx($module, data, crc, /)\n" +"--\n" +"\n" +"Compute CRC-CCITT incrementally."); + +#define BINASCII_CRC_HQX_METHODDEF \ {"crc_hqx", (PyCFunction)(void(*)(void))binascii_crc_hqx, METH_FASTCALL, binascii_crc_hqx__doc__}, - -static PyObject * -binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc); - + static PyObject * -binascii_crc_hqx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - unsigned int crc; - +binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc); + +static PyObject * +binascii_crc_hqx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int crc; + if (!_PyArg_CheckPositional("crc_hqx", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -358,39 +358,39 @@ binascii_crc_hqx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } return_value = binascii_crc_hqx_impl(module, &data, crc); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_crc32__doc__, -"crc32($module, data, crc=0, /)\n" -"--\n" -"\n" -"Compute CRC-32 incrementally."); - -#define BINASCII_CRC32_METHODDEF \ + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_crc32__doc__, +"crc32($module, data, crc=0, /)\n" +"--\n" +"\n" +"Compute CRC-32 incrementally."); + +#define BINASCII_CRC32_METHODDEF \ {"crc32", (PyCFunction)(void(*)(void))binascii_crc32, METH_FASTCALL, binascii_crc32__doc__}, - -static unsigned int -binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc); - -static PyObject * -binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - unsigned int crc = 0; - unsigned int _return_value; - + +static unsigned int +binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc); + +static PyObject * +binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int crc = 0; + unsigned int _return_value; + if (!_PyArg_CheckPositional("crc32", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -411,34 +411,34 @@ binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - _return_value = binascii_crc32_impl(module, &data, crc); - if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_b2a_hex__doc__, + _return_value = binascii_crc32_impl(module, &data, crc); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_hex__doc__, "b2a_hex($module, /, data, sep=, bytes_per_sep=1)\n" -"--\n" -"\n" -"Hexadecimal representation of binary data.\n" -"\n" +"--\n" +"\n" +"Hexadecimal representation of binary data.\n" +"\n" " sep\n" " An optional single character or byte to separate hex bytes.\n" " bytes_per_sep\n" " How many bytes between separators. Positive values count from the\n" " right, negative values count from the left.\n" "\n" -"The return value is a bytes object. This function is also\n" +"The return value is a bytes object. This function is also\n" "available as \"hexlify()\".\n" "\n" "Example:\n" @@ -448,30 +448,30 @@ PyDoc_STRVAR(binascii_b2a_hex__doc__, "b\'b9:01:ef\'\n" ">>> binascii.b2a_hex(b\'\\xb9\\x01\\xef\', b\'_\', 2)\n" "b\'b9_01ef\'"); - -#define BINASCII_B2A_HEX_METHODDEF \ + +#define BINASCII_B2A_HEX_METHODDEF \ {"b2a_hex", (PyCFunction)(void(*)(void))binascii_b2a_hex, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_hex__doc__}, - -static PyObject * + +static PyObject * binascii_b2a_hex_impl(PyObject *module, Py_buffer *data, PyObject *sep, int bytes_per_sep); - -static PyObject * + +static PyObject * binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "b2a_hex", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; + Py_buffer data = {NULL, NULL}; PyObject *sep = NULL; int bytes_per_sep = 1; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -499,22 +499,22 @@ binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } skip_optional_pos: return_value = binascii_b2a_hex_impl(module, &data, sep, bytes_per_sep); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_hexlify__doc__, + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_hexlify__doc__, "hexlify($module, /, data, sep=, bytes_per_sep=1)\n" -"--\n" -"\n" -"Hexadecimal representation of binary data.\n" -"\n" +"--\n" +"\n" +"Hexadecimal representation of binary data.\n" +"\n" " sep\n" " An optional single character or byte to separate hex bytes.\n" " bytes_per_sep\n" @@ -523,30 +523,30 @@ PyDoc_STRVAR(binascii_hexlify__doc__, "\n" "The return value is a bytes object. This function is also\n" "available as \"b2a_hex()\"."); - -#define BINASCII_HEXLIFY_METHODDEF \ + +#define BINASCII_HEXLIFY_METHODDEF \ {"hexlify", (PyCFunction)(void(*)(void))binascii_hexlify, METH_FASTCALL|METH_KEYWORDS, binascii_hexlify__doc__}, - -static PyObject * + +static PyObject * binascii_hexlify_impl(PyObject *module, Py_buffer *data, PyObject *sep, int bytes_per_sep); - -static PyObject * + +static PyObject * binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "hexlify", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; + Py_buffer data = {NULL, NULL}; PyObject *sep = NULL; int bytes_per_sep = 1; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -574,110 +574,110 @@ binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb } skip_optional_pos: return_value = binascii_hexlify_impl(module, &data, sep, bytes_per_sep); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(binascii_a2b_hex__doc__, -"a2b_hex($module, hexstr, /)\n" -"--\n" -"\n" -"Binary data of hexadecimal representation.\n" -"\n" -"hexstr must contain an even number of hex digits (upper or lower case).\n" -"This function is also available as \"unhexlify()\"."); - -#define BINASCII_A2B_HEX_METHODDEF \ - {"a2b_hex", (PyCFunction)binascii_a2b_hex, METH_O, binascii_a2b_hex__doc__}, - -static PyObject * -binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr); - -static PyObject * -binascii_a2b_hex(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer hexstr = {NULL, NULL}; - + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_hex__doc__, +"a2b_hex($module, hexstr, /)\n" +"--\n" +"\n" +"Binary data of hexadecimal representation.\n" +"\n" +"hexstr must contain an even number of hex digits (upper or lower case).\n" +"This function is also available as \"unhexlify()\"."); + +#define BINASCII_A2B_HEX_METHODDEF \ + {"a2b_hex", (PyCFunction)binascii_a2b_hex, METH_O, binascii_a2b_hex__doc__}, + +static PyObject * +binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr); + +static PyObject * +binascii_a2b_hex(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer hexstr = {NULL, NULL}; + if (!ascii_buffer_converter(arg, &hexstr)) { - goto exit; - } - return_value = binascii_a2b_hex_impl(module, &hexstr); - -exit: - /* Cleanup for hexstr */ - if (hexstr.obj) - PyBuffer_Release(&hexstr); - - return return_value; -} - -PyDoc_STRVAR(binascii_unhexlify__doc__, -"unhexlify($module, hexstr, /)\n" -"--\n" -"\n" -"Binary data of hexadecimal representation.\n" -"\n" -"hexstr must contain an even number of hex digits (upper or lower case)."); - -#define BINASCII_UNHEXLIFY_METHODDEF \ - {"unhexlify", (PyCFunction)binascii_unhexlify, METH_O, binascii_unhexlify__doc__}, - -static PyObject * -binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr); - -static PyObject * -binascii_unhexlify(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer hexstr = {NULL, NULL}; - + goto exit; + } + return_value = binascii_a2b_hex_impl(module, &hexstr); + +exit: + /* Cleanup for hexstr */ + if (hexstr.obj) + PyBuffer_Release(&hexstr); + + return return_value; +} + +PyDoc_STRVAR(binascii_unhexlify__doc__, +"unhexlify($module, hexstr, /)\n" +"--\n" +"\n" +"Binary data of hexadecimal representation.\n" +"\n" +"hexstr must contain an even number of hex digits (upper or lower case)."); + +#define BINASCII_UNHEXLIFY_METHODDEF \ + {"unhexlify", (PyCFunction)binascii_unhexlify, METH_O, binascii_unhexlify__doc__}, + +static PyObject * +binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr); + +static PyObject * +binascii_unhexlify(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer hexstr = {NULL, NULL}; + if (!ascii_buffer_converter(arg, &hexstr)) { - goto exit; - } - return_value = binascii_unhexlify_impl(module, &hexstr); - -exit: - /* Cleanup for hexstr */ - if (hexstr.obj) - PyBuffer_Release(&hexstr); - - return return_value; -} - -PyDoc_STRVAR(binascii_a2b_qp__doc__, -"a2b_qp($module, /, data, header=False)\n" -"--\n" -"\n" -"Decode a string of qp-encoded data."); - -#define BINASCII_A2B_QP_METHODDEF \ + goto exit; + } + return_value = binascii_unhexlify_impl(module, &hexstr); + +exit: + /* Cleanup for hexstr */ + if (hexstr.obj) + PyBuffer_Release(&hexstr); + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_qp__doc__, +"a2b_qp($module, /, data, header=False)\n" +"--\n" +"\n" +"Decode a string of qp-encoded data."); + +#define BINASCII_A2B_QP_METHODDEF \ {"a2b_qp", (PyCFunction)(void(*)(void))binascii_a2b_qp, METH_FASTCALL|METH_KEYWORDS, binascii_a2b_qp__doc__}, - -static PyObject * -binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header); - -static PyObject * -binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"data", "header", NULL}; + +static PyObject * +binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header); + +static PyObject * +binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"data", "header", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "a2b_qp", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - int header = 0; - + Py_buffer data = {NULL, NULL}; + int header = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!ascii_buffer_converter(args[0], &data)) { goto exit; } @@ -694,50 +694,50 @@ binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } skip_optional_pos: - return_value = binascii_a2b_qp_impl(module, &data, header); - -exit: - /* Cleanup for data */ - if (data.obj) - PyBuffer_Release(&data); - - return return_value; -} - -PyDoc_STRVAR(binascii_b2a_qp__doc__, -"b2a_qp($module, /, data, quotetabs=False, istext=True, header=False)\n" -"--\n" -"\n" -"Encode a string using quoted-printable encoding.\n" -"\n" -"On encoding, when istext is set, newlines are not encoded, and white\n" -"space at end of lines is. When istext is not set, \\r and \\n (CR/LF)\n" -"are both encoded. When quotetabs is set, space and tabs are encoded."); - -#define BINASCII_B2A_QP_METHODDEF \ + return_value = binascii_a2b_qp_impl(module, &data, header); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_qp__doc__, +"b2a_qp($module, /, data, quotetabs=False, istext=True, header=False)\n" +"--\n" +"\n" +"Encode a string using quoted-printable encoding.\n" +"\n" +"On encoding, when istext is set, newlines are not encoded, and white\n" +"space at end of lines is. When istext is not set, \\r and \\n (CR/LF)\n" +"are both encoded. When quotetabs is set, space and tabs are encoded."); + +#define BINASCII_B2A_QP_METHODDEF \ {"b2a_qp", (PyCFunction)(void(*)(void))binascii_b2a_qp, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_qp__doc__}, - -static PyObject * -binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, - int istext, int header); - -static PyObject * -binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"data", "quotetabs", "istext", "header", NULL}; + +static PyObject * +binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, + int istext, int header); + +static PyObject * +binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"data", "quotetabs", "istext", "header", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "b2a_qp", 0}; PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - int quotetabs = 0; - int istext = 1; - int header = 0; - + Py_buffer data = {NULL, NULL}; + int quotetabs = 0; + int istext = 1; + int header = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -786,14 +786,14 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } skip_optional_pos: - return_value = binascii_b2a_qp_impl(module, &data, quotetabs, istext, header); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} + return_value = binascii_b2a_qp_impl(module, &data, quotetabs, istext, header); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} /*[clinic end generated code: output=a1e878d3963b615e input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/cmathmodule.c.h b/contrib/tools/python3/src/Modules/clinic/cmathmodule.c.h index 4b6653aa219..c6ff85103ab 100644 --- a/contrib/tools/python3/src/Modules/clinic/cmathmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/cmathmodule.c.h @@ -1,661 +1,661 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(cmath_acos__doc__, -"acos($module, z, /)\n" -"--\n" -"\n" -"Return the arc cosine of z."); - -#define CMATH_ACOS_METHODDEF \ - {"acos", (PyCFunction)cmath_acos, METH_O, cmath_acos__doc__}, - -static Py_complex -cmath_acos_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_acos(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(cmath_acos__doc__, +"acos($module, z, /)\n" +"--\n" +"\n" +"Return the arc cosine of z."); + +#define CMATH_ACOS_METHODDEF \ + {"acos", (PyCFunction)cmath_acos, METH_O, cmath_acos__doc__}, + +static Py_complex +cmath_acos_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_acos(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_acos_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_acosh__doc__, -"acosh($module, z, /)\n" -"--\n" -"\n" -"Return the inverse hyperbolic cosine of z."); - -#define CMATH_ACOSH_METHODDEF \ - {"acosh", (PyCFunction)cmath_acosh, METH_O, cmath_acosh__doc__}, - -static Py_complex -cmath_acosh_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_acosh(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_acos_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_acosh__doc__, +"acosh($module, z, /)\n" +"--\n" +"\n" +"Return the inverse hyperbolic cosine of z."); + +#define CMATH_ACOSH_METHODDEF \ + {"acosh", (PyCFunction)cmath_acosh, METH_O, cmath_acosh__doc__}, + +static Py_complex +cmath_acosh_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_acosh(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_acosh_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_asin__doc__, -"asin($module, z, /)\n" -"--\n" -"\n" -"Return the arc sine of z."); - -#define CMATH_ASIN_METHODDEF \ - {"asin", (PyCFunction)cmath_asin, METH_O, cmath_asin__doc__}, - -static Py_complex -cmath_asin_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_asin(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_acosh_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_asin__doc__, +"asin($module, z, /)\n" +"--\n" +"\n" +"Return the arc sine of z."); + +#define CMATH_ASIN_METHODDEF \ + {"asin", (PyCFunction)cmath_asin, METH_O, cmath_asin__doc__}, + +static Py_complex +cmath_asin_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_asin(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_asin_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_asinh__doc__, -"asinh($module, z, /)\n" -"--\n" -"\n" -"Return the inverse hyperbolic sine of z."); - -#define CMATH_ASINH_METHODDEF \ - {"asinh", (PyCFunction)cmath_asinh, METH_O, cmath_asinh__doc__}, - -static Py_complex -cmath_asinh_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_asinh(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_asin_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_asinh__doc__, +"asinh($module, z, /)\n" +"--\n" +"\n" +"Return the inverse hyperbolic sine of z."); + +#define CMATH_ASINH_METHODDEF \ + {"asinh", (PyCFunction)cmath_asinh, METH_O, cmath_asinh__doc__}, + +static Py_complex +cmath_asinh_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_asinh(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_asinh_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_atan__doc__, -"atan($module, z, /)\n" -"--\n" -"\n" -"Return the arc tangent of z."); - -#define CMATH_ATAN_METHODDEF \ - {"atan", (PyCFunction)cmath_atan, METH_O, cmath_atan__doc__}, - -static Py_complex -cmath_atan_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_atan(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_asinh_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_atan__doc__, +"atan($module, z, /)\n" +"--\n" +"\n" +"Return the arc tangent of z."); + +#define CMATH_ATAN_METHODDEF \ + {"atan", (PyCFunction)cmath_atan, METH_O, cmath_atan__doc__}, + +static Py_complex +cmath_atan_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_atan(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_atan_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_atanh__doc__, -"atanh($module, z, /)\n" -"--\n" -"\n" -"Return the inverse hyperbolic tangent of z."); - -#define CMATH_ATANH_METHODDEF \ - {"atanh", (PyCFunction)cmath_atanh, METH_O, cmath_atanh__doc__}, - -static Py_complex -cmath_atanh_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_atanh(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_atan_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_atanh__doc__, +"atanh($module, z, /)\n" +"--\n" +"\n" +"Return the inverse hyperbolic tangent of z."); + +#define CMATH_ATANH_METHODDEF \ + {"atanh", (PyCFunction)cmath_atanh, METH_O, cmath_atanh__doc__}, + +static Py_complex +cmath_atanh_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_atanh(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_atanh_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_cos__doc__, -"cos($module, z, /)\n" -"--\n" -"\n" -"Return the cosine of z."); - -#define CMATH_COS_METHODDEF \ - {"cos", (PyCFunction)cmath_cos, METH_O, cmath_cos__doc__}, - -static Py_complex -cmath_cos_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_cos(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_atanh_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_cos__doc__, +"cos($module, z, /)\n" +"--\n" +"\n" +"Return the cosine of z."); + +#define CMATH_COS_METHODDEF \ + {"cos", (PyCFunction)cmath_cos, METH_O, cmath_cos__doc__}, + +static Py_complex +cmath_cos_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_cos(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_cos_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_cosh__doc__, -"cosh($module, z, /)\n" -"--\n" -"\n" -"Return the hyperbolic cosine of z."); - -#define CMATH_COSH_METHODDEF \ - {"cosh", (PyCFunction)cmath_cosh, METH_O, cmath_cosh__doc__}, - -static Py_complex -cmath_cosh_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_cosh(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_cos_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_cosh__doc__, +"cosh($module, z, /)\n" +"--\n" +"\n" +"Return the hyperbolic cosine of z."); + +#define CMATH_COSH_METHODDEF \ + {"cosh", (PyCFunction)cmath_cosh, METH_O, cmath_cosh__doc__}, + +static Py_complex +cmath_cosh_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_cosh(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_cosh_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_exp__doc__, -"exp($module, z, /)\n" -"--\n" -"\n" -"Return the exponential value e**z."); - -#define CMATH_EXP_METHODDEF \ - {"exp", (PyCFunction)cmath_exp, METH_O, cmath_exp__doc__}, - -static Py_complex -cmath_exp_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_exp(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_cosh_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_exp__doc__, +"exp($module, z, /)\n" +"--\n" +"\n" +"Return the exponential value e**z."); + +#define CMATH_EXP_METHODDEF \ + {"exp", (PyCFunction)cmath_exp, METH_O, cmath_exp__doc__}, + +static Py_complex +cmath_exp_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_exp(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_exp_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_log10__doc__, -"log10($module, z, /)\n" -"--\n" -"\n" -"Return the base-10 logarithm of z."); - -#define CMATH_LOG10_METHODDEF \ - {"log10", (PyCFunction)cmath_log10, METH_O, cmath_log10__doc__}, - -static Py_complex -cmath_log10_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_log10(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_exp_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_log10__doc__, +"log10($module, z, /)\n" +"--\n" +"\n" +"Return the base-10 logarithm of z."); + +#define CMATH_LOG10_METHODDEF \ + {"log10", (PyCFunction)cmath_log10, METH_O, cmath_log10__doc__}, + +static Py_complex +cmath_log10_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_log10(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_log10_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_sin__doc__, -"sin($module, z, /)\n" -"--\n" -"\n" -"Return the sine of z."); - -#define CMATH_SIN_METHODDEF \ - {"sin", (PyCFunction)cmath_sin, METH_O, cmath_sin__doc__}, - -static Py_complex -cmath_sin_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_sin(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_log10_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_sin__doc__, +"sin($module, z, /)\n" +"--\n" +"\n" +"Return the sine of z."); + +#define CMATH_SIN_METHODDEF \ + {"sin", (PyCFunction)cmath_sin, METH_O, cmath_sin__doc__}, + +static Py_complex +cmath_sin_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_sin(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_sin_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_sinh__doc__, -"sinh($module, z, /)\n" -"--\n" -"\n" -"Return the hyperbolic sine of z."); - -#define CMATH_SINH_METHODDEF \ - {"sinh", (PyCFunction)cmath_sinh, METH_O, cmath_sinh__doc__}, - -static Py_complex -cmath_sinh_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_sinh(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_sin_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_sinh__doc__, +"sinh($module, z, /)\n" +"--\n" +"\n" +"Return the hyperbolic sine of z."); + +#define CMATH_SINH_METHODDEF \ + {"sinh", (PyCFunction)cmath_sinh, METH_O, cmath_sinh__doc__}, + +static Py_complex +cmath_sinh_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_sinh(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_sinh_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_sqrt__doc__, -"sqrt($module, z, /)\n" -"--\n" -"\n" -"Return the square root of z."); - -#define CMATH_SQRT_METHODDEF \ - {"sqrt", (PyCFunction)cmath_sqrt, METH_O, cmath_sqrt__doc__}, - -static Py_complex -cmath_sqrt_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_sqrt(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_sinh_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_sqrt__doc__, +"sqrt($module, z, /)\n" +"--\n" +"\n" +"Return the square root of z."); + +#define CMATH_SQRT_METHODDEF \ + {"sqrt", (PyCFunction)cmath_sqrt, METH_O, cmath_sqrt__doc__}, + +static Py_complex +cmath_sqrt_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_sqrt(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_sqrt_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_tan__doc__, -"tan($module, z, /)\n" -"--\n" -"\n" -"Return the tangent of z."); - -#define CMATH_TAN_METHODDEF \ - {"tan", (PyCFunction)cmath_tan, METH_O, cmath_tan__doc__}, - -static Py_complex -cmath_tan_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_tan(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_sqrt_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_tan__doc__, +"tan($module, z, /)\n" +"--\n" +"\n" +"Return the tangent of z."); + +#define CMATH_TAN_METHODDEF \ + {"tan", (PyCFunction)cmath_tan, METH_O, cmath_tan__doc__}, + +static Py_complex +cmath_tan_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_tan(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_tan_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_tanh__doc__, -"tanh($module, z, /)\n" -"--\n" -"\n" -"Return the hyperbolic tangent of z."); - -#define CMATH_TANH_METHODDEF \ - {"tanh", (PyCFunction)cmath_tanh, METH_O, cmath_tanh__doc__}, - -static Py_complex -cmath_tanh_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_tanh(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - Py_complex _return_value; - + _return_value = cmath_tan_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_tanh__doc__, +"tanh($module, z, /)\n" +"--\n" +"\n" +"Return the hyperbolic tangent of z."); + +#define CMATH_TANH_METHODDEF \ + {"tanh", (PyCFunction)cmath_tanh, METH_O, cmath_tanh__doc__}, + +static Py_complex +cmath_tanh_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_tanh(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - /* modifications for z */ + goto exit; + } + /* modifications for z */ errno = 0; - _return_value = cmath_tanh_impl(module, z); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; - } - else { - return_value = PyComplex_FromCComplex(_return_value); - } - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_log__doc__, + _return_value = cmath_tanh_impl(module, z); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_log__doc__, "log($module, z, base=, /)\n" -"--\n" -"\n" +"--\n" +"\n" "log(z[, base]) -> the logarithm of z to the given base.\n" -"\n" -"If the base not specified, returns the natural logarithm (base e) of z."); - -#define CMATH_LOG_METHODDEF \ +"\n" +"If the base not specified, returns the natural logarithm (base e) of z."); + +#define CMATH_LOG_METHODDEF \ {"log", (PyCFunction)(void(*)(void))cmath_log, METH_FASTCALL, cmath_log__doc__}, - -static PyObject * -cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj); - -static PyObject * -cmath_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_complex x; - PyObject *y_obj = NULL; - + +static PyObject * +cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj); + +static PyObject * +cmath_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_complex x; + PyObject *y_obj = NULL; + if (!_PyArg_CheckPositional("log", nargs, 1, 2)) { - goto exit; - } + goto exit; + } x = PyComplex_AsCComplex(args[0]); if (PyErr_Occurred()) { goto exit; @@ -665,92 +665,92 @@ cmath_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } y_obj = args[1]; skip_optional: - return_value = cmath_log_impl(module, x, y_obj); - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_phase__doc__, -"phase($module, z, /)\n" -"--\n" -"\n" -"Return argument, also known as the phase angle, of a complex."); - -#define CMATH_PHASE_METHODDEF \ - {"phase", (PyCFunction)cmath_phase, METH_O, cmath_phase__doc__}, - -static PyObject * -cmath_phase_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_phase(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - + return_value = cmath_log_impl(module, x, y_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_phase__doc__, +"phase($module, z, /)\n" +"--\n" +"\n" +"Return argument, also known as the phase angle, of a complex."); + +#define CMATH_PHASE_METHODDEF \ + {"phase", (PyCFunction)cmath_phase, METH_O, cmath_phase__doc__}, + +static PyObject * +cmath_phase_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_phase(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - return_value = cmath_phase_impl(module, z); - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_polar__doc__, -"polar($module, z, /)\n" -"--\n" -"\n" -"Convert a complex from rectangular coordinates to polar coordinates.\n" -"\n" -"r is the distance from 0 and phi the phase angle."); - -#define CMATH_POLAR_METHODDEF \ - {"polar", (PyCFunction)cmath_polar, METH_O, cmath_polar__doc__}, - -static PyObject * -cmath_polar_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_polar(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - + goto exit; + } + return_value = cmath_phase_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_polar__doc__, +"polar($module, z, /)\n" +"--\n" +"\n" +"Convert a complex from rectangular coordinates to polar coordinates.\n" +"\n" +"r is the distance from 0 and phi the phase angle."); + +#define CMATH_POLAR_METHODDEF \ + {"polar", (PyCFunction)cmath_polar, METH_O, cmath_polar__doc__}, + +static PyObject * +cmath_polar_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_polar(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - return_value = cmath_polar_impl(module, z); - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_rect__doc__, -"rect($module, r, phi, /)\n" -"--\n" -"\n" -"Convert from polar coordinates to rectangular coordinates."); - -#define CMATH_RECT_METHODDEF \ + goto exit; + } + return_value = cmath_polar_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_rect__doc__, +"rect($module, r, phi, /)\n" +"--\n" +"\n" +"Convert from polar coordinates to rectangular coordinates."); + +#define CMATH_RECT_METHODDEF \ {"rect", (PyCFunction)(void(*)(void))cmath_rect, METH_FASTCALL, cmath_rect__doc__}, - -static PyObject * -cmath_rect_impl(PyObject *module, double r, double phi); - -static PyObject * -cmath_rect(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - double r; - double phi; - + +static PyObject * +cmath_rect_impl(PyObject *module, double r, double phi); + +static PyObject * +cmath_rect(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + double r; + double phi; + if (!_PyArg_CheckPositional("rect", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_CheckExact(args[0])) { r = PyFloat_AS_DOUBLE(args[0]); } @@ -771,142 +771,142 @@ cmath_rect(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - return_value = cmath_rect_impl(module, r, phi); - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_isfinite__doc__, -"isfinite($module, z, /)\n" -"--\n" -"\n" -"Return True if both the real and imaginary parts of z are finite, else False."); - -#define CMATH_ISFINITE_METHODDEF \ - {"isfinite", (PyCFunction)cmath_isfinite, METH_O, cmath_isfinite__doc__}, - -static PyObject * -cmath_isfinite_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_isfinite(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - + return_value = cmath_rect_impl(module, r, phi); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isfinite__doc__, +"isfinite($module, z, /)\n" +"--\n" +"\n" +"Return True if both the real and imaginary parts of z are finite, else False."); + +#define CMATH_ISFINITE_METHODDEF \ + {"isfinite", (PyCFunction)cmath_isfinite, METH_O, cmath_isfinite__doc__}, + +static PyObject * +cmath_isfinite_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_isfinite(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - return_value = cmath_isfinite_impl(module, z); - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_isnan__doc__, -"isnan($module, z, /)\n" -"--\n" -"\n" -"Checks if the real or imaginary part of z not a number (NaN)."); - -#define CMATH_ISNAN_METHODDEF \ - {"isnan", (PyCFunction)cmath_isnan, METH_O, cmath_isnan__doc__}, - -static PyObject * -cmath_isnan_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_isnan(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - + goto exit; + } + return_value = cmath_isfinite_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isnan__doc__, +"isnan($module, z, /)\n" +"--\n" +"\n" +"Checks if the real or imaginary part of z not a number (NaN)."); + +#define CMATH_ISNAN_METHODDEF \ + {"isnan", (PyCFunction)cmath_isnan, METH_O, cmath_isnan__doc__}, + +static PyObject * +cmath_isnan_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_isnan(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - return_value = cmath_isnan_impl(module, z); - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_isinf__doc__, -"isinf($module, z, /)\n" -"--\n" -"\n" -"Checks if the real or imaginary part of z is infinite."); - -#define CMATH_ISINF_METHODDEF \ - {"isinf", (PyCFunction)cmath_isinf, METH_O, cmath_isinf__doc__}, - -static PyObject * -cmath_isinf_impl(PyObject *module, Py_complex z); - -static PyObject * -cmath_isinf(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_complex z; - + goto exit; + } + return_value = cmath_isnan_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isinf__doc__, +"isinf($module, z, /)\n" +"--\n" +"\n" +"Checks if the real or imaginary part of z is infinite."); + +#define CMATH_ISINF_METHODDEF \ + {"isinf", (PyCFunction)cmath_isinf, METH_O, cmath_isinf__doc__}, + +static PyObject * +cmath_isinf_impl(PyObject *module, Py_complex z); + +static PyObject * +cmath_isinf(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + z = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) { - goto exit; - } - return_value = cmath_isinf_impl(module, z); - -exit: - return return_value; -} - -PyDoc_STRVAR(cmath_isclose__doc__, -"isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n" -"--\n" -"\n" -"Determine whether two complex numbers are close in value.\n" -"\n" -" rel_tol\n" -" maximum difference for being considered \"close\", relative to the\n" -" magnitude of the input values\n" -" abs_tol\n" -" maximum difference for being considered \"close\", regardless of the\n" -" magnitude of the input values\n" -"\n" -"Return True if a is close in value to b, and False otherwise.\n" -"\n" -"For the values to be considered close, the difference between them must be\n" -"smaller than at least one of the tolerances.\n" -"\n" -"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That is, NaN is\n" -"not close to anything, even itself. inf and -inf are only close to themselves."); - -#define CMATH_ISCLOSE_METHODDEF \ + goto exit; + } + return_value = cmath_isinf_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isclose__doc__, +"isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n" +"--\n" +"\n" +"Determine whether two complex numbers are close in value.\n" +"\n" +" rel_tol\n" +" maximum difference for being considered \"close\", relative to the\n" +" magnitude of the input values\n" +" abs_tol\n" +" maximum difference for being considered \"close\", regardless of the\n" +" magnitude of the input values\n" +"\n" +"Return True if a is close in value to b, and False otherwise.\n" +"\n" +"For the values to be considered close, the difference between them must be\n" +"smaller than at least one of the tolerances.\n" +"\n" +"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That is, NaN is\n" +"not close to anything, even itself. inf and -inf are only close to themselves."); + +#define CMATH_ISCLOSE_METHODDEF \ {"isclose", (PyCFunction)(void(*)(void))cmath_isclose, METH_FASTCALL|METH_KEYWORDS, cmath_isclose__doc__}, - -static int -cmath_isclose_impl(PyObject *module, Py_complex a, Py_complex b, - double rel_tol, double abs_tol); - -static PyObject * -cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; + +static int +cmath_isclose_impl(PyObject *module, Py_complex a, Py_complex b, + double rel_tol, double abs_tol); + +static PyObject * +cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0}; PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - Py_complex a; - Py_complex b; - double rel_tol = 1e-09; - double abs_tol = 0.0; - int _return_value; - + Py_complex a; + Py_complex b; + double rel_tol = 1e-09; + double abs_tol = 0.0; + int _return_value; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } a = PyComplex_AsCComplex(args[0]); if (PyErr_Occurred()) { goto exit; @@ -944,13 +944,13 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec } } skip_optional_kwonly: - _return_value = cmath_isclose_impl(module, a, b, rel_tol, abs_tol); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} + _return_value = cmath_isclose_impl(module, a, b, rel_tol, abs_tol); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} /*[clinic end generated code: output=353347db2e808e0d input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/fcntlmodule.c.h b/contrib/tools/python3/src/Modules/clinic/fcntlmodule.c.h index 024a44cfbf8..abaf237fd39 100644 --- a/contrib/tools/python3/src/Modules/clinic/fcntlmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/fcntlmodule.c.h @@ -1,40 +1,40 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(fcntl_fcntl__doc__, -"fcntl($module, fd, cmd, arg=0, /)\n" -"--\n" -"\n" -"Perform the operation `cmd` on file descriptor fd.\n" -"\n" -"The values used for `cmd` are operating system dependent, and are available\n" -"as constants in the fcntl module, using the same names as used in\n" -"the relevant C header files. The argument arg is optional, and\n" -"defaults to 0; it may be an int or a string. If arg is given as a string,\n" -"the return value of fcntl is a string of that length, containing the\n" -"resulting value put in the arg buffer by the operating system. The length\n" -"of the arg string is not allowed to exceed 1024 bytes. If the arg given\n" -"is an integer or if none is specified, the result value is an integer\n" -"corresponding to the return value of the fcntl call in the C code."); - -#define FCNTL_FCNTL_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(fcntl_fcntl__doc__, +"fcntl($module, fd, cmd, arg=0, /)\n" +"--\n" +"\n" +"Perform the operation `cmd` on file descriptor fd.\n" +"\n" +"The values used for `cmd` are operating system dependent, and are available\n" +"as constants in the fcntl module, using the same names as used in\n" +"the relevant C header files. The argument arg is optional, and\n" +"defaults to 0; it may be an int or a string. If arg is given as a string,\n" +"the return value of fcntl is a string of that length, containing the\n" +"resulting value put in the arg buffer by the operating system. The length\n" +"of the arg string is not allowed to exceed 1024 bytes. If the arg given\n" +"is an integer or if none is specified, the result value is an integer\n" +"corresponding to the return value of the fcntl call in the C code."); + +#define FCNTL_FCNTL_METHODDEF \ {"fcntl", (PyCFunction)(void(*)(void))fcntl_fcntl, METH_FASTCALL, fcntl_fcntl__doc__}, - -static PyObject * -fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg); - -static PyObject * -fcntl_fcntl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - int code; - PyObject *arg = NULL; - + +static PyObject * +fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg); + +static PyObject * +fcntl_fcntl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int code; + PyObject *arg = NULL; + if (!_PyArg_CheckPositional("fcntl", nargs, 2, 3)) { - goto exit; - } + goto exit; + } if (!conv_descriptor(args[0], &fd)) { goto exit; } @@ -52,64 +52,64 @@ fcntl_fcntl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } arg = args[2]; skip_optional: - return_value = fcntl_fcntl_impl(module, fd, code, arg); - -exit: - return return_value; -} - -PyDoc_STRVAR(fcntl_ioctl__doc__, -"ioctl($module, fd, request, arg=0, mutate_flag=True, /)\n" -"--\n" -"\n" -"Perform the operation `request` on file descriptor `fd`.\n" -"\n" -"The values used for `request` are operating system dependent, and are available\n" -"as constants in the fcntl or termios library modules, using the same names as\n" -"used in the relevant C header files.\n" -"\n" -"The argument `arg` is optional, and defaults to 0; it may be an int or a\n" -"buffer containing character data (most likely a string or an array).\n" -"\n" -"If the argument is a mutable buffer (such as an array) and if the\n" -"mutate_flag argument (which is only allowed in this case) is true then the\n" -"buffer is (in effect) passed to the operating system and changes made by\n" -"the OS will be reflected in the contents of the buffer after the call has\n" -"returned. The return value is the integer returned by the ioctl system\n" -"call.\n" -"\n" -"If the argument is a mutable buffer and the mutable_flag argument is false,\n" -"the behavior is as if a string had been passed.\n" -"\n" -"If the argument is an immutable buffer (most likely a string) then a copy\n" -"of the buffer is passed to the operating system and the return value is a\n" -"string of the same length containing whatever the operating system put in\n" -"the buffer. The length of the arg buffer in this case is not allowed to\n" -"exceed 1024 bytes.\n" -"\n" -"If the arg given is an integer or if none is specified, the result value is\n" -"an integer corresponding to the return value of the ioctl call in the C\n" -"code."); - -#define FCNTL_IOCTL_METHODDEF \ + return_value = fcntl_fcntl_impl(module, fd, code, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(fcntl_ioctl__doc__, +"ioctl($module, fd, request, arg=0, mutate_flag=True, /)\n" +"--\n" +"\n" +"Perform the operation `request` on file descriptor `fd`.\n" +"\n" +"The values used for `request` are operating system dependent, and are available\n" +"as constants in the fcntl or termios library modules, using the same names as\n" +"used in the relevant C header files.\n" +"\n" +"The argument `arg` is optional, and defaults to 0; it may be an int or a\n" +"buffer containing character data (most likely a string or an array).\n" +"\n" +"If the argument is a mutable buffer (such as an array) and if the\n" +"mutate_flag argument (which is only allowed in this case) is true then the\n" +"buffer is (in effect) passed to the operating system and changes made by\n" +"the OS will be reflected in the contents of the buffer after the call has\n" +"returned. The return value is the integer returned by the ioctl system\n" +"call.\n" +"\n" +"If the argument is a mutable buffer and the mutable_flag argument is false,\n" +"the behavior is as if a string had been passed.\n" +"\n" +"If the argument is an immutable buffer (most likely a string) then a copy\n" +"of the buffer is passed to the operating system and the return value is a\n" +"string of the same length containing whatever the operating system put in\n" +"the buffer. The length of the arg buffer in this case is not allowed to\n" +"exceed 1024 bytes.\n" +"\n" +"If the arg given is an integer or if none is specified, the result value is\n" +"an integer corresponding to the return value of the ioctl call in the C\n" +"code."); + +#define FCNTL_IOCTL_METHODDEF \ {"ioctl", (PyCFunction)(void(*)(void))fcntl_ioctl, METH_FASTCALL, fcntl_ioctl__doc__}, - -static PyObject * -fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, - PyObject *ob_arg, int mutate_arg); - -static PyObject * -fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - unsigned int code; - PyObject *ob_arg = NULL; - int mutate_arg = 1; - + +static PyObject * +fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, + PyObject *ob_arg, int mutate_arg); + +static PyObject * +fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + unsigned int code; + PyObject *ob_arg = NULL; + int mutate_arg = 1; + if (!_PyArg_CheckPositional("ioctl", nargs, 2, 4)) { - goto exit; - } + goto exit; + } if (!conv_descriptor(args[0], &fd)) { goto exit; } @@ -134,37 +134,37 @@ fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = fcntl_ioctl_impl(module, fd, code, ob_arg, mutate_arg); - -exit: - return return_value; -} - -PyDoc_STRVAR(fcntl_flock__doc__, -"flock($module, fd, operation, /)\n" -"--\n" -"\n" -"Perform the lock operation `operation` on file descriptor `fd`.\n" -"\n" -"See the Unix manual page for flock(2) for details (On some systems, this\n" -"function is emulated using fcntl())."); - -#define FCNTL_FLOCK_METHODDEF \ + return_value = fcntl_ioctl_impl(module, fd, code, ob_arg, mutate_arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(fcntl_flock__doc__, +"flock($module, fd, operation, /)\n" +"--\n" +"\n" +"Perform the lock operation `operation` on file descriptor `fd`.\n" +"\n" +"See the Unix manual page for flock(2) for details (On some systems, this\n" +"function is emulated using fcntl())."); + +#define FCNTL_FLOCK_METHODDEF \ {"flock", (PyCFunction)(void(*)(void))fcntl_flock, METH_FASTCALL, fcntl_flock__doc__}, - -static PyObject * -fcntl_flock_impl(PyObject *module, int fd, int code); - -static PyObject * -fcntl_flock(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - int code; - + +static PyObject * +fcntl_flock_impl(PyObject *module, int fd, int code); + +static PyObject * +fcntl_flock(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int code; + if (!_PyArg_CheckPositional("flock", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!conv_descriptor(args[0], &fd)) { goto exit; } @@ -177,59 +177,59 @@ fcntl_flock(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (code == -1 && PyErr_Occurred()) { goto exit; } - return_value = fcntl_flock_impl(module, fd, code); - -exit: - return return_value; -} - -PyDoc_STRVAR(fcntl_lockf__doc__, -"lockf($module, fd, cmd, len=0, start=0, whence=0, /)\n" -"--\n" -"\n" -"A wrapper around the fcntl() locking calls.\n" -"\n" -"`fd` is the file descriptor of the file to lock or unlock, and operation is one\n" -"of the following values:\n" -"\n" -" LOCK_UN - unlock\n" -" LOCK_SH - acquire a shared lock\n" -" LOCK_EX - acquire an exclusive lock\n" -"\n" -"When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n" -"LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n" -"lock cannot be acquired, an OSError will be raised and the exception will\n" -"have an errno attribute set to EACCES or EAGAIN (depending on the operating\n" -"system -- for portability, check for either value).\n" -"\n" -"`len` is the number of bytes to lock, with the default meaning to lock to\n" -"EOF. `start` is the byte offset, relative to `whence`, to that the lock\n" -"starts. `whence` is as with fileobj.seek(), specifically:\n" -"\n" -" 0 - relative to the start of the file (SEEK_SET)\n" -" 1 - relative to the current buffer position (SEEK_CUR)\n" -" 2 - relative to the end of the file (SEEK_END)"); - -#define FCNTL_LOCKF_METHODDEF \ + return_value = fcntl_flock_impl(module, fd, code); + +exit: + return return_value; +} + +PyDoc_STRVAR(fcntl_lockf__doc__, +"lockf($module, fd, cmd, len=0, start=0, whence=0, /)\n" +"--\n" +"\n" +"A wrapper around the fcntl() locking calls.\n" +"\n" +"`fd` is the file descriptor of the file to lock or unlock, and operation is one\n" +"of the following values:\n" +"\n" +" LOCK_UN - unlock\n" +" LOCK_SH - acquire a shared lock\n" +" LOCK_EX - acquire an exclusive lock\n" +"\n" +"When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n" +"LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n" +"lock cannot be acquired, an OSError will be raised and the exception will\n" +"have an errno attribute set to EACCES or EAGAIN (depending on the operating\n" +"system -- for portability, check for either value).\n" +"\n" +"`len` is the number of bytes to lock, with the default meaning to lock to\n" +"EOF. `start` is the byte offset, relative to `whence`, to that the lock\n" +"starts. `whence` is as with fileobj.seek(), specifically:\n" +"\n" +" 0 - relative to the start of the file (SEEK_SET)\n" +" 1 - relative to the current buffer position (SEEK_CUR)\n" +" 2 - relative to the end of the file (SEEK_END)"); + +#define FCNTL_LOCKF_METHODDEF \ {"lockf", (PyCFunction)(void(*)(void))fcntl_lockf, METH_FASTCALL, fcntl_lockf__doc__}, - -static PyObject * -fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, - PyObject *startobj, int whence); - -static PyObject * -fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - int code; - PyObject *lenobj = NULL; - PyObject *startobj = NULL; - int whence = 0; - + +static PyObject * +fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, + PyObject *startobj, int whence); + +static PyObject * +fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int code; + PyObject *lenobj = NULL; + PyObject *startobj = NULL; + int whence = 0; + if (!_PyArg_CheckPositional("lockf", nargs, 2, 5)) { - goto exit; - } + goto exit; + } if (!conv_descriptor(args[0], &fd)) { goto exit; } @@ -263,9 +263,9 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = fcntl_lockf_impl(module, fd, code, lenobj, startobj, whence); - -exit: - return return_value; -} + return_value = fcntl_lockf_impl(module, fd, code, lenobj, startobj, whence); + +exit: + return return_value; +} /*[clinic end generated code: output=e912d25e28362c52 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/gcmodule.c.h b/contrib/tools/python3/src/Modules/clinic/gcmodule.c.h index 72795c66bf7..16f8b1ae551 100644 --- a/contrib/tools/python3/src/Modules/clinic/gcmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/gcmodule.c.h @@ -1,104 +1,104 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(gc_enable__doc__, -"enable($module, /)\n" -"--\n" -"\n" -"Enable automatic garbage collection."); - -#define GC_ENABLE_METHODDEF \ - {"enable", (PyCFunction)gc_enable, METH_NOARGS, gc_enable__doc__}, - -static PyObject * -gc_enable_impl(PyObject *module); - -static PyObject * -gc_enable(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return gc_enable_impl(module); -} - -PyDoc_STRVAR(gc_disable__doc__, -"disable($module, /)\n" -"--\n" -"\n" -"Disable automatic garbage collection."); - -#define GC_DISABLE_METHODDEF \ - {"disable", (PyCFunction)gc_disable, METH_NOARGS, gc_disable__doc__}, - -static PyObject * -gc_disable_impl(PyObject *module); - -static PyObject * -gc_disable(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return gc_disable_impl(module); -} - -PyDoc_STRVAR(gc_isenabled__doc__, -"isenabled($module, /)\n" -"--\n" -"\n" -"Returns true if automatic garbage collection is enabled."); - -#define GC_ISENABLED_METHODDEF \ - {"isenabled", (PyCFunction)gc_isenabled, METH_NOARGS, gc_isenabled__doc__}, - -static int -gc_isenabled_impl(PyObject *module); - -static PyObject * -gc_isenabled(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = gc_isenabled_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(gc_collect__doc__, -"collect($module, /, generation=2)\n" -"--\n" -"\n" -"Run the garbage collector.\n" -"\n" -"With no arguments, run a full collection. The optional argument\n" -"may be an integer specifying which generation to collect. A ValueError\n" -"is raised if the generation number is invalid.\n" -"\n" -"The number of unreachable objects is returned."); - -#define GC_COLLECT_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(gc_enable__doc__, +"enable($module, /)\n" +"--\n" +"\n" +"Enable automatic garbage collection."); + +#define GC_ENABLE_METHODDEF \ + {"enable", (PyCFunction)gc_enable, METH_NOARGS, gc_enable__doc__}, + +static PyObject * +gc_enable_impl(PyObject *module); + +static PyObject * +gc_enable(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return gc_enable_impl(module); +} + +PyDoc_STRVAR(gc_disable__doc__, +"disable($module, /)\n" +"--\n" +"\n" +"Disable automatic garbage collection."); + +#define GC_DISABLE_METHODDEF \ + {"disable", (PyCFunction)gc_disable, METH_NOARGS, gc_disable__doc__}, + +static PyObject * +gc_disable_impl(PyObject *module); + +static PyObject * +gc_disable(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return gc_disable_impl(module); +} + +PyDoc_STRVAR(gc_isenabled__doc__, +"isenabled($module, /)\n" +"--\n" +"\n" +"Returns true if automatic garbage collection is enabled."); + +#define GC_ISENABLED_METHODDEF \ + {"isenabled", (PyCFunction)gc_isenabled, METH_NOARGS, gc_isenabled__doc__}, + +static int +gc_isenabled_impl(PyObject *module); + +static PyObject * +gc_isenabled(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = gc_isenabled_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(gc_collect__doc__, +"collect($module, /, generation=2)\n" +"--\n" +"\n" +"Run the garbage collector.\n" +"\n" +"With no arguments, run a full collection. The optional argument\n" +"may be an integer specifying which generation to collect. A ValueError\n" +"is raised if the generation number is invalid.\n" +"\n" +"The number of unreachable objects is returned."); + +#define GC_COLLECT_METHODDEF \ {"collect", (PyCFunction)(void(*)(void))gc_collect, METH_FASTCALL|METH_KEYWORDS, gc_collect__doc__}, - -static Py_ssize_t -gc_collect_impl(PyObject *module, int generation); - -static PyObject * -gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"generation", NULL}; + +static Py_ssize_t +gc_collect_impl(PyObject *module, int generation); + +static PyObject * +gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"generation", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "collect", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - int generation = NUM_GENERATIONS - 1; - Py_ssize_t _return_value; - + int generation = NUM_GENERATIONS - 1; + Py_ssize_t _return_value; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -112,128 +112,128 @@ gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * goto exit; } skip_optional_pos: - _return_value = gc_collect_impl(module, generation); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(gc_set_debug__doc__, -"set_debug($module, flags, /)\n" -"--\n" -"\n" -"Set the garbage collection debugging flags.\n" -"\n" -" flags\n" -" An integer that can have the following bits turned on:\n" -" DEBUG_STATS - Print statistics during collection.\n" -" DEBUG_COLLECTABLE - Print collectable objects found.\n" -" DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects\n" -" found.\n" -" DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n" -" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n" -"\n" -"Debugging information is written to sys.stderr."); - -#define GC_SET_DEBUG_METHODDEF \ - {"set_debug", (PyCFunction)gc_set_debug, METH_O, gc_set_debug__doc__}, - -static PyObject * -gc_set_debug_impl(PyObject *module, int flags); - -static PyObject * -gc_set_debug(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int flags; - + _return_value = gc_collect_impl(module, generation); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(gc_set_debug__doc__, +"set_debug($module, flags, /)\n" +"--\n" +"\n" +"Set the garbage collection debugging flags.\n" +"\n" +" flags\n" +" An integer that can have the following bits turned on:\n" +" DEBUG_STATS - Print statistics during collection.\n" +" DEBUG_COLLECTABLE - Print collectable objects found.\n" +" DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects\n" +" found.\n" +" DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n" +" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n" +"\n" +"Debugging information is written to sys.stderr."); + +#define GC_SET_DEBUG_METHODDEF \ + {"set_debug", (PyCFunction)gc_set_debug, METH_O, gc_set_debug__doc__}, + +static PyObject * +gc_set_debug_impl(PyObject *module, int flags); + +static PyObject * +gc_set_debug(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flags; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } flags = _PyLong_AsInt(arg); if (flags == -1 && PyErr_Occurred()) { goto exit; } - return_value = gc_set_debug_impl(module, flags); - -exit: - return return_value; -} - -PyDoc_STRVAR(gc_get_debug__doc__, -"get_debug($module, /)\n" -"--\n" -"\n" -"Get the garbage collection debugging flags."); - -#define GC_GET_DEBUG_METHODDEF \ - {"get_debug", (PyCFunction)gc_get_debug, METH_NOARGS, gc_get_debug__doc__}, - -static int -gc_get_debug_impl(PyObject *module); - -static PyObject * -gc_get_debug(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = gc_get_debug_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(gc_get_threshold__doc__, -"get_threshold($module, /)\n" -"--\n" -"\n" -"Return the current collection thresholds."); - -#define GC_GET_THRESHOLD_METHODDEF \ - {"get_threshold", (PyCFunction)gc_get_threshold, METH_NOARGS, gc_get_threshold__doc__}, - -static PyObject * -gc_get_threshold_impl(PyObject *module); - -static PyObject * -gc_get_threshold(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return gc_get_threshold_impl(module); -} - -PyDoc_STRVAR(gc_get_count__doc__, -"get_count($module, /)\n" -"--\n" -"\n" -"Return a three-tuple of the current collection counts."); - -#define GC_GET_COUNT_METHODDEF \ - {"get_count", (PyCFunction)gc_get_count, METH_NOARGS, gc_get_count__doc__}, - -static PyObject * -gc_get_count_impl(PyObject *module); - -static PyObject * -gc_get_count(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return gc_get_count_impl(module); -} - -PyDoc_STRVAR(gc_get_objects__doc__, + return_value = gc_set_debug_impl(module, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(gc_get_debug__doc__, +"get_debug($module, /)\n" +"--\n" +"\n" +"Get the garbage collection debugging flags."); + +#define GC_GET_DEBUG_METHODDEF \ + {"get_debug", (PyCFunction)gc_get_debug, METH_NOARGS, gc_get_debug__doc__}, + +static int +gc_get_debug_impl(PyObject *module); + +static PyObject * +gc_get_debug(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = gc_get_debug_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(gc_get_threshold__doc__, +"get_threshold($module, /)\n" +"--\n" +"\n" +"Return the current collection thresholds."); + +#define GC_GET_THRESHOLD_METHODDEF \ + {"get_threshold", (PyCFunction)gc_get_threshold, METH_NOARGS, gc_get_threshold__doc__}, + +static PyObject * +gc_get_threshold_impl(PyObject *module); + +static PyObject * +gc_get_threshold(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return gc_get_threshold_impl(module); +} + +PyDoc_STRVAR(gc_get_count__doc__, +"get_count($module, /)\n" +"--\n" +"\n" +"Return a three-tuple of the current collection counts."); + +#define GC_GET_COUNT_METHODDEF \ + {"get_count", (PyCFunction)gc_get_count, METH_NOARGS, gc_get_count__doc__}, + +static PyObject * +gc_get_count_impl(PyObject *module); + +static PyObject * +gc_get_count(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return gc_get_count_impl(module); +} + +PyDoc_STRVAR(gc_get_objects__doc__, "get_objects($module, /, generation=None)\n" -"--\n" -"\n" +"--\n" +"\n" "Return a list of objects tracked by the collector (excluding the list returned).\n" "\n" " generation\n" @@ -241,16 +241,16 @@ PyDoc_STRVAR(gc_get_objects__doc__, "\n" "If generation is not None, return only the objects tracked by the collector\n" "that are in that generation."); - -#define GC_GET_OBJECTS_METHODDEF \ + +#define GC_GET_OBJECTS_METHODDEF \ {"get_objects", (PyCFunction)(void(*)(void))gc_get_objects, METH_FASTCALL|METH_KEYWORDS, gc_get_objects__doc__}, - -static PyObject * + +static PyObject * gc_get_objects_impl(PyObject *module, Py_ssize_t generation); - -static PyObject * + +static PyObject * gc_get_objects(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ +{ PyObject *return_value = NULL; static const char * const _keywords[] = {"generation", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "get_objects", 0}; @@ -273,37 +273,37 @@ skip_optional_pos: exit: return return_value; -} - -PyDoc_STRVAR(gc_get_stats__doc__, -"get_stats($module, /)\n" -"--\n" -"\n" -"Return a list of dictionaries containing per-generation statistics."); - -#define GC_GET_STATS_METHODDEF \ - {"get_stats", (PyCFunction)gc_get_stats, METH_NOARGS, gc_get_stats__doc__}, - -static PyObject * -gc_get_stats_impl(PyObject *module); - -static PyObject * -gc_get_stats(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return gc_get_stats_impl(module); -} - -PyDoc_STRVAR(gc_is_tracked__doc__, -"is_tracked($module, obj, /)\n" -"--\n" -"\n" -"Returns true if the object is tracked by the garbage collector.\n" -"\n" -"Simple atomic objects will return false."); - -#define GC_IS_TRACKED_METHODDEF \ - {"is_tracked", (PyCFunction)gc_is_tracked, METH_O, gc_is_tracked__doc__}, - +} + +PyDoc_STRVAR(gc_get_stats__doc__, +"get_stats($module, /)\n" +"--\n" +"\n" +"Return a list of dictionaries containing per-generation statistics."); + +#define GC_GET_STATS_METHODDEF \ + {"get_stats", (PyCFunction)gc_get_stats, METH_NOARGS, gc_get_stats__doc__}, + +static PyObject * +gc_get_stats_impl(PyObject *module); + +static PyObject * +gc_get_stats(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return gc_get_stats_impl(module); +} + +PyDoc_STRVAR(gc_is_tracked__doc__, +"is_tracked($module, obj, /)\n" +"--\n" +"\n" +"Returns true if the object is tracked by the garbage collector.\n" +"\n" +"Simple atomic objects will return false."); + +#define GC_IS_TRACKED_METHODDEF \ + {"is_tracked", (PyCFunction)gc_is_tracked, METH_O, gc_is_tracked__doc__}, + PyDoc_STRVAR(gc_is_finalized__doc__, "is_finalized($module, obj, /)\n" "--\n" @@ -313,73 +313,73 @@ PyDoc_STRVAR(gc_is_finalized__doc__, #define GC_IS_FINALIZED_METHODDEF \ {"is_finalized", (PyCFunction)gc_is_finalized, METH_O, gc_is_finalized__doc__}, -PyDoc_STRVAR(gc_freeze__doc__, -"freeze($module, /)\n" -"--\n" -"\n" -"Freeze all current tracked objects and ignore them for future collections.\n" -"\n" -"This can be used before a POSIX fork() call to make the gc copy-on-write friendly.\n" -"Note: collection before a POSIX fork() call may free pages for future allocation\n" -"which can cause copy-on-write."); - -#define GC_FREEZE_METHODDEF \ - {"freeze", (PyCFunction)gc_freeze, METH_NOARGS, gc_freeze__doc__}, - -static PyObject * -gc_freeze_impl(PyObject *module); - -static PyObject * -gc_freeze(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return gc_freeze_impl(module); -} - -PyDoc_STRVAR(gc_unfreeze__doc__, -"unfreeze($module, /)\n" -"--\n" -"\n" -"Unfreeze all objects in the permanent generation.\n" -"\n" -"Put all objects in the permanent generation back into oldest generation."); - -#define GC_UNFREEZE_METHODDEF \ - {"unfreeze", (PyCFunction)gc_unfreeze, METH_NOARGS, gc_unfreeze__doc__}, - -static PyObject * -gc_unfreeze_impl(PyObject *module); - -static PyObject * -gc_unfreeze(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return gc_unfreeze_impl(module); -} - -PyDoc_STRVAR(gc_get_freeze_count__doc__, -"get_freeze_count($module, /)\n" -"--\n" -"\n" -"Return the number of objects in the permanent generation."); - -#define GC_GET_FREEZE_COUNT_METHODDEF \ - {"get_freeze_count", (PyCFunction)gc_get_freeze_count, METH_NOARGS, gc_get_freeze_count__doc__}, - -static Py_ssize_t -gc_get_freeze_count_impl(PyObject *module); - -static PyObject * -gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = gc_get_freeze_count_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} +PyDoc_STRVAR(gc_freeze__doc__, +"freeze($module, /)\n" +"--\n" +"\n" +"Freeze all current tracked objects and ignore them for future collections.\n" +"\n" +"This can be used before a POSIX fork() call to make the gc copy-on-write friendly.\n" +"Note: collection before a POSIX fork() call may free pages for future allocation\n" +"which can cause copy-on-write."); + +#define GC_FREEZE_METHODDEF \ + {"freeze", (PyCFunction)gc_freeze, METH_NOARGS, gc_freeze__doc__}, + +static PyObject * +gc_freeze_impl(PyObject *module); + +static PyObject * +gc_freeze(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return gc_freeze_impl(module); +} + +PyDoc_STRVAR(gc_unfreeze__doc__, +"unfreeze($module, /)\n" +"--\n" +"\n" +"Unfreeze all objects in the permanent generation.\n" +"\n" +"Put all objects in the permanent generation back into oldest generation."); + +#define GC_UNFREEZE_METHODDEF \ + {"unfreeze", (PyCFunction)gc_unfreeze, METH_NOARGS, gc_unfreeze__doc__}, + +static PyObject * +gc_unfreeze_impl(PyObject *module); + +static PyObject * +gc_unfreeze(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return gc_unfreeze_impl(module); +} + +PyDoc_STRVAR(gc_get_freeze_count__doc__, +"get_freeze_count($module, /)\n" +"--\n" +"\n" +"Return the number of objects in the permanent generation."); + +#define GC_GET_FREEZE_COUNT_METHODDEF \ + {"get_freeze_count", (PyCFunction)gc_get_freeze_count, METH_NOARGS, gc_get_freeze_count__doc__}, + +static Py_ssize_t +gc_get_freeze_count_impl(PyObject *module); + +static PyObject * +gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = gc_get_freeze_count_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} /*[clinic end generated code: output=bd6a8056989e2e69 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/grpmodule.c.h b/contrib/tools/python3/src/Modules/clinic/grpmodule.c.h index 2e2690ad8d3..3b4af80e436 100644 --- a/contrib/tools/python3/src/Modules/clinic/grpmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/grpmodule.c.h @@ -1,68 +1,68 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(grp_getgrgid__doc__, -"getgrgid($module, /, id)\n" -"--\n" -"\n" -"Return the group database entry for the given numeric group ID.\n" -"\n" -"If id is not valid, raise KeyError."); - -#define GRP_GETGRGID_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(grp_getgrgid__doc__, +"getgrgid($module, /, id)\n" +"--\n" +"\n" +"Return the group database entry for the given numeric group ID.\n" +"\n" +"If id is not valid, raise KeyError."); + +#define GRP_GETGRGID_METHODDEF \ {"getgrgid", (PyCFunction)(void(*)(void))grp_getgrgid, METH_FASTCALL|METH_KEYWORDS, grp_getgrgid__doc__}, - -static PyObject * -grp_getgrgid_impl(PyObject *module, PyObject *id); - -static PyObject * -grp_getgrgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"id", NULL}; + +static PyObject * +grp_getgrgid_impl(PyObject *module, PyObject *id); + +static PyObject * +grp_getgrgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"id", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "getgrgid", 0}; PyObject *argsbuf[1]; - PyObject *id; - + PyObject *id; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } id = args[0]; - return_value = grp_getgrgid_impl(module, id); - -exit: - return return_value; -} - -PyDoc_STRVAR(grp_getgrnam__doc__, -"getgrnam($module, /, name)\n" -"--\n" -"\n" -"Return the group database entry for the given group name.\n" -"\n" -"If name is not valid, raise KeyError."); - -#define GRP_GETGRNAM_METHODDEF \ + return_value = grp_getgrgid_impl(module, id); + +exit: + return return_value; +} + +PyDoc_STRVAR(grp_getgrnam__doc__, +"getgrnam($module, /, name)\n" +"--\n" +"\n" +"Return the group database entry for the given group name.\n" +"\n" +"If name is not valid, raise KeyError."); + +#define GRP_GETGRNAM_METHODDEF \ {"getgrnam", (PyCFunction)(void(*)(void))grp_getgrnam, METH_FASTCALL|METH_KEYWORDS, grp_getgrnam__doc__}, - -static PyObject * -grp_getgrnam_impl(PyObject *module, PyObject *name); - -static PyObject * -grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"name", NULL}; + +static PyObject * +grp_getgrnam_impl(PyObject *module, PyObject *name); + +static PyObject * +grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "getgrnam", 0}; PyObject *argsbuf[1]; - PyObject *name; - + PyObject *name; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("getgrnam", "argument 'name'", "str", args[0]); goto exit; @@ -71,30 +71,30 @@ grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } name = args[0]; - return_value = grp_getgrnam_impl(module, name); - -exit: - return return_value; -} - -PyDoc_STRVAR(grp_getgrall__doc__, -"getgrall($module, /)\n" -"--\n" -"\n" -"Return a list of all available group entries, in arbitrary order.\n" -"\n" -"An entry whose name starts with \'+\' or \'-\' represents an instruction\n" -"to use YP/NIS and may not be accessible via getgrnam or getgrgid."); - -#define GRP_GETGRALL_METHODDEF \ - {"getgrall", (PyCFunction)grp_getgrall, METH_NOARGS, grp_getgrall__doc__}, - -static PyObject * -grp_getgrall_impl(PyObject *module); - -static PyObject * -grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return grp_getgrall_impl(module); -} + return_value = grp_getgrnam_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(grp_getgrall__doc__, +"getgrall($module, /)\n" +"--\n" +"\n" +"Return a list of all available group entries, in arbitrary order.\n" +"\n" +"An entry whose name starts with \'+\' or \'-\' represents an instruction\n" +"to use YP/NIS and may not be accessible via getgrnam or getgrgid."); + +#define GRP_GETGRALL_METHODDEF \ + {"getgrall", (PyCFunction)grp_getgrall, METH_NOARGS, grp_getgrall__doc__}, + +static PyObject * +grp_getgrall_impl(PyObject *module); + +static PyObject * +grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return grp_getgrall_impl(module); +} /*[clinic end generated code: output=9b3f26779e4e1a52 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/mathmodule.c.h b/contrib/tools/python3/src/Modules/clinic/mathmodule.c.h index 65f3dd4f520..95c0ece266a 100644 --- a/contrib/tools/python3/src/Modules/clinic/mathmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/mathmodule.c.h @@ -1,40 +1,40 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(math_ceil__doc__, -"ceil($module, x, /)\n" -"--\n" -"\n" -"Return the ceiling of x as an Integral.\n" -"\n" -"This is the smallest integer >= x."); - -#define MATH_CEIL_METHODDEF \ - {"ceil", (PyCFunction)math_ceil, METH_O, math_ceil__doc__}, - -PyDoc_STRVAR(math_floor__doc__, -"floor($module, x, /)\n" -"--\n" -"\n" -"Return the floor of x as an Integral.\n" -"\n" -"This is the largest integer <= x."); - -#define MATH_FLOOR_METHODDEF \ - {"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__}, - -PyDoc_STRVAR(math_fsum__doc__, -"fsum($module, seq, /)\n" -"--\n" -"\n" -"Return an accurate floating point sum of values in the iterable seq.\n" -"\n" -"Assumes IEEE-754 floating point arithmetic."); - -#define MATH_FSUM_METHODDEF \ - {"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__}, - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(math_ceil__doc__, +"ceil($module, x, /)\n" +"--\n" +"\n" +"Return the ceiling of x as an Integral.\n" +"\n" +"This is the smallest integer >= x."); + +#define MATH_CEIL_METHODDEF \ + {"ceil", (PyCFunction)math_ceil, METH_O, math_ceil__doc__}, + +PyDoc_STRVAR(math_floor__doc__, +"floor($module, x, /)\n" +"--\n" +"\n" +"Return the floor of x as an Integral.\n" +"\n" +"This is the largest integer <= x."); + +#define MATH_FLOOR_METHODDEF \ + {"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__}, + +PyDoc_STRVAR(math_fsum__doc__, +"fsum($module, seq, /)\n" +"--\n" +"\n" +"Return an accurate floating point sum of values in the iterable seq.\n" +"\n" +"Assumes IEEE-754 floating point arithmetic."); + +#define MATH_FSUM_METHODDEF \ + {"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__}, + PyDoc_STRVAR(math_isqrt__doc__, "isqrt($module, n, /)\n" "--\n" @@ -44,52 +44,52 @@ PyDoc_STRVAR(math_isqrt__doc__, #define MATH_ISQRT_METHODDEF \ {"isqrt", (PyCFunction)math_isqrt, METH_O, math_isqrt__doc__}, -PyDoc_STRVAR(math_factorial__doc__, -"factorial($module, x, /)\n" -"--\n" -"\n" -"Find x!.\n" -"\n" -"Raise a ValueError if x is negative or non-integral."); - -#define MATH_FACTORIAL_METHODDEF \ - {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__}, - -PyDoc_STRVAR(math_trunc__doc__, -"trunc($module, x, /)\n" -"--\n" -"\n" -"Truncates the Real x to the nearest Integral toward 0.\n" -"\n" -"Uses the __trunc__ magic method."); - -#define MATH_TRUNC_METHODDEF \ - {"trunc", (PyCFunction)math_trunc, METH_O, math_trunc__doc__}, - -PyDoc_STRVAR(math_frexp__doc__, -"frexp($module, x, /)\n" -"--\n" -"\n" -"Return the mantissa and exponent of x, as pair (m, e).\n" -"\n" -"m is a float and e is an int, such that x = m * 2.**e.\n" -"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0."); - -#define MATH_FREXP_METHODDEF \ - {"frexp", (PyCFunction)math_frexp, METH_O, math_frexp__doc__}, - -static PyObject * -math_frexp_impl(PyObject *module, double x); - -static PyObject * -math_frexp(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - double x; - +PyDoc_STRVAR(math_factorial__doc__, +"factorial($module, x, /)\n" +"--\n" +"\n" +"Find x!.\n" +"\n" +"Raise a ValueError if x is negative or non-integral."); + +#define MATH_FACTORIAL_METHODDEF \ + {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__}, + +PyDoc_STRVAR(math_trunc__doc__, +"trunc($module, x, /)\n" +"--\n" +"\n" +"Truncates the Real x to the nearest Integral toward 0.\n" +"\n" +"Uses the __trunc__ magic method."); + +#define MATH_TRUNC_METHODDEF \ + {"trunc", (PyCFunction)math_trunc, METH_O, math_trunc__doc__}, + +PyDoc_STRVAR(math_frexp__doc__, +"frexp($module, x, /)\n" +"--\n" +"\n" +"Return the mantissa and exponent of x, as pair (m, e).\n" +"\n" +"m is a float and e is an int, such that x = m * 2.**e.\n" +"If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0."); + +#define MATH_FREXP_METHODDEF \ + {"frexp", (PyCFunction)math_frexp, METH_O, math_frexp__doc__}, + +static PyObject * +math_frexp_impl(PyObject *module, double x); + +static PyObject * +math_frexp(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double x; + if (PyFloat_CheckExact(arg)) { x = PyFloat_AS_DOUBLE(arg); - } + } else { x = PyFloat_AsDouble(arg); @@ -97,36 +97,36 @@ math_frexp(PyObject *module, PyObject *arg) goto exit; } } - return_value = math_frexp_impl(module, x); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_ldexp__doc__, -"ldexp($module, x, i, /)\n" -"--\n" -"\n" -"Return x * (2**i).\n" -"\n" -"This is essentially the inverse of frexp()."); - -#define MATH_LDEXP_METHODDEF \ + return_value = math_frexp_impl(module, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_ldexp__doc__, +"ldexp($module, x, i, /)\n" +"--\n" +"\n" +"Return x * (2**i).\n" +"\n" +"This is essentially the inverse of frexp()."); + +#define MATH_LDEXP_METHODDEF \ {"ldexp", (PyCFunction)(void(*)(void))math_ldexp, METH_FASTCALL, math_ldexp__doc__}, - -static PyObject * -math_ldexp_impl(PyObject *module, double x, PyObject *i); - -static PyObject * -math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - double x; - PyObject *i; - + +static PyObject * +math_ldexp_impl(PyObject *module, double x, PyObject *i); + +static PyObject * +math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + double x; + PyObject *i; + if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_CheckExact(args[0])) { x = PyFloat_AS_DOUBLE(args[0]); } @@ -138,35 +138,35 @@ math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } } i = args[1]; - return_value = math_ldexp_impl(module, x, i); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_modf__doc__, -"modf($module, x, /)\n" -"--\n" -"\n" -"Return the fractional and integer parts of x.\n" -"\n" -"Both results carry the sign of x and are floats."); - -#define MATH_MODF_METHODDEF \ - {"modf", (PyCFunction)math_modf, METH_O, math_modf__doc__}, - -static PyObject * -math_modf_impl(PyObject *module, double x); - -static PyObject * -math_modf(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - double x; - + return_value = math_ldexp_impl(module, x, i); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_modf__doc__, +"modf($module, x, /)\n" +"--\n" +"\n" +"Return the fractional and integer parts of x.\n" +"\n" +"Both results carry the sign of x and are floats."); + +#define MATH_MODF_METHODDEF \ + {"modf", (PyCFunction)math_modf, METH_O, math_modf__doc__}, + +static PyObject * +math_modf_impl(PyObject *module, double x); + +static PyObject * +math_modf(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double x; + if (PyFloat_CheckExact(arg)) { x = PyFloat_AS_DOUBLE(arg); - } + } else { x = PyFloat_AsDouble(arg); @@ -174,97 +174,97 @@ math_modf(PyObject *module, PyObject *arg) goto exit; } } - return_value = math_modf_impl(module, x); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_log__doc__, -"log(x, [base=math.e])\n" -"Return the logarithm of x to the given base.\n" -"\n" -"If the base not specified, returns the natural logarithm (base e) of x."); - -#define MATH_LOG_METHODDEF \ - {"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__}, - -static PyObject * -math_log_impl(PyObject *module, PyObject *x, int group_right_1, - PyObject *base); - -static PyObject * -math_log(PyObject *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *x; - int group_right_1 = 0; - PyObject *base = NULL; - - switch (PyTuple_GET_SIZE(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O:log", &x)) { - goto exit; - } - break; - case 2: - if (!PyArg_ParseTuple(args, "OO:log", &x, &base)) { - goto exit; - } - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "math.log requires 1 to 2 arguments"); - goto exit; - } - return_value = math_log_impl(module, x, group_right_1, base); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_log2__doc__, -"log2($module, x, /)\n" -"--\n" -"\n" -"Return the base 2 logarithm of x."); - -#define MATH_LOG2_METHODDEF \ - {"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__}, - -PyDoc_STRVAR(math_log10__doc__, -"log10($module, x, /)\n" -"--\n" -"\n" -"Return the base 10 logarithm of x."); - -#define MATH_LOG10_METHODDEF \ - {"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__}, - -PyDoc_STRVAR(math_fmod__doc__, -"fmod($module, x, y, /)\n" -"--\n" -"\n" -"Return fmod(x, y), according to platform C.\n" -"\n" -"x % y may differ."); - -#define MATH_FMOD_METHODDEF \ + return_value = math_modf_impl(module, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_log__doc__, +"log(x, [base=math.e])\n" +"Return the logarithm of x to the given base.\n" +"\n" +"If the base not specified, returns the natural logarithm (base e) of x."); + +#define MATH_LOG_METHODDEF \ + {"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__}, + +static PyObject * +math_log_impl(PyObject *module, PyObject *x, int group_right_1, + PyObject *base); + +static PyObject * +math_log(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *x; + int group_right_1 = 0; + PyObject *base = NULL; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:log", &x)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:log", &x, &base)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "math.log requires 1 to 2 arguments"); + goto exit; + } + return_value = math_log_impl(module, x, group_right_1, base); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_log2__doc__, +"log2($module, x, /)\n" +"--\n" +"\n" +"Return the base 2 logarithm of x."); + +#define MATH_LOG2_METHODDEF \ + {"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__}, + +PyDoc_STRVAR(math_log10__doc__, +"log10($module, x, /)\n" +"--\n" +"\n" +"Return the base 10 logarithm of x."); + +#define MATH_LOG10_METHODDEF \ + {"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__}, + +PyDoc_STRVAR(math_fmod__doc__, +"fmod($module, x, y, /)\n" +"--\n" +"\n" +"Return fmod(x, y), according to platform C.\n" +"\n" +"x % y may differ."); + +#define MATH_FMOD_METHODDEF \ {"fmod", (PyCFunction)(void(*)(void))math_fmod, METH_FASTCALL, math_fmod__doc__}, - -static PyObject * -math_fmod_impl(PyObject *module, double x, double y); - -static PyObject * -math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - double x; - double y; - + +static PyObject * +math_fmod_impl(PyObject *module, double x, double y); + +static PyObject * +math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + double x; + double y; + if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_CheckExact(args[0])) { x = PyFloat_AS_DOUBLE(args[0]); } @@ -285,16 +285,16 @@ math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - return_value = math_fmod_impl(module, x, y); - -exit: - return return_value; -} - + return_value = math_fmod_impl(module, x, y); + +exit: + return return_value; +} + PyDoc_STRVAR(math_dist__doc__, "dist($module, p, q, /)\n" -"--\n" -"\n" +"--\n" +"\n" "Return the Euclidean distance between two points p and q.\n" "\n" "The points should be specified as sequences (or iterables) of\n" @@ -302,53 +302,53 @@ PyDoc_STRVAR(math_dist__doc__, "\n" "Roughly equivalent to:\n" " sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))"); - + #define MATH_DIST_METHODDEF \ {"dist", (PyCFunction)(void(*)(void))math_dist, METH_FASTCALL, math_dist__doc__}, - -static PyObject * + +static PyObject * math_dist_impl(PyObject *module, PyObject *p, PyObject *q); - -static PyObject * + +static PyObject * math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; +{ + PyObject *return_value = NULL; PyObject *p; PyObject *q; - + if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) { - goto exit; - } + goto exit; + } p = args[0]; q = args[1]; return_value = math_dist_impl(module, p, q); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_pow__doc__, -"pow($module, x, y, /)\n" -"--\n" -"\n" -"Return x**y (x to the power of y)."); - -#define MATH_POW_METHODDEF \ + +exit: + return return_value; +} + +PyDoc_STRVAR(math_pow__doc__, +"pow($module, x, y, /)\n" +"--\n" +"\n" +"Return x**y (x to the power of y)."); + +#define MATH_POW_METHODDEF \ {"pow", (PyCFunction)(void(*)(void))math_pow, METH_FASTCALL, math_pow__doc__}, - -static PyObject * -math_pow_impl(PyObject *module, double x, double y); - -static PyObject * -math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - double x; - double y; - + +static PyObject * +math_pow_impl(PyObject *module, double x, double y); + +static PyObject * +math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + double x; + double y; + if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_CheckExact(args[0])) { x = PyFloat_AS_DOUBLE(args[0]); } @@ -369,33 +369,33 @@ math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - return_value = math_pow_impl(module, x, y); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_degrees__doc__, -"degrees($module, x, /)\n" -"--\n" -"\n" -"Convert angle x from radians to degrees."); - -#define MATH_DEGREES_METHODDEF \ - {"degrees", (PyCFunction)math_degrees, METH_O, math_degrees__doc__}, - -static PyObject * -math_degrees_impl(PyObject *module, double x); - -static PyObject * -math_degrees(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - double x; - + return_value = math_pow_impl(module, x, y); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_degrees__doc__, +"degrees($module, x, /)\n" +"--\n" +"\n" +"Convert angle x from radians to degrees."); + +#define MATH_DEGREES_METHODDEF \ + {"degrees", (PyCFunction)math_degrees, METH_O, math_degrees__doc__}, + +static PyObject * +math_degrees_impl(PyObject *module, double x); + +static PyObject * +math_degrees(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double x; + if (PyFloat_CheckExact(arg)) { x = PyFloat_AS_DOUBLE(arg); - } + } else { x = PyFloat_AsDouble(arg); @@ -403,33 +403,33 @@ math_degrees(PyObject *module, PyObject *arg) goto exit; } } - return_value = math_degrees_impl(module, x); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_radians__doc__, -"radians($module, x, /)\n" -"--\n" -"\n" -"Convert angle x from degrees to radians."); - -#define MATH_RADIANS_METHODDEF \ - {"radians", (PyCFunction)math_radians, METH_O, math_radians__doc__}, - -static PyObject * -math_radians_impl(PyObject *module, double x); - -static PyObject * -math_radians(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - double x; - + return_value = math_degrees_impl(module, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_radians__doc__, +"radians($module, x, /)\n" +"--\n" +"\n" +"Convert angle x from degrees to radians."); + +#define MATH_RADIANS_METHODDEF \ + {"radians", (PyCFunction)math_radians, METH_O, math_radians__doc__}, + +static PyObject * +math_radians_impl(PyObject *module, double x); + +static PyObject * +math_radians(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double x; + if (PyFloat_CheckExact(arg)) { x = PyFloat_AS_DOUBLE(arg); - } + } else { x = PyFloat_AsDouble(arg); @@ -437,33 +437,33 @@ math_radians(PyObject *module, PyObject *arg) goto exit; } } - return_value = math_radians_impl(module, x); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_isfinite__doc__, -"isfinite($module, x, /)\n" -"--\n" -"\n" -"Return True if x is neither an infinity nor a NaN, and False otherwise."); - -#define MATH_ISFINITE_METHODDEF \ - {"isfinite", (PyCFunction)math_isfinite, METH_O, math_isfinite__doc__}, - -static PyObject * -math_isfinite_impl(PyObject *module, double x); - -static PyObject * -math_isfinite(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - double x; - + return_value = math_radians_impl(module, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_isfinite__doc__, +"isfinite($module, x, /)\n" +"--\n" +"\n" +"Return True if x is neither an infinity nor a NaN, and False otherwise."); + +#define MATH_ISFINITE_METHODDEF \ + {"isfinite", (PyCFunction)math_isfinite, METH_O, math_isfinite__doc__}, + +static PyObject * +math_isfinite_impl(PyObject *module, double x); + +static PyObject * +math_isfinite(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double x; + if (PyFloat_CheckExact(arg)) { x = PyFloat_AS_DOUBLE(arg); - } + } else { x = PyFloat_AsDouble(arg); @@ -471,33 +471,33 @@ math_isfinite(PyObject *module, PyObject *arg) goto exit; } } - return_value = math_isfinite_impl(module, x); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_isnan__doc__, -"isnan($module, x, /)\n" -"--\n" -"\n" -"Return True if x is a NaN (not a number), and False otherwise."); - -#define MATH_ISNAN_METHODDEF \ - {"isnan", (PyCFunction)math_isnan, METH_O, math_isnan__doc__}, - -static PyObject * -math_isnan_impl(PyObject *module, double x); - -static PyObject * -math_isnan(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - double x; - + return_value = math_isfinite_impl(module, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_isnan__doc__, +"isnan($module, x, /)\n" +"--\n" +"\n" +"Return True if x is a NaN (not a number), and False otherwise."); + +#define MATH_ISNAN_METHODDEF \ + {"isnan", (PyCFunction)math_isnan, METH_O, math_isnan__doc__}, + +static PyObject * +math_isnan_impl(PyObject *module, double x); + +static PyObject * +math_isnan(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double x; + if (PyFloat_CheckExact(arg)) { x = PyFloat_AS_DOUBLE(arg); - } + } else { x = PyFloat_AsDouble(arg); @@ -505,33 +505,33 @@ math_isnan(PyObject *module, PyObject *arg) goto exit; } } - return_value = math_isnan_impl(module, x); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_isinf__doc__, -"isinf($module, x, /)\n" -"--\n" -"\n" -"Return True if x is a positive or negative infinity, and False otherwise."); - -#define MATH_ISINF_METHODDEF \ - {"isinf", (PyCFunction)math_isinf, METH_O, math_isinf__doc__}, - -static PyObject * -math_isinf_impl(PyObject *module, double x); - -static PyObject * -math_isinf(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - double x; - + return_value = math_isnan_impl(module, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_isinf__doc__, +"isinf($module, x, /)\n" +"--\n" +"\n" +"Return True if x is a positive or negative infinity, and False otherwise."); + +#define MATH_ISINF_METHODDEF \ + {"isinf", (PyCFunction)math_isinf, METH_O, math_isinf__doc__}, + +static PyObject * +math_isinf_impl(PyObject *module, double x); + +static PyObject * +math_isinf(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double x; + if (PyFloat_CheckExact(arg)) { x = PyFloat_AS_DOUBLE(arg); - } + } else { x = PyFloat_AsDouble(arg); @@ -539,59 +539,59 @@ math_isinf(PyObject *module, PyObject *arg) goto exit; } } - return_value = math_isinf_impl(module, x); - -exit: - return return_value; -} - -PyDoc_STRVAR(math_isclose__doc__, -"isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n" -"--\n" -"\n" -"Determine whether two floating point numbers are close in value.\n" -"\n" -" rel_tol\n" -" maximum difference for being considered \"close\", relative to the\n" -" magnitude of the input values\n" -" abs_tol\n" -" maximum difference for being considered \"close\", regardless of the\n" -" magnitude of the input values\n" -"\n" -"Return True if a is close in value to b, and False otherwise.\n" -"\n" -"For the values to be considered close, the difference between them\n" -"must be smaller than at least one of the tolerances.\n" -"\n" -"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That\n" -"is, NaN is not close to anything, even itself. inf and -inf are\n" -"only close to themselves."); - -#define MATH_ISCLOSE_METHODDEF \ + return_value = math_isinf_impl(module, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(math_isclose__doc__, +"isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n" +"--\n" +"\n" +"Determine whether two floating point numbers are close in value.\n" +"\n" +" rel_tol\n" +" maximum difference for being considered \"close\", relative to the\n" +" magnitude of the input values\n" +" abs_tol\n" +" maximum difference for being considered \"close\", regardless of the\n" +" magnitude of the input values\n" +"\n" +"Return True if a is close in value to b, and False otherwise.\n" +"\n" +"For the values to be considered close, the difference between them\n" +"must be smaller than at least one of the tolerances.\n" +"\n" +"-inf, inf and NaN behave similarly to the IEEE 754 Standard. That\n" +"is, NaN is not close to anything, even itself. inf and -inf are\n" +"only close to themselves."); + +#define MATH_ISCLOSE_METHODDEF \ {"isclose", (PyCFunction)(void(*)(void))math_isclose, METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__}, - -static int -math_isclose_impl(PyObject *module, double a, double b, double rel_tol, - double abs_tol); - -static PyObject * -math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; + +static int +math_isclose_impl(PyObject *module, double a, double b, double rel_tol, + double abs_tol); + +static PyObject * +math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0}; PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - double a; - double b; - double rel_tol = 1e-09; - double abs_tol = 0.0; - int _return_value; - + double a; + double b; + double rel_tol = 1e-09; + double abs_tol = 0.0; + int _return_value; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_CheckExact(args[0])) { a = PyFloat_AS_DOUBLE(args[0]); } @@ -641,15 +641,15 @@ math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject } } skip_optional_kwonly: - _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} + _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} PyDoc_STRVAR(math_prod__doc__, "prod($module, iterable, /, *, start=1)\n" diff --git a/contrib/tools/python3/src/Modules/clinic/md5module.c.h b/contrib/tools/python3/src/Modules/clinic/md5module.c.h index c109f9efec6..8c41a3ed871 100644 --- a/contrib/tools/python3/src/Modules/clinic/md5module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/md5module.c.h @@ -1,97 +1,97 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(MD5Type_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define MD5TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)MD5Type_copy, METH_NOARGS, MD5Type_copy__doc__}, - -static PyObject * -MD5Type_copy_impl(MD5object *self); - -static PyObject * -MD5Type_copy(MD5object *self, PyObject *Py_UNUSED(ignored)) -{ - return MD5Type_copy_impl(self); -} - -PyDoc_STRVAR(MD5Type_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define MD5TYPE_DIGEST_METHODDEF \ - {"digest", (PyCFunction)MD5Type_digest, METH_NOARGS, MD5Type_digest__doc__}, - -static PyObject * -MD5Type_digest_impl(MD5object *self); - -static PyObject * -MD5Type_digest(MD5object *self, PyObject *Py_UNUSED(ignored)) -{ - return MD5Type_digest_impl(self); -} - -PyDoc_STRVAR(MD5Type_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define MD5TYPE_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)MD5Type_hexdigest, METH_NOARGS, MD5Type_hexdigest__doc__}, - -static PyObject * -MD5Type_hexdigest_impl(MD5object *self); - -static PyObject * -MD5Type_hexdigest(MD5object *self, PyObject *Py_UNUSED(ignored)) -{ - return MD5Type_hexdigest_impl(self); -} - -PyDoc_STRVAR(MD5Type_update__doc__, -"update($self, obj, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided string."); - -#define MD5TYPE_UPDATE_METHODDEF \ - {"update", (PyCFunction)MD5Type_update, METH_O, MD5Type_update__doc__}, - -PyDoc_STRVAR(_md5_md5__doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(MD5Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define MD5TYPE_COPY_METHODDEF \ + {"copy", (PyCFunction)MD5Type_copy, METH_NOARGS, MD5Type_copy__doc__}, + +static PyObject * +MD5Type_copy_impl(MD5object *self); + +static PyObject * +MD5Type_copy(MD5object *self, PyObject *Py_UNUSED(ignored)) +{ + return MD5Type_copy_impl(self); +} + +PyDoc_STRVAR(MD5Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define MD5TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)MD5Type_digest, METH_NOARGS, MD5Type_digest__doc__}, + +static PyObject * +MD5Type_digest_impl(MD5object *self); + +static PyObject * +MD5Type_digest(MD5object *self, PyObject *Py_UNUSED(ignored)) +{ + return MD5Type_digest_impl(self); +} + +PyDoc_STRVAR(MD5Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define MD5TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)MD5Type_hexdigest, METH_NOARGS, MD5Type_hexdigest__doc__}, + +static PyObject * +MD5Type_hexdigest_impl(MD5object *self); + +static PyObject * +MD5Type_hexdigest(MD5object *self, PyObject *Py_UNUSED(ignored)) +{ + return MD5Type_hexdigest_impl(self); +} + +PyDoc_STRVAR(MD5Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define MD5TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)MD5Type_update, METH_O, MD5Type_update__doc__}, + +PyDoc_STRVAR(_md5_md5__doc__, "md5($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new MD5 hash object; optionally initialized with a string."); - -#define _MD5_MD5_METHODDEF \ +"--\n" +"\n" +"Return a new MD5 hash object; optionally initialized with a string."); + +#define _MD5_MD5_METHODDEF \ {"md5", (PyCFunction)(void(*)(void))_md5_md5, METH_FASTCALL|METH_KEYWORDS, _md5_md5__doc__}, - -static PyObject * + +static PyObject * _md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "md5", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; + PyObject *string = NULL; int usedforsecurity = 1; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -111,8 +111,8 @@ skip_optional_pos: } skip_optional_kwonly: return_value = _md5_md5_impl(module, string, usedforsecurity); - -exit: - return return_value; -} + +exit: + return return_value; +} /*[clinic end generated code: output=dbe3abc60086f3ef input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/posixmodule.c.h b/contrib/tools/python3/src/Modules/clinic/posixmodule.c.h index 28798ab99c1..e7d4328d30e 100644 --- a/contrib/tools/python3/src/Modules/clinic/posixmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/posixmodule.c.h @@ -1,54 +1,54 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(os_stat__doc__, -"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" -"--\n" -"\n" -"Perform a stat system call on the given path.\n" -"\n" -" path\n" -" Path to be examined; can be string, bytes, a path-like object or\n" -" open-file-descriptor int.\n" -" dir_fd\n" -" If not None, it should be a file descriptor open to a directory,\n" -" and path should be a relative string; path will then be relative to\n" -" that directory.\n" -" follow_symlinks\n" -" If False, and the last element of the path is a symbolic link,\n" -" stat will examine the symbolic link itself instead of the file\n" -" the link points to.\n" -"\n" -"dir_fd and follow_symlinks may not be implemented\n" -" on your platform. If they are unavailable, using them will raise a\n" -" NotImplementedError.\n" -"\n" -"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n" -" an open file descriptor."); - -#define OS_STAT_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(os_stat__doc__, +"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" +"--\n" +"\n" +"Perform a stat system call on the given path.\n" +"\n" +" path\n" +" Path to be examined; can be string, bytes, a path-like object or\n" +" open-file-descriptor int.\n" +" dir_fd\n" +" If not None, it should be a file descriptor open to a directory,\n" +" and path should be a relative string; path will then be relative to\n" +" that directory.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" stat will examine the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"dir_fd and follow_symlinks may not be implemented\n" +" on your platform. If they are unavailable, using them will raise a\n" +" NotImplementedError.\n" +"\n" +"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n" +" an open file descriptor."); + +#define OS_STAT_METHODDEF \ {"stat", (PyCFunction)(void(*)(void))os_stat, METH_FASTCALL|METH_KEYWORDS, os_stat__doc__}, - -static PyObject * -os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks); - -static PyObject * -os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; + +static PyObject * +os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks); + +static PyObject * +os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "stat", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); - int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; - + path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); + int dir_fd = DEFAULT_DIR_FD; + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -68,45 +68,45 @@ os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn goto exit; } skip_optional_kwonly: - return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -PyDoc_STRVAR(os_lstat__doc__, -"lstat($module, /, path, *, dir_fd=None)\n" -"--\n" -"\n" -"Perform a stat system call on the given path, without following symbolic links.\n" -"\n" -"Like stat(), but do not follow symbolic links.\n" -"Equivalent to stat(path, follow_symlinks=False)."); - -#define OS_LSTAT_METHODDEF \ + return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +PyDoc_STRVAR(os_lstat__doc__, +"lstat($module, /, path, *, dir_fd=None)\n" +"--\n" +"\n" +"Perform a stat system call on the given path, without following symbolic links.\n" +"\n" +"Like stat(), but do not follow symbolic links.\n" +"Equivalent to stat(path, follow_symlinks=False)."); + +#define OS_LSTAT_METHODDEF \ {"lstat", (PyCFunction)(void(*)(void))os_lstat, METH_FASTCALL|METH_KEYWORDS, os_lstat__doc__}, - -static PyObject * -os_lstat_impl(PyObject *module, path_t *path, int dir_fd); - -static PyObject * -os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "dir_fd", NULL}; + +static PyObject * +os_lstat_impl(PyObject *module, path_t *path, int dir_fd); + +static PyObject * +os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "lstat", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); - int dir_fd = DEFAULT_DIR_FD; - + path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -117,73 +117,73 @@ os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw goto exit; } skip_optional_kwonly: - return_value = os_lstat_impl(module, &path, dir_fd); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -PyDoc_STRVAR(os_access__doc__, -"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n" -" follow_symlinks=True)\n" -"--\n" -"\n" -"Use the real uid/gid to test for access to a path.\n" -"\n" -" path\n" -" Path to be tested; can be string, bytes, or a path-like object.\n" -" mode\n" -" Operating-system mode bitfield. Can be F_OK to test existence,\n" -" or the inclusive-OR of R_OK, W_OK, and X_OK.\n" -" dir_fd\n" -" If not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that\n" -" directory.\n" -" effective_ids\n" -" If True, access will use the effective uid/gid instead of\n" -" the real uid/gid.\n" -" follow_symlinks\n" -" If False, and the last element of the path is a symbolic link,\n" -" access will examine the symbolic link itself instead of the file\n" -" the link points to.\n" -"\n" -"dir_fd, effective_ids, and follow_symlinks may not be implemented\n" -" on your platform. If they are unavailable, using them will raise a\n" -" NotImplementedError.\n" -"\n" -"Note that most operations will use the effective uid/gid, therefore this\n" -" routine can be used in a suid/sgid environment to test if the invoking user\n" -" has the specified access to the path."); - -#define OS_ACCESS_METHODDEF \ + return_value = os_lstat_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +PyDoc_STRVAR(os_access__doc__, +"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n" +" follow_symlinks=True)\n" +"--\n" +"\n" +"Use the real uid/gid to test for access to a path.\n" +"\n" +" path\n" +" Path to be tested; can be string, bytes, or a path-like object.\n" +" mode\n" +" Operating-system mode bitfield. Can be F_OK to test existence,\n" +" or the inclusive-OR of R_OK, W_OK, and X_OK.\n" +" dir_fd\n" +" If not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that\n" +" directory.\n" +" effective_ids\n" +" If True, access will use the effective uid/gid instead of\n" +" the real uid/gid.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" access will examine the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"dir_fd, effective_ids, and follow_symlinks may not be implemented\n" +" on your platform. If they are unavailable, using them will raise a\n" +" NotImplementedError.\n" +"\n" +"Note that most operations will use the effective uid/gid, therefore this\n" +" routine can be used in a suid/sgid environment to test if the invoking user\n" +" has the specified access to the path."); + +#define OS_ACCESS_METHODDEF \ {"access", (PyCFunction)(void(*)(void))os_access, METH_FASTCALL|METH_KEYWORDS, os_access__doc__}, - -static int -os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd, - int effective_ids, int follow_symlinks); - -static PyObject * -os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; + +static int +os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd, + int effective_ids, int follow_symlinks); + +static PyObject * +os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "access", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("access", "path", 0, 0); - int mode; - int dir_fd = DEFAULT_DIR_FD; - int effective_ids = 0; - int follow_symlinks = 1; - int _return_value; - + path_t path = PATH_T_INITIALIZE("access", "path", 0, 0); + int mode; + int dir_fd = DEFAULT_DIR_FD; + int effective_ids = 0; + int follow_symlinks = 1; + int _return_value; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -221,213 +221,213 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k goto exit; } skip_optional_kwonly: - _return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#if defined(HAVE_TTYNAME) - -PyDoc_STRVAR(os_ttyname__doc__, -"ttyname($module, fd, /)\n" -"--\n" -"\n" -"Return the name of the terminal device connected to \'fd\'.\n" -"\n" -" fd\n" -" Integer file descriptor handle."); - -#define OS_TTYNAME_METHODDEF \ - {"ttyname", (PyCFunction)os_ttyname, METH_O, os_ttyname__doc__}, - -static PyObject * -os_ttyname_impl(PyObject *module, int fd); - -static PyObject * -os_ttyname(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int fd; - + _return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#if defined(HAVE_TTYNAME) + +PyDoc_STRVAR(os_ttyname__doc__, +"ttyname($module, fd, /)\n" +"--\n" +"\n" +"Return the name of the terminal device connected to \'fd\'.\n" +"\n" +" fd\n" +" Integer file descriptor handle."); + +#define OS_TTYNAME_METHODDEF \ + {"ttyname", (PyCFunction)os_ttyname, METH_O, os_ttyname__doc__}, + +static PyObject * +os_ttyname_impl(PyObject *module, int fd); + +static PyObject * +os_ttyname(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { - goto exit; - } + goto exit; + } return_value = os_ttyname_impl(module, fd); - -exit: - return return_value; -} - -#endif /* defined(HAVE_TTYNAME) */ - -#if defined(HAVE_CTERMID) - -PyDoc_STRVAR(os_ctermid__doc__, -"ctermid($module, /)\n" -"--\n" -"\n" -"Return the name of the controlling terminal for this process."); - -#define OS_CTERMID_METHODDEF \ - {"ctermid", (PyCFunction)os_ctermid, METH_NOARGS, os_ctermid__doc__}, - -static PyObject * -os_ctermid_impl(PyObject *module); - -static PyObject * -os_ctermid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_ctermid_impl(module); -} - -#endif /* defined(HAVE_CTERMID) */ - -PyDoc_STRVAR(os_chdir__doc__, -"chdir($module, /, path)\n" -"--\n" -"\n" -"Change the current working directory to the specified path.\n" -"\n" -"path may always be specified as a string.\n" -"On some platforms, path may also be specified as an open file descriptor.\n" -" If this functionality is unavailable, using it raises an exception."); - -#define OS_CHDIR_METHODDEF \ + +exit: + return return_value; +} + +#endif /* defined(HAVE_TTYNAME) */ + +#if defined(HAVE_CTERMID) + +PyDoc_STRVAR(os_ctermid__doc__, +"ctermid($module, /)\n" +"--\n" +"\n" +"Return the name of the controlling terminal for this process."); + +#define OS_CTERMID_METHODDEF \ + {"ctermid", (PyCFunction)os_ctermid, METH_NOARGS, os_ctermid__doc__}, + +static PyObject * +os_ctermid_impl(PyObject *module); + +static PyObject * +os_ctermid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_ctermid_impl(module); +} + +#endif /* defined(HAVE_CTERMID) */ + +PyDoc_STRVAR(os_chdir__doc__, +"chdir($module, /, path)\n" +"--\n" +"\n" +"Change the current working directory to the specified path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_CHDIR_METHODDEF \ {"chdir", (PyCFunction)(void(*)(void))os_chdir, METH_FASTCALL|METH_KEYWORDS, os_chdir__doc__}, - -static PyObject * -os_chdir_impl(PyObject *module, path_t *path); - -static PyObject * -os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; + +static PyObject * +os_chdir_impl(PyObject *module, path_t *path); + +static PyObject * +os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "chdir", 0}; PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); - + path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } - return_value = os_chdir_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#if defined(HAVE_FCHDIR) - -PyDoc_STRVAR(os_fchdir__doc__, -"fchdir($module, /, fd)\n" -"--\n" -"\n" -"Change to the directory of the given file descriptor.\n" -"\n" -"fd must be opened on a directory, not a file.\n" -"Equivalent to os.chdir(fd)."); - -#define OS_FCHDIR_METHODDEF \ + return_value = os_chdir_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#if defined(HAVE_FCHDIR) + +PyDoc_STRVAR(os_fchdir__doc__, +"fchdir($module, /, fd)\n" +"--\n" +"\n" +"Change to the directory of the given file descriptor.\n" +"\n" +"fd must be opened on a directory, not a file.\n" +"Equivalent to os.chdir(fd)."); + +#define OS_FCHDIR_METHODDEF \ {"fchdir", (PyCFunction)(void(*)(void))os_fchdir, METH_FASTCALL|METH_KEYWORDS, os_fchdir__doc__}, - -static PyObject * -os_fchdir_impl(PyObject *module, int fd); - -static PyObject * -os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", NULL}; + +static PyObject * +os_fchdir_impl(PyObject *module, int fd); + +static PyObject * +os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "fchdir", 0}; PyObject *argsbuf[1]; - int fd; - + int fd; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!fildes_converter(args[0], &fd)) { goto exit; } - return_value = os_fchdir_impl(module, fd); - -exit: - return return_value; -} - -#endif /* defined(HAVE_FCHDIR) */ - -PyDoc_STRVAR(os_chmod__doc__, -"chmod($module, /, path, mode, *, dir_fd=None, follow_symlinks=True)\n" -"--\n" -"\n" -"Change the access permissions of a file.\n" -"\n" -" path\n" -" Path to be modified. May always be specified as a str, bytes, or a path-like object.\n" -" On some platforms, path may also be specified as an open file descriptor.\n" -" If this functionality is unavailable, using it raises an exception.\n" -" mode\n" -" Operating-system mode bitfield.\n" -" dir_fd\n" -" If not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that\n" -" directory.\n" -" follow_symlinks\n" -" If False, and the last element of the path is a symbolic link,\n" -" chmod will modify the symbolic link itself instead of the file\n" -" the link points to.\n" -"\n" -"It is an error to use dir_fd or follow_symlinks when specifying path as\n" -" an open file descriptor.\n" -"dir_fd and follow_symlinks may not be implemented on your platform.\n" -" If they are unavailable, using them will raise a NotImplementedError."); - -#define OS_CHMOD_METHODDEF \ + return_value = os_fchdir_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_FCHDIR) */ + +PyDoc_STRVAR(os_chmod__doc__, +"chmod($module, /, path, mode, *, dir_fd=None, follow_symlinks=True)\n" +"--\n" +"\n" +"Change the access permissions of a file.\n" +"\n" +" path\n" +" Path to be modified. May always be specified as a str, bytes, or a path-like object.\n" +" On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +" mode\n" +" Operating-system mode bitfield.\n" +" dir_fd\n" +" If not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that\n" +" directory.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" chmod will modify the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"It is an error to use dir_fd or follow_symlinks when specifying path as\n" +" an open file descriptor.\n" +"dir_fd and follow_symlinks may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_CHMOD_METHODDEF \ {"chmod", (PyCFunction)(void(*)(void))os_chmod, METH_FASTCALL|METH_KEYWORDS, os_chmod__doc__}, - -static PyObject * -os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, - int follow_symlinks); - -static PyObject * -os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; + +static PyObject * +os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, + int follow_symlinks); + +static PyObject * +os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "chmod", 0}; PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); - int mode; - int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; - + path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); + int mode; + int dir_fd = DEFAULT_DIR_FD; + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -456,45 +456,45 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw goto exit; } skip_optional_kwonly: - return_value = os_chmod_impl(module, &path, mode, dir_fd, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#if defined(HAVE_FCHMOD) - -PyDoc_STRVAR(os_fchmod__doc__, -"fchmod($module, /, fd, mode)\n" -"--\n" -"\n" -"Change the access permissions of the file given by file descriptor fd.\n" -"\n" -"Equivalent to os.chmod(fd, mode)."); - -#define OS_FCHMOD_METHODDEF \ + return_value = os_chmod_impl(module, &path, mode, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#if defined(HAVE_FCHMOD) + +PyDoc_STRVAR(os_fchmod__doc__, +"fchmod($module, /, fd, mode)\n" +"--\n" +"\n" +"Change the access permissions of the file given by file descriptor fd.\n" +"\n" +"Equivalent to os.chmod(fd, mode)."); + +#define OS_FCHMOD_METHODDEF \ {"fchmod", (PyCFunction)(void(*)(void))os_fchmod, METH_FASTCALL|METH_KEYWORDS, os_fchmod__doc__}, - -static PyObject * -os_fchmod_impl(PyObject *module, int fd, int mode); - -static PyObject * -os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", "mode", NULL}; + +static PyObject * +os_fchmod_impl(PyObject *module, int fd, int mode); + +static PyObject * +os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", "mode", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "fchmod", 0}; PyObject *argsbuf[2]; - int fd; - int mode; - + int fd; + int mode; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -513,45 +513,45 @@ os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (mode == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_fchmod_impl(module, fd, mode); - -exit: - return return_value; -} - -#endif /* defined(HAVE_FCHMOD) */ - -#if defined(HAVE_LCHMOD) - -PyDoc_STRVAR(os_lchmod__doc__, -"lchmod($module, /, path, mode)\n" -"--\n" -"\n" -"Change the access permissions of a file, without following symbolic links.\n" -"\n" -"If path is a symlink, this affects the link itself rather than the target.\n" -"Equivalent to chmod(path, mode, follow_symlinks=False).\""); - -#define OS_LCHMOD_METHODDEF \ + return_value = os_fchmod_impl(module, fd, mode); + +exit: + return return_value; +} + +#endif /* defined(HAVE_FCHMOD) */ + +#if defined(HAVE_LCHMOD) + +PyDoc_STRVAR(os_lchmod__doc__, +"lchmod($module, /, path, mode)\n" +"--\n" +"\n" +"Change the access permissions of a file, without following symbolic links.\n" +"\n" +"If path is a symlink, this affects the link itself rather than the target.\n" +"Equivalent to chmod(path, mode, follow_symlinks=False).\""); + +#define OS_LCHMOD_METHODDEF \ {"lchmod", (PyCFunction)(void(*)(void))os_lchmod, METH_FASTCALL|METH_KEYWORDS, os_lchmod__doc__}, - -static PyObject * -os_lchmod_impl(PyObject *module, path_t *path, int mode); - -static PyObject * -os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "mode", NULL}; + +static PyObject * +os_lchmod_impl(PyObject *module, path_t *path, int mode); + +static PyObject * +os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "mode", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "lchmod", 0}; PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); - int mode; - + path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); + int mode; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -564,54 +564,54 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (mode == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_lchmod_impl(module, &path, mode); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_LCHMOD) */ - -#if defined(HAVE_CHFLAGS) - -PyDoc_STRVAR(os_chflags__doc__, -"chflags($module, /, path, flags, follow_symlinks=True)\n" -"--\n" -"\n" -"Set file flags.\n" -"\n" -"If follow_symlinks is False, and the last element of the path is a symbolic\n" -" link, chflags will change flags on the symbolic link itself instead of the\n" -" file the link points to.\n" -"follow_symlinks may not be implemented on your platform. If it is\n" -"unavailable, using it will raise a NotImplementedError."); - -#define OS_CHFLAGS_METHODDEF \ + return_value = os_lchmod_impl(module, &path, mode); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_LCHMOD) */ + +#if defined(HAVE_CHFLAGS) + +PyDoc_STRVAR(os_chflags__doc__, +"chflags($module, /, path, flags, follow_symlinks=True)\n" +"--\n" +"\n" +"Set file flags.\n" +"\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, chflags will change flags on the symbolic link itself instead of the\n" +" file the link points to.\n" +"follow_symlinks may not be implemented on your platform. If it is\n" +"unavailable, using it will raise a NotImplementedError."); + +#define OS_CHFLAGS_METHODDEF \ {"chflags", (PyCFunction)(void(*)(void))os_chflags, METH_FASTCALL|METH_KEYWORDS, os_chflags__doc__}, - -static PyObject * -os_chflags_impl(PyObject *module, path_t *path, unsigned long flags, - int follow_symlinks); - -static PyObject * -os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "flags", "follow_symlinks", NULL}; + +static PyObject * +os_chflags_impl(PyObject *module, path_t *path, unsigned long flags, + int follow_symlinks); + +static PyObject * +os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "flags", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "chflags", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); - unsigned long flags; - int follow_symlinks = 1; - + path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); + unsigned long flags; + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -628,48 +628,48 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * goto exit; } skip_optional_pos: - return_value = os_chflags_impl(module, &path, flags, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_CHFLAGS) */ - -#if defined(HAVE_LCHFLAGS) - -PyDoc_STRVAR(os_lchflags__doc__, -"lchflags($module, /, path, flags)\n" -"--\n" -"\n" -"Set file flags.\n" -"\n" -"This function will not follow symbolic links.\n" -"Equivalent to chflags(path, flags, follow_symlinks=False)."); - -#define OS_LCHFLAGS_METHODDEF \ + return_value = os_chflags_impl(module, &path, flags, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_CHFLAGS) */ + +#if defined(HAVE_LCHFLAGS) + +PyDoc_STRVAR(os_lchflags__doc__, +"lchflags($module, /, path, flags)\n" +"--\n" +"\n" +"Set file flags.\n" +"\n" +"This function will not follow symbolic links.\n" +"Equivalent to chflags(path, flags, follow_symlinks=False)."); + +#define OS_LCHFLAGS_METHODDEF \ {"lchflags", (PyCFunction)(void(*)(void))os_lchflags, METH_FASTCALL|METH_KEYWORDS, os_lchflags__doc__}, - -static PyObject * -os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags); - -static PyObject * -os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "flags", NULL}; + +static PyObject * +os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags); + +static PyObject * +os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "flags", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "lchflags", 0}; PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); - unsigned long flags; - + path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); + unsigned long flags; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -678,213 +678,213 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } flags = PyLong_AsUnsignedLongMask(args[1]); - return_value = os_lchflags_impl(module, &path, flags); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_LCHFLAGS) */ - -#if defined(HAVE_CHROOT) - -PyDoc_STRVAR(os_chroot__doc__, -"chroot($module, /, path)\n" -"--\n" -"\n" -"Change root directory to path."); - -#define OS_CHROOT_METHODDEF \ + return_value = os_lchflags_impl(module, &path, flags); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_LCHFLAGS) */ + +#if defined(HAVE_CHROOT) + +PyDoc_STRVAR(os_chroot__doc__, +"chroot($module, /, path)\n" +"--\n" +"\n" +"Change root directory to path."); + +#define OS_CHROOT_METHODDEF \ {"chroot", (PyCFunction)(void(*)(void))os_chroot, METH_FASTCALL|METH_KEYWORDS, os_chroot__doc__}, - -static PyObject * -os_chroot_impl(PyObject *module, path_t *path); - -static PyObject * -os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; + +static PyObject * +os_chroot_impl(PyObject *module, path_t *path); + +static PyObject * +os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "chroot", 0}; PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); - + path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } - return_value = os_chroot_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_CHROOT) */ - -#if defined(HAVE_FSYNC) - -PyDoc_STRVAR(os_fsync__doc__, -"fsync($module, /, fd)\n" -"--\n" -"\n" -"Force write of fd to disk."); - -#define OS_FSYNC_METHODDEF \ + return_value = os_chroot_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_CHROOT) */ + +#if defined(HAVE_FSYNC) + +PyDoc_STRVAR(os_fsync__doc__, +"fsync($module, /, fd)\n" +"--\n" +"\n" +"Force write of fd to disk."); + +#define OS_FSYNC_METHODDEF \ {"fsync", (PyCFunction)(void(*)(void))os_fsync, METH_FASTCALL|METH_KEYWORDS, os_fsync__doc__}, - -static PyObject * -os_fsync_impl(PyObject *module, int fd); - -static PyObject * -os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", NULL}; + +static PyObject * +os_fsync_impl(PyObject *module, int fd); + +static PyObject * +os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "fsync", 0}; PyObject *argsbuf[1]; - int fd; - + int fd; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!fildes_converter(args[0], &fd)) { goto exit; } - return_value = os_fsync_impl(module, fd); - -exit: - return return_value; -} - -#endif /* defined(HAVE_FSYNC) */ - -#if defined(HAVE_SYNC) - -PyDoc_STRVAR(os_sync__doc__, -"sync($module, /)\n" -"--\n" -"\n" -"Force write of everything to disk."); - -#define OS_SYNC_METHODDEF \ - {"sync", (PyCFunction)os_sync, METH_NOARGS, os_sync__doc__}, - -static PyObject * -os_sync_impl(PyObject *module); - -static PyObject * -os_sync(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_sync_impl(module); -} - -#endif /* defined(HAVE_SYNC) */ - -#if defined(HAVE_FDATASYNC) - -PyDoc_STRVAR(os_fdatasync__doc__, -"fdatasync($module, /, fd)\n" -"--\n" -"\n" -"Force write of fd to disk without forcing update of metadata."); - -#define OS_FDATASYNC_METHODDEF \ + return_value = os_fsync_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_FSYNC) */ + +#if defined(HAVE_SYNC) + +PyDoc_STRVAR(os_sync__doc__, +"sync($module, /)\n" +"--\n" +"\n" +"Force write of everything to disk."); + +#define OS_SYNC_METHODDEF \ + {"sync", (PyCFunction)os_sync, METH_NOARGS, os_sync__doc__}, + +static PyObject * +os_sync_impl(PyObject *module); + +static PyObject * +os_sync(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_sync_impl(module); +} + +#endif /* defined(HAVE_SYNC) */ + +#if defined(HAVE_FDATASYNC) + +PyDoc_STRVAR(os_fdatasync__doc__, +"fdatasync($module, /, fd)\n" +"--\n" +"\n" +"Force write of fd to disk without forcing update of metadata."); + +#define OS_FDATASYNC_METHODDEF \ {"fdatasync", (PyCFunction)(void(*)(void))os_fdatasync, METH_FASTCALL|METH_KEYWORDS, os_fdatasync__doc__}, - -static PyObject * -os_fdatasync_impl(PyObject *module, int fd); - -static PyObject * -os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", NULL}; + +static PyObject * +os_fdatasync_impl(PyObject *module, int fd); + +static PyObject * +os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "fdatasync", 0}; PyObject *argsbuf[1]; - int fd; - + int fd; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!fildes_converter(args[0], &fd)) { goto exit; } - return_value = os_fdatasync_impl(module, fd); - -exit: - return return_value; -} - -#endif /* defined(HAVE_FDATASYNC) */ - -#if defined(HAVE_CHOWN) - -PyDoc_STRVAR(os_chown__doc__, -"chown($module, /, path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n" -"--\n" -"\n" -"Change the owner and group id of path to the numeric uid and gid.\\\n" -"\n" -" path\n" -" Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.\n" -" dir_fd\n" -" If not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that\n" -" directory.\n" -" follow_symlinks\n" -" If False, and the last element of the path is a symbolic link,\n" -" stat will examine the symbolic link itself instead of the file\n" -" the link points to.\n" -"\n" -"path may always be specified as a string.\n" -"On some platforms, path may also be specified as an open file descriptor.\n" -" If this functionality is unavailable, using it raises an exception.\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"If follow_symlinks is False, and the last element of the path is a symbolic\n" -" link, chown will modify the symbolic link itself instead of the file the\n" -" link points to.\n" -"It is an error to use dir_fd or follow_symlinks when specifying path as\n" -" an open file descriptor.\n" -"dir_fd and follow_symlinks may not be implemented on your platform.\n" -" If they are unavailable, using them will raise a NotImplementedError."); - -#define OS_CHOWN_METHODDEF \ + return_value = os_fdatasync_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_FDATASYNC) */ + +#if defined(HAVE_CHOWN) + +PyDoc_STRVAR(os_chown__doc__, +"chown($module, /, path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n" +"--\n" +"\n" +"Change the owner and group id of path to the numeric uid and gid.\\\n" +"\n" +" path\n" +" Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.\n" +" dir_fd\n" +" If not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that\n" +" directory.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" stat will examine the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, chown will modify the symbolic link itself instead of the file the\n" +" link points to.\n" +"It is an error to use dir_fd or follow_symlinks when specifying path as\n" +" an open file descriptor.\n" +"dir_fd and follow_symlinks may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_CHOWN_METHODDEF \ {"chown", (PyCFunction)(void(*)(void))os_chown, METH_FASTCALL|METH_KEYWORDS, os_chown__doc__}, - -static PyObject * -os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, - int dir_fd, int follow_symlinks); - -static PyObject * -os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; + +static PyObject * +os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, + int dir_fd, int follow_symlinks); + +static PyObject * +os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "chown", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); - uid_t uid; - gid_t gid; - int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; - + path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); + uid_t uid; + gid_t gid; + int dir_fd = DEFAULT_DIR_FD; + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -910,48 +910,48 @@ os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw goto exit; } skip_optional_kwonly: - return_value = os_chown_impl(module, &path, uid, gid, dir_fd, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_CHOWN) */ - -#if defined(HAVE_FCHOWN) - -PyDoc_STRVAR(os_fchown__doc__, -"fchown($module, /, fd, uid, gid)\n" -"--\n" -"\n" -"Change the owner and group id of the file specified by file descriptor.\n" -"\n" -"Equivalent to os.chown(fd, uid, gid)."); - -#define OS_FCHOWN_METHODDEF \ + return_value = os_chown_impl(module, &path, uid, gid, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_CHOWN) */ + +#if defined(HAVE_FCHOWN) + +PyDoc_STRVAR(os_fchown__doc__, +"fchown($module, /, fd, uid, gid)\n" +"--\n" +"\n" +"Change the owner and group id of the file specified by file descriptor.\n" +"\n" +"Equivalent to os.chown(fd, uid, gid)."); + +#define OS_FCHOWN_METHODDEF \ {"fchown", (PyCFunction)(void(*)(void))os_fchown, METH_FASTCALL|METH_KEYWORDS, os_fchown__doc__}, - -static PyObject * -os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid); - -static PyObject * -os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", "uid", "gid", NULL}; + +static PyObject * +os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid); + +static PyObject * +os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", "uid", "gid", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "fchown", 0}; PyObject *argsbuf[3]; - int fd; - uid_t uid; - gid_t gid; - + int fd; + uid_t uid; + gid_t gid; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -967,46 +967,46 @@ os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!_Py_Gid_Converter(args[2], &gid)) { goto exit; } - return_value = os_fchown_impl(module, fd, uid, gid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_FCHOWN) */ - -#if defined(HAVE_LCHOWN) - -PyDoc_STRVAR(os_lchown__doc__, -"lchown($module, /, path, uid, gid)\n" -"--\n" -"\n" -"Change the owner and group id of path to the numeric uid and gid.\n" -"\n" -"This function will not follow symbolic links.\n" -"Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); - -#define OS_LCHOWN_METHODDEF \ + return_value = os_fchown_impl(module, fd, uid, gid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_FCHOWN) */ + +#if defined(HAVE_LCHOWN) + +PyDoc_STRVAR(os_lchown__doc__, +"lchown($module, /, path, uid, gid)\n" +"--\n" +"\n" +"Change the owner and group id of path to the numeric uid and gid.\n" +"\n" +"This function will not follow symbolic links.\n" +"Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); + +#define OS_LCHOWN_METHODDEF \ {"lchown", (PyCFunction)(void(*)(void))os_lchown, METH_FASTCALL|METH_KEYWORDS, os_lchown__doc__}, - -static PyObject * -os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid); - -static PyObject * -os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "uid", "gid", NULL}; + +static PyObject * +os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid); + +static PyObject * +os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "uid", "gid", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "lchown", 0}; PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); - uid_t uid; - gid_t gid; - + path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); + uid_t uid; + gid_t gid; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -1016,97 +1016,97 @@ os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k if (!_Py_Gid_Converter(args[2], &gid)) { goto exit; } - return_value = os_lchown_impl(module, &path, uid, gid); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_LCHOWN) */ - -PyDoc_STRVAR(os_getcwd__doc__, -"getcwd($module, /)\n" -"--\n" -"\n" -"Return a unicode string representing the current working directory."); - -#define OS_GETCWD_METHODDEF \ - {"getcwd", (PyCFunction)os_getcwd, METH_NOARGS, os_getcwd__doc__}, - -static PyObject * -os_getcwd_impl(PyObject *module); - -static PyObject * -os_getcwd(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getcwd_impl(module); -} - -PyDoc_STRVAR(os_getcwdb__doc__, -"getcwdb($module, /)\n" -"--\n" -"\n" -"Return a bytes string representing the current working directory."); - -#define OS_GETCWDB_METHODDEF \ - {"getcwdb", (PyCFunction)os_getcwdb, METH_NOARGS, os_getcwdb__doc__}, - -static PyObject * -os_getcwdb_impl(PyObject *module); - -static PyObject * -os_getcwdb(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getcwdb_impl(module); -} - -#if defined(HAVE_LINK) - -PyDoc_STRVAR(os_link__doc__, -"link($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None,\n" -" follow_symlinks=True)\n" -"--\n" -"\n" -"Create a hard link to a file.\n" -"\n" -"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" -" descriptor open to a directory, and the respective path string (src or dst)\n" -" should be relative; the path will then be relative to that directory.\n" -"If follow_symlinks is False, and the last element of src is a symbolic\n" -" link, link will create a link to the symbolic link itself instead of the\n" -" file the link points to.\n" -"src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n" -" platform. If they are unavailable, using them will raise a\n" -" NotImplementedError."); - -#define OS_LINK_METHODDEF \ + return_value = os_lchown_impl(module, &path, uid, gid); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_LCHOWN) */ + +PyDoc_STRVAR(os_getcwd__doc__, +"getcwd($module, /)\n" +"--\n" +"\n" +"Return a unicode string representing the current working directory."); + +#define OS_GETCWD_METHODDEF \ + {"getcwd", (PyCFunction)os_getcwd, METH_NOARGS, os_getcwd__doc__}, + +static PyObject * +os_getcwd_impl(PyObject *module); + +static PyObject * +os_getcwd(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getcwd_impl(module); +} + +PyDoc_STRVAR(os_getcwdb__doc__, +"getcwdb($module, /)\n" +"--\n" +"\n" +"Return a bytes string representing the current working directory."); + +#define OS_GETCWDB_METHODDEF \ + {"getcwdb", (PyCFunction)os_getcwdb, METH_NOARGS, os_getcwdb__doc__}, + +static PyObject * +os_getcwdb_impl(PyObject *module); + +static PyObject * +os_getcwdb(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getcwdb_impl(module); +} + +#if defined(HAVE_LINK) + +PyDoc_STRVAR(os_link__doc__, +"link($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None,\n" +" follow_symlinks=True)\n" +"--\n" +"\n" +"Create a hard link to a file.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of src is a symbolic\n" +" link, link will create a link to the symbolic link itself instead of the\n" +" file the link points to.\n" +"src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n" +" platform. If they are unavailable, using them will raise a\n" +" NotImplementedError."); + +#define OS_LINK_METHODDEF \ {"link", (PyCFunction)(void(*)(void))os_link, METH_FASTCALL|METH_KEYWORDS, os_link__doc__}, - -static PyObject * -os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, - int dst_dir_fd, int follow_symlinks); - -static PyObject * -os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; + +static PyObject * +os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd, int follow_symlinks); + +static PyObject * +os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "link", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); - path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0); - int src_dir_fd = DEFAULT_DIR_FD; - int dst_dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; - + path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0); + int src_dir_fd = DEFAULT_DIR_FD; + int dst_dir_fd = DEFAULT_DIR_FD; + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &src)) { goto exit; } @@ -1137,56 +1137,56 @@ os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn goto exit; } skip_optional_kwonly: - return_value = os_link_impl(module, &src, &dst, src_dir_fd, dst_dir_fd, follow_symlinks); - -exit: - /* Cleanup for src */ - path_cleanup(&src); - /* Cleanup for dst */ - path_cleanup(&dst); - - return return_value; -} - -#endif /* defined(HAVE_LINK) */ - -PyDoc_STRVAR(os_listdir__doc__, -"listdir($module, /, path=None)\n" -"--\n" -"\n" -"Return a list containing the names of the files in the directory.\n" -"\n" -"path can be specified as either str, bytes, or a path-like object. If path is bytes,\n" -" the filenames returned will also be bytes; in all other circumstances\n" -" the filenames returned will be str.\n" -"If path is None, uses the path=\'.\'.\n" -"On some platforms, path may also be specified as an open file descriptor;\\\n" -" the file descriptor must refer to a directory.\n" -" If this functionality is unavailable, using it raises NotImplementedError.\n" -"\n" -"The list is in arbitrary order. It does not include the special\n" -"entries \'.\' and \'..\' even if they are present in the directory."); - -#define OS_LISTDIR_METHODDEF \ + return_value = os_link_impl(module, &src, &dst, src_dir_fd, dst_dir_fd, follow_symlinks); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +#endif /* defined(HAVE_LINK) */ + +PyDoc_STRVAR(os_listdir__doc__, +"listdir($module, /, path=None)\n" +"--\n" +"\n" +"Return a list containing the names of the files in the directory.\n" +"\n" +"path can be specified as either str, bytes, or a path-like object. If path is bytes,\n" +" the filenames returned will also be bytes; in all other circumstances\n" +" the filenames returned will be str.\n" +"If path is None, uses the path=\'.\'.\n" +"On some platforms, path may also be specified as an open file descriptor;\\\n" +" the file descriptor must refer to a directory.\n" +" If this functionality is unavailable, using it raises NotImplementedError.\n" +"\n" +"The list is in arbitrary order. It does not include the special\n" +"entries \'.\' and \'..\' even if they are present in the directory."); + +#define OS_LISTDIR_METHODDEF \ {"listdir", (PyCFunction)(void(*)(void))os_listdir, METH_FASTCALL|METH_KEYWORDS, os_listdir__doc__}, - -static PyObject * -os_listdir_impl(PyObject *module, path_t *path); - -static PyObject * -os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; + +static PyObject * +os_listdir_impl(PyObject *module, path_t *path); + +static PyObject * +os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "listdir", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); - + path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -1194,38 +1194,154 @@ os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * goto exit; } skip_optional_pos: - return_value = os_listdir_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - + return_value = os_listdir_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__getfullpathname__doc__, +"_getfullpathname($module, path, /)\n" +"--\n" +"\n"); + +#define OS__GETFULLPATHNAME_METHODDEF \ + {"_getfullpathname", (PyCFunction)os__getfullpathname, METH_O, os__getfullpathname__doc__}, + +static PyObject * +os__getfullpathname_impl(PyObject *module, path_t *path); + +static PyObject * +os__getfullpathname(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0); + + if (!path_converter(arg, &path)) { + goto exit; + } + return_value = os__getfullpathname_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__getfinalpathname__doc__, +"_getfinalpathname($module, path, /)\n" +"--\n" +"\n" +"A helper function for samepath on windows."); + +#define OS__GETFINALPATHNAME_METHODDEF \ + {"_getfinalpathname", (PyCFunction)os__getfinalpathname, METH_O, os__getfinalpathname__doc__}, + +static PyObject * +os__getfinalpathname_impl(PyObject *module, path_t *path); + +static PyObject * +os__getfinalpathname(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + path_t path = PATH_T_INITIALIZE("_getfinalpathname", "path", 0, 0); + + if (!path_converter(arg, &path)) { + goto exit; + } + return_value = os__getfinalpathname_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__getvolumepathname__doc__, +"_getvolumepathname($module, /, path)\n" +"--\n" +"\n" +"A helper function for ismount on Win32."); + +#define OS__GETVOLUMEPATHNAME_METHODDEF \ + {"_getvolumepathname", (PyCFunction)(void(*)(void))os__getvolumepathname, METH_FASTCALL|METH_KEYWORDS, os__getvolumepathname__doc__}, + +static PyObject * +os__getvolumepathname_impl(PyObject *module, path_t *path); + +static PyObject * +os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "_getvolumepathname", 0}; + PyObject *argsbuf[1]; + path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0); + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__getvolumepathname_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + #if defined(MS_WINDOWS) -PyDoc_STRVAR(os__getfullpathname__doc__, -"_getfullpathname($module, path, /)\n" +PyDoc_STRVAR(os__path_splitroot__doc__, +"_path_splitroot($module, /, path)\n" "--\n" -"\n"); +"\n" +"Removes everything after the root on Win32."); -#define OS__GETFULLPATHNAME_METHODDEF \ - {"_getfullpathname", (PyCFunction)os__getfullpathname, METH_O, os__getfullpathname__doc__}, +#define OS__PATH_SPLITROOT_METHODDEF \ + {"_path_splitroot", (PyCFunction)(void(*)(void))os__path_splitroot, METH_FASTCALL|METH_KEYWORDS, os__path_splitroot__doc__}, static PyObject * -os__getfullpathname_impl(PyObject *module, path_t *path); +os__path_splitroot_impl(PyObject *module, path_t *path); static PyObject * -os__getfullpathname(PyObject *module, PyObject *arg) +os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0); + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "_path_splitroot", 0}; + PyObject *argsbuf[1]; + path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0); - if (!path_converter(arg, &path)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } - return_value = os__getfullpathname_impl(module, &path); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_splitroot_impl(module, &path); exit: /* Cleanup for path */ @@ -1236,157 +1352,41 @@ exit: #endif /* defined(MS_WINDOWS) */ -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(os__getfinalpathname__doc__, -"_getfinalpathname($module, path, /)\n" -"--\n" -"\n" -"A helper function for samepath on windows."); - -#define OS__GETFINALPATHNAME_METHODDEF \ - {"_getfinalpathname", (PyCFunction)os__getfinalpathname, METH_O, os__getfinalpathname__doc__}, - -static PyObject * -os__getfinalpathname_impl(PyObject *module, path_t *path); - -static PyObject * -os__getfinalpathname(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_getfinalpathname", "path", 0, 0); - - if (!path_converter(arg, &path)) { - goto exit; - } - return_value = os__getfinalpathname_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(os__getvolumepathname__doc__, -"_getvolumepathname($module, /, path)\n" -"--\n" -"\n" -"A helper function for ismount on Win32."); - -#define OS__GETVOLUMEPATHNAME_METHODDEF \ - {"_getvolumepathname", (PyCFunction)(void(*)(void))os__getvolumepathname, METH_FASTCALL|METH_KEYWORDS, os__getvolumepathname__doc__}, - -static PyObject * -os__getvolumepathname_impl(PyObject *module, path_t *path); - -static PyObject * -os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_getvolumepathname", 0}; - PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0); - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!path_converter(args[0], &path)) { - goto exit; - } - return_value = os__getvolumepathname_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(os__path_splitroot__doc__, -"_path_splitroot($module, /, path)\n" -"--\n" -"\n" -"Removes everything after the root on Win32."); - -#define OS__PATH_SPLITROOT_METHODDEF \ - {"_path_splitroot", (PyCFunction)(void(*)(void))os__path_splitroot, METH_FASTCALL|METH_KEYWORDS, os__path_splitroot__doc__}, - -static PyObject * -os__path_splitroot_impl(PyObject *module, path_t *path); - -static PyObject * -os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_path_splitroot", 0}; - PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0); - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!path_converter(args[0], &path)) { - goto exit; - } - return_value = os__path_splitroot_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -PyDoc_STRVAR(os_mkdir__doc__, -"mkdir($module, /, path, mode=511, *, dir_fd=None)\n" -"--\n" -"\n" -"Create a directory.\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"dir_fd may not be implemented on your platform.\n" -" If it is unavailable, using it will raise a NotImplementedError.\n" -"\n" -"The mode argument is ignored on Windows."); - -#define OS_MKDIR_METHODDEF \ +PyDoc_STRVAR(os_mkdir__doc__, +"mkdir($module, /, path, mode=511, *, dir_fd=None)\n" +"--\n" +"\n" +"Create a directory.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError.\n" +"\n" +"The mode argument is ignored on Windows."); + +#define OS_MKDIR_METHODDEF \ {"mkdir", (PyCFunction)(void(*)(void))os_mkdir, METH_FASTCALL|METH_KEYWORDS, os_mkdir__doc__}, - -static PyObject * -os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd); - -static PyObject * -os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; + +static PyObject * +os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd); + +static PyObject * +os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "mkdir", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); - int mode = 511; - int dir_fd = DEFAULT_DIR_FD; - + path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); + int mode = 511; + int dir_fd = DEFAULT_DIR_FD; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -1415,80 +1415,80 @@ skip_optional_pos: goto exit; } skip_optional_kwonly: - return_value = os_mkdir_impl(module, &path, mode, dir_fd); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#if defined(HAVE_NICE) - -PyDoc_STRVAR(os_nice__doc__, -"nice($module, increment, /)\n" -"--\n" -"\n" -"Add increment to the priority of process and return the new priority."); - -#define OS_NICE_METHODDEF \ - {"nice", (PyCFunction)os_nice, METH_O, os_nice__doc__}, - -static PyObject * -os_nice_impl(PyObject *module, int increment); - -static PyObject * -os_nice(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int increment; - + return_value = os_mkdir_impl(module, &path, mode, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#if defined(HAVE_NICE) + +PyDoc_STRVAR(os_nice__doc__, +"nice($module, increment, /)\n" +"--\n" +"\n" +"Add increment to the priority of process and return the new priority."); + +#define OS_NICE_METHODDEF \ + {"nice", (PyCFunction)os_nice, METH_O, os_nice__doc__}, + +static PyObject * +os_nice_impl(PyObject *module, int increment); + +static PyObject * +os_nice(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int increment; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } increment = _PyLong_AsInt(arg); if (increment == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_nice_impl(module, increment); - -exit: - return return_value; -} - -#endif /* defined(HAVE_NICE) */ - -#if defined(HAVE_GETPRIORITY) - -PyDoc_STRVAR(os_getpriority__doc__, -"getpriority($module, /, which, who)\n" -"--\n" -"\n" -"Return program scheduling priority."); - -#define OS_GETPRIORITY_METHODDEF \ + return_value = os_nice_impl(module, increment); + +exit: + return return_value; +} + +#endif /* defined(HAVE_NICE) */ + +#if defined(HAVE_GETPRIORITY) + +PyDoc_STRVAR(os_getpriority__doc__, +"getpriority($module, /, which, who)\n" +"--\n" +"\n" +"Return program scheduling priority."); + +#define OS_GETPRIORITY_METHODDEF \ {"getpriority", (PyCFunction)(void(*)(void))os_getpriority, METH_FASTCALL|METH_KEYWORDS, os_getpriority__doc__}, - -static PyObject * -os_getpriority_impl(PyObject *module, int which, int who); - -static PyObject * -os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"which", "who", NULL}; + +static PyObject * +os_getpriority_impl(PyObject *module, int which, int who); + +static PyObject * +os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"which", "who", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "getpriority", 0}; PyObject *argsbuf[2]; - int which; - int who; - + int which; + int who; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -1507,43 +1507,43 @@ os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (who == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_getpriority_impl(module, which, who); - -exit: - return return_value; -} - -#endif /* defined(HAVE_GETPRIORITY) */ - -#if defined(HAVE_SETPRIORITY) - -PyDoc_STRVAR(os_setpriority__doc__, -"setpriority($module, /, which, who, priority)\n" -"--\n" -"\n" -"Set program scheduling priority."); - -#define OS_SETPRIORITY_METHODDEF \ + return_value = os_getpriority_impl(module, which, who); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETPRIORITY) */ + +#if defined(HAVE_SETPRIORITY) + +PyDoc_STRVAR(os_setpriority__doc__, +"setpriority($module, /, which, who, priority)\n" +"--\n" +"\n" +"Set program scheduling priority."); + +#define OS_SETPRIORITY_METHODDEF \ {"setpriority", (PyCFunction)(void(*)(void))os_setpriority, METH_FASTCALL|METH_KEYWORDS, os_setpriority__doc__}, - -static PyObject * -os_setpriority_impl(PyObject *module, int which, int who, int priority); - -static PyObject * -os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"which", "who", "priority", NULL}; + +static PyObject * +os_setpriority_impl(PyObject *module, int which, int who, int priority); + +static PyObject * +os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"which", "who", "priority", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "setpriority", 0}; PyObject *argsbuf[3]; - int which; - int who; - int priority; - + int which; + int who; + int priority; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -1571,50 +1571,50 @@ os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje if (priority == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_setpriority_impl(module, which, who, priority); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETPRIORITY) */ - -PyDoc_STRVAR(os_rename__doc__, -"rename($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n" -"--\n" -"\n" -"Rename a file or directory.\n" -"\n" -"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" -" descriptor open to a directory, and the respective path string (src or dst)\n" -" should be relative; the path will then be relative to that directory.\n" -"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n" -" If they are unavailable, using them will raise a NotImplementedError."); - -#define OS_RENAME_METHODDEF \ + return_value = os_setpriority_impl(module, which, who, priority); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETPRIORITY) */ + +PyDoc_STRVAR(os_rename__doc__, +"rename($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n" +"--\n" +"\n" +"Rename a file or directory.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_RENAME_METHODDEF \ {"rename", (PyCFunction)(void(*)(void))os_rename, METH_FASTCALL|METH_KEYWORDS, os_rename__doc__}, - -static PyObject * -os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, - int dst_dir_fd); - -static PyObject * -os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + +static PyObject * +os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd); + +static PyObject * +os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "rename", 0}; PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); - path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0); - int src_dir_fd = DEFAULT_DIR_FD; - int dst_dir_fd = DEFAULT_DIR_FD; - + path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0); + int src_dir_fd = DEFAULT_DIR_FD; + int dst_dir_fd = DEFAULT_DIR_FD; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &src)) { goto exit; } @@ -1636,53 +1636,53 @@ os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k goto exit; } skip_optional_kwonly: - return_value = os_rename_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); - -exit: - /* Cleanup for src */ - path_cleanup(&src); - /* Cleanup for dst */ - path_cleanup(&dst); - - return return_value; -} - -PyDoc_STRVAR(os_replace__doc__, -"replace($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n" -"--\n" -"\n" -"Rename a file or directory, overwriting the destination.\n" -"\n" -"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" -" descriptor open to a directory, and the respective path string (src or dst)\n" -" should be relative; the path will then be relative to that directory.\n" -"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n" -" If they are unavailable, using them will raise a NotImplementedError."); - -#define OS_REPLACE_METHODDEF \ + return_value = os_rename_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +PyDoc_STRVAR(os_replace__doc__, +"replace($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n" +"--\n" +"\n" +"Rename a file or directory, overwriting the destination.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_REPLACE_METHODDEF \ {"replace", (PyCFunction)(void(*)(void))os_replace, METH_FASTCALL|METH_KEYWORDS, os_replace__doc__}, - -static PyObject * -os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, - int dst_dir_fd); - -static PyObject * -os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + +static PyObject * +os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd); + +static PyObject * +os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0); - path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0); - int src_dir_fd = DEFAULT_DIR_FD; - int dst_dir_fd = DEFAULT_DIR_FD; - + path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0); + int src_dir_fd = DEFAULT_DIR_FD; + int dst_dir_fd = DEFAULT_DIR_FD; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &src)) { goto exit; } @@ -1704,49 +1704,49 @@ os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * goto exit; } skip_optional_kwonly: - return_value = os_replace_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); - -exit: - /* Cleanup for src */ - path_cleanup(&src); - /* Cleanup for dst */ - path_cleanup(&dst); - - return return_value; -} - -PyDoc_STRVAR(os_rmdir__doc__, -"rmdir($module, /, path, *, dir_fd=None)\n" -"--\n" -"\n" -"Remove a directory.\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"dir_fd may not be implemented on your platform.\n" -" If it is unavailable, using it will raise a NotImplementedError."); - -#define OS_RMDIR_METHODDEF \ + return_value = os_replace_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +PyDoc_STRVAR(os_rmdir__doc__, +"rmdir($module, /, path, *, dir_fd=None)\n" +"--\n" +"\n" +"Remove a directory.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_RMDIR_METHODDEF \ {"rmdir", (PyCFunction)(void(*)(void))os_rmdir, METH_FASTCALL|METH_KEYWORDS, os_rmdir__doc__}, - -static PyObject * -os_rmdir_impl(PyObject *module, path_t *path, int dir_fd); - -static PyObject * -os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "dir_fd", NULL}; + +static PyObject * +os_rmdir_impl(PyObject *module, path_t *path, int dir_fd); + +static PyObject * +os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "rmdir", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); - int dir_fd = DEFAULT_DIR_FD; - + path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -1757,165 +1757,165 @@ os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw goto exit; } skip_optional_kwonly: - return_value = os_rmdir_impl(module, &path, dir_fd); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#if defined(HAVE_SYSTEM) && defined(MS_WINDOWS) - -PyDoc_STRVAR(os_system__doc__, -"system($module, /, command)\n" -"--\n" -"\n" -"Execute the command in a subshell."); - -#define OS_SYSTEM_METHODDEF \ + return_value = os_rmdir_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#if defined(HAVE_SYSTEM) && defined(MS_WINDOWS) + +PyDoc_STRVAR(os_system__doc__, +"system($module, /, command)\n" +"--\n" +"\n" +"Execute the command in a subshell."); + +#define OS_SYSTEM_METHODDEF \ {"system", (PyCFunction)(void(*)(void))os_system, METH_FASTCALL|METH_KEYWORDS, os_system__doc__}, - -static long -os_system_impl(PyObject *module, const Py_UNICODE *command); - -static PyObject * -os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {"u:system", _keywords, 0}; - const Py_UNICODE *command; - long _return_value; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &command)) { - goto exit; - } - _return_value = os_system_impl(module, command); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong(_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SYSTEM) && defined(MS_WINDOWS) */ - -#if defined(HAVE_SYSTEM) && !defined(MS_WINDOWS) - -PyDoc_STRVAR(os_system__doc__, -"system($module, /, command)\n" -"--\n" -"\n" -"Execute the command in a subshell."); - -#define OS_SYSTEM_METHODDEF \ + +static long +os_system_impl(PyObject *module, const Py_UNICODE *command); + +static PyObject * +os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"command", NULL}; + static _PyArg_Parser _parser = {"u:system", _keywords, 0}; + const Py_UNICODE *command; + long _return_value; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &command)) { + goto exit; + } + _return_value = os_system_impl(module, command); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYSTEM) && defined(MS_WINDOWS) */ + +#if defined(HAVE_SYSTEM) && !defined(MS_WINDOWS) + +PyDoc_STRVAR(os_system__doc__, +"system($module, /, command)\n" +"--\n" +"\n" +"Execute the command in a subshell."); + +#define OS_SYSTEM_METHODDEF \ {"system", (PyCFunction)(void(*)(void))os_system, METH_FASTCALL|METH_KEYWORDS, os_system__doc__}, - -static long -os_system_impl(PyObject *module, PyObject *command); - -static PyObject * -os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"command", NULL}; + +static long +os_system_impl(PyObject *module, PyObject *command); + +static PyObject * +os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"command", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; PyObject *argsbuf[1]; - PyObject *command = NULL; - long _return_value; - + PyObject *command = NULL; + long _return_value; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!PyUnicode_FSConverter(args[0], &command)) { goto exit; } - _return_value = os_system_impl(module, command); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong(_return_value); - -exit: - /* Cleanup for command */ - Py_XDECREF(command); - - return return_value; -} - -#endif /* defined(HAVE_SYSTEM) && !defined(MS_WINDOWS) */ - -PyDoc_STRVAR(os_umask__doc__, -"umask($module, mask, /)\n" -"--\n" -"\n" -"Set the current numeric umask and return the previous umask."); - -#define OS_UMASK_METHODDEF \ - {"umask", (PyCFunction)os_umask, METH_O, os_umask__doc__}, - -static PyObject * -os_umask_impl(PyObject *module, int mask); - -static PyObject * -os_umask(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int mask; - + _return_value = os_system_impl(module, command); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + /* Cleanup for command */ + Py_XDECREF(command); + + return return_value; +} + +#endif /* defined(HAVE_SYSTEM) && !defined(MS_WINDOWS) */ + +PyDoc_STRVAR(os_umask__doc__, +"umask($module, mask, /)\n" +"--\n" +"\n" +"Set the current numeric umask and return the previous umask."); + +#define OS_UMASK_METHODDEF \ + {"umask", (PyCFunction)os_umask, METH_O, os_umask__doc__}, + +static PyObject * +os_umask_impl(PyObject *module, int mask); + +static PyObject * +os_umask(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int mask; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } mask = _PyLong_AsInt(arg); if (mask == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_umask_impl(module, mask); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_unlink__doc__, -"unlink($module, /, path, *, dir_fd=None)\n" -"--\n" -"\n" -"Remove a file (same as remove()).\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"dir_fd may not be implemented on your platform.\n" -" If it is unavailable, using it will raise a NotImplementedError."); - -#define OS_UNLINK_METHODDEF \ + return_value = os_umask_impl(module, mask); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_unlink__doc__, +"unlink($module, /, path, *, dir_fd=None)\n" +"--\n" +"\n" +"Remove a file (same as remove()).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_UNLINK_METHODDEF \ {"unlink", (PyCFunction)(void(*)(void))os_unlink, METH_FASTCALL|METH_KEYWORDS, os_unlink__doc__}, - -static PyObject * -os_unlink_impl(PyObject *module, path_t *path, int dir_fd); - -static PyObject * -os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "dir_fd", NULL}; + +static PyObject * +os_unlink_impl(PyObject *module, path_t *path, int dir_fd); + +static PyObject * +os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "unlink", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); - int dir_fd = DEFAULT_DIR_FD; - + path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -1926,47 +1926,47 @@ os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k goto exit; } skip_optional_kwonly: - return_value = os_unlink_impl(module, &path, dir_fd); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -PyDoc_STRVAR(os_remove__doc__, -"remove($module, /, path, *, dir_fd=None)\n" -"--\n" -"\n" -"Remove a file (same as unlink()).\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"dir_fd may not be implemented on your platform.\n" -" If it is unavailable, using it will raise a NotImplementedError."); - -#define OS_REMOVE_METHODDEF \ + return_value = os_unlink_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +PyDoc_STRVAR(os_remove__doc__, +"remove($module, /, path, *, dir_fd=None)\n" +"--\n" +"\n" +"Remove a file (same as unlink()).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_REMOVE_METHODDEF \ {"remove", (PyCFunction)(void(*)(void))os_remove, METH_FASTCALL|METH_KEYWORDS, os_remove__doc__}, - -static PyObject * -os_remove_impl(PyObject *module, path_t *path, int dir_fd); - -static PyObject * -os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "dir_fd", NULL}; + +static PyObject * +os_remove_impl(PyObject *module, path_t *path, int dir_fd); + +static PyObject * +os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "remove", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); - int dir_fd = DEFAULT_DIR_FD; - + path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -1977,94 +1977,94 @@ os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k goto exit; } skip_optional_kwonly: - return_value = os_remove_impl(module, &path, dir_fd); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#if defined(HAVE_UNAME) - -PyDoc_STRVAR(os_uname__doc__, -"uname($module, /)\n" -"--\n" -"\n" -"Return an object identifying the current operating system.\n" -"\n" -"The object behaves like a named tuple with the following fields:\n" -" (sysname, nodename, release, version, machine)"); - -#define OS_UNAME_METHODDEF \ - {"uname", (PyCFunction)os_uname, METH_NOARGS, os_uname__doc__}, - -static PyObject * -os_uname_impl(PyObject *module); - -static PyObject * -os_uname(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_uname_impl(module); -} - -#endif /* defined(HAVE_UNAME) */ - -PyDoc_STRVAR(os_utime__doc__, + return_value = os_remove_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#if defined(HAVE_UNAME) + +PyDoc_STRVAR(os_uname__doc__, +"uname($module, /)\n" +"--\n" +"\n" +"Return an object identifying the current operating system.\n" +"\n" +"The object behaves like a named tuple with the following fields:\n" +" (sysname, nodename, release, version, machine)"); + +#define OS_UNAME_METHODDEF \ + {"uname", (PyCFunction)os_uname, METH_NOARGS, os_uname__doc__}, + +static PyObject * +os_uname_impl(PyObject *module); + +static PyObject * +os_uname(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_uname_impl(module); +} + +#endif /* defined(HAVE_UNAME) */ + +PyDoc_STRVAR(os_utime__doc__, "utime($module, /, path, times=None, *, ns=,\n" " dir_fd=None, follow_symlinks=True)\n" -"--\n" -"\n" -"Set the access and modified time of path.\n" -"\n" -"path may always be specified as a string.\n" -"On some platforms, path may also be specified as an open file descriptor.\n" -" If this functionality is unavailable, using it raises an exception.\n" -"\n" -"If times is not None, it must be a tuple (atime, mtime);\n" -" atime and mtime should be expressed as float seconds since the epoch.\n" -"If ns is specified, it must be a tuple (atime_ns, mtime_ns);\n" -" atime_ns and mtime_ns should be expressed as integer nanoseconds\n" -" since the epoch.\n" -"If times is None and ns is unspecified, utime uses the current time.\n" -"Specifying tuples for both times and ns is an error.\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"If follow_symlinks is False, and the last element of the path is a symbolic\n" -" link, utime will modify the symbolic link itself instead of the file the\n" -" link points to.\n" -"It is an error to use dir_fd or follow_symlinks when specifying path\n" -" as an open file descriptor.\n" -"dir_fd and follow_symlinks may not be available on your platform.\n" -" If they are unavailable, using them will raise a NotImplementedError."); - -#define OS_UTIME_METHODDEF \ +"--\n" +"\n" +"Set the access and modified time of path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +"\n" +"If times is not None, it must be a tuple (atime, mtime);\n" +" atime and mtime should be expressed as float seconds since the epoch.\n" +"If ns is specified, it must be a tuple (atime_ns, mtime_ns);\n" +" atime_ns and mtime_ns should be expressed as integer nanoseconds\n" +" since the epoch.\n" +"If times is None and ns is unspecified, utime uses the current time.\n" +"Specifying tuples for both times and ns is an error.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, utime will modify the symbolic link itself instead of the file the\n" +" link points to.\n" +"It is an error to use dir_fd or follow_symlinks when specifying path\n" +" as an open file descriptor.\n" +"dir_fd and follow_symlinks may not be available on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_UTIME_METHODDEF \ {"utime", (PyCFunction)(void(*)(void))os_utime, METH_FASTCALL|METH_KEYWORDS, os_utime__doc__}, - -static PyObject * -os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, - int dir_fd, int follow_symlinks); - -static PyObject * -os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; + +static PyObject * +os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, + int dir_fd, int follow_symlinks); + +static PyObject * +os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "utime", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); + path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); PyObject *times = Py_None; - PyObject *ns = NULL; - int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; - + PyObject *ns = NULL; + int dir_fd = DEFAULT_DIR_FD; + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -2100,40 +2100,40 @@ skip_optional_pos: goto exit; } skip_optional_kwonly: - return_value = os_utime_impl(module, &path, times, ns, dir_fd, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -PyDoc_STRVAR(os__exit__doc__, -"_exit($module, /, status)\n" -"--\n" -"\n" -"Exit to the system with specified status, without normal exit processing."); - -#define OS__EXIT_METHODDEF \ + return_value = os_utime_impl(module, &path, times, ns, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +PyDoc_STRVAR(os__exit__doc__, +"_exit($module, /, status)\n" +"--\n" +"\n" +"Exit to the system with specified status, without normal exit processing."); + +#define OS__EXIT_METHODDEF \ {"_exit", (PyCFunction)(void(*)(void))os__exit, METH_FASTCALL|METH_KEYWORDS, os__exit__doc__}, - -static PyObject * -os__exit_impl(PyObject *module, int status); - -static PyObject * -os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"status", NULL}; + +static PyObject * +os__exit_impl(PyObject *module, int status); + +static PyObject * +os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"status", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "_exit", 0}; PyObject *argsbuf[1]; - int status; - + int status; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -2143,110 +2143,110 @@ os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw if (status == -1 && PyErr_Occurred()) { goto exit; } - return_value = os__exit_impl(module, status); - -exit: - return return_value; -} - -#if defined(HAVE_EXECV) - -PyDoc_STRVAR(os_execv__doc__, -"execv($module, path, argv, /)\n" -"--\n" -"\n" -"Execute an executable path with arguments, replacing current process.\n" -"\n" -" path\n" -" Path of executable file.\n" -" argv\n" -" Tuple or list of strings."); - -#define OS_EXECV_METHODDEF \ + return_value = os__exit_impl(module, status); + +exit: + return return_value; +} + +#if defined(HAVE_EXECV) + +PyDoc_STRVAR(os_execv__doc__, +"execv($module, path, argv, /)\n" +"--\n" +"\n" +"Execute an executable path with arguments, replacing current process.\n" +"\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings."); + +#define OS_EXECV_METHODDEF \ {"execv", (PyCFunction)(void(*)(void))os_execv, METH_FASTCALL, os_execv__doc__}, - -static PyObject * -os_execv_impl(PyObject *module, path_t *path, PyObject *argv); - -static PyObject * -os_execv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0); - PyObject *argv; - + +static PyObject * +os_execv_impl(PyObject *module, path_t *path, PyObject *argv); + +static PyObject * +os_execv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0); + PyObject *argv; + if (!_PyArg_CheckPositional("execv", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } argv = args[1]; - return_value = os_execv_impl(module, &path, argv); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_EXECV) */ - -#if defined(HAVE_EXECV) - -PyDoc_STRVAR(os_execve__doc__, -"execve($module, /, path, argv, env)\n" -"--\n" -"\n" -"Execute an executable path with arguments, replacing current process.\n" -"\n" -" path\n" -" Path of executable file.\n" -" argv\n" -" Tuple or list of strings.\n" -" env\n" -" Dictionary of strings mapping to strings."); - -#define OS_EXECVE_METHODDEF \ + return_value = os_execv_impl(module, &path, argv); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_EXECV) */ + +#if defined(HAVE_EXECV) + +PyDoc_STRVAR(os_execve__doc__, +"execve($module, /, path, argv, env)\n" +"--\n" +"\n" +"Execute an executable path with arguments, replacing current process.\n" +"\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings.\n" +" env\n" +" Dictionary of strings mapping to strings."); + +#define OS_EXECVE_METHODDEF \ {"execve", (PyCFunction)(void(*)(void))os_execve, METH_FASTCALL|METH_KEYWORDS, os_execve__doc__}, - -static PyObject * -os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env); - -static PyObject * -os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "argv", "env", NULL}; + +static PyObject * +os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env); + +static PyObject * +os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "argv", "env", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "execve", 0}; PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); - PyObject *argv; - PyObject *env; - + path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); + PyObject *argv; + PyObject *env; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } argv = args[1]; env = args[2]; - return_value = os_execve_impl(module, &path, argv, env); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_EXECV) */ - + return_value = os_execve_impl(module, &path, argv, env); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_EXECV) */ + #if defined(HAVE_POSIX_SPAWN) - + PyDoc_STRVAR(os_posix_spawn__doc__, "posix_spawn($module, path, argv, env, /, *, file_actions=(),\n" " setpgroup=, resetids=False, setsid=False,\n" @@ -2521,36 +2521,36 @@ exit: #if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) -PyDoc_STRVAR(os_spawnv__doc__, -"spawnv($module, mode, path, argv, /)\n" -"--\n" -"\n" -"Execute the program specified by path in a new process.\n" -"\n" -" mode\n" -" Mode of process creation.\n" -" path\n" -" Path of executable file.\n" -" argv\n" -" Tuple or list of strings."); - -#define OS_SPAWNV_METHODDEF \ +PyDoc_STRVAR(os_spawnv__doc__, +"spawnv($module, mode, path, argv, /)\n" +"--\n" +"\n" +"Execute the program specified by path in a new process.\n" +"\n" +" mode\n" +" Mode of process creation.\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings."); + +#define OS_SPAWNV_METHODDEF \ {"spawnv", (PyCFunction)(void(*)(void))os_spawnv, METH_FASTCALL, os_spawnv__doc__}, - -static PyObject * -os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv); - -static PyObject * -os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int mode; - path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0); - PyObject *argv; - + +static PyObject * +os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv); + +static PyObject * +os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int mode; + path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0); + PyObject *argv; + if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -2564,53 +2564,53 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } argv = args[2]; - return_value = os_spawnv_impl(module, mode, &path, argv); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - + return_value = os_spawnv_impl(module, mode, &path, argv); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + #endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) */ - + #if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) - -PyDoc_STRVAR(os_spawnve__doc__, -"spawnve($module, mode, path, argv, env, /)\n" -"--\n" -"\n" -"Execute the program specified by path in a new process.\n" -"\n" -" mode\n" -" Mode of process creation.\n" -" path\n" -" Path of executable file.\n" -" argv\n" -" Tuple or list of strings.\n" -" env\n" -" Dictionary of strings mapping to strings."); - -#define OS_SPAWNVE_METHODDEF \ + +PyDoc_STRVAR(os_spawnve__doc__, +"spawnve($module, mode, path, argv, env, /)\n" +"--\n" +"\n" +"Execute the program specified by path in a new process.\n" +"\n" +" mode\n" +" Mode of process creation.\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings.\n" +" env\n" +" Dictionary of strings mapping to strings."); + +#define OS_SPAWNVE_METHODDEF \ {"spawnve", (PyCFunction)(void(*)(void))os_spawnve, METH_FASTCALL, os_spawnve__doc__}, - -static PyObject * -os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, - PyObject *env); - -static PyObject * -os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int mode; - path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0); - PyObject *argv; - PyObject *env; - + +static PyObject * +os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, + PyObject *env); + +static PyObject * +os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int mode; + path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0); + PyObject *argv; + PyObject *env; + if (!_PyArg_CheckPositional("spawnve", nargs, 4, 4)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -2625,60 +2625,60 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } argv = args[2]; env = args[3]; - return_value = os_spawnve_impl(module, mode, &path, argv, env); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - + return_value = os_spawnve_impl(module, mode, &path, argv, env); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + #endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) */ - -#if defined(HAVE_FORK) - -PyDoc_STRVAR(os_register_at_fork__doc__, + +#if defined(HAVE_FORK) + +PyDoc_STRVAR(os_register_at_fork__doc__, "register_at_fork($module, /, *, before=,\n" " after_in_child=,\n" " after_in_parent=)\n" -"--\n" -"\n" -"Register callables to be called when forking a new process.\n" -"\n" -" before\n" -" A callable to be called in the parent before the fork() syscall.\n" -" after_in_child\n" -" A callable to be called in the child after fork().\n" -" after_in_parent\n" -" A callable to be called in the parent after fork().\n" -"\n" -"\'before\' callbacks are called in reverse order.\n" -"\'after_in_child\' and \'after_in_parent\' callbacks are called in order."); - -#define OS_REGISTER_AT_FORK_METHODDEF \ +"--\n" +"\n" +"Register callables to be called when forking a new process.\n" +"\n" +" before\n" +" A callable to be called in the parent before the fork() syscall.\n" +" after_in_child\n" +" A callable to be called in the child after fork().\n" +" after_in_parent\n" +" A callable to be called in the parent after fork().\n" +"\n" +"\'before\' callbacks are called in reverse order.\n" +"\'after_in_child\' and \'after_in_parent\' callbacks are called in order."); + +#define OS_REGISTER_AT_FORK_METHODDEF \ {"register_at_fork", (PyCFunction)(void(*)(void))os_register_at_fork, METH_FASTCALL|METH_KEYWORDS, os_register_at_fork__doc__}, - -static PyObject * -os_register_at_fork_impl(PyObject *module, PyObject *before, - PyObject *after_in_child, PyObject *after_in_parent); - -static PyObject * -os_register_at_fork(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"before", "after_in_child", "after_in_parent", NULL}; + +static PyObject * +os_register_at_fork_impl(PyObject *module, PyObject *before, + PyObject *after_in_child, PyObject *after_in_parent); + +static PyObject * +os_register_at_fork(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"before", "after_in_child", "after_in_parent", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "register_at_fork", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *before = NULL; - PyObject *after_in_child = NULL; - PyObject *after_in_parent = NULL; - + PyObject *before = NULL; + PyObject *after_in_child = NULL; + PyObject *after_in_parent = NULL; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_kwonly; } @@ -2696,89 +2696,89 @@ os_register_at_fork(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P } after_in_parent = args[2]; skip_optional_kwonly: - return_value = os_register_at_fork_impl(module, before, after_in_child, after_in_parent); - -exit: - return return_value; -} - -#endif /* defined(HAVE_FORK) */ - -#if defined(HAVE_FORK1) - -PyDoc_STRVAR(os_fork1__doc__, -"fork1($module, /)\n" -"--\n" -"\n" -"Fork a child process with a single multiplexed (i.e., not bound) thread.\n" -"\n" -"Return 0 to child process and PID of child to parent process."); - -#define OS_FORK1_METHODDEF \ - {"fork1", (PyCFunction)os_fork1, METH_NOARGS, os_fork1__doc__}, - -static PyObject * -os_fork1_impl(PyObject *module); - -static PyObject * -os_fork1(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_fork1_impl(module); -} - -#endif /* defined(HAVE_FORK1) */ - -#if defined(HAVE_FORK) - -PyDoc_STRVAR(os_fork__doc__, -"fork($module, /)\n" -"--\n" -"\n" -"Fork a child process.\n" -"\n" -"Return 0 to child process and PID of child to parent process."); - -#define OS_FORK_METHODDEF \ - {"fork", (PyCFunction)os_fork, METH_NOARGS, os_fork__doc__}, - -static PyObject * -os_fork_impl(PyObject *module); - -static PyObject * -os_fork(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_fork_impl(module); -} - -#endif /* defined(HAVE_FORK) */ - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GET_PRIORITY_MAX) - -PyDoc_STRVAR(os_sched_get_priority_max__doc__, -"sched_get_priority_max($module, /, policy)\n" -"--\n" -"\n" -"Get the maximum scheduling priority for policy."); - -#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF \ + return_value = os_register_at_fork_impl(module, before, after_in_child, after_in_parent); + +exit: + return return_value; +} + +#endif /* defined(HAVE_FORK) */ + +#if defined(HAVE_FORK1) + +PyDoc_STRVAR(os_fork1__doc__, +"fork1($module, /)\n" +"--\n" +"\n" +"Fork a child process with a single multiplexed (i.e., not bound) thread.\n" +"\n" +"Return 0 to child process and PID of child to parent process."); + +#define OS_FORK1_METHODDEF \ + {"fork1", (PyCFunction)os_fork1, METH_NOARGS, os_fork1__doc__}, + +static PyObject * +os_fork1_impl(PyObject *module); + +static PyObject * +os_fork1(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_fork1_impl(module); +} + +#endif /* defined(HAVE_FORK1) */ + +#if defined(HAVE_FORK) + +PyDoc_STRVAR(os_fork__doc__, +"fork($module, /)\n" +"--\n" +"\n" +"Fork a child process.\n" +"\n" +"Return 0 to child process and PID of child to parent process."); + +#define OS_FORK_METHODDEF \ + {"fork", (PyCFunction)os_fork, METH_NOARGS, os_fork__doc__}, + +static PyObject * +os_fork_impl(PyObject *module); + +static PyObject * +os_fork(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_fork_impl(module); +} + +#endif /* defined(HAVE_FORK) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GET_PRIORITY_MAX) + +PyDoc_STRVAR(os_sched_get_priority_max__doc__, +"sched_get_priority_max($module, /, policy)\n" +"--\n" +"\n" +"Get the maximum scheduling priority for policy."); + +#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF \ {"sched_get_priority_max", (PyCFunction)(void(*)(void))os_sched_get_priority_max, METH_FASTCALL|METH_KEYWORDS, os_sched_get_priority_max__doc__}, - -static PyObject * -os_sched_get_priority_max_impl(PyObject *module, int policy); - -static PyObject * -os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"policy", NULL}; + +static PyObject * +os_sched_get_priority_max_impl(PyObject *module, int policy); + +static PyObject * +os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"policy", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_max", 0}; PyObject *argsbuf[1]; - int policy; - + int policy; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -2788,41 +2788,41 @@ os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t na if (policy == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_sched_get_priority_max_impl(module, policy); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GET_PRIORITY_MAX) */ - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GET_PRIORITY_MAX) - -PyDoc_STRVAR(os_sched_get_priority_min__doc__, -"sched_get_priority_min($module, /, policy)\n" -"--\n" -"\n" -"Get the minimum scheduling priority for policy."); - -#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF \ + return_value = os_sched_get_priority_max_impl(module, policy); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GET_PRIORITY_MAX) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GET_PRIORITY_MAX) + +PyDoc_STRVAR(os_sched_get_priority_min__doc__, +"sched_get_priority_min($module, /, policy)\n" +"--\n" +"\n" +"Get the minimum scheduling priority for policy."); + +#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF \ {"sched_get_priority_min", (PyCFunction)(void(*)(void))os_sched_get_priority_min, METH_FASTCALL|METH_KEYWORDS, os_sched_get_priority_min__doc__}, - -static PyObject * -os_sched_get_priority_min_impl(PyObject *module, int policy); - -static PyObject * -os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"policy", NULL}; + +static PyObject * +os_sched_get_priority_min_impl(PyObject *module, int policy); + +static PyObject * +os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"policy", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_min", 0}; PyObject *argsbuf[1]; - int policy; - + int policy; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -2832,3183 +2832,1896 @@ os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t na if (policy == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_sched_get_priority_min_impl(module, policy); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GET_PRIORITY_MAX) */ - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) + return_value = os_sched_get_priority_min_impl(module, policy); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GET_PRIORITY_MAX) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) + +PyDoc_STRVAR(os_sched_getscheduler__doc__, +"sched_getscheduler($module, pid, /)\n" +"--\n" +"\n" +"Get the scheduling policy for the process identified by pid.\n" +"\n" +"Passing 0 for pid returns the scheduling policy for the calling process."); + +#define OS_SCHED_GETSCHEDULER_METHODDEF \ + {"sched_getscheduler", (PyCFunction)os_sched_getscheduler, METH_O, os_sched_getscheduler__doc__}, + +static PyObject * +os_sched_getscheduler_impl(PyObject *module, pid_t pid); + +static PyObject * +os_sched_getscheduler(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + pid_t pid; + + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getscheduler", &pid)) { + goto exit; + } + return_value = os_sched_getscheduler_impl(module, pid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) */ + +#if defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)) + +PyDoc_STRVAR(os_sched_param__doc__, +"sched_param(sched_priority)\n" +"--\n" +"\n" +"Currently has only one field: sched_priority\n" +"\n" +" sched_priority\n" +" A scheduling parameter."); + +static PyObject * +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority); + +static PyObject * +os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sched_priority", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sched_param", 0}; + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *sched_priority; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + sched_priority = fastargs[0]; + return_value = os_sched_param_impl(type, sched_priority); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) + +PyDoc_STRVAR(os_sched_setscheduler__doc__, +"sched_setscheduler($module, pid, policy, param, /)\n" +"--\n" +"\n" +"Set the scheduling policy for the process identified by pid.\n" +"\n" +"If pid is 0, the calling process is changed.\n" +"param is an instance of sched_param."); + +#define OS_SCHED_SETSCHEDULER_METHODDEF \ + {"sched_setscheduler", (PyCFunction)(void(*)(void))os_sched_setscheduler, METH_FASTCALL, os_sched_setscheduler__doc__}, + +static PyObject * +os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy, + PyObject *param_obj); + +static PyObject * +os_sched_setscheduler(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pid; + int policy; + PyObject *param_obj; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "iO:sched_setscheduler", + &pid, &policy, ¶m_obj)) { + goto exit; + } + return_value = os_sched_setscheduler_impl(module, pid, policy, param_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETPARAM) + +PyDoc_STRVAR(os_sched_getparam__doc__, +"sched_getparam($module, pid, /)\n" +"--\n" +"\n" +"Returns scheduling parameters for the process identified by pid.\n" +"\n" +"If pid is 0, returns parameters for the calling process.\n" +"Return value is an instance of sched_param."); + +#define OS_SCHED_GETPARAM_METHODDEF \ + {"sched_getparam", (PyCFunction)os_sched_getparam, METH_O, os_sched_getparam__doc__}, + +static PyObject * +os_sched_getparam_impl(PyObject *module, pid_t pid); + +static PyObject * +os_sched_getparam(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + pid_t pid; + + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getparam", &pid)) { + goto exit; + } + return_value = os_sched_getparam_impl(module, pid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETPARAM) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETPARAM) + +PyDoc_STRVAR(os_sched_setparam__doc__, +"sched_setparam($module, pid, param, /)\n" +"--\n" +"\n" +"Set scheduling parameters for the process identified by pid.\n" +"\n" +"If pid is 0, sets parameters for the calling process.\n" +"param should be an instance of sched_param."); + +#define OS_SCHED_SETPARAM_METHODDEF \ + {"sched_setparam", (PyCFunction)(void(*)(void))os_sched_setparam, METH_FASTCALL, os_sched_setparam__doc__}, + +static PyObject * +os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj); + +static PyObject * +os_sched_setparam(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pid; + PyObject *param_obj; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "O:sched_setparam", + &pid, ¶m_obj)) { + goto exit; + } + return_value = os_sched_setparam_impl(module, pid, param_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETPARAM) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_RR_GET_INTERVAL) + +PyDoc_STRVAR(os_sched_rr_get_interval__doc__, +"sched_rr_get_interval($module, pid, /)\n" +"--\n" +"\n" +"Return the round-robin quantum for the process identified by pid, in seconds.\n" +"\n" +"Value returned is a float."); + +#define OS_SCHED_RR_GET_INTERVAL_METHODDEF \ + {"sched_rr_get_interval", (PyCFunction)os_sched_rr_get_interval, METH_O, os_sched_rr_get_interval__doc__}, + +static double +os_sched_rr_get_interval_impl(PyObject *module, pid_t pid); + +static PyObject * +os_sched_rr_get_interval(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + pid_t pid; + double _return_value; + + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_rr_get_interval", &pid)) { + goto exit; + } + _return_value = os_sched_rr_get_interval_impl(module, pid); + if ((_return_value == -1.0) && PyErr_Occurred()) { + goto exit; + } + return_value = PyFloat_FromDouble(_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_RR_GET_INTERVAL) */ + +#if defined(HAVE_SCHED_H) + +PyDoc_STRVAR(os_sched_yield__doc__, +"sched_yield($module, /)\n" +"--\n" +"\n" +"Voluntarily relinquish the CPU."); + +#define OS_SCHED_YIELD_METHODDEF \ + {"sched_yield", (PyCFunction)os_sched_yield, METH_NOARGS, os_sched_yield__doc__}, + +static PyObject * +os_sched_yield_impl(PyObject *module); + +static PyObject * +os_sched_yield(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_sched_yield_impl(module); +} + +#endif /* defined(HAVE_SCHED_H) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) + +PyDoc_STRVAR(os_sched_setaffinity__doc__, +"sched_setaffinity($module, pid, mask, /)\n" +"--\n" +"\n" +"Set the CPU affinity of the process identified by pid to mask.\n" +"\n" +"mask should be an iterable of integers identifying CPUs."); + +#define OS_SCHED_SETAFFINITY_METHODDEF \ + {"sched_setaffinity", (PyCFunction)(void(*)(void))os_sched_setaffinity, METH_FASTCALL, os_sched_setaffinity__doc__}, + +static PyObject * +os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask); + +static PyObject * +os_sched_setaffinity(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pid; + PyObject *mask; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "O:sched_setaffinity", + &pid, &mask)) { + goto exit; + } + return_value = os_sched_setaffinity_impl(module, pid, mask); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) */ + +#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) + +PyDoc_STRVAR(os_sched_getaffinity__doc__, +"sched_getaffinity($module, pid, /)\n" +"--\n" +"\n" +"Return the affinity of the process identified by pid (or the current process if zero).\n" +"\n" +"The affinity is returned as a set of CPU identifiers."); + +#define OS_SCHED_GETAFFINITY_METHODDEF \ + {"sched_getaffinity", (PyCFunction)os_sched_getaffinity, METH_O, os_sched_getaffinity__doc__}, + +static PyObject * +os_sched_getaffinity_impl(PyObject *module, pid_t pid); + +static PyObject * +os_sched_getaffinity(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + pid_t pid; + + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getaffinity", &pid)) { + goto exit; + } + return_value = os_sched_getaffinity_impl(module, pid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) */ + +#if (defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)) + +PyDoc_STRVAR(os_openpty__doc__, +"openpty($module, /)\n" +"--\n" +"\n" +"Open a pseudo-terminal.\n" +"\n" +"Return a tuple of (master_fd, slave_fd) containing open file descriptors\n" +"for both the master and slave ends."); + +#define OS_OPENPTY_METHODDEF \ + {"openpty", (PyCFunction)os_openpty, METH_NOARGS, os_openpty__doc__}, + +static PyObject * +os_openpty_impl(PyObject *module); + +static PyObject * +os_openpty(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_openpty_impl(module); +} + +#endif /* (defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)) */ + +#if defined(HAVE_FORKPTY) + +PyDoc_STRVAR(os_forkpty__doc__, +"forkpty($module, /)\n" +"--\n" +"\n" +"Fork a new process with a new pseudo-terminal as controlling tty.\n" +"\n" +"Returns a tuple of (pid, master_fd).\n" +"Like fork(), return pid of 0 to the child process,\n" +"and pid of child to the parent process.\n" +"To both, return fd of newly opened pseudo-terminal."); + +#define OS_FORKPTY_METHODDEF \ + {"forkpty", (PyCFunction)os_forkpty, METH_NOARGS, os_forkpty__doc__}, + +static PyObject * +os_forkpty_impl(PyObject *module); + +static PyObject * +os_forkpty(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_forkpty_impl(module); +} + +#endif /* defined(HAVE_FORKPTY) */ + +#if defined(HAVE_GETEGID) + +PyDoc_STRVAR(os_getegid__doc__, +"getegid($module, /)\n" +"--\n" +"\n" +"Return the current process\'s effective group id."); + +#define OS_GETEGID_METHODDEF \ + {"getegid", (PyCFunction)os_getegid, METH_NOARGS, os_getegid__doc__}, + +static PyObject * +os_getegid_impl(PyObject *module); + +static PyObject * +os_getegid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getegid_impl(module); +} + +#endif /* defined(HAVE_GETEGID) */ + +#if defined(HAVE_GETEUID) + +PyDoc_STRVAR(os_geteuid__doc__, +"geteuid($module, /)\n" +"--\n" +"\n" +"Return the current process\'s effective user id."); + +#define OS_GETEUID_METHODDEF \ + {"geteuid", (PyCFunction)os_geteuid, METH_NOARGS, os_geteuid__doc__}, + +static PyObject * +os_geteuid_impl(PyObject *module); + +static PyObject * +os_geteuid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_geteuid_impl(module); +} + +#endif /* defined(HAVE_GETEUID) */ + +#if defined(HAVE_GETGID) + +PyDoc_STRVAR(os_getgid__doc__, +"getgid($module, /)\n" +"--\n" +"\n" +"Return the current process\'s group id."); + +#define OS_GETGID_METHODDEF \ + {"getgid", (PyCFunction)os_getgid, METH_NOARGS, os_getgid__doc__}, + +static PyObject * +os_getgid_impl(PyObject *module); + +static PyObject * +os_getgid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getgid_impl(module); +} + +#endif /* defined(HAVE_GETGID) */ + +#if defined(HAVE_GETPID) + +PyDoc_STRVAR(os_getpid__doc__, +"getpid($module, /)\n" +"--\n" +"\n" +"Return the current process id."); + +#define OS_GETPID_METHODDEF \ + {"getpid", (PyCFunction)os_getpid, METH_NOARGS, os_getpid__doc__}, + +static PyObject * +os_getpid_impl(PyObject *module); + +static PyObject * +os_getpid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getpid_impl(module); +} + +#endif /* defined(HAVE_GETPID) */ + +#if defined(HAVE_GETGROUPLIST) && defined(__APPLE__) -PyDoc_STRVAR(os_sched_getscheduler__doc__, -"sched_getscheduler($module, pid, /)\n" +PyDoc_STRVAR(os_getgrouplist__doc__, +"getgrouplist($module, user, group, /)\n" "--\n" "\n" -"Get the scheduling policy for the process identified by pid.\n" +"Returns a list of groups to which a user belongs.\n" "\n" -"Passing 0 for pid returns the scheduling policy for the calling process."); +" user\n" +" username to lookup\n" +" group\n" +" base group id of the user"); -#define OS_SCHED_GETSCHEDULER_METHODDEF \ - {"sched_getscheduler", (PyCFunction)os_sched_getscheduler, METH_O, os_sched_getscheduler__doc__}, +#define OS_GETGROUPLIST_METHODDEF \ + {"getgrouplist", (PyCFunction)(void(*)(void))os_getgrouplist, METH_FASTCALL, os_getgrouplist__doc__}, static PyObject * -os_sched_getscheduler_impl(PyObject *module, pid_t pid); +os_getgrouplist_impl(PyObject *module, const char *user, int basegid); static PyObject * -os_sched_getscheduler(PyObject *module, PyObject *arg) +os_getgrouplist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - pid_t pid; + const char *user; + int basegid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getscheduler", &pid)) { + if (!_PyArg_CheckPositional("getgrouplist", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("getgrouplist", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t user_length; + user = PyUnicode_AsUTF8AndSize(args[0], &user_length); + if (user == NULL) { + goto exit; + } + if (strlen(user) != (size_t)user_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + basegid = _PyLong_AsInt(args[1]); + if (basegid == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_sched_getscheduler_impl(module, pid); + return_value = os_getgrouplist_impl(module, user, basegid); exit: return return_value; } -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) */ +#endif /* defined(HAVE_GETGROUPLIST) && defined(__APPLE__) */ -#if defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)) +#if defined(HAVE_GETGROUPLIST) && !defined(__APPLE__) -PyDoc_STRVAR(os_sched_param__doc__, -"sched_param(sched_priority)\n" +PyDoc_STRVAR(os_getgrouplist__doc__, +"getgrouplist($module, user, group, /)\n" "--\n" "\n" -"Currently has only one field: sched_priority\n" +"Returns a list of groups to which a user belongs.\n" "\n" -" sched_priority\n" -" A scheduling parameter."); +" user\n" +" username to lookup\n" +" group\n" +" base group id of the user"); + +#define OS_GETGROUPLIST_METHODDEF \ + {"getgrouplist", (PyCFunction)(void(*)(void))os_getgrouplist, METH_FASTCALL, os_getgrouplist__doc__}, static PyObject * -os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority); +os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid); static PyObject * -os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) +os_getgrouplist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"sched_priority", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_param", 0}; - PyObject *argsbuf[1]; - PyObject * const *fastargs; - Py_ssize_t nargs = PyTuple_GET_SIZE(args); - PyObject *sched_priority; + const char *user; + gid_t basegid; - fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); - if (!fastargs) { + if (!_PyArg_CheckPositional("getgrouplist", nargs, 2, 2)) { goto exit; } - sched_priority = fastargs[0]; - return_value = os_sched_param_impl(type, sched_priority); + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("getgrouplist", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t user_length; + user = PyUnicode_AsUTF8AndSize(args[0], &user_length); + if (user == NULL) { + goto exit; + } + if (strlen(user) != (size_t)user_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!_Py_Gid_Converter(args[1], &basegid)) { + goto exit; + } + return_value = os_getgrouplist_impl(module, user, basegid); exit: return return_value; } -#endif /* defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)) */ +#endif /* defined(HAVE_GETGROUPLIST) && !defined(__APPLE__) */ -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) +#if defined(HAVE_GETGROUPS) + +PyDoc_STRVAR(os_getgroups__doc__, +"getgroups($module, /)\n" +"--\n" +"\n" +"Return list of supplemental group IDs for the process."); + +#define OS_GETGROUPS_METHODDEF \ + {"getgroups", (PyCFunction)os_getgroups, METH_NOARGS, os_getgroups__doc__}, + +static PyObject * +os_getgroups_impl(PyObject *module); + +static PyObject * +os_getgroups(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getgroups_impl(module); +} + +#endif /* defined(HAVE_GETGROUPS) */ + +#if defined(HAVE_INITGROUPS) && defined(__APPLE__) -PyDoc_STRVAR(os_sched_setscheduler__doc__, -"sched_setscheduler($module, pid, policy, param, /)\n" +PyDoc_STRVAR(os_initgroups__doc__, +"initgroups($module, username, gid, /)\n" "--\n" "\n" -"Set the scheduling policy for the process identified by pid.\n" +"Initialize the group access list.\n" "\n" -"If pid is 0, the calling process is changed.\n" -"param is an instance of sched_param."); +"Call the system initgroups() to initialize the group access list with all of\n" +"the groups of which the specified username is a member, plus the specified\n" +"group id."); -#define OS_SCHED_SETSCHEDULER_METHODDEF \ - {"sched_setscheduler", (PyCFunction)(void(*)(void))os_sched_setscheduler, METH_FASTCALL, os_sched_setscheduler__doc__}, +#define OS_INITGROUPS_METHODDEF \ + {"initgroups", (PyCFunction)(void(*)(void))os_initgroups, METH_FASTCALL, os_initgroups__doc__}, static PyObject * -os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy, - PyObject *param_obj); +os_initgroups_impl(PyObject *module, PyObject *oname, int gid); static PyObject * -os_sched_setscheduler(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +os_initgroups(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - pid_t pid; - int policy; - PyObject *param_obj; + PyObject *oname = NULL; + int gid; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "iO:sched_setscheduler", - &pid, &policy, ¶m_obj)) { + if (!_PyArg_CheckPositional("initgroups", nargs, 2, 2)) { goto exit; } - return_value = os_sched_setscheduler_impl(module, pid, policy, param_obj); + if (!PyUnicode_FSConverter(args[0], &oname)) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + gid = _PyLong_AsInt(args[1]); + if (gid == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os_initgroups_impl(module, oname, gid); exit: + /* Cleanup for oname */ + Py_XDECREF(oname); + return return_value; } -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETSCHEDULER) */ +#endif /* defined(HAVE_INITGROUPS) && defined(__APPLE__) */ -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETPARAM) +#if defined(HAVE_INITGROUPS) && !defined(__APPLE__) -PyDoc_STRVAR(os_sched_getparam__doc__, -"sched_getparam($module, pid, /)\n" +PyDoc_STRVAR(os_initgroups__doc__, +"initgroups($module, username, gid, /)\n" "--\n" "\n" -"Returns scheduling parameters for the process identified by pid.\n" +"Initialize the group access list.\n" "\n" -"If pid is 0, returns parameters for the calling process.\n" -"Return value is an instance of sched_param."); +"Call the system initgroups() to initialize the group access list with all of\n" +"the groups of which the specified username is a member, plus the specified\n" +"group id."); -#define OS_SCHED_GETPARAM_METHODDEF \ - {"sched_getparam", (PyCFunction)os_sched_getparam, METH_O, os_sched_getparam__doc__}, +#define OS_INITGROUPS_METHODDEF \ + {"initgroups", (PyCFunction)(void(*)(void))os_initgroups, METH_FASTCALL, os_initgroups__doc__}, static PyObject * -os_sched_getparam_impl(PyObject *module, pid_t pid); +os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid); static PyObject * -os_sched_getparam(PyObject *module, PyObject *arg) +os_initgroups(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - pid_t pid; + PyObject *oname = NULL; + gid_t gid; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getparam", &pid)) { + if (!_PyArg_CheckPositional("initgroups", nargs, 2, 2)) { goto exit; } - return_value = os_sched_getparam_impl(module, pid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETPARAM) */ - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETPARAM) - -PyDoc_STRVAR(os_sched_setparam__doc__, -"sched_setparam($module, pid, param, /)\n" -"--\n" -"\n" -"Set scheduling parameters for the process identified by pid.\n" -"\n" -"If pid is 0, sets parameters for the calling process.\n" -"param should be an instance of sched_param."); - -#define OS_SCHED_SETPARAM_METHODDEF \ - {"sched_setparam", (PyCFunction)(void(*)(void))os_sched_setparam, METH_FASTCALL, os_sched_setparam__doc__}, - -static PyObject * -os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj); - -static PyObject * -os_sched_setparam(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - pid_t pid; - PyObject *param_obj; - - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "O:sched_setparam", - &pid, ¶m_obj)) { + if (!PyUnicode_FSConverter(args[0], &oname)) { goto exit; } - return_value = os_sched_setparam_impl(module, pid, param_obj); + if (!_Py_Gid_Converter(args[1], &gid)) { + goto exit; + } + return_value = os_initgroups_impl(module, oname, gid); exit: + /* Cleanup for oname */ + Py_XDECREF(oname); + return return_value; } -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETPARAM) */ - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_RR_GET_INTERVAL) - -PyDoc_STRVAR(os_sched_rr_get_interval__doc__, -"sched_rr_get_interval($module, pid, /)\n" -"--\n" -"\n" -"Return the round-robin quantum for the process identified by pid, in seconds.\n" -"\n" -"Value returned is a float."); - -#define OS_SCHED_RR_GET_INTERVAL_METHODDEF \ - {"sched_rr_get_interval", (PyCFunction)os_sched_rr_get_interval, METH_O, os_sched_rr_get_interval__doc__}, - -static double -os_sched_rr_get_interval_impl(PyObject *module, pid_t pid); - -static PyObject * -os_sched_rr_get_interval(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - pid_t pid; - double _return_value; +#endif /* defined(HAVE_INITGROUPS) && !defined(__APPLE__) */ - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_rr_get_interval", &pid)) { +#if defined(HAVE_GETPGID) + +PyDoc_STRVAR(os_getpgid__doc__, +"getpgid($module, /, pid)\n" +"--\n" +"\n" +"Call the system call getpgid(), and return the result."); + +#define OS_GETPGID_METHODDEF \ + {"getpgid", (PyCFunction)(void(*)(void))os_getpgid, METH_FASTCALL|METH_KEYWORDS, os_getpgid__doc__}, + +static PyObject * +os_getpgid_impl(PyObject *module, pid_t pid); + +static PyObject * +os_getpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"pid", NULL}; + static _PyArg_Parser _parser = {"" _Py_PARSE_PID ":getpgid", _keywords, 0}; + pid_t pid; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &pid)) { + goto exit; + } + return_value = os_getpgid_impl(module, pid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETPGID) */ + +#if defined(HAVE_GETPGRP) + +PyDoc_STRVAR(os_getpgrp__doc__, +"getpgrp($module, /)\n" +"--\n" +"\n" +"Return the current process group id."); + +#define OS_GETPGRP_METHODDEF \ + {"getpgrp", (PyCFunction)os_getpgrp, METH_NOARGS, os_getpgrp__doc__}, + +static PyObject * +os_getpgrp_impl(PyObject *module); + +static PyObject * +os_getpgrp(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getpgrp_impl(module); +} + +#endif /* defined(HAVE_GETPGRP) */ + +#if defined(HAVE_SETPGRP) + +PyDoc_STRVAR(os_setpgrp__doc__, +"setpgrp($module, /)\n" +"--\n" +"\n" +"Make the current process the leader of its process group."); + +#define OS_SETPGRP_METHODDEF \ + {"setpgrp", (PyCFunction)os_setpgrp, METH_NOARGS, os_setpgrp__doc__}, + +static PyObject * +os_setpgrp_impl(PyObject *module); + +static PyObject * +os_setpgrp(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_setpgrp_impl(module); +} + +#endif /* defined(HAVE_SETPGRP) */ + +#if defined(HAVE_GETPPID) + +PyDoc_STRVAR(os_getppid__doc__, +"getppid($module, /)\n" +"--\n" +"\n" +"Return the parent\'s process id.\n" +"\n" +"If the parent process has already exited, Windows machines will still\n" +"return its id; others systems will return the id of the \'init\' process (1)."); + +#define OS_GETPPID_METHODDEF \ + {"getppid", (PyCFunction)os_getppid, METH_NOARGS, os_getppid__doc__}, + +static PyObject * +os_getppid_impl(PyObject *module); + +static PyObject * +os_getppid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getppid_impl(module); +} + +#endif /* defined(HAVE_GETPPID) */ + +#if defined(HAVE_GETLOGIN) + +PyDoc_STRVAR(os_getlogin__doc__, +"getlogin($module, /)\n" +"--\n" +"\n" +"Return the actual login name."); + +#define OS_GETLOGIN_METHODDEF \ + {"getlogin", (PyCFunction)os_getlogin, METH_NOARGS, os_getlogin__doc__}, + +static PyObject * +os_getlogin_impl(PyObject *module); + +static PyObject * +os_getlogin(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getlogin_impl(module); +} + +#endif /* defined(HAVE_GETLOGIN) */ + +#if defined(HAVE_GETUID) + +PyDoc_STRVAR(os_getuid__doc__, +"getuid($module, /)\n" +"--\n" +"\n" +"Return the current process\'s user id."); + +#define OS_GETUID_METHODDEF \ + {"getuid", (PyCFunction)os_getuid, METH_NOARGS, os_getuid__doc__}, + +static PyObject * +os_getuid_impl(PyObject *module); + +static PyObject * +os_getuid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getuid_impl(module); +} + +#endif /* defined(HAVE_GETUID) */ + +#if defined(HAVE_KILL) + +PyDoc_STRVAR(os_kill__doc__, +"kill($module, pid, signal, /)\n" +"--\n" +"\n" +"Kill a process with a signal."); + +#define OS_KILL_METHODDEF \ + {"kill", (PyCFunction)(void(*)(void))os_kill, METH_FASTCALL, os_kill__doc__}, + +static PyObject * +os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal); + +static PyObject * +os_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pid; + Py_ssize_t signal; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "n:kill", + &pid, &signal)) { + goto exit; + } + return_value = os_kill_impl(module, pid, signal); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KILL) */ + +#if defined(HAVE_KILLPG) + +PyDoc_STRVAR(os_killpg__doc__, +"killpg($module, pgid, signal, /)\n" +"--\n" +"\n" +"Kill a process group with a signal."); + +#define OS_KILLPG_METHODDEF \ + {"killpg", (PyCFunction)(void(*)(void))os_killpg, METH_FASTCALL, os_killpg__doc__}, + +static PyObject * +os_killpg_impl(PyObject *module, pid_t pgid, int signal); + +static PyObject * +os_killpg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pgid; + int signal; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "i:killpg", + &pgid, &signal)) { + goto exit; + } + return_value = os_killpg_impl(module, pgid, signal); + +exit: + return return_value; +} + +#endif /* defined(HAVE_KILLPG) */ + +#if defined(HAVE_PLOCK) + +PyDoc_STRVAR(os_plock__doc__, +"plock($module, op, /)\n" +"--\n" +"\n" +"Lock program segments into memory.\");"); + +#define OS_PLOCK_METHODDEF \ + {"plock", (PyCFunction)os_plock, METH_O, os_plock__doc__}, + +static PyObject * +os_plock_impl(PyObject *module, int op); + +static PyObject * +os_plock(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int op; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + op = _PyLong_AsInt(arg); + if (op == -1 && PyErr_Occurred()) { goto exit; } - _return_value = os_sched_rr_get_interval_impl(module, pid); - if ((_return_value == -1.0) && PyErr_Occurred()) { + return_value = os_plock_impl(module, op); + +exit: + return return_value; +} + +#endif /* defined(HAVE_PLOCK) */ + +#if defined(HAVE_SETUID) + +PyDoc_STRVAR(os_setuid__doc__, +"setuid($module, uid, /)\n" +"--\n" +"\n" +"Set the current process\'s user id."); + +#define OS_SETUID_METHODDEF \ + {"setuid", (PyCFunction)os_setuid, METH_O, os_setuid__doc__}, + +static PyObject * +os_setuid_impl(PyObject *module, uid_t uid); + +static PyObject * +os_setuid(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + uid_t uid; + + if (!_Py_Uid_Converter(arg, &uid)) { + goto exit; + } + return_value = os_setuid_impl(module, uid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETUID) */ + +#if defined(HAVE_SETEUID) + +PyDoc_STRVAR(os_seteuid__doc__, +"seteuid($module, euid, /)\n" +"--\n" +"\n" +"Set the current process\'s effective user id."); + +#define OS_SETEUID_METHODDEF \ + {"seteuid", (PyCFunction)os_seteuid, METH_O, os_seteuid__doc__}, + +static PyObject * +os_seteuid_impl(PyObject *module, uid_t euid); + +static PyObject * +os_seteuid(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + uid_t euid; + + if (!_Py_Uid_Converter(arg, &euid)) { + goto exit; + } + return_value = os_seteuid_impl(module, euid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETEUID) */ + +#if defined(HAVE_SETEGID) + +PyDoc_STRVAR(os_setegid__doc__, +"setegid($module, egid, /)\n" +"--\n" +"\n" +"Set the current process\'s effective group id."); + +#define OS_SETEGID_METHODDEF \ + {"setegid", (PyCFunction)os_setegid, METH_O, os_setegid__doc__}, + +static PyObject * +os_setegid_impl(PyObject *module, gid_t egid); + +static PyObject * +os_setegid(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + gid_t egid; + + if (!_Py_Gid_Converter(arg, &egid)) { + goto exit; + } + return_value = os_setegid_impl(module, egid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETEGID) */ + +#if defined(HAVE_SETREUID) + +PyDoc_STRVAR(os_setreuid__doc__, +"setreuid($module, ruid, euid, /)\n" +"--\n" +"\n" +"Set the current process\'s real and effective user ids."); + +#define OS_SETREUID_METHODDEF \ + {"setreuid", (PyCFunction)(void(*)(void))os_setreuid, METH_FASTCALL, os_setreuid__doc__}, + +static PyObject * +os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid); + +static PyObject * +os_setreuid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + uid_t ruid; + uid_t euid; + + if (!_PyArg_CheckPositional("setreuid", nargs, 2, 2)) { + goto exit; + } + if (!_Py_Uid_Converter(args[0], &ruid)) { goto exit; } - return_value = PyFloat_FromDouble(_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_RR_GET_INTERVAL) */ - -#if defined(HAVE_SCHED_H) - -PyDoc_STRVAR(os_sched_yield__doc__, -"sched_yield($module, /)\n" -"--\n" -"\n" -"Voluntarily relinquish the CPU."); - -#define OS_SCHED_YIELD_METHODDEF \ - {"sched_yield", (PyCFunction)os_sched_yield, METH_NOARGS, os_sched_yield__doc__}, - -static PyObject * -os_sched_yield_impl(PyObject *module); - -static PyObject * -os_sched_yield(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_sched_yield_impl(module); -} - -#endif /* defined(HAVE_SCHED_H) */ - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) + if (!_Py_Uid_Converter(args[1], &euid)) { + goto exit; + } + return_value = os_setreuid_impl(module, ruid, euid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETREUID) */ + +#if defined(HAVE_SETREGID) + +PyDoc_STRVAR(os_setregid__doc__, +"setregid($module, rgid, egid, /)\n" +"--\n" +"\n" +"Set the current process\'s real and effective group ids."); + +#define OS_SETREGID_METHODDEF \ + {"setregid", (PyCFunction)(void(*)(void))os_setregid, METH_FASTCALL, os_setregid__doc__}, + +static PyObject * +os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid); + +static PyObject * +os_setregid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + gid_t rgid; + gid_t egid; + + if (!_PyArg_CheckPositional("setregid", nargs, 2, 2)) { + goto exit; + } + if (!_Py_Gid_Converter(args[0], &rgid)) { + goto exit; + } + if (!_Py_Gid_Converter(args[1], &egid)) { + goto exit; + } + return_value = os_setregid_impl(module, rgid, egid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETREGID) */ + +#if defined(HAVE_SETGID) + +PyDoc_STRVAR(os_setgid__doc__, +"setgid($module, gid, /)\n" +"--\n" +"\n" +"Set the current process\'s group id."); + +#define OS_SETGID_METHODDEF \ + {"setgid", (PyCFunction)os_setgid, METH_O, os_setgid__doc__}, + +static PyObject * +os_setgid_impl(PyObject *module, gid_t gid); + +static PyObject * +os_setgid(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + gid_t gid; + + if (!_Py_Gid_Converter(arg, &gid)) { + goto exit; + } + return_value = os_setgid_impl(module, gid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETGID) */ + +#if defined(HAVE_SETGROUPS) + +PyDoc_STRVAR(os_setgroups__doc__, +"setgroups($module, groups, /)\n" +"--\n" +"\n" +"Set the groups of the current process to list."); + +#define OS_SETGROUPS_METHODDEF \ + {"setgroups", (PyCFunction)os_setgroups, METH_O, os_setgroups__doc__}, + +#endif /* defined(HAVE_SETGROUPS) */ + +#if defined(HAVE_WAIT3) + +PyDoc_STRVAR(os_wait3__doc__, +"wait3($module, /, options)\n" +"--\n" +"\n" +"Wait for completion of a child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status, rusage)"); + +#define OS_WAIT3_METHODDEF \ + {"wait3", (PyCFunction)(void(*)(void))os_wait3, METH_FASTCALL|METH_KEYWORDS, os_wait3__doc__}, + +static PyObject * +os_wait3_impl(PyObject *module, int options); + +static PyObject * +os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"options", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "wait3", 0}; + PyObject *argsbuf[1]; + int options; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + options = _PyLong_AsInt(args[0]); + if (options == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os_wait3_impl(module, options); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WAIT3) */ + +#if defined(HAVE_WAIT4) + +PyDoc_STRVAR(os_wait4__doc__, +"wait4($module, /, pid, options)\n" +"--\n" +"\n" +"Wait for completion of a specific child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status, rusage)"); + +#define OS_WAIT4_METHODDEF \ + {"wait4", (PyCFunction)(void(*)(void))os_wait4, METH_FASTCALL|METH_KEYWORDS, os_wait4__doc__}, + +static PyObject * +os_wait4_impl(PyObject *module, pid_t pid, int options); + +static PyObject * +os_wait4(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"pid", "options", NULL}; + static _PyArg_Parser _parser = {"" _Py_PARSE_PID "i:wait4", _keywords, 0}; + pid_t pid; + int options; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &pid, &options)) { + goto exit; + } + return_value = os_wait4_impl(module, pid, options); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WAIT4) */ + +#if (defined(HAVE_WAITID) && !defined(__APPLE__)) + +PyDoc_STRVAR(os_waitid__doc__, +"waitid($module, idtype, id, options, /)\n" +"--\n" +"\n" +"Returns the result of waiting for a process or processes.\n" +"\n" +" idtype\n" +" Must be one of be P_PID, P_PGID or P_ALL.\n" +" id\n" +" The id to wait on.\n" +" options\n" +" Constructed from the ORing of one or more of WEXITED, WSTOPPED\n" +" or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n" +"\n" +"Returns either waitid_result or None if WNOHANG is specified and there are\n" +"no children in a waitable state."); + +#define OS_WAITID_METHODDEF \ + {"waitid", (PyCFunction)(void(*)(void))os_waitid, METH_FASTCALL, os_waitid__doc__}, + +static PyObject * +os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options); + +static PyObject * +os_waitid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + idtype_t idtype; + id_t id; + int options; + + if (!_PyArg_ParseStack(args, nargs, "i" _Py_PARSE_PID "i:waitid", + &idtype, &id, &options)) { + goto exit; + } + return_value = os_waitid_impl(module, idtype, id, options); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_WAITID) && !defined(__APPLE__)) */ + +#if defined(HAVE_WAITPID) + +PyDoc_STRVAR(os_waitpid__doc__, +"waitpid($module, pid, options, /)\n" +"--\n" +"\n" +"Wait for completion of a given child process.\n" +"\n" +"Returns a tuple of information regarding the child process:\n" +" (pid, status)\n" +"\n" +"The options argument is ignored on Windows."); + +#define OS_WAITPID_METHODDEF \ + {"waitpid", (PyCFunction)(void(*)(void))os_waitpid, METH_FASTCALL, os_waitpid__doc__}, + +static PyObject * +os_waitpid_impl(PyObject *module, pid_t pid, int options); + +static PyObject * +os_waitpid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pid; + int options; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "i:waitpid", + &pid, &options)) { + goto exit; + } + return_value = os_waitpid_impl(module, pid, options); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WAITPID) */ + +#if !defined(HAVE_WAITPID) && defined(HAVE_CWAIT) + +PyDoc_STRVAR(os_waitpid__doc__, +"waitpid($module, pid, options, /)\n" +"--\n" +"\n" +"Wait for completion of a given process.\n" +"\n" +"Returns a tuple of information regarding the process:\n" +" (pid, status << 8)\n" +"\n" +"The options argument is ignored on Windows."); + +#define OS_WAITPID_METHODDEF \ + {"waitpid", (PyCFunction)(void(*)(void))os_waitpid, METH_FASTCALL, os_waitpid__doc__}, + +static PyObject * +os_waitpid_impl(PyObject *module, intptr_t pid, int options); + +static PyObject * +os_waitpid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + intptr_t pid; + int options; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_INTPTR "i:waitpid", + &pid, &options)) { + goto exit; + } + return_value = os_waitpid_impl(module, pid, options); + +exit: + return return_value; +} + +#endif /* !defined(HAVE_WAITPID) && defined(HAVE_CWAIT) */ + +#if defined(HAVE_WAIT) + +PyDoc_STRVAR(os_wait__doc__, +"wait($module, /)\n" +"--\n" +"\n" +"Wait for completion of a child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status)"); + +#define OS_WAIT_METHODDEF \ + {"wait", (PyCFunction)os_wait, METH_NOARGS, os_wait__doc__}, + +static PyObject * +os_wait_impl(PyObject *module); + +static PyObject * +os_wait(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_wait_impl(module); +} + +#endif /* defined(HAVE_WAIT) */ + +#if (defined(__linux__) && defined(__NR_pidfd_open)) -PyDoc_STRVAR(os_sched_setaffinity__doc__, -"sched_setaffinity($module, pid, mask, /)\n" +PyDoc_STRVAR(os_pidfd_open__doc__, +"pidfd_open($module, /, pid, flags=0)\n" "--\n" "\n" -"Set the CPU affinity of the process identified by pid to mask.\n" +"Return a file descriptor referring to the process *pid*.\n" "\n" -"mask should be an iterable of integers identifying CPUs."); +"The descriptor can be used to perform process management without races and\n" +"signals."); -#define OS_SCHED_SETAFFINITY_METHODDEF \ - {"sched_setaffinity", (PyCFunction)(void(*)(void))os_sched_setaffinity, METH_FASTCALL, os_sched_setaffinity__doc__}, +#define OS_PIDFD_OPEN_METHODDEF \ + {"pidfd_open", (PyCFunction)(void(*)(void))os_pidfd_open, METH_FASTCALL|METH_KEYWORDS, os_pidfd_open__doc__}, static PyObject * -os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask); +os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags); static PyObject * -os_sched_setaffinity(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"pid", "flags", NULL}; + static _PyArg_Parser _parser = {"" _Py_PARSE_PID "|O&:pidfd_open", _keywords, 0}; pid_t pid; - PyObject *mask; + unsigned int flags = 0; - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "O:sched_setaffinity", - &pid, &mask)) { + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &pid, _PyLong_UnsignedInt_Converter, &flags)) { goto exit; } - return_value = os_sched_setaffinity_impl(module, pid, mask); + return_value = os_pidfd_open_impl(module, pid, flags); exit: return return_value; } -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) */ +#endif /* (defined(__linux__) && defined(__NR_pidfd_open)) */ -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) +#if (defined(HAVE_READLINK) || defined(MS_WINDOWS)) -PyDoc_STRVAR(os_sched_getaffinity__doc__, -"sched_getaffinity($module, pid, /)\n" +PyDoc_STRVAR(os_readlink__doc__, +"readlink($module, /, path, *, dir_fd=None)\n" "--\n" "\n" -"Return the affinity of the process identified by pid (or the current process if zero).\n" +"Return a string representing the path to which the symbolic link points.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +"and path should be relative; path will then be relative to that directory.\n" "\n" -"The affinity is returned as a set of CPU identifiers."); +"dir_fd may not be implemented on your platform. If it is unavailable,\n" +"using it will raise a NotImplementedError."); -#define OS_SCHED_GETAFFINITY_METHODDEF \ - {"sched_getaffinity", (PyCFunction)os_sched_getaffinity, METH_O, os_sched_getaffinity__doc__}, +#define OS_READLINK_METHODDEF \ + {"readlink", (PyCFunction)(void(*)(void))os_readlink, METH_FASTCALL|METH_KEYWORDS, os_readlink__doc__}, static PyObject * -os_sched_getaffinity_impl(PyObject *module, pid_t pid); +os_readlink_impl(PyObject *module, path_t *path, int dir_fd); static PyObject * -os_sched_getaffinity(PyObject *module, PyObject *arg) +os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - pid_t pid; + static const char * const _keywords[] = {"path", "dir_fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "readlink", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":sched_getaffinity", &pid)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!READLINKAT_DIR_FD_CONVERTER(args[1], &dir_fd)) { goto exit; } - return_value = os_sched_getaffinity_impl(module, pid); +skip_optional_kwonly: + return_value = os_readlink_impl(module, &path, dir_fd); exit: - return return_value; -} - -#endif /* defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) */ - -#if (defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)) - -PyDoc_STRVAR(os_openpty__doc__, -"openpty($module, /)\n" -"--\n" -"\n" -"Open a pseudo-terminal.\n" -"\n" -"Return a tuple of (master_fd, slave_fd) containing open file descriptors\n" -"for both the master and slave ends."); - -#define OS_OPENPTY_METHODDEF \ - {"openpty", (PyCFunction)os_openpty, METH_NOARGS, os_openpty__doc__}, - -static PyObject * -os_openpty_impl(PyObject *module); - -static PyObject * -os_openpty(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_openpty_impl(module); -} - -#endif /* (defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)) */ - -#if defined(HAVE_FORKPTY) - -PyDoc_STRVAR(os_forkpty__doc__, -"forkpty($module, /)\n" -"--\n" -"\n" -"Fork a new process with a new pseudo-terminal as controlling tty.\n" -"\n" -"Returns a tuple of (pid, master_fd).\n" -"Like fork(), return pid of 0 to the child process,\n" -"and pid of child to the parent process.\n" -"To both, return fd of newly opened pseudo-terminal."); - -#define OS_FORKPTY_METHODDEF \ - {"forkpty", (PyCFunction)os_forkpty, METH_NOARGS, os_forkpty__doc__}, - -static PyObject * -os_forkpty_impl(PyObject *module); - -static PyObject * -os_forkpty(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_forkpty_impl(module); -} - -#endif /* defined(HAVE_FORKPTY) */ - -#if defined(HAVE_GETEGID) - -PyDoc_STRVAR(os_getegid__doc__, -"getegid($module, /)\n" -"--\n" -"\n" -"Return the current process\'s effective group id."); - -#define OS_GETEGID_METHODDEF \ - {"getegid", (PyCFunction)os_getegid, METH_NOARGS, os_getegid__doc__}, - -static PyObject * -os_getegid_impl(PyObject *module); - -static PyObject * -os_getegid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getegid_impl(module); -} - -#endif /* defined(HAVE_GETEGID) */ - -#if defined(HAVE_GETEUID) - -PyDoc_STRVAR(os_geteuid__doc__, -"geteuid($module, /)\n" -"--\n" -"\n" -"Return the current process\'s effective user id."); - -#define OS_GETEUID_METHODDEF \ - {"geteuid", (PyCFunction)os_geteuid, METH_NOARGS, os_geteuid__doc__}, - -static PyObject * -os_geteuid_impl(PyObject *module); - -static PyObject * -os_geteuid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_geteuid_impl(module); -} - -#endif /* defined(HAVE_GETEUID) */ - -#if defined(HAVE_GETGID) - -PyDoc_STRVAR(os_getgid__doc__, -"getgid($module, /)\n" -"--\n" -"\n" -"Return the current process\'s group id."); - -#define OS_GETGID_METHODDEF \ - {"getgid", (PyCFunction)os_getgid, METH_NOARGS, os_getgid__doc__}, - -static PyObject * -os_getgid_impl(PyObject *module); - -static PyObject * -os_getgid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getgid_impl(module); -} - -#endif /* defined(HAVE_GETGID) */ - -#if defined(HAVE_GETPID) - -PyDoc_STRVAR(os_getpid__doc__, -"getpid($module, /)\n" -"--\n" -"\n" -"Return the current process id."); - -#define OS_GETPID_METHODDEF \ - {"getpid", (PyCFunction)os_getpid, METH_NOARGS, os_getpid__doc__}, - -static PyObject * -os_getpid_impl(PyObject *module); + /* Cleanup for path */ + path_cleanup(&path); -static PyObject * -os_getpid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getpid_impl(module); + return return_value; } -#endif /* defined(HAVE_GETPID) */ - -#if defined(HAVE_GETGROUPLIST) && defined(__APPLE__) - -PyDoc_STRVAR(os_getgrouplist__doc__, -"getgrouplist($module, user, group, /)\n" -"--\n" -"\n" -"Returns a list of groups to which a user belongs.\n" -"\n" -" user\n" -" username to lookup\n" -" group\n" -" base group id of the user"); - -#define OS_GETGROUPLIST_METHODDEF \ - {"getgrouplist", (PyCFunction)(void(*)(void))os_getgrouplist, METH_FASTCALL, os_getgrouplist__doc__}, +#endif /* (defined(HAVE_READLINK) || defined(MS_WINDOWS)) */ -static PyObject * -os_getgrouplist_impl(PyObject *module, const char *user, int basegid); - -static PyObject * -os_getgrouplist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *user; - int basegid; - - if (!_PyArg_CheckPositional("getgrouplist", nargs, 2, 2)) { - goto exit; - } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("getgrouplist", "argument 1", "str", args[0]); - goto exit; - } - Py_ssize_t user_length; - user = PyUnicode_AsUTF8AndSize(args[0], &user_length); - if (user == NULL) { - goto exit; - } - if (strlen(user) != (size_t)user_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - basegid = _PyLong_AsInt(args[1]); - if (basegid == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_getgrouplist_impl(module, user, basegid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_GETGROUPLIST) && defined(__APPLE__) */ - -#if defined(HAVE_GETGROUPLIST) && !defined(__APPLE__) - -PyDoc_STRVAR(os_getgrouplist__doc__, -"getgrouplist($module, user, group, /)\n" -"--\n" -"\n" -"Returns a list of groups to which a user belongs.\n" -"\n" -" user\n" -" username to lookup\n" -" group\n" -" base group id of the user"); - -#define OS_GETGROUPLIST_METHODDEF \ - {"getgrouplist", (PyCFunction)(void(*)(void))os_getgrouplist, METH_FASTCALL, os_getgrouplist__doc__}, - -static PyObject * -os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid); - -static PyObject * -os_getgrouplist(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *user; - gid_t basegid; - - if (!_PyArg_CheckPositional("getgrouplist", nargs, 2, 2)) { - goto exit; - } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("getgrouplist", "argument 1", "str", args[0]); - goto exit; - } - Py_ssize_t user_length; - user = PyUnicode_AsUTF8AndSize(args[0], &user_length); - if (user == NULL) { - goto exit; - } - if (strlen(user) != (size_t)user_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - if (!_Py_Gid_Converter(args[1], &basegid)) { - goto exit; - } - return_value = os_getgrouplist_impl(module, user, basegid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_GETGROUPLIST) && !defined(__APPLE__) */ - -#if defined(HAVE_GETGROUPS) - -PyDoc_STRVAR(os_getgroups__doc__, -"getgroups($module, /)\n" -"--\n" -"\n" -"Return list of supplemental group IDs for the process."); - -#define OS_GETGROUPS_METHODDEF \ - {"getgroups", (PyCFunction)os_getgroups, METH_NOARGS, os_getgroups__doc__}, - -static PyObject * -os_getgroups_impl(PyObject *module); - -static PyObject * -os_getgroups(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getgroups_impl(module); -} - -#endif /* defined(HAVE_GETGROUPS) */ - -#if defined(HAVE_INITGROUPS) && defined(__APPLE__) - -PyDoc_STRVAR(os_initgroups__doc__, -"initgroups($module, username, gid, /)\n" -"--\n" -"\n" -"Initialize the group access list.\n" -"\n" -"Call the system initgroups() to initialize the group access list with all of\n" -"the groups of which the specified username is a member, plus the specified\n" -"group id."); - -#define OS_INITGROUPS_METHODDEF \ - {"initgroups", (PyCFunction)(void(*)(void))os_initgroups, METH_FASTCALL, os_initgroups__doc__}, - -static PyObject * -os_initgroups_impl(PyObject *module, PyObject *oname, int gid); - -static PyObject * -os_initgroups(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *oname = NULL; - int gid; - - if (!_PyArg_CheckPositional("initgroups", nargs, 2, 2)) { - goto exit; - } - if (!PyUnicode_FSConverter(args[0], &oname)) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - gid = _PyLong_AsInt(args[1]); - if (gid == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_initgroups_impl(module, oname, gid); - -exit: - /* Cleanup for oname */ - Py_XDECREF(oname); - - return return_value; -} - -#endif /* defined(HAVE_INITGROUPS) && defined(__APPLE__) */ - -#if defined(HAVE_INITGROUPS) && !defined(__APPLE__) - -PyDoc_STRVAR(os_initgroups__doc__, -"initgroups($module, username, gid, /)\n" -"--\n" -"\n" -"Initialize the group access list.\n" -"\n" -"Call the system initgroups() to initialize the group access list with all of\n" -"the groups of which the specified username is a member, plus the specified\n" -"group id."); - -#define OS_INITGROUPS_METHODDEF \ - {"initgroups", (PyCFunction)(void(*)(void))os_initgroups, METH_FASTCALL, os_initgroups__doc__}, - -static PyObject * -os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid); - -static PyObject * -os_initgroups(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *oname = NULL; - gid_t gid; - - if (!_PyArg_CheckPositional("initgroups", nargs, 2, 2)) { - goto exit; - } - if (!PyUnicode_FSConverter(args[0], &oname)) { - goto exit; - } - if (!_Py_Gid_Converter(args[1], &gid)) { - goto exit; - } - return_value = os_initgroups_impl(module, oname, gid); - -exit: - /* Cleanup for oname */ - Py_XDECREF(oname); - - return return_value; -} - -#endif /* defined(HAVE_INITGROUPS) && !defined(__APPLE__) */ - -#if defined(HAVE_GETPGID) - -PyDoc_STRVAR(os_getpgid__doc__, -"getpgid($module, /, pid)\n" -"--\n" -"\n" -"Call the system call getpgid(), and return the result."); - -#define OS_GETPGID_METHODDEF \ - {"getpgid", (PyCFunction)(void(*)(void))os_getpgid, METH_FASTCALL|METH_KEYWORDS, os_getpgid__doc__}, - -static PyObject * -os_getpgid_impl(PyObject *module, pid_t pid); - -static PyObject * -os_getpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"pid", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID ":getpgid", _keywords, 0}; - pid_t pid; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &pid)) { - goto exit; - } - return_value = os_getpgid_impl(module, pid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_GETPGID) */ - -#if defined(HAVE_GETPGRP) - -PyDoc_STRVAR(os_getpgrp__doc__, -"getpgrp($module, /)\n" -"--\n" -"\n" -"Return the current process group id."); - -#define OS_GETPGRP_METHODDEF \ - {"getpgrp", (PyCFunction)os_getpgrp, METH_NOARGS, os_getpgrp__doc__}, - -static PyObject * -os_getpgrp_impl(PyObject *module); - -static PyObject * -os_getpgrp(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getpgrp_impl(module); -} - -#endif /* defined(HAVE_GETPGRP) */ - -#if defined(HAVE_SETPGRP) - -PyDoc_STRVAR(os_setpgrp__doc__, -"setpgrp($module, /)\n" -"--\n" -"\n" -"Make the current process the leader of its process group."); - -#define OS_SETPGRP_METHODDEF \ - {"setpgrp", (PyCFunction)os_setpgrp, METH_NOARGS, os_setpgrp__doc__}, - -static PyObject * -os_setpgrp_impl(PyObject *module); - -static PyObject * -os_setpgrp(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_setpgrp_impl(module); -} - -#endif /* defined(HAVE_SETPGRP) */ - -#if defined(HAVE_GETPPID) - -PyDoc_STRVAR(os_getppid__doc__, -"getppid($module, /)\n" -"--\n" -"\n" -"Return the parent\'s process id.\n" -"\n" -"If the parent process has already exited, Windows machines will still\n" -"return its id; others systems will return the id of the \'init\' process (1)."); - -#define OS_GETPPID_METHODDEF \ - {"getppid", (PyCFunction)os_getppid, METH_NOARGS, os_getppid__doc__}, - -static PyObject * -os_getppid_impl(PyObject *module); - -static PyObject * -os_getppid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getppid_impl(module); -} - -#endif /* defined(HAVE_GETPPID) */ - -#if defined(HAVE_GETLOGIN) - -PyDoc_STRVAR(os_getlogin__doc__, -"getlogin($module, /)\n" -"--\n" -"\n" -"Return the actual login name."); - -#define OS_GETLOGIN_METHODDEF \ - {"getlogin", (PyCFunction)os_getlogin, METH_NOARGS, os_getlogin__doc__}, - -static PyObject * -os_getlogin_impl(PyObject *module); - -static PyObject * -os_getlogin(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getlogin_impl(module); -} - -#endif /* defined(HAVE_GETLOGIN) */ - -#if defined(HAVE_GETUID) - -PyDoc_STRVAR(os_getuid__doc__, -"getuid($module, /)\n" -"--\n" -"\n" -"Return the current process\'s user id."); - -#define OS_GETUID_METHODDEF \ - {"getuid", (PyCFunction)os_getuid, METH_NOARGS, os_getuid__doc__}, - -static PyObject * -os_getuid_impl(PyObject *module); - -static PyObject * -os_getuid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getuid_impl(module); -} - -#endif /* defined(HAVE_GETUID) */ - -#if defined(HAVE_KILL) - -PyDoc_STRVAR(os_kill__doc__, -"kill($module, pid, signal, /)\n" -"--\n" -"\n" -"Kill a process with a signal."); - -#define OS_KILL_METHODDEF \ - {"kill", (PyCFunction)(void(*)(void))os_kill, METH_FASTCALL, os_kill__doc__}, - -static PyObject * -os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal); - -static PyObject * -os_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - pid_t pid; - Py_ssize_t signal; - - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "n:kill", - &pid, &signal)) { - goto exit; - } - return_value = os_kill_impl(module, pid, signal); - -exit: - return return_value; -} - -#endif /* defined(HAVE_KILL) */ - -#if defined(HAVE_KILLPG) - -PyDoc_STRVAR(os_killpg__doc__, -"killpg($module, pgid, signal, /)\n" -"--\n" -"\n" -"Kill a process group with a signal."); - -#define OS_KILLPG_METHODDEF \ - {"killpg", (PyCFunction)(void(*)(void))os_killpg, METH_FASTCALL, os_killpg__doc__}, - -static PyObject * -os_killpg_impl(PyObject *module, pid_t pgid, int signal); - -static PyObject * -os_killpg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - pid_t pgid; - int signal; - - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "i:killpg", - &pgid, &signal)) { - goto exit; - } - return_value = os_killpg_impl(module, pgid, signal); - -exit: - return return_value; -} - -#endif /* defined(HAVE_KILLPG) */ - -#if defined(HAVE_PLOCK) - -PyDoc_STRVAR(os_plock__doc__, -"plock($module, op, /)\n" -"--\n" -"\n" -"Lock program segments into memory.\");"); - -#define OS_PLOCK_METHODDEF \ - {"plock", (PyCFunction)os_plock, METH_O, os_plock__doc__}, - -static PyObject * -os_plock_impl(PyObject *module, int op); - -static PyObject * -os_plock(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int op; - - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - op = _PyLong_AsInt(arg); - if (op == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_plock_impl(module, op); - -exit: - return return_value; -} - -#endif /* defined(HAVE_PLOCK) */ - -#if defined(HAVE_SETUID) - -PyDoc_STRVAR(os_setuid__doc__, -"setuid($module, uid, /)\n" -"--\n" -"\n" -"Set the current process\'s user id."); - -#define OS_SETUID_METHODDEF \ - {"setuid", (PyCFunction)os_setuid, METH_O, os_setuid__doc__}, - -static PyObject * -os_setuid_impl(PyObject *module, uid_t uid); - -static PyObject * -os_setuid(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - uid_t uid; - - if (!_Py_Uid_Converter(arg, &uid)) { - goto exit; - } - return_value = os_setuid_impl(module, uid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETUID) */ - -#if defined(HAVE_SETEUID) - -PyDoc_STRVAR(os_seteuid__doc__, -"seteuid($module, euid, /)\n" -"--\n" -"\n" -"Set the current process\'s effective user id."); - -#define OS_SETEUID_METHODDEF \ - {"seteuid", (PyCFunction)os_seteuid, METH_O, os_seteuid__doc__}, - -static PyObject * -os_seteuid_impl(PyObject *module, uid_t euid); - -static PyObject * -os_seteuid(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - uid_t euid; - - if (!_Py_Uid_Converter(arg, &euid)) { - goto exit; - } - return_value = os_seteuid_impl(module, euid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETEUID) */ - -#if defined(HAVE_SETEGID) - -PyDoc_STRVAR(os_setegid__doc__, -"setegid($module, egid, /)\n" -"--\n" -"\n" -"Set the current process\'s effective group id."); - -#define OS_SETEGID_METHODDEF \ - {"setegid", (PyCFunction)os_setegid, METH_O, os_setegid__doc__}, - -static PyObject * -os_setegid_impl(PyObject *module, gid_t egid); - -static PyObject * -os_setegid(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - gid_t egid; - - if (!_Py_Gid_Converter(arg, &egid)) { - goto exit; - } - return_value = os_setegid_impl(module, egid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETEGID) */ - -#if defined(HAVE_SETREUID) - -PyDoc_STRVAR(os_setreuid__doc__, -"setreuid($module, ruid, euid, /)\n" -"--\n" -"\n" -"Set the current process\'s real and effective user ids."); - -#define OS_SETREUID_METHODDEF \ - {"setreuid", (PyCFunction)(void(*)(void))os_setreuid, METH_FASTCALL, os_setreuid__doc__}, - -static PyObject * -os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid); - -static PyObject * -os_setreuid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - uid_t ruid; - uid_t euid; - - if (!_PyArg_CheckPositional("setreuid", nargs, 2, 2)) { - goto exit; - } - if (!_Py_Uid_Converter(args[0], &ruid)) { - goto exit; - } - if (!_Py_Uid_Converter(args[1], &euid)) { - goto exit; - } - return_value = os_setreuid_impl(module, ruid, euid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETREUID) */ - -#if defined(HAVE_SETREGID) - -PyDoc_STRVAR(os_setregid__doc__, -"setregid($module, rgid, egid, /)\n" -"--\n" -"\n" -"Set the current process\'s real and effective group ids."); - -#define OS_SETREGID_METHODDEF \ - {"setregid", (PyCFunction)(void(*)(void))os_setregid, METH_FASTCALL, os_setregid__doc__}, - -static PyObject * -os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid); - -static PyObject * -os_setregid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - gid_t rgid; - gid_t egid; - - if (!_PyArg_CheckPositional("setregid", nargs, 2, 2)) { - goto exit; - } - if (!_Py_Gid_Converter(args[0], &rgid)) { - goto exit; - } - if (!_Py_Gid_Converter(args[1], &egid)) { - goto exit; - } - return_value = os_setregid_impl(module, rgid, egid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETREGID) */ - -#if defined(HAVE_SETGID) - -PyDoc_STRVAR(os_setgid__doc__, -"setgid($module, gid, /)\n" -"--\n" -"\n" -"Set the current process\'s group id."); - -#define OS_SETGID_METHODDEF \ - {"setgid", (PyCFunction)os_setgid, METH_O, os_setgid__doc__}, - -static PyObject * -os_setgid_impl(PyObject *module, gid_t gid); - -static PyObject * -os_setgid(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - gid_t gid; - - if (!_Py_Gid_Converter(arg, &gid)) { - goto exit; - } - return_value = os_setgid_impl(module, gid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETGID) */ - -#if defined(HAVE_SETGROUPS) - -PyDoc_STRVAR(os_setgroups__doc__, -"setgroups($module, groups, /)\n" -"--\n" -"\n" -"Set the groups of the current process to list."); - -#define OS_SETGROUPS_METHODDEF \ - {"setgroups", (PyCFunction)os_setgroups, METH_O, os_setgroups__doc__}, - -#endif /* defined(HAVE_SETGROUPS) */ - -#if defined(HAVE_WAIT3) - -PyDoc_STRVAR(os_wait3__doc__, -"wait3($module, /, options)\n" -"--\n" -"\n" -"Wait for completion of a child process.\n" -"\n" -"Returns a tuple of information about the child process:\n" -" (pid, status, rusage)"); - -#define OS_WAIT3_METHODDEF \ - {"wait3", (PyCFunction)(void(*)(void))os_wait3, METH_FASTCALL|METH_KEYWORDS, os_wait3__doc__}, - -static PyObject * -os_wait3_impl(PyObject *module, int options); - -static PyObject * -os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"options", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "wait3", 0}; - PyObject *argsbuf[1]; - int options; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - options = _PyLong_AsInt(args[0]); - if (options == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_wait3_impl(module, options); - -exit: - return return_value; -} - -#endif /* defined(HAVE_WAIT3) */ - -#if defined(HAVE_WAIT4) - -PyDoc_STRVAR(os_wait4__doc__, -"wait4($module, /, pid, options)\n" -"--\n" -"\n" -"Wait for completion of a specific child process.\n" -"\n" -"Returns a tuple of information about the child process:\n" -" (pid, status, rusage)"); - -#define OS_WAIT4_METHODDEF \ - {"wait4", (PyCFunction)(void(*)(void))os_wait4, METH_FASTCALL|METH_KEYWORDS, os_wait4__doc__}, - -static PyObject * -os_wait4_impl(PyObject *module, pid_t pid, int options); - -static PyObject * -os_wait4(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"pid", "options", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID "i:wait4", _keywords, 0}; - pid_t pid; - int options; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &pid, &options)) { - goto exit; - } - return_value = os_wait4_impl(module, pid, options); - -exit: - return return_value; -} - -#endif /* defined(HAVE_WAIT4) */ - -#if (defined(HAVE_WAITID) && !defined(__APPLE__)) - -PyDoc_STRVAR(os_waitid__doc__, -"waitid($module, idtype, id, options, /)\n" -"--\n" -"\n" -"Returns the result of waiting for a process or processes.\n" -"\n" -" idtype\n" -" Must be one of be P_PID, P_PGID or P_ALL.\n" -" id\n" -" The id to wait on.\n" -" options\n" -" Constructed from the ORing of one or more of WEXITED, WSTOPPED\n" -" or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n" -"\n" -"Returns either waitid_result or None if WNOHANG is specified and there are\n" -"no children in a waitable state."); - -#define OS_WAITID_METHODDEF \ - {"waitid", (PyCFunction)(void(*)(void))os_waitid, METH_FASTCALL, os_waitid__doc__}, - -static PyObject * -os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options); - -static PyObject * -os_waitid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - idtype_t idtype; - id_t id; - int options; - - if (!_PyArg_ParseStack(args, nargs, "i" _Py_PARSE_PID "i:waitid", - &idtype, &id, &options)) { - goto exit; - } - return_value = os_waitid_impl(module, idtype, id, options); - -exit: - return return_value; -} - -#endif /* (defined(HAVE_WAITID) && !defined(__APPLE__)) */ - -#if defined(HAVE_WAITPID) - -PyDoc_STRVAR(os_waitpid__doc__, -"waitpid($module, pid, options, /)\n" -"--\n" -"\n" -"Wait for completion of a given child process.\n" -"\n" -"Returns a tuple of information regarding the child process:\n" -" (pid, status)\n" -"\n" -"The options argument is ignored on Windows."); - -#define OS_WAITPID_METHODDEF \ - {"waitpid", (PyCFunction)(void(*)(void))os_waitpid, METH_FASTCALL, os_waitpid__doc__}, - -static PyObject * -os_waitpid_impl(PyObject *module, pid_t pid, int options); - -static PyObject * -os_waitpid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - pid_t pid; - int options; - - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "i:waitpid", - &pid, &options)) { - goto exit; - } - return_value = os_waitpid_impl(module, pid, options); - -exit: - return return_value; -} - -#endif /* defined(HAVE_WAITPID) */ - -#if !defined(HAVE_WAITPID) && defined(HAVE_CWAIT) - -PyDoc_STRVAR(os_waitpid__doc__, -"waitpid($module, pid, options, /)\n" -"--\n" -"\n" -"Wait for completion of a given process.\n" -"\n" -"Returns a tuple of information regarding the process:\n" -" (pid, status << 8)\n" -"\n" -"The options argument is ignored on Windows."); - -#define OS_WAITPID_METHODDEF \ - {"waitpid", (PyCFunction)(void(*)(void))os_waitpid, METH_FASTCALL, os_waitpid__doc__}, - -static PyObject * -os_waitpid_impl(PyObject *module, intptr_t pid, int options); - -static PyObject * -os_waitpid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - intptr_t pid; - int options; - - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_INTPTR "i:waitpid", - &pid, &options)) { - goto exit; - } - return_value = os_waitpid_impl(module, pid, options); - -exit: - return return_value; -} - -#endif /* !defined(HAVE_WAITPID) && defined(HAVE_CWAIT) */ - -#if defined(HAVE_WAIT) - -PyDoc_STRVAR(os_wait__doc__, -"wait($module, /)\n" -"--\n" -"\n" -"Wait for completion of a child process.\n" -"\n" -"Returns a tuple of information about the child process:\n" -" (pid, status)"); - -#define OS_WAIT_METHODDEF \ - {"wait", (PyCFunction)os_wait, METH_NOARGS, os_wait__doc__}, - -static PyObject * -os_wait_impl(PyObject *module); - -static PyObject * -os_wait(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_wait_impl(module); -} - -#endif /* defined(HAVE_WAIT) */ - -#if (defined(__linux__) && defined(__NR_pidfd_open)) - -PyDoc_STRVAR(os_pidfd_open__doc__, -"pidfd_open($module, /, pid, flags=0)\n" -"--\n" -"\n" -"Return a file descriptor referring to the process *pid*.\n" -"\n" -"The descriptor can be used to perform process management without races and\n" -"signals."); - -#define OS_PIDFD_OPEN_METHODDEF \ - {"pidfd_open", (PyCFunction)(void(*)(void))os_pidfd_open, METH_FASTCALL|METH_KEYWORDS, os_pidfd_open__doc__}, - -static PyObject * -os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags); - -static PyObject * -os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"pid", "flags", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID "|O&:pidfd_open", _keywords, 0}; - pid_t pid; - unsigned int flags = 0; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &pid, _PyLong_UnsignedInt_Converter, &flags)) { - goto exit; - } - return_value = os_pidfd_open_impl(module, pid, flags); - -exit: - return return_value; -} - -#endif /* (defined(__linux__) && defined(__NR_pidfd_open)) */ - -#if (defined(HAVE_READLINK) || defined(MS_WINDOWS)) - -PyDoc_STRVAR(os_readlink__doc__, -"readlink($module, /, path, *, dir_fd=None)\n" -"--\n" -"\n" -"Return a string representing the path to which the symbolic link points.\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -"and path should be relative; path will then be relative to that directory.\n" -"\n" -"dir_fd may not be implemented on your platform. If it is unavailable,\n" -"using it will raise a NotImplementedError."); - -#define OS_READLINK_METHODDEF \ - {"readlink", (PyCFunction)(void(*)(void))os_readlink, METH_FASTCALL|METH_KEYWORDS, os_readlink__doc__}, - -static PyObject * -os_readlink_impl(PyObject *module, path_t *path, int dir_fd); - -static PyObject * -os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "readlink", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0); - int dir_fd = DEFAULT_DIR_FD; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!path_converter(args[0], &path)) { - goto exit; - } - if (!noptargs) { - goto skip_optional_kwonly; - } - if (!READLINKAT_DIR_FD_CONVERTER(args[1], &dir_fd)) { - goto exit; - } -skip_optional_kwonly: - return_value = os_readlink_impl(module, &path, dir_fd); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* (defined(HAVE_READLINK) || defined(MS_WINDOWS)) */ - -#if defined(HAVE_SYMLINK) - -PyDoc_STRVAR(os_symlink__doc__, -"symlink($module, /, src, dst, target_is_directory=False, *, dir_fd=None)\n" -"--\n" -"\n" -"Create a symbolic link pointing to src named dst.\n" -"\n" -"target_is_directory is required on Windows if the target is to be\n" -" interpreted as a directory. (On Windows, symlink requires\n" -" Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n" -" target_is_directory is ignored on non-Windows platforms.\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"dir_fd may not be implemented on your platform.\n" -" If it is unavailable, using it will raise a NotImplementedError."); - -#define OS_SYMLINK_METHODDEF \ - {"symlink", (PyCFunction)(void(*)(void))os_symlink, METH_FASTCALL|METH_KEYWORDS, os_symlink__doc__}, - -static PyObject * -os_symlink_impl(PyObject *module, path_t *src, path_t *dst, - int target_is_directory, int dir_fd); - -static PyObject * -os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "symlink", 0}; - PyObject *argsbuf[4]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); - path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0); - int target_is_directory = 0; - int dir_fd = DEFAULT_DIR_FD; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { - goto exit; - } - if (!path_converter(args[0], &src)) { - goto exit; - } - if (!path_converter(args[1], &dst)) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[2]) { - target_is_directory = PyObject_IsTrue(args[2]); - if (target_is_directory < 0) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - if (!SYMLINKAT_DIR_FD_CONVERTER(args[3], &dir_fd)) { - goto exit; - } -skip_optional_kwonly: - return_value = os_symlink_impl(module, &src, &dst, target_is_directory, dir_fd); - -exit: - /* Cleanup for src */ - path_cleanup(&src); - /* Cleanup for dst */ - path_cleanup(&dst); - - return return_value; -} - -#endif /* defined(HAVE_SYMLINK) */ - -#if defined(HAVE_TIMES) - -PyDoc_STRVAR(os_times__doc__, -"times($module, /)\n" -"--\n" -"\n" -"Return a collection containing process timing information.\n" -"\n" -"The object returned behaves like a named tuple with these fields:\n" -" (utime, stime, cutime, cstime, elapsed_time)\n" -"All fields are floating point numbers."); - -#define OS_TIMES_METHODDEF \ - {"times", (PyCFunction)os_times, METH_NOARGS, os_times__doc__}, - -static PyObject * -os_times_impl(PyObject *module); - -static PyObject * -os_times(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_times_impl(module); -} - -#endif /* defined(HAVE_TIMES) */ - -#if defined(HAVE_GETSID) - -PyDoc_STRVAR(os_getsid__doc__, -"getsid($module, pid, /)\n" -"--\n" -"\n" -"Call the system call getsid(pid) and return the result."); - -#define OS_GETSID_METHODDEF \ - {"getsid", (PyCFunction)os_getsid, METH_O, os_getsid__doc__}, - -static PyObject * -os_getsid_impl(PyObject *module, pid_t pid); - -static PyObject * -os_getsid(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - pid_t pid; - - if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":getsid", &pid)) { - goto exit; - } - return_value = os_getsid_impl(module, pid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_GETSID) */ - -#if defined(HAVE_SETSID) - -PyDoc_STRVAR(os_setsid__doc__, -"setsid($module, /)\n" -"--\n" -"\n" -"Call the system call setsid()."); - -#define OS_SETSID_METHODDEF \ - {"setsid", (PyCFunction)os_setsid, METH_NOARGS, os_setsid__doc__}, - -static PyObject * -os_setsid_impl(PyObject *module); - -static PyObject * -os_setsid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_setsid_impl(module); -} - -#endif /* defined(HAVE_SETSID) */ - -#if defined(HAVE_SETPGID) - -PyDoc_STRVAR(os_setpgid__doc__, -"setpgid($module, pid, pgrp, /)\n" -"--\n" -"\n" -"Call the system call setpgid(pid, pgrp)."); - -#define OS_SETPGID_METHODDEF \ - {"setpgid", (PyCFunction)(void(*)(void))os_setpgid, METH_FASTCALL, os_setpgid__doc__}, - -static PyObject * -os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp); - -static PyObject * -os_setpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - pid_t pid; - pid_t pgrp; - - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "" _Py_PARSE_PID ":setpgid", - &pid, &pgrp)) { - goto exit; - } - return_value = os_setpgid_impl(module, pid, pgrp); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETPGID) */ - -#if defined(HAVE_TCGETPGRP) - -PyDoc_STRVAR(os_tcgetpgrp__doc__, -"tcgetpgrp($module, fd, /)\n" -"--\n" -"\n" -"Return the process group associated with the terminal specified by fd."); - -#define OS_TCGETPGRP_METHODDEF \ - {"tcgetpgrp", (PyCFunction)os_tcgetpgrp, METH_O, os_tcgetpgrp__doc__}, - -static PyObject * -os_tcgetpgrp_impl(PyObject *module, int fd); - -static PyObject * -os_tcgetpgrp(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int fd; - - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(arg); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_tcgetpgrp_impl(module, fd); - -exit: - return return_value; -} - -#endif /* defined(HAVE_TCGETPGRP) */ - -#if defined(HAVE_TCSETPGRP) - -PyDoc_STRVAR(os_tcsetpgrp__doc__, -"tcsetpgrp($module, fd, pgid, /)\n" -"--\n" -"\n" -"Set the process group associated with the terminal specified by fd."); - -#define OS_TCSETPGRP_METHODDEF \ - {"tcsetpgrp", (PyCFunction)(void(*)(void))os_tcsetpgrp, METH_FASTCALL, os_tcsetpgrp__doc__}, - -static PyObject * -os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid); - -static PyObject * -os_tcsetpgrp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - pid_t pgid; - - if (!_PyArg_ParseStack(args, nargs, "i" _Py_PARSE_PID ":tcsetpgrp", - &fd, &pgid)) { - goto exit; - } - return_value = os_tcsetpgrp_impl(module, fd, pgid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_TCSETPGRP) */ - -PyDoc_STRVAR(os_open__doc__, -"open($module, /, path, flags, mode=511, *, dir_fd=None)\n" -"--\n" -"\n" -"Open a file for low level IO. Returns a file descriptor (integer).\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"dir_fd may not be implemented on your platform.\n" -" If it is unavailable, using it will raise a NotImplementedError."); - -#define OS_OPEN_METHODDEF \ - {"open", (PyCFunction)(void(*)(void))os_open, METH_FASTCALL|METH_KEYWORDS, os_open__doc__}, - -static int -os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd); - -static PyObject * -os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; - PyObject *argsbuf[4]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); - int flags; - int mode = 511; - int dir_fd = DEFAULT_DIR_FD; - int _return_value; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { - goto exit; - } - if (!path_converter(args[0], &path)) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - flags = _PyLong_AsInt(args[1]); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[2]) { - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - mode = _PyLong_AsInt(args[2]); - if (mode == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - if (!OPENAT_DIR_FD_CONVERTER(args[3], &dir_fd)) { - goto exit; - } -skip_optional_kwonly: - _return_value = os_open_impl(module, &path, flags, mode, dir_fd); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -PyDoc_STRVAR(os_close__doc__, -"close($module, /, fd)\n" -"--\n" -"\n" -"Close a file descriptor."); - -#define OS_CLOSE_METHODDEF \ - {"close", (PyCFunction)(void(*)(void))os_close, METH_FASTCALL|METH_KEYWORDS, os_close__doc__}, - -static PyObject * -os_close_impl(PyObject *module, int fd); - -static PyObject * -os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "close", 0}; - PyObject *argsbuf[1]; - int fd; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_close_impl(module, fd); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_closerange__doc__, -"closerange($module, fd_low, fd_high, /)\n" -"--\n" -"\n" -"Closes all file descriptors in [fd_low, fd_high), ignoring errors."); - -#define OS_CLOSERANGE_METHODDEF \ - {"closerange", (PyCFunction)(void(*)(void))os_closerange, METH_FASTCALL, os_closerange__doc__}, - -static PyObject * -os_closerange_impl(PyObject *module, int fd_low, int fd_high); - -static PyObject * -os_closerange(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd_low; - int fd_high; - - if (!_PyArg_CheckPositional("closerange", nargs, 2, 2)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd_low = _PyLong_AsInt(args[0]); - if (fd_low == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd_high = _PyLong_AsInt(args[1]); - if (fd_high == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_closerange_impl(module, fd_low, fd_high); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_dup__doc__, -"dup($module, fd, /)\n" -"--\n" -"\n" -"Return a duplicate of a file descriptor."); - -#define OS_DUP_METHODDEF \ - {"dup", (PyCFunction)os_dup, METH_O, os_dup__doc__}, - -static int -os_dup_impl(PyObject *module, int fd); - -static PyObject * -os_dup(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int fd; - int _return_value; - - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(arg); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - _return_value = os_dup_impl(module, fd); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_dup2__doc__, -"dup2($module, /, fd, fd2, inheritable=True)\n" -"--\n" -"\n" -"Duplicate file descriptor."); - -#define OS_DUP2_METHODDEF \ - {"dup2", (PyCFunction)(void(*)(void))os_dup2, METH_FASTCALL|METH_KEYWORDS, os_dup2__doc__}, - -static int -os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable); - -static PyObject * -os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", "fd2", "inheritable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dup2", 0}; - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - int fd; - int fd2; - int inheritable = 1; - int _return_value; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd2 = _PyLong_AsInt(args[1]); - if (fd2 == -1 && PyErr_Occurred()) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - inheritable = PyObject_IsTrue(args[2]); - if (inheritable < 0) { - goto exit; - } -skip_optional_pos: - _return_value = os_dup2_impl(module, fd, fd2, inheritable); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -#if defined(HAVE_LOCKF) - -PyDoc_STRVAR(os_lockf__doc__, -"lockf($module, fd, command, length, /)\n" -"--\n" -"\n" -"Apply, test or remove a POSIX lock on an open file descriptor.\n" -"\n" -" fd\n" -" An open file descriptor.\n" -" command\n" -" One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.\n" -" length\n" -" The number of bytes to lock, starting at the current position."); - -#define OS_LOCKF_METHODDEF \ - {"lockf", (PyCFunction)(void(*)(void))os_lockf, METH_FASTCALL, os_lockf__doc__}, - -static PyObject * -os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length); - -static PyObject * -os_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - int command; - Py_off_t length; - - if (!_PyArg_CheckPositional("lockf", nargs, 3, 3)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - command = _PyLong_AsInt(args[1]); - if (command == -1 && PyErr_Occurred()) { - goto exit; - } - if (!Py_off_t_converter(args[2], &length)) { - goto exit; - } - return_value = os_lockf_impl(module, fd, command, length); - -exit: - return return_value; -} - -#endif /* defined(HAVE_LOCKF) */ - -PyDoc_STRVAR(os_lseek__doc__, -"lseek($module, fd, position, how, /)\n" -"--\n" -"\n" -"Set the position of a file descriptor. Return the new position.\n" -"\n" -"Return the new cursor position in number of bytes\n" -"relative to the beginning of the file."); - -#define OS_LSEEK_METHODDEF \ - {"lseek", (PyCFunction)(void(*)(void))os_lseek, METH_FASTCALL, os_lseek__doc__}, - -static Py_off_t -os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how); - -static PyObject * -os_lseek(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - Py_off_t position; - int how; - Py_off_t _return_value; - - if (!_PyArg_CheckPositional("lseek", nargs, 3, 3)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (!Py_off_t_converter(args[1], &position)) { - goto exit; - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - how = _PyLong_AsInt(args[2]); - if (how == -1 && PyErr_Occurred()) { - goto exit; - } - _return_value = os_lseek_impl(module, fd, position, how); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromPy_off_t(_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_read__doc__, -"read($module, fd, length, /)\n" -"--\n" -"\n" -"Read from a file descriptor. Returns a bytes object."); - -#define OS_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))os_read, METH_FASTCALL, os_read__doc__}, - -static PyObject * -os_read_impl(PyObject *module, int fd, Py_ssize_t length); - -static PyObject * -os_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - Py_ssize_t length; - - if (!_PyArg_CheckPositional("read", nargs, 2, 2)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - length = ival; - } - return_value = os_read_impl(module, fd, length); - -exit: - return return_value; -} - -#if defined(HAVE_READV) - -PyDoc_STRVAR(os_readv__doc__, -"readv($module, fd, buffers, /)\n" -"--\n" -"\n" -"Read from a file descriptor fd into an iterable of buffers.\n" -"\n" -"The buffers should be mutable buffers accepting bytes.\n" -"readv will transfer data into each buffer until it is full\n" -"and then move on to the next buffer in the sequence to hold\n" -"the rest of the data.\n" -"\n" -"readv returns the total number of bytes read,\n" -"which may be less than the total capacity of all the buffers."); - -#define OS_READV_METHODDEF \ - {"readv", (PyCFunction)(void(*)(void))os_readv, METH_FASTCALL, os_readv__doc__}, - -static Py_ssize_t -os_readv_impl(PyObject *module, int fd, PyObject *buffers); - -static PyObject * -os_readv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - PyObject *buffers; - Py_ssize_t _return_value; - - if (!_PyArg_CheckPositional("readv", nargs, 2, 2)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - buffers = args[1]; - _return_value = os_readv_impl(module, fd, buffers); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_READV) */ - -#if defined(HAVE_PREAD) - -PyDoc_STRVAR(os_pread__doc__, -"pread($module, fd, length, offset, /)\n" -"--\n" -"\n" -"Read a number of bytes from a file descriptor starting at a particular offset.\n" -"\n" -"Read length bytes from file descriptor fd, starting at offset bytes from\n" -"the beginning of the file. The file offset remains unchanged."); - -#define OS_PREAD_METHODDEF \ - {"pread", (PyCFunction)(void(*)(void))os_pread, METH_FASTCALL, os_pread__doc__}, - -static PyObject * -os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset); - -static PyObject * -os_pread(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - Py_ssize_t length; - Py_off_t offset; - - if (!_PyArg_CheckPositional("pread", nargs, 3, 3)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[1]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - length = ival; - } - if (!Py_off_t_converter(args[2], &offset)) { - goto exit; - } - return_value = os_pread_impl(module, fd, length, offset); - -exit: - return return_value; -} - -#endif /* defined(HAVE_PREAD) */ - -#if (defined(HAVE_PREADV) || defined (HAVE_PREADV2)) - -PyDoc_STRVAR(os_preadv__doc__, -"preadv($module, fd, buffers, offset, flags=0, /)\n" -"--\n" -"\n" -"Reads from a file descriptor into a number of mutable bytes-like objects.\n" -"\n" -"Combines the functionality of readv() and pread(). As readv(), it will\n" -"transfer data into each buffer until it is full and then move on to the next\n" -"buffer in the sequence to hold the rest of the data. Its fourth argument,\n" -"specifies the file offset at which the input operation is to be performed. It\n" -"will return the total number of bytes read (which can be less than the total\n" -"capacity of all the objects).\n" -"\n" -"The flags argument contains a bitwise OR of zero or more of the following flags:\n" -"\n" -"- RWF_HIPRI\n" -"- RWF_NOWAIT\n" -"\n" -"Using non-zero flags requires Linux 4.6 or newer."); - -#define OS_PREADV_METHODDEF \ - {"preadv", (PyCFunction)(void(*)(void))os_preadv, METH_FASTCALL, os_preadv__doc__}, - -static Py_ssize_t -os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, - int flags); - -static PyObject * -os_preadv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - PyObject *buffers; - Py_off_t offset; - int flags = 0; - Py_ssize_t _return_value; - - if (!_PyArg_CheckPositional("preadv", nargs, 3, 4)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - buffers = args[1]; - if (!Py_off_t_converter(args[2], &offset)) { - goto exit; - } - if (nargs < 4) { - goto skip_optional; - } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - flags = _PyLong_AsInt(args[3]); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional: - _return_value = os_preadv_impl(module, fd, buffers, offset, flags); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -#endif /* (defined(HAVE_PREADV) || defined (HAVE_PREADV2)) */ - -PyDoc_STRVAR(os_write__doc__, -"write($module, fd, data, /)\n" -"--\n" -"\n" -"Write a bytes object to a file descriptor."); - -#define OS_WRITE_METHODDEF \ - {"write", (PyCFunction)(void(*)(void))os_write, METH_FASTCALL, os_write__doc__}, - -static Py_ssize_t -os_write_impl(PyObject *module, int fd, Py_buffer *data); - -static PyObject * -os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - Py_buffer data = {NULL, NULL}; - Py_ssize_t _return_value; - - if (!_PyArg_CheckPositional("write", nargs, 2, 2)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyObject_GetBuffer(args[1], &data, PyBUF_SIMPLE) != 0) { - goto exit; - } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("write", "argument 2", "contiguous buffer", args[1]); - goto exit; - } - _return_value = os_write_impl(module, fd, &data); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -#if defined(HAVE_SENDFILE) && defined(__APPLE__) - -PyDoc_STRVAR(os_sendfile__doc__, -"sendfile($module, /, out_fd, in_fd, offset, count, headers=(),\n" -" trailers=(), flags=0)\n" -"--\n" -"\n" -"Copy count bytes from file descriptor in_fd to file descriptor out_fd."); - -#define OS_SENDFILE_METHODDEF \ - {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, - -static PyObject * -os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, - Py_off_t sbytes, PyObject *headers, PyObject *trailers, - int flags); - -static PyObject * -os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; - PyObject *argsbuf[7]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; - int out_fd; - int in_fd; - Py_off_t offset; - Py_off_t sbytes; - PyObject *headers = NULL; - PyObject *trailers = NULL; - int flags = 0; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 7, 0, argsbuf); - if (!args) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - out_fd = _PyLong_AsInt(args[0]); - if (out_fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - in_fd = _PyLong_AsInt(args[1]); - if (in_fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (!Py_off_t_converter(args[2], &offset)) { - goto exit; - } - if (!Py_off_t_converter(args[3], &sbytes)) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[4]) { - headers = args[4]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[5]) { - trailers = args[5]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - flags = _PyLong_AsInt(args[6]); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional_pos: - return_value = os_sendfile_impl(module, out_fd, in_fd, offset, sbytes, headers, trailers, flags); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SENDFILE) && defined(__APPLE__) */ - -#if defined(HAVE_SENDFILE) && !defined(__APPLE__) && (defined(__FreeBSD__) || defined(__DragonFly__)) - -PyDoc_STRVAR(os_sendfile__doc__, -"sendfile($module, /, out_fd, in_fd, offset, count, headers=(),\n" -" trailers=(), flags=0)\n" -"--\n" -"\n" -"Copy count bytes from file descriptor in_fd to file descriptor out_fd."); - -#define OS_SENDFILE_METHODDEF \ - {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, - -static PyObject * -os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, - Py_ssize_t count, PyObject *headers, PyObject *trailers, - int flags); - -static PyObject * -os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; - PyObject *argsbuf[7]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; - int out_fd; - int in_fd; - Py_off_t offset; - Py_ssize_t count; - PyObject *headers = NULL; - PyObject *trailers = NULL; - int flags = 0; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 7, 0, argsbuf); - if (!args) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - out_fd = _PyLong_AsInt(args[0]); - if (out_fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - in_fd = _PyLong_AsInt(args[1]); - if (in_fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (!Py_off_t_converter(args[2], &offset)) { - goto exit; - } - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[3]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - count = ival; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[4]) { - headers = args[4]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[5]) { - trailers = args[5]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (PyFloat_Check(args[6])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - flags = _PyLong_AsInt(args[6]); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional_pos: - return_value = os_sendfile_impl(module, out_fd, in_fd, offset, count, headers, trailers, flags); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SENDFILE) && !defined(__APPLE__) && (defined(__FreeBSD__) || defined(__DragonFly__)) */ - -#if defined(HAVE_SENDFILE) && !defined(__APPLE__) && !(defined(__FreeBSD__) || defined(__DragonFly__)) - -PyDoc_STRVAR(os_sendfile__doc__, -"sendfile($module, /, out_fd, in_fd, offset, count)\n" -"--\n" -"\n" -"Copy count bytes from file descriptor in_fd to file descriptor out_fd."); - -#define OS_SENDFILE_METHODDEF \ - {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, - -static PyObject * -os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, - Py_ssize_t count); - -static PyObject * -os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; - PyObject *argsbuf[4]; - int out_fd; - int in_fd; - PyObject *offobj; - Py_ssize_t count; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 4, 0, argsbuf); - if (!args) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - out_fd = _PyLong_AsInt(args[0]); - if (out_fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - in_fd = _PyLong_AsInt(args[1]); - if (in_fd == -1 && PyErr_Occurred()) { - goto exit; - } - offobj = args[2]; - if (PyFloat_Check(args[3])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[3]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - count = ival; - } - return_value = os_sendfile_impl(module, out_fd, in_fd, offobj, count); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SENDFILE) && !defined(__APPLE__) && !(defined(__FreeBSD__) || defined(__DragonFly__)) */ - -#if defined(__APPLE__) - -PyDoc_STRVAR(os__fcopyfile__doc__, -"_fcopyfile($module, in_fd, out_fd, flags, /)\n" -"--\n" -"\n" -"Efficiently copy content or metadata of 2 regular file descriptors (macOS)."); - -#define OS__FCOPYFILE_METHODDEF \ - {"_fcopyfile", (PyCFunction)(void(*)(void))os__fcopyfile, METH_FASTCALL, os__fcopyfile__doc__}, - -static PyObject * -os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags); - -static PyObject * -os__fcopyfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int in_fd; - int out_fd; - int flags; - - if (!_PyArg_CheckPositional("_fcopyfile", nargs, 3, 3)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - in_fd = _PyLong_AsInt(args[0]); - if (in_fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - out_fd = _PyLong_AsInt(args[1]); - if (out_fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyFloat_Check(args[2])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - flags = _PyLong_AsInt(args[2]); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os__fcopyfile_impl(module, in_fd, out_fd, flags); - -exit: - return return_value; -} - -#endif /* defined(__APPLE__) */ - -PyDoc_STRVAR(os_fstat__doc__, -"fstat($module, /, fd)\n" -"--\n" -"\n" -"Perform a stat system call on the given file descriptor.\n" -"\n" -"Like stat(), but for an open file descriptor.\n" -"Equivalent to os.stat(fd)."); - -#define OS_FSTAT_METHODDEF \ - {"fstat", (PyCFunction)(void(*)(void))os_fstat, METH_FASTCALL|METH_KEYWORDS, os_fstat__doc__}, - -static PyObject * -os_fstat_impl(PyObject *module, int fd); - -static PyObject * -os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fstat", 0}; - PyObject *argsbuf[1]; - int fd; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_fstat_impl(module, fd); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_isatty__doc__, -"isatty($module, fd, /)\n" -"--\n" -"\n" -"Return True if the fd is connected to a terminal.\n" -"\n" -"Return True if the file descriptor is an open file descriptor\n" -"connected to the slave end of a terminal."); - -#define OS_ISATTY_METHODDEF \ - {"isatty", (PyCFunction)os_isatty, METH_O, os_isatty__doc__}, - -static int -os_isatty_impl(PyObject *module, int fd); - -static PyObject * -os_isatty(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int fd; - int _return_value; - - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(arg); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - _return_value = os_isatty_impl(module, fd); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -#if defined(HAVE_PIPE) - -PyDoc_STRVAR(os_pipe__doc__, -"pipe($module, /)\n" -"--\n" -"\n" -"Create a pipe.\n" -"\n" -"Returns a tuple of two file descriptors:\n" -" (read_fd, write_fd)"); - -#define OS_PIPE_METHODDEF \ - {"pipe", (PyCFunction)os_pipe, METH_NOARGS, os_pipe__doc__}, - -static PyObject * -os_pipe_impl(PyObject *module); - -static PyObject * -os_pipe(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_pipe_impl(module); -} - -#endif /* defined(HAVE_PIPE) */ - -#if defined(HAVE_PIPE2) - -PyDoc_STRVAR(os_pipe2__doc__, -"pipe2($module, flags, /)\n" -"--\n" -"\n" -"Create a pipe with flags set atomically.\n" -"\n" -"Returns a tuple of two file descriptors:\n" -" (read_fd, write_fd)\n" -"\n" -"flags can be constructed by ORing together one or more of these values:\n" -"O_NONBLOCK, O_CLOEXEC."); - -#define OS_PIPE2_METHODDEF \ - {"pipe2", (PyCFunction)os_pipe2, METH_O, os_pipe2__doc__}, - -static PyObject * -os_pipe2_impl(PyObject *module, int flags); - -static PyObject * -os_pipe2(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int flags; - - if (PyFloat_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - flags = _PyLong_AsInt(arg); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = os_pipe2_impl(module, flags); - -exit: - return return_value; -} - -#endif /* defined(HAVE_PIPE2) */ - -#if defined(HAVE_WRITEV) - -PyDoc_STRVAR(os_writev__doc__, -"writev($module, fd, buffers, /)\n" -"--\n" -"\n" -"Iterate over buffers, and write the contents of each to a file descriptor.\n" -"\n" -"Returns the total number of bytes written.\n" -"buffers must be a sequence of bytes-like objects."); - -#define OS_WRITEV_METHODDEF \ - {"writev", (PyCFunction)(void(*)(void))os_writev, METH_FASTCALL, os_writev__doc__}, - -static Py_ssize_t -os_writev_impl(PyObject *module, int fd, PyObject *buffers); - -static PyObject * -os_writev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - PyObject *buffers; - Py_ssize_t _return_value; - - if (!_PyArg_CheckPositional("writev", nargs, 2, 2)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - buffers = args[1]; - _return_value = os_writev_impl(module, fd, buffers); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_WRITEV) */ - -#if defined(HAVE_PWRITE) - -PyDoc_STRVAR(os_pwrite__doc__, -"pwrite($module, fd, buffer, offset, /)\n" -"--\n" -"\n" -"Write bytes to a file descriptor starting at a particular offset.\n" -"\n" -"Write buffer to fd, starting at offset bytes from the beginning of\n" -"the file. Returns the number of bytes writte. Does not change the\n" -"current file offset."); - -#define OS_PWRITE_METHODDEF \ - {"pwrite", (PyCFunction)(void(*)(void))os_pwrite, METH_FASTCALL, os_pwrite__doc__}, - -static Py_ssize_t -os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset); - -static PyObject * -os_pwrite(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - Py_buffer buffer = {NULL, NULL}; - Py_off_t offset; - Py_ssize_t _return_value; - - if (!_PyArg_CheckPositional("pwrite", nargs, 3, 3)) { - goto exit; - } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { - goto exit; - } - if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { +#if defined(HAVE_SYMLINK) + +PyDoc_STRVAR(os_symlink__doc__, +"symlink($module, /, src, dst, target_is_directory=False, *, dir_fd=None)\n" +"--\n" +"\n" +"Create a symbolic link pointing to src named dst.\n" +"\n" +"target_is_directory is required on Windows if the target is to be\n" +" interpreted as a directory. (On Windows, symlink requires\n" +" Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n" +" target_is_directory is ignored on non-Windows platforms.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_SYMLINK_METHODDEF \ + {"symlink", (PyCFunction)(void(*)(void))os_symlink, METH_FASTCALL|METH_KEYWORDS, os_symlink__doc__}, + +static PyObject * +os_symlink_impl(PyObject *module, path_t *src, path_t *dst, + int target_is_directory, int dir_fd); + +static PyObject * +os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "symlink", 0}; + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0); + int target_is_directory = 0; + int dir_fd = DEFAULT_DIR_FD; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &src)) { goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("pwrite", "argument 2", "contiguous buffer", args[1]); + if (!path_converter(args[1], &dst)) { goto exit; } - if (!Py_off_t_converter(args[2], &offset)) { - goto exit; + if (!noptargs) { + goto skip_optional_pos; } - _return_value = os_pwrite_impl(module, fd, &buffer, offset); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; + if (args[2]) { + target_is_directory = PyObject_IsTrue(args[2]); + if (target_is_directory < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - /* Cleanup for buffer */ - if (buffer.obj) { - PyBuffer_Release(&buffer); +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; } - - return return_value; -} - -#endif /* defined(HAVE_PWRITE) */ - -#if (defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)) - -PyDoc_STRVAR(os_pwritev__doc__, -"pwritev($module, fd, buffers, offset, flags=0, /)\n" -"--\n" -"\n" -"Writes the contents of bytes-like objects to a file descriptor at a given offset.\n" -"\n" -"Combines the functionality of writev() and pwrite(). All buffers must be a sequence\n" -"of bytes-like objects. Buffers are processed in array order. Entire contents of first\n" -"buffer is written before proceeding to second, and so on. The operating system may\n" -"set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.\n" -"This function writes the contents of each object to the file descriptor and returns\n" -"the total number of bytes written.\n" -"\n" -"The flags argument contains a bitwise OR of zero or more of the following flags:\n" -"\n" -"- RWF_DSYNC\n" -"- RWF_SYNC\n" -"\n" -"Using non-zero flags requires Linux 4.7 or newer."); - -#define OS_PWRITEV_METHODDEF \ - {"pwritev", (PyCFunction)(void(*)(void))os_pwritev, METH_FASTCALL, os_pwritev__doc__}, - -static Py_ssize_t -os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, - int flags); - -static PyObject * -os_pwritev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - PyObject *buffers; - Py_off_t offset; - int flags = 0; - Py_ssize_t _return_value; - - if (!_PyArg_CheckPositional("pwritev", nargs, 3, 4)) { + if (!SYMLINKAT_DIR_FD_CONVERTER(args[3], &dir_fd)) { goto exit; } - if (PyFloat_Check(args[0])) { +skip_optional_kwonly: + return_value = os_symlink_impl(module, &src, &dst, target_is_directory, dir_fd); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +#endif /* defined(HAVE_SYMLINK) */ + +#if defined(HAVE_TIMES) + +PyDoc_STRVAR(os_times__doc__, +"times($module, /)\n" +"--\n" +"\n" +"Return a collection containing process timing information.\n" +"\n" +"The object returned behaves like a named tuple with these fields:\n" +" (utime, stime, cutime, cstime, elapsed_time)\n" +"All fields are floating point numbers."); + +#define OS_TIMES_METHODDEF \ + {"times", (PyCFunction)os_times, METH_NOARGS, os_times__doc__}, + +static PyObject * +os_times_impl(PyObject *module); + +static PyObject * +os_times(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_times_impl(module); +} + +#endif /* defined(HAVE_TIMES) */ + +#if defined(HAVE_GETSID) + +PyDoc_STRVAR(os_getsid__doc__, +"getsid($module, pid, /)\n" +"--\n" +"\n" +"Call the system call getsid(pid) and return the result."); + +#define OS_GETSID_METHODDEF \ + {"getsid", (PyCFunction)os_getsid, METH_O, os_getsid__doc__}, + +static PyObject * +os_getsid_impl(PyObject *module, pid_t pid); + +static PyObject * +os_getsid(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + pid_t pid; + + if (!PyArg_Parse(arg, "" _Py_PARSE_PID ":getsid", &pid)) { + goto exit; + } + return_value = os_getsid_impl(module, pid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETSID) */ + +#if defined(HAVE_SETSID) + +PyDoc_STRVAR(os_setsid__doc__, +"setsid($module, /)\n" +"--\n" +"\n" +"Call the system call setsid()."); + +#define OS_SETSID_METHODDEF \ + {"setsid", (PyCFunction)os_setsid, METH_NOARGS, os_setsid__doc__}, + +static PyObject * +os_setsid_impl(PyObject *module); + +static PyObject * +os_setsid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_setsid_impl(module); +} + +#endif /* defined(HAVE_SETSID) */ + +#if defined(HAVE_SETPGID) + +PyDoc_STRVAR(os_setpgid__doc__, +"setpgid($module, pid, pgrp, /)\n" +"--\n" +"\n" +"Call the system call setpgid(pid, pgrp)."); + +#define OS_SETPGID_METHODDEF \ + {"setpgid", (PyCFunction)(void(*)(void))os_setpgid, METH_FASTCALL, os_setpgid__doc__}, + +static PyObject * +os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp); + +static PyObject * +os_setpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + pid_t pid; + pid_t pgrp; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_PID "" _Py_PARSE_PID ":setpgid", + &pid, &pgrp)) { + goto exit; + } + return_value = os_setpgid_impl(module, pid, pgrp); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETPGID) */ + +#if defined(HAVE_TCGETPGRP) + +PyDoc_STRVAR(os_tcgetpgrp__doc__, +"tcgetpgrp($module, fd, /)\n" +"--\n" +"\n" +"Return the process group associated with the terminal specified by fd."); + +#define OS_TCGETPGRP_METHODDEF \ + {"tcgetpgrp", (PyCFunction)os_tcgetpgrp, METH_O, os_tcgetpgrp__doc__}, + +static PyObject * +os_tcgetpgrp_impl(PyObject *module, int fd); + +static PyObject * +os_tcgetpgrp(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } - fd = _PyLong_AsInt(args[0]); + goto exit; + } + fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } - buffers = args[1]; - if (!Py_off_t_converter(args[2], &offset)) { + return_value = os_tcgetpgrp_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TCGETPGRP) */ + +#if defined(HAVE_TCSETPGRP) + +PyDoc_STRVAR(os_tcsetpgrp__doc__, +"tcsetpgrp($module, fd, pgid, /)\n" +"--\n" +"\n" +"Set the process group associated with the terminal specified by fd."); + +#define OS_TCSETPGRP_METHODDEF \ + {"tcsetpgrp", (PyCFunction)(void(*)(void))os_tcsetpgrp, METH_FASTCALL, os_tcsetpgrp__doc__}, + +static PyObject * +os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid); + +static PyObject * +os_tcsetpgrp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + pid_t pgid; + + if (!_PyArg_ParseStack(args, nargs, "i" _Py_PARSE_PID ":tcsetpgrp", + &fd, &pgid)) { + goto exit; + } + return_value = os_tcsetpgrp_impl(module, fd, pgid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_TCSETPGRP) */ + +PyDoc_STRVAR(os_open__doc__, +"open($module, /, path, flags, mode=511, *, dir_fd=None)\n" +"--\n" +"\n" +"Open a file for low level IO. Returns a file descriptor (integer).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_OPEN_METHODDEF \ + {"open", (PyCFunction)(void(*)(void))os_open, METH_FASTCALL|METH_KEYWORDS, os_open__doc__}, + +static int +os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd); + +static PyObject * +os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); + int flags; + int mode = 511; + int dir_fd = DEFAULT_DIR_FD; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { goto exit; } - if (nargs < 4) { - goto skip_optional; - } - if (PyFloat_Check(args[3])) { + if (PyFloat_Check(args[1])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - flags = _PyLong_AsInt(args[3]); + flags = _PyLong_AsInt(args[1]); if (flags == -1 && PyErr_Occurred()) { goto exit; } -skip_optional: - _return_value = os_pwritev_impl(module, fd, buffers, offset, flags); - if ((_return_value == -1) && PyErr_Occurred()) { + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + mode = _PyLong_AsInt(args[2]); + if (mode == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!OPENAT_DIR_FD_CONVERTER(args[3], &dir_fd)) { goto exit; } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - -#endif /* (defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)) */ - -#if defined(HAVE_COPY_FILE_RANGE) - -PyDoc_STRVAR(os_copy_file_range__doc__, -"copy_file_range($module, /, src, dst, count, offset_src=None,\n" -" offset_dst=None)\n" -"--\n" -"\n" -"Copy count bytes from one file descriptor to another.\n" -"\n" -" src\n" -" Source file descriptor.\n" -" dst\n" -" Destination file descriptor.\n" -" count\n" -" Number of bytes to copy.\n" -" offset_src\n" -" Starting offset in src.\n" -" offset_dst\n" -" Starting offset in dst.\n" -"\n" -"If offset_src is None, then src is read from the current position;\n" -"respectively for offset_dst."); - -#define OS_COPY_FILE_RANGE_METHODDEF \ - {"copy_file_range", (PyCFunction)(void(*)(void))os_copy_file_range, METH_FASTCALL|METH_KEYWORDS, os_copy_file_range__doc__}, - -static PyObject * -os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count, - PyObject *offset_src, PyObject *offset_dst); - -static PyObject * -os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "copy_file_range", 0}; - PyObject *argsbuf[5]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - int src; - int dst; - Py_ssize_t count; - PyObject *offset_src = Py_None; - PyObject *offset_dst = Py_None; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 5, 0, argsbuf); +skip_optional_kwonly: + _return_value = os_open_impl(module, &path, flags, mode, dir_fd); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +PyDoc_STRVAR(os_close__doc__, +"close($module, /, fd)\n" +"--\n" +"\n" +"Close a file descriptor."); + +#define OS_CLOSE_METHODDEF \ + {"close", (PyCFunction)(void(*)(void))os_close, METH_FASTCALL|METH_KEYWORDS, os_close__doc__}, + +static PyObject * +os_close_impl(PyObject *module, int fd); + +static PyObject * +os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "close", 0}; + PyObject *argsbuf[1]; + int fd; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } + return_value = os_close_impl(module, fd); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_closerange__doc__, +"closerange($module, fd_low, fd_high, /)\n" +"--\n" +"\n" +"Closes all file descriptors in [fd_low, fd_high), ignoring errors."); + +#define OS_CLOSERANGE_METHODDEF \ + {"closerange", (PyCFunction)(void(*)(void))os_closerange, METH_FASTCALL, os_closerange__doc__}, + +static PyObject * +os_closerange_impl(PyObject *module, int fd_low, int fd_high); + +static PyObject * +os_closerange(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd_low; + int fd_high; + + if (!_PyArg_CheckPositional("closerange", nargs, 2, 2)) { + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - src = _PyLong_AsInt(args[0]); - if (src == -1 && PyErr_Occurred()) { + fd_low = _PyLong_AsInt(args[0]); + if (fd_low == -1 && PyErr_Occurred()) { goto exit; } if (PyFloat_Check(args[1])) { @@ -6016,315 +4729,267 @@ os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py "integer argument expected, got float" ); goto exit; } - dst = _PyLong_AsInt(args[1]); - if (dst == -1 && PyErr_Occurred()) { + fd_high = _PyLong_AsInt(args[1]); + if (fd_high == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[2])) { + return_value = os_closerange_impl(module, fd_low, fd_high); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_dup__doc__, +"dup($module, fd, /)\n" +"--\n" +"\n" +"Return a duplicate of a file descriptor."); + +#define OS_DUP_METHODDEF \ + {"dup", (PyCFunction)os_dup, METH_O, os_dup__doc__}, + +static int +os_dup_impl(PyObject *module, int fd); + +static PyObject * +os_dup(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + int _return_value; + + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); + goto exit; + } + fd = _PyLong_AsInt(arg); + if (fd == -1 && PyErr_Occurred()) { goto exit; } - { - Py_ssize_t ival = -1; - PyObject *iobj = PyNumber_Index(args[2]); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); - } - if (ival == -1 && PyErr_Occurred()) { - goto exit; - } - count = ival; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[3]) { - offset_src = args[3]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - offset_dst = args[4]; -skip_optional_pos: - return_value = os_copy_file_range_impl(module, src, dst, count, offset_src, offset_dst); - -exit: - return return_value; -} - -#endif /* defined(HAVE_COPY_FILE_RANGE) */ - -#if defined(HAVE_MKFIFO) - -PyDoc_STRVAR(os_mkfifo__doc__, -"mkfifo($module, /, path, mode=438, *, dir_fd=None)\n" -"--\n" -"\n" -"Create a \"fifo\" (a POSIX named pipe).\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"dir_fd may not be implemented on your platform.\n" -" If it is unavailable, using it will raise a NotImplementedError."); - -#define OS_MKFIFO_METHODDEF \ - {"mkfifo", (PyCFunction)(void(*)(void))os_mkfifo, METH_FASTCALL|METH_KEYWORDS, os_mkfifo__doc__}, - -static PyObject * -os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd); - -static PyObject * -os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mkfifo", 0}; + _return_value = os_dup_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_dup2__doc__, +"dup2($module, /, fd, fd2, inheritable=True)\n" +"--\n" +"\n" +"Duplicate file descriptor."); + +#define OS_DUP2_METHODDEF \ + {"dup2", (PyCFunction)(void(*)(void))os_dup2, METH_FASTCALL|METH_KEYWORDS, os_dup2__doc__}, + +static int +os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable); + +static PyObject * +os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", "fd2", "inheritable", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "dup2", 0}; PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); - int mode = 438; - int dir_fd = DEFAULT_DIR_FD; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + int fd; + int fd2; + int inheritable = 1; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (!path_converter(args[0], &path)) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - mode = _PyLong_AsInt(args[1]); - if (mode == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - if (!MKFIFOAT_DIR_FD_CONVERTER(args[2], &dir_fd)) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } -skip_optional_kwonly: - return_value = os_mkfifo_impl(module, &path, mode, dir_fd); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_MKFIFO) */ - -#if (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) - -PyDoc_STRVAR(os_mknod__doc__, -"mknod($module, /, path, mode=384, device=0, *, dir_fd=None)\n" -"--\n" -"\n" -"Create a node in the file system.\n" -"\n" -"Create a node in the file system (file, device special file or named pipe)\n" -"at path. mode specifies both the permissions to use and the\n" -"type of node to be created, being combined (bitwise OR) with one of\n" -"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,\n" -"device defines the newly created device special file (probably using\n" -"os.makedev()). Otherwise device is ignored.\n" -"\n" -"If dir_fd is not None, it should be a file descriptor open to a directory,\n" -" and path should be relative; path will then be relative to that directory.\n" -"dir_fd may not be implemented on your platform.\n" -" If it is unavailable, using it will raise a NotImplementedError."); - -#define OS_MKNOD_METHODDEF \ - {"mknod", (PyCFunction)(void(*)(void))os_mknod, METH_FASTCALL|METH_KEYWORDS, os_mknod__doc__}, - -static PyObject * -os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, - int dir_fd); - -static PyObject * -os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "mode", "device", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mknod", 0}; - PyObject *argsbuf[4]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); - int mode = 384; - dev_t device = 0; - int dir_fd = DEFAULT_DIR_FD; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); - if (!args) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (!path_converter(args[0], &path)) { + fd2 = _PyLong_AsInt(args[1]); + if (fd2 == -1 && PyErr_Occurred()) { goto exit; } if (!noptargs) { goto skip_optional_pos; } - if (args[1]) { - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } - mode = _PyLong_AsInt(args[1]); - if (mode == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[2]) { - if (!_Py_Dev_Converter(args[2], &device)) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } + inheritable = PyObject_IsTrue(args[2]); + if (inheritable < 0) { + goto exit; } skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; + _return_value = os_dup2_impl(module, fd, fd2, inheritable); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#if defined(HAVE_LOCKF) + +PyDoc_STRVAR(os_lockf__doc__, +"lockf($module, fd, command, length, /)\n" +"--\n" +"\n" +"Apply, test or remove a POSIX lock on an open file descriptor.\n" +"\n" +" fd\n" +" An open file descriptor.\n" +" command\n" +" One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.\n" +" length\n" +" The number of bytes to lock, starting at the current position."); + +#define OS_LOCKF_METHODDEF \ + {"lockf", (PyCFunction)(void(*)(void))os_lockf, METH_FASTCALL, os_lockf__doc__}, + +static PyObject * +os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length); + +static PyObject * +os_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int command; + Py_off_t length; + + if (!_PyArg_CheckPositional("lockf", nargs, 3, 3)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; } - if (!MKNODAT_DIR_FD_CONVERTER(args[3], &dir_fd)) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } -skip_optional_kwonly: - return_value = os_mknod_impl(module, &path, mode, device, dir_fd); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) */ - -#if defined(HAVE_DEVICE_MACROS) - -PyDoc_STRVAR(os_major__doc__, -"major($module, device, /)\n" -"--\n" -"\n" -"Extracts a device major number from a raw device number."); - -#define OS_MAJOR_METHODDEF \ - {"major", (PyCFunction)os_major, METH_O, os_major__doc__}, - -static unsigned int -os_major_impl(PyObject *module, dev_t device); - -static PyObject * -os_major(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - dev_t device; - unsigned int _return_value; - - if (!_Py_Dev_Converter(arg, &device)) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - _return_value = os_major_impl(module, device); - if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { + command = _PyLong_AsInt(args[1]); + if (command == -1 && PyErr_Occurred()) { goto exit; } - return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_DEVICE_MACROS) */ - -#if defined(HAVE_DEVICE_MACROS) - -PyDoc_STRVAR(os_minor__doc__, -"minor($module, device, /)\n" -"--\n" -"\n" -"Extracts a device minor number from a raw device number."); - -#define OS_MINOR_METHODDEF \ - {"minor", (PyCFunction)os_minor, METH_O, os_minor__doc__}, - -static unsigned int -os_minor_impl(PyObject *module, dev_t device); - -static PyObject * -os_minor(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - dev_t device; - unsigned int _return_value; - - if (!_Py_Dev_Converter(arg, &device)) { + if (!Py_off_t_converter(args[2], &length)) { goto exit; } - _return_value = os_minor_impl(module, device); - if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { + return_value = os_lockf_impl(module, fd, command, length); + +exit: + return return_value; +} + +#endif /* defined(HAVE_LOCKF) */ + +PyDoc_STRVAR(os_lseek__doc__, +"lseek($module, fd, position, how, /)\n" +"--\n" +"\n" +"Set the position of a file descriptor. Return the new position.\n" +"\n" +"Return the new cursor position in number of bytes\n" +"relative to the beginning of the file."); + +#define OS_LSEEK_METHODDEF \ + {"lseek", (PyCFunction)(void(*)(void))os_lseek, METH_FASTCALL, os_lseek__doc__}, + +static Py_off_t +os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how); + +static PyObject * +os_lseek(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t position; + int how; + Py_off_t _return_value; + + if (!_PyArg_CheckPositional("lseek", nargs, 3, 3)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_DEVICE_MACROS) */ - -#if defined(HAVE_DEVICE_MACROS) - -PyDoc_STRVAR(os_makedev__doc__, -"makedev($module, major, minor, /)\n" -"--\n" -"\n" -"Composes a raw device number from the major and minor device numbers."); - -#define OS_MAKEDEV_METHODDEF \ - {"makedev", (PyCFunction)(void(*)(void))os_makedev, METH_FASTCALL, os_makedev__doc__}, - -static dev_t -os_makedev_impl(PyObject *module, int major, int minor); - -static PyObject * -os_makedev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int major; - int minor; - dev_t _return_value; - - if (!_PyArg_CheckPositional("makedev", nargs, 2, 2)) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { + goto exit; + } + if (!Py_off_t_converter(args[1], &position)) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + how = _PyLong_AsInt(args[2]); + if (how == -1 && PyErr_Occurred()) { goto exit; } + _return_value = os_lseek_impl(module, fd, position, how); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromPy_off_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_read__doc__, +"read($module, fd, length, /)\n" +"--\n" +"\n" +"Read from a file descriptor. Returns a bytes object."); + +#define OS_READ_METHODDEF \ + {"read", (PyCFunction)(void(*)(void))os_read, METH_FASTCALL, os_read__doc__}, + +static PyObject * +os_read_impl(PyObject *module, int fd, Py_ssize_t length); + +static PyObject * +os_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + Py_ssize_t length; + + if (!_PyArg_CheckPositional("read", nargs, 2, 2)) { + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - major = _PyLong_AsInt(args[0]); - if (major == -1 && PyErr_Occurred()) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } if (PyFloat_Check(args[1])) { @@ -6332,46 +4997,107 @@ os_makedev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) "integer argument expected, got float" ); goto exit; } - minor = _PyLong_AsInt(args[1]); - if (minor == -1 && PyErr_Occurred()) { - goto exit; + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + length = ival; } - _return_value = os_makedev_impl(module, major, minor); - if ((_return_value == (dev_t)-1) && PyErr_Occurred()) { + return_value = os_read_impl(module, fd, length); + +exit: + return return_value; +} + +#if defined(HAVE_READV) + +PyDoc_STRVAR(os_readv__doc__, +"readv($module, fd, buffers, /)\n" +"--\n" +"\n" +"Read from a file descriptor fd into an iterable of buffers.\n" +"\n" +"The buffers should be mutable buffers accepting bytes.\n" +"readv will transfer data into each buffer until it is full\n" +"and then move on to the next buffer in the sequence to hold\n" +"the rest of the data.\n" +"\n" +"readv returns the total number of bytes read,\n" +"which may be less than the total capacity of all the buffers."); + +#define OS_READV_METHODDEF \ + {"readv", (PyCFunction)(void(*)(void))os_readv, METH_FASTCALL, os_readv__doc__}, + +static Py_ssize_t +os_readv_impl(PyObject *module, int fd, PyObject *buffers); + +static PyObject * +os_readv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_ssize_t _return_value; + + if (!_PyArg_CheckPositional("readv", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = _PyLong_FromDev(_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_DEVICE_MACROS) */ - -#if (defined HAVE_FTRUNCATE || defined MS_WINDOWS) - -PyDoc_STRVAR(os_ftruncate__doc__, -"ftruncate($module, fd, length, /)\n" -"--\n" -"\n" -"Truncate a file, specified by file descriptor, to a specific length."); - -#define OS_FTRUNCATE_METHODDEF \ - {"ftruncate", (PyCFunction)(void(*)(void))os_ftruncate, METH_FASTCALL, os_ftruncate__doc__}, - -static PyObject * -os_ftruncate_impl(PyObject *module, int fd, Py_off_t length); - -static PyObject * -os_ftruncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - Py_off_t length; - - if (!_PyArg_CheckPositional("ftruncate", nargs, 2, 2)) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } + buffers = args[1]; + _return_value = os_readv_impl(module, fd, buffers); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_READV) */ + +#if defined(HAVE_PREAD) + +PyDoc_STRVAR(os_pread__doc__, +"pread($module, fd, length, offset, /)\n" +"--\n" +"\n" +"Read a number of bytes from a file descriptor starting at a particular offset.\n" +"\n" +"Read length bytes from file descriptor fd, starting at offset bytes from\n" +"the beginning of the file. The file offset remains unchanged."); + +#define OS_PREAD_METHODDEF \ + {"pread", (PyCFunction)(void(*)(void))os_pread, METH_FASTCALL, os_pread__doc__}, + +static PyObject * +os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset); + +static PyObject * +os_pread(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + Py_ssize_t length; + Py_off_t offset; + + if (!_PyArg_CheckPositional("pread", nargs, 3, 3)) { + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -6381,94 +5107,137 @@ os_ftruncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (!Py_off_t_converter(args[1], &length)) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = os_ftruncate_impl(module, fd, length); - -exit: - return return_value; -} - -#endif /* (defined HAVE_FTRUNCATE || defined MS_WINDOWS) */ - -#if (defined HAVE_TRUNCATE || defined MS_WINDOWS) - -PyDoc_STRVAR(os_truncate__doc__, -"truncate($module, /, path, length)\n" -"--\n" -"\n" -"Truncate a file, specified by path, to a specific length.\n" -"\n" -"On some platforms, path may also be specified as an open file descriptor.\n" -" If this functionality is unavailable, using it raises an exception."); - -#define OS_TRUNCATE_METHODDEF \ - {"truncate", (PyCFunction)(void(*)(void))os_truncate, METH_FASTCALL|METH_KEYWORDS, os_truncate__doc__}, - -static PyObject * -os_truncate_impl(PyObject *module, path_t *path, Py_off_t length); - -static PyObject * -os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "truncate", 0}; - PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); - Py_off_t length; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + length = ival; + } + if (!Py_off_t_converter(args[2], &offset)) { + goto exit; + } + return_value = os_pread_impl(module, fd, length, offset); + +exit: + return return_value; +} + +#endif /* defined(HAVE_PREAD) */ + +#if (defined(HAVE_PREADV) || defined (HAVE_PREADV2)) + +PyDoc_STRVAR(os_preadv__doc__, +"preadv($module, fd, buffers, offset, flags=0, /)\n" +"--\n" +"\n" +"Reads from a file descriptor into a number of mutable bytes-like objects.\n" +"\n" +"Combines the functionality of readv() and pread(). As readv(), it will\n" +"transfer data into each buffer until it is full and then move on to the next\n" +"buffer in the sequence to hold the rest of the data. Its fourth argument,\n" +"specifies the file offset at which the input operation is to be performed. It\n" +"will return the total number of bytes read (which can be less than the total\n" +"capacity of all the objects).\n" +"\n" +"The flags argument contains a bitwise OR of zero or more of the following flags:\n" +"\n" +"- RWF_HIPRI\n" +"- RWF_NOWAIT\n" +"\n" +"Using non-zero flags requires Linux 4.6 or newer."); + +#define OS_PREADV_METHODDEF \ + {"preadv", (PyCFunction)(void(*)(void))os_preadv, METH_FASTCALL, os_preadv__doc__}, + +static Py_ssize_t +os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, + int flags); + +static PyObject * +os_preadv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_off_t offset; + int flags = 0; + Py_ssize_t _return_value; + + if (!_PyArg_CheckPositional("preadv", nargs, 3, 4)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (!path_converter(args[0], &path)) { + buffers = args[1]; + if (!Py_off_t_converter(args[2], &offset)) { goto exit; } - if (!Py_off_t_converter(args[1], &length)) { + if (nargs < 4) { + goto skip_optional; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = os_truncate_impl(module, &path, length); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* (defined HAVE_TRUNCATE || defined MS_WINDOWS) */ - -#if (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)) - -PyDoc_STRVAR(os_posix_fallocate__doc__, -"posix_fallocate($module, fd, offset, length, /)\n" -"--\n" -"\n" -"Ensure a file has allocated at least a particular number of bytes on disk.\n" -"\n" -"Ensure that the file specified by fd encompasses a range of bytes\n" -"starting at offset bytes from the beginning and continuing for length bytes."); - -#define OS_POSIX_FALLOCATE_METHODDEF \ - {"posix_fallocate", (PyCFunction)(void(*)(void))os_posix_fallocate, METH_FASTCALL, os_posix_fallocate__doc__}, - -static PyObject * -os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset, - Py_off_t length); - -static PyObject * -os_posix_fallocate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - Py_off_t offset; - Py_off_t length; - - if (!_PyArg_CheckPositional("posix_fallocate", nargs, 3, 3)) { + flags = _PyLong_AsInt(args[3]); + if (flags == -1 && PyErr_Occurred()) { goto exit; } +skip_optional: + _return_value = os_preadv_impl(module, fd, buffers, offset, flags); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_PREADV) || defined (HAVE_PREADV2)) */ + +PyDoc_STRVAR(os_write__doc__, +"write($module, fd, data, /)\n" +"--\n" +"\n" +"Write a bytes object to a file descriptor."); + +#define OS_WRITE_METHODDEF \ + {"write", (PyCFunction)(void(*)(void))os_write, METH_FASTCALL, os_write__doc__}, + +static Py_ssize_t +os_write_impl(PyObject *module, int fd, Py_buffer *data); + +static PyObject * +os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + Py_buffer data = {NULL, NULL}; + Py_ssize_t _return_value; + + if (!_PyArg_CheckPositional("write", nargs, 2, 2)) { + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -6478,53 +5247,63 @@ os_posix_fallocate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (!Py_off_t_converter(args[1], &offset)) { + if (PyObject_GetBuffer(args[1], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!Py_off_t_converter(args[2], &length)) { + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("write", "argument 2", "contiguous buffer", args[1]); goto exit; } - return_value = os_posix_fallocate_impl(module, fd, offset, length); - -exit: - return return_value; -} - -#endif /* (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)) */ - -#if (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) + _return_value = os_write_impl(module, fd, &data); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +#if defined(HAVE_SENDFILE) && defined(__APPLE__) -PyDoc_STRVAR(os_posix_fadvise__doc__, -"posix_fadvise($module, fd, offset, length, advice, /)\n" +PyDoc_STRVAR(os_sendfile__doc__, +"sendfile($module, /, out_fd, in_fd, offset, count, headers=(),\n" +" trailers=(), flags=0)\n" "--\n" "\n" -"Announce an intention to access data in a specific pattern.\n" -"\n" -"Announce an intention to access data in a specific pattern, thus allowing\n" -"the kernel to make optimizations.\n" -"The advice applies to the region of the file specified by fd starting at\n" -"offset and continuing for length bytes.\n" -"advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n" -"POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or\n" -"POSIX_FADV_DONTNEED."); - -#define OS_POSIX_FADVISE_METHODDEF \ - {"posix_fadvise", (PyCFunction)(void(*)(void))os_posix_fadvise, METH_FASTCALL, os_posix_fadvise__doc__}, +"Copy count bytes from file descriptor in_fd to file descriptor out_fd."); + +#define OS_SENDFILE_METHODDEF \ + {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, static PyObject * -os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, - Py_off_t length, int advice); +os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, + Py_off_t sbytes, PyObject *headers, PyObject *trailers, + int flags); static PyObject * -os_posix_fadvise(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - int fd; + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + PyObject *argsbuf[7]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; + int out_fd; + int in_fd; Py_off_t offset; - Py_off_t length; - int advice; + Py_off_t sbytes; + PyObject *headers = NULL; + PyObject *trailers = NULL; + int flags = 0; - if (!_PyArg_CheckPositional("posix_fadvise", nargs, 4, 4)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 7, 0, argsbuf); + if (!args) { goto exit; } if (PyFloat_Check(args[0])) { @@ -6532,298 +5311,264 @@ os_posix_fadvise(PyObject *module, PyObject *const *args, Py_ssize_t nargs) "integer argument expected, got float" ); goto exit; } - fd = _PyLong_AsInt(args[0]); - if (fd == -1 && PyErr_Occurred()) { + out_fd = _PyLong_AsInt(args[0]); + if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - if (!Py_off_t_converter(args[1], &offset)) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (!Py_off_t_converter(args[2], &length)) { + in_fd = _PyLong_AsInt(args[1]); + if (in_fd == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[3])) { + if (!Py_off_t_converter(args[2], &offset)) { + goto exit; + } + if (!Py_off_t_converter(args[3], &sbytes)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[4]) { + headers = args[4]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[5]) { + trailers = args[5]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[6])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - advice = _PyLong_AsInt(args[3]); - if (advice == -1 && PyErr_Occurred()) { + flags = _PyLong_AsInt(args[6]); + if (flags == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_posix_fadvise_impl(module, fd, offset, length, advice); +skip_optional_pos: + return_value = os_sendfile_impl(module, out_fd, in_fd, offset, sbytes, headers, trailers, flags); exit: return return_value; } -#endif /* (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) */ +#endif /* defined(HAVE_SENDFILE) && defined(__APPLE__) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_SENDFILE) && !defined(__APPLE__) && (defined(__FreeBSD__) || defined(__DragonFly__)) -PyDoc_STRVAR(os_putenv__doc__, -"putenv($module, name, value, /)\n" +PyDoc_STRVAR(os_sendfile__doc__, +"sendfile($module, /, out_fd, in_fd, offset, count, headers=(),\n" +" trailers=(), flags=0)\n" "--\n" "\n" -"Change or add an environment variable."); +"Copy count bytes from file descriptor in_fd to file descriptor out_fd."); -#define OS_PUTENV_METHODDEF \ - {"putenv", (PyCFunction)(void(*)(void))os_putenv, METH_FASTCALL, os_putenv__doc__}, +#define OS_SENDFILE_METHODDEF \ + {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, static PyObject * -os_putenv_impl(PyObject *module, PyObject *name, PyObject *value); +os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, + Py_ssize_t count, PyObject *headers, PyObject *trailers, + int flags); static PyObject * -os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - PyObject *name; - PyObject *value; + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + PyObject *argsbuf[7]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; + int out_fd; + int in_fd; + Py_off_t offset; + Py_ssize_t count; + PyObject *headers = NULL; + PyObject *trailers = NULL; + int flags = 0; - if (!_PyArg_CheckPositional("putenv", nargs, 2, 2)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 7, 0, argsbuf); + if (!args) { goto exit; } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("putenv", "argument 1", "str", args[0]); + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (PyUnicode_READY(args[0]) == -1) { + out_fd = _PyLong_AsInt(args[0]); + if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - name = args[0]; - if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("putenv", "argument 2", "str", args[1]); + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (PyUnicode_READY(args[1]) == -1) { + in_fd = _PyLong_AsInt(args[1]); + if (in_fd == -1 && PyErr_Occurred()) { goto exit; } - value = args[1]; - return_value = os_putenv_impl(module, name, value); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if !defined(MS_WINDOWS) - -PyDoc_STRVAR(os_putenv__doc__, -"putenv($module, name, value, /)\n" -"--\n" -"\n" -"Change or add an environment variable."); - -#define OS_PUTENV_METHODDEF \ - {"putenv", (PyCFunction)(void(*)(void))os_putenv, METH_FASTCALL, os_putenv__doc__}, - -static PyObject * -os_putenv_impl(PyObject *module, PyObject *name, PyObject *value); - -static PyObject * -os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *name = NULL; - PyObject *value = NULL; - - if (!_PyArg_CheckPositional("putenv", nargs, 2, 2)) { + if (!Py_off_t_converter(args[2], &offset)) { goto exit; } - if (!PyUnicode_FSConverter(args[0], &name)) { + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (!PyUnicode_FSConverter(args[1], &value)) { - goto exit; + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[3]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; } - return_value = os_putenv_impl(module, name, value); - -exit: - /* Cleanup for name */ - Py_XDECREF(name); - /* Cleanup for value */ - Py_XDECREF(value); - - return return_value; -} - -#endif /* !defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(os_unsetenv__doc__, -"unsetenv($module, name, /)\n" -"--\n" -"\n" -"Delete an environment variable."); - -#define OS_UNSETENV_METHODDEF \ - {"unsetenv", (PyCFunction)os_unsetenv, METH_O, os_unsetenv__doc__}, - -static PyObject * -os_unsetenv_impl(PyObject *module, PyObject *name); - -static PyObject * -os_unsetenv(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("unsetenv", "argument", "str", arg); + if (!noptargs) { + goto skip_optional_pos; + } + if (args[4]) { + headers = args[4]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[5]) { + trailers = args[5]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (PyUnicode_READY(arg) == -1) { + flags = _PyLong_AsInt(args[6]); + if (flags == -1 && PyErr_Occurred()) { goto exit; } - name = arg; - return_value = os_unsetenv_impl(module, name); +skip_optional_pos: + return_value = os_sendfile_impl(module, out_fd, in_fd, offset, count, headers, trailers, flags); exit: return return_value; } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_SENDFILE) && !defined(__APPLE__) && (defined(__FreeBSD__) || defined(__DragonFly__)) */ -#if !defined(MS_WINDOWS) +#if defined(HAVE_SENDFILE) && !defined(__APPLE__) && !(defined(__FreeBSD__) || defined(__DragonFly__)) -PyDoc_STRVAR(os_unsetenv__doc__, -"unsetenv($module, name, /)\n" +PyDoc_STRVAR(os_sendfile__doc__, +"sendfile($module, /, out_fd, in_fd, offset, count)\n" "--\n" "\n" -"Delete an environment variable."); +"Copy count bytes from file descriptor in_fd to file descriptor out_fd."); -#define OS_UNSETENV_METHODDEF \ - {"unsetenv", (PyCFunction)os_unsetenv, METH_O, os_unsetenv__doc__}, +#define OS_SENDFILE_METHODDEF \ + {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, static PyObject * -os_unsetenv_impl(PyObject *module, PyObject *name); +os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, + Py_ssize_t count); static PyObject * -os_unsetenv(PyObject *module, PyObject *arg) +os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - PyObject *name = NULL; + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + PyObject *argsbuf[4]; + int out_fd; + int in_fd; + PyObject *offobj; + Py_ssize_t count; - if (!PyUnicode_FSConverter(arg, &name)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 4, 0, argsbuf); + if (!args) { goto exit; } - return_value = os_unsetenv_impl(module, name); - -exit: - /* Cleanup for name */ - Py_XDECREF(name); - - return return_value; -} - -#endif /* !defined(MS_WINDOWS) */ - -PyDoc_STRVAR(os_strerror__doc__, -"strerror($module, code, /)\n" -"--\n" -"\n" -"Translate an error code to a message string."); - -#define OS_STRERROR_METHODDEF \ - {"strerror", (PyCFunction)os_strerror, METH_O, os_strerror__doc__}, - -static PyObject * -os_strerror_impl(PyObject *module, int code); - -static PyObject * -os_strerror(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int code; - - if (PyFloat_Check(arg)) { + if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - code = _PyLong_AsInt(arg); - if (code == -1 && PyErr_Occurred()) { + out_fd = _PyLong_AsInt(args[0]); + if (out_fd == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_strerror_impl(module, code); - -exit: - return return_value; -} - -#if defined(HAVE_SYS_WAIT_H) && defined(WCOREDUMP) - -PyDoc_STRVAR(os_WCOREDUMP__doc__, -"WCOREDUMP($module, status, /)\n" -"--\n" -"\n" -"Return True if the process returning status was dumped to a core file."); - -#define OS_WCOREDUMP_METHODDEF \ - {"WCOREDUMP", (PyCFunction)os_WCOREDUMP, METH_O, os_WCOREDUMP__doc__}, - -static int -os_WCOREDUMP_impl(PyObject *module, int status); - -static PyObject * -os_WCOREDUMP(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int status; - int _return_value; - - if (PyFloat_Check(arg)) { + if (PyFloat_Check(args[1])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - status = _PyLong_AsInt(arg); - if (status == -1 && PyErr_Occurred()) { + in_fd = _PyLong_AsInt(args[1]); + if (in_fd == -1 && PyErr_Occurred()) { goto exit; } - _return_value = os_WCOREDUMP_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) { + offobj = args[2]; + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = PyBool_FromLong((long)_return_value); + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[3]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; + } + return_value = os_sendfile_impl(module, out_fd, in_fd, offobj, count); exit: return return_value; } -#endif /* defined(HAVE_SYS_WAIT_H) && defined(WCOREDUMP) */ +#endif /* defined(HAVE_SENDFILE) && !defined(__APPLE__) && !(defined(__FreeBSD__) || defined(__DragonFly__)) */ -#if defined(HAVE_SYS_WAIT_H) && defined(WIFCONTINUED) +#if defined(__APPLE__) -PyDoc_STRVAR(os_WIFCONTINUED__doc__, -"WIFCONTINUED($module, /, status)\n" +PyDoc_STRVAR(os__fcopyfile__doc__, +"_fcopyfile($module, in_fd, out_fd, flags, /)\n" "--\n" "\n" -"Return True if a particular process was continued from a job control stop.\n" -"\n" -"Return True if the process returning status was continued from a\n" -"job control stop."); +"Efficiently copy content or metadata of 2 regular file descriptors (macOS)."); -#define OS_WIFCONTINUED_METHODDEF \ - {"WIFCONTINUED", (PyCFunction)(void(*)(void))os_WIFCONTINUED, METH_FASTCALL|METH_KEYWORDS, os_WIFCONTINUED__doc__}, +#define OS__FCOPYFILE_METHODDEF \ + {"_fcopyfile", (PyCFunction)(void(*)(void))os__fcopyfile, METH_FASTCALL, os__fcopyfile__doc__}, -static int -os_WIFCONTINUED_impl(PyObject *module, int status); +static PyObject * +os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags); static PyObject * -os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +os__fcopyfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFCONTINUED", 0}; - PyObject *argsbuf[1]; - int status; - int _return_value; + int in_fd; + int out_fd; + int flags; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { + if (!_PyArg_CheckPositional("_fcopyfile", nargs, 3, 3)) { goto exit; } if (PyFloat_Check(args[0])) { @@ -6831,194 +5576,429 @@ os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj "integer argument expected, got float" ); goto exit; } - status = _PyLong_AsInt(args[0]); - if (status == -1 && PyErr_Occurred()) { + in_fd = _PyLong_AsInt(args[0]); + if (in_fd == -1 && PyErr_Occurred()) { goto exit; } - _return_value = os_WIFCONTINUED_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = PyBool_FromLong((long)_return_value); + out_fd = _PyLong_AsInt(args[1]); + if (out_fd == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flags = _PyLong_AsInt(args[2]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os__fcopyfile_impl(module, in_fd, out_fd, flags); exit: return return_value; } -#endif /* defined(HAVE_SYS_WAIT_H) && defined(WIFCONTINUED) */ - -#if defined(HAVE_SYS_WAIT_H) && defined(WIFSTOPPED) - -PyDoc_STRVAR(os_WIFSTOPPED__doc__, -"WIFSTOPPED($module, /, status)\n" -"--\n" -"\n" -"Return True if the process returning status was stopped."); - -#define OS_WIFSTOPPED_METHODDEF \ - {"WIFSTOPPED", (PyCFunction)(void(*)(void))os_WIFSTOPPED, METH_FASTCALL|METH_KEYWORDS, os_WIFSTOPPED__doc__}, - -static int -os_WIFSTOPPED_impl(PyObject *module, int status); +#endif /* defined(__APPLE__) */ -static PyObject * -os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFSTOPPED", 0}; +PyDoc_STRVAR(os_fstat__doc__, +"fstat($module, /, fd)\n" +"--\n" +"\n" +"Perform a stat system call on the given file descriptor.\n" +"\n" +"Like stat(), but for an open file descriptor.\n" +"Equivalent to os.stat(fd)."); + +#define OS_FSTAT_METHODDEF \ + {"fstat", (PyCFunction)(void(*)(void))os_fstat, METH_FASTCALL|METH_KEYWORDS, os_fstat__doc__}, + +static PyObject * +os_fstat_impl(PyObject *module, int fd); + +static PyObject * +os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "fstat", 0}; PyObject *argsbuf[1]; - int status; - int _return_value; - + int fd; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - status = _PyLong_AsInt(args[0]); - if (status == -1 && PyErr_Occurred()) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } - _return_value = os_WIFSTOPPED_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) { + return_value = os_fstat_impl(module, fd); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_isatty__doc__, +"isatty($module, fd, /)\n" +"--\n" +"\n" +"Return True if the fd is connected to a terminal.\n" +"\n" +"Return True if the file descriptor is an open file descriptor\n" +"connected to the slave end of a terminal."); + +#define OS_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)os_isatty, METH_O, os_isatty__doc__}, + +static int +os_isatty_impl(PyObject *module, int fd); + +static PyObject * +os_isatty(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + int _return_value; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + fd = _PyLong_AsInt(arg); + if (fd == -1 && PyErr_Occurred()) { goto exit; } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SYS_WAIT_H) && defined(WIFSTOPPED) */ - -#if defined(HAVE_SYS_WAIT_H) && defined(WIFSIGNALED) - -PyDoc_STRVAR(os_WIFSIGNALED__doc__, -"WIFSIGNALED($module, /, status)\n" -"--\n" -"\n" -"Return True if the process returning status was terminated by a signal."); - -#define OS_WIFSIGNALED_METHODDEF \ - {"WIFSIGNALED", (PyCFunction)(void(*)(void))os_WIFSIGNALED, METH_FASTCALL|METH_KEYWORDS, os_WIFSIGNALED__doc__}, - -static int -os_WIFSIGNALED_impl(PyObject *module, int status); - -static PyObject * -os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFSIGNALED", 0}; - PyObject *argsbuf[1]; - int status; - int _return_value; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { + _return_value = os_isatty_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +#if defined(HAVE_PIPE) + +PyDoc_STRVAR(os_pipe__doc__, +"pipe($module, /)\n" +"--\n" +"\n" +"Create a pipe.\n" +"\n" +"Returns a tuple of two file descriptors:\n" +" (read_fd, write_fd)"); + +#define OS_PIPE_METHODDEF \ + {"pipe", (PyCFunction)os_pipe, METH_NOARGS, os_pipe__doc__}, + +static PyObject * +os_pipe_impl(PyObject *module); + +static PyObject * +os_pipe(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_pipe_impl(module); +} + +#endif /* defined(HAVE_PIPE) */ + +#if defined(HAVE_PIPE2) + +PyDoc_STRVAR(os_pipe2__doc__, +"pipe2($module, flags, /)\n" +"--\n" +"\n" +"Create a pipe with flags set atomically.\n" +"\n" +"Returns a tuple of two file descriptors:\n" +" (read_fd, write_fd)\n" +"\n" +"flags can be constructed by ORing together one or more of these values:\n" +"O_NONBLOCK, O_CLOEXEC."); + +#define OS_PIPE2_METHODDEF \ + {"pipe2", (PyCFunction)os_pipe2, METH_O, os_pipe2__doc__}, + +static PyObject * +os_pipe2_impl(PyObject *module, int flags); + +static PyObject * +os_pipe2(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flags; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flags = _PyLong_AsInt(arg); + if (flags == -1 && PyErr_Occurred()) { goto exit; } + return_value = os_pipe2_impl(module, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_PIPE2) */ + +#if defined(HAVE_WRITEV) + +PyDoc_STRVAR(os_writev__doc__, +"writev($module, fd, buffers, /)\n" +"--\n" +"\n" +"Iterate over buffers, and write the contents of each to a file descriptor.\n" +"\n" +"Returns the total number of bytes written.\n" +"buffers must be a sequence of bytes-like objects."); + +#define OS_WRITEV_METHODDEF \ + {"writev", (PyCFunction)(void(*)(void))os_writev, METH_FASTCALL, os_writev__doc__}, + +static Py_ssize_t +os_writev_impl(PyObject *module, int fd, PyObject *buffers); + +static PyObject * +os_writev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_ssize_t _return_value; + + if (!_PyArg_CheckPositional("writev", nargs, 2, 2)) { + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - status = _PyLong_AsInt(args[0]); - if (status == -1 && PyErr_Occurred()) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } - _return_value = os_WIFSIGNALED_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) { + buffers = args[1]; + _return_value = os_writev_impl(module, fd, buffers); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WRITEV) */ + +#if defined(HAVE_PWRITE) + +PyDoc_STRVAR(os_pwrite__doc__, +"pwrite($module, fd, buffer, offset, /)\n" +"--\n" +"\n" +"Write bytes to a file descriptor starting at a particular offset.\n" +"\n" +"Write buffer to fd, starting at offset bytes from the beginning of\n" +"the file. Returns the number of bytes writte. Does not change the\n" +"current file offset."); + +#define OS_PWRITE_METHODDEF \ + {"pwrite", (PyCFunction)(void(*)(void))os_pwrite, METH_FASTCALL, os_pwrite__doc__}, + +static Py_ssize_t +os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset); + +static PyObject * +os_pwrite(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + Py_buffer buffer = {NULL, NULL}; + Py_off_t offset; + Py_ssize_t _return_value; + + if (!_PyArg_CheckPositional("pwrite", nargs, 3, 3)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SYS_WAIT_H) && defined(WIFSIGNALED) */ - -#if defined(HAVE_SYS_WAIT_H) && defined(WIFEXITED) - -PyDoc_STRVAR(os_WIFEXITED__doc__, -"WIFEXITED($module, /, status)\n" -"--\n" -"\n" -"Return True if the process returning status exited via the exit() system call."); - -#define OS_WIFEXITED_METHODDEF \ - {"WIFEXITED", (PyCFunction)(void(*)(void))os_WIFEXITED, METH_FASTCALL|METH_KEYWORDS, os_WIFEXITED__doc__}, - -static int -os_WIFEXITED_impl(PyObject *module, int status); - -static PyObject * -os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFEXITED", 0}; - PyObject *argsbuf[1]; - int status; - int _return_value; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&buffer, 'C')) { + _PyArg_BadArgument("pwrite", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!Py_off_t_converter(args[2], &offset)) { goto exit; } + _return_value = os_pwrite_impl(module, fd, &buffer, offset); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) { + PyBuffer_Release(&buffer); + } + + return return_value; +} + +#endif /* defined(HAVE_PWRITE) */ + +#if (defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)) + +PyDoc_STRVAR(os_pwritev__doc__, +"pwritev($module, fd, buffers, offset, flags=0, /)\n" +"--\n" +"\n" +"Writes the contents of bytes-like objects to a file descriptor at a given offset.\n" +"\n" +"Combines the functionality of writev() and pwrite(). All buffers must be a sequence\n" +"of bytes-like objects. Buffers are processed in array order. Entire contents of first\n" +"buffer is written before proceeding to second, and so on. The operating system may\n" +"set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.\n" +"This function writes the contents of each object to the file descriptor and returns\n" +"the total number of bytes written.\n" +"\n" +"The flags argument contains a bitwise OR of zero or more of the following flags:\n" +"\n" +"- RWF_DSYNC\n" +"- RWF_SYNC\n" +"\n" +"Using non-zero flags requires Linux 4.7 or newer."); + +#define OS_PWRITEV_METHODDEF \ + {"pwritev", (PyCFunction)(void(*)(void))os_pwritev, METH_FASTCALL, os_pwritev__doc__}, + +static Py_ssize_t +os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, + int flags); + +static PyObject * +os_pwritev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_off_t offset; + int flags = 0; + Py_ssize_t _return_value; + + if (!_PyArg_CheckPositional("pwritev", nargs, 3, 4)) { + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - status = _PyLong_AsInt(args[0]); - if (status == -1 && PyErr_Occurred()) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } - _return_value = os_WIFEXITED_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) { + buffers = args[1]; + if (!Py_off_t_converter(args[2], &offset)) { goto exit; } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SYS_WAIT_H) && defined(WIFEXITED) */ - -#if defined(HAVE_SYS_WAIT_H) && defined(WEXITSTATUS) + if (nargs < 4) { + goto skip_optional; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flags = _PyLong_AsInt(args[3]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + _return_value = os_pwritev_impl(module, fd, buffers, offset, flags); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)) */ + +#if defined(HAVE_COPY_FILE_RANGE) -PyDoc_STRVAR(os_WEXITSTATUS__doc__, -"WEXITSTATUS($module, /, status)\n" +PyDoc_STRVAR(os_copy_file_range__doc__, +"copy_file_range($module, /, src, dst, count, offset_src=None,\n" +" offset_dst=None)\n" "--\n" "\n" -"Return the process return code from status."); +"Copy count bytes from one file descriptor to another.\n" +"\n" +" src\n" +" Source file descriptor.\n" +" dst\n" +" Destination file descriptor.\n" +" count\n" +" Number of bytes to copy.\n" +" offset_src\n" +" Starting offset in src.\n" +" offset_dst\n" +" Starting offset in dst.\n" +"\n" +"If offset_src is None, then src is read from the current position;\n" +"respectively for offset_dst."); -#define OS_WEXITSTATUS_METHODDEF \ - {"WEXITSTATUS", (PyCFunction)(void(*)(void))os_WEXITSTATUS, METH_FASTCALL|METH_KEYWORDS, os_WEXITSTATUS__doc__}, +#define OS_COPY_FILE_RANGE_METHODDEF \ + {"copy_file_range", (PyCFunction)(void(*)(void))os_copy_file_range, METH_FASTCALL|METH_KEYWORDS, os_copy_file_range__doc__}, -static int -os_WEXITSTATUS_impl(PyObject *module, int status); +static PyObject * +os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count, + PyObject *offset_src, PyObject *offset_dst); static PyObject * -os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WEXITSTATUS", 0}; - PyObject *argsbuf[1]; - int status; - int _return_value; + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "copy_file_range", 0}; + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + int src; + int dst; + Py_ssize_t count; + PyObject *offset_src = Py_None; + PyObject *offset_dst = Py_None; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 5, 0, argsbuf); if (!args) { goto exit; } @@ -7027,272 +6007,526 @@ os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje "integer argument expected, got float" ); goto exit; } - status = _PyLong_AsInt(args[0]); - if (status == -1 && PyErr_Occurred()) { + src = _PyLong_AsInt(args[0]); + if (src == -1 && PyErr_Occurred()) { goto exit; } - _return_value = os_WEXITSTATUS_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SYS_WAIT_H) && defined(WEXITSTATUS) */ - -#if defined(HAVE_SYS_WAIT_H) && defined(WTERMSIG) - -PyDoc_STRVAR(os_WTERMSIG__doc__, -"WTERMSIG($module, /, status)\n" -"--\n" -"\n" -"Return the signal that terminated the process that provided the status value."); - -#define OS_WTERMSIG_METHODDEF \ - {"WTERMSIG", (PyCFunction)(void(*)(void))os_WTERMSIG, METH_FASTCALL|METH_KEYWORDS, os_WTERMSIG__doc__}, - -static int -os_WTERMSIG_impl(PyObject *module, int status); - -static PyObject * -os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WTERMSIG", 0}; - PyObject *argsbuf[1]; - int status; - int _return_value; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { + dst = _PyLong_AsInt(args[1]); + if (dst == -1 && PyErr_Occurred()) { goto exit; } - if (PyFloat_Check(args[0])) { + if (PyFloat_Check(args[2])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - status = _PyLong_AsInt(args[0]); - if (status == -1 && PyErr_Occurred()) { - goto exit; + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; } - _return_value = os_WTERMSIG_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[3]) { + offset_src = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } } - return_value = PyLong_FromLong((long)_return_value); + offset_dst = args[4]; +skip_optional_pos: + return_value = os_copy_file_range_impl(module, src, dst, count, offset_src, offset_dst); exit: return return_value; } -#endif /* defined(HAVE_SYS_WAIT_H) && defined(WTERMSIG) */ - -#if defined(HAVE_SYS_WAIT_H) && defined(WSTOPSIG) - -PyDoc_STRVAR(os_WSTOPSIG__doc__, -"WSTOPSIG($module, /, status)\n" -"--\n" -"\n" -"Return the signal that stopped the process that provided the status value."); - -#define OS_WSTOPSIG_METHODDEF \ - {"WSTOPSIG", (PyCFunction)(void(*)(void))os_WSTOPSIG, METH_FASTCALL|METH_KEYWORDS, os_WSTOPSIG__doc__}, - -static int -os_WSTOPSIG_impl(PyObject *module, int status); - -static PyObject * -os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WSTOPSIG", 0}; - PyObject *argsbuf[1]; - int status; - int _return_value; +#endif /* defined(HAVE_COPY_FILE_RANGE) */ - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); +#if defined(HAVE_MKFIFO) + +PyDoc_STRVAR(os_mkfifo__doc__, +"mkfifo($module, /, path, mode=438, *, dir_fd=None)\n" +"--\n" +"\n" +"Create a \"fifo\" (a POSIX named pipe).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_MKFIFO_METHODDEF \ + {"mkfifo", (PyCFunction)(void(*)(void))os_mkfifo, METH_FASTCALL|METH_KEYWORDS, os_mkfifo__doc__}, + +static PyObject * +os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd); + +static PyObject * +os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "mkfifo", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); + int mode = 438; + int dir_fd = DEFAULT_DIR_FD; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { goto exit; } - if (PyFloat_Check(args[0])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + mode = _PyLong_AsInt(args[1]); + if (mode == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!MKFIFOAT_DIR_FD_CONVERTER(args[2], &dir_fd)) { goto exit; } - status = _PyLong_AsInt(args[0]); - if (status == -1 && PyErr_Occurred()) { +skip_optional_kwonly: + return_value = os_mkfifo_impl(module, &path, mode, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_MKFIFO) */ + +#if (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) + +PyDoc_STRVAR(os_mknod__doc__, +"mknod($module, /, path, mode=384, device=0, *, dir_fd=None)\n" +"--\n" +"\n" +"Create a node in the file system.\n" +"\n" +"Create a node in the file system (file, device special file or named pipe)\n" +"at path. mode specifies both the permissions to use and the\n" +"type of node to be created, being combined (bitwise OR) with one of\n" +"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,\n" +"device defines the newly created device special file (probably using\n" +"os.makedev()). Otherwise device is ignored.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_MKNOD_METHODDEF \ + {"mknod", (PyCFunction)(void(*)(void))os_mknod, METH_FASTCALL|METH_KEYWORDS, os_mknod__doc__}, + +static PyObject * +os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, + int dir_fd); + +static PyObject * +os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "mode", "device", "dir_fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "mknod", 0}; + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); + int mode = 384; + dev_t device = 0; + int dir_fd = DEFAULT_DIR_FD; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { goto exit; } - _return_value = os_WSTOPSIG_impl(module, status); - if ((_return_value == -1) && PyErr_Occurred()) { + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + mode = _PyLong_AsInt(args[1]); + if (mode == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[2]) { + if (!_Py_Dev_Converter(args[2], &device)) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!MKNODAT_DIR_FD_CONVERTER(args[3], &dir_fd)) { goto exit; } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SYS_WAIT_H) && defined(WSTOPSIG) */ - -#if (defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)) - -PyDoc_STRVAR(os_fstatvfs__doc__, -"fstatvfs($module, fd, /)\n" -"--\n" -"\n" -"Perform an fstatvfs system call on the given fd.\n" -"\n" -"Equivalent to statvfs(fd)."); - -#define OS_FSTATVFS_METHODDEF \ - {"fstatvfs", (PyCFunction)os_fstatvfs, METH_O, os_fstatvfs__doc__}, - -static PyObject * -os_fstatvfs_impl(PyObject *module, int fd); - -static PyObject * -os_fstatvfs(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int fd; - - if (PyFloat_Check(arg)) { +skip_optional_kwonly: + return_value = os_mknod_impl(module, &path, mode, device, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) */ + +#if defined(HAVE_DEVICE_MACROS) + +PyDoc_STRVAR(os_major__doc__, +"major($module, device, /)\n" +"--\n" +"\n" +"Extracts a device major number from a raw device number."); + +#define OS_MAJOR_METHODDEF \ + {"major", (PyCFunction)os_major, METH_O, os_major__doc__}, + +static unsigned int +os_major_impl(PyObject *module, dev_t device); + +static PyObject * +os_major(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + dev_t device; + unsigned int _return_value; + + if (!_Py_Dev_Converter(arg, &device)) { + goto exit; + } + _return_value = os_major_impl(module, device); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_DEVICE_MACROS) */ + +#if defined(HAVE_DEVICE_MACROS) + +PyDoc_STRVAR(os_minor__doc__, +"minor($module, device, /)\n" +"--\n" +"\n" +"Extracts a device minor number from a raw device number."); + +#define OS_MINOR_METHODDEF \ + {"minor", (PyCFunction)os_minor, METH_O, os_minor__doc__}, + +static unsigned int +os_minor_impl(PyObject *module, dev_t device); + +static PyObject * +os_minor(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + dev_t device; + unsigned int _return_value; + + if (!_Py_Dev_Converter(arg, &device)) { + goto exit; + } + _return_value = os_minor_impl(module, device); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_DEVICE_MACROS) */ + +#if defined(HAVE_DEVICE_MACROS) + +PyDoc_STRVAR(os_makedev__doc__, +"makedev($module, major, minor, /)\n" +"--\n" +"\n" +"Composes a raw device number from the major and minor device numbers."); + +#define OS_MAKEDEV_METHODDEF \ + {"makedev", (PyCFunction)(void(*)(void))os_makedev, METH_FASTCALL, os_makedev__doc__}, + +static dev_t +os_makedev_impl(PyObject *module, int major, int minor); + +static PyObject * +os_makedev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int major; + int minor; + dev_t _return_value; + + if (!_PyArg_CheckPositional("makedev", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - fd = _PyLong_AsInt(arg); + major = _PyLong_AsInt(args[0]); + if (major == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + minor = _PyLong_AsInt(args[1]); + if (minor == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = os_makedev_impl(module, major, minor); + if ((_return_value == (dev_t)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = _PyLong_FromDev(_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_DEVICE_MACROS) */ + +#if (defined HAVE_FTRUNCATE || defined MS_WINDOWS) + +PyDoc_STRVAR(os_ftruncate__doc__, +"ftruncate($module, fd, length, /)\n" +"--\n" +"\n" +"Truncate a file, specified by file descriptor, to a specific length."); + +#define OS_FTRUNCATE_METHODDEF \ + {"ftruncate", (PyCFunction)(void(*)(void))os_ftruncate, METH_FASTCALL, os_ftruncate__doc__}, + +static PyObject * +os_ftruncate_impl(PyObject *module, int fd, Py_off_t length); + +static PyObject * +os_ftruncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t length; + + if (!_PyArg_CheckPositional("ftruncate", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + fd = _PyLong_AsInt(args[0]); if (fd == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_fstatvfs_impl(module, fd); - -exit: - return return_value; -} - -#endif /* (defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)) */ - -#if (defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)) - -PyDoc_STRVAR(os_statvfs__doc__, -"statvfs($module, /, path)\n" -"--\n" -"\n" -"Perform a statvfs system call on the given path.\n" -"\n" -"path may always be specified as a string.\n" -"On some platforms, path may also be specified as an open file descriptor.\n" -" If this functionality is unavailable, using it raises an exception."); - -#define OS_STATVFS_METHODDEF \ - {"statvfs", (PyCFunction)(void(*)(void))os_statvfs, METH_FASTCALL|METH_KEYWORDS, os_statvfs__doc__}, - -static PyObject * -os_statvfs_impl(PyObject *module, path_t *path); - -static PyObject * -os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "statvfs", 0}; - PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { + if (!Py_off_t_converter(args[1], &length)) { goto exit; } + return_value = os_ftruncate_impl(module, fd, length); + +exit: + return return_value; +} + +#endif /* (defined HAVE_FTRUNCATE || defined MS_WINDOWS) */ + +#if (defined HAVE_TRUNCATE || defined MS_WINDOWS) + +PyDoc_STRVAR(os_truncate__doc__, +"truncate($module, /, path, length)\n" +"--\n" +"\n" +"Truncate a file, specified by path, to a specific length.\n" +"\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_TRUNCATE_METHODDEF \ + {"truncate", (PyCFunction)(void(*)(void))os_truncate, METH_FASTCALL|METH_KEYWORDS, os_truncate__doc__}, + +static PyObject * +os_truncate_impl(PyObject *module, path_t *path, Py_off_t length); + +static PyObject * +os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "length", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "truncate", 0}; + PyObject *argsbuf[2]; + path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); + Py_off_t length; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } - return_value = os_statvfs_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* (defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(os__getdiskusage__doc__, -"_getdiskusage($module, /, path)\n" -"--\n" -"\n" -"Return disk usage statistics about the given path as a (total, free) tuple."); - -#define OS__GETDISKUSAGE_METHODDEF \ - {"_getdiskusage", (PyCFunction)(void(*)(void))os__getdiskusage, METH_FASTCALL|METH_KEYWORDS, os__getdiskusage__doc__}, - -static PyObject * -os__getdiskusage_impl(PyObject *module, path_t *path); - -static PyObject * -os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_getdiskusage", 0}; - PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0); - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { + if (!Py_off_t_converter(args[1], &length)) { goto exit; } - if (!path_converter(args[0], &path)) { + return_value = os_truncate_impl(module, &path, length); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* (defined HAVE_TRUNCATE || defined MS_WINDOWS) */ + +#if (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)) + +PyDoc_STRVAR(os_posix_fallocate__doc__, +"posix_fallocate($module, fd, offset, length, /)\n" +"--\n" +"\n" +"Ensure a file has allocated at least a particular number of bytes on disk.\n" +"\n" +"Ensure that the file specified by fd encompasses a range of bytes\n" +"starting at offset bytes from the beginning and continuing for length bytes."); + +#define OS_POSIX_FALLOCATE_METHODDEF \ + {"posix_fallocate", (PyCFunction)(void(*)(void))os_posix_fallocate, METH_FASTCALL, os_posix_fallocate__doc__}, + +static PyObject * +os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset, + Py_off_t length); + +static PyObject * +os_posix_fallocate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t offset; + Py_off_t length; + + if (!_PyArg_CheckPositional("posix_fallocate", nargs, 3, 3)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = os__getdiskusage_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(HAVE_FPATHCONF) - -PyDoc_STRVAR(os_fpathconf__doc__, -"fpathconf($module, fd, name, /)\n" -"--\n" -"\n" -"Return the configuration limit name for the file descriptor fd.\n" -"\n" -"If there is no limit, return -1."); - -#define OS_FPATHCONF_METHODDEF \ - {"fpathconf", (PyCFunction)(void(*)(void))os_fpathconf, METH_FASTCALL, os_fpathconf__doc__}, - -static long -os_fpathconf_impl(PyObject *module, int fd, int name); - -static PyObject * -os_fpathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - int name; - long _return_value; - - if (!_PyArg_CheckPositional("fpathconf", nargs, 2, 2)) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { + goto exit; + } + if (!Py_off_t_converter(args[1], &offset)) { + goto exit; + } + if (!Py_off_t_converter(args[2], &length)) { goto exit; } + return_value = os_posix_fallocate_impl(module, fd, offset, length); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)) */ + +#if (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) + +PyDoc_STRVAR(os_posix_fadvise__doc__, +"posix_fadvise($module, fd, offset, length, advice, /)\n" +"--\n" +"\n" +"Announce an intention to access data in a specific pattern.\n" +"\n" +"Announce an intention to access data in a specific pattern, thus allowing\n" +"the kernel to make optimizations.\n" +"The advice applies to the region of the file specified by fd starting at\n" +"offset and continuing for length bytes.\n" +"advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n" +"POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or\n" +"POSIX_FADV_DONTNEED."); + +#define OS_POSIX_FADVISE_METHODDEF \ + {"posix_fadvise", (PyCFunction)(void(*)(void))os_posix_fadvise, METH_FASTCALL, os_posix_fadvise__doc__}, + +static PyObject * +os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, + Py_off_t length, int advice); + +static PyObject * +os_posix_fadvise(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t offset; + Py_off_t length; + int advice; + + if (!_PyArg_CheckPositional("posix_fadvise", nargs, 4, 4)) { + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -7302,450 +6536,1216 @@ os_fpathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (fd == -1 && PyErr_Occurred()) { goto exit; } - if (!conv_path_confname(args[1], &name)) { + if (!Py_off_t_converter(args[1], &offset)) { goto exit; } - _return_value = os_fpathconf_impl(module, fd, name); - if ((_return_value == -1) && PyErr_Occurred()) { + if (!Py_off_t_converter(args[2], &length)) { goto exit; } - return_value = PyLong_FromLong(_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_FPATHCONF) */ - -#if defined(HAVE_PATHCONF) - -PyDoc_STRVAR(os_pathconf__doc__, -"pathconf($module, /, path, name)\n" -"--\n" -"\n" -"Return the configuration limit name for the file or directory path.\n" -"\n" -"If there is no limit, return -1.\n" -"On some platforms, path may also be specified as an open file descriptor.\n" -" If this functionality is unavailable, using it raises an exception."); - -#define OS_PATHCONF_METHODDEF \ - {"pathconf", (PyCFunction)(void(*)(void))os_pathconf, METH_FASTCALL|METH_KEYWORDS, os_pathconf__doc__}, - -static long -os_pathconf_impl(PyObject *module, path_t *path, int name); - -static PyObject * -os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pathconf", 0}; - PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); - int name; - long _return_value; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (!path_converter(args[0], &path)) { + advice = _PyLong_AsInt(args[3]); + if (advice == -1 && PyErr_Occurred()) { goto exit; } - if (!conv_path_confname(args[1], &name)) { + return_value = os_posix_fadvise_impl(module, fd, offset, length, advice); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os_putenv__doc__, +"putenv($module, name, value, /)\n" +"--\n" +"\n" +"Change or add an environment variable."); + +#define OS_PUTENV_METHODDEF \ + {"putenv", (PyCFunction)(void(*)(void))os_putenv, METH_FASTCALL, os_putenv__doc__}, + +static PyObject * +os_putenv_impl(PyObject *module, PyObject *name, PyObject *value); + +static PyObject * +os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *name; + PyObject *value; + + if (!_PyArg_CheckPositional("putenv", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("putenv", "argument 1", "str", args[0]); goto exit; } - _return_value = os_pathconf_impl(module, &path, name); - if ((_return_value == -1) && PyErr_Occurred()) { + if (PyUnicode_READY(args[0]) == -1) { goto exit; } - return_value = PyLong_FromLong(_return_value); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(HAVE_PATHCONF) */ - -#if defined(HAVE_CONFSTR) - -PyDoc_STRVAR(os_confstr__doc__, -"confstr($module, name, /)\n" -"--\n" -"\n" -"Return a string-valued system configuration variable."); - -#define OS_CONFSTR_METHODDEF \ - {"confstr", (PyCFunction)os_confstr, METH_O, os_confstr__doc__}, - -static PyObject * -os_confstr_impl(PyObject *module, int name); - -static PyObject * -os_confstr(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int name; - - if (!conv_confstr_confname(arg, &name)) { + name = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("putenv", "argument 2", "str", args[1]); goto exit; } - return_value = os_confstr_impl(module, name); - -exit: - return return_value; -} - -#endif /* defined(HAVE_CONFSTR) */ - -#if defined(HAVE_SYSCONF) - -PyDoc_STRVAR(os_sysconf__doc__, -"sysconf($module, name, /)\n" -"--\n" -"\n" -"Return an integer-valued system configuration variable."); - -#define OS_SYSCONF_METHODDEF \ - {"sysconf", (PyCFunction)os_sysconf, METH_O, os_sysconf__doc__}, - -static long -os_sysconf_impl(PyObject *module, int name); - -static PyObject * -os_sysconf(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int name; - long _return_value; - - if (!conv_sysconf_confname(arg, &name)) { + if (PyUnicode_READY(args[1]) == -1) { goto exit; } - _return_value = os_sysconf_impl(module, name); - if ((_return_value == -1) && PyErr_Occurred()) { + value = args[1]; + return_value = os_putenv_impl(module, name, value); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if !defined(MS_WINDOWS) + +PyDoc_STRVAR(os_putenv__doc__, +"putenv($module, name, value, /)\n" +"--\n" +"\n" +"Change or add an environment variable."); + +#define OS_PUTENV_METHODDEF \ + {"putenv", (PyCFunction)(void(*)(void))os_putenv, METH_FASTCALL, os_putenv__doc__}, + +static PyObject * +os_putenv_impl(PyObject *module, PyObject *name, PyObject *value); + +static PyObject * +os_putenv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *name = NULL; + PyObject *value = NULL; + + if (!_PyArg_CheckPositional("putenv", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_FSConverter(args[0], &name)) { goto exit; } - return_value = PyLong_FromLong(_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SYSCONF) */ - -PyDoc_STRVAR(os_abort__doc__, -"abort($module, /)\n" -"--\n" -"\n" -"Abort the interpreter immediately.\n" -"\n" -"This function \'dumps core\' or otherwise fails in the hardest way possible\n" -"on the hosting operating system. This function never returns."); - -#define OS_ABORT_METHODDEF \ - {"abort", (PyCFunction)os_abort, METH_NOARGS, os_abort__doc__}, - -static PyObject * -os_abort_impl(PyObject *module); - -static PyObject * -os_abort(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_abort_impl(module); -} - + if (!PyUnicode_FSConverter(args[1], &value)) { + goto exit; + } + return_value = os_putenv_impl(module, name, value); + +exit: + /* Cleanup for name */ + Py_XDECREF(name); + /* Cleanup for value */ + Py_XDECREF(value); + + return return_value; +} + +#endif /* !defined(MS_WINDOWS) */ + #if defined(MS_WINDOWS) + +PyDoc_STRVAR(os_unsetenv__doc__, +"unsetenv($module, name, /)\n" +"--\n" +"\n" +"Delete an environment variable."); + +#define OS_UNSETENV_METHODDEF \ + {"unsetenv", (PyCFunction)os_unsetenv, METH_O, os_unsetenv__doc__}, + +static PyObject * +os_unsetenv_impl(PyObject *module, PyObject *name); + +static PyObject * +os_unsetenv(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; -PyDoc_STRVAR(os_startfile__doc__, -"startfile($module, /, filepath, operation=)\n" -"--\n" -"\n" -"Start a file with its associated application.\n" -"\n" -"When \"operation\" is not specified or \"open\", this acts like\n" -"double-clicking the file in Explorer, or giving the file name as an\n" -"argument to the DOS \"start\" command: the file is opened with whatever\n" -"application (if any) its extension is associated.\n" -"When another \"operation\" is given, it specifies what should be done with\n" -"the file. A typical operation is \"print\".\n" -"\n" -"startfile returns as soon as the associated application is launched.\n" -"There is no option to wait for the application to close, and no way\n" -"to retrieve the application\'s exit status.\n" -"\n" -"The filepath is relative to the current directory. If you want to use\n" -"an absolute path, make sure the first character is not a slash (\"/\");\n" -"the underlying Win32 ShellExecute function doesn\'t work if it is."); - -#define OS_STARTFILE_METHODDEF \ - {"startfile", (PyCFunction)(void(*)(void))os_startfile, METH_FASTCALL|METH_KEYWORDS, os_startfile__doc__}, - -static PyObject * -os_startfile_impl(PyObject *module, path_t *filepath, - const Py_UNICODE *operation); - -static PyObject * -os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"filepath", "operation", NULL}; - static _PyArg_Parser _parser = {"O&|u:startfile", _keywords, 0}; - path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0); - const Py_UNICODE *operation = NULL; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - path_converter, &filepath, &operation)) { + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("unsetenv", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { goto exit; } - return_value = os_startfile_impl(module, &filepath, operation); + name = arg; + return_value = os_unsetenv_impl(module, name); exit: - /* Cleanup for filepath */ - path_cleanup(&filepath); - return return_value; } #endif /* defined(MS_WINDOWS) */ -#if defined(HAVE_GETLOADAVG) - -PyDoc_STRVAR(os_getloadavg__doc__, -"getloadavg($module, /)\n" -"--\n" -"\n" -"Return average recent system load information.\n" -"\n" -"Return the number of processes in the system run queue averaged over\n" -"the last 1, 5, and 15 minutes as a tuple of three floats.\n" -"Raises OSError if the load average was unobtainable."); - -#define OS_GETLOADAVG_METHODDEF \ - {"getloadavg", (PyCFunction)os_getloadavg, METH_NOARGS, os_getloadavg__doc__}, - -static PyObject * -os_getloadavg_impl(PyObject *module); - -static PyObject * -os_getloadavg(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getloadavg_impl(module); -} - -#endif /* defined(HAVE_GETLOADAVG) */ +#if !defined(MS_WINDOWS) -PyDoc_STRVAR(os_device_encoding__doc__, -"device_encoding($module, /, fd)\n" +PyDoc_STRVAR(os_unsetenv__doc__, +"unsetenv($module, name, /)\n" "--\n" "\n" -"Return a string describing the encoding of a terminal\'s file descriptor.\n" -"\n" -"The file descriptor must be attached to a terminal.\n" -"If the device is not a terminal, return None."); +"Delete an environment variable."); -#define OS_DEVICE_ENCODING_METHODDEF \ - {"device_encoding", (PyCFunction)(void(*)(void))os_device_encoding, METH_FASTCALL|METH_KEYWORDS, os_device_encoding__doc__}, +#define OS_UNSETENV_METHODDEF \ + {"unsetenv", (PyCFunction)os_unsetenv, METH_O, os_unsetenv__doc__}, static PyObject * -os_device_encoding_impl(PyObject *module, int fd); +os_unsetenv_impl(PyObject *module, PyObject *name); static PyObject * -os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +os_unsetenv(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "device_encoding", 0}; + PyObject *name = NULL; + + if (!PyUnicode_FSConverter(arg, &name)) { + goto exit; + } + return_value = os_unsetenv_impl(module, name); + +exit: + /* Cleanup for name */ + Py_XDECREF(name); + + return return_value; +} + +#endif /* !defined(MS_WINDOWS) */ + +PyDoc_STRVAR(os_strerror__doc__, +"strerror($module, code, /)\n" +"--\n" +"\n" +"Translate an error code to a message string."); + +#define OS_STRERROR_METHODDEF \ + {"strerror", (PyCFunction)os_strerror, METH_O, os_strerror__doc__}, + +static PyObject * +os_strerror_impl(PyObject *module, int code); + +static PyObject * +os_strerror(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int code; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + code = _PyLong_AsInt(arg); + if (code == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os_strerror_impl(module, code); + +exit: + return return_value; +} + +#if defined(HAVE_SYS_WAIT_H) && defined(WCOREDUMP) + +PyDoc_STRVAR(os_WCOREDUMP__doc__, +"WCOREDUMP($module, status, /)\n" +"--\n" +"\n" +"Return True if the process returning status was dumped to a core file."); + +#define OS_WCOREDUMP_METHODDEF \ + {"WCOREDUMP", (PyCFunction)os_WCOREDUMP, METH_O, os_WCOREDUMP__doc__}, + +static int +os_WCOREDUMP_impl(PyObject *module, int status); + +static PyObject * +os_WCOREDUMP(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int status; + int _return_value; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + status = _PyLong_AsInt(arg); + if (status == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = os_WCOREDUMP_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYS_WAIT_H) && defined(WCOREDUMP) */ + +#if defined(HAVE_SYS_WAIT_H) && defined(WIFCONTINUED) + +PyDoc_STRVAR(os_WIFCONTINUED__doc__, +"WIFCONTINUED($module, /, status)\n" +"--\n" +"\n" +"Return True if a particular process was continued from a job control stop.\n" +"\n" +"Return True if the process returning status was continued from a\n" +"job control stop."); + +#define OS_WIFCONTINUED_METHODDEF \ + {"WIFCONTINUED", (PyCFunction)(void(*)(void))os_WIFCONTINUED, METH_FASTCALL|METH_KEYWORDS, os_WIFCONTINUED__doc__}, + +static int +os_WIFCONTINUED_impl(PyObject *module, int status); + +static PyObject * +os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "WIFCONTINUED", 0}; PyObject *argsbuf[1]; - int fd; - + int status; + int _return_value; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + status = _PyLong_AsInt(args[0]); + if (status == -1 && PyErr_Occurred()) { goto exit; } + _return_value = os_WIFCONTINUED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYS_WAIT_H) && defined(WIFCONTINUED) */ + +#if defined(HAVE_SYS_WAIT_H) && defined(WIFSTOPPED) + +PyDoc_STRVAR(os_WIFSTOPPED__doc__, +"WIFSTOPPED($module, /, status)\n" +"--\n" +"\n" +"Return True if the process returning status was stopped."); + +#define OS_WIFSTOPPED_METHODDEF \ + {"WIFSTOPPED", (PyCFunction)(void(*)(void))os_WIFSTOPPED, METH_FASTCALL|METH_KEYWORDS, os_WIFSTOPPED__doc__}, + +static int +os_WIFSTOPPED_impl(PyObject *module, int status); + +static PyObject * +os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "WIFSTOPPED", 0}; + PyObject *argsbuf[1]; + int status; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); goto exit; } - fd = _PyLong_AsInt(args[0]); + status = _PyLong_AsInt(args[0]); + if (status == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = os_WIFSTOPPED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYS_WAIT_H) && defined(WIFSTOPPED) */ + +#if defined(HAVE_SYS_WAIT_H) && defined(WIFSIGNALED) + +PyDoc_STRVAR(os_WIFSIGNALED__doc__, +"WIFSIGNALED($module, /, status)\n" +"--\n" +"\n" +"Return True if the process returning status was terminated by a signal."); + +#define OS_WIFSIGNALED_METHODDEF \ + {"WIFSIGNALED", (PyCFunction)(void(*)(void))os_WIFSIGNALED, METH_FASTCALL|METH_KEYWORDS, os_WIFSIGNALED__doc__}, + +static int +os_WIFSIGNALED_impl(PyObject *module, int status); + +static PyObject * +os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "WIFSIGNALED", 0}; + PyObject *argsbuf[1]; + int status; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + status = _PyLong_AsInt(args[0]); + if (status == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = os_WIFSIGNALED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYS_WAIT_H) && defined(WIFSIGNALED) */ + +#if defined(HAVE_SYS_WAIT_H) && defined(WIFEXITED) + +PyDoc_STRVAR(os_WIFEXITED__doc__, +"WIFEXITED($module, /, status)\n" +"--\n" +"\n" +"Return True if the process returning status exited via the exit() system call."); + +#define OS_WIFEXITED_METHODDEF \ + {"WIFEXITED", (PyCFunction)(void(*)(void))os_WIFEXITED, METH_FASTCALL|METH_KEYWORDS, os_WIFEXITED__doc__}, + +static int +os_WIFEXITED_impl(PyObject *module, int status); + +static PyObject * +os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "WIFEXITED", 0}; + PyObject *argsbuf[1]; + int status; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + status = _PyLong_AsInt(args[0]); + if (status == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = os_WIFEXITED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYS_WAIT_H) && defined(WIFEXITED) */ + +#if defined(HAVE_SYS_WAIT_H) && defined(WEXITSTATUS) + +PyDoc_STRVAR(os_WEXITSTATUS__doc__, +"WEXITSTATUS($module, /, status)\n" +"--\n" +"\n" +"Return the process return code from status."); + +#define OS_WEXITSTATUS_METHODDEF \ + {"WEXITSTATUS", (PyCFunction)(void(*)(void))os_WEXITSTATUS, METH_FASTCALL|METH_KEYWORDS, os_WEXITSTATUS__doc__}, + +static int +os_WEXITSTATUS_impl(PyObject *module, int status); + +static PyObject * +os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "WEXITSTATUS", 0}; + PyObject *argsbuf[1]; + int status; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + status = _PyLong_AsInt(args[0]); + if (status == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = os_WEXITSTATUS_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYS_WAIT_H) && defined(WEXITSTATUS) */ + +#if defined(HAVE_SYS_WAIT_H) && defined(WTERMSIG) + +PyDoc_STRVAR(os_WTERMSIG__doc__, +"WTERMSIG($module, /, status)\n" +"--\n" +"\n" +"Return the signal that terminated the process that provided the status value."); + +#define OS_WTERMSIG_METHODDEF \ + {"WTERMSIG", (PyCFunction)(void(*)(void))os_WTERMSIG, METH_FASTCALL|METH_KEYWORDS, os_WTERMSIG__doc__}, + +static int +os_WTERMSIG_impl(PyObject *module, int status); + +static PyObject * +os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "WTERMSIG", 0}; + PyObject *argsbuf[1]; + int status; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + status = _PyLong_AsInt(args[0]); + if (status == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = os_WTERMSIG_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYS_WAIT_H) && defined(WTERMSIG) */ + +#if defined(HAVE_SYS_WAIT_H) && defined(WSTOPSIG) + +PyDoc_STRVAR(os_WSTOPSIG__doc__, +"WSTOPSIG($module, /, status)\n" +"--\n" +"\n" +"Return the signal that stopped the process that provided the status value."); + +#define OS_WSTOPSIG_METHODDEF \ + {"WSTOPSIG", (PyCFunction)(void(*)(void))os_WSTOPSIG, METH_FASTCALL|METH_KEYWORDS, os_WSTOPSIG__doc__}, + +static int +os_WSTOPSIG_impl(PyObject *module, int status); + +static PyObject * +os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"status", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "WSTOPSIG", 0}; + PyObject *argsbuf[1]; + int status; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + status = _PyLong_AsInt(args[0]); + if (status == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = os_WSTOPSIG_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYS_WAIT_H) && defined(WSTOPSIG) */ + +#if (defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)) + +PyDoc_STRVAR(os_fstatvfs__doc__, +"fstatvfs($module, fd, /)\n" +"--\n" +"\n" +"Perform an fstatvfs system call on the given fd.\n" +"\n" +"Equivalent to statvfs(fd)."); + +#define OS_FSTATVFS_METHODDEF \ + {"fstatvfs", (PyCFunction)os_fstatvfs, METH_O, os_fstatvfs__doc__}, + +static PyObject * +os_fstatvfs_impl(PyObject *module, int fd); + +static PyObject * +os_fstatvfs(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_device_encoding_impl(module, fd); - -exit: - return return_value; -} - -#if defined(HAVE_SETRESUID) - -PyDoc_STRVAR(os_setresuid__doc__, -"setresuid($module, ruid, euid, suid, /)\n" -"--\n" -"\n" -"Set the current process\'s real, effective, and saved user ids."); - -#define OS_SETRESUID_METHODDEF \ - {"setresuid", (PyCFunction)(void(*)(void))os_setresuid, METH_FASTCALL, os_setresuid__doc__}, - -static PyObject * -os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid); - -static PyObject * -os_setresuid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - uid_t ruid; - uid_t euid; - uid_t suid; - - if (!_PyArg_CheckPositional("setresuid", nargs, 3, 3)) { + return_value = os_fstatvfs_impl(module, fd); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)) */ + +#if (defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)) + +PyDoc_STRVAR(os_statvfs__doc__, +"statvfs($module, /, path)\n" +"--\n" +"\n" +"Perform a statvfs system call on the given path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_STATVFS_METHODDEF \ + {"statvfs", (PyCFunction)(void(*)(void))os_statvfs, METH_FASTCALL|METH_KEYWORDS, os_statvfs__doc__}, + +static PyObject * +os_statvfs_impl(PyObject *module, path_t *path); + +static PyObject * +os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "statvfs", 0}; + PyObject *argsbuf[1]; + path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { goto exit; } - if (!_Py_Uid_Converter(args[0], &ruid)) { + return_value = os_statvfs_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* (defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__getdiskusage__doc__, +"_getdiskusage($module, /, path)\n" +"--\n" +"\n" +"Return disk usage statistics about the given path as a (total, free) tuple."); + +#define OS__GETDISKUSAGE_METHODDEF \ + {"_getdiskusage", (PyCFunction)(void(*)(void))os__getdiskusage, METH_FASTCALL|METH_KEYWORDS, os__getdiskusage__doc__}, + +static PyObject * +os__getdiskusage_impl(PyObject *module, path_t *path); + +static PyObject * +os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "_getdiskusage", 0}; + PyObject *argsbuf[1]; + path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0); + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { goto exit; } - if (!_Py_Uid_Converter(args[1], &euid)) { + return_value = os__getdiskusage_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(HAVE_FPATHCONF) + +PyDoc_STRVAR(os_fpathconf__doc__, +"fpathconf($module, fd, name, /)\n" +"--\n" +"\n" +"Return the configuration limit name for the file descriptor fd.\n" +"\n" +"If there is no limit, return -1."); + +#define OS_FPATHCONF_METHODDEF \ + {"fpathconf", (PyCFunction)(void(*)(void))os_fpathconf, METH_FASTCALL, os_fpathconf__doc__}, + +static long +os_fpathconf_impl(PyObject *module, int fd, int name); + +static PyObject * +os_fpathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int name; + long _return_value; + + if (!_PyArg_CheckPositional("fpathconf", nargs, 2, 2)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - if (!_Py_Uid_Converter(args[2], &suid)) { + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_setresuid_impl(module, ruid, euid, suid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETRESUID) */ - -#if defined(HAVE_SETRESGID) - -PyDoc_STRVAR(os_setresgid__doc__, -"setresgid($module, rgid, egid, sgid, /)\n" -"--\n" -"\n" -"Set the current process\'s real, effective, and saved group ids."); - -#define OS_SETRESGID_METHODDEF \ - {"setresgid", (PyCFunction)(void(*)(void))os_setresgid, METH_FASTCALL, os_setresgid__doc__}, - -static PyObject * -os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid); - -static PyObject * -os_setresgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - gid_t rgid; - gid_t egid; - gid_t sgid; - - if (!_PyArg_CheckPositional("setresgid", nargs, 3, 3)) { + if (!conv_path_confname(args[1], &name)) { goto exit; } - if (!_Py_Gid_Converter(args[0], &rgid)) { + _return_value = os_fpathconf_impl(module, fd, name); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_FPATHCONF) */ + +#if defined(HAVE_PATHCONF) + +PyDoc_STRVAR(os_pathconf__doc__, +"pathconf($module, /, path, name)\n" +"--\n" +"\n" +"Return the configuration limit name for the file or directory path.\n" +"\n" +"If there is no limit, return -1.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_PATHCONF_METHODDEF \ + {"pathconf", (PyCFunction)(void(*)(void))os_pathconf, METH_FASTCALL|METH_KEYWORDS, os_pathconf__doc__}, + +static long +os_pathconf_impl(PyObject *module, path_t *path, int name); + +static PyObject * +os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "name", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "pathconf", 0}; + PyObject *argsbuf[2]; + path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); + int name; + long _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { goto exit; } - if (!_Py_Gid_Converter(args[1], &egid)) { + if (!conv_path_confname(args[1], &name)) { goto exit; } - if (!_Py_Gid_Converter(args[2], &sgid)) { + _return_value = os_pathconf_impl(module, &path, name); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(HAVE_PATHCONF) */ + +#if defined(HAVE_CONFSTR) + +PyDoc_STRVAR(os_confstr__doc__, +"confstr($module, name, /)\n" +"--\n" +"\n" +"Return a string-valued system configuration variable."); + +#define OS_CONFSTR_METHODDEF \ + {"confstr", (PyCFunction)os_confstr, METH_O, os_confstr__doc__}, + +static PyObject * +os_confstr_impl(PyObject *module, int name); + +static PyObject * +os_confstr(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int name; + + if (!conv_confstr_confname(arg, &name)) { + goto exit; + } + return_value = os_confstr_impl(module, name); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CONFSTR) */ + +#if defined(HAVE_SYSCONF) + +PyDoc_STRVAR(os_sysconf__doc__, +"sysconf($module, name, /)\n" +"--\n" +"\n" +"Return an integer-valued system configuration variable."); + +#define OS_SYSCONF_METHODDEF \ + {"sysconf", (PyCFunction)os_sysconf, METH_O, os_sysconf__doc__}, + +static long +os_sysconf_impl(PyObject *module, int name); + +static PyObject * +os_sysconf(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int name; + long _return_value; + + if (!conv_sysconf_confname(arg, &name)) { + goto exit; + } + _return_value = os_sysconf_impl(module, name); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SYSCONF) */ + +PyDoc_STRVAR(os_abort__doc__, +"abort($module, /)\n" +"--\n" +"\n" +"Abort the interpreter immediately.\n" +"\n" +"This function \'dumps core\' or otherwise fails in the hardest way possible\n" +"on the hosting operating system. This function never returns."); + +#define OS_ABORT_METHODDEF \ + {"abort", (PyCFunction)os_abort, METH_NOARGS, os_abort__doc__}, + +static PyObject * +os_abort_impl(PyObject *module); + +static PyObject * +os_abort(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_abort_impl(module); +} + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os_startfile__doc__, +"startfile($module, /, filepath, operation=)\n" +"--\n" +"\n" +"Start a file with its associated application.\n" +"\n" +"When \"operation\" is not specified or \"open\", this acts like\n" +"double-clicking the file in Explorer, or giving the file name as an\n" +"argument to the DOS \"start\" command: the file is opened with whatever\n" +"application (if any) its extension is associated.\n" +"When another \"operation\" is given, it specifies what should be done with\n" +"the file. A typical operation is \"print\".\n" +"\n" +"startfile returns as soon as the associated application is launched.\n" +"There is no option to wait for the application to close, and no way\n" +"to retrieve the application\'s exit status.\n" +"\n" +"The filepath is relative to the current directory. If you want to use\n" +"an absolute path, make sure the first character is not a slash (\"/\");\n" +"the underlying Win32 ShellExecute function doesn\'t work if it is."); + +#define OS_STARTFILE_METHODDEF \ + {"startfile", (PyCFunction)(void(*)(void))os_startfile, METH_FASTCALL|METH_KEYWORDS, os_startfile__doc__}, + +static PyObject * +os_startfile_impl(PyObject *module, path_t *filepath, + const Py_UNICODE *operation); + +static PyObject * +os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"filepath", "operation", NULL}; + static _PyArg_Parser _parser = {"O&|u:startfile", _keywords, 0}; + path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0); + const Py_UNICODE *operation = NULL; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + path_converter, &filepath, &operation)) { + goto exit; + } + return_value = os_startfile_impl(module, &filepath, operation); + +exit: + /* Cleanup for filepath */ + path_cleanup(&filepath); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(HAVE_GETLOADAVG) + +PyDoc_STRVAR(os_getloadavg__doc__, +"getloadavg($module, /)\n" +"--\n" +"\n" +"Return average recent system load information.\n" +"\n" +"Return the number of processes in the system run queue averaged over\n" +"the last 1, 5, and 15 minutes as a tuple of three floats.\n" +"Raises OSError if the load average was unobtainable."); + +#define OS_GETLOADAVG_METHODDEF \ + {"getloadavg", (PyCFunction)os_getloadavg, METH_NOARGS, os_getloadavg__doc__}, + +static PyObject * +os_getloadavg_impl(PyObject *module); + +static PyObject * +os_getloadavg(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getloadavg_impl(module); +} + +#endif /* defined(HAVE_GETLOADAVG) */ + +PyDoc_STRVAR(os_device_encoding__doc__, +"device_encoding($module, /, fd)\n" +"--\n" +"\n" +"Return a string describing the encoding of a terminal\'s file descriptor.\n" +"\n" +"The file descriptor must be attached to a terminal.\n" +"If the device is not a terminal, return None."); + +#define OS_DEVICE_ENCODING_METHODDEF \ + {"device_encoding", (PyCFunction)(void(*)(void))os_device_encoding, METH_FASTCALL|METH_KEYWORDS, os_device_encoding__doc__}, + +static PyObject * +os_device_encoding_impl(PyObject *module, int fd); + +static PyObject * +os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"fd", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "device_encoding", 0}; + PyObject *argsbuf[1]; + int fd; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); goto exit; } - return_value = os_setresgid_impl(module, rgid, egid, sgid); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETRESGID) */ - -#if defined(HAVE_GETRESUID) - -PyDoc_STRVAR(os_getresuid__doc__, -"getresuid($module, /)\n" -"--\n" -"\n" -"Return a tuple of the current process\'s real, effective, and saved user ids."); - -#define OS_GETRESUID_METHODDEF \ - {"getresuid", (PyCFunction)os_getresuid, METH_NOARGS, os_getresuid__doc__}, - -static PyObject * -os_getresuid_impl(PyObject *module); - -static PyObject * -os_getresuid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getresuid_impl(module); -} - -#endif /* defined(HAVE_GETRESUID) */ - -#if defined(HAVE_GETRESGID) - -PyDoc_STRVAR(os_getresgid__doc__, -"getresgid($module, /)\n" -"--\n" -"\n" -"Return a tuple of the current process\'s real, effective, and saved group ids."); - -#define OS_GETRESGID_METHODDEF \ - {"getresgid", (PyCFunction)os_getresgid, METH_NOARGS, os_getresgid__doc__}, - -static PyObject * -os_getresgid_impl(PyObject *module); - -static PyObject * -os_getresgid(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_getresgid_impl(module); -} - -#endif /* defined(HAVE_GETRESGID) */ - -#if defined(USE_XATTRS) - -PyDoc_STRVAR(os_getxattr__doc__, -"getxattr($module, /, path, attribute, *, follow_symlinks=True)\n" -"--\n" -"\n" -"Return the value of extended attribute attribute on path.\n" -"\n" -"path may be either a string, a path-like object, or an open file descriptor.\n" -"If follow_symlinks is False, and the last element of the path is a symbolic\n" -" link, getxattr will examine the symbolic link itself instead of the file\n" -" the link points to."); - -#define OS_GETXATTR_METHODDEF \ + fd = _PyLong_AsInt(args[0]); + if (fd == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os_device_encoding_impl(module, fd); + +exit: + return return_value; +} + +#if defined(HAVE_SETRESUID) + +PyDoc_STRVAR(os_setresuid__doc__, +"setresuid($module, ruid, euid, suid, /)\n" +"--\n" +"\n" +"Set the current process\'s real, effective, and saved user ids."); + +#define OS_SETRESUID_METHODDEF \ + {"setresuid", (PyCFunction)(void(*)(void))os_setresuid, METH_FASTCALL, os_setresuid__doc__}, + +static PyObject * +os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid); + +static PyObject * +os_setresuid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + uid_t ruid; + uid_t euid; + uid_t suid; + + if (!_PyArg_CheckPositional("setresuid", nargs, 3, 3)) { + goto exit; + } + if (!_Py_Uid_Converter(args[0], &ruid)) { + goto exit; + } + if (!_Py_Uid_Converter(args[1], &euid)) { + goto exit; + } + if (!_Py_Uid_Converter(args[2], &suid)) { + goto exit; + } + return_value = os_setresuid_impl(module, ruid, euid, suid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETRESUID) */ + +#if defined(HAVE_SETRESGID) + +PyDoc_STRVAR(os_setresgid__doc__, +"setresgid($module, rgid, egid, sgid, /)\n" +"--\n" +"\n" +"Set the current process\'s real, effective, and saved group ids."); + +#define OS_SETRESGID_METHODDEF \ + {"setresgid", (PyCFunction)(void(*)(void))os_setresgid, METH_FASTCALL, os_setresgid__doc__}, + +static PyObject * +os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid); + +static PyObject * +os_setresgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + gid_t rgid; + gid_t egid; + gid_t sgid; + + if (!_PyArg_CheckPositional("setresgid", nargs, 3, 3)) { + goto exit; + } + if (!_Py_Gid_Converter(args[0], &rgid)) { + goto exit; + } + if (!_Py_Gid_Converter(args[1], &egid)) { + goto exit; + } + if (!_Py_Gid_Converter(args[2], &sgid)) { + goto exit; + } + return_value = os_setresgid_impl(module, rgid, egid, sgid); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETRESGID) */ + +#if defined(HAVE_GETRESUID) + +PyDoc_STRVAR(os_getresuid__doc__, +"getresuid($module, /)\n" +"--\n" +"\n" +"Return a tuple of the current process\'s real, effective, and saved user ids."); + +#define OS_GETRESUID_METHODDEF \ + {"getresuid", (PyCFunction)os_getresuid, METH_NOARGS, os_getresuid__doc__}, + +static PyObject * +os_getresuid_impl(PyObject *module); + +static PyObject * +os_getresuid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getresuid_impl(module); +} + +#endif /* defined(HAVE_GETRESUID) */ + +#if defined(HAVE_GETRESGID) + +PyDoc_STRVAR(os_getresgid__doc__, +"getresgid($module, /)\n" +"--\n" +"\n" +"Return a tuple of the current process\'s real, effective, and saved group ids."); + +#define OS_GETRESGID_METHODDEF \ + {"getresgid", (PyCFunction)os_getresgid, METH_NOARGS, os_getresgid__doc__}, + +static PyObject * +os_getresgid_impl(PyObject *module); + +static PyObject * +os_getresgid(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getresgid_impl(module); +} + +#endif /* defined(HAVE_GETRESGID) */ + +#if defined(USE_XATTRS) + +PyDoc_STRVAR(os_getxattr__doc__, +"getxattr($module, /, path, attribute, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Return the value of extended attribute attribute on path.\n" +"\n" +"path may be either a string, a path-like object, or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, getxattr will examine the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_GETXATTR_METHODDEF \ {"getxattr", (PyCFunction)(void(*)(void))os_getxattr, METH_FASTCALL|METH_KEYWORDS, os_getxattr__doc__}, - -static PyObject * -os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, - int follow_symlinks); - -static PyObject * -os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + +static PyObject * +os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, + int follow_symlinks); + +static PyObject * +os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "getxattr", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); - path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0); - int follow_symlinks = 1; - + path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0); + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -7760,58 +7760,58 @@ os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } skip_optional_kwonly: - return_value = os_getxattr_impl(module, &path, &attribute, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - /* Cleanup for attribute */ - path_cleanup(&attribute); - - return return_value; -} - -#endif /* defined(USE_XATTRS) */ - -#if defined(USE_XATTRS) - -PyDoc_STRVAR(os_setxattr__doc__, -"setxattr($module, /, path, attribute, value, flags=0, *,\n" -" follow_symlinks=True)\n" -"--\n" -"\n" -"Set extended attribute attribute on path to value.\n" -"\n" -"path may be either a string, a path-like object, or an open file descriptor.\n" -"If follow_symlinks is False, and the last element of the path is a symbolic\n" -" link, setxattr will modify the symbolic link itself instead of the file\n" -" the link points to."); - -#define OS_SETXATTR_METHODDEF \ + return_value = os_getxattr_impl(module, &path, &attribute, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + /* Cleanup for attribute */ + path_cleanup(&attribute); + + return return_value; +} + +#endif /* defined(USE_XATTRS) */ + +#if defined(USE_XATTRS) + +PyDoc_STRVAR(os_setxattr__doc__, +"setxattr($module, /, path, attribute, value, flags=0, *,\n" +" follow_symlinks=True)\n" +"--\n" +"\n" +"Set extended attribute attribute on path to value.\n" +"\n" +"path may be either a string, a path-like object, or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, setxattr will modify the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_SETXATTR_METHODDEF \ {"setxattr", (PyCFunction)(void(*)(void))os_setxattr, METH_FASTCALL|METH_KEYWORDS, os_setxattr__doc__}, - -static PyObject * -os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, - Py_buffer *value, int flags, int follow_symlinks); - -static PyObject * -os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; + +static PyObject * +os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, + Py_buffer *value, int flags, int follow_symlinks); + +static PyObject * +os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "setxattr", 0}; PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); - path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0); - Py_buffer value = {NULL, NULL}; - int flags = 0; - int follow_symlinks = 1; - + path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0); + Py_buffer value = {NULL, NULL}; + int flags = 0; + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 4, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -7851,59 +7851,59 @@ skip_optional_pos: goto exit; } skip_optional_kwonly: - return_value = os_setxattr_impl(module, &path, &attribute, &value, flags, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - /* Cleanup for attribute */ - path_cleanup(&attribute); - /* Cleanup for value */ - if (value.obj) { - PyBuffer_Release(&value); - } - - return return_value; -} - -#endif /* defined(USE_XATTRS) */ - -#if defined(USE_XATTRS) - -PyDoc_STRVAR(os_removexattr__doc__, -"removexattr($module, /, path, attribute, *, follow_symlinks=True)\n" -"--\n" -"\n" -"Remove extended attribute attribute on path.\n" -"\n" -"path may be either a string, a path-like object, or an open file descriptor.\n" -"If follow_symlinks is False, and the last element of the path is a symbolic\n" -" link, removexattr will modify the symbolic link itself instead of the file\n" -" the link points to."); - -#define OS_REMOVEXATTR_METHODDEF \ + return_value = os_setxattr_impl(module, &path, &attribute, &value, flags, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + /* Cleanup for attribute */ + path_cleanup(&attribute); + /* Cleanup for value */ + if (value.obj) { + PyBuffer_Release(&value); + } + + return return_value; +} + +#endif /* defined(USE_XATTRS) */ + +#if defined(USE_XATTRS) + +PyDoc_STRVAR(os_removexattr__doc__, +"removexattr($module, /, path, attribute, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Remove extended attribute attribute on path.\n" +"\n" +"path may be either a string, a path-like object, or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, removexattr will modify the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_REMOVEXATTR_METHODDEF \ {"removexattr", (PyCFunction)(void(*)(void))os_removexattr, METH_FASTCALL|METH_KEYWORDS, os_removexattr__doc__}, - -static PyObject * -os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, - int follow_symlinks); - -static PyObject * -os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + +static PyObject * +os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, + int follow_symlinks); + +static PyObject * +os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "removexattr", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); - path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0); - int follow_symlinks = 1; - + path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0); + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!path_converter(args[0], &path)) { goto exit; } @@ -7918,54 +7918,54 @@ os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje goto exit; } skip_optional_kwonly: - return_value = os_removexattr_impl(module, &path, &attribute, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - /* Cleanup for attribute */ - path_cleanup(&attribute); - - return return_value; -} - -#endif /* defined(USE_XATTRS) */ - -#if defined(USE_XATTRS) - -PyDoc_STRVAR(os_listxattr__doc__, -"listxattr($module, /, path=None, *, follow_symlinks=True)\n" -"--\n" -"\n" -"Return a list of extended attributes on path.\n" -"\n" -"path may be either None, a string, a path-like object, or an open file descriptor.\n" -"if path is None, listxattr will examine the current directory.\n" -"If follow_symlinks is False, and the last element of the path is a symbolic\n" -" link, listxattr will examine the symbolic link itself instead of the file\n" -" the link points to."); - -#define OS_LISTXATTR_METHODDEF \ + return_value = os_removexattr_impl(module, &path, &attribute, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + /* Cleanup for attribute */ + path_cleanup(&attribute); + + return return_value; +} + +#endif /* defined(USE_XATTRS) */ + +#if defined(USE_XATTRS) + +PyDoc_STRVAR(os_listxattr__doc__, +"listxattr($module, /, path=None, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Return a list of extended attributes on path.\n" +"\n" +"path may be either None, a string, a path-like object, or an open file descriptor.\n" +"if path is None, listxattr will examine the current directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, listxattr will examine the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_LISTXATTR_METHODDEF \ {"listxattr", (PyCFunction)(void(*)(void))os_listxattr, METH_FASTCALL|METH_KEYWORDS, os_listxattr__doc__}, - -static PyObject * -os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks); - -static PyObject * -os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", "follow_symlinks", NULL}; + +static PyObject * +os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks); + +static PyObject * +os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", "follow_symlinks", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "listxattr", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); - int follow_symlinks = 1; - + path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); + int follow_symlinks = 1; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -7986,40 +7986,40 @@ skip_optional_pos: goto exit; } skip_optional_kwonly: - return_value = os_listxattr_impl(module, &path, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -#endif /* defined(USE_XATTRS) */ - -PyDoc_STRVAR(os_urandom__doc__, -"urandom($module, size, /)\n" -"--\n" -"\n" -"Return a bytes object containing random bytes suitable for cryptographic use."); - -#define OS_URANDOM_METHODDEF \ - {"urandom", (PyCFunction)os_urandom, METH_O, os_urandom__doc__}, - -static PyObject * -os_urandom_impl(PyObject *module, Py_ssize_t size); - -static PyObject * -os_urandom(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_ssize_t size; - + return_value = os_listxattr_impl(module, &path, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(USE_XATTRS) */ + +PyDoc_STRVAR(os_urandom__doc__, +"urandom($module, size, /)\n" +"--\n" +"\n" +"Return a bytes object containing random bytes suitable for cryptographic use."); + +#define OS_URANDOM_METHODDEF \ + {"urandom", (PyCFunction)os_urandom, METH_O, os_urandom__doc__}, + +static PyObject * +os_urandom_impl(PyObject *module, Py_ssize_t size); + +static PyObject * +os_urandom(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t size; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } { Py_ssize_t ival = -1; PyObject *iobj = PyNumber_Index(arg); @@ -8032,12 +8032,12 @@ os_urandom(PyObject *module, PyObject *arg) } size = ival; } - return_value = os_urandom_impl(module, size); - -exit: - return return_value; -} - + return_value = os_urandom_impl(module, size); + +exit: + return return_value; +} + #if defined(HAVE_MEMFD_CREATE) PyDoc_STRVAR(os_memfd_create__doc__, @@ -8149,88 +8149,88 @@ exit: #endif /* (defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)) */ -PyDoc_STRVAR(os_cpu_count__doc__, -"cpu_count($module, /)\n" -"--\n" -"\n" -"Return the number of CPUs in the system; return None if indeterminable.\n" -"\n" -"This number is not equivalent to the number of CPUs the current process can\n" -"use. The number of usable CPUs can be obtained with\n" -"``len(os.sched_getaffinity(0))``"); - -#define OS_CPU_COUNT_METHODDEF \ - {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__}, - -static PyObject * -os_cpu_count_impl(PyObject *module); - -static PyObject * -os_cpu_count(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return os_cpu_count_impl(module); -} - -PyDoc_STRVAR(os_get_inheritable__doc__, -"get_inheritable($module, fd, /)\n" -"--\n" -"\n" -"Get the close-on-exe flag of the specified file descriptor."); - -#define OS_GET_INHERITABLE_METHODDEF \ - {"get_inheritable", (PyCFunction)os_get_inheritable, METH_O, os_get_inheritable__doc__}, - -static int -os_get_inheritable_impl(PyObject *module, int fd); - -static PyObject * -os_get_inheritable(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int fd; - int _return_value; - +PyDoc_STRVAR(os_cpu_count__doc__, +"cpu_count($module, /)\n" +"--\n" +"\n" +"Return the number of CPUs in the system; return None if indeterminable.\n" +"\n" +"This number is not equivalent to the number of CPUs the current process can\n" +"use. The number of usable CPUs can be obtained with\n" +"``len(os.sched_getaffinity(0))``"); + +#define OS_CPU_COUNT_METHODDEF \ + {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__}, + +static PyObject * +os_cpu_count_impl(PyObject *module); + +static PyObject * +os_cpu_count(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_cpu_count_impl(module); +} + +PyDoc_STRVAR(os_get_inheritable__doc__, +"get_inheritable($module, fd, /)\n" +"--\n" +"\n" +"Get the close-on-exe flag of the specified file descriptor."); + +#define OS_GET_INHERITABLE_METHODDEF \ + {"get_inheritable", (PyCFunction)os_get_inheritable, METH_O, os_get_inheritable__doc__}, + +static int +os_get_inheritable_impl(PyObject *module, int fd); + +static PyObject * +os_get_inheritable(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + int _return_value; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } fd = _PyLong_AsInt(arg); if (fd == -1 && PyErr_Occurred()) { goto exit; } - _return_value = os_get_inheritable_impl(module, fd); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_set_inheritable__doc__, -"set_inheritable($module, fd, inheritable, /)\n" -"--\n" -"\n" -"Set the inheritable flag of the specified file descriptor."); - -#define OS_SET_INHERITABLE_METHODDEF \ + _return_value = os_get_inheritable_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_set_inheritable__doc__, +"set_inheritable($module, fd, inheritable, /)\n" +"--\n" +"\n" +"Set the inheritable flag of the specified file descriptor."); + +#define OS_SET_INHERITABLE_METHODDEF \ {"set_inheritable", (PyCFunction)(void(*)(void))os_set_inheritable, METH_FASTCALL, os_set_inheritable__doc__}, - -static PyObject * -os_set_inheritable_impl(PyObject *module, int fd, int inheritable); - -static PyObject * -os_set_inheritable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int fd; - int inheritable; - + +static PyObject * +os_set_inheritable_impl(PyObject *module, int fd, int inheritable); + +static PyObject * +os_set_inheritable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + int inheritable; + if (!_PyArg_CheckPositional("set_inheritable", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -8249,82 +8249,82 @@ os_set_inheritable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (inheritable == -1 && PyErr_Occurred()) { goto exit; } - return_value = os_set_inheritable_impl(module, fd, inheritable); - -exit: - return return_value; -} - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(os_get_handle_inheritable__doc__, -"get_handle_inheritable($module, handle, /)\n" -"--\n" -"\n" -"Get the close-on-exe flag of the specified file descriptor."); - -#define OS_GET_HANDLE_INHERITABLE_METHODDEF \ - {"get_handle_inheritable", (PyCFunction)os_get_handle_inheritable, METH_O, os_get_handle_inheritable__doc__}, - -static int -os_get_handle_inheritable_impl(PyObject *module, intptr_t handle); - -static PyObject * -os_get_handle_inheritable(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - intptr_t handle; - int _return_value; - - if (!PyArg_Parse(arg, "" _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) { - goto exit; - } - _return_value = os_get_handle_inheritable_impl(module, handle); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(os_set_handle_inheritable__doc__, -"set_handle_inheritable($module, handle, inheritable, /)\n" -"--\n" -"\n" -"Set the inheritable flag of the specified handle."); - -#define OS_SET_HANDLE_INHERITABLE_METHODDEF \ + return_value = os_set_inheritable_impl(module, fd, inheritable); + +exit: + return return_value; +} + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os_get_handle_inheritable__doc__, +"get_handle_inheritable($module, handle, /)\n" +"--\n" +"\n" +"Get the close-on-exe flag of the specified file descriptor."); + +#define OS_GET_HANDLE_INHERITABLE_METHODDEF \ + {"get_handle_inheritable", (PyCFunction)os_get_handle_inheritable, METH_O, os_get_handle_inheritable__doc__}, + +static int +os_get_handle_inheritable_impl(PyObject *module, intptr_t handle); + +static PyObject * +os_get_handle_inheritable(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + intptr_t handle; + int _return_value; + + if (!PyArg_Parse(arg, "" _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) { + goto exit; + } + _return_value = os_get_handle_inheritable_impl(module, handle); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os_set_handle_inheritable__doc__, +"set_handle_inheritable($module, handle, inheritable, /)\n" +"--\n" +"\n" +"Set the inheritable flag of the specified handle."); + +#define OS_SET_HANDLE_INHERITABLE_METHODDEF \ {"set_handle_inheritable", (PyCFunction)(void(*)(void))os_set_handle_inheritable, METH_FASTCALL, os_set_handle_inheritable__doc__}, - -static PyObject * -os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, - int inheritable); - -static PyObject * -os_set_handle_inheritable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - intptr_t handle; - int inheritable; - - if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_INTPTR "p:set_handle_inheritable", - &handle, &inheritable)) { - goto exit; - } - return_value = os_set_handle_inheritable_impl(module, handle, inheritable); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - + +static PyObject * +os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, + int inheritable); + +static PyObject * +os_set_handle_inheritable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + intptr_t handle; + int inheritable; + + if (!_PyArg_ParseStack(args, nargs, "" _Py_PARSE_INTPTR "p:set_handle_inheritable", + &handle, &inheritable)) { + goto exit; + } + return_value = os_set_handle_inheritable_impl(module, handle, inheritable); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + #if !defined(MS_WINDOWS) PyDoc_STRVAR(os_get_blocking__doc__, @@ -8422,211 +8422,211 @@ exit: #endif /* !defined(MS_WINDOWS) */ -PyDoc_STRVAR(os_DirEntry_is_symlink__doc__, -"is_symlink($self, /)\n" -"--\n" -"\n" -"Return True if the entry is a symbolic link; cached per entry."); - -#define OS_DIRENTRY_IS_SYMLINK_METHODDEF \ +PyDoc_STRVAR(os_DirEntry_is_symlink__doc__, +"is_symlink($self, /)\n" +"--\n" +"\n" +"Return True if the entry is a symbolic link; cached per entry."); + +#define OS_DIRENTRY_IS_SYMLINK_METHODDEF \ {"is_symlink", (PyCFunction)(void(*)(void))os_DirEntry_is_symlink, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_symlink__doc__}, - -static int + +static int os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class); - -static PyObject * + +static PyObject * os_DirEntry_is_symlink(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; +{ + PyObject *return_value = NULL; static const char * const _keywords[] = { NULL}; static _PyArg_Parser _parser = {":is_symlink", _keywords, 0}; - int _return_value; - + int _return_value; + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser )) { goto exit; } _return_value = os_DirEntry_is_symlink_impl(self, defining_class); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_DirEntry_stat__doc__, -"stat($self, /, *, follow_symlinks=True)\n" -"--\n" -"\n" -"Return stat_result object for the entry; cached per entry."); - -#define OS_DIRENTRY_STAT_METHODDEF \ + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_DirEntry_stat__doc__, +"stat($self, /, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Return stat_result object for the entry; cached per entry."); + +#define OS_DIRENTRY_STAT_METHODDEF \ {"stat", (PyCFunction)(void(*)(void))os_DirEntry_stat, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_stat__doc__}, - -static PyObject * + +static PyObject * os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class, int follow_symlinks); - -static PyObject * + +static PyObject * os_DirEntry_stat(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"follow_symlinks", NULL}; +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"follow_symlinks", NULL}; static _PyArg_Parser _parser = {"|$p:stat", _keywords, 0}; - int follow_symlinks = 1; - + int follow_symlinks = 1; + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, &follow_symlinks)) { - goto exit; - } + goto exit; + } return_value = os_DirEntry_stat_impl(self, defining_class, follow_symlinks); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_DirEntry_is_dir__doc__, -"is_dir($self, /, *, follow_symlinks=True)\n" -"--\n" -"\n" -"Return True if the entry is a directory; cached per entry."); - -#define OS_DIRENTRY_IS_DIR_METHODDEF \ + +exit: + return return_value; +} + +PyDoc_STRVAR(os_DirEntry_is_dir__doc__, +"is_dir($self, /, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Return True if the entry is a directory; cached per entry."); + +#define OS_DIRENTRY_IS_DIR_METHODDEF \ {"is_dir", (PyCFunction)(void(*)(void))os_DirEntry_is_dir, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_dir__doc__}, - -static int + +static int os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class, int follow_symlinks); - -static PyObject * + +static PyObject * os_DirEntry_is_dir(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"follow_symlinks", NULL}; +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"follow_symlinks", NULL}; static _PyArg_Parser _parser = {"|$p:is_dir", _keywords, 0}; - int follow_symlinks = 1; - int _return_value; - + int follow_symlinks = 1; + int _return_value; + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, &follow_symlinks)) { - goto exit; - } + goto exit; + } _return_value = os_DirEntry_is_dir_impl(self, defining_class, follow_symlinks); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_DirEntry_is_file__doc__, -"is_file($self, /, *, follow_symlinks=True)\n" -"--\n" -"\n" -"Return True if the entry is a file; cached per entry."); - -#define OS_DIRENTRY_IS_FILE_METHODDEF \ + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_DirEntry_is_file__doc__, +"is_file($self, /, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Return True if the entry is a file; cached per entry."); + +#define OS_DIRENTRY_IS_FILE_METHODDEF \ {"is_file", (PyCFunction)(void(*)(void))os_DirEntry_is_file, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_file__doc__}, - -static int + +static int os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class, int follow_symlinks); - -static PyObject * + +static PyObject * os_DirEntry_is_file(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"follow_symlinks", NULL}; +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"follow_symlinks", NULL}; static _PyArg_Parser _parser = {"|$p:is_file", _keywords, 0}; - int follow_symlinks = 1; - int _return_value; - + int follow_symlinks = 1; + int _return_value; + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, &follow_symlinks)) { - goto exit; - } + goto exit; + } _return_value = os_DirEntry_is_file_impl(self, defining_class, follow_symlinks); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyBool_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(os_DirEntry_inode__doc__, -"inode($self, /)\n" -"--\n" -"\n" -"Return inode of the entry; cached per entry."); - -#define OS_DIRENTRY_INODE_METHODDEF \ - {"inode", (PyCFunction)os_DirEntry_inode, METH_NOARGS, os_DirEntry_inode__doc__}, - -static PyObject * -os_DirEntry_inode_impl(DirEntry *self); - -static PyObject * -os_DirEntry_inode(DirEntry *self, PyObject *Py_UNUSED(ignored)) -{ - return os_DirEntry_inode_impl(self); -} - -PyDoc_STRVAR(os_DirEntry___fspath____doc__, -"__fspath__($self, /)\n" -"--\n" -"\n" -"Returns the path for the entry."); - -#define OS_DIRENTRY___FSPATH___METHODDEF \ - {"__fspath__", (PyCFunction)os_DirEntry___fspath__, METH_NOARGS, os_DirEntry___fspath____doc__}, - -static PyObject * -os_DirEntry___fspath___impl(DirEntry *self); - -static PyObject * -os_DirEntry___fspath__(DirEntry *self, PyObject *Py_UNUSED(ignored)) -{ - return os_DirEntry___fspath___impl(self); -} - -PyDoc_STRVAR(os_scandir__doc__, -"scandir($module, /, path=None)\n" -"--\n" -"\n" -"Return an iterator of DirEntry objects for given path.\n" -"\n" -"path can be specified as either str, bytes, or a path-like object. If path\n" -"is bytes, the names of yielded DirEntry objects will also be bytes; in\n" -"all other circumstances they will be str.\n" -"\n" -"If path is None, uses the path=\'.\'."); - -#define OS_SCANDIR_METHODDEF \ + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_DirEntry_inode__doc__, +"inode($self, /)\n" +"--\n" +"\n" +"Return inode of the entry; cached per entry."); + +#define OS_DIRENTRY_INODE_METHODDEF \ + {"inode", (PyCFunction)os_DirEntry_inode, METH_NOARGS, os_DirEntry_inode__doc__}, + +static PyObject * +os_DirEntry_inode_impl(DirEntry *self); + +static PyObject * +os_DirEntry_inode(DirEntry *self, PyObject *Py_UNUSED(ignored)) +{ + return os_DirEntry_inode_impl(self); +} + +PyDoc_STRVAR(os_DirEntry___fspath____doc__, +"__fspath__($self, /)\n" +"--\n" +"\n" +"Returns the path for the entry."); + +#define OS_DIRENTRY___FSPATH___METHODDEF \ + {"__fspath__", (PyCFunction)os_DirEntry___fspath__, METH_NOARGS, os_DirEntry___fspath____doc__}, + +static PyObject * +os_DirEntry___fspath___impl(DirEntry *self); + +static PyObject * +os_DirEntry___fspath__(DirEntry *self, PyObject *Py_UNUSED(ignored)) +{ + return os_DirEntry___fspath___impl(self); +} + +PyDoc_STRVAR(os_scandir__doc__, +"scandir($module, /, path=None)\n" +"--\n" +"\n" +"Return an iterator of DirEntry objects for given path.\n" +"\n" +"path can be specified as either str, bytes, or a path-like object. If path\n" +"is bytes, the names of yielded DirEntry objects will also be bytes; in\n" +"all other circumstances they will be str.\n" +"\n" +"If path is None, uses the path=\'.\'."); + +#define OS_SCANDIR_METHODDEF \ {"scandir", (PyCFunction)(void(*)(void))os_scandir, METH_FASTCALL|METH_KEYWORDS, os_scandir__doc__}, - -static PyObject * -os_scandir_impl(PyObject *module, path_t *path); - -static PyObject * -os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; + +static PyObject * +os_scandir_impl(PyObject *module, path_t *path); + +static PyObject * +os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "scandir", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("scandir", "path", 1, PATH_HAVE_FDOPENDIR); - + path_t path = PATH_T_INITIALIZE("scandir", "path", 1, PATH_HAVE_FDOPENDIR); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -8634,80 +8634,80 @@ os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * goto exit; } skip_optional_pos: - return_value = os_scandir_impl(module, &path); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} - -PyDoc_STRVAR(os_fspath__doc__, -"fspath($module, /, path)\n" -"--\n" -"\n" -"Return the file system path representation of the object.\n" -"\n" -"If the object is str or bytes, then allow it to pass through as-is. If the\n" -"object defines __fspath__(), then return the result of that method. All other\n" -"types raise a TypeError."); - -#define OS_FSPATH_METHODDEF \ + return_value = os_scandir_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +PyDoc_STRVAR(os_fspath__doc__, +"fspath($module, /, path)\n" +"--\n" +"\n" +"Return the file system path representation of the object.\n" +"\n" +"If the object is str or bytes, then allow it to pass through as-is. If the\n" +"object defines __fspath__(), then return the result of that method. All other\n" +"types raise a TypeError."); + +#define OS_FSPATH_METHODDEF \ {"fspath", (PyCFunction)(void(*)(void))os_fspath, METH_FASTCALL|METH_KEYWORDS, os_fspath__doc__}, - -static PyObject * -os_fspath_impl(PyObject *module, PyObject *path); - -static PyObject * -os_fspath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"path", NULL}; + +static PyObject * +os_fspath_impl(PyObject *module, PyObject *path); + +static PyObject * +os_fspath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "fspath", 0}; PyObject *argsbuf[1]; - PyObject *path; - + PyObject *path; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } path = args[0]; - return_value = os_fspath_impl(module, path); - -exit: - return return_value; -} - -#if defined(HAVE_GETRANDOM_SYSCALL) - -PyDoc_STRVAR(os_getrandom__doc__, -"getrandom($module, /, size, flags=0)\n" -"--\n" -"\n" -"Obtain a series of random bytes."); - -#define OS_GETRANDOM_METHODDEF \ + return_value = os_fspath_impl(module, path); + +exit: + return return_value; +} + +#if defined(HAVE_GETRANDOM_SYSCALL) + +PyDoc_STRVAR(os_getrandom__doc__, +"getrandom($module, /, size, flags=0)\n" +"--\n" +"\n" +"Obtain a series of random bytes."); + +#define OS_GETRANDOM_METHODDEF \ {"getrandom", (PyCFunction)(void(*)(void))os_getrandom, METH_FASTCALL|METH_KEYWORDS, os_getrandom__doc__}, - -static PyObject * -os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags); - -static PyObject * -os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"size", "flags", NULL}; + +static PyObject * +os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags); + +static PyObject * +os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"size", "flags", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "getrandom", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_ssize_t size; - int flags = 0; - + Py_ssize_t size; + int flags = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -8738,14 +8738,14 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } skip_optional_pos: - return_value = os_getrandom_impl(module, size, flags); - -exit: - return return_value; -} - -#endif /* defined(HAVE_GETRANDOM_SYSCALL) */ - + return_value = os_getrandom_impl(module, size, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETRANDOM_SYSCALL) */ + #if defined(MS_WINDOWS) PyDoc_STRVAR(os__add_dll_directory__doc__, @@ -8882,110 +8882,110 @@ exit: #endif /* (defined(WIFEXITED) || defined(MS_WINDOWS)) */ -#ifndef OS_TTYNAME_METHODDEF - #define OS_TTYNAME_METHODDEF -#endif /* !defined(OS_TTYNAME_METHODDEF) */ - -#ifndef OS_CTERMID_METHODDEF - #define OS_CTERMID_METHODDEF -#endif /* !defined(OS_CTERMID_METHODDEF) */ - -#ifndef OS_FCHDIR_METHODDEF - #define OS_FCHDIR_METHODDEF -#endif /* !defined(OS_FCHDIR_METHODDEF) */ - -#ifndef OS_FCHMOD_METHODDEF - #define OS_FCHMOD_METHODDEF -#endif /* !defined(OS_FCHMOD_METHODDEF) */ - -#ifndef OS_LCHMOD_METHODDEF - #define OS_LCHMOD_METHODDEF -#endif /* !defined(OS_LCHMOD_METHODDEF) */ - -#ifndef OS_CHFLAGS_METHODDEF - #define OS_CHFLAGS_METHODDEF -#endif /* !defined(OS_CHFLAGS_METHODDEF) */ - -#ifndef OS_LCHFLAGS_METHODDEF - #define OS_LCHFLAGS_METHODDEF -#endif /* !defined(OS_LCHFLAGS_METHODDEF) */ - -#ifndef OS_CHROOT_METHODDEF - #define OS_CHROOT_METHODDEF -#endif /* !defined(OS_CHROOT_METHODDEF) */ - -#ifndef OS_FSYNC_METHODDEF - #define OS_FSYNC_METHODDEF -#endif /* !defined(OS_FSYNC_METHODDEF) */ - -#ifndef OS_SYNC_METHODDEF - #define OS_SYNC_METHODDEF -#endif /* !defined(OS_SYNC_METHODDEF) */ - -#ifndef OS_FDATASYNC_METHODDEF - #define OS_FDATASYNC_METHODDEF -#endif /* !defined(OS_FDATASYNC_METHODDEF) */ - -#ifndef OS_CHOWN_METHODDEF - #define OS_CHOWN_METHODDEF -#endif /* !defined(OS_CHOWN_METHODDEF) */ - -#ifndef OS_FCHOWN_METHODDEF - #define OS_FCHOWN_METHODDEF -#endif /* !defined(OS_FCHOWN_METHODDEF) */ - -#ifndef OS_LCHOWN_METHODDEF - #define OS_LCHOWN_METHODDEF -#endif /* !defined(OS_LCHOWN_METHODDEF) */ - -#ifndef OS_LINK_METHODDEF - #define OS_LINK_METHODDEF -#endif /* !defined(OS_LINK_METHODDEF) */ - -#ifndef OS__GETFULLPATHNAME_METHODDEF - #define OS__GETFULLPATHNAME_METHODDEF -#endif /* !defined(OS__GETFULLPATHNAME_METHODDEF) */ - -#ifndef OS__GETFINALPATHNAME_METHODDEF - #define OS__GETFINALPATHNAME_METHODDEF -#endif /* !defined(OS__GETFINALPATHNAME_METHODDEF) */ - -#ifndef OS__GETVOLUMEPATHNAME_METHODDEF - #define OS__GETVOLUMEPATHNAME_METHODDEF -#endif /* !defined(OS__GETVOLUMEPATHNAME_METHODDEF) */ - +#ifndef OS_TTYNAME_METHODDEF + #define OS_TTYNAME_METHODDEF +#endif /* !defined(OS_TTYNAME_METHODDEF) */ + +#ifndef OS_CTERMID_METHODDEF + #define OS_CTERMID_METHODDEF +#endif /* !defined(OS_CTERMID_METHODDEF) */ + +#ifndef OS_FCHDIR_METHODDEF + #define OS_FCHDIR_METHODDEF +#endif /* !defined(OS_FCHDIR_METHODDEF) */ + +#ifndef OS_FCHMOD_METHODDEF + #define OS_FCHMOD_METHODDEF +#endif /* !defined(OS_FCHMOD_METHODDEF) */ + +#ifndef OS_LCHMOD_METHODDEF + #define OS_LCHMOD_METHODDEF +#endif /* !defined(OS_LCHMOD_METHODDEF) */ + +#ifndef OS_CHFLAGS_METHODDEF + #define OS_CHFLAGS_METHODDEF +#endif /* !defined(OS_CHFLAGS_METHODDEF) */ + +#ifndef OS_LCHFLAGS_METHODDEF + #define OS_LCHFLAGS_METHODDEF +#endif /* !defined(OS_LCHFLAGS_METHODDEF) */ + +#ifndef OS_CHROOT_METHODDEF + #define OS_CHROOT_METHODDEF +#endif /* !defined(OS_CHROOT_METHODDEF) */ + +#ifndef OS_FSYNC_METHODDEF + #define OS_FSYNC_METHODDEF +#endif /* !defined(OS_FSYNC_METHODDEF) */ + +#ifndef OS_SYNC_METHODDEF + #define OS_SYNC_METHODDEF +#endif /* !defined(OS_SYNC_METHODDEF) */ + +#ifndef OS_FDATASYNC_METHODDEF + #define OS_FDATASYNC_METHODDEF +#endif /* !defined(OS_FDATASYNC_METHODDEF) */ + +#ifndef OS_CHOWN_METHODDEF + #define OS_CHOWN_METHODDEF +#endif /* !defined(OS_CHOWN_METHODDEF) */ + +#ifndef OS_FCHOWN_METHODDEF + #define OS_FCHOWN_METHODDEF +#endif /* !defined(OS_FCHOWN_METHODDEF) */ + +#ifndef OS_LCHOWN_METHODDEF + #define OS_LCHOWN_METHODDEF +#endif /* !defined(OS_LCHOWN_METHODDEF) */ + +#ifndef OS_LINK_METHODDEF + #define OS_LINK_METHODDEF +#endif /* !defined(OS_LINK_METHODDEF) */ + +#ifndef OS__GETFULLPATHNAME_METHODDEF + #define OS__GETFULLPATHNAME_METHODDEF +#endif /* !defined(OS__GETFULLPATHNAME_METHODDEF) */ + +#ifndef OS__GETFINALPATHNAME_METHODDEF + #define OS__GETFINALPATHNAME_METHODDEF +#endif /* !defined(OS__GETFINALPATHNAME_METHODDEF) */ + +#ifndef OS__GETVOLUMEPATHNAME_METHODDEF + #define OS__GETVOLUMEPATHNAME_METHODDEF +#endif /* !defined(OS__GETVOLUMEPATHNAME_METHODDEF) */ + #ifndef OS__PATH_SPLITROOT_METHODDEF #define OS__PATH_SPLITROOT_METHODDEF #endif /* !defined(OS__PATH_SPLITROOT_METHODDEF) */ -#ifndef OS_NICE_METHODDEF - #define OS_NICE_METHODDEF -#endif /* !defined(OS_NICE_METHODDEF) */ - -#ifndef OS_GETPRIORITY_METHODDEF - #define OS_GETPRIORITY_METHODDEF -#endif /* !defined(OS_GETPRIORITY_METHODDEF) */ - -#ifndef OS_SETPRIORITY_METHODDEF - #define OS_SETPRIORITY_METHODDEF -#endif /* !defined(OS_SETPRIORITY_METHODDEF) */ - -#ifndef OS_SYSTEM_METHODDEF - #define OS_SYSTEM_METHODDEF -#endif /* !defined(OS_SYSTEM_METHODDEF) */ - -#ifndef OS_UNAME_METHODDEF - #define OS_UNAME_METHODDEF -#endif /* !defined(OS_UNAME_METHODDEF) */ - -#ifndef OS_EXECV_METHODDEF - #define OS_EXECV_METHODDEF -#endif /* !defined(OS_EXECV_METHODDEF) */ - -#ifndef OS_EXECVE_METHODDEF - #define OS_EXECVE_METHODDEF -#endif /* !defined(OS_EXECVE_METHODDEF) */ - +#ifndef OS_NICE_METHODDEF + #define OS_NICE_METHODDEF +#endif /* !defined(OS_NICE_METHODDEF) */ + +#ifndef OS_GETPRIORITY_METHODDEF + #define OS_GETPRIORITY_METHODDEF +#endif /* !defined(OS_GETPRIORITY_METHODDEF) */ + +#ifndef OS_SETPRIORITY_METHODDEF + #define OS_SETPRIORITY_METHODDEF +#endif /* !defined(OS_SETPRIORITY_METHODDEF) */ + +#ifndef OS_SYSTEM_METHODDEF + #define OS_SYSTEM_METHODDEF +#endif /* !defined(OS_SYSTEM_METHODDEF) */ + +#ifndef OS_UNAME_METHODDEF + #define OS_UNAME_METHODDEF +#endif /* !defined(OS_UNAME_METHODDEF) */ + +#ifndef OS_EXECV_METHODDEF + #define OS_EXECV_METHODDEF +#endif /* !defined(OS_EXECV_METHODDEF) */ + +#ifndef OS_EXECVE_METHODDEF + #define OS_EXECVE_METHODDEF +#endif /* !defined(OS_EXECVE_METHODDEF) */ + #ifndef OS_POSIX_SPAWN_METHODDEF #define OS_POSIX_SPAWN_METHODDEF #endif /* !defined(OS_POSIX_SPAWN_METHODDEF) */ @@ -8994,186 +8994,186 @@ exit: #define OS_POSIX_SPAWNP_METHODDEF #endif /* !defined(OS_POSIX_SPAWNP_METHODDEF) */ -#ifndef OS_SPAWNV_METHODDEF - #define OS_SPAWNV_METHODDEF -#endif /* !defined(OS_SPAWNV_METHODDEF) */ - -#ifndef OS_SPAWNVE_METHODDEF - #define OS_SPAWNVE_METHODDEF -#endif /* !defined(OS_SPAWNVE_METHODDEF) */ - -#ifndef OS_REGISTER_AT_FORK_METHODDEF - #define OS_REGISTER_AT_FORK_METHODDEF -#endif /* !defined(OS_REGISTER_AT_FORK_METHODDEF) */ - -#ifndef OS_FORK1_METHODDEF - #define OS_FORK1_METHODDEF -#endif /* !defined(OS_FORK1_METHODDEF) */ - -#ifndef OS_FORK_METHODDEF - #define OS_FORK_METHODDEF -#endif /* !defined(OS_FORK_METHODDEF) */ - -#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF - #define OS_SCHED_GET_PRIORITY_MAX_METHODDEF -#endif /* !defined(OS_SCHED_GET_PRIORITY_MAX_METHODDEF) */ - -#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF - #define OS_SCHED_GET_PRIORITY_MIN_METHODDEF -#endif /* !defined(OS_SCHED_GET_PRIORITY_MIN_METHODDEF) */ - -#ifndef OS_SCHED_GETSCHEDULER_METHODDEF - #define OS_SCHED_GETSCHEDULER_METHODDEF -#endif /* !defined(OS_SCHED_GETSCHEDULER_METHODDEF) */ - -#ifndef OS_SCHED_SETSCHEDULER_METHODDEF - #define OS_SCHED_SETSCHEDULER_METHODDEF -#endif /* !defined(OS_SCHED_SETSCHEDULER_METHODDEF) */ - -#ifndef OS_SCHED_GETPARAM_METHODDEF - #define OS_SCHED_GETPARAM_METHODDEF -#endif /* !defined(OS_SCHED_GETPARAM_METHODDEF) */ - -#ifndef OS_SCHED_SETPARAM_METHODDEF - #define OS_SCHED_SETPARAM_METHODDEF -#endif /* !defined(OS_SCHED_SETPARAM_METHODDEF) */ - -#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF - #define OS_SCHED_RR_GET_INTERVAL_METHODDEF -#endif /* !defined(OS_SCHED_RR_GET_INTERVAL_METHODDEF) */ - -#ifndef OS_SCHED_YIELD_METHODDEF - #define OS_SCHED_YIELD_METHODDEF -#endif /* !defined(OS_SCHED_YIELD_METHODDEF) */ - -#ifndef OS_SCHED_SETAFFINITY_METHODDEF - #define OS_SCHED_SETAFFINITY_METHODDEF -#endif /* !defined(OS_SCHED_SETAFFINITY_METHODDEF) */ - -#ifndef OS_SCHED_GETAFFINITY_METHODDEF - #define OS_SCHED_GETAFFINITY_METHODDEF -#endif /* !defined(OS_SCHED_GETAFFINITY_METHODDEF) */ - -#ifndef OS_OPENPTY_METHODDEF - #define OS_OPENPTY_METHODDEF -#endif /* !defined(OS_OPENPTY_METHODDEF) */ - -#ifndef OS_FORKPTY_METHODDEF - #define OS_FORKPTY_METHODDEF -#endif /* !defined(OS_FORKPTY_METHODDEF) */ - -#ifndef OS_GETEGID_METHODDEF - #define OS_GETEGID_METHODDEF -#endif /* !defined(OS_GETEGID_METHODDEF) */ - -#ifndef OS_GETEUID_METHODDEF - #define OS_GETEUID_METHODDEF -#endif /* !defined(OS_GETEUID_METHODDEF) */ - -#ifndef OS_GETGID_METHODDEF - #define OS_GETGID_METHODDEF -#endif /* !defined(OS_GETGID_METHODDEF) */ - -#ifndef OS_GETPID_METHODDEF - #define OS_GETPID_METHODDEF -#endif /* !defined(OS_GETPID_METHODDEF) */ - +#ifndef OS_SPAWNV_METHODDEF + #define OS_SPAWNV_METHODDEF +#endif /* !defined(OS_SPAWNV_METHODDEF) */ + +#ifndef OS_SPAWNVE_METHODDEF + #define OS_SPAWNVE_METHODDEF +#endif /* !defined(OS_SPAWNVE_METHODDEF) */ + +#ifndef OS_REGISTER_AT_FORK_METHODDEF + #define OS_REGISTER_AT_FORK_METHODDEF +#endif /* !defined(OS_REGISTER_AT_FORK_METHODDEF) */ + +#ifndef OS_FORK1_METHODDEF + #define OS_FORK1_METHODDEF +#endif /* !defined(OS_FORK1_METHODDEF) */ + +#ifndef OS_FORK_METHODDEF + #define OS_FORK_METHODDEF +#endif /* !defined(OS_FORK_METHODDEF) */ + +#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF + #define OS_SCHED_GET_PRIORITY_MAX_METHODDEF +#endif /* !defined(OS_SCHED_GET_PRIORITY_MAX_METHODDEF) */ + +#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF + #define OS_SCHED_GET_PRIORITY_MIN_METHODDEF +#endif /* !defined(OS_SCHED_GET_PRIORITY_MIN_METHODDEF) */ + +#ifndef OS_SCHED_GETSCHEDULER_METHODDEF + #define OS_SCHED_GETSCHEDULER_METHODDEF +#endif /* !defined(OS_SCHED_GETSCHEDULER_METHODDEF) */ + +#ifndef OS_SCHED_SETSCHEDULER_METHODDEF + #define OS_SCHED_SETSCHEDULER_METHODDEF +#endif /* !defined(OS_SCHED_SETSCHEDULER_METHODDEF) */ + +#ifndef OS_SCHED_GETPARAM_METHODDEF + #define OS_SCHED_GETPARAM_METHODDEF +#endif /* !defined(OS_SCHED_GETPARAM_METHODDEF) */ + +#ifndef OS_SCHED_SETPARAM_METHODDEF + #define OS_SCHED_SETPARAM_METHODDEF +#endif /* !defined(OS_SCHED_SETPARAM_METHODDEF) */ + +#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF + #define OS_SCHED_RR_GET_INTERVAL_METHODDEF +#endif /* !defined(OS_SCHED_RR_GET_INTERVAL_METHODDEF) */ + +#ifndef OS_SCHED_YIELD_METHODDEF + #define OS_SCHED_YIELD_METHODDEF +#endif /* !defined(OS_SCHED_YIELD_METHODDEF) */ + +#ifndef OS_SCHED_SETAFFINITY_METHODDEF + #define OS_SCHED_SETAFFINITY_METHODDEF +#endif /* !defined(OS_SCHED_SETAFFINITY_METHODDEF) */ + +#ifndef OS_SCHED_GETAFFINITY_METHODDEF + #define OS_SCHED_GETAFFINITY_METHODDEF +#endif /* !defined(OS_SCHED_GETAFFINITY_METHODDEF) */ + +#ifndef OS_OPENPTY_METHODDEF + #define OS_OPENPTY_METHODDEF +#endif /* !defined(OS_OPENPTY_METHODDEF) */ + +#ifndef OS_FORKPTY_METHODDEF + #define OS_FORKPTY_METHODDEF +#endif /* !defined(OS_FORKPTY_METHODDEF) */ + +#ifndef OS_GETEGID_METHODDEF + #define OS_GETEGID_METHODDEF +#endif /* !defined(OS_GETEGID_METHODDEF) */ + +#ifndef OS_GETEUID_METHODDEF + #define OS_GETEUID_METHODDEF +#endif /* !defined(OS_GETEUID_METHODDEF) */ + +#ifndef OS_GETGID_METHODDEF + #define OS_GETGID_METHODDEF +#endif /* !defined(OS_GETGID_METHODDEF) */ + +#ifndef OS_GETPID_METHODDEF + #define OS_GETPID_METHODDEF +#endif /* !defined(OS_GETPID_METHODDEF) */ + #ifndef OS_GETGROUPLIST_METHODDEF #define OS_GETGROUPLIST_METHODDEF #endif /* !defined(OS_GETGROUPLIST_METHODDEF) */ -#ifndef OS_GETGROUPS_METHODDEF - #define OS_GETGROUPS_METHODDEF -#endif /* !defined(OS_GETGROUPS_METHODDEF) */ - +#ifndef OS_GETGROUPS_METHODDEF + #define OS_GETGROUPS_METHODDEF +#endif /* !defined(OS_GETGROUPS_METHODDEF) */ + #ifndef OS_INITGROUPS_METHODDEF #define OS_INITGROUPS_METHODDEF #endif /* !defined(OS_INITGROUPS_METHODDEF) */ -#ifndef OS_GETPGID_METHODDEF - #define OS_GETPGID_METHODDEF -#endif /* !defined(OS_GETPGID_METHODDEF) */ - -#ifndef OS_GETPGRP_METHODDEF - #define OS_GETPGRP_METHODDEF -#endif /* !defined(OS_GETPGRP_METHODDEF) */ - -#ifndef OS_SETPGRP_METHODDEF - #define OS_SETPGRP_METHODDEF -#endif /* !defined(OS_SETPGRP_METHODDEF) */ - -#ifndef OS_GETPPID_METHODDEF - #define OS_GETPPID_METHODDEF -#endif /* !defined(OS_GETPPID_METHODDEF) */ - -#ifndef OS_GETLOGIN_METHODDEF - #define OS_GETLOGIN_METHODDEF -#endif /* !defined(OS_GETLOGIN_METHODDEF) */ - -#ifndef OS_GETUID_METHODDEF - #define OS_GETUID_METHODDEF -#endif /* !defined(OS_GETUID_METHODDEF) */ - -#ifndef OS_KILL_METHODDEF - #define OS_KILL_METHODDEF -#endif /* !defined(OS_KILL_METHODDEF) */ - -#ifndef OS_KILLPG_METHODDEF - #define OS_KILLPG_METHODDEF -#endif /* !defined(OS_KILLPG_METHODDEF) */ - -#ifndef OS_PLOCK_METHODDEF - #define OS_PLOCK_METHODDEF -#endif /* !defined(OS_PLOCK_METHODDEF) */ - -#ifndef OS_SETUID_METHODDEF - #define OS_SETUID_METHODDEF -#endif /* !defined(OS_SETUID_METHODDEF) */ - -#ifndef OS_SETEUID_METHODDEF - #define OS_SETEUID_METHODDEF -#endif /* !defined(OS_SETEUID_METHODDEF) */ - -#ifndef OS_SETEGID_METHODDEF - #define OS_SETEGID_METHODDEF -#endif /* !defined(OS_SETEGID_METHODDEF) */ - -#ifndef OS_SETREUID_METHODDEF - #define OS_SETREUID_METHODDEF -#endif /* !defined(OS_SETREUID_METHODDEF) */ - -#ifndef OS_SETREGID_METHODDEF - #define OS_SETREGID_METHODDEF -#endif /* !defined(OS_SETREGID_METHODDEF) */ - -#ifndef OS_SETGID_METHODDEF - #define OS_SETGID_METHODDEF -#endif /* !defined(OS_SETGID_METHODDEF) */ - -#ifndef OS_SETGROUPS_METHODDEF - #define OS_SETGROUPS_METHODDEF -#endif /* !defined(OS_SETGROUPS_METHODDEF) */ - -#ifndef OS_WAIT3_METHODDEF - #define OS_WAIT3_METHODDEF -#endif /* !defined(OS_WAIT3_METHODDEF) */ - -#ifndef OS_WAIT4_METHODDEF - #define OS_WAIT4_METHODDEF -#endif /* !defined(OS_WAIT4_METHODDEF) */ - -#ifndef OS_WAITID_METHODDEF - #define OS_WAITID_METHODDEF -#endif /* !defined(OS_WAITID_METHODDEF) */ - -#ifndef OS_WAITPID_METHODDEF - #define OS_WAITPID_METHODDEF -#endif /* !defined(OS_WAITPID_METHODDEF) */ - -#ifndef OS_WAIT_METHODDEF - #define OS_WAIT_METHODDEF -#endif /* !defined(OS_WAIT_METHODDEF) */ - +#ifndef OS_GETPGID_METHODDEF + #define OS_GETPGID_METHODDEF +#endif /* !defined(OS_GETPGID_METHODDEF) */ + +#ifndef OS_GETPGRP_METHODDEF + #define OS_GETPGRP_METHODDEF +#endif /* !defined(OS_GETPGRP_METHODDEF) */ + +#ifndef OS_SETPGRP_METHODDEF + #define OS_SETPGRP_METHODDEF +#endif /* !defined(OS_SETPGRP_METHODDEF) */ + +#ifndef OS_GETPPID_METHODDEF + #define OS_GETPPID_METHODDEF +#endif /* !defined(OS_GETPPID_METHODDEF) */ + +#ifndef OS_GETLOGIN_METHODDEF + #define OS_GETLOGIN_METHODDEF +#endif /* !defined(OS_GETLOGIN_METHODDEF) */ + +#ifndef OS_GETUID_METHODDEF + #define OS_GETUID_METHODDEF +#endif /* !defined(OS_GETUID_METHODDEF) */ + +#ifndef OS_KILL_METHODDEF + #define OS_KILL_METHODDEF +#endif /* !defined(OS_KILL_METHODDEF) */ + +#ifndef OS_KILLPG_METHODDEF + #define OS_KILLPG_METHODDEF +#endif /* !defined(OS_KILLPG_METHODDEF) */ + +#ifndef OS_PLOCK_METHODDEF + #define OS_PLOCK_METHODDEF +#endif /* !defined(OS_PLOCK_METHODDEF) */ + +#ifndef OS_SETUID_METHODDEF + #define OS_SETUID_METHODDEF +#endif /* !defined(OS_SETUID_METHODDEF) */ + +#ifndef OS_SETEUID_METHODDEF + #define OS_SETEUID_METHODDEF +#endif /* !defined(OS_SETEUID_METHODDEF) */ + +#ifndef OS_SETEGID_METHODDEF + #define OS_SETEGID_METHODDEF +#endif /* !defined(OS_SETEGID_METHODDEF) */ + +#ifndef OS_SETREUID_METHODDEF + #define OS_SETREUID_METHODDEF +#endif /* !defined(OS_SETREUID_METHODDEF) */ + +#ifndef OS_SETREGID_METHODDEF + #define OS_SETREGID_METHODDEF +#endif /* !defined(OS_SETREGID_METHODDEF) */ + +#ifndef OS_SETGID_METHODDEF + #define OS_SETGID_METHODDEF +#endif /* !defined(OS_SETGID_METHODDEF) */ + +#ifndef OS_SETGROUPS_METHODDEF + #define OS_SETGROUPS_METHODDEF +#endif /* !defined(OS_SETGROUPS_METHODDEF) */ + +#ifndef OS_WAIT3_METHODDEF + #define OS_WAIT3_METHODDEF +#endif /* !defined(OS_WAIT3_METHODDEF) */ + +#ifndef OS_WAIT4_METHODDEF + #define OS_WAIT4_METHODDEF +#endif /* !defined(OS_WAIT4_METHODDEF) */ + +#ifndef OS_WAITID_METHODDEF + #define OS_WAITID_METHODDEF +#endif /* !defined(OS_WAITID_METHODDEF) */ + +#ifndef OS_WAITPID_METHODDEF + #define OS_WAITPID_METHODDEF +#endif /* !defined(OS_WAITPID_METHODDEF) */ + +#ifndef OS_WAIT_METHODDEF + #define OS_WAIT_METHODDEF +#endif /* !defined(OS_WAIT_METHODDEF) */ + #ifndef OS_PIDFD_OPEN_METHODDEF #define OS_PIDFD_OPEN_METHODDEF #endif /* !defined(OS_PIDFD_OPEN_METHODDEF) */ @@ -9182,50 +9182,50 @@ exit: #define OS_READLINK_METHODDEF #endif /* !defined(OS_READLINK_METHODDEF) */ -#ifndef OS_SYMLINK_METHODDEF - #define OS_SYMLINK_METHODDEF -#endif /* !defined(OS_SYMLINK_METHODDEF) */ - -#ifndef OS_TIMES_METHODDEF - #define OS_TIMES_METHODDEF -#endif /* !defined(OS_TIMES_METHODDEF) */ - -#ifndef OS_GETSID_METHODDEF - #define OS_GETSID_METHODDEF -#endif /* !defined(OS_GETSID_METHODDEF) */ - -#ifndef OS_SETSID_METHODDEF - #define OS_SETSID_METHODDEF -#endif /* !defined(OS_SETSID_METHODDEF) */ - -#ifndef OS_SETPGID_METHODDEF - #define OS_SETPGID_METHODDEF -#endif /* !defined(OS_SETPGID_METHODDEF) */ - -#ifndef OS_TCGETPGRP_METHODDEF - #define OS_TCGETPGRP_METHODDEF -#endif /* !defined(OS_TCGETPGRP_METHODDEF) */ - -#ifndef OS_TCSETPGRP_METHODDEF - #define OS_TCSETPGRP_METHODDEF -#endif /* !defined(OS_TCSETPGRP_METHODDEF) */ - -#ifndef OS_LOCKF_METHODDEF - #define OS_LOCKF_METHODDEF -#endif /* !defined(OS_LOCKF_METHODDEF) */ - -#ifndef OS_READV_METHODDEF - #define OS_READV_METHODDEF -#endif /* !defined(OS_READV_METHODDEF) */ - -#ifndef OS_PREAD_METHODDEF - #define OS_PREAD_METHODDEF -#endif /* !defined(OS_PREAD_METHODDEF) */ - -#ifndef OS_PREADV_METHODDEF - #define OS_PREADV_METHODDEF -#endif /* !defined(OS_PREADV_METHODDEF) */ - +#ifndef OS_SYMLINK_METHODDEF + #define OS_SYMLINK_METHODDEF +#endif /* !defined(OS_SYMLINK_METHODDEF) */ + +#ifndef OS_TIMES_METHODDEF + #define OS_TIMES_METHODDEF +#endif /* !defined(OS_TIMES_METHODDEF) */ + +#ifndef OS_GETSID_METHODDEF + #define OS_GETSID_METHODDEF +#endif /* !defined(OS_GETSID_METHODDEF) */ + +#ifndef OS_SETSID_METHODDEF + #define OS_SETSID_METHODDEF +#endif /* !defined(OS_SETSID_METHODDEF) */ + +#ifndef OS_SETPGID_METHODDEF + #define OS_SETPGID_METHODDEF +#endif /* !defined(OS_SETPGID_METHODDEF) */ + +#ifndef OS_TCGETPGRP_METHODDEF + #define OS_TCGETPGRP_METHODDEF +#endif /* !defined(OS_TCGETPGRP_METHODDEF) */ + +#ifndef OS_TCSETPGRP_METHODDEF + #define OS_TCSETPGRP_METHODDEF +#endif /* !defined(OS_TCSETPGRP_METHODDEF) */ + +#ifndef OS_LOCKF_METHODDEF + #define OS_LOCKF_METHODDEF +#endif /* !defined(OS_LOCKF_METHODDEF) */ + +#ifndef OS_READV_METHODDEF + #define OS_READV_METHODDEF +#endif /* !defined(OS_READV_METHODDEF) */ + +#ifndef OS_PREAD_METHODDEF + #define OS_PREAD_METHODDEF +#endif /* !defined(OS_PREAD_METHODDEF) */ + +#ifndef OS_PREADV_METHODDEF + #define OS_PREADV_METHODDEF +#endif /* !defined(OS_PREADV_METHODDEF) */ + #ifndef OS_SENDFILE_METHODDEF #define OS_SENDFILE_METHODDEF #endif /* !defined(OS_SENDFILE_METHODDEF) */ @@ -9234,174 +9234,174 @@ exit: #define OS__FCOPYFILE_METHODDEF #endif /* !defined(OS__FCOPYFILE_METHODDEF) */ -#ifndef OS_PIPE_METHODDEF - #define OS_PIPE_METHODDEF -#endif /* !defined(OS_PIPE_METHODDEF) */ - -#ifndef OS_PIPE2_METHODDEF - #define OS_PIPE2_METHODDEF -#endif /* !defined(OS_PIPE2_METHODDEF) */ - -#ifndef OS_WRITEV_METHODDEF - #define OS_WRITEV_METHODDEF -#endif /* !defined(OS_WRITEV_METHODDEF) */ - -#ifndef OS_PWRITE_METHODDEF - #define OS_PWRITE_METHODDEF -#endif /* !defined(OS_PWRITE_METHODDEF) */ - -#ifndef OS_PWRITEV_METHODDEF - #define OS_PWRITEV_METHODDEF -#endif /* !defined(OS_PWRITEV_METHODDEF) */ - +#ifndef OS_PIPE_METHODDEF + #define OS_PIPE_METHODDEF +#endif /* !defined(OS_PIPE_METHODDEF) */ + +#ifndef OS_PIPE2_METHODDEF + #define OS_PIPE2_METHODDEF +#endif /* !defined(OS_PIPE2_METHODDEF) */ + +#ifndef OS_WRITEV_METHODDEF + #define OS_WRITEV_METHODDEF +#endif /* !defined(OS_WRITEV_METHODDEF) */ + +#ifndef OS_PWRITE_METHODDEF + #define OS_PWRITE_METHODDEF +#endif /* !defined(OS_PWRITE_METHODDEF) */ + +#ifndef OS_PWRITEV_METHODDEF + #define OS_PWRITEV_METHODDEF +#endif /* !defined(OS_PWRITEV_METHODDEF) */ + #ifndef OS_COPY_FILE_RANGE_METHODDEF #define OS_COPY_FILE_RANGE_METHODDEF #endif /* !defined(OS_COPY_FILE_RANGE_METHODDEF) */ -#ifndef OS_MKFIFO_METHODDEF - #define OS_MKFIFO_METHODDEF -#endif /* !defined(OS_MKFIFO_METHODDEF) */ - -#ifndef OS_MKNOD_METHODDEF - #define OS_MKNOD_METHODDEF -#endif /* !defined(OS_MKNOD_METHODDEF) */ - -#ifndef OS_MAJOR_METHODDEF - #define OS_MAJOR_METHODDEF -#endif /* !defined(OS_MAJOR_METHODDEF) */ - -#ifndef OS_MINOR_METHODDEF - #define OS_MINOR_METHODDEF -#endif /* !defined(OS_MINOR_METHODDEF) */ - -#ifndef OS_MAKEDEV_METHODDEF - #define OS_MAKEDEV_METHODDEF -#endif /* !defined(OS_MAKEDEV_METHODDEF) */ - -#ifndef OS_FTRUNCATE_METHODDEF - #define OS_FTRUNCATE_METHODDEF -#endif /* !defined(OS_FTRUNCATE_METHODDEF) */ - -#ifndef OS_TRUNCATE_METHODDEF - #define OS_TRUNCATE_METHODDEF -#endif /* !defined(OS_TRUNCATE_METHODDEF) */ - -#ifndef OS_POSIX_FALLOCATE_METHODDEF - #define OS_POSIX_FALLOCATE_METHODDEF -#endif /* !defined(OS_POSIX_FALLOCATE_METHODDEF) */ - -#ifndef OS_POSIX_FADVISE_METHODDEF - #define OS_POSIX_FADVISE_METHODDEF -#endif /* !defined(OS_POSIX_FADVISE_METHODDEF) */ - -#ifndef OS_PUTENV_METHODDEF - #define OS_PUTENV_METHODDEF -#endif /* !defined(OS_PUTENV_METHODDEF) */ - -#ifndef OS_UNSETENV_METHODDEF - #define OS_UNSETENV_METHODDEF -#endif /* !defined(OS_UNSETENV_METHODDEF) */ - -#ifndef OS_WCOREDUMP_METHODDEF - #define OS_WCOREDUMP_METHODDEF -#endif /* !defined(OS_WCOREDUMP_METHODDEF) */ - -#ifndef OS_WIFCONTINUED_METHODDEF - #define OS_WIFCONTINUED_METHODDEF -#endif /* !defined(OS_WIFCONTINUED_METHODDEF) */ - -#ifndef OS_WIFSTOPPED_METHODDEF - #define OS_WIFSTOPPED_METHODDEF -#endif /* !defined(OS_WIFSTOPPED_METHODDEF) */ - -#ifndef OS_WIFSIGNALED_METHODDEF - #define OS_WIFSIGNALED_METHODDEF -#endif /* !defined(OS_WIFSIGNALED_METHODDEF) */ - -#ifndef OS_WIFEXITED_METHODDEF - #define OS_WIFEXITED_METHODDEF -#endif /* !defined(OS_WIFEXITED_METHODDEF) */ - -#ifndef OS_WEXITSTATUS_METHODDEF - #define OS_WEXITSTATUS_METHODDEF -#endif /* !defined(OS_WEXITSTATUS_METHODDEF) */ - -#ifndef OS_WTERMSIG_METHODDEF - #define OS_WTERMSIG_METHODDEF -#endif /* !defined(OS_WTERMSIG_METHODDEF) */ - -#ifndef OS_WSTOPSIG_METHODDEF - #define OS_WSTOPSIG_METHODDEF -#endif /* !defined(OS_WSTOPSIG_METHODDEF) */ - -#ifndef OS_FSTATVFS_METHODDEF - #define OS_FSTATVFS_METHODDEF -#endif /* !defined(OS_FSTATVFS_METHODDEF) */ - -#ifndef OS_STATVFS_METHODDEF - #define OS_STATVFS_METHODDEF -#endif /* !defined(OS_STATVFS_METHODDEF) */ - -#ifndef OS__GETDISKUSAGE_METHODDEF - #define OS__GETDISKUSAGE_METHODDEF -#endif /* !defined(OS__GETDISKUSAGE_METHODDEF) */ - -#ifndef OS_FPATHCONF_METHODDEF - #define OS_FPATHCONF_METHODDEF -#endif /* !defined(OS_FPATHCONF_METHODDEF) */ - -#ifndef OS_PATHCONF_METHODDEF - #define OS_PATHCONF_METHODDEF -#endif /* !defined(OS_PATHCONF_METHODDEF) */ - -#ifndef OS_CONFSTR_METHODDEF - #define OS_CONFSTR_METHODDEF -#endif /* !defined(OS_CONFSTR_METHODDEF) */ - -#ifndef OS_SYSCONF_METHODDEF - #define OS_SYSCONF_METHODDEF -#endif /* !defined(OS_SYSCONF_METHODDEF) */ - -#ifndef OS_STARTFILE_METHODDEF - #define OS_STARTFILE_METHODDEF -#endif /* !defined(OS_STARTFILE_METHODDEF) */ - -#ifndef OS_GETLOADAVG_METHODDEF - #define OS_GETLOADAVG_METHODDEF -#endif /* !defined(OS_GETLOADAVG_METHODDEF) */ - -#ifndef OS_SETRESUID_METHODDEF - #define OS_SETRESUID_METHODDEF -#endif /* !defined(OS_SETRESUID_METHODDEF) */ - -#ifndef OS_SETRESGID_METHODDEF - #define OS_SETRESGID_METHODDEF -#endif /* !defined(OS_SETRESGID_METHODDEF) */ - -#ifndef OS_GETRESUID_METHODDEF - #define OS_GETRESUID_METHODDEF -#endif /* !defined(OS_GETRESUID_METHODDEF) */ - -#ifndef OS_GETRESGID_METHODDEF - #define OS_GETRESGID_METHODDEF -#endif /* !defined(OS_GETRESGID_METHODDEF) */ - -#ifndef OS_GETXATTR_METHODDEF - #define OS_GETXATTR_METHODDEF -#endif /* !defined(OS_GETXATTR_METHODDEF) */ - -#ifndef OS_SETXATTR_METHODDEF - #define OS_SETXATTR_METHODDEF -#endif /* !defined(OS_SETXATTR_METHODDEF) */ - -#ifndef OS_REMOVEXATTR_METHODDEF - #define OS_REMOVEXATTR_METHODDEF -#endif /* !defined(OS_REMOVEXATTR_METHODDEF) */ - -#ifndef OS_LISTXATTR_METHODDEF - #define OS_LISTXATTR_METHODDEF -#endif /* !defined(OS_LISTXATTR_METHODDEF) */ - +#ifndef OS_MKFIFO_METHODDEF + #define OS_MKFIFO_METHODDEF +#endif /* !defined(OS_MKFIFO_METHODDEF) */ + +#ifndef OS_MKNOD_METHODDEF + #define OS_MKNOD_METHODDEF +#endif /* !defined(OS_MKNOD_METHODDEF) */ + +#ifndef OS_MAJOR_METHODDEF + #define OS_MAJOR_METHODDEF +#endif /* !defined(OS_MAJOR_METHODDEF) */ + +#ifndef OS_MINOR_METHODDEF + #define OS_MINOR_METHODDEF +#endif /* !defined(OS_MINOR_METHODDEF) */ + +#ifndef OS_MAKEDEV_METHODDEF + #define OS_MAKEDEV_METHODDEF +#endif /* !defined(OS_MAKEDEV_METHODDEF) */ + +#ifndef OS_FTRUNCATE_METHODDEF + #define OS_FTRUNCATE_METHODDEF +#endif /* !defined(OS_FTRUNCATE_METHODDEF) */ + +#ifndef OS_TRUNCATE_METHODDEF + #define OS_TRUNCATE_METHODDEF +#endif /* !defined(OS_TRUNCATE_METHODDEF) */ + +#ifndef OS_POSIX_FALLOCATE_METHODDEF + #define OS_POSIX_FALLOCATE_METHODDEF +#endif /* !defined(OS_POSIX_FALLOCATE_METHODDEF) */ + +#ifndef OS_POSIX_FADVISE_METHODDEF + #define OS_POSIX_FADVISE_METHODDEF +#endif /* !defined(OS_POSIX_FADVISE_METHODDEF) */ + +#ifndef OS_PUTENV_METHODDEF + #define OS_PUTENV_METHODDEF +#endif /* !defined(OS_PUTENV_METHODDEF) */ + +#ifndef OS_UNSETENV_METHODDEF + #define OS_UNSETENV_METHODDEF +#endif /* !defined(OS_UNSETENV_METHODDEF) */ + +#ifndef OS_WCOREDUMP_METHODDEF + #define OS_WCOREDUMP_METHODDEF +#endif /* !defined(OS_WCOREDUMP_METHODDEF) */ + +#ifndef OS_WIFCONTINUED_METHODDEF + #define OS_WIFCONTINUED_METHODDEF +#endif /* !defined(OS_WIFCONTINUED_METHODDEF) */ + +#ifndef OS_WIFSTOPPED_METHODDEF + #define OS_WIFSTOPPED_METHODDEF +#endif /* !defined(OS_WIFSTOPPED_METHODDEF) */ + +#ifndef OS_WIFSIGNALED_METHODDEF + #define OS_WIFSIGNALED_METHODDEF +#endif /* !defined(OS_WIFSIGNALED_METHODDEF) */ + +#ifndef OS_WIFEXITED_METHODDEF + #define OS_WIFEXITED_METHODDEF +#endif /* !defined(OS_WIFEXITED_METHODDEF) */ + +#ifndef OS_WEXITSTATUS_METHODDEF + #define OS_WEXITSTATUS_METHODDEF +#endif /* !defined(OS_WEXITSTATUS_METHODDEF) */ + +#ifndef OS_WTERMSIG_METHODDEF + #define OS_WTERMSIG_METHODDEF +#endif /* !defined(OS_WTERMSIG_METHODDEF) */ + +#ifndef OS_WSTOPSIG_METHODDEF + #define OS_WSTOPSIG_METHODDEF +#endif /* !defined(OS_WSTOPSIG_METHODDEF) */ + +#ifndef OS_FSTATVFS_METHODDEF + #define OS_FSTATVFS_METHODDEF +#endif /* !defined(OS_FSTATVFS_METHODDEF) */ + +#ifndef OS_STATVFS_METHODDEF + #define OS_STATVFS_METHODDEF +#endif /* !defined(OS_STATVFS_METHODDEF) */ + +#ifndef OS__GETDISKUSAGE_METHODDEF + #define OS__GETDISKUSAGE_METHODDEF +#endif /* !defined(OS__GETDISKUSAGE_METHODDEF) */ + +#ifndef OS_FPATHCONF_METHODDEF + #define OS_FPATHCONF_METHODDEF +#endif /* !defined(OS_FPATHCONF_METHODDEF) */ + +#ifndef OS_PATHCONF_METHODDEF + #define OS_PATHCONF_METHODDEF +#endif /* !defined(OS_PATHCONF_METHODDEF) */ + +#ifndef OS_CONFSTR_METHODDEF + #define OS_CONFSTR_METHODDEF +#endif /* !defined(OS_CONFSTR_METHODDEF) */ + +#ifndef OS_SYSCONF_METHODDEF + #define OS_SYSCONF_METHODDEF +#endif /* !defined(OS_SYSCONF_METHODDEF) */ + +#ifndef OS_STARTFILE_METHODDEF + #define OS_STARTFILE_METHODDEF +#endif /* !defined(OS_STARTFILE_METHODDEF) */ + +#ifndef OS_GETLOADAVG_METHODDEF + #define OS_GETLOADAVG_METHODDEF +#endif /* !defined(OS_GETLOADAVG_METHODDEF) */ + +#ifndef OS_SETRESUID_METHODDEF + #define OS_SETRESUID_METHODDEF +#endif /* !defined(OS_SETRESUID_METHODDEF) */ + +#ifndef OS_SETRESGID_METHODDEF + #define OS_SETRESGID_METHODDEF +#endif /* !defined(OS_SETRESGID_METHODDEF) */ + +#ifndef OS_GETRESUID_METHODDEF + #define OS_GETRESUID_METHODDEF +#endif /* !defined(OS_GETRESUID_METHODDEF) */ + +#ifndef OS_GETRESGID_METHODDEF + #define OS_GETRESGID_METHODDEF +#endif /* !defined(OS_GETRESGID_METHODDEF) */ + +#ifndef OS_GETXATTR_METHODDEF + #define OS_GETXATTR_METHODDEF +#endif /* !defined(OS_GETXATTR_METHODDEF) */ + +#ifndef OS_SETXATTR_METHODDEF + #define OS_SETXATTR_METHODDEF +#endif /* !defined(OS_SETXATTR_METHODDEF) */ + +#ifndef OS_REMOVEXATTR_METHODDEF + #define OS_REMOVEXATTR_METHODDEF +#endif /* !defined(OS_REMOVEXATTR_METHODDEF) */ + +#ifndef OS_LISTXATTR_METHODDEF + #define OS_LISTXATTR_METHODDEF +#endif /* !defined(OS_LISTXATTR_METHODDEF) */ + #ifndef OS_MEMFD_CREATE_METHODDEF #define OS_MEMFD_CREATE_METHODDEF #endif /* !defined(OS_MEMFD_CREATE_METHODDEF) */ @@ -9410,14 +9410,14 @@ exit: #define OS_GET_TERMINAL_SIZE_METHODDEF #endif /* !defined(OS_GET_TERMINAL_SIZE_METHODDEF) */ -#ifndef OS_GET_HANDLE_INHERITABLE_METHODDEF - #define OS_GET_HANDLE_INHERITABLE_METHODDEF -#endif /* !defined(OS_GET_HANDLE_INHERITABLE_METHODDEF) */ - -#ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF - #define OS_SET_HANDLE_INHERITABLE_METHODDEF -#endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */ - +#ifndef OS_GET_HANDLE_INHERITABLE_METHODDEF + #define OS_GET_HANDLE_INHERITABLE_METHODDEF +#endif /* !defined(OS_GET_HANDLE_INHERITABLE_METHODDEF) */ + +#ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF + #define OS_SET_HANDLE_INHERITABLE_METHODDEF +#endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */ + #ifndef OS_GET_BLOCKING_METHODDEF #define OS_GET_BLOCKING_METHODDEF #endif /* !defined(OS_GET_BLOCKING_METHODDEF) */ @@ -9426,9 +9426,9 @@ exit: #define OS_SET_BLOCKING_METHODDEF #endif /* !defined(OS_SET_BLOCKING_METHODDEF) */ -#ifndef OS_GETRANDOM_METHODDEF - #define OS_GETRANDOM_METHODDEF -#endif /* !defined(OS_GETRANDOM_METHODDEF) */ +#ifndef OS_GETRANDOM_METHODDEF + #define OS_GETRANDOM_METHODDEF +#endif /* !defined(OS_GETRANDOM_METHODDEF) */ #ifndef OS__ADD_DLL_DIRECTORY_METHODDEF #define OS__ADD_DLL_DIRECTORY_METHODDEF diff --git a/contrib/tools/python3/src/Modules/clinic/pwdmodule.c.h b/contrib/tools/python3/src/Modules/clinic/pwdmodule.c.h index cb83062495d..f8bac9b0a16 100644 --- a/contrib/tools/python3/src/Modules/clinic/pwdmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/pwdmodule.c.h @@ -1,77 +1,77 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(pwd_getpwuid__doc__, -"getpwuid($module, uidobj, /)\n" -"--\n" -"\n" -"Return the password database entry for the given numeric user ID.\n" -"\n" -"See `help(pwd)` for more on password database entries."); - -#define PWD_GETPWUID_METHODDEF \ - {"getpwuid", (PyCFunction)pwd_getpwuid, METH_O, pwd_getpwuid__doc__}, - -PyDoc_STRVAR(pwd_getpwnam__doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(pwd_getpwuid__doc__, +"getpwuid($module, uidobj, /)\n" +"--\n" +"\n" +"Return the password database entry for the given numeric user ID.\n" +"\n" +"See `help(pwd)` for more on password database entries."); + +#define PWD_GETPWUID_METHODDEF \ + {"getpwuid", (PyCFunction)pwd_getpwuid, METH_O, pwd_getpwuid__doc__}, + +PyDoc_STRVAR(pwd_getpwnam__doc__, "getpwnam($module, name, /)\n" -"--\n" -"\n" -"Return the password database entry for the given user name.\n" -"\n" -"See `help(pwd)` for more on password database entries."); - -#define PWD_GETPWNAM_METHODDEF \ - {"getpwnam", (PyCFunction)pwd_getpwnam, METH_O, pwd_getpwnam__doc__}, - -static PyObject * +"--\n" +"\n" +"Return the password database entry for the given user name.\n" +"\n" +"See `help(pwd)` for more on password database entries."); + +#define PWD_GETPWNAM_METHODDEF \ + {"getpwnam", (PyCFunction)pwd_getpwnam, METH_O, pwd_getpwnam__doc__}, + +static PyObject * pwd_getpwnam_impl(PyObject *module, PyObject *name); - -static PyObject * + +static PyObject * pwd_getpwnam(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; +{ + PyObject *return_value = NULL; PyObject *name; - + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("getpwnam", "argument", "str", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg) == -1) { goto exit; } name = arg; return_value = pwd_getpwnam_impl(module, name); - -exit: - return return_value; -} - -#if defined(HAVE_GETPWENT) - -PyDoc_STRVAR(pwd_getpwall__doc__, -"getpwall($module, /)\n" -"--\n" -"\n" -"Return a list of all available password database entries, in arbitrary order.\n" -"\n" -"See help(pwd) for more on password database entries."); - -#define PWD_GETPWALL_METHODDEF \ - {"getpwall", (PyCFunction)pwd_getpwall, METH_NOARGS, pwd_getpwall__doc__}, - -static PyObject * -pwd_getpwall_impl(PyObject *module); - -static PyObject * -pwd_getpwall(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return pwd_getpwall_impl(module); -} - -#endif /* defined(HAVE_GETPWENT) */ - -#ifndef PWD_GETPWALL_METHODDEF - #define PWD_GETPWALL_METHODDEF -#endif /* !defined(PWD_GETPWALL_METHODDEF) */ + +exit: + return return_value; +} + +#if defined(HAVE_GETPWENT) + +PyDoc_STRVAR(pwd_getpwall__doc__, +"getpwall($module, /)\n" +"--\n" +"\n" +"Return a list of all available password database entries, in arbitrary order.\n" +"\n" +"See help(pwd) for more on password database entries."); + +#define PWD_GETPWALL_METHODDEF \ + {"getpwall", (PyCFunction)pwd_getpwall, METH_NOARGS, pwd_getpwall__doc__}, + +static PyObject * +pwd_getpwall_impl(PyObject *module); + +static PyObject * +pwd_getpwall(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return pwd_getpwall_impl(module); +} + +#endif /* defined(HAVE_GETPWENT) */ + +#ifndef PWD_GETPWALL_METHODDEF + #define PWD_GETPWALL_METHODDEF +#endif /* !defined(PWD_GETPWALL_METHODDEF) */ /*[clinic end generated code: output=7fceab7f1a85da36 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/pyexpat.c.h b/contrib/tools/python3/src/Modules/clinic/pyexpat.c.h index ee5907ca7e4..1877ce0e718 100644 --- a/contrib/tools/python3/src/Modules/clinic/pyexpat.c.h +++ b/contrib/tools/python3/src/Modules/clinic/pyexpat.c.h @@ -1,32 +1,32 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, -"Parse($self, data, isfinal=False, /)\n" -"--\n" -"\n" -"Parse XML data.\n" -"\n" -"`isfinal\' should be true at end of input."); - -#define PYEXPAT_XMLPARSER_PARSE_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, +"Parse($self, data, isfinal=False, /)\n" +"--\n" +"\n" +"Parse XML data.\n" +"\n" +"`isfinal\' should be true at end of input."); + +#define PYEXPAT_XMLPARSER_PARSE_METHODDEF \ {"Parse", (PyCFunction)(void(*)(void))pyexpat_xmlparser_Parse, METH_FASTCALL, pyexpat_xmlparser_Parse__doc__}, - -static PyObject * -pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, - int isfinal); - -static PyObject * -pyexpat_xmlparser_Parse(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - PyObject *data; - int isfinal = 0; - + +static PyObject * +pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, + int isfinal); + +static PyObject * +pyexpat_xmlparser_Parse(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *data; + int isfinal = 0; + if (!_PyArg_CheckPositional("Parse", nargs, 1, 2)) { - goto exit; - } + goto exit; + } data = args[0]; if (nargs < 2) { goto skip_optional; @@ -41,43 +41,43 @@ pyexpat_xmlparser_Parse(xmlparseobject *self, PyObject *const *args, Py_ssize_t goto exit; } skip_optional: - return_value = pyexpat_xmlparser_Parse_impl(self, data, isfinal); - -exit: - return return_value; -} - -PyDoc_STRVAR(pyexpat_xmlparser_ParseFile__doc__, -"ParseFile($self, file, /)\n" -"--\n" -"\n" -"Parse XML data from file-like object."); - -#define PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF \ - {"ParseFile", (PyCFunction)pyexpat_xmlparser_ParseFile, METH_O, pyexpat_xmlparser_ParseFile__doc__}, - -PyDoc_STRVAR(pyexpat_xmlparser_SetBase__doc__, -"SetBase($self, base, /)\n" -"--\n" -"\n" -"Set the base URL for the parser."); - -#define PYEXPAT_XMLPARSER_SETBASE_METHODDEF \ - {"SetBase", (PyCFunction)pyexpat_xmlparser_SetBase, METH_O, pyexpat_xmlparser_SetBase__doc__}, - -static PyObject * -pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base); - -static PyObject * -pyexpat_xmlparser_SetBase(xmlparseobject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *base; - + return_value = pyexpat_xmlparser_Parse_impl(self, data, isfinal); + +exit: + return return_value; +} + +PyDoc_STRVAR(pyexpat_xmlparser_ParseFile__doc__, +"ParseFile($self, file, /)\n" +"--\n" +"\n" +"Parse XML data from file-like object."); + +#define PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF \ + {"ParseFile", (PyCFunction)pyexpat_xmlparser_ParseFile, METH_O, pyexpat_xmlparser_ParseFile__doc__}, + +PyDoc_STRVAR(pyexpat_xmlparser_SetBase__doc__, +"SetBase($self, base, /)\n" +"--\n" +"\n" +"Set the base URL for the parser."); + +#define PYEXPAT_XMLPARSER_SETBASE_METHODDEF \ + {"SetBase", (PyCFunction)pyexpat_xmlparser_SetBase, METH_O, pyexpat_xmlparser_SetBase__doc__}, + +static PyObject * +pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base); + +static PyObject * +pyexpat_xmlparser_SetBase(xmlparseobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *base; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("SetBase", "argument", "str", arg); - goto exit; - } + goto exit; + } Py_ssize_t base_length; base = PyUnicode_AsUTF8AndSize(arg, &base_length); if (base == NULL) { @@ -87,76 +87,76 @@ pyexpat_xmlparser_SetBase(xmlparseobject *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = pyexpat_xmlparser_SetBase_impl(self, base); - -exit: - return return_value; -} - -PyDoc_STRVAR(pyexpat_xmlparser_GetBase__doc__, -"GetBase($self, /)\n" -"--\n" -"\n" -"Return base URL string for the parser."); - -#define PYEXPAT_XMLPARSER_GETBASE_METHODDEF \ - {"GetBase", (PyCFunction)pyexpat_xmlparser_GetBase, METH_NOARGS, pyexpat_xmlparser_GetBase__doc__}, - -static PyObject * -pyexpat_xmlparser_GetBase_impl(xmlparseobject *self); - -static PyObject * -pyexpat_xmlparser_GetBase(xmlparseobject *self, PyObject *Py_UNUSED(ignored)) -{ - return pyexpat_xmlparser_GetBase_impl(self); -} - -PyDoc_STRVAR(pyexpat_xmlparser_GetInputContext__doc__, -"GetInputContext($self, /)\n" -"--\n" -"\n" -"Return the untranslated text of the input that caused the current event.\n" -"\n" -"If the event was generated by a large amount of text (such as a start tag\n" -"for an element with many attributes), not all of the text may be available."); - -#define PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF \ - {"GetInputContext", (PyCFunction)pyexpat_xmlparser_GetInputContext, METH_NOARGS, pyexpat_xmlparser_GetInputContext__doc__}, - -static PyObject * -pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self); - -static PyObject * -pyexpat_xmlparser_GetInputContext(xmlparseobject *self, PyObject *Py_UNUSED(ignored)) -{ - return pyexpat_xmlparser_GetInputContext_impl(self); -} - -PyDoc_STRVAR(pyexpat_xmlparser_ExternalEntityParserCreate__doc__, + return_value = pyexpat_xmlparser_SetBase_impl(self, base); + +exit: + return return_value; +} + +PyDoc_STRVAR(pyexpat_xmlparser_GetBase__doc__, +"GetBase($self, /)\n" +"--\n" +"\n" +"Return base URL string for the parser."); + +#define PYEXPAT_XMLPARSER_GETBASE_METHODDEF \ + {"GetBase", (PyCFunction)pyexpat_xmlparser_GetBase, METH_NOARGS, pyexpat_xmlparser_GetBase__doc__}, + +static PyObject * +pyexpat_xmlparser_GetBase_impl(xmlparseobject *self); + +static PyObject * +pyexpat_xmlparser_GetBase(xmlparseobject *self, PyObject *Py_UNUSED(ignored)) +{ + return pyexpat_xmlparser_GetBase_impl(self); +} + +PyDoc_STRVAR(pyexpat_xmlparser_GetInputContext__doc__, +"GetInputContext($self, /)\n" +"--\n" +"\n" +"Return the untranslated text of the input that caused the current event.\n" +"\n" +"If the event was generated by a large amount of text (such as a start tag\n" +"for an element with many attributes), not all of the text may be available."); + +#define PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF \ + {"GetInputContext", (PyCFunction)pyexpat_xmlparser_GetInputContext, METH_NOARGS, pyexpat_xmlparser_GetInputContext__doc__}, + +static PyObject * +pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self); + +static PyObject * +pyexpat_xmlparser_GetInputContext(xmlparseobject *self, PyObject *Py_UNUSED(ignored)) +{ + return pyexpat_xmlparser_GetInputContext_impl(self); +} + +PyDoc_STRVAR(pyexpat_xmlparser_ExternalEntityParserCreate__doc__, "ExternalEntityParserCreate($self, context, encoding=,\n" " /)\n" -"--\n" -"\n" -"Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler."); - -#define PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF \ +"--\n" +"\n" +"Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler."); + +#define PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF \ {"ExternalEntityParserCreate", (PyCFunction)(void(*)(void))pyexpat_xmlparser_ExternalEntityParserCreate, METH_FASTCALL, pyexpat_xmlparser_ExternalEntityParserCreate__doc__}, - -static PyObject * -pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, - const char *context, - const char *encoding); - -static PyObject * -pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *context; - const char *encoding = NULL; - + +static PyObject * +pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, + const char *context, + const char *encoding); + +static PyObject * +pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *context; + const char *encoding = NULL; + if (!_PyArg_CheckPositional("ExternalEntityParserCreate", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (args[0] == Py_None) { context = NULL; } @@ -192,77 +192,77 @@ pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyObject *con goto exit; } skip_optional: - return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, context, encoding); - -exit: - return return_value; -} - -PyDoc_STRVAR(pyexpat_xmlparser_SetParamEntityParsing__doc__, -"SetParamEntityParsing($self, flag, /)\n" -"--\n" -"\n" -"Controls parsing of parameter entities (including the external DTD subset).\n" -"\n" -"Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n" -"XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n" -"XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n" -"was successful."); - -#define PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF \ - {"SetParamEntityParsing", (PyCFunction)pyexpat_xmlparser_SetParamEntityParsing, METH_O, pyexpat_xmlparser_SetParamEntityParsing__doc__}, - -static PyObject * -pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag); - -static PyObject * -pyexpat_xmlparser_SetParamEntityParsing(xmlparseobject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int flag; - + return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, context, encoding); + +exit: + return return_value; +} + +PyDoc_STRVAR(pyexpat_xmlparser_SetParamEntityParsing__doc__, +"SetParamEntityParsing($self, flag, /)\n" +"--\n" +"\n" +"Controls parsing of parameter entities (including the external DTD subset).\n" +"\n" +"Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n" +"XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n" +"XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n" +"was successful."); + +#define PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF \ + {"SetParamEntityParsing", (PyCFunction)pyexpat_xmlparser_SetParamEntityParsing, METH_O, pyexpat_xmlparser_SetParamEntityParsing__doc__}, + +static PyObject * +pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag); + +static PyObject * +pyexpat_xmlparser_SetParamEntityParsing(xmlparseobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int flag; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } flag = _PyLong_AsInt(arg); if (flag == -1 && PyErr_Occurred()) { goto exit; } - return_value = pyexpat_xmlparser_SetParamEntityParsing_impl(self, flag); - -exit: - return return_value; -} - -#if (XML_COMBINED_VERSION >= 19505) - -PyDoc_STRVAR(pyexpat_xmlparser_UseForeignDTD__doc__, -"UseForeignDTD($self, flag=True, /)\n" -"--\n" -"\n" -"Allows the application to provide an artificial external subset if one is not specified as part of the document instance.\n" -"\n" -"This readily allows the use of a \'default\' document type controlled by the\n" -"application, while still getting the advantage of providing document type\n" -"information to the parser. \'flag\' defaults to True if not provided."); - -#define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF \ + return_value = pyexpat_xmlparser_SetParamEntityParsing_impl(self, flag); + +exit: + return return_value; +} + +#if (XML_COMBINED_VERSION >= 19505) + +PyDoc_STRVAR(pyexpat_xmlparser_UseForeignDTD__doc__, +"UseForeignDTD($self, flag=True, /)\n" +"--\n" +"\n" +"Allows the application to provide an artificial external subset if one is not specified as part of the document instance.\n" +"\n" +"This readily allows the use of a \'default\' document type controlled by the\n" +"application, while still getting the advantage of providing document type\n" +"information to the parser. \'flag\' defaults to True if not provided."); + +#define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF \ {"UseForeignDTD", (PyCFunction)(void(*)(void))pyexpat_xmlparser_UseForeignDTD, METH_FASTCALL, pyexpat_xmlparser_UseForeignDTD__doc__}, - -static PyObject * -pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag); - -static PyObject * -pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int flag = 1; - + +static PyObject * +pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag); + +static PyObject * +pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + if (!_PyArg_CheckPositional("UseForeignDTD", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -271,44 +271,44 @@ pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *const *args, Py_ goto exit; } skip_optional: - return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, flag); - -exit: - return return_value; -} - -#endif /* (XML_COMBINED_VERSION >= 19505) */ - -PyDoc_STRVAR(pyexpat_ParserCreate__doc__, -"ParserCreate($module, /, encoding=None, namespace_separator=None,\n" + return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, flag); + +exit: + return return_value; +} + +#endif /* (XML_COMBINED_VERSION >= 19505) */ + +PyDoc_STRVAR(pyexpat_ParserCreate__doc__, +"ParserCreate($module, /, encoding=None, namespace_separator=None,\n" " intern=)\n" -"--\n" -"\n" -"Return a new XML parser object."); - -#define PYEXPAT_PARSERCREATE_METHODDEF \ +"--\n" +"\n" +"Return a new XML parser object."); + +#define PYEXPAT_PARSERCREATE_METHODDEF \ {"ParserCreate", (PyCFunction)(void(*)(void))pyexpat_ParserCreate, METH_FASTCALL|METH_KEYWORDS, pyexpat_ParserCreate__doc__}, - -static PyObject * -pyexpat_ParserCreate_impl(PyObject *module, const char *encoding, - const char *namespace_separator, PyObject *intern); - -static PyObject * -pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"encoding", "namespace_separator", "intern", NULL}; + +static PyObject * +pyexpat_ParserCreate_impl(PyObject *module, const char *encoding, + const char *namespace_separator, PyObject *intern); + +static PyObject * +pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"encoding", "namespace_separator", "intern", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "ParserCreate", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - const char *encoding = NULL; - const char *namespace_separator = NULL; - PyObject *intern = NULL; - + const char *encoding = NULL; + const char *namespace_separator = NULL; + PyObject *intern = NULL; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -360,46 +360,46 @@ pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, } intern = args[2]; skip_optional_pos: - return_value = pyexpat_ParserCreate_impl(module, encoding, namespace_separator, intern); - -exit: - return return_value; -} - -PyDoc_STRVAR(pyexpat_ErrorString__doc__, -"ErrorString($module, code, /)\n" -"--\n" -"\n" -"Returns string error for given number."); - -#define PYEXPAT_ERRORSTRING_METHODDEF \ - {"ErrorString", (PyCFunction)pyexpat_ErrorString, METH_O, pyexpat_ErrorString__doc__}, - -static PyObject * -pyexpat_ErrorString_impl(PyObject *module, long code); - -static PyObject * -pyexpat_ErrorString(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - long code; - + return_value = pyexpat_ParserCreate_impl(module, encoding, namespace_separator, intern); + +exit: + return return_value; +} + +PyDoc_STRVAR(pyexpat_ErrorString__doc__, +"ErrorString($module, code, /)\n" +"--\n" +"\n" +"Returns string error for given number."); + +#define PYEXPAT_ERRORSTRING_METHODDEF \ + {"ErrorString", (PyCFunction)pyexpat_ErrorString, METH_O, pyexpat_ErrorString__doc__}, + +static PyObject * +pyexpat_ErrorString_impl(PyObject *module, long code); + +static PyObject * +pyexpat_ErrorString(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + long code; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } code = PyLong_AsLong(arg); if (code == -1 && PyErr_Occurred()) { goto exit; } - return_value = pyexpat_ErrorString_impl(module, code); - -exit: - return return_value; -} - -#ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF - #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF -#endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ + return_value = pyexpat_ErrorString_impl(module, code); + +exit: + return return_value; +} + +#ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF + #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF +#endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ /*[clinic end generated code: output=68ce25024280af41 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/resource.c.h b/contrib/tools/python3/src/Modules/clinic/resource.c.h index 80efb714bb6..b9d539eaa72 100644 --- a/contrib/tools/python3/src/Modules/clinic/resource.c.h +++ b/contrib/tools/python3/src/Modules/clinic/resource.c.h @@ -1,92 +1,92 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(resource_getrusage__doc__, -"getrusage($module, who, /)\n" -"--\n" -"\n"); - -#define RESOURCE_GETRUSAGE_METHODDEF \ - {"getrusage", (PyCFunction)resource_getrusage, METH_O, resource_getrusage__doc__}, - -static PyObject * -resource_getrusage_impl(PyObject *module, int who); - -static PyObject * -resource_getrusage(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int who; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(resource_getrusage__doc__, +"getrusage($module, who, /)\n" +"--\n" +"\n"); + +#define RESOURCE_GETRUSAGE_METHODDEF \ + {"getrusage", (PyCFunction)resource_getrusage, METH_O, resource_getrusage__doc__}, + +static PyObject * +resource_getrusage_impl(PyObject *module, int who); + +static PyObject * +resource_getrusage(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int who; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } who = _PyLong_AsInt(arg); if (who == -1 && PyErr_Occurred()) { goto exit; } - return_value = resource_getrusage_impl(module, who); - -exit: - return return_value; -} - -PyDoc_STRVAR(resource_getrlimit__doc__, -"getrlimit($module, resource, /)\n" -"--\n" -"\n"); - -#define RESOURCE_GETRLIMIT_METHODDEF \ - {"getrlimit", (PyCFunction)resource_getrlimit, METH_O, resource_getrlimit__doc__}, - -static PyObject * -resource_getrlimit_impl(PyObject *module, int resource); - -static PyObject * -resource_getrlimit(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int resource; - + return_value = resource_getrusage_impl(module, who); + +exit: + return return_value; +} + +PyDoc_STRVAR(resource_getrlimit__doc__, +"getrlimit($module, resource, /)\n" +"--\n" +"\n"); + +#define RESOURCE_GETRLIMIT_METHODDEF \ + {"getrlimit", (PyCFunction)resource_getrlimit, METH_O, resource_getrlimit__doc__}, + +static PyObject * +resource_getrlimit_impl(PyObject *module, int resource); + +static PyObject * +resource_getrlimit(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int resource; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } resource = _PyLong_AsInt(arg); if (resource == -1 && PyErr_Occurred()) { goto exit; } - return_value = resource_getrlimit_impl(module, resource); - -exit: - return return_value; -} - -PyDoc_STRVAR(resource_setrlimit__doc__, -"setrlimit($module, resource, limits, /)\n" -"--\n" -"\n"); - -#define RESOURCE_SETRLIMIT_METHODDEF \ + return_value = resource_getrlimit_impl(module, resource); + +exit: + return return_value; +} + +PyDoc_STRVAR(resource_setrlimit__doc__, +"setrlimit($module, resource, limits, /)\n" +"--\n" +"\n"); + +#define RESOURCE_SETRLIMIT_METHODDEF \ {"setrlimit", (PyCFunction)(void(*)(void))resource_setrlimit, METH_FASTCALL, resource_setrlimit__doc__}, - -static PyObject * -resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits); - -static PyObject * -resource_setrlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int resource; - PyObject *limits; - + +static PyObject * +resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits); + +static PyObject * +resource_setrlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int resource; + PyObject *limits; + if (!_PyArg_CheckPositional("setrlimit", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -97,85 +97,85 @@ resource_setrlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } limits = args[1]; - return_value = resource_setrlimit_impl(module, resource, limits); - -exit: - return return_value; -} - -#if defined(HAVE_PRLIMIT) - -PyDoc_STRVAR(resource_prlimit__doc__, -"prlimit(pid, resource, [limits])"); - -#define RESOURCE_PRLIMIT_METHODDEF \ - {"prlimit", (PyCFunction)resource_prlimit, METH_VARARGS, resource_prlimit__doc__}, - -static PyObject * -resource_prlimit_impl(PyObject *module, pid_t pid, int resource, - int group_right_1, PyObject *limits); - -static PyObject * -resource_prlimit(PyObject *module, PyObject *args) -{ - PyObject *return_value = NULL; - pid_t pid; - int resource; - int group_right_1 = 0; - PyObject *limits = NULL; - - switch (PyTuple_GET_SIZE(args)) { - case 2: - if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "i:prlimit", &pid, &resource)) { - goto exit; - } - break; - case 3: - if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "iO:prlimit", &pid, &resource, &limits)) { - goto exit; - } - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "resource.prlimit requires 2 to 3 arguments"); - goto exit; - } - return_value = resource_prlimit_impl(module, pid, resource, group_right_1, limits); - -exit: - return return_value; -} - -#endif /* defined(HAVE_PRLIMIT) */ - -PyDoc_STRVAR(resource_getpagesize__doc__, -"getpagesize($module, /)\n" -"--\n" -"\n"); - -#define RESOURCE_GETPAGESIZE_METHODDEF \ - {"getpagesize", (PyCFunction)resource_getpagesize, METH_NOARGS, resource_getpagesize__doc__}, - -static int -resource_getpagesize_impl(PyObject *module); - -static PyObject * -resource_getpagesize(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - int _return_value; - - _return_value = resource_getpagesize_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -#ifndef RESOURCE_PRLIMIT_METHODDEF - #define RESOURCE_PRLIMIT_METHODDEF -#endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */ + return_value = resource_setrlimit_impl(module, resource, limits); + +exit: + return return_value; +} + +#if defined(HAVE_PRLIMIT) + +PyDoc_STRVAR(resource_prlimit__doc__, +"prlimit(pid, resource, [limits])"); + +#define RESOURCE_PRLIMIT_METHODDEF \ + {"prlimit", (PyCFunction)resource_prlimit, METH_VARARGS, resource_prlimit__doc__}, + +static PyObject * +resource_prlimit_impl(PyObject *module, pid_t pid, int resource, + int group_right_1, PyObject *limits); + +static PyObject * +resource_prlimit(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pid; + int resource; + int group_right_1 = 0; + PyObject *limits = NULL; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "i:prlimit", &pid, &resource)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "iO:prlimit", &pid, &resource, &limits)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "resource.prlimit requires 2 to 3 arguments"); + goto exit; + } + return_value = resource_prlimit_impl(module, pid, resource, group_right_1, limits); + +exit: + return return_value; +} + +#endif /* defined(HAVE_PRLIMIT) */ + +PyDoc_STRVAR(resource_getpagesize__doc__, +"getpagesize($module, /)\n" +"--\n" +"\n"); + +#define RESOURCE_GETPAGESIZE_METHODDEF \ + {"getpagesize", (PyCFunction)resource_getpagesize, METH_NOARGS, resource_getpagesize__doc__}, + +static int +resource_getpagesize_impl(PyObject *module); + +static PyObject * +resource_getpagesize(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = resource_getpagesize_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#ifndef RESOURCE_PRLIMIT_METHODDEF + #define RESOURCE_PRLIMIT_METHODDEF +#endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */ /*[clinic end generated code: output=ef3034f291156a34 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/sha1module.c.h b/contrib/tools/python3/src/Modules/clinic/sha1module.c.h index fc37b1ab880..b2a5f854e99 100644 --- a/contrib/tools/python3/src/Modules/clinic/sha1module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/sha1module.c.h @@ -1,97 +1,97 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(SHA1Type_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define SHA1TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA1Type_copy, METH_NOARGS, SHA1Type_copy__doc__}, - -static PyObject * -SHA1Type_copy_impl(SHA1object *self); - -static PyObject * -SHA1Type_copy(SHA1object *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA1Type_copy_impl(self); -} - -PyDoc_STRVAR(SHA1Type_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define SHA1TYPE_DIGEST_METHODDEF \ - {"digest", (PyCFunction)SHA1Type_digest, METH_NOARGS, SHA1Type_digest__doc__}, - -static PyObject * -SHA1Type_digest_impl(SHA1object *self); - -static PyObject * -SHA1Type_digest(SHA1object *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA1Type_digest_impl(self); -} - -PyDoc_STRVAR(SHA1Type_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define SHA1TYPE_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)SHA1Type_hexdigest, METH_NOARGS, SHA1Type_hexdigest__doc__}, - -static PyObject * -SHA1Type_hexdigest_impl(SHA1object *self); - -static PyObject * -SHA1Type_hexdigest(SHA1object *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA1Type_hexdigest_impl(self); -} - -PyDoc_STRVAR(SHA1Type_update__doc__, -"update($self, obj, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided string."); - -#define SHA1TYPE_UPDATE_METHODDEF \ - {"update", (PyCFunction)SHA1Type_update, METH_O, SHA1Type_update__doc__}, - -PyDoc_STRVAR(_sha1_sha1__doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA1Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define SHA1TYPE_COPY_METHODDEF \ + {"copy", (PyCFunction)SHA1Type_copy, METH_NOARGS, SHA1Type_copy__doc__}, + +static PyObject * +SHA1Type_copy_impl(SHA1object *self); + +static PyObject * +SHA1Type_copy(SHA1object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA1Type_copy_impl(self); +} + +PyDoc_STRVAR(SHA1Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define SHA1TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)SHA1Type_digest, METH_NOARGS, SHA1Type_digest__doc__}, + +static PyObject * +SHA1Type_digest_impl(SHA1object *self); + +static PyObject * +SHA1Type_digest(SHA1object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA1Type_digest_impl(self); +} + +PyDoc_STRVAR(SHA1Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define SHA1TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)SHA1Type_hexdigest, METH_NOARGS, SHA1Type_hexdigest__doc__}, + +static PyObject * +SHA1Type_hexdigest_impl(SHA1object *self); + +static PyObject * +SHA1Type_hexdigest(SHA1object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA1Type_hexdigest_impl(self); +} + +PyDoc_STRVAR(SHA1Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define SHA1TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)SHA1Type_update, METH_O, SHA1Type_update__doc__}, + +PyDoc_STRVAR(_sha1_sha1__doc__, "sha1($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA1 hash object; optionally initialized with a string."); - -#define _SHA1_SHA1_METHODDEF \ +"--\n" +"\n" +"Return a new SHA1 hash object; optionally initialized with a string."); + +#define _SHA1_SHA1_METHODDEF \ {"sha1", (PyCFunction)(void(*)(void))_sha1_sha1, METH_FASTCALL|METH_KEYWORDS, _sha1_sha1__doc__}, - -static PyObject * + +static PyObject * _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "sha1", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; + PyObject *string = NULL; int usedforsecurity = 1; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -111,8 +111,8 @@ skip_optional_pos: } skip_optional_kwonly: return_value = _sha1_sha1_impl(module, string, usedforsecurity); - -exit: - return return_value; -} + +exit: + return return_value; +} /*[clinic end generated code: output=3ddd637ae17e14b3 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/sha256module.c.h b/contrib/tools/python3/src/Modules/clinic/sha256module.c.h index 2a788ea9849..90802aacd39 100644 --- a/contrib/tools/python3/src/Modules/clinic/sha256module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/sha256module.c.h @@ -1,97 +1,97 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(SHA256Type_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define SHA256TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA256Type_copy, METH_NOARGS, SHA256Type_copy__doc__}, - -static PyObject * -SHA256Type_copy_impl(SHAobject *self); - -static PyObject * -SHA256Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA256Type_copy_impl(self); -} - -PyDoc_STRVAR(SHA256Type_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define SHA256TYPE_DIGEST_METHODDEF \ - {"digest", (PyCFunction)SHA256Type_digest, METH_NOARGS, SHA256Type_digest__doc__}, - -static PyObject * -SHA256Type_digest_impl(SHAobject *self); - -static PyObject * -SHA256Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA256Type_digest_impl(self); -} - -PyDoc_STRVAR(SHA256Type_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define SHA256TYPE_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)SHA256Type_hexdigest, METH_NOARGS, SHA256Type_hexdigest__doc__}, - -static PyObject * -SHA256Type_hexdigest_impl(SHAobject *self); - -static PyObject * -SHA256Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA256Type_hexdigest_impl(self); -} - -PyDoc_STRVAR(SHA256Type_update__doc__, -"update($self, obj, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided string."); - -#define SHA256TYPE_UPDATE_METHODDEF \ - {"update", (PyCFunction)SHA256Type_update, METH_O, SHA256Type_update__doc__}, - -PyDoc_STRVAR(_sha256_sha256__doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA256Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define SHA256TYPE_COPY_METHODDEF \ + {"copy", (PyCFunction)SHA256Type_copy, METH_NOARGS, SHA256Type_copy__doc__}, + +static PyObject * +SHA256Type_copy_impl(SHAobject *self); + +static PyObject * +SHA256Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA256Type_copy_impl(self); +} + +PyDoc_STRVAR(SHA256Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define SHA256TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)SHA256Type_digest, METH_NOARGS, SHA256Type_digest__doc__}, + +static PyObject * +SHA256Type_digest_impl(SHAobject *self); + +static PyObject * +SHA256Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA256Type_digest_impl(self); +} + +PyDoc_STRVAR(SHA256Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define SHA256TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)SHA256Type_hexdigest, METH_NOARGS, SHA256Type_hexdigest__doc__}, + +static PyObject * +SHA256Type_hexdigest_impl(SHAobject *self); + +static PyObject * +SHA256Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA256Type_hexdigest_impl(self); +} + +PyDoc_STRVAR(SHA256Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define SHA256TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)SHA256Type_update, METH_O, SHA256Type_update__doc__}, + +PyDoc_STRVAR(_sha256_sha256__doc__, "sha256($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA-256 hash object; optionally initialized with a string."); - -#define _SHA256_SHA256_METHODDEF \ +"--\n" +"\n" +"Return a new SHA-256 hash object; optionally initialized with a string."); + +#define _SHA256_SHA256_METHODDEF \ {"sha256", (PyCFunction)(void(*)(void))_sha256_sha256, METH_FASTCALL|METH_KEYWORDS, _sha256_sha256__doc__}, - -static PyObject * + +static PyObject * _sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha256_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_sha256_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "sha256", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; + PyObject *string = NULL; int usedforsecurity = 1; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -111,38 +111,38 @@ skip_optional_pos: } skip_optional_kwonly: return_value = _sha256_sha256_impl(module, string, usedforsecurity); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sha256_sha224__doc__, + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha256_sha224__doc__, "sha224($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA-224 hash object; optionally initialized with a string."); - -#define _SHA256_SHA224_METHODDEF \ +"--\n" +"\n" +"Return a new SHA-224 hash object; optionally initialized with a string."); + +#define _SHA256_SHA224_METHODDEF \ {"sha224", (PyCFunction)(void(*)(void))_sha256_sha224, METH_FASTCALL|METH_KEYWORDS, _sha256_sha224__doc__}, - -static PyObject * + +static PyObject * _sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "sha224", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; + PyObject *string = NULL; int usedforsecurity = 1; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -162,8 +162,8 @@ skip_optional_pos: } skip_optional_kwonly: return_value = _sha256_sha224_impl(module, string, usedforsecurity); - -exit: - return return_value; -} + +exit: + return return_value; +} /*[clinic end generated code: output=c8cca8adbe72ec9a input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/sha512module.c.h b/contrib/tools/python3/src/Modules/clinic/sha512module.c.h index b8185b62bb6..35db468eeda 100644 --- a/contrib/tools/python3/src/Modules/clinic/sha512module.c.h +++ b/contrib/tools/python3/src/Modules/clinic/sha512module.c.h @@ -1,97 +1,97 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(SHA512Type_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define SHA512TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)SHA512Type_copy, METH_NOARGS, SHA512Type_copy__doc__}, - -static PyObject * -SHA512Type_copy_impl(SHAobject *self); - -static PyObject * -SHA512Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA512Type_copy_impl(self); -} - -PyDoc_STRVAR(SHA512Type_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define SHA512TYPE_DIGEST_METHODDEF \ - {"digest", (PyCFunction)SHA512Type_digest, METH_NOARGS, SHA512Type_digest__doc__}, - -static PyObject * -SHA512Type_digest_impl(SHAobject *self); - -static PyObject * -SHA512Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA512Type_digest_impl(self); -} - -PyDoc_STRVAR(SHA512Type_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define SHA512TYPE_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)SHA512Type_hexdigest, METH_NOARGS, SHA512Type_hexdigest__doc__}, - -static PyObject * -SHA512Type_hexdigest_impl(SHAobject *self); - -static PyObject * -SHA512Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA512Type_hexdigest_impl(self); -} - -PyDoc_STRVAR(SHA512Type_update__doc__, -"update($self, obj, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided string."); - -#define SHA512TYPE_UPDATE_METHODDEF \ - {"update", (PyCFunction)SHA512Type_update, METH_O, SHA512Type_update__doc__}, - -PyDoc_STRVAR(_sha512_sha512__doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA512Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define SHA512TYPE_COPY_METHODDEF \ + {"copy", (PyCFunction)SHA512Type_copy, METH_NOARGS, SHA512Type_copy__doc__}, + +static PyObject * +SHA512Type_copy_impl(SHAobject *self); + +static PyObject * +SHA512Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA512Type_copy_impl(self); +} + +PyDoc_STRVAR(SHA512Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define SHA512TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)SHA512Type_digest, METH_NOARGS, SHA512Type_digest__doc__}, + +static PyObject * +SHA512Type_digest_impl(SHAobject *self); + +static PyObject * +SHA512Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA512Type_digest_impl(self); +} + +PyDoc_STRVAR(SHA512Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define SHA512TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)SHA512Type_hexdigest, METH_NOARGS, SHA512Type_hexdigest__doc__}, + +static PyObject * +SHA512Type_hexdigest_impl(SHAobject *self); + +static PyObject * +SHA512Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA512Type_hexdigest_impl(self); +} + +PyDoc_STRVAR(SHA512Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define SHA512TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)SHA512Type_update, METH_O, SHA512Type_update__doc__}, + +PyDoc_STRVAR(_sha512_sha512__doc__, "sha512($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA-512 hash object; optionally initialized with a string."); - -#define _SHA512_SHA512_METHODDEF \ +"--\n" +"\n" +"Return a new SHA-512 hash object; optionally initialized with a string."); + +#define _SHA512_SHA512_METHODDEF \ {"sha512", (PyCFunction)(void(*)(void))_sha512_sha512, METH_FASTCALL|METH_KEYWORDS, _sha512_sha512__doc__}, - -static PyObject * + +static PyObject * _sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha512_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_sha512_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "sha512", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; + PyObject *string = NULL; int usedforsecurity = 1; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -111,38 +111,38 @@ skip_optional_pos: } skip_optional_kwonly: return_value = _sha512_sha512_impl(module, string, usedforsecurity); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sha512_sha384__doc__, + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha512_sha384__doc__, "sha384($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA-384 hash object; optionally initialized with a string."); - -#define _SHA512_SHA384_METHODDEF \ +"--\n" +"\n" +"Return a new SHA-384 hash object; optionally initialized with a string."); + +#define _SHA512_SHA384_METHODDEF \ {"sha384", (PyCFunction)(void(*)(void))_sha512_sha384, METH_FASTCALL|METH_KEYWORDS, _sha512_sha384__doc__}, - -static PyObject * + +static PyObject * _sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; + +static PyObject * +_sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "sha384", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; + PyObject *string = NULL; int usedforsecurity = 1; - + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -162,8 +162,8 @@ skip_optional_pos: } skip_optional_kwonly: return_value = _sha512_sha384_impl(module, string, usedforsecurity); - -exit: - return return_value; -} + +exit: + return return_value; +} /*[clinic end generated code: output=bbfa72d8703c82b5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/signalmodule.c.h b/contrib/tools/python3/src/Modules/clinic/signalmodule.c.h index 0fb25d5640b..ecb449b58ea 100644 --- a/contrib/tools/python3/src/Modules/clinic/signalmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/signalmodule.c.h @@ -1,71 +1,71 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -#if defined(HAVE_ALARM) - -PyDoc_STRVAR(signal_alarm__doc__, -"alarm($module, seconds, /)\n" -"--\n" -"\n" -"Arrange for SIGALRM to arrive after the given number of seconds."); - -#define SIGNAL_ALARM_METHODDEF \ - {"alarm", (PyCFunction)signal_alarm, METH_O, signal_alarm__doc__}, - -static long -signal_alarm_impl(PyObject *module, int seconds); - -static PyObject * -signal_alarm(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int seconds; - long _return_value; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(HAVE_ALARM) + +PyDoc_STRVAR(signal_alarm__doc__, +"alarm($module, seconds, /)\n" +"--\n" +"\n" +"Arrange for SIGALRM to arrive after the given number of seconds."); + +#define SIGNAL_ALARM_METHODDEF \ + {"alarm", (PyCFunction)signal_alarm, METH_O, signal_alarm__doc__}, + +static long +signal_alarm_impl(PyObject *module, int seconds); + +static PyObject * +signal_alarm(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int seconds; + long _return_value; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } seconds = _PyLong_AsInt(arg); if (seconds == -1 && PyErr_Occurred()) { goto exit; } - _return_value = signal_alarm_impl(module, seconds); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong(_return_value); - -exit: - return return_value; -} - -#endif /* defined(HAVE_ALARM) */ - -#if defined(HAVE_PAUSE) - -PyDoc_STRVAR(signal_pause__doc__, -"pause($module, /)\n" -"--\n" -"\n" -"Wait until a signal arrives."); - -#define SIGNAL_PAUSE_METHODDEF \ - {"pause", (PyCFunction)signal_pause, METH_NOARGS, signal_pause__doc__}, - -static PyObject * -signal_pause_impl(PyObject *module); - -static PyObject * -signal_pause(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return signal_pause_impl(module); -} - -#endif /* defined(HAVE_PAUSE) */ - + _return_value = signal_alarm_impl(module, seconds); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(HAVE_ALARM) */ + +#if defined(HAVE_PAUSE) + +PyDoc_STRVAR(signal_pause__doc__, +"pause($module, /)\n" +"--\n" +"\n" +"Wait until a signal arrives."); + +#define SIGNAL_PAUSE_METHODDEF \ + {"pause", (PyCFunction)signal_pause, METH_NOARGS, signal_pause__doc__}, + +static PyObject * +signal_pause_impl(PyObject *module); + +static PyObject * +signal_pause(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return signal_pause_impl(module); +} + +#endif /* defined(HAVE_PAUSE) */ + PyDoc_STRVAR(signal_raise_signal__doc__, "raise_signal($module, signalnum, /)\n" "--\n" @@ -99,35 +99,35 @@ exit: return return_value; } -PyDoc_STRVAR(signal_signal__doc__, -"signal($module, signalnum, handler, /)\n" -"--\n" -"\n" -"Set the action for the given signal.\n" -"\n" -"The action can be SIG_DFL, SIG_IGN, or a callable Python object.\n" -"The previous action is returned. See getsignal() for possible return values.\n" -"\n" -"*** IMPORTANT NOTICE ***\n" -"A signal handler function is called with two arguments:\n" -"the first is the signal number, the second is the interrupted stack frame."); - -#define SIGNAL_SIGNAL_METHODDEF \ +PyDoc_STRVAR(signal_signal__doc__, +"signal($module, signalnum, handler, /)\n" +"--\n" +"\n" +"Set the action for the given signal.\n" +"\n" +"The action can be SIG_DFL, SIG_IGN, or a callable Python object.\n" +"The previous action is returned. See getsignal() for possible return values.\n" +"\n" +"*** IMPORTANT NOTICE ***\n" +"A signal handler function is called with two arguments:\n" +"the first is the signal number, the second is the interrupted stack frame."); + +#define SIGNAL_SIGNAL_METHODDEF \ {"signal", (PyCFunction)(void(*)(void))signal_signal, METH_FASTCALL, signal_signal__doc__}, - -static PyObject * -signal_signal_impl(PyObject *module, int signalnum, PyObject *handler); - -static PyObject * -signal_signal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int signalnum; - PyObject *handler; - + +static PyObject * +signal_signal_impl(PyObject *module, int signalnum, PyObject *handler); + +static PyObject * +signal_signal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int signalnum; + PyObject *handler; + if (!_PyArg_CheckPositional("signal", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -138,51 +138,51 @@ signal_signal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } handler = args[1]; - return_value = signal_signal_impl(module, signalnum, handler); - -exit: - return return_value; -} - -PyDoc_STRVAR(signal_getsignal__doc__, -"getsignal($module, signalnum, /)\n" -"--\n" -"\n" -"Return the current action for the given signal.\n" -"\n" -"The return value can be:\n" -" SIG_IGN -- if the signal is being ignored\n" -" SIG_DFL -- if the default action for the signal is in effect\n" -" None -- if an unknown handler is in effect\n" -" anything else -- the callable Python object used as a handler"); - -#define SIGNAL_GETSIGNAL_METHODDEF \ - {"getsignal", (PyCFunction)signal_getsignal, METH_O, signal_getsignal__doc__}, - -static PyObject * -signal_getsignal_impl(PyObject *module, int signalnum); - -static PyObject * -signal_getsignal(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int signalnum; - + return_value = signal_signal_impl(module, signalnum, handler); + +exit: + return return_value; +} + +PyDoc_STRVAR(signal_getsignal__doc__, +"getsignal($module, signalnum, /)\n" +"--\n" +"\n" +"Return the current action for the given signal.\n" +"\n" +"The return value can be:\n" +" SIG_IGN -- if the signal is being ignored\n" +" SIG_DFL -- if the default action for the signal is in effect\n" +" None -- if an unknown handler is in effect\n" +" anything else -- the callable Python object used as a handler"); + +#define SIGNAL_GETSIGNAL_METHODDEF \ + {"getsignal", (PyCFunction)signal_getsignal, METH_O, signal_getsignal__doc__}, + +static PyObject * +signal_getsignal_impl(PyObject *module, int signalnum); + +static PyObject * +signal_getsignal(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int signalnum; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } signalnum = _PyLong_AsInt(arg); if (signalnum == -1 && PyErr_Occurred()) { goto exit; } - return_value = signal_getsignal_impl(module, signalnum); - -exit: - return return_value; -} - + return_value = signal_getsignal_impl(module, signalnum); + +exit: + return return_value; +} + PyDoc_STRVAR(signal_strsignal__doc__, "strsignal($module, signalnum, /)\n" "--\n" @@ -219,33 +219,33 @@ exit: return return_value; } -#if defined(HAVE_SIGINTERRUPT) - -PyDoc_STRVAR(signal_siginterrupt__doc__, -"siginterrupt($module, signalnum, flag, /)\n" -"--\n" -"\n" -"Change system call restart behaviour.\n" -"\n" -"If flag is False, system calls will be restarted when interrupted by\n" -"signal sig, else system calls will be interrupted."); - -#define SIGNAL_SIGINTERRUPT_METHODDEF \ +#if defined(HAVE_SIGINTERRUPT) + +PyDoc_STRVAR(signal_siginterrupt__doc__, +"siginterrupt($module, signalnum, flag, /)\n" +"--\n" +"\n" +"Change system call restart behaviour.\n" +"\n" +"If flag is False, system calls will be restarted when interrupted by\n" +"signal sig, else system calls will be interrupted."); + +#define SIGNAL_SIGINTERRUPT_METHODDEF \ {"siginterrupt", (PyCFunction)(void(*)(void))signal_siginterrupt, METH_FASTCALL, signal_siginterrupt__doc__}, - -static PyObject * -signal_siginterrupt_impl(PyObject *module, int signalnum, int flag); - -static PyObject * -signal_siginterrupt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int signalnum; - int flag; - + +static PyObject * +signal_siginterrupt_impl(PyObject *module, int signalnum, int flag); + +static PyObject * +signal_siginterrupt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int signalnum; + int flag; + if (!_PyArg_CheckPositional("siginterrupt", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -264,45 +264,45 @@ signal_siginterrupt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (flag == -1 && PyErr_Occurred()) { goto exit; } - return_value = signal_siginterrupt_impl(module, signalnum, flag); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SIGINTERRUPT) */ - -#if defined(HAVE_SETITIMER) - -PyDoc_STRVAR(signal_setitimer__doc__, -"setitimer($module, which, seconds, interval=0.0, /)\n" -"--\n" -"\n" -"Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).\n" -"\n" -"The timer will fire after value seconds and after that every interval seconds.\n" -"The itimer can be cleared by setting seconds to zero.\n" -"\n" -"Returns old values as a tuple: (delay, interval)."); - -#define SIGNAL_SETITIMER_METHODDEF \ + return_value = signal_siginterrupt_impl(module, signalnum, flag); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SIGINTERRUPT) */ + +#if defined(HAVE_SETITIMER) + +PyDoc_STRVAR(signal_setitimer__doc__, +"setitimer($module, which, seconds, interval=0.0, /)\n" +"--\n" +"\n" +"Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).\n" +"\n" +"The timer will fire after value seconds and after that every interval seconds.\n" +"The itimer can be cleared by setting seconds to zero.\n" +"\n" +"Returns old values as a tuple: (delay, interval)."); + +#define SIGNAL_SETITIMER_METHODDEF \ {"setitimer", (PyCFunction)(void(*)(void))signal_setitimer, METH_FASTCALL, signal_setitimer__doc__}, - -static PyObject * -signal_setitimer_impl(PyObject *module, int which, PyObject *seconds, - PyObject *interval); - -static PyObject * -signal_setitimer(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int which; - PyObject *seconds; - PyObject *interval = NULL; - + +static PyObject * +signal_setitimer_impl(PyObject *module, int which, PyObject *seconds, + PyObject *interval); + +static PyObject * +signal_setitimer(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int which; + PyObject *seconds; + PyObject *interval = NULL; + if (!_PyArg_CheckPositional("setitimer", nargs, 2, 3)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -318,75 +318,75 @@ signal_setitimer(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } interval = args[2]; skip_optional: - return_value = signal_setitimer_impl(module, which, seconds, interval); - -exit: - return return_value; -} - -#endif /* defined(HAVE_SETITIMER) */ - -#if defined(HAVE_GETITIMER) - -PyDoc_STRVAR(signal_getitimer__doc__, -"getitimer($module, which, /)\n" -"--\n" -"\n" -"Returns current value of given itimer."); - -#define SIGNAL_GETITIMER_METHODDEF \ - {"getitimer", (PyCFunction)signal_getitimer, METH_O, signal_getitimer__doc__}, - -static PyObject * -signal_getitimer_impl(PyObject *module, int which); - -static PyObject * -signal_getitimer(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int which; - + return_value = signal_setitimer_impl(module, which, seconds, interval); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETITIMER) */ + +#if defined(HAVE_GETITIMER) + +PyDoc_STRVAR(signal_getitimer__doc__, +"getitimer($module, which, /)\n" +"--\n" +"\n" +"Returns current value of given itimer."); + +#define SIGNAL_GETITIMER_METHODDEF \ + {"getitimer", (PyCFunction)signal_getitimer, METH_O, signal_getitimer__doc__}, + +static PyObject * +signal_getitimer_impl(PyObject *module, int which); + +static PyObject * +signal_getitimer(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int which; + if (PyFloat_Check(arg)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); - goto exit; - } + goto exit; + } which = _PyLong_AsInt(arg); if (which == -1 && PyErr_Occurred()) { goto exit; } - return_value = signal_getitimer_impl(module, which); - -exit: - return return_value; -} - -#endif /* defined(HAVE_GETITIMER) */ - + return_value = signal_getitimer_impl(module, which); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETITIMER) */ + #if defined(HAVE_SIGSET_T) && defined(PYPTHREAD_SIGMASK) - -PyDoc_STRVAR(signal_pthread_sigmask__doc__, -"pthread_sigmask($module, how, mask, /)\n" -"--\n" -"\n" -"Fetch and/or change the signal mask of the calling thread."); - -#define SIGNAL_PTHREAD_SIGMASK_METHODDEF \ + +PyDoc_STRVAR(signal_pthread_sigmask__doc__, +"pthread_sigmask($module, how, mask, /)\n" +"--\n" +"\n" +"Fetch and/or change the signal mask of the calling thread."); + +#define SIGNAL_PTHREAD_SIGMASK_METHODDEF \ {"pthread_sigmask", (PyCFunction)(void(*)(void))signal_pthread_sigmask, METH_FASTCALL, signal_pthread_sigmask__doc__}, - -static PyObject * + +static PyObject * signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask); - -static PyObject * -signal_pthread_sigmask(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int how; + +static PyObject * +signal_pthread_sigmask(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int how; sigset_t mask; - + if (!_PyArg_CheckPositional("pthread_sigmask", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (PyFloat_Check(args[0])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -399,54 +399,54 @@ signal_pthread_sigmask(PyObject *module, PyObject *const *args, Py_ssize_t nargs if (!_Py_Sigset_Converter(args[1], &mask)) { goto exit; } - return_value = signal_pthread_sigmask_impl(module, how, mask); - -exit: - return return_value; -} - + return_value = signal_pthread_sigmask_impl(module, how, mask); + +exit: + return return_value; +} + #endif /* defined(HAVE_SIGSET_T) && defined(PYPTHREAD_SIGMASK) */ - + #if defined(HAVE_SIGSET_T) && defined(HAVE_SIGPENDING) - -PyDoc_STRVAR(signal_sigpending__doc__, -"sigpending($module, /)\n" -"--\n" -"\n" -"Examine pending signals.\n" -"\n" -"Returns a set of signal numbers that are pending for delivery to\n" -"the calling thread."); - -#define SIGNAL_SIGPENDING_METHODDEF \ - {"sigpending", (PyCFunction)signal_sigpending, METH_NOARGS, signal_sigpending__doc__}, - -static PyObject * -signal_sigpending_impl(PyObject *module); - -static PyObject * -signal_sigpending(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return signal_sigpending_impl(module); -} - + +PyDoc_STRVAR(signal_sigpending__doc__, +"sigpending($module, /)\n" +"--\n" +"\n" +"Examine pending signals.\n" +"\n" +"Returns a set of signal numbers that are pending for delivery to\n" +"the calling thread."); + +#define SIGNAL_SIGPENDING_METHODDEF \ + {"sigpending", (PyCFunction)signal_sigpending, METH_NOARGS, signal_sigpending__doc__}, + +static PyObject * +signal_sigpending_impl(PyObject *module); + +static PyObject * +signal_sigpending(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return signal_sigpending_impl(module); +} + #endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGPENDING) */ - + #if defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAIT) - -PyDoc_STRVAR(signal_sigwait__doc__, -"sigwait($module, sigset, /)\n" -"--\n" -"\n" -"Wait for a signal.\n" -"\n" -"Suspend execution of the calling thread until the delivery of one of the\n" -"signals specified in the signal set sigset. The function accepts the signal\n" -"and returns the signal number."); - -#define SIGNAL_SIGWAIT_METHODDEF \ - {"sigwait", (PyCFunction)signal_sigwait, METH_O, signal_sigwait__doc__}, - + +PyDoc_STRVAR(signal_sigwait__doc__, +"sigwait($module, sigset, /)\n" +"--\n" +"\n" +"Wait for a signal.\n" +"\n" +"Suspend execution of the calling thread until the delivery of one of the\n" +"signals specified in the signal set sigset. The function accepts the signal\n" +"and returns the signal number."); + +#define SIGNAL_SIGWAIT_METHODDEF \ + {"sigwait", (PyCFunction)signal_sigwait, METH_O, signal_sigwait__doc__}, + static PyObject * signal_sigwait_impl(PyObject *module, sigset_t sigset); @@ -466,7 +466,7 @@ exit: } #endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAIT) */ - + #if ((defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)) PyDoc_STRVAR(signal_valid_signals__doc__, @@ -493,18 +493,18 @@ signal_valid_signals(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* ((defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)) */ #if defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAITINFO) - -PyDoc_STRVAR(signal_sigwaitinfo__doc__, -"sigwaitinfo($module, sigset, /)\n" -"--\n" -"\n" -"Wait synchronously until one of the signals in *sigset* is delivered.\n" -"\n" -"Returns a struct_siginfo containing information about the signal."); - -#define SIGNAL_SIGWAITINFO_METHODDEF \ - {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, METH_O, signal_sigwaitinfo__doc__}, - + +PyDoc_STRVAR(signal_sigwaitinfo__doc__, +"sigwaitinfo($module, sigset, /)\n" +"--\n" +"\n" +"Wait synchronously until one of the signals in *sigset* is delivered.\n" +"\n" +"Returns a struct_siginfo containing information about the signal."); + +#define SIGNAL_SIGWAITINFO_METHODDEF \ + {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, METH_O, signal_sigwaitinfo__doc__}, + static PyObject * signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset); @@ -524,71 +524,71 @@ exit: } #endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAITINFO) */ - + #if defined(HAVE_SIGSET_T) && defined(HAVE_SIGTIMEDWAIT) - -PyDoc_STRVAR(signal_sigtimedwait__doc__, -"sigtimedwait($module, sigset, timeout, /)\n" -"--\n" -"\n" -"Like sigwaitinfo(), but with a timeout.\n" -"\n" -"The timeout is specified in seconds, with floating point numbers allowed."); - -#define SIGNAL_SIGTIMEDWAIT_METHODDEF \ + +PyDoc_STRVAR(signal_sigtimedwait__doc__, +"sigtimedwait($module, sigset, timeout, /)\n" +"--\n" +"\n" +"Like sigwaitinfo(), but with a timeout.\n" +"\n" +"The timeout is specified in seconds, with floating point numbers allowed."); + +#define SIGNAL_SIGTIMEDWAIT_METHODDEF \ {"sigtimedwait", (PyCFunction)(void(*)(void))signal_sigtimedwait, METH_FASTCALL, signal_sigtimedwait__doc__}, - -static PyObject * + +static PyObject * signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, - PyObject *timeout_obj); - -static PyObject * -signal_sigtimedwait(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; + PyObject *timeout_obj); + +static PyObject * +signal_sigtimedwait(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; sigset_t sigset; - PyObject *timeout_obj; - + PyObject *timeout_obj; + if (!_PyArg_CheckPositional("sigtimedwait", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!_Py_Sigset_Converter(args[0], &sigset)) { goto exit; } timeout_obj = args[1]; - return_value = signal_sigtimedwait_impl(module, sigset, timeout_obj); - -exit: - return return_value; -} - + return_value = signal_sigtimedwait_impl(module, sigset, timeout_obj); + +exit: + return return_value; +} + #endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGTIMEDWAIT) */ - -#if defined(HAVE_PTHREAD_KILL) - -PyDoc_STRVAR(signal_pthread_kill__doc__, -"pthread_kill($module, thread_id, signalnum, /)\n" -"--\n" -"\n" -"Send a signal to a thread."); - -#define SIGNAL_PTHREAD_KILL_METHODDEF \ + +#if defined(HAVE_PTHREAD_KILL) + +PyDoc_STRVAR(signal_pthread_kill__doc__, +"pthread_kill($module, thread_id, signalnum, /)\n" +"--\n" +"\n" +"Send a signal to a thread."); + +#define SIGNAL_PTHREAD_KILL_METHODDEF \ {"pthread_kill", (PyCFunction)(void(*)(void))signal_pthread_kill, METH_FASTCALL, signal_pthread_kill__doc__}, - -static PyObject * -signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, - int signalnum); - -static PyObject * -signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - unsigned long thread_id; - int signalnum; - + +static PyObject * +signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, + int signalnum); + +static PyObject * +signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + unsigned long thread_id; + int signalnum; + if (!_PyArg_CheckPositional("pthread_kill", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!PyLong_Check(args[0])) { _PyArg_BadArgument("pthread_kill", "argument 1", "int", args[0]); goto exit; @@ -603,14 +603,14 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (signalnum == -1 && PyErr_Occurred()) { goto exit; } - return_value = signal_pthread_kill_impl(module, thread_id, signalnum); - -exit: - return return_value; -} - -#endif /* defined(HAVE_PTHREAD_KILL) */ - + return_value = signal_pthread_kill_impl(module, thread_id, signalnum); + +exit: + return return_value; +} + +#endif /* defined(HAVE_PTHREAD_KILL) */ + #if (defined(__linux__) && defined(__NR_pidfd_send_signal)) PyDoc_STRVAR(signal_pidfd_send_signal__doc__, @@ -681,53 +681,53 @@ exit: #endif /* (defined(__linux__) && defined(__NR_pidfd_send_signal)) */ -#ifndef SIGNAL_ALARM_METHODDEF - #define SIGNAL_ALARM_METHODDEF -#endif /* !defined(SIGNAL_ALARM_METHODDEF) */ - -#ifndef SIGNAL_PAUSE_METHODDEF - #define SIGNAL_PAUSE_METHODDEF -#endif /* !defined(SIGNAL_PAUSE_METHODDEF) */ - -#ifndef SIGNAL_SIGINTERRUPT_METHODDEF - #define SIGNAL_SIGINTERRUPT_METHODDEF -#endif /* !defined(SIGNAL_SIGINTERRUPT_METHODDEF) */ - -#ifndef SIGNAL_SETITIMER_METHODDEF - #define SIGNAL_SETITIMER_METHODDEF -#endif /* !defined(SIGNAL_SETITIMER_METHODDEF) */ - -#ifndef SIGNAL_GETITIMER_METHODDEF - #define SIGNAL_GETITIMER_METHODDEF -#endif /* !defined(SIGNAL_GETITIMER_METHODDEF) */ - -#ifndef SIGNAL_PTHREAD_SIGMASK_METHODDEF - #define SIGNAL_PTHREAD_SIGMASK_METHODDEF -#endif /* !defined(SIGNAL_PTHREAD_SIGMASK_METHODDEF) */ - -#ifndef SIGNAL_SIGPENDING_METHODDEF - #define SIGNAL_SIGPENDING_METHODDEF -#endif /* !defined(SIGNAL_SIGPENDING_METHODDEF) */ - -#ifndef SIGNAL_SIGWAIT_METHODDEF - #define SIGNAL_SIGWAIT_METHODDEF -#endif /* !defined(SIGNAL_SIGWAIT_METHODDEF) */ - +#ifndef SIGNAL_ALARM_METHODDEF + #define SIGNAL_ALARM_METHODDEF +#endif /* !defined(SIGNAL_ALARM_METHODDEF) */ + +#ifndef SIGNAL_PAUSE_METHODDEF + #define SIGNAL_PAUSE_METHODDEF +#endif /* !defined(SIGNAL_PAUSE_METHODDEF) */ + +#ifndef SIGNAL_SIGINTERRUPT_METHODDEF + #define SIGNAL_SIGINTERRUPT_METHODDEF +#endif /* !defined(SIGNAL_SIGINTERRUPT_METHODDEF) */ + +#ifndef SIGNAL_SETITIMER_METHODDEF + #define SIGNAL_SETITIMER_METHODDEF +#endif /* !defined(SIGNAL_SETITIMER_METHODDEF) */ + +#ifndef SIGNAL_GETITIMER_METHODDEF + #define SIGNAL_GETITIMER_METHODDEF +#endif /* !defined(SIGNAL_GETITIMER_METHODDEF) */ + +#ifndef SIGNAL_PTHREAD_SIGMASK_METHODDEF + #define SIGNAL_PTHREAD_SIGMASK_METHODDEF +#endif /* !defined(SIGNAL_PTHREAD_SIGMASK_METHODDEF) */ + +#ifndef SIGNAL_SIGPENDING_METHODDEF + #define SIGNAL_SIGPENDING_METHODDEF +#endif /* !defined(SIGNAL_SIGPENDING_METHODDEF) */ + +#ifndef SIGNAL_SIGWAIT_METHODDEF + #define SIGNAL_SIGWAIT_METHODDEF +#endif /* !defined(SIGNAL_SIGWAIT_METHODDEF) */ + #ifndef SIGNAL_VALID_SIGNALS_METHODDEF #define SIGNAL_VALID_SIGNALS_METHODDEF #endif /* !defined(SIGNAL_VALID_SIGNALS_METHODDEF) */ -#ifndef SIGNAL_SIGWAITINFO_METHODDEF - #define SIGNAL_SIGWAITINFO_METHODDEF -#endif /* !defined(SIGNAL_SIGWAITINFO_METHODDEF) */ - -#ifndef SIGNAL_SIGTIMEDWAIT_METHODDEF - #define SIGNAL_SIGTIMEDWAIT_METHODDEF -#endif /* !defined(SIGNAL_SIGTIMEDWAIT_METHODDEF) */ - -#ifndef SIGNAL_PTHREAD_KILL_METHODDEF - #define SIGNAL_PTHREAD_KILL_METHODDEF -#endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ +#ifndef SIGNAL_SIGWAITINFO_METHODDEF + #define SIGNAL_SIGWAITINFO_METHODDEF +#endif /* !defined(SIGNAL_SIGWAITINFO_METHODDEF) */ + +#ifndef SIGNAL_SIGTIMEDWAIT_METHODDEF + #define SIGNAL_SIGTIMEDWAIT_METHODDEF +#endif /* !defined(SIGNAL_SIGTIMEDWAIT_METHODDEF) */ + +#ifndef SIGNAL_PTHREAD_KILL_METHODDEF + #define SIGNAL_PTHREAD_KILL_METHODDEF +#endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ #ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF diff --git a/contrib/tools/python3/src/Modules/clinic/spwdmodule.c.h b/contrib/tools/python3/src/Modules/clinic/spwdmodule.c.h index 411d2344e18..7fb3ad62767 100644 --- a/contrib/tools/python3/src/Modules/clinic/spwdmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/spwdmodule.c.h @@ -1,74 +1,74 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -#if defined(HAVE_GETSPNAM) - -PyDoc_STRVAR(spwd_getspnam__doc__, -"getspnam($module, arg, /)\n" -"--\n" -"\n" -"Return the shadow password database entry for the given user name.\n" -"\n" -"See `help(spwd)` for more on shadow password database entries."); - -#define SPWD_GETSPNAM_METHODDEF \ - {"getspnam", (PyCFunction)spwd_getspnam, METH_O, spwd_getspnam__doc__}, - -static PyObject * -spwd_getspnam_impl(PyObject *module, PyObject *arg); - -static PyObject * -spwd_getspnam(PyObject *module, PyObject *arg_) -{ - PyObject *return_value = NULL; - PyObject *arg; - +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(HAVE_GETSPNAM) + +PyDoc_STRVAR(spwd_getspnam__doc__, +"getspnam($module, arg, /)\n" +"--\n" +"\n" +"Return the shadow password database entry for the given user name.\n" +"\n" +"See `help(spwd)` for more on shadow password database entries."); + +#define SPWD_GETSPNAM_METHODDEF \ + {"getspnam", (PyCFunction)spwd_getspnam, METH_O, spwd_getspnam__doc__}, + +static PyObject * +spwd_getspnam_impl(PyObject *module, PyObject *arg); + +static PyObject * +spwd_getspnam(PyObject *module, PyObject *arg_) +{ + PyObject *return_value = NULL; + PyObject *arg; + if (!PyUnicode_Check(arg_)) { _PyArg_BadArgument("getspnam", "argument", "str", arg_); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg_) == -1) { goto exit; } arg = arg_; - return_value = spwd_getspnam_impl(module, arg); - -exit: - return return_value; -} - -#endif /* defined(HAVE_GETSPNAM) */ - -#if defined(HAVE_GETSPENT) - -PyDoc_STRVAR(spwd_getspall__doc__, -"getspall($module, /)\n" -"--\n" -"\n" -"Return a list of all available shadow password database entries, in arbitrary order.\n" -"\n" -"See `help(spwd)` for more on shadow password database entries."); - -#define SPWD_GETSPALL_METHODDEF \ - {"getspall", (PyCFunction)spwd_getspall, METH_NOARGS, spwd_getspall__doc__}, - -static PyObject * -spwd_getspall_impl(PyObject *module); - -static PyObject * -spwd_getspall(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return spwd_getspall_impl(module); -} - -#endif /* defined(HAVE_GETSPENT) */ - -#ifndef SPWD_GETSPNAM_METHODDEF - #define SPWD_GETSPNAM_METHODDEF -#endif /* !defined(SPWD_GETSPNAM_METHODDEF) */ - -#ifndef SPWD_GETSPALL_METHODDEF - #define SPWD_GETSPALL_METHODDEF -#endif /* !defined(SPWD_GETSPALL_METHODDEF) */ + return_value = spwd_getspnam_impl(module, arg); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETSPNAM) */ + +#if defined(HAVE_GETSPENT) + +PyDoc_STRVAR(spwd_getspall__doc__, +"getspall($module, /)\n" +"--\n" +"\n" +"Return a list of all available shadow password database entries, in arbitrary order.\n" +"\n" +"See `help(spwd)` for more on shadow password database entries."); + +#define SPWD_GETSPALL_METHODDEF \ + {"getspall", (PyCFunction)spwd_getspall, METH_NOARGS, spwd_getspall__doc__}, + +static PyObject * +spwd_getspall_impl(PyObject *module); + +static PyObject * +spwd_getspall(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return spwd_getspall_impl(module); +} + +#endif /* defined(HAVE_GETSPENT) */ + +#ifndef SPWD_GETSPNAM_METHODDEF + #define SPWD_GETSPNAM_METHODDEF +#endif /* !defined(SPWD_GETSPNAM_METHODDEF) */ + +#ifndef SPWD_GETSPALL_METHODDEF + #define SPWD_GETSPALL_METHODDEF +#endif /* !defined(SPWD_GETSPALL_METHODDEF) */ /*[clinic end generated code: output=eec8d0bedcd312e5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/symtablemodule.c.h b/contrib/tools/python3/src/Modules/clinic/symtablemodule.c.h index 4a17f130ac9..507996689a7 100644 --- a/contrib/tools/python3/src/Modules/clinic/symtablemodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/symtablemodule.c.h @@ -1,31 +1,31 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(_symtable_symtable__doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_symtable_symtable__doc__, "symtable($module, source, filename, startstr, /)\n" -"--\n" -"\n" -"Return symbol and scope dictionaries used internally by compiler."); - -#define _SYMTABLE_SYMTABLE_METHODDEF \ +"--\n" +"\n" +"Return symbol and scope dictionaries used internally by compiler."); + +#define _SYMTABLE_SYMTABLE_METHODDEF \ {"symtable", (PyCFunction)(void(*)(void))_symtable_symtable, METH_FASTCALL, _symtable_symtable__doc__}, - -static PyObject * + +static PyObject * _symtable_symtable_impl(PyObject *module, PyObject *source, - PyObject *filename, const char *startstr); - -static PyObject * -_symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; + PyObject *filename, const char *startstr); + +static PyObject * +_symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; PyObject *source; - PyObject *filename; - const char *startstr; - + PyObject *filename; + const char *startstr; + if (!_PyArg_CheckPositional("symtable", nargs, 3, 3)) { - goto exit; - } + goto exit; + } source = args[0]; if (!PyUnicode_FSDecoder(args[1], &filename)) { goto exit; @@ -44,8 +44,8 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } return_value = _symtable_symtable_impl(module, source, filename, startstr); - -exit: - return return_value; -} + +exit: + return return_value; +} /*[clinic end generated code: output=a12f75cdbdf4e52a input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/unicodedata.c.h b/contrib/tools/python3/src/Modules/clinic/unicodedata.c.h index 4251db2edc7..abae069a74f 100644 --- a/contrib/tools/python3/src/Modules/clinic/unicodedata.c.h +++ b/contrib/tools/python3/src/Modules/clinic/unicodedata.c.h @@ -1,34 +1,34 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, "decimal($self, chr, default=, /)\n" -"--\n" -"\n" -"Converts a Unicode character into its equivalent decimal value.\n" -"\n" -"Returns the decimal value assigned to the character chr as integer.\n" -"If no such value is defined, default is returned, or, if not given,\n" -"ValueError is raised."); - -#define UNICODEDATA_UCD_DECIMAL_METHODDEF \ +"--\n" +"\n" +"Converts a Unicode character into its equivalent decimal value.\n" +"\n" +"Returns the decimal value assigned to the character chr as integer.\n" +"If no such value is defined, default is returned, or, if not given,\n" +"ValueError is raised."); + +#define UNICODEDATA_UCD_DECIMAL_METHODDEF \ {"decimal", (PyCFunction)(void(*)(void))unicodedata_UCD_decimal, METH_FASTCALL, unicodedata_UCD_decimal__doc__}, - -static PyObject * -unicodedata_UCD_decimal_impl(PyObject *self, int chr, - PyObject *default_value); - -static PyObject * -unicodedata_UCD_decimal(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int chr; - PyObject *default_value = NULL; - + +static PyObject * +unicodedata_UCD_decimal_impl(PyObject *self, int chr, + PyObject *default_value); + +static PyObject * +unicodedata_UCD_decimal(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int chr; + PyObject *default_value = NULL; + if (!_PyArg_CheckPositional("decimal", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("decimal", "argument 1", "a unicode character", args[0]); goto exit; @@ -46,38 +46,38 @@ unicodedata_UCD_decimal(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } default_value = args[1]; skip_optional: - return_value = unicodedata_UCD_decimal_impl(self, chr, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_digit__doc__, + return_value = unicodedata_UCD_decimal_impl(self, chr, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_digit__doc__, "digit($self, chr, default=, /)\n" -"--\n" -"\n" -"Converts a Unicode character into its equivalent digit value.\n" -"\n" -"Returns the digit value assigned to the character chr as integer.\n" -"If no such value is defined, default is returned, or, if not given,\n" -"ValueError is raised."); - -#define UNICODEDATA_UCD_DIGIT_METHODDEF \ +"--\n" +"\n" +"Converts a Unicode character into its equivalent digit value.\n" +"\n" +"Returns the digit value assigned to the character chr as integer.\n" +"If no such value is defined, default is returned, or, if not given,\n" +"ValueError is raised."); + +#define UNICODEDATA_UCD_DIGIT_METHODDEF \ {"digit", (PyCFunction)(void(*)(void))unicodedata_UCD_digit, METH_FASTCALL, unicodedata_UCD_digit__doc__}, - -static PyObject * -unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value); - -static PyObject * -unicodedata_UCD_digit(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int chr; - PyObject *default_value = NULL; - + +static PyObject * +unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value); + +static PyObject * +unicodedata_UCD_digit(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int chr; + PyObject *default_value = NULL; + if (!_PyArg_CheckPositional("digit", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("digit", "argument 1", "a unicode character", args[0]); goto exit; @@ -95,39 +95,39 @@ unicodedata_UCD_digit(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } default_value = args[1]; skip_optional: - return_value = unicodedata_UCD_digit_impl(self, chr, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_numeric__doc__, + return_value = unicodedata_UCD_digit_impl(self, chr, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_numeric__doc__, "numeric($self, chr, default=, /)\n" -"--\n" -"\n" -"Converts a Unicode character into its equivalent numeric value.\n" -"\n" -"Returns the numeric value assigned to the character chr as float.\n" -"If no such value is defined, default is returned, or, if not given,\n" -"ValueError is raised."); - -#define UNICODEDATA_UCD_NUMERIC_METHODDEF \ +"--\n" +"\n" +"Converts a Unicode character into its equivalent numeric value.\n" +"\n" +"Returns the numeric value assigned to the character chr as float.\n" +"If no such value is defined, default is returned, or, if not given,\n" +"ValueError is raised."); + +#define UNICODEDATA_UCD_NUMERIC_METHODDEF \ {"numeric", (PyCFunction)(void(*)(void))unicodedata_UCD_numeric, METH_FASTCALL, unicodedata_UCD_numeric__doc__}, - -static PyObject * -unicodedata_UCD_numeric_impl(PyObject *self, int chr, - PyObject *default_value); - -static PyObject * -unicodedata_UCD_numeric(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int chr; - PyObject *default_value = NULL; - + +static PyObject * +unicodedata_UCD_numeric_impl(PyObject *self, int chr, + PyObject *default_value); + +static PyObject * +unicodedata_UCD_numeric(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int chr; + PyObject *default_value = NULL; + if (!_PyArg_CheckPositional("numeric", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("numeric", "argument 1", "a unicode character", args[0]); goto exit; @@ -145,34 +145,34 @@ unicodedata_UCD_numeric(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } default_value = args[1]; skip_optional: - return_value = unicodedata_UCD_numeric_impl(self, chr, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_category__doc__, -"category($self, chr, /)\n" -"--\n" -"\n" -"Returns the general category assigned to the character chr as string."); - -#define UNICODEDATA_UCD_CATEGORY_METHODDEF \ - {"category", (PyCFunction)unicodedata_UCD_category, METH_O, unicodedata_UCD_category__doc__}, - -static PyObject * -unicodedata_UCD_category_impl(PyObject *self, int chr); - -static PyObject * -unicodedata_UCD_category(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int chr; - + return_value = unicodedata_UCD_numeric_impl(self, chr, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_category__doc__, +"category($self, chr, /)\n" +"--\n" +"\n" +"Returns the general category assigned to the character chr as string."); + +#define UNICODEDATA_UCD_CATEGORY_METHODDEF \ + {"category", (PyCFunction)unicodedata_UCD_category, METH_O, unicodedata_UCD_category__doc__}, + +static PyObject * +unicodedata_UCD_category_impl(PyObject *self, int chr); + +static PyObject * +unicodedata_UCD_category(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int chr; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("category", "argument", "a unicode character", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg)) { goto exit; } @@ -181,36 +181,36 @@ unicodedata_UCD_category(PyObject *self, PyObject *arg) goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); - return_value = unicodedata_UCD_category_impl(self, chr); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_bidirectional__doc__, -"bidirectional($self, chr, /)\n" -"--\n" -"\n" -"Returns the bidirectional class assigned to the character chr as string.\n" -"\n" -"If no such value is defined, an empty string is returned."); - -#define UNICODEDATA_UCD_BIDIRECTIONAL_METHODDEF \ - {"bidirectional", (PyCFunction)unicodedata_UCD_bidirectional, METH_O, unicodedata_UCD_bidirectional__doc__}, - -static PyObject * -unicodedata_UCD_bidirectional_impl(PyObject *self, int chr); - -static PyObject * -unicodedata_UCD_bidirectional(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int chr; - + return_value = unicodedata_UCD_category_impl(self, chr); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_bidirectional__doc__, +"bidirectional($self, chr, /)\n" +"--\n" +"\n" +"Returns the bidirectional class assigned to the character chr as string.\n" +"\n" +"If no such value is defined, an empty string is returned."); + +#define UNICODEDATA_UCD_BIDIRECTIONAL_METHODDEF \ + {"bidirectional", (PyCFunction)unicodedata_UCD_bidirectional, METH_O, unicodedata_UCD_bidirectional__doc__}, + +static PyObject * +unicodedata_UCD_bidirectional_impl(PyObject *self, int chr); + +static PyObject * +unicodedata_UCD_bidirectional(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int chr; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("bidirectional", "argument", "a unicode character", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg)) { goto exit; } @@ -219,37 +219,37 @@ unicodedata_UCD_bidirectional(PyObject *self, PyObject *arg) goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); - return_value = unicodedata_UCD_bidirectional_impl(self, chr); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_combining__doc__, -"combining($self, chr, /)\n" -"--\n" -"\n" -"Returns the canonical combining class assigned to the character chr as integer.\n" -"\n" -"Returns 0 if no combining class is defined."); - -#define UNICODEDATA_UCD_COMBINING_METHODDEF \ - {"combining", (PyCFunction)unicodedata_UCD_combining, METH_O, unicodedata_UCD_combining__doc__}, - -static int -unicodedata_UCD_combining_impl(PyObject *self, int chr); - -static PyObject * -unicodedata_UCD_combining(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int chr; - int _return_value; - + return_value = unicodedata_UCD_bidirectional_impl(self, chr); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_combining__doc__, +"combining($self, chr, /)\n" +"--\n" +"\n" +"Returns the canonical combining class assigned to the character chr as integer.\n" +"\n" +"Returns 0 if no combining class is defined."); + +#define UNICODEDATA_UCD_COMBINING_METHODDEF \ + {"combining", (PyCFunction)unicodedata_UCD_combining, METH_O, unicodedata_UCD_combining__doc__}, + +static int +unicodedata_UCD_combining_impl(PyObject *self, int chr); + +static PyObject * +unicodedata_UCD_combining(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int chr; + int _return_value; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("combining", "argument", "a unicode character", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg)) { goto exit; } @@ -258,42 +258,42 @@ unicodedata_UCD_combining(PyObject *self, PyObject *arg) goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); - _return_value = unicodedata_UCD_combining_impl(self, chr); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_mirrored__doc__, -"mirrored($self, chr, /)\n" -"--\n" -"\n" -"Returns the mirrored property assigned to the character chr as integer.\n" -"\n" -"Returns 1 if the character has been identified as a \"mirrored\"\n" -"character in bidirectional text, 0 otherwise."); - -#define UNICODEDATA_UCD_MIRRORED_METHODDEF \ - {"mirrored", (PyCFunction)unicodedata_UCD_mirrored, METH_O, unicodedata_UCD_mirrored__doc__}, - -static int -unicodedata_UCD_mirrored_impl(PyObject *self, int chr); - -static PyObject * -unicodedata_UCD_mirrored(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int chr; - int _return_value; - + _return_value = unicodedata_UCD_combining_impl(self, chr); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_mirrored__doc__, +"mirrored($self, chr, /)\n" +"--\n" +"\n" +"Returns the mirrored property assigned to the character chr as integer.\n" +"\n" +"Returns 1 if the character has been identified as a \"mirrored\"\n" +"character in bidirectional text, 0 otherwise."); + +#define UNICODEDATA_UCD_MIRRORED_METHODDEF \ + {"mirrored", (PyCFunction)unicodedata_UCD_mirrored, METH_O, unicodedata_UCD_mirrored__doc__}, + +static int +unicodedata_UCD_mirrored_impl(PyObject *self, int chr); + +static PyObject * +unicodedata_UCD_mirrored(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int chr; + int _return_value; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("mirrored", "argument", "a unicode character", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg)) { goto exit; } @@ -302,38 +302,38 @@ unicodedata_UCD_mirrored(PyObject *self, PyObject *arg) goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); - _return_value = unicodedata_UCD_mirrored_impl(self, chr); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_east_asian_width__doc__, -"east_asian_width($self, chr, /)\n" -"--\n" -"\n" -"Returns the east asian width assigned to the character chr as string."); - -#define UNICODEDATA_UCD_EAST_ASIAN_WIDTH_METHODDEF \ - {"east_asian_width", (PyCFunction)unicodedata_UCD_east_asian_width, METH_O, unicodedata_UCD_east_asian_width__doc__}, - -static PyObject * -unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr); - -static PyObject * -unicodedata_UCD_east_asian_width(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int chr; - + _return_value = unicodedata_UCD_mirrored_impl(self, chr); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_east_asian_width__doc__, +"east_asian_width($self, chr, /)\n" +"--\n" +"\n" +"Returns the east asian width assigned to the character chr as string."); + +#define UNICODEDATA_UCD_EAST_ASIAN_WIDTH_METHODDEF \ + {"east_asian_width", (PyCFunction)unicodedata_UCD_east_asian_width, METH_O, unicodedata_UCD_east_asian_width__doc__}, + +static PyObject * +unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr); + +static PyObject * +unicodedata_UCD_east_asian_width(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int chr; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("east_asian_width", "argument", "a unicode character", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg)) { goto exit; } @@ -342,36 +342,36 @@ unicodedata_UCD_east_asian_width(PyObject *self, PyObject *arg) goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); - return_value = unicodedata_UCD_east_asian_width_impl(self, chr); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_decomposition__doc__, -"decomposition($self, chr, /)\n" -"--\n" -"\n" -"Returns the character decomposition mapping assigned to the character chr as string.\n" -"\n" -"An empty string is returned in case no such mapping is defined."); - -#define UNICODEDATA_UCD_DECOMPOSITION_METHODDEF \ - {"decomposition", (PyCFunction)unicodedata_UCD_decomposition, METH_O, unicodedata_UCD_decomposition__doc__}, - -static PyObject * -unicodedata_UCD_decomposition_impl(PyObject *self, int chr); - -static PyObject * -unicodedata_UCD_decomposition(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - int chr; - + return_value = unicodedata_UCD_east_asian_width_impl(self, chr); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_decomposition__doc__, +"decomposition($self, chr, /)\n" +"--\n" +"\n" +"Returns the character decomposition mapping assigned to the character chr as string.\n" +"\n" +"An empty string is returned in case no such mapping is defined."); + +#define UNICODEDATA_UCD_DECOMPOSITION_METHODDEF \ + {"decomposition", (PyCFunction)unicodedata_UCD_decomposition, METH_O, unicodedata_UCD_decomposition__doc__}, + +static PyObject * +unicodedata_UCD_decomposition_impl(PyObject *self, int chr); + +static PyObject * +unicodedata_UCD_decomposition(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int chr; + if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("decomposition", "argument", "a unicode character", arg); - goto exit; - } + goto exit; + } if (PyUnicode_READY(arg)) { goto exit; } @@ -380,12 +380,12 @@ unicodedata_UCD_decomposition(PyObject *self, PyObject *arg) goto exit; } chr = PyUnicode_READ_CHAR(arg, 0); - return_value = unicodedata_UCD_decomposition_impl(self, chr); - -exit: - return return_value; -} - + return_value = unicodedata_UCD_decomposition_impl(self, chr); + +exit: + return return_value; +} + PyDoc_STRVAR(unicodedata_UCD_is_normalized__doc__, "is_normalized($self, form, unistr, /)\n" "--\n" @@ -433,31 +433,31 @@ exit: return return_value; } -PyDoc_STRVAR(unicodedata_UCD_normalize__doc__, -"normalize($self, form, unistr, /)\n" -"--\n" -"\n" -"Return the normal form \'form\' for the Unicode string unistr.\n" -"\n" -"Valid values for form are \'NFC\', \'NFKC\', \'NFD\', and \'NFKD\'."); - -#define UNICODEDATA_UCD_NORMALIZE_METHODDEF \ +PyDoc_STRVAR(unicodedata_UCD_normalize__doc__, +"normalize($self, form, unistr, /)\n" +"--\n" +"\n" +"Return the normal form \'form\' for the Unicode string unistr.\n" +"\n" +"Valid values for form are \'NFC\', \'NFKC\', \'NFD\', and \'NFKD\'."); + +#define UNICODEDATA_UCD_NORMALIZE_METHODDEF \ {"normalize", (PyCFunction)(void(*)(void))unicodedata_UCD_normalize, METH_FASTCALL, unicodedata_UCD_normalize__doc__}, - -static PyObject * + +static PyObject * unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, - PyObject *input); - -static PyObject * -unicodedata_UCD_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; + PyObject *input); + +static PyObject * +unicodedata_UCD_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; PyObject *form; - PyObject *input; - + PyObject *input; + if (!_PyArg_CheckPositional("normalize", nargs, 2, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("normalize", "argument 1", "str", args[0]); goto exit; @@ -474,37 +474,37 @@ unicodedata_UCD_normalize(PyObject *self, PyObject *const *args, Py_ssize_t narg goto exit; } input = args[1]; - return_value = unicodedata_UCD_normalize_impl(self, form, input); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_name__doc__, + return_value = unicodedata_UCD_normalize_impl(self, form, input); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_name__doc__, "name($self, chr, default=, /)\n" -"--\n" -"\n" -"Returns the name assigned to the character chr as a string.\n" -"\n" -"If no name is defined, default is returned, or, if not given,\n" -"ValueError is raised."); - -#define UNICODEDATA_UCD_NAME_METHODDEF \ +"--\n" +"\n" +"Returns the name assigned to the character chr as a string.\n" +"\n" +"If no name is defined, default is returned, or, if not given,\n" +"ValueError is raised."); + +#define UNICODEDATA_UCD_NAME_METHODDEF \ {"name", (PyCFunction)(void(*)(void))unicodedata_UCD_name, METH_FASTCALL, unicodedata_UCD_name__doc__}, - -static PyObject * -unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value); - -static PyObject * -unicodedata_UCD_name(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int chr; - PyObject *default_value = NULL; - + +static PyObject * +unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value); + +static PyObject * +unicodedata_UCD_name(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int chr; + PyObject *default_value = NULL; + if (!_PyArg_CheckPositional("name", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (!PyUnicode_Check(args[0])) { _PyArg_BadArgument("name", "argument 1", "a unicode character", args[0]); goto exit; @@ -522,41 +522,41 @@ unicodedata_UCD_name(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } default_value = args[1]; skip_optional: - return_value = unicodedata_UCD_name_impl(self, chr, default_value); - -exit: - return return_value; -} - -PyDoc_STRVAR(unicodedata_UCD_lookup__doc__, -"lookup($self, name, /)\n" -"--\n" -"\n" -"Look up character by name.\n" -"\n" -"If a character with the given name is found, return the\n" -"corresponding character. If not found, KeyError is raised."); - -#define UNICODEDATA_UCD_LOOKUP_METHODDEF \ - {"lookup", (PyCFunction)unicodedata_UCD_lookup, METH_O, unicodedata_UCD_lookup__doc__}, - -static PyObject * -unicodedata_UCD_lookup_impl(PyObject *self, const char *name, - Py_ssize_clean_t name_length); - -static PyObject * -unicodedata_UCD_lookup(PyObject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - const char *name; - Py_ssize_clean_t name_length; - - if (!PyArg_Parse(arg, "s#:lookup", &name, &name_length)) { - goto exit; - } - return_value = unicodedata_UCD_lookup_impl(self, name, name_length); - -exit: - return return_value; -} + return_value = unicodedata_UCD_name_impl(self, chr, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_lookup__doc__, +"lookup($self, name, /)\n" +"--\n" +"\n" +"Look up character by name.\n" +"\n" +"If a character with the given name is found, return the\n" +"corresponding character. If not found, KeyError is raised."); + +#define UNICODEDATA_UCD_LOOKUP_METHODDEF \ + {"lookup", (PyCFunction)unicodedata_UCD_lookup, METH_O, unicodedata_UCD_lookup__doc__}, + +static PyObject * +unicodedata_UCD_lookup_impl(PyObject *self, const char *name, + Py_ssize_clean_t name_length); + +static PyObject * +unicodedata_UCD_lookup(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *name; + Py_ssize_clean_t name_length; + + if (!PyArg_Parse(arg, "s#:lookup", &name, &name_length)) { + goto exit; + } + return_value = unicodedata_UCD_lookup_impl(self, name, name_length); + +exit: + return return_value; +} /*[clinic end generated code: output=10c23477dbe8a202 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/clinic/zlibmodule.c.h b/contrib/tools/python3/src/Modules/clinic/zlibmodule.c.h index 77ea04a353b..bc244deeda1 100644 --- a/contrib/tools/python3/src/Modules/clinic/zlibmodule.c.h +++ b/contrib/tools/python3/src/Modules/clinic/zlibmodule.c.h @@ -1,39 +1,39 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(zlib_compress__doc__, -"compress($module, data, /, level=Z_DEFAULT_COMPRESSION)\n" -"--\n" -"\n" -"Returns a bytes object containing compressed data.\n" -"\n" -" data\n" -" Binary data to be compressed.\n" -" level\n" -" Compression level, in 0-9 or -1."); - -#define ZLIB_COMPRESS_METHODDEF \ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(zlib_compress__doc__, +"compress($module, data, /, level=Z_DEFAULT_COMPRESSION)\n" +"--\n" +"\n" +"Returns a bytes object containing compressed data.\n" +"\n" +" data\n" +" Binary data to be compressed.\n" +" level\n" +" Compression level, in 0-9 or -1."); + +#define ZLIB_COMPRESS_METHODDEF \ {"compress", (PyCFunction)(void(*)(void))zlib_compress, METH_FASTCALL|METH_KEYWORDS, zlib_compress__doc__}, - -static PyObject * -zlib_compress_impl(PyObject *module, Py_buffer *data, int level); - -static PyObject * -zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "level", NULL}; + +static PyObject * +zlib_compress_impl(PyObject *module, Py_buffer *data, int level); + +static PyObject * +zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "level", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - int level = Z_DEFAULT_COMPRESSION; - + Py_buffer data = {NULL, NULL}; + int level = Z_DEFAULT_COMPRESSION; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -54,53 +54,53 @@ zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto exit; } skip_optional_pos: - return_value = zlib_compress_impl(module, &data, level); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(zlib_decompress__doc__, -"decompress($module, data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE)\n" -"--\n" -"\n" -"Returns a bytes object containing the uncompressed data.\n" -"\n" -" data\n" -" Compressed data.\n" -" wbits\n" -" The window buffer size and container format.\n" -" bufsize\n" -" The initial output buffer size."); - -#define ZLIB_DECOMPRESS_METHODDEF \ + return_value = zlib_compress_impl(module, &data, level); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(zlib_decompress__doc__, +"decompress($module, data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE)\n" +"--\n" +"\n" +"Returns a bytes object containing the uncompressed data.\n" +"\n" +" data\n" +" Compressed data.\n" +" wbits\n" +" The window buffer size and container format.\n" +" bufsize\n" +" The initial output buffer size."); + +#define ZLIB_DECOMPRESS_METHODDEF \ {"decompress", (PyCFunction)(void(*)(void))zlib_decompress, METH_FASTCALL|METH_KEYWORDS, zlib_decompress__doc__}, - -static PyObject * -zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, - Py_ssize_t bufsize); - -static PyObject * -zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "wbits", "bufsize", NULL}; + +static PyObject * +zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, + Py_ssize_t bufsize); + +static PyObject * +zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "wbits", "bufsize", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - int wbits = MAX_WBITS; - Py_ssize_t bufsize = DEF_BUF_SIZE; - + Py_buffer data = {NULL, NULL}; + int wbits = MAX_WBITS; + Py_ssize_t bufsize = DEF_BUF_SIZE; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -129,73 +129,73 @@ zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto exit; } skip_optional_pos: - return_value = zlib_decompress_impl(module, &data, wbits, bufsize); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(zlib_compressobj__doc__, -"compressobj($module, /, level=Z_DEFAULT_COMPRESSION, method=DEFLATED,\n" -" wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL,\n" -" strategy=Z_DEFAULT_STRATEGY, zdict=None)\n" -"--\n" -"\n" -"Return a compressor object.\n" -"\n" -" level\n" -" The compression level (an integer in the range 0-9 or -1; default is\n" -" currently equivalent to 6). Higher compression levels are slower,\n" -" but produce smaller results.\n" -" method\n" -" The compression algorithm. If given, this must be DEFLATED.\n" -" wbits\n" -" +9 to +15: The base-two logarithm of the window size. Include a zlib\n" -" container.\n" -" -9 to -15: Generate a raw stream.\n" -" +25 to +31: Include a gzip container.\n" -" memLevel\n" -" Controls the amount of memory used for internal compression state.\n" -" Valid values range from 1 to 9. Higher values result in higher memory\n" -" usage, faster compression, and smaller output.\n" -" strategy\n" -" Used to tune the compression algorithm. Possible values are\n" -" Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n" -" zdict\n" -" The predefined compression dictionary - a sequence of bytes\n" -" containing subsequences that are likely to occur in the input data."); - -#define ZLIB_COMPRESSOBJ_METHODDEF \ + return_value = zlib_decompress_impl(module, &data, wbits, bufsize); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(zlib_compressobj__doc__, +"compressobj($module, /, level=Z_DEFAULT_COMPRESSION, method=DEFLATED,\n" +" wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL,\n" +" strategy=Z_DEFAULT_STRATEGY, zdict=None)\n" +"--\n" +"\n" +"Return a compressor object.\n" +"\n" +" level\n" +" The compression level (an integer in the range 0-9 or -1; default is\n" +" currently equivalent to 6). Higher compression levels are slower,\n" +" but produce smaller results.\n" +" method\n" +" The compression algorithm. If given, this must be DEFLATED.\n" +" wbits\n" +" +9 to +15: The base-two logarithm of the window size. Include a zlib\n" +" container.\n" +" -9 to -15: Generate a raw stream.\n" +" +25 to +31: Include a gzip container.\n" +" memLevel\n" +" Controls the amount of memory used for internal compression state.\n" +" Valid values range from 1 to 9. Higher values result in higher memory\n" +" usage, faster compression, and smaller output.\n" +" strategy\n" +" Used to tune the compression algorithm. Possible values are\n" +" Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n" +" zdict\n" +" The predefined compression dictionary - a sequence of bytes\n" +" containing subsequences that are likely to occur in the input data."); + +#define ZLIB_COMPRESSOBJ_METHODDEF \ {"compressobj", (PyCFunction)(void(*)(void))zlib_compressobj, METH_FASTCALL|METH_KEYWORDS, zlib_compressobj__doc__}, - -static PyObject * -zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, - int memLevel, int strategy, Py_buffer *zdict); - -static PyObject * -zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; + +static PyObject * +zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, + int memLevel, int strategy, Py_buffer *zdict); + +static PyObject * +zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "compressobj", 0}; PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - int level = Z_DEFAULT_COMPRESSION; - int method = DEFLATED; - int wbits = MAX_WBITS; - int memLevel = DEF_MEM_LEVEL; - int strategy = Z_DEFAULT_STRATEGY; - Py_buffer zdict = {NULL, NULL}; - + int level = Z_DEFAULT_COMPRESSION; + int method = DEFLATED; + int wbits = MAX_WBITS; + int memLevel = DEF_MEM_LEVEL; + int strategy = Z_DEFAULT_STRATEGY; + Py_buffer zdict = {NULL, NULL}; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 6, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -277,50 +277,50 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb goto exit; } skip_optional_pos: - return_value = zlib_compressobj_impl(module, level, method, wbits, memLevel, strategy, &zdict); - -exit: - /* Cleanup for zdict */ - if (zdict.obj) { - PyBuffer_Release(&zdict); - } - - return return_value; -} - -PyDoc_STRVAR(zlib_decompressobj__doc__, -"decompressobj($module, /, wbits=MAX_WBITS, zdict=b\'\')\n" -"--\n" -"\n" -"Return a decompressor object.\n" -"\n" -" wbits\n" -" The window buffer size and container format.\n" -" zdict\n" -" The predefined compression dictionary. This must be the same\n" -" dictionary as used by the compressor that produced the input data."); - -#define ZLIB_DECOMPRESSOBJ_METHODDEF \ + return_value = zlib_compressobj_impl(module, level, method, wbits, memLevel, strategy, &zdict); + +exit: + /* Cleanup for zdict */ + if (zdict.obj) { + PyBuffer_Release(&zdict); + } + + return return_value; +} + +PyDoc_STRVAR(zlib_decompressobj__doc__, +"decompressobj($module, /, wbits=MAX_WBITS, zdict=b\'\')\n" +"--\n" +"\n" +"Return a decompressor object.\n" +"\n" +" wbits\n" +" The window buffer size and container format.\n" +" zdict\n" +" The predefined compression dictionary. This must be the same\n" +" dictionary as used by the compressor that produced the input data."); + +#define ZLIB_DECOMPRESSOBJ_METHODDEF \ {"decompressobj", (PyCFunction)(void(*)(void))zlib_decompressobj, METH_FASTCALL|METH_KEYWORDS, zlib_decompressobj__doc__}, - -static PyObject * -zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict); - -static PyObject * -zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"wbits", "zdict", NULL}; + +static PyObject * +zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict); + +static PyObject * +zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"wbits", "zdict", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decompressobj", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - int wbits = MAX_WBITS; - PyObject *zdict = NULL; - + int wbits = MAX_WBITS; + PyObject *zdict = NULL; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -340,94 +340,94 @@ zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py } zdict = args[1]; skip_optional_pos: - return_value = zlib_decompressobj_impl(module, wbits, zdict); - -exit: - return return_value; -} - -PyDoc_STRVAR(zlib_Compress_compress__doc__, -"compress($self, data, /)\n" -"--\n" -"\n" -"Returns a bytes object containing compressed data.\n" -"\n" -" data\n" -" Binary data to be compressed.\n" -"\n" -"After calling this function, some of the input data may still\n" -"be stored in internal buffers for later processing.\n" -"Call the flush() method to clear these buffers."); - -#define ZLIB_COMPRESS_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)zlib_Compress_compress, METH_O, zlib_Compress_compress__doc__}, - -static PyObject * -zlib_Compress_compress_impl(compobject *self, Py_buffer *data); - -static PyObject * -zlib_Compress_compress(compobject *self, PyObject *arg) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - + return_value = zlib_decompressobj_impl(module, wbits, zdict); + +exit: + return return_value; +} + +PyDoc_STRVAR(zlib_Compress_compress__doc__, +"compress($self, data, /)\n" +"--\n" +"\n" +"Returns a bytes object containing compressed data.\n" +"\n" +" data\n" +" Binary data to be compressed.\n" +"\n" +"After calling this function, some of the input data may still\n" +"be stored in internal buffers for later processing.\n" +"Call the flush() method to clear these buffers."); + +#define ZLIB_COMPRESS_COMPRESS_METHODDEF \ + {"compress", (PyCFunction)zlib_Compress_compress, METH_O, zlib_Compress_compress__doc__}, + +static PyObject * +zlib_Compress_compress_impl(compobject *self, Py_buffer *data); + +static PyObject * +zlib_Compress_compress(compobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { - goto exit; - } + goto exit; + } if (!PyBuffer_IsContiguous(&data, 'C')) { _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); goto exit; } - return_value = zlib_Compress_compress_impl(self, &data); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(zlib_Decompress_decompress__doc__, -"decompress($self, data, /, max_length=0)\n" -"--\n" -"\n" -"Return a bytes object containing the decompressed version of the data.\n" -"\n" -" data\n" -" The binary data to decompress.\n" -" max_length\n" -" The maximum allowable length of the decompressed data.\n" -" Unconsumed input data will be stored in\n" -" the unconsumed_tail attribute.\n" -"\n" -"After calling this function, some of the input data may still be stored in\n" -"internal buffers for later processing.\n" -"Call the flush() method to clear these buffers."); - -#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \ + return_value = zlib_Compress_compress_impl(self, &data); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(zlib_Decompress_decompress__doc__, +"decompress($self, data, /, max_length=0)\n" +"--\n" +"\n" +"Return a bytes object containing the decompressed version of the data.\n" +"\n" +" data\n" +" The binary data to decompress.\n" +" max_length\n" +" The maximum allowable length of the decompressed data.\n" +" Unconsumed input data will be stored in\n" +" the unconsumed_tail attribute.\n" +"\n" +"After calling this function, some of the input data may still be stored in\n" +"internal buffers for later processing.\n" +"Call the flush() method to clear these buffers."); + +#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \ {"decompress", (PyCFunction)(void(*)(void))zlib_Decompress_decompress, METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_decompress__doc__}, - -static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, - Py_ssize_t max_length); - -static PyObject * -zlib_Decompress_decompress(compobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"", "max_length", NULL}; + +static PyObject * +zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, + Py_ssize_t max_length); + +static PyObject * +zlib_Decompress_decompress(compobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "max_length", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - Py_buffer data = {NULL, NULL}; - Py_ssize_t max_length = 0; - + Py_buffer data = {NULL, NULL}; + Py_ssize_t max_length = 0; + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -442,44 +442,44 @@ zlib_Decompress_decompress(compobject *self, PyObject *const *args, Py_ssize_t n goto exit; } skip_optional_pos: - return_value = zlib_Decompress_decompress_impl(self, &data, max_length); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(zlib_Compress_flush__doc__, -"flush($self, mode=zlib.Z_FINISH, /)\n" -"--\n" -"\n" -"Return a bytes object containing any remaining compressed data.\n" -"\n" -" mode\n" -" One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH.\n" -" If mode == Z_FINISH, the compressor object can no longer be\n" -" used after calling the flush() method. Otherwise, more data\n" -" can still be compressed."); - -#define ZLIB_COMPRESS_FLUSH_METHODDEF \ + return_value = zlib_Decompress_decompress_impl(self, &data, max_length); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(zlib_Compress_flush__doc__, +"flush($self, mode=zlib.Z_FINISH, /)\n" +"--\n" +"\n" +"Return a bytes object containing any remaining compressed data.\n" +"\n" +" mode\n" +" One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH.\n" +" If mode == Z_FINISH, the compressor object can no longer be\n" +" used after calling the flush() method. Otherwise, more data\n" +" can still be compressed."); + +#define ZLIB_COMPRESS_FLUSH_METHODDEF \ {"flush", (PyCFunction)(void(*)(void))zlib_Compress_flush, METH_FASTCALL, zlib_Compress_flush__doc__}, - -static PyObject * -zlib_Compress_flush_impl(compobject *self, int mode); - -static PyObject * -zlib_Compress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - int mode = Z_FINISH; - + +static PyObject * +zlib_Compress_flush_impl(compobject *self, int mode); + +static PyObject * +zlib_Compress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int mode = Z_FINISH; + if (!_PyArg_CheckPositional("flush", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -493,36 +493,36 @@ zlib_Compress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = zlib_Compress_flush_impl(self, mode); - -exit: - return return_value; -} - -#if defined(HAVE_ZLIB_COPY) - -PyDoc_STRVAR(zlib_Compress_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the compression object."); - -#define ZLIB_COMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__}, - -static PyObject * -zlib_Compress_copy_impl(compobject *self); - -static PyObject * -zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) -{ - return zlib_Compress_copy_impl(self); -} - -#endif /* defined(HAVE_ZLIB_COPY) */ - -#if defined(HAVE_ZLIB_COPY) - + return_value = zlib_Compress_flush_impl(self, mode); + +exit: + return return_value; +} + +#if defined(HAVE_ZLIB_COPY) + +PyDoc_STRVAR(zlib_Compress_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the compression object."); + +#define ZLIB_COMPRESS_COPY_METHODDEF \ + {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__}, + +static PyObject * +zlib_Compress_copy_impl(compobject *self); + +static PyObject * +zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +{ + return zlib_Compress_copy_impl(self); +} + +#endif /* defined(HAVE_ZLIB_COPY) */ + +#if defined(HAVE_ZLIB_COPY) + PyDoc_STRVAR(zlib_Compress___copy____doc__, "__copy__($self, /)\n" "--\n" @@ -556,26 +556,26 @@ PyDoc_STRVAR(zlib_Compress___deepcopy____doc__, #if defined(HAVE_ZLIB_COPY) -PyDoc_STRVAR(zlib_Decompress_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the decompression object."); - -#define ZLIB_DECOMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)zlib_Decompress_copy, METH_NOARGS, zlib_Decompress_copy__doc__}, - -static PyObject * -zlib_Decompress_copy_impl(compobject *self); - -static PyObject * -zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) -{ - return zlib_Decompress_copy_impl(self); -} - -#endif /* defined(HAVE_ZLIB_COPY) */ - +PyDoc_STRVAR(zlib_Decompress_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the decompression object."); + +#define ZLIB_DECOMPRESS_COPY_METHODDEF \ + {"copy", (PyCFunction)zlib_Decompress_copy, METH_NOARGS, zlib_Decompress_copy__doc__}, + +static PyObject * +zlib_Decompress_copy_impl(compobject *self); + +static PyObject * +zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +{ + return zlib_Decompress_copy_impl(self); +} + +#endif /* defined(HAVE_ZLIB_COPY) */ + #if defined(HAVE_ZLIB_COPY) PyDoc_STRVAR(zlib_Decompress___copy____doc__, @@ -609,30 +609,30 @@ PyDoc_STRVAR(zlib_Decompress___deepcopy____doc__, #endif /* defined(HAVE_ZLIB_COPY) */ -PyDoc_STRVAR(zlib_Decompress_flush__doc__, -"flush($self, length=zlib.DEF_BUF_SIZE, /)\n" -"--\n" -"\n" -"Return a bytes object containing any remaining decompressed data.\n" -"\n" -" length\n" -" the initial size of the output buffer."); - -#define ZLIB_DECOMPRESS_FLUSH_METHODDEF \ +PyDoc_STRVAR(zlib_Decompress_flush__doc__, +"flush($self, length=zlib.DEF_BUF_SIZE, /)\n" +"--\n" +"\n" +"Return a bytes object containing any remaining decompressed data.\n" +"\n" +" length\n" +" the initial size of the output buffer."); + +#define ZLIB_DECOMPRESS_FLUSH_METHODDEF \ {"flush", (PyCFunction)(void(*)(void))zlib_Decompress_flush, METH_FASTCALL, zlib_Decompress_flush__doc__}, - -static PyObject * -zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length); - -static PyObject * -zlib_Decompress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_ssize_t length = DEF_BUF_SIZE; - + +static PyObject * +zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length); + +static PyObject * +zlib_Decompress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t length = DEF_BUF_SIZE; + if (!_PyArg_CheckPositional("flush", nargs, 0, 1)) { - goto exit; - } + goto exit; + } if (nargs < 1) { goto skip_optional; } @@ -640,39 +640,39 @@ zlib_Decompress_flush(compobject *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = zlib_Decompress_flush_impl(self, length); - -exit: - return return_value; -} - -PyDoc_STRVAR(zlib_adler32__doc__, -"adler32($module, data, value=1, /)\n" -"--\n" -"\n" -"Compute an Adler-32 checksum of data.\n" -"\n" -" value\n" -" Starting value of the checksum.\n" -"\n" -"The returned checksum is an integer."); - -#define ZLIB_ADLER32_METHODDEF \ + return_value = zlib_Decompress_flush_impl(self, length); + +exit: + return return_value; +} + +PyDoc_STRVAR(zlib_adler32__doc__, +"adler32($module, data, value=1, /)\n" +"--\n" +"\n" +"Compute an Adler-32 checksum of data.\n" +"\n" +" value\n" +" Starting value of the checksum.\n" +"\n" +"The returned checksum is an integer."); + +#define ZLIB_ADLER32_METHODDEF \ {"adler32", (PyCFunction)(void(*)(void))zlib_adler32, METH_FASTCALL, zlib_adler32__doc__}, - -static PyObject * -zlib_adler32_impl(PyObject *module, Py_buffer *data, unsigned int value); - -static PyObject * -zlib_adler32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - unsigned int value = 1; - + +static PyObject * +zlib_adler32_impl(PyObject *module, Py_buffer *data, unsigned int value); + +static PyObject * +zlib_adler32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int value = 1; + if (!_PyArg_CheckPositional("adler32", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -693,44 +693,44 @@ zlib_adler32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = zlib_adler32_impl(module, &data, value); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -PyDoc_STRVAR(zlib_crc32__doc__, -"crc32($module, data, value=0, /)\n" -"--\n" -"\n" -"Compute a CRC-32 checksum of data.\n" -"\n" -" value\n" -" Starting value of the checksum.\n" -"\n" -"The returned checksum is an integer."); - -#define ZLIB_CRC32_METHODDEF \ + return_value = zlib_adler32_impl(module, &data, value); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(zlib_crc32__doc__, +"crc32($module, data, value=0, /)\n" +"--\n" +"\n" +"Compute a CRC-32 checksum of data.\n" +"\n" +" value\n" +" Starting value of the checksum.\n" +"\n" +"The returned checksum is an integer."); + +#define ZLIB_CRC32_METHODDEF \ {"crc32", (PyCFunction)(void(*)(void))zlib_crc32, METH_FASTCALL, zlib_crc32__doc__}, - -static PyObject * -zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value); - -static PyObject * -zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - Py_buffer data = {NULL, NULL}; - unsigned int value = 0; - + +static PyObject * +zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value); + +static PyObject * +zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int value = 0; + if (!_PyArg_CheckPositional("crc32", nargs, 1, 2)) { - goto exit; - } + goto exit; + } if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } @@ -751,21 +751,21 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = zlib_crc32_impl(module, &data, value); - -exit: - /* Cleanup for data */ - if (data.obj) { - PyBuffer_Release(&data); - } - - return return_value; -} - -#ifndef ZLIB_COMPRESS_COPY_METHODDEF - #define ZLIB_COMPRESS_COPY_METHODDEF -#endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */ - + return_value = zlib_crc32_impl(module, &data, value); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +#ifndef ZLIB_COMPRESS_COPY_METHODDEF + #define ZLIB_COMPRESS_COPY_METHODDEF +#endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */ + #ifndef ZLIB_COMPRESS___COPY___METHODDEF #define ZLIB_COMPRESS___COPY___METHODDEF #endif /* !defined(ZLIB_COMPRESS___COPY___METHODDEF) */ @@ -774,9 +774,9 @@ exit: #define ZLIB_COMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_COMPRESS___DEEPCOPY___METHODDEF) */ -#ifndef ZLIB_DECOMPRESS_COPY_METHODDEF - #define ZLIB_DECOMPRESS_COPY_METHODDEF -#endif /* !defined(ZLIB_DECOMPRESS_COPY_METHODDEF) */ +#ifndef ZLIB_DECOMPRESS_COPY_METHODDEF + #define ZLIB_DECOMPRESS_COPY_METHODDEF +#endif /* !defined(ZLIB_DECOMPRESS_COPY_METHODDEF) */ #ifndef ZLIB_DECOMPRESS___COPY___METHODDEF #define ZLIB_DECOMPRESS___COPY___METHODDEF diff --git a/contrib/tools/python3/src/Modules/cmathmodule.c b/contrib/tools/python3/src/Modules/cmathmodule.c index 5eac4b4940b..eb87a84d323 100644 --- a/contrib/tools/python3/src/Modules/cmathmodule.c +++ b/contrib/tools/python3/src/Modules/cmathmodule.c @@ -1,1405 +1,1405 @@ -/* Complex math module */ - -/* much code borrowed from mathmodule.c */ - -#include "Python.h" +/* Complex math module */ + +/* much code borrowed from mathmodule.c */ + +#include "Python.h" #include "pycore_dtoa.h" -#include "_math.h" -/* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from - float.h. We assume that FLT_RADIX is either 2 or 16. */ -#include - -#include "clinic/cmathmodule.c.h" -/*[clinic input] -module cmath -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=308d6839f4a46333]*/ - -/*[python input] -class Py_complex_protected_converter(Py_complex_converter): - def modify(self): +#include "_math.h" +/* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from + float.h. We assume that FLT_RADIX is either 2 or 16. */ +#include + +#include "clinic/cmathmodule.c.h" +/*[clinic input] +module cmath +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=308d6839f4a46333]*/ + +/*[python input] +class Py_complex_protected_converter(Py_complex_converter): + def modify(self): return 'errno = 0;' - - -class Py_complex_protected_return_converter(CReturnConverter): - type = "Py_complex" - - def render(self, function, data): - self.declare(data) - data.return_conversion.append(""" -if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - goto exit; -} -else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - goto exit; -} -else { - return_value = PyComplex_FromCComplex(_return_value); -} -""".strip()) -[python start generated code]*/ + + +class Py_complex_protected_return_converter(CReturnConverter): + type = "Py_complex" + + def render(self, function, data): + self.declare(data) + data.return_conversion.append(""" +if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; +} +else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; +} +else { + return_value = PyComplex_FromCComplex(_return_value); +} +""".strip()) +[python start generated code]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=8b27adb674c08321]*/ - -#if (FLT_RADIX != 2 && FLT_RADIX != 16) -#error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16" -#endif - -#ifndef M_LN2 -#define M_LN2 (0.6931471805599453094) /* natural log of 2 */ -#endif - -#ifndef M_LN10 -#define M_LN10 (2.302585092994045684) /* natural log of 10 */ -#endif - -/* - CM_LARGE_DOUBLE is used to avoid spurious overflow in the sqrt, log, - inverse trig and inverse hyperbolic trig functions. Its log is used in the - evaluation of exp, cos, cosh, sin, sinh, tan, and tanh to avoid unnecessary - overflow. - */ - -#define CM_LARGE_DOUBLE (DBL_MAX/4.) -#define CM_SQRT_LARGE_DOUBLE (sqrt(CM_LARGE_DOUBLE)) -#define CM_LOG_LARGE_DOUBLE (log(CM_LARGE_DOUBLE)) -#define CM_SQRT_DBL_MIN (sqrt(DBL_MIN)) - -/* - CM_SCALE_UP is an odd integer chosen such that multiplication by - 2**CM_SCALE_UP is sufficient to turn a subnormal into a normal. - CM_SCALE_DOWN is (-(CM_SCALE_UP+1)/2). These scalings are used to compute - square roots accurately when the real and imaginary parts of the argument - are subnormal. -*/ - -#if FLT_RADIX==2 -#define CM_SCALE_UP (2*(DBL_MANT_DIG/2) + 1) -#elif FLT_RADIX==16 -#define CM_SCALE_UP (4*DBL_MANT_DIG+1) -#endif -#define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2) - -/* Constants cmath.inf, cmath.infj, cmath.nan, cmath.nanj. - cmath.nan and cmath.nanj are defined only when either - PY_NO_SHORT_FLOAT_REPR is *not* defined (which should be - the most common situation on machines using an IEEE 754 - representation), or Py_NAN is defined. */ - -static double -m_inf(void) -{ -#ifndef PY_NO_SHORT_FLOAT_REPR - return _Py_dg_infinity(0); -#else - return Py_HUGE_VAL; -#endif -} - -static Py_complex -c_infj(void) -{ - Py_complex r; - r.real = 0.0; - r.imag = m_inf(); - return r; -} - -#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) - -static double -m_nan(void) -{ -#ifndef PY_NO_SHORT_FLOAT_REPR - return _Py_dg_stdnan(0); -#else - return Py_NAN; -#endif -} - -static Py_complex -c_nanj(void) -{ - Py_complex r; - r.real = 0.0; - r.imag = m_nan(); - return r; -} - -#endif - -/* forward declarations */ -static Py_complex cmath_asinh_impl(PyObject *, Py_complex); -static Py_complex cmath_atanh_impl(PyObject *, Py_complex); -static Py_complex cmath_cosh_impl(PyObject *, Py_complex); -static Py_complex cmath_sinh_impl(PyObject *, Py_complex); -static Py_complex cmath_sqrt_impl(PyObject *, Py_complex); -static Py_complex cmath_tanh_impl(PyObject *, Py_complex); -static PyObject * math_error(void); - -/* Code to deal with special values (infinities, NaNs, etc.). */ - -/* special_type takes a double and returns an integer code indicating - the type of the double as follows: -*/ - -enum special_types { - ST_NINF, /* 0, negative infinity */ - ST_NEG, /* 1, negative finite number (nonzero) */ - ST_NZERO, /* 2, -0. */ - ST_PZERO, /* 3, +0. */ - ST_POS, /* 4, positive finite number (nonzero) */ - ST_PINF, /* 5, positive infinity */ - ST_NAN /* 6, Not a Number */ -}; - -static enum special_types -special_type(double d) -{ - if (Py_IS_FINITE(d)) { - if (d != 0) { - if (copysign(1., d) == 1.) - return ST_POS; - else - return ST_NEG; - } - else { - if (copysign(1., d) == 1.) - return ST_PZERO; - else - return ST_NZERO; - } - } - if (Py_IS_NAN(d)) - return ST_NAN; - if (copysign(1., d) == 1.) - return ST_PINF; - else - return ST_NINF; -} - -#define SPECIAL_VALUE(z, table) \ - if (!Py_IS_FINITE((z).real) || !Py_IS_FINITE((z).imag)) { \ - errno = 0; \ - return table[special_type((z).real)] \ - [special_type((z).imag)]; \ - } - -#define P Py_MATH_PI -#define P14 0.25*Py_MATH_PI -#define P12 0.5*Py_MATH_PI -#define P34 0.75*Py_MATH_PI -#define INF Py_HUGE_VAL -#define N Py_NAN -#define U -9.5426319407711027e33 /* unlikely value, used as placeholder */ - -/* First, the C functions that do the real work. Each of the c_* - functions computes and returns the C99 Annex G recommended result - and also sets errno as follows: errno = 0 if no floating-point - exception is associated with the result; errno = EDOM if C99 Annex - G recommends raising divide-by-zero or invalid for this result; and - errno = ERANGE where the overflow floating-point signal should be - raised. -*/ - -static Py_complex acos_special_values[7][7]; - -/*[clinic input] -cmath.acos -> Py_complex_protected - - z: Py_complex_protected - / - -Return the arc cosine of z. -[clinic start generated code]*/ - -static Py_complex -cmath_acos_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=40bd42853fd460ae input=bd6cbd78ae851927]*/ -{ - Py_complex s1, s2, r; - - SPECIAL_VALUE(z, acos_special_values); - - if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { - /* avoid unnecessary overflow for large arguments */ - r.real = atan2(fabs(z.imag), z.real); - /* split into cases to make sure that the branch cut has the - correct continuity on systems with unsigned zeros */ - if (z.real < 0.) { - r.imag = -copysign(log(hypot(z.real/2., z.imag/2.)) + - M_LN2*2., z.imag); - } else { - r.imag = copysign(log(hypot(z.real/2., z.imag/2.)) + - M_LN2*2., -z.imag); - } - } else { - s1.real = 1.-z.real; - s1.imag = -z.imag; - s1 = cmath_sqrt_impl(module, s1); - s2.real = 1.+z.real; - s2.imag = z.imag; - s2 = cmath_sqrt_impl(module, s2); - r.real = 2.*atan2(s1.real, s2.real); - r.imag = m_asinh(s2.real*s1.imag - s2.imag*s1.real); - } - errno = 0; - return r; -} - - -static Py_complex acosh_special_values[7][7]; - -/*[clinic input] -cmath.acosh = cmath.acos - -Return the inverse hyperbolic cosine of z. -[clinic start generated code]*/ - -static Py_complex -cmath_acosh_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=3e2454d4fcf404ca input=3f61bee7d703e53c]*/ -{ - Py_complex s1, s2, r; - - SPECIAL_VALUE(z, acosh_special_values); - - if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { - /* avoid unnecessary overflow for large arguments */ - r.real = log(hypot(z.real/2., z.imag/2.)) + M_LN2*2.; - r.imag = atan2(z.imag, z.real); - } else { - s1.real = z.real - 1.; - s1.imag = z.imag; - s1 = cmath_sqrt_impl(module, s1); - s2.real = z.real + 1.; - s2.imag = z.imag; - s2 = cmath_sqrt_impl(module, s2); - r.real = m_asinh(s1.real*s2.real + s1.imag*s2.imag); - r.imag = 2.*atan2(s1.imag, s2.real); - } - errno = 0; - return r; -} - -/*[clinic input] -cmath.asin = cmath.acos - -Return the arc sine of z. -[clinic start generated code]*/ - -static Py_complex -cmath_asin_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=3b264cd1b16bf4e1 input=be0bf0cfdd5239c5]*/ -{ - /* asin(z) = -i asinh(iz) */ - Py_complex s, r; - s.real = -z.imag; - s.imag = z.real; - s = cmath_asinh_impl(module, s); - r.real = s.imag; - r.imag = -s.real; - return r; -} - - -static Py_complex asinh_special_values[7][7]; - -/*[clinic input] -cmath.asinh = cmath.acos - -Return the inverse hyperbolic sine of z. -[clinic start generated code]*/ - -static Py_complex -cmath_asinh_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=733d8107841a7599 input=5c09448fcfc89a79]*/ -{ - Py_complex s1, s2, r; - - SPECIAL_VALUE(z, asinh_special_values); - - if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { - if (z.imag >= 0.) { - r.real = copysign(log(hypot(z.real/2., z.imag/2.)) + - M_LN2*2., z.real); - } else { - r.real = -copysign(log(hypot(z.real/2., z.imag/2.)) + - M_LN2*2., -z.real); - } - r.imag = atan2(z.imag, fabs(z.real)); - } else { - s1.real = 1.+z.imag; - s1.imag = -z.real; - s1 = cmath_sqrt_impl(module, s1); - s2.real = 1.-z.imag; - s2.imag = z.real; - s2 = cmath_sqrt_impl(module, s2); - r.real = m_asinh(s1.real*s2.imag-s2.real*s1.imag); - r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag); - } - errno = 0; - return r; -} - - -/*[clinic input] -cmath.atan = cmath.acos - -Return the arc tangent of z. -[clinic start generated code]*/ - -static Py_complex -cmath_atan_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=b6bfc497058acba4 input=3b21ff7d5eac632a]*/ -{ - /* atan(z) = -i atanh(iz) */ - Py_complex s, r; - s.real = -z.imag; - s.imag = z.real; - s = cmath_atanh_impl(module, s); - r.real = s.imag; - r.imag = -s.real; - return r; -} - -/* Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't follow - C99 for atan2(0., 0.). */ -static double -c_atan2(Py_complex z) -{ - if (Py_IS_NAN(z.real) || Py_IS_NAN(z.imag)) - return Py_NAN; - if (Py_IS_INFINITY(z.imag)) { - if (Py_IS_INFINITY(z.real)) { - if (copysign(1., z.real) == 1.) - /* atan2(+-inf, +inf) == +-pi/4 */ - return copysign(0.25*Py_MATH_PI, z.imag); - else - /* atan2(+-inf, -inf) == +-pi*3/4 */ - return copysign(0.75*Py_MATH_PI, z.imag); - } - /* atan2(+-inf, x) == +-pi/2 for finite x */ - return copysign(0.5*Py_MATH_PI, z.imag); - } - if (Py_IS_INFINITY(z.real) || z.imag == 0.) { - if (copysign(1., z.real) == 1.) - /* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */ - return copysign(0., z.imag); - else - /* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */ - return copysign(Py_MATH_PI, z.imag); - } - return atan2(z.imag, z.real); -} - - -static Py_complex atanh_special_values[7][7]; - -/*[clinic input] -cmath.atanh = cmath.acos - -Return the inverse hyperbolic tangent of z. -[clinic start generated code]*/ - -static Py_complex -cmath_atanh_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=e83355f93a989c9e input=2b3fdb82fb34487b]*/ -{ - Py_complex r; - double ay, h; - - SPECIAL_VALUE(z, atanh_special_values); - - /* Reduce to case where z.real >= 0., using atanh(z) = -atanh(-z). */ - if (z.real < 0.) { - return _Py_c_neg(cmath_atanh_impl(module, _Py_c_neg(z))); - } - - ay = fabs(z.imag); - if (z.real > CM_SQRT_LARGE_DOUBLE || ay > CM_SQRT_LARGE_DOUBLE) { - /* - if abs(z) is large then we use the approximation - atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign - of z.imag) - */ - h = hypot(z.real/2., z.imag/2.); /* safe from overflow */ - r.real = z.real/4./h/h; - /* the two negations in the next line cancel each other out - except when working with unsigned zeros: they're there to - ensure that the branch cut has the correct continuity on - systems that don't support signed zeros */ - r.imag = -copysign(Py_MATH_PI/2., -z.imag); - errno = 0; - } else if (z.real == 1. && ay < CM_SQRT_DBL_MIN) { - /* C99 standard says: atanh(1+/-0.) should be inf +/- 0i */ - if (ay == 0.) { - r.real = INF; - r.imag = z.imag; - errno = EDOM; - } else { - r.real = -log(sqrt(ay)/sqrt(hypot(ay, 2.))); - r.imag = copysign(atan2(2., -ay)/2, z.imag); - errno = 0; - } - } else { - r.real = m_log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.; - r.imag = -atan2(-2.*z.imag, (1-z.real)*(1+z.real) - ay*ay)/2.; - errno = 0; - } - return r; -} - - -/*[clinic input] -cmath.cos = cmath.acos - -Return the cosine of z. -[clinic start generated code]*/ - -static Py_complex -cmath_cos_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=fd64918d5b3186db input=6022e39b77127ac7]*/ -{ - /* cos(z) = cosh(iz) */ - Py_complex r; - r.real = -z.imag; - r.imag = z.real; - r = cmath_cosh_impl(module, r); - return r; -} - - -/* cosh(infinity + i*y) needs to be dealt with specially */ -static Py_complex cosh_special_values[7][7]; - -/*[clinic input] -cmath.cosh = cmath.acos - -Return the hyperbolic cosine of z. -[clinic start generated code]*/ - -static Py_complex -cmath_cosh_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=2e969047da601bdb input=d6b66339e9cc332b]*/ -{ - Py_complex r; - double x_minus_one; - - /* special treatment for cosh(+/-inf + iy) if y is not a NaN */ - if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { - if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) && - (z.imag != 0.)) { - if (z.real > 0) { - r.real = copysign(INF, cos(z.imag)); - r.imag = copysign(INF, sin(z.imag)); - } - else { - r.real = copysign(INF, cos(z.imag)); - r.imag = -copysign(INF, sin(z.imag)); - } - } - else { - r = cosh_special_values[special_type(z.real)] - [special_type(z.imag)]; - } - /* need to set errno = EDOM if y is +/- infinity and x is not - a NaN */ - if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real)) - errno = EDOM; - else - errno = 0; - return r; - } - - if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { - /* deal correctly with cases where cosh(z.real) overflows but - cosh(z) does not. */ - x_minus_one = z.real - copysign(1., z.real); - r.real = cos(z.imag) * cosh(x_minus_one) * Py_MATH_E; - r.imag = sin(z.imag) * sinh(x_minus_one) * Py_MATH_E; - } else { - r.real = cos(z.imag) * cosh(z.real); - r.imag = sin(z.imag) * sinh(z.real); - } - /* detect overflow, and set errno accordingly */ - if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) - errno = ERANGE; - else - errno = 0; - return r; -} - - -/* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for - finite y */ -static Py_complex exp_special_values[7][7]; - -/*[clinic input] -cmath.exp = cmath.acos - -Return the exponential value e**z. -[clinic start generated code]*/ - -static Py_complex -cmath_exp_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=edcec61fb9dfda6c input=8b9e6cf8a92174c3]*/ -{ - Py_complex r; - double l; - - if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { - if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) - && (z.imag != 0.)) { - if (z.real > 0) { - r.real = copysign(INF, cos(z.imag)); - r.imag = copysign(INF, sin(z.imag)); - } - else { - r.real = copysign(0., cos(z.imag)); - r.imag = copysign(0., sin(z.imag)); - } - } - else { - r = exp_special_values[special_type(z.real)] - [special_type(z.imag)]; - } - /* need to set errno = EDOM if y is +/- infinity and x is not - a NaN and not -infinity */ - if (Py_IS_INFINITY(z.imag) && - (Py_IS_FINITE(z.real) || - (Py_IS_INFINITY(z.real) && z.real > 0))) - errno = EDOM; - else - errno = 0; - return r; - } - - if (z.real > CM_LOG_LARGE_DOUBLE) { - l = exp(z.real-1.); - r.real = l*cos(z.imag)*Py_MATH_E; - r.imag = l*sin(z.imag)*Py_MATH_E; - } else { - l = exp(z.real); - r.real = l*cos(z.imag); - r.imag = l*sin(z.imag); - } - /* detect overflow, and set errno accordingly */ - if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) - errno = ERANGE; - else - errno = 0; - return r; -} - -static Py_complex log_special_values[7][7]; - -static Py_complex -c_log(Py_complex z) -{ - /* - The usual formula for the real part is log(hypot(z.real, z.imag)). - There are four situations where this formula is potentially - problematic: - - (1) the absolute value of z is subnormal. Then hypot is subnormal, - so has fewer than the usual number of bits of accuracy, hence may - have large relative error. This then gives a large absolute error - in the log. This can be solved by rescaling z by a suitable power - of 2. - - (2) the absolute value of z is greater than DBL_MAX (e.g. when both - z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX) - Again, rescaling solves this. - - (3) the absolute value of z is close to 1. In this case it's - difficult to achieve good accuracy, at least in part because a - change of 1ulp in the real or imaginary part of z can result in a - change of billions of ulps in the correctly rounded answer. - - (4) z = 0. The simplest thing to do here is to call the - floating-point log with an argument of 0, and let its behaviour - (returning -infinity, signaling a floating-point exception, setting - errno, or whatever) determine that of c_log. So the usual formula - is fine here. - - */ - - Py_complex r; - double ax, ay, am, an, h; - - SPECIAL_VALUE(z, log_special_values); - - ax = fabs(z.real); - ay = fabs(z.imag); - - if (ax > CM_LARGE_DOUBLE || ay > CM_LARGE_DOUBLE) { - r.real = log(hypot(ax/2., ay/2.)) + M_LN2; - } else if (ax < DBL_MIN && ay < DBL_MIN) { - if (ax > 0. || ay > 0.) { - /* catch cases where hypot(ax, ay) is subnormal */ - r.real = log(hypot(ldexp(ax, DBL_MANT_DIG), - ldexp(ay, DBL_MANT_DIG))) - DBL_MANT_DIG*M_LN2; - } - else { - /* log(+/-0. +/- 0i) */ - r.real = -INF; - r.imag = atan2(z.imag, z.real); - errno = EDOM; - return r; - } - } else { - h = hypot(ax, ay); - if (0.71 <= h && h <= 1.73) { - am = ax > ay ? ax : ay; /* max(ax, ay) */ - an = ax > ay ? ay : ax; /* min(ax, ay) */ - r.real = m_log1p((am-1)*(am+1)+an*an)/2.; - } else { - r.real = log(h); - } - } - r.imag = atan2(z.imag, z.real); - errno = 0; - return r; -} - - -/*[clinic input] -cmath.log10 = cmath.acos - -Return the base-10 logarithm of z. -[clinic start generated code]*/ - -static Py_complex -cmath_log10_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=2922779a7c38cbe1 input=cff5644f73c1519c]*/ -{ - Py_complex r; - int errno_save; - - r = c_log(z); - errno_save = errno; /* just in case the divisions affect errno */ - r.real = r.real / M_LN10; - r.imag = r.imag / M_LN10; - errno = errno_save; - return r; -} - - -/*[clinic input] -cmath.sin = cmath.acos - -Return the sine of z. -[clinic start generated code]*/ - -static Py_complex -cmath_sin_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=980370d2ff0bb5aa input=2d3519842a8b4b85]*/ -{ - /* sin(z) = -i sin(iz) */ - Py_complex s, r; - s.real = -z.imag; - s.imag = z.real; - s = cmath_sinh_impl(module, s); - r.real = s.imag; - r.imag = -s.real; - return r; -} - - -/* sinh(infinity + i*y) needs to be dealt with specially */ -static Py_complex sinh_special_values[7][7]; - -/*[clinic input] -cmath.sinh = cmath.acos - -Return the hyperbolic sine of z. -[clinic start generated code]*/ - -static Py_complex -cmath_sinh_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=38b0a6cce26f3536 input=d2d3fc8c1ddfd2dd]*/ -{ - Py_complex r; - double x_minus_one; - - /* special treatment for sinh(+/-inf + iy) if y is finite and - nonzero */ - if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { - if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) - && (z.imag != 0.)) { - if (z.real > 0) { - r.real = copysign(INF, cos(z.imag)); - r.imag = copysign(INF, sin(z.imag)); - } - else { - r.real = -copysign(INF, cos(z.imag)); - r.imag = copysign(INF, sin(z.imag)); - } - } - else { - r = sinh_special_values[special_type(z.real)] - [special_type(z.imag)]; - } - /* need to set errno = EDOM if y is +/- infinity and x is not - a NaN */ - if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real)) - errno = EDOM; - else - errno = 0; - return r; - } - - if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { - x_minus_one = z.real - copysign(1., z.real); - r.real = cos(z.imag) * sinh(x_minus_one) * Py_MATH_E; - r.imag = sin(z.imag) * cosh(x_minus_one) * Py_MATH_E; - } else { - r.real = cos(z.imag) * sinh(z.real); - r.imag = sin(z.imag) * cosh(z.real); - } - /* detect overflow, and set errno accordingly */ - if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) - errno = ERANGE; - else - errno = 0; - return r; -} - - -static Py_complex sqrt_special_values[7][7]; - -/*[clinic input] -cmath.sqrt = cmath.acos - -Return the square root of z. -[clinic start generated code]*/ - -static Py_complex -cmath_sqrt_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=b6507b3029c339fc input=7088b166fc9a58c7]*/ -{ - /* - Method: use symmetries to reduce to the case when x = z.real and y - = z.imag are nonnegative. Then the real part of the result is - given by - - s = sqrt((x + hypot(x, y))/2) - - and the imaginary part is - - d = (y/2)/s - - If either x or y is very large then there's a risk of overflow in - computation of the expression x + hypot(x, y). We can avoid this - by rewriting the formula for s as: - - s = 2*sqrt(x/8 + hypot(x/8, y/8)) - - This costs us two extra multiplications/divisions, but avoids the - overhead of checking for x and y large. - - If both x and y are subnormal then hypot(x, y) may also be - subnormal, so will lack full precision. We solve this by rescaling - x and y by a sufficiently large power of 2 to ensure that x and y - are normal. - */ - - - Py_complex r; - double s,d; - double ax, ay; - - SPECIAL_VALUE(z, sqrt_special_values); - - if (z.real == 0. && z.imag == 0.) { - r.real = 0.; - r.imag = z.imag; - return r; - } - - ax = fabs(z.real); - ay = fabs(z.imag); - - if (ax < DBL_MIN && ay < DBL_MIN && (ax > 0. || ay > 0.)) { - /* here we catch cases where hypot(ax, ay) is subnormal */ - ax = ldexp(ax, CM_SCALE_UP); - s = ldexp(sqrt(ax + hypot(ax, ldexp(ay, CM_SCALE_UP))), - CM_SCALE_DOWN); - } else { - ax /= 8.; - s = 2.*sqrt(ax + hypot(ax, ay/8.)); - } - d = ay/(2.*s); - - if (z.real >= 0.) { - r.real = s; - r.imag = copysign(d, z.imag); - } else { - r.real = d; - r.imag = copysign(s, z.imag); - } - errno = 0; - return r; -} - - -/*[clinic input] -cmath.tan = cmath.acos - -Return the tangent of z. -[clinic start generated code]*/ - -static Py_complex -cmath_tan_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=7c5f13158a72eb13 input=fc167e528767888e]*/ -{ - /* tan(z) = -i tanh(iz) */ - Py_complex s, r; - s.real = -z.imag; - s.imag = z.real; - s = cmath_tanh_impl(module, s); - r.real = s.imag; - r.imag = -s.real; - return r; -} - - -/* tanh(infinity + i*y) needs to be dealt with specially */ -static Py_complex tanh_special_values[7][7]; - -/*[clinic input] -cmath.tanh = cmath.acos - -Return the hyperbolic tangent of z. -[clinic start generated code]*/ - -static Py_complex -cmath_tanh_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=36d547ef7aca116c input=22f67f9dc6d29685]*/ -{ - /* Formula: - - tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) / - (1+tan(y)^2 tanh(x)^2) - - To avoid excessive roundoff error, 1-tanh(x)^2 is better computed - as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2 - by 4 exp(-2*x) instead, to avoid possible overflow in the - computation of cosh(x). - - */ - - Py_complex r; - double tx, ty, cx, txty, denom; - - /* special treatment for tanh(+/-inf + iy) if y is finite and - nonzero */ - if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { - if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) - && (z.imag != 0.)) { - if (z.real > 0) { - r.real = 1.0; - r.imag = copysign(0., - 2.*sin(z.imag)*cos(z.imag)); - } - else { - r.real = -1.0; - r.imag = copysign(0., - 2.*sin(z.imag)*cos(z.imag)); - } - } - else { - r = tanh_special_values[special_type(z.real)] - [special_type(z.imag)]; - } - /* need to set errno = EDOM if z.imag is +/-infinity and - z.real is finite */ - if (Py_IS_INFINITY(z.imag) && Py_IS_FINITE(z.real)) - errno = EDOM; - else - errno = 0; - return r; - } - - /* danger of overflow in 2.*z.imag !*/ - if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { - r.real = copysign(1., z.real); - r.imag = 4.*sin(z.imag)*cos(z.imag)*exp(-2.*fabs(z.real)); - } else { - tx = tanh(z.real); - ty = tan(z.imag); - cx = 1./cosh(z.real); - txty = tx*ty; - denom = 1. + txty*txty; - r.real = tx*(1.+ty*ty)/denom; - r.imag = ((ty/denom)*cx)*cx; - } - errno = 0; - return r; -} - - -/*[clinic input] -cmath.log - + +#if (FLT_RADIX != 2 && FLT_RADIX != 16) +#error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16" +#endif + +#ifndef M_LN2 +#define M_LN2 (0.6931471805599453094) /* natural log of 2 */ +#endif + +#ifndef M_LN10 +#define M_LN10 (2.302585092994045684) /* natural log of 10 */ +#endif + +/* + CM_LARGE_DOUBLE is used to avoid spurious overflow in the sqrt, log, + inverse trig and inverse hyperbolic trig functions. Its log is used in the + evaluation of exp, cos, cosh, sin, sinh, tan, and tanh to avoid unnecessary + overflow. + */ + +#define CM_LARGE_DOUBLE (DBL_MAX/4.) +#define CM_SQRT_LARGE_DOUBLE (sqrt(CM_LARGE_DOUBLE)) +#define CM_LOG_LARGE_DOUBLE (log(CM_LARGE_DOUBLE)) +#define CM_SQRT_DBL_MIN (sqrt(DBL_MIN)) + +/* + CM_SCALE_UP is an odd integer chosen such that multiplication by + 2**CM_SCALE_UP is sufficient to turn a subnormal into a normal. + CM_SCALE_DOWN is (-(CM_SCALE_UP+1)/2). These scalings are used to compute + square roots accurately when the real and imaginary parts of the argument + are subnormal. +*/ + +#if FLT_RADIX==2 +#define CM_SCALE_UP (2*(DBL_MANT_DIG/2) + 1) +#elif FLT_RADIX==16 +#define CM_SCALE_UP (4*DBL_MANT_DIG+1) +#endif +#define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2) + +/* Constants cmath.inf, cmath.infj, cmath.nan, cmath.nanj. + cmath.nan and cmath.nanj are defined only when either + PY_NO_SHORT_FLOAT_REPR is *not* defined (which should be + the most common situation on machines using an IEEE 754 + representation), or Py_NAN is defined. */ + +static double +m_inf(void) +{ +#ifndef PY_NO_SHORT_FLOAT_REPR + return _Py_dg_infinity(0); +#else + return Py_HUGE_VAL; +#endif +} + +static Py_complex +c_infj(void) +{ + Py_complex r; + r.real = 0.0; + r.imag = m_inf(); + return r; +} + +#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) + +static double +m_nan(void) +{ +#ifndef PY_NO_SHORT_FLOAT_REPR + return _Py_dg_stdnan(0); +#else + return Py_NAN; +#endif +} + +static Py_complex +c_nanj(void) +{ + Py_complex r; + r.real = 0.0; + r.imag = m_nan(); + return r; +} + +#endif + +/* forward declarations */ +static Py_complex cmath_asinh_impl(PyObject *, Py_complex); +static Py_complex cmath_atanh_impl(PyObject *, Py_complex); +static Py_complex cmath_cosh_impl(PyObject *, Py_complex); +static Py_complex cmath_sinh_impl(PyObject *, Py_complex); +static Py_complex cmath_sqrt_impl(PyObject *, Py_complex); +static Py_complex cmath_tanh_impl(PyObject *, Py_complex); +static PyObject * math_error(void); + +/* Code to deal with special values (infinities, NaNs, etc.). */ + +/* special_type takes a double and returns an integer code indicating + the type of the double as follows: +*/ + +enum special_types { + ST_NINF, /* 0, negative infinity */ + ST_NEG, /* 1, negative finite number (nonzero) */ + ST_NZERO, /* 2, -0. */ + ST_PZERO, /* 3, +0. */ + ST_POS, /* 4, positive finite number (nonzero) */ + ST_PINF, /* 5, positive infinity */ + ST_NAN /* 6, Not a Number */ +}; + +static enum special_types +special_type(double d) +{ + if (Py_IS_FINITE(d)) { + if (d != 0) { + if (copysign(1., d) == 1.) + return ST_POS; + else + return ST_NEG; + } + else { + if (copysign(1., d) == 1.) + return ST_PZERO; + else + return ST_NZERO; + } + } + if (Py_IS_NAN(d)) + return ST_NAN; + if (copysign(1., d) == 1.) + return ST_PINF; + else + return ST_NINF; +} + +#define SPECIAL_VALUE(z, table) \ + if (!Py_IS_FINITE((z).real) || !Py_IS_FINITE((z).imag)) { \ + errno = 0; \ + return table[special_type((z).real)] \ + [special_type((z).imag)]; \ + } + +#define P Py_MATH_PI +#define P14 0.25*Py_MATH_PI +#define P12 0.5*Py_MATH_PI +#define P34 0.75*Py_MATH_PI +#define INF Py_HUGE_VAL +#define N Py_NAN +#define U -9.5426319407711027e33 /* unlikely value, used as placeholder */ + +/* First, the C functions that do the real work. Each of the c_* + functions computes and returns the C99 Annex G recommended result + and also sets errno as follows: errno = 0 if no floating-point + exception is associated with the result; errno = EDOM if C99 Annex + G recommends raising divide-by-zero or invalid for this result; and + errno = ERANGE where the overflow floating-point signal should be + raised. +*/ + +static Py_complex acos_special_values[7][7]; + +/*[clinic input] +cmath.acos -> Py_complex_protected + + z: Py_complex_protected + / + +Return the arc cosine of z. +[clinic start generated code]*/ + +static Py_complex +cmath_acos_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=40bd42853fd460ae input=bd6cbd78ae851927]*/ +{ + Py_complex s1, s2, r; + + SPECIAL_VALUE(z, acos_special_values); + + if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { + /* avoid unnecessary overflow for large arguments */ + r.real = atan2(fabs(z.imag), z.real); + /* split into cases to make sure that the branch cut has the + correct continuity on systems with unsigned zeros */ + if (z.real < 0.) { + r.imag = -copysign(log(hypot(z.real/2., z.imag/2.)) + + M_LN2*2., z.imag); + } else { + r.imag = copysign(log(hypot(z.real/2., z.imag/2.)) + + M_LN2*2., -z.imag); + } + } else { + s1.real = 1.-z.real; + s1.imag = -z.imag; + s1 = cmath_sqrt_impl(module, s1); + s2.real = 1.+z.real; + s2.imag = z.imag; + s2 = cmath_sqrt_impl(module, s2); + r.real = 2.*atan2(s1.real, s2.real); + r.imag = m_asinh(s2.real*s1.imag - s2.imag*s1.real); + } + errno = 0; + return r; +} + + +static Py_complex acosh_special_values[7][7]; + +/*[clinic input] +cmath.acosh = cmath.acos + +Return the inverse hyperbolic cosine of z. +[clinic start generated code]*/ + +static Py_complex +cmath_acosh_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=3e2454d4fcf404ca input=3f61bee7d703e53c]*/ +{ + Py_complex s1, s2, r; + + SPECIAL_VALUE(z, acosh_special_values); + + if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { + /* avoid unnecessary overflow for large arguments */ + r.real = log(hypot(z.real/2., z.imag/2.)) + M_LN2*2.; + r.imag = atan2(z.imag, z.real); + } else { + s1.real = z.real - 1.; + s1.imag = z.imag; + s1 = cmath_sqrt_impl(module, s1); + s2.real = z.real + 1.; + s2.imag = z.imag; + s2 = cmath_sqrt_impl(module, s2); + r.real = m_asinh(s1.real*s2.real + s1.imag*s2.imag); + r.imag = 2.*atan2(s1.imag, s2.real); + } + errno = 0; + return r; +} + +/*[clinic input] +cmath.asin = cmath.acos + +Return the arc sine of z. +[clinic start generated code]*/ + +static Py_complex +cmath_asin_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=3b264cd1b16bf4e1 input=be0bf0cfdd5239c5]*/ +{ + /* asin(z) = -i asinh(iz) */ + Py_complex s, r; + s.real = -z.imag; + s.imag = z.real; + s = cmath_asinh_impl(module, s); + r.real = s.imag; + r.imag = -s.real; + return r; +} + + +static Py_complex asinh_special_values[7][7]; + +/*[clinic input] +cmath.asinh = cmath.acos + +Return the inverse hyperbolic sine of z. +[clinic start generated code]*/ + +static Py_complex +cmath_asinh_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=733d8107841a7599 input=5c09448fcfc89a79]*/ +{ + Py_complex s1, s2, r; + + SPECIAL_VALUE(z, asinh_special_values); + + if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) { + if (z.imag >= 0.) { + r.real = copysign(log(hypot(z.real/2., z.imag/2.)) + + M_LN2*2., z.real); + } else { + r.real = -copysign(log(hypot(z.real/2., z.imag/2.)) + + M_LN2*2., -z.real); + } + r.imag = atan2(z.imag, fabs(z.real)); + } else { + s1.real = 1.+z.imag; + s1.imag = -z.real; + s1 = cmath_sqrt_impl(module, s1); + s2.real = 1.-z.imag; + s2.imag = z.real; + s2 = cmath_sqrt_impl(module, s2); + r.real = m_asinh(s1.real*s2.imag-s2.real*s1.imag); + r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag); + } + errno = 0; + return r; +} + + +/*[clinic input] +cmath.atan = cmath.acos + +Return the arc tangent of z. +[clinic start generated code]*/ + +static Py_complex +cmath_atan_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=b6bfc497058acba4 input=3b21ff7d5eac632a]*/ +{ + /* atan(z) = -i atanh(iz) */ + Py_complex s, r; + s.real = -z.imag; + s.imag = z.real; + s = cmath_atanh_impl(module, s); + r.real = s.imag; + r.imag = -s.real; + return r; +} + +/* Windows screws up atan2 for inf and nan, and alpha Tru64 5.1 doesn't follow + C99 for atan2(0., 0.). */ +static double +c_atan2(Py_complex z) +{ + if (Py_IS_NAN(z.real) || Py_IS_NAN(z.imag)) + return Py_NAN; + if (Py_IS_INFINITY(z.imag)) { + if (Py_IS_INFINITY(z.real)) { + if (copysign(1., z.real) == 1.) + /* atan2(+-inf, +inf) == +-pi/4 */ + return copysign(0.25*Py_MATH_PI, z.imag); + else + /* atan2(+-inf, -inf) == +-pi*3/4 */ + return copysign(0.75*Py_MATH_PI, z.imag); + } + /* atan2(+-inf, x) == +-pi/2 for finite x */ + return copysign(0.5*Py_MATH_PI, z.imag); + } + if (Py_IS_INFINITY(z.real) || z.imag == 0.) { + if (copysign(1., z.real) == 1.) + /* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */ + return copysign(0., z.imag); + else + /* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */ + return copysign(Py_MATH_PI, z.imag); + } + return atan2(z.imag, z.real); +} + + +static Py_complex atanh_special_values[7][7]; + +/*[clinic input] +cmath.atanh = cmath.acos + +Return the inverse hyperbolic tangent of z. +[clinic start generated code]*/ + +static Py_complex +cmath_atanh_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=e83355f93a989c9e input=2b3fdb82fb34487b]*/ +{ + Py_complex r; + double ay, h; + + SPECIAL_VALUE(z, atanh_special_values); + + /* Reduce to case where z.real >= 0., using atanh(z) = -atanh(-z). */ + if (z.real < 0.) { + return _Py_c_neg(cmath_atanh_impl(module, _Py_c_neg(z))); + } + + ay = fabs(z.imag); + if (z.real > CM_SQRT_LARGE_DOUBLE || ay > CM_SQRT_LARGE_DOUBLE) { + /* + if abs(z) is large then we use the approximation + atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign + of z.imag) + */ + h = hypot(z.real/2., z.imag/2.); /* safe from overflow */ + r.real = z.real/4./h/h; + /* the two negations in the next line cancel each other out + except when working with unsigned zeros: they're there to + ensure that the branch cut has the correct continuity on + systems that don't support signed zeros */ + r.imag = -copysign(Py_MATH_PI/2., -z.imag); + errno = 0; + } else if (z.real == 1. && ay < CM_SQRT_DBL_MIN) { + /* C99 standard says: atanh(1+/-0.) should be inf +/- 0i */ + if (ay == 0.) { + r.real = INF; + r.imag = z.imag; + errno = EDOM; + } else { + r.real = -log(sqrt(ay)/sqrt(hypot(ay, 2.))); + r.imag = copysign(atan2(2., -ay)/2, z.imag); + errno = 0; + } + } else { + r.real = m_log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.; + r.imag = -atan2(-2.*z.imag, (1-z.real)*(1+z.real) - ay*ay)/2.; + errno = 0; + } + return r; +} + + +/*[clinic input] +cmath.cos = cmath.acos + +Return the cosine of z. +[clinic start generated code]*/ + +static Py_complex +cmath_cos_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=fd64918d5b3186db input=6022e39b77127ac7]*/ +{ + /* cos(z) = cosh(iz) */ + Py_complex r; + r.real = -z.imag; + r.imag = z.real; + r = cmath_cosh_impl(module, r); + return r; +} + + +/* cosh(infinity + i*y) needs to be dealt with specially */ +static Py_complex cosh_special_values[7][7]; + +/*[clinic input] +cmath.cosh = cmath.acos + +Return the hyperbolic cosine of z. +[clinic start generated code]*/ + +static Py_complex +cmath_cosh_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=2e969047da601bdb input=d6b66339e9cc332b]*/ +{ + Py_complex r; + double x_minus_one; + + /* special treatment for cosh(+/-inf + iy) if y is not a NaN */ + if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { + if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) && + (z.imag != 0.)) { + if (z.real > 0) { + r.real = copysign(INF, cos(z.imag)); + r.imag = copysign(INF, sin(z.imag)); + } + else { + r.real = copysign(INF, cos(z.imag)); + r.imag = -copysign(INF, sin(z.imag)); + } + } + else { + r = cosh_special_values[special_type(z.real)] + [special_type(z.imag)]; + } + /* need to set errno = EDOM if y is +/- infinity and x is not + a NaN */ + if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real)) + errno = EDOM; + else + errno = 0; + return r; + } + + if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { + /* deal correctly with cases where cosh(z.real) overflows but + cosh(z) does not. */ + x_minus_one = z.real - copysign(1., z.real); + r.real = cos(z.imag) * cosh(x_minus_one) * Py_MATH_E; + r.imag = sin(z.imag) * sinh(x_minus_one) * Py_MATH_E; + } else { + r.real = cos(z.imag) * cosh(z.real); + r.imag = sin(z.imag) * sinh(z.real); + } + /* detect overflow, and set errno accordingly */ + if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) + errno = ERANGE; + else + errno = 0; + return r; +} + + +/* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for + finite y */ +static Py_complex exp_special_values[7][7]; + +/*[clinic input] +cmath.exp = cmath.acos + +Return the exponential value e**z. +[clinic start generated code]*/ + +static Py_complex +cmath_exp_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=edcec61fb9dfda6c input=8b9e6cf8a92174c3]*/ +{ + Py_complex r; + double l; + + if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { + if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) + && (z.imag != 0.)) { + if (z.real > 0) { + r.real = copysign(INF, cos(z.imag)); + r.imag = copysign(INF, sin(z.imag)); + } + else { + r.real = copysign(0., cos(z.imag)); + r.imag = copysign(0., sin(z.imag)); + } + } + else { + r = exp_special_values[special_type(z.real)] + [special_type(z.imag)]; + } + /* need to set errno = EDOM if y is +/- infinity and x is not + a NaN and not -infinity */ + if (Py_IS_INFINITY(z.imag) && + (Py_IS_FINITE(z.real) || + (Py_IS_INFINITY(z.real) && z.real > 0))) + errno = EDOM; + else + errno = 0; + return r; + } + + if (z.real > CM_LOG_LARGE_DOUBLE) { + l = exp(z.real-1.); + r.real = l*cos(z.imag)*Py_MATH_E; + r.imag = l*sin(z.imag)*Py_MATH_E; + } else { + l = exp(z.real); + r.real = l*cos(z.imag); + r.imag = l*sin(z.imag); + } + /* detect overflow, and set errno accordingly */ + if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) + errno = ERANGE; + else + errno = 0; + return r; +} + +static Py_complex log_special_values[7][7]; + +static Py_complex +c_log(Py_complex z) +{ + /* + The usual formula for the real part is log(hypot(z.real, z.imag)). + There are four situations where this formula is potentially + problematic: + + (1) the absolute value of z is subnormal. Then hypot is subnormal, + so has fewer than the usual number of bits of accuracy, hence may + have large relative error. This then gives a large absolute error + in the log. This can be solved by rescaling z by a suitable power + of 2. + + (2) the absolute value of z is greater than DBL_MAX (e.g. when both + z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX) + Again, rescaling solves this. + + (3) the absolute value of z is close to 1. In this case it's + difficult to achieve good accuracy, at least in part because a + change of 1ulp in the real or imaginary part of z can result in a + change of billions of ulps in the correctly rounded answer. + + (4) z = 0. The simplest thing to do here is to call the + floating-point log with an argument of 0, and let its behaviour + (returning -infinity, signaling a floating-point exception, setting + errno, or whatever) determine that of c_log. So the usual formula + is fine here. + + */ + + Py_complex r; + double ax, ay, am, an, h; + + SPECIAL_VALUE(z, log_special_values); + + ax = fabs(z.real); + ay = fabs(z.imag); + + if (ax > CM_LARGE_DOUBLE || ay > CM_LARGE_DOUBLE) { + r.real = log(hypot(ax/2., ay/2.)) + M_LN2; + } else if (ax < DBL_MIN && ay < DBL_MIN) { + if (ax > 0. || ay > 0.) { + /* catch cases where hypot(ax, ay) is subnormal */ + r.real = log(hypot(ldexp(ax, DBL_MANT_DIG), + ldexp(ay, DBL_MANT_DIG))) - DBL_MANT_DIG*M_LN2; + } + else { + /* log(+/-0. +/- 0i) */ + r.real = -INF; + r.imag = atan2(z.imag, z.real); + errno = EDOM; + return r; + } + } else { + h = hypot(ax, ay); + if (0.71 <= h && h <= 1.73) { + am = ax > ay ? ax : ay; /* max(ax, ay) */ + an = ax > ay ? ay : ax; /* min(ax, ay) */ + r.real = m_log1p((am-1)*(am+1)+an*an)/2.; + } else { + r.real = log(h); + } + } + r.imag = atan2(z.imag, z.real); + errno = 0; + return r; +} + + +/*[clinic input] +cmath.log10 = cmath.acos + +Return the base-10 logarithm of z. +[clinic start generated code]*/ + +static Py_complex +cmath_log10_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=2922779a7c38cbe1 input=cff5644f73c1519c]*/ +{ + Py_complex r; + int errno_save; + + r = c_log(z); + errno_save = errno; /* just in case the divisions affect errno */ + r.real = r.real / M_LN10; + r.imag = r.imag / M_LN10; + errno = errno_save; + return r; +} + + +/*[clinic input] +cmath.sin = cmath.acos + +Return the sine of z. +[clinic start generated code]*/ + +static Py_complex +cmath_sin_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=980370d2ff0bb5aa input=2d3519842a8b4b85]*/ +{ + /* sin(z) = -i sin(iz) */ + Py_complex s, r; + s.real = -z.imag; + s.imag = z.real; + s = cmath_sinh_impl(module, s); + r.real = s.imag; + r.imag = -s.real; + return r; +} + + +/* sinh(infinity + i*y) needs to be dealt with specially */ +static Py_complex sinh_special_values[7][7]; + +/*[clinic input] +cmath.sinh = cmath.acos + +Return the hyperbolic sine of z. +[clinic start generated code]*/ + +static Py_complex +cmath_sinh_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=38b0a6cce26f3536 input=d2d3fc8c1ddfd2dd]*/ +{ + Py_complex r; + double x_minus_one; + + /* special treatment for sinh(+/-inf + iy) if y is finite and + nonzero */ + if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { + if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) + && (z.imag != 0.)) { + if (z.real > 0) { + r.real = copysign(INF, cos(z.imag)); + r.imag = copysign(INF, sin(z.imag)); + } + else { + r.real = -copysign(INF, cos(z.imag)); + r.imag = copysign(INF, sin(z.imag)); + } + } + else { + r = sinh_special_values[special_type(z.real)] + [special_type(z.imag)]; + } + /* need to set errno = EDOM if y is +/- infinity and x is not + a NaN */ + if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real)) + errno = EDOM; + else + errno = 0; + return r; + } + + if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { + x_minus_one = z.real - copysign(1., z.real); + r.real = cos(z.imag) * sinh(x_minus_one) * Py_MATH_E; + r.imag = sin(z.imag) * cosh(x_minus_one) * Py_MATH_E; + } else { + r.real = cos(z.imag) * sinh(z.real); + r.imag = sin(z.imag) * cosh(z.real); + } + /* detect overflow, and set errno accordingly */ + if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag)) + errno = ERANGE; + else + errno = 0; + return r; +} + + +static Py_complex sqrt_special_values[7][7]; + +/*[clinic input] +cmath.sqrt = cmath.acos + +Return the square root of z. +[clinic start generated code]*/ + +static Py_complex +cmath_sqrt_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=b6507b3029c339fc input=7088b166fc9a58c7]*/ +{ + /* + Method: use symmetries to reduce to the case when x = z.real and y + = z.imag are nonnegative. Then the real part of the result is + given by + + s = sqrt((x + hypot(x, y))/2) + + and the imaginary part is + + d = (y/2)/s + + If either x or y is very large then there's a risk of overflow in + computation of the expression x + hypot(x, y). We can avoid this + by rewriting the formula for s as: + + s = 2*sqrt(x/8 + hypot(x/8, y/8)) + + This costs us two extra multiplications/divisions, but avoids the + overhead of checking for x and y large. + + If both x and y are subnormal then hypot(x, y) may also be + subnormal, so will lack full precision. We solve this by rescaling + x and y by a sufficiently large power of 2 to ensure that x and y + are normal. + */ + + + Py_complex r; + double s,d; + double ax, ay; + + SPECIAL_VALUE(z, sqrt_special_values); + + if (z.real == 0. && z.imag == 0.) { + r.real = 0.; + r.imag = z.imag; + return r; + } + + ax = fabs(z.real); + ay = fabs(z.imag); + + if (ax < DBL_MIN && ay < DBL_MIN && (ax > 0. || ay > 0.)) { + /* here we catch cases where hypot(ax, ay) is subnormal */ + ax = ldexp(ax, CM_SCALE_UP); + s = ldexp(sqrt(ax + hypot(ax, ldexp(ay, CM_SCALE_UP))), + CM_SCALE_DOWN); + } else { + ax /= 8.; + s = 2.*sqrt(ax + hypot(ax, ay/8.)); + } + d = ay/(2.*s); + + if (z.real >= 0.) { + r.real = s; + r.imag = copysign(d, z.imag); + } else { + r.real = d; + r.imag = copysign(s, z.imag); + } + errno = 0; + return r; +} + + +/*[clinic input] +cmath.tan = cmath.acos + +Return the tangent of z. +[clinic start generated code]*/ + +static Py_complex +cmath_tan_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=7c5f13158a72eb13 input=fc167e528767888e]*/ +{ + /* tan(z) = -i tanh(iz) */ + Py_complex s, r; + s.real = -z.imag; + s.imag = z.real; + s = cmath_tanh_impl(module, s); + r.real = s.imag; + r.imag = -s.real; + return r; +} + + +/* tanh(infinity + i*y) needs to be dealt with specially */ +static Py_complex tanh_special_values[7][7]; + +/*[clinic input] +cmath.tanh = cmath.acos + +Return the hyperbolic tangent of z. +[clinic start generated code]*/ + +static Py_complex +cmath_tanh_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=36d547ef7aca116c input=22f67f9dc6d29685]*/ +{ + /* Formula: + + tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) / + (1+tan(y)^2 tanh(x)^2) + + To avoid excessive roundoff error, 1-tanh(x)^2 is better computed + as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2 + by 4 exp(-2*x) instead, to avoid possible overflow in the + computation of cosh(x). + + */ + + Py_complex r; + double tx, ty, cx, txty, denom; + + /* special treatment for tanh(+/-inf + iy) if y is finite and + nonzero */ + if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { + if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) + && (z.imag != 0.)) { + if (z.real > 0) { + r.real = 1.0; + r.imag = copysign(0., + 2.*sin(z.imag)*cos(z.imag)); + } + else { + r.real = -1.0; + r.imag = copysign(0., + 2.*sin(z.imag)*cos(z.imag)); + } + } + else { + r = tanh_special_values[special_type(z.real)] + [special_type(z.imag)]; + } + /* need to set errno = EDOM if z.imag is +/-infinity and + z.real is finite */ + if (Py_IS_INFINITY(z.imag) && Py_IS_FINITE(z.real)) + errno = EDOM; + else + errno = 0; + return r; + } + + /* danger of overflow in 2.*z.imag !*/ + if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) { + r.real = copysign(1., z.real); + r.imag = 4.*sin(z.imag)*cos(z.imag)*exp(-2.*fabs(z.real)); + } else { + tx = tanh(z.real); + ty = tan(z.imag); + cx = 1./cosh(z.real); + txty = tx*ty; + denom = 1. + txty*txty; + r.real = tx*(1.+ty*ty)/denom; + r.imag = ((ty/denom)*cx)*cx; + } + errno = 0; + return r; +} + + +/*[clinic input] +cmath.log + z as x: Py_complex base as y_obj: object = NULL - / - + / + log(z[, base]) -> the logarithm of z to the given base. - -If the base not specified, returns the natural logarithm (base e) of z. -[clinic start generated code]*/ - -static PyObject * -cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj) + +If the base not specified, returns the natural logarithm (base e) of z. +[clinic start generated code]*/ + +static PyObject * +cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj) /*[clinic end generated code: output=4effdb7d258e0d94 input=230ed3a71ecd000a]*/ -{ - Py_complex y; - - errno = 0; - x = c_log(x); - if (y_obj != NULL) { - y = PyComplex_AsCComplex(y_obj); - if (PyErr_Occurred()) { - return NULL; - } - y = c_log(y); - x = _Py_c_quot(x, y); - } - if (errno != 0) - return math_error(); - return PyComplex_FromCComplex(x); -} - - -/* And now the glue to make them available from Python: */ - -static PyObject * -math_error(void) -{ - if (errno == EDOM) - PyErr_SetString(PyExc_ValueError, "math domain error"); - else if (errno == ERANGE) - PyErr_SetString(PyExc_OverflowError, "math range error"); - else /* Unexpected math error */ - PyErr_SetFromErrno(PyExc_ValueError); - return NULL; -} - - -/*[clinic input] -cmath.phase - - z: Py_complex - / - -Return argument, also known as the phase angle, of a complex. -[clinic start generated code]*/ - -static PyObject * -cmath_phase_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=50725086a7bfd253 input=5cf75228ba94b69d]*/ -{ - double phi; - - errno = 0; - phi = c_atan2(z); - if (errno != 0) - return math_error(); - else - return PyFloat_FromDouble(phi); -} - -/*[clinic input] -cmath.polar - - z: Py_complex - / - -Convert a complex from rectangular coordinates to polar coordinates. - -r is the distance from 0 and phi the phase angle. -[clinic start generated code]*/ - -static PyObject * -cmath_polar_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=d0a8147c41dbb654 input=26c353574fd1a861]*/ -{ - double r, phi; - - errno = 0; - phi = c_atan2(z); /* should not cause any exception */ - r = _Py_c_abs(z); /* sets errno to ERANGE on overflow */ - if (errno != 0) - return math_error(); - else - return Py_BuildValue("dd", r, phi); -} - -/* - rect() isn't covered by the C99 standard, but it's not too hard to - figure out 'spirit of C99' rules for special value handing: - - rect(x, t) should behave like exp(log(x) + it) for positive-signed x - rect(x, t) should behave like -exp(log(-x) + it) for negative-signed x - rect(nan, t) should behave like exp(nan + it), except that rect(nan, 0) - gives nan +- i0 with the sign of the imaginary part unspecified. - -*/ - -static Py_complex rect_special_values[7][7]; - -/*[clinic input] -cmath.rect - - r: double - phi: double - / - -Convert from polar coordinates to rectangular coordinates. -[clinic start generated code]*/ - -static PyObject * -cmath_rect_impl(PyObject *module, double r, double phi) -/*[clinic end generated code: output=385a0690925df2d5 input=24c5646d147efd69]*/ -{ - Py_complex z; - errno = 0; - - /* deal with special values */ - if (!Py_IS_FINITE(r) || !Py_IS_FINITE(phi)) { - /* if r is +/-infinity and phi is finite but nonzero then - result is (+-INF +-INF i), but we need to compute cos(phi) - and sin(phi) to figure out the signs. */ - if (Py_IS_INFINITY(r) && (Py_IS_FINITE(phi) - && (phi != 0.))) { - if (r > 0) { - z.real = copysign(INF, cos(phi)); - z.imag = copysign(INF, sin(phi)); - } - else { - z.real = -copysign(INF, cos(phi)); - z.imag = -copysign(INF, sin(phi)); - } - } - else { - z = rect_special_values[special_type(r)] - [special_type(phi)]; - } - /* need to set errno = EDOM if r is a nonzero number and phi - is infinite */ - if (r != 0. && !Py_IS_NAN(r) && Py_IS_INFINITY(phi)) - errno = EDOM; - else - errno = 0; - } - else if (phi == 0.0) { - /* Workaround for buggy results with phi=-0.0 on OS X 10.8. See - bugs.python.org/issue18513. */ - z.real = r; - z.imag = r * phi; - errno = 0; - } - else { - z.real = r * cos(phi); - z.imag = r * sin(phi); - errno = 0; - } - - if (errno != 0) - return math_error(); - else - return PyComplex_FromCComplex(z); -} - -/*[clinic input] -cmath.isfinite = cmath.polar - -Return True if both the real and imaginary parts of z are finite, else False. -[clinic start generated code]*/ - -static PyObject * -cmath_isfinite_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=ac76611e2c774a36 input=848e7ee701895815]*/ -{ - return PyBool_FromLong(Py_IS_FINITE(z.real) && Py_IS_FINITE(z.imag)); -} - -/*[clinic input] -cmath.isnan = cmath.polar - -Checks if the real or imaginary part of z not a number (NaN). -[clinic start generated code]*/ - -static PyObject * -cmath_isnan_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=e7abf6e0b28beab7 input=71799f5d284c9baf]*/ -{ - return PyBool_FromLong(Py_IS_NAN(z.real) || Py_IS_NAN(z.imag)); -} - -/*[clinic input] -cmath.isinf = cmath.polar - -Checks if the real or imaginary part of z is infinite. -[clinic start generated code]*/ - -static PyObject * -cmath_isinf_impl(PyObject *module, Py_complex z) -/*[clinic end generated code: output=502a75a79c773469 input=363df155c7181329]*/ -{ - return PyBool_FromLong(Py_IS_INFINITY(z.real) || - Py_IS_INFINITY(z.imag)); -} - -/*[clinic input] -cmath.isclose -> bool - - a: Py_complex - b: Py_complex - * - rel_tol: double = 1e-09 - maximum difference for being considered "close", relative to the - magnitude of the input values - abs_tol: double = 0.0 - maximum difference for being considered "close", regardless of the - magnitude of the input values - -Determine whether two complex numbers are close in value. - -Return True if a is close in value to b, and False otherwise. - -For the values to be considered close, the difference between them must be -smaller than at least one of the tolerances. - --inf, inf and NaN behave similarly to the IEEE 754 Standard. That is, NaN is -not close to anything, even itself. inf and -inf are only close to themselves. -[clinic start generated code]*/ - -static int -cmath_isclose_impl(PyObject *module, Py_complex a, Py_complex b, - double rel_tol, double abs_tol) -/*[clinic end generated code: output=8a2486cc6e0014d1 input=df9636d7de1d4ac3]*/ -{ - double diff; - - /* sanity check on the inputs */ - if (rel_tol < 0.0 || abs_tol < 0.0 ) { - PyErr_SetString(PyExc_ValueError, - "tolerances must be non-negative"); - return -1; - } - - if ( (a.real == b.real) && (a.imag == b.imag) ) { - /* short circuit exact equality -- needed to catch two infinities of - the same sign. And perhaps speeds things up a bit sometimes. - */ - return 1; - } - - /* This catches the case of two infinities of opposite sign, or - one infinity and one finite number. Two infinities of opposite - sign would otherwise have an infinite relative tolerance. - Two infinities of the same sign are caught by the equality check - above. - */ - - if (Py_IS_INFINITY(a.real) || Py_IS_INFINITY(a.imag) || - Py_IS_INFINITY(b.real) || Py_IS_INFINITY(b.imag)) { - return 0; - } - - /* now do the regular computation - this is essentially the "weak" test from the Boost library - */ - - diff = _Py_c_abs(_Py_c_diff(a, b)); - - return (((diff <= rel_tol * _Py_c_abs(b)) || - (diff <= rel_tol * _Py_c_abs(a))) || - (diff <= abs_tol)); -} - -PyDoc_STRVAR(module_doc, +{ + Py_complex y; + + errno = 0; + x = c_log(x); + if (y_obj != NULL) { + y = PyComplex_AsCComplex(y_obj); + if (PyErr_Occurred()) { + return NULL; + } + y = c_log(y); + x = _Py_c_quot(x, y); + } + if (errno != 0) + return math_error(); + return PyComplex_FromCComplex(x); +} + + +/* And now the glue to make them available from Python: */ + +static PyObject * +math_error(void) +{ + if (errno == EDOM) + PyErr_SetString(PyExc_ValueError, "math domain error"); + else if (errno == ERANGE) + PyErr_SetString(PyExc_OverflowError, "math range error"); + else /* Unexpected math error */ + PyErr_SetFromErrno(PyExc_ValueError); + return NULL; +} + + +/*[clinic input] +cmath.phase + + z: Py_complex + / + +Return argument, also known as the phase angle, of a complex. +[clinic start generated code]*/ + +static PyObject * +cmath_phase_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=50725086a7bfd253 input=5cf75228ba94b69d]*/ +{ + double phi; + + errno = 0; + phi = c_atan2(z); + if (errno != 0) + return math_error(); + else + return PyFloat_FromDouble(phi); +} + +/*[clinic input] +cmath.polar + + z: Py_complex + / + +Convert a complex from rectangular coordinates to polar coordinates. + +r is the distance from 0 and phi the phase angle. +[clinic start generated code]*/ + +static PyObject * +cmath_polar_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=d0a8147c41dbb654 input=26c353574fd1a861]*/ +{ + double r, phi; + + errno = 0; + phi = c_atan2(z); /* should not cause any exception */ + r = _Py_c_abs(z); /* sets errno to ERANGE on overflow */ + if (errno != 0) + return math_error(); + else + return Py_BuildValue("dd", r, phi); +} + +/* + rect() isn't covered by the C99 standard, but it's not too hard to + figure out 'spirit of C99' rules for special value handing: + + rect(x, t) should behave like exp(log(x) + it) for positive-signed x + rect(x, t) should behave like -exp(log(-x) + it) for negative-signed x + rect(nan, t) should behave like exp(nan + it), except that rect(nan, 0) + gives nan +- i0 with the sign of the imaginary part unspecified. + +*/ + +static Py_complex rect_special_values[7][7]; + +/*[clinic input] +cmath.rect + + r: double + phi: double + / + +Convert from polar coordinates to rectangular coordinates. +[clinic start generated code]*/ + +static PyObject * +cmath_rect_impl(PyObject *module, double r, double phi) +/*[clinic end generated code: output=385a0690925df2d5 input=24c5646d147efd69]*/ +{ + Py_complex z; + errno = 0; + + /* deal with special values */ + if (!Py_IS_FINITE(r) || !Py_IS_FINITE(phi)) { + /* if r is +/-infinity and phi is finite but nonzero then + result is (+-INF +-INF i), but we need to compute cos(phi) + and sin(phi) to figure out the signs. */ + if (Py_IS_INFINITY(r) && (Py_IS_FINITE(phi) + && (phi != 0.))) { + if (r > 0) { + z.real = copysign(INF, cos(phi)); + z.imag = copysign(INF, sin(phi)); + } + else { + z.real = -copysign(INF, cos(phi)); + z.imag = -copysign(INF, sin(phi)); + } + } + else { + z = rect_special_values[special_type(r)] + [special_type(phi)]; + } + /* need to set errno = EDOM if r is a nonzero number and phi + is infinite */ + if (r != 0. && !Py_IS_NAN(r) && Py_IS_INFINITY(phi)) + errno = EDOM; + else + errno = 0; + } + else if (phi == 0.0) { + /* Workaround for buggy results with phi=-0.0 on OS X 10.8. See + bugs.python.org/issue18513. */ + z.real = r; + z.imag = r * phi; + errno = 0; + } + else { + z.real = r * cos(phi); + z.imag = r * sin(phi); + errno = 0; + } + + if (errno != 0) + return math_error(); + else + return PyComplex_FromCComplex(z); +} + +/*[clinic input] +cmath.isfinite = cmath.polar + +Return True if both the real and imaginary parts of z are finite, else False. +[clinic start generated code]*/ + +static PyObject * +cmath_isfinite_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=ac76611e2c774a36 input=848e7ee701895815]*/ +{ + return PyBool_FromLong(Py_IS_FINITE(z.real) && Py_IS_FINITE(z.imag)); +} + +/*[clinic input] +cmath.isnan = cmath.polar + +Checks if the real or imaginary part of z not a number (NaN). +[clinic start generated code]*/ + +static PyObject * +cmath_isnan_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=e7abf6e0b28beab7 input=71799f5d284c9baf]*/ +{ + return PyBool_FromLong(Py_IS_NAN(z.real) || Py_IS_NAN(z.imag)); +} + +/*[clinic input] +cmath.isinf = cmath.polar + +Checks if the real or imaginary part of z is infinite. +[clinic start generated code]*/ + +static PyObject * +cmath_isinf_impl(PyObject *module, Py_complex z) +/*[clinic end generated code: output=502a75a79c773469 input=363df155c7181329]*/ +{ + return PyBool_FromLong(Py_IS_INFINITY(z.real) || + Py_IS_INFINITY(z.imag)); +} + +/*[clinic input] +cmath.isclose -> bool + + a: Py_complex + b: Py_complex + * + rel_tol: double = 1e-09 + maximum difference for being considered "close", relative to the + magnitude of the input values + abs_tol: double = 0.0 + maximum difference for being considered "close", regardless of the + magnitude of the input values + +Determine whether two complex numbers are close in value. + +Return True if a is close in value to b, and False otherwise. + +For the values to be considered close, the difference between them must be +smaller than at least one of the tolerances. + +-inf, inf and NaN behave similarly to the IEEE 754 Standard. That is, NaN is +not close to anything, even itself. inf and -inf are only close to themselves. +[clinic start generated code]*/ + +static int +cmath_isclose_impl(PyObject *module, Py_complex a, Py_complex b, + double rel_tol, double abs_tol) +/*[clinic end generated code: output=8a2486cc6e0014d1 input=df9636d7de1d4ac3]*/ +{ + double diff; + + /* sanity check on the inputs */ + if (rel_tol < 0.0 || abs_tol < 0.0 ) { + PyErr_SetString(PyExc_ValueError, + "tolerances must be non-negative"); + return -1; + } + + if ( (a.real == b.real) && (a.imag == b.imag) ) { + /* short circuit exact equality -- needed to catch two infinities of + the same sign. And perhaps speeds things up a bit sometimes. + */ + return 1; + } + + /* This catches the case of two infinities of opposite sign, or + one infinity and one finite number. Two infinities of opposite + sign would otherwise have an infinite relative tolerance. + Two infinities of the same sign are caught by the equality check + above. + */ + + if (Py_IS_INFINITY(a.real) || Py_IS_INFINITY(a.imag) || + Py_IS_INFINITY(b.real) || Py_IS_INFINITY(b.imag)) { + return 0; + } + + /* now do the regular computation + this is essentially the "weak" test from the Boost library + */ + + diff = _Py_c_abs(_Py_c_diff(a, b)); + + return (((diff <= rel_tol * _Py_c_abs(b)) || + (diff <= rel_tol * _Py_c_abs(a))) || + (diff <= abs_tol)); +} + +PyDoc_STRVAR(module_doc, "This module provides access to mathematical functions for complex\n" "numbers."); - -static PyMethodDef cmath_methods[] = { - CMATH_ACOS_METHODDEF - CMATH_ACOSH_METHODDEF - CMATH_ASIN_METHODDEF - CMATH_ASINH_METHODDEF - CMATH_ATAN_METHODDEF - CMATH_ATANH_METHODDEF - CMATH_COS_METHODDEF - CMATH_COSH_METHODDEF - CMATH_EXP_METHODDEF - CMATH_ISCLOSE_METHODDEF - CMATH_ISFINITE_METHODDEF - CMATH_ISINF_METHODDEF - CMATH_ISNAN_METHODDEF - CMATH_LOG_METHODDEF - CMATH_LOG10_METHODDEF - CMATH_PHASE_METHODDEF - CMATH_POLAR_METHODDEF - CMATH_RECT_METHODDEF - CMATH_SIN_METHODDEF - CMATH_SINH_METHODDEF - CMATH_SQRT_METHODDEF - CMATH_TAN_METHODDEF - CMATH_TANH_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -static struct PyModuleDef cmathmodule = { - PyModuleDef_HEAD_INIT, - "cmath", - module_doc, - -1, - cmath_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_cmath(void) -{ - PyObject *m; - - m = PyModule_Create(&cmathmodule); - if (m == NULL) - return NULL; - - PyModule_AddObject(m, "pi", - PyFloat_FromDouble(Py_MATH_PI)); - PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); - PyModule_AddObject(m, "tau", PyFloat_FromDouble(Py_MATH_TAU)); /* 2pi */ - PyModule_AddObject(m, "inf", PyFloat_FromDouble(m_inf())); - PyModule_AddObject(m, "infj", PyComplex_FromCComplex(c_infj())); -#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) - PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); - PyModule_AddObject(m, "nanj", PyComplex_FromCComplex(c_nanj())); -#endif - - /* initialize special value tables */ - -#define INIT_SPECIAL_VALUES(NAME, BODY) { Py_complex* p = (Py_complex*)NAME; BODY } -#define C(REAL, IMAG) p->real = REAL; p->imag = IMAG; ++p; - - INIT_SPECIAL_VALUES(acos_special_values, { - C(P34,INF) C(P,INF) C(P,INF) C(P,-INF) C(P,-INF) C(P34,-INF) C(N,INF) - C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N) - C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N) - C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N) - C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N) - C(P14,INF) C(0.,INF) C(0.,INF) C(0.,-INF) C(0.,-INF) C(P14,-INF) C(N,INF) - C(N,INF) C(N,N) C(N,N) C(N,N) C(N,N) C(N,-INF) C(N,N) - }) - - INIT_SPECIAL_VALUES(acosh_special_values, { - C(INF,-P34) C(INF,-P) C(INF,-P) C(INF,P) C(INF,P) C(INF,P34) C(INF,N) - C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) - C(INF,-P12) C(U,U) C(0.,-P12) C(0.,P12) C(U,U) C(INF,P12) C(N,N) - C(INF,-P12) C(U,U) C(0.,-P12) C(0.,P12) C(U,U) C(INF,P12) C(N,N) - C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) - C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N) - C(INF,N) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,N) C(N,N) - }) - - INIT_SPECIAL_VALUES(asinh_special_values, { - C(-INF,-P14) C(-INF,-0.) C(-INF,-0.) C(-INF,0.) C(-INF,0.) C(-INF,P14) C(-INF,N) - C(-INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(-INF,P12) C(N,N) - C(-INF,-P12) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(-INF,P12) C(N,N) - C(INF,-P12) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,P12) C(N,N) - C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) - C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N) - C(INF,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(INF,N) C(N,N) - }) - - INIT_SPECIAL_VALUES(atanh_special_values, { - C(-0.,-P12) C(-0.,-P12) C(-0.,-P12) C(-0.,P12) C(-0.,P12) C(-0.,P12) C(-0.,N) - C(-0.,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(-0.,P12) C(N,N) - C(-0.,-P12) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(-0.,P12) C(-0.,N) - C(0.,-P12) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,P12) C(0.,N) - C(0.,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(0.,P12) C(N,N) - C(0.,-P12) C(0.,-P12) C(0.,-P12) C(0.,P12) C(0.,P12) C(0.,P12) C(0.,N) - C(0.,-P12) C(N,N) C(N,N) C(N,N) C(N,N) C(0.,P12) C(N,N) - }) - - INIT_SPECIAL_VALUES(cosh_special_values, { - C(INF,N) C(U,U) C(INF,0.) C(INF,-0.) C(U,U) C(INF,N) C(INF,N) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(N,0.) C(U,U) C(1.,0.) C(1.,-0.) C(U,U) C(N,0.) C(N,0.) - C(N,0.) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,0.) C(N,0.) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) - C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N) - }) - - INIT_SPECIAL_VALUES(exp_special_values, { - C(0.,0.) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,0.) C(0.,0.) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(N,N) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,N) C(N,N) - C(N,N) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,N) C(N,N) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) - C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N) - }) - - INIT_SPECIAL_VALUES(log_special_values, { - C(INF,-P34) C(INF,-P) C(INF,-P) C(INF,P) C(INF,P) C(INF,P34) C(INF,N) - C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) - C(INF,-P12) C(U,U) C(-INF,-P) C(-INF,P) C(U,U) C(INF,P12) C(N,N) - C(INF,-P12) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,P12) C(N,N) - C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) - C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N) - C(INF,N) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,N) C(N,N) - }) - - INIT_SPECIAL_VALUES(sinh_special_values, { - C(INF,N) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,N) C(INF,N) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(0.,N) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(0.,N) C(0.,N) - C(0.,N) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,N) C(0.,N) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) - C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N) - }) - - INIT_SPECIAL_VALUES(sqrt_special_values, { - C(INF,-INF) C(0.,-INF) C(0.,-INF) C(0.,INF) C(0.,INF) C(INF,INF) C(N,INF) - C(INF,-INF) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,INF) C(N,N) - C(INF,-INF) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,INF) C(N,N) - C(INF,-INF) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,INF) C(N,N) - C(INF,-INF) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,INF) C(N,N) - C(INF,-INF) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,INF) C(INF,N) - C(INF,-INF) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,INF) C(N,N) - }) - - INIT_SPECIAL_VALUES(tanh_special_values, { - C(-1.,0.) C(U,U) C(-1.,-0.) C(-1.,0.) C(U,U) C(-1.,0.) C(-1.,0.) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(N,N) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(N,N) C(N,N) - C(N,N) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(N,N) C(N,N) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(1.,0.) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(1.,0.) C(1.,0.) - C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N) - }) - - INIT_SPECIAL_VALUES(rect_special_values, { - C(INF,N) C(U,U) C(-INF,0.) C(-INF,-0.) C(U,U) C(INF,N) C(INF,N) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(0.,0.) C(U,U) C(-0.,0.) C(-0.,-0.) C(U,U) C(0.,0.) C(0.,0.) - C(0.,0.) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,0.) C(0.,0.) - C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) - C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) - C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N) - }) - return m; -} + +static PyMethodDef cmath_methods[] = { + CMATH_ACOS_METHODDEF + CMATH_ACOSH_METHODDEF + CMATH_ASIN_METHODDEF + CMATH_ASINH_METHODDEF + CMATH_ATAN_METHODDEF + CMATH_ATANH_METHODDEF + CMATH_COS_METHODDEF + CMATH_COSH_METHODDEF + CMATH_EXP_METHODDEF + CMATH_ISCLOSE_METHODDEF + CMATH_ISFINITE_METHODDEF + CMATH_ISINF_METHODDEF + CMATH_ISNAN_METHODDEF + CMATH_LOG_METHODDEF + CMATH_LOG10_METHODDEF + CMATH_PHASE_METHODDEF + CMATH_POLAR_METHODDEF + CMATH_RECT_METHODDEF + CMATH_SIN_METHODDEF + CMATH_SINH_METHODDEF + CMATH_SQRT_METHODDEF + CMATH_TAN_METHODDEF + CMATH_TANH_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef cmathmodule = { + PyModuleDef_HEAD_INIT, + "cmath", + module_doc, + -1, + cmath_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_cmath(void) +{ + PyObject *m; + + m = PyModule_Create(&cmathmodule); + if (m == NULL) + return NULL; + + PyModule_AddObject(m, "pi", + PyFloat_FromDouble(Py_MATH_PI)); + PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); + PyModule_AddObject(m, "tau", PyFloat_FromDouble(Py_MATH_TAU)); /* 2pi */ + PyModule_AddObject(m, "inf", PyFloat_FromDouble(m_inf())); + PyModule_AddObject(m, "infj", PyComplex_FromCComplex(c_infj())); +#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) + PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); + PyModule_AddObject(m, "nanj", PyComplex_FromCComplex(c_nanj())); +#endif + + /* initialize special value tables */ + +#define INIT_SPECIAL_VALUES(NAME, BODY) { Py_complex* p = (Py_complex*)NAME; BODY } +#define C(REAL, IMAG) p->real = REAL; p->imag = IMAG; ++p; + + INIT_SPECIAL_VALUES(acos_special_values, { + C(P34,INF) C(P,INF) C(P,INF) C(P,-INF) C(P,-INF) C(P34,-INF) C(N,INF) + C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N) + C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N) + C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N) + C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N) + C(P14,INF) C(0.,INF) C(0.,INF) C(0.,-INF) C(0.,-INF) C(P14,-INF) C(N,INF) + C(N,INF) C(N,N) C(N,N) C(N,N) C(N,N) C(N,-INF) C(N,N) + }) + + INIT_SPECIAL_VALUES(acosh_special_values, { + C(INF,-P34) C(INF,-P) C(INF,-P) C(INF,P) C(INF,P) C(INF,P34) C(INF,N) + C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) + C(INF,-P12) C(U,U) C(0.,-P12) C(0.,P12) C(U,U) C(INF,P12) C(N,N) + C(INF,-P12) C(U,U) C(0.,-P12) C(0.,P12) C(U,U) C(INF,P12) C(N,N) + C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) + C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N) + C(INF,N) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,N) C(N,N) + }) + + INIT_SPECIAL_VALUES(asinh_special_values, { + C(-INF,-P14) C(-INF,-0.) C(-INF,-0.) C(-INF,0.) C(-INF,0.) C(-INF,P14) C(-INF,N) + C(-INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(-INF,P12) C(N,N) + C(-INF,-P12) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(-INF,P12) C(N,N) + C(INF,-P12) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,P12) C(N,N) + C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) + C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N) + C(INF,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(INF,N) C(N,N) + }) + + INIT_SPECIAL_VALUES(atanh_special_values, { + C(-0.,-P12) C(-0.,-P12) C(-0.,-P12) C(-0.,P12) C(-0.,P12) C(-0.,P12) C(-0.,N) + C(-0.,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(-0.,P12) C(N,N) + C(-0.,-P12) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(-0.,P12) C(-0.,N) + C(0.,-P12) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,P12) C(0.,N) + C(0.,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(0.,P12) C(N,N) + C(0.,-P12) C(0.,-P12) C(0.,-P12) C(0.,P12) C(0.,P12) C(0.,P12) C(0.,N) + C(0.,-P12) C(N,N) C(N,N) C(N,N) C(N,N) C(0.,P12) C(N,N) + }) + + INIT_SPECIAL_VALUES(cosh_special_values, { + C(INF,N) C(U,U) C(INF,0.) C(INF,-0.) C(U,U) C(INF,N) C(INF,N) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(N,0.) C(U,U) C(1.,0.) C(1.,-0.) C(U,U) C(N,0.) C(N,0.) + C(N,0.) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,0.) C(N,0.) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) + C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N) + }) + + INIT_SPECIAL_VALUES(exp_special_values, { + C(0.,0.) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,0.) C(0.,0.) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(N,N) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,N) C(N,N) + C(N,N) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(N,N) C(N,N) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) + C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N) + }) + + INIT_SPECIAL_VALUES(log_special_values, { + C(INF,-P34) C(INF,-P) C(INF,-P) C(INF,P) C(INF,P) C(INF,P34) C(INF,N) + C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) + C(INF,-P12) C(U,U) C(-INF,-P) C(-INF,P) C(U,U) C(INF,P12) C(N,N) + C(INF,-P12) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,P12) C(N,N) + C(INF,-P12) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,P12) C(N,N) + C(INF,-P14) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,P14) C(INF,N) + C(INF,N) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,N) C(N,N) + }) + + INIT_SPECIAL_VALUES(sinh_special_values, { + C(INF,N) C(U,U) C(-INF,-0.) C(-INF,0.) C(U,U) C(INF,N) C(INF,N) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(0.,N) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(0.,N) C(0.,N) + C(0.,N) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,N) C(0.,N) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) + C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N) + }) + + INIT_SPECIAL_VALUES(sqrt_special_values, { + C(INF,-INF) C(0.,-INF) C(0.,-INF) C(0.,INF) C(0.,INF) C(INF,INF) C(N,INF) + C(INF,-INF) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,INF) C(N,N) + C(INF,-INF) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,INF) C(N,N) + C(INF,-INF) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(INF,INF) C(N,N) + C(INF,-INF) C(U,U) C(U,U) C(U,U) C(U,U) C(INF,INF) C(N,N) + C(INF,-INF) C(INF,-0.) C(INF,-0.) C(INF,0.) C(INF,0.) C(INF,INF) C(INF,N) + C(INF,-INF) C(N,N) C(N,N) C(N,N) C(N,N) C(INF,INF) C(N,N) + }) + + INIT_SPECIAL_VALUES(tanh_special_values, { + C(-1.,0.) C(U,U) C(-1.,-0.) C(-1.,0.) C(U,U) C(-1.,0.) C(-1.,0.) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(N,N) C(U,U) C(-0.,-0.) C(-0.,0.) C(U,U) C(N,N) C(N,N) + C(N,N) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(N,N) C(N,N) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(1.,0.) C(U,U) C(1.,-0.) C(1.,0.) C(U,U) C(1.,0.) C(1.,0.) + C(N,N) C(N,N) C(N,-0.) C(N,0.) C(N,N) C(N,N) C(N,N) + }) + + INIT_SPECIAL_VALUES(rect_special_values, { + C(INF,N) C(U,U) C(-INF,0.) C(-INF,-0.) C(U,U) C(INF,N) C(INF,N) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(0.,0.) C(U,U) C(-0.,0.) C(-0.,-0.) C(U,U) C(0.,0.) C(0.,0.) + C(0.,0.) C(U,U) C(0.,-0.) C(0.,0.) C(U,U) C(0.,0.) C(0.,0.) + C(N,N) C(U,U) C(U,U) C(U,U) C(U,U) C(N,N) C(N,N) + C(INF,N) C(U,U) C(INF,-0.) C(INF,0.) C(U,U) C(INF,N) C(INF,N) + C(N,N) C(N,N) C(N,0.) C(N,0.) C(N,N) C(N,N) C(N,N) + }) + return m; +} diff --git a/contrib/tools/python3/src/Modules/config.c b/contrib/tools/python3/src/Modules/config.c index 2128f544e58..996a499de9a 100644 --- a/contrib/tools/python3/src/Modules/config.c +++ b/contrib/tools/python3/src/Modules/config.c @@ -1,313 +1,313 @@ -/* -*- C -*- *********************************************** -Copyright (c) 2000, BeOpen.com. -Copyright (c) 1995-2000, Corporation for National Research Initiatives. -Copyright (c) 1990-1995, Stichting Mathematisch Centrum. -All rights reserved. - -See the file "Misc/COPYRIGHT" for information on usage and -redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. -******************************************************************/ - -/* Module configuration */ - -/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */ - -/* This file contains the table of built-in modules. - See create_builtin() in import.c. */ - -#include "Python.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -extern PyObject* PyInit__abc(void); // _abc -extern PyObject* PyInit__asyncio(void); // _asyncio -extern PyObject* PyInit__bisect(void); // _bisect -extern PyObject* PyInit__blake2(void); // _blake2 -extern PyObject* PyInit__bz2(void); // _bz2 -extern PyObject* PyInit__codecs(void); // _codecs -extern PyObject* PyInit__codecs_cn(void); // _codecs_cn -extern PyObject* PyInit__codecs_hk(void); // _codecs_hk -extern PyObject* PyInit__codecs_iso2022(void); // _codecs_iso2022 -extern PyObject* PyInit__codecs_jp(void); // _codecs_jp -extern PyObject* PyInit__codecs_kr(void); // _codecs_kr -extern PyObject* PyInit__codecs_tw(void); // _codecs_tw -extern PyObject* PyInit__collections(void); // _collections -extern PyObject* PyInit__contextvars(void); // _contextvars +/* -*- C -*- *********************************************** +Copyright (c) 2000, BeOpen.com. +Copyright (c) 1995-2000, Corporation for National Research Initiatives. +Copyright (c) 1990-1995, Stichting Mathematisch Centrum. +All rights reserved. + +See the file "Misc/COPYRIGHT" for information on usage and +redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. +******************************************************************/ + +/* Module configuration */ + +/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */ + +/* This file contains the table of built-in modules. + See create_builtin() in import.c. */ + +#include "Python.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +extern PyObject* PyInit__abc(void); // _abc +extern PyObject* PyInit__asyncio(void); // _asyncio +extern PyObject* PyInit__bisect(void); // _bisect +extern PyObject* PyInit__blake2(void); // _blake2 +extern PyObject* PyInit__bz2(void); // _bz2 +extern PyObject* PyInit__codecs(void); // _codecs +extern PyObject* PyInit__codecs_cn(void); // _codecs_cn +extern PyObject* PyInit__codecs_hk(void); // _codecs_hk +extern PyObject* PyInit__codecs_iso2022(void); // _codecs_iso2022 +extern PyObject* PyInit__codecs_jp(void); // _codecs_jp +extern PyObject* PyInit__codecs_kr(void); // _codecs_kr +extern PyObject* PyInit__codecs_tw(void); // _codecs_tw +extern PyObject* PyInit__collections(void); // _collections +extern PyObject* PyInit__contextvars(void); // _contextvars #if !defined(_MSC_VER) extern PyObject* PyInit__crypt(void); // _crypt #endif -extern PyObject* PyInit__csv(void); // _csv -extern PyObject* PyInit__ctypes(void); // _ctypes -extern PyObject* PyInit__datetime(void); // _datetime -extern PyObject* PyInit__decimal(void); // _decimal -extern PyObject* PyInit__elementtree(void); // _elementtree -extern PyObject* PyInit__functools(void); // _functools -extern PyObject* PyInit__hashlib(void); // _hashlib -extern PyObject* PyInit__heapq(void); // _heapq -extern PyObject* PyInit__imp(void); // _imp -extern PyObject* PyInit__io(void); // _io -extern PyObject* PyInit__json(void); // _json -extern PyObject* PyInit__locale(void); // _locale -extern PyObject* PyInit__lsprof(void); // _lsprof -extern PyObject* PyInit__lzma(void); // _lzma -extern PyObject* PyInit__md5(void); // _md5 -extern PyObject* PyInit__multibytecodec(void); // _multibytecodec -extern PyObject* PyInit__multiprocessing(void); // _multiprocessing -extern PyObject* PyInit__opcode(void); // _opcode -extern PyObject* PyInit__operator(void); // _operator +extern PyObject* PyInit__csv(void); // _csv +extern PyObject* PyInit__ctypes(void); // _ctypes +extern PyObject* PyInit__datetime(void); // _datetime +extern PyObject* PyInit__decimal(void); // _decimal +extern PyObject* PyInit__elementtree(void); // _elementtree +extern PyObject* PyInit__functools(void); // _functools +extern PyObject* PyInit__hashlib(void); // _hashlib +extern PyObject* PyInit__heapq(void); // _heapq +extern PyObject* PyInit__imp(void); // _imp +extern PyObject* PyInit__io(void); // _io +extern PyObject* PyInit__json(void); // _json +extern PyObject* PyInit__locale(void); // _locale +extern PyObject* PyInit__lsprof(void); // _lsprof +extern PyObject* PyInit__lzma(void); // _lzma +extern PyObject* PyInit__md5(void); // _md5 +extern PyObject* PyInit__multibytecodec(void); // _multibytecodec +extern PyObject* PyInit__multiprocessing(void); // _multiprocessing +extern PyObject* PyInit__opcode(void); // _opcode +extern PyObject* PyInit__operator(void); // _operator extern PyObject* PyInit__peg_parser(void); // _peg_parser -extern PyObject* PyInit__pickle(void); // _pickle +extern PyObject* PyInit__pickle(void); // _pickle extern PyObject* PyInit__posixshmem(void); // _posixshmem -#if !defined(_MSC_VER) -extern PyObject* PyInit__posixsubprocess(void); // _posixsubprocess -#endif -extern PyObject* PyInit__queue(void); // _queue -extern PyObject* PyInit__random(void); // _random -extern PyObject* PyInit__sha1(void); // _sha1 -extern PyObject* PyInit__sha256(void); // _sha256 -extern PyObject* PyInit__sha3(void); // _sha3 -extern PyObject* PyInit__sha512(void); // _sha512 -extern PyObject* PyInit__signal(void); // _signal -extern PyObject* PyInit__socket(void); // _socket -extern PyObject* PyInit__sre(void); // _sre -extern PyObject* PyInit__ssl(void); // _ssl -extern PyObject* PyInit__stat(void); // _stat +#if !defined(_MSC_VER) +extern PyObject* PyInit__posixsubprocess(void); // _posixsubprocess +#endif +extern PyObject* PyInit__queue(void); // _queue +extern PyObject* PyInit__random(void); // _random +extern PyObject* PyInit__sha1(void); // _sha1 +extern PyObject* PyInit__sha256(void); // _sha256 +extern PyObject* PyInit__sha3(void); // _sha3 +extern PyObject* PyInit__sha512(void); // _sha512 +extern PyObject* PyInit__signal(void); // _signal +extern PyObject* PyInit__socket(void); // _socket +extern PyObject* PyInit__sre(void); // _sre +extern PyObject* PyInit__ssl(void); // _ssl +extern PyObject* PyInit__stat(void); // _stat extern PyObject* PyInit__statistics(void); // _statistics -extern PyObject* PyInit__string(void); // _string -extern PyObject* PyInit__struct(void); // _struct -extern PyObject* PyInit__symtable(void); // _symtable -extern PyObject* PyInit__thread(void); // _thread -extern PyObject* PyInit__tracemalloc(void); // _tracemalloc -extern PyObject* PyInit__weakref(void); // _weakref +extern PyObject* PyInit__string(void); // _string +extern PyObject* PyInit__struct(void); // _struct +extern PyObject* PyInit__symtable(void); // _symtable +extern PyObject* PyInit__thread(void); // _thread +extern PyObject* PyInit__tracemalloc(void); // _tracemalloc +extern PyObject* PyInit__weakref(void); // _weakref extern PyObject* PyInit__xxsubinterpreters(void); // _xxsubinterpreters -extern PyObject* PyInit__xxtestfuzz(void); // _xxtestfuzz +extern PyObject* PyInit__xxtestfuzz(void); // _xxtestfuzz extern PyObject* PyInit__zoneinfo(void); // _zoneinfo -extern PyObject* PyInit_array(void); // array -extern PyObject* PyInit_atexit(void); // atexit -extern PyObject* PyInit_audioop(void); // audioop -extern PyObject* PyInit_binascii(void); // binascii -extern PyObject* PyInit_cmath(void); // cmath -extern PyObject* PyInit_errno(void); // errno -extern PyObject* PyInit_faulthandler(void); // faulthandler -#if !defined(_MSC_VER) -extern PyObject* PyInit_fcntl(void); // fcntl -#endif -#if !defined(_MSC_VER) -extern PyObject* PyInit_grp(void); // grp -#endif -extern PyObject* PyInit_itertools(void); // itertools -extern PyObject* PyInit_math(void); // math -extern PyObject* PyInit_mmap(void); // mmap -#if defined(_MSC_VER) -extern PyObject* PyInit_nt(void); // nt -#endif -extern PyObject* PyInit_parser(void); // parser -#if !defined(_MSC_VER) -extern PyObject* PyInit_posix(void); // posix -#endif -#if !defined(_MSC_VER) -extern PyObject* PyInit_pwd(void); // pwd -#endif -extern PyObject* PyInit_pyexpat(void); // pyexpat -#if !defined(_MSC_VER) -extern PyObject* PyInit_resource(void); // resource -#endif -extern PyObject* PyInit_select(void); // select -#if defined(__linux__) -extern PyObject* PyInit_spwd(void); // spwd -#endif -#if !defined(_MSC_VER) -extern PyObject* PyInit_syslog(void); // syslog -#endif -#if !defined(_MSC_VER) -extern PyObject* PyInit_termios(void); // termios -#endif -extern PyObject* PyInit_time(void); // time -extern PyObject* PyInit_unicodedata(void); // unicodedata -extern PyObject* PyInit_zlib(void); // zlib -#if defined(__APPLE__) -extern PyObject* PyInit__scproxy(void); // _scproxy -#endif -#if defined(_MSC_VER) -extern PyObject* PyInit__overlapped(void); // _overlapped -#endif -#if defined(_MSC_VER) -extern PyObject* PyInit__winapi(void); // _winapi -#endif -#if defined(_MSC_VER) -extern PyObject* PyInit_msvcrt(void); // msvcrt -#endif -#if defined(_MSC_VER) -extern PyObject* PyInit_winreg(void); // winreg -#endif -#if defined(_MSC_VER) -extern PyObject* PyInit_winsound(void); // winsound -#endif - -extern PyObject* PyMarshal_Init(void); -extern PyObject* PyInit__imp(void); -extern PyObject* PyInit_gc(void); -extern PyObject* PyInit__ast(void); -extern PyObject* _PyWarnings_Init(void); -extern PyObject* PyInit__string(void); - -struct _inittab _PyImport_Inittab[] = { - - {"_abc", PyInit__abc}, - {"_asyncio", PyInit__asyncio}, - {"_bisect", PyInit__bisect}, - {"_blake2", PyInit__blake2}, - {"_bz2", PyInit__bz2}, - {"_codecs", PyInit__codecs}, - {"_codecs_cn", PyInit__codecs_cn}, - {"_codecs_hk", PyInit__codecs_hk}, - {"_codecs_iso2022", PyInit__codecs_iso2022}, - {"_codecs_jp", PyInit__codecs_jp}, - {"_codecs_kr", PyInit__codecs_kr}, - {"_codecs_tw", PyInit__codecs_tw}, - {"_collections", PyInit__collections}, - {"_contextvars", PyInit__contextvars}, +extern PyObject* PyInit_array(void); // array +extern PyObject* PyInit_atexit(void); // atexit +extern PyObject* PyInit_audioop(void); // audioop +extern PyObject* PyInit_binascii(void); // binascii +extern PyObject* PyInit_cmath(void); // cmath +extern PyObject* PyInit_errno(void); // errno +extern PyObject* PyInit_faulthandler(void); // faulthandler +#if !defined(_MSC_VER) +extern PyObject* PyInit_fcntl(void); // fcntl +#endif +#if !defined(_MSC_VER) +extern PyObject* PyInit_grp(void); // grp +#endif +extern PyObject* PyInit_itertools(void); // itertools +extern PyObject* PyInit_math(void); // math +extern PyObject* PyInit_mmap(void); // mmap +#if defined(_MSC_VER) +extern PyObject* PyInit_nt(void); // nt +#endif +extern PyObject* PyInit_parser(void); // parser +#if !defined(_MSC_VER) +extern PyObject* PyInit_posix(void); // posix +#endif +#if !defined(_MSC_VER) +extern PyObject* PyInit_pwd(void); // pwd +#endif +extern PyObject* PyInit_pyexpat(void); // pyexpat +#if !defined(_MSC_VER) +extern PyObject* PyInit_resource(void); // resource +#endif +extern PyObject* PyInit_select(void); // select +#if defined(__linux__) +extern PyObject* PyInit_spwd(void); // spwd +#endif +#if !defined(_MSC_VER) +extern PyObject* PyInit_syslog(void); // syslog +#endif +#if !defined(_MSC_VER) +extern PyObject* PyInit_termios(void); // termios +#endif +extern PyObject* PyInit_time(void); // time +extern PyObject* PyInit_unicodedata(void); // unicodedata +extern PyObject* PyInit_zlib(void); // zlib +#if defined(__APPLE__) +extern PyObject* PyInit__scproxy(void); // _scproxy +#endif +#if defined(_MSC_VER) +extern PyObject* PyInit__overlapped(void); // _overlapped +#endif +#if defined(_MSC_VER) +extern PyObject* PyInit__winapi(void); // _winapi +#endif +#if defined(_MSC_VER) +extern PyObject* PyInit_msvcrt(void); // msvcrt +#endif +#if defined(_MSC_VER) +extern PyObject* PyInit_winreg(void); // winreg +#endif +#if defined(_MSC_VER) +extern PyObject* PyInit_winsound(void); // winsound +#endif + +extern PyObject* PyMarshal_Init(void); +extern PyObject* PyInit__imp(void); +extern PyObject* PyInit_gc(void); +extern PyObject* PyInit__ast(void); +extern PyObject* _PyWarnings_Init(void); +extern PyObject* PyInit__string(void); + +struct _inittab _PyImport_Inittab[] = { + + {"_abc", PyInit__abc}, + {"_asyncio", PyInit__asyncio}, + {"_bisect", PyInit__bisect}, + {"_blake2", PyInit__blake2}, + {"_bz2", PyInit__bz2}, + {"_codecs", PyInit__codecs}, + {"_codecs_cn", PyInit__codecs_cn}, + {"_codecs_hk", PyInit__codecs_hk}, + {"_codecs_iso2022", PyInit__codecs_iso2022}, + {"_codecs_jp", PyInit__codecs_jp}, + {"_codecs_kr", PyInit__codecs_kr}, + {"_codecs_tw", PyInit__codecs_tw}, + {"_collections", PyInit__collections}, + {"_contextvars", PyInit__contextvars}, #if !defined(_MSC_VER) {"_crypt", PyInit__crypt}, #endif - {"_csv", PyInit__csv}, - {"_ctypes", PyInit__ctypes}, - {"_datetime", PyInit__datetime}, - {"_decimal", PyInit__decimal}, - {"_elementtree", PyInit__elementtree}, - {"_functools", PyInit__functools}, - {"_hashlib", PyInit__hashlib}, - {"_heapq", PyInit__heapq}, - {"_imp", PyInit__imp}, - {"_io", PyInit__io}, - {"_json", PyInit__json}, - {"_locale", PyInit__locale}, - {"_lsprof", PyInit__lsprof}, - {"_lzma", PyInit__lzma}, - {"_md5", PyInit__md5}, - {"_multibytecodec", PyInit__multibytecodec}, - {"_multiprocessing", PyInit__multiprocessing}, - {"_opcode", PyInit__opcode}, - {"_operator", PyInit__operator}, + {"_csv", PyInit__csv}, + {"_ctypes", PyInit__ctypes}, + {"_datetime", PyInit__datetime}, + {"_decimal", PyInit__decimal}, + {"_elementtree", PyInit__elementtree}, + {"_functools", PyInit__functools}, + {"_hashlib", PyInit__hashlib}, + {"_heapq", PyInit__heapq}, + {"_imp", PyInit__imp}, + {"_io", PyInit__io}, + {"_json", PyInit__json}, + {"_locale", PyInit__locale}, + {"_lsprof", PyInit__lsprof}, + {"_lzma", PyInit__lzma}, + {"_md5", PyInit__md5}, + {"_multibytecodec", PyInit__multibytecodec}, + {"_multiprocessing", PyInit__multiprocessing}, + {"_opcode", PyInit__opcode}, + {"_operator", PyInit__operator}, {"_peg_parser", PyInit__peg_parser}, - {"_pickle", PyInit__pickle}, + {"_pickle", PyInit__pickle}, {"_posixshmem", PyInit__posixshmem}, -#if !defined(_MSC_VER) - {"_posixsubprocess", PyInit__posixsubprocess}, -#endif - {"_queue", PyInit__queue}, - {"_random", PyInit__random}, - {"_sha1", PyInit__sha1}, - {"_sha256", PyInit__sha256}, - {"_sha3", PyInit__sha3}, - {"_sha512", PyInit__sha512}, - {"_signal", PyInit__signal}, - {"_socket", PyInit__socket}, - {"_sre", PyInit__sre}, - {"_ssl", PyInit__ssl}, - {"_stat", PyInit__stat}, +#if !defined(_MSC_VER) + {"_posixsubprocess", PyInit__posixsubprocess}, +#endif + {"_queue", PyInit__queue}, + {"_random", PyInit__random}, + {"_sha1", PyInit__sha1}, + {"_sha256", PyInit__sha256}, + {"_sha3", PyInit__sha3}, + {"_sha512", PyInit__sha512}, + {"_signal", PyInit__signal}, + {"_socket", PyInit__socket}, + {"_sre", PyInit__sre}, + {"_ssl", PyInit__ssl}, + {"_stat", PyInit__stat}, {"_statistics", PyInit__statistics}, - {"_string", PyInit__string}, - {"_struct", PyInit__struct}, - {"_symtable", PyInit__symtable}, - {"_thread", PyInit__thread}, - {"_tracemalloc", PyInit__tracemalloc}, - {"_weakref", PyInit__weakref}, + {"_string", PyInit__string}, + {"_struct", PyInit__struct}, + {"_symtable", PyInit__symtable}, + {"_thread", PyInit__thread}, + {"_tracemalloc", PyInit__tracemalloc}, + {"_weakref", PyInit__weakref}, {"_xxsubinterpreters", PyInit__xxsubinterpreters}, - {"_xxtestfuzz", PyInit__xxtestfuzz}, + {"_xxtestfuzz", PyInit__xxtestfuzz}, {"_zoneinfo", PyInit__zoneinfo}, - {"array", PyInit_array}, - {"atexit", PyInit_atexit}, - {"audioop", PyInit_audioop}, - {"binascii", PyInit_binascii}, - {"cmath", PyInit_cmath}, - {"errno", PyInit_errno}, - {"faulthandler", PyInit_faulthandler}, -#if !defined(_MSC_VER) - {"fcntl", PyInit_fcntl}, -#endif -#if !defined(_MSC_VER) - {"grp", PyInit_grp}, -#endif - {"itertools", PyInit_itertools}, - {"math", PyInit_math}, - {"mmap", PyInit_mmap}, -#if defined(_MSC_VER) - {"nt", PyInit_nt}, -#endif - {"parser", PyInit_parser}, -#if !defined(_MSC_VER) - {"posix", PyInit_posix}, -#endif -#if !defined(_MSC_VER) - {"pwd", PyInit_pwd}, -#endif - {"pyexpat", PyInit_pyexpat}, -#if !defined(_MSC_VER) - {"resource", PyInit_resource}, -#endif - {"select", PyInit_select}, -#if defined(__linux__) - {"spwd", PyInit_spwd}, -#endif -#if !defined(_MSC_VER) - {"syslog", PyInit_syslog}, -#endif -#if !defined(_MSC_VER) - {"termios", PyInit_termios}, -#endif - {"time", PyInit_time}, - {"unicodedata", PyInit_unicodedata}, - {"zlib", PyInit_zlib}, -#if defined(__APPLE__) - {"_scproxy", PyInit__scproxy}, -#endif -#if defined(_MSC_VER) - {"_overlapped", PyInit__overlapped}, -#endif -#if defined(_MSC_VER) - {"_winapi", PyInit__winapi}, -#endif -#if defined(_MSC_VER) - {"msvcrt", PyInit_msvcrt}, -#endif -#if defined(_MSC_VER) - {"winreg", PyInit_winreg}, -#endif -#if defined(_MSC_VER) - {"winsound", PyInit_winsound}, -#endif - - /* This module lives in marshal.c */ - {"marshal", PyMarshal_Init}, - - /* This lives in import.c */ - {"_imp", PyInit__imp}, - - /* This lives in Python/Python-ast.c */ - {"_ast", PyInit__ast}, - - /* These entries are here for sys.builtin_module_names */ - {"builtins", NULL}, - {"sys", NULL}, - - /* This lives in gcmodule.c */ - {"gc", PyInit_gc}, - - /* This lives in _warnings.c */ - {"_warnings", _PyWarnings_Init}, - - /* This lives in Objects/unicodeobject.c */ - {"_string", PyInit__string}, - - /* Sentinel */ - {0, 0} -}; - - -#ifdef __cplusplus -} -#endif + {"array", PyInit_array}, + {"atexit", PyInit_atexit}, + {"audioop", PyInit_audioop}, + {"binascii", PyInit_binascii}, + {"cmath", PyInit_cmath}, + {"errno", PyInit_errno}, + {"faulthandler", PyInit_faulthandler}, +#if !defined(_MSC_VER) + {"fcntl", PyInit_fcntl}, +#endif +#if !defined(_MSC_VER) + {"grp", PyInit_grp}, +#endif + {"itertools", PyInit_itertools}, + {"math", PyInit_math}, + {"mmap", PyInit_mmap}, +#if defined(_MSC_VER) + {"nt", PyInit_nt}, +#endif + {"parser", PyInit_parser}, +#if !defined(_MSC_VER) + {"posix", PyInit_posix}, +#endif +#if !defined(_MSC_VER) + {"pwd", PyInit_pwd}, +#endif + {"pyexpat", PyInit_pyexpat}, +#if !defined(_MSC_VER) + {"resource", PyInit_resource}, +#endif + {"select", PyInit_select}, +#if defined(__linux__) + {"spwd", PyInit_spwd}, +#endif +#if !defined(_MSC_VER) + {"syslog", PyInit_syslog}, +#endif +#if !defined(_MSC_VER) + {"termios", PyInit_termios}, +#endif + {"time", PyInit_time}, + {"unicodedata", PyInit_unicodedata}, + {"zlib", PyInit_zlib}, +#if defined(__APPLE__) + {"_scproxy", PyInit__scproxy}, +#endif +#if defined(_MSC_VER) + {"_overlapped", PyInit__overlapped}, +#endif +#if defined(_MSC_VER) + {"_winapi", PyInit__winapi}, +#endif +#if defined(_MSC_VER) + {"msvcrt", PyInit_msvcrt}, +#endif +#if defined(_MSC_VER) + {"winreg", PyInit_winreg}, +#endif +#if defined(_MSC_VER) + {"winsound", PyInit_winsound}, +#endif + + /* This module lives in marshal.c */ + {"marshal", PyMarshal_Init}, + + /* This lives in import.c */ + {"_imp", PyInit__imp}, + + /* This lives in Python/Python-ast.c */ + {"_ast", PyInit__ast}, + + /* These entries are here for sys.builtin_module_names */ + {"builtins", NULL}, + {"sys", NULL}, + + /* This lives in gcmodule.c */ + {"gc", PyInit_gc}, + + /* This lives in _warnings.c */ + {"_warnings", _PyWarnings_Init}, + + /* This lives in Objects/unicodeobject.c */ + {"_string", PyInit__string}, + + /* Sentinel */ + {0, 0} +}; + + +#ifdef __cplusplus +} +#endif diff --git a/contrib/tools/python3/src/Modules/errnomodule.c b/contrib/tools/python3/src/Modules/errnomodule.c index d99bed45bd6..63482cf78ea 100644 --- a/contrib/tools/python3/src/Modules/errnomodule.c +++ b/contrib/tools/python3/src/Modules/errnomodule.c @@ -1,64 +1,64 @@ - -/* Errno module */ - -#include "Python.h" - -/* Windows socket errors (WSA*) */ -#ifdef MS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -/* The following constants were added to errno.h in VS2010 but have - preferred WSA equivalents. */ -#undef EADDRINUSE -#undef EADDRNOTAVAIL -#undef EAFNOSUPPORT -#undef EALREADY -#undef ECONNABORTED -#undef ECONNREFUSED -#undef ECONNRESET -#undef EDESTADDRREQ -#undef EHOSTUNREACH -#undef EINPROGRESS -#undef EISCONN -#undef ELOOP -#undef EMSGSIZE -#undef ENETDOWN -#undef ENETRESET -#undef ENETUNREACH -#undef ENOBUFS -#undef ENOPROTOOPT -#undef ENOTCONN -#undef ENOTSOCK -#undef EOPNOTSUPP -#undef EPROTONOSUPPORT -#undef EPROTOTYPE -#undef ETIMEDOUT -#undef EWOULDBLOCK -#endif - -/* - * Pull in the system error definitions - */ - -static PyMethodDef errno_methods[] = { - {NULL, NULL} -}; - -/* Helper function doing the dictionary inserting */ - + +/* Errno module */ + +#include "Python.h" + +/* Windows socket errors (WSA*) */ +#ifdef MS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +/* The following constants were added to errno.h in VS2010 but have + preferred WSA equivalents. */ +#undef EADDRINUSE +#undef EADDRNOTAVAIL +#undef EAFNOSUPPORT +#undef EALREADY +#undef ECONNABORTED +#undef ECONNREFUSED +#undef ECONNRESET +#undef EDESTADDRREQ +#undef EHOSTUNREACH +#undef EINPROGRESS +#undef EISCONN +#undef ELOOP +#undef EMSGSIZE +#undef ENETDOWN +#undef ENETRESET +#undef ENETUNREACH +#undef ENOBUFS +#undef ENOPROTOOPT +#undef ENOTCONN +#undef ENOTSOCK +#undef EOPNOTSUPP +#undef EPROTONOSUPPORT +#undef EPROTOTYPE +#undef ETIMEDOUT +#undef EWOULDBLOCK +#endif + +/* + * Pull in the system error definitions + */ + +static PyMethodDef errno_methods[] = { + {NULL, NULL} +}; + +/* Helper function doing the dictionary inserting */ + static int _add_errcode(PyObject *module_dict, PyObject *error_dict, const char *name_str, int code_int) -{ +{ PyObject *name = PyUnicode_FromString(name_str); if (!name) { return -1; } - + PyObject *code = PyLong_FromLong(code_int); if (!code) { Py_DECREF(name); return -1; - } + } int ret = -1; /* insert in modules dict */ @@ -74,11 +74,11 @@ end: Py_DECREF(name); Py_DECREF(code); return ret; -} - +} + static int errno_exec(PyObject *module) -{ +{ PyObject *module_dict = PyModule_GetDict(module); PyObject *error_dict = PyDict_New(); if (!module_dict || !error_dict) { @@ -88,8 +88,8 @@ errno_exec(PyObject *module) Py_DECREF(error_dict); return -1; } - -/* Macro so I don't have to edit each and every line below... */ + +/* Macro so I don't have to edit each and every line below... */ #define add_errcode(name, code, comment) \ do { \ if (_add_errcode(module_dict, error_dict, name, code) < 0) { \ @@ -97,833 +97,833 @@ errno_exec(PyObject *module) return -1; \ } \ } while (0); - - /* - * The names and comments are borrowed from linux/include/errno.h, - * which should be pretty all-inclusive. However, the Solaris specific - * names and comments are borrowed from sys/errno.h in Solaris. - * MacOSX specific names and comments are borrowed from sys/errno.h in - * MacOSX. - */ - -#ifdef ENODEV + + /* + * The names and comments are borrowed from linux/include/errno.h, + * which should be pretty all-inclusive. However, the Solaris specific + * names and comments are borrowed from sys/errno.h in Solaris. + * MacOSX specific names and comments are borrowed from sys/errno.h in + * MacOSX. + */ + +#ifdef ENODEV add_errcode("ENODEV", ENODEV, "No such device"); -#endif -#ifdef ENOCSI +#endif +#ifdef ENOCSI add_errcode("ENOCSI", ENOCSI, "No CSI structure available"); -#endif -#ifdef EHOSTUNREACH +#endif +#ifdef EHOSTUNREACH add_errcode("EHOSTUNREACH", EHOSTUNREACH, "No route to host"); -#else -#ifdef WSAEHOSTUNREACH +#else +#ifdef WSAEHOSTUNREACH add_errcode("EHOSTUNREACH", WSAEHOSTUNREACH, "No route to host"); -#endif -#endif -#ifdef ENOMSG +#endif +#endif +#ifdef ENOMSG add_errcode("ENOMSG", ENOMSG, "No message of desired type"); -#endif -#ifdef EUCLEAN +#endif +#ifdef EUCLEAN add_errcode("EUCLEAN", EUCLEAN, "Structure needs cleaning"); -#endif -#ifdef EL2NSYNC +#endif +#ifdef EL2NSYNC add_errcode("EL2NSYNC", EL2NSYNC, "Level 2 not synchronized"); -#endif -#ifdef EL2HLT +#endif +#ifdef EL2HLT add_errcode("EL2HLT", EL2HLT, "Level 2 halted"); -#endif -#ifdef ENODATA +#endif +#ifdef ENODATA add_errcode("ENODATA", ENODATA, "No data available"); -#endif -#ifdef ENOTBLK +#endif +#ifdef ENOTBLK add_errcode("ENOTBLK", ENOTBLK, "Block device required"); -#endif -#ifdef ENOSYS +#endif +#ifdef ENOSYS add_errcode("ENOSYS", ENOSYS, "Function not implemented"); -#endif -#ifdef EPIPE +#endif +#ifdef EPIPE add_errcode("EPIPE", EPIPE, "Broken pipe"); -#endif -#ifdef EINVAL +#endif +#ifdef EINVAL add_errcode("EINVAL", EINVAL, "Invalid argument"); -#else -#ifdef WSAEINVAL +#else +#ifdef WSAEINVAL add_errcode("EINVAL", WSAEINVAL, "Invalid argument"); -#endif -#endif -#ifdef EOVERFLOW +#endif +#endif +#ifdef EOVERFLOW add_errcode("EOVERFLOW", EOVERFLOW, "Value too large for defined data type"); -#endif -#ifdef EADV +#endif +#ifdef EADV add_errcode("EADV", EADV, "Advertise error"); -#endif -#ifdef EINTR +#endif +#ifdef EINTR add_errcode("EINTR", EINTR, "Interrupted system call"); -#else -#ifdef WSAEINTR +#else +#ifdef WSAEINTR add_errcode("EINTR", WSAEINTR, "Interrupted system call"); -#endif -#endif -#ifdef EUSERS +#endif +#endif +#ifdef EUSERS add_errcode("EUSERS", EUSERS, "Too many users"); -#else -#ifdef WSAEUSERS +#else +#ifdef WSAEUSERS add_errcode("EUSERS", WSAEUSERS, "Too many users"); -#endif -#endif -#ifdef ENOTEMPTY +#endif +#endif +#ifdef ENOTEMPTY add_errcode("ENOTEMPTY", ENOTEMPTY, "Directory not empty"); -#else -#ifdef WSAENOTEMPTY +#else +#ifdef WSAENOTEMPTY add_errcode("ENOTEMPTY", WSAENOTEMPTY, "Directory not empty"); -#endif -#endif -#ifdef ENOBUFS +#endif +#endif +#ifdef ENOBUFS add_errcode("ENOBUFS", ENOBUFS, "No buffer space available"); -#else -#ifdef WSAENOBUFS +#else +#ifdef WSAENOBUFS add_errcode("ENOBUFS", WSAENOBUFS, "No buffer space available"); -#endif -#endif -#ifdef EPROTO +#endif +#endif +#ifdef EPROTO add_errcode("EPROTO", EPROTO, "Protocol error"); -#endif -#ifdef EREMOTE +#endif +#ifdef EREMOTE add_errcode("EREMOTE", EREMOTE, "Object is remote"); -#else -#ifdef WSAEREMOTE +#else +#ifdef WSAEREMOTE add_errcode("EREMOTE", WSAEREMOTE, "Object is remote"); -#endif -#endif -#ifdef ENAVAIL +#endif +#endif +#ifdef ENAVAIL add_errcode("ENAVAIL", ENAVAIL, "No XENIX semaphores available"); -#endif -#ifdef ECHILD +#endif +#ifdef ECHILD add_errcode("ECHILD", ECHILD, "No child processes"); -#endif -#ifdef ELOOP +#endif +#ifdef ELOOP add_errcode("ELOOP", ELOOP, "Too many symbolic links encountered"); -#else -#ifdef WSAELOOP +#else +#ifdef WSAELOOP add_errcode("ELOOP", WSAELOOP, "Too many symbolic links encountered"); -#endif -#endif -#ifdef EXDEV +#endif +#endif +#ifdef EXDEV add_errcode("EXDEV", EXDEV, "Cross-device link"); -#endif -#ifdef E2BIG +#endif +#ifdef E2BIG add_errcode("E2BIG", E2BIG, "Arg list too long"); -#endif -#ifdef ESRCH +#endif +#ifdef ESRCH add_errcode("ESRCH", ESRCH, "No such process"); -#endif -#ifdef EMSGSIZE +#endif +#ifdef EMSGSIZE add_errcode("EMSGSIZE", EMSGSIZE, "Message too long"); -#else -#ifdef WSAEMSGSIZE +#else +#ifdef WSAEMSGSIZE add_errcode("EMSGSIZE", WSAEMSGSIZE, "Message too long"); -#endif -#endif -#ifdef EAFNOSUPPORT +#endif +#endif +#ifdef EAFNOSUPPORT add_errcode("EAFNOSUPPORT", EAFNOSUPPORT, "Address family not supported by protocol"); -#else -#ifdef WSAEAFNOSUPPORT +#else +#ifdef WSAEAFNOSUPPORT add_errcode("EAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol"); -#endif -#endif -#ifdef EBADR +#endif +#endif +#ifdef EBADR add_errcode("EBADR", EBADR, "Invalid request descriptor"); -#endif -#ifdef EHOSTDOWN +#endif +#ifdef EHOSTDOWN add_errcode("EHOSTDOWN", EHOSTDOWN, "Host is down"); -#else -#ifdef WSAEHOSTDOWN +#else +#ifdef WSAEHOSTDOWN add_errcode("EHOSTDOWN", WSAEHOSTDOWN, "Host is down"); -#endif -#endif -#ifdef EPFNOSUPPORT +#endif +#endif +#ifdef EPFNOSUPPORT add_errcode("EPFNOSUPPORT", EPFNOSUPPORT, "Protocol family not supported"); -#else -#ifdef WSAEPFNOSUPPORT +#else +#ifdef WSAEPFNOSUPPORT add_errcode("EPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported"); -#endif -#endif -#ifdef ENOPROTOOPT +#endif +#endif +#ifdef ENOPROTOOPT add_errcode("ENOPROTOOPT", ENOPROTOOPT, "Protocol not available"); -#else -#ifdef WSAENOPROTOOPT +#else +#ifdef WSAENOPROTOOPT add_errcode("ENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available"); -#endif -#endif -#ifdef EBUSY +#endif +#endif +#ifdef EBUSY add_errcode("EBUSY", EBUSY, "Device or resource busy"); -#endif -#ifdef EWOULDBLOCK +#endif +#ifdef EWOULDBLOCK add_errcode("EWOULDBLOCK", EWOULDBLOCK, "Operation would block"); -#else -#ifdef WSAEWOULDBLOCK +#else +#ifdef WSAEWOULDBLOCK add_errcode("EWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block"); -#endif -#endif -#ifdef EBADFD +#endif +#endif +#ifdef EBADFD add_errcode("EBADFD", EBADFD, "File descriptor in bad state"); -#endif -#ifdef EDOTDOT +#endif +#ifdef EDOTDOT add_errcode("EDOTDOT", EDOTDOT, "RFS specific error"); -#endif -#ifdef EISCONN +#endif +#ifdef EISCONN add_errcode("EISCONN", EISCONN, "Transport endpoint is already connected"); -#else -#ifdef WSAEISCONN +#else +#ifdef WSAEISCONN add_errcode("EISCONN", WSAEISCONN, "Transport endpoint is already connected"); -#endif -#endif -#ifdef ENOANO +#endif +#endif +#ifdef ENOANO add_errcode("ENOANO", ENOANO, "No anode"); -#endif -#ifdef ESHUTDOWN +#endif +#ifdef ESHUTDOWN add_errcode("ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown"); -#else -#ifdef WSAESHUTDOWN +#else +#ifdef WSAESHUTDOWN add_errcode("ESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown"); -#endif -#endif -#ifdef ECHRNG +#endif +#endif +#ifdef ECHRNG add_errcode("ECHRNG", ECHRNG, "Channel number out of range"); -#endif -#ifdef ELIBBAD +#endif +#ifdef ELIBBAD add_errcode("ELIBBAD", ELIBBAD, "Accessing a corrupted shared library"); -#endif -#ifdef ENONET +#endif +#ifdef ENONET add_errcode("ENONET", ENONET, "Machine is not on the network"); -#endif -#ifdef EBADE +#endif +#ifdef EBADE add_errcode("EBADE", EBADE, "Invalid exchange"); -#endif -#ifdef EBADF +#endif +#ifdef EBADF add_errcode("EBADF", EBADF, "Bad file number"); -#else -#ifdef WSAEBADF +#else +#ifdef WSAEBADF add_errcode("EBADF", WSAEBADF, "Bad file number"); -#endif -#endif -#ifdef EMULTIHOP +#endif +#endif +#ifdef EMULTIHOP add_errcode("EMULTIHOP", EMULTIHOP, "Multihop attempted"); -#endif -#ifdef EIO +#endif +#ifdef EIO add_errcode("EIO", EIO, "I/O error"); -#endif -#ifdef EUNATCH +#endif +#ifdef EUNATCH add_errcode("EUNATCH", EUNATCH, "Protocol driver not attached"); -#endif -#ifdef EPROTOTYPE +#endif +#ifdef EPROTOTYPE add_errcode("EPROTOTYPE", EPROTOTYPE, "Protocol wrong type for socket"); -#else -#ifdef WSAEPROTOTYPE +#else +#ifdef WSAEPROTOTYPE add_errcode("EPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket"); -#endif -#endif -#ifdef ENOSPC +#endif +#endif +#ifdef ENOSPC add_errcode("ENOSPC", ENOSPC, "No space left on device"); -#endif -#ifdef ENOEXEC +#endif +#ifdef ENOEXEC add_errcode("ENOEXEC", ENOEXEC, "Exec format error"); -#endif -#ifdef EALREADY +#endif +#ifdef EALREADY add_errcode("EALREADY", EALREADY, "Operation already in progress"); -#else -#ifdef WSAEALREADY +#else +#ifdef WSAEALREADY add_errcode("EALREADY", WSAEALREADY, "Operation already in progress"); -#endif -#endif -#ifdef ENETDOWN +#endif +#endif +#ifdef ENETDOWN add_errcode("ENETDOWN", ENETDOWN, "Network is down"); -#else -#ifdef WSAENETDOWN +#else +#ifdef WSAENETDOWN add_errcode("ENETDOWN", WSAENETDOWN, "Network is down"); -#endif -#endif -#ifdef ENOTNAM +#endif +#endif +#ifdef ENOTNAM add_errcode("ENOTNAM", ENOTNAM, "Not a XENIX named type file"); -#endif -#ifdef EACCES +#endif +#ifdef EACCES add_errcode("EACCES", EACCES, "Permission denied"); -#else -#ifdef WSAEACCES +#else +#ifdef WSAEACCES add_errcode("EACCES", WSAEACCES, "Permission denied"); -#endif -#endif -#ifdef ELNRNG +#endif +#endif +#ifdef ELNRNG add_errcode("ELNRNG", ELNRNG, "Link number out of range"); -#endif -#ifdef EILSEQ +#endif +#ifdef EILSEQ add_errcode("EILSEQ", EILSEQ, "Illegal byte sequence"); -#endif -#ifdef ENOTDIR +#endif +#ifdef ENOTDIR add_errcode("ENOTDIR", ENOTDIR, "Not a directory"); -#endif -#ifdef ENOTUNIQ +#endif +#ifdef ENOTUNIQ add_errcode("ENOTUNIQ", ENOTUNIQ, "Name not unique on network"); -#endif -#ifdef EPERM +#endif +#ifdef EPERM add_errcode("EPERM", EPERM, "Operation not permitted"); -#endif -#ifdef EDOM +#endif +#ifdef EDOM add_errcode("EDOM", EDOM, "Math argument out of domain of func"); -#endif -#ifdef EXFULL +#endif +#ifdef EXFULL add_errcode("EXFULL", EXFULL, "Exchange full"); -#endif -#ifdef ECONNREFUSED +#endif +#ifdef ECONNREFUSED add_errcode("ECONNREFUSED", ECONNREFUSED, "Connection refused"); -#else -#ifdef WSAECONNREFUSED +#else +#ifdef WSAECONNREFUSED add_errcode("ECONNREFUSED", WSAECONNREFUSED, "Connection refused"); -#endif -#endif -#ifdef EISDIR +#endif +#endif +#ifdef EISDIR add_errcode("EISDIR", EISDIR, "Is a directory"); -#endif -#ifdef EPROTONOSUPPORT +#endif +#ifdef EPROTONOSUPPORT add_errcode("EPROTONOSUPPORT", EPROTONOSUPPORT, "Protocol not supported"); -#else -#ifdef WSAEPROTONOSUPPORT +#else +#ifdef WSAEPROTONOSUPPORT add_errcode("EPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported"); -#endif -#endif -#ifdef EROFS +#endif +#endif +#ifdef EROFS add_errcode("EROFS", EROFS, "Read-only file system"); -#endif -#ifdef EADDRNOTAVAIL +#endif +#ifdef EADDRNOTAVAIL add_errcode("EADDRNOTAVAIL", EADDRNOTAVAIL, "Cannot assign requested address"); -#else -#ifdef WSAEADDRNOTAVAIL +#else +#ifdef WSAEADDRNOTAVAIL add_errcode("EADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address"); -#endif -#endif -#ifdef EIDRM +#endif +#endif +#ifdef EIDRM add_errcode("EIDRM", EIDRM, "Identifier removed"); -#endif -#ifdef ECOMM +#endif +#ifdef ECOMM add_errcode("ECOMM", ECOMM, "Communication error on send"); -#endif -#ifdef ESRMNT +#endif +#ifdef ESRMNT add_errcode("ESRMNT", ESRMNT, "Srmount error"); -#endif -#ifdef EREMOTEIO +#endif +#ifdef EREMOTEIO add_errcode("EREMOTEIO", EREMOTEIO, "Remote I/O error"); -#endif -#ifdef EL3RST +#endif +#ifdef EL3RST add_errcode("EL3RST", EL3RST, "Level 3 reset"); -#endif -#ifdef EBADMSG +#endif +#ifdef EBADMSG add_errcode("EBADMSG", EBADMSG, "Not a data message"); -#endif -#ifdef ENFILE +#endif +#ifdef ENFILE add_errcode("ENFILE", ENFILE, "File table overflow"); -#endif -#ifdef ELIBMAX +#endif +#ifdef ELIBMAX add_errcode("ELIBMAX", ELIBMAX, "Attempting to link in too many shared libraries"); -#endif -#ifdef ESPIPE +#endif +#ifdef ESPIPE add_errcode("ESPIPE", ESPIPE, "Illegal seek"); -#endif -#ifdef ENOLINK +#endif +#ifdef ENOLINK add_errcode("ENOLINK", ENOLINK, "Link has been severed"); -#endif -#ifdef ENETRESET +#endif +#ifdef ENETRESET add_errcode("ENETRESET", ENETRESET, "Network dropped connection because of reset"); -#else -#ifdef WSAENETRESET +#else +#ifdef WSAENETRESET add_errcode("ENETRESET", WSAENETRESET, "Network dropped connection because of reset"); -#endif -#endif -#ifdef ETIMEDOUT +#endif +#endif +#ifdef ETIMEDOUT add_errcode("ETIMEDOUT", ETIMEDOUT, "Connection timed out"); -#else -#ifdef WSAETIMEDOUT +#else +#ifdef WSAETIMEDOUT add_errcode("ETIMEDOUT", WSAETIMEDOUT, "Connection timed out"); -#endif -#endif -#ifdef ENOENT +#endif +#endif +#ifdef ENOENT add_errcode("ENOENT", ENOENT, "No such file or directory"); -#endif -#ifdef EEXIST +#endif +#ifdef EEXIST add_errcode("EEXIST", EEXIST, "File exists"); -#endif -#ifdef EDQUOT +#endif +#ifdef EDQUOT add_errcode("EDQUOT", EDQUOT, "Quota exceeded"); -#else -#ifdef WSAEDQUOT +#else +#ifdef WSAEDQUOT add_errcode("EDQUOT", WSAEDQUOT, "Quota exceeded"); -#endif -#endif -#ifdef ENOSTR +#endif +#endif +#ifdef ENOSTR add_errcode("ENOSTR", ENOSTR, "Device not a stream"); -#endif -#ifdef EBADSLT +#endif +#ifdef EBADSLT add_errcode("EBADSLT", EBADSLT, "Invalid slot"); -#endif -#ifdef EBADRQC +#endif +#ifdef EBADRQC add_errcode("EBADRQC", EBADRQC, "Invalid request code"); -#endif -#ifdef ELIBACC +#endif +#ifdef ELIBACC add_errcode("ELIBACC", ELIBACC, "Can not access a needed shared library"); -#endif -#ifdef EFAULT +#endif +#ifdef EFAULT add_errcode("EFAULT", EFAULT, "Bad address"); -#else -#ifdef WSAEFAULT +#else +#ifdef WSAEFAULT add_errcode("EFAULT", WSAEFAULT, "Bad address"); -#endif -#endif -#ifdef EFBIG +#endif +#endif +#ifdef EFBIG add_errcode("EFBIG", EFBIG, "File too large"); -#endif -#ifdef EDEADLK +#endif +#ifdef EDEADLK add_errcode("EDEADLK", EDEADLK, "Resource deadlock would occur"); -#endif -#ifdef ENOTCONN +#endif +#ifdef ENOTCONN add_errcode("ENOTCONN", ENOTCONN, "Transport endpoint is not connected"); -#else -#ifdef WSAENOTCONN +#else +#ifdef WSAENOTCONN add_errcode("ENOTCONN", WSAENOTCONN, "Transport endpoint is not connected"); -#endif -#endif -#ifdef EDESTADDRREQ +#endif +#endif +#ifdef EDESTADDRREQ add_errcode("EDESTADDRREQ", EDESTADDRREQ, "Destination address required"); -#else -#ifdef WSAEDESTADDRREQ +#else +#ifdef WSAEDESTADDRREQ add_errcode("EDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required"); -#endif -#endif -#ifdef ELIBSCN +#endif +#endif +#ifdef ELIBSCN add_errcode("ELIBSCN", ELIBSCN, ".lib section in a.out corrupted"); -#endif -#ifdef ENOLCK +#endif +#ifdef ENOLCK add_errcode("ENOLCK", ENOLCK, "No record locks available"); -#endif -#ifdef EISNAM +#endif +#ifdef EISNAM add_errcode("EISNAM", EISNAM, "Is a named type file"); -#endif -#ifdef ECONNABORTED +#endif +#ifdef ECONNABORTED add_errcode("ECONNABORTED", ECONNABORTED, "Software caused connection abort"); -#else -#ifdef WSAECONNABORTED +#else +#ifdef WSAECONNABORTED add_errcode("ECONNABORTED", WSAECONNABORTED, "Software caused connection abort"); -#endif -#endif -#ifdef ENETUNREACH +#endif +#endif +#ifdef ENETUNREACH add_errcode("ENETUNREACH", ENETUNREACH, "Network is unreachable"); -#else -#ifdef WSAENETUNREACH +#else +#ifdef WSAENETUNREACH add_errcode("ENETUNREACH", WSAENETUNREACH, "Network is unreachable"); -#endif -#endif -#ifdef ESTALE +#endif +#endif +#ifdef ESTALE add_errcode("ESTALE", ESTALE, "Stale NFS file handle"); -#else -#ifdef WSAESTALE +#else +#ifdef WSAESTALE add_errcode("ESTALE", WSAESTALE, "Stale NFS file handle"); -#endif -#endif -#ifdef ENOSR +#endif +#endif +#ifdef ENOSR add_errcode("ENOSR", ENOSR, "Out of streams resources"); -#endif -#ifdef ENOMEM +#endif +#ifdef ENOMEM add_errcode("ENOMEM", ENOMEM, "Out of memory"); -#endif -#ifdef ENOTSOCK +#endif +#ifdef ENOTSOCK add_errcode("ENOTSOCK", ENOTSOCK, "Socket operation on non-socket"); -#else -#ifdef WSAENOTSOCK +#else +#ifdef WSAENOTSOCK add_errcode("ENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket"); -#endif -#endif -#ifdef ESTRPIPE +#endif +#endif +#ifdef ESTRPIPE add_errcode("ESTRPIPE", ESTRPIPE, "Streams pipe error"); -#endif -#ifdef EMLINK +#endif +#ifdef EMLINK add_errcode("EMLINK", EMLINK, "Too many links"); -#endif -#ifdef ERANGE +#endif +#ifdef ERANGE add_errcode("ERANGE", ERANGE, "Math result not representable"); -#endif -#ifdef ELIBEXEC +#endif +#ifdef ELIBEXEC add_errcode("ELIBEXEC", ELIBEXEC, "Cannot exec a shared library directly"); -#endif -#ifdef EL3HLT +#endif +#ifdef EL3HLT add_errcode("EL3HLT", EL3HLT, "Level 3 halted"); -#endif -#ifdef ECONNRESET +#endif +#ifdef ECONNRESET add_errcode("ECONNRESET", ECONNRESET, "Connection reset by peer"); -#else -#ifdef WSAECONNRESET +#else +#ifdef WSAECONNRESET add_errcode("ECONNRESET", WSAECONNRESET, "Connection reset by peer"); -#endif -#endif -#ifdef EADDRINUSE +#endif +#endif +#ifdef EADDRINUSE add_errcode("EADDRINUSE", EADDRINUSE, "Address already in use"); -#else -#ifdef WSAEADDRINUSE +#else +#ifdef WSAEADDRINUSE add_errcode("EADDRINUSE", WSAEADDRINUSE, "Address already in use"); -#endif -#endif -#ifdef EOPNOTSUPP +#endif +#endif +#ifdef EOPNOTSUPP add_errcode("EOPNOTSUPP", EOPNOTSUPP, "Operation not supported on transport endpoint"); -#else -#ifdef WSAEOPNOTSUPP +#else +#ifdef WSAEOPNOTSUPP add_errcode("EOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint"); -#endif -#endif -#ifdef EREMCHG +#endif +#endif +#ifdef EREMCHG add_errcode("EREMCHG", EREMCHG, "Remote address changed"); -#endif -#ifdef EAGAIN +#endif +#ifdef EAGAIN add_errcode("EAGAIN", EAGAIN, "Try again"); -#endif -#ifdef ENAMETOOLONG +#endif +#ifdef ENAMETOOLONG add_errcode("ENAMETOOLONG", ENAMETOOLONG, "File name too long"); -#else -#ifdef WSAENAMETOOLONG +#else +#ifdef WSAENAMETOOLONG add_errcode("ENAMETOOLONG", WSAENAMETOOLONG, "File name too long"); -#endif -#endif -#ifdef ENOTTY +#endif +#endif +#ifdef ENOTTY add_errcode("ENOTTY", ENOTTY, "Not a typewriter"); -#endif -#ifdef ERESTART +#endif +#ifdef ERESTART add_errcode("ERESTART", ERESTART, "Interrupted system call should be restarted"); -#endif -#ifdef ESOCKTNOSUPPORT +#endif +#ifdef ESOCKTNOSUPPORT add_errcode("ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, "Socket type not supported"); -#else -#ifdef WSAESOCKTNOSUPPORT +#else +#ifdef WSAESOCKTNOSUPPORT add_errcode("ESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported"); -#endif -#endif -#ifdef ETIME +#endif +#endif +#ifdef ETIME add_errcode("ETIME", ETIME, "Timer expired"); -#endif -#ifdef EBFONT +#endif +#ifdef EBFONT add_errcode("EBFONT", EBFONT, "Bad font file format"); -#endif -#ifdef EDEADLOCK +#endif +#ifdef EDEADLOCK add_errcode("EDEADLOCK", EDEADLOCK, "Error EDEADLOCK"); -#endif -#ifdef ETOOMANYREFS +#endif +#ifdef ETOOMANYREFS add_errcode("ETOOMANYREFS", ETOOMANYREFS, "Too many references: cannot splice"); -#else -#ifdef WSAETOOMANYREFS +#else +#ifdef WSAETOOMANYREFS add_errcode("ETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice"); -#endif -#endif -#ifdef EMFILE +#endif +#endif +#ifdef EMFILE add_errcode("EMFILE", EMFILE, "Too many open files"); -#else -#ifdef WSAEMFILE +#else +#ifdef WSAEMFILE add_errcode("EMFILE", WSAEMFILE, "Too many open files"); -#endif -#endif -#ifdef ETXTBSY +#endif +#endif +#ifdef ETXTBSY add_errcode("ETXTBSY", ETXTBSY, "Text file busy"); -#endif -#ifdef EINPROGRESS +#endif +#ifdef EINPROGRESS add_errcode("EINPROGRESS", EINPROGRESS, "Operation now in progress"); -#else -#ifdef WSAEINPROGRESS +#else +#ifdef WSAEINPROGRESS add_errcode("EINPROGRESS", WSAEINPROGRESS, "Operation now in progress"); -#endif -#endif -#ifdef ENXIO +#endif +#endif +#ifdef ENXIO add_errcode("ENXIO", ENXIO, "No such device or address"); -#endif -#ifdef ENOPKG +#endif +#ifdef ENOPKG add_errcode("ENOPKG", ENOPKG, "Package not installed"); -#endif -#ifdef WSASY +#endif +#ifdef WSASY add_errcode("WSASY", WSASY, "Error WSASY"); -#endif -#ifdef WSAEHOSTDOWN +#endif +#ifdef WSAEHOSTDOWN add_errcode("WSAEHOSTDOWN", WSAEHOSTDOWN, "Host is down"); -#endif -#ifdef WSAENETDOWN +#endif +#ifdef WSAENETDOWN add_errcode("WSAENETDOWN", WSAENETDOWN, "Network is down"); -#endif -#ifdef WSAENOTSOCK +#endif +#ifdef WSAENOTSOCK add_errcode("WSAENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket"); -#endif -#ifdef WSAEHOSTUNREACH +#endif +#ifdef WSAEHOSTUNREACH add_errcode("WSAEHOSTUNREACH", WSAEHOSTUNREACH, "No route to host"); -#endif -#ifdef WSAELOOP +#endif +#ifdef WSAELOOP add_errcode("WSAELOOP", WSAELOOP, "Too many symbolic links encountered"); -#endif -#ifdef WSAEMFILE +#endif +#ifdef WSAEMFILE add_errcode("WSAEMFILE", WSAEMFILE, "Too many open files"); -#endif -#ifdef WSAESTALE +#endif +#ifdef WSAESTALE add_errcode("WSAESTALE", WSAESTALE, "Stale NFS file handle"); -#endif -#ifdef WSAVERNOTSUPPORTED +#endif +#ifdef WSAVERNOTSUPPORTED add_errcode("WSAVERNOTSUPPORTED", WSAVERNOTSUPPORTED, "Error WSAVERNOTSUPPORTED"); -#endif -#ifdef WSAENETUNREACH +#endif +#ifdef WSAENETUNREACH add_errcode("WSAENETUNREACH", WSAENETUNREACH, "Network is unreachable"); -#endif -#ifdef WSAEPROCLIM +#endif +#ifdef WSAEPROCLIM add_errcode("WSAEPROCLIM", WSAEPROCLIM, "Error WSAEPROCLIM"); -#endif -#ifdef WSAEFAULT +#endif +#ifdef WSAEFAULT add_errcode("WSAEFAULT", WSAEFAULT, "Bad address"); -#endif -#ifdef WSANOTINITIALISED +#endif +#ifdef WSANOTINITIALISED add_errcode("WSANOTINITIALISED", WSANOTINITIALISED, "Error WSANOTINITIALISED"); -#endif -#ifdef WSAEUSERS +#endif +#ifdef WSAEUSERS add_errcode("WSAEUSERS", WSAEUSERS, "Too many users"); -#endif -#ifdef WSAMAKEASYNCREPL +#endif +#ifdef WSAMAKEASYNCREPL add_errcode("WSAMAKEASYNCREPL", WSAMAKEASYNCREPL, "Error WSAMAKEASYNCREPL"); -#endif -#ifdef WSAENOPROTOOPT +#endif +#ifdef WSAENOPROTOOPT add_errcode("WSAENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available"); -#endif -#ifdef WSAECONNABORTED +#endif +#ifdef WSAECONNABORTED add_errcode("WSAECONNABORTED", WSAECONNABORTED, "Software caused connection abort"); -#endif -#ifdef WSAENAMETOOLONG +#endif +#ifdef WSAENAMETOOLONG add_errcode("WSAENAMETOOLONG", WSAENAMETOOLONG, "File name too long"); -#endif -#ifdef WSAENOTEMPTY +#endif +#ifdef WSAENOTEMPTY add_errcode("WSAENOTEMPTY", WSAENOTEMPTY, "Directory not empty"); -#endif -#ifdef WSAESHUTDOWN +#endif +#ifdef WSAESHUTDOWN add_errcode("WSAESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown"); -#endif -#ifdef WSAEAFNOSUPPORT +#endif +#ifdef WSAEAFNOSUPPORT add_errcode("WSAEAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol"); -#endif -#ifdef WSAETOOMANYREFS +#endif +#ifdef WSAETOOMANYREFS add_errcode("WSAETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice"); -#endif -#ifdef WSAEACCES +#endif +#ifdef WSAEACCES add_errcode("WSAEACCES", WSAEACCES, "Permission denied"); -#endif -#ifdef WSATR +#endif +#ifdef WSATR add_errcode("WSATR", WSATR, "Error WSATR"); -#endif -#ifdef WSABASEERR +#endif +#ifdef WSABASEERR add_errcode("WSABASEERR", WSABASEERR, "Error WSABASEERR"); -#endif -#ifdef WSADESCRIPTIO +#endif +#ifdef WSADESCRIPTIO add_errcode("WSADESCRIPTIO", WSADESCRIPTIO, "Error WSADESCRIPTIO"); -#endif -#ifdef WSAEMSGSIZE +#endif +#ifdef WSAEMSGSIZE add_errcode("WSAEMSGSIZE", WSAEMSGSIZE, "Message too long"); -#endif -#ifdef WSAEBADF +#endif +#ifdef WSAEBADF add_errcode("WSAEBADF", WSAEBADF, "Bad file number"); -#endif -#ifdef WSAECONNRESET +#endif +#ifdef WSAECONNRESET add_errcode("WSAECONNRESET", WSAECONNRESET, "Connection reset by peer"); -#endif -#ifdef WSAGETSELECTERRO +#endif +#ifdef WSAGETSELECTERRO add_errcode("WSAGETSELECTERRO", WSAGETSELECTERRO, "Error WSAGETSELECTERRO"); -#endif -#ifdef WSAETIMEDOUT +#endif +#ifdef WSAETIMEDOUT add_errcode("WSAETIMEDOUT", WSAETIMEDOUT, "Connection timed out"); -#endif -#ifdef WSAENOBUFS +#endif +#ifdef WSAENOBUFS add_errcode("WSAENOBUFS", WSAENOBUFS, "No buffer space available"); -#endif -#ifdef WSAEDISCON +#endif +#ifdef WSAEDISCON add_errcode("WSAEDISCON", WSAEDISCON, "Error WSAEDISCON"); -#endif -#ifdef WSAEINTR +#endif +#ifdef WSAEINTR add_errcode("WSAEINTR", WSAEINTR, "Interrupted system call"); -#endif -#ifdef WSAEPROTOTYPE +#endif +#ifdef WSAEPROTOTYPE add_errcode("WSAEPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket"); -#endif -#ifdef WSAHOS +#endif +#ifdef WSAHOS add_errcode("WSAHOS", WSAHOS, "Error WSAHOS"); -#endif -#ifdef WSAEADDRINUSE +#endif +#ifdef WSAEADDRINUSE add_errcode("WSAEADDRINUSE", WSAEADDRINUSE, "Address already in use"); -#endif -#ifdef WSAEADDRNOTAVAIL +#endif +#ifdef WSAEADDRNOTAVAIL add_errcode("WSAEADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address"); -#endif -#ifdef WSAEALREADY +#endif +#ifdef WSAEALREADY add_errcode("WSAEALREADY", WSAEALREADY, "Operation already in progress"); -#endif -#ifdef WSAEPROTONOSUPPORT +#endif +#ifdef WSAEPROTONOSUPPORT add_errcode("WSAEPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported"); -#endif -#ifdef WSASYSNOTREADY +#endif +#ifdef WSASYSNOTREADY add_errcode("WSASYSNOTREADY", WSASYSNOTREADY, "Error WSASYSNOTREADY"); -#endif -#ifdef WSAEWOULDBLOCK +#endif +#ifdef WSAEWOULDBLOCK add_errcode("WSAEWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block"); -#endif -#ifdef WSAEPFNOSUPPORT +#endif +#ifdef WSAEPFNOSUPPORT add_errcode("WSAEPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported"); -#endif -#ifdef WSAEOPNOTSUPP +#endif +#ifdef WSAEOPNOTSUPP add_errcode("WSAEOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint"); -#endif -#ifdef WSAEISCONN +#endif +#ifdef WSAEISCONN add_errcode("WSAEISCONN", WSAEISCONN, "Transport endpoint is already connected"); -#endif -#ifdef WSAEDQUOT +#endif +#ifdef WSAEDQUOT add_errcode("WSAEDQUOT", WSAEDQUOT, "Quota exceeded"); -#endif -#ifdef WSAENOTCONN +#endif +#ifdef WSAENOTCONN add_errcode("WSAENOTCONN", WSAENOTCONN, "Transport endpoint is not connected"); -#endif -#ifdef WSAEREMOTE +#endif +#ifdef WSAEREMOTE add_errcode("WSAEREMOTE", WSAEREMOTE, "Object is remote"); -#endif -#ifdef WSAEINVAL +#endif +#ifdef WSAEINVAL add_errcode("WSAEINVAL", WSAEINVAL, "Invalid argument"); -#endif -#ifdef WSAEINPROGRESS +#endif +#ifdef WSAEINPROGRESS add_errcode("WSAEINPROGRESS", WSAEINPROGRESS, "Operation now in progress"); -#endif -#ifdef WSAGETSELECTEVEN +#endif +#ifdef WSAGETSELECTEVEN add_errcode("WSAGETSELECTEVEN", WSAGETSELECTEVEN, "Error WSAGETSELECTEVEN"); -#endif -#ifdef WSAESOCKTNOSUPPORT +#endif +#ifdef WSAESOCKTNOSUPPORT add_errcode("WSAESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported"); -#endif -#ifdef WSAGETASYNCERRO +#endif +#ifdef WSAGETASYNCERRO add_errcode("WSAGETASYNCERRO", WSAGETASYNCERRO, "Error WSAGETASYNCERRO"); -#endif -#ifdef WSAMAKESELECTREPL +#endif +#ifdef WSAMAKESELECTREPL add_errcode("WSAMAKESELECTREPL", WSAMAKESELECTREPL, "Error WSAMAKESELECTREPL"); -#endif -#ifdef WSAGETASYNCBUFLE +#endif +#ifdef WSAGETASYNCBUFLE add_errcode("WSAGETASYNCBUFLE", WSAGETASYNCBUFLE, "Error WSAGETASYNCBUFLE"); -#endif -#ifdef WSAEDESTADDRREQ +#endif +#ifdef WSAEDESTADDRREQ add_errcode("WSAEDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required"); -#endif -#ifdef WSAECONNREFUSED +#endif +#ifdef WSAECONNREFUSED add_errcode("WSAECONNREFUSED", WSAECONNREFUSED, "Connection refused"); -#endif -#ifdef WSAENETRESET +#endif +#ifdef WSAENETRESET add_errcode("WSAENETRESET", WSAENETRESET, "Network dropped connection because of reset"); -#endif -#ifdef WSAN +#endif +#ifdef WSAN add_errcode("WSAN", WSAN, "Error WSAN"); -#endif -#ifdef ENOMEDIUM +#endif +#ifdef ENOMEDIUM add_errcode("ENOMEDIUM", ENOMEDIUM, "No medium found"); -#endif -#ifdef EMEDIUMTYPE +#endif +#ifdef EMEDIUMTYPE add_errcode("EMEDIUMTYPE", EMEDIUMTYPE, "Wrong medium type"); -#endif -#ifdef ECANCELED +#endif +#ifdef ECANCELED add_errcode("ECANCELED", ECANCELED, "Operation Canceled"); -#endif -#ifdef ENOKEY +#endif +#ifdef ENOKEY add_errcode("ENOKEY", ENOKEY, "Required key not available"); -#endif -#ifdef EKEYEXPIRED +#endif +#ifdef EKEYEXPIRED add_errcode("EKEYEXPIRED", EKEYEXPIRED, "Key has expired"); -#endif -#ifdef EKEYREVOKED +#endif +#ifdef EKEYREVOKED add_errcode("EKEYREVOKED", EKEYREVOKED, "Key has been revoked"); -#endif -#ifdef EKEYREJECTED +#endif +#ifdef EKEYREJECTED add_errcode("EKEYREJECTED", EKEYREJECTED, "Key was rejected by service"); -#endif -#ifdef EOWNERDEAD +#endif +#ifdef EOWNERDEAD add_errcode("EOWNERDEAD", EOWNERDEAD, "Owner died"); -#endif -#ifdef ENOTRECOVERABLE +#endif +#ifdef ENOTRECOVERABLE add_errcode("ENOTRECOVERABLE", ENOTRECOVERABLE, "State not recoverable"); -#endif -#ifdef ERFKILL +#endif +#ifdef ERFKILL add_errcode("ERFKILL", ERFKILL, "Operation not possible due to RF-kill"); -#endif - - /* Solaris-specific errnos */ -#ifdef ECANCELED +#endif + + /* Solaris-specific errnos */ +#ifdef ECANCELED add_errcode("ECANCELED", ECANCELED, "Operation canceled"); -#endif -#ifdef ENOTSUP +#endif +#ifdef ENOTSUP add_errcode("ENOTSUP", ENOTSUP, "Operation not supported"); -#endif -#ifdef EOWNERDEAD +#endif +#ifdef EOWNERDEAD add_errcode("EOWNERDEAD", EOWNERDEAD, "Process died with the lock"); -#endif -#ifdef ENOTRECOVERABLE +#endif +#ifdef ENOTRECOVERABLE add_errcode("ENOTRECOVERABLE", ENOTRECOVERABLE, "Lock is not recoverable"); -#endif -#ifdef ELOCKUNMAPPED +#endif +#ifdef ELOCKUNMAPPED add_errcode("ELOCKUNMAPPED", ELOCKUNMAPPED, "Locked lock was unmapped"); -#endif -#ifdef ENOTACTIVE +#endif +#ifdef ENOTACTIVE add_errcode("ENOTACTIVE", ENOTACTIVE, "Facility is not active"); -#endif - - /* MacOSX specific errnos */ -#ifdef EAUTH +#endif + + /* MacOSX specific errnos */ +#ifdef EAUTH add_errcode("EAUTH", EAUTH, "Authentication error"); -#endif -#ifdef EBADARCH +#endif +#ifdef EBADARCH add_errcode("EBADARCH", EBADARCH, "Bad CPU type in executable"); -#endif -#ifdef EBADEXEC +#endif +#ifdef EBADEXEC add_errcode("EBADEXEC", EBADEXEC, "Bad executable (or shared library)"); -#endif -#ifdef EBADMACHO +#endif +#ifdef EBADMACHO add_errcode("EBADMACHO", EBADMACHO, "Malformed Mach-o file"); -#endif -#ifdef EBADRPC +#endif +#ifdef EBADRPC add_errcode("EBADRPC", EBADRPC, "RPC struct is bad"); -#endif -#ifdef EDEVERR +#endif +#ifdef EDEVERR add_errcode("EDEVERR", EDEVERR, "Device error"); -#endif -#ifdef EFTYPE +#endif +#ifdef EFTYPE add_errcode("EFTYPE", EFTYPE, "Inappropriate file type or format"); -#endif -#ifdef ENEEDAUTH +#endif +#ifdef ENEEDAUTH add_errcode("ENEEDAUTH", ENEEDAUTH, "Need authenticator"); -#endif -#ifdef ENOATTR +#endif +#ifdef ENOATTR add_errcode("ENOATTR", ENOATTR, "Attribute not found"); -#endif -#ifdef ENOPOLICY +#endif +#ifdef ENOPOLICY add_errcode("ENOPOLICY", ENOPOLICY, "Policy not found"); -#endif -#ifdef EPROCLIM +#endif +#ifdef EPROCLIM add_errcode("EPROCLIM", EPROCLIM, "Too many processes"); -#endif -#ifdef EPROCUNAVAIL +#endif +#ifdef EPROCUNAVAIL add_errcode("EPROCUNAVAIL", EPROCUNAVAIL, "Bad procedure for program"); -#endif -#ifdef EPROGMISMATCH +#endif +#ifdef EPROGMISMATCH add_errcode("EPROGMISMATCH", EPROGMISMATCH, "Program version wrong"); -#endif -#ifdef EPROGUNAVAIL +#endif +#ifdef EPROGUNAVAIL add_errcode("EPROGUNAVAIL", EPROGUNAVAIL, "RPC prog. not avail"); -#endif -#ifdef EPWROFF +#endif +#ifdef EPWROFF add_errcode("EPWROFF", EPWROFF, "Device power is off"); -#endif -#ifdef ERPCMISMATCH +#endif +#ifdef ERPCMISMATCH add_errcode("ERPCMISMATCH", ERPCMISMATCH, "RPC version wrong"); -#endif -#ifdef ESHLIBVERS +#endif +#ifdef ESHLIBVERS add_errcode("ESHLIBVERS", ESHLIBVERS, "Shared library version mismatch"); -#endif - +#endif + Py_DECREF(error_dict); return 0; -} +} static PyModuleDef_Slot errno_slots[] = { {Py_mod_exec, errno_exec}, diff --git a/contrib/tools/python3/src/Modules/faulthandler.c b/contrib/tools/python3/src/Modules/faulthandler.c index e7a28503305..e7dab3b9b2d 100644 --- a/contrib/tools/python3/src/Modules/faulthandler.c +++ b/contrib/tools/python3/src/Modules/faulthandler.c @@ -1,125 +1,125 @@ -#include "Python.h" +#include "Python.h" #include "pycore_initconfig.h" #include "pycore_traceback.h" -#include -#include -#include -#include -#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) -# include -#endif -#ifdef MS_WINDOWS -# include -#endif -#ifdef HAVE_SYS_RESOURCE_H -# include -#endif - -/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ -#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) - -#ifndef MS_WINDOWS - /* register() is useless on Windows, because only SIGSEGV, SIGABRT and - SIGILL can be handled by the process, and these signals can only be used - with enable(), not using register() */ -# define FAULTHANDLER_USER -#endif - -#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) - -_Py_IDENTIFIER(enable); -_Py_IDENTIFIER(fileno); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(stderr); - -#ifdef HAVE_SIGACTION -typedef struct sigaction _Py_sighandler_t; -#else -typedef PyOS_sighandler_t _Py_sighandler_t; -#endif - -typedef struct { - int signum; - int enabled; - const char* name; - _Py_sighandler_t previous; - int all_threads; -} fault_handler_t; - -static struct { - int enabled; - PyObject *file; - int fd; - int all_threads; - PyInterpreterState *interp; -#ifdef MS_WINDOWS - void *exc_handler; -#endif -} fatal_error = {0, NULL, -1, 0}; - -static struct { - PyObject *file; - int fd; - PY_TIMEOUT_T timeout_us; /* timeout in microseconds */ - int repeat; - PyInterpreterState *interp; - int exit; - char *header; - size_t header_len; - /* The main thread always holds this lock. It is only released when - faulthandler_thread() is interrupted before this thread exits, or at - Python exit. */ - PyThread_type_lock cancel_event; - /* released by child thread when joined */ - PyThread_type_lock running; -} thread; - -#ifdef FAULTHANDLER_USER -typedef struct { - int enabled; - PyObject *file; - int fd; - int all_threads; - int chain; - _Py_sighandler_t previous; - PyInterpreterState *interp; -} user_signal_t; - -static user_signal_t *user_signals; - -/* the following macros come from Python: Modules/signalmodule.c */ -#ifndef NSIG -# if defined(_NSIG) -# define NSIG _NSIG /* For BSD/SysV */ -# elif defined(_SIGMAX) -# define NSIG (_SIGMAX + 1) /* For QNX */ -# elif defined(SIGMAX) -# define NSIG (SIGMAX + 1) /* For djgpp */ -# else -# define NSIG 64 /* Use a reasonable default value */ -# endif -#endif - -static void faulthandler_user(int signum); -#endif /* FAULTHANDLER_USER */ - - -static fault_handler_t faulthandler_handlers[] = { -#ifdef SIGBUS - {SIGBUS, 0, "Bus error", }, -#endif -#ifdef SIGILL - {SIGILL, 0, "Illegal instruction", }, -#endif - {SIGFPE, 0, "Floating point exception", }, - {SIGABRT, 0, "Aborted", }, - /* define SIGSEGV at the end to make it the default choice if searching the - handler fails in faulthandler_fatal_error() */ - {SIGSEGV, 0, "Segmentation fault", } -}; -static const size_t faulthandler_nsignals = \ - Py_ARRAY_LENGTH(faulthandler_handlers); - +#include +#include +#include +#include +#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) +# include +#endif +#ifdef MS_WINDOWS +# include +#endif +#ifdef HAVE_SYS_RESOURCE_H +# include +#endif + +/* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ +#define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) + +#ifndef MS_WINDOWS + /* register() is useless on Windows, because only SIGSEGV, SIGABRT and + SIGILL can be handled by the process, and these signals can only be used + with enable(), not using register() */ +# define FAULTHANDLER_USER +#endif + +#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) + +_Py_IDENTIFIER(enable); +_Py_IDENTIFIER(fileno); +_Py_IDENTIFIER(flush); +_Py_IDENTIFIER(stderr); + +#ifdef HAVE_SIGACTION +typedef struct sigaction _Py_sighandler_t; +#else +typedef PyOS_sighandler_t _Py_sighandler_t; +#endif + +typedef struct { + int signum; + int enabled; + const char* name; + _Py_sighandler_t previous; + int all_threads; +} fault_handler_t; + +static struct { + int enabled; + PyObject *file; + int fd; + int all_threads; + PyInterpreterState *interp; +#ifdef MS_WINDOWS + void *exc_handler; +#endif +} fatal_error = {0, NULL, -1, 0}; + +static struct { + PyObject *file; + int fd; + PY_TIMEOUT_T timeout_us; /* timeout in microseconds */ + int repeat; + PyInterpreterState *interp; + int exit; + char *header; + size_t header_len; + /* The main thread always holds this lock. It is only released when + faulthandler_thread() is interrupted before this thread exits, or at + Python exit. */ + PyThread_type_lock cancel_event; + /* released by child thread when joined */ + PyThread_type_lock running; +} thread; + +#ifdef FAULTHANDLER_USER +typedef struct { + int enabled; + PyObject *file; + int fd; + int all_threads; + int chain; + _Py_sighandler_t previous; + PyInterpreterState *interp; +} user_signal_t; + +static user_signal_t *user_signals; + +/* the following macros come from Python: Modules/signalmodule.c */ +#ifndef NSIG +# if defined(_NSIG) +# define NSIG _NSIG /* For BSD/SysV */ +# elif defined(_SIGMAX) +# define NSIG (_SIGMAX + 1) /* For QNX */ +# elif defined(SIGMAX) +# define NSIG (SIGMAX + 1) /* For djgpp */ +# else +# define NSIG 64 /* Use a reasonable default value */ +# endif +#endif + +static void faulthandler_user(int signum); +#endif /* FAULTHANDLER_USER */ + + +static fault_handler_t faulthandler_handlers[] = { +#ifdef SIGBUS + {SIGBUS, 0, "Bus error", }, +#endif +#ifdef SIGILL + {SIGILL, 0, "Illegal instruction", }, +#endif + {SIGFPE, 0, "Floating point exception", }, + {SIGABRT, 0, "Aborted", }, + /* define SIGSEGV at the end to make it the default choice if searching the + handler fails in faulthandler_fatal_error() */ + {SIGSEGV, 0, "Segmentation fault", } +}; +static const size_t faulthandler_nsignals = \ + Py_ARRAY_LENGTH(faulthandler_handlers); + /* Using an alternative stack requires sigaltstack() and sigaction() SA_ONSTACK */ #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) @@ -127,307 +127,307 @@ static const size_t faulthandler_nsignals = \ #endif #ifdef FAULTHANDLER_USE_ALT_STACK -static stack_t stack; -static stack_t old_stack; -#endif - - -/* Get the file descriptor of a file by calling its fileno() method and then - call its flush() method. - - If file is NULL or Py_None, use sys.stderr as the new file. - If file is an integer, it will be treated as file descriptor. - - On success, return the file descriptor and write the new file into *file_ptr. - On error, return -1. */ - -static int -faulthandler_get_fileno(PyObject **file_ptr) -{ - PyObject *result; - long fd_long; - int fd; - PyObject *file = *file_ptr; - - if (file == NULL || file == Py_None) { - file = _PySys_GetObjectId(&PyId_stderr); - if (file == NULL) { - PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr"); - return -1; - } - if (file == Py_None) { - PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None"); - return -1; - } - } - else if (PyLong_Check(file)) { - fd = _PyLong_AsInt(file); - if (fd == -1 && PyErr_Occurred()) - return -1; - if (fd < 0) { - PyErr_SetString(PyExc_ValueError, - "file is not a valid file descripter"); - return -1; - } - *file_ptr = NULL; - return fd; - } - +static stack_t stack; +static stack_t old_stack; +#endif + + +/* Get the file descriptor of a file by calling its fileno() method and then + call its flush() method. + + If file is NULL or Py_None, use sys.stderr as the new file. + If file is an integer, it will be treated as file descriptor. + + On success, return the file descriptor and write the new file into *file_ptr. + On error, return -1. */ + +static int +faulthandler_get_fileno(PyObject **file_ptr) +{ + PyObject *result; + long fd_long; + int fd; + PyObject *file = *file_ptr; + + if (file == NULL || file == Py_None) { + file = _PySys_GetObjectId(&PyId_stderr); + if (file == NULL) { + PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr"); + return -1; + } + if (file == Py_None) { + PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None"); + return -1; + } + } + else if (PyLong_Check(file)) { + fd = _PyLong_AsInt(file); + if (fd == -1 && PyErr_Occurred()) + return -1; + if (fd < 0) { + PyErr_SetString(PyExc_ValueError, + "file is not a valid file descripter"); + return -1; + } + *file_ptr = NULL; + return fd; + } + result = _PyObject_CallMethodIdNoArgs(file, &PyId_fileno); - if (result == NULL) - return -1; - - fd = -1; - if (PyLong_Check(result)) { - fd_long = PyLong_AsLong(result); - if (0 <= fd_long && fd_long < INT_MAX) - fd = (int)fd_long; - } - Py_DECREF(result); - - if (fd == -1) { - PyErr_SetString(PyExc_RuntimeError, - "file.fileno() is not a valid file descriptor"); - return -1; - } - + if (result == NULL) + return -1; + + fd = -1; + if (PyLong_Check(result)) { + fd_long = PyLong_AsLong(result); + if (0 <= fd_long && fd_long < INT_MAX) + fd = (int)fd_long; + } + Py_DECREF(result); + + if (fd == -1) { + PyErr_SetString(PyExc_RuntimeError, + "file.fileno() is not a valid file descriptor"); + return -1; + } + result = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); - if (result != NULL) - Py_DECREF(result); - else { - /* ignore flush() error */ - PyErr_Clear(); - } - *file_ptr = file; - return fd; -} - -/* Get the state of the current thread: only call this function if the current - thread holds the GIL. Raise an exception on error. */ -static PyThreadState* -get_thread_state(void) -{ - PyThreadState *tstate = _PyThreadState_UncheckedGet(); - if (tstate == NULL) { - /* just in case but very unlikely... */ - PyErr_SetString(PyExc_RuntimeError, - "unable to get the current thread state"); - return NULL; - } - return tstate; -} - -static void -faulthandler_dump_traceback(int fd, int all_threads, - PyInterpreterState *interp) -{ - static volatile int reentrant = 0; - PyThreadState *tstate; - - if (reentrant) - return; - - reentrant = 1; - - /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and - are thus delivered to the thread that caused the fault. Get the Python - thread state of the current thread. - - PyThreadState_Get() doesn't give the state of the thread that caused the - fault if the thread released the GIL, and so this function cannot be - used. Read the thread specific storage (TSS) instead: call - PyGILState_GetThisThreadState(). */ - tstate = PyGILState_GetThisThreadState(); - - if (all_threads) { - (void)_Py_DumpTracebackThreads(fd, NULL, tstate); - } - else { - if (tstate != NULL) - _Py_DumpTraceback(fd, tstate); - } - - reentrant = 0; -} - -static PyObject* -faulthandler_dump_traceback_py(PyObject *self, - PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"file", "all_threads", NULL}; - PyObject *file = NULL; - int all_threads = 1; - PyThreadState *tstate; - const char *errmsg; - int fd; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|Oi:dump_traceback", kwlist, - &file, &all_threads)) - return NULL; - - fd = faulthandler_get_fileno(&file); - if (fd < 0) - return NULL; - - tstate = get_thread_state(); - if (tstate == NULL) - return NULL; - - if (all_threads) { - errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate); - if (errmsg != NULL) { - PyErr_SetString(PyExc_RuntimeError, errmsg); - return NULL; - } - } - else { - _Py_DumpTraceback(fd, tstate); - } - - if (PyErr_CheckSignals()) - return NULL; - - Py_RETURN_NONE; -} - -static void -faulthandler_disable_fatal_handler(fault_handler_t *handler) -{ - if (!handler->enabled) - return; - handler->enabled = 0; -#ifdef HAVE_SIGACTION - (void)sigaction(handler->signum, &handler->previous, NULL); -#else - (void)signal(handler->signum, handler->previous); -#endif -} - - -/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals. - - Display the current Python traceback, restore the previous handler and call - the previous handler. - - On Windows, don't explicitly call the previous handler, because the Windows - signal handler would not be called (for an unknown reason). The execution of - the program continues at faulthandler_fatal_error() exit, but the same - instruction will raise the same fault (signal), and so the previous handler - will be called. - - This function is signal-safe and should only call signal-safe functions. */ - -static void -faulthandler_fatal_error(int signum) -{ - const int fd = fatal_error.fd; - size_t i; - fault_handler_t *handler = NULL; - int save_errno = errno; - - if (!fatal_error.enabled) - return; - - for (i=0; i < faulthandler_nsignals; i++) { - handler = &faulthandler_handlers[i]; - if (handler->signum == signum) - break; - } - if (handler == NULL) { - /* faulthandler_nsignals == 0 (unlikely) */ - return; - } - - /* restore the previous handler */ - faulthandler_disable_fatal_handler(handler); - - PUTS(fd, "Fatal Python error: "); - PUTS(fd, handler->name); - PUTS(fd, "\n\n"); - - faulthandler_dump_traceback(fd, fatal_error.all_threads, - fatal_error.interp); - - errno = save_errno; -#ifdef MS_WINDOWS - if (signum == SIGSEGV) { - /* don't explicitly call the previous handler for SIGSEGV in this signal - handler, because the Windows signal handler would not be called */ - return; - } -#endif - /* call the previous signal handler: it is called immediately if we use - sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */ - raise(signum); -} - -#ifdef MS_WINDOWS -static int -faulthandler_ignore_exception(DWORD code) -{ - /* bpo-30557: ignore exceptions which are not errors */ - if (!(code & 0x80000000)) { - return 1; - } - /* bpo-31701: ignore MSC and COM exceptions - E0000000 + code */ - if (code == 0xE06D7363 /* MSC exception ("Emsc") */ - || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) { - return 1; - } - /* Interesting exception: log it with the Python traceback */ - return 0; -} - -static LONG WINAPI -faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) -{ - const int fd = fatal_error.fd; - DWORD code = exc_info->ExceptionRecord->ExceptionCode; - DWORD flags = exc_info->ExceptionRecord->ExceptionFlags; - - if (faulthandler_ignore_exception(code)) { - /* ignore the exception: call the next exception handler */ - return EXCEPTION_CONTINUE_SEARCH; - } - - PUTS(fd, "Windows fatal exception: "); - switch (code) - { - /* only format most common errors */ - case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break; - case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break; - case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break; - case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break; - case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break; - case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break; - default: - PUTS(fd, "code 0x"); - _Py_DumpHexadecimal(fd, code, 8); - } - PUTS(fd, "\n\n"); - - if (code == EXCEPTION_ACCESS_VIOLATION) { - /* disable signal handler for SIGSEGV */ - for (size_t i=0; i < faulthandler_nsignals; i++) { - fault_handler_t *handler = &faulthandler_handlers[i]; - if (handler->signum == SIGSEGV) { - faulthandler_disable_fatal_handler(handler); - break; - } - } - } - - faulthandler_dump_traceback(fd, fatal_error.all_threads, - fatal_error.interp); - - /* call the next exception handler */ - return EXCEPTION_CONTINUE_SEARCH; -} -#endif - + if (result != NULL) + Py_DECREF(result); + else { + /* ignore flush() error */ + PyErr_Clear(); + } + *file_ptr = file; + return fd; +} + +/* Get the state of the current thread: only call this function if the current + thread holds the GIL. Raise an exception on error. */ +static PyThreadState* +get_thread_state(void) +{ + PyThreadState *tstate = _PyThreadState_UncheckedGet(); + if (tstate == NULL) { + /* just in case but very unlikely... */ + PyErr_SetString(PyExc_RuntimeError, + "unable to get the current thread state"); + return NULL; + } + return tstate; +} + +static void +faulthandler_dump_traceback(int fd, int all_threads, + PyInterpreterState *interp) +{ + static volatile int reentrant = 0; + PyThreadState *tstate; + + if (reentrant) + return; + + reentrant = 1; + + /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and + are thus delivered to the thread that caused the fault. Get the Python + thread state of the current thread. + + PyThreadState_Get() doesn't give the state of the thread that caused the + fault if the thread released the GIL, and so this function cannot be + used. Read the thread specific storage (TSS) instead: call + PyGILState_GetThisThreadState(). */ + tstate = PyGILState_GetThisThreadState(); + + if (all_threads) { + (void)_Py_DumpTracebackThreads(fd, NULL, tstate); + } + else { + if (tstate != NULL) + _Py_DumpTraceback(fd, tstate); + } + + reentrant = 0; +} + +static PyObject* +faulthandler_dump_traceback_py(PyObject *self, + PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"file", "all_threads", NULL}; + PyObject *file = NULL; + int all_threads = 1; + PyThreadState *tstate; + const char *errmsg; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|Oi:dump_traceback", kwlist, + &file, &all_threads)) + return NULL; + + fd = faulthandler_get_fileno(&file); + if (fd < 0) + return NULL; + + tstate = get_thread_state(); + if (tstate == NULL) + return NULL; + + if (all_threads) { + errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate); + if (errmsg != NULL) { + PyErr_SetString(PyExc_RuntimeError, errmsg); + return NULL; + } + } + else { + _Py_DumpTraceback(fd, tstate); + } + + if (PyErr_CheckSignals()) + return NULL; + + Py_RETURN_NONE; +} + +static void +faulthandler_disable_fatal_handler(fault_handler_t *handler) +{ + if (!handler->enabled) + return; + handler->enabled = 0; +#ifdef HAVE_SIGACTION + (void)sigaction(handler->signum, &handler->previous, NULL); +#else + (void)signal(handler->signum, handler->previous); +#endif +} + + +/* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals. + + Display the current Python traceback, restore the previous handler and call + the previous handler. + + On Windows, don't explicitly call the previous handler, because the Windows + signal handler would not be called (for an unknown reason). The execution of + the program continues at faulthandler_fatal_error() exit, but the same + instruction will raise the same fault (signal), and so the previous handler + will be called. + + This function is signal-safe and should only call signal-safe functions. */ + +static void +faulthandler_fatal_error(int signum) +{ + const int fd = fatal_error.fd; + size_t i; + fault_handler_t *handler = NULL; + int save_errno = errno; + + if (!fatal_error.enabled) + return; + + for (i=0; i < faulthandler_nsignals; i++) { + handler = &faulthandler_handlers[i]; + if (handler->signum == signum) + break; + } + if (handler == NULL) { + /* faulthandler_nsignals == 0 (unlikely) */ + return; + } + + /* restore the previous handler */ + faulthandler_disable_fatal_handler(handler); + + PUTS(fd, "Fatal Python error: "); + PUTS(fd, handler->name); + PUTS(fd, "\n\n"); + + faulthandler_dump_traceback(fd, fatal_error.all_threads, + fatal_error.interp); + + errno = save_errno; +#ifdef MS_WINDOWS + if (signum == SIGSEGV) { + /* don't explicitly call the previous handler for SIGSEGV in this signal + handler, because the Windows signal handler would not be called */ + return; + } +#endif + /* call the previous signal handler: it is called immediately if we use + sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */ + raise(signum); +} + +#ifdef MS_WINDOWS +static int +faulthandler_ignore_exception(DWORD code) +{ + /* bpo-30557: ignore exceptions which are not errors */ + if (!(code & 0x80000000)) { + return 1; + } + /* bpo-31701: ignore MSC and COM exceptions + E0000000 + code */ + if (code == 0xE06D7363 /* MSC exception ("Emsc") */ + || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) { + return 1; + } + /* Interesting exception: log it with the Python traceback */ + return 0; +} + +static LONG WINAPI +faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info) +{ + const int fd = fatal_error.fd; + DWORD code = exc_info->ExceptionRecord->ExceptionCode; + DWORD flags = exc_info->ExceptionRecord->ExceptionFlags; + + if (faulthandler_ignore_exception(code)) { + /* ignore the exception: call the next exception handler */ + return EXCEPTION_CONTINUE_SEARCH; + } + + PUTS(fd, "Windows fatal exception: "); + switch (code) + { + /* only format most common errors */ + case EXCEPTION_ACCESS_VIOLATION: PUTS(fd, "access violation"); break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: PUTS(fd, "float divide by zero"); break; + case EXCEPTION_FLT_OVERFLOW: PUTS(fd, "float overflow"); break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: PUTS(fd, "int divide by zero"); break; + case EXCEPTION_INT_OVERFLOW: PUTS(fd, "integer overflow"); break; + case EXCEPTION_IN_PAGE_ERROR: PUTS(fd, "page error"); break; + case EXCEPTION_STACK_OVERFLOW: PUTS(fd, "stack overflow"); break; + default: + PUTS(fd, "code 0x"); + _Py_DumpHexadecimal(fd, code, 8); + } + PUTS(fd, "\n\n"); + + if (code == EXCEPTION_ACCESS_VIOLATION) { + /* disable signal handler for SIGSEGV */ + for (size_t i=0; i < faulthandler_nsignals; i++) { + fault_handler_t *handler = &faulthandler_handlers[i]; + if (handler->signum == SIGSEGV) { + faulthandler_disable_fatal_handler(handler); + break; + } + } + } + + faulthandler_dump_traceback(fd, fatal_error.all_threads, + fatal_error.interp); + + /* call the next exception handler */ + return EXCEPTION_CONTINUE_SEARCH; +} +#endif + #ifdef FAULTHANDLER_USE_ALT_STACK static int @@ -458,270 +458,270 @@ faulthandler_allocate_stack(void) #endif -/* Install the handler for fatal signals, faulthandler_fatal_error(). */ - -static int -faulthandler_enable(void) -{ - if (fatal_error.enabled) { - return 0; - } - fatal_error.enabled = 1; - +/* Install the handler for fatal signals, faulthandler_fatal_error(). */ + +static int +faulthandler_enable(void) +{ + if (fatal_error.enabled) { + return 0; + } + fatal_error.enabled = 1; + #ifdef FAULTHANDLER_USE_ALT_STACK if (faulthandler_allocate_stack() < 0) { return -1; } #endif - for (size_t i=0; i < faulthandler_nsignals; i++) { - fault_handler_t *handler; - int err; - - handler = &faulthandler_handlers[i]; - assert(!handler->enabled); -#ifdef HAVE_SIGACTION + for (size_t i=0; i < faulthandler_nsignals; i++) { + fault_handler_t *handler; + int err; + + handler = &faulthandler_handlers[i]; + assert(!handler->enabled); +#ifdef HAVE_SIGACTION struct sigaction action; - action.sa_handler = faulthandler_fatal_error; - sigemptyset(&action.sa_mask); - /* Do not prevent the signal from being received from within - its own signal handler */ - action.sa_flags = SA_NODEFER; + action.sa_handler = faulthandler_fatal_error; + sigemptyset(&action.sa_mask); + /* Do not prevent the signal from being received from within + its own signal handler */ + action.sa_flags = SA_NODEFER; #ifdef FAULTHANDLER_USE_ALT_STACK assert(stack.ss_sp != NULL); /* Call the signal handler on an alternate signal stack provided by sigaltstack() */ action.sa_flags |= SA_ONSTACK; -#endif - err = sigaction(handler->signum, &action, &handler->previous); -#else - handler->previous = signal(handler->signum, +#endif + err = sigaction(handler->signum, &action, &handler->previous); +#else + handler->previous = signal(handler->signum, faulthandler_fatal_error); - err = (handler->previous == SIG_ERR); -#endif - if (err) { - PyErr_SetFromErrno(PyExc_RuntimeError); - return -1; - } - - handler->enabled = 1; - } - -#ifdef MS_WINDOWS - assert(fatal_error.exc_handler == NULL); - fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler); -#endif - return 0; -} - -static PyObject* -faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"file", "all_threads", NULL}; - PyObject *file = NULL; - int all_threads = 1; - int fd; - PyThreadState *tstate; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|Oi:enable", kwlist, &file, &all_threads)) - return NULL; - - fd = faulthandler_get_fileno(&file); - if (fd < 0) - return NULL; - - tstate = get_thread_state(); - if (tstate == NULL) - return NULL; - - Py_XINCREF(file); - Py_XSETREF(fatal_error.file, file); - fatal_error.fd = fd; - fatal_error.all_threads = all_threads; + err = (handler->previous == SIG_ERR); +#endif + if (err) { + PyErr_SetFromErrno(PyExc_RuntimeError); + return -1; + } + + handler->enabled = 1; + } + +#ifdef MS_WINDOWS + assert(fatal_error.exc_handler == NULL); + fatal_error.exc_handler = AddVectoredExceptionHandler(1, faulthandler_exc_handler); +#endif + return 0; +} + +static PyObject* +faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"file", "all_threads", NULL}; + PyObject *file = NULL; + int all_threads = 1; + int fd; + PyThreadState *tstate; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|Oi:enable", kwlist, &file, &all_threads)) + return NULL; + + fd = faulthandler_get_fileno(&file); + if (fd < 0) + return NULL; + + tstate = get_thread_state(); + if (tstate == NULL) + return NULL; + + Py_XINCREF(file); + Py_XSETREF(fatal_error.file, file); + fatal_error.fd = fd; + fatal_error.all_threads = all_threads; fatal_error.interp = PyThreadState_GetInterpreter(tstate); - - if (faulthandler_enable() < 0) { - return NULL; - } - - Py_RETURN_NONE; -} - -static void -faulthandler_disable(void) -{ - if (fatal_error.enabled) { - fatal_error.enabled = 0; - for (size_t i=0; i < faulthandler_nsignals; i++) { - fault_handler_t *handler; - handler = &faulthandler_handlers[i]; - faulthandler_disable_fatal_handler(handler); - } - } -#ifdef MS_WINDOWS - if (fatal_error.exc_handler != NULL) { - RemoveVectoredExceptionHandler(fatal_error.exc_handler); - fatal_error.exc_handler = NULL; - } -#endif - Py_CLEAR(fatal_error.file); -} - -static PyObject* + + if (faulthandler_enable() < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +static void +faulthandler_disable(void) +{ + if (fatal_error.enabled) { + fatal_error.enabled = 0; + for (size_t i=0; i < faulthandler_nsignals; i++) { + fault_handler_t *handler; + handler = &faulthandler_handlers[i]; + faulthandler_disable_fatal_handler(handler); + } + } +#ifdef MS_WINDOWS + if (fatal_error.exc_handler != NULL) { + RemoveVectoredExceptionHandler(fatal_error.exc_handler); + fatal_error.exc_handler = NULL; + } +#endif + Py_CLEAR(fatal_error.file); +} + +static PyObject* faulthandler_disable_py(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - if (!fatal_error.enabled) { - Py_RETURN_FALSE; - } - faulthandler_disable(); - Py_RETURN_TRUE; -} - -static PyObject* +{ + if (!fatal_error.enabled) { + Py_RETURN_FALSE; + } + faulthandler_disable(); + Py_RETURN_TRUE; +} + +static PyObject* faulthandler_is_enabled(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return PyBool_FromLong(fatal_error.enabled); -} - -static void -faulthandler_thread(void *unused) -{ - PyLockStatus st; - const char* errmsg; - int ok; -#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) - sigset_t set; - - /* we don't want to receive any signal */ - sigfillset(&set); - pthread_sigmask(SIG_SETMASK, &set, NULL); -#endif - - do { - st = PyThread_acquire_lock_timed(thread.cancel_event, - thread.timeout_us, 0); - if (st == PY_LOCK_ACQUIRED) { - PyThread_release_lock(thread.cancel_event); - break; - } - /* Timeout => dump traceback */ - assert(st == PY_LOCK_FAILURE); - - _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len); - - errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL); - ok = (errmsg == NULL); - - if (thread.exit) - _exit(1); - } while (ok && thread.repeat); - - /* The only way out */ - PyThread_release_lock(thread.running); -} - -static void -cancel_dump_traceback_later(void) -{ +{ + return PyBool_FromLong(fatal_error.enabled); +} + +static void +faulthandler_thread(void *unused) +{ + PyLockStatus st; + const char* errmsg; + int ok; +#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) + sigset_t set; + + /* we don't want to receive any signal */ + sigfillset(&set); + pthread_sigmask(SIG_SETMASK, &set, NULL); +#endif + + do { + st = PyThread_acquire_lock_timed(thread.cancel_event, + thread.timeout_us, 0); + if (st == PY_LOCK_ACQUIRED) { + PyThread_release_lock(thread.cancel_event); + break; + } + /* Timeout => dump traceback */ + assert(st == PY_LOCK_FAILURE); + + _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len); + + errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, NULL); + ok = (errmsg == NULL); + + if (thread.exit) + _exit(1); + } while (ok && thread.repeat); + + /* The only way out */ + PyThread_release_lock(thread.running); +} + +static void +cancel_dump_traceback_later(void) +{ /* If not scheduled, nothing to cancel */ if (!thread.cancel_event) { return; } - /* Notify cancellation */ - PyThread_release_lock(thread.cancel_event); - - /* Wait for thread to join */ - PyThread_acquire_lock(thread.running, 1); - PyThread_release_lock(thread.running); - - /* The main thread should always hold the cancel_event lock */ - PyThread_acquire_lock(thread.cancel_event, 1); - - Py_CLEAR(thread.file); - if (thread.header) { - PyMem_Free(thread.header); - thread.header = NULL; - } -} - -#define SEC_TO_US (1000 * 1000) - -static char* -format_timeout(_PyTime_t us) -{ - unsigned long sec, min, hour; - char buffer[100]; - - /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */ - sec = (unsigned long)(us / SEC_TO_US); - us %= SEC_TO_US; - - min = sec / 60; - sec %= 60; - hour = min / 60; - min %= 60; - - if (us != 0) { - PyOS_snprintf(buffer, sizeof(buffer), - "Timeout (%lu:%02lu:%02lu.%06u)!\n", - hour, min, sec, (unsigned int)us); - } - else { - PyOS_snprintf(buffer, sizeof(buffer), - "Timeout (%lu:%02lu:%02lu)!\n", - hour, min, sec); - } - return _PyMem_Strdup(buffer); -} - -static PyObject* -faulthandler_dump_traceback_later(PyObject *self, - PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL}; - PyObject *timeout_obj; - _PyTime_t timeout, timeout_us; - int repeat = 0; - PyObject *file = NULL; - int fd; - int exit = 0; - PyThreadState *tstate; - char *header; - size_t header_len; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|iOi:dump_traceback_later", kwlist, - &timeout_obj, &repeat, &file, &exit)) - return NULL; - - if (_PyTime_FromSecondsObject(&timeout, timeout_obj, - _PyTime_ROUND_TIMEOUT) < 0) { - return NULL; - } - timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT); - if (timeout_us <= 0) { - PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0"); - return NULL; - } - /* Limit to LONG_MAX seconds for format_timeout() */ - if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) { - PyErr_SetString(PyExc_OverflowError, - "timeout value is too large"); - return NULL; - } - - tstate = get_thread_state(); + /* Notify cancellation */ + PyThread_release_lock(thread.cancel_event); + + /* Wait for thread to join */ + PyThread_acquire_lock(thread.running, 1); + PyThread_release_lock(thread.running); + + /* The main thread should always hold the cancel_event lock */ + PyThread_acquire_lock(thread.cancel_event, 1); + + Py_CLEAR(thread.file); + if (thread.header) { + PyMem_Free(thread.header); + thread.header = NULL; + } +} + +#define SEC_TO_US (1000 * 1000) + +static char* +format_timeout(_PyTime_t us) +{ + unsigned long sec, min, hour; + char buffer[100]; + + /* the downcast is safe: the caller check that 0 < us <= LONG_MAX */ + sec = (unsigned long)(us / SEC_TO_US); + us %= SEC_TO_US; + + min = sec / 60; + sec %= 60; + hour = min / 60; + min %= 60; + + if (us != 0) { + PyOS_snprintf(buffer, sizeof(buffer), + "Timeout (%lu:%02lu:%02lu.%06u)!\n", + hour, min, sec, (unsigned int)us); + } + else { + PyOS_snprintf(buffer, sizeof(buffer), + "Timeout (%lu:%02lu:%02lu)!\n", + hour, min, sec); + } + return _PyMem_Strdup(buffer); +} + +static PyObject* +faulthandler_dump_traceback_later(PyObject *self, + PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL}; + PyObject *timeout_obj; + _PyTime_t timeout, timeout_us; + int repeat = 0; + PyObject *file = NULL; + int fd; + int exit = 0; + PyThreadState *tstate; + char *header; + size_t header_len; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|iOi:dump_traceback_later", kwlist, + &timeout_obj, &repeat, &file, &exit)) + return NULL; + + if (_PyTime_FromSecondsObject(&timeout, timeout_obj, + _PyTime_ROUND_TIMEOUT) < 0) { + return NULL; + } + timeout_us = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_TIMEOUT); + if (timeout_us <= 0) { + PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0"); + return NULL; + } + /* Limit to LONG_MAX seconds for format_timeout() */ + if (timeout_us >= PY_TIMEOUT_MAX || timeout_us / SEC_TO_US >= LONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "timeout value is too large"); + return NULL; + } + + tstate = get_thread_state(); if (tstate == NULL) { - return NULL; + return NULL; } - - fd = faulthandler_get_fileno(&file); + + fd = faulthandler_get_fileno(&file); if (fd < 0) { - return NULL; + return NULL; } - + if (!thread.running) { thread.running = PyThread_allocate_lock(); if (!thread.running) { @@ -739,438 +739,438 @@ faulthandler_dump_traceback_later(PyObject *self, PyThread_acquire_lock(thread.cancel_event, 1); } - /* format the timeout */ - header = format_timeout(timeout_us); + /* format the timeout */ + header = format_timeout(timeout_us); if (header == NULL) { - return PyErr_NoMemory(); - } - header_len = strlen(header); - - /* Cancel previous thread, if running */ - cancel_dump_traceback_later(); - - Py_XINCREF(file); - Py_XSETREF(thread.file, file); - thread.fd = fd; - /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */ - thread.timeout_us = (PY_TIMEOUT_T)timeout_us; - thread.repeat = repeat; + return PyErr_NoMemory(); + } + header_len = strlen(header); + + /* Cancel previous thread, if running */ + cancel_dump_traceback_later(); + + Py_XINCREF(file); + Py_XSETREF(thread.file, file); + thread.fd = fd; + /* the downcast is safe: we check that 0 < timeout_us < PY_TIMEOUT_MAX */ + thread.timeout_us = (PY_TIMEOUT_T)timeout_us; + thread.repeat = repeat; thread.interp = PyThreadState_GetInterpreter(tstate); - thread.exit = exit; - thread.header = header; - thread.header_len = header_len; - - /* Arm these locks to serve as events when released */ - PyThread_acquire_lock(thread.running, 1); - - if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) { - PyThread_release_lock(thread.running); - Py_CLEAR(thread.file); - PyMem_Free(header); - thread.header = NULL; - PyErr_SetString(PyExc_RuntimeError, - "unable to start watchdog thread"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject* + thread.exit = exit; + thread.header = header; + thread.header_len = header_len; + + /* Arm these locks to serve as events when released */ + PyThread_acquire_lock(thread.running, 1); + + if (PyThread_start_new_thread(faulthandler_thread, NULL) == PYTHREAD_INVALID_THREAD_ID) { + PyThread_release_lock(thread.running); + Py_CLEAR(thread.file); + PyMem_Free(header); + thread.header = NULL; + PyErr_SetString(PyExc_RuntimeError, + "unable to start watchdog thread"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject* faulthandler_cancel_dump_traceback_later_py(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - cancel_dump_traceback_later(); - Py_RETURN_NONE; -} - - -#ifdef FAULTHANDLER_USER -static int +{ + cancel_dump_traceback_later(); + Py_RETURN_NONE; +} + + +#ifdef FAULTHANDLER_USER +static int faulthandler_register(int signum, int chain, _Py_sighandler_t *previous_p) -{ -#ifdef HAVE_SIGACTION - struct sigaction action; - action.sa_handler = faulthandler_user; - sigemptyset(&action.sa_mask); - /* if the signal is received while the kernel is executing a system - call, try to restart the system call instead of interrupting it and - return EINTR. */ - action.sa_flags = SA_RESTART; - if (chain) { - /* do not prevent the signal from being received from within its - own signal handler */ - action.sa_flags = SA_NODEFER; - } +{ +#ifdef HAVE_SIGACTION + struct sigaction action; + action.sa_handler = faulthandler_user; + sigemptyset(&action.sa_mask); + /* if the signal is received while the kernel is executing a system + call, try to restart the system call instead of interrupting it and + return EINTR. */ + action.sa_flags = SA_RESTART; + if (chain) { + /* do not prevent the signal from being received from within its + own signal handler */ + action.sa_flags = SA_NODEFER; + } #ifdef FAULTHANDLER_USE_ALT_STACK assert(stack.ss_sp != NULL); /* Call the signal handler on an alternate signal stack provided by sigaltstack() */ action.sa_flags |= SA_ONSTACK; -#endif +#endif return sigaction(signum, &action, previous_p); -#else - _Py_sighandler_t previous; - previous = signal(signum, faulthandler_user); +#else + _Py_sighandler_t previous; + previous = signal(signum, faulthandler_user); if (previous_p != NULL) { *previous_p = previous; } - return (previous == SIG_ERR); -#endif -} - -/* Handler of user signals (e.g. SIGUSR1). - - Dump the traceback of the current thread, or of all threads if - thread.all_threads is true. - - This function is signal safe and should only call signal safe functions. */ - -static void -faulthandler_user(int signum) -{ - user_signal_t *user; - int save_errno = errno; - - user = &user_signals[signum]; - if (!user->enabled) - return; - - faulthandler_dump_traceback(user->fd, user->all_threads, user->interp); - -#ifdef HAVE_SIGACTION - if (user->chain) { - (void)sigaction(signum, &user->previous, NULL); - errno = save_errno; - - /* call the previous signal handler */ - raise(signum); - - save_errno = errno; - (void)faulthandler_register(signum, user->chain, NULL); - errno = save_errno; - } -#else - if (user->chain) { - errno = save_errno; - /* call the previous signal handler */ - user->previous(signum); - } -#endif -} - -static int -check_signum(int signum) -{ - for (size_t i=0; i < faulthandler_nsignals; i++) { - if (faulthandler_handlers[i].signum == signum) { - PyErr_Format(PyExc_RuntimeError, - "signal %i cannot be registered, " - "use enable() instead", - signum); - return 0; - } - } - if (signum < 1 || NSIG <= signum) { - PyErr_SetString(PyExc_ValueError, "signal number out of range"); - return 0; - } - return 1; -} - -static PyObject* -faulthandler_register_py(PyObject *self, - PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL}; - int signum; - PyObject *file = NULL; - int all_threads = 1; - int chain = 0; - int fd; - user_signal_t *user; - _Py_sighandler_t previous; - PyThreadState *tstate; - int err; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "i|Oii:register", kwlist, - &signum, &file, &all_threads, &chain)) - return NULL; - - if (!check_signum(signum)) - return NULL; - - tstate = get_thread_state(); - if (tstate == NULL) - return NULL; - - fd = faulthandler_get_fileno(&file); - if (fd < 0) - return NULL; - - if (user_signals == NULL) { + return (previous == SIG_ERR); +#endif +} + +/* Handler of user signals (e.g. SIGUSR1). + + Dump the traceback of the current thread, or of all threads if + thread.all_threads is true. + + This function is signal safe and should only call signal safe functions. */ + +static void +faulthandler_user(int signum) +{ + user_signal_t *user; + int save_errno = errno; + + user = &user_signals[signum]; + if (!user->enabled) + return; + + faulthandler_dump_traceback(user->fd, user->all_threads, user->interp); + +#ifdef HAVE_SIGACTION + if (user->chain) { + (void)sigaction(signum, &user->previous, NULL); + errno = save_errno; + + /* call the previous signal handler */ + raise(signum); + + save_errno = errno; + (void)faulthandler_register(signum, user->chain, NULL); + errno = save_errno; + } +#else + if (user->chain) { + errno = save_errno; + /* call the previous signal handler */ + user->previous(signum); + } +#endif +} + +static int +check_signum(int signum) +{ + for (size_t i=0; i < faulthandler_nsignals; i++) { + if (faulthandler_handlers[i].signum == signum) { + PyErr_Format(PyExc_RuntimeError, + "signal %i cannot be registered, " + "use enable() instead", + signum); + return 0; + } + } + if (signum < 1 || NSIG <= signum) { + PyErr_SetString(PyExc_ValueError, "signal number out of range"); + return 0; + } + return 1; +} + +static PyObject* +faulthandler_register_py(PyObject *self, + PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL}; + int signum; + PyObject *file = NULL; + int all_threads = 1; + int chain = 0; + int fd; + user_signal_t *user; + _Py_sighandler_t previous; + PyThreadState *tstate; + int err; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i|Oii:register", kwlist, + &signum, &file, &all_threads, &chain)) + return NULL; + + if (!check_signum(signum)) + return NULL; + + tstate = get_thread_state(); + if (tstate == NULL) + return NULL; + + fd = faulthandler_get_fileno(&file); + if (fd < 0) + return NULL; + + if (user_signals == NULL) { user_signals = PyMem_Calloc(NSIG, sizeof(user_signal_t)); - if (user_signals == NULL) - return PyErr_NoMemory(); - } - user = &user_signals[signum]; - - if (!user->enabled) { + if (user_signals == NULL) + return PyErr_NoMemory(); + } + user = &user_signals[signum]; + + if (!user->enabled) { #ifdef FAULTHANDLER_USE_ALT_STACK if (faulthandler_allocate_stack() < 0) { return NULL; } #endif - err = faulthandler_register(signum, chain, &previous); - if (err) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - user->previous = previous; - } - - Py_XINCREF(file); - Py_XSETREF(user->file, file); - user->fd = fd; - user->all_threads = all_threads; - user->chain = chain; + err = faulthandler_register(signum, chain, &previous); + if (err) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + user->previous = previous; + } + + Py_XINCREF(file); + Py_XSETREF(user->file, file); + user->fd = fd; + user->all_threads = all_threads; + user->chain = chain; user->interp = PyThreadState_GetInterpreter(tstate); - user->enabled = 1; - - Py_RETURN_NONE; -} - -static int -faulthandler_unregister(user_signal_t *user, int signum) -{ - if (!user->enabled) - return 0; - user->enabled = 0; -#ifdef HAVE_SIGACTION - (void)sigaction(signum, &user->previous, NULL); -#else - (void)signal(signum, user->previous); -#endif - Py_CLEAR(user->file); - user->fd = -1; - return 1; -} - -static PyObject* -faulthandler_unregister_py(PyObject *self, PyObject *args) -{ - int signum; - user_signal_t *user; - int change; - - if (!PyArg_ParseTuple(args, "i:unregister", &signum)) - return NULL; - - if (!check_signum(signum)) - return NULL; - - if (user_signals == NULL) - Py_RETURN_FALSE; - - user = &user_signals[signum]; - change = faulthandler_unregister(user, signum); - return PyBool_FromLong(change); -} -#endif /* FAULTHANDLER_USER */ - - -static void -faulthandler_suppress_crash_report(void) -{ -#ifdef MS_WINDOWS - UINT mode; - - /* Configure Windows to not display the Windows Error Reporting dialog */ - mode = SetErrorMode(SEM_NOGPFAULTERRORBOX); - SetErrorMode(mode | SEM_NOGPFAULTERRORBOX); -#endif - -#ifdef HAVE_SYS_RESOURCE_H - struct rlimit rl; - - /* Disable creation of core dump */ - if (getrlimit(RLIMIT_CORE, &rl) == 0) { - rl.rlim_cur = 0; - setrlimit(RLIMIT_CORE, &rl); - } -#endif - -#ifdef _MSC_VER - /* Visual Studio: configure abort() to not display an error message nor - open a popup asking to report the fault. */ - _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); -#endif -} - -static PyObject * -faulthandler_read_null(PyObject *self, PyObject *args) -{ - volatile int *x; - volatile int y; - - faulthandler_suppress_crash_report(); - x = NULL; - y = *x; - return PyLong_FromLong(y); - -} - -static void -faulthandler_raise_sigsegv(void) -{ - faulthandler_suppress_crash_report(); -#if defined(MS_WINDOWS) - /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal - handler and then gives back the execution flow to the program (without - explicitly calling the previous error handler). In a normal case, the - SIGSEGV was raised by the kernel because of a fault, and so if the - program retries to execute the same instruction, the fault will be - raised again. - - Here the fault is simulated by a fake SIGSEGV signal raised by the - application. We have to raise SIGSEGV at lease twice: once for - faulthandler_fatal_error(), and one more time for the previous signal - handler. */ - while(1) - raise(SIGSEGV); -#else - raise(SIGSEGV); -#endif -} - -static PyObject * -faulthandler_sigsegv(PyObject *self, PyObject *args) -{ - int release_gil = 0; - if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil)) - return NULL; - - if (release_gil) { - Py_BEGIN_ALLOW_THREADS - faulthandler_raise_sigsegv(); - Py_END_ALLOW_THREADS - } else { - faulthandler_raise_sigsegv(); - } - Py_RETURN_NONE; -} - + user->enabled = 1; + + Py_RETURN_NONE; +} + +static int +faulthandler_unregister(user_signal_t *user, int signum) +{ + if (!user->enabled) + return 0; + user->enabled = 0; +#ifdef HAVE_SIGACTION + (void)sigaction(signum, &user->previous, NULL); +#else + (void)signal(signum, user->previous); +#endif + Py_CLEAR(user->file); + user->fd = -1; + return 1; +} + +static PyObject* +faulthandler_unregister_py(PyObject *self, PyObject *args) +{ + int signum; + user_signal_t *user; + int change; + + if (!PyArg_ParseTuple(args, "i:unregister", &signum)) + return NULL; + + if (!check_signum(signum)) + return NULL; + + if (user_signals == NULL) + Py_RETURN_FALSE; + + user = &user_signals[signum]; + change = faulthandler_unregister(user, signum); + return PyBool_FromLong(change); +} +#endif /* FAULTHANDLER_USER */ + + +static void +faulthandler_suppress_crash_report(void) +{ +#ifdef MS_WINDOWS + UINT mode; + + /* Configure Windows to not display the Windows Error Reporting dialog */ + mode = SetErrorMode(SEM_NOGPFAULTERRORBOX); + SetErrorMode(mode | SEM_NOGPFAULTERRORBOX); +#endif + +#ifdef HAVE_SYS_RESOURCE_H + struct rlimit rl; + + /* Disable creation of core dump */ + if (getrlimit(RLIMIT_CORE, &rl) == 0) { + rl.rlim_cur = 0; + setrlimit(RLIMIT_CORE, &rl); + } +#endif + +#ifdef _MSC_VER + /* Visual Studio: configure abort() to not display an error message nor + open a popup asking to report the fault. */ + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif +} + +static PyObject * +faulthandler_read_null(PyObject *self, PyObject *args) +{ + volatile int *x; + volatile int y; + + faulthandler_suppress_crash_report(); + x = NULL; + y = *x; + return PyLong_FromLong(y); + +} + +static void +faulthandler_raise_sigsegv(void) +{ + faulthandler_suppress_crash_report(); +#if defined(MS_WINDOWS) + /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal + handler and then gives back the execution flow to the program (without + explicitly calling the previous error handler). In a normal case, the + SIGSEGV was raised by the kernel because of a fault, and so if the + program retries to execute the same instruction, the fault will be + raised again. + + Here the fault is simulated by a fake SIGSEGV signal raised by the + application. We have to raise SIGSEGV at lease twice: once for + faulthandler_fatal_error(), and one more time for the previous signal + handler. */ + while(1) + raise(SIGSEGV); +#else + raise(SIGSEGV); +#endif +} + +static PyObject * +faulthandler_sigsegv(PyObject *self, PyObject *args) +{ + int release_gil = 0; + if (!PyArg_ParseTuple(args, "|i:_sigsegv", &release_gil)) + return NULL; + + if (release_gil) { + Py_BEGIN_ALLOW_THREADS + faulthandler_raise_sigsegv(); + Py_END_ALLOW_THREADS + } else { + faulthandler_raise_sigsegv(); + } + Py_RETURN_NONE; +} + static void _Py_NO_RETURN -faulthandler_fatal_error_thread(void *plock) -{ - Py_FatalError("in new thread"); -} - -static PyObject * -faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) -{ - long thread; - PyThread_type_lock lock; - - faulthandler_suppress_crash_report(); - - lock = PyThread_allocate_lock(); - if (lock == NULL) - return PyErr_NoMemory(); - - PyThread_acquire_lock(lock, WAIT_LOCK); - - thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock); - if (thread == -1) { - PyThread_free_lock(lock); - PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); - return NULL; - } - - /* wait until the thread completes: it will never occur, since Py_FatalError() - exits the process immediately. */ - PyThread_acquire_lock(lock, WAIT_LOCK); - PyThread_release_lock(lock); - PyThread_free_lock(lock); - - Py_RETURN_NONE; -} - -static PyObject * -faulthandler_sigfpe(PyObject *self, PyObject *args) -{ - /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on - PowerPC. Use volatile to disable compile-time optimizations. */ - volatile int x = 1, y = 0, z; - faulthandler_suppress_crash_report(); - z = x / y; - /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), - raise it manually. */ - raise(SIGFPE); - /* This line is never reached, but we pretend to make something with z - to silence a compiler warning. */ - return PyLong_FromLong(z); -} - -static PyObject * -faulthandler_sigabrt(PyObject *self, PyObject *args) -{ - faulthandler_suppress_crash_report(); - abort(); - Py_RETURN_NONE; -} - -static PyObject * -faulthandler_fatal_error_py(PyObject *self, PyObject *args) -{ - char *message; - int release_gil = 0; - if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) - return NULL; - faulthandler_suppress_crash_report(); - if (release_gil) { - Py_BEGIN_ALLOW_THREADS - Py_FatalError(message); - Py_END_ALLOW_THREADS - } - else { - Py_FatalError(message); - } - Py_RETURN_NONE; -} - +faulthandler_fatal_error_thread(void *plock) +{ + Py_FatalError("in new thread"); +} + +static PyObject * +faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) +{ + long thread; + PyThread_type_lock lock; + + faulthandler_suppress_crash_report(); + + lock = PyThread_allocate_lock(); + if (lock == NULL) + return PyErr_NoMemory(); + + PyThread_acquire_lock(lock, WAIT_LOCK); + + thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock); + if (thread == -1) { + PyThread_free_lock(lock); + PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); + return NULL; + } + + /* wait until the thread completes: it will never occur, since Py_FatalError() + exits the process immediately. */ + PyThread_acquire_lock(lock, WAIT_LOCK); + PyThread_release_lock(lock); + PyThread_free_lock(lock); + + Py_RETURN_NONE; +} + +static PyObject * +faulthandler_sigfpe(PyObject *self, PyObject *args) +{ + /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on + PowerPC. Use volatile to disable compile-time optimizations. */ + volatile int x = 1, y = 0, z; + faulthandler_suppress_crash_report(); + z = x / y; + /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), + raise it manually. */ + raise(SIGFPE); + /* This line is never reached, but we pretend to make something with z + to silence a compiler warning. */ + return PyLong_FromLong(z); +} + +static PyObject * +faulthandler_sigabrt(PyObject *self, PyObject *args) +{ + faulthandler_suppress_crash_report(); + abort(); + Py_RETURN_NONE; +} + +static PyObject * +faulthandler_fatal_error_py(PyObject *self, PyObject *args) +{ + char *message; + int release_gil = 0; + if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) + return NULL; + faulthandler_suppress_crash_report(); + if (release_gil) { + Py_BEGIN_ALLOW_THREADS + Py_FatalError(message); + Py_END_ALLOW_THREADS + } + else { + Py_FatalError(message); + } + Py_RETURN_NONE; +} + #if defined(FAULTHANDLER_USE_ALT_STACK) -#define FAULTHANDLER_STACK_OVERFLOW - +#define FAULTHANDLER_STACK_OVERFLOW + static uintptr_t -stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth) -{ +stack_overflow(uintptr_t min_sp, uintptr_t max_sp, size_t *depth) +{ /* Allocate (at least) 4096 bytes on the stack at each call. bpo-23654, bpo-38965: use volatile keyword to prevent tail call optimization. */ volatile unsigned char buffer[4096]; - uintptr_t sp = (uintptr_t)&buffer; - *depth += 1; - if (sp < min_sp || max_sp < sp) - return sp; - buffer[0] = 1; - buffer[4095] = 0; - return stack_overflow(min_sp, max_sp, depth); -} - -static PyObject * + uintptr_t sp = (uintptr_t)&buffer; + *depth += 1; + if (sp < min_sp || max_sp < sp) + return sp; + buffer[0] = 1; + buffer[4095] = 0; + return stack_overflow(min_sp, max_sp, depth); +} + +static PyObject * faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - size_t depth, size; - uintptr_t sp = (uintptr_t)&depth; +{ + size_t depth, size; + uintptr_t sp = (uintptr_t)&depth; uintptr_t stop, lower_limit, upper_limit; - - faulthandler_suppress_crash_report(); - depth = 0; + + faulthandler_suppress_crash_report(); + depth = 0; if (STACK_OVERFLOW_MAX_SIZE <= sp) { lower_limit = sp - STACK_OVERFLOW_MAX_SIZE; @@ -1187,253 +1187,253 @@ faulthandler_stack_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) } stop = stack_overflow(lower_limit, upper_limit, &depth); - if (sp < stop) - size = stop - sp; - else - size = sp - stop; - PyErr_Format(PyExc_RuntimeError, - "unable to raise a stack overflow (allocated %zu bytes " - "on the stack, %zu recursive calls)", - size, depth); - return NULL; -} + if (sp < stop) + size = stop - sp; + else + size = sp - stop; + PyErr_Format(PyExc_RuntimeError, + "unable to raise a stack overflow (allocated %zu bytes " + "on the stack, %zu recursive calls)", + size, depth); + return NULL; +} #endif /* defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_SIGACTION) */ - - -static int -faulthandler_traverse(PyObject *module, visitproc visit, void *arg) -{ - Py_VISIT(thread.file); -#ifdef FAULTHANDLER_USER - if (user_signals != NULL) { - for (size_t signum=0; signum < NSIG; signum++) - Py_VISIT(user_signals[signum].file); - } -#endif - Py_VISIT(fatal_error.file); - return 0; -} - -#ifdef MS_WINDOWS -static PyObject * -faulthandler_raise_exception(PyObject *self, PyObject *args) -{ - unsigned int code, flags = 0; - if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags)) - return NULL; - faulthandler_suppress_crash_report(); - RaiseException(code, flags, 0, NULL); - Py_RETURN_NONE; -} -#endif - -PyDoc_STRVAR(module_doc, -"faulthandler module."); - -static PyMethodDef module_methods[] = { - {"enable", + + +static int +faulthandler_traverse(PyObject *module, visitproc visit, void *arg) +{ + Py_VISIT(thread.file); +#ifdef FAULTHANDLER_USER + if (user_signals != NULL) { + for (size_t signum=0; signum < NSIG; signum++) + Py_VISIT(user_signals[signum].file); + } +#endif + Py_VISIT(fatal_error.file); + return 0; +} + +#ifdef MS_WINDOWS +static PyObject * +faulthandler_raise_exception(PyObject *self, PyObject *args) +{ + unsigned int code, flags = 0; + if (!PyArg_ParseTuple(args, "I|I:_raise_exception", &code, &flags)) + return NULL; + faulthandler_suppress_crash_report(); + RaiseException(code, flags, 0, NULL); + Py_RETURN_NONE; +} +#endif + +PyDoc_STRVAR(module_doc, +"faulthandler module."); + +static PyMethodDef module_methods[] = { + {"enable", (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("enable(file=sys.stderr, all_threads=True): " - "enable the fault handler")}, + PyDoc_STR("enable(file=sys.stderr, all_threads=True): " + "enable the fault handler")}, {"disable", faulthandler_disable_py, METH_NOARGS, - PyDoc_STR("disable(): disable the fault handler")}, + PyDoc_STR("disable(): disable the fault handler")}, {"is_enabled", faulthandler_is_enabled, METH_NOARGS, - PyDoc_STR("is_enabled()->bool: check if the handler is enabled")}, - {"dump_traceback", + PyDoc_STR("is_enabled()->bool: check if the handler is enabled")}, + {"dump_traceback", (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): " - "dump the traceback of the current thread, or of all threads " - "if all_threads is True, into file")}, - {"dump_traceback_later", + PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): " + "dump the traceback of the current thread, or of all threads " + "if all_threads is True, into file")}, + {"dump_traceback_later", (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n" - "dump the traceback of all threads in timeout seconds,\n" - "or each timeout seconds if repeat is True. If exit is True, " - "call _exit(1) which is not safe.")}, - {"cancel_dump_traceback_later", + PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n" + "dump the traceback of all threads in timeout seconds,\n" + "or each timeout seconds if repeat is True. If exit is True, " + "call _exit(1) which is not safe.")}, + {"cancel_dump_traceback_later", faulthandler_cancel_dump_traceback_later_py, METH_NOARGS, - PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call " - "to dump_traceback_later().")}, -#ifdef FAULTHANDLER_USER - {"register", + PyDoc_STR("cancel_dump_traceback_later():\ncancel the previous call " + "to dump_traceback_later().")}, +#ifdef FAULTHANDLER_USER + {"register", (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): " - "register a handler for the signal 'signum': dump the " - "traceback of the current thread, or of all threads if " - "all_threads is True, into file")}, - {"unregister", + PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): " + "register a handler for the signal 'signum': dump the " + "traceback of the current thread, or of all threads if " + "all_threads is True, into file")}, + {"unregister", (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("unregister(signum): unregister the handler of the signal " - "'signum' registered by register()")}, -#endif - {"_read_null", faulthandler_read_null, METH_NOARGS, - PyDoc_STR("_read_null(): read from NULL, raise " - "a SIGSEGV or SIGBUS signal depending on the platform")}, - {"_sigsegv", faulthandler_sigsegv, METH_VARARGS, - PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")}, - {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS, - PyDoc_STR("fatal_error_c_thread(): " - "call Py_FatalError() in a new C thread.")}, - {"_sigabrt", faulthandler_sigabrt, METH_NOARGS, - PyDoc_STR("_sigabrt(): raise a SIGABRT signal")}, - {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS, - PyDoc_STR("_sigfpe(): raise a SIGFPE signal")}, - {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS, - PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")}, -#ifdef FAULTHANDLER_STACK_OVERFLOW + PyDoc_STR("unregister(signum): unregister the handler of the signal " + "'signum' registered by register()")}, +#endif + {"_read_null", faulthandler_read_null, METH_NOARGS, + PyDoc_STR("_read_null(): read from NULL, raise " + "a SIGSEGV or SIGBUS signal depending on the platform")}, + {"_sigsegv", faulthandler_sigsegv, METH_VARARGS, + PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")}, + {"_fatal_error_c_thread", faulthandler_fatal_error_c_thread, METH_NOARGS, + PyDoc_STR("fatal_error_c_thread(): " + "call Py_FatalError() in a new C thread.")}, + {"_sigabrt", faulthandler_sigabrt, METH_NOARGS, + PyDoc_STR("_sigabrt(): raise a SIGABRT signal")}, + {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS, + PyDoc_STR("_sigfpe(): raise a SIGFPE signal")}, + {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS, + PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")}, +#ifdef FAULTHANDLER_STACK_OVERFLOW {"_stack_overflow", faulthandler_stack_overflow, METH_NOARGS, - PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")}, -#endif -#ifdef MS_WINDOWS - {"_raise_exception", faulthandler_raise_exception, METH_VARARGS, - PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")}, -#endif - {NULL, NULL} /* sentinel */ -}; - -static struct PyModuleDef module_def = { - PyModuleDef_HEAD_INIT, - "faulthandler", - module_doc, - 0, /* non-negative size to be able to unload the module */ - module_methods, - NULL, - faulthandler_traverse, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_faulthandler(void) -{ - PyObject *m = PyModule_Create(&module_def); - if (m == NULL) - return NULL; - - /* Add constants for unit tests */ -#ifdef MS_WINDOWS - /* RaiseException() codes (prefixed by an underscore) */ - if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION", + PyDoc_STR("_stack_overflow(): recursive call to raise a stack overflow")}, +#endif +#ifdef MS_WINDOWS + {"_raise_exception", faulthandler_raise_exception, METH_VARARGS, + PyDoc_STR("raise_exception(code, flags=0): Call RaiseException(code, flags).")}, +#endif + {NULL, NULL} /* sentinel */ +}; + +static struct PyModuleDef module_def = { + PyModuleDef_HEAD_INIT, + "faulthandler", + module_doc, + 0, /* non-negative size to be able to unload the module */ + module_methods, + NULL, + faulthandler_traverse, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_faulthandler(void) +{ + PyObject *m = PyModule_Create(&module_def); + if (m == NULL) + return NULL; + + /* Add constants for unit tests */ +#ifdef MS_WINDOWS + /* RaiseException() codes (prefixed by an underscore) */ + if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION", EXCEPTION_ACCESS_VIOLATION)) { goto error; } - if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", + if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", EXCEPTION_INT_DIVIDE_BY_ZERO)) { goto error; } - if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", + if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", EXCEPTION_STACK_OVERFLOW)) { goto error; } - - /* RaiseException() flags (prefixed by an underscore) */ - if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", + + /* RaiseException() flags (prefixed by an underscore) */ + if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", EXCEPTION_NONCONTINUABLE)) { goto error; } - if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", + if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", EXCEPTION_NONCONTINUABLE_EXCEPTION)) { goto error; } -#endif - - return m; +#endif + + return m; #ifdef MS_WINDOWS error: Py_DECREF(m); return NULL; #endif -} - -static int -faulthandler_init_enable(void) -{ - PyObject *module = PyImport_ImportModule("faulthandler"); - if (module == NULL) { - return -1; - } - +} + +static int +faulthandler_init_enable(void) +{ + PyObject *module = PyImport_ImportModule("faulthandler"); + if (module == NULL) { + return -1; + } + PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable); - Py_DECREF(module); - if (res == NULL) { - return -1; - } - Py_DECREF(res); - - return 0; -} - + Py_DECREF(module); + if (res == NULL) { + return -1; + } + Py_DECREF(res); + + return 0; +} + PyStatus -_PyFaulthandler_Init(int enable) -{ +_PyFaulthandler_Init(int enable) +{ #ifdef FAULTHANDLER_USE_ALT_STACK memset(&stack, 0, sizeof(stack)); - stack.ss_flags = 0; + stack.ss_flags = 0; /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just SIGSTKSZ bytes. Calling the previous signal handler in faulthandler signal handler uses more than SIGSTKSZ bytes of stack memory on some platforms. */ stack.ss_size = SIGSTKSZ * 2; -#endif - +#endif + memset(&thread, 0, sizeof(thread)); - if (enable) { - if (faulthandler_init_enable() < 0) { + if (enable) { + if (faulthandler_init_enable() < 0) { return _PyStatus_ERR("failed to enable faulthandler"); - } - } + } + } return _PyStatus_OK(); -} - -void _PyFaulthandler_Fini(void) -{ - /* later */ - if (thread.cancel_event) { - cancel_dump_traceback_later(); - PyThread_release_lock(thread.cancel_event); - PyThread_free_lock(thread.cancel_event); - thread.cancel_event = NULL; - } - if (thread.running) { - PyThread_free_lock(thread.running); - thread.running = NULL; - } - -#ifdef FAULTHANDLER_USER - /* user */ - if (user_signals != NULL) { - for (size_t signum=0; signum < NSIG; signum++) { - faulthandler_unregister(&user_signals[signum], signum); - } - PyMem_Free(user_signals); - user_signals = NULL; - } -#endif - - /* fatal */ - faulthandler_disable(); +} + +void _PyFaulthandler_Fini(void) +{ + /* later */ + if (thread.cancel_event) { + cancel_dump_traceback_later(); + PyThread_release_lock(thread.cancel_event); + PyThread_free_lock(thread.cancel_event); + thread.cancel_event = NULL; + } + if (thread.running) { + PyThread_free_lock(thread.running); + thread.running = NULL; + } + +#ifdef FAULTHANDLER_USER + /* user */ + if (user_signals != NULL) { + for (size_t signum=0; signum < NSIG; signum++) { + faulthandler_unregister(&user_signals[signum], signum); + } + PyMem_Free(user_signals); + user_signals = NULL; + } +#endif + + /* fatal */ + faulthandler_disable(); #ifdef FAULTHANDLER_USE_ALT_STACK - if (stack.ss_sp != NULL) { - /* Fetch the current alt stack */ + if (stack.ss_sp != NULL) { + /* Fetch the current alt stack */ stack_t current_stack; memset(¤t_stack, 0, sizeof(current_stack)); - if (sigaltstack(NULL, ¤t_stack) == 0) { - if (current_stack.ss_sp == stack.ss_sp) { - /* The current alt stack is the one that we installed. - It is safe to restore the old stack that we found when - we installed ours */ - sigaltstack(&old_stack, NULL); - } else { - /* Someone switched to a different alt stack and didn't - restore ours when they were done (if they're done). - There's not much we can do in this unlikely case */ - } - } - PyMem_Free(stack.ss_sp); - stack.ss_sp = NULL; - } -#endif -} + if (sigaltstack(NULL, ¤t_stack) == 0) { + if (current_stack.ss_sp == stack.ss_sp) { + /* The current alt stack is the one that we installed. + It is safe to restore the old stack that we found when + we installed ours */ + sigaltstack(&old_stack, NULL); + } else { + /* Someone switched to a different alt stack and didn't + restore ours when they were done (if they're done). + There's not much we can do in this unlikely case */ + } + } + PyMem_Free(stack.ss_sp); + stack.ss_sp = NULL; + } +#endif +} diff --git a/contrib/tools/python3/src/Modules/fcntlmodule.c b/contrib/tools/python3/src/Modules/fcntlmodule.c index 43f9b22f672..1f6540ae39d 100644 --- a/contrib/tools/python3/src/Modules/fcntlmodule.c +++ b/contrib/tools/python3/src/Modules/fcntlmodule.c @@ -1,518 +1,518 @@ - -/* fcntl module */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" - -#ifdef HAVE_SYS_FILE_H -#include -#endif - -#include -#include -#ifdef HAVE_STROPTS_H -#include -#endif - -/*[clinic input] -module fcntl -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/ - -static int -conv_descriptor(PyObject *object, int *target) -{ - int fd = PyObject_AsFileDescriptor(object); - - if (fd < 0) - return 0; - *target = fd; - return 1; -} - -/* Must come after conv_descriptor definition. */ -#include "clinic/fcntlmodule.c.h" - -/*[clinic input] -fcntl.fcntl - - fd: object(type='int', converter='conv_descriptor') - cmd as code: int - arg: object(c_default='NULL') = 0 - / - -Perform the operation `cmd` on file descriptor fd. - -The values used for `cmd` are operating system dependent, and are available -as constants in the fcntl module, using the same names as used in -the relevant C header files. The argument arg is optional, and -defaults to 0; it may be an int or a string. If arg is given as a string, -the return value of fcntl is a string of that length, containing the -resulting value put in the arg buffer by the operating system. The length -of the arg string is not allowed to exceed 1024 bytes. If the arg given -is an integer or if none is specified, the result value is an integer -corresponding to the return value of the fcntl call in the C code. -[clinic start generated code]*/ - -static PyObject * -fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) -/*[clinic end generated code: output=888fc93b51c295bd input=8cefbe59b29efbe2]*/ -{ - unsigned int int_arg = 0; - int ret; - char *str; - Py_ssize_t len; - char buf[1024]; - int async_err = 0; - + +/* fcntl module */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" + +#ifdef HAVE_SYS_FILE_H +#include +#endif + +#include +#include +#ifdef HAVE_STROPTS_H +#include +#endif + +/*[clinic input] +module fcntl +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/ + +static int +conv_descriptor(PyObject *object, int *target) +{ + int fd = PyObject_AsFileDescriptor(object); + + if (fd < 0) + return 0; + *target = fd; + return 1; +} + +/* Must come after conv_descriptor definition. */ +#include "clinic/fcntlmodule.c.h" + +/*[clinic input] +fcntl.fcntl + + fd: object(type='int', converter='conv_descriptor') + cmd as code: int + arg: object(c_default='NULL') = 0 + / + +Perform the operation `cmd` on file descriptor fd. + +The values used for `cmd` are operating system dependent, and are available +as constants in the fcntl module, using the same names as used in +the relevant C header files. The argument arg is optional, and +defaults to 0; it may be an int or a string. If arg is given as a string, +the return value of fcntl is a string of that length, containing the +resulting value put in the arg buffer by the operating system. The length +of the arg string is not allowed to exceed 1024 bytes. If the arg given +is an integer or if none is specified, the result value is an integer +corresponding to the return value of the fcntl call in the C code. +[clinic start generated code]*/ + +static PyObject * +fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) +/*[clinic end generated code: output=888fc93b51c295bd input=8cefbe59b29efbe2]*/ +{ + unsigned int int_arg = 0; + int ret; + char *str; + Py_ssize_t len; + char buf[1024]; + int async_err = 0; + if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) { return NULL; } - if (arg != NULL) { - int parse_result; - - if (PyArg_Parse(arg, "s#", &str, &len)) { - if ((size_t)len > sizeof buf) { - PyErr_SetString(PyExc_ValueError, - "fcntl string arg too long"); - return NULL; - } - memcpy(buf, str, len); - do { - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, buf); - Py_END_ALLOW_THREADS - } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (ret < 0) { - return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; - } - return PyBytes_FromStringAndSize(buf, len); - } - - PyErr_Clear(); - parse_result = PyArg_Parse(arg, - "I;fcntl requires a file or file descriptor," - " an integer and optionally a third integer or a string", - &int_arg); - if (!parse_result) { - return NULL; - } - } - - do { - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, (int)int_arg); - Py_END_ALLOW_THREADS - } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (ret < 0) { - return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; - } - return PyLong_FromLong((long)ret); -} - - -/*[clinic input] -fcntl.ioctl - - fd: object(type='int', converter='conv_descriptor') - request as code: unsigned_int(bitwise=True) - arg as ob_arg: object(c_default='NULL') = 0 - mutate_flag as mutate_arg: bool = True - / - -Perform the operation `request` on file descriptor `fd`. - -The values used for `request` are operating system dependent, and are available -as constants in the fcntl or termios library modules, using the same names as -used in the relevant C header files. - -The argument `arg` is optional, and defaults to 0; it may be an int or a -buffer containing character data (most likely a string or an array). - -If the argument is a mutable buffer (such as an array) and if the -mutate_flag argument (which is only allowed in this case) is true then the -buffer is (in effect) passed to the operating system and changes made by -the OS will be reflected in the contents of the buffer after the call has -returned. The return value is the integer returned by the ioctl system -call. - -If the argument is a mutable buffer and the mutable_flag argument is false, -the behavior is as if a string had been passed. - -If the argument is an immutable buffer (most likely a string) then a copy -of the buffer is passed to the operating system and the return value is a -string of the same length containing whatever the operating system put in -the buffer. The length of the arg buffer in this case is not allowed to -exceed 1024 bytes. - -If the arg given is an integer or if none is specified, the result value is -an integer corresponding to the return value of the ioctl call in the C -code. -[clinic start generated code]*/ - -static PyObject * -fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, - PyObject *ob_arg, int mutate_arg) -/*[clinic end generated code: output=7f7f5840c65991be input=ede70c433cccbbb2]*/ -{ -#define IOCTL_BUFSZ 1024 - /* We use the unsigned non-checked 'I' format for the 'code' parameter - because the system expects it to be a 32bit bit field value - regardless of it being passed as an int or unsigned long on - various platforms. See the termios.TIOCSWINSZ constant across - platforms for an example of this. - - If any of the 64bit platforms ever decide to use more than 32bits - in their unsigned long ioctl codes this will break and need - special casing based on the platform being built on. - */ - int arg = 0; - int ret; - Py_buffer pstr; - char *str; - Py_ssize_t len; - char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ - + if (arg != NULL) { + int parse_result; + + if (PyArg_Parse(arg, "s#", &str, &len)) { + if ((size_t)len > sizeof buf) { + PyErr_SetString(PyExc_ValueError, + "fcntl string arg too long"); + return NULL; + } + memcpy(buf, str, len); + do { + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, code, buf); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (ret < 0) { + return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; + } + return PyBytes_FromStringAndSize(buf, len); + } + + PyErr_Clear(); + parse_result = PyArg_Parse(arg, + "I;fcntl requires a file or file descriptor," + " an integer and optionally a third integer or a string", + &int_arg); + if (!parse_result) { + return NULL; + } + } + + do { + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, code, (int)int_arg); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (ret < 0) { + return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; + } + return PyLong_FromLong((long)ret); +} + + +/*[clinic input] +fcntl.ioctl + + fd: object(type='int', converter='conv_descriptor') + request as code: unsigned_int(bitwise=True) + arg as ob_arg: object(c_default='NULL') = 0 + mutate_flag as mutate_arg: bool = True + / + +Perform the operation `request` on file descriptor `fd`. + +The values used for `request` are operating system dependent, and are available +as constants in the fcntl or termios library modules, using the same names as +used in the relevant C header files. + +The argument `arg` is optional, and defaults to 0; it may be an int or a +buffer containing character data (most likely a string or an array). + +If the argument is a mutable buffer (such as an array) and if the +mutate_flag argument (which is only allowed in this case) is true then the +buffer is (in effect) passed to the operating system and changes made by +the OS will be reflected in the contents of the buffer after the call has +returned. The return value is the integer returned by the ioctl system +call. + +If the argument is a mutable buffer and the mutable_flag argument is false, +the behavior is as if a string had been passed. + +If the argument is an immutable buffer (most likely a string) then a copy +of the buffer is passed to the operating system and the return value is a +string of the same length containing whatever the operating system put in +the buffer. The length of the arg buffer in this case is not allowed to +exceed 1024 bytes. + +If the arg given is an integer or if none is specified, the result value is +an integer corresponding to the return value of the ioctl call in the C +code. +[clinic start generated code]*/ + +static PyObject * +fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, + PyObject *ob_arg, int mutate_arg) +/*[clinic end generated code: output=7f7f5840c65991be input=ede70c433cccbbb2]*/ +{ +#define IOCTL_BUFSZ 1024 + /* We use the unsigned non-checked 'I' format for the 'code' parameter + because the system expects it to be a 32bit bit field value + regardless of it being passed as an int or unsigned long on + various platforms. See the termios.TIOCSWINSZ constant across + platforms for an example of this. + + If any of the 64bit platforms ever decide to use more than 32bits + in their unsigned long ioctl codes this will break and need + special casing based on the platform being built on. + */ + int arg = 0; + int ret; + Py_buffer pstr; + char *str; + Py_ssize_t len; + char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ + if (PySys_Audit("fcntl.ioctl", "iIO", fd, code, ob_arg ? ob_arg : Py_None) < 0) { return NULL; } - if (ob_arg != NULL) { - if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) { - char *arg; - str = pstr.buf; - len = pstr.len; - - if (mutate_arg) { - if (len <= IOCTL_BUFSZ) { - memcpy(buf, str, len); - buf[len] = '\0'; - arg = buf; - } - else { - arg = str; - } - } - else { - if (len > IOCTL_BUFSZ) { - PyBuffer_Release(&pstr); - PyErr_SetString(PyExc_ValueError, - "ioctl string arg too long"); - return NULL; - } - else { - memcpy(buf, str, len); - buf[len] = '\0'; - arg = buf; - } - } - if (buf == arg) { - Py_BEGIN_ALLOW_THREADS /* think array.resize() */ - ret = ioctl(fd, code, arg); - Py_END_ALLOW_THREADS - } - else { - ret = ioctl(fd, code, arg); - } - if (mutate_arg && (len <= IOCTL_BUFSZ)) { - memcpy(str, buf, len); - } - PyBuffer_Release(&pstr); /* No further access to str below this point */ - if (ret < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - if (mutate_arg) { - return PyLong_FromLong(ret); - } - else { - return PyBytes_FromStringAndSize(buf, len); - } - } - - PyErr_Clear(); - if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) { - str = pstr.buf; - len = pstr.len; - if (len > IOCTL_BUFSZ) { - PyBuffer_Release(&pstr); - PyErr_SetString(PyExc_ValueError, - "ioctl string arg too long"); - return NULL; - } - memcpy(buf, str, len); - buf[len] = '\0'; - Py_BEGIN_ALLOW_THREADS - ret = ioctl(fd, code, buf); - Py_END_ALLOW_THREADS - if (ret < 0) { - PyBuffer_Release(&pstr); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - PyBuffer_Release(&pstr); - return PyBytes_FromStringAndSize(buf, len); - } - - PyErr_Clear(); - if (!PyArg_Parse(ob_arg, - "i;ioctl requires a file or file descriptor," - " an integer and optionally an integer or buffer argument", - &arg)) { - return NULL; - } - // Fall-through to outside the 'if' statement. - } - Py_BEGIN_ALLOW_THREADS - ret = ioctl(fd, code, arg); - Py_END_ALLOW_THREADS - if (ret < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return PyLong_FromLong((long)ret); -#undef IOCTL_BUFSZ -} - -/*[clinic input] -fcntl.flock - - fd: object(type='int', converter='conv_descriptor') - operation as code: int - / - -Perform the lock operation `operation` on file descriptor `fd`. - -See the Unix manual page for flock(2) for details (On some systems, this -function is emulated using fcntl()). -[clinic start generated code]*/ - -static PyObject * -fcntl_flock_impl(PyObject *module, int fd, int code) -/*[clinic end generated code: output=84059e2b37d2fc64 input=b70a0a41ca22a8a0]*/ -{ - int ret; - int async_err = 0; - + if (ob_arg != NULL) { + if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) { + char *arg; + str = pstr.buf; + len = pstr.len; + + if (mutate_arg) { + if (len <= IOCTL_BUFSZ) { + memcpy(buf, str, len); + buf[len] = '\0'; + arg = buf; + } + else { + arg = str; + } + } + else { + if (len > IOCTL_BUFSZ) { + PyBuffer_Release(&pstr); + PyErr_SetString(PyExc_ValueError, + "ioctl string arg too long"); + return NULL; + } + else { + memcpy(buf, str, len); + buf[len] = '\0'; + arg = buf; + } + } + if (buf == arg) { + Py_BEGIN_ALLOW_THREADS /* think array.resize() */ + ret = ioctl(fd, code, arg); + Py_END_ALLOW_THREADS + } + else { + ret = ioctl(fd, code, arg); + } + if (mutate_arg && (len <= IOCTL_BUFSZ)) { + memcpy(str, buf, len); + } + PyBuffer_Release(&pstr); /* No further access to str below this point */ + if (ret < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (mutate_arg) { + return PyLong_FromLong(ret); + } + else { + return PyBytes_FromStringAndSize(buf, len); + } + } + + PyErr_Clear(); + if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) { + str = pstr.buf; + len = pstr.len; + if (len > IOCTL_BUFSZ) { + PyBuffer_Release(&pstr); + PyErr_SetString(PyExc_ValueError, + "ioctl string arg too long"); + return NULL; + } + memcpy(buf, str, len); + buf[len] = '\0'; + Py_BEGIN_ALLOW_THREADS + ret = ioctl(fd, code, buf); + Py_END_ALLOW_THREADS + if (ret < 0) { + PyBuffer_Release(&pstr); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + PyBuffer_Release(&pstr); + return PyBytes_FromStringAndSize(buf, len); + } + + PyErr_Clear(); + if (!PyArg_Parse(ob_arg, + "i;ioctl requires a file or file descriptor," + " an integer and optionally an integer or buffer argument", + &arg)) { + return NULL; + } + // Fall-through to outside the 'if' statement. + } + Py_BEGIN_ALLOW_THREADS + ret = ioctl(fd, code, arg); + Py_END_ALLOW_THREADS + if (ret < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyLong_FromLong((long)ret); +#undef IOCTL_BUFSZ +} + +/*[clinic input] +fcntl.flock + + fd: object(type='int', converter='conv_descriptor') + operation as code: int + / + +Perform the lock operation `operation` on file descriptor `fd`. + +See the Unix manual page for flock(2) for details (On some systems, this +function is emulated using fcntl()). +[clinic start generated code]*/ + +static PyObject * +fcntl_flock_impl(PyObject *module, int fd, int code) +/*[clinic end generated code: output=84059e2b37d2fc64 input=b70a0a41ca22a8a0]*/ +{ + int ret; + int async_err = 0; + if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) { return NULL; } -#ifdef HAVE_FLOCK - do { - Py_BEGIN_ALLOW_THREADS - ret = flock(fd, code); - Py_END_ALLOW_THREADS - } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#else - -#ifndef LOCK_SH -#define LOCK_SH 1 /* shared lock */ -#define LOCK_EX 2 /* exclusive lock */ -#define LOCK_NB 4 /* don't block when locking */ -#define LOCK_UN 8 /* unlock */ -#endif - { - struct flock l; - if (code == LOCK_UN) - l.l_type = F_UNLCK; - else if (code & LOCK_SH) - l.l_type = F_RDLCK; - else if (code & LOCK_EX) - l.l_type = F_WRLCK; - else { - PyErr_SetString(PyExc_ValueError, - "unrecognized flock argument"); - return NULL; - } - l.l_whence = l.l_start = l.l_len = 0; - do { - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); - Py_END_ALLOW_THREADS - } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - } -#endif /* HAVE_FLOCK */ - if (ret < 0) { - return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; - } - Py_RETURN_NONE; -} - - -/*[clinic input] -fcntl.lockf - - fd: object(type='int', converter='conv_descriptor') - cmd as code: int - len as lenobj: object(c_default='NULL') = 0 - start as startobj: object(c_default='NULL') = 0 - whence: int = 0 - / - -A wrapper around the fcntl() locking calls. - -`fd` is the file descriptor of the file to lock or unlock, and operation is one -of the following values: - - LOCK_UN - unlock - LOCK_SH - acquire a shared lock - LOCK_EX - acquire an exclusive lock - -When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with -LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the -lock cannot be acquired, an OSError will be raised and the exception will -have an errno attribute set to EACCES or EAGAIN (depending on the operating -system -- for portability, check for either value). - -`len` is the number of bytes to lock, with the default meaning to lock to -EOF. `start` is the byte offset, relative to `whence`, to that the lock -starts. `whence` is as with fileobj.seek(), specifically: - - 0 - relative to the start of the file (SEEK_SET) - 1 - relative to the current buffer position (SEEK_CUR) - 2 - relative to the end of the file (SEEK_END) -[clinic start generated code]*/ - -static PyObject * -fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, - PyObject *startobj, int whence) -/*[clinic end generated code: output=4985e7a172e7461a input=3a5dc01b04371f1a]*/ -{ - int ret; - int async_err = 0; - +#ifdef HAVE_FLOCK + do { + Py_BEGIN_ALLOW_THREADS + ret = flock(fd, code); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#else + +#ifndef LOCK_SH +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* don't block when locking */ +#define LOCK_UN 8 /* unlock */ +#endif + { + struct flock l; + if (code == LOCK_UN) + l.l_type = F_UNLCK; + else if (code & LOCK_SH) + l.l_type = F_RDLCK; + else if (code & LOCK_EX) + l.l_type = F_WRLCK; + else { + PyErr_SetString(PyExc_ValueError, + "unrecognized flock argument"); + return NULL; + } + l.l_whence = l.l_start = l.l_len = 0; + do { + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + } +#endif /* HAVE_FLOCK */ + if (ret < 0) { + return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; + } + Py_RETURN_NONE; +} + + +/*[clinic input] +fcntl.lockf + + fd: object(type='int', converter='conv_descriptor') + cmd as code: int + len as lenobj: object(c_default='NULL') = 0 + start as startobj: object(c_default='NULL') = 0 + whence: int = 0 + / + +A wrapper around the fcntl() locking calls. + +`fd` is the file descriptor of the file to lock or unlock, and operation is one +of the following values: + + LOCK_UN - unlock + LOCK_SH - acquire a shared lock + LOCK_EX - acquire an exclusive lock + +When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with +LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the +lock cannot be acquired, an OSError will be raised and the exception will +have an errno attribute set to EACCES or EAGAIN (depending on the operating +system -- for portability, check for either value). + +`len` is the number of bytes to lock, with the default meaning to lock to +EOF. `start` is the byte offset, relative to `whence`, to that the lock +starts. `whence` is as with fileobj.seek(), specifically: + + 0 - relative to the start of the file (SEEK_SET) + 1 - relative to the current buffer position (SEEK_CUR) + 2 - relative to the end of the file (SEEK_END) +[clinic start generated code]*/ + +static PyObject * +fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, + PyObject *startobj, int whence) +/*[clinic end generated code: output=4985e7a172e7461a input=3a5dc01b04371f1a]*/ +{ + int ret; + int async_err = 0; + if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None, startobj ? startobj : Py_None, whence) < 0) { return NULL; } -#ifndef LOCK_SH -#define LOCK_SH 1 /* shared lock */ -#define LOCK_EX 2 /* exclusive lock */ -#define LOCK_NB 4 /* don't block when locking */ -#define LOCK_UN 8 /* unlock */ -#endif /* LOCK_SH */ - { - struct flock l; - if (code == LOCK_UN) - l.l_type = F_UNLCK; - else if (code & LOCK_SH) - l.l_type = F_RDLCK; - else if (code & LOCK_EX) - l.l_type = F_WRLCK; - else { - PyErr_SetString(PyExc_ValueError, - "unrecognized lockf argument"); - return NULL; - } - l.l_start = l.l_len = 0; - if (startobj != NULL) { -#if !defined(HAVE_LARGEFILE_SUPPORT) - l.l_start = PyLong_AsLong(startobj); -#else - l.l_start = PyLong_Check(startobj) ? - PyLong_AsLongLong(startobj) : - PyLong_AsLong(startobj); -#endif - if (PyErr_Occurred()) - return NULL; - } - if (lenobj != NULL) { -#if !defined(HAVE_LARGEFILE_SUPPORT) - l.l_len = PyLong_AsLong(lenobj); -#else - l.l_len = PyLong_Check(lenobj) ? - PyLong_AsLongLong(lenobj) : - PyLong_AsLong(lenobj); -#endif - if (PyErr_Occurred()) - return NULL; - } - l.l_whence = whence; - do { - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); - Py_END_ALLOW_THREADS - } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - } - if (ret < 0) { - return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; - } - Py_RETURN_NONE; -} - -/* List of functions */ - -static PyMethodDef fcntl_methods[] = { - FCNTL_FCNTL_METHODDEF - FCNTL_IOCTL_METHODDEF - FCNTL_FLOCK_METHODDEF - FCNTL_LOCKF_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -PyDoc_STRVAR(module_doc, +#ifndef LOCK_SH +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* don't block when locking */ +#define LOCK_UN 8 /* unlock */ +#endif /* LOCK_SH */ + { + struct flock l; + if (code == LOCK_UN) + l.l_type = F_UNLCK; + else if (code & LOCK_SH) + l.l_type = F_RDLCK; + else if (code & LOCK_EX) + l.l_type = F_WRLCK; + else { + PyErr_SetString(PyExc_ValueError, + "unrecognized lockf argument"); + return NULL; + } + l.l_start = l.l_len = 0; + if (startobj != NULL) { +#if !defined(HAVE_LARGEFILE_SUPPORT) + l.l_start = PyLong_AsLong(startobj); +#else + l.l_start = PyLong_Check(startobj) ? + PyLong_AsLongLong(startobj) : + PyLong_AsLong(startobj); +#endif + if (PyErr_Occurred()) + return NULL; + } + if (lenobj != NULL) { +#if !defined(HAVE_LARGEFILE_SUPPORT) + l.l_len = PyLong_AsLong(lenobj); +#else + l.l_len = PyLong_Check(lenobj) ? + PyLong_AsLongLong(lenobj) : + PyLong_AsLong(lenobj); +#endif + if (PyErr_Occurred()) + return NULL; + } + l.l_whence = whence; + do { + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); + Py_END_ALLOW_THREADS + } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + } + if (ret < 0) { + return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; + } + Py_RETURN_NONE; +} + +/* List of functions */ + +static PyMethodDef fcntl_methods[] = { + FCNTL_FCNTL_METHODDEF + FCNTL_IOCTL_METHODDEF + FCNTL_FLOCK_METHODDEF + FCNTL_LOCKF_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +PyDoc_STRVAR(module_doc, "This module performs file control and I/O control on file\n\ -descriptors. It is an interface to the fcntl() and ioctl() Unix\n\ -routines. File descriptors can be obtained with the fileno() method of\n\ -a file or socket object."); - -/* Module initialisation */ - - -static int -all_ins(PyObject* m) -{ - if (PyModule_AddIntMacro(m, LOCK_SH)) return -1; - if (PyModule_AddIntMacro(m, LOCK_EX)) return -1; - if (PyModule_AddIntMacro(m, LOCK_NB)) return -1; - if (PyModule_AddIntMacro(m, LOCK_UN)) return -1; -/* GNU extensions, as of glibc 2.2.4 */ -#ifdef LOCK_MAND - if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1; -#endif -#ifdef LOCK_READ - if (PyModule_AddIntMacro(m, LOCK_READ)) return -1; -#endif -#ifdef LOCK_WRITE - if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1; -#endif -#ifdef LOCK_RW - if (PyModule_AddIntMacro(m, LOCK_RW)) return -1; -#endif - -#ifdef F_DUPFD - if (PyModule_AddIntMacro(m, F_DUPFD)) return -1; -#endif -#ifdef F_DUPFD_CLOEXEC - if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1; -#endif -#ifdef F_GETFD - if (PyModule_AddIntMacro(m, F_GETFD)) return -1; -#endif -#ifdef F_SETFD - if (PyModule_AddIntMacro(m, F_SETFD)) return -1; -#endif -#ifdef F_GETFL - if (PyModule_AddIntMacro(m, F_GETFL)) return -1; -#endif -#ifdef F_SETFL - if (PyModule_AddIntMacro(m, F_SETFL)) return -1; -#endif -#ifdef F_GETLK - if (PyModule_AddIntMacro(m, F_GETLK)) return -1; -#endif -#ifdef F_SETLK - if (PyModule_AddIntMacro(m, F_SETLK)) return -1; -#endif -#ifdef F_SETLKW - if (PyModule_AddIntMacro(m, F_SETLKW)) return -1; -#endif +descriptors. It is an interface to the fcntl() and ioctl() Unix\n\ +routines. File descriptors can be obtained with the fileno() method of\n\ +a file or socket object."); + +/* Module initialisation */ + + +static int +all_ins(PyObject* m) +{ + if (PyModule_AddIntMacro(m, LOCK_SH)) return -1; + if (PyModule_AddIntMacro(m, LOCK_EX)) return -1; + if (PyModule_AddIntMacro(m, LOCK_NB)) return -1; + if (PyModule_AddIntMacro(m, LOCK_UN)) return -1; +/* GNU extensions, as of glibc 2.2.4 */ +#ifdef LOCK_MAND + if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1; +#endif +#ifdef LOCK_READ + if (PyModule_AddIntMacro(m, LOCK_READ)) return -1; +#endif +#ifdef LOCK_WRITE + if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1; +#endif +#ifdef LOCK_RW + if (PyModule_AddIntMacro(m, LOCK_RW)) return -1; +#endif + +#ifdef F_DUPFD + if (PyModule_AddIntMacro(m, F_DUPFD)) return -1; +#endif +#ifdef F_DUPFD_CLOEXEC + if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1; +#endif +#ifdef F_GETFD + if (PyModule_AddIntMacro(m, F_GETFD)) return -1; +#endif +#ifdef F_SETFD + if (PyModule_AddIntMacro(m, F_SETFD)) return -1; +#endif +#ifdef F_GETFL + if (PyModule_AddIntMacro(m, F_GETFL)) return -1; +#endif +#ifdef F_SETFL + if (PyModule_AddIntMacro(m, F_SETFL)) return -1; +#endif +#ifdef F_GETLK + if (PyModule_AddIntMacro(m, F_GETLK)) return -1; +#endif +#ifdef F_SETLK + if (PyModule_AddIntMacro(m, F_SETLK)) return -1; +#endif +#ifdef F_SETLKW + if (PyModule_AddIntMacro(m, F_SETLKW)) return -1; +#endif #ifdef F_OFD_GETLK if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1; #endif @@ -522,134 +522,134 @@ all_ins(PyObject* m) #ifdef F_OFD_SETLKW if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1; #endif -#ifdef F_GETOWN - if (PyModule_AddIntMacro(m, F_GETOWN)) return -1; -#endif -#ifdef F_SETOWN - if (PyModule_AddIntMacro(m, F_SETOWN)) return -1; -#endif +#ifdef F_GETOWN + if (PyModule_AddIntMacro(m, F_GETOWN)) return -1; +#endif +#ifdef F_SETOWN + if (PyModule_AddIntMacro(m, F_SETOWN)) return -1; +#endif #ifdef F_GETPATH if (PyModule_AddIntMacro(m, F_GETPATH)) return -1; #endif -#ifdef F_GETSIG - if (PyModule_AddIntMacro(m, F_GETSIG)) return -1; -#endif -#ifdef F_SETSIG - if (PyModule_AddIntMacro(m, F_SETSIG)) return -1; -#endif -#ifdef F_RDLCK - if (PyModule_AddIntMacro(m, F_RDLCK)) return -1; -#endif -#ifdef F_WRLCK - if (PyModule_AddIntMacro(m, F_WRLCK)) return -1; -#endif -#ifdef F_UNLCK - if (PyModule_AddIntMacro(m, F_UNLCK)) return -1; -#endif -/* LFS constants */ -#ifdef F_GETLK64 - if (PyModule_AddIntMacro(m, F_GETLK64)) return -1; -#endif -#ifdef F_SETLK64 - if (PyModule_AddIntMacro(m, F_SETLK64)) return -1; -#endif -#ifdef F_SETLKW64 - if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1; -#endif -/* GNU extensions, as of glibc 2.2.4. */ -#ifdef FASYNC - if (PyModule_AddIntMacro(m, FASYNC)) return -1; -#endif -#ifdef F_SETLEASE - if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1; -#endif -#ifdef F_GETLEASE - if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1; -#endif -#ifdef F_NOTIFY - if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1; -#endif -/* Old BSD flock(). */ -#ifdef F_EXLCK - if (PyModule_AddIntMacro(m, F_EXLCK)) return -1; -#endif -#ifdef F_SHLCK - if (PyModule_AddIntMacro(m, F_SHLCK)) return -1; -#endif - -/* OS X specifics */ -#ifdef F_FULLFSYNC - if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1; -#endif -#ifdef F_NOCACHE - if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1; -#endif - -/* For F_{GET|SET}FL */ -#ifdef FD_CLOEXEC - if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1; -#endif - -/* For F_NOTIFY */ -#ifdef DN_ACCESS - if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1; -#endif -#ifdef DN_MODIFY - if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1; -#endif -#ifdef DN_CREATE - if (PyModule_AddIntMacro(m, DN_CREATE)) return -1; -#endif -#ifdef DN_DELETE - if (PyModule_AddIntMacro(m, DN_DELETE)) return -1; -#endif -#ifdef DN_RENAME - if (PyModule_AddIntMacro(m, DN_RENAME)) return -1; -#endif -#ifdef DN_ATTRIB - if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1; -#endif -#ifdef DN_MULTISHOT - if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1; -#endif - -#ifdef HAVE_STROPTS_H - /* Unix 98 guarantees that these are in stropts.h. */ - if (PyModule_AddIntMacro(m, I_PUSH)) return -1; - if (PyModule_AddIntMacro(m, I_POP)) return -1; - if (PyModule_AddIntMacro(m, I_LOOK)) return -1; - if (PyModule_AddIntMacro(m, I_FLUSH)) return -1; - if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1; - if (PyModule_AddIntMacro(m, I_SETSIG)) return -1; - if (PyModule_AddIntMacro(m, I_GETSIG)) return -1; - if (PyModule_AddIntMacro(m, I_FIND)) return -1; - if (PyModule_AddIntMacro(m, I_PEEK)) return -1; - if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1; - if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1; - if (PyModule_AddIntMacro(m, I_NREAD)) return -1; - if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1; - if (PyModule_AddIntMacro(m, I_STR)) return -1; - if (PyModule_AddIntMacro(m, I_SWROPT)) return -1; -#ifdef I_GWROPT - /* despite the comment above, old-ish glibcs miss a couple... */ - if (PyModule_AddIntMacro(m, I_GWROPT)) return -1; -#endif - if (PyModule_AddIntMacro(m, I_SENDFD)) return -1; - if (PyModule_AddIntMacro(m, I_RECVFD)) return -1; - if (PyModule_AddIntMacro(m, I_LIST)) return -1; - if (PyModule_AddIntMacro(m, I_ATMARK)) return -1; - if (PyModule_AddIntMacro(m, I_CKBAND)) return -1; - if (PyModule_AddIntMacro(m, I_GETBAND)) return -1; - if (PyModule_AddIntMacro(m, I_CANPUT)) return -1; - if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1; -#ifdef I_GETCLTIME - if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1; -#endif - if (PyModule_AddIntMacro(m, I_LINK)) return -1; - if (PyModule_AddIntMacro(m, I_UNLINK)) return -1; - if (PyModule_AddIntMacro(m, I_PLINK)) return -1; - if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1; -#endif +#ifdef F_GETSIG + if (PyModule_AddIntMacro(m, F_GETSIG)) return -1; +#endif +#ifdef F_SETSIG + if (PyModule_AddIntMacro(m, F_SETSIG)) return -1; +#endif +#ifdef F_RDLCK + if (PyModule_AddIntMacro(m, F_RDLCK)) return -1; +#endif +#ifdef F_WRLCK + if (PyModule_AddIntMacro(m, F_WRLCK)) return -1; +#endif +#ifdef F_UNLCK + if (PyModule_AddIntMacro(m, F_UNLCK)) return -1; +#endif +/* LFS constants */ +#ifdef F_GETLK64 + if (PyModule_AddIntMacro(m, F_GETLK64)) return -1; +#endif +#ifdef F_SETLK64 + if (PyModule_AddIntMacro(m, F_SETLK64)) return -1; +#endif +#ifdef F_SETLKW64 + if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1; +#endif +/* GNU extensions, as of glibc 2.2.4. */ +#ifdef FASYNC + if (PyModule_AddIntMacro(m, FASYNC)) return -1; +#endif +#ifdef F_SETLEASE + if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1; +#endif +#ifdef F_GETLEASE + if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1; +#endif +#ifdef F_NOTIFY + if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1; +#endif +/* Old BSD flock(). */ +#ifdef F_EXLCK + if (PyModule_AddIntMacro(m, F_EXLCK)) return -1; +#endif +#ifdef F_SHLCK + if (PyModule_AddIntMacro(m, F_SHLCK)) return -1; +#endif + +/* OS X specifics */ +#ifdef F_FULLFSYNC + if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1; +#endif +#ifdef F_NOCACHE + if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1; +#endif + +/* For F_{GET|SET}FL */ +#ifdef FD_CLOEXEC + if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1; +#endif + +/* For F_NOTIFY */ +#ifdef DN_ACCESS + if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1; +#endif +#ifdef DN_MODIFY + if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1; +#endif +#ifdef DN_CREATE + if (PyModule_AddIntMacro(m, DN_CREATE)) return -1; +#endif +#ifdef DN_DELETE + if (PyModule_AddIntMacro(m, DN_DELETE)) return -1; +#endif +#ifdef DN_RENAME + if (PyModule_AddIntMacro(m, DN_RENAME)) return -1; +#endif +#ifdef DN_ATTRIB + if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1; +#endif +#ifdef DN_MULTISHOT + if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1; +#endif + +#ifdef HAVE_STROPTS_H + /* Unix 98 guarantees that these are in stropts.h. */ + if (PyModule_AddIntMacro(m, I_PUSH)) return -1; + if (PyModule_AddIntMacro(m, I_POP)) return -1; + if (PyModule_AddIntMacro(m, I_LOOK)) return -1; + if (PyModule_AddIntMacro(m, I_FLUSH)) return -1; + if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1; + if (PyModule_AddIntMacro(m, I_SETSIG)) return -1; + if (PyModule_AddIntMacro(m, I_GETSIG)) return -1; + if (PyModule_AddIntMacro(m, I_FIND)) return -1; + if (PyModule_AddIntMacro(m, I_PEEK)) return -1; + if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1; + if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1; + if (PyModule_AddIntMacro(m, I_NREAD)) return -1; + if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1; + if (PyModule_AddIntMacro(m, I_STR)) return -1; + if (PyModule_AddIntMacro(m, I_SWROPT)) return -1; +#ifdef I_GWROPT + /* despite the comment above, old-ish glibcs miss a couple... */ + if (PyModule_AddIntMacro(m, I_GWROPT)) return -1; +#endif + if (PyModule_AddIntMacro(m, I_SENDFD)) return -1; + if (PyModule_AddIntMacro(m, I_RECVFD)) return -1; + if (PyModule_AddIntMacro(m, I_LIST)) return -1; + if (PyModule_AddIntMacro(m, I_ATMARK)) return -1; + if (PyModule_AddIntMacro(m, I_CKBAND)) return -1; + if (PyModule_AddIntMacro(m, I_GETBAND)) return -1; + if (PyModule_AddIntMacro(m, I_CANPUT)) return -1; + if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1; +#ifdef I_GETCLTIME + if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1; +#endif + if (PyModule_AddIntMacro(m, I_LINK)) return -1; + if (PyModule_AddIntMacro(m, I_UNLINK)) return -1; + if (PyModule_AddIntMacro(m, I_PLINK)) return -1; + if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1; +#endif #ifdef F_ADD_SEALS /* Linux: file sealing for memfd_create() */ if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1; @@ -659,37 +659,37 @@ all_ins(PyObject* m) if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1; if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1; #endif - return 0; -} - - -static struct PyModuleDef fcntlmodule = { - PyModuleDef_HEAD_INIT, - "fcntl", - module_doc, - -1, - fcntl_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_fcntl(void) -{ - PyObject *m; - - /* Create the module and add the functions and documentation */ - m = PyModule_Create(&fcntlmodule); - if (m == NULL) - return NULL; - - /* Add some symbolic constants to the module */ + return 0; +} + + +static struct PyModuleDef fcntlmodule = { + PyModuleDef_HEAD_INIT, + "fcntl", + module_doc, + -1, + fcntl_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_fcntl(void) +{ + PyObject *m; + + /* Create the module and add the functions and documentation */ + m = PyModule_Create(&fcntlmodule); + if (m == NULL) + return NULL; + + /* Add some symbolic constants to the module */ if (all_ins(m) < 0) { Py_DECREF(m); - return NULL; + return NULL; } - - return m; -} + + return m; +} diff --git a/contrib/tools/python3/src/Modules/gcmodule.c b/contrib/tools/python3/src/Modules/gcmodule.c index 3cf1a00b003..95898225544 100644 --- a/contrib/tools/python3/src/Modules/gcmodule.c +++ b/contrib/tools/python3/src/Modules/gcmodule.c @@ -1,45 +1,45 @@ -/* - - Reference Cycle Garbage Collection - ================================== - - Neil Schemenauer - - Based on a post on the python-dev list. Ideas from Guido van Rossum, - Eric Tiedemann, and various others. - - http://www.arctrix.com/nas/python/gc/ - - The following mailing list threads provide a historical perspective on - the design of this module. Note that a fair amount of refinement has - occurred since those discussions. - - http://mail.python.org/pipermail/python-dev/2000-March/002385.html - http://mail.python.org/pipermail/python-dev/2000-March/002434.html - http://mail.python.org/pipermail/python-dev/2000-March/002497.html - - For a highlevel view of the collection process, read the collect - function. - -*/ - -#include "Python.h" +/* + + Reference Cycle Garbage Collection + ================================== + + Neil Schemenauer + + Based on a post on the python-dev list. Ideas from Guido van Rossum, + Eric Tiedemann, and various others. + + http://www.arctrix.com/nas/python/gc/ + + The following mailing list threads provide a historical perspective on + the design of this module. Note that a fair amount of refinement has + occurred since those discussions. + + http://mail.python.org/pipermail/python-dev/2000-March/002385.html + http://mail.python.org/pipermail/python-dev/2000-March/002434.html + http://mail.python.org/pipermail/python-dev/2000-March/002497.html + + For a highlevel view of the collection process, read the collect + function. + +*/ + +#include "Python.h" #include "pycore_context.h" #include "pycore_initconfig.h" #include "pycore_interp.h" // PyInterpreterState.gc #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() -#include "pydtrace.h" +#include "pydtrace.h" #include "pytime.h" // _PyTime_GetMonotonicClock() - + typedef struct _gc_runtime_state GCState; -/*[clinic input] -module gc -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b5c9690ecc842d79]*/ - +/*[clinic input] +module gc +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b5c9690ecc842d79]*/ + #ifdef Py_DEBUG # define GC_DEBUG @@ -69,12 +69,12 @@ module gc // most gc_list_* functions for it. #define NEXT_MASK_UNREACHABLE (1) -/* Get an object's GC head */ -#define AS_GC(o) ((PyGC_Head *)(o)-1) - -/* Get the object given the GC head */ -#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1)) - +/* Get an object's GC head */ +#define AS_GC(o) ((PyGC_Head *)(o)-1) + +/* Get the object given the GC head */ +#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1)) + static inline int gc_is_collecting(PyGC_Head *g) { @@ -117,40 +117,40 @@ gc_decref(PyGC_Head *g) g->_gc_prev -= 1 << _PyGC_PREV_SHIFT; } -/* set for debugging information */ -#define DEBUG_STATS (1<<0) /* print collection statistics */ -#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */ -#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */ -#define DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */ -#define DEBUG_LEAK DEBUG_COLLECTABLE | \ - DEBUG_UNCOLLECTABLE | \ - DEBUG_SAVEALL - +/* set for debugging information */ +#define DEBUG_STATS (1<<0) /* print collection statistics */ +#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */ +#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */ +#define DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */ +#define DEBUG_LEAK DEBUG_COLLECTABLE | \ + DEBUG_UNCOLLECTABLE | \ + DEBUG_SAVEALL + #define GEN_HEAD(gcstate, n) (&(gcstate)->generations[n].head) - -void + +void _PyGC_InitState(GCState *gcstate) -{ +{ gcstate->enabled = 1; /* automatic collection enabled? */ - + #define _GEN_HEAD(n) GEN_HEAD(gcstate, n) - struct gc_generation generations[NUM_GENERATIONS] = { + struct gc_generation generations[NUM_GENERATIONS] = { /* PyGC_Head, threshold, count */ {{(uintptr_t)_GEN_HEAD(0), (uintptr_t)_GEN_HEAD(0)}, 700, 0}, {{(uintptr_t)_GEN_HEAD(1), (uintptr_t)_GEN_HEAD(1)}, 10, 0}, {{(uintptr_t)_GEN_HEAD(2), (uintptr_t)_GEN_HEAD(2)}, 10, 0}, - }; - for (int i = 0; i < NUM_GENERATIONS; i++) { + }; + for (int i = 0; i < NUM_GENERATIONS; i++) { gcstate->generations[i] = generations[i]; - }; + }; gcstate->generation0 = GEN_HEAD(gcstate, 0); - struct gc_generation permanent_generation = { + struct gc_generation permanent_generation = { {(uintptr_t)&gcstate->permanent_generation.head, (uintptr_t)&gcstate->permanent_generation.head}, 0, 0 - }; + }; gcstate->permanent_generation = permanent_generation; -} - +} + PyStatus _PyGC_Init(PyThreadState *tstate) @@ -169,23 +169,23 @@ _PyGC_Init(PyThreadState *tstate) /* _gc_prev values --------------- - + Between collections, _gc_prev is used for doubly linked list. - + Lowest two bits of _gc_prev are used for flags. PREV_MASK_COLLECTING is used only while collecting and cleared before GC ends or _PyObject_GC_UNTRACK() is called. - + During a collection, _gc_prev is temporary used for gc_refs, and the gc list is singly linked until _gc_prev is restored. - + gc_refs - At the start of a collection, update_refs() copies the true refcount - to gc_refs, for each object in the generation being collected. - subtract_refs() then adjusts gc_refs so that it equals the number of - times an object is referenced directly from outside the generation - being collected. - + At the start of a collection, update_refs() copies the true refcount + to gc_refs, for each object in the generation being collected. + subtract_refs() then adjusts gc_refs so that it equals the number of + times an object is referenced directly from outside the generation + being collected. + PREV_MASK_COLLECTING Objects in generation being collected are marked PREV_MASK_COLLECTING in update_refs(). @@ -205,39 +205,39 @@ _gc_next takes these values: NEXT_MASK_UNREACHABLE flag described below. NEXT_MASK_UNREACHABLE - move_unreachable() then moves objects not reachable (whether directly or + move_unreachable() then moves objects not reachable (whether directly or indirectly) from outside the generation into an "unreachable" set and set this flag. - + Objects that are found to be reachable have gc_refs set to 1. When this flag is set for the reachable object, the object must be in "unreachable" set. The flag is unset and the object is moved back to "reachable" set. move_legacy_finalizers() will remove this flag from "unreachable" set. -*/ - -/*** list functions ***/ - +*/ + +/*** list functions ***/ + static inline void -gc_list_init(PyGC_Head *list) -{ +gc_list_init(PyGC_Head *list) +{ // List header must not have flags. // We can assign pointer by simple cast. list->_gc_prev = (uintptr_t)list; list->_gc_next = (uintptr_t)list; -} - +} + static inline int -gc_list_is_empty(PyGC_Head *list) -{ +gc_list_is_empty(PyGC_Head *list) +{ return (list->_gc_next == (uintptr_t)list); -} - -/* Append `node` to `list`. */ +} + +/* Append `node` to `list`. */ static inline void -gc_list_append(PyGC_Head *node, PyGC_Head *list) -{ +gc_list_append(PyGC_Head *node, PyGC_Head *list) +{ PyGC_Head *last = (PyGC_Head *)list->_gc_prev; // last <-> node @@ -247,12 +247,12 @@ gc_list_append(PyGC_Head *node, PyGC_Head *list) // node <-> list _PyGCHead_SET_NEXT(node, list); list->_gc_prev = (uintptr_t)node; -} - -/* Remove `node` from the gc list it's currently in. */ +} + +/* Remove `node` from the gc list it's currently in. */ static inline void -gc_list_remove(PyGC_Head *node) -{ +gc_list_remove(PyGC_Head *node) +{ PyGC_Head *prev = GC_PREV(node); PyGC_Head *next = GC_NEXT(node); @@ -260,36 +260,36 @@ gc_list_remove(PyGC_Head *node) _PyGCHead_SET_PREV(next, prev); node->_gc_next = 0; /* object is not currently tracked */ -} - -/* Move `node` from the gc list it's currently in (which is not explicitly - * named here) to the end of `list`. This is semantically the same as - * gc_list_remove(node) followed by gc_list_append(node, list). - */ -static void -gc_list_move(PyGC_Head *node, PyGC_Head *list) -{ - /* Unlink from current list. */ +} + +/* Move `node` from the gc list it's currently in (which is not explicitly + * named here) to the end of `list`. This is semantically the same as + * gc_list_remove(node) followed by gc_list_append(node, list). + */ +static void +gc_list_move(PyGC_Head *node, PyGC_Head *list) +{ + /* Unlink from current list. */ PyGC_Head *from_prev = GC_PREV(node); PyGC_Head *from_next = GC_NEXT(node); _PyGCHead_SET_NEXT(from_prev, from_next); _PyGCHead_SET_PREV(from_next, from_prev); - /* Relink at end of new list. */ + /* Relink at end of new list. */ // list must not have flags. So we can skip macros. PyGC_Head *to_prev = (PyGC_Head*)list->_gc_prev; _PyGCHead_SET_PREV(node, to_prev); _PyGCHead_SET_NEXT(to_prev, node); list->_gc_prev = (uintptr_t)node; _PyGCHead_SET_NEXT(node, list); -} - -/* append list `from` onto list `to`; `from` becomes an empty list */ -static void -gc_list_merge(PyGC_Head *from, PyGC_Head *to) -{ - assert(from != to); - if (!gc_list_is_empty(from)) { +} + +/* append list `from` onto list `to`; `from` becomes an empty list */ +static void +gc_list_merge(PyGC_Head *from, PyGC_Head *to) +{ + assert(from != to); + if (!gc_list_is_empty(from)) { PyGC_Head *to_tail = GC_PREV(to); PyGC_Head *from_head = GC_NEXT(from); PyGC_Head *from_tail = GC_PREV(from); @@ -301,21 +301,21 @@ gc_list_merge(PyGC_Head *from, PyGC_Head *to) _PyGCHead_SET_NEXT(from_tail, to); _PyGCHead_SET_PREV(to, from_tail); - } - gc_list_init(from); -} - -static Py_ssize_t -gc_list_size(PyGC_Head *list) -{ - PyGC_Head *gc; - Py_ssize_t n = 0; + } + gc_list_init(from); +} + +static Py_ssize_t +gc_list_size(PyGC_Head *list) +{ + PyGC_Head *gc; + Py_ssize_t n = 0; for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(gc)) { - n++; - } - return n; -} - + n++; + } + return n; +} + /* Walk the list and mark all objects as non-collecting */ static inline void gc_list_clear_collecting(PyGC_Head *collectable) @@ -326,24 +326,24 @@ gc_list_clear_collecting(PyGC_Head *collectable) } } -/* Append objects in a GC list to a Python list. +/* Append objects in a GC list to a Python list. * Return 0 if all OK, < 0 if error (out of memory for list) - */ -static int -append_objects(PyObject *py_list, PyGC_Head *gc_list) -{ - PyGC_Head *gc; + */ +static int +append_objects(PyObject *py_list, PyGC_Head *gc_list) +{ + PyGC_Head *gc; for (gc = GC_NEXT(gc_list); gc != gc_list; gc = GC_NEXT(gc)) { - PyObject *op = FROM_GC(gc); - if (op != py_list) { - if (PyList_Append(py_list, op)) { - return -1; /* exception */ - } - } - } - return 0; -} - + PyObject *op = FROM_GC(gc); + if (op != py_list) { + if (PyList_Append(py_list, op)) { + return -1; /* exception */ + } + } + } + return 0; +} + // Constants for validate_list's flags argument. enum flagstates {collecting_clear_unreachable_clear, collecting_clear_unreachable_set, @@ -400,86 +400,86 @@ validate_list(PyGC_Head *head, enum flagstates flags) #define validate_list(x, y) do{}while(0) #endif -/*** end of list stuff ***/ - - +/*** end of list stuff ***/ + + /* Set all gc_refs = ob_refcnt. After this, gc_refs is > 0 and * PREV_MASK_COLLECTING bit is set for all objects in containers. - */ -static void -update_refs(PyGC_Head *containers) -{ + */ +static void +update_refs(PyGC_Head *containers) +{ PyGC_Head *gc = GC_NEXT(containers); for (; gc != containers; gc = GC_NEXT(gc)) { gc_reset_refs(gc, Py_REFCNT(FROM_GC(gc))); - /* Python's cyclic gc should never see an incoming refcount - * of 0: if something decref'ed to 0, it should have been - * deallocated immediately at that time. - * Possible cause (if the assert triggers): a tp_dealloc - * routine left a gc-aware object tracked during its teardown - * phase, and did something-- or allowed something to happen -- - * that called back into Python. gc can trigger then, and may - * see the still-tracked dying object. Before this assert - * was added, such mistakes went on to allow gc to try to - * delete the object again. In a debug build, that caused - * a mysterious segfault, when _Py_ForgetReference tried - * to remove the object from the doubly-linked list of all - * objects a second time. In a release build, an actual - * double deallocation occurred, which leads to corruption - * of the allocator's internal bookkeeping pointers. That's - * so serious that maybe this should be a release-build - * check instead of an assert? - */ + /* Python's cyclic gc should never see an incoming refcount + * of 0: if something decref'ed to 0, it should have been + * deallocated immediately at that time. + * Possible cause (if the assert triggers): a tp_dealloc + * routine left a gc-aware object tracked during its teardown + * phase, and did something-- or allowed something to happen -- + * that called back into Python. gc can trigger then, and may + * see the still-tracked dying object. Before this assert + * was added, such mistakes went on to allow gc to try to + * delete the object again. In a debug build, that caused + * a mysterious segfault, when _Py_ForgetReference tried + * to remove the object from the doubly-linked list of all + * objects a second time. In a release build, an actual + * double deallocation occurred, which leads to corruption + * of the allocator's internal bookkeeping pointers. That's + * so serious that maybe this should be a release-build + * check instead of an assert? + */ _PyObject_ASSERT(FROM_GC(gc), gc_get_refs(gc) != 0); - } -} - -/* A traversal callback for subtract_refs. */ -static int + } +} + +/* A traversal callback for subtract_refs. */ +static int visit_decref(PyObject *op, void *parent) -{ +{ _PyObject_ASSERT(_PyObject_CAST(parent), !_PyObject_IsFreed(op)); if (_PyObject_IS_GC(op)) { - PyGC_Head *gc = AS_GC(op); - /* We're only interested in gc_refs for objects in the - * generation being collected, which can be recognized - * because only they have positive gc_refs. - */ + PyGC_Head *gc = AS_GC(op); + /* We're only interested in gc_refs for objects in the + * generation being collected, which can be recognized + * because only they have positive gc_refs. + */ if (gc_is_collecting(gc)) { gc_decref(gc); } - } - return 0; -} - -/* Subtract internal references from gc_refs. After this, gc_refs is >= 0 - * for all objects in containers, and is GC_REACHABLE for all tracked gc - * objects not in containers. The ones with gc_refs > 0 are directly - * reachable from outside containers, and so can't be collected. - */ -static void -subtract_refs(PyGC_Head *containers) -{ - traverseproc traverse; + } + return 0; +} + +/* Subtract internal references from gc_refs. After this, gc_refs is >= 0 + * for all objects in containers, and is GC_REACHABLE for all tracked gc + * objects not in containers. The ones with gc_refs > 0 are directly + * reachable from outside containers, and so can't be collected. + */ +static void +subtract_refs(PyGC_Head *containers) +{ + traverseproc traverse; PyGC_Head *gc = GC_NEXT(containers); for (; gc != containers; gc = GC_NEXT(gc)) { PyObject *op = FROM_GC(gc); traverse = Py_TYPE(op)->tp_traverse; - (void) traverse(FROM_GC(gc), - (visitproc)visit_decref, + (void) traverse(FROM_GC(gc), + (visitproc)visit_decref, op); - } -} - -/* A traversal callback for move_unreachable. */ -static int -visit_reachable(PyObject *op, PyGC_Head *reachable) -{ + } +} + +/* A traversal callback for move_unreachable. */ +static int +visit_reachable(PyObject *op, PyGC_Head *reachable) +{ if (!_PyObject_IS_GC(op)) { return 0; } - + PyGC_Head *gc = AS_GC(op); const Py_ssize_t gc_refs = gc_get_refs(gc); @@ -500,7 +500,7 @@ visit_reachable(PyObject *op, PyGC_Head *reachable) * Move it back to move_unreachable's 'young' list, * and move_unreachable will eventually get to it * again. - */ + */ // Manually unlink gc from unreachable list because the list functions // don't work right in the presence of NEXT_MASK_UNREACHABLE flags. PyGC_Head *prev = GC_PREV(gc); @@ -514,7 +514,7 @@ visit_reachable(PyObject *op, PyGC_Head *reachable) gc_list_append(gc, reachable); gc_set_refs(gc, 1); - } + } else if (gc_refs == 0) { /* This is in move_unreachable's 'young' list, but * the traversal hasn't yet gotten to it. All @@ -530,54 +530,54 @@ visit_reachable(PyObject *op, PyGC_Head *reachable) else { _PyObject_ASSERT_WITH_MSG(op, gc_refs > 0, "refcount is too small"); } - return 0; -} - -/* Move the unreachable objects from young to unreachable. After this, + return 0; +} + +/* Move the unreachable objects from young to unreachable. After this, * all objects in young don't have PREV_MASK_COLLECTING flag and * unreachable have the flag. - * All objects in young after this are directly or indirectly reachable - * from outside the original young; and all objects in unreachable are - * not. + * All objects in young after this are directly or indirectly reachable + * from outside the original young; and all objects in unreachable are + * not. * * This function restores _gc_prev pointer. young and unreachable are * doubly linked list after this function. * But _gc_next in unreachable list has NEXT_MASK_UNREACHABLE flag. * So we can not gc_list_* functions for unreachable until we remove the flag. - */ -static void -move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) -{ + */ +static void +move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) +{ // previous elem in the young list, used for restore gc_prev. PyGC_Head *prev = young; PyGC_Head *gc = GC_NEXT(young); - + /* Invariants: all objects "to the left" of us in young are reachable * (directly or indirectly) from outside the young list as it was at entry. * * All other objects from the original young "to the left" of us are in * unreachable now, and have NEXT_MASK_UNREACHABLE. All objects to the - * left of us in 'young' now have been scanned, and no objects here - * or to the right have been scanned yet. - */ - - while (gc != young) { + * left of us in 'young' now have been scanned, and no objects here + * or to the right have been scanned yet. + */ + + while (gc != young) { if (gc_get_refs(gc)) { - /* gc is definitely reachable from outside the - * original 'young'. Mark it as such, and traverse - * its pointers to find any other objects that may - * be directly reachable from it. Note that the - * call to tp_traverse may append objects to young, - * so we have to wait until it returns to determine - * the next object to visit. - */ - PyObject *op = FROM_GC(gc); - traverseproc traverse = Py_TYPE(op)->tp_traverse; + /* gc is definitely reachable from outside the + * original 'young'. Mark it as such, and traverse + * its pointers to find any other objects that may + * be directly reachable from it. Note that the + * call to tp_traverse may append objects to young, + * so we have to wait until it returns to determine + * the next object to visit. + */ + PyObject *op = FROM_GC(gc); + traverseproc traverse = Py_TYPE(op)->tp_traverse; _PyObject_ASSERT_WITH_MSG(op, gc_get_refs(gc) > 0, "refcount is too small"); // NOTE: visit_reachable may change gc->_gc_next when // young->_gc_prev == gc. Don't do gc = GC_NEXT(gc) before! - (void) traverse(op, + (void) traverse(op, (visitproc)visit_reachable, (void *)young); // relink gc_prev to prev element. @@ -585,15 +585,15 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) // gc is not COLLECTING state after here. gc_clear_collecting(gc); prev = gc; - } - else { - /* This *may* be unreachable. To make progress, - * assume it is. gc isn't directly reachable from - * any object we've already traversed, but may be - * reachable from an object we haven't gotten to yet. - * visit_reachable will eventually move gc back into - * young if that's so, and we'll see it again. - */ + } + else { + /* This *may* be unreachable. To make progress, + * assume it is. gc isn't directly reachable from + * any object we've already traversed, but may be + * reachable from an object we haven't gotten to yet. + * visit_reachable will eventually move gc back into + * young if that's so, and we'll see it again. + */ // Move gc to unreachable. // No need to gc->next->prev = prev because it is single linked. prev->_gc_next = gc->_gc_next; @@ -610,7 +610,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) _PyGCHead_SET_PREV(gc, last); gc->_gc_next = (NEXT_MASK_UNREACHABLE | (uintptr_t)unreachable); unreachable->_gc_prev = (uintptr_t)gc; - } + } gc = (PyGC_Head*)prev->_gc_next; } // young->_gc_prev must be last element remained in the list. @@ -629,60 +629,60 @@ untrack_tuples(PyGC_Head *head) if (PyTuple_CheckExact(op)) { _PyTuple_MaybeUntrack(op); } - gc = next; - } -} - -/* Try to untrack all currently tracked dictionaries */ -static void -untrack_dicts(PyGC_Head *head) -{ + gc = next; + } +} + +/* Try to untrack all currently tracked dictionaries */ +static void +untrack_dicts(PyGC_Head *head) +{ PyGC_Head *next, *gc = GC_NEXT(head); - while (gc != head) { - PyObject *op = FROM_GC(gc); + while (gc != head) { + PyObject *op = FROM_GC(gc); next = GC_NEXT(gc); if (PyDict_CheckExact(op)) { - _PyDict_MaybeUntrack(op); + _PyDict_MaybeUntrack(op); } - gc = next; - } -} - -/* Return true if object has a pre-PEP 442 finalization method. */ -static int -has_legacy_finalizer(PyObject *op) -{ + gc = next; + } +} + +/* Return true if object has a pre-PEP 442 finalization method. */ +static int +has_legacy_finalizer(PyObject *op) +{ return Py_TYPE(op)->tp_del != NULL; -} - -/* Move the objects in unreachable with tp_del slots into `finalizers`. +} + +/* Move the objects in unreachable with tp_del slots into `finalizers`. * * This function also removes NEXT_MASK_UNREACHABLE flag * from _gc_next in unreachable. - */ -static void -move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) -{ + */ +static void +move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) +{ PyGC_Head *gc, *next; assert((unreachable->_gc_next & NEXT_MASK_UNREACHABLE) == 0); - - /* March over unreachable. Move objects with finalizers into - * `finalizers`. - */ + + /* March over unreachable. Move objects with finalizers into + * `finalizers`. + */ for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) { - PyObject *op = FROM_GC(gc); - + PyObject *op = FROM_GC(gc); + _PyObject_ASSERT(op, gc->_gc_next & NEXT_MASK_UNREACHABLE); gc->_gc_next &= ~NEXT_MASK_UNREACHABLE; next = (PyGC_Head*)gc->_gc_next; - - if (has_legacy_finalizer(op)) { + + if (has_legacy_finalizer(op)) { gc_clear_collecting(gc); - gc_list_move(gc, finalizers); - } - } -} - + gc_list_move(gc, finalizers); + } + } +} + static inline void clear_unreachable_mask(PyGC_Head *unreachable) { @@ -699,74 +699,74 @@ clear_unreachable_mask(PyGC_Head *unreachable) validate_list(unreachable, collecting_set_unreachable_clear); } -/* A traversal callback for move_legacy_finalizer_reachable. */ -static int -visit_move(PyObject *op, PyGC_Head *tolist) -{ +/* A traversal callback for move_legacy_finalizer_reachable. */ +static int +visit_move(PyObject *op, PyGC_Head *tolist) +{ if (_PyObject_IS_GC(op)) { PyGC_Head *gc = AS_GC(op); if (gc_is_collecting(gc)) { - gc_list_move(gc, tolist); + gc_list_move(gc, tolist); gc_clear_collecting(gc); - } - } - return 0; -} - -/* Move objects that are reachable from finalizers, from the unreachable set - * into finalizers set. - */ -static void -move_legacy_finalizer_reachable(PyGC_Head *finalizers) -{ - traverseproc traverse; + } + } + return 0; +} + +/* Move objects that are reachable from finalizers, from the unreachable set + * into finalizers set. + */ +static void +move_legacy_finalizer_reachable(PyGC_Head *finalizers) +{ + traverseproc traverse; PyGC_Head *gc = GC_NEXT(finalizers); for (; gc != finalizers; gc = GC_NEXT(gc)) { - /* Note that the finalizers list may grow during this. */ - traverse = Py_TYPE(FROM_GC(gc))->tp_traverse; - (void) traverse(FROM_GC(gc), - (visitproc)visit_move, - (void *)finalizers); - } -} - -/* Clear all weakrefs to unreachable objects, and if such a weakref has a - * callback, invoke it if necessary. Note that it's possible for such - * weakrefs to be outside the unreachable set -- indeed, those are precisely - * the weakrefs whose callbacks must be invoked. See gc_weakref.txt for - * overview & some details. Some weakrefs with callbacks may be reclaimed - * directly by this routine; the number reclaimed is the return value. Other - * weakrefs with callbacks may be moved into the `old` generation. Objects - * moved into `old` have gc_refs set to GC_REACHABLE; the objects remaining in - * unreachable are left at GC_TENTATIVELY_UNREACHABLE. When this returns, - * no object in `unreachable` is weakly referenced anymore. - */ -static int -handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) -{ - PyGC_Head *gc; - PyObject *op; /* generally FROM_GC(gc) */ - PyWeakReference *wr; /* generally a cast of op */ - PyGC_Head wrcb_to_call; /* weakrefs with callbacks to call */ - PyGC_Head *next; - int num_freed = 0; - - gc_list_init(&wrcb_to_call); - - /* Clear all weakrefs to the objects in unreachable. If such a weakref - * also has a callback, move it into `wrcb_to_call` if the callback - * needs to be invoked. Note that we cannot invoke any callbacks until - * all weakrefs to unreachable objects are cleared, lest the callback - * resurrect an unreachable object via a still-active weakref. We - * make another pass over wrcb_to_call, invoking callbacks, after this - * pass completes. - */ + /* Note that the finalizers list may grow during this. */ + traverse = Py_TYPE(FROM_GC(gc))->tp_traverse; + (void) traverse(FROM_GC(gc), + (visitproc)visit_move, + (void *)finalizers); + } +} + +/* Clear all weakrefs to unreachable objects, and if such a weakref has a + * callback, invoke it if necessary. Note that it's possible for such + * weakrefs to be outside the unreachable set -- indeed, those are precisely + * the weakrefs whose callbacks must be invoked. See gc_weakref.txt for + * overview & some details. Some weakrefs with callbacks may be reclaimed + * directly by this routine; the number reclaimed is the return value. Other + * weakrefs with callbacks may be moved into the `old` generation. Objects + * moved into `old` have gc_refs set to GC_REACHABLE; the objects remaining in + * unreachable are left at GC_TENTATIVELY_UNREACHABLE. When this returns, + * no object in `unreachable` is weakly referenced anymore. + */ +static int +handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) +{ + PyGC_Head *gc; + PyObject *op; /* generally FROM_GC(gc) */ + PyWeakReference *wr; /* generally a cast of op */ + PyGC_Head wrcb_to_call; /* weakrefs with callbacks to call */ + PyGC_Head *next; + int num_freed = 0; + + gc_list_init(&wrcb_to_call); + + /* Clear all weakrefs to the objects in unreachable. If such a weakref + * also has a callback, move it into `wrcb_to_call` if the callback + * needs to be invoked. Note that we cannot invoke any callbacks until + * all weakrefs to unreachable objects are cleared, lest the callback + * resurrect an unreachable object via a still-active weakref. We + * make another pass over wrcb_to_call, invoking callbacks, after this + * pass completes. + */ for (gc = GC_NEXT(unreachable); gc != unreachable; gc = next) { - PyWeakReference **wrlist; - - op = FROM_GC(gc); + PyWeakReference **wrlist; + + op = FROM_GC(gc); next = GC_NEXT(gc); - + if (PyWeakref_Check(op)) { /* A weakref inside the unreachable set must be cleared. If we * allow its callback to execute inside delete_garbage(), it @@ -782,32 +782,32 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) _PyWeakref_ClearRef((PyWeakReference *)op); } - if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) - continue; - - /* It supports weakrefs. Does it have any? */ - wrlist = (PyWeakReference **) + if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) + continue; + + /* It supports weakrefs. Does it have any? */ + wrlist = (PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(op); - - /* `op` may have some weakrefs. March over the list, clear - * all the weakrefs, and move the weakrefs with callbacks - * that must be called into wrcb_to_call. - */ - for (wr = *wrlist; wr != NULL; wr = *wrlist) { - PyGC_Head *wrasgc; /* AS_GC(wr) */ - - /* _PyWeakref_ClearRef clears the weakref but leaves - * the callback pointer intact. Obscure: it also - * changes *wrlist. - */ + + /* `op` may have some weakrefs. March over the list, clear + * all the weakrefs, and move the weakrefs with callbacks + * that must be called into wrcb_to_call. + */ + for (wr = *wrlist; wr != NULL; wr = *wrlist) { + PyGC_Head *wrasgc; /* AS_GC(wr) */ + + /* _PyWeakref_ClearRef clears the weakref but leaves + * the callback pointer intact. Obscure: it also + * changes *wrlist. + */ _PyObject_ASSERT((PyObject *)wr, wr->wr_object == op); - _PyWeakref_ClearRef(wr); + _PyWeakref_ClearRef(wr); _PyObject_ASSERT((PyObject *)wr, wr->wr_object == Py_None); if (wr->wr_callback == NULL) { /* no callback */ continue; } - + /* Headache time. `op` is going away, and is weakly referenced by * `wr`, which has a callback. Should the callback be invoked? If wr * is also trash, no: @@ -839,155 +839,155 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) if (gc_is_collecting(AS_GC(wr))) { /* it should already have been cleared above */ assert(wr->wr_object == Py_None); - continue; + continue; } - - /* Create a new reference so that wr can't go away - * before we can process it again. - */ - Py_INCREF(wr); - - /* Move wr to wrcb_to_call, for the next pass. */ - wrasgc = AS_GC(wr); - assert(wrasgc != next); /* wrasgc is reachable, but - next isn't, so they can't - be the same */ - gc_list_move(wrasgc, &wrcb_to_call); - } - } - - /* Invoke the callbacks we decided to honor. It's safe to invoke them - * because they can't reference unreachable objects. - */ - while (! gc_list_is_empty(&wrcb_to_call)) { - PyObject *temp; - PyObject *callback; - + + /* Create a new reference so that wr can't go away + * before we can process it again. + */ + Py_INCREF(wr); + + /* Move wr to wrcb_to_call, for the next pass. */ + wrasgc = AS_GC(wr); + assert(wrasgc != next); /* wrasgc is reachable, but + next isn't, so they can't + be the same */ + gc_list_move(wrasgc, &wrcb_to_call); + } + } + + /* Invoke the callbacks we decided to honor. It's safe to invoke them + * because they can't reference unreachable objects. + */ + while (! gc_list_is_empty(&wrcb_to_call)) { + PyObject *temp; + PyObject *callback; + gc = (PyGC_Head*)wrcb_to_call._gc_next; - op = FROM_GC(gc); + op = FROM_GC(gc); _PyObject_ASSERT(op, PyWeakref_Check(op)); - wr = (PyWeakReference *)op; - callback = wr->wr_callback; + wr = (PyWeakReference *)op; + callback = wr->wr_callback; _PyObject_ASSERT(op, callback != NULL); - - /* copy-paste of weakrefobject.c's handle_callback() */ + + /* copy-paste of weakrefobject.c's handle_callback() */ temp = PyObject_CallOneArg(callback, (PyObject *)wr); - if (temp == NULL) - PyErr_WriteUnraisable(callback); - else - Py_DECREF(temp); - - /* Give up the reference we created in the first pass. When - * op's refcount hits 0 (which it may or may not do right now), - * op's tp_dealloc will decref op->wr_callback too. Note - * that the refcount probably will hit 0 now, and because this - * weakref was reachable to begin with, gc didn't already - * add it to its count of freed objects. Example: a reachable - * weak value dict maps some key to this reachable weakref. - * The callback removes this key->weakref mapping from the - * dict, leaving no other references to the weakref (excepting - * ours). - */ - Py_DECREF(op); + if (temp == NULL) + PyErr_WriteUnraisable(callback); + else + Py_DECREF(temp); + + /* Give up the reference we created in the first pass. When + * op's refcount hits 0 (which it may or may not do right now), + * op's tp_dealloc will decref op->wr_callback too. Note + * that the refcount probably will hit 0 now, and because this + * weakref was reachable to begin with, gc didn't already + * add it to its count of freed objects. Example: a reachable + * weak value dict maps some key to this reachable weakref. + * The callback removes this key->weakref mapping from the + * dict, leaving no other references to the weakref (excepting + * ours). + */ + Py_DECREF(op); if (wrcb_to_call._gc_next == (uintptr_t)gc) { - /* object is still alive -- move it */ - gc_list_move(gc, old); - } + /* object is still alive -- move it */ + gc_list_move(gc, old); + } else { - ++num_freed; + ++num_freed; } - } - - return num_freed; -} - -static void -debug_cycle(const char *msg, PyObject *op) -{ - PySys_FormatStderr("gc: %s <%s %p>\n", - msg, Py_TYPE(op)->tp_name, op); -} - -/* Handle uncollectable garbage (cycles with tp_del slots, and stuff reachable - * only from such cycles). - * If DEBUG_SAVEALL, all objects in finalizers are appended to the module - * garbage list (a Python list), else only the objects in finalizers with - * __del__ methods are appended to garbage. All objects in finalizers are - * merged into the old list regardless. - */ -static void + } + + return num_freed; +} + +static void +debug_cycle(const char *msg, PyObject *op) +{ + PySys_FormatStderr("gc: %s <%s %p>\n", + msg, Py_TYPE(op)->tp_name, op); +} + +/* Handle uncollectable garbage (cycles with tp_del slots, and stuff reachable + * only from such cycles). + * If DEBUG_SAVEALL, all objects in finalizers are appended to the module + * garbage list (a Python list), else only the objects in finalizers with + * __del__ methods are appended to garbage. All objects in finalizers are + * merged into the old list regardless. + */ +static void handle_legacy_finalizers(PyThreadState *tstate, GCState *gcstate, PyGC_Head *finalizers, PyGC_Head *old) -{ +{ assert(!_PyErr_Occurred(tstate)); assert(gcstate->garbage != NULL); - + PyGC_Head *gc = GC_NEXT(finalizers); for (; gc != finalizers; gc = GC_NEXT(gc)) { - PyObject *op = FROM_GC(gc); - + PyObject *op = FROM_GC(gc); + if ((gcstate->debug & DEBUG_SAVEALL) || has_legacy_finalizer(op)) { if (PyList_Append(gcstate->garbage, op) < 0) { _PyErr_Clear(tstate); - break; + break; } - } - } - - gc_list_merge(finalizers, old); -} - -/* Run first-time finalizers (if any) on all the objects in collectable. - * Note that this may remove some (or even all) of the objects from the - * list, due to refcounts falling to 0. - */ -static void + } + } + + gc_list_merge(finalizers, old); +} + +/* Run first-time finalizers (if any) on all the objects in collectable. + * Note that this may remove some (or even all) of the objects from the + * list, due to refcounts falling to 0. + */ +static void finalize_garbage(PyThreadState *tstate, PyGC_Head *collectable) -{ - destructor finalize; - PyGC_Head seen; - - /* While we're going through the loop, `finalize(op)` may cause op, or - * other objects, to be reclaimed via refcounts falling to zero. So - * there's little we can rely on about the structure of the input - * `collectable` list across iterations. For safety, we always take the - * first object in that list and move it to a temporary `seen` list. - * If objects vanish from the `collectable` and `seen` lists we don't - * care. - */ - gc_list_init(&seen); - - while (!gc_list_is_empty(collectable)) { +{ + destructor finalize; + PyGC_Head seen; + + /* While we're going through the loop, `finalize(op)` may cause op, or + * other objects, to be reclaimed via refcounts falling to zero. So + * there's little we can rely on about the structure of the input + * `collectable` list across iterations. For safety, we always take the + * first object in that list and move it to a temporary `seen` list. + * If objects vanish from the `collectable` and `seen` lists we don't + * care. + */ + gc_list_init(&seen); + + while (!gc_list_is_empty(collectable)) { PyGC_Head *gc = GC_NEXT(collectable); - PyObject *op = FROM_GC(gc); - gc_list_move(gc, &seen); - if (!_PyGCHead_FINALIZED(gc) && - (finalize = Py_TYPE(op)->tp_finalize) != NULL) { + PyObject *op = FROM_GC(gc); + gc_list_move(gc, &seen); + if (!_PyGCHead_FINALIZED(gc) && + (finalize = Py_TYPE(op)->tp_finalize) != NULL) { _PyGCHead_SET_FINALIZED(gc); - Py_INCREF(op); - finalize(op); + Py_INCREF(op); + finalize(op); assert(!_PyErr_Occurred(tstate)); - Py_DECREF(op); - } - } - gc_list_merge(&seen, collectable); -} - -/* Break reference cycles by clearing the containers involved. This is - * tricky business as the lists can be changing and we don't know which - * objects may be freed. It is possible I screwed something up here. - */ -static void + Py_DECREF(op); + } + } + gc_list_merge(&seen, collectable); +} + +/* Break reference cycles by clearing the containers involved. This is + * tricky business as the lists can be changing and we don't know which + * objects may be freed. It is possible I screwed something up here. + */ +static void delete_garbage(PyThreadState *tstate, GCState *gcstate, PyGC_Head *collectable, PyGC_Head *old) -{ +{ assert(!_PyErr_Occurred(tstate)); - - while (!gc_list_is_empty(collectable)) { + + while (!gc_list_is_empty(collectable)) { PyGC_Head *gc = GC_NEXT(collectable); - PyObject *op = FROM_GC(gc); - + PyObject *op = FROM_GC(gc); + _PyObject_ASSERT_WITH_MSG(op, Py_REFCNT(op) > 0, "refcount is too small"); @@ -996,35 +996,35 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, if (PyList_Append(gcstate->garbage, op) < 0) { _PyErr_Clear(tstate); } - } - else { + } + else { inquiry clear; - if ((clear = Py_TYPE(op)->tp_clear) != NULL) { - Py_INCREF(op); + if ((clear = Py_TYPE(op)->tp_clear) != NULL) { + Py_INCREF(op); (void) clear(op); if (_PyErr_Occurred(tstate)) { _PyErr_WriteUnraisableMsg("in tp_clear of", (PyObject*)Py_TYPE(op)); } - Py_DECREF(op); - } - } + Py_DECREF(op); + } + } if (GC_NEXT(collectable) == gc) { - /* object is still alive, move it, it may die later */ + /* object is still alive, move it, it may die later */ gc_clear_collecting(gc); - gc_list_move(gc, old); - } - } -} - -/* Clear all free lists - * All free lists are cleared during the collection of the highest generation. - * Allocated items in the free list may keep a pymalloc arena occupied. - * Clearing the free lists may give back memory to the OS earlier. - */ -static void -clear_freelists(void) -{ + gc_list_move(gc, old); + } + } +} + +/* Clear all free lists + * All free lists are cleared during the collection of the highest generation. + * Allocated items in the free list may keep a pymalloc arena occupied. + * Clearing the free lists may give back memory to the OS earlier. + */ +static void +clear_freelists(void) +{ _PyFrame_ClearFreeList(); _PyTuple_ClearFreeList(); _PyFloat_ClearFreeList(); @@ -1032,8 +1032,8 @@ clear_freelists(void) _PyDict_ClearFreeList(); _PyAsyncGen_ClearFreeLists(); _PyContext_ClearFreeList(); -} - +} + // Show stats for objects in each generations static void show_stats_each_generations(GCState *gcstate) @@ -1164,107 +1164,107 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable, gc_list_merge(resurrected, old_generation); } -/* This is the main function. Read this to understand how the - * collection process works. */ -static Py_ssize_t +/* This is the main function. Read this to understand how the + * collection process works. */ +static Py_ssize_t collect(PyThreadState *tstate, int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, int nofail) -{ - int i; - Py_ssize_t m = 0; /* # objects collected */ - Py_ssize_t n = 0; /* # unreachable objects that couldn't be collected */ - PyGC_Head *young; /* the generation we are examining */ - PyGC_Head *old; /* next older generation */ - PyGC_Head unreachable; /* non-problematic unreachable trash */ - PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ - PyGC_Head *gc; - _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ +{ + int i; + Py_ssize_t m = 0; /* # objects collected */ + Py_ssize_t n = 0; /* # unreachable objects that couldn't be collected */ + PyGC_Head *young; /* the generation we are examining */ + PyGC_Head *old; /* next older generation */ + PyGC_Head unreachable; /* non-problematic unreachable trash */ + PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ + PyGC_Head *gc; + _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ GCState *gcstate = &tstate->interp->gc; - + if (gcstate->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); show_stats_each_generations(gcstate); - t1 = _PyTime_GetMonotonicClock(); - } - - if (PyDTrace_GC_START_ENABLED()) - PyDTrace_GC_START(generation); - - /* update collection and allocation counters */ - if (generation+1 < NUM_GENERATIONS) + t1 = _PyTime_GetMonotonicClock(); + } + + if (PyDTrace_GC_START_ENABLED()) + PyDTrace_GC_START(generation); + + /* update collection and allocation counters */ + if (generation+1 < NUM_GENERATIONS) gcstate->generations[generation+1].count += 1; - for (i = 0; i <= generation; i++) + for (i = 0; i <= generation; i++) gcstate->generations[i].count = 0; - - /* merge younger generations with one we are currently collecting */ - for (i = 0; i < generation; i++) { + + /* merge younger generations with one we are currently collecting */ + for (i = 0; i < generation; i++) { gc_list_merge(GEN_HEAD(gcstate, i), GEN_HEAD(gcstate, generation)); - } - - /* handy references */ + } + + /* handy references */ young = GEN_HEAD(gcstate, generation); - if (generation < NUM_GENERATIONS-1) + if (generation < NUM_GENERATIONS-1) old = GEN_HEAD(gcstate, generation+1); - else - old = young; + else + old = young; validate_list(old, collecting_clear_unreachable_clear); - + deduce_unreachable(young, &unreachable); - + untrack_tuples(young); - /* Move reachable objects to next generation. */ - if (young != old) { - if (generation == NUM_GENERATIONS - 2) { + /* Move reachable objects to next generation. */ + if (young != old) { + if (generation == NUM_GENERATIONS - 2) { gcstate->long_lived_pending += gc_list_size(young); - } - gc_list_merge(young, old); - } - else { + } + gc_list_merge(young, old); + } + else { /* We only un-track dicts in full collections, to avoid quadratic - dict build-up. See issue #14775. */ - untrack_dicts(young); + dict build-up. See issue #14775. */ + untrack_dicts(young); gcstate->long_lived_pending = 0; gcstate->long_lived_total = gc_list_size(young); - } - - /* All objects in unreachable are trash, but objects reachable from - * legacy finalizers (e.g. tp_del) can't safely be deleted. - */ - gc_list_init(&finalizers); + } + + /* All objects in unreachable are trash, but objects reachable from + * legacy finalizers (e.g. tp_del) can't safely be deleted. + */ + gc_list_init(&finalizers); // NEXT_MASK_UNREACHABLE is cleared here. // After move_legacy_finalizers(), unreachable is normal list. - move_legacy_finalizers(&unreachable, &finalizers); - /* finalizers contains the unreachable objects with a legacy finalizer; - * unreachable objects reachable *from* those are also uncollectable, - * and we move those into the finalizers list too. - */ - move_legacy_finalizer_reachable(&finalizers); - + move_legacy_finalizers(&unreachable, &finalizers); + /* finalizers contains the unreachable objects with a legacy finalizer; + * unreachable objects reachable *from* those are also uncollectable, + * and we move those into the finalizers list too. + */ + move_legacy_finalizer_reachable(&finalizers); + validate_list(&finalizers, collecting_clear_unreachable_clear); validate_list(&unreachable, collecting_set_unreachable_clear); /* Print debugging information. */ if (gcstate->debug & DEBUG_COLLECTABLE) { for (gc = GC_NEXT(&unreachable); gc != &unreachable; gc = GC_NEXT(gc)) { - debug_cycle("collectable", FROM_GC(gc)); - } - } - - /* Clear weakrefs and invoke callbacks as necessary. */ - m += handle_weakrefs(&unreachable, old); - + debug_cycle("collectable", FROM_GC(gc)); + } + } + + /* Clear weakrefs and invoke callbacks as necessary. */ + m += handle_weakrefs(&unreachable, old); + validate_list(old, collecting_clear_unreachable_clear); validate_list(&unreachable, collecting_set_unreachable_clear); - /* Call tp_finalize on objects which have one. */ + /* Call tp_finalize on objects which have one. */ finalize_garbage(tstate, &unreachable); - + /* Handle any objects that may have resurrected after the call * to 'finalize_garbage' and continue the collection with the * objects that are still unreachable */ PyGC_Head final_unreachable; handle_resurrected_objects(&unreachable, &final_unreachable, old); - + /* Call tp_clear on objects in the final_unreachable set. This will cause * the reference cycles to be broken. It may also cause some objects * in finalizers to be freed. @@ -1272,135 +1272,135 @@ collect(PyThreadState *tstate, int generation, m += gc_list_size(&final_unreachable); delete_garbage(tstate, gcstate, &final_unreachable, old); - /* Collect statistics on uncollectable objects found and print - * debugging information. */ + /* Collect statistics on uncollectable objects found and print + * debugging information. */ for (gc = GC_NEXT(&finalizers); gc != &finalizers; gc = GC_NEXT(gc)) { - n++; + n++; if (gcstate->debug & DEBUG_UNCOLLECTABLE) - debug_cycle("uncollectable", FROM_GC(gc)); - } + debug_cycle("uncollectable", FROM_GC(gc)); + } if (gcstate->debug & DEBUG_STATS) { double d = _PyTime_AsSecondsDouble(_PyTime_GetMonotonicClock() - t1); PySys_WriteStderr( "gc: done, %" PY_FORMAT_SIZE_T "d unreachable, " "%" PY_FORMAT_SIZE_T "d uncollectable, %.4fs elapsed\n", n+m, n, d); - } - - /* Append instances in the uncollectable set to a Python - * reachable list of garbage. The programmer has to deal with - * this if they insist on creating this type of structure. - */ + } + + /* Append instances in the uncollectable set to a Python + * reachable list of garbage. The programmer has to deal with + * this if they insist on creating this type of structure. + */ handle_legacy_finalizers(tstate, gcstate, &finalizers, old); validate_list(old, collecting_clear_unreachable_clear); - - /* Clear free list only during the collection of the highest - * generation */ - if (generation == NUM_GENERATIONS-1) { - clear_freelists(); - } - + + /* Clear free list only during the collection of the highest + * generation */ + if (generation == NUM_GENERATIONS-1) { + clear_freelists(); + } + if (_PyErr_Occurred(tstate)) { - if (nofail) { + if (nofail) { _PyErr_Clear(tstate); - } - else { + } + else { _PyErr_WriteUnraisableMsg("in garbage collection", NULL); - } - } - - /* Update stats */ + } + } + + /* Update stats */ if (n_collected) { - *n_collected = m; + *n_collected = m; } if (n_uncollectable) { - *n_uncollectable = n; + *n_uncollectable = n; } struct gc_generation_stats *stats = &gcstate->generation_stats[generation]; - stats->collections++; - stats->collected += m; - stats->uncollectable += n; - + stats->collections++; + stats->collected += m; + stats->uncollectable += n; + if (PyDTrace_GC_DONE_ENABLED()) { PyDTrace_GC_DONE(n + m); } - + assert(!_PyErr_Occurred(tstate)); return n + m; -} - -/* Invoke progress callbacks to notify clients that garbage collection - * is starting or stopping - */ -static void +} + +/* Invoke progress callbacks to notify clients that garbage collection + * is starting or stopping + */ +static void invoke_gc_callback(PyThreadState *tstate, const char *phase, int generation, Py_ssize_t collected, Py_ssize_t uncollectable) -{ +{ assert(!_PyErr_Occurred(tstate)); - - /* we may get called very early */ + + /* we may get called very early */ GCState *gcstate = &tstate->interp->gc; if (gcstate->callbacks == NULL) { - return; + return; } - /* The local variable cannot be rebound, check it for sanity */ + /* The local variable cannot be rebound, check it for sanity */ assert(PyList_CheckExact(gcstate->callbacks)); PyObject *info = NULL; if (PyList_GET_SIZE(gcstate->callbacks) != 0) { - info = Py_BuildValue("{sisnsn}", - "generation", generation, - "collected", collected, - "uncollectable", uncollectable); - if (info == NULL) { - PyErr_WriteUnraisable(NULL); - return; - } - } + info = Py_BuildValue("{sisnsn}", + "generation", generation, + "collected", collected, + "uncollectable", uncollectable); + if (info == NULL) { + PyErr_WriteUnraisable(NULL); + return; + } + } for (Py_ssize_t i=0; icallbacks); i++) { PyObject *r, *cb = PyList_GET_ITEM(gcstate->callbacks, i); - Py_INCREF(cb); /* make sure cb doesn't go away */ - r = PyObject_CallFunction(cb, "sO", phase, info); - if (r == NULL) { - PyErr_WriteUnraisable(cb); - } - else { - Py_DECREF(r); - } - Py_DECREF(cb); - } - Py_XDECREF(info); + Py_INCREF(cb); /* make sure cb doesn't go away */ + r = PyObject_CallFunction(cb, "sO", phase, info); + if (r == NULL) { + PyErr_WriteUnraisable(cb); + } + else { + Py_DECREF(r); + } + Py_DECREF(cb); + } + Py_XDECREF(info); assert(!_PyErr_Occurred(tstate)); -} - -/* Perform garbage collection of a generation and invoke - * progress callbacks. - */ -static Py_ssize_t +} + +/* Perform garbage collection of a generation and invoke + * progress callbacks. + */ +static Py_ssize_t collect_with_callback(PyThreadState *tstate, int generation) -{ +{ assert(!_PyErr_Occurred(tstate)); - Py_ssize_t result, collected, uncollectable; + Py_ssize_t result, collected, uncollectable; invoke_gc_callback(tstate, "start", generation, 0, 0); result = collect(tstate, generation, &collected, &uncollectable, 0); invoke_gc_callback(tstate, "stop", generation, collected, uncollectable); assert(!_PyErr_Occurred(tstate)); - return result; -} - -static Py_ssize_t + return result; +} + +static Py_ssize_t collect_generations(PyThreadState *tstate) -{ +{ GCState *gcstate = &tstate->interp->gc; - /* Find the oldest generation (highest numbered) where the count - * exceeds the threshold. Objects in the that generation and - * generations younger than it will be collected. */ + /* Find the oldest generation (highest numbered) where the count + * exceeds the threshold. Objects in the that generation and + * generations younger than it will be collected. */ Py_ssize_t n = 0; for (int i = NUM_GENERATIONS-1; i >= 0; i--) { if (gcstate->generations[i].count > gcstate->generations[i].threshold) { - /* Avoid quadratic performance degradation in number + /* Avoid quadratic performance degradation in number of tracked objects (see also issue #4074): To limit the cost of garbage collection, there are two strategies; @@ -1435,332 +1435,332 @@ collect_generations(PyThreadState *tstate) This heuristic was suggested by Martin von Löwis on python-dev in June 2008. His original analysis and proposal can be found at: http://mail.python.org/pipermail/python-dev/2008-June/080579.html - */ - if (i == NUM_GENERATIONS - 1 + */ + if (i == NUM_GENERATIONS - 1 && gcstate->long_lived_pending < gcstate->long_lived_total / 4) - continue; + continue; n = collect_with_callback(tstate, i); - break; - } - } - return n; -} - -#include "clinic/gcmodule.c.h" - -/*[clinic input] -gc.enable - -Enable automatic garbage collection. -[clinic start generated code]*/ - -static PyObject * -gc_enable_impl(PyObject *module) -/*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ -{ + break; + } + } + return n; +} + +#include "clinic/gcmodule.c.h" + +/*[clinic input] +gc.enable + +Enable automatic garbage collection. +[clinic start generated code]*/ + +static PyObject * +gc_enable_impl(PyObject *module) +/*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; gcstate->enabled = 1; - Py_RETURN_NONE; -} - -/*[clinic input] -gc.disable - -Disable automatic garbage collection. -[clinic start generated code]*/ - -static PyObject * -gc_disable_impl(PyObject *module) -/*[clinic end generated code: output=97d1030f7aa9d279 input=8c2e5a14e800d83b]*/ -{ + Py_RETURN_NONE; +} + +/*[clinic input] +gc.disable + +Disable automatic garbage collection. +[clinic start generated code]*/ + +static PyObject * +gc_disable_impl(PyObject *module) +/*[clinic end generated code: output=97d1030f7aa9d279 input=8c2e5a14e800d83b]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; gcstate->enabled = 0; - Py_RETURN_NONE; -} - -/*[clinic input] -gc.isenabled -> bool - -Returns true if automatic garbage collection is enabled. -[clinic start generated code]*/ - -static int -gc_isenabled_impl(PyObject *module) -/*[clinic end generated code: output=1874298331c49130 input=30005e0422373b31]*/ -{ + Py_RETURN_NONE; +} + +/*[clinic input] +gc.isenabled -> bool + +Returns true if automatic garbage collection is enabled. +[clinic start generated code]*/ + +static int +gc_isenabled_impl(PyObject *module) +/*[clinic end generated code: output=1874298331c49130 input=30005e0422373b31]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; return gcstate->enabled; -} - -/*[clinic input] -gc.collect -> Py_ssize_t - - generation: int(c_default="NUM_GENERATIONS - 1") = 2 - -Run the garbage collector. - -With no arguments, run a full collection. The optional argument -may be an integer specifying which generation to collect. A ValueError -is raised if the generation number is invalid. - -The number of unreachable objects is returned. -[clinic start generated code]*/ - -static Py_ssize_t -gc_collect_impl(PyObject *module, int generation) -/*[clinic end generated code: output=b697e633043233c7 input=40720128b682d879]*/ -{ +} + +/*[clinic input] +gc.collect -> Py_ssize_t + + generation: int(c_default="NUM_GENERATIONS - 1") = 2 + +Run the garbage collector. + +With no arguments, run a full collection. The optional argument +may be an integer specifying which generation to collect. A ValueError +is raised if the generation number is invalid. + +The number of unreachable objects is returned. +[clinic start generated code]*/ + +static Py_ssize_t +gc_collect_impl(PyObject *module, int generation) +/*[clinic end generated code: output=b697e633043233c7 input=40720128b682d879]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); - - if (generation < 0 || generation >= NUM_GENERATIONS) { + + if (generation < 0 || generation >= NUM_GENERATIONS) { _PyErr_SetString(tstate, PyExc_ValueError, "invalid generation"); - return -1; - } - + return -1; + } + GCState *gcstate = &tstate->interp->gc; Py_ssize_t n; if (gcstate->collecting) { /* already collecting, don't do anything */ n = 0; } - else { + else { gcstate->collecting = 1; n = collect_with_callback(tstate, generation); gcstate->collecting = 0; - } - return n; -} - -/*[clinic input] -gc.set_debug - - flags: int - An integer that can have the following bits turned on: - DEBUG_STATS - Print statistics during collection. - DEBUG_COLLECTABLE - Print collectable objects found. - DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects - found. - DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them. - DEBUG_LEAK - Debug leaking programs (everything but STATS). - / - -Set the garbage collection debugging flags. - -Debugging information is written to sys.stderr. -[clinic start generated code]*/ - -static PyObject * -gc_set_debug_impl(PyObject *module, int flags) -/*[clinic end generated code: output=7c8366575486b228 input=5e5ce15e84fbed15]*/ -{ + } + return n; +} + +/*[clinic input] +gc.set_debug + + flags: int + An integer that can have the following bits turned on: + DEBUG_STATS - Print statistics during collection. + DEBUG_COLLECTABLE - Print collectable objects found. + DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects + found. + DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them. + DEBUG_LEAK - Debug leaking programs (everything but STATS). + / + +Set the garbage collection debugging flags. + +Debugging information is written to sys.stderr. +[clinic start generated code]*/ + +static PyObject * +gc_set_debug_impl(PyObject *module, int flags) +/*[clinic end generated code: output=7c8366575486b228 input=5e5ce15e84fbed15]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; gcstate->debug = flags; - Py_RETURN_NONE; -} - -/*[clinic input] -gc.get_debug -> int - -Get the garbage collection debugging flags. -[clinic start generated code]*/ - -static int -gc_get_debug_impl(PyObject *module) -/*[clinic end generated code: output=91242f3506cd1e50 input=91a101e1c3b98366]*/ -{ + Py_RETURN_NONE; +} + +/*[clinic input] +gc.get_debug -> int + +Get the garbage collection debugging flags. +[clinic start generated code]*/ + +static int +gc_get_debug_impl(PyObject *module) +/*[clinic end generated code: output=91242f3506cd1e50 input=91a101e1c3b98366]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; return gcstate->debug; -} - -PyDoc_STRVAR(gc_set_thresh__doc__, -"set_threshold(threshold0, [threshold1, threshold2]) -> None\n" -"\n" -"Sets the collection thresholds. Setting threshold0 to zero disables\n" -"collection.\n"); - -static PyObject * +} + +PyDoc_STRVAR(gc_set_thresh__doc__, +"set_threshold(threshold0, [threshold1, threshold2]) -> None\n" +"\n" +"Sets the collection thresholds. Setting threshold0 to zero disables\n" +"collection.\n"); + +static PyObject * gc_set_threshold(PyObject *self, PyObject *args) -{ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; - if (!PyArg_ParseTuple(args, "i|ii:set_threshold", + if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &gcstate->generations[0].threshold, &gcstate->generations[1].threshold, &gcstate->generations[2].threshold)) - return NULL; + return NULL; for (int i = 3; i < NUM_GENERATIONS; i++) { - /* generations higher than 2 get the same threshold */ + /* generations higher than 2 get the same threshold */ gcstate->generations[i].threshold = gcstate->generations[2].threshold; - } - Py_RETURN_NONE; -} - -/*[clinic input] -gc.get_threshold - -Return the current collection thresholds. -[clinic start generated code]*/ - -static PyObject * -gc_get_threshold_impl(PyObject *module) -/*[clinic end generated code: output=7902bc9f41ecbbd8 input=286d79918034d6e6]*/ -{ + } + Py_RETURN_NONE; +} + +/*[clinic input] +gc.get_threshold + +Return the current collection thresholds. +[clinic start generated code]*/ + +static PyObject * +gc_get_threshold_impl(PyObject *module) +/*[clinic end generated code: output=7902bc9f41ecbbd8 input=286d79918034d6e6]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; - return Py_BuildValue("(iii)", + return Py_BuildValue("(iii)", gcstate->generations[0].threshold, gcstate->generations[1].threshold, gcstate->generations[2].threshold); -} - -/*[clinic input] -gc.get_count - -Return a three-tuple of the current collection counts. -[clinic start generated code]*/ - -static PyObject * -gc_get_count_impl(PyObject *module) -/*[clinic end generated code: output=354012e67b16398f input=a392794a08251751]*/ -{ +} + +/*[clinic input] +gc.get_count + +Return a three-tuple of the current collection counts. +[clinic start generated code]*/ + +static PyObject * +gc_get_count_impl(PyObject *module) +/*[clinic end generated code: output=354012e67b16398f input=a392794a08251751]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; - return Py_BuildValue("(iii)", + return Py_BuildValue("(iii)", gcstate->generations[0].count, gcstate->generations[1].count, gcstate->generations[2].count); -} - -static int -referrersvisit(PyObject* obj, PyObject *objs) -{ - Py_ssize_t i; - for (i = 0; i < PyTuple_GET_SIZE(objs); i++) - if (PyTuple_GET_ITEM(objs, i) == obj) - return 1; - return 0; -} - -static int -gc_referrers_for(PyObject *objs, PyGC_Head *list, PyObject *resultlist) -{ - PyGC_Head *gc; - PyObject *obj; - traverseproc traverse; +} + +static int +referrersvisit(PyObject* obj, PyObject *objs) +{ + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(objs); i++) + if (PyTuple_GET_ITEM(objs, i) == obj) + return 1; + return 0; +} + +static int +gc_referrers_for(PyObject *objs, PyGC_Head *list, PyObject *resultlist) +{ + PyGC_Head *gc; + PyObject *obj; + traverseproc traverse; for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(gc)) { - obj = FROM_GC(gc); - traverse = Py_TYPE(obj)->tp_traverse; - if (obj == objs || obj == resultlist) - continue; - if (traverse(obj, (visitproc)referrersvisit, objs)) { - if (PyList_Append(resultlist, obj) < 0) - return 0; /* error */ - } - } - return 1; /* no error */ -} - -PyDoc_STRVAR(gc_get_referrers__doc__, -"get_referrers(*objs) -> list\n\ -Return the list of objects that directly refer to any of objs."); - -static PyObject * -gc_get_referrers(PyObject *self, PyObject *args) -{ + obj = FROM_GC(gc); + traverse = Py_TYPE(obj)->tp_traverse; + if (obj == objs || obj == resultlist) + continue; + if (traverse(obj, (visitproc)referrersvisit, objs)) { + if (PyList_Append(resultlist, obj) < 0) + return 0; /* error */ + } + } + return 1; /* no error */ +} + +PyDoc_STRVAR(gc_get_referrers__doc__, +"get_referrers(*objs) -> list\n\ +Return the list of objects that directly refer to any of objs."); + +static PyObject * +gc_get_referrers(PyObject *self, PyObject *args) +{ PyThreadState *tstate = _PyThreadState_GET(); - int i; + int i; if (PySys_Audit("gc.get_referrers", "(O)", args) < 0) { return NULL; } - PyObject *result = PyList_New(0); + PyObject *result = PyList_New(0); if (!result) { return NULL; } - + GCState *gcstate = &tstate->interp->gc; - for (i = 0; i < NUM_GENERATIONS; i++) { + for (i = 0; i < NUM_GENERATIONS; i++) { if (!(gc_referrers_for(args, GEN_HEAD(gcstate, i), result))) { - Py_DECREF(result); - return NULL; - } - } - return result; -} - -/* Append obj to list; return true if error (out of memory), false if OK. */ -static int -referentsvisit(PyObject *obj, PyObject *list) -{ - return PyList_Append(list, obj) < 0; -} - -PyDoc_STRVAR(gc_get_referents__doc__, -"get_referents(*objs) -> list\n\ -Return the list of objects that are directly referred to by objs."); - -static PyObject * -gc_get_referents(PyObject *self, PyObject *args) -{ - Py_ssize_t i; + Py_DECREF(result); + return NULL; + } + } + return result; +} + +/* Append obj to list; return true if error (out of memory), false if OK. */ +static int +referentsvisit(PyObject *obj, PyObject *list) +{ + return PyList_Append(list, obj) < 0; +} + +PyDoc_STRVAR(gc_get_referents__doc__, +"get_referents(*objs) -> list\n\ +Return the list of objects that are directly referred to by objs."); + +static PyObject * +gc_get_referents(PyObject *self, PyObject *args) +{ + Py_ssize_t i; if (PySys_Audit("gc.get_referents", "(O)", args) < 0) { return NULL; } - PyObject *result = PyList_New(0); - - if (result == NULL) - return NULL; - - for (i = 0; i < PyTuple_GET_SIZE(args); i++) { - traverseproc traverse; - PyObject *obj = PyTuple_GET_ITEM(args, i); - + PyObject *result = PyList_New(0); + + if (result == NULL) + return NULL; + + for (i = 0; i < PyTuple_GET_SIZE(args); i++) { + traverseproc traverse; + PyObject *obj = PyTuple_GET_ITEM(args, i); + if (!_PyObject_IS_GC(obj)) - continue; - traverse = Py_TYPE(obj)->tp_traverse; - if (! traverse) - continue; - if (traverse(obj, (visitproc)referentsvisit, result)) { - Py_DECREF(result); - return NULL; - } - } - return result; -} - -/*[clinic input] -gc.get_objects + continue; + traverse = Py_TYPE(obj)->tp_traverse; + if (! traverse) + continue; + if (traverse(obj, (visitproc)referentsvisit, result)) { + Py_DECREF(result); + return NULL; + } + } + return result; +} + +/*[clinic input] +gc.get_objects generation: Py_ssize_t(accept={int, NoneType}, c_default="-1") = None Generation to extract the objects from. - -Return a list of objects tracked by the collector (excluding the list returned). + +Return a list of objects tracked by the collector (excluding the list returned). If generation is not None, return only the objects tracked by the collector that are in that generation. -[clinic start generated code]*/ - -static PyObject * +[clinic start generated code]*/ + +static PyObject * gc_get_objects_impl(PyObject *module, Py_ssize_t generation) /*[clinic end generated code: output=48b35fea4ba6cb0e input=ef7da9df9806754c]*/ -{ +{ PyThreadState *tstate = _PyThreadState_GET(); - int i; - PyObject* result; + int i; + PyObject* result; GCState *gcstate = &tstate->interp->gc; - + if (PySys_Audit("gc.get_objects", "n", generation) < 0) { return NULL; } - result = PyList_New(0); + result = PyList_New(0); if (result == NULL) { - return NULL; + return NULL; } /* If generation is passed, we extract only that generation */ @@ -1787,93 +1787,93 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) } /* If generation is not passed or None, get all objects from all generations */ - for (i = 0; i < NUM_GENERATIONS; i++) { + for (i = 0; i < NUM_GENERATIONS; i++) { if (append_objects(result, GEN_HEAD(gcstate, i))) { goto error; - } - } - return result; + } + } + return result; error: Py_DECREF(result); return NULL; -} - -/*[clinic input] -gc.get_stats - -Return a list of dictionaries containing per-generation statistics. -[clinic start generated code]*/ - -static PyObject * -gc_get_stats_impl(PyObject *module) -/*[clinic end generated code: output=a8ab1d8a5d26f3ab input=1ef4ed9d17b1a470]*/ -{ - int i; - struct gc_generation_stats stats[NUM_GENERATIONS], *st; +} + +/*[clinic input] +gc.get_stats + +Return a list of dictionaries containing per-generation statistics. +[clinic start generated code]*/ + +static PyObject * +gc_get_stats_impl(PyObject *module) +/*[clinic end generated code: output=a8ab1d8a5d26f3ab input=1ef4ed9d17b1a470]*/ +{ + int i; + struct gc_generation_stats stats[NUM_GENERATIONS], *st; PyThreadState *tstate = _PyThreadState_GET(); - - /* To get consistent values despite allocations while constructing - the result list, we use a snapshot of the running stats. */ + + /* To get consistent values despite allocations while constructing + the result list, we use a snapshot of the running stats. */ GCState *gcstate = &tstate->interp->gc; - for (i = 0; i < NUM_GENERATIONS; i++) { + for (i = 0; i < NUM_GENERATIONS; i++) { stats[i] = gcstate->generation_stats[i]; - } - + } + PyObject *result = PyList_New(0); - if (result == NULL) - return NULL; - - for (i = 0; i < NUM_GENERATIONS; i++) { - PyObject *dict; - st = &stats[i]; - dict = Py_BuildValue("{snsnsn}", - "collections", st->collections, - "collected", st->collected, - "uncollectable", st->uncollectable - ); - if (dict == NULL) - goto error; - if (PyList_Append(result, dict)) { - Py_DECREF(dict); - goto error; - } - Py_DECREF(dict); - } - return result; - -error: - Py_XDECREF(result); - return NULL; -} - - -/*[clinic input] -gc.is_tracked - - obj: object - / - -Returns true if the object is tracked by the garbage collector. - -Simple atomic objects will return false. -[clinic start generated code]*/ - -static PyObject * -gc_is_tracked(PyObject *module, PyObject *obj) -/*[clinic end generated code: output=14f0103423b28e31 input=d83057f170ea2723]*/ -{ - PyObject *result; - + if (result == NULL) + return NULL; + + for (i = 0; i < NUM_GENERATIONS; i++) { + PyObject *dict; + st = &stats[i]; + dict = Py_BuildValue("{snsnsn}", + "collections", st->collections, + "collected", st->collected, + "uncollectable", st->uncollectable + ); + if (dict == NULL) + goto error; + if (PyList_Append(result, dict)) { + Py_DECREF(dict); + goto error; + } + Py_DECREF(dict); + } + return result; + +error: + Py_XDECREF(result); + return NULL; +} + + +/*[clinic input] +gc.is_tracked + + obj: object + / + +Returns true if the object is tracked by the garbage collector. + +Simple atomic objects will return false. +[clinic start generated code]*/ + +static PyObject * +gc_is_tracked(PyObject *module, PyObject *obj) +/*[clinic end generated code: output=14f0103423b28e31 input=d83057f170ea2723]*/ +{ + PyObject *result; + if (_PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)) - result = Py_True; - else - result = Py_False; - Py_INCREF(result); - return result; -} - -/*[clinic input] + result = Py_True; + else + result = Py_False; + Py_INCREF(result); + return result; +} + +/*[clinic input] gc.is_finalized obj: object @@ -1893,169 +1893,169 @@ gc_is_finalized(PyObject *module, PyObject *obj) } /*[clinic input] -gc.freeze - -Freeze all current tracked objects and ignore them for future collections. - -This can be used before a POSIX fork() call to make the gc copy-on-write friendly. -Note: collection before a POSIX fork() call may free pages for future allocation -which can cause copy-on-write. -[clinic start generated code]*/ - -static PyObject * -gc_freeze_impl(PyObject *module) -/*[clinic end generated code: output=502159d9cdc4c139 input=b602b16ac5febbe5]*/ -{ +gc.freeze + +Freeze all current tracked objects and ignore them for future collections. + +This can be used before a POSIX fork() call to make the gc copy-on-write friendly. +Note: collection before a POSIX fork() call may free pages for future allocation +which can cause copy-on-write. +[clinic start generated code]*/ + +static PyObject * +gc_freeze_impl(PyObject *module) +/*[clinic end generated code: output=502159d9cdc4c139 input=b602b16ac5febbe5]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; - for (int i = 0; i < NUM_GENERATIONS; ++i) { + for (int i = 0; i < NUM_GENERATIONS; ++i) { gc_list_merge(GEN_HEAD(gcstate, i), &gcstate->permanent_generation.head); gcstate->generations[i].count = 0; - } - Py_RETURN_NONE; -} - -/*[clinic input] -gc.unfreeze - -Unfreeze all objects in the permanent generation. - -Put all objects in the permanent generation back into oldest generation. -[clinic start generated code]*/ - -static PyObject * -gc_unfreeze_impl(PyObject *module) -/*[clinic end generated code: output=1c15f2043b25e169 input=2dd52b170f4cef6c]*/ -{ + } + Py_RETURN_NONE; +} + +/*[clinic input] +gc.unfreeze + +Unfreeze all objects in the permanent generation. + +Put all objects in the permanent generation back into oldest generation. +[clinic start generated code]*/ + +static PyObject * +gc_unfreeze_impl(PyObject *module) +/*[clinic end generated code: output=1c15f2043b25e169 input=2dd52b170f4cef6c]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; gc_list_merge(&gcstate->permanent_generation.head, GEN_HEAD(gcstate, NUM_GENERATIONS-1)); - Py_RETURN_NONE; -} - -/*[clinic input] -gc.get_freeze_count -> Py_ssize_t - -Return the number of objects in the permanent generation. -[clinic start generated code]*/ - -static Py_ssize_t -gc_get_freeze_count_impl(PyObject *module) -/*[clinic end generated code: output=61cbd9f43aa032e1 input=45ffbc65cfe2a6ed]*/ -{ + Py_RETURN_NONE; +} + +/*[clinic input] +gc.get_freeze_count -> Py_ssize_t + +Return the number of objects in the permanent generation. +[clinic start generated code]*/ + +static Py_ssize_t +gc_get_freeze_count_impl(PyObject *module) +/*[clinic end generated code: output=61cbd9f43aa032e1 input=45ffbc65cfe2a6ed]*/ +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; return gc_list_size(&gcstate->permanent_generation.head); -} - - -PyDoc_STRVAR(gc__doc__, -"This module provides access to the garbage collector for reference cycles.\n" -"\n" -"enable() -- Enable automatic garbage collection.\n" -"disable() -- Disable automatic garbage collection.\n" -"isenabled() -- Returns true if automatic collection is enabled.\n" -"collect() -- Do a full collection right now.\n" -"get_count() -- Return the current collection counts.\n" -"get_stats() -- Return list of dictionaries containing per-generation stats.\n" -"set_debug() -- Set debugging flags.\n" -"get_debug() -- Get debugging flags.\n" -"set_threshold() -- Set the collection thresholds.\n" -"get_threshold() -- Return the current the collection thresholds.\n" -"get_objects() -- Return a list of all objects tracked by the collector.\n" -"is_tracked() -- Returns true if a given object is tracked.\n" +} + + +PyDoc_STRVAR(gc__doc__, +"This module provides access to the garbage collector for reference cycles.\n" +"\n" +"enable() -- Enable automatic garbage collection.\n" +"disable() -- Disable automatic garbage collection.\n" +"isenabled() -- Returns true if automatic collection is enabled.\n" +"collect() -- Do a full collection right now.\n" +"get_count() -- Return the current collection counts.\n" +"get_stats() -- Return list of dictionaries containing per-generation stats.\n" +"set_debug() -- Set debugging flags.\n" +"get_debug() -- Get debugging flags.\n" +"set_threshold() -- Set the collection thresholds.\n" +"get_threshold() -- Return the current the collection thresholds.\n" +"get_objects() -- Return a list of all objects tracked by the collector.\n" +"is_tracked() -- Returns true if a given object is tracked.\n" "is_finalized() -- Returns true if a given object has been already finalized.\n" -"get_referrers() -- Return the list of objects that refer to an object.\n" -"get_referents() -- Return the list of objects that an object refers to.\n" -"freeze() -- Freeze all tracked objects and ignore them for future collections.\n" -"unfreeze() -- Unfreeze all objects in the permanent generation.\n" -"get_freeze_count() -- Return the number of objects in the permanent generation.\n"); - -static PyMethodDef GcMethods[] = { - GC_ENABLE_METHODDEF - GC_DISABLE_METHODDEF - GC_ISENABLED_METHODDEF - GC_SET_DEBUG_METHODDEF - GC_GET_DEBUG_METHODDEF - GC_GET_COUNT_METHODDEF +"get_referrers() -- Return the list of objects that refer to an object.\n" +"get_referents() -- Return the list of objects that an object refers to.\n" +"freeze() -- Freeze all tracked objects and ignore them for future collections.\n" +"unfreeze() -- Unfreeze all objects in the permanent generation.\n" +"get_freeze_count() -- Return the number of objects in the permanent generation.\n"); + +static PyMethodDef GcMethods[] = { + GC_ENABLE_METHODDEF + GC_DISABLE_METHODDEF + GC_ISENABLED_METHODDEF + GC_SET_DEBUG_METHODDEF + GC_GET_DEBUG_METHODDEF + GC_GET_COUNT_METHODDEF {"set_threshold", gc_set_threshold, METH_VARARGS, gc_set_thresh__doc__}, - GC_GET_THRESHOLD_METHODDEF - GC_COLLECT_METHODDEF - GC_GET_OBJECTS_METHODDEF - GC_GET_STATS_METHODDEF - GC_IS_TRACKED_METHODDEF + GC_GET_THRESHOLD_METHODDEF + GC_COLLECT_METHODDEF + GC_GET_OBJECTS_METHODDEF + GC_GET_STATS_METHODDEF + GC_IS_TRACKED_METHODDEF GC_IS_FINALIZED_METHODDEF - {"get_referrers", gc_get_referrers, METH_VARARGS, - gc_get_referrers__doc__}, - {"get_referents", gc_get_referents, METH_VARARGS, - gc_get_referents__doc__}, - GC_FREEZE_METHODDEF - GC_UNFREEZE_METHODDEF - GC_GET_FREEZE_COUNT_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - -static struct PyModuleDef gcmodule = { - PyModuleDef_HEAD_INIT, - "gc", /* m_name */ - gc__doc__, /* m_doc */ - -1, /* m_size */ - GcMethods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; - -PyMODINIT_FUNC -PyInit_gc(void) -{ + {"get_referrers", gc_get_referrers, METH_VARARGS, + gc_get_referrers__doc__}, + {"get_referents", gc_get_referents, METH_VARARGS, + gc_get_referents__doc__}, + GC_FREEZE_METHODDEF + GC_UNFREEZE_METHODDEF + GC_GET_FREEZE_COUNT_METHODDEF + {NULL, NULL} /* Sentinel */ +}; + +static struct PyModuleDef gcmodule = { + PyModuleDef_HEAD_INIT, + "gc", /* m_name */ + gc__doc__, /* m_doc */ + -1, /* m_size */ + GcMethods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; + +PyMODINIT_FUNC +PyInit_gc(void) +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; - + PyObject *m = PyModule_Create(&gcmodule); - + if (m == NULL) { - return NULL; + return NULL; } - + if (gcstate->garbage == NULL) { gcstate->garbage = PyList_New(0); if (gcstate->garbage == NULL) { - return NULL; + return NULL; } - } + } Py_INCREF(gcstate->garbage); if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) { - return NULL; + return NULL; } - + if (gcstate->callbacks == NULL) { gcstate->callbacks = PyList_New(0); if (gcstate->callbacks == NULL) { - return NULL; + return NULL; } - } + } Py_INCREF(gcstate->callbacks); if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) { - return NULL; + return NULL; } - + #define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) { return NULL; } - ADD_INT(DEBUG_STATS); - ADD_INT(DEBUG_COLLECTABLE); - ADD_INT(DEBUG_UNCOLLECTABLE); - ADD_INT(DEBUG_SAVEALL); - ADD_INT(DEBUG_LEAK); -#undef ADD_INT - return m; -} - -/* API to invoke gc.collect() from C */ -Py_ssize_t -PyGC_Collect(void) -{ + ADD_INT(DEBUG_STATS); + ADD_INT(DEBUG_COLLECTABLE); + ADD_INT(DEBUG_UNCOLLECTABLE); + ADD_INT(DEBUG_SAVEALL); + ADD_INT(DEBUG_LEAK); +#undef ADD_INT + return m; +} + +/* API to invoke gc.collect() from C */ +Py_ssize_t +PyGC_Collect(void) +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; @@ -2063,92 +2063,92 @@ PyGC_Collect(void) return 0; } - Py_ssize_t n; + Py_ssize_t n; if (gcstate->collecting) { /* already collecting, don't do anything */ n = 0; } - else { - PyObject *exc, *value, *tb; + else { + PyObject *exc, *value, *tb; gcstate->collecting = 1; _PyErr_Fetch(tstate, &exc, &value, &tb); n = collect_with_callback(tstate, NUM_GENERATIONS - 1); _PyErr_Restore(tstate, exc, value, tb); gcstate->collecting = 0; - } - - return n; -} - -Py_ssize_t -_PyGC_CollectIfEnabled(void) -{ - return PyGC_Collect(); -} - -Py_ssize_t -_PyGC_CollectNoFail(void) -{ + } + + return n; +} + +Py_ssize_t +_PyGC_CollectIfEnabled(void) +{ + return PyGC_Collect(); +} + +Py_ssize_t +_PyGC_CollectNoFail(void) +{ PyThreadState *tstate = _PyThreadState_GET(); assert(!_PyErr_Occurred(tstate)); GCState *gcstate = &tstate->interp->gc; - Py_ssize_t n; - - /* Ideally, this function is only called on interpreter shutdown, - and therefore not recursively. Unfortunately, when there are daemon - threads, a daemon thread can start a cyclic garbage collection - during interpreter shutdown (and then never finish it). - See http://bugs.python.org/issue8713#msg195178 for an example. - */ + Py_ssize_t n; + + /* Ideally, this function is only called on interpreter shutdown, + and therefore not recursively. Unfortunately, when there are daemon + threads, a daemon thread can start a cyclic garbage collection + during interpreter shutdown (and then never finish it). + See http://bugs.python.org/issue8713#msg195178 for an example. + */ if (gcstate->collecting) { - n = 0; + n = 0; } - else { + else { gcstate->collecting = 1; n = collect(tstate, NUM_GENERATIONS - 1, NULL, NULL, 1); gcstate->collecting = 0; - } - return n; -} - -void + } + return n; +} + +void _PyGC_DumpShutdownStats(PyThreadState *tstate) -{ +{ GCState *gcstate = &tstate->interp->gc; if (!(gcstate->debug & DEBUG_SAVEALL) && gcstate->garbage != NULL && PyList_GET_SIZE(gcstate->garbage) > 0) { - const char *message; + const char *message; if (gcstate->debug & DEBUG_UNCOLLECTABLE) - message = "gc: %zd uncollectable objects at " \ - "shutdown"; - else - message = "gc: %zd uncollectable objects at " \ - "shutdown; use gc.set_debug(gc.DEBUG_UNCOLLECTABLE) to list them"; - /* PyErr_WarnFormat does too many things and we are at shutdown, - the warnings module's dependencies (e.g. linecache) may be gone - already. */ - if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0, - "gc", NULL, message, + message = "gc: %zd uncollectable objects at " \ + "shutdown"; + else + message = "gc: %zd uncollectable objects at " \ + "shutdown; use gc.set_debug(gc.DEBUG_UNCOLLECTABLE) to list them"; + /* PyErr_WarnFormat does too many things and we are at shutdown, + the warnings module's dependencies (e.g. linecache) may be gone + already. */ + if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0, + "gc", NULL, message, PyList_GET_SIZE(gcstate->garbage))) - PyErr_WriteUnraisable(NULL); + PyErr_WriteUnraisable(NULL); if (gcstate->debug & DEBUG_UNCOLLECTABLE) { - PyObject *repr = NULL, *bytes = NULL; + PyObject *repr = NULL, *bytes = NULL; repr = PyObject_Repr(gcstate->garbage); - if (!repr || !(bytes = PyUnicode_EncodeFSDefault(repr))) + if (!repr || !(bytes = PyUnicode_EncodeFSDefault(repr))) PyErr_WriteUnraisable(gcstate->garbage); - else { - PySys_WriteStderr( - " %s\n", - PyBytes_AS_STRING(bytes) - ); - } - Py_XDECREF(repr); - Py_XDECREF(bytes); - } - } -} - + else { + PySys_WriteStderr( + " %s\n", + PyBytes_AS_STRING(bytes) + ); + } + Py_XDECREF(repr); + Py_XDECREF(bytes); + } + } +} + static void gc_fini_untrack(PyGC_Head *list) @@ -2161,9 +2161,9 @@ gc_fini_untrack(PyGC_Head *list) } -void +void _PyGC_Fini(PyThreadState *tstate) -{ +{ GCState *gcstate = &tstate->interp->gc; Py_CLEAR(gcstate->garbage); Py_CLEAR(gcstate->callbacks); @@ -2179,15 +2179,15 @@ _PyGC_Fini(PyThreadState *tstate) gc_fini_untrack(gen); } } -} - -/* for debugging */ -void -_PyGC_Dump(PyGC_Head *g) -{ - _PyObject_Dump(FROM_GC(g)); -} - +} + +/* for debugging */ +void +_PyGC_Dump(PyGC_Head *g) +{ + _PyObject_Dump(FROM_GC(g)); +} + #ifdef Py_DEBUG static int @@ -2203,19 +2203,19 @@ visit_validate(PyObject *op, void *parent_raw) #endif -/* extension modules might be compiled with GC support so these - functions must always be available */ - -void +/* extension modules might be compiled with GC support so these + functions must always be available */ + +void PyObject_GC_Track(void *op_raw) -{ +{ PyObject *op = _PyObject_CAST(op_raw); if (_PyObject_GC_IS_TRACKED(op)) { _PyObject_ASSERT_FAILED_MSG(op, "object already tracked " "by the garbage collector"); } - _PyObject_GC_TRACK(op); + _PyObject_GC_TRACK(op); #ifdef Py_DEBUG /* Check that the object is valid: validate objects traversed @@ -2223,29 +2223,29 @@ PyObject_GC_Track(void *op_raw) traverseproc traverse = Py_TYPE(op)->tp_traverse; (void)traverse(op, visit_validate, op); #endif -} - -void +} + +void PyObject_GC_UnTrack(void *op_raw) -{ +{ PyObject *op = _PyObject_CAST(op_raw); - /* Obscure: the Py_TRASHCAN mechanism requires that we be able to - * call PyObject_GC_UnTrack twice on an object. - */ + /* Obscure: the Py_TRASHCAN mechanism requires that we be able to + * call PyObject_GC_UnTrack twice on an object. + */ if (_PyObject_GC_IS_TRACKED(op)) { - _PyObject_GC_UNTRACK(op); + _PyObject_GC_UNTRACK(op); } -} - +} + int PyObject_IS_GC(PyObject *obj) { return _PyObject_IS_GC(obj); } -static PyObject * -_PyObject_GC_Alloc(int use_calloc, size_t basicsize) -{ +static PyObject * +_PyObject_GC_Alloc(int use_calloc, size_t basicsize) +{ PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { @@ -2253,12 +2253,12 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize) } size_t size = sizeof(PyGC_Head) + basicsize; - PyGC_Head *g; + PyGC_Head *g; if (use_calloc) { - g = (PyGC_Head *)PyObject_Calloc(1, size); + g = (PyGC_Head *)PyObject_Calloc(1, size); } else { - g = (PyGC_Head *)PyObject_Malloc(size); + g = (PyGC_Head *)PyObject_Malloc(size); } if (g == NULL) { return _PyErr_NoMemory(tstate); @@ -2277,81 +2277,81 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize) gcstate->collecting = 1; collect_generations(tstate); gcstate->collecting = 0; - } + } PyObject *op = FROM_GC(g); - return op; -} - -PyObject * -_PyObject_GC_Malloc(size_t basicsize) -{ - return _PyObject_GC_Alloc(0, basicsize); -} - -PyObject * -_PyObject_GC_Calloc(size_t basicsize) -{ - return _PyObject_GC_Alloc(1, basicsize); -} - -PyObject * -_PyObject_GC_New(PyTypeObject *tp) -{ - PyObject *op = _PyObject_GC_Malloc(_PyObject_SIZE(tp)); - if (op != NULL) - op = PyObject_INIT(op, tp); - return op; -} - -PyVarObject * -_PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) -{ - size_t size; - PyVarObject *op; - - if (nitems < 0) { - PyErr_BadInternalCall(); - return NULL; - } - size = _PyObject_VAR_SIZE(tp, nitems); - op = (PyVarObject *) _PyObject_GC_Malloc(size); - if (op != NULL) - op = PyObject_INIT_VAR(op, tp, nitems); - return op; -} - -PyVarObject * -_PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) -{ - const size_t basicsize = _PyObject_VAR_SIZE(Py_TYPE(op), nitems); + return op; +} + +PyObject * +_PyObject_GC_Malloc(size_t basicsize) +{ + return _PyObject_GC_Alloc(0, basicsize); +} + +PyObject * +_PyObject_GC_Calloc(size_t basicsize) +{ + return _PyObject_GC_Alloc(1, basicsize); +} + +PyObject * +_PyObject_GC_New(PyTypeObject *tp) +{ + PyObject *op = _PyObject_GC_Malloc(_PyObject_SIZE(tp)); + if (op != NULL) + op = PyObject_INIT(op, tp); + return op; +} + +PyVarObject * +_PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) +{ + size_t size; + PyVarObject *op; + + if (nitems < 0) { + PyErr_BadInternalCall(); + return NULL; + } + size = _PyObject_VAR_SIZE(tp, nitems); + op = (PyVarObject *) _PyObject_GC_Malloc(size); + if (op != NULL) + op = PyObject_INIT_VAR(op, tp, nitems); + return op; +} + +PyVarObject * +_PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) +{ + const size_t basicsize = _PyObject_VAR_SIZE(Py_TYPE(op), nitems); _PyObject_ASSERT((PyObject *)op, !_PyObject_GC_IS_TRACKED(op)); if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { return (PyVarObject *)PyErr_NoMemory(); } - PyGC_Head *g = AS_GC(op); - g = (PyGC_Head *)PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize); - if (g == NULL) - return (PyVarObject *)PyErr_NoMemory(); - op = (PyVarObject *) FROM_GC(g); + PyGC_Head *g = AS_GC(op); + g = (PyGC_Head *)PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize); + if (g == NULL) + return (PyVarObject *)PyErr_NoMemory(); + op = (PyVarObject *) FROM_GC(g); Py_SET_SIZE(op, nitems); - return op; -} - -void -PyObject_GC_Del(void *op) -{ - PyGC_Head *g = AS_GC(op); + return op; +} + +void +PyObject_GC_Del(void *op) +{ + PyGC_Head *g = AS_GC(op); if (_PyObject_GC_IS_TRACKED(op)) { - gc_list_remove(g); - } + gc_list_remove(g); + } PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; if (gcstate->generations[0].count > 0) { gcstate->generations[0].count--; } - PyObject_FREE(g); -} + PyObject_FREE(g); +} int PyObject_GC_IsTracked(PyObject* obj) diff --git a/contrib/tools/python3/src/Modules/getaddrinfo.c b/contrib/tools/python3/src/Modules/getaddrinfo.c index 5aaa6e7c814..d8b27f75574 100644 --- a/contrib/tools/python3/src/Modules/getaddrinfo.c +++ b/contrib/tools/python3/src/Modules/getaddrinfo.c @@ -1,638 +1,638 @@ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. - * - * Issues to be discussed: - * - Thread safe-ness must be checked. - * - Return values. There are nonstandard return values defined and used - * in the source code. This is because RFC2133 is silent about which error - * code must be returned for which situation. - * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag. - */ - -#if 0 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "addrinfo.h" -#endif - -#if defined(__KAME__) && defined(ENABLE_IPV6) -# define FAITH -#endif - -#define SUCCESS 0 -#define GAI_ANY 0 -#define YES 1 -#define NO 0 - -#ifdef FAITH -static int translate = NO; -static struct in6_addr faith_prefix = IN6ADDR_GAI_ANY_INIT; -#endif - -static const char in_addrany[] = { 0, 0, 0, 0 }; -static const char in6_addrany[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -static const char in_loopback[] = { 127, 0, 0, 1 }; -static const char in6_loopback[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 -}; - -struct sockinet { - u_char si_len; - u_char si_family; - u_short si_port; -}; - -static struct gai_afd { - int a_af; - int a_addrlen; - int a_socklen; - int a_off; - const char *a_addrany; - const char *a_loopback; -} gai_afdl [] = { -#ifdef ENABLE_IPV6 -#define N_INET6 0 - {PF_INET6, sizeof(struct in6_addr), - sizeof(struct sockaddr_in6), - offsetof(struct sockaddr_in6, sin6_addr), - in6_addrany, in6_loopback}, -#define N_INET 1 -#else -#define N_INET 0 -#endif - {PF_INET, sizeof(struct in_addr), - sizeof(struct sockaddr_in), - offsetof(struct sockaddr_in, sin_addr), - in_addrany, in_loopback}, - {0, 0, 0, 0, NULL, NULL}, -}; - -#ifdef ENABLE_IPV6 -#define PTON_MAX 16 -#else -#define PTON_MAX 4 -#endif - -#ifndef IN_MULTICAST -#define IN_MULTICAST(i) (((i) & 0xf0000000U) == 0xe0000000U) -#endif - -#ifndef IN_EXPERIMENTAL -#define IN_EXPERIMENTAL(i) (((i) & 0xe0000000U) == 0xe0000000U) -#endif - -#ifndef IN_LOOPBACKNET -#define IN_LOOPBACKNET 127 -#endif - -static int get_name(const char *, struct gai_afd *, - struct addrinfo **, char *, struct addrinfo *, - int); -static int get_addr(const char *, int, struct addrinfo **, - struct addrinfo *, int); -static int str_isnumber(const char *); - -static const char * const ai_errlist[] = { - "success.", - "address family for hostname not supported.", /* EAI_ADDRFAMILY */ - "temporary failure in name resolution.", /* EAI_AGAIN */ - "invalid value for ai_flags.", /* EAI_BADFLAGS */ - "non-recoverable failure in name resolution.", /* EAI_FAIL */ - "ai_family not supported.", /* EAI_FAMILY */ - "memory allocation failure.", /* EAI_MEMORY */ - "no address associated with hostname.", /* EAI_NODATA */ - "hostname nor servname provided, or not known.",/* EAI_NONAME */ - "servname not supported for ai_socktype.", /* EAI_SERVICE */ - "ai_socktype not supported.", /* EAI_SOCKTYPE */ - "system error returned in errno.", /* EAI_SYSTEM */ - "invalid value for hints.", /* EAI_BADHINTS */ - "resolved protocol is unknown.", /* EAI_PROTOCOL */ - "unknown error.", /* EAI_MAX */ -}; - -#define GET_CANONNAME(ai, str) \ -if (pai->ai_flags & AI_CANONNAME) {\ - if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\ - strcpy((ai)->ai_canonname, (str));\ - } else {\ - error = EAI_MEMORY;\ - goto free;\ - }\ -} - -#ifdef HAVE_SOCKADDR_SA_LEN -#define GET_AI(ai, gai_afd, addr, port) {\ - char *p;\ - if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ - ((gai_afd)->a_socklen)))\ - == NULL) goto free;\ - memcpy(ai, pai, sizeof(struct addrinfo));\ - (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ - memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ - (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\ - (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ - ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ - p = (char *)((ai)->ai_addr);\ - memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ -} -#else -#define GET_AI(ai, gai_afd, addr, port) {\ - char *p;\ - if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ - ((gai_afd)->a_socklen)))\ - == NULL) goto free;\ - memcpy(ai, pai, sizeof(struct addrinfo));\ - (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ - memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ - (ai)->ai_addrlen = (gai_afd)->a_socklen;\ - (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ - ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ - p = (char *)((ai)->ai_addr);\ - memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ -} -#endif - -#define ERR(err) { error = (err); goto bad; } - -const char * -gai_strerror(int ecode) -{ - if (ecode < 0 || ecode > EAI_MAX) - ecode = EAI_MAX; - return ai_errlist[ecode]; -} - -void -freeaddrinfo(struct addrinfo *ai) -{ - struct addrinfo *next; - - do { - next = ai->ai_next; - if (ai->ai_canonname) - free(ai->ai_canonname); - /* no need to free(ai->ai_addr) */ - free(ai); - } while ((ai = next) != NULL); -} - -static int -str_isnumber(const char *p) -{ - unsigned char *q = (unsigned char *)p; - while (*q) { - if (! isdigit(*q)) - return NO; - q++; - } - return YES; -} - -int -getaddrinfo(const char*hostname, const char*servname, - const struct addrinfo *hints, struct addrinfo **res) -{ - struct addrinfo sentinel; - struct addrinfo *top = NULL; - struct addrinfo *cur; - int i, error = 0; - char pton[PTON_MAX]; - struct addrinfo ai; - struct addrinfo *pai; - u_short port; - -#ifdef FAITH - static int firsttime = 1; - - if (firsttime) { - /* translator hack */ - { - const char *q = getenv("GAI"); - if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) - translate = YES; - } - firsttime = 0; - } -#endif - - /* initialize file static vars */ - sentinel.ai_next = NULL; - cur = &sentinel; - pai = &ai; - pai->ai_flags = 0; - pai->ai_family = PF_UNSPEC; - pai->ai_socktype = GAI_ANY; - pai->ai_protocol = GAI_ANY; - pai->ai_addrlen = 0; - pai->ai_canonname = NULL; - pai->ai_addr = NULL; - pai->ai_next = NULL; - port = GAI_ANY; - - if (hostname == NULL && servname == NULL) - return EAI_NONAME; - if (hints) { - /* error check for hints */ - if (hints->ai_addrlen || hints->ai_canonname || - hints->ai_addr || hints->ai_next) - ERR(EAI_BADHINTS); /* xxx */ - if (hints->ai_flags & ~AI_MASK) - ERR(EAI_BADFLAGS); - switch (hints->ai_family) { - case PF_UNSPEC: - case PF_INET: -#ifdef ENABLE_IPV6 - case PF_INET6: -#endif - break; - default: - ERR(EAI_FAMILY); - } - memcpy(pai, hints, sizeof(*pai)); - switch (pai->ai_socktype) { - case GAI_ANY: - switch (pai->ai_protocol) { - case GAI_ANY: - break; - case IPPROTO_UDP: - pai->ai_socktype = SOCK_DGRAM; - break; - case IPPROTO_TCP: - pai->ai_socktype = SOCK_STREAM; - break; - default: - pai->ai_socktype = SOCK_RAW; - break; - } - break; - case SOCK_RAW: - break; - case SOCK_DGRAM: - if (pai->ai_protocol != IPPROTO_UDP && - pai->ai_protocol != GAI_ANY) - ERR(EAI_BADHINTS); /*xxx*/ - pai->ai_protocol = IPPROTO_UDP; - break; - case SOCK_STREAM: - if (pai->ai_protocol != IPPROTO_TCP && - pai->ai_protocol != GAI_ANY) - ERR(EAI_BADHINTS); /*xxx*/ - pai->ai_protocol = IPPROTO_TCP; - break; - default: - ERR(EAI_SOCKTYPE); - /* unreachable */ - } - } - - /* - * service port - */ - if (servname) { - if (str_isnumber(servname)) { - if (pai->ai_socktype == GAI_ANY) { - /* caller accept *GAI_ANY* socktype */ - pai->ai_socktype = SOCK_DGRAM; - pai->ai_protocol = IPPROTO_UDP; - } - port = htons((u_short)atoi(servname)); - } else { - struct servent *sp; - const char *proto; - - proto = NULL; - switch (pai->ai_socktype) { - case GAI_ANY: - proto = NULL; - break; - case SOCK_DGRAM: - proto = "udp"; - break; - case SOCK_STREAM: - proto = "tcp"; - break; - default: - fprintf(stderr, "panic!\n"); - break; - } - if ((sp = getservbyname(servname, proto)) == NULL) - ERR(EAI_SERVICE); - port = sp->s_port; - if (pai->ai_socktype == GAI_ANY) { - if (strcmp(sp->s_proto, "udp") == 0) { - pai->ai_socktype = SOCK_DGRAM; - pai->ai_protocol = IPPROTO_UDP; - } else if (strcmp(sp->s_proto, "tcp") == 0) { - pai->ai_socktype = SOCK_STREAM; - pai->ai_protocol = IPPROTO_TCP; - } else - ERR(EAI_PROTOCOL); /*xxx*/ - } - } - } - - /* - * hostname == NULL. - * passive socket -> anyaddr (0.0.0.0 or ::) - * non-passive socket -> localhost (127.0.0.1 or ::1) - */ - if (hostname == NULL) { - struct gai_afd *gai_afd; - - for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) { - if (!(pai->ai_family == PF_UNSPEC - || pai->ai_family == gai_afd->a_af)) { - continue; - } - - if (pai->ai_flags & AI_PASSIVE) { - GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port); - /* xxx meaningless? - * GET_CANONNAME(cur->ai_next, "anyaddr"); - */ - } else { - GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback, - port); - /* xxx meaningless? - * GET_CANONNAME(cur->ai_next, "localhost"); - */ - } - cur = cur->ai_next; - } - top = sentinel.ai_next; - if (top) - goto good; - else - ERR(EAI_FAMILY); - } - - /* hostname as numeric name */ - for (i = 0; gai_afdl[i].a_af; i++) { - if (inet_pton(gai_afdl[i].a_af, hostname, pton)) { - u_long v4a; -#ifdef ENABLE_IPV6 - u_char pfx; -#endif - - switch (gai_afdl[i].a_af) { - case AF_INET: - v4a = ((struct in_addr *)pton)->s_addr; - v4a = ntohl(v4a); - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - pai->ai_flags &= ~AI_CANONNAME; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0 || v4a == IN_LOOPBACKNET) - pai->ai_flags &= ~AI_CANONNAME; - break; -#ifdef ENABLE_IPV6 - case AF_INET6: - pfx = ((struct in6_addr *)pton)->s6_addr[0]; - if (pfx == 0 || pfx == 0xfe || pfx == 0xff) - pai->ai_flags &= ~AI_CANONNAME; - break; -#endif - } - - if (pai->ai_family == gai_afdl[i].a_af || - pai->ai_family == PF_UNSPEC) { - if (! (pai->ai_flags & AI_CANONNAME)) { - GET_AI(top, &gai_afdl[i], pton, port); - goto good; - } - /* - * if AI_CANONNAME and if reverse lookup - * fail, return ai anyway to pacify - * calling application. - * - * XXX getaddrinfo() is a name->address - * translation function, and it looks strange - * that we do addr->name translation here. - */ - get_name(pton, &gai_afdl[i], &top, pton, pai, port); - goto good; - } else - ERR(EAI_FAMILY); /*xxx*/ - } - } - - if (pai->ai_flags & AI_NUMERICHOST) - ERR(EAI_NONAME); - - /* hostname as alphabetical name */ - error = get_addr(hostname, pai->ai_family, &top, pai, port); - if (error == 0) { - if (top) { - good: - *res = top; - return SUCCESS; - } else - error = EAI_FAIL; - } - free: - if (top) - freeaddrinfo(top); - bad: - *res = NULL; - return error; -} - -static int -get_name(addr, gai_afd, res, numaddr, pai, port0) - const char *addr; - struct gai_afd *gai_afd; - struct addrinfo **res; - char *numaddr; - struct addrinfo *pai; - int port0; -{ - u_short port = port0 & 0xffff; - struct hostent *hp; - struct addrinfo *cur; - int error = 0; -#ifdef ENABLE_IPV6 - int h_error; -#endif - -#ifdef ENABLE_IPV6 - hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error); -#else - hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET); -#endif - if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { - GET_AI(cur, gai_afd, hp->h_addr_list[0], port); - GET_CANONNAME(cur, hp->h_name); - } else - GET_AI(cur, gai_afd, numaddr, port); - -#ifdef ENABLE_IPV6 - if (hp) - freehostent(hp); -#endif - *res = cur; - return SUCCESS; - free: - if (cur) - freeaddrinfo(cur); -#ifdef ENABLE_IPV6 - if (hp) - freehostent(hp); -#endif - /* bad: */ - *res = NULL; - return error; -} - -static int -get_addr(hostname, af, res, pai, port0) - const char *hostname; - int af; - struct addrinfo **res; - struct addrinfo *pai; - int port0; -{ - u_short port = port0 & 0xffff; - struct addrinfo sentinel; - struct hostent *hp; - struct addrinfo *top, *cur; - struct gai_afd *gai_afd; - int i, error = 0, h_error; - char *ap; - - top = NULL; - sentinel.ai_next = NULL; - cur = &sentinel; -#ifdef ENABLE_IPV6 - if (af == AF_UNSPEC) { - hp = getipnodebyname(hostname, AF_INET6, - AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); - } else - hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); -#else - hp = gethostbyname(hostname); - h_error = h_errno; -#endif - if (hp == NULL) { - switch (h_error) { - case HOST_NOT_FOUND: - case NO_DATA: - error = EAI_NODATA; - break; - case TRY_AGAIN: - error = EAI_AGAIN; - break; - case NO_RECOVERY: - default: - error = EAI_FAIL; - break; - } - goto free; - } - - if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || - (hp->h_addr_list[0] == NULL)) { - error = EAI_FAIL; - goto free; - } - - for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { - switch (af) { -#ifdef ENABLE_IPV6 - case AF_INET6: - gai_afd = &gai_afdl[N_INET6]; - break; -#endif -#ifndef ENABLE_IPV6 - default: /* AF_UNSPEC */ -#endif - case AF_INET: - gai_afd = &gai_afdl[N_INET]; - break; -#ifdef ENABLE_IPV6 - default: /* AF_UNSPEC */ - if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { - ap += sizeof(struct in6_addr) - - sizeof(struct in_addr); - gai_afd = &gai_afdl[N_INET]; - } else - gai_afd = &gai_afdl[N_INET6]; - break; -#endif - } -#ifdef FAITH - if (translate && gai_afd->a_af == AF_INET) { - struct in6_addr *in6; - - GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port); - in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; - memcpy(&in6->s6_addr32[0], &faith_prefix, - sizeof(struct in6_addr) - sizeof(struct in_addr)); - memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr)); - } else -#endif /* FAITH */ - GET_AI(cur->ai_next, gai_afd, ap, port); - if (cur == &sentinel) { - top = cur->ai_next; - GET_CANONNAME(top, hp->h_name); - } - cur = cur->ai_next; - } -#ifdef ENABLE_IPV6 - freehostent(hp); -#endif - *res = top; - return SUCCESS; - free: - if (top) - freeaddrinfo(top); -#ifdef ENABLE_IPV6 - if (hp) - freehostent(hp); -#endif -/* bad: */ - *res = NULL; - return error; -} +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. + * + * Issues to be discussed: + * - Thread safe-ness must be checked. + * - Return values. There are nonstandard return values defined and used + * in the source code. This is because RFC2133 is silent about which error + * code must be returned for which situation. + * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag. + */ + +#if 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "addrinfo.h" +#endif + +#if defined(__KAME__) && defined(ENABLE_IPV6) +# define FAITH +#endif + +#define SUCCESS 0 +#define GAI_ANY 0 +#define YES 1 +#define NO 0 + +#ifdef FAITH +static int translate = NO; +static struct in6_addr faith_prefix = IN6ADDR_GAI_ANY_INIT; +#endif + +static const char in_addrany[] = { 0, 0, 0, 0 }; +static const char in6_addrany[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const char in_loopback[] = { 127, 0, 0, 1 }; +static const char in6_loopback[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 +}; + +struct sockinet { + u_char si_len; + u_char si_family; + u_short si_port; +}; + +static struct gai_afd { + int a_af; + int a_addrlen; + int a_socklen; + int a_off; + const char *a_addrany; + const char *a_loopback; +} gai_afdl [] = { +#ifdef ENABLE_IPV6 +#define N_INET6 0 + {PF_INET6, sizeof(struct in6_addr), + sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr), + in6_addrany, in6_loopback}, +#define N_INET 1 +#else +#define N_INET 0 +#endif + {PF_INET, sizeof(struct in_addr), + sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr), + in_addrany, in_loopback}, + {0, 0, 0, 0, NULL, NULL}, +}; + +#ifdef ENABLE_IPV6 +#define PTON_MAX 16 +#else +#define PTON_MAX 4 +#endif + +#ifndef IN_MULTICAST +#define IN_MULTICAST(i) (((i) & 0xf0000000U) == 0xe0000000U) +#endif + +#ifndef IN_EXPERIMENTAL +#define IN_EXPERIMENTAL(i) (((i) & 0xe0000000U) == 0xe0000000U) +#endif + +#ifndef IN_LOOPBACKNET +#define IN_LOOPBACKNET 127 +#endif + +static int get_name(const char *, struct gai_afd *, + struct addrinfo **, char *, struct addrinfo *, + int); +static int get_addr(const char *, int, struct addrinfo **, + struct addrinfo *, int); +static int str_isnumber(const char *); + +static const char * const ai_errlist[] = { + "success.", + "address family for hostname not supported.", /* EAI_ADDRFAMILY */ + "temporary failure in name resolution.", /* EAI_AGAIN */ + "invalid value for ai_flags.", /* EAI_BADFLAGS */ + "non-recoverable failure in name resolution.", /* EAI_FAIL */ + "ai_family not supported.", /* EAI_FAMILY */ + "memory allocation failure.", /* EAI_MEMORY */ + "no address associated with hostname.", /* EAI_NODATA */ + "hostname nor servname provided, or not known.",/* EAI_NONAME */ + "servname not supported for ai_socktype.", /* EAI_SERVICE */ + "ai_socktype not supported.", /* EAI_SOCKTYPE */ + "system error returned in errno.", /* EAI_SYSTEM */ + "invalid value for hints.", /* EAI_BADHINTS */ + "resolved protocol is unknown.", /* EAI_PROTOCOL */ + "unknown error.", /* EAI_MAX */ +}; + +#define GET_CANONNAME(ai, str) \ +if (pai->ai_flags & AI_CANONNAME) {\ + if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\ + strcpy((ai)->ai_canonname, (str));\ + } else {\ + error = EAI_MEMORY;\ + goto free;\ + }\ +} + +#ifdef HAVE_SOCKADDR_SA_LEN +#define GET_AI(ai, gai_afd, addr, port) {\ + char *p;\ + if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ + ((gai_afd)->a_socklen)))\ + == NULL) goto free;\ + memcpy(ai, pai, sizeof(struct addrinfo));\ + (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ + memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ + (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\ + (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ + ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ + p = (char *)((ai)->ai_addr);\ + memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ +} +#else +#define GET_AI(ai, gai_afd, addr, port) {\ + char *p;\ + if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ + ((gai_afd)->a_socklen)))\ + == NULL) goto free;\ + memcpy(ai, pai, sizeof(struct addrinfo));\ + (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ + memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ + (ai)->ai_addrlen = (gai_afd)->a_socklen;\ + (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ + ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ + p = (char *)((ai)->ai_addr);\ + memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ +} +#endif + +#define ERR(err) { error = (err); goto bad; } + +const char * +gai_strerror(int ecode) +{ + if (ecode < 0 || ecode > EAI_MAX) + ecode = EAI_MAX; + return ai_errlist[ecode]; +} + +void +freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + do { + next = ai->ai_next; + if (ai->ai_canonname) + free(ai->ai_canonname); + /* no need to free(ai->ai_addr) */ + free(ai); + } while ((ai = next) != NULL); +} + +static int +str_isnumber(const char *p) +{ + unsigned char *q = (unsigned char *)p; + while (*q) { + if (! isdigit(*q)) + return NO; + q++; + } + return YES; +} + +int +getaddrinfo(const char*hostname, const char*servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct addrinfo sentinel; + struct addrinfo *top = NULL; + struct addrinfo *cur; + int i, error = 0; + char pton[PTON_MAX]; + struct addrinfo ai; + struct addrinfo *pai; + u_short port; + +#ifdef FAITH + static int firsttime = 1; + + if (firsttime) { + /* translator hack */ + { + const char *q = getenv("GAI"); + if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) + translate = YES; + } + firsttime = 0; + } +#endif + + /* initialize file static vars */ + sentinel.ai_next = NULL; + cur = &sentinel; + pai = &ai; + pai->ai_flags = 0; + pai->ai_family = PF_UNSPEC; + pai->ai_socktype = GAI_ANY; + pai->ai_protocol = GAI_ANY; + pai->ai_addrlen = 0; + pai->ai_canonname = NULL; + pai->ai_addr = NULL; + pai->ai_next = NULL; + port = GAI_ANY; + + if (hostname == NULL && servname == NULL) + return EAI_NONAME; + if (hints) { + /* error check for hints */ + if (hints->ai_addrlen || hints->ai_canonname || + hints->ai_addr || hints->ai_next) + ERR(EAI_BADHINTS); /* xxx */ + if (hints->ai_flags & ~AI_MASK) + ERR(EAI_BADFLAGS); + switch (hints->ai_family) { + case PF_UNSPEC: + case PF_INET: +#ifdef ENABLE_IPV6 + case PF_INET6: +#endif + break; + default: + ERR(EAI_FAMILY); + } + memcpy(pai, hints, sizeof(*pai)); + switch (pai->ai_socktype) { + case GAI_ANY: + switch (pai->ai_protocol) { + case GAI_ANY: + break; + case IPPROTO_UDP: + pai->ai_socktype = SOCK_DGRAM; + break; + case IPPROTO_TCP: + pai->ai_socktype = SOCK_STREAM; + break; + default: + pai->ai_socktype = SOCK_RAW; + break; + } + break; + case SOCK_RAW: + break; + case SOCK_DGRAM: + if (pai->ai_protocol != IPPROTO_UDP && + pai->ai_protocol != GAI_ANY) + ERR(EAI_BADHINTS); /*xxx*/ + pai->ai_protocol = IPPROTO_UDP; + break; + case SOCK_STREAM: + if (pai->ai_protocol != IPPROTO_TCP && + pai->ai_protocol != GAI_ANY) + ERR(EAI_BADHINTS); /*xxx*/ + pai->ai_protocol = IPPROTO_TCP; + break; + default: + ERR(EAI_SOCKTYPE); + /* unreachable */ + } + } + + /* + * service port + */ + if (servname) { + if (str_isnumber(servname)) { + if (pai->ai_socktype == GAI_ANY) { + /* caller accept *GAI_ANY* socktype */ + pai->ai_socktype = SOCK_DGRAM; + pai->ai_protocol = IPPROTO_UDP; + } + port = htons((u_short)atoi(servname)); + } else { + struct servent *sp; + const char *proto; + + proto = NULL; + switch (pai->ai_socktype) { + case GAI_ANY: + proto = NULL; + break; + case SOCK_DGRAM: + proto = "udp"; + break; + case SOCK_STREAM: + proto = "tcp"; + break; + default: + fprintf(stderr, "panic!\n"); + break; + } + if ((sp = getservbyname(servname, proto)) == NULL) + ERR(EAI_SERVICE); + port = sp->s_port; + if (pai->ai_socktype == GAI_ANY) { + if (strcmp(sp->s_proto, "udp") == 0) { + pai->ai_socktype = SOCK_DGRAM; + pai->ai_protocol = IPPROTO_UDP; + } else if (strcmp(sp->s_proto, "tcp") == 0) { + pai->ai_socktype = SOCK_STREAM; + pai->ai_protocol = IPPROTO_TCP; + } else + ERR(EAI_PROTOCOL); /*xxx*/ + } + } + } + + /* + * hostname == NULL. + * passive socket -> anyaddr (0.0.0.0 or ::) + * non-passive socket -> localhost (127.0.0.1 or ::1) + */ + if (hostname == NULL) { + struct gai_afd *gai_afd; + + for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) { + if (!(pai->ai_family == PF_UNSPEC + || pai->ai_family == gai_afd->a_af)) { + continue; + } + + if (pai->ai_flags & AI_PASSIVE) { + GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "anyaddr"); + */ + } else { + GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback, + port); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "localhost"); + */ + } + cur = cur->ai_next; + } + top = sentinel.ai_next; + if (top) + goto good; + else + ERR(EAI_FAMILY); + } + + /* hostname as numeric name */ + for (i = 0; gai_afdl[i].a_af; i++) { + if (inet_pton(gai_afdl[i].a_af, hostname, pton)) { + u_long v4a; +#ifdef ENABLE_IPV6 + u_char pfx; +#endif + + switch (gai_afdl[i].a_af) { + case AF_INET: + v4a = ((struct in_addr *)pton)->s_addr; + v4a = ntohl(v4a); + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + pai->ai_flags &= ~AI_CANONNAME; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0 || v4a == IN_LOOPBACKNET) + pai->ai_flags &= ~AI_CANONNAME; + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + pfx = ((struct in6_addr *)pton)->s6_addr[0]; + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + pai->ai_flags &= ~AI_CANONNAME; + break; +#endif + } + + if (pai->ai_family == gai_afdl[i].a_af || + pai->ai_family == PF_UNSPEC) { + if (! (pai->ai_flags & AI_CANONNAME)) { + GET_AI(top, &gai_afdl[i], pton, port); + goto good; + } + /* + * if AI_CANONNAME and if reverse lookup + * fail, return ai anyway to pacify + * calling application. + * + * XXX getaddrinfo() is a name->address + * translation function, and it looks strange + * that we do addr->name translation here. + */ + get_name(pton, &gai_afdl[i], &top, pton, pai, port); + goto good; + } else + ERR(EAI_FAMILY); /*xxx*/ + } + } + + if (pai->ai_flags & AI_NUMERICHOST) + ERR(EAI_NONAME); + + /* hostname as alphabetical name */ + error = get_addr(hostname, pai->ai_family, &top, pai, port); + if (error == 0) { + if (top) { + good: + *res = top; + return SUCCESS; + } else + error = EAI_FAIL; + } + free: + if (top) + freeaddrinfo(top); + bad: + *res = NULL; + return error; +} + +static int +get_name(addr, gai_afd, res, numaddr, pai, port0) + const char *addr; + struct gai_afd *gai_afd; + struct addrinfo **res; + char *numaddr; + struct addrinfo *pai; + int port0; +{ + u_short port = port0 & 0xffff; + struct hostent *hp; + struct addrinfo *cur; + int error = 0; +#ifdef ENABLE_IPV6 + int h_error; +#endif + +#ifdef ENABLE_IPV6 + hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error); +#else + hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET); +#endif + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + GET_AI(cur, gai_afd, hp->h_addr_list[0], port); + GET_CANONNAME(cur, hp->h_name); + } else + GET_AI(cur, gai_afd, numaddr, port); + +#ifdef ENABLE_IPV6 + if (hp) + freehostent(hp); +#endif + *res = cur; + return SUCCESS; + free: + if (cur) + freeaddrinfo(cur); +#ifdef ENABLE_IPV6 + if (hp) + freehostent(hp); +#endif + /* bad: */ + *res = NULL; + return error; +} + +static int +get_addr(hostname, af, res, pai, port0) + const char *hostname; + int af; + struct addrinfo **res; + struct addrinfo *pai; + int port0; +{ + u_short port = port0 & 0xffff; + struct addrinfo sentinel; + struct hostent *hp; + struct addrinfo *top, *cur; + struct gai_afd *gai_afd; + int i, error = 0, h_error; + char *ap; + + top = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; +#ifdef ENABLE_IPV6 + if (af == AF_UNSPEC) { + hp = getipnodebyname(hostname, AF_INET6, + AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); + } else + hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); +#else + hp = gethostbyname(hostname); + h_error = h_errno; +#endif + if (hp == NULL) { + switch (h_error) { + case HOST_NOT_FOUND: + case NO_DATA: + error = EAI_NODATA; + break; + case TRY_AGAIN: + error = EAI_AGAIN; + break; + case NO_RECOVERY: + default: + error = EAI_FAIL; + break; + } + goto free; + } + + if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || + (hp->h_addr_list[0] == NULL)) { + error = EAI_FAIL; + goto free; + } + + for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { + switch (af) { +#ifdef ENABLE_IPV6 + case AF_INET6: + gai_afd = &gai_afdl[N_INET6]; + break; +#endif +#ifndef ENABLE_IPV6 + default: /* AF_UNSPEC */ +#endif + case AF_INET: + gai_afd = &gai_afdl[N_INET]; + break; +#ifdef ENABLE_IPV6 + default: /* AF_UNSPEC */ + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { + ap += sizeof(struct in6_addr) - + sizeof(struct in_addr); + gai_afd = &gai_afdl[N_INET]; + } else + gai_afd = &gai_afdl[N_INET6]; + break; +#endif + } +#ifdef FAITH + if (translate && gai_afd->a_af == AF_INET) { + struct in6_addr *in6; + + GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port); + in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; + memcpy(&in6->s6_addr32[0], &faith_prefix, + sizeof(struct in6_addr) - sizeof(struct in_addr)); + memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr)); + } else +#endif /* FAITH */ + GET_AI(cur->ai_next, gai_afd, ap, port); + if (cur == &sentinel) { + top = cur->ai_next; + GET_CANONNAME(top, hp->h_name); + } + cur = cur->ai_next; + } +#ifdef ENABLE_IPV6 + freehostent(hp); +#endif + *res = top; + return SUCCESS; + free: + if (top) + freeaddrinfo(top); +#ifdef ENABLE_IPV6 + if (hp) + freehostent(hp); +#endif +/* bad: */ + *res = NULL; + return error; +} diff --git a/contrib/tools/python3/src/Modules/getbuildinfo.c b/contrib/tools/python3/src/Modules/getbuildinfo.c index 7cb7397a22c..bb720c2a265 100644 --- a/contrib/tools/python3/src/Modules/getbuildinfo.c +++ b/contrib/tools/python3/src/Modules/getbuildinfo.c @@ -1,68 +1,68 @@ -#include "Python.h" - -#ifndef DONT_HAVE_STDIO_H -#include -#endif - -#ifndef DATE -#ifdef __DATE__ -#define DATE __DATE__ -#else -#define DATE "xx/xx/xx" -#endif -#endif - -#ifndef TIME -#ifdef __TIME__ -#define TIME __TIME__ -#else -#define TIME "xx:xx:xx" -#endif -#endif - -/* XXX Only unix build process has been tested */ -#ifndef GITVERSION -#define GITVERSION "" -#endif -#ifndef GITTAG -#define GITTAG "" -#endif -#ifndef GITBRANCH -#define GITBRANCH "" -#endif - -const char * -Py_GetBuildInfo(void) -{ - static char buildinfo[50 + sizeof(GITVERSION) + - ((sizeof(GITTAG) > sizeof(GITBRANCH)) ? - sizeof(GITTAG) : sizeof(GITBRANCH))]; - const char *revision = _Py_gitversion(); - const char *sep = *revision ? ":" : ""; - const char *gitid = _Py_gitidentifier(); +#include "Python.h" + +#ifndef DONT_HAVE_STDIO_H +#include +#endif + +#ifndef DATE +#ifdef __DATE__ +#define DATE __DATE__ +#else +#define DATE "xx/xx/xx" +#endif +#endif + +#ifndef TIME +#ifdef __TIME__ +#define TIME __TIME__ +#else +#define TIME "xx:xx:xx" +#endif +#endif + +/* XXX Only unix build process has been tested */ +#ifndef GITVERSION +#define GITVERSION "" +#endif +#ifndef GITTAG +#define GITTAG "" +#endif +#ifndef GITBRANCH +#define GITBRANCH "" +#endif + +const char * +Py_GetBuildInfo(void) +{ + static char buildinfo[50 + sizeof(GITVERSION) + + ((sizeof(GITTAG) > sizeof(GITBRANCH)) ? + sizeof(GITTAG) : sizeof(GITBRANCH))]; + const char *revision = _Py_gitversion(); + const char *sep = *revision ? ":" : ""; + const char *gitid = _Py_gitidentifier(); if (!(*gitid)) { gitid = "main"; } - PyOS_snprintf(buildinfo, sizeof(buildinfo), - "%s%s%s, %.20s, %.9s", gitid, sep, revision, - DATE, TIME); - return buildinfo; -} - -const char * -_Py_gitversion(void) -{ - return GITVERSION; -} - -const char * -_Py_gitidentifier(void) -{ - const char *gittag, *gitid; - gittag = GITTAG; - if ((*gittag) && strcmp(gittag, "undefined") != 0) - gitid = gittag; - else - gitid = GITBRANCH; - return gitid; -} + PyOS_snprintf(buildinfo, sizeof(buildinfo), + "%s%s%s, %.20s, %.9s", gitid, sep, revision, + DATE, TIME); + return buildinfo; +} + +const char * +_Py_gitversion(void) +{ + return GITVERSION; +} + +const char * +_Py_gitidentifier(void) +{ + const char *gittag, *gitid; + gittag = GITTAG; + if ((*gittag) && strcmp(gittag, "undefined") != 0) + gitid = gittag; + else + gitid = GITBRANCH; + return gitid; +} diff --git a/contrib/tools/python3/src/Modules/getnameinfo.c b/contrib/tools/python3/src/Modules/getnameinfo.c index f014c11ae15..ffc2bd91235 100644 --- a/contrib/tools/python3/src/Modules/getnameinfo.c +++ b/contrib/tools/python3/src/Modules/getnameinfo.c @@ -1,214 +1,214 @@ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Issues to be discussed: - * - Thread safe-ness must be checked - * - Return values. There seems to be no standard for return value (RFC2133) - * but INRIA implementation returns EAI_xxx defined for getaddrinfo(). - */ - -#if 0 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "addrinfo.h" -#endif - -#define SUCCESS 0 -#define YES 1 -#define NO 0 - -static struct gni_afd { - int a_af; - int a_addrlen; - int a_socklen; - int a_off; -} gni_afdl [] = { -#ifdef ENABLE_IPV6 - {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), - offsetof(struct sockaddr_in6, sin6_addr)}, -#endif - {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), - offsetof(struct sockaddr_in, sin_addr)}, - {0, 0, 0}, -}; - -struct gni_sockinet { - u_char si_len; - u_char si_family; - u_short si_port; -}; - -#define ENI_NOSOCKET 0 -#define ENI_NOSERVNAME 1 -#define ENI_NOHOSTNAME 2 -#define ENI_MEMORY 3 -#define ENI_SYSTEM 4 -#define ENI_FAMILY 5 -#define ENI_SALEN 6 - -/* forward declaration to make gcc happy */ -int getnameinfo(const struct sockaddr *, size_t, char *, size_t, - char *, size_t, int); - -int -getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) - const struct sockaddr *sa; - size_t salen; - char *host; - size_t hostlen; - char *serv; - size_t servlen; - int flags; -{ - struct gni_afd *gni_afd; - struct servent *sp; - struct hostent *hp; - u_short port; - int family, len, i; - char *addr, *p; - u_long v4a; -#ifdef ENABLE_IPV6 - u_char pfx; -#endif - int h_error; - char numserv[512]; - char numaddr[512]; - - if (sa == NULL) - return ENI_NOSOCKET; - -#ifdef HAVE_SOCKADDR_SA_LEN - len = sa->sa_len; - if (len != salen) return ENI_SALEN; -#else - len = salen; -#endif - - family = sa->sa_family; - for (i = 0; gni_afdl[i].a_af; i++) - if (gni_afdl[i].a_af == family) { - gni_afd = &gni_afdl[i]; - goto found; - } - return ENI_FAMILY; - - found: - if (len != gni_afd->a_socklen) return ENI_SALEN; - - port = ((struct gni_sockinet *)sa)->si_port; /* network byte order */ - addr = (char *)sa + gni_afd->a_off; - - if (serv == NULL || servlen == 0) { - /* what we should do? */ - } else if (flags & NI_NUMERICSERV) { - sprintf(numserv, "%d", ntohs(port)); - if (strlen(numserv) > servlen) - return ENI_MEMORY; - strcpy(serv, numserv); - } else { - sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); - if (sp) { - if (strlen(sp->s_name) > servlen) - return ENI_MEMORY; - strcpy(serv, sp->s_name); - } else - return ENI_NOSERVNAME; - } - - switch (sa->sa_family) { - case AF_INET: - v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr; - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - flags |= NI_NUMERICHOST; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0 || v4a == IN_LOOPBACKNET) - flags |= NI_NUMERICHOST; - break; -#ifdef ENABLE_IPV6 - case AF_INET6: - pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; - if (pfx == 0 || pfx == 0xfe || pfx == 0xff) - flags |= NI_NUMERICHOST; - break; -#endif - } - if (host == NULL || hostlen == 0) { - /* what should we do? */ - } else if (flags & NI_NUMERICHOST) { - if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_SYSTEM; - if (strlen(numaddr) > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); - } else { -#ifdef ENABLE_IPV6 - hp = getipnodebyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af, &h_error); -#else - hp = gethostbyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af); - h_error = h_errno; -#endif - - if (hp) { - if (flags & NI_NOFQDN) { - p = strchr(hp->h_name, '.'); - if (p) *p = '\0'; - } - if (strlen(hp->h_name) > hostlen) { -#ifdef ENABLE_IPV6 - freehostent(hp); -#endif - return ENI_MEMORY; - } - strcpy(host, hp->h_name); -#ifdef ENABLE_IPV6 - freehostent(hp); -#endif - } else { - if (flags & NI_NAMEREQD) - return ENI_NOHOSTNAME; - if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_NOHOSTNAME; - if (strlen(numaddr) > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); - } - } - return SUCCESS; -} +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Issues to be discussed: + * - Thread safe-ness must be checked + * - Return values. There seems to be no standard for return value (RFC2133) + * but INRIA implementation returns EAI_xxx defined for getaddrinfo(). + */ + +#if 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "addrinfo.h" +#endif + +#define SUCCESS 0 +#define YES 1 +#define NO 0 + +static struct gni_afd { + int a_af; + int a_addrlen; + int a_socklen; + int a_off; +} gni_afdl [] = { +#ifdef ENABLE_IPV6 + {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr)}, +#endif + {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr)}, + {0, 0, 0}, +}; + +struct gni_sockinet { + u_char si_len; + u_char si_family; + u_short si_port; +}; + +#define ENI_NOSOCKET 0 +#define ENI_NOSERVNAME 1 +#define ENI_NOHOSTNAME 2 +#define ENI_MEMORY 3 +#define ENI_SYSTEM 4 +#define ENI_FAMILY 5 +#define ENI_SALEN 6 + +/* forward declaration to make gcc happy */ +int getnameinfo(const struct sockaddr *, size_t, char *, size_t, + char *, size_t, int); + +int +getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) + const struct sockaddr *sa; + size_t salen; + char *host; + size_t hostlen; + char *serv; + size_t servlen; + int flags; +{ + struct gni_afd *gni_afd; + struct servent *sp; + struct hostent *hp; + u_short port; + int family, len, i; + char *addr, *p; + u_long v4a; +#ifdef ENABLE_IPV6 + u_char pfx; +#endif + int h_error; + char numserv[512]; + char numaddr[512]; + + if (sa == NULL) + return ENI_NOSOCKET; + +#ifdef HAVE_SOCKADDR_SA_LEN + len = sa->sa_len; + if (len != salen) return ENI_SALEN; +#else + len = salen; +#endif + + family = sa->sa_family; + for (i = 0; gni_afdl[i].a_af; i++) + if (gni_afdl[i].a_af == family) { + gni_afd = &gni_afdl[i]; + goto found; + } + return ENI_FAMILY; + + found: + if (len != gni_afd->a_socklen) return ENI_SALEN; + + port = ((struct gni_sockinet *)sa)->si_port; /* network byte order */ + addr = (char *)sa + gni_afd->a_off; + + if (serv == NULL || servlen == 0) { + /* what we should do? */ + } else if (flags & NI_NUMERICSERV) { + sprintf(numserv, "%d", ntohs(port)); + if (strlen(numserv) > servlen) + return ENI_MEMORY; + strcpy(serv, numserv); + } else { + sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); + if (sp) { + if (strlen(sp->s_name) > servlen) + return ENI_MEMORY; + strcpy(serv, sp->s_name); + } else + return ENI_NOSERVNAME; + } + + switch (sa->sa_family) { + case AF_INET: + v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr; + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + flags |= NI_NUMERICHOST; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0 || v4a == IN_LOOPBACKNET) + flags |= NI_NUMERICHOST; + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + flags |= NI_NUMERICHOST; + break; +#endif + } + if (host == NULL || hostlen == 0) { + /* what should we do? */ + } else if (flags & NI_NUMERICHOST) { + if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr)) + == NULL) + return ENI_SYSTEM; + if (strlen(numaddr) > hostlen) + return ENI_MEMORY; + strcpy(host, numaddr); + } else { +#ifdef ENABLE_IPV6 + hp = getipnodebyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af, &h_error); +#else + hp = gethostbyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af); + h_error = h_errno; +#endif + + if (hp) { + if (flags & NI_NOFQDN) { + p = strchr(hp->h_name, '.'); + if (p) *p = '\0'; + } + if (strlen(hp->h_name) > hostlen) { +#ifdef ENABLE_IPV6 + freehostent(hp); +#endif + return ENI_MEMORY; + } + strcpy(host, hp->h_name); +#ifdef ENABLE_IPV6 + freehostent(hp); +#endif + } else { + if (flags & NI_NAMEREQD) + return ENI_NOHOSTNAME; + if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr)) + == NULL) + return ENI_NOHOSTNAME; + if (strlen(numaddr) > hostlen) + return ENI_MEMORY; + strcpy(host, numaddr); + } + } + return SUCCESS; +} diff --git a/contrib/tools/python3/src/Modules/getpath.c b/contrib/tools/python3/src/Modules/getpath.c index 5014dde930e..b20be8abe90 100644 --- a/contrib/tools/python3/src/Modules/getpath.c +++ b/contrib/tools/python3/src/Modules/getpath.c @@ -1,140 +1,140 @@ -#define PYTHONPATH ":" -/* Return the initial module search path. */ - -#include "Python.h" +#define PYTHONPATH ":" +/* Return the initial module search path. */ + +#include "Python.h" #include "pycore_fileutils.h" #include "pycore_initconfig.h" #include "pycore_pathconfig.h" #include "osdefs.h" // DELIM - -#include -#include - -#ifdef __APPLE__ -# include -#endif - -/* Search in some common locations for the associated Python libraries. - * - * Two directories must be found, the platform independent directory - * (prefix), containing the common .py and .pyc files, and the platform - * dependent directory (exec_prefix), containing the shared library - * modules. Note that prefix and exec_prefix can be the same directory, - * but for some installations, they are different. - * - * Py_GetPath() carries out separate searches for prefix and exec_prefix. - * Each search tries a number of different locations until a ``landmark'' - * file or directory is found. If no prefix or exec_prefix is found, a - * warning message is issued and the preprocessor defined PREFIX and - * EXEC_PREFIX are used (even though they will not work); python carries on - * as best as is possible, but most imports will fail. - * - * Before any searches are done, the location of the executable is - * determined. If argv[0] has one or more slashes in it, it is used - * unchanged. Otherwise, it must have been invoked from the shell's path, - * so we search $PATH for the named executable and use that. If the - * executable was not found on $PATH (or there was no $PATH environment - * variable), the original argv[0] string is used. - * - * Next, the executable location is examined to see if it is a symbolic - * link. If so, the link is chased (correctly interpreting a relative - * pathname if one is found) and the directory of the link target is used. - * - * Finally, argv0_path is set to the directory containing the executable - * (i.e. the last component is stripped). - * - * With argv0_path in hand, we perform a number of steps. The same steps - * are performed for prefix and for exec_prefix, but with a different - * landmark. - * - * Step 1. Are we running python out of the build directory? This is - * checked by looking for a different kind of landmark relative to - * argv0_path. For prefix, the landmark's path is derived from the VPATH - * preprocessor variable (taking into account that its value is almost, but - * not quite, what we need). For exec_prefix, the landmark is - * pybuilddir.txt. If the landmark is found, we're done. - * - * For the remaining steps, the prefix landmark will always be - * lib/python$VERSION/os.py and the exec_prefix will always be - * lib/python$VERSION/lib-dynload, where $VERSION is Python's version - * number as supplied by the Makefile. Note that this means that no more - * build directory checking is performed; if the first step did not find - * the landmarks, the assumption is that python is running from an - * installed setup. - * - * Step 2. See if the $PYTHONHOME environment variable points to the - * installed location of the Python libraries. If $PYTHONHOME is set, then - * it points to prefix and exec_prefix. $PYTHONHOME can be a single - * directory, which is used for both, or the prefix and exec_prefix - * directories separated by a colon. - * - * Step 3. Try to find prefix and exec_prefix relative to argv0_path, - * backtracking up the path until it is exhausted. This is the most common - * step to succeed. Note that if prefix and exec_prefix are different, - * exec_prefix is more likely to be found; however if exec_prefix is a - * subdirectory of prefix, both will be found. - * - * Step 4. Search the directories pointed to by the preprocessor variables - * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be - * passed in as options to the configure script. - * - * That's it! - * - * Well, almost. Once we have determined prefix and exec_prefix, the - * preprocessor variable PYTHONPATH is used to construct a path. Each - * relative path on PYTHONPATH is prefixed with prefix. Then the directory - * containing the shared library modules is appended. The environment - * variable $PYTHONPATH is inserted in front of it all. Finally, the - * prefix and exec_prefix globals are tweaked so they reflect the values - * expected by other code, by stripping the "lib/python$VERSION/..." stuff - * off. If either points to the build directory, the globals are reset to - * the corresponding preprocessor variables (so sys.prefix will reflect the - * installation location, even though sys.path points into the build - * directory). This seems to make more sense given that currently the only - * known use of sys.prefix and sys.exec_prefix is for the ILU installation - * process to find the installed Python tree. - * - * An embedding application can use Py_SetPath() to override all of + +#include +#include + +#ifdef __APPLE__ +# include +#endif + +/* Search in some common locations for the associated Python libraries. + * + * Two directories must be found, the platform independent directory + * (prefix), containing the common .py and .pyc files, and the platform + * dependent directory (exec_prefix), containing the shared library + * modules. Note that prefix and exec_prefix can be the same directory, + * but for some installations, they are different. + * + * Py_GetPath() carries out separate searches for prefix and exec_prefix. + * Each search tries a number of different locations until a ``landmark'' + * file or directory is found. If no prefix or exec_prefix is found, a + * warning message is issued and the preprocessor defined PREFIX and + * EXEC_PREFIX are used (even though they will not work); python carries on + * as best as is possible, but most imports will fail. + * + * Before any searches are done, the location of the executable is + * determined. If argv[0] has one or more slashes in it, it is used + * unchanged. Otherwise, it must have been invoked from the shell's path, + * so we search $PATH for the named executable and use that. If the + * executable was not found on $PATH (or there was no $PATH environment + * variable), the original argv[0] string is used. + * + * Next, the executable location is examined to see if it is a symbolic + * link. If so, the link is chased (correctly interpreting a relative + * pathname if one is found) and the directory of the link target is used. + * + * Finally, argv0_path is set to the directory containing the executable + * (i.e. the last component is stripped). + * + * With argv0_path in hand, we perform a number of steps. The same steps + * are performed for prefix and for exec_prefix, but with a different + * landmark. + * + * Step 1. Are we running python out of the build directory? This is + * checked by looking for a different kind of landmark relative to + * argv0_path. For prefix, the landmark's path is derived from the VPATH + * preprocessor variable (taking into account that its value is almost, but + * not quite, what we need). For exec_prefix, the landmark is + * pybuilddir.txt. If the landmark is found, we're done. + * + * For the remaining steps, the prefix landmark will always be + * lib/python$VERSION/os.py and the exec_prefix will always be + * lib/python$VERSION/lib-dynload, where $VERSION is Python's version + * number as supplied by the Makefile. Note that this means that no more + * build directory checking is performed; if the first step did not find + * the landmarks, the assumption is that python is running from an + * installed setup. + * + * Step 2. See if the $PYTHONHOME environment variable points to the + * installed location of the Python libraries. If $PYTHONHOME is set, then + * it points to prefix and exec_prefix. $PYTHONHOME can be a single + * directory, which is used for both, or the prefix and exec_prefix + * directories separated by a colon. + * + * Step 3. Try to find prefix and exec_prefix relative to argv0_path, + * backtracking up the path until it is exhausted. This is the most common + * step to succeed. Note that if prefix and exec_prefix are different, + * exec_prefix is more likely to be found; however if exec_prefix is a + * subdirectory of prefix, both will be found. + * + * Step 4. Search the directories pointed to by the preprocessor variables + * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be + * passed in as options to the configure script. + * + * That's it! + * + * Well, almost. Once we have determined prefix and exec_prefix, the + * preprocessor variable PYTHONPATH is used to construct a path. Each + * relative path on PYTHONPATH is prefixed with prefix. Then the directory + * containing the shared library modules is appended. The environment + * variable $PYTHONPATH is inserted in front of it all. Finally, the + * prefix and exec_prefix globals are tweaked so they reflect the values + * expected by other code, by stripping the "lib/python$VERSION/..." stuff + * off. If either points to the build directory, the globals are reset to + * the corresponding preprocessor variables (so sys.prefix will reflect the + * installation location, even though sys.path points into the build + * directory). This seems to make more sense given that currently the only + * known use of sys.prefix and sys.exec_prefix is for the ILU installation + * process to find the installed Python tree. + * + * An embedding application can use Py_SetPath() to override all of * these automatic path computations. - * - * NOTE: Windows MSVC builds use PC/getpathp.c instead! - */ - -#ifdef __cplusplus -extern "C" { -#endif - - + * + * NOTE: Windows MSVC builds use PC/getpathp.c instead! + */ + +#ifdef __cplusplus +extern "C" { +#endif + + #if (!defined(PREFIX) || !defined(EXEC_PREFIX) \ || !defined(VERSION) || !defined(VPATH)) #error "PREFIX, EXEC_PREFIX, VERSION and VPATH macros must be defined" -#endif - -#ifndef LANDMARK -#define LANDMARK L"os.py" -#endif - +#endif + +#ifndef LANDMARK +#define LANDMARK L"os.py" +#endif + #define BUILD_LANDMARK L"Modules/Setup.local" -#define DECODE_LOCALE_ERR(NAME, LEN) \ - ((LEN) == (size_t)-2) \ +#define DECODE_LOCALE_ERR(NAME, LEN) \ + ((LEN) == (size_t)-2) \ ? _PyStatus_ERR("cannot decode " NAME) \ : _PyStatus_NO_MEMORY() - + #define PATHLEN_ERR() _PyStatus_ERR("path configuration: path too long") -typedef struct { - wchar_t *path_env; /* PATH environment variable */ - +typedef struct { + wchar_t *path_env; /* PATH environment variable */ + wchar_t *pythonpath_macro; /* PYTHONPATH macro */ wchar_t *prefix_macro; /* PREFIX macro */ wchar_t *exec_prefix_macro; /* EXEC_PREFIX macro */ wchar_t *vpath_macro; /* VPATH macro */ - + wchar_t *lib_python; /* / "pythonX.Y" */ - - int prefix_found; /* found platform independent libraries? */ - int exec_prefix_found; /* found the platform dependent libraries? */ + + int prefix_found; /* found platform independent libraries? */ + int exec_prefix_found; /* found the platform dependent libraries? */ int warnings; const wchar_t *pythonpath_env; @@ -144,89 +144,89 @@ typedef struct { wchar_t *zip_path; wchar_t *prefix; wchar_t *exec_prefix; -} PyCalculatePath; - -static const wchar_t delimiter[2] = {DELIM, '\0'}; -static const wchar_t separator[2] = {SEP, '\0'}; - - -/* Get file status. Encode the path to the locale encoding. */ -static int -_Py_wstat(const wchar_t* path, struct stat *buf) -{ - int err; - char *fname; - fname = _Py_EncodeLocaleRaw(path, NULL); - if (fname == NULL) { - errno = EINVAL; - return -1; - } - err = stat(fname, buf); - PyMem_RawFree(fname); - return err; -} - - -static void -reduce(wchar_t *dir) -{ - size_t i = wcslen(dir); +} PyCalculatePath; + +static const wchar_t delimiter[2] = {DELIM, '\0'}; +static const wchar_t separator[2] = {SEP, '\0'}; + + +/* Get file status. Encode the path to the locale encoding. */ +static int +_Py_wstat(const wchar_t* path, struct stat *buf) +{ + int err; + char *fname; + fname = _Py_EncodeLocaleRaw(path, NULL); + if (fname == NULL) { + errno = EINVAL; + return -1; + } + err = stat(fname, buf); + PyMem_RawFree(fname); + return err; +} + + +static void +reduce(wchar_t *dir) +{ + size_t i = wcslen(dir); while (i > 0 && dir[i] != SEP) { - --i; + --i; } - dir[i] = '\0'; -} - - + dir[i] = '\0'; +} + + /* Is file, not directory */ -static int +static int isfile(const wchar_t *filename) -{ - struct stat buf; - if (_Py_wstat(filename, &buf) != 0) { - return 0; - } - if (!S_ISREG(buf.st_mode)) { - return 0; - } - return 1; -} - - -/* Is executable file */ -static int +{ + struct stat buf; + if (_Py_wstat(filename, &buf) != 0) { + return 0; + } + if (!S_ISREG(buf.st_mode)) { + return 0; + } + return 1; +} + + +/* Is executable file */ +static int isxfile(const wchar_t *filename) -{ - struct stat buf; - if (_Py_wstat(filename, &buf) != 0) { - return 0; - } - if (!S_ISREG(buf.st_mode)) { - return 0; - } - if ((buf.st_mode & 0111) == 0) { - return 0; - } - return 1; -} - - -/* Is directory */ -static int +{ + struct stat buf; + if (_Py_wstat(filename, &buf) != 0) { + return 0; + } + if (!S_ISREG(buf.st_mode)) { + return 0; + } + if ((buf.st_mode & 0111) == 0) { + return 0; + } + return 1; +} + + +/* Is directory */ +static int isdir(const wchar_t *filename) -{ - struct stat buf; - if (_Py_wstat(filename, &buf) != 0) { - return 0; - } - if (!S_ISDIR(buf.st_mode)) { - return 0; - } - return 1; -} - - -/* Add a path component, by appending stuff to buffer. +{ + struct stat buf; + if (_Py_wstat(filename, &buf) != 0) { + return 0; + } + if (!S_ISDIR(buf.st_mode)) { + return 0; + } + return 1; +} + + +/* Add a path component, by appending stuff to buffer. buflen: 'buffer' length in characters including trailing NUL. If path2 is empty: @@ -235,7 +235,7 @@ isdir(const wchar_t *filename) - otherwise, do nothing. */ static PyStatus joinpath(wchar_t *path, const wchar_t *path2, size_t path_len) -{ +{ size_t n; if (!_Py_isabs(path2)) { n = wcslen(path); @@ -245,23 +245,23 @@ joinpath(wchar_t *path, const wchar_t *path2, size_t path_len) if (n > 0 && path[n-1] != SEP) { path[n++] = SEP; - } - } + } + } else { n = 0; - } + } size_t k = wcslen(path2); if (n + k >= path_len) { return PATHLEN_ERR(); - } + } wcsncpy(path + n, path2, k); path[n + k] = '\0'; return _PyStatus_OK(); -} - - +} + + static wchar_t* substring(const wchar_t *str, size_t len) { @@ -317,40 +317,40 @@ safe_wcscpy(wchar_t *dst, const wchar_t *src, size_t n) } -/* copy_absolute requires that path be allocated at least +/* copy_absolute requires that path be allocated at least 'abs_path_len' characters (including trailing NUL). */ static PyStatus copy_absolute(wchar_t *abs_path, const wchar_t *path, size_t abs_path_len) -{ +{ if (_Py_isabs(path)) { if (safe_wcscpy(abs_path, path, abs_path_len) < 0) { return PATHLEN_ERR(); } - } - else { + } + else { if (!_Py_wgetcwd(abs_path, abs_path_len)) { - /* unable to get the current directory */ + /* unable to get the current directory */ if (safe_wcscpy(abs_path, path, abs_path_len) < 0) { return PATHLEN_ERR(); } return _PyStatus_OK(); - } + } if (path[0] == '.' && path[1] == SEP) { path += 2; - } + } PyStatus status = joinpath(abs_path, path, abs_path_len); if (_PyStatus_EXCEPTION(status)) { return status; } - } + } return _PyStatus_OK(); -} - - +} + + /* path_len: path length in characters including trailing NUL */ static PyStatus absolutize(wchar_t **path_p) -{ +{ assert(!_Py_isabs(*path_p)); wchar_t abs_path[MAXPATHLEN+1]; @@ -367,9 +367,9 @@ absolutize(wchar_t **path_p) return _PyStatus_NO_MEMORY(); } return _PyStatus_OK(); -} - - +} + + /* Is module -- check for .pyc too */ static PyStatus ismodule(const wchar_t *path, int *result) @@ -405,29 +405,29 @@ ismodule(const wchar_t *path, int *result) } -#if defined(__CYGWIN__) || defined(__MINGW32__) -#ifndef EXE_SUFFIX -#define EXE_SUFFIX L".exe" -#endif - +#if defined(__CYGWIN__) || defined(__MINGW32__) +#ifndef EXE_SUFFIX +#define EXE_SUFFIX L".exe" +#endif + /* pathlen: 'path' length in characters including trailing NUL */ static PyStatus add_exe_suffix(wchar_t **progpath_p) -{ +{ wchar_t *progpath = *progpath_p; - /* Check for already have an executable suffix */ - size_t n = wcslen(progpath); - size_t s = wcslen(EXE_SUFFIX); + /* Check for already have an executable suffix */ + size_t n = wcslen(progpath); + size_t s = wcslen(EXE_SUFFIX); if (wcsncasecmp(EXE_SUFFIX, progpath + n - s, s) == 0) { return _PyStatus_OK(); } - + wchar_t *progpath2 = PyMem_RawMalloc((n + s + 1) * sizeof(wchar_t)); if (progpath2 == NULL) { return _PyStatus_NO_MEMORY(); } - + memcpy(progpath2, progpath, n * sizeof(wchar_t)); memcpy(progpath2 + n, EXE_SUFFIX, s * sizeof(wchar_t)); progpath2[n+s] = L'\0'; @@ -435,42 +435,42 @@ add_exe_suffix(wchar_t **progpath_p) if (isxfile(progpath2)) { PyMem_RawFree(*progpath_p); *progpath_p = progpath2; - } + } else { PyMem_RawFree(progpath2); } return _PyStatus_OK(); -} -#endif - - -/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN - bytes long. -*/ +} +#endif + + +/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN + bytes long. +*/ static PyStatus search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, wchar_t *prefix, size_t prefix_len, int *found) -{ +{ PyStatus status; - /* If PYTHONHOME is set, we believe it unconditionally */ + /* If PYTHONHOME is set, we believe it unconditionally */ if (pathconfig->home) { /* Path: / */ if (safe_wcscpy(prefix, pathconfig->home, prefix_len) < 0) { return PATHLEN_ERR(); } - wchar_t *delim = wcschr(prefix, DELIM); - if (delim) { - *delim = L'\0'; - } + wchar_t *delim = wcschr(prefix, DELIM); + if (delim) { + *delim = L'\0'; + } status = joinpath(prefix, calculate->lib_python, prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; } *found = 1; return _PyStatus_OK(); - } - + } + /* Check to see if argv0_path is in the build directory Path: / */ @@ -490,7 +490,7 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, /* or if VPATH is empty: / Lib */ if (safe_wcscpy(prefix, calculate->argv0_path, prefix_len) < 0) { return PATHLEN_ERR(); - } + } status = joinpath(prefix, calculate->vpath_macro, prefix_len); if (_PyStatus_EXCEPTION(status)) { @@ -512,21 +512,21 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, *found = -1; return _PyStatus_OK(); } - } - - /* Search from argv0_path, until root is found */ + } + + /* Search from argv0_path, until root is found */ status = copy_absolute(prefix, calculate->argv0_path, prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; } - do { + do { /* Path: / / LANDMARK */ size_t n = wcslen(prefix); status = joinpath(prefix, calculate->lib_python, prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; - } + } int module; status = ismodule(prefix, &module); @@ -537,15 +537,15 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, *found = 1; return _PyStatus_OK(); } - prefix[n] = L'\0'; - reduce(prefix); - } while (prefix[0]); - + prefix[n] = L'\0'; + reduce(prefix); + } while (prefix[0]); + /* Look at configure's PREFIX. Path: / / LANDMARK */ if (safe_wcscpy(prefix, calculate->prefix_macro, prefix_len) < 0) { return PATHLEN_ERR(); - } + } status = joinpath(prefix, calculate->lib_python, prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; @@ -561,15 +561,15 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, return _PyStatus_OK(); } - /* Fail */ + /* Fail */ *found = 0; return _PyStatus_OK(); -} - - +} + + static PyStatus calculate_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ +{ wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); size_t prefix_len = Py_ARRAY_LENGTH(prefix); @@ -582,15 +582,15 @@ calculate_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) return status; } - if (!calculate->prefix_found) { + if (!calculate->prefix_found) { if (calculate->warnings) { - fprintf(stderr, - "Could not find platform independent libraries \n"); - } + fprintf(stderr, + "Could not find platform independent libraries \n"); + } calculate->prefix = joinpath2(calculate->prefix_macro, calculate->lib_python); - } + } else { calculate->prefix = _PyMem_RawWcsdup(prefix); } @@ -599,28 +599,28 @@ calculate_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) return _PyStatus_NO_MEMORY(); } return _PyStatus_OK(); -} - - +} + + static PyStatus calculate_set_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - /* Reduce prefix and exec_prefix to their essence, - * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. - * If we're loading relative to the build directory, - * return the compiled-in defaults instead. - */ - if (calculate->prefix_found > 0) { +{ + /* Reduce prefix and exec_prefix to their essence, + * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. + * If we're loading relative to the build directory, + * return the compiled-in defaults instead. + */ + if (calculate->prefix_found > 0) { wchar_t *prefix = _PyMem_RawWcsdup(calculate->prefix); if (prefix == NULL) { return _PyStatus_NO_MEMORY(); } - reduce(prefix); - reduce(prefix); + reduce(prefix); + reduce(prefix); if (prefix[0]) { pathconfig->prefix = prefix; - } + } else { PyMem_RawFree(prefix); @@ -631,17 +631,17 @@ calculate_set_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) return _PyStatus_NO_MEMORY(); } } - } - else { + } + else { pathconfig->prefix = _PyMem_RawWcsdup(calculate->prefix_macro); if (pathconfig->prefix == NULL) { return _PyStatus_NO_MEMORY(); } - } + } return _PyStatus_OK(); -} - - +} + + static PyStatus calculate_pybuilddir(const wchar_t *argv0_path, wchar_t *exec_prefix, size_t exec_prefix_len, @@ -693,42 +693,42 @@ calculate_pybuilddir(const wchar_t *argv0_path, } -/* search_for_exec_prefix requires that argv0_path be no more than - MAXPATHLEN bytes long. -*/ +/* search_for_exec_prefix requires that argv0_path be no more than + MAXPATHLEN bytes long. +*/ static PyStatus search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, wchar_t *exec_prefix, size_t exec_prefix_len, int *found) -{ +{ PyStatus status; - - /* If PYTHONHOME is set, we believe it unconditionally */ + + /* If PYTHONHOME is set, we believe it unconditionally */ if (pathconfig->home) { /* Path: / / "lib-dynload" */ wchar_t *delim = wcschr(pathconfig->home, DELIM); - if (delim) { + if (delim) { if (safe_wcscpy(exec_prefix, delim+1, exec_prefix_len) < 0) { return PATHLEN_ERR(); } - } - else { + } + else { if (safe_wcscpy(exec_prefix, pathconfig->home, exec_prefix_len) < 0) { return PATHLEN_ERR(); } - } + } status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; - } + } status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; - } + } *found = 1; return _PyStatus_OK(); - } - + } + /* Check for pybuilddir.txt */ assert(*found == 0); status = calculate_pybuilddir(calculate->argv0_path, @@ -740,13 +740,13 @@ search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, return _PyStatus_OK(); } - /* Search from argv0_path, until root is found */ + /* Search from argv0_path, until root is found */ status = copy_absolute(exec_prefix, calculate->argv0_path, exec_prefix_len); if (_PyStatus_EXCEPTION(status)) { return status; } - do { + do { /* Path: / / "lib-dynload" */ size_t n = wcslen(exec_prefix); status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); @@ -757,14 +757,14 @@ search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, if (_PyStatus_EXCEPTION(status)) { return status; } - if (isdir(exec_prefix)) { + if (isdir(exec_prefix)) { *found = 1; return _PyStatus_OK(); - } - exec_prefix[n] = L'\0'; - reduce(exec_prefix); - } while (exec_prefix[0]); - + } + exec_prefix[n] = L'\0'; + reduce(exec_prefix); + } while (exec_prefix[0]); + /* Look at configure's EXEC_PREFIX. Path: / / "lib-dynload" */ @@ -779,20 +779,20 @@ search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, if (_PyStatus_EXCEPTION(status)) { return status; } - if (isdir(exec_prefix)) { + if (isdir(exec_prefix)) { *found = 1; return _PyStatus_OK(); - } - - /* Fail */ + } + + /* Fail */ *found = 0; return _PyStatus_OK(); -} - - +} + + static PyStatus calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ +{ PyStatus status; wchar_t exec_prefix[MAXPATHLEN+1]; memset(exec_prefix, 0, sizeof(exec_prefix)); @@ -805,11 +805,11 @@ calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) return status; } - if (!calculate->exec_prefix_found) { + if (!calculate->exec_prefix_found) { if (calculate->warnings) { - fprintf(stderr, - "Could not find platform dependent libraries \n"); - } + fprintf(stderr, + "Could not find platform dependent libraries \n"); + } /* / "lib-dynload" */ wchar_t *lib_dynload = joinpath2(calculate->platlibdir, @@ -825,7 +825,7 @@ calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) if (calculate->exec_prefix == NULL) { return _PyStatus_NO_MEMORY(); } - } + } else { /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ calculate->exec_prefix = _PyMem_RawWcsdup(exec_prefix); @@ -834,26 +834,26 @@ calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) } } return _PyStatus_OK(); -} - - +} + + static PyStatus calculate_set_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - if (calculate->exec_prefix_found > 0) { +{ + if (calculate->exec_prefix_found > 0) { wchar_t *exec_prefix = _PyMem_RawWcsdup(calculate->exec_prefix); if (exec_prefix == NULL) { return _PyStatus_NO_MEMORY(); } - reduce(exec_prefix); - reduce(exec_prefix); - reduce(exec_prefix); + reduce(exec_prefix); + reduce(exec_prefix); + reduce(exec_prefix); if (exec_prefix[0]) { pathconfig->exec_prefix = exec_prefix; - } + } else { /* empty string: use SEP instead */ PyMem_RawFree(exec_prefix); @@ -865,13 +865,13 @@ calculate_set_exec_prefix(PyCalculatePath *calculate, return _PyStatus_NO_MEMORY(); } } - } - else { + } + else { pathconfig->exec_prefix = _PyMem_RawWcsdup(calculate->exec_prefix_macro); if (pathconfig->exec_prefix == NULL) { return _PyStatus_NO_MEMORY(); } - } + } return _PyStatus_OK(); } @@ -916,16 +916,16 @@ calculate_which(const wchar_t *path_env, wchar_t *program_name, /* not found */ return _PyStatus_OK(); -} - - +} + + #ifdef __APPLE__ static PyStatus calculate_program_macos(wchar_t **abs_path_p) -{ +{ char execpath[MAXPATHLEN + 1]; uint32_t nsexeclength = Py_ARRAY_LENGTH(execpath) - 1; - + /* On Mac OS X, if a script uses an interpreter of the form "#!/opt/python2.3/bin/python", the kernel only passes "python" as argv[0], which falls through to the $PATH search below. @@ -960,31 +960,31 @@ calculate_program_impl(PyCalculatePath *calculate, _PyPathConfig *pathconfig) PyStatus status; - /* If there is no slash in the argv0 path, then we have to - * assume python is on the user's $PATH, since there's no - * other way to find a directory to start the search from. If - * $PATH isn't exported, you lose. - */ + /* If there is no slash in the argv0 path, then we have to + * assume python is on the user's $PATH, since there's no + * other way to find a directory to start the search from. If + * $PATH isn't exported, you lose. + */ if (wcschr(pathconfig->program_name, SEP)) { pathconfig->program_full_path = _PyMem_RawWcsdup(pathconfig->program_name); if (pathconfig->program_full_path == NULL) { return _PyStatus_NO_MEMORY(); } return _PyStatus_OK(); - } + } -#ifdef __APPLE__ +#ifdef __APPLE__ wchar_t *abs_path = NULL; status = calculate_program_macos(&abs_path); if (_PyStatus_EXCEPTION(status)) { return status; - } + } if (abs_path) { pathconfig->program_full_path = abs_path; return _PyStatus_OK(); } -#endif /* __APPLE__ */ - +#endif /* __APPLE__ */ + if (calculate->path_env) { wchar_t *abs_path = NULL; status = calculate_which(calculate->path_env, pathconfig->program_name, @@ -996,39 +996,39 @@ calculate_program_impl(PyCalculatePath *calculate, _PyPathConfig *pathconfig) pathconfig->program_full_path = abs_path; return _PyStatus_OK(); } - } - + } + /* In the last resort, use an empty string */ pathconfig->program_full_path = _PyMem_RawWcsdup(L""); if (pathconfig->program_full_path == NULL) { return _PyStatus_NO_MEMORY(); - } + } return _PyStatus_OK(); -} - - +} + + /* Calculate pathconfig->program_full_path */ static PyStatus calculate_program(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ +{ PyStatus status; status = calculate_program_impl(calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { return status; } - + if (pathconfig->program_full_path[0] != '\0') { /* program_full_path is not empty */ - + /* Make sure that program_full_path is an absolute path */ if (!_Py_isabs(pathconfig->program_full_path)) { status = absolutize(&pathconfig->program_full_path); if (_PyStatus_EXCEPTION(status)) { return status; } - } - + } + #if defined(__CYGWIN__) || defined(__MINGW32__) /* For these platforms it is necessary to ensure that the .exe suffix * is appended to the filename, otherwise there is potential for @@ -1066,8 +1066,8 @@ resolve_symlinks(wchar_t **path_p) if (*path_p == NULL) { return _PyStatus_NO_MEMORY(); } - } - else { + } + else { /* new_path is relative to path */ reduce(*path_p); @@ -1078,18 +1078,18 @@ resolve_symlinks(wchar_t **path_p) PyMem_RawFree(*path_p); *path_p = abs_path; - } - + } + nlink++; /* 40 is the Linux kernel 4.2 limit */ if (nlink >= 40) { return _PyStatus_ERR("maximum number of symbolic links reached"); - } - } + } + } return _PyStatus_OK(); } -#endif /* HAVE_READLINK */ - +#endif /* HAVE_READLINK */ + #ifdef WITH_NEXT_FRAMEWORK static PyStatus @@ -1170,21 +1170,21 @@ calculate_argv0_path_framework(PyCalculatePath *calculate, _PyPathConfig *pathco done: PyMem_RawFree(wbuf); return status; -} +} #endif - - + + static PyStatus calculate_argv0_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ +{ PyStatus status; - + calculate->argv0_path = _PyMem_RawWcsdup(pathconfig->program_full_path); if (calculate->argv0_path == NULL) { return _PyStatus_NO_MEMORY(); } - + #ifdef WITH_NEXT_FRAMEWORK status = calculate_argv0_path_framework(calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { @@ -1245,12 +1245,12 @@ calculate_open_pyenv(PyCalculatePath *calculate, FILE **env_file_p) if (*env_file_p == NULL) { /* fopen() failed: reset errno */ - errno = 0; + errno = 0; } return _PyStatus_OK(); } - - + + /* Search for an "pyvenv.cfg" environment configuration file, first in the executable's directory and then in the parent directory. If found, open it for use when searching for prefixes. @@ -1266,12 +1266,12 @@ calculate_read_pyenv(PyCalculatePath *calculate) if (_PyStatus_EXCEPTION(status)) { assert(env_file == NULL); return status; - } + } if (env_file == NULL) { /* pyvenv.cfg not found */ return _PyStatus_OK(); } - + /* Look for a 'home' variable and set argv0_path to it, if found */ wchar_t *home = NULL; status = _Py_FindEnvConfigValue(env_file, L"home", &home); @@ -1279,21 +1279,21 @@ calculate_read_pyenv(PyCalculatePath *calculate) fclose(env_file); return status; } - + if (home) { PyMem_RawFree(calculate->argv0_path); calculate->argv0_path = home; - } - fclose(env_file); + } + fclose(env_file); return _PyStatus_OK(); -} - - +} + + static PyStatus calculate_zip_path(PyCalculatePath *calculate) -{ +{ PyStatus res; - + /* Path: / "pythonXY.zip" */ wchar_t *path = joinpath2(calculate->platlibdir, L"python" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) @@ -1302,7 +1302,7 @@ calculate_zip_path(PyCalculatePath *calculate) return _PyStatus_NO_MEMORY(); } - if (calculate->prefix_found > 0) { + if (calculate->prefix_found > 0) { /* Use the reduced prefix returned by Py_GetPrefix() Path: / / "pythonXY.zip" */ @@ -1315,17 +1315,17 @@ calculate_zip_path(PyCalculatePath *calculate) reduce(parent); calculate->zip_path = joinpath2(parent, path); PyMem_RawFree(parent); - } - else { + } + else { calculate->zip_path = joinpath2(calculate->prefix_macro, path); - } + } if (calculate->zip_path == NULL) { res = _PyStatus_NO_MEMORY(); goto done; } - - /* Replace "00" with version */ + + /* Replace "00" with version */ size_t len = wcslen(calculate->zip_path); calculate->zip_path[len - 6] = VERSION[0]; calculate->zip_path[len - 5] = VERSION[2]; @@ -1335,139 +1335,139 @@ calculate_zip_path(PyCalculatePath *calculate) done: PyMem_RawFree(path); return res; -} - - +} + + static PyStatus calculate_module_search_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ +{ pathconfig->module_search_path = calculate->pythonpath_env; if (!pathconfig->module_search_path) { pathconfig->module_search_path = pathconfig->program_full_path; - } + } pathconfig->module_search_path = _PyMem_RawWcsdup(pathconfig->module_search_path); return _PyStatus_OK(); - - /* Calculate size of return buffer */ - size_t bufsz = 0; + + /* Calculate size of return buffer */ + size_t bufsz = 0; if (calculate->pythonpath_env != NULL) { bufsz += wcslen(calculate->pythonpath_env) + 1; - } - + } + wchar_t *defpath = calculate->pythonpath_macro; size_t prefixsz = wcslen(calculate->prefix) + 1; - while (1) { - wchar_t *delim = wcschr(defpath, DELIM); - + while (1) { + wchar_t *delim = wcschr(defpath, DELIM); + if (!_Py_isabs(defpath)) { - /* Paths are relative to prefix */ - bufsz += prefixsz; - } - - if (delim) { - bufsz += delim - defpath + 1; - } - else { - bufsz += wcslen(defpath) + 1; - break; - } - defpath = delim + 1; - } - + /* Paths are relative to prefix */ + bufsz += prefixsz; + } + + if (delim) { + bufsz += delim - defpath + 1; + } + else { + bufsz += wcslen(defpath) + 1; + break; + } + defpath = delim + 1; + } + bufsz += wcslen(calculate->zip_path) + 1; bufsz += wcslen(calculate->exec_prefix) + 1; - - /* Allocate the buffer */ - wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); - if (buf == NULL) { + + /* Allocate the buffer */ + wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); + if (buf == NULL) { return _PyStatus_NO_MEMORY(); - } - buf[0] = '\0'; - - /* Run-time value of $PYTHONPATH goes first */ + } + buf[0] = '\0'; + + /* Run-time value of $PYTHONPATH goes first */ if (calculate->pythonpath_env) { wcscpy(buf, calculate->pythonpath_env); - wcscat(buf, delimiter); - } - - /* Next is the default zip path */ + wcscat(buf, delimiter); + } + + /* Next is the default zip path */ wcscat(buf, calculate->zip_path); - wcscat(buf, delimiter); - - /* Next goes merge of compile-time $PYTHONPATH with - * dynamically located prefix. - */ + wcscat(buf, delimiter); + + /* Next goes merge of compile-time $PYTHONPATH with + * dynamically located prefix. + */ defpath = calculate->pythonpath_macro; - while (1) { - wchar_t *delim = wcschr(defpath, DELIM); - + while (1) { + wchar_t *delim = wcschr(defpath, DELIM); + if (!_Py_isabs(defpath)) { wcscat(buf, calculate->prefix); if (prefixsz >= 2 && calculate->prefix[prefixsz - 2] != SEP && - defpath[0] != (delim ? DELIM : L'\0')) - { - /* not empty */ - wcscat(buf, separator); - } - } - - if (delim) { - size_t len = delim - defpath + 1; - size_t end = wcslen(buf) + len; - wcsncat(buf, defpath, len); - buf[end] = '\0'; - } - else { - wcscat(buf, defpath); - break; - } - defpath = delim + 1; - } - wcscat(buf, delimiter); - - /* Finally, on goes the directory for dynamic-load modules */ + defpath[0] != (delim ? DELIM : L'\0')) + { + /* not empty */ + wcscat(buf, separator); + } + } + + if (delim) { + size_t len = delim - defpath + 1; + size_t end = wcslen(buf) + len; + wcsncat(buf, defpath, len); + buf[end] = '\0'; + } + else { + wcscat(buf, defpath); + break; + } + defpath = delim + 1; + } + wcscat(buf, delimiter); + + /* Finally, on goes the directory for dynamic-load modules */ wcscat(buf, calculate->exec_prefix); - + pathconfig->module_search_path = buf; return _PyStatus_OK(); -} - - +} + + static PyStatus calculate_init(PyCalculatePath *calculate, const PyConfig *config) -{ - size_t len; +{ + size_t len; calculate->warnings = config->pathconfig_warnings; calculate->pythonpath_env = config->pythonpath_env; calculate->platlibdir = config->platlibdir; - const char *path = getenv("PATH"); - if (path) { - calculate->path_env = Py_DecodeLocale(path, &len); - if (!calculate->path_env) { - return DECODE_LOCALE_ERR("PATH environment variable", len); - } - } - + const char *path = getenv("PATH"); + if (path) { + calculate->path_env = Py_DecodeLocale(path, &len); + if (!calculate->path_env) { + return DECODE_LOCALE_ERR("PATH environment variable", len); + } + } + /* Decode macros */ calculate->pythonpath_macro = Py_DecodeLocale(PYTHONPATH, &len); if (!calculate->pythonpath_macro) { return DECODE_LOCALE_ERR("PYTHONPATH macro", len); - } + } calculate->prefix_macro = Py_DecodeLocale(PREFIX, &len); if (!calculate->prefix_macro) { return DECODE_LOCALE_ERR("PREFIX macro", len); - } + } calculate->exec_prefix_macro = Py_DecodeLocale(EXEC_PREFIX, &len); if (!calculate->exec_prefix_macro) { return DECODE_LOCALE_ERR("EXEC_PREFIX macro", len); - } + } calculate->vpath_macro = Py_DecodeLocale(VPATH, &len); if (!calculate->vpath_macro) { return DECODE_LOCALE_ERR("VPATH macro", len); - } + } // / "pythonX.Y" wchar_t *pyversion = Py_DecodeLocale("python" VERSION, &len); @@ -1481,12 +1481,12 @@ calculate_init(PyCalculatePath *calculate, const PyConfig *config) } return _PyStatus_OK(); -} - - -static void -calculate_free(PyCalculatePath *calculate) -{ +} + + +static void +calculate_free(PyCalculatePath *calculate) +{ PyMem_RawFree(calculate->pythonpath_macro); PyMem_RawFree(calculate->prefix_macro); PyMem_RawFree(calculate->exec_prefix_macro); @@ -1495,40 +1495,40 @@ calculate_free(PyCalculatePath *calculate) PyMem_RawFree(calculate->path_env); PyMem_RawFree(calculate->zip_path); PyMem_RawFree(calculate->argv0_path); - PyMem_RawFree(calculate->prefix); - PyMem_RawFree(calculate->exec_prefix); -} - - + PyMem_RawFree(calculate->prefix); + PyMem_RawFree(calculate->exec_prefix); +} + + static PyStatus calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ +{ PyStatus status; - + if (pathconfig->program_full_path == NULL) { status = calculate_program(calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { return status; } - } - + } + status = calculate_argv0_path(calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { return status; - } - + } + /* If a pyvenv.cfg configure file is found, argv0_path is overridden with its 'home' variable. */ status = calculate_read_pyenv(calculate); if (_PyStatus_EXCEPTION(status)) { return status; } - + status = calculate_prefix(calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { return status; } - + status = calculate_zip_path(calculate); if (_PyStatus_EXCEPTION(status)) { return status; @@ -1538,38 +1538,38 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) if (_PyStatus_EXCEPTION(status)) { return status; } - + if ((!calculate->prefix_found || !calculate->exec_prefix_found) && calculate->warnings) - { - fprintf(stderr, - "Consider setting $PYTHONHOME to [:]\n"); - } - + { + fprintf(stderr, + "Consider setting $PYTHONHOME to [:]\n"); + } + if (pathconfig->module_search_path == NULL) { status = calculate_module_search_path(calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { return status; } - } - + } + if (pathconfig->prefix == NULL) { status = calculate_set_prefix(calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { return status; } - } - + } + if (pathconfig->exec_prefix == NULL) { status = calculate_set_exec_prefix(calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { return status; } - } + } return _PyStatus_OK(); -} - - +} + + /* Calculate the Python path configuration. Inputs: @@ -1602,32 +1602,32 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) If a field is already set (non NULL), it is left unchanged. */ PyStatus _PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config) -{ +{ PyStatus status; - PyCalculatePath calculate; - memset(&calculate, 0, sizeof(calculate)); - + PyCalculatePath calculate; + memset(&calculate, 0, sizeof(calculate)); + status = calculate_init(&calculate, config); if (_PyStatus_EXCEPTION(status)) { - goto done; - } - + goto done; + } + status = calculate_path(&calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { - goto done; - } - + goto done; + } + /* program_full_path must an either an empty string or an absolute path */ assert(wcslen(pathconfig->program_full_path) == 0 || _Py_isabs(pathconfig->program_full_path)); status = _PyStatus_OK(); - -done: - calculate_free(&calculate); + +done: + calculate_free(&calculate); return status; -} - -#ifdef __cplusplus -} -#endif +} + +#ifdef __cplusplus +} +#endif diff --git a/contrib/tools/python3/src/Modules/grpmodule.c b/contrib/tools/python3/src/Modules/grpmodule.c index cdb3ae859b3..612096924d8 100644 --- a/contrib/tools/python3/src/Modules/grpmodule.c +++ b/contrib/tools/python3/src/Modules/grpmodule.c @@ -1,43 +1,43 @@ - -/* UNIX group file access module */ - -#include "Python.h" -#include "posixmodule.h" - -#include - -#include "clinic/grpmodule.c.h" -/*[clinic input] -module grp -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cade63f2ed1bd9f8]*/ - -static PyStructSequence_Field struct_group_type_fields[] = { - {"gr_name", "group name"}, - {"gr_passwd", "password"}, - {"gr_gid", "group id"}, - {"gr_mem", "group members"}, - {0} -}; - -PyDoc_STRVAR(struct_group__doc__, -"grp.struct_group: Results from getgr*() routines.\n\n\ -This object may be accessed either as a tuple of\n\ - (gr_name,gr_passwd,gr_gid,gr_mem)\n\ -or via the object attributes as named in the above tuple.\n"); - -static PyStructSequence_Desc struct_group_type_desc = { - "grp.struct_group", - struct_group__doc__, - struct_group_type_fields, - 4, -}; - - + +/* UNIX group file access module */ + +#include "Python.h" +#include "posixmodule.h" + +#include + +#include "clinic/grpmodule.c.h" +/*[clinic input] +module grp +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cade63f2ed1bd9f8]*/ + +static PyStructSequence_Field struct_group_type_fields[] = { + {"gr_name", "group name"}, + {"gr_passwd", "password"}, + {"gr_gid", "group id"}, + {"gr_mem", "group members"}, + {0} +}; + +PyDoc_STRVAR(struct_group__doc__, +"grp.struct_group: Results from getgr*() routines.\n\n\ +This object may be accessed either as a tuple of\n\ + (gr_name,gr_passwd,gr_gid,gr_mem)\n\ +or via the object attributes as named in the above tuple.\n"); + +static PyStructSequence_Desc struct_group_type_desc = { + "grp.struct_group", + struct_group__doc__, + struct_group_type_fields, + 4, +}; + + typedef struct { PyTypeObject *StructGrpType; } grpmodulestate; - + static inline grpmodulestate* get_grp_state(PyObject *module) { @@ -52,96 +52,96 @@ static struct PyModuleDef grpmodule; #define DEFAULT_BUFFER_SIZE 1024 -static PyObject * -mkgrent(struct group *p) -{ - int setIndex = 0; +static PyObject * +mkgrent(struct group *p) +{ + int setIndex = 0; PyObject *v, *w; - char **member; - + char **member; + if ((v = PyStructSequence_New(modulestate_global->StructGrpType)) == NULL) - return NULL; - - if ((w = PyList_New(0)) == NULL) { - Py_DECREF(v); - return NULL; - } - for (member = p->gr_mem; *member != NULL; member++) { - PyObject *x = PyUnicode_DecodeFSDefault(*member); - if (x == NULL || PyList_Append(w, x) != 0) { - Py_XDECREF(x); - Py_DECREF(w); - Py_DECREF(v); - return NULL; - } - Py_DECREF(x); - } - -#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val) - SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_name)); - if (p->gr_passwd) - SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd)); - else { - SET(setIndex++, Py_None); - Py_INCREF(Py_None); - } - SET(setIndex++, _PyLong_FromGid(p->gr_gid)); - SET(setIndex++, w); -#undef SET - - if (PyErr_Occurred()) { - Py_DECREF(v); - return NULL; - } - - return v; -} - -/*[clinic input] -grp.getgrgid - - id: object - -Return the group database entry for the given numeric group ID. - -If id is not valid, raise KeyError. -[clinic start generated code]*/ - -static PyObject * -grp_getgrgid_impl(PyObject *module, PyObject *id) -/*[clinic end generated code: output=30797c289504a1ba input=15fa0e2ccf5cda25]*/ -{ + return NULL; + + if ((w = PyList_New(0)) == NULL) { + Py_DECREF(v); + return NULL; + } + for (member = p->gr_mem; *member != NULL; member++) { + PyObject *x = PyUnicode_DecodeFSDefault(*member); + if (x == NULL || PyList_Append(w, x) != 0) { + Py_XDECREF(x); + Py_DECREF(w); + Py_DECREF(v); + return NULL; + } + Py_DECREF(x); + } + +#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val) + SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_name)); + if (p->gr_passwd) + SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd)); + else { + SET(setIndex++, Py_None); + Py_INCREF(Py_None); + } + SET(setIndex++, _PyLong_FromGid(p->gr_gid)); + SET(setIndex++, w); +#undef SET + + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + + return v; +} + +/*[clinic input] +grp.getgrgid + + id: object + +Return the group database entry for the given numeric group ID. + +If id is not valid, raise KeyError. +[clinic start generated code]*/ + +static PyObject * +grp_getgrgid_impl(PyObject *module, PyObject *id) +/*[clinic end generated code: output=30797c289504a1ba input=15fa0e2ccf5cda25]*/ +{ PyObject *py_int_id, *retval = NULL; int nomem = 0; char *buf = NULL, *buf2 = NULL; - gid_t gid; - struct group *p; - - if (!_Py_Gid_Converter(id, &gid)) { - if (!PyErr_ExceptionMatches(PyExc_TypeError)) { - return NULL; - } - PyErr_Clear(); - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "group id must be int, not %.200", + gid_t gid; + struct group *p; + + if (!_Py_Gid_Converter(id, &gid)) { + if (!PyErr_ExceptionMatches(PyExc_TypeError)) { + return NULL; + } + PyErr_Clear(); + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "group id must be int, not %.200", Py_TYPE(id)->tp_name) < 0) { - return NULL; - } - py_int_id = PyNumber_Long(id); - if (!py_int_id) - return NULL; - if (!_Py_Gid_Converter(py_int_id, &gid)) { - Py_DECREF(py_int_id); - return NULL; - } - Py_DECREF(py_int_id); - } + return NULL; + } + py_int_id = PyNumber_Long(id); + if (!py_int_id) + return NULL; + if (!_Py_Gid_Converter(py_int_id, &gid)) { + Py_DECREF(py_int_id); + return NULL; + } + Py_DECREF(py_int_id); + } #ifdef HAVE_GETGRGID_R int status; Py_ssize_t bufsize; /* Note: 'grp' will be used via pointer 'p' on getgrgid_r success. */ struct group grp; - + Py_BEGIN_ALLOW_THREADS bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); if (bufsize == -1) { @@ -179,50 +179,50 @@ grp_getgrgid_impl(PyObject *module, PyObject *id) if (nomem == 1) { return PyErr_NoMemory(); } - PyObject *gid_obj = _PyLong_FromGid(gid); - if (gid_obj == NULL) - return NULL; - PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj); - Py_DECREF(gid_obj); - return NULL; - } + PyObject *gid_obj = _PyLong_FromGid(gid); + if (gid_obj == NULL) + return NULL; + PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj); + Py_DECREF(gid_obj); + return NULL; + } retval = mkgrent(p); #ifdef HAVE_GETGRGID_R PyMem_RawFree(buf); #endif return retval; -} - -/*[clinic input] -grp.getgrnam - - name: unicode - -Return the group database entry for the given group name. - -If name is not valid, raise KeyError. -[clinic start generated code]*/ - -static PyObject * -grp_getgrnam_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=67905086f403c21c input=08ded29affa3c863]*/ -{ +} + +/*[clinic input] +grp.getgrnam + + name: unicode + +Return the group database entry for the given group name. + +If name is not valid, raise KeyError. +[clinic start generated code]*/ + +static PyObject * +grp_getgrnam_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=67905086f403c21c input=08ded29affa3c863]*/ +{ char *buf = NULL, *buf2 = NULL, *name_chars; int nomem = 0; - struct group *p; - PyObject *bytes, *retval = NULL; - - if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL) - return NULL; - /* check for embedded null bytes */ - if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1) - goto out; + struct group *p; + PyObject *bytes, *retval = NULL; + + if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL) + return NULL; + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1) + goto out; #ifdef HAVE_GETGRNAM_R int status; Py_ssize_t bufsize; /* Note: 'grp' will be used via pointer 'p' on getgrnam_r success. */ struct group grp; - + Py_BEGIN_ALLOW_THREADS bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); if (bufsize == -1) { @@ -262,100 +262,100 @@ grp_getgrnam_impl(PyObject *module, PyObject *name) else { PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %R", name); } - goto out; - } - retval = mkgrent(p); -out: + goto out; + } + retval = mkgrent(p); +out: PyMem_RawFree(buf); - Py_DECREF(bytes); - return retval; -} - -/*[clinic input] -grp.getgrall - -Return a list of all available group entries, in arbitrary order. - -An entry whose name starts with '+' or '-' represents an instruction -to use YP/NIS and may not be accessible via getgrnam or getgrgid. -[clinic start generated code]*/ - -static PyObject * -grp_getgrall_impl(PyObject *module) -/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/ -{ - PyObject *d; - struct group *p; - - if ((d = PyList_New(0)) == NULL) - return NULL; - setgrent(); - while ((p = getgrent()) != NULL) { - PyObject *v = mkgrent(p); - if (v == NULL || PyList_Append(d, v) != 0) { - Py_XDECREF(v); - Py_DECREF(d); - endgrent(); - return NULL; - } - Py_DECREF(v); - } - endgrent(); - return d; -} - -static PyMethodDef grp_methods[] = { - GRP_GETGRGID_METHODDEF - GRP_GETGRNAM_METHODDEF - GRP_GETGRALL_METHODDEF - {NULL, NULL} -}; - -PyDoc_STRVAR(grp__doc__, -"Access to the Unix group database.\n\ -\n\ -Group entries are reported as 4-tuples containing the following fields\n\ -from the group database, in order:\n\ -\n\ - gr_name - name of the group\n\ - gr_passwd - group password (encrypted); often empty\n\ - gr_gid - numeric ID of the group\n\ - gr_mem - list of members\n\ -\n\ -The gid is an integer, name and password are strings. (Note that most\n\ -users are not explicitly listed as members of the groups they are in\n\ -according to the password database. Check both databases to get\n\ -complete membership information.)"); - + Py_DECREF(bytes); + return retval; +} + +/*[clinic input] +grp.getgrall + +Return a list of all available group entries, in arbitrary order. + +An entry whose name starts with '+' or '-' represents an instruction +to use YP/NIS and may not be accessible via getgrnam or getgrgid. +[clinic start generated code]*/ + +static PyObject * +grp_getgrall_impl(PyObject *module) +/*[clinic end generated code: output=585dad35e2e763d7 input=d7df76c825c367df]*/ +{ + PyObject *d; + struct group *p; + + if ((d = PyList_New(0)) == NULL) + return NULL; + setgrent(); + while ((p = getgrent()) != NULL) { + PyObject *v = mkgrent(p); + if (v == NULL || PyList_Append(d, v) != 0) { + Py_XDECREF(v); + Py_DECREF(d); + endgrent(); + return NULL; + } + Py_DECREF(v); + } + endgrent(); + return d; +} + +static PyMethodDef grp_methods[] = { + GRP_GETGRGID_METHODDEF + GRP_GETGRNAM_METHODDEF + GRP_GETGRALL_METHODDEF + {NULL, NULL} +}; + +PyDoc_STRVAR(grp__doc__, +"Access to the Unix group database.\n\ +\n\ +Group entries are reported as 4-tuples containing the following fields\n\ +from the group database, in order:\n\ +\n\ + gr_name - name of the group\n\ + gr_passwd - group password (encrypted); often empty\n\ + gr_gid - numeric ID of the group\n\ + gr_mem - list of members\n\ +\n\ +The gid is an integer, name and password are strings. (Note that most\n\ +users are not explicitly listed as members of the groups they are in\n\ +according to the password database. Check both databases to get\n\ +complete membership information.)"); + static int grpmodule_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(get_grp_state(m)->StructGrpType); return 0; } - + static int grpmodule_clear(PyObject *m) { Py_CLEAR(get_grp_state(m)->StructGrpType); return 0; } - + static void grpmodule_free(void *m) { grpmodule_clear((PyObject *)m); } -static struct PyModuleDef grpmodule = { - PyModuleDef_HEAD_INIT, - "grp", - grp__doc__, +static struct PyModuleDef grpmodule = { + PyModuleDef_HEAD_INIT, + "grp", + grp__doc__, sizeof(grpmodulestate), - grp_methods, - NULL, + grp_methods, + NULL, grpmodule_traverse, grpmodule_clear, grpmodule_free, -}; - -PyMODINIT_FUNC -PyInit_grp(void) -{ +}; + +PyMODINIT_FUNC +PyInit_grp(void) +{ PyObject *m; if ((m = PyState_FindModule(&grpmodule)) != NULL) { Py_INCREF(m); @@ -363,16 +363,16 @@ PyInit_grp(void) } if ((m = PyModule_Create(&grpmodule)) == NULL) { - return NULL; - } + return NULL; + } grpmodulestate *state = PyModule_GetState(m); state->StructGrpType = PyStructSequence_NewType(&struct_group_type_desc); if (state->StructGrpType == NULL) { - return NULL; + return NULL; } Py_INCREF(state->StructGrpType); PyModule_AddObject(m, "struct_group", (PyObject *) state->StructGrpType); - return m; -} + return m; +} diff --git a/contrib/tools/python3/src/Modules/hashlib.h b/contrib/tools/python3/src/Modules/hashlib.h index 56ae7a5e50b..f2bd1a38468 100644 --- a/contrib/tools/python3/src/Modules/hashlib.h +++ b/contrib/tools/python3/src/Modules/hashlib.h @@ -1,59 +1,59 @@ -/* Common code for use by all hashlib related modules. */ - -/* - * Given a PyObject* obj, fill in the Py_buffer* viewp with the result - * of PyObject_GetBuffer. Sets an exception and issues the erraction - * on any errors, e.g. 'return NULL' or 'goto error'. - */ -#define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \ - if (PyUnicode_Check((obj))) { \ - PyErr_SetString(PyExc_TypeError, \ +/* Common code for use by all hashlib related modules. */ + +/* + * Given a PyObject* obj, fill in the Py_buffer* viewp with the result + * of PyObject_GetBuffer. Sets an exception and issues the erraction + * on any errors, e.g. 'return NULL' or 'goto error'. + */ +#define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \ + if (PyUnicode_Check((obj))) { \ + PyErr_SetString(PyExc_TypeError, \ "Strings must be encoded before hashing");\ - erraction; \ - } \ - if (!PyObject_CheckBuffer((obj))) { \ - PyErr_SetString(PyExc_TypeError, \ - "object supporting the buffer API required"); \ - erraction; \ - } \ - if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \ - erraction; \ - } \ - if ((viewp)->ndim > 1) { \ - PyErr_SetString(PyExc_BufferError, \ - "Buffer must be single dimension"); \ - PyBuffer_Release((viewp)); \ - erraction; \ - } \ - } while(0) - -#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \ - GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL) - -/* - * Helper code to synchronize access to the hash object when the GIL is - * released around a CPU consuming hashlib operation. All code paths that - * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / - * LEAVE_HASHLIB block or explicitly acquire and release the lock inside - * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for - * an operation. - */ - -#include "pythread.h" -#define ENTER_HASHLIB(obj) \ - if ((obj)->lock) { \ - if (!PyThread_acquire_lock((obj)->lock, 0)) { \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock((obj)->lock, 1); \ - Py_END_ALLOW_THREADS \ - } \ - } -#define LEAVE_HASHLIB(obj) \ - if ((obj)->lock) { \ - PyThread_release_lock((obj)->lock); \ - } - -/* TODO(gps): We should probably make this a module or EVPobject attribute - * to allow the user to optimize based on the platform they're using. */ -#define HASHLIB_GIL_MINSIZE 2048 - + erraction; \ + } \ + if (!PyObject_CheckBuffer((obj))) { \ + PyErr_SetString(PyExc_TypeError, \ + "object supporting the buffer API required"); \ + erraction; \ + } \ + if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \ + erraction; \ + } \ + if ((viewp)->ndim > 1) { \ + PyErr_SetString(PyExc_BufferError, \ + "Buffer must be single dimension"); \ + PyBuffer_Release((viewp)); \ + erraction; \ + } \ + } while(0) + +#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \ + GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL) + +/* + * Helper code to synchronize access to the hash object when the GIL is + * released around a CPU consuming hashlib operation. All code paths that + * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / + * LEAVE_HASHLIB block or explicitly acquire and release the lock inside + * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for + * an operation. + */ + +#include "pythread.h" +#define ENTER_HASHLIB(obj) \ + if ((obj)->lock) { \ + if (!PyThread_acquire_lock((obj)->lock, 0)) { \ + Py_BEGIN_ALLOW_THREADS \ + PyThread_acquire_lock((obj)->lock, 1); \ + Py_END_ALLOW_THREADS \ + } \ + } +#define LEAVE_HASHLIB(obj) \ + if ((obj)->lock) { \ + PyThread_release_lock((obj)->lock); \ + } + +/* TODO(gps): We should probably make this a module or EVPobject attribute + * to allow the user to optimize based on the platform they're using. */ +#define HASHLIB_GIL_MINSIZE 2048 + diff --git a/contrib/tools/python3/src/Modules/itertoolsmodule.c b/contrib/tools/python3/src/Modules/itertoolsmodule.c index bc5382af7e9..58da533b9be 100644 --- a/contrib/tools/python3/src/Modules/itertoolsmodule.c +++ b/contrib/tools/python3/src/Modules/itertoolsmodule.c @@ -1,14 +1,14 @@ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" + +#define PY_SSIZE_T_CLEAN +#include "Python.h" #include "pycore_tupleobject.h" #include "pycore_object.h" // _PyObject_GC_TRACK() #include // offsetof() - -/* Itertools module written and maintained - by Raymond D. Hettinger -*/ - + +/* Itertools module written and maintained + by Raymond D. Hettinger +*/ + /*[clinic input] module itertools class itertools.groupby "groupbyobject *" "&groupby_type" @@ -29,7 +29,7 @@ class itertools.filterfalse "filterfalseobject *" "&filterfalse_type" class itertools.count "countobject *" "&count_type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ea05c93c6d94726a]*/ - + static PyTypeObject groupby_type; static PyTypeObject _grouper_type; static PyTypeObject teedataobject_type; @@ -49,20 +49,20 @@ static PyTypeObject count_type; #include "clinic/itertoolsmodule.c.h" -/* groupby object ************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *it; - PyObject *keyfunc; - PyObject *tgtkey; - PyObject *currkey; - PyObject *currvalue; - const void *currgrouper; /* borrowed reference */ -} groupbyobject; - -static PyObject *_grouper_create(groupbyobject *, PyObject *); - +/* groupby object ************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *it; + PyObject *keyfunc; + PyObject *tgtkey; + PyObject *currkey; + PyObject *currvalue; + const void *currgrouper; /* borrowed reference */ +} groupbyobject; + +static PyObject *_grouper_create(groupbyobject *, PyObject *); + /*[clinic input] @classmethod itertools.groupby.__new__ @@ -77,506 +77,506 @@ itertools.groupby.__new__ make an iterator that returns consecutive keys and groups from the iterable [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc) /*[clinic end generated code: output=cbb1ae3a90fd4141 input=6b3d123e87ff65a1]*/ -{ - groupbyobject *gbo; - - gbo = (groupbyobject *)type->tp_alloc(type, 0); - if (gbo == NULL) - return NULL; - gbo->tgtkey = NULL; - gbo->currkey = NULL; - gbo->currvalue = NULL; - gbo->keyfunc = keyfunc; - Py_INCREF(keyfunc); - gbo->it = PyObject_GetIter(it); - if (gbo->it == NULL) { - Py_DECREF(gbo); - return NULL; - } - return (PyObject *)gbo; -} - -static void -groupby_dealloc(groupbyobject *gbo) -{ - PyObject_GC_UnTrack(gbo); - Py_XDECREF(gbo->it); - Py_XDECREF(gbo->keyfunc); - Py_XDECREF(gbo->tgtkey); - Py_XDECREF(gbo->currkey); - Py_XDECREF(gbo->currvalue); - Py_TYPE(gbo)->tp_free(gbo); -} - -static int -groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg) -{ - Py_VISIT(gbo->it); - Py_VISIT(gbo->keyfunc); - Py_VISIT(gbo->tgtkey); - Py_VISIT(gbo->currkey); - Py_VISIT(gbo->currvalue); - return 0; -} - -Py_LOCAL_INLINE(int) -groupby_step(groupbyobject *gbo) -{ - PyObject *newvalue, *newkey, *oldvalue; - - newvalue = PyIter_Next(gbo->it); - if (newvalue == NULL) - return -1; - - if (gbo->keyfunc == Py_None) { - newkey = newvalue; - Py_INCREF(newvalue); - } else { +{ + groupbyobject *gbo; + + gbo = (groupbyobject *)type->tp_alloc(type, 0); + if (gbo == NULL) + return NULL; + gbo->tgtkey = NULL; + gbo->currkey = NULL; + gbo->currvalue = NULL; + gbo->keyfunc = keyfunc; + Py_INCREF(keyfunc); + gbo->it = PyObject_GetIter(it); + if (gbo->it == NULL) { + Py_DECREF(gbo); + return NULL; + } + return (PyObject *)gbo; +} + +static void +groupby_dealloc(groupbyobject *gbo) +{ + PyObject_GC_UnTrack(gbo); + Py_XDECREF(gbo->it); + Py_XDECREF(gbo->keyfunc); + Py_XDECREF(gbo->tgtkey); + Py_XDECREF(gbo->currkey); + Py_XDECREF(gbo->currvalue); + Py_TYPE(gbo)->tp_free(gbo); +} + +static int +groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg) +{ + Py_VISIT(gbo->it); + Py_VISIT(gbo->keyfunc); + Py_VISIT(gbo->tgtkey); + Py_VISIT(gbo->currkey); + Py_VISIT(gbo->currvalue); + return 0; +} + +Py_LOCAL_INLINE(int) +groupby_step(groupbyobject *gbo) +{ + PyObject *newvalue, *newkey, *oldvalue; + + newvalue = PyIter_Next(gbo->it); + if (newvalue == NULL) + return -1; + + if (gbo->keyfunc == Py_None) { + newkey = newvalue; + Py_INCREF(newvalue); + } else { newkey = PyObject_CallOneArg(gbo->keyfunc, newvalue); - if (newkey == NULL) { - Py_DECREF(newvalue); - return -1; - } - } - - oldvalue = gbo->currvalue; - gbo->currvalue = newvalue; - Py_XSETREF(gbo->currkey, newkey); - Py_XDECREF(oldvalue); - return 0; -} - -static PyObject * -groupby_next(groupbyobject *gbo) -{ - PyObject *r, *grouper; - - gbo->currgrouper = NULL; - /* skip to next iteration group */ - for (;;) { - if (gbo->currkey == NULL) - /* pass */; - else if (gbo->tgtkey == NULL) - break; - else { - int rcmp; - - rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ); - if (rcmp == -1) - return NULL; - else if (rcmp == 0) - break; - } - - if (groupby_step(gbo) < 0) - return NULL; - } - Py_INCREF(gbo->currkey); - Py_XSETREF(gbo->tgtkey, gbo->currkey); - - grouper = _grouper_create(gbo, gbo->tgtkey); - if (grouper == NULL) - return NULL; - - r = PyTuple_Pack(2, gbo->currkey, grouper); - Py_DECREF(grouper); - return r; -} - -static PyObject * + if (newkey == NULL) { + Py_DECREF(newvalue); + return -1; + } + } + + oldvalue = gbo->currvalue; + gbo->currvalue = newvalue; + Py_XSETREF(gbo->currkey, newkey); + Py_XDECREF(oldvalue); + return 0; +} + +static PyObject * +groupby_next(groupbyobject *gbo) +{ + PyObject *r, *grouper; + + gbo->currgrouper = NULL; + /* skip to next iteration group */ + for (;;) { + if (gbo->currkey == NULL) + /* pass */; + else if (gbo->tgtkey == NULL) + break; + else { + int rcmp; + + rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ); + if (rcmp == -1) + return NULL; + else if (rcmp == 0) + break; + } + + if (groupby_step(gbo) < 0) + return NULL; + } + Py_INCREF(gbo->currkey); + Py_XSETREF(gbo->tgtkey, gbo->currkey); + + grouper = _grouper_create(gbo, gbo->tgtkey); + if (grouper == NULL) + return NULL; + + r = PyTuple_Pack(2, gbo->currkey, grouper); + Py_DECREF(grouper); + return r; +} + +static PyObject * groupby_reduce(groupbyobject *lz, PyObject *Py_UNUSED(ignored)) -{ - /* reduce as a 'new' call with an optional 'setstate' if groupby - * has started - */ - PyObject *value; - if (lz->tgtkey && lz->currkey && lz->currvalue) - value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz), - lz->it, lz->keyfunc, lz->currkey, lz->currvalue, lz->tgtkey); - else - value = Py_BuildValue("O(OO)", Py_TYPE(lz), - lz->it, lz->keyfunc); - - return value; -} - -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - -static PyObject * -groupby_setstate(groupbyobject *lz, PyObject *state) -{ - PyObject *currkey, *currvalue, *tgtkey; - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state is not a tuple"); - return NULL; - } - if (!PyArg_ParseTuple(state, "OOO", &currkey, &currvalue, &tgtkey)) { - return NULL; - } - Py_INCREF(currkey); - Py_XSETREF(lz->currkey, currkey); - Py_INCREF(currvalue); - Py_XSETREF(lz->currvalue, currvalue); - Py_INCREF(tgtkey); - Py_XSETREF(lz->tgtkey, tgtkey); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); - -static PyMethodDef groupby_methods[] = { - {"__reduce__", (PyCFunction)groupby_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)groupby_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject groupby_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.groupby", /* tp_name */ - sizeof(groupbyobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)groupby_dealloc, /* tp_dealloc */ +{ + /* reduce as a 'new' call with an optional 'setstate' if groupby + * has started + */ + PyObject *value; + if (lz->tgtkey && lz->currkey && lz->currvalue) + value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz), + lz->it, lz->keyfunc, lz->currkey, lz->currvalue, lz->tgtkey); + else + value = Py_BuildValue("O(OO)", Py_TYPE(lz), + lz->it, lz->keyfunc); + + return value; +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyObject * +groupby_setstate(groupbyobject *lz, PyObject *state) +{ + PyObject *currkey, *currvalue, *tgtkey; + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state is not a tuple"); + return NULL; + } + if (!PyArg_ParseTuple(state, "OOO", &currkey, &currvalue, &tgtkey)) { + return NULL; + } + Py_INCREF(currkey); + Py_XSETREF(lz->currkey, currkey); + Py_INCREF(currvalue); + Py_XSETREF(lz->currvalue, currvalue); + Py_INCREF(tgtkey); + Py_XSETREF(lz->tgtkey, tgtkey); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); + +static PyMethodDef groupby_methods[] = { + {"__reduce__", (PyCFunction)groupby_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)groupby_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject groupby_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.groupby", /* tp_name */ + sizeof(groupbyobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)groupby_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_groupby__doc__, /* tp_doc */ - (traverseproc)groupby_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)groupby_next, /* tp_iternext */ - groupby_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)groupby_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)groupby_next, /* tp_iternext */ + groupby_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_groupby, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* _grouper object (internal) ************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *parent; - PyObject *tgtkey; -} _grouperobject; - + PyObject_GC_Del, /* tp_free */ +}; + + +/* _grouper object (internal) ************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *parent; + PyObject *tgtkey; +} _grouperobject; + /*[clinic input] @classmethod itertools._grouper.__new__ - + parent: object(subclass_of='&groupby_type') tgtkey: object / [clinic start generated code]*/ -static PyObject * +static PyObject * itertools__grouper_impl(PyTypeObject *type, PyObject *parent, PyObject *tgtkey) /*[clinic end generated code: output=462efb1cdebb5914 input=dc180d7771fc8c59]*/ -{ - return _grouper_create((groupbyobject*) parent, tgtkey); -} - -static PyObject * -_grouper_create(groupbyobject *parent, PyObject *tgtkey) -{ - _grouperobject *igo; - - igo = PyObject_GC_New(_grouperobject, &_grouper_type); - if (igo == NULL) - return NULL; - igo->parent = (PyObject *)parent; - Py_INCREF(parent); - igo->tgtkey = tgtkey; - Py_INCREF(tgtkey); - parent->currgrouper = igo; /* borrowed reference */ - - PyObject_GC_Track(igo); - return (PyObject *)igo; -} - -static void -_grouper_dealloc(_grouperobject *igo) -{ - PyObject_GC_UnTrack(igo); - Py_DECREF(igo->parent); - Py_DECREF(igo->tgtkey); - PyObject_GC_Del(igo); -} - -static int -_grouper_traverse(_grouperobject *igo, visitproc visit, void *arg) -{ - Py_VISIT(igo->parent); - Py_VISIT(igo->tgtkey); - return 0; -} - -static PyObject * -_grouper_next(_grouperobject *igo) -{ - groupbyobject *gbo = (groupbyobject *)igo->parent; - PyObject *r; - int rcmp; - - if (gbo->currgrouper != igo) - return NULL; - if (gbo->currvalue == NULL) { - if (groupby_step(gbo) < 0) - return NULL; - } - - assert(gbo->currkey != NULL); - rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ); - if (rcmp <= 0) - /* got any error or current group is end */ - return NULL; - - r = gbo->currvalue; - gbo->currvalue = NULL; - Py_CLEAR(gbo->currkey); - - return r; -} - -static PyObject * +{ + return _grouper_create((groupbyobject*) parent, tgtkey); +} + +static PyObject * +_grouper_create(groupbyobject *parent, PyObject *tgtkey) +{ + _grouperobject *igo; + + igo = PyObject_GC_New(_grouperobject, &_grouper_type); + if (igo == NULL) + return NULL; + igo->parent = (PyObject *)parent; + Py_INCREF(parent); + igo->tgtkey = tgtkey; + Py_INCREF(tgtkey); + parent->currgrouper = igo; /* borrowed reference */ + + PyObject_GC_Track(igo); + return (PyObject *)igo; +} + +static void +_grouper_dealloc(_grouperobject *igo) +{ + PyObject_GC_UnTrack(igo); + Py_DECREF(igo->parent); + Py_DECREF(igo->tgtkey); + PyObject_GC_Del(igo); +} + +static int +_grouper_traverse(_grouperobject *igo, visitproc visit, void *arg) +{ + Py_VISIT(igo->parent); + Py_VISIT(igo->tgtkey); + return 0; +} + +static PyObject * +_grouper_next(_grouperobject *igo) +{ + groupbyobject *gbo = (groupbyobject *)igo->parent; + PyObject *r; + int rcmp; + + if (gbo->currgrouper != igo) + return NULL; + if (gbo->currvalue == NULL) { + if (groupby_step(gbo) < 0) + return NULL; + } + + assert(gbo->currkey != NULL); + rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ); + if (rcmp <= 0) + /* got any error or current group is end */ + return NULL; + + r = gbo->currvalue; + gbo->currvalue = NULL; + Py_CLEAR(gbo->currkey); + + return r; +} + +static PyObject * _grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored)) -{ +{ _Py_IDENTIFIER(iter); - if (((groupbyobject *)lz->parent)->currgrouper != lz) { + if (((groupbyobject *)lz->parent)->currgrouper != lz) { return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); - } - return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey); -} - -static PyMethodDef _grouper_methods[] = { - {"__reduce__", (PyCFunction)_grouper_reduce, METH_NOARGS, - reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - - -static PyTypeObject _grouper_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools._grouper", /* tp_name */ - sizeof(_grouperobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)_grouper_dealloc, /* tp_dealloc */ + } + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey); +} + +static PyMethodDef _grouper_methods[] = { + {"__reduce__", (PyCFunction)_grouper_reduce, METH_NOARGS, + reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + + +static PyTypeObject _grouper_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools._grouper", /* tp_name */ + sizeof(_grouperobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)_grouper_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)_grouper_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)_grouper_next, /* tp_iternext */ - _grouper_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)_grouper_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)_grouper_next, /* tp_iternext */ + _grouper_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools__grouper, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* tee object and with supporting function and objects ***********************/ - -/* The teedataobject pre-allocates space for LINKCELLS number of objects. - To help the object fit neatly inside cache lines (space for 16 to 32 - pointers), the value should be a multiple of 16 minus space for - the other structure members including PyHEAD overhead. The larger the - value, the less memory overhead per object and the less time spent - allocating/deallocating new links. The smaller the number, the less - wasted space and the more rapid freeing of older data. -*/ -#define LINKCELLS 57 - -typedef struct { - PyObject_HEAD - PyObject *it; - int numread; /* 0 <= numread <= LINKCELLS */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* tee object and with supporting function and objects ***********************/ + +/* The teedataobject pre-allocates space for LINKCELLS number of objects. + To help the object fit neatly inside cache lines (space for 16 to 32 + pointers), the value should be a multiple of 16 minus space for + the other structure members including PyHEAD overhead. The larger the + value, the less memory overhead per object and the less time spent + allocating/deallocating new links. The smaller the number, the less + wasted space and the more rapid freeing of older data. +*/ +#define LINKCELLS 57 + +typedef struct { + PyObject_HEAD + PyObject *it; + int numread; /* 0 <= numread <= LINKCELLS */ int running; - PyObject *nextlink; - PyObject *(values[LINKCELLS]); -} teedataobject; - -typedef struct { - PyObject_HEAD - teedataobject *dataobj; - int index; /* 0 <= index <= LINKCELLS */ - PyObject *weakreflist; -} teeobject; - -static PyObject * -teedataobject_newinternal(PyObject *it) -{ - teedataobject *tdo; - - tdo = PyObject_GC_New(teedataobject, &teedataobject_type); - if (tdo == NULL) - return NULL; - + PyObject *nextlink; + PyObject *(values[LINKCELLS]); +} teedataobject; + +typedef struct { + PyObject_HEAD + teedataobject *dataobj; + int index; /* 0 <= index <= LINKCELLS */ + PyObject *weakreflist; +} teeobject; + +static PyObject * +teedataobject_newinternal(PyObject *it) +{ + teedataobject *tdo; + + tdo = PyObject_GC_New(teedataobject, &teedataobject_type); + if (tdo == NULL) + return NULL; + tdo->running = 0; - tdo->numread = 0; - tdo->nextlink = NULL; - Py_INCREF(it); - tdo->it = it; - PyObject_GC_Track(tdo); - return (PyObject *)tdo; -} - -static PyObject * -teedataobject_jumplink(teedataobject *tdo) -{ - if (tdo->nextlink == NULL) - tdo->nextlink = teedataobject_newinternal(tdo->it); - Py_XINCREF(tdo->nextlink); - return tdo->nextlink; -} - -static PyObject * -teedataobject_getitem(teedataobject *tdo, int i) -{ - PyObject *value; - - assert(i < LINKCELLS); - if (i < tdo->numread) - value = tdo->values[i]; - else { - /* this is the lead iterator, so fetch more data */ - assert(i == tdo->numread); + tdo->numread = 0; + tdo->nextlink = NULL; + Py_INCREF(it); + tdo->it = it; + PyObject_GC_Track(tdo); + return (PyObject *)tdo; +} + +static PyObject * +teedataobject_jumplink(teedataobject *tdo) +{ + if (tdo->nextlink == NULL) + tdo->nextlink = teedataobject_newinternal(tdo->it); + Py_XINCREF(tdo->nextlink); + return tdo->nextlink; +} + +static PyObject * +teedataobject_getitem(teedataobject *tdo, int i) +{ + PyObject *value; + + assert(i < LINKCELLS); + if (i < tdo->numread) + value = tdo->values[i]; + else { + /* this is the lead iterator, so fetch more data */ + assert(i == tdo->numread); if (tdo->running) { PyErr_SetString(PyExc_RuntimeError, "cannot re-enter the tee iterator"); return NULL; } tdo->running = 1; - value = PyIter_Next(tdo->it); + value = PyIter_Next(tdo->it); tdo->running = 0; - if (value == NULL) - return NULL; - tdo->numread++; - tdo->values[i] = value; - } - Py_INCREF(value); - return value; -} - -static int -teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg) -{ - int i; - - Py_VISIT(tdo->it); - for (i = 0; i < tdo->numread; i++) - Py_VISIT(tdo->values[i]); - Py_VISIT(tdo->nextlink); - return 0; -} - -static void -teedataobject_safe_decref(PyObject *obj) -{ + if (value == NULL) + return NULL; + tdo->numread++; + tdo->values[i] = value; + } + Py_INCREF(value); + return value; +} + +static int +teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg) +{ + int i; + + Py_VISIT(tdo->it); + for (i = 0; i < tdo->numread; i++) + Py_VISIT(tdo->values[i]); + Py_VISIT(tdo->nextlink); + return 0; +} + +static void +teedataobject_safe_decref(PyObject *obj) +{ while (obj && Py_IS_TYPE(obj, &teedataobject_type) && - Py_REFCNT(obj) == 1) { - PyObject *nextlink = ((teedataobject *)obj)->nextlink; - ((teedataobject *)obj)->nextlink = NULL; - Py_DECREF(obj); - obj = nextlink; - } - Py_XDECREF(obj); -} - -static int -teedataobject_clear(teedataobject *tdo) -{ - int i; - PyObject *tmp; - - Py_CLEAR(tdo->it); - for (i=0 ; inumread ; i++) - Py_CLEAR(tdo->values[i]); - tmp = tdo->nextlink; - tdo->nextlink = NULL; - teedataobject_safe_decref(tmp); - return 0; -} - -static void -teedataobject_dealloc(teedataobject *tdo) -{ - PyObject_GC_UnTrack(tdo); - teedataobject_clear(tdo); - PyObject_GC_Del(tdo); -} - -static PyObject * + Py_REFCNT(obj) == 1) { + PyObject *nextlink = ((teedataobject *)obj)->nextlink; + ((teedataobject *)obj)->nextlink = NULL; + Py_DECREF(obj); + obj = nextlink; + } + Py_XDECREF(obj); +} + +static int +teedataobject_clear(teedataobject *tdo) +{ + int i; + PyObject *tmp; + + Py_CLEAR(tdo->it); + for (i=0 ; inumread ; i++) + Py_CLEAR(tdo->values[i]); + tmp = tdo->nextlink; + tdo->nextlink = NULL; + teedataobject_safe_decref(tmp); + return 0; +} + +static void +teedataobject_dealloc(teedataobject *tdo) +{ + PyObject_GC_UnTrack(tdo); + teedataobject_clear(tdo); + PyObject_GC_Del(tdo); +} + +static PyObject * teedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored)) -{ - int i; - /* create a temporary list of already iterated values */ - PyObject *values = PyList_New(tdo->numread); - - if (!values) - return NULL; - for (i=0 ; inumread ; i++) { - Py_INCREF(tdo->values[i]); - PyList_SET_ITEM(values, i, tdo->values[i]); - } - return Py_BuildValue("O(ONO)", Py_TYPE(tdo), tdo->it, - values, - tdo->nextlink ? tdo->nextlink : Py_None); -} - +{ + int i; + /* create a temporary list of already iterated values */ + PyObject *values = PyList_New(tdo->numread); + + if (!values) + return NULL; + for (i=0 ; inumread ; i++) { + Py_INCREF(tdo->values[i]); + PyList_SET_ITEM(values, i, tdo->values[i]); + } + return Py_BuildValue("O(ONO)", Py_TYPE(tdo), tdo->it, + values, + tdo->nextlink ? tdo->nextlink : Py_None); +} + /*[clinic input] @classmethod itertools.teedataobject.__new__ @@ -586,178 +586,178 @@ itertools.teedataobject.__new__ / Data container common to multiple tee objects. [clinic start generated code]*/ - -static PyObject * + +static PyObject * itertools_teedataobject_impl(PyTypeObject *type, PyObject *it, PyObject *values, PyObject *next) /*[clinic end generated code: output=3343ceb07e08df5e input=be60f2fabd2b72ba]*/ -{ - teedataobject *tdo; - Py_ssize_t i, len; - - assert(type == &teedataobject_type); - - tdo = (teedataobject *)teedataobject_newinternal(it); - if (!tdo) - return NULL; - - len = PyList_GET_SIZE(values); - if (len > LINKCELLS) - goto err; - for (i=0; ivalues[i] = PyList_GET_ITEM(values, i); - Py_INCREF(tdo->values[i]); - } - /* len <= LINKCELLS < INT_MAX */ - tdo->numread = Py_SAFE_DOWNCAST(len, Py_ssize_t, int); - - if (len == LINKCELLS) { - if (next != Py_None) { +{ + teedataobject *tdo; + Py_ssize_t i, len; + + assert(type == &teedataobject_type); + + tdo = (teedataobject *)teedataobject_newinternal(it); + if (!tdo) + return NULL; + + len = PyList_GET_SIZE(values); + if (len > LINKCELLS) + goto err; + for (i=0; ivalues[i] = PyList_GET_ITEM(values, i); + Py_INCREF(tdo->values[i]); + } + /* len <= LINKCELLS < INT_MAX */ + tdo->numread = Py_SAFE_DOWNCAST(len, Py_ssize_t, int); + + if (len == LINKCELLS) { + if (next != Py_None) { if (!Py_IS_TYPE(next, &teedataobject_type)) - goto err; - assert(tdo->nextlink == NULL); - Py_INCREF(next); - tdo->nextlink = next; - } - } else { - if (next != Py_None) - goto err; /* shouldn't have a next if we are not full */ - } - return (PyObject*)tdo; - -err: - Py_XDECREF(tdo); - PyErr_SetString(PyExc_ValueError, "Invalid arguments"); - return NULL; -} - -static PyMethodDef teedataobject_methods[] = { - {"__reduce__", (PyCFunction)teedataobject_reduce, METH_NOARGS, - reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject teedataobject_type = { - PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ - "itertools._tee_dataobject", /* tp_name */ - sizeof(teedataobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)teedataobject_dealloc, /* tp_dealloc */ + goto err; + assert(tdo->nextlink == NULL); + Py_INCREF(next); + tdo->nextlink = next; + } + } else { + if (next != Py_None) + goto err; /* shouldn't have a next if we are not full */ + } + return (PyObject*)tdo; + +err: + Py_XDECREF(tdo); + PyErr_SetString(PyExc_ValueError, "Invalid arguments"); + return NULL; +} + +static PyMethodDef teedataobject_methods[] = { + {"__reduce__", (PyCFunction)teedataobject_reduce, METH_NOARGS, + reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject teedataobject_type = { + PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ + "itertools._tee_dataobject", /* tp_name */ + sizeof(teedataobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)teedataobject_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ itertools_teedataobject__doc__, /* tp_doc */ - (traverseproc)teedataobject_traverse, /* tp_traverse */ - (inquiry)teedataobject_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - teedataobject_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)teedataobject_traverse, /* tp_traverse */ + (inquiry)teedataobject_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + teedataobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_teedataobject, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -static PyObject * -tee_next(teeobject *to) -{ - PyObject *value, *link; - - if (to->index >= LINKCELLS) { - link = teedataobject_jumplink(to->dataobj); - if (link == NULL) - return NULL; - Py_SETREF(to->dataobj, (teedataobject *)link); - to->index = 0; - } - value = teedataobject_getitem(to->dataobj, to->index); - if (value == NULL) - return NULL; - to->index++; - return value; -} - -static int -tee_traverse(teeobject *to, visitproc visit, void *arg) -{ - Py_VISIT((PyObject *)to->dataobj); - return 0; -} - -static PyObject * + PyObject_GC_Del, /* tp_free */ +}; + + +static PyObject * +tee_next(teeobject *to) +{ + PyObject *value, *link; + + if (to->index >= LINKCELLS) { + link = teedataobject_jumplink(to->dataobj); + if (link == NULL) + return NULL; + Py_SETREF(to->dataobj, (teedataobject *)link); + to->index = 0; + } + value = teedataobject_getitem(to->dataobj, to->index); + if (value == NULL) + return NULL; + to->index++; + return value; +} + +static int +tee_traverse(teeobject *to, visitproc visit, void *arg) +{ + Py_VISIT((PyObject *)to->dataobj); + return 0; +} + +static PyObject * tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored)) -{ - teeobject *newto; - - newto = PyObject_GC_New(teeobject, &tee_type); - if (newto == NULL) - return NULL; - Py_INCREF(to->dataobj); - newto->dataobj = to->dataobj; - newto->index = to->index; - newto->weakreflist = NULL; - PyObject_GC_Track(newto); - return (PyObject *)newto; -} - -PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator."); - -static PyObject * -tee_fromiterable(PyObject *iterable) -{ - teeobject *to; +{ + teeobject *newto; + + newto = PyObject_GC_New(teeobject, &tee_type); + if (newto == NULL) + return NULL; + Py_INCREF(to->dataobj); + newto->dataobj = to->dataobj; + newto->index = to->index; + newto->weakreflist = NULL; + PyObject_GC_Track(newto); + return (PyObject *)newto; +} + +PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator."); + +static PyObject * +tee_fromiterable(PyObject *iterable) +{ + teeobject *to; PyObject *it; - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - if (PyObject_TypeCheck(it, &tee_type)) { + + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + if (PyObject_TypeCheck(it, &tee_type)) { to = (teeobject *)tee_copy((teeobject *)it, NULL); - goto done; - } - + goto done; + } + PyObject *dataobj = teedataobject_newinternal(it); if (!dataobj) { - to = NULL; - goto done; - } + to = NULL; + goto done; + } to = PyObject_GC_New(teeobject, &tee_type); if (to == NULL) { Py_DECREF(dataobj); goto done; } to->dataobj = (teedataobject *)dataobj; - to->index = 0; - to->weakreflist = NULL; - PyObject_GC_Track(to); -done: + to->index = 0; + to->weakreflist = NULL; + PyObject_GC_Track(to); +done: Py_DECREF(it); - return (PyObject *)to; -} - + return (PyObject *)to; +} + /*[clinic input] @classmethod itertools._tee.__new__ @@ -766,108 +766,108 @@ itertools._tee.__new__ Iterator wrapped to make it copyable. [clinic start generated code]*/ -static PyObject * +static PyObject * itertools__tee_impl(PyTypeObject *type, PyObject *iterable) /*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/ -{ - return tee_fromiterable(iterable); -} - -static int -tee_clear(teeobject *to) -{ - if (to->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) to); - Py_CLEAR(to->dataobj); - return 0; -} - -static void -tee_dealloc(teeobject *to) -{ - PyObject_GC_UnTrack(to); - tee_clear(to); - PyObject_GC_Del(to); -} - -static PyObject * +{ + return tee_fromiterable(iterable); +} + +static int +tee_clear(teeobject *to) +{ + if (to->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) to); + Py_CLEAR(to->dataobj); + return 0; +} + +static void +tee_dealloc(teeobject *to) +{ + PyObject_GC_UnTrack(to); + tee_clear(to); + PyObject_GC_Del(to); +} + +static PyObject * tee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index); -} - -static PyObject * -tee_setstate(teeobject *to, PyObject *state) -{ - teedataobject *tdo; - int index; - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state is not a tuple"); - return NULL; - } - if (!PyArg_ParseTuple(state, "O!i", &teedataobject_type, &tdo, &index)) { - return NULL; - } - if (index < 0 || index > LINKCELLS) { - PyErr_SetString(PyExc_ValueError, "Index out of range"); - return NULL; - } - Py_INCREF(tdo); - Py_XSETREF(to->dataobj, tdo); - to->index = index; - Py_RETURN_NONE; -} - -static PyMethodDef tee_methods[] = { - {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc}, - {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject tee_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools._tee", /* tp_name */ - sizeof(teeobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)tee_dealloc, /* tp_dealloc */ +{ + return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index); +} + +static PyObject * +tee_setstate(teeobject *to, PyObject *state) +{ + teedataobject *tdo; + int index; + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state is not a tuple"); + return NULL; + } + if (!PyArg_ParseTuple(state, "O!i", &teedataobject_type, &tdo, &index)) { + return NULL; + } + if (index < 0 || index > LINKCELLS) { + PyErr_SetString(PyExc_ValueError, "Index out of range"); + return NULL; + } + Py_INCREF(tdo); + Py_XSETREF(to->dataobj, tdo); + to->index = index; + Py_RETURN_NONE; +} + +static PyMethodDef tee_methods[] = { + {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc}, + {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject tee_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools._tee", /* tp_name */ + sizeof(teeobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)tee_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ itertools__tee__doc__, /* tp_doc */ - (traverseproc)tee_traverse, /* tp_traverse */ - (inquiry)tee_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)tee_next, /* tp_iternext */ - tee_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)tee_traverse, /* tp_traverse */ + (inquiry)tee_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)tee_next, /* tp_iternext */ + tee_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools__tee, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - + PyObject_GC_Del, /* tp_free */ +}; + /*[clinic input] itertools.tee iterable: object @@ -876,77 +876,77 @@ itertools.tee Returns a tuple of n independent iterators. [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n) /*[clinic end generated code: output=1c64519cd859c2f0 input=c99a1472c425d66d]*/ -{ +{ Py_ssize_t i; PyObject *it, *copyable, *copyfunc, *result; - _Py_IDENTIFIER(__copy__); - - if (n < 0) { - PyErr_SetString(PyExc_ValueError, "n must be >= 0"); - return NULL; - } - result = PyTuple_New(n); - if (result == NULL) - return NULL; - if (n == 0) - return result; - it = PyObject_GetIter(iterable); - if (it == NULL) { - Py_DECREF(result); - return NULL; - } - - if (_PyObject_LookupAttrId(it, &PyId___copy__, ©func) < 0) { - Py_DECREF(it); - Py_DECREF(result); - return NULL; - } - if (copyfunc != NULL) { - copyable = it; - } - else { - copyable = tee_fromiterable(it); - Py_DECREF(it); - if (copyable == NULL) { - Py_DECREF(result); - return NULL; - } - copyfunc = _PyObject_GetAttrId(copyable, &PyId___copy__); - if (copyfunc == NULL) { - Py_DECREF(copyable); - Py_DECREF(result); - return NULL; - } - } - - PyTuple_SET_ITEM(result, 0, copyable); - for (i = 1; i < n; i++) { - copyable = _PyObject_CallNoArg(copyfunc); - if (copyable == NULL) { - Py_DECREF(copyfunc); - Py_DECREF(result); - return NULL; - } - PyTuple_SET_ITEM(result, i, copyable); - } - Py_DECREF(copyfunc); - return result; -} - - -/* cycle object **************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *it; - PyObject *saved; - Py_ssize_t index; - int firstpass; -} cycleobject; - + _Py_IDENTIFIER(__copy__); + + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "n must be >= 0"); + return NULL; + } + result = PyTuple_New(n); + if (result == NULL) + return NULL; + if (n == 0) + return result; + it = PyObject_GetIter(iterable); + if (it == NULL) { + Py_DECREF(result); + return NULL; + } + + if (_PyObject_LookupAttrId(it, &PyId___copy__, ©func) < 0) { + Py_DECREF(it); + Py_DECREF(result); + return NULL; + } + if (copyfunc != NULL) { + copyable = it; + } + else { + copyable = tee_fromiterable(it); + Py_DECREF(it); + if (copyable == NULL) { + Py_DECREF(result); + return NULL; + } + copyfunc = _PyObject_GetAttrId(copyable, &PyId___copy__); + if (copyfunc == NULL) { + Py_DECREF(copyable); + Py_DECREF(result); + return NULL; + } + } + + PyTuple_SET_ITEM(result, 0, copyable); + for (i = 1; i < n; i++) { + copyable = _PyObject_CallNoArg(copyfunc); + if (copyable == NULL) { + Py_DECREF(copyfunc); + Py_DECREF(result); + return NULL; + } + PyTuple_SET_ITEM(result, i, copyable); + } + Py_DECREF(copyfunc); + return result; +} + + +/* cycle object **************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *it; + PyObject *saved; + Py_ssize_t index; + int firstpass; +} cycleobject; + /*[clinic input] @classmethod itertools.cycle.__new__ @@ -955,359 +955,359 @@ itertools.cycle.__new__ Return elements from the iterable until it is exhausted. Then repeat the sequence indefinitely. [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_cycle_impl(PyTypeObject *type, PyObject *iterable) /*[clinic end generated code: output=f60e5ec17a45b35c input=9d1d84bcf66e908b]*/ -{ - PyObject *it; - PyObject *saved; - cycleobject *lz; - - /* Get iterator. */ - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - saved = PyList_New(0); - if (saved == NULL) { - Py_DECREF(it); - return NULL; - } - - /* create cycleobject structure */ - lz = (cycleobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(it); - Py_DECREF(saved); - return NULL; - } - lz->it = it; - lz->saved = saved; - lz->index = 0; - lz->firstpass = 0; - - return (PyObject *)lz; -} +{ + PyObject *it; + PyObject *saved; + cycleobject *lz; + + /* Get iterator. */ + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + + saved = PyList_New(0); + if (saved == NULL) { + Py_DECREF(it); + return NULL; + } + + /* create cycleobject structure */ + lz = (cycleobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + Py_DECREF(saved); + return NULL; + } + lz->it = it; + lz->saved = saved; + lz->index = 0; + lz->firstpass = 0; + + return (PyObject *)lz; +} + +static void +cycle_dealloc(cycleobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->it); + Py_XDECREF(lz->saved); + Py_TYPE(lz)->tp_free(lz); +} + +static int +cycle_traverse(cycleobject *lz, visitproc visit, void *arg) +{ + if (lz->it) + Py_VISIT(lz->it); + Py_VISIT(lz->saved); + return 0; +} + +static PyObject * +cycle_next(cycleobject *lz) +{ + PyObject *item; + + if (lz->it != NULL) { + item = PyIter_Next(lz->it); + if (item != NULL) { + if (lz->firstpass) + return item; + if (PyList_Append(lz->saved, item)) { + Py_DECREF(item); + return NULL; + } + return item; + } + /* Note: StopIteration is already cleared by PyIter_Next() */ + if (PyErr_Occurred()) + return NULL; + Py_CLEAR(lz->it); + } + if (PyList_GET_SIZE(lz->saved) == 0) + return NULL; + item = PyList_GET_ITEM(lz->saved, lz->index); + lz->index++; + if (lz->index >= PyList_GET_SIZE(lz->saved)) + lz->index = 0; + Py_INCREF(item); + return item; +} + +static PyObject * +cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored)) +{ + /* Create a new cycle with the iterator tuple, then set the saved state */ + if (lz->it == NULL) { + PyObject *it = PyObject_GetIter(lz->saved); + if (it == NULL) + return NULL; + if (lz->index != 0) { + _Py_IDENTIFIER(__setstate__); + PyObject *res = _PyObject_CallMethodId(it, &PyId___setstate__, + "n", lz->index); + if (res == NULL) { + Py_DECREF(it); + return NULL; + } + Py_DECREF(res); + } + return Py_BuildValue("O(N)(OO)", Py_TYPE(lz), it, lz->saved, Py_True); + } + return Py_BuildValue("O(O)(OO)", Py_TYPE(lz), lz->it, lz->saved, + lz->firstpass ? Py_True : Py_False); +} + +static PyObject * +cycle_setstate(cycleobject *lz, PyObject *state) +{ + PyObject *saved=NULL; + int firstpass; + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state is not a tuple"); + return NULL; + } + if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) { + return NULL; + } + Py_INCREF(saved); + Py_XSETREF(lz->saved, saved); + lz->firstpass = firstpass != 0; + lz->index = 0; + Py_RETURN_NONE; +} + +static PyMethodDef cycle_methods[] = { + {"__reduce__", (PyCFunction)cycle_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)cycle_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject cycle_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.cycle", /* tp_name */ + sizeof(cycleobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)cycle_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + itertools_cycle__doc__, /* tp_doc */ + (traverseproc)cycle_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)cycle_next, /* tp_iternext */ + cycle_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + itertools_cycle, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* dropwhile object **********************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; + long start; +} dropwhileobject; + +/*[clinic input] +@classmethod +itertools.dropwhile.__new__ + predicate as func: object + iterable as seq: object + / +Drop items from the iterable while predicate(item) is true. -static void -cycle_dealloc(cycleobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->it); - Py_XDECREF(lz->saved); - Py_TYPE(lz)->tp_free(lz); -} +Afterwards, return every element until the iterable is exhausted. +[clinic start generated code]*/ -static int -cycle_traverse(cycleobject *lz, visitproc visit, void *arg) -{ - if (lz->it) - Py_VISIT(lz->it); - Py_VISIT(lz->saved); - return 0; -} - -static PyObject * -cycle_next(cycleobject *lz) -{ - PyObject *item; - - if (lz->it != NULL) { - item = PyIter_Next(lz->it); - if (item != NULL) { - if (lz->firstpass) - return item; - if (PyList_Append(lz->saved, item)) { - Py_DECREF(item); - return NULL; - } - return item; - } - /* Note: StopIteration is already cleared by PyIter_Next() */ - if (PyErr_Occurred()) - return NULL; - Py_CLEAR(lz->it); - } - if (PyList_GET_SIZE(lz->saved) == 0) - return NULL; - item = PyList_GET_ITEM(lz->saved, lz->index); - lz->index++; - if (lz->index >= PyList_GET_SIZE(lz->saved)) - lz->index = 0; - Py_INCREF(item); - return item; -} - -static PyObject * -cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored)) -{ - /* Create a new cycle with the iterator tuple, then set the saved state */ - if (lz->it == NULL) { - PyObject *it = PyObject_GetIter(lz->saved); - if (it == NULL) - return NULL; - if (lz->index != 0) { - _Py_IDENTIFIER(__setstate__); - PyObject *res = _PyObject_CallMethodId(it, &PyId___setstate__, - "n", lz->index); - if (res == NULL) { - Py_DECREF(it); - return NULL; - } - Py_DECREF(res); - } - return Py_BuildValue("O(N)(OO)", Py_TYPE(lz), it, lz->saved, Py_True); - } - return Py_BuildValue("O(O)(OO)", Py_TYPE(lz), lz->it, lz->saved, - lz->firstpass ? Py_True : Py_False); -} - -static PyObject * -cycle_setstate(cycleobject *lz, PyObject *state) -{ - PyObject *saved=NULL; - int firstpass; - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state is not a tuple"); - return NULL; - } - if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) { - return NULL; - } - Py_INCREF(saved); - Py_XSETREF(lz->saved, saved); - lz->firstpass = firstpass != 0; - lz->index = 0; - Py_RETURN_NONE; -} - -static PyMethodDef cycle_methods[] = { - {"__reduce__", (PyCFunction)cycle_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)cycle_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject cycle_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.cycle", /* tp_name */ - sizeof(cycleobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)cycle_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_cycle__doc__, /* tp_doc */ - (traverseproc)cycle_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)cycle_next, /* tp_iternext */ - cycle_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_cycle, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* dropwhile object **********************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *func; - PyObject *it; - long start; -} dropwhileobject; - -/*[clinic input] -@classmethod -itertools.dropwhile.__new__ - predicate as func: object - iterable as seq: object - / -Drop items from the iterable while predicate(item) is true. - -Afterwards, return every element until the iterable is exhausted. -[clinic start generated code]*/ - -static PyObject * +static PyObject * itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) /*[clinic end generated code: output=92f9d0d89af149e4 input=d39737147c9f0a26]*/ -{ - PyObject *it; - dropwhileobject *lz; - - /* Get iterator. */ - it = PyObject_GetIter(seq); - if (it == NULL) - return NULL; - - /* create dropwhileobject structure */ - lz = (dropwhileobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(it); - return NULL; - } - Py_INCREF(func); - lz->func = func; - lz->it = it; - lz->start = 0; - - return (PyObject *)lz; -} - -static void -dropwhile_dealloc(dropwhileobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->func); - Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); -} - -static int -dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->it); - Py_VISIT(lz->func); - return 0; -} - -static PyObject * -dropwhile_next(dropwhileobject *lz) -{ - PyObject *item, *good; - PyObject *it = lz->it; - long ok; - PyObject *(*iternext)(PyObject *); - - iternext = *Py_TYPE(it)->tp_iternext; - for (;;) { - item = iternext(it); - if (item == NULL) - return NULL; - if (lz->start == 1) - return item; - +{ + PyObject *it; + dropwhileobject *lz; + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create dropwhileobject structure */ + lz = (dropwhileobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + Py_INCREF(func); + lz->func = func; + lz->it = it; + lz->start = 0; + + return (PyObject *)lz; +} + +static void +dropwhile_dealloc(dropwhileobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->func); + Py_XDECREF(lz->it); + Py_TYPE(lz)->tp_free(lz); +} + +static int +dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->it); + Py_VISIT(lz->func); + return 0; +} + +static PyObject * +dropwhile_next(dropwhileobject *lz) +{ + PyObject *item, *good; + PyObject *it = lz->it; + long ok; + PyObject *(*iternext)(PyObject *); + + iternext = *Py_TYPE(it)->tp_iternext; + for (;;) { + item = iternext(it); + if (item == NULL) + return NULL; + if (lz->start == 1) + return item; + good = PyObject_CallOneArg(lz->func, item); - if (good == NULL) { - Py_DECREF(item); - return NULL; - } - ok = PyObject_IsTrue(good); - Py_DECREF(good); - if (ok == 0) { - lz->start = 1; - return item; - } - Py_DECREF(item); - if (ok < 0) - return NULL; - } -} - -static PyObject * + if (good == NULL) { + Py_DECREF(item); + return NULL; + } + ok = PyObject_IsTrue(good); + Py_DECREF(good); + if (ok == 0) { + lz->start = 1; + return item; + } + Py_DECREF(item); + if (ok < 0) + return NULL; + } +} + +static PyObject * dropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); -} - -static PyObject * -dropwhile_setstate(dropwhileobject *lz, PyObject *state) -{ - int start = PyObject_IsTrue(state); - if (start < 0) - return NULL; - lz->start = start; - Py_RETURN_NONE; -} - -static PyMethodDef dropwhile_methods[] = { - {"__reduce__", (PyCFunction)dropwhile_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)dropwhile_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject dropwhile_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.dropwhile", /* tp_name */ - sizeof(dropwhileobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)dropwhile_dealloc, /* tp_dealloc */ +{ + return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); +} + +static PyObject * +dropwhile_setstate(dropwhileobject *lz, PyObject *state) +{ + int start = PyObject_IsTrue(state); + if (start < 0) + return NULL; + lz->start = start; + Py_RETURN_NONE; +} + +static PyMethodDef dropwhile_methods[] = { + {"__reduce__", (PyCFunction)dropwhile_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)dropwhile_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject dropwhile_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.dropwhile", /* tp_name */ + sizeof(dropwhileobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)dropwhile_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_dropwhile__doc__, /* tp_doc */ - (traverseproc)dropwhile_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)dropwhile_next, /* tp_iternext */ - dropwhile_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)dropwhile_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)dropwhile_next, /* tp_iternext */ + dropwhile_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_dropwhile, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* takewhile object **********************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *func; - PyObject *it; - long stop; -} takewhileobject; - + PyObject_GC_Del, /* tp_free */ +}; + + +/* takewhile object **********************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; + long stop; +} takewhileobject; + /*[clinic input] @classmethod itertools.takewhile.__new__ @@ -1317,415 +1317,415 @@ itertools.takewhile.__new__ Return successive entries from an iterable as long as the predicate evaluates to true for each entry. [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) /*[clinic end generated code: output=bb179ea7864e2ef6 input=ba5255f7519aa119]*/ -{ - PyObject *it; - takewhileobject *lz; - - /* Get iterator. */ - it = PyObject_GetIter(seq); - if (it == NULL) - return NULL; - - /* create takewhileobject structure */ - lz = (takewhileobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(it); - return NULL; - } - Py_INCREF(func); - lz->func = func; - lz->it = it; - lz->stop = 0; - - return (PyObject *)lz; -} - -static void -takewhile_dealloc(takewhileobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->func); - Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); -} - -static int -takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->it); - Py_VISIT(lz->func); - return 0; -} - -static PyObject * -takewhile_next(takewhileobject *lz) -{ - PyObject *item, *good; - PyObject *it = lz->it; - long ok; - - if (lz->stop == 1) - return NULL; - - item = (*Py_TYPE(it)->tp_iternext)(it); - if (item == NULL) - return NULL; - +{ + PyObject *it; + takewhileobject *lz; + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create takewhileobject structure */ + lz = (takewhileobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + Py_INCREF(func); + lz->func = func; + lz->it = it; + lz->stop = 0; + + return (PyObject *)lz; +} + +static void +takewhile_dealloc(takewhileobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->func); + Py_XDECREF(lz->it); + Py_TYPE(lz)->tp_free(lz); +} + +static int +takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->it); + Py_VISIT(lz->func); + return 0; +} + +static PyObject * +takewhile_next(takewhileobject *lz) +{ + PyObject *item, *good; + PyObject *it = lz->it; + long ok; + + if (lz->stop == 1) + return NULL; + + item = (*Py_TYPE(it)->tp_iternext)(it); + if (item == NULL) + return NULL; + good = PyObject_CallOneArg(lz->func, item); - if (good == NULL) { - Py_DECREF(item); - return NULL; - } - ok = PyObject_IsTrue(good); - Py_DECREF(good); - if (ok > 0) - return item; - Py_DECREF(item); - if (ok == 0) - lz->stop = 1; - return NULL; -} - -static PyObject * + if (good == NULL) { + Py_DECREF(item); + return NULL; + } + ok = PyObject_IsTrue(good); + Py_DECREF(good); + if (ok > 0) + return item; + Py_DECREF(item); + if (ok == 0) + lz->stop = 1; + return NULL; +} + +static PyObject * takewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop); -} - -static PyObject * -takewhile_reduce_setstate(takewhileobject *lz, PyObject *state) -{ - int stop = PyObject_IsTrue(state); - - if (stop < 0) - return NULL; - lz->stop = stop; - Py_RETURN_NONE; -} - -static PyMethodDef takewhile_reduce_methods[] = { - {"__reduce__", (PyCFunction)takewhile_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)takewhile_reduce_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject takewhile_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.takewhile", /* tp_name */ - sizeof(takewhileobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)takewhile_dealloc, /* tp_dealloc */ +{ + return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop); +} + +static PyObject * +takewhile_reduce_setstate(takewhileobject *lz, PyObject *state) +{ + int stop = PyObject_IsTrue(state); + + if (stop < 0) + return NULL; + lz->stop = stop; + Py_RETURN_NONE; +} + +static PyMethodDef takewhile_reduce_methods[] = { + {"__reduce__", (PyCFunction)takewhile_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)takewhile_reduce_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject takewhile_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.takewhile", /* tp_name */ + sizeof(takewhileobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)takewhile_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_takewhile__doc__, /* tp_doc */ - (traverseproc)takewhile_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)takewhile_next, /* tp_iternext */ - takewhile_reduce_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)takewhile_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)takewhile_next, /* tp_iternext */ + takewhile_reduce_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_takewhile, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* islice object *************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *it; - Py_ssize_t next; - Py_ssize_t stop; - Py_ssize_t step; - Py_ssize_t cnt; -} isliceobject; - -static PyTypeObject islice_type; - -static PyObject * -islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *seq; - Py_ssize_t start=0, stop=-1, step=1; - PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL; - Py_ssize_t numargs; - isliceobject *lz; - - if (type == &islice_type && !_PyArg_NoKeywords("islice", kwds)) - return NULL; - - if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3)) - return NULL; - - numargs = PyTuple_Size(args); - if (numargs == 2) { - if (a1 != Py_None) { - stop = PyNumber_AsSsize_t(a1, PyExc_OverflowError); - if (stop == -1) { - if (PyErr_Occurred()) - PyErr_Clear(); - PyErr_SetString(PyExc_ValueError, - "Stop argument for islice() must be None or " - "an integer: 0 <= x <= sys.maxsize."); - return NULL; - } - } - } else { - if (a1 != Py_None) - start = PyNumber_AsSsize_t(a1, PyExc_OverflowError); - if (start == -1 && PyErr_Occurred()) - PyErr_Clear(); - if (a2 != Py_None) { - stop = PyNumber_AsSsize_t(a2, PyExc_OverflowError); - if (stop == -1) { - if (PyErr_Occurred()) - PyErr_Clear(); - PyErr_SetString(PyExc_ValueError, - "Stop argument for islice() must be None or " - "an integer: 0 <= x <= sys.maxsize."); - return NULL; - } - } - } - if (start<0 || stop<-1) { - PyErr_SetString(PyExc_ValueError, - "Indices for islice() must be None or " - "an integer: 0 <= x <= sys.maxsize."); - return NULL; - } - - if (a3 != NULL) { - if (a3 != Py_None) - step = PyNumber_AsSsize_t(a3, PyExc_OverflowError); - if (step == -1 && PyErr_Occurred()) - PyErr_Clear(); - } - if (step<1) { - PyErr_SetString(PyExc_ValueError, - "Step for islice() must be a positive integer or None."); - return NULL; - } - - /* Get iterator. */ - it = PyObject_GetIter(seq); - if (it == NULL) - return NULL; - - /* create isliceobject structure */ - lz = (isliceobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(it); - return NULL; - } - lz->it = it; - lz->next = start; - lz->stop = stop; - lz->step = step; - lz->cnt = 0L; - - return (PyObject *)lz; -} - -static void -islice_dealloc(isliceobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); -} - -static int -islice_traverse(isliceobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->it); - return 0; -} - -static PyObject * -islice_next(isliceobject *lz) -{ - PyObject *item; - PyObject *it = lz->it; - Py_ssize_t stop = lz->stop; - Py_ssize_t oldnext; - PyObject *(*iternext)(PyObject *); - - if (it == NULL) - return NULL; - - iternext = *Py_TYPE(it)->tp_iternext; - while (lz->cnt < lz->next) { - item = iternext(it); - if (item == NULL) - goto empty; - Py_DECREF(item); - lz->cnt++; - } - if (stop != -1 && lz->cnt >= stop) - goto empty; - item = iternext(it); - if (item == NULL) - goto empty; - lz->cnt++; - oldnext = lz->next; - /* The (size_t) cast below avoids the danger of undefined - behaviour from signed integer overflow. */ - lz->next += (size_t)lz->step; - if (lz->next < oldnext || (stop != -1 && lz->next > stop)) - lz->next = stop; - return item; - -empty: - Py_CLEAR(lz->it); - return NULL; -} - -static PyObject * + PyObject_GC_Del, /* tp_free */ +}; + + +/* islice object *************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *it; + Py_ssize_t next; + Py_ssize_t stop; + Py_ssize_t step; + Py_ssize_t cnt; +} isliceobject; + +static PyTypeObject islice_type; + +static PyObject * +islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *seq; + Py_ssize_t start=0, stop=-1, step=1; + PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL; + Py_ssize_t numargs; + isliceobject *lz; + + if (type == &islice_type && !_PyArg_NoKeywords("islice", kwds)) + return NULL; + + if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3)) + return NULL; + + numargs = PyTuple_Size(args); + if (numargs == 2) { + if (a1 != Py_None) { + stop = PyNumber_AsSsize_t(a1, PyExc_OverflowError); + if (stop == -1) { + if (PyErr_Occurred()) + PyErr_Clear(); + PyErr_SetString(PyExc_ValueError, + "Stop argument for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); + return NULL; + } + } + } else { + if (a1 != Py_None) + start = PyNumber_AsSsize_t(a1, PyExc_OverflowError); + if (start == -1 && PyErr_Occurred()) + PyErr_Clear(); + if (a2 != Py_None) { + stop = PyNumber_AsSsize_t(a2, PyExc_OverflowError); + if (stop == -1) { + if (PyErr_Occurred()) + PyErr_Clear(); + PyErr_SetString(PyExc_ValueError, + "Stop argument for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); + return NULL; + } + } + } + if (start<0 || stop<-1) { + PyErr_SetString(PyExc_ValueError, + "Indices for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); + return NULL; + } + + if (a3 != NULL) { + if (a3 != Py_None) + step = PyNumber_AsSsize_t(a3, PyExc_OverflowError); + if (step == -1 && PyErr_Occurred()) + PyErr_Clear(); + } + if (step<1) { + PyErr_SetString(PyExc_ValueError, + "Step for islice() must be a positive integer or None."); + return NULL; + } + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create isliceobject structure */ + lz = (isliceobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + lz->it = it; + lz->next = start; + lz->stop = stop; + lz->step = step; + lz->cnt = 0L; + + return (PyObject *)lz; +} + +static void +islice_dealloc(isliceobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->it); + Py_TYPE(lz)->tp_free(lz); +} + +static int +islice_traverse(isliceobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->it); + return 0; +} + +static PyObject * +islice_next(isliceobject *lz) +{ + PyObject *item; + PyObject *it = lz->it; + Py_ssize_t stop = lz->stop; + Py_ssize_t oldnext; + PyObject *(*iternext)(PyObject *); + + if (it == NULL) + return NULL; + + iternext = *Py_TYPE(it)->tp_iternext; + while (lz->cnt < lz->next) { + item = iternext(it); + if (item == NULL) + goto empty; + Py_DECREF(item); + lz->cnt++; + } + if (stop != -1 && lz->cnt >= stop) + goto empty; + item = iternext(it); + if (item == NULL) + goto empty; + lz->cnt++; + oldnext = lz->next; + /* The (size_t) cast below avoids the danger of undefined + behaviour from signed integer overflow. */ + lz->next += (size_t)lz->step; + if (lz->next < oldnext || (stop != -1 && lz->next > stop)) + lz->next = stop; + return item; + +empty: + Py_CLEAR(lz->it); + return NULL; +} + +static PyObject * islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored)) -{ - /* When unpickled, generate a new object with the same bounds, - * then 'setstate' with the next and count - */ - PyObject *stop; - - if (lz->it == NULL) { - PyObject *empty_list; - PyObject *empty_it; - empty_list = PyList_New(0); - if (empty_list == NULL) - return NULL; - empty_it = PyObject_GetIter(empty_list); - Py_DECREF(empty_list); - if (empty_it == NULL) - return NULL; - return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0); - } - if (lz->stop == -1) { - stop = Py_None; - Py_INCREF(stop); - } else { - stop = PyLong_FromSsize_t(lz->stop); - if (stop == NULL) - return NULL; - } - return Py_BuildValue("O(OnNn)n", Py_TYPE(lz), - lz->it, lz->next, stop, lz->step, - lz->cnt); -} - -static PyObject * -islice_setstate(isliceobject *lz, PyObject *state) -{ - Py_ssize_t cnt = PyLong_AsSsize_t(state); - - if (cnt == -1 && PyErr_Occurred()) - return NULL; - lz->cnt = cnt; - Py_RETURN_NONE; -} - -static PyMethodDef islice_methods[] = { - {"__reduce__", (PyCFunction)islice_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)islice_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(islice_doc, -"islice(iterable, stop) --> islice object\n\ -islice(iterable, start, stop[, step]) --> islice object\n\ -\n\ -Return an iterator whose next() method returns selected values from an\n\ -iterable. If start is specified, will skip all preceding elements;\n\ -otherwise, start defaults to zero. Step defaults to one. If\n\ +{ + /* When unpickled, generate a new object with the same bounds, + * then 'setstate' with the next and count + */ + PyObject *stop; + + if (lz->it == NULL) { + PyObject *empty_list; + PyObject *empty_it; + empty_list = PyList_New(0); + if (empty_list == NULL) + return NULL; + empty_it = PyObject_GetIter(empty_list); + Py_DECREF(empty_list); + if (empty_it == NULL) + return NULL; + return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0); + } + if (lz->stop == -1) { + stop = Py_None; + Py_INCREF(stop); + } else { + stop = PyLong_FromSsize_t(lz->stop); + if (stop == NULL) + return NULL; + } + return Py_BuildValue("O(OnNn)n", Py_TYPE(lz), + lz->it, lz->next, stop, lz->step, + lz->cnt); +} + +static PyObject * +islice_setstate(isliceobject *lz, PyObject *state) +{ + Py_ssize_t cnt = PyLong_AsSsize_t(state); + + if (cnt == -1 && PyErr_Occurred()) + return NULL; + lz->cnt = cnt; + Py_RETURN_NONE; +} + +static PyMethodDef islice_methods[] = { + {"__reduce__", (PyCFunction)islice_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)islice_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(islice_doc, +"islice(iterable, stop) --> islice object\n\ +islice(iterable, start, stop[, step]) --> islice object\n\ +\n\ +Return an iterator whose next() method returns selected values from an\n\ +iterable. If start is specified, will skip all preceding elements;\n\ +otherwise, start defaults to zero. Step defaults to one. If\n\ specified as another value, step determines how many values are\n\ -skipped between successive calls. Works like a slice() on a list\n\ -but returns an iterator."); - -static PyTypeObject islice_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.islice", /* tp_name */ - sizeof(isliceobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)islice_dealloc, /* tp_dealloc */ +skipped between successive calls. Works like a slice() on a list\n\ +but returns an iterator."); + +static PyTypeObject islice_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.islice", /* tp_name */ + sizeof(isliceobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)islice_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - islice_doc, /* tp_doc */ - (traverseproc)islice_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)islice_next, /* tp_iternext */ - islice_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - islice_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* starmap object ************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *func; - PyObject *it; -} starmapobject; - + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + islice_doc, /* tp_doc */ + (traverseproc)islice_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)islice_next, /* tp_iternext */ + islice_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + islice_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* starmap object ************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; +} starmapobject; + /*[clinic input] @classmethod itertools.starmap.__new__ @@ -1735,169 +1735,169 @@ itertools.starmap.__new__ Return an iterator whose values are returned from the function evaluated with an argument tuple taken from the given sequence. [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq) /*[clinic end generated code: output=79eeb81d452c6e8d input=844766df6a0d4dad]*/ -{ - PyObject *it; - starmapobject *lz; - - /* Get iterator. */ - it = PyObject_GetIter(seq); - if (it == NULL) - return NULL; - - /* create starmapobject structure */ - lz = (starmapobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(it); - return NULL; - } - Py_INCREF(func); - lz->func = func; - lz->it = it; - - return (PyObject *)lz; -} - -static void -starmap_dealloc(starmapobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->func); - Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); -} - -static int -starmap_traverse(starmapobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->it); - Py_VISIT(lz->func); - return 0; -} - -static PyObject * -starmap_next(starmapobject *lz) -{ - PyObject *args; - PyObject *result; - PyObject *it = lz->it; - - args = (*Py_TYPE(it)->tp_iternext)(it); - if (args == NULL) - return NULL; - if (!PyTuple_CheckExact(args)) { - PyObject *newargs = PySequence_Tuple(args); - Py_DECREF(args); - if (newargs == NULL) - return NULL; - args = newargs; - } - result = PyObject_Call(lz->func, args, NULL); - Py_DECREF(args); - return result; -} - -static PyObject * +{ + PyObject *it; + starmapobject *lz; + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create starmapobject structure */ + lz = (starmapobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + Py_INCREF(func); + lz->func = func; + lz->it = it; + + return (PyObject *)lz; +} + +static void +starmap_dealloc(starmapobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->func); + Py_XDECREF(lz->it); + Py_TYPE(lz)->tp_free(lz); +} + +static int +starmap_traverse(starmapobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->it); + Py_VISIT(lz->func); + return 0; +} + +static PyObject * +starmap_next(starmapobject *lz) +{ + PyObject *args; + PyObject *result; + PyObject *it = lz->it; + + args = (*Py_TYPE(it)->tp_iternext)(it); + if (args == NULL) + return NULL; + if (!PyTuple_CheckExact(args)) { + PyObject *newargs = PySequence_Tuple(args); + Py_DECREF(args); + if (newargs == NULL) + return NULL; + args = newargs; + } + result = PyObject_Call(lz->func, args, NULL); + Py_DECREF(args); + return result; +} + +static PyObject * starmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored)) -{ - /* Just pickle the iterator */ - return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); -} - -static PyMethodDef starmap_methods[] = { - {"__reduce__", (PyCFunction)starmap_reduce, METH_NOARGS, - reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject starmap_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.starmap", /* tp_name */ - sizeof(starmapobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)starmap_dealloc, /* tp_dealloc */ +{ + /* Just pickle the iterator */ + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); +} + +static PyMethodDef starmap_methods[] = { + {"__reduce__", (PyCFunction)starmap_reduce, METH_NOARGS, + reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject starmap_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.starmap", /* tp_name */ + sizeof(starmapobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)starmap_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_starmap__doc__, /* tp_doc */ - (traverseproc)starmap_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)starmap_next, /* tp_iternext */ - starmap_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)starmap_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)starmap_next, /* tp_iternext */ + starmap_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_starmap, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* chain object **************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *source; /* Iterator over input iterables */ - PyObject *active; /* Currently running input iterator */ -} chainobject; - -static PyTypeObject chain_type; - -static PyObject * -chain_new_internal(PyTypeObject *type, PyObject *source) -{ - chainobject *lz; - - lz = (chainobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(source); - return NULL; - } - - lz->source = source; - lz->active = NULL; - return (PyObject *)lz; -} - -static PyObject * -chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *source; - - if (type == &chain_type && !_PyArg_NoKeywords("chain", kwds)) - return NULL; - - source = PyObject_GetIter(args); - if (source == NULL) - return NULL; - - return chain_new_internal(type, source); -} - + PyObject_GC_Del, /* tp_free */ +}; + + +/* chain object **************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *source; /* Iterator over input iterables */ + PyObject *active; /* Currently running input iterator */ +} chainobject; + +static PyTypeObject chain_type; + +static PyObject * +chain_new_internal(PyTypeObject *type, PyObject *source) +{ + chainobject *lz; + + lz = (chainobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(source); + return NULL; + } + + lz->source = source; + lz->active = NULL; + return (PyObject *)lz; +} + +static PyObject * +chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *source; + + if (type == &chain_type && !_PyArg_NoKeywords("chain", kwds)) + return NULL; + + source = PyObject_GetIter(args); + if (source == NULL) + return NULL; + + return chain_new_internal(type, source); +} + /*[clinic input] @classmethod itertools.chain.from_iterable @@ -1906,550 +1906,550 @@ itertools.chain.from_iterable Alternative chain() constructor taking a single iterable argument that evaluates lazily. [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_chain_from_iterable(PyTypeObject *type, PyObject *arg) /*[clinic end generated code: output=667ae7a7f7b68654 input=72c39e3a2ca3be85]*/ -{ - PyObject *source; - - source = PyObject_GetIter(arg); - if (source == NULL) - return NULL; - - return chain_new_internal(type, source); -} - -static void -chain_dealloc(chainobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->active); - Py_XDECREF(lz->source); - Py_TYPE(lz)->tp_free(lz); -} - -static int -chain_traverse(chainobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->source); - Py_VISIT(lz->active); - return 0; -} - -static PyObject * -chain_next(chainobject *lz) -{ - PyObject *item; - - /* lz->source is the iterator of iterables. If it's NULL, we've already - * consumed them all. lz->active is the current iterator. If it's NULL, - * we should grab a new one from lz->source. */ - while (lz->source != NULL) { - if (lz->active == NULL) { - PyObject *iterable = PyIter_Next(lz->source); - if (iterable == NULL) { - Py_CLEAR(lz->source); - return NULL; /* no more input sources */ - } - lz->active = PyObject_GetIter(iterable); - Py_DECREF(iterable); - if (lz->active == NULL) { - Py_CLEAR(lz->source); - return NULL; /* input not iterable */ - } - } - item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active); - if (item != NULL) - return item; - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); - else - return NULL; /* input raised an exception */ - } - /* lz->active is consumed, try with the next iterable. */ - Py_CLEAR(lz->active); - } - /* Everything had been consumed already. */ - return NULL; -} - -static PyObject * +{ + PyObject *source; + + source = PyObject_GetIter(arg); + if (source == NULL) + return NULL; + + return chain_new_internal(type, source); +} + +static void +chain_dealloc(chainobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->active); + Py_XDECREF(lz->source); + Py_TYPE(lz)->tp_free(lz); +} + +static int +chain_traverse(chainobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->source); + Py_VISIT(lz->active); + return 0; +} + +static PyObject * +chain_next(chainobject *lz) +{ + PyObject *item; + + /* lz->source is the iterator of iterables. If it's NULL, we've already + * consumed them all. lz->active is the current iterator. If it's NULL, + * we should grab a new one from lz->source. */ + while (lz->source != NULL) { + if (lz->active == NULL) { + PyObject *iterable = PyIter_Next(lz->source); + if (iterable == NULL) { + Py_CLEAR(lz->source); + return NULL; /* no more input sources */ + } + lz->active = PyObject_GetIter(iterable); + Py_DECREF(iterable); + if (lz->active == NULL) { + Py_CLEAR(lz->source); + return NULL; /* input not iterable */ + } + } + item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active); + if (item != NULL) + return item; + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else + return NULL; /* input raised an exception */ + } + /* lz->active is consumed, try with the next iterable. */ + Py_CLEAR(lz->active); + } + /* Everything had been consumed already. */ + return NULL; +} + +static PyObject * chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored)) -{ - if (lz->source) { - /* we can't pickle function objects (itertools.from_iterable) so - * we must use setstate to replace the iterable. One day we - * will fix pickling of functions - */ - if (lz->active) { - return Py_BuildValue("O()(OO)", Py_TYPE(lz), lz->source, lz->active); - } else { - return Py_BuildValue("O()(O)", Py_TYPE(lz), lz->source); - } - } else { - return Py_BuildValue("O()", Py_TYPE(lz)); /* exhausted */ - } - return NULL; -} - -static PyObject * -chain_setstate(chainobject *lz, PyObject *state) -{ - PyObject *source, *active=NULL; - - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state is not a tuple"); - return NULL; - } - if (!PyArg_ParseTuple(state, "O|O", &source, &active)) { - return NULL; - } - if (!PyIter_Check(source) || (active != NULL && !PyIter_Check(active))) { - PyErr_SetString(PyExc_TypeError, "Arguments must be iterators."); - return NULL; - } - - Py_INCREF(source); - Py_XSETREF(lz->source, source); - Py_XINCREF(active); - Py_XSETREF(lz->active, active); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(chain_doc, -"chain(*iterables) --> chain object\n\ -\n\ -Return a chain object whose .__next__() method returns elements from the\n\ -first iterable until it is exhausted, then elements from the next\n\ -iterable, until all of the iterables are exhausted."); - -static PyMethodDef chain_methods[] = { +{ + if (lz->source) { + /* we can't pickle function objects (itertools.from_iterable) so + * we must use setstate to replace the iterable. One day we + * will fix pickling of functions + */ + if (lz->active) { + return Py_BuildValue("O()(OO)", Py_TYPE(lz), lz->source, lz->active); + } else { + return Py_BuildValue("O()(O)", Py_TYPE(lz), lz->source); + } + } else { + return Py_BuildValue("O()", Py_TYPE(lz)); /* exhausted */ + } + return NULL; +} + +static PyObject * +chain_setstate(chainobject *lz, PyObject *state) +{ + PyObject *source, *active=NULL; + + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state is not a tuple"); + return NULL; + } + if (!PyArg_ParseTuple(state, "O|O", &source, &active)) { + return NULL; + } + if (!PyIter_Check(source) || (active != NULL && !PyIter_Check(active))) { + PyErr_SetString(PyExc_TypeError, "Arguments must be iterators."); + return NULL; + } + + Py_INCREF(source); + Py_XSETREF(lz->source, source); + Py_XINCREF(active); + Py_XSETREF(lz->active, active); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(chain_doc, +"chain(*iterables) --> chain object\n\ +\n\ +Return a chain object whose .__next__() method returns elements from the\n\ +first iterable until it is exhausted, then elements from the next\n\ +iterable, until all of the iterables are exhausted."); + +static PyMethodDef chain_methods[] = { ITERTOOLS_CHAIN_FROM_ITERABLE_METHODDEF - {"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)chain_setstate, METH_O, - setstate_doc}, + {"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)chain_setstate, METH_O, + setstate_doc}, {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject chain_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.chain", /* tp_name */ - sizeof(chainobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)chain_dealloc, /* tp_dealloc */ + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject chain_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.chain", /* tp_name */ + sizeof(chainobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)chain_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - chain_doc, /* tp_doc */ - (traverseproc)chain_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)chain_next, /* tp_iternext */ - chain_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - chain_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* product object ************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *pools; /* tuple of pool tuples */ - Py_ssize_t *indices; /* one index per pool */ - PyObject *result; /* most recently returned result tuple */ - int stopped; /* set to 1 when the iterator is exhausted */ -} productobject; - -static PyTypeObject product_type; - -static PyObject * -product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - productobject *lz; - Py_ssize_t nargs, npools, repeat=1; - PyObject *pools = NULL; - Py_ssize_t *indices = NULL; - Py_ssize_t i; - - if (kwds != NULL) { - char *kwlist[] = {"repeat", 0}; - PyObject *tmpargs = PyTuple_New(0); - if (tmpargs == NULL) - return NULL; - if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", - kwlist, &repeat)) { - Py_DECREF(tmpargs); - return NULL; - } - Py_DECREF(tmpargs); - if (repeat < 0) { - PyErr_SetString(PyExc_ValueError, - "repeat argument cannot be negative"); - return NULL; - } - } - - assert(PyTuple_CheckExact(args)); - if (repeat == 0) { - nargs = 0; - } else { - nargs = PyTuple_GET_SIZE(args); - if ((size_t)nargs > PY_SSIZE_T_MAX/sizeof(Py_ssize_t)/repeat) { - PyErr_SetString(PyExc_OverflowError, "repeat argument too large"); - return NULL; - } - } - npools = nargs * repeat; - - indices = PyMem_New(Py_ssize_t, npools); - if (indices == NULL) { - PyErr_NoMemory(); - goto error; - } - - pools = PyTuple_New(npools); - if (pools == NULL) - goto error; - - for (i=0; i < nargs ; ++i) { - PyObject *item = PyTuple_GET_ITEM(args, i); - PyObject *pool = PySequence_Tuple(item); - if (pool == NULL) - goto error; - PyTuple_SET_ITEM(pools, i, pool); - indices[i] = 0; - } - for ( ; i < npools; ++i) { - PyObject *pool = PyTuple_GET_ITEM(pools, i - nargs); - Py_INCREF(pool); - PyTuple_SET_ITEM(pools, i, pool); - indices[i] = 0; - } - - /* create productobject structure */ - lz = (productobject *)type->tp_alloc(type, 0); - if (lz == NULL) - goto error; - - lz->pools = pools; - lz->indices = indices; - lz->result = NULL; - lz->stopped = 0; - - return (PyObject *)lz; - -error: - if (indices != NULL) - PyMem_Free(indices); - Py_XDECREF(pools); - return NULL; -} - -static void -product_dealloc(productobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->pools); - Py_XDECREF(lz->result); - if (lz->indices != NULL) - PyMem_Free(lz->indices); - Py_TYPE(lz)->tp_free(lz); -} - -static PyObject * -product_sizeof(productobject *lz, void *unused) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(lz)); - res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); -} - -PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes."); - -static int -product_traverse(productobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->pools); - Py_VISIT(lz->result); - return 0; -} - -static PyObject * -product_next(productobject *lz) -{ - PyObject *pool; - PyObject *elem; - PyObject *oldelem; - PyObject *pools = lz->pools; - PyObject *result = lz->result; - Py_ssize_t npools = PyTuple_GET_SIZE(pools); - Py_ssize_t i; - - if (lz->stopped) - return NULL; - - if (result == NULL) { - /* On the first pass, return an initial tuple filled with the - first element from each pool. */ - result = PyTuple_New(npools); - if (result == NULL) - goto empty; - lz->result = result; - for (i=0; i < npools; i++) { - pool = PyTuple_GET_ITEM(pools, i); - if (PyTuple_GET_SIZE(pool) == 0) - goto empty; - elem = PyTuple_GET_ITEM(pool, 0); - Py_INCREF(elem); - PyTuple_SET_ITEM(result, i, elem); - } - } else { - Py_ssize_t *indices = lz->indices; - - /* Copy the previous result tuple or re-use it if available */ - if (Py_REFCNT(result) > 1) { - PyObject *old_result = result; + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + chain_doc, /* tp_doc */ + (traverseproc)chain_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)chain_next, /* tp_iternext */ + chain_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + chain_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* product object ************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *pools; /* tuple of pool tuples */ + Py_ssize_t *indices; /* one index per pool */ + PyObject *result; /* most recently returned result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ +} productobject; + +static PyTypeObject product_type; + +static PyObject * +product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + productobject *lz; + Py_ssize_t nargs, npools, repeat=1; + PyObject *pools = NULL; + Py_ssize_t *indices = NULL; + Py_ssize_t i; + + if (kwds != NULL) { + char *kwlist[] = {"repeat", 0}; + PyObject *tmpargs = PyTuple_New(0); + if (tmpargs == NULL) + return NULL; + if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", + kwlist, &repeat)) { + Py_DECREF(tmpargs); + return NULL; + } + Py_DECREF(tmpargs); + if (repeat < 0) { + PyErr_SetString(PyExc_ValueError, + "repeat argument cannot be negative"); + return NULL; + } + } + + assert(PyTuple_CheckExact(args)); + if (repeat == 0) { + nargs = 0; + } else { + nargs = PyTuple_GET_SIZE(args); + if ((size_t)nargs > PY_SSIZE_T_MAX/sizeof(Py_ssize_t)/repeat) { + PyErr_SetString(PyExc_OverflowError, "repeat argument too large"); + return NULL; + } + } + npools = nargs * repeat; + + indices = PyMem_New(Py_ssize_t, npools); + if (indices == NULL) { + PyErr_NoMemory(); + goto error; + } + + pools = PyTuple_New(npools); + if (pools == NULL) + goto error; + + for (i=0; i < nargs ; ++i) { + PyObject *item = PyTuple_GET_ITEM(args, i); + PyObject *pool = PySequence_Tuple(item); + if (pool == NULL) + goto error; + PyTuple_SET_ITEM(pools, i, pool); + indices[i] = 0; + } + for ( ; i < npools; ++i) { + PyObject *pool = PyTuple_GET_ITEM(pools, i - nargs); + Py_INCREF(pool); + PyTuple_SET_ITEM(pools, i, pool); + indices[i] = 0; + } + + /* create productobject structure */ + lz = (productobject *)type->tp_alloc(type, 0); + if (lz == NULL) + goto error; + + lz->pools = pools; + lz->indices = indices; + lz->result = NULL; + lz->stopped = 0; + + return (PyObject *)lz; + +error: + if (indices != NULL) + PyMem_Free(indices); + Py_XDECREF(pools); + return NULL; +} + +static void +product_dealloc(productobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->pools); + Py_XDECREF(lz->result); + if (lz->indices != NULL) + PyMem_Free(lz->indices); + Py_TYPE(lz)->tp_free(lz); +} + +static PyObject * +product_sizeof(productobject *lz, void *unused) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(lz)); + res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + +PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes."); + +static int +product_traverse(productobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->pools); + Py_VISIT(lz->result); + return 0; +} + +static PyObject * +product_next(productobject *lz) +{ + PyObject *pool; + PyObject *elem; + PyObject *oldelem; + PyObject *pools = lz->pools; + PyObject *result = lz->result; + Py_ssize_t npools = PyTuple_GET_SIZE(pools); + Py_ssize_t i; + + if (lz->stopped) + return NULL; + + if (result == NULL) { + /* On the first pass, return an initial tuple filled with the + first element from each pool. */ + result = PyTuple_New(npools); + if (result == NULL) + goto empty; + lz->result = result; + for (i=0; i < npools; i++) { + pool = PyTuple_GET_ITEM(pools, i); + if (PyTuple_GET_SIZE(pool) == 0) + goto empty; + elem = PyTuple_GET_ITEM(pool, 0); + Py_INCREF(elem); + PyTuple_SET_ITEM(result, i, elem); + } + } else { + Py_ssize_t *indices = lz->indices; + + /* Copy the previous result tuple or re-use it if available */ + if (Py_REFCNT(result) > 1) { + PyObject *old_result = result; result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), npools); - if (result == NULL) - goto empty; - lz->result = result; - Py_DECREF(old_result); - } + if (result == NULL) + goto empty; + lz->result = result; + Py_DECREF(old_result); + } // bpo-42536: The GC may have untracked this result tuple. Since we're // recycling it, make sure it's tracked again: else if (!_PyObject_GC_IS_TRACKED(result)) { _PyObject_GC_TRACK(result); - } - /* Now, we've got the only copy so we can update it in-place */ - assert (npools==0 || Py_REFCNT(result) == 1); - - /* Update the pool indices right-to-left. Only advance to the - next pool when the previous one rolls-over */ - for (i=npools-1 ; i >= 0 ; i--) { - pool = PyTuple_GET_ITEM(pools, i); - indices[i]++; - if (indices[i] == PyTuple_GET_SIZE(pool)) { - /* Roll-over and advance to next pool */ - indices[i] = 0; - elem = PyTuple_GET_ITEM(pool, 0); - Py_INCREF(elem); - oldelem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, elem); - Py_DECREF(oldelem); - } else { - /* No rollover. Just increment and stop here. */ - elem = PyTuple_GET_ITEM(pool, indices[i]); - Py_INCREF(elem); - oldelem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, elem); - Py_DECREF(oldelem); - break; - } - } - - /* If i is negative, then the indices have all rolled-over - and we're done. */ - if (i < 0) - goto empty; - } - - Py_INCREF(result); - return result; - -empty: - lz->stopped = 1; - return NULL; -} - -static PyObject * -product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored)) -{ - if (lz->stopped) { - return Py_BuildValue("O(())", Py_TYPE(lz)); - } else if (lz->result == NULL) { - return Py_BuildValue("OO", Py_TYPE(lz), lz->pools); - } else { - PyObject *indices; - Py_ssize_t n, i; - - /* we must pickle the indices use them for setstate, and - * additionally indicate that the iterator has started - */ - n = PyTuple_GET_SIZE(lz->pools); - indices = PyTuple_New(n); - if (indices == NULL) - return NULL; - for (i=0; iindices[i]); - if (!index) { - Py_DECREF(indices); - return NULL; - } - PyTuple_SET_ITEM(indices, i, index); - } - return Py_BuildValue("OON", Py_TYPE(lz), lz->pools, indices); - } -} - -static PyObject * -product_setstate(productobject *lz, PyObject *state) -{ - PyObject *result; - Py_ssize_t n, i; - - n = PyTuple_GET_SIZE(lz->pools); - if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != n) { - PyErr_SetString(PyExc_ValueError, "invalid arguments"); - return NULL; - } - for (i=0; ipools, i); - poolsize = PyTuple_GET_SIZE(pool); - if (poolsize == 0) { - lz->stopped = 1; - Py_RETURN_NONE; - } - /* clamp the index */ - if (index < 0) - index = 0; - else if (index > poolsize-1) - index = poolsize-1; - lz->indices[i] = index; - } - - result = PyTuple_New(n); - if (!result) - return NULL; - for (i=0; ipools, i); - PyObject *element = PyTuple_GET_ITEM(pool, lz->indices[i]); - Py_INCREF(element); - PyTuple_SET_ITEM(result, i, element); - } - Py_XSETREF(lz->result, result); - Py_RETURN_NONE; -} - -static PyMethodDef product_methods[] = { - {"__reduce__", (PyCFunction)product_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)product_setstate, METH_O, - setstate_doc}, - {"__sizeof__", (PyCFunction)product_sizeof, METH_NOARGS, - sizeof_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(product_doc, -"product(*iterables, repeat=1) --> product object\n\ -\n\ -Cartesian product of input iterables. Equivalent to nested for-loops.\n\n\ -For example, product(A, B) returns the same as: ((x,y) for x in A for y in B).\n\ -The leftmost iterators are in the outermost for-loop, so the output tuples\n\ -cycle in a manner similar to an odometer (with the rightmost element changing\n\ -on every iteration).\n\n\ -To compute the product of an iterable with itself, specify the number\n\ -of repetitions with the optional repeat keyword argument. For example,\n\ -product(A, repeat=4) means the same as product(A, A, A, A).\n\n\ -product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\ -product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ..."); - -static PyTypeObject product_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.product", /* tp_name */ - sizeof(productobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)product_dealloc, /* tp_dealloc */ + } + /* Now, we've got the only copy so we can update it in-place */ + assert (npools==0 || Py_REFCNT(result) == 1); + + /* Update the pool indices right-to-left. Only advance to the + next pool when the previous one rolls-over */ + for (i=npools-1 ; i >= 0 ; i--) { + pool = PyTuple_GET_ITEM(pools, i); + indices[i]++; + if (indices[i] == PyTuple_GET_SIZE(pool)) { + /* Roll-over and advance to next pool */ + indices[i] = 0; + elem = PyTuple_GET_ITEM(pool, 0); + Py_INCREF(elem); + oldelem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, elem); + Py_DECREF(oldelem); + } else { + /* No rollover. Just increment and stop here. */ + elem = PyTuple_GET_ITEM(pool, indices[i]); + Py_INCREF(elem); + oldelem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, elem); + Py_DECREF(oldelem); + break; + } + } + + /* If i is negative, then the indices have all rolled-over + and we're done. */ + if (i < 0) + goto empty; + } + + Py_INCREF(result); + return result; + +empty: + lz->stopped = 1; + return NULL; +} + +static PyObject * +product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored)) +{ + if (lz->stopped) { + return Py_BuildValue("O(())", Py_TYPE(lz)); + } else if (lz->result == NULL) { + return Py_BuildValue("OO", Py_TYPE(lz), lz->pools); + } else { + PyObject *indices; + Py_ssize_t n, i; + + /* we must pickle the indices use them for setstate, and + * additionally indicate that the iterator has started + */ + n = PyTuple_GET_SIZE(lz->pools); + indices = PyTuple_New(n); + if (indices == NULL) + return NULL; + for (i=0; iindices[i]); + if (!index) { + Py_DECREF(indices); + return NULL; + } + PyTuple_SET_ITEM(indices, i, index); + } + return Py_BuildValue("OON", Py_TYPE(lz), lz->pools, indices); + } +} + +static PyObject * +product_setstate(productobject *lz, PyObject *state) +{ + PyObject *result; + Py_ssize_t n, i; + + n = PyTuple_GET_SIZE(lz->pools); + if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != n) { + PyErr_SetString(PyExc_ValueError, "invalid arguments"); + return NULL; + } + for (i=0; ipools, i); + poolsize = PyTuple_GET_SIZE(pool); + if (poolsize == 0) { + lz->stopped = 1; + Py_RETURN_NONE; + } + /* clamp the index */ + if (index < 0) + index = 0; + else if (index > poolsize-1) + index = poolsize-1; + lz->indices[i] = index; + } + + result = PyTuple_New(n); + if (!result) + return NULL; + for (i=0; ipools, i); + PyObject *element = PyTuple_GET_ITEM(pool, lz->indices[i]); + Py_INCREF(element); + PyTuple_SET_ITEM(result, i, element); + } + Py_XSETREF(lz->result, result); + Py_RETURN_NONE; +} + +static PyMethodDef product_methods[] = { + {"__reduce__", (PyCFunction)product_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)product_setstate, METH_O, + setstate_doc}, + {"__sizeof__", (PyCFunction)product_sizeof, METH_NOARGS, + sizeof_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(product_doc, +"product(*iterables, repeat=1) --> product object\n\ +\n\ +Cartesian product of input iterables. Equivalent to nested for-loops.\n\n\ +For example, product(A, B) returns the same as: ((x,y) for x in A for y in B).\n\ +The leftmost iterators are in the outermost for-loop, so the output tuples\n\ +cycle in a manner similar to an odometer (with the rightmost element changing\n\ +on every iteration).\n\n\ +To compute the product of an iterable with itself, specify the number\n\ +of repetitions with the optional repeat keyword argument. For example,\n\ +product(A, repeat=4) means the same as product(A, A, A, A).\n\n\ +product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\ +product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ..."); + +static PyTypeObject product_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.product", /* tp_name */ + sizeof(productobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)product_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - product_doc, /* tp_doc */ - (traverseproc)product_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)product_next, /* tp_iternext */ - product_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - product_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* combinations object *******************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ - Py_ssize_t *indices; /* one index per result element */ - PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the iterator is exhausted */ -} combinationsobject; - - + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + product_doc, /* tp_doc */ + (traverseproc)product_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)product_next, /* tp_iternext */ + product_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + product_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* combinations object *******************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *pool; /* input converted to a tuple */ + Py_ssize_t *indices; /* one index per result element */ + PyObject *result; /* most recently returned result tuple */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ +} combinationsobject; + + /*[clinic input] @classmethod itertools.combinations.__new__ @@ -2460,332 +2460,332 @@ Return successive r-length combinations of elements in the iterable. combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3) [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_combinations_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t r) /*[clinic end generated code: output=87a689b39c40039c input=06bede09e3da20f8]*/ -{ - combinationsobject *co; - Py_ssize_t n; - PyObject *pool = NULL; - Py_ssize_t *indices = NULL; - Py_ssize_t i; - - pool = PySequence_Tuple(iterable); - if (pool == NULL) - goto error; - n = PyTuple_GET_SIZE(pool); - if (r < 0) { - PyErr_SetString(PyExc_ValueError, "r must be non-negative"); - goto error; - } - - indices = PyMem_New(Py_ssize_t, r); - if (indices == NULL) { - PyErr_NoMemory(); - goto error; - } - - for (i=0 ; itp_alloc(type, 0); - if (co == NULL) - goto error; - - co->pool = pool; - co->indices = indices; - co->result = NULL; - co->r = r; - co->stopped = r > n ? 1 : 0; - - return (PyObject *)co; - -error: - if (indices != NULL) - PyMem_Free(indices); - Py_XDECREF(pool); - return NULL; -} - -static void -combinations_dealloc(combinationsobject *co) -{ - PyObject_GC_UnTrack(co); - Py_XDECREF(co->pool); - Py_XDECREF(co->result); - if (co->indices != NULL) - PyMem_Free(co->indices); - Py_TYPE(co)->tp_free(co); -} - -static PyObject * -combinations_sizeof(combinationsobject *co, void *unused) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(co)); - res += co->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); -} - -static int -combinations_traverse(combinationsobject *co, visitproc visit, void *arg) -{ - Py_VISIT(co->pool); - Py_VISIT(co->result); - return 0; -} - -static PyObject * -combinations_next(combinationsobject *co) -{ - PyObject *elem; - PyObject *oldelem; - PyObject *pool = co->pool; - Py_ssize_t *indices = co->indices; - PyObject *result = co->result; - Py_ssize_t n = PyTuple_GET_SIZE(pool); - Py_ssize_t r = co->r; - Py_ssize_t i, j, index; - - if (co->stopped) - return NULL; - - if (result == NULL) { - /* On the first pass, initialize result tuple using the indices */ - result = PyTuple_New(r); - if (result == NULL) - goto empty; - co->result = result; - for (i=0; i 1) { - PyObject *old_result = result; +{ + combinationsobject *co; + Py_ssize_t n; + PyObject *pool = NULL; + Py_ssize_t *indices = NULL; + Py_ssize_t i; + + pool = PySequence_Tuple(iterable); + if (pool == NULL) + goto error; + n = PyTuple_GET_SIZE(pool); + if (r < 0) { + PyErr_SetString(PyExc_ValueError, "r must be non-negative"); + goto error; + } + + indices = PyMem_New(Py_ssize_t, r); + if (indices == NULL) { + PyErr_NoMemory(); + goto error; + } + + for (i=0 ; itp_alloc(type, 0); + if (co == NULL) + goto error; + + co->pool = pool; + co->indices = indices; + co->result = NULL; + co->r = r; + co->stopped = r > n ? 1 : 0; + + return (PyObject *)co; + +error: + if (indices != NULL) + PyMem_Free(indices); + Py_XDECREF(pool); + return NULL; +} + +static void +combinations_dealloc(combinationsobject *co) +{ + PyObject_GC_UnTrack(co); + Py_XDECREF(co->pool); + Py_XDECREF(co->result); + if (co->indices != NULL) + PyMem_Free(co->indices); + Py_TYPE(co)->tp_free(co); +} + +static PyObject * +combinations_sizeof(combinationsobject *co, void *unused) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(co)); + res += co->r * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + +static int +combinations_traverse(combinationsobject *co, visitproc visit, void *arg) +{ + Py_VISIT(co->pool); + Py_VISIT(co->result); + return 0; +} + +static PyObject * +combinations_next(combinationsobject *co) +{ + PyObject *elem; + PyObject *oldelem; + PyObject *pool = co->pool; + Py_ssize_t *indices = co->indices; + PyObject *result = co->result; + Py_ssize_t n = PyTuple_GET_SIZE(pool); + Py_ssize_t r = co->r; + Py_ssize_t i, j, index; + + if (co->stopped) + return NULL; + + if (result == NULL) { + /* On the first pass, initialize result tuple using the indices */ + result = PyTuple_New(r); + if (result == NULL) + goto empty; + co->result = result; + for (i=0; i 1) { + PyObject *old_result = result; result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); - if (result == NULL) - goto empty; - co->result = result; - Py_DECREF(old_result); - } + if (result == NULL) + goto empty; + co->result = result; + Py_DECREF(old_result); + } // bpo-42536: The GC may have untracked this result tuple. Since we're // recycling it, make sure it's tracked again: else if (!_PyObject_GC_IS_TRACKED(result)) { _PyObject_GC_TRACK(result); } - /* Now, we've got the only copy so we can update it in-place - * CPython's empty tuple is a singleton and cached in - * PyTuple's freelist. - */ - assert(r == 0 || Py_REFCNT(result) == 1); - - /* Scan indices right-to-left until finding one that is not - at its maximum (i + n - r). */ - for (i=r-1 ; i >= 0 && indices[i] == i+n-r ; i--) - ; - - /* If i is negative, then the indices are all at - their maximum value and we're done. */ - if (i < 0) - goto empty; - - /* Increment the current index which we know is not at its - maximum. Then move back to the right setting each index - to its lowest possible value (one higher than the index - to its left -- this maintains the sort order invariant). */ - indices[i]++; - for (j=i+1 ; jstopped = 1; - return NULL; -} - -static PyObject * + /* Now, we've got the only copy so we can update it in-place + * CPython's empty tuple is a singleton and cached in + * PyTuple's freelist. + */ + assert(r == 0 || Py_REFCNT(result) == 1); + + /* Scan indices right-to-left until finding one that is not + at its maximum (i + n - r). */ + for (i=r-1 ; i >= 0 && indices[i] == i+n-r ; i--) + ; + + /* If i is negative, then the indices are all at + their maximum value and we're done. */ + if (i < 0) + goto empty; + + /* Increment the current index which we know is not at its + maximum. Then move back to the right setting each index + to its lowest possible value (one higher than the index + to its left -- this maintains the sort order invariant). */ + indices[i]++; + for (j=i+1 ; jstopped = 1; + return NULL; +} + +static PyObject * combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored)) -{ - if (lz->result == NULL) { - return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); - } else if (lz->stopped) { - return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r); - } else { - PyObject *indices; - Py_ssize_t i; - - /* we must pickle the indices and use them for setstate */ - indices = PyTuple_New(lz->r); - if (!indices) - return NULL; - for (i=0; ir; i++) - { - PyObject* index = PyLong_FromSsize_t(lz->indices[i]); - if (!index) { - Py_DECREF(indices); - return NULL; - } - PyTuple_SET_ITEM(indices, i, index); - } - - return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices); - } -} - -static PyObject * -combinations_setstate(combinationsobject *lz, PyObject *state) -{ - PyObject *result; - Py_ssize_t i; - Py_ssize_t n = PyTuple_GET_SIZE(lz->pool); - - if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) { - PyErr_SetString(PyExc_ValueError, "invalid arguments"); - return NULL; - } - - for (i=0; ir; i++) { - Py_ssize_t max; - PyObject* indexObject = PyTuple_GET_ITEM(state, i); - Py_ssize_t index = PyLong_AsSsize_t(indexObject); - - if (index == -1 && PyErr_Occurred()) - return NULL; /* not an integer */ - max = i + n - lz->r; - /* clamp the index (beware of negative max) */ - if (index > max) - index = max; - if (index < 0) - index = 0; - lz->indices[i] = index; - } - - result = PyTuple_New(lz->r); - if (result == NULL) - return NULL; - for (i=0; ir; i++) { - PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]); - Py_INCREF(element); - PyTuple_SET_ITEM(result, i, element); - } - - Py_XSETREF(lz->result, result); - Py_RETURN_NONE; -} - -static PyMethodDef combinations_methods[] = { - {"__reduce__", (PyCFunction)combinations_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)combinations_setstate, METH_O, - setstate_doc}, - {"__sizeof__", (PyCFunction)combinations_sizeof, METH_NOARGS, - sizeof_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject combinations_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.combinations", /* tp_name */ - sizeof(combinationsobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)combinations_dealloc, /* tp_dealloc */ +{ + if (lz->result == NULL) { + return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); + } else if (lz->stopped) { + return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r); + } else { + PyObject *indices; + Py_ssize_t i; + + /* we must pickle the indices and use them for setstate */ + indices = PyTuple_New(lz->r); + if (!indices) + return NULL; + for (i=0; ir; i++) + { + PyObject* index = PyLong_FromSsize_t(lz->indices[i]); + if (!index) { + Py_DECREF(indices); + return NULL; + } + PyTuple_SET_ITEM(indices, i, index); + } + + return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices); + } +} + +static PyObject * +combinations_setstate(combinationsobject *lz, PyObject *state) +{ + PyObject *result; + Py_ssize_t i; + Py_ssize_t n = PyTuple_GET_SIZE(lz->pool); + + if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) { + PyErr_SetString(PyExc_ValueError, "invalid arguments"); + return NULL; + } + + for (i=0; ir; i++) { + Py_ssize_t max; + PyObject* indexObject = PyTuple_GET_ITEM(state, i); + Py_ssize_t index = PyLong_AsSsize_t(indexObject); + + if (index == -1 && PyErr_Occurred()) + return NULL; /* not an integer */ + max = i + n - lz->r; + /* clamp the index (beware of negative max) */ + if (index > max) + index = max; + if (index < 0) + index = 0; + lz->indices[i] = index; + } + + result = PyTuple_New(lz->r); + if (result == NULL) + return NULL; + for (i=0; ir; i++) { + PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]); + Py_INCREF(element); + PyTuple_SET_ITEM(result, i, element); + } + + Py_XSETREF(lz->result, result); + Py_RETURN_NONE; +} + +static PyMethodDef combinations_methods[] = { + {"__reduce__", (PyCFunction)combinations_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)combinations_setstate, METH_O, + setstate_doc}, + {"__sizeof__", (PyCFunction)combinations_sizeof, METH_NOARGS, + sizeof_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject combinations_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.combinations", /* tp_name */ + sizeof(combinationsobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)combinations_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_combinations__doc__, /* tp_doc */ - (traverseproc)combinations_traverse,/* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)combinations_next, /* tp_iternext */ - combinations_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)combinations_traverse,/* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)combinations_next, /* tp_iternext */ + combinations_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_combinations, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* combinations with replacement object **************************************/ - -/* Equivalent to: - - def combinations_with_replacement(iterable, r): - "combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC" - # number items returned: (n+r-1)! / r! / (n-1)! - pool = tuple(iterable) - n = len(pool) - indices = [0] * r - yield tuple(pool[i] for i in indices) - while 1: - for i in reversed(range(r)): - if indices[i] != n - 1: - break - else: - return - indices[i:] = [indices[i] + 1] * (r - i) - yield tuple(pool[i] for i in indices) - - def combinations_with_replacement2(iterable, r): - 'Alternate version that filters from product()' - pool = tuple(iterable) - n = len(pool) - for indices in product(range(n), repeat=r): - if sorted(indices) == list(indices): - yield tuple(pool[i] for i in indices) -*/ -typedef struct { - PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ - Py_ssize_t *indices; /* one index per result element */ - PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the cwr iterator is exhausted */ -} cwrobject; - + PyObject_GC_Del, /* tp_free */ +}; + + +/* combinations with replacement object **************************************/ + +/* Equivalent to: + + def combinations_with_replacement(iterable, r): + "combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC" + # number items returned: (n+r-1)! / r! / (n-1)! + pool = tuple(iterable) + n = len(pool) + indices = [0] * r + yield tuple(pool[i] for i in indices) + while 1: + for i in reversed(range(r)): + if indices[i] != n - 1: + break + else: + return + indices[i:] = [indices[i] + 1] * (r - i) + yield tuple(pool[i] for i in indices) + + def combinations_with_replacement2(iterable, r): + 'Alternate version that filters from product()' + pool = tuple(iterable) + n = len(pool) + for indices in product(range(n), repeat=r): + if sorted(indices) == list(indices): + yield tuple(pool[i] for i in indices) +*/ +typedef struct { + PyObject_HEAD + PyObject *pool; /* input converted to a tuple */ + Py_ssize_t *indices; /* one index per result element */ + PyObject *result; /* most recently returned result tuple */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the cwr iterator is exhausted */ +} cwrobject; + /*[clinic input] @classmethod itertools.combinations_with_replacement.__new__ @@ -2796,324 +2796,324 @@ Return successive r-length combinations of elements in the iterable allowing ind combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC" [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_combinations_with_replacement_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t r) /*[clinic end generated code: output=48b26856d4e659ca input=dc2a8c7ba785fad7]*/ -{ - cwrobject *co; - Py_ssize_t n; - PyObject *pool = NULL; - Py_ssize_t *indices = NULL; - Py_ssize_t i; - - pool = PySequence_Tuple(iterable); - if (pool == NULL) - goto error; - n = PyTuple_GET_SIZE(pool); - if (r < 0) { - PyErr_SetString(PyExc_ValueError, "r must be non-negative"); - goto error; - } - - indices = PyMem_New(Py_ssize_t, r); - if (indices == NULL) { - PyErr_NoMemory(); - goto error; - } - - for (i=0 ; itp_alloc(type, 0); - if (co == NULL) - goto error; - - co->pool = pool; - co->indices = indices; - co->result = NULL; - co->r = r; - co->stopped = !n && r; - - return (PyObject *)co; - -error: - if (indices != NULL) - PyMem_Free(indices); - Py_XDECREF(pool); - return NULL; -} - -static void -cwr_dealloc(cwrobject *co) -{ - PyObject_GC_UnTrack(co); - Py_XDECREF(co->pool); - Py_XDECREF(co->result); - if (co->indices != NULL) - PyMem_Free(co->indices); - Py_TYPE(co)->tp_free(co); -} - -static PyObject * -cwr_sizeof(cwrobject *co, void *unused) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(co)); - res += co->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); -} - -static int -cwr_traverse(cwrobject *co, visitproc visit, void *arg) -{ - Py_VISIT(co->pool); - Py_VISIT(co->result); - return 0; -} - -static PyObject * -cwr_next(cwrobject *co) -{ - PyObject *elem; - PyObject *oldelem; - PyObject *pool = co->pool; - Py_ssize_t *indices = co->indices; - PyObject *result = co->result; - Py_ssize_t n = PyTuple_GET_SIZE(pool); - Py_ssize_t r = co->r; - Py_ssize_t i, index; - - if (co->stopped) - return NULL; - - if (result == NULL) { - /* On the first pass, initialize result tuple with pool[0] */ - result = PyTuple_New(r); - if (result == NULL) - goto empty; - co->result = result; - if (n > 0) { - elem = PyTuple_GET_ITEM(pool, 0); - for (i=0; i 1) { - PyObject *old_result = result; +{ + cwrobject *co; + Py_ssize_t n; + PyObject *pool = NULL; + Py_ssize_t *indices = NULL; + Py_ssize_t i; + + pool = PySequence_Tuple(iterable); + if (pool == NULL) + goto error; + n = PyTuple_GET_SIZE(pool); + if (r < 0) { + PyErr_SetString(PyExc_ValueError, "r must be non-negative"); + goto error; + } + + indices = PyMem_New(Py_ssize_t, r); + if (indices == NULL) { + PyErr_NoMemory(); + goto error; + } + + for (i=0 ; itp_alloc(type, 0); + if (co == NULL) + goto error; + + co->pool = pool; + co->indices = indices; + co->result = NULL; + co->r = r; + co->stopped = !n && r; + + return (PyObject *)co; + +error: + if (indices != NULL) + PyMem_Free(indices); + Py_XDECREF(pool); + return NULL; +} + +static void +cwr_dealloc(cwrobject *co) +{ + PyObject_GC_UnTrack(co); + Py_XDECREF(co->pool); + Py_XDECREF(co->result); + if (co->indices != NULL) + PyMem_Free(co->indices); + Py_TYPE(co)->tp_free(co); +} + +static PyObject * +cwr_sizeof(cwrobject *co, void *unused) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(co)); + res += co->r * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + +static int +cwr_traverse(cwrobject *co, visitproc visit, void *arg) +{ + Py_VISIT(co->pool); + Py_VISIT(co->result); + return 0; +} + +static PyObject * +cwr_next(cwrobject *co) +{ + PyObject *elem; + PyObject *oldelem; + PyObject *pool = co->pool; + Py_ssize_t *indices = co->indices; + PyObject *result = co->result; + Py_ssize_t n = PyTuple_GET_SIZE(pool); + Py_ssize_t r = co->r; + Py_ssize_t i, index; + + if (co->stopped) + return NULL; + + if (result == NULL) { + /* On the first pass, initialize result tuple with pool[0] */ + result = PyTuple_New(r); + if (result == NULL) + goto empty; + co->result = result; + if (n > 0) { + elem = PyTuple_GET_ITEM(pool, 0); + for (i=0; i 1) { + PyObject *old_result = result; result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); - if (result == NULL) - goto empty; - co->result = result; - Py_DECREF(old_result); - } + if (result == NULL) + goto empty; + co->result = result; + Py_DECREF(old_result); + } // bpo-42536: The GC may have untracked this result tuple. Since we're // recycling it, make sure it's tracked again: else if (!_PyObject_GC_IS_TRACKED(result)) { _PyObject_GC_TRACK(result); } - /* Now, we've got the only copy so we can update it in-place CPython's - empty tuple is a singleton and cached in PyTuple's freelist. */ - assert(r == 0 || Py_REFCNT(result) == 1); - - /* Scan indices right-to-left until finding one that is not - * at its maximum (n-1). */ - for (i=r-1 ; i >= 0 && indices[i] == n-1; i--) - ; - - /* If i is negative, then the indices are all at - their maximum value and we're done. */ - if (i < 0) - goto empty; - - /* Increment the current index which we know is not at its - maximum. Then set all to the right to the same value. */ - index = indices[i] + 1; - assert(index < n); - elem = PyTuple_GET_ITEM(pool, index); - for ( ; istopped = 1; - return NULL; -} - -static PyObject * + /* Now, we've got the only copy so we can update it in-place CPython's + empty tuple is a singleton and cached in PyTuple's freelist. */ + assert(r == 0 || Py_REFCNT(result) == 1); + + /* Scan indices right-to-left until finding one that is not + * at its maximum (n-1). */ + for (i=r-1 ; i >= 0 && indices[i] == n-1; i--) + ; + + /* If i is negative, then the indices are all at + their maximum value and we're done. */ + if (i < 0) + goto empty; + + /* Increment the current index which we know is not at its + maximum. Then set all to the right to the same value. */ + index = indices[i] + 1; + assert(index < n); + elem = PyTuple_GET_ITEM(pool, index); + for ( ; istopped = 1; + return NULL; +} + +static PyObject * cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored)) -{ - if (lz->result == NULL) { - return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); - } else if (lz->stopped) { - return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r); - } else { - PyObject *indices; - Py_ssize_t i; - - /* we must pickle the indices and use them for setstate */ - indices = PyTuple_New(lz->r); - if (!indices) - return NULL; - for (i=0; ir; i++) { - PyObject* index = PyLong_FromSsize_t(lz->indices[i]); - if (!index) { - Py_DECREF(indices); - return NULL; - } - PyTuple_SET_ITEM(indices, i, index); - } - - return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices); - } -} - -static PyObject * -cwr_setstate(cwrobject *lz, PyObject *state) -{ - PyObject *result; - Py_ssize_t n, i; - - if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) - { - PyErr_SetString(PyExc_ValueError, "invalid arguments"); - return NULL; - } - - n = PyTuple_GET_SIZE(lz->pool); - for (i=0; ir; i++) { - PyObject* indexObject = PyTuple_GET_ITEM(state, i); - Py_ssize_t index = PyLong_AsSsize_t(indexObject); - - if (index < 0 && PyErr_Occurred()) - return NULL; /* not an integer */ - /* clamp the index */ - if (index < 0) - index = 0; - else if (index > n-1) - index = n-1; - lz->indices[i] = index; - } - result = PyTuple_New(lz->r); - if (result == NULL) - return NULL; - for (i=0; ir; i++) { - PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]); - Py_INCREF(element); - PyTuple_SET_ITEM(result, i, element); - } - Py_XSETREF(lz->result, result); - Py_RETURN_NONE; -} - -static PyMethodDef cwr_methods[] = { - {"__reduce__", (PyCFunction)cwr_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)cwr_setstate, METH_O, - setstate_doc}, - {"__sizeof__", (PyCFunction)cwr_sizeof, METH_NOARGS, - sizeof_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject cwr_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.combinations_with_replacement", /* tp_name */ - sizeof(cwrobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)cwr_dealloc, /* tp_dealloc */ +{ + if (lz->result == NULL) { + return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); + } else if (lz->stopped) { + return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r); + } else { + PyObject *indices; + Py_ssize_t i; + + /* we must pickle the indices and use them for setstate */ + indices = PyTuple_New(lz->r); + if (!indices) + return NULL; + for (i=0; ir; i++) { + PyObject* index = PyLong_FromSsize_t(lz->indices[i]); + if (!index) { + Py_DECREF(indices); + return NULL; + } + PyTuple_SET_ITEM(indices, i, index); + } + + return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices); + } +} + +static PyObject * +cwr_setstate(cwrobject *lz, PyObject *state) +{ + PyObject *result; + Py_ssize_t n, i; + + if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) + { + PyErr_SetString(PyExc_ValueError, "invalid arguments"); + return NULL; + } + + n = PyTuple_GET_SIZE(lz->pool); + for (i=0; ir; i++) { + PyObject* indexObject = PyTuple_GET_ITEM(state, i); + Py_ssize_t index = PyLong_AsSsize_t(indexObject); + + if (index < 0 && PyErr_Occurred()) + return NULL; /* not an integer */ + /* clamp the index */ + if (index < 0) + index = 0; + else if (index > n-1) + index = n-1; + lz->indices[i] = index; + } + result = PyTuple_New(lz->r); + if (result == NULL) + return NULL; + for (i=0; ir; i++) { + PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]); + Py_INCREF(element); + PyTuple_SET_ITEM(result, i, element); + } + Py_XSETREF(lz->result, result); + Py_RETURN_NONE; +} + +static PyMethodDef cwr_methods[] = { + {"__reduce__", (PyCFunction)cwr_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)cwr_setstate, METH_O, + setstate_doc}, + {"__sizeof__", (PyCFunction)cwr_sizeof, METH_NOARGS, + sizeof_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject cwr_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.combinations_with_replacement", /* tp_name */ + sizeof(cwrobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)cwr_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_combinations_with_replacement__doc__, /* tp_doc */ - (traverseproc)cwr_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)cwr_next, /* tp_iternext */ - cwr_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)cwr_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)cwr_next, /* tp_iternext */ + cwr_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_combinations_with_replacement, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* permutations object ******************************************************** - -def permutations(iterable, r=None): + PyObject_GC_Del, /* tp_free */ +}; + + +/* permutations object ******************************************************** + +def permutations(iterable, r=None): # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC # permutations(range(3)) --> 012 021 102 120 201 210 - pool = tuple(iterable) - n = len(pool) - r = n if r is None else r + pool = tuple(iterable) + n = len(pool) + r = n if r is None else r if r > n: return indices = list(range(n)) cycles = list(range(n, n-r, -1)) - yield tuple(pool[i] for i in indices[:r]) - while n: - for i in reversed(range(r)): - cycles[i] -= 1 - if cycles[i] == 0: - indices[i:] = indices[i+1:] + indices[i:i+1] - cycles[i] = n - i - else: - j = cycles[i] - indices[i], indices[-j] = indices[-j], indices[i] - yield tuple(pool[i] for i in indices[:r]) - break - else: - return -*/ - -typedef struct { - PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ - Py_ssize_t *indices; /* one index per element in the pool */ - Py_ssize_t *cycles; /* one rollover counter per element in the result */ - PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the iterator is exhausted */ -} permutationsobject; - + yield tuple(pool[i] for i in indices[:r]) + while n: + for i in reversed(range(r)): + cycles[i] -= 1 + if cycles[i] == 0: + indices[i:] = indices[i+1:] + indices[i:i+1] + cycles[i] = n - i + else: + j = cycles[i] + indices[i], indices[-j] = indices[-j], indices[i] + yield tuple(pool[i] for i in indices[:r]) + break + else: + return +*/ + +typedef struct { + PyObject_HEAD + PyObject *pool; /* input converted to a tuple */ + Py_ssize_t *indices; /* one index per element in the pool */ + Py_ssize_t *cycles; /* one rollover counter per element in the result */ + PyObject *result; /* most recently returned result tuple */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ +} permutationsobject; + /*[clinic input] @classmethod itertools.permutations.__new__ @@ -3124,360 +3124,360 @@ Return successive r-length permutations of elements in the iterable. permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1) [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_permutations_impl(PyTypeObject *type, PyObject *iterable, PyObject *robj) /*[clinic end generated code: output=296a72fa76d620ea input=57d0170a4ac0ec7a]*/ -{ - permutationsobject *po; - Py_ssize_t n; - Py_ssize_t r; - PyObject *pool = NULL; - Py_ssize_t *indices = NULL; - Py_ssize_t *cycles = NULL; - Py_ssize_t i; - - pool = PySequence_Tuple(iterable); - if (pool == NULL) - goto error; - n = PyTuple_GET_SIZE(pool); - - r = n; - if (robj != Py_None) { - if (!PyLong_Check(robj)) { - PyErr_SetString(PyExc_TypeError, "Expected int as r"); - goto error; - } - r = PyLong_AsSsize_t(robj); - if (r == -1 && PyErr_Occurred()) - goto error; - } - if (r < 0) { - PyErr_SetString(PyExc_ValueError, "r must be non-negative"); - goto error; - } - - indices = PyMem_New(Py_ssize_t, n); - cycles = PyMem_New(Py_ssize_t, r); - if (indices == NULL || cycles == NULL) { - PyErr_NoMemory(); - goto error; - } - - for (i=0 ; itp_alloc(type, 0); - if (po == NULL) - goto error; - - po->pool = pool; - po->indices = indices; - po->cycles = cycles; - po->result = NULL; - po->r = r; - po->stopped = r > n ? 1 : 0; - - return (PyObject *)po; - -error: - if (indices != NULL) - PyMem_Free(indices); - if (cycles != NULL) - PyMem_Free(cycles); - Py_XDECREF(pool); - return NULL; -} - -static void -permutations_dealloc(permutationsobject *po) -{ - PyObject_GC_UnTrack(po); - Py_XDECREF(po->pool); - Py_XDECREF(po->result); - PyMem_Free(po->indices); - PyMem_Free(po->cycles); - Py_TYPE(po)->tp_free(po); -} - -static PyObject * -permutations_sizeof(permutationsobject *po, void *unused) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(po)); - res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); - res += po->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); -} - -static int -permutations_traverse(permutationsobject *po, visitproc visit, void *arg) -{ - Py_VISIT(po->pool); - Py_VISIT(po->result); - return 0; -} - -static PyObject * -permutations_next(permutationsobject *po) -{ - PyObject *elem; - PyObject *oldelem; - PyObject *pool = po->pool; - Py_ssize_t *indices = po->indices; - Py_ssize_t *cycles = po->cycles; - PyObject *result = po->result; - Py_ssize_t n = PyTuple_GET_SIZE(pool); - Py_ssize_t r = po->r; - Py_ssize_t i, j, k, index; - - if (po->stopped) - return NULL; - - if (result == NULL) { - /* On the first pass, initialize result tuple using the indices */ - result = PyTuple_New(r); - if (result == NULL) - goto empty; - po->result = result; - for (i=0; i 1) { - PyObject *old_result = result; +{ + permutationsobject *po; + Py_ssize_t n; + Py_ssize_t r; + PyObject *pool = NULL; + Py_ssize_t *indices = NULL; + Py_ssize_t *cycles = NULL; + Py_ssize_t i; + + pool = PySequence_Tuple(iterable); + if (pool == NULL) + goto error; + n = PyTuple_GET_SIZE(pool); + + r = n; + if (robj != Py_None) { + if (!PyLong_Check(robj)) { + PyErr_SetString(PyExc_TypeError, "Expected int as r"); + goto error; + } + r = PyLong_AsSsize_t(robj); + if (r == -1 && PyErr_Occurred()) + goto error; + } + if (r < 0) { + PyErr_SetString(PyExc_ValueError, "r must be non-negative"); + goto error; + } + + indices = PyMem_New(Py_ssize_t, n); + cycles = PyMem_New(Py_ssize_t, r); + if (indices == NULL || cycles == NULL) { + PyErr_NoMemory(); + goto error; + } + + for (i=0 ; itp_alloc(type, 0); + if (po == NULL) + goto error; + + po->pool = pool; + po->indices = indices; + po->cycles = cycles; + po->result = NULL; + po->r = r; + po->stopped = r > n ? 1 : 0; + + return (PyObject *)po; + +error: + if (indices != NULL) + PyMem_Free(indices); + if (cycles != NULL) + PyMem_Free(cycles); + Py_XDECREF(pool); + return NULL; +} + +static void +permutations_dealloc(permutationsobject *po) +{ + PyObject_GC_UnTrack(po); + Py_XDECREF(po->pool); + Py_XDECREF(po->result); + PyMem_Free(po->indices); + PyMem_Free(po->cycles); + Py_TYPE(po)->tp_free(po); +} + +static PyObject * +permutations_sizeof(permutationsobject *po, void *unused) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(po)); + res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); + res += po->r * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + +static int +permutations_traverse(permutationsobject *po, visitproc visit, void *arg) +{ + Py_VISIT(po->pool); + Py_VISIT(po->result); + return 0; +} + +static PyObject * +permutations_next(permutationsobject *po) +{ + PyObject *elem; + PyObject *oldelem; + PyObject *pool = po->pool; + Py_ssize_t *indices = po->indices; + Py_ssize_t *cycles = po->cycles; + PyObject *result = po->result; + Py_ssize_t n = PyTuple_GET_SIZE(pool); + Py_ssize_t r = po->r; + Py_ssize_t i, j, k, index; + + if (po->stopped) + return NULL; + + if (result == NULL) { + /* On the first pass, initialize result tuple using the indices */ + result = PyTuple_New(r); + if (result == NULL) + goto empty; + po->result = result; + for (i=0; i 1) { + PyObject *old_result = result; result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r); - if (result == NULL) - goto empty; - po->result = result; - Py_DECREF(old_result); - } + if (result == NULL) + goto empty; + po->result = result; + Py_DECREF(old_result); + } // bpo-42536: The GC may have untracked this result tuple. Since we're // recycling it, make sure it's tracked again: else if (!_PyObject_GC_IS_TRACKED(result)) { _PyObject_GC_TRACK(result); } - /* Now, we've got the only copy so we can update it in-place */ - assert(r == 0 || Py_REFCNT(result) == 1); - - /* Decrement rightmost cycle, moving leftward upon zero rollover */ - for (i=r-1 ; i>=0 ; i--) { - cycles[i] -= 1; - if (cycles[i] == 0) { - /* rotatation: indices[i:] = indices[i+1:] + indices[i:i+1] */ - index = indices[i]; - for (j=i ; jstopped = 1; - return NULL; -} - -static PyObject * + /* Now, we've got the only copy so we can update it in-place */ + assert(r == 0 || Py_REFCNT(result) == 1); + + /* Decrement rightmost cycle, moving leftward upon zero rollover */ + for (i=r-1 ; i>=0 ; i--) { + cycles[i] -= 1; + if (cycles[i] == 0) { + /* rotatation: indices[i:] = indices[i+1:] + indices[i:i+1] */ + index = indices[i]; + for (j=i ; jstopped = 1; + return NULL; +} + +static PyObject * permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored)) -{ - if (po->result == NULL) { - return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r); - } else if (po->stopped) { - return Py_BuildValue("O(()n)", Py_TYPE(po), po->r); - } else { - PyObject *indices=NULL, *cycles=NULL; - Py_ssize_t n, i; - - /* we must pickle the indices and cycles and use them for setstate */ - n = PyTuple_GET_SIZE(po->pool); - indices = PyTuple_New(n); - if (indices == NULL) - goto err; - for (i=0; iindices[i]); - if (!index) - goto err; - PyTuple_SET_ITEM(indices, i, index); - } - - cycles = PyTuple_New(po->r); - if (cycles == NULL) - goto err; - for (i=0 ; ir ; i++) { - PyObject* index = PyLong_FromSsize_t(po->cycles[i]); - if (!index) - goto err; - PyTuple_SET_ITEM(cycles, i, index); - } - return Py_BuildValue("O(On)(NN)", Py_TYPE(po), - po->pool, po->r, - indices, cycles); - err: - Py_XDECREF(indices); - Py_XDECREF(cycles); - return NULL; - } -} - -static PyObject * -permutations_setstate(permutationsobject *po, PyObject *state) -{ - PyObject *indices, *cycles, *result; - Py_ssize_t n, i; - - if (!PyTuple_Check(state)) { - PyErr_SetString(PyExc_TypeError, "state is not a tuple"); - return NULL; - } - if (!PyArg_ParseTuple(state, "O!O!", - &PyTuple_Type, &indices, - &PyTuple_Type, &cycles)) { - return NULL; - } - - n = PyTuple_GET_SIZE(po->pool); - if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) { - PyErr_SetString(PyExc_ValueError, "invalid arguments"); - return NULL; - } - - for (i=0; i n-1) - index = n-1; - po->indices[i] = index; - } - - for (i=0; ir; i++) { - PyObject* indexObject = PyTuple_GET_ITEM(cycles, i); - Py_ssize_t index = PyLong_AsSsize_t(indexObject); - if (index < 0 && PyErr_Occurred()) - return NULL; /* not an integer */ - if (index < 1) - index = 1; - else if (index > n-i) - index = n-i; - po->cycles[i] = index; - } - result = PyTuple_New(po->r); - if (result == NULL) - return NULL; - for (i=0; ir; i++) { - PyObject *element = PyTuple_GET_ITEM(po->pool, po->indices[i]); - Py_INCREF(element); - PyTuple_SET_ITEM(result, i, element); - } - Py_XSETREF(po->result, result); - Py_RETURN_NONE; -} - -static PyMethodDef permuations_methods[] = { - {"__reduce__", (PyCFunction)permutations_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)permutations_setstate, METH_O, - setstate_doc}, - {"__sizeof__", (PyCFunction)permutations_sizeof, METH_NOARGS, - sizeof_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject permutations_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.permutations", /* tp_name */ - sizeof(permutationsobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)permutations_dealloc, /* tp_dealloc */ +{ + if (po->result == NULL) { + return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r); + } else if (po->stopped) { + return Py_BuildValue("O(()n)", Py_TYPE(po), po->r); + } else { + PyObject *indices=NULL, *cycles=NULL; + Py_ssize_t n, i; + + /* we must pickle the indices and cycles and use them for setstate */ + n = PyTuple_GET_SIZE(po->pool); + indices = PyTuple_New(n); + if (indices == NULL) + goto err; + for (i=0; iindices[i]); + if (!index) + goto err; + PyTuple_SET_ITEM(indices, i, index); + } + + cycles = PyTuple_New(po->r); + if (cycles == NULL) + goto err; + for (i=0 ; ir ; i++) { + PyObject* index = PyLong_FromSsize_t(po->cycles[i]); + if (!index) + goto err; + PyTuple_SET_ITEM(cycles, i, index); + } + return Py_BuildValue("O(On)(NN)", Py_TYPE(po), + po->pool, po->r, + indices, cycles); + err: + Py_XDECREF(indices); + Py_XDECREF(cycles); + return NULL; + } +} + +static PyObject * +permutations_setstate(permutationsobject *po, PyObject *state) +{ + PyObject *indices, *cycles, *result; + Py_ssize_t n, i; + + if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state is not a tuple"); + return NULL; + } + if (!PyArg_ParseTuple(state, "O!O!", + &PyTuple_Type, &indices, + &PyTuple_Type, &cycles)) { + return NULL; + } + + n = PyTuple_GET_SIZE(po->pool); + if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) { + PyErr_SetString(PyExc_ValueError, "invalid arguments"); + return NULL; + } + + for (i=0; i n-1) + index = n-1; + po->indices[i] = index; + } + + for (i=0; ir; i++) { + PyObject* indexObject = PyTuple_GET_ITEM(cycles, i); + Py_ssize_t index = PyLong_AsSsize_t(indexObject); + if (index < 0 && PyErr_Occurred()) + return NULL; /* not an integer */ + if (index < 1) + index = 1; + else if (index > n-i) + index = n-i; + po->cycles[i] = index; + } + result = PyTuple_New(po->r); + if (result == NULL) + return NULL; + for (i=0; ir; i++) { + PyObject *element = PyTuple_GET_ITEM(po->pool, po->indices[i]); + Py_INCREF(element); + PyTuple_SET_ITEM(result, i, element); + } + Py_XSETREF(po->result, result); + Py_RETURN_NONE; +} + +static PyMethodDef permuations_methods[] = { + {"__reduce__", (PyCFunction)permutations_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)permutations_setstate, METH_O, + setstate_doc}, + {"__sizeof__", (PyCFunction)permutations_sizeof, METH_NOARGS, + sizeof_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject permutations_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.permutations", /* tp_name */ + sizeof(permutationsobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)permutations_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_permutations__doc__, /* tp_doc */ - (traverseproc)permutations_traverse,/* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)permutations_next, /* tp_iternext */ - permuations_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)permutations_traverse,/* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)permutations_next, /* tp_iternext */ + permuations_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_permutations, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* accumulate object ********************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *total; - PyObject *it; - PyObject *binop; + PyObject_GC_Del, /* tp_free */ +}; + + +/* accumulate object ********************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *total; + PyObject *it; + PyObject *binop; PyObject *initial; -} accumulateobject; - +} accumulateobject; + /*[clinic input] @classmethod itertools.accumulate.__new__ @@ -3488,63 +3488,63 @@ itertools.accumulate.__new__ Return series of accumulated sums (or other binary function results). [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable, PyObject *binop, PyObject *initial) /*[clinic end generated code: output=66da2650627128f8 input=c4ce20ac59bf7ffd]*/ -{ - PyObject *it; - accumulateobject *lz; - - /* Get iterator. */ - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - /* create accumulateobject structure */ - lz = (accumulateobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(it); - return NULL; - } - - if (binop != Py_None) { - Py_XINCREF(binop); - lz->binop = binop; - } - lz->total = NULL; - lz->it = it; +{ + PyObject *it; + accumulateobject *lz; + + /* Get iterator. */ + it = PyObject_GetIter(iterable); + if (it == NULL) + return NULL; + + /* create accumulateobject structure */ + lz = (accumulateobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + + if (binop != Py_None) { + Py_XINCREF(binop); + lz->binop = binop; + } + lz->total = NULL; + lz->it = it; Py_XINCREF(initial); lz->initial = initial; - return (PyObject *)lz; -} - -static void -accumulate_dealloc(accumulateobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->binop); - Py_XDECREF(lz->total); - Py_XDECREF(lz->it); + return (PyObject *)lz; +} + +static void +accumulate_dealloc(accumulateobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->binop); + Py_XDECREF(lz->total); + Py_XDECREF(lz->it); Py_XDECREF(lz->initial); - Py_TYPE(lz)->tp_free(lz); -} - -static int -accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->binop); - Py_VISIT(lz->it); - Py_VISIT(lz->total); + Py_TYPE(lz)->tp_free(lz); +} + +static int +accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->binop); + Py_VISIT(lz->it); + Py_VISIT(lz->total); Py_VISIT(lz->initial); - return 0; -} - -static PyObject * -accumulate_next(accumulateobject *lz) -{ - PyObject *val, *newtotal; - + return 0; +} + +static PyObject * +accumulate_next(accumulateobject *lz) +{ + PyObject *val, *newtotal; + if (lz->initial != Py_None) { lz->total = lz->initial; Py_INCREF(Py_None); @@ -3552,143 +3552,143 @@ accumulate_next(accumulateobject *lz) Py_INCREF(lz->total); return lz->total; } - val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it); - if (val == NULL) - return NULL; - - if (lz->total == NULL) { - Py_INCREF(val); - lz->total = val; - return lz->total; - } - - if (lz->binop == NULL) - newtotal = PyNumber_Add(lz->total, val); - else - newtotal = PyObject_CallFunctionObjArgs(lz->binop, lz->total, val, NULL); - Py_DECREF(val); - if (newtotal == NULL) - return NULL; - - Py_INCREF(newtotal); - Py_SETREF(lz->total, newtotal); - return newtotal; -} - -static PyObject * -accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored)) -{ - if (lz->initial != Py_None) { - PyObject *it; - - assert(lz->total == NULL); - if (PyType_Ready(&chain_type) < 0) - return NULL; - it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O", - lz->initial, lz->it); - if (it == NULL) - return NULL; - return Py_BuildValue("O(NO)O", Py_TYPE(lz), - it, lz->binop?lz->binop:Py_None, Py_None); - } - if (lz->total == Py_None) { + val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it); + if (val == NULL) + return NULL; + + if (lz->total == NULL) { + Py_INCREF(val); + lz->total = val; + return lz->total; + } + + if (lz->binop == NULL) + newtotal = PyNumber_Add(lz->total, val); + else + newtotal = PyObject_CallFunctionObjArgs(lz->binop, lz->total, val, NULL); + Py_DECREF(val); + if (newtotal == NULL) + return NULL; + + Py_INCREF(newtotal); + Py_SETREF(lz->total, newtotal); + return newtotal; +} + +static PyObject * +accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored)) +{ + if (lz->initial != Py_None) { PyObject *it; + assert(lz->total == NULL); if (PyType_Ready(&chain_type) < 0) return NULL; - if (PyType_Ready(&islice_type) < 0) - return NULL; it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O", - lz->total, lz->it); - if (it == NULL) - return NULL; - it = PyObject_CallFunction((PyObject *)Py_TYPE(lz), "NO", - it, lz->binop ? lz->binop : Py_None); + lz->initial, lz->it); if (it == NULL) return NULL; - return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None); + return Py_BuildValue("O(NO)O", Py_TYPE(lz), + it, lz->binop?lz->binop:Py_None, Py_None); } - return Py_BuildValue("O(OO)O", Py_TYPE(lz), - lz->it, lz->binop?lz->binop:Py_None, - lz->total?lz->total:Py_None); -} - -static PyObject * -accumulate_setstate(accumulateobject *lz, PyObject *state) -{ - Py_INCREF(state); - Py_XSETREF(lz->total, state); - Py_RETURN_NONE; -} - -static PyMethodDef accumulate_methods[] = { - {"__reduce__", (PyCFunction)accumulate_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)accumulate_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject accumulate_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.accumulate", /* tp_name */ - sizeof(accumulateobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)accumulate_dealloc, /* tp_dealloc */ + if (lz->total == Py_None) { + PyObject *it; + + if (PyType_Ready(&chain_type) < 0) + return NULL; + if (PyType_Ready(&islice_type) < 0) + return NULL; + it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O", + lz->total, lz->it); + if (it == NULL) + return NULL; + it = PyObject_CallFunction((PyObject *)Py_TYPE(lz), "NO", + it, lz->binop ? lz->binop : Py_None); + if (it == NULL) + return NULL; + return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None); + } + return Py_BuildValue("O(OO)O", Py_TYPE(lz), + lz->it, lz->binop?lz->binop:Py_None, + lz->total?lz->total:Py_None); +} + +static PyObject * +accumulate_setstate(accumulateobject *lz, PyObject *state) +{ + Py_INCREF(state); + Py_XSETREF(lz->total, state); + Py_RETURN_NONE; +} + +static PyMethodDef accumulate_methods[] = { + {"__reduce__", (PyCFunction)accumulate_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)accumulate_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject accumulate_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.accumulate", /* tp_name */ + sizeof(accumulateobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)accumulate_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_accumulate__doc__, /* tp_doc */ - (traverseproc)accumulate_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)accumulate_next, /* tp_iternext */ - accumulate_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)accumulate_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)accumulate_next, /* tp_iternext */ + accumulate_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_accumulate, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* compress object ************************************************************/ - -/* Equivalent to: - - def compress(data, selectors): - "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F" - return (d for d, s in zip(data, selectors) if s) -*/ - -typedef struct { - PyObject_HEAD - PyObject *data; - PyObject *selectors; -} compressobject; - + PyObject_GC_Del, /* tp_free */ +}; + + +/* compress object ************************************************************/ + +/* Equivalent to: + + def compress(data, selectors): + "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F" + return (d for d, s in zip(data, selectors) if s) +*/ + +typedef struct { + PyObject_HEAD + PyObject *data; + PyObject *selectors; +} compressobject; + /*[clinic input] @classmethod itertools.compress.__new__ @@ -3700,153 +3700,153 @@ Forms a shorter iterator from selected data elements using the selectors to choose the data elements. [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2) /*[clinic end generated code: output=7e67157212ed09e0 input=79596d7cd20c77e5]*/ -{ - PyObject *data=NULL, *selectors=NULL; - compressobject *lz; - - data = PyObject_GetIter(seq1); - if (data == NULL) - goto fail; - selectors = PyObject_GetIter(seq2); - if (selectors == NULL) - goto fail; - - /* create compressobject structure */ - lz = (compressobject *)type->tp_alloc(type, 0); - if (lz == NULL) - goto fail; - lz->data = data; - lz->selectors = selectors; - return (PyObject *)lz; - -fail: - Py_XDECREF(data); - Py_XDECREF(selectors); - return NULL; -} - -static void -compress_dealloc(compressobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->data); - Py_XDECREF(lz->selectors); - Py_TYPE(lz)->tp_free(lz); -} - -static int -compress_traverse(compressobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->data); - Py_VISIT(lz->selectors); - return 0; -} - -static PyObject * -compress_next(compressobject *lz) -{ - PyObject *data = lz->data, *selectors = lz->selectors; - PyObject *datum, *selector; - PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext; - PyObject *(*selectornext)(PyObject *) = *Py_TYPE(selectors)->tp_iternext; - int ok; - - while (1) { - /* Steps: get datum, get selector, evaluate selector. - Order is important (to match the pure python version - in terms of which input gets a chance to raise an - exception first). - */ - - datum = datanext(data); - if (datum == NULL) - return NULL; - - selector = selectornext(selectors); - if (selector == NULL) { - Py_DECREF(datum); - return NULL; - } - - ok = PyObject_IsTrue(selector); - Py_DECREF(selector); - if (ok > 0) - return datum; - Py_DECREF(datum); - if (ok < 0) - return NULL; - } -} - -static PyObject * +{ + PyObject *data=NULL, *selectors=NULL; + compressobject *lz; + + data = PyObject_GetIter(seq1); + if (data == NULL) + goto fail; + selectors = PyObject_GetIter(seq2); + if (selectors == NULL) + goto fail; + + /* create compressobject structure */ + lz = (compressobject *)type->tp_alloc(type, 0); + if (lz == NULL) + goto fail; + lz->data = data; + lz->selectors = selectors; + return (PyObject *)lz; + +fail: + Py_XDECREF(data); + Py_XDECREF(selectors); + return NULL; +} + +static void +compress_dealloc(compressobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->data); + Py_XDECREF(lz->selectors); + Py_TYPE(lz)->tp_free(lz); +} + +static int +compress_traverse(compressobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->data); + Py_VISIT(lz->selectors); + return 0; +} + +static PyObject * +compress_next(compressobject *lz) +{ + PyObject *data = lz->data, *selectors = lz->selectors; + PyObject *datum, *selector; + PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext; + PyObject *(*selectornext)(PyObject *) = *Py_TYPE(selectors)->tp_iternext; + int ok; + + while (1) { + /* Steps: get datum, get selector, evaluate selector. + Order is important (to match the pure python version + in terms of which input gets a chance to raise an + exception first). + */ + + datum = datanext(data); + if (datum == NULL) + return NULL; + + selector = selectornext(selectors); + if (selector == NULL) { + Py_DECREF(datum); + return NULL; + } + + ok = PyObject_IsTrue(selector); + Py_DECREF(selector); + if (ok > 0) + return datum; + Py_DECREF(datum); + if (ok < 0) + return NULL; + } +} + +static PyObject * compress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("O(OO)", Py_TYPE(lz), - lz->data, lz->selectors); -} - -static PyMethodDef compress_methods[] = { - {"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS, - reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject compress_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.compress", /* tp_name */ - sizeof(compressobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)compress_dealloc, /* tp_dealloc */ +{ + return Py_BuildValue("O(OO)", Py_TYPE(lz), + lz->data, lz->selectors); +} + +static PyMethodDef compress_methods[] = { + {"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS, + reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject compress_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.compress", /* tp_name */ + sizeof(compressobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)compress_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_compress__doc__, /* tp_doc */ - (traverseproc)compress_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)compress_next, /* tp_iternext */ - compress_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)compress_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)compress_next, /* tp_iternext */ + compress_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_compress, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* filterfalse object ************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *func; - PyObject *it; -} filterfalseobject; - + PyObject_GC_Del, /* tp_free */ +}; + + +/* filterfalse object ************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *func; + PyObject *it; +} filterfalseobject; + /*[clinic input] @classmethod itertools.filterfalse.__new__ @@ -3858,165 +3858,165 @@ Return those items of iterable for which function(item) is false. If function is None, return the items that are false. [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq) /*[clinic end generated code: output=55f87eab9fc0484e input=2d684a2c66f99cde]*/ -{ - PyObject *it; - filterfalseobject *lz; - - /* Get iterator. */ - it = PyObject_GetIter(seq); - if (it == NULL) - return NULL; - - /* create filterfalseobject structure */ - lz = (filterfalseobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(it); - return NULL; - } - Py_INCREF(func); - lz->func = func; - lz->it = it; - - return (PyObject *)lz; -} - -static void -filterfalse_dealloc(filterfalseobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->func); - Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); -} - -static int -filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->it); - Py_VISIT(lz->func); - return 0; -} - -static PyObject * -filterfalse_next(filterfalseobject *lz) -{ - PyObject *item; - PyObject *it = lz->it; - long ok; - PyObject *(*iternext)(PyObject *); - - iternext = *Py_TYPE(it)->tp_iternext; - for (;;) { - item = iternext(it); - if (item == NULL) - return NULL; - - if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) { - ok = PyObject_IsTrue(item); - } else { - PyObject *good; +{ + PyObject *it; + filterfalseobject *lz; + + /* Get iterator. */ + it = PyObject_GetIter(seq); + if (it == NULL) + return NULL; + + /* create filterfalseobject structure */ + lz = (filterfalseobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(it); + return NULL; + } + Py_INCREF(func); + lz->func = func; + lz->it = it; + + return (PyObject *)lz; +} + +static void +filterfalse_dealloc(filterfalseobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->func); + Py_XDECREF(lz->it); + Py_TYPE(lz)->tp_free(lz); +} + +static int +filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->it); + Py_VISIT(lz->func); + return 0; +} + +static PyObject * +filterfalse_next(filterfalseobject *lz) +{ + PyObject *item; + PyObject *it = lz->it; + long ok; + PyObject *(*iternext)(PyObject *); + + iternext = *Py_TYPE(it)->tp_iternext; + for (;;) { + item = iternext(it); + if (item == NULL) + return NULL; + + if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) { + ok = PyObject_IsTrue(item); + } else { + PyObject *good; good = PyObject_CallOneArg(lz->func, item); - if (good == NULL) { - Py_DECREF(item); - return NULL; - } - ok = PyObject_IsTrue(good); - Py_DECREF(good); - } - if (ok == 0) - return item; - Py_DECREF(item); - if (ok < 0) - return NULL; - } -} - -static PyObject * + if (good == NULL) { + Py_DECREF(item); + return NULL; + } + ok = PyObject_IsTrue(good); + Py_DECREF(good); + } + if (ok == 0) + return item; + Py_DECREF(item); + if (ok < 0) + return NULL; + } +} + +static PyObject * filterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored)) -{ - return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); -} - -static PyMethodDef filterfalse_methods[] = { - {"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS, - reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject filterfalse_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.filterfalse", /* tp_name */ - sizeof(filterfalseobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)filterfalse_dealloc, /* tp_dealloc */ +{ + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); +} + +static PyMethodDef filterfalse_methods[] = { + {"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS, + reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject filterfalse_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.filterfalse", /* tp_name */ + sizeof(filterfalseobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)filterfalse_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_filterfalse__doc__, /* tp_doc */ - (traverseproc)filterfalse_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)filterfalse_next, /* tp_iternext */ - filterfalse_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)filterfalse_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)filterfalse_next, /* tp_iternext */ + filterfalse_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_filterfalse, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* count object ************************************************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t cnt; - PyObject *long_cnt; - PyObject *long_step; -} countobject; - -/* Counting logic and invariants: - -fast_mode: when cnt an integer < PY_SSIZE_T_MAX and no step is specified. - - assert(cnt != PY_SSIZE_T_MAX && long_cnt == NULL && long_step==PyLong(1)); - Advances with: cnt += 1 - When count hits Y_SSIZE_T_MAX, switch to slow_mode. - -slow_mode: when cnt == PY_SSIZE_T_MAX, step is not int(1), or cnt is a float. - - assert(cnt == PY_SSIZE_T_MAX && long_cnt != NULL && long_step != NULL); - All counting is done with python objects (no overflows or underflows). - Advances with: long_cnt += long_step - Step may be zero -- effectively a slow version of repeat(cnt). - Either long_cnt or long_step may be a float, Fraction, or Decimal. -*/ - + PyObject_GC_Del, /* tp_free */ +}; + + +/* count object ************************************************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t cnt; + PyObject *long_cnt; + PyObject *long_step; +} countobject; + +/* Counting logic and invariants: + +fast_mode: when cnt an integer < PY_SSIZE_T_MAX and no step is specified. + + assert(cnt != PY_SSIZE_T_MAX && long_cnt == NULL && long_step==PyLong(1)); + Advances with: cnt += 1 + When count hits Y_SSIZE_T_MAX, switch to slow_mode. + +slow_mode: when cnt == PY_SSIZE_T_MAX, step is not int(1), or cnt is a float. + + assert(cnt == PY_SSIZE_T_MAX && long_cnt != NULL && long_step != NULL); + All counting is done with python objects (no overflows or underflows). + Advances with: long_cnt += long_step + Step may be zero -- effectively a slow version of repeat(cnt). + Either long_cnt or long_step may be a float, Fraction, or Decimal. +*/ + /*[clinic input] @classmethod itertools.count.__new__ @@ -4032,393 +4032,393 @@ Equivalent to: x += step [clinic start generated code]*/ -static PyObject * +static PyObject * itertools_count_impl(PyTypeObject *type, PyObject *long_cnt, PyObject *long_step) /*[clinic end generated code: output=09a9250aebd00b1c input=d7a85eec18bfcd94]*/ -{ - countobject *lz; - int fast_mode; - Py_ssize_t cnt = 0; - long step; - - if ((long_cnt != NULL && !PyNumber_Check(long_cnt)) || - (long_step != NULL && !PyNumber_Check(long_step))) { - PyErr_SetString(PyExc_TypeError, "a number is required"); - return NULL; - } - - fast_mode = (long_cnt == NULL || PyLong_Check(long_cnt)) && - (long_step == NULL || PyLong_Check(long_step)); - - /* If not specified, start defaults to 0 */ - if (long_cnt != NULL) { - if (fast_mode) { - assert(PyLong_Check(long_cnt)); - cnt = PyLong_AsSsize_t(long_cnt); - if (cnt == -1 && PyErr_Occurred()) { - PyErr_Clear(); - fast_mode = 0; - } - } - } else { - cnt = 0; - long_cnt = _PyLong_Zero; - } - Py_INCREF(long_cnt); - - /* If not specified, step defaults to 1 */ - if (long_step == NULL) - long_step = _PyLong_One; - Py_INCREF(long_step); - - assert(long_cnt != NULL && long_step != NULL); - - /* Fast mode only works when the step is 1 */ - if (fast_mode) { - assert(PyLong_Check(long_step)); - step = PyLong_AsLong(long_step); - if (step != 1) { - fast_mode = 0; - if (step == -1 && PyErr_Occurred()) - PyErr_Clear(); - } - } - - if (fast_mode) - Py_CLEAR(long_cnt); - else - cnt = PY_SSIZE_T_MAX; - - assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && fast_mode) || - (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && !fast_mode)); - assert(!fast_mode || - (PyLong_Check(long_step) && PyLong_AS_LONG(long_step) == 1)); - - /* create countobject structure */ - lz = (countobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_XDECREF(long_cnt); +{ + countobject *lz; + int fast_mode; + Py_ssize_t cnt = 0; + long step; + + if ((long_cnt != NULL && !PyNumber_Check(long_cnt)) || + (long_step != NULL && !PyNumber_Check(long_step))) { + PyErr_SetString(PyExc_TypeError, "a number is required"); + return NULL; + } + + fast_mode = (long_cnt == NULL || PyLong_Check(long_cnt)) && + (long_step == NULL || PyLong_Check(long_step)); + + /* If not specified, start defaults to 0 */ + if (long_cnt != NULL) { + if (fast_mode) { + assert(PyLong_Check(long_cnt)); + cnt = PyLong_AsSsize_t(long_cnt); + if (cnt == -1 && PyErr_Occurred()) { + PyErr_Clear(); + fast_mode = 0; + } + } + } else { + cnt = 0; + long_cnt = _PyLong_Zero; + } + Py_INCREF(long_cnt); + + /* If not specified, step defaults to 1 */ + if (long_step == NULL) + long_step = _PyLong_One; + Py_INCREF(long_step); + + assert(long_cnt != NULL && long_step != NULL); + + /* Fast mode only works when the step is 1 */ + if (fast_mode) { + assert(PyLong_Check(long_step)); + step = PyLong_AsLong(long_step); + if (step != 1) { + fast_mode = 0; + if (step == -1 && PyErr_Occurred()) + PyErr_Clear(); + } + } + + if (fast_mode) + Py_CLEAR(long_cnt); + else + cnt = PY_SSIZE_T_MAX; + + assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && fast_mode) || + (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && !fast_mode)); + assert(!fast_mode || + (PyLong_Check(long_step) && PyLong_AS_LONG(long_step) == 1)); + + /* create countobject structure */ + lz = (countobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_XDECREF(long_cnt); Py_DECREF(long_step); - return NULL; - } - lz->cnt = cnt; - lz->long_cnt = long_cnt; - lz->long_step = long_step; - - return (PyObject *)lz; -} - -static void -count_dealloc(countobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->long_cnt); - Py_XDECREF(lz->long_step); - Py_TYPE(lz)->tp_free(lz); -} - -static int -count_traverse(countobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->long_cnt); - Py_VISIT(lz->long_step); - return 0; -} - -static PyObject * -count_nextlong(countobject *lz) -{ - PyObject *long_cnt; - PyObject *stepped_up; - - long_cnt = lz->long_cnt; - if (long_cnt == NULL) { - /* Switch to slow_mode */ - long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX); - if (long_cnt == NULL) - return NULL; - } - assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL); - - stepped_up = PyNumber_Add(long_cnt, lz->long_step); - if (stepped_up == NULL) - return NULL; - lz->long_cnt = stepped_up; - return long_cnt; -} - -static PyObject * -count_next(countobject *lz) -{ - if (lz->cnt == PY_SSIZE_T_MAX) - return count_nextlong(lz); - return PyLong_FromSsize_t(lz->cnt++); -} - -static PyObject * -count_repr(countobject *lz) -{ - if (lz->cnt != PY_SSIZE_T_MAX) - return PyUnicode_FromFormat("%s(%zd)", - _PyType_Name(Py_TYPE(lz)), lz->cnt); - - if (PyLong_Check(lz->long_step)) { - long step = PyLong_AsLong(lz->long_step); - if (step == -1 && PyErr_Occurred()) { - PyErr_Clear(); - } - if (step == 1) { - /* Don't display step when it is an integer equal to 1 */ - return PyUnicode_FromFormat("%s(%R)", - _PyType_Name(Py_TYPE(lz)), - lz->long_cnt); - } - } - return PyUnicode_FromFormat("%s(%R, %R)", - _PyType_Name(Py_TYPE(lz)), - lz->long_cnt, lz->long_step); -} - -static PyObject * + return NULL; + } + lz->cnt = cnt; + lz->long_cnt = long_cnt; + lz->long_step = long_step; + + return (PyObject *)lz; +} + +static void +count_dealloc(countobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->long_cnt); + Py_XDECREF(lz->long_step); + Py_TYPE(lz)->tp_free(lz); +} + +static int +count_traverse(countobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->long_cnt); + Py_VISIT(lz->long_step); + return 0; +} + +static PyObject * +count_nextlong(countobject *lz) +{ + PyObject *long_cnt; + PyObject *stepped_up; + + long_cnt = lz->long_cnt; + if (long_cnt == NULL) { + /* Switch to slow_mode */ + long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX); + if (long_cnt == NULL) + return NULL; + } + assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL); + + stepped_up = PyNumber_Add(long_cnt, lz->long_step); + if (stepped_up == NULL) + return NULL; + lz->long_cnt = stepped_up; + return long_cnt; +} + +static PyObject * +count_next(countobject *lz) +{ + if (lz->cnt == PY_SSIZE_T_MAX) + return count_nextlong(lz); + return PyLong_FromSsize_t(lz->cnt++); +} + +static PyObject * +count_repr(countobject *lz) +{ + if (lz->cnt != PY_SSIZE_T_MAX) + return PyUnicode_FromFormat("%s(%zd)", + _PyType_Name(Py_TYPE(lz)), lz->cnt); + + if (PyLong_Check(lz->long_step)) { + long step = PyLong_AsLong(lz->long_step); + if (step == -1 && PyErr_Occurred()) { + PyErr_Clear(); + } + if (step == 1) { + /* Don't display step when it is an integer equal to 1 */ + return PyUnicode_FromFormat("%s(%R)", + _PyType_Name(Py_TYPE(lz)), + lz->long_cnt); + } + } + return PyUnicode_FromFormat("%s(%R, %R)", + _PyType_Name(Py_TYPE(lz)), + lz->long_cnt, lz->long_step); +} + +static PyObject * count_reduce(countobject *lz, PyObject *Py_UNUSED(ignored)) -{ - if (lz->cnt == PY_SSIZE_T_MAX) - return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); - return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); -} - -static PyMethodDef count_methods[] = { - {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, - reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject count_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.count", /* tp_name */ - sizeof(countobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)count_dealloc, /* tp_dealloc */ +{ + if (lz->cnt == PY_SSIZE_T_MAX) + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); + return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); +} + +static PyMethodDef count_methods[] = { + {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, + reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject count_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.count", /* tp_name */ + sizeof(countobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)count_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)count_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + (reprfunc)count_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ itertools_count__doc__, /* tp_doc */ - (traverseproc)count_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)count_next, /* tp_iternext */ - count_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ + (traverseproc)count_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)count_next, /* tp_iternext */ + count_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ itertools_count, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* repeat object ************************************************************/ - -typedef struct { - PyObject_HEAD - PyObject *element; - Py_ssize_t cnt; -} repeatobject; - -static PyTypeObject repeat_type; - -static PyObject * -repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - repeatobject *ro; - PyObject *element; + PyObject_GC_Del, /* tp_free */ +}; + + +/* repeat object ************************************************************/ + +typedef struct { + PyObject_HEAD + PyObject *element; + Py_ssize_t cnt; +} repeatobject; + +static PyTypeObject repeat_type; + +static PyObject * +repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + repeatobject *ro; + PyObject *element; Py_ssize_t cnt = -1, n_args; - static char *kwargs[] = {"object", "times", NULL}; - + static char *kwargs[] = {"object", "times", NULL}; + n_args = PyTuple_GET_SIZE(args); if (kwds != NULL) n_args += PyDict_GET_SIZE(kwds); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs, - &element, &cnt)) - return NULL; - /* Does user supply times argument? */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs, + &element, &cnt)) + return NULL; + /* Does user supply times argument? */ if (n_args == 2 && cnt < 0) - cnt = 0; - - ro = (repeatobject *)type->tp_alloc(type, 0); - if (ro == NULL) - return NULL; - Py_INCREF(element); - ro->element = element; - ro->cnt = cnt; - return (PyObject *)ro; -} - -static void -repeat_dealloc(repeatobject *ro) -{ - PyObject_GC_UnTrack(ro); - Py_XDECREF(ro->element); - Py_TYPE(ro)->tp_free(ro); -} - -static int -repeat_traverse(repeatobject *ro, visitproc visit, void *arg) -{ - Py_VISIT(ro->element); - return 0; -} - -static PyObject * -repeat_next(repeatobject *ro) -{ - if (ro->cnt == 0) - return NULL; - if (ro->cnt > 0) - ro->cnt--; - Py_INCREF(ro->element); - return ro->element; -} - -static PyObject * -repeat_repr(repeatobject *ro) -{ - if (ro->cnt == -1) - return PyUnicode_FromFormat("%s(%R)", - _PyType_Name(Py_TYPE(ro)), ro->element); - else - return PyUnicode_FromFormat("%s(%R, %zd)", - _PyType_Name(Py_TYPE(ro)), ro->element, - ro->cnt); -} - -static PyObject * + cnt = 0; + + ro = (repeatobject *)type->tp_alloc(type, 0); + if (ro == NULL) + return NULL; + Py_INCREF(element); + ro->element = element; + ro->cnt = cnt; + return (PyObject *)ro; +} + +static void +repeat_dealloc(repeatobject *ro) +{ + PyObject_GC_UnTrack(ro); + Py_XDECREF(ro->element); + Py_TYPE(ro)->tp_free(ro); +} + +static int +repeat_traverse(repeatobject *ro, visitproc visit, void *arg) +{ + Py_VISIT(ro->element); + return 0; +} + +static PyObject * +repeat_next(repeatobject *ro) +{ + if (ro->cnt == 0) + return NULL; + if (ro->cnt > 0) + ro->cnt--; + Py_INCREF(ro->element); + return ro->element; +} + +static PyObject * +repeat_repr(repeatobject *ro) +{ + if (ro->cnt == -1) + return PyUnicode_FromFormat("%s(%R)", + _PyType_Name(Py_TYPE(ro)), ro->element); + else + return PyUnicode_FromFormat("%s(%R, %zd)", + _PyType_Name(Py_TYPE(ro)), ro->element, + ro->cnt); +} + +static PyObject * repeat_len(repeatobject *ro, PyObject *Py_UNUSED(ignored)) -{ - if (ro->cnt == -1) { - PyErr_SetString(PyExc_TypeError, "len() of unsized object"); - return NULL; - } - return PyLong_FromSize_t(ro->cnt); -} - -PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); - -static PyObject * +{ + if (ro->cnt == -1) { + PyErr_SetString(PyExc_TypeError, "len() of unsized object"); + return NULL; + } + return PyLong_FromSize_t(ro->cnt); +} + +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); + +static PyObject * repeat_reduce(repeatobject *ro, PyObject *Py_UNUSED(ignored)) -{ - /* unpickle this so that a new repeat iterator is constructed with an - * object, then call __setstate__ on it to set cnt - */ - if (ro->cnt >= 0) - return Py_BuildValue("O(On)", Py_TYPE(ro), ro->element, ro->cnt); - else - return Py_BuildValue("O(O)", Py_TYPE(ro), ro->element); -} - -static PyMethodDef repeat_methods[] = { - {"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc}, - {"__reduce__", (PyCFunction)repeat_reduce, METH_NOARGS, reduce_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(repeat_doc, -"repeat(object [,times]) -> create an iterator which returns the object\n\ -for the specified number of times. If not specified, returns the object\n\ -endlessly."); - -static PyTypeObject repeat_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.repeat", /* tp_name */ - sizeof(repeatobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)repeat_dealloc, /* tp_dealloc */ +{ + /* unpickle this so that a new repeat iterator is constructed with an + * object, then call __setstate__ on it to set cnt + */ + if (ro->cnt >= 0) + return Py_BuildValue("O(On)", Py_TYPE(ro), ro->element, ro->cnt); + else + return Py_BuildValue("O(O)", Py_TYPE(ro), ro->element); +} + +static PyMethodDef repeat_methods[] = { + {"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc}, + {"__reduce__", (PyCFunction)repeat_reduce, METH_NOARGS, reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(repeat_doc, +"repeat(object [,times]) -> create an iterator which returns the object\n\ +for the specified number of times. If not specified, returns the object\n\ +endlessly."); + +static PyTypeObject repeat_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.repeat", /* tp_name */ + sizeof(repeatobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)repeat_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)repeat_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - repeat_doc, /* tp_doc */ - (traverseproc)repeat_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)repeat_next, /* tp_iternext */ - repeat_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - repeat_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* ziplongest object *********************************************************/ - -typedef struct { - PyObject_HEAD - Py_ssize_t tuplesize; - Py_ssize_t numactive; - PyObject *ittuple; /* tuple of iterators */ - PyObject *result; - PyObject *fillvalue; -} ziplongestobject; - -static PyTypeObject ziplongest_type; - -static PyObject * -zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ + (reprfunc)repeat_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + repeat_doc, /* tp_doc */ + (traverseproc)repeat_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)repeat_next, /* tp_iternext */ + repeat_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + repeat_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* ziplongest object *********************************************************/ + +typedef struct { + PyObject_HEAD + Py_ssize_t tuplesize; + Py_ssize_t numactive; + PyObject *ittuple; /* tuple of iterators */ + PyObject *result; + PyObject *fillvalue; +} ziplongestobject; + +static PyTypeObject ziplongest_type; + +static PyObject * +zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ _Py_IDENTIFIER(fillvalue); - ziplongestobject *lz; - Py_ssize_t i; - PyObject *ittuple; /* tuple of iterators */ - PyObject *result; - PyObject *fillvalue = Py_None; - Py_ssize_t tuplesize; - - if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_GET_SIZE(kwds) > 0) { + ziplongestobject *lz; + Py_ssize_t i; + PyObject *ittuple; /* tuple of iterators */ + PyObject *result; + PyObject *fillvalue = Py_None; + Py_ssize_t tuplesize; + + if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_GET_SIZE(kwds) > 0) { fillvalue = NULL; if (PyDict_GET_SIZE(kwds) == 1) { fillvalue = _PyDict_GetItemIdWithError(kwds, &PyId_fillvalue); @@ -4428,318 +4428,318 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyErr_SetString(PyExc_TypeError, "zip_longest() got an unexpected keyword argument"); } - return NULL; - } - } - - /* args must be a tuple */ - assert(PyTuple_Check(args)); - tuplesize = PyTuple_GET_SIZE(args); - - /* obtain iterators */ - ittuple = PyTuple_New(tuplesize); - if (ittuple == NULL) - return NULL; - for (i=0; i < tuplesize; i++) { - PyObject *item = PyTuple_GET_ITEM(args, i); - PyObject *it = PyObject_GetIter(item); - if (it == NULL) { - Py_DECREF(ittuple); - return NULL; - } - PyTuple_SET_ITEM(ittuple, i, it); - } - - /* create a result holder */ - result = PyTuple_New(tuplesize); - if (result == NULL) { - Py_DECREF(ittuple); - return NULL; - } - for (i=0 ; i < tuplesize ; i++) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(result, i, Py_None); - } - - /* create ziplongestobject structure */ - lz = (ziplongestobject *)type->tp_alloc(type, 0); - if (lz == NULL) { - Py_DECREF(ittuple); - Py_DECREF(result); - return NULL; - } - lz->ittuple = ittuple; - lz->tuplesize = tuplesize; - lz->numactive = tuplesize; - lz->result = result; - Py_INCREF(fillvalue); - lz->fillvalue = fillvalue; - return (PyObject *)lz; -} - -static void -zip_longest_dealloc(ziplongestobject *lz) -{ - PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->ittuple); - Py_XDECREF(lz->result); - Py_XDECREF(lz->fillvalue); - Py_TYPE(lz)->tp_free(lz); -} - -static int -zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg) -{ - Py_VISIT(lz->ittuple); - Py_VISIT(lz->result); - Py_VISIT(lz->fillvalue); - return 0; -} - -static PyObject * -zip_longest_next(ziplongestobject *lz) -{ - Py_ssize_t i; - Py_ssize_t tuplesize = lz->tuplesize; - PyObject *result = lz->result; - PyObject *it; - PyObject *item; - PyObject *olditem; - - if (tuplesize == 0) - return NULL; - if (lz->numactive == 0) - return NULL; - if (Py_REFCNT(result) == 1) { - Py_INCREF(result); - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); - if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - } else { - item = PyIter_Next(it); - if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0 || PyErr_Occurred()) { - lz->numactive = 0; - Py_DECREF(result); - return NULL; - } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - PyTuple_SET_ITEM(lz->ittuple, i, NULL); - Py_DECREF(it); - } - } - } - olditem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, item); - Py_DECREF(olditem); - } + return NULL; + } + } + + /* args must be a tuple */ + assert(PyTuple_Check(args)); + tuplesize = PyTuple_GET_SIZE(args); + + /* obtain iterators */ + ittuple = PyTuple_New(tuplesize); + if (ittuple == NULL) + return NULL; + for (i=0; i < tuplesize; i++) { + PyObject *item = PyTuple_GET_ITEM(args, i); + PyObject *it = PyObject_GetIter(item); + if (it == NULL) { + Py_DECREF(ittuple); + return NULL; + } + PyTuple_SET_ITEM(ittuple, i, it); + } + + /* create a result holder */ + result = PyTuple_New(tuplesize); + if (result == NULL) { + Py_DECREF(ittuple); + return NULL; + } + for (i=0 ; i < tuplesize ; i++) { + Py_INCREF(Py_None); + PyTuple_SET_ITEM(result, i, Py_None); + } + + /* create ziplongestobject structure */ + lz = (ziplongestobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(ittuple); + Py_DECREF(result); + return NULL; + } + lz->ittuple = ittuple; + lz->tuplesize = tuplesize; + lz->numactive = tuplesize; + lz->result = result; + Py_INCREF(fillvalue); + lz->fillvalue = fillvalue; + return (PyObject *)lz; +} + +static void +zip_longest_dealloc(ziplongestobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->ittuple); + Py_XDECREF(lz->result); + Py_XDECREF(lz->fillvalue); + Py_TYPE(lz)->tp_free(lz); +} + +static int +zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->ittuple); + Py_VISIT(lz->result); + Py_VISIT(lz->fillvalue); + return 0; +} + +static PyObject * +zip_longest_next(ziplongestobject *lz) +{ + Py_ssize_t i; + Py_ssize_t tuplesize = lz->tuplesize; + PyObject *result = lz->result; + PyObject *it; + PyObject *item; + PyObject *olditem; + + if (tuplesize == 0) + return NULL; + if (lz->numactive == 0) + return NULL; + if (Py_REFCNT(result) == 1) { + Py_INCREF(result); + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); + if (it == NULL) { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + } else { + item = PyIter_Next(it); + if (item == NULL) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + PyTuple_SET_ITEM(lz->ittuple, i, NULL); + Py_DECREF(it); + } + } + } + olditem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, item); + Py_DECREF(olditem); + } // bpo-42536: The GC may have untracked this result tuple. Since we're // recycling it, make sure it's tracked again: if (!_PyObject_GC_IS_TRACKED(result)) { _PyObject_GC_TRACK(result); } - } else { - result = PyTuple_New(tuplesize); - if (result == NULL) - return NULL; - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); - if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - } else { - item = PyIter_Next(it); - if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0 || PyErr_Occurred()) { - lz->numactive = 0; - Py_DECREF(result); - return NULL; - } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - PyTuple_SET_ITEM(lz->ittuple, i, NULL); - Py_DECREF(it); - } - } - } - PyTuple_SET_ITEM(result, i, item); - } - } - return result; -} - -static PyObject * + } else { + result = PyTuple_New(tuplesize); + if (result == NULL) + return NULL; + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); + if (it == NULL) { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + } else { + item = PyIter_Next(it); + if (item == NULL) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + PyTuple_SET_ITEM(lz->ittuple, i, NULL); + Py_DECREF(it); + } + } + } + PyTuple_SET_ITEM(result, i, item); + } + } + return result; +} + +static PyObject * zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored)) -{ - - /* Create a new tuple with empty sequences where appropriate to pickle. - * Then use setstate to set the fillvalue - */ - int i; - PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple)); - - if (args == NULL) - return NULL; - for (i=0; iittuple); i++) { - PyObject *elem = PyTuple_GET_ITEM(lz->ittuple, i); - if (elem == NULL) { - elem = PyTuple_New(0); - if (elem == NULL) { - Py_DECREF(args); - return NULL; - } - } else - Py_INCREF(elem); - PyTuple_SET_ITEM(args, i, elem); - } - return Py_BuildValue("ONO", Py_TYPE(lz), args, lz->fillvalue); -} - -static PyObject * -zip_longest_setstate(ziplongestobject *lz, PyObject *state) -{ - Py_INCREF(state); - Py_XSETREF(lz->fillvalue, state); - Py_RETURN_NONE; -} - -static PyMethodDef zip_longest_methods[] = { - {"__reduce__", (PyCFunction)zip_longest_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)zip_longest_setstate, METH_O, - setstate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(zip_longest_doc, -"zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object\n\ -\n\ -Return a zip_longest object whose .__next__() method returns a tuple where\n\ -the i-th element comes from the i-th iterable argument. The .__next__()\n\ -method continues until the longest iterable in the argument sequence\n\ -is exhausted and then it raises StopIteration. When the shorter iterables\n\ -are exhausted, the fillvalue is substituted in their place. The fillvalue\n\ -defaults to None or can be specified by a keyword argument.\n\ -"); - -static PyTypeObject ziplongest_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.zip_longest", /* tp_name */ - sizeof(ziplongestobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)zip_longest_dealloc, /* tp_dealloc */ +{ + + /* Create a new tuple with empty sequences where appropriate to pickle. + * Then use setstate to set the fillvalue + */ + int i; + PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple)); + + if (args == NULL) + return NULL; + for (i=0; iittuple); i++) { + PyObject *elem = PyTuple_GET_ITEM(lz->ittuple, i); + if (elem == NULL) { + elem = PyTuple_New(0); + if (elem == NULL) { + Py_DECREF(args); + return NULL; + } + } else + Py_INCREF(elem); + PyTuple_SET_ITEM(args, i, elem); + } + return Py_BuildValue("ONO", Py_TYPE(lz), args, lz->fillvalue); +} + +static PyObject * +zip_longest_setstate(ziplongestobject *lz, PyObject *state) +{ + Py_INCREF(state); + Py_XSETREF(lz->fillvalue, state); + Py_RETURN_NONE; +} + +static PyMethodDef zip_longest_methods[] = { + {"__reduce__", (PyCFunction)zip_longest_reduce, METH_NOARGS, + reduce_doc}, + {"__setstate__", (PyCFunction)zip_longest_setstate, METH_O, + setstate_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyDoc_STRVAR(zip_longest_doc, +"zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object\n\ +\n\ +Return a zip_longest object whose .__next__() method returns a tuple where\n\ +the i-th element comes from the i-th iterable argument. The .__next__()\n\ +method continues until the longest iterable in the argument sequence\n\ +is exhausted and then it raises StopIteration. When the shorter iterables\n\ +are exhausted, the fillvalue is substituted in their place. The fillvalue\n\ +defaults to None or can be specified by a keyword argument.\n\ +"); + +static PyTypeObject ziplongest_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "itertools.zip_longest", /* tp_name */ + sizeof(ziplongestobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)zip_longest_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - zip_longest_doc, /* tp_doc */ - (traverseproc)zip_longest_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)zip_longest_next, /* tp_iternext */ - zip_longest_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - zip_longest_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - -/* module level code ********************************************************/ - -PyDoc_STRVAR(module_doc, -"Functional tools for creating and using iterators.\n\ -\n\ -Infinite iterators:\n\ -count(start=0, step=1) --> start, start+step, start+2*step, ...\n\ -cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\ -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ -\n\ -Iterators terminating on the shortest input sequence:\n\ -accumulate(p[, func]) --> p0, p0+p1, p0+p1+p2\n\ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + zip_longest_doc, /* tp_doc */ + (traverseproc)zip_longest_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)zip_longest_next, /* tp_iternext */ + zip_longest_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + zip_longest_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + +/* module level code ********************************************************/ + +PyDoc_STRVAR(module_doc, +"Functional tools for creating and using iterators.\n\ +\n\ +Infinite iterators:\n\ +count(start=0, step=1) --> start, start+step, start+2*step, ...\n\ +cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\ +repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ +\n\ +Iterators terminating on the shortest input sequence:\n\ +accumulate(p[, func]) --> p0, p0+p1, p0+p1+p2\n\ chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n\ chain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ...\n\ -compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\ -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\ -filterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\ -islice(seq, [start,] stop [, step]) --> elements from\n\ - seq[start:stop:step]\n\ -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\ -takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ +compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\ +dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ +groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\ +filterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\ +islice(seq, [start,] stop [, step]) --> elements from\n\ + seq[start:stop:step]\n\ +starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ +tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\ +takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n\ -\n\ -Combinatoric generators:\n\ -product(p, q, ... [repeat=1]) --> cartesian product\n\ -permutations(p[, r])\n\ -combinations(p, r)\n\ -combinations_with_replacement(p, r)\n\ -"); - +\n\ +Combinatoric generators:\n\ +product(p, q, ... [repeat=1]) --> cartesian product\n\ +permutations(p[, r])\n\ +combinations(p, r)\n\ +combinations_with_replacement(p, r)\n\ +"); + static int itertoolsmodule_exec(PyObject *m) -{ - PyTypeObject *typelist[] = { - &accumulate_type, - &combinations_type, - &cwr_type, - &cycle_type, - &dropwhile_type, - &takewhile_type, - &islice_type, - &starmap_type, - &chain_type, - &compress_type, - &filterfalse_type, - &count_type, - &ziplongest_type, - &permutations_type, - &product_type, - &repeat_type, - &groupby_type, - &_grouper_type, - &tee_type, +{ + PyTypeObject *typelist[] = { + &accumulate_type, + &combinations_type, + &cwr_type, + &cycle_type, + &dropwhile_type, + &takewhile_type, + &islice_type, + &starmap_type, + &chain_type, + &compress_type, + &filterfalse_type, + &count_type, + &ziplongest_type, + &permutations_type, + &product_type, + &repeat_type, + &groupby_type, + &_grouper_type, + &tee_type, &teedataobject_type - }; - + }; + Py_SET_TYPE(&teedataobject_type, &PyType_Type); - + for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { if (PyModule_AddType(m, typelist[i]) < 0) { return -1; } - } - + } + return 0; -} +} static struct PyModuleDef_Slot itertoolsmodule_slots[] = { {Py_mod_exec, itertoolsmodule_exec}, diff --git a/contrib/tools/python3/src/Modules/main.c b/contrib/tools/python3/src/Modules/main.c index 1eec0f96c09..443408a3d33 100644 --- a/contrib/tools/python3/src/Modules/main.c +++ b/contrib/tools/python3/src/Modules/main.c @@ -1,81 +1,81 @@ -/* Python interpreter main program */ - -#include "Python.h" +/* Python interpreter main program */ + +#include "Python.h" #include "pycore_initconfig.h" // _PyArgv #include "pycore_interp.h" // _PyInterpreterState.sysdict #include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() #include "pycore_pylifecycle.h" // _Py_PreInitializeFromPyArgv() #include "pycore_pystate.h" // _PyInterpreterState_GET() - + /* Includes for exit_sigint() */ #include // perror() #ifdef HAVE_SIGNAL_H # include // SIGINT -#endif +#endif #if defined(HAVE_GETPID) && defined(HAVE_UNISTD_H) # include // getpid() #endif #ifdef MS_WINDOWS # include // STATUS_CONTROL_C_EXIT -#endif +#endif /* End of includes for exit_sigint() */ - -#define COPYRIGHT \ - "Type \"help\", \"copyright\", \"credits\" or \"license\" " \ - "for more information." - -#ifdef __cplusplus -extern "C" { -#endif - + +#define COPYRIGHT \ + "Type \"help\", \"copyright\", \"credits\" or \"license\" " \ + "for more information." + +#ifdef __cplusplus +extern "C" { +#endif + /* --- pymain_init() ---------------------------------------------- */ - + static PyStatus pymain_init(const _PyArgv *args) { PyStatus status; - + status = _PyRuntime_Initialize(); if (_PyStatus_EXCEPTION(status)) { return status; } - + PyPreConfig preconfig; PyPreConfig_InitPythonConfig(&preconfig); - + status = _Py_PreInitializeFromPyArgv(&preconfig, args); if (_PyStatus_EXCEPTION(status)) { return status; - } - + } + PyConfig config; PyConfig_InitPythonConfig(&config); - config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ - + config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ + /* pass NULL as the config: config is read from command line arguments, environment variables, configuration files */ if (args->use_bytes_argv) { status = PyConfig_SetBytesArgv(&config, args->argc, args->bytes_argv); - } - else { + } + else { status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv); - } + } if (_PyStatus_EXCEPTION(status)) { goto done; - } - + } + status = Py_InitializeFromConfig(&config); if (_PyStatus_EXCEPTION(status)) { goto done; - } + } status = _PyStatus_OK(); - + done: PyConfig_Clear(&config); return status; } - - + + /* --- pymain_run_python() ---------------------------------------- */ /* Non-zero if filename, command (-c) or module (-m) is set @@ -85,200 +85,200 @@ static inline int config_run_code(const PyConfig *config) return (config->run_command != NULL || config->run_filename != NULL || config->run_module != NULL); -} - - +} + + /* Return non-zero is stdin is a TTY or if -i command line option is used */ static int stdin_is_interactive(const PyConfig *config) -{ +{ return (isatty(fileno(stdin)) || config->interactive); } - - + + /* Display the current Python exception and return an exitcode */ static int pymain_err_print(int *exitcode_p) -{ +{ int exitcode; if (_Py_HandleSystemExit(&exitcode)) { *exitcode_p = exitcode; return 1; - } - - PyErr_Print(); + } + + PyErr_Print(); return 0; -} - - -static int +} + + +static int pymain_exit_err_print(void) -{ +{ int exitcode = 1; pymain_err_print(&exitcode); return exitcode; -} - +} + /* Write an exitcode into *exitcode and return 1 if we have to exit Python. Return 0 otherwise. */ static int pymain_get_importer(const wchar_t *filename, PyObject **importer_p, int *exitcode) -{ - PyObject *sys_path0 = NULL, *importer; - - sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename)); - if (sys_path0 == NULL) { - goto error; - } - - importer = PyImport_GetImporter(sys_path0); - if (importer == NULL) { - goto error; - } - - if (importer == Py_None) { - Py_DECREF(sys_path0); - Py_DECREF(importer); +{ + PyObject *sys_path0 = NULL, *importer; + + sys_path0 = PyUnicode_FromWideChar(filename, wcslen(filename)); + if (sys_path0 == NULL) { + goto error; + } + + importer = PyImport_GetImporter(sys_path0); + if (importer == NULL) { + goto error; + } + + if (importer == Py_None) { + Py_DECREF(sys_path0); + Py_DECREF(importer); return 0; - } - - Py_DECREF(importer); + } + + Py_DECREF(importer); *importer_p = sys_path0; return 0; + +error: + Py_XDECREF(sys_path0); -error: - Py_XDECREF(sys_path0); - - PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n"); + PySys_WriteStderr("Failed checking if argv[0] is an import path entry\n"); return pymain_err_print(exitcode); -} - - -static int +} + + +static int pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0) -{ +{ _Py_IDENTIFIER(path); PyObject *sys_path; PyObject *sysdict = interp->sysdict; if (sysdict != NULL) { sys_path = _PyDict_GetItemIdWithError(sysdict, &PyId_path); if (sys_path == NULL && PyErr_Occurred()) { - return -1; - } - } - else { + return -1; + } + } + else { sys_path = NULL; - } - if (sys_path == NULL) { - PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path"); + } + if (sys_path == NULL) { + PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path"); return -1; - } - + } + if (PyList_Insert(sys_path, 0, path0)) { - return -1; - } - return 0; -} - - + return -1; + } + return 0; +} + + static void pymain_header(const PyConfig *config) -{ +{ if (config->quiet) { return; - } - + } + if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) { return; - } - + } + fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform()); if (config->site_import) { fprintf(stderr, "%s\n", COPYRIGHT); - } -} - - -static void + } +} + + +static void pymain_import_readline(const PyConfig *config) -{ +{ if (config->isolated) { return; - } + } if (!config->inspect && config_run_code(config)) { return; - } + } if (!isatty(fileno(stdin))) { return; - } - + } + PyObject *mod = PyImport_ImportModule("readline"); if (mod == NULL) { PyErr_Clear(); - } - else { + } + else { Py_DECREF(mod); - } -} - - + } +} + + static int pymain_run_command(wchar_t *command, PyCompilerFlags *cf) -{ +{ PyObject *unicode, *bytes; int ret; - + unicode = PyUnicode_FromWideChar(command, -1); if (unicode == NULL) { goto error; - } - + } + if (PySys_Audit("cpython.run_command", "O", unicode) < 0) { return pymain_exit_err_print(); - } - + } + bytes = PyUnicode_AsUTF8String(unicode); Py_DECREF(unicode); if (bytes == NULL) { goto error; - } - + } + ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), cf); Py_DECREF(bytes); return (ret != 0); - + error: PySys_WriteStderr("Unable to decode the command from the command line:\n"); return pymain_exit_err_print(); -} - - -static int +} + + +static int pymain_run_module(const wchar_t *modname, int set_argv0) -{ +{ PyObject *module, *runpy, *runmodule, *runargs, *result; if (PySys_Audit("cpython.run_module", "u", modname) < 0) { return pymain_exit_err_print(); - } + } runpy = PyImport_ImportModule("runpy"); if (runpy == NULL) { fprintf(stderr, "Could not import runpy module\n"); return pymain_exit_err_print(); - } + } runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main"); if (runmodule == NULL) { fprintf(stderr, "Could not access runpy._run_module_as_main\n"); Py_DECREF(runpy); return pymain_exit_err_print(); - } + } module = PyUnicode_FromWideChar(modname, wcslen(modname)); if (module == NULL) { fprintf(stderr, "Could not convert module name to unicode\n"); Py_DECREF(runpy); Py_DECREF(runmodule); return pymain_exit_err_print(); - } + } runargs = PyTuple_Pack(2, module, set_argv0 ? Py_True : Py_False); if (runargs == NULL) { fprintf(stderr, @@ -287,7 +287,7 @@ pymain_run_module(const wchar_t *modname, int set_argv0) Py_DECREF(runmodule); Py_DECREF(module); return pymain_exit_err_print(); - } + } _Py_UnhandledKeyboardInterrupt = 0; result = PyObject_Call(runmodule, runargs, NULL); if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) { @@ -299,327 +299,327 @@ pymain_run_module(const wchar_t *modname, int set_argv0) Py_DECREF(runargs); if (result == NULL) { return pymain_exit_err_print(); - } + } Py_DECREF(result); - return 0; -} - - -static int + return 0; +} + + +static int pymain_run_file(const PyConfig *config, PyCompilerFlags *cf) -{ +{ const wchar_t *filename = config->run_filename; if (PySys_Audit("cpython.run_file", "u", filename) < 0) { return pymain_exit_err_print(); - } + } FILE *fp = _Py_wfopen(filename, L"rb"); - if (fp == NULL) { - char *cfilename_buffer; - const char *cfilename; - int err = errno; + if (fp == NULL) { + char *cfilename_buffer; + const char *cfilename; + int err = errno; cfilename_buffer = _Py_EncodeLocaleRaw(filename, NULL); - if (cfilename_buffer != NULL) - cfilename = cfilename_buffer; - else - cfilename = ""; - fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n", + if (cfilename_buffer != NULL) + cfilename = cfilename_buffer; + else + cfilename = ""; + fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n", config->program_name, cfilename, err, strerror(err)); - PyMem_RawFree(cfilename_buffer); + PyMem_RawFree(cfilename_buffer); return 2; - } - + } + if (config->skip_source_first_line) { - int ch; + int ch; /* Push back first newline so line numbers remain the same */ - while ((ch = getc(fp)) != EOF) { - if (ch == '\n') { - (void)ungetc(ch, fp); - break; - } - } - } - - struct _Py_stat_struct sb; + while ((ch = getc(fp)) != EOF) { + if (ch == '\n') { + (void)ungetc(ch, fp); + break; + } + } + } + + struct _Py_stat_struct sb; if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) { - fprintf(stderr, - "%ls: '%ls' is a directory, cannot continue\n", + fprintf(stderr, + "%ls: '%ls' is a directory, cannot continue\n", config->program_name, filename); - fclose(fp); - return 1; - } - + fclose(fp); + return 1; + } + /* call pending calls like signal handlers (SIGINT) */ if (Py_MakePendingCalls() == -1) { fclose(fp); return pymain_exit_err_print(); - } - + } + PyObject *unicode, *bytes = NULL; const char *filename_str; - + unicode = PyUnicode_FromWideChar(filename, wcslen(filename)); if (unicode != NULL) { bytes = PyUnicode_EncodeFSDefault(unicode); Py_DECREF(unicode); - } + } if (bytes != NULL) { filename_str = PyBytes_AsString(bytes); - } + } else { PyErr_Clear(); filename_str = ""; - } - + } + /* PyRun_AnyFileExFlags(closeit=1) calls fclose(fp) before running code */ int run = PyRun_AnyFileExFlags(fp, filename_str, 1, cf); Py_XDECREF(bytes); return (run != 0); -} - - -static int +} + + +static int pymain_run_startup(PyConfig *config, PyCompilerFlags *cf, int *exitcode) -{ +{ int ret; PyObject *startup_obj = NULL; if (!config->use_environment) { return 0; - } + } #ifdef MS_WINDOWS const wchar_t *wstartup = _wgetenv(L"PYTHONSTARTUP"); if (wstartup == NULL || wstartup[0] == L'\0') { return 0; - } + } PyObject *startup_bytes = NULL; startup_obj = PyUnicode_FromWideChar(wstartup, wcslen(wstartup)); if (startup_obj == NULL) { goto error; - } + } startup_bytes = PyUnicode_EncodeFSDefault(startup_obj); if (startup_bytes == NULL) { goto error; - } + } const char *startup = PyBytes_AS_STRING(startup_bytes); #else const char *startup = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP"); if (startup == NULL) { return 0; - } + } startup_obj = PyUnicode_DecodeFSDefault(startup); if (startup_obj == NULL) { goto error; - } + } #endif if (PySys_Audit("cpython.run_startup", "O", startup_obj) < 0) { goto error; - } - -#ifdef MS_WINDOWS + } + +#ifdef MS_WINDOWS FILE *fp = _Py_wfopen(wstartup, L"r"); #else FILE *fp = _Py_fopen(startup, "r"); -#endif +#endif if (fp == NULL) { int save_errno = errno; PyErr_Clear(); PySys_WriteStderr("Could not open PYTHONSTARTUP\n"); - + errno = save_errno; PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, startup_obj, NULL); goto error; - } - + } + (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf); PyErr_Clear(); fclose(fp); ret = 0; - + done: #ifdef MS_WINDOWS Py_XDECREF(startup_bytes); #endif Py_XDECREF(startup_obj); return ret; - + error: ret = pymain_err_print(exitcode); goto done; -} - - +} + + /* Write an exitcode into *exitcode and return 1 if we have to exit Python. Return 0 otherwise. */ -static int +static int pymain_run_interactive_hook(int *exitcode) -{ +{ PyObject *sys, *hook, *result; sys = PyImport_ImportModule("sys"); if (sys == NULL) { goto error; - } - + } + hook = PyObject_GetAttrString(sys, "__interactivehook__"); Py_DECREF(sys); if (hook == NULL) { PyErr_Clear(); return 0; - } - + } + if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) { goto error; - } - + } + result = _PyObject_CallNoArg(hook); Py_DECREF(hook); if (result == NULL) { goto error; - } + } Py_DECREF(result); - + return 0; - + error: PySys_WriteStderr("Failed calling sys.__interactivehook__\n"); return pymain_err_print(exitcode); -} - - -static int +} + + +static int pymain_run_stdin(PyConfig *config, PyCompilerFlags *cf) -{ +{ if (stdin_is_interactive(config)) { config->inspect = 0; Py_InspectFlag = 0; /* do exit on SystemExit */ - + int exitcode; if (pymain_run_startup(config, cf, &exitcode)) { return exitcode; - } - + } + if (pymain_run_interactive_hook(&exitcode)) { return exitcode; - } - } - + } + } + /* call pending calls like signal handlers (SIGINT) */ if (Py_MakePendingCalls() == -1) { return pymain_exit_err_print(); - } - + } + if (PySys_Audit("cpython.run_stdin", NULL) < 0) { return pymain_exit_err_print(); - } - + } + int run = PyRun_AnyFileExFlags(stdin, "", 0, cf); return (run != 0); -} - - +} + + static void pymain_repl(PyConfig *config, PyCompilerFlags *cf, int *exitcode) -{ +{ /* Check this environment variable at the end, to give programs the opportunity to set it from Python. */ if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) { config->inspect = 1; Py_InspectFlag = 1; - } - + } + if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) { return; - } - + } + config->inspect = 0; Py_InspectFlag = 0; if (pymain_run_interactive_hook(exitcode)) { return; - } - + } + int res = PyRun_AnyFileFlags(stdin, "", cf); *exitcode = (res != 0); -} - - +} + + static void pymain_run_python(int *exitcode) -{ +{ PyInterpreterState *interp = _PyInterpreterState_GET(); /* pymain_run_stdin() modify the config */ PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp); - + PyObject *main_importer_path = NULL; if (config->run_filename != NULL) { /* If filename is a package (ex: directory or ZIP file) which contains __main__.py, main_importer_path is set to filename and will be prepended to sys.path. - + Otherwise, main_importer_path is left unchanged. */ if (pymain_get_importer(config->run_filename, &main_importer_path, exitcode)) { return; - } - } - + } + } + if (main_importer_path != NULL) { if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) { goto error; - } - } + } + } else if (!config->isolated && 0) { // Do not add current directory. PyObject *path0 = NULL; int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0); if (res < 0) { goto error; - } - + } + if (res > 0) { if (pymain_sys_path_add_path0(interp, path0) < 0) { Py_DECREF(path0); goto error; } Py_DECREF(path0); - } - } - + } + } + PyCompilerFlags cf = _PyCompilerFlags_INIT; - + pymain_header(config); pymain_import_readline(config); - + if (config->run_command) { *exitcode = pymain_run_command(config->run_command, &cf); - } + } else if (config->run_module) { *exitcode = pymain_run_module(config->run_module, 1); - } + } else if (main_importer_path != NULL) { *exitcode = pymain_run_module(L"__main__", 0); - } + } else if (config->run_filename != NULL) { *exitcode = pymain_run_file(config, &cf); - } - else { + } + else { *exitcode = pymain_run_stdin(config, &cf); - } - + } + pymain_repl(config, &cf, exitcode); goto done; - + error: *exitcode = pymain_exit_err_print(); - + done: Py_XDECREF(main_importer_path); -} - - +} + + /* --- pymain_main() ---------------------------------------------- */ - -static void + +static void pymain_free(void) -{ +{ _PyImport_Fini2(); - + /* Free global variables which cannot be freed in Py_Finalize(): configuration options set before Py_Initialize() which should remain valid after Py_Finalize(), since @@ -628,12 +628,12 @@ pymain_free(void) _Py_ClearStandardStreamEncoding(); _Py_ClearArgcArgv(); _PyRuntime_Finalize(); -} - - -static int +} + + +static int exit_sigint(void) -{ +{ /* bpo-1054041: We need to exit via the * SIG_DFL handler for SIGINT if KeyboardInterrupt went unhandled. * If we don't, a calling process such as a shell may not know @@ -643,7 +643,7 @@ exit_sigint(void) perror("signal"); /* Impossible in normal environments. */ } else { kill(getpid(), SIGINT); - } + } /* If setting SIG_DFL failed, or kill failed to terminate us, * there isn't much else we can do aside from an error code. */ #endif /* HAVE_GETPID && !MS_WINDOWS */ @@ -654,84 +654,84 @@ exit_sigint(void) #else return SIGINT + 128; #endif /* !MS_WINDOWS */ -} - - +} + + static void _Py_NO_RETURN pymain_exit_error(PyStatus status) -{ +{ if (_PyStatus_IS_EXIT(status)) { /* If it's an error rather than a regular exit, leave Python runtime alive: Py_ExitStatusException() uses the current exception and use sys.stdout in this case. */ pymain_free(); - } + } Py_ExitStatusException(status); -} - - +} + + int Py_RunMain(void) -{ +{ int exitcode = 0; - + pymain_run_python(&exitcode); - + if (Py_FinalizeEx() < 0) { /* Value unlikely to be confused with a non-error exit status or other special meaning */ exitcode = 120; - } - + } + pymain_free(); - + if (_Py_UnhandledKeyboardInterrupt) { exitcode = exit_sigint(); - } - + } + return exitcode; -} - - -static int +} + + +static int pymain_main(_PyArgv *args) -{ +{ PyStatus status = pymain_init(args); if (_PyStatus_IS_EXIT(status)) { pymain_free(); return status.exitcode; - } + } if (_PyStatus_EXCEPTION(status)) { pymain_exit_error(status); - } - + } + return Py_RunMain(); -} - - -int -Py_Main(int argc, wchar_t **argv) -{ +} + + +int +Py_Main(int argc, wchar_t **argv) +{ _PyArgv args = { .argc = argc, .use_bytes_argv = 0, .bytes_argv = NULL, .wchar_argv = argv}; return pymain_main(&args); -} - - -int +} + + +int Py_BytesMain(int argc, char **argv) -{ +{ _PyArgv args = { .argc = argc, .use_bytes_argv = 1, .bytes_argv = argv, .wchar_argv = NULL}; return pymain_main(&args); -} - -#ifdef __cplusplus -} -#endif +} + +#ifdef __cplusplus +} +#endif diff --git a/contrib/tools/python3/src/Modules/mathmodule.c b/contrib/tools/python3/src/Modules/mathmodule.c index 1f16849a3e6..157a7e4858a 100644 --- a/contrib/tools/python3/src/Modules/mathmodule.c +++ b/contrib/tools/python3/src/Modules/mathmodule.c @@ -1,82 +1,82 @@ -/* Math module -- standard C math library functions, pi and e */ - -/* Here are some comments from Tim Peters, extracted from the - discussion attached to http://bugs.python.org/issue1640. They - describe the general aims of the math module with respect to - special values, IEEE-754 floating-point exceptions, and Python - exceptions. - -These are the "spirit of 754" rules: - -1. If the mathematical result is a real number, but of magnitude too -large to approximate by a machine float, overflow is signaled and the -result is an infinity (with the appropriate sign). - -2. If the mathematical result is a real number, but of magnitude too -small to approximate by a machine float, underflow is signaled and the -result is a zero (with the appropriate sign). - -3. At a singularity (a value x such that the limit of f(y) as y -approaches x exists and is an infinity), "divide by zero" is signaled -and the result is an infinity (with the appropriate sign). This is -complicated a little by that the left-side and right-side limits may -not be the same; e.g., 1/x approaches +inf or -inf as x approaches 0 -from the positive or negative directions. In that specific case, the -sign of the zero determines the result of 1/0. - -4. At a point where a function has no defined result in the extended -reals (i.e., the reals plus an infinity or two), invalid operation is -signaled and a NaN is returned. - -And these are what Python has historically /tried/ to do (but not -always successfully, as platform libm behavior varies a lot): - -For #1, raise OverflowError. - -For #2, return a zero (with the appropriate sign if that happens by -accident ;-)). - -For #3 and #4, raise ValueError. It may have made sense to raise -Python's ZeroDivisionError in #3, but historically that's only been -raised for division by zero and mod by zero. - -*/ - -/* - In general, on an IEEE-754 platform the aim is to follow the C99 - standard, including Annex 'F', whenever possible. Where the - standard recommends raising the 'divide-by-zero' or 'invalid' - floating-point exceptions, Python should raise a ValueError. Where - the standard recommends raising 'overflow', Python should raise an - OverflowError. In all other circumstances a value should be - returned. - */ - -#include "Python.h" +/* Math module -- standard C math library functions, pi and e */ + +/* Here are some comments from Tim Peters, extracted from the + discussion attached to http://bugs.python.org/issue1640. They + describe the general aims of the math module with respect to + special values, IEEE-754 floating-point exceptions, and Python + exceptions. + +These are the "spirit of 754" rules: + +1. If the mathematical result is a real number, but of magnitude too +large to approximate by a machine float, overflow is signaled and the +result is an infinity (with the appropriate sign). + +2. If the mathematical result is a real number, but of magnitude too +small to approximate by a machine float, underflow is signaled and the +result is a zero (with the appropriate sign). + +3. At a singularity (a value x such that the limit of f(y) as y +approaches x exists and is an infinity), "divide by zero" is signaled +and the result is an infinity (with the appropriate sign). This is +complicated a little by that the left-side and right-side limits may +not be the same; e.g., 1/x approaches +inf or -inf as x approaches 0 +from the positive or negative directions. In that specific case, the +sign of the zero determines the result of 1/0. + +4. At a point where a function has no defined result in the extended +reals (i.e., the reals plus an infinity or two), invalid operation is +signaled and a NaN is returned. + +And these are what Python has historically /tried/ to do (but not +always successfully, as platform libm behavior varies a lot): + +For #1, raise OverflowError. + +For #2, return a zero (with the appropriate sign if that happens by +accident ;-)). + +For #3 and #4, raise ValueError. It may have made sense to raise +Python's ZeroDivisionError in #3, but historically that's only been +raised for division by zero and mod by zero. + +*/ + +/* + In general, on an IEEE-754 platform the aim is to follow the C99 + standard, including Annex 'F', whenever possible. Where the + standard recommends raising the 'divide-by-zero' or 'invalid' + floating-point exceptions, Python should raise a ValueError. Where + the standard recommends raising 'overflow', Python should raise an + OverflowError. In all other circumstances a value should be + returned. + */ + +#include "Python.h" #include "pycore_dtoa.h" -#include "_math.h" - -#include "clinic/mathmodule.c.h" - -/*[clinic input] -module math -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=76bc7002685dd942]*/ - - -/* - sin(pi*x), giving accurate results for all finite x (especially x - integral or close to an integer). This is here for use in the - reflection formula for the gamma function. It conforms to IEEE - 754-2008 for finite arguments, but not for infinities or nans. -*/ - -static const double pi = 3.141592653589793238462643383279502884197; -static const double logpi = 1.144729885849400174143427351353058711647; -#if !defined(HAVE_ERF) || !defined(HAVE_ERFC) -static const double sqrtpi = 1.772453850905516027298167483341145182798; -#endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */ - +#include "_math.h" + +#include "clinic/mathmodule.c.h" + +/*[clinic input] +module math +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=76bc7002685dd942]*/ + + +/* + sin(pi*x), giving accurate results for all finite x (especially x + integral or close to an integer). This is here for use in the + reflection formula for the gamma function. It conforms to IEEE + 754-2008 for finite arguments, but not for infinities or nans. +*/ + +static const double pi = 3.141592653589793238462643383279502884197; +static const double logpi = 1.144729885849400174143427351353058711647; +#if !defined(HAVE_ERF) || !defined(HAVE_ERFC) +static const double sqrtpi = 1.772453850905516027298167483341145182798; +#endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */ + /* Version of PyFloat_AsDouble() with in-line fast paths for exact floats and integers. Gives a substantial @@ -100,738 +100,738 @@ static const double sqrtpi = 1.772453850905516027298167483341145182798; } \ } -static double -m_sinpi(double x) -{ - double y, r; - int n; - /* this function should only ever be called for finite arguments */ - assert(Py_IS_FINITE(x)); - y = fmod(fabs(x), 2.0); - n = (int)round(2.0*y); - assert(0 <= n && n <= 4); - switch (n) { - case 0: - r = sin(pi*y); - break; - case 1: - r = cos(pi*(y-0.5)); - break; - case 2: - /* N.B. -sin(pi*(y-1.0)) is *not* equivalent: it would give - -0.0 instead of 0.0 when y == 1.0. */ - r = sin(pi*(1.0-y)); - break; - case 3: - r = -cos(pi*(y-1.5)); - break; - case 4: - r = sin(pi*(y-2.0)); - break; - default: - Py_UNREACHABLE(); - } - return copysign(1.0, x)*r; -} - -/* Implementation of the real gamma function. In extensive but non-exhaustive - random tests, this function proved accurate to within <= 10 ulps across the - entire float domain. Note that accuracy may depend on the quality of the - system math functions, the pow function in particular. Special cases - follow C99 annex F. The parameters and method are tailored to platforms - whose double format is the IEEE 754 binary64 format. - - Method: for x > 0.0 we use the Lanczos approximation with parameters N=13 - and g=6.024680040776729583740234375; these parameters are amongst those - used by the Boost library. Following Boost (again), we re-express the - Lanczos sum as a rational function, and compute it that way. The - coefficients below were computed independently using MPFR, and have been - double-checked against the coefficients in the Boost source code. - - For x < 0.0 we use the reflection formula. - - There's one minor tweak that deserves explanation: Lanczos' formula for - Gamma(x) involves computing pow(x+g-0.5, x-0.5) / exp(x+g-0.5). For many x - values, x+g-0.5 can be represented exactly. However, in cases where it - can't be represented exactly the small error in x+g-0.5 can be magnified - significantly by the pow and exp calls, especially for large x. A cheap - correction is to multiply by (1 + e*g/(x+g-0.5)), where e is the error - involved in the computation of x+g-0.5 (that is, e = computed value of - x+g-0.5 - exact value of x+g-0.5). Here's the proof: - - Correction factor - ----------------- - Write x+g-0.5 = y-e, where y is exactly representable as an IEEE 754 - double, and e is tiny. Then: - - pow(x+g-0.5,x-0.5)/exp(x+g-0.5) = pow(y-e, x-0.5)/exp(y-e) - = pow(y, x-0.5)/exp(y) * C, - - where the correction_factor C is given by - - C = pow(1-e/y, x-0.5) * exp(e) - - Since e is tiny, pow(1-e/y, x-0.5) ~ 1-(x-0.5)*e/y, and exp(x) ~ 1+e, so: - - C ~ (1-(x-0.5)*e/y) * (1+e) ~ 1 + e*(y-(x-0.5))/y - - But y-(x-0.5) = g+e, and g+e ~ g. So we get C ~ 1 + e*g/y, and - - pow(x+g-0.5,x-0.5)/exp(x+g-0.5) ~ pow(y, x-0.5)/exp(y) * (1 + e*g/y), - - Note that for accuracy, when computing r*C it's better to do - - r + e*g/y*r; - - than - - r * (1 + e*g/y); - - since the addition in the latter throws away most of the bits of - information in e*g/y. -*/ - -#define LANCZOS_N 13 -static const double lanczos_g = 6.024680040776729583740234375; -static const double lanczos_g_minus_half = 5.524680040776729583740234375; -static const double lanczos_num_coeffs[LANCZOS_N] = { - 23531376880.410759688572007674451636754734846804940, - 42919803642.649098768957899047001988850926355848959, - 35711959237.355668049440185451547166705960488635843, - 17921034426.037209699919755754458931112671403265390, - 6039542586.3520280050642916443072979210699388420708, - 1439720407.3117216736632230727949123939715485786772, - 248874557.86205415651146038641322942321632125127801, - 31426415.585400194380614231628318205362874684987640, - 2876370.6289353724412254090516208496135991145378768, - 186056.26539522349504029498971604569928220784236328, - 8071.6720023658162106380029022722506138218516325024, - 210.82427775157934587250973392071336271166969580291, - 2.5066282746310002701649081771338373386264310793408 -}; - -/* denominator is x*(x+1)*...*(x+LANCZOS_N-2) */ -static const double lanczos_den_coeffs[LANCZOS_N] = { - 0.0, 39916800.0, 120543840.0, 150917976.0, 105258076.0, 45995730.0, - 13339535.0, 2637558.0, 357423.0, 32670.0, 1925.0, 66.0, 1.0}; - -/* gamma values for small positive integers, 1 though NGAMMA_INTEGRAL */ -#define NGAMMA_INTEGRAL 23 -static const double gamma_integral[NGAMMA_INTEGRAL] = { - 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0, - 3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0, - 1307674368000.0, 20922789888000.0, 355687428096000.0, - 6402373705728000.0, 121645100408832000.0, 2432902008176640000.0, - 51090942171709440000.0, 1124000727777607680000.0, -}; - -/* Lanczos' sum L_g(x), for positive x */ - -static double -lanczos_sum(double x) -{ - double num = 0.0, den = 0.0; - int i; - assert(x > 0.0); - /* evaluate the rational function lanczos_sum(x). For large - x, the obvious algorithm risks overflow, so we instead - rescale the denominator and numerator of the rational - function by x**(1-LANCZOS_N) and treat this as a - rational function in 1/x. This also reduces the error for - larger x values. The choice of cutoff point (5.0 below) is - somewhat arbitrary; in tests, smaller cutoff values than - this resulted in lower accuracy. */ - if (x < 5.0) { - for (i = LANCZOS_N; --i >= 0; ) { - num = num * x + lanczos_num_coeffs[i]; - den = den * x + lanczos_den_coeffs[i]; - } - } - else { - for (i = 0; i < LANCZOS_N; i++) { - num = num / x + lanczos_num_coeffs[i]; - den = den / x + lanczos_den_coeffs[i]; - } - } - return num/den; -} - -/* Constant for +infinity, generated in the same way as float('inf'). */ - -static double -m_inf(void) -{ -#ifndef PY_NO_SHORT_FLOAT_REPR - return _Py_dg_infinity(0); -#else - return Py_HUGE_VAL; -#endif -} - -/* Constant nan value, generated in the same way as float('nan'). */ -/* We don't currently assume that Py_NAN is defined everywhere. */ - -#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) - -static double -m_nan(void) -{ -#ifndef PY_NO_SHORT_FLOAT_REPR - return _Py_dg_stdnan(0); -#else - return Py_NAN; -#endif -} - -#endif - -static double -m_tgamma(double x) -{ - double absx, r, y, z, sqrtpow; - - /* special cases */ - if (!Py_IS_FINITE(x)) { - if (Py_IS_NAN(x) || x > 0.0) - return x; /* tgamma(nan) = nan, tgamma(inf) = inf */ - else { - errno = EDOM; - return Py_NAN; /* tgamma(-inf) = nan, invalid */ - } - } - if (x == 0.0) { - errno = EDOM; - /* tgamma(+-0.0) = +-inf, divide-by-zero */ - return copysign(Py_HUGE_VAL, x); - } - - /* integer arguments */ - if (x == floor(x)) { - if (x < 0.0) { - errno = EDOM; /* tgamma(n) = nan, invalid for */ - return Py_NAN; /* negative integers n */ - } - if (x <= NGAMMA_INTEGRAL) - return gamma_integral[(int)x - 1]; - } - absx = fabs(x); - - /* tiny arguments: tgamma(x) ~ 1/x for x near 0 */ - if (absx < 1e-20) { - r = 1.0/x; - if (Py_IS_INFINITY(r)) - errno = ERANGE; - return r; - } - - /* large arguments: assuming IEEE 754 doubles, tgamma(x) overflows for - x > 200, and underflows to +-0.0 for x < -200, not a negative - integer. */ - if (absx > 200.0) { - if (x < 0.0) { - return 0.0/m_sinpi(x); - } - else { - errno = ERANGE; - return Py_HUGE_VAL; - } - } - - y = absx + lanczos_g_minus_half; - /* compute error in sum */ - if (absx > lanczos_g_minus_half) { - /* note: the correction can be foiled by an optimizing - compiler that (incorrectly) thinks that an expression like - a + b - a - b can be optimized to 0.0. This shouldn't - happen in a standards-conforming compiler. */ - double q = y - absx; - z = q - lanczos_g_minus_half; - } - else { - double q = y - lanczos_g_minus_half; - z = q - absx; - } - z = z * lanczos_g / y; - if (x < 0.0) { - r = -pi / m_sinpi(absx) / absx * exp(y) / lanczos_sum(absx); - r -= z * r; - if (absx < 140.0) { - r /= pow(y, absx - 0.5); - } - else { - sqrtpow = pow(y, absx / 2.0 - 0.25); - r /= sqrtpow; - r /= sqrtpow; - } - } - else { - r = lanczos_sum(absx) / exp(y); - r += z * r; - if (absx < 140.0) { - r *= pow(y, absx - 0.5); - } - else { - sqrtpow = pow(y, absx / 2.0 - 0.25); - r *= sqrtpow; - r *= sqrtpow; - } - } - if (Py_IS_INFINITY(r)) - errno = ERANGE; - return r; -} - -/* - lgamma: natural log of the absolute value of the Gamma function. - For large arguments, Lanczos' formula works extremely well here. -*/ - -static double -m_lgamma(double x) -{ - double r; - double absx; - - /* special cases */ - if (!Py_IS_FINITE(x)) { - if (Py_IS_NAN(x)) - return x; /* lgamma(nan) = nan */ - else - return Py_HUGE_VAL; /* lgamma(+-inf) = +inf */ - } - - /* integer arguments */ - if (x == floor(x) && x <= 2.0) { - if (x <= 0.0) { - errno = EDOM; /* lgamma(n) = inf, divide-by-zero for */ - return Py_HUGE_VAL; /* integers n <= 0 */ - } - else { - return 0.0; /* lgamma(1) = lgamma(2) = 0.0 */ - } - } - - absx = fabs(x); - /* tiny arguments: lgamma(x) ~ -log(fabs(x)) for small x */ - if (absx < 1e-20) - return -log(absx); - - /* Lanczos' formula. We could save a fraction of a ulp in accuracy by - having a second set of numerator coefficients for lanczos_sum that - absorbed the exp(-lanczos_g) term, and throwing out the lanczos_g - subtraction below; it's probably not worth it. */ - r = log(lanczos_sum(absx)) - lanczos_g; - r += (absx - 0.5) * (log(absx + lanczos_g - 0.5) - 1); - if (x < 0.0) - /* Use reflection formula to get value for negative x. */ - r = logpi - log(fabs(m_sinpi(absx))) - log(absx) - r; - if (Py_IS_INFINITY(r)) - errno = ERANGE; - return r; -} - -#if !defined(HAVE_ERF) || !defined(HAVE_ERFC) - -/* - Implementations of the error function erf(x) and the complementary error - function erfc(x). - - Method: we use a series approximation for erf for small x, and a continued - fraction approximation for erfc(x) for larger x; - combined with the relations erf(-x) = -erf(x) and erfc(x) = 1.0 - erf(x), - this gives us erf(x) and erfc(x) for all x. - - The series expansion used is: - - erf(x) = x*exp(-x*x)/sqrt(pi) * [ - 2/1 + 4/3 x**2 + 8/15 x**4 + 16/105 x**6 + ...] - - The coefficient of x**(2k-2) here is 4**k*factorial(k)/factorial(2*k). - This series converges well for smallish x, but slowly for larger x. - - The continued fraction expansion used is: - - erfc(x) = x*exp(-x*x)/sqrt(pi) * [1/(0.5 + x**2 -) 0.5/(2.5 + x**2 - ) - 3.0/(4.5 + x**2 - ) 7.5/(6.5 + x**2 - ) ...] - - after the first term, the general term has the form: - - k*(k-0.5)/(2*k+0.5 + x**2 - ...). - - This expansion converges fast for larger x, but convergence becomes - infinitely slow as x approaches 0.0. The (somewhat naive) continued - fraction evaluation algorithm used below also risks overflow for large x; - but for large x, erfc(x) == 0.0 to within machine precision. (For - example, erfc(30.0) is approximately 2.56e-393). - - Parameters: use series expansion for abs(x) < ERF_SERIES_CUTOFF and - continued fraction expansion for ERF_SERIES_CUTOFF <= abs(x) < - ERFC_CONTFRAC_CUTOFF. ERFC_SERIES_TERMS and ERFC_CONTFRAC_TERMS are the - numbers of terms to use for the relevant expansions. */ - -#define ERF_SERIES_CUTOFF 1.5 -#define ERF_SERIES_TERMS 25 -#define ERFC_CONTFRAC_CUTOFF 30.0 -#define ERFC_CONTFRAC_TERMS 50 - -/* - Error function, via power series. - - Given a finite float x, return an approximation to erf(x). - Converges reasonably fast for small x. -*/ - -static double -m_erf_series(double x) -{ - double x2, acc, fk, result; - int i, saved_errno; - - x2 = x * x; - acc = 0.0; - fk = (double)ERF_SERIES_TERMS + 0.5; - for (i = 0; i < ERF_SERIES_TERMS; i++) { - acc = 2.0 + x2 * acc / fk; - fk -= 1.0; - } - /* Make sure the exp call doesn't affect errno; - see m_erfc_contfrac for more. */ - saved_errno = errno; - result = acc * x * exp(-x2) / sqrtpi; - errno = saved_errno; - return result; -} - -/* - Complementary error function, via continued fraction expansion. - - Given a positive float x, return an approximation to erfc(x). Converges - reasonably fast for x large (say, x > 2.0), and should be safe from - overflow if x and nterms are not too large. On an IEEE 754 machine, with x - <= 30.0, we're safe up to nterms = 100. For x >= 30.0, erfc(x) is smaller - than the smallest representable nonzero float. */ - -static double -m_erfc_contfrac(double x) -{ - double x2, a, da, p, p_last, q, q_last, b, result; - int i, saved_errno; - - if (x >= ERFC_CONTFRAC_CUTOFF) - return 0.0; - - x2 = x*x; - a = 0.0; - da = 0.5; - p = 1.0; p_last = 0.0; - q = da + x2; q_last = 1.0; - for (i = 0; i < ERFC_CONTFRAC_TERMS; i++) { - double temp; - a += da; - da += 2.0; - b = da + x2; - temp = p; p = b*p - a*p_last; p_last = temp; - temp = q; q = b*q - a*q_last; q_last = temp; - } - /* Issue #8986: On some platforms, exp sets errno on underflow to zero; - save the current errno value so that we can restore it later. */ - saved_errno = errno; - result = p / q * x * exp(-x2) / sqrtpi; - errno = saved_errno; - return result; -} - -#endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */ - -/* Error function erf(x), for general x */ - -static double -m_erf(double x) -{ -#ifdef HAVE_ERF - return erf(x); -#else - double absx, cf; - - if (Py_IS_NAN(x)) - return x; - absx = fabs(x); - if (absx < ERF_SERIES_CUTOFF) - return m_erf_series(x); - else { - cf = m_erfc_contfrac(absx); - return x > 0.0 ? 1.0 - cf : cf - 1.0; - } -#endif -} - -/* Complementary error function erfc(x), for general x. */ - -static double -m_erfc(double x) -{ -#ifdef HAVE_ERFC - return erfc(x); -#else - double absx, cf; - - if (Py_IS_NAN(x)) - return x; - absx = fabs(x); - if (absx < ERF_SERIES_CUTOFF) - return 1.0 - m_erf_series(x); - else { - cf = m_erfc_contfrac(absx); - return x > 0.0 ? cf : 2.0 - cf; - } -#endif -} - -/* - wrapper for atan2 that deals directly with special cases before - delegating to the platform libm for the remaining cases. This - is necessary to get consistent behaviour across platforms. - Windows, FreeBSD and alpha Tru64 are amongst platforms that don't - always follow C99. -*/ - -static double -m_atan2(double y, double x) -{ - if (Py_IS_NAN(x) || Py_IS_NAN(y)) - return Py_NAN; - if (Py_IS_INFINITY(y)) { - if (Py_IS_INFINITY(x)) { - if (copysign(1., x) == 1.) - /* atan2(+-inf, +inf) == +-pi/4 */ - return copysign(0.25*Py_MATH_PI, y); - else - /* atan2(+-inf, -inf) == +-pi*3/4 */ - return copysign(0.75*Py_MATH_PI, y); - } - /* atan2(+-inf, x) == +-pi/2 for finite x */ - return copysign(0.5*Py_MATH_PI, y); - } - if (Py_IS_INFINITY(x) || y == 0.) { - if (copysign(1., x) == 1.) - /* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */ - return copysign(0., y); - else - /* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */ - return copysign(Py_MATH_PI, y); - } - return atan2(y, x); -} - - -/* IEEE 754-style remainder operation: x - n*y where n*y is the nearest - multiple of y to x, taking n even in the case of a tie. Assuming an IEEE 754 - binary floating-point format, the result is always exact. */ - -static double -m_remainder(double x, double y) -{ - /* Deal with most common case first. */ - if (Py_IS_FINITE(x) && Py_IS_FINITE(y)) { - double absx, absy, c, m, r; - - if (y == 0.0) { - return Py_NAN; - } - - absx = fabs(x); - absy = fabs(y); - m = fmod(absx, absy); - - /* - Warning: some subtlety here. What we *want* to know at this point is - whether the remainder m is less than, equal to, or greater than half - of absy. However, we can't do that comparison directly because we +static double +m_sinpi(double x) +{ + double y, r; + int n; + /* this function should only ever be called for finite arguments */ + assert(Py_IS_FINITE(x)); + y = fmod(fabs(x), 2.0); + n = (int)round(2.0*y); + assert(0 <= n && n <= 4); + switch (n) { + case 0: + r = sin(pi*y); + break; + case 1: + r = cos(pi*(y-0.5)); + break; + case 2: + /* N.B. -sin(pi*(y-1.0)) is *not* equivalent: it would give + -0.0 instead of 0.0 when y == 1.0. */ + r = sin(pi*(1.0-y)); + break; + case 3: + r = -cos(pi*(y-1.5)); + break; + case 4: + r = sin(pi*(y-2.0)); + break; + default: + Py_UNREACHABLE(); + } + return copysign(1.0, x)*r; +} + +/* Implementation of the real gamma function. In extensive but non-exhaustive + random tests, this function proved accurate to within <= 10 ulps across the + entire float domain. Note that accuracy may depend on the quality of the + system math functions, the pow function in particular. Special cases + follow C99 annex F. The parameters and method are tailored to platforms + whose double format is the IEEE 754 binary64 format. + + Method: for x > 0.0 we use the Lanczos approximation with parameters N=13 + and g=6.024680040776729583740234375; these parameters are amongst those + used by the Boost library. Following Boost (again), we re-express the + Lanczos sum as a rational function, and compute it that way. The + coefficients below were computed independently using MPFR, and have been + double-checked against the coefficients in the Boost source code. + + For x < 0.0 we use the reflection formula. + + There's one minor tweak that deserves explanation: Lanczos' formula for + Gamma(x) involves computing pow(x+g-0.5, x-0.5) / exp(x+g-0.5). For many x + values, x+g-0.5 can be represented exactly. However, in cases where it + can't be represented exactly the small error in x+g-0.5 can be magnified + significantly by the pow and exp calls, especially for large x. A cheap + correction is to multiply by (1 + e*g/(x+g-0.5)), where e is the error + involved in the computation of x+g-0.5 (that is, e = computed value of + x+g-0.5 - exact value of x+g-0.5). Here's the proof: + + Correction factor + ----------------- + Write x+g-0.5 = y-e, where y is exactly representable as an IEEE 754 + double, and e is tiny. Then: + + pow(x+g-0.5,x-0.5)/exp(x+g-0.5) = pow(y-e, x-0.5)/exp(y-e) + = pow(y, x-0.5)/exp(y) * C, + + where the correction_factor C is given by + + C = pow(1-e/y, x-0.5) * exp(e) + + Since e is tiny, pow(1-e/y, x-0.5) ~ 1-(x-0.5)*e/y, and exp(x) ~ 1+e, so: + + C ~ (1-(x-0.5)*e/y) * (1+e) ~ 1 + e*(y-(x-0.5))/y + + But y-(x-0.5) = g+e, and g+e ~ g. So we get C ~ 1 + e*g/y, and + + pow(x+g-0.5,x-0.5)/exp(x+g-0.5) ~ pow(y, x-0.5)/exp(y) * (1 + e*g/y), + + Note that for accuracy, when computing r*C it's better to do + + r + e*g/y*r; + + than + + r * (1 + e*g/y); + + since the addition in the latter throws away most of the bits of + information in e*g/y. +*/ + +#define LANCZOS_N 13 +static const double lanczos_g = 6.024680040776729583740234375; +static const double lanczos_g_minus_half = 5.524680040776729583740234375; +static const double lanczos_num_coeffs[LANCZOS_N] = { + 23531376880.410759688572007674451636754734846804940, + 42919803642.649098768957899047001988850926355848959, + 35711959237.355668049440185451547166705960488635843, + 17921034426.037209699919755754458931112671403265390, + 6039542586.3520280050642916443072979210699388420708, + 1439720407.3117216736632230727949123939715485786772, + 248874557.86205415651146038641322942321632125127801, + 31426415.585400194380614231628318205362874684987640, + 2876370.6289353724412254090516208496135991145378768, + 186056.26539522349504029498971604569928220784236328, + 8071.6720023658162106380029022722506138218516325024, + 210.82427775157934587250973392071336271166969580291, + 2.5066282746310002701649081771338373386264310793408 +}; + +/* denominator is x*(x+1)*...*(x+LANCZOS_N-2) */ +static const double lanczos_den_coeffs[LANCZOS_N] = { + 0.0, 39916800.0, 120543840.0, 150917976.0, 105258076.0, 45995730.0, + 13339535.0, 2637558.0, 357423.0, 32670.0, 1925.0, 66.0, 1.0}; + +/* gamma values for small positive integers, 1 though NGAMMA_INTEGRAL */ +#define NGAMMA_INTEGRAL 23 +static const double gamma_integral[NGAMMA_INTEGRAL] = { + 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0, + 3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0, + 1307674368000.0, 20922789888000.0, 355687428096000.0, + 6402373705728000.0, 121645100408832000.0, 2432902008176640000.0, + 51090942171709440000.0, 1124000727777607680000.0, +}; + +/* Lanczos' sum L_g(x), for positive x */ + +static double +lanczos_sum(double x) +{ + double num = 0.0, den = 0.0; + int i; + assert(x > 0.0); + /* evaluate the rational function lanczos_sum(x). For large + x, the obvious algorithm risks overflow, so we instead + rescale the denominator and numerator of the rational + function by x**(1-LANCZOS_N) and treat this as a + rational function in 1/x. This also reduces the error for + larger x values. The choice of cutoff point (5.0 below) is + somewhat arbitrary; in tests, smaller cutoff values than + this resulted in lower accuracy. */ + if (x < 5.0) { + for (i = LANCZOS_N; --i >= 0; ) { + num = num * x + lanczos_num_coeffs[i]; + den = den * x + lanczos_den_coeffs[i]; + } + } + else { + for (i = 0; i < LANCZOS_N; i++) { + num = num / x + lanczos_num_coeffs[i]; + den = den / x + lanczos_den_coeffs[i]; + } + } + return num/den; +} + +/* Constant for +infinity, generated in the same way as float('inf'). */ + +static double +m_inf(void) +{ +#ifndef PY_NO_SHORT_FLOAT_REPR + return _Py_dg_infinity(0); +#else + return Py_HUGE_VAL; +#endif +} + +/* Constant nan value, generated in the same way as float('nan'). */ +/* We don't currently assume that Py_NAN is defined everywhere. */ + +#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) + +static double +m_nan(void) +{ +#ifndef PY_NO_SHORT_FLOAT_REPR + return _Py_dg_stdnan(0); +#else + return Py_NAN; +#endif +} + +#endif + +static double +m_tgamma(double x) +{ + double absx, r, y, z, sqrtpow; + + /* special cases */ + if (!Py_IS_FINITE(x)) { + if (Py_IS_NAN(x) || x > 0.0) + return x; /* tgamma(nan) = nan, tgamma(inf) = inf */ + else { + errno = EDOM; + return Py_NAN; /* tgamma(-inf) = nan, invalid */ + } + } + if (x == 0.0) { + errno = EDOM; + /* tgamma(+-0.0) = +-inf, divide-by-zero */ + return copysign(Py_HUGE_VAL, x); + } + + /* integer arguments */ + if (x == floor(x)) { + if (x < 0.0) { + errno = EDOM; /* tgamma(n) = nan, invalid for */ + return Py_NAN; /* negative integers n */ + } + if (x <= NGAMMA_INTEGRAL) + return gamma_integral[(int)x - 1]; + } + absx = fabs(x); + + /* tiny arguments: tgamma(x) ~ 1/x for x near 0 */ + if (absx < 1e-20) { + r = 1.0/x; + if (Py_IS_INFINITY(r)) + errno = ERANGE; + return r; + } + + /* large arguments: assuming IEEE 754 doubles, tgamma(x) overflows for + x > 200, and underflows to +-0.0 for x < -200, not a negative + integer. */ + if (absx > 200.0) { + if (x < 0.0) { + return 0.0/m_sinpi(x); + } + else { + errno = ERANGE; + return Py_HUGE_VAL; + } + } + + y = absx + lanczos_g_minus_half; + /* compute error in sum */ + if (absx > lanczos_g_minus_half) { + /* note: the correction can be foiled by an optimizing + compiler that (incorrectly) thinks that an expression like + a + b - a - b can be optimized to 0.0. This shouldn't + happen in a standards-conforming compiler. */ + double q = y - absx; + z = q - lanczos_g_minus_half; + } + else { + double q = y - lanczos_g_minus_half; + z = q - absx; + } + z = z * lanczos_g / y; + if (x < 0.0) { + r = -pi / m_sinpi(absx) / absx * exp(y) / lanczos_sum(absx); + r -= z * r; + if (absx < 140.0) { + r /= pow(y, absx - 0.5); + } + else { + sqrtpow = pow(y, absx / 2.0 - 0.25); + r /= sqrtpow; + r /= sqrtpow; + } + } + else { + r = lanczos_sum(absx) / exp(y); + r += z * r; + if (absx < 140.0) { + r *= pow(y, absx - 0.5); + } + else { + sqrtpow = pow(y, absx / 2.0 - 0.25); + r *= sqrtpow; + r *= sqrtpow; + } + } + if (Py_IS_INFINITY(r)) + errno = ERANGE; + return r; +} + +/* + lgamma: natural log of the absolute value of the Gamma function. + For large arguments, Lanczos' formula works extremely well here. +*/ + +static double +m_lgamma(double x) +{ + double r; + double absx; + + /* special cases */ + if (!Py_IS_FINITE(x)) { + if (Py_IS_NAN(x)) + return x; /* lgamma(nan) = nan */ + else + return Py_HUGE_VAL; /* lgamma(+-inf) = +inf */ + } + + /* integer arguments */ + if (x == floor(x) && x <= 2.0) { + if (x <= 0.0) { + errno = EDOM; /* lgamma(n) = inf, divide-by-zero for */ + return Py_HUGE_VAL; /* integers n <= 0 */ + } + else { + return 0.0; /* lgamma(1) = lgamma(2) = 0.0 */ + } + } + + absx = fabs(x); + /* tiny arguments: lgamma(x) ~ -log(fabs(x)) for small x */ + if (absx < 1e-20) + return -log(absx); + + /* Lanczos' formula. We could save a fraction of a ulp in accuracy by + having a second set of numerator coefficients for lanczos_sum that + absorbed the exp(-lanczos_g) term, and throwing out the lanczos_g + subtraction below; it's probably not worth it. */ + r = log(lanczos_sum(absx)) - lanczos_g; + r += (absx - 0.5) * (log(absx + lanczos_g - 0.5) - 1); + if (x < 0.0) + /* Use reflection formula to get value for negative x. */ + r = logpi - log(fabs(m_sinpi(absx))) - log(absx) - r; + if (Py_IS_INFINITY(r)) + errno = ERANGE; + return r; +} + +#if !defined(HAVE_ERF) || !defined(HAVE_ERFC) + +/* + Implementations of the error function erf(x) and the complementary error + function erfc(x). + + Method: we use a series approximation for erf for small x, and a continued + fraction approximation for erfc(x) for larger x; + combined with the relations erf(-x) = -erf(x) and erfc(x) = 1.0 - erf(x), + this gives us erf(x) and erfc(x) for all x. + + The series expansion used is: + + erf(x) = x*exp(-x*x)/sqrt(pi) * [ + 2/1 + 4/3 x**2 + 8/15 x**4 + 16/105 x**6 + ...] + + The coefficient of x**(2k-2) here is 4**k*factorial(k)/factorial(2*k). + This series converges well for smallish x, but slowly for larger x. + + The continued fraction expansion used is: + + erfc(x) = x*exp(-x*x)/sqrt(pi) * [1/(0.5 + x**2 -) 0.5/(2.5 + x**2 - ) + 3.0/(4.5 + x**2 - ) 7.5/(6.5 + x**2 - ) ...] + + after the first term, the general term has the form: + + k*(k-0.5)/(2*k+0.5 + x**2 - ...). + + This expansion converges fast for larger x, but convergence becomes + infinitely slow as x approaches 0.0. The (somewhat naive) continued + fraction evaluation algorithm used below also risks overflow for large x; + but for large x, erfc(x) == 0.0 to within machine precision. (For + example, erfc(30.0) is approximately 2.56e-393). + + Parameters: use series expansion for abs(x) < ERF_SERIES_CUTOFF and + continued fraction expansion for ERF_SERIES_CUTOFF <= abs(x) < + ERFC_CONTFRAC_CUTOFF. ERFC_SERIES_TERMS and ERFC_CONTFRAC_TERMS are the + numbers of terms to use for the relevant expansions. */ + +#define ERF_SERIES_CUTOFF 1.5 +#define ERF_SERIES_TERMS 25 +#define ERFC_CONTFRAC_CUTOFF 30.0 +#define ERFC_CONTFRAC_TERMS 50 + +/* + Error function, via power series. + + Given a finite float x, return an approximation to erf(x). + Converges reasonably fast for small x. +*/ + +static double +m_erf_series(double x) +{ + double x2, acc, fk, result; + int i, saved_errno; + + x2 = x * x; + acc = 0.0; + fk = (double)ERF_SERIES_TERMS + 0.5; + for (i = 0; i < ERF_SERIES_TERMS; i++) { + acc = 2.0 + x2 * acc / fk; + fk -= 1.0; + } + /* Make sure the exp call doesn't affect errno; + see m_erfc_contfrac for more. */ + saved_errno = errno; + result = acc * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; +} + +/* + Complementary error function, via continued fraction expansion. + + Given a positive float x, return an approximation to erfc(x). Converges + reasonably fast for x large (say, x > 2.0), and should be safe from + overflow if x and nterms are not too large. On an IEEE 754 machine, with x + <= 30.0, we're safe up to nterms = 100. For x >= 30.0, erfc(x) is smaller + than the smallest representable nonzero float. */ + +static double +m_erfc_contfrac(double x) +{ + double x2, a, da, p, p_last, q, q_last, b, result; + int i, saved_errno; + + if (x >= ERFC_CONTFRAC_CUTOFF) + return 0.0; + + x2 = x*x; + a = 0.0; + da = 0.5; + p = 1.0; p_last = 0.0; + q = da + x2; q_last = 1.0; + for (i = 0; i < ERFC_CONTFRAC_TERMS; i++) { + double temp; + a += da; + da += 2.0; + b = da + x2; + temp = p; p = b*p - a*p_last; p_last = temp; + temp = q; q = b*q - a*q_last; q_last = temp; + } + /* Issue #8986: On some platforms, exp sets errno on underflow to zero; + save the current errno value so that we can restore it later. */ + saved_errno = errno; + result = p / q * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; +} + +#endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */ + +/* Error function erf(x), for general x */ + +static double +m_erf(double x) +{ +#ifdef HAVE_ERF + return erf(x); +#else + double absx, cf; + + if (Py_IS_NAN(x)) + return x; + absx = fabs(x); + if (absx < ERF_SERIES_CUTOFF) + return m_erf_series(x); + else { + cf = m_erfc_contfrac(absx); + return x > 0.0 ? 1.0 - cf : cf - 1.0; + } +#endif +} + +/* Complementary error function erfc(x), for general x. */ + +static double +m_erfc(double x) +{ +#ifdef HAVE_ERFC + return erfc(x); +#else + double absx, cf; + + if (Py_IS_NAN(x)) + return x; + absx = fabs(x); + if (absx < ERF_SERIES_CUTOFF) + return 1.0 - m_erf_series(x); + else { + cf = m_erfc_contfrac(absx); + return x > 0.0 ? cf : 2.0 - cf; + } +#endif +} + +/* + wrapper for atan2 that deals directly with special cases before + delegating to the platform libm for the remaining cases. This + is necessary to get consistent behaviour across platforms. + Windows, FreeBSD and alpha Tru64 are amongst platforms that don't + always follow C99. +*/ + +static double +m_atan2(double y, double x) +{ + if (Py_IS_NAN(x) || Py_IS_NAN(y)) + return Py_NAN; + if (Py_IS_INFINITY(y)) { + if (Py_IS_INFINITY(x)) { + if (copysign(1., x) == 1.) + /* atan2(+-inf, +inf) == +-pi/4 */ + return copysign(0.25*Py_MATH_PI, y); + else + /* atan2(+-inf, -inf) == +-pi*3/4 */ + return copysign(0.75*Py_MATH_PI, y); + } + /* atan2(+-inf, x) == +-pi/2 for finite x */ + return copysign(0.5*Py_MATH_PI, y); + } + if (Py_IS_INFINITY(x) || y == 0.) { + if (copysign(1., x) == 1.) + /* atan2(+-y, +inf) = atan2(+-0, +x) = +-0. */ + return copysign(0., y); + else + /* atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. */ + return copysign(Py_MATH_PI, y); + } + return atan2(y, x); +} + + +/* IEEE 754-style remainder operation: x - n*y where n*y is the nearest + multiple of y to x, taking n even in the case of a tie. Assuming an IEEE 754 + binary floating-point format, the result is always exact. */ + +static double +m_remainder(double x, double y) +{ + /* Deal with most common case first. */ + if (Py_IS_FINITE(x) && Py_IS_FINITE(y)) { + double absx, absy, c, m, r; + + if (y == 0.0) { + return Py_NAN; + } + + absx = fabs(x); + absy = fabs(y); + m = fmod(absx, absy); + + /* + Warning: some subtlety here. What we *want* to know at this point is + whether the remainder m is less than, equal to, or greater than half + of absy. However, we can't do that comparison directly because we can't be sure that 0.5*absy is representable (the multiplication - might incur precision loss due to underflow). So instead we compare - m with the complement c = absy - m: m < 0.5*absy if and only if m < - c, and so on. The catch is that absy - m might also not be - representable, but it turns out that it doesn't matter: - - - if m > 0.5*absy then absy - m is exactly representable, by - Sterbenz's lemma, so m > c - - if m == 0.5*absy then again absy - m is exactly representable - and m == c - - if m < 0.5*absy then either (i) 0.5*absy is exactly representable, - in which case 0.5*absy < absy - m, so 0.5*absy <= c and hence m < - c, or (ii) absy is tiny, either subnormal or in the lowest normal - binade. Then absy - m is exactly representable and again m < c. - */ - - c = absy - m; - if (m < c) { - r = m; - } - else if (m > c) { - r = -c; - } - else { - /* - Here absx is exactly halfway between two multiples of absy, - and we need to choose the even multiple. x now has the form - - absx = n * absy + m - - for some integer n (recalling that m = 0.5*absy at this point). - If n is even we want to return m; if n is odd, we need to - return -m. - - So - - 0.5 * (absx - m) = (n/2) * absy - - and now reducing modulo absy gives us: - - | m, if n is odd - fmod(0.5 * (absx - m), absy) = | - | 0, if n is even - - Now m - 2.0 * fmod(...) gives the desired result: m - if n is even, -m if m is odd. - - Note that all steps in fmod(0.5 * (absx - m), absy) - will be computed exactly, with no rounding error - introduced. - */ - assert(m == c); - r = m - 2.0 * fmod(0.5 * (absx - m), absy); - } - return copysign(1.0, x) * r; - } - - /* Special values. */ - if (Py_IS_NAN(x)) { - return x; - } - if (Py_IS_NAN(y)) { - return y; - } - if (Py_IS_INFINITY(x)) { - return Py_NAN; - } - assert(Py_IS_INFINITY(y)); - return x; -} - - -/* - Various platforms (Solaris, OpenBSD) do nonstandard things for log(0), - log(-ve), log(NaN). Here are wrappers for log and log10 that deal with - special values directly, passing positive non-special values through to - the system log/log10. - */ - -static double -m_log(double x) -{ - if (Py_IS_FINITE(x)) { - if (x > 0.0) - return log(x); - errno = EDOM; - if (x == 0.0) - return -Py_HUGE_VAL; /* log(0) = -inf */ - else - return Py_NAN; /* log(-ve) = nan */ - } - else if (Py_IS_NAN(x)) - return x; /* log(nan) = nan */ - else if (x > 0.0) - return x; /* log(inf) = inf */ - else { - errno = EDOM; - return Py_NAN; /* log(-inf) = nan */ - } -} - -/* - log2: log to base 2. - - Uses an algorithm that should: - - (a) produce exact results for powers of 2, and - (b) give a monotonic log2 (for positive finite floats), - assuming that the system log is monotonic. -*/ - -static double -m_log2(double x) -{ - if (!Py_IS_FINITE(x)) { - if (Py_IS_NAN(x)) - return x; /* log2(nan) = nan */ - else if (x > 0.0) - return x; /* log2(+inf) = +inf */ - else { - errno = EDOM; - return Py_NAN; /* log2(-inf) = nan, invalid-operation */ - } - } - - if (x > 0.0) { -#ifdef HAVE_LOG2 - return log2(x); -#else - double m; - int e; - m = frexp(x, &e); - /* We want log2(m * 2**e) == log(m) / log(2) + e. Care is needed when - * x is just greater than 1.0: in that case e is 1, log(m) is negative, - * and we get significant cancellation error from the addition of - * log(m) / log(2) to e. The slight rewrite of the expression below - * avoids this problem. - */ - if (x >= 1.0) { - return log(2.0 * m) / log(2.0) + (e - 1); - } - else { - return log(m) / log(2.0) + e; - } -#endif - } - else if (x == 0.0) { - errno = EDOM; - return -Py_HUGE_VAL; /* log2(0) = -inf, divide-by-zero */ - } - else { - errno = EDOM; - return Py_NAN; /* log2(-inf) = nan, invalid-operation */ - } -} - -static double -m_log10(double x) -{ - if (Py_IS_FINITE(x)) { - if (x > 0.0) - return log10(x); - errno = EDOM; - if (x == 0.0) - return -Py_HUGE_VAL; /* log10(0) = -inf */ - else - return Py_NAN; /* log10(-ve) = nan */ - } - else if (Py_IS_NAN(x)) - return x; /* log10(nan) = nan */ - else if (x > 0.0) - return x; /* log10(inf) = inf */ - else { - errno = EDOM; - return Py_NAN; /* log10(-inf) = nan */ - } -} - - + might incur precision loss due to underflow). So instead we compare + m with the complement c = absy - m: m < 0.5*absy if and only if m < + c, and so on. The catch is that absy - m might also not be + representable, but it turns out that it doesn't matter: + + - if m > 0.5*absy then absy - m is exactly representable, by + Sterbenz's lemma, so m > c + - if m == 0.5*absy then again absy - m is exactly representable + and m == c + - if m < 0.5*absy then either (i) 0.5*absy is exactly representable, + in which case 0.5*absy < absy - m, so 0.5*absy <= c and hence m < + c, or (ii) absy is tiny, either subnormal or in the lowest normal + binade. Then absy - m is exactly representable and again m < c. + */ + + c = absy - m; + if (m < c) { + r = m; + } + else if (m > c) { + r = -c; + } + else { + /* + Here absx is exactly halfway between two multiples of absy, + and we need to choose the even multiple. x now has the form + + absx = n * absy + m + + for some integer n (recalling that m = 0.5*absy at this point). + If n is even we want to return m; if n is odd, we need to + return -m. + + So + + 0.5 * (absx - m) = (n/2) * absy + + and now reducing modulo absy gives us: + + | m, if n is odd + fmod(0.5 * (absx - m), absy) = | + | 0, if n is even + + Now m - 2.0 * fmod(...) gives the desired result: m + if n is even, -m if m is odd. + + Note that all steps in fmod(0.5 * (absx - m), absy) + will be computed exactly, with no rounding error + introduced. + */ + assert(m == c); + r = m - 2.0 * fmod(0.5 * (absx - m), absy); + } + return copysign(1.0, x) * r; + } + + /* Special values. */ + if (Py_IS_NAN(x)) { + return x; + } + if (Py_IS_NAN(y)) { + return y; + } + if (Py_IS_INFINITY(x)) { + return Py_NAN; + } + assert(Py_IS_INFINITY(y)); + return x; +} + + +/* + Various platforms (Solaris, OpenBSD) do nonstandard things for log(0), + log(-ve), log(NaN). Here are wrappers for log and log10 that deal with + special values directly, passing positive non-special values through to + the system log/log10. + */ + +static double +m_log(double x) +{ + if (Py_IS_FINITE(x)) { + if (x > 0.0) + return log(x); + errno = EDOM; + if (x == 0.0) + return -Py_HUGE_VAL; /* log(0) = -inf */ + else + return Py_NAN; /* log(-ve) = nan */ + } + else if (Py_IS_NAN(x)) + return x; /* log(nan) = nan */ + else if (x > 0.0) + return x; /* log(inf) = inf */ + else { + errno = EDOM; + return Py_NAN; /* log(-inf) = nan */ + } +} + +/* + log2: log to base 2. + + Uses an algorithm that should: + + (a) produce exact results for powers of 2, and + (b) give a monotonic log2 (for positive finite floats), + assuming that the system log is monotonic. +*/ + +static double +m_log2(double x) +{ + if (!Py_IS_FINITE(x)) { + if (Py_IS_NAN(x)) + return x; /* log2(nan) = nan */ + else if (x > 0.0) + return x; /* log2(+inf) = +inf */ + else { + errno = EDOM; + return Py_NAN; /* log2(-inf) = nan, invalid-operation */ + } + } + + if (x > 0.0) { +#ifdef HAVE_LOG2 + return log2(x); +#else + double m; + int e; + m = frexp(x, &e); + /* We want log2(m * 2**e) == log(m) / log(2) + e. Care is needed when + * x is just greater than 1.0: in that case e is 1, log(m) is negative, + * and we get significant cancellation error from the addition of + * log(m) / log(2) to e. The slight rewrite of the expression below + * avoids this problem. + */ + if (x >= 1.0) { + return log(2.0 * m) / log(2.0) + (e - 1); + } + else { + return log(m) / log(2.0) + e; + } +#endif + } + else if (x == 0.0) { + errno = EDOM; + return -Py_HUGE_VAL; /* log2(0) = -inf, divide-by-zero */ + } + else { + errno = EDOM; + return Py_NAN; /* log2(-inf) = nan, invalid-operation */ + } +} + +static double +m_log10(double x) +{ + if (Py_IS_FINITE(x)) { + if (x > 0.0) + return log10(x); + errno = EDOM; + if (x == 0.0) + return -Py_HUGE_VAL; /* log10(0) = -inf */ + else + return Py_NAN; /* log10(-ve) = nan */ + } + else if (Py_IS_NAN(x)) + return x; /* log10(nan) = nan */ + else if (x > 0.0) + return x; /* log10(inf) = inf */ + else { + errno = EDOM; + return Py_NAN; /* log10(-inf) = nan */ + } +} + + static PyObject * math_gcd(PyObject *module, PyObject * const *args, Py_ssize_t nargs) { PyObject *res, *x; Py_ssize_t i; - + if (nargs == 0) { return PyLong_FromLong(0); } @@ -863,31 +863,31 @@ math_gcd(PyObject *module, PyObject * const *args, Py_ssize_t nargs) } return res; } - + PyDoc_STRVAR(math_gcd_doc, "gcd($module, *integers)\n" "--\n" "\n" "Greatest Common Divisor."); + - -static PyObject * +static PyObject * long_lcm(PyObject *a, PyObject *b) -{ +{ PyObject *g, *m, *f, *ab; - + if (Py_SIZE(a) == 0 || Py_SIZE(b) == 0) { return PyLong_FromLong(0); } g = _PyLong_GCD(a, b); if (g == NULL) { - return NULL; + return NULL; } f = PyNumber_FloorDivide(a, g); Py_DECREF(g); if (f == NULL) { - return NULL; - } + return NULL; + } m = PyNumber_Multiply(f, b); Py_DECREF(f); if (m == NULL) { @@ -896,9 +896,9 @@ long_lcm(PyObject *a, PyObject *b) ab = PyNumber_Absolute(m); Py_DECREF(m); return ab; -} - - +} + + static PyObject * math_lcm(PyObject *module, PyObject * const *args, Py_ssize_t nargs) { @@ -945,259 +945,259 @@ PyDoc_STRVAR(math_lcm_doc, "Least Common Multiple."); -/* Call is_error when errno != 0, and where x is the result libm - * returned. is_error will usually set up an exception and return - * true (1), but may return false (0) without setting up an exception. - */ -static int -is_error(double x) -{ - int result = 1; /* presumption of guilt */ - assert(errno); /* non-zero errno is a precondition for calling */ - if (errno == EDOM) - PyErr_SetString(PyExc_ValueError, "math domain error"); - - else if (errno == ERANGE) { - /* ANSI C generally requires libm functions to set ERANGE - * on overflow, but also generally *allows* them to set - * ERANGE on underflow too. There's no consistency about - * the latter across platforms. - * Alas, C99 never requires that errno be set. - * Here we suppress the underflow errors (libm functions - * should return a zero on underflow, and +- HUGE_VAL on - * overflow, so testing the result for zero suffices to - * distinguish the cases). - * - * On some platforms (Ubuntu/ia64) it seems that errno can be - * set to ERANGE for subnormal results that do *not* underflow - * to zero. So to be safe, we'll ignore ERANGE whenever the +/* Call is_error when errno != 0, and where x is the result libm + * returned. is_error will usually set up an exception and return + * true (1), but may return false (0) without setting up an exception. + */ +static int +is_error(double x) +{ + int result = 1; /* presumption of guilt */ + assert(errno); /* non-zero errno is a precondition for calling */ + if (errno == EDOM) + PyErr_SetString(PyExc_ValueError, "math domain error"); + + else if (errno == ERANGE) { + /* ANSI C generally requires libm functions to set ERANGE + * on overflow, but also generally *allows* them to set + * ERANGE on underflow too. There's no consistency about + * the latter across platforms. + * Alas, C99 never requires that errno be set. + * Here we suppress the underflow errors (libm functions + * should return a zero on underflow, and +- HUGE_VAL on + * overflow, so testing the result for zero suffices to + * distinguish the cases). + * + * On some platforms (Ubuntu/ia64) it seems that errno can be + * set to ERANGE for subnormal results that do *not* underflow + * to zero. So to be safe, we'll ignore ERANGE whenever the * function result is less than 1.5 in absolute value. * * bpo-46018: Changed to 1.5 to ensure underflows in expm1() * are correctly detected, since the function may underflow * toward -1.0 rather than 0.0. - */ + */ if (fabs(x) < 1.5) - result = 0; - else - PyErr_SetString(PyExc_OverflowError, - "math range error"); - } - else - /* Unexpected math error */ - PyErr_SetFromErrno(PyExc_ValueError); - return result; -} - -/* - math_1 is used to wrap a libm function f that takes a double - argument and returns a double. - - The error reporting follows these rules, which are designed to do - the right thing on C89/C99 platforms and IEEE 754/non IEEE 754 - platforms. - - - a NaN result from non-NaN inputs causes ValueError to be raised - - an infinite result from finite inputs causes OverflowError to be - raised if can_overflow is 1, or raises ValueError if can_overflow - is 0. - - if the result is finite and errno == EDOM then ValueError is - raised - - if the result is finite and nonzero and errno == ERANGE then - OverflowError is raised - - The last rule is used to catch overflow on platforms which follow - C89 but for which HUGE_VAL is not an infinity. - - For the majority of one-argument functions these rules are enough - to ensure that Python's functions behave as specified in 'Annex F' - of the C99 standard, with the 'invalid' and 'divide-by-zero' - floating-point exceptions mapping to Python's ValueError and the - 'overflow' floating-point exception mapping to OverflowError. - math_1 only works for functions that don't have singularities *and* - the possibility of overflow; fortunately, that covers everything we - care about right now. -*/ - -static PyObject * -math_1_to_whatever(PyObject *arg, double (*func) (double), - PyObject *(*from_double_func) (double), - int can_overflow) -{ - double x, r; - x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; - errno = 0; - r = (*func)(x); - if (Py_IS_NAN(r) && !Py_IS_NAN(x)) { - PyErr_SetString(PyExc_ValueError, - "math domain error"); /* invalid arg */ - return NULL; - } - if (Py_IS_INFINITY(r) && Py_IS_FINITE(x)) { - if (can_overflow) - PyErr_SetString(PyExc_OverflowError, - "math range error"); /* overflow */ - else - PyErr_SetString(PyExc_ValueError, - "math domain error"); /* singularity */ - return NULL; - } - if (Py_IS_FINITE(r) && errno && is_error(r)) - /* this branch unnecessary on most platforms */ - return NULL; - - return (*from_double_func)(r); -} - -/* variant of math_1, to be used when the function being wrapped is known to - set errno properly (that is, errno = EDOM for invalid or divide-by-zero, - errno = ERANGE for overflow). */ - -static PyObject * -math_1a(PyObject *arg, double (*func) (double)) -{ - double x, r; - x = PyFloat_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) - return NULL; - errno = 0; - r = (*func)(x); - if (errno && is_error(r)) - return NULL; - return PyFloat_FromDouble(r); -} - -/* - math_2 is used to wrap a libm function f that takes two double - arguments and returns a double. - - The error reporting follows these rules, which are designed to do - the right thing on C89/C99 platforms and IEEE 754/non IEEE 754 - platforms. - - - a NaN result from non-NaN inputs causes ValueError to be raised - - an infinite result from finite inputs causes OverflowError to be - raised. - - if the result is finite and errno == EDOM then ValueError is - raised - - if the result is finite and nonzero and errno == ERANGE then - OverflowError is raised - - The last rule is used to catch overflow on platforms which follow - C89 but for which HUGE_VAL is not an infinity. - - For most two-argument functions (copysign, fmod, hypot, atan2) - these rules are enough to ensure that Python's functions behave as - specified in 'Annex F' of the C99 standard, with the 'invalid' and - 'divide-by-zero' floating-point exceptions mapping to Python's - ValueError and the 'overflow' floating-point exception mapping to - OverflowError. -*/ - -static PyObject * -math_1(PyObject *arg, double (*func) (double), int can_overflow) -{ - return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow); -} - -static PyObject * + result = 0; + else + PyErr_SetString(PyExc_OverflowError, + "math range error"); + } + else + /* Unexpected math error */ + PyErr_SetFromErrno(PyExc_ValueError); + return result; +} + +/* + math_1 is used to wrap a libm function f that takes a double + argument and returns a double. + + The error reporting follows these rules, which are designed to do + the right thing on C89/C99 platforms and IEEE 754/non IEEE 754 + platforms. + + - a NaN result from non-NaN inputs causes ValueError to be raised + - an infinite result from finite inputs causes OverflowError to be + raised if can_overflow is 1, or raises ValueError if can_overflow + is 0. + - if the result is finite and errno == EDOM then ValueError is + raised + - if the result is finite and nonzero and errno == ERANGE then + OverflowError is raised + + The last rule is used to catch overflow on platforms which follow + C89 but for which HUGE_VAL is not an infinity. + + For the majority of one-argument functions these rules are enough + to ensure that Python's functions behave as specified in 'Annex F' + of the C99 standard, with the 'invalid' and 'divide-by-zero' + floating-point exceptions mapping to Python's ValueError and the + 'overflow' floating-point exception mapping to OverflowError. + math_1 only works for functions that don't have singularities *and* + the possibility of overflow; fortunately, that covers everything we + care about right now. +*/ + +static PyObject * +math_1_to_whatever(PyObject *arg, double (*func) (double), + PyObject *(*from_double_func) (double), + int can_overflow) +{ + double x, r; + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + errno = 0; + r = (*func)(x); + if (Py_IS_NAN(r) && !Py_IS_NAN(x)) { + PyErr_SetString(PyExc_ValueError, + "math domain error"); /* invalid arg */ + return NULL; + } + if (Py_IS_INFINITY(r) && Py_IS_FINITE(x)) { + if (can_overflow) + PyErr_SetString(PyExc_OverflowError, + "math range error"); /* overflow */ + else + PyErr_SetString(PyExc_ValueError, + "math domain error"); /* singularity */ + return NULL; + } + if (Py_IS_FINITE(r) && errno && is_error(r)) + /* this branch unnecessary on most platforms */ + return NULL; + + return (*from_double_func)(r); +} + +/* variant of math_1, to be used when the function being wrapped is known to + set errno properly (that is, errno = EDOM for invalid or divide-by-zero, + errno = ERANGE for overflow). */ + +static PyObject * +math_1a(PyObject *arg, double (*func) (double)) +{ + double x, r; + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + errno = 0; + r = (*func)(x); + if (errno && is_error(r)) + return NULL; + return PyFloat_FromDouble(r); +} + +/* + math_2 is used to wrap a libm function f that takes two double + arguments and returns a double. + + The error reporting follows these rules, which are designed to do + the right thing on C89/C99 platforms and IEEE 754/non IEEE 754 + platforms. + + - a NaN result from non-NaN inputs causes ValueError to be raised + - an infinite result from finite inputs causes OverflowError to be + raised. + - if the result is finite and errno == EDOM then ValueError is + raised + - if the result is finite and nonzero and errno == ERANGE then + OverflowError is raised + + The last rule is used to catch overflow on platforms which follow + C89 but for which HUGE_VAL is not an infinity. + + For most two-argument functions (copysign, fmod, hypot, atan2) + these rules are enough to ensure that Python's functions behave as + specified in 'Annex F' of the C99 standard, with the 'invalid' and + 'divide-by-zero' floating-point exceptions mapping to Python's + ValueError and the 'overflow' floating-point exception mapping to + OverflowError. +*/ + +static PyObject * +math_1(PyObject *arg, double (*func) (double), int can_overflow) +{ + return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow); +} + +static PyObject * math_2(PyObject *const *args, Py_ssize_t nargs, double (*func) (double, double), const char *funcname) -{ - double x, y, r; +{ + double x, y, r; if (!_PyArg_CheckPositional(funcname, nargs, 2, 2)) - return NULL; + return NULL; x = PyFloat_AsDouble(args[0]); if (x == -1.0 && PyErr_Occurred()) { - return NULL; + return NULL; } y = PyFloat_AsDouble(args[1]); if (y == -1.0 && PyErr_Occurred()) { return NULL; } - errno = 0; - r = (*func)(x, y); - if (Py_IS_NAN(r)) { - if (!Py_IS_NAN(x) && !Py_IS_NAN(y)) - errno = EDOM; - else - errno = 0; - } - else if (Py_IS_INFINITY(r)) { - if (Py_IS_FINITE(x) && Py_IS_FINITE(y)) - errno = ERANGE; - else - errno = 0; - } - if (errno && is_error(r)) - return NULL; - else - return PyFloat_FromDouble(r); -} - -#define FUNC1(funcname, func, can_overflow, docstring) \ - static PyObject * math_##funcname(PyObject *self, PyObject *args) { \ - return math_1(args, func, can_overflow); \ - }\ - PyDoc_STRVAR(math_##funcname##_doc, docstring); - -#define FUNC1A(funcname, func, docstring) \ - static PyObject * math_##funcname(PyObject *self, PyObject *args) { \ - return math_1a(args, func); \ - }\ - PyDoc_STRVAR(math_##funcname##_doc, docstring); - -#define FUNC2(funcname, func, docstring) \ + errno = 0; + r = (*func)(x, y); + if (Py_IS_NAN(r)) { + if (!Py_IS_NAN(x) && !Py_IS_NAN(y)) + errno = EDOM; + else + errno = 0; + } + else if (Py_IS_INFINITY(r)) { + if (Py_IS_FINITE(x) && Py_IS_FINITE(y)) + errno = ERANGE; + else + errno = 0; + } + if (errno && is_error(r)) + return NULL; + else + return PyFloat_FromDouble(r); +} + +#define FUNC1(funcname, func, can_overflow, docstring) \ + static PyObject * math_##funcname(PyObject *self, PyObject *args) { \ + return math_1(args, func, can_overflow); \ + }\ + PyDoc_STRVAR(math_##funcname##_doc, docstring); + +#define FUNC1A(funcname, func, docstring) \ + static PyObject * math_##funcname(PyObject *self, PyObject *args) { \ + return math_1a(args, func); \ + }\ + PyDoc_STRVAR(math_##funcname##_doc, docstring); + +#define FUNC2(funcname, func, docstring) \ static PyObject * math_##funcname(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { \ return math_2(args, nargs, func, #funcname); \ - }\ - PyDoc_STRVAR(math_##funcname##_doc, docstring); - -FUNC1(acos, acos, 0, - "acos($module, x, /)\n--\n\n" + }\ + PyDoc_STRVAR(math_##funcname##_doc, docstring); + +FUNC1(acos, acos, 0, + "acos($module, x, /)\n--\n\n" "Return the arc cosine (measured in radians) of x.\n\n" "The result is between 0 and pi.") -FUNC1(acosh, m_acosh, 0, - "acosh($module, x, /)\n--\n\n" - "Return the inverse hyperbolic cosine of x.") -FUNC1(asin, asin, 0, - "asin($module, x, /)\n--\n\n" +FUNC1(acosh, m_acosh, 0, + "acosh($module, x, /)\n--\n\n" + "Return the inverse hyperbolic cosine of x.") +FUNC1(asin, asin, 0, + "asin($module, x, /)\n--\n\n" "Return the arc sine (measured in radians) of x.\n\n" "The result is between -pi/2 and pi/2.") -FUNC1(asinh, m_asinh, 0, - "asinh($module, x, /)\n--\n\n" - "Return the inverse hyperbolic sine of x.") -FUNC1(atan, atan, 0, - "atan($module, x, /)\n--\n\n" +FUNC1(asinh, m_asinh, 0, + "asinh($module, x, /)\n--\n\n" + "Return the inverse hyperbolic sine of x.") +FUNC1(atan, atan, 0, + "atan($module, x, /)\n--\n\n" "Return the arc tangent (measured in radians) of x.\n\n" "The result is between -pi/2 and pi/2.") -FUNC2(atan2, m_atan2, - "atan2($module, y, x, /)\n--\n\n" - "Return the arc tangent (measured in radians) of y/x.\n\n" - "Unlike atan(y/x), the signs of both x and y are considered.") -FUNC1(atanh, m_atanh, 0, - "atanh($module, x, /)\n--\n\n" - "Return the inverse hyperbolic tangent of x.") - -/*[clinic input] -math.ceil - - x as number: object - / - -Return the ceiling of x as an Integral. - -This is the smallest integer >= x. -[clinic start generated code]*/ - -static PyObject * -math_ceil(PyObject *module, PyObject *number) -/*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/ -{ - _Py_IDENTIFIER(__ceil__); - +FUNC2(atan2, m_atan2, + "atan2($module, y, x, /)\n--\n\n" + "Return the arc tangent (measured in radians) of y/x.\n\n" + "Unlike atan(y/x), the signs of both x and y are considered.") +FUNC1(atanh, m_atanh, 0, + "atanh($module, x, /)\n--\n\n" + "Return the inverse hyperbolic tangent of x.") + +/*[clinic input] +math.ceil + + x as number: object + / + +Return the ceiling of x as an Integral. + +This is the smallest integer >= x. +[clinic start generated code]*/ + +static PyObject * +math_ceil(PyObject *module, PyObject *number) +/*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/ +{ + _Py_IDENTIFIER(__ceil__); + if (!PyFloat_CheckExact(number)) { PyObject *method = _PyObject_LookupSpecial(number, &PyId___ceil__); if (method != NULL) { @@ -1205,64 +1205,64 @@ math_ceil(PyObject *module, PyObject *number) Py_DECREF(method); return result; } - if (PyErr_Occurred()) - return NULL; - } + if (PyErr_Occurred()) + return NULL; + } double x = PyFloat_AsDouble(number); if (x == -1.0 && PyErr_Occurred()) return NULL; return PyLong_FromDouble(ceil(x)); -} - -FUNC2(copysign, copysign, - "copysign($module, x, y, /)\n--\n\n" - "Return a float with the magnitude (absolute value) of x but the sign of y.\n\n" - "On platforms that support signed zeros, copysign(1.0, -0.0)\n" - "returns -1.0.\n") -FUNC1(cos, cos, 0, - "cos($module, x, /)\n--\n\n" - "Return the cosine of x (measured in radians).") -FUNC1(cosh, cosh, 1, - "cosh($module, x, /)\n--\n\n" - "Return the hyperbolic cosine of x.") -FUNC1A(erf, m_erf, - "erf($module, x, /)\n--\n\n" - "Error function at x.") -FUNC1A(erfc, m_erfc, - "erfc($module, x, /)\n--\n\n" - "Complementary error function at x.") -FUNC1(exp, exp, 1, - "exp($module, x, /)\n--\n\n" - "Return e raised to the power of x.") -FUNC1(expm1, m_expm1, 1, - "expm1($module, x, /)\n--\n\n" - "Return exp(x)-1.\n\n" - "This function avoids the loss of precision involved in the direct " - "evaluation of exp(x)-1 for small x.") -FUNC1(fabs, fabs, 0, - "fabs($module, x, /)\n--\n\n" - "Return the absolute value of the float x.") - -/*[clinic input] -math.floor - - x as number: object - / - -Return the floor of x as an Integral. - -This is the largest integer <= x. -[clinic start generated code]*/ - -static PyObject * -math_floor(PyObject *module, PyObject *number) -/*[clinic end generated code: output=c6a65c4884884b8a input=63af6b5d7ebcc3d6]*/ -{ +} + +FUNC2(copysign, copysign, + "copysign($module, x, y, /)\n--\n\n" + "Return a float with the magnitude (absolute value) of x but the sign of y.\n\n" + "On platforms that support signed zeros, copysign(1.0, -0.0)\n" + "returns -1.0.\n") +FUNC1(cos, cos, 0, + "cos($module, x, /)\n--\n\n" + "Return the cosine of x (measured in radians).") +FUNC1(cosh, cosh, 1, + "cosh($module, x, /)\n--\n\n" + "Return the hyperbolic cosine of x.") +FUNC1A(erf, m_erf, + "erf($module, x, /)\n--\n\n" + "Error function at x.") +FUNC1A(erfc, m_erfc, + "erfc($module, x, /)\n--\n\n" + "Complementary error function at x.") +FUNC1(exp, exp, 1, + "exp($module, x, /)\n--\n\n" + "Return e raised to the power of x.") +FUNC1(expm1, m_expm1, 1, + "expm1($module, x, /)\n--\n\n" + "Return exp(x)-1.\n\n" + "This function avoids the loss of precision involved in the direct " + "evaluation of exp(x)-1 for small x.") +FUNC1(fabs, fabs, 0, + "fabs($module, x, /)\n--\n\n" + "Return the absolute value of the float x.") + +/*[clinic input] +math.floor + + x as number: object + / + +Return the floor of x as an Integral. + +This is the largest integer <= x. +[clinic start generated code]*/ + +static PyObject * +math_floor(PyObject *module, PyObject *number) +/*[clinic end generated code: output=c6a65c4884884b8a input=63af6b5d7ebcc3d6]*/ +{ double x; - _Py_IDENTIFIER(__floor__); - + _Py_IDENTIFIER(__floor__); + if (PyFloat_CheckExact(number)) { x = PyFloat_AS_DOUBLE(number); } @@ -1274,286 +1274,286 @@ math_floor(PyObject *module, PyObject *number) Py_DECREF(method); return result; } - if (PyErr_Occurred()) - return NULL; + if (PyErr_Occurred()) + return NULL; x = PyFloat_AsDouble(number); if (x == -1.0 && PyErr_Occurred()) return NULL; - } + } return PyLong_FromDouble(floor(x)); -} - -FUNC1A(gamma, m_tgamma, - "gamma($module, x, /)\n--\n\n" - "Gamma function at x.") -FUNC1A(lgamma, m_lgamma, - "lgamma($module, x, /)\n--\n\n" - "Natural logarithm of absolute value of Gamma function at x.") -FUNC1(log1p, m_log1p, 0, - "log1p($module, x, /)\n--\n\n" - "Return the natural logarithm of 1+x (base e).\n\n" - "The result is computed in a way which is accurate for x near zero.") -FUNC2(remainder, m_remainder, - "remainder($module, x, y, /)\n--\n\n" - "Difference between x and the closest integer multiple of y.\n\n" - "Return x - n*y where n*y is the closest integer multiple of y.\n" - "In the case where x is exactly halfway between two multiples of\n" - "y, the nearest even value of n is used. The result is always exact.") -FUNC1(sin, sin, 0, - "sin($module, x, /)\n--\n\n" - "Return the sine of x (measured in radians).") -FUNC1(sinh, sinh, 1, - "sinh($module, x, /)\n--\n\n" - "Return the hyperbolic sine of x.") -FUNC1(sqrt, sqrt, 0, - "sqrt($module, x, /)\n--\n\n" - "Return the square root of x.") -FUNC1(tan, tan, 0, - "tan($module, x, /)\n--\n\n" - "Return the tangent of x (measured in radians).") -FUNC1(tanh, tanh, 0, - "tanh($module, x, /)\n--\n\n" - "Return the hyperbolic tangent of x.") - -/* Precision summation function as msum() by Raymond Hettinger in - , - enhanced with the exact partials sum and roundoff from Mark - Dickinson's post at . - See those links for more details, proofs and other references. - - Note 1: IEEE 754R floating point semantics are assumed, - but the current implementation does not re-establish special - value semantics across iterations (i.e. handling -Inf + Inf). - - Note 2: No provision is made for intermediate overflow handling; - therefore, sum([1e+308, 1e-308, 1e+308]) returns 1e+308 while - sum([1e+308, 1e+308, 1e-308]) raises an OverflowError due to the - overflow of the first partial sum. - - Note 3: The intermediate values lo, yr, and hi are declared volatile so - aggressive compilers won't algebraically reduce lo to always be exactly 0.0. - Also, the volatile declaration forces the values to be stored in memory as - regular doubles instead of extended long precision (80-bit) values. This - prevents double rounding because any addition or subtraction of two doubles - can be resolved exactly into double-sized hi and lo values. As long as the - hi value gets forced into a double before yr and lo are computed, the extra - bits in downstream extended precision operations (x87 for example) will be - exactly zero and therefore can be losslessly stored back into a double, - thereby preventing double rounding. - - Note 4: A similar implementation is in Modules/cmathmodule.c. - Be sure to update both when making changes. - - Note 5: The signature of math.fsum() differs from builtins.sum() - because the start argument doesn't make sense in the context of - accurate summation. Since the partials table is collapsed before - returning a result, sum(seq2, start=sum(seq1)) may not equal the - accurate result returned by sum(itertools.chain(seq1, seq2)). -*/ - -#define NUM_PARTIALS 32 /* initial partials array size, on stack */ - -/* Extend the partials array p[] by doubling its size. */ -static int /* non-zero on error */ -_fsum_realloc(double **p_ptr, Py_ssize_t n, - double *ps, Py_ssize_t *m_ptr) -{ - void *v = NULL; - Py_ssize_t m = *m_ptr; - - m += m; /* double */ - if (n < m && (size_t)m < ((size_t)PY_SSIZE_T_MAX / sizeof(double))) { - double *p = *p_ptr; - if (p == ps) { - v = PyMem_Malloc(sizeof(double) * m); - if (v != NULL) - memcpy(v, ps, sizeof(double) * n); - } - else - v = PyMem_Realloc(p, sizeof(double) * m); - } - if (v == NULL) { /* size overflow or no memory */ - PyErr_SetString(PyExc_MemoryError, "math.fsum partials"); - return 1; - } - *p_ptr = (double*) v; - *m_ptr = m; - return 0; -} - -/* Full precision summation of a sequence of floats. - - def msum(iterable): - partials = [] # sorted, non-overlapping partial sums - for x in iterable: - i = 0 - for y in partials: - if abs(x) < abs(y): - x, y = y, x - hi = x + y - lo = y - (hi - x) - if lo: - partials[i] = lo - i += 1 - x = hi - partials[i:] = [x] - return sum_exact(partials) - - Rounded x+y stored in hi with the roundoff stored in lo. Together hi+lo - are exactly equal to x+y. The inner loop applies hi/lo summation to each - partial so that the list of partial sums remains exact. - - Sum_exact() adds the partial sums exactly and correctly rounds the final - result (using the round-half-to-even rule). The items in partials remain - non-zero, non-special, non-overlapping and strictly increasing in - magnitude, but possibly not all having the same sign. - - Depends on IEEE 754 arithmetic guarantees and half-even rounding. -*/ - -/*[clinic input] -math.fsum - - seq: object - / - -Return an accurate floating point sum of values in the iterable seq. - -Assumes IEEE-754 floating point arithmetic. -[clinic start generated code]*/ - -static PyObject * -math_fsum(PyObject *module, PyObject *seq) -/*[clinic end generated code: output=ba5c672b87fe34fc input=c51b7d8caf6f6e82]*/ -{ - PyObject *item, *iter, *sum = NULL; - Py_ssize_t i, j, n = 0, m = NUM_PARTIALS; - double x, y, t, ps[NUM_PARTIALS], *p = ps; - double xsave, special_sum = 0.0, inf_sum = 0.0; - volatile double hi, yr, lo; - - iter = PyObject_GetIter(seq); - if (iter == NULL) - return NULL; - - for(;;) { /* for x in iterable */ - assert(0 <= n && n <= m); - assert((m == NUM_PARTIALS && p == ps) || - (m > NUM_PARTIALS && p != NULL)); - - item = PyIter_Next(iter); - if (item == NULL) { - if (PyErr_Occurred()) - goto _fsum_error; - break; - } +} + +FUNC1A(gamma, m_tgamma, + "gamma($module, x, /)\n--\n\n" + "Gamma function at x.") +FUNC1A(lgamma, m_lgamma, + "lgamma($module, x, /)\n--\n\n" + "Natural logarithm of absolute value of Gamma function at x.") +FUNC1(log1p, m_log1p, 0, + "log1p($module, x, /)\n--\n\n" + "Return the natural logarithm of 1+x (base e).\n\n" + "The result is computed in a way which is accurate for x near zero.") +FUNC2(remainder, m_remainder, + "remainder($module, x, y, /)\n--\n\n" + "Difference between x and the closest integer multiple of y.\n\n" + "Return x - n*y where n*y is the closest integer multiple of y.\n" + "In the case where x is exactly halfway between two multiples of\n" + "y, the nearest even value of n is used. The result is always exact.") +FUNC1(sin, sin, 0, + "sin($module, x, /)\n--\n\n" + "Return the sine of x (measured in radians).") +FUNC1(sinh, sinh, 1, + "sinh($module, x, /)\n--\n\n" + "Return the hyperbolic sine of x.") +FUNC1(sqrt, sqrt, 0, + "sqrt($module, x, /)\n--\n\n" + "Return the square root of x.") +FUNC1(tan, tan, 0, + "tan($module, x, /)\n--\n\n" + "Return the tangent of x (measured in radians).") +FUNC1(tanh, tanh, 0, + "tanh($module, x, /)\n--\n\n" + "Return the hyperbolic tangent of x.") + +/* Precision summation function as msum() by Raymond Hettinger in + , + enhanced with the exact partials sum and roundoff from Mark + Dickinson's post at . + See those links for more details, proofs and other references. + + Note 1: IEEE 754R floating point semantics are assumed, + but the current implementation does not re-establish special + value semantics across iterations (i.e. handling -Inf + Inf). + + Note 2: No provision is made for intermediate overflow handling; + therefore, sum([1e+308, 1e-308, 1e+308]) returns 1e+308 while + sum([1e+308, 1e+308, 1e-308]) raises an OverflowError due to the + overflow of the first partial sum. + + Note 3: The intermediate values lo, yr, and hi are declared volatile so + aggressive compilers won't algebraically reduce lo to always be exactly 0.0. + Also, the volatile declaration forces the values to be stored in memory as + regular doubles instead of extended long precision (80-bit) values. This + prevents double rounding because any addition or subtraction of two doubles + can be resolved exactly into double-sized hi and lo values. As long as the + hi value gets forced into a double before yr and lo are computed, the extra + bits in downstream extended precision operations (x87 for example) will be + exactly zero and therefore can be losslessly stored back into a double, + thereby preventing double rounding. + + Note 4: A similar implementation is in Modules/cmathmodule.c. + Be sure to update both when making changes. + + Note 5: The signature of math.fsum() differs from builtins.sum() + because the start argument doesn't make sense in the context of + accurate summation. Since the partials table is collapsed before + returning a result, sum(seq2, start=sum(seq1)) may not equal the + accurate result returned by sum(itertools.chain(seq1, seq2)). +*/ + +#define NUM_PARTIALS 32 /* initial partials array size, on stack */ + +/* Extend the partials array p[] by doubling its size. */ +static int /* non-zero on error */ +_fsum_realloc(double **p_ptr, Py_ssize_t n, + double *ps, Py_ssize_t *m_ptr) +{ + void *v = NULL; + Py_ssize_t m = *m_ptr; + + m += m; /* double */ + if (n < m && (size_t)m < ((size_t)PY_SSIZE_T_MAX / sizeof(double))) { + double *p = *p_ptr; + if (p == ps) { + v = PyMem_Malloc(sizeof(double) * m); + if (v != NULL) + memcpy(v, ps, sizeof(double) * n); + } + else + v = PyMem_Realloc(p, sizeof(double) * m); + } + if (v == NULL) { /* size overflow or no memory */ + PyErr_SetString(PyExc_MemoryError, "math.fsum partials"); + return 1; + } + *p_ptr = (double*) v; + *m_ptr = m; + return 0; +} + +/* Full precision summation of a sequence of floats. + + def msum(iterable): + partials = [] # sorted, non-overlapping partial sums + for x in iterable: + i = 0 + for y in partials: + if abs(x) < abs(y): + x, y = y, x + hi = x + y + lo = y - (hi - x) + if lo: + partials[i] = lo + i += 1 + x = hi + partials[i:] = [x] + return sum_exact(partials) + + Rounded x+y stored in hi with the roundoff stored in lo. Together hi+lo + are exactly equal to x+y. The inner loop applies hi/lo summation to each + partial so that the list of partial sums remains exact. + + Sum_exact() adds the partial sums exactly and correctly rounds the final + result (using the round-half-to-even rule). The items in partials remain + non-zero, non-special, non-overlapping and strictly increasing in + magnitude, but possibly not all having the same sign. + + Depends on IEEE 754 arithmetic guarantees and half-even rounding. +*/ + +/*[clinic input] +math.fsum + + seq: object + / + +Return an accurate floating point sum of values in the iterable seq. + +Assumes IEEE-754 floating point arithmetic. +[clinic start generated code]*/ + +static PyObject * +math_fsum(PyObject *module, PyObject *seq) +/*[clinic end generated code: output=ba5c672b87fe34fc input=c51b7d8caf6f6e82]*/ +{ + PyObject *item, *iter, *sum = NULL; + Py_ssize_t i, j, n = 0, m = NUM_PARTIALS; + double x, y, t, ps[NUM_PARTIALS], *p = ps; + double xsave, special_sum = 0.0, inf_sum = 0.0; + volatile double hi, yr, lo; + + iter = PyObject_GetIter(seq); + if (iter == NULL) + return NULL; + + for(;;) { /* for x in iterable */ + assert(0 <= n && n <= m); + assert((m == NUM_PARTIALS && p == ps) || + (m > NUM_PARTIALS && p != NULL)); + + item = PyIter_Next(iter); + if (item == NULL) { + if (PyErr_Occurred()) + goto _fsum_error; + break; + } ASSIGN_DOUBLE(x, item, error_with_item); - Py_DECREF(item); - - xsave = x; - for (i = j = 0; j < n; j++) { /* for y in partials */ - y = p[j]; - if (fabs(x) < fabs(y)) { - t = x; x = y; y = t; - } - hi = x + y; - yr = hi - x; - lo = y - yr; - if (lo != 0.0) - p[i++] = lo; - x = hi; - } - - n = i; /* ps[i:] = [x] */ - if (x != 0.0) { - if (! Py_IS_FINITE(x)) { - /* a nonfinite x could arise either as - a result of intermediate overflow, or - as a result of a nan or inf in the - summands */ - if (Py_IS_FINITE(xsave)) { - PyErr_SetString(PyExc_OverflowError, - "intermediate overflow in fsum"); - goto _fsum_error; - } - if (Py_IS_INFINITY(xsave)) - inf_sum += xsave; - special_sum += xsave; - /* reset partials */ - n = 0; - } - else if (n >= m && _fsum_realloc(&p, n, ps, &m)) - goto _fsum_error; - else - p[n++] = x; - } - } - - if (special_sum != 0.0) { - if (Py_IS_NAN(inf_sum)) - PyErr_SetString(PyExc_ValueError, - "-inf + inf in fsum"); - else - sum = PyFloat_FromDouble(special_sum); - goto _fsum_error; - } - - hi = 0.0; - if (n > 0) { - hi = p[--n]; - /* sum_exact(ps, hi) from the top, stop when the sum becomes - inexact. */ - while (n > 0) { - x = hi; - y = p[--n]; - assert(fabs(y) < fabs(x)); - hi = x + y; - yr = hi - x; - lo = y - yr; - if (lo != 0.0) - break; - } - /* Make half-even rounding work across multiple partials. - Needed so that sum([1e-16, 1, 1e16]) will round-up the last - digit to two instead of down to zero (the 1e-16 makes the 1 - slightly closer to two). With a potential 1 ULP rounding - error fixed-up, math.fsum() can guarantee commutativity. */ - if (n > 0 && ((lo < 0.0 && p[n-1] < 0.0) || - (lo > 0.0 && p[n-1] > 0.0))) { - y = lo * 2.0; - x = hi + y; - yr = x - hi; - if (y == yr) - hi = x; - } - } - sum = PyFloat_FromDouble(hi); - + Py_DECREF(item); + + xsave = x; + for (i = j = 0; j < n; j++) { /* for y in partials */ + y = p[j]; + if (fabs(x) < fabs(y)) { + t = x; x = y; y = t; + } + hi = x + y; + yr = hi - x; + lo = y - yr; + if (lo != 0.0) + p[i++] = lo; + x = hi; + } + + n = i; /* ps[i:] = [x] */ + if (x != 0.0) { + if (! Py_IS_FINITE(x)) { + /* a nonfinite x could arise either as + a result of intermediate overflow, or + as a result of a nan or inf in the + summands */ + if (Py_IS_FINITE(xsave)) { + PyErr_SetString(PyExc_OverflowError, + "intermediate overflow in fsum"); + goto _fsum_error; + } + if (Py_IS_INFINITY(xsave)) + inf_sum += xsave; + special_sum += xsave; + /* reset partials */ + n = 0; + } + else if (n >= m && _fsum_realloc(&p, n, ps, &m)) + goto _fsum_error; + else + p[n++] = x; + } + } + + if (special_sum != 0.0) { + if (Py_IS_NAN(inf_sum)) + PyErr_SetString(PyExc_ValueError, + "-inf + inf in fsum"); + else + sum = PyFloat_FromDouble(special_sum); + goto _fsum_error; + } + + hi = 0.0; + if (n > 0) { + hi = p[--n]; + /* sum_exact(ps, hi) from the top, stop when the sum becomes + inexact. */ + while (n > 0) { + x = hi; + y = p[--n]; + assert(fabs(y) < fabs(x)); + hi = x + y; + yr = hi - x; + lo = y - yr; + if (lo != 0.0) + break; + } + /* Make half-even rounding work across multiple partials. + Needed so that sum([1e-16, 1, 1e16]) will round-up the last + digit to two instead of down to zero (the 1e-16 makes the 1 + slightly closer to two). With a potential 1 ULP rounding + error fixed-up, math.fsum() can guarantee commutativity. */ + if (n > 0 && ((lo < 0.0 && p[n-1] < 0.0) || + (lo > 0.0 && p[n-1] > 0.0))) { + y = lo * 2.0; + x = hi + y; + yr = x - hi; + if (y == yr) + hi = x; + } + } + sum = PyFloat_FromDouble(hi); + _fsum_error: - Py_DECREF(iter); - if (p != ps) - PyMem_Free(p); - return sum; + Py_DECREF(iter); + if (p != ps) + PyMem_Free(p); + return sum; error_with_item: Py_DECREF(item); goto _fsum_error; -} - -#undef NUM_PARTIALS - - -static unsigned long -count_set_bits(unsigned long n) -{ - unsigned long count = 0; - while (n != 0) { - ++count; - n &= n - 1; /* clear least significant bit */ - } - return count; -} - +} + +#undef NUM_PARTIALS + + +static unsigned long +count_set_bits(unsigned long n) +{ + unsigned long count = 0; + while (n != 0) { + ++count; + n &= n - 1; /* clear least significant bit */ + } + return count; +} + /* Integer square root Given a nonnegative integer `n`, we want to compute the largest integer @@ -1762,681 +1762,681 @@ math_isqrt(PyObject *module, PyObject *n) if (c <= 31U) { m = (uint64_t)PyLong_AsUnsignedLongLong(n); Py_DECREF(n); - if (m == (uint64_t)(-1) && PyErr_Occurred()) { - return NULL; - } - u = _approximate_isqrt(m << (62U - 2U*c)) >> (31U - c); - u -= u * u - 1U >= m; - return PyLong_FromUnsignedLongLong((unsigned long long)u); - } - - /* Slow path: n >= 2**64. We perform the first five iterations in C integer - arithmetic, then switch to using Python long integers. */ - - /* From n >= 2**64 it follows that c.bit_length() >= 6. */ - c_bit_length = 6; - while ((c >> c_bit_length) > 0U) { - ++c_bit_length; - } - - /* Initialise d and a. */ - d = c >> (c_bit_length - 5); - b = _PyLong_Rshift(n, 2U*c - 62U); - if (b == NULL) { - goto error; - } - m = (uint64_t)PyLong_AsUnsignedLongLong(b); - Py_DECREF(b); - if (m == (uint64_t)(-1) && PyErr_Occurred()) { - goto error; - } - u = _approximate_isqrt(m) >> (31U - d); - a = PyLong_FromUnsignedLongLong((unsigned long long)u); - if (a == NULL) { - goto error; - } - - for (int s = c_bit_length - 6; s >= 0; --s) { - PyObject *q; - size_t e = d; - - d = c >> s; - - /* q = (n >> 2*c - e - d + 1) // a */ - q = _PyLong_Rshift(n, 2U*c - d - e + 1U); - if (q == NULL) { - goto error; - } - Py_SETREF(q, PyNumber_FloorDivide(q, a)); - if (q == NULL) { - goto error; - } - - /* a = (a << d - 1 - e) + q */ - Py_SETREF(a, _PyLong_Lshift(a, d - 1U - e)); - if (a == NULL) { - Py_DECREF(q); - goto error; - } - Py_SETREF(a, PyNumber_Add(a, q)); - Py_DECREF(q); - if (a == NULL) { - goto error; - } - } - - /* The correct result is either a or a - 1. Figure out which, and - decrement a if necessary. */ - - /* a_too_large = n < a * a */ - b = PyNumber_Multiply(a, a); - if (b == NULL) { - goto error; - } - a_too_large = PyObject_RichCompareBool(n, b, Py_LT); - Py_DECREF(b); - if (a_too_large == -1) { - goto error; - } - - if (a_too_large) { - Py_SETREF(a, PyNumber_Subtract(a, _PyLong_One)); - } - Py_DECREF(n); - return a; - - error: - Py_XDECREF(a); - Py_DECREF(n); - return NULL; -} - -/* Divide-and-conquer factorial algorithm - * - * Based on the formula and pseudo-code provided at: - * http://www.luschny.de/math/factorial/binarysplitfact.html - * - * Faster algorithms exist, but they're more complicated and depend on - * a fast prime factorization algorithm. - * - * Notes on the algorithm - * ---------------------- - * - * factorial(n) is written in the form 2**k * m, with m odd. k and m are - * computed separately, and then combined using a left shift. - * - * The function factorial_odd_part computes the odd part m (i.e., the greatest - * odd divisor) of factorial(n), using the formula: - * - * factorial_odd_part(n) = - * - * product_{i >= 0} product_{0 < j <= n / 2**i, j odd} j - * - * Example: factorial_odd_part(20) = - * - * (1) * - * (1) * - * (1 * 3 * 5) * - * (1 * 3 * 5 * 7 * 9) - * (1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19) - * - * Here i goes from large to small: the first term corresponds to i=4 (any - * larger i gives an empty product), and the last term corresponds to i=0. - * Each term can be computed from the last by multiplying by the extra odd - * numbers required: e.g., to get from the penultimate term to the last one, - * we multiply by (11 * 13 * 15 * 17 * 19). - * - * To see a hint of why this formula works, here are the same numbers as above - * but with the even parts (i.e., the appropriate powers of 2) included. For - * each subterm in the product for i, we multiply that subterm by 2**i: - * - * factorial(20) = - * - * (16) * - * (8) * - * (4 * 12 * 20) * - * (2 * 6 * 10 * 14 * 18) * - * (1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19) - * - * The factorial_partial_product function computes the product of all odd j in - * range(start, stop) for given start and stop. It's used to compute the - * partial products like (11 * 13 * 15 * 17 * 19) in the example above. It - * operates recursively, repeatedly splitting the range into two roughly equal - * pieces until the subranges are small enough to be computed using only C - * integer arithmetic. - * - * The two-valuation k (i.e., the exponent of the largest power of 2 dividing - * the factorial) is computed independently in the main math_factorial - * function. By standard results, its value is: - * - * two_valuation = n//2 + n//4 + n//8 + .... - * - * It can be shown (e.g., by complete induction on n) that two_valuation is - * equal to n - count_set_bits(n), where count_set_bits(n) gives the number of - * '1'-bits in the binary expansion of n. - */ - -/* factorial_partial_product: Compute product(range(start, stop, 2)) using - * divide and conquer. Assumes start and stop are odd and stop > start. - * max_bits must be >= bit_length(stop - 2). */ - -static PyObject * -factorial_partial_product(unsigned long start, unsigned long stop, - unsigned long max_bits) -{ - unsigned long midpoint, num_operands; - PyObject *left = NULL, *right = NULL, *result = NULL; - - /* If the return value will fit an unsigned long, then we can - * multiply in a tight, fast loop where each multiply is O(1). - * Compute an upper bound on the number of bits required to store - * the answer. - * - * Storing some integer z requires floor(lg(z))+1 bits, which is - * conveniently the value returned by bit_length(z). The - * product x*y will require at most - * bit_length(x) + bit_length(y) bits to store, based - * on the idea that lg product = lg x + lg y. - * - * We know that stop - 2 is the largest number to be multiplied. From - * there, we have: bit_length(answer) <= num_operands * - * bit_length(stop - 2) - */ - - num_operands = (stop - start) / 2; - /* The "num_operands <= 8 * SIZEOF_LONG" check guards against the - * unlikely case of an overflow in num_operands * max_bits. */ - if (num_operands <= 8 * SIZEOF_LONG && - num_operands * max_bits <= 8 * SIZEOF_LONG) { - unsigned long j, total; - for (total = start, j = start + 2; j < stop; j += 2) - total *= j; - return PyLong_FromUnsignedLong(total); - } - - /* find midpoint of range(start, stop), rounded up to next odd number. */ - midpoint = (start + num_operands) | 1; - left = factorial_partial_product(start, midpoint, - _Py_bit_length(midpoint - 2)); - if (left == NULL) - goto error; - right = factorial_partial_product(midpoint, stop, max_bits); - if (right == NULL) - goto error; - result = PyNumber_Multiply(left, right); - - error: - Py_XDECREF(left); - Py_XDECREF(right); - return result; -} - -/* factorial_odd_part: compute the odd part of factorial(n). */ - -static PyObject * -factorial_odd_part(unsigned long n) -{ - long i; - unsigned long v, lower, upper; - PyObject *partial, *tmp, *inner, *outer; - - inner = PyLong_FromLong(1); - if (inner == NULL) - return NULL; - outer = inner; - Py_INCREF(outer); - - upper = 3; - for (i = _Py_bit_length(n) - 2; i >= 0; i--) { - v = n >> i; - if (v <= 2) - continue; - lower = upper; - /* (v + 1) | 1 = least odd integer strictly larger than n / 2**i */ - upper = (v + 1) | 1; - /* Here inner is the product of all odd integers j in the range (0, - n/2**(i+1)]. The factorial_partial_product call below gives the - product of all odd integers j in the range (n/2**(i+1), n/2**i]. */ - partial = factorial_partial_product(lower, upper, _Py_bit_length(upper-2)); - /* inner *= partial */ - if (partial == NULL) - goto error; - tmp = PyNumber_Multiply(inner, partial); - Py_DECREF(partial); - if (tmp == NULL) - goto error; - Py_DECREF(inner); - inner = tmp; - /* Now inner is the product of all odd integers j in the range (0, - n/2**i], giving the inner product in the formula above. */ - - /* outer *= inner; */ - tmp = PyNumber_Multiply(outer, inner); - if (tmp == NULL) - goto error; - Py_DECREF(outer); - outer = tmp; - } - Py_DECREF(inner); - return outer; - - error: - Py_DECREF(outer); - Py_DECREF(inner); - return NULL; -} - - -/* Lookup table for small factorial values */ - -static const unsigned long SmallFactorials[] = { - 1, 1, 2, 6, 24, 120, 720, 5040, 40320, - 362880, 3628800, 39916800, 479001600, -#if SIZEOF_LONG >= 8 - 6227020800, 87178291200, 1307674368000, - 20922789888000, 355687428096000, 6402373705728000, - 121645100408832000, 2432902008176640000 -#endif -}; - -/*[clinic input] -math.factorial - - x as arg: object - / - -Find x!. - -Raise a ValueError if x is negative or non-integral. -[clinic start generated code]*/ - -static PyObject * -math_factorial(PyObject *module, PyObject *arg) -/*[clinic end generated code: output=6686f26fae00e9ca input=6d1c8105c0d91fb4]*/ -{ - long x, two_valuation; - int overflow; - PyObject *result, *odd_part, *pyint_form; - - if (PyFloat_Check(arg)) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "Using factorial() with floats is deprecated", - 1) < 0) - { - return NULL; - } - PyObject *lx; - double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg); - if (!(Py_IS_FINITE(dx) && dx == floor(dx))) { - PyErr_SetString(PyExc_ValueError, - "factorial() only accepts integral values"); - return NULL; - } - lx = PyLong_FromDouble(dx); - if (lx == NULL) - return NULL; - x = PyLong_AsLongAndOverflow(lx, &overflow); - Py_DECREF(lx); - } - else { - pyint_form = PyNumber_Index(arg); - if (pyint_form == NULL) { - return NULL; - } - x = PyLong_AsLongAndOverflow(pyint_form, &overflow); - Py_DECREF(pyint_form); - } - - if (x == -1 && PyErr_Occurred()) { - return NULL; - } - else if (overflow == 1) { - PyErr_Format(PyExc_OverflowError, - "factorial() argument should not exceed %ld", - LONG_MAX); - return NULL; - } - else if (overflow == -1 || x < 0) { - PyErr_SetString(PyExc_ValueError, - "factorial() not defined for negative values"); - return NULL; - } - - /* use lookup table if x is small */ - if (x < (long)Py_ARRAY_LENGTH(SmallFactorials)) - return PyLong_FromUnsignedLong(SmallFactorials[x]); - - /* else express in the form odd_part * 2**two_valuation, and compute as - odd_part << two_valuation. */ - odd_part = factorial_odd_part(x); - if (odd_part == NULL) - return NULL; - two_valuation = x - count_set_bits(x); - result = _PyLong_Lshift(odd_part, two_valuation); - Py_DECREF(odd_part); - return result; -} - - -/*[clinic input] -math.trunc - - x: object - / - -Truncates the Real x to the nearest Integral toward 0. - -Uses the __trunc__ magic method. -[clinic start generated code]*/ - -static PyObject * -math_trunc(PyObject *module, PyObject *x) -/*[clinic end generated code: output=34b9697b707e1031 input=2168b34e0a09134d]*/ -{ - _Py_IDENTIFIER(__trunc__); - PyObject *trunc, *result; - - if (PyFloat_CheckExact(x)) { - return PyFloat_Type.tp_as_number->nb_int(x); - } - - if (Py_TYPE(x)->tp_dict == NULL) { - if (PyType_Ready(Py_TYPE(x)) < 0) - return NULL; - } - - trunc = _PyObject_LookupSpecial(x, &PyId___trunc__); - if (trunc == NULL) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_TypeError, - "type %.100s doesn't define __trunc__ method", - Py_TYPE(x)->tp_name); - return NULL; - } - result = _PyObject_CallNoArg(trunc); - Py_DECREF(trunc); - return result; -} - - -/*[clinic input] -math.frexp - - x: double - / - -Return the mantissa and exponent of x, as pair (m, e). - -m is a float and e is an int, such that x = m * 2.**e. -If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0. -[clinic start generated code]*/ - -static PyObject * -math_frexp_impl(PyObject *module, double x) -/*[clinic end generated code: output=03e30d252a15ad4a input=96251c9e208bc6e9]*/ -{ - int i; - /* deal with special cases directly, to sidestep platform - differences */ - if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) { - i = 0; - } - else { - x = frexp(x, &i); - } - return Py_BuildValue("(di)", x, i); -} - - -/*[clinic input] -math.ldexp - - x: double - i: object - / - -Return x * (2**i). - -This is essentially the inverse of frexp(). -[clinic start generated code]*/ - -static PyObject * -math_ldexp_impl(PyObject *module, double x, PyObject *i) -/*[clinic end generated code: output=b6892f3c2df9cc6a input=17d5970c1a40a8c1]*/ -{ - double r; - long exp; - int overflow; - - if (PyLong_Check(i)) { - /* on overflow, replace exponent with either LONG_MAX - or LONG_MIN, depending on the sign. */ - exp = PyLong_AsLongAndOverflow(i, &overflow); - if (exp == -1 && PyErr_Occurred()) - return NULL; - if (overflow) - exp = overflow < 0 ? LONG_MIN : LONG_MAX; - } - else { - PyErr_SetString(PyExc_TypeError, - "Expected an int as second argument to ldexp."); - return NULL; - } - - if (x == 0. || !Py_IS_FINITE(x)) { - /* NaNs, zeros and infinities are returned unchanged */ - r = x; - errno = 0; - } else if (exp > INT_MAX) { - /* overflow */ - r = copysign(Py_HUGE_VAL, x); - errno = ERANGE; - } else if (exp < INT_MIN) { - /* underflow to +-0 */ - r = copysign(0., x); - errno = 0; - } else { - errno = 0; - r = ldexp(x, (int)exp); - if (Py_IS_INFINITY(r)) - errno = ERANGE; - } - - if (errno && is_error(r)) - return NULL; - return PyFloat_FromDouble(r); -} - - -/*[clinic input] -math.modf - - x: double - / - -Return the fractional and integer parts of x. - -Both results carry the sign of x and are floats. -[clinic start generated code]*/ - -static PyObject * -math_modf_impl(PyObject *module, double x) -/*[clinic end generated code: output=90cee0260014c3c0 input=b4cfb6786afd9035]*/ -{ - double y; - /* some platforms don't do the right thing for NaNs and - infinities, so we take care of special cases directly. */ - if (!Py_IS_FINITE(x)) { - if (Py_IS_INFINITY(x)) - return Py_BuildValue("(dd)", copysign(0., x), x); - else if (Py_IS_NAN(x)) - return Py_BuildValue("(dd)", x, x); - } - - errno = 0; - x = modf(x, &y); - return Py_BuildValue("(dd)", x, y); -} - - -/* A decent logarithm is easy to compute even for huge ints, but libm can't - do that by itself -- loghelper can. func is log or log10, and name is - "log" or "log10". Note that overflow of the result isn't possible: an int - can contain no more than INT_MAX * SHIFT bits, so has value certainly less - than 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is - small enough to fit in an IEEE single. log and log10 are even smaller. - However, intermediate overflow is possible for an int if the number of bits - in that int is larger than PY_SSIZE_T_MAX. */ - -static PyObject* -loghelper(PyObject* arg, double (*func)(double), const char *funcname) -{ - /* If it is int, do it ourselves. */ - if (PyLong_Check(arg)) { - double x, result; - Py_ssize_t e; - - /* Negative or zero inputs give a ValueError. */ - if (Py_SIZE(arg) <= 0) { - PyErr_SetString(PyExc_ValueError, - "math domain error"); - return NULL; - } - - x = PyLong_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - /* Here the conversion to double overflowed, but it's possible - to compute the log anyway. Clear the exception and continue. */ - PyErr_Clear(); - x = _PyLong_Frexp((PyLongObject *)arg, &e); - if (x == -1.0 && PyErr_Occurred()) - return NULL; - /* Value is ~= x * 2**e, so the log ~= log(x) + log(2) * e. */ - result = func(x) + func(2.0) * e; - } - else - /* Successfully converted x to a double. */ - result = func(x); - return PyFloat_FromDouble(result); - } - - /* Else let libm handle it by itself. */ - return math_1(arg, func, 0); -} - - -/*[clinic input] -math.log - - x: object - [ - base: object(c_default="NULL") = math.e - ] - / - -Return the logarithm of x to the given base. - -If the base not specified, returns the natural logarithm (base e) of x. -[clinic start generated code]*/ - -static PyObject * -math_log_impl(PyObject *module, PyObject *x, int group_right_1, - PyObject *base) -/*[clinic end generated code: output=7b5a39e526b73fc9 input=0f62d5726cbfebbd]*/ -{ - PyObject *num, *den; - PyObject *ans; - - num = loghelper(x, m_log, "log"); - if (num == NULL || base == NULL) - return num; - - den = loghelper(base, m_log, "log"); - if (den == NULL) { - Py_DECREF(num); - return NULL; - } - - ans = PyNumber_TrueDivide(num, den); - Py_DECREF(num); - Py_DECREF(den); - return ans; -} - - -/*[clinic input] -math.log2 - - x: object - / - -Return the base 2 logarithm of x. -[clinic start generated code]*/ - -static PyObject * -math_log2(PyObject *module, PyObject *x) -/*[clinic end generated code: output=5425899a4d5d6acb input=08321262bae4f39b]*/ -{ - return loghelper(x, m_log2, "log2"); -} + if (m == (uint64_t)(-1) && PyErr_Occurred()) { + return NULL; + } + u = _approximate_isqrt(m << (62U - 2U*c)) >> (31U - c); + u -= u * u - 1U >= m; + return PyLong_FromUnsignedLongLong((unsigned long long)u); + } + /* Slow path: n >= 2**64. We perform the first five iterations in C integer + arithmetic, then switch to using Python long integers. */ -/*[clinic input] -math.log10 + /* From n >= 2**64 it follows that c.bit_length() >= 6. */ + c_bit_length = 6; + while ((c >> c_bit_length) > 0U) { + ++c_bit_length; + } - x: object - / + /* Initialise d and a. */ + d = c >> (c_bit_length - 5); + b = _PyLong_Rshift(n, 2U*c - 62U); + if (b == NULL) { + goto error; + } + m = (uint64_t)PyLong_AsUnsignedLongLong(b); + Py_DECREF(b); + if (m == (uint64_t)(-1) && PyErr_Occurred()) { + goto error; + } + u = _approximate_isqrt(m) >> (31U - d); + a = PyLong_FromUnsignedLongLong((unsigned long long)u); + if (a == NULL) { + goto error; + } -Return the base 10 logarithm of x. -[clinic start generated code]*/ + for (int s = c_bit_length - 6; s >= 0; --s) { + PyObject *q; + size_t e = d; -static PyObject * -math_log10(PyObject *module, PyObject *x) -/*[clinic end generated code: output=be72a64617df9c6f input=b2469d02c6469e53]*/ -{ - return loghelper(x, m_log10, "log10"); -} + d = c >> s; + /* q = (n >> 2*c - e - d + 1) // a */ + q = _PyLong_Rshift(n, 2U*c - d - e + 1U); + if (q == NULL) { + goto error; + } + Py_SETREF(q, PyNumber_FloorDivide(q, a)); + if (q == NULL) { + goto error; + } -/*[clinic input] -math.fmod + /* a = (a << d - 1 - e) + q */ + Py_SETREF(a, _PyLong_Lshift(a, d - 1U - e)); + if (a == NULL) { + Py_DECREF(q); + goto error; + } + Py_SETREF(a, PyNumber_Add(a, q)); + Py_DECREF(q); + if (a == NULL) { + goto error; + } + } - x: double - y: double - / + /* The correct result is either a or a - 1. Figure out which, and + decrement a if necessary. */ -Return fmod(x, y), according to platform C. + /* a_too_large = n < a * a */ + b = PyNumber_Multiply(a, a); + if (b == NULL) { + goto error; + } + a_too_large = PyObject_RichCompareBool(n, b, Py_LT); + Py_DECREF(b); + if (a_too_large == -1) { + goto error; + } -x % y may differ. -[clinic start generated code]*/ + if (a_too_large) { + Py_SETREF(a, PyNumber_Subtract(a, _PyLong_One)); + } + Py_DECREF(n); + return a; -static PyObject * -math_fmod_impl(PyObject *module, double x, double y) -/*[clinic end generated code: output=7559d794343a27b5 input=4f84caa8cfc26a03]*/ -{ - double r; - /* fmod(x, +/-Inf) returns x for finite x. */ - if (Py_IS_INFINITY(y) && Py_IS_FINITE(x)) - return PyFloat_FromDouble(x); - errno = 0; - r = fmod(x, y); - if (Py_IS_NAN(r)) { - if (!Py_IS_NAN(x) && !Py_IS_NAN(y)) - errno = EDOM; - else - errno = 0; - } - if (errno && is_error(r)) - return NULL; - else - return PyFloat_FromDouble(r); + error: + Py_XDECREF(a); + Py_DECREF(n); + return NULL; } +/* Divide-and-conquer factorial algorithm + * + * Based on the formula and pseudo-code provided at: + * http://www.luschny.de/math/factorial/binarysplitfact.html + * + * Faster algorithms exist, but they're more complicated and depend on + * a fast prime factorization algorithm. + * + * Notes on the algorithm + * ---------------------- + * + * factorial(n) is written in the form 2**k * m, with m odd. k and m are + * computed separately, and then combined using a left shift. + * + * The function factorial_odd_part computes the odd part m (i.e., the greatest + * odd divisor) of factorial(n), using the formula: + * + * factorial_odd_part(n) = + * + * product_{i >= 0} product_{0 < j <= n / 2**i, j odd} j + * + * Example: factorial_odd_part(20) = + * + * (1) * + * (1) * + * (1 * 3 * 5) * + * (1 * 3 * 5 * 7 * 9) + * (1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19) + * + * Here i goes from large to small: the first term corresponds to i=4 (any + * larger i gives an empty product), and the last term corresponds to i=0. + * Each term can be computed from the last by multiplying by the extra odd + * numbers required: e.g., to get from the penultimate term to the last one, + * we multiply by (11 * 13 * 15 * 17 * 19). + * + * To see a hint of why this formula works, here are the same numbers as above + * but with the even parts (i.e., the appropriate powers of 2) included. For + * each subterm in the product for i, we multiply that subterm by 2**i: + * + * factorial(20) = + * + * (16) * + * (8) * + * (4 * 12 * 20) * + * (2 * 6 * 10 * 14 * 18) * + * (1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * 19) + * + * The factorial_partial_product function computes the product of all odd j in + * range(start, stop) for given start and stop. It's used to compute the + * partial products like (11 * 13 * 15 * 17 * 19) in the example above. It + * operates recursively, repeatedly splitting the range into two roughly equal + * pieces until the subranges are small enough to be computed using only C + * integer arithmetic. + * + * The two-valuation k (i.e., the exponent of the largest power of 2 dividing + * the factorial) is computed independently in the main math_factorial + * function. By standard results, its value is: + * + * two_valuation = n//2 + n//4 + n//8 + .... + * + * It can be shown (e.g., by complete induction on n) that two_valuation is + * equal to n - count_set_bits(n), where count_set_bits(n) gives the number of + * '1'-bits in the binary expansion of n. + */ + +/* factorial_partial_product: Compute product(range(start, stop, 2)) using + * divide and conquer. Assumes start and stop are odd and stop > start. + * max_bits must be >= bit_length(stop - 2). */ + +static PyObject * +factorial_partial_product(unsigned long start, unsigned long stop, + unsigned long max_bits) +{ + unsigned long midpoint, num_operands; + PyObject *left = NULL, *right = NULL, *result = NULL; + + /* If the return value will fit an unsigned long, then we can + * multiply in a tight, fast loop where each multiply is O(1). + * Compute an upper bound on the number of bits required to store + * the answer. + * + * Storing some integer z requires floor(lg(z))+1 bits, which is + * conveniently the value returned by bit_length(z). The + * product x*y will require at most + * bit_length(x) + bit_length(y) bits to store, based + * on the idea that lg product = lg x + lg y. + * + * We know that stop - 2 is the largest number to be multiplied. From + * there, we have: bit_length(answer) <= num_operands * + * bit_length(stop - 2) + */ + + num_operands = (stop - start) / 2; + /* The "num_operands <= 8 * SIZEOF_LONG" check guards against the + * unlikely case of an overflow in num_operands * max_bits. */ + if (num_operands <= 8 * SIZEOF_LONG && + num_operands * max_bits <= 8 * SIZEOF_LONG) { + unsigned long j, total; + for (total = start, j = start + 2; j < stop; j += 2) + total *= j; + return PyLong_FromUnsignedLong(total); + } + + /* find midpoint of range(start, stop), rounded up to next odd number. */ + midpoint = (start + num_operands) | 1; + left = factorial_partial_product(start, midpoint, + _Py_bit_length(midpoint - 2)); + if (left == NULL) + goto error; + right = factorial_partial_product(midpoint, stop, max_bits); + if (right == NULL) + goto error; + result = PyNumber_Multiply(left, right); + + error: + Py_XDECREF(left); + Py_XDECREF(right); + return result; +} + +/* factorial_odd_part: compute the odd part of factorial(n). */ + +static PyObject * +factorial_odd_part(unsigned long n) +{ + long i; + unsigned long v, lower, upper; + PyObject *partial, *tmp, *inner, *outer; + + inner = PyLong_FromLong(1); + if (inner == NULL) + return NULL; + outer = inner; + Py_INCREF(outer); + + upper = 3; + for (i = _Py_bit_length(n) - 2; i >= 0; i--) { + v = n >> i; + if (v <= 2) + continue; + lower = upper; + /* (v + 1) | 1 = least odd integer strictly larger than n / 2**i */ + upper = (v + 1) | 1; + /* Here inner is the product of all odd integers j in the range (0, + n/2**(i+1)]. The factorial_partial_product call below gives the + product of all odd integers j in the range (n/2**(i+1), n/2**i]. */ + partial = factorial_partial_product(lower, upper, _Py_bit_length(upper-2)); + /* inner *= partial */ + if (partial == NULL) + goto error; + tmp = PyNumber_Multiply(inner, partial); + Py_DECREF(partial); + if (tmp == NULL) + goto error; + Py_DECREF(inner); + inner = tmp; + /* Now inner is the product of all odd integers j in the range (0, + n/2**i], giving the inner product in the formula above. */ + + /* outer *= inner; */ + tmp = PyNumber_Multiply(outer, inner); + if (tmp == NULL) + goto error; + Py_DECREF(outer); + outer = tmp; + } + Py_DECREF(inner); + return outer; + + error: + Py_DECREF(outer); + Py_DECREF(inner); + return NULL; +} + + +/* Lookup table for small factorial values */ + +static const unsigned long SmallFactorials[] = { + 1, 1, 2, 6, 24, 120, 720, 5040, 40320, + 362880, 3628800, 39916800, 479001600, +#if SIZEOF_LONG >= 8 + 6227020800, 87178291200, 1307674368000, + 20922789888000, 355687428096000, 6402373705728000, + 121645100408832000, 2432902008176640000 +#endif +}; + +/*[clinic input] +math.factorial + + x as arg: object + / + +Find x!. + +Raise a ValueError if x is negative or non-integral. +[clinic start generated code]*/ + +static PyObject * +math_factorial(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=6686f26fae00e9ca input=6d1c8105c0d91fb4]*/ +{ + long x, two_valuation; + int overflow; + PyObject *result, *odd_part, *pyint_form; + + if (PyFloat_Check(arg)) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Using factorial() with floats is deprecated", + 1) < 0) + { + return NULL; + } + PyObject *lx; + double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg); + if (!(Py_IS_FINITE(dx) && dx == floor(dx))) { + PyErr_SetString(PyExc_ValueError, + "factorial() only accepts integral values"); + return NULL; + } + lx = PyLong_FromDouble(dx); + if (lx == NULL) + return NULL; + x = PyLong_AsLongAndOverflow(lx, &overflow); + Py_DECREF(lx); + } + else { + pyint_form = PyNumber_Index(arg); + if (pyint_form == NULL) { + return NULL; + } + x = PyLong_AsLongAndOverflow(pyint_form, &overflow); + Py_DECREF(pyint_form); + } + + if (x == -1 && PyErr_Occurred()) { + return NULL; + } + else if (overflow == 1) { + PyErr_Format(PyExc_OverflowError, + "factorial() argument should not exceed %ld", + LONG_MAX); + return NULL; + } + else if (overflow == -1 || x < 0) { + PyErr_SetString(PyExc_ValueError, + "factorial() not defined for negative values"); + return NULL; + } + + /* use lookup table if x is small */ + if (x < (long)Py_ARRAY_LENGTH(SmallFactorials)) + return PyLong_FromUnsignedLong(SmallFactorials[x]); + + /* else express in the form odd_part * 2**two_valuation, and compute as + odd_part << two_valuation. */ + odd_part = factorial_odd_part(x); + if (odd_part == NULL) + return NULL; + two_valuation = x - count_set_bits(x); + result = _PyLong_Lshift(odd_part, two_valuation); + Py_DECREF(odd_part); + return result; +} + + +/*[clinic input] +math.trunc + + x: object + / + +Truncates the Real x to the nearest Integral toward 0. + +Uses the __trunc__ magic method. +[clinic start generated code]*/ + +static PyObject * +math_trunc(PyObject *module, PyObject *x) +/*[clinic end generated code: output=34b9697b707e1031 input=2168b34e0a09134d]*/ +{ + _Py_IDENTIFIER(__trunc__); + PyObject *trunc, *result; + + if (PyFloat_CheckExact(x)) { + return PyFloat_Type.tp_as_number->nb_int(x); + } + + if (Py_TYPE(x)->tp_dict == NULL) { + if (PyType_Ready(Py_TYPE(x)) < 0) + return NULL; + } + + trunc = _PyObject_LookupSpecial(x, &PyId___trunc__); + if (trunc == NULL) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "type %.100s doesn't define __trunc__ method", + Py_TYPE(x)->tp_name); + return NULL; + } + result = _PyObject_CallNoArg(trunc); + Py_DECREF(trunc); + return result; +} + + +/*[clinic input] +math.frexp + + x: double + / + +Return the mantissa and exponent of x, as pair (m, e). + +m is a float and e is an int, such that x = m * 2.**e. +If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0. +[clinic start generated code]*/ + +static PyObject * +math_frexp_impl(PyObject *module, double x) +/*[clinic end generated code: output=03e30d252a15ad4a input=96251c9e208bc6e9]*/ +{ + int i; + /* deal with special cases directly, to sidestep platform + differences */ + if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) { + i = 0; + } + else { + x = frexp(x, &i); + } + return Py_BuildValue("(di)", x, i); +} + + +/*[clinic input] +math.ldexp + + x: double + i: object + / + +Return x * (2**i). + +This is essentially the inverse of frexp(). +[clinic start generated code]*/ + +static PyObject * +math_ldexp_impl(PyObject *module, double x, PyObject *i) +/*[clinic end generated code: output=b6892f3c2df9cc6a input=17d5970c1a40a8c1]*/ +{ + double r; + long exp; + int overflow; + + if (PyLong_Check(i)) { + /* on overflow, replace exponent with either LONG_MAX + or LONG_MIN, depending on the sign. */ + exp = PyLong_AsLongAndOverflow(i, &overflow); + if (exp == -1 && PyErr_Occurred()) + return NULL; + if (overflow) + exp = overflow < 0 ? LONG_MIN : LONG_MAX; + } + else { + PyErr_SetString(PyExc_TypeError, + "Expected an int as second argument to ldexp."); + return NULL; + } + + if (x == 0. || !Py_IS_FINITE(x)) { + /* NaNs, zeros and infinities are returned unchanged */ + r = x; + errno = 0; + } else if (exp > INT_MAX) { + /* overflow */ + r = copysign(Py_HUGE_VAL, x); + errno = ERANGE; + } else if (exp < INT_MIN) { + /* underflow to +-0 */ + r = copysign(0., x); + errno = 0; + } else { + errno = 0; + r = ldexp(x, (int)exp); + if (Py_IS_INFINITY(r)) + errno = ERANGE; + } + + if (errno && is_error(r)) + return NULL; + return PyFloat_FromDouble(r); +} + + +/*[clinic input] +math.modf + + x: double + / + +Return the fractional and integer parts of x. + +Both results carry the sign of x and are floats. +[clinic start generated code]*/ + +static PyObject * +math_modf_impl(PyObject *module, double x) +/*[clinic end generated code: output=90cee0260014c3c0 input=b4cfb6786afd9035]*/ +{ + double y; + /* some platforms don't do the right thing for NaNs and + infinities, so we take care of special cases directly. */ + if (!Py_IS_FINITE(x)) { + if (Py_IS_INFINITY(x)) + return Py_BuildValue("(dd)", copysign(0., x), x); + else if (Py_IS_NAN(x)) + return Py_BuildValue("(dd)", x, x); + } + + errno = 0; + x = modf(x, &y); + return Py_BuildValue("(dd)", x, y); +} + + +/* A decent logarithm is easy to compute even for huge ints, but libm can't + do that by itself -- loghelper can. func is log or log10, and name is + "log" or "log10". Note that overflow of the result isn't possible: an int + can contain no more than INT_MAX * SHIFT bits, so has value certainly less + than 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is + small enough to fit in an IEEE single. log and log10 are even smaller. + However, intermediate overflow is possible for an int if the number of bits + in that int is larger than PY_SSIZE_T_MAX. */ + +static PyObject* +loghelper(PyObject* arg, double (*func)(double), const char *funcname) +{ + /* If it is int, do it ourselves. */ + if (PyLong_Check(arg)) { + double x, result; + Py_ssize_t e; + + /* Negative or zero inputs give a ValueError. */ + if (Py_SIZE(arg) <= 0) { + PyErr_SetString(PyExc_ValueError, + "math domain error"); + return NULL; + } + + x = PyLong_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + /* Here the conversion to double overflowed, but it's possible + to compute the log anyway. Clear the exception and continue. */ + PyErr_Clear(); + x = _PyLong_Frexp((PyLongObject *)arg, &e); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + /* Value is ~= x * 2**e, so the log ~= log(x) + log(2) * e. */ + result = func(x) + func(2.0) * e; + } + else + /* Successfully converted x to a double. */ + result = func(x); + return PyFloat_FromDouble(result); + } + + /* Else let libm handle it by itself. */ + return math_1(arg, func, 0); +} + + +/*[clinic input] +math.log + + x: object + [ + base: object(c_default="NULL") = math.e + ] + / + +Return the logarithm of x to the given base. + +If the base not specified, returns the natural logarithm (base e) of x. +[clinic start generated code]*/ + +static PyObject * +math_log_impl(PyObject *module, PyObject *x, int group_right_1, + PyObject *base) +/*[clinic end generated code: output=7b5a39e526b73fc9 input=0f62d5726cbfebbd]*/ +{ + PyObject *num, *den; + PyObject *ans; + + num = loghelper(x, m_log, "log"); + if (num == NULL || base == NULL) + return num; + + den = loghelper(base, m_log, "log"); + if (den == NULL) { + Py_DECREF(num); + return NULL; + } + + ans = PyNumber_TrueDivide(num, den); + Py_DECREF(num); + Py_DECREF(den); + return ans; +} + + +/*[clinic input] +math.log2 + + x: object + / + +Return the base 2 logarithm of x. +[clinic start generated code]*/ + +static PyObject * +math_log2(PyObject *module, PyObject *x) +/*[clinic end generated code: output=5425899a4d5d6acb input=08321262bae4f39b]*/ +{ + return loghelper(x, m_log2, "log2"); +} + + +/*[clinic input] +math.log10 + + x: object + / + +Return the base 10 logarithm of x. +[clinic start generated code]*/ + +static PyObject * +math_log10(PyObject *module, PyObject *x) +/*[clinic end generated code: output=be72a64617df9c6f input=b2469d02c6469e53]*/ +{ + return loghelper(x, m_log10, "log10"); +} + + +/*[clinic input] +math.fmod + + x: double + y: double + / + +Return fmod(x, y), according to platform C. + +x % y may differ. +[clinic start generated code]*/ + +static PyObject * +math_fmod_impl(PyObject *module, double x, double y) +/*[clinic end generated code: output=7559d794343a27b5 input=4f84caa8cfc26a03]*/ +{ + double r; + /* fmod(x, +/-Inf) returns x for finite x. */ + if (Py_IS_INFINITY(y) && Py_IS_FINITE(x)) + return PyFloat_FromDouble(x); + errno = 0; + r = fmod(x, y); + if (Py_IS_NAN(r)) { + if (!Py_IS_NAN(x) && !Py_IS_NAN(y)) + errno = EDOM; + else + errno = 0; + } + if (errno && is_error(r)) + return NULL; + else + return PyFloat_FromDouble(r); +} + /* Given an *n* length *vec* of values and a value *max*, compute: - + max * sqrt(sum((x / max) ** 2 for x in vec)) The value of the *max* variable must be non-negative and @@ -2495,13 +2495,13 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) #define NUM_STACK_ELEMS 16 -/*[clinic input] +/*[clinic input] math.dist - + p: object q: object - / - + / + Return the Euclidean distance between two points p and q. The points should be specified as sequences (or iterables) of @@ -2509,12 +2509,12 @@ coordinates. Both inputs must have the same dimension. Roughly equivalent to: sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q))) -[clinic start generated code]*/ - -static PyObject * +[clinic start generated code]*/ + +static PyObject * math_dist_impl(PyObject *module, PyObject *p, PyObject *q) /*[clinic end generated code: output=56bd9538d06bbcfe input=74e85e1b6092e68e]*/ -{ +{ PyObject *item; double max = 0.0; double x, px, qx, result; @@ -2529,7 +2529,7 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) return NULL; } p_allocated = 1; - } + } if (!PyTuple_Check(q)) { q = PySequence_Tuple(q); if (q == NULL) { @@ -2539,14 +2539,14 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) return NULL; } q_allocated = 1; - } + } m = PyTuple_GET_SIZE(p); n = PyTuple_GET_SIZE(q); if (m != n) { PyErr_SetString(PyExc_ValueError, "both points must have the same number of dimensions"); - return NULL; + return NULL; } if (n > NUM_STACK_ELEMS) { @@ -2590,8 +2590,8 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) Py_DECREF(q); } return NULL; -} - +} + /* AC: cannot convert yet, waiting for *args support */ static PyObject * math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs) @@ -2603,7 +2603,7 @@ math_hypot(PyObject *self, PyObject *const *args, Py_ssize_t nargs) int found_nan = 0; double coord_on_stack[NUM_STACK_ELEMS]; double *coordinates = coord_on_stack; - + if (nargs > NUM_STACK_ELEMS) { coordinates = (double *) PyObject_Malloc(nargs * sizeof(double)); if (coordinates == NULL) { @@ -2651,251 +2651,251 @@ For example, the hypotenuse of a 3/4/5 right triangle is:\n\ 5.0\n\ "); -/* pow can't use math_2, but needs its own wrapper: the problem is - that an infinite result can arise either as a result of overflow - (in which case OverflowError should be raised) or as a result of - e.g. 0.**-5. (for which ValueError needs to be raised.) -*/ - -/*[clinic input] -math.pow - - x: double - y: double - / - -Return x**y (x to the power of y). -[clinic start generated code]*/ - -static PyObject * -math_pow_impl(PyObject *module, double x, double y) -/*[clinic end generated code: output=fff93e65abccd6b0 input=c26f1f6075088bfd]*/ -{ - double r; - int odd_y; - - /* deal directly with IEEE specials, to cope with problems on various - platforms whose semantics don't exactly match C99 */ - r = 0.; /* silence compiler warning */ - if (!Py_IS_FINITE(x) || !Py_IS_FINITE(y)) { - errno = 0; - if (Py_IS_NAN(x)) - r = y == 0. ? 1. : x; /* NaN**0 = 1 */ - else if (Py_IS_NAN(y)) - r = x == 1. ? 1. : y; /* 1**NaN = 1 */ - else if (Py_IS_INFINITY(x)) { - odd_y = Py_IS_FINITE(y) && fmod(fabs(y), 2.0) == 1.0; - if (y > 0.) - r = odd_y ? x : fabs(x); - else if (y == 0.) - r = 1.; - else /* y < 0. */ - r = odd_y ? copysign(0., x) : 0.; - } - else if (Py_IS_INFINITY(y)) { - if (fabs(x) == 1.0) - r = 1.; - else if (y > 0. && fabs(x) > 1.0) - r = y; - else if (y < 0. && fabs(x) < 1.0) { - r = -y; /* result is +inf */ - if (x == 0.) /* 0**-inf: divide-by-zero */ - errno = EDOM; - } - else - r = 0.; - } - } - else { - /* let libm handle finite**finite */ - errno = 0; - r = pow(x, y); - /* a NaN result should arise only from (-ve)**(finite - non-integer); in this case we want to raise ValueError. */ - if (!Py_IS_FINITE(r)) { - if (Py_IS_NAN(r)) { - errno = EDOM; - } - /* - an infinite result here arises either from: - (A) (+/-0.)**negative (-> divide-by-zero) - (B) overflow of x**y with x and y finite - */ - else if (Py_IS_INFINITY(r)) { - if (x == 0.) - errno = EDOM; - else - errno = ERANGE; - } - } - } - - if (errno && is_error(r)) - return NULL; - else - return PyFloat_FromDouble(r); -} - - -static const double degToRad = Py_MATH_PI / 180.0; -static const double radToDeg = 180.0 / Py_MATH_PI; - -/*[clinic input] -math.degrees - - x: double - / - -Convert angle x from radians to degrees. -[clinic start generated code]*/ - -static PyObject * -math_degrees_impl(PyObject *module, double x) -/*[clinic end generated code: output=7fea78b294acd12f input=81e016555d6e3660]*/ -{ - return PyFloat_FromDouble(x * radToDeg); -} - - -/*[clinic input] -math.radians - - x: double - / - -Convert angle x from degrees to radians. -[clinic start generated code]*/ - -static PyObject * -math_radians_impl(PyObject *module, double x) -/*[clinic end generated code: output=34daa47caf9b1590 input=91626fc489fe3d63]*/ -{ - return PyFloat_FromDouble(x * degToRad); -} - - -/*[clinic input] -math.isfinite - - x: double - / - -Return True if x is neither an infinity nor a NaN, and False otherwise. -[clinic start generated code]*/ - -static PyObject * -math_isfinite_impl(PyObject *module, double x) -/*[clinic end generated code: output=8ba1f396440c9901 input=46967d254812e54a]*/ -{ - return PyBool_FromLong((long)Py_IS_FINITE(x)); -} - - -/*[clinic input] -math.isnan - - x: double - / - -Return True if x is a NaN (not a number), and False otherwise. -[clinic start generated code]*/ - -static PyObject * -math_isnan_impl(PyObject *module, double x) -/*[clinic end generated code: output=f537b4d6df878c3e input=935891e66083f46a]*/ -{ - return PyBool_FromLong((long)Py_IS_NAN(x)); -} - - -/*[clinic input] -math.isinf - - x: double - / - -Return True if x is a positive or negative infinity, and False otherwise. -[clinic start generated code]*/ - -static PyObject * -math_isinf_impl(PyObject *module, double x) -/*[clinic end generated code: output=9f00cbec4de7b06b input=32630e4212cf961f]*/ -{ - return PyBool_FromLong((long)Py_IS_INFINITY(x)); -} - - -/*[clinic input] -math.isclose -> bool - - a: double - b: double - * - rel_tol: double = 1e-09 - maximum difference for being considered "close", relative to the - magnitude of the input values - abs_tol: double = 0.0 - maximum difference for being considered "close", regardless of the - magnitude of the input values - -Determine whether two floating point numbers are close in value. - -Return True if a is close in value to b, and False otherwise. - -For the values to be considered close, the difference between them -must be smaller than at least one of the tolerances. - --inf, inf and NaN behave similarly to the IEEE 754 Standard. That -is, NaN is not close to anything, even itself. inf and -inf are -only close to themselves. -[clinic start generated code]*/ - -static int -math_isclose_impl(PyObject *module, double a, double b, double rel_tol, - double abs_tol) -/*[clinic end generated code: output=b73070207511952d input=f28671871ea5bfba]*/ -{ - double diff = 0.0; - - /* sanity check on the inputs */ - if (rel_tol < 0.0 || abs_tol < 0.0 ) { - PyErr_SetString(PyExc_ValueError, - "tolerances must be non-negative"); - return -1; - } - - if ( a == b ) { - /* short circuit exact equality -- needed to catch two infinities of - the same sign. And perhaps speeds things up a bit sometimes. - */ - return 1; - } - - /* This catches the case of two infinities of opposite sign, or - one infinity and one finite number. Two infinities of opposite - sign would otherwise have an infinite relative tolerance. - Two infinities of the same sign are caught by the equality check - above. - */ - - if (Py_IS_INFINITY(a) || Py_IS_INFINITY(b)) { - return 0; - } - - /* now do the regular computation - this is essentially the "weak" test from the Boost library - */ - - diff = fabs(b - a); - - return (((diff <= fabs(rel_tol * b)) || - (diff <= fabs(rel_tol * a))) || - (diff <= abs_tol)); -} - +/* pow can't use math_2, but needs its own wrapper: the problem is + that an infinite result can arise either as a result of overflow + (in which case OverflowError should be raised) or as a result of + e.g. 0.**-5. (for which ValueError needs to be raised.) +*/ + +/*[clinic input] +math.pow + + x: double + y: double + / + +Return x**y (x to the power of y). +[clinic start generated code]*/ + +static PyObject * +math_pow_impl(PyObject *module, double x, double y) +/*[clinic end generated code: output=fff93e65abccd6b0 input=c26f1f6075088bfd]*/ +{ + double r; + int odd_y; + + /* deal directly with IEEE specials, to cope with problems on various + platforms whose semantics don't exactly match C99 */ + r = 0.; /* silence compiler warning */ + if (!Py_IS_FINITE(x) || !Py_IS_FINITE(y)) { + errno = 0; + if (Py_IS_NAN(x)) + r = y == 0. ? 1. : x; /* NaN**0 = 1 */ + else if (Py_IS_NAN(y)) + r = x == 1. ? 1. : y; /* 1**NaN = 1 */ + else if (Py_IS_INFINITY(x)) { + odd_y = Py_IS_FINITE(y) && fmod(fabs(y), 2.0) == 1.0; + if (y > 0.) + r = odd_y ? x : fabs(x); + else if (y == 0.) + r = 1.; + else /* y < 0. */ + r = odd_y ? copysign(0., x) : 0.; + } + else if (Py_IS_INFINITY(y)) { + if (fabs(x) == 1.0) + r = 1.; + else if (y > 0. && fabs(x) > 1.0) + r = y; + else if (y < 0. && fabs(x) < 1.0) { + r = -y; /* result is +inf */ + if (x == 0.) /* 0**-inf: divide-by-zero */ + errno = EDOM; + } + else + r = 0.; + } + } + else { + /* let libm handle finite**finite */ + errno = 0; + r = pow(x, y); + /* a NaN result should arise only from (-ve)**(finite + non-integer); in this case we want to raise ValueError. */ + if (!Py_IS_FINITE(r)) { + if (Py_IS_NAN(r)) { + errno = EDOM; + } + /* + an infinite result here arises either from: + (A) (+/-0.)**negative (-> divide-by-zero) + (B) overflow of x**y with x and y finite + */ + else if (Py_IS_INFINITY(r)) { + if (x == 0.) + errno = EDOM; + else + errno = ERANGE; + } + } + } + + if (errno && is_error(r)) + return NULL; + else + return PyFloat_FromDouble(r); +} + + +static const double degToRad = Py_MATH_PI / 180.0; +static const double radToDeg = 180.0 / Py_MATH_PI; + +/*[clinic input] +math.degrees + + x: double + / + +Convert angle x from radians to degrees. +[clinic start generated code]*/ + +static PyObject * +math_degrees_impl(PyObject *module, double x) +/*[clinic end generated code: output=7fea78b294acd12f input=81e016555d6e3660]*/ +{ + return PyFloat_FromDouble(x * radToDeg); +} + + +/*[clinic input] +math.radians + + x: double + / + +Convert angle x from degrees to radians. +[clinic start generated code]*/ + +static PyObject * +math_radians_impl(PyObject *module, double x) +/*[clinic end generated code: output=34daa47caf9b1590 input=91626fc489fe3d63]*/ +{ + return PyFloat_FromDouble(x * degToRad); +} + + +/*[clinic input] +math.isfinite + + x: double + / + +Return True if x is neither an infinity nor a NaN, and False otherwise. +[clinic start generated code]*/ + +static PyObject * +math_isfinite_impl(PyObject *module, double x) +/*[clinic end generated code: output=8ba1f396440c9901 input=46967d254812e54a]*/ +{ + return PyBool_FromLong((long)Py_IS_FINITE(x)); +} + + +/*[clinic input] +math.isnan + + x: double + / + +Return True if x is a NaN (not a number), and False otherwise. +[clinic start generated code]*/ + +static PyObject * +math_isnan_impl(PyObject *module, double x) +/*[clinic end generated code: output=f537b4d6df878c3e input=935891e66083f46a]*/ +{ + return PyBool_FromLong((long)Py_IS_NAN(x)); +} + + +/*[clinic input] +math.isinf + + x: double + / + +Return True if x is a positive or negative infinity, and False otherwise. +[clinic start generated code]*/ + +static PyObject * +math_isinf_impl(PyObject *module, double x) +/*[clinic end generated code: output=9f00cbec4de7b06b input=32630e4212cf961f]*/ +{ + return PyBool_FromLong((long)Py_IS_INFINITY(x)); +} + + +/*[clinic input] +math.isclose -> bool + + a: double + b: double + * + rel_tol: double = 1e-09 + maximum difference for being considered "close", relative to the + magnitude of the input values + abs_tol: double = 0.0 + maximum difference for being considered "close", regardless of the + magnitude of the input values + +Determine whether two floating point numbers are close in value. + +Return True if a is close in value to b, and False otherwise. + +For the values to be considered close, the difference between them +must be smaller than at least one of the tolerances. + +-inf, inf and NaN behave similarly to the IEEE 754 Standard. That +is, NaN is not close to anything, even itself. inf and -inf are +only close to themselves. +[clinic start generated code]*/ + +static int +math_isclose_impl(PyObject *module, double a, double b, double rel_tol, + double abs_tol) +/*[clinic end generated code: output=b73070207511952d input=f28671871ea5bfba]*/ +{ + double diff = 0.0; + + /* sanity check on the inputs */ + if (rel_tol < 0.0 || abs_tol < 0.0 ) { + PyErr_SetString(PyExc_ValueError, + "tolerances must be non-negative"); + return -1; + } + + if ( a == b ) { + /* short circuit exact equality -- needed to catch two infinities of + the same sign. And perhaps speeds things up a bit sometimes. + */ + return 1; + } + + /* This catches the case of two infinities of opposite sign, or + one infinity and one finite number. Two infinities of opposite + sign would otherwise have an infinite relative tolerance. + Two infinities of the same sign are caught by the equality check + above. + */ + + if (Py_IS_INFINITY(a) || Py_IS_INFINITY(b)) { + return 0; + } + + /* now do the regular computation + this is essentially the "weak" test from the Boost library + */ + + diff = fabs(b - a); + + return (((diff <= fabs(rel_tol * b)) || + (diff <= fabs(rel_tol * a))) || + (diff <= abs_tol)); +} + static inline int _check_long_mult_overflow(long a, long b) { - + /* From Python2's int_mul code: Integer overflow checking for * is painful: Python tried a couple ways, but @@ -3449,83 +3449,83 @@ math_exec(PyObject *module) return 0; } -static PyMethodDef math_methods[] = { - {"acos", math_acos, METH_O, math_acos_doc}, - {"acosh", math_acosh, METH_O, math_acosh_doc}, - {"asin", math_asin, METH_O, math_asin_doc}, - {"asinh", math_asinh, METH_O, math_asinh_doc}, - {"atan", math_atan, METH_O, math_atan_doc}, +static PyMethodDef math_methods[] = { + {"acos", math_acos, METH_O, math_acos_doc}, + {"acosh", math_acosh, METH_O, math_acosh_doc}, + {"asin", math_asin, METH_O, math_asin_doc}, + {"asinh", math_asinh, METH_O, math_asinh_doc}, + {"atan", math_atan, METH_O, math_atan_doc}, {"atan2", (PyCFunction)(void(*)(void))math_atan2, METH_FASTCALL, math_atan2_doc}, - {"atanh", math_atanh, METH_O, math_atanh_doc}, - MATH_CEIL_METHODDEF + {"atanh", math_atanh, METH_O, math_atanh_doc}, + MATH_CEIL_METHODDEF {"copysign", (PyCFunction)(void(*)(void))math_copysign, METH_FASTCALL, math_copysign_doc}, - {"cos", math_cos, METH_O, math_cos_doc}, - {"cosh", math_cosh, METH_O, math_cosh_doc}, - MATH_DEGREES_METHODDEF + {"cos", math_cos, METH_O, math_cos_doc}, + {"cosh", math_cosh, METH_O, math_cosh_doc}, + MATH_DEGREES_METHODDEF MATH_DIST_METHODDEF - {"erf", math_erf, METH_O, math_erf_doc}, - {"erfc", math_erfc, METH_O, math_erfc_doc}, - {"exp", math_exp, METH_O, math_exp_doc}, - {"expm1", math_expm1, METH_O, math_expm1_doc}, - {"fabs", math_fabs, METH_O, math_fabs_doc}, - MATH_FACTORIAL_METHODDEF - MATH_FLOOR_METHODDEF - MATH_FMOD_METHODDEF - MATH_FREXP_METHODDEF - MATH_FSUM_METHODDEF - {"gamma", math_gamma, METH_O, math_gamma_doc}, + {"erf", math_erf, METH_O, math_erf_doc}, + {"erfc", math_erfc, METH_O, math_erfc_doc}, + {"exp", math_exp, METH_O, math_exp_doc}, + {"expm1", math_expm1, METH_O, math_expm1_doc}, + {"fabs", math_fabs, METH_O, math_fabs_doc}, + MATH_FACTORIAL_METHODDEF + MATH_FLOOR_METHODDEF + MATH_FMOD_METHODDEF + MATH_FREXP_METHODDEF + MATH_FSUM_METHODDEF + {"gamma", math_gamma, METH_O, math_gamma_doc}, {"gcd", (PyCFunction)(void(*)(void))math_gcd, METH_FASTCALL, math_gcd_doc}, {"hypot", (PyCFunction)(void(*)(void))math_hypot, METH_FASTCALL, math_hypot_doc}, - MATH_ISCLOSE_METHODDEF - MATH_ISFINITE_METHODDEF - MATH_ISINF_METHODDEF - MATH_ISNAN_METHODDEF + MATH_ISCLOSE_METHODDEF + MATH_ISFINITE_METHODDEF + MATH_ISINF_METHODDEF + MATH_ISNAN_METHODDEF MATH_ISQRT_METHODDEF {"lcm", (PyCFunction)(void(*)(void))math_lcm, METH_FASTCALL, math_lcm_doc}, - MATH_LDEXP_METHODDEF - {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, - MATH_LOG_METHODDEF - {"log1p", math_log1p, METH_O, math_log1p_doc}, - MATH_LOG10_METHODDEF - MATH_LOG2_METHODDEF - MATH_MODF_METHODDEF - MATH_POW_METHODDEF - MATH_RADIANS_METHODDEF + MATH_LDEXP_METHODDEF + {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, + MATH_LOG_METHODDEF + {"log1p", math_log1p, METH_O, math_log1p_doc}, + MATH_LOG10_METHODDEF + MATH_LOG2_METHODDEF + MATH_MODF_METHODDEF + MATH_POW_METHODDEF + MATH_RADIANS_METHODDEF {"remainder", (PyCFunction)(void(*)(void))math_remainder, METH_FASTCALL, math_remainder_doc}, - {"sin", math_sin, METH_O, math_sin_doc}, - {"sinh", math_sinh, METH_O, math_sinh_doc}, - {"sqrt", math_sqrt, METH_O, math_sqrt_doc}, - {"tan", math_tan, METH_O, math_tan_doc}, - {"tanh", math_tanh, METH_O, math_tanh_doc}, - MATH_TRUNC_METHODDEF + {"sin", math_sin, METH_O, math_sin_doc}, + {"sinh", math_sinh, METH_O, math_sinh_doc}, + {"sqrt", math_sqrt, METH_O, math_sqrt_doc}, + {"tan", math_tan, METH_O, math_tan_doc}, + {"tanh", math_tanh, METH_O, math_tanh_doc}, + MATH_TRUNC_METHODDEF MATH_PROD_METHODDEF MATH_PERM_METHODDEF MATH_COMB_METHODDEF MATH_NEXTAFTER_METHODDEF MATH_ULP_METHODDEF - {NULL, NULL} /* sentinel */ -}; - + {NULL, NULL} /* sentinel */ +}; + static PyModuleDef_Slot math_slots[] = { {Py_mod_exec, math_exec}, {0, NULL} }; - -PyDoc_STRVAR(module_doc, + +PyDoc_STRVAR(module_doc, "This module provides access to the mathematical functions\n" "defined by the C standard."); - -static struct PyModuleDef mathmodule = { - PyModuleDef_HEAD_INIT, + +static struct PyModuleDef mathmodule = { + PyModuleDef_HEAD_INIT, .m_name = "math", .m_doc = module_doc, .m_size = 0, .m_methods = math_methods, .m_slots = math_slots, -}; - -PyMODINIT_FUNC -PyInit_math(void) -{ +}; + +PyMODINIT_FUNC +PyInit_math(void) +{ return PyModuleDef_Init(&mathmodule); -} +} diff --git a/contrib/tools/python3/src/Modules/md5module.c b/contrib/tools/python3/src/Modules/md5module.c index 6ed843376ae..b6294908e6c 100644 --- a/contrib/tools/python3/src/Modules/md5module.c +++ b/contrib/tools/python3/src/Modules/md5module.c @@ -1,585 +1,585 @@ -/* MD5 module */ - -/* This module provides an interface to the MD5 algorithm */ - -/* See below for information about the original code this module was - based upon. Additional work performed by: - - Andrew Kuchling (amk@amk.ca) - Greg Stein (gstein@lyra.org) - Trevor Perrin (trevp@trevp.net) - - Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) - Licensed to PSF under a Contributor Agreement. - -*/ - -/* MD5 objects */ - -#include "Python.h" -#include "hashlib.h" -#include "pystrhex.h" - -/*[clinic input] -module _md5 -class MD5Type "MD5object *" "&PyType_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6e5261719957a912]*/ - -/* Some useful types */ - -#if SIZEOF_INT == 4 -typedef unsigned int MD5_INT32; /* 32-bit integer */ -typedef long long MD5_INT64; /* 64-bit integer */ -#else -/* not defined. compilation will die. */ -#endif - -/* The MD5 block size and message digest sizes, in bytes */ - -#define MD5_BLOCKSIZE 64 -#define MD5_DIGESTSIZE 16 - -/* The structure for storing MD5 info */ - -struct md5_state { - MD5_INT64 length; - MD5_INT32 state[4], curlen; - unsigned char buf[MD5_BLOCKSIZE]; -}; - -typedef struct { - PyObject_HEAD - - struct md5_state hash_state; -} MD5object; - -#include "clinic/md5module.c.h" - -/* ------------------------------------------------------------------------ - * - * This code for the MD5 algorithm was noted as public domain. The - * original headers are pasted below. - * - * Several changes have been made to make it more compatible with the - * Python environment and desired interface. - * - */ - -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * +/* MD5 module */ + +/* This module provides an interface to the MD5 algorithm */ + +/* See below for information about the original code this module was + based upon. Additional work performed by: + + Andrew Kuchling (amk@amk.ca) + Greg Stein (gstein@lyra.org) + Trevor Perrin (trevp@trevp.net) + + Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) + Licensed to PSF under a Contributor Agreement. + +*/ + +/* MD5 objects */ + +#include "Python.h" +#include "hashlib.h" +#include "pystrhex.h" + +/*[clinic input] +module _md5 +class MD5Type "MD5object *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6e5261719957a912]*/ + +/* Some useful types */ + +#if SIZEOF_INT == 4 +typedef unsigned int MD5_INT32; /* 32-bit integer */ +typedef long long MD5_INT64; /* 64-bit integer */ +#else +/* not defined. compilation will die. */ +#endif + +/* The MD5 block size and message digest sizes, in bytes */ + +#define MD5_BLOCKSIZE 64 +#define MD5_DIGESTSIZE 16 + +/* The structure for storing MD5 info */ + +struct md5_state { + MD5_INT64 length; + MD5_INT32 state[4], curlen; + unsigned char buf[MD5_BLOCKSIZE]; +}; + +typedef struct { + PyObject_HEAD + + struct md5_state hash_state; +} MD5object; + +#include "clinic/md5module.c.h" + +/* ------------------------------------------------------------------------ + * + * This code for the MD5 algorithm was noted as public domain. The + * original headers are pasted below. + * + * Several changes have been made to make it more compatible with the + * Python environment and desired interface. + * + */ + +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * * Tom St Denis, tomstdenis@gmail.com, https://www.libtom.net - */ - -/* rotate the hard way (platform optimizations could be done) */ -#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) - -/* Endian Neutral macros that work on all platforms */ - -#define STORE32L(x, y) \ - { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - -#define LOAD32L(x, y) \ - { x = ((unsigned long)((y)[3] & 255)<<24) | \ - ((unsigned long)((y)[2] & 255)<<16) | \ - ((unsigned long)((y)[1] & 255)<<8) | \ - ((unsigned long)((y)[0] & 255)); } - -#define STORE64L(x, y) \ - { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ - (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ - (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - - -/* MD5 macros */ - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define G(x,y,z) (y ^ (z & (y ^ x))) -#define H(x,y,z) (x^y^z) -#define I(x,y,z) (y^(x|(~z))) - -#define FF(a,b,c,d,M,s,t) \ - a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define GG(a,b,c,d,M,s,t) \ - a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define HH(a,b,c,d,M,s,t) \ - a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define II(a,b,c,d,M,s,t) \ - a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; - - + */ + +/* rotate the hard way (platform optimizations could be done) */ +#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +/* Endian Neutral macros that work on all platforms */ + +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + + +/* MD5 macros */ + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define G(x,y,z) (y ^ (z & (y ^ x))) +#define H(x,y,z) (x^y^z) +#define I(x,y,z) (y^(x|(~z))) + +#define FF(a,b,c,d,M,s,t) \ + a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define GG(a,b,c,d,M,s,t) \ + a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define HH(a,b,c,d,M,s,t) \ + a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b; + +#define II(a,b,c,d,M,s,t) \ + a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; + + static void md5_compress(struct md5_state *md5, const unsigned char *buf) -{ - MD5_INT32 i, W[16], a, b, c, d; - - assert(md5 != NULL); - assert(buf != NULL); - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD32L(W[i], buf + (4*i)); - } - - /* copy state */ - a = md5->state[0]; - b = md5->state[1]; - c = md5->state[2]; - d = md5->state[3]; - - FF(a,b,c,d,W[0],7,0xd76aa478UL) - FF(d,a,b,c,W[1],12,0xe8c7b756UL) - FF(c,d,a,b,W[2],17,0x242070dbUL) - FF(b,c,d,a,W[3],22,0xc1bdceeeUL) - FF(a,b,c,d,W[4],7,0xf57c0fafUL) - FF(d,a,b,c,W[5],12,0x4787c62aUL) - FF(c,d,a,b,W[6],17,0xa8304613UL) - FF(b,c,d,a,W[7],22,0xfd469501UL) - FF(a,b,c,d,W[8],7,0x698098d8UL) - FF(d,a,b,c,W[9],12,0x8b44f7afUL) - FF(c,d,a,b,W[10],17,0xffff5bb1UL) - FF(b,c,d,a,W[11],22,0x895cd7beUL) - FF(a,b,c,d,W[12],7,0x6b901122UL) - FF(d,a,b,c,W[13],12,0xfd987193UL) - FF(c,d,a,b,W[14],17,0xa679438eUL) - FF(b,c,d,a,W[15],22,0x49b40821UL) - GG(a,b,c,d,W[1],5,0xf61e2562UL) - GG(d,a,b,c,W[6],9,0xc040b340UL) - GG(c,d,a,b,W[11],14,0x265e5a51UL) - GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) - GG(a,b,c,d,W[5],5,0xd62f105dUL) - GG(d,a,b,c,W[10],9,0x02441453UL) - GG(c,d,a,b,W[15],14,0xd8a1e681UL) - GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) - GG(a,b,c,d,W[9],5,0x21e1cde6UL) - GG(d,a,b,c,W[14],9,0xc33707d6UL) - GG(c,d,a,b,W[3],14,0xf4d50d87UL) - GG(b,c,d,a,W[8],20,0x455a14edUL) - GG(a,b,c,d,W[13],5,0xa9e3e905UL) - GG(d,a,b,c,W[2],9,0xfcefa3f8UL) - GG(c,d,a,b,W[7],14,0x676f02d9UL) - GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) - HH(a,b,c,d,W[5],4,0xfffa3942UL) - HH(d,a,b,c,W[8],11,0x8771f681UL) - HH(c,d,a,b,W[11],16,0x6d9d6122UL) - HH(b,c,d,a,W[14],23,0xfde5380cUL) - HH(a,b,c,d,W[1],4,0xa4beea44UL) - HH(d,a,b,c,W[4],11,0x4bdecfa9UL) - HH(c,d,a,b,W[7],16,0xf6bb4b60UL) - HH(b,c,d,a,W[10],23,0xbebfbc70UL) - HH(a,b,c,d,W[13],4,0x289b7ec6UL) - HH(d,a,b,c,W[0],11,0xeaa127faUL) - HH(c,d,a,b,W[3],16,0xd4ef3085UL) - HH(b,c,d,a,W[6],23,0x04881d05UL) - HH(a,b,c,d,W[9],4,0xd9d4d039UL) - HH(d,a,b,c,W[12],11,0xe6db99e5UL) - HH(c,d,a,b,W[15],16,0x1fa27cf8UL) - HH(b,c,d,a,W[2],23,0xc4ac5665UL) - II(a,b,c,d,W[0],6,0xf4292244UL) - II(d,a,b,c,W[7],10,0x432aff97UL) - II(c,d,a,b,W[14],15,0xab9423a7UL) - II(b,c,d,a,W[5],21,0xfc93a039UL) - II(a,b,c,d,W[12],6,0x655b59c3UL) - II(d,a,b,c,W[3],10,0x8f0ccc92UL) - II(c,d,a,b,W[10],15,0xffeff47dUL) - II(b,c,d,a,W[1],21,0x85845dd1UL) - II(a,b,c,d,W[8],6,0x6fa87e4fUL) - II(d,a,b,c,W[15],10,0xfe2ce6e0UL) - II(c,d,a,b,W[6],15,0xa3014314UL) - II(b,c,d,a,W[13],21,0x4e0811a1UL) - II(a,b,c,d,W[4],6,0xf7537e82UL) - II(d,a,b,c,W[11],10,0xbd3af235UL) - II(c,d,a,b,W[2],15,0x2ad7d2bbUL) - II(b,c,d,a,W[9],21,0xeb86d391UL) - - md5->state[0] = md5->state[0] + a; - md5->state[1] = md5->state[1] + b; - md5->state[2] = md5->state[2] + c; - md5->state[3] = md5->state[3] + d; -} - - -/** - Initialize the hash state - @param sha1 The hash state you wish to initialize -*/ -static void -md5_init(struct md5_state *md5) -{ - assert(md5 != NULL); - md5->state[0] = 0x67452301UL; - md5->state[1] = 0xefcdab89UL; - md5->state[2] = 0x98badcfeUL; - md5->state[3] = 0x10325476UL; - md5->curlen = 0; - md5->length = 0; -} - -/** - Process a block of memory though the hash - @param sha1 The hash state - @param in The data to hash - @param inlen The length of the data (octets) -*/ -static void -md5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen) -{ - Py_ssize_t n; - - assert(md5 != NULL); - assert(in != NULL); - assert(md5->curlen <= sizeof(md5->buf)); - - while (inlen > 0) { - if (md5->curlen == 0 && inlen >= MD5_BLOCKSIZE) { +{ + MD5_INT32 i, W[16], a, b, c, d; + + assert(md5 != NULL); + assert(buf != NULL); + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(W[i], buf + (4*i)); + } + + /* copy state */ + a = md5->state[0]; + b = md5->state[1]; + c = md5->state[2]; + d = md5->state[3]; + + FF(a,b,c,d,W[0],7,0xd76aa478UL) + FF(d,a,b,c,W[1],12,0xe8c7b756UL) + FF(c,d,a,b,W[2],17,0x242070dbUL) + FF(b,c,d,a,W[3],22,0xc1bdceeeUL) + FF(a,b,c,d,W[4],7,0xf57c0fafUL) + FF(d,a,b,c,W[5],12,0x4787c62aUL) + FF(c,d,a,b,W[6],17,0xa8304613UL) + FF(b,c,d,a,W[7],22,0xfd469501UL) + FF(a,b,c,d,W[8],7,0x698098d8UL) + FF(d,a,b,c,W[9],12,0x8b44f7afUL) + FF(c,d,a,b,W[10],17,0xffff5bb1UL) + FF(b,c,d,a,W[11],22,0x895cd7beUL) + FF(a,b,c,d,W[12],7,0x6b901122UL) + FF(d,a,b,c,W[13],12,0xfd987193UL) + FF(c,d,a,b,W[14],17,0xa679438eUL) + FF(b,c,d,a,W[15],22,0x49b40821UL) + GG(a,b,c,d,W[1],5,0xf61e2562UL) + GG(d,a,b,c,W[6],9,0xc040b340UL) + GG(c,d,a,b,W[11],14,0x265e5a51UL) + GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) + GG(a,b,c,d,W[5],5,0xd62f105dUL) + GG(d,a,b,c,W[10],9,0x02441453UL) + GG(c,d,a,b,W[15],14,0xd8a1e681UL) + GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) + GG(a,b,c,d,W[9],5,0x21e1cde6UL) + GG(d,a,b,c,W[14],9,0xc33707d6UL) + GG(c,d,a,b,W[3],14,0xf4d50d87UL) + GG(b,c,d,a,W[8],20,0x455a14edUL) + GG(a,b,c,d,W[13],5,0xa9e3e905UL) + GG(d,a,b,c,W[2],9,0xfcefa3f8UL) + GG(c,d,a,b,W[7],14,0x676f02d9UL) + GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) + HH(a,b,c,d,W[5],4,0xfffa3942UL) + HH(d,a,b,c,W[8],11,0x8771f681UL) + HH(c,d,a,b,W[11],16,0x6d9d6122UL) + HH(b,c,d,a,W[14],23,0xfde5380cUL) + HH(a,b,c,d,W[1],4,0xa4beea44UL) + HH(d,a,b,c,W[4],11,0x4bdecfa9UL) + HH(c,d,a,b,W[7],16,0xf6bb4b60UL) + HH(b,c,d,a,W[10],23,0xbebfbc70UL) + HH(a,b,c,d,W[13],4,0x289b7ec6UL) + HH(d,a,b,c,W[0],11,0xeaa127faUL) + HH(c,d,a,b,W[3],16,0xd4ef3085UL) + HH(b,c,d,a,W[6],23,0x04881d05UL) + HH(a,b,c,d,W[9],4,0xd9d4d039UL) + HH(d,a,b,c,W[12],11,0xe6db99e5UL) + HH(c,d,a,b,W[15],16,0x1fa27cf8UL) + HH(b,c,d,a,W[2],23,0xc4ac5665UL) + II(a,b,c,d,W[0],6,0xf4292244UL) + II(d,a,b,c,W[7],10,0x432aff97UL) + II(c,d,a,b,W[14],15,0xab9423a7UL) + II(b,c,d,a,W[5],21,0xfc93a039UL) + II(a,b,c,d,W[12],6,0x655b59c3UL) + II(d,a,b,c,W[3],10,0x8f0ccc92UL) + II(c,d,a,b,W[10],15,0xffeff47dUL) + II(b,c,d,a,W[1],21,0x85845dd1UL) + II(a,b,c,d,W[8],6,0x6fa87e4fUL) + II(d,a,b,c,W[15],10,0xfe2ce6e0UL) + II(c,d,a,b,W[6],15,0xa3014314UL) + II(b,c,d,a,W[13],21,0x4e0811a1UL) + II(a,b,c,d,W[4],6,0xf7537e82UL) + II(d,a,b,c,W[11],10,0xbd3af235UL) + II(c,d,a,b,W[2],15,0x2ad7d2bbUL) + II(b,c,d,a,W[9],21,0xeb86d391UL) + + md5->state[0] = md5->state[0] + a; + md5->state[1] = md5->state[1] + b; + md5->state[2] = md5->state[2] + c; + md5->state[3] = md5->state[3] + d; +} + + +/** + Initialize the hash state + @param sha1 The hash state you wish to initialize +*/ +static void +md5_init(struct md5_state *md5) +{ + assert(md5 != NULL); + md5->state[0] = 0x67452301UL; + md5->state[1] = 0xefcdab89UL; + md5->state[2] = 0x98badcfeUL; + md5->state[3] = 0x10325476UL; + md5->curlen = 0; + md5->length = 0; +} + +/** + Process a block of memory though the hash + @param sha1 The hash state + @param in The data to hash + @param inlen The length of the data (octets) +*/ +static void +md5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen) +{ + Py_ssize_t n; + + assert(md5 != NULL); + assert(in != NULL); + assert(md5->curlen <= sizeof(md5->buf)); + + while (inlen > 0) { + if (md5->curlen == 0 && inlen >= MD5_BLOCKSIZE) { md5_compress(md5, in); - md5->length += MD5_BLOCKSIZE * 8; - in += MD5_BLOCKSIZE; - inlen -= MD5_BLOCKSIZE; - } else { - n = Py_MIN(inlen, (Py_ssize_t)(MD5_BLOCKSIZE - md5->curlen)); - memcpy(md5->buf + md5->curlen, in, (size_t)n); - md5->curlen += (MD5_INT32)n; - in += n; - inlen -= n; - if (md5->curlen == MD5_BLOCKSIZE) { - md5_compress(md5, md5->buf); - md5->length += 8*MD5_BLOCKSIZE; - md5->curlen = 0; - } - } - } -} - -/** - Terminate the hash to get the digest - @param sha1 The hash state - @param out [out] The destination of the hash (16 bytes) -*/ -static void -md5_done(struct md5_state *md5, unsigned char *out) -{ - int i; - - assert(md5 != NULL); - assert(out != NULL); - assert(md5->curlen < sizeof(md5->buf)); - - /* increase the length of the message */ - md5->length += md5->curlen * 8; - - /* append the '1' bit */ - md5->buf[md5->curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md5->curlen > 56) { - while (md5->curlen < 64) { - md5->buf[md5->curlen++] = (unsigned char)0; - } - md5_compress(md5, md5->buf); - md5->curlen = 0; - } - - /* pad up to 56 bytes of zeroes */ - while (md5->curlen < 56) { - md5->buf[md5->curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64L(md5->length, md5->buf+56); - md5_compress(md5, md5->buf); - - /* copy output */ - for (i = 0; i < 4; i++) { - STORE32L(md5->state[i], out+(4*i)); - } -} - -/* .Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */ -/* .Revision: 1.10 $ */ -/* .Date: 2007/05/12 14:25:28 $ */ - -/* - * End of copied MD5 code. - * - * ------------------------------------------------------------------------ - */ - -static PyTypeObject MD5type; - - -static MD5object * -newMD5object(void) -{ - return (MD5object *)PyObject_New(MD5object, &MD5type); -} - - -/* Internal methods for a hash object */ - -static void -MD5_dealloc(PyObject *ptr) -{ - PyObject_Del(ptr); -} - - -/* External methods for a hash object */ - -/*[clinic input] -MD5Type.copy - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -MD5Type_copy_impl(MD5object *self) -/*[clinic end generated code: output=596eb36852f02071 input=2c09e6d2493f3079]*/ -{ - MD5object *newobj; - - if ((newobj = newMD5object())==NULL) - return NULL; - - newobj->hash_state = self->hash_state; - return (PyObject *)newobj; -} - -/*[clinic input] -MD5Type.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -MD5Type_digest_impl(MD5object *self) -/*[clinic end generated code: output=eb691dc4190a07ec input=bc0c4397c2994be6]*/ -{ - unsigned char digest[MD5_DIGESTSIZE]; - struct md5_state temp; - - temp = self->hash_state; - md5_done(&temp, digest); - return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); -} - -/*[clinic input] -MD5Type.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -MD5Type_hexdigest_impl(MD5object *self) -/*[clinic end generated code: output=17badced1f3ac932 input=b60b19de644798dd]*/ -{ - unsigned char digest[MD5_DIGESTSIZE]; - struct md5_state temp; - - /* Get the raw (binary) digest value */ - temp = self->hash_state; - md5_done(&temp, digest); - - return _Py_strhex((const char*)digest, MD5_DIGESTSIZE); -} - -/*[clinic input] -MD5Type.update - - obj: object - / - -Update this hash object's state with the provided string. -[clinic start generated code]*/ - -static PyObject * -MD5Type_update(MD5object *self, PyObject *obj) -/*[clinic end generated code: output=f6ad168416338423 input=6e1efcd9ecf17032]*/ -{ - Py_buffer buf; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - - md5_process(&self->hash_state, buf.buf, buf.len); - - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyMethodDef MD5_methods[] = { - MD5TYPE_COPY_METHODDEF - MD5TYPE_DIGEST_METHODDEF - MD5TYPE_HEXDIGEST_METHODDEF - MD5TYPE_UPDATE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -MD5_get_block_size(PyObject *self, void *closure) -{ - return PyLong_FromLong(MD5_BLOCKSIZE); -} - -static PyObject * -MD5_get_name(PyObject *self, void *closure) -{ - return PyUnicode_FromStringAndSize("md5", 3); -} - -static PyObject * -md5_get_digest_size(PyObject *self, void *closure) -{ - return PyLong_FromLong(MD5_DIGESTSIZE); -} - - -static PyGetSetDef MD5_getseters[] = { - {"block_size", - (getter)MD5_get_block_size, NULL, - NULL, - NULL}, - {"name", - (getter)MD5_get_name, NULL, - NULL, - NULL}, - {"digest_size", - (getter)md5_get_digest_size, NULL, - NULL, - NULL}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject MD5type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_md5.md5", /*tp_name*/ - sizeof(MD5object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - MD5_dealloc, /*tp_dealloc*/ + md5->length += MD5_BLOCKSIZE * 8; + in += MD5_BLOCKSIZE; + inlen -= MD5_BLOCKSIZE; + } else { + n = Py_MIN(inlen, (Py_ssize_t)(MD5_BLOCKSIZE - md5->curlen)); + memcpy(md5->buf + md5->curlen, in, (size_t)n); + md5->curlen += (MD5_INT32)n; + in += n; + inlen -= n; + if (md5->curlen == MD5_BLOCKSIZE) { + md5_compress(md5, md5->buf); + md5->length += 8*MD5_BLOCKSIZE; + md5->curlen = 0; + } + } + } +} + +/** + Terminate the hash to get the digest + @param sha1 The hash state + @param out [out] The destination of the hash (16 bytes) +*/ +static void +md5_done(struct md5_state *md5, unsigned char *out) +{ + int i; + + assert(md5 != NULL); + assert(out != NULL); + assert(md5->curlen < sizeof(md5->buf)); + + /* increase the length of the message */ + md5->length += md5->curlen * 8; + + /* append the '1' bit */ + md5->buf[md5->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md5->curlen > 56) { + while (md5->curlen < 64) { + md5->buf[md5->curlen++] = (unsigned char)0; + } + md5_compress(md5, md5->buf); + md5->curlen = 0; + } + + /* pad up to 56 bytes of zeroes */ + while (md5->curlen < 56) { + md5->buf[md5->curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md5->length, md5->buf+56); + md5_compress(md5, md5->buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md5->state[i], out+(4*i)); + } +} + +/* .Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */ +/* .Revision: 1.10 $ */ +/* .Date: 2007/05/12 14:25:28 $ */ + +/* + * End of copied MD5 code. + * + * ------------------------------------------------------------------------ + */ + +static PyTypeObject MD5type; + + +static MD5object * +newMD5object(void) +{ + return (MD5object *)PyObject_New(MD5object, &MD5type); +} + + +/* Internal methods for a hash object */ + +static void +MD5_dealloc(PyObject *ptr) +{ + PyObject_Del(ptr); +} + + +/* External methods for a hash object */ + +/*[clinic input] +MD5Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +MD5Type_copy_impl(MD5object *self) +/*[clinic end generated code: output=596eb36852f02071 input=2c09e6d2493f3079]*/ +{ + MD5object *newobj; + + if ((newobj = newMD5object())==NULL) + return NULL; + + newobj->hash_state = self->hash_state; + return (PyObject *)newobj; +} + +/*[clinic input] +MD5Type.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +MD5Type_digest_impl(MD5object *self) +/*[clinic end generated code: output=eb691dc4190a07ec input=bc0c4397c2994be6]*/ +{ + unsigned char digest[MD5_DIGESTSIZE]; + struct md5_state temp; + + temp = self->hash_state; + md5_done(&temp, digest); + return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); +} + +/*[clinic input] +MD5Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +MD5Type_hexdigest_impl(MD5object *self) +/*[clinic end generated code: output=17badced1f3ac932 input=b60b19de644798dd]*/ +{ + unsigned char digest[MD5_DIGESTSIZE]; + struct md5_state temp; + + /* Get the raw (binary) digest value */ + temp = self->hash_state; + md5_done(&temp, digest); + + return _Py_strhex((const char*)digest, MD5_DIGESTSIZE); +} + +/*[clinic input] +MD5Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +MD5Type_update(MD5object *self, PyObject *obj) +/*[clinic end generated code: output=f6ad168416338423 input=6e1efcd9ecf17032]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + + md5_process(&self->hash_state, buf.buf, buf.len); + + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyMethodDef MD5_methods[] = { + MD5TYPE_COPY_METHODDEF + MD5TYPE_DIGEST_METHODDEF + MD5TYPE_HEXDIGEST_METHODDEF + MD5TYPE_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +MD5_get_block_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(MD5_BLOCKSIZE); +} + +static PyObject * +MD5_get_name(PyObject *self, void *closure) +{ + return PyUnicode_FromStringAndSize("md5", 3); +} + +static PyObject * +md5_get_digest_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(MD5_DIGESTSIZE); +} + + +static PyGetSetDef MD5_getseters[] = { + {"block_size", + (getter)MD5_get_block_size, NULL, + NULL, + NULL}, + {"name", + (getter)MD5_get_name, NULL, + NULL, + NULL}, + {"digest_size", + (getter)md5_get_digest_size, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject MD5type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_md5.md5", /*tp_name*/ + sizeof(MD5object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + MD5_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - MD5_methods, /* tp_methods */ - NULL, /* tp_members */ - MD5_getseters, /* tp_getset */ -}; - - -/* The single module-level function: new() */ - -/*[clinic input] -_md5.md5 - - string: object(c_default="NULL") = b'' + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + MD5_methods, /* tp_methods */ + NULL, /* tp_members */ + MD5_getseters, /* tp_getset */ +}; + + +/* The single module-level function: new() */ + +/*[clinic input] +_md5.md5 + + string: object(c_default="NULL") = b'' * usedforsecurity: bool = True - -Return a new MD5 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * + +Return a new MD5 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * _md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=587071f76254a4ac input=7a144a1905636985]*/ -{ - MD5object *new; - Py_buffer buf; - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newMD5object()) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - md5_init(&new->hash_state); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - md5_process(&new->hash_state, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - - -/* List of functions exported by this module */ - -static struct PyMethodDef MD5_functions[] = { - _MD5_MD5_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ - -static struct PyModuleDef _md5module = { - PyModuleDef_HEAD_INIT, - "_md5", - NULL, - -1, - MD5_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__md5(void) -{ - PyObject *m; - +{ + MD5object *new; + Py_buffer buf; + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newMD5object()) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + md5_init(&new->hash_state); + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + md5_process(&new->hash_state, buf.buf, buf.len); + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + + +/* List of functions exported by this module */ + +static struct PyMethodDef MD5_functions[] = { + _MD5_MD5_METHODDEF + {NULL, NULL} /* Sentinel */ +}; + + +/* Initialize this module. */ + +static struct PyModuleDef _md5module = { + PyModuleDef_HEAD_INIT, + "_md5", + NULL, + -1, + MD5_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__md5(void) +{ + PyObject *m; + Py_SET_TYPE(&MD5type, &PyType_Type); if (PyType_Ready(&MD5type) < 0) { - return NULL; + return NULL; } - - m = PyModule_Create(&_md5module); + + m = PyModule_Create(&_md5module); if (m == NULL) { - return NULL; + return NULL; } - - Py_INCREF((PyObject *)&MD5type); - PyModule_AddObject(m, "MD5Type", (PyObject *)&MD5type); - return m; -} + + Py_INCREF((PyObject *)&MD5type); + PyModule_AddObject(m, "MD5Type", (PyObject *)&MD5type); + return m; +} diff --git a/contrib/tools/python3/src/Modules/mmapmodule.c b/contrib/tools/python3/src/Modules/mmapmodule.c index a3e22d0a511..042aae6aa95 100644 --- a/contrib/tools/python3/src/Modules/mmapmodule.c +++ b/contrib/tools/python3/src/Modules/mmapmodule.c @@ -1,166 +1,166 @@ -/* - / Author: Sam Rushing - / Hacked for Unix by AMK - / $Id$ - - / Modified to support mmap with offset - to map a 'window' of a file - / Author: Yotam Medini yotamm@mellanox.co.il - / - / mmapmodule.cpp -- map a view of a file into memory - / - / todo: need permission flags, perhaps a 'chsize' analog - / not all functions check range yet!!! - / - / - / This version of mmapmodule.c has been changed significantly - / from the original mmapfile.c on which it was based. - / The original version of mmapfile is maintained by Sam at - / ftp://squirl.nightmare.com/pub/python/python-ext. -*/ - -#define PY_SSIZE_T_CLEAN -#include +/* + / Author: Sam Rushing + / Hacked for Unix by AMK + / $Id$ + + / Modified to support mmap with offset - to map a 'window' of a file + / Author: Yotam Medini yotamm@mellanox.co.il + / + / mmapmodule.cpp -- map a view of a file into memory + / + / todo: need permission flags, perhaps a 'chsize' analog + / not all functions check range yet!!! + / + / + / This version of mmapmodule.c has been changed significantly + / from the original mmapfile.c on which it was based. + / The original version of mmapfile is maintained by Sam at + / ftp://squirl.nightmare.com/pub/python/python-ext. +*/ + +#define PY_SSIZE_T_CLEAN +#include #include // offsetof() - -#ifndef MS_WINDOWS -#define UNIX -# ifdef HAVE_FCNTL_H -# include -# endif /* HAVE_FCNTL_H */ -#endif - -#ifdef MS_WINDOWS -#include -static int -my_getpagesize(void) -{ - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwPageSize; -} - -static int -my_getallocationgranularity (void) -{ - - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwAllocationGranularity; -} - -#endif - -#ifdef UNIX -#include -#include - -#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) -static int -my_getpagesize(void) -{ - return sysconf(_SC_PAGESIZE); -} - -#define my_getallocationgranularity my_getpagesize -#else -#define my_getpagesize getpagesize -#endif - -#endif /* UNIX */ - -#include - -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ - -/* Prefer MAP_ANONYMOUS since MAP_ANON is deprecated according to man page. */ -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -# define MAP_ANONYMOUS MAP_ANON -#endif - -typedef enum -{ - ACCESS_DEFAULT, - ACCESS_READ, - ACCESS_WRITE, - ACCESS_COPY -} access_mode; - -typedef struct { - PyObject_HEAD - char * data; - Py_ssize_t size; - Py_ssize_t pos; /* relative to offset */ -#ifdef MS_WINDOWS - long long offset; -#else - off_t offset; -#endif + +#ifndef MS_WINDOWS +#define UNIX +# ifdef HAVE_FCNTL_H +# include +# endif /* HAVE_FCNTL_H */ +#endif + +#ifdef MS_WINDOWS +#include +static int +my_getpagesize(void) +{ + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwPageSize; +} + +static int +my_getallocationgranularity (void) +{ + + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwAllocationGranularity; +} + +#endif + +#ifdef UNIX +#include +#include + +#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) +static int +my_getpagesize(void) +{ + return sysconf(_SC_PAGESIZE); +} + +#define my_getallocationgranularity my_getpagesize +#else +#define my_getpagesize getpagesize +#endif + +#endif /* UNIX */ + +#include + +#ifdef HAVE_SYS_TYPES_H +#include +#endif /* HAVE_SYS_TYPES_H */ + +/* Prefer MAP_ANONYMOUS since MAP_ANON is deprecated according to man page. */ +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +#endif + +typedef enum +{ + ACCESS_DEFAULT, + ACCESS_READ, + ACCESS_WRITE, + ACCESS_COPY +} access_mode; + +typedef struct { + PyObject_HEAD + char * data; + Py_ssize_t size; + Py_ssize_t pos; /* relative to offset */ +#ifdef MS_WINDOWS + long long offset; +#else + off_t offset; +#endif Py_ssize_t exports; - -#ifdef MS_WINDOWS - HANDLE map_handle; - HANDLE file_handle; - char * tagname; -#endif - -#ifdef UNIX - int fd; -#endif - - PyObject *weakreflist; - access_mode access; -} mmap_object; - - -static void -mmap_object_dealloc(mmap_object *m_obj) -{ -#ifdef MS_WINDOWS + +#ifdef MS_WINDOWS + HANDLE map_handle; + HANDLE file_handle; + char * tagname; +#endif + +#ifdef UNIX + int fd; +#endif + + PyObject *weakreflist; + access_mode access; +} mmap_object; + + +static void +mmap_object_dealloc(mmap_object *m_obj) +{ +#ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (m_obj->data != NULL) - UnmapViewOfFile (m_obj->data); - if (m_obj->map_handle != NULL) - CloseHandle (m_obj->map_handle); - if (m_obj->file_handle != INVALID_HANDLE_VALUE) - CloseHandle (m_obj->file_handle); + if (m_obj->data != NULL) + UnmapViewOfFile (m_obj->data); + if (m_obj->map_handle != NULL) + CloseHandle (m_obj->map_handle); + if (m_obj->file_handle != INVALID_HANDLE_VALUE) + CloseHandle (m_obj->file_handle); Py_END_ALLOW_THREADS - if (m_obj->tagname) - PyMem_Free(m_obj->tagname); -#endif /* MS_WINDOWS */ - -#ifdef UNIX + if (m_obj->tagname) + PyMem_Free(m_obj->tagname); +#endif /* MS_WINDOWS */ + +#ifdef UNIX Py_BEGIN_ALLOW_THREADS - if (m_obj->fd >= 0) - (void) close(m_obj->fd); - if (m_obj->data!=NULL) { - munmap(m_obj->data, m_obj->size); - } + if (m_obj->fd >= 0) + (void) close(m_obj->fd); + if (m_obj->data!=NULL) { + munmap(m_obj->data, m_obj->size); + } Py_END_ALLOW_THREADS -#endif /* UNIX */ - - if (m_obj->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) m_obj); - Py_TYPE(m_obj)->tp_free((PyObject*)m_obj); -} - -static PyObject * -mmap_close_method(mmap_object *self, PyObject *unused) -{ - if (self->exports > 0) { - PyErr_SetString(PyExc_BufferError, "cannot close "\ - "exported pointers exist"); - return NULL; - } -#ifdef MS_WINDOWS - /* For each resource we maintain, we need to check - the value is valid, and if so, free the resource - and set the member value to an invalid value so - the dealloc does not attempt to resource clearing - again. - TODO - should we check for errors in the close operations??? - */ +#endif /* UNIX */ + + if (m_obj->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) m_obj); + Py_TYPE(m_obj)->tp_free((PyObject*)m_obj); +} + +static PyObject * +mmap_close_method(mmap_object *self, PyObject *unused) +{ + if (self->exports > 0) { + PyErr_SetString(PyExc_BufferError, "cannot close "\ + "exported pointers exist"); + return NULL; + } +#ifdef MS_WINDOWS + /* For each resource we maintain, we need to check + the value is valid, and if so, free the resource + and set the member value to an invalid value so + the dealloc does not attempt to resource clearing + again. + TODO - should we check for errors in the close operations??? + */ HANDLE map_handle = self->map_handle; HANDLE file_handle = self->file_handle; char *data = self->data; @@ -170,537 +170,537 @@ mmap_close_method(mmap_object *self, PyObject *unused) Py_BEGIN_ALLOW_THREADS if (data != NULL) { UnmapViewOfFile(data); - } + } if (map_handle != NULL) { CloseHandle(map_handle); - } + } if (file_handle != INVALID_HANDLE_VALUE) { CloseHandle(file_handle); - } + } Py_END_ALLOW_THREADS -#endif /* MS_WINDOWS */ - -#ifdef UNIX +#endif /* MS_WINDOWS */ + +#ifdef UNIX int fd = self->fd; char *data = self->data; - self->fd = -1; + self->fd = -1; self->data = NULL; Py_BEGIN_ALLOW_THREADS if (0 <= fd) (void) close(fd); if (data != NULL) { munmap(data, self->size); - } + } Py_END_ALLOW_THREADS -#endif - - Py_RETURN_NONE; -} - -#ifdef MS_WINDOWS -#define CHECK_VALID(err) \ -do { \ - if (self->map_handle == NULL) { \ - PyErr_SetString(PyExc_ValueError, "mmap closed or invalid"); \ - return err; \ - } \ -} while (0) -#endif /* MS_WINDOWS */ - -#ifdef UNIX -#define CHECK_VALID(err) \ -do { \ - if (self->data == NULL) { \ - PyErr_SetString(PyExc_ValueError, "mmap closed or invalid"); \ - return err; \ - } \ -} while (0) -#endif /* UNIX */ - -static PyObject * -mmap_read_byte_method(mmap_object *self, - PyObject *unused) -{ - CHECK_VALID(NULL); - if (self->pos >= self->size) { - PyErr_SetString(PyExc_ValueError, "read byte out of range"); - return NULL; - } - return PyLong_FromLong((unsigned char)self->data[self->pos++]); -} - -static PyObject * -mmap_read_line_method(mmap_object *self, - PyObject *unused) -{ - Py_ssize_t remaining; - char *start, *eol; - PyObject *result; - - CHECK_VALID(NULL); - - remaining = (self->pos < self->size) ? self->size - self->pos : 0; - if (!remaining) - return PyBytes_FromString(""); - start = self->data + self->pos; - eol = memchr(start, '\n', remaining); - if (!eol) - eol = self->data + self->size; - else - ++eol; /* advance past newline */ - result = PyBytes_FromStringAndSize(start, (eol - start)); - self->pos += (eol - start); - return result; -} - -static PyObject * -mmap_read_method(mmap_object *self, - PyObject *args) -{ - Py_ssize_t num_bytes = PY_SSIZE_T_MAX, remaining; - PyObject *result; - - CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "|O&:read", _Py_convert_optional_to_ssize_t, &num_bytes)) - return(NULL); - - /* silently 'adjust' out-of-range requests */ - remaining = (self->pos < self->size) ? self->size - self->pos : 0; - if (num_bytes < 0 || num_bytes > remaining) - num_bytes = remaining; - result = PyBytes_FromStringAndSize(&self->data[self->pos], num_bytes); - self->pos += num_bytes; - return result; -} - -static PyObject * -mmap_gfind(mmap_object *self, - PyObject *args, - int reverse) -{ - Py_ssize_t start = self->pos; - Py_ssize_t end = self->size; - Py_buffer view; - - CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, reverse ? "y*|nn:rfind" : "y*|nn:find", - &view, &start, &end)) { - return NULL; - } else { - const char *p, *start_p, *end_p; - int sign = reverse ? -1 : 1; - const char *needle = view.buf; - Py_ssize_t len = view.len; - - if (start < 0) - start += self->size; - if (start < 0) - start = 0; - else if (start > self->size) - start = self->size; - - if (end < 0) - end += self->size; - if (end < 0) - end = 0; - else if (end > self->size) - end = self->size; - - start_p = self->data + start; - end_p = self->data + end; - - for (p = (reverse ? end_p - len : start_p); - (p >= start_p) && (p + len <= end_p); p += sign) { - Py_ssize_t i; - for (i = 0; i < len && needle[i] == p[i]; ++i) - /* nothing */; - if (i == len) { - PyBuffer_Release(&view); - return PyLong_FromSsize_t(p - self->data); - } - } - PyBuffer_Release(&view); - return PyLong_FromLong(-1); - } -} - -static PyObject * -mmap_find_method(mmap_object *self, - PyObject *args) -{ - return mmap_gfind(self, args, 0); -} - -static PyObject * -mmap_rfind_method(mmap_object *self, - PyObject *args) -{ - return mmap_gfind(self, args, 1); -} - -static int -is_writable(mmap_object *self) -{ - if (self->access != ACCESS_READ) - return 1; - PyErr_Format(PyExc_TypeError, "mmap can't modify a readonly memory map."); - return 0; -} - -static int -is_resizeable(mmap_object *self) -{ - if (self->exports > 0) { - PyErr_SetString(PyExc_BufferError, - "mmap can't resize with extant buffers exported."); - return 0; - } - if ((self->access == ACCESS_WRITE) || (self->access == ACCESS_DEFAULT)) - return 1; - PyErr_Format(PyExc_TypeError, - "mmap can't resize a readonly or copy-on-write memory map."); - return 0; -} - - -static PyObject * -mmap_write_method(mmap_object *self, - PyObject *args) -{ - Py_buffer data; - - CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "y*:write", &data)) - return(NULL); - - if (!is_writable(self)) { - PyBuffer_Release(&data); - return NULL; - } - - if (self->pos > self->size || self->size - self->pos < data.len) { - PyBuffer_Release(&data); - PyErr_SetString(PyExc_ValueError, "data out of range"); - return NULL; - } - - memcpy(&self->data[self->pos], data.buf, data.len); - self->pos += data.len; - PyBuffer_Release(&data); - return PyLong_FromSsize_t(data.len); -} - -static PyObject * -mmap_write_byte_method(mmap_object *self, - PyObject *args) -{ - char value; - - CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "b:write_byte", &value)) - return(NULL); - - if (!is_writable(self)) - return NULL; - - if (self->pos < self->size) { - self->data[self->pos++] = value; - Py_RETURN_NONE; - } - else { - PyErr_SetString(PyExc_ValueError, "write byte out of range"); - return NULL; - } -} - -static PyObject * -mmap_size_method(mmap_object *self, - PyObject *unused) -{ - CHECK_VALID(NULL); - -#ifdef MS_WINDOWS - if (self->file_handle != INVALID_HANDLE_VALUE) { - DWORD low,high; - long long size; - low = GetFileSize(self->file_handle, &high); - if (low == INVALID_FILE_SIZE) { - /* It might be that the function appears to have failed, - when indeed its size equals INVALID_FILE_SIZE */ - DWORD error = GetLastError(); - if (error != NO_ERROR) - return PyErr_SetFromWindowsErr(error); - } - if (!high && low < LONG_MAX) - return PyLong_FromLong((long)low); - size = (((long long)high)<<32) + low; - return PyLong_FromLongLong(size); - } else { - return PyLong_FromSsize_t(self->size); - } -#endif /* MS_WINDOWS */ - -#ifdef UNIX - { - struct _Py_stat_struct status; - if (_Py_fstat(self->fd, &status) == -1) - return NULL; -#ifdef HAVE_LARGEFILE_SUPPORT - return PyLong_FromLongLong(status.st_size); -#else - return PyLong_FromLong(status.st_size); -#endif - } -#endif /* UNIX */ -} - -/* This assumes that you want the entire file mapped, - / and when recreating the map will make the new file - / have the new size - / - / Is this really necessary? This could easily be done - / from python by just closing and re-opening with the - / new size? - */ - -static PyObject * -mmap_resize_method(mmap_object *self, - PyObject *args) -{ - Py_ssize_t new_size; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "n:resize", &new_size) || - !is_resizeable(self)) { - return NULL; - } - if (new_size < 0 || PY_SSIZE_T_MAX - new_size < self->offset) { - PyErr_SetString(PyExc_ValueError, "new size out of range"); - return NULL; - } - - { -#ifdef MS_WINDOWS - DWORD dwErrCode = 0; - DWORD off_hi, off_lo, newSizeLow, newSizeHigh; - /* First, unmap the file view */ - UnmapViewOfFile(self->data); - self->data = NULL; - /* Close the mapping object */ - CloseHandle(self->map_handle); - self->map_handle = NULL; - /* Move to the desired EOF position */ - newSizeHigh = (DWORD)((self->offset + new_size) >> 32); - newSizeLow = (DWORD)((self->offset + new_size) & 0xFFFFFFFF); - off_hi = (DWORD)(self->offset >> 32); - off_lo = (DWORD)(self->offset & 0xFFFFFFFF); - SetFilePointer(self->file_handle, - newSizeLow, &newSizeHigh, FILE_BEGIN); - /* Change the size of the file */ - SetEndOfFile(self->file_handle); - /* Create another mapping object and remap the file view */ - self->map_handle = CreateFileMapping( - self->file_handle, - NULL, - PAGE_READWRITE, - 0, - 0, - self->tagname); - if (self->map_handle != NULL) { - self->data = (char *) MapViewOfFile(self->map_handle, - FILE_MAP_WRITE, - off_hi, - off_lo, - new_size); - if (self->data != NULL) { - self->size = new_size; - Py_RETURN_NONE; - } else { - dwErrCode = GetLastError(); - CloseHandle(self->map_handle); - self->map_handle = NULL; - } - } else { - dwErrCode = GetLastError(); - } - PyErr_SetFromWindowsErr(dwErrCode); - return NULL; -#endif /* MS_WINDOWS */ - -#ifdef UNIX -#ifndef HAVE_MREMAP - PyErr_SetString(PyExc_SystemError, - "mmap: resizing not available--no mremap()"); - return NULL; -#else - void *newmap; - - if (self->fd != -1 && ftruncate(self->fd, self->offset + new_size) == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - -#ifdef MREMAP_MAYMOVE - newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE); -#else -#if defined(__NetBSD__) - newmap = mremap(self->data, self->size, self->data, new_size, 0); -#else - newmap = mremap(self->data, self->size, new_size, 0); -#endif /* __NetBSD__ */ -#endif - if (newmap == (void *)-1) - { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - self->data = newmap; - self->size = new_size; - Py_RETURN_NONE; -#endif /* HAVE_MREMAP */ -#endif /* UNIX */ - } -} - -static PyObject * -mmap_tell_method(mmap_object *self, PyObject *unused) -{ - CHECK_VALID(NULL); - return PyLong_FromSize_t(self->pos); -} - -static PyObject * -mmap_flush_method(mmap_object *self, PyObject *args) -{ - Py_ssize_t offset = 0; - Py_ssize_t size = self->size; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size)) - return NULL; - if (size < 0 || offset < 0 || self->size - offset < size) { - PyErr_SetString(PyExc_ValueError, "flush values out of range"); - return NULL; - } - - if (self->access == ACCESS_READ || self->access == ACCESS_COPY) +#endif + + Py_RETURN_NONE; +} + +#ifdef MS_WINDOWS +#define CHECK_VALID(err) \ +do { \ + if (self->map_handle == NULL) { \ + PyErr_SetString(PyExc_ValueError, "mmap closed or invalid"); \ + return err; \ + } \ +} while (0) +#endif /* MS_WINDOWS */ + +#ifdef UNIX +#define CHECK_VALID(err) \ +do { \ + if (self->data == NULL) { \ + PyErr_SetString(PyExc_ValueError, "mmap closed or invalid"); \ + return err; \ + } \ +} while (0) +#endif /* UNIX */ + +static PyObject * +mmap_read_byte_method(mmap_object *self, + PyObject *unused) +{ + CHECK_VALID(NULL); + if (self->pos >= self->size) { + PyErr_SetString(PyExc_ValueError, "read byte out of range"); + return NULL; + } + return PyLong_FromLong((unsigned char)self->data[self->pos++]); +} + +static PyObject * +mmap_read_line_method(mmap_object *self, + PyObject *unused) +{ + Py_ssize_t remaining; + char *start, *eol; + PyObject *result; + + CHECK_VALID(NULL); + + remaining = (self->pos < self->size) ? self->size - self->pos : 0; + if (!remaining) + return PyBytes_FromString(""); + start = self->data + self->pos; + eol = memchr(start, '\n', remaining); + if (!eol) + eol = self->data + self->size; + else + ++eol; /* advance past newline */ + result = PyBytes_FromStringAndSize(start, (eol - start)); + self->pos += (eol - start); + return result; +} + +static PyObject * +mmap_read_method(mmap_object *self, + PyObject *args) +{ + Py_ssize_t num_bytes = PY_SSIZE_T_MAX, remaining; + PyObject *result; + + CHECK_VALID(NULL); + if (!PyArg_ParseTuple(args, "|O&:read", _Py_convert_optional_to_ssize_t, &num_bytes)) + return(NULL); + + /* silently 'adjust' out-of-range requests */ + remaining = (self->pos < self->size) ? self->size - self->pos : 0; + if (num_bytes < 0 || num_bytes > remaining) + num_bytes = remaining; + result = PyBytes_FromStringAndSize(&self->data[self->pos], num_bytes); + self->pos += num_bytes; + return result; +} + +static PyObject * +mmap_gfind(mmap_object *self, + PyObject *args, + int reverse) +{ + Py_ssize_t start = self->pos; + Py_ssize_t end = self->size; + Py_buffer view; + + CHECK_VALID(NULL); + if (!PyArg_ParseTuple(args, reverse ? "y*|nn:rfind" : "y*|nn:find", + &view, &start, &end)) { + return NULL; + } else { + const char *p, *start_p, *end_p; + int sign = reverse ? -1 : 1; + const char *needle = view.buf; + Py_ssize_t len = view.len; + + if (start < 0) + start += self->size; + if (start < 0) + start = 0; + else if (start > self->size) + start = self->size; + + if (end < 0) + end += self->size; + if (end < 0) + end = 0; + else if (end > self->size) + end = self->size; + + start_p = self->data + start; + end_p = self->data + end; + + for (p = (reverse ? end_p - len : start_p); + (p >= start_p) && (p + len <= end_p); p += sign) { + Py_ssize_t i; + for (i = 0; i < len && needle[i] == p[i]; ++i) + /* nothing */; + if (i == len) { + PyBuffer_Release(&view); + return PyLong_FromSsize_t(p - self->data); + } + } + PyBuffer_Release(&view); + return PyLong_FromLong(-1); + } +} + +static PyObject * +mmap_find_method(mmap_object *self, + PyObject *args) +{ + return mmap_gfind(self, args, 0); +} + +static PyObject * +mmap_rfind_method(mmap_object *self, + PyObject *args) +{ + return mmap_gfind(self, args, 1); +} + +static int +is_writable(mmap_object *self) +{ + if (self->access != ACCESS_READ) + return 1; + PyErr_Format(PyExc_TypeError, "mmap can't modify a readonly memory map."); + return 0; +} + +static int +is_resizeable(mmap_object *self) +{ + if (self->exports > 0) { + PyErr_SetString(PyExc_BufferError, + "mmap can't resize with extant buffers exported."); + return 0; + } + if ((self->access == ACCESS_WRITE) || (self->access == ACCESS_DEFAULT)) + return 1; + PyErr_Format(PyExc_TypeError, + "mmap can't resize a readonly or copy-on-write memory map."); + return 0; +} + + +static PyObject * +mmap_write_method(mmap_object *self, + PyObject *args) +{ + Py_buffer data; + + CHECK_VALID(NULL); + if (!PyArg_ParseTuple(args, "y*:write", &data)) + return(NULL); + + if (!is_writable(self)) { + PyBuffer_Release(&data); + return NULL; + } + + if (self->pos > self->size || self->size - self->pos < data.len) { + PyBuffer_Release(&data); + PyErr_SetString(PyExc_ValueError, "data out of range"); + return NULL; + } + + memcpy(&self->data[self->pos], data.buf, data.len); + self->pos += data.len; + PyBuffer_Release(&data); + return PyLong_FromSsize_t(data.len); +} + +static PyObject * +mmap_write_byte_method(mmap_object *self, + PyObject *args) +{ + char value; + + CHECK_VALID(NULL); + if (!PyArg_ParseTuple(args, "b:write_byte", &value)) + return(NULL); + + if (!is_writable(self)) + return NULL; + + if (self->pos < self->size) { + self->data[self->pos++] = value; + Py_RETURN_NONE; + } + else { + PyErr_SetString(PyExc_ValueError, "write byte out of range"); + return NULL; + } +} + +static PyObject * +mmap_size_method(mmap_object *self, + PyObject *unused) +{ + CHECK_VALID(NULL); + +#ifdef MS_WINDOWS + if (self->file_handle != INVALID_HANDLE_VALUE) { + DWORD low,high; + long long size; + low = GetFileSize(self->file_handle, &high); + if (low == INVALID_FILE_SIZE) { + /* It might be that the function appears to have failed, + when indeed its size equals INVALID_FILE_SIZE */ + DWORD error = GetLastError(); + if (error != NO_ERROR) + return PyErr_SetFromWindowsErr(error); + } + if (!high && low < LONG_MAX) + return PyLong_FromLong((long)low); + size = (((long long)high)<<32) + low; + return PyLong_FromLongLong(size); + } else { + return PyLong_FromSsize_t(self->size); + } +#endif /* MS_WINDOWS */ + +#ifdef UNIX + { + struct _Py_stat_struct status; + if (_Py_fstat(self->fd, &status) == -1) + return NULL; +#ifdef HAVE_LARGEFILE_SUPPORT + return PyLong_FromLongLong(status.st_size); +#else + return PyLong_FromLong(status.st_size); +#endif + } +#endif /* UNIX */ +} + +/* This assumes that you want the entire file mapped, + / and when recreating the map will make the new file + / have the new size + / + / Is this really necessary? This could easily be done + / from python by just closing and re-opening with the + / new size? + */ + +static PyObject * +mmap_resize_method(mmap_object *self, + PyObject *args) +{ + Py_ssize_t new_size; + CHECK_VALID(NULL); + if (!PyArg_ParseTuple(args, "n:resize", &new_size) || + !is_resizeable(self)) { + return NULL; + } + if (new_size < 0 || PY_SSIZE_T_MAX - new_size < self->offset) { + PyErr_SetString(PyExc_ValueError, "new size out of range"); + return NULL; + } + + { +#ifdef MS_WINDOWS + DWORD dwErrCode = 0; + DWORD off_hi, off_lo, newSizeLow, newSizeHigh; + /* First, unmap the file view */ + UnmapViewOfFile(self->data); + self->data = NULL; + /* Close the mapping object */ + CloseHandle(self->map_handle); + self->map_handle = NULL; + /* Move to the desired EOF position */ + newSizeHigh = (DWORD)((self->offset + new_size) >> 32); + newSizeLow = (DWORD)((self->offset + new_size) & 0xFFFFFFFF); + off_hi = (DWORD)(self->offset >> 32); + off_lo = (DWORD)(self->offset & 0xFFFFFFFF); + SetFilePointer(self->file_handle, + newSizeLow, &newSizeHigh, FILE_BEGIN); + /* Change the size of the file */ + SetEndOfFile(self->file_handle); + /* Create another mapping object and remap the file view */ + self->map_handle = CreateFileMapping( + self->file_handle, + NULL, + PAGE_READWRITE, + 0, + 0, + self->tagname); + if (self->map_handle != NULL) { + self->data = (char *) MapViewOfFile(self->map_handle, + FILE_MAP_WRITE, + off_hi, + off_lo, + new_size); + if (self->data != NULL) { + self->size = new_size; + Py_RETURN_NONE; + } else { + dwErrCode = GetLastError(); + CloseHandle(self->map_handle); + self->map_handle = NULL; + } + } else { + dwErrCode = GetLastError(); + } + PyErr_SetFromWindowsErr(dwErrCode); + return NULL; +#endif /* MS_WINDOWS */ + +#ifdef UNIX +#ifndef HAVE_MREMAP + PyErr_SetString(PyExc_SystemError, + "mmap: resizing not available--no mremap()"); + return NULL; +#else + void *newmap; + + if (self->fd != -1 && ftruncate(self->fd, self->offset + new_size) == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + +#ifdef MREMAP_MAYMOVE + newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE); +#else +#if defined(__NetBSD__) + newmap = mremap(self->data, self->size, self->data, new_size, 0); +#else + newmap = mremap(self->data, self->size, new_size, 0); +#endif /* __NetBSD__ */ +#endif + if (newmap == (void *)-1) + { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + self->data = newmap; + self->size = new_size; + Py_RETURN_NONE; +#endif /* HAVE_MREMAP */ +#endif /* UNIX */ + } +} + +static PyObject * +mmap_tell_method(mmap_object *self, PyObject *unused) +{ + CHECK_VALID(NULL); + return PyLong_FromSize_t(self->pos); +} + +static PyObject * +mmap_flush_method(mmap_object *self, PyObject *args) +{ + Py_ssize_t offset = 0; + Py_ssize_t size = self->size; + CHECK_VALID(NULL); + if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size)) + return NULL; + if (size < 0 || offset < 0 || self->size - offset < size) { + PyErr_SetString(PyExc_ValueError, "flush values out of range"); + return NULL; + } + + if (self->access == ACCESS_READ || self->access == ACCESS_COPY) Py_RETURN_NONE; - -#ifdef MS_WINDOWS + +#ifdef MS_WINDOWS if (!FlushViewOfFile(self->data+offset, size)) { PyErr_SetFromWindowsErr(GetLastError()); return NULL; } Py_RETURN_NONE; -#elif defined(UNIX) - /* XXX flags for msync? */ - if (-1 == msync(self->data + offset, size, MS_SYNC)) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } +#elif defined(UNIX) + /* XXX flags for msync? */ + if (-1 == msync(self->data + offset, size, MS_SYNC)) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } Py_RETURN_NONE; -#else - PyErr_SetString(PyExc_ValueError, "flush not supported on this system"); - return NULL; -#endif -} - -static PyObject * -mmap_seek_method(mmap_object *self, PyObject *args) -{ - Py_ssize_t dist; - int how=0; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "n|i:seek", &dist, &how)) - return NULL; - else { - Py_ssize_t where; - switch (how) { - case 0: /* relative to start */ - where = dist; - break; - case 1: /* relative to current position */ - if (PY_SSIZE_T_MAX - self->pos < dist) - goto onoutofrange; - where = self->pos + dist; - break; - case 2: /* relative to end */ - if (PY_SSIZE_T_MAX - self->size < dist) - goto onoutofrange; - where = self->size + dist; - break; - default: - PyErr_SetString(PyExc_ValueError, "unknown seek type"); - return NULL; - } - if (where > self->size || where < 0) - goto onoutofrange; - self->pos = where; - Py_RETURN_NONE; - } - - onoutofrange: - PyErr_SetString(PyExc_ValueError, "seek out of range"); - return NULL; -} - -static PyObject * -mmap_move_method(mmap_object *self, PyObject *args) -{ - Py_ssize_t dest, src, cnt; - CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "nnn:move", &dest, &src, &cnt) || - !is_writable(self)) { - return NULL; - } else { - /* bounds check the values */ - if (dest < 0 || src < 0 || cnt < 0) - goto bounds; - if (self->size - dest < cnt || self->size - src < cnt) - goto bounds; - - memmove(&self->data[dest], &self->data[src], cnt); - - Py_RETURN_NONE; - - bounds: - PyErr_SetString(PyExc_ValueError, - "source, destination, or count out of range"); - return NULL; - } -} - -static PyObject * -mmap_closed_get(mmap_object *self, void *Py_UNUSED(ignored)) -{ -#ifdef MS_WINDOWS - return PyBool_FromLong(self->map_handle == NULL ? 1 : 0); -#elif defined(UNIX) - return PyBool_FromLong(self->data == NULL ? 1 : 0); -#endif -} - -static PyObject * -mmap__enter__method(mmap_object *self, PyObject *args) -{ - CHECK_VALID(NULL); - - Py_INCREF(self); - return (PyObject *)self; -} - -static PyObject * -mmap__exit__method(PyObject *self, PyObject *args) -{ - _Py_IDENTIFIER(close); - +#else + PyErr_SetString(PyExc_ValueError, "flush not supported on this system"); + return NULL; +#endif +} + +static PyObject * +mmap_seek_method(mmap_object *self, PyObject *args) +{ + Py_ssize_t dist; + int how=0; + CHECK_VALID(NULL); + if (!PyArg_ParseTuple(args, "n|i:seek", &dist, &how)) + return NULL; + else { + Py_ssize_t where; + switch (how) { + case 0: /* relative to start */ + where = dist; + break; + case 1: /* relative to current position */ + if (PY_SSIZE_T_MAX - self->pos < dist) + goto onoutofrange; + where = self->pos + dist; + break; + case 2: /* relative to end */ + if (PY_SSIZE_T_MAX - self->size < dist) + goto onoutofrange; + where = self->size + dist; + break; + default: + PyErr_SetString(PyExc_ValueError, "unknown seek type"); + return NULL; + } + if (where > self->size || where < 0) + goto onoutofrange; + self->pos = where; + Py_RETURN_NONE; + } + + onoutofrange: + PyErr_SetString(PyExc_ValueError, "seek out of range"); + return NULL; +} + +static PyObject * +mmap_move_method(mmap_object *self, PyObject *args) +{ + Py_ssize_t dest, src, cnt; + CHECK_VALID(NULL); + if (!PyArg_ParseTuple(args, "nnn:move", &dest, &src, &cnt) || + !is_writable(self)) { + return NULL; + } else { + /* bounds check the values */ + if (dest < 0 || src < 0 || cnt < 0) + goto bounds; + if (self->size - dest < cnt || self->size - src < cnt) + goto bounds; + + memmove(&self->data[dest], &self->data[src], cnt); + + Py_RETURN_NONE; + + bounds: + PyErr_SetString(PyExc_ValueError, + "source, destination, or count out of range"); + return NULL; + } +} + +static PyObject * +mmap_closed_get(mmap_object *self, void *Py_UNUSED(ignored)) +{ +#ifdef MS_WINDOWS + return PyBool_FromLong(self->map_handle == NULL ? 1 : 0); +#elif defined(UNIX) + return PyBool_FromLong(self->data == NULL ? 1 : 0); +#endif +} + +static PyObject * +mmap__enter__method(mmap_object *self, PyObject *args) +{ + CHECK_VALID(NULL); + + Py_INCREF(self); + return (PyObject *)self; +} + +static PyObject * +mmap__exit__method(PyObject *self, PyObject *args) +{ + _Py_IDENTIFIER(close); + return _PyObject_CallMethodIdNoArgs(self, &PyId_close); -} - +} + static PyObject * mmap__repr__method(PyObject *self) { mmap_object *mobj = (mmap_object *)self; -#ifdef MS_WINDOWS +#ifdef MS_WINDOWS #define _Py_FORMAT_OFFSET "lld" if (mobj->map_handle == NULL) #elif defined(UNIX) @@ -741,18 +741,18 @@ mmap__repr__method(PyObject *self) } #ifdef MS_WINDOWS -static PyObject * -mmap__sizeof__method(mmap_object *self, void *unused) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); - if (self->tagname) - res += strlen(self->tagname) + 1; - return PyLong_FromSsize_t(res); -} -#endif - +static PyObject * +mmap__sizeof__method(mmap_object *self, void *unused) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(self)); + if (self->tagname) + res += strlen(self->tagname) + 1; + return PyLong_FromSsize_t(res); +} +#endif + #ifdef HAVE_MADVISE static PyObject * mmap_madvise_method(mmap_object *self, PyObject *args) @@ -793,309 +793,309 @@ mmap_madvise_method(mmap_object *self, PyObject *args) } #endif // HAVE_MADVISE -static struct PyMethodDef mmap_object_methods[] = { - {"close", (PyCFunction) mmap_close_method, METH_NOARGS}, - {"find", (PyCFunction) mmap_find_method, METH_VARARGS}, - {"rfind", (PyCFunction) mmap_rfind_method, METH_VARARGS}, - {"flush", (PyCFunction) mmap_flush_method, METH_VARARGS}, +static struct PyMethodDef mmap_object_methods[] = { + {"close", (PyCFunction) mmap_close_method, METH_NOARGS}, + {"find", (PyCFunction) mmap_find_method, METH_VARARGS}, + {"rfind", (PyCFunction) mmap_rfind_method, METH_VARARGS}, + {"flush", (PyCFunction) mmap_flush_method, METH_VARARGS}, #ifdef HAVE_MADVISE {"madvise", (PyCFunction) mmap_madvise_method, METH_VARARGS}, #endif - {"move", (PyCFunction) mmap_move_method, METH_VARARGS}, - {"read", (PyCFunction) mmap_read_method, METH_VARARGS}, - {"read_byte", (PyCFunction) mmap_read_byte_method, METH_NOARGS}, - {"readline", (PyCFunction) mmap_read_line_method, METH_NOARGS}, - {"resize", (PyCFunction) mmap_resize_method, METH_VARARGS}, - {"seek", (PyCFunction) mmap_seek_method, METH_VARARGS}, - {"size", (PyCFunction) mmap_size_method, METH_NOARGS}, - {"tell", (PyCFunction) mmap_tell_method, METH_NOARGS}, - {"write", (PyCFunction) mmap_write_method, METH_VARARGS}, - {"write_byte", (PyCFunction) mmap_write_byte_method, METH_VARARGS}, - {"__enter__", (PyCFunction) mmap__enter__method, METH_NOARGS}, - {"__exit__", (PyCFunction) mmap__exit__method, METH_VARARGS}, -#ifdef MS_WINDOWS - {"__sizeof__", (PyCFunction) mmap__sizeof__method, METH_NOARGS}, -#endif - {NULL, NULL} /* sentinel */ -}; - -static PyGetSetDef mmap_object_getset[] = { - {"closed", (getter) mmap_closed_get, NULL, NULL}, - {NULL} -}; - - -/* Functions for treating an mmap'ed file as a buffer */ - -static int -mmap_buffer_getbuf(mmap_object *self, Py_buffer *view, int flags) -{ - CHECK_VALID(-1); - if (PyBuffer_FillInfo(view, (PyObject*)self, self->data, self->size, - (self->access == ACCESS_READ), flags) < 0) - return -1; - self->exports++; - return 0; -} - -static void -mmap_buffer_releasebuf(mmap_object *self, Py_buffer *view) -{ - self->exports--; -} - -static Py_ssize_t -mmap_length(mmap_object *self) -{ - CHECK_VALID(-1); - return self->size; -} - -static PyObject * -mmap_item(mmap_object *self, Py_ssize_t i) -{ - CHECK_VALID(NULL); - if (i < 0 || i >= self->size) { - PyErr_SetString(PyExc_IndexError, "mmap index out of range"); - return NULL; - } - return PyBytes_FromStringAndSize(self->data + i, 1); -} - -static PyObject * -mmap_subscript(mmap_object *self, PyObject *item) -{ - CHECK_VALID(NULL); - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return NULL; - if (i < 0) - i += self->size; - if (i < 0 || i >= self->size) { - PyErr_SetString(PyExc_IndexError, - "mmap index out of range"); - return NULL; - } - return PyLong_FromLong(Py_CHARMASK(self->data[i])); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelen; - - if (PySlice_Unpack(item, &start, &stop, &step) < 0) { - return NULL; - } - slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); - - if (slicelen <= 0) - return PyBytes_FromStringAndSize("", 0); - else if (step == 1) - return PyBytes_FromStringAndSize(self->data + start, - slicelen); - else { - char *result_buf = (char *)PyMem_Malloc(slicelen); + {"move", (PyCFunction) mmap_move_method, METH_VARARGS}, + {"read", (PyCFunction) mmap_read_method, METH_VARARGS}, + {"read_byte", (PyCFunction) mmap_read_byte_method, METH_NOARGS}, + {"readline", (PyCFunction) mmap_read_line_method, METH_NOARGS}, + {"resize", (PyCFunction) mmap_resize_method, METH_VARARGS}, + {"seek", (PyCFunction) mmap_seek_method, METH_VARARGS}, + {"size", (PyCFunction) mmap_size_method, METH_NOARGS}, + {"tell", (PyCFunction) mmap_tell_method, METH_NOARGS}, + {"write", (PyCFunction) mmap_write_method, METH_VARARGS}, + {"write_byte", (PyCFunction) mmap_write_byte_method, METH_VARARGS}, + {"__enter__", (PyCFunction) mmap__enter__method, METH_NOARGS}, + {"__exit__", (PyCFunction) mmap__exit__method, METH_VARARGS}, +#ifdef MS_WINDOWS + {"__sizeof__", (PyCFunction) mmap__sizeof__method, METH_NOARGS}, +#endif + {NULL, NULL} /* sentinel */ +}; + +static PyGetSetDef mmap_object_getset[] = { + {"closed", (getter) mmap_closed_get, NULL, NULL}, + {NULL} +}; + + +/* Functions for treating an mmap'ed file as a buffer */ + +static int +mmap_buffer_getbuf(mmap_object *self, Py_buffer *view, int flags) +{ + CHECK_VALID(-1); + if (PyBuffer_FillInfo(view, (PyObject*)self, self->data, self->size, + (self->access == ACCESS_READ), flags) < 0) + return -1; + self->exports++; + return 0; +} + +static void +mmap_buffer_releasebuf(mmap_object *self, Py_buffer *view) +{ + self->exports--; +} + +static Py_ssize_t +mmap_length(mmap_object *self) +{ + CHECK_VALID(-1); + return self->size; +} + +static PyObject * +mmap_item(mmap_object *self, Py_ssize_t i) +{ + CHECK_VALID(NULL); + if (i < 0 || i >= self->size) { + PyErr_SetString(PyExc_IndexError, "mmap index out of range"); + return NULL; + } + return PyBytes_FromStringAndSize(self->data + i, 1); +} + +static PyObject * +mmap_subscript(mmap_object *self, PyObject *item) +{ + CHECK_VALID(NULL); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) + i += self->size; + if (i < 0 || i >= self->size) { + PyErr_SetString(PyExc_IndexError, + "mmap index out of range"); + return NULL; + } + return PyLong_FromLong(Py_CHARMASK(self->data[i])); + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return NULL; + } + slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); + + if (slicelen <= 0) + return PyBytes_FromStringAndSize("", 0); + else if (step == 1) + return PyBytes_FromStringAndSize(self->data + start, + slicelen); + else { + char *result_buf = (char *)PyMem_Malloc(slicelen); size_t cur; Py_ssize_t i; - PyObject *result; - - if (result_buf == NULL) - return PyErr_NoMemory(); - for (cur = start, i = 0; i < slicelen; - cur += step, i++) { - result_buf[i] = self->data[cur]; - } - result = PyBytes_FromStringAndSize(result_buf, - slicelen); - PyMem_Free(result_buf); - return result; - } - } - else { - PyErr_SetString(PyExc_TypeError, - "mmap indices must be integers"); - return NULL; - } -} - -static int -mmap_ass_item(mmap_object *self, Py_ssize_t i, PyObject *v) -{ - const char *buf; - - CHECK_VALID(-1); - if (i < 0 || i >= self->size) { - PyErr_SetString(PyExc_IndexError, "mmap index out of range"); - return -1; - } - if (v == NULL) { - PyErr_SetString(PyExc_TypeError, - "mmap object doesn't support item deletion"); - return -1; - } - if (! (PyBytes_Check(v) && PyBytes_Size(v)==1) ) { - PyErr_SetString(PyExc_IndexError, - "mmap assignment must be length-1 bytes()"); - return -1; - } - if (!is_writable(self)) - return -1; - buf = PyBytes_AsString(v); - self->data[i] = buf[0]; - return 0; -} - -static int -mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) -{ - CHECK_VALID(-1); - - if (!is_writable(self)) - return -1; - - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - Py_ssize_t v; - - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += self->size; - if (i < 0 || i >= self->size) { - PyErr_SetString(PyExc_IndexError, - "mmap index out of range"); - return -1; - } - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "mmap doesn't support item deletion"); - return -1; - } - if (!PyIndex_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "mmap item value must be an int"); - return -1; - } - v = PyNumber_AsSsize_t(value, PyExc_TypeError); - if (v == -1 && PyErr_Occurred()) - return -1; - if (v < 0 || v > 255) { - PyErr_SetString(PyExc_ValueError, - "mmap item value must be " - "in range(0, 256)"); - return -1; - } - self->data[i] = (char) v; - return 0; - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelen; - Py_buffer vbuf; - - if (PySlice_Unpack(item, &start, &stop, &step) < 0) { - return -1; - } - slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "mmap object doesn't support slice deletion"); - return -1; - } - if (PyObject_GetBuffer(value, &vbuf, PyBUF_SIMPLE) < 0) - return -1; - if (vbuf.len != slicelen) { - PyErr_SetString(PyExc_IndexError, - "mmap slice assignment is wrong size"); - PyBuffer_Release(&vbuf); - return -1; - } - - if (slicelen == 0) { - } - else if (step == 1) { - memcpy(self->data + start, vbuf.buf, slicelen); - } - else { + PyObject *result; + + if (result_buf == NULL) + return PyErr_NoMemory(); + for (cur = start, i = 0; i < slicelen; + cur += step, i++) { + result_buf[i] = self->data[cur]; + } + result = PyBytes_FromStringAndSize(result_buf, + slicelen); + PyMem_Free(result_buf); + return result; + } + } + else { + PyErr_SetString(PyExc_TypeError, + "mmap indices must be integers"); + return NULL; + } +} + +static int +mmap_ass_item(mmap_object *self, Py_ssize_t i, PyObject *v) +{ + const char *buf; + + CHECK_VALID(-1); + if (i < 0 || i >= self->size) { + PyErr_SetString(PyExc_IndexError, "mmap index out of range"); + return -1; + } + if (v == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap object doesn't support item deletion"); + return -1; + } + if (! (PyBytes_Check(v) && PyBytes_Size(v)==1) ) { + PyErr_SetString(PyExc_IndexError, + "mmap assignment must be length-1 bytes()"); + return -1; + } + if (!is_writable(self)) + return -1; + buf = PyBytes_AsString(v); + self->data[i] = buf[0]; + return 0; +} + +static int +mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) +{ + CHECK_VALID(-1); + + if (!is_writable(self)) + return -1; + + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + Py_ssize_t v; + + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) + i += self->size; + if (i < 0 || i >= self->size) { + PyErr_SetString(PyExc_IndexError, + "mmap index out of range"); + return -1; + } + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap doesn't support item deletion"); + return -1; + } + if (!PyIndex_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "mmap item value must be an int"); + return -1; + } + v = PyNumber_AsSsize_t(value, PyExc_TypeError); + if (v == -1 && PyErr_Occurred()) + return -1; + if (v < 0 || v > 255) { + PyErr_SetString(PyExc_ValueError, + "mmap item value must be " + "in range(0, 256)"); + return -1; + } + self->data[i] = (char) v; + return 0; + } + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelen; + Py_buffer vbuf; + + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { + return -1; + } + slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "mmap object doesn't support slice deletion"); + return -1; + } + if (PyObject_GetBuffer(value, &vbuf, PyBUF_SIMPLE) < 0) + return -1; + if (vbuf.len != slicelen) { + PyErr_SetString(PyExc_IndexError, + "mmap slice assignment is wrong size"); + PyBuffer_Release(&vbuf); + return -1; + } + + if (slicelen == 0) { + } + else if (step == 1) { + memcpy(self->data + start, vbuf.buf, slicelen); + } + else { size_t cur; Py_ssize_t i; - - for (cur = start, i = 0; - i < slicelen; - cur += step, i++) - { - self->data[cur] = ((char *)vbuf.buf)[i]; - } - } - PyBuffer_Release(&vbuf); - return 0; - } - else { - PyErr_SetString(PyExc_TypeError, - "mmap indices must be integer"); - return -1; - } -} - -static PySequenceMethods mmap_as_sequence = { - (lenfunc)mmap_length, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - (ssizeargfunc)mmap_item, /*sq_item*/ - 0, /*sq_slice*/ - (ssizeobjargproc)mmap_ass_item, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ -}; - -static PyMappingMethods mmap_as_mapping = { - (lenfunc)mmap_length, - (binaryfunc)mmap_subscript, - (objobjargproc)mmap_ass_subscript, -}; - -static PyBufferProcs mmap_as_buffer = { - (getbufferproc)mmap_buffer_getbuf, - (releasebufferproc)mmap_buffer_releasebuf, -}; - -static PyObject * -new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict); - -PyDoc_STRVAR(mmap_doc, -"Windows: mmap(fileno, length[, tagname[, access[, offset]]])\n\ -\n\ -Maps length bytes from the file specified by the file handle fileno,\n\ -and returns a mmap object. If length is larger than the current size\n\ -of the file, the file is extended to contain length bytes. If length\n\ -is 0, the maximum length of the map is the current size of the file,\n\ -except that if the file is empty Windows raises an exception (you cannot\n\ -create an empty mapping on Windows).\n\ -\n\ -Unix: mmap(fileno, length[, flags[, prot[, access[, offset]]]])\n\ -\n\ -Maps length bytes from the file specified by the file descriptor fileno,\n\ -and returns a mmap object. If length is 0, the maximum length of the map\n\ -will be the current size of the file when mmap is called.\n\ -flags specifies the nature of the mapping. MAP_PRIVATE creates a\n\ -private copy-on-write mapping, so changes to the contents of the mmap\n\ -object will be private to this process, and MAP_SHARED creates a mapping\n\ -that's shared with all other processes mapping the same areas of the file.\n\ -The default value is MAP_SHARED.\n\ -\n\ -To map anonymous memory, pass -1 as the fileno (both versions)."); - - -static PyTypeObject mmap_object_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "mmap.mmap", /* tp_name */ - sizeof(mmap_object), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ + + for (cur = start, i = 0; + i < slicelen; + cur += step, i++) + { + self->data[cur] = ((char *)vbuf.buf)[i]; + } + } + PyBuffer_Release(&vbuf); + return 0; + } + else { + PyErr_SetString(PyExc_TypeError, + "mmap indices must be integer"); + return -1; + } +} + +static PySequenceMethods mmap_as_sequence = { + (lenfunc)mmap_length, /*sq_length*/ + 0, /*sq_concat*/ + 0, /*sq_repeat*/ + (ssizeargfunc)mmap_item, /*sq_item*/ + 0, /*sq_slice*/ + (ssizeobjargproc)mmap_ass_item, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ +}; + +static PyMappingMethods mmap_as_mapping = { + (lenfunc)mmap_length, + (binaryfunc)mmap_subscript, + (objobjargproc)mmap_ass_subscript, +}; + +static PyBufferProcs mmap_as_buffer = { + (getbufferproc)mmap_buffer_getbuf, + (releasebufferproc)mmap_buffer_releasebuf, +}; + +static PyObject * +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict); + +PyDoc_STRVAR(mmap_doc, +"Windows: mmap(fileno, length[, tagname[, access[, offset]]])\n\ +\n\ +Maps length bytes from the file specified by the file handle fileno,\n\ +and returns a mmap object. If length is larger than the current size\n\ +of the file, the file is extended to contain length bytes. If length\n\ +is 0, the maximum length of the map is the current size of the file,\n\ +except that if the file is empty Windows raises an exception (you cannot\n\ +create an empty mapping on Windows).\n\ +\n\ +Unix: mmap(fileno, length[, flags[, prot[, access[, offset]]]])\n\ +\n\ +Maps length bytes from the file specified by the file descriptor fileno,\n\ +and returns a mmap object. If length is 0, the maximum length of the map\n\ +will be the current size of the file when mmap is called.\n\ +flags specifies the nature of the mapping. MAP_PRIVATE creates a\n\ +private copy-on-write mapping, so changes to the contents of the mmap\n\ +object will be private to this process, and MAP_SHARED creates a mapping\n\ +that's shared with all other processes mapping the same areas of the file.\n\ +The default value is MAP_SHARED.\n\ +\n\ +To map anonymous memory, pass -1 as the fileno (both versions)."); + + +static PyTypeObject mmap_object_type = { + PyVarObject_HEAD_INIT(NULL, 0) + "mmap.mmap", /* tp_name */ + sizeof(mmap_object), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ (destructor)mmap_object_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ (reprfunc)mmap__repr__method, /* tp_repr */ - 0, /* tp_as_number */ + 0, /* tp_as_number */ &mmap_as_sequence, /* tp_as_sequence */ &mmap_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ @@ -1106,157 +1106,157 @@ static PyTypeObject mmap_object_type = { &mmap_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ mmap_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(mmap_object, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - mmap_object_methods, /* tp_methods */ - 0, /* tp_members */ - mmap_object_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - new_mmap_object, /* tp_new */ - PyObject_Del, /* tp_free */ -}; - - -#ifdef UNIX -#ifdef HAVE_LARGEFILE_SUPPORT -#define _Py_PARSE_OFF_T "L" -#else -#define _Py_PARSE_OFF_T "l" -#endif - -static PyObject * -new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) -{ - struct _Py_stat_struct status; - int fstat_result = -1; - mmap_object *m_obj; - Py_ssize_t map_size; - off_t offset = 0; - int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ; - int devzero = -1; - int access = (int)ACCESS_DEFAULT; - static char *keywords[] = {"fileno", "length", - "flags", "prot", - "access", "offset", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|iii" _Py_PARSE_OFF_T, keywords, - &fd, &map_size, &flags, &prot, - &access, &offset)) - return NULL; - if (map_size < 0) { - PyErr_SetString(PyExc_OverflowError, - "memory mapped length must be positive"); - return NULL; - } - if (offset < 0) { - PyErr_SetString(PyExc_OverflowError, - "memory mapped offset must be positive"); - return NULL; - } - - if ((access != (int)ACCESS_DEFAULT) && - ((flags != MAP_SHARED) || (prot != (PROT_WRITE | PROT_READ)))) - return PyErr_Format(PyExc_ValueError, - "mmap can't specify both access and flags, prot."); - switch ((access_mode)access) { - case ACCESS_READ: - flags = MAP_SHARED; - prot = PROT_READ; - break; - case ACCESS_WRITE: - flags = MAP_SHARED; - prot = PROT_READ | PROT_WRITE; - break; - case ACCESS_COPY: - flags = MAP_PRIVATE; - prot = PROT_READ | PROT_WRITE; - break; - case ACCESS_DEFAULT: - /* map prot to access type */ - if ((prot & PROT_READ) && (prot & PROT_WRITE)) { - /* ACCESS_DEFAULT */ - } - else if (prot & PROT_WRITE) { - access = ACCESS_WRITE; - } - else { - access = ACCESS_READ; - } - break; - default: - return PyErr_Format(PyExc_ValueError, - "mmap invalid access parameter."); - } - + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(mmap_object, weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + mmap_object_methods, /* tp_methods */ + 0, /* tp_members */ + mmap_object_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + new_mmap_object, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + + +#ifdef UNIX +#ifdef HAVE_LARGEFILE_SUPPORT +#define _Py_PARSE_OFF_T "L" +#else +#define _Py_PARSE_OFF_T "l" +#endif + +static PyObject * +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) +{ + struct _Py_stat_struct status; + int fstat_result = -1; + mmap_object *m_obj; + Py_ssize_t map_size; + off_t offset = 0; + int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ; + int devzero = -1; + int access = (int)ACCESS_DEFAULT; + static char *keywords[] = {"fileno", "length", + "flags", "prot", + "access", "offset", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|iii" _Py_PARSE_OFF_T, keywords, + &fd, &map_size, &flags, &prot, + &access, &offset)) + return NULL; + if (map_size < 0) { + PyErr_SetString(PyExc_OverflowError, + "memory mapped length must be positive"); + return NULL; + } + if (offset < 0) { + PyErr_SetString(PyExc_OverflowError, + "memory mapped offset must be positive"); + return NULL; + } + + if ((access != (int)ACCESS_DEFAULT) && + ((flags != MAP_SHARED) || (prot != (PROT_WRITE | PROT_READ)))) + return PyErr_Format(PyExc_ValueError, + "mmap can't specify both access and flags, prot."); + switch ((access_mode)access) { + case ACCESS_READ: + flags = MAP_SHARED; + prot = PROT_READ; + break; + case ACCESS_WRITE: + flags = MAP_SHARED; + prot = PROT_READ | PROT_WRITE; + break; + case ACCESS_COPY: + flags = MAP_PRIVATE; + prot = PROT_READ | PROT_WRITE; + break; + case ACCESS_DEFAULT: + /* map prot to access type */ + if ((prot & PROT_READ) && (prot & PROT_WRITE)) { + /* ACCESS_DEFAULT */ + } + else if (prot & PROT_WRITE) { + access = ACCESS_WRITE; + } + else { + access = ACCESS_READ; + } + break; + default: + return PyErr_Format(PyExc_ValueError, + "mmap invalid access parameter."); + } + if (PySys_Audit("mmap.__new__", "ini" _Py_PARSE_OFF_T, fd, map_size, access, offset) < 0) { return NULL; } -#ifdef __APPLE__ - /* Issue #11277: fsync(2) is not enough on OS X - a special, OS X specific - fcntl(2) is necessary to force DISKSYNC and get around mmap(2) bug */ - if (fd != -1) - (void)fcntl(fd, F_FULLFSYNC); -#endif - - if (fd != -1) { - Py_BEGIN_ALLOW_THREADS - fstat_result = _Py_fstat_noraise(fd, &status); - Py_END_ALLOW_THREADS - } - - if (fd != -1 && fstat_result == 0 && S_ISREG(status.st_mode)) { - if (map_size == 0) { - if (status.st_size == 0) { - PyErr_SetString(PyExc_ValueError, - "cannot mmap an empty file"); - return NULL; - } - if (offset >= status.st_size) { - PyErr_SetString(PyExc_ValueError, - "mmap offset is greater than file size"); - return NULL; - } - if (status.st_size - offset > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_ValueError, - "mmap length is too large"); - return NULL; - } - map_size = (Py_ssize_t) (status.st_size - offset); - } else if (offset > status.st_size || status.st_size - offset < map_size) { - PyErr_SetString(PyExc_ValueError, - "mmap length is greater than file size"); - return NULL; - } - } - m_obj = (mmap_object *)type->tp_alloc(type, 0); - if (m_obj == NULL) {return NULL;} - m_obj->data = NULL; - m_obj->size = map_size; - m_obj->pos = 0; - m_obj->weakreflist = NULL; - m_obj->exports = 0; - m_obj->offset = offset; - if (fd == -1) { - m_obj->fd = -1; - /* Assume the caller wants to map anonymous memory. - This is the same behaviour as Windows. mmap.mmap(-1, size) - on both Windows and Unix map anonymous memory. - */ -#ifdef MAP_ANONYMOUS - /* BSD way to map anonymous memory */ - flags |= MAP_ANONYMOUS; +#ifdef __APPLE__ + /* Issue #11277: fsync(2) is not enough on OS X - a special, OS X specific + fcntl(2) is necessary to force DISKSYNC and get around mmap(2) bug */ + if (fd != -1) + (void)fcntl(fd, F_FULLFSYNC); +#endif + + if (fd != -1) { + Py_BEGIN_ALLOW_THREADS + fstat_result = _Py_fstat_noraise(fd, &status); + Py_END_ALLOW_THREADS + } + + if (fd != -1 && fstat_result == 0 && S_ISREG(status.st_mode)) { + if (map_size == 0) { + if (status.st_size == 0) { + PyErr_SetString(PyExc_ValueError, + "cannot mmap an empty file"); + return NULL; + } + if (offset >= status.st_size) { + PyErr_SetString(PyExc_ValueError, + "mmap offset is greater than file size"); + return NULL; + } + if (status.st_size - offset > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_ValueError, + "mmap length is too large"); + return NULL; + } + map_size = (Py_ssize_t) (status.st_size - offset); + } else if (offset > status.st_size || status.st_size - offset < map_size) { + PyErr_SetString(PyExc_ValueError, + "mmap length is greater than file size"); + return NULL; + } + } + m_obj = (mmap_object *)type->tp_alloc(type, 0); + if (m_obj == NULL) {return NULL;} + m_obj->data = NULL; + m_obj->size = map_size; + m_obj->pos = 0; + m_obj->weakreflist = NULL; + m_obj->exports = 0; + m_obj->offset = offset; + if (fd == -1) { + m_obj->fd = -1; + /* Assume the caller wants to map anonymous memory. + This is the same behaviour as Windows. mmap.mmap(-1, size) + on both Windows and Unix map anonymous memory. + */ +#ifdef MAP_ANONYMOUS + /* BSD way to map anonymous memory */ + flags |= MAP_ANONYMOUS; /* VxWorks only supports MAP_ANONYMOUS with MAP_PRIVATE flag */ #ifdef __VXWORKS__ @@ -1264,325 +1264,325 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) flags |= MAP_PRIVATE; #endif -#else - /* SVR4 method to map anonymous memory is to open /dev/zero */ - fd = devzero = _Py_open("/dev/zero", O_RDWR); - if (devzero == -1) { - Py_DECREF(m_obj); - return NULL; - } -#endif - } - else { - m_obj->fd = _Py_dup(fd); - if (m_obj->fd == -1) { - Py_DECREF(m_obj); - return NULL; - } - } - - m_obj->data = mmap(NULL, map_size, - prot, flags, - fd, offset); - - if (devzero != -1) { - close(devzero); - } - - if (m_obj->data == (char *)-1) { - m_obj->data = NULL; - Py_DECREF(m_obj); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - m_obj->access = (access_mode)access; - return (PyObject *)m_obj; -} -#endif /* UNIX */ - -#ifdef MS_WINDOWS - -/* A note on sizes and offsets: while the actual map size must hold in a - Py_ssize_t, both the total file size and the start offset can be longer - than a Py_ssize_t, so we use long long which is always 64-bit. -*/ - -static PyObject * -new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) -{ - mmap_object *m_obj; - Py_ssize_t map_size; - long long offset = 0, size; - DWORD off_hi; /* upper 32 bits of offset */ - DWORD off_lo; /* lower 32 bits of offset */ - DWORD size_hi; /* upper 32 bits of size */ - DWORD size_lo; /* lower 32 bits of size */ - const char *tagname = ""; - DWORD dwErr = 0; - int fileno; - HANDLE fh = 0; - int access = (access_mode)ACCESS_DEFAULT; - DWORD flProtect, dwDesiredAccess; - static char *keywords[] = { "fileno", "length", - "tagname", - "access", "offset", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|ziL", keywords, - &fileno, &map_size, - &tagname, &access, &offset)) { - return NULL; - } - +#else + /* SVR4 method to map anonymous memory is to open /dev/zero */ + fd = devzero = _Py_open("/dev/zero", O_RDWR); + if (devzero == -1) { + Py_DECREF(m_obj); + return NULL; + } +#endif + } + else { + m_obj->fd = _Py_dup(fd); + if (m_obj->fd == -1) { + Py_DECREF(m_obj); + return NULL; + } + } + + m_obj->data = mmap(NULL, map_size, + prot, flags, + fd, offset); + + if (devzero != -1) { + close(devzero); + } + + if (m_obj->data == (char *)-1) { + m_obj->data = NULL; + Py_DECREF(m_obj); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + m_obj->access = (access_mode)access; + return (PyObject *)m_obj; +} +#endif /* UNIX */ + +#ifdef MS_WINDOWS + +/* A note on sizes and offsets: while the actual map size must hold in a + Py_ssize_t, both the total file size and the start offset can be longer + than a Py_ssize_t, so we use long long which is always 64-bit. +*/ + +static PyObject * +new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) +{ + mmap_object *m_obj; + Py_ssize_t map_size; + long long offset = 0, size; + DWORD off_hi; /* upper 32 bits of offset */ + DWORD off_lo; /* lower 32 bits of offset */ + DWORD size_hi; /* upper 32 bits of size */ + DWORD size_lo; /* lower 32 bits of size */ + const char *tagname = ""; + DWORD dwErr = 0; + int fileno; + HANDLE fh = 0; + int access = (access_mode)ACCESS_DEFAULT; + DWORD flProtect, dwDesiredAccess; + static char *keywords[] = { "fileno", "length", + "tagname", + "access", "offset", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|ziL", keywords, + &fileno, &map_size, + &tagname, &access, &offset)) { + return NULL; + } + if (PySys_Audit("mmap.__new__", "iniL", fileno, map_size, access, offset) < 0) { return NULL; } - switch((access_mode)access) { - case ACCESS_READ: - flProtect = PAGE_READONLY; - dwDesiredAccess = FILE_MAP_READ; - break; - case ACCESS_DEFAULT: case ACCESS_WRITE: - flProtect = PAGE_READWRITE; - dwDesiredAccess = FILE_MAP_WRITE; - break; - case ACCESS_COPY: - flProtect = PAGE_WRITECOPY; - dwDesiredAccess = FILE_MAP_COPY; - break; - default: - return PyErr_Format(PyExc_ValueError, - "mmap invalid access parameter."); - } - - if (map_size < 0) { - PyErr_SetString(PyExc_OverflowError, - "memory mapped length must be positive"); - return NULL; - } - if (offset < 0) { - PyErr_SetString(PyExc_OverflowError, - "memory mapped offset must be positive"); - return NULL; - } - - /* assume -1 and 0 both mean invalid filedescriptor - to 'anonymously' map memory. - XXX: fileno == 0 is a valid fd, but was accepted prior to 2.5. - XXX: Should this code be added? - if (fileno == 0) - PyErr_WarnEx(PyExc_DeprecationWarning, - "don't use 0 for anonymous memory", - 1); - */ - if (fileno != -1 && fileno != 0) { - /* Ensure that fileno is within the CRT's valid range */ - _Py_BEGIN_SUPPRESS_IPH - fh = (HANDLE)_get_osfhandle(fileno); - _Py_END_SUPPRESS_IPH - if (fh==(HANDLE)-1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - /* Win9x appears to need us seeked to zero */ - lseek(fileno, 0, SEEK_SET); - } - - m_obj = (mmap_object *)type->tp_alloc(type, 0); - if (m_obj == NULL) - return NULL; - /* Set every field to an invalid marker, so we can safely - destruct the object in the face of failure */ - m_obj->data = NULL; - m_obj->file_handle = INVALID_HANDLE_VALUE; - m_obj->map_handle = NULL; - m_obj->tagname = NULL; - m_obj->offset = offset; - - if (fh) { - /* It is necessary to duplicate the handle, so the - Python code can close it on us */ - if (!DuplicateHandle( - GetCurrentProcess(), /* source process handle */ - fh, /* handle to be duplicated */ - GetCurrentProcess(), /* target proc handle */ - (LPHANDLE)&m_obj->file_handle, /* result */ - 0, /* access - ignored due to options value */ - FALSE, /* inherited by child processes? */ - DUPLICATE_SAME_ACCESS)) { /* options */ - dwErr = GetLastError(); - Py_DECREF(m_obj); - PyErr_SetFromWindowsErr(dwErr); - return NULL; - } - if (!map_size) { - DWORD low,high; - low = GetFileSize(fh, &high); - /* low might just happen to have the value INVALID_FILE_SIZE; - so we need to check the last error also. */ - if (low == INVALID_FILE_SIZE && - (dwErr = GetLastError()) != NO_ERROR) { - Py_DECREF(m_obj); - return PyErr_SetFromWindowsErr(dwErr); - } - - size = (((long long) high) << 32) + low; - if (size == 0) { - PyErr_SetString(PyExc_ValueError, - "cannot mmap an empty file"); - Py_DECREF(m_obj); - return NULL; - } - if (offset >= size) { - PyErr_SetString(PyExc_ValueError, - "mmap offset is greater than file size"); - Py_DECREF(m_obj); - return NULL; - } - if (size - offset > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_ValueError, - "mmap length is too large"); - Py_DECREF(m_obj); - return NULL; - } - m_obj->size = (Py_ssize_t) (size - offset); - } else { - m_obj->size = map_size; - size = offset + map_size; - } - } - else { - m_obj->size = map_size; - size = offset + map_size; - } - - /* set the initial position */ - m_obj->pos = (size_t) 0; - - m_obj->weakreflist = NULL; - m_obj->exports = 0; - /* set the tag name */ - if (tagname != NULL && *tagname != '\0') { - m_obj->tagname = PyMem_Malloc(strlen(tagname)+1); - if (m_obj->tagname == NULL) { - PyErr_NoMemory(); - Py_DECREF(m_obj); - return NULL; - } - strcpy(m_obj->tagname, tagname); - } - else - m_obj->tagname = NULL; - - m_obj->access = (access_mode)access; - size_hi = (DWORD)(size >> 32); - size_lo = (DWORD)(size & 0xFFFFFFFF); - off_hi = (DWORD)(offset >> 32); - off_lo = (DWORD)(offset & 0xFFFFFFFF); - /* For files, it would be sufficient to pass 0 as size. - For anonymous maps, we have to pass the size explicitly. */ - m_obj->map_handle = CreateFileMapping(m_obj->file_handle, - NULL, - flProtect, - size_hi, - size_lo, - m_obj->tagname); - if (m_obj->map_handle != NULL) { - m_obj->data = (char *) MapViewOfFile(m_obj->map_handle, - dwDesiredAccess, - off_hi, - off_lo, - m_obj->size); - if (m_obj->data != NULL) - return (PyObject *)m_obj; - else { - dwErr = GetLastError(); - CloseHandle(m_obj->map_handle); - m_obj->map_handle = NULL; - } - } else - dwErr = GetLastError(); - Py_DECREF(m_obj); - PyErr_SetFromWindowsErr(dwErr); - return NULL; -} -#endif /* MS_WINDOWS */ - -static void -setint(PyObject *d, const char *name, long value) -{ - PyObject *o = PyLong_FromLong(value); + switch((access_mode)access) { + case ACCESS_READ: + flProtect = PAGE_READONLY; + dwDesiredAccess = FILE_MAP_READ; + break; + case ACCESS_DEFAULT: case ACCESS_WRITE: + flProtect = PAGE_READWRITE; + dwDesiredAccess = FILE_MAP_WRITE; + break; + case ACCESS_COPY: + flProtect = PAGE_WRITECOPY; + dwDesiredAccess = FILE_MAP_COPY; + break; + default: + return PyErr_Format(PyExc_ValueError, + "mmap invalid access parameter."); + } + + if (map_size < 0) { + PyErr_SetString(PyExc_OverflowError, + "memory mapped length must be positive"); + return NULL; + } + if (offset < 0) { + PyErr_SetString(PyExc_OverflowError, + "memory mapped offset must be positive"); + return NULL; + } + + /* assume -1 and 0 both mean invalid filedescriptor + to 'anonymously' map memory. + XXX: fileno == 0 is a valid fd, but was accepted prior to 2.5. + XXX: Should this code be added? + if (fileno == 0) + PyErr_WarnEx(PyExc_DeprecationWarning, + "don't use 0 for anonymous memory", + 1); + */ + if (fileno != -1 && fileno != 0) { + /* Ensure that fileno is within the CRT's valid range */ + _Py_BEGIN_SUPPRESS_IPH + fh = (HANDLE)_get_osfhandle(fileno); + _Py_END_SUPPRESS_IPH + if (fh==(HANDLE)-1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + /* Win9x appears to need us seeked to zero */ + lseek(fileno, 0, SEEK_SET); + } + + m_obj = (mmap_object *)type->tp_alloc(type, 0); + if (m_obj == NULL) + return NULL; + /* Set every field to an invalid marker, so we can safely + destruct the object in the face of failure */ + m_obj->data = NULL; + m_obj->file_handle = INVALID_HANDLE_VALUE; + m_obj->map_handle = NULL; + m_obj->tagname = NULL; + m_obj->offset = offset; + + if (fh) { + /* It is necessary to duplicate the handle, so the + Python code can close it on us */ + if (!DuplicateHandle( + GetCurrentProcess(), /* source process handle */ + fh, /* handle to be duplicated */ + GetCurrentProcess(), /* target proc handle */ + (LPHANDLE)&m_obj->file_handle, /* result */ + 0, /* access - ignored due to options value */ + FALSE, /* inherited by child processes? */ + DUPLICATE_SAME_ACCESS)) { /* options */ + dwErr = GetLastError(); + Py_DECREF(m_obj); + PyErr_SetFromWindowsErr(dwErr); + return NULL; + } + if (!map_size) { + DWORD low,high; + low = GetFileSize(fh, &high); + /* low might just happen to have the value INVALID_FILE_SIZE; + so we need to check the last error also. */ + if (low == INVALID_FILE_SIZE && + (dwErr = GetLastError()) != NO_ERROR) { + Py_DECREF(m_obj); + return PyErr_SetFromWindowsErr(dwErr); + } + + size = (((long long) high) << 32) + low; + if (size == 0) { + PyErr_SetString(PyExc_ValueError, + "cannot mmap an empty file"); + Py_DECREF(m_obj); + return NULL; + } + if (offset >= size) { + PyErr_SetString(PyExc_ValueError, + "mmap offset is greater than file size"); + Py_DECREF(m_obj); + return NULL; + } + if (size - offset > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_ValueError, + "mmap length is too large"); + Py_DECREF(m_obj); + return NULL; + } + m_obj->size = (Py_ssize_t) (size - offset); + } else { + m_obj->size = map_size; + size = offset + map_size; + } + } + else { + m_obj->size = map_size; + size = offset + map_size; + } + + /* set the initial position */ + m_obj->pos = (size_t) 0; + + m_obj->weakreflist = NULL; + m_obj->exports = 0; + /* set the tag name */ + if (tagname != NULL && *tagname != '\0') { + m_obj->tagname = PyMem_Malloc(strlen(tagname)+1); + if (m_obj->tagname == NULL) { + PyErr_NoMemory(); + Py_DECREF(m_obj); + return NULL; + } + strcpy(m_obj->tagname, tagname); + } + else + m_obj->tagname = NULL; + + m_obj->access = (access_mode)access; + size_hi = (DWORD)(size >> 32); + size_lo = (DWORD)(size & 0xFFFFFFFF); + off_hi = (DWORD)(offset >> 32); + off_lo = (DWORD)(offset & 0xFFFFFFFF); + /* For files, it would be sufficient to pass 0 as size. + For anonymous maps, we have to pass the size explicitly. */ + m_obj->map_handle = CreateFileMapping(m_obj->file_handle, + NULL, + flProtect, + size_hi, + size_lo, + m_obj->tagname); + if (m_obj->map_handle != NULL) { + m_obj->data = (char *) MapViewOfFile(m_obj->map_handle, + dwDesiredAccess, + off_hi, + off_lo, + m_obj->size); + if (m_obj->data != NULL) + return (PyObject *)m_obj; + else { + dwErr = GetLastError(); + CloseHandle(m_obj->map_handle); + m_obj->map_handle = NULL; + } + } else + dwErr = GetLastError(); + Py_DECREF(m_obj); + PyErr_SetFromWindowsErr(dwErr); + return NULL; +} +#endif /* MS_WINDOWS */ + +static void +setint(PyObject *d, const char *name, long value) +{ + PyObject *o = PyLong_FromLong(value); if (o) { PyDict_SetItemString(d, name, o); - Py_DECREF(o); - } -} - - -static struct PyModuleDef mmapmodule = { - PyModuleDef_HEAD_INIT, - "mmap", - NULL, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_mmap(void) -{ - PyObject *dict, *module; - - if (PyType_Ready(&mmap_object_type) < 0) - return NULL; - - module = PyModule_Create(&mmapmodule); - if (module == NULL) - return NULL; - dict = PyModule_GetDict(module); - if (!dict) - return NULL; - PyDict_SetItemString(dict, "error", PyExc_OSError); - PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type); -#ifdef PROT_EXEC - setint(dict, "PROT_EXEC", PROT_EXEC); -#endif -#ifdef PROT_READ - setint(dict, "PROT_READ", PROT_READ); -#endif -#ifdef PROT_WRITE - setint(dict, "PROT_WRITE", PROT_WRITE); -#endif - -#ifdef MAP_SHARED - setint(dict, "MAP_SHARED", MAP_SHARED); -#endif -#ifdef MAP_PRIVATE - setint(dict, "MAP_PRIVATE", MAP_PRIVATE); -#endif -#ifdef MAP_DENYWRITE - setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE); -#endif -#ifdef MAP_EXECUTABLE - setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE); -#endif -#ifdef MAP_ANONYMOUS - setint(dict, "MAP_ANON", MAP_ANONYMOUS); - setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS); -#endif - - setint(dict, "PAGESIZE", (long)my_getpagesize()); - - setint(dict, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()); - - setint(dict, "ACCESS_DEFAULT", ACCESS_DEFAULT); - setint(dict, "ACCESS_READ", ACCESS_READ); - setint(dict, "ACCESS_WRITE", ACCESS_WRITE); - setint(dict, "ACCESS_COPY", ACCESS_COPY); + Py_DECREF(o); + } +} + + +static struct PyModuleDef mmapmodule = { + PyModuleDef_HEAD_INIT, + "mmap", + NULL, + -1, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_mmap(void) +{ + PyObject *dict, *module; + + if (PyType_Ready(&mmap_object_type) < 0) + return NULL; + + module = PyModule_Create(&mmapmodule); + if (module == NULL) + return NULL; + dict = PyModule_GetDict(module); + if (!dict) + return NULL; + PyDict_SetItemString(dict, "error", PyExc_OSError); + PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type); +#ifdef PROT_EXEC + setint(dict, "PROT_EXEC", PROT_EXEC); +#endif +#ifdef PROT_READ + setint(dict, "PROT_READ", PROT_READ); +#endif +#ifdef PROT_WRITE + setint(dict, "PROT_WRITE", PROT_WRITE); +#endif + +#ifdef MAP_SHARED + setint(dict, "MAP_SHARED", MAP_SHARED); +#endif +#ifdef MAP_PRIVATE + setint(dict, "MAP_PRIVATE", MAP_PRIVATE); +#endif +#ifdef MAP_DENYWRITE + setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE); +#endif +#ifdef MAP_EXECUTABLE + setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE); +#endif +#ifdef MAP_ANONYMOUS + setint(dict, "MAP_ANON", MAP_ANONYMOUS); + setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS); +#endif + + setint(dict, "PAGESIZE", (long)my_getpagesize()); + + setint(dict, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()); + + setint(dict, "ACCESS_DEFAULT", ACCESS_DEFAULT); + setint(dict, "ACCESS_READ", ACCESS_READ); + setint(dict, "ACCESS_WRITE", ACCESS_WRITE); + setint(dict, "ACCESS_COPY", ACCESS_COPY); #ifdef HAVE_MADVISE // Conventional advice values @@ -1658,5 +1658,5 @@ PyInit_mmap(void) #endif #endif // HAVE_MADVISE - return module; -} + return module; +} diff --git a/contrib/tools/python3/src/Modules/overlapped.c b/contrib/tools/python3/src/Modules/overlapped.c index cd7869fa8aa..6ae66643991 100644 --- a/contrib/tools/python3/src/Modules/overlapped.c +++ b/contrib/tools/python3/src/Modules/overlapped.c @@ -1,1507 +1,1507 @@ -/* - * Support for overlapped IO - * - * Some code borrowed from Modules/_winapi.c of CPython - */ - -/* XXX check overflow and DWORD <-> Py_ssize_t conversions - Check itemsize */ - -#include "Python.h" -#include "structmember.h" // PyMemberDef - -#define WINDOWS_LEAN_AND_MEAN -#include -#include -#include - -#if defined(MS_WIN32) && !defined(MS_WIN64) -# define F_POINTER "k" -# define T_POINTER T_ULONG -#else -# define F_POINTER "K" -# define T_POINTER T_ULONGLONG -#endif - -/* Compatibility with Python 3.3 */ -#if PY_VERSION_HEX < 0x03040000 -# define PyMem_RawMalloc PyMem_Malloc -# define PyMem_RawFree PyMem_Free -#endif - -#define F_HANDLE F_POINTER -#define F_ULONG_PTR F_POINTER -#define F_DWORD "k" -#define F_BOOL "i" -#define F_UINT "I" - -#define T_HANDLE T_POINTER - -enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE, - TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE, - TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM, - TYPE_WRITE_TO}; - -typedef struct { - PyObject_HEAD - OVERLAPPED overlapped; - /* For convenience, we store the file handle too */ - HANDLE handle; - /* Error returned by last method call */ - DWORD error; - /* Type of operation */ - DWORD type; - union { - /* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */ - PyObject *allocated_buffer; - /* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */ - Py_buffer user_buffer; - - /* Data used for reading from a connectionless socket: - TYPE_READ_FROM */ - struct { - // A (buffer, (host, port)) tuple - PyObject *result; - // The actual read buffer - PyObject *allocated_buffer; - struct sockaddr_in6 address; - int address_length; - } read_from; - }; -} OverlappedObject; - -/* - * Map Windows error codes to subclasses of OSError - */ - -static PyObject * -SetFromWindowsErr(DWORD err) -{ - PyObject *exception_type; - - if (err == 0) - err = GetLastError(); - switch (err) { - case ERROR_CONNECTION_REFUSED: - exception_type = PyExc_ConnectionRefusedError; - break; - case ERROR_CONNECTION_ABORTED: - exception_type = PyExc_ConnectionAbortedError; - break; - default: - exception_type = PyExc_OSError; - } - return PyErr_SetExcFromWindowsErr(exception_type, err); -} - -/* - * Some functions should be loaded at runtime - */ - -static LPFN_ACCEPTEX Py_AcceptEx = NULL; -static LPFN_CONNECTEX Py_ConnectEx = NULL; -static LPFN_DISCONNECTEX Py_DisconnectEx = NULL; -static LPFN_TRANSMITFILE Py_TransmitFile = NULL; -static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED) = NULL; - -#define GET_WSA_POINTER(s, x) \ - (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ - &Guid##x, sizeof(Guid##x), &Py_##x, \ - sizeof(Py_##x), &dwBytes, NULL, NULL)) - -static int -initialize_function_pointers(void) -{ - GUID GuidAcceptEx = WSAID_ACCEPTEX; - GUID GuidConnectEx = WSAID_CONNECTEX; - GUID GuidDisconnectEx = WSAID_DISCONNECTEX; - GUID GuidTransmitFile = WSAID_TRANSMITFILE; - HINSTANCE hKernel32; - SOCKET s; - DWORD dwBytes; - - s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (s == INVALID_SOCKET) { - SetFromWindowsErr(WSAGetLastError()); - return -1; - } - - if (!GET_WSA_POINTER(s, AcceptEx) || - !GET_WSA_POINTER(s, ConnectEx) || - !GET_WSA_POINTER(s, DisconnectEx) || - !GET_WSA_POINTER(s, TransmitFile)) - { - closesocket(s); - SetFromWindowsErr(WSAGetLastError()); - return -1; - } - - closesocket(s); - - /* On WinXP we will have Py_CancelIoEx == NULL */ - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandle("KERNEL32"); - *(FARPROC *)&Py_CancelIoEx = GetProcAddress(hKernel32, "CancelIoEx"); - Py_END_ALLOW_THREADS - return 0; -} - -/* - * Completion port stuff - */ - -PyDoc_STRVAR( - CreateIoCompletionPort_doc, - "CreateIoCompletionPort(handle, port, key, concurrency) -> port\n\n" - "Create a completion port or register a handle with a port."); - -static PyObject * -overlapped_CreateIoCompletionPort(PyObject *self, PyObject *args) -{ - HANDLE FileHandle; - HANDLE ExistingCompletionPort; - ULONG_PTR CompletionKey; - DWORD NumberOfConcurrentThreads; - HANDLE ret; - - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_ULONG_PTR F_DWORD, - &FileHandle, &ExistingCompletionPort, &CompletionKey, - &NumberOfConcurrentThreads)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - ret = CreateIoCompletionPort(FileHandle, ExistingCompletionPort, - CompletionKey, NumberOfConcurrentThreads); - Py_END_ALLOW_THREADS - - if (ret == NULL) - return SetFromWindowsErr(0); - return Py_BuildValue(F_HANDLE, ret); -} - -PyDoc_STRVAR( - GetQueuedCompletionStatus_doc, - "GetQueuedCompletionStatus(port, msecs) -> (err, bytes, key, address)\n\n" - "Get a message from completion port. Wait for up to msecs milliseconds."); - -static PyObject * -overlapped_GetQueuedCompletionStatus(PyObject *self, PyObject *args) -{ - HANDLE CompletionPort = NULL; - DWORD NumberOfBytes = 0; - ULONG_PTR CompletionKey = 0; - OVERLAPPED *Overlapped = NULL; - DWORD Milliseconds; - DWORD err; - BOOL ret; - - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, - &CompletionPort, &Milliseconds)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - ret = GetQueuedCompletionStatus(CompletionPort, &NumberOfBytes, - &CompletionKey, &Overlapped, Milliseconds); - Py_END_ALLOW_THREADS - - err = ret ? ERROR_SUCCESS : GetLastError(); - if (Overlapped == NULL) { - if (err == WAIT_TIMEOUT) - Py_RETURN_NONE; - else - return SetFromWindowsErr(err); - } - return Py_BuildValue(F_DWORD F_DWORD F_ULONG_PTR F_POINTER, - err, NumberOfBytes, CompletionKey, Overlapped); -} - -PyDoc_STRVAR( - PostQueuedCompletionStatus_doc, - "PostQueuedCompletionStatus(port, bytes, key, address) -> None\n\n" - "Post a message to completion port."); - -static PyObject * -overlapped_PostQueuedCompletionStatus(PyObject *self, PyObject *args) -{ - HANDLE CompletionPort; - DWORD NumberOfBytes; - ULONG_PTR CompletionKey; - OVERLAPPED *Overlapped; - BOOL ret; - - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD F_ULONG_PTR F_POINTER, - &CompletionPort, &NumberOfBytes, &CompletionKey, - &Overlapped)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - ret = PostQueuedCompletionStatus(CompletionPort, NumberOfBytes, - CompletionKey, Overlapped); - Py_END_ALLOW_THREADS - - if (!ret) - return SetFromWindowsErr(0); - Py_RETURN_NONE; -} - -/* - * Wait for a handle - */ - -struct PostCallbackData { - HANDLE CompletionPort; - LPOVERLAPPED Overlapped; -}; - -static VOID CALLBACK -PostToQueueCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) -{ - struct PostCallbackData *p = (struct PostCallbackData*) lpParameter; - - PostQueuedCompletionStatus(p->CompletionPort, TimerOrWaitFired, - 0, p->Overlapped); - /* ignore possible error! */ - PyMem_RawFree(p); -} - -PyDoc_STRVAR( - RegisterWaitWithQueue_doc, - "RegisterWaitWithQueue(Object, CompletionPort, Overlapped, Timeout)\n" - " -> WaitHandle\n\n" - "Register wait for Object; when complete CompletionPort is notified.\n"); - -static PyObject * -overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args) -{ - HANDLE NewWaitObject; - HANDLE Object; - ULONG Milliseconds; - struct PostCallbackData data, *pdata; - - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_POINTER F_DWORD, - &Object, - &data.CompletionPort, - &data.Overlapped, - &Milliseconds)) - return NULL; - - /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since - PostToQueueCallback() will call PyMem_Free() from a new C thread - which doesn't hold the GIL. */ - pdata = PyMem_RawMalloc(sizeof(struct PostCallbackData)); - if (pdata == NULL) - return SetFromWindowsErr(0); - - *pdata = data; - - if (!RegisterWaitForSingleObject( - &NewWaitObject, Object, PostToQueueCallback, pdata, Milliseconds, - WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) - { - PyMem_RawFree(pdata); - return SetFromWindowsErr(0); - } - - return Py_BuildValue(F_HANDLE, NewWaitObject); -} - -PyDoc_STRVAR( - UnregisterWait_doc, - "UnregisterWait(WaitHandle) -> None\n\n" - "Unregister wait handle.\n"); - -static PyObject * -overlapped_UnregisterWait(PyObject *self, PyObject *args) -{ - HANDLE WaitHandle; - BOOL ret; - - if (!PyArg_ParseTuple(args, F_HANDLE, &WaitHandle)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - ret = UnregisterWait(WaitHandle); - Py_END_ALLOW_THREADS - - if (!ret) - return SetFromWindowsErr(0); - Py_RETURN_NONE; -} - -PyDoc_STRVAR( - UnregisterWaitEx_doc, - "UnregisterWaitEx(WaitHandle, Event) -> None\n\n" - "Unregister wait handle.\n"); - -static PyObject * -overlapped_UnregisterWaitEx(PyObject *self, PyObject *args) -{ - HANDLE WaitHandle, Event; - BOOL ret; - - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &WaitHandle, &Event)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - ret = UnregisterWaitEx(WaitHandle, Event); - Py_END_ALLOW_THREADS - - if (!ret) - return SetFromWindowsErr(0); - Py_RETURN_NONE; -} - -/* - * Event functions -- currently only used by tests - */ - -PyDoc_STRVAR( - CreateEvent_doc, - "CreateEvent(EventAttributes, ManualReset, InitialState, Name)" - " -> Handle\n\n" - "Create an event. EventAttributes must be None.\n"); - -static PyObject * -overlapped_CreateEvent(PyObject *self, PyObject *args) -{ - PyObject *EventAttributes; - BOOL ManualReset; - BOOL InitialState; - Py_UNICODE *Name; - HANDLE Event; - - if (!PyArg_ParseTuple(args, "O" F_BOOL F_BOOL "Z", - &EventAttributes, &ManualReset, - &InitialState, &Name)) - return NULL; - - if (EventAttributes != Py_None) { - PyErr_SetString(PyExc_ValueError, "EventAttributes must be None"); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - Event = CreateEventW(NULL, ManualReset, InitialState, Name); - Py_END_ALLOW_THREADS - - if (Event == NULL) - return SetFromWindowsErr(0); - return Py_BuildValue(F_HANDLE, Event); -} - -PyDoc_STRVAR( - SetEvent_doc, - "SetEvent(Handle) -> None\n\n" - "Set event.\n"); - -static PyObject * -overlapped_SetEvent(PyObject *self, PyObject *args) -{ - HANDLE Handle; - BOOL ret; - - if (!PyArg_ParseTuple(args, F_HANDLE, &Handle)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - ret = SetEvent(Handle); - Py_END_ALLOW_THREADS - - if (!ret) - return SetFromWindowsErr(0); - Py_RETURN_NONE; -} - -PyDoc_STRVAR( - ResetEvent_doc, - "ResetEvent(Handle) -> None\n\n" - "Reset event.\n"); - -static PyObject * -overlapped_ResetEvent(PyObject *self, PyObject *args) -{ - HANDLE Handle; - BOOL ret; - - if (!PyArg_ParseTuple(args, F_HANDLE, &Handle)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - ret = ResetEvent(Handle); - Py_END_ALLOW_THREADS - - if (!ret) - return SetFromWindowsErr(0); - Py_RETURN_NONE; -} - -/* - * Bind socket handle to local port without doing slow getaddrinfo() - */ - -PyDoc_STRVAR( - BindLocal_doc, - "BindLocal(handle, family) -> None\n\n" - "Bind a socket handle to an arbitrary local port.\n" - "family should AF_INET or AF_INET6.\n"); - -static PyObject * -overlapped_BindLocal(PyObject *self, PyObject *args) -{ - SOCKET Socket; - int Family; - BOOL ret; - - if (!PyArg_ParseTuple(args, F_HANDLE "i", &Socket, &Family)) - return NULL; - - if (Family == AF_INET) { - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.S_un.S_addr = INADDR_ANY; - ret = bind(Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; - } else if (Family == AF_INET6) { - struct sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_port = 0; - addr.sin6_addr = in6addr_any; - ret = bind(Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; - } else { - PyErr_SetString(PyExc_ValueError, "expected tuple of length 2 or 4"); - return NULL; - } - - if (!ret) - return SetFromWindowsErr(WSAGetLastError()); - Py_RETURN_NONE; -} - -/* - * Windows equivalent of os.strerror() -- compare _ctypes/callproc.c - */ - -PyDoc_STRVAR( - FormatMessage_doc, - "FormatMessage(error_code) -> error_message\n\n" - "Return error message for an error code."); - -static PyObject * -overlapped_FormatMessage(PyObject *ignore, PyObject *args) -{ - DWORD code, n; - WCHAR *lpMsgBuf; - PyObject *res; - - if (!PyArg_ParseTuple(args, F_DWORD, &code)) - return NULL; - - n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - code, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPWSTR) &lpMsgBuf, - 0, - NULL); - if (n) { - while (iswspace(lpMsgBuf[n-1])) - --n; - lpMsgBuf[n] = L'\0'; - res = Py_BuildValue("u", lpMsgBuf); - } else { - res = PyUnicode_FromFormat("unknown error code %u", code); - } - LocalFree(lpMsgBuf); - return res; -} - - -/* - * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE - */ - -static void -mark_as_completed(OVERLAPPED *ov) -{ - ov->Internal = 0; - if (ov->hEvent != NULL) - SetEvent(ov->hEvent); -} - -/* - * A Python object wrapping an OVERLAPPED structure and other useful data - * for overlapped I/O - */ - -PyDoc_STRVAR( - Overlapped_doc, - "Overlapped object"); - -static PyObject * -Overlapped_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - OverlappedObject *self; - HANDLE event = INVALID_HANDLE_VALUE; - static char *kwlist[] = {"event", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|" F_HANDLE, kwlist, &event)) - return NULL; - - if (event == INVALID_HANDLE_VALUE) { - event = CreateEvent(NULL, TRUE, FALSE, NULL); - if (event == NULL) - return SetFromWindowsErr(0); - } - - self = PyObject_New(OverlappedObject, type); - if (self == NULL) { - if (event != NULL) - CloseHandle(event); - return NULL; - } - - self->handle = NULL; - self->error = 0; - self->type = TYPE_NONE; - self->allocated_buffer = NULL; - memset(&self->overlapped, 0, sizeof(OVERLAPPED)); - memset(&self->user_buffer, 0, sizeof(Py_buffer)); - if (event) - self->overlapped.hEvent = event; - return (PyObject *)self; -} - - -/* Note (bpo-32710): OverlappedType.tp_clear is not defined to not release - buffers while overlapped are still running, to prevent a crash. */ -static int -Overlapped_clear(OverlappedObject *self) -{ - switch (self->type) { - case TYPE_READ: - case TYPE_ACCEPT: { - Py_CLEAR(self->allocated_buffer); - break; - } - case TYPE_READ_FROM: { - // An initial call to WSARecvFrom will only allocate the buffer. - // The result tuple of (message, address) is only - // allocated _after_ a message has been received. - if(self->read_from.result) { - // We've received a message, free the result tuple. - Py_CLEAR(self->read_from.result); - } - if(self->read_from.allocated_buffer) { - Py_CLEAR(self->read_from.allocated_buffer); - } - break; - } - case TYPE_WRITE: - case TYPE_WRITE_TO: - case TYPE_READINTO: { - if (self->user_buffer.obj) { - PyBuffer_Release(&self->user_buffer); - } - break; - } - } - self->type = TYPE_NOT_STARTED; - return 0; -} - -static void -Overlapped_dealloc(OverlappedObject *self) -{ - DWORD bytes; - DWORD olderr = GetLastError(); - BOOL wait = FALSE; - BOOL ret; - - if (!HasOverlappedIoCompleted(&self->overlapped) && - self->type != TYPE_NOT_STARTED) - { - if (Py_CancelIoEx && Py_CancelIoEx(self->handle, &self->overlapped)) - wait = TRUE; - - Py_BEGIN_ALLOW_THREADS - ret = GetOverlappedResult(self->handle, &self->overlapped, - &bytes, wait); - Py_END_ALLOW_THREADS - - switch (ret ? ERROR_SUCCESS : GetLastError()) { - case ERROR_SUCCESS: - case ERROR_NOT_FOUND: - case ERROR_OPERATION_ABORTED: - break; - default: - PyErr_Format( - PyExc_RuntimeError, - "%R still has pending operation at " - "deallocation, the process may crash", self); - PyErr_WriteUnraisable(NULL); - } - } - - if (self->overlapped.hEvent != NULL) { - CloseHandle(self->overlapped.hEvent); - } - - Overlapped_clear(self); - PyObject_Del(self); - SetLastError(olderr); -} - - -/* Convert IPv4 sockaddr to a Python str. */ - -static PyObject * -make_ipv4_addr(const struct sockaddr_in *addr) -{ - char buf[INET_ADDRSTRLEN]; - if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return PyUnicode_FromString(buf); -} - -/* Convert IPv6 sockaddr to a Python str. */ - -static PyObject * -make_ipv6_addr(const struct sockaddr_in6 *addr) -{ - char buf[INET6_ADDRSTRLEN]; - if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return PyUnicode_FromString(buf); -} - -static PyObject* -unparse_address(LPSOCKADDR Address, DWORD Length) -{ - /* The function is adopted from mocketmodule.c makesockaddr()*/ - - switch(Address->sa_family) { - case AF_INET: { - const struct sockaddr_in *a = (const struct sockaddr_in *)Address; - PyObject *addrobj = make_ipv4_addr(a); - PyObject *ret = NULL; - if (addrobj) { - ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port)); - Py_DECREF(addrobj); - } - return ret; - } - case AF_INET6: { - const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)Address; - PyObject *addrobj = make_ipv6_addr(a); - PyObject *ret = NULL; - if (addrobj) { - ret = Py_BuildValue("OiII", - addrobj, - ntohs(a->sin6_port), - ntohl(a->sin6_flowinfo), - a->sin6_scope_id); - Py_DECREF(addrobj); - } - return ret; - } - default: { - PyErr_SetString(PyExc_ValueError, "recvfrom returned unsupported address family"); - return NULL; - } - } -} - -PyDoc_STRVAR( - Overlapped_cancel_doc, - "cancel() -> None\n\n" - "Cancel overlapped operation"); - -static PyObject * -Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) -{ - BOOL ret = TRUE; - - if (self->type == TYPE_NOT_STARTED - || self->type == TYPE_WAIT_NAMED_PIPE_AND_CONNECT) - Py_RETURN_NONE; - - if (!HasOverlappedIoCompleted(&self->overlapped)) { - Py_BEGIN_ALLOW_THREADS - if (Py_CancelIoEx) - ret = Py_CancelIoEx(self->handle, &self->overlapped); - else - ret = CancelIo(self->handle); - Py_END_ALLOW_THREADS - } - - /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */ - if (!ret && GetLastError() != ERROR_NOT_FOUND) - return SetFromWindowsErr(0); - Py_RETURN_NONE; -} - -PyDoc_STRVAR( - Overlapped_getresult_doc, - "getresult(wait=False) -> result\n\n" - "Retrieve result of operation. If wait is true then it blocks\n" - "until the operation is finished. If wait is false and the\n" - "operation is still pending then an error is raised."); - -static PyObject * -Overlapped_getresult(OverlappedObject *self, PyObject *args) -{ - BOOL wait = FALSE; - DWORD transferred = 0; - BOOL ret; - DWORD err; - PyObject *addr; - - if (!PyArg_ParseTuple(args, "|" F_BOOL, &wait)) - return NULL; - - if (self->type == TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation not yet attempted"); - return NULL; - } - - if (self->type == TYPE_NOT_STARTED) { - PyErr_SetString(PyExc_ValueError, "operation failed to start"); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - ret = GetOverlappedResult(self->handle, &self->overlapped, &transferred, - wait); - Py_END_ALLOW_THREADS - - self->error = err = ret ? ERROR_SUCCESS : GetLastError(); - switch (err) { - case ERROR_SUCCESS: - case ERROR_MORE_DATA: - break; - case ERROR_BROKEN_PIPE: - if (self->type == TYPE_READ || self->type == TYPE_READINTO) { - break; - } - else if (self->type == TYPE_READ_FROM && - (self->read_from.result != NULL || - self->read_from.allocated_buffer != NULL)) - { - break; - } - /* fall through */ - default: - return SetFromWindowsErr(err); - } - - switch (self->type) { - case TYPE_READ: - assert(PyBytes_CheckExact(self->allocated_buffer)); - if (transferred != PyBytes_GET_SIZE(self->allocated_buffer) && - _PyBytes_Resize(&self->allocated_buffer, transferred)) - return NULL; - - Py_INCREF(self->allocated_buffer); - return self->allocated_buffer; - case TYPE_READ_FROM: - assert(PyBytes_CheckExact(self->read_from.allocated_buffer)); - - if (transferred != PyBytes_GET_SIZE( - self->read_from.allocated_buffer) && - _PyBytes_Resize(&self->read_from.allocated_buffer, transferred)) - { - return NULL; - } - - // unparse the address - addr = unparse_address((SOCKADDR*)&self->read_from.address, - self->read_from.address_length); - - if (addr == NULL) { - return NULL; - } - - // The result is a two item tuple: (message, address) - self->read_from.result = PyTuple_New(2); - if (self->read_from.result == NULL) { - Py_CLEAR(addr); - return NULL; - } - - // first item: message - Py_INCREF(self->read_from.allocated_buffer); - PyTuple_SET_ITEM(self->read_from.result, 0, - self->read_from.allocated_buffer); - // second item: address - PyTuple_SET_ITEM(self->read_from.result, 1, addr); - - Py_INCREF(self->read_from.result); - return self->read_from.result; - default: - return PyLong_FromUnsignedLong((unsigned long) transferred); - } -} - -static PyObject * -do_ReadFile(OverlappedObject *self, HANDLE handle, - char *bufstart, DWORD buflen) -{ - DWORD nread; - int ret; - DWORD err; - - Py_BEGIN_ALLOW_THREADS - ret = ReadFile(handle, bufstart, buflen, &nread, - &self->overlapped); - Py_END_ALLOW_THREADS - - self->error = err = ret ? ERROR_SUCCESS : GetLastError(); - switch (err) { - case ERROR_BROKEN_PIPE: - mark_as_completed(&self->overlapped); - return SetFromWindowsErr(err); - case ERROR_SUCCESS: - case ERROR_MORE_DATA: - case ERROR_IO_PENDING: - Py_RETURN_NONE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); - } -} - -PyDoc_STRVAR( - Overlapped_ReadFile_doc, - "ReadFile(handle, size) -> Overlapped[message]\n\n" - "Start overlapped read"); - -static PyObject * -Overlapped_ReadFile(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - DWORD size; - PyObject *buf; - - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, &handle, &size)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - -#if SIZEOF_SIZE_T <= SIZEOF_LONG - size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX); -#endif - buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1)); - if (buf == NULL) - return NULL; - - self->type = TYPE_READ; - self->handle = handle; - self->allocated_buffer = buf; - - return do_ReadFile(self, handle, PyBytes_AS_STRING(buf), size); -} - -PyDoc_STRVAR( - Overlapped_ReadFileInto_doc, - "ReadFileInto(handle, buf) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped receive"); - -static PyObject * -Overlapped_ReadFileInto(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - PyObject *bufobj; - - if (!PyArg_ParseTuple(args, F_HANDLE "O", &handle, &bufobj)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - -#if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); - PyErr_SetString(PyExc_ValueError, "buffer too large"); - return NULL; - } -#endif - - self->type = TYPE_READINTO; - self->handle = handle; - - return do_ReadFile(self, handle, self->user_buffer.buf, - (DWORD)self->user_buffer.len); -} - -static PyObject * -do_WSARecv(OverlappedObject *self, HANDLE handle, - char *bufstart, DWORD buflen, DWORD flags) -{ - DWORD nread; - WSABUF wsabuf; - int ret; - DWORD err; - - wsabuf.buf = bufstart; - wsabuf.len = buflen; - - Py_BEGIN_ALLOW_THREADS - ret = WSARecv((SOCKET)handle, &wsabuf, 1, &nread, &flags, - &self->overlapped, NULL); - Py_END_ALLOW_THREADS - - self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); - switch (err) { - case ERROR_BROKEN_PIPE: - mark_as_completed(&self->overlapped); - return SetFromWindowsErr(err); - case ERROR_SUCCESS: - case ERROR_MORE_DATA: - case ERROR_IO_PENDING: - Py_RETURN_NONE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); - } -} - -PyDoc_STRVAR( - Overlapped_WSARecv_doc, - "RecvFile(handle, size, flags) -> Overlapped[message]\n\n" - "Start overlapped receive"); - -static PyObject * -Overlapped_WSARecv(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - DWORD size; - DWORD flags = 0; - PyObject *buf; - - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD "|" F_DWORD, - &handle, &size, &flags)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - -#if SIZEOF_SIZE_T <= SIZEOF_LONG - size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX); -#endif - buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1)); - if (buf == NULL) - return NULL; - - self->type = TYPE_READ; - self->handle = handle; - self->allocated_buffer = buf; - - return do_WSARecv(self, handle, PyBytes_AS_STRING(buf), size, flags); -} - -PyDoc_STRVAR( - Overlapped_WSARecvInto_doc, - "WSARecvInto(handle, buf, flags) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped receive"); - -static PyObject * -Overlapped_WSARecvInto(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - PyObject *bufobj; - DWORD flags; - - if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD, - &handle, &bufobj, &flags)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - -#if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); - PyErr_SetString(PyExc_ValueError, "buffer too large"); - return NULL; - } -#endif - - self->type = TYPE_READINTO; - self->handle = handle; - - return do_WSARecv(self, handle, self->user_buffer.buf, - (DWORD)self->user_buffer.len, flags); -} - -PyDoc_STRVAR( - Overlapped_WriteFile_doc, - "WriteFile(handle, buf) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped write"); - -static PyObject * -Overlapped_WriteFile(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - PyObject *bufobj; - DWORD written; - BOOL ret; - DWORD err; - - if (!PyArg_ParseTuple(args, F_HANDLE "O", &handle, &bufobj)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - -#if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); - PyErr_SetString(PyExc_ValueError, "buffer too large"); - return NULL; - } -#endif - - self->type = TYPE_WRITE; - self->handle = handle; - - Py_BEGIN_ALLOW_THREADS - ret = WriteFile(handle, self->user_buffer.buf, - (DWORD)self->user_buffer.len, - &written, &self->overlapped); - Py_END_ALLOW_THREADS - - self->error = err = ret ? ERROR_SUCCESS : GetLastError(); - switch (err) { - case ERROR_SUCCESS: - case ERROR_IO_PENDING: - Py_RETURN_NONE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); - } -} - -PyDoc_STRVAR( - Overlapped_WSASend_doc, - "WSASend(handle, buf, flags) -> Overlapped[bytes_transferred]\n\n" - "Start overlapped send"); - -static PyObject * -Overlapped_WSASend(OverlappedObject *self, PyObject *args) -{ - HANDLE handle; - PyObject *bufobj; - DWORD flags; - DWORD written; - WSABUF wsabuf; - int ret; - DWORD err; - - if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD, - &handle, &bufobj, &flags)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - -#if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); - PyErr_SetString(PyExc_ValueError, "buffer too large"); - return NULL; - } -#endif - - self->type = TYPE_WRITE; - self->handle = handle; - wsabuf.len = (DWORD)self->user_buffer.len; - wsabuf.buf = self->user_buffer.buf; - - Py_BEGIN_ALLOW_THREADS - ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags, - &self->overlapped, NULL); - Py_END_ALLOW_THREADS - - self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); - switch (err) { - case ERROR_SUCCESS: - case ERROR_IO_PENDING: - Py_RETURN_NONE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); - } -} - -PyDoc_STRVAR( - Overlapped_AcceptEx_doc, - "AcceptEx(listen_handle, accept_handle) -> Overlapped[address_as_bytes]\n\n" - "Start overlapped wait for client to connect"); - -static PyObject * -Overlapped_AcceptEx(OverlappedObject *self, PyObject *args) -{ - SOCKET ListenSocket; - SOCKET AcceptSocket; - DWORD BytesReceived; - DWORD size; - PyObject *buf; - BOOL ret; - DWORD err; - - if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, - &ListenSocket, &AcceptSocket)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - size = sizeof(struct sockaddr_in6) + 16; - buf = PyBytes_FromStringAndSize(NULL, size*2); - if (!buf) - return NULL; - - self->type = TYPE_ACCEPT; - self->handle = (HANDLE)ListenSocket; - self->allocated_buffer = buf; - - Py_BEGIN_ALLOW_THREADS - ret = Py_AcceptEx(ListenSocket, AcceptSocket, PyBytes_AS_STRING(buf), - 0, size, size, &BytesReceived, &self->overlapped); - Py_END_ALLOW_THREADS - - self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); - switch (err) { - case ERROR_SUCCESS: - case ERROR_IO_PENDING: - Py_RETURN_NONE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); - } -} - - -static int -parse_address(PyObject *obj, SOCKADDR *Address, int Length) -{ - Py_UNICODE *Host; - unsigned short Port; - unsigned long FlowInfo; - unsigned long ScopeId; - - memset(Address, 0, Length); - - if (PyArg_ParseTuple(obj, "uH", &Host, &Port)) - { - Address->sa_family = AF_INET; - if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) { - SetFromWindowsErr(WSAGetLastError()); - return -1; - } - ((SOCKADDR_IN*)Address)->sin_port = htons(Port); - return Length; - } - else if (PyArg_ParseTuple(obj, - "uHkk;ConnectEx(): illegal address_as_bytes " - "argument", &Host, &Port, &FlowInfo, &ScopeId)) - { - PyErr_Clear(); - Address->sa_family = AF_INET6; - if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) { - SetFromWindowsErr(WSAGetLastError()); - return -1; - } - ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port); - ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo; - ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId; - return Length; - } - - return -1; -} - -PyDoc_STRVAR( - Overlapped_ConnectEx_doc, - "ConnectEx(client_handle, address_as_bytes) -> Overlapped[None]\n\n" - "Start overlapped connect. client_handle should be unbound."); - -static PyObject * -Overlapped_ConnectEx(OverlappedObject *self, PyObject *args) -{ - SOCKET ConnectSocket; - PyObject *AddressObj; - char AddressBuf[sizeof(struct sockaddr_in6)]; - SOCKADDR *Address = (SOCKADDR*)AddressBuf; - int Length; - BOOL ret; - DWORD err; - - if (!PyArg_ParseTuple(args, F_HANDLE "O!:ConnectEx", - &ConnectSocket, &PyTuple_Type, &AddressObj)) - { - return NULL; - } - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - Length = sizeof(AddressBuf); - Length = parse_address(AddressObj, Address, Length); - if (Length < 0) - return NULL; - - self->type = TYPE_CONNECT; - self->handle = (HANDLE)ConnectSocket; +/* + * Support for overlapped IO + * + * Some code borrowed from Modules/_winapi.c of CPython + */ + +/* XXX check overflow and DWORD <-> Py_ssize_t conversions + Check itemsize */ + +#include "Python.h" +#include "structmember.h" // PyMemberDef + +#define WINDOWS_LEAN_AND_MEAN +#include +#include +#include + +#if defined(MS_WIN32) && !defined(MS_WIN64) +# define F_POINTER "k" +# define T_POINTER T_ULONG +#else +# define F_POINTER "K" +# define T_POINTER T_ULONGLONG +#endif + +/* Compatibility with Python 3.3 */ +#if PY_VERSION_HEX < 0x03040000 +# define PyMem_RawMalloc PyMem_Malloc +# define PyMem_RawFree PyMem_Free +#endif + +#define F_HANDLE F_POINTER +#define F_ULONG_PTR F_POINTER +#define F_DWORD "k" +#define F_BOOL "i" +#define F_UINT "I" + +#define T_HANDLE T_POINTER + +enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE, + TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE, + TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM, + TYPE_WRITE_TO}; + +typedef struct { + PyObject_HEAD + OVERLAPPED overlapped; + /* For convenience, we store the file handle too */ + HANDLE handle; + /* Error returned by last method call */ + DWORD error; + /* Type of operation */ + DWORD type; + union { + /* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */ + PyObject *allocated_buffer; + /* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */ + Py_buffer user_buffer; + /* Data used for reading from a connectionless socket: + TYPE_READ_FROM */ + struct { + // A (buffer, (host, port)) tuple + PyObject *result; + // The actual read buffer + PyObject *allocated_buffer; + struct sockaddr_in6 address; + int address_length; + } read_from; + }; +} OverlappedObject; + +/* + * Map Windows error codes to subclasses of OSError + */ + +static PyObject * +SetFromWindowsErr(DWORD err) +{ + PyObject *exception_type; + + if (err == 0) + err = GetLastError(); + switch (err) { + case ERROR_CONNECTION_REFUSED: + exception_type = PyExc_ConnectionRefusedError; + break; + case ERROR_CONNECTION_ABORTED: + exception_type = PyExc_ConnectionAbortedError; + break; + default: + exception_type = PyExc_OSError; + } + return PyErr_SetExcFromWindowsErr(exception_type, err); +} + +/* + * Some functions should be loaded at runtime + */ + +static LPFN_ACCEPTEX Py_AcceptEx = NULL; +static LPFN_CONNECTEX Py_ConnectEx = NULL; +static LPFN_DISCONNECTEX Py_DisconnectEx = NULL; +static LPFN_TRANSMITFILE Py_TransmitFile = NULL; +static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED) = NULL; + +#define GET_WSA_POINTER(s, x) \ + (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ + &Guid##x, sizeof(Guid##x), &Py_##x, \ + sizeof(Py_##x), &dwBytes, NULL, NULL)) + +static int +initialize_function_pointers(void) +{ + GUID GuidAcceptEx = WSAID_ACCEPTEX; + GUID GuidConnectEx = WSAID_CONNECTEX; + GUID GuidDisconnectEx = WSAID_DISCONNECTEX; + GUID GuidTransmitFile = WSAID_TRANSMITFILE; + HINSTANCE hKernel32; + SOCKET s; + DWORD dwBytes; + + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (s == INVALID_SOCKET) { + SetFromWindowsErr(WSAGetLastError()); + return -1; + } + + if (!GET_WSA_POINTER(s, AcceptEx) || + !GET_WSA_POINTER(s, ConnectEx) || + !GET_WSA_POINTER(s, DisconnectEx) || + !GET_WSA_POINTER(s, TransmitFile)) + { + closesocket(s); + SetFromWindowsErr(WSAGetLastError()); + return -1; + } + + closesocket(s); + + /* On WinXP we will have Py_CancelIoEx == NULL */ Py_BEGIN_ALLOW_THREADS - ret = Py_ConnectEx(ConnectSocket, Address, Length, - NULL, 0, NULL, &self->overlapped); + hKernel32 = GetModuleHandle("KERNEL32"); + *(FARPROC *)&Py_CancelIoEx = GetProcAddress(hKernel32, "CancelIoEx"); Py_END_ALLOW_THREADS + return 0; +} + +/* + * Completion port stuff + */ + +PyDoc_STRVAR( + CreateIoCompletionPort_doc, + "CreateIoCompletionPort(handle, port, key, concurrency) -> port\n\n" + "Create a completion port or register a handle with a port."); + +static PyObject * +overlapped_CreateIoCompletionPort(PyObject *self, PyObject *args) +{ + HANDLE FileHandle; + HANDLE ExistingCompletionPort; + ULONG_PTR CompletionKey; + DWORD NumberOfConcurrentThreads; + HANDLE ret; + + if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_ULONG_PTR F_DWORD, + &FileHandle, &ExistingCompletionPort, &CompletionKey, + &NumberOfConcurrentThreads)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = CreateIoCompletionPort(FileHandle, ExistingCompletionPort, + CompletionKey, NumberOfConcurrentThreads); + Py_END_ALLOW_THREADS + + if (ret == NULL) + return SetFromWindowsErr(0); + return Py_BuildValue(F_HANDLE, ret); +} + +PyDoc_STRVAR( + GetQueuedCompletionStatus_doc, + "GetQueuedCompletionStatus(port, msecs) -> (err, bytes, key, address)\n\n" + "Get a message from completion port. Wait for up to msecs milliseconds."); + +static PyObject * +overlapped_GetQueuedCompletionStatus(PyObject *self, PyObject *args) +{ + HANDLE CompletionPort = NULL; + DWORD NumberOfBytes = 0; + ULONG_PTR CompletionKey = 0; + OVERLAPPED *Overlapped = NULL; + DWORD Milliseconds; + DWORD err; + BOOL ret; + + if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, + &CompletionPort, &Milliseconds)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = GetQueuedCompletionStatus(CompletionPort, &NumberOfBytes, + &CompletionKey, &Overlapped, Milliseconds); + Py_END_ALLOW_THREADS + + err = ret ? ERROR_SUCCESS : GetLastError(); + if (Overlapped == NULL) { + if (err == WAIT_TIMEOUT) + Py_RETURN_NONE; + else + return SetFromWindowsErr(err); + } + return Py_BuildValue(F_DWORD F_DWORD F_ULONG_PTR F_POINTER, + err, NumberOfBytes, CompletionKey, Overlapped); +} + +PyDoc_STRVAR( + PostQueuedCompletionStatus_doc, + "PostQueuedCompletionStatus(port, bytes, key, address) -> None\n\n" + "Post a message to completion port."); + +static PyObject * +overlapped_PostQueuedCompletionStatus(PyObject *self, PyObject *args) +{ + HANDLE CompletionPort; + DWORD NumberOfBytes; + ULONG_PTR CompletionKey; + OVERLAPPED *Overlapped; + BOOL ret; + + if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD F_ULONG_PTR F_POINTER, + &CompletionPort, &NumberOfBytes, &CompletionKey, + &Overlapped)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = PostQueuedCompletionStatus(CompletionPort, NumberOfBytes, + CompletionKey, Overlapped); + Py_END_ALLOW_THREADS + + if (!ret) + return SetFromWindowsErr(0); + Py_RETURN_NONE; +} + +/* + * Wait for a handle + */ + +struct PostCallbackData { + HANDLE CompletionPort; + LPOVERLAPPED Overlapped; +}; + +static VOID CALLBACK +PostToQueueCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) +{ + struct PostCallbackData *p = (struct PostCallbackData*) lpParameter; + + PostQueuedCompletionStatus(p->CompletionPort, TimerOrWaitFired, + 0, p->Overlapped); + /* ignore possible error! */ + PyMem_RawFree(p); +} + +PyDoc_STRVAR( + RegisterWaitWithQueue_doc, + "RegisterWaitWithQueue(Object, CompletionPort, Overlapped, Timeout)\n" + " -> WaitHandle\n\n" + "Register wait for Object; when complete CompletionPort is notified.\n"); + +static PyObject * +overlapped_RegisterWaitWithQueue(PyObject *self, PyObject *args) +{ + HANDLE NewWaitObject; + HANDLE Object; + ULONG Milliseconds; + struct PostCallbackData data, *pdata; + + if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE F_POINTER F_DWORD, + &Object, + &data.CompletionPort, + &data.Overlapped, + &Milliseconds)) + return NULL; + + /* Use PyMem_RawMalloc() rather than PyMem_Malloc(), since + PostToQueueCallback() will call PyMem_Free() from a new C thread + which doesn't hold the GIL. */ + pdata = PyMem_RawMalloc(sizeof(struct PostCallbackData)); + if (pdata == NULL) + return SetFromWindowsErr(0); + + *pdata = data; + + if (!RegisterWaitForSingleObject( + &NewWaitObject, Object, PostToQueueCallback, pdata, Milliseconds, + WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) + { + PyMem_RawFree(pdata); + return SetFromWindowsErr(0); + } + + return Py_BuildValue(F_HANDLE, NewWaitObject); +} + +PyDoc_STRVAR( + UnregisterWait_doc, + "UnregisterWait(WaitHandle) -> None\n\n" + "Unregister wait handle.\n"); + +static PyObject * +overlapped_UnregisterWait(PyObject *self, PyObject *args) +{ + HANDLE WaitHandle; + BOOL ret; + + if (!PyArg_ParseTuple(args, F_HANDLE, &WaitHandle)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = UnregisterWait(WaitHandle); + Py_END_ALLOW_THREADS + + if (!ret) + return SetFromWindowsErr(0); + Py_RETURN_NONE; +} + +PyDoc_STRVAR( + UnregisterWaitEx_doc, + "UnregisterWaitEx(WaitHandle, Event) -> None\n\n" + "Unregister wait handle.\n"); + +static PyObject * +overlapped_UnregisterWaitEx(PyObject *self, PyObject *args) +{ + HANDLE WaitHandle, Event; + BOOL ret; + + if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &WaitHandle, &Event)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = UnregisterWaitEx(WaitHandle, Event); + Py_END_ALLOW_THREADS + + if (!ret) + return SetFromWindowsErr(0); + Py_RETURN_NONE; +} + +/* + * Event functions -- currently only used by tests + */ + +PyDoc_STRVAR( + CreateEvent_doc, + "CreateEvent(EventAttributes, ManualReset, InitialState, Name)" + " -> Handle\n\n" + "Create an event. EventAttributes must be None.\n"); + +static PyObject * +overlapped_CreateEvent(PyObject *self, PyObject *args) +{ + PyObject *EventAttributes; + BOOL ManualReset; + BOOL InitialState; + Py_UNICODE *Name; + HANDLE Event; + + if (!PyArg_ParseTuple(args, "O" F_BOOL F_BOOL "Z", + &EventAttributes, &ManualReset, + &InitialState, &Name)) + return NULL; + + if (EventAttributes != Py_None) { + PyErr_SetString(PyExc_ValueError, "EventAttributes must be None"); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + Event = CreateEventW(NULL, ManualReset, InitialState, Name); + Py_END_ALLOW_THREADS + + if (Event == NULL) + return SetFromWindowsErr(0); + return Py_BuildValue(F_HANDLE, Event); +} + +PyDoc_STRVAR( + SetEvent_doc, + "SetEvent(Handle) -> None\n\n" + "Set event.\n"); + +static PyObject * +overlapped_SetEvent(PyObject *self, PyObject *args) +{ + HANDLE Handle; + BOOL ret; + + if (!PyArg_ParseTuple(args, F_HANDLE, &Handle)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = SetEvent(Handle); + Py_END_ALLOW_THREADS + + if (!ret) + return SetFromWindowsErr(0); + Py_RETURN_NONE; +} + +PyDoc_STRVAR( + ResetEvent_doc, + "ResetEvent(Handle) -> None\n\n" + "Reset event.\n"); + +static PyObject * +overlapped_ResetEvent(PyObject *self, PyObject *args) +{ + HANDLE Handle; + BOOL ret; + + if (!PyArg_ParseTuple(args, F_HANDLE, &Handle)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = ResetEvent(Handle); + Py_END_ALLOW_THREADS + + if (!ret) + return SetFromWindowsErr(0); + Py_RETURN_NONE; +} + +/* + * Bind socket handle to local port without doing slow getaddrinfo() + */ + +PyDoc_STRVAR( + BindLocal_doc, + "BindLocal(handle, family) -> None\n\n" + "Bind a socket handle to an arbitrary local port.\n" + "family should AF_INET or AF_INET6.\n"); + +static PyObject * +overlapped_BindLocal(PyObject *self, PyObject *args) +{ + SOCKET Socket; + int Family; + BOOL ret; + + if (!PyArg_ParseTuple(args, F_HANDLE "i", &Socket, &Family)) + return NULL; + + if (Family == AF_INET) { + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = 0; + addr.sin_addr.S_un.S_addr = INADDR_ANY; + ret = bind(Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; + } else if (Family == AF_INET6) { + struct sockaddr_in6 addr; + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + addr.sin6_port = 0; + addr.sin6_addr = in6addr_any; + ret = bind(Socket, (SOCKADDR*)&addr, sizeof(addr)) != SOCKET_ERROR; + } else { + PyErr_SetString(PyExc_ValueError, "expected tuple of length 2 or 4"); + return NULL; + } + + if (!ret) + return SetFromWindowsErr(WSAGetLastError()); + Py_RETURN_NONE; +} + +/* + * Windows equivalent of os.strerror() -- compare _ctypes/callproc.c + */ + +PyDoc_STRVAR( + FormatMessage_doc, + "FormatMessage(error_code) -> error_message\n\n" + "Return error message for an error code."); + +static PyObject * +overlapped_FormatMessage(PyObject *ignore, PyObject *args) +{ + DWORD code, n; + WCHAR *lpMsgBuf; + PyObject *res; + + if (!PyArg_ParseTuple(args, F_DWORD, &code)) + return NULL; + + n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &lpMsgBuf, + 0, + NULL); + if (n) { + while (iswspace(lpMsgBuf[n-1])) + --n; + lpMsgBuf[n] = L'\0'; + res = Py_BuildValue("u", lpMsgBuf); + } else { + res = PyUnicode_FromFormat("unknown error code %u", code); + } + LocalFree(lpMsgBuf); + return res; +} + + +/* + * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE + */ + +static void +mark_as_completed(OVERLAPPED *ov) +{ + ov->Internal = 0; + if (ov->hEvent != NULL) + SetEvent(ov->hEvent); +} + +/* + * A Python object wrapping an OVERLAPPED structure and other useful data + * for overlapped I/O + */ + +PyDoc_STRVAR( + Overlapped_doc, + "Overlapped object"); + +static PyObject * +Overlapped_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + OverlappedObject *self; + HANDLE event = INVALID_HANDLE_VALUE; + static char *kwlist[] = {"event", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|" F_HANDLE, kwlist, &event)) + return NULL; + + if (event == INVALID_HANDLE_VALUE) { + event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (event == NULL) + return SetFromWindowsErr(0); + } + + self = PyObject_New(OverlappedObject, type); + if (self == NULL) { + if (event != NULL) + CloseHandle(event); + return NULL; + } + + self->handle = NULL; + self->error = 0; + self->type = TYPE_NONE; + self->allocated_buffer = NULL; + memset(&self->overlapped, 0, sizeof(OVERLAPPED)); + memset(&self->user_buffer, 0, sizeof(Py_buffer)); + if (event) + self->overlapped.hEvent = event; + return (PyObject *)self; +} + + +/* Note (bpo-32710): OverlappedType.tp_clear is not defined to not release + buffers while overlapped are still running, to prevent a crash. */ +static int +Overlapped_clear(OverlappedObject *self) +{ + switch (self->type) { + case TYPE_READ: + case TYPE_ACCEPT: { + Py_CLEAR(self->allocated_buffer); + break; + } + case TYPE_READ_FROM: { + // An initial call to WSARecvFrom will only allocate the buffer. + // The result tuple of (message, address) is only + // allocated _after_ a message has been received. + if(self->read_from.result) { + // We've received a message, free the result tuple. + Py_CLEAR(self->read_from.result); + } + if(self->read_from.allocated_buffer) { + Py_CLEAR(self->read_from.allocated_buffer); + } + break; + } + case TYPE_WRITE: + case TYPE_WRITE_TO: + case TYPE_READINTO: { + if (self->user_buffer.obj) { + PyBuffer_Release(&self->user_buffer); + } + break; + } + } + self->type = TYPE_NOT_STARTED; + return 0; +} + +static void +Overlapped_dealloc(OverlappedObject *self) +{ + DWORD bytes; + DWORD olderr = GetLastError(); + BOOL wait = FALSE; + BOOL ret; + + if (!HasOverlappedIoCompleted(&self->overlapped) && + self->type != TYPE_NOT_STARTED) + { + if (Py_CancelIoEx && Py_CancelIoEx(self->handle, &self->overlapped)) + wait = TRUE; + + Py_BEGIN_ALLOW_THREADS + ret = GetOverlappedResult(self->handle, &self->overlapped, + &bytes, wait); + Py_END_ALLOW_THREADS + + switch (ret ? ERROR_SUCCESS : GetLastError()) { + case ERROR_SUCCESS: + case ERROR_NOT_FOUND: + case ERROR_OPERATION_ABORTED: + break; + default: + PyErr_Format( + PyExc_RuntimeError, + "%R still has pending operation at " + "deallocation, the process may crash", self); + PyErr_WriteUnraisable(NULL); + } + } + + if (self->overlapped.hEvent != NULL) { + CloseHandle(self->overlapped.hEvent); + } + + Overlapped_clear(self); + PyObject_Del(self); + SetLastError(olderr); +} + - self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); - switch (err) { - case ERROR_SUCCESS: - case ERROR_IO_PENDING: - Py_RETURN_NONE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); - } -} - -PyDoc_STRVAR( - Overlapped_DisconnectEx_doc, - "DisconnectEx(handle, flags) -> Overlapped[None]\n\n" - "Start overlapped connect. client_handle should be unbound."); +/* Convert IPv4 sockaddr to a Python str. */ static PyObject * -Overlapped_DisconnectEx(OverlappedObject *self, PyObject *args) +make_ipv4_addr(const struct sockaddr_in *addr) { - SOCKET Socket; - DWORD flags; - BOOL ret; - DWORD err; - - if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, &Socket, &flags)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - self->type = TYPE_DISCONNECT; - self->handle = (HANDLE)Socket; - - Py_BEGIN_ALLOW_THREADS - ret = Py_DisconnectEx(Socket, &self->overlapped, flags, 0); - Py_END_ALLOW_THREADS - - self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); - switch (err) { - case ERROR_SUCCESS: - case ERROR_IO_PENDING: - Py_RETURN_NONE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); - } + char buf[INET_ADDRSTRLEN]; + if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyUnicode_FromString(buf); } -PyDoc_STRVAR( - Overlapped_TransmitFile_doc, - "TransmitFile(socket, file, offset, offset_high, " - "count_to_write, count_per_send, flags) " - "-> Overlapped[None]\n\n" - "Transmit file data over a connected socket."); +/* Convert IPv6 sockaddr to a Python str. */ static PyObject * -Overlapped_TransmitFile(OverlappedObject *self, PyObject *args) +make_ipv6_addr(const struct sockaddr_in6 *addr) { - SOCKET Socket; - HANDLE File; - DWORD offset; - DWORD offset_high; - DWORD count_to_write; - DWORD count_per_send; - DWORD flags; - BOOL ret; - DWORD err; - - if (!PyArg_ParseTuple(args, - F_HANDLE F_HANDLE F_DWORD F_DWORD - F_DWORD F_DWORD F_DWORD, - &Socket, &File, &offset, &offset_high, - &count_to_write, &count_per_send, - &flags)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - self->type = TYPE_TRANSMIT_FILE; - self->handle = (HANDLE)Socket; - self->overlapped.Offset = offset; - self->overlapped.OffsetHigh = offset_high; - - Py_BEGIN_ALLOW_THREADS - ret = Py_TransmitFile(Socket, File, count_to_write, count_per_send, - &self->overlapped, - NULL, flags); - Py_END_ALLOW_THREADS - - self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); - switch (err) { - case ERROR_SUCCESS: - case ERROR_IO_PENDING: - Py_RETURN_NONE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); - } + char buf[INET6_ADDRSTRLEN]; + if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyUnicode_FromString(buf); } -PyDoc_STRVAR( - Overlapped_ConnectNamedPipe_doc, - "ConnectNamedPipe(handle) -> Overlapped[None]\n\n" - "Start overlapped wait for a client to connect."); - -static PyObject * -Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args) +static PyObject* +unparse_address(LPSOCKADDR Address, DWORD Length) { - HANDLE Pipe; - BOOL ret; - DWORD err; - - if (!PyArg_ParseTuple(args, F_HANDLE, &Pipe)) - return NULL; - - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); - return NULL; - } - - self->type = TYPE_CONNECT_NAMED_PIPE; - self->handle = Pipe; - - Py_BEGIN_ALLOW_THREADS - ret = ConnectNamedPipe(Pipe, &self->overlapped); - Py_END_ALLOW_THREADS + /* The function is adopted from mocketmodule.c makesockaddr()*/ - self->error = err = ret ? ERROR_SUCCESS : GetLastError(); - switch (err) { - case ERROR_PIPE_CONNECTED: - mark_as_completed(&self->overlapped); - Py_RETURN_TRUE; - case ERROR_SUCCESS: - case ERROR_IO_PENDING: - Py_RETURN_FALSE; - default: - Overlapped_clear(self); - return SetFromWindowsErr(err); + switch(Address->sa_family) { + case AF_INET: { + const struct sockaddr_in *a = (const struct sockaddr_in *)Address; + PyObject *addrobj = make_ipv4_addr(a); + PyObject *ret = NULL; + if (addrobj) { + ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port)); + Py_DECREF(addrobj); + } + return ret; + } + case AF_INET6: { + const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)Address; + PyObject *addrobj = make_ipv6_addr(a); + PyObject *ret = NULL; + if (addrobj) { + ret = Py_BuildValue("OiII", + addrobj, + ntohs(a->sin6_port), + ntohl(a->sin6_flowinfo), + a->sin6_scope_id); + Py_DECREF(addrobj); + } + return ret; + } + default: { + PyErr_SetString(PyExc_ValueError, "recvfrom returned unsupported address family"); + return NULL; + } } } -PyDoc_STRVAR( - ConnectPipe_doc, - "ConnectPipe(addr) -> pipe_handle\n\n" - "Connect to the pipe for asynchronous I/O (overlapped)."); - -static PyObject * -overlapped_ConnectPipe(PyObject *self, PyObject *args) -{ - PyObject *AddressObj; - wchar_t *Address; - HANDLE PipeHandle; - - if (!PyArg_ParseTuple(args, "U", &AddressObj)) - return NULL; +PyDoc_STRVAR( + Overlapped_cancel_doc, + "cancel() -> None\n\n" + "Cancel overlapped operation"); + +static PyObject * +Overlapped_cancel(OverlappedObject *self, PyObject *Py_UNUSED(ignored)) +{ + BOOL ret = TRUE; + + if (self->type == TYPE_NOT_STARTED + || self->type == TYPE_WAIT_NAMED_PIPE_AND_CONNECT) + Py_RETURN_NONE; + + if (!HasOverlappedIoCompleted(&self->overlapped)) { + Py_BEGIN_ALLOW_THREADS + if (Py_CancelIoEx) + ret = Py_CancelIoEx(self->handle, &self->overlapped); + else + ret = CancelIo(self->handle); + Py_END_ALLOW_THREADS + } + + /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */ + if (!ret && GetLastError() != ERROR_NOT_FOUND) + return SetFromWindowsErr(0); + Py_RETURN_NONE; +} + +PyDoc_STRVAR( + Overlapped_getresult_doc, + "getresult(wait=False) -> result\n\n" + "Retrieve result of operation. If wait is true then it blocks\n" + "until the operation is finished. If wait is false and the\n" + "operation is still pending then an error is raised."); + +static PyObject * +Overlapped_getresult(OverlappedObject *self, PyObject *args) +{ + BOOL wait = FALSE; + DWORD transferred = 0; + BOOL ret; + DWORD err; + PyObject *addr; + + if (!PyArg_ParseTuple(args, "|" F_BOOL, &wait)) + return NULL; + + if (self->type == TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation not yet attempted"); + return NULL; + } + + if (self->type == TYPE_NOT_STARTED) { + PyErr_SetString(PyExc_ValueError, "operation failed to start"); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + ret = GetOverlappedResult(self->handle, &self->overlapped, &transferred, + wait); + Py_END_ALLOW_THREADS + + self->error = err = ret ? ERROR_SUCCESS : GetLastError(); + switch (err) { + case ERROR_SUCCESS: + case ERROR_MORE_DATA: + break; + case ERROR_BROKEN_PIPE: + if (self->type == TYPE_READ || self->type == TYPE_READINTO) { + break; + } + else if (self->type == TYPE_READ_FROM && + (self->read_from.result != NULL || + self->read_from.allocated_buffer != NULL)) + { + break; + } + /* fall through */ + default: + return SetFromWindowsErr(err); + } + + switch (self->type) { + case TYPE_READ: + assert(PyBytes_CheckExact(self->allocated_buffer)); + if (transferred != PyBytes_GET_SIZE(self->allocated_buffer) && + _PyBytes_Resize(&self->allocated_buffer, transferred)) + return NULL; + + Py_INCREF(self->allocated_buffer); + return self->allocated_buffer; + case TYPE_READ_FROM: + assert(PyBytes_CheckExact(self->read_from.allocated_buffer)); - Address = PyUnicode_AsWideCharString(AddressObj, NULL); - if (Address == NULL) - return NULL; + if (transferred != PyBytes_GET_SIZE( + self->read_from.allocated_buffer) && + _PyBytes_Resize(&self->read_from.allocated_buffer, transferred)) + { + return NULL; + } - Py_BEGIN_ALLOW_THREADS - PipeHandle = CreateFileW(Address, - GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, NULL); - Py_END_ALLOW_THREADS + // unparse the address + addr = unparse_address((SOCKADDR*)&self->read_from.address, + self->read_from.address_length); - PyMem_Free(Address); - if (PipeHandle == INVALID_HANDLE_VALUE) - return SetFromWindowsErr(0); - return Py_BuildValue(F_HANDLE, PipeHandle); -} + if (addr == NULL) { + return NULL; + } -static PyObject* -Overlapped_getaddress(OverlappedObject *self) -{ - return PyLong_FromVoidPtr(&self->overlapped); -} + // The result is a two item tuple: (message, address) + self->read_from.result = PyTuple_New(2); + if (self->read_from.result == NULL) { + Py_CLEAR(addr); + return NULL; + } -static PyObject* -Overlapped_getpending(OverlappedObject *self) -{ - return PyBool_FromLong(!HasOverlappedIoCompleted(&self->overlapped) && - self->type != TYPE_NOT_STARTED); -} + // first item: message + Py_INCREF(self->read_from.allocated_buffer); + PyTuple_SET_ITEM(self->read_from.result, 0, + self->read_from.allocated_buffer); + // second item: address + PyTuple_SET_ITEM(self->read_from.result, 1, addr); -static int -Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) -{ - switch (self->type) { - case TYPE_READ: - case TYPE_ACCEPT: - Py_VISIT(self->allocated_buffer); - break; - case TYPE_WRITE: + Py_INCREF(self->read_from.result); + return self->read_from.result; + default: + return PyLong_FromUnsignedLong((unsigned long) transferred); + } +} + +static PyObject * +do_ReadFile(OverlappedObject *self, HANDLE handle, + char *bufstart, DWORD buflen) +{ + DWORD nread; + int ret; + DWORD err; + + Py_BEGIN_ALLOW_THREADS + ret = ReadFile(handle, bufstart, buflen, &nread, + &self->overlapped); + Py_END_ALLOW_THREADS + + self->error = err = ret ? ERROR_SUCCESS : GetLastError(); + switch (err) { + case ERROR_BROKEN_PIPE: + mark_as_completed(&self->overlapped); + return SetFromWindowsErr(err); + case ERROR_SUCCESS: + case ERROR_MORE_DATA: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + +PyDoc_STRVAR( + Overlapped_ReadFile_doc, + "ReadFile(handle, size) -> Overlapped[message]\n\n" + "Start overlapped read"); + +static PyObject * +Overlapped_ReadFile(OverlappedObject *self, PyObject *args) +{ + HANDLE handle; + DWORD size; + PyObject *buf; + + if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, &handle, &size)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + +#if SIZEOF_SIZE_T <= SIZEOF_LONG + size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX); +#endif + buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1)); + if (buf == NULL) + return NULL; + + self->type = TYPE_READ; + self->handle = handle; + self->allocated_buffer = buf; + + return do_ReadFile(self, handle, PyBytes_AS_STRING(buf), size); +} + +PyDoc_STRVAR( + Overlapped_ReadFileInto_doc, + "ReadFileInto(handle, buf) -> Overlapped[bytes_transferred]\n\n" + "Start overlapped receive"); + +static PyObject * +Overlapped_ReadFileInto(OverlappedObject *self, PyObject *args) +{ + HANDLE handle; + PyObject *bufobj; + + if (!PyArg_ParseTuple(args, F_HANDLE "O", &handle, &bufobj)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) + return NULL; + +#if SIZEOF_SIZE_T > SIZEOF_LONG + if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { + PyBuffer_Release(&self->user_buffer); + PyErr_SetString(PyExc_ValueError, "buffer too large"); + return NULL; + } +#endif + + self->type = TYPE_READINTO; + self->handle = handle; + + return do_ReadFile(self, handle, self->user_buffer.buf, + (DWORD)self->user_buffer.len); +} + +static PyObject * +do_WSARecv(OverlappedObject *self, HANDLE handle, + char *bufstart, DWORD buflen, DWORD flags) +{ + DWORD nread; + WSABUF wsabuf; + int ret; + DWORD err; + + wsabuf.buf = bufstart; + wsabuf.len = buflen; + + Py_BEGIN_ALLOW_THREADS + ret = WSARecv((SOCKET)handle, &wsabuf, 1, &nread, &flags, + &self->overlapped, NULL); + Py_END_ALLOW_THREADS + + self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); + switch (err) { + case ERROR_BROKEN_PIPE: + mark_as_completed(&self->overlapped); + return SetFromWindowsErr(err); + case ERROR_SUCCESS: + case ERROR_MORE_DATA: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + +PyDoc_STRVAR( + Overlapped_WSARecv_doc, + "RecvFile(handle, size, flags) -> Overlapped[message]\n\n" + "Start overlapped receive"); + +static PyObject * +Overlapped_WSARecv(OverlappedObject *self, PyObject *args) +{ + HANDLE handle; + DWORD size; + DWORD flags = 0; + PyObject *buf; + + if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD "|" F_DWORD, + &handle, &size, &flags)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + +#if SIZEOF_SIZE_T <= SIZEOF_LONG + size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX); +#endif + buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1)); + if (buf == NULL) + return NULL; + + self->type = TYPE_READ; + self->handle = handle; + self->allocated_buffer = buf; + + return do_WSARecv(self, handle, PyBytes_AS_STRING(buf), size, flags); +} + +PyDoc_STRVAR( + Overlapped_WSARecvInto_doc, + "WSARecvInto(handle, buf, flags) -> Overlapped[bytes_transferred]\n\n" + "Start overlapped receive"); + +static PyObject * +Overlapped_WSARecvInto(OverlappedObject *self, PyObject *args) +{ + HANDLE handle; + PyObject *bufobj; + DWORD flags; + + if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD, + &handle, &bufobj, &flags)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) + return NULL; + +#if SIZEOF_SIZE_T > SIZEOF_LONG + if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { + PyBuffer_Release(&self->user_buffer); + PyErr_SetString(PyExc_ValueError, "buffer too large"); + return NULL; + } +#endif + + self->type = TYPE_READINTO; + self->handle = handle; + + return do_WSARecv(self, handle, self->user_buffer.buf, + (DWORD)self->user_buffer.len, flags); +} + +PyDoc_STRVAR( + Overlapped_WriteFile_doc, + "WriteFile(handle, buf) -> Overlapped[bytes_transferred]\n\n" + "Start overlapped write"); + +static PyObject * +Overlapped_WriteFile(OverlappedObject *self, PyObject *args) +{ + HANDLE handle; + PyObject *bufobj; + DWORD written; + BOOL ret; + DWORD err; + + if (!PyArg_ParseTuple(args, F_HANDLE "O", &handle, &bufobj)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) + return NULL; + +#if SIZEOF_SIZE_T > SIZEOF_LONG + if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { + PyBuffer_Release(&self->user_buffer); + PyErr_SetString(PyExc_ValueError, "buffer too large"); + return NULL; + } +#endif + + self->type = TYPE_WRITE; + self->handle = handle; + + Py_BEGIN_ALLOW_THREADS + ret = WriteFile(handle, self->user_buffer.buf, + (DWORD)self->user_buffer.len, + &written, &self->overlapped); + Py_END_ALLOW_THREADS + + self->error = err = ret ? ERROR_SUCCESS : GetLastError(); + switch (err) { + case ERROR_SUCCESS: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + +PyDoc_STRVAR( + Overlapped_WSASend_doc, + "WSASend(handle, buf, flags) -> Overlapped[bytes_transferred]\n\n" + "Start overlapped send"); + +static PyObject * +Overlapped_WSASend(OverlappedObject *self, PyObject *args) +{ + HANDLE handle; + PyObject *bufobj; + DWORD flags; + DWORD written; + WSABUF wsabuf; + int ret; + DWORD err; + + if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD, + &handle, &bufobj, &flags)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) + return NULL; + +#if SIZEOF_SIZE_T > SIZEOF_LONG + if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { + PyBuffer_Release(&self->user_buffer); + PyErr_SetString(PyExc_ValueError, "buffer too large"); + return NULL; + } +#endif + + self->type = TYPE_WRITE; + self->handle = handle; + wsabuf.len = (DWORD)self->user_buffer.len; + wsabuf.buf = self->user_buffer.buf; + + Py_BEGIN_ALLOW_THREADS + ret = WSASend((SOCKET)handle, &wsabuf, 1, &written, flags, + &self->overlapped, NULL); + Py_END_ALLOW_THREADS + + self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); + switch (err) { + case ERROR_SUCCESS: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + +PyDoc_STRVAR( + Overlapped_AcceptEx_doc, + "AcceptEx(listen_handle, accept_handle) -> Overlapped[address_as_bytes]\n\n" + "Start overlapped wait for client to connect"); + +static PyObject * +Overlapped_AcceptEx(OverlappedObject *self, PyObject *args) +{ + SOCKET ListenSocket; + SOCKET AcceptSocket; + DWORD BytesReceived; + DWORD size; + PyObject *buf; + BOOL ret; + DWORD err; + + if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, + &ListenSocket, &AcceptSocket)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + size = sizeof(struct sockaddr_in6) + 16; + buf = PyBytes_FromStringAndSize(NULL, size*2); + if (!buf) + return NULL; + + self->type = TYPE_ACCEPT; + self->handle = (HANDLE)ListenSocket; + self->allocated_buffer = buf; + + Py_BEGIN_ALLOW_THREADS + ret = Py_AcceptEx(ListenSocket, AcceptSocket, PyBytes_AS_STRING(buf), + 0, size, size, &BytesReceived, &self->overlapped); + Py_END_ALLOW_THREADS + + self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); + switch (err) { + case ERROR_SUCCESS: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + + +static int +parse_address(PyObject *obj, SOCKADDR *Address, int Length) +{ + Py_UNICODE *Host; + unsigned short Port; + unsigned long FlowInfo; + unsigned long ScopeId; + + memset(Address, 0, Length); + + if (PyArg_ParseTuple(obj, "uH", &Host, &Port)) + { + Address->sa_family = AF_INET; + if (WSAStringToAddressW(Host, AF_INET, NULL, Address, &Length) < 0) { + SetFromWindowsErr(WSAGetLastError()); + return -1; + } + ((SOCKADDR_IN*)Address)->sin_port = htons(Port); + return Length; + } + else if (PyArg_ParseTuple(obj, + "uHkk;ConnectEx(): illegal address_as_bytes " + "argument", &Host, &Port, &FlowInfo, &ScopeId)) + { + PyErr_Clear(); + Address->sa_family = AF_INET6; + if (WSAStringToAddressW(Host, AF_INET6, NULL, Address, &Length) < 0) { + SetFromWindowsErr(WSAGetLastError()); + return -1; + } + ((SOCKADDR_IN6*)Address)->sin6_port = htons(Port); + ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo; + ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId; + return Length; + } + + return -1; +} + +PyDoc_STRVAR( + Overlapped_ConnectEx_doc, + "ConnectEx(client_handle, address_as_bytes) -> Overlapped[None]\n\n" + "Start overlapped connect. client_handle should be unbound."); + +static PyObject * +Overlapped_ConnectEx(OverlappedObject *self, PyObject *args) +{ + SOCKET ConnectSocket; + PyObject *AddressObj; + char AddressBuf[sizeof(struct sockaddr_in6)]; + SOCKADDR *Address = (SOCKADDR*)AddressBuf; + int Length; + BOOL ret; + DWORD err; + + if (!PyArg_ParseTuple(args, F_HANDLE "O!:ConnectEx", + &ConnectSocket, &PyTuple_Type, &AddressObj)) + { + return NULL; + } + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + Length = sizeof(AddressBuf); + Length = parse_address(AddressObj, Address, Length); + if (Length < 0) + return NULL; + + self->type = TYPE_CONNECT; + self->handle = (HANDLE)ConnectSocket; + + Py_BEGIN_ALLOW_THREADS + ret = Py_ConnectEx(ConnectSocket, Address, Length, + NULL, 0, NULL, &self->overlapped); + Py_END_ALLOW_THREADS + + self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); + switch (err) { + case ERROR_SUCCESS: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + +PyDoc_STRVAR( + Overlapped_DisconnectEx_doc, + "DisconnectEx(handle, flags) -> Overlapped[None]\n\n" + "Start overlapped connect. client_handle should be unbound."); + +static PyObject * +Overlapped_DisconnectEx(OverlappedObject *self, PyObject *args) +{ + SOCKET Socket; + DWORD flags; + BOOL ret; + DWORD err; + + if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD, &Socket, &flags)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + self->type = TYPE_DISCONNECT; + self->handle = (HANDLE)Socket; + + Py_BEGIN_ALLOW_THREADS + ret = Py_DisconnectEx(Socket, &self->overlapped, flags, 0); + Py_END_ALLOW_THREADS + + self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); + switch (err) { + case ERROR_SUCCESS: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + +PyDoc_STRVAR( + Overlapped_TransmitFile_doc, + "TransmitFile(socket, file, offset, offset_high, " + "count_to_write, count_per_send, flags) " + "-> Overlapped[None]\n\n" + "Transmit file data over a connected socket."); + +static PyObject * +Overlapped_TransmitFile(OverlappedObject *self, PyObject *args) +{ + SOCKET Socket; + HANDLE File; + DWORD offset; + DWORD offset_high; + DWORD count_to_write; + DWORD count_per_send; + DWORD flags; + BOOL ret; + DWORD err; + + if (!PyArg_ParseTuple(args, + F_HANDLE F_HANDLE F_DWORD F_DWORD + F_DWORD F_DWORD F_DWORD, + &Socket, &File, &offset, &offset_high, + &count_to_write, &count_per_send, + &flags)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + self->type = TYPE_TRANSMIT_FILE; + self->handle = (HANDLE)Socket; + self->overlapped.Offset = offset; + self->overlapped.OffsetHigh = offset_high; + + Py_BEGIN_ALLOW_THREADS + ret = Py_TransmitFile(Socket, File, count_to_write, count_per_send, + &self->overlapped, + NULL, flags); + Py_END_ALLOW_THREADS + + self->error = err = ret ? ERROR_SUCCESS : WSAGetLastError(); + switch (err) { + case ERROR_SUCCESS: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + +PyDoc_STRVAR( + Overlapped_ConnectNamedPipe_doc, + "ConnectNamedPipe(handle) -> Overlapped[None]\n\n" + "Start overlapped wait for a client to connect."); + +static PyObject * +Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args) +{ + HANDLE Pipe; + BOOL ret; + DWORD err; + + if (!PyArg_ParseTuple(args, F_HANDLE, &Pipe)) + return NULL; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + self->type = TYPE_CONNECT_NAMED_PIPE; + self->handle = Pipe; + + Py_BEGIN_ALLOW_THREADS + ret = ConnectNamedPipe(Pipe, &self->overlapped); + Py_END_ALLOW_THREADS + + self->error = err = ret ? ERROR_SUCCESS : GetLastError(); + switch (err) { + case ERROR_PIPE_CONNECTED: + mark_as_completed(&self->overlapped); + Py_RETURN_TRUE; + case ERROR_SUCCESS: + case ERROR_IO_PENDING: + Py_RETURN_FALSE; + default: + Overlapped_clear(self); + return SetFromWindowsErr(err); + } +} + +PyDoc_STRVAR( + ConnectPipe_doc, + "ConnectPipe(addr) -> pipe_handle\n\n" + "Connect to the pipe for asynchronous I/O (overlapped)."); + +static PyObject * +overlapped_ConnectPipe(PyObject *self, PyObject *args) +{ + PyObject *AddressObj; + wchar_t *Address; + HANDLE PipeHandle; + + if (!PyArg_ParseTuple(args, "U", &AddressObj)) + return NULL; + + Address = PyUnicode_AsWideCharString(AddressObj, NULL); + if (Address == NULL) + return NULL; + + Py_BEGIN_ALLOW_THREADS + PipeHandle = CreateFileW(Address, + GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + Py_END_ALLOW_THREADS + + PyMem_Free(Address); + if (PipeHandle == INVALID_HANDLE_VALUE) + return SetFromWindowsErr(0); + return Py_BuildValue(F_HANDLE, PipeHandle); +} + +static PyObject* +Overlapped_getaddress(OverlappedObject *self) +{ + return PyLong_FromVoidPtr(&self->overlapped); +} + +static PyObject* +Overlapped_getpending(OverlappedObject *self) +{ + return PyBool_FromLong(!HasOverlappedIoCompleted(&self->overlapped) && + self->type != TYPE_NOT_STARTED); +} + +static int +Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) +{ + switch (self->type) { + case TYPE_READ: + case TYPE_ACCEPT: + Py_VISIT(self->allocated_buffer); + break; + case TYPE_WRITE: case TYPE_WRITE_TO: - case TYPE_READINTO: - if (self->user_buffer.obj) { - Py_VISIT(&self->user_buffer.obj); - } - break; + case TYPE_READINTO: + if (self->user_buffer.obj) { + Py_VISIT(&self->user_buffer.obj); + } + break; case TYPE_READ_FROM: if(self->read_from.result) { Py_VISIT(self->read_from.result); @@ -1509,12 +1509,12 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) if(self->read_from.allocated_buffer) { Py_VISIT(self->read_from.allocated_buffer); } - } - return 0; -} - + } + return 0; +} + // UDP functions - + PyDoc_STRVAR( WSAConnect_doc, "WSAConnect(client_handle, address_as_bytes) -> Overlapped[None]\n\n" @@ -1704,176 +1704,176 @@ Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *args) } -static PyMethodDef Overlapped_methods[] = { - {"getresult", (PyCFunction) Overlapped_getresult, - METH_VARARGS, Overlapped_getresult_doc}, - {"cancel", (PyCFunction) Overlapped_cancel, - METH_NOARGS, Overlapped_cancel_doc}, - {"ReadFile", (PyCFunction) Overlapped_ReadFile, - METH_VARARGS, Overlapped_ReadFile_doc}, - {"ReadFileInto", (PyCFunction) Overlapped_ReadFileInto, - METH_VARARGS, Overlapped_ReadFileInto_doc}, - {"WSARecv", (PyCFunction) Overlapped_WSARecv, - METH_VARARGS, Overlapped_WSARecv_doc}, - {"WSARecvInto", (PyCFunction) Overlapped_WSARecvInto, - METH_VARARGS, Overlapped_WSARecvInto_doc}, - {"WriteFile", (PyCFunction) Overlapped_WriteFile, - METH_VARARGS, Overlapped_WriteFile_doc}, - {"WSASend", (PyCFunction) Overlapped_WSASend, - METH_VARARGS, Overlapped_WSASend_doc}, - {"AcceptEx", (PyCFunction) Overlapped_AcceptEx, - METH_VARARGS, Overlapped_AcceptEx_doc}, - {"ConnectEx", (PyCFunction) Overlapped_ConnectEx, - METH_VARARGS, Overlapped_ConnectEx_doc}, - {"DisconnectEx", (PyCFunction) Overlapped_DisconnectEx, - METH_VARARGS, Overlapped_DisconnectEx_doc}, - {"TransmitFile", (PyCFunction) Overlapped_TransmitFile, - METH_VARARGS, Overlapped_TransmitFile_doc}, - {"ConnectNamedPipe", (PyCFunction) Overlapped_ConnectNamedPipe, - METH_VARARGS, Overlapped_ConnectNamedPipe_doc}, +static PyMethodDef Overlapped_methods[] = { + {"getresult", (PyCFunction) Overlapped_getresult, + METH_VARARGS, Overlapped_getresult_doc}, + {"cancel", (PyCFunction) Overlapped_cancel, + METH_NOARGS, Overlapped_cancel_doc}, + {"ReadFile", (PyCFunction) Overlapped_ReadFile, + METH_VARARGS, Overlapped_ReadFile_doc}, + {"ReadFileInto", (PyCFunction) Overlapped_ReadFileInto, + METH_VARARGS, Overlapped_ReadFileInto_doc}, + {"WSARecv", (PyCFunction) Overlapped_WSARecv, + METH_VARARGS, Overlapped_WSARecv_doc}, + {"WSARecvInto", (PyCFunction) Overlapped_WSARecvInto, + METH_VARARGS, Overlapped_WSARecvInto_doc}, + {"WriteFile", (PyCFunction) Overlapped_WriteFile, + METH_VARARGS, Overlapped_WriteFile_doc}, + {"WSASend", (PyCFunction) Overlapped_WSASend, + METH_VARARGS, Overlapped_WSASend_doc}, + {"AcceptEx", (PyCFunction) Overlapped_AcceptEx, + METH_VARARGS, Overlapped_AcceptEx_doc}, + {"ConnectEx", (PyCFunction) Overlapped_ConnectEx, + METH_VARARGS, Overlapped_ConnectEx_doc}, + {"DisconnectEx", (PyCFunction) Overlapped_DisconnectEx, + METH_VARARGS, Overlapped_DisconnectEx_doc}, + {"TransmitFile", (PyCFunction) Overlapped_TransmitFile, + METH_VARARGS, Overlapped_TransmitFile_doc}, + {"ConnectNamedPipe", (PyCFunction) Overlapped_ConnectNamedPipe, + METH_VARARGS, Overlapped_ConnectNamedPipe_doc}, {"WSARecvFrom", (PyCFunction) Overlapped_WSARecvFrom, METH_VARARGS, Overlapped_WSARecvFrom_doc }, {"WSASendTo", (PyCFunction) Overlapped_WSASendTo, METH_VARARGS, Overlapped_WSASendTo_doc }, - {NULL} -}; - -static PyMemberDef Overlapped_members[] = { - {"error", T_ULONG, - offsetof(OverlappedObject, error), - READONLY, "Error from last operation"}, - {"event", T_HANDLE, - offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent), - READONLY, "Overlapped event handle"}, - {NULL} -}; - -static PyGetSetDef Overlapped_getsets[] = { - {"address", (getter)Overlapped_getaddress, NULL, - "Address of overlapped structure"}, - {"pending", (getter)Overlapped_getpending, NULL, - "Whether the operation is pending"}, - {NULL}, -}; - -PyTypeObject OverlappedType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_overlapped.Overlapped", - /* tp_basicsize */ sizeof(OverlappedObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor) Overlapped_dealloc, + {NULL} +}; + +static PyMemberDef Overlapped_members[] = { + {"error", T_ULONG, + offsetof(OverlappedObject, error), + READONLY, "Error from last operation"}, + {"event", T_HANDLE, + offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent), + READONLY, "Overlapped event handle"}, + {NULL} +}; + +static PyGetSetDef Overlapped_getsets[] = { + {"address", (getter)Overlapped_getaddress, NULL, + "Address of overlapped structure"}, + {"pending", (getter)Overlapped_getpending, NULL, + "Whether the operation is pending"}, + {NULL}, +}; + +PyTypeObject OverlappedType = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_overlapped.Overlapped", + /* tp_basicsize */ sizeof(OverlappedObject), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor) Overlapped_dealloc, /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, + /* tp_getattr */ 0, + /* tp_setattr */ 0, /* tp_as_async */ 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 */ Py_TPFLAGS_DEFAULT, - /* tp_doc */ "OVERLAPPED structure wrapper", - /* tp_traverse */ (traverseproc)Overlapped_traverse, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ Overlapped_methods, - /* tp_members */ Overlapped_members, - /* tp_getset */ Overlapped_getsets, - /* tp_base */ 0, - /* tp_dict */ 0, - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ Overlapped_new, -}; - -static PyMethodDef overlapped_functions[] = { - {"CreateIoCompletionPort", overlapped_CreateIoCompletionPort, - METH_VARARGS, CreateIoCompletionPort_doc}, - {"GetQueuedCompletionStatus", overlapped_GetQueuedCompletionStatus, - METH_VARARGS, GetQueuedCompletionStatus_doc}, - {"PostQueuedCompletionStatus", overlapped_PostQueuedCompletionStatus, - METH_VARARGS, PostQueuedCompletionStatus_doc}, - {"FormatMessage", overlapped_FormatMessage, - METH_VARARGS, FormatMessage_doc}, - {"BindLocal", overlapped_BindLocal, - METH_VARARGS, BindLocal_doc}, - {"RegisterWaitWithQueue", overlapped_RegisterWaitWithQueue, - METH_VARARGS, RegisterWaitWithQueue_doc}, - {"UnregisterWait", overlapped_UnregisterWait, - METH_VARARGS, UnregisterWait_doc}, - {"UnregisterWaitEx", overlapped_UnregisterWaitEx, - METH_VARARGS, UnregisterWaitEx_doc}, - {"CreateEvent", overlapped_CreateEvent, - METH_VARARGS, CreateEvent_doc}, - {"SetEvent", overlapped_SetEvent, - METH_VARARGS, SetEvent_doc}, - {"ResetEvent", overlapped_ResetEvent, - METH_VARARGS, ResetEvent_doc}, + /* 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 */ Py_TPFLAGS_DEFAULT, + /* tp_doc */ "OVERLAPPED structure wrapper", + /* tp_traverse */ (traverseproc)Overlapped_traverse, + /* tp_clear */ 0, + /* tp_richcompare */ 0, + /* tp_weaklistoffset */ 0, + /* tp_iter */ 0, + /* tp_iternext */ 0, + /* tp_methods */ Overlapped_methods, + /* tp_members */ Overlapped_members, + /* tp_getset */ Overlapped_getsets, + /* tp_base */ 0, + /* tp_dict */ 0, + /* tp_descr_get */ 0, + /* tp_descr_set */ 0, + /* tp_dictoffset */ 0, + /* tp_init */ 0, + /* tp_alloc */ 0, + /* tp_new */ Overlapped_new, +}; + +static PyMethodDef overlapped_functions[] = { + {"CreateIoCompletionPort", overlapped_CreateIoCompletionPort, + METH_VARARGS, CreateIoCompletionPort_doc}, + {"GetQueuedCompletionStatus", overlapped_GetQueuedCompletionStatus, + METH_VARARGS, GetQueuedCompletionStatus_doc}, + {"PostQueuedCompletionStatus", overlapped_PostQueuedCompletionStatus, + METH_VARARGS, PostQueuedCompletionStatus_doc}, + {"FormatMessage", overlapped_FormatMessage, + METH_VARARGS, FormatMessage_doc}, + {"BindLocal", overlapped_BindLocal, + METH_VARARGS, BindLocal_doc}, + {"RegisterWaitWithQueue", overlapped_RegisterWaitWithQueue, + METH_VARARGS, RegisterWaitWithQueue_doc}, + {"UnregisterWait", overlapped_UnregisterWait, + METH_VARARGS, UnregisterWait_doc}, + {"UnregisterWaitEx", overlapped_UnregisterWaitEx, + METH_VARARGS, UnregisterWaitEx_doc}, + {"CreateEvent", overlapped_CreateEvent, + METH_VARARGS, CreateEvent_doc}, + {"SetEvent", overlapped_SetEvent, + METH_VARARGS, SetEvent_doc}, + {"ResetEvent", overlapped_ResetEvent, + METH_VARARGS, ResetEvent_doc}, {"ConnectPipe", overlapped_ConnectPipe, - METH_VARARGS, ConnectPipe_doc}, + METH_VARARGS, ConnectPipe_doc}, {"WSAConnect", overlapped_WSAConnect, METH_VARARGS, WSAConnect_doc}, - {NULL} -}; - -static struct PyModuleDef overlapped_module = { - PyModuleDef_HEAD_INIT, - "_overlapped", - NULL, - -1, - overlapped_functions, - NULL, - NULL, - NULL, - NULL -}; - -#define WINAPI_CONSTANT(fmt, con) \ - PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) - -PyMODINIT_FUNC -PyInit__overlapped(void) -{ - PyObject *m, *d; - - /* Ensure WSAStartup() called before initializing function pointers */ - m = PyImport_ImportModule("_socket"); - if (!m) - return NULL; - Py_DECREF(m); - - if (initialize_function_pointers() < 0) - return NULL; - - m = PyModule_Create(&overlapped_module); + {NULL} +}; + +static struct PyModuleDef overlapped_module = { + PyModuleDef_HEAD_INIT, + "_overlapped", + NULL, + -1, + overlapped_functions, + NULL, + NULL, + NULL, + NULL +}; + +#define WINAPI_CONSTANT(fmt, con) \ + PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) + +PyMODINIT_FUNC +PyInit__overlapped(void) +{ + PyObject *m, *d; + + /* Ensure WSAStartup() called before initializing function pointers */ + m = PyImport_ImportModule("_socket"); + if (!m) + return NULL; + Py_DECREF(m); + + if (initialize_function_pointers() < 0) + return NULL; + + m = PyModule_Create(&overlapped_module); if (PyModule_AddType(m, &OverlappedType) < 0) { - return NULL; + return NULL; } - - d = PyModule_GetDict(m); - - WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); - WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); - WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED); - WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT); - WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY); - WINAPI_CONSTANT(F_DWORD, INFINITE); - WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE); - WINAPI_CONSTANT(F_HANDLE, NULL); - WINAPI_CONSTANT(F_DWORD, SO_UPDATE_ACCEPT_CONTEXT); - WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT); - WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET); - - return m; -} + + d = PyModule_GetDict(m); + + WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); + WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); + WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED); + WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT); + WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY); + WINAPI_CONSTANT(F_DWORD, INFINITE); + WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE); + WINAPI_CONSTANT(F_HANDLE, NULL); + WINAPI_CONSTANT(F_DWORD, SO_UPDATE_ACCEPT_CONTEXT); + WINAPI_CONSTANT(F_DWORD, SO_UPDATE_CONNECT_CONTEXT); + WINAPI_CONSTANT(F_DWORD, TF_REUSE_SOCKET); + + return m; +} diff --git a/contrib/tools/python3/src/Modules/parsermodule.c b/contrib/tools/python3/src/Modules/parsermodule.c index 24b0ffbe36a..ea94ceb6180 100644 --- a/contrib/tools/python3/src/Modules/parsermodule.c +++ b/contrib/tools/python3/src/Modules/parsermodule.c @@ -1,665 +1,665 @@ -/* parsermodule.c - * - * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic - * Institute and State University, Blacksburg, Virginia, USA. - * Portions copyright 1991-1995 by Stichting Mathematisch Centrum, - * Amsterdam, The Netherlands. Copying is permitted under the terms - * associated with the main Python distribution, with the additional - * restriction that this additional notice be included and maintained - * on all distributed copies. - * - * This module serves to replace the original parser module written - * by Guido. The functionality is not matched precisely, but the - * original may be implemented on top of this. This is desirable - * since the source of the text to be parsed is now divorced from - * this interface. - * - * Unlike the prior interface, the ability to give a parse tree - * produced by Python code as a tuple to the compiler is enabled by - * this module. See the documentation for more details. - * - * I've added some annotations that help with the lint code-checking - * program, but they're not complete by a long shot. The real errors - * that lint detects are gone, but there are still warnings with - * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations - * look like "NOTE(...)". - * - */ - -#include "Python.h" /* general Python API */ -#include "Python-ast.h" /* mod_ty */ +/* parsermodule.c + * + * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic + * Institute and State University, Blacksburg, Virginia, USA. + * Portions copyright 1991-1995 by Stichting Mathematisch Centrum, + * Amsterdam, The Netherlands. Copying is permitted under the terms + * associated with the main Python distribution, with the additional + * restriction that this additional notice be included and maintained + * on all distributed copies. + * + * This module serves to replace the original parser module written + * by Guido. The functionality is not matched precisely, but the + * original may be implemented on top of this. This is desirable + * since the source of the text to be parsed is now divorced from + * this interface. + * + * Unlike the prior interface, the ability to give a parse tree + * produced by Python code as a tuple to the compiler is enabled by + * this module. See the documentation for more details. + * + * I've added some annotations that help with the lint code-checking + * program, but they're not complete by a long shot. The real errors + * that lint detects are gone, but there are still warnings with + * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations + * look like "NOTE(...)". + * + */ + +#include "Python.h" /* general Python API */ +#include "Python-ast.h" /* mod_ty */ #undef Yield /* undefine macro conflicting with */ #include "ast.h" -#include "graminit.h" /* symbols defined in the grammar */ -#include "node.h" /* internal parser structure */ -#include "errcode.h" /* error codes for PyNode_*() */ -#include "token.h" /* token definitions */ +#include "graminit.h" /* symbols defined in the grammar */ +#include "node.h" /* internal parser structure */ +#include "errcode.h" /* error codes for PyNode_*() */ +#include "token.h" /* token definitions */ /* ISTERMINAL() / ISNONTERMINAL() */ -#include "grammar.h" -#include "parsetok.h" - -extern grammar _PyParser_Grammar; /* From graminit.c */ - -#ifdef lint -#include -#else -#define NOTE(x) -#endif - -/* String constants used to initialize module attributes. - * - */ -static const char parser_copyright_string[] = -"Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\ -University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\ -Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\ -Centrum, Amsterdam, The Netherlands."; - - -PyDoc_STRVAR(parser_doc_string, -"This is an interface to Python's internal parser."); - -static const char parser_version_string[] = "0.5"; - - -typedef PyObject* (*SeqMaker) (Py_ssize_t length); -typedef int (*SeqInserter) (PyObject* sequence, - Py_ssize_t index, - PyObject* element); - -/* The function below is copyrighted by Stichting Mathematisch Centrum. The - * original copyright statement is included below, and continues to apply - * in full to the function immediately following. All other material is - * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic - * Institute and State University. Changes were made to comply with the - * new naming conventions. Added arguments to provide support for creating - * lists as well as tuples, and optionally including the line numbers. - */ - - -static PyObject* -node2tuple(node *n, /* node to convert */ - SeqMaker mkseq, /* create sequence */ - SeqInserter addelem, /* func. to add elem. in seq. */ - int lineno, /* include line numbers? */ - int col_offset) /* include column offsets? */ -{ - PyObject *result = NULL, *w; - - if (n == NULL) { - Py_RETURN_NONE; - } - - if (ISNONTERMINAL(TYPE(n))) { - int i; - - result = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl)); - if (result == NULL) - goto error; - - w = PyLong_FromLong(TYPE(n)); - if (w == NULL) - goto error; - (void) addelem(result, 0, w); - - for (i = 0; i < NCH(n); i++) { - w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset); - if (w == NULL) - goto error; - (void) addelem(result, i+1, w); - } - - if (TYPE(n) == encoding_decl) { - w = PyUnicode_FromString(STR(n)); - if (w == NULL) - goto error; - (void) addelem(result, i+1, w); - } - } - else if (ISTERMINAL(TYPE(n))) { - result = mkseq(2 + lineno + col_offset); - if (result == NULL) - goto error; - - w = PyLong_FromLong(TYPE(n)); - if (w == NULL) - goto error; - (void) addelem(result, 0, w); - - w = PyUnicode_FromString(STR(n)); - if (w == NULL) - goto error; - (void) addelem(result, 1, w); - - if (lineno) { - w = PyLong_FromLong(n->n_lineno); - if (w == NULL) - goto error; - (void) addelem(result, 2, w); - } - - if (col_offset) { - w = PyLong_FromLong(n->n_col_offset); - if (w == NULL) - goto error; - (void) addelem(result, 2 + lineno, w); - } - } - else { - PyErr_SetString(PyExc_SystemError, - "unrecognized parse tree node type"); - return ((PyObject*) NULL); - } - return result; - -error: - Py_XDECREF(result); - return NULL; -} -/* - * End of material copyrighted by Stichting Mathematisch Centrum. - */ - - - -/* There are two types of intermediate objects we're interested in: - * 'eval' and 'exec' types. These constants can be used in the st_type - * field of the object type to identify which any given object represents. - * These should probably go in an external header to allow other extensions - * to use them, but then, we really should be using C++ too. ;-) - */ - -#define PyST_EXPR 1 -#define PyST_SUITE 2 - - -/* These are the internal objects and definitions required to implement the - * ST type. Most of the internal names are more reminiscent of the 'old' - * naming style, but the code uses the new naming convention. - */ - -static PyObject* -parser_error = 0; - - -typedef struct { - PyObject_HEAD /* standard object header */ - node* st_node; /* the node* returned by the parser */ - int st_type; /* EXPR or SUITE ? */ - PyCompilerFlags st_flags; /* Parser and compiler flags */ -} PyST_Object; - - -static void parser_free(PyST_Object *st); -static PyObject* parser_sizeof(PyST_Object *, void *); -static PyObject* parser_richcompare(PyObject *left, PyObject *right, int op); -static PyObject* parser_compilest(PyST_Object *, PyObject *, PyObject *); -static PyObject* parser_isexpr(PyST_Object *, PyObject *, PyObject *); -static PyObject* parser_issuite(PyST_Object *, PyObject *, PyObject *); -static PyObject* parser_st2list(PyST_Object *, PyObject *, PyObject *); -static PyObject* parser_st2tuple(PyST_Object *, PyObject *, PyObject *); - -#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS) - -static PyMethodDef parser_methods[] = { +#include "grammar.h" +#include "parsetok.h" + +extern grammar _PyParser_Grammar; /* From graminit.c */ + +#ifdef lint +#include +#else +#define NOTE(x) +#endif + +/* String constants used to initialize module attributes. + * + */ +static const char parser_copyright_string[] = +"Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\ +University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\ +Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\ +Centrum, Amsterdam, The Netherlands."; + + +PyDoc_STRVAR(parser_doc_string, +"This is an interface to Python's internal parser."); + +static const char parser_version_string[] = "0.5"; + + +typedef PyObject* (*SeqMaker) (Py_ssize_t length); +typedef int (*SeqInserter) (PyObject* sequence, + Py_ssize_t index, + PyObject* element); + +/* The function below is copyrighted by Stichting Mathematisch Centrum. The + * original copyright statement is included below, and continues to apply + * in full to the function immediately following. All other material is + * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic + * Institute and State University. Changes were made to comply with the + * new naming conventions. Added arguments to provide support for creating + * lists as well as tuples, and optionally including the line numbers. + */ + + +static PyObject* +node2tuple(node *n, /* node to convert */ + SeqMaker mkseq, /* create sequence */ + SeqInserter addelem, /* func. to add elem. in seq. */ + int lineno, /* include line numbers? */ + int col_offset) /* include column offsets? */ +{ + PyObject *result = NULL, *w; + + if (n == NULL) { + Py_RETURN_NONE; + } + + if (ISNONTERMINAL(TYPE(n))) { + int i; + + result = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl)); + if (result == NULL) + goto error; + + w = PyLong_FromLong(TYPE(n)); + if (w == NULL) + goto error; + (void) addelem(result, 0, w); + + for (i = 0; i < NCH(n); i++) { + w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset); + if (w == NULL) + goto error; + (void) addelem(result, i+1, w); + } + + if (TYPE(n) == encoding_decl) { + w = PyUnicode_FromString(STR(n)); + if (w == NULL) + goto error; + (void) addelem(result, i+1, w); + } + } + else if (ISTERMINAL(TYPE(n))) { + result = mkseq(2 + lineno + col_offset); + if (result == NULL) + goto error; + + w = PyLong_FromLong(TYPE(n)); + if (w == NULL) + goto error; + (void) addelem(result, 0, w); + + w = PyUnicode_FromString(STR(n)); + if (w == NULL) + goto error; + (void) addelem(result, 1, w); + + if (lineno) { + w = PyLong_FromLong(n->n_lineno); + if (w == NULL) + goto error; + (void) addelem(result, 2, w); + } + + if (col_offset) { + w = PyLong_FromLong(n->n_col_offset); + if (w == NULL) + goto error; + (void) addelem(result, 2 + lineno, w); + } + } + else { + PyErr_SetString(PyExc_SystemError, + "unrecognized parse tree node type"); + return ((PyObject*) NULL); + } + return result; + +error: + Py_XDECREF(result); + return NULL; +} +/* + * End of material copyrighted by Stichting Mathematisch Centrum. + */ + + + +/* There are two types of intermediate objects we're interested in: + * 'eval' and 'exec' types. These constants can be used in the st_type + * field of the object type to identify which any given object represents. + * These should probably go in an external header to allow other extensions + * to use them, but then, we really should be using C++ too. ;-) + */ + +#define PyST_EXPR 1 +#define PyST_SUITE 2 + + +/* These are the internal objects and definitions required to implement the + * ST type. Most of the internal names are more reminiscent of the 'old' + * naming style, but the code uses the new naming convention. + */ + +static PyObject* +parser_error = 0; + + +typedef struct { + PyObject_HEAD /* standard object header */ + node* st_node; /* the node* returned by the parser */ + int st_type; /* EXPR or SUITE ? */ + PyCompilerFlags st_flags; /* Parser and compiler flags */ +} PyST_Object; + + +static void parser_free(PyST_Object *st); +static PyObject* parser_sizeof(PyST_Object *, void *); +static PyObject* parser_richcompare(PyObject *left, PyObject *right, int op); +static PyObject* parser_compilest(PyST_Object *, PyObject *, PyObject *); +static PyObject* parser_isexpr(PyST_Object *, PyObject *, PyObject *); +static PyObject* parser_issuite(PyST_Object *, PyObject *, PyObject *); +static PyObject* parser_st2list(PyST_Object *, PyObject *, PyObject *); +static PyObject* parser_st2tuple(PyST_Object *, PyObject *, PyObject *); + +#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS) + +static PyMethodDef parser_methods[] = { {"compile", (PyCFunction)(void(*)(void))parser_compilest, PUBLIC_METHOD_TYPE, - PyDoc_STR("Compile this ST object into a code object.")}, + PyDoc_STR("Compile this ST object into a code object.")}, {"isexpr", (PyCFunction)(void(*)(void))parser_isexpr, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if this ST object was created from an expression.")}, + PyDoc_STR("Determines if this ST object was created from an expression.")}, {"issuite", (PyCFunction)(void(*)(void))parser_issuite, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if this ST object was created from a suite.")}, + PyDoc_STR("Determines if this ST object was created from a suite.")}, {"tolist", (PyCFunction)(void(*)(void))parser_st2list, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a list-tree representation of this ST.")}, + PyDoc_STR("Creates a list-tree representation of this ST.")}, {"totuple", (PyCFunction)(void(*)(void))parser_st2tuple, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a tuple-tree representation of this ST.")}, - {"__sizeof__", (PyCFunction)parser_sizeof, METH_NOARGS, - PyDoc_STR("Returns size in memory, in bytes.")}, - {NULL, NULL, 0, NULL} -}; - -static -PyTypeObject PyST_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "parser.st", /* tp_name */ - (int) sizeof(PyST_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)parser_free, /* tp_dealloc */ + PyDoc_STR("Creates a tuple-tree representation of this ST.")}, + {"__sizeof__", (PyCFunction)parser_sizeof, METH_NOARGS, + PyDoc_STR("Returns size in memory, in bytes.")}, + {NULL, NULL, 0, NULL} +}; + +static +PyTypeObject PyST_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "parser.st", /* tp_name */ + (int) sizeof(PyST_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)parser_free, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ 0, /* tp_as_async */ - 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 */ - - /* Functions to access object as input/output buffer */ - 0, /* tp_as_buffer */ - - Py_TPFLAGS_DEFAULT, /* tp_flags */ - - /* __doc__ */ - "Intermediate representation of a Python parse tree.", - 0, /* tp_traverse */ - 0, /* tp_clear */ - parser_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - parser_methods, /* tp_methods */ -}; /* PyST_Type */ - - -/* PyST_Type isn't subclassable, so just check ob_type */ + 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 */ + + /* Functions to access object as input/output buffer */ + 0, /* tp_as_buffer */ + + Py_TPFLAGS_DEFAULT, /* tp_flags */ + + /* __doc__ */ + "Intermediate representation of a Python parse tree.", + 0, /* tp_traverse */ + 0, /* tp_clear */ + parser_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + parser_methods, /* tp_methods */ +}; /* PyST_Type */ + + +/* PyST_Type isn't subclassable, so just check ob_type */ #define PyST_Object_Check(v) Py_IS_TYPE(v, &PyST_Type) - -static int -parser_compare_nodes(node *left, node *right) -{ - int j; - - if (TYPE(left) < TYPE(right)) - return (-1); - - if (TYPE(right) < TYPE(left)) - return (1); - - if (ISTERMINAL(TYPE(left))) - return (strcmp(STR(left), STR(right))); - - if (NCH(left) < NCH(right)) - return (-1); - - if (NCH(right) < NCH(left)) - return (1); - - for (j = 0; j < NCH(left); ++j) { - int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j)); - - if (v != 0) - return (v); - } - return (0); -} - -/* parser_richcompare(PyObject* left, PyObject* right, int op) - * - * Comparison function used by the Python operators ==, !=, <, >, <=, >= - * This really just wraps a call to parser_compare_nodes() with some easy - * checks and protection code. - * - */ - -static PyObject * -parser_richcompare(PyObject *left, PyObject *right, int op) -{ - int result; - - /* neither argument should be NULL, unless something's gone wrong */ - if (left == NULL || right == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - - /* both arguments should be instances of PyST_Object */ - if (!PyST_Object_Check(left) || !PyST_Object_Check(right)) { - Py_RETURN_NOTIMPLEMENTED; - } - - if (left == right) - /* if arguments are identical, they're equal */ - result = 0; - else - result = parser_compare_nodes(((PyST_Object *)left)->st_node, - ((PyST_Object *)right)->st_node); - - Py_RETURN_RICHCOMPARE(result, 0, op); -} - -/* parser_newstobject(node* st) - * - * Allocates a new Python object representing an ST. This is simply the - * 'wrapper' object that holds a node* and allows it to be passed around in - * Python code. - * - */ -static PyObject* -parser_newstobject(node *st, int type) -{ - PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type); - - if (o != 0) { - o->st_node = st; - o->st_type = type; + +static int +parser_compare_nodes(node *left, node *right) +{ + int j; + + if (TYPE(left) < TYPE(right)) + return (-1); + + if (TYPE(right) < TYPE(left)) + return (1); + + if (ISTERMINAL(TYPE(left))) + return (strcmp(STR(left), STR(right))); + + if (NCH(left) < NCH(right)) + return (-1); + + if (NCH(right) < NCH(left)) + return (1); + + for (j = 0; j < NCH(left); ++j) { + int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j)); + + if (v != 0) + return (v); + } + return (0); +} + +/* parser_richcompare(PyObject* left, PyObject* right, int op) + * + * Comparison function used by the Python operators ==, !=, <, >, <=, >= + * This really just wraps a call to parser_compare_nodes() with some easy + * checks and protection code. + * + */ + +static PyObject * +parser_richcompare(PyObject *left, PyObject *right, int op) +{ + int result; + + /* neither argument should be NULL, unless something's gone wrong */ + if (left == NULL || right == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + /* both arguments should be instances of PyST_Object */ + if (!PyST_Object_Check(left) || !PyST_Object_Check(right)) { + Py_RETURN_NOTIMPLEMENTED; + } + + if (left == right) + /* if arguments are identical, they're equal */ + result = 0; + else + result = parser_compare_nodes(((PyST_Object *)left)->st_node, + ((PyST_Object *)right)->st_node); + + Py_RETURN_RICHCOMPARE(result, 0, op); +} + +/* parser_newstobject(node* st) + * + * Allocates a new Python object representing an ST. This is simply the + * 'wrapper' object that holds a node* and allows it to be passed around in + * Python code. + * + */ +static PyObject* +parser_newstobject(node *st, int type) +{ + PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type); + + if (o != 0) { + o->st_node = st; + o->st_type = type; o->st_flags = _PyCompilerFlags_INIT; - } - else { - PyNode_Free(st); - } - return ((PyObject*)o); -} - - -/* void parser_free(PyST_Object* st) - * - * This is called by a del statement that reduces the reference count to 0. - * - */ -static void -parser_free(PyST_Object *st) -{ - PyNode_Free(st->st_node); - PyObject_Del(st); -} - -static PyObject * -parser_sizeof(PyST_Object *st, void *unused) -{ - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(st)) + _PyNode_SizeOf(st->st_node); - return PyLong_FromSsize_t(res); -} - - -/* parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw) - * - * This provides conversion from a node* to a tuple object that can be - * returned to the Python-level caller. The ST object is not modified. - * - */ -static PyObject* -parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw) -{ - int line_info = 0; - int col_info = 0; - PyObject *res = 0; - int ok; - - static char *keywords[] = {"st", "line_info", "col_info", NULL}; - - if (self == NULL || PyModule_Check(self)) { - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2tuple", keywords, - &PyST_Type, &self, &line_info, - &col_info); - } - else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:totuple", &keywords[1], - &line_info, &col_info); - if (ok != 0) { - /* - * Convert ST into a tuple representation. Use Guido's function, - * since it's known to work already. - */ - res = node2tuple(((PyST_Object*)self)->st_node, - PyTuple_New, PyTuple_SetItem, line_info, col_info); - } - return (res); -} - - -/* parser_st2list(PyObject* self, PyObject* args, PyObject* kw) - * - * This provides conversion from a node* to a list object that can be - * returned to the Python-level caller. The ST object is not modified. - * - */ -static PyObject* -parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw) -{ - int line_info = 0; - int col_info = 0; - PyObject *res = 0; - int ok; - - static char *keywords[] = {"st", "line_info", "col_info", NULL}; - - if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2list", keywords, - &PyST_Type, &self, &line_info, - &col_info); - else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:tolist", &keywords[1], - &line_info, &col_info); - if (ok) { - /* - * Convert ST into a tuple representation. Use Guido's function, - * since it's known to work already. - */ - res = node2tuple(self->st_node, - PyList_New, PyList_SetItem, line_info, col_info); - } - return (res); -} - - -/* parser_compilest(PyObject* self, PyObject* args) - * - * This function creates code objects from the parse tree represented by - * the passed-in data object. An optional file name is passed in as well. - * - */ -static PyObject* -parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) -{ - PyObject* res = NULL; - PyArena* arena = NULL; - mod_ty mod; - PyObject* filename = NULL; - int ok; - - static char *keywords[] = {"st", "filename", NULL}; - - if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O&:compilest", keywords, - &PyST_Type, &self, - PyUnicode_FSDecoder, &filename); - else - ok = PyArg_ParseTupleAndKeywords(args, kw, "|O&:compile", &keywords[1], - PyUnicode_FSDecoder, &filename); - if (!ok) - goto error; - - if (filename == NULL) { - filename = PyUnicode_FromString(""); - if (filename == NULL) - goto error; - } - - arena = PyArena_New(); - if (!arena) - goto error; - - mod = PyAST_FromNodeObject(self->st_node, &self->st_flags, - filename, arena); - if (!mod) - goto error; - - res = (PyObject *)PyAST_CompileObject(mod, filename, - &self->st_flags, -1, arena); -error: - Py_XDECREF(filename); - if (arena != NULL) - PyArena_Free(arena); - return res; -} - - -/* PyObject* parser_isexpr(PyObject* self, PyObject* args) - * PyObject* parser_issuite(PyObject* self, PyObject* args) - * - * Checks the passed-in ST object to determine if it is an expression or - * a statement suite, respectively. The return is a Python truth value. - * - */ -static PyObject* -parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw) -{ - PyObject* res = 0; - int ok; - - static char *keywords[] = {"st", NULL}; - - if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords, - &PyST_Type, &self); - else - ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]); - - if (ok) { - /* Check to see if the ST represents an expression or not. */ - res = (self->st_type == PyST_EXPR) ? Py_True : Py_False; - Py_INCREF(res); - } - return (res); -} - - -static PyObject* -parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw) -{ - PyObject* res = 0; - int ok; - - static char *keywords[] = {"st", NULL}; - - if (self == NULL || PyModule_Check(self)) - ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords, - &PyST_Type, &self); - else - ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]); - - if (ok) { - /* Check to see if the ST represents an expression or not. */ - res = (self->st_type == PyST_EXPR) ? Py_False : Py_True; - Py_INCREF(res); - } - return (res); -} - - -/* err_string(const char* message) - * - * Sets the error string for an exception of type ParserError. - * - */ -static void -err_string(const char *message) -{ - PyErr_SetString(parser_error, message); -} - - -/* PyObject* parser_do_parse(PyObject* args, int type) - * - * Internal function to actually execute the parse and return the result if - * successful or set an exception if not. - * - */ -static PyObject* -parser_do_parse(PyObject *args, PyObject *kw, const char *argspec, int type) -{ - char* string = 0; - PyObject* res = 0; - int flags = 0; - perrdetail err; - - static char *keywords[] = {"source", NULL}; - - if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) { - node* n = PyParser_ParseStringFlagsFilenameEx(string, NULL, - &_PyParser_Grammar, - (type == PyST_EXPR) - ? eval_input : file_input, - &err, &flags); - - if (n) { - res = parser_newstobject(n, type); + } + else { + PyNode_Free(st); + } + return ((PyObject*)o); +} + + +/* void parser_free(PyST_Object* st) + * + * This is called by a del statement that reduces the reference count to 0. + * + */ +static void +parser_free(PyST_Object *st) +{ + PyNode_Free(st->st_node); + PyObject_Del(st); +} + +static PyObject * +parser_sizeof(PyST_Object *st, void *unused) +{ + Py_ssize_t res; + + res = _PyObject_SIZE(Py_TYPE(st)) + _PyNode_SizeOf(st->st_node); + return PyLong_FromSsize_t(res); +} + + +/* parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw) + * + * This provides conversion from a node* to a tuple object that can be + * returned to the Python-level caller. The ST object is not modified. + * + */ +static PyObject* +parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw) +{ + int line_info = 0; + int col_info = 0; + PyObject *res = 0; + int ok; + + static char *keywords[] = {"st", "line_info", "col_info", NULL}; + + if (self == NULL || PyModule_Check(self)) { + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2tuple", keywords, + &PyST_Type, &self, &line_info, + &col_info); + } + else + ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:totuple", &keywords[1], + &line_info, &col_info); + if (ok != 0) { + /* + * Convert ST into a tuple representation. Use Guido's function, + * since it's known to work already. + */ + res = node2tuple(((PyST_Object*)self)->st_node, + PyTuple_New, PyTuple_SetItem, line_info, col_info); + } + return (res); +} + + +/* parser_st2list(PyObject* self, PyObject* args, PyObject* kw) + * + * This provides conversion from a node* to a list object that can be + * returned to the Python-level caller. The ST object is not modified. + * + */ +static PyObject* +parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw) +{ + int line_info = 0; + int col_info = 0; + PyObject *res = 0; + int ok; + + static char *keywords[] = {"st", "line_info", "col_info", NULL}; + + if (self == NULL || PyModule_Check(self)) + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2list", keywords, + &PyST_Type, &self, &line_info, + &col_info); + else + ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:tolist", &keywords[1], + &line_info, &col_info); + if (ok) { + /* + * Convert ST into a tuple representation. Use Guido's function, + * since it's known to work already. + */ + res = node2tuple(self->st_node, + PyList_New, PyList_SetItem, line_info, col_info); + } + return (res); +} + + +/* parser_compilest(PyObject* self, PyObject* args) + * + * This function creates code objects from the parse tree represented by + * the passed-in data object. An optional file name is passed in as well. + * + */ +static PyObject* +parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw) +{ + PyObject* res = NULL; + PyArena* arena = NULL; + mod_ty mod; + PyObject* filename = NULL; + int ok; + + static char *keywords[] = {"st", "filename", NULL}; + + if (self == NULL || PyModule_Check(self)) + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O&:compilest", keywords, + &PyST_Type, &self, + PyUnicode_FSDecoder, &filename); + else + ok = PyArg_ParseTupleAndKeywords(args, kw, "|O&:compile", &keywords[1], + PyUnicode_FSDecoder, &filename); + if (!ok) + goto error; + + if (filename == NULL) { + filename = PyUnicode_FromString(""); + if (filename == NULL) + goto error; + } + + arena = PyArena_New(); + if (!arena) + goto error; + + mod = PyAST_FromNodeObject(self->st_node, &self->st_flags, + filename, arena); + if (!mod) + goto error; + + res = (PyObject *)PyAST_CompileObject(mod, filename, + &self->st_flags, -1, arena); +error: + Py_XDECREF(filename); + if (arena != NULL) + PyArena_Free(arena); + return res; +} + + +/* PyObject* parser_isexpr(PyObject* self, PyObject* args) + * PyObject* parser_issuite(PyObject* self, PyObject* args) + * + * Checks the passed-in ST object to determine if it is an expression or + * a statement suite, respectively. The return is a Python truth value. + * + */ +static PyObject* +parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw) +{ + PyObject* res = 0; + int ok; + + static char *keywords[] = {"st", NULL}; + + if (self == NULL || PyModule_Check(self)) + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords, + &PyST_Type, &self); + else + ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]); + + if (ok) { + /* Check to see if the ST represents an expression or not. */ + res = (self->st_type == PyST_EXPR) ? Py_True : Py_False; + Py_INCREF(res); + } + return (res); +} + + +static PyObject* +parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw) +{ + PyObject* res = 0; + int ok; + + static char *keywords[] = {"st", NULL}; + + if (self == NULL || PyModule_Check(self)) + ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords, + &PyST_Type, &self); + else + ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]); + + if (ok) { + /* Check to see if the ST represents an expression or not. */ + res = (self->st_type == PyST_EXPR) ? Py_False : Py_True; + Py_INCREF(res); + } + return (res); +} + + +/* err_string(const char* message) + * + * Sets the error string for an exception of type ParserError. + * + */ +static void +err_string(const char *message) +{ + PyErr_SetString(parser_error, message); +} + + +/* PyObject* parser_do_parse(PyObject* args, int type) + * + * Internal function to actually execute the parse and return the result if + * successful or set an exception if not. + * + */ +static PyObject* +parser_do_parse(PyObject *args, PyObject *kw, const char *argspec, int type) +{ + char* string = 0; + PyObject* res = 0; + int flags = 0; + perrdetail err; + + static char *keywords[] = {"source", NULL}; + + if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) { + node* n = PyParser_ParseStringFlagsFilenameEx(string, NULL, + &_PyParser_Grammar, + (type == PyST_EXPR) + ? eval_input : file_input, + &err, &flags); + + if (n) { + res = parser_newstobject(n, type); if (res) { - ((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK; + ((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK; ((PyST_Object *)res)->st_flags.cf_feature_version = PY_MINOR_VERSION; } - } - else { - PyParser_SetError(&err); - } - PyParser_ClearError(&err); - } - return (res); -} - - -/* PyObject* parser_expr(PyObject* self, PyObject* args) - * PyObject* parser_suite(PyObject* self, PyObject* args) - * - * External interfaces to the parser itself. Which is called determines if - * the parser attempts to recognize an expression ('eval' form) or statement - * suite ('exec' form). The real work is done by parser_do_parse() above. - * - */ -static PyObject* -parser_expr(PyST_Object *self, PyObject *args, PyObject *kw) -{ - NOTE(ARGUNUSED(self)) - return (parser_do_parse(args, kw, "s:expr", PyST_EXPR)); -} - - -static PyObject* -parser_suite(PyST_Object *self, PyObject *args, PyObject *kw) -{ - NOTE(ARGUNUSED(self)) - return (parser_do_parse(args, kw, "s:suite", PyST_SUITE)); -} - - - -/* This is the messy part of the code. Conversion from a tuple to an ST - * object requires that the input tuple be valid without having to rely on - * catching an exception from the compiler. This is done to allow the - * compiler itself to remain fast, since most of its input will come from - * the parser directly, and therefore be known to be syntactically correct. - * This validation is done to ensure that we don't core dump the compile - * phase, returning an exception instead. - * - * Two aspects can be broken out in this code: creating a node tree from - * the tuple passed in, and verifying that it is indeed valid. It may be - * advantageous to expand the number of ST types to include funcdefs and - * lambdadefs to take advantage of the optimizer, recognizing those STs - * here. They are not necessary, and not quite as useful in a raw form. - * For now, let's get expressions and suites working reliably. - */ - - -static node* build_node_tree(PyObject *tuple); - -static int -validate_node(node *tree) -{ - int type = TYPE(tree); - int nch = NCH(tree); - state *dfa_state; - int pos, arc; - - assert(ISNONTERMINAL(type)); - type -= NT_OFFSET; - if (type >= _PyParser_Grammar.g_ndfas) { - PyErr_Format(parser_error, "Unrecognized node type %d.", TYPE(tree)); - return 0; - } + } + else { + PyParser_SetError(&err); + } + PyParser_ClearError(&err); + } + return (res); +} + + +/* PyObject* parser_expr(PyObject* self, PyObject* args) + * PyObject* parser_suite(PyObject* self, PyObject* args) + * + * External interfaces to the parser itself. Which is called determines if + * the parser attempts to recognize an expression ('eval' form) or statement + * suite ('exec' form). The real work is done by parser_do_parse() above. + * + */ +static PyObject* +parser_expr(PyST_Object *self, PyObject *args, PyObject *kw) +{ + NOTE(ARGUNUSED(self)) + return (parser_do_parse(args, kw, "s:expr", PyST_EXPR)); +} + + +static PyObject* +parser_suite(PyST_Object *self, PyObject *args, PyObject *kw) +{ + NOTE(ARGUNUSED(self)) + return (parser_do_parse(args, kw, "s:suite", PyST_SUITE)); +} + + + +/* This is the messy part of the code. Conversion from a tuple to an ST + * object requires that the input tuple be valid without having to rely on + * catching an exception from the compiler. This is done to allow the + * compiler itself to remain fast, since most of its input will come from + * the parser directly, and therefore be known to be syntactically correct. + * This validation is done to ensure that we don't core dump the compile + * phase, returning an exception instead. + * + * Two aspects can be broken out in this code: creating a node tree from + * the tuple passed in, and verifying that it is indeed valid. It may be + * advantageous to expand the number of ST types to include funcdefs and + * lambdadefs to take advantage of the optimizer, recognizing those STs + * here. They are not necessary, and not quite as useful in a raw form. + * For now, let's get expressions and suites working reliably. + */ + + +static node* build_node_tree(PyObject *tuple); + +static int +validate_node(node *tree) +{ + int type = TYPE(tree); + int nch = NCH(tree); + state *dfa_state; + int pos, arc; + + assert(ISNONTERMINAL(type)); + type -= NT_OFFSET; + if (type >= _PyParser_Grammar.g_ndfas) { + PyErr_Format(parser_error, "Unrecognized node type %d.", TYPE(tree)); + return 0; + } const dfa *nt_dfa = &_PyParser_Grammar.g_dfa[type]; - REQ(tree, nt_dfa->d_type); - - /* Run the DFA for this nonterminal. */ + REQ(tree, nt_dfa->d_type); + + /* Run the DFA for this nonterminal. */ dfa_state = nt_dfa->d_state; - for (pos = 0; pos < nch; ++pos) { - node *ch = CHILD(tree, pos); - int ch_type = TYPE(ch); + for (pos = 0; pos < nch; ++pos) { + node *ch = CHILD(tree, pos); + int ch_type = TYPE(ch); if ((ch_type >= NT_OFFSET + _PyParser_Grammar.g_ndfas) || (ISTERMINAL(ch_type) && (ch_type >= N_TOKENS)) || (ch_type < 0) @@ -673,30 +673,30 @@ validate_node(node *tree) support type comments here. */ ch_type = func_body_suite; } - for (arc = 0; arc < dfa_state->s_narcs; ++arc) { - short a_label = dfa_state->s_arc[arc].a_lbl; - assert(a_label < _PyParser_Grammar.g_ll.ll_nlabels); + for (arc = 0; arc < dfa_state->s_narcs; ++arc) { + short a_label = dfa_state->s_arc[arc].a_lbl; + assert(a_label < _PyParser_Grammar.g_ll.ll_nlabels); const char *label_str = _PyParser_Grammar.g_ll.ll_label[a_label].lb_str; if ((_PyParser_Grammar.g_ll.ll_label[a_label].lb_type == ch_type) && ((ch->n_str == NULL) || (label_str == NULL) || (strcmp(ch->n_str, label_str) == 0)) ) { - /* The child is acceptable; if non-terminal, validate it recursively. */ - if (ISNONTERMINAL(ch_type) && !validate_node(ch)) - return 0; - - /* Update the state, and move on to the next child. */ - dfa_state = &nt_dfa->d_state[dfa_state->s_arc[arc].a_arrow]; - goto arc_found; - } - } - /* What would this state have accepted? */ - { - short a_label = dfa_state->s_arc->a_lbl; - if (!a_label) /* Wouldn't accept any more children */ - goto illegal_num_children; - + /* The child is acceptable; if non-terminal, validate it recursively. */ + if (ISNONTERMINAL(ch_type) && !validate_node(ch)) + return 0; + + /* Update the state, and move on to the next child. */ + dfa_state = &nt_dfa->d_state[dfa_state->s_arc[arc].a_arrow]; + goto arc_found; + } + } + /* What would this state have accepted? */ + { + short a_label = dfa_state->s_arc->a_lbl; + if (!a_label) /* Wouldn't accept any more children */ + goto illegal_num_children; + int next_type = _PyParser_Grammar.g_ll.ll_label[a_label].lb_type; const char *expected_str = _PyParser_Grammar.g_ll.ll_label[a_label].lb_str; @@ -711,512 +711,512 @@ validate_node(node *tree) expected_str); } else { - PyErr_Format(parser_error, "Illegal terminal: expected %s.", - _PyParser_TokenNames[next_type]); - } - return 0; - } - -arc_found: - continue; - } - /* Are we in a final state? If so, return 1 for successful validation. */ - for (arc = 0; arc < dfa_state->s_narcs; ++arc) { - if (!dfa_state->s_arc[arc].a_lbl) { - return 1; - } - } - -illegal_num_children: - PyErr_Format(parser_error, - "Illegal number of children for %s node.", nt_dfa->d_name); - return 0; -} - -/* PyObject* parser_tuple2st(PyObject* self, PyObject* args) - * - * This is the public function, called from the Python code. It receives a - * single tuple object from the caller, and creates an ST object if the - * tuple can be validated. It does this by checking the first code of the - * tuple, and, if acceptable, builds the internal representation. If this - * step succeeds, the internal representation is validated as fully as - * possible with the recursive validate_node() routine defined above. - * - * This function must be changed if support is to be added for PyST_FRAGMENT - * ST objects. - * - */ -static PyObject* -parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw) -{ - NOTE(ARGUNUSED(self)) - PyObject *st = 0; - PyObject *tuple; - node *tree; - - static char *keywords[] = {"sequence", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords, - &tuple)) - return (0); - if (!PySequence_Check(tuple)) { - PyErr_SetString(PyExc_ValueError, - "sequence2st() requires a single sequence argument"); - return (0); - } - /* - * Convert the tree to the internal form before checking it. - */ - tree = build_node_tree(tuple); - if (tree != 0) { - node *validation_root = NULL; - int tree_type = 0; - switch (TYPE(tree)) { - case eval_input: - /* Might be an eval form. */ - tree_type = PyST_EXPR; - validation_root = tree; - break; - case encoding_decl: - /* This looks like an encoding_decl so far. */ - if (NCH(tree) == 1) { - tree_type = PyST_SUITE; - validation_root = CHILD(tree, 0); - } - else { - err_string("Error Parsing encoding_decl"); + PyErr_Format(parser_error, "Illegal terminal: expected %s.", + _PyParser_TokenNames[next_type]); } - break; - case file_input: - /* This looks like an exec form so far. */ - tree_type = PyST_SUITE; - validation_root = tree; - break; - default: - /* This is a fragment, at best. */ - err_string("parse tree does not use a valid start symbol"); - } - - if (validation_root != NULL && validate_node(validation_root)) - st = parser_newstobject(tree, tree_type); - else - PyNode_Free(tree); - } - /* Make sure we raise an exception on all errors. We should never - * get this, but we'd do well to be sure something is done. - */ - if (st == NULL && !PyErr_Occurred()) - err_string("unspecified ST error occurred"); - - return st; -} - - -/* node* build_node_children() - * - * Iterate across the children of the current non-terminal node and build - * their structures. If successful, return the root of this portion of - * the tree, otherwise, 0. Any required exception will be specified already, - * and no memory will have been deallocated. - * - */ -static node* -build_node_children(PyObject *tuple, node *root, int *line_num) -{ - Py_ssize_t len = PyObject_Size(tuple); - Py_ssize_t i; - int err; - - if (len < 0) { - return NULL; - } - for (i = 1; i < len; ++i) { - /* elem must always be a sequence, however simple */ - PyObject* elem = PySequence_GetItem(tuple, i); - int ok = elem != NULL; - int type = 0; - char *strn = 0; - - if (ok) - ok = PySequence_Check(elem); - if (ok) { - PyObject *temp = PySequence_GetItem(elem, 0); - if (temp == NULL) - ok = 0; - else { - ok = PyLong_Check(temp); - if (ok) { - type = _PyLong_AsInt(temp); - if (type == -1 && PyErr_Occurred()) { - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - } - Py_DECREF(temp); - } - } - if (!ok) { - PyObject *err = Py_BuildValue("Os", elem, - "Illegal node construct."); - PyErr_SetObject(parser_error, err); - Py_XDECREF(err); - Py_XDECREF(elem); - return NULL; - } - if (ISTERMINAL(type)) { - Py_ssize_t len = PyObject_Size(elem); - PyObject *temp; - const char *temp_str; - - if ((len != 2) && (len != 3)) { - err_string("terminal nodes must have 2 or 3 entries"); - Py_DECREF(elem); - return NULL; - } - temp = PySequence_GetItem(elem, 1); - if (temp == NULL) { - Py_DECREF(elem); - return NULL; - } - if (!PyUnicode_Check(temp)) { - PyErr_Format(parser_error, - "second item in terminal node must be a string," - " found %s", - Py_TYPE(temp)->tp_name); - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - if (len == 3) { - PyObject *o = PySequence_GetItem(elem, 2); - if (o == NULL) { - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - if (PyLong_Check(o)) { - int num = _PyLong_AsInt(o); - if (num == -1 && PyErr_Occurred()) { - Py_DECREF(o); - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - *line_num = num; - } - else { - PyErr_Format(parser_error, - "third item in terminal node must be an" - " integer, found %s", - Py_TYPE(temp)->tp_name); - Py_DECREF(o); - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - Py_DECREF(o); - } - temp_str = PyUnicode_AsUTF8AndSize(temp, &len); - if (temp_str == NULL) { - Py_DECREF(temp); - Py_DECREF(elem); - return NULL; - } - strn = (char *)PyObject_MALLOC(len + 1); - if (strn == NULL) { - Py_DECREF(temp); - Py_DECREF(elem); - PyErr_NoMemory(); - return NULL; - } - (void) memcpy(strn, temp_str, len + 1); - Py_DECREF(temp); - } - else if (!ISNONTERMINAL(type)) { - /* - * It has to be one or the other; this is an error. - * Raise an exception. - */ - PyObject *err = Py_BuildValue("Os", elem, "unknown node type."); - PyErr_SetObject(parser_error, err); - Py_XDECREF(err); - Py_DECREF(elem); - return NULL; - } + return 0; + } + +arc_found: + continue; + } + /* Are we in a final state? If so, return 1 for successful validation. */ + for (arc = 0; arc < dfa_state->s_narcs; ++arc) { + if (!dfa_state->s_arc[arc].a_lbl) { + return 1; + } + } + +illegal_num_children: + PyErr_Format(parser_error, + "Illegal number of children for %s node.", nt_dfa->d_name); + return 0; +} + +/* PyObject* parser_tuple2st(PyObject* self, PyObject* args) + * + * This is the public function, called from the Python code. It receives a + * single tuple object from the caller, and creates an ST object if the + * tuple can be validated. It does this by checking the first code of the + * tuple, and, if acceptable, builds the internal representation. If this + * step succeeds, the internal representation is validated as fully as + * possible with the recursive validate_node() routine defined above. + * + * This function must be changed if support is to be added for PyST_FRAGMENT + * ST objects. + * + */ +static PyObject* +parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw) +{ + NOTE(ARGUNUSED(self)) + PyObject *st = 0; + PyObject *tuple; + node *tree; + + static char *keywords[] = {"sequence", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords, + &tuple)) + return (0); + if (!PySequence_Check(tuple)) { + PyErr_SetString(PyExc_ValueError, + "sequence2st() requires a single sequence argument"); + return (0); + } + /* + * Convert the tree to the internal form before checking it. + */ + tree = build_node_tree(tuple); + if (tree != 0) { + node *validation_root = NULL; + int tree_type = 0; + switch (TYPE(tree)) { + case eval_input: + /* Might be an eval form. */ + tree_type = PyST_EXPR; + validation_root = tree; + break; + case encoding_decl: + /* This looks like an encoding_decl so far. */ + if (NCH(tree) == 1) { + tree_type = PyST_SUITE; + validation_root = CHILD(tree, 0); + } + else { + err_string("Error Parsing encoding_decl"); + } + break; + case file_input: + /* This looks like an exec form so far. */ + tree_type = PyST_SUITE; + validation_root = tree; + break; + default: + /* This is a fragment, at best. */ + err_string("parse tree does not use a valid start symbol"); + } + + if (validation_root != NULL && validate_node(validation_root)) + st = parser_newstobject(tree, tree_type); + else + PyNode_Free(tree); + } + /* Make sure we raise an exception on all errors. We should never + * get this, but we'd do well to be sure something is done. + */ + if (st == NULL && !PyErr_Occurred()) + err_string("unspecified ST error occurred"); + + return st; +} + + +/* node* build_node_children() + * + * Iterate across the children of the current non-terminal node and build + * their structures. If successful, return the root of this portion of + * the tree, otherwise, 0. Any required exception will be specified already, + * and no memory will have been deallocated. + * + */ +static node* +build_node_children(PyObject *tuple, node *root, int *line_num) +{ + Py_ssize_t len = PyObject_Size(tuple); + Py_ssize_t i; + int err; + + if (len < 0) { + return NULL; + } + for (i = 1; i < len; ++i) { + /* elem must always be a sequence, however simple */ + PyObject* elem = PySequence_GetItem(tuple, i); + int ok = elem != NULL; + int type = 0; + char *strn = 0; + + if (ok) + ok = PySequence_Check(elem); + if (ok) { + PyObject *temp = PySequence_GetItem(elem, 0); + if (temp == NULL) + ok = 0; + else { + ok = PyLong_Check(temp); + if (ok) { + type = _PyLong_AsInt(temp); + if (type == -1 && PyErr_Occurred()) { + Py_DECREF(temp); + Py_DECREF(elem); + return NULL; + } + } + Py_DECREF(temp); + } + } + if (!ok) { + PyObject *err = Py_BuildValue("Os", elem, + "Illegal node construct."); + PyErr_SetObject(parser_error, err); + Py_XDECREF(err); + Py_XDECREF(elem); + return NULL; + } + if (ISTERMINAL(type)) { + Py_ssize_t len = PyObject_Size(elem); + PyObject *temp; + const char *temp_str; + + if ((len != 2) && (len != 3)) { + err_string("terminal nodes must have 2 or 3 entries"); + Py_DECREF(elem); + return NULL; + } + temp = PySequence_GetItem(elem, 1); + if (temp == NULL) { + Py_DECREF(elem); + return NULL; + } + if (!PyUnicode_Check(temp)) { + PyErr_Format(parser_error, + "second item in terminal node must be a string," + " found %s", + Py_TYPE(temp)->tp_name); + Py_DECREF(temp); + Py_DECREF(elem); + return NULL; + } + if (len == 3) { + PyObject *o = PySequence_GetItem(elem, 2); + if (o == NULL) { + Py_DECREF(temp); + Py_DECREF(elem); + return NULL; + } + if (PyLong_Check(o)) { + int num = _PyLong_AsInt(o); + if (num == -1 && PyErr_Occurred()) { + Py_DECREF(o); + Py_DECREF(temp); + Py_DECREF(elem); + return NULL; + } + *line_num = num; + } + else { + PyErr_Format(parser_error, + "third item in terminal node must be an" + " integer, found %s", + Py_TYPE(temp)->tp_name); + Py_DECREF(o); + Py_DECREF(temp); + Py_DECREF(elem); + return NULL; + } + Py_DECREF(o); + } + temp_str = PyUnicode_AsUTF8AndSize(temp, &len); + if (temp_str == NULL) { + Py_DECREF(temp); + Py_DECREF(elem); + return NULL; + } + strn = (char *)PyObject_MALLOC(len + 1); + if (strn == NULL) { + Py_DECREF(temp); + Py_DECREF(elem); + PyErr_NoMemory(); + return NULL; + } + (void) memcpy(strn, temp_str, len + 1); + Py_DECREF(temp); + } + else if (!ISNONTERMINAL(type)) { + /* + * It has to be one or the other; this is an error. + * Raise an exception. + */ + PyObject *err = Py_BuildValue("Os", elem, "unknown node type."); + PyErr_SetObject(parser_error, err); + Py_XDECREF(err); + Py_DECREF(elem); + return NULL; + } err = PyNode_AddChild(root, type, strn, *line_num, 0, *line_num, 0); - if (err == E_NOMEM) { - Py_DECREF(elem); - PyObject_FREE(strn); - PyErr_NoMemory(); - return NULL; - } - if (err == E_OVERFLOW) { - Py_DECREF(elem); - PyObject_FREE(strn); - PyErr_SetString(PyExc_ValueError, - "unsupported number of child nodes"); - return NULL; - } - - if (ISNONTERMINAL(type)) { - node* new_child = CHILD(root, i - 1); - - if (new_child != build_node_children(elem, new_child, line_num)) { - Py_DECREF(elem); - return NULL; - } - } - else if (type == NEWLINE) { /* It's true: we increment the */ - ++(*line_num); /* line number *after* the newline! */ - } - Py_DECREF(elem); - } - return root; -} - - -static node* -build_node_tree(PyObject *tuple) -{ - node* res = 0; - PyObject *temp = PySequence_GetItem(tuple, 0); - long num = -1; - - if (temp != NULL) - num = PyLong_AsLong(temp); - Py_XDECREF(temp); - if (ISTERMINAL(num)) { - /* - * The tuple is simple, but it doesn't start with a start symbol. - * Raise an exception now and be done with it. - */ - tuple = Py_BuildValue("Os", tuple, - "Illegal syntax-tree; cannot start with terminal symbol."); - PyErr_SetObject(parser_error, tuple); - Py_XDECREF(tuple); - } - else if (ISNONTERMINAL(num)) { - /* - * Not efficient, but that can be handled later. - */ - int line_num = 0; - PyObject *encoding = NULL; - - if (num == encoding_decl) { - encoding = PySequence_GetItem(tuple, 2); - if (encoding == NULL) { - PyErr_SetString(parser_error, "missed encoding"); - return NULL; - } - if (!PyUnicode_Check(encoding)) { - PyErr_Format(parser_error, - "encoding must be a string, found %.200s", - Py_TYPE(encoding)->tp_name); - Py_DECREF(encoding); - return NULL; - } - /* tuple isn't borrowed anymore here, need to DECREF */ - tuple = PySequence_GetSlice(tuple, 0, 2); - if (tuple == NULL) { - Py_DECREF(encoding); - return NULL; - } - } - res = PyNode_New(num); - if (res != NULL) { - if (res != build_node_children(tuple, res, &line_num)) { - PyNode_Free(res); - res = NULL; - } - if (res && encoding) { - Py_ssize_t len; - const char *temp; - temp = PyUnicode_AsUTF8AndSize(encoding, &len); - if (temp == NULL) { - PyNode_Free(res); - Py_DECREF(encoding); - Py_DECREF(tuple); - return NULL; - } - res->n_str = (char *)PyObject_MALLOC(len + 1); - if (res->n_str == NULL) { - PyNode_Free(res); - Py_DECREF(encoding); - Py_DECREF(tuple); - PyErr_NoMemory(); - return NULL; - } - (void) memcpy(res->n_str, temp, len + 1); - } - } - if (encoding != NULL) { - Py_DECREF(encoding); - Py_DECREF(tuple); - } - } - else { - /* The tuple is illegal -- if the number is neither TERMINAL nor - * NONTERMINAL, we can't use it. Not sure the implementation - * allows this condition, but the API doesn't preclude it. - */ - PyObject *err = Py_BuildValue("Os", tuple, - "Illegal component tuple."); - PyErr_SetObject(parser_error, err); - Py_XDECREF(err); - } - - return (res); -} - - -static PyObject* -pickle_constructor = NULL; - - -static PyObject* -parser__pickler(PyObject *self, PyObject *args) -{ - NOTE(ARGUNUSED(self)) - PyObject *result = NULL; - PyObject *st = NULL; - - if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) { - PyObject *newargs; - PyObject *tuple; - + if (err == E_NOMEM) { + Py_DECREF(elem); + PyObject_FREE(strn); + PyErr_NoMemory(); + return NULL; + } + if (err == E_OVERFLOW) { + Py_DECREF(elem); + PyObject_FREE(strn); + PyErr_SetString(PyExc_ValueError, + "unsupported number of child nodes"); + return NULL; + } + + if (ISNONTERMINAL(type)) { + node* new_child = CHILD(root, i - 1); + + if (new_child != build_node_children(elem, new_child, line_num)) { + Py_DECREF(elem); + return NULL; + } + } + else if (type == NEWLINE) { /* It's true: we increment the */ + ++(*line_num); /* line number *after* the newline! */ + } + Py_DECREF(elem); + } + return root; +} + + +static node* +build_node_tree(PyObject *tuple) +{ + node* res = 0; + PyObject *temp = PySequence_GetItem(tuple, 0); + long num = -1; + + if (temp != NULL) + num = PyLong_AsLong(temp); + Py_XDECREF(temp); + if (ISTERMINAL(num)) { + /* + * The tuple is simple, but it doesn't start with a start symbol. + * Raise an exception now and be done with it. + */ + tuple = Py_BuildValue("Os", tuple, + "Illegal syntax-tree; cannot start with terminal symbol."); + PyErr_SetObject(parser_error, tuple); + Py_XDECREF(tuple); + } + else if (ISNONTERMINAL(num)) { + /* + * Not efficient, but that can be handled later. + */ + int line_num = 0; + PyObject *encoding = NULL; + + if (num == encoding_decl) { + encoding = PySequence_GetItem(tuple, 2); + if (encoding == NULL) { + PyErr_SetString(parser_error, "missed encoding"); + return NULL; + } + if (!PyUnicode_Check(encoding)) { + PyErr_Format(parser_error, + "encoding must be a string, found %.200s", + Py_TYPE(encoding)->tp_name); + Py_DECREF(encoding); + return NULL; + } + /* tuple isn't borrowed anymore here, need to DECREF */ + tuple = PySequence_GetSlice(tuple, 0, 2); + if (tuple == NULL) { + Py_DECREF(encoding); + return NULL; + } + } + res = PyNode_New(num); + if (res != NULL) { + if (res != build_node_children(tuple, res, &line_num)) { + PyNode_Free(res); + res = NULL; + } + if (res && encoding) { + Py_ssize_t len; + const char *temp; + temp = PyUnicode_AsUTF8AndSize(encoding, &len); + if (temp == NULL) { + PyNode_Free(res); + Py_DECREF(encoding); + Py_DECREF(tuple); + return NULL; + } + res->n_str = (char *)PyObject_MALLOC(len + 1); + if (res->n_str == NULL) { + PyNode_Free(res); + Py_DECREF(encoding); + Py_DECREF(tuple); + PyErr_NoMemory(); + return NULL; + } + (void) memcpy(res->n_str, temp, len + 1); + } + } + if (encoding != NULL) { + Py_DECREF(encoding); + Py_DECREF(tuple); + } + } + else { + /* The tuple is illegal -- if the number is neither TERMINAL nor + * NONTERMINAL, we can't use it. Not sure the implementation + * allows this condition, but the API doesn't preclude it. + */ + PyObject *err = Py_BuildValue("Os", tuple, + "Illegal component tuple."); + PyErr_SetObject(parser_error, err); + Py_XDECREF(err); + } + + return (res); +} + + +static PyObject* +pickle_constructor = NULL; + + +static PyObject* +parser__pickler(PyObject *self, PyObject *args) +{ + NOTE(ARGUNUSED(self)) + PyObject *result = NULL; + PyObject *st = NULL; + + if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) { + PyObject *newargs; + PyObject *tuple; + if ((newargs = PyTuple_Pack(2, st, Py_True)) == NULL) return NULL; tuple = parser_st2tuple((PyST_Object*)NULL, newargs, NULL); - if (tuple != NULL) { - result = Py_BuildValue("O(O)", pickle_constructor, tuple); - Py_DECREF(tuple); - } - Py_DECREF(newargs); - } - - return (result); -} - - -/* Functions exported by this module. Most of this should probably - * be converted into an ST object with methods, but that is better - * done directly in Python, allowing subclasses to be created directly. - * We'd really have to write a wrapper around it all anyway to allow - * inheritance. - */ -static PyMethodDef parser_functions[] = { + if (tuple != NULL) { + result = Py_BuildValue("O(O)", pickle_constructor, tuple); + Py_DECREF(tuple); + } + Py_DECREF(newargs); + } + + return (result); +} + + +/* Functions exported by this module. Most of this should probably + * be converted into an ST object with methods, but that is better + * done directly in Python, allowing subclasses to be created directly. + * We'd really have to write a wrapper around it all anyway to allow + * inheritance. + */ +static PyMethodDef parser_functions[] = { {"compilest", (PyCFunction)(void(*)(void))parser_compilest, PUBLIC_METHOD_TYPE, - PyDoc_STR("Compiles an ST object into a code object.")}, + PyDoc_STR("Compiles an ST object into a code object.")}, {"expr", (PyCFunction)(void(*)(void))parser_expr, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates an ST object from an expression.")}, + PyDoc_STR("Creates an ST object from an expression.")}, {"isexpr", (PyCFunction)(void(*)(void))parser_isexpr, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if an ST object was created from an expression.")}, + PyDoc_STR("Determines if an ST object was created from an expression.")}, {"issuite", (PyCFunction)(void(*)(void))parser_issuite, PUBLIC_METHOD_TYPE, - PyDoc_STR("Determines if an ST object was created from a suite.")}, + PyDoc_STR("Determines if an ST object was created from a suite.")}, {"suite", (PyCFunction)(void(*)(void))parser_suite, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates an ST object from a suite.")}, + PyDoc_STR("Creates an ST object from a suite.")}, {"sequence2st", (PyCFunction)(void(*)(void))parser_tuple2st, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates an ST object from a tree representation.")}, + PyDoc_STR("Creates an ST object from a tree representation.")}, {"st2tuple", (PyCFunction)(void(*)(void))parser_st2tuple, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a tuple-tree representation of an ST.")}, + PyDoc_STR("Creates a tuple-tree representation of an ST.")}, {"st2list", (PyCFunction)(void(*)(void))parser_st2list, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates a list-tree representation of an ST.")}, + PyDoc_STR("Creates a list-tree representation of an ST.")}, {"tuple2st", (PyCFunction)(void(*)(void))parser_tuple2st, PUBLIC_METHOD_TYPE, - PyDoc_STR("Creates an ST object from a tree representation.")}, - - /* private stuff: support pickle module */ - {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS, - PyDoc_STR("Returns the pickle magic to allow ST objects to be pickled.")}, - - {NULL, NULL, 0, NULL} - }; - - - -static struct PyModuleDef parsermodule = { - PyModuleDef_HEAD_INIT, - "parser", - NULL, - -1, - parser_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC PyInit_parser(void); /* supply a prototype */ - -PyMODINIT_FUNC -PyInit_parser(void) -{ - PyObject *module, *copyreg; - + PyDoc_STR("Creates an ST object from a tree representation.")}, + + /* private stuff: support pickle module */ + {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS, + PyDoc_STR("Returns the pickle magic to allow ST objects to be pickled.")}, + + {NULL, NULL, 0, NULL} + }; + + + +static struct PyModuleDef parsermodule = { + PyModuleDef_HEAD_INIT, + "parser", + NULL, + -1, + parser_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit_parser(void); /* supply a prototype */ + +PyMODINIT_FUNC +PyInit_parser(void) +{ + PyObject *module, *copyreg; + if (PyErr_WarnEx(PyExc_DeprecationWarning, "The parser module is deprecated and will be removed " "in future versions of Python", 7) != 0) { return NULL; } - if (PyType_Ready(&PyST_Type) < 0) - return NULL; - module = PyModule_Create(&parsermodule); - if (module == NULL) - return NULL; - - if (parser_error == 0) - parser_error = PyErr_NewException("parser.ParserError", NULL, NULL); - - if (parser_error == 0) - return NULL; - /* CAUTION: The code next used to skip bumping the refcount on - * parser_error. That's a disaster if PyInit_parser() gets called more - * than once. By incref'ing, we ensure that each module dict that - * gets created owns its reference to the shared parser_error object, - * and the file static parser_error vrbl owns a reference too. - */ - Py_INCREF(parser_error); - if (PyModule_AddObject(module, "ParserError", parser_error) != 0) - return NULL; - - Py_INCREF(&PyST_Type); - PyModule_AddObject(module, "STType", (PyObject*)&PyST_Type); - - PyModule_AddStringConstant(module, "__copyright__", - parser_copyright_string); - PyModule_AddStringConstant(module, "__doc__", - parser_doc_string); - PyModule_AddStringConstant(module, "__version__", - parser_version_string); - - /* Register to support pickling. - * If this fails, the import of this module will fail because an - * exception will be raised here; should we clear the exception? - */ - copyreg = PyImport_ImportModuleNoBlock("copyreg"); - if (copyreg != NULL) { - PyObject *func, *pickler; - _Py_IDENTIFIER(pickle); - _Py_IDENTIFIER(sequence2st); - _Py_IDENTIFIER(_pickler); - - func = _PyObject_GetAttrId(copyreg, &PyId_pickle); - pickle_constructor = _PyObject_GetAttrId(module, &PyId_sequence2st); - pickler = _PyObject_GetAttrId(module, &PyId__pickler); - Py_XINCREF(pickle_constructor); - if ((func != NULL) && (pickle_constructor != NULL) - && (pickler != NULL)) { - PyObject *res; - - res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler, - pickle_constructor, NULL); - Py_XDECREF(res); - } - Py_XDECREF(func); - Py_XDECREF(pickle_constructor); - Py_XDECREF(pickler); - Py_DECREF(copyreg); - } - return module; -} + if (PyType_Ready(&PyST_Type) < 0) + return NULL; + module = PyModule_Create(&parsermodule); + if (module == NULL) + return NULL; + + if (parser_error == 0) + parser_error = PyErr_NewException("parser.ParserError", NULL, NULL); + + if (parser_error == 0) + return NULL; + /* CAUTION: The code next used to skip bumping the refcount on + * parser_error. That's a disaster if PyInit_parser() gets called more + * than once. By incref'ing, we ensure that each module dict that + * gets created owns its reference to the shared parser_error object, + * and the file static parser_error vrbl owns a reference too. + */ + Py_INCREF(parser_error); + if (PyModule_AddObject(module, "ParserError", parser_error) != 0) + return NULL; + + Py_INCREF(&PyST_Type); + PyModule_AddObject(module, "STType", (PyObject*)&PyST_Type); + + PyModule_AddStringConstant(module, "__copyright__", + parser_copyright_string); + PyModule_AddStringConstant(module, "__doc__", + parser_doc_string); + PyModule_AddStringConstant(module, "__version__", + parser_version_string); + + /* Register to support pickling. + * If this fails, the import of this module will fail because an + * exception will be raised here; should we clear the exception? + */ + copyreg = PyImport_ImportModuleNoBlock("copyreg"); + if (copyreg != NULL) { + PyObject *func, *pickler; + _Py_IDENTIFIER(pickle); + _Py_IDENTIFIER(sequence2st); + _Py_IDENTIFIER(_pickler); + + func = _PyObject_GetAttrId(copyreg, &PyId_pickle); + pickle_constructor = _PyObject_GetAttrId(module, &PyId_sequence2st); + pickler = _PyObject_GetAttrId(module, &PyId__pickler); + Py_XINCREF(pickle_constructor); + if ((func != NULL) && (pickle_constructor != NULL) + && (pickler != NULL)) { + PyObject *res; + + res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler, + pickle_constructor, NULL); + Py_XDECREF(res); + } + Py_XDECREF(func); + Py_XDECREF(pickle_constructor); + Py_XDECREF(pickler); + Py_DECREF(copyreg); + } + return module; +} diff --git a/contrib/tools/python3/src/Modules/posixmodule.c b/contrib/tools/python3/src/Modules/posixmodule.c index 09182668432..61adb2e6593 100644 --- a/contrib/tools/python3/src/Modules/posixmodule.c +++ b/contrib/tools/python3/src/Modules/posixmodule.c @@ -1,15 +1,15 @@ -/* POSIX module implementation */ - -/* This file is also used for Windows NT/MS-Win. In that case the - module actually calls itself 'nt', not 'posix', and a few - functions are either unimplemented or implemented differently. The source - assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent - of the compiler used. Different compilers define their own feature - test macro, e.g. '_MSC_VER'. */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" +/* POSIX module implementation */ + +/* This file is also used for Windows NT/MS-Win. In that case the + module actually calls itself 'nt', not 'posix', and a few + functions are either unimplemented or implemented differently. The source + assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent + of the compiler used. Different compilers define their own feature + test macro, e.g. '_MSC_VER'. */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" #ifdef MS_WINDOWS /* include early to avoid conflict with pycore_condvar.h: @@ -25,20 +25,20 @@ #include "pycore_import.h" // _PyImport_ReInitLock() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "structmember.h" // PyMemberDef -#ifndef MS_WINDOWS +#ifndef MS_WINDOWS # include "posixmodule.h" -#else +#else # include "winreparse.h" -#endif - -/* On android API level 21, 'AT_EACCESS' is not declared although - * HAVE_FACCESSAT is defined. */ -#ifdef __ANDROID__ +#endif + +/* On android API level 21, 'AT_EACCESS' is not declared although + * HAVE_FACCESSAT is defined. */ +#ifdef __ANDROID__ # undef HAVE_FACCESSAT -#endif - -#include /* needed for ctermid() */ - +#endif + +#include /* needed for ctermid() */ + /* * A number of APIs are available on macOS from a certain macOS version. * To support building with a new SDK while deploying to older versions @@ -166,137 +166,137 @@ #endif -#ifdef __cplusplus -extern "C" { -#endif - -PyDoc_STRVAR(posix__doc__, -"This module provides access to operating system functionality that is\n\ -standardized by the C Standard and the POSIX standard (a thinly\n\ -disguised Unix interface). Refer to the library manual and\n\ -corresponding Unix manual entries for more information on calls."); - - -#ifdef HAVE_SYS_UIO_H +#ifdef __cplusplus +extern "C" { +#endif + +PyDoc_STRVAR(posix__doc__, +"This module provides access to operating system functionality that is\n\ +standardized by the C Standard and the POSIX standard (a thinly\n\ +disguised Unix interface). Refer to the library manual and\n\ +corresponding Unix manual entries for more information on calls."); + + +#ifdef HAVE_SYS_UIO_H # include -#endif - -#ifdef HAVE_SYS_SYSMACROS_H -/* GNU C Library: major(), minor(), makedev() */ +#endif + +#ifdef HAVE_SYS_SYSMACROS_H +/* GNU C Library: major(), minor(), makedev() */ # include -#endif - -#ifdef HAVE_SYS_TYPES_H +#endif + +#ifdef HAVE_SYS_TYPES_H # include -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_SYS_STAT_H +#endif /* HAVE_SYS_TYPES_H */ + +#ifdef HAVE_SYS_STAT_H # include -#endif /* HAVE_SYS_STAT_H */ - -#ifdef HAVE_SYS_WAIT_H +#endif /* HAVE_SYS_STAT_H */ + +#ifdef HAVE_SYS_WAIT_H # include // WNOHANG -#endif +#endif #ifdef HAVE_LINUX_WAIT_H # include // P_PIDFD #endif - -#ifdef HAVE_SIGNAL_H + +#ifdef HAVE_SIGNAL_H # include -#endif - -#ifdef HAVE_FCNTL_H +#endif + +#ifdef HAVE_FCNTL_H # include #endif - -#ifdef HAVE_GRP_H + +#ifdef HAVE_GRP_H # include -#endif - -#ifdef HAVE_SYSEXITS_H +#endif + +#ifdef HAVE_SYSEXITS_H # include #endif - -#ifdef HAVE_SYS_LOADAVG_H + +#ifdef HAVE_SYS_LOADAVG_H # include -#endif - -#ifdef HAVE_SYS_SENDFILE_H +#endif + +#ifdef HAVE_SYS_SENDFILE_H # include -#endif - +#endif + #if defined(__APPLE__) # include #endif -#ifdef HAVE_SCHED_H +#ifdef HAVE_SCHED_H # include -#endif - +#endif + #ifdef HAVE_COPY_FILE_RANGE # include #endif -#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) +#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) # undef HAVE_SCHED_SETAFFINITY -#endif - -#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) +#endif + +#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) # define USE_XATTRS -#endif - -#ifdef USE_XATTRS +#endif + +#ifdef USE_XATTRS # include -#endif - -#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#endif + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) # ifdef HAVE_SYS_SOCKET_H # include # endif -#endif - -#ifdef HAVE_DLFCN_H +#endif + +#ifdef HAVE_DLFCN_H # include -#endif - -#ifdef __hpux +#endif + +#ifdef __hpux # include -#endif - -#if defined(__DragonFly__) || \ - defined(__OpenBSD__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__APPLE__) +#endif + +#if defined(__DragonFly__) || \ + defined(__OpenBSD__) || \ + defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__APPLE__) # include -#endif - -#ifdef HAVE_LINUX_RANDOM_H -# include -#endif -#ifdef HAVE_GETRANDOM_SYSCALL -# include -#endif - -#if defined(MS_WINDOWS) -# define TERMSIZE_USE_CONIO -#elif defined(HAVE_SYS_IOCTL_H) -# include -# if defined(HAVE_TERMIOS_H) -# include -# endif -# if defined(TIOCGWINSZ) -# define TERMSIZE_USE_IOCTL -# endif -#endif /* MS_WINDOWS */ - -/* Various compilers have only certain posix functions */ -/* XXX Gosh I wish these were all moved into pyconfig.h */ -#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ +#endif + +#ifdef HAVE_LINUX_RANDOM_H +# include +#endif +#ifdef HAVE_GETRANDOM_SYSCALL +# include +#endif + +#if defined(MS_WINDOWS) +# define TERMSIZE_USE_CONIO +#elif defined(HAVE_SYS_IOCTL_H) +# include +# if defined(HAVE_TERMIOS_H) +# include +# endif +# if defined(TIOCGWINSZ) +# define TERMSIZE_USE_IOCTL +# endif +#endif /* MS_WINDOWS */ + +/* Various compilers have only certain posix functions */ +/* XXX Gosh I wish these were all moved into pyconfig.h */ +#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ # define HAVE_OPENDIR 1 # define HAVE_SYSTEM 1 # include -#else +#else # ifdef _MSC_VER /* Microsoft compiler */ # define HAVE_GETPPID 1 @@ -331,24 +331,24 @@ corresponding Unix manual entries for more information on calls."); # define HAVE_WAIT 1 # define HAVE_TTYNAME 1 # endif /* _MSC_VER */ -#endif /* ! __WATCOMC__ || __QNX__ */ - +#endif /* ! __WATCOMC__ || __QNX__ */ + _Py_IDENTIFIER(__fspath__); - -/*[clinic input] -# one of the few times we lie about this name! -module os -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/ - -#ifndef _MSC_VER - -#if defined(__sgi)&&_COMPILER_VERSION>=700 -/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode - (default) */ -extern char *ctermid_r(char *); -#endif - + +/*[clinic input] +# one of the few times we lie about this name! +module os +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/ + +#ifndef _MSC_VER + +#if defined(__sgi)&&_COMPILER_VERSION>=700 +/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode + (default) */ +extern char *ctermid_r(char *); +#endif + #endif /* !_MSC_VER */ #if defined(__VXWORKS__) @@ -365,33 +365,33 @@ extern char *ctermid_r(char *); #ifdef HAVE_POSIX_SPAWN # include -#endif - -#ifdef HAVE_UTIME_H +#endif + +#ifdef HAVE_UTIME_H # include -#endif /* HAVE_UTIME_H */ - -#ifdef HAVE_SYS_UTIME_H +#endif /* HAVE_UTIME_H */ + +#ifdef HAVE_SYS_UTIME_H # include # define HAVE_UTIME_H /* pretend we do for the rest of this file */ -#endif /* HAVE_SYS_UTIME_H */ - -#ifdef HAVE_SYS_TIMES_H +#endif /* HAVE_SYS_UTIME_H */ + +#ifdef HAVE_SYS_TIMES_H # include -#endif /* HAVE_SYS_TIMES_H */ - -#ifdef HAVE_SYS_PARAM_H +#endif /* HAVE_SYS_TIMES_H */ + +#ifdef HAVE_SYS_PARAM_H # include -#endif /* HAVE_SYS_PARAM_H */ - -#ifdef HAVE_SYS_UTSNAME_H +#endif /* HAVE_SYS_PARAM_H */ + +#ifdef HAVE_SYS_UTSNAME_H # include -#endif /* HAVE_SYS_UTSNAME_H */ - -#ifdef HAVE_DIRENT_H +#endif /* HAVE_SYS_UTSNAME_H */ + +#ifdef HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) -#else +#else # if defined(__WATCOMC__) && !defined(__QNX__) # include # define NAMLEN(dirent) strlen((dirent)->d_name) @@ -408,9 +408,9 @@ extern char *ctermid_r(char *); # ifdef HAVE_NDIR_H # include # endif -#endif - -#ifdef _MSC_VER +#endif + +#ifdef _MSC_VER # ifdef HAVE_DIRECT_H # include # endif @@ -433,17 +433,17 @@ extern char *ctermid_r(char *); # include // ShellExecute() # include // UNLEN # define HAVE_SYMLINK -#endif /* _MSC_VER */ - -#ifndef MAXPATHLEN +#endif /* _MSC_VER */ + +#ifndef MAXPATHLEN # if defined(PATH_MAX) && PATH_MAX > 1024 # define MAXPATHLEN PATH_MAX # else # define MAXPATHLEN 1024 # endif -#endif /* MAXPATHLEN */ - -#ifdef UNION_WAIT +#endif /* MAXPATHLEN */ + +#ifdef UNION_WAIT /* Emulate some macros on systems that have a union instead of macros */ # ifndef WIFEXITED # define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) @@ -460,54 +460,54 @@ extern char *ctermid_r(char *); /* !UNION_WAIT */ # define WAIT_TYPE int # define WAIT_STATUS_INT(s) (s) -#endif /* UNION_WAIT */ - -/* Don't use the "_r" form if we don't need it (also, won't have a - prototype for it, at least on Solaris -- maybe others as well?). */ -#if defined(HAVE_CTERMID_R) +#endif /* UNION_WAIT */ + +/* Don't use the "_r" form if we don't need it (also, won't have a + prototype for it, at least on Solaris -- maybe others as well?). */ +#if defined(HAVE_CTERMID_R) # define USE_CTERMID_R -#endif - -/* choose the appropriate stat and fstat functions and return structs */ -#undef STAT -#undef FSTAT -#undef STRUCT_STAT -#ifdef MS_WINDOWS +#endif + +/* choose the appropriate stat and fstat functions and return structs */ +#undef STAT +#undef FSTAT +#undef STRUCT_STAT +#ifdef MS_WINDOWS # define STAT win32_stat # define LSTAT win32_lstat # define FSTAT _Py_fstat_noraise # define STRUCT_STAT struct _Py_stat_struct -#else +#else # define STAT stat # define LSTAT lstat # define FSTAT fstat # define STRUCT_STAT struct stat -#endif - -#if defined(MAJOR_IN_MKDEV) +#endif + +#if defined(MAJOR_IN_MKDEV) # include -#else +#else # if defined(MAJOR_IN_SYSMACROS) # include # endif # if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) # include # endif -#endif - -#ifdef MS_WINDOWS +#endif + +#ifdef MS_WINDOWS # define INITFUNC PyInit_nt # define MODNAME "nt" -#else +#else # define INITFUNC PyInit_posix # define MODNAME "posix" -#endif - -#if defined(__sun) -/* Something to implement in autoconf, not present in autoconf 2.69 */ +#endif + +#if defined(__sun) +/* Something to implement in autoconf, not present in autoconf 2.69 */ # define HAVE_STRUCT_STAT_ST_FSTYPE 1 -#endif - +#endif + /* memfd_create is either defined in sys/mman.h or sys/memfd.h * linux/memfd.h defines additional flags */ @@ -521,13799 +521,13799 @@ extern char *ctermid_r(char *); # include #endif -#ifdef _Py_MEMORY_SANITIZER +#ifdef _Py_MEMORY_SANITIZER # include -#endif - -#ifdef HAVE_FORK -static void -run_at_forkers(PyObject *lst, int reverse) -{ - Py_ssize_t i; - PyObject *cpy; - - if (lst != NULL) { - assert(PyList_CheckExact(lst)); - - /* Use a list copy in case register_at_fork() is called from - * one of the callbacks. - */ - cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst)); - if (cpy == NULL) - PyErr_WriteUnraisable(lst); - else { - if (reverse) - PyList_Reverse(cpy); - for (i = 0; i < PyList_GET_SIZE(cpy); i++) { - PyObject *func, *res; - func = PyList_GET_ITEM(cpy, i); +#endif + +#ifdef HAVE_FORK +static void +run_at_forkers(PyObject *lst, int reverse) +{ + Py_ssize_t i; + PyObject *cpy; + + if (lst != NULL) { + assert(PyList_CheckExact(lst)); + + /* Use a list copy in case register_at_fork() is called from + * one of the callbacks. + */ + cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst)); + if (cpy == NULL) + PyErr_WriteUnraisable(lst); + else { + if (reverse) + PyList_Reverse(cpy); + for (i = 0; i < PyList_GET_SIZE(cpy); i++) { + PyObject *func, *res; + func = PyList_GET_ITEM(cpy, i); res = _PyObject_CallNoArg(func); - if (res == NULL) - PyErr_WriteUnraisable(func); - else - Py_DECREF(res); - } - Py_DECREF(cpy); - } - } -} - -void -PyOS_BeforeFork(void) -{ + if (res == NULL) + PyErr_WriteUnraisable(func); + else + Py_DECREF(res); + } + Py_DECREF(cpy); + } + } +} + +void +PyOS_BeforeFork(void) +{ run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1); - - _PyImport_AcquireLock(); -} - -void -PyOS_AfterFork_Parent(void) -{ - if (_PyImport_ReleaseLock() <= 0) - Py_FatalError("failed releasing import lock after fork"); - + + _PyImport_AcquireLock(); +} + +void +PyOS_AfterFork_Parent(void) +{ + if (_PyImport_ReleaseLock() <= 0) + Py_FatalError("failed releasing import lock after fork"); + run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0); -} - -void -PyOS_AfterFork_Child(void) -{ +} + +void +PyOS_AfterFork_Child(void) +{ _PyRuntimeState *runtime = &_PyRuntime; _PyGILState_Reinit(runtime); _PyEval_ReInitThreads(runtime); - _PyImport_ReInitLock(); - _PySignal_AfterFork(); + _PyImport_ReInitLock(); + _PySignal_AfterFork(); _PyRuntimeState_ReInitThreads(runtime); _PyInterpreterState_DeleteExceptMain(runtime); - + run_at_forkers(_PyInterpreterState_GET()->after_forkers_child, 0); -} - -static int -register_at_forker(PyObject **lst, PyObject *func) -{ - if (func == NULL) /* nothing to register? do nothing. */ - return 0; - if (*lst == NULL) { - *lst = PyList_New(0); - if (*lst == NULL) - return -1; - } - return PyList_Append(*lst, func); -} +} + +static int +register_at_forker(PyObject **lst, PyObject *func) +{ + if (func == NULL) /* nothing to register? do nothing. */ + return 0; + if (*lst == NULL) { + *lst = PyList_New(0); + if (*lst == NULL) + return -1; + } + return PyList_Append(*lst, func); +} #endif /* HAVE_FORK */ - - -/* Legacy wrapper */ -void -PyOS_AfterFork(void) -{ -#ifdef HAVE_FORK - PyOS_AfterFork_Child(); -#endif -} - - -#ifdef MS_WINDOWS -/* defined in fileutils.c */ + + +/* Legacy wrapper */ +void +PyOS_AfterFork(void) +{ +#ifdef HAVE_FORK + PyOS_AfterFork_Child(); +#endif +} + + +#ifdef MS_WINDOWS +/* defined in fileutils.c */ void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, - ULONG, struct _Py_stat_struct *); + ULONG, struct _Py_stat_struct *); +#endif + + +#ifndef MS_WINDOWS +PyObject * +_PyLong_FromUid(uid_t uid) +{ + if (uid == (uid_t)-1) + return PyLong_FromLong(-1); + return PyLong_FromUnsignedLong(uid); +} + +PyObject * +_PyLong_FromGid(gid_t gid) +{ + if (gid == (gid_t)-1) + return PyLong_FromLong(-1); + return PyLong_FromUnsignedLong(gid); +} + +int +_Py_Uid_Converter(PyObject *obj, uid_t *p) +{ + uid_t uid; + PyObject *index; + int overflow; + long result; + unsigned long uresult; + + index = PyNumber_Index(obj); + if (index == NULL) { + PyErr_Format(PyExc_TypeError, + "uid should be integer, not %.200s", + _PyType_Name(Py_TYPE(obj))); + return 0; + } + + /* + * Handling uid_t is complicated for two reasons: + * * Although uid_t is (always?) unsigned, it still + * accepts -1. + * * We don't know its size in advance--it may be + * bigger than an int, or it may be smaller than + * a long. + * + * So a bit of defensive programming is in order. + * Start with interpreting the value passed + * in as a signed long and see if it works. + */ + + result = PyLong_AsLongAndOverflow(index, &overflow); + + if (!overflow) { + uid = (uid_t)result; + + if (result == -1) { + if (PyErr_Occurred()) + goto fail; + /* It's a legitimate -1, we're done. */ + goto success; + } + + /* Any other negative number is disallowed. */ + if (result < 0) + goto underflow; + + /* Ensure the value wasn't truncated. */ + if (sizeof(uid_t) < sizeof(long) && + (long)uid != result) + goto underflow; + goto success; + } + + if (overflow < 0) + goto underflow; + + /* + * Okay, the value overflowed a signed long. If it + * fits in an *unsigned* long, it may still be okay, + * as uid_t may be unsigned long on this platform. + */ + uresult = PyLong_AsUnsignedLong(index); + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + goto overflow; + goto fail; + } + + uid = (uid_t)uresult; + + /* + * If uid == (uid_t)-1, the user actually passed in ULONG_MAX, + * but this value would get interpreted as (uid_t)-1 by chown + * and its siblings. That's not what the user meant! So we + * throw an overflow exception instead. (We already + * handled a real -1 with PyLong_AsLongAndOverflow() above.) + */ + if (uid == (uid_t)-1) + goto overflow; + + /* Ensure the value wasn't truncated. */ + if (sizeof(uid_t) < sizeof(long) && + (unsigned long)uid != uresult) + goto overflow; + /* fallthrough */ + +success: + Py_DECREF(index); + *p = uid; + return 1; + +underflow: + PyErr_SetString(PyExc_OverflowError, + "uid is less than minimum"); + goto fail; + +overflow: + PyErr_SetString(PyExc_OverflowError, + "uid is greater than maximum"); + /* fallthrough */ + +fail: + Py_DECREF(index); + return 0; +} + +int +_Py_Gid_Converter(PyObject *obj, gid_t *p) +{ + gid_t gid; + PyObject *index; + int overflow; + long result; + unsigned long uresult; + + index = PyNumber_Index(obj); + if (index == NULL) { + PyErr_Format(PyExc_TypeError, + "gid should be integer, not %.200s", + _PyType_Name(Py_TYPE(obj))); + return 0; + } + + /* + * Handling gid_t is complicated for two reasons: + * * Although gid_t is (always?) unsigned, it still + * accepts -1. + * * We don't know its size in advance--it may be + * bigger than an int, or it may be smaller than + * a long. + * + * So a bit of defensive programming is in order. + * Start with interpreting the value passed + * in as a signed long and see if it works. + */ + + result = PyLong_AsLongAndOverflow(index, &overflow); + + if (!overflow) { + gid = (gid_t)result; + + if (result == -1) { + if (PyErr_Occurred()) + goto fail; + /* It's a legitimate -1, we're done. */ + goto success; + } + + /* Any other negative number is disallowed. */ + if (result < 0) { + goto underflow; + } + + /* Ensure the value wasn't truncated. */ + if (sizeof(gid_t) < sizeof(long) && + (long)gid != result) + goto underflow; + goto success; + } + + if (overflow < 0) + goto underflow; + + /* + * Okay, the value overflowed a signed long. If it + * fits in an *unsigned* long, it may still be okay, + * as gid_t may be unsigned long on this platform. + */ + uresult = PyLong_AsUnsignedLong(index); + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + goto overflow; + goto fail; + } + + gid = (gid_t)uresult; + + /* + * If gid == (gid_t)-1, the user actually passed in ULONG_MAX, + * but this value would get interpreted as (gid_t)-1 by chown + * and its siblings. That's not what the user meant! So we + * throw an overflow exception instead. (We already + * handled a real -1 with PyLong_AsLongAndOverflow() above.) + */ + if (gid == (gid_t)-1) + goto overflow; + + /* Ensure the value wasn't truncated. */ + if (sizeof(gid_t) < sizeof(long) && + (unsigned long)gid != uresult) + goto overflow; + /* fallthrough */ + +success: + Py_DECREF(index); + *p = gid; + return 1; + +underflow: + PyErr_SetString(PyExc_OverflowError, + "gid is less than minimum"); + goto fail; + +overflow: + PyErr_SetString(PyExc_OverflowError, + "gid is greater than maximum"); + /* fallthrough */ + +fail: + Py_DECREF(index); + return 0; +} +#endif /* MS_WINDOWS */ + + +#define _PyLong_FromDev PyLong_FromLongLong + + +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) +static int +_Py_Dev_Converter(PyObject *obj, void *p) +{ + *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); + if (PyErr_Occurred()) + return 0; + return 1; +} +#endif /* HAVE_MKNOD && HAVE_MAKEDEV */ + + +#ifdef AT_FDCWD +/* + * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965); + * without the int cast, the value gets interpreted as uint (4291925331), + * which doesn't play nicely with all the initializer lines in this file that + * look like this: + * int dir_fd = DEFAULT_DIR_FD; + */ +#define DEFAULT_DIR_FD (int)AT_FDCWD +#else +#define DEFAULT_DIR_FD (-100) +#endif + +static int +_fd_converter(PyObject *o, int *p) +{ + int overflow; + long long_value; + + PyObject *index = PyNumber_Index(o); + if (index == NULL) { + return 0; + } + + assert(PyLong_Check(index)); + long_value = PyLong_AsLongAndOverflow(index, &overflow); + Py_DECREF(index); + assert(!PyErr_Occurred()); + if (overflow > 0 || long_value > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "fd is greater than maximum"); + return 0; + } + if (overflow < 0 || long_value < INT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "fd is less than minimum"); + return 0; + } + + *p = (int)long_value; + return 1; +} + +static int +dir_fd_converter(PyObject *o, void *p) +{ + if (o == Py_None) { + *(int *)p = DEFAULT_DIR_FD; + return 1; + } + else if (PyIndex_Check(o)) { + return _fd_converter(o, (int *)p); + } + else { + PyErr_Format(PyExc_TypeError, + "argument should be integer or None, not %.200s", + _PyType_Name(Py_TYPE(o))); + return 0; + } +} + +typedef struct { + PyObject *billion; + PyObject *DirEntryType; + PyObject *ScandirIteratorType; +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + PyObject *SchedParamType; #endif + PyObject *StatResultType; + PyObject *StatVFSResultType; + PyObject *TerminalSizeType; + PyObject *TimesResultType; + PyObject *UnameResultType; +#if defined(HAVE_WAITID) && !defined(__APPLE__) + PyObject *WaitidResultType; +#endif +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + PyObject *struct_rusage; +#endif + PyObject *st_mode; +} _posixstate; + - -#ifndef MS_WINDOWS -PyObject * -_PyLong_FromUid(uid_t uid) -{ - if (uid == (uid_t)-1) - return PyLong_FromLong(-1); - return PyLong_FromUnsignedLong(uid); -} - -PyObject * -_PyLong_FromGid(gid_t gid) +static inline _posixstate* +get_posix_state(PyObject *module) { - if (gid == (gid_t)-1) - return PyLong_FromLong(-1); - return PyLong_FromUnsignedLong(gid); + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_posixstate *)state; } +/* + * A PyArg_ParseTuple "converter" function + * that handles filesystem paths in the manner + * preferred by the os module. + * + * path_converter accepts (Unicode) strings and their + * subclasses, and bytes and their subclasses. What + * it does with the argument depends on the platform: + * + * * On Windows, if we get a (Unicode) string we + * extract the wchar_t * and return it; if we get + * bytes we decode to wchar_t * and return that. + * + * * On all other platforms, strings are encoded + * to bytes using PyUnicode_FSConverter, then we + * extract the char * from the bytes object and + * return that. + * + * path_converter also optionally accepts signed + * integers (representing open file descriptors) instead + * of path strings. + * + * Input fields: + * path.nullable + * If nonzero, the path is permitted to be None. + * path.allow_fd + * If nonzero, the path is permitted to be a file handle + * (a signed int) instead of a string. + * path.function_name + * If non-NULL, path_converter will use that as the name + * of the function in error messages. + * (If path.function_name is NULL it omits the function name.) + * path.argument_name + * If non-NULL, path_converter will use that as the name + * of the parameter in error messages. + * (If path.argument_name is NULL it uses "path".) + * + * Output fields: + * path.wide + * Points to the path if it was expressed as Unicode + * and was not encoded. (Only used on Windows.) + * path.narrow + * Points to the path if it was expressed as bytes, + * or it was Unicode and was encoded to bytes. (On Windows, + * is a non-zero integer if the path was expressed as bytes. + * The type is deliberately incompatible to prevent misuse.) + * path.fd + * Contains a file descriptor if path.accept_fd was true + * and the caller provided a signed integer instead of any + * sort of string. + * + * WARNING: if your "path" parameter is optional, and is + * unspecified, path_converter will never get called. + * So if you set allow_fd, you *MUST* initialize path.fd = -1 + * yourself! + * path.length + * The length of the path in characters, if specified as + * a string. + * path.object + * The original object passed in (if get a PathLike object, + * the result of PyOS_FSPath() is treated as the original object). + * Own a reference to the object. + * path.cleanup + * For internal use only. May point to a temporary object. + * (Pay no attention to the man behind the curtain.) + * + * At most one of path.wide or path.narrow will be non-NULL. + * If path was None and path.nullable was set, + * or if path was an integer and path.allow_fd was set, + * both path.wide and path.narrow will be NULL + * and path.length will be 0. + * + * path_converter takes care to not write to the path_t + * unless it's successful. However it must reset the + * "cleanup" field each time it's called. + * + * Use as follows: + * path_t path; + * memset(&path, 0, sizeof(path)); + * PyArg_ParseTuple(args, "O&", path_converter, &path); + * // ... use values from path ... + * path_cleanup(&path); + * + * (Note that if PyArg_Parse fails you don't need to call + * path_cleanup(). However it is safe to do so.) + */ +typedef struct { + const char *function_name; + const char *argument_name; + int nullable; + int allow_fd; + const wchar_t *wide; +#ifdef MS_WINDOWS + BOOL narrow; +#else + const char *narrow; +#endif + int fd; + Py_ssize_t length; + PyObject *object; + PyObject *cleanup; +} path_t; + +#ifdef MS_WINDOWS +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ + {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL} +#else +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ + {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} +#endif + +static void +path_cleanup(path_t *path) +{ + Py_CLEAR(path->object); + Py_CLEAR(path->cleanup); +} + +static int +path_converter(PyObject *o, void *p) +{ + path_t *path = (path_t *)p; + PyObject *bytes = NULL; + Py_ssize_t length = 0; + int is_index, is_buffer, is_bytes, is_unicode; + const char *narrow; +#ifdef MS_WINDOWS + PyObject *wo = NULL; + const wchar_t *wide; +#endif + +#define FORMAT_EXCEPTION(exc, fmt) \ + PyErr_Format(exc, "%s%s" fmt, \ + path->function_name ? path->function_name : "", \ + path->function_name ? ": " : "", \ + path->argument_name ? path->argument_name : "path") + + /* Py_CLEANUP_SUPPORTED support */ + if (o == NULL) { + path_cleanup(path); + return 1; + } + + /* Ensure it's always safe to call path_cleanup(). */ + path->object = path->cleanup = NULL; + /* path->object owns a reference to the original object */ + Py_INCREF(o); + + if ((o == Py_None) && path->nullable) { + path->wide = NULL; +#ifdef MS_WINDOWS + path->narrow = FALSE; +#else + path->narrow = NULL; +#endif + path->fd = -1; + goto success_exit; + } + + /* Only call this here so that we don't treat the return value of + os.fspath() as an fd or buffer. */ + is_index = path->allow_fd && PyIndex_Check(o); + is_buffer = PyObject_CheckBuffer(o); + is_bytes = PyBytes_Check(o); + is_unicode = PyUnicode_Check(o); + + if (!is_index && !is_buffer && !is_unicode && !is_bytes) { + /* Inline PyOS_FSPath() for better error messages. */ + PyObject *func, *res; + + func = _PyObject_LookupSpecial(o, &PyId___fspath__); + if (NULL == func) { + goto error_format; + } + res = _PyObject_CallNoArg(func); + Py_DECREF(func); + if (NULL == res) { + goto error_exit; + } + else if (PyUnicode_Check(res)) { + is_unicode = 1; + } + else if (PyBytes_Check(res)) { + is_bytes = 1; + } + else { + PyErr_Format(PyExc_TypeError, + "expected %.200s.__fspath__() to return str or bytes, " + "not %.200s", _PyType_Name(Py_TYPE(o)), + _PyType_Name(Py_TYPE(res))); + Py_DECREF(res); + goto error_exit; + } + + /* still owns a reference to the original object */ + Py_DECREF(o); + o = res; + } + + if (is_unicode) { +#ifdef MS_WINDOWS +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + wide = PyUnicode_AsUnicodeAndSize(o, &length); +_Py_COMP_DIAG_POP + if (!wide) { + goto error_exit; + } + if (length > 32767) { + FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); + goto error_exit; + } + if (wcslen(wide) != length) { + FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); + goto error_exit; + } + + path->wide = wide; + path->narrow = FALSE; + path->fd = -1; + goto success_exit; +#else + if (!PyUnicode_FSConverter(o, &bytes)) { + goto error_exit; + } +#endif + } + else if (is_bytes) { + bytes = o; + Py_INCREF(bytes); + } + else if (is_buffer) { + /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code + after removing support of non-bytes buffer objects. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "%s%s%s should be %s, not %.200s", + path->function_name ? path->function_name : "", + path->function_name ? ": " : "", + path->argument_name ? path->argument_name : "path", + path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " + "integer or None" : + path->allow_fd ? "string, bytes, os.PathLike or integer" : + path->nullable ? "string, bytes, os.PathLike or None" : + "string, bytes or os.PathLike", + _PyType_Name(Py_TYPE(o)))) { + goto error_exit; + } + bytes = PyBytes_FromObject(o); + if (!bytes) { + goto error_exit; + } + } + else if (is_index) { + if (!_fd_converter(o, &path->fd)) { + goto error_exit; + } + path->wide = NULL; +#ifdef MS_WINDOWS + path->narrow = FALSE; +#else + path->narrow = NULL; +#endif + goto success_exit; + } + else { + error_format: + PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s", + path->function_name ? path->function_name : "", + path->function_name ? ": " : "", + path->argument_name ? path->argument_name : "path", + path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " + "integer or None" : + path->allow_fd ? "string, bytes, os.PathLike or integer" : + path->nullable ? "string, bytes, os.PathLike or None" : + "string, bytes or os.PathLike", + _PyType_Name(Py_TYPE(o))); + goto error_exit; + } + + length = PyBytes_GET_SIZE(bytes); + narrow = PyBytes_AS_STRING(bytes); + if ((size_t)length != strlen(narrow)) { + FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); + goto error_exit; + } + +#ifdef MS_WINDOWS + wo = PyUnicode_DecodeFSDefaultAndSize( + narrow, + length + ); + if (!wo) { + goto error_exit; + } + +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + wide = PyUnicode_AsUnicodeAndSize(wo, &length); +_Py_COMP_DIAG_POP + if (!wide) { + goto error_exit; + } + if (length > 32767) { + FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); + goto error_exit; + } + if (wcslen(wide) != length) { + FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); + goto error_exit; + } + path->wide = wide; + path->narrow = TRUE; + path->cleanup = wo; + Py_DECREF(bytes); +#else + path->wide = NULL; + path->narrow = narrow; + if (bytes == o) { + /* Still a reference owned by path->object, don't have to + worry about path->narrow is used after free. */ + Py_DECREF(bytes); + } + else { + path->cleanup = bytes; + } +#endif + path->fd = -1; + + success_exit: + path->length = length; + path->object = o; + return Py_CLEANUP_SUPPORTED; + + error_exit: + Py_XDECREF(o); + Py_XDECREF(bytes); +#ifdef MS_WINDOWS + Py_XDECREF(wo); +#endif + return 0; +} + +static void +argument_unavailable_error(const char *function_name, const char *argument_name) +{ + PyErr_Format(PyExc_NotImplementedError, + "%s%s%s unavailable on this platform", + (function_name != NULL) ? function_name : "", + (function_name != NULL) ? ": ": "", + argument_name); +} + +static int +dir_fd_unavailable(PyObject *o, void *p) +{ + int dir_fd; + if (!dir_fd_converter(o, &dir_fd)) + return 0; + if (dir_fd != DEFAULT_DIR_FD) { + argument_unavailable_error(NULL, "dir_fd"); + return 0; + } + *(int *)p = dir_fd; + return 1; +} + +static int +fd_specified(const char *function_name, int fd) +{ + if (fd == -1) + return 0; + + argument_unavailable_error(function_name, "fd"); + return 1; +} + +static int +follow_symlinks_specified(const char *function_name, int follow_symlinks) +{ + if (follow_symlinks) + return 0; + + argument_unavailable_error(function_name, "follow_symlinks"); + return 1; +} + +static int +path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd) +{ + if (!path->wide && (dir_fd != DEFAULT_DIR_FD) +#ifndef MS_WINDOWS + && !path->narrow +#endif + ) { + PyErr_Format(PyExc_ValueError, + "%s: can't specify dir_fd without matching path", + function_name); + return 1; + } + return 0; +} + +static int +dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd) +{ + if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) { + PyErr_Format(PyExc_ValueError, + "%s: can't specify both dir_fd and fd", + function_name); + return 1; + } + return 0; +} + +static int +fd_and_follow_symlinks_invalid(const char *function_name, int fd, + int follow_symlinks) +{ + if ((fd > 0) && (!follow_symlinks)) { + PyErr_Format(PyExc_ValueError, + "%s: cannot use fd and follow_symlinks together", + function_name); + return 1; + } + return 0; +} + +static int +dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd, + int follow_symlinks) +{ + if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { + PyErr_Format(PyExc_ValueError, + "%s: cannot use dir_fd and follow_symlinks together", + function_name); + return 1; + } + return 0; +} + +#ifdef MS_WINDOWS + typedef long long Py_off_t; +#else + typedef off_t Py_off_t; +#endif + +static int +Py_off_t_converter(PyObject *arg, void *addr) +{ +#ifdef HAVE_LARGEFILE_SUPPORT + *((Py_off_t *)addr) = PyLong_AsLongLong(arg); +#else + *((Py_off_t *)addr) = PyLong_AsLong(arg); +#endif + if (PyErr_Occurred()) + return 0; + return 1; +} + +static PyObject * +PyLong_FromPy_off_t(Py_off_t offset) +{ +#ifdef HAVE_LARGEFILE_SUPPORT + return PyLong_FromLongLong(offset); +#else + return PyLong_FromLong(offset); +#endif +} + +#ifdef HAVE_SIGSET_T +/* Convert an iterable of integers to a sigset. + Return 1 on success, return 0 and raise an exception on error. */ int -_Py_Uid_Converter(PyObject *obj, uid_t *p) +_Py_Sigset_Converter(PyObject *obj, void *addr) { - uid_t uid; - PyObject *index; + sigset_t *mask = (sigset_t *)addr; + PyObject *iterator, *item; + long signum; int overflow; - long result; - unsigned long uresult; - index = PyNumber_Index(obj); - if (index == NULL) { - PyErr_Format(PyExc_TypeError, - "uid should be integer, not %.200s", - _PyType_Name(Py_TYPE(obj))); + // The extra parens suppress the unreachable-code warning with clang on MacOS + if (sigemptyset(mask) < (0)) { + /* Probably only if mask == NULL. */ + PyErr_SetFromErrno(PyExc_OSError); return 0; } - /* - * Handling uid_t is complicated for two reasons: - * * Although uid_t is (always?) unsigned, it still - * accepts -1. - * * We don't know its size in advance--it may be - * bigger than an int, or it may be smaller than - * a long. - * - * So a bit of defensive programming is in order. - * Start with interpreting the value passed - * in as a signed long and see if it works. - */ - - result = PyLong_AsLongAndOverflow(index, &overflow); - - if (!overflow) { - uid = (uid_t)result; + iterator = PyObject_GetIter(obj); + if (iterator == NULL) { + return 0; + } - if (result == -1) { - if (PyErr_Occurred()) - goto fail; - /* It's a legitimate -1, we're done. */ - goto success; + while ((item = PyIter_Next(iterator)) != NULL) { + signum = PyLong_AsLongAndOverflow(item, &overflow); + Py_DECREF(item); + if (signum <= 0 || signum >= NSIG) { + if (overflow || signum != -1 || !PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, + "signal number %ld out of range", signum); + } + goto error; + } + if (sigaddset(mask, (int)signum)) { + if (errno != EINVAL) { + /* Probably impossible */ + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + /* For backwards compatibility, allow idioms such as + * `range(1, NSIG)` but warn about invalid signal numbers + */ + const char msg[] = + "invalid signal number %ld, please use valid_signals()"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) { + goto error; + } } - - /* Any other negative number is disallowed. */ - if (result < 0) - goto underflow; - - /* Ensure the value wasn't truncated. */ - if (sizeof(uid_t) < sizeof(long) && - (long)uid != result) - goto underflow; - goto success; } - - if (overflow < 0) - goto underflow; - - /* - * Okay, the value overflowed a signed long. If it - * fits in an *unsigned* long, it may still be okay, - * as uid_t may be unsigned long on this platform. - */ - uresult = PyLong_AsUnsignedLong(index); - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - goto overflow; - goto fail; + if (!PyErr_Occurred()) { + Py_DECREF(iterator); + return 1; } - uid = (uid_t)uresult; - - /* - * If uid == (uid_t)-1, the user actually passed in ULONG_MAX, - * but this value would get interpreted as (uid_t)-1 by chown - * and its siblings. That's not what the user meant! So we - * throw an overflow exception instead. (We already - * handled a real -1 with PyLong_AsLongAndOverflow() above.) - */ - if (uid == (uid_t)-1) - goto overflow; - - /* Ensure the value wasn't truncated. */ - if (sizeof(uid_t) < sizeof(long) && - (unsigned long)uid != uresult) - goto overflow; - /* fallthrough */ - -success: - Py_DECREF(index); - *p = uid; - return 1; - -underflow: - PyErr_SetString(PyExc_OverflowError, - "uid is less than minimum"); - goto fail; - -overflow: - PyErr_SetString(PyExc_OverflowError, - "uid is greater than maximum"); - /* fallthrough */ - -fail: - Py_DECREF(index); +error: + Py_DECREF(iterator); return 0; } +#endif /* HAVE_SIGSET_T */ -int -_Py_Gid_Converter(PyObject *obj, gid_t *p) -{ - gid_t gid; - PyObject *index; - int overflow; - long result; - unsigned long uresult; - - index = PyNumber_Index(obj); - if (index == NULL) { - PyErr_Format(PyExc_TypeError, - "gid should be integer, not %.200s", - _PyType_Name(Py_TYPE(obj))); - return 0; - } - - /* - * Handling gid_t is complicated for two reasons: - * * Although gid_t is (always?) unsigned, it still - * accepts -1. - * * We don't know its size in advance--it may be - * bigger than an int, or it may be smaller than - * a long. - * - * So a bit of defensive programming is in order. - * Start with interpreting the value passed - * in as a signed long and see if it works. - */ - - result = PyLong_AsLongAndOverflow(index, &overflow); - - if (!overflow) { - gid = (gid_t)result; - - if (result == -1) { - if (PyErr_Occurred()) - goto fail; - /* It's a legitimate -1, we're done. */ - goto success; - } - - /* Any other negative number is disallowed. */ - if (result < 0) { - goto underflow; - } - - /* Ensure the value wasn't truncated. */ - if (sizeof(gid_t) < sizeof(long) && - (long)gid != result) - goto underflow; - goto success; - } - - if (overflow < 0) - goto underflow; - - /* - * Okay, the value overflowed a signed long. If it - * fits in an *unsigned* long, it may still be okay, - * as gid_t may be unsigned long on this platform. - */ - uresult = PyLong_AsUnsignedLong(index); - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - goto overflow; - goto fail; - } - - gid = (gid_t)uresult; - - /* - * If gid == (gid_t)-1, the user actually passed in ULONG_MAX, - * but this value would get interpreted as (gid_t)-1 by chown - * and its siblings. That's not what the user meant! So we - * throw an overflow exception instead. (We already - * handled a real -1 with PyLong_AsLongAndOverflow() above.) - */ - if (gid == (gid_t)-1) - goto overflow; - - /* Ensure the value wasn't truncated. */ - if (sizeof(gid_t) < sizeof(long) && - (unsigned long)gid != uresult) - goto overflow; - /* fallthrough */ - -success: - Py_DECREF(index); - *p = gid; - return 1; - -underflow: - PyErr_SetString(PyExc_OverflowError, - "gid is less than minimum"); - goto fail; - -overflow: - PyErr_SetString(PyExc_OverflowError, - "gid is greater than maximum"); - /* fallthrough */ - -fail: - Py_DECREF(index); - return 0; -} -#endif /* MS_WINDOWS */ - - -#define _PyLong_FromDev PyLong_FromLongLong - - -#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) -static int -_Py_Dev_Converter(PyObject *obj, void *p) -{ - *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); - if (PyErr_Occurred()) - return 0; - return 1; -} -#endif /* HAVE_MKNOD && HAVE_MAKEDEV */ - - -#ifdef AT_FDCWD -/* - * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965); - * without the int cast, the value gets interpreted as uint (4291925331), - * which doesn't play nicely with all the initializer lines in this file that - * look like this: - * int dir_fd = DEFAULT_DIR_FD; - */ -#define DEFAULT_DIR_FD (int)AT_FDCWD +#ifdef MS_WINDOWS + +static int +win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) +{ + char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; + DWORD n_bytes_returned; + + if (0 == DeviceIoControl( + reparse_point_handle, + FSCTL_GET_REPARSE_POINT, + NULL, 0, /* in buffer */ + target_buffer, sizeof(target_buffer), + &n_bytes_returned, + NULL)) /* we're not using OVERLAPPED_IO */ + return FALSE; + + if (reparse_tag) + *reparse_tag = rdb->ReparseTag; + + return TRUE; +} + +#endif /* MS_WINDOWS */ + +/* Return a dictionary corresponding to the POSIX environment table */ +#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) +/* On Darwin/MacOSX a shared library or framework has no access to +** environ directly, we must obtain it with _NSGetEnviron(). See also +** man environ(7). +*/ +#include +#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__)) +extern char **environ; +#endif /* !_MSC_VER */ + +static PyObject * +convertenviron(void) +{ + PyObject *d; +#ifdef MS_WINDOWS + wchar_t **e; +#else + char **e; +#endif + + d = PyDict_New(); + if (d == NULL) + return NULL; +#ifdef MS_WINDOWS + /* _wenviron must be initialized in this way if the program is started + through main() instead of wmain(). */ + _wgetenv(L""); + e = _wenviron; +#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) + /* environ is not accessible as an extern in a shared object on OSX; use + _NSGetEnviron to resolve it. The value changes if you add environment + variables between calls to Py_Initialize, so don't cache the value. */ + e = *_NSGetEnviron(); #else -#define DEFAULT_DIR_FD (-100) -#endif - -static int -_fd_converter(PyObject *o, int *p) -{ - int overflow; - long long_value; - - PyObject *index = PyNumber_Index(o); - if (index == NULL) { - return 0; - } - - assert(PyLong_Check(index)); - long_value = PyLong_AsLongAndOverflow(index, &overflow); - Py_DECREF(index); - assert(!PyErr_Occurred()); - if (overflow > 0 || long_value > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "fd is greater than maximum"); - return 0; - } - if (overflow < 0 || long_value < INT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "fd is less than minimum"); - return 0; - } - - *p = (int)long_value; - return 1; -} - -static int -dir_fd_converter(PyObject *o, void *p) -{ - if (o == Py_None) { - *(int *)p = DEFAULT_DIR_FD; - return 1; - } - else if (PyIndex_Check(o)) { - return _fd_converter(o, (int *)p); - } - else { - PyErr_Format(PyExc_TypeError, - "argument should be integer or None, not %.200s", - _PyType_Name(Py_TYPE(o))); - return 0; - } -} - -typedef struct { - PyObject *billion; - PyObject *DirEntryType; - PyObject *ScandirIteratorType; -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) - PyObject *SchedParamType; -#endif - PyObject *StatResultType; - PyObject *StatVFSResultType; - PyObject *TerminalSizeType; - PyObject *TimesResultType; - PyObject *UnameResultType; -#if defined(HAVE_WAITID) && !defined(__APPLE__) - PyObject *WaitidResultType; -#endif -#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) - PyObject *struct_rusage; + e = environ; #endif - PyObject *st_mode; -} _posixstate; - - -static inline _posixstate* -get_posix_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (_posixstate *)state; -} - -/* - * A PyArg_ParseTuple "converter" function - * that handles filesystem paths in the manner - * preferred by the os module. - * - * path_converter accepts (Unicode) strings and their - * subclasses, and bytes and their subclasses. What - * it does with the argument depends on the platform: - * - * * On Windows, if we get a (Unicode) string we - * extract the wchar_t * and return it; if we get - * bytes we decode to wchar_t * and return that. - * - * * On all other platforms, strings are encoded - * to bytes using PyUnicode_FSConverter, then we - * extract the char * from the bytes object and - * return that. - * - * path_converter also optionally accepts signed - * integers (representing open file descriptors) instead - * of path strings. - * - * Input fields: - * path.nullable - * If nonzero, the path is permitted to be None. - * path.allow_fd - * If nonzero, the path is permitted to be a file handle - * (a signed int) instead of a string. - * path.function_name - * If non-NULL, path_converter will use that as the name - * of the function in error messages. - * (If path.function_name is NULL it omits the function name.) - * path.argument_name - * If non-NULL, path_converter will use that as the name - * of the parameter in error messages. - * (If path.argument_name is NULL it uses "path".) - * - * Output fields: - * path.wide - * Points to the path if it was expressed as Unicode - * and was not encoded. (Only used on Windows.) - * path.narrow - * Points to the path if it was expressed as bytes, - * or it was Unicode and was encoded to bytes. (On Windows, - * is a non-zero integer if the path was expressed as bytes. - * The type is deliberately incompatible to prevent misuse.) - * path.fd - * Contains a file descriptor if path.accept_fd was true - * and the caller provided a signed integer instead of any - * sort of string. - * - * WARNING: if your "path" parameter is optional, and is - * unspecified, path_converter will never get called. - * So if you set allow_fd, you *MUST* initialize path.fd = -1 - * yourself! - * path.length - * The length of the path in characters, if specified as - * a string. - * path.object - * The original object passed in (if get a PathLike object, - * the result of PyOS_FSPath() is treated as the original object). - * Own a reference to the object. - * path.cleanup - * For internal use only. May point to a temporary object. - * (Pay no attention to the man behind the curtain.) - * - * At most one of path.wide or path.narrow will be non-NULL. - * If path was None and path.nullable was set, - * or if path was an integer and path.allow_fd was set, - * both path.wide and path.narrow will be NULL - * and path.length will be 0. - * - * path_converter takes care to not write to the path_t - * unless it's successful. However it must reset the - * "cleanup" field each time it's called. - * - * Use as follows: - * path_t path; - * memset(&path, 0, sizeof(path)); - * PyArg_ParseTuple(args, "O&", path_converter, &path); - * // ... use values from path ... - * path_cleanup(&path); - * - * (Note that if PyArg_Parse fails you don't need to call - * path_cleanup(). However it is safe to do so.) - */ -typedef struct { - const char *function_name; - const char *argument_name; - int nullable; - int allow_fd; - const wchar_t *wide; + if (e == NULL) + return d; + for (; *e != NULL; e++) { + PyObject *k; + PyObject *v; #ifdef MS_WINDOWS - BOOL narrow; + const wchar_t *p = wcschr(*e, L'='); #else - const char *narrow; + const char *p = strchr(*e, '='); #endif - int fd; - Py_ssize_t length; - PyObject *object; - PyObject *cleanup; -} path_t; - + if (p == NULL) + continue; #ifdef MS_WINDOWS -#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ - {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL} + k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e)); #else -#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ - {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} -#endif - -static void -path_cleanup(path_t *path) -{ - Py_CLEAR(path->object); - Py_CLEAR(path->cleanup); -} - -static int -path_converter(PyObject *o, void *p) -{ - path_t *path = (path_t *)p; - PyObject *bytes = NULL; - Py_ssize_t length = 0; - int is_index, is_buffer, is_bytes, is_unicode; - const char *narrow; -#ifdef MS_WINDOWS - PyObject *wo = NULL; - const wchar_t *wide; + k = PyBytes_FromStringAndSize(*e, (int)(p-*e)); #endif - -#define FORMAT_EXCEPTION(exc, fmt) \ - PyErr_Format(exc, "%s%s" fmt, \ - path->function_name ? path->function_name : "", \ - path->function_name ? ": " : "", \ - path->argument_name ? path->argument_name : "path") - - /* Py_CLEANUP_SUPPORTED support */ - if (o == NULL) { - path_cleanup(path); - return 1; - } - - /* Ensure it's always safe to call path_cleanup(). */ - path->object = path->cleanup = NULL; - /* path->object owns a reference to the original object */ - Py_INCREF(o); - - if ((o == Py_None) && path->nullable) { - path->wide = NULL; + if (k == NULL) { + Py_DECREF(d); + return NULL; + } #ifdef MS_WINDOWS - path->narrow = FALSE; -#else - path->narrow = NULL; + v = PyUnicode_FromWideChar(p+1, wcslen(p+1)); +#else + v = PyBytes_FromStringAndSize(p+1, strlen(p+1)); #endif - path->fd = -1; - goto success_exit; - } - - /* Only call this here so that we don't treat the return value of - os.fspath() as an fd or buffer. */ - is_index = path->allow_fd && PyIndex_Check(o); - is_buffer = PyObject_CheckBuffer(o); - is_bytes = PyBytes_Check(o); - is_unicode = PyUnicode_Check(o); - - if (!is_index && !is_buffer && !is_unicode && !is_bytes) { - /* Inline PyOS_FSPath() for better error messages. */ - PyObject *func, *res; - - func = _PyObject_LookupSpecial(o, &PyId___fspath__); - if (NULL == func) { - goto error_format; - } - res = _PyObject_CallNoArg(func); - Py_DECREF(func); - if (NULL == res) { - goto error_exit; - } - else if (PyUnicode_Check(res)) { - is_unicode = 1; - } - else if (PyBytes_Check(res)) { - is_bytes = 1; - } - else { - PyErr_Format(PyExc_TypeError, - "expected %.200s.__fspath__() to return str or bytes, " - "not %.200s", _PyType_Name(Py_TYPE(o)), - _PyType_Name(Py_TYPE(res))); - Py_DECREF(res); - goto error_exit; - } - - /* still owns a reference to the original object */ - Py_DECREF(o); - o = res; - } - - if (is_unicode) { -#ifdef MS_WINDOWS -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wide = PyUnicode_AsUnicodeAndSize(o, &length); -_Py_COMP_DIAG_POP - if (!wide) { - goto error_exit; - } - if (length > 32767) { - FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); - goto error_exit; - } - if (wcslen(wide) != length) { - FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); - goto error_exit; - } + if (v == NULL) { + Py_DECREF(k); + Py_DECREF(d); + return NULL; + } + if (PyDict_GetItemWithError(d, k) == NULL) { + if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) { + Py_DECREF(v); + Py_DECREF(k); + Py_DECREF(d); + return NULL; + } + } + Py_DECREF(k); + Py_DECREF(v); + } + return d; +} + +/* Set a POSIX-specific error from errno, and return NULL */ + +static PyObject * +posix_error(void) +{ + return PyErr_SetFromErrno(PyExc_OSError); +} + +#ifdef MS_WINDOWS +static PyObject * +win32_error(const char* function, const char* filename) +{ + /* XXX We should pass the function name along in the future. + (winreg.c also wants to pass the function name.) + This would however require an additional param to the + Windows error object, which is non-trivial. + */ + errno = GetLastError(); + if (filename) + return PyErr_SetFromWindowsErrWithFilename(errno, filename); + else + return PyErr_SetFromWindowsErr(errno); +} + +static PyObject * +win32_error_object_err(const char* function, PyObject* filename, DWORD err) +{ + /* XXX - see win32_error for comments on 'function' */ + if (filename) + return PyErr_SetExcFromWindowsErrWithFilenameObject( + PyExc_OSError, + err, + filename); + else + return PyErr_SetFromWindowsErr(err); +} + +static PyObject * +win32_error_object(const char* function, PyObject* filename) +{ + errno = GetLastError(); + return win32_error_object_err(function, filename, errno); +} - path->wide = wide; - path->narrow = FALSE; - path->fd = -1; - goto success_exit; -#else - if (!PyUnicode_FSConverter(o, &bytes)) { - goto error_exit; - } -#endif - } - else if (is_bytes) { - bytes = o; - Py_INCREF(bytes); - } - else if (is_buffer) { - /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code - after removing support of non-bytes buffer objects. */ - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "%s%s%s should be %s, not %.200s", - path->function_name ? path->function_name : "", - path->function_name ? ": " : "", - path->argument_name ? path->argument_name : "path", - path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " - "integer or None" : - path->allow_fd ? "string, bytes, os.PathLike or integer" : - path->nullable ? "string, bytes, os.PathLike or None" : - "string, bytes or os.PathLike", - _PyType_Name(Py_TYPE(o)))) { - goto error_exit; - } - bytes = PyBytes_FromObject(o); - if (!bytes) { - goto error_exit; +#endif /* MS_WINDOWS */ + +static PyObject * +posix_path_object_error(PyObject *path) +{ + return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); +} + +static PyObject * +path_object_error(PyObject *path) +{ +#ifdef MS_WINDOWS + return PyErr_SetExcFromWindowsErrWithFilenameObject( + PyExc_OSError, 0, path); +#else + return posix_path_object_error(path); +#endif +} + +static PyObject * +path_object_error2(PyObject *path, PyObject *path2) +{ +#ifdef MS_WINDOWS + return PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyExc_OSError, 0, path, path2); +#else + return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2); +#endif +} + +static PyObject * +path_error(path_t *path) +{ + return path_object_error(path->object); +} + +static PyObject * +posix_path_error(path_t *path) +{ + return posix_path_object_error(path->object); +} + +static PyObject * +path_error2(path_t *path, path_t *path2) +{ + return path_object_error2(path->object, path2->object); +} + + +/* POSIX generic methods */ + +static int +fildes_converter(PyObject *o, void *p) +{ + int fd; + int *pointer = (int *)p; + fd = PyObject_AsFileDescriptor(o); + if (fd < 0) + return 0; + *pointer = fd; + return 1; +} + +static PyObject * +posix_fildes_fd(int fd, int (*func)(int)) +{ + int res; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + res = (*func)(fd); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) + return (!async_err) ? posix_error() : NULL; + Py_RETURN_NONE; +} + + +#ifdef MS_WINDOWS +/* This is a reimplementation of the C library's chdir function, + but one that produces Win32 errors instead of DOS error codes. + chdir is essentially a wrapper around SetCurrentDirectory; however, + it also needs to set "magic" environment variables indicating + the per-drive current directory, which are of the form =: */ +static BOOL __stdcall +win32_wchdir(LPCWSTR path) +{ + wchar_t path_buf[MAX_PATH], *new_path = path_buf; + int result; + wchar_t env[4] = L"=x:"; + + if(!SetCurrentDirectoryW(path)) + return FALSE; + result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path); + if (!result) + return FALSE; + if (result > Py_ARRAY_LENGTH(path_buf)) { + new_path = PyMem_RawMalloc(result * sizeof(wchar_t)); + if (!new_path) { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + result = GetCurrentDirectoryW(result, new_path); + if (!result) { + PyMem_RawFree(new_path); + return FALSE; + } + } + int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 || + wcsncmp(new_path, L"//", 2) == 0); + if (!is_unc_like_path) { + env[1] = new_path[0]; + result = SetEnvironmentVariableW(env, new_path); + } + if (new_path != path_buf) + PyMem_RawFree(new_path); + return result ? TRUE : FALSE; +} +#endif + +#ifdef MS_WINDOWS +/* The CRT of Windows has a number of flaws wrt. its stat() implementation: + - time stamps are restricted to second resolution + - file modification times suffer from forth-and-back conversions between + UTC and local time + Therefore, we implement our own stat, based on the Win32 API directly. +*/ +#define HAVE_STAT_NSEC 1 +#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1 +#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1 + +static void +find_data_to_file_info(WIN32_FIND_DATAW *pFileData, + BY_HANDLE_FILE_INFORMATION *info, + ULONG *reparse_tag) +{ + memset(info, 0, sizeof(*info)); + info->dwFileAttributes = pFileData->dwFileAttributes; + info->ftCreationTime = pFileData->ftCreationTime; + info->ftLastAccessTime = pFileData->ftLastAccessTime; + info->ftLastWriteTime = pFileData->ftLastWriteTime; + info->nFileSizeHigh = pFileData->nFileSizeHigh; + info->nFileSizeLow = pFileData->nFileSizeLow; +/* info->nNumberOfLinks = 1; */ + if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + *reparse_tag = pFileData->dwReserved0; + else + *reparse_tag = 0; +} + +static BOOL +attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) +{ + HANDLE hFindFile; + WIN32_FIND_DATAW FileData; + LPCWSTR filename = pszFile; + size_t n = wcslen(pszFile); + if (n && (pszFile[n - 1] == L'\\' || pszFile[n - 1] == L'/')) { + // cannot use PyMem_Malloc here because we do not hold the GIL + filename = (LPCWSTR)malloc((n + 1) * sizeof(filename[0])); + wcsncpy_s((LPWSTR)filename, n + 1, pszFile, n); + while (--n > 0 && (filename[n] == L'\\' || filename[n] == L'/')) { + ((LPWSTR)filename)[n] = L'\0'; } - } - else if (is_index) { - if (!_fd_converter(o, &path->fd)) { - goto error_exit; + if (!n || (n == 1 && filename[1] == L':')) { + // Nothing left to query + free((void *)filename); + return FALSE; } - path->wide = NULL; -#ifdef MS_WINDOWS - path->narrow = FALSE; -#else - path->narrow = NULL; -#endif - goto success_exit; } - else { - error_format: - PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s", - path->function_name ? path->function_name : "", - path->function_name ? ": " : "", - path->argument_name ? path->argument_name : "path", - path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " - "integer or None" : - path->allow_fd ? "string, bytes, os.PathLike or integer" : - path->nullable ? "string, bytes, os.PathLike or None" : - "string, bytes or os.PathLike", - _PyType_Name(Py_TYPE(o))); - goto error_exit; + hFindFile = FindFirstFileW(filename, &FileData); + if (pszFile != filename) { + free((void *)filename); } - - length = PyBytes_GET_SIZE(bytes); - narrow = PyBytes_AS_STRING(bytes); - if ((size_t)length != strlen(narrow)) { - FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); - goto error_exit; + if (hFindFile == INVALID_HANDLE_VALUE) { + return FALSE; + } + FindClose(hFindFile); + find_data_to_file_info(&FileData, info, reparse_tag); + return TRUE; +} + +static int +win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, + BOOL traverse) +{ + HANDLE hFile; + BY_HANDLE_FILE_INFORMATION fileInfo; + FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 }; + DWORD fileType, error; + BOOL isUnhandledTag = FALSE; + int retval = 0; + + DWORD access = FILE_READ_ATTRIBUTES; + DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */ + if (!traverse) { + flags |= FILE_FLAG_OPEN_REPARSE_POINT; } + + hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + /* Either the path doesn't exist, or the caller lacks access. */ + error = GetLastError(); + switch (error) { + case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */ + case ERROR_SHARING_VIOLATION: /* It's a paging file. */ + /* Try reading the parent directory. */ + if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) { + /* Cannot read the parent directory. */ + SetLastError(error); + return -1; + } + if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + if (traverse || + !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) { + /* The stat call has to traverse but cannot, so fail. */ + SetLastError(error); + return -1; + } + } + break; -#ifdef MS_WINDOWS - wo = PyUnicode_DecodeFSDefaultAndSize( - narrow, - length - ); - if (!wo) { - goto error_exit; - } - -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wide = PyUnicode_AsUnicodeAndSize(wo, &length); -_Py_COMP_DIAG_POP - if (!wide) { - goto error_exit; - } - if (length > 32767) { - FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); - goto error_exit; - } - if (wcslen(wide) != length) { - FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); - goto error_exit; - } - path->wide = wide; - path->narrow = TRUE; - path->cleanup = wo; - Py_DECREF(bytes); -#else - path->wide = NULL; - path->narrow = narrow; - if (bytes == o) { - /* Still a reference owned by path->object, don't have to - worry about path->narrow is used after free. */ - Py_DECREF(bytes); - } - else { - path->cleanup = bytes; - } -#endif - path->fd = -1; - - success_exit: - path->length = length; - path->object = o; - return Py_CLEANUP_SUPPORTED; - - error_exit: - Py_XDECREF(o); - Py_XDECREF(bytes); -#ifdef MS_WINDOWS - Py_XDECREF(wo); -#endif - return 0; -} - -static void -argument_unavailable_error(const char *function_name, const char *argument_name) -{ - PyErr_Format(PyExc_NotImplementedError, - "%s%s%s unavailable on this platform", - (function_name != NULL) ? function_name : "", - (function_name != NULL) ? ": ": "", - argument_name); -} - -static int -dir_fd_unavailable(PyObject *o, void *p) -{ - int dir_fd; - if (!dir_fd_converter(o, &dir_fd)) - return 0; - if (dir_fd != DEFAULT_DIR_FD) { - argument_unavailable_error(NULL, "dir_fd"); - return 0; - } - *(int *)p = dir_fd; - return 1; -} - -static int -fd_specified(const char *function_name, int fd) -{ - if (fd == -1) - return 0; - - argument_unavailable_error(function_name, "fd"); - return 1; -} - -static int -follow_symlinks_specified(const char *function_name, int follow_symlinks) -{ - if (follow_symlinks) - return 0; - - argument_unavailable_error(function_name, "follow_symlinks"); - return 1; -} - -static int -path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd) -{ - if (!path->wide && (dir_fd != DEFAULT_DIR_FD) -#ifndef MS_WINDOWS - && !path->narrow -#endif - ) { - PyErr_Format(PyExc_ValueError, - "%s: can't specify dir_fd without matching path", - function_name); - return 1; - } - return 0; -} - -static int -dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd) -{ - if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) { - PyErr_Format(PyExc_ValueError, - "%s: can't specify both dir_fd and fd", - function_name); - return 1; - } - return 0; -} - -static int -fd_and_follow_symlinks_invalid(const char *function_name, int fd, - int follow_symlinks) -{ - if ((fd > 0) && (!follow_symlinks)) { - PyErr_Format(PyExc_ValueError, - "%s: cannot use fd and follow_symlinks together", - function_name); - return 1; - } - return 0; -} - -static int -dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd, - int follow_symlinks) -{ - if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { - PyErr_Format(PyExc_ValueError, - "%s: cannot use dir_fd and follow_symlinks together", - function_name); - return 1; - } - return 0; -} - -#ifdef MS_WINDOWS - typedef long long Py_off_t; -#else - typedef off_t Py_off_t; -#endif - -static int -Py_off_t_converter(PyObject *arg, void *addr) -{ -#ifdef HAVE_LARGEFILE_SUPPORT - *((Py_off_t *)addr) = PyLong_AsLongLong(arg); -#else - *((Py_off_t *)addr) = PyLong_AsLong(arg); -#endif - if (PyErr_Occurred()) - return 0; - return 1; -} - -static PyObject * -PyLong_FromPy_off_t(Py_off_t offset) -{ -#ifdef HAVE_LARGEFILE_SUPPORT - return PyLong_FromLongLong(offset); -#else - return PyLong_FromLong(offset); -#endif -} - -#ifdef HAVE_SIGSET_T -/* Convert an iterable of integers to a sigset. - Return 1 on success, return 0 and raise an exception on error. */ -int -_Py_Sigset_Converter(PyObject *obj, void *addr) -{ - sigset_t *mask = (sigset_t *)addr; - PyObject *iterator, *item; - long signum; - int overflow; - - // The extra parens suppress the unreachable-code warning with clang on MacOS - if (sigemptyset(mask) < (0)) { - /* Probably only if mask == NULL. */ - PyErr_SetFromErrno(PyExc_OSError); - return 0; - } - - iterator = PyObject_GetIter(obj); - if (iterator == NULL) { - return 0; - } - - while ((item = PyIter_Next(iterator)) != NULL) { - signum = PyLong_AsLongAndOverflow(item, &overflow); - Py_DECREF(item); - if (signum <= 0 || signum >= NSIG) { - if (overflow || signum != -1 || !PyErr_Occurred()) { - PyErr_Format(PyExc_ValueError, - "signal number %ld out of range", signum); + case ERROR_INVALID_PARAMETER: + /* \\.\con requires read or write access. */ + hFile = CreateFileW(path, access | GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, flags, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + SetLastError(error); + return -1; + } + break; + + case ERROR_CANT_ACCESS_FILE: + /* bpo37834: open unhandled reparse points if traverse fails. */ + if (traverse) { + traverse = FALSE; + isUnhandledTag = TRUE; + hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, + flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL); } - goto error; + if (hFile == INVALID_HANDLE_VALUE) { + SetLastError(error); + return -1; + } + break; + + default: + return -1; } - if (sigaddset(mask, (int)signum)) { - if (errno != EINVAL) { - /* Probably impossible */ - PyErr_SetFromErrno(PyExc_OSError); - goto error; + } + + if (hFile != INVALID_HANDLE_VALUE) { + /* Handle types other than files on disk. */ + fileType = GetFileType(hFile); + if (fileType != FILE_TYPE_DISK) { + if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) { + retval = -1; + goto cleanup; } - /* For backwards compatibility, allow idioms such as - * `range(1, NSIG)` but warn about invalid signal numbers - */ - const char msg[] = - "invalid signal number %ld, please use valid_signals()"; - if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) { - goto error; + DWORD fileAttributes = GetFileAttributesW(path); + memset(result, 0, sizeof(*result)); + if (fileAttributes != INVALID_FILE_ATTRIBUTES && + fileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + /* \\.\pipe\ or \\.\mailslot\ */ + result->st_mode = _S_IFDIR; + } else if (fileType == FILE_TYPE_CHAR) { + /* \\.\nul */ + result->st_mode = _S_IFCHR; + } else if (fileType == FILE_TYPE_PIPE) { + /* \\.\pipe\spam */ + result->st_mode = _S_IFIFO; } + /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */ + goto cleanup; } - } - if (!PyErr_Occurred()) { - Py_DECREF(iterator); - return 1; - } -error: - Py_DECREF(iterator); - return 0; -} -#endif /* HAVE_SIGSET_T */ + /* Query the reparse tag, and traverse a non-link. */ + if (!traverse) { + if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo, + &tagInfo, sizeof(tagInfo))) { + /* Allow devices that do not support FileAttributeTagInfo. */ + switch (GetLastError()) { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_FUNCTION: + case ERROR_NOT_SUPPORTED: + tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; + tagInfo.ReparseTag = 0; + break; + default: + retval = -1; + goto cleanup; + } + } else if (tagInfo.FileAttributes & + FILE_ATTRIBUTE_REPARSE_POINT) { + if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) { + if (isUnhandledTag) { + /* Traversing previously failed for either this link + or its target. */ + SetLastError(ERROR_CANT_ACCESS_FILE); + retval = -1; + goto cleanup; + } + /* Traverse a non-link, but not if traversing already failed + for an unhandled tag. */ + } else if (!isUnhandledTag) { + CloseHandle(hFile); + return win32_xstat_impl(path, result, TRUE); + } + } + } + + if (!GetFileInformationByHandle(hFile, &fileInfo)) { + switch (GetLastError()) { + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_FUNCTION: + case ERROR_NOT_SUPPORTED: + /* Volumes and physical disks are block devices, e.g. + \\.\C: and \\.\PhysicalDrive0. */ + memset(result, 0, sizeof(*result)); + result->st_mode = 0x6000; /* S_IFBLK */ + goto cleanup; + } + retval = -1; + goto cleanup; + } + } + + _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result); -#ifdef MS_WINDOWS - -static int -win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) -{ - char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; - DWORD n_bytes_returned; - - if (0 == DeviceIoControl( - reparse_point_handle, - FSCTL_GET_REPARSE_POINT, - NULL, 0, /* in buffer */ - target_buffer, sizeof(target_buffer), - &n_bytes_returned, - NULL)) /* we're not using OVERLAPPED_IO */ - return FALSE; - - if (reparse_tag) - *reparse_tag = rdb->ReparseTag; - - return TRUE; -} - -#endif /* MS_WINDOWS */ - -/* Return a dictionary corresponding to the POSIX environment table */ -#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) -/* On Darwin/MacOSX a shared library or framework has no access to -** environ directly, we must obtain it with _NSGetEnviron(). See also -** man environ(7). -*/ -#include -#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__)) -extern char **environ; -#endif /* !_MSC_VER */ - -static PyObject * -convertenviron(void) -{ - PyObject *d; -#ifdef MS_WINDOWS - wchar_t **e; -#else - char **e; -#endif - - d = PyDict_New(); - if (d == NULL) - return NULL; -#ifdef MS_WINDOWS - /* _wenviron must be initialized in this way if the program is started - through main() instead of wmain(). */ - _wgetenv(L""); - e = _wenviron; -#elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) - /* environ is not accessible as an extern in a shared object on OSX; use - _NSGetEnviron to resolve it. The value changes if you add environment - variables between calls to Py_Initialize, so don't cache the value. */ - e = *_NSGetEnviron(); -#else - e = environ; -#endif - if (e == NULL) - return d; - for (; *e != NULL; e++) { - PyObject *k; - PyObject *v; -#ifdef MS_WINDOWS - const wchar_t *p = wcschr(*e, L'='); -#else - const char *p = strchr(*e, '='); -#endif - if (p == NULL) - continue; -#ifdef MS_WINDOWS - k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e)); -#else - k = PyBytes_FromStringAndSize(*e, (int)(p-*e)); -#endif - if (k == NULL) { - Py_DECREF(d); - return NULL; - } -#ifdef MS_WINDOWS - v = PyUnicode_FromWideChar(p+1, wcslen(p+1)); -#else - v = PyBytes_FromStringAndSize(p+1, strlen(p+1)); -#endif - if (v == NULL) { - Py_DECREF(k); - Py_DECREF(d); - return NULL; - } - if (PyDict_GetItemWithError(d, k) == NULL) { - if (PyErr_Occurred() || PyDict_SetItem(d, k, v) != 0) { - Py_DECREF(v); - Py_DECREF(k); - Py_DECREF(d); - return NULL; - } - } - Py_DECREF(k); - Py_DECREF(v); - } - return d; -} - -/* Set a POSIX-specific error from errno, and return NULL */ - -static PyObject * -posix_error(void) -{ - return PyErr_SetFromErrno(PyExc_OSError); -} - -#ifdef MS_WINDOWS -static PyObject * -win32_error(const char* function, const char* filename) -{ - /* XXX We should pass the function name along in the future. - (winreg.c also wants to pass the function name.) - This would however require an additional param to the - Windows error object, which is non-trivial. - */ - errno = GetLastError(); - if (filename) - return PyErr_SetFromWindowsErrWithFilename(errno, filename); - else - return PyErr_SetFromWindowsErr(errno); -} - -static PyObject * -win32_error_object_err(const char* function, PyObject* filename, DWORD err) -{ - /* XXX - see win32_error for comments on 'function' */ - if (filename) - return PyErr_SetExcFromWindowsErrWithFilenameObject( - PyExc_OSError, - err, - filename); - else - return PyErr_SetFromWindowsErr(err); -} - -static PyObject * -win32_error_object(const char* function, PyObject* filename) -{ - errno = GetLastError(); - return win32_error_object_err(function, filename, errno); -} - -#endif /* MS_WINDOWS */ - -static PyObject * -posix_path_object_error(PyObject *path) -{ - return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); -} - -static PyObject * -path_object_error(PyObject *path) -{ -#ifdef MS_WINDOWS - return PyErr_SetExcFromWindowsErrWithFilenameObject( - PyExc_OSError, 0, path); -#else - return posix_path_object_error(path); -#endif -} - -static PyObject * -path_object_error2(PyObject *path, PyObject *path2) -{ -#ifdef MS_WINDOWS - return PyErr_SetExcFromWindowsErrWithFilenameObjects( - PyExc_OSError, 0, path, path2); -#else - return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2); -#endif -} - -static PyObject * -path_error(path_t *path) -{ - return path_object_error(path->object); -} - -static PyObject * -posix_path_error(path_t *path) -{ - return posix_path_object_error(path->object); -} - -static PyObject * -path_error2(path_t *path, path_t *path2) -{ - return path_object_error2(path->object, path2->object); -} - - -/* POSIX generic methods */ - -static int -fildes_converter(PyObject *o, void *p) -{ - int fd; - int *pointer = (int *)p; - fd = PyObject_AsFileDescriptor(o); - if (fd < 0) - return 0; - *pointer = fd; - return 1; -} - -static PyObject * -posix_fildes_fd(int fd, int (*func)(int)) -{ - int res; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - res = (*func)(fd); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (res != 0) - return (!async_err) ? posix_error() : NULL; - Py_RETURN_NONE; -} - - -#ifdef MS_WINDOWS -/* This is a reimplementation of the C library's chdir function, - but one that produces Win32 errors instead of DOS error codes. - chdir is essentially a wrapper around SetCurrentDirectory; however, - it also needs to set "magic" environment variables indicating - the per-drive current directory, which are of the form =: */ -static BOOL __stdcall -win32_wchdir(LPCWSTR path) -{ - wchar_t path_buf[MAX_PATH], *new_path = path_buf; - int result; - wchar_t env[4] = L"=x:"; - - if(!SetCurrentDirectoryW(path)) - return FALSE; - result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path); - if (!result) - return FALSE; - if (result > Py_ARRAY_LENGTH(path_buf)) { - new_path = PyMem_RawMalloc(result * sizeof(wchar_t)); - if (!new_path) { - SetLastError(ERROR_OUTOFMEMORY); - return FALSE; - } - result = GetCurrentDirectoryW(result, new_path); - if (!result) { - PyMem_RawFree(new_path); - return FALSE; - } - } - int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 || - wcsncmp(new_path, L"//", 2) == 0); - if (!is_unc_like_path) { - env[1] = new_path[0]; - result = SetEnvironmentVariableW(env, new_path); - } - if (new_path != path_buf) - PyMem_RawFree(new_path); - return result ? TRUE : FALSE; -} -#endif - -#ifdef MS_WINDOWS -/* The CRT of Windows has a number of flaws wrt. its stat() implementation: - - time stamps are restricted to second resolution - - file modification times suffer from forth-and-back conversions between - UTC and local time - Therefore, we implement our own stat, based on the Win32 API directly. -*/ -#define HAVE_STAT_NSEC 1 -#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1 -#define HAVE_STRUCT_STAT_ST_REPARSE_TAG 1 - -static void -find_data_to_file_info(WIN32_FIND_DATAW *pFileData, - BY_HANDLE_FILE_INFORMATION *info, - ULONG *reparse_tag) -{ - memset(info, 0, sizeof(*info)); - info->dwFileAttributes = pFileData->dwFileAttributes; - info->ftCreationTime = pFileData->ftCreationTime; - info->ftLastAccessTime = pFileData->ftLastAccessTime; - info->ftLastWriteTime = pFileData->ftLastWriteTime; - info->nFileSizeHigh = pFileData->nFileSizeHigh; - info->nFileSizeLow = pFileData->nFileSizeLow; -/* info->nNumberOfLinks = 1; */ - if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - *reparse_tag = pFileData->dwReserved0; - else - *reparse_tag = 0; -} - -static BOOL -attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) -{ - HANDLE hFindFile; - WIN32_FIND_DATAW FileData; - LPCWSTR filename = pszFile; - size_t n = wcslen(pszFile); - if (n && (pszFile[n - 1] == L'\\' || pszFile[n - 1] == L'/')) { - // cannot use PyMem_Malloc here because we do not hold the GIL - filename = (LPCWSTR)malloc((n + 1) * sizeof(filename[0])); - wcsncpy_s((LPWSTR)filename, n + 1, pszFile, n); - while (--n > 0 && (filename[n] == L'\\' || filename[n] == L'/')) { - ((LPWSTR)filename)[n] = L'\0'; - } - if (!n || (n == 1 && filename[1] == L':')) { - // Nothing left to query - free((void *)filename); - return FALSE; - } - } - hFindFile = FindFirstFileW(filename, &FileData); - if (pszFile != filename) { - free((void *)filename); - } - if (hFindFile == INVALID_HANDLE_VALUE) { - return FALSE; - } - FindClose(hFindFile); - find_data_to_file_info(&FileData, info, reparse_tag); - return TRUE; -} - -static int -win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, - BOOL traverse) -{ - HANDLE hFile; - BY_HANDLE_FILE_INFORMATION fileInfo; - FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 }; - DWORD fileType, error; - BOOL isUnhandledTag = FALSE; - int retval = 0; - - DWORD access = FILE_READ_ATTRIBUTES; - DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */ - if (!traverse) { - flags |= FILE_FLAG_OPEN_REPARSE_POINT; - } - - hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL); - if (hFile == INVALID_HANDLE_VALUE) { - /* Either the path doesn't exist, or the caller lacks access. */ - error = GetLastError(); - switch (error) { - case ERROR_ACCESS_DENIED: /* Cannot sync or read attributes. */ - case ERROR_SHARING_VIOLATION: /* It's a paging file. */ - /* Try reading the parent directory. */ - if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) { - /* Cannot read the parent directory. */ - SetLastError(error); - return -1; - } - if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - if (traverse || - !IsReparseTagNameSurrogate(tagInfo.ReparseTag)) { - /* The stat call has to traverse but cannot, so fail. */ - SetLastError(error); - return -1; - } - } - break; - - case ERROR_INVALID_PARAMETER: - /* \\.\con requires read or write access. */ - hFile = CreateFileW(path, access | GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, flags, NULL); - if (hFile == INVALID_HANDLE_VALUE) { - SetLastError(error); - return -1; - } - break; - - case ERROR_CANT_ACCESS_FILE: - /* bpo37834: open unhandled reparse points if traverse fails. */ - if (traverse) { - traverse = FALSE; - isUnhandledTag = TRUE; - hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, - flags | FILE_FLAG_OPEN_REPARSE_POINT, NULL); - } - if (hFile == INVALID_HANDLE_VALUE) { - SetLastError(error); - return -1; - } - break; - - default: - return -1; - } - } + if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + /* Fix the file execute permissions. This hack sets S_IEXEC if + the filename has an extension that is commonly used by files + that CreateProcessW can execute. A real implementation calls + GetSecurityInfo, OpenThreadToken/OpenProcessToken, and + AccessCheck to check for generic read, write, and execute + access. */ + const wchar_t *fileExtension = wcsrchr(path, '.'); + if (fileExtension) { + if (_wcsicmp(fileExtension, L".exe") == 0 || + _wcsicmp(fileExtension, L".bat") == 0 || + _wcsicmp(fileExtension, L".cmd") == 0 || + _wcsicmp(fileExtension, L".com") == 0) { + result->st_mode |= 0111; + } + } + } - if (hFile != INVALID_HANDLE_VALUE) { - /* Handle types other than files on disk. */ - fileType = GetFileType(hFile); - if (fileType != FILE_TYPE_DISK) { - if (fileType == FILE_TYPE_UNKNOWN && GetLastError() != 0) { - retval = -1; - goto cleanup; - } - DWORD fileAttributes = GetFileAttributesW(path); - memset(result, 0, sizeof(*result)); - if (fileAttributes != INVALID_FILE_ATTRIBUTES && - fileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - /* \\.\pipe\ or \\.\mailslot\ */ - result->st_mode = _S_IFDIR; - } else if (fileType == FILE_TYPE_CHAR) { - /* \\.\nul */ - result->st_mode = _S_IFCHR; - } else if (fileType == FILE_TYPE_PIPE) { - /* \\.\pipe\spam */ - result->st_mode = _S_IFIFO; - } - /* FILE_TYPE_UNKNOWN, e.g. \\.\mailslot\waitfor.exe\spam */ - goto cleanup; - } - - /* Query the reparse tag, and traverse a non-link. */ - if (!traverse) { - if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo, - &tagInfo, sizeof(tagInfo))) { - /* Allow devices that do not support FileAttributeTagInfo. */ - switch (GetLastError()) { - case ERROR_INVALID_PARAMETER: - case ERROR_INVALID_FUNCTION: - case ERROR_NOT_SUPPORTED: - tagInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; - tagInfo.ReparseTag = 0; - break; - default: - retval = -1; - goto cleanup; - } - } else if (tagInfo.FileAttributes & - FILE_ATTRIBUTE_REPARSE_POINT) { - if (IsReparseTagNameSurrogate(tagInfo.ReparseTag)) { - if (isUnhandledTag) { - /* Traversing previously failed for either this link - or its target. */ - SetLastError(ERROR_CANT_ACCESS_FILE); - retval = -1; - goto cleanup; - } - /* Traverse a non-link, but not if traversing already failed - for an unhandled tag. */ - } else if (!isUnhandledTag) { - CloseHandle(hFile); - return win32_xstat_impl(path, result, TRUE); - } - } - } - - if (!GetFileInformationByHandle(hFile, &fileInfo)) { - switch (GetLastError()) { - case ERROR_INVALID_PARAMETER: - case ERROR_INVALID_FUNCTION: - case ERROR_NOT_SUPPORTED: - /* Volumes and physical disks are block devices, e.g. - \\.\C: and \\.\PhysicalDrive0. */ - memset(result, 0, sizeof(*result)); - result->st_mode = 0x6000; /* S_IFBLK */ - goto cleanup; - } - retval = -1; - goto cleanup; - } - } - - _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result); - - if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - /* Fix the file execute permissions. This hack sets S_IEXEC if - the filename has an extension that is commonly used by files - that CreateProcessW can execute. A real implementation calls - GetSecurityInfo, OpenThreadToken/OpenProcessToken, and - AccessCheck to check for generic read, write, and execute - access. */ - const wchar_t *fileExtension = wcsrchr(path, '.'); - if (fileExtension) { - if (_wcsicmp(fileExtension, L".exe") == 0 || - _wcsicmp(fileExtension, L".bat") == 0 || - _wcsicmp(fileExtension, L".cmd") == 0 || - _wcsicmp(fileExtension, L".com") == 0) { - result->st_mode |= 0111; - } - } - } - -cleanup: +cleanup: if (hFile != INVALID_HANDLE_VALUE) { /* Preserve last error if we are failing */ error = retval ? GetLastError() : 0; if (!CloseHandle(hFile)) { retval = -1; } else if (retval) { - /* Restore last error */ - SetLastError(error); - } - } - - return retval; -} - -static int -win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) -{ - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - int code = win32_xstat_impl(path, result, traverse); - errno = 0; - return code; -} -/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w - - In Posix, stat automatically traverses symlinks and returns the stat - structure for the target. In Windows, the equivalent GetFileAttributes by - default does not traverse symlinks and instead returns attributes for - the symlink. - - Instead, we will open the file (which *does* traverse symlinks by default) - and GetFileInformationByHandle(). */ - -static int -win32_lstat(const wchar_t* path, struct _Py_stat_struct *result) -{ - return win32_xstat(path, result, FALSE); -} - -static int -win32_stat(const wchar_t* path, struct _Py_stat_struct *result) -{ - return win32_xstat(path, result, TRUE); -} - -#endif /* MS_WINDOWS */ - -PyDoc_STRVAR(stat_result__doc__, -"stat_result: Result from stat, fstat, or lstat.\n\n\ -This object may be accessed either as a tuple of\n\ - (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ -or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ -\n\ -Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\ -or st_flags, they are available as attributes only.\n\ -\n\ -See os.stat for more information."); - -static PyStructSequence_Field stat_result_fields[] = { - {"st_mode", "protection bits"}, - {"st_ino", "inode"}, - {"st_dev", "device"}, - {"st_nlink", "number of hard links"}, - {"st_uid", "user ID of owner"}, - {"st_gid", "group ID of owner"}, - {"st_size", "total size, in bytes"}, - /* The NULL is replaced with PyStructSequence_UnnamedField later. */ - {NULL, "integer time of last access"}, - {NULL, "integer time of last modification"}, - {NULL, "integer time of last change"}, - {"st_atime", "time of last access"}, - {"st_mtime", "time of last modification"}, - {"st_ctime", "time of last change"}, - {"st_atime_ns", "time of last access in nanoseconds"}, - {"st_mtime_ns", "time of last modification in nanoseconds"}, - {"st_ctime_ns", "time of last change in nanoseconds"}, -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - {"st_blksize", "blocksize for filesystem I/O"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_BLOCKS - {"st_blocks", "number of blocks allocated"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_RDEV - {"st_rdev", "device type (if inode device)"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_FLAGS - {"st_flags", "user defined flags for file"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_GEN - {"st_gen", "generation number"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME - {"st_birthtime", "time of creation"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES - {"st_file_attributes", "Windows file attribute bits"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_FSTYPE - {"st_fstype", "Type of filesystem"}, -#endif -#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG - {"st_reparse_tag", "Windows reparse tag"}, -#endif - {0} -}; - -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE -#define ST_BLKSIZE_IDX 16 -#else -#define ST_BLKSIZE_IDX 15 -#endif - -#ifdef HAVE_STRUCT_STAT_ST_BLOCKS -#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1) -#else -#define ST_BLOCKS_IDX ST_BLKSIZE_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_RDEV -#define ST_RDEV_IDX (ST_BLOCKS_IDX+1) -#else -#define ST_RDEV_IDX ST_BLOCKS_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_FLAGS -#define ST_FLAGS_IDX (ST_RDEV_IDX+1) -#else -#define ST_FLAGS_IDX ST_RDEV_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_GEN -#define ST_GEN_IDX (ST_FLAGS_IDX+1) -#else -#define ST_GEN_IDX ST_FLAGS_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME -#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1) -#else -#define ST_BIRTHTIME_IDX ST_GEN_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES -#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1) -#else -#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_FSTYPE -#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1) -#else -#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX -#endif - -#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG -#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1) -#else -#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX -#endif - -static PyStructSequence_Desc stat_result_desc = { - "stat_result", /* name */ - stat_result__doc__, /* doc */ - stat_result_fields, - 10 -}; - -PyDoc_STRVAR(statvfs_result__doc__, -"statvfs_result: Result from statvfs or fstatvfs.\n\n\ -This object may be accessed either as a tuple of\n\ - (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\ -or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\ -\n\ -See os.statvfs for more information."); - -static PyStructSequence_Field statvfs_result_fields[] = { - {"f_bsize", }, - {"f_frsize", }, - {"f_blocks", }, - {"f_bfree", }, - {"f_bavail", }, - {"f_files", }, - {"f_ffree", }, - {"f_favail", }, - {"f_flag", }, - {"f_namemax",}, - {"f_fsid", }, - {0} -}; - -static PyStructSequence_Desc statvfs_result_desc = { - "statvfs_result", /* name */ - statvfs_result__doc__, /* doc */ - statvfs_result_fields, - 10 -}; - -#if defined(HAVE_WAITID) && !defined(__APPLE__) -PyDoc_STRVAR(waitid_result__doc__, -"waitid_result: Result from waitid.\n\n\ -This object may be accessed either as a tuple of\n\ - (si_pid, si_uid, si_signo, si_status, si_code),\n\ -or via the attributes si_pid, si_uid, and so on.\n\ -\n\ -See os.waitid for more information."); - -static PyStructSequence_Field waitid_result_fields[] = { - {"si_pid", }, - {"si_uid", }, - {"si_signo", }, - {"si_status", }, - {"si_code", }, - {0} -}; - -static PyStructSequence_Desc waitid_result_desc = { - "waitid_result", /* name */ - waitid_result__doc__, /* doc */ - waitid_result_fields, - 5 -}; -#endif -static newfunc structseq_new; - -static PyObject * -statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyStructSequence *result; - int i; - - result = (PyStructSequence*)structseq_new(type, args, kwds); - if (!result) - return NULL; - /* If we have been initialized from a tuple, - st_?time might be set to None. Initialize it - from the int slots. */ - for (i = 7; i <= 9; i++) { - if (result->ob_item[i+3] == Py_None) { - Py_DECREF(Py_None); - Py_INCREF(result->ob_item[i]); - result->ob_item[i+3] = result->ob_item[i]; - } - } - return (PyObject*)result; -} - -static int -_posix_clear(PyObject *module) -{ - _posixstate *state = get_posix_state(module); - Py_CLEAR(state->billion); - Py_CLEAR(state->DirEntryType); - Py_CLEAR(state->ScandirIteratorType); -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) - Py_CLEAR(state->SchedParamType); -#endif - Py_CLEAR(state->StatResultType); - Py_CLEAR(state->StatVFSResultType); - Py_CLEAR(state->TerminalSizeType); - Py_CLEAR(state->TimesResultType); - Py_CLEAR(state->UnameResultType); -#if defined(HAVE_WAITID) && !defined(__APPLE__) - Py_CLEAR(state->WaitidResultType); -#endif -#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) - Py_CLEAR(state->struct_rusage); -#endif - Py_CLEAR(state->st_mode); - return 0; -} - -static int -_posix_traverse(PyObject *module, visitproc visit, void *arg) -{ - _posixstate *state = get_posix_state(module); - Py_VISIT(state->billion); - Py_VISIT(state->DirEntryType); - Py_VISIT(state->ScandirIteratorType); -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) - Py_VISIT(state->SchedParamType); -#endif - Py_VISIT(state->StatResultType); - Py_VISIT(state->StatVFSResultType); - Py_VISIT(state->TerminalSizeType); - Py_VISIT(state->TimesResultType); - Py_VISIT(state->UnameResultType); -#if defined(HAVE_WAITID) && !defined(__APPLE__) - Py_VISIT(state->WaitidResultType); -#endif -#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) - Py_VISIT(state->struct_rusage); -#endif - Py_VISIT(state->st_mode); - return 0; -} - -static void -_posix_free(void *module) -{ - _posix_clear((PyObject *)module); -} - -static void -fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec) -{ - PyObject *s = _PyLong_FromTime_t(sec); - PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec); - PyObject *s_in_ns = NULL; - PyObject *ns_total = NULL; - PyObject *float_s = NULL; - - if (!(s && ns_fractional)) - goto exit; - - s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion); - if (!s_in_ns) - goto exit; - - ns_total = PyNumber_Add(s_in_ns, ns_fractional); - if (!ns_total) - goto exit; - - float_s = PyFloat_FromDouble(sec + 1e-9*nsec); - if (!float_s) { - goto exit; - } - - PyStructSequence_SET_ITEM(v, index, s); - PyStructSequence_SET_ITEM(v, index+3, float_s); - PyStructSequence_SET_ITEM(v, index+6, ns_total); - s = NULL; - float_s = NULL; - ns_total = NULL; -exit: - Py_XDECREF(s); - Py_XDECREF(ns_fractional); - Py_XDECREF(s_in_ns); - Py_XDECREF(ns_total); - Py_XDECREF(float_s); -} - -/* pack a system stat C structure into the Python stat tuple - (used by posix_stat() and posix_fstat()) */ -static PyObject* -_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) -{ - unsigned long ansec, mnsec, cnsec; - PyObject *StatResultType = get_posix_state(module)->StatResultType; - PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType); - if (v == NULL) - return NULL; - - PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); - Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino)); - PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino)); -#ifdef MS_WINDOWS - PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); -#else - PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev)); -#endif - PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); -#if defined(MS_WINDOWS) - PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0)); - PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0)); -#else - PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid)); - PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid)); -#endif - Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size)); - PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size)); - -#if defined(HAVE_STAT_TV_NSEC) - ansec = st->st_atim.tv_nsec; - mnsec = st->st_mtim.tv_nsec; - cnsec = st->st_ctim.tv_nsec; -#elif defined(HAVE_STAT_TV_NSEC2) - ansec = st->st_atimespec.tv_nsec; - mnsec = st->st_mtimespec.tv_nsec; - cnsec = st->st_ctimespec.tv_nsec; -#elif defined(HAVE_STAT_NSEC) - ansec = st->st_atime_nsec; - mnsec = st->st_mtime_nsec; - cnsec = st->st_ctime_nsec; -#else - ansec = mnsec = cnsec = 0; -#endif - fill_time(module, v, 7, st->st_atime, ansec); - fill_time(module, v, 8, st->st_mtime, mnsec); - fill_time(module, v, 9, st->st_ctime, cnsec); - -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, - PyLong_FromLong((long)st->st_blksize)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_BLOCKS - PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, - PyLong_FromLong((long)st->st_blocks)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_RDEV - PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, - PyLong_FromLong((long)st->st_rdev)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_GEN - PyStructSequence_SET_ITEM(v, ST_GEN_IDX, - PyLong_FromLong((long)st->st_gen)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME - { - PyObject *val; - unsigned long bsec,bnsec; - bsec = (long)st->st_birthtime; -#ifdef HAVE_STAT_TV_NSEC2 - bnsec = st->st_birthtimespec.tv_nsec; -#else - bnsec = 0; -#endif - val = PyFloat_FromDouble(bsec + 1e-9*bnsec); - PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, - val); - } -#endif -#ifdef HAVE_STRUCT_STAT_ST_FLAGS - PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, - PyLong_FromLong((long)st->st_flags)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES - PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX, - PyLong_FromUnsignedLong(st->st_file_attributes)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_FSTYPE - PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX, - PyUnicode_FromString(st->st_fstype)); -#endif -#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG - PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX, - PyLong_FromUnsignedLong(st->st_reparse_tag)); -#endif - - if (PyErr_Occurred()) { - Py_DECREF(v); - return NULL; - } - - return v; -} - -/* POSIX methods */ - - -static PyObject * -posix_do_stat(PyObject *module, const char *function_name, path_t *path, - int dir_fd, int follow_symlinks) -{ - STRUCT_STAT st; - int result; - -#ifdef HAVE_FSTATAT - int fstatat_unavailable = 0; -#endif - -#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT) - if (follow_symlinks_specified(function_name, follow_symlinks)) - return NULL; -#endif - - if (path_and_dir_fd_invalid("stat", path, dir_fd) || - dir_fd_and_fd_invalid("stat", dir_fd, path->fd) || - fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - if (path->fd != -1) - result = FSTAT(path->fd, &st); -#ifdef MS_WINDOWS - else if (follow_symlinks) - result = win32_stat(path->wide, &st); - else - result = win32_lstat(path->wide, &st); -#else - else -#if defined(HAVE_LSTAT) - if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = LSTAT(path->narrow, &st); - else -#endif /* HAVE_LSTAT */ -#ifdef HAVE_FSTATAT - if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) { - if (HAVE_FSTATAT_RUNTIME) { - result = fstatat(dir_fd, path->narrow, &st, - follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); - - } else { - fstatat_unavailable = 1; - } - } else -#endif /* HAVE_FSTATAT */ - result = STAT(path->narrow, &st); -#endif /* MS_WINDOWS */ - Py_END_ALLOW_THREADS - -#ifdef HAVE_FSTATAT - if (fstatat_unavailable) { - argument_unavailable_error("stat", "dir_fd"); - return NULL; - } -#endif - - if (result != 0) { - return path_error(path); - } - - return _pystat_fromstructstat(module, &st); -} - -/*[python input] - -for s in """ - -FACCESSAT -FCHMODAT -FCHOWNAT -FSTATAT -LINKAT -MKDIRAT -MKFIFOAT -MKNODAT -OPENAT -READLINKAT -SYMLINKAT -UNLINKAT - -""".strip().split(): - s = s.strip() - print(""" -#ifdef HAVE_{s} - #define {s}_DIR_FD_CONVERTER dir_fd_converter -#else - #define {s}_DIR_FD_CONVERTER dir_fd_unavailable -#endif -""".rstrip().format(s=s)) - -for s in """ - -FCHDIR -FCHMOD -FCHOWN -FDOPENDIR -FEXECVE -FPATHCONF -FSTATVFS -FTRUNCATE - -""".strip().split(): - s = s.strip() - print(""" -#ifdef HAVE_{s} - #define PATH_HAVE_{s} 1 -#else - #define PATH_HAVE_{s} 0 -#endif - -""".rstrip().format(s=s)) -[python start generated code]*/ - -#ifdef HAVE_FACCESSAT - #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_FCHMODAT - #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_FCHOWNAT - #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_FSTATAT - #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_LINKAT - #define LINKAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_MKDIRAT - #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_MKFIFOAT - #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_MKNODAT - #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_OPENAT - #define OPENAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_READLINKAT - #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_SYMLINKAT - #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_UNLINKAT - #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#ifdef HAVE_FCHDIR - #define PATH_HAVE_FCHDIR 1 -#else - #define PATH_HAVE_FCHDIR 0 -#endif - -#ifdef HAVE_FCHMOD - #define PATH_HAVE_FCHMOD 1 -#else - #define PATH_HAVE_FCHMOD 0 -#endif - -#ifdef HAVE_FCHOWN - #define PATH_HAVE_FCHOWN 1 -#else - #define PATH_HAVE_FCHOWN 0 -#endif - -#ifdef HAVE_FDOPENDIR - #define PATH_HAVE_FDOPENDIR 1 -#else - #define PATH_HAVE_FDOPENDIR 0 -#endif - -#ifdef HAVE_FEXECVE - #define PATH_HAVE_FEXECVE 1 -#else - #define PATH_HAVE_FEXECVE 0 -#endif - -#ifdef HAVE_FPATHCONF - #define PATH_HAVE_FPATHCONF 1 -#else - #define PATH_HAVE_FPATHCONF 0 -#endif - -#ifdef HAVE_FSTATVFS - #define PATH_HAVE_FSTATVFS 1 -#else - #define PATH_HAVE_FSTATVFS 0 -#endif - -#ifdef HAVE_FTRUNCATE - #define PATH_HAVE_FTRUNCATE 1 -#else - #define PATH_HAVE_FTRUNCATE 0 -#endif -/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/ - -#ifdef MS_WINDOWS - #undef PATH_HAVE_FTRUNCATE - #define PATH_HAVE_FTRUNCATE 1 -#endif - -/*[python input] - -class path_t_converter(CConverter): - - type = "path_t" - impl_by_reference = True - parse_by_reference = True - - converter = 'path_converter' - - def converter_init(self, *, allow_fd=False, nullable=False): - # right now path_t doesn't support default values. - # to support a default value, you'll need to override initialize(). - if self.default not in (unspecified, None): - fail("Can't specify a default to the path_t converter!") - - if self.c_default not in (None, 'Py_None'): - raise RuntimeError("Can't specify a c_default to the path_t converter!") - - self.nullable = nullable - self.allow_fd = allow_fd - - def pre_render(self): - def strify(value): - if isinstance(value, str): - return value - return str(int(bool(value))) - - # add self.py_name here when merging with posixmodule conversion - self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format( - self.function.name, - self.name, - strify(self.nullable), - strify(self.allow_fd), - ) - - def cleanup(self): - return "path_cleanup(&" + self.name + ");\n" - - -class dir_fd_converter(CConverter): - type = 'int' - - def converter_init(self, requires=None): - if self.default in (unspecified, None): - self.c_default = 'DEFAULT_DIR_FD' - if isinstance(requires, str): - self.converter = requires.upper() + '_DIR_FD_CONVERTER' - else: - self.converter = 'dir_fd_converter' - -class fildes_converter(CConverter): - type = 'int' - converter = 'fildes_converter' - -class uid_t_converter(CConverter): - type = "uid_t" - converter = '_Py_Uid_Converter' - -class gid_t_converter(CConverter): - type = "gid_t" - converter = '_Py_Gid_Converter' - -class dev_t_converter(CConverter): - type = 'dev_t' - converter = '_Py_Dev_Converter' - -class dev_t_return_converter(unsigned_long_return_converter): - type = 'dev_t' - conversion_fn = '_PyLong_FromDev' - unsigned_cast = '(dev_t)' - -class FSConverter_converter(CConverter): - type = 'PyObject *' - converter = 'PyUnicode_FSConverter' - def converter_init(self): - if self.default is not unspecified: - fail("FSConverter_converter does not support default values") - self.c_default = 'NULL' - - def cleanup(self): - return "Py_XDECREF(" + self.name + ");\n" - -class pid_t_converter(CConverter): - type = 'pid_t' - format_unit = '" _Py_PARSE_PID "' - -class idtype_t_converter(int_converter): - type = 'idtype_t' - -class id_t_converter(CConverter): - type = 'id_t' - format_unit = '" _Py_PARSE_PID "' - -class intptr_t_converter(CConverter): - type = 'intptr_t' - format_unit = '" _Py_PARSE_INTPTR "' - -class Py_off_t_converter(CConverter): - type = 'Py_off_t' - converter = 'Py_off_t_converter' - -class Py_off_t_return_converter(long_return_converter): - type = 'Py_off_t' - conversion_fn = 'PyLong_FromPy_off_t' - -class path_confname_converter(CConverter): - type="int" - converter="conv_path_confname" - -class confstr_confname_converter(path_confname_converter): - converter='conv_confstr_confname' - -class sysconf_confname_converter(path_confname_converter): - converter="conv_sysconf_confname" - -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=f1c8ae8d744f6c8b]*/ - -/*[clinic input] - -os.stat - - path : path_t(allow_fd=True) - Path to be examined; can be string, bytes, a path-like object or - open-file-descriptor int. - - * - - dir_fd : dir_fd(requires='fstatat') = None - If not None, it should be a file descriptor open to a directory, - and path should be a relative string; path will then be relative to - that directory. - - follow_symlinks: bool = True - If False, and the last element of the path is a symbolic link, - stat will examine the symbolic link itself instead of the file - the link points to. - -Perform a stat system call on the given path. - -dir_fd and follow_symlinks may not be implemented - on your platform. If they are unavailable, using them will raise a - NotImplementedError. - -It's an error to use dir_fd or follow_symlinks when specifying path as - an open file descriptor. - -[clinic start generated code]*/ - -static PyObject * -os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/ -{ - return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks); -} - - -/*[clinic input] -os.lstat - - path : path_t - - * - - dir_fd : dir_fd(requires='fstatat') = None - -Perform a stat system call on the given path, without following symbolic links. - -Like stat(), but do not follow symbolic links. -Equivalent to stat(path, follow_symlinks=False). -[clinic start generated code]*/ - -static PyObject * -os_lstat_impl(PyObject *module, path_t *path, int dir_fd) -/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/ -{ - int follow_symlinks = 0; - return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks); -} - - -/*[clinic input] -os.access -> bool - - path: path_t - Path to be tested; can be string, bytes, or a path-like object. - - mode: int - Operating-system mode bitfield. Can be F_OK to test existence, - or the inclusive-OR of R_OK, W_OK, and X_OK. - - * - - dir_fd : dir_fd(requires='faccessat') = None - If not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that - directory. - - effective_ids: bool = False - If True, access will use the effective uid/gid instead of - the real uid/gid. - - follow_symlinks: bool = True - If False, and the last element of the path is a symbolic link, - access will examine the symbolic link itself instead of the file - the link points to. - -Use the real uid/gid to test for access to a path. - -{parameters} -dir_fd, effective_ids, and follow_symlinks may not be implemented - on your platform. If they are unavailable, using them will raise a - NotImplementedError. - -Note that most operations will use the effective uid/gid, therefore this - routine can be used in a suid/sgid environment to test if the invoking user - has the specified access to the path. - -[clinic start generated code]*/ - -static int -os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd, - int effective_ids, int follow_symlinks) -/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/ -{ - int return_value; - -#ifdef MS_WINDOWS - DWORD attr; -#else - int result; -#endif - -#ifdef HAVE_FACCESSAT - int faccessat_unavailable = 0; -#endif - -#ifndef HAVE_FACCESSAT - if (follow_symlinks_specified("access", follow_symlinks)) - return -1; - - if (effective_ids) { - argument_unavailable_error("access", "effective_ids"); - return -1; - } -#endif - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - attr = GetFileAttributesW(path->wide); - Py_END_ALLOW_THREADS - - /* - * Access is possible if - * * we didn't get a -1, and - * * write access wasn't requested, - * * or the file isn't read-only, - * * or it's a directory. - * (Directories cannot be read-only on Windows.) - */ - return_value = (attr != INVALID_FILE_ATTRIBUTES) && - (!(mode & 2) || - !(attr & FILE_ATTRIBUTE_READONLY) || - (attr & FILE_ATTRIBUTE_DIRECTORY)); -#else - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FACCESSAT - if ((dir_fd != DEFAULT_DIR_FD) || - effective_ids || - !follow_symlinks) { - - if (HAVE_FACCESSAT_RUNTIME) { - int flags = 0; - if (!follow_symlinks) - flags |= AT_SYMLINK_NOFOLLOW; - if (effective_ids) - flags |= AT_EACCESS; - result = faccessat(dir_fd, path->narrow, mode, flags); - } else { - faccessat_unavailable = 1; - } - } - else -#endif - result = access(path->narrow, mode); - Py_END_ALLOW_THREADS - -#ifdef HAVE_FACCESSAT - if (faccessat_unavailable) { - if (dir_fd != DEFAULT_DIR_FD) { - argument_unavailable_error("access", "dir_fd"); - return -1; - } - if (follow_symlinks_specified("access", follow_symlinks)) - return -1; - - if (effective_ids) { - argument_unavailable_error("access", "effective_ids"); - return -1; - } - /* should be unreachable */ - return -1; - } -#endif - return_value = !result; -#endif - - return return_value; -} - -#ifndef F_OK -#define F_OK 0 -#endif -#ifndef R_OK -#define R_OK 4 -#endif -#ifndef W_OK -#define W_OK 2 -#endif -#ifndef X_OK -#define X_OK 1 -#endif - - -#ifdef HAVE_TTYNAME -/*[clinic input] -os.ttyname - - fd: int - Integer file descriptor handle. - - / - -Return the name of the terminal device connected to 'fd'. -[clinic start generated code]*/ - -static PyObject * -os_ttyname_impl(PyObject *module, int fd) -/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/ -{ - - long size = sysconf(_SC_TTY_NAME_MAX); - if (size == -1) { - return posix_error(); - } - char *buffer = (char *)PyMem_RawMalloc(size); - if (buffer == NULL) { - return PyErr_NoMemory(); - } - int ret = ttyname_r(fd, buffer, size); - if (ret != 0) { - PyMem_RawFree(buffer); - errno = ret; - return posix_error(); - } - PyObject *res = PyUnicode_DecodeFSDefault(buffer); - PyMem_RawFree(buffer); - return res; -} -#endif - -#ifdef HAVE_CTERMID -/*[clinic input] -os.ctermid - -Return the name of the controlling terminal for this process. -[clinic start generated code]*/ - -static PyObject * -os_ctermid_impl(PyObject *module) -/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/ -{ - char *ret; - char buffer[L_ctermid]; - -#ifdef USE_CTERMID_R - ret = ctermid_r(buffer); -#else - ret = ctermid(buffer); -#endif - if (ret == NULL) - return posix_error(); - return PyUnicode_DecodeFSDefault(buffer); -} -#endif /* HAVE_CTERMID */ - - -/*[clinic input] -os.chdir - - path: path_t(allow_fd='PATH_HAVE_FCHDIR') - -Change the current working directory to the specified path. - -path may always be specified as a string. -On some platforms, path may also be specified as an open file descriptor. - If this functionality is unavailable, using it raises an exception. -[clinic start generated code]*/ - -static PyObject * -os_chdir_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/ -{ - int result; - - if (PySys_Audit("os.chdir", "(O)", path->object) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - /* on unix, success = 0, on windows, success = !0 */ - result = !win32_wchdir(path->wide); -#else -#ifdef HAVE_FCHDIR - if (path->fd != -1) - result = fchdir(path->fd); - else -#endif - result = chdir(path->narrow); -#endif - Py_END_ALLOW_THREADS - - if (result) { - return path_error(path); - } - - Py_RETURN_NONE; -} - - -#ifdef HAVE_FCHDIR -/*[clinic input] -os.fchdir - - fd: fildes - -Change to the directory of the given file descriptor. - -fd must be opened on a directory, not a file. -Equivalent to os.chdir(fd). - -[clinic start generated code]*/ - -static PyObject * -os_fchdir_impl(PyObject *module, int fd) -/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/ -{ - if (PySys_Audit("os.chdir", "(i)", fd) < 0) { - return NULL; - } - return posix_fildes_fd(fd, fchdir); -} -#endif /* HAVE_FCHDIR */ - - -/*[clinic input] -os.chmod - - path: path_t(allow_fd='PATH_HAVE_FCHMOD') - Path to be modified. May always be specified as a str, bytes, or a path-like object. - On some platforms, path may also be specified as an open file descriptor. - If this functionality is unavailable, using it raises an exception. - - mode: int - Operating-system mode bitfield. - - * - - dir_fd : dir_fd(requires='fchmodat') = None - If not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that - directory. - - follow_symlinks: bool = True - If False, and the last element of the path is a symbolic link, - chmod will modify the symbolic link itself instead of the file - the link points to. - -Change the access permissions of a file. - -It is an error to use dir_fd or follow_symlinks when specifying path as - an open file descriptor. -dir_fd and follow_symlinks may not be implemented on your platform. - If they are unavailable, using them will raise a NotImplementedError. - -[clinic start generated code]*/ - -static PyObject * -os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, - int follow_symlinks) -/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/ -{ - int result; - -#ifdef MS_WINDOWS - DWORD attr; -#endif - -#ifdef HAVE_FCHMODAT - int fchmodat_nofollow_unsupported = 0; - int fchmodat_unsupported = 0; -#endif - -#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD)) - if (follow_symlinks_specified("chmod", follow_symlinks)) - return NULL; -#endif - - if (PySys_Audit("os.chmod", "Oii", path->object, mode, - dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { - return NULL; - } - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - attr = GetFileAttributesW(path->wide); - if (attr == INVALID_FILE_ATTRIBUTES) - result = 0; - else { - if (mode & _S_IWRITE) - attr &= ~FILE_ATTRIBUTE_READONLY; - else - attr |= FILE_ATTRIBUTE_READONLY; - result = SetFileAttributesW(path->wide, attr); - } - Py_END_ALLOW_THREADS - - if (!result) { - return path_error(path); - } -#else /* MS_WINDOWS */ - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FCHMOD - if (path->fd != -1) - result = fchmod(path->fd, mode); - else -#endif /* HAVE_CHMOD */ -#ifdef HAVE_LCHMOD - if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = lchmod(path->narrow, mode); - else -#endif /* HAVE_LCHMOD */ -#ifdef HAVE_FCHMODAT - if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) { - if (HAVE_FCHMODAT_RUNTIME) { - /* - * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW! - * The documentation specifically shows how to use it, - * and then says it isn't implemented yet. - * (true on linux with glibc 2.15, and openindiana 3.x) - * - * Once it is supported, os.chmod will automatically - * support dir_fd and follow_symlinks=False. (Hopefully.) - * Until then, we need to be careful what exception we raise. - */ - result = fchmodat(dir_fd, path->narrow, mode, - follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); - /* - * But wait! We can't throw the exception without allowing threads, - * and we can't do that in this nested scope. (Macro trickery, sigh.) - */ - fchmodat_nofollow_unsupported = - result && - ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) && - !follow_symlinks; - } else { - fchmodat_unsupported = 1; - fchmodat_nofollow_unsupported = 1; - - result = -1; - } - } - else -#endif /* HAVE_FHCMODAT */ - result = chmod(path->narrow, mode); - Py_END_ALLOW_THREADS - - if (result) { -#ifdef HAVE_FCHMODAT - if (fchmodat_unsupported) { - if (dir_fd != DEFAULT_DIR_FD) { - argument_unavailable_error("chmod", "dir_fd"); - return NULL; - } - } - - if (fchmodat_nofollow_unsupported) { - if (dir_fd != DEFAULT_DIR_FD) - dir_fd_and_follow_symlinks_invalid("chmod", - dir_fd, follow_symlinks); - else - follow_symlinks_specified("chmod", follow_symlinks); - return NULL; - } - else -#endif /* HAVE_FCHMODAT */ - return path_error(path); - } -#endif /* MS_WINDOWS */ - - Py_RETURN_NONE; -} - - -#ifdef HAVE_FCHMOD -/*[clinic input] -os.fchmod - - fd: int - mode: int - -Change the access permissions of the file given by file descriptor fd. - -Equivalent to os.chmod(fd, mode). -[clinic start generated code]*/ - -static PyObject * -os_fchmod_impl(PyObject *module, int fd, int mode) -/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/ -{ - int res; - int async_err = 0; - - if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) { - return NULL; - } - - do { - Py_BEGIN_ALLOW_THREADS - res = fchmod(fd, mode); - Py_END_ALLOW_THREADS - } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (res != 0) - return (!async_err) ? posix_error() : NULL; - - Py_RETURN_NONE; -} -#endif /* HAVE_FCHMOD */ - - -#ifdef HAVE_LCHMOD -/*[clinic input] -os.lchmod - - path: path_t - mode: int - -Change the access permissions of a file, without following symbolic links. - -If path is a symlink, this affects the link itself rather than the target. -Equivalent to chmod(path, mode, follow_symlinks=False)." -[clinic start generated code]*/ - -static PyObject * -os_lchmod_impl(PyObject *module, path_t *path, int mode) -/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/ -{ - int res; - if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) { - return NULL; - } - Py_BEGIN_ALLOW_THREADS - res = lchmod(path->narrow, mode); - Py_END_ALLOW_THREADS - if (res < 0) { - path_error(path); - return NULL; - } - Py_RETURN_NONE; -} -#endif /* HAVE_LCHMOD */ - - -#ifdef HAVE_CHFLAGS -/*[clinic input] -os.chflags - - path: path_t - flags: unsigned_long(bitwise=True) - follow_symlinks: bool=True - -Set file flags. - -If follow_symlinks is False, and the last element of the path is a symbolic - link, chflags will change flags on the symbolic link itself instead of the - file the link points to. -follow_symlinks may not be implemented on your platform. If it is -unavailable, using it will raise a NotImplementedError. - -[clinic start generated code]*/ - -static PyObject * -os_chflags_impl(PyObject *module, path_t *path, unsigned long flags, - int follow_symlinks) -/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/ -{ - int result; - -#ifndef HAVE_LCHFLAGS - if (follow_symlinks_specified("chflags", follow_symlinks)) - return NULL; -#endif - - if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_LCHFLAGS - if (!follow_symlinks) - result = lchflags(path->narrow, flags); - else -#endif - result = chflags(path->narrow, flags); - Py_END_ALLOW_THREADS - - if (result) - return path_error(path); - - Py_RETURN_NONE; -} -#endif /* HAVE_CHFLAGS */ - - -#ifdef HAVE_LCHFLAGS -/*[clinic input] -os.lchflags - - path: path_t - flags: unsigned_long(bitwise=True) - -Set file flags. - -This function will not follow symbolic links. -Equivalent to chflags(path, flags, follow_symlinks=False). -[clinic start generated code]*/ - -static PyObject * -os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags) -/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/ -{ - int res; - if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) { - return NULL; - } - Py_BEGIN_ALLOW_THREADS - res = lchflags(path->narrow, flags); - Py_END_ALLOW_THREADS - if (res < 0) { - return path_error(path); - } - Py_RETURN_NONE; -} -#endif /* HAVE_LCHFLAGS */ - - -#ifdef HAVE_CHROOT -/*[clinic input] -os.chroot - path: path_t - -Change root directory to path. - -[clinic start generated code]*/ - -static PyObject * -os_chroot_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/ -{ - int res; - Py_BEGIN_ALLOW_THREADS - res = chroot(path->narrow); - Py_END_ALLOW_THREADS - if (res < 0) - return path_error(path); - Py_RETURN_NONE; -} -#endif /* HAVE_CHROOT */ - - -#ifdef HAVE_FSYNC -/*[clinic input] -os.fsync - - fd: fildes - -Force write of fd to disk. -[clinic start generated code]*/ - -static PyObject * -os_fsync_impl(PyObject *module, int fd) -/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/ -{ - return posix_fildes_fd(fd, fsync); -} -#endif /* HAVE_FSYNC */ - - -#ifdef HAVE_SYNC -/*[clinic input] -os.sync - -Force write of everything to disk. -[clinic start generated code]*/ - -static PyObject * -os_sync_impl(PyObject *module) -/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/ -{ - Py_BEGIN_ALLOW_THREADS - sync(); - Py_END_ALLOW_THREADS - Py_RETURN_NONE; -} -#endif /* HAVE_SYNC */ - - -#ifdef HAVE_FDATASYNC -#ifdef __hpux -extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ -#endif - -/*[clinic input] -os.fdatasync - - fd: fildes - -Force write of fd to disk without forcing update of metadata. -[clinic start generated code]*/ - -static PyObject * -os_fdatasync_impl(PyObject *module, int fd) -/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/ -{ - return posix_fildes_fd(fd, fdatasync); -} -#endif /* HAVE_FDATASYNC */ - - -#ifdef HAVE_CHOWN -/*[clinic input] -os.chown - - path : path_t(allow_fd='PATH_HAVE_FCHOWN') - Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int. - - uid: uid_t - - gid: gid_t - - * - - dir_fd : dir_fd(requires='fchownat') = None - If not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that - directory. - - follow_symlinks: bool = True - If False, and the last element of the path is a symbolic link, - stat will examine the symbolic link itself instead of the file - the link points to. - -Change the owner and group id of path to the numeric uid and gid.\ - -path may always be specified as a string. -On some platforms, path may also be specified as an open file descriptor. - If this functionality is unavailable, using it raises an exception. -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -If follow_symlinks is False, and the last element of the path is a symbolic - link, chown will modify the symbolic link itself instead of the file the - link points to. -It is an error to use dir_fd or follow_symlinks when specifying path as - an open file descriptor. -dir_fd and follow_symlinks may not be implemented on your platform. - If they are unavailable, using them will raise a NotImplementedError. - -[clinic start generated code]*/ - -static PyObject * -os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, - int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/ -{ - int result; - -#if defined(HAVE_FCHOWNAT) - int fchownat_unsupported = 0; -#endif - -#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT)) - if (follow_symlinks_specified("chown", follow_symlinks)) - return NULL; -#endif - if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) || - fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks)) - return NULL; - - if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, - dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FCHOWN - if (path->fd != -1) - result = fchown(path->fd, uid, gid); - else -#endif -#ifdef HAVE_LCHOWN - if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = lchown(path->narrow, uid, gid); - else -#endif -#ifdef HAVE_FCHOWNAT - if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) { - if (HAVE_FCHOWNAT_RUNTIME) { - result = fchownat(dir_fd, path->narrow, uid, gid, - follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); - } else { - fchownat_unsupported = 1; - } - } else -#endif - result = chown(path->narrow, uid, gid); - Py_END_ALLOW_THREADS - -#ifdef HAVE_FCHOWNAT - if (fchownat_unsupported) { - /* This would be incorrect if the current platform - * doesn't support lchown. - */ - argument_unavailable_error(NULL, "dir_fd"); - return NULL; - } -#endif - - if (result) - return path_error(path); - - Py_RETURN_NONE; -} -#endif /* HAVE_CHOWN */ - - -#ifdef HAVE_FCHOWN -/*[clinic input] -os.fchown - - fd: int - uid: uid_t - gid: gid_t - -Change the owner and group id of the file specified by file descriptor. - -Equivalent to os.chown(fd, uid, gid). - -[clinic start generated code]*/ - -static PyObject * -os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid) -/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/ -{ - int res; - int async_err = 0; - - if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) { - return NULL; - } - - do { - Py_BEGIN_ALLOW_THREADS - res = fchown(fd, uid, gid); - Py_END_ALLOW_THREADS - } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (res != 0) - return (!async_err) ? posix_error() : NULL; - - Py_RETURN_NONE; -} -#endif /* HAVE_FCHOWN */ - - -#ifdef HAVE_LCHOWN -/*[clinic input] -os.lchown - - path : path_t - uid: uid_t - gid: gid_t - -Change the owner and group id of path to the numeric uid and gid. - -This function will not follow symbolic links. -Equivalent to os.chown(path, uid, gid, follow_symlinks=False). -[clinic start generated code]*/ - -static PyObject * -os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid) -/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/ -{ - int res; - if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) { - return NULL; - } - Py_BEGIN_ALLOW_THREADS - res = lchown(path->narrow, uid, gid); - Py_END_ALLOW_THREADS - if (res < 0) { - return path_error(path); - } - Py_RETURN_NONE; -} -#endif /* HAVE_LCHOWN */ - - -static PyObject * -posix_getcwd(int use_bytes) -{ -#ifdef MS_WINDOWS - wchar_t wbuf[MAXPATHLEN]; - wchar_t *wbuf2 = wbuf; - DWORD len; - - Py_BEGIN_ALLOW_THREADS - len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); - /* If the buffer is large enough, len does not include the - terminating \0. If the buffer is too small, len includes - the space needed for the terminator. */ - if (len >= Py_ARRAY_LENGTH(wbuf)) { - if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) { - wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t)); - } - else { - wbuf2 = NULL; - } - if (wbuf2) { - len = GetCurrentDirectoryW(len, wbuf2); - } - } - Py_END_ALLOW_THREADS - - if (!wbuf2) { - PyErr_NoMemory(); - return NULL; - } - if (!len) { - if (wbuf2 != wbuf) - PyMem_RawFree(wbuf2); - return PyErr_SetFromWindowsErr(0); - } - - PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len); - if (wbuf2 != wbuf) { - PyMem_RawFree(wbuf2); - } - - if (use_bytes) { - if (resobj == NULL) { - return NULL; - } - Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj)); - } - - return resobj; -#else - const size_t chunk = 1024; - - char *buf = NULL; - char *cwd = NULL; - size_t buflen = 0; - - Py_BEGIN_ALLOW_THREADS - do { - char *newbuf; - if (buflen <= PY_SSIZE_T_MAX - chunk) { - buflen += chunk; - newbuf = PyMem_RawRealloc(buf, buflen); - } - else { - newbuf = NULL; - } - if (newbuf == NULL) { - PyMem_RawFree(buf); - buf = NULL; - break; - } - buf = newbuf; - - cwd = getcwd(buf, buflen); - } while (cwd == NULL && errno == ERANGE); - Py_END_ALLOW_THREADS - - if (buf == NULL) { - return PyErr_NoMemory(); - } - if (cwd == NULL) { - PyMem_RawFree(buf); - return posix_error(); - } - - PyObject *obj; - if (use_bytes) { - obj = PyBytes_FromStringAndSize(buf, strlen(buf)); - } - else { - obj = PyUnicode_DecodeFSDefault(buf); - } - PyMem_RawFree(buf); - - return obj; -#endif /* !MS_WINDOWS */ -} - - -/*[clinic input] -os.getcwd - -Return a unicode string representing the current working directory. -[clinic start generated code]*/ - -static PyObject * -os_getcwd_impl(PyObject *module) -/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/ -{ - return posix_getcwd(0); -} - - -/*[clinic input] -os.getcwdb - -Return a bytes string representing the current working directory. -[clinic start generated code]*/ - -static PyObject * -os_getcwdb_impl(PyObject *module) -/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/ -{ - return posix_getcwd(1); -} - - -#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS)) -#define HAVE_LINK 1 -#endif - -#ifdef HAVE_LINK -/*[clinic input] - -os.link - - src : path_t - dst : path_t - * - src_dir_fd : dir_fd = None - dst_dir_fd : dir_fd = None - follow_symlinks: bool = True - -Create a hard link to a file. - -If either src_dir_fd or dst_dir_fd is not None, it should be a file - descriptor open to a directory, and the respective path string (src or dst) - should be relative; the path will then be relative to that directory. -If follow_symlinks is False, and the last element of src is a symbolic - link, link will create a link to the symbolic link itself instead of the - file the link points to. -src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your - platform. If they are unavailable, using them will raise a - NotImplementedError. -[clinic start generated code]*/ - -static PyObject * -os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, - int dst_dir_fd, int follow_symlinks) -/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/ -{ -#ifdef MS_WINDOWS - BOOL result = FALSE; -#else - int result; -#endif -#if defined(HAVE_LINKAT) - int linkat_unavailable = 0; -#endif - -#ifndef HAVE_LINKAT - if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) { - argument_unavailable_error("link", "src_dir_fd and dst_dir_fd"); - return NULL; - } -#endif - -#ifndef MS_WINDOWS - if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { - PyErr_SetString(PyExc_NotImplementedError, - "link: src and dst must be the same type"); - return NULL; - } -#endif - - if (PySys_Audit("os.link", "OOii", src->object, dst->object, - src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd, - dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) { - return NULL; - } - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - result = CreateHardLinkW(dst->wide, src->wide, NULL); - Py_END_ALLOW_THREADS - - if (!result) - return path_error2(src, dst); -#else - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_LINKAT - if ((src_dir_fd != DEFAULT_DIR_FD) || - (dst_dir_fd != DEFAULT_DIR_FD) || - (!follow_symlinks)) { - - if (HAVE_LINKAT_RUNTIME) { - - result = linkat(src_dir_fd, src->narrow, - dst_dir_fd, dst->narrow, - follow_symlinks ? AT_SYMLINK_FOLLOW : 0); - - } -#ifdef __APPLE__ - else { - if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) { - /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */ - result = link(src->narrow, dst->narrow); - } else { - linkat_unavailable = 1; - } - } -#endif - } - else -#endif /* HAVE_LINKAT */ - result = link(src->narrow, dst->narrow); - Py_END_ALLOW_THREADS - -#ifdef HAVE_LINKAT - if (linkat_unavailable) { - /* Either or both dir_fd arguments were specified */ - if (src_dir_fd != DEFAULT_DIR_FD) { - argument_unavailable_error("link", "src_dir_fd"); - } else { - argument_unavailable_error("link", "dst_dir_fd"); - } - return NULL; - } -#endif - - if (result) - return path_error2(src, dst); -#endif /* MS_WINDOWS */ - - Py_RETURN_NONE; -} -#endif - - -#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) -static PyObject * -_listdir_windows_no_opendir(path_t *path, PyObject *list) -{ - PyObject *v; - HANDLE hFindFile = INVALID_HANDLE_VALUE; - BOOL result; - wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */ - /* only claim to have space for MAX_PATH */ - Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4; - wchar_t *wnamebuf = NULL; - - WIN32_FIND_DATAW wFileData; - const wchar_t *po_wchars; - - if (!path->wide) { /* Default arg: "." */ - po_wchars = L"."; - len = 1; - } else { - po_wchars = path->wide; - len = wcslen(path->wide); - } - /* The +5 is so we can append "\\*.*\0" */ - wnamebuf = PyMem_New(wchar_t, len + 5); - if (!wnamebuf) { - PyErr_NoMemory(); - goto exit; - } - wcscpy(wnamebuf, po_wchars); - if (len > 0) { - wchar_t wch = wnamebuf[len-1]; - if (wch != SEP && wch != ALTSEP && wch != L':') - wnamebuf[len++] = SEP; - wcscpy(wnamebuf + len, L"*.*"); - } - if ((list = PyList_New(0)) == NULL) { - goto exit; - } - Py_BEGIN_ALLOW_THREADS - hFindFile = FindFirstFileW(wnamebuf, &wFileData); - Py_END_ALLOW_THREADS - if (hFindFile == INVALID_HANDLE_VALUE) { - int error = GetLastError(); - if (error == ERROR_FILE_NOT_FOUND) - goto exit; - Py_DECREF(list); - list = path_error(path); - goto exit; - } - do { - /* Skip over . and .. */ - if (wcscmp(wFileData.cFileName, L".") != 0 && - wcscmp(wFileData.cFileName, L"..") != 0) { - v = PyUnicode_FromWideChar(wFileData.cFileName, - wcslen(wFileData.cFileName)); - if (path->narrow && v) { - Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); - } - if (v == NULL) { - Py_DECREF(list); - list = NULL; - break; - } - if (PyList_Append(list, v) != 0) { - Py_DECREF(v); - Py_DECREF(list); - list = NULL; - break; - } - Py_DECREF(v); - } - Py_BEGIN_ALLOW_THREADS - result = FindNextFileW(hFindFile, &wFileData); - Py_END_ALLOW_THREADS - /* FindNextFile sets error to ERROR_NO_MORE_FILES if - it got to the end of the directory. */ - if (!result && GetLastError() != ERROR_NO_MORE_FILES) { - Py_DECREF(list); - list = path_error(path); - goto exit; - } - } while (result == TRUE); - -exit: - if (hFindFile != INVALID_HANDLE_VALUE) { - if (FindClose(hFindFile) == FALSE) { - if (list != NULL) { - Py_DECREF(list); - list = path_error(path); - } - } - } - PyMem_Free(wnamebuf); - - return list; -} /* end of _listdir_windows_no_opendir */ - -#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */ - -static PyObject * -_posix_listdir(path_t *path, PyObject *list) -{ - PyObject *v; - DIR *dirp = NULL; - struct dirent *ep; - int return_str; /* if false, return bytes */ -#ifdef HAVE_FDOPENDIR - int fd = -1; -#endif - - errno = 0; -#ifdef HAVE_FDOPENDIR - if (path->fd != -1) { - if (HAVE_FDOPENDIR_RUNTIME) { - /* closedir() closes the FD, so we duplicate it */ - fd = _Py_dup(path->fd); - if (fd == -1) - return NULL; - - return_str = 1; - - Py_BEGIN_ALLOW_THREADS - dirp = fdopendir(fd); - Py_END_ALLOW_THREADS - } else { - PyErr_SetString(PyExc_TypeError, - "listdir: path should be string, bytes, os.PathLike or None, not int"); - return NULL; - } - } - else -#endif - { - const char *name; - if (path->narrow) { - name = path->narrow; - /* only return bytes if they specified a bytes-like object */ - return_str = !PyObject_CheckBuffer(path->object); - } - else { - name = "."; - return_str = 1; - } - - Py_BEGIN_ALLOW_THREADS - dirp = opendir(name); - Py_END_ALLOW_THREADS - } - - if (dirp == NULL) { - list = path_error(path); -#ifdef HAVE_FDOPENDIR - if (fd != -1) { - Py_BEGIN_ALLOW_THREADS - close(fd); - Py_END_ALLOW_THREADS - } -#endif - goto exit; - } - if ((list = PyList_New(0)) == NULL) { - goto exit; - } - for (;;) { - errno = 0; - Py_BEGIN_ALLOW_THREADS - ep = readdir(dirp); - Py_END_ALLOW_THREADS - if (ep == NULL) { - if (errno == 0) { - break; - } else { - Py_DECREF(list); - list = path_error(path); - goto exit; - } - } - if (ep->d_name[0] == '.' && - (NAMLEN(ep) == 1 || - (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) - continue; - if (return_str) - v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep)); - else - v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep)); - if (v == NULL) { - Py_CLEAR(list); - break; - } - if (PyList_Append(list, v) != 0) { - Py_DECREF(v); - Py_CLEAR(list); - break; - } - Py_DECREF(v); - } - -exit: - if (dirp != NULL) { - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FDOPENDIR - if (fd > -1) - rewinddir(dirp); -#endif - closedir(dirp); - Py_END_ALLOW_THREADS - } - - return list; -} /* end of _posix_listdir */ -#endif /* which OS */ - - -/*[clinic input] -os.listdir - - path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None - -Return a list containing the names of the files in the directory. - -path can be specified as either str, bytes, or a path-like object. If path is bytes, - the filenames returned will also be bytes; in all other circumstances - the filenames returned will be str. -If path is None, uses the path='.'. -On some platforms, path may also be specified as an open file descriptor;\ - the file descriptor must refer to a directory. - If this functionality is unavailable, using it raises NotImplementedError. - -The list is in arbitrary order. It does not include the special -entries '.' and '..' even if they are present in the directory. - - -[clinic start generated code]*/ - -static PyObject * -os_listdir_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/ -{ - if (PySys_Audit("os.listdir", "O", - path->object ? path->object : Py_None) < 0) { - return NULL; - } -#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) - return _listdir_windows_no_opendir(path, NULL); -#else - return _posix_listdir(path, NULL); -#endif -} - -#ifdef MS_WINDOWS -/* A helper function for abspath on win32 */ -/*[clinic input] -os._getfullpathname - - path: path_t - / - -[clinic start generated code]*/ - -static PyObject * -os__getfullpathname_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/ -{ - wchar_t *abspath; - - /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */ - if (_Py_abspath(path->wide, &abspath) < 0) { - return win32_error_object("GetFullPathNameW", path->object); - } - if (abspath == NULL) { - return PyErr_NoMemory(); - } - - PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath)); - PyMem_RawFree(abspath); - if (str == NULL) { - return NULL; - } - if (path->narrow) { - Py_SETREF(str, PyUnicode_EncodeFSDefault(str)); - } - return str; -} - - -/*[clinic input] -os._getfinalpathname - - path: path_t - / - -A helper function for samepath on windows. -[clinic start generated code]*/ - -static PyObject * -os__getfinalpathname_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/ -{ - HANDLE hFile; - wchar_t buf[MAXPATHLEN], *target_path = buf; - int buf_size = Py_ARRAY_LENGTH(buf); - int result_length; - PyObject *result; - - Py_BEGIN_ALLOW_THREADS - hFile = CreateFileW( - path->wide, - 0, /* desired access */ - 0, /* share mode */ - NULL, /* security attributes */ - OPEN_EXISTING, - /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - Py_END_ALLOW_THREADS - - if (hFile == INVALID_HANDLE_VALUE) { - return win32_error_object("CreateFileW", path->object); - } - - /* We have a good handle to the target, use it to determine the - target path name. */ - while (1) { - Py_BEGIN_ALLOW_THREADS - result_length = GetFinalPathNameByHandleW(hFile, target_path, - buf_size, VOLUME_NAME_DOS); - Py_END_ALLOW_THREADS - - if (!result_length) { - result = win32_error_object("GetFinalPathNameByHandleW", - path->object); - goto cleanup; - } - - if (result_length < buf_size) { - break; - } - - wchar_t *tmp; - tmp = PyMem_Realloc(target_path != buf ? target_path : NULL, - result_length * sizeof(*tmp)); - if (!tmp) { - result = PyErr_NoMemory(); - goto cleanup; - } - - buf_size = result_length; - target_path = tmp; - } - - result = PyUnicode_FromWideChar(target_path, result_length); - if (result && path->narrow) { - Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); - } - -cleanup: - if (target_path != buf) { - PyMem_Free(target_path); - } - CloseHandle(hFile); - return result; -} - - -/*[clinic input] -os._getvolumepathname - - path: path_t - -A helper function for ismount on Win32. -[clinic start generated code]*/ - -static PyObject * -os__getvolumepathname_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/ -{ - PyObject *result; - wchar_t *mountpath=NULL; - size_t buflen; - BOOL ret; - - /* Volume path should be shorter than entire path */ - buflen = Py_MAX(path->length, MAX_PATH); - - if (buflen > PY_DWORD_MAX) { - PyErr_SetString(PyExc_OverflowError, "path too long"); - return NULL; - } - - mountpath = PyMem_New(wchar_t, buflen); - if (mountpath == NULL) - return PyErr_NoMemory(); - - Py_BEGIN_ALLOW_THREADS - ret = GetVolumePathNameW(path->wide, mountpath, - Py_SAFE_DOWNCAST(buflen, size_t, DWORD)); - Py_END_ALLOW_THREADS - - if (!ret) { - result = win32_error_object("_getvolumepathname", path->object); - goto exit; - } - result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); - if (path->narrow) - Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); - -exit: - PyMem_Free(mountpath); - return result; -} - - -/*[clinic input] -os._path_splitroot - - path: path_t - -Removes everything after the root on Win32. -[clinic start generated code]*/ - -static PyObject * -os__path_splitroot_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=ab7f1a88b654581c input=dc93b1d3984cffb6]*/ -{ - wchar_t *buffer; - wchar_t *end; - PyObject *result = NULL; - HRESULT ret; - - buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * (wcslen(path->wide) + 1)); - if (!buffer) { - return NULL; - } - wcscpy(buffer, path->wide); - for (wchar_t *p = wcschr(buffer, L'/'); p; p = wcschr(p, L'/')) { - *p = L'\\'; - } - - Py_BEGIN_ALLOW_THREADS - ret = PathCchSkipRoot(buffer, &end); - Py_END_ALLOW_THREADS - if (FAILED(ret)) { - result = Py_BuildValue("sO", "", path->object); - } else if (end != buffer) { - size_t rootLen = (size_t)(end - buffer); - result = Py_BuildValue("NN", - PyUnicode_FromWideChar(path->wide, rootLen), - PyUnicode_FromWideChar(path->wide + rootLen, -1) - ); - } else { - result = Py_BuildValue("Os", path->object, ""); - } - PyMem_Free(buffer); - - return result; -} - - -#endif /* MS_WINDOWS */ - - -/*[clinic input] -os.mkdir - - path : path_t - - mode: int = 0o777 - - * - - dir_fd : dir_fd(requires='mkdirat') = None - -# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\ - -Create a directory. - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. - -The mode argument is ignored on Windows. -[clinic start generated code]*/ - -static PyObject * -os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) -/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/ -{ - int result; -#ifdef HAVE_MKDIRAT - int mkdirat_unavailable = 0; -#endif - - if (PySys_Audit("os.mkdir", "Oii", path->object, mode, - dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { - return NULL; - } - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - result = CreateDirectoryW(path->wide, NULL); - Py_END_ALLOW_THREADS - - if (!result) - return path_error(path); -#else - Py_BEGIN_ALLOW_THREADS -#if HAVE_MKDIRAT - if (dir_fd != DEFAULT_DIR_FD) { - if (HAVE_MKDIRAT_RUNTIME) { - result = mkdirat(dir_fd, path->narrow, mode); - - } else { - mkdirat_unavailable = 1; - } - } else -#endif -#if defined(__WATCOMC__) && !defined(__QNX__) - result = mkdir(path->narrow); -#else - result = mkdir(path->narrow, mode); -#endif - Py_END_ALLOW_THREADS - -#if HAVE_MKDIRAT - if (mkdirat_unavailable) { - argument_unavailable_error(NULL, "dir_fd"); - return NULL; - } -#endif - - if (result < 0) - return path_error(path); -#endif /* MS_WINDOWS */ - Py_RETURN_NONE; -} - - -/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */ -#if defined(HAVE_SYS_RESOURCE_H) -#include -#endif - - -#ifdef HAVE_NICE -/*[clinic input] -os.nice - - increment: int - / - -Add increment to the priority of process and return the new priority. -[clinic start generated code]*/ - -static PyObject * -os_nice_impl(PyObject *module, int increment) -/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/ -{ - int value; - - /* There are two flavours of 'nice': one that returns the new - priority (as required by almost all standards out there) and the - Linux/FreeBSD one, which returns '0' on success and advices - the use of getpriority() to get the new priority. - - If we are of the nice family that returns the new priority, we - need to clear errno before the call, and check if errno is filled - before calling posix_error() on a returnvalue of -1, because the - -1 may be the actual new priority! */ - - errno = 0; - value = nice(increment); -#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) - if (value == 0) - value = getpriority(PRIO_PROCESS, 0); -#endif - if (value == -1 && errno != 0) - /* either nice() or getpriority() returned an error */ - return posix_error(); - return PyLong_FromLong((long) value); -} -#endif /* HAVE_NICE */ - - -#ifdef HAVE_GETPRIORITY -/*[clinic input] -os.getpriority - - which: int - who: int - -Return program scheduling priority. -[clinic start generated code]*/ - -static PyObject * -os_getpriority_impl(PyObject *module, int which, int who) -/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/ -{ - int retval; - - errno = 0; - retval = getpriority(which, who); - if (errno != 0) - return posix_error(); - return PyLong_FromLong((long)retval); -} -#endif /* HAVE_GETPRIORITY */ - - -#ifdef HAVE_SETPRIORITY -/*[clinic input] -os.setpriority - - which: int - who: int - priority: int - -Set program scheduling priority. -[clinic start generated code]*/ - -static PyObject * -os_setpriority_impl(PyObject *module, int which, int who, int priority) -/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/ -{ - int retval; - - retval = setpriority(which, who, priority); - if (retval == -1) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETPRIORITY */ - - -static PyObject * -internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace) -{ - const char *function_name = is_replace ? "replace" : "rename"; - int dir_fd_specified; - -#ifdef HAVE_RENAMEAT - int renameat_unavailable = 0; -#endif - -#ifdef MS_WINDOWS - BOOL result; - int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0; -#else - int result; -#endif - - dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) || - (dst_dir_fd != DEFAULT_DIR_FD); -#ifndef HAVE_RENAMEAT - if (dir_fd_specified) { - argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); - return NULL; - } -#endif - - if (PySys_Audit("os.rename", "OOii", src->object, dst->object, - src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd, - dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) { - return NULL; - } - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - result = MoveFileExW(src->wide, dst->wide, flags); - Py_END_ALLOW_THREADS - - if (!result) - return path_error2(src, dst); - -#else - if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { - PyErr_Format(PyExc_ValueError, - "%s: src and dst must be the same type", function_name); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_RENAMEAT - if (dir_fd_specified) { - if (HAVE_RENAMEAT_RUNTIME) { - result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow); - } else { - renameat_unavailable = 1; - } - } else -#endif - result = rename(src->narrow, dst->narrow); - Py_END_ALLOW_THREADS - - -#ifdef HAVE_RENAMEAT - if (renameat_unavailable) { - argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); - return NULL; - } -#endif - - if (result) - return path_error2(src, dst); -#endif - Py_RETURN_NONE; -} - - -/*[clinic input] -os.rename - - src : path_t - dst : path_t - * - src_dir_fd : dir_fd = None - dst_dir_fd : dir_fd = None - -Rename a file or directory. - -If either src_dir_fd or dst_dir_fd is not None, it should be a file - descriptor open to a directory, and the respective path string (src or dst) - should be relative; the path will then be relative to that directory. -src_dir_fd and dst_dir_fd, may not be implemented on your platform. - If they are unavailable, using them will raise a NotImplementedError. -[clinic start generated code]*/ - -static PyObject * -os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, - int dst_dir_fd) -/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/ -{ - return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0); -} - - -/*[clinic input] -os.replace = os.rename - -Rename a file or directory, overwriting the destination. - -If either src_dir_fd or dst_dir_fd is not None, it should be a file - descriptor open to a directory, and the respective path string (src or dst) - should be relative; the path will then be relative to that directory. -src_dir_fd and dst_dir_fd, may not be implemented on your platform. - If they are unavailable, using them will raise a NotImplementedError. -[clinic start generated code]*/ - -static PyObject * -os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, - int dst_dir_fd) -/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/ -{ - return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1); -} - - -/*[clinic input] -os.rmdir - - path: path_t - * - dir_fd: dir_fd(requires='unlinkat') = None - -Remove a directory. - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. -[clinic start generated code]*/ - -static PyObject * -os_rmdir_impl(PyObject *module, path_t *path, int dir_fd) -/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/ -{ - int result; -#ifdef HAVE_UNLINKAT - int unlinkat_unavailable = 0; -#endif - - if (PySys_Audit("os.rmdir", "Oi", path->object, - dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - /* Windows, success=1, UNIX, success=0 */ - result = !RemoveDirectoryW(path->wide); -#else -#ifdef HAVE_UNLINKAT - if (dir_fd != DEFAULT_DIR_FD) { - if (HAVE_UNLINKAT_RUNTIME) { - result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR); - } else { - unlinkat_unavailable = 1; - result = -1; - } - } else -#endif - result = rmdir(path->narrow); -#endif - Py_END_ALLOW_THREADS - -#ifdef HAVE_UNLINKAT - if (unlinkat_unavailable) { - argument_unavailable_error("rmdir", "dir_fd"); - return NULL; - } -#endif - - if (result) - return path_error(path); - - Py_RETURN_NONE; -} - - -#ifdef HAVE_SYSTEM -#ifdef MS_WINDOWS -/*[clinic input] -os.system -> long - - command: Py_UNICODE - -Execute the command in a subshell. -[clinic start generated code]*/ - -static long -os_system_impl(PyObject *module, const Py_UNICODE *command) -/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/ -{ - long result; - - if (PySys_Audit("os.system", "(u)", command) < 0) { - return -1; - } - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - result = _wsystem(command); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - return result; -} -#else /* MS_WINDOWS */ -/*[clinic input] -os.system -> long - - command: FSConverter - -Execute the command in a subshell. -[clinic start generated code]*/ - -static long -os_system_impl(PyObject *module, PyObject *command) -/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/ -{ - long result; - const char *bytes = PyBytes_AsString(command); - - if (PySys_Audit("os.system", "(O)", command) < 0) { - return -1; - } - - Py_BEGIN_ALLOW_THREADS - result = system(bytes); - Py_END_ALLOW_THREADS - return result; -} -#endif -#endif /* HAVE_SYSTEM */ - - -/*[clinic input] -os.umask - - mask: int - / - -Set the current numeric umask and return the previous umask. -[clinic start generated code]*/ - -static PyObject * -os_umask_impl(PyObject *module, int mask) -/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/ -{ - int i = (int)umask(mask); - if (i < 0) - return posix_error(); - return PyLong_FromLong((long)i); -} - -#ifdef MS_WINDOWS - -/* override the default DeleteFileW behavior so that directory -symlinks can be removed with this function, the same as with -Unix symlinks */ -BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) -{ - WIN32_FILE_ATTRIBUTE_DATA info; - WIN32_FIND_DATAW find_data; - HANDLE find_data_handle; - int is_directory = 0; - int is_link = 0; - - if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) { - is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; - - /* Get WIN32_FIND_DATA structure for the path to determine if - it is a symlink */ - if(is_directory && - info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - find_data_handle = FindFirstFileW(lpFileName, &find_data); - - if(find_data_handle != INVALID_HANDLE_VALUE) { - /* IO_REPARSE_TAG_SYMLINK if it is a symlink and - IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */ - is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK || - find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT; - FindClose(find_data_handle); - } - } - } - - if (is_directory && is_link) - return RemoveDirectoryW(lpFileName); - - return DeleteFileW(lpFileName); -} -#endif /* MS_WINDOWS */ - - -/*[clinic input] -os.unlink - - path: path_t - * - dir_fd: dir_fd(requires='unlinkat')=None - -Remove a file (same as remove()). - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. - -[clinic start generated code]*/ - -static PyObject * -os_unlink_impl(PyObject *module, path_t *path, int dir_fd) -/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/ -{ - int result; -#ifdef HAVE_UNLINKAT - int unlinkat_unavailable = 0; -#endif - - if (PySys_Audit("os.remove", "Oi", path->object, - dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef MS_WINDOWS - /* Windows, success=1, UNIX, success=0 */ - result = !Py_DeleteFileW(path->wide); -#else -#ifdef HAVE_UNLINKAT - if (dir_fd != DEFAULT_DIR_FD) { - if (HAVE_UNLINKAT_RUNTIME) { - - result = unlinkat(dir_fd, path->narrow, 0); - } else { - unlinkat_unavailable = 1; - } - } else -#endif /* HAVE_UNLINKAT */ - result = unlink(path->narrow); -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - -#ifdef HAVE_UNLINKAT - if (unlinkat_unavailable) { - argument_unavailable_error(NULL, "dir_fd"); - return NULL; - } -#endif - - if (result) - return path_error(path); - - Py_RETURN_NONE; -} - - -/*[clinic input] -os.remove = os.unlink - -Remove a file (same as unlink()). - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. -[clinic start generated code]*/ - -static PyObject * -os_remove_impl(PyObject *module, path_t *path, int dir_fd) -/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/ -{ - return os_unlink_impl(module, path, dir_fd); -} - - -static PyStructSequence_Field uname_result_fields[] = { - {"sysname", "operating system name"}, - {"nodename", "name of machine on network (implementation-defined)"}, - {"release", "operating system release"}, - {"version", "operating system version"}, - {"machine", "hardware identifier"}, - {NULL} -}; - -PyDoc_STRVAR(uname_result__doc__, -"uname_result: Result from os.uname().\n\n\ -This object may be accessed either as a tuple of\n\ - (sysname, nodename, release, version, machine),\n\ -or via the attributes sysname, nodename, release, version, and machine.\n\ -\n\ -See os.uname for more information."); - -static PyStructSequence_Desc uname_result_desc = { - MODNAME ".uname_result", /* name */ - uname_result__doc__, /* doc */ - uname_result_fields, - 5 -}; - -#ifdef HAVE_UNAME -/*[clinic input] -os.uname - -Return an object identifying the current operating system. - -The object behaves like a named tuple with the following fields: - (sysname, nodename, release, version, machine) - -[clinic start generated code]*/ - -static PyObject * -os_uname_impl(PyObject *module) -/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/ -{ - struct utsname u; - int res; - PyObject *value; - - Py_BEGIN_ALLOW_THREADS - res = uname(&u); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - - PyObject *UnameResultType = get_posix_state(module)->UnameResultType; - value = PyStructSequence_New((PyTypeObject *)UnameResultType); - if (value == NULL) - return NULL; - -#define SET(i, field) \ - { \ - PyObject *o = PyUnicode_DecodeFSDefault(field); \ - if (!o) { \ - Py_DECREF(value); \ - return NULL; \ - } \ - PyStructSequence_SET_ITEM(value, i, o); \ - } \ - - SET(0, u.sysname); - SET(1, u.nodename); - SET(2, u.release); - SET(3, u.version); - SET(4, u.machine); - -#undef SET - - return value; -} -#endif /* HAVE_UNAME */ - - - -typedef struct { - int now; - time_t atime_s; - long atime_ns; - time_t mtime_s; - long mtime_ns; -} utime_t; - -/* - * these macros assume that "ut" is a pointer to a utime_t - * they also intentionally leak the declaration of a pointer named "time" - */ -#define UTIME_TO_TIMESPEC \ - struct timespec ts[2]; \ - struct timespec *time; \ - if (ut->now) \ - time = NULL; \ - else { \ - ts[0].tv_sec = ut->atime_s; \ - ts[0].tv_nsec = ut->atime_ns; \ - ts[1].tv_sec = ut->mtime_s; \ - ts[1].tv_nsec = ut->mtime_ns; \ - time = ts; \ - } \ - -#define UTIME_TO_TIMEVAL \ - struct timeval tv[2]; \ - struct timeval *time; \ - if (ut->now) \ - time = NULL; \ - else { \ - tv[0].tv_sec = ut->atime_s; \ - tv[0].tv_usec = ut->atime_ns / 1000; \ - tv[1].tv_sec = ut->mtime_s; \ - tv[1].tv_usec = ut->mtime_ns / 1000; \ - time = tv; \ - } \ - -#define UTIME_TO_UTIMBUF \ - struct utimbuf u; \ - struct utimbuf *time; \ - if (ut->now) \ - time = NULL; \ - else { \ - u.actime = ut->atime_s; \ - u.modtime = ut->mtime_s; \ - time = &u; \ - } - -#define UTIME_TO_TIME_T \ - time_t timet[2]; \ - time_t *time; \ - if (ut->now) \ - time = NULL; \ - else { \ - timet[0] = ut->atime_s; \ - timet[1] = ut->mtime_s; \ - time = timet; \ - } \ - - -#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) - -static int -utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks) -{ -#if defined(__APPLE__) && defined(HAVE_UTIMENSAT) - if (HAVE_UTIMENSAT_RUNTIME) { - int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; - UTIME_TO_TIMESPEC; - return utimensat(dir_fd, path, time, flags); - } else { - errno = ENOSYS; - return -1; - } -#elif defined(HAVE_UTIMENSAT) - int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; - UTIME_TO_TIMESPEC; - return utimensat(dir_fd, path, time, flags); -#elif defined(HAVE_FUTIMESAT) - UTIME_TO_TIMEVAL; - /* - * follow_symlinks will never be false here; - * we only allow !follow_symlinks and dir_fd together - * if we have utimensat() - */ - assert(follow_symlinks); - return futimesat(dir_fd, path, time); -#endif -} - - #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter -#else - #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable -#endif - -#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) - -static int -utime_fd(utime_t *ut, int fd) -{ -#ifdef HAVE_FUTIMENS - - if (HAVE_FUTIMENS_RUNTIME) { - - UTIME_TO_TIMESPEC; - return futimens(fd, time); - - } else -#ifndef HAVE_FUTIMES - { - /* Not sure if this can happen */ - PyErr_SetString( - PyExc_RuntimeError, - "neither futimens nor futimes are supported" - " on this system"); - return -1; - } -#endif - -#endif -#ifdef HAVE_FUTIMES - { - UTIME_TO_TIMEVAL; - return futimes(fd, time); - } -#endif -} - - #define PATH_UTIME_HAVE_FD 1 -#else - #define PATH_UTIME_HAVE_FD 0 -#endif - -#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES) -# define UTIME_HAVE_NOFOLLOW_SYMLINKS -#endif - -#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS - -static int -utime_nofollow_symlinks(utime_t *ut, const char *path) -{ -#ifdef HAVE_UTIMENSAT - if (HAVE_UTIMENSAT_RUNTIME) { - UTIME_TO_TIMESPEC; - return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW); - } else -#ifndef HAVE_LUTIMES - { - /* Not sure if this can happen */ - PyErr_SetString( - PyExc_RuntimeError, - "neither utimensat nor lutimes are supported" - " on this system"); - return -1; - } -#endif -#endif - -#ifdef HAVE_LUTIMES - { - UTIME_TO_TIMEVAL; - return lutimes(path, time); - } -#endif -} - -#endif - -#ifndef MS_WINDOWS - -static int -utime_default(utime_t *ut, const char *path) -{ -#if defined(__APPLE__) && defined(HAVE_UTIMENSAT) - if (HAVE_UTIMENSAT_RUNTIME) { - UTIME_TO_TIMESPEC; - return utimensat(DEFAULT_DIR_FD, path, time, 0); - } else { - UTIME_TO_TIMEVAL; - return utimes(path, time); - } -#elif defined(HAVE_UTIMENSAT) - UTIME_TO_TIMESPEC; - return utimensat(DEFAULT_DIR_FD, path, time, 0); -#elif defined(HAVE_UTIMES) - UTIME_TO_TIMEVAL; - return utimes(path, time); -#elif defined(HAVE_UTIME_H) - UTIME_TO_UTIMBUF; - return utime(path, time); -#else - UTIME_TO_TIME_T; - return utime(path, time); -#endif -} - -#endif - -static int -split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns) -{ - int result = 0; - PyObject *divmod; - divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion); - if (!divmod) - goto exit; - if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) { - PyErr_Format(PyExc_TypeError, - "%.200s.__divmod__() must return a 2-tuple, not %.200s", - _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod))); - goto exit; - } - *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0)); - if ((*s == -1) && PyErr_Occurred()) - goto exit; - *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1)); - if ((*ns == -1) && PyErr_Occurred()) - goto exit; - - result = 1; -exit: - Py_XDECREF(divmod); - return result; -} - - -/*[clinic input] -os.utime - - path: path_t(allow_fd='PATH_UTIME_HAVE_FD') - times: object = None - * - ns: object = NULL - dir_fd: dir_fd(requires='futimensat') = None - follow_symlinks: bool=True - -# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\ - -Set the access and modified time of path. - -path may always be specified as a string. -On some platforms, path may also be specified as an open file descriptor. - If this functionality is unavailable, using it raises an exception. - -If times is not None, it must be a tuple (atime, mtime); - atime and mtime should be expressed as float seconds since the epoch. -If ns is specified, it must be a tuple (atime_ns, mtime_ns); - atime_ns and mtime_ns should be expressed as integer nanoseconds - since the epoch. -If times is None and ns is unspecified, utime uses the current time. -Specifying tuples for both times and ns is an error. - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -If follow_symlinks is False, and the last element of the path is a symbolic - link, utime will modify the symbolic link itself instead of the file the - link points to. -It is an error to use dir_fd or follow_symlinks when specifying path - as an open file descriptor. -dir_fd and follow_symlinks may not be available on your platform. - If they are unavailable, using them will raise a NotImplementedError. - -[clinic start generated code]*/ - -static PyObject * -os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, - int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/ -{ -#ifdef MS_WINDOWS - HANDLE hFile; - FILETIME atime, mtime; -#else - int result; -#endif - - utime_t utime; - - memset(&utime, 0, sizeof(utime_t)); - - if (times != Py_None && ns) { - PyErr_SetString(PyExc_ValueError, - "utime: you may specify either 'times'" - " or 'ns' but not both"); - return NULL; - } - - if (times != Py_None) { - time_t a_sec, m_sec; - long a_nsec, m_nsec; - if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) { - PyErr_SetString(PyExc_TypeError, - "utime: 'times' must be either" - " a tuple of two ints or None"); - return NULL; - } - utime.now = 0; - if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), - &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 || - _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), - &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) { - return NULL; - } - utime.atime_s = a_sec; - utime.atime_ns = a_nsec; - utime.mtime_s = m_sec; - utime.mtime_ns = m_nsec; - } - else if (ns) { - if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) { - PyErr_SetString(PyExc_TypeError, - "utime: 'ns' must be a tuple of two ints"); - return NULL; - } - utime.now = 0; - if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0), - &utime.atime_s, &utime.atime_ns) || - !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1), - &utime.mtime_s, &utime.mtime_ns)) { - return NULL; - } - } - else { - /* times and ns are both None/unspecified. use "now". */ - utime.now = 1; - } - -#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS) - if (follow_symlinks_specified("utime", follow_symlinks)) - return NULL; -#endif - - if (path_and_dir_fd_invalid("utime", path, dir_fd) || - dir_fd_and_fd_invalid("utime", dir_fd, path->fd) || - fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks)) - return NULL; - -#if !defined(HAVE_UTIMENSAT) - if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { - PyErr_SetString(PyExc_ValueError, - "utime: cannot use dir_fd and follow_symlinks " - "together on this platform"); - return NULL; - } -#endif - - if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None, - dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { - return NULL; - } - -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, - NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL); - Py_END_ALLOW_THREADS - if (hFile == INVALID_HANDLE_VALUE) { - path_error(path); - return NULL; - } - - if (utime.now) { - GetSystemTimeAsFileTime(&mtime); - atime = mtime; - } - else { - _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime); - _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime); - } - if (!SetFileTime(hFile, NULL, &atime, &mtime)) { - /* Avoid putting the file name into the error here, - as that may confuse the user into believing that - something is wrong with the file, when it also - could be the time stamp that gives a problem. */ - PyErr_SetFromWindowsErr(0); - CloseHandle(hFile); - return NULL; - } - CloseHandle(hFile); -#else /* MS_WINDOWS */ - Py_BEGIN_ALLOW_THREADS - -#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS - if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = utime_nofollow_symlinks(&utime, path->narrow); - else -#endif - -#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) - if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) { - result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks); - - } else -#endif - -#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) - if (path->fd != -1) - result = utime_fd(&utime, path->fd); - else -#endif - - result = utime_default(&utime, path->narrow); - - Py_END_ALLOW_THREADS - -#if defined(__APPLE__) && defined(HAVE_UTIMENSAT) - /* See utime_dir_fd implementation */ - if (result == -1 && errno == ENOSYS) { - argument_unavailable_error(NULL, "dir_fd"); - return NULL; - } -#endif - - if (result < 0) { - /* see previous comment about not putting filename in error here */ - posix_error(); - return NULL; - } - -#endif /* MS_WINDOWS */ - - Py_RETURN_NONE; -} - -/* Process operations */ - - -/*[clinic input] -os._exit - - status: int - -Exit to the system with specified status, without normal exit processing. -[clinic start generated code]*/ - -static PyObject * -os__exit_impl(PyObject *module, int status) -/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/ -{ - _exit(status); - return NULL; /* Make gcc -Wall happy */ -} - -#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) -#define EXECV_CHAR wchar_t -#else -#define EXECV_CHAR char -#endif - -#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN) -static void -free_string_array(EXECV_CHAR **array, Py_ssize_t count) -{ - Py_ssize_t i; - for (i = 0; i < count; i++) - PyMem_Free(array[i]); - PyMem_DEL(array); -} - -static int -fsconvert_strdup(PyObject *o, EXECV_CHAR **out) -{ - Py_ssize_t size; - PyObject *ub; - int result = 0; -#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) - if (!PyUnicode_FSDecoder(o, &ub)) - return 0; - *out = PyUnicode_AsWideCharString(ub, &size); - if (*out) - result = 1; -#else - if (!PyUnicode_FSConverter(o, &ub)) - return 0; - size = PyBytes_GET_SIZE(ub); - *out = PyMem_Malloc(size + 1); - if (*out) { - memcpy(*out, PyBytes_AS_STRING(ub), size + 1); - result = 1; - } else - PyErr_NoMemory(); -#endif - Py_DECREF(ub); - return result; -} -#endif - -#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN) -static EXECV_CHAR** -parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) -{ - Py_ssize_t i, pos, envc; - PyObject *keys=NULL, *vals=NULL; - PyObject *key, *val, *key2, *val2, *keyval; - EXECV_CHAR **envlist; - - i = PyMapping_Size(env); - if (i < 0) - return NULL; - envlist = PyMem_NEW(EXECV_CHAR *, i + 1); - if (envlist == NULL) { - PyErr_NoMemory(); - return NULL; - } - envc = 0; - keys = PyMapping_Keys(env); - if (!keys) - goto error; - vals = PyMapping_Values(env); - if (!vals) - goto error; - if (!PyList_Check(keys) || !PyList_Check(vals)) { - PyErr_Format(PyExc_TypeError, - "env.keys() or env.values() is not a list"); - goto error; - } - - for (pos = 0; pos < i; pos++) { - key = PyList_GetItem(keys, pos); - val = PyList_GetItem(vals, pos); - if (!key || !val) - goto error; - -#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) - if (!PyUnicode_FSDecoder(key, &key2)) - goto error; - if (!PyUnicode_FSDecoder(val, &val2)) { - Py_DECREF(key2); - goto error; - } - /* Search from index 1 because on Windows starting '=' is allowed for - defining hidden environment variables. */ - if (PyUnicode_GET_LENGTH(key2) == 0 || - PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1) - { - PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); - Py_DECREF(key2); - Py_DECREF(val2); - goto error; - } - keyval = PyUnicode_FromFormat("%U=%U", key2, val2); -#else - if (!PyUnicode_FSConverter(key, &key2)) - goto error; - if (!PyUnicode_FSConverter(val, &val2)) { - Py_DECREF(key2); - goto error; - } - if (PyBytes_GET_SIZE(key2) == 0 || - strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL) - { - PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); - Py_DECREF(key2); - Py_DECREF(val2); - goto error; - } - keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2), - PyBytes_AS_STRING(val2)); -#endif - Py_DECREF(key2); - Py_DECREF(val2); - if (!keyval) - goto error; - - if (!fsconvert_strdup(keyval, &envlist[envc++])) { - Py_DECREF(keyval); - goto error; - } - - Py_DECREF(keyval); - } - Py_DECREF(vals); - Py_DECREF(keys); - - envlist[envc] = 0; - *envc_ptr = envc; - return envlist; - -error: - Py_XDECREF(keys); - Py_XDECREF(vals); - free_string_array(envlist, envc); - return NULL; -} - -static EXECV_CHAR** -parse_arglist(PyObject* argv, Py_ssize_t *argc) -{ - int i; - EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1); - if (argvlist == NULL) { - PyErr_NoMemory(); - return NULL; - } - for (i = 0; i < *argc; i++) { - PyObject* item = PySequence_ITEM(argv, i); - if (item == NULL) - goto fail; - if (!fsconvert_strdup(item, &argvlist[i])) { - Py_DECREF(item); - goto fail; - } - Py_DECREF(item); - } - argvlist[*argc] = NULL; - return argvlist; -fail: - *argc = i; - free_string_array(argvlist, *argc); - return NULL; -} - -#endif - - -#ifdef HAVE_EXECV -/*[clinic input] -os.execv - - path: path_t - Path of executable file. - argv: object - Tuple or list of strings. - / - -Execute an executable path with arguments, replacing current process. -[clinic start generated code]*/ - -static PyObject * -os_execv_impl(PyObject *module, path_t *path, PyObject *argv) -/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/ -{ - EXECV_CHAR **argvlist; - Py_ssize_t argc; - - /* execv has two arguments: (path, argv), where - argv is a list or tuple of strings. */ - - if (!PyList_Check(argv) && !PyTuple_Check(argv)) { - PyErr_SetString(PyExc_TypeError, - "execv() arg 2 must be a tuple or list"); - return NULL; - } - argc = PySequence_Size(argv); - if (argc < 1) { - PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); - return NULL; - } - - argvlist = parse_arglist(argv, &argc); - if (argvlist == NULL) { - return NULL; - } - if (!argvlist[0][0]) { - PyErr_SetString(PyExc_ValueError, - "execv() arg 2 first element cannot be empty"); - free_string_array(argvlist, argc); - return NULL; - } - - if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) { - free_string_array(argvlist, argc); - return NULL; - } - - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_WEXECV - _wexecv(path->wide, argvlist); -#else - execv(path->narrow, argvlist); -#endif - _Py_END_SUPPRESS_IPH - - /* If we get here it's definitely an error */ - - free_string_array(argvlist, argc); - return posix_error(); -} - - -/*[clinic input] -os.execve - - path: path_t(allow_fd='PATH_HAVE_FEXECVE') - Path of executable file. - argv: object - Tuple or list of strings. - env: object - Dictionary of strings mapping to strings. - -Execute an executable path with arguments, replacing current process. -[clinic start generated code]*/ - -static PyObject * -os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) -/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/ -{ - EXECV_CHAR **argvlist = NULL; - EXECV_CHAR **envlist; - Py_ssize_t argc, envc; - - /* execve has three arguments: (path, argv, env), where - argv is a list or tuple of strings and env is a dictionary - like posix.environ. */ - - if (!PyList_Check(argv) && !PyTuple_Check(argv)) { - PyErr_SetString(PyExc_TypeError, - "execve: argv must be a tuple or list"); - goto fail_0; - } - argc = PySequence_Size(argv); - if (argc < 1) { - PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty"); - return NULL; - } - - if (!PyMapping_Check(env)) { - PyErr_SetString(PyExc_TypeError, - "execve: environment must be a mapping object"); - goto fail_0; - } - - argvlist = parse_arglist(argv, &argc); - if (argvlist == NULL) { - goto fail_0; - } - if (!argvlist[0][0]) { - PyErr_SetString(PyExc_ValueError, - "execve: argv first element cannot be empty"); - goto fail_0; - } - - envlist = parse_envlist(env, &envc); - if (envlist == NULL) - goto fail_0; - - if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) { - goto fail_1; - } - - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_FEXECVE - if (path->fd > -1) - fexecve(path->fd, argvlist, envlist); - else -#endif -#ifdef HAVE_WEXECV - _wexecve(path->wide, argvlist, envlist); -#else - execve(path->narrow, argvlist, envlist); -#endif - _Py_END_SUPPRESS_IPH - - /* If we get here it's definitely an error */ - - posix_path_error(path); - fail_1: - free_string_array(envlist, envc); - fail_0: - if (argvlist) - free_string_array(argvlist, argc); - return NULL; -} - -#endif /* HAVE_EXECV */ - -#ifdef HAVE_POSIX_SPAWN - -enum posix_spawn_file_actions_identifier { - POSIX_SPAWN_OPEN, - POSIX_SPAWN_CLOSE, - POSIX_SPAWN_DUP2 -}; - -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) -static int -convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res); -#endif - -static int -parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup, - int resetids, int setsid, PyObject *setsigmask, - PyObject *setsigdef, PyObject *scheduler, - posix_spawnattr_t *attrp) -{ - long all_flags = 0; - - errno = posix_spawnattr_init(attrp); - if (errno) { - posix_error(); - return -1; - } - - if (setpgroup) { - pid_t pgid = PyLong_AsPid(setpgroup); - if (pgid == (pid_t)-1 && PyErr_Occurred()) { - goto fail; - } - errno = posix_spawnattr_setpgroup(attrp, pgid); - if (errno) { - posix_error(); - goto fail; - } - all_flags |= POSIX_SPAWN_SETPGROUP; - } - - if (resetids) { - all_flags |= POSIX_SPAWN_RESETIDS; - } - - if (setsid) { -#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME - if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) { -#endif -#ifdef POSIX_SPAWN_SETSID - all_flags |= POSIX_SPAWN_SETSID; -#elif defined(POSIX_SPAWN_SETSID_NP) - all_flags |= POSIX_SPAWN_SETSID_NP; -#else - argument_unavailable_error(func_name, "setsid"); - return -1; -#endif - -#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME - } else { - argument_unavailable_error(func_name, "setsid"); - return -1; - } -#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */ - - } - -#ifdef HAVE_SIGSET_T - if (setsigmask) { - sigset_t set; - if (!_Py_Sigset_Converter(setsigmask, &set)) { - goto fail; - } - errno = posix_spawnattr_setsigmask(attrp, &set); - if (errno) { - posix_error(); - goto fail; - } - all_flags |= POSIX_SPAWN_SETSIGMASK; - } - - if (setsigdef) { - sigset_t set; - if (!_Py_Sigset_Converter(setsigdef, &set)) { - goto fail; - } - errno = posix_spawnattr_setsigdefault(attrp, &set); - if (errno) { - posix_error(); - goto fail; - } - all_flags |= POSIX_SPAWN_SETSIGDEF; - } -#else - if (setsigmask || setsigdef) { - PyErr_SetString(PyExc_NotImplementedError, - "sigset is not supported on this platform"); - goto fail; - } -#endif - - if (scheduler) { -#ifdef POSIX_SPAWN_SETSCHEDULER - PyObject *py_schedpolicy; - PyObject *schedparam_obj; - struct sched_param schedparam; - - if (!PyArg_ParseTuple(scheduler, "OO" - ";A scheduler tuple must have two elements", - &py_schedpolicy, &schedparam_obj)) { - goto fail; - } - if (!convert_sched_param(module, schedparam_obj, &schedparam)) { - goto fail; - } - if (py_schedpolicy != Py_None) { - int schedpolicy = _PyLong_AsInt(py_schedpolicy); - - if (schedpolicy == -1 && PyErr_Occurred()) { - goto fail; - } - errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy); - if (errno) { - posix_error(); - goto fail; - } - all_flags |= POSIX_SPAWN_SETSCHEDULER; - } - errno = posix_spawnattr_setschedparam(attrp, &schedparam); - if (errno) { - posix_error(); - goto fail; - } - all_flags |= POSIX_SPAWN_SETSCHEDPARAM; -#else - PyErr_SetString(PyExc_NotImplementedError, - "The scheduler option is not supported in this system."); - goto fail; -#endif - } - - errno = posix_spawnattr_setflags(attrp, all_flags); - if (errno) { - posix_error(); - goto fail; - } - - return 0; - -fail: - (void)posix_spawnattr_destroy(attrp); - return -1; -} - -static int -parse_file_actions(PyObject *file_actions, - posix_spawn_file_actions_t *file_actionsp, - PyObject *temp_buffer) -{ - PyObject *seq; - PyObject *file_action = NULL; - PyObject *tag_obj; - - seq = PySequence_Fast(file_actions, - "file_actions must be a sequence or None"); - if (seq == NULL) { - return -1; - } - - errno = posix_spawn_file_actions_init(file_actionsp); - if (errno) { - posix_error(); - Py_DECREF(seq); - return -1; - } - - for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { - file_action = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(file_action); - if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) { - PyErr_SetString(PyExc_TypeError, - "Each file_actions element must be a non-empty tuple"); - goto fail; - } - long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0)); - if (tag == -1 && PyErr_Occurred()) { - goto fail; - } - - /* Populate the file_actions object */ - switch (tag) { - case POSIX_SPAWN_OPEN: { - int fd, oflag; - PyObject *path; - unsigned long mode; - if (!PyArg_ParseTuple(file_action, "OiO&ik" - ";A open file_action tuple must have 5 elements", - &tag_obj, &fd, PyUnicode_FSConverter, &path, - &oflag, &mode)) - { - goto fail; - } - if (PyList_Append(temp_buffer, path)) { - Py_DECREF(path); - goto fail; - } - errno = posix_spawn_file_actions_addopen(file_actionsp, - fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); - Py_DECREF(path); - if (errno) { - posix_error(); - goto fail; - } - break; - } - case POSIX_SPAWN_CLOSE: { - int fd; - if (!PyArg_ParseTuple(file_action, "Oi" - ";A close file_action tuple must have 2 elements", - &tag_obj, &fd)) - { - goto fail; - } - errno = posix_spawn_file_actions_addclose(file_actionsp, fd); - if (errno) { - posix_error(); - goto fail; - } - break; - } - case POSIX_SPAWN_DUP2: { - int fd1, fd2; - if (!PyArg_ParseTuple(file_action, "Oii" - ";A dup2 file_action tuple must have 3 elements", - &tag_obj, &fd1, &fd2)) - { - goto fail; - } - errno = posix_spawn_file_actions_adddup2(file_actionsp, - fd1, fd2); - if (errno) { - posix_error(); - goto fail; - } - break; - } - default: { - PyErr_SetString(PyExc_TypeError, - "Unknown file_actions identifier"); - goto fail; - } - } - Py_DECREF(file_action); - } - - Py_DECREF(seq); - return 0; - -fail: - Py_DECREF(seq); - Py_DECREF(file_action); - (void)posix_spawn_file_actions_destroy(file_actionsp); - return -1; -} - - -static PyObject * -py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv, - PyObject *env, PyObject *file_actions, - PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask, - PyObject *setsigdef, PyObject *scheduler) -{ - const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn"; - EXECV_CHAR **argvlist = NULL; - EXECV_CHAR **envlist = NULL; - posix_spawn_file_actions_t file_actions_buf; - posix_spawn_file_actions_t *file_actionsp = NULL; - posix_spawnattr_t attr; - posix_spawnattr_t *attrp = NULL; - Py_ssize_t argc, envc; - PyObject *result = NULL; - PyObject *temp_buffer = NULL; - pid_t pid; - int err_code; - - /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where - argv is a list or tuple of strings and env is a dictionary - like posix.environ. */ - - if (!PyList_Check(argv) && !PyTuple_Check(argv)) { - PyErr_Format(PyExc_TypeError, - "%s: argv must be a tuple or list", func_name); - goto exit; - } - argc = PySequence_Size(argv); - if (argc < 1) { - PyErr_Format(PyExc_ValueError, - "%s: argv must not be empty", func_name); - return NULL; - } - - if (!PyMapping_Check(env)) { - PyErr_Format(PyExc_TypeError, - "%s: environment must be a mapping object", func_name); - goto exit; - } - - argvlist = parse_arglist(argv, &argc); - if (argvlist == NULL) { - goto exit; - } - if (!argvlist[0][0]) { - PyErr_Format(PyExc_ValueError, - "%s: argv first element cannot be empty", func_name); - goto exit; - } - - envlist = parse_envlist(env, &envc); - if (envlist == NULL) { - goto exit; - } - - if (file_actions != NULL && file_actions != Py_None) { - /* There is a bug in old versions of glibc that makes some of the - * helper functions for manipulating file actions not copy the provided - * buffers. The problem is that posix_spawn_file_actions_addopen does not - * copy the value of path for some old versions of glibc (<2.20). - * The use of temp_buffer here is a workaround that keeps the - * python objects that own the buffers alive until posix_spawn gets called. - * Check https://bugs.python.org/issue33630 and - * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/ - temp_buffer = PyList_New(0); - if (!temp_buffer) { - goto exit; - } - if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) { - goto exit; - } - file_actionsp = &file_actions_buf; - } - - if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid, - setsigmask, setsigdef, scheduler, &attr)) { - goto exit; - } - attrp = &attr; - - if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) { - goto exit; - } - - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_POSIX_SPAWNP - if (use_posix_spawnp) { - err_code = posix_spawnp(&pid, path->narrow, - file_actionsp, attrp, argvlist, envlist); - } - else -#endif /* HAVE_POSIX_SPAWNP */ - { - err_code = posix_spawn(&pid, path->narrow, - file_actionsp, attrp, argvlist, envlist); - } - _Py_END_SUPPRESS_IPH - - if (err_code) { - errno = err_code; - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); - goto exit; - } -#ifdef _Py_MEMORY_SANITIZER - __msan_unpoison(&pid, sizeof(pid)); -#endif - result = PyLong_FromPid(pid); - -exit: - if (file_actionsp) { - (void)posix_spawn_file_actions_destroy(file_actionsp); - } - if (attrp) { - (void)posix_spawnattr_destroy(attrp); - } - if (envlist) { - free_string_array(envlist, envc); - } - if (argvlist) { - free_string_array(argvlist, argc); - } - Py_XDECREF(temp_buffer); - return result; -} - - -/*[clinic input] - -os.posix_spawn - path: path_t - Path of executable file. - argv: object - Tuple or list of strings. - env: object - Dictionary of strings mapping to strings. - / - * - file_actions: object(c_default='NULL') = () - A sequence of file action tuples. - setpgroup: object = NULL - The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. - resetids: bool(accept={int}) = False - If the value is `true` the POSIX_SPAWN_RESETIDS will be activated. - setsid: bool(accept={int}) = False - If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated. - setsigmask: object(c_default='NULL') = () - The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. - setsigdef: object(c_default='NULL') = () - The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag. - scheduler: object = NULL - A tuple with the scheduler policy (optional) and parameters. - -Execute the program specified by path in a new process. -[clinic start generated code]*/ - -static PyObject * -os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, - PyObject *env, PyObject *file_actions, - PyObject *setpgroup, int resetids, int setsid, - PyObject *setsigmask, PyObject *setsigdef, - PyObject *scheduler) -/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/ -{ - return py_posix_spawn(0, module, path, argv, env, file_actions, - setpgroup, resetids, setsid, setsigmask, setsigdef, - scheduler); -} - #endif /* HAVE_POSIX_SPAWN */ - - - -#ifdef HAVE_POSIX_SPAWNP -/*[clinic input] - -os.posix_spawnp - path: path_t - Path of executable file. - argv: object - Tuple or list of strings. - env: object - Dictionary of strings mapping to strings. - / - * - file_actions: object(c_default='NULL') = () - A sequence of file action tuples. - setpgroup: object = NULL - The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. - resetids: bool(accept={int}) = False - If the value is `True` the POSIX_SPAWN_RESETIDS will be activated. - setsid: bool(accept={int}) = False - If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated. - setsigmask: object(c_default='NULL') = () - The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. - setsigdef: object(c_default='NULL') = () - The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag. - scheduler: object = NULL - A tuple with the scheduler policy (optional) and parameters. - -Execute the program specified by path in a new process. -[clinic start generated code]*/ - -static PyObject * -os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv, - PyObject *env, PyObject *file_actions, - PyObject *setpgroup, int resetids, int setsid, - PyObject *setsigmask, PyObject *setsigdef, - PyObject *scheduler) -/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/ -{ - return py_posix_spawn(1, module, path, argv, env, file_actions, - setpgroup, resetids, setsid, setsigmask, setsigdef, - scheduler); -} -#endif /* HAVE_POSIX_SPAWNP */ - -#ifdef HAVE_RTPSPAWN -static intptr_t -_rtp_spawn(int mode, const char *rtpFileName, const char *argv[], - const char *envp[]) -{ - RTP_ID rtpid; - int status; - pid_t res; - int async_err = 0; - - /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes. - uStackSize=0 cannot be used, the default stack size is too small for - Python. */ - if (envp) { - rtpid = rtpSpawn(rtpFileName, argv, envp, - 100, 0x1000000, 0, VX_FP_TASK); - } - else { - rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ, - 100, 0x1000000, 0, VX_FP_TASK); - } - if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) { - do { - res = waitpid((pid_t)rtpid, &status, 0); - } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - - if (res < 0) - return RTP_ID_ERROR; - return ((intptr_t)status); - } - return ((intptr_t)rtpid); -} -#endif - -#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN) -/*[clinic input] -os.spawnv - - mode: int - Mode of process creation. - path: path_t - Path of executable file. - argv: object - Tuple or list of strings. - / - -Execute the program specified by path in a new process. -[clinic start generated code]*/ - -static PyObject * -os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) -/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/ -{ - EXECV_CHAR **argvlist; - int i; - Py_ssize_t argc; - intptr_t spawnval; - PyObject *(*getitem)(PyObject *, Py_ssize_t); - - /* spawnv has three arguments: (mode, path, argv), where - argv is a list or tuple of strings. */ - - if (PyList_Check(argv)) { - argc = PyList_Size(argv); - getitem = PyList_GetItem; - } - else if (PyTuple_Check(argv)) { - argc = PyTuple_Size(argv); - getitem = PyTuple_GetItem; - } - else { - PyErr_SetString(PyExc_TypeError, - "spawnv() arg 2 must be a tuple or list"); - return NULL; - } - if (argc == 0) { - PyErr_SetString(PyExc_ValueError, - "spawnv() arg 2 cannot be empty"); - return NULL; - } - - argvlist = PyMem_NEW(EXECV_CHAR *, argc+1); - if (argvlist == NULL) { - return PyErr_NoMemory(); - } - for (i = 0; i < argc; i++) { - if (!fsconvert_strdup((*getitem)(argv, i), - &argvlist[i])) { - free_string_array(argvlist, i); - PyErr_SetString( - PyExc_TypeError, - "spawnv() arg 2 must contain only strings"); - return NULL; - } - if (i == 0 && !argvlist[0][0]) { - free_string_array(argvlist, i + 1); - PyErr_SetString( - PyExc_ValueError, - "spawnv() arg 2 first element cannot be empty"); - return NULL; - } - } - argvlist[argc] = NULL; - -#if !defined(HAVE_RTPSPAWN) - if (mode == _OLD_P_OVERLAY) - mode = _P_OVERLAY; -#endif - - if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, - Py_None) < 0) { - free_string_array(argvlist, argc); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_WSPAWNV - spawnval = _wspawnv(mode, path->wide, argvlist); -#elif defined(HAVE_RTPSPAWN) - spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL); -#else - spawnval = _spawnv(mode, path->narrow, argvlist); -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - - free_string_array(argvlist, argc); - - if (spawnval == -1) - return posix_error(); - else - return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); -} - -/*[clinic input] -os.spawnve - - mode: int - Mode of process creation. - path: path_t - Path of executable file. - argv: object - Tuple or list of strings. - env: object - Dictionary of strings mapping to strings. - / - -Execute the program specified by path in a new process. -[clinic start generated code]*/ - -static PyObject * -os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, - PyObject *env) -/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/ -{ - EXECV_CHAR **argvlist; - EXECV_CHAR **envlist; - PyObject *res = NULL; - Py_ssize_t argc, i, envc; - intptr_t spawnval; - PyObject *(*getitem)(PyObject *, Py_ssize_t); - Py_ssize_t lastarg = 0; - - /* spawnve has four arguments: (mode, path, argv, env), where - argv is a list or tuple of strings and env is a dictionary - like posix.environ. */ - - if (PyList_Check(argv)) { - argc = PyList_Size(argv); - getitem = PyList_GetItem; - } - else if (PyTuple_Check(argv)) { - argc = PyTuple_Size(argv); - getitem = PyTuple_GetItem; - } - else { - PyErr_SetString(PyExc_TypeError, - "spawnve() arg 2 must be a tuple or list"); - goto fail_0; - } - if (argc == 0) { - PyErr_SetString(PyExc_ValueError, - "spawnve() arg 2 cannot be empty"); - goto fail_0; - } - if (!PyMapping_Check(env)) { - PyErr_SetString(PyExc_TypeError, - "spawnve() arg 3 must be a mapping object"); - goto fail_0; - } - - argvlist = PyMem_NEW(EXECV_CHAR *, argc+1); - if (argvlist == NULL) { - PyErr_NoMemory(); - goto fail_0; - } - for (i = 0; i < argc; i++) { - if (!fsconvert_strdup((*getitem)(argv, i), - &argvlist[i])) - { - lastarg = i; - goto fail_1; - } - if (i == 0 && !argvlist[0][0]) { - lastarg = i + 1; - PyErr_SetString( - PyExc_ValueError, - "spawnv() arg 2 first element cannot be empty"); - goto fail_1; - } - } - lastarg = argc; - argvlist[argc] = NULL; - - envlist = parse_envlist(env, &envc); - if (envlist == NULL) - goto fail_1; - -#if !defined(HAVE_RTPSPAWN) - if (mode == _OLD_P_OVERLAY) - mode = _P_OVERLAY; -#endif - - if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) { - goto fail_2; - } - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_WSPAWNV - spawnval = _wspawnve(mode, path->wide, argvlist, envlist); -#elif defined(HAVE_RTPSPAWN) - spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, - (const char **)envlist); -#else - spawnval = _spawnve(mode, path->narrow, argvlist, envlist); -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - - if (spawnval == -1) - (void) posix_error(); - else - res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval); - - fail_2: - while (--envc >= 0) - PyMem_DEL(envlist[envc]); - PyMem_DEL(envlist); - fail_1: - free_string_array(argvlist, lastarg); - fail_0: - return res; -} - -#endif /* HAVE_SPAWNV */ - - -#ifdef HAVE_FORK - -/* Helper function to validate arguments. - Returns 0 on success. non-zero on failure with a TypeError raised. - If obj is non-NULL it must be callable. */ -static int -check_null_or_callable(PyObject *obj, const char* obj_name) -{ - if (obj && !PyCallable_Check(obj)) { - PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s", - obj_name, _PyType_Name(Py_TYPE(obj))); - return -1; - } - return 0; -} - -/*[clinic input] -os.register_at_fork - - * - before: object=NULL - A callable to be called in the parent before the fork() syscall. - after_in_child: object=NULL - A callable to be called in the child after fork(). - after_in_parent: object=NULL - A callable to be called in the parent after fork(). - -Register callables to be called when forking a new process. - -'before' callbacks are called in reverse order. -'after_in_child' and 'after_in_parent' callbacks are called in order. - -[clinic start generated code]*/ - -static PyObject * -os_register_at_fork_impl(PyObject *module, PyObject *before, - PyObject *after_in_child, PyObject *after_in_parent) -/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/ -{ - PyInterpreterState *interp; - - if (!before && !after_in_child && !after_in_parent) { - PyErr_SetString(PyExc_TypeError, "At least one argument is required."); - return NULL; - } - if (check_null_or_callable(before, "before") || - check_null_or_callable(after_in_child, "after_in_child") || - check_null_or_callable(after_in_parent, "after_in_parent")) { - return NULL; - } - interp = _PyInterpreterState_GET(); - - if (register_at_forker(&interp->before_forkers, before)) { - return NULL; - } - if (register_at_forker(&interp->after_forkers_child, after_in_child)) { - return NULL; - } - if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) { - return NULL; - } - Py_RETURN_NONE; -} -#endif /* HAVE_FORK */ - - -#ifdef HAVE_FORK1 -/*[clinic input] -os.fork1 - -Fork a child process with a single multiplexed (i.e., not bound) thread. - -Return 0 to child process and PID of child to parent process. -[clinic start generated code]*/ - -static PyObject * -os_fork1_impl(PyObject *module) -/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/ -{ - pid_t pid; - - if (_PyInterpreterState_GET() != PyInterpreterState_Main()) { - PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); - return NULL; - } - PyOS_BeforeFork(); - pid = fork1(); - if (pid == 0) { - /* child: this clobbers and resets the import lock. */ - PyOS_AfterFork_Child(); - } else { - /* parent: release the import lock. */ - PyOS_AfterFork_Parent(); - } - if (pid == -1) - return posix_error(); - return PyLong_FromPid(pid); -} -#endif /* HAVE_FORK1 */ - - -#ifdef HAVE_FORK -/*[clinic input] -os.fork - -Fork a child process. - -Return 0 to child process and PID of child to parent process. -[clinic start generated code]*/ - -static PyObject * -os_fork_impl(PyObject *module) -/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/ -{ - pid_t pid; - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->config._isolated_interpreter) { - PyErr_SetString(PyExc_RuntimeError, - "fork not supported for isolated subinterpreters"); - return NULL; - } - if (PySys_Audit("os.fork", NULL) < 0) { - return NULL; - } - PyOS_BeforeFork(); - pid = fork(); - if (pid == 0) { - /* child: this clobbers and resets the import lock. */ - PyOS_AfterFork_Child(); - } else { - /* parent: release the import lock. */ - PyOS_AfterFork_Parent(); - } - if (pid == -1) - return posix_error(); - return PyLong_FromPid(pid); -} -#endif /* HAVE_FORK */ - - -#ifdef HAVE_SCHED_H -#ifdef HAVE_SCHED_GET_PRIORITY_MAX -/*[clinic input] -os.sched_get_priority_max - - policy: int - -Get the maximum scheduling priority for policy. -[clinic start generated code]*/ - -static PyObject * -os_sched_get_priority_max_impl(PyObject *module, int policy) -/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/ -{ - int max; - - max = sched_get_priority_max(policy); - if (max < 0) - return posix_error(); - return PyLong_FromLong(max); -} - - -/*[clinic input] -os.sched_get_priority_min - - policy: int - -Get the minimum scheduling priority for policy. -[clinic start generated code]*/ - -static PyObject * -os_sched_get_priority_min_impl(PyObject *module, int policy) -/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/ -{ - int min = sched_get_priority_min(policy); - if (min < 0) - return posix_error(); - return PyLong_FromLong(min); -} -#endif /* HAVE_SCHED_GET_PRIORITY_MAX */ - - -#ifdef HAVE_SCHED_SETSCHEDULER -/*[clinic input] -os.sched_getscheduler - pid: pid_t - / - -Get the scheduling policy for the process identified by pid. - -Passing 0 for pid returns the scheduling policy for the calling process. -[clinic start generated code]*/ - -static PyObject * -os_sched_getscheduler_impl(PyObject *module, pid_t pid) -/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/ -{ - int policy; - - policy = sched_getscheduler(pid); - if (policy < 0) - return posix_error(); - return PyLong_FromLong(policy); -} -#endif /* HAVE_SCHED_SETSCHEDULER */ - - -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) -/*[clinic input] -class os.sched_param "PyObject *" "SchedParamType" - -@classmethod -os.sched_param.__new__ - - sched_priority: object - A scheduling parameter. - -Currently has only one field: sched_priority -[clinic start generated code]*/ - -static PyObject * -os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) -/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/ -{ - PyObject *res; - - res = PyStructSequence_New(type); - if (!res) - return NULL; - Py_INCREF(sched_priority); - PyStructSequence_SET_ITEM(res, 0, sched_priority); - return res; -} - -PyDoc_VAR(os_sched_param__doc__); - -static PyStructSequence_Field sched_param_fields[] = { - {"sched_priority", "the scheduling priority"}, - {0} -}; - -static PyStructSequence_Desc sched_param_desc = { - "sched_param", /* name */ - os_sched_param__doc__, /* doc */ - sched_param_fields, - 1 -}; - -static int -convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res) -{ - long priority; - - if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) { - PyErr_SetString(PyExc_TypeError, "must have a sched_param object"); - return 0; - } - priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0)); - if (priority == -1 && PyErr_Occurred()) - return 0; - if (priority > INT_MAX || priority < INT_MIN) { - PyErr_SetString(PyExc_OverflowError, "sched_priority out of range"); - return 0; - } - res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int); - return 1; -} -#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */ - - -#ifdef HAVE_SCHED_SETSCHEDULER -/*[clinic input] -os.sched_setscheduler - - pid: pid_t - policy: int - param as param_obj: object - / - -Set the scheduling policy for the process identified by pid. - -If pid is 0, the calling process is changed. -param is an instance of sched_param. -[clinic start generated code]*/ - -static PyObject * -os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy, - PyObject *param_obj) -/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/ -{ - struct sched_param param; - if (!convert_sched_param(module, param_obj, ¶m)) { - return NULL; - } - - /* - ** sched_setscheduler() returns 0 in Linux, but the previous - ** scheduling policy under Solaris/Illumos, and others. - ** On error, -1 is returned in all Operating Systems. - */ - if (sched_setscheduler(pid, policy, ¶m) == -1) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SCHED_SETSCHEDULER*/ - - -#ifdef HAVE_SCHED_SETPARAM -/*[clinic input] -os.sched_getparam - pid: pid_t - / - -Returns scheduling parameters for the process identified by pid. - -If pid is 0, returns parameters for the calling process. -Return value is an instance of sched_param. -[clinic start generated code]*/ - -static PyObject * -os_sched_getparam_impl(PyObject *module, pid_t pid) -/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/ -{ - struct sched_param param; - PyObject *result; - PyObject *priority; - - if (sched_getparam(pid, ¶m)) - return posix_error(); - PyObject *SchedParamType = get_posix_state(module)->SchedParamType; - result = PyStructSequence_New((PyTypeObject *)SchedParamType); - if (!result) - return NULL; - priority = PyLong_FromLong(param.sched_priority); - if (!priority) { - Py_DECREF(result); - return NULL; - } - PyStructSequence_SET_ITEM(result, 0, priority); - return result; -} - - -/*[clinic input] -os.sched_setparam - pid: pid_t - param as param_obj: object - / - -Set scheduling parameters for the process identified by pid. - -If pid is 0, sets parameters for the calling process. -param should be an instance of sched_param. -[clinic start generated code]*/ - -static PyObject * -os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj) -/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/ -{ - struct sched_param param; - if (!convert_sched_param(module, param_obj, ¶m)) { - return NULL; - } - - if (sched_setparam(pid, ¶m)) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SCHED_SETPARAM */ - - -#ifdef HAVE_SCHED_RR_GET_INTERVAL -/*[clinic input] -os.sched_rr_get_interval -> double - pid: pid_t - / - -Return the round-robin quantum for the process identified by pid, in seconds. - -Value returned is a float. -[clinic start generated code]*/ - -static double -os_sched_rr_get_interval_impl(PyObject *module, pid_t pid) -/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/ -{ - struct timespec interval; - if (sched_rr_get_interval(pid, &interval)) { - posix_error(); - return -1.0; - } -#ifdef _Py_MEMORY_SANITIZER - __msan_unpoison(&interval, sizeof(interval)); -#endif - return (double)interval.tv_sec + 1e-9*interval.tv_nsec; -} -#endif /* HAVE_SCHED_RR_GET_INTERVAL */ - - -/*[clinic input] -os.sched_yield - -Voluntarily relinquish the CPU. -[clinic start generated code]*/ - -static PyObject * -os_sched_yield_impl(PyObject *module) -/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/ -{ - if (sched_yield()) - return posix_error(); - Py_RETURN_NONE; -} - -#ifdef HAVE_SCHED_SETAFFINITY -/* The minimum number of CPUs allocated in a cpu_set_t */ -static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT; - -/*[clinic input] -os.sched_setaffinity - pid: pid_t - mask : object - / - -Set the CPU affinity of the process identified by pid to mask. - -mask should be an iterable of integers identifying CPUs. -[clinic start generated code]*/ - -static PyObject * -os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask) -/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/ -{ - int ncpus; - size_t setsize; - cpu_set_t *cpu_set = NULL; - PyObject *iterator = NULL, *item; - - iterator = PyObject_GetIter(mask); - if (iterator == NULL) - return NULL; - - ncpus = NCPUS_START; - setsize = CPU_ALLOC_SIZE(ncpus); - cpu_set = CPU_ALLOC(ncpus); - if (cpu_set == NULL) { - PyErr_NoMemory(); - goto error; - } - CPU_ZERO_S(setsize, cpu_set); - - while ((item = PyIter_Next(iterator))) { - long cpu; - if (!PyLong_Check(item)) { - PyErr_Format(PyExc_TypeError, - "expected an iterator of ints, " - "but iterator yielded %R", - Py_TYPE(item)); - Py_DECREF(item); - goto error; - } - cpu = PyLong_AsLong(item); - Py_DECREF(item); - if (cpu < 0) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_ValueError, "negative CPU number"); - goto error; - } - if (cpu > INT_MAX - 1) { - PyErr_SetString(PyExc_OverflowError, "CPU number too large"); - goto error; - } - if (cpu >= ncpus) { - /* Grow CPU mask to fit the CPU number */ - int newncpus = ncpus; - cpu_set_t *newmask; - size_t newsetsize; - while (newncpus <= cpu) { - if (newncpus > INT_MAX / 2) - newncpus = cpu + 1; - else - newncpus = newncpus * 2; - } - newmask = CPU_ALLOC(newncpus); - if (newmask == NULL) { - PyErr_NoMemory(); - goto error; - } - newsetsize = CPU_ALLOC_SIZE(newncpus); - CPU_ZERO_S(newsetsize, newmask); - memcpy(newmask, cpu_set, setsize); - CPU_FREE(cpu_set); - setsize = newsetsize; - cpu_set = newmask; - ncpus = newncpus; - } - CPU_SET_S(cpu, setsize, cpu_set); - } - if (PyErr_Occurred()) { - goto error; - } - Py_CLEAR(iterator); - - if (sched_setaffinity(pid, setsize, cpu_set)) { - posix_error(); - goto error; - } - CPU_FREE(cpu_set); - Py_RETURN_NONE; - -error: - if (cpu_set) - CPU_FREE(cpu_set); - Py_XDECREF(iterator); - return NULL; -} - - -/*[clinic input] -os.sched_getaffinity - pid: pid_t - / - -Return the affinity of the process identified by pid (or the current process if zero). - -The affinity is returned as a set of CPU identifiers. -[clinic start generated code]*/ - -static PyObject * -os_sched_getaffinity_impl(PyObject *module, pid_t pid) -/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/ -{ - int cpu, ncpus, count; - size_t setsize; - cpu_set_t *mask = NULL; - PyObject *res = NULL; - - ncpus = NCPUS_START; - while (1) { - setsize = CPU_ALLOC_SIZE(ncpus); - mask = CPU_ALLOC(ncpus); - if (mask == NULL) - return PyErr_NoMemory(); - if (sched_getaffinity(pid, setsize, mask) == 0) - break; - CPU_FREE(mask); - if (errno != EINVAL) - return posix_error(); - if (ncpus > INT_MAX / 2) { - PyErr_SetString(PyExc_OverflowError, "could not allocate " - "a large enough CPU set"); - return NULL; - } - ncpus = ncpus * 2; - } - - res = PySet_New(NULL); - if (res == NULL) - goto error; - for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) { - if (CPU_ISSET_S(cpu, setsize, mask)) { - PyObject *cpu_num = PyLong_FromLong(cpu); - --count; - if (cpu_num == NULL) - goto error; - if (PySet_Add(res, cpu_num)) { - Py_DECREF(cpu_num); - goto error; - } - Py_DECREF(cpu_num); - } - } - CPU_FREE(mask); - return res; - -error: - if (mask) - CPU_FREE(mask); - Py_XDECREF(res); - return NULL; -} - -#endif /* HAVE_SCHED_SETAFFINITY */ - -#endif /* HAVE_SCHED_H */ - - -/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ -/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ -#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) -#define DEV_PTY_FILE "/dev/ptc" -#define HAVE_DEV_PTMX -#else -#define DEV_PTY_FILE "/dev/ptmx" -#endif - -#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) -#ifdef HAVE_PTY_H -#include -#else -#ifdef HAVE_LIBUTIL_H -#include -#else -#ifdef HAVE_UTIL_H -#include -#endif /* HAVE_UTIL_H */ -#endif /* HAVE_LIBUTIL_H */ -#endif /* HAVE_PTY_H */ -#ifdef HAVE_STROPTS_H -#include -#else - #define __SID ('S' << 8) - #define I_PUSH (__SID | 2) -#endif -#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */ - - -#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) -/*[clinic input] -os.openpty - -Open a pseudo-terminal. - -Return a tuple of (master_fd, slave_fd) containing open file descriptors -for both the master and slave ends. -[clinic start generated code]*/ - -static PyObject * -os_openpty_impl(PyObject *module) -/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/ -{ - int master_fd = -1, slave_fd = -1; -#ifndef HAVE_OPENPTY - char * slave_name; -#endif -#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) - PyOS_sighandler_t sig_saved; -#if defined(__sun) && defined(__SVR4) - extern char *ptsname(int fildes); -#endif -#endif - -#ifdef HAVE_OPENPTY - if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) - goto posix_error; - - if (_Py_set_inheritable(master_fd, 0, NULL) < 0) - goto error; - if (_Py_set_inheritable(slave_fd, 0, NULL) < 0) - goto error; - -#elif defined(HAVE__GETPTY) - slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); - if (slave_name == NULL) - goto posix_error; - if (_Py_set_inheritable(master_fd, 0, NULL) < 0) - goto error; - - slave_fd = _Py_open(slave_name, O_RDWR); - if (slave_fd < 0) - goto error; - -#else - master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */ - if (master_fd < 0) - goto posix_error; - - sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL); - - /* change permission of slave */ - if (grantpt(master_fd) < 0) { - PyOS_setsig(SIGCHLD, sig_saved); - goto posix_error; - } - - /* unlock slave */ - if (unlockpt(master_fd) < 0) { - PyOS_setsig(SIGCHLD, sig_saved); - goto posix_error; - } - - PyOS_setsig(SIGCHLD, sig_saved); - - slave_name = ptsname(master_fd); /* get name of slave */ - if (slave_name == NULL) - goto posix_error; - - slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ - if (slave_fd == -1) - goto error; - - if (_Py_set_inheritable(master_fd, 0, NULL) < 0) - goto posix_error; - -#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC) - ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ - ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ -#ifndef __hpux - ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */ -#endif /* __hpux */ -#endif /* HAVE_CYGWIN */ -#endif /* HAVE_OPENPTY */ - - return Py_BuildValue("(ii)", master_fd, slave_fd); - -posix_error: - posix_error(); -error: - if (master_fd != -1) - close(master_fd); - if (slave_fd != -1) - close(slave_fd); - return NULL; -} -#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ - - -#ifdef HAVE_FORKPTY -/*[clinic input] -os.forkpty - -Fork a new process with a new pseudo-terminal as controlling tty. - -Returns a tuple of (pid, master_fd). -Like fork(), return pid of 0 to the child process, -and pid of child to the parent process. -To both, return fd of newly opened pseudo-terminal. -[clinic start generated code]*/ - -static PyObject * -os_forkpty_impl(PyObject *module) -/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/ -{ - int master_fd = -1; - pid_t pid; - - if (_PyInterpreterState_GET() != PyInterpreterState_Main()) { - PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); - return NULL; - } - if (PySys_Audit("os.forkpty", NULL) < 0) { - return NULL; - } - PyOS_BeforeFork(); - pid = forkpty(&master_fd, NULL, NULL, NULL); - if (pid == 0) { - /* child: this clobbers and resets the import lock. */ - PyOS_AfterFork_Child(); - } else { - /* parent: release the import lock. */ - PyOS_AfterFork_Parent(); - } - if (pid == -1) - return posix_error(); - return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); -} -#endif /* HAVE_FORKPTY */ - - -#ifdef HAVE_GETEGID -/*[clinic input] -os.getegid - -Return the current process's effective group id. -[clinic start generated code]*/ - -static PyObject * -os_getegid_impl(PyObject *module) -/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/ -{ - return _PyLong_FromGid(getegid()); -} -#endif /* HAVE_GETEGID */ - - -#ifdef HAVE_GETEUID -/*[clinic input] -os.geteuid - -Return the current process's effective user id. -[clinic start generated code]*/ - -static PyObject * -os_geteuid_impl(PyObject *module) -/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/ -{ - return _PyLong_FromUid(geteuid()); -} -#endif /* HAVE_GETEUID */ - - -#ifdef HAVE_GETGID -/*[clinic input] -os.getgid - -Return the current process's group id. -[clinic start generated code]*/ - -static PyObject * -os_getgid_impl(PyObject *module) -/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/ -{ - return _PyLong_FromGid(getgid()); -} -#endif /* HAVE_GETGID */ - - -#ifdef HAVE_GETPID -/*[clinic input] -os.getpid - -Return the current process id. -[clinic start generated code]*/ - -static PyObject * -os_getpid_impl(PyObject *module) -/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/ -{ - return PyLong_FromPid(getpid()); -} -#endif /* HAVE_GETPID */ - -#ifdef NGROUPS_MAX -#define MAX_GROUPS NGROUPS_MAX -#else - /* defined to be 16 on Solaris7, so this should be a small number */ -#define MAX_GROUPS 64 -#endif - -#ifdef HAVE_GETGROUPLIST - -#ifdef __APPLE__ -/*[clinic input] -os.getgrouplist - - user: str - username to lookup - group as basegid: int - base group id of the user - / - -Returns a list of groups to which a user belongs. -[clinic start generated code]*/ - -static PyObject * -os_getgrouplist_impl(PyObject *module, const char *user, int basegid) -/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/ -#else -/*[clinic input] -os.getgrouplist - - user: str - username to lookup - group as basegid: gid_t - base group id of the user - / - -Returns a list of groups to which a user belongs. -[clinic start generated code]*/ - -static PyObject * -os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid) -/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/ -#endif -{ - int i, ngroups; - PyObject *list; -#ifdef __APPLE__ - int *groups; -#else - gid_t *groups; -#endif - - /* - * NGROUPS_MAX is defined by POSIX.1 as the maximum - * number of supplimental groups a users can belong to. - * We have to increment it by one because - * getgrouplist() returns both the supplemental groups - * and the primary group, i.e. all of the groups the - * user belongs to. - */ - ngroups = 1 + MAX_GROUPS; - - while (1) { -#ifdef __APPLE__ - groups = PyMem_New(int, ngroups); -#else - groups = PyMem_New(gid_t, ngroups); -#endif - if (groups == NULL) { - return PyErr_NoMemory(); - } - - int old_ngroups = ngroups; - if (getgrouplist(user, basegid, groups, &ngroups) != -1) { - /* Success */ - break; - } - - /* getgrouplist() fails if the group list is too small */ - PyMem_Free(groups); - - if (ngroups > old_ngroups) { - /* If the group list is too small, the glibc implementation of - getgrouplist() sets ngroups to the total number of groups and - returns -1. */ - } - else { - /* Double the group list size */ - if (ngroups > INT_MAX / 2) { - return PyErr_NoMemory(); - } - ngroups *= 2; - } - - /* Retry getgrouplist() with a larger group list */ - } - -#ifdef _Py_MEMORY_SANITIZER - /* Clang memory sanitizer libc intercepts don't know getgrouplist. */ - __msan_unpoison(&ngroups, sizeof(ngroups)); - __msan_unpoison(groups, ngroups*sizeof(*groups)); -#endif - - list = PyList_New(ngroups); - if (list == NULL) { - PyMem_Del(groups); - return NULL; - } - - for (i = 0; i < ngroups; i++) { -#ifdef __APPLE__ - PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]); -#else - PyObject *o = _PyLong_FromGid(groups[i]); -#endif - if (o == NULL) { - Py_DECREF(list); - PyMem_Del(groups); - return NULL; - } - PyList_SET_ITEM(list, i, o); - } - - PyMem_Del(groups); - - return list; -} -#endif /* HAVE_GETGROUPLIST */ - - -#ifdef HAVE_GETGROUPS -/*[clinic input] -os.getgroups - -Return list of supplemental group IDs for the process. -[clinic start generated code]*/ - -static PyObject * -os_getgroups_impl(PyObject *module) -/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/ -{ - PyObject *result = NULL; - gid_t grouplist[MAX_GROUPS]; - - /* On MacOSX getgroups(2) can return more than MAX_GROUPS results - * This is a helper variable to store the intermediate result when - * that happens. - * - * To keep the code readable the OSX behaviour is unconditional, - * according to the POSIX spec this should be safe on all unix-y - * systems. - */ - gid_t* alt_grouplist = grouplist; - int n; - -#ifdef __APPLE__ - /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if - * there are more groups than can fit in grouplist. Therefore, on OS X - * always first call getgroups with length 0 to get the actual number - * of groups. - */ - n = getgroups(0, NULL); - if (n < 0) { - return posix_error(); - } else if (n <= MAX_GROUPS) { - /* groups will fit in existing array */ - alt_grouplist = grouplist; - } else { - alt_grouplist = PyMem_New(gid_t, n); - if (alt_grouplist == NULL) { - return PyErr_NoMemory(); - } - } - - n = getgroups(n, alt_grouplist); - if (n == -1) { - if (alt_grouplist != grouplist) { - PyMem_Free(alt_grouplist); - } - return posix_error(); - } -#else - n = getgroups(MAX_GROUPS, grouplist); - if (n < 0) { - if (errno == EINVAL) { - n = getgroups(0, NULL); - if (n == -1) { - return posix_error(); - } - if (n == 0) { - /* Avoid malloc(0) */ - alt_grouplist = grouplist; - } else { - alt_grouplist = PyMem_New(gid_t, n); - if (alt_grouplist == NULL) { - return PyErr_NoMemory(); - } - n = getgroups(n, alt_grouplist); - if (n == -1) { - PyMem_Free(alt_grouplist); - return posix_error(); - } - } - } else { - return posix_error(); - } - } -#endif - - result = PyList_New(n); - if (result != NULL) { - int i; - for (i = 0; i < n; ++i) { - PyObject *o = _PyLong_FromGid(alt_grouplist[i]); - if (o == NULL) { - Py_DECREF(result); - result = NULL; - break; - } - PyList_SET_ITEM(result, i, o); - } - } - - if (alt_grouplist != grouplist) { - PyMem_Free(alt_grouplist); - } - - return result; -} -#endif /* HAVE_GETGROUPS */ - -#ifdef HAVE_INITGROUPS -#ifdef __APPLE__ -/*[clinic input] -os.initgroups - - username as oname: FSConverter - gid: int - / - -Initialize the group access list. - -Call the system initgroups() to initialize the group access list with all of -the groups of which the specified username is a member, plus the specified -group id. -[clinic start generated code]*/ - -static PyObject * -os_initgroups_impl(PyObject *module, PyObject *oname, int gid) -/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/ -#else -/*[clinic input] -os.initgroups - - username as oname: FSConverter - gid: gid_t - / - -Initialize the group access list. - -Call the system initgroups() to initialize the group access list with all of -the groups of which the specified username is a member, plus the specified -group id. -[clinic start generated code]*/ - -static PyObject * -os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid) -/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/ -#endif -{ - const char *username = PyBytes_AS_STRING(oname); - - if (initgroups(username, gid) == -1) - return PyErr_SetFromErrno(PyExc_OSError); - - Py_RETURN_NONE; -} -#endif /* HAVE_INITGROUPS */ - - -#ifdef HAVE_GETPGID -/*[clinic input] -os.getpgid - - pid: pid_t - -Call the system call getpgid(), and return the result. -[clinic start generated code]*/ - -static PyObject * -os_getpgid_impl(PyObject *module, pid_t pid) -/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/ -{ - pid_t pgid = getpgid(pid); - if (pgid < 0) - return posix_error(); - return PyLong_FromPid(pgid); -} -#endif /* HAVE_GETPGID */ - - -#ifdef HAVE_GETPGRP -/*[clinic input] -os.getpgrp - -Return the current process group id. -[clinic start generated code]*/ - -static PyObject * -os_getpgrp_impl(PyObject *module) -/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/ -{ -#ifdef GETPGRP_HAVE_ARG - return PyLong_FromPid(getpgrp(0)); -#else /* GETPGRP_HAVE_ARG */ - return PyLong_FromPid(getpgrp()); -#endif /* GETPGRP_HAVE_ARG */ -} -#endif /* HAVE_GETPGRP */ - - -#ifdef HAVE_SETPGRP -/*[clinic input] -os.setpgrp - -Make the current process the leader of its process group. -[clinic start generated code]*/ - -static PyObject * -os_setpgrp_impl(PyObject *module) -/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/ -{ -#ifdef SETPGRP_HAVE_ARG - if (setpgrp(0, 0) < 0) -#else /* SETPGRP_HAVE_ARG */ - if (setpgrp() < 0) -#endif /* SETPGRP_HAVE_ARG */ - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETPGRP */ - -#ifdef HAVE_GETPPID - -#ifdef MS_WINDOWS -#include - -static PyObject* -win32_getppid() -{ - HANDLE snapshot; - pid_t mypid; - PyObject* result = NULL; - BOOL have_record; - PROCESSENTRY32 pe; - - mypid = getpid(); /* This function never fails */ - - snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (snapshot == INVALID_HANDLE_VALUE) - return PyErr_SetFromWindowsErr(GetLastError()); - - pe.dwSize = sizeof(pe); - have_record = Process32First(snapshot, &pe); - while (have_record) { - if (mypid == (pid_t)pe.th32ProcessID) { - /* We could cache the ulong value in a static variable. */ - result = PyLong_FromPid((pid_t)pe.th32ParentProcessID); - break; - } - - have_record = Process32Next(snapshot, &pe); - } - - /* If our loop exits and our pid was not found (result will be NULL) - * then GetLastError will return ERROR_NO_MORE_FILES. This is an - * error anyway, so let's raise it. */ - if (!result) - result = PyErr_SetFromWindowsErr(GetLastError()); - - CloseHandle(snapshot); - - return result; -} -#endif /*MS_WINDOWS*/ - - -/*[clinic input] -os.getppid - -Return the parent's process id. - -If the parent process has already exited, Windows machines will still -return its id; others systems will return the id of the 'init' process (1). -[clinic start generated code]*/ - -static PyObject * -os_getppid_impl(PyObject *module) -/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/ -{ -#ifdef MS_WINDOWS - return win32_getppid(); -#else - return PyLong_FromPid(getppid()); -#endif -} -#endif /* HAVE_GETPPID */ - - -#ifdef HAVE_GETLOGIN -/*[clinic input] -os.getlogin - -Return the actual login name. -[clinic start generated code]*/ - -static PyObject * -os_getlogin_impl(PyObject *module) -/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/ -{ - PyObject *result = NULL; -#ifdef MS_WINDOWS - wchar_t user_name[UNLEN + 1]; - DWORD num_chars = Py_ARRAY_LENGTH(user_name); - - if (GetUserNameW(user_name, &num_chars)) { - /* num_chars is the number of unicode chars plus null terminator */ - result = PyUnicode_FromWideChar(user_name, num_chars - 1); - } - else - result = PyErr_SetFromWindowsErr(GetLastError()); -#else - char *name; - int old_errno = errno; - - errno = 0; - name = getlogin(); - if (name == NULL) { - if (errno) - posix_error(); - else - PyErr_SetString(PyExc_OSError, "unable to determine login name"); - } - else - result = PyUnicode_DecodeFSDefault(name); - errno = old_errno; -#endif - return result; -} -#endif /* HAVE_GETLOGIN */ - - -#ifdef HAVE_GETUID -/*[clinic input] -os.getuid - -Return the current process's user id. -[clinic start generated code]*/ - -static PyObject * -os_getuid_impl(PyObject *module) -/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/ -{ - return _PyLong_FromUid(getuid()); -} -#endif /* HAVE_GETUID */ - - -#ifdef MS_WINDOWS -#define HAVE_KILL -#endif /* MS_WINDOWS */ - -#ifdef HAVE_KILL -/*[clinic input] -os.kill - - pid: pid_t - signal: Py_ssize_t - / - -Kill a process with a signal. -[clinic start generated code]*/ - -static PyObject * -os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) -/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/ -{ - if (PySys_Audit("os.kill", "in", pid, signal) < 0) { - return NULL; - } -#ifndef MS_WINDOWS - if (kill(pid, (int)signal) == -1) - return posix_error(); - Py_RETURN_NONE; -#else /* !MS_WINDOWS */ - PyObject *result; - DWORD sig = (DWORD)signal; - DWORD err; - HANDLE handle; - - /* Console processes which share a common console can be sent CTRL+C or - CTRL+BREAK events, provided they handle said events. */ - if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { - if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) { - err = GetLastError(); - PyErr_SetFromWindowsErr(err); - } - else - Py_RETURN_NONE; - } - - /* If the signal is outside of what GenerateConsoleCtrlEvent can use, - attempt to open and terminate the process. */ - handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); - if (handle == NULL) { - err = GetLastError(); - return PyErr_SetFromWindowsErr(err); - } - - if (TerminateProcess(handle, sig) == 0) { - err = GetLastError(); - result = PyErr_SetFromWindowsErr(err); - } else { - Py_INCREF(Py_None); - result = Py_None; - } - - CloseHandle(handle); - return result; -#endif /* !MS_WINDOWS */ -} -#endif /* HAVE_KILL */ - - -#ifdef HAVE_KILLPG -/*[clinic input] -os.killpg - - pgid: pid_t - signal: int - / - -Kill a process group with a signal. -[clinic start generated code]*/ - -static PyObject * -os_killpg_impl(PyObject *module, pid_t pgid, int signal) -/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/ -{ - if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) { - return NULL; - } - /* XXX some man pages make the `pgid` parameter an int, others - a pid_t. Since getpgrp() returns a pid_t, we assume killpg should - take the same type. Moreover, pid_t is always at least as wide as - int (else compilation of this module fails), which is safe. */ - if (killpg(pgid, signal) == -1) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_KILLPG */ - - -#ifdef HAVE_PLOCK -#ifdef HAVE_SYS_LOCK_H -#include -#endif - -/*[clinic input] -os.plock - op: int - / - -Lock program segments into memory."); -[clinic start generated code]*/ - -static PyObject * -os_plock_impl(PyObject *module, int op) -/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/ -{ - if (plock(op) == -1) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_PLOCK */ - - -#ifdef HAVE_SETUID -/*[clinic input] -os.setuid - - uid: uid_t - / - -Set the current process's user id. -[clinic start generated code]*/ - -static PyObject * -os_setuid_impl(PyObject *module, uid_t uid) -/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/ -{ - if (setuid(uid) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETUID */ - - -#ifdef HAVE_SETEUID -/*[clinic input] -os.seteuid - - euid: uid_t - / - -Set the current process's effective user id. -[clinic start generated code]*/ - -static PyObject * -os_seteuid_impl(PyObject *module, uid_t euid) -/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/ -{ - if (seteuid(euid) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETEUID */ - - -#ifdef HAVE_SETEGID -/*[clinic input] -os.setegid - - egid: gid_t - / - -Set the current process's effective group id. -[clinic start generated code]*/ - -static PyObject * -os_setegid_impl(PyObject *module, gid_t egid) -/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/ -{ - if (setegid(egid) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETEGID */ - - -#ifdef HAVE_SETREUID -/*[clinic input] -os.setreuid - - ruid: uid_t - euid: uid_t - / - -Set the current process's real and effective user ids. -[clinic start generated code]*/ - -static PyObject * -os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid) -/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/ -{ - if (setreuid(ruid, euid) < 0) { - return posix_error(); - } else { - Py_RETURN_NONE; - } -} -#endif /* HAVE_SETREUID */ - - -#ifdef HAVE_SETREGID -/*[clinic input] -os.setregid - - rgid: gid_t - egid: gid_t - / - -Set the current process's real and effective group ids. -[clinic start generated code]*/ - -static PyObject * -os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid) -/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/ -{ - if (setregid(rgid, egid) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETREGID */ - - -#ifdef HAVE_SETGID -/*[clinic input] -os.setgid - gid: gid_t - / - -Set the current process's group id. -[clinic start generated code]*/ - -static PyObject * -os_setgid_impl(PyObject *module, gid_t gid) -/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/ -{ - if (setgid(gid) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETGID */ - - -#ifdef HAVE_SETGROUPS -/*[clinic input] -os.setgroups - - groups: object - / - -Set the groups of the current process to list. -[clinic start generated code]*/ - -static PyObject * -os_setgroups(PyObject *module, PyObject *groups) -/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/ -{ - Py_ssize_t i, len; - gid_t grouplist[MAX_GROUPS]; - - if (!PySequence_Check(groups)) { - PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); - return NULL; - } - len = PySequence_Size(groups); - if (len < 0) { - return NULL; - } - if (len > MAX_GROUPS) { - PyErr_SetString(PyExc_ValueError, "too many groups"); - return NULL; - } - for(i = 0; i < len; i++) { - PyObject *elem; - elem = PySequence_GetItem(groups, i); - if (!elem) - return NULL; - if (!PyLong_Check(elem)) { - PyErr_SetString(PyExc_TypeError, - "groups must be integers"); - Py_DECREF(elem); - return NULL; - } else { - if (!_Py_Gid_Converter(elem, &grouplist[i])) { - Py_DECREF(elem); - return NULL; - } - } - Py_DECREF(elem); - } - - if (setgroups(len, grouplist) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETGROUPS */ - -#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) -static PyObject * -wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru) -{ - PyObject *result; - PyObject *struct_rusage; - - if (pid == -1) - return posix_error(); - - // If wait succeeded but no child was ready to report status, ru will not - // have been populated. - if (pid == 0) { - memset(ru, 0, sizeof(*ru)); - } - - PyObject *m = PyImport_ImportModuleNoBlock("resource"); - if (m == NULL) - return NULL; - struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage); - Py_DECREF(m); - if (struct_rusage == NULL) - return NULL; - - /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ - result = PyStructSequence_New((PyTypeObject*) struct_rusage); - Py_DECREF(struct_rusage); - if (!result) - return NULL; - -#ifndef doubletime -#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) -#endif - - PyStructSequence_SET_ITEM(result, 0, - PyFloat_FromDouble(doubletime(ru->ru_utime))); - PyStructSequence_SET_ITEM(result, 1, - PyFloat_FromDouble(doubletime(ru->ru_stime))); -#define SET_INT(result, index, value)\ - PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value)) - SET_INT(result, 2, ru->ru_maxrss); - SET_INT(result, 3, ru->ru_ixrss); - SET_INT(result, 4, ru->ru_idrss); - SET_INT(result, 5, ru->ru_isrss); - SET_INT(result, 6, ru->ru_minflt); - SET_INT(result, 7, ru->ru_majflt); - SET_INT(result, 8, ru->ru_nswap); - SET_INT(result, 9, ru->ru_inblock); - SET_INT(result, 10, ru->ru_oublock); - SET_INT(result, 11, ru->ru_msgsnd); - SET_INT(result, 12, ru->ru_msgrcv); - SET_INT(result, 13, ru->ru_nsignals); - SET_INT(result, 14, ru->ru_nvcsw); - SET_INT(result, 15, ru->ru_nivcsw); -#undef SET_INT - - if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } - - return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result); -} -#endif /* HAVE_WAIT3 || HAVE_WAIT4 */ - - -#ifdef HAVE_WAIT3 -/*[clinic input] -os.wait3 - - options: int -Wait for completion of a child process. - -Returns a tuple of information about the child process: - (pid, status, rusage) -[clinic start generated code]*/ - -static PyObject * -os_wait3_impl(PyObject *module, int options) -/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/ -{ - pid_t pid; - struct rusage ru; - int async_err = 0; - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - do { - Py_BEGIN_ALLOW_THREADS - pid = wait3(&status, options, &ru); - Py_END_ALLOW_THREADS - } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (pid < 0) - return (!async_err) ? posix_error() : NULL; - - return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru); -} -#endif /* HAVE_WAIT3 */ - - -#ifdef HAVE_WAIT4 -/*[clinic input] - -os.wait4 - - pid: pid_t - options: int - -Wait for completion of a specific child process. - -Returns a tuple of information about the child process: - (pid, status, rusage) -[clinic start generated code]*/ - -static PyObject * -os_wait4_impl(PyObject *module, pid_t pid, int options) -/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/ -{ - pid_t res; - struct rusage ru; - int async_err = 0; - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - do { - Py_BEGIN_ALLOW_THREADS - res = wait4(pid, &status, options, &ru); - Py_END_ALLOW_THREADS - } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (res < 0) - return (!async_err) ? posix_error() : NULL; - - return wait_helper(module, res, WAIT_STATUS_INT(status), &ru); -} -#endif /* HAVE_WAIT4 */ - - -#if defined(HAVE_WAITID) && !defined(__APPLE__) -/*[clinic input] -os.waitid - - idtype: idtype_t - Must be one of be P_PID, P_PGID or P_ALL. - id: id_t - The id to wait on. - options: int - Constructed from the ORing of one or more of WEXITED, WSTOPPED - or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT. - / - -Returns the result of waiting for a process or processes. - -Returns either waitid_result or None if WNOHANG is specified and there are -no children in a waitable state. -[clinic start generated code]*/ - -static PyObject * -os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options) -/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/ -{ - PyObject *result; - int res; - int async_err = 0; - siginfo_t si; - si.si_pid = 0; - - do { - Py_BEGIN_ALLOW_THREADS - res = waitid(idtype, id, &si, options); - Py_END_ALLOW_THREADS - } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (res < 0) - return (!async_err) ? posix_error() : NULL; - - if (si.si_pid == 0) - Py_RETURN_NONE; - - PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType; - result = PyStructSequence_New((PyTypeObject *)WaitidResultType); - if (!result) - return NULL; - - PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid)); - PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid)); - PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo))); - PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status))); - PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code))); - if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } - - return result; -} -#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */ - - -#if defined(HAVE_WAITPID) -/*[clinic input] -os.waitpid - pid: pid_t - options: int - / - -Wait for completion of a given child process. - -Returns a tuple of information regarding the child process: - (pid, status) - -The options argument is ignored on Windows. -[clinic start generated code]*/ - -static PyObject * -os_waitpid_impl(PyObject *module, pid_t pid, int options) -/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/ -{ - pid_t res; - int async_err = 0; - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - do { - Py_BEGIN_ALLOW_THREADS - res = waitpid(pid, &status, options); - Py_END_ALLOW_THREADS - } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (res < 0) - return (!async_err) ? posix_error() : NULL; - - return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status)); -} -#elif defined(HAVE_CWAIT) -/* MS C has a variant of waitpid() that's usable for most purposes. */ -/*[clinic input] -os.waitpid - pid: intptr_t - options: int - / - -Wait for completion of a given process. - -Returns a tuple of information regarding the process: - (pid, status << 8) - -The options argument is ignored on Windows. -[clinic start generated code]*/ - -static PyObject * -os_waitpid_impl(PyObject *module, intptr_t pid, int options) -/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/ -{ - int status; - intptr_t res; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - res = _cwait(&status, pid, options); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (res < 0) - return (!async_err) ? posix_error() : NULL; - - unsigned long long ustatus = (unsigned int)status; - - /* shift the status left a byte so this is more like the POSIX waitpid */ - return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8); -} -#endif - - -#ifdef HAVE_WAIT -/*[clinic input] -os.wait - -Wait for completion of a child process. - -Returns a tuple of information about the child process: - (pid, status) -[clinic start generated code]*/ - -static PyObject * -os_wait_impl(PyObject *module) -/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/ -{ - pid_t pid; - int async_err = 0; - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - do { - Py_BEGIN_ALLOW_THREADS - pid = wait(&status); - Py_END_ALLOW_THREADS - } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (pid < 0) - return (!async_err) ? posix_error() : NULL; - - return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); -} -#endif /* HAVE_WAIT */ - -#if defined(__linux__) && defined(__NR_pidfd_open) -/*[clinic input] -os.pidfd_open - pid: pid_t - flags: unsigned_int = 0 - -Return a file descriptor referring to the process *pid*. - -The descriptor can be used to perform process management without races and -signals. -[clinic start generated code]*/ - -static PyObject * -os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags) -/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/ -{ - int fd = syscall(__NR_pidfd_open, pid, flags); - if (fd < 0) { - return posix_error(); - } - return PyLong_FromLong(fd); -} -#endif - - -#if defined(HAVE_READLINK) || defined(MS_WINDOWS) -/*[clinic input] -os.readlink - - path: path_t - * - dir_fd: dir_fd(requires='readlinkat') = None - -Return a string representing the path to which the symbolic link points. - -If dir_fd is not None, it should be a file descriptor open to a directory, -and path should be relative; path will then be relative to that directory. - -dir_fd may not be implemented on your platform. If it is unavailable, -using it will raise a NotImplementedError. -[clinic start generated code]*/ - -static PyObject * -os_readlink_impl(PyObject *module, path_t *path, int dir_fd) -/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/ -{ -#if defined(HAVE_READLINK) - char buffer[MAXPATHLEN+1]; - ssize_t length; -#ifdef HAVE_READLINKAT - int readlinkat_unavailable = 0; -#endif - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_READLINKAT - if (dir_fd != DEFAULT_DIR_FD) { - if (HAVE_READLINKAT_RUNTIME) { - length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN); - } else { - readlinkat_unavailable = 1; - } - } else -#endif - length = readlink(path->narrow, buffer, MAXPATHLEN); - Py_END_ALLOW_THREADS - -#ifdef HAVE_READLINKAT - if (readlinkat_unavailable) { - argument_unavailable_error(NULL, "dir_fd"); - return NULL; - } -#endif - - if (length < 0) { - return path_error(path); - } - buffer[length] = '\0'; - - if (PyUnicode_Check(path->object)) - return PyUnicode_DecodeFSDefaultAndSize(buffer, length); - else - return PyBytes_FromStringAndSize(buffer, length); -#elif defined(MS_WINDOWS) - DWORD n_bytes_returned; - DWORD io_result = 0; - HANDLE reparse_point_handle; - char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; - PyObject *result = NULL; - - /* First get a handle to the reparse point */ - Py_BEGIN_ALLOW_THREADS - reparse_point_handle = CreateFileW( - path->wide, - 0, - 0, - 0, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, - 0); - if (reparse_point_handle != INVALID_HANDLE_VALUE) { - /* New call DeviceIoControl to read the reparse point */ - io_result = DeviceIoControl( - reparse_point_handle, - FSCTL_GET_REPARSE_POINT, - 0, 0, /* in buffer */ - target_buffer, sizeof(target_buffer), - &n_bytes_returned, - 0 /* we're not using OVERLAPPED_IO */ - ); - CloseHandle(reparse_point_handle); - } - Py_END_ALLOW_THREADS - - if (io_result == 0) { - return path_error(path); - } - - wchar_t *name = NULL; - Py_ssize_t nameLen = 0; - if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) - { - name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset); - nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); - } - else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) - { - name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer + - rdb->MountPointReparseBuffer.SubstituteNameOffset); - nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t); - } - else - { - PyErr_SetString(PyExc_ValueError, "not a symbolic link"); - } - if (name) { - if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) { - /* Our buffer is mutable, so this is okay */ - name[1] = L'\\'; - } - result = PyUnicode_FromWideChar(name, nameLen); - if (result && path->narrow) { - Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); - } - } - return result; -#endif -} -#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */ - -#if defined(MS_WINDOWS) - -/* Remove the last portion of the path - return 0 on success */ -static int -_dirnameW(WCHAR *path) -{ - WCHAR *ptr; - size_t length = wcsnlen_s(path, MAX_PATH); - if (length == MAX_PATH) { - return -1; - } - - /* walk the path from the end until a backslash is encountered */ - for(ptr = path + length; ptr != path; ptr--) { - if (*ptr == L'\\' || *ptr == L'/') { - break; - } - } - *ptr = 0; - return 0; -} - -#endif - -#ifdef HAVE_SYMLINK - -#if defined(MS_WINDOWS) - -/* Is this path absolute? */ -static int -_is_absW(const WCHAR *path) -{ - return path[0] == L'\\' || path[0] == L'/' || - (path[0] && path[1] == L':'); -} - -/* join root and rest with a backslash - return 0 on success */ -static int -_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) -{ - if (_is_absW(rest)) { - return wcscpy_s(dest_path, MAX_PATH, rest); - } - - if (wcscpy_s(dest_path, MAX_PATH, root)) { - return -1; - } - - if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) { - return -1; - } - - return wcscat_s(dest_path, MAX_PATH, rest); -} - -/* Return True if the path at src relative to dest is a directory */ -static int -_check_dirW(LPCWSTR src, LPCWSTR dest) -{ - WIN32_FILE_ATTRIBUTE_DATA src_info; - WCHAR dest_parent[MAX_PATH]; - WCHAR src_resolved[MAX_PATH] = L""; - - /* dest_parent = os.path.dirname(dest) */ - if (wcscpy_s(dest_parent, MAX_PATH, dest) || - _dirnameW(dest_parent)) { - return 0; - } - /* src_resolved = os.path.join(dest_parent, src) */ - if (_joinW(src_resolved, dest_parent, src)) { - return 0; - } - return ( - GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info) - && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY - ); -} -#endif - - -/*[clinic input] -os.symlink - src: path_t - dst: path_t - target_is_directory: bool = False - * - dir_fd: dir_fd(requires='symlinkat')=None - -# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\ - -Create a symbolic link pointing to src named dst. - -target_is_directory is required on Windows if the target is to be - interpreted as a directory. (On Windows, symlink requires - Windows 6.0 or greater, and raises a NotImplementedError otherwise.) - target_is_directory is ignored on non-Windows platforms. - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. - -[clinic start generated code]*/ - -static PyObject * -os_symlink_impl(PyObject *module, path_t *src, path_t *dst, - int target_is_directory, int dir_fd) -/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/ -{ -#ifdef MS_WINDOWS - DWORD result; - DWORD flags = 0; - - /* Assumed true, set to false if detected to not be available. */ - static int windows_has_symlink_unprivileged_flag = TRUE; -#else - int result; -#ifdef HAVE_SYMLINKAT - int symlinkat_unavailable = 0; -#endif -#endif - - if (PySys_Audit("os.symlink", "OOi", src->object, dst->object, - dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { - return NULL; - } - -#ifdef MS_WINDOWS - - if (windows_has_symlink_unprivileged_flag) { - /* Allow non-admin symlinks if system allows it. */ - flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; - } - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - /* if src is a directory, ensure flags==1 (target_is_directory bit) */ - if (target_is_directory || _check_dirW(src->wide, dst->wide)) { - flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; - } - - result = CreateSymbolicLinkW(dst->wide, src->wide, flags); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - - if (windows_has_symlink_unprivileged_flag && !result && - ERROR_INVALID_PARAMETER == GetLastError()) { - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - /* This error might be caused by - SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported. - Try again, and update windows_has_symlink_unprivileged_flag if we - are successful this time. - - NOTE: There is a risk of a race condition here if there are other - conditions than the flag causing ERROR_INVALID_PARAMETER, and - another process (or thread) changes that condition in between our - calls to CreateSymbolicLink. - */ - flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); - result = CreateSymbolicLinkW(dst->wide, src->wide, flags); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - - if (result || ERROR_INVALID_PARAMETER != GetLastError()) { - windows_has_symlink_unprivileged_flag = FALSE; - } - } - - if (!result) - return path_error2(src, dst); - -#else - - if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { - PyErr_SetString(PyExc_ValueError, - "symlink: src and dst must be the same type"); - return NULL; - } - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_SYMLINKAT - if (dir_fd != DEFAULT_DIR_FD) { - if (HAVE_SYMLINKAT_RUNTIME) { - result = symlinkat(src->narrow, dir_fd, dst->narrow); - } else { - symlinkat_unavailable = 1; - } - } else -#endif - result = symlink(src->narrow, dst->narrow); - Py_END_ALLOW_THREADS - -#ifdef HAVE_SYMLINKAT - if (symlinkat_unavailable) { - argument_unavailable_error(NULL, "dir_fd"); - return NULL; - } -#endif - - if (result) - return path_error2(src, dst); -#endif - - Py_RETURN_NONE; -} -#endif /* HAVE_SYMLINK */ - - - - -static PyStructSequence_Field times_result_fields[] = { - {"user", "user time"}, - {"system", "system time"}, - {"children_user", "user time of children"}, - {"children_system", "system time of children"}, - {"elapsed", "elapsed time since an arbitrary point in the past"}, - {NULL} -}; - -PyDoc_STRVAR(times_result__doc__, -"times_result: Result from os.times().\n\n\ -This object may be accessed either as a tuple of\n\ - (user, system, children_user, children_system, elapsed),\n\ -or via the attributes user, system, children_user, children_system,\n\ -and elapsed.\n\ -\n\ -See os.times for more information."); - -static PyStructSequence_Desc times_result_desc = { - "times_result", /* name */ - times_result__doc__, /* doc */ - times_result_fields, - 5 -}; - -#ifdef MS_WINDOWS -#define HAVE_TIMES /* mandatory, for the method table */ -#endif - -#ifdef HAVE_TIMES - -static PyObject * -build_times_result(PyObject *module, double user, double system, - double children_user, double children_system, - double elapsed) -{ - PyObject *TimesResultType = get_posix_state(module)->TimesResultType; - PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType); - if (value == NULL) - return NULL; - -#define SET(i, field) \ - { \ - PyObject *o = PyFloat_FromDouble(field); \ - if (!o) { \ - Py_DECREF(value); \ - return NULL; \ - } \ - PyStructSequence_SET_ITEM(value, i, o); \ - } \ - - SET(0, user); - SET(1, system); - SET(2, children_user); - SET(3, children_system); - SET(4, elapsed); - -#undef SET - - return value; -} - - -#ifndef MS_WINDOWS -#define NEED_TICKS_PER_SECOND -static long ticks_per_second = -1; -#endif /* MS_WINDOWS */ - -/*[clinic input] -os.times - -Return a collection containing process timing information. - -The object returned behaves like a named tuple with these fields: - (utime, stime, cutime, cstime, elapsed_time) -All fields are floating point numbers. -[clinic start generated code]*/ - -static PyObject * -os_times_impl(PyObject *module) -/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/ -#ifdef MS_WINDOWS -{ - FILETIME create, exit, kernel, user; - HANDLE hProc; - hProc = GetCurrentProcess(); - GetProcessTimes(hProc, &create, &exit, &kernel, &user); - /* The fields of a FILETIME structure are the hi and lo part - of a 64-bit value expressed in 100 nanosecond units. - 1e7 is one second in such units; 1e-7 the inverse. - 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. - */ - return build_times_result(module, - (double)(user.dwHighDateTime*429.4967296 + - user.dwLowDateTime*1e-7), - (double)(kernel.dwHighDateTime*429.4967296 + - kernel.dwLowDateTime*1e-7), - (double)0, - (double)0, - (double)0); -} -#else /* MS_WINDOWS */ -{ - - - struct tms t; - clock_t c; - errno = 0; - c = times(&t); - if (c == (clock_t) -1) - return posix_error(); - return build_times_result(module, - (double)t.tms_utime / ticks_per_second, - (double)t.tms_stime / ticks_per_second, - (double)t.tms_cutime / ticks_per_second, - (double)t.tms_cstime / ticks_per_second, - (double)c / ticks_per_second); -} -#endif /* MS_WINDOWS */ -#endif /* HAVE_TIMES */ - - -#ifdef HAVE_GETSID -/*[clinic input] -os.getsid - - pid: pid_t - / - -Call the system call getsid(pid) and return the result. -[clinic start generated code]*/ - -static PyObject * -os_getsid_impl(PyObject *module, pid_t pid) -/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/ -{ - int sid; - sid = getsid(pid); - if (sid < 0) - return posix_error(); - return PyLong_FromLong((long)sid); -} -#endif /* HAVE_GETSID */ - - -#ifdef HAVE_SETSID -/*[clinic input] -os.setsid - -Call the system call setsid(). -[clinic start generated code]*/ - -static PyObject * -os_setsid_impl(PyObject *module) -/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/ -{ - if (setsid() < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETSID */ - - -#ifdef HAVE_SETPGID -/*[clinic input] -os.setpgid - - pid: pid_t - pgrp: pid_t - / - -Call the system call setpgid(pid, pgrp). -[clinic start generated code]*/ - -static PyObject * -os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp) -/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/ -{ - if (setpgid(pid, pgrp) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETPGID */ - - -#ifdef HAVE_TCGETPGRP -/*[clinic input] -os.tcgetpgrp - - fd: int - / - -Return the process group associated with the terminal specified by fd. -[clinic start generated code]*/ - -static PyObject * -os_tcgetpgrp_impl(PyObject *module, int fd) -/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/ -{ - pid_t pgid = tcgetpgrp(fd); - if (pgid < 0) - return posix_error(); - return PyLong_FromPid(pgid); -} -#endif /* HAVE_TCGETPGRP */ - - -#ifdef HAVE_TCSETPGRP -/*[clinic input] -os.tcsetpgrp - - fd: int - pgid: pid_t - / - -Set the process group associated with the terminal specified by fd. -[clinic start generated code]*/ - -static PyObject * -os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid) -/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/ -{ - if (tcsetpgrp(fd, pgid) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_TCSETPGRP */ - -/* Functions acting on file descriptors */ - -#ifdef O_CLOEXEC -extern int _Py_open_cloexec_works; -#endif - - -/*[clinic input] -os.open -> int - path: path_t - flags: int - mode: int = 0o777 - * - dir_fd: dir_fd(requires='openat') = None - -# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ - -Open a file for low level IO. Returns a file descriptor (integer). - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. -[clinic start generated code]*/ - -static int -os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd) -/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/ -{ - int fd; - int async_err = 0; -#ifdef HAVE_OPENAT - int openat_unavailable = 0; -#endif - -#ifdef O_CLOEXEC - int *atomic_flag_works = &_Py_open_cloexec_works; -#elif !defined(MS_WINDOWS) - int *atomic_flag_works = NULL; -#endif - -#ifdef MS_WINDOWS - flags |= O_NOINHERIT; -#elif defined(O_CLOEXEC) - flags |= O_CLOEXEC; -#endif - - if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) { - return -1; - } - - _Py_BEGIN_SUPPRESS_IPH - do { - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - fd = _wopen(path->wide, flags, mode); -#else -#ifdef HAVE_OPENAT - if (dir_fd != DEFAULT_DIR_FD) { - if (HAVE_OPENAT_RUNTIME) { - fd = openat(dir_fd, path->narrow, flags, mode); - - } else { - openat_unavailable = 1; - fd = -1; - } - } else -#endif /* HAVE_OPENAT */ - fd = open(path->narrow, flags, mode); -#endif /* !MS_WINDOWS */ - Py_END_ALLOW_THREADS - } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - _Py_END_SUPPRESS_IPH - -#ifdef HAVE_OPENAT - if (openat_unavailable) { - argument_unavailable_error(NULL, "dir_fd"); - return -1; - } -#endif - - if (fd < 0) { - if (!async_err) - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); - return -1; - } - -#ifndef MS_WINDOWS - if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { - close(fd); - return -1; - } -#endif - - return fd; -} - - -/*[clinic input] -os.close - - fd: int - -Close a file descriptor. -[clinic start generated code]*/ - -static PyObject * -os_close_impl(PyObject *module, int fd) -/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/ -{ - int res; - /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/ - * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html - * for more details. - */ - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - res = close(fd); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_RETURN_NONE; -} - - -#ifdef HAVE_FDWALK -static int -_fdwalk_close_func(void *lohi, int fd) -{ - int lo = ((int *)lohi)[0]; - int hi = ((int *)lohi)[1]; - - if (fd >= hi) { - return 1; - } - else if (fd >= lo) { - /* Ignore errors */ - (void)close(fd); - } - return 0; -} -#endif /* HAVE_FDWALK */ - -/*[clinic input] -os.closerange - - fd_low: int - fd_high: int - / - -Closes all file descriptors in [fd_low, fd_high), ignoring errors. -[clinic start generated code]*/ - -static PyObject * -os_closerange_impl(PyObject *module, int fd_low, int fd_high) -/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/ -{ -#ifdef HAVE_FDWALK - int lohi[2]; -#endif - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef HAVE_FDWALK - lohi[0] = Py_MAX(fd_low, 0); - lohi[1] = fd_high; - fdwalk(_fdwalk_close_func, lohi); -#else - fd_low = Py_MAX(fd_low, 0); -#ifdef __FreeBSD__ - if (fd_high >= sysconf(_SC_OPEN_MAX)) { - /* Any errors encountered while closing file descriptors are ignored */ - closefrom(fd_low); - } - else -#endif - { - for (int i = fd_low; i < fd_high; i++) { - /* Ignore errors */ - (void)close(i); - } - } -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - Py_RETURN_NONE; -} - - -/*[clinic input] -os.dup -> int - - fd: int - / - -Return a duplicate of a file descriptor. -[clinic start generated code]*/ - -static int -os_dup_impl(PyObject *module, int fd) -/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/ -{ - return _Py_dup(fd); -} - - -/*[clinic input] -os.dup2 -> int - fd: int - fd2: int - inheritable: bool=True - -Duplicate file descriptor. -[clinic start generated code]*/ - -static int -os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable) -/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/ -{ - int res = 0; -#if defined(HAVE_DUP3) && \ - !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)) - /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */ - static int dup3_works = -1; -#endif - - if (fd < 0 || fd2 < 0) { - posix_error(); - return -1; - } - - /* dup2() can fail with EINTR if the target FD is already open, because it - * then has to be closed. See os_close_impl() for why we don't handle EINTR - * upon close(), and therefore below. - */ -#ifdef MS_WINDOWS - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - res = dup2(fd, fd2); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - if (res < 0) { - posix_error(); - return -1; - } - res = fd2; // msvcrt dup2 returns 0 on success. - - /* Character files like console cannot be make non-inheritable */ - if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { - close(fd2); - return -1; - } - -#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC) - Py_BEGIN_ALLOW_THREADS - if (!inheritable) - res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2); - else - res = dup2(fd, fd2); - Py_END_ALLOW_THREADS - if (res < 0) { - posix_error(); - return -1; - } - -#else - -#ifdef HAVE_DUP3 - if (!inheritable && dup3_works != 0) { - Py_BEGIN_ALLOW_THREADS - res = dup3(fd, fd2, O_CLOEXEC); - Py_END_ALLOW_THREADS - if (res < 0) { - if (dup3_works == -1) - dup3_works = (errno != ENOSYS); - if (dup3_works) { - posix_error(); - return -1; - } - } - } - - if (inheritable || dup3_works == 0) - { -#endif - Py_BEGIN_ALLOW_THREADS - res = dup2(fd, fd2); - Py_END_ALLOW_THREADS - if (res < 0) { - posix_error(); - return -1; - } - - if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { - close(fd2); - return -1; - } -#ifdef HAVE_DUP3 - } -#endif - -#endif - - return res; -} - - -#ifdef HAVE_LOCKF -/*[clinic input] -os.lockf - - fd: int - An open file descriptor. - command: int - One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST. - length: Py_off_t - The number of bytes to lock, starting at the current position. - / - -Apply, test or remove a POSIX lock on an open file descriptor. - -[clinic start generated code]*/ - -static PyObject * -os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length) -/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/ -{ - int res; - - if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - res = lockf(fd, command, length); - Py_END_ALLOW_THREADS - - if (res < 0) - return posix_error(); - - Py_RETURN_NONE; -} -#endif /* HAVE_LOCKF */ - - -/*[clinic input] -os.lseek -> Py_off_t - - fd: int - position: Py_off_t - how: int - / - -Set the position of a file descriptor. Return the new position. - -Return the new cursor position in number of bytes -relative to the beginning of the file. -[clinic start generated code]*/ - -static Py_off_t -os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) -/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/ -{ - Py_off_t result; - -#ifdef SEEK_SET - /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ - switch (how) { - case 0: how = SEEK_SET; break; - case 1: how = SEEK_CUR; break; - case 2: how = SEEK_END; break; - } -#endif /* SEEK_END */ - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef MS_WINDOWS - result = _lseeki64(fd, position, how); -#else - result = lseek(fd, position, how); -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - if (result < 0) - posix_error(); - - return result; -} - - -/*[clinic input] -os.read - fd: int - length: Py_ssize_t - / - -Read from a file descriptor. Returns a bytes object. -[clinic start generated code]*/ - -static PyObject * -os_read_impl(PyObject *module, int fd, Py_ssize_t length) -/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/ -{ - Py_ssize_t n; - PyObject *buffer; - - if (length < 0) { - errno = EINVAL; - return posix_error(); - } - - length = Py_MIN(length, _PY_READ_MAX); - - buffer = PyBytes_FromStringAndSize((char *)NULL, length); - if (buffer == NULL) - return NULL; - - n = _Py_read(fd, PyBytes_AS_STRING(buffer), length); - if (n == -1) { - Py_DECREF(buffer); - return NULL; - } - - if (n != length) - _PyBytes_Resize(&buffer, n); - - return buffer; -} - -#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \ - || defined(__APPLE__))) \ - || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \ - || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2) -static int -iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type) -{ - Py_ssize_t i, j; - - *iov = PyMem_New(struct iovec, cnt); - if (*iov == NULL) { - PyErr_NoMemory(); - return -1; - } - - *buf = PyMem_New(Py_buffer, cnt); - if (*buf == NULL) { - PyMem_Del(*iov); - PyErr_NoMemory(); - return -1; - } - - for (i = 0; i < cnt; i++) { - PyObject *item = PySequence_GetItem(seq, i); - if (item == NULL) - goto fail; - if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) { - Py_DECREF(item); - goto fail; - } - Py_DECREF(item); - (*iov)[i].iov_base = (*buf)[i].buf; - (*iov)[i].iov_len = (*buf)[i].len; - } - return 0; - -fail: - PyMem_Del(*iov); - for (j = 0; j < i; j++) { - PyBuffer_Release(&(*buf)[j]); - } - PyMem_Del(*buf); - return -1; -} - -static void -iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt) -{ - int i; - PyMem_Del(iov); - for (i = 0; i < cnt; i++) { - PyBuffer_Release(&buf[i]); - } - PyMem_Del(buf); -} -#endif - - -#ifdef HAVE_READV -/*[clinic input] -os.readv -> Py_ssize_t - - fd: int - buffers: object - / - -Read from a file descriptor fd into an iterable of buffers. - -The buffers should be mutable buffers accepting bytes. -readv will transfer data into each buffer until it is full -and then move on to the next buffer in the sequence to hold -the rest of the data. - -readv returns the total number of bytes read, -which may be less than the total capacity of all the buffers. -[clinic start generated code]*/ - -static Py_ssize_t -os_readv_impl(PyObject *module, int fd, PyObject *buffers) -/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/ -{ - Py_ssize_t cnt, n; - int async_err = 0; - struct iovec *iov; - Py_buffer *buf; - - if (!PySequence_Check(buffers)) { - PyErr_SetString(PyExc_TypeError, - "readv() arg 2 must be a sequence"); - return -1; - } - - cnt = PySequence_Size(buffers); - if (cnt < 0) - return -1; - - if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) - return -1; - - do { - Py_BEGIN_ALLOW_THREADS - n = readv(fd, iov, cnt); - Py_END_ALLOW_THREADS - } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - - iov_cleanup(iov, buf, cnt); - if (n < 0) { - if (!async_err) - posix_error(); - return -1; - } - - return n; -} -#endif /* HAVE_READV */ - - -#ifdef HAVE_PREAD -/*[clinic input] -os.pread - - fd: int - length: Py_ssize_t - offset: Py_off_t - / - -Read a number of bytes from a file descriptor starting at a particular offset. - -Read length bytes from file descriptor fd, starting at offset bytes from -the beginning of the file. The file offset remains unchanged. -[clinic start generated code]*/ - -static PyObject * -os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset) -/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/ -{ - Py_ssize_t n; - int async_err = 0; - PyObject *buffer; - - if (length < 0) { - errno = EINVAL; - return posix_error(); - } - buffer = PyBytes_FromStringAndSize((char *)NULL, length); - if (buffer == NULL) - return NULL; - - do { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - n = pread(fd, PyBytes_AS_STRING(buffer), length, offset); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - - if (n < 0) { - Py_DECREF(buffer); - return (!async_err) ? posix_error() : NULL; - } - if (n != length) - _PyBytes_Resize(&buffer, n); - return buffer; -} -#endif /* HAVE_PREAD */ - -#if defined(HAVE_PREADV) || defined (HAVE_PREADV2) -/*[clinic input] -os.preadv -> Py_ssize_t - - fd: int - buffers: object - offset: Py_off_t - flags: int = 0 - / - -Reads from a file descriptor into a number of mutable bytes-like objects. - -Combines the functionality of readv() and pread(). As readv(), it will -transfer data into each buffer until it is full and then move on to the next -buffer in the sequence to hold the rest of the data. Its fourth argument, -specifies the file offset at which the input operation is to be performed. It -will return the total number of bytes read (which can be less than the total -capacity of all the objects). - -The flags argument contains a bitwise OR of zero or more of the following flags: - -- RWF_HIPRI -- RWF_NOWAIT - -Using non-zero flags requires Linux 4.6 or newer. -[clinic start generated code]*/ - -static Py_ssize_t -os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, - int flags) -/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/ -{ - Py_ssize_t cnt, n; - int async_err = 0; - struct iovec *iov; - Py_buffer *buf; - - if (!PySequence_Check(buffers)) { - PyErr_SetString(PyExc_TypeError, - "preadv2() arg 2 must be a sequence"); - return -1; - } - - cnt = PySequence_Size(buffers); - if (cnt < 0) { - return -1; - } - -#ifndef HAVE_PREADV2 - if(flags != 0) { - argument_unavailable_error("preadv2", "flags"); - return -1; - } -#endif - - if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) { - return -1; - } -#ifdef HAVE_PREADV2 - do { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - n = preadv2(fd, iov, cnt, offset, flags); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#else - do { -#ifdef __APPLE__ -/* This entire function will be removed from the module dict when the API - * is not available. - */ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -#pragma clang diagnostic ignored "-Wunguarded-availability-new" -#endif - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - n = preadv(fd, iov, cnt, offset); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - -#ifdef __APPLE__ -#pragma clang diagnostic pop -#endif - -#endif - - iov_cleanup(iov, buf, cnt); - if (n < 0) { - if (!async_err) { - posix_error(); - } - return -1; - } - - return n; -} -#endif /* HAVE_PREADV */ - - -/*[clinic input] -os.write -> Py_ssize_t - - fd: int - data: Py_buffer - / - -Write a bytes object to a file descriptor. -[clinic start generated code]*/ - -static Py_ssize_t -os_write_impl(PyObject *module, int fd, Py_buffer *data) -/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/ -{ - return _Py_write(fd, data->buf, data->len); -} - -#ifdef HAVE_SENDFILE -#ifdef __APPLE__ -/*[clinic input] -os.sendfile - - out_fd: int - in_fd: int - offset: Py_off_t - count as sbytes: Py_off_t - headers: object(c_default="NULL") = () - trailers: object(c_default="NULL") = () - flags: int = 0 - -Copy count bytes from file descriptor in_fd to file descriptor out_fd. -[clinic start generated code]*/ - -static PyObject * -os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, - Py_off_t sbytes, PyObject *headers, PyObject *trailers, - int flags) -/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/ -#elif defined(__FreeBSD__) || defined(__DragonFly__) -/*[clinic input] -os.sendfile - - out_fd: int - in_fd: int - offset: Py_off_t - count: Py_ssize_t - headers: object(c_default="NULL") = () - trailers: object(c_default="NULL") = () - flags: int = 0 - -Copy count bytes from file descriptor in_fd to file descriptor out_fd. -[clinic start generated code]*/ - -static PyObject * -os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, - Py_ssize_t count, PyObject *headers, PyObject *trailers, - int flags) -/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/ -#else -/*[clinic input] -os.sendfile - - out_fd: int - in_fd: int - offset as offobj: object - count: Py_ssize_t - -Copy count bytes from file descriptor in_fd to file descriptor out_fd. -[clinic start generated code]*/ - -static PyObject * -os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, - Py_ssize_t count) -/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/ -#endif -{ - Py_ssize_t ret; - int async_err = 0; - -#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) -#ifndef __APPLE__ - off_t sbytes; -#endif - Py_buffer *hbuf, *tbuf; - struct sf_hdtr sf; - - sf.headers = NULL; - sf.trailers = NULL; - - if (headers != NULL) { - if (!PySequence_Check(headers)) { - PyErr_SetString(PyExc_TypeError, - "sendfile() headers must be a sequence"); - return NULL; - } else { - Py_ssize_t i = PySequence_Size(headers); - if (i < 0) - return NULL; - if (i > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "sendfile() header is too large"); - return NULL; - } - if (i > 0) { - sf.hdr_cnt = (int)i; - if (iov_setup(&(sf.headers), &hbuf, - headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0) - return NULL; -#ifdef __APPLE__ - for (i = 0; i < sf.hdr_cnt; i++) { - Py_ssize_t blen = sf.headers[i].iov_len; -# define OFF_T_MAX 0x7fffffffffffffff - if (sbytes >= OFF_T_MAX - blen) { - PyErr_SetString(PyExc_OverflowError, - "sendfile() header is too large"); - return NULL; - } - sbytes += blen; - } -#endif - } - } - } - if (trailers != NULL) { - if (!PySequence_Check(trailers)) { - PyErr_SetString(PyExc_TypeError, - "sendfile() trailers must be a sequence"); - return NULL; - } else { - Py_ssize_t i = PySequence_Size(trailers); - if (i < 0) - return NULL; - if (i > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "sendfile() trailer is too large"); - return NULL; - } - if (i > 0) { - sf.trl_cnt = (int)i; - if (iov_setup(&(sf.trailers), &tbuf, - trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0) - return NULL; - } - } - } - - _Py_BEGIN_SUPPRESS_IPH - do { - Py_BEGIN_ALLOW_THREADS -#ifdef __APPLE__ - ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags); -#else - ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags); -#endif - Py_END_ALLOW_THREADS - } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - _Py_END_SUPPRESS_IPH - - if (sf.headers != NULL) - iov_cleanup(sf.headers, hbuf, sf.hdr_cnt); - if (sf.trailers != NULL) - iov_cleanup(sf.trailers, tbuf, sf.trl_cnt); - - if (ret < 0) { - if ((errno == EAGAIN) || (errno == EBUSY)) { - if (sbytes != 0) { - // some data has been sent - goto done; - } - else { - // no data has been sent; upper application is supposed - // to retry on EAGAIN or EBUSY - return posix_error(); - } - } - return (!async_err) ? posix_error() : NULL; - } - goto done; - -done: - #if !defined(HAVE_LARGEFILE_SUPPORT) - return Py_BuildValue("l", sbytes); - #else - return Py_BuildValue("L", sbytes); - #endif - -#else -#ifdef __linux__ - if (offobj == Py_None) { - do { - Py_BEGIN_ALLOW_THREADS - ret = sendfile(out_fd, in_fd, NULL, count); - Py_END_ALLOW_THREADS - } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (ret < 0) - return (!async_err) ? posix_error() : NULL; - return Py_BuildValue("n", ret); - } -#endif - off_t offset; - if (!Py_off_t_converter(offobj, &offset)) - return NULL; - -#if defined(__sun) && defined(__SVR4) - // On Solaris, sendfile raises EINVAL rather than returning 0 - // when the offset is equal or bigger than the in_fd size. - struct stat st; - - do { - Py_BEGIN_ALLOW_THREADS - ret = fstat(in_fd, &st); - Py_END_ALLOW_THREADS - } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (ret < 0) - return (!async_err) ? posix_error() : NULL; - - if (offset >= st.st_size) { - return Py_BuildValue("i", 0); - } - - // On illumos specifically sendfile() may perform a partial write but - // return -1/an error (in one confirmed case the destination socket - // had a 5 second timeout set and errno was EAGAIN) and it's on the client - // code to check if the offset parameter was modified by sendfile(). - // - // We need this variable to track said change. - off_t original_offset = offset; -#endif - - do { - Py_BEGIN_ALLOW_THREADS - ret = sendfile(out_fd, in_fd, &offset, count); -#if defined(__sun) && defined(__SVR4) - // This handles illumos-specific sendfile() partial write behavior, - // see a comment above for more details. - if (ret < 0 && offset != original_offset) { - ret = offset - original_offset; - } -#endif - Py_END_ALLOW_THREADS - } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (ret < 0) - return (!async_err) ? posix_error() : NULL; - return Py_BuildValue("n", ret); -#endif -} -#endif /* HAVE_SENDFILE */ - - -#if defined(__APPLE__) -/*[clinic input] -os._fcopyfile - - in_fd: int - out_fd: int - flags: int - / - -Efficiently copy content or metadata of 2 regular file descriptors (macOS). -[clinic start generated code]*/ - -static PyObject * -os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags) -/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/ -{ - int ret; - - Py_BEGIN_ALLOW_THREADS - ret = fcopyfile(in_fd, out_fd, NULL, flags); - Py_END_ALLOW_THREADS - if (ret < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif - - -/*[clinic input] -os.fstat - - fd : int - -Perform a stat system call on the given file descriptor. - -Like stat(), but for an open file descriptor. -Equivalent to os.stat(fd). -[clinic start generated code]*/ - -static PyObject * -os_fstat_impl(PyObject *module, int fd) -/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/ -{ - STRUCT_STAT st; - int res; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS - res = FSTAT(fd, &st); - Py_END_ALLOW_THREADS - } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (res != 0) { -#ifdef MS_WINDOWS - return PyErr_SetFromWindowsErr(0); -#else - return (!async_err) ? posix_error() : NULL; -#endif - } - - return _pystat_fromstructstat(module, &st); -} - - -/*[clinic input] -os.isatty -> bool - fd: int - / - -Return True if the fd is connected to a terminal. - -Return True if the file descriptor is an open file descriptor -connected to the slave end of a terminal. -[clinic start generated code]*/ - -static int -os_isatty_impl(PyObject *module, int fd) -/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/ -{ - int return_value; - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - return_value = isatty(fd); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - return return_value; -} - - -#ifdef HAVE_PIPE -/*[clinic input] -os.pipe - -Create a pipe. - -Returns a tuple of two file descriptors: - (read_fd, write_fd) -[clinic start generated code]*/ - -static PyObject * -os_pipe_impl(PyObject *module) -/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/ -{ - int fds[2]; -#ifdef MS_WINDOWS - HANDLE read, write; - SECURITY_ATTRIBUTES attr; - BOOL ok; -#else - int res; -#endif - -#ifdef MS_WINDOWS - attr.nLength = sizeof(attr); - attr.lpSecurityDescriptor = NULL; - attr.bInheritHandle = FALSE; - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - ok = CreatePipe(&read, &write, &attr, 0); - if (ok) { - fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY); - fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY); - if (fds[0] == -1 || fds[1] == -1) { - CloseHandle(read); - CloseHandle(write); - ok = 0; - } - } - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - - if (!ok) - return PyErr_SetFromWindowsErr(0); -#else - -#ifdef HAVE_PIPE2 - Py_BEGIN_ALLOW_THREADS - res = pipe2(fds, O_CLOEXEC); - Py_END_ALLOW_THREADS - - if (res != 0 && errno == ENOSYS) - { -#endif - Py_BEGIN_ALLOW_THREADS - res = pipe(fds); - Py_END_ALLOW_THREADS - - if (res == 0) { - if (_Py_set_inheritable(fds[0], 0, NULL) < 0) { - close(fds[0]); - close(fds[1]); - return NULL; - } - if (_Py_set_inheritable(fds[1], 0, NULL) < 0) { - close(fds[0]); - close(fds[1]); - return NULL; - } - } -#ifdef HAVE_PIPE2 - } -#endif - - if (res != 0) - return PyErr_SetFromErrno(PyExc_OSError); -#endif /* !MS_WINDOWS */ - return Py_BuildValue("(ii)", fds[0], fds[1]); -} -#endif /* HAVE_PIPE */ - - -#ifdef HAVE_PIPE2 -/*[clinic input] -os.pipe2 - - flags: int - / - -Create a pipe with flags set atomically. - -Returns a tuple of two file descriptors: - (read_fd, write_fd) - -flags can be constructed by ORing together one or more of these values: -O_NONBLOCK, O_CLOEXEC. -[clinic start generated code]*/ - -static PyObject * -os_pipe2_impl(PyObject *module, int flags) -/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/ -{ - int fds[2]; - int res; - - res = pipe2(fds, flags); - if (res != 0) - return posix_error(); - return Py_BuildValue("(ii)", fds[0], fds[1]); -} -#endif /* HAVE_PIPE2 */ - - -#ifdef HAVE_WRITEV -/*[clinic input] -os.writev -> Py_ssize_t - fd: int - buffers: object - / - -Iterate over buffers, and write the contents of each to a file descriptor. - -Returns the total number of bytes written. -buffers must be a sequence of bytes-like objects. -[clinic start generated code]*/ - -static Py_ssize_t -os_writev_impl(PyObject *module, int fd, PyObject *buffers) -/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/ -{ - Py_ssize_t cnt; - Py_ssize_t result; - int async_err = 0; - struct iovec *iov; - Py_buffer *buf; - - if (!PySequence_Check(buffers)) { - PyErr_SetString(PyExc_TypeError, - "writev() arg 2 must be a sequence"); - return -1; - } - cnt = PySequence_Size(buffers); - if (cnt < 0) - return -1; - - if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { - return -1; - } - - do { - Py_BEGIN_ALLOW_THREADS - result = writev(fd, iov, cnt); - Py_END_ALLOW_THREADS - } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - - iov_cleanup(iov, buf, cnt); - if (result < 0 && !async_err) - posix_error(); - - return result; -} -#endif /* HAVE_WRITEV */ - - -#ifdef HAVE_PWRITE -/*[clinic input] -os.pwrite -> Py_ssize_t - - fd: int - buffer: Py_buffer - offset: Py_off_t - / - -Write bytes to a file descriptor starting at a particular offset. - -Write buffer to fd, starting at offset bytes from the beginning of -the file. Returns the number of bytes writte. Does not change the -current file offset. -[clinic start generated code]*/ - -static Py_ssize_t -os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset) -/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/ -{ - Py_ssize_t size; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - - if (size < 0 && !async_err) - posix_error(); - return size; -} -#endif /* HAVE_PWRITE */ - -#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2) -/*[clinic input] -os.pwritev -> Py_ssize_t - - fd: int - buffers: object - offset: Py_off_t - flags: int = 0 - / - -Writes the contents of bytes-like objects to a file descriptor at a given offset. - -Combines the functionality of writev() and pwrite(). All buffers must be a sequence -of bytes-like objects. Buffers are processed in array order. Entire contents of first -buffer is written before proceeding to second, and so on. The operating system may -set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used. -This function writes the contents of each object to the file descriptor and returns -the total number of bytes written. - -The flags argument contains a bitwise OR of zero or more of the following flags: - -- RWF_DSYNC -- RWF_SYNC - -Using non-zero flags requires Linux 4.7 or newer. -[clinic start generated code]*/ - -static Py_ssize_t -os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, - int flags) -/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/ -{ - Py_ssize_t cnt; - Py_ssize_t result; - int async_err = 0; - struct iovec *iov; - Py_buffer *buf; - - if (!PySequence_Check(buffers)) { - PyErr_SetString(PyExc_TypeError, - "pwritev() arg 2 must be a sequence"); - return -1; - } - - cnt = PySequence_Size(buffers); - if (cnt < 0) { - return -1; - } - -#ifndef HAVE_PWRITEV2 - if(flags != 0) { - argument_unavailable_error("pwritev2", "flags"); - return -1; - } -#endif - - if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { - return -1; - } -#ifdef HAVE_PWRITEV2 - do { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - result = pwritev2(fd, iov, cnt, offset, flags); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#else - -#ifdef __APPLE__ -/* This entire function will be removed from the module dict when the API - * is not available. - */ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -#pragma clang diagnostic ignored "-Wunguarded-availability-new" -#endif - do { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH - result = pwritev(fd, iov, cnt, offset); - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - -#ifdef __APPLE__ -#pragma clang diagnostic pop -#endif - -#endif - - iov_cleanup(iov, buf, cnt); - if (result < 0) { - if (!async_err) { - posix_error(); - } - return -1; - } - - return result; -} -#endif /* HAVE_PWRITEV */ - -#ifdef HAVE_COPY_FILE_RANGE -/*[clinic input] - -os.copy_file_range - src: int - Source file descriptor. - dst: int - Destination file descriptor. - count: Py_ssize_t - Number of bytes to copy. - offset_src: object = None - Starting offset in src. - offset_dst: object = None - Starting offset in dst. - -Copy count bytes from one file descriptor to another. - -If offset_src is None, then src is read from the current position; -respectively for offset_dst. -[clinic start generated code]*/ - -static PyObject * -os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count, - PyObject *offset_src, PyObject *offset_dst) -/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/ -{ - off_t offset_src_val, offset_dst_val; - off_t *p_offset_src = NULL; - off_t *p_offset_dst = NULL; - Py_ssize_t ret; - int async_err = 0; - /* The flags argument is provided to allow - * for future extensions and currently must be to 0. */ - int flags = 0; - - - if (count < 0) { - PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed"); - return NULL; - } - - if (offset_src != Py_None) { - if (!Py_off_t_converter(offset_src, &offset_src_val)) { - return NULL; - } - p_offset_src = &offset_src_val; - } - - if (offset_dst != Py_None) { - if (!Py_off_t_converter(offset_dst, &offset_dst_val)) { - return NULL; - } - p_offset_dst = &offset_dst_val; - } - - do { - Py_BEGIN_ALLOW_THREADS - ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags); - Py_END_ALLOW_THREADS - } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - - if (ret < 0) { - return (!async_err) ? posix_error() : NULL; - } - - return PyLong_FromSsize_t(ret); -} -#endif /* HAVE_COPY_FILE_RANGE*/ - -#ifdef HAVE_MKFIFO -/*[clinic input] -os.mkfifo - - path: path_t - mode: int=0o666 - * - dir_fd: dir_fd(requires='mkfifoat')=None - -Create a "fifo" (a POSIX named pipe). - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. -[clinic start generated code]*/ - -static PyObject * -os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd) -/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/ -{ - int result; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_MKFIFOAT - if (dir_fd != DEFAULT_DIR_FD) - result = mkfifoat(dir_fd, path->narrow, mode); - else -#endif - result = mkfifo(path->narrow, mode); - Py_END_ALLOW_THREADS - } while (result != 0 && errno == EINTR && - !(async_err = PyErr_CheckSignals())); - if (result != 0) - return (!async_err) ? posix_error() : NULL; - - Py_RETURN_NONE; -} -#endif /* HAVE_MKFIFO */ - - -#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) -/*[clinic input] -os.mknod - - path: path_t - mode: int=0o600 - device: dev_t=0 - * - dir_fd: dir_fd(requires='mknodat')=None - -Create a node in the file system. - -Create a node in the file system (file, device special file or named pipe) -at path. mode specifies both the permissions to use and the -type of node to be created, being combined (bitwise OR) with one of -S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode, -device defines the newly created device special file (probably using -os.makedev()). Otherwise device is ignored. - -If dir_fd is not None, it should be a file descriptor open to a directory, - and path should be relative; path will then be relative to that directory. -dir_fd may not be implemented on your platform. - If it is unavailable, using it will raise a NotImplementedError. -[clinic start generated code]*/ - -static PyObject * -os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, - int dir_fd) -/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/ -{ - int result; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_MKNODAT - if (dir_fd != DEFAULT_DIR_FD) - result = mknodat(dir_fd, path->narrow, mode, device); - else -#endif - result = mknod(path->narrow, mode, device); - Py_END_ALLOW_THREADS - } while (result != 0 && errno == EINTR && - !(async_err = PyErr_CheckSignals())); - if (result != 0) - return (!async_err) ? posix_error() : NULL; - - Py_RETURN_NONE; -} -#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */ - - -#ifdef HAVE_DEVICE_MACROS -/*[clinic input] -os.major -> unsigned_int - - device: dev_t - / - -Extracts a device major number from a raw device number. -[clinic start generated code]*/ - -static unsigned int -os_major_impl(PyObject *module, dev_t device) -/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/ -{ - return major(device); -} - - -/*[clinic input] -os.minor -> unsigned_int - - device: dev_t - / - -Extracts a device minor number from a raw device number. -[clinic start generated code]*/ - -static unsigned int -os_minor_impl(PyObject *module, dev_t device) -/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/ -{ - return minor(device); -} - - -/*[clinic input] -os.makedev -> dev_t - - major: int - minor: int - / - -Composes a raw device number from the major and minor device numbers. -[clinic start generated code]*/ - -static dev_t -os_makedev_impl(PyObject *module, int major, int minor) -/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/ -{ - return makedev(major, minor); -} -#endif /* HAVE_DEVICE_MACROS */ - - -#if defined HAVE_FTRUNCATE || defined MS_WINDOWS -/*[clinic input] -os.ftruncate - - fd: int - length: Py_off_t - / - -Truncate a file, specified by file descriptor, to a specific length. -[clinic start generated code]*/ - -static PyObject * -os_ftruncate_impl(PyObject *module, int fd, Py_off_t length) -/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/ -{ - int result; - int async_err = 0; - - if (PySys_Audit("os.truncate", "in", fd, length) < 0) { - return NULL; - } - - do { - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef MS_WINDOWS - result = _chsize_s(fd, length); -#else - result = ftruncate(fd, length); -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - } while (result != 0 && errno == EINTR && - !(async_err = PyErr_CheckSignals())); - if (result != 0) - return (!async_err) ? posix_error() : NULL; - Py_RETURN_NONE; -} -#endif /* HAVE_FTRUNCATE || MS_WINDOWS */ - - -#if defined HAVE_TRUNCATE || defined MS_WINDOWS -/*[clinic input] -os.truncate - path: path_t(allow_fd='PATH_HAVE_FTRUNCATE') - length: Py_off_t - -Truncate a file, specified by path, to a specific length. - -On some platforms, path may also be specified as an open file descriptor. - If this functionality is unavailable, using it raises an exception. -[clinic start generated code]*/ - -static PyObject * -os_truncate_impl(PyObject *module, path_t *path, Py_off_t length) -/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/ -{ - int result; -#ifdef MS_WINDOWS - int fd; -#endif - - if (path->fd != -1) - return os_ftruncate_impl(module, path->fd, length); - - if (PySys_Audit("os.truncate", "On", path->object, length) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH -#ifdef MS_WINDOWS - fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT); - if (fd < 0) - result = -1; - else { - result = _chsize_s(fd, length); - close(fd); - if (result < 0) - errno = result; - } -#else - result = truncate(path->narrow, length); -#endif - _Py_END_SUPPRESS_IPH - Py_END_ALLOW_THREADS - if (result < 0) - return posix_path_error(path); - - Py_RETURN_NONE; -} -#endif /* HAVE_TRUNCATE || MS_WINDOWS */ - - -/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise() - and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is - defined, which is the case in Python on AIX. AIX bug report: - http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */ -#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__) -# define POSIX_FADVISE_AIX_BUG -#endif - - -#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) -/*[clinic input] -os.posix_fallocate - - fd: int - offset: Py_off_t - length: Py_off_t - / - -Ensure a file has allocated at least a particular number of bytes on disk. - -Ensure that the file specified by fd encompasses a range of bytes -starting at offset bytes from the beginning and continuing for length bytes. -[clinic start generated code]*/ - -static PyObject * -os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset, - Py_off_t length) -/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/ -{ - int result; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS - result = posix_fallocate(fd, offset, length); - Py_END_ALLOW_THREADS - } while (result == EINTR && !(async_err = PyErr_CheckSignals())); - - if (result == 0) - Py_RETURN_NONE; - - if (async_err) - return NULL; - - errno = result; - return posix_error(); -} -#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */ - - -#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) -/*[clinic input] -os.posix_fadvise - - fd: int - offset: Py_off_t - length: Py_off_t - advice: int - / - -Announce an intention to access data in a specific pattern. - -Announce an intention to access data in a specific pattern, thus allowing -the kernel to make optimizations. -The advice applies to the region of the file specified by fd starting at -offset and continuing for length bytes. -advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL, -POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or -POSIX_FADV_DONTNEED. -[clinic start generated code]*/ - -static PyObject * -os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, - Py_off_t length, int advice) -/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/ -{ - int result; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS - result = posix_fadvise(fd, offset, length, advice); - Py_END_ALLOW_THREADS - } while (result == EINTR && !(async_err = PyErr_CheckSignals())); - - if (result == 0) - Py_RETURN_NONE; - - if (async_err) - return NULL; - - errno = result; - return posix_error(); -} -#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */ - - -#ifdef MS_WINDOWS -static PyObject* -win32_putenv(PyObject *name, PyObject *value) -{ - /* Search from index 1 because on Windows starting '=' is allowed for - defining hidden environment variables. */ - if (PyUnicode_GET_LENGTH(name) == 0 || - PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1) - { - PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); - return NULL; - } - PyObject *unicode; - if (value != NULL) { - unicode = PyUnicode_FromFormat("%U=%U", name, value); - } - else { - unicode = PyUnicode_FromFormat("%U=", name); - } - if (unicode == NULL) { - return NULL; - } - - Py_ssize_t size; - /* PyUnicode_AsWideCharString() rejects embedded null characters */ - wchar_t *env = PyUnicode_AsWideCharString(unicode, &size); - Py_DECREF(unicode); - - if (env == NULL) { - return NULL; - } - if (size > _MAX_ENV) { - PyErr_Format(PyExc_ValueError, - "the environment variable is longer than %u characters", - _MAX_ENV); - PyMem_Free(env); - return NULL; - } - - /* _wputenv() and SetEnvironmentVariableW() update the environment in the - Process Environment Block (PEB). _wputenv() also updates CRT 'environ' - and '_wenviron' variables, whereas SetEnvironmentVariableW() does not. - - Prefer _wputenv() to be compatible with C libraries using CRT - variables and CRT functions using these variables (ex: getenv()). */ - int err = _wputenv(env); - PyMem_Free(env); - - if (err) { - posix_error(); - return NULL; - } - - Py_RETURN_NONE; -} -#endif - - -#ifdef MS_WINDOWS -/*[clinic input] -os.putenv - - name: unicode - value: unicode - / - -Change or add an environment variable. -[clinic start generated code]*/ - -static PyObject * -os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) -/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ -{ - if (PySys_Audit("os.putenv", "OO", name, value) < 0) { - return NULL; - } - return win32_putenv(name, value); -} -#else -/*[clinic input] -os.putenv - - name: FSConverter - value: FSConverter - / - -Change or add an environment variable. -[clinic start generated code]*/ - -static PyObject * -os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) -/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/ -{ - const char *name_string = PyBytes_AS_STRING(name); - const char *value_string = PyBytes_AS_STRING(value); - - if (strchr(name_string, '=') != NULL) { - PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); - return NULL; - } - - if (PySys_Audit("os.putenv", "OO", name, value) < 0) { - return NULL; - } - - if (setenv(name_string, value_string, 1)) { - return posix_error(); - } - Py_RETURN_NONE; -} -#endif /* !defined(MS_WINDOWS) */ - - -#ifdef MS_WINDOWS -/*[clinic input] -os.unsetenv - name: unicode - / - -Delete an environment variable. -[clinic start generated code]*/ - -static PyObject * -os_unsetenv_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/ -{ - if (PySys_Audit("os.unsetenv", "(O)", name) < 0) { - return NULL; - } - return win32_putenv(name, NULL); -} -#else -/*[clinic input] -os.unsetenv - name: FSConverter - / - -Delete an environment variable. -[clinic start generated code]*/ - -static PyObject * -os_unsetenv_impl(PyObject *module, PyObject *name) -/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/ -{ - if (PySys_Audit("os.unsetenv", "(O)", name) < 0) { - return NULL; - } -#ifdef HAVE_BROKEN_UNSETENV - unsetenv(PyBytes_AS_STRING(name)); -#else - int err = unsetenv(PyBytes_AS_STRING(name)); - if (err) { - return posix_error(); - } -#endif - - Py_RETURN_NONE; -} -#endif /* !MS_WINDOWS */ - - -/*[clinic input] -os.strerror - - code: int - / - -Translate an error code to a message string. -[clinic start generated code]*/ - -static PyObject * -os_strerror_impl(PyObject *module, int code) -/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/ -{ - char *message = strerror(code); - if (message == NULL) { - PyErr_SetString(PyExc_ValueError, - "strerror() argument out of range"); - return NULL; - } - return PyUnicode_DecodeLocale(message, "surrogateescape"); -} - - -#ifdef HAVE_SYS_WAIT_H -#ifdef WCOREDUMP -/*[clinic input] -os.WCOREDUMP -> bool - - status: int - / - -Return True if the process returning status was dumped to a core file. -[clinic start generated code]*/ - -static int -os_WCOREDUMP_impl(PyObject *module, int status) -/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/ -{ - WAIT_TYPE wait_status; - WAIT_STATUS_INT(wait_status) = status; - return WCOREDUMP(wait_status); -} -#endif /* WCOREDUMP */ - - -#ifdef WIFCONTINUED -/*[clinic input] -os.WIFCONTINUED -> bool - - status: int - -Return True if a particular process was continued from a job control stop. - -Return True if the process returning status was continued from a -job control stop. -[clinic start generated code]*/ - -static int -os_WIFCONTINUED_impl(PyObject *module, int status) -/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/ -{ - WAIT_TYPE wait_status; - WAIT_STATUS_INT(wait_status) = status; - return WIFCONTINUED(wait_status); -} -#endif /* WIFCONTINUED */ - - -#ifdef WIFSTOPPED -/*[clinic input] -os.WIFSTOPPED -> bool - - status: int - -Return True if the process returning status was stopped. -[clinic start generated code]*/ - -static int -os_WIFSTOPPED_impl(PyObject *module, int status) -/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/ -{ - WAIT_TYPE wait_status; - WAIT_STATUS_INT(wait_status) = status; - return WIFSTOPPED(wait_status); -} -#endif /* WIFSTOPPED */ - - -#ifdef WIFSIGNALED -/*[clinic input] -os.WIFSIGNALED -> bool - - status: int - -Return True if the process returning status was terminated by a signal. -[clinic start generated code]*/ - -static int -os_WIFSIGNALED_impl(PyObject *module, int status) -/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/ -{ - WAIT_TYPE wait_status; - WAIT_STATUS_INT(wait_status) = status; - return WIFSIGNALED(wait_status); -} -#endif /* WIFSIGNALED */ - - -#ifdef WIFEXITED -/*[clinic input] -os.WIFEXITED -> bool - - status: int - -Return True if the process returning status exited via the exit() system call. -[clinic start generated code]*/ - -static int -os_WIFEXITED_impl(PyObject *module, int status) -/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/ -{ - WAIT_TYPE wait_status; - WAIT_STATUS_INT(wait_status) = status; - return WIFEXITED(wait_status); -} -#endif /* WIFEXITED */ - - -#ifdef WEXITSTATUS -/*[clinic input] -os.WEXITSTATUS -> int - - status: int - -Return the process return code from status. -[clinic start generated code]*/ - -static int -os_WEXITSTATUS_impl(PyObject *module, int status) -/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/ -{ - WAIT_TYPE wait_status; - WAIT_STATUS_INT(wait_status) = status; - return WEXITSTATUS(wait_status); -} -#endif /* WEXITSTATUS */ - - -#ifdef WTERMSIG -/*[clinic input] -os.WTERMSIG -> int - - status: int - -Return the signal that terminated the process that provided the status value. -[clinic start generated code]*/ - -static int -os_WTERMSIG_impl(PyObject *module, int status) -/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/ -{ - WAIT_TYPE wait_status; - WAIT_STATUS_INT(wait_status) = status; - return WTERMSIG(wait_status); -} -#endif /* WTERMSIG */ - - -#ifdef WSTOPSIG -/*[clinic input] -os.WSTOPSIG -> int - - status: int - -Return the signal that stopped the process that provided the status value. -[clinic start generated code]*/ - -static int -os_WSTOPSIG_impl(PyObject *module, int status) -/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/ -{ - WAIT_TYPE wait_status; - WAIT_STATUS_INT(wait_status) = status; - return WSTOPSIG(wait_status); -} -#endif /* WSTOPSIG */ -#endif /* HAVE_SYS_WAIT_H */ - - -#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) -#ifdef _SCO_DS -/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the - needed definitions in sys/statvfs.h */ -#define _SVID3 -#endif -#include - -static PyObject* -_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) { - PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType; - PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType); - if (v == NULL) - return NULL; - -#if !defined(HAVE_LARGEFILE_SUPPORT) - PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); - PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); - PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks)); - PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree)); - PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); - PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); - PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); - PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); - PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); - PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); -#else - PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); - PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); - PyStructSequence_SET_ITEM(v, 2, - PyLong_FromLongLong((long long) st.f_blocks)); - PyStructSequence_SET_ITEM(v, 3, - PyLong_FromLongLong((long long) st.f_bfree)); - PyStructSequence_SET_ITEM(v, 4, - PyLong_FromLongLong((long long) st.f_bavail)); - PyStructSequence_SET_ITEM(v, 5, - PyLong_FromLongLong((long long) st.f_files)); - PyStructSequence_SET_ITEM(v, 6, - PyLong_FromLongLong((long long) st.f_ffree)); - PyStructSequence_SET_ITEM(v, 7, - PyLong_FromLongLong((long long) st.f_favail)); - PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); - PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); -#endif -/* The _ALL_SOURCE feature test macro defines f_fsid as a structure - * (issue #32390). */ -#if defined(_AIX) && defined(_ALL_SOURCE) - PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0])); -#else - PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid)); -#endif - if (PyErr_Occurred()) { - Py_DECREF(v); - return NULL; - } - - return v; -} - - -/*[clinic input] -os.fstatvfs - fd: int - / - -Perform an fstatvfs system call on the given fd. - -Equivalent to statvfs(fd). -[clinic start generated code]*/ - -static PyObject * -os_fstatvfs_impl(PyObject *module, int fd) -/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/ -{ - int result; - int async_err = 0; - struct statvfs st; - - do { - Py_BEGIN_ALLOW_THREADS - result = fstatvfs(fd, &st); - Py_END_ALLOW_THREADS - } while (result != 0 && errno == EINTR && - !(async_err = PyErr_CheckSignals())); - if (result != 0) - return (!async_err) ? posix_error() : NULL; - - return _pystatvfs_fromstructstatvfs(module, st); -} -#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */ - - -#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) -#include -/*[clinic input] -os.statvfs - - path: path_t(allow_fd='PATH_HAVE_FSTATVFS') - -Perform a statvfs system call on the given path. - -path may always be specified as a string. -On some platforms, path may also be specified as an open file descriptor. - If this functionality is unavailable, using it raises an exception. -[clinic start generated code]*/ - -static PyObject * -os_statvfs_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/ -{ - int result; - struct statvfs st; - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FSTATVFS - if (path->fd != -1) { - result = fstatvfs(path->fd, &st); - } - else -#endif - result = statvfs(path->narrow, &st); - Py_END_ALLOW_THREADS - - if (result) { - return path_error(path); - } - - return _pystatvfs_fromstructstatvfs(module, st); -} -#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */ - - -#ifdef MS_WINDOWS -/*[clinic input] -os._getdiskusage - - path: path_t - -Return disk usage statistics about the given path as a (total, free) tuple. -[clinic start generated code]*/ - -static PyObject * -os__getdiskusage_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/ -{ - BOOL retval; - ULARGE_INTEGER _, total, free; - DWORD err = 0; - - Py_BEGIN_ALLOW_THREADS - retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free); - Py_END_ALLOW_THREADS - if (retval == 0) { - if (GetLastError() == ERROR_DIRECTORY) { - wchar_t *dir_path = NULL; - - dir_path = PyMem_New(wchar_t, path->length + 1); - if (dir_path == NULL) { - return PyErr_NoMemory(); - } - - wcscpy_s(dir_path, path->length + 1, path->wide); - - if (_dirnameW(dir_path) != -1) { - Py_BEGIN_ALLOW_THREADS - retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free); - Py_END_ALLOW_THREADS - } - /* Record the last error in case it's modified by PyMem_Free. */ - err = GetLastError(); - PyMem_Free(dir_path); - if (retval) { - goto success; - } - } - return PyErr_SetFromWindowsErr(err); - } - -success: - return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart); -} -#endif /* MS_WINDOWS */ - - -/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). - * It maps strings representing configuration variable names to - * integer values, allowing those functions to be called with the - * magic names instead of polluting the module's namespace with tons of - * rarely-used constants. There are three separate tables that use - * these definitions. - * - * This code is always included, even if none of the interfaces that - * need it are included. The #if hackery needed to avoid it would be - * sufficiently pervasive that it's not worth the loss of readability. - */ -struct constdef { - const char *name; - int value; -}; - -static int -conv_confname(PyObject *arg, int *valuep, struct constdef *table, - size_t tablesize) -{ - if (PyLong_Check(arg)) { - int value = _PyLong_AsInt(arg); - if (value == -1 && PyErr_Occurred()) - return 0; - *valuep = value; - return 1; - } - else { - /* look up the value in the table using a binary search */ - size_t lo = 0; - size_t mid; - size_t hi = tablesize; - int cmp; - const char *confname; - if (!PyUnicode_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "configuration names must be strings or integers"); - return 0; - } - confname = PyUnicode_AsUTF8(arg); - if (confname == NULL) - return 0; - while (lo < hi) { - mid = (lo + hi) / 2; - cmp = strcmp(confname, table[mid].name); - if (cmp < 0) - hi = mid; - else if (cmp > 0) - lo = mid + 1; - else { - *valuep = table[mid].value; - return 1; - } - } - PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); - return 0; - } -} - - -#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) -static struct constdef posix_constants_pathconf[] = { -#ifdef _PC_ABI_AIO_XFER_MAX - {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, -#endif -#ifdef _PC_ABI_ASYNC_IO - {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, -#endif -#ifdef _PC_ASYNC_IO - {"PC_ASYNC_IO", _PC_ASYNC_IO}, -#endif -#ifdef _PC_CHOWN_RESTRICTED - {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, -#endif -#ifdef _PC_FILESIZEBITS - {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, -#endif -#ifdef _PC_LAST - {"PC_LAST", _PC_LAST}, -#endif -#ifdef _PC_LINK_MAX - {"PC_LINK_MAX", _PC_LINK_MAX}, -#endif -#ifdef _PC_MAX_CANON - {"PC_MAX_CANON", _PC_MAX_CANON}, -#endif -#ifdef _PC_MAX_INPUT - {"PC_MAX_INPUT", _PC_MAX_INPUT}, -#endif -#ifdef _PC_NAME_MAX - {"PC_NAME_MAX", _PC_NAME_MAX}, -#endif -#ifdef _PC_NO_TRUNC - {"PC_NO_TRUNC", _PC_NO_TRUNC}, -#endif -#ifdef _PC_PATH_MAX - {"PC_PATH_MAX", _PC_PATH_MAX}, -#endif -#ifdef _PC_PIPE_BUF - {"PC_PIPE_BUF", _PC_PIPE_BUF}, -#endif -#ifdef _PC_PRIO_IO - {"PC_PRIO_IO", _PC_PRIO_IO}, -#endif -#ifdef _PC_SOCK_MAXBUF - {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, -#endif -#ifdef _PC_SYNC_IO - {"PC_SYNC_IO", _PC_SYNC_IO}, -#endif -#ifdef _PC_VDISABLE - {"PC_VDISABLE", _PC_VDISABLE}, -#endif -#ifdef _PC_ACL_ENABLED - {"PC_ACL_ENABLED", _PC_ACL_ENABLED}, -#endif -#ifdef _PC_MIN_HOLE_SIZE - {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE}, -#endif -#ifdef _PC_ALLOC_SIZE_MIN - {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN}, -#endif -#ifdef _PC_REC_INCR_XFER_SIZE - {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE}, -#endif -#ifdef _PC_REC_MAX_XFER_SIZE - {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE}, -#endif -#ifdef _PC_REC_MIN_XFER_SIZE - {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE}, -#endif -#ifdef _PC_REC_XFER_ALIGN - {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN}, -#endif -#ifdef _PC_SYMLINK_MAX - {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX}, -#endif -#ifdef _PC_XATTR_ENABLED - {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED}, -#endif -#ifdef _PC_XATTR_EXISTS - {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS}, -#endif -#ifdef _PC_TIMESTAMP_RESOLUTION - {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION}, -#endif -}; - -static int -conv_path_confname(PyObject *arg, int *valuep) -{ - return conv_confname(arg, valuep, posix_constants_pathconf, - sizeof(posix_constants_pathconf) - / sizeof(struct constdef)); -} -#endif - - -#ifdef HAVE_FPATHCONF -/*[clinic input] -os.fpathconf -> long - - fd: int - name: path_confname - / - -Return the configuration limit name for the file descriptor fd. - -If there is no limit, return -1. -[clinic start generated code]*/ - -static long -os_fpathconf_impl(PyObject *module, int fd, int name) -/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/ -{ - long limit; - - errno = 0; - limit = fpathconf(fd, name); - if (limit == -1 && errno != 0) - posix_error(); - - return limit; -} -#endif /* HAVE_FPATHCONF */ - - -#ifdef HAVE_PATHCONF -/*[clinic input] -os.pathconf -> long - path: path_t(allow_fd='PATH_HAVE_FPATHCONF') - name: path_confname - -Return the configuration limit name for the file or directory path. - -If there is no limit, return -1. -On some platforms, path may also be specified as an open file descriptor. - If this functionality is unavailable, using it raises an exception. -[clinic start generated code]*/ - -static long -os_pathconf_impl(PyObject *module, path_t *path, int name) -/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/ -{ - long limit; - - errno = 0; -#ifdef HAVE_FPATHCONF - if (path->fd != -1) - limit = fpathconf(path->fd, name); - else -#endif - limit = pathconf(path->narrow, name); - if (limit == -1 && errno != 0) { - if (errno == EINVAL) - /* could be a path or name problem */ - posix_error(); - else - path_error(path); - } - - return limit; -} -#endif /* HAVE_PATHCONF */ - -#ifdef HAVE_CONFSTR -static struct constdef posix_constants_confstr[] = { -#ifdef _CS_ARCHITECTURE - {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, -#endif -#ifdef _CS_GNU_LIBC_VERSION - {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION}, -#endif -#ifdef _CS_GNU_LIBPTHREAD_VERSION - {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION}, -#endif -#ifdef _CS_HOSTNAME - {"CS_HOSTNAME", _CS_HOSTNAME}, -#endif -#ifdef _CS_HW_PROVIDER - {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, -#endif -#ifdef _CS_HW_SERIAL - {"CS_HW_SERIAL", _CS_HW_SERIAL}, -#endif -#ifdef _CS_INITTAB_NAME - {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, -#endif -#ifdef _CS_LFS64_CFLAGS - {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, -#endif -#ifdef _CS_LFS64_LDFLAGS - {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, -#endif -#ifdef _CS_LFS64_LIBS - {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, -#endif -#ifdef _CS_LFS64_LINTFLAGS - {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, -#endif -#ifdef _CS_LFS_CFLAGS - {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, -#endif -#ifdef _CS_LFS_LDFLAGS - {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, -#endif -#ifdef _CS_LFS_LIBS - {"CS_LFS_LIBS", _CS_LFS_LIBS}, -#endif -#ifdef _CS_LFS_LINTFLAGS - {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, -#endif -#ifdef _CS_MACHINE - {"CS_MACHINE", _CS_MACHINE}, -#endif -#ifdef _CS_PATH - {"CS_PATH", _CS_PATH}, -#endif -#ifdef _CS_RELEASE - {"CS_RELEASE", _CS_RELEASE}, -#endif -#ifdef _CS_SRPC_DOMAIN - {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, -#endif -#ifdef _CS_SYSNAME - {"CS_SYSNAME", _CS_SYSNAME}, -#endif -#ifdef _CS_VERSION - {"CS_VERSION", _CS_VERSION}, -#endif -#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS - {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS - {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFF32_LIBS - {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, -#endif -#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS - {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS - {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS - {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS - {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, -#endif -#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS - {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, -#endif -#ifdef _CS_XBS5_LP64_OFF64_CFLAGS - {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, -#endif -#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS - {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, -#endif -#ifdef _CS_XBS5_LP64_OFF64_LIBS - {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, -#endif -#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS - {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, -#endif -#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS - {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, -#endif -#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS - {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, -#endif -#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS - {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, -#endif -#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS - {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, -#endif -#ifdef _MIPS_CS_AVAIL_PROCESSORS - {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, -#endif -#ifdef _MIPS_CS_BASE - {"MIPS_CS_BASE", _MIPS_CS_BASE}, -#endif -#ifdef _MIPS_CS_HOSTID - {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, -#endif -#ifdef _MIPS_CS_HW_NAME - {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, -#endif -#ifdef _MIPS_CS_NUM_PROCESSORS - {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, -#endif -#ifdef _MIPS_CS_OSREL_MAJ - {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, -#endif -#ifdef _MIPS_CS_OSREL_MIN - {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, -#endif -#ifdef _MIPS_CS_OSREL_PATCH - {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, -#endif -#ifdef _MIPS_CS_OS_NAME - {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, -#endif -#ifdef _MIPS_CS_OS_PROVIDER - {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, -#endif -#ifdef _MIPS_CS_PROCESSORS - {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, -#endif -#ifdef _MIPS_CS_SERIAL - {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, -#endif -#ifdef _MIPS_CS_VENDOR - {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, -#endif -}; - -static int -conv_confstr_confname(PyObject *arg, int *valuep) -{ - return conv_confname(arg, valuep, posix_constants_confstr, - sizeof(posix_constants_confstr) - / sizeof(struct constdef)); -} - - -/*[clinic input] -os.confstr - - name: confstr_confname - / - -Return a string-valued system configuration variable. -[clinic start generated code]*/ - -static PyObject * -os_confstr_impl(PyObject *module, int name) -/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/ -{ - PyObject *result = NULL; - char buffer[255]; - size_t len; - - errno = 0; - len = confstr(name, buffer, sizeof(buffer)); - if (len == 0) { - if (errno) { - posix_error(); - return NULL; - } - else { - Py_RETURN_NONE; - } - } - - if (len >= sizeof(buffer)) { - size_t len2; - char *buf = PyMem_Malloc(len); - if (buf == NULL) - return PyErr_NoMemory(); - len2 = confstr(name, buf, len); - assert(len == len2); - result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1); - PyMem_Free(buf); - } - else - result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); - return result; -} -#endif /* HAVE_CONFSTR */ - - -#ifdef HAVE_SYSCONF -static struct constdef posix_constants_sysconf[] = { -#ifdef _SC_2_CHAR_TERM - {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, -#endif -#ifdef _SC_2_C_BIND - {"SC_2_C_BIND", _SC_2_C_BIND}, -#endif -#ifdef _SC_2_C_DEV - {"SC_2_C_DEV", _SC_2_C_DEV}, -#endif -#ifdef _SC_2_C_VERSION - {"SC_2_C_VERSION", _SC_2_C_VERSION}, -#endif -#ifdef _SC_2_FORT_DEV - {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, -#endif -#ifdef _SC_2_FORT_RUN - {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, -#endif -#ifdef _SC_2_LOCALEDEF - {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, -#endif -#ifdef _SC_2_SW_DEV - {"SC_2_SW_DEV", _SC_2_SW_DEV}, -#endif -#ifdef _SC_2_UPE - {"SC_2_UPE", _SC_2_UPE}, -#endif -#ifdef _SC_2_VERSION - {"SC_2_VERSION", _SC_2_VERSION}, -#endif -#ifdef _SC_ABI_ASYNCHRONOUS_IO - {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, -#endif -#ifdef _SC_ACL - {"SC_ACL", _SC_ACL}, -#endif -#ifdef _SC_AIO_LISTIO_MAX - {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, -#endif -#ifdef _SC_AIO_MAX - {"SC_AIO_MAX", _SC_AIO_MAX}, -#endif -#ifdef _SC_AIO_PRIO_DELTA_MAX - {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, -#endif -#ifdef _SC_ARG_MAX - {"SC_ARG_MAX", _SC_ARG_MAX}, -#endif -#ifdef _SC_ASYNCHRONOUS_IO - {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, -#endif -#ifdef _SC_ATEXIT_MAX - {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, -#endif -#ifdef _SC_AUDIT - {"SC_AUDIT", _SC_AUDIT}, -#endif -#ifdef _SC_AVPHYS_PAGES - {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, -#endif -#ifdef _SC_BC_BASE_MAX - {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, -#endif -#ifdef _SC_BC_DIM_MAX - {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, -#endif -#ifdef _SC_BC_SCALE_MAX - {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, -#endif -#ifdef _SC_BC_STRING_MAX - {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, -#endif -#ifdef _SC_CAP - {"SC_CAP", _SC_CAP}, -#endif -#ifdef _SC_CHARCLASS_NAME_MAX - {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, -#endif -#ifdef _SC_CHAR_BIT - {"SC_CHAR_BIT", _SC_CHAR_BIT}, -#endif -#ifdef _SC_CHAR_MAX - {"SC_CHAR_MAX", _SC_CHAR_MAX}, -#endif -#ifdef _SC_CHAR_MIN - {"SC_CHAR_MIN", _SC_CHAR_MIN}, -#endif -#ifdef _SC_CHILD_MAX - {"SC_CHILD_MAX", _SC_CHILD_MAX}, -#endif -#ifdef _SC_CLK_TCK - {"SC_CLK_TCK", _SC_CLK_TCK}, -#endif -#ifdef _SC_COHER_BLKSZ - {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, -#endif -#ifdef _SC_COLL_WEIGHTS_MAX - {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, -#endif -#ifdef _SC_DCACHE_ASSOC - {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, -#endif -#ifdef _SC_DCACHE_BLKSZ - {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, -#endif -#ifdef _SC_DCACHE_LINESZ - {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, -#endif -#ifdef _SC_DCACHE_SZ - {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, -#endif -#ifdef _SC_DCACHE_TBLKSZ - {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, -#endif -#ifdef _SC_DELAYTIMER_MAX - {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, -#endif -#ifdef _SC_EQUIV_CLASS_MAX - {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, -#endif -#ifdef _SC_EXPR_NEST_MAX - {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, -#endif -#ifdef _SC_FSYNC - {"SC_FSYNC", _SC_FSYNC}, -#endif -#ifdef _SC_GETGR_R_SIZE_MAX - {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, -#endif -#ifdef _SC_GETPW_R_SIZE_MAX - {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, -#endif -#ifdef _SC_ICACHE_ASSOC - {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, -#endif -#ifdef _SC_ICACHE_BLKSZ - {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, -#endif -#ifdef _SC_ICACHE_LINESZ - {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, -#endif -#ifdef _SC_ICACHE_SZ - {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, -#endif -#ifdef _SC_INF - {"SC_INF", _SC_INF}, -#endif -#ifdef _SC_INT_MAX - {"SC_INT_MAX", _SC_INT_MAX}, -#endif -#ifdef _SC_INT_MIN - {"SC_INT_MIN", _SC_INT_MIN}, -#endif -#ifdef _SC_IOV_MAX - {"SC_IOV_MAX", _SC_IOV_MAX}, -#endif -#ifdef _SC_IP_SECOPTS - {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, -#endif -#ifdef _SC_JOB_CONTROL - {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, -#endif -#ifdef _SC_KERN_POINTERS - {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, -#endif -#ifdef _SC_KERN_SIM - {"SC_KERN_SIM", _SC_KERN_SIM}, -#endif -#ifdef _SC_LINE_MAX - {"SC_LINE_MAX", _SC_LINE_MAX}, -#endif -#ifdef _SC_LOGIN_NAME_MAX - {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, -#endif -#ifdef _SC_LOGNAME_MAX - {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, -#endif -#ifdef _SC_LONG_BIT - {"SC_LONG_BIT", _SC_LONG_BIT}, -#endif -#ifdef _SC_MAC - {"SC_MAC", _SC_MAC}, -#endif -#ifdef _SC_MAPPED_FILES - {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, -#endif -#ifdef _SC_MAXPID - {"SC_MAXPID", _SC_MAXPID}, -#endif -#ifdef _SC_MB_LEN_MAX - {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, -#endif -#ifdef _SC_MEMLOCK - {"SC_MEMLOCK", _SC_MEMLOCK}, -#endif -#ifdef _SC_MEMLOCK_RANGE - {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, -#endif -#ifdef _SC_MEMORY_PROTECTION - {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, -#endif -#ifdef _SC_MESSAGE_PASSING - {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, -#endif -#ifdef _SC_MMAP_FIXED_ALIGNMENT - {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, -#endif -#ifdef _SC_MQ_OPEN_MAX - {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, -#endif -#ifdef _SC_MQ_PRIO_MAX - {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, -#endif -#ifdef _SC_NACLS_MAX - {"SC_NACLS_MAX", _SC_NACLS_MAX}, -#endif -#ifdef _SC_NGROUPS_MAX - {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, -#endif -#ifdef _SC_NL_ARGMAX - {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, -#endif -#ifdef _SC_NL_LANGMAX - {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, -#endif -#ifdef _SC_NL_MSGMAX - {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, -#endif -#ifdef _SC_NL_NMAX - {"SC_NL_NMAX", _SC_NL_NMAX}, -#endif -#ifdef _SC_NL_SETMAX - {"SC_NL_SETMAX", _SC_NL_SETMAX}, -#endif -#ifdef _SC_NL_TEXTMAX - {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, -#endif -#ifdef _SC_NPROCESSORS_CONF - {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, -#endif -#ifdef _SC_NPROCESSORS_ONLN - {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, -#endif -#ifdef _SC_NPROC_CONF - {"SC_NPROC_CONF", _SC_NPROC_CONF}, -#endif -#ifdef _SC_NPROC_ONLN - {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, -#endif -#ifdef _SC_NZERO - {"SC_NZERO", _SC_NZERO}, -#endif -#ifdef _SC_OPEN_MAX - {"SC_OPEN_MAX", _SC_OPEN_MAX}, -#endif -#ifdef _SC_PAGESIZE - {"SC_PAGESIZE", _SC_PAGESIZE}, -#endif -#ifdef _SC_PAGE_SIZE - {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, -#endif -#ifdef _SC_AIX_REALMEM - {"SC_AIX_REALMEM", _SC_AIX_REALMEM}, -#endif -#ifdef _SC_PASS_MAX - {"SC_PASS_MAX", _SC_PASS_MAX}, -#endif -#ifdef _SC_PHYS_PAGES - {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, -#endif -#ifdef _SC_PII - {"SC_PII", _SC_PII}, -#endif -#ifdef _SC_PII_INTERNET - {"SC_PII_INTERNET", _SC_PII_INTERNET}, -#endif -#ifdef _SC_PII_INTERNET_DGRAM - {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, -#endif -#ifdef _SC_PII_INTERNET_STREAM - {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, -#endif -#ifdef _SC_PII_OSI - {"SC_PII_OSI", _SC_PII_OSI}, -#endif -#ifdef _SC_PII_OSI_CLTS - {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, -#endif -#ifdef _SC_PII_OSI_COTS - {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, -#endif -#ifdef _SC_PII_OSI_M - {"SC_PII_OSI_M", _SC_PII_OSI_M}, -#endif -#ifdef _SC_PII_SOCKET - {"SC_PII_SOCKET", _SC_PII_SOCKET}, -#endif -#ifdef _SC_PII_XTI - {"SC_PII_XTI", _SC_PII_XTI}, -#endif -#ifdef _SC_POLL - {"SC_POLL", _SC_POLL}, -#endif -#ifdef _SC_PRIORITIZED_IO - {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, -#endif -#ifdef _SC_PRIORITY_SCHEDULING - {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, -#endif -#ifdef _SC_REALTIME_SIGNALS - {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, -#endif -#ifdef _SC_RE_DUP_MAX - {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, -#endif -#ifdef _SC_RTSIG_MAX - {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, -#endif -#ifdef _SC_SAVED_IDS - {"SC_SAVED_IDS", _SC_SAVED_IDS}, -#endif -#ifdef _SC_SCHAR_MAX - {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, -#endif -#ifdef _SC_SCHAR_MIN - {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, -#endif -#ifdef _SC_SELECT - {"SC_SELECT", _SC_SELECT}, -#endif -#ifdef _SC_SEMAPHORES - {"SC_SEMAPHORES", _SC_SEMAPHORES}, -#endif -#ifdef _SC_SEM_NSEMS_MAX - {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, -#endif -#ifdef _SC_SEM_VALUE_MAX - {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, -#endif -#ifdef _SC_SHARED_MEMORY_OBJECTS - {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, -#endif -#ifdef _SC_SHRT_MAX - {"SC_SHRT_MAX", _SC_SHRT_MAX}, -#endif -#ifdef _SC_SHRT_MIN - {"SC_SHRT_MIN", _SC_SHRT_MIN}, -#endif -#ifdef _SC_SIGQUEUE_MAX - {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, -#endif -#ifdef _SC_SIGRT_MAX - {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, -#endif -#ifdef _SC_SIGRT_MIN - {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, -#endif -#ifdef _SC_SOFTPOWER - {"SC_SOFTPOWER", _SC_SOFTPOWER}, -#endif -#ifdef _SC_SPLIT_CACHE - {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, -#endif -#ifdef _SC_SSIZE_MAX - {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, -#endif -#ifdef _SC_STACK_PROT - {"SC_STACK_PROT", _SC_STACK_PROT}, -#endif -#ifdef _SC_STREAM_MAX - {"SC_STREAM_MAX", _SC_STREAM_MAX}, -#endif -#ifdef _SC_SYNCHRONIZED_IO - {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, -#endif -#ifdef _SC_THREADS - {"SC_THREADS", _SC_THREADS}, -#endif -#ifdef _SC_THREAD_ATTR_STACKADDR - {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, -#endif -#ifdef _SC_THREAD_ATTR_STACKSIZE - {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, -#endif -#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS - {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, -#endif -#ifdef _SC_THREAD_KEYS_MAX - {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, -#endif -#ifdef _SC_THREAD_PRIORITY_SCHEDULING - {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, -#endif -#ifdef _SC_THREAD_PRIO_INHERIT - {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, -#endif -#ifdef _SC_THREAD_PRIO_PROTECT - {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, -#endif -#ifdef _SC_THREAD_PROCESS_SHARED - {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, -#endif -#ifdef _SC_THREAD_SAFE_FUNCTIONS - {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, -#endif -#ifdef _SC_THREAD_STACK_MIN - {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, -#endif -#ifdef _SC_THREAD_THREADS_MAX - {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, -#endif -#ifdef _SC_TIMERS - {"SC_TIMERS", _SC_TIMERS}, -#endif -#ifdef _SC_TIMER_MAX - {"SC_TIMER_MAX", _SC_TIMER_MAX}, -#endif -#ifdef _SC_TTY_NAME_MAX - {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, -#endif -#ifdef _SC_TZNAME_MAX - {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, -#endif -#ifdef _SC_T_IOV_MAX - {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, -#endif -#ifdef _SC_UCHAR_MAX - {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, -#endif -#ifdef _SC_UINT_MAX - {"SC_UINT_MAX", _SC_UINT_MAX}, -#endif -#ifdef _SC_UIO_MAXIOV - {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, -#endif -#ifdef _SC_ULONG_MAX - {"SC_ULONG_MAX", _SC_ULONG_MAX}, -#endif -#ifdef _SC_USHRT_MAX - {"SC_USHRT_MAX", _SC_USHRT_MAX}, -#endif -#ifdef _SC_VERSION - {"SC_VERSION", _SC_VERSION}, -#endif -#ifdef _SC_WORD_BIT - {"SC_WORD_BIT", _SC_WORD_BIT}, -#endif -#ifdef _SC_XBS5_ILP32_OFF32 - {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, -#endif -#ifdef _SC_XBS5_ILP32_OFFBIG - {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, -#endif -#ifdef _SC_XBS5_LP64_OFF64 - {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, -#endif -#ifdef _SC_XBS5_LPBIG_OFFBIG - {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, -#endif -#ifdef _SC_XOPEN_CRYPT - {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, -#endif -#ifdef _SC_XOPEN_ENH_I18N - {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, -#endif -#ifdef _SC_XOPEN_LEGACY - {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, -#endif -#ifdef _SC_XOPEN_REALTIME - {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, -#endif -#ifdef _SC_XOPEN_REALTIME_THREADS - {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, -#endif -#ifdef _SC_XOPEN_SHM - {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, -#endif -#ifdef _SC_XOPEN_UNIX - {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, -#endif -#ifdef _SC_XOPEN_VERSION - {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, -#endif -#ifdef _SC_XOPEN_XCU_VERSION - {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, -#endif -#ifdef _SC_XOPEN_XPG2 - {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, -#endif -#ifdef _SC_XOPEN_XPG3 - {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, -#endif -#ifdef _SC_XOPEN_XPG4 - {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, -#endif -}; - -static int -conv_sysconf_confname(PyObject *arg, int *valuep) -{ - return conv_confname(arg, valuep, posix_constants_sysconf, - sizeof(posix_constants_sysconf) - / sizeof(struct constdef)); -} - - -/*[clinic input] -os.sysconf -> long - name: sysconf_confname - / - -Return an integer-valued system configuration variable. -[clinic start generated code]*/ - -static long -os_sysconf_impl(PyObject *module, int name) -/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/ -{ - long value; - - errno = 0; - value = sysconf(name); - if (value == -1 && errno != 0) - posix_error(); - return value; -} -#endif /* HAVE_SYSCONF */ - - -/* This code is used to ensure that the tables of configuration value names - * are in sorted order as required by conv_confname(), and also to build - * the exported dictionaries that are used to publish information about the - * names available on the host platform. - * - * Sorting the table at runtime ensures that the table is properly ordered - * when used, even for platforms we're not able to test on. It also makes - * it easier to add additional entries to the tables. - */ - -static int -cmp_constdefs(const void *v1, const void *v2) -{ - const struct constdef *c1 = - (const struct constdef *) v1; - const struct constdef *c2 = - (const struct constdef *) v2; + /* Restore last error */ + SetLastError(error); + } + } - return strcmp(c1->name, c2->name); -} + return retval; +} + +static int +win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) +{ + /* Protocol violation: we explicitly clear errno, instead of + setting it to a POSIX error. Callers should use GetLastError. */ + int code = win32_xstat_impl(path, result, traverse); + errno = 0; + return code; +} +/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w + + In Posix, stat automatically traverses symlinks and returns the stat + structure for the target. In Windows, the equivalent GetFileAttributes by + default does not traverse symlinks and instead returns attributes for + the symlink. + + Instead, we will open the file (which *does* traverse symlinks by default) + and GetFileInformationByHandle(). */ + +static int +win32_lstat(const wchar_t* path, struct _Py_stat_struct *result) +{ + return win32_xstat(path, result, FALSE); +} + +static int +win32_stat(const wchar_t* path, struct _Py_stat_struct *result) +{ + return win32_xstat(path, result, TRUE); +} + +#endif /* MS_WINDOWS */ + +PyDoc_STRVAR(stat_result__doc__, +"stat_result: Result from stat, fstat, or lstat.\n\n\ +This object may be accessed either as a tuple of\n\ + (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ +or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ +\n\ +Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\ +or st_flags, they are available as attributes only.\n\ +\n\ +See os.stat for more information."); + +static PyStructSequence_Field stat_result_fields[] = { + {"st_mode", "protection bits"}, + {"st_ino", "inode"}, + {"st_dev", "device"}, + {"st_nlink", "number of hard links"}, + {"st_uid", "user ID of owner"}, + {"st_gid", "group ID of owner"}, + {"st_size", "total size, in bytes"}, + /* The NULL is replaced with PyStructSequence_UnnamedField later. */ + {NULL, "integer time of last access"}, + {NULL, "integer time of last modification"}, + {NULL, "integer time of last change"}, + {"st_atime", "time of last access"}, + {"st_mtime", "time of last modification"}, + {"st_ctime", "time of last change"}, + {"st_atime_ns", "time of last access in nanoseconds"}, + {"st_mtime_ns", "time of last modification in nanoseconds"}, + {"st_ctime_ns", "time of last change in nanoseconds"}, +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE + {"st_blksize", "blocksize for filesystem I/O"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS + {"st_blocks", "number of blocks allocated"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_RDEV + {"st_rdev", "device type (if inode device)"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_FLAGS + {"st_flags", "user defined flags for file"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_GEN + {"st_gen", "generation number"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME + {"st_birthtime", "time of creation"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES + {"st_file_attributes", "Windows file attribute bits"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_FSTYPE + {"st_fstype", "Type of filesystem"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG + {"st_reparse_tag", "Windows reparse tag"}, +#endif + {0} +}; + +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE +#define ST_BLKSIZE_IDX 16 +#else +#define ST_BLKSIZE_IDX 15 +#endif + +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS +#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1) +#else +#define ST_BLOCKS_IDX ST_BLKSIZE_IDX +#endif + +#ifdef HAVE_STRUCT_STAT_ST_RDEV +#define ST_RDEV_IDX (ST_BLOCKS_IDX+1) +#else +#define ST_RDEV_IDX ST_BLOCKS_IDX +#endif + +#ifdef HAVE_STRUCT_STAT_ST_FLAGS +#define ST_FLAGS_IDX (ST_RDEV_IDX+1) +#else +#define ST_FLAGS_IDX ST_RDEV_IDX +#endif + +#ifdef HAVE_STRUCT_STAT_ST_GEN +#define ST_GEN_IDX (ST_FLAGS_IDX+1) +#else +#define ST_GEN_IDX ST_FLAGS_IDX +#endif + +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME +#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1) +#else +#define ST_BIRTHTIME_IDX ST_GEN_IDX +#endif + +#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES +#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1) +#else +#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX +#endif + +#ifdef HAVE_STRUCT_STAT_ST_FSTYPE +#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1) +#else +#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX +#endif + +#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG +#define ST_REPARSE_TAG_IDX (ST_FSTYPE_IDX+1) +#else +#define ST_REPARSE_TAG_IDX ST_FSTYPE_IDX +#endif +static PyStructSequence_Desc stat_result_desc = { + "stat_result", /* name */ + stat_result__doc__, /* doc */ + stat_result_fields, + 10 +}; + +PyDoc_STRVAR(statvfs_result__doc__, +"statvfs_result: Result from statvfs or fstatvfs.\n\n\ +This object may be accessed either as a tuple of\n\ + (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\ +or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\ +\n\ +See os.statvfs for more information."); + +static PyStructSequence_Field statvfs_result_fields[] = { + {"f_bsize", }, + {"f_frsize", }, + {"f_blocks", }, + {"f_bfree", }, + {"f_bavail", }, + {"f_files", }, + {"f_ffree", }, + {"f_favail", }, + {"f_flag", }, + {"f_namemax",}, + {"f_fsid", }, + {0} +}; + +static PyStructSequence_Desc statvfs_result_desc = { + "statvfs_result", /* name */ + statvfs_result__doc__, /* doc */ + statvfs_result_fields, + 10 +}; + +#if defined(HAVE_WAITID) && !defined(__APPLE__) +PyDoc_STRVAR(waitid_result__doc__, +"waitid_result: Result from waitid.\n\n\ +This object may be accessed either as a tuple of\n\ + (si_pid, si_uid, si_signo, si_status, si_code),\n\ +or via the attributes si_pid, si_uid, and so on.\n\ +\n\ +See os.waitid for more information."); + +static PyStructSequence_Field waitid_result_fields[] = { + {"si_pid", }, + {"si_uid", }, + {"si_signo", }, + {"si_status", }, + {"si_code", }, + {0} +}; + +static PyStructSequence_Desc waitid_result_desc = { + "waitid_result", /* name */ + waitid_result__doc__, /* doc */ + waitid_result_fields, + 5 +}; +#endif +static newfunc structseq_new; + +static PyObject * +statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyStructSequence *result; + int i; + + result = (PyStructSequence*)structseq_new(type, args, kwds); + if (!result) + return NULL; + /* If we have been initialized from a tuple, + st_?time might be set to None. Initialize it + from the int slots. */ + for (i = 7; i <= 9; i++) { + if (result->ob_item[i+3] == Py_None) { + Py_DECREF(Py_None); + Py_INCREF(result->ob_item[i]); + result->ob_item[i+3] = result->ob_item[i]; + } + } + return (PyObject*)result; +} + static int -setup_confname_table(struct constdef *table, size_t tablesize, - const char *tablename, PyObject *module) +_posix_clear(PyObject *module) { - PyObject *d = NULL; - size_t i; - - qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); - d = PyDict_New(); - if (d == NULL) - return -1; - - for (i=0; i < tablesize; ++i) { - PyObject *o = PyLong_FromLong(table[i].value); - if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { - Py_XDECREF(o); - Py_DECREF(d); - return -1; - } - Py_DECREF(o); - } - return PyModule_AddObject(module, tablename, d); + _posixstate *state = get_posix_state(module); + Py_CLEAR(state->billion); + Py_CLEAR(state->DirEntryType); + Py_CLEAR(state->ScandirIteratorType); +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + Py_CLEAR(state->SchedParamType); +#endif + Py_CLEAR(state->StatResultType); + Py_CLEAR(state->StatVFSResultType); + Py_CLEAR(state->TerminalSizeType); + Py_CLEAR(state->TimesResultType); + Py_CLEAR(state->UnameResultType); +#if defined(HAVE_WAITID) && !defined(__APPLE__) + Py_CLEAR(state->WaitidResultType); +#endif +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + Py_CLEAR(state->struct_rusage); +#endif + Py_CLEAR(state->st_mode); + return 0; } - -/* Return -1 on failure, 0 on success. */ + static int -setup_confname_tables(PyObject *module) +_posix_traverse(PyObject *module, visitproc visit, void *arg) { -#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) - if (setup_confname_table(posix_constants_pathconf, - sizeof(posix_constants_pathconf) - / sizeof(struct constdef), - "pathconf_names", module)) - return -1; + _posixstate *state = get_posix_state(module); + Py_VISIT(state->billion); + Py_VISIT(state->DirEntryType); + Py_VISIT(state->ScandirIteratorType); +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + Py_VISIT(state->SchedParamType); #endif -#ifdef HAVE_CONFSTR - if (setup_confname_table(posix_constants_confstr, - sizeof(posix_constants_confstr) - / sizeof(struct constdef), - "confstr_names", module)) - return -1; + Py_VISIT(state->StatResultType); + Py_VISIT(state->StatVFSResultType); + Py_VISIT(state->TerminalSizeType); + Py_VISIT(state->TimesResultType); + Py_VISIT(state->UnameResultType); +#if defined(HAVE_WAITID) && !defined(__APPLE__) + Py_VISIT(state->WaitidResultType); #endif -#ifdef HAVE_SYSCONF - if (setup_confname_table(posix_constants_sysconf, - sizeof(posix_constants_sysconf) - / sizeof(struct constdef), - "sysconf_names", module)) - return -1; +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + Py_VISIT(state->struct_rusage); #endif + Py_VISIT(state->st_mode); return 0; } + +static void +_posix_free(void *module) +{ + _posix_clear((PyObject *)module); +} - -/*[clinic input] -os.abort - -Abort the interpreter immediately. - -This function 'dumps core' or otherwise fails in the hardest way possible -on the hosting operating system. This function never returns. -[clinic start generated code]*/ - -static PyObject * -os_abort_impl(PyObject *module) -/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/ +static void +fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec) { - abort(); - /*NOTREACHED*/ -#ifndef __clang__ - /* Issue #28152: abort() is declared with __attribute__((__noreturn__)). - GCC emits a warning without "return NULL;" (compiler bug?), but Clang - is smarter and emits a warning on the return. */ - Py_FatalError("abort() called from Python code didn't abort!"); - return NULL; + PyObject *s = _PyLong_FromTime_t(sec); + PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec); + PyObject *s_in_ns = NULL; + PyObject *ns_total = NULL; + PyObject *float_s = NULL; + + if (!(s && ns_fractional)) + goto exit; + + s_in_ns = PyNumber_Multiply(s, get_posix_state(module)->billion); + if (!s_in_ns) + goto exit; + + ns_total = PyNumber_Add(s_in_ns, ns_fractional); + if (!ns_total) + goto exit; + + float_s = PyFloat_FromDouble(sec + 1e-9*nsec); + if (!float_s) { + goto exit; + } + + PyStructSequence_SET_ITEM(v, index, s); + PyStructSequence_SET_ITEM(v, index+3, float_s); + PyStructSequence_SET_ITEM(v, index+6, ns_total); + s = NULL; + float_s = NULL; + ns_total = NULL; +exit: + Py_XDECREF(s); + Py_XDECREF(ns_fractional); + Py_XDECREF(s_in_ns); + Py_XDECREF(ns_total); + Py_XDECREF(float_s); +} + +/* pack a system stat C structure into the Python stat tuple + (used by posix_stat() and posix_fstat()) */ +static PyObject* +_pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) +{ + unsigned long ansec, mnsec, cnsec; + PyObject *StatResultType = get_posix_state(module)->StatResultType; + PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType); + if (v == NULL) + return NULL; + + PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); + Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino)); + PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino)); +#ifdef MS_WINDOWS + PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); +#else + PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev)); +#endif + PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); +#if defined(MS_WINDOWS) + PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0)); + PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0)); +#else + PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid)); + PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid)); +#endif + Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size)); + PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size)); + +#if defined(HAVE_STAT_TV_NSEC) + ansec = st->st_atim.tv_nsec; + mnsec = st->st_mtim.tv_nsec; + cnsec = st->st_ctim.tv_nsec; +#elif defined(HAVE_STAT_TV_NSEC2) + ansec = st->st_atimespec.tv_nsec; + mnsec = st->st_mtimespec.tv_nsec; + cnsec = st->st_ctimespec.tv_nsec; +#elif defined(HAVE_STAT_NSEC) + ansec = st->st_atime_nsec; + mnsec = st->st_mtime_nsec; + cnsec = st->st_ctime_nsec; +#else + ansec = mnsec = cnsec = 0; +#endif + fill_time(module, v, 7, st->st_atime, ansec); + fill_time(module, v, 8, st->st_mtime, mnsec); + fill_time(module, v, 9, st->st_ctime, cnsec); + +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE + PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, + PyLong_FromLong((long)st->st_blksize)); +#endif +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS + PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, + PyLong_FromLong((long)st->st_blocks)); +#endif +#ifdef HAVE_STRUCT_STAT_ST_RDEV + PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, + PyLong_FromLong((long)st->st_rdev)); +#endif +#ifdef HAVE_STRUCT_STAT_ST_GEN + PyStructSequence_SET_ITEM(v, ST_GEN_IDX, + PyLong_FromLong((long)st->st_gen)); +#endif +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME + { + PyObject *val; + unsigned long bsec,bnsec; + bsec = (long)st->st_birthtime; +#ifdef HAVE_STAT_TV_NSEC2 + bnsec = st->st_birthtimespec.tv_nsec; +#else + bnsec = 0; +#endif + val = PyFloat_FromDouble(bsec + 1e-9*bnsec); + PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, + val); + } +#endif +#ifdef HAVE_STRUCT_STAT_ST_FLAGS + PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, + PyLong_FromLong((long)st->st_flags)); +#endif +#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES + PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX, + PyLong_FromUnsignedLong(st->st_file_attributes)); +#endif +#ifdef HAVE_STRUCT_STAT_ST_FSTYPE + PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX, + PyUnicode_FromString(st->st_fstype)); +#endif +#ifdef HAVE_STRUCT_STAT_ST_REPARSE_TAG + PyStructSequence_SET_ITEM(v, ST_REPARSE_TAG_IDX, + PyLong_FromUnsignedLong(st->st_reparse_tag)); +#endif + + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + + return v; +} + +/* POSIX methods */ + + +static PyObject * +posix_do_stat(PyObject *module, const char *function_name, path_t *path, + int dir_fd, int follow_symlinks) +{ + STRUCT_STAT st; + int result; + +#ifdef HAVE_FSTATAT + int fstatat_unavailable = 0; #endif -} -#ifdef MS_WINDOWS -/* Grab ShellExecute dynamically from shell32 */ -static int has_ShellExecute = -1; -static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR, - LPCWSTR, INT); -static int -check_ShellExecute() -{ - HINSTANCE hShell32; +#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT) + if (follow_symlinks_specified(function_name, follow_symlinks)) + return NULL; +#endif + + if (path_and_dir_fd_invalid("stat", path, dir_fd) || + dir_fd_and_fd_invalid("stat", dir_fd, path->fd) || + fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + if (path->fd != -1) + result = FSTAT(path->fd, &st); +#ifdef MS_WINDOWS + else if (follow_symlinks) + result = win32_stat(path->wide, &st); + else + result = win32_lstat(path->wide, &st); +#else + else +#if defined(HAVE_LSTAT) + if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) + result = LSTAT(path->narrow, &st); + else +#endif /* HAVE_LSTAT */ +#ifdef HAVE_FSTATAT + if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) { + if (HAVE_FSTATAT_RUNTIME) { + result = fstatat(dir_fd, path->narrow, &st, + follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); - /* only recheck */ - if (-1 == has_ShellExecute) { - Py_BEGIN_ALLOW_THREADS - /* Security note: this call is not vulnerable to "DLL hijacking". - SHELL32 is part of "KnownDLLs" and so Windows always load - the system SHELL32.DLL, even if there is another SHELL32.DLL - in the DLL search path. */ - hShell32 = LoadLibraryW(L"SHELL32"); - if (hShell32) { - *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32, - "ShellExecuteW"); - has_ShellExecute = Py_ShellExecuteW != NULL; } else { - has_ShellExecute = 0; + fstatat_unavailable = 1; } - Py_END_ALLOW_THREADS + } else +#endif /* HAVE_FSTATAT */ + result = STAT(path->narrow, &st); +#endif /* MS_WINDOWS */ + Py_END_ALLOW_THREADS + +#ifdef HAVE_FSTATAT + if (fstatat_unavailable) { + argument_unavailable_error("stat", "dir_fd"); + return NULL; } - return has_ShellExecute; -} +#endif + if (result != 0) { + return path_error(path); + } + + return _pystat_fromstructstat(module, &st); +} + +/*[python input] + +for s in """ + +FACCESSAT +FCHMODAT +FCHOWNAT +FSTATAT +LINKAT +MKDIRAT +MKFIFOAT +MKNODAT +OPENAT +READLINKAT +SYMLINKAT +UNLINKAT + +""".strip().split(): + s = s.strip() + print(""" +#ifdef HAVE_{s} + #define {s}_DIR_FD_CONVERTER dir_fd_converter +#else + #define {s}_DIR_FD_CONVERTER dir_fd_unavailable +#endif +""".rstrip().format(s=s)) + +for s in """ + +FCHDIR +FCHMOD +FCHOWN +FDOPENDIR +FEXECVE +FPATHCONF +FSTATVFS +FTRUNCATE + +""".strip().split(): + s = s.strip() + print(""" +#ifdef HAVE_{s} + #define PATH_HAVE_{s} 1 +#else + #define PATH_HAVE_{s} 0 +#endif + +""".rstrip().format(s=s)) +[python start generated code]*/ + +#ifdef HAVE_FACCESSAT + #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FCHMODAT + #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FCHOWNAT + #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FSTATAT + #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_LINKAT + #define LINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKDIRAT + #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKFIFOAT + #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKNODAT + #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_OPENAT + #define OPENAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_READLINKAT + #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_SYMLINKAT + #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_UNLINKAT + #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FCHDIR + #define PATH_HAVE_FCHDIR 1 +#else + #define PATH_HAVE_FCHDIR 0 +#endif + +#ifdef HAVE_FCHMOD + #define PATH_HAVE_FCHMOD 1 +#else + #define PATH_HAVE_FCHMOD 0 +#endif + +#ifdef HAVE_FCHOWN + #define PATH_HAVE_FCHOWN 1 +#else + #define PATH_HAVE_FCHOWN 0 +#endif + +#ifdef HAVE_FDOPENDIR + #define PATH_HAVE_FDOPENDIR 1 +#else + #define PATH_HAVE_FDOPENDIR 0 +#endif + +#ifdef HAVE_FEXECVE + #define PATH_HAVE_FEXECVE 1 +#else + #define PATH_HAVE_FEXECVE 0 +#endif + +#ifdef HAVE_FPATHCONF + #define PATH_HAVE_FPATHCONF 1 +#else + #define PATH_HAVE_FPATHCONF 0 +#endif + +#ifdef HAVE_FSTATVFS + #define PATH_HAVE_FSTATVFS 1 +#else + #define PATH_HAVE_FSTATVFS 0 +#endif + +#ifdef HAVE_FTRUNCATE + #define PATH_HAVE_FTRUNCATE 1 +#else + #define PATH_HAVE_FTRUNCATE 0 +#endif +/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/ + +#ifdef MS_WINDOWS + #undef PATH_HAVE_FTRUNCATE + #define PATH_HAVE_FTRUNCATE 1 +#endif + +/*[python input] + +class path_t_converter(CConverter): + + type = "path_t" + impl_by_reference = True + parse_by_reference = True + + converter = 'path_converter' + + def converter_init(self, *, allow_fd=False, nullable=False): + # right now path_t doesn't support default values. + # to support a default value, you'll need to override initialize(). + if self.default not in (unspecified, None): + fail("Can't specify a default to the path_t converter!") + + if self.c_default not in (None, 'Py_None'): + raise RuntimeError("Can't specify a c_default to the path_t converter!") + + self.nullable = nullable + self.allow_fd = allow_fd + + def pre_render(self): + def strify(value): + if isinstance(value, str): + return value + return str(int(bool(value))) + + # add self.py_name here when merging with posixmodule conversion + self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format( + self.function.name, + self.name, + strify(self.nullable), + strify(self.allow_fd), + ) + + def cleanup(self): + return "path_cleanup(&" + self.name + ");\n" + + +class dir_fd_converter(CConverter): + type = 'int' + + def converter_init(self, requires=None): + if self.default in (unspecified, None): + self.c_default = 'DEFAULT_DIR_FD' + if isinstance(requires, str): + self.converter = requires.upper() + '_DIR_FD_CONVERTER' + else: + self.converter = 'dir_fd_converter' + +class fildes_converter(CConverter): + type = 'int' + converter = 'fildes_converter' + +class uid_t_converter(CConverter): + type = "uid_t" + converter = '_Py_Uid_Converter' + +class gid_t_converter(CConverter): + type = "gid_t" + converter = '_Py_Gid_Converter' + +class dev_t_converter(CConverter): + type = 'dev_t' + converter = '_Py_Dev_Converter' + +class dev_t_return_converter(unsigned_long_return_converter): + type = 'dev_t' + conversion_fn = '_PyLong_FromDev' + unsigned_cast = '(dev_t)' + +class FSConverter_converter(CConverter): + type = 'PyObject *' + converter = 'PyUnicode_FSConverter' + def converter_init(self): + if self.default is not unspecified: + fail("FSConverter_converter does not support default values") + self.c_default = 'NULL' + + def cleanup(self): + return "Py_XDECREF(" + self.name + ");\n" + +class pid_t_converter(CConverter): + type = 'pid_t' + format_unit = '" _Py_PARSE_PID "' + +class idtype_t_converter(int_converter): + type = 'idtype_t' + +class id_t_converter(CConverter): + type = 'id_t' + format_unit = '" _Py_PARSE_PID "' + +class intptr_t_converter(CConverter): + type = 'intptr_t' + format_unit = '" _Py_PARSE_INTPTR "' + +class Py_off_t_converter(CConverter): + type = 'Py_off_t' + converter = 'Py_off_t_converter' + +class Py_off_t_return_converter(long_return_converter): + type = 'Py_off_t' + conversion_fn = 'PyLong_FromPy_off_t' + +class path_confname_converter(CConverter): + type="int" + converter="conv_path_confname" + +class confstr_confname_converter(path_confname_converter): + converter='conv_confstr_confname' + +class sysconf_confname_converter(path_confname_converter): + converter="conv_sysconf_confname" + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=f1c8ae8d744f6c8b]*/ + +/*[clinic input] + +os.stat + + path : path_t(allow_fd=True) + Path to be examined; can be string, bytes, a path-like object or + open-file-descriptor int. + + * + + dir_fd : dir_fd(requires='fstatat') = None + If not None, it should be a file descriptor open to a directory, + and path should be a relative string; path will then be relative to + that directory. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + stat will examine the symbolic link itself instead of the file + the link points to. + +Perform a stat system call on the given path. + +dir_fd and follow_symlinks may not be implemented + on your platform. If they are unavailable, using them will raise a + NotImplementedError. + +It's an error to use dir_fd or follow_symlinks when specifying path as + an open file descriptor. + +[clinic start generated code]*/ + +static PyObject * +os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/ +{ + return posix_do_stat(module, "stat", path, dir_fd, follow_symlinks); +} + + +/*[clinic input] +os.lstat + + path : path_t + + * + + dir_fd : dir_fd(requires='fstatat') = None + +Perform a stat system call on the given path, without following symbolic links. + +Like stat(), but do not follow symbolic links. +Equivalent to stat(path, follow_symlinks=False). +[clinic start generated code]*/ + +static PyObject * +os_lstat_impl(PyObject *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/ +{ + int follow_symlinks = 0; + return posix_do_stat(module, "lstat", path, dir_fd, follow_symlinks); +} + + +/*[clinic input] +os.access -> bool + + path: path_t + Path to be tested; can be string, bytes, or a path-like object. + + mode: int + Operating-system mode bitfield. Can be F_OK to test existence, + or the inclusive-OR of R_OK, W_OK, and X_OK. + + * + + dir_fd : dir_fd(requires='faccessat') = None + If not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that + directory. + + effective_ids: bool = False + If True, access will use the effective uid/gid instead of + the real uid/gid. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + access will examine the symbolic link itself instead of the file + the link points to. + +Use the real uid/gid to test for access to a path. + +{parameters} +dir_fd, effective_ids, and follow_symlinks may not be implemented + on your platform. If they are unavailable, using them will raise a + NotImplementedError. + +Note that most operations will use the effective uid/gid, therefore this + routine can be used in a suid/sgid environment to test if the invoking user + has the specified access to the path. + +[clinic start generated code]*/ + +static int +os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd, + int effective_ids, int follow_symlinks) +/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/ +{ + int return_value; + +#ifdef MS_WINDOWS + DWORD attr; +#else + int result; +#endif + +#ifdef HAVE_FACCESSAT + int faccessat_unavailable = 0; +#endif -/*[clinic input] -os.startfile - filepath: path_t - operation: Py_UNICODE = NULL - -Start a file with its associated application. - -When "operation" is not specified or "open", this acts like -double-clicking the file in Explorer, or giving the file name as an -argument to the DOS "start" command: the file is opened with whatever -application (if any) its extension is associated. -When another "operation" is given, it specifies what should be done with -the file. A typical operation is "print". - -startfile returns as soon as the associated application is launched. -There is no option to wait for the application to close, and no way -to retrieve the application's exit status. - -The filepath is relative to the current directory. If you want to use -an absolute path, make sure the first character is not a slash ("/"); -the underlying Win32 ShellExecute function doesn't work if it is. -[clinic start generated code]*/ +#ifndef HAVE_FACCESSAT + if (follow_symlinks_specified("access", follow_symlinks)) + return -1; + + if (effective_ids) { + argument_unavailable_error("access", "effective_ids"); + return -1; + } +#endif + +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + attr = GetFileAttributesW(path->wide); + Py_END_ALLOW_THREADS + + /* + * Access is possible if + * * we didn't get a -1, and + * * write access wasn't requested, + * * or the file isn't read-only, + * * or it's a directory. + * (Directories cannot be read-only on Windows.) + */ + return_value = (attr != INVALID_FILE_ATTRIBUTES) && + (!(mode & 2) || + !(attr & FILE_ATTRIBUTE_READONLY) || + (attr & FILE_ATTRIBUTE_DIRECTORY)); +#else + + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FACCESSAT + if ((dir_fd != DEFAULT_DIR_FD) || + effective_ids || + !follow_symlinks) { -static PyObject * -os_startfile_impl(PyObject *module, path_t *filepath, - const Py_UNICODE *operation) -/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/ -{ - HINSTANCE rc; + if (HAVE_FACCESSAT_RUNTIME) { + int flags = 0; + if (!follow_symlinks) + flags |= AT_SYMLINK_NOFOLLOW; + if (effective_ids) + flags |= AT_EACCESS; + result = faccessat(dir_fd, path->narrow, mode, flags); + } else { + faccessat_unavailable = 1; + } + } + else +#endif + result = access(path->narrow, mode); + Py_END_ALLOW_THREADS - if(!check_ShellExecute()) { - /* If the OS doesn't have ShellExecute, return a - NotImplementedError. */ - return PyErr_Format(PyExc_NotImplementedError, - "startfile not available on this platform"); - } +#ifdef HAVE_FACCESSAT + if (faccessat_unavailable) { + if (dir_fd != DEFAULT_DIR_FD) { + argument_unavailable_error("access", "dir_fd"); + return -1; + } + if (follow_symlinks_specified("access", follow_symlinks)) + return -1; - if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) { + if (effective_ids) { + argument_unavailable_error("access", "effective_ids"); + return -1; + } + /* should be unreachable */ + return -1; + } +#endif + return_value = !result; +#endif + + return return_value; +} + +#ifndef F_OK +#define F_OK 0 +#endif +#ifndef R_OK +#define R_OK 4 +#endif +#ifndef W_OK +#define W_OK 2 +#endif +#ifndef X_OK +#define X_OK 1 +#endif + + +#ifdef HAVE_TTYNAME +/*[clinic input] +os.ttyname + + fd: int + Integer file descriptor handle. + + / + +Return the name of the terminal device connected to 'fd'. +[clinic start generated code]*/ + +static PyObject * +os_ttyname_impl(PyObject *module, int fd) +/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/ +{ + + long size = sysconf(_SC_TTY_NAME_MAX); + if (size == -1) { + return posix_error(); + } + char *buffer = (char *)PyMem_RawMalloc(size); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + int ret = ttyname_r(fd, buffer, size); + if (ret != 0) { + PyMem_RawFree(buffer); + errno = ret; + return posix_error(); + } + PyObject *res = PyUnicode_DecodeFSDefault(buffer); + PyMem_RawFree(buffer); + return res; +} +#endif + +#ifdef HAVE_CTERMID +/*[clinic input] +os.ctermid + +Return the name of the controlling terminal for this process. +[clinic start generated code]*/ + +static PyObject * +os_ctermid_impl(PyObject *module) +/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/ +{ + char *ret; + char buffer[L_ctermid]; + +#ifdef USE_CTERMID_R + ret = ctermid_r(buffer); +#else + ret = ctermid(buffer); +#endif + if (ret == NULL) + return posix_error(); + return PyUnicode_DecodeFSDefault(buffer); +} +#endif /* HAVE_CTERMID */ + + +/*[clinic input] +os.chdir + + path: path_t(allow_fd='PATH_HAVE_FCHDIR') + +Change the current working directory to the specified path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +static PyObject * +os_chdir_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/ +{ + int result; + + if (PySys_Audit("os.chdir", "(O)", path->object) < 0) { return NULL; } - Py_BEGIN_ALLOW_THREADS - rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide, - NULL, NULL, SW_SHOWNORMAL); - Py_END_ALLOW_THREADS - - if (rc <= (HINSTANCE)32) { - win32_error_object("startfile", filepath->object); + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + /* on unix, success = 0, on windows, success = !0 */ + result = !win32_wchdir(path->wide); +#else +#ifdef HAVE_FCHDIR + if (path->fd != -1) + result = fchdir(path->fd); + else +#endif + result = chdir(path->narrow); +#endif + Py_END_ALLOW_THREADS + + if (result) { + return path_error(path); + } + + Py_RETURN_NONE; +} + + +#ifdef HAVE_FCHDIR +/*[clinic input] +os.fchdir + + fd: fildes + +Change to the directory of the given file descriptor. + +fd must be opened on a directory, not a file. +Equivalent to os.chdir(fd). + +[clinic start generated code]*/ + +static PyObject * +os_fchdir_impl(PyObject *module, int fd) +/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/ +{ + if (PySys_Audit("os.chdir", "(i)", fd) < 0) { return NULL; } - Py_RETURN_NONE; -} -#endif /* MS_WINDOWS */ - - -#ifdef HAVE_GETLOADAVG -/*[clinic input] -os.getloadavg - -Return average recent system load information. - -Return the number of processes in the system run queue averaged over -the last 1, 5, and 15 minutes as a tuple of three floats. -Raises OSError if the load average was unobtainable. -[clinic start generated code]*/ - -static PyObject * -os_getloadavg_impl(PyObject *module) -/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/ -{ - double loadavg[3]; - if (getloadavg(loadavg, 3)!=3) { - PyErr_SetString(PyExc_OSError, "Load averages are unobtainable"); + return posix_fildes_fd(fd, fchdir); +} +#endif /* HAVE_FCHDIR */ + + +/*[clinic input] +os.chmod + + path: path_t(allow_fd='PATH_HAVE_FCHMOD') + Path to be modified. May always be specified as a str, bytes, or a path-like object. + On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. + + mode: int + Operating-system mode bitfield. + + * + + dir_fd : dir_fd(requires='fchmodat') = None + If not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that + directory. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + chmod will modify the symbolic link itself instead of the file + the link points to. + +Change the access permissions of a file. + +It is an error to use dir_fd or follow_symlinks when specifying path as + an open file descriptor. +dir_fd and follow_symlinks may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +static PyObject * +os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, + int follow_symlinks) +/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/ +{ + int result; + +#ifdef MS_WINDOWS + DWORD attr; +#endif + +#ifdef HAVE_FCHMODAT + int fchmodat_nofollow_unsupported = 0; + int fchmodat_unsupported = 0; +#endif + +#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD)) + if (follow_symlinks_specified("chmod", follow_symlinks)) + return NULL; +#endif + + if (PySys_Audit("os.chmod", "Oii", path->object, mode, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { return NULL; - } else - return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); -} -#endif /* HAVE_GETLOADAVG */ - - -/*[clinic input] -os.device_encoding - fd: int - -Return a string describing the encoding of a terminal's file descriptor. - -The file descriptor must be attached to a terminal. -If the device is not a terminal, return None. -[clinic start generated code]*/ - -static PyObject * -os_device_encoding_impl(PyObject *module, int fd) -/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/ -{ - return _Py_device_encoding(fd); -} - - -#ifdef HAVE_SETRESUID -/*[clinic input] -os.setresuid - - ruid: uid_t - euid: uid_t - suid: uid_t - / - -Set the current process's real, effective, and saved user ids. -[clinic start generated code]*/ - -static PyObject * -os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid) -/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/ -{ - if (setresuid(ruid, euid, suid) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETRESUID */ - - -#ifdef HAVE_SETRESGID -/*[clinic input] -os.setresgid - - rgid: gid_t - egid: gid_t - sgid: gid_t - / - -Set the current process's real, effective, and saved group ids. -[clinic start generated code]*/ - -static PyObject * -os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid) -/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/ -{ - if (setresgid(rgid, egid, sgid) < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_SETRESGID */ - - -#ifdef HAVE_GETRESUID -/*[clinic input] -os.getresuid - -Return a tuple of the current process's real, effective, and saved user ids. -[clinic start generated code]*/ - -static PyObject * -os_getresuid_impl(PyObject *module) -/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/ -{ - uid_t ruid, euid, suid; - if (getresuid(&ruid, &euid, &suid) < 0) - return posix_error(); - return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid), - _PyLong_FromUid(euid), - _PyLong_FromUid(suid)); -} -#endif /* HAVE_GETRESUID */ - - -#ifdef HAVE_GETRESGID -/*[clinic input] -os.getresgid - -Return a tuple of the current process's real, effective, and saved group ids. -[clinic start generated code]*/ - -static PyObject * -os_getresgid_impl(PyObject *module) -/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/ -{ - gid_t rgid, egid, sgid; - if (getresgid(&rgid, &egid, &sgid) < 0) - return posix_error(); - return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid), - _PyLong_FromGid(egid), - _PyLong_FromGid(sgid)); -} -#endif /* HAVE_GETRESGID */ + } +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + attr = GetFileAttributesW(path->wide); + if (attr == INVALID_FILE_ATTRIBUTES) + result = 0; + else { + if (mode & _S_IWRITE) + attr &= ~FILE_ATTRIBUTE_READONLY; + else + attr |= FILE_ATTRIBUTE_READONLY; + result = SetFileAttributesW(path->wide, attr); + } + Py_END_ALLOW_THREADS + + if (!result) { + return path_error(path); + } +#else /* MS_WINDOWS */ + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FCHMOD + if (path->fd != -1) + result = fchmod(path->fd, mode); + else +#endif /* HAVE_CHMOD */ +#ifdef HAVE_LCHMOD + if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) + result = lchmod(path->narrow, mode); + else +#endif /* HAVE_LCHMOD */ +#ifdef HAVE_FCHMODAT + if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) { + if (HAVE_FCHMODAT_RUNTIME) { + /* + * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW! + * The documentation specifically shows how to use it, + * and then says it isn't implemented yet. + * (true on linux with glibc 2.15, and openindiana 3.x) + * + * Once it is supported, os.chmod will automatically + * support dir_fd and follow_symlinks=False. (Hopefully.) + * Until then, we need to be careful what exception we raise. + */ + result = fchmodat(dir_fd, path->narrow, mode, + follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); + /* + * But wait! We can't throw the exception without allowing threads, + * and we can't do that in this nested scope. (Macro trickery, sigh.) + */ + fchmodat_nofollow_unsupported = + result && + ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) && + !follow_symlinks; + } else { + fchmodat_unsupported = 1; + fchmodat_nofollow_unsupported = 1; -#ifdef USE_XATTRS -/*[clinic input] -os.getxattr + result = -1; + } + } + else +#endif /* HAVE_FHCMODAT */ + result = chmod(path->narrow, mode); + Py_END_ALLOW_THREADS + + if (result) { +#ifdef HAVE_FCHMODAT + if (fchmodat_unsupported) { + if (dir_fd != DEFAULT_DIR_FD) { + argument_unavailable_error("chmod", "dir_fd"); + return NULL; + } + } - path: path_t(allow_fd=True) - attribute: path_t - * - follow_symlinks: bool = True + if (fchmodat_nofollow_unsupported) { + if (dir_fd != DEFAULT_DIR_FD) + dir_fd_and_follow_symlinks_invalid("chmod", + dir_fd, follow_symlinks); + else + follow_symlinks_specified("chmod", follow_symlinks); + return NULL; + } + else +#endif /* HAVE_FCHMODAT */ + return path_error(path); + } +#endif /* MS_WINDOWS */ + + Py_RETURN_NONE; +} + + +#ifdef HAVE_FCHMOD +/*[clinic input] +os.fchmod + + fd: int + mode: int + +Change the access permissions of the file given by file descriptor fd. + +Equivalent to os.chmod(fd, mode). +[clinic start generated code]*/ + +static PyObject * +os_fchmod_impl(PyObject *module, int fd, int mode) +/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/ +{ + int res; + int async_err = 0; + + if (PySys_Audit("os.chmod", "iii", fd, mode, -1) < 0) { + return NULL; + } -Return the value of extended attribute attribute on path. + do { + Py_BEGIN_ALLOW_THREADS + res = fchmod(fd, mode); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) + return (!async_err) ? posix_error() : NULL; + + Py_RETURN_NONE; +} +#endif /* HAVE_FCHMOD */ + + +#ifdef HAVE_LCHMOD +/*[clinic input] +os.lchmod + + path: path_t + mode: int + +Change the access permissions of a file, without following symbolic links. + +If path is a symlink, this affects the link itself rather than the target. +Equivalent to chmod(path, mode, follow_symlinks=False)." +[clinic start generated code]*/ + +static PyObject * +os_lchmod_impl(PyObject *module, path_t *path, int mode) +/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/ +{ + int res; + if (PySys_Audit("os.chmod", "Oii", path->object, mode, -1) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS + res = lchmod(path->narrow, mode); + Py_END_ALLOW_THREADS + if (res < 0) { + path_error(path); + return NULL; + } + Py_RETURN_NONE; +} +#endif /* HAVE_LCHMOD */ + + +#ifdef HAVE_CHFLAGS +/*[clinic input] +os.chflags + + path: path_t + flags: unsigned_long(bitwise=True) + follow_symlinks: bool=True + +Set file flags. + +If follow_symlinks is False, and the last element of the path is a symbolic + link, chflags will change flags on the symbolic link itself instead of the + file the link points to. +follow_symlinks may not be implemented on your platform. If it is +unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +static PyObject * +os_chflags_impl(PyObject *module, path_t *path, unsigned long flags, + int follow_symlinks) +/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/ +{ + int result; + +#ifndef HAVE_LCHFLAGS + if (follow_symlinks_specified("chflags", follow_symlinks)) + return NULL; +#endif + + if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) { + return NULL; + } -path may be either a string, a path-like object, or an open file descriptor. -If follow_symlinks is False, and the last element of the path is a symbolic - link, getxattr will examine the symbolic link itself instead of the file - the link points to. + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_LCHFLAGS + if (!follow_symlinks) + result = lchflags(path->narrow, flags); + else +#endif + result = chflags(path->narrow, flags); + Py_END_ALLOW_THREADS + + if (result) + return path_error(path); + + Py_RETURN_NONE; +} +#endif /* HAVE_CHFLAGS */ + + +#ifdef HAVE_LCHFLAGS +/*[clinic input] +os.lchflags + + path: path_t + flags: unsigned_long(bitwise=True) + +Set file flags. + +This function will not follow symbolic links. +Equivalent to chflags(path, flags, follow_symlinks=False). +[clinic start generated code]*/ + +static PyObject * +os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags) +/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/ +{ + int res; + if (PySys_Audit("os.chflags", "Ok", path->object, flags) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS + res = lchflags(path->narrow, flags); + Py_END_ALLOW_THREADS + if (res < 0) { + return path_error(path); + } + Py_RETURN_NONE; +} +#endif /* HAVE_LCHFLAGS */ + + +#ifdef HAVE_CHROOT +/*[clinic input] +os.chroot + path: path_t + +Change root directory to path. + +[clinic start generated code]*/ + +static PyObject * +os_chroot_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/ +{ + int res; + Py_BEGIN_ALLOW_THREADS + res = chroot(path->narrow); + Py_END_ALLOW_THREADS + if (res < 0) + return path_error(path); + Py_RETURN_NONE; +} +#endif /* HAVE_CHROOT */ + + +#ifdef HAVE_FSYNC +/*[clinic input] +os.fsync + + fd: fildes + +Force write of fd to disk. +[clinic start generated code]*/ + +static PyObject * +os_fsync_impl(PyObject *module, int fd) +/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/ +{ + return posix_fildes_fd(fd, fsync); +} +#endif /* HAVE_FSYNC */ + + +#ifdef HAVE_SYNC +/*[clinic input] +os.sync + +Force write of everything to disk. +[clinic start generated code]*/ + +static PyObject * +os_sync_impl(PyObject *module) +/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/ +{ + Py_BEGIN_ALLOW_THREADS + sync(); + Py_END_ALLOW_THREADS + Py_RETURN_NONE; +} +#endif /* HAVE_SYNC */ + + +#ifdef HAVE_FDATASYNC +#ifdef __hpux +extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ +#endif + +/*[clinic input] +os.fdatasync + + fd: fildes + +Force write of fd to disk without forcing update of metadata. +[clinic start generated code]*/ + +static PyObject * +os_fdatasync_impl(PyObject *module, int fd) +/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/ +{ + return posix_fildes_fd(fd, fdatasync); +} +#endif /* HAVE_FDATASYNC */ + + +#ifdef HAVE_CHOWN +/*[clinic input] +os.chown + + path : path_t(allow_fd='PATH_HAVE_FCHOWN') + Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int. + + uid: uid_t + + gid: gid_t + + * + + dir_fd : dir_fd(requires='fchownat') = None + If not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that + directory. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + stat will examine the symbolic link itself instead of the file + the link points to. + +Change the owner and group id of path to the numeric uid and gid.\ + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, chown will modify the symbolic link itself instead of the file the + link points to. +It is an error to use dir_fd or follow_symlinks when specifying path as + an open file descriptor. +dir_fd and follow_symlinks may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +static PyObject * +os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, + int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/ +{ + int result; + +#if defined(HAVE_FCHOWNAT) + int fchownat_unsupported = 0; +#endif -[clinic start generated code]*/ +#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT)) + if (follow_symlinks_specified("chown", follow_symlinks)) + return NULL; +#endif + if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) || + fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks)) + return NULL; + + if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } -static PyObject * -os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, - int follow_symlinks) -/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/ -{ - Py_ssize_t i; - PyObject *buffer = NULL; + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FCHOWN + if (path->fd != -1) + result = fchown(path->fd, uid, gid); + else +#endif +#ifdef HAVE_LCHOWN + if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) + result = lchown(path->narrow, uid, gid); + else +#endif +#ifdef HAVE_FCHOWNAT + if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) { + if (HAVE_FCHOWNAT_RUNTIME) { + result = fchownat(dir_fd, path->narrow, uid, gid, + follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); + } else { + fchownat_unsupported = 1; + } + } else +#endif + result = chown(path->narrow, uid, gid); + Py_END_ALLOW_THREADS + +#ifdef HAVE_FCHOWNAT + if (fchownat_unsupported) { + /* This would be incorrect if the current platform + * doesn't support lchown. + */ + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif - if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) + if (result) + return path_error(path); + + Py_RETURN_NONE; +} +#endif /* HAVE_CHOWN */ + + +#ifdef HAVE_FCHOWN +/*[clinic input] +os.fchown + + fd: int + uid: uid_t + gid: gid_t + +Change the owner and group id of the file specified by file descriptor. + +Equivalent to os.chown(fd, uid, gid). + +[clinic start generated code]*/ + +static PyObject * +os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid) +/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/ +{ + int res; + int async_err = 0; + + if (PySys_Audit("os.chown", "iIIi", fd, uid, gid, -1) < 0) { return NULL; + } - if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) { + do { + Py_BEGIN_ALLOW_THREADS + res = fchown(fd, uid, gid); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) + return (!async_err) ? posix_error() : NULL; + + Py_RETURN_NONE; +} +#endif /* HAVE_FCHOWN */ + + +#ifdef HAVE_LCHOWN +/*[clinic input] +os.lchown + + path : path_t + uid: uid_t + gid: gid_t + +Change the owner and group id of path to the numeric uid and gid. + +This function will not follow symbolic links. +Equivalent to os.chown(path, uid, gid, follow_symlinks=False). +[clinic start generated code]*/ + +static PyObject * +os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid) +/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/ +{ + int res; + if (PySys_Audit("os.chown", "OIIi", path->object, uid, gid, -1) < 0) { return NULL; } + Py_BEGIN_ALLOW_THREADS + res = lchown(path->narrow, uid, gid); + Py_END_ALLOW_THREADS + if (res < 0) { + return path_error(path); + } + Py_RETURN_NONE; +} +#endif /* HAVE_LCHOWN */ + + +static PyObject * +posix_getcwd(int use_bytes) +{ +#ifdef MS_WINDOWS + wchar_t wbuf[MAXPATHLEN]; + wchar_t *wbuf2 = wbuf; + DWORD len; + + Py_BEGIN_ALLOW_THREADS + len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); + /* If the buffer is large enough, len does not include the + terminating \0. If the buffer is too small, len includes + the space needed for the terminator. */ + if (len >= Py_ARRAY_LENGTH(wbuf)) { + if (len <= PY_SSIZE_T_MAX / sizeof(wchar_t)) { + wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t)); + } + else { + wbuf2 = NULL; + } + if (wbuf2) { + len = GetCurrentDirectoryW(len, wbuf2); + } + } + Py_END_ALLOW_THREADS - for (i = 0; ; i++) { - void *ptr; - ssize_t result; - static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; - Py_ssize_t buffer_size = buffer_sizes[i]; - if (!buffer_size) { - path_error(path); - return NULL; - } - buffer = PyBytes_FromStringAndSize(NULL, buffer_size); - if (!buffer) - return NULL; - ptr = PyBytes_AS_STRING(buffer); - - Py_BEGIN_ALLOW_THREADS; - if (path->fd >= 0) - result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size); - else if (follow_symlinks) - result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size); - else - result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size); - Py_END_ALLOW_THREADS; - - if (result < 0) { - Py_DECREF(buffer); - if (errno == ERANGE) - continue; - path_error(path); + if (!wbuf2) { + PyErr_NoMemory(); + return NULL; + } + if (!len) { + if (wbuf2 != wbuf) + PyMem_RawFree(wbuf2); + return PyErr_SetFromWindowsErr(0); + } + + PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len); + if (wbuf2 != wbuf) { + PyMem_RawFree(wbuf2); + } + + if (use_bytes) { + if (resobj == NULL) { return NULL; } - - if (result != buffer_size) { - /* Can only shrink. */ - _PyBytes_Resize(&buffer, result); - } - break; + Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj)); } - return buffer; -} - - -/*[clinic input] -os.setxattr + return resobj; +#else + const size_t chunk = 1024; - path: path_t(allow_fd=True) - attribute: path_t - value: Py_buffer - flags: int = 0 - * - follow_symlinks: bool = True + char *buf = NULL; + char *cwd = NULL; + size_t buflen = 0; -Set extended attribute attribute on path to value. + Py_BEGIN_ALLOW_THREADS + do { + char *newbuf; + if (buflen <= PY_SSIZE_T_MAX - chunk) { + buflen += chunk; + newbuf = PyMem_RawRealloc(buf, buflen); + } + else { + newbuf = NULL; + } + if (newbuf == NULL) { + PyMem_RawFree(buf); + buf = NULL; + break; + } + buf = newbuf; + + cwd = getcwd(buf, buflen); + } while (cwd == NULL && errno == ERANGE); + Py_END_ALLOW_THREADS + + if (buf == NULL) { + return PyErr_NoMemory(); + } + if (cwd == NULL) { + PyMem_RawFree(buf); + return posix_error(); + } + + PyObject *obj; + if (use_bytes) { + obj = PyBytes_FromStringAndSize(buf, strlen(buf)); + } + else { + obj = PyUnicode_DecodeFSDefault(buf); + } + PyMem_RawFree(buf); + + return obj; +#endif /* !MS_WINDOWS */ +} + + +/*[clinic input] +os.getcwd + +Return a unicode string representing the current working directory. +[clinic start generated code]*/ + +static PyObject * +os_getcwd_impl(PyObject *module) +/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/ +{ + return posix_getcwd(0); +} + + +/*[clinic input] +os.getcwdb + +Return a bytes string representing the current working directory. +[clinic start generated code]*/ + +static PyObject * +os_getcwdb_impl(PyObject *module) +/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/ +{ + return posix_getcwd(1); +} + + +#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS)) +#define HAVE_LINK 1 +#endif + +#ifdef HAVE_LINK +/*[clinic input] + +os.link + + src : path_t + dst : path_t + * + src_dir_fd : dir_fd = None + dst_dir_fd : dir_fd = None + follow_symlinks: bool = True + +Create a hard link to a file. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +If follow_symlinks is False, and the last element of src is a symbolic + link, link will create a link to the symbolic link itself instead of the + file the link points to. +src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your + platform. If they are unavailable, using them will raise a + NotImplementedError. +[clinic start generated code]*/ + +static PyObject * +os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd, int follow_symlinks) +/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/ +{ +#ifdef MS_WINDOWS + BOOL result = FALSE; +#else + int result; +#endif +#if defined(HAVE_LINKAT) + int linkat_unavailable = 0; +#endif + +#ifndef HAVE_LINKAT + if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) { + argument_unavailable_error("link", "src_dir_fd and dst_dir_fd"); + return NULL; + } +#endif + +#ifndef MS_WINDOWS + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { + PyErr_SetString(PyExc_NotImplementedError, + "link: src and dst must be the same type"); + return NULL; + } +#endif + + if (PySys_Audit("os.link", "OOii", src->object, dst->object, + src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd, + dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) { + return NULL; + } -path may be either a string, a path-like object, or an open file descriptor. -If follow_symlinks is False, and the last element of the path is a symbolic - link, setxattr will modify the symbolic link itself instead of the file - the link points to. +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + result = CreateHardLinkW(dst->wide, src->wide, NULL); + Py_END_ALLOW_THREADS + + if (!result) + return path_error2(src, dst); +#else + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_LINKAT + if ((src_dir_fd != DEFAULT_DIR_FD) || + (dst_dir_fd != DEFAULT_DIR_FD) || + (!follow_symlinks)) { -[clinic start generated code]*/ + if (HAVE_LINKAT_RUNTIME) { -static PyObject * -os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, - Py_buffer *value, int flags, int follow_symlinks) -/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/ -{ - ssize_t result; + result = linkat(src_dir_fd, src->narrow, + dst_dir_fd, dst->narrow, + follow_symlinks ? AT_SYMLINK_FOLLOW : 0); - if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) + } +#ifdef __APPLE__ + else { + if (src_dir_fd == DEFAULT_DIR_FD && dst_dir_fd == DEFAULT_DIR_FD) { + /* See issue 41355: This matches the behaviour of !HAVE_LINKAT */ + result = link(src->narrow, dst->narrow); + } else { + linkat_unavailable = 1; + } + } +#endif + } + else +#endif /* HAVE_LINKAT */ + result = link(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + +#ifdef HAVE_LINKAT + if (linkat_unavailable) { + /* Either or both dir_fd arguments were specified */ + if (src_dir_fd != DEFAULT_DIR_FD) { + argument_unavailable_error("link", "src_dir_fd"); + } else { + argument_unavailable_error("link", "dst_dir_fd"); + } return NULL; + } +#endif - if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object, - value->buf, value->len, flags) < 0) { + if (result) + return path_error2(src, dst); +#endif /* MS_WINDOWS */ + + Py_RETURN_NONE; +} +#endif + + +#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) +static PyObject * +_listdir_windows_no_opendir(path_t *path, PyObject *list) +{ + PyObject *v; + HANDLE hFindFile = INVALID_HANDLE_VALUE; + BOOL result; + wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */ + /* only claim to have space for MAX_PATH */ + Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4; + wchar_t *wnamebuf = NULL; + + WIN32_FIND_DATAW wFileData; + const wchar_t *po_wchars; + + if (!path->wide) { /* Default arg: "." */ + po_wchars = L"."; + len = 1; + } else { + po_wchars = path->wide; + len = wcslen(path->wide); + } + /* The +5 is so we can append "\\*.*\0" */ + wnamebuf = PyMem_New(wchar_t, len + 5); + if (!wnamebuf) { + PyErr_NoMemory(); + goto exit; + } + wcscpy(wnamebuf, po_wchars); + if (len > 0) { + wchar_t wch = wnamebuf[len-1]; + if (wch != SEP && wch != ALTSEP && wch != L':') + wnamebuf[len++] = SEP; + wcscpy(wnamebuf + len, L"*.*"); + } + if ((list = PyList_New(0)) == NULL) { + goto exit; + } + Py_BEGIN_ALLOW_THREADS + hFindFile = FindFirstFileW(wnamebuf, &wFileData); + Py_END_ALLOW_THREADS + if (hFindFile == INVALID_HANDLE_VALUE) { + int error = GetLastError(); + if (error == ERROR_FILE_NOT_FOUND) + goto exit; + Py_DECREF(list); + list = path_error(path); + goto exit; + } + do { + /* Skip over . and .. */ + if (wcscmp(wFileData.cFileName, L".") != 0 && + wcscmp(wFileData.cFileName, L"..") != 0) { + v = PyUnicode_FromWideChar(wFileData.cFileName, + wcslen(wFileData.cFileName)); + if (path->narrow && v) { + Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); + } + if (v == NULL) { + Py_DECREF(list); + list = NULL; + break; + } + if (PyList_Append(list, v) != 0) { + Py_DECREF(v); + Py_DECREF(list); + list = NULL; + break; + } + Py_DECREF(v); + } + Py_BEGIN_ALLOW_THREADS + result = FindNextFileW(hFindFile, &wFileData); + Py_END_ALLOW_THREADS + /* FindNextFile sets error to ERROR_NO_MORE_FILES if + it got to the end of the directory. */ + if (!result && GetLastError() != ERROR_NO_MORE_FILES) { + Py_DECREF(list); + list = path_error(path); + goto exit; + } + } while (result == TRUE); + +exit: + if (hFindFile != INVALID_HANDLE_VALUE) { + if (FindClose(hFindFile) == FALSE) { + if (list != NULL) { + Py_DECREF(list); + list = path_error(path); + } + } + } + PyMem_Free(wnamebuf); + + return list; +} /* end of _listdir_windows_no_opendir */ + +#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */ + +static PyObject * +_posix_listdir(path_t *path, PyObject *list) +{ + PyObject *v; + DIR *dirp = NULL; + struct dirent *ep; + int return_str; /* if false, return bytes */ +#ifdef HAVE_FDOPENDIR + int fd = -1; +#endif + + errno = 0; +#ifdef HAVE_FDOPENDIR + if (path->fd != -1) { + if (HAVE_FDOPENDIR_RUNTIME) { + /* closedir() closes the FD, so we duplicate it */ + fd = _Py_dup(path->fd); + if (fd == -1) + return NULL; + + return_str = 1; + + Py_BEGIN_ALLOW_THREADS + dirp = fdopendir(fd); + Py_END_ALLOW_THREADS + } else { + PyErr_SetString(PyExc_TypeError, + "listdir: path should be string, bytes, os.PathLike or None, not int"); + return NULL; + } + } + else +#endif + { + const char *name; + if (path->narrow) { + name = path->narrow; + /* only return bytes if they specified a bytes-like object */ + return_str = !PyObject_CheckBuffer(path->object); + } + else { + name = "."; + return_str = 1; + } + + Py_BEGIN_ALLOW_THREADS + dirp = opendir(name); + Py_END_ALLOW_THREADS + } + + if (dirp == NULL) { + list = path_error(path); +#ifdef HAVE_FDOPENDIR + if (fd != -1) { + Py_BEGIN_ALLOW_THREADS + close(fd); + Py_END_ALLOW_THREADS + } +#endif + goto exit; + } + if ((list = PyList_New(0)) == NULL) { + goto exit; + } + for (;;) { + errno = 0; + Py_BEGIN_ALLOW_THREADS + ep = readdir(dirp); + Py_END_ALLOW_THREADS + if (ep == NULL) { + if (errno == 0) { + break; + } else { + Py_DECREF(list); + list = path_error(path); + goto exit; + } + } + if (ep->d_name[0] == '.' && + (NAMLEN(ep) == 1 || + (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) + continue; + if (return_str) + v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep)); + else + v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep)); + if (v == NULL) { + Py_CLEAR(list); + break; + } + if (PyList_Append(list, v) != 0) { + Py_DECREF(v); + Py_CLEAR(list); + break; + } + Py_DECREF(v); + } + +exit: + if (dirp != NULL) { + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FDOPENDIR + if (fd > -1) + rewinddir(dirp); +#endif + closedir(dirp); + Py_END_ALLOW_THREADS + } + + return list; +} /* end of _posix_listdir */ +#endif /* which OS */ + + +/*[clinic input] +os.listdir + + path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None + +Return a list containing the names of the files in the directory. + +path can be specified as either str, bytes, or a path-like object. If path is bytes, + the filenames returned will also be bytes; in all other circumstances + the filenames returned will be str. +If path is None, uses the path='.'. +On some platforms, path may also be specified as an open file descriptor;\ + the file descriptor must refer to a directory. + If this functionality is unavailable, using it raises NotImplementedError. + +The list is in arbitrary order. It does not include the special +entries '.' and '..' even if they are present in the directory. + + +[clinic start generated code]*/ + +static PyObject * +os_listdir_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/ +{ + if (PySys_Audit("os.listdir", "O", + path->object ? path->object : Py_None) < 0) { return NULL; } +#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) + return _listdir_windows_no_opendir(path, NULL); +#else + return _posix_listdir(path, NULL); +#endif +} + +#ifdef MS_WINDOWS +/* A helper function for abspath on win32 */ +/*[clinic input] +os._getfullpathname + + path: path_t + / + +[clinic start generated code]*/ + +static PyObject * +os__getfullpathname_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/ +{ + wchar_t *abspath; + + /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */ + if (_Py_abspath(path->wide, &abspath) < 0) { + return win32_error_object("GetFullPathNameW", path->object); + } + if (abspath == NULL) { + return PyErr_NoMemory(); + } - Py_BEGIN_ALLOW_THREADS; - if (path->fd > -1) - result = fsetxattr(path->fd, attribute->narrow, - value->buf, value->len, flags); - else if (follow_symlinks) - result = setxattr(path->narrow, attribute->narrow, - value->buf, value->len, flags); - else - result = lsetxattr(path->narrow, attribute->narrow, - value->buf, value->len, flags); - Py_END_ALLOW_THREADS; - - if (result) { - path_error(path); + PyObject *str = PyUnicode_FromWideChar(abspath, wcslen(abspath)); + PyMem_RawFree(abspath); + if (str == NULL) { return NULL; } - - Py_RETURN_NONE; -} - + if (path->narrow) { + Py_SETREF(str, PyUnicode_EncodeFSDefault(str)); + } + return str; +} + + +/*[clinic input] +os._getfinalpathname + + path: path_t + / + +A helper function for samepath on windows. +[clinic start generated code]*/ + +static PyObject * +os__getfinalpathname_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/ +{ + HANDLE hFile; + wchar_t buf[MAXPATHLEN], *target_path = buf; + int buf_size = Py_ARRAY_LENGTH(buf); + int result_length; + PyObject *result; + + Py_BEGIN_ALLOW_THREADS + hFile = CreateFileW( + path->wide, + 0, /* desired access */ + 0, /* share mode */ + NULL, /* security attributes */ + OPEN_EXISTING, + /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + Py_END_ALLOW_THREADS + + if (hFile == INVALID_HANDLE_VALUE) { + return win32_error_object("CreateFileW", path->object); + } + + /* We have a good handle to the target, use it to determine the + target path name. */ + while (1) { + Py_BEGIN_ALLOW_THREADS + result_length = GetFinalPathNameByHandleW(hFile, target_path, + buf_size, VOLUME_NAME_DOS); + Py_END_ALLOW_THREADS + + if (!result_length) { + result = win32_error_object("GetFinalPathNameByHandleW", + path->object); + goto cleanup; + } + + if (result_length < buf_size) { + break; + } + + wchar_t *tmp; + tmp = PyMem_Realloc(target_path != buf ? target_path : NULL, + result_length * sizeof(*tmp)); + if (!tmp) { + result = PyErr_NoMemory(); + goto cleanup; + } + + buf_size = result_length; + target_path = tmp; + } + + result = PyUnicode_FromWideChar(target_path, result_length); + if (result && path->narrow) { + Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); + } + +cleanup: + if (target_path != buf) { + PyMem_Free(target_path); + } + CloseHandle(hFile); + return result; +} + + +/*[clinic input] +os._getvolumepathname + + path: path_t + +A helper function for ismount on Win32. +[clinic start generated code]*/ + +static PyObject * +os__getvolumepathname_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/ +{ + PyObject *result; + wchar_t *mountpath=NULL; + size_t buflen; + BOOL ret; + + /* Volume path should be shorter than entire path */ + buflen = Py_MAX(path->length, MAX_PATH); + + if (buflen > PY_DWORD_MAX) { + PyErr_SetString(PyExc_OverflowError, "path too long"); + return NULL; + } + + mountpath = PyMem_New(wchar_t, buflen); + if (mountpath == NULL) + return PyErr_NoMemory(); + + Py_BEGIN_ALLOW_THREADS + ret = GetVolumePathNameW(path->wide, mountpath, + Py_SAFE_DOWNCAST(buflen, size_t, DWORD)); + Py_END_ALLOW_THREADS + + if (!ret) { + result = win32_error_object("_getvolumepathname", path->object); + goto exit; + } + result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); + if (path->narrow) + Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); + +exit: + PyMem_Free(mountpath); + return result; +} + /*[clinic input] -os.removexattr - - path: path_t(allow_fd=True) - attribute: path_t - * - follow_symlinks: bool = True - -Remove extended attribute attribute on path. +os._path_splitroot -path may be either a string, a path-like object, or an open file descriptor. -If follow_symlinks is False, and the last element of the path is a symbolic - link, removexattr will modify the symbolic link itself instead of the file - the link points to. + path: path_t +Removes everything after the root on Win32. [clinic start generated code]*/ static PyObject * -os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, - int follow_symlinks) -/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/ +os__path_splitroot_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=ab7f1a88b654581c input=dc93b1d3984cffb6]*/ { - ssize_t result; - - if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) - return NULL; + wchar_t *buffer; + wchar_t *end; + PyObject *result = NULL; + HRESULT ret; - if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) { + buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * (wcslen(path->wide) + 1)); + if (!buffer) { return NULL; } + wcscpy(buffer, path->wide); + for (wchar_t *p = wcschr(buffer, L'/'); p; p = wcschr(p, L'/')) { + *p = L'\\'; + } - Py_BEGIN_ALLOW_THREADS; - if (path->fd > -1) - result = fremovexattr(path->fd, attribute->narrow); - else if (follow_symlinks) - result = removexattr(path->narrow, attribute->narrow); - else - result = lremovexattr(path->narrow, attribute->narrow); - Py_END_ALLOW_THREADS; - - if (result) { - return path_error(path); + Py_BEGIN_ALLOW_THREADS + ret = PathCchSkipRoot(buffer, &end); + Py_END_ALLOW_THREADS + if (FAILED(ret)) { + result = Py_BuildValue("sO", "", path->object); + } else if (end != buffer) { + size_t rootLen = (size_t)(end - buffer); + result = Py_BuildValue("NN", + PyUnicode_FromWideChar(path->wide, rootLen), + PyUnicode_FromWideChar(path->wide + rootLen, -1) + ); + } else { + result = Py_BuildValue("Os", path->object, ""); } + PyMem_Free(buffer); - Py_RETURN_NONE; + return result; } -/*[clinic input] -os.listxattr - - path: path_t(allow_fd=True, nullable=True) = None - * - follow_symlinks: bool = True - -Return a list of extended attributes on path. - -path may be either None, a string, a path-like object, or an open file descriptor. -if path is None, listxattr will examine the current directory. -If follow_symlinks is False, and the last element of the path is a symbolic - link, listxattr will examine the symbolic link itself instead of the file - the link points to. -[clinic start generated code]*/ +#endif /* MS_WINDOWS */ + + +/*[clinic input] +os.mkdir + + path : path_t + + mode: int = 0o777 + + * + + dir_fd : dir_fd(requires='mkdirat') = None + +# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\ + +Create a directory. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +The mode argument is ignored on Windows. +[clinic start generated code]*/ + +static PyObject * +os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) +/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/ +{ + int result; +#ifdef HAVE_MKDIRAT + int mkdirat_unavailable = 0; +#endif + + if (PySys_Audit("os.mkdir", "Oii", path->object, mode, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } -static PyObject * -os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) -/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/ -{ - Py_ssize_t i; - PyObject *result = NULL; - const char *name; - char *buffer = NULL; +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + result = CreateDirectoryW(path->wide, NULL); + Py_END_ALLOW_THREADS + + if (!result) + return path_error(path); +#else + Py_BEGIN_ALLOW_THREADS +#if HAVE_MKDIRAT + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_MKDIRAT_RUNTIME) { + result = mkdirat(dir_fd, path->narrow, mode); - if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) - goto exit; + } else { + mkdirat_unavailable = 1; + } + } else +#endif +#if defined(__WATCOMC__) && !defined(__QNX__) + result = mkdir(path->narrow); +#else + result = mkdir(path->narrow, mode); +#endif + Py_END_ALLOW_THREADS - if (PySys_Audit("os.listxattr", "(O)", - path->object ? path->object : Py_None) < 0) { +#if HAVE_MKDIRAT + if (mkdirat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); return NULL; } +#endif - name = path->narrow ? path->narrow : "."; + if (result < 0) + return path_error(path); +#endif /* MS_WINDOWS */ + Py_RETURN_NONE; +} + + +/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */ +#if defined(HAVE_SYS_RESOURCE_H) +#include +#endif + + +#ifdef HAVE_NICE +/*[clinic input] +os.nice + + increment: int + / + +Add increment to the priority of process and return the new priority. +[clinic start generated code]*/ + +static PyObject * +os_nice_impl(PyObject *module, int increment) +/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/ +{ + int value; + + /* There are two flavours of 'nice': one that returns the new + priority (as required by almost all standards out there) and the + Linux/FreeBSD one, which returns '0' on success and advices + the use of getpriority() to get the new priority. + + If we are of the nice family that returns the new priority, we + need to clear errno before the call, and check if errno is filled + before calling posix_error() on a returnvalue of -1, because the + -1 may be the actual new priority! */ + + errno = 0; + value = nice(increment); +#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) + if (value == 0) + value = getpriority(PRIO_PROCESS, 0); +#endif + if (value == -1 && errno != 0) + /* either nice() or getpriority() returned an error */ + return posix_error(); + return PyLong_FromLong((long) value); +} +#endif /* HAVE_NICE */ + + +#ifdef HAVE_GETPRIORITY +/*[clinic input] +os.getpriority + + which: int + who: int + +Return program scheduling priority. +[clinic start generated code]*/ + +static PyObject * +os_getpriority_impl(PyObject *module, int which, int who) +/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/ +{ + int retval; + + errno = 0; + retval = getpriority(which, who); + if (errno != 0) + return posix_error(); + return PyLong_FromLong((long)retval); +} +#endif /* HAVE_GETPRIORITY */ + + +#ifdef HAVE_SETPRIORITY +/*[clinic input] +os.setpriority + + which: int + who: int + priority: int + +Set program scheduling priority. +[clinic start generated code]*/ + +static PyObject * +os_setpriority_impl(PyObject *module, int which, int who, int priority) +/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/ +{ + int retval; + + retval = setpriority(which, who, priority); + if (retval == -1) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETPRIORITY */ + + +static PyObject * +internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace) +{ + const char *function_name = is_replace ? "replace" : "rename"; + int dir_fd_specified; + +#ifdef HAVE_RENAMEAT + int renameat_unavailable = 0; +#endif - for (i = 0; ; i++) { - const char *start, *trace, *end; - ssize_t length; - static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 }; - Py_ssize_t buffer_size = buffer_sizes[i]; - if (!buffer_size) { - /* ERANGE */ - path_error(path); - break; - } - buffer = PyMem_MALLOC(buffer_size); - if (!buffer) { - PyErr_NoMemory(); - break; - } +#ifdef MS_WINDOWS + BOOL result; + int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0; +#else + int result; +#endif + + dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) || + (dst_dir_fd != DEFAULT_DIR_FD); +#ifndef HAVE_RENAMEAT + if (dir_fd_specified) { + argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); + return NULL; + } +#endif + + if (PySys_Audit("os.rename", "OOii", src->object, dst->object, + src_dir_fd == DEFAULT_DIR_FD ? -1 : src_dir_fd, + dst_dir_fd == DEFAULT_DIR_FD ? -1 : dst_dir_fd) < 0) { + return NULL; + } - Py_BEGIN_ALLOW_THREADS; - if (path->fd > -1) - length = flistxattr(path->fd, buffer, buffer_size); - else if (follow_symlinks) - length = listxattr(name, buffer, buffer_size); - else - length = llistxattr(name, buffer, buffer_size); - Py_END_ALLOW_THREADS; - - if (length < 0) { - if (errno == ERANGE) { - PyMem_FREE(buffer); - buffer = NULL; - continue; - } - path_error(path); - break; +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + result = MoveFileExW(src->wide, dst->wide, flags); + Py_END_ALLOW_THREADS + + if (!result) + return path_error2(src, dst); + +#else + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { + PyErr_Format(PyExc_ValueError, + "%s: src and dst must be the same type", function_name); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_RENAMEAT + if (dir_fd_specified) { + if (HAVE_RENAMEAT_RUNTIME) { + result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow); + } else { + renameat_unavailable = 1; } + } else +#endif + result = rename(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + - result = PyList_New(0); - if (!result) { - goto exit; - } +#ifdef HAVE_RENAMEAT + if (renameat_unavailable) { + argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); + return NULL; + } +#endif - end = buffer + length; - for (trace = start = buffer; trace != end; trace++) { - if (!*trace) { - int error; - PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start, - trace - start); - if (!attribute) { - Py_DECREF(result); - result = NULL; - goto exit; - } - error = PyList_Append(result, attribute); - Py_DECREF(attribute); - if (error) { - Py_DECREF(result); - result = NULL; - goto exit; - } - start = trace + 1; - } - } - break; + if (result) + return path_error2(src, dst); +#endif + Py_RETURN_NONE; +} + + +/*[clinic input] +os.rename + + src : path_t + dst : path_t + * + src_dir_fd : dir_fd = None + dst_dir_fd : dir_fd = None + +Rename a file or directory. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +src_dir_fd and dst_dir_fd, may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. +[clinic start generated code]*/ + +static PyObject * +os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd) +/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/ +{ + return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0); +} + + +/*[clinic input] +os.replace = os.rename + +Rename a file or directory, overwriting the destination. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +src_dir_fd and dst_dir_fd, may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. +[clinic start generated code]*/ + +static PyObject * +os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd) +/*[clinic end generated code: output=1968c02e7857422b input=c003f0def43378ef]*/ +{ + return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1); +} + + +/*[clinic input] +os.rmdir + + path: path_t + * + dir_fd: dir_fd(requires='unlinkat') = None + +Remove a directory. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +static PyObject * +os_rmdir_impl(PyObject *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/ +{ + int result; +#ifdef HAVE_UNLINKAT + int unlinkat_unavailable = 0; +#endif + + if (PySys_Audit("os.rmdir", "Oi", path->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; } -exit: - if (buffer) - PyMem_FREE(buffer); - return result; -} -#endif /* USE_XATTRS */ + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + /* Windows, success=1, UNIX, success=0 */ + result = !RemoveDirectoryW(path->wide); +#else +#ifdef HAVE_UNLINKAT + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_UNLINKAT_RUNTIME) { + result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR); + } else { + unlinkat_unavailable = 1; + result = -1; + } + } else +#endif + result = rmdir(path->narrow); +#endif + Py_END_ALLOW_THREADS + +#ifdef HAVE_UNLINKAT + if (unlinkat_unavailable) { + argument_unavailable_error("rmdir", "dir_fd"); + return NULL; + } +#endif -/*[clinic input] -os.urandom + if (result) + return path_error(path); + + Py_RETURN_NONE; +} + + +#ifdef HAVE_SYSTEM +#ifdef MS_WINDOWS +/*[clinic input] +os.system -> long + + command: Py_UNICODE + +Execute the command in a subshell. +[clinic start generated code]*/ + +static long +os_system_impl(PyObject *module, const Py_UNICODE *command) +/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/ +{ + long result; - size: Py_ssize_t - / + if (PySys_Audit("os.system", "(u)", command) < 0) { + return -1; + } -Return a bytes object containing random bytes suitable for cryptographic use. -[clinic start generated code]*/ + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + result = _wsystem(command); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + return result; +} +#else /* MS_WINDOWS */ +/*[clinic input] +os.system -> long + + command: FSConverter + +Execute the command in a subshell. +[clinic start generated code]*/ + +static long +os_system_impl(PyObject *module, PyObject *command) +/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/ +{ + long result; + const char *bytes = PyBytes_AsString(command); -static PyObject * -os_urandom_impl(PyObject *module, Py_ssize_t size) -/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/ -{ - PyObject *bytes; - int result; + if (PySys_Audit("os.system", "(O)", command) < 0) { + return -1; + } - if (size < 0) - return PyErr_Format(PyExc_ValueError, - "negative argument not allowed"); - bytes = PyBytes_FromStringAndSize(NULL, size); - if (bytes == NULL) + Py_BEGIN_ALLOW_THREADS + result = system(bytes); + Py_END_ALLOW_THREADS + return result; +} +#endif +#endif /* HAVE_SYSTEM */ + + +/*[clinic input] +os.umask + + mask: int + / + +Set the current numeric umask and return the previous umask. +[clinic start generated code]*/ + +static PyObject * +os_umask_impl(PyObject *module, int mask) +/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/ +{ + int i = (int)umask(mask); + if (i < 0) + return posix_error(); + return PyLong_FromLong((long)i); +} + +#ifdef MS_WINDOWS + +/* override the default DeleteFileW behavior so that directory +symlinks can be removed with this function, the same as with +Unix symlinks */ +BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) +{ + WIN32_FILE_ATTRIBUTE_DATA info; + WIN32_FIND_DATAW find_data; + HANDLE find_data_handle; + int is_directory = 0; + int is_link = 0; + + if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) { + is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + + /* Get WIN32_FIND_DATA structure for the path to determine if + it is a symlink */ + if(is_directory && + info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + find_data_handle = FindFirstFileW(lpFileName, &find_data); + + if(find_data_handle != INVALID_HANDLE_VALUE) { + /* IO_REPARSE_TAG_SYMLINK if it is a symlink and + IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */ + is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK || + find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT; + FindClose(find_data_handle); + } + } + } + + if (is_directory && is_link) + return RemoveDirectoryW(lpFileName); + + return DeleteFileW(lpFileName); +} +#endif /* MS_WINDOWS */ + + +/*[clinic input] +os.unlink + + path: path_t + * + dir_fd: dir_fd(requires='unlinkat')=None + +Remove a file (same as remove()). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +static PyObject * +os_unlink_impl(PyObject *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/ +{ + int result; +#ifdef HAVE_UNLINKAT + int unlinkat_unavailable = 0; +#endif + + if (PySys_Audit("os.remove", "Oi", path->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { return NULL; + } + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef MS_WINDOWS + /* Windows, success=1, UNIX, success=0 */ + result = !Py_DeleteFileW(path->wide); +#else +#ifdef HAVE_UNLINKAT + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_UNLINKAT_RUNTIME) { - result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); - if (result == -1) { - Py_DECREF(bytes); + result = unlinkat(dir_fd, path->narrow, 0); + } else { + unlinkat_unavailable = 1; + } + } else +#endif /* HAVE_UNLINKAT */ + result = unlink(path->narrow); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + +#ifdef HAVE_UNLINKAT + if (unlinkat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); return NULL; } - return bytes; -} +#endif -#ifdef HAVE_MEMFD_CREATE -/*[clinic input] -os.memfd_create + if (result) + return path_error(path); + + Py_RETURN_NONE; +} + + +/*[clinic input] +os.remove = os.unlink + +Remove a file (same as unlink()). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +static PyObject * +os_remove_impl(PyObject *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/ +{ + return os_unlink_impl(module, path, dir_fd); +} + + +static PyStructSequence_Field uname_result_fields[] = { + {"sysname", "operating system name"}, + {"nodename", "name of machine on network (implementation-defined)"}, + {"release", "operating system release"}, + {"version", "operating system version"}, + {"machine", "hardware identifier"}, + {NULL} +}; + +PyDoc_STRVAR(uname_result__doc__, +"uname_result: Result from os.uname().\n\n\ +This object may be accessed either as a tuple of\n\ + (sysname, nodename, release, version, machine),\n\ +or via the attributes sysname, nodename, release, version, and machine.\n\ +\n\ +See os.uname for more information."); + +static PyStructSequence_Desc uname_result_desc = { + MODNAME ".uname_result", /* name */ + uname_result__doc__, /* doc */ + uname_result_fields, + 5 +}; + +#ifdef HAVE_UNAME +/*[clinic input] +os.uname + +Return an object identifying the current operating system. + +The object behaves like a named tuple with the following fields: + (sysname, nodename, release, version, machine) + +[clinic start generated code]*/ + +static PyObject * +os_uname_impl(PyObject *module) +/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/ +{ + struct utsname u; + int res; + PyObject *value; + + Py_BEGIN_ALLOW_THREADS + res = uname(&u); + Py_END_ALLOW_THREADS + if (res < 0) + return posix_error(); + + PyObject *UnameResultType = get_posix_state(module)->UnameResultType; + value = PyStructSequence_New((PyTypeObject *)UnameResultType); + if (value == NULL) + return NULL; + +#define SET(i, field) \ + { \ + PyObject *o = PyUnicode_DecodeFSDefault(field); \ + if (!o) { \ + Py_DECREF(value); \ + return NULL; \ + } \ + PyStructSequence_SET_ITEM(value, i, o); \ + } \ + + SET(0, u.sysname); + SET(1, u.nodename); + SET(2, u.release); + SET(3, u.version); + SET(4, u.machine); + +#undef SET + + return value; +} +#endif /* HAVE_UNAME */ + + + +typedef struct { + int now; + time_t atime_s; + long atime_ns; + time_t mtime_s; + long mtime_ns; +} utime_t; + +/* + * these macros assume that "ut" is a pointer to a utime_t + * they also intentionally leak the declaration of a pointer named "time" + */ +#define UTIME_TO_TIMESPEC \ + struct timespec ts[2]; \ + struct timespec *time; \ + if (ut->now) \ + time = NULL; \ + else { \ + ts[0].tv_sec = ut->atime_s; \ + ts[0].tv_nsec = ut->atime_ns; \ + ts[1].tv_sec = ut->mtime_s; \ + ts[1].tv_nsec = ut->mtime_ns; \ + time = ts; \ + } \ + +#define UTIME_TO_TIMEVAL \ + struct timeval tv[2]; \ + struct timeval *time; \ + if (ut->now) \ + time = NULL; \ + else { \ + tv[0].tv_sec = ut->atime_s; \ + tv[0].tv_usec = ut->atime_ns / 1000; \ + tv[1].tv_sec = ut->mtime_s; \ + tv[1].tv_usec = ut->mtime_ns / 1000; \ + time = tv; \ + } \ + +#define UTIME_TO_UTIMBUF \ + struct utimbuf u; \ + struct utimbuf *time; \ + if (ut->now) \ + time = NULL; \ + else { \ + u.actime = ut->atime_s; \ + u.modtime = ut->mtime_s; \ + time = &u; \ + } + +#define UTIME_TO_TIME_T \ + time_t timet[2]; \ + time_t *time; \ + if (ut->now) \ + time = NULL; \ + else { \ + timet[0] = ut->atime_s; \ + timet[1] = ut->mtime_s; \ + time = timet; \ + } \ + + +#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) + +static int +utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks) +{ +#if defined(__APPLE__) && defined(HAVE_UTIMENSAT) + if (HAVE_UTIMENSAT_RUNTIME) { + int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; + UTIME_TO_TIMESPEC; + return utimensat(dir_fd, path, time, flags); + } else { + errno = ENOSYS; + return -1; + } +#elif defined(HAVE_UTIMENSAT) + int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; + UTIME_TO_TIMESPEC; + return utimensat(dir_fd, path, time, flags); +#elif defined(HAVE_FUTIMESAT) + UTIME_TO_TIMEVAL; + /* + * follow_symlinks will never be false here; + * we only allow !follow_symlinks and dir_fd together + * if we have utimensat() + */ + assert(follow_symlinks); + return futimesat(dir_fd, path, time); +#endif +} + + #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) + +static int +utime_fd(utime_t *ut, int fd) +{ +#ifdef HAVE_FUTIMENS - name: FSConverter - flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC + if (HAVE_FUTIMENS_RUNTIME) { -[clinic start generated code]*/ + UTIME_TO_TIMESPEC; + return futimens(fd, time); -static PyObject * -os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) -/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/ -{ - int fd; - const char *bytes = PyBytes_AS_STRING(name); - Py_BEGIN_ALLOW_THREADS - fd = memfd_create(bytes, flags); - Py_END_ALLOW_THREADS - if (fd == -1) { - return PyErr_SetFromErrno(PyExc_OSError); + } else +#ifndef HAVE_FUTIMES + { + /* Not sure if this can happen */ + PyErr_SetString( + PyExc_RuntimeError, + "neither futimens nor futimes are supported" + " on this system"); + return -1; } - return PyLong_FromLong(fd); -} #endif -/* Terminal size querying */ - -PyDoc_STRVAR(TerminalSize_docstring, - "A tuple of (columns, lines) for holding terminal window size"); - -static PyStructSequence_Field TerminalSize_fields[] = { - {"columns", "width of the terminal window in characters"}, - {"lines", "height of the terminal window in characters"}, - {NULL, NULL} -}; +#endif +#ifdef HAVE_FUTIMES + { + UTIME_TO_TIMEVAL; + return futimes(fd, time); + } +#endif +} + + #define PATH_UTIME_HAVE_FD 1 +#else + #define PATH_UTIME_HAVE_FD 0 +#endif + +#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES) +# define UTIME_HAVE_NOFOLLOW_SYMLINKS +#endif + +#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS + +static int +utime_nofollow_symlinks(utime_t *ut, const char *path) +{ +#ifdef HAVE_UTIMENSAT + if (HAVE_UTIMENSAT_RUNTIME) { + UTIME_TO_TIMESPEC; + return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW); + } else +#ifndef HAVE_LUTIMES + { + /* Not sure if this can happen */ + PyErr_SetString( + PyExc_RuntimeError, + "neither utimensat nor lutimes are supported" + " on this system"); + return -1; + } +#endif +#endif -static PyStructSequence_Desc TerminalSize_desc = { - "os.terminal_size", - TerminalSize_docstring, - TerminalSize_fields, - 2, -}; +#ifdef HAVE_LUTIMES + { + UTIME_TO_TIMEVAL; + return lutimes(path, time); + } +#endif +} + +#endif + +#ifndef MS_WINDOWS + +static int +utime_default(utime_t *ut, const char *path) +{ +#if defined(__APPLE__) && defined(HAVE_UTIMENSAT) + if (HAVE_UTIMENSAT_RUNTIME) { + UTIME_TO_TIMESPEC; + return utimensat(DEFAULT_DIR_FD, path, time, 0); + } else { + UTIME_TO_TIMEVAL; + return utimes(path, time); + } +#elif defined(HAVE_UTIMENSAT) + UTIME_TO_TIMESPEC; + return utimensat(DEFAULT_DIR_FD, path, time, 0); +#elif defined(HAVE_UTIMES) + UTIME_TO_TIMEVAL; + return utimes(path, time); +#elif defined(HAVE_UTIME_H) + UTIME_TO_UTIMBUF; + return utime(path, time); +#else + UTIME_TO_TIME_T; + return utime(path, time); +#endif +} + +#endif + +static int +split_py_long_to_s_and_ns(PyObject *module, PyObject *py_long, time_t *s, long *ns) +{ + int result = 0; + PyObject *divmod; + divmod = PyNumber_Divmod(py_long, get_posix_state(module)->billion); + if (!divmod) + goto exit; + if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) { + PyErr_Format(PyExc_TypeError, + "%.200s.__divmod__() must return a 2-tuple, not %.200s", + _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod))); + goto exit; + } + *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0)); + if ((*s == -1) && PyErr_Occurred()) + goto exit; + *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1)); + if ((*ns == -1) && PyErr_Occurred()) + goto exit; + + result = 1; +exit: + Py_XDECREF(divmod); + return result; +} + + +/*[clinic input] +os.utime + + path: path_t(allow_fd='PATH_UTIME_HAVE_FD') + times: object = None + * + ns: object = NULL + dir_fd: dir_fd(requires='futimensat') = None + follow_symlinks: bool=True + +# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\ + +Set the access and modified time of path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. + +If times is not None, it must be a tuple (atime, mtime); + atime and mtime should be expressed as float seconds since the epoch. +If ns is specified, it must be a tuple (atime_ns, mtime_ns); + atime_ns and mtime_ns should be expressed as integer nanoseconds + since the epoch. +If times is None and ns is unspecified, utime uses the current time. +Specifying tuples for both times and ns is an error. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, utime will modify the symbolic link itself instead of the file the + link points to. +It is an error to use dir_fd or follow_symlinks when specifying path + as an open file descriptor. +dir_fd and follow_symlinks may not be available on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +static PyObject * +os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, + int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/ +{ +#ifdef MS_WINDOWS + HANDLE hFile; + FILETIME atime, mtime; +#else + int result; +#endif + + utime_t utime; + + memset(&utime, 0, sizeof(utime_t)); + + if (times != Py_None && ns) { + PyErr_SetString(PyExc_ValueError, + "utime: you may specify either 'times'" + " or 'ns' but not both"); + return NULL; + } + + if (times != Py_None) { + time_t a_sec, m_sec; + long a_nsec, m_nsec; + if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) { + PyErr_SetString(PyExc_TypeError, + "utime: 'times' must be either" + " a tuple of two ints or None"); + return NULL; + } + utime.now = 0; + if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), + &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 || + _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), + &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) { + return NULL; + } + utime.atime_s = a_sec; + utime.atime_ns = a_nsec; + utime.mtime_s = m_sec; + utime.mtime_ns = m_nsec; + } + else if (ns) { + if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) { + PyErr_SetString(PyExc_TypeError, + "utime: 'ns' must be a tuple of two ints"); + return NULL; + } + utime.now = 0; + if (!split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 0), + &utime.atime_s, &utime.atime_ns) || + !split_py_long_to_s_and_ns(module, PyTuple_GET_ITEM(ns, 1), + &utime.mtime_s, &utime.mtime_ns)) { + return NULL; + } + } + else { + /* times and ns are both None/unspecified. use "now". */ + utime.now = 1; + } + +#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS) + if (follow_symlinks_specified("utime", follow_symlinks)) + return NULL; +#endif + + if (path_and_dir_fd_invalid("utime", path, dir_fd) || + dir_fd_and_fd_invalid("utime", dir_fd, path->fd) || + fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks)) + return NULL; + +#if !defined(HAVE_UTIMENSAT) + if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { + PyErr_SetString(PyExc_ValueError, + "utime: cannot use dir_fd and follow_symlinks " + "together on this platform"); + return NULL; + } +#endif + + if (PySys_Audit("os.utime", "OOOi", path->object, times, ns ? ns : Py_None, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } -#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) -/*[clinic input] -os.get_terminal_size +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, + NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL); + Py_END_ALLOW_THREADS + if (hFile == INVALID_HANDLE_VALUE) { + path_error(path); + return NULL; + } + + if (utime.now) { + GetSystemTimeAsFileTime(&mtime); + atime = mtime; + } + else { + _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime); + _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime); + } + if (!SetFileTime(hFile, NULL, &atime, &mtime)) { + /* Avoid putting the file name into the error here, + as that may confuse the user into believing that + something is wrong with the file, when it also + could be the time stamp that gives a problem. */ + PyErr_SetFromWindowsErr(0); + CloseHandle(hFile); + return NULL; + } + CloseHandle(hFile); +#else /* MS_WINDOWS */ + Py_BEGIN_ALLOW_THREADS + +#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS + if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) + result = utime_nofollow_symlinks(&utime, path->narrow); + else +#endif + +#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) + if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) { + result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks); - fd: int(c_default="fileno(stdout)", py_default="") = -1 - / + } else +#endif + +#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) + if (path->fd != -1) + result = utime_fd(&utime, path->fd); + else +#endif + + result = utime_default(&utime, path->narrow); + + Py_END_ALLOW_THREADS + +#if defined(__APPLE__) && defined(HAVE_UTIMENSAT) + /* See utime_dir_fd implementation */ + if (result == -1 && errno == ENOSYS) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif -Return the size of the terminal window as (columns, lines). + if (result < 0) { + /* see previous comment about not putting filename in error here */ + posix_error(); + return NULL; + } + +#endif /* MS_WINDOWS */ + + Py_RETURN_NONE; +} + +/* Process operations */ + + +/*[clinic input] +os._exit + + status: int + +Exit to the system with specified status, without normal exit processing. +[clinic start generated code]*/ + +static PyObject * +os__exit_impl(PyObject *module, int status) +/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/ +{ + _exit(status); + return NULL; /* Make gcc -Wall happy */ +} + +#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) +#define EXECV_CHAR wchar_t +#else +#define EXECV_CHAR char +#endif + +#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN) +static void +free_string_array(EXECV_CHAR **array, Py_ssize_t count) +{ + Py_ssize_t i; + for (i = 0; i < count; i++) + PyMem_Free(array[i]); + PyMem_DEL(array); +} + +static int +fsconvert_strdup(PyObject *o, EXECV_CHAR **out) +{ + Py_ssize_t size; + PyObject *ub; + int result = 0; +#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) + if (!PyUnicode_FSDecoder(o, &ub)) + return 0; + *out = PyUnicode_AsWideCharString(ub, &size); + if (*out) + result = 1; +#else + if (!PyUnicode_FSConverter(o, &ub)) + return 0; + size = PyBytes_GET_SIZE(ub); + *out = PyMem_Malloc(size + 1); + if (*out) { + memcpy(*out, PyBytes_AS_STRING(ub), size + 1); + result = 1; + } else + PyErr_NoMemory(); +#endif + Py_DECREF(ub); + return result; +} +#endif + +#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN) +static EXECV_CHAR** +parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) +{ + Py_ssize_t i, pos, envc; + PyObject *keys=NULL, *vals=NULL; + PyObject *key, *val, *key2, *val2, *keyval; + EXECV_CHAR **envlist; + + i = PyMapping_Size(env); + if (i < 0) + return NULL; + envlist = PyMem_NEW(EXECV_CHAR *, i + 1); + if (envlist == NULL) { + PyErr_NoMemory(); + return NULL; + } + envc = 0; + keys = PyMapping_Keys(env); + if (!keys) + goto error; + vals = PyMapping_Values(env); + if (!vals) + goto error; + if (!PyList_Check(keys) || !PyList_Check(vals)) { + PyErr_Format(PyExc_TypeError, + "env.keys() or env.values() is not a list"); + goto error; + } + + for (pos = 0; pos < i; pos++) { + key = PyList_GetItem(keys, pos); + val = PyList_GetItem(vals, pos); + if (!key || !val) + goto error; + +#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) + if (!PyUnicode_FSDecoder(key, &key2)) + goto error; + if (!PyUnicode_FSDecoder(val, &val2)) { + Py_DECREF(key2); + goto error; + } + /* Search from index 1 because on Windows starting '=' is allowed for + defining hidden environment variables. */ + if (PyUnicode_GET_LENGTH(key2) == 0 || + PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1) + { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + Py_DECREF(key2); + Py_DECREF(val2); + goto error; + } + keyval = PyUnicode_FromFormat("%U=%U", key2, val2); +#else + if (!PyUnicode_FSConverter(key, &key2)) + goto error; + if (!PyUnicode_FSConverter(val, &val2)) { + Py_DECREF(key2); + goto error; + } + if (PyBytes_GET_SIZE(key2) == 0 || + strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL) + { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + Py_DECREF(key2); + Py_DECREF(val2); + goto error; + } + keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2), + PyBytes_AS_STRING(val2)); +#endif + Py_DECREF(key2); + Py_DECREF(val2); + if (!keyval) + goto error; + + if (!fsconvert_strdup(keyval, &envlist[envc++])) { + Py_DECREF(keyval); + goto error; + } + + Py_DECREF(keyval); + } + Py_DECREF(vals); + Py_DECREF(keys); + + envlist[envc] = 0; + *envc_ptr = envc; + return envlist; + +error: + Py_XDECREF(keys); + Py_XDECREF(vals); + free_string_array(envlist, envc); + return NULL; +} + +static EXECV_CHAR** +parse_arglist(PyObject* argv, Py_ssize_t *argc) +{ + int i; + EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1); + if (argvlist == NULL) { + PyErr_NoMemory(); + return NULL; + } + for (i = 0; i < *argc; i++) { + PyObject* item = PySequence_ITEM(argv, i); + if (item == NULL) + goto fail; + if (!fsconvert_strdup(item, &argvlist[i])) { + Py_DECREF(item); + goto fail; + } + Py_DECREF(item); + } + argvlist[*argc] = NULL; + return argvlist; +fail: + *argc = i; + free_string_array(argvlist, *argc); + return NULL; +} + +#endif + + +#ifdef HAVE_EXECV +/*[clinic input] +os.execv + + path: path_t + Path of executable file. + argv: object + Tuple or list of strings. + / + +Execute an executable path with arguments, replacing current process. +[clinic start generated code]*/ + +static PyObject * +os_execv_impl(PyObject *module, path_t *path, PyObject *argv) +/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/ +{ + EXECV_CHAR **argvlist; + Py_ssize_t argc; + + /* execv has two arguments: (path, argv), where + argv is a list or tuple of strings. */ + + if (!PyList_Check(argv) && !PyTuple_Check(argv)) { + PyErr_SetString(PyExc_TypeError, + "execv() arg 2 must be a tuple or list"); + return NULL; + } + argc = PySequence_Size(argv); + if (argc < 1) { + PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); + return NULL; + } + + argvlist = parse_arglist(argv, &argc); + if (argvlist == NULL) { + return NULL; + } + if (!argvlist[0][0]) { + PyErr_SetString(PyExc_ValueError, + "execv() arg 2 first element cannot be empty"); + free_string_array(argvlist, argc); + return NULL; + } + + if (PySys_Audit("os.exec", "OOO", path->object, argv, Py_None) < 0) { + free_string_array(argvlist, argc); + return NULL; + } -The optional argument fd (default standard output) specifies -which file descriptor should be queried. + _Py_BEGIN_SUPPRESS_IPH +#ifdef HAVE_WEXECV + _wexecv(path->wide, argvlist); +#else + execv(path->narrow, argvlist); +#endif + _Py_END_SUPPRESS_IPH + + /* If we get here it's definitely an error */ + + free_string_array(argvlist, argc); + return posix_error(); +} + + +/*[clinic input] +os.execve + + path: path_t(allow_fd='PATH_HAVE_FEXECVE') + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. + +Execute an executable path with arguments, replacing current process. +[clinic start generated code]*/ + +static PyObject * +os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) +/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/ +{ + EXECV_CHAR **argvlist = NULL; + EXECV_CHAR **envlist; + Py_ssize_t argc, envc; + + /* execve has three arguments: (path, argv, env), where + argv is a list or tuple of strings and env is a dictionary + like posix.environ. */ + + if (!PyList_Check(argv) && !PyTuple_Check(argv)) { + PyErr_SetString(PyExc_TypeError, + "execve: argv must be a tuple or list"); + goto fail_0; + } + argc = PySequence_Size(argv); + if (argc < 1) { + PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty"); + return NULL; + } + + if (!PyMapping_Check(env)) { + PyErr_SetString(PyExc_TypeError, + "execve: environment must be a mapping object"); + goto fail_0; + } + + argvlist = parse_arglist(argv, &argc); + if (argvlist == NULL) { + goto fail_0; + } + if (!argvlist[0][0]) { + PyErr_SetString(PyExc_ValueError, + "execve: argv first element cannot be empty"); + goto fail_0; + } + + envlist = parse_envlist(env, &envc); + if (envlist == NULL) + goto fail_0; + + if (PySys_Audit("os.exec", "OOO", path->object, argv, env) < 0) { + goto fail_1; + } -If the file descriptor is not connected to a terminal, an OSError -is thrown. + _Py_BEGIN_SUPPRESS_IPH +#ifdef HAVE_FEXECVE + if (path->fd > -1) + fexecve(path->fd, argvlist, envlist); + else +#endif +#ifdef HAVE_WEXECV + _wexecve(path->wide, argvlist, envlist); +#else + execve(path->narrow, argvlist, envlist); +#endif + _Py_END_SUPPRESS_IPH + + /* If we get here it's definitely an error */ + + posix_path_error(path); + fail_1: + free_string_array(envlist, envc); + fail_0: + if (argvlist) + free_string_array(argvlist, argc); + return NULL; +} + +#endif /* HAVE_EXECV */ + +#ifdef HAVE_POSIX_SPAWN -This function will only be defined if an implementation is -available for this system. +enum posix_spawn_file_actions_identifier { + POSIX_SPAWN_OPEN, + POSIX_SPAWN_CLOSE, + POSIX_SPAWN_DUP2 +}; -shutil.get_terminal_size is the high-level function which should -normally be used, os.get_terminal_size is the low-level implementation. -[clinic start generated code]*/ +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) +static int +convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res); +#endif -static PyObject * -os_get_terminal_size_impl(PyObject *module, int fd) -/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/ +static int +parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpgroup, + int resetids, int setsid, PyObject *setsigmask, + PyObject *setsigdef, PyObject *scheduler, + posix_spawnattr_t *attrp) { - int columns, lines; - PyObject *termsize; - - /* Under some conditions stdout may not be connected and - * fileno(stdout) may point to an invalid file descriptor. For example - * GUI apps don't have valid standard streams by default. - * - * If this happens, and the optional fd argument is not present, - * the ioctl below will fail returning EBADF. This is what we want. - */ + long all_flags = 0; -#ifdef TERMSIZE_USE_IOCTL - { - struct winsize w; - if (ioctl(fd, TIOCGWINSZ, &w)) - return PyErr_SetFromErrno(PyExc_OSError); - columns = w.ws_col; - lines = w.ws_row; + errno = posix_spawnattr_init(attrp); + if (errno) { + posix_error(); + return -1; } -#endif /* TERMSIZE_USE_IOCTL */ -#ifdef TERMSIZE_USE_CONIO - { - DWORD nhandle; - HANDLE handle; - CONSOLE_SCREEN_BUFFER_INFO csbi; - switch (fd) { - case 0: nhandle = STD_INPUT_HANDLE; - break; - case 1: nhandle = STD_OUTPUT_HANDLE; - break; - case 2: nhandle = STD_ERROR_HANDLE; - break; - default: - return PyErr_Format(PyExc_ValueError, "bad file descriptor"); + if (setpgroup) { + pid_t pgid = PyLong_AsPid(setpgroup); + if (pgid == (pid_t)-1 && PyErr_Occurred()) { + goto fail; } - handle = GetStdHandle(nhandle); - if (handle == NULL) - return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); - if (handle == INVALID_HANDLE_VALUE) - return PyErr_SetFromWindowsErr(0); - - if (!GetConsoleScreenBufferInfo(handle, &csbi)) - return PyErr_SetFromWindowsErr(0); - - columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; - lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + errno = posix_spawnattr_setpgroup(attrp, pgid); + if (errno) { + posix_error(); + goto fail; + } + all_flags |= POSIX_SPAWN_SETPGROUP; } -#endif /* TERMSIZE_USE_CONIO */ - PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType; - termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType); - if (termsize == NULL) - return NULL; - PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns)); - PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines)); - if (PyErr_Occurred()) { - Py_DECREF(termsize); - return NULL; + if (resetids) { + all_flags |= POSIX_SPAWN_RESETIDS; } - return termsize; -} -#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ - - -/*[clinic input] -os.cpu_count - -Return the number of CPUs in the system; return None if indeterminable. - -This number is not equivalent to the number of CPUs the current process can -use. The number of usable CPUs can be obtained with -``len(os.sched_getaffinity(0))`` -[clinic start generated code]*/ -static PyObject * -os_cpu_count_impl(PyObject *module) -/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/ -{ - int ncpu = 0; -#ifdef MS_WINDOWS - ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS); -#elif defined(__hpux) - ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); -#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) - ncpu = sysconf(_SC_NPROCESSORS_ONLN); -#elif defined(__DragonFly__) || \ - defined(__OpenBSD__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__APPLE__) - int mib[2]; - size_t len = sizeof(ncpu); - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) - ncpu = 0; -#endif - if (ncpu >= 1) - return PyLong_FromLong(ncpu); - else - Py_RETURN_NONE; -} + if (setsid) { +#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME + if (HAVE_POSIX_SPAWN_SETSID_RUNTIME) { +#endif +#ifdef POSIX_SPAWN_SETSID + all_flags |= POSIX_SPAWN_SETSID; +#elif defined(POSIX_SPAWN_SETSID_NP) + all_flags |= POSIX_SPAWN_SETSID_NP; +#else + argument_unavailable_error(func_name, "setsid"); + return -1; +#endif +#ifdef HAVE_POSIX_SPAWN_SETSID_RUNTIME + } else { + argument_unavailable_error(func_name, "setsid"); + return -1; + } +#endif /* HAVE_POSIX_SPAWN_SETSID_RUNTIME */ -/*[clinic input] -os.get_inheritable -> bool + } - fd: int - / +#ifdef HAVE_SIGSET_T + if (setsigmask) { + sigset_t set; + if (!_Py_Sigset_Converter(setsigmask, &set)) { + goto fail; + } + errno = posix_spawnattr_setsigmask(attrp, &set); + if (errno) { + posix_error(); + goto fail; + } + all_flags |= POSIX_SPAWN_SETSIGMASK; + } -Get the close-on-exe flag of the specified file descriptor. -[clinic start generated code]*/ + if (setsigdef) { + sigset_t set; + if (!_Py_Sigset_Converter(setsigdef, &set)) { + goto fail; + } + errno = posix_spawnattr_setsigdefault(attrp, &set); + if (errno) { + posix_error(); + goto fail; + } + all_flags |= POSIX_SPAWN_SETSIGDEF; + } +#else + if (setsigmask || setsigdef) { + PyErr_SetString(PyExc_NotImplementedError, + "sigset is not supported on this platform"); + goto fail; + } +#endif -static int -os_get_inheritable_impl(PyObject *module, int fd) -/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/ -{ - int return_value; - _Py_BEGIN_SUPPRESS_IPH - return_value = _Py_get_inheritable(fd); - _Py_END_SUPPRESS_IPH - return return_value; -} + if (scheduler) { +#ifdef POSIX_SPAWN_SETSCHEDULER + PyObject *py_schedpolicy; + PyObject *schedparam_obj; + struct sched_param schedparam; + if (!PyArg_ParseTuple(scheduler, "OO" + ";A scheduler tuple must have two elements", + &py_schedpolicy, &schedparam_obj)) { + goto fail; + } + if (!convert_sched_param(module, schedparam_obj, &schedparam)) { + goto fail; + } + if (py_schedpolicy != Py_None) { + int schedpolicy = _PyLong_AsInt(py_schedpolicy); -/*[clinic input] -os.set_inheritable - fd: int - inheritable: int - / + if (schedpolicy == -1 && PyErr_Occurred()) { + goto fail; + } + errno = posix_spawnattr_setschedpolicy(attrp, schedpolicy); + if (errno) { + posix_error(); + goto fail; + } + all_flags |= POSIX_SPAWN_SETSCHEDULER; + } + errno = posix_spawnattr_setschedparam(attrp, &schedparam); + if (errno) { + posix_error(); + goto fail; + } + all_flags |= POSIX_SPAWN_SETSCHEDPARAM; +#else + PyErr_SetString(PyExc_NotImplementedError, + "The scheduler option is not supported in this system."); + goto fail; +#endif + } -Set the inheritable flag of the specified file descriptor. -[clinic start generated code]*/ + errno = posix_spawnattr_setflags(attrp, all_flags); + if (errno) { + posix_error(); + goto fail; + } -static PyObject * -os_set_inheritable_impl(PyObject *module, int fd, int inheritable) -/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/ -{ - int result; + return 0; - _Py_BEGIN_SUPPRESS_IPH - result = _Py_set_inheritable(fd, inheritable, NULL); - _Py_END_SUPPRESS_IPH - if (result < 0) - return NULL; - Py_RETURN_NONE; +fail: + (void)posix_spawnattr_destroy(attrp); + return -1; } - -#ifdef MS_WINDOWS -/*[clinic input] -os.get_handle_inheritable -> bool - handle: intptr_t - / - -Get the close-on-exe flag of the specified file descriptor. -[clinic start generated code]*/ - static int -os_get_handle_inheritable_impl(PyObject *module, intptr_t handle) -/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/ +parse_file_actions(PyObject *file_actions, + posix_spawn_file_actions_t *file_actionsp, + PyObject *temp_buffer) { - DWORD flags; + PyObject *seq; + PyObject *file_action = NULL; + PyObject *tag_obj; + + seq = PySequence_Fast(file_actions, + "file_actions must be a sequence or None"); + if (seq == NULL) { + return -1; + } - if (!GetHandleInformation((HANDLE)handle, &flags)) { - PyErr_SetFromWindowsErr(0); + errno = posix_spawn_file_actions_init(file_actionsp); + if (errno) { + posix_error(); + Py_DECREF(seq); return -1; } - return flags & HANDLE_FLAG_INHERIT; -} - + for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { + file_action = PySequence_Fast_GET_ITEM(seq, i); + Py_INCREF(file_action); + if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) { + PyErr_SetString(PyExc_TypeError, + "Each file_actions element must be a non-empty tuple"); + goto fail; + } + long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0)); + if (tag == -1 && PyErr_Occurred()) { + goto fail; + } + + /* Populate the file_actions object */ + switch (tag) { + case POSIX_SPAWN_OPEN: { + int fd, oflag; + PyObject *path; + unsigned long mode; + if (!PyArg_ParseTuple(file_action, "OiO&ik" + ";A open file_action tuple must have 5 elements", + &tag_obj, &fd, PyUnicode_FSConverter, &path, + &oflag, &mode)) + { + goto fail; + } + if (PyList_Append(temp_buffer, path)) { + Py_DECREF(path); + goto fail; + } + errno = posix_spawn_file_actions_addopen(file_actionsp, + fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); + Py_DECREF(path); + if (errno) { + posix_error(); + goto fail; + } + break; + } + case POSIX_SPAWN_CLOSE: { + int fd; + if (!PyArg_ParseTuple(file_action, "Oi" + ";A close file_action tuple must have 2 elements", + &tag_obj, &fd)) + { + goto fail; + } + errno = posix_spawn_file_actions_addclose(file_actionsp, fd); + if (errno) { + posix_error(); + goto fail; + } + break; + } + case POSIX_SPAWN_DUP2: { + int fd1, fd2; + if (!PyArg_ParseTuple(file_action, "Oii" + ";A dup2 file_action tuple must have 3 elements", + &tag_obj, &fd1, &fd2)) + { + goto fail; + } + errno = posix_spawn_file_actions_adddup2(file_actionsp, + fd1, fd2); + if (errno) { + posix_error(); + goto fail; + } + break; + } + default: { + PyErr_SetString(PyExc_TypeError, + "Unknown file_actions identifier"); + goto fail; + } + } + Py_DECREF(file_action); + } + + Py_DECREF(seq); + return 0; -/*[clinic input] -os.set_handle_inheritable - handle: intptr_t - inheritable: bool - / +fail: + Py_DECREF(seq); + Py_DECREF(file_action); + (void)posix_spawn_file_actions_destroy(file_actionsp); + return -1; +} -Set the inheritable flag of the specified handle. -[clinic start generated code]*/ static PyObject * -os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, - int inheritable) -/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/ +py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *argv, + PyObject *env, PyObject *file_actions, + PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask, + PyObject *setsigdef, PyObject *scheduler) { - DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0; - if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { - PyErr_SetFromWindowsErr(0); - return NULL; - } - Py_RETURN_NONE; -} -#endif /* MS_WINDOWS */ - -#ifndef MS_WINDOWS -/*[clinic input] -os.get_blocking -> bool - fd: int - / + const char *func_name = use_posix_spawnp ? "posix_spawnp" : "posix_spawn"; + EXECV_CHAR **argvlist = NULL; + EXECV_CHAR **envlist = NULL; + posix_spawn_file_actions_t file_actions_buf; + posix_spawn_file_actions_t *file_actionsp = NULL; + posix_spawnattr_t attr; + posix_spawnattr_t *attrp = NULL; + Py_ssize_t argc, envc; + PyObject *result = NULL; + PyObject *temp_buffer = NULL; + pid_t pid; + int err_code; -Get the blocking mode of the file descriptor. + /* posix_spawn and posix_spawnp have three arguments: (path, argv, env), where + argv is a list or tuple of strings and env is a dictionary + like posix.environ. */ -Return False if the O_NONBLOCK flag is set, True if the flag is cleared. -[clinic start generated code]*/ + if (!PyList_Check(argv) && !PyTuple_Check(argv)) { + PyErr_Format(PyExc_TypeError, + "%s: argv must be a tuple or list", func_name); + goto exit; + } + argc = PySequence_Size(argv); + if (argc < 1) { + PyErr_Format(PyExc_ValueError, + "%s: argv must not be empty", func_name); + return NULL; + } -static int -os_get_blocking_impl(PyObject *module, int fd) -/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/ -{ - int blocking; + if (!PyMapping_Check(env)) { + PyErr_Format(PyExc_TypeError, + "%s: environment must be a mapping object", func_name); + goto exit; + } - _Py_BEGIN_SUPPRESS_IPH - blocking = _Py_get_blocking(fd); - _Py_END_SUPPRESS_IPH - return blocking; -} + argvlist = parse_arglist(argv, &argc); + if (argvlist == NULL) { + goto exit; + } + if (!argvlist[0][0]) { + PyErr_Format(PyExc_ValueError, + "%s: argv first element cannot be empty", func_name); + goto exit; + } -/*[clinic input] -os.set_blocking - fd: int - blocking: bool(accept={int}) - / + envlist = parse_envlist(env, &envc); + if (envlist == NULL) { + goto exit; + } -Set the blocking mode of the specified file descriptor. + if (file_actions != NULL && file_actions != Py_None) { + /* There is a bug in old versions of glibc that makes some of the + * helper functions for manipulating file actions not copy the provided + * buffers. The problem is that posix_spawn_file_actions_addopen does not + * copy the value of path for some old versions of glibc (<2.20). + * The use of temp_buffer here is a workaround that keeps the + * python objects that own the buffers alive until posix_spawn gets called. + * Check https://bugs.python.org/issue33630 and + * https://sourceware.org/bugzilla/show_bug.cgi?id=17048 for more info.*/ + temp_buffer = PyList_New(0); + if (!temp_buffer) { + goto exit; + } + if (parse_file_actions(file_actions, &file_actions_buf, temp_buffer)) { + goto exit; + } + file_actionsp = &file_actions_buf; + } -Set the O_NONBLOCK flag if blocking is False, -clear the O_NONBLOCK flag otherwise. -[clinic start generated code]*/ + if (parse_posix_spawn_flags(module, func_name, setpgroup, resetids, setsid, + setsigmask, setsigdef, scheduler, &attr)) { + goto exit; + } + attrp = &attr; -static PyObject * -os_set_blocking_impl(PyObject *module, int fd, int blocking) -/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/ -{ - int result; + if (PySys_Audit("os.posix_spawn", "OOO", path->object, argv, env) < 0) { + goto exit; + } _Py_BEGIN_SUPPRESS_IPH - result = _Py_set_blocking(fd, blocking); +#ifdef HAVE_POSIX_SPAWNP + if (use_posix_spawnp) { + err_code = posix_spawnp(&pid, path->narrow, + file_actionsp, attrp, argvlist, envlist); + } + else +#endif /* HAVE_POSIX_SPAWNP */ + { + err_code = posix_spawn(&pid, path->narrow, + file_actionsp, attrp, argvlist, envlist); + } _Py_END_SUPPRESS_IPH - if (result < 0) - return NULL; - Py_RETURN_NONE; -} -#endif /* !MS_WINDOWS */ - - -/*[clinic input] -class os.DirEntry "DirEntry *" "DirEntryType" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/ -typedef struct { - PyObject_HEAD - PyObject *name; - PyObject *path; - PyObject *stat; - PyObject *lstat; -#ifdef MS_WINDOWS - struct _Py_stat_struct win32_lstat; - uint64_t win32_file_index; - int got_file_index; -#else /* POSIX */ -#ifdef HAVE_DIRENT_D_TYPE - unsigned char d_type; -#endif - ino_t d_ino; - int dir_fd; + if (err_code) { + errno = err_code; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); + goto exit; + } +#ifdef _Py_MEMORY_SANITIZER + __msan_unpoison(&pid, sizeof(pid)); #endif -} DirEntry; + result = PyLong_FromPid(pid); -static PyObject * -_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyErr_Format(PyExc_TypeError, - "cannot create '%.100s' instances", _PyType_Name(type)); - return NULL; +exit: + if (file_actionsp) { + (void)posix_spawn_file_actions_destroy(file_actionsp); + } + if (attrp) { + (void)posix_spawnattr_destroy(attrp); + } + if (envlist) { + free_string_array(envlist, envc); + } + if (argvlist) { + free_string_array(argvlist, argc); + } + Py_XDECREF(temp_buffer); + return result; } -static void -DirEntry_dealloc(DirEntry *entry) -{ - PyTypeObject *tp = Py_TYPE(entry); - Py_XDECREF(entry->name); - Py_XDECREF(entry->path); - Py_XDECREF(entry->stat); - Py_XDECREF(entry->lstat); - freefunc free_func = PyType_GetSlot(tp, Py_tp_free); - free_func(entry); - Py_DECREF(tp); -} -/* Forward reference */ -static int -DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self, - int follow_symlinks, unsigned short mode_bits); +/*[clinic input] -/*[clinic input] -os.DirEntry.is_symlink -> bool - defining_class: defining_class +os.posix_spawn + path: path_t + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. / + * + file_actions: object(c_default='NULL') = () + A sequence of file action tuples. + setpgroup: object = NULL + The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. + resetids: bool(accept={int}) = False + If the value is `true` the POSIX_SPAWN_RESETIDS will be activated. + setsid: bool(accept={int}) = False + If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated. + setsigmask: object(c_default='NULL') = () + The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. + setsigdef: object(c_default='NULL') = () + The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag. + scheduler: object = NULL + A tuple with the scheduler policy (optional) and parameters. -Return True if the entry is a symbolic link; cached per entry. -[clinic start generated code]*/ - -static int -os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class) -/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/ -{ -#ifdef MS_WINDOWS - return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK; -#elif defined(HAVE_DIRENT_D_TYPE) - /* POSIX */ - if (self->d_type != DT_UNKNOWN) - return self->d_type == DT_LNK; - else - return DirEntry_test_mode(defining_class, self, 0, S_IFLNK); -#else - /* POSIX without d_type */ - return DirEntry_test_mode(defining_class, self, 0, S_IFLNK); -#endif -} - -static PyObject * -DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) -{ - int result; - STRUCT_STAT st; - PyObject *ub; - -#ifdef MS_WINDOWS - if (!PyUnicode_FSDecoder(self->path, &ub)) - return NULL; -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - const wchar_t *path = PyUnicode_AsUnicode(ub); -_Py_COMP_DIAG_POP -#else /* POSIX */ - if (!PyUnicode_FSConverter(self->path, &ub)) - return NULL; - const char *path = PyBytes_AS_STRING(ub); - if (self->dir_fd != DEFAULT_DIR_FD) { -#ifdef HAVE_FSTATAT - if (HAVE_FSTATAT_RUNTIME) { - result = fstatat(self->dir_fd, path, &st, - follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); - } else - -#endif /* HAVE_FSTATAT */ - { - Py_DECREF(ub); - PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat"); - return NULL; - } - } - else -#endif - { - if (follow_symlinks) - result = STAT(path, &st); - else - result = LSTAT(path, &st); - } - Py_DECREF(ub); - - if (result != 0) - return path_object_error(self->path); - - return _pystat_fromstructstat(module, &st); -} +Execute the program specified by path in a new process. +[clinic start generated code]*/ static PyObject * -DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self) +os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, + PyObject *env, PyObject *file_actions, + PyObject *setpgroup, int resetids, int setsid, + PyObject *setsigmask, PyObject *setsigdef, + PyObject *scheduler) +/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/ { - if (!self->lstat) { - PyObject *module = PyType_GetModule(defining_class); -#ifdef MS_WINDOWS - self->lstat = _pystat_fromstructstat(module, &self->win32_lstat); -#else /* POSIX */ - self->lstat = DirEntry_fetch_stat(module, self, 0); -#endif - } - Py_XINCREF(self->lstat); - return self->lstat; + return py_posix_spawn(0, module, path, argv, env, file_actions, + setpgroup, resetids, setsid, setsigmask, setsigdef, + scheduler); } + #endif /* HAVE_POSIX_SPAWN */ + + +#ifdef HAVE_POSIX_SPAWNP /*[clinic input] -os.DirEntry.stat - defining_class: defining_class + +os.posix_spawnp + path: path_t + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. / * - follow_symlinks: bool = True + file_actions: object(c_default='NULL') = () + A sequence of file action tuples. + setpgroup: object = NULL + The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. + resetids: bool(accept={int}) = False + If the value is `True` the POSIX_SPAWN_RESETIDS will be activated. + setsid: bool(accept={int}) = False + If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated. + setsigmask: object(c_default='NULL') = () + The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. + setsigdef: object(c_default='NULL') = () + The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag. + scheduler: object = NULL + A tuple with the scheduler policy (optional) and parameters. -Return stat_result object for the entry; cached per entry. +Execute the program specified by path in a new process. [clinic start generated code]*/ static PyObject * -os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class, - int follow_symlinks) -/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/ +os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv, + PyObject *env, PyObject *file_actions, + PyObject *setpgroup, int resetids, int setsid, + PyObject *setsigmask, PyObject *setsigdef, + PyObject *scheduler) +/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/ { - if (!follow_symlinks) { - return DirEntry_get_lstat(defining_class, self); - } - - if (!self->stat) { - int result = os_DirEntry_is_symlink_impl(self, defining_class); - if (result == -1) { - return NULL; - } - if (result) { - PyObject *module = PyType_GetModule(defining_class); - self->stat = DirEntry_fetch_stat(module, self, 1); - } - else { - self->stat = DirEntry_get_lstat(defining_class, self); - } - } - - Py_XINCREF(self->stat); - return self->stat; + return py_posix_spawn(1, module, path, argv, env, file_actions, + setpgroup, resetids, setsid, setsigmask, setsigdef, + scheduler); } +#endif /* HAVE_POSIX_SPAWNP */ -/* Set exception and return -1 on error, 0 for False, 1 for True */ -static int -DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self, - int follow_symlinks, unsigned short mode_bits) +#ifdef HAVE_RTPSPAWN +static intptr_t +_rtp_spawn(int mode, const char *rtpFileName, const char *argv[], + const char *envp[]) { - PyObject *stat = NULL; - PyObject *st_mode = NULL; - long mode; - int result; -#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) - int is_symlink; - int need_stat; -#endif -#ifdef MS_WINDOWS - unsigned long dir_bits; + RTP_ID rtpid; + int status; + pid_t res; + int async_err = 0; + + /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes. + uStackSize=0 cannot be used, the default stack size is too small for + Python. */ + if (envp) { + rtpid = rtpSpawn(rtpFileName, argv, envp, + 100, 0x1000000, 0, VX_FP_TASK); + } + else { + rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ, + 100, 0x1000000, 0, VX_FP_TASK); + } + if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) { + do { + res = waitpid((pid_t)rtpid, &status, 0); + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (res < 0) + return RTP_ID_ERROR; + return ((intptr_t)status); + } + return ((intptr_t)rtpid); +} #endif -#ifdef MS_WINDOWS - is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK; - need_stat = follow_symlinks && is_symlink; -#elif defined(HAVE_DIRENT_D_TYPE) - is_symlink = self->d_type == DT_LNK; - need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink); +#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN) +/*[clinic input] +os.spawnv + + mode: int + Mode of process creation. + path: path_t + Path of executable file. + argv: object + Tuple or list of strings. + / + +Execute the program specified by path in a new process. +[clinic start generated code]*/ + +static PyObject * +os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) +/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/ +{ + EXECV_CHAR **argvlist; + int i; + Py_ssize_t argc; + intptr_t spawnval; + PyObject *(*getitem)(PyObject *, Py_ssize_t); + + /* spawnv has three arguments: (mode, path, argv), where + argv is a list or tuple of strings. */ + + if (PyList_Check(argv)) { + argc = PyList_Size(argv); + getitem = PyList_GetItem; + } + else if (PyTuple_Check(argv)) { + argc = PyTuple_Size(argv); + getitem = PyTuple_GetItem; + } + else { + PyErr_SetString(PyExc_TypeError, + "spawnv() arg 2 must be a tuple or list"); + return NULL; + } + if (argc == 0) { + PyErr_SetString(PyExc_ValueError, + "spawnv() arg 2 cannot be empty"); + return NULL; + } + + argvlist = PyMem_NEW(EXECV_CHAR *, argc+1); + if (argvlist == NULL) { + return PyErr_NoMemory(); + } + for (i = 0; i < argc; i++) { + if (!fsconvert_strdup((*getitem)(argv, i), + &argvlist[i])) { + free_string_array(argvlist, i); + PyErr_SetString( + PyExc_TypeError, + "spawnv() arg 2 must contain only strings"); + return NULL; + } + if (i == 0 && !argvlist[0][0]) { + free_string_array(argvlist, i + 1); + PyErr_SetString( + PyExc_ValueError, + "spawnv() arg 2 first element cannot be empty"); + return NULL; + } + } + argvlist[argc] = NULL; + +#if !defined(HAVE_RTPSPAWN) + if (mode == _OLD_P_OVERLAY) + mode = _P_OVERLAY; #endif + + if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, + Py_None) < 0) { + free_string_array(argvlist, argc); + return NULL; + } -#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) - if (need_stat) { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef HAVE_WSPAWNV + spawnval = _wspawnv(mode, path->wide, argvlist); +#elif defined(HAVE_RTPSPAWN) + spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL); +#else + spawnval = _spawnv(mode, path->narrow, argvlist); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + free_string_array(argvlist, argc); + + if (spawnval == -1) + return posix_error(); + else + return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); +} + +/*[clinic input] +os.spawnve + + mode: int + Mode of process creation. + path: path_t + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. + / + +Execute the program specified by path in a new process. +[clinic start generated code]*/ + +static PyObject * +os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, + PyObject *env) +/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/ +{ + EXECV_CHAR **argvlist; + EXECV_CHAR **envlist; + PyObject *res = NULL; + Py_ssize_t argc, i, envc; + intptr_t spawnval; + PyObject *(*getitem)(PyObject *, Py_ssize_t); + Py_ssize_t lastarg = 0; + + /* spawnve has four arguments: (mode, path, argv, env), where + argv is a list or tuple of strings and env is a dictionary + like posix.environ. */ + + if (PyList_Check(argv)) { + argc = PyList_Size(argv); + getitem = PyList_GetItem; + } + else if (PyTuple_Check(argv)) { + argc = PyTuple_Size(argv); + getitem = PyTuple_GetItem; + } + else { + PyErr_SetString(PyExc_TypeError, + "spawnve() arg 2 must be a tuple or list"); + goto fail_0; + } + if (argc == 0) { + PyErr_SetString(PyExc_ValueError, + "spawnve() arg 2 cannot be empty"); + goto fail_0; + } + if (!PyMapping_Check(env)) { + PyErr_SetString(PyExc_TypeError, + "spawnve() arg 3 must be a mapping object"); + goto fail_0; + } + + argvlist = PyMem_NEW(EXECV_CHAR *, argc+1); + if (argvlist == NULL) { + PyErr_NoMemory(); + goto fail_0; + } + for (i = 0; i < argc; i++) { + if (!fsconvert_strdup((*getitem)(argv, i), + &argvlist[i])) + { + lastarg = i; + goto fail_1; + } + if (i == 0 && !argvlist[0][0]) { + lastarg = i + 1; + PyErr_SetString( + PyExc_ValueError, + "spawnv() arg 2 first element cannot be empty"); + goto fail_1; + } + } + lastarg = argc; + argvlist[argc] = NULL; + + envlist = parse_envlist(env, &envc); + if (envlist == NULL) + goto fail_1; + +#if !defined(HAVE_RTPSPAWN) + if (mode == _OLD_P_OVERLAY) + mode = _P_OVERLAY; #endif - stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks); - if (!stat) { - if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) { - /* If file doesn't exist (anymore), then return False - (i.e., say it's not a file/directory) */ - PyErr_Clear(); - return 0; - } - goto error; - } - _posixstate* state = get_posix_state(PyType_GetModule(defining_class)); - st_mode = PyObject_GetAttr(stat, state->st_mode); - if (!st_mode) - goto error; + + if (PySys_Audit("os.spawn", "iOOO", mode, path->object, argv, env) < 0) { + goto fail_2; + } - mode = PyLong_AsLong(st_mode); - if (mode == -1 && PyErr_Occurred()) - goto error; - Py_CLEAR(st_mode); - Py_CLEAR(stat); - result = (mode & S_IFMT) == mode_bits; -#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef HAVE_WSPAWNV + spawnval = _wspawnve(mode, path->wide, argvlist, envlist); +#elif defined(HAVE_RTPSPAWN) + spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, + (const char **)envlist); +#else + spawnval = _spawnve(mode, path->narrow, argvlist, envlist); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + if (spawnval == -1) + (void) posix_error(); + else + res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval); + + fail_2: + while (--envc >= 0) + PyMem_DEL(envlist[envc]); + PyMem_DEL(envlist); + fail_1: + free_string_array(argvlist, lastarg); + fail_0: + return res; +} + +#endif /* HAVE_SPAWNV */ + + +#ifdef HAVE_FORK + +/* Helper function to validate arguments. + Returns 0 on success. non-zero on failure with a TypeError raised. + If obj is non-NULL it must be callable. */ +static int +check_null_or_callable(PyObject *obj, const char* obj_name) +{ + if (obj && !PyCallable_Check(obj)) { + PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s", + obj_name, _PyType_Name(Py_TYPE(obj))); + return -1; + } + return 0; +} + +/*[clinic input] +os.register_at_fork + + * + before: object=NULL + A callable to be called in the parent before the fork() syscall. + after_in_child: object=NULL + A callable to be called in the child after fork(). + after_in_parent: object=NULL + A callable to be called in the parent after fork(). + +Register callables to be called when forking a new process. + +'before' callbacks are called in reverse order. +'after_in_child' and 'after_in_parent' callbacks are called in order. + +[clinic start generated code]*/ + +static PyObject * +os_register_at_fork_impl(PyObject *module, PyObject *before, + PyObject *after_in_child, PyObject *after_in_parent) +/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/ +{ + PyInterpreterState *interp; + + if (!before && !after_in_child && !after_in_parent) { + PyErr_SetString(PyExc_TypeError, "At least one argument is required."); + return NULL; + } + if (check_null_or_callable(before, "before") || + check_null_or_callable(after_in_child, "after_in_child") || + check_null_or_callable(after_in_parent, "after_in_parent")) { + return NULL; + } + interp = _PyInterpreterState_GET(); + + if (register_at_forker(&interp->before_forkers, before)) { + return NULL; + } + if (register_at_forker(&interp->after_forkers_child, after_in_child)) { + return NULL; + } + if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) { + return NULL; + } + Py_RETURN_NONE; +} +#endif /* HAVE_FORK */ + + +#ifdef HAVE_FORK1 +/*[clinic input] +os.fork1 + +Fork a child process with a single multiplexed (i.e., not bound) thread. + +Return 0 to child process and PID of child to parent process. +[clinic start generated code]*/ + +static PyObject * +os_fork1_impl(PyObject *module) +/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/ +{ + pid_t pid; + + if (_PyInterpreterState_GET() != PyInterpreterState_Main()) { + PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); + return NULL; } - else if (is_symlink) { - assert(mode_bits != S_IFLNK); - result = 0; + PyOS_BeforeFork(); + pid = fork1(); + if (pid == 0) { + /* child: this clobbers and resets the import lock. */ + PyOS_AfterFork_Child(); + } else { + /* parent: release the import lock. */ + PyOS_AfterFork_Parent(); + } + if (pid == -1) + return posix_error(); + return PyLong_FromPid(pid); +} +#endif /* HAVE_FORK1 */ + + +#ifdef HAVE_FORK +/*[clinic input] +os.fork + +Fork a child process. + +Return 0 to child process and PID of child to parent process. +[clinic start generated code]*/ + +static PyObject * +os_fork_impl(PyObject *module) +/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/ +{ + pid_t pid; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (interp->config._isolated_interpreter) { + PyErr_SetString(PyExc_RuntimeError, + "fork not supported for isolated subinterpreters"); + return NULL; } - else { - assert(mode_bits == S_IFDIR || mode_bits == S_IFREG); -#ifdef MS_WINDOWS - dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY; - if (mode_bits == S_IFDIR) - result = dir_bits != 0; - else - result = dir_bits == 0; -#else /* POSIX */ - if (mode_bits == S_IFDIR) - result = self->d_type == DT_DIR; - else - result = self->d_type == DT_REG; -#endif + if (PySys_Audit("os.fork", NULL) < 0) { + return NULL; + } + PyOS_BeforeFork(); + pid = fork(); + if (pid == 0) { + /* child: this clobbers and resets the import lock. */ + PyOS_AfterFork_Child(); + } else { + /* parent: release the import lock. */ + PyOS_AfterFork_Parent(); + } + if (pid == -1) + return posix_error(); + return PyLong_FromPid(pid); +} +#endif /* HAVE_FORK */ + + +#ifdef HAVE_SCHED_H +#ifdef HAVE_SCHED_GET_PRIORITY_MAX +/*[clinic input] +os.sched_get_priority_max + + policy: int + +Get the maximum scheduling priority for policy. +[clinic start generated code]*/ + +static PyObject * +os_sched_get_priority_max_impl(PyObject *module, int policy) +/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/ +{ + int max; + + max = sched_get_priority_max(policy); + if (max < 0) + return posix_error(); + return PyLong_FromLong(max); +} + + +/*[clinic input] +os.sched_get_priority_min + + policy: int + +Get the minimum scheduling priority for policy. +[clinic start generated code]*/ + +static PyObject * +os_sched_get_priority_min_impl(PyObject *module, int policy) +/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/ +{ + int min = sched_get_priority_min(policy); + if (min < 0) + return posix_error(); + return PyLong_FromLong(min); +} +#endif /* HAVE_SCHED_GET_PRIORITY_MAX */ + + +#ifdef HAVE_SCHED_SETSCHEDULER +/*[clinic input] +os.sched_getscheduler + pid: pid_t + / + +Get the scheduling policy for the process identified by pid. + +Passing 0 for pid returns the scheduling policy for the calling process. +[clinic start generated code]*/ + +static PyObject * +os_sched_getscheduler_impl(PyObject *module, pid_t pid) +/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=8d99dac505485ac8]*/ +{ + int policy; + + policy = sched_getscheduler(pid); + if (policy < 0) + return posix_error(); + return PyLong_FromLong(policy); +} +#endif /* HAVE_SCHED_SETSCHEDULER */ + + +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) +/*[clinic input] +class os.sched_param "PyObject *" "SchedParamType" + +@classmethod +os.sched_param.__new__ + + sched_priority: object + A scheduling parameter. + +Currently has only one field: sched_priority +[clinic start generated code]*/ + +static PyObject * +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) +/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/ +{ + PyObject *res; + + res = PyStructSequence_New(type); + if (!res) + return NULL; + Py_INCREF(sched_priority); + PyStructSequence_SET_ITEM(res, 0, sched_priority); + return res; +} + +PyDoc_VAR(os_sched_param__doc__); + +static PyStructSequence_Field sched_param_fields[] = { + {"sched_priority", "the scheduling priority"}, + {0} +}; + +static PyStructSequence_Desc sched_param_desc = { + "sched_param", /* name */ + os_sched_param__doc__, /* doc */ + sched_param_fields, + 1 +}; + +static int +convert_sched_param(PyObject *module, PyObject *param, struct sched_param *res) +{ + long priority; + + if (!Py_IS_TYPE(param, (PyTypeObject *)get_posix_state(module)->SchedParamType)) { + PyErr_SetString(PyExc_TypeError, "must have a sched_param object"); + return 0; + } + priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0)); + if (priority == -1 && PyErr_Occurred()) + return 0; + if (priority > INT_MAX || priority < INT_MIN) { + PyErr_SetString(PyExc_OverflowError, "sched_priority out of range"); + return 0; + } + res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int); + return 1; +} +#endif /* defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) */ + + +#ifdef HAVE_SCHED_SETSCHEDULER +/*[clinic input] +os.sched_setscheduler + + pid: pid_t + policy: int + param as param_obj: object + / + +Set the scheduling policy for the process identified by pid. + +If pid is 0, the calling process is changed. +param is an instance of sched_param. +[clinic start generated code]*/ + +static PyObject * +os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy, + PyObject *param_obj) +/*[clinic end generated code: output=cde27faa55dc993e input=73013d731bd8fbe9]*/ +{ + struct sched_param param; + if (!convert_sched_param(module, param_obj, ¶m)) { + return NULL; + } + + /* + ** sched_setscheduler() returns 0 in Linux, but the previous + ** scheduling policy under Solaris/Illumos, and others. + ** On error, -1 is returned in all Operating Systems. + */ + if (sched_setscheduler(pid, policy, ¶m) == -1) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SCHED_SETSCHEDULER*/ + + +#ifdef HAVE_SCHED_SETPARAM +/*[clinic input] +os.sched_getparam + pid: pid_t + / + +Returns scheduling parameters for the process identified by pid. + +If pid is 0, returns parameters for the calling process. +Return value is an instance of sched_param. +[clinic start generated code]*/ + +static PyObject * +os_sched_getparam_impl(PyObject *module, pid_t pid) +/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/ +{ + struct sched_param param; + PyObject *result; + PyObject *priority; + + if (sched_getparam(pid, ¶m)) + return posix_error(); + PyObject *SchedParamType = get_posix_state(module)->SchedParamType; + result = PyStructSequence_New((PyTypeObject *)SchedParamType); + if (!result) + return NULL; + priority = PyLong_FromLong(param.sched_priority); + if (!priority) { + Py_DECREF(result); + return NULL; + } + PyStructSequence_SET_ITEM(result, 0, priority); + return result; +} + + +/*[clinic input] +os.sched_setparam + pid: pid_t + param as param_obj: object + / + +Set scheduling parameters for the process identified by pid. + +If pid is 0, sets parameters for the calling process. +param should be an instance of sched_param. +[clinic start generated code]*/ + +static PyObject * +os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj) +/*[clinic end generated code: output=f19fe020a53741c1 input=27b98337c8b2dcc7]*/ +{ + struct sched_param param; + if (!convert_sched_param(module, param_obj, ¶m)) { + return NULL; + } + + if (sched_setparam(pid, ¶m)) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SCHED_SETPARAM */ + + +#ifdef HAVE_SCHED_RR_GET_INTERVAL +/*[clinic input] +os.sched_rr_get_interval -> double + pid: pid_t + / + +Return the round-robin quantum for the process identified by pid, in seconds. + +Value returned is a float. +[clinic start generated code]*/ + +static double +os_sched_rr_get_interval_impl(PyObject *module, pid_t pid) +/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/ +{ + struct timespec interval; + if (sched_rr_get_interval(pid, &interval)) { + posix_error(); + return -1.0; + } +#ifdef _Py_MEMORY_SANITIZER + __msan_unpoison(&interval, sizeof(interval)); +#endif + return (double)interval.tv_sec + 1e-9*interval.tv_nsec; +} +#endif /* HAVE_SCHED_RR_GET_INTERVAL */ + + +/*[clinic input] +os.sched_yield + +Voluntarily relinquish the CPU. +[clinic start generated code]*/ + +static PyObject * +os_sched_yield_impl(PyObject *module) +/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/ +{ + if (sched_yield()) + return posix_error(); + Py_RETURN_NONE; +} + +#ifdef HAVE_SCHED_SETAFFINITY +/* The minimum number of CPUs allocated in a cpu_set_t */ +static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT; + +/*[clinic input] +os.sched_setaffinity + pid: pid_t + mask : object + / + +Set the CPU affinity of the process identified by pid to mask. + +mask should be an iterable of integers identifying CPUs. +[clinic start generated code]*/ + +static PyObject * +os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask) +/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/ +{ + int ncpus; + size_t setsize; + cpu_set_t *cpu_set = NULL; + PyObject *iterator = NULL, *item; + + iterator = PyObject_GetIter(mask); + if (iterator == NULL) + return NULL; + + ncpus = NCPUS_START; + setsize = CPU_ALLOC_SIZE(ncpus); + cpu_set = CPU_ALLOC(ncpus); + if (cpu_set == NULL) { + PyErr_NoMemory(); + goto error; + } + CPU_ZERO_S(setsize, cpu_set); + + while ((item = PyIter_Next(iterator))) { + long cpu; + if (!PyLong_Check(item)) { + PyErr_Format(PyExc_TypeError, + "expected an iterator of ints, " + "but iterator yielded %R", + Py_TYPE(item)); + Py_DECREF(item); + goto error; + } + cpu = PyLong_AsLong(item); + Py_DECREF(item); + if (cpu < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_ValueError, "negative CPU number"); + goto error; + } + if (cpu > INT_MAX - 1) { + PyErr_SetString(PyExc_OverflowError, "CPU number too large"); + goto error; + } + if (cpu >= ncpus) { + /* Grow CPU mask to fit the CPU number */ + int newncpus = ncpus; + cpu_set_t *newmask; + size_t newsetsize; + while (newncpus <= cpu) { + if (newncpus > INT_MAX / 2) + newncpus = cpu + 1; + else + newncpus = newncpus * 2; + } + newmask = CPU_ALLOC(newncpus); + if (newmask == NULL) { + PyErr_NoMemory(); + goto error; + } + newsetsize = CPU_ALLOC_SIZE(newncpus); + CPU_ZERO_S(newsetsize, newmask); + memcpy(newmask, cpu_set, setsize); + CPU_FREE(cpu_set); + setsize = newsetsize; + cpu_set = newmask; + ncpus = newncpus; + } + CPU_SET_S(cpu, setsize, cpu_set); + } + if (PyErr_Occurred()) { + goto error; + } + Py_CLEAR(iterator); + + if (sched_setaffinity(pid, setsize, cpu_set)) { + posix_error(); + goto error; + } + CPU_FREE(cpu_set); + Py_RETURN_NONE; + +error: + if (cpu_set) + CPU_FREE(cpu_set); + Py_XDECREF(iterator); + return NULL; +} + + +/*[clinic input] +os.sched_getaffinity + pid: pid_t + / + +Return the affinity of the process identified by pid (or the current process if zero). + +The affinity is returned as a set of CPU identifiers. +[clinic start generated code]*/ + +static PyObject * +os_sched_getaffinity_impl(PyObject *module, pid_t pid) +/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/ +{ + int cpu, ncpus, count; + size_t setsize; + cpu_set_t *mask = NULL; + PyObject *res = NULL; + + ncpus = NCPUS_START; + while (1) { + setsize = CPU_ALLOC_SIZE(ncpus); + mask = CPU_ALLOC(ncpus); + if (mask == NULL) + return PyErr_NoMemory(); + if (sched_getaffinity(pid, setsize, mask) == 0) + break; + CPU_FREE(mask); + if (errno != EINVAL) + return posix_error(); + if (ncpus > INT_MAX / 2) { + PyErr_SetString(PyExc_OverflowError, "could not allocate " + "a large enough CPU set"); + return NULL; + } + ncpus = ncpus * 2; + } + + res = PySet_New(NULL); + if (res == NULL) + goto error; + for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) { + if (CPU_ISSET_S(cpu, setsize, mask)) { + PyObject *cpu_num = PyLong_FromLong(cpu); + --count; + if (cpu_num == NULL) + goto error; + if (PySet_Add(res, cpu_num)) { + Py_DECREF(cpu_num); + goto error; + } + Py_DECREF(cpu_num); + } + } + CPU_FREE(mask); + return res; + +error: + if (mask) + CPU_FREE(mask); + Py_XDECREF(res); + return NULL; +} + +#endif /* HAVE_SCHED_SETAFFINITY */ + +#endif /* HAVE_SCHED_H */ + + +/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ +/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ +#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) +#define DEV_PTY_FILE "/dev/ptc" +#define HAVE_DEV_PTMX +#else +#define DEV_PTY_FILE "/dev/ptmx" +#endif + +#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) +#ifdef HAVE_PTY_H +#include +#else +#ifdef HAVE_LIBUTIL_H +#include +#else +#ifdef HAVE_UTIL_H +#include +#endif /* HAVE_UTIL_H */ +#endif /* HAVE_LIBUTIL_H */ +#endif /* HAVE_PTY_H */ +#ifdef HAVE_STROPTS_H +#include +#else + #define __SID ('S' << 8) + #define I_PUSH (__SID | 2) +#endif +#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */ + + +#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) +/*[clinic input] +os.openpty + +Open a pseudo-terminal. + +Return a tuple of (master_fd, slave_fd) containing open file descriptors +for both the master and slave ends. +[clinic start generated code]*/ + +static PyObject * +os_openpty_impl(PyObject *module) +/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/ +{ + int master_fd = -1, slave_fd = -1; +#ifndef HAVE_OPENPTY + char * slave_name; +#endif +#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) + PyOS_sighandler_t sig_saved; +#if defined(__sun) && defined(__SVR4) + extern char *ptsname(int fildes); +#endif +#endif + +#ifdef HAVE_OPENPTY + if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) + goto posix_error; + + if (_Py_set_inheritable(master_fd, 0, NULL) < 0) + goto error; + if (_Py_set_inheritable(slave_fd, 0, NULL) < 0) + goto error; + +#elif defined(HAVE__GETPTY) + slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); + if (slave_name == NULL) + goto posix_error; + if (_Py_set_inheritable(master_fd, 0, NULL) < 0) + goto error; + + slave_fd = _Py_open(slave_name, O_RDWR); + if (slave_fd < 0) + goto error; + +#else + master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */ + if (master_fd < 0) + goto posix_error; + + sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL); + + /* change permission of slave */ + if (grantpt(master_fd) < 0) { + PyOS_setsig(SIGCHLD, sig_saved); + goto posix_error; + } + + /* unlock slave */ + if (unlockpt(master_fd) < 0) { + PyOS_setsig(SIGCHLD, sig_saved); + goto posix_error; + } + + PyOS_setsig(SIGCHLD, sig_saved); + + slave_name = ptsname(master_fd); /* get name of slave */ + if (slave_name == NULL) + goto posix_error; + + slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ + if (slave_fd == -1) + goto error; + + if (_Py_set_inheritable(master_fd, 0, NULL) < 0) + goto posix_error; + +#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC) + ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ + ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ +#ifndef __hpux + ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */ +#endif /* __hpux */ +#endif /* HAVE_CYGWIN */ +#endif /* HAVE_OPENPTY */ + + return Py_BuildValue("(ii)", master_fd, slave_fd); + +posix_error: + posix_error(); +error: + if (master_fd != -1) + close(master_fd); + if (slave_fd != -1) + close(slave_fd); + return NULL; +} +#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ + + +#ifdef HAVE_FORKPTY +/*[clinic input] +os.forkpty + +Fork a new process with a new pseudo-terminal as controlling tty. + +Returns a tuple of (pid, master_fd). +Like fork(), return pid of 0 to the child process, +and pid of child to the parent process. +To both, return fd of newly opened pseudo-terminal. +[clinic start generated code]*/ + +static PyObject * +os_forkpty_impl(PyObject *module) +/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/ +{ + int master_fd = -1; + pid_t pid; + + if (_PyInterpreterState_GET() != PyInterpreterState_Main()) { + PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); + return NULL; + } + if (PySys_Audit("os.forkpty", NULL) < 0) { + return NULL; } + PyOS_BeforeFork(); + pid = forkpty(&master_fd, NULL, NULL, NULL); + if (pid == 0) { + /* child: this clobbers and resets the import lock. */ + PyOS_AfterFork_Child(); + } else { + /* parent: release the import lock. */ + PyOS_AfterFork_Parent(); + } + if (pid == -1) + return posix_error(); + return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); +} +#endif /* HAVE_FORKPTY */ + + +#ifdef HAVE_GETEGID +/*[clinic input] +os.getegid + +Return the current process's effective group id. +[clinic start generated code]*/ + +static PyObject * +os_getegid_impl(PyObject *module) +/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/ +{ + return _PyLong_FromGid(getegid()); +} +#endif /* HAVE_GETEGID */ + + +#ifdef HAVE_GETEUID +/*[clinic input] +os.geteuid + +Return the current process's effective user id. +[clinic start generated code]*/ + +static PyObject * +os_geteuid_impl(PyObject *module) +/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/ +{ + return _PyLong_FromUid(geteuid()); +} +#endif /* HAVE_GETEUID */ + + +#ifdef HAVE_GETGID +/*[clinic input] +os.getgid + +Return the current process's group id. +[clinic start generated code]*/ + +static PyObject * +os_getgid_impl(PyObject *module) +/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/ +{ + return _PyLong_FromGid(getgid()); +} +#endif /* HAVE_GETGID */ + + +#ifdef HAVE_GETPID +/*[clinic input] +os.getpid + +Return the current process id. +[clinic start generated code]*/ + +static PyObject * +os_getpid_impl(PyObject *module) +/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/ +{ + return PyLong_FromPid(getpid()); +} +#endif /* HAVE_GETPID */ + +#ifdef NGROUPS_MAX +#define MAX_GROUPS NGROUPS_MAX +#else + /* defined to be 16 on Solaris7, so this should be a small number */ +#define MAX_GROUPS 64 #endif - return result; +#ifdef HAVE_GETGROUPLIST + +#ifdef __APPLE__ +/*[clinic input] +os.getgrouplist + + user: str + username to lookup + group as basegid: int + base group id of the user + / -error: - Py_XDECREF(st_mode); - Py_XDECREF(stat); - return -1; -} +Returns a list of groups to which a user belongs. +[clinic start generated code]*/ +static PyObject * +os_getgrouplist_impl(PyObject *module, const char *user, int basegid) +/*[clinic end generated code: output=6e734697b8c26de0 input=f8d870374b09a490]*/ +#else /*[clinic input] -os.DirEntry.is_dir -> bool - defining_class: defining_class +os.getgrouplist + + user: str + username to lookup + group as basegid: gid_t + base group id of the user / - * - follow_symlinks: bool = True -Return True if the entry is a directory; cached per entry. -[clinic start generated code]*/ +Returns a list of groups to which a user belongs. +[clinic start generated code]*/ + +static PyObject * +os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid) +/*[clinic end generated code: output=0ebd7fb70115575b input=cc61d5c20b08958d]*/ +#endif +{ + int i, ngroups; + PyObject *list; +#ifdef __APPLE__ + int *groups; +#else + gid_t *groups; +#endif + + /* + * NGROUPS_MAX is defined by POSIX.1 as the maximum + * number of supplimental groups a users can belong to. + * We have to increment it by one because + * getgrouplist() returns both the supplemental groups + * and the primary group, i.e. all of the groups the + * user belongs to. + */ + ngroups = 1 + MAX_GROUPS; + + while (1) { +#ifdef __APPLE__ + groups = PyMem_New(int, ngroups); +#else + groups = PyMem_New(gid_t, ngroups); +#endif + if (groups == NULL) { + return PyErr_NoMemory(); + } + + int old_ngroups = ngroups; + if (getgrouplist(user, basegid, groups, &ngroups) != -1) { + /* Success */ + break; + } + + /* getgrouplist() fails if the group list is too small */ + PyMem_Free(groups); -static int -os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class, - int follow_symlinks) -/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/ -{ - return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR); -} + if (ngroups > old_ngroups) { + /* If the group list is too small, the glibc implementation of + getgrouplist() sets ngroups to the total number of groups and + returns -1. */ + } + else { + /* Double the group list size */ + if (ngroups > INT_MAX / 2) { + return PyErr_NoMemory(); + } + ngroups *= 2; + } + /* Retry getgrouplist() with a larger group list */ + } + +#ifdef _Py_MEMORY_SANITIZER + /* Clang memory sanitizer libc intercepts don't know getgrouplist. */ + __msan_unpoison(&ngroups, sizeof(ngroups)); + __msan_unpoison(groups, ngroups*sizeof(*groups)); +#endif + + list = PyList_New(ngroups); + if (list == NULL) { + PyMem_Del(groups); + return NULL; + } + + for (i = 0; i < ngroups; i++) { +#ifdef __APPLE__ + PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]); +#else + PyObject *o = _PyLong_FromGid(groups[i]); +#endif + if (o == NULL) { + Py_DECREF(list); + PyMem_Del(groups); + return NULL; + } + PyList_SET_ITEM(list, i, o); + } + + PyMem_Del(groups); + + return list; +} +#endif /* HAVE_GETGROUPLIST */ + + +#ifdef HAVE_GETGROUPS +/*[clinic input] +os.getgroups + +Return list of supplemental group IDs for the process. +[clinic start generated code]*/ + +static PyObject * +os_getgroups_impl(PyObject *module) +/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/ +{ + PyObject *result = NULL; + gid_t grouplist[MAX_GROUPS]; + + /* On MacOSX getgroups(2) can return more than MAX_GROUPS results + * This is a helper variable to store the intermediate result when + * that happens. + * + * To keep the code readable the OSX behaviour is unconditional, + * according to the POSIX spec this should be safe on all unix-y + * systems. + */ + gid_t* alt_grouplist = grouplist; + int n; + +#ifdef __APPLE__ + /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if + * there are more groups than can fit in grouplist. Therefore, on OS X + * always first call getgroups with length 0 to get the actual number + * of groups. + */ + n = getgroups(0, NULL); + if (n < 0) { + return posix_error(); + } else if (n <= MAX_GROUPS) { + /* groups will fit in existing array */ + alt_grouplist = grouplist; + } else { + alt_grouplist = PyMem_New(gid_t, n); + if (alt_grouplist == NULL) { + return PyErr_NoMemory(); + } + } + + n = getgroups(n, alt_grouplist); + if (n == -1) { + if (alt_grouplist != grouplist) { + PyMem_Free(alt_grouplist); + } + return posix_error(); + } +#else + n = getgroups(MAX_GROUPS, grouplist); + if (n < 0) { + if (errno == EINVAL) { + n = getgroups(0, NULL); + if (n == -1) { + return posix_error(); + } + if (n == 0) { + /* Avoid malloc(0) */ + alt_grouplist = grouplist; + } else { + alt_grouplist = PyMem_New(gid_t, n); + if (alt_grouplist == NULL) { + return PyErr_NoMemory(); + } + n = getgroups(n, alt_grouplist); + if (n == -1) { + PyMem_Free(alt_grouplist); + return posix_error(); + } + } + } else { + return posix_error(); + } + } +#endif + + result = PyList_New(n); + if (result != NULL) { + int i; + for (i = 0; i < n; ++i) { + PyObject *o = _PyLong_FromGid(alt_grouplist[i]); + if (o == NULL) { + Py_DECREF(result); + result = NULL; + break; + } + PyList_SET_ITEM(result, i, o); + } + } + + if (alt_grouplist != grouplist) { + PyMem_Free(alt_grouplist); + } + + return result; +} +#endif /* HAVE_GETGROUPS */ + +#ifdef HAVE_INITGROUPS +#ifdef __APPLE__ /*[clinic input] -os.DirEntry.is_file -> bool - defining_class: defining_class +os.initgroups + + username as oname: FSConverter + gid: int / - * - follow_symlinks: bool = True -Return True if the entry is a file; cached per entry. -[clinic start generated code]*/ +Initialize the group access list. -static int -os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class, - int follow_symlinks) -/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/ -{ - return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG); -} +Call the system initgroups() to initialize the group access list with all of +the groups of which the specified username is a member, plus the specified +group id. +[clinic start generated code]*/ +static PyObject * +os_initgroups_impl(PyObject *module, PyObject *oname, int gid) +/*[clinic end generated code: output=7f074d30a425fd3a input=df3d54331b0af204]*/ +#else /*[clinic input] -os.DirEntry.inode +os.initgroups + + username as oname: FSConverter + gid: gid_t + / + +Initialize the group access list. -Return inode of the entry; cached per entry. +Call the system initgroups() to initialize the group access list with all of +the groups of which the specified username is a member, plus the specified +group id. [clinic start generated code]*/ static PyObject * -os_DirEntry_inode_impl(DirEntry *self) -/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/ +os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid) +/*[clinic end generated code: output=59341244521a9e3f input=0cb91bdc59a4c564]*/ +#endif { -#ifdef MS_WINDOWS - if (!self->got_file_index) { - PyObject *unicode; - const wchar_t *path; - STRUCT_STAT stat; - int result; - - if (!PyUnicode_FSDecoder(self->path, &unicode)) - return NULL; -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - path = PyUnicode_AsUnicode(unicode); -_Py_COMP_DIAG_POP - result = LSTAT(path, &stat); - Py_DECREF(unicode); - - if (result != 0) - return path_object_error(self->path); - - self->win32_file_index = stat.st_ino; - self->got_file_index = 1; + const char *username = PyBytes_AS_STRING(oname); + + if (initgroups(username, gid) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_RETURN_NONE; +} +#endif /* HAVE_INITGROUPS */ + + +#ifdef HAVE_GETPGID +/*[clinic input] +os.getpgid + + pid: pid_t + +Call the system call getpgid(), and return the result. +[clinic start generated code]*/ + +static PyObject * +os_getpgid_impl(PyObject *module, pid_t pid) +/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/ +{ + pid_t pgid = getpgid(pid); + if (pgid < 0) + return posix_error(); + return PyLong_FromPid(pgid); +} +#endif /* HAVE_GETPGID */ + + +#ifdef HAVE_GETPGRP +/*[clinic input] +os.getpgrp + +Return the current process group id. +[clinic start generated code]*/ + +static PyObject * +os_getpgrp_impl(PyObject *module) +/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/ +{ +#ifdef GETPGRP_HAVE_ARG + return PyLong_FromPid(getpgrp(0)); +#else /* GETPGRP_HAVE_ARG */ + return PyLong_FromPid(getpgrp()); +#endif /* GETPGRP_HAVE_ARG */ +} +#endif /* HAVE_GETPGRP */ + + +#ifdef HAVE_SETPGRP +/*[clinic input] +os.setpgrp + +Make the current process the leader of its process group. +[clinic start generated code]*/ + +static PyObject * +os_setpgrp_impl(PyObject *module) +/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/ +{ +#ifdef SETPGRP_HAVE_ARG + if (setpgrp(0, 0) < 0) +#else /* SETPGRP_HAVE_ARG */ + if (setpgrp() < 0) +#endif /* SETPGRP_HAVE_ARG */ + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETPGRP */ + +#ifdef HAVE_GETPPID + +#ifdef MS_WINDOWS +#include + +static PyObject* +win32_getppid() +{ + HANDLE snapshot; + pid_t mypid; + PyObject* result = NULL; + BOOL have_record; + PROCESSENTRY32 pe; + + mypid = getpid(); /* This function never fails */ + + snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snapshot == INVALID_HANDLE_VALUE) + return PyErr_SetFromWindowsErr(GetLastError()); + + pe.dwSize = sizeof(pe); + have_record = Process32First(snapshot, &pe); + while (have_record) { + if (mypid == (pid_t)pe.th32ProcessID) { + /* We could cache the ulong value in a static variable. */ + result = PyLong_FromPid((pid_t)pe.th32ParentProcessID); + break; + } + + have_record = Process32Next(snapshot, &pe); + } + + /* If our loop exits and our pid was not found (result will be NULL) + * then GetLastError will return ERROR_NO_MORE_FILES. This is an + * error anyway, so let's raise it. */ + if (!result) + result = PyErr_SetFromWindowsErr(GetLastError()); + + CloseHandle(snapshot); + + return result; +} +#endif /*MS_WINDOWS*/ + + +/*[clinic input] +os.getppid + +Return the parent's process id. + +If the parent process has already exited, Windows machines will still +return its id; others systems will return the id of the 'init' process (1). +[clinic start generated code]*/ + +static PyObject * +os_getppid_impl(PyObject *module) +/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/ +{ +#ifdef MS_WINDOWS + return win32_getppid(); +#else + return PyLong_FromPid(getppid()); +#endif +} +#endif /* HAVE_GETPPID */ + + +#ifdef HAVE_GETLOGIN +/*[clinic input] +os.getlogin + +Return the actual login name. +[clinic start generated code]*/ + +static PyObject * +os_getlogin_impl(PyObject *module) +/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/ +{ + PyObject *result = NULL; +#ifdef MS_WINDOWS + wchar_t user_name[UNLEN + 1]; + DWORD num_chars = Py_ARRAY_LENGTH(user_name); + + if (GetUserNameW(user_name, &num_chars)) { + /* num_chars is the number of unicode chars plus null terminator */ + result = PyUnicode_FromWideChar(user_name, num_chars - 1); + } + else + result = PyErr_SetFromWindowsErr(GetLastError()); +#else + char *name; + int old_errno = errno; + + errno = 0; + name = getlogin(); + if (name == NULL) { + if (errno) + posix_error(); + else + PyErr_SetString(PyExc_OSError, "unable to determine login name"); + } + else + result = PyUnicode_DecodeFSDefault(name); + errno = old_errno; +#endif + return result; +} +#endif /* HAVE_GETLOGIN */ + + +#ifdef HAVE_GETUID +/*[clinic input] +os.getuid + +Return the current process's user id. +[clinic start generated code]*/ + +static PyObject * +os_getuid_impl(PyObject *module) +/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/ +{ + return _PyLong_FromUid(getuid()); +} +#endif /* HAVE_GETUID */ + + +#ifdef MS_WINDOWS +#define HAVE_KILL +#endif /* MS_WINDOWS */ + +#ifdef HAVE_KILL +/*[clinic input] +os.kill + + pid: pid_t + signal: Py_ssize_t + / + +Kill a process with a signal. +[clinic start generated code]*/ + +static PyObject * +os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) +/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/ +{ + if (PySys_Audit("os.kill", "in", pid, signal) < 0) { + return NULL; } - Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index)); - return PyLong_FromUnsignedLongLong(self->win32_file_index); -#else /* POSIX */ - Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino)); - return PyLong_FromUnsignedLongLong(self->d_ino); -#endif -} +#ifndef MS_WINDOWS + if (kill(pid, (int)signal) == -1) + return posix_error(); + Py_RETURN_NONE; +#else /* !MS_WINDOWS */ + PyObject *result; + DWORD sig = (DWORD)signal; + DWORD err; + HANDLE handle; + + /* Console processes which share a common console can be sent CTRL+C or + CTRL+BREAK events, provided they handle said events. */ + if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { + if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) { + err = GetLastError(); + PyErr_SetFromWindowsErr(err); + } + else + Py_RETURN_NONE; + } + + /* If the signal is outside of what GenerateConsoleCtrlEvent can use, + attempt to open and terminate the process. */ + handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); + if (handle == NULL) { + err = GetLastError(); + return PyErr_SetFromWindowsErr(err); + } + + if (TerminateProcess(handle, sig) == 0) { + err = GetLastError(); + result = PyErr_SetFromWindowsErr(err); + } else { + Py_INCREF(Py_None); + result = Py_None; + } + + CloseHandle(handle); + return result; +#endif /* !MS_WINDOWS */ +} +#endif /* HAVE_KILL */ + + +#ifdef HAVE_KILLPG +/*[clinic input] +os.killpg + + pgid: pid_t + signal: int + / + +Kill a process group with a signal. +[clinic start generated code]*/ + +static PyObject * +os_killpg_impl(PyObject *module, pid_t pgid, int signal) +/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/ +{ + if (PySys_Audit("os.killpg", "ii", pgid, signal) < 0) { + return NULL; + } + /* XXX some man pages make the `pgid` parameter an int, others + a pid_t. Since getpgrp() returns a pid_t, we assume killpg should + take the same type. Moreover, pid_t is always at least as wide as + int (else compilation of this module fails), which is safe. */ + if (killpg(pgid, signal) == -1) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_KILLPG */ + + +#ifdef HAVE_PLOCK +#ifdef HAVE_SYS_LOCK_H +#include +#endif + +/*[clinic input] +os.plock + op: int + / + +Lock program segments into memory."); +[clinic start generated code]*/ + +static PyObject * +os_plock_impl(PyObject *module, int op) +/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/ +{ + if (plock(op) == -1) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_PLOCK */ + + +#ifdef HAVE_SETUID +/*[clinic input] +os.setuid + + uid: uid_t + / + +Set the current process's user id. +[clinic start generated code]*/ + +static PyObject * +os_setuid_impl(PyObject *module, uid_t uid) +/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/ +{ + if (setuid(uid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETUID */ + + +#ifdef HAVE_SETEUID +/*[clinic input] +os.seteuid + + euid: uid_t + / + +Set the current process's effective user id. +[clinic start generated code]*/ + +static PyObject * +os_seteuid_impl(PyObject *module, uid_t euid) +/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/ +{ + if (seteuid(euid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETEUID */ + + +#ifdef HAVE_SETEGID +/*[clinic input] +os.setegid + + egid: gid_t + / + +Set the current process's effective group id. +[clinic start generated code]*/ + +static PyObject * +os_setegid_impl(PyObject *module, gid_t egid) +/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/ +{ + if (setegid(egid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETEGID */ + + +#ifdef HAVE_SETREUID +/*[clinic input] +os.setreuid + + ruid: uid_t + euid: uid_t + / + +Set the current process's real and effective user ids. +[clinic start generated code]*/ + +static PyObject * +os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid) +/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/ +{ + if (setreuid(ruid, euid) < 0) { + return posix_error(); + } else { + Py_RETURN_NONE; + } +} +#endif /* HAVE_SETREUID */ + + +#ifdef HAVE_SETREGID +/*[clinic input] +os.setregid + + rgid: gid_t + egid: gid_t + / + +Set the current process's real and effective group ids. +[clinic start generated code]*/ + +static PyObject * +os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid) +/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/ +{ + if (setregid(rgid, egid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETREGID */ + + +#ifdef HAVE_SETGID +/*[clinic input] +os.setgid + gid: gid_t + / + +Set the current process's group id. +[clinic start generated code]*/ + +static PyObject * +os_setgid_impl(PyObject *module, gid_t gid) +/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/ +{ + if (setgid(gid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETGID */ + + +#ifdef HAVE_SETGROUPS +/*[clinic input] +os.setgroups + + groups: object + / + +Set the groups of the current process to list. +[clinic start generated code]*/ + +static PyObject * +os_setgroups(PyObject *module, PyObject *groups) +/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/ +{ + Py_ssize_t i, len; + gid_t grouplist[MAX_GROUPS]; + + if (!PySequence_Check(groups)) { + PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); + return NULL; + } + len = PySequence_Size(groups); + if (len < 0) { + return NULL; + } + if (len > MAX_GROUPS) { + PyErr_SetString(PyExc_ValueError, "too many groups"); + return NULL; + } + for(i = 0; i < len; i++) { + PyObject *elem; + elem = PySequence_GetItem(groups, i); + if (!elem) + return NULL; + if (!PyLong_Check(elem)) { + PyErr_SetString(PyExc_TypeError, + "groups must be integers"); + Py_DECREF(elem); + return NULL; + } else { + if (!_Py_Gid_Converter(elem, &grouplist[i])) { + Py_DECREF(elem); + return NULL; + } + } + Py_DECREF(elem); + } + + if (setgroups(len, grouplist) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETGROUPS */ + +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) +static PyObject * +wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru) +{ + PyObject *result; + PyObject *struct_rusage; + + if (pid == -1) + return posix_error(); + + // If wait succeeded but no child was ready to report status, ru will not + // have been populated. + if (pid == 0) { + memset(ru, 0, sizeof(*ru)); + } + + PyObject *m = PyImport_ImportModuleNoBlock("resource"); + if (m == NULL) + return NULL; + struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage); + Py_DECREF(m); + if (struct_rusage == NULL) + return NULL; -static PyObject * -DirEntry_repr(DirEntry *self) -{ - return PyUnicode_FromFormat("", self->name); -} + /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ + result = PyStructSequence_New((PyTypeObject*) struct_rusage); + Py_DECREF(struct_rusage); + if (!result) + return NULL; + +#ifndef doubletime +#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) +#endif + + PyStructSequence_SET_ITEM(result, 0, + PyFloat_FromDouble(doubletime(ru->ru_utime))); + PyStructSequence_SET_ITEM(result, 1, + PyFloat_FromDouble(doubletime(ru->ru_stime))); +#define SET_INT(result, index, value)\ + PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value)) + SET_INT(result, 2, ru->ru_maxrss); + SET_INT(result, 3, ru->ru_ixrss); + SET_INT(result, 4, ru->ru_idrss); + SET_INT(result, 5, ru->ru_isrss); + SET_INT(result, 6, ru->ru_minflt); + SET_INT(result, 7, ru->ru_majflt); + SET_INT(result, 8, ru->ru_nswap); + SET_INT(result, 9, ru->ru_inblock); + SET_INT(result, 10, ru->ru_oublock); + SET_INT(result, 11, ru->ru_msgsnd); + SET_INT(result, 12, ru->ru_msgrcv); + SET_INT(result, 13, ru->ru_nsignals); + SET_INT(result, 14, ru->ru_nvcsw); + SET_INT(result, 15, ru->ru_nivcsw); +#undef SET_INT + + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } + + return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result); +} +#endif /* HAVE_WAIT3 || HAVE_WAIT4 */ + + +#ifdef HAVE_WAIT3 +/*[clinic input] +os.wait3 + + options: int +Wait for completion of a child process. + +Returns a tuple of information about the child process: + (pid, status, rusage) +[clinic start generated code]*/ + +static PyObject * +os_wait3_impl(PyObject *module, int options) +/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/ +{ + pid_t pid; + struct rusage ru; + int async_err = 0; + WAIT_TYPE status; + WAIT_STATUS_INT(status) = 0; + + do { + Py_BEGIN_ALLOW_THREADS + pid = wait3(&status, options, &ru); + Py_END_ALLOW_THREADS + } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (pid < 0) + return (!async_err) ? posix_error() : NULL; + + return wait_helper(module, pid, WAIT_STATUS_INT(status), &ru); +} +#endif /* HAVE_WAIT3 */ + + +#ifdef HAVE_WAIT4 +/*[clinic input] + +os.wait4 + + pid: pid_t + options: int + +Wait for completion of a specific child process. + +Returns a tuple of information about the child process: + (pid, status, rusage) +[clinic start generated code]*/ + +static PyObject * +os_wait4_impl(PyObject *module, pid_t pid, int options) +/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/ +{ + pid_t res; + struct rusage ru; + int async_err = 0; + WAIT_TYPE status; + WAIT_STATUS_INT(status) = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = wait4(pid, &status, options, &ru); + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res < 0) + return (!async_err) ? posix_error() : NULL; + + return wait_helper(module, res, WAIT_STATUS_INT(status), &ru); +} +#endif /* HAVE_WAIT4 */ + + +#if defined(HAVE_WAITID) && !defined(__APPLE__) +/*[clinic input] +os.waitid + + idtype: idtype_t + Must be one of be P_PID, P_PGID or P_ALL. + id: id_t + The id to wait on. + options: int + Constructed from the ORing of one or more of WEXITED, WSTOPPED + or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT. + / + +Returns the result of waiting for a process or processes. + +Returns either waitid_result or None if WNOHANG is specified and there are +no children in a waitable state. +[clinic start generated code]*/ + +static PyObject * +os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options) +/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/ +{ + PyObject *result; + int res; + int async_err = 0; + siginfo_t si; + si.si_pid = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = waitid(idtype, id, &si, options); + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res < 0) + return (!async_err) ? posix_error() : NULL; + + if (si.si_pid == 0) + Py_RETURN_NONE; + + PyObject *WaitidResultType = get_posix_state(module)->WaitidResultType; + result = PyStructSequence_New((PyTypeObject *)WaitidResultType); + if (!result) + return NULL; + + PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid)); + PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid)); + PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo))); + PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status))); + PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code))); + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } + + return result; +} +#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */ + + +#if defined(HAVE_WAITPID) +/*[clinic input] +os.waitpid + pid: pid_t + options: int + / + +Wait for completion of a given child process. + +Returns a tuple of information regarding the child process: + (pid, status) + +The options argument is ignored on Windows. +[clinic start generated code]*/ + +static PyObject * +os_waitpid_impl(PyObject *module, pid_t pid, int options) +/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/ +{ + pid_t res; + int async_err = 0; + WAIT_TYPE status; + WAIT_STATUS_INT(status) = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = waitpid(pid, &status, options); + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res < 0) + return (!async_err) ? posix_error() : NULL; + + return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status)); +} +#elif defined(HAVE_CWAIT) +/* MS C has a variant of waitpid() that's usable for most purposes. */ +/*[clinic input] +os.waitpid + pid: intptr_t + options: int + / + +Wait for completion of a given process. + +Returns a tuple of information regarding the process: + (pid, status << 8) + +The options argument is ignored on Windows. +[clinic start generated code]*/ + +static PyObject * +os_waitpid_impl(PyObject *module, intptr_t pid, int options) +/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/ +{ + int status; + intptr_t res; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + res = _cwait(&status, pid, options); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res < 0) + return (!async_err) ? posix_error() : NULL; + + unsigned long long ustatus = (unsigned int)status; + /* shift the status left a byte so this is more like the POSIX waitpid */ + return Py_BuildValue(_Py_PARSE_INTPTR "K", res, ustatus << 8); +} +#endif + + +#ifdef HAVE_WAIT +/*[clinic input] +os.wait + +Wait for completion of a child process. + +Returns a tuple of information about the child process: + (pid, status) +[clinic start generated code]*/ + +static PyObject * +os_wait_impl(PyObject *module) +/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/ +{ + pid_t pid; + int async_err = 0; + WAIT_TYPE status; + WAIT_STATUS_INT(status) = 0; + + do { + Py_BEGIN_ALLOW_THREADS + pid = wait(&status); + Py_END_ALLOW_THREADS + } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (pid < 0) + return (!async_err) ? posix_error() : NULL; + + return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); +} +#endif /* HAVE_WAIT */ + +#if defined(__linux__) && defined(__NR_pidfd_open) /*[clinic input] -os.DirEntry.__fspath__ +os.pidfd_open + pid: pid_t + flags: unsigned_int = 0 + +Return a file descriptor referring to the process *pid*. -Returns the path for the entry. +The descriptor can be used to perform process management without races and +signals. [clinic start generated code]*/ static PyObject * -os_DirEntry___fspath___impl(DirEntry *self) -/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/ +os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags) +/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/ { - Py_INCREF(self->path); - return self->path; + int fd = syscall(__NR_pidfd_open, pid, flags); + if (fd < 0) { + return posix_error(); + } + return PyLong_FromLong(fd); } +#endif -static PyMemberDef DirEntry_members[] = { - {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY, - "the entry's base filename, relative to scandir() \"path\" argument"}, - {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY, - "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"}, - {NULL} -}; - -#include "clinic/posixmodule.c.h" - -static PyMethodDef DirEntry_methods[] = { - OS_DIRENTRY_IS_DIR_METHODDEF - OS_DIRENTRY_IS_FILE_METHODDEF - OS_DIRENTRY_IS_SYMLINK_METHODDEF - OS_DIRENTRY_STAT_METHODDEF - OS_DIRENTRY_INODE_METHODDEF - OS_DIRENTRY___FSPATH___METHODDEF - {"__class_getitem__", (PyCFunction)Py_GenericAlias, - METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {NULL} -}; - -static PyType_Slot DirEntryType_slots[] = { - {Py_tp_new, _disabled_new}, - {Py_tp_dealloc, DirEntry_dealloc}, - {Py_tp_repr, DirEntry_repr}, - {Py_tp_methods, DirEntry_methods}, - {Py_tp_members, DirEntry_members}, - {0, 0}, -}; -static PyType_Spec DirEntryType_spec = { - MODNAME ".DirEntry", - sizeof(DirEntry), - 0, - Py_TPFLAGS_DEFAULT, - DirEntryType_slots -}; +#if defined(HAVE_READLINK) || defined(MS_WINDOWS) +/*[clinic input] +os.readlink + + path: path_t + * + dir_fd: dir_fd(requires='readlinkat') = None + +Return a string representing the path to which the symbolic link points. +If dir_fd is not None, it should be a file descriptor open to a directory, +and path should be relative; path will then be relative to that directory. -#ifdef MS_WINDOWS +dir_fd may not be implemented on your platform. If it is unavailable, +using it will raise a NotImplementedError. +[clinic start generated code]*/ -static wchar_t * -join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename) -{ - Py_ssize_t path_len; - Py_ssize_t size; - wchar_t *result; - wchar_t ch; +static PyObject * +os_readlink_impl(PyObject *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=d21b732a2e814030 input=113c87e0db1ecaf2]*/ +{ +#if defined(HAVE_READLINK) + char buffer[MAXPATHLEN+1]; + ssize_t length; +#ifdef HAVE_READLINKAT + int readlinkat_unavailable = 0; +#endif + + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_READLINKAT + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_READLINKAT_RUNTIME) { + length = readlinkat(dir_fd, path->narrow, buffer, MAXPATHLEN); + } else { + readlinkat_unavailable = 1; + } + } else +#endif + length = readlink(path->narrow, buffer, MAXPATHLEN); + Py_END_ALLOW_THREADS + +#ifdef HAVE_READLINKAT + if (readlinkat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif - if (!path_wide) { /* Default arg: "." */ - path_wide = L"."; - path_len = 1; + if (length < 0) { + return path_error(path); + } + buffer[length] = '\0'; + + if (PyUnicode_Check(path->object)) + return PyUnicode_DecodeFSDefaultAndSize(buffer, length); + else + return PyBytes_FromStringAndSize(buffer, length); +#elif defined(MS_WINDOWS) + DWORD n_bytes_returned; + DWORD io_result = 0; + HANDLE reparse_point_handle; + char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; + PyObject *result = NULL; + + /* First get a handle to the reparse point */ + Py_BEGIN_ALLOW_THREADS + reparse_point_handle = CreateFileW( + path->wide, + 0, + 0, + 0, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, + 0); + if (reparse_point_handle != INVALID_HANDLE_VALUE) { + /* New call DeviceIoControl to read the reparse point */ + io_result = DeviceIoControl( + reparse_point_handle, + FSCTL_GET_REPARSE_POINT, + 0, 0, /* in buffer */ + target_buffer, sizeof(target_buffer), + &n_bytes_returned, + 0 /* we're not using OVERLAPPED_IO */ + ); + CloseHandle(reparse_point_handle); } - else { - path_len = wcslen(path_wide); + Py_END_ALLOW_THREADS + + if (io_result == 0) { + return path_error(path); } - - /* The +1's are for the path separator and the NUL */ - size = path_len + 1 + wcslen(filename) + 1; - result = PyMem_New(wchar_t, size); - if (!result) { - PyErr_NoMemory(); - return NULL; + + wchar_t *name = NULL; + Py_ssize_t nameLen = 0; + if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) + { + name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer + + rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset); + nameLen = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); + } + else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) + { + name = (wchar_t *)((char*)rdb->MountPointReparseBuffer.PathBuffer + + rdb->MountPointReparseBuffer.SubstituteNameOffset); + nameLen = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t); + } + else + { + PyErr_SetString(PyExc_ValueError, "not a symbolic link"); } - wcscpy(result, path_wide); - if (path_len > 0) { - ch = result[path_len - 1]; - if (ch != SEP && ch != ALTSEP && ch != L':') - result[path_len++] = SEP; - wcscpy(result + path_len, filename); + if (name) { + if (nameLen > 4 && wcsncmp(name, L"\\??\\", 4) == 0) { + /* Our buffer is mutable, so this is okay */ + name[1] = L'\\'; + } + result = PyUnicode_FromWideChar(name, nameLen); + if (result && path->narrow) { + Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); + } } - return result; -} + return result; +#endif +} +#endif /* defined(HAVE_READLINK) || defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +/* Remove the last portion of the path - return 0 on success */ +static int +_dirnameW(WCHAR *path) +{ + WCHAR *ptr; + size_t length = wcsnlen_s(path, MAX_PATH); + if (length == MAX_PATH) { + return -1; + } + + /* walk the path from the end until a backslash is encountered */ + for(ptr = path + length; ptr != path; ptr--) { + if (*ptr == L'\\' || *ptr == L'/') { + break; + } + } + *ptr = 0; + return 0; +} + +#endif -static PyObject * -DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW) -{ - DirEntry *entry; - BY_HANDLE_FILE_INFORMATION file_info; - ULONG reparse_tag; - wchar_t *joined_path; +#ifdef HAVE_SYMLINK - PyObject *DirEntryType = get_posix_state(module)->DirEntryType; - entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); - if (!entry) - return NULL; - entry->name = NULL; - entry->path = NULL; - entry->stat = NULL; - entry->lstat = NULL; - entry->got_file_index = 0; - - entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1); - if (!entry->name) - goto error; - if (path->narrow) { - Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name)); - if (!entry->name) - goto error; - } +#if defined(MS_WINDOWS) - joined_path = join_path_filenameW(path->wide, dataW->cFileName); - if (!joined_path) - goto error; +/* Is this path absolute? */ +static int +_is_absW(const WCHAR *path) +{ + return path[0] == L'\\' || path[0] == L'/' || + (path[0] && path[1] == L':'); +} + +/* join root and rest with a backslash - return 0 on success */ +static int +_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) +{ + if (_is_absW(rest)) { + return wcscpy_s(dest_path, MAX_PATH, rest); + } + + if (wcscpy_s(dest_path, MAX_PATH, root)) { + return -1; + } + + if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) { + return -1; + } + + return wcscat_s(dest_path, MAX_PATH, rest); +} + +/* Return True if the path at src relative to dest is a directory */ +static int +_check_dirW(LPCWSTR src, LPCWSTR dest) +{ + WIN32_FILE_ATTRIBUTE_DATA src_info; + WCHAR dest_parent[MAX_PATH]; + WCHAR src_resolved[MAX_PATH] = L""; + + /* dest_parent = os.path.dirname(dest) */ + if (wcscpy_s(dest_parent, MAX_PATH, dest) || + _dirnameW(dest_parent)) { + return 0; + } + /* src_resolved = os.path.join(dest_parent, src) */ + if (_joinW(src_resolved, dest_parent, src)) { + return 0; + } + return ( + GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info) + && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY + ); +} +#endif + + +/*[clinic input] +os.symlink + src: path_t + dst: path_t + target_is_directory: bool = False + * + dir_fd: dir_fd(requires='symlinkat')=None + +# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\ + +Create a symbolic link pointing to src named dst. + +target_is_directory is required on Windows if the target is to be + interpreted as a directory. (On Windows, symlink requires + Windows 6.0 or greater, and raises a NotImplementedError otherwise.) + target_is_directory is ignored on non-Windows platforms. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +static PyObject * +os_symlink_impl(PyObject *module, path_t *src, path_t *dst, + int target_is_directory, int dir_fd) +/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/ +{ +#ifdef MS_WINDOWS + DWORD result; + DWORD flags = 0; - entry->path = PyUnicode_FromWideChar(joined_path, -1); - PyMem_Free(joined_path); - if (!entry->path) - goto error; - if (path->narrow) { - Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path)); - if (!entry->path) - goto error; + /* Assumed true, set to false if detected to not be available. */ + static int windows_has_symlink_unprivileged_flag = TRUE; +#else + int result; +#ifdef HAVE_SYMLINKAT + int symlinkat_unavailable = 0; +#endif +#endif + + if (PySys_Audit("os.symlink", "OOi", src->object, dst->object, + dir_fd == DEFAULT_DIR_FD ? -1 : dir_fd) < 0) { + return NULL; + } + +#ifdef MS_WINDOWS + + if (windows_has_symlink_unprivileged_flag) { + /* Allow non-admin symlinks if system allows it. */ + flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; + } + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + /* if src is a directory, ensure flags==1 (target_is_directory bit) */ + if (target_is_directory || _check_dirW(src->wide, dst->wide)) { + flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; } - find_data_to_file_info(dataW, &file_info, &reparse_tag); - _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat); - - return (PyObject *)entry; + result = CreateSymbolicLinkW(dst->wide, src->wide, flags); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + if (windows_has_symlink_unprivileged_flag && !result && + ERROR_INVALID_PARAMETER == GetLastError()) { -error: - Py_DECREF(entry); - return NULL; -} + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + /* This error might be caused by + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported. + Try again, and update windows_has_symlink_unprivileged_flag if we + are successful this time. -#else /* POSIX */ + NOTE: There is a risk of a race condition here if there are other + conditions than the flag causing ERROR_INVALID_PARAMETER, and + another process (or thread) changes that condition in between our + calls to CreateSymbolicLink. + */ + flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); + result = CreateSymbolicLinkW(dst->wide, src->wide, flags); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS -static char * -join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len) -{ - Py_ssize_t path_len; - Py_ssize_t size; - char *result; + if (result || ERROR_INVALID_PARAMETER != GetLastError()) { + windows_has_symlink_unprivileged_flag = FALSE; + } + } - if (!path_narrow) { /* Default arg: "." */ - path_narrow = "."; - path_len = 1; + if (!result) + return path_error2(src, dst); + +#else + + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { + PyErr_SetString(PyExc_ValueError, + "symlink: src and dst must be the same type"); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_SYMLINKAT + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_SYMLINKAT_RUNTIME) { + result = symlinkat(src->narrow, dir_fd, dst->narrow); + } else { + symlinkat_unavailable = 1; + } + } else +#endif + result = symlink(src->narrow, dst->narrow); + Py_END_ALLOW_THREADS + +#ifdef HAVE_SYMLINKAT + if (symlinkat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; } - else { - path_len = strlen(path_narrow); +#endif + + if (result) + return path_error2(src, dst); +#endif + + Py_RETURN_NONE; +} +#endif /* HAVE_SYMLINK */ + + + + +static PyStructSequence_Field times_result_fields[] = { + {"user", "user time"}, + {"system", "system time"}, + {"children_user", "user time of children"}, + {"children_system", "system time of children"}, + {"elapsed", "elapsed time since an arbitrary point in the past"}, + {NULL} +}; + +PyDoc_STRVAR(times_result__doc__, +"times_result: Result from os.times().\n\n\ +This object may be accessed either as a tuple of\n\ + (user, system, children_user, children_system, elapsed),\n\ +or via the attributes user, system, children_user, children_system,\n\ +and elapsed.\n\ +\n\ +See os.times for more information."); + +static PyStructSequence_Desc times_result_desc = { + "times_result", /* name */ + times_result__doc__, /* doc */ + times_result_fields, + 5 +}; + +#ifdef MS_WINDOWS +#define HAVE_TIMES /* mandatory, for the method table */ +#endif + +#ifdef HAVE_TIMES + +static PyObject * +build_times_result(PyObject *module, double user, double system, + double children_user, double children_system, + double elapsed) +{ + PyObject *TimesResultType = get_posix_state(module)->TimesResultType; + PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType); + if (value == NULL) + return NULL; + +#define SET(i, field) \ + { \ + PyObject *o = PyFloat_FromDouble(field); \ + if (!o) { \ + Py_DECREF(value); \ + return NULL; \ + } \ + PyStructSequence_SET_ITEM(value, i, o); \ + } \ + + SET(0, user); + SET(1, system); + SET(2, children_user); + SET(3, children_system); + SET(4, elapsed); + +#undef SET + + return value; +} + + +#ifndef MS_WINDOWS +#define NEED_TICKS_PER_SECOND +static long ticks_per_second = -1; +#endif /* MS_WINDOWS */ + +/*[clinic input] +os.times + +Return a collection containing process timing information. + +The object returned behaves like a named tuple with these fields: + (utime, stime, cutime, cstime, elapsed_time) +All fields are floating point numbers. +[clinic start generated code]*/ + +static PyObject * +os_times_impl(PyObject *module) +/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/ +#ifdef MS_WINDOWS +{ + FILETIME create, exit, kernel, user; + HANDLE hProc; + hProc = GetCurrentProcess(); + GetProcessTimes(hProc, &create, &exit, &kernel, &user); + /* The fields of a FILETIME structure are the hi and lo part + of a 64-bit value expressed in 100 nanosecond units. + 1e7 is one second in such units; 1e-7 the inverse. + 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. + */ + return build_times_result(module, + (double)(user.dwHighDateTime*429.4967296 + + user.dwLowDateTime*1e-7), + (double)(kernel.dwHighDateTime*429.4967296 + + kernel.dwLowDateTime*1e-7), + (double)0, + (double)0, + (double)0); +} +#else /* MS_WINDOWS */ +{ + + + struct tms t; + clock_t c; + errno = 0; + c = times(&t); + if (c == (clock_t) -1) + return posix_error(); + return build_times_result(module, + (double)t.tms_utime / ticks_per_second, + (double)t.tms_stime / ticks_per_second, + (double)t.tms_cutime / ticks_per_second, + (double)t.tms_cstime / ticks_per_second, + (double)c / ticks_per_second); +} +#endif /* MS_WINDOWS */ +#endif /* HAVE_TIMES */ + + +#ifdef HAVE_GETSID +/*[clinic input] +os.getsid + + pid: pid_t + / + +Call the system call getsid(pid) and return the result. +[clinic start generated code]*/ + +static PyObject * +os_getsid_impl(PyObject *module, pid_t pid) +/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/ +{ + int sid; + sid = getsid(pid); + if (sid < 0) + return posix_error(); + return PyLong_FromLong((long)sid); +} +#endif /* HAVE_GETSID */ + + +#ifdef HAVE_SETSID +/*[clinic input] +os.setsid + +Call the system call setsid(). +[clinic start generated code]*/ + +static PyObject * +os_setsid_impl(PyObject *module) +/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/ +{ + if (setsid() < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETSID */ + + +#ifdef HAVE_SETPGID +/*[clinic input] +os.setpgid + + pid: pid_t + pgrp: pid_t + / + +Call the system call setpgid(pid, pgrp). +[clinic start generated code]*/ + +static PyObject * +os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp) +/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/ +{ + if (setpgid(pid, pgrp) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETPGID */ + + +#ifdef HAVE_TCGETPGRP +/*[clinic input] +os.tcgetpgrp + + fd: int + / + +Return the process group associated with the terminal specified by fd. +[clinic start generated code]*/ + +static PyObject * +os_tcgetpgrp_impl(PyObject *module, int fd) +/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/ +{ + pid_t pgid = tcgetpgrp(fd); + if (pgid < 0) + return posix_error(); + return PyLong_FromPid(pgid); +} +#endif /* HAVE_TCGETPGRP */ + + +#ifdef HAVE_TCSETPGRP +/*[clinic input] +os.tcsetpgrp + + fd: int + pgid: pid_t + / + +Set the process group associated with the terminal specified by fd. +[clinic start generated code]*/ + +static PyObject * +os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid) +/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/ +{ + if (tcsetpgrp(fd, pgid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_TCSETPGRP */ + +/* Functions acting on file descriptors */ + +#ifdef O_CLOEXEC +extern int _Py_open_cloexec_works; +#endif + + +/*[clinic input] +os.open -> int + path: path_t + flags: int + mode: int = 0o777 + * + dir_fd: dir_fd(requires='openat') = None + +# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ + +Open a file for low level IO. Returns a file descriptor (integer). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +static int +os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd) +/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/ +{ + int fd; + int async_err = 0; +#ifdef HAVE_OPENAT + int openat_unavailable = 0; +#endif + +#ifdef O_CLOEXEC + int *atomic_flag_works = &_Py_open_cloexec_works; +#elif !defined(MS_WINDOWS) + int *atomic_flag_works = NULL; +#endif + +#ifdef MS_WINDOWS + flags |= O_NOINHERIT; +#elif defined(O_CLOEXEC) + flags |= O_CLOEXEC; +#endif + + if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) { + return -1; } - if (filename_len == -1) - filename_len = strlen(filename); + _Py_BEGIN_SUPPRESS_IPH + do { + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + fd = _wopen(path->wide, flags, mode); +#else +#ifdef HAVE_OPENAT + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_OPENAT_RUNTIME) { + fd = openat(dir_fd, path->narrow, flags, mode); - /* The +1's are for the path separator and the NUL */ - size = path_len + 1 + filename_len + 1; - result = PyMem_New(char, size); - if (!result) { - PyErr_NoMemory(); - return NULL; + } else { + openat_unavailable = 1; + fd = -1; + } + } else +#endif /* HAVE_OPENAT */ + fd = open(path->narrow, flags, mode); +#endif /* !MS_WINDOWS */ + Py_END_ALLOW_THREADS + } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + _Py_END_SUPPRESS_IPH + +#ifdef HAVE_OPENAT + if (openat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return -1; } - strcpy(result, path_narrow); - if (path_len > 0 && result[path_len - 1] != '/') - result[path_len++] = '/'; - strcpy(result + path_len, filename); - return result; -} - -static PyObject * -DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, - Py_ssize_t name_len, ino_t d_ino -#ifdef HAVE_DIRENT_D_TYPE - , unsigned char d_type #endif - ) -{ - DirEntry *entry; - char *joined_path; - PyObject *DirEntryType = get_posix_state(module)->DirEntryType; - entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); - if (!entry) - return NULL; - entry->name = NULL; - entry->path = NULL; - entry->stat = NULL; - entry->lstat = NULL; + if (fd < 0) { + if (!async_err) + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); + return -1; + } + +#ifndef MS_WINDOWS + if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { + close(fd); + return -1; + } +#endif + + return fd; +} + + +/*[clinic input] +os.close + + fd: int + +Close a file descriptor. +[clinic start generated code]*/ + +static PyObject * +os_close_impl(PyObject *module, int fd) +/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/ +{ + int res; + /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/ + * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html + * for more details. + */ + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + res = close(fd); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + if (res < 0) + return posix_error(); + Py_RETURN_NONE; +} + + +#ifdef HAVE_FDWALK +static int +_fdwalk_close_func(void *lohi, int fd) +{ + int lo = ((int *)lohi)[0]; + int hi = ((int *)lohi)[1]; - if (path->fd != -1) { - entry->dir_fd = path->fd; - joined_path = NULL; + if (fd >= hi) { + return 1; } - else { - entry->dir_fd = DEFAULT_DIR_FD; - joined_path = join_path_filename(path->narrow, name, name_len); - if (!joined_path) - goto error; + else if (fd >= lo) { + /* Ignore errors */ + (void)close(fd); } + return 0; +} +#endif /* HAVE_FDWALK */ - if (!path->narrow || !PyObject_CheckBuffer(path->object)) { - entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); - if (joined_path) - entry->path = PyUnicode_DecodeFSDefault(joined_path); +/*[clinic input] +os.closerange + + fd_low: int + fd_high: int + / + +Closes all file descriptors in [fd_low, fd_high), ignoring errors. +[clinic start generated code]*/ + +static PyObject * +os_closerange_impl(PyObject *module, int fd_low, int fd_high) +/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/ +{ +#ifdef HAVE_FDWALK + int lohi[2]; +#endif + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef HAVE_FDWALK + lohi[0] = Py_MAX(fd_low, 0); + lohi[1] = fd_high; + fdwalk(_fdwalk_close_func, lohi); +#else + fd_low = Py_MAX(fd_low, 0); +#ifdef __FreeBSD__ + if (fd_high >= sysconf(_SC_OPEN_MAX)) { + /* Any errors encountered while closing file descriptors are ignored */ + closefrom(fd_low); } - else { - entry->name = PyBytes_FromStringAndSize(name, name_len); - if (joined_path) - entry->path = PyBytes_FromString(joined_path); + else +#endif + { + for (int i = fd_low; i < fd_high; i++) { + /* Ignore errors */ + (void)close(i); + } } - PyMem_Free(joined_path); - if (!entry->name) - goto error; - - if (path->fd != -1) { - entry->path = entry->name; - Py_INCREF(entry->path); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + Py_RETURN_NONE; +} + + +/*[clinic input] +os.dup -> int + + fd: int + / + +Return a duplicate of a file descriptor. +[clinic start generated code]*/ + +static int +os_dup_impl(PyObject *module, int fd) +/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/ +{ + return _Py_dup(fd); +} + + +/*[clinic input] +os.dup2 -> int + fd: int + fd2: int + inheritable: bool=True + +Duplicate file descriptor. +[clinic start generated code]*/ + +static int +os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable) +/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/ +{ + int res = 0; +#if defined(HAVE_DUP3) && \ + !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)) + /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */ + static int dup3_works = -1; +#endif + + if (fd < 0 || fd2 < 0) { + posix_error(); + return -1; + } + + /* dup2() can fail with EINTR if the target FD is already open, because it + * then has to be closed. See os_close_impl() for why we don't handle EINTR + * upon close(), and therefore below. + */ +#ifdef MS_WINDOWS + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + res = dup2(fd, fd2); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + if (res < 0) { + posix_error(); + return -1; + } + res = fd2; // msvcrt dup2 returns 0 on success. + + /* Character files like console cannot be make non-inheritable */ + if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { + close(fd2); + return -1; + } + +#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC) + Py_BEGIN_ALLOW_THREADS + if (!inheritable) + res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2); + else + res = dup2(fd, fd2); + Py_END_ALLOW_THREADS + if (res < 0) { + posix_error(); + return -1; + } + +#else + +#ifdef HAVE_DUP3 + if (!inheritable && dup3_works != 0) { + Py_BEGIN_ALLOW_THREADS + res = dup3(fd, fd2, O_CLOEXEC); + Py_END_ALLOW_THREADS + if (res < 0) { + if (dup3_works == -1) + dup3_works = (errno != ENOSYS); + if (dup3_works) { + posix_error(); + return -1; + } + } + } + + if (inheritable || dup3_works == 0) + { +#endif + Py_BEGIN_ALLOW_THREADS + res = dup2(fd, fd2); + Py_END_ALLOW_THREADS + if (res < 0) { + posix_error(); + return -1; + } + + if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { + close(fd2); + return -1; + } +#ifdef HAVE_DUP3 + } +#endif + +#endif + + return res; +} + + +#ifdef HAVE_LOCKF +/*[clinic input] +os.lockf + + fd: int + An open file descriptor. + command: int + One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST. + length: Py_off_t + The number of bytes to lock, starting at the current position. + / + +Apply, test or remove a POSIX lock on an open file descriptor. + +[clinic start generated code]*/ + +static PyObject * +os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length) +/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/ +{ + int res; + + if (PySys_Audit("os.lockf", "iiL", fd, command, length) < 0) { + return NULL; } - else if (!entry->path) - goto error; -#ifdef HAVE_DIRENT_D_TYPE - entry->d_type = d_type; + Py_BEGIN_ALLOW_THREADS + res = lockf(fd, command, length); + Py_END_ALLOW_THREADS + + if (res < 0) + return posix_error(); + + Py_RETURN_NONE; +} +#endif /* HAVE_LOCKF */ + + +/*[clinic input] +os.lseek -> Py_off_t + + fd: int + position: Py_off_t + how: int + / + +Set the position of a file descriptor. Return the new position. + +Return the new cursor position in number of bytes +relative to the beginning of the file. +[clinic start generated code]*/ + +static Py_off_t +os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) +/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/ +{ + Py_off_t result; + +#ifdef SEEK_SET + /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ + switch (how) { + case 0: how = SEEK_SET; break; + case 1: how = SEEK_CUR; break; + case 2: how = SEEK_END; break; + } +#endif /* SEEK_END */ + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef MS_WINDOWS + result = _lseeki64(fd, position, how); +#else + result = lseek(fd, position, how); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + if (result < 0) + posix_error(); + + return result; +} + + +/*[clinic input] +os.read + fd: int + length: Py_ssize_t + / + +Read from a file descriptor. Returns a bytes object. +[clinic start generated code]*/ + +static PyObject * +os_read_impl(PyObject *module, int fd, Py_ssize_t length) +/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/ +{ + Py_ssize_t n; + PyObject *buffer; + + if (length < 0) { + errno = EINVAL; + return posix_error(); + } + + length = Py_MIN(length, _PY_READ_MAX); + + buffer = PyBytes_FromStringAndSize((char *)NULL, length); + if (buffer == NULL) + return NULL; + + n = _Py_read(fd, PyBytes_AS_STRING(buffer), length); + if (n == -1) { + Py_DECREF(buffer); + return NULL; + } + + if (n != length) + _PyBytes_Resize(&buffer, n); + + return buffer; +} + +#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \ + || defined(__APPLE__))) \ + || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \ + || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2) +static int +iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type) +{ + Py_ssize_t i, j; + + *iov = PyMem_New(struct iovec, cnt); + if (*iov == NULL) { + PyErr_NoMemory(); + return -1; + } + + *buf = PyMem_New(Py_buffer, cnt); + if (*buf == NULL) { + PyMem_Del(*iov); + PyErr_NoMemory(); + return -1; + } + + for (i = 0; i < cnt; i++) { + PyObject *item = PySequence_GetItem(seq, i); + if (item == NULL) + goto fail; + if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) { + Py_DECREF(item); + goto fail; + } + Py_DECREF(item); + (*iov)[i].iov_base = (*buf)[i].buf; + (*iov)[i].iov_len = (*buf)[i].len; + } + return 0; + +fail: + PyMem_Del(*iov); + for (j = 0; j < i; j++) { + PyBuffer_Release(&(*buf)[j]); + } + PyMem_Del(*buf); + return -1; +} + +static void +iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt) +{ + int i; + PyMem_Del(iov); + for (i = 0; i < cnt; i++) { + PyBuffer_Release(&buf[i]); + } + PyMem_Del(buf); +} +#endif + + +#ifdef HAVE_READV +/*[clinic input] +os.readv -> Py_ssize_t + + fd: int + buffers: object + / + +Read from a file descriptor fd into an iterable of buffers. + +The buffers should be mutable buffers accepting bytes. +readv will transfer data into each buffer until it is full +and then move on to the next buffer in the sequence to hold +the rest of the data. + +readv returns the total number of bytes read, +which may be less than the total capacity of all the buffers. +[clinic start generated code]*/ + +static Py_ssize_t +os_readv_impl(PyObject *module, int fd, PyObject *buffers) +/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/ +{ + Py_ssize_t cnt, n; + int async_err = 0; + struct iovec *iov; + Py_buffer *buf; + + if (!PySequence_Check(buffers)) { + PyErr_SetString(PyExc_TypeError, + "readv() arg 2 must be a sequence"); + return -1; + } + + cnt = PySequence_Size(buffers); + if (cnt < 0) + return -1; + + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) + return -1; + + do { + Py_BEGIN_ALLOW_THREADS + n = readv(fd, iov, cnt); + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + iov_cleanup(iov, buf, cnt); + if (n < 0) { + if (!async_err) + posix_error(); + return -1; + } + + return n; +} +#endif /* HAVE_READV */ + + +#ifdef HAVE_PREAD +/*[clinic input] +os.pread + + fd: int + length: Py_ssize_t + offset: Py_off_t + / + +Read a number of bytes from a file descriptor starting at a particular offset. + +Read length bytes from file descriptor fd, starting at offset bytes from +the beginning of the file. The file offset remains unchanged. +[clinic start generated code]*/ + +static PyObject * +os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset) +/*[clinic end generated code: output=3f875c1eef82e32f input=85cb4a5589627144]*/ +{ + Py_ssize_t n; + int async_err = 0; + PyObject *buffer; + + if (length < 0) { + errno = EINVAL; + return posix_error(); + } + buffer = PyBytes_FromStringAndSize((char *)NULL, length); + if (buffer == NULL) + return NULL; + + do { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + n = pread(fd, PyBytes_AS_STRING(buffer), length, offset); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (n < 0) { + Py_DECREF(buffer); + return (!async_err) ? posix_error() : NULL; + } + if (n != length) + _PyBytes_Resize(&buffer, n); + return buffer; +} +#endif /* HAVE_PREAD */ + +#if defined(HAVE_PREADV) || defined (HAVE_PREADV2) +/*[clinic input] +os.preadv -> Py_ssize_t + + fd: int + buffers: object + offset: Py_off_t + flags: int = 0 + / + +Reads from a file descriptor into a number of mutable bytes-like objects. + +Combines the functionality of readv() and pread(). As readv(), it will +transfer data into each buffer until it is full and then move on to the next +buffer in the sequence to hold the rest of the data. Its fourth argument, +specifies the file offset at which the input operation is to be performed. It +will return the total number of bytes read (which can be less than the total +capacity of all the objects). + +The flags argument contains a bitwise OR of zero or more of the following flags: + +- RWF_HIPRI +- RWF_NOWAIT + +Using non-zero flags requires Linux 4.6 or newer. +[clinic start generated code]*/ + +static Py_ssize_t +os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, + int flags) +/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/ +{ + Py_ssize_t cnt, n; + int async_err = 0; + struct iovec *iov; + Py_buffer *buf; + + if (!PySequence_Check(buffers)) { + PyErr_SetString(PyExc_TypeError, + "preadv2() arg 2 must be a sequence"); + return -1; + } + + cnt = PySequence_Size(buffers); + if (cnt < 0) { + return -1; + } + +#ifndef HAVE_PREADV2 + if(flags != 0) { + argument_unavailable_error("preadv2", "flags"); + return -1; + } +#endif + + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) { + return -1; + } +#ifdef HAVE_PREADV2 + do { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + n = preadv2(fd, iov, cnt, offset, flags); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#else + do { +#ifdef __APPLE__ +/* This entire function will be removed from the module dict when the API + * is not available. + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" +#pragma clang diagnostic ignored "-Wunguarded-availability-new" #endif - entry->d_ino = d_ino; - - return (PyObject *)entry; - -error: - Py_XDECREF(entry); - return NULL; -} + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + n = preadv(fd, iov, cnt, offset); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#endif +#ifdef __APPLE__ +#pragma clang diagnostic pop +#endif + +#endif + + iov_cleanup(iov, buf, cnt); + if (n < 0) { + if (!async_err) { + posix_error(); + } + return -1; + } + + return n; +} +#endif /* HAVE_PREADV */ + + +/*[clinic input] +os.write -> Py_ssize_t + + fd: int + data: Py_buffer + / + +Write a bytes object to a file descriptor. +[clinic start generated code]*/ + +static Py_ssize_t +os_write_impl(PyObject *module, int fd, Py_buffer *data) +/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/ +{ + return _Py_write(fd, data->buf, data->len); +} + +#ifdef HAVE_SENDFILE +#ifdef __APPLE__ +/*[clinic input] +os.sendfile + + out_fd: int + in_fd: int + offset: Py_off_t + count as sbytes: Py_off_t + headers: object(c_default="NULL") = () + trailers: object(c_default="NULL") = () + flags: int = 0 +Copy count bytes from file descriptor in_fd to file descriptor out_fd. +[clinic start generated code]*/ -typedef struct { - PyObject_HEAD - path_t path; -#ifdef MS_WINDOWS - HANDLE handle; - WIN32_FIND_DATAW file_data; - int first_time; -#else /* POSIX */ - DIR *dirp; -#endif -#ifdef HAVE_FDOPENDIR - int fd; -#endif -} ScandirIterator; +static PyObject * +os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, + Py_off_t sbytes, PyObject *headers, PyObject *trailers, + int flags) +/*[clinic end generated code: output=81c4bcd143f5c82b input=b0d72579d4c69afa]*/ +#elif defined(__FreeBSD__) || defined(__DragonFly__) +/*[clinic input] +os.sendfile -#ifdef MS_WINDOWS + out_fd: int + in_fd: int + offset: Py_off_t + count: Py_ssize_t + headers: object(c_default="NULL") = () + trailers: object(c_default="NULL") = () + flags: int = 0 -static int -ScandirIterator_is_closed(ScandirIterator *iterator) -{ - return iterator->handle == INVALID_HANDLE_VALUE; -} +Copy count bytes from file descriptor in_fd to file descriptor out_fd. +[clinic start generated code]*/ -static void -ScandirIterator_closedir(ScandirIterator *iterator) -{ - HANDLE handle = iterator->handle; +static PyObject * +os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, + Py_ssize_t count, PyObject *headers, PyObject *trailers, + int flags) +/*[clinic end generated code: output=329ea009bdd55afc input=338adb8ff84ae8cd]*/ +#else +/*[clinic input] +os.sendfile - if (handle == INVALID_HANDLE_VALUE) - return; + out_fd: int + in_fd: int + offset as offobj: object + count: Py_ssize_t - iterator->handle = INVALID_HANDLE_VALUE; - Py_BEGIN_ALLOW_THREADS - FindClose(handle); - Py_END_ALLOW_THREADS -} +Copy count bytes from file descriptor in_fd to file descriptor out_fd. +[clinic start generated code]*/ static PyObject * -ScandirIterator_iternext(ScandirIterator *iterator) -{ - WIN32_FIND_DATAW *file_data = &iterator->file_data; - BOOL success; - PyObject *entry; - - /* Happens if the iterator is iterated twice, or closed explicitly */ - if (iterator->handle == INVALID_HANDLE_VALUE) - return NULL; - - while (1) { - if (!iterator->first_time) { - Py_BEGIN_ALLOW_THREADS - success = FindNextFileW(iterator->handle, file_data); - Py_END_ALLOW_THREADS - if (!success) { - /* Error or no more files */ - if (GetLastError() != ERROR_NO_MORE_FILES) - path_error(&iterator->path); - break; - } - } - iterator->first_time = 0; +os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, + Py_ssize_t count) +/*[clinic end generated code: output=ae81216e40f167d8 input=76d64058c74477ba]*/ +#endif +{ + Py_ssize_t ret; + int async_err = 0; + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#ifndef __APPLE__ + off_t sbytes; +#endif + Py_buffer *hbuf, *tbuf; + struct sf_hdtr sf; + + sf.headers = NULL; + sf.trailers = NULL; + + if (headers != NULL) { + if (!PySequence_Check(headers)) { + PyErr_SetString(PyExc_TypeError, + "sendfile() headers must be a sequence"); + return NULL; + } else { + Py_ssize_t i = PySequence_Size(headers); + if (i < 0) + return NULL; + if (i > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "sendfile() header is too large"); + return NULL; + } + if (i > 0) { + sf.hdr_cnt = (int)i; + if (iov_setup(&(sf.headers), &hbuf, + headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0) + return NULL; +#ifdef __APPLE__ + for (i = 0; i < sf.hdr_cnt; i++) { + Py_ssize_t blen = sf.headers[i].iov_len; +# define OFF_T_MAX 0x7fffffffffffffff + if (sbytes >= OFF_T_MAX - blen) { + PyErr_SetString(PyExc_OverflowError, + "sendfile() header is too large"); + return NULL; + } + sbytes += blen; + } +#endif + } + } + } + if (trailers != NULL) { + if (!PySequence_Check(trailers)) { + PyErr_SetString(PyExc_TypeError, + "sendfile() trailers must be a sequence"); + return NULL; + } else { + Py_ssize_t i = PySequence_Size(trailers); + if (i < 0) + return NULL; + if (i > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "sendfile() trailer is too large"); + return NULL; + } + if (i > 0) { + sf.trl_cnt = (int)i; + if (iov_setup(&(sf.trailers), &tbuf, + trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0) + return NULL; + } + } + } + + _Py_BEGIN_SUPPRESS_IPH + do { + Py_BEGIN_ALLOW_THREADS +#ifdef __APPLE__ + ret = sendfile(in_fd, out_fd, offset, &sbytes, &sf, flags); +#else + ret = sendfile(in_fd, out_fd, offset, count, &sf, &sbytes, flags); +#endif + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + _Py_END_SUPPRESS_IPH + + if (sf.headers != NULL) + iov_cleanup(sf.headers, hbuf, sf.hdr_cnt); + if (sf.trailers != NULL) + iov_cleanup(sf.trailers, tbuf, sf.trl_cnt); + + if (ret < 0) { + if ((errno == EAGAIN) || (errno == EBUSY)) { + if (sbytes != 0) { + // some data has been sent + goto done; + } + else { + // no data has been sent; upper application is supposed + // to retry on EAGAIN or EBUSY + return posix_error(); + } + } + return (!async_err) ? posix_error() : NULL; + } + goto done; + +done: + #if !defined(HAVE_LARGEFILE_SUPPORT) + return Py_BuildValue("l", sbytes); + #else + return Py_BuildValue("L", sbytes); + #endif + +#else +#ifdef __linux__ + if (offobj == Py_None) { + do { + Py_BEGIN_ALLOW_THREADS + ret = sendfile(out_fd, in_fd, NULL, count); + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (ret < 0) + return (!async_err) ? posix_error() : NULL; + return Py_BuildValue("n", ret); + } +#endif + off_t offset; + if (!Py_off_t_converter(offobj, &offset)) + return NULL; + +#if defined(__sun) && defined(__SVR4) + // On Solaris, sendfile raises EINVAL rather than returning 0 + // when the offset is equal or bigger than the in_fd size. + struct stat st; - /* Skip over . and .. */ - if (wcscmp(file_data->cFileName, L".") != 0 && - wcscmp(file_data->cFileName, L"..") != 0) - { - PyObject *module = PyType_GetModule(Py_TYPE(iterator)); - entry = DirEntry_from_find_data(module, &iterator->path, file_data); - if (!entry) - break; - return entry; - } + do { + Py_BEGIN_ALLOW_THREADS + ret = fstat(in_fd, &st); + Py_END_ALLOW_THREADS + } while (ret != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (ret < 0) + return (!async_err) ? posix_error() : NULL; - /* Loop till we get a non-dot directory or finish iterating */ + if (offset >= st.st_size) { + return Py_BuildValue("i", 0); } - /* Error or no more files */ - ScandirIterator_closedir(iterator); - return NULL; -} + // On illumos specifically sendfile() may perform a partial write but + // return -1/an error (in one confirmed case the destination socket + // had a 5 second timeout set and errno was EAGAIN) and it's on the client + // code to check if the offset parameter was modified by sendfile(). + // + // We need this variable to track said change. + off_t original_offset = offset; +#endif + + do { + Py_BEGIN_ALLOW_THREADS + ret = sendfile(out_fd, in_fd, &offset, count); +#if defined(__sun) && defined(__SVR4) + // This handles illumos-specific sendfile() partial write behavior, + // see a comment above for more details. + if (ret < 0 && offset != original_offset) { + ret = offset - original_offset; + } +#endif + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (ret < 0) + return (!async_err) ? posix_error() : NULL; + return Py_BuildValue("n", ret); +#endif +} +#endif /* HAVE_SENDFILE */ + + +#if defined(__APPLE__) +/*[clinic input] +os._fcopyfile -#else /* POSIX */ + in_fd: int + out_fd: int + flags: int + / -static int -ScandirIterator_is_closed(ScandirIterator *iterator) -{ - return !iterator->dirp; -} +Efficiently copy content or metadata of 2 regular file descriptors (macOS). +[clinic start generated code]*/ -static void -ScandirIterator_closedir(ScandirIterator *iterator) +static PyObject * +os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags) +/*[clinic end generated code: output=c9d1a35a992e401b input=1e34638a86948795]*/ { - DIR *dirp = iterator->dirp; - - if (!dirp) - return; + int ret; - iterator->dirp = NULL; Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FDOPENDIR - if (iterator->path.fd != -1) - rewinddir(dirp); -#endif - closedir(dirp); + ret = fcopyfile(in_fd, out_fd, NULL, flags); Py_END_ALLOW_THREADS - return; + if (ret < 0) + return posix_error(); + Py_RETURN_NONE; } - -static PyObject * -ScandirIterator_iternext(ScandirIterator *iterator) -{ - struct dirent *direntp; - Py_ssize_t name_len; - int is_dot; - PyObject *entry; - - /* Happens if the iterator is iterated twice, or closed explicitly */ - if (!iterator->dirp) - return NULL; - - while (1) { - errno = 0; - Py_BEGIN_ALLOW_THREADS - direntp = readdir(iterator->dirp); - Py_END_ALLOW_THREADS - - if (!direntp) { - /* Error or no more files */ - if (errno != 0) - path_error(&iterator->path); - break; - } - - /* Skip over . and .. */ - name_len = NAMLEN(direntp); - is_dot = direntp->d_name[0] == '.' && - (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2)); - if (!is_dot) { - PyObject *module = PyType_GetModule(Py_TYPE(iterator)); - entry = DirEntry_from_posix_info(module, - &iterator->path, direntp->d_name, - name_len, direntp->d_ino -#ifdef HAVE_DIRENT_D_TYPE - , direntp->d_type #endif - ); - if (!entry) - break; - return entry; - } - /* Loop till we get a non-dot directory or finish iterating */ - } - /* Error or no more files */ - ScandirIterator_closedir(iterator); - return NULL; -} +/*[clinic input] +os.fstat + + fd : int + +Perform a stat system call on the given file descriptor. + +Like stat(), but for an open file descriptor. +Equivalent to os.stat(fd). +[clinic start generated code]*/ + +static PyObject * +os_fstat_impl(PyObject *module, int fd) +/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/ +{ + STRUCT_STAT st; + int res; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = FSTAT(fd, &st); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) { +#ifdef MS_WINDOWS + return PyErr_SetFromWindowsErr(0); +#else + return (!async_err) ? posix_error() : NULL; +#endif + } + + return _pystat_fromstructstat(module, &st); +} + + +/*[clinic input] +os.isatty -> bool + fd: int + / + +Return True if the fd is connected to a terminal. + +Return True if the file descriptor is an open file descriptor +connected to the slave end of a terminal. +[clinic start generated code]*/ + +static int +os_isatty_impl(PyObject *module, int fd) +/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/ +{ + int return_value; + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + return_value = isatty(fd); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + return return_value; +} + + +#ifdef HAVE_PIPE +/*[clinic input] +os.pipe + +Create a pipe. + +Returns a tuple of two file descriptors: + (read_fd, write_fd) +[clinic start generated code]*/ + +static PyObject * +os_pipe_impl(PyObject *module) +/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/ +{ + int fds[2]; +#ifdef MS_WINDOWS + HANDLE read, write; + SECURITY_ATTRIBUTES attr; + BOOL ok; +#else + int res; +#endif + +#ifdef MS_WINDOWS + attr.nLength = sizeof(attr); + attr.lpSecurityDescriptor = NULL; + attr.bInheritHandle = FALSE; + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + ok = CreatePipe(&read, &write, &attr, 0); + if (ok) { + fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY); + fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY); + if (fds[0] == -1 || fds[1] == -1) { + CloseHandle(read); + CloseHandle(write); + ok = 0; + } + } + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + if (!ok) + return PyErr_SetFromWindowsErr(0); +#else + +#ifdef HAVE_PIPE2 + Py_BEGIN_ALLOW_THREADS + res = pipe2(fds, O_CLOEXEC); + Py_END_ALLOW_THREADS + + if (res != 0 && errno == ENOSYS) + { +#endif + Py_BEGIN_ALLOW_THREADS + res = pipe(fds); + Py_END_ALLOW_THREADS + + if (res == 0) { + if (_Py_set_inheritable(fds[0], 0, NULL) < 0) { + close(fds[0]); + close(fds[1]); + return NULL; + } + if (_Py_set_inheritable(fds[1], 0, NULL) < 0) { + close(fds[0]); + close(fds[1]); + return NULL; + } + } +#ifdef HAVE_PIPE2 + } +#endif + + if (res != 0) + return PyErr_SetFromErrno(PyExc_OSError); +#endif /* !MS_WINDOWS */ + return Py_BuildValue("(ii)", fds[0], fds[1]); +} +#endif /* HAVE_PIPE */ + + +#ifdef HAVE_PIPE2 +/*[clinic input] +os.pipe2 + + flags: int + / + +Create a pipe with flags set atomically. + +Returns a tuple of two file descriptors: + (read_fd, write_fd) + +flags can be constructed by ORing together one or more of these values: +O_NONBLOCK, O_CLOEXEC. +[clinic start generated code]*/ + +static PyObject * +os_pipe2_impl(PyObject *module, int flags) +/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/ +{ + int fds[2]; + int res; + + res = pipe2(fds, flags); + if (res != 0) + return posix_error(); + return Py_BuildValue("(ii)", fds[0], fds[1]); +} +#endif /* HAVE_PIPE2 */ + + +#ifdef HAVE_WRITEV +/*[clinic input] +os.writev -> Py_ssize_t + fd: int + buffers: object + / + +Iterate over buffers, and write the contents of each to a file descriptor. + +Returns the total number of bytes written. +buffers must be a sequence of bytes-like objects. +[clinic start generated code]*/ + +static Py_ssize_t +os_writev_impl(PyObject *module, int fd, PyObject *buffers) +/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/ +{ + Py_ssize_t cnt; + Py_ssize_t result; + int async_err = 0; + struct iovec *iov; + Py_buffer *buf; + + if (!PySequence_Check(buffers)) { + PyErr_SetString(PyExc_TypeError, + "writev() arg 2 must be a sequence"); + return -1; + } + cnt = PySequence_Size(buffers); + if (cnt < 0) + return -1; + + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { + return -1; + } + + do { + Py_BEGIN_ALLOW_THREADS + result = writev(fd, iov, cnt); + Py_END_ALLOW_THREADS + } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + iov_cleanup(iov, buf, cnt); + if (result < 0 && !async_err) + posix_error(); + + return result; +} +#endif /* HAVE_WRITEV */ + + +#ifdef HAVE_PWRITE +/*[clinic input] +os.pwrite -> Py_ssize_t + + fd: int + buffer: Py_buffer + offset: Py_off_t + / + +Write bytes to a file descriptor starting at a particular offset. + +Write buffer to fd, starting at offset bytes from the beginning of +the file. Returns the number of bytes writte. Does not change the +current file offset. +[clinic start generated code]*/ + +static Py_ssize_t +os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset) +/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/ +{ + Py_ssize_t size; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (size < 0 && !async_err) + posix_error(); + return size; +} +#endif /* HAVE_PWRITE */ + +#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2) +/*[clinic input] +os.pwritev -> Py_ssize_t + + fd: int + buffers: object + offset: Py_off_t + flags: int = 0 + / + +Writes the contents of bytes-like objects to a file descriptor at a given offset. + +Combines the functionality of writev() and pwrite(). All buffers must be a sequence +of bytes-like objects. Buffers are processed in array order. Entire contents of first +buffer is written before proceeding to second, and so on. The operating system may +set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used. +This function writes the contents of each object to the file descriptor and returns +the total number of bytes written. + +The flags argument contains a bitwise OR of zero or more of the following flags: + +- RWF_DSYNC +- RWF_SYNC + +Using non-zero flags requires Linux 4.7 or newer. +[clinic start generated code]*/ + +static Py_ssize_t +os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, + int flags) +/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/ +{ + Py_ssize_t cnt; + Py_ssize_t result; + int async_err = 0; + struct iovec *iov; + Py_buffer *buf; + + if (!PySequence_Check(buffers)) { + PyErr_SetString(PyExc_TypeError, + "pwritev() arg 2 must be a sequence"); + return -1; + } + + cnt = PySequence_Size(buffers); + if (cnt < 0) { + return -1; + } + +#ifndef HAVE_PWRITEV2 + if(flags != 0) { + argument_unavailable_error("pwritev2", "flags"); + return -1; + } +#endif + + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { + return -1; + } +#ifdef HAVE_PWRITEV2 + do { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + result = pwritev2(fd, iov, cnt, offset, flags); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#else +#ifdef __APPLE__ +/* This entire function will be removed from the module dict when the API + * is not available. + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" +#pragma clang diagnostic ignored "-Wunguarded-availability-new" #endif + do { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + result = pwritev(fd, iov, cnt, offset); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); -static PyObject * -ScandirIterator_close(ScandirIterator *self, PyObject *args) -{ - ScandirIterator_closedir(self); - Py_RETURN_NONE; -} - -static PyObject * -ScandirIterator_enter(PyObject *self, PyObject *args) -{ - Py_INCREF(self); - return self; -} +#ifdef __APPLE__ +#pragma clang diagnostic pop +#endif + +#endif + + iov_cleanup(iov, buf, cnt); + if (result < 0) { + if (!async_err) { + posix_error(); + } + return -1; + } + + return result; +} +#endif /* HAVE_PWRITEV */ + +#ifdef HAVE_COPY_FILE_RANGE +/*[clinic input] + +os.copy_file_range + src: int + Source file descriptor. + dst: int + Destination file descriptor. + count: Py_ssize_t + Number of bytes to copy. + offset_src: object = None + Starting offset in src. + offset_dst: object = None + Starting offset in dst. + +Copy count bytes from one file descriptor to another. + +If offset_src is None, then src is read from the current position; +respectively for offset_dst. +[clinic start generated code]*/ static PyObject * -ScandirIterator_exit(ScandirIterator *self, PyObject *args) -{ - ScandirIterator_closedir(self); - Py_RETURN_NONE; -} - -static void -ScandirIterator_finalize(ScandirIterator *iterator) +os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count, + PyObject *offset_src, PyObject *offset_dst) +/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/ { - PyObject *error_type, *error_value, *error_traceback; + off_t offset_src_val, offset_dst_val; + off_t *p_offset_src = NULL; + off_t *p_offset_dst = NULL; + Py_ssize_t ret; + int async_err = 0; + /* The flags argument is provided to allow + * for future extensions and currently must be to 0. */ + int flags = 0; - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - if (!ScandirIterator_is_closed(iterator)) { - ScandirIterator_closedir(iterator); + if (count < 0) { + PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed"); + return NULL; + } - if (PyErr_ResourceWarning((PyObject *)iterator, 1, - "unclosed scandir iterator %R", iterator)) { - /* Spurious errors can appear at shutdown */ - if (PyErr_ExceptionMatches(PyExc_Warning)) { - PyErr_WriteUnraisable((PyObject *) iterator); - } + if (offset_src != Py_None) { + if (!Py_off_t_converter(offset_src, &offset_src_val)) { + return NULL; } + p_offset_src = &offset_src_val; } - path_cleanup(&iterator->path); + if (offset_dst != Py_None) { + if (!Py_off_t_converter(offset_dst, &offset_dst_val)) { + return NULL; + } + p_offset_dst = &offset_dst_val; + } - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); -} + do { + Py_BEGIN_ALLOW_THREADS + ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags); + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); -static void -ScandirIterator_dealloc(ScandirIterator *iterator) -{ - PyTypeObject *tp = Py_TYPE(iterator); - if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) - return; + if (ret < 0) { + return (!async_err) ? posix_error() : NULL; + } - freefunc free_func = PyType_GetSlot(tp, Py_tp_free); - free_func(iterator); - Py_DECREF(tp); + return PyLong_FromSsize_t(ret); } +#endif /* HAVE_COPY_FILE_RANGE*/ -static PyMethodDef ScandirIterator_methods[] = { - {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, - {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, - {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, - {NULL} -}; +#ifdef HAVE_MKFIFO +/*[clinic input] +os.mkfifo + + path: path_t + mode: int=0o666 + * + dir_fd: dir_fd(requires='mkfifoat')=None + +Create a "fifo" (a POSIX named pipe). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +static PyObject * +os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd) +/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/ +{ + int result; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_MKFIFOAT + if (dir_fd != DEFAULT_DIR_FD) + result = mkfifoat(dir_fd, path->narrow, mode); + else +#endif + result = mkfifo(path->narrow, mode); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; + + Py_RETURN_NONE; +} +#endif /* HAVE_MKFIFO */ + + +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) +/*[clinic input] +os.mknod + + path: path_t + mode: int=0o600 + device: dev_t=0 + * + dir_fd: dir_fd(requires='mknodat')=None + +Create a node in the file system. + +Create a node in the file system (file, device special file or named pipe) +at path. mode specifies both the permissions to use and the +type of node to be created, being combined (bitwise OR) with one of +S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode, +device defines the newly created device special file (probably using +os.makedev()). Otherwise device is ignored. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +static PyObject * +os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, + int dir_fd) +/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/ +{ + int result; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_MKNODAT + if (dir_fd != DEFAULT_DIR_FD) + result = mknodat(dir_fd, path->narrow, mode, device); + else +#endif + result = mknod(path->narrow, mode, device); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; + + Py_RETURN_NONE; +} +#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */ + + +#ifdef HAVE_DEVICE_MACROS +/*[clinic input] +os.major -> unsigned_int + + device: dev_t + / + +Extracts a device major number from a raw device number. +[clinic start generated code]*/ + +static unsigned int +os_major_impl(PyObject *module, dev_t device) +/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/ +{ + return major(device); +} + + +/*[clinic input] +os.minor -> unsigned_int + + device: dev_t + / + +Extracts a device minor number from a raw device number. +[clinic start generated code]*/ + +static unsigned int +os_minor_impl(PyObject *module, dev_t device) +/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/ +{ + return minor(device); +} + + +/*[clinic input] +os.makedev -> dev_t + + major: int + minor: int + / + +Composes a raw device number from the major and minor device numbers. +[clinic start generated code]*/ + +static dev_t +os_makedev_impl(PyObject *module, int major, int minor) +/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/ +{ + return makedev(major, minor); +} +#endif /* HAVE_DEVICE_MACROS */ + + +#if defined HAVE_FTRUNCATE || defined MS_WINDOWS +/*[clinic input] +os.ftruncate + + fd: int + length: Py_off_t + / + +Truncate a file, specified by file descriptor, to a specific length. +[clinic start generated code]*/ + +static PyObject * +os_ftruncate_impl(PyObject *module, int fd, Py_off_t length) +/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/ +{ + int result; + int async_err = 0; + + if (PySys_Audit("os.truncate", "in", fd, length) < 0) { + return NULL; + } -static PyType_Slot ScandirIteratorType_slots[] = { - {Py_tp_new, _disabled_new}, - {Py_tp_dealloc, ScandirIterator_dealloc}, - {Py_tp_finalize, ScandirIterator_finalize}, - {Py_tp_iter, PyObject_SelfIter}, - {Py_tp_iternext, ScandirIterator_iternext}, - {Py_tp_methods, ScandirIterator_methods}, - {0, 0}, -}; + do { + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef MS_WINDOWS + result = _chsize_s(fd, length); +#else + result = ftruncate(fd, length); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; + Py_RETURN_NONE; +} +#endif /* HAVE_FTRUNCATE || MS_WINDOWS */ + + +#if defined HAVE_TRUNCATE || defined MS_WINDOWS +/*[clinic input] +os.truncate + path: path_t(allow_fd='PATH_HAVE_FTRUNCATE') + length: Py_off_t + +Truncate a file, specified by path, to a specific length. + +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +static PyObject * +os_truncate_impl(PyObject *module, path_t *path, Py_off_t length) +/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/ +{ + int result; +#ifdef MS_WINDOWS + int fd; +#endif + + if (path->fd != -1) + return os_ftruncate_impl(module, path->fd, length); + + if (PySys_Audit("os.truncate", "On", path->object, length) < 0) { + return NULL; + } -static PyType_Spec ScandirIteratorType_spec = { - MODNAME ".ScandirIterator", - sizeof(ScandirIterator), - 0, - // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since - // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance. - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, - ScandirIteratorType_slots -}; + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH +#ifdef MS_WINDOWS + fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT); + if (fd < 0) + result = -1; + else { + result = _chsize_s(fd, length); + close(fd); + if (result < 0) + errno = result; + } +#else + result = truncate(path->narrow, length); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + if (result < 0) + return posix_path_error(path); + + Py_RETURN_NONE; +} +#endif /* HAVE_TRUNCATE || MS_WINDOWS */ + + +/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise() + and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is + defined, which is the case in Python on AIX. AIX bug report: + http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */ +#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__) +# define POSIX_FADVISE_AIX_BUG +#endif + + +#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) +/*[clinic input] +os.posix_fallocate + + fd: int + offset: Py_off_t + length: Py_off_t + / + +Ensure a file has allocated at least a particular number of bytes on disk. + +Ensure that the file specified by fd encompasses a range of bytes +starting at offset bytes from the beginning and continuing for length bytes. +[clinic start generated code]*/ + +static PyObject * +os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset, + Py_off_t length) +/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/ +{ + int result; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + result = posix_fallocate(fd, offset, length); + Py_END_ALLOW_THREADS + } while (result == EINTR && !(async_err = PyErr_CheckSignals())); + + if (result == 0) + Py_RETURN_NONE; + + if (async_err) + return NULL; + + errno = result; + return posix_error(); +} +#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */ + + +#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) +/*[clinic input] +os.posix_fadvise + + fd: int + offset: Py_off_t + length: Py_off_t + advice: int + / + +Announce an intention to access data in a specific pattern. + +Announce an intention to access data in a specific pattern, thus allowing +the kernel to make optimizations. +The advice applies to the region of the file specified by fd starting at +offset and continuing for length bytes. +advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL, +POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or +POSIX_FADV_DONTNEED. +[clinic start generated code]*/ + +static PyObject * +os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, + Py_off_t length, int advice) +/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/ +{ + int result; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + result = posix_fadvise(fd, offset, length, advice); + Py_END_ALLOW_THREADS + } while (result == EINTR && !(async_err = PyErr_CheckSignals())); + + if (result == 0) + Py_RETURN_NONE; + + if (async_err) + return NULL; + + errno = result; + return posix_error(); +} +#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */ + + +#ifdef MS_WINDOWS +static PyObject* +win32_putenv(PyObject *name, PyObject *value) +{ + /* Search from index 1 because on Windows starting '=' is allowed for + defining hidden environment variables. */ + if (PyUnicode_GET_LENGTH(name) == 0 || + PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1) + { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + return NULL; + } + PyObject *unicode; + if (value != NULL) { + unicode = PyUnicode_FromFormat("%U=%U", name, value); + } + else { + unicode = PyUnicode_FromFormat("%U=", name); + } + if (unicode == NULL) { + return NULL; + } + + Py_ssize_t size; + /* PyUnicode_AsWideCharString() rejects embedded null characters */ + wchar_t *env = PyUnicode_AsWideCharString(unicode, &size); + Py_DECREF(unicode); -/*[clinic input] -os.scandir + if (env == NULL) { + return NULL; + } + if (size > _MAX_ENV) { + PyErr_Format(PyExc_ValueError, + "the environment variable is longer than %u characters", + _MAX_ENV); + PyMem_Free(env); + return NULL; + } + + /* _wputenv() and SetEnvironmentVariableW() update the environment in the + Process Environment Block (PEB). _wputenv() also updates CRT 'environ' + and '_wenviron' variables, whereas SetEnvironmentVariableW() does not. + + Prefer _wputenv() to be compatible with C libraries using CRT + variables and CRT functions using these variables (ex: getenv()). */ + int err = _wputenv(env); + PyMem_Free(env); - path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None + if (err) { + posix_error(); + return NULL; + } + + Py_RETURN_NONE; +} +#endif + -Return an iterator of DirEntry objects for given path. +#ifdef MS_WINDOWS +/*[clinic input] +os.putenv -path can be specified as either str, bytes, or a path-like object. If path -is bytes, the names of yielded DirEntry objects will also be bytes; in -all other circumstances they will be str. + name: unicode + value: unicode + / -If path is None, uses the path='.'. +Change or add an environment variable. [clinic start generated code]*/ static PyObject * -os_scandir_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/ +os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) +/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ { - ScandirIterator *iterator; -#ifdef MS_WINDOWS - wchar_t *path_strW; -#else - const char *path_str; -#ifdef HAVE_FDOPENDIR - int fd = -1; -#endif -#endif - - if (PySys_Audit("os.scandir", "O", - path->object ? path->object : Py_None) < 0) { + if (PySys_Audit("os.putenv", "OO", name, value) < 0) { return NULL; } + return win32_putenv(name, value); +} +#else +/*[clinic input] +os.putenv + + name: FSConverter + value: FSConverter + / + +Change or add an environment variable. +[clinic start generated code]*/ + +static PyObject * +os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) +/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/ +{ + const char *name_string = PyBytes_AS_STRING(name); + const char *value_string = PyBytes_AS_STRING(value); + + if (strchr(name_string, '=') != NULL) { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + return NULL; + } - PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType; - iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType); - if (!iterator) + if (PySys_Audit("os.putenv", "OO", name, value) < 0) { return NULL; - -#ifdef MS_WINDOWS - iterator->handle = INVALID_HANDLE_VALUE; -#else - iterator->dirp = NULL; -#endif - - memcpy(&iterator->path, path, sizeof(path_t)); - /* Move the ownership to iterator->path */ - path->object = NULL; - path->cleanup = NULL; - + } + + if (setenv(name_string, value_string, 1)) { + return posix_error(); + } + Py_RETURN_NONE; +} +#endif /* !defined(MS_WINDOWS) */ + + #ifdef MS_WINDOWS - iterator->first_time = 1; - - path_strW = join_path_filenameW(iterator->path.wide, L"*.*"); - if (!path_strW) - goto error; - - Py_BEGIN_ALLOW_THREADS - iterator->handle = FindFirstFileW(path_strW, &iterator->file_data); - Py_END_ALLOW_THREADS +/*[clinic input] +os.unsetenv + name: unicode + / - PyMem_Free(path_strW); +Delete an environment variable. +[clinic start generated code]*/ - if (iterator->handle == INVALID_HANDLE_VALUE) { - path_error(&iterator->path); - goto error; +static PyObject * +os_unsetenv_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/ +{ + if (PySys_Audit("os.unsetenv", "(O)", name) < 0) { + return NULL; } -#else /* POSIX */ - errno = 0; -#ifdef HAVE_FDOPENDIR - if (iterator->path.fd != -1) { - if (HAVE_FDOPENDIR_RUNTIME) { - /* closedir() closes the FD, so we duplicate it */ - fd = _Py_dup(path->fd); - if (fd == -1) - goto error; + return win32_putenv(name, NULL); +} +#else +/*[clinic input] +os.unsetenv + name: FSConverter + / + +Delete an environment variable. +[clinic start generated code]*/ + +static PyObject * +os_unsetenv_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/ +{ + if (PySys_Audit("os.unsetenv", "(O)", name) < 0) { + return NULL; + } +#ifdef HAVE_BROKEN_UNSETENV + unsetenv(PyBytes_AS_STRING(name)); +#else + int err = unsetenv(PyBytes_AS_STRING(name)); + if (err) { + return posix_error(); + } +#endif + + Py_RETURN_NONE; +} +#endif /* !MS_WINDOWS */ + + +/*[clinic input] +os.strerror + + code: int + / + +Translate an error code to a message string. +[clinic start generated code]*/ + +static PyObject * +os_strerror_impl(PyObject *module, int code) +/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/ +{ + char *message = strerror(code); + if (message == NULL) { + PyErr_SetString(PyExc_ValueError, + "strerror() argument out of range"); + return NULL; + } + return PyUnicode_DecodeLocale(message, "surrogateescape"); +} + + +#ifdef HAVE_SYS_WAIT_H +#ifdef WCOREDUMP +/*[clinic input] +os.WCOREDUMP -> bool + + status: int + / + +Return True if the process returning status was dumped to a core file. +[clinic start generated code]*/ + +static int +os_WCOREDUMP_impl(PyObject *module, int status) +/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WCOREDUMP(wait_status); +} +#endif /* WCOREDUMP */ + + +#ifdef WIFCONTINUED +/*[clinic input] +os.WIFCONTINUED -> bool + + status: int + +Return True if a particular process was continued from a job control stop. + +Return True if the process returning status was continued from a +job control stop. +[clinic start generated code]*/ + +static int +os_WIFCONTINUED_impl(PyObject *module, int status) +/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFCONTINUED(wait_status); +} +#endif /* WIFCONTINUED */ + + +#ifdef WIFSTOPPED +/*[clinic input] +os.WIFSTOPPED -> bool + + status: int + +Return True if the process returning status was stopped. +[clinic start generated code]*/ + +static int +os_WIFSTOPPED_impl(PyObject *module, int status) +/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFSTOPPED(wait_status); +} +#endif /* WIFSTOPPED */ + + +#ifdef WIFSIGNALED +/*[clinic input] +os.WIFSIGNALED -> bool + + status: int + +Return True if the process returning status was terminated by a signal. +[clinic start generated code]*/ + +static int +os_WIFSIGNALED_impl(PyObject *module, int status) +/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFSIGNALED(wait_status); +} +#endif /* WIFSIGNALED */ + + +#ifdef WIFEXITED +/*[clinic input] +os.WIFEXITED -> bool + + status: int + +Return True if the process returning status exited via the exit() system call. +[clinic start generated code]*/ + +static int +os_WIFEXITED_impl(PyObject *module, int status) +/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFEXITED(wait_status); +} +#endif /* WIFEXITED */ + + +#ifdef WEXITSTATUS +/*[clinic input] +os.WEXITSTATUS -> int + + status: int + +Return the process return code from status. +[clinic start generated code]*/ + +static int +os_WEXITSTATUS_impl(PyObject *module, int status) +/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WEXITSTATUS(wait_status); +} +#endif /* WEXITSTATUS */ + + +#ifdef WTERMSIG +/*[clinic input] +os.WTERMSIG -> int + + status: int + +Return the signal that terminated the process that provided the status value. +[clinic start generated code]*/ + +static int +os_WTERMSIG_impl(PyObject *module, int status) +/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WTERMSIG(wait_status); +} +#endif /* WTERMSIG */ + + +#ifdef WSTOPSIG +/*[clinic input] +os.WSTOPSIG -> int + + status: int + +Return the signal that stopped the process that provided the status value. +[clinic start generated code]*/ + +static int +os_WSTOPSIG_impl(PyObject *module, int status) +/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WSTOPSIG(wait_status); +} +#endif /* WSTOPSIG */ +#endif /* HAVE_SYS_WAIT_H */ + + +#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) +#ifdef _SCO_DS +/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the + needed definitions in sys/statvfs.h */ +#define _SVID3 +#endif +#include + +static PyObject* +_pystatvfs_fromstructstatvfs(PyObject *module, struct statvfs st) { + PyObject *StatVFSResultType = get_posix_state(module)->StatVFSResultType; + PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType); + if (v == NULL) + return NULL; + +#if !defined(HAVE_LARGEFILE_SUPPORT) + PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); + PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); + PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks)); + PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree)); + PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); + PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); + PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); + PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); + PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); + PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); +#else + PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); + PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); + PyStructSequence_SET_ITEM(v, 2, + PyLong_FromLongLong((long long) st.f_blocks)); + PyStructSequence_SET_ITEM(v, 3, + PyLong_FromLongLong((long long) st.f_bfree)); + PyStructSequence_SET_ITEM(v, 4, + PyLong_FromLongLong((long long) st.f_bavail)); + PyStructSequence_SET_ITEM(v, 5, + PyLong_FromLongLong((long long) st.f_files)); + PyStructSequence_SET_ITEM(v, 6, + PyLong_FromLongLong((long long) st.f_ffree)); + PyStructSequence_SET_ITEM(v, 7, + PyLong_FromLongLong((long long) st.f_favail)); + PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); + PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); +#endif +/* The _ALL_SOURCE feature test macro defines f_fsid as a structure + * (issue #32390). */ +#if defined(_AIX) && defined(_ALL_SOURCE) + PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0])); +#else + PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid)); +#endif + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + + return v; +} + + +/*[clinic input] +os.fstatvfs + fd: int + / + +Perform an fstatvfs system call on the given fd. + +Equivalent to statvfs(fd). +[clinic start generated code]*/ + +static PyObject * +os_fstatvfs_impl(PyObject *module, int fd) +/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/ +{ + int result; + int async_err = 0; + struct statvfs st; + + do { + Py_BEGIN_ALLOW_THREADS + result = fstatvfs(fd, &st); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; + + return _pystatvfs_fromstructstatvfs(module, st); +} +#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */ + + +#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) +#include +/*[clinic input] +os.statvfs + + path: path_t(allow_fd='PATH_HAVE_FSTATVFS') + +Perform a statvfs system call on the given path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +static PyObject * +os_statvfs_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/ +{ + int result; + struct statvfs st; + + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FSTATVFS + if (path->fd != -1) { + result = fstatvfs(path->fd, &st); + } + else +#endif + result = statvfs(path->narrow, &st); + Py_END_ALLOW_THREADS + + if (result) { + return path_error(path); + } + + return _pystatvfs_fromstructstatvfs(module, st); +} +#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */ + + +#ifdef MS_WINDOWS +/*[clinic input] +os._getdiskusage + + path: path_t + +Return disk usage statistics about the given path as a (total, free) tuple. +[clinic start generated code]*/ + +static PyObject * +os__getdiskusage_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/ +{ + BOOL retval; + ULARGE_INTEGER _, total, free; + DWORD err = 0; + + Py_BEGIN_ALLOW_THREADS + retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free); + Py_END_ALLOW_THREADS + if (retval == 0) { + if (GetLastError() == ERROR_DIRECTORY) { + wchar_t *dir_path = NULL; + + dir_path = PyMem_New(wchar_t, path->length + 1); + if (dir_path == NULL) { + return PyErr_NoMemory(); + } - Py_BEGIN_ALLOW_THREADS - iterator->dirp = fdopendir(fd); - Py_END_ALLOW_THREADS - } else { - PyErr_SetString(PyExc_TypeError, - "scandir: path should be string, bytes, os.PathLike or None, not int"); - return NULL; - } - } - else -#endif - { - if (iterator->path.narrow) - path_str = iterator->path.narrow; - else - path_str = "."; + wcscpy_s(dir_path, path->length + 1, path->wide); - Py_BEGIN_ALLOW_THREADS - iterator->dirp = opendir(path_str); - Py_END_ALLOW_THREADS + if (_dirnameW(dir_path) != -1) { + Py_BEGIN_ALLOW_THREADS + retval = GetDiskFreeSpaceExW(dir_path, &_, &total, &free); + Py_END_ALLOW_THREADS + } + /* Record the last error in case it's modified by PyMem_Free. */ + err = GetLastError(); + PyMem_Free(dir_path); + if (retval) { + goto success; + } + } + return PyErr_SetFromWindowsErr(err); } - if (!iterator->dirp) { - path_error(&iterator->path); -#ifdef HAVE_FDOPENDIR - if (fd != -1) { - Py_BEGIN_ALLOW_THREADS - close(fd); - Py_END_ALLOW_THREADS - } +success: + return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart); +} +#endif /* MS_WINDOWS */ + + +/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). + * It maps strings representing configuration variable names to + * integer values, allowing those functions to be called with the + * magic names instead of polluting the module's namespace with tons of + * rarely-used constants. There are three separate tables that use + * these definitions. + * + * This code is always included, even if none of the interfaces that + * need it are included. The #if hackery needed to avoid it would be + * sufficiently pervasive that it's not worth the loss of readability. + */ +struct constdef { + const char *name; + int value; +}; + +static int +conv_confname(PyObject *arg, int *valuep, struct constdef *table, + size_t tablesize) +{ + if (PyLong_Check(arg)) { + int value = _PyLong_AsInt(arg); + if (value == -1 && PyErr_Occurred()) + return 0; + *valuep = value; + return 1; + } + else { + /* look up the value in the table using a binary search */ + size_t lo = 0; + size_t mid; + size_t hi = tablesize; + int cmp; + const char *confname; + if (!PyUnicode_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "configuration names must be strings or integers"); + return 0; + } + confname = PyUnicode_AsUTF8(arg); + if (confname == NULL) + return 0; + while (lo < hi) { + mid = (lo + hi) / 2; + cmp = strcmp(confname, table[mid].name); + if (cmp < 0) + hi = mid; + else if (cmp > 0) + lo = mid + 1; + else { + *valuep = table[mid].value; + return 1; + } + } + PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); + return 0; + } +} + + +#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) +static struct constdef posix_constants_pathconf[] = { +#ifdef _PC_ABI_AIO_XFER_MAX + {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, +#endif +#ifdef _PC_ABI_ASYNC_IO + {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, +#endif +#ifdef _PC_ASYNC_IO + {"PC_ASYNC_IO", _PC_ASYNC_IO}, +#endif +#ifdef _PC_CHOWN_RESTRICTED + {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, +#endif +#ifdef _PC_FILESIZEBITS + {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, +#endif +#ifdef _PC_LAST + {"PC_LAST", _PC_LAST}, +#endif +#ifdef _PC_LINK_MAX + {"PC_LINK_MAX", _PC_LINK_MAX}, +#endif +#ifdef _PC_MAX_CANON + {"PC_MAX_CANON", _PC_MAX_CANON}, +#endif +#ifdef _PC_MAX_INPUT + {"PC_MAX_INPUT", _PC_MAX_INPUT}, +#endif +#ifdef _PC_NAME_MAX + {"PC_NAME_MAX", _PC_NAME_MAX}, +#endif +#ifdef _PC_NO_TRUNC + {"PC_NO_TRUNC", _PC_NO_TRUNC}, +#endif +#ifdef _PC_PATH_MAX + {"PC_PATH_MAX", _PC_PATH_MAX}, +#endif +#ifdef _PC_PIPE_BUF + {"PC_PIPE_BUF", _PC_PIPE_BUF}, +#endif +#ifdef _PC_PRIO_IO + {"PC_PRIO_IO", _PC_PRIO_IO}, +#endif +#ifdef _PC_SOCK_MAXBUF + {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, +#endif +#ifdef _PC_SYNC_IO + {"PC_SYNC_IO", _PC_SYNC_IO}, +#endif +#ifdef _PC_VDISABLE + {"PC_VDISABLE", _PC_VDISABLE}, +#endif +#ifdef _PC_ACL_ENABLED + {"PC_ACL_ENABLED", _PC_ACL_ENABLED}, +#endif +#ifdef _PC_MIN_HOLE_SIZE + {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE}, +#endif +#ifdef _PC_ALLOC_SIZE_MIN + {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN}, +#endif +#ifdef _PC_REC_INCR_XFER_SIZE + {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE}, +#endif +#ifdef _PC_REC_MAX_XFER_SIZE + {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE}, +#endif +#ifdef _PC_REC_MIN_XFER_SIZE + {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE}, +#endif +#ifdef _PC_REC_XFER_ALIGN + {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN}, +#endif +#ifdef _PC_SYMLINK_MAX + {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX}, +#endif +#ifdef _PC_XATTR_ENABLED + {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED}, +#endif +#ifdef _PC_XATTR_EXISTS + {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS}, +#endif +#ifdef _PC_TIMESTAMP_RESOLUTION + {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION}, +#endif +}; + +static int +conv_path_confname(PyObject *arg, int *valuep) +{ + return conv_confname(arg, valuep, posix_constants_pathconf, + sizeof(posix_constants_pathconf) + / sizeof(struct constdef)); +} +#endif + + +#ifdef HAVE_FPATHCONF +/*[clinic input] +os.fpathconf -> long + + fd: int + name: path_confname + / + +Return the configuration limit name for the file descriptor fd. + +If there is no limit, return -1. +[clinic start generated code]*/ + +static long +os_fpathconf_impl(PyObject *module, int fd, int name) +/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/ +{ + long limit; + + errno = 0; + limit = fpathconf(fd, name); + if (limit == -1 && errno != 0) + posix_error(); + + return limit; +} +#endif /* HAVE_FPATHCONF */ + + +#ifdef HAVE_PATHCONF +/*[clinic input] +os.pathconf -> long + path: path_t(allow_fd='PATH_HAVE_FPATHCONF') + name: path_confname + +Return the configuration limit name for the file or directory path. + +If there is no limit, return -1. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +static long +os_pathconf_impl(PyObject *module, path_t *path, int name) +/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/ +{ + long limit; + + errno = 0; +#ifdef HAVE_FPATHCONF + if (path->fd != -1) + limit = fpathconf(path->fd, name); + else +#endif + limit = pathconf(path->narrow, name); + if (limit == -1 && errno != 0) { + if (errno == EINVAL) + /* could be a path or name problem */ + posix_error(); + else + path_error(path); + } + + return limit; +} +#endif /* HAVE_PATHCONF */ + +#ifdef HAVE_CONFSTR +static struct constdef posix_constants_confstr[] = { +#ifdef _CS_ARCHITECTURE + {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, +#endif +#ifdef _CS_GNU_LIBC_VERSION + {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION}, +#endif +#ifdef _CS_GNU_LIBPTHREAD_VERSION + {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION}, +#endif +#ifdef _CS_HOSTNAME + {"CS_HOSTNAME", _CS_HOSTNAME}, +#endif +#ifdef _CS_HW_PROVIDER + {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, +#endif +#ifdef _CS_HW_SERIAL + {"CS_HW_SERIAL", _CS_HW_SERIAL}, +#endif +#ifdef _CS_INITTAB_NAME + {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, +#endif +#ifdef _CS_LFS64_CFLAGS + {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, +#endif +#ifdef _CS_LFS64_LDFLAGS + {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, +#endif +#ifdef _CS_LFS64_LIBS + {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, +#endif +#ifdef _CS_LFS64_LINTFLAGS + {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, +#endif +#ifdef _CS_LFS_CFLAGS + {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, +#endif +#ifdef _CS_LFS_LDFLAGS + {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, +#endif +#ifdef _CS_LFS_LIBS + {"CS_LFS_LIBS", _CS_LFS_LIBS}, +#endif +#ifdef _CS_LFS_LINTFLAGS + {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, +#endif +#ifdef _CS_MACHINE + {"CS_MACHINE", _CS_MACHINE}, +#endif +#ifdef _CS_PATH + {"CS_PATH", _CS_PATH}, +#endif +#ifdef _CS_RELEASE + {"CS_RELEASE", _CS_RELEASE}, +#endif +#ifdef _CS_SRPC_DOMAIN + {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, +#endif +#ifdef _CS_SYSNAME + {"CS_SYSNAME", _CS_SYSNAME}, +#endif +#ifdef _CS_VERSION + {"CS_VERSION", _CS_VERSION}, +#endif +#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS + {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, +#endif +#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS + {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, +#endif +#ifdef _CS_XBS5_ILP32_OFF32_LIBS + {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, +#endif +#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS + {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, +#endif +#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS + {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, +#endif +#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS + {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, +#endif +#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS + {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, +#endif +#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS + {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, +#endif +#ifdef _CS_XBS5_LP64_OFF64_CFLAGS + {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, +#endif +#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS + {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, +#endif +#ifdef _CS_XBS5_LP64_OFF64_LIBS + {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, +#endif +#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS + {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, +#endif +#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS + {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, +#endif +#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS + {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, +#endif +#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS + {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, +#endif +#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS + {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, +#endif +#ifdef _MIPS_CS_AVAIL_PROCESSORS + {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, +#endif +#ifdef _MIPS_CS_BASE + {"MIPS_CS_BASE", _MIPS_CS_BASE}, +#endif +#ifdef _MIPS_CS_HOSTID + {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, +#endif +#ifdef _MIPS_CS_HW_NAME + {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, +#endif +#ifdef _MIPS_CS_NUM_PROCESSORS + {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, +#endif +#ifdef _MIPS_CS_OSREL_MAJ + {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, +#endif +#ifdef _MIPS_CS_OSREL_MIN + {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, +#endif +#ifdef _MIPS_CS_OSREL_PATCH + {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, +#endif +#ifdef _MIPS_CS_OS_NAME + {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, +#endif +#ifdef _MIPS_CS_OS_PROVIDER + {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, +#endif +#ifdef _MIPS_CS_PROCESSORS + {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, +#endif +#ifdef _MIPS_CS_SERIAL + {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, +#endif +#ifdef _MIPS_CS_VENDOR + {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, +#endif +}; + +static int +conv_confstr_confname(PyObject *arg, int *valuep) +{ + return conv_confname(arg, valuep, posix_constants_confstr, + sizeof(posix_constants_confstr) + / sizeof(struct constdef)); +} + + +/*[clinic input] +os.confstr + + name: confstr_confname + / + +Return a string-valued system configuration variable. +[clinic start generated code]*/ + +static PyObject * +os_confstr_impl(PyObject *module, int name) +/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/ +{ + PyObject *result = NULL; + char buffer[255]; + size_t len; + + errno = 0; + len = confstr(name, buffer, sizeof(buffer)); + if (len == 0) { + if (errno) { + posix_error(); + return NULL; + } + else { + Py_RETURN_NONE; + } + } + + if (len >= sizeof(buffer)) { + size_t len2; + char *buf = PyMem_Malloc(len); + if (buf == NULL) + return PyErr_NoMemory(); + len2 = confstr(name, buf, len); + assert(len == len2); + result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1); + PyMem_Free(buf); + } + else + result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); + return result; +} +#endif /* HAVE_CONFSTR */ + + +#ifdef HAVE_SYSCONF +static struct constdef posix_constants_sysconf[] = { +#ifdef _SC_2_CHAR_TERM + {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, +#endif +#ifdef _SC_2_C_BIND + {"SC_2_C_BIND", _SC_2_C_BIND}, +#endif +#ifdef _SC_2_C_DEV + {"SC_2_C_DEV", _SC_2_C_DEV}, +#endif +#ifdef _SC_2_C_VERSION + {"SC_2_C_VERSION", _SC_2_C_VERSION}, +#endif +#ifdef _SC_2_FORT_DEV + {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, +#endif +#ifdef _SC_2_FORT_RUN + {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, +#endif +#ifdef _SC_2_LOCALEDEF + {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, +#endif +#ifdef _SC_2_SW_DEV + {"SC_2_SW_DEV", _SC_2_SW_DEV}, +#endif +#ifdef _SC_2_UPE + {"SC_2_UPE", _SC_2_UPE}, +#endif +#ifdef _SC_2_VERSION + {"SC_2_VERSION", _SC_2_VERSION}, +#endif +#ifdef _SC_ABI_ASYNCHRONOUS_IO + {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, +#endif +#ifdef _SC_ACL + {"SC_ACL", _SC_ACL}, +#endif +#ifdef _SC_AIO_LISTIO_MAX + {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, +#endif +#ifdef _SC_AIO_MAX + {"SC_AIO_MAX", _SC_AIO_MAX}, +#endif +#ifdef _SC_AIO_PRIO_DELTA_MAX + {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, +#endif +#ifdef _SC_ARG_MAX + {"SC_ARG_MAX", _SC_ARG_MAX}, +#endif +#ifdef _SC_ASYNCHRONOUS_IO + {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, +#endif +#ifdef _SC_ATEXIT_MAX + {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, +#endif +#ifdef _SC_AUDIT + {"SC_AUDIT", _SC_AUDIT}, +#endif +#ifdef _SC_AVPHYS_PAGES + {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, +#endif +#ifdef _SC_BC_BASE_MAX + {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, +#endif +#ifdef _SC_BC_DIM_MAX + {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, +#endif +#ifdef _SC_BC_SCALE_MAX + {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, +#endif +#ifdef _SC_BC_STRING_MAX + {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, +#endif +#ifdef _SC_CAP + {"SC_CAP", _SC_CAP}, +#endif +#ifdef _SC_CHARCLASS_NAME_MAX + {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, +#endif +#ifdef _SC_CHAR_BIT + {"SC_CHAR_BIT", _SC_CHAR_BIT}, +#endif +#ifdef _SC_CHAR_MAX + {"SC_CHAR_MAX", _SC_CHAR_MAX}, +#endif +#ifdef _SC_CHAR_MIN + {"SC_CHAR_MIN", _SC_CHAR_MIN}, +#endif +#ifdef _SC_CHILD_MAX + {"SC_CHILD_MAX", _SC_CHILD_MAX}, +#endif +#ifdef _SC_CLK_TCK + {"SC_CLK_TCK", _SC_CLK_TCK}, +#endif +#ifdef _SC_COHER_BLKSZ + {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, +#endif +#ifdef _SC_COLL_WEIGHTS_MAX + {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, +#endif +#ifdef _SC_DCACHE_ASSOC + {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, +#endif +#ifdef _SC_DCACHE_BLKSZ + {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, +#endif +#ifdef _SC_DCACHE_LINESZ + {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, +#endif +#ifdef _SC_DCACHE_SZ + {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, +#endif +#ifdef _SC_DCACHE_TBLKSZ + {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, +#endif +#ifdef _SC_DELAYTIMER_MAX + {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, +#endif +#ifdef _SC_EQUIV_CLASS_MAX + {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, +#endif +#ifdef _SC_EXPR_NEST_MAX + {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, +#endif +#ifdef _SC_FSYNC + {"SC_FSYNC", _SC_FSYNC}, +#endif +#ifdef _SC_GETGR_R_SIZE_MAX + {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, +#endif +#ifdef _SC_GETPW_R_SIZE_MAX + {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, +#endif +#ifdef _SC_ICACHE_ASSOC + {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, +#endif +#ifdef _SC_ICACHE_BLKSZ + {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, +#endif +#ifdef _SC_ICACHE_LINESZ + {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, +#endif +#ifdef _SC_ICACHE_SZ + {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, +#endif +#ifdef _SC_INF + {"SC_INF", _SC_INF}, +#endif +#ifdef _SC_INT_MAX + {"SC_INT_MAX", _SC_INT_MAX}, +#endif +#ifdef _SC_INT_MIN + {"SC_INT_MIN", _SC_INT_MIN}, +#endif +#ifdef _SC_IOV_MAX + {"SC_IOV_MAX", _SC_IOV_MAX}, +#endif +#ifdef _SC_IP_SECOPTS + {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, +#endif +#ifdef _SC_JOB_CONTROL + {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, +#endif +#ifdef _SC_KERN_POINTERS + {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, +#endif +#ifdef _SC_KERN_SIM + {"SC_KERN_SIM", _SC_KERN_SIM}, +#endif +#ifdef _SC_LINE_MAX + {"SC_LINE_MAX", _SC_LINE_MAX}, +#endif +#ifdef _SC_LOGIN_NAME_MAX + {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, +#endif +#ifdef _SC_LOGNAME_MAX + {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, +#endif +#ifdef _SC_LONG_BIT + {"SC_LONG_BIT", _SC_LONG_BIT}, +#endif +#ifdef _SC_MAC + {"SC_MAC", _SC_MAC}, +#endif +#ifdef _SC_MAPPED_FILES + {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, +#endif +#ifdef _SC_MAXPID + {"SC_MAXPID", _SC_MAXPID}, +#endif +#ifdef _SC_MB_LEN_MAX + {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, +#endif +#ifdef _SC_MEMLOCK + {"SC_MEMLOCK", _SC_MEMLOCK}, +#endif +#ifdef _SC_MEMLOCK_RANGE + {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, +#endif +#ifdef _SC_MEMORY_PROTECTION + {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, +#endif +#ifdef _SC_MESSAGE_PASSING + {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, +#endif +#ifdef _SC_MMAP_FIXED_ALIGNMENT + {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, +#endif +#ifdef _SC_MQ_OPEN_MAX + {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, +#endif +#ifdef _SC_MQ_PRIO_MAX + {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, +#endif +#ifdef _SC_NACLS_MAX + {"SC_NACLS_MAX", _SC_NACLS_MAX}, +#endif +#ifdef _SC_NGROUPS_MAX + {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, +#endif +#ifdef _SC_NL_ARGMAX + {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, +#endif +#ifdef _SC_NL_LANGMAX + {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, +#endif +#ifdef _SC_NL_MSGMAX + {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, +#endif +#ifdef _SC_NL_NMAX + {"SC_NL_NMAX", _SC_NL_NMAX}, +#endif +#ifdef _SC_NL_SETMAX + {"SC_NL_SETMAX", _SC_NL_SETMAX}, +#endif +#ifdef _SC_NL_TEXTMAX + {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, +#endif +#ifdef _SC_NPROCESSORS_CONF + {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, +#endif +#ifdef _SC_NPROCESSORS_ONLN + {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, +#endif +#ifdef _SC_NPROC_CONF + {"SC_NPROC_CONF", _SC_NPROC_CONF}, +#endif +#ifdef _SC_NPROC_ONLN + {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, +#endif +#ifdef _SC_NZERO + {"SC_NZERO", _SC_NZERO}, +#endif +#ifdef _SC_OPEN_MAX + {"SC_OPEN_MAX", _SC_OPEN_MAX}, +#endif +#ifdef _SC_PAGESIZE + {"SC_PAGESIZE", _SC_PAGESIZE}, +#endif +#ifdef _SC_PAGE_SIZE + {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, +#endif +#ifdef _SC_AIX_REALMEM + {"SC_AIX_REALMEM", _SC_AIX_REALMEM}, #endif - goto error; +#ifdef _SC_PASS_MAX + {"SC_PASS_MAX", _SC_PASS_MAX}, +#endif +#ifdef _SC_PHYS_PAGES + {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, +#endif +#ifdef _SC_PII + {"SC_PII", _SC_PII}, +#endif +#ifdef _SC_PII_INTERNET + {"SC_PII_INTERNET", _SC_PII_INTERNET}, +#endif +#ifdef _SC_PII_INTERNET_DGRAM + {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, +#endif +#ifdef _SC_PII_INTERNET_STREAM + {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, +#endif +#ifdef _SC_PII_OSI + {"SC_PII_OSI", _SC_PII_OSI}, +#endif +#ifdef _SC_PII_OSI_CLTS + {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, +#endif +#ifdef _SC_PII_OSI_COTS + {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, +#endif +#ifdef _SC_PII_OSI_M + {"SC_PII_OSI_M", _SC_PII_OSI_M}, +#endif +#ifdef _SC_PII_SOCKET + {"SC_PII_SOCKET", _SC_PII_SOCKET}, +#endif +#ifdef _SC_PII_XTI + {"SC_PII_XTI", _SC_PII_XTI}, +#endif +#ifdef _SC_POLL + {"SC_POLL", _SC_POLL}, +#endif +#ifdef _SC_PRIORITIZED_IO + {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, +#endif +#ifdef _SC_PRIORITY_SCHEDULING + {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, +#endif +#ifdef _SC_REALTIME_SIGNALS + {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, +#endif +#ifdef _SC_RE_DUP_MAX + {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, +#endif +#ifdef _SC_RTSIG_MAX + {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, +#endif +#ifdef _SC_SAVED_IDS + {"SC_SAVED_IDS", _SC_SAVED_IDS}, +#endif +#ifdef _SC_SCHAR_MAX + {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, +#endif +#ifdef _SC_SCHAR_MIN + {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, +#endif +#ifdef _SC_SELECT + {"SC_SELECT", _SC_SELECT}, +#endif +#ifdef _SC_SEMAPHORES + {"SC_SEMAPHORES", _SC_SEMAPHORES}, +#endif +#ifdef _SC_SEM_NSEMS_MAX + {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, +#endif +#ifdef _SC_SEM_VALUE_MAX + {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, +#endif +#ifdef _SC_SHARED_MEMORY_OBJECTS + {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, +#endif +#ifdef _SC_SHRT_MAX + {"SC_SHRT_MAX", _SC_SHRT_MAX}, +#endif +#ifdef _SC_SHRT_MIN + {"SC_SHRT_MIN", _SC_SHRT_MIN}, +#endif +#ifdef _SC_SIGQUEUE_MAX + {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, +#endif +#ifdef _SC_SIGRT_MAX + {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, +#endif +#ifdef _SC_SIGRT_MIN + {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, +#endif +#ifdef _SC_SOFTPOWER + {"SC_SOFTPOWER", _SC_SOFTPOWER}, +#endif +#ifdef _SC_SPLIT_CACHE + {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, +#endif +#ifdef _SC_SSIZE_MAX + {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, +#endif +#ifdef _SC_STACK_PROT + {"SC_STACK_PROT", _SC_STACK_PROT}, +#endif +#ifdef _SC_STREAM_MAX + {"SC_STREAM_MAX", _SC_STREAM_MAX}, +#endif +#ifdef _SC_SYNCHRONIZED_IO + {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, +#endif +#ifdef _SC_THREADS + {"SC_THREADS", _SC_THREADS}, +#endif +#ifdef _SC_THREAD_ATTR_STACKADDR + {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, +#endif +#ifdef _SC_THREAD_ATTR_STACKSIZE + {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, +#endif +#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS + {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, +#endif +#ifdef _SC_THREAD_KEYS_MAX + {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, +#endif +#ifdef _SC_THREAD_PRIORITY_SCHEDULING + {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, +#endif +#ifdef _SC_THREAD_PRIO_INHERIT + {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, +#endif +#ifdef _SC_THREAD_PRIO_PROTECT + {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, +#endif +#ifdef _SC_THREAD_PROCESS_SHARED + {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, +#endif +#ifdef _SC_THREAD_SAFE_FUNCTIONS + {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, +#endif +#ifdef _SC_THREAD_STACK_MIN + {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, +#endif +#ifdef _SC_THREAD_THREADS_MAX + {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, +#endif +#ifdef _SC_TIMERS + {"SC_TIMERS", _SC_TIMERS}, +#endif +#ifdef _SC_TIMER_MAX + {"SC_TIMER_MAX", _SC_TIMER_MAX}, +#endif +#ifdef _SC_TTY_NAME_MAX + {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, +#endif +#ifdef _SC_TZNAME_MAX + {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, +#endif +#ifdef _SC_T_IOV_MAX + {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, +#endif +#ifdef _SC_UCHAR_MAX + {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, +#endif +#ifdef _SC_UINT_MAX + {"SC_UINT_MAX", _SC_UINT_MAX}, +#endif +#ifdef _SC_UIO_MAXIOV + {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, +#endif +#ifdef _SC_ULONG_MAX + {"SC_ULONG_MAX", _SC_ULONG_MAX}, +#endif +#ifdef _SC_USHRT_MAX + {"SC_USHRT_MAX", _SC_USHRT_MAX}, +#endif +#ifdef _SC_VERSION + {"SC_VERSION", _SC_VERSION}, +#endif +#ifdef _SC_WORD_BIT + {"SC_WORD_BIT", _SC_WORD_BIT}, +#endif +#ifdef _SC_XBS5_ILP32_OFF32 + {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, +#endif +#ifdef _SC_XBS5_ILP32_OFFBIG + {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, +#endif +#ifdef _SC_XBS5_LP64_OFF64 + {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, +#endif +#ifdef _SC_XBS5_LPBIG_OFFBIG + {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, +#endif +#ifdef _SC_XOPEN_CRYPT + {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, +#endif +#ifdef _SC_XOPEN_ENH_I18N + {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, +#endif +#ifdef _SC_XOPEN_LEGACY + {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, +#endif +#ifdef _SC_XOPEN_REALTIME + {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, +#endif +#ifdef _SC_XOPEN_REALTIME_THREADS + {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, +#endif +#ifdef _SC_XOPEN_SHM + {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, +#endif +#ifdef _SC_XOPEN_UNIX + {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, +#endif +#ifdef _SC_XOPEN_VERSION + {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, +#endif +#ifdef _SC_XOPEN_XCU_VERSION + {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, +#endif +#ifdef _SC_XOPEN_XPG2 + {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, +#endif +#ifdef _SC_XOPEN_XPG3 + {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, +#endif +#ifdef _SC_XOPEN_XPG4 + {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, +#endif +}; + +static int +conv_sysconf_confname(PyObject *arg, int *valuep) +{ + return conv_confname(arg, valuep, posix_constants_sysconf, + sizeof(posix_constants_sysconf) + / sizeof(struct constdef)); +} + + +/*[clinic input] +os.sysconf -> long + name: sysconf_confname + / + +Return an integer-valued system configuration variable. +[clinic start generated code]*/ + +static long +os_sysconf_impl(PyObject *module, int name) +/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/ +{ + long value; + + errno = 0; + value = sysconf(name); + if (value == -1 && errno != 0) + posix_error(); + return value; +} +#endif /* HAVE_SYSCONF */ + + +/* This code is used to ensure that the tables of configuration value names + * are in sorted order as required by conv_confname(), and also to build + * the exported dictionaries that are used to publish information about the + * names available on the host platform. + * + * Sorting the table at runtime ensures that the table is properly ordered + * when used, even for platforms we're not able to test on. It also makes + * it easier to add additional entries to the tables. + */ + +static int +cmp_constdefs(const void *v1, const void *v2) +{ + const struct constdef *c1 = + (const struct constdef *) v1; + const struct constdef *c2 = + (const struct constdef *) v2; + + return strcmp(c1->name, c2->name); +} + +static int +setup_confname_table(struct constdef *table, size_t tablesize, + const char *tablename, PyObject *module) +{ + PyObject *d = NULL; + size_t i; + + qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); + d = PyDict_New(); + if (d == NULL) + return -1; + + for (i=0; i < tablesize; ++i) { + PyObject *o = PyLong_FromLong(table[i].value); + if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { + Py_XDECREF(o); + Py_DECREF(d); + return -1; + } + Py_DECREF(o); + } + return PyModule_AddObject(module, tablename, d); +} + +/* Return -1 on failure, 0 on success. */ +static int +setup_confname_tables(PyObject *module) +{ +#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) + if (setup_confname_table(posix_constants_pathconf, + sizeof(posix_constants_pathconf) + / sizeof(struct constdef), + "pathconf_names", module)) + return -1; +#endif +#ifdef HAVE_CONFSTR + if (setup_confname_table(posix_constants_confstr, + sizeof(posix_constants_confstr) + / sizeof(struct constdef), + "confstr_names", module)) + return -1; +#endif +#ifdef HAVE_SYSCONF + if (setup_confname_table(posix_constants_sysconf, + sizeof(posix_constants_sysconf) + / sizeof(struct constdef), + "sysconf_names", module)) + return -1; +#endif + return 0; +} + + +/*[clinic input] +os.abort + +Abort the interpreter immediately. + +This function 'dumps core' or otherwise fails in the hardest way possible +on the hosting operating system. This function never returns. +[clinic start generated code]*/ + +static PyObject * +os_abort_impl(PyObject *module) +/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/ +{ + abort(); + /*NOTREACHED*/ +#ifndef __clang__ + /* Issue #28152: abort() is declared with __attribute__((__noreturn__)). + GCC emits a warning without "return NULL;" (compiler bug?), but Clang + is smarter and emits a warning on the return. */ + Py_FatalError("abort() called from Python code didn't abort!"); + return NULL; +#endif +} + +#ifdef MS_WINDOWS +/* Grab ShellExecute dynamically from shell32 */ +static int has_ShellExecute = -1; +static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR, + LPCWSTR, INT); +static int +check_ShellExecute() +{ + HINSTANCE hShell32; + + /* only recheck */ + if (-1 == has_ShellExecute) { + Py_BEGIN_ALLOW_THREADS + /* Security note: this call is not vulnerable to "DLL hijacking". + SHELL32 is part of "KnownDLLs" and so Windows always load + the system SHELL32.DLL, even if there is another SHELL32.DLL + in the DLL search path. */ + hShell32 = LoadLibraryW(L"SHELL32"); + if (hShell32) { + *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32, + "ShellExecuteW"); + has_ShellExecute = Py_ShellExecuteW != NULL; + } else { + has_ShellExecute = 0; + } + Py_END_ALLOW_THREADS + } + return has_ShellExecute; +} + + +/*[clinic input] +os.startfile + filepath: path_t + operation: Py_UNICODE = NULL + +Start a file with its associated application. + +When "operation" is not specified or "open", this acts like +double-clicking the file in Explorer, or giving the file name as an +argument to the DOS "start" command: the file is opened with whatever +application (if any) its extension is associated. +When another "operation" is given, it specifies what should be done with +the file. A typical operation is "print". + +startfile returns as soon as the associated application is launched. +There is no option to wait for the application to close, and no way +to retrieve the application's exit status. + +The filepath is relative to the current directory. If you want to use +an absolute path, make sure the first character is not a slash ("/"); +the underlying Win32 ShellExecute function doesn't work if it is. +[clinic start generated code]*/ + +static PyObject * +os_startfile_impl(PyObject *module, path_t *filepath, + const Py_UNICODE *operation) +/*[clinic end generated code: output=66dc311c94d50797 input=c940888a5390f039]*/ +{ + HINSTANCE rc; + + if(!check_ShellExecute()) { + /* If the OS doesn't have ShellExecute, return a + NotImplementedError. */ + return PyErr_Format(PyExc_NotImplementedError, + "startfile not available on this platform"); + } + + if (PySys_Audit("os.startfile", "Ou", filepath->object, operation) < 0) { + return NULL; } -#endif - - return (PyObject *)iterator; - -error: - Py_DECREF(iterator); - return NULL; -} - -/* - Return the file system path representation of the object. - - If the object is str or bytes, then allow it to pass through with - an incremented refcount. If the object defines __fspath__(), then - return the result of that method. All other types raise a TypeError. -*/ -PyObject * -PyOS_FSPath(PyObject *path) -{ - /* For error message reasons, this function is manually inlined in - path_converter(). */ - PyObject *func = NULL; - PyObject *path_repr = NULL; - if (PyUnicode_Check(path) || PyBytes_Check(path)) { - Py_INCREF(path); - return path; + Py_BEGIN_ALLOW_THREADS + rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide, + NULL, NULL, SW_SHOWNORMAL); + Py_END_ALLOW_THREADS + + if (rc <= (HINSTANCE)32) { + win32_error_object("startfile", filepath->object); + return NULL; + } + Py_RETURN_NONE; +} +#endif /* MS_WINDOWS */ + + +#ifdef HAVE_GETLOADAVG +/*[clinic input] +os.getloadavg + +Return average recent system load information. + +Return the number of processes in the system run queue averaged over +the last 1, 5, and 15 minutes as a tuple of three floats. +Raises OSError if the load average was unobtainable. +[clinic start generated code]*/ + +static PyObject * +os_getloadavg_impl(PyObject *module) +/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/ +{ + double loadavg[3]; + if (getloadavg(loadavg, 3)!=3) { + PyErr_SetString(PyExc_OSError, "Load averages are unobtainable"); + return NULL; + } else + return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); +} +#endif /* HAVE_GETLOADAVG */ + + +/*[clinic input] +os.device_encoding + fd: int + +Return a string describing the encoding of a terminal's file descriptor. + +The file descriptor must be attached to a terminal. +If the device is not a terminal, return None. +[clinic start generated code]*/ + +static PyObject * +os_device_encoding_impl(PyObject *module, int fd) +/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/ +{ + return _Py_device_encoding(fd); +} + + +#ifdef HAVE_SETRESUID +/*[clinic input] +os.setresuid + + ruid: uid_t + euid: uid_t + suid: uid_t + / + +Set the current process's real, effective, and saved user ids. +[clinic start generated code]*/ + +static PyObject * +os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid) +/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/ +{ + if (setresuid(ruid, euid, suid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETRESUID */ + + +#ifdef HAVE_SETRESGID +/*[clinic input] +os.setresgid + + rgid: gid_t + egid: gid_t + sgid: gid_t + / + +Set the current process's real, effective, and saved group ids. +[clinic start generated code]*/ + +static PyObject * +os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid) +/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/ +{ + if (setresgid(rgid, egid, sgid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETRESGID */ + + +#ifdef HAVE_GETRESUID +/*[clinic input] +os.getresuid + +Return a tuple of the current process's real, effective, and saved user ids. +[clinic start generated code]*/ + +static PyObject * +os_getresuid_impl(PyObject *module) +/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/ +{ + uid_t ruid, euid, suid; + if (getresuid(&ruid, &euid, &suid) < 0) + return posix_error(); + return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid), + _PyLong_FromUid(euid), + _PyLong_FromUid(suid)); +} +#endif /* HAVE_GETRESUID */ + + +#ifdef HAVE_GETRESGID +/*[clinic input] +os.getresgid + +Return a tuple of the current process's real, effective, and saved group ids. +[clinic start generated code]*/ + +static PyObject * +os_getresgid_impl(PyObject *module) +/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/ +{ + gid_t rgid, egid, sgid; + if (getresgid(&rgid, &egid, &sgid) < 0) + return posix_error(); + return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid), + _PyLong_FromGid(egid), + _PyLong_FromGid(sgid)); +} +#endif /* HAVE_GETRESGID */ + + +#ifdef USE_XATTRS +/*[clinic input] +os.getxattr + + path: path_t(allow_fd=True) + attribute: path_t + * + follow_symlinks: bool = True + +Return the value of extended attribute attribute on path. + +path may be either a string, a path-like object, or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, getxattr will examine the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +static PyObject * +os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, + int follow_symlinks) +/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/ +{ + Py_ssize_t i; + PyObject *buffer = NULL; + + if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) + return NULL; + + if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) { + return NULL; } - func = _PyObject_LookupSpecial(path, &PyId___fspath__); - if (NULL == func) { - return PyErr_Format(PyExc_TypeError, - "expected str, bytes or os.PathLike object, " - "not %.200s", - _PyType_Name(Py_TYPE(path))); + for (i = 0; ; i++) { + void *ptr; + ssize_t result; + static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; + Py_ssize_t buffer_size = buffer_sizes[i]; + if (!buffer_size) { + path_error(path); + return NULL; + } + buffer = PyBytes_FromStringAndSize(NULL, buffer_size); + if (!buffer) + return NULL; + ptr = PyBytes_AS_STRING(buffer); + + Py_BEGIN_ALLOW_THREADS; + if (path->fd >= 0) + result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size); + else if (follow_symlinks) + result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size); + else + result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size); + Py_END_ALLOW_THREADS; + + if (result < 0) { + Py_DECREF(buffer); + if (errno == ERANGE) + continue; + path_error(path); + return NULL; + } + + if (result != buffer_size) { + /* Can only shrink. */ + _PyBytes_Resize(&buffer, result); + } + break; + } + + return buffer; +} + + +/*[clinic input] +os.setxattr + + path: path_t(allow_fd=True) + attribute: path_t + value: Py_buffer + flags: int = 0 + * + follow_symlinks: bool = True + +Set extended attribute attribute on path to value. + +path may be either a string, a path-like object, or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, setxattr will modify the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +static PyObject * +os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, + Py_buffer *value, int flags, int follow_symlinks) +/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/ +{ + ssize_t result; + + if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) + return NULL; + + if (PySys_Audit("os.setxattr", "OOy#i", path->object, attribute->object, + value->buf, value->len, flags) < 0) { + return NULL; } - path_repr = _PyObject_CallNoArg(func); - Py_DECREF(func); - if (NULL == path_repr) { + Py_BEGIN_ALLOW_THREADS; + if (path->fd > -1) + result = fsetxattr(path->fd, attribute->narrow, + value->buf, value->len, flags); + else if (follow_symlinks) + result = setxattr(path->narrow, attribute->narrow, + value->buf, value->len, flags); + else + result = lsetxattr(path->narrow, attribute->narrow, + value->buf, value->len, flags); + Py_END_ALLOW_THREADS; + + if (result) { + path_error(path); + return NULL; + } + + Py_RETURN_NONE; +} + + +/*[clinic input] +os.removexattr + + path: path_t(allow_fd=True) + attribute: path_t + * + follow_symlinks: bool = True + +Remove extended attribute attribute on path. + +path may be either a string, a path-like object, or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, removexattr will modify the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +static PyObject * +os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, + int follow_symlinks) +/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/ +{ + ssize_t result; + + if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) + return NULL; + + if (PySys_Audit("os.removexattr", "OO", path->object, attribute->object) < 0) { return NULL; } - if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) { - PyErr_Format(PyExc_TypeError, - "expected %.200s.__fspath__() to return str or bytes, " - "not %.200s", _PyType_Name(Py_TYPE(path)), - _PyType_Name(Py_TYPE(path_repr))); - Py_DECREF(path_repr); + Py_BEGIN_ALLOW_THREADS; + if (path->fd > -1) + result = fremovexattr(path->fd, attribute->narrow); + else if (follow_symlinks) + result = removexattr(path->narrow, attribute->narrow); + else + result = lremovexattr(path->narrow, attribute->narrow); + Py_END_ALLOW_THREADS; + + if (result) { + return path_error(path); + } + + Py_RETURN_NONE; +} + + +/*[clinic input] +os.listxattr + + path: path_t(allow_fd=True, nullable=True) = None + * + follow_symlinks: bool = True + +Return a list of extended attributes on path. + +path may be either None, a string, a path-like object, or an open file descriptor. +if path is None, listxattr will examine the current directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, listxattr will examine the symbolic link itself instead of the file + the link points to. +[clinic start generated code]*/ + +static PyObject * +os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) +/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/ +{ + Py_ssize_t i; + PyObject *result = NULL; + const char *name; + char *buffer = NULL; + + if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) + goto exit; + + if (PySys_Audit("os.listxattr", "(O)", + path->object ? path->object : Py_None) < 0) { return NULL; } - return path_repr; -} - + name = path->narrow ? path->narrow : "."; + + for (i = 0; ; i++) { + const char *start, *trace, *end; + ssize_t length; + static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 }; + Py_ssize_t buffer_size = buffer_sizes[i]; + if (!buffer_size) { + /* ERANGE */ + path_error(path); + break; + } + buffer = PyMem_MALLOC(buffer_size); + if (!buffer) { + PyErr_NoMemory(); + break; + } + + Py_BEGIN_ALLOW_THREADS; + if (path->fd > -1) + length = flistxattr(path->fd, buffer, buffer_size); + else if (follow_symlinks) + length = listxattr(name, buffer, buffer_size); + else + length = llistxattr(name, buffer, buffer_size); + Py_END_ALLOW_THREADS; + + if (length < 0) { + if (errno == ERANGE) { + PyMem_FREE(buffer); + buffer = NULL; + continue; + } + path_error(path); + break; + } + + result = PyList_New(0); + if (!result) { + goto exit; + } + + end = buffer + length; + for (trace = start = buffer; trace != end; trace++) { + if (!*trace) { + int error; + PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start, + trace - start); + if (!attribute) { + Py_DECREF(result); + result = NULL; + goto exit; + } + error = PyList_Append(result, attribute); + Py_DECREF(attribute); + if (error) { + Py_DECREF(result); + result = NULL; + goto exit; + } + start = trace + 1; + } + } + break; + } +exit: + if (buffer) + PyMem_FREE(buffer); + return result; +} +#endif /* USE_XATTRS */ + + +/*[clinic input] +os.urandom + + size: Py_ssize_t + / + +Return a bytes object containing random bytes suitable for cryptographic use. +[clinic start generated code]*/ + +static PyObject * +os_urandom_impl(PyObject *module, Py_ssize_t size) +/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/ +{ + PyObject *bytes; + int result; + + if (size < 0) + return PyErr_Format(PyExc_ValueError, + "negative argument not allowed"); + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) + return NULL; + + result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); + if (result == -1) { + Py_DECREF(bytes); + return NULL; + } + return bytes; +} + +#ifdef HAVE_MEMFD_CREATE /*[clinic input] -os.fspath - - path: object +os.memfd_create -Return the file system path representation of the object. + name: FSConverter + flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC -If the object is str or bytes, then allow it to pass through as-is. If the -object defines __fspath__(), then return the result of that method. All other -types raise a TypeError. [clinic start generated code]*/ static PyObject * -os_fspath_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/ +os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) +/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/ { - return PyOS_FSPath(path); + int fd; + const char *bytes = PyBytes_AS_STRING(name); + Py_BEGIN_ALLOW_THREADS + fd = memfd_create(bytes, flags); + Py_END_ALLOW_THREADS + if (fd == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return PyLong_FromLong(fd); } +#endif -#ifdef HAVE_GETRANDOM_SYSCALL +/* Terminal size querying */ + +PyDoc_STRVAR(TerminalSize_docstring, + "A tuple of (columns, lines) for holding terminal window size"); + +static PyStructSequence_Field TerminalSize_fields[] = { + {"columns", "width of the terminal window in characters"}, + {"lines", "height of the terminal window in characters"}, + {NULL, NULL} +}; + +static PyStructSequence_Desc TerminalSize_desc = { + "os.terminal_size", + TerminalSize_docstring, + TerminalSize_fields, + 2, +}; + +#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) /*[clinic input] -os.getrandom +os.get_terminal_size + + fd: int(c_default="fileno(stdout)", py_default="") = -1 + / + +Return the size of the terminal window as (columns, lines). + +The optional argument fd (default standard output) specifies +which file descriptor should be queried. + +If the file descriptor is not connected to a terminal, an OSError +is thrown. - size: Py_ssize_t - flags: int=0 +This function will only be defined if an implementation is +available for this system. -Obtain a series of random bytes. +shutil.get_terminal_size is the high-level function which should +normally be used, os.get_terminal_size is the low-level implementation. [clinic start generated code]*/ static PyObject * -os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags) -/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/ -{ - PyObject *bytes; - Py_ssize_t n; +os_get_terminal_size_impl(PyObject *module, int fd) +/*[clinic end generated code: output=fbab93acef980508 input=ead5679b82ddb920]*/ +{ + int columns, lines; + PyObject *termsize; + + /* Under some conditions stdout may not be connected and + * fileno(stdout) may point to an invalid file descriptor. For example + * GUI apps don't have valid standard streams by default. + * + * If this happens, and the optional fd argument is not present, + * the ioctl below will fail returning EBADF. This is what we want. + */ + +#ifdef TERMSIZE_USE_IOCTL + { + struct winsize w; + if (ioctl(fd, TIOCGWINSZ, &w)) + return PyErr_SetFromErrno(PyExc_OSError); + columns = w.ws_col; + lines = w.ws_row; + } +#endif /* TERMSIZE_USE_IOCTL */ + +#ifdef TERMSIZE_USE_CONIO + { + DWORD nhandle; + HANDLE handle; + CONSOLE_SCREEN_BUFFER_INFO csbi; + switch (fd) { + case 0: nhandle = STD_INPUT_HANDLE; + break; + case 1: nhandle = STD_OUTPUT_HANDLE; + break; + case 2: nhandle = STD_ERROR_HANDLE; + break; + default: + return PyErr_Format(PyExc_ValueError, "bad file descriptor"); + } + handle = GetStdHandle(nhandle); + if (handle == NULL) + return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); + if (handle == INVALID_HANDLE_VALUE) + return PyErr_SetFromWindowsErr(0); + + if (!GetConsoleScreenBufferInfo(handle, &csbi)) + return PyErr_SetFromWindowsErr(0); + + columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; + lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + } +#endif /* TERMSIZE_USE_CONIO */ + + PyObject *TerminalSizeType = get_posix_state(module)->TerminalSizeType; + termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType); + if (termsize == NULL) + return NULL; + PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns)); + PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines)); + if (PyErr_Occurred()) { + Py_DECREF(termsize); + return NULL; + } + return termsize; +} +#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ + + +/*[clinic input] +os.cpu_count + +Return the number of CPUs in the system; return None if indeterminable. + +This number is not equivalent to the number of CPUs the current process can +use. The number of usable CPUs can be obtained with +``len(os.sched_getaffinity(0))`` +[clinic start generated code]*/ + +static PyObject * +os_cpu_count_impl(PyObject *module) +/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/ +{ + int ncpu = 0; +#ifdef MS_WINDOWS + ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS); +#elif defined(__hpux) + ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); +#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) + ncpu = sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(__DragonFly__) || \ + defined(__OpenBSD__) || \ + defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__APPLE__) + int mib[2]; + size_t len = sizeof(ncpu); + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) + ncpu = 0; +#endif + if (ncpu >= 1) + return PyLong_FromLong(ncpu); + else + Py_RETURN_NONE; +} + + +/*[clinic input] +os.get_inheritable -> bool + + fd: int + / + +Get the close-on-exe flag of the specified file descriptor. +[clinic start generated code]*/ + +static int +os_get_inheritable_impl(PyObject *module, int fd) +/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/ +{ + int return_value; + _Py_BEGIN_SUPPRESS_IPH + return_value = _Py_get_inheritable(fd); + _Py_END_SUPPRESS_IPH + return return_value; +} + + +/*[clinic input] +os.set_inheritable + fd: int + inheritable: int + / + +Set the inheritable flag of the specified file descriptor. +[clinic start generated code]*/ + +static PyObject * +os_set_inheritable_impl(PyObject *module, int fd, int inheritable) +/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/ +{ + int result; + + _Py_BEGIN_SUPPRESS_IPH + result = _Py_set_inheritable(fd, inheritable, NULL); + _Py_END_SUPPRESS_IPH + if (result < 0) + return NULL; + Py_RETURN_NONE; +} + + +#ifdef MS_WINDOWS +/*[clinic input] +os.get_handle_inheritable -> bool + handle: intptr_t + / + +Get the close-on-exe flag of the specified file descriptor. +[clinic start generated code]*/ + +static int +os_get_handle_inheritable_impl(PyObject *module, intptr_t handle) +/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/ +{ + DWORD flags; + + if (!GetHandleInformation((HANDLE)handle, &flags)) { + PyErr_SetFromWindowsErr(0); + return -1; + } + + return flags & HANDLE_FLAG_INHERIT; +} + + +/*[clinic input] +os.set_handle_inheritable + handle: intptr_t + inheritable: bool + / + +Set the inheritable flag of the specified handle. +[clinic start generated code]*/ + +static PyObject * +os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, + int inheritable) +/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/ +{ + DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0; + if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + Py_RETURN_NONE; +} +#endif /* MS_WINDOWS */ + +#ifndef MS_WINDOWS +/*[clinic input] +os.get_blocking -> bool + fd: int + / + +Get the blocking mode of the file descriptor. - if (size < 0) { - errno = EINVAL; - return posix_error(); - } +Return False if the O_NONBLOCK flag is set, True if the flag is cleared. +[clinic start generated code]*/ - bytes = PyBytes_FromStringAndSize(NULL, size); - if (bytes == NULL) { - PyErr_NoMemory(); - return NULL; - } +static int +os_get_blocking_impl(PyObject *module, int fd) +/*[clinic end generated code: output=336a12ad76a61482 input=f4afb59d51560179]*/ +{ + int blocking; + + _Py_BEGIN_SUPPRESS_IPH + blocking = _Py_get_blocking(fd); + _Py_END_SUPPRESS_IPH + return blocking; +} + +/*[clinic input] +os.set_blocking + fd: int + blocking: bool(accept={int}) + / + +Set the blocking mode of the specified file descriptor. - while (1) { - n = syscall(SYS_getrandom, - PyBytes_AS_STRING(bytes), - PyBytes_GET_SIZE(bytes), - flags); - if (n < 0 && errno == EINTR) { - if (PyErr_CheckSignals() < 0) { - goto error; - } +Set the O_NONBLOCK flag if blocking is False, +clear the O_NONBLOCK flag otherwise. +[clinic start generated code]*/ - /* getrandom() was interrupted by a signal: retry */ - continue; - } - break; - } +static PyObject * +os_set_blocking_impl(PyObject *module, int fd, int blocking) +/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/ +{ + int result; + + _Py_BEGIN_SUPPRESS_IPH + result = _Py_set_blocking(fd, blocking); + _Py_END_SUPPRESS_IPH + if (result < 0) + return NULL; + Py_RETURN_NONE; +} +#endif /* !MS_WINDOWS */ + + +/*[clinic input] +class os.DirEntry "DirEntry *" "DirEntryType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/ + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *path; + PyObject *stat; + PyObject *lstat; +#ifdef MS_WINDOWS + struct _Py_stat_struct win32_lstat; + uint64_t win32_file_index; + int got_file_index; +#else /* POSIX */ +#ifdef HAVE_DIRENT_D_TYPE + unsigned char d_type; +#endif + ino_t d_ino; + int dir_fd; +#endif +} DirEntry; + +static PyObject * +_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", _PyType_Name(type)); + return NULL; +} - if (n < 0) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; +static void +DirEntry_dealloc(DirEntry *entry) +{ + PyTypeObject *tp = Py_TYPE(entry); + Py_XDECREF(entry->name); + Py_XDECREF(entry->path); + Py_XDECREF(entry->stat); + Py_XDECREF(entry->lstat); + freefunc free_func = PyType_GetSlot(tp, Py_tp_free); + free_func(entry); + Py_DECREF(tp); +} + +/* Forward reference */ +static int +DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self, + int follow_symlinks, unsigned short mode_bits); + +/*[clinic input] +os.DirEntry.is_symlink -> bool + defining_class: defining_class + / + +Return True if the entry is a symbolic link; cached per entry. +[clinic start generated code]*/ + +static int +os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class) +/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/ +{ +#ifdef MS_WINDOWS + return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK; +#elif defined(HAVE_DIRENT_D_TYPE) + /* POSIX */ + if (self->d_type != DT_UNKNOWN) + return self->d_type == DT_LNK; + else + return DirEntry_test_mode(defining_class, self, 0, S_IFLNK); +#else + /* POSIX without d_type */ + return DirEntry_test_mode(defining_class, self, 0, S_IFLNK); +#endif +} + +static PyObject * +DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) +{ + int result; + STRUCT_STAT st; + PyObject *ub; + +#ifdef MS_WINDOWS + if (!PyUnicode_FSDecoder(self->path, &ub)) + return NULL; +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + const wchar_t *path = PyUnicode_AsUnicode(ub); +_Py_COMP_DIAG_POP +#else /* POSIX */ + if (!PyUnicode_FSConverter(self->path, &ub)) + return NULL; + const char *path = PyBytes_AS_STRING(ub); + if (self->dir_fd != DEFAULT_DIR_FD) { +#ifdef HAVE_FSTATAT + if (HAVE_FSTATAT_RUNTIME) { + result = fstatat(self->dir_fd, path, &st, + follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); + } else + +#endif /* HAVE_FSTATAT */ + { + Py_DECREF(ub); + PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat"); + return NULL; + } + } + else +#endif + { + if (follow_symlinks) + result = STAT(path, &st); + else + result = LSTAT(path, &st); + } + Py_DECREF(ub); + + if (result != 0) + return path_object_error(self->path); + + return _pystat_fromstructstat(module, &st); +} + +static PyObject * +DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self) +{ + if (!self->lstat) { + PyObject *module = PyType_GetModule(defining_class); +#ifdef MS_WINDOWS + self->lstat = _pystat_fromstructstat(module, &self->win32_lstat); +#else /* POSIX */ + self->lstat = DirEntry_fetch_stat(module, self, 0); +#endif + } + Py_XINCREF(self->lstat); + return self->lstat; +} + +/*[clinic input] +os.DirEntry.stat + defining_class: defining_class + / + * + follow_symlinks: bool = True + +Return stat_result object for the entry; cached per entry. +[clinic start generated code]*/ + +static PyObject * +os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class, + int follow_symlinks) +/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/ +{ + if (!follow_symlinks) { + return DirEntry_get_lstat(defining_class, self); } + + if (!self->stat) { + int result = os_DirEntry_is_symlink_impl(self, defining_class); + if (result == -1) { + return NULL; + } + if (result) { + PyObject *module = PyType_GetModule(defining_class); + self->stat = DirEntry_fetch_stat(module, self, 1); + } + else { + self->stat = DirEntry_get_lstat(defining_class, self); + } + } + + Py_XINCREF(self->stat); + return self->stat; +} + +/* Set exception and return -1 on error, 0 for False, 1 for True */ +static int +DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self, + int follow_symlinks, unsigned short mode_bits) +{ + PyObject *stat = NULL; + PyObject *st_mode = NULL; + long mode; + int result; +#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) + int is_symlink; + int need_stat; +#endif +#ifdef MS_WINDOWS + unsigned long dir_bits; +#endif + +#ifdef MS_WINDOWS + is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK; + need_stat = follow_symlinks && is_symlink; +#elif defined(HAVE_DIRENT_D_TYPE) + is_symlink = self->d_type == DT_LNK; + need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink); +#endif + +#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) + if (need_stat) { +#endif + stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks); + if (!stat) { + if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) { + /* If file doesn't exist (anymore), then return False + (i.e., say it's not a file/directory) */ + PyErr_Clear(); + return 0; + } + goto error; + } + _posixstate* state = get_posix_state(PyType_GetModule(defining_class)); + st_mode = PyObject_GetAttr(stat, state->st_mode); + if (!st_mode) + goto error; + + mode = PyLong_AsLong(st_mode); + if (mode == -1 && PyErr_Occurred()) + goto error; + Py_CLEAR(st_mode); + Py_CLEAR(stat); + result = (mode & S_IFMT) == mode_bits; +#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) + } + else if (is_symlink) { + assert(mode_bits != S_IFLNK); + result = 0; + } + else { + assert(mode_bits == S_IFDIR || mode_bits == S_IFREG); +#ifdef MS_WINDOWS + dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY; + if (mode_bits == S_IFDIR) + result = dir_bits != 0; + else + result = dir_bits == 0; +#else /* POSIX */ + if (mode_bits == S_IFDIR) + result = self->d_type == DT_DIR; + else + result = self->d_type == DT_REG; +#endif + } +#endif + + return result; + +error: + Py_XDECREF(st_mode); + Py_XDECREF(stat); + return -1; +} + +/*[clinic input] +os.DirEntry.is_dir -> bool + defining_class: defining_class + / + * + follow_symlinks: bool = True + +Return True if the entry is a directory; cached per entry. +[clinic start generated code]*/ + +static int +os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class, + int follow_symlinks) +/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/ +{ + return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR); +} + +/*[clinic input] +os.DirEntry.is_file -> bool + defining_class: defining_class + / + * + follow_symlinks: bool = True + +Return True if the entry is a file; cached per entry. +[clinic start generated code]*/ + +static int +os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class, + int follow_symlinks) +/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/ +{ + return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG); +} + +/*[clinic input] +os.DirEntry.inode + +Return inode of the entry; cached per entry. +[clinic start generated code]*/ + +static PyObject * +os_DirEntry_inode_impl(DirEntry *self) +/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/ +{ +#ifdef MS_WINDOWS + if (!self->got_file_index) { + PyObject *unicode; + const wchar_t *path; + STRUCT_STAT stat; + int result; + + if (!PyUnicode_FSDecoder(self->path, &unicode)) + return NULL; +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + path = PyUnicode_AsUnicode(unicode); +_Py_COMP_DIAG_POP + result = LSTAT(path, &stat); + Py_DECREF(unicode); + + if (result != 0) + return path_object_error(self->path); + + self->win32_file_index = stat.st_ino; + self->got_file_index = 1; + } + Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index)); + return PyLong_FromUnsignedLongLong(self->win32_file_index); +#else /* POSIX */ + Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino)); + return PyLong_FromUnsignedLongLong(self->d_ino); +#endif +} + +static PyObject * +DirEntry_repr(DirEntry *self) +{ + return PyUnicode_FromFormat("", self->name); +} + +/*[clinic input] +os.DirEntry.__fspath__ + +Returns the path for the entry. +[clinic start generated code]*/ + +static PyObject * +os_DirEntry___fspath___impl(DirEntry *self) +/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/ +{ + Py_INCREF(self->path); + return self->path; +} + +static PyMemberDef DirEntry_members[] = { + {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY, + "the entry's base filename, relative to scandir() \"path\" argument"}, + {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY, + "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"}, + {NULL} +}; + +#include "clinic/posixmodule.c.h" + +static PyMethodDef DirEntry_methods[] = { + OS_DIRENTRY_IS_DIR_METHODDEF + OS_DIRENTRY_IS_FILE_METHODDEF + OS_DIRENTRY_IS_SYMLINK_METHODDEF + OS_DIRENTRY_STAT_METHODDEF + OS_DIRENTRY_INODE_METHODDEF + OS_DIRENTRY___FSPATH___METHODDEF + {"__class_getitem__", (PyCFunction)Py_GenericAlias, + METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, + {NULL} +}; + +static PyType_Slot DirEntryType_slots[] = { + {Py_tp_new, _disabled_new}, + {Py_tp_dealloc, DirEntry_dealloc}, + {Py_tp_repr, DirEntry_repr}, + {Py_tp_methods, DirEntry_methods}, + {Py_tp_members, DirEntry_members}, + {0, 0}, +}; + +static PyType_Spec DirEntryType_spec = { + MODNAME ".DirEntry", + sizeof(DirEntry), + 0, + Py_TPFLAGS_DEFAULT, + DirEntryType_slots +}; + + +#ifdef MS_WINDOWS + +static wchar_t * +join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename) +{ + Py_ssize_t path_len; + Py_ssize_t size; + wchar_t *result; + wchar_t ch; + + if (!path_wide) { /* Default arg: "." */ + path_wide = L"."; + path_len = 1; + } + else { + path_len = wcslen(path_wide); + } + + /* The +1's are for the path separator and the NUL */ + size = path_len + 1 + wcslen(filename) + 1; + result = PyMem_New(wchar_t, size); + if (!result) { + PyErr_NoMemory(); + return NULL; + } + wcscpy(result, path_wide); + if (path_len > 0) { + ch = result[path_len - 1]; + if (ch != SEP && ch != ALTSEP && ch != L':') + result[path_len++] = SEP; + wcscpy(result + path_len, filename); + } + return result; +} + +static PyObject * +DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW) +{ + DirEntry *entry; + BY_HANDLE_FILE_INFORMATION file_info; + ULONG reparse_tag; + wchar_t *joined_path; + + PyObject *DirEntryType = get_posix_state(module)->DirEntryType; + entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); + if (!entry) + return NULL; + entry->name = NULL; + entry->path = NULL; + entry->stat = NULL; + entry->lstat = NULL; + entry->got_file_index = 0; + + entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1); + if (!entry->name) + goto error; + if (path->narrow) { + Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name)); + if (!entry->name) + goto error; + } + + joined_path = join_path_filenameW(path->wide, dataW->cFileName); + if (!joined_path) + goto error; + + entry->path = PyUnicode_FromWideChar(joined_path, -1); + PyMem_Free(joined_path); + if (!entry->path) + goto error; + if (path->narrow) { + Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path)); + if (!entry->path) + goto error; + } + + find_data_to_file_info(dataW, &file_info, &reparse_tag); + _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat); + + return (PyObject *)entry; + +error: + Py_DECREF(entry); + return NULL; +} + +#else /* POSIX */ + +static char * +join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len) +{ + Py_ssize_t path_len; + Py_ssize_t size; + char *result; + + if (!path_narrow) { /* Default arg: "." */ + path_narrow = "."; + path_len = 1; + } + else { + path_len = strlen(path_narrow); + } + + if (filename_len == -1) + filename_len = strlen(filename); + + /* The +1's are for the path separator and the NUL */ + size = path_len + 1 + filename_len + 1; + result = PyMem_New(char, size); + if (!result) { + PyErr_NoMemory(); + return NULL; + } + strcpy(result, path_narrow); + if (path_len > 0 && result[path_len - 1] != '/') + result[path_len++] = '/'; + strcpy(result + path_len, filename); + return result; +} + +static PyObject * +DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, + Py_ssize_t name_len, ino_t d_ino +#ifdef HAVE_DIRENT_D_TYPE + , unsigned char d_type +#endif + ) +{ + DirEntry *entry; + char *joined_path; + + PyObject *DirEntryType = get_posix_state(module)->DirEntryType; + entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); + if (!entry) + return NULL; + entry->name = NULL; + entry->path = NULL; + entry->stat = NULL; + entry->lstat = NULL; + + if (path->fd != -1) { + entry->dir_fd = path->fd; + joined_path = NULL; + } + else { + entry->dir_fd = DEFAULT_DIR_FD; + joined_path = join_path_filename(path->narrow, name, name_len); + if (!joined_path) + goto error; + } + + if (!path->narrow || !PyObject_CheckBuffer(path->object)) { + entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); + if (joined_path) + entry->path = PyUnicode_DecodeFSDefault(joined_path); + } + else { + entry->name = PyBytes_FromStringAndSize(name, name_len); + if (joined_path) + entry->path = PyBytes_FromString(joined_path); + } + PyMem_Free(joined_path); + if (!entry->name) + goto error; + + if (path->fd != -1) { + entry->path = entry->name; + Py_INCREF(entry->path); + } + else if (!entry->path) + goto error; + +#ifdef HAVE_DIRENT_D_TYPE + entry->d_type = d_type; +#endif + entry->d_ino = d_ino; + + return (PyObject *)entry; + +error: + Py_XDECREF(entry); + return NULL; +} + +#endif + + +typedef struct { + PyObject_HEAD + path_t path; +#ifdef MS_WINDOWS + HANDLE handle; + WIN32_FIND_DATAW file_data; + int first_time; +#else /* POSIX */ + DIR *dirp; +#endif +#ifdef HAVE_FDOPENDIR + int fd; +#endif +} ScandirIterator; + +#ifdef MS_WINDOWS + +static int +ScandirIterator_is_closed(ScandirIterator *iterator) +{ + return iterator->handle == INVALID_HANDLE_VALUE; +} + +static void +ScandirIterator_closedir(ScandirIterator *iterator) +{ + HANDLE handle = iterator->handle; + + if (handle == INVALID_HANDLE_VALUE) + return; + + iterator->handle = INVALID_HANDLE_VALUE; + Py_BEGIN_ALLOW_THREADS + FindClose(handle); + Py_END_ALLOW_THREADS +} + +static PyObject * +ScandirIterator_iternext(ScandirIterator *iterator) +{ + WIN32_FIND_DATAW *file_data = &iterator->file_data; + BOOL success; + PyObject *entry; + + /* Happens if the iterator is iterated twice, or closed explicitly */ + if (iterator->handle == INVALID_HANDLE_VALUE) + return NULL; + + while (1) { + if (!iterator->first_time) { + Py_BEGIN_ALLOW_THREADS + success = FindNextFileW(iterator->handle, file_data); + Py_END_ALLOW_THREADS + if (!success) { + /* Error or no more files */ + if (GetLastError() != ERROR_NO_MORE_FILES) + path_error(&iterator->path); + break; + } + } + iterator->first_time = 0; + + /* Skip over . and .. */ + if (wcscmp(file_data->cFileName, L".") != 0 && + wcscmp(file_data->cFileName, L"..") != 0) + { + PyObject *module = PyType_GetModule(Py_TYPE(iterator)); + entry = DirEntry_from_find_data(module, &iterator->path, file_data); + if (!entry) + break; + return entry; + } + + /* Loop till we get a non-dot directory or finish iterating */ + } + + /* Error or no more files */ + ScandirIterator_closedir(iterator); + return NULL; +} + +#else /* POSIX */ + +static int +ScandirIterator_is_closed(ScandirIterator *iterator) +{ + return !iterator->dirp; +} + +static void +ScandirIterator_closedir(ScandirIterator *iterator) +{ + DIR *dirp = iterator->dirp; + + if (!dirp) + return; + + iterator->dirp = NULL; + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FDOPENDIR + if (iterator->path.fd != -1) + rewinddir(dirp); +#endif + closedir(dirp); + Py_END_ALLOW_THREADS + return; +} + +static PyObject * +ScandirIterator_iternext(ScandirIterator *iterator) +{ + struct dirent *direntp; + Py_ssize_t name_len; + int is_dot; + PyObject *entry; + + /* Happens if the iterator is iterated twice, or closed explicitly */ + if (!iterator->dirp) + return NULL; + + while (1) { + errno = 0; + Py_BEGIN_ALLOW_THREADS + direntp = readdir(iterator->dirp); + Py_END_ALLOW_THREADS + + if (!direntp) { + /* Error or no more files */ + if (errno != 0) + path_error(&iterator->path); + break; + } + + /* Skip over . and .. */ + name_len = NAMLEN(direntp); + is_dot = direntp->d_name[0] == '.' && + (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2)); + if (!is_dot) { + PyObject *module = PyType_GetModule(Py_TYPE(iterator)); + entry = DirEntry_from_posix_info(module, + &iterator->path, direntp->d_name, + name_len, direntp->d_ino +#ifdef HAVE_DIRENT_D_TYPE + , direntp->d_type +#endif + ); + if (!entry) + break; + return entry; + } + + /* Loop till we get a non-dot directory or finish iterating */ + } + + /* Error or no more files */ + ScandirIterator_closedir(iterator); + return NULL; +} + +#endif + +static PyObject * +ScandirIterator_close(ScandirIterator *self, PyObject *args) +{ + ScandirIterator_closedir(self); + Py_RETURN_NONE; +} + +static PyObject * +ScandirIterator_enter(PyObject *self, PyObject *args) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +ScandirIterator_exit(ScandirIterator *self, PyObject *args) +{ + ScandirIterator_closedir(self); + Py_RETURN_NONE; +} + +static void +ScandirIterator_finalize(ScandirIterator *iterator) +{ + PyObject *error_type, *error_value, *error_traceback; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + if (!ScandirIterator_is_closed(iterator)) { + ScandirIterator_closedir(iterator); + + if (PyErr_ResourceWarning((PyObject *)iterator, 1, + "unclosed scandir iterator %R", iterator)) { + /* Spurious errors can appear at shutdown */ + if (PyErr_ExceptionMatches(PyExc_Warning)) { + PyErr_WriteUnraisable((PyObject *) iterator); + } + } + } + + path_cleanup(&iterator->path); + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +static void +ScandirIterator_dealloc(ScandirIterator *iterator) +{ + PyTypeObject *tp = Py_TYPE(iterator); + if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) + return; + + freefunc free_func = PyType_GetSlot(tp, Py_tp_free); + free_func(iterator); + Py_DECREF(tp); +} + +static PyMethodDef ScandirIterator_methods[] = { + {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, + {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, + {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, + {NULL} +}; + +static PyType_Slot ScandirIteratorType_slots[] = { + {Py_tp_new, _disabled_new}, + {Py_tp_dealloc, ScandirIterator_dealloc}, + {Py_tp_finalize, ScandirIterator_finalize}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, ScandirIterator_iternext}, + {Py_tp_methods, ScandirIterator_methods}, + {0, 0}, +}; + +static PyType_Spec ScandirIteratorType_spec = { + MODNAME ".ScandirIterator", + sizeof(ScandirIterator), + 0, + // bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since + // PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance. + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + ScandirIteratorType_slots +}; - if (n != size) { - _PyBytes_Resize(&bytes, n); +/*[clinic input] +os.scandir + + path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None + +Return an iterator of DirEntry objects for given path. + +path can be specified as either str, bytes, or a path-like object. If path +is bytes, the names of yielded DirEntry objects will also be bytes; in +all other circumstances they will be str. + +If path is None, uses the path='.'. +[clinic start generated code]*/ + +static PyObject * +os_scandir_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/ +{ + ScandirIterator *iterator; +#ifdef MS_WINDOWS + wchar_t *path_strW; +#else + const char *path_str; +#ifdef HAVE_FDOPENDIR + int fd = -1; +#endif +#endif + + if (PySys_Audit("os.scandir", "O", + path->object ? path->object : Py_None) < 0) { + return NULL; } - return bytes; - -error: - Py_DECREF(bytes); - return NULL; -} -#endif /* HAVE_GETRANDOM_SYSCALL */ - + PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType; + iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType); + if (!iterator) + return NULL; + +#ifdef MS_WINDOWS + iterator->handle = INVALID_HANDLE_VALUE; +#else + iterator->dirp = NULL; +#endif + + memcpy(&iterator->path, path, sizeof(path_t)); + /* Move the ownership to iterator->path */ + path->object = NULL; + path->cleanup = NULL; + +#ifdef MS_WINDOWS + iterator->first_time = 1; + + path_strW = join_path_filenameW(iterator->path.wide, L"*.*"); + if (!path_strW) + goto error; + + Py_BEGIN_ALLOW_THREADS + iterator->handle = FindFirstFileW(path_strW, &iterator->file_data); + Py_END_ALLOW_THREADS + + PyMem_Free(path_strW); + + if (iterator->handle == INVALID_HANDLE_VALUE) { + path_error(&iterator->path); + goto error; + } +#else /* POSIX */ + errno = 0; +#ifdef HAVE_FDOPENDIR + if (iterator->path.fd != -1) { + if (HAVE_FDOPENDIR_RUNTIME) { + /* closedir() closes the FD, so we duplicate it */ + fd = _Py_dup(path->fd); + if (fd == -1) + goto error; + + Py_BEGIN_ALLOW_THREADS + iterator->dirp = fdopendir(fd); + Py_END_ALLOW_THREADS + } else { + PyErr_SetString(PyExc_TypeError, + "scandir: path should be string, bytes, os.PathLike or None, not int"); + return NULL; + } + } + else +#endif + { + if (iterator->path.narrow) + path_str = iterator->path.narrow; + else + path_str = "."; + + Py_BEGIN_ALLOW_THREADS + iterator->dirp = opendir(path_str); + Py_END_ALLOW_THREADS + } + + if (!iterator->dirp) { + path_error(&iterator->path); +#ifdef HAVE_FDOPENDIR + if (fd != -1) { + Py_BEGIN_ALLOW_THREADS + close(fd); + Py_END_ALLOW_THREADS + } +#endif + goto error; + } +#endif + + return (PyObject *)iterator; + +error: + Py_DECREF(iterator); + return NULL; +} + +/* + Return the file system path representation of the object. + + If the object is str or bytes, then allow it to pass through with + an incremented refcount. If the object defines __fspath__(), then + return the result of that method. All other types raise a TypeError. +*/ +PyObject * +PyOS_FSPath(PyObject *path) +{ + /* For error message reasons, this function is manually inlined in + path_converter(). */ + PyObject *func = NULL; + PyObject *path_repr = NULL; + + if (PyUnicode_Check(path) || PyBytes_Check(path)) { + Py_INCREF(path); + return path; + } + + func = _PyObject_LookupSpecial(path, &PyId___fspath__); + if (NULL == func) { + return PyErr_Format(PyExc_TypeError, + "expected str, bytes or os.PathLike object, " + "not %.200s", + _PyType_Name(Py_TYPE(path))); + } + + path_repr = _PyObject_CallNoArg(func); + Py_DECREF(func); + if (NULL == path_repr) { + return NULL; + } + + if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) { + PyErr_Format(PyExc_TypeError, + "expected %.200s.__fspath__() to return str or bytes, " + "not %.200s", _PyType_Name(Py_TYPE(path)), + _PyType_Name(Py_TYPE(path_repr))); + Py_DECREF(path_repr); + return NULL; + } + + return path_repr; +} + +/*[clinic input] +os.fspath + + path: object + +Return the file system path representation of the object. + +If the object is str or bytes, then allow it to pass through as-is. If the +object defines __fspath__(), then return the result of that method. All other +types raise a TypeError. +[clinic start generated code]*/ + +static PyObject * +os_fspath_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/ +{ + return PyOS_FSPath(path); +} + +#ifdef HAVE_GETRANDOM_SYSCALL +/*[clinic input] +os.getrandom + + size: Py_ssize_t + flags: int=0 + +Obtain a series of random bytes. +[clinic start generated code]*/ + +static PyObject * +os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags) +/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/ +{ + PyObject *bytes; + Py_ssize_t n; + + if (size < 0) { + errno = EINVAL; + return posix_error(); + } + + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) { + PyErr_NoMemory(); + return NULL; + } + + while (1) { + n = syscall(SYS_getrandom, + PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes), + flags); + if (n < 0 && errno == EINTR) { + if (PyErr_CheckSignals() < 0) { + goto error; + } + + /* getrandom() was interrupted by a signal: retry */ + continue; + } + break; + } + + if (n < 0) { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + + if (n != size) { + _PyBytes_Resize(&bytes, n); + } + + return bytes; + +error: + Py_DECREF(bytes); + return NULL; +} +#endif /* HAVE_GETRANDOM_SYSCALL */ + #ifdef MS_WINDOWS /* bpo-36085: Helper functions for managing DLL search directories * on win32 */ - + typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory); typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie); @@ -14520,552 +14520,552 @@ os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj) #endif -static PyMethodDef posix_methods[] = { - - OS_STAT_METHODDEF - OS_ACCESS_METHODDEF - OS_TTYNAME_METHODDEF - OS_CHDIR_METHODDEF - OS_CHFLAGS_METHODDEF - OS_CHMOD_METHODDEF - OS_FCHMOD_METHODDEF - OS_LCHMOD_METHODDEF - OS_CHOWN_METHODDEF - OS_FCHOWN_METHODDEF - OS_LCHOWN_METHODDEF - OS_LCHFLAGS_METHODDEF - OS_CHROOT_METHODDEF - OS_CTERMID_METHODDEF - OS_GETCWD_METHODDEF - OS_GETCWDB_METHODDEF - OS_LINK_METHODDEF - OS_LISTDIR_METHODDEF - OS_LSTAT_METHODDEF - OS_MKDIR_METHODDEF - OS_NICE_METHODDEF - OS_GETPRIORITY_METHODDEF - OS_SETPRIORITY_METHODDEF +static PyMethodDef posix_methods[] = { + + OS_STAT_METHODDEF + OS_ACCESS_METHODDEF + OS_TTYNAME_METHODDEF + OS_CHDIR_METHODDEF + OS_CHFLAGS_METHODDEF + OS_CHMOD_METHODDEF + OS_FCHMOD_METHODDEF + OS_LCHMOD_METHODDEF + OS_CHOWN_METHODDEF + OS_FCHOWN_METHODDEF + OS_LCHOWN_METHODDEF + OS_LCHFLAGS_METHODDEF + OS_CHROOT_METHODDEF + OS_CTERMID_METHODDEF + OS_GETCWD_METHODDEF + OS_GETCWDB_METHODDEF + OS_LINK_METHODDEF + OS_LISTDIR_METHODDEF + OS_LSTAT_METHODDEF + OS_MKDIR_METHODDEF + OS_NICE_METHODDEF + OS_GETPRIORITY_METHODDEF + OS_SETPRIORITY_METHODDEF OS_POSIX_SPAWN_METHODDEF OS_POSIX_SPAWNP_METHODDEF OS_READLINK_METHODDEF OS_COPY_FILE_RANGE_METHODDEF - OS_RENAME_METHODDEF - OS_REPLACE_METHODDEF - OS_RMDIR_METHODDEF - OS_SYMLINK_METHODDEF - OS_SYSTEM_METHODDEF - OS_UMASK_METHODDEF - OS_UNAME_METHODDEF - OS_UNLINK_METHODDEF - OS_REMOVE_METHODDEF - OS_UTIME_METHODDEF - OS_TIMES_METHODDEF - OS__EXIT_METHODDEF + OS_RENAME_METHODDEF + OS_REPLACE_METHODDEF + OS_RMDIR_METHODDEF + OS_SYMLINK_METHODDEF + OS_SYSTEM_METHODDEF + OS_UMASK_METHODDEF + OS_UNAME_METHODDEF + OS_UNLINK_METHODDEF + OS_REMOVE_METHODDEF + OS_UTIME_METHODDEF + OS_TIMES_METHODDEF + OS__EXIT_METHODDEF OS__FCOPYFILE_METHODDEF - OS_EXECV_METHODDEF - OS_EXECVE_METHODDEF - OS_SPAWNV_METHODDEF - OS_SPAWNVE_METHODDEF - OS_FORK1_METHODDEF - OS_FORK_METHODDEF - OS_REGISTER_AT_FORK_METHODDEF - OS_SCHED_GET_PRIORITY_MAX_METHODDEF - OS_SCHED_GET_PRIORITY_MIN_METHODDEF - OS_SCHED_GETPARAM_METHODDEF - OS_SCHED_GETSCHEDULER_METHODDEF - OS_SCHED_RR_GET_INTERVAL_METHODDEF - OS_SCHED_SETPARAM_METHODDEF - OS_SCHED_SETSCHEDULER_METHODDEF - OS_SCHED_YIELD_METHODDEF - OS_SCHED_SETAFFINITY_METHODDEF - OS_SCHED_GETAFFINITY_METHODDEF - OS_OPENPTY_METHODDEF - OS_FORKPTY_METHODDEF - OS_GETEGID_METHODDEF - OS_GETEUID_METHODDEF - OS_GETGID_METHODDEF + OS_EXECV_METHODDEF + OS_EXECVE_METHODDEF + OS_SPAWNV_METHODDEF + OS_SPAWNVE_METHODDEF + OS_FORK1_METHODDEF + OS_FORK_METHODDEF + OS_REGISTER_AT_FORK_METHODDEF + OS_SCHED_GET_PRIORITY_MAX_METHODDEF + OS_SCHED_GET_PRIORITY_MIN_METHODDEF + OS_SCHED_GETPARAM_METHODDEF + OS_SCHED_GETSCHEDULER_METHODDEF + OS_SCHED_RR_GET_INTERVAL_METHODDEF + OS_SCHED_SETPARAM_METHODDEF + OS_SCHED_SETSCHEDULER_METHODDEF + OS_SCHED_YIELD_METHODDEF + OS_SCHED_SETAFFINITY_METHODDEF + OS_SCHED_GETAFFINITY_METHODDEF + OS_OPENPTY_METHODDEF + OS_FORKPTY_METHODDEF + OS_GETEGID_METHODDEF + OS_GETEUID_METHODDEF + OS_GETGID_METHODDEF OS_GETGROUPLIST_METHODDEF - OS_GETGROUPS_METHODDEF - OS_GETPID_METHODDEF - OS_GETPGRP_METHODDEF - OS_GETPPID_METHODDEF - OS_GETUID_METHODDEF - OS_GETLOGIN_METHODDEF - OS_KILL_METHODDEF - OS_KILLPG_METHODDEF - OS_PLOCK_METHODDEF - OS_STARTFILE_METHODDEF - OS_SETUID_METHODDEF - OS_SETEUID_METHODDEF - OS_SETREUID_METHODDEF - OS_SETGID_METHODDEF - OS_SETEGID_METHODDEF - OS_SETREGID_METHODDEF - OS_SETGROUPS_METHODDEF + OS_GETGROUPS_METHODDEF + OS_GETPID_METHODDEF + OS_GETPGRP_METHODDEF + OS_GETPPID_METHODDEF + OS_GETUID_METHODDEF + OS_GETLOGIN_METHODDEF + OS_KILL_METHODDEF + OS_KILLPG_METHODDEF + OS_PLOCK_METHODDEF + OS_STARTFILE_METHODDEF + OS_SETUID_METHODDEF + OS_SETEUID_METHODDEF + OS_SETREUID_METHODDEF + OS_SETGID_METHODDEF + OS_SETEGID_METHODDEF + OS_SETREGID_METHODDEF + OS_SETGROUPS_METHODDEF OS_INITGROUPS_METHODDEF - OS_GETPGID_METHODDEF - OS_SETPGRP_METHODDEF - OS_WAIT_METHODDEF - OS_WAIT3_METHODDEF - OS_WAIT4_METHODDEF - OS_WAITID_METHODDEF - OS_WAITPID_METHODDEF + OS_GETPGID_METHODDEF + OS_SETPGRP_METHODDEF + OS_WAIT_METHODDEF + OS_WAIT3_METHODDEF + OS_WAIT4_METHODDEF + OS_WAITID_METHODDEF + OS_WAITPID_METHODDEF OS_PIDFD_OPEN_METHODDEF - OS_GETSID_METHODDEF - OS_SETSID_METHODDEF - OS_SETPGID_METHODDEF - OS_TCGETPGRP_METHODDEF - OS_TCSETPGRP_METHODDEF - OS_OPEN_METHODDEF - OS_CLOSE_METHODDEF - OS_CLOSERANGE_METHODDEF - OS_DEVICE_ENCODING_METHODDEF - OS_DUP_METHODDEF - OS_DUP2_METHODDEF - OS_LOCKF_METHODDEF - OS_LSEEK_METHODDEF - OS_READ_METHODDEF - OS_READV_METHODDEF - OS_PREAD_METHODDEF - OS_PREADV_METHODDEF - OS_WRITE_METHODDEF - OS_WRITEV_METHODDEF - OS_PWRITE_METHODDEF - OS_PWRITEV_METHODDEF + OS_GETSID_METHODDEF + OS_SETSID_METHODDEF + OS_SETPGID_METHODDEF + OS_TCGETPGRP_METHODDEF + OS_TCSETPGRP_METHODDEF + OS_OPEN_METHODDEF + OS_CLOSE_METHODDEF + OS_CLOSERANGE_METHODDEF + OS_DEVICE_ENCODING_METHODDEF + OS_DUP_METHODDEF + OS_DUP2_METHODDEF + OS_LOCKF_METHODDEF + OS_LSEEK_METHODDEF + OS_READ_METHODDEF + OS_READV_METHODDEF + OS_PREAD_METHODDEF + OS_PREADV_METHODDEF + OS_WRITE_METHODDEF + OS_WRITEV_METHODDEF + OS_PWRITE_METHODDEF + OS_PWRITEV_METHODDEF OS_SENDFILE_METHODDEF - OS_FSTAT_METHODDEF - OS_ISATTY_METHODDEF - OS_PIPE_METHODDEF - OS_PIPE2_METHODDEF - OS_MKFIFO_METHODDEF - OS_MKNOD_METHODDEF - OS_MAJOR_METHODDEF - OS_MINOR_METHODDEF - OS_MAKEDEV_METHODDEF - OS_FTRUNCATE_METHODDEF - OS_TRUNCATE_METHODDEF - OS_POSIX_FALLOCATE_METHODDEF - OS_POSIX_FADVISE_METHODDEF - OS_PUTENV_METHODDEF - OS_UNSETENV_METHODDEF - OS_STRERROR_METHODDEF - OS_FCHDIR_METHODDEF - OS_FSYNC_METHODDEF - OS_SYNC_METHODDEF - OS_FDATASYNC_METHODDEF - OS_WCOREDUMP_METHODDEF - OS_WIFCONTINUED_METHODDEF - OS_WIFSTOPPED_METHODDEF - OS_WIFSIGNALED_METHODDEF - OS_WIFEXITED_METHODDEF - OS_WEXITSTATUS_METHODDEF - OS_WTERMSIG_METHODDEF - OS_WSTOPSIG_METHODDEF - OS_FSTATVFS_METHODDEF - OS_STATVFS_METHODDEF - OS_CONFSTR_METHODDEF - OS_SYSCONF_METHODDEF - OS_FPATHCONF_METHODDEF - OS_PATHCONF_METHODDEF - OS_ABORT_METHODDEF - OS__GETFULLPATHNAME_METHODDEF - OS__GETDISKUSAGE_METHODDEF - OS__GETFINALPATHNAME_METHODDEF - OS__GETVOLUMEPATHNAME_METHODDEF + OS_FSTAT_METHODDEF + OS_ISATTY_METHODDEF + OS_PIPE_METHODDEF + OS_PIPE2_METHODDEF + OS_MKFIFO_METHODDEF + OS_MKNOD_METHODDEF + OS_MAJOR_METHODDEF + OS_MINOR_METHODDEF + OS_MAKEDEV_METHODDEF + OS_FTRUNCATE_METHODDEF + OS_TRUNCATE_METHODDEF + OS_POSIX_FALLOCATE_METHODDEF + OS_POSIX_FADVISE_METHODDEF + OS_PUTENV_METHODDEF + OS_UNSETENV_METHODDEF + OS_STRERROR_METHODDEF + OS_FCHDIR_METHODDEF + OS_FSYNC_METHODDEF + OS_SYNC_METHODDEF + OS_FDATASYNC_METHODDEF + OS_WCOREDUMP_METHODDEF + OS_WIFCONTINUED_METHODDEF + OS_WIFSTOPPED_METHODDEF + OS_WIFSIGNALED_METHODDEF + OS_WIFEXITED_METHODDEF + OS_WEXITSTATUS_METHODDEF + OS_WTERMSIG_METHODDEF + OS_WSTOPSIG_METHODDEF + OS_FSTATVFS_METHODDEF + OS_STATVFS_METHODDEF + OS_CONFSTR_METHODDEF + OS_SYSCONF_METHODDEF + OS_FPATHCONF_METHODDEF + OS_PATHCONF_METHODDEF + OS_ABORT_METHODDEF + OS__GETFULLPATHNAME_METHODDEF + OS__GETDISKUSAGE_METHODDEF + OS__GETFINALPATHNAME_METHODDEF + OS__GETVOLUMEPATHNAME_METHODDEF OS__PATH_SPLITROOT_METHODDEF - OS_GETLOADAVG_METHODDEF - OS_URANDOM_METHODDEF - OS_SETRESUID_METHODDEF - OS_SETRESGID_METHODDEF - OS_GETRESUID_METHODDEF - OS_GETRESGID_METHODDEF - - OS_GETXATTR_METHODDEF - OS_SETXATTR_METHODDEF - OS_REMOVEXATTR_METHODDEF - OS_LISTXATTR_METHODDEF - + OS_GETLOADAVG_METHODDEF + OS_URANDOM_METHODDEF + OS_SETRESUID_METHODDEF + OS_SETRESGID_METHODDEF + OS_GETRESUID_METHODDEF + OS_GETRESGID_METHODDEF + + OS_GETXATTR_METHODDEF + OS_SETXATTR_METHODDEF + OS_REMOVEXATTR_METHODDEF + OS_LISTXATTR_METHODDEF + OS_GET_TERMINAL_SIZE_METHODDEF - OS_CPU_COUNT_METHODDEF - OS_GET_INHERITABLE_METHODDEF - OS_SET_INHERITABLE_METHODDEF - OS_GET_HANDLE_INHERITABLE_METHODDEF - OS_SET_HANDLE_INHERITABLE_METHODDEF + OS_CPU_COUNT_METHODDEF + OS_GET_INHERITABLE_METHODDEF + OS_SET_INHERITABLE_METHODDEF + OS_GET_HANDLE_INHERITABLE_METHODDEF + OS_SET_HANDLE_INHERITABLE_METHODDEF OS_GET_BLOCKING_METHODDEF OS_SET_BLOCKING_METHODDEF - OS_SCANDIR_METHODDEF - OS_FSPATH_METHODDEF - OS_GETRANDOM_METHODDEF + OS_SCANDIR_METHODDEF + OS_FSPATH_METHODDEF + OS_GETRANDOM_METHODDEF OS_MEMFD_CREATE_METHODDEF OS__ADD_DLL_DIRECTORY_METHODDEF OS__REMOVE_DLL_DIRECTORY_METHODDEF OS_WAITSTATUS_TO_EXITCODE_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - -static int -all_ins(PyObject *m) -{ -#ifdef F_OK - if (PyModule_AddIntMacro(m, F_OK)) return -1; -#endif -#ifdef R_OK - if (PyModule_AddIntMacro(m, R_OK)) return -1; -#endif -#ifdef W_OK - if (PyModule_AddIntMacro(m, W_OK)) return -1; -#endif -#ifdef X_OK - if (PyModule_AddIntMacro(m, X_OK)) return -1; -#endif -#ifdef NGROUPS_MAX - if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1; -#endif -#ifdef TMP_MAX - if (PyModule_AddIntMacro(m, TMP_MAX)) return -1; -#endif -#ifdef WCONTINUED - if (PyModule_AddIntMacro(m, WCONTINUED)) return -1; -#endif -#ifdef WNOHANG - if (PyModule_AddIntMacro(m, WNOHANG)) return -1; -#endif -#ifdef WUNTRACED - if (PyModule_AddIntMacro(m, WUNTRACED)) return -1; -#endif -#ifdef O_RDONLY - if (PyModule_AddIntMacro(m, O_RDONLY)) return -1; -#endif -#ifdef O_WRONLY - if (PyModule_AddIntMacro(m, O_WRONLY)) return -1; -#endif -#ifdef O_RDWR - if (PyModule_AddIntMacro(m, O_RDWR)) return -1; -#endif -#ifdef O_NDELAY - if (PyModule_AddIntMacro(m, O_NDELAY)) return -1; -#endif -#ifdef O_NONBLOCK - if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1; -#endif -#ifdef O_APPEND - if (PyModule_AddIntMacro(m, O_APPEND)) return -1; -#endif -#ifdef O_DSYNC - if (PyModule_AddIntMacro(m, O_DSYNC)) return -1; -#endif -#ifdef O_RSYNC - if (PyModule_AddIntMacro(m, O_RSYNC)) return -1; -#endif -#ifdef O_SYNC - if (PyModule_AddIntMacro(m, O_SYNC)) return -1; -#endif -#ifdef O_NOCTTY - if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1; -#endif -#ifdef O_CREAT - if (PyModule_AddIntMacro(m, O_CREAT)) return -1; -#endif -#ifdef O_EXCL - if (PyModule_AddIntMacro(m, O_EXCL)) return -1; -#endif -#ifdef O_TRUNC - if (PyModule_AddIntMacro(m, O_TRUNC)) return -1; -#endif -#ifdef O_BINARY - if (PyModule_AddIntMacro(m, O_BINARY)) return -1; -#endif -#ifdef O_TEXT - if (PyModule_AddIntMacro(m, O_TEXT)) return -1; -#endif -#ifdef O_XATTR - if (PyModule_AddIntMacro(m, O_XATTR)) return -1; -#endif -#ifdef O_LARGEFILE - if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1; -#endif -#ifndef __GNU__ -#ifdef O_SHLOCK - if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1; -#endif -#ifdef O_EXLOCK - if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1; -#endif -#endif -#ifdef O_EXEC - if (PyModule_AddIntMacro(m, O_EXEC)) return -1; -#endif -#ifdef O_SEARCH - if (PyModule_AddIntMacro(m, O_SEARCH)) return -1; -#endif -#ifdef O_PATH - if (PyModule_AddIntMacro(m, O_PATH)) return -1; -#endif -#ifdef O_TTY_INIT - if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1; -#endif -#ifdef O_TMPFILE - if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1; -#endif -#ifdef PRIO_PROCESS - if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1; -#endif -#ifdef PRIO_PGRP - if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1; -#endif -#ifdef PRIO_USER - if (PyModule_AddIntMacro(m, PRIO_USER)) return -1; -#endif -#ifdef O_CLOEXEC - if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1; -#endif -#ifdef O_ACCMODE - if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1; -#endif - - -#ifdef SEEK_HOLE - if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1; -#endif -#ifdef SEEK_DATA - if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1; -#endif - -/* MS Windows */ -#ifdef O_NOINHERIT - /* Don't inherit in child processes. */ - if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1; -#endif -#ifdef _O_SHORT_LIVED - /* Optimize for short life (keep in memory). */ - /* MS forgot to define this one with a non-underscore form too. */ - if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1; -#endif -#ifdef O_TEMPORARY - /* Automatically delete when last handle is closed. */ - if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1; -#endif -#ifdef O_RANDOM - /* Optimize for random access. */ - if (PyModule_AddIntMacro(m, O_RANDOM)) return -1; -#endif -#ifdef O_SEQUENTIAL - /* Optimize for sequential access. */ - if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1; -#endif - -/* GNU extensions. */ -#ifdef O_ASYNC - /* Send a SIGIO signal whenever input or output - becomes available on file descriptor */ - if (PyModule_AddIntMacro(m, O_ASYNC)) return -1; -#endif -#ifdef O_DIRECT - /* Direct disk access. */ - if (PyModule_AddIntMacro(m, O_DIRECT)) return -1; -#endif -#ifdef O_DIRECTORY - /* Must be a directory. */ - if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1; -#endif -#ifdef O_NOFOLLOW - /* Do not follow links. */ - if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1; -#endif -#ifdef O_NOLINKS - /* Fails if link count of the named file is greater than 1 */ - if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1; -#endif -#ifdef O_NOATIME - /* Do not update the access time. */ - if (PyModule_AddIntMacro(m, O_NOATIME)) return -1; -#endif - - /* These come from sysexits.h */ -#ifdef EX_OK - if (PyModule_AddIntMacro(m, EX_OK)) return -1; -#endif /* EX_OK */ -#ifdef EX_USAGE - if (PyModule_AddIntMacro(m, EX_USAGE)) return -1; -#endif /* EX_USAGE */ -#ifdef EX_DATAERR - if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1; -#endif /* EX_DATAERR */ -#ifdef EX_NOINPUT - if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1; -#endif /* EX_NOINPUT */ -#ifdef EX_NOUSER - if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1; -#endif /* EX_NOUSER */ -#ifdef EX_NOHOST - if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1; -#endif /* EX_NOHOST */ -#ifdef EX_UNAVAILABLE - if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1; -#endif /* EX_UNAVAILABLE */ -#ifdef EX_SOFTWARE - if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1; -#endif /* EX_SOFTWARE */ -#ifdef EX_OSERR - if (PyModule_AddIntMacro(m, EX_OSERR)) return -1; -#endif /* EX_OSERR */ -#ifdef EX_OSFILE - if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1; -#endif /* EX_OSFILE */ -#ifdef EX_CANTCREAT - if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1; -#endif /* EX_CANTCREAT */ -#ifdef EX_IOERR - if (PyModule_AddIntMacro(m, EX_IOERR)) return -1; -#endif /* EX_IOERR */ -#ifdef EX_TEMPFAIL - if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1; -#endif /* EX_TEMPFAIL */ -#ifdef EX_PROTOCOL - if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1; -#endif /* EX_PROTOCOL */ -#ifdef EX_NOPERM - if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1; -#endif /* EX_NOPERM */ -#ifdef EX_CONFIG - if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1; -#endif /* EX_CONFIG */ -#ifdef EX_NOTFOUND - if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1; -#endif /* EX_NOTFOUND */ - - /* statvfs */ -#ifdef ST_RDONLY - if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1; -#endif /* ST_RDONLY */ -#ifdef ST_NOSUID - if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1; -#endif /* ST_NOSUID */ - - /* GNU extensions */ -#ifdef ST_NODEV - if (PyModule_AddIntMacro(m, ST_NODEV)) return -1; -#endif /* ST_NODEV */ -#ifdef ST_NOEXEC - if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1; -#endif /* ST_NOEXEC */ -#ifdef ST_SYNCHRONOUS - if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1; -#endif /* ST_SYNCHRONOUS */ -#ifdef ST_MANDLOCK - if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1; -#endif /* ST_MANDLOCK */ -#ifdef ST_WRITE - if (PyModule_AddIntMacro(m, ST_WRITE)) return -1; -#endif /* ST_WRITE */ -#ifdef ST_APPEND - if (PyModule_AddIntMacro(m, ST_APPEND)) return -1; -#endif /* ST_APPEND */ -#ifdef ST_NOATIME - if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1; -#endif /* ST_NOATIME */ -#ifdef ST_NODIRATIME - if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1; -#endif /* ST_NODIRATIME */ -#ifdef ST_RELATIME - if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1; -#endif /* ST_RELATIME */ - - /* FreeBSD sendfile() constants */ -#ifdef SF_NODISKIO - if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1; -#endif -#ifdef SF_MNOWAIT - if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1; -#endif -#ifdef SF_SYNC - if (PyModule_AddIntMacro(m, SF_SYNC)) return -1; -#endif - - /* constants for posix_fadvise */ -#ifdef POSIX_FADV_NORMAL - if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1; -#endif -#ifdef POSIX_FADV_SEQUENTIAL - if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1; -#endif -#ifdef POSIX_FADV_RANDOM - if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1; -#endif -#ifdef POSIX_FADV_NOREUSE - if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1; -#endif -#ifdef POSIX_FADV_WILLNEED - if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1; -#endif -#ifdef POSIX_FADV_DONTNEED - if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1; -#endif - - /* constants for waitid */ -#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID) - if (PyModule_AddIntMacro(m, P_PID)) return -1; - if (PyModule_AddIntMacro(m, P_PGID)) return -1; - if (PyModule_AddIntMacro(m, P_ALL)) return -1; + {NULL, NULL} /* Sentinel */ +}; + +static int +all_ins(PyObject *m) +{ +#ifdef F_OK + if (PyModule_AddIntMacro(m, F_OK)) return -1; +#endif +#ifdef R_OK + if (PyModule_AddIntMacro(m, R_OK)) return -1; +#endif +#ifdef W_OK + if (PyModule_AddIntMacro(m, W_OK)) return -1; +#endif +#ifdef X_OK + if (PyModule_AddIntMacro(m, X_OK)) return -1; +#endif +#ifdef NGROUPS_MAX + if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1; +#endif +#ifdef TMP_MAX + if (PyModule_AddIntMacro(m, TMP_MAX)) return -1; +#endif +#ifdef WCONTINUED + if (PyModule_AddIntMacro(m, WCONTINUED)) return -1; +#endif +#ifdef WNOHANG + if (PyModule_AddIntMacro(m, WNOHANG)) return -1; +#endif +#ifdef WUNTRACED + if (PyModule_AddIntMacro(m, WUNTRACED)) return -1; +#endif +#ifdef O_RDONLY + if (PyModule_AddIntMacro(m, O_RDONLY)) return -1; +#endif +#ifdef O_WRONLY + if (PyModule_AddIntMacro(m, O_WRONLY)) return -1; +#endif +#ifdef O_RDWR + if (PyModule_AddIntMacro(m, O_RDWR)) return -1; +#endif +#ifdef O_NDELAY + if (PyModule_AddIntMacro(m, O_NDELAY)) return -1; +#endif +#ifdef O_NONBLOCK + if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1; +#endif +#ifdef O_APPEND + if (PyModule_AddIntMacro(m, O_APPEND)) return -1; +#endif +#ifdef O_DSYNC + if (PyModule_AddIntMacro(m, O_DSYNC)) return -1; +#endif +#ifdef O_RSYNC + if (PyModule_AddIntMacro(m, O_RSYNC)) return -1; +#endif +#ifdef O_SYNC + if (PyModule_AddIntMacro(m, O_SYNC)) return -1; +#endif +#ifdef O_NOCTTY + if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1; +#endif +#ifdef O_CREAT + if (PyModule_AddIntMacro(m, O_CREAT)) return -1; +#endif +#ifdef O_EXCL + if (PyModule_AddIntMacro(m, O_EXCL)) return -1; +#endif +#ifdef O_TRUNC + if (PyModule_AddIntMacro(m, O_TRUNC)) return -1; +#endif +#ifdef O_BINARY + if (PyModule_AddIntMacro(m, O_BINARY)) return -1; +#endif +#ifdef O_TEXT + if (PyModule_AddIntMacro(m, O_TEXT)) return -1; +#endif +#ifdef O_XATTR + if (PyModule_AddIntMacro(m, O_XATTR)) return -1; +#endif +#ifdef O_LARGEFILE + if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1; +#endif +#ifndef __GNU__ +#ifdef O_SHLOCK + if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1; +#endif +#ifdef O_EXLOCK + if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1; +#endif +#endif +#ifdef O_EXEC + if (PyModule_AddIntMacro(m, O_EXEC)) return -1; +#endif +#ifdef O_SEARCH + if (PyModule_AddIntMacro(m, O_SEARCH)) return -1; +#endif +#ifdef O_PATH + if (PyModule_AddIntMacro(m, O_PATH)) return -1; +#endif +#ifdef O_TTY_INIT + if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1; +#endif +#ifdef O_TMPFILE + if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1; +#endif +#ifdef PRIO_PROCESS + if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1; +#endif +#ifdef PRIO_PGRP + if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1; +#endif +#ifdef PRIO_USER + if (PyModule_AddIntMacro(m, PRIO_USER)) return -1; +#endif +#ifdef O_CLOEXEC + if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1; +#endif +#ifdef O_ACCMODE + if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1; +#endif + + +#ifdef SEEK_HOLE + if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1; +#endif +#ifdef SEEK_DATA + if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1; +#endif + +/* MS Windows */ +#ifdef O_NOINHERIT + /* Don't inherit in child processes. */ + if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1; +#endif +#ifdef _O_SHORT_LIVED + /* Optimize for short life (keep in memory). */ + /* MS forgot to define this one with a non-underscore form too. */ + if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1; +#endif +#ifdef O_TEMPORARY + /* Automatically delete when last handle is closed. */ + if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1; +#endif +#ifdef O_RANDOM + /* Optimize for random access. */ + if (PyModule_AddIntMacro(m, O_RANDOM)) return -1; +#endif +#ifdef O_SEQUENTIAL + /* Optimize for sequential access. */ + if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1; +#endif + +/* GNU extensions. */ +#ifdef O_ASYNC + /* Send a SIGIO signal whenever input or output + becomes available on file descriptor */ + if (PyModule_AddIntMacro(m, O_ASYNC)) return -1; +#endif +#ifdef O_DIRECT + /* Direct disk access. */ + if (PyModule_AddIntMacro(m, O_DIRECT)) return -1; +#endif +#ifdef O_DIRECTORY + /* Must be a directory. */ + if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1; +#endif +#ifdef O_NOFOLLOW + /* Do not follow links. */ + if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1; +#endif +#ifdef O_NOLINKS + /* Fails if link count of the named file is greater than 1 */ + if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1; +#endif +#ifdef O_NOATIME + /* Do not update the access time. */ + if (PyModule_AddIntMacro(m, O_NOATIME)) return -1; +#endif + + /* These come from sysexits.h */ +#ifdef EX_OK + if (PyModule_AddIntMacro(m, EX_OK)) return -1; +#endif /* EX_OK */ +#ifdef EX_USAGE + if (PyModule_AddIntMacro(m, EX_USAGE)) return -1; +#endif /* EX_USAGE */ +#ifdef EX_DATAERR + if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1; +#endif /* EX_DATAERR */ +#ifdef EX_NOINPUT + if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1; +#endif /* EX_NOINPUT */ +#ifdef EX_NOUSER + if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1; +#endif /* EX_NOUSER */ +#ifdef EX_NOHOST + if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1; +#endif /* EX_NOHOST */ +#ifdef EX_UNAVAILABLE + if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1; +#endif /* EX_UNAVAILABLE */ +#ifdef EX_SOFTWARE + if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1; +#endif /* EX_SOFTWARE */ +#ifdef EX_OSERR + if (PyModule_AddIntMacro(m, EX_OSERR)) return -1; +#endif /* EX_OSERR */ +#ifdef EX_OSFILE + if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1; +#endif /* EX_OSFILE */ +#ifdef EX_CANTCREAT + if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1; +#endif /* EX_CANTCREAT */ +#ifdef EX_IOERR + if (PyModule_AddIntMacro(m, EX_IOERR)) return -1; +#endif /* EX_IOERR */ +#ifdef EX_TEMPFAIL + if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1; +#endif /* EX_TEMPFAIL */ +#ifdef EX_PROTOCOL + if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1; +#endif /* EX_PROTOCOL */ +#ifdef EX_NOPERM + if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1; +#endif /* EX_NOPERM */ +#ifdef EX_CONFIG + if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1; +#endif /* EX_CONFIG */ +#ifdef EX_NOTFOUND + if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1; +#endif /* EX_NOTFOUND */ + + /* statvfs */ +#ifdef ST_RDONLY + if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1; +#endif /* ST_RDONLY */ +#ifdef ST_NOSUID + if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1; +#endif /* ST_NOSUID */ + + /* GNU extensions */ +#ifdef ST_NODEV + if (PyModule_AddIntMacro(m, ST_NODEV)) return -1; +#endif /* ST_NODEV */ +#ifdef ST_NOEXEC + if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1; +#endif /* ST_NOEXEC */ +#ifdef ST_SYNCHRONOUS + if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1; +#endif /* ST_SYNCHRONOUS */ +#ifdef ST_MANDLOCK + if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1; +#endif /* ST_MANDLOCK */ +#ifdef ST_WRITE + if (PyModule_AddIntMacro(m, ST_WRITE)) return -1; +#endif /* ST_WRITE */ +#ifdef ST_APPEND + if (PyModule_AddIntMacro(m, ST_APPEND)) return -1; +#endif /* ST_APPEND */ +#ifdef ST_NOATIME + if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1; +#endif /* ST_NOATIME */ +#ifdef ST_NODIRATIME + if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1; +#endif /* ST_NODIRATIME */ +#ifdef ST_RELATIME + if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1; +#endif /* ST_RELATIME */ + + /* FreeBSD sendfile() constants */ +#ifdef SF_NODISKIO + if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1; +#endif +#ifdef SF_MNOWAIT + if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1; +#endif +#ifdef SF_SYNC + if (PyModule_AddIntMacro(m, SF_SYNC)) return -1; +#endif + + /* constants for posix_fadvise */ +#ifdef POSIX_FADV_NORMAL + if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1; +#endif +#ifdef POSIX_FADV_SEQUENTIAL + if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1; +#endif +#ifdef POSIX_FADV_RANDOM + if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1; +#endif +#ifdef POSIX_FADV_NOREUSE + if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1; +#endif +#ifdef POSIX_FADV_WILLNEED + if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1; +#endif +#ifdef POSIX_FADV_DONTNEED + if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1; +#endif + + /* constants for waitid */ +#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID) + if (PyModule_AddIntMacro(m, P_PID)) return -1; + if (PyModule_AddIntMacro(m, P_PGID)) return -1; + if (PyModule_AddIntMacro(m, P_ALL)) return -1; #ifdef P_PIDFD if (PyModule_AddIntMacro(m, P_PIDFD)) return -1; -#endif -#endif -#ifdef WEXITED - if (PyModule_AddIntMacro(m, WEXITED)) return -1; -#endif -#ifdef WNOWAIT - if (PyModule_AddIntMacro(m, WNOWAIT)) return -1; -#endif -#ifdef WSTOPPED - if (PyModule_AddIntMacro(m, WSTOPPED)) return -1; -#endif -#ifdef CLD_EXITED - if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1; -#endif +#endif +#endif +#ifdef WEXITED + if (PyModule_AddIntMacro(m, WEXITED)) return -1; +#endif +#ifdef WNOWAIT + if (PyModule_AddIntMacro(m, WNOWAIT)) return -1; +#endif +#ifdef WSTOPPED + if (PyModule_AddIntMacro(m, WSTOPPED)) return -1; +#endif +#ifdef CLD_EXITED + if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1; +#endif #ifdef CLD_KILLED if (PyModule_AddIntMacro(m, CLD_KILLED)) return -1; #endif -#ifdef CLD_DUMPED - if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1; -#endif -#ifdef CLD_TRAPPED - if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1; -#endif +#ifdef CLD_DUMPED + if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1; +#endif +#ifdef CLD_TRAPPED + if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1; +#endif #ifdef CLD_STOPPED if (PyModule_AddIntMacro(m, CLD_STOPPED)) return -1; #endif -#ifdef CLD_CONTINUED - if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1; -#endif - - /* constants for lockf */ -#ifdef F_LOCK - if (PyModule_AddIntMacro(m, F_LOCK)) return -1; -#endif -#ifdef F_TLOCK - if (PyModule_AddIntMacro(m, F_TLOCK)) return -1; -#endif -#ifdef F_ULOCK - if (PyModule_AddIntMacro(m, F_ULOCK)) return -1; -#endif -#ifdef F_TEST - if (PyModule_AddIntMacro(m, F_TEST)) return -1; -#endif - -#ifdef RWF_DSYNC - if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1; -#endif -#ifdef RWF_HIPRI - if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1; -#endif -#ifdef RWF_SYNC - if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1; -#endif -#ifdef RWF_NOWAIT - if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1; -#endif - +#ifdef CLD_CONTINUED + if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1; +#endif + + /* constants for lockf */ +#ifdef F_LOCK + if (PyModule_AddIntMacro(m, F_LOCK)) return -1; +#endif +#ifdef F_TLOCK + if (PyModule_AddIntMacro(m, F_TLOCK)) return -1; +#endif +#ifdef F_ULOCK + if (PyModule_AddIntMacro(m, F_ULOCK)) return -1; +#endif +#ifdef F_TEST + if (PyModule_AddIntMacro(m, F_TEST)) return -1; +#endif + +#ifdef RWF_DSYNC + if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1; +#endif +#ifdef RWF_HIPRI + if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1; +#endif +#ifdef RWF_SYNC + if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1; +#endif +#ifdef RWF_NOWAIT + if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1; +#endif + /* constants for posix_spawn */ #ifdef HAVE_POSIX_SPAWN if (PyModule_AddIntConstant(m, "POSIX_SPAWN_OPEN", POSIX_SPAWN_OPEN)) return -1; @@ -15074,86 +15074,86 @@ all_ins(PyObject *m) #endif #if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN) - if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1; - if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1; + if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1; + if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1; if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1; #endif #ifdef HAVE_SPAWNV - if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1; - if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1; -#endif - -#ifdef HAVE_SCHED_H -#ifdef SCHED_OTHER - if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1; -#endif -#ifdef SCHED_FIFO - if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1; -#endif -#ifdef SCHED_RR - if (PyModule_AddIntMacro(m, SCHED_RR)) return -1; -#endif -#ifdef SCHED_SPORADIC - if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1; -#endif -#ifdef SCHED_BATCH - if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1; -#endif -#ifdef SCHED_IDLE - if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1; -#endif -#ifdef SCHED_RESET_ON_FORK - if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1; -#endif -#ifdef SCHED_SYS - if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1; -#endif -#ifdef SCHED_IA - if (PyModule_AddIntMacro(m, SCHED_IA)) return -1; -#endif -#ifdef SCHED_FSS - if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1; -#endif -#ifdef SCHED_FX - if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1; -#endif -#endif - -#ifdef USE_XATTRS - if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1; - if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1; - if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1; -#endif - -#if HAVE_DECL_RTLD_LAZY - if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1; -#endif -#if HAVE_DECL_RTLD_NOW - if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1; -#endif -#if HAVE_DECL_RTLD_GLOBAL - if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1; -#endif -#if HAVE_DECL_RTLD_LOCAL - if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1; -#endif -#if HAVE_DECL_RTLD_NODELETE - if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1; -#endif -#if HAVE_DECL_RTLD_NOLOAD - if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1; -#endif -#if HAVE_DECL_RTLD_DEEPBIND - if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1; -#endif -#if HAVE_DECL_RTLD_MEMBER - if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1; -#endif - -#ifdef HAVE_GETRANDOM_SYSCALL - if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1; - if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1; -#endif + if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1; + if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1; +#endif + +#ifdef HAVE_SCHED_H +#ifdef SCHED_OTHER + if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1; +#endif +#ifdef SCHED_FIFO + if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1; +#endif +#ifdef SCHED_RR + if (PyModule_AddIntMacro(m, SCHED_RR)) return -1; +#endif +#ifdef SCHED_SPORADIC + if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1; +#endif +#ifdef SCHED_BATCH + if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1; +#endif +#ifdef SCHED_IDLE + if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1; +#endif +#ifdef SCHED_RESET_ON_FORK + if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1; +#endif +#ifdef SCHED_SYS + if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1; +#endif +#ifdef SCHED_IA + if (PyModule_AddIntMacro(m, SCHED_IA)) return -1; +#endif +#ifdef SCHED_FSS + if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1; +#endif +#ifdef SCHED_FX + if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1; +#endif +#endif + +#ifdef USE_XATTRS + if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1; + if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1; + if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1; +#endif + +#if HAVE_DECL_RTLD_LAZY + if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1; +#endif +#if HAVE_DECL_RTLD_NOW + if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1; +#endif +#if HAVE_DECL_RTLD_GLOBAL + if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1; +#endif +#if HAVE_DECL_RTLD_LOCAL + if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1; +#endif +#if HAVE_DECL_RTLD_NODELETE + if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1; +#endif +#if HAVE_DECL_RTLD_NOLOAD + if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1; +#endif +#if HAVE_DECL_RTLD_DEEPBIND + if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1; +#endif +#if HAVE_DECL_RTLD_MEMBER + if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1; +#endif + +#ifdef HAVE_GETRANDOM_SYSCALL + if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1; + if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1; +#endif #ifdef HAVE_MEMFD_CREATE if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1; if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1; @@ -15203,7 +15203,7 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1; #endif #endif - + #if defined(__APPLE__) if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1; #endif @@ -15216,11 +15216,11 @@ all_ins(PyObject *m) if (PyModule_AddIntConstant(m, "_LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR", LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)) return -1; #endif - return 0; -} - - - + return 0; +} + + + #define PROBE(name, test) \ static int name(void) \ { \ @@ -15230,15 +15230,15 @@ all_ins(PyObject *m) return 0; \ } \ } - + #ifdef HAVE_FSTATAT PROBE(probe_fstatat, HAVE_FSTATAT_RUNTIME) #endif - -#ifdef HAVE_FACCESSAT + +#ifdef HAVE_FACCESSAT PROBE(probe_faccessat, HAVE_FACCESSAT_RUNTIME) -#endif - +#endif + #ifdef HAVE_FCHMODAT PROBE(probe_fchmodat, HAVE_FCHMODAT_RUNTIME) #endif @@ -15299,143 +15299,143 @@ static const struct have_function { { "HAVE_FACCESSAT", probe_faccessat }, #endif -#ifdef HAVE_FCHDIR +#ifdef HAVE_FCHDIR { "HAVE_FCHDIR", NULL }, -#endif - -#ifdef HAVE_FCHMOD +#endif + +#ifdef HAVE_FCHMOD { "HAVE_FCHMOD", NULL }, -#endif - -#ifdef HAVE_FCHMODAT +#endif + +#ifdef HAVE_FCHMODAT { "HAVE_FCHMODAT", probe_fchmodat }, -#endif - -#ifdef HAVE_FCHOWN +#endif + +#ifdef HAVE_FCHOWN { "HAVE_FCHOWN", NULL }, -#endif - -#ifdef HAVE_FCHOWNAT +#endif + +#ifdef HAVE_FCHOWNAT { "HAVE_FCHOWNAT", probe_fchownat }, -#endif - -#ifdef HAVE_FEXECVE +#endif + +#ifdef HAVE_FEXECVE { "HAVE_FEXECVE", NULL }, -#endif - -#ifdef HAVE_FDOPENDIR +#endif + +#ifdef HAVE_FDOPENDIR { "HAVE_FDOPENDIR", probe_fdopendir }, -#endif - -#ifdef HAVE_FPATHCONF +#endif + +#ifdef HAVE_FPATHCONF { "HAVE_FPATHCONF", NULL }, -#endif - -#ifdef HAVE_FSTATAT +#endif + +#ifdef HAVE_FSTATAT { "HAVE_FSTATAT", probe_fstatat }, -#endif - -#ifdef HAVE_FSTATVFS +#endif + +#ifdef HAVE_FSTATVFS { "HAVE_FSTATVFS", NULL }, -#endif - -#if defined HAVE_FTRUNCATE || defined MS_WINDOWS +#endif + +#if defined HAVE_FTRUNCATE || defined MS_WINDOWS { "HAVE_FTRUNCATE", NULL }, -#endif - -#ifdef HAVE_FUTIMENS +#endif + +#ifdef HAVE_FUTIMENS { "HAVE_FUTIMENS", probe_futimens }, -#endif - -#ifdef HAVE_FUTIMES +#endif + +#ifdef HAVE_FUTIMES { "HAVE_FUTIMES", NULL }, -#endif - -#ifdef HAVE_FUTIMESAT +#endif + +#ifdef HAVE_FUTIMESAT { "HAVE_FUTIMESAT", NULL }, -#endif - -#ifdef HAVE_LINKAT +#endif + +#ifdef HAVE_LINKAT { "HAVE_LINKAT", probe_linkat }, -#endif - -#ifdef HAVE_LCHFLAGS +#endif + +#ifdef HAVE_LCHFLAGS { "HAVE_LCHFLAGS", NULL }, -#endif - -#ifdef HAVE_LCHMOD +#endif + +#ifdef HAVE_LCHMOD { "HAVE_LCHMOD", NULL }, -#endif - -#ifdef HAVE_LCHOWN +#endif + +#ifdef HAVE_LCHOWN { "HAVE_LCHOWN", NULL }, -#endif - -#ifdef HAVE_LSTAT +#endif + +#ifdef HAVE_LSTAT { "HAVE_LSTAT", NULL }, -#endif - -#ifdef HAVE_LUTIMES +#endif + +#ifdef HAVE_LUTIMES { "HAVE_LUTIMES", NULL }, -#endif - +#endif + #ifdef HAVE_MEMFD_CREATE { "HAVE_MEMFD_CREATE", NULL }, #endif -#ifdef HAVE_MKDIRAT +#ifdef HAVE_MKDIRAT { "HAVE_MKDIRAT", probe_mkdirat }, -#endif - -#ifdef HAVE_MKFIFOAT +#endif + +#ifdef HAVE_MKFIFOAT { "HAVE_MKFIFOAT", NULL }, -#endif - -#ifdef HAVE_MKNODAT +#endif + +#ifdef HAVE_MKNODAT { "HAVE_MKNODAT", NULL }, -#endif - -#ifdef HAVE_OPENAT +#endif + +#ifdef HAVE_OPENAT { "HAVE_OPENAT", probe_openat }, -#endif - -#ifdef HAVE_READLINKAT +#endif + +#ifdef HAVE_READLINKAT { "HAVE_READLINKAT", probe_readlinkat }, -#endif - -#ifdef HAVE_RENAMEAT +#endif + +#ifdef HAVE_RENAMEAT { "HAVE_RENAMEAT", probe_renameat }, -#endif - -#ifdef HAVE_SYMLINKAT +#endif + +#ifdef HAVE_SYMLINKAT { "HAVE_SYMLINKAT", probe_symlinkat }, -#endif - -#ifdef HAVE_UNLINKAT +#endif + +#ifdef HAVE_UNLINKAT { "HAVE_UNLINKAT", probe_unlinkat }, -#endif - -#ifdef HAVE_UTIMENSAT +#endif + +#ifdef HAVE_UTIMENSAT { "HAVE_UTIMENSAT", probe_utimensat }, -#endif - -#ifdef MS_WINDOWS +#endif + +#ifdef MS_WINDOWS { "MS_WINDOWS", NULL }, -#endif - +#endif + { NULL, NULL } -}; - - +}; + + static int posixmodule_exec(PyObject *m) -{ +{ _posixstate *state = get_posix_state(m); - + #if defined(HAVE_PWRITEV) if (HAVE_PWRITEV_RUNTIME) {} else { PyObject* dct = PyModule_GetDict(m); - + if (dct == NULL) { return -1; } @@ -15449,23 +15449,23 @@ posixmodule_exec(PyObject *m) } #endif - /* Initialize environ dictionary */ + /* Initialize environ dictionary */ PyObject *v = convertenviron(); - Py_XINCREF(v); - if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) + Py_XINCREF(v); + if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) return -1; - Py_DECREF(v); - - if (all_ins(m)) + Py_DECREF(v); + + if (all_ins(m)) return -1; - - if (setup_confname_tables(m)) + + if (setup_confname_tables(m)) return -1; - - Py_INCREF(PyExc_OSError); - PyModule_AddObject(m, "error", PyExc_OSError); - -#if defined(HAVE_WAITID) && !defined(__APPLE__) + + Py_INCREF(PyExc_OSError); + PyModule_AddObject(m, "error", PyExc_OSError); + +#if defined(HAVE_WAITID) && !defined(__APPLE__) waitid_result_desc.name = MODNAME ".waitid_result"; PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc); if (WaitidResultType == NULL) { @@ -15474,8 +15474,8 @@ posixmodule_exec(PyObject *m) Py_INCREF(WaitidResultType); PyModule_AddObject(m, "waitid_result", WaitidResultType); state->WaitidResultType = WaitidResultType; -#endif - +#endif + stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; @@ -15489,7 +15489,7 @@ posixmodule_exec(PyObject *m) state->StatResultType = StatResultType; structseq_new = ((PyTypeObject *)StatResultType)->tp_new; ((PyTypeObject *)StatResultType)->tp_new = statresult_new; - + statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc); if (StatVFSResultType == NULL) { @@ -15498,16 +15498,16 @@ posixmodule_exec(PyObject *m) Py_INCREF(StatVFSResultType); PyModule_AddObject(m, "statvfs_result", StatVFSResultType); state->StatVFSResultType = StatVFSResultType; -#ifdef NEED_TICKS_PER_SECOND -# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) +#ifdef NEED_TICKS_PER_SECOND +# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) ticks_per_second = sysconf(_SC_CLK_TCK); -# elif defined(HZ) +# elif defined(HZ) ticks_per_second = HZ; -# else +# else ticks_per_second = 60; /* magic fallback value; may be bogus */ -# endif -#endif - +# endif +#endif + #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) sched_param_desc.name = MODNAME ".sched_param"; PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc); @@ -15518,8 +15518,8 @@ posixmodule_exec(PyObject *m) PyModule_AddObject(m, "sched_param", SchedParamType); state->SchedParamType = SchedParamType; ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param; -#endif - +#endif + /* initialize TerminalSize_info */ PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc); if (TerminalSizeType == NULL) { @@ -15528,14 +15528,14 @@ posixmodule_exec(PyObject *m) Py_INCREF(TerminalSizeType); PyModule_AddObject(m, "terminal_size", TerminalSizeType); state->TerminalSizeType = TerminalSizeType; - + /* initialize scandir types */ PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL); if (ScandirIteratorType == NULL) { return -1; - } + } state->ScandirIteratorType = ScandirIteratorType; - + PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL); if (DirEntryType == NULL) { return -1; @@ -15543,8 +15543,8 @@ posixmodule_exec(PyObject *m) Py_INCREF(DirEntryType); PyModule_AddObject(m, "DirEntry", DirEntryType); state->DirEntryType = DirEntryType; - - times_result_desc.name = MODNAME ".times_result"; + + times_result_desc.name = MODNAME ".times_result"; PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(×_result_desc); if (TimesResultType == NULL) { return -1; @@ -15552,7 +15552,7 @@ posixmodule_exec(PyObject *m) Py_INCREF(TimesResultType); PyModule_AddObject(m, "times_result", TimesResultType); state->TimesResultType = TimesResultType; - + PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc); if (UnameResultType == NULL) { return -1; @@ -15560,7 +15560,7 @@ posixmodule_exec(PyObject *m) Py_INCREF(UnameResultType); PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType); state->UnameResultType = (PyObject *)UnameResultType; - + if ((state->billion = PyLong_FromLong(1000000000)) == NULL) return -1; #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) @@ -15571,21 +15571,21 @@ posixmodule_exec(PyObject *m) state->st_mode = PyUnicode_InternFromString("st_mode"); if (state->st_mode == NULL) return -1; - - /* suppress "function not used" warnings */ - { - int ignored; - fd_specified("", -1); - follow_symlinks_specified("", 1); - dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1); - dir_fd_converter(Py_None, &ignored); - dir_fd_unavailable(Py_None, &ignored); - } - - /* - * provide list of locally available functions - * so os.py can populate support_* lists - */ + + /* suppress "function not used" warnings */ + { + int ignored; + fd_specified("", -1); + follow_symlinks_specified("", 1); + dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1); + dir_fd_converter(Py_None, &ignored); + dir_fd_unavailable(Py_None, &ignored); + } + + /* + * provide list of locally available functions + * so os.py can populate support_* lists + */ PyObject *list = PyList_New(0); if (!list) { return -1; @@ -15594,19 +15594,19 @@ posixmodule_exec(PyObject *m) PyObject *unicode; if (trace->probe && !trace->probe()) continue; unicode = PyUnicode_DecodeASCII(trace->label, strlen(trace->label), NULL); - if (!unicode) + if (!unicode) return -1; - if (PyList_Append(list, unicode)) + if (PyList_Append(list, unicode)) return -1; - Py_DECREF(unicode); - } - - PyModule_AddObject(m, "_have_functions", list); + Py_DECREF(unicode); + } + PyModule_AddObject(m, "_have_functions", list); + return 0; } - - + + static PyModuleDef_Slot posixmodile_slots[] = { {Py_mod_exec, posixmodule_exec}, {0, NULL} @@ -15628,8 +15628,8 @@ PyMODINIT_FUNC INITFUNC(void) { return PyModuleDef_Init(&posixmodule); -} - -#ifdef __cplusplus -} -#endif +} + +#ifdef __cplusplus +} +#endif diff --git a/contrib/tools/python3/src/Modules/posixmodule.h b/contrib/tools/python3/src/Modules/posixmodule.h index 5452ffbf17a..6898d8c61c9 100644 --- a/contrib/tools/python3/src/Modules/posixmodule.h +++ b/contrib/tools/python3/src/Modules/posixmodule.h @@ -1,32 +1,32 @@ -/* Declarations shared between the different POSIX-related modules */ - -#ifndef Py_POSIXMODULE_H -#define Py_POSIXMODULE_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifndef Py_LIMITED_API -#ifndef MS_WINDOWS -PyAPI_FUNC(PyObject *) _PyLong_FromUid(uid_t); -PyAPI_FUNC(PyObject *) _PyLong_FromGid(gid_t); +/* Declarations shared between the different POSIX-related modules */ + +#ifndef Py_POSIXMODULE_H +#define Py_POSIXMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifndef Py_LIMITED_API +#ifndef MS_WINDOWS +PyAPI_FUNC(PyObject *) _PyLong_FromUid(uid_t); +PyAPI_FUNC(PyObject *) _PyLong_FromGid(gid_t); PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, uid_t *); PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, gid_t *); -#endif /* MS_WINDOWS */ +#endif /* MS_WINDOWS */ #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) # define HAVE_SIGSET_T -#endif - +#endif + PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *); #endif /* Py_LIMITED_API */ -#ifdef __cplusplus -} -#endif -#endif /* !Py_POSIXMODULE_H */ +#ifdef __cplusplus +} +#endif +#endif /* !Py_POSIXMODULE_H */ diff --git a/contrib/tools/python3/src/Modules/pwdmodule.c b/contrib/tools/python3/src/Modules/pwdmodule.c index 901a3ed9a2e..cf5a1c09941 100644 --- a/contrib/tools/python3/src/Modules/pwdmodule.c +++ b/contrib/tools/python3/src/Modules/pwdmodule.c @@ -1,56 +1,56 @@ - -/* UNIX password file access module */ - -#include "Python.h" -#include "posixmodule.h" - -#include - -#include "clinic/pwdmodule.c.h" -/*[clinic input] -module pwd -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=60f628ef356b97b6]*/ - -static PyStructSequence_Field struct_pwd_type_fields[] = { - {"pw_name", "user name"}, - {"pw_passwd", "password"}, - {"pw_uid", "user id"}, - {"pw_gid", "group id"}, - {"pw_gecos", "real name"}, - {"pw_dir", "home directory"}, - {"pw_shell", "shell program"}, - {0} -}; - -PyDoc_STRVAR(struct_passwd__doc__, -"pwd.struct_passwd: Results from getpw*() routines.\n\n\ -This object may be accessed either as a tuple of\n\ - (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)\n\ -or via the object attributes as named in the above tuple."); - -static PyStructSequence_Desc struct_pwd_type_desc = { - "pwd.struct_passwd", - struct_passwd__doc__, - struct_pwd_type_fields, - 7, -}; - -PyDoc_STRVAR(pwd__doc__, -"This module provides access to the Unix password database.\n\ -It is available on all Unix versions.\n\ -\n\ -Password database entries are reported as 7-tuples containing the following\n\ -items from the password database (see `'), in order:\n\ -pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell.\n\ -The uid and gid items are integers, all others are strings. An\n\ -exception is raised if the entry asked for cannot be found."); - - + +/* UNIX password file access module */ + +#include "Python.h" +#include "posixmodule.h" + +#include + +#include "clinic/pwdmodule.c.h" +/*[clinic input] +module pwd +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=60f628ef356b97b6]*/ + +static PyStructSequence_Field struct_pwd_type_fields[] = { + {"pw_name", "user name"}, + {"pw_passwd", "password"}, + {"pw_uid", "user id"}, + {"pw_gid", "group id"}, + {"pw_gecos", "real name"}, + {"pw_dir", "home directory"}, + {"pw_shell", "shell program"}, + {0} +}; + +PyDoc_STRVAR(struct_passwd__doc__, +"pwd.struct_passwd: Results from getpw*() routines.\n\n\ +This object may be accessed either as a tuple of\n\ + (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)\n\ +or via the object attributes as named in the above tuple."); + +static PyStructSequence_Desc struct_pwd_type_desc = { + "pwd.struct_passwd", + struct_passwd__doc__, + struct_pwd_type_fields, + 7, +}; + +PyDoc_STRVAR(pwd__doc__, +"This module provides access to the Unix password database.\n\ +It is available on all Unix versions.\n\ +\n\ +Password database entries are reported as 7-tuples containing the following\n\ +items from the password database (see `'), in order:\n\ +pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell.\n\ +The uid and gid items are integers, all others are strings. An\n\ +exception is raised if the entry asked for cannot be found."); + + typedef struct { PyTypeObject *StructPwdType; } pwdmodulestate; - + static inline pwdmodulestate* get_pwd_state(PyObject *module) { @@ -65,84 +65,84 @@ static struct PyModuleDef pwdmodule; #define DEFAULT_BUFFER_SIZE 1024 -static void -sets(PyObject *v, int i, const char* val) -{ - if (val) { - PyObject *o = PyUnicode_DecodeFSDefault(val); - PyStructSequence_SET_ITEM(v, i, o); - } - else { - PyStructSequence_SET_ITEM(v, i, Py_None); - Py_INCREF(Py_None); - } -} - -static PyObject * -mkpwent(struct passwd *p) -{ - int setIndex = 0; +static void +sets(PyObject *v, int i, const char* val) +{ + if (val) { + PyObject *o = PyUnicode_DecodeFSDefault(val); + PyStructSequence_SET_ITEM(v, i, o); + } + else { + PyStructSequence_SET_ITEM(v, i, Py_None); + Py_INCREF(Py_None); + } +} + +static PyObject * +mkpwent(struct passwd *p) +{ + int setIndex = 0; PyObject *v = PyStructSequence_New(modulestate_global->StructPwdType); - if (v == NULL) - return NULL; - -#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) -#define SETS(i,val) sets(v, i, val) - - SETS(setIndex++, p->pw_name); -#if defined(HAVE_STRUCT_PASSWD_PW_PASSWD) && !defined(__ANDROID__) - SETS(setIndex++, p->pw_passwd); -#else - SETS(setIndex++, ""); -#endif - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); -#if defined(HAVE_STRUCT_PASSWD_PW_GECOS) - SETS(setIndex++, p->pw_gecos); -#else - SETS(setIndex++, ""); -#endif - SETS(setIndex++, p->pw_dir); - SETS(setIndex++, p->pw_shell); - -#undef SETS -#undef SETI - - if (PyErr_Occurred()) { - Py_XDECREF(v); - return NULL; - } - - return v; -} - -/*[clinic input] -pwd.getpwuid - - uidobj: object - / - -Return the password database entry for the given numeric user ID. - -See `help(pwd)` for more on password database entries. -[clinic start generated code]*/ - -static PyObject * -pwd_getpwuid(PyObject *module, PyObject *uidobj) -/*[clinic end generated code: output=c4ee1d4d429b86c4 input=ae64d507a1c6d3e8]*/ -{ + if (v == NULL) + return NULL; + +#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) +#define SETS(i,val) sets(v, i, val) + + SETS(setIndex++, p->pw_name); +#if defined(HAVE_STRUCT_PASSWD_PW_PASSWD) && !defined(__ANDROID__) + SETS(setIndex++, p->pw_passwd); +#else + SETS(setIndex++, ""); +#endif + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); +#if defined(HAVE_STRUCT_PASSWD_PW_GECOS) + SETS(setIndex++, p->pw_gecos); +#else + SETS(setIndex++, ""); +#endif + SETS(setIndex++, p->pw_dir); + SETS(setIndex++, p->pw_shell); + +#undef SETS +#undef SETI + + if (PyErr_Occurred()) { + Py_XDECREF(v); + return NULL; + } + + return v; +} + +/*[clinic input] +pwd.getpwuid + + uidobj: object + / + +Return the password database entry for the given numeric user ID. + +See `help(pwd)` for more on password database entries. +[clinic start generated code]*/ + +static PyObject * +pwd_getpwuid(PyObject *module, PyObject *uidobj) +/*[clinic end generated code: output=c4ee1d4d429b86c4 input=ae64d507a1c6d3e8]*/ +{ PyObject *retval = NULL; - uid_t uid; + uid_t uid; int nomem = 0; - struct passwd *p; + struct passwd *p; char *buf = NULL, *buf2 = NULL; - - if (!_Py_Uid_Converter(uidobj, &uid)) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_Format(PyExc_KeyError, - "getpwuid(): uid not found"); - return NULL; - } + + if (!_Py_Uid_Converter(uidobj, &uid)) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_Format(PyExc_KeyError, + "getpwuid(): uid not found"); + return NULL; + } #ifdef HAVE_GETPWUID_R int status; Py_ssize_t bufsize; @@ -186,46 +186,46 @@ pwd_getpwuid(PyObject *module, PyObject *uidobj) if (nomem == 1) { return PyErr_NoMemory(); } - PyObject *uid_obj = _PyLong_FromUid(uid); - if (uid_obj == NULL) - return NULL; - PyErr_Format(PyExc_KeyError, - "getpwuid(): uid not found: %S", uid_obj); - Py_DECREF(uid_obj); - return NULL; - } + PyObject *uid_obj = _PyLong_FromUid(uid); + if (uid_obj == NULL) + return NULL; + PyErr_Format(PyExc_KeyError, + "getpwuid(): uid not found: %S", uid_obj); + Py_DECREF(uid_obj); + return NULL; + } retval = mkpwent(p); #ifdef HAVE_GETPWUID_R PyMem_RawFree(buf); #endif return retval; -} - -/*[clinic input] -pwd.getpwnam - +} + +/*[clinic input] +pwd.getpwnam + name: unicode - / - -Return the password database entry for the given user name. - -See `help(pwd)` for more on password database entries. -[clinic start generated code]*/ - -static PyObject * + / + +Return the password database entry for the given user name. + +See `help(pwd)` for more on password database entries. +[clinic start generated code]*/ + +static PyObject * pwd_getpwnam_impl(PyObject *module, PyObject *name) /*[clinic end generated code: output=359ce1ddeb7a824f input=a6aeb5e3447fb9e0]*/ -{ +{ char *buf = NULL, *buf2 = NULL, *name_chars; int nomem = 0; - struct passwd *p; - PyObject *bytes, *retval = NULL; - + struct passwd *p; + PyObject *bytes, *retval = NULL; + if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL) - return NULL; - /* check for embedded null bytes */ + return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1) - goto out; + goto out; #ifdef HAVE_GETPWNAM_R int status; Py_ssize_t bufsize; @@ -272,57 +272,57 @@ pwd_getpwnam_impl(PyObject *module, PyObject *name) PyErr_Format(PyExc_KeyError, "getpwnam(): name not found: %R", name); } - goto out; - } - retval = mkpwent(p); -out: + goto out; + } + retval = mkpwent(p); +out: PyMem_RawFree(buf); - Py_DECREF(bytes); - return retval; -} - -#ifdef HAVE_GETPWENT -/*[clinic input] -pwd.getpwall - -Return a list of all available password database entries, in arbitrary order. - -See help(pwd) for more on password database entries. -[clinic start generated code]*/ - -static PyObject * -pwd_getpwall_impl(PyObject *module) -/*[clinic end generated code: output=4853d2f5a0afac8a input=d7ecebfd90219b85]*/ -{ - PyObject *d; - struct passwd *p; - if ((d = PyList_New(0)) == NULL) - return NULL; - setpwent(); - while ((p = getpwent()) != NULL) { - PyObject *v = mkpwent(p); - if (v == NULL || PyList_Append(d, v) != 0) { - Py_XDECREF(v); - Py_DECREF(d); - endpwent(); - return NULL; - } - Py_DECREF(v); - } - endpwent(); - return d; -} -#endif - -static PyMethodDef pwd_methods[] = { - PWD_GETPWUID_METHODDEF - PWD_GETPWNAM_METHODDEF -#ifdef HAVE_GETPWENT - PWD_GETPWALL_METHODDEF -#endif - {NULL, NULL} /* sentinel */ -}; - + Py_DECREF(bytes); + return retval; +} + +#ifdef HAVE_GETPWENT +/*[clinic input] +pwd.getpwall + +Return a list of all available password database entries, in arbitrary order. + +See help(pwd) for more on password database entries. +[clinic start generated code]*/ + +static PyObject * +pwd_getpwall_impl(PyObject *module) +/*[clinic end generated code: output=4853d2f5a0afac8a input=d7ecebfd90219b85]*/ +{ + PyObject *d; + struct passwd *p; + if ((d = PyList_New(0)) == NULL) + return NULL; + setpwent(); + while ((p = getpwent()) != NULL) { + PyObject *v = mkpwent(p); + if (v == NULL || PyList_Append(d, v) != 0) { + Py_XDECREF(v); + Py_DECREF(d); + endpwent(); + return NULL; + } + Py_DECREF(v); + } + endpwent(); + return d; +} +#endif + +static PyMethodDef pwd_methods[] = { + PWD_GETPWUID_METHODDEF + PWD_GETPWNAM_METHODDEF +#ifdef HAVE_GETPWENT + PWD_GETPWALL_METHODDEF +#endif + {NULL, NULL} /* sentinel */ +}; + static int pwdmodule_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(get_pwd_state(m)->StructPwdType); return 0; @@ -335,36 +335,36 @@ static void pwdmodule_free(void *m) { pwdmodule_clear((PyObject *)m); } -static struct PyModuleDef pwdmodule = { - PyModuleDef_HEAD_INIT, - "pwd", - pwd__doc__, +static struct PyModuleDef pwdmodule = { + PyModuleDef_HEAD_INIT, + "pwd", + pwd__doc__, sizeof(pwdmodulestate), - pwd_methods, - NULL, + pwd_methods, + NULL, pwdmodule_traverse, pwdmodule_clear, pwdmodule_free, -}; - - -PyMODINIT_FUNC -PyInit_pwd(void) -{ - PyObject *m; +}; + + +PyMODINIT_FUNC +PyInit_pwd(void) +{ + PyObject *m; if ((m = PyState_FindModule(&pwdmodule)) != NULL) { Py_INCREF(m); return m; } if ((m = PyModule_Create(&pwdmodule)) == NULL) - return NULL; - + return NULL; + pwdmodulestate *state = PyModule_GetState(m); state->StructPwdType = PyStructSequence_NewType(&struct_pwd_type_desc); if (state->StructPwdType == NULL) { return NULL; - } + } Py_INCREF(state->StructPwdType); PyModule_AddObject(m, "struct_passwd", (PyObject *) state->StructPwdType); - return m; -} + return m; +} diff --git a/contrib/tools/python3/src/Modules/pyexpat.c b/contrib/tools/python3/src/Modules/pyexpat.c index 12ae66d945b..8205adafffa 100644 --- a/contrib/tools/python3/src/Modules/pyexpat.c +++ b/contrib/tools/python3/src/Modules/pyexpat.c @@ -1,1207 +1,1207 @@ -#include "Python.h" -#include - +#include "Python.h" +#include + #include "structmember.h" // PyMemberDef -#include "frameobject.h" -#include "expat.h" - -#include "pyexpat.h" - -/* Do not emit Clinic output to a file as that wreaks havoc with conditionally - included methods. */ -/*[clinic input] -module pyexpat -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b168d503a4490c15]*/ - -#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION) - -static XML_Memory_Handling_Suite ExpatMemoryHandler = { - PyObject_Malloc, PyObject_Realloc, PyObject_Free}; - -enum HandlerTypes { - StartElement, - EndElement, - ProcessingInstruction, - CharacterData, - UnparsedEntityDecl, - NotationDecl, - StartNamespaceDecl, - EndNamespaceDecl, - Comment, - StartCdataSection, - EndCdataSection, - Default, - DefaultHandlerExpand, - NotStandalone, - ExternalEntityRef, - StartDoctypeDecl, - EndDoctypeDecl, - EntityDecl, - XmlDecl, - ElementDecl, - AttlistDecl, -#if XML_COMBINED_VERSION >= 19504 - SkippedEntity, -#endif - _DummyDecl -}; - -static PyObject *ErrorObject; - -/* ----------------------------------------------------- */ - -/* Declarations for objects of type xmlparser */ - -typedef struct { - PyObject_HEAD - - XML_Parser itself; - int ordered_attributes; /* Return attributes as a list. */ - int specified_attributes; /* Report only specified attributes. */ - int in_callback; /* Is a callback active? */ - int ns_prefixes; /* Namespace-triplets mode? */ - XML_Char *buffer; /* Buffer used when accumulating characters */ - /* NULL if not enabled */ - int buffer_size; /* Size of buffer, in XML_Char units */ - int buffer_used; /* Buffer units in use */ - PyObject *intern; /* Dictionary to intern strings */ - PyObject **handlers; -} xmlparseobject; - -#include "clinic/pyexpat.c.h" - -#define CHARACTER_DATA_BUFFER_SIZE 8192 - -static PyTypeObject Xmlparsetype; - -typedef void (*xmlhandlersetter)(XML_Parser self, void *meth); -typedef void* xmlhandler; - -struct HandlerInfo { - const char *name; - xmlhandlersetter setter; - xmlhandler handler; +#include "frameobject.h" +#include "expat.h" + +#include "pyexpat.h" + +/* Do not emit Clinic output to a file as that wreaks havoc with conditionally + included methods. */ +/*[clinic input] +module pyexpat +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b168d503a4490c15]*/ + +#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION) + +static XML_Memory_Handling_Suite ExpatMemoryHandler = { + PyObject_Malloc, PyObject_Realloc, PyObject_Free}; + +enum HandlerTypes { + StartElement, + EndElement, + ProcessingInstruction, + CharacterData, + UnparsedEntityDecl, + NotationDecl, + StartNamespaceDecl, + EndNamespaceDecl, + Comment, + StartCdataSection, + EndCdataSection, + Default, + DefaultHandlerExpand, + NotStandalone, + ExternalEntityRef, + StartDoctypeDecl, + EndDoctypeDecl, + EntityDecl, + XmlDecl, + ElementDecl, + AttlistDecl, +#if XML_COMBINED_VERSION >= 19504 + SkippedEntity, +#endif + _DummyDecl +}; + +static PyObject *ErrorObject; + +/* ----------------------------------------------------- */ + +/* Declarations for objects of type xmlparser */ + +typedef struct { + PyObject_HEAD + + XML_Parser itself; + int ordered_attributes; /* Return attributes as a list. */ + int specified_attributes; /* Report only specified attributes. */ + int in_callback; /* Is a callback active? */ + int ns_prefixes; /* Namespace-triplets mode? */ + XML_Char *buffer; /* Buffer used when accumulating characters */ + /* NULL if not enabled */ + int buffer_size; /* Size of buffer, in XML_Char units */ + int buffer_used; /* Buffer units in use */ + PyObject *intern; /* Dictionary to intern strings */ + PyObject **handlers; +} xmlparseobject; + +#include "clinic/pyexpat.c.h" + +#define CHARACTER_DATA_BUFFER_SIZE 8192 + +static PyTypeObject Xmlparsetype; + +typedef void (*xmlhandlersetter)(XML_Parser self, void *meth); +typedef void* xmlhandler; + +struct HandlerInfo { + const char *name; + xmlhandlersetter setter; + xmlhandler handler; PyGetSetDef getset; -}; - -static struct HandlerInfo handler_info[64]; - -/* Set an integer attribute on the error object; return true on success, - * false on an exception. - */ -static int -set_error_attr(PyObject *err, const char *name, int value) -{ - PyObject *v = PyLong_FromLong(value); - - if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) { - Py_XDECREF(v); - return 0; - } - Py_DECREF(v); - return 1; -} - -/* Build and set an Expat exception, including positioning - * information. Always returns NULL. - */ -static PyObject * -set_error(xmlparseobject *self, enum XML_Error code) -{ - PyObject *err; - PyObject *buffer; - XML_Parser parser = self->itself; - int lineno = XML_GetErrorLineNumber(parser); - int column = XML_GetErrorColumnNumber(parser); - - buffer = PyUnicode_FromFormat("%s: line %i, column %i", - XML_ErrorString(code), lineno, column); - if (buffer == NULL) - return NULL; +}; + +static struct HandlerInfo handler_info[64]; + +/* Set an integer attribute on the error object; return true on success, + * false on an exception. + */ +static int +set_error_attr(PyObject *err, const char *name, int value) +{ + PyObject *v = PyLong_FromLong(value); + + if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) { + Py_XDECREF(v); + return 0; + } + Py_DECREF(v); + return 1; +} + +/* Build and set an Expat exception, including positioning + * information. Always returns NULL. + */ +static PyObject * +set_error(xmlparseobject *self, enum XML_Error code) +{ + PyObject *err; + PyObject *buffer; + XML_Parser parser = self->itself; + int lineno = XML_GetErrorLineNumber(parser); + int column = XML_GetErrorColumnNumber(parser); + + buffer = PyUnicode_FromFormat("%s: line %i, column %i", + XML_ErrorString(code), lineno, column); + if (buffer == NULL) + return NULL; err = PyObject_CallOneArg(ErrorObject, buffer); - Py_DECREF(buffer); - if ( err != NULL - && set_error_attr(err, "code", code) - && set_error_attr(err, "offset", column) - && set_error_attr(err, "lineno", lineno)) { - PyErr_SetObject(ErrorObject, err); - } - Py_XDECREF(err); - return NULL; -} - -static int -have_handler(xmlparseobject *self, int type) -{ - PyObject *handler = self->handlers[type]; - return handler != NULL; -} - -/* Convert a string of XML_Chars into a Unicode string. - Returns None if str is a null pointer. */ - -static PyObject * -conv_string_to_unicode(const XML_Char *str) -{ - /* XXX currently this code assumes that XML_Char is 8-bit, - and hence in UTF-8. */ - /* UTF-8 from Expat, Unicode desired */ - if (str == NULL) { - Py_RETURN_NONE; - } - return PyUnicode_DecodeUTF8(str, strlen(str), "strict"); -} - -static PyObject * -conv_string_len_to_unicode(const XML_Char *str, int len) -{ - /* XXX currently this code assumes that XML_Char is 8-bit, - and hence in UTF-8. */ - /* UTF-8 from Expat, Unicode desired */ - if (str == NULL) { - Py_RETURN_NONE; - } - return PyUnicode_DecodeUTF8((const char *)str, len, "strict"); -} - -/* Callback routines */ - -static void clear_handlers(xmlparseobject *self, int initial); - -/* This handler is used when an error has been detected, in the hope - that actual parsing can be terminated early. This will only help - if an external entity reference is encountered. */ -static int -error_external_entity_ref_handler(XML_Parser parser, - const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) -{ - return 0; -} - -/* Dummy character data handler used when an error (exception) has - been detected, and the actual parsing can be terminated early. - This is needed since character data handler can't be safely removed - from within the character data handler, but can be replaced. It is - used only from the character data handler trampoline, and must be - used right after `flag_error()` is called. */ -static void -noop_character_data_handler(void *userData, const XML_Char *data, int len) -{ - /* Do nothing. */ -} - -static void -flag_error(xmlparseobject *self) -{ - clear_handlers(self, 0); - XML_SetExternalEntityRefHandler(self->itself, - error_external_entity_ref_handler); -} - -static PyObject* -call_with_frame(const char *funcname, int lineno, PyObject* func, PyObject* args, - xmlparseobject *self) -{ - PyObject *res; - + Py_DECREF(buffer); + if ( err != NULL + && set_error_attr(err, "code", code) + && set_error_attr(err, "offset", column) + && set_error_attr(err, "lineno", lineno)) { + PyErr_SetObject(ErrorObject, err); + } + Py_XDECREF(err); + return NULL; +} + +static int +have_handler(xmlparseobject *self, int type) +{ + PyObject *handler = self->handlers[type]; + return handler != NULL; +} + +/* Convert a string of XML_Chars into a Unicode string. + Returns None if str is a null pointer. */ + +static PyObject * +conv_string_to_unicode(const XML_Char *str) +{ + /* XXX currently this code assumes that XML_Char is 8-bit, + and hence in UTF-8. */ + /* UTF-8 from Expat, Unicode desired */ + if (str == NULL) { + Py_RETURN_NONE; + } + return PyUnicode_DecodeUTF8(str, strlen(str), "strict"); +} + +static PyObject * +conv_string_len_to_unicode(const XML_Char *str, int len) +{ + /* XXX currently this code assumes that XML_Char is 8-bit, + and hence in UTF-8. */ + /* UTF-8 from Expat, Unicode desired */ + if (str == NULL) { + Py_RETURN_NONE; + } + return PyUnicode_DecodeUTF8((const char *)str, len, "strict"); +} + +/* Callback routines */ + +static void clear_handlers(xmlparseobject *self, int initial); + +/* This handler is used when an error has been detected, in the hope + that actual parsing can be terminated early. This will only help + if an external entity reference is encountered. */ +static int +error_external_entity_ref_handler(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) +{ + return 0; +} + +/* Dummy character data handler used when an error (exception) has + been detected, and the actual parsing can be terminated early. + This is needed since character data handler can't be safely removed + from within the character data handler, but can be replaced. It is + used only from the character data handler trampoline, and must be + used right after `flag_error()` is called. */ +static void +noop_character_data_handler(void *userData, const XML_Char *data, int len) +{ + /* Do nothing. */ +} + +static void +flag_error(xmlparseobject *self) +{ + clear_handlers(self, 0); + XML_SetExternalEntityRefHandler(self->itself, + error_external_entity_ref_handler); +} + +static PyObject* +call_with_frame(const char *funcname, int lineno, PyObject* func, PyObject* args, + xmlparseobject *self) +{ + PyObject *res; + res = PyObject_Call(func, args, NULL); - if (res == NULL) { - _PyTraceback_Add(funcname, __FILE__, lineno); - XML_StopParser(self->itself, XML_FALSE); - } - return res; -} - -static PyObject* -string_intern(xmlparseobject *self, const char* str) -{ - PyObject *result = conv_string_to_unicode(str); - PyObject *value; - /* result can be NULL if the unicode conversion failed. */ - if (!result) - return result; - if (!self->intern) - return result; + if (res == NULL) { + _PyTraceback_Add(funcname, __FILE__, lineno); + XML_StopParser(self->itself, XML_FALSE); + } + return res; +} + +static PyObject* +string_intern(xmlparseobject *self, const char* str) +{ + PyObject *result = conv_string_to_unicode(str); + PyObject *value; + /* result can be NULL if the unicode conversion failed. */ + if (!result) + return result; + if (!self->intern) + return result; value = PyDict_GetItemWithError(self->intern, result); - if (!value) { + if (!value) { if (!PyErr_Occurred() && PyDict_SetItem(self->intern, result, result) == 0) { - return result; - } - else { - Py_DECREF(result); - return NULL; - } - } - Py_INCREF(value); - Py_DECREF(result); - return value; -} - -/* Return 0 on success, -1 on exception. - * flag_error() will be called before return if needed. - */ -static int -call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len) -{ - PyObject *args; - PyObject *temp; - - if (!have_handler(self, CharacterData)) - return -1; - - args = PyTuple_New(1); - if (args == NULL) - return -1; - temp = (conv_string_len_to_unicode(buffer, len)); - if (temp == NULL) { - Py_DECREF(args); - flag_error(self); - XML_SetCharacterDataHandler(self->itself, - noop_character_data_handler); - return -1; - } - PyTuple_SET_ITEM(args, 0, temp); - /* temp is now a borrowed reference; consider it unused. */ - self->in_callback = 1; - temp = call_with_frame("CharacterData", __LINE__, - self->handlers[CharacterData], args, self); - /* temp is an owned reference again, or NULL */ - self->in_callback = 0; - Py_DECREF(args); - if (temp == NULL) { - flag_error(self); - XML_SetCharacterDataHandler(self->itself, - noop_character_data_handler); - return -1; - } - Py_DECREF(temp); - return 0; -} - -static int -flush_character_buffer(xmlparseobject *self) -{ - int rc; - if (self->buffer == NULL || self->buffer_used == 0) - return 0; - rc = call_character_handler(self, self->buffer, self->buffer_used); - self->buffer_used = 0; - return rc; -} - -static void -my_CharacterDataHandler(void *userData, const XML_Char *data, int len) -{ - xmlparseobject *self = (xmlparseobject *) userData; - - if (PyErr_Occurred()) - return; - - if (self->buffer == NULL) - call_character_handler(self, data, len); - else { - if ((self->buffer_used + len) > self->buffer_size) { - if (flush_character_buffer(self) < 0) - return; - /* handler might have changed; drop the rest on the floor - * if there isn't a handler anymore - */ - if (!have_handler(self, CharacterData)) - return; + return result; } - if (len > self->buffer_size) { - call_character_handler(self, data, len); - self->buffer_used = 0; - } - else { - memcpy(self->buffer + self->buffer_used, - data, len * sizeof(XML_Char)); - self->buffer_used += len; - } - } -} - -static void -my_StartElementHandler(void *userData, - const XML_Char *name, const XML_Char *atts[]) -{ - xmlparseobject *self = (xmlparseobject *)userData; - - if (have_handler(self, StartElement)) { - PyObject *container, *rv, *args; - int i, max; - - if (PyErr_Occurred()) - return; - - if (flush_character_buffer(self) < 0) - return; - /* Set max to the number of slots filled in atts[]; max/2 is - * the number of attributes we need to process. - */ - if (self->specified_attributes) { - max = XML_GetSpecifiedAttributeCount(self->itself); - } - else { - max = 0; - while (atts[max] != NULL) - max += 2; - } - /* Build the container. */ - if (self->ordered_attributes) - container = PyList_New(max); - else - container = PyDict_New(); - if (container == NULL) { - flag_error(self); - return; - } - for (i = 0; i < max; i += 2) { - PyObject *n = string_intern(self, (XML_Char *) atts[i]); - PyObject *v; - if (n == NULL) { - flag_error(self); - Py_DECREF(container); - return; - } - v = conv_string_to_unicode((XML_Char *) atts[i+1]); - if (v == NULL) { - flag_error(self); - Py_DECREF(container); - Py_DECREF(n); - return; - } - if (self->ordered_attributes) { - PyList_SET_ITEM(container, i, n); - PyList_SET_ITEM(container, i+1, v); - } - else if (PyDict_SetItem(container, n, v)) { - flag_error(self); - Py_DECREF(n); - Py_DECREF(v); - Py_DECREF(container); - return; - } - else { - Py_DECREF(n); - Py_DECREF(v); - } - } - args = string_intern(self, name); - if (args == NULL) { - Py_DECREF(container); - return; - } - args = Py_BuildValue("(NN)", args, container); - if (args == NULL) { - return; - } - /* Container is now a borrowed reference; ignore it. */ - self->in_callback = 1; - rv = call_with_frame("StartElement", __LINE__, - self->handlers[StartElement], args, self); - self->in_callback = 0; - Py_DECREF(args); - if (rv == NULL) { - flag_error(self); - return; - } - Py_DECREF(rv); - } -} - -#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \ - RETURN, GETUSERDATA) \ -static RC \ -my_##NAME##Handler PARAMS {\ - xmlparseobject *self = GETUSERDATA ; \ - PyObject *args = NULL; \ - PyObject *rv = NULL; \ - INIT \ -\ - if (have_handler(self, NAME)) { \ - if (PyErr_Occurred()) \ - return RETURN; \ - if (flush_character_buffer(self) < 0) \ - return RETURN; \ - args = Py_BuildValue PARAM_FORMAT ;\ - if (!args) { flag_error(self); return RETURN;} \ - self->in_callback = 1; \ - rv = call_with_frame(#NAME,__LINE__, \ - self->handlers[NAME], args, self); \ - self->in_callback = 0; \ - Py_DECREF(args); \ - if (rv == NULL) { \ - flag_error(self); \ - return RETURN; \ - } \ - CONVERSION \ - Py_DECREF(rv); \ - } \ - return RETURN; \ -} - -#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \ - RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\ - (xmlparseobject *)userData) - -#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\ - RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \ - rc = PyLong_AsLong(rv);, rc, \ - (xmlparseobject *)userData) - -VOID_HANDLER(EndElement, - (void *userData, const XML_Char *name), - ("(N)", string_intern(self, name))) - -VOID_HANDLER(ProcessingInstruction, - (void *userData, - const XML_Char *target, - const XML_Char *data), - ("(NO&)", string_intern(self, target), conv_string_to_unicode ,data)) - -VOID_HANDLER(UnparsedEntityDecl, - (void *userData, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName), - ("(NNNNN)", - string_intern(self, entityName), string_intern(self, base), - string_intern(self, systemId), string_intern(self, publicId), - string_intern(self, notationName))) - -VOID_HANDLER(EntityDecl, - (void *userData, - const XML_Char *entityName, - int is_parameter_entity, - const XML_Char *value, - int value_length, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName), - ("NiNNNNN", - string_intern(self, entityName), is_parameter_entity, - (conv_string_len_to_unicode(value, value_length)), - string_intern(self, base), string_intern(self, systemId), - string_intern(self, publicId), - string_intern(self, notationName))) - -VOID_HANDLER(XmlDecl, - (void *userData, - const XML_Char *version, - const XML_Char *encoding, - int standalone), - ("(O&O&i)", - conv_string_to_unicode ,version, conv_string_to_unicode ,encoding, - standalone)) - -static PyObject * -conv_content_model(XML_Content * const model, - PyObject *(*conv_string)(const XML_Char *)) -{ - PyObject *result = NULL; - PyObject *children = PyTuple_New(model->numchildren); - int i; - - if (children != NULL) { - assert(model->numchildren < INT_MAX); - for (i = 0; i < (int)model->numchildren; ++i) { - PyObject *child = conv_content_model(&model->children[i], - conv_string); - if (child == NULL) { - Py_XDECREF(children); - return NULL; - } - PyTuple_SET_ITEM(children, i, child); - } - result = Py_BuildValue("(iiO&N)", - model->type, model->quant, - conv_string,model->name, children); - } - return result; -} - -static void -my_ElementDeclHandler(void *userData, - const XML_Char *name, - XML_Content *model) -{ - xmlparseobject *self = (xmlparseobject *)userData; - PyObject *args = NULL; - - if (have_handler(self, ElementDecl)) { - PyObject *rv = NULL; - PyObject *modelobj, *nameobj; - - if (PyErr_Occurred()) - return; - - if (flush_character_buffer(self) < 0) - goto finally; - modelobj = conv_content_model(model, (conv_string_to_unicode)); - if (modelobj == NULL) { - flag_error(self); - goto finally; - } - nameobj = string_intern(self, name); - if (nameobj == NULL) { - Py_DECREF(modelobj); - flag_error(self); - goto finally; - } - args = Py_BuildValue("NN", nameobj, modelobj); - if (args == NULL) { - flag_error(self); - goto finally; - } - self->in_callback = 1; - rv = call_with_frame("ElementDecl", __LINE__, - self->handlers[ElementDecl], args, self); - self->in_callback = 0; - if (rv == NULL) { - flag_error(self); - goto finally; - } - Py_DECREF(rv); - } - finally: - Py_XDECREF(args); - XML_FreeContentModel(self->itself, model); - return; -} - -VOID_HANDLER(AttlistDecl, - (void *userData, - const XML_Char *elname, - const XML_Char *attname, - const XML_Char *att_type, - const XML_Char *dflt, - int isrequired), - ("(NNO&O&i)", - string_intern(self, elname), string_intern(self, attname), - conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt, - isrequired)) - -#if XML_COMBINED_VERSION >= 19504 -VOID_HANDLER(SkippedEntity, - (void *userData, - const XML_Char *entityName, - int is_parameter_entity), - ("Ni", - string_intern(self, entityName), is_parameter_entity)) -#endif - -VOID_HANDLER(NotationDecl, - (void *userData, - const XML_Char *notationName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId), - ("(NNNN)", - string_intern(self, notationName), string_intern(self, base), - string_intern(self, systemId), string_intern(self, publicId))) - -VOID_HANDLER(StartNamespaceDecl, - (void *userData, - const XML_Char *prefix, - const XML_Char *uri), - ("(NN)", - string_intern(self, prefix), string_intern(self, uri))) - -VOID_HANDLER(EndNamespaceDecl, - (void *userData, - const XML_Char *prefix), - ("(N)", string_intern(self, prefix))) - -VOID_HANDLER(Comment, - (void *userData, const XML_Char *data), - ("(O&)", conv_string_to_unicode ,data)) - -VOID_HANDLER(StartCdataSection, - (void *userData), - ("()")) - -VOID_HANDLER(EndCdataSection, - (void *userData), - ("()")) - -VOID_HANDLER(Default, - (void *userData, const XML_Char *s, int len), - ("(N)", (conv_string_len_to_unicode(s,len)))) - -VOID_HANDLER(DefaultHandlerExpand, - (void *userData, const XML_Char *s, int len), - ("(N)", (conv_string_len_to_unicode(s,len)))) + else { + Py_DECREF(result); + return NULL; + } + } + Py_INCREF(value); + Py_DECREF(result); + return value; +} + +/* Return 0 on success, -1 on exception. + * flag_error() will be called before return if needed. + */ +static int +call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len) +{ + PyObject *args; + PyObject *temp; + + if (!have_handler(self, CharacterData)) + return -1; + + args = PyTuple_New(1); + if (args == NULL) + return -1; + temp = (conv_string_len_to_unicode(buffer, len)); + if (temp == NULL) { + Py_DECREF(args); + flag_error(self); + XML_SetCharacterDataHandler(self->itself, + noop_character_data_handler); + return -1; + } + PyTuple_SET_ITEM(args, 0, temp); + /* temp is now a borrowed reference; consider it unused. */ + self->in_callback = 1; + temp = call_with_frame("CharacterData", __LINE__, + self->handlers[CharacterData], args, self); + /* temp is an owned reference again, or NULL */ + self->in_callback = 0; + Py_DECREF(args); + if (temp == NULL) { + flag_error(self); + XML_SetCharacterDataHandler(self->itself, + noop_character_data_handler); + return -1; + } + Py_DECREF(temp); + return 0; +} + +static int +flush_character_buffer(xmlparseobject *self) +{ + int rc; + if (self->buffer == NULL || self->buffer_used == 0) + return 0; + rc = call_character_handler(self, self->buffer, self->buffer_used); + self->buffer_used = 0; + return rc; +} + +static void +my_CharacterDataHandler(void *userData, const XML_Char *data, int len) +{ + xmlparseobject *self = (xmlparseobject *) userData; + + if (PyErr_Occurred()) + return; + + if (self->buffer == NULL) + call_character_handler(self, data, len); + else { + if ((self->buffer_used + len) > self->buffer_size) { + if (flush_character_buffer(self) < 0) + return; + /* handler might have changed; drop the rest on the floor + * if there isn't a handler anymore + */ + if (!have_handler(self, CharacterData)) + return; + } + if (len > self->buffer_size) { + call_character_handler(self, data, len); + self->buffer_used = 0; + } + else { + memcpy(self->buffer + self->buffer_used, + data, len * sizeof(XML_Char)); + self->buffer_used += len; + } + } +} + +static void +my_StartElementHandler(void *userData, + const XML_Char *name, const XML_Char *atts[]) +{ + xmlparseobject *self = (xmlparseobject *)userData; + + if (have_handler(self, StartElement)) { + PyObject *container, *rv, *args; + int i, max; + + if (PyErr_Occurred()) + return; + + if (flush_character_buffer(self) < 0) + return; + /* Set max to the number of slots filled in atts[]; max/2 is + * the number of attributes we need to process. + */ + if (self->specified_attributes) { + max = XML_GetSpecifiedAttributeCount(self->itself); + } + else { + max = 0; + while (atts[max] != NULL) + max += 2; + } + /* Build the container. */ + if (self->ordered_attributes) + container = PyList_New(max); + else + container = PyDict_New(); + if (container == NULL) { + flag_error(self); + return; + } + for (i = 0; i < max; i += 2) { + PyObject *n = string_intern(self, (XML_Char *) atts[i]); + PyObject *v; + if (n == NULL) { + flag_error(self); + Py_DECREF(container); + return; + } + v = conv_string_to_unicode((XML_Char *) atts[i+1]); + if (v == NULL) { + flag_error(self); + Py_DECREF(container); + Py_DECREF(n); + return; + } + if (self->ordered_attributes) { + PyList_SET_ITEM(container, i, n); + PyList_SET_ITEM(container, i+1, v); + } + else if (PyDict_SetItem(container, n, v)) { + flag_error(self); + Py_DECREF(n); + Py_DECREF(v); + Py_DECREF(container); + return; + } + else { + Py_DECREF(n); + Py_DECREF(v); + } + } + args = string_intern(self, name); + if (args == NULL) { + Py_DECREF(container); + return; + } + args = Py_BuildValue("(NN)", args, container); + if (args == NULL) { + return; + } + /* Container is now a borrowed reference; ignore it. */ + self->in_callback = 1; + rv = call_with_frame("StartElement", __LINE__, + self->handlers[StartElement], args, self); + self->in_callback = 0; + Py_DECREF(args); + if (rv == NULL) { + flag_error(self); + return; + } + Py_DECREF(rv); + } +} + +#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \ + RETURN, GETUSERDATA) \ +static RC \ +my_##NAME##Handler PARAMS {\ + xmlparseobject *self = GETUSERDATA ; \ + PyObject *args = NULL; \ + PyObject *rv = NULL; \ + INIT \ +\ + if (have_handler(self, NAME)) { \ + if (PyErr_Occurred()) \ + return RETURN; \ + if (flush_character_buffer(self) < 0) \ + return RETURN; \ + args = Py_BuildValue PARAM_FORMAT ;\ + if (!args) { flag_error(self); return RETURN;} \ + self->in_callback = 1; \ + rv = call_with_frame(#NAME,__LINE__, \ + self->handlers[NAME], args, self); \ + self->in_callback = 0; \ + Py_DECREF(args); \ + if (rv == NULL) { \ + flag_error(self); \ + return RETURN; \ + } \ + CONVERSION \ + Py_DECREF(rv); \ + } \ + return RETURN; \ +} + +#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \ + RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\ + (xmlparseobject *)userData) + +#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\ + RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \ + rc = PyLong_AsLong(rv);, rc, \ + (xmlparseobject *)userData) + +VOID_HANDLER(EndElement, + (void *userData, const XML_Char *name), + ("(N)", string_intern(self, name))) + +VOID_HANDLER(ProcessingInstruction, + (void *userData, + const XML_Char *target, + const XML_Char *data), + ("(NO&)", string_intern(self, target), conv_string_to_unicode ,data)) + +VOID_HANDLER(UnparsedEntityDecl, + (void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName), + ("(NNNNN)", + string_intern(self, entityName), string_intern(self, base), + string_intern(self, systemId), string_intern(self, publicId), + string_intern(self, notationName))) + +VOID_HANDLER(EntityDecl, + (void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName), + ("NiNNNNN", + string_intern(self, entityName), is_parameter_entity, + (conv_string_len_to_unicode(value, value_length)), + string_intern(self, base), string_intern(self, systemId), + string_intern(self, publicId), + string_intern(self, notationName))) + +VOID_HANDLER(XmlDecl, + (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone), + ("(O&O&i)", + conv_string_to_unicode ,version, conv_string_to_unicode ,encoding, + standalone)) + +static PyObject * +conv_content_model(XML_Content * const model, + PyObject *(*conv_string)(const XML_Char *)) +{ + PyObject *result = NULL; + PyObject *children = PyTuple_New(model->numchildren); + int i; + + if (children != NULL) { + assert(model->numchildren < INT_MAX); + for (i = 0; i < (int)model->numchildren; ++i) { + PyObject *child = conv_content_model(&model->children[i], + conv_string); + if (child == NULL) { + Py_XDECREF(children); + return NULL; + } + PyTuple_SET_ITEM(children, i, child); + } + result = Py_BuildValue("(iiO&N)", + model->type, model->quant, + conv_string,model->name, children); + } + return result; +} + +static void +my_ElementDeclHandler(void *userData, + const XML_Char *name, + XML_Content *model) +{ + xmlparseobject *self = (xmlparseobject *)userData; + PyObject *args = NULL; + + if (have_handler(self, ElementDecl)) { + PyObject *rv = NULL; + PyObject *modelobj, *nameobj; + + if (PyErr_Occurred()) + return; + + if (flush_character_buffer(self) < 0) + goto finally; + modelobj = conv_content_model(model, (conv_string_to_unicode)); + if (modelobj == NULL) { + flag_error(self); + goto finally; + } + nameobj = string_intern(self, name); + if (nameobj == NULL) { + Py_DECREF(modelobj); + flag_error(self); + goto finally; + } + args = Py_BuildValue("NN", nameobj, modelobj); + if (args == NULL) { + flag_error(self); + goto finally; + } + self->in_callback = 1; + rv = call_with_frame("ElementDecl", __LINE__, + self->handlers[ElementDecl], args, self); + self->in_callback = 0; + if (rv == NULL) { + flag_error(self); + goto finally; + } + Py_DECREF(rv); + } + finally: + Py_XDECREF(args); + XML_FreeContentModel(self->itself, model); + return; +} + +VOID_HANDLER(AttlistDecl, + (void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired), + ("(NNO&O&i)", + string_intern(self, elname), string_intern(self, attname), + conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt, + isrequired)) + +#if XML_COMBINED_VERSION >= 19504 +VOID_HANDLER(SkippedEntity, + (void *userData, + const XML_Char *entityName, + int is_parameter_entity), + ("Ni", + string_intern(self, entityName), is_parameter_entity)) +#endif + +VOID_HANDLER(NotationDecl, + (void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId), + ("(NNNN)", + string_intern(self, notationName), string_intern(self, base), + string_intern(self, systemId), string_intern(self, publicId))) + +VOID_HANDLER(StartNamespaceDecl, + (void *userData, + const XML_Char *prefix, + const XML_Char *uri), + ("(NN)", + string_intern(self, prefix), string_intern(self, uri))) + +VOID_HANDLER(EndNamespaceDecl, + (void *userData, + const XML_Char *prefix), + ("(N)", string_intern(self, prefix))) + +VOID_HANDLER(Comment, + (void *userData, const XML_Char *data), + ("(O&)", conv_string_to_unicode ,data)) + +VOID_HANDLER(StartCdataSection, + (void *userData), + ("()")) + +VOID_HANDLER(EndCdataSection, + (void *userData), + ("()")) + +VOID_HANDLER(Default, + (void *userData, const XML_Char *s, int len), + ("(N)", (conv_string_len_to_unicode(s,len)))) + +VOID_HANDLER(DefaultHandlerExpand, + (void *userData, const XML_Char *s, int len), + ("(N)", (conv_string_len_to_unicode(s,len)))) #define my_DefaultHandlerExpand my_DefaultHandlerExpandHandler - -INT_HANDLER(NotStandalone, - (void *userData), - ("()")) - -RC_HANDLER(int, ExternalEntityRef, - (XML_Parser parser, - const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId), - int rc=0;, - ("(O&NNN)", - conv_string_to_unicode ,context, string_intern(self, base), - string_intern(self, systemId), string_intern(self, publicId)), - rc = PyLong_AsLong(rv);, rc, - XML_GetUserData(parser)) - -/* XXX UnknownEncodingHandler */ - -VOID_HANDLER(StartDoctypeDecl, - (void *userData, const XML_Char *doctypeName, - const XML_Char *sysid, const XML_Char *pubid, - int has_internal_subset), - ("(NNNi)", string_intern(self, doctypeName), - string_intern(self, sysid), string_intern(self, pubid), - has_internal_subset)) - -VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()")) - -/* ---------------------------------------------------------------- */ -/*[clinic input] -class pyexpat.xmlparser "xmlparseobject *" "&Xmlparsetype" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2393162385232e1c]*/ - - -static PyObject * -get_parse_result(xmlparseobject *self, int rv) -{ - if (PyErr_Occurred()) { - return NULL; - } - if (rv == 0) { - return set_error(self, XML_GetErrorCode(self->itself)); - } - if (flush_character_buffer(self) < 0) { - return NULL; - } - return PyLong_FromLong(rv); -} - -#define MAX_CHUNK_SIZE (1 << 20) - -/*[clinic input] -pyexpat.xmlparser.Parse - - data: object - isfinal: bool(accept={int}) = False - / - -Parse XML data. - -`isfinal' should be true at end of input. -[clinic start generated code]*/ - -static PyObject * -pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, - int isfinal) -/*[clinic end generated code: output=f4db843dd1f4ed4b input=eb616027bfa9847f]*/ -{ - const char *s; - Py_ssize_t slen; - Py_buffer view; - int rc; - - if (PyUnicode_Check(data)) { - view.buf = NULL; - s = PyUnicode_AsUTF8AndSize(data, &slen); - if (s == NULL) - return NULL; - /* Explicitly set UTF-8 encoding. Return code ignored. */ - (void)XML_SetEncoding(self->itself, "utf-8"); - } - else { - if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0) - return NULL; - s = view.buf; - slen = view.len; - } - - while (slen > MAX_CHUNK_SIZE) { - rc = XML_Parse(self->itself, s, MAX_CHUNK_SIZE, 0); - if (!rc) - goto done; - s += MAX_CHUNK_SIZE; - slen -= MAX_CHUNK_SIZE; - } - Py_BUILD_ASSERT(MAX_CHUNK_SIZE <= INT_MAX); - assert(slen <= INT_MAX); - rc = XML_Parse(self->itself, s, (int)slen, isfinal); - -done: - if (view.buf != NULL) - PyBuffer_Release(&view); - return get_parse_result(self, rc); -} - -/* File reading copied from cPickle */ - -#define BUF_SIZE 2048 - -static int -readinst(char *buf, int buf_size, PyObject *meth) -{ - PyObject *str; - Py_ssize_t len; - const char *ptr; - - str = PyObject_CallFunction(meth, "n", buf_size); - if (str == NULL) - goto error; - - if (PyBytes_Check(str)) - ptr = PyBytes_AS_STRING(str); - else if (PyByteArray_Check(str)) - ptr = PyByteArray_AS_STRING(str); - else { - PyErr_Format(PyExc_TypeError, - "read() did not return a bytes object (type=%.400s)", - Py_TYPE(str)->tp_name); - goto error; - } - len = Py_SIZE(str); - if (len > buf_size) { - PyErr_Format(PyExc_ValueError, - "read() returned too much data: " - "%i bytes requested, %zd returned", - buf_size, len); - goto error; - } - memcpy(buf, ptr, len); - Py_DECREF(str); - /* len <= buf_size <= INT_MAX */ - return (int)len; - -error: - Py_XDECREF(str); - return -1; -} - -/*[clinic input] -pyexpat.xmlparser.ParseFile - - file: object - / - -Parse XML data from file-like object. -[clinic start generated code]*/ - -static PyObject * -pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file) -/*[clinic end generated code: output=2adc6a13100cc42b input=fbb5a12b6038d735]*/ -{ - int rv = 1; - PyObject *readmethod = NULL; - _Py_IDENTIFIER(read); - + +INT_HANDLER(NotStandalone, + (void *userData), + ("()")) + +RC_HANDLER(int, ExternalEntityRef, + (XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId), + int rc=0;, + ("(O&NNN)", + conv_string_to_unicode ,context, string_intern(self, base), + string_intern(self, systemId), string_intern(self, publicId)), + rc = PyLong_AsLong(rv);, rc, + XML_GetUserData(parser)) + +/* XXX UnknownEncodingHandler */ + +VOID_HANDLER(StartDoctypeDecl, + (void *userData, const XML_Char *doctypeName, + const XML_Char *sysid, const XML_Char *pubid, + int has_internal_subset), + ("(NNNi)", string_intern(self, doctypeName), + string_intern(self, sysid), string_intern(self, pubid), + has_internal_subset)) + +VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()")) + +/* ---------------------------------------------------------------- */ +/*[clinic input] +class pyexpat.xmlparser "xmlparseobject *" "&Xmlparsetype" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2393162385232e1c]*/ + + +static PyObject * +get_parse_result(xmlparseobject *self, int rv) +{ + if (PyErr_Occurred()) { + return NULL; + } + if (rv == 0) { + return set_error(self, XML_GetErrorCode(self->itself)); + } + if (flush_character_buffer(self) < 0) { + return NULL; + } + return PyLong_FromLong(rv); +} + +#define MAX_CHUNK_SIZE (1 << 20) + +/*[clinic input] +pyexpat.xmlparser.Parse + + data: object + isfinal: bool(accept={int}) = False + / + +Parse XML data. + +`isfinal' should be true at end of input. +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, + int isfinal) +/*[clinic end generated code: output=f4db843dd1f4ed4b input=eb616027bfa9847f]*/ +{ + const char *s; + Py_ssize_t slen; + Py_buffer view; + int rc; + + if (PyUnicode_Check(data)) { + view.buf = NULL; + s = PyUnicode_AsUTF8AndSize(data, &slen); + if (s == NULL) + return NULL; + /* Explicitly set UTF-8 encoding. Return code ignored. */ + (void)XML_SetEncoding(self->itself, "utf-8"); + } + else { + if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0) + return NULL; + s = view.buf; + slen = view.len; + } + + while (slen > MAX_CHUNK_SIZE) { + rc = XML_Parse(self->itself, s, MAX_CHUNK_SIZE, 0); + if (!rc) + goto done; + s += MAX_CHUNK_SIZE; + slen -= MAX_CHUNK_SIZE; + } + Py_BUILD_ASSERT(MAX_CHUNK_SIZE <= INT_MAX); + assert(slen <= INT_MAX); + rc = XML_Parse(self->itself, s, (int)slen, isfinal); + +done: + if (view.buf != NULL) + PyBuffer_Release(&view); + return get_parse_result(self, rc); +} + +/* File reading copied from cPickle */ + +#define BUF_SIZE 2048 + +static int +readinst(char *buf, int buf_size, PyObject *meth) +{ + PyObject *str; + Py_ssize_t len; + const char *ptr; + + str = PyObject_CallFunction(meth, "n", buf_size); + if (str == NULL) + goto error; + + if (PyBytes_Check(str)) + ptr = PyBytes_AS_STRING(str); + else if (PyByteArray_Check(str)) + ptr = PyByteArray_AS_STRING(str); + else { + PyErr_Format(PyExc_TypeError, + "read() did not return a bytes object (type=%.400s)", + Py_TYPE(str)->tp_name); + goto error; + } + len = Py_SIZE(str); + if (len > buf_size) { + PyErr_Format(PyExc_ValueError, + "read() returned too much data: " + "%i bytes requested, %zd returned", + buf_size, len); + goto error; + } + memcpy(buf, ptr, len); + Py_DECREF(str); + /* len <= buf_size <= INT_MAX */ + return (int)len; + +error: + Py_XDECREF(str); + return -1; +} + +/*[clinic input] +pyexpat.xmlparser.ParseFile + + file: object + / + +Parse XML data from file-like object. +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file) +/*[clinic end generated code: output=2adc6a13100cc42b input=fbb5a12b6038d735]*/ +{ + int rv = 1; + PyObject *readmethod = NULL; + _Py_IDENTIFIER(read); + if (_PyObject_LookupAttrId(file, &PyId_read, &readmethod) < 0) { return NULL; } - if (readmethod == NULL) { - PyErr_SetString(PyExc_TypeError, - "argument must have 'read' attribute"); - return NULL; - } - for (;;) { - int bytes_read; - void *buf = XML_GetBuffer(self->itself, BUF_SIZE); - if (buf == NULL) { - Py_XDECREF(readmethod); - return get_parse_result(self, 0); - } - - bytes_read = readinst(buf, BUF_SIZE, readmethod); - if (bytes_read < 0) { - Py_DECREF(readmethod); - return NULL; - } - rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0); - if (PyErr_Occurred()) { - Py_XDECREF(readmethod); - return NULL; - } - - if (!rv || bytes_read == 0) - break; - } - Py_XDECREF(readmethod); - return get_parse_result(self, rv); -} - -/*[clinic input] -pyexpat.xmlparser.SetBase - - base: str - / - -Set the base URL for the parser. -[clinic start generated code]*/ - -static PyObject * -pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base) -/*[clinic end generated code: output=c212ddceb607b539 input=c684e5de895ee1a8]*/ -{ - if (!XML_SetBase(self->itself, base)) { - return PyErr_NoMemory(); - } - Py_RETURN_NONE; -} - -/*[clinic input] -pyexpat.xmlparser.GetBase - -Return base URL string for the parser. -[clinic start generated code]*/ - -static PyObject * -pyexpat_xmlparser_GetBase_impl(xmlparseobject *self) -/*[clinic end generated code: output=2886cb21f9a8739a input=918d71c38009620e]*/ -{ - return Py_BuildValue("z", XML_GetBase(self->itself)); -} - -/*[clinic input] -pyexpat.xmlparser.GetInputContext - -Return the untranslated text of the input that caused the current event. - -If the event was generated by a large amount of text (such as a start tag -for an element with many attributes), not all of the text may be available. -[clinic start generated code]*/ - -static PyObject * -pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self) -/*[clinic end generated code: output=a88026d683fc22cc input=034df8712db68379]*/ -{ - if (self->in_callback) { - int offset, size; - const char *buffer - = XML_GetInputContext(self->itself, &offset, &size); - - if (buffer != NULL) - return PyBytes_FromStringAndSize(buffer + offset, - size - offset); - else - Py_RETURN_NONE; - } - else - Py_RETURN_NONE; -} - -/*[clinic input] -pyexpat.xmlparser.ExternalEntityParserCreate - - context: str(accept={str, NoneType}) - encoding: str = NULL - / - -Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler. -[clinic start generated code]*/ - -static PyObject * -pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, - const char *context, - const char *encoding) -/*[clinic end generated code: output=535cda9d7a0fbcd6 input=b906714cc122c322]*/ -{ - xmlparseobject *new_parser; - int i; - - new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype); - if (new_parser == NULL) - return NULL; - new_parser->buffer_size = self->buffer_size; - new_parser->buffer_used = 0; - new_parser->buffer = NULL; - new_parser->ordered_attributes = self->ordered_attributes; - new_parser->specified_attributes = self->specified_attributes; - new_parser->in_callback = 0; - new_parser->ns_prefixes = self->ns_prefixes; - new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context, - encoding); - new_parser->handlers = 0; - new_parser->intern = self->intern; - Py_XINCREF(new_parser->intern); - - if (self->buffer != NULL) { - new_parser->buffer = PyMem_Malloc(new_parser->buffer_size); - if (new_parser->buffer == NULL) { - Py_DECREF(new_parser); - return PyErr_NoMemory(); - } - } - if (!new_parser->itself) { - Py_DECREF(new_parser); - return PyErr_NoMemory(); - } - - XML_SetUserData(new_parser->itself, (void *)new_parser); - - /* allocate and clear handlers first */ - for (i = 0; handler_info[i].name != NULL; i++) - /* do nothing */; - - new_parser->handlers = PyMem_New(PyObject *, i); - if (!new_parser->handlers) { - Py_DECREF(new_parser); - return PyErr_NoMemory(); - } - clear_handlers(new_parser, 1); - - /* then copy handlers from self */ - for (i = 0; handler_info[i].name != NULL; i++) { - PyObject *handler = self->handlers[i]; - if (handler != NULL) { - Py_INCREF(handler); - new_parser->handlers[i] = handler; - handler_info[i].setter(new_parser->itself, - handler_info[i].handler); - } - } + if (readmethod == NULL) { + PyErr_SetString(PyExc_TypeError, + "argument must have 'read' attribute"); + return NULL; + } + for (;;) { + int bytes_read; + void *buf = XML_GetBuffer(self->itself, BUF_SIZE); + if (buf == NULL) { + Py_XDECREF(readmethod); + return get_parse_result(self, 0); + } + + bytes_read = readinst(buf, BUF_SIZE, readmethod); + if (bytes_read < 0) { + Py_DECREF(readmethod); + return NULL; + } + rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0); + if (PyErr_Occurred()) { + Py_XDECREF(readmethod); + return NULL; + } + + if (!rv || bytes_read == 0) + break; + } + Py_XDECREF(readmethod); + return get_parse_result(self, rv); +} + +/*[clinic input] +pyexpat.xmlparser.SetBase + + base: str + / + +Set the base URL for the parser. +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base) +/*[clinic end generated code: output=c212ddceb607b539 input=c684e5de895ee1a8]*/ +{ + if (!XML_SetBase(self->itself, base)) { + return PyErr_NoMemory(); + } + Py_RETURN_NONE; +} + +/*[clinic input] +pyexpat.xmlparser.GetBase + +Return base URL string for the parser. +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser_GetBase_impl(xmlparseobject *self) +/*[clinic end generated code: output=2886cb21f9a8739a input=918d71c38009620e]*/ +{ + return Py_BuildValue("z", XML_GetBase(self->itself)); +} + +/*[clinic input] +pyexpat.xmlparser.GetInputContext + +Return the untranslated text of the input that caused the current event. + +If the event was generated by a large amount of text (such as a start tag +for an element with many attributes), not all of the text may be available. +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self) +/*[clinic end generated code: output=a88026d683fc22cc input=034df8712db68379]*/ +{ + if (self->in_callback) { + int offset, size; + const char *buffer + = XML_GetInputContext(self->itself, &offset, &size); + + if (buffer != NULL) + return PyBytes_FromStringAndSize(buffer + offset, + size - offset); + else + Py_RETURN_NONE; + } + else + Py_RETURN_NONE; +} + +/*[clinic input] +pyexpat.xmlparser.ExternalEntityParserCreate + + context: str(accept={str, NoneType}) + encoding: str = NULL + / + +Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler. +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, + const char *context, + const char *encoding) +/*[clinic end generated code: output=535cda9d7a0fbcd6 input=b906714cc122c322]*/ +{ + xmlparseobject *new_parser; + int i; + + new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype); + if (new_parser == NULL) + return NULL; + new_parser->buffer_size = self->buffer_size; + new_parser->buffer_used = 0; + new_parser->buffer = NULL; + new_parser->ordered_attributes = self->ordered_attributes; + new_parser->specified_attributes = self->specified_attributes; + new_parser->in_callback = 0; + new_parser->ns_prefixes = self->ns_prefixes; + new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context, + encoding); + new_parser->handlers = 0; + new_parser->intern = self->intern; + Py_XINCREF(new_parser->intern); + + if (self->buffer != NULL) { + new_parser->buffer = PyMem_Malloc(new_parser->buffer_size); + if (new_parser->buffer == NULL) { + Py_DECREF(new_parser); + return PyErr_NoMemory(); + } + } + if (!new_parser->itself) { + Py_DECREF(new_parser); + return PyErr_NoMemory(); + } + + XML_SetUserData(new_parser->itself, (void *)new_parser); + + /* allocate and clear handlers first */ + for (i = 0; handler_info[i].name != NULL; i++) + /* do nothing */; + + new_parser->handlers = PyMem_New(PyObject *, i); + if (!new_parser->handlers) { + Py_DECREF(new_parser); + return PyErr_NoMemory(); + } + clear_handlers(new_parser, 1); + + /* then copy handlers from self */ + for (i = 0; handler_info[i].name != NULL; i++) { + PyObject *handler = self->handlers[i]; + if (handler != NULL) { + Py_INCREF(handler); + new_parser->handlers[i] = handler; + handler_info[i].setter(new_parser->itself, + handler_info[i].handler); + } + } PyObject_GC_Track(new_parser); - return (PyObject *)new_parser; -} - -/*[clinic input] -pyexpat.xmlparser.SetParamEntityParsing - - flag: int - / - -Controls parsing of parameter entities (including the external DTD subset). - -Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER, -XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and -XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag -was successful. -[clinic start generated code]*/ - -static PyObject * -pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag) -/*[clinic end generated code: output=18668ee8e760d64c input=8aea19b4b15e9af1]*/ -{ - flag = XML_SetParamEntityParsing(self->itself, flag); - return PyLong_FromLong(flag); -} - - -#if XML_COMBINED_VERSION >= 19505 -/*[clinic input] -pyexpat.xmlparser.UseForeignDTD - - flag: bool = True - / - -Allows the application to provide an artificial external subset if one is not specified as part of the document instance. - -This readily allows the use of a 'default' document type controlled by the -application, while still getting the advantage of providing document type -information to the parser. 'flag' defaults to True if not provided. -[clinic start generated code]*/ - -static PyObject * -pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag) -/*[clinic end generated code: output=cfaa9aa50bb0f65c input=78144c519d116a6e]*/ -{ - enum XML_Error rc; - - rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE); - if (rc != XML_ERROR_NONE) { - return set_error(self, rc); - } - Py_RETURN_NONE; -} -#endif - -static struct PyMethodDef xmlparse_methods[] = { - PYEXPAT_XMLPARSER_PARSE_METHODDEF - PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF - PYEXPAT_XMLPARSER_SETBASE_METHODDEF - PYEXPAT_XMLPARSER_GETBASE_METHODDEF - PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF - PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF - PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF -#if XML_COMBINED_VERSION >= 19505 - PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF -#endif - {NULL, NULL} /* sentinel */ -}; - -/* ---------- */ - - - -/* pyexpat international encoding support. - Make it as simple as possible. -*/ - -static int -PyUnknownEncodingHandler(void *encodingHandlerData, - const XML_Char *name, - XML_Encoding *info) -{ - static unsigned char template_buffer[256] = {0}; - PyObject* u; - int i; + return (PyObject *)new_parser; +} + +/*[clinic input] +pyexpat.xmlparser.SetParamEntityParsing + + flag: int + / + +Controls parsing of parameter entities (including the external DTD subset). + +Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER, +XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and +XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag +was successful. +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag) +/*[clinic end generated code: output=18668ee8e760d64c input=8aea19b4b15e9af1]*/ +{ + flag = XML_SetParamEntityParsing(self->itself, flag); + return PyLong_FromLong(flag); +} + + +#if XML_COMBINED_VERSION >= 19505 +/*[clinic input] +pyexpat.xmlparser.UseForeignDTD + + flag: bool = True + / + +Allows the application to provide an artificial external subset if one is not specified as part of the document instance. + +This readily allows the use of a 'default' document type controlled by the +application, while still getting the advantage of providing document type +information to the parser. 'flag' defaults to True if not provided. +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag) +/*[clinic end generated code: output=cfaa9aa50bb0f65c input=78144c519d116a6e]*/ +{ + enum XML_Error rc; + + rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE); + if (rc != XML_ERROR_NONE) { + return set_error(self, rc); + } + Py_RETURN_NONE; +} +#endif + +static struct PyMethodDef xmlparse_methods[] = { + PYEXPAT_XMLPARSER_PARSE_METHODDEF + PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF + PYEXPAT_XMLPARSER_SETBASE_METHODDEF + PYEXPAT_XMLPARSER_GETBASE_METHODDEF + PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF + PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF + PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF +#if XML_COMBINED_VERSION >= 19505 + PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF +#endif + {NULL, NULL} /* sentinel */ +}; + +/* ---------- */ + + + +/* pyexpat international encoding support. + Make it as simple as possible. +*/ + +static int +PyUnknownEncodingHandler(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info) +{ + static unsigned char template_buffer[256] = {0}; + PyObject* u; + int i; const void *data; - unsigned int kind; - - if (PyErr_Occurred()) - return XML_STATUS_ERROR; - - if (template_buffer[1] == 0) { - for (i = 0; i < 256; i++) - template_buffer[i] = i; - } - - u = PyUnicode_Decode((char*) template_buffer, 256, name, "replace"); - if (u == NULL || PyUnicode_READY(u)) { - Py_XDECREF(u); - return XML_STATUS_ERROR; - } - - if (PyUnicode_GET_LENGTH(u) != 256) { - Py_DECREF(u); - PyErr_SetString(PyExc_ValueError, - "multi-byte encodings are not supported"); - return XML_STATUS_ERROR; - } - - kind = PyUnicode_KIND(u); - data = PyUnicode_DATA(u); - for (i = 0; i < 256; i++) { - Py_UCS4 ch = PyUnicode_READ(kind, data, i); - if (ch != Py_UNICODE_REPLACEMENT_CHARACTER) - info->map[i] = ch; - else - info->map[i] = -1; - } - - info->data = NULL; - info->convert = NULL; - info->release = NULL; - Py_DECREF(u); - - return XML_STATUS_OK; -} - - -static PyObject * -newxmlparseobject(const char *encoding, const char *namespace_separator, PyObject *intern) -{ - int i; - xmlparseobject *self; - - self = PyObject_GC_New(xmlparseobject, &Xmlparsetype); - if (self == NULL) - return NULL; - - self->buffer = NULL; - self->buffer_size = CHARACTER_DATA_BUFFER_SIZE; - self->buffer_used = 0; - self->ordered_attributes = 0; - self->specified_attributes = 0; - self->in_callback = 0; - self->ns_prefixes = 0; - self->handlers = NULL; - self->intern = intern; - Py_XINCREF(self->intern); - - /* namespace_separator is either NULL or contains one char + \0 */ - self->itself = XML_ParserCreate_MM(encoding, &ExpatMemoryHandler, - namespace_separator); - if (self->itself == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "XML_ParserCreate failed"); - Py_DECREF(self); - return NULL; - } -#if XML_COMBINED_VERSION >= 20100 - /* This feature was added upstream in libexpat 2.1.0. */ - XML_SetHashSalt(self->itself, - (unsigned long)_Py_HashSecret.expat.hashsalt); -#endif - XML_SetUserData(self->itself, (void *)self); - XML_SetUnknownEncodingHandler(self->itself, - (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL); - - for (i = 0; handler_info[i].name != NULL; i++) - /* do nothing */; - - self->handlers = PyMem_New(PyObject *, i); - if (!self->handlers) { - Py_DECREF(self); - return PyErr_NoMemory(); - } - clear_handlers(self, 1); - + unsigned int kind; + + if (PyErr_Occurred()) + return XML_STATUS_ERROR; + + if (template_buffer[1] == 0) { + for (i = 0; i < 256; i++) + template_buffer[i] = i; + } + + u = PyUnicode_Decode((char*) template_buffer, 256, name, "replace"); + if (u == NULL || PyUnicode_READY(u)) { + Py_XDECREF(u); + return XML_STATUS_ERROR; + } + + if (PyUnicode_GET_LENGTH(u) != 256) { + Py_DECREF(u); + PyErr_SetString(PyExc_ValueError, + "multi-byte encodings are not supported"); + return XML_STATUS_ERROR; + } + + kind = PyUnicode_KIND(u); + data = PyUnicode_DATA(u); + for (i = 0; i < 256; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + if (ch != Py_UNICODE_REPLACEMENT_CHARACTER) + info->map[i] = ch; + else + info->map[i] = -1; + } + + info->data = NULL; + info->convert = NULL; + info->release = NULL; + Py_DECREF(u); + + return XML_STATUS_OK; +} + + +static PyObject * +newxmlparseobject(const char *encoding, const char *namespace_separator, PyObject *intern) +{ + int i; + xmlparseobject *self; + + self = PyObject_GC_New(xmlparseobject, &Xmlparsetype); + if (self == NULL) + return NULL; + + self->buffer = NULL; + self->buffer_size = CHARACTER_DATA_BUFFER_SIZE; + self->buffer_used = 0; + self->ordered_attributes = 0; + self->specified_attributes = 0; + self->in_callback = 0; + self->ns_prefixes = 0; + self->handlers = NULL; + self->intern = intern; + Py_XINCREF(self->intern); + + /* namespace_separator is either NULL or contains one char + \0 */ + self->itself = XML_ParserCreate_MM(encoding, &ExpatMemoryHandler, + namespace_separator); + if (self->itself == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "XML_ParserCreate failed"); + Py_DECREF(self); + return NULL; + } +#if XML_COMBINED_VERSION >= 20100 + /* This feature was added upstream in libexpat 2.1.0. */ + XML_SetHashSalt(self->itself, + (unsigned long)_Py_HashSecret.expat.hashsalt); +#endif + XML_SetUserData(self->itself, (void *)self); + XML_SetUnknownEncodingHandler(self->itself, + (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL); + + for (i = 0; handler_info[i].name != NULL; i++) + /* do nothing */; + + self->handlers = PyMem_New(PyObject *, i); + if (!self->handlers) { + Py_DECREF(self); + return PyErr_NoMemory(); + } + clear_handlers(self, 1); + PyObject_GC_Track(self); - return (PyObject*)self; -} - - -static void -xmlparse_dealloc(xmlparseobject *self) -{ - int i; - PyObject_GC_UnTrack(self); - if (self->itself != NULL) - XML_ParserFree(self->itself); - self->itself = NULL; - - if (self->handlers != NULL) { - for (i = 0; handler_info[i].name != NULL; i++) - Py_CLEAR(self->handlers[i]); - PyMem_Free(self->handlers); - self->handlers = NULL; - } - if (self->buffer != NULL) { - PyMem_Free(self->buffer); - self->buffer = NULL; - } - Py_XDECREF(self->intern); - PyObject_GC_Del(self); -} - - -static PyObject * + return (PyObject*)self; +} + + +static void +xmlparse_dealloc(xmlparseobject *self) +{ + int i; + PyObject_GC_UnTrack(self); + if (self->itself != NULL) + XML_ParserFree(self->itself); + self->itself = NULL; + + if (self->handlers != NULL) { + for (i = 0; handler_info[i].name != NULL; i++) + Py_CLEAR(self->handlers[i]); + PyMem_Free(self->handlers); + self->handlers = NULL; + } + if (self->buffer != NULL) { + PyMem_Free(self->buffer); + self->buffer = NULL; + } + Py_XDECREF(self->intern); + PyObject_GC_Del(self); +} + + +static PyObject * xmlparse_handler_getter(xmlparseobject *self, struct HandlerInfo *hi) -{ +{ assert((hi - handler_info) < (Py_ssize_t)Py_ARRAY_LENGTH(handler_info)); int handlernum = (int)(hi - handler_info); PyObject *result = self->handlers[handlernum]; if (result == NULL) result = Py_None; - Py_INCREF(result); - return result; -} - + Py_INCREF(result); + return result; +} + static int xmlparse_handler_setter(xmlparseobject *self, PyObject *v, struct HandlerInfo *hi) -{ +{ assert((hi - handler_info) < (Py_ssize_t)Py_ARRAY_LENGTH(handler_info)); int handlernum = (int)(hi - handler_info); if (v == NULL) { PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); return -1; - } + } if (handlernum == CharacterData) { /* If we're changing the character data handler, flush all * cached data with the old handler. Not sure there's a @@ -1211,7 +1211,7 @@ xmlparse_handler_setter(xmlparseobject *self, PyObject *v, struct HandlerInfo *h if (flush_character_buffer(self) < 0) return -1; } - + xmlhandler c_handler = NULL; if (v == Py_None) { /* If this is the character data handler, and a character @@ -1228,16 +1228,16 @@ xmlparse_handler_setter(xmlparseobject *self, PyObject *v, struct HandlerInfo *h if (handlernum == CharacterData && self->in_callback) c_handler = noop_character_data_handler; v = NULL; - } + } else if (v != NULL) { Py_INCREF(v); c_handler = handler_info[handlernum].handler; - } + } Py_XSETREF(self->handlers[handlernum], v); handler_info[handlernum].setter(self->itself, c_handler); return 0; -} - +} + #define INT_GETTER(name) \ static PyObject * \ xmlparse_##name##_getter(xmlparseobject *self, void *closure) \ @@ -1256,36 +1256,36 @@ INT_GETTER(CurrentByteIndex) static PyObject * xmlparse_buffer_text_getter(xmlparseobject *self, void *closure) -{ +{ return PyBool_FromLong(self->buffer != NULL); -} - -static int +} + +static int xmlparse_buffer_text_setter(xmlparseobject *self, PyObject *v, void *closure) -{ - if (v == NULL) { - PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); - return -1; - } +{ + if (v == NULL) { + PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); + return -1; + } int b = PyObject_IsTrue(v); if (b < 0) return -1; if (b) { if (self->buffer == NULL) { self->buffer = PyMem_Malloc(self->buffer_size); - if (self->buffer == NULL) { + if (self->buffer == NULL) { PyErr_NoMemory(); return -1; - } + } self->buffer_used = 0; - } - } + } + } else if (self->buffer != NULL) { if (flush_character_buffer(self) < 0) - return -1; + return -1; PyMem_Free(self->buffer); self->buffer = NULL; - } + } return 0; } @@ -1301,52 +1301,52 @@ xmlparse_buffer_size_setter(xmlparseobject *self, PyObject *v, void *closure) if (v == NULL) { PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); return -1; - } + } long new_buffer_size; if (!PyLong_Check(v)) { - PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer"); - return -1; + PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer"); + return -1; } - + new_buffer_size = PyLong_AsLong(v); if (new_buffer_size <= 0) { - if (!PyErr_Occurred()) + if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero"); - return -1; + return -1; } - + /* trivial case -- no change */ if (new_buffer_size == self->buffer_size) { - return 0; + return 0; } - + /* check maximum */ if (new_buffer_size > INT_MAX) { - char errmsg[100]; - sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX); - PyErr_SetString(PyExc_ValueError, errmsg); - return -1; + char errmsg[100]; + sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX); + PyErr_SetString(PyExc_ValueError, errmsg); + return -1; } - + if (self->buffer != NULL) { - /* there is already a buffer */ - if (self->buffer_used != 0) { - if (flush_character_buffer(self) < 0) { - return -1; - } - } - /* free existing buffer */ - PyMem_Free(self->buffer); + /* there is already a buffer */ + if (self->buffer_used != 0) { + if (flush_character_buffer(self) < 0) { + return -1; + } + } + /* free existing buffer */ + PyMem_Free(self->buffer); } self->buffer = PyMem_Malloc(new_buffer_size); if (self->buffer == NULL) { - PyErr_NoMemory(); - return -1; - } + PyErr_NoMemory(); + return -1; + } self->buffer_size = new_buffer_size; return 0; } - + static PyObject * xmlparse_buffer_used_getter(xmlparseobject *self, void *closure) { @@ -1365,7 +1365,7 @@ xmlparse_namespace_prefixes_setter(xmlparseobject *self, PyObject *v, void *clos if (v == NULL) { PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); return -1; - } + } int b = PyObject_IsTrue(v); if (b < 0) return -1; @@ -1386,21 +1386,21 @@ xmlparse_ordered_attributes_setter(xmlparseobject *self, PyObject *v, void *clos if (v == NULL) { PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); return -1; - } + } int b = PyObject_IsTrue(v); if (b < 0) return -1; self->ordered_attributes = b; return 0; -} - +} + static PyObject * xmlparse_specified_attributes_getter(xmlparseobject *self, void *closure) { return PyBool_FromLong((long) self->specified_attributes); } -static int +static int xmlparse_specified_attributes_setter(xmlparseobject *self, PyObject *v, void *closure) { if (v == NULL) { @@ -1446,159 +1446,159 @@ static PyGetSetDef xmlparse_getsetlist[] = { #undef XMLPARSE_GETTER_SETTER_DEF static int -xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg) -{ - int i; - for (i = 0; handler_info[i].name != NULL; i++) - Py_VISIT(op->handlers[i]); - return 0; -} - -static int -xmlparse_clear(xmlparseobject *op) -{ - clear_handlers(op, 0); - Py_CLEAR(op->intern); - return 0; -} - -PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser"); - -static PyTypeObject Xmlparsetype = { - PyVarObject_HEAD_INIT(NULL, 0) - "pyexpat.xmlparser", /*tp_name*/ - sizeof(xmlparseobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)xmlparse_dealloc, /*tp_dealloc*/ +xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg) +{ + int i; + for (i = 0; handler_info[i].name != NULL; i++) + Py_VISIT(op->handlers[i]); + return 0; +} + +static int +xmlparse_clear(xmlparseobject *op) +{ + clear_handlers(op, 0); + Py_CLEAR(op->intern); + return 0; +} + +PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser"); + +static PyTypeObject Xmlparsetype = { + PyVarObject_HEAD_INIT(NULL, 0) + "pyexpat.xmlparser", /*tp_name*/ + sizeof(xmlparseobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)xmlparse_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)0, /*tp_str*/ + (reprfunc)0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + (hashfunc)0, /*tp_hash*/ + (ternaryfunc)0, /*tp_call*/ + (reprfunc)0, /*tp_str*/ (getattrofunc)0, /* tp_getattro */ (setattrofunc)0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - Xmlparsetype__doc__, /* tp_doc - Documentation string */ - (traverseproc)xmlparse_traverse, /* tp_traverse */ - (inquiry)xmlparse_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - xmlparse_methods, /* tp_methods */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + Xmlparsetype__doc__, /* tp_doc - Documentation string */ + (traverseproc)xmlparse_traverse, /* tp_traverse */ + (inquiry)xmlparse_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + xmlparse_methods, /* tp_methods */ xmlparse_members, /* tp_members */ xmlparse_getsetlist, /* tp_getset */ -}; - -/* End of code for xmlparser objects */ -/* -------------------------------------------------------- */ - -/*[clinic input] -pyexpat.ParserCreate - +}; + +/* End of code for xmlparser objects */ +/* -------------------------------------------------------- */ + +/*[clinic input] +pyexpat.ParserCreate + encoding: str(accept={str, NoneType}) = None namespace_separator: str(accept={str, NoneType}) = None - intern: object = NULL - -Return a new XML parser object. -[clinic start generated code]*/ - -static PyObject * -pyexpat_ParserCreate_impl(PyObject *module, const char *encoding, - const char *namespace_separator, PyObject *intern) + intern: object = NULL + +Return a new XML parser object. +[clinic start generated code]*/ + +static PyObject * +pyexpat_ParserCreate_impl(PyObject *module, const char *encoding, + const char *namespace_separator, PyObject *intern) /*[clinic end generated code: output=295c0cf01ab1146c input=e8da8e8d7122cb5d]*/ -{ - PyObject *result; - int intern_decref = 0; - - if (namespace_separator != NULL - && strlen(namespace_separator) > 1) { - PyErr_SetString(PyExc_ValueError, - "namespace_separator must be at most one" - " character, omitted, or None"); - return NULL; - } - /* Explicitly passing None means no interning is desired. - Not passing anything means that a new dictionary is used. */ - if (intern == Py_None) - intern = NULL; - else if (intern == NULL) { - intern = PyDict_New(); - if (!intern) - return NULL; - intern_decref = 1; - } - else if (!PyDict_Check(intern)) { - PyErr_SetString(PyExc_TypeError, "intern must be a dictionary"); - return NULL; - } - - result = newxmlparseobject(encoding, namespace_separator, intern); - if (intern_decref) { - Py_DECREF(intern); - } - return result; -} - -/*[clinic input] -pyexpat.ErrorString - - code: long - / - -Returns string error for given number. -[clinic start generated code]*/ - -static PyObject * -pyexpat_ErrorString_impl(PyObject *module, long code) -/*[clinic end generated code: output=2feae50d166f2174 input=cc67de010d9e62b3]*/ -{ - return Py_BuildValue("z", XML_ErrorString((int)code)); -} - -/* List of methods defined in the module */ - -static struct PyMethodDef pyexpat_methods[] = { - PYEXPAT_PARSERCREATE_METHODDEF - PYEXPAT_ERRORSTRING_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -/* Module docstring */ - -PyDoc_STRVAR(pyexpat_module_documentation, -"Python wrapper for Expat parser."); - -/* Initialization function for the module */ - -#ifndef MODULE_NAME -#define MODULE_NAME "pyexpat" -#endif - -#ifndef MODULE_INITFUNC -#define MODULE_INITFUNC PyInit_pyexpat -#endif - -static struct PyModuleDef pyexpatmodule = { - PyModuleDef_HEAD_INIT, - MODULE_NAME, - pyexpat_module_documentation, - -1, - pyexpat_methods, - NULL, - NULL, - NULL, - NULL -}; - +{ + PyObject *result; + int intern_decref = 0; + + if (namespace_separator != NULL + && strlen(namespace_separator) > 1) { + PyErr_SetString(PyExc_ValueError, + "namespace_separator must be at most one" + " character, omitted, or None"); + return NULL; + } + /* Explicitly passing None means no interning is desired. + Not passing anything means that a new dictionary is used. */ + if (intern == Py_None) + intern = NULL; + else if (intern == NULL) { + intern = PyDict_New(); + if (!intern) + return NULL; + intern_decref = 1; + } + else if (!PyDict_Check(intern)) { + PyErr_SetString(PyExc_TypeError, "intern must be a dictionary"); + return NULL; + } + + result = newxmlparseobject(encoding, namespace_separator, intern); + if (intern_decref) { + Py_DECREF(intern); + } + return result; +} + +/*[clinic input] +pyexpat.ErrorString + + code: long + / + +Returns string error for given number. +[clinic start generated code]*/ + +static PyObject * +pyexpat_ErrorString_impl(PyObject *module, long code) +/*[clinic end generated code: output=2feae50d166f2174 input=cc67de010d9e62b3]*/ +{ + return Py_BuildValue("z", XML_ErrorString((int)code)); +} + +/* List of methods defined in the module */ + +static struct PyMethodDef pyexpat_methods[] = { + PYEXPAT_PARSERCREATE_METHODDEF + PYEXPAT_ERRORSTRING_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +/* Module docstring */ + +PyDoc_STRVAR(pyexpat_module_documentation, +"Python wrapper for Expat parser."); + +/* Initialization function for the module */ + +#ifndef MODULE_NAME +#define MODULE_NAME "pyexpat" +#endif + +#ifndef MODULE_INITFUNC +#define MODULE_INITFUNC PyInit_pyexpat +#endif + +static struct PyModuleDef pyexpatmodule = { + PyModuleDef_HEAD_INIT, + MODULE_NAME, + pyexpat_module_documentation, + -1, + pyexpat_methods, + NULL, + NULL, + NULL, + NULL +}; + static int init_handler_descrs(void) { int i; @@ -1631,277 +1631,277 @@ static int init_handler_descrs(void) return 0; } -PyMODINIT_FUNC -MODULE_INITFUNC(void) -{ - PyObject *m, *d; - PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors"); - PyObject *errors_module; - PyObject *modelmod_name; - PyObject *model_module; - PyObject *tmpnum, *tmpstr; - PyObject *codes_dict; - PyObject *rev_codes_dict; - int res; - static struct PyExpat_CAPI capi; - PyObject *capi_object; - - if (errmod_name == NULL) - return NULL; - modelmod_name = PyUnicode_FromString(MODULE_NAME ".model"); - if (modelmod_name == NULL) - return NULL; - +PyMODINIT_FUNC +MODULE_INITFUNC(void) +{ + PyObject *m, *d; + PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors"); + PyObject *errors_module; + PyObject *modelmod_name; + PyObject *model_module; + PyObject *tmpnum, *tmpstr; + PyObject *codes_dict; + PyObject *rev_codes_dict; + int res; + static struct PyExpat_CAPI capi; + PyObject *capi_object; + + if (errmod_name == NULL) + return NULL; + modelmod_name = PyUnicode_FromString(MODULE_NAME ".model"); + if (modelmod_name == NULL) + return NULL; + if (PyType_Ready(&Xmlparsetype) < 0 || init_handler_descrs() < 0) - return NULL; - - /* Create the module and add the functions */ - m = PyModule_Create(&pyexpatmodule); - if (m == NULL) - return NULL; - - /* Add some symbolic constants to the module */ - if (ErrorObject == NULL) { - ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError", - NULL, NULL); - if (ErrorObject == NULL) - return NULL; - } - Py_INCREF(ErrorObject); - PyModule_AddObject(m, "error", ErrorObject); - Py_INCREF(ErrorObject); - PyModule_AddObject(m, "ExpatError", ErrorObject); - Py_INCREF(&Xmlparsetype); - PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - - PyModule_AddStringConstant(m, "EXPAT_VERSION", - XML_ExpatVersion()); - { - XML_Expat_Version info = XML_ExpatVersionInfo(); - PyModule_AddObject(m, "version_info", - Py_BuildValue("(iii)", info.major, - info.minor, info.micro)); - } - /* XXX When Expat supports some way of figuring out how it was - compiled, this should check and set native_encoding - appropriately. - */ - PyModule_AddStringConstant(m, "native_encoding", "UTF-8"); - - d = PyModule_GetDict(m); - if (d == NULL) { - Py_DECREF(m); - return NULL; - } + return NULL; + + /* Create the module and add the functions */ + m = PyModule_Create(&pyexpatmodule); + if (m == NULL) + return NULL; + + /* Add some symbolic constants to the module */ + if (ErrorObject == NULL) { + ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError", + NULL, NULL); + if (ErrorObject == NULL) + return NULL; + } + Py_INCREF(ErrorObject); + PyModule_AddObject(m, "error", ErrorObject); + Py_INCREF(ErrorObject); + PyModule_AddObject(m, "ExpatError", ErrorObject); + Py_INCREF(&Xmlparsetype); + PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); + + PyModule_AddStringConstant(m, "EXPAT_VERSION", + XML_ExpatVersion()); + { + XML_Expat_Version info = XML_ExpatVersionInfo(); + PyModule_AddObject(m, "version_info", + Py_BuildValue("(iii)", info.major, + info.minor, info.micro)); + } + /* XXX When Expat supports some way of figuring out how it was + compiled, this should check and set native_encoding + appropriately. + */ + PyModule_AddStringConstant(m, "native_encoding", "UTF-8"); + + d = PyModule_GetDict(m); + if (d == NULL) { + Py_DECREF(m); + return NULL; + } errors_module = PyDict_GetItemWithError(d, errmod_name); if (errors_module == NULL && !PyErr_Occurred()) { - errors_module = PyModule_New(MODULE_NAME ".errors"); - if (errors_module != NULL) { - _PyImport_SetModule(errmod_name, errors_module); - /* gives away the reference to errors_module */ - PyModule_AddObject(m, "errors", errors_module); - } - } - Py_DECREF(errmod_name); + errors_module = PyModule_New(MODULE_NAME ".errors"); + if (errors_module != NULL) { + _PyImport_SetModule(errmod_name, errors_module); + /* gives away the reference to errors_module */ + PyModule_AddObject(m, "errors", errors_module); + } + } + Py_DECREF(errmod_name); model_module = PyDict_GetItemWithError(d, modelmod_name); if (model_module == NULL && !PyErr_Occurred()) { - model_module = PyModule_New(MODULE_NAME ".model"); - if (model_module != NULL) { - _PyImport_SetModule(modelmod_name, model_module); - /* gives away the reference to model_module */ - PyModule_AddObject(m, "model", model_module); - } - } - Py_DECREF(modelmod_name); - if (errors_module == NULL || model_module == NULL) { - /* Don't core dump later! */ - Py_DECREF(m); - return NULL; - } - -#if XML_COMBINED_VERSION > 19505 - { - const XML_Feature *features = XML_GetFeatureList(); - PyObject *list = PyList_New(0); - if (list == NULL) - /* just ignore it */ - PyErr_Clear(); - else { - int i = 0; - for (; features[i].feature != XML_FEATURE_END; ++i) { - int ok; - PyObject *item = Py_BuildValue("si", features[i].name, - features[i].value); - if (item == NULL) { - Py_DECREF(list); - list = NULL; - break; - } - ok = PyList_Append(list, item); - Py_DECREF(item); - if (ok < 0) { - PyErr_Clear(); - break; - } - } - if (list != NULL) - PyModule_AddObject(m, "features", list); - } - } -#endif - - codes_dict = PyDict_New(); - rev_codes_dict = PyDict_New(); - if (codes_dict == NULL || rev_codes_dict == NULL) { - Py_XDECREF(codes_dict); - Py_XDECREF(rev_codes_dict); - return NULL; - } - -#define MYCONST(name) \ - if (PyModule_AddStringConstant(errors_module, #name, \ - XML_ErrorString(name)) < 0) \ - return NULL; \ - tmpnum = PyLong_FromLong(name); \ - if (tmpnum == NULL) return NULL; \ - res = PyDict_SetItemString(codes_dict, \ - XML_ErrorString(name), tmpnum); \ - if (res < 0) return NULL; \ - tmpstr = PyUnicode_FromString(XML_ErrorString(name)); \ - if (tmpstr == NULL) return NULL; \ - res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr); \ - Py_DECREF(tmpstr); \ - Py_DECREF(tmpnum); \ - if (res < 0) return NULL; \ - - MYCONST(XML_ERROR_NO_MEMORY); - MYCONST(XML_ERROR_SYNTAX); - MYCONST(XML_ERROR_NO_ELEMENTS); - MYCONST(XML_ERROR_INVALID_TOKEN); - MYCONST(XML_ERROR_UNCLOSED_TOKEN); - MYCONST(XML_ERROR_PARTIAL_CHAR); - MYCONST(XML_ERROR_TAG_MISMATCH); - MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE); - MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT); - MYCONST(XML_ERROR_PARAM_ENTITY_REF); - MYCONST(XML_ERROR_UNDEFINED_ENTITY); - MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF); - MYCONST(XML_ERROR_ASYNC_ENTITY); - MYCONST(XML_ERROR_BAD_CHAR_REF); - MYCONST(XML_ERROR_BINARY_ENTITY_REF); - MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF); - MYCONST(XML_ERROR_MISPLACED_XML_PI); - MYCONST(XML_ERROR_UNKNOWN_ENCODING); - MYCONST(XML_ERROR_INCORRECT_ENCODING); - MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION); - MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING); - MYCONST(XML_ERROR_NOT_STANDALONE); - MYCONST(XML_ERROR_UNEXPECTED_STATE); - MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE); - MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD); - MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING); - /* Added in Expat 1.95.7. */ - MYCONST(XML_ERROR_UNBOUND_PREFIX); - /* Added in Expat 1.95.8. */ - MYCONST(XML_ERROR_UNDECLARING_PREFIX); - MYCONST(XML_ERROR_INCOMPLETE_PE); - MYCONST(XML_ERROR_XML_DECL); - MYCONST(XML_ERROR_TEXT_DECL); - MYCONST(XML_ERROR_PUBLICID); - MYCONST(XML_ERROR_SUSPENDED); - MYCONST(XML_ERROR_NOT_SUSPENDED); - MYCONST(XML_ERROR_ABORTED); - MYCONST(XML_ERROR_FINISHED); - MYCONST(XML_ERROR_SUSPEND_PE); - - if (PyModule_AddStringConstant(errors_module, "__doc__", - "Constants used to describe " - "error conditions.") < 0) - return NULL; - - if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0) - return NULL; - if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0) - return NULL; - -#undef MYCONST - -#define MYCONST(c) PyModule_AddIntConstant(m, #c, c) - MYCONST(XML_PARAM_ENTITY_PARSING_NEVER); - MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); - MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS); -#undef MYCONST - -#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c) - PyModule_AddStringConstant(model_module, "__doc__", - "Constants used to interpret content model information."); - - MYCONST(XML_CTYPE_EMPTY); - MYCONST(XML_CTYPE_ANY); - MYCONST(XML_CTYPE_MIXED); - MYCONST(XML_CTYPE_NAME); - MYCONST(XML_CTYPE_CHOICE); - MYCONST(XML_CTYPE_SEQ); - - MYCONST(XML_CQUANT_NONE); - MYCONST(XML_CQUANT_OPT); - MYCONST(XML_CQUANT_REP); - MYCONST(XML_CQUANT_PLUS); -#undef MYCONST - - /* initialize pyexpat dispatch table */ - capi.size = sizeof(capi); - capi.magic = PyExpat_CAPI_MAGIC; - capi.MAJOR_VERSION = XML_MAJOR_VERSION; - capi.MINOR_VERSION = XML_MINOR_VERSION; - capi.MICRO_VERSION = XML_MICRO_VERSION; - capi.ErrorString = XML_ErrorString; - capi.GetErrorCode = XML_GetErrorCode; - capi.GetErrorColumnNumber = XML_GetErrorColumnNumber; - capi.GetErrorLineNumber = XML_GetErrorLineNumber; - capi.Parse = XML_Parse; - capi.ParserCreate_MM = XML_ParserCreate_MM; - capi.ParserFree = XML_ParserFree; - capi.SetCharacterDataHandler = XML_SetCharacterDataHandler; - capi.SetCommentHandler = XML_SetCommentHandler; - capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand; - capi.SetElementHandler = XML_SetElementHandler; - capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler; - capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler; - capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler; - capi.SetUserData = XML_SetUserData; - capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler; - capi.SetEncoding = XML_SetEncoding; - capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler; -#if XML_COMBINED_VERSION >= 20100 - capi.SetHashSalt = XML_SetHashSalt; -#else - capi.SetHashSalt = NULL; -#endif - - /* export using capsule */ - capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL); - if (capi_object) - PyModule_AddObject(m, "expat_CAPI", capi_object); - return m; -} - -static void -clear_handlers(xmlparseobject *self, int initial) -{ - int i = 0; - - for (; handler_info[i].name != NULL; i++) { - if (initial) - self->handlers[i] = NULL; - else { - Py_CLEAR(self->handlers[i]); - handler_info[i].setter(self->itself, NULL); - } - } -} - -static struct HandlerInfo handler_info[] = { + model_module = PyModule_New(MODULE_NAME ".model"); + if (model_module != NULL) { + _PyImport_SetModule(modelmod_name, model_module); + /* gives away the reference to model_module */ + PyModule_AddObject(m, "model", model_module); + } + } + Py_DECREF(modelmod_name); + if (errors_module == NULL || model_module == NULL) { + /* Don't core dump later! */ + Py_DECREF(m); + return NULL; + } + +#if XML_COMBINED_VERSION > 19505 + { + const XML_Feature *features = XML_GetFeatureList(); + PyObject *list = PyList_New(0); + if (list == NULL) + /* just ignore it */ + PyErr_Clear(); + else { + int i = 0; + for (; features[i].feature != XML_FEATURE_END; ++i) { + int ok; + PyObject *item = Py_BuildValue("si", features[i].name, + features[i].value); + if (item == NULL) { + Py_DECREF(list); + list = NULL; + break; + } + ok = PyList_Append(list, item); + Py_DECREF(item); + if (ok < 0) { + PyErr_Clear(); + break; + } + } + if (list != NULL) + PyModule_AddObject(m, "features", list); + } + } +#endif + + codes_dict = PyDict_New(); + rev_codes_dict = PyDict_New(); + if (codes_dict == NULL || rev_codes_dict == NULL) { + Py_XDECREF(codes_dict); + Py_XDECREF(rev_codes_dict); + return NULL; + } + +#define MYCONST(name) \ + if (PyModule_AddStringConstant(errors_module, #name, \ + XML_ErrorString(name)) < 0) \ + return NULL; \ + tmpnum = PyLong_FromLong(name); \ + if (tmpnum == NULL) return NULL; \ + res = PyDict_SetItemString(codes_dict, \ + XML_ErrorString(name), tmpnum); \ + if (res < 0) return NULL; \ + tmpstr = PyUnicode_FromString(XML_ErrorString(name)); \ + if (tmpstr == NULL) return NULL; \ + res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr); \ + Py_DECREF(tmpstr); \ + Py_DECREF(tmpnum); \ + if (res < 0) return NULL; \ + + MYCONST(XML_ERROR_NO_MEMORY); + MYCONST(XML_ERROR_SYNTAX); + MYCONST(XML_ERROR_NO_ELEMENTS); + MYCONST(XML_ERROR_INVALID_TOKEN); + MYCONST(XML_ERROR_UNCLOSED_TOKEN); + MYCONST(XML_ERROR_PARTIAL_CHAR); + MYCONST(XML_ERROR_TAG_MISMATCH); + MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE); + MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT); + MYCONST(XML_ERROR_PARAM_ENTITY_REF); + MYCONST(XML_ERROR_UNDEFINED_ENTITY); + MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF); + MYCONST(XML_ERROR_ASYNC_ENTITY); + MYCONST(XML_ERROR_BAD_CHAR_REF); + MYCONST(XML_ERROR_BINARY_ENTITY_REF); + MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF); + MYCONST(XML_ERROR_MISPLACED_XML_PI); + MYCONST(XML_ERROR_UNKNOWN_ENCODING); + MYCONST(XML_ERROR_INCORRECT_ENCODING); + MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION); + MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING); + MYCONST(XML_ERROR_NOT_STANDALONE); + MYCONST(XML_ERROR_UNEXPECTED_STATE); + MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE); + MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD); + MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING); + /* Added in Expat 1.95.7. */ + MYCONST(XML_ERROR_UNBOUND_PREFIX); + /* Added in Expat 1.95.8. */ + MYCONST(XML_ERROR_UNDECLARING_PREFIX); + MYCONST(XML_ERROR_INCOMPLETE_PE); + MYCONST(XML_ERROR_XML_DECL); + MYCONST(XML_ERROR_TEXT_DECL); + MYCONST(XML_ERROR_PUBLICID); + MYCONST(XML_ERROR_SUSPENDED); + MYCONST(XML_ERROR_NOT_SUSPENDED); + MYCONST(XML_ERROR_ABORTED); + MYCONST(XML_ERROR_FINISHED); + MYCONST(XML_ERROR_SUSPEND_PE); + + if (PyModule_AddStringConstant(errors_module, "__doc__", + "Constants used to describe " + "error conditions.") < 0) + return NULL; + + if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0) + return NULL; + if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0) + return NULL; + +#undef MYCONST + +#define MYCONST(c) PyModule_AddIntConstant(m, #c, c) + MYCONST(XML_PARAM_ENTITY_PARSING_NEVER); + MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); + MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS); +#undef MYCONST + +#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c) + PyModule_AddStringConstant(model_module, "__doc__", + "Constants used to interpret content model information."); + + MYCONST(XML_CTYPE_EMPTY); + MYCONST(XML_CTYPE_ANY); + MYCONST(XML_CTYPE_MIXED); + MYCONST(XML_CTYPE_NAME); + MYCONST(XML_CTYPE_CHOICE); + MYCONST(XML_CTYPE_SEQ); + + MYCONST(XML_CQUANT_NONE); + MYCONST(XML_CQUANT_OPT); + MYCONST(XML_CQUANT_REP); + MYCONST(XML_CQUANT_PLUS); +#undef MYCONST + + /* initialize pyexpat dispatch table */ + capi.size = sizeof(capi); + capi.magic = PyExpat_CAPI_MAGIC; + capi.MAJOR_VERSION = XML_MAJOR_VERSION; + capi.MINOR_VERSION = XML_MINOR_VERSION; + capi.MICRO_VERSION = XML_MICRO_VERSION; + capi.ErrorString = XML_ErrorString; + capi.GetErrorCode = XML_GetErrorCode; + capi.GetErrorColumnNumber = XML_GetErrorColumnNumber; + capi.GetErrorLineNumber = XML_GetErrorLineNumber; + capi.Parse = XML_Parse; + capi.ParserCreate_MM = XML_ParserCreate_MM; + capi.ParserFree = XML_ParserFree; + capi.SetCharacterDataHandler = XML_SetCharacterDataHandler; + capi.SetCommentHandler = XML_SetCommentHandler; + capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand; + capi.SetElementHandler = XML_SetElementHandler; + capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler; + capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler; + capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler; + capi.SetUserData = XML_SetUserData; + capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler; + capi.SetEncoding = XML_SetEncoding; + capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler; +#if XML_COMBINED_VERSION >= 20100 + capi.SetHashSalt = XML_SetHashSalt; +#else + capi.SetHashSalt = NULL; +#endif + + /* export using capsule */ + capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL); + if (capi_object) + PyModule_AddObject(m, "expat_CAPI", capi_object); + return m; +} + +static void +clear_handlers(xmlparseobject *self, int initial) +{ + int i = 0; + + for (; handler_info[i].name != NULL; i++) { + if (initial) + self->handlers[i] = NULL; + else { + Py_CLEAR(self->handlers[i]); + handler_info[i].setter(self->itself, NULL); + } + } +} + +static struct HandlerInfo handler_info[] = { #define HANDLER_INFO(name) \ {#name, (xmlhandlersetter)XML_Set##name, (xmlhandler)my_##name}, @@ -1927,11 +1927,11 @@ static struct HandlerInfo handler_info[] = { HANDLER_INFO(XmlDeclHandler) HANDLER_INFO(ElementDeclHandler) HANDLER_INFO(AttlistDeclHandler) -#if XML_COMBINED_VERSION >= 19504 +#if XML_COMBINED_VERSION >= 19504 HANDLER_INFO(SkippedEntityHandler) -#endif - +#endif + #undef HANDLER_INFO - {NULL, NULL, NULL} /* sentinel */ -}; + {NULL, NULL, NULL} /* sentinel */ +}; diff --git a/contrib/tools/python3/src/Modules/resource.c b/contrib/tools/python3/src/Modules/resource.c index ddbf80be9c6..310e1fdedb9 100644 --- a/contrib/tools/python3/src/Modules/resource.c +++ b/contrib/tools/python3/src/Modules/resource.c @@ -1,497 +1,497 @@ - -#include "Python.h" -#include -#include -#include -#include -#include - -/* On some systems, these aren't in any header file. - On others they are, with inconsistent prototypes. - We declare the (default) return type, to shut up gcc -Wall; - but we can't declare the prototype, to avoid errors - when the header files declare it different. - Worse, on some Linuxes, getpagesize() returns a size_t... */ - -#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) - -/*[clinic input] -module resource -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e89d38ed52609d7c]*/ - -/*[python input] -class pid_t_converter(CConverter): - type = 'pid_t' - format_unit = '" _Py_PARSE_PID "' -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=0c1d19f640d57e48]*/ - -#include "clinic/resource.c.h" - -PyDoc_STRVAR(struct_rusage__doc__, -"struct_rusage: Result from getrusage.\n\n" -"This object may be accessed either as a tuple of\n" -" (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n" -" nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n" -"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on."); - -static PyStructSequence_Field struct_rusage_fields[] = { - {"ru_utime", "user time used"}, - {"ru_stime", "system time used"}, - {"ru_maxrss", "max. resident set size"}, - {"ru_ixrss", "shared memory size"}, - {"ru_idrss", "unshared data size"}, - {"ru_isrss", "unshared stack size"}, - {"ru_minflt", "page faults not requiring I/O"}, - {"ru_majflt", "page faults requiring I/O"}, - {"ru_nswap", "number of swap outs"}, - {"ru_inblock", "block input operations"}, - {"ru_oublock", "block output operations"}, - {"ru_msgsnd", "IPC messages sent"}, - {"ru_msgrcv", "IPC messages received"}, - {"ru_nsignals", "signals received"}, - {"ru_nvcsw", "voluntary context switches"}, - {"ru_nivcsw", "involuntary context switches"}, - {0} -}; - -static PyStructSequence_Desc struct_rusage_desc = { - "resource.struct_rusage", /* name */ - struct_rusage__doc__, /* doc */ - struct_rusage_fields, /* fields */ - 16 /* n_in_sequence */ -}; - -static int initialized; -static PyTypeObject StructRUsageType; - -/*[clinic input] -resource.getrusage - - who: int - / - -[clinic start generated code]*/ - -static PyObject * -resource_getrusage_impl(PyObject *module, int who) -/*[clinic end generated code: output=8fad2880ba6a9843 input=5c857bcc5b9ccb1b]*/ -{ - struct rusage ru; - PyObject *result; - - if (getrusage(who, &ru) == -1) { - if (errno == EINVAL) { - PyErr_SetString(PyExc_ValueError, - "invalid who parameter"); - return NULL; - } - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - result = PyStructSequence_New(&StructRUsageType); - if (!result) - return NULL; - - PyStructSequence_SET_ITEM(result, 0, - PyFloat_FromDouble(doubletime(ru.ru_utime))); - PyStructSequence_SET_ITEM(result, 1, - PyFloat_FromDouble(doubletime(ru.ru_stime))); - PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(ru.ru_maxrss)); - PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(ru.ru_ixrss)); - PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(ru.ru_idrss)); - PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(ru.ru_isrss)); - PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(ru.ru_minflt)); - PyStructSequence_SET_ITEM(result, 7, PyLong_FromLong(ru.ru_majflt)); - PyStructSequence_SET_ITEM(result, 8, PyLong_FromLong(ru.ru_nswap)); - PyStructSequence_SET_ITEM(result, 9, PyLong_FromLong(ru.ru_inblock)); - PyStructSequence_SET_ITEM(result, 10, PyLong_FromLong(ru.ru_oublock)); - PyStructSequence_SET_ITEM(result, 11, PyLong_FromLong(ru.ru_msgsnd)); - PyStructSequence_SET_ITEM(result, 12, PyLong_FromLong(ru.ru_msgrcv)); - PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(ru.ru_nsignals)); - PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw)); - PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw)); - - if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } - - return result; -} - -static int -py2rlimit(PyObject *limits, struct rlimit *rl_out) -{ - PyObject *curobj, *maxobj; - limits = PySequence_Tuple(limits); - if (!limits) - /* Here limits is a borrowed reference */ - return -1; - - if (PyTuple_GET_SIZE(limits) != 2) { - PyErr_SetString(PyExc_ValueError, - "expected a tuple of 2 integers"); - goto error; - } - curobj = PyTuple_GET_ITEM(limits, 0); - maxobj = PyTuple_GET_ITEM(limits, 1); -#if !defined(HAVE_LARGEFILE_SUPPORT) - rl_out->rlim_cur = PyLong_AsLong(curobj); - if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) - goto error; - rl_out->rlim_max = PyLong_AsLong(maxobj); - if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred()) - goto error; -#else - /* The limits are probably bigger than a long */ - rl_out->rlim_cur = PyLong_AsLongLong(curobj); - if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) - goto error; - rl_out->rlim_max = PyLong_AsLongLong(maxobj); - if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred()) - goto error; -#endif - - Py_DECREF(limits); - rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY; - rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY; - return 0; - -error: - Py_DECREF(limits); - return -1; -} - -static PyObject* -rlimit2py(struct rlimit rl) -{ - if (sizeof(rl.rlim_cur) > sizeof(long)) { - return Py_BuildValue("LL", - (long long) rl.rlim_cur, - (long long) rl.rlim_max); - } - return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max); -} - -/*[clinic input] -resource.getrlimit - - resource: int - / - -[clinic start generated code]*/ - -static PyObject * -resource_getrlimit_impl(PyObject *module, int resource) -/*[clinic end generated code: output=98327b25061ffe39 input=a697cb0004cb3c36]*/ -{ - struct rlimit rl; - - if (resource < 0 || resource >= RLIM_NLIMITS) { - PyErr_SetString(PyExc_ValueError, - "invalid resource specified"); - return NULL; - } - - if (getrlimit(resource, &rl) == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return rlimit2py(rl); -} - -/*[clinic input] -resource.setrlimit - - resource: int - limits: object - / - -[clinic start generated code]*/ - -static PyObject * -resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits) -/*[clinic end generated code: output=4e82ec3f34d013d1 input=6235a6ce23b4ca75]*/ -{ - struct rlimit rl; - - if (resource < 0 || resource >= RLIM_NLIMITS) { - PyErr_SetString(PyExc_ValueError, - "invalid resource specified"); - return NULL; - } - + +#include "Python.h" +#include +#include +#include +#include +#include + +/* On some systems, these aren't in any header file. + On others they are, with inconsistent prototypes. + We declare the (default) return type, to shut up gcc -Wall; + but we can't declare the prototype, to avoid errors + when the header files declare it different. + Worse, on some Linuxes, getpagesize() returns a size_t... */ + +#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) + +/*[clinic input] +module resource +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e89d38ed52609d7c]*/ + +/*[python input] +class pid_t_converter(CConverter): + type = 'pid_t' + format_unit = '" _Py_PARSE_PID "' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=0c1d19f640d57e48]*/ + +#include "clinic/resource.c.h" + +PyDoc_STRVAR(struct_rusage__doc__, +"struct_rusage: Result from getrusage.\n\n" +"This object may be accessed either as a tuple of\n" +" (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n" +" nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n" +"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on."); + +static PyStructSequence_Field struct_rusage_fields[] = { + {"ru_utime", "user time used"}, + {"ru_stime", "system time used"}, + {"ru_maxrss", "max. resident set size"}, + {"ru_ixrss", "shared memory size"}, + {"ru_idrss", "unshared data size"}, + {"ru_isrss", "unshared stack size"}, + {"ru_minflt", "page faults not requiring I/O"}, + {"ru_majflt", "page faults requiring I/O"}, + {"ru_nswap", "number of swap outs"}, + {"ru_inblock", "block input operations"}, + {"ru_oublock", "block output operations"}, + {"ru_msgsnd", "IPC messages sent"}, + {"ru_msgrcv", "IPC messages received"}, + {"ru_nsignals", "signals received"}, + {"ru_nvcsw", "voluntary context switches"}, + {"ru_nivcsw", "involuntary context switches"}, + {0} +}; + +static PyStructSequence_Desc struct_rusage_desc = { + "resource.struct_rusage", /* name */ + struct_rusage__doc__, /* doc */ + struct_rusage_fields, /* fields */ + 16 /* n_in_sequence */ +}; + +static int initialized; +static PyTypeObject StructRUsageType; + +/*[clinic input] +resource.getrusage + + who: int + / + +[clinic start generated code]*/ + +static PyObject * +resource_getrusage_impl(PyObject *module, int who) +/*[clinic end generated code: output=8fad2880ba6a9843 input=5c857bcc5b9ccb1b]*/ +{ + struct rusage ru; + PyObject *result; + + if (getrusage(who, &ru) == -1) { + if (errno == EINVAL) { + PyErr_SetString(PyExc_ValueError, + "invalid who parameter"); + return NULL; + } + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + result = PyStructSequence_New(&StructRUsageType); + if (!result) + return NULL; + + PyStructSequence_SET_ITEM(result, 0, + PyFloat_FromDouble(doubletime(ru.ru_utime))); + PyStructSequence_SET_ITEM(result, 1, + PyFloat_FromDouble(doubletime(ru.ru_stime))); + PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(ru.ru_maxrss)); + PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(ru.ru_ixrss)); + PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(ru.ru_idrss)); + PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(ru.ru_isrss)); + PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(ru.ru_minflt)); + PyStructSequence_SET_ITEM(result, 7, PyLong_FromLong(ru.ru_majflt)); + PyStructSequence_SET_ITEM(result, 8, PyLong_FromLong(ru.ru_nswap)); + PyStructSequence_SET_ITEM(result, 9, PyLong_FromLong(ru.ru_inblock)); + PyStructSequence_SET_ITEM(result, 10, PyLong_FromLong(ru.ru_oublock)); + PyStructSequence_SET_ITEM(result, 11, PyLong_FromLong(ru.ru_msgsnd)); + PyStructSequence_SET_ITEM(result, 12, PyLong_FromLong(ru.ru_msgrcv)); + PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(ru.ru_nsignals)); + PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw)); + PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw)); + + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +static int +py2rlimit(PyObject *limits, struct rlimit *rl_out) +{ + PyObject *curobj, *maxobj; + limits = PySequence_Tuple(limits); + if (!limits) + /* Here limits is a borrowed reference */ + return -1; + + if (PyTuple_GET_SIZE(limits) != 2) { + PyErr_SetString(PyExc_ValueError, + "expected a tuple of 2 integers"); + goto error; + } + curobj = PyTuple_GET_ITEM(limits, 0); + maxobj = PyTuple_GET_ITEM(limits, 1); +#if !defined(HAVE_LARGEFILE_SUPPORT) + rl_out->rlim_cur = PyLong_AsLong(curobj); + if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) + goto error; + rl_out->rlim_max = PyLong_AsLong(maxobj); + if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred()) + goto error; +#else + /* The limits are probably bigger than a long */ + rl_out->rlim_cur = PyLong_AsLongLong(curobj); + if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) + goto error; + rl_out->rlim_max = PyLong_AsLongLong(maxobj); + if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred()) + goto error; +#endif + + Py_DECREF(limits); + rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY; + rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY; + return 0; + +error: + Py_DECREF(limits); + return -1; +} + +static PyObject* +rlimit2py(struct rlimit rl) +{ + if (sizeof(rl.rlim_cur) > sizeof(long)) { + return Py_BuildValue("LL", + (long long) rl.rlim_cur, + (long long) rl.rlim_max); + } + return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max); +} + +/*[clinic input] +resource.getrlimit + + resource: int + / + +[clinic start generated code]*/ + +static PyObject * +resource_getrlimit_impl(PyObject *module, int resource) +/*[clinic end generated code: output=98327b25061ffe39 input=a697cb0004cb3c36]*/ +{ + struct rlimit rl; + + if (resource < 0 || resource >= RLIM_NLIMITS) { + PyErr_SetString(PyExc_ValueError, + "invalid resource specified"); + return NULL; + } + + if (getrlimit(resource, &rl) == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return rlimit2py(rl); +} + +/*[clinic input] +resource.setrlimit + + resource: int + limits: object + / + +[clinic start generated code]*/ + +static PyObject * +resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits) +/*[clinic end generated code: output=4e82ec3f34d013d1 input=6235a6ce23b4ca75]*/ +{ + struct rlimit rl; + + if (resource < 0 || resource >= RLIM_NLIMITS) { + PyErr_SetString(PyExc_ValueError, + "invalid resource specified"); + return NULL; + } + if (PySys_Audit("resource.setrlimit", "iO", resource, limits ? limits : Py_None) < 0) { return NULL; } - if (py2rlimit(limits, &rl) < 0) { - return NULL; - } - - if (setrlimit(resource, &rl) == -1) { - if (errno == EINVAL) - PyErr_SetString(PyExc_ValueError, - "current limit exceeds maximum limit"); - else if (errno == EPERM) - PyErr_SetString(PyExc_ValueError, - "not allowed to raise maximum limit"); - else - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_RETURN_NONE; -} - -#ifdef HAVE_PRLIMIT -/*[clinic input] -resource.prlimit - - pid: pid_t - resource: int - [ - limits: object - ] - / - -[clinic start generated code]*/ - -static PyObject * -resource_prlimit_impl(PyObject *module, pid_t pid, int resource, - int group_right_1, PyObject *limits) -/*[clinic end generated code: output=ee976b393187a7a3 input=b77743bdccc83564]*/ -{ - struct rlimit old_limit, new_limit; - int retval; - - if (resource < 0 || resource >= RLIM_NLIMITS) { - PyErr_SetString(PyExc_ValueError, - "invalid resource specified"); - return NULL; - } - + if (py2rlimit(limits, &rl) < 0) { + return NULL; + } + + if (setrlimit(resource, &rl) == -1) { + if (errno == EINVAL) + PyErr_SetString(PyExc_ValueError, + "current limit exceeds maximum limit"); + else if (errno == EPERM) + PyErr_SetString(PyExc_ValueError, + "not allowed to raise maximum limit"); + else + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} + +#ifdef HAVE_PRLIMIT +/*[clinic input] +resource.prlimit + + pid: pid_t + resource: int + [ + limits: object + ] + / + +[clinic start generated code]*/ + +static PyObject * +resource_prlimit_impl(PyObject *module, pid_t pid, int resource, + int group_right_1, PyObject *limits) +/*[clinic end generated code: output=ee976b393187a7a3 input=b77743bdccc83564]*/ +{ + struct rlimit old_limit, new_limit; + int retval; + + if (resource < 0 || resource >= RLIM_NLIMITS) { + PyErr_SetString(PyExc_ValueError, + "invalid resource specified"); + return NULL; + } + if (PySys_Audit("resource.prlimit", "iiO", pid, resource, limits ? limits : Py_None) < 0) { return NULL; } - if (group_right_1) { - if (py2rlimit(limits, &new_limit) < 0) { - return NULL; - } - retval = prlimit(pid, resource, &new_limit, &old_limit); - } - else { - retval = prlimit(pid, resource, NULL, &old_limit); - } - - if (retval == -1) { - if (errno == EINVAL) { - PyErr_SetString(PyExc_ValueError, - "current limit exceeds maximum limit"); - } else { - PyErr_SetFromErrno(PyExc_OSError); - } - return NULL; - } - return rlimit2py(old_limit); -} -#endif /* HAVE_PRLIMIT */ - -/*[clinic input] -resource.getpagesize -> int -[clinic start generated code]*/ - -static int -resource_getpagesize_impl(PyObject *module) -/*[clinic end generated code: output=9ba93eb0f3d6c3a9 input=546545e8c1f42085]*/ -{ - long pagesize = 0; -#if defined(HAVE_GETPAGESIZE) - pagesize = getpagesize(); -#elif defined(HAVE_SYSCONF) -#if defined(_SC_PAGE_SIZE) - pagesize = sysconf(_SC_PAGE_SIZE); -#else - /* Irix 5.3 has _SC_PAGESIZE, but not _SC_PAGE_SIZE */ - pagesize = sysconf(_SC_PAGESIZE); -#endif -#endif - return pagesize; -} - -/* List of functions */ - -static struct PyMethodDef -resource_methods[] = { - RESOURCE_GETRUSAGE_METHODDEF - RESOURCE_GETRLIMIT_METHODDEF - RESOURCE_PRLIMIT_METHODDEF - RESOURCE_SETRLIMIT_METHODDEF - RESOURCE_GETPAGESIZE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - - -/* Module initialization */ - - + if (group_right_1) { + if (py2rlimit(limits, &new_limit) < 0) { + return NULL; + } + retval = prlimit(pid, resource, &new_limit, &old_limit); + } + else { + retval = prlimit(pid, resource, NULL, &old_limit); + } + + if (retval == -1) { + if (errno == EINVAL) { + PyErr_SetString(PyExc_ValueError, + "current limit exceeds maximum limit"); + } else { + PyErr_SetFromErrno(PyExc_OSError); + } + return NULL; + } + return rlimit2py(old_limit); +} +#endif /* HAVE_PRLIMIT */ + +/*[clinic input] +resource.getpagesize -> int +[clinic start generated code]*/ + +static int +resource_getpagesize_impl(PyObject *module) +/*[clinic end generated code: output=9ba93eb0f3d6c3a9 input=546545e8c1f42085]*/ +{ + long pagesize = 0; +#if defined(HAVE_GETPAGESIZE) + pagesize = getpagesize(); +#elif defined(HAVE_SYSCONF) +#if defined(_SC_PAGE_SIZE) + pagesize = sysconf(_SC_PAGE_SIZE); +#else + /* Irix 5.3 has _SC_PAGESIZE, but not _SC_PAGE_SIZE */ + pagesize = sysconf(_SC_PAGESIZE); +#endif +#endif + return pagesize; +} + +/* List of functions */ + +static struct PyMethodDef +resource_methods[] = { + RESOURCE_GETRUSAGE_METHODDEF + RESOURCE_GETRLIMIT_METHODDEF + RESOURCE_PRLIMIT_METHODDEF + RESOURCE_SETRLIMIT_METHODDEF + RESOURCE_GETPAGESIZE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + + +/* Module initialization */ + + static int resource_exec(PyObject *module) -{ +{ #define ADD_INT(module, value) \ do { \ if (PyModule_AddIntConstant(module, #value, value) < 0) { \ return -1; \ } \ } while (0) - - /* Add some symbolic constants to the module */ - Py_INCREF(PyExc_OSError); + + /* Add some symbolic constants to the module */ + Py_INCREF(PyExc_OSError); if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) { Py_DECREF(PyExc_OSError); return -1; } - if (!initialized) { - if (PyStructSequence_InitType2(&StructRUsageType, - &struct_rusage_desc) < 0) + if (!initialized) { + if (PyStructSequence_InitType2(&StructRUsageType, + &struct_rusage_desc) < 0) return -1; - } - + } + if(PyModule_AddType(module, &StructRUsageType) < 0) { return -1; } - - /* insert constants */ -#ifdef RLIMIT_CPU + + /* insert constants */ +#ifdef RLIMIT_CPU ADD_INT(module, RLIMIT_CPU); -#endif - -#ifdef RLIMIT_FSIZE +#endif + +#ifdef RLIMIT_FSIZE ADD_INT(module, RLIMIT_FSIZE); -#endif - -#ifdef RLIMIT_DATA +#endif + +#ifdef RLIMIT_DATA ADD_INT(module, RLIMIT_DATA); -#endif - -#ifdef RLIMIT_STACK +#endif + +#ifdef RLIMIT_STACK ADD_INT(module, RLIMIT_STACK); -#endif - -#ifdef RLIMIT_CORE +#endif + +#ifdef RLIMIT_CORE ADD_INT(module, RLIMIT_CORE); -#endif - -#ifdef RLIMIT_NOFILE +#endif + +#ifdef RLIMIT_NOFILE ADD_INT(module, RLIMIT_NOFILE); -#endif - -#ifdef RLIMIT_OFILE +#endif + +#ifdef RLIMIT_OFILE ADD_INT(module, RLIMIT_OFILE); -#endif - -#ifdef RLIMIT_VMEM +#endif + +#ifdef RLIMIT_VMEM ADD_INT(module, RLIMIT_VMEM); -#endif - -#ifdef RLIMIT_AS +#endif + +#ifdef RLIMIT_AS ADD_INT(module, RLIMIT_AS); -#endif - -#ifdef RLIMIT_RSS +#endif + +#ifdef RLIMIT_RSS ADD_INT(module, RLIMIT_RSS); -#endif - -#ifdef RLIMIT_NPROC +#endif + +#ifdef RLIMIT_NPROC ADD_INT(module, RLIMIT_NPROC); -#endif - -#ifdef RLIMIT_MEMLOCK +#endif + +#ifdef RLIMIT_MEMLOCK ADD_INT(module, RLIMIT_MEMLOCK); -#endif - -#ifdef RLIMIT_SBSIZE +#endif + +#ifdef RLIMIT_SBSIZE ADD_INT(module, RLIMIT_SBSIZE); -#endif - -/* Linux specific */ -#ifdef RLIMIT_MSGQUEUE +#endif + +/* Linux specific */ +#ifdef RLIMIT_MSGQUEUE ADD_INT(module, RLIMIT_MSGQUEUE); -#endif - -#ifdef RLIMIT_NICE +#endif + +#ifdef RLIMIT_NICE ADD_INT(module, RLIMIT_NICE); -#endif - -#ifdef RLIMIT_RTPRIO +#endif + +#ifdef RLIMIT_RTPRIO ADD_INT(module, RLIMIT_RTPRIO); -#endif - -#ifdef RLIMIT_RTTIME +#endif + +#ifdef RLIMIT_RTTIME ADD_INT(module, RLIMIT_RTTIME); -#endif - -#ifdef RLIMIT_SIGPENDING +#endif + +#ifdef RLIMIT_SIGPENDING ADD_INT(module, RLIMIT_SIGPENDING); -#endif - -/* target */ -#ifdef RUSAGE_SELF +#endif + +/* target */ +#ifdef RUSAGE_SELF ADD_INT(module, RUSAGE_SELF); -#endif - -#ifdef RUSAGE_CHILDREN +#endif + +#ifdef RUSAGE_CHILDREN ADD_INT(module, RUSAGE_CHILDREN); -#endif - -#ifdef RUSAGE_BOTH +#endif + +#ifdef RUSAGE_BOTH ADD_INT(module, RUSAGE_BOTH); -#endif - -#ifdef RUSAGE_THREAD +#endif + +#ifdef RUSAGE_THREAD ADD_INT(module, RUSAGE_THREAD); -#endif - -/* FreeBSD specific */ - -#ifdef RLIMIT_SWAP +#endif + +/* FreeBSD specific */ + +#ifdef RLIMIT_SWAP ADD_INT(module, RLIMIT_SWAP); -#endif - -#ifdef RLIMIT_SBSIZE +#endif + +#ifdef RLIMIT_SBSIZE ADD_INT(module, RLIMIT_SBSIZE); -#endif - -#ifdef RLIMIT_NPTS +#endif + +#ifdef RLIMIT_NPTS ADD_INT(module, RLIMIT_NPTS); -#endif - +#endif + PyObject *v; - if (sizeof(RLIM_INFINITY) > sizeof(long)) { - v = PyLong_FromLongLong((long long) RLIM_INFINITY); - } else - { - v = PyLong_FromLong((long) RLIM_INFINITY); - } + if (sizeof(RLIM_INFINITY) > sizeof(long)) { + v = PyLong_FromLongLong((long long) RLIM_INFINITY); + } else + { + v = PyLong_FromLong((long) RLIM_INFINITY); + } if (!v) { return -1; - } + } if (PyModule_AddObject(module, "RLIM_INFINITY", v) < 0) { Py_DECREF(v); return -1; } - initialized = 1; + initialized = 1; return 0; #undef ADD_INT -} +} static struct PyModuleDef_Slot resource_slots[] = { {Py_mod_exec, resource_exec}, diff --git a/contrib/tools/python3/src/Modules/rotatingtree.c b/contrib/tools/python3/src/Modules/rotatingtree.c index 07e08bc3167..6d31a2ec90e 100644 --- a/contrib/tools/python3/src/Modules/rotatingtree.c +++ b/contrib/tools/python3/src/Modules/rotatingtree.c @@ -1,121 +1,121 @@ -#include "rotatingtree.h" - -#define KEY_LOWER_THAN(key1, key2) ((char*)(key1) < (char*)(key2)) - -/* The randombits() function below is a fast-and-dirty generator that - * is probably irregular enough for our purposes. Note that it's biased: - * I think that ones are slightly more probable than zeroes. It's not - * important here, though. - */ - -static unsigned int random_value = 1; -static unsigned int random_stream = 0; - -static int -randombits(int bits) -{ - int result; - if (random_stream < (1U << bits)) { - random_value *= 1082527; - random_stream = random_value; - } - result = random_stream & ((1<>= bits; - return result; -} - - -/* Insert a new node into the tree. - (*root) is modified to point to the new root. */ -void -RotatingTree_Add(rotating_node_t **root, rotating_node_t *node) -{ - while (*root != NULL) { - if (KEY_LOWER_THAN(node->key, (*root)->key)) - root = &((*root)->left); - else - root = &((*root)->right); - } - node->left = NULL; - node->right = NULL; - *root = node; -} - -/* Locate the node with the given key. This is the most complicated - function because it occasionally rebalances the tree to move the - resulting node closer to the root. */ -rotating_node_t * -RotatingTree_Get(rotating_node_t **root, void *key) -{ - if (randombits(3) != 4) { - /* Fast path, no rebalancing */ - rotating_node_t *node = *root; - while (node != NULL) { - if (node->key == key) - return node; - if (KEY_LOWER_THAN(key, node->key)) - node = node->left; - else - node = node->right; - } - return NULL; - } - else { - rotating_node_t **pnode = root; - rotating_node_t *node = *pnode; - rotating_node_t *next; - int rotate; - if (node == NULL) - return NULL; - while (1) { - if (node->key == key) - return node; - rotate = !randombits(1); - if (KEY_LOWER_THAN(key, node->key)) { - next = node->left; - if (next == NULL) - return NULL; - if (rotate) { - node->left = next->right; - next->right = node; - *pnode = next; - } - else - pnode = &(node->left); - } - else { - next = node->right; - if (next == NULL) - return NULL; - if (rotate) { - node->right = next->left; - next->left = node; - *pnode = next; - } - else - pnode = &(node->right); - } - node = next; - } - } -} - -/* Enumerate all nodes in the tree. The callback enumfn() should return - zero to continue the enumeration, or non-zero to interrupt it. - A non-zero value is directly returned by RotatingTree_Enum(). */ -int -RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn, - void *arg) -{ - int result; - rotating_node_t *node; - while (root != NULL) { - result = RotatingTree_Enum(root->left, enumfn, arg); - if (result != 0) return result; - node = root->right; - result = enumfn(root, arg); - if (result != 0) return result; - root = node; - } - return 0; -} +#include "rotatingtree.h" + +#define KEY_LOWER_THAN(key1, key2) ((char*)(key1) < (char*)(key2)) + +/* The randombits() function below is a fast-and-dirty generator that + * is probably irregular enough for our purposes. Note that it's biased: + * I think that ones are slightly more probable than zeroes. It's not + * important here, though. + */ + +static unsigned int random_value = 1; +static unsigned int random_stream = 0; + +static int +randombits(int bits) +{ + int result; + if (random_stream < (1U << bits)) { + random_value *= 1082527; + random_stream = random_value; + } + result = random_stream & ((1<>= bits; + return result; +} + + +/* Insert a new node into the tree. + (*root) is modified to point to the new root. */ +void +RotatingTree_Add(rotating_node_t **root, rotating_node_t *node) +{ + while (*root != NULL) { + if (KEY_LOWER_THAN(node->key, (*root)->key)) + root = &((*root)->left); + else + root = &((*root)->right); + } + node->left = NULL; + node->right = NULL; + *root = node; +} + +/* Locate the node with the given key. This is the most complicated + function because it occasionally rebalances the tree to move the + resulting node closer to the root. */ +rotating_node_t * +RotatingTree_Get(rotating_node_t **root, void *key) +{ + if (randombits(3) != 4) { + /* Fast path, no rebalancing */ + rotating_node_t *node = *root; + while (node != NULL) { + if (node->key == key) + return node; + if (KEY_LOWER_THAN(key, node->key)) + node = node->left; + else + node = node->right; + } + return NULL; + } + else { + rotating_node_t **pnode = root; + rotating_node_t *node = *pnode; + rotating_node_t *next; + int rotate; + if (node == NULL) + return NULL; + while (1) { + if (node->key == key) + return node; + rotate = !randombits(1); + if (KEY_LOWER_THAN(key, node->key)) { + next = node->left; + if (next == NULL) + return NULL; + if (rotate) { + node->left = next->right; + next->right = node; + *pnode = next; + } + else + pnode = &(node->left); + } + else { + next = node->right; + if (next == NULL) + return NULL; + if (rotate) { + node->right = next->left; + next->left = node; + *pnode = next; + } + else + pnode = &(node->right); + } + node = next; + } + } +} + +/* Enumerate all nodes in the tree. The callback enumfn() should return + zero to continue the enumeration, or non-zero to interrupt it. + A non-zero value is directly returned by RotatingTree_Enum(). */ +int +RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn, + void *arg) +{ + int result; + rotating_node_t *node; + while (root != NULL) { + result = RotatingTree_Enum(root->left, enumfn, arg); + if (result != 0) return result; + node = root->right; + result = enumfn(root, arg); + if (result != 0) return result; + root = node; + } + return 0; +} diff --git a/contrib/tools/python3/src/Modules/rotatingtree.h b/contrib/tools/python3/src/Modules/rotatingtree.h index 7b3e5fde921..ea9a4206bcb 100644 --- a/contrib/tools/python3/src/Modules/rotatingtree.h +++ b/contrib/tools/python3/src/Modules/rotatingtree.h @@ -1,27 +1,27 @@ -/* "Rotating trees" (Armin Rigo) - * - * Google "splay trees" for the general idea. - * - * It's a dict-like data structure that works best when accesses are not - * random, but follow a strong pattern. The one implemented here is for - * access patterns where the same small set of keys is looked up over - * and over again, and this set of keys evolves slowly over time. - */ - -#include - -#define EMPTY_ROTATING_TREE ((rotating_node_t *)NULL) - -typedef struct rotating_node_s rotating_node_t; -typedef int (*rotating_tree_enum_fn) (rotating_node_t *node, void *arg); - -struct rotating_node_s { - void *key; - rotating_node_t *left; - rotating_node_t *right; -}; - -void RotatingTree_Add(rotating_node_t **root, rotating_node_t *node); -rotating_node_t* RotatingTree_Get(rotating_node_t **root, void *key); -int RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn, - void *arg); +/* "Rotating trees" (Armin Rigo) + * + * Google "splay trees" for the general idea. + * + * It's a dict-like data structure that works best when accesses are not + * random, but follow a strong pattern. The one implemented here is for + * access patterns where the same small set of keys is looked up over + * and over again, and this set of keys evolves slowly over time. + */ + +#include + +#define EMPTY_ROTATING_TREE ((rotating_node_t *)NULL) + +typedef struct rotating_node_s rotating_node_t; +typedef int (*rotating_tree_enum_fn) (rotating_node_t *node, void *arg); + +struct rotating_node_s { + void *key; + rotating_node_t *left; + rotating_node_t *right; +}; + +void RotatingTree_Add(rotating_node_t **root, rotating_node_t *node); +rotating_node_t* RotatingTree_Get(rotating_node_t **root, void *key); +int RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn, + void *arg); diff --git a/contrib/tools/python3/src/Modules/selectmodule.c b/contrib/tools/python3/src/Modules/selectmodule.c index fb71e9196f3..f79d6b55527 100644 --- a/contrib/tools/python3/src/Modules/selectmodule.c +++ b/contrib/tools/python3/src/Modules/selectmodule.c @@ -1,63 +1,63 @@ -/* select - Module containing unix select(2) call. - Under Unix, the file descriptors are small integers. - Under Win32, select only exists for sockets, and sockets may - have any value except INVALID_SOCKET. -*/ - -#if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE) -#define _GNU_SOURCE -#endif - -#include "Python.h" +/* select - Module containing unix select(2) call. + Under Unix, the file descriptors are small integers. + Under Win32, select only exists for sockets, and sockets may + have any value except INVALID_SOCKET. +*/ + +#if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + +#include "Python.h" #include "structmember.h" // PyMemberDef - -#ifdef HAVE_SYS_DEVPOLL_H -#include -#include -#include -#include -#include -#endif - -#ifdef __APPLE__ - /* Perform runtime testing for a broken poll on OSX to make it easier - * to use the same binary on multiple releases of the OS. - */ -#undef HAVE_BROKEN_POLL -#endif - -/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined. - 64 is too small (too many people have bumped into that limit). - Here we boost it. - Users who want even more than the boosted limit should #define - FD_SETSIZE higher before this; e.g., via compiler /D switch. -*/ -#if defined(MS_WINDOWS) && !defined(FD_SETSIZE) -#define FD_SETSIZE 512 -#endif - -#if defined(HAVE_POLL_H) -#include -#elif defined(HAVE_SYS_POLL_H) -#include -#endif - -#ifdef __sgi -/* This is missing from unistd.h */ -extern void bzero(void *, int); -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef MS_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include -#else -# define SOCKET int -#endif - + +#ifdef HAVE_SYS_DEVPOLL_H +#include +#include +#include +#include +#include +#endif + +#ifdef __APPLE__ + /* Perform runtime testing for a broken poll on OSX to make it easier + * to use the same binary on multiple releases of the OS. + */ +#undef HAVE_BROKEN_POLL +#endif + +/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined. + 64 is too small (too many people have bumped into that limit). + Here we boost it. + Users who want even more than the boosted limit should #define + FD_SETSIZE higher before this; e.g., via compiler /D switch. +*/ +#if defined(MS_WINDOWS) && !defined(FD_SETSIZE) +#define FD_SETSIZE 512 +#endif + +#if defined(HAVE_POLL_H) +#include +#elif defined(HAVE_SYS_POLL_H) +#include +#endif + +#ifdef __sgi +/* This is missing from unistd.h */ +extern void bzero(void *, int); +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef MS_WINDOWS +# define WIN32_LEAN_AND_MEAN +# include +#else +# define SOCKET int +#endif + typedef struct { PyObject *close; PyTypeObject *poll_Type; @@ -107,127 +107,127 @@ class fildes_converter(CConverter): [python start generated code]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=ca54eb5aa476e20a]*/ -/* list of Python objects and their file descriptor */ -typedef struct { - PyObject *obj; /* owned reference */ - SOCKET fd; - int sentinel; /* -1 == sentinel */ -} pylist; - -static void -reap_obj(pylist fd2obj[FD_SETSIZE + 1]) -{ - unsigned int i; - for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) { - Py_CLEAR(fd2obj[i].obj); - } - fd2obj[0].sentinel = -1; -} - - -/* returns -1 and sets the Python exception if an error occurred, otherwise - returns a number >= 0 -*/ -static int -seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) -{ - int max = -1; - unsigned int index = 0; - Py_ssize_t i; - PyObject* fast_seq = NULL; - PyObject* o = NULL; - - fd2obj[0].obj = (PyObject*)0; /* set list to zero size */ - FD_ZERO(set); - - fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences"); - if (!fast_seq) - return -1; - - for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) { - SOCKET v; - - /* any intervening fileno() calls could decr this refcnt */ - if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i))) - goto finally; - - Py_INCREF(o); - v = PyObject_AsFileDescriptor( o ); - if (v == -1) goto finally; - -#if defined(_MSC_VER) - max = 0; /* not used for Win32 */ -#else /* !_MSC_VER */ - if (!_PyIsSelectable_fd(v)) { - PyErr_SetString(PyExc_ValueError, - "filedescriptor out of range in select()"); - goto finally; - } - if (v > max) - max = v; -#endif /* _MSC_VER */ - FD_SET(v, set); - - /* add object and its file descriptor to the list */ - if (index >= (unsigned int)FD_SETSIZE) { - PyErr_SetString(PyExc_ValueError, - "too many file descriptors in select()"); - goto finally; - } - fd2obj[index].obj = o; - fd2obj[index].fd = v; - fd2obj[index].sentinel = 0; - fd2obj[++index].sentinel = -1; - } - Py_DECREF(fast_seq); - return max+1; - - finally: - Py_XDECREF(o); - Py_DECREF(fast_seq); - return -1; -} - -/* returns NULL and sets the Python exception if an error occurred */ -static PyObject * -set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) -{ - int i, j, count=0; - PyObject *list, *o; - SOCKET fd; - - for (j = 0; fd2obj[j].sentinel >= 0; j++) { - if (FD_ISSET(fd2obj[j].fd, set)) - count++; - } - list = PyList_New(count); - if (!list) - return NULL; - - i = 0; - for (j = 0; fd2obj[j].sentinel >= 0; j++) { - fd = fd2obj[j].fd; - if (FD_ISSET(fd, set)) { - o = fd2obj[j].obj; - fd2obj[j].obj = NULL; - /* transfer ownership */ - if (PyList_SetItem(list, i, o) < 0) - goto finally; - - i++; - } - } - return list; - finally: - Py_DECREF(list); - return NULL; -} - -#undef SELECT_USES_HEAP -#if FD_SETSIZE > 1024 -#define SELECT_USES_HEAP -#endif /* FD_SETSIZE > 1024 */ - +/* list of Python objects and their file descriptor */ +typedef struct { + PyObject *obj; /* owned reference */ + SOCKET fd; + int sentinel; /* -1 == sentinel */ +} pylist; + +static void +reap_obj(pylist fd2obj[FD_SETSIZE + 1]) +{ + unsigned int i; + for (i = 0; i < (unsigned int)FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) { + Py_CLEAR(fd2obj[i].obj); + } + fd2obj[0].sentinel = -1; +} + + +/* returns -1 and sets the Python exception if an error occurred, otherwise + returns a number >= 0 +*/ +static int +seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) +{ + int max = -1; + unsigned int index = 0; + Py_ssize_t i; + PyObject* fast_seq = NULL; + PyObject* o = NULL; + + fd2obj[0].obj = (PyObject*)0; /* set list to zero size */ + FD_ZERO(set); + + fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences"); + if (!fast_seq) + return -1; + + for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) { + SOCKET v; + + /* any intervening fileno() calls could decr this refcnt */ + if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i))) + goto finally; + + Py_INCREF(o); + v = PyObject_AsFileDescriptor( o ); + if (v == -1) goto finally; + +#if defined(_MSC_VER) + max = 0; /* not used for Win32 */ +#else /* !_MSC_VER */ + if (!_PyIsSelectable_fd(v)) { + PyErr_SetString(PyExc_ValueError, + "filedescriptor out of range in select()"); + goto finally; + } + if (v > max) + max = v; +#endif /* _MSC_VER */ + FD_SET(v, set); + + /* add object and its file descriptor to the list */ + if (index >= (unsigned int)FD_SETSIZE) { + PyErr_SetString(PyExc_ValueError, + "too many file descriptors in select()"); + goto finally; + } + fd2obj[index].obj = o; + fd2obj[index].fd = v; + fd2obj[index].sentinel = 0; + fd2obj[++index].sentinel = -1; + } + Py_DECREF(fast_seq); + return max+1; + + finally: + Py_XDECREF(o); + Py_DECREF(fast_seq); + return -1; +} + +/* returns NULL and sets the Python exception if an error occurred */ +static PyObject * +set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) +{ + int i, j, count=0; + PyObject *list, *o; + SOCKET fd; + + for (j = 0; fd2obj[j].sentinel >= 0; j++) { + if (FD_ISSET(fd2obj[j].fd, set)) + count++; + } + list = PyList_New(count); + if (!list) + return NULL; + + i = 0; + for (j = 0; fd2obj[j].sentinel >= 0; j++) { + fd = fd2obj[j].fd; + if (FD_ISSET(fd, set)) { + o = fd2obj[j].obj; + fd2obj[j].obj = NULL; + /* transfer ownership */ + if (PyList_SetItem(list, i, o) < 0) + goto finally; + + i++; + } + } + return list; + finally: + Py_DECREF(list); + return NULL; +} + +#undef SELECT_USES_HEAP +#if FD_SETSIZE > 1024 +#define SELECT_USES_HEAP +#endif /* FD_SETSIZE > 1024 */ + /*[clinic input] select.select @@ -261,239 +261,239 @@ On Windows, only sockets are supported; on Unix, all file descriptors can be used. [clinic start generated code]*/ -static PyObject * +static PyObject * select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, PyObject *xlist, PyObject *timeout_obj) /*[clinic end generated code: output=2b3cfa824f7ae4cf input=e467f5d68033de00]*/ -{ -#ifdef SELECT_USES_HEAP - pylist *rfd2obj, *wfd2obj, *efd2obj; -#else /* !SELECT_USES_HEAP */ - /* XXX: All this should probably be implemented as follows: - * - find the highest descriptor we're interested in - * - add one - * - that's the size - * See: Stevens, APitUE, $12.5.1 - */ - pylist rfd2obj[FD_SETSIZE + 1]; - pylist wfd2obj[FD_SETSIZE + 1]; - pylist efd2obj[FD_SETSIZE + 1]; -#endif /* SELECT_USES_HEAP */ - PyObject *ret = NULL; - fd_set ifdset, ofdset, efdset; - struct timeval tv, *tvp; - int imax, omax, emax, max; - int n; - _PyTime_t timeout, deadline = 0; - - if (timeout_obj == Py_None) - tvp = (struct timeval *)NULL; - else { - if (_PyTime_FromSecondsObject(&timeout, timeout_obj, - _PyTime_ROUND_TIMEOUT) < 0) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_SetString(PyExc_TypeError, - "timeout must be a float or None"); - } - return NULL; - } - - if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1) - return NULL; - if (tv.tv_sec < 0) { - PyErr_SetString(PyExc_ValueError, "timeout must be non-negative"); - return NULL; - } - tvp = &tv; - } - -#ifdef SELECT_USES_HEAP - /* Allocate memory for the lists */ - rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); - wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); - efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); - if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) { - if (rfd2obj) PyMem_DEL(rfd2obj); - if (wfd2obj) PyMem_DEL(wfd2obj); - if (efd2obj) PyMem_DEL(efd2obj); - return PyErr_NoMemory(); - } -#endif /* SELECT_USES_HEAP */ - +{ +#ifdef SELECT_USES_HEAP + pylist *rfd2obj, *wfd2obj, *efd2obj; +#else /* !SELECT_USES_HEAP */ + /* XXX: All this should probably be implemented as follows: + * - find the highest descriptor we're interested in + * - add one + * - that's the size + * See: Stevens, APitUE, $12.5.1 + */ + pylist rfd2obj[FD_SETSIZE + 1]; + pylist wfd2obj[FD_SETSIZE + 1]; + pylist efd2obj[FD_SETSIZE + 1]; +#endif /* SELECT_USES_HEAP */ + PyObject *ret = NULL; + fd_set ifdset, ofdset, efdset; + struct timeval tv, *tvp; + int imax, omax, emax, max; + int n; + _PyTime_t timeout, deadline = 0; + + if (timeout_obj == Py_None) + tvp = (struct timeval *)NULL; + else { + if (_PyTime_FromSecondsObject(&timeout, timeout_obj, + _PyTime_ROUND_TIMEOUT) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "timeout must be a float or None"); + } + return NULL; + } + + if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1) + return NULL; + if (tv.tv_sec < 0) { + PyErr_SetString(PyExc_ValueError, "timeout must be non-negative"); + return NULL; + } + tvp = &tv; + } + +#ifdef SELECT_USES_HEAP + /* Allocate memory for the lists */ + rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); + wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); + efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); + if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) { + if (rfd2obj) PyMem_DEL(rfd2obj); + if (wfd2obj) PyMem_DEL(wfd2obj); + if (efd2obj) PyMem_DEL(efd2obj); + return PyErr_NoMemory(); + } +#endif /* SELECT_USES_HEAP */ + /* Convert iterables to fd_sets, and get maximum fd number - * propagates the Python exception set in seq2set() - */ - rfd2obj[0].sentinel = -1; - wfd2obj[0].sentinel = -1; - efd2obj[0].sentinel = -1; + * propagates the Python exception set in seq2set() + */ + rfd2obj[0].sentinel = -1; + wfd2obj[0].sentinel = -1; + efd2obj[0].sentinel = -1; if ((imax = seq2set(rlist, &ifdset, rfd2obj)) < 0) - goto finally; + goto finally; if ((omax = seq2set(wlist, &ofdset, wfd2obj)) < 0) - goto finally; + goto finally; if ((emax = seq2set(xlist, &efdset, efd2obj)) < 0) - goto finally; - - max = imax; - if (omax > max) max = omax; - if (emax > max) max = emax; - - if (tvp) - deadline = _PyTime_GetMonotonicClock() + timeout; - - do { - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = select(max, &ifdset, &ofdset, &efdset, tvp); - Py_END_ALLOW_THREADS - - if (errno != EINTR) - break; - - /* select() was interrupted by a signal */ - if (PyErr_CheckSignals()) - goto finally; - - if (tvp) { - timeout = deadline - _PyTime_GetMonotonicClock(); - if (timeout < 0) { - /* bpo-35310: lists were unmodified -- clear them explicitly */ - FD_ZERO(&ifdset); - FD_ZERO(&ofdset); - FD_ZERO(&efdset); - n = 0; - break; - } - _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING); - /* retry select() with the recomputed timeout */ - } - } while (1); - -#ifdef MS_WINDOWS - if (n == SOCKET_ERROR) { - PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); - } -#else - if (n < 0) { - PyErr_SetFromErrno(PyExc_OSError); - } -#endif - else { - /* any of these three calls can raise an exception. it's more - convenient to test for this after all three calls... but - is that acceptable? - */ + goto finally; + + max = imax; + if (omax > max) max = omax; + if (emax > max) max = emax; + + if (tvp) + deadline = _PyTime_GetMonotonicClock() + timeout; + + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; + n = select(max, &ifdset, &ofdset, &efdset, tvp); + Py_END_ALLOW_THREADS + + if (errno != EINTR) + break; + + /* select() was interrupted by a signal */ + if (PyErr_CheckSignals()) + goto finally; + + if (tvp) { + timeout = deadline - _PyTime_GetMonotonicClock(); + if (timeout < 0) { + /* bpo-35310: lists were unmodified -- clear them explicitly */ + FD_ZERO(&ifdset); + FD_ZERO(&ofdset); + FD_ZERO(&efdset); + n = 0; + break; + } + _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING); + /* retry select() with the recomputed timeout */ + } + } while (1); + +#ifdef MS_WINDOWS + if (n == SOCKET_ERROR) { + PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + } +#else + if (n < 0) { + PyErr_SetFromErrno(PyExc_OSError); + } +#endif + else { + /* any of these three calls can raise an exception. it's more + convenient to test for this after all three calls... but + is that acceptable? + */ rlist = set2list(&ifdset, rfd2obj); wlist = set2list(&ofdset, wfd2obj); xlist = set2list(&efdset, efd2obj); - if (PyErr_Occurred()) - ret = NULL; - else + if (PyErr_Occurred()) + ret = NULL; + else ret = PyTuple_Pack(3, rlist, wlist, xlist); - + Py_XDECREF(rlist); Py_XDECREF(wlist); Py_XDECREF(xlist); - } - - finally: - reap_obj(rfd2obj); - reap_obj(wfd2obj); - reap_obj(efd2obj); -#ifdef SELECT_USES_HEAP - PyMem_DEL(rfd2obj); - PyMem_DEL(wfd2obj); - PyMem_DEL(efd2obj); -#endif /* SELECT_USES_HEAP */ - return ret; -} - -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) -/* - * poll() support - */ - -typedef struct { - PyObject_HEAD - PyObject *dict; - int ufd_uptodate; - int ufd_len; - struct pollfd *ufds; - int poll_running; -} pollObject; - -/* Update the malloc'ed array of pollfds to match the dictionary - contained within a pollObject. Return 1 on success, 0 on an error. -*/ - -static int -update_ufd_array(pollObject *self) -{ - Py_ssize_t i, pos; - PyObject *key, *value; - struct pollfd *old_ufds = self->ufds; - - self->ufd_len = PyDict_GET_SIZE(self->dict); - PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len); - if (self->ufds == NULL) { - self->ufds = old_ufds; - PyErr_NoMemory(); - return 0; - } - - i = pos = 0; - while (PyDict_Next(self->dict, &pos, &key, &value)) { - assert(i < self->ufd_len); - /* Never overflow */ - self->ufds[i].fd = (int)PyLong_AsLong(key); - self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value); - i++; - } - assert(i == self->ufd_len); - self->ufd_uptodate = 1; - return 1; -} - + } + + finally: + reap_obj(rfd2obj); + reap_obj(wfd2obj); + reap_obj(efd2obj); +#ifdef SELECT_USES_HEAP + PyMem_DEL(rfd2obj); + PyMem_DEL(wfd2obj); + PyMem_DEL(efd2obj); +#endif /* SELECT_USES_HEAP */ + return ret; +} + +#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) +/* + * poll() support + */ + +typedef struct { + PyObject_HEAD + PyObject *dict; + int ufd_uptodate; + int ufd_len; + struct pollfd *ufds; + int poll_running; +} pollObject; + +/* Update the malloc'ed array of pollfds to match the dictionary + contained within a pollObject. Return 1 on success, 0 on an error. +*/ + +static int +update_ufd_array(pollObject *self) +{ + Py_ssize_t i, pos; + PyObject *key, *value; + struct pollfd *old_ufds = self->ufds; + + self->ufd_len = PyDict_GET_SIZE(self->dict); + PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len); + if (self->ufds == NULL) { + self->ufds = old_ufds; + PyErr_NoMemory(); + return 0; + } + + i = pos = 0; + while (PyDict_Next(self->dict, &pos, &key, &value)) { + assert(i < self->ufd_len); + /* Never overflow */ + self->ufds[i].fd = (int)PyLong_AsLong(key); + self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value); + i++; + } + assert(i == self->ufd_len); + self->ufd_uptodate = 1; + return 1; +} + /*[clinic input] select.poll.register - + fd: fildes either an integer, or an object with a fileno() method returning an int eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = select.POLLIN | select.POLLPRI | select.POLLOUT an optional bitmask describing the type of events to check for / - + Register a file descriptor with the polling object. [clinic start generated code]*/ - -static PyObject * + +static PyObject * select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask) /*[clinic end generated code: output=0dc7173c800a4a65 input=34e16cfb28d3c900]*/ -{ +{ PyObject *key, *value; - int err; - - /* Add entry to the internal dictionary: the key is the - file descriptor, and the value is the event mask. */ - key = PyLong_FromLong(fd); - if (key == NULL) - return NULL; + int err; + + /* Add entry to the internal dictionary: the key is the + file descriptor, and the value is the event mask. */ + key = PyLong_FromLong(fd); + if (key == NULL) + return NULL; value = PyLong_FromLong(eventmask); - if (value == NULL) { - Py_DECREF(key); - return NULL; - } - err = PyDict_SetItem(self->dict, key, value); - Py_DECREF(key); - Py_DECREF(value); - if (err < 0) - return NULL; - - self->ufd_uptodate = 0; - - Py_RETURN_NONE; -} - - + if (value == NULL) { + Py_DECREF(key); + return NULL; + } + err = PyDict_SetItem(self->dict, key, value); + Py_DECREF(key); + Py_DECREF(value); + if (err < 0) + return NULL; + + self->ufd_uptodate = 0; + + Py_RETURN_NONE; +} + + /*[clinic input] select.poll.modify @@ -507,78 +507,78 @@ select.poll.modify Modify an already registered file descriptor. [clinic start generated code]*/ -static PyObject * +static PyObject * select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask) /*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/ -{ +{ PyObject *key, *value; - int err; - - /* Modify registered fd */ - key = PyLong_FromLong(fd); - if (key == NULL) - return NULL; + int err; + + /* Modify registered fd */ + key = PyLong_FromLong(fd); + if (key == NULL) + return NULL; if (PyDict_GetItemWithError(self->dict, key) == NULL) { if (!PyErr_Occurred()) { errno = ENOENT; PyErr_SetFromErrno(PyExc_OSError); } - Py_DECREF(key); - return NULL; - } + Py_DECREF(key); + return NULL; + } value = PyLong_FromLong(eventmask); - if (value == NULL) { - Py_DECREF(key); - return NULL; - } - err = PyDict_SetItem(self->dict, key, value); - Py_DECREF(key); - Py_DECREF(value); - if (err < 0) - return NULL; - - self->ufd_uptodate = 0; - - Py_RETURN_NONE; -} - - + if (value == NULL) { + Py_DECREF(key); + return NULL; + } + err = PyDict_SetItem(self->dict, key, value); + Py_DECREF(key); + Py_DECREF(value); + if (err < 0) + return NULL; + + self->ufd_uptodate = 0; + + Py_RETURN_NONE; +} + + /*[clinic input] select.poll.unregister - + fd: fildes / Remove a file descriptor being tracked by the polling object. [clinic start generated code]*/ -static PyObject * +static PyObject * select_poll_unregister_impl(pollObject *self, int fd) /*[clinic end generated code: output=8c9f42e75e7d291b input=4b4fccc1040e79cb]*/ -{ - PyObject *key; - - /* Check whether the fd is already in the array */ - key = PyLong_FromLong(fd); - if (key == NULL) - return NULL; - - if (PyDict_DelItem(self->dict, key) == -1) { - Py_DECREF(key); - /* This will simply raise the KeyError set by PyDict_DelItem - if the file descriptor isn't registered. */ - return NULL; - } - - Py_DECREF(key); - self->ufd_uptodate = 0; - - Py_RETURN_NONE; -} - +{ + PyObject *key; + + /* Check whether the fd is already in the array */ + key = PyLong_FromLong(fd); + if (key == NULL) + return NULL; + + if (PyDict_DelItem(self->dict, key) == -1) { + Py_DECREF(key); + /* This will simply raise the KeyError set by PyDict_DelItem + if the file descriptor isn't registered. */ + return NULL; + } + + Py_DECREF(key); + self->ufd_uptodate = 0; + + Py_RETURN_NONE; +} + /*[clinic input] select.poll.poll - + timeout as timeout_obj: object = None / @@ -588,162 +588,162 @@ Returns a list containing any descriptors that have events or errors to report, as a list of (fd, event) 2-tuples. [clinic start generated code]*/ -static PyObject * +static PyObject * select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) /*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/ -{ +{ PyObject *result_list = NULL; - int poll_result, i, j; - PyObject *value = NULL, *num = NULL; - _PyTime_t timeout = -1, ms = -1, deadline = 0; - int async_err = 0; - + int poll_result, i, j; + PyObject *value = NULL, *num = NULL; + _PyTime_t timeout = -1, ms = -1, deadline = 0; + int async_err = 0; + if (timeout_obj != Py_None) { - if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, - _PyTime_ROUND_TIMEOUT) < 0) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_SetString(PyExc_TypeError, - "timeout must be an integer or None"); - } - return NULL; - } - - ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT); - if (ms < INT_MIN || ms > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "timeout is too large"); - return NULL; - } - - if (timeout >= 0) { - deadline = _PyTime_GetMonotonicClock() + timeout; - } - } - - /* On some OSes, typically BSD-based ones, the timeout parameter of the - poll() syscall, when negative, must be exactly INFTIM, where defined, - or -1. See issue 31334. */ - if (ms < 0) { -#ifdef INFTIM - ms = INFTIM; -#else - ms = -1; -#endif - } - - /* Avoid concurrent poll() invocation, issue 8865 */ - if (self->poll_running) { - PyErr_SetString(PyExc_RuntimeError, - "concurrent poll() invocation"); - return NULL; - } - - /* Ensure the ufd array is up to date */ - if (!self->ufd_uptodate) - if (update_ufd_array(self) == 0) - return NULL; - - self->poll_running = 1; - - /* call poll() */ - async_err = 0; - do { - Py_BEGIN_ALLOW_THREADS - errno = 0; - poll_result = poll(self->ufds, self->ufd_len, (int)ms); - Py_END_ALLOW_THREADS - - if (errno != EINTR) - break; - - /* poll() was interrupted by a signal */ - if (PyErr_CheckSignals()) { - async_err = 1; - break; - } - - if (timeout >= 0) { - timeout = deadline - _PyTime_GetMonotonicClock(); - if (timeout < 0) { - poll_result = 0; - break; - } - ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); - /* retry poll() with the recomputed timeout */ - } - } while (1); - - self->poll_running = 0; - - if (poll_result < 0) { - if (!async_err) - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - /* build the result list */ - - result_list = PyList_New(poll_result); - if (!result_list) - return NULL; - - for (i = 0, j = 0; j < poll_result; j++) { - /* skip to the next fired descriptor */ - while (!self->ufds[i].revents) { - i++; - } - /* if we hit a NULL return, set value to NULL - and break out of loop; code at end will - clean up result_list */ - value = PyTuple_New(2); - if (value == NULL) - goto error; - num = PyLong_FromLong(self->ufds[i].fd); - if (num == NULL) { - Py_DECREF(value); - goto error; - } - PyTuple_SET_ITEM(value, 0, num); - - /* The &0xffff is a workaround for AIX. 'revents' - is a 16-bit short, and IBM assigned POLLNVAL - to be 0x8000, so the conversion to int results - in a negative number. See SF bug #923315. */ - num = PyLong_FromLong(self->ufds[i].revents & 0xffff); - if (num == NULL) { - Py_DECREF(value); - goto error; - } - PyTuple_SET_ITEM(value, 1, num); - PyList_SET_ITEM(result_list, j, value); - i++; - } - return result_list; - - error: - Py_DECREF(result_list); - return NULL; -} - -static pollObject * -newPollObject(void) -{ - pollObject *self; + if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, + _PyTime_ROUND_TIMEOUT) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "timeout must be an integer or None"); + } + return NULL; + } + + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT); + if (ms < INT_MIN || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "timeout is too large"); + return NULL; + } + + if (timeout >= 0) { + deadline = _PyTime_GetMonotonicClock() + timeout; + } + } + + /* On some OSes, typically BSD-based ones, the timeout parameter of the + poll() syscall, when negative, must be exactly INFTIM, where defined, + or -1. See issue 31334. */ + if (ms < 0) { +#ifdef INFTIM + ms = INFTIM; +#else + ms = -1; +#endif + } + + /* Avoid concurrent poll() invocation, issue 8865 */ + if (self->poll_running) { + PyErr_SetString(PyExc_RuntimeError, + "concurrent poll() invocation"); + return NULL; + } + + /* Ensure the ufd array is up to date */ + if (!self->ufd_uptodate) + if (update_ufd_array(self) == 0) + return NULL; + + self->poll_running = 1; + + /* call poll() */ + async_err = 0; + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; + poll_result = poll(self->ufds, self->ufd_len, (int)ms); + Py_END_ALLOW_THREADS + + if (errno != EINTR) + break; + + /* poll() was interrupted by a signal */ + if (PyErr_CheckSignals()) { + async_err = 1; + break; + } + + if (timeout >= 0) { + timeout = deadline - _PyTime_GetMonotonicClock(); + if (timeout < 0) { + poll_result = 0; + break; + } + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); + /* retry poll() with the recomputed timeout */ + } + } while (1); + + self->poll_running = 0; + + if (poll_result < 0) { + if (!async_err) + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + /* build the result list */ + + result_list = PyList_New(poll_result); + if (!result_list) + return NULL; + + for (i = 0, j = 0; j < poll_result; j++) { + /* skip to the next fired descriptor */ + while (!self->ufds[i].revents) { + i++; + } + /* if we hit a NULL return, set value to NULL + and break out of loop; code at end will + clean up result_list */ + value = PyTuple_New(2); + if (value == NULL) + goto error; + num = PyLong_FromLong(self->ufds[i].fd); + if (num == NULL) { + Py_DECREF(value); + goto error; + } + PyTuple_SET_ITEM(value, 0, num); + + /* The &0xffff is a workaround for AIX. 'revents' + is a 16-bit short, and IBM assigned POLLNVAL + to be 0x8000, so the conversion to int results + in a negative number. See SF bug #923315. */ + num = PyLong_FromLong(self->ufds[i].revents & 0xffff); + if (num == NULL) { + Py_DECREF(value); + goto error; + } + PyTuple_SET_ITEM(value, 1, num); + PyList_SET_ITEM(result_list, j, value); + i++; + } + return result_list; + + error: + Py_DECREF(result_list); + return NULL; +} + +static pollObject * +newPollObject(void) +{ + pollObject *self; self = PyObject_New(pollObject, _selectstate_global->poll_Type); - if (self == NULL) - return NULL; - /* ufd_uptodate is a Boolean, denoting whether the - array pointed to by ufds matches the contents of the dictionary. */ - self->ufd_uptodate = 0; - self->ufds = NULL; - self->poll_running = 0; - self->dict = PyDict_New(); - if (self->dict == NULL) { - Py_DECREF(self); - return NULL; - } - return self; -} - + if (self == NULL) + return NULL; + /* ufd_uptodate is a Boolean, denoting whether the + array pointed to by ufds matches the contents of the dictionary. */ + self->ufd_uptodate = 0; + self->ufds = NULL; + self->poll_running = 0; + self->dict = PyDict_New(); + if (self->dict == NULL) { + Py_DECREF(self); + return NULL; + } + return self; +} + static PyObject * poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { @@ -751,97 +751,97 @@ poll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) return NULL; } -static void -poll_dealloc(pollObject *self) -{ +static void +poll_dealloc(pollObject *self) +{ PyObject* type = (PyObject *)Py_TYPE(self); - if (self->ufds != NULL) - PyMem_DEL(self->ufds); - Py_XDECREF(self->dict); - PyObject_Del(self); + if (self->ufds != NULL) + PyMem_DEL(self->ufds); + Py_XDECREF(self->dict); + PyObject_Del(self); Py_DECREF(type); -} - - -#ifdef HAVE_SYS_DEVPOLL_H +} + + +#ifdef HAVE_SYS_DEVPOLL_H static PyMethodDef devpoll_methods[]; -typedef struct { - PyObject_HEAD - int fd_devpoll; - int max_n_fds; - int n_fds; - struct pollfd *fds; -} devpollObject; - -static PyObject * -devpoll_err_closed(void) -{ - PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object"); - return NULL; -} - -static int devpoll_flush(devpollObject *self) -{ - int size, n; - - if (!self->n_fds) return 0; - - size = sizeof(struct pollfd)*self->n_fds; - self->n_fds = 0; - - n = _Py_write(self->fd_devpoll, self->fds, size); - if (n == -1) - return -1; - - if (n < size) { - /* - ** Data writed to /dev/poll is a binary data structure. It is not - ** clear what to do if a partial write occurred. For now, raise - ** an exception and see if we actually found this problem in - ** the wild. - ** See http://bugs.python.org/issue6397. - */ - PyErr_Format(PyExc_OSError, "failed to write all pollfds. " - "Please, report at http://bugs.python.org/. " - "Data to report: Size tried: %d, actual size written: %d.", - size, n); - return -1; - } - return 0; -} - -static PyObject * +typedef struct { + PyObject_HEAD + int fd_devpoll; + int max_n_fds; + int n_fds; + struct pollfd *fds; +} devpollObject; + +static PyObject * +devpoll_err_closed(void) +{ + PyErr_SetString(PyExc_ValueError, "I/O operation on closed devpoll object"); + return NULL; +} + +static int devpoll_flush(devpollObject *self) +{ + int size, n; + + if (!self->n_fds) return 0; + + size = sizeof(struct pollfd)*self->n_fds; + self->n_fds = 0; + + n = _Py_write(self->fd_devpoll, self->fds, size); + if (n == -1) + return -1; + + if (n < size) { + /* + ** Data writed to /dev/poll is a binary data structure. It is not + ** clear what to do if a partial write occurred. For now, raise + ** an exception and see if we actually found this problem in + ** the wild. + ** See http://bugs.python.org/issue6397. + */ + PyErr_Format(PyExc_OSError, "failed to write all pollfds. " + "Please, report at http://bugs.python.org/. " + "Data to report: Size tried: %d, actual size written: %d.", + size, n); + return -1; + } + return 0; +} + +static PyObject * internal_devpoll_register(devpollObject *self, int fd, unsigned short events, int remove) -{ - if (self->fd_devpoll < 0) - return devpoll_err_closed(); - - if (remove) { - self->fds[self->n_fds].fd = fd; - self->fds[self->n_fds].events = POLLREMOVE; - - if (++self->n_fds == self->max_n_fds) { - if (devpoll_flush(self)) - return NULL; - } - } - - self->fds[self->n_fds].fd = fd; - self->fds[self->n_fds].events = (signed short)events; - - if (++self->n_fds == self->max_n_fds) { - if (devpoll_flush(self)) - return NULL; - } - - Py_RETURN_NONE; -} - +{ + if (self->fd_devpoll < 0) + return devpoll_err_closed(); + + if (remove) { + self->fds[self->n_fds].fd = fd; + self->fds[self->n_fds].events = POLLREMOVE; + + if (++self->n_fds == self->max_n_fds) { + if (devpoll_flush(self)) + return NULL; + } + } + + self->fds[self->n_fds].fd = fd; + self->fds[self->n_fds].events = (signed short)events; + + if (++self->n_fds == self->max_n_fds) { + if (devpoll_flush(self)) + return NULL; + } + + Py_RETURN_NONE; +} + /*[clinic input] select.devpoll.register - + fd: fildes either an integer, or an object with a fileno() method returning an int @@ -852,17 +852,17 @@ select.devpoll.register Register a file descriptor with the polling object. [clinic start generated code]*/ -static PyObject * +static PyObject * select_devpoll_register_impl(devpollObject *self, int fd, unsigned short eventmask) /*[clinic end generated code: output=6e07fe8b74abba0c input=22006fabe9567522]*/ -{ +{ return internal_devpoll_register(self, fd, eventmask, 0); -} - +} + /*[clinic input] select.devpoll.modify - + fd: fildes either an integer, or an object with a fileno() method returning an int @@ -873,171 +873,171 @@ select.devpoll.modify Modify a possible already registered file descriptor. [clinic start generated code]*/ -static PyObject * +static PyObject * select_devpoll_modify_impl(devpollObject *self, int fd, unsigned short eventmask) /*[clinic end generated code: output=bc2e6d23aaff98b4 input=09fa335db7cdc09e]*/ -{ +{ return internal_devpoll_register(self, fd, eventmask, 1); -} - +} + /*[clinic input] select.devpoll.unregister - + fd: fildes / - + Remove a file descriptor being tracked by the polling object. [clinic start generated code]*/ -static PyObject * +static PyObject * select_devpoll_unregister_impl(devpollObject *self, int fd) /*[clinic end generated code: output=95519ffa0c7d43fe input=b4ea42a4442fd467]*/ -{ - if (self->fd_devpoll < 0) - return devpoll_err_closed(); - - self->fds[self->n_fds].fd = fd; - self->fds[self->n_fds].events = POLLREMOVE; - - if (++self->n_fds == self->max_n_fds) { - if (devpoll_flush(self)) - return NULL; - } - - Py_RETURN_NONE; -} - +{ + if (self->fd_devpoll < 0) + return devpoll_err_closed(); + + self->fds[self->n_fds].fd = fd; + self->fds[self->n_fds].events = POLLREMOVE; + + if (++self->n_fds == self->max_n_fds) { + if (devpoll_flush(self)) + return NULL; + } + + Py_RETURN_NONE; +} + /*[clinic input] select.devpoll.poll timeout as timeout_obj: object = None / - + Polls the set of registered file descriptors. Returns a list containing any descriptors that have events or errors to report, as a list of (fd, event) 2-tuples. [clinic start generated code]*/ -static PyObject * +static PyObject * select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj) /*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/ -{ - struct dvpoll dvp; +{ + struct dvpoll dvp; PyObject *result_list = NULL; - int poll_result, i; - PyObject *value, *num1, *num2; - _PyTime_t timeout, ms, deadline = 0; - - if (self->fd_devpoll < 0) - return devpoll_err_closed(); - - /* Check values for timeout */ + int poll_result, i; + PyObject *value, *num1, *num2; + _PyTime_t timeout, ms, deadline = 0; + + if (self->fd_devpoll < 0) + return devpoll_err_closed(); + + /* Check values for timeout */ if (timeout_obj == Py_None) { - timeout = -1; - ms = -1; - } - else { - if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, - _PyTime_ROUND_TIMEOUT) < 0) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_SetString(PyExc_TypeError, - "timeout must be an integer or None"); - } - return NULL; - } - - ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT); - if (ms < -1 || ms > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "timeout is too large"); - return NULL; - } - } - - if (devpoll_flush(self)) - return NULL; - - dvp.dp_fds = self->fds; - dvp.dp_nfds = self->max_n_fds; - dvp.dp_timeout = (int)ms; - - if (timeout >= 0) - deadline = _PyTime_GetMonotonicClock() + timeout; - - do { - /* call devpoll() */ - Py_BEGIN_ALLOW_THREADS - errno = 0; - poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp); - Py_END_ALLOW_THREADS - - if (errno != EINTR) - break; - - /* devpoll() was interrupted by a signal */ - if (PyErr_CheckSignals()) - return NULL; - - if (timeout >= 0) { - timeout = deadline - _PyTime_GetMonotonicClock(); - if (timeout < 0) { - poll_result = 0; - break; - } - ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); - dvp.dp_timeout = (int)ms; - /* retry devpoll() with the recomputed timeout */ - } - } while (1); - - if (poll_result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - /* build the result list */ - result_list = PyList_New(poll_result); - if (!result_list) - return NULL; - - for (i = 0; i < poll_result; i++) { - num1 = PyLong_FromLong(self->fds[i].fd); - num2 = PyLong_FromLong(self->fds[i].revents); - if ((num1 == NULL) || (num2 == NULL)) { - Py_XDECREF(num1); - Py_XDECREF(num2); - goto error; - } - value = PyTuple_Pack(2, num1, num2); - Py_DECREF(num1); - Py_DECREF(num2); - if (value == NULL) - goto error; - PyList_SET_ITEM(result_list, i, value); - } - - return result_list; - - error: - Py_DECREF(result_list); - return NULL; -} - -static int -devpoll_internal_close(devpollObject *self) -{ - int save_errno = 0; - if (self->fd_devpoll >= 0) { - int fd = self->fd_devpoll; - self->fd_devpoll = -1; - Py_BEGIN_ALLOW_THREADS - if (close(fd) < 0) - save_errno = errno; - Py_END_ALLOW_THREADS - } - return save_errno; -} - + timeout = -1; + ms = -1; + } + else { + if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, + _PyTime_ROUND_TIMEOUT) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "timeout must be an integer or None"); + } + return NULL; + } + + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT); + if (ms < -1 || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "timeout is too large"); + return NULL; + } + } + + if (devpoll_flush(self)) + return NULL; + + dvp.dp_fds = self->fds; + dvp.dp_nfds = self->max_n_fds; + dvp.dp_timeout = (int)ms; + + if (timeout >= 0) + deadline = _PyTime_GetMonotonicClock() + timeout; + + do { + /* call devpoll() */ + Py_BEGIN_ALLOW_THREADS + errno = 0; + poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp); + Py_END_ALLOW_THREADS + + if (errno != EINTR) + break; + + /* devpoll() was interrupted by a signal */ + if (PyErr_CheckSignals()) + return NULL; + + if (timeout >= 0) { + timeout = deadline - _PyTime_GetMonotonicClock(); + if (timeout < 0) { + poll_result = 0; + break; + } + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); + dvp.dp_timeout = (int)ms; + /* retry devpoll() with the recomputed timeout */ + } + } while (1); + + if (poll_result < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + /* build the result list */ + result_list = PyList_New(poll_result); + if (!result_list) + return NULL; + + for (i = 0; i < poll_result; i++) { + num1 = PyLong_FromLong(self->fds[i].fd); + num2 = PyLong_FromLong(self->fds[i].revents); + if ((num1 == NULL) || (num2 == NULL)) { + Py_XDECREF(num1); + Py_XDECREF(num2); + goto error; + } + value = PyTuple_Pack(2, num1, num2); + Py_DECREF(num1); + Py_DECREF(num2); + if (value == NULL) + goto error; + PyList_SET_ITEM(result_list, i, value); + } + + return result_list; + + error: + Py_DECREF(result_list); + return NULL; +} + +static int +devpoll_internal_close(devpollObject *self) +{ + int save_errno = 0; + if (self->fd_devpoll >= 0) { + int fd = self->fd_devpoll; + self->fd_devpoll = -1; + Py_BEGIN_ALLOW_THREADS + if (close(fd) < 0) + save_errno = errno; + Py_END_ALLOW_THREADS + } + return save_errno; +} + /*[clinic input] select.devpoll.close @@ -1049,24 +1049,24 @@ Further operations on the devpoll object will raise an exception. static PyObject * select_devpoll_close_impl(devpollObject *self) /*[clinic end generated code: output=26b355bd6429f21b input=6273c30f5560a99b]*/ -{ - errno = devpoll_internal_close(self); - if (errno < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject* -devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored)) -{ - if (self->fd_devpoll < 0) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - +{ + errno = devpoll_internal_close(self); + if (errno < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject* +devpoll_get_closed(devpollObject *self, void *Py_UNUSED(ignored)) +{ + if (self->fd_devpoll < 0) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + /*[clinic input] select.devpoll.fileno @@ -1076,63 +1076,63 @@ Return the file descriptor. static PyObject * select_devpoll_fileno_impl(devpollObject *self) /*[clinic end generated code: output=26920929f8d292f4 input=ef15331ebde6c368]*/ -{ - if (self->fd_devpoll < 0) - return devpoll_err_closed(); - return PyLong_FromLong(self->fd_devpoll); -} - -static PyGetSetDef devpoll_getsetlist[] = { - {"closed", (getter)devpoll_get_closed, NULL, - "True if the devpoll object is closed"}, - {0}, -}; - -static devpollObject * -newDevPollObject(void) -{ - devpollObject *self; - int fd_devpoll, limit_result; - struct pollfd *fds; - struct rlimit limit; - - /* - ** If we try to process more that getrlimit() - ** fds, the kernel will give an error, so - ** we set the limit here. It is a dynamic - ** value, because we can change rlimit() anytime. - */ - limit_result = getrlimit(RLIMIT_NOFILE, &limit); - if (limit_result == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - fd_devpoll = _Py_open("/dev/poll", O_RDWR); - if (fd_devpoll == -1) - return NULL; - - fds = PyMem_NEW(struct pollfd, limit.rlim_cur); - if (fds == NULL) { - close(fd_devpoll); - PyErr_NoMemory(); - return NULL; - } - +{ + if (self->fd_devpoll < 0) + return devpoll_err_closed(); + return PyLong_FromLong(self->fd_devpoll); +} + +static PyGetSetDef devpoll_getsetlist[] = { + {"closed", (getter)devpoll_get_closed, NULL, + "True if the devpoll object is closed"}, + {0}, +}; + +static devpollObject * +newDevPollObject(void) +{ + devpollObject *self; + int fd_devpoll, limit_result; + struct pollfd *fds; + struct rlimit limit; + + /* + ** If we try to process more that getrlimit() + ** fds, the kernel will give an error, so + ** we set the limit here. It is a dynamic + ** value, because we can change rlimit() anytime. + */ + limit_result = getrlimit(RLIMIT_NOFILE, &limit); + if (limit_result == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + fd_devpoll = _Py_open("/dev/poll", O_RDWR); + if (fd_devpoll == -1) + return NULL; + + fds = PyMem_NEW(struct pollfd, limit.rlim_cur); + if (fds == NULL) { + close(fd_devpoll); + PyErr_NoMemory(); + return NULL; + } + self = PyObject_New(devpollObject, _selectstate_global->devpoll_Type); - if (self == NULL) { - close(fd_devpoll); - PyMem_DEL(fds); - return NULL; - } - self->fd_devpoll = fd_devpoll; - self->max_n_fds = limit.rlim_cur; - self->n_fds = 0; - self->fds = fds; - - return self; -} - + if (self == NULL) { + close(fd_devpoll); + PyMem_DEL(fds); + return NULL; + } + self->fd_devpoll = fd_devpoll; + self->max_n_fds = limit.rlim_cur; + self->n_fds = 0; + self->fds = fds; + + return self; +} + static PyObject * devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { @@ -1140,16 +1140,16 @@ devpoll_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) return NULL; } -static void -devpoll_dealloc(devpollObject *self) -{ +static void +devpoll_dealloc(devpollObject *self) +{ PyObject *type = (PyObject *)Py_TYPE(self); - (void)devpoll_internal_close(self); - PyMem_DEL(self->fds); - PyObject_Del(self); + (void)devpoll_internal_close(self); + PyMem_DEL(self->fds); + PyObject_Del(self); Py_DECREF(type); -} - +} + static PyType_Slot devpoll_Type_slots[] = { {Py_tp_dealloc, devpoll_dealloc}, {Py_tp_getset, devpoll_getsetlist}, @@ -1166,27 +1166,27 @@ static PyType_Spec devpoll_Type_spec = { devpoll_Type_slots }; -#endif /* HAVE_SYS_DEVPOLL_H */ - - +#endif /* HAVE_SYS_DEVPOLL_H */ + + /*[clinic input] select.poll - + Returns a polling object. - + This object supports registering and unregistering file descriptors, and then polling them for I/O events. [clinic start generated code]*/ -static PyObject * +static PyObject * select_poll_impl(PyObject *module) /*[clinic end generated code: output=16a665a4e1d228c5 input=3f877909d5696bbf]*/ -{ - return (PyObject *)newPollObject(); -} - -#ifdef HAVE_SYS_DEVPOLL_H - +{ + return (PyObject *)newPollObject(); +} + +#ifdef HAVE_SYS_DEVPOLL_H + /*[clinic input] select.devpoll @@ -1196,128 +1196,128 @@ This object supports registering and unregistering file descriptors, and then polling them for I/O events. [clinic start generated code]*/ -static PyObject * +static PyObject * select_devpoll_impl(PyObject *module) /*[clinic end generated code: output=ea9213cc87fd9581 input=53a1af94564f00a3]*/ -{ - return (PyObject *)newDevPollObject(); -} -#endif - - -#ifdef __APPLE__ -/* - * On some systems poll() sets errno on invalid file descriptors. We test - * for this at runtime because this bug may be fixed or introduced between - * OS releases. - */ -static int select_have_broken_poll(void) -{ - int poll_test; - int filedes[2]; - - struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 }; - - /* Create a file descriptor to make invalid */ - if (pipe(filedes) < 0) { - return 1; - } - poll_struct.fd = filedes[0]; - close(filedes[0]); - close(filedes[1]); - poll_test = poll(&poll_struct, 1, 0); - if (poll_test < 0) { - return 1; - } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) { - return 1; - } - return 0; -} -#endif /* __APPLE__ */ - -#endif /* HAVE_POLL */ - -#ifdef HAVE_EPOLL -/* ************************************************************************** - * epoll interface for Linux 2.6 - * - * Written by Christian Heimes - * Inspired by Twisted's _epoll.pyx and select.poll() - */ - -#ifdef HAVE_SYS_EPOLL_H -#include -#endif - -typedef struct { - PyObject_HEAD - SOCKET epfd; /* epoll control file descriptor */ -} pyEpoll_Object; - +{ + return (PyObject *)newDevPollObject(); +} +#endif + + +#ifdef __APPLE__ +/* + * On some systems poll() sets errno on invalid file descriptors. We test + * for this at runtime because this bug may be fixed or introduced between + * OS releases. + */ +static int select_have_broken_poll(void) +{ + int poll_test; + int filedes[2]; + + struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 }; + + /* Create a file descriptor to make invalid */ + if (pipe(filedes) < 0) { + return 1; + } + poll_struct.fd = filedes[0]; + close(filedes[0]); + close(filedes[1]); + poll_test = poll(&poll_struct, 1, 0); + if (poll_test < 0) { + return 1; + } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) { + return 1; + } + return 0; +} +#endif /* __APPLE__ */ + +#endif /* HAVE_POLL */ + +#ifdef HAVE_EPOLL +/* ************************************************************************** + * epoll interface for Linux 2.6 + * + * Written by Christian Heimes + * Inspired by Twisted's _epoll.pyx and select.poll() + */ + +#ifdef HAVE_SYS_EPOLL_H +#include +#endif + +typedef struct { + PyObject_HEAD + SOCKET epfd; /* epoll control file descriptor */ +} pyEpoll_Object; + #define pyepoll_CHECK(op) (PyObject_TypeCheck((op), _selectstate_global->pyEpoll_Type)) - -static PyObject * -pyepoll_err_closed(void) -{ - PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object"); - return NULL; -} - -static int -pyepoll_internal_close(pyEpoll_Object *self) -{ - int save_errno = 0; - if (self->epfd >= 0) { - int epfd = self->epfd; - self->epfd = -1; - Py_BEGIN_ALLOW_THREADS - if (close(epfd) < 0) - save_errno = errno; - Py_END_ALLOW_THREADS - } - return save_errno; -} - -static PyObject * -newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) -{ - pyEpoll_Object *self; + +static PyObject * +pyepoll_err_closed(void) +{ + PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll object"); + return NULL; +} + +static int +pyepoll_internal_close(pyEpoll_Object *self) +{ + int save_errno = 0; + if (self->epfd >= 0) { + int epfd = self->epfd; + self->epfd = -1; + Py_BEGIN_ALLOW_THREADS + if (close(epfd) < 0) + save_errno = errno; + Py_END_ALLOW_THREADS + } + return save_errno; +} + +static PyObject * +newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) +{ + pyEpoll_Object *self; assert(type != NULL); allocfunc epoll_alloc = PyType_GetSlot(type, Py_tp_alloc); assert(epoll_alloc != NULL); self = (pyEpoll_Object *) epoll_alloc(type, 0); - if (self == NULL) - return NULL; - - if (fd == -1) { - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_EPOLL_CREATE1 - self->epfd = epoll_create1(EPOLL_CLOEXEC); -#else - self->epfd = epoll_create(sizehint); -#endif - Py_END_ALLOW_THREADS - } - else { - self->epfd = fd; - } - if (self->epfd < 0) { - Py_DECREF(self); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - -#ifndef HAVE_EPOLL_CREATE1 - if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) { - Py_DECREF(self); - return NULL; - } -#endif - - return (PyObject *)self; -} - - + if (self == NULL) + return NULL; + + if (fd == -1) { + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_EPOLL_CREATE1 + self->epfd = epoll_create1(EPOLL_CLOEXEC); +#else + self->epfd = epoll_create(sizehint); +#endif + Py_END_ALLOW_THREADS + } + else { + self->epfd = fd; + } + if (self->epfd < 0) { + Py_DECREF(self); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + +#ifndef HAVE_EPOLL_CREATE1 + if (fd == -1 && _Py_set_inheritable(self->epfd, 0, NULL) < 0) { + Py_DECREF(self); + return NULL; + } +#endif + + return (PyObject *)self; +} + + /*[clinic input] @classmethod select.epoll.__new__ @@ -1334,39 +1334,39 @@ select.epoll.__new__ Returns an epolling object. [clinic start generated code]*/ -static PyObject * +static PyObject * select_epoll_impl(PyTypeObject *type, int sizehint, int flags) /*[clinic end generated code: output=c87404e705013bb5 input=303e3295e7975e43]*/ -{ - if (sizehint == -1) { - sizehint = FD_SETSIZE - 1; - } - else if (sizehint <= 0) { +{ + if (sizehint == -1) { + sizehint = FD_SETSIZE - 1; + } + else if (sizehint <= 0) { PyErr_SetString(PyExc_ValueError, "negative sizehint"); - return NULL; - } - -#ifdef HAVE_EPOLL_CREATE1 - if (flags && flags != EPOLL_CLOEXEC) { - PyErr_SetString(PyExc_OSError, "invalid flags"); - return NULL; - } -#endif - - return newPyEpoll_Object(type, sizehint, -1); -} - - -static void -pyepoll_dealloc(pyEpoll_Object *self) -{ + return NULL; + } + +#ifdef HAVE_EPOLL_CREATE1 + if (flags && flags != EPOLL_CLOEXEC) { + PyErr_SetString(PyExc_OSError, "invalid flags"); + return NULL; + } +#endif + + return newPyEpoll_Object(type, sizehint, -1); +} + + +static void +pyepoll_dealloc(pyEpoll_Object *self) +{ PyTypeObject* type = Py_TYPE(self); - (void)pyepoll_internal_close(self); + (void)pyepoll_internal_close(self); freefunc epoll_free = PyType_GetSlot(type, Py_tp_free); epoll_free((PyObject *)self); Py_DECREF((PyObject *)type); -} - +} + /*[clinic input] select.epoll.close @@ -1378,25 +1378,25 @@ Further operations on the epoll object will raise an exception. static PyObject * select_epoll_close_impl(pyEpoll_Object *self) /*[clinic end generated code: output=ee2144c446a1a435 input=ca6c66ba5a736bfd]*/ -{ - errno = pyepoll_internal_close(self); - if (errno < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_RETURN_NONE; -} - - -static PyObject* -pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored)) -{ - if (self->epfd < 0) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - +{ + errno = pyepoll_internal_close(self); + if (errno < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} + + +static PyObject* +pyepoll_get_closed(pyEpoll_Object *self, void *Py_UNUSED(ignored)) +{ + if (self->epfd < 0) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + /*[clinic input] select.epoll.fileno @@ -1406,20 +1406,20 @@ Return the epoll control file descriptor. static PyObject * select_epoll_fileno_impl(pyEpoll_Object *self) /*[clinic end generated code: output=e171375fdc619ba3 input=c11091a6aee60b5c]*/ -{ - if (self->epfd < 0) - return pyepoll_err_closed(); - return PyLong_FromLong(self->epfd); -} - - +{ + if (self->epfd < 0) + return pyepoll_err_closed(); + return PyLong_FromLong(self->epfd); +} + + /*[clinic input] @classmethod select.epoll.fromfd - + fd: int / - + Create an epoll object from a given control fd. [clinic start generated code]*/ @@ -1429,47 +1429,47 @@ select_epoll_fromfd_impl(PyTypeObject *type, int fd) { SOCKET s_fd = (SOCKET)fd; return newPyEpoll_Object(type, FD_SETSIZE - 1, s_fd); -} - - -static PyObject * +} + + +static PyObject * pyepoll_internal_ctl(int epfd, int op, int fd, unsigned int events) -{ - struct epoll_event ev; - int result; - - if (epfd < 0) - return pyepoll_err_closed(); - - switch (op) { - case EPOLL_CTL_ADD: - case EPOLL_CTL_MOD: - ev.events = events; - ev.data.fd = fd; - Py_BEGIN_ALLOW_THREADS - result = epoll_ctl(epfd, op, fd, &ev); - Py_END_ALLOW_THREADS - break; - case EPOLL_CTL_DEL: - /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL - * operation required a non-NULL pointer in event, even - * though this argument is ignored. */ - Py_BEGIN_ALLOW_THREADS - result = epoll_ctl(epfd, op, fd, &ev); - Py_END_ALLOW_THREADS - break; - default: - result = -1; - errno = EINVAL; - } - - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_RETURN_NONE; -} - +{ + struct epoll_event ev; + int result; + + if (epfd < 0) + return pyepoll_err_closed(); + + switch (op) { + case EPOLL_CTL_ADD: + case EPOLL_CTL_MOD: + ev.events = events; + ev.data.fd = fd; + Py_BEGIN_ALLOW_THREADS + result = epoll_ctl(epfd, op, fd, &ev); + Py_END_ALLOW_THREADS + break; + case EPOLL_CTL_DEL: + /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL + * operation required a non-NULL pointer in event, even + * though this argument is ignored. */ + Py_BEGIN_ALLOW_THREADS + result = epoll_ctl(epfd, op, fd, &ev); + Py_END_ALLOW_THREADS + break; + default: + result = -1; + errno = EINVAL; + } + + if (result < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} + /*[clinic input] select.epoll.register @@ -1483,99 +1483,99 @@ Registers a new fd or raises an OSError if the fd is already registered. The epoll interface supports all file descriptors that support poll. [clinic start generated code]*/ -static PyObject * +static PyObject * select_epoll_register_impl(pyEpoll_Object *self, int fd, unsigned int eventmask) /*[clinic end generated code: output=318e5e6386520599 input=a5071b71edfe3578]*/ -{ +{ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, fd, eventmask); } - + /*[clinic input] select.epoll.modify - + fd: fildes the target file descriptor of the operation eventmask: unsigned_int(bitwise=True) a bit set composed of the various EPOLL constants - + Modify event mask for a registered file descriptor. [clinic start generated code]*/ - -static PyObject * + +static PyObject * select_epoll_modify_impl(pyEpoll_Object *self, int fd, unsigned int eventmask) /*[clinic end generated code: output=7e3447307cff6f65 input=88a83dac53a8c3da]*/ -{ +{ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, fd, eventmask); } - + /*[clinic input] select.epoll.unregister - + fd: fildes the target file descriptor of the operation - + Remove a registered file descriptor from the epoll object. [clinic start generated code]*/ - -static PyObject * + +static PyObject * select_epoll_unregister_impl(pyEpoll_Object *self, int fd) /*[clinic end generated code: output=07c5dbd612a512d4 input=3093f68d3644743d]*/ -{ +{ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, fd, 0); } - + /*[clinic input] select.epoll.poll - + timeout as timeout_obj: object = None the maximum time to wait in seconds (as float); a timeout of None or -1 makes poll wait indefinitely maxevents: int = -1 the maximum number of events returned; -1 means no limit - + Wait for events on the epoll file descriptor. - + Returns a list containing any descriptors that have events to report, as a list of (fd, events) 2-tuples. [clinic start generated code]*/ -static PyObject * +static PyObject * select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, int maxevents) /*[clinic end generated code: output=e02d121a20246c6c input=33d34a5ea430fd5b]*/ -{ - int nfds, i; - PyObject *elist = NULL, *etuple = NULL; - struct epoll_event *evs = NULL; +{ + int nfds, i; + PyObject *elist = NULL, *etuple = NULL; + struct epoll_event *evs = NULL; _PyTime_t timeout = -1, ms = -1, deadline = 0; - - if (self->epfd < 0) - return pyepoll_err_closed(); - + + if (self->epfd < 0) + return pyepoll_err_closed(); + if (timeout_obj != Py_None) { - /* epoll_wait() has a resolution of 1 millisecond, round towards - infinity to wait at least timeout seconds. */ - if (_PyTime_FromSecondsObject(&timeout, timeout_obj, - _PyTime_ROUND_TIMEOUT) < 0) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_SetString(PyExc_TypeError, - "timeout must be an integer or None"); - } - return NULL; - } - - ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); - if (ms < INT_MIN || ms > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, "timeout is too large"); - return NULL; - } + /* epoll_wait() has a resolution of 1 millisecond, round towards + infinity to wait at least timeout seconds. */ + if (_PyTime_FromSecondsObject(&timeout, timeout_obj, + _PyTime_ROUND_TIMEOUT) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "timeout must be an integer or None"); + } + return NULL; + } + + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); + if (ms < INT_MIN || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "timeout is too large"); + return NULL; + } /* epoll_wait(2) treats all arbitrary negative numbers the same for the timeout argument, but -1 is the documented way to block indefinitely in the epoll_wait(2) documentation, so we set ms to -1 if the value of ms is a negative number. - + Note that we didn't use INFTIM here since it's non-standard and isn't available under Linux. */ if (ms < 0) { @@ -1585,89 +1585,89 @@ select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, if (timeout >= 0) { deadline = _PyTime_GetMonotonicClock() + timeout; } - } - - if (maxevents == -1) { - maxevents = FD_SETSIZE-1; - } - else if (maxevents < 1) { - PyErr_Format(PyExc_ValueError, - "maxevents must be greater than 0, got %d", - maxevents); - return NULL; - } - - evs = PyMem_New(struct epoll_event, maxevents); - if (evs == NULL) { - PyErr_NoMemory(); - return NULL; - } - - do { - Py_BEGIN_ALLOW_THREADS - errno = 0; - nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms); - Py_END_ALLOW_THREADS - - if (errno != EINTR) - break; - - /* poll() was interrupted by a signal */ - if (PyErr_CheckSignals()) - goto error; - - if (timeout >= 0) { - timeout = deadline - _PyTime_GetMonotonicClock(); - if (timeout < 0) { - nfds = 0; - break; - } - ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); - /* retry epoll_wait() with the recomputed timeout */ - } - } while(1); - - if (nfds < 0) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - - elist = PyList_New(nfds); - if (elist == NULL) { - goto error; - } - - for (i = 0; i < nfds; i++) { - etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events); - if (etuple == NULL) { - Py_CLEAR(elist); - goto error; - } - PyList_SET_ITEM(elist, i, etuple); - } - - error: - PyMem_Free(evs); - return elist; -} - - + } + + if (maxevents == -1) { + maxevents = FD_SETSIZE-1; + } + else if (maxevents < 1) { + PyErr_Format(PyExc_ValueError, + "maxevents must be greater than 0, got %d", + maxevents); + return NULL; + } + + evs = PyMem_New(struct epoll_event, maxevents); + if (evs == NULL) { + PyErr_NoMemory(); + return NULL; + } + + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; + nfds = epoll_wait(self->epfd, evs, maxevents, (int)ms); + Py_END_ALLOW_THREADS + + if (errno != EINTR) + break; + + /* poll() was interrupted by a signal */ + if (PyErr_CheckSignals()) + goto error; + + if (timeout >= 0) { + timeout = deadline - _PyTime_GetMonotonicClock(); + if (timeout < 0) { + nfds = 0; + break; + } + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); + /* retry epoll_wait() with the recomputed timeout */ + } + } while(1); + + if (nfds < 0) { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + + elist = PyList_New(nfds); + if (elist == NULL) { + goto error; + } + + for (i = 0; i < nfds; i++) { + etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events); + if (etuple == NULL) { + Py_CLEAR(elist); + goto error; + } + PyList_SET_ITEM(elist, i, etuple); + } + + error: + PyMem_Free(evs); + return elist; +} + + /*[clinic input] select.epoll.__enter__ [clinic start generated code]*/ -static PyObject * +static PyObject * select_epoll___enter___impl(pyEpoll_Object *self) /*[clinic end generated code: output=ab45d433504db2a0 input=3c22568587efeadb]*/ -{ - if (self->epfd < 0) - return pyepoll_err_closed(); - - Py_INCREF(self); - return (PyObject *)self; -} - +{ + if (self->epfd < 0) + return pyepoll_err_closed(); + + Py_INCREF(self); + return (PyObject *)self; +} + /*[clinic input] select.epoll.__exit__ @@ -1678,20 +1678,20 @@ select.epoll.__exit__ [clinic start generated code]*/ -static PyObject * +static PyObject * select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb) /*[clinic end generated code: output=c480f38ce361748e input=7ae81a5a4c1a98d8]*/ -{ +{ return PyObject_CallMethodObjArgs((PyObject *)self, _selectstate_global->close, NULL); -} - -static PyGetSetDef pyepoll_getsetlist[] = { - {"closed", (getter)pyepoll_get_closed, NULL, - "True if the epoll handler is closed"}, - {0}, -}; - +} + +static PyGetSetDef pyepoll_getsetlist[] = { + {"closed", (getter)pyepoll_get_closed, NULL, + "True if the epoll handler is closed"}, + {0}, +}; + PyDoc_STRVAR(pyepoll_doc, "select.epoll(sizehint=-1, flags=0)\n\ \n\ @@ -1701,229 +1701,229 @@ sizehint must be a positive integer or -1 for the default size. The\n\ sizehint is used to optimize internal data structures. It doesn't limit\n\ the maximum number of monitored events."); -#endif /* HAVE_EPOLL */ - -#ifdef HAVE_KQUEUE -/* ************************************************************************** - * kqueue interface for BSD - * - * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_SYS_EVENT_H -#include -#endif - -PyDoc_STRVAR(kqueue_event_doc, -"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\ -\n\ -This object is the equivalent of the struct kevent for the C API.\n\ -\n\ -See the kqueue manpage for more detailed information about the meaning\n\ -of the arguments.\n\ -\n\ -One minor note: while you might hope that udata could store a\n\ -reference to a python object, it cannot, because it is impossible to\n\ -keep a proper reference count of the object once it's passed into the\n\ -kernel. Therefore, I have restricted it to only storing an integer. I\n\ -recommend ignoring it and simply using the 'ident' field to key off\n\ -of. You could also set up a dictionary on the python side to store a\n\ -udata->object mapping."); - -typedef struct { - PyObject_HEAD - struct kevent e; -} kqueue_event_Object; - +#endif /* HAVE_EPOLL */ + +#ifdef HAVE_KQUEUE +/* ************************************************************************** + * kqueue interface for BSD + * + * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_SYS_EVENT_H +#include +#endif + +PyDoc_STRVAR(kqueue_event_doc, +"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\ +\n\ +This object is the equivalent of the struct kevent for the C API.\n\ +\n\ +See the kqueue manpage for more detailed information about the meaning\n\ +of the arguments.\n\ +\n\ +One minor note: while you might hope that udata could store a\n\ +reference to a python object, it cannot, because it is impossible to\n\ +keep a proper reference count of the object once it's passed into the\n\ +kernel. Therefore, I have restricted it to only storing an integer. I\n\ +recommend ignoring it and simply using the 'ident' field to key off\n\ +of. You could also set up a dictionary on the python side to store a\n\ +udata->object mapping."); + +typedef struct { + PyObject_HEAD + struct kevent e; +} kqueue_event_Object; + #define kqueue_event_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_event_Type)) - -typedef struct { - PyObject_HEAD - SOCKET kqfd; /* kqueue control fd */ -} kqueue_queue_Object; - + +typedef struct { + PyObject_HEAD + SOCKET kqfd; /* kqueue control fd */ +} kqueue_queue_Object; + #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), _selectstate_global->kqueue_queue_Type)) - -#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) -# error uintptr_t does not match void *! -#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) -# define T_UINTPTRT T_ULONGLONG -# define T_INTPTRT T_LONGLONG -# define UINTPTRT_FMT_UNIT "K" -# define INTPTRT_FMT_UNIT "L" -#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG) -# define T_UINTPTRT T_ULONG -# define T_INTPTRT T_LONG -# define UINTPTRT_FMT_UNIT "k" -# define INTPTRT_FMT_UNIT "l" -#elif (SIZEOF_UINTPTR_T == SIZEOF_INT) -# define T_UINTPTRT T_UINT -# define T_INTPTRT T_INT -# define UINTPTRT_FMT_UNIT "I" -# define INTPTRT_FMT_UNIT "i" -#else -# error uintptr_t does not match int, long, or long long! -#endif - -#if SIZEOF_LONG_LONG == 8 -# define T_INT64 T_LONGLONG -# define INT64_FMT_UNIT "L" -#elif SIZEOF_LONG == 8 -# define T_INT64 T_LONG -# define INT64_FMT_UNIT "l" -#elif SIZEOF_INT == 8 -# define T_INT64 T_INT -# define INT64_FMT_UNIT "i" -#else -# define INT64_FMT_UNIT "_" -#endif - -#if SIZEOF_LONG_LONG == 4 -# define T_UINT32 T_ULONGLONG -# define UINT32_FMT_UNIT "K" -#elif SIZEOF_LONG == 4 -# define T_UINT32 T_ULONG -# define UINT32_FMT_UNIT "k" -#elif SIZEOF_INT == 4 -# define T_UINT32 T_UINT -# define UINT32_FMT_UNIT "I" -#else -# define UINT32_FMT_UNIT "_" -#endif - -/* - * kevent is not standard and its members vary across BSDs. - */ -#ifdef __NetBSD__ -# define FILTER_TYPE T_UINT32 -# define FILTER_FMT_UNIT UINT32_FMT_UNIT -# define FLAGS_TYPE T_UINT32 -# define FLAGS_FMT_UNIT UINT32_FMT_UNIT -# define FFLAGS_TYPE T_UINT32 -# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT -#else -# define FILTER_TYPE T_SHORT -# define FILTER_FMT_UNIT "h" -# define FLAGS_TYPE T_USHORT -# define FLAGS_FMT_UNIT "H" -# define FFLAGS_TYPE T_UINT -# define FFLAGS_FMT_UNIT "I" -#endif - -#if defined(__NetBSD__) || defined(__OpenBSD__) -# define DATA_TYPE T_INT64 -# define DATA_FMT_UNIT INT64_FMT_UNIT -#else -# define DATA_TYPE T_INTPTRT -# define DATA_FMT_UNIT INTPTRT_FMT_UNIT -#endif - -/* Unfortunately, we can't store python objects in udata, because - * kevents in the kernel can be removed without warning, which would - * forever lose the refcount on the object stored with it. - */ - -#define KQ_OFF(x) offsetof(kqueue_event_Object, x) -static struct PyMemberDef kqueue_event_members[] = { - {"ident", T_UINTPTRT, KQ_OFF(e.ident)}, - {"filter", FILTER_TYPE, KQ_OFF(e.filter)}, - {"flags", FLAGS_TYPE, KQ_OFF(e.flags)}, - {"fflags", T_UINT, KQ_OFF(e.fflags)}, - {"data", DATA_TYPE, KQ_OFF(e.data)}, - {"udata", T_UINTPTRT, KQ_OFF(e.udata)}, - {NULL} /* Sentinel */ -}; -#undef KQ_OFF - -static PyObject * - -kqueue_event_repr(kqueue_event_Object *s) -{ - char buf[1024]; - PyOS_snprintf( - buf, sizeof(buf), - "", - (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags, - (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata); - return PyUnicode_FromString(buf); -} - -static int -kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds) -{ - PyObject *pfd; - static char *kwlist[] = {"ident", "filter", "flags", "fflags", - "data", "udata", NULL}; - static const char fmt[] = "O|" - FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT - UINTPTRT_FMT_UNIT ":kevent"; - - EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ - - if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist, - &pfd, &(self->e.filter), &(self->e.flags), - &(self->e.fflags), &(self->e.data), &(self->e.udata))) { - return -1; - } - - if (PyLong_Check(pfd)) { - self->e.ident = PyLong_AsSize_t(pfd); - } - else { - self->e.ident = PyObject_AsFileDescriptor(pfd); - } - if (PyErr_Occurred()) { - return -1; - } - return 0; -} - -static PyObject * -kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, - int op) -{ - int result; - - if (!kqueue_event_Check(o)) { - Py_RETURN_NOTIMPLEMENTED; - } - -#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1) - result = CMP(s->e.ident, o->e.ident) - : CMP(s->e.filter, o->e.filter) - : CMP(s->e.flags, o->e.flags) - : CMP(s->e.fflags, o->e.fflags) - : CMP(s->e.data, o->e.data) - : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata) - : 0; -#undef CMP - - Py_RETURN_RICHCOMPARE(result, 0, op); -} - + +#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) +# error uintptr_t does not match void *! +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) +# define T_UINTPTRT T_ULONGLONG +# define T_INTPTRT T_LONGLONG +# define UINTPTRT_FMT_UNIT "K" +# define INTPTRT_FMT_UNIT "L" +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG) +# define T_UINTPTRT T_ULONG +# define T_INTPTRT T_LONG +# define UINTPTRT_FMT_UNIT "k" +# define INTPTRT_FMT_UNIT "l" +#elif (SIZEOF_UINTPTR_T == SIZEOF_INT) +# define T_UINTPTRT T_UINT +# define T_INTPTRT T_INT +# define UINTPTRT_FMT_UNIT "I" +# define INTPTRT_FMT_UNIT "i" +#else +# error uintptr_t does not match int, long, or long long! +#endif + +#if SIZEOF_LONG_LONG == 8 +# define T_INT64 T_LONGLONG +# define INT64_FMT_UNIT "L" +#elif SIZEOF_LONG == 8 +# define T_INT64 T_LONG +# define INT64_FMT_UNIT "l" +#elif SIZEOF_INT == 8 +# define T_INT64 T_INT +# define INT64_FMT_UNIT "i" +#else +# define INT64_FMT_UNIT "_" +#endif + +#if SIZEOF_LONG_LONG == 4 +# define T_UINT32 T_ULONGLONG +# define UINT32_FMT_UNIT "K" +#elif SIZEOF_LONG == 4 +# define T_UINT32 T_ULONG +# define UINT32_FMT_UNIT "k" +#elif SIZEOF_INT == 4 +# define T_UINT32 T_UINT +# define UINT32_FMT_UNIT "I" +#else +# define UINT32_FMT_UNIT "_" +#endif + +/* + * kevent is not standard and its members vary across BSDs. + */ +#ifdef __NetBSD__ +# define FILTER_TYPE T_UINT32 +# define FILTER_FMT_UNIT UINT32_FMT_UNIT +# define FLAGS_TYPE T_UINT32 +# define FLAGS_FMT_UNIT UINT32_FMT_UNIT +# define FFLAGS_TYPE T_UINT32 +# define FFLAGS_FMT_UNIT UINT32_FMT_UNIT +#else +# define FILTER_TYPE T_SHORT +# define FILTER_FMT_UNIT "h" +# define FLAGS_TYPE T_USHORT +# define FLAGS_FMT_UNIT "H" +# define FFLAGS_TYPE T_UINT +# define FFLAGS_FMT_UNIT "I" +#endif + +#if defined(__NetBSD__) || defined(__OpenBSD__) +# define DATA_TYPE T_INT64 +# define DATA_FMT_UNIT INT64_FMT_UNIT +#else +# define DATA_TYPE T_INTPTRT +# define DATA_FMT_UNIT INTPTRT_FMT_UNIT +#endif + +/* Unfortunately, we can't store python objects in udata, because + * kevents in the kernel can be removed without warning, which would + * forever lose the refcount on the object stored with it. + */ + +#define KQ_OFF(x) offsetof(kqueue_event_Object, x) +static struct PyMemberDef kqueue_event_members[] = { + {"ident", T_UINTPTRT, KQ_OFF(e.ident)}, + {"filter", FILTER_TYPE, KQ_OFF(e.filter)}, + {"flags", FLAGS_TYPE, KQ_OFF(e.flags)}, + {"fflags", T_UINT, KQ_OFF(e.fflags)}, + {"data", DATA_TYPE, KQ_OFF(e.data)}, + {"udata", T_UINTPTRT, KQ_OFF(e.udata)}, + {NULL} /* Sentinel */ +}; +#undef KQ_OFF + +static PyObject * + +kqueue_event_repr(kqueue_event_Object *s) +{ + char buf[1024]; + PyOS_snprintf( + buf, sizeof(buf), + "", + (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags, + (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata); + return PyUnicode_FromString(buf); +} + +static int +kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds) +{ + PyObject *pfd; + static char *kwlist[] = {"ident", "filter", "flags", "fflags", + "data", "udata", NULL}; + static const char fmt[] = "O|" + FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT + UINTPTRT_FMT_UNIT ":kevent"; + + EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ + + if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist, + &pfd, &(self->e.filter), &(self->e.flags), + &(self->e.fflags), &(self->e.data), &(self->e.udata))) { + return -1; + } + + if (PyLong_Check(pfd)) { + self->e.ident = PyLong_AsSize_t(pfd); + } + else { + self->e.ident = PyObject_AsFileDescriptor(pfd); + } + if (PyErr_Occurred()) { + return -1; + } + return 0; +} + +static PyObject * +kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, + int op) +{ + int result; + + if (!kqueue_event_Check(o)) { + Py_RETURN_NOTIMPLEMENTED; + } + +#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1) + result = CMP(s->e.ident, o->e.ident) + : CMP(s->e.filter, o->e.filter) + : CMP(s->e.flags, o->e.flags) + : CMP(s->e.fflags, o->e.fflags) + : CMP(s->e.data, o->e.data) + : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata) + : 0; +#undef CMP + + Py_RETURN_RICHCOMPARE(result, 0, op); +} + static PyType_Slot kqueue_event_Type_slots[] = { {Py_tp_doc, (void*)kqueue_event_doc}, {Py_tp_init, kqueue_event_init}, @@ -1942,63 +1942,63 @@ static PyType_Spec kqueue_event_Type_spec = { kqueue_event_Type_slots }; -static PyObject * -kqueue_queue_err_closed(void) -{ - PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object"); - return NULL; -} - -static int -kqueue_queue_internal_close(kqueue_queue_Object *self) -{ - int save_errno = 0; - if (self->kqfd >= 0) { - int kqfd = self->kqfd; - self->kqfd = -1; - Py_BEGIN_ALLOW_THREADS - if (close(kqfd) < 0) - save_errno = errno; - Py_END_ALLOW_THREADS - } - return save_errno; -} - -static PyObject * -newKqueue_Object(PyTypeObject *type, SOCKET fd) -{ - kqueue_queue_Object *self; +static PyObject * +kqueue_queue_err_closed(void) +{ + PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue object"); + return NULL; +} + +static int +kqueue_queue_internal_close(kqueue_queue_Object *self) +{ + int save_errno = 0; + if (self->kqfd >= 0) { + int kqfd = self->kqfd; + self->kqfd = -1; + Py_BEGIN_ALLOW_THREADS + if (close(kqfd) < 0) + save_errno = errno; + Py_END_ALLOW_THREADS + } + return save_errno; +} + +static PyObject * +newKqueue_Object(PyTypeObject *type, SOCKET fd) +{ + kqueue_queue_Object *self; assert(type != NULL); allocfunc queue_alloc = PyType_GetSlot(type, Py_tp_alloc); assert(queue_alloc != NULL); self = (kqueue_queue_Object *) queue_alloc(type, 0); - if (self == NULL) { - return NULL; - } - - if (fd == -1) { - Py_BEGIN_ALLOW_THREADS - self->kqfd = kqueue(); - Py_END_ALLOW_THREADS - } - else { - self->kqfd = fd; - } - if (self->kqfd < 0) { - Py_DECREF(self); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - if (fd == -1) { - if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) { - Py_DECREF(self); - return NULL; - } - } - return (PyObject *)self; -} - + if (self == NULL) { + return NULL; + } + + if (fd == -1) { + Py_BEGIN_ALLOW_THREADS + self->kqfd = kqueue(); + Py_END_ALLOW_THREADS + } + else { + self->kqfd = fd; + } + if (self->kqfd < 0) { + Py_DECREF(self); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + if (fd == -1) { + if (_Py_set_inheritable(self->kqfd, 0, NULL) < 0) { + Py_DECREF(self); + return NULL; + } + } + return (PyObject *)self; +} + /*[clinic input] @classmethod select.kqueue.__new__ @@ -2018,23 +2018,23 @@ To stop listening: >>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0) [clinic start generated code]*/ -static PyObject * +static PyObject * select_kqueue_impl(PyTypeObject *type) /*[clinic end generated code: output=e0ff89f154d56236 input=cf625e49218366e8]*/ -{ - return newKqueue_Object(type, -1); -} - -static void -kqueue_queue_dealloc(kqueue_queue_Object *self) -{ +{ + return newKqueue_Object(type, -1); +} + +static void +kqueue_queue_dealloc(kqueue_queue_Object *self) +{ PyTypeObject* type = Py_TYPE(self); - kqueue_queue_internal_close(self); + kqueue_queue_internal_close(self); freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free); kqueue_free((PyObject *)self); Py_DECREF((PyObject *)type); -} - +} + /*[clinic input] select.kqueue.close @@ -2046,24 +2046,24 @@ Further operations on the kqueue object will raise an exception. static PyObject * select_kqueue_close_impl(kqueue_queue_Object *self) /*[clinic end generated code: output=d1c7df0b407a4bc1 input=0b12d95430e0634c]*/ -{ - errno = kqueue_queue_internal_close(self); - if (errno < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject* -kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored)) -{ - if (self->kqfd < 0) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - +{ + errno = kqueue_queue_internal_close(self); + if (errno < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject* +kqueue_queue_get_closed(kqueue_queue_Object *self, void *Py_UNUSED(ignored)) +{ + if (self->kqfd < 0) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + /*[clinic input] select.kqueue.fileno @@ -2073,16 +2073,16 @@ Return the kqueue control file descriptor. static PyObject * select_kqueue_fileno_impl(kqueue_queue_Object *self) /*[clinic end generated code: output=716f46112a4f6e5c input=41911c539ca2b0ca]*/ -{ - if (self->kqfd < 0) - return kqueue_queue_err_closed(); - return PyLong_FromLong(self->kqfd); -} - +{ + if (self->kqfd < 0) + return kqueue_queue_err_closed(); + return PyLong_FromLong(self->kqfd); +} + /*[clinic input] @classmethod select.kqueue.fromfd - + fd: int / @@ -2092,15 +2092,15 @@ Create a kqueue object from a given control fd. static PyObject * select_kqueue_fromfd_impl(PyTypeObject *type, int fd) /*[clinic end generated code: output=d02c3c7dc538a653 input=f6172a48ca4ecdd0]*/ -{ +{ SOCKET s_fd = (SOCKET)fd; - + return newKqueue_Object(type, s_fd); -} - +} + /*[clinic input] select.kqueue.control - + changelist: object Must be an iterable of kevent objects describing the changes to be made to the kernel's watch list or None. @@ -2114,164 +2114,164 @@ select.kqueue.control Calls the kernel kevent function. [clinic start generated code]*/ -static PyObject * +static PyObject * select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, int maxevents, PyObject *otimeout) /*[clinic end generated code: output=81324ff5130db7ae input=59c4e30811209c47]*/ -{ - int gotevents = 0; - int nchanges = 0; - int i = 0; - PyObject *seq = NULL, *ei = NULL; - PyObject *result = NULL; - struct kevent *evl = NULL; - struct kevent *chl = NULL; - struct timespec timeoutspec; - struct timespec *ptimeoutspec; - _PyTime_t timeout, deadline = 0; - - if (self->kqfd < 0) - return kqueue_queue_err_closed(); - +{ + int gotevents = 0; + int nchanges = 0; + int i = 0; + PyObject *seq = NULL, *ei = NULL; + PyObject *result = NULL; + struct kevent *evl = NULL; + struct kevent *chl = NULL; + struct timespec timeoutspec; + struct timespec *ptimeoutspec; + _PyTime_t timeout, deadline = 0; + + if (self->kqfd < 0) + return kqueue_queue_err_closed(); + if (maxevents < 0) { - PyErr_Format(PyExc_ValueError, - "Length of eventlist must be 0 or positive, got %d", + PyErr_Format(PyExc_ValueError, + "Length of eventlist must be 0 or positive, got %d", maxevents); - return NULL; - } - + return NULL; + } + if (otimeout == Py_None) { - ptimeoutspec = NULL; - } - else { - if (_PyTime_FromSecondsObject(&timeout, - otimeout, _PyTime_ROUND_TIMEOUT) < 0) { - PyErr_Format(PyExc_TypeError, - "timeout argument must be a number " - "or None, got %.200s", + ptimeoutspec = NULL; + } + else { + if (_PyTime_FromSecondsObject(&timeout, + otimeout, _PyTime_ROUND_TIMEOUT) < 0) { + PyErr_Format(PyExc_TypeError, + "timeout argument must be a number " + "or None, got %.200s", _PyType_Name(Py_TYPE(otimeout))); - return NULL; - } - - if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1) - return NULL; - - if (timeoutspec.tv_sec < 0) { - PyErr_SetString(PyExc_ValueError, - "timeout must be positive or None"); - return NULL; - } - ptimeoutspec = &timeoutspec; - } - + return NULL; + } + + if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1) + return NULL; + + if (timeoutspec.tv_sec < 0) { + PyErr_SetString(PyExc_ValueError, + "timeout must be positive or None"); + return NULL; + } + ptimeoutspec = &timeoutspec; + } + if (changelist != Py_None) { seq = PySequence_Fast(changelist, "changelist is not iterable"); - if (seq == NULL) { - return NULL; - } - if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "changelist is too long"); - goto error; - } - nchanges = (int)PySequence_Fast_GET_SIZE(seq); - - chl = PyMem_New(struct kevent, nchanges); - if (chl == NULL) { - PyErr_NoMemory(); - goto error; - } - for (i = 0; i < nchanges; ++i) { - ei = PySequence_Fast_GET_ITEM(seq, i); - if (!kqueue_event_Check(ei)) { - PyErr_SetString(PyExc_TypeError, - "changelist must be an iterable of " - "select.kevent objects"); - goto error; - } - chl[i] = ((kqueue_event_Object *)ei)->e; - } - Py_CLEAR(seq); - } - - /* event list */ + if (seq == NULL) { + return NULL; + } + if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "changelist is too long"); + goto error; + } + nchanges = (int)PySequence_Fast_GET_SIZE(seq); + + chl = PyMem_New(struct kevent, nchanges); + if (chl == NULL) { + PyErr_NoMemory(); + goto error; + } + for (i = 0; i < nchanges; ++i) { + ei = PySequence_Fast_GET_ITEM(seq, i); + if (!kqueue_event_Check(ei)) { + PyErr_SetString(PyExc_TypeError, + "changelist must be an iterable of " + "select.kevent objects"); + goto error; + } + chl[i] = ((kqueue_event_Object *)ei)->e; + } + Py_CLEAR(seq); + } + + /* event list */ if (maxevents) { evl = PyMem_New(struct kevent, maxevents); - if (evl == NULL) { - PyErr_NoMemory(); - goto error; - } - } - - if (ptimeoutspec) - deadline = _PyTime_GetMonotonicClock() + timeout; - - do { - Py_BEGIN_ALLOW_THREADS - errno = 0; - gotevents = kevent(self->kqfd, chl, nchanges, + if (evl == NULL) { + PyErr_NoMemory(); + goto error; + } + } + + if (ptimeoutspec) + deadline = _PyTime_GetMonotonicClock() + timeout; + + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; + gotevents = kevent(self->kqfd, chl, nchanges, evl, maxevents, ptimeoutspec); - Py_END_ALLOW_THREADS - - if (errno != EINTR) - break; - - /* kevent() was interrupted by a signal */ - if (PyErr_CheckSignals()) - goto error; - - if (ptimeoutspec) { - timeout = deadline - _PyTime_GetMonotonicClock(); - if (timeout < 0) { - gotevents = 0; - break; - } - if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1) - goto error; - /* retry kevent() with the recomputed timeout */ - } - } while (1); - - if (gotevents == -1) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - - result = PyList_New(gotevents); - if (result == NULL) { - goto error; - } - - for (i = 0; i < gotevents; i++) { - kqueue_event_Object *ch; - + Py_END_ALLOW_THREADS + + if (errno != EINTR) + break; + + /* kevent() was interrupted by a signal */ + if (PyErr_CheckSignals()) + goto error; + + if (ptimeoutspec) { + timeout = deadline - _PyTime_GetMonotonicClock(); + if (timeout < 0) { + gotevents = 0; + break; + } + if (_PyTime_AsTimespec(timeout, &timeoutspec) == -1) + goto error; + /* retry kevent() with the recomputed timeout */ + } + } while (1); + + if (gotevents == -1) { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + + result = PyList_New(gotevents); + if (result == NULL) { + goto error; + } + + for (i = 0; i < gotevents; i++) { + kqueue_event_Object *ch; + ch = PyObject_New(kqueue_event_Object, _selectstate_global->kqueue_event_Type); - if (ch == NULL) { - goto error; - } - ch->e = evl[i]; - PyList_SET_ITEM(result, i, (PyObject *)ch); - } - PyMem_Free(chl); - PyMem_Free(evl); - return result; - - error: - PyMem_Free(chl); - PyMem_Free(evl); - Py_XDECREF(result); - Py_XDECREF(seq); - return NULL; -} - + if (ch == NULL) { + goto error; + } + ch->e = evl[i]; + PyList_SET_ITEM(result, i, (PyObject *)ch); + } + PyMem_Free(chl); + PyMem_Free(evl); + return result; + + error: + PyMem_Free(chl); + PyMem_Free(evl); + Py_XDECREF(result); + Py_XDECREF(seq); + return NULL; +} + static PyGetSetDef kqueue_queue_getsetlist[] = { {"closed", (getter)kqueue_queue_get_closed, NULL, "True if the kqueue handler is closed"}, {0}, }; - + #endif /* HAVE_KQUEUE */ - + /* ************************************************************************ */ @@ -2331,9 +2331,9 @@ static PyMethodDef pyepoll_methods[] = { SELECT_EPOLL_POLL_METHODDEF SELECT_EPOLL___ENTER___METHODDEF SELECT_EPOLL___EXIT___METHODDEF - {NULL, NULL}, -}; - + {NULL, NULL}, +}; + static PyType_Slot pyEpoll_Type_slots[] = { {Py_tp_dealloc, pyepoll_dealloc}, {Py_tp_doc, (void*)pyepoll_doc}, @@ -2342,8 +2342,8 @@ static PyType_Slot pyEpoll_Type_slots[] = { {Py_tp_methods, pyepoll_methods}, {Py_tp_new, select_epoll}, {0, 0}, -}; - +}; + static PyType_Spec pyEpoll_Type_spec = { "select.epoll", sizeof(pyEpoll_Object), @@ -2353,7 +2353,7 @@ static PyType_Spec pyEpoll_Type_spec = { }; #endif /* HAVE_EPOLL */ - + #ifdef HAVE_KQUEUE static PyMethodDef kqueue_queue_methods[] = { @@ -2371,8 +2371,8 @@ static PyType_Slot kqueue_queue_Type_slots[] = { {Py_tp_methods, kqueue_queue_methods}, {Py_tp_new, select_kqueue}, {0, 0}, -}; - +}; + static PyType_Spec kqueue_queue_Type_spec = { "select.kqueue", sizeof(kqueue_queue_Object), @@ -2381,29 +2381,29 @@ static PyType_Spec kqueue_queue_Type_spec = { kqueue_queue_Type_slots }; -#endif /* HAVE_KQUEUE */ - - - - - -/* ************************************************************************ */ - - -static PyMethodDef select_methods[] = { +#endif /* HAVE_KQUEUE */ + + + + + +/* ************************************************************************ */ + + +static PyMethodDef select_methods[] = { SELECT_SELECT_METHODDEF SELECT_POLL_METHODDEF SELECT_DEVPOLL_METHODDEF - {0, 0}, /* sentinel */ -}; - -PyDoc_STRVAR(module_doc, -"This module supports asynchronous I/O on multiple file descriptors.\n\ -\n\ -*** IMPORTANT NOTICE ***\n\ -On Windows, only sockets are supported; on Unix, all file descriptors."); - - + {0, 0}, /* sentinel */ +}; + +PyDoc_STRVAR(module_doc, +"This module supports asynchronous I/O on multiple file descriptors.\n\ +\n\ +*** IMPORTANT NOTICE ***\n\ +On Windows, only sockets are supported; on Unix, all file descriptors."); + + static int _select_traverse(PyObject *module, visitproc visit, void *arg) @@ -2435,228 +2435,228 @@ _select_free(void *module) _select_clear((PyObject *)module); } -static struct PyModuleDef selectmodule = { - PyModuleDef_HEAD_INIT, - "select", - module_doc, +static struct PyModuleDef selectmodule = { + PyModuleDef_HEAD_INIT, + "select", + module_doc, sizeof(_selectstate), - select_methods, - NULL, + select_methods, + NULL, _select_traverse, _select_clear, _select_free, -}; - -PyMODINIT_FUNC -PyInit_select(void) -{ - PyObject *m; - m = PyModule_Create(&selectmodule); - if (m == NULL) - return NULL; - +}; + +PyMODINIT_FUNC +PyInit_select(void) +{ + PyObject *m; + m = PyModule_Create(&selectmodule); + if (m == NULL) + return NULL; + get_select_state(m)->close = PyUnicode_InternFromString("close"); - Py_INCREF(PyExc_OSError); - PyModule_AddObject(m, "error", PyExc_OSError); - -#ifdef PIPE_BUF -#ifdef HAVE_BROKEN_PIPE_BUF -#undef PIPE_BUF -#define PIPE_BUF 512 -#endif - PyModule_AddIntMacro(m, PIPE_BUF); -#endif - -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) -#ifdef __APPLE__ - if (select_have_broken_poll()) { - if (PyObject_DelAttrString(m, "poll") == -1) { - PyErr_Clear(); - } - } else { -#else - { -#endif + Py_INCREF(PyExc_OSError); + PyModule_AddObject(m, "error", PyExc_OSError); + +#ifdef PIPE_BUF +#ifdef HAVE_BROKEN_PIPE_BUF +#undef PIPE_BUF +#define PIPE_BUF 512 +#endif + PyModule_AddIntMacro(m, PIPE_BUF); +#endif + +#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) +#ifdef __APPLE__ + if (select_have_broken_poll()) { + if (PyObject_DelAttrString(m, "poll") == -1) { + PyErr_Clear(); + } + } else { +#else + { +#endif PyObject *poll_Type = PyType_FromSpec(&poll_Type_spec); if (poll_Type == NULL) - return NULL; + return NULL; get_select_state(m)->poll_Type = (PyTypeObject *)poll_Type; Py_INCREF(poll_Type); - PyModule_AddIntMacro(m, POLLIN); - PyModule_AddIntMacro(m, POLLPRI); - PyModule_AddIntMacro(m, POLLOUT); - PyModule_AddIntMacro(m, POLLERR); - PyModule_AddIntMacro(m, POLLHUP); - PyModule_AddIntMacro(m, POLLNVAL); - -#ifdef POLLRDNORM - PyModule_AddIntMacro(m, POLLRDNORM); -#endif -#ifdef POLLRDBAND - PyModule_AddIntMacro(m, POLLRDBAND); -#endif -#ifdef POLLWRNORM - PyModule_AddIntMacro(m, POLLWRNORM); -#endif -#ifdef POLLWRBAND - PyModule_AddIntMacro(m, POLLWRBAND); -#endif -#ifdef POLLMSG - PyModule_AddIntMacro(m, POLLMSG); -#endif -#ifdef POLLRDHUP - /* Kernel 2.6.17+ */ - PyModule_AddIntMacro(m, POLLRDHUP); -#endif - } -#endif /* HAVE_POLL */ - -#ifdef HAVE_SYS_DEVPOLL_H + PyModule_AddIntMacro(m, POLLIN); + PyModule_AddIntMacro(m, POLLPRI); + PyModule_AddIntMacro(m, POLLOUT); + PyModule_AddIntMacro(m, POLLERR); + PyModule_AddIntMacro(m, POLLHUP); + PyModule_AddIntMacro(m, POLLNVAL); + +#ifdef POLLRDNORM + PyModule_AddIntMacro(m, POLLRDNORM); +#endif +#ifdef POLLRDBAND + PyModule_AddIntMacro(m, POLLRDBAND); +#endif +#ifdef POLLWRNORM + PyModule_AddIntMacro(m, POLLWRNORM); +#endif +#ifdef POLLWRBAND + PyModule_AddIntMacro(m, POLLWRBAND); +#endif +#ifdef POLLMSG + PyModule_AddIntMacro(m, POLLMSG); +#endif +#ifdef POLLRDHUP + /* Kernel 2.6.17+ */ + PyModule_AddIntMacro(m, POLLRDHUP); +#endif + } +#endif /* HAVE_POLL */ + +#ifdef HAVE_SYS_DEVPOLL_H PyObject *devpoll_Type = PyType_FromSpec(&devpoll_Type_spec); if (devpoll_Type == NULL) - return NULL; + return NULL; get_select_state(m)->devpoll_Type = (PyTypeObject *)devpoll_Type; Py_INCREF(devpoll_Type); -#endif - -#ifdef HAVE_EPOLL +#endif + +#ifdef HAVE_EPOLL PyObject *pyEpoll_Type = PyType_FromSpec(&pyEpoll_Type_spec); if (pyEpoll_Type == NULL) - return NULL; + return NULL; get_select_state(m)->pyEpoll_Type = (PyTypeObject *)pyEpoll_Type; Py_INCREF(pyEpoll_Type); PyModule_AddObject(m, "epoll", (PyObject *)get_select_state(m)->pyEpoll_Type); - - PyModule_AddIntMacro(m, EPOLLIN); - PyModule_AddIntMacro(m, EPOLLOUT); - PyModule_AddIntMacro(m, EPOLLPRI); - PyModule_AddIntMacro(m, EPOLLERR); - PyModule_AddIntMacro(m, EPOLLHUP); -#ifdef EPOLLRDHUP - /* Kernel 2.6.17 */ - PyModule_AddIntMacro(m, EPOLLRDHUP); -#endif - PyModule_AddIntMacro(m, EPOLLET); -#ifdef EPOLLONESHOT - /* Kernel 2.6.2+ */ - PyModule_AddIntMacro(m, EPOLLONESHOT); -#endif -#ifdef EPOLLEXCLUSIVE - PyModule_AddIntMacro(m, EPOLLEXCLUSIVE); -#endif - -#ifdef EPOLLRDNORM - PyModule_AddIntMacro(m, EPOLLRDNORM); -#endif -#ifdef EPOLLRDBAND - PyModule_AddIntMacro(m, EPOLLRDBAND); -#endif -#ifdef EPOLLWRNORM - PyModule_AddIntMacro(m, EPOLLWRNORM); -#endif -#ifdef EPOLLWRBAND - PyModule_AddIntMacro(m, EPOLLWRBAND); -#endif -#ifdef EPOLLMSG - PyModule_AddIntMacro(m, EPOLLMSG); -#endif - -#ifdef EPOLL_CLOEXEC - PyModule_AddIntMacro(m, EPOLL_CLOEXEC); -#endif -#endif /* HAVE_EPOLL */ - -#ifdef HAVE_KQUEUE + + PyModule_AddIntMacro(m, EPOLLIN); + PyModule_AddIntMacro(m, EPOLLOUT); + PyModule_AddIntMacro(m, EPOLLPRI); + PyModule_AddIntMacro(m, EPOLLERR); + PyModule_AddIntMacro(m, EPOLLHUP); +#ifdef EPOLLRDHUP + /* Kernel 2.6.17 */ + PyModule_AddIntMacro(m, EPOLLRDHUP); +#endif + PyModule_AddIntMacro(m, EPOLLET); +#ifdef EPOLLONESHOT + /* Kernel 2.6.2+ */ + PyModule_AddIntMacro(m, EPOLLONESHOT); +#endif +#ifdef EPOLLEXCLUSIVE + PyModule_AddIntMacro(m, EPOLLEXCLUSIVE); +#endif + +#ifdef EPOLLRDNORM + PyModule_AddIntMacro(m, EPOLLRDNORM); +#endif +#ifdef EPOLLRDBAND + PyModule_AddIntMacro(m, EPOLLRDBAND); +#endif +#ifdef EPOLLWRNORM + PyModule_AddIntMacro(m, EPOLLWRNORM); +#endif +#ifdef EPOLLWRBAND + PyModule_AddIntMacro(m, EPOLLWRBAND); +#endif +#ifdef EPOLLMSG + PyModule_AddIntMacro(m, EPOLLMSG); +#endif + +#ifdef EPOLL_CLOEXEC + PyModule_AddIntMacro(m, EPOLL_CLOEXEC); +#endif +#endif /* HAVE_EPOLL */ + +#ifdef HAVE_KQUEUE PyObject *kqueue_event_Type = PyType_FromSpec(&kqueue_event_Type_spec); if (kqueue_event_Type == NULL) - return NULL; + return NULL; get_select_state(m)->kqueue_event_Type = (PyTypeObject *)kqueue_event_Type; Py_INCREF(get_select_state(m)->kqueue_event_Type); PyModule_AddObject(m, "kevent", kqueue_event_Type); - + PyObject *kqueue_queue_Type = PyType_FromSpec(&kqueue_queue_Type_spec); if (kqueue_queue_Type == NULL) - return NULL; + return NULL; get_select_state(m)->kqueue_queue_Type = (PyTypeObject *)kqueue_queue_Type; Py_INCREF(get_select_state(m)->kqueue_queue_Type); PyModule_AddObject(m, "kqueue", kqueue_queue_Type); - - /* event filters */ - PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ); - PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE); -#ifdef EVFILT_AIO - PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO); -#endif -#ifdef EVFILT_VNODE - PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE); -#endif -#ifdef EVFILT_PROC - PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC); -#endif -#ifdef EVFILT_NETDEV - PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV); -#endif -#ifdef EVFILT_SIGNAL - PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL); -#endif - PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER); - - /* event flags */ - PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD); - PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE); - PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE); - PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE); - PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT); - PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR); - -#ifdef EV_SYSFLAGS - PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS); -#endif -#ifdef EV_FLAG1 - PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1); -#endif - - PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF); - PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR); - - /* READ WRITE filter flag */ -#ifdef NOTE_LOWAT - PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT); -#endif - - /* VNODE filter flags */ -#ifdef EVFILT_VNODE - PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE); - PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE); - PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND); - PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB); - PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK); - PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME); - PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE); -#endif - - /* PROC filter flags */ -#ifdef EVFILT_PROC - PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT); - PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK); - PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC); - PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK); - PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK); - - PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK); - PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD); - PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR); -#endif - - /* NETDEV filter flags */ -#ifdef EVFILT_NETDEV - PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP); - PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN); - PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV); -#endif - -#endif /* HAVE_KQUEUE */ - return m; -} + + /* event filters */ + PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ); + PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE); +#ifdef EVFILT_AIO + PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO); +#endif +#ifdef EVFILT_VNODE + PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE); +#endif +#ifdef EVFILT_PROC + PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC); +#endif +#ifdef EVFILT_NETDEV + PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV); +#endif +#ifdef EVFILT_SIGNAL + PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL); +#endif + PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER); + + /* event flags */ + PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD); + PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE); + PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE); + PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE); + PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT); + PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR); + +#ifdef EV_SYSFLAGS + PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS); +#endif +#ifdef EV_FLAG1 + PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1); +#endif + + PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF); + PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR); + + /* READ WRITE filter flag */ +#ifdef NOTE_LOWAT + PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT); +#endif + + /* VNODE filter flags */ +#ifdef EVFILT_VNODE + PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE); + PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE); + PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND); + PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB); + PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK); + PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME); + PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE); +#endif + + /* PROC filter flags */ +#ifdef EVFILT_PROC + PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT); + PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK); + PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC); + PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK); + PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK); + + PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK); + PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD); + PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR); +#endif + + /* NETDEV filter flags */ +#ifdef EVFILT_NETDEV + PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP); + PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN); + PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV); +#endif + +#endif /* HAVE_KQUEUE */ + return m; +} diff --git a/contrib/tools/python3/src/Modules/sha1module.c b/contrib/tools/python3/src/Modules/sha1module.c index 44fe8ef7b35..e809b14d314 100644 --- a/contrib/tools/python3/src/Modules/sha1module.c +++ b/contrib/tools/python3/src/Modules/sha1module.c @@ -1,562 +1,562 @@ -/* SHA1 module */ - -/* This module provides an interface to the SHA1 algorithm */ - -/* See below for information about the original code this module was - based upon. Additional work performed by: - - Andrew Kuchling (amk@amk.ca) - Greg Stein (gstein@lyra.org) - Trevor Perrin (trevp@trevp.net) - - Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) - Licensed to PSF under a Contributor Agreement. - -*/ - -/* SHA1 objects */ - -#include "Python.h" -#include "hashlib.h" -#include "pystrhex.h" - -/*[clinic input] -module _sha1 -class SHA1Type "SHA1object *" "&PyType_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3dc9a20d1becb759]*/ - -/* Some useful types */ - -#if SIZEOF_INT == 4 -typedef unsigned int SHA1_INT32; /* 32-bit integer */ -typedef long long SHA1_INT64; /* 64-bit integer */ -#else -/* not defined. compilation will die. */ -#endif - -/* The SHA1 block size and message digest sizes, in bytes */ - -#define SHA1_BLOCKSIZE 64 -#define SHA1_DIGESTSIZE 20 - -/* The structure for storing SHA1 info */ - -struct sha1_state { - SHA1_INT64 length; - SHA1_INT32 state[5], curlen; - unsigned char buf[SHA1_BLOCKSIZE]; -}; - -typedef struct { - PyObject_HEAD - - struct sha1_state hash_state; -} SHA1object; - -#include "clinic/sha1module.c.h" - -/* ------------------------------------------------------------------------ - * - * This code for the SHA1 algorithm was noted as public domain. The - * original headers are pasted below. - * - * Several changes have been made to make it more compatible with the - * Python environment and desired interface. - * - */ - -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * +/* SHA1 module */ + +/* This module provides an interface to the SHA1 algorithm */ + +/* See below for information about the original code this module was + based upon. Additional work performed by: + + Andrew Kuchling (amk@amk.ca) + Greg Stein (gstein@lyra.org) + Trevor Perrin (trevp@trevp.net) + + Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) + Licensed to PSF under a Contributor Agreement. + +*/ + +/* SHA1 objects */ + +#include "Python.h" +#include "hashlib.h" +#include "pystrhex.h" + +/*[clinic input] +module _sha1 +class SHA1Type "SHA1object *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3dc9a20d1becb759]*/ + +/* Some useful types */ + +#if SIZEOF_INT == 4 +typedef unsigned int SHA1_INT32; /* 32-bit integer */ +typedef long long SHA1_INT64; /* 64-bit integer */ +#else +/* not defined. compilation will die. */ +#endif + +/* The SHA1 block size and message digest sizes, in bytes */ + +#define SHA1_BLOCKSIZE 64 +#define SHA1_DIGESTSIZE 20 + +/* The structure for storing SHA1 info */ + +struct sha1_state { + SHA1_INT64 length; + SHA1_INT32 state[5], curlen; + unsigned char buf[SHA1_BLOCKSIZE]; +}; + +typedef struct { + PyObject_HEAD + + struct sha1_state hash_state; +} SHA1object; + +#include "clinic/sha1module.c.h" + +/* ------------------------------------------------------------------------ + * + * This code for the SHA1 algorithm was noted as public domain. The + * original headers are pasted below. + * + * Several changes have been made to make it more compatible with the + * Python environment and desired interface. + * + */ + +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * * Tom St Denis, tomstdenis@gmail.com, https://www.libtom.net - */ - -/* rotate the hard way (platform optimizations could be done) */ -#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) - -/* Endian Neutral macros that work on all platforms */ - -#define STORE32H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ - (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } - -#define LOAD32H(x, y) \ - { x = ((unsigned long)((y)[0] & 255)<<24) | \ - ((unsigned long)((y)[1] & 255)<<16) | \ - ((unsigned long)((y)[2] & 255)<<8) | \ - ((unsigned long)((y)[3] & 255)); } - -#define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } - - -/* SHA1 macros */ - -#define F0(x,y,z) (z ^ (x & (y ^ z))) -#define F1(x,y,z) (x ^ y ^ z) -#define F2(x,y,z) ((x & y) | (z & (x | y))) -#define F3(x,y,z) (x ^ y ^ z) - -static void sha1_compress(struct sha1_state *sha1, unsigned char *buf) -{ - SHA1_INT32 a,b,c,d,e,W[80],i; - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD32H(W[i], buf + (4*i)); - } - - /* copy state */ - a = sha1->state[0]; - b = sha1->state[1]; - c = sha1->state[2]; - d = sha1->state[3]; - e = sha1->state[4]; - - /* expand it */ - for (i = 16; i < 80; i++) { - W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); - } - - /* compress */ - /* round one */ - #define FF_0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); - #define FF_1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); - #define FF_2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); - #define FF_3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); - - for (i = 0; i < 20; ) { - FF_0(a,b,c,d,e,i++); - FF_0(e,a,b,c,d,i++); - FF_0(d,e,a,b,c,i++); - FF_0(c,d,e,a,b,i++); - FF_0(b,c,d,e,a,i++); - } - - /* round two */ - for (; i < 40; ) { - FF_1(a,b,c,d,e,i++); - FF_1(e,a,b,c,d,i++); - FF_1(d,e,a,b,c,i++); - FF_1(c,d,e,a,b,i++); - FF_1(b,c,d,e,a,i++); - } - - /* round three */ - for (; i < 60; ) { - FF_2(a,b,c,d,e,i++); - FF_2(e,a,b,c,d,i++); - FF_2(d,e,a,b,c,i++); - FF_2(c,d,e,a,b,i++); - FF_2(b,c,d,e,a,i++); - } - - /* round four */ - for (; i < 80; ) { - FF_3(a,b,c,d,e,i++); - FF_3(e,a,b,c,d,i++); - FF_3(d,e,a,b,c,i++); - FF_3(c,d,e,a,b,i++); - FF_3(b,c,d,e,a,i++); - } - - #undef FF_0 - #undef FF_1 - #undef FF_2 - #undef FF_3 - - /* store */ - sha1->state[0] = sha1->state[0] + a; - sha1->state[1] = sha1->state[1] + b; - sha1->state[2] = sha1->state[2] + c; - sha1->state[3] = sha1->state[3] + d; - sha1->state[4] = sha1->state[4] + e; -} - -/** - Initialize the hash state - @param sha1 The hash state you wish to initialize -*/ -static void -sha1_init(struct sha1_state *sha1) -{ - assert(sha1 != NULL); - sha1->state[0] = 0x67452301UL; - sha1->state[1] = 0xefcdab89UL; - sha1->state[2] = 0x98badcfeUL; - sha1->state[3] = 0x10325476UL; - sha1->state[4] = 0xc3d2e1f0UL; - sha1->curlen = 0; - sha1->length = 0; -} - -/** - Process a block of memory though the hash - @param sha1 The hash state - @param in The data to hash - @param inlen The length of the data (octets) -*/ -static void -sha1_process(struct sha1_state *sha1, - const unsigned char *in, Py_ssize_t inlen) -{ - Py_ssize_t n; - - assert(sha1 != NULL); - assert(in != NULL); - assert(sha1->curlen <= sizeof(sha1->buf)); - - while (inlen > 0) { - if (sha1->curlen == 0 && inlen >= SHA1_BLOCKSIZE) { - sha1_compress(sha1, (unsigned char *)in); - sha1->length += SHA1_BLOCKSIZE * 8; - in += SHA1_BLOCKSIZE; - inlen -= SHA1_BLOCKSIZE; - } else { - n = Py_MIN(inlen, (Py_ssize_t)(SHA1_BLOCKSIZE - sha1->curlen)); - memcpy(sha1->buf + sha1->curlen, in, (size_t)n); - sha1->curlen += (SHA1_INT32)n; - in += n; - inlen -= n; - if (sha1->curlen == SHA1_BLOCKSIZE) { - sha1_compress(sha1, sha1->buf); - sha1->length += 8*SHA1_BLOCKSIZE; - sha1->curlen = 0; - } - } - } -} - -/** - Terminate the hash to get the digest - @param sha1 The hash state - @param out [out] The destination of the hash (20 bytes) -*/ -static void -sha1_done(struct sha1_state *sha1, unsigned char *out) -{ - int i; - - assert(sha1 != NULL); - assert(out != NULL); - assert(sha1->curlen < sizeof(sha1->buf)); - - /* increase the length of the message */ - sha1->length += sha1->curlen * 8; - - /* append the '1' bit */ - sha1->buf[sha1->curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (sha1->curlen > 56) { - while (sha1->curlen < 64) { - sha1->buf[sha1->curlen++] = (unsigned char)0; - } - sha1_compress(sha1, sha1->buf); - sha1->curlen = 0; - } - + */ + +/* rotate the hard way (platform optimizations could be done) */ +#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +/* Endian Neutral macros that work on all platforms */ + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + + +/* SHA1 macros */ + +#define F0(x,y,z) (z ^ (x & (y ^ z))) +#define F1(x,y,z) (x ^ y ^ z) +#define F2(x,y,z) ((x & y) | (z & (x | y))) +#define F3(x,y,z) (x ^ y ^ z) + +static void sha1_compress(struct sha1_state *sha1, unsigned char *buf) +{ + SHA1_INT32 a,b,c,d,e,W[80],i; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* copy state */ + a = sha1->state[0]; + b = sha1->state[1]; + c = sha1->state[2]; + d = sha1->state[3]; + e = sha1->state[4]; + + /* expand it */ + for (i = 16; i < 80; i++) { + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } + + /* compress */ + /* round one */ + #define FF_0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); + #define FF_1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); + #define FF_2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); + #define FF_3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); + + for (i = 0; i < 20; ) { + FF_0(a,b,c,d,e,i++); + FF_0(e,a,b,c,d,i++); + FF_0(d,e,a,b,c,i++); + FF_0(c,d,e,a,b,i++); + FF_0(b,c,d,e,a,i++); + } + + /* round two */ + for (; i < 40; ) { + FF_1(a,b,c,d,e,i++); + FF_1(e,a,b,c,d,i++); + FF_1(d,e,a,b,c,i++); + FF_1(c,d,e,a,b,i++); + FF_1(b,c,d,e,a,i++); + } + + /* round three */ + for (; i < 60; ) { + FF_2(a,b,c,d,e,i++); + FF_2(e,a,b,c,d,i++); + FF_2(d,e,a,b,c,i++); + FF_2(c,d,e,a,b,i++); + FF_2(b,c,d,e,a,i++); + } + + /* round four */ + for (; i < 80; ) { + FF_3(a,b,c,d,e,i++); + FF_3(e,a,b,c,d,i++); + FF_3(d,e,a,b,c,i++); + FF_3(c,d,e,a,b,i++); + FF_3(b,c,d,e,a,i++); + } + + #undef FF_0 + #undef FF_1 + #undef FF_2 + #undef FF_3 + + /* store */ + sha1->state[0] = sha1->state[0] + a; + sha1->state[1] = sha1->state[1] + b; + sha1->state[2] = sha1->state[2] + c; + sha1->state[3] = sha1->state[3] + d; + sha1->state[4] = sha1->state[4] + e; +} + +/** + Initialize the hash state + @param sha1 The hash state you wish to initialize +*/ +static void +sha1_init(struct sha1_state *sha1) +{ + assert(sha1 != NULL); + sha1->state[0] = 0x67452301UL; + sha1->state[1] = 0xefcdab89UL; + sha1->state[2] = 0x98badcfeUL; + sha1->state[3] = 0x10325476UL; + sha1->state[4] = 0xc3d2e1f0UL; + sha1->curlen = 0; + sha1->length = 0; +} + +/** + Process a block of memory though the hash + @param sha1 The hash state + @param in The data to hash + @param inlen The length of the data (octets) +*/ +static void +sha1_process(struct sha1_state *sha1, + const unsigned char *in, Py_ssize_t inlen) +{ + Py_ssize_t n; + + assert(sha1 != NULL); + assert(in != NULL); + assert(sha1->curlen <= sizeof(sha1->buf)); + + while (inlen > 0) { + if (sha1->curlen == 0 && inlen >= SHA1_BLOCKSIZE) { + sha1_compress(sha1, (unsigned char *)in); + sha1->length += SHA1_BLOCKSIZE * 8; + in += SHA1_BLOCKSIZE; + inlen -= SHA1_BLOCKSIZE; + } else { + n = Py_MIN(inlen, (Py_ssize_t)(SHA1_BLOCKSIZE - sha1->curlen)); + memcpy(sha1->buf + sha1->curlen, in, (size_t)n); + sha1->curlen += (SHA1_INT32)n; + in += n; + inlen -= n; + if (sha1->curlen == SHA1_BLOCKSIZE) { + sha1_compress(sha1, sha1->buf); + sha1->length += 8*SHA1_BLOCKSIZE; + sha1->curlen = 0; + } + } + } +} + +/** + Terminate the hash to get the digest + @param sha1 The hash state + @param out [out] The destination of the hash (20 bytes) +*/ +static void +sha1_done(struct sha1_state *sha1, unsigned char *out) +{ + int i; + + assert(sha1 != NULL); + assert(out != NULL); + assert(sha1->curlen < sizeof(sha1->buf)); + + /* increase the length of the message */ + sha1->length += sha1->curlen * 8; + + /* append the '1' bit */ + sha1->buf[sha1->curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (sha1->curlen > 56) { + while (sha1->curlen < 64) { + sha1->buf[sha1->curlen++] = (unsigned char)0; + } + sha1_compress(sha1, sha1->buf); + sha1->curlen = 0; + } + /* pad up to 56 bytes of zeroes */ - while (sha1->curlen < 56) { - sha1->buf[sha1->curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64H(sha1->length, sha1->buf+56); - sha1_compress(sha1, sha1->buf); - - /* copy output */ - for (i = 0; i < 5; i++) { - STORE32H(sha1->state[i], out+(4*i)); - } -} - - -/* .Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ -/* .Revision: 1.10 $ */ -/* .Date: 2007/05/12 14:25:28 $ */ - -/* - * End of copied SHA1 code. - * - * ------------------------------------------------------------------------ - */ - -static PyTypeObject SHA1type; - - -static SHA1object * -newSHA1object(void) -{ - return (SHA1object *)PyObject_New(SHA1object, &SHA1type); -} - - -/* Internal methods for a hash object */ - -static void -SHA1_dealloc(PyObject *ptr) -{ - PyObject_Del(ptr); -} - - -/* External methods for a hash object */ - -/*[clinic input] -SHA1Type.copy - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -SHA1Type_copy_impl(SHA1object *self) -/*[clinic end generated code: output=b4e001264620f02a input=b7eae10df6f89b36]*/ -{ - SHA1object *newobj; - - if ((newobj = newSHA1object()) == NULL) - return NULL; - - newobj->hash_state = self->hash_state; - return (PyObject *)newobj; -} - -/*[clinic input] -SHA1Type.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -SHA1Type_digest_impl(SHA1object *self) -/*[clinic end generated code: output=2f05302a7aa2b5cb input=13824b35407444bd]*/ -{ - unsigned char digest[SHA1_DIGESTSIZE]; - struct sha1_state temp; - - temp = self->hash_state; - sha1_done(&temp, digest); - return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE); -} - -/*[clinic input] -SHA1Type.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -SHA1Type_hexdigest_impl(SHA1object *self) -/*[clinic end generated code: output=4161fd71e68c6659 input=97691055c0c74ab0]*/ -{ - unsigned char digest[SHA1_DIGESTSIZE]; - struct sha1_state temp; - - /* Get the raw (binary) digest value */ - temp = self->hash_state; - sha1_done(&temp, digest); - - return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE); -} - -/*[clinic input] -SHA1Type.update - - obj: object - / - -Update this hash object's state with the provided string. -[clinic start generated code]*/ - -static PyObject * -SHA1Type_update(SHA1object *self, PyObject *obj) -/*[clinic end generated code: output=d9902f0e5015e9ae input=aad8e07812edbba3]*/ -{ - Py_buffer buf; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - - sha1_process(&self->hash_state, buf.buf, buf.len); - - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyMethodDef SHA1_methods[] = { - SHA1TYPE_COPY_METHODDEF - SHA1TYPE_DIGEST_METHODDEF - SHA1TYPE_HEXDIGEST_METHODDEF - SHA1TYPE_UPDATE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -SHA1_get_block_size(PyObject *self, void *closure) -{ - return PyLong_FromLong(SHA1_BLOCKSIZE); -} - -static PyObject * -SHA1_get_name(PyObject *self, void *closure) -{ - return PyUnicode_FromStringAndSize("sha1", 4); -} - -static PyObject * -sha1_get_digest_size(PyObject *self, void *closure) -{ - return PyLong_FromLong(SHA1_DIGESTSIZE); -} - - -static PyGetSetDef SHA1_getseters[] = { - {"block_size", - (getter)SHA1_get_block_size, NULL, - NULL, - NULL}, - {"name", - (getter)SHA1_get_name, NULL, - NULL, - NULL}, - {"digest_size", - (getter)sha1_get_digest_size, NULL, - NULL, - NULL}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject SHA1type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha1.sha1", /*tp_name*/ - sizeof(SHA1object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA1_dealloc, /*tp_dealloc*/ + while (sha1->curlen < 56) { + sha1->buf[sha1->curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(sha1->length, sha1->buf+56); + sha1_compress(sha1, sha1->buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32H(sha1->state[i], out+(4*i)); + } +} + + +/* .Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ +/* .Revision: 1.10 $ */ +/* .Date: 2007/05/12 14:25:28 $ */ + +/* + * End of copied SHA1 code. + * + * ------------------------------------------------------------------------ + */ + +static PyTypeObject SHA1type; + + +static SHA1object * +newSHA1object(void) +{ + return (SHA1object *)PyObject_New(SHA1object, &SHA1type); +} + + +/* Internal methods for a hash object */ + +static void +SHA1_dealloc(PyObject *ptr) +{ + PyObject_Del(ptr); +} + + +/* External methods for a hash object */ + +/*[clinic input] +SHA1Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +SHA1Type_copy_impl(SHA1object *self) +/*[clinic end generated code: output=b4e001264620f02a input=b7eae10df6f89b36]*/ +{ + SHA1object *newobj; + + if ((newobj = newSHA1object()) == NULL) + return NULL; + + newobj->hash_state = self->hash_state; + return (PyObject *)newobj; +} + +/*[clinic input] +SHA1Type.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +SHA1Type_digest_impl(SHA1object *self) +/*[clinic end generated code: output=2f05302a7aa2b5cb input=13824b35407444bd]*/ +{ + unsigned char digest[SHA1_DIGESTSIZE]; + struct sha1_state temp; + + temp = self->hash_state; + sha1_done(&temp, digest); + return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE); +} + +/*[clinic input] +SHA1Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +SHA1Type_hexdigest_impl(SHA1object *self) +/*[clinic end generated code: output=4161fd71e68c6659 input=97691055c0c74ab0]*/ +{ + unsigned char digest[SHA1_DIGESTSIZE]; + struct sha1_state temp; + + /* Get the raw (binary) digest value */ + temp = self->hash_state; + sha1_done(&temp, digest); + + return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE); +} + +/*[clinic input] +SHA1Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +SHA1Type_update(SHA1object *self, PyObject *obj) +/*[clinic end generated code: output=d9902f0e5015e9ae input=aad8e07812edbba3]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + + sha1_process(&self->hash_state, buf.buf, buf.len); + + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyMethodDef SHA1_methods[] = { + SHA1TYPE_COPY_METHODDEF + SHA1TYPE_DIGEST_METHODDEF + SHA1TYPE_HEXDIGEST_METHODDEF + SHA1TYPE_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +SHA1_get_block_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(SHA1_BLOCKSIZE); +} + +static PyObject * +SHA1_get_name(PyObject *self, void *closure) +{ + return PyUnicode_FromStringAndSize("sha1", 4); +} + +static PyObject * +sha1_get_digest_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(SHA1_DIGESTSIZE); +} + + +static PyGetSetDef SHA1_getseters[] = { + {"block_size", + (getter)SHA1_get_block_size, NULL, + NULL, + NULL}, + {"name", + (getter)SHA1_get_name, NULL, + NULL, + NULL}, + {"digest_size", + (getter)sha1_get_digest_size, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject SHA1type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_sha1.sha1", /*tp_name*/ + sizeof(SHA1object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + SHA1_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA1_methods, /* tp_methods */ - NULL, /* tp_members */ - SHA1_getseters, /* tp_getset */ -}; - - -/* The single module-level function: new() */ - -/*[clinic input] -_sha1.sha1 - - string: object(c_default="NULL") = b'' + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + SHA1_methods, /* tp_methods */ + NULL, /* tp_members */ + SHA1_getseters, /* tp_getset */ +}; + + +/* The single module-level function: new() */ + +/*[clinic input] +_sha1.sha1 + + string: object(c_default="NULL") = b'' * usedforsecurity: bool = True - -Return a new SHA1 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * + +Return a new SHA1 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=6f8b3af05126e18e input=bd54b68e2bf36a8a]*/ -{ - SHA1object *new; - Py_buffer buf; - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA1object()) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha1_init(&new->hash_state); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha1_process(&new->hash_state, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - - -/* List of functions exported by this module */ - -static struct PyMethodDef SHA1_functions[] = { - _SHA1_SHA1_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ - -static struct PyModuleDef _sha1module = { - PyModuleDef_HEAD_INIT, - "_sha1", - NULL, - -1, - SHA1_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__sha1(void) -{ - PyObject *m; - +{ + SHA1object *new; + Py_buffer buf; + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newSHA1object()) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + sha1_init(&new->hash_state); + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + sha1_process(&new->hash_state, buf.buf, buf.len); + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + + +/* List of functions exported by this module */ + +static struct PyMethodDef SHA1_functions[] = { + _SHA1_SHA1_METHODDEF + {NULL, NULL} /* Sentinel */ +}; + + +/* Initialize this module. */ + +static struct PyModuleDef _sha1module = { + PyModuleDef_HEAD_INIT, + "_sha1", + NULL, + -1, + SHA1_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__sha1(void) +{ + PyObject *m; + Py_SET_TYPE(&SHA1type, &PyType_Type); if (PyType_Ready(&SHA1type) < 0) { - return NULL; + return NULL; } - - m = PyModule_Create(&_sha1module); + + m = PyModule_Create(&_sha1module); if (m == NULL) { - return NULL; + return NULL; } - - Py_INCREF((PyObject *)&SHA1type); - PyModule_AddObject(m, "SHA1Type", (PyObject *)&SHA1type); - return m; -} + + Py_INCREF((PyObject *)&SHA1type); + PyModule_AddObject(m, "SHA1Type", (PyObject *)&SHA1type); + return m; +} diff --git a/contrib/tools/python3/src/Modules/sha256module.c b/contrib/tools/python3/src/Modules/sha256module.c index 9b885c72553..1012fbdc245 100644 --- a/contrib/tools/python3/src/Modules/sha256module.c +++ b/contrib/tools/python3/src/Modules/sha256module.c @@ -1,723 +1,723 @@ -/* SHA256 module */ - -/* This module provides an interface to NIST's SHA-256 and SHA-224 Algorithms */ - -/* See below for information about the original code this module was - based upon. Additional work performed by: - - Andrew Kuchling (amk@amk.ca) - Greg Stein (gstein@lyra.org) - Trevor Perrin (trevp@trevp.net) - - Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) - Licensed to PSF under a Contributor Agreement. - -*/ - -/* SHA objects */ - -#include "Python.h" +/* SHA256 module */ + +/* This module provides an interface to NIST's SHA-256 and SHA-224 Algorithms */ + +/* See below for information about the original code this module was + based upon. Additional work performed by: + + Andrew Kuchling (amk@amk.ca) + Greg Stein (gstein@lyra.org) + Trevor Perrin (trevp@trevp.net) + + Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) + Licensed to PSF under a Contributor Agreement. + +*/ + +/* SHA objects */ + +#include "Python.h" #include "pycore_byteswap.h" // _Py_bswap32() #include "structmember.h" // PyMemberDef -#include "hashlib.h" -#include "pystrhex.h" - -/*[clinic input] -module _sha256 -class SHA256Type "SHAobject *" "&PyType_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=71a39174d4f0a744]*/ - -/* Some useful types */ - -typedef unsigned char SHA_BYTE; +#include "hashlib.h" +#include "pystrhex.h" + +/*[clinic input] +module _sha256 +class SHA256Type "SHAobject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=71a39174d4f0a744]*/ + +/* Some useful types */ + +typedef unsigned char SHA_BYTE; typedef uint32_t SHA_INT32; /* 32-bit integer */ - -/* The SHA block size and message digest sizes, in bytes */ - -#define SHA_BLOCKSIZE 64 -#define SHA_DIGESTSIZE 32 - -/* The structure for storing SHA info */ - -typedef struct { - PyObject_HEAD - SHA_INT32 digest[8]; /* Message digest */ - SHA_INT32 count_lo, count_hi; /* 64-bit bit count */ - SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ - int local; /* unprocessed amount in data */ - int digestsize; -} SHAobject; - -#include "clinic/sha256module.c.h" - -/* When run on a little-endian CPU we need to perform byte reversal on an - array of longwords. */ - -#if PY_LITTLE_ENDIAN -static void longReverse(SHA_INT32 *buffer, int byteCount) -{ - byteCount /= sizeof(*buffer); + +/* The SHA block size and message digest sizes, in bytes */ + +#define SHA_BLOCKSIZE 64 +#define SHA_DIGESTSIZE 32 + +/* The structure for storing SHA info */ + +typedef struct { + PyObject_HEAD + SHA_INT32 digest[8]; /* Message digest */ + SHA_INT32 count_lo, count_hi; /* 64-bit bit count */ + SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ + int local; /* unprocessed amount in data */ + int digestsize; +} SHAobject; + +#include "clinic/sha256module.c.h" + +/* When run on a little-endian CPU we need to perform byte reversal on an + array of longwords. */ + +#if PY_LITTLE_ENDIAN +static void longReverse(SHA_INT32 *buffer, int byteCount) +{ + byteCount /= sizeof(*buffer); for (; byteCount--; buffer++) { *buffer = _Py_bswap32(*buffer); - } -} -#endif - -static void SHAcopy(SHAobject *src, SHAobject *dest) -{ - dest->local = src->local; - dest->digestsize = src->digestsize; - dest->count_lo = src->count_lo; - dest->count_hi = src->count_hi; - memcpy(dest->digest, src->digest, sizeof(src->digest)); - memcpy(dest->data, src->data, sizeof(src->data)); -} - - -/* ------------------------------------------------------------------------ - * - * This code for the SHA-256 algorithm was noted as public domain. The - * original headers are pasted below. - * - * Several changes have been made to make it more compatible with the - * Python environment and desired interface. - * - */ - -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * + } +} +#endif + +static void SHAcopy(SHAobject *src, SHAobject *dest) +{ + dest->local = src->local; + dest->digestsize = src->digestsize; + dest->count_lo = src->count_lo; + dest->count_hi = src->count_hi; + memcpy(dest->digest, src->digest, sizeof(src->digest)); + memcpy(dest->data, src->data, sizeof(src->data)); +} + + +/* ------------------------------------------------------------------------ + * + * This code for the SHA-256 algorithm was noted as public domain. The + * original headers are pasted below. + * + * Several changes have been made to make it more compatible with the + * Python environment and desired interface. + * + */ + +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * * Tom St Denis, tomstdenis@iahu.ca, https://www.libtom.net - */ - - -/* SHA256 by Tom St Denis */ - -/* Various logical functions */ -#define ROR(x, y)\ -( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \ -((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) ROR((x),(n)) -#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) - - -static void -sha_transform(SHAobject *sha_info) -{ - int i; - SHA_INT32 S[8], W[64], t0, t1; - - memcpy(W, sha_info->data, sizeof(sha_info->data)); -#if PY_LITTLE_ENDIAN - longReverse(W, (int)sizeof(sha_info->data)); -#endif - - for (i = 16; i < 64; ++i) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } - for (i = 0; i < 8; ++i) { - S[i] = sha_info->digest[i]; - } - - /* Compress */ -#define RND(a,b,c,d,e,f,g,h,i,ki) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; - - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); - -#undef RND - - /* feedback */ - for (i = 0; i < 8; i++) { - sha_info->digest[i] = sha_info->digest[i] + S[i]; - } - -} - - - -/* initialize the SHA digest */ - -static void -sha_init(SHAobject *sha_info) -{ - sha_info->digest[0] = 0x6A09E667L; - sha_info->digest[1] = 0xBB67AE85L; - sha_info->digest[2] = 0x3C6EF372L; - sha_info->digest[3] = 0xA54FF53AL; - sha_info->digest[4] = 0x510E527FL; - sha_info->digest[5] = 0x9B05688CL; - sha_info->digest[6] = 0x1F83D9ABL; - sha_info->digest[7] = 0x5BE0CD19L; - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - sha_info->digestsize = 32; -} - -static void -sha224_init(SHAobject *sha_info) -{ - sha_info->digest[0] = 0xc1059ed8L; - sha_info->digest[1] = 0x367cd507L; - sha_info->digest[2] = 0x3070dd17L; - sha_info->digest[3] = 0xf70e5939L; - sha_info->digest[4] = 0xffc00b31L; - sha_info->digest[5] = 0x68581511L; - sha_info->digest[6] = 0x64f98fa7L; - sha_info->digest[7] = 0xbefa4fa4L; - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - sha_info->digestsize = 28; -} - - -/* update the SHA digest */ - -static void -sha_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count) -{ - Py_ssize_t i; - SHA_INT32 clo; - - clo = sha_info->count_lo + ((SHA_INT32) count << 3); - if (clo < sha_info->count_lo) { - ++sha_info->count_hi; - } - sha_info->count_lo = clo; - sha_info->count_hi += (SHA_INT32) count >> 29; - if (sha_info->local) { - i = SHA_BLOCKSIZE - sha_info->local; - if (i > count) { - i = count; - } - memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i); - count -= i; - buffer += i; - sha_info->local += (int)i; - if (sha_info->local == SHA_BLOCKSIZE) { - sha_transform(sha_info); - } - else { - return; - } - } - while (count >= SHA_BLOCKSIZE) { - memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); - buffer += SHA_BLOCKSIZE; - count -= SHA_BLOCKSIZE; - sha_transform(sha_info); - } - memcpy(sha_info->data, buffer, count); - sha_info->local = (int)count; -} - -/* finish computing the SHA digest */ - -static void -sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) -{ - int count; - SHA_INT32 lo_bit_count, hi_bit_count; - - lo_bit_count = sha_info->count_lo; - hi_bit_count = sha_info->count_hi; - count = (int) ((lo_bit_count >> 3) & 0x3f); - ((SHA_BYTE *) sha_info->data)[count++] = 0x80; - if (count > SHA_BLOCKSIZE - 8) { - memset(((SHA_BYTE *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - count); - sha_transform(sha_info); - memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8); - } - else { - memset(((SHA_BYTE *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - 8 - count); - } - - /* GJS: note that we add the hi/lo in big-endian. sha_transform will - swap these values into host-order. */ - sha_info->data[56] = (hi_bit_count >> 24) & 0xff; - sha_info->data[57] = (hi_bit_count >> 16) & 0xff; - sha_info->data[58] = (hi_bit_count >> 8) & 0xff; - sha_info->data[59] = (hi_bit_count >> 0) & 0xff; - sha_info->data[60] = (lo_bit_count >> 24) & 0xff; - sha_info->data[61] = (lo_bit_count >> 16) & 0xff; - sha_info->data[62] = (lo_bit_count >> 8) & 0xff; - sha_info->data[63] = (lo_bit_count >> 0) & 0xff; - sha_transform(sha_info); - digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); - digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); - digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); - digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff); - digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); - digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); - digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); - digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff); - digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); - digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); - digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); - digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff); - digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); - digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); - digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); - digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff); - digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); - digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); - digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); - digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff); - digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff); - digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff); - digest[22] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff); - digest[23] = (unsigned char) ((sha_info->digest[5] ) & 0xff); - digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff); - digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff); - digest[26] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff); - digest[27] = (unsigned char) ((sha_info->digest[6] ) & 0xff); - digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff); - digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff); - digest[30] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff); - digest[31] = (unsigned char) ((sha_info->digest[7] ) & 0xff); -} - -/* - * End of copied SHA code. - * - * ------------------------------------------------------------------------ - */ - -static PyTypeObject SHA224type; -static PyTypeObject SHA256type; - - -static SHAobject * -newSHA224object(void) -{ - return (SHAobject *)PyObject_New(SHAobject, &SHA224type); -} - -static SHAobject * -newSHA256object(void) -{ - return (SHAobject *)PyObject_New(SHAobject, &SHA256type); -} - -/* Internal methods for a hash object */ - -static void -SHA_dealloc(PyObject *ptr) -{ - PyObject_Del(ptr); -} - - -/* External methods for a hash object */ - -/*[clinic input] -SHA256Type.copy - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -SHA256Type_copy_impl(SHAobject *self) -/*[clinic end generated code: output=1a8bbd66a0c9c168 input=f58840a618d4f2a7]*/ -{ - SHAobject *newobj; - + */ + + +/* SHA256 by Tom St Denis */ + +/* Various logical functions */ +#define ROR(x, y)\ +( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \ +((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + + +static void +sha_transform(SHAobject *sha_info) +{ + int i; + SHA_INT32 S[8], W[64], t0, t1; + + memcpy(W, sha_info->data, sizeof(sha_info->data)); +#if PY_LITTLE_ENDIAN + longReverse(W, (int)sizeof(sha_info->data)); +#endif + + for (i = 16; i < 64; ++i) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + for (i = 0; i < 8; ++i) { + S[i] = sha_info->digest[i]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); + +#undef RND + + /* feedback */ + for (i = 0; i < 8; i++) { + sha_info->digest[i] = sha_info->digest[i] + S[i]; + } + +} + + + +/* initialize the SHA digest */ + +static void +sha_init(SHAobject *sha_info) +{ + sha_info->digest[0] = 0x6A09E667L; + sha_info->digest[1] = 0xBB67AE85L; + sha_info->digest[2] = 0x3C6EF372L; + sha_info->digest[3] = 0xA54FF53AL; + sha_info->digest[4] = 0x510E527FL; + sha_info->digest[5] = 0x9B05688CL; + sha_info->digest[6] = 0x1F83D9ABL; + sha_info->digest[7] = 0x5BE0CD19L; + sha_info->count_lo = 0L; + sha_info->count_hi = 0L; + sha_info->local = 0; + sha_info->digestsize = 32; +} + +static void +sha224_init(SHAobject *sha_info) +{ + sha_info->digest[0] = 0xc1059ed8L; + sha_info->digest[1] = 0x367cd507L; + sha_info->digest[2] = 0x3070dd17L; + sha_info->digest[3] = 0xf70e5939L; + sha_info->digest[4] = 0xffc00b31L; + sha_info->digest[5] = 0x68581511L; + sha_info->digest[6] = 0x64f98fa7L; + sha_info->digest[7] = 0xbefa4fa4L; + sha_info->count_lo = 0L; + sha_info->count_hi = 0L; + sha_info->local = 0; + sha_info->digestsize = 28; +} + + +/* update the SHA digest */ + +static void +sha_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count) +{ + Py_ssize_t i; + SHA_INT32 clo; + + clo = sha_info->count_lo + ((SHA_INT32) count << 3); + if (clo < sha_info->count_lo) { + ++sha_info->count_hi; + } + sha_info->count_lo = clo; + sha_info->count_hi += (SHA_INT32) count >> 29; + if (sha_info->local) { + i = SHA_BLOCKSIZE - sha_info->local; + if (i > count) { + i = count; + } + memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i); + count -= i; + buffer += i; + sha_info->local += (int)i; + if (sha_info->local == SHA_BLOCKSIZE) { + sha_transform(sha_info); + } + else { + return; + } + } + while (count >= SHA_BLOCKSIZE) { + memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); + buffer += SHA_BLOCKSIZE; + count -= SHA_BLOCKSIZE; + sha_transform(sha_info); + } + memcpy(sha_info->data, buffer, count); + sha_info->local = (int)count; +} + +/* finish computing the SHA digest */ + +static void +sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) +{ + int count; + SHA_INT32 lo_bit_count, hi_bit_count; + + lo_bit_count = sha_info->count_lo; + hi_bit_count = sha_info->count_hi; + count = (int) ((lo_bit_count >> 3) & 0x3f); + ((SHA_BYTE *) sha_info->data)[count++] = 0x80; + if (count > SHA_BLOCKSIZE - 8) { + memset(((SHA_BYTE *) sha_info->data) + count, 0, + SHA_BLOCKSIZE - count); + sha_transform(sha_info); + memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8); + } + else { + memset(((SHA_BYTE *) sha_info->data) + count, 0, + SHA_BLOCKSIZE - 8 - count); + } + + /* GJS: note that we add the hi/lo in big-endian. sha_transform will + swap these values into host-order. */ + sha_info->data[56] = (hi_bit_count >> 24) & 0xff; + sha_info->data[57] = (hi_bit_count >> 16) & 0xff; + sha_info->data[58] = (hi_bit_count >> 8) & 0xff; + sha_info->data[59] = (hi_bit_count >> 0) & 0xff; + sha_info->data[60] = (lo_bit_count >> 24) & 0xff; + sha_info->data[61] = (lo_bit_count >> 16) & 0xff; + sha_info->data[62] = (lo_bit_count >> 8) & 0xff; + sha_info->data[63] = (lo_bit_count >> 0) & 0xff; + sha_transform(sha_info); + digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); + digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); + digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); + digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff); + digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); + digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); + digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); + digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff); + digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); + digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); + digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); + digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff); + digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); + digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); + digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); + digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff); + digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); + digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); + digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); + digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff); + digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff); + digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff); + digest[22] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff); + digest[23] = (unsigned char) ((sha_info->digest[5] ) & 0xff); + digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff); + digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff); + digest[26] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff); + digest[27] = (unsigned char) ((sha_info->digest[6] ) & 0xff); + digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff); + digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff); + digest[30] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff); + digest[31] = (unsigned char) ((sha_info->digest[7] ) & 0xff); +} + +/* + * End of copied SHA code. + * + * ------------------------------------------------------------------------ + */ + +static PyTypeObject SHA224type; +static PyTypeObject SHA256type; + + +static SHAobject * +newSHA224object(void) +{ + return (SHAobject *)PyObject_New(SHAobject, &SHA224type); +} + +static SHAobject * +newSHA256object(void) +{ + return (SHAobject *)PyObject_New(SHAobject, &SHA256type); +} + +/* Internal methods for a hash object */ + +static void +SHA_dealloc(PyObject *ptr) +{ + PyObject_Del(ptr); +} + + +/* External methods for a hash object */ + +/*[clinic input] +SHA256Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +SHA256Type_copy_impl(SHAobject *self) +/*[clinic end generated code: output=1a8bbd66a0c9c168 input=f58840a618d4f2a7]*/ +{ + SHAobject *newobj; + if (Py_IS_TYPE(self, &SHA256type)) { - if ( (newobj = newSHA256object())==NULL) - return NULL; - } else { - if ( (newobj = newSHA224object())==NULL) - return NULL; - } - - SHAcopy(self, newobj); - return (PyObject *)newobj; -} - -/*[clinic input] -SHA256Type.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -SHA256Type_digest_impl(SHAobject *self) -/*[clinic end generated code: output=46616a5e909fbc3d input=f1f4cfea5cbde35c]*/ -{ - unsigned char digest[SHA_DIGESTSIZE]; - SHAobject temp; - - SHAcopy(self, &temp); - sha_final(digest, &temp); - return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); -} - -/*[clinic input] -SHA256Type.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -SHA256Type_hexdigest_impl(SHAobject *self) -/*[clinic end generated code: output=725f8a7041ae97f3 input=0cc4c714693010d1]*/ -{ - unsigned char digest[SHA_DIGESTSIZE]; - SHAobject temp; - - /* Get the raw (binary) digest value */ - SHAcopy(self, &temp); - sha_final(digest, &temp); - - return _Py_strhex((const char *)digest, self->digestsize); -} - -/*[clinic input] -SHA256Type.update - - obj: object - / - -Update this hash object's state with the provided string. -[clinic start generated code]*/ - -static PyObject * -SHA256Type_update(SHAobject *self, PyObject *obj) -/*[clinic end generated code: output=0967fb2860c66af7 input=b2d449d5b30f0f5a]*/ -{ - Py_buffer buf; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - - sha_update(self, buf.buf, buf.len); - - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyMethodDef SHA_methods[] = { - SHA256TYPE_COPY_METHODDEF - SHA256TYPE_DIGEST_METHODDEF - SHA256TYPE_HEXDIGEST_METHODDEF - SHA256TYPE_UPDATE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -SHA256_get_block_size(PyObject *self, void *closure) -{ - return PyLong_FromLong(SHA_BLOCKSIZE); -} - -static PyObject * -SHA256_get_name(PyObject *self, void *closure) -{ - if (((SHAobject *)self)->digestsize == 32) - return PyUnicode_FromStringAndSize("sha256", 6); - else - return PyUnicode_FromStringAndSize("sha224", 6); -} - -static PyGetSetDef SHA_getseters[] = { - {"block_size", - (getter)SHA256_get_block_size, NULL, - NULL, - NULL}, - {"name", - (getter)SHA256_get_name, NULL, - NULL, - NULL}, - {NULL} /* Sentinel */ -}; - -static PyMemberDef SHA_members[] = { - {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject SHA224type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha256.sha224", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA_dealloc, /*tp_dealloc*/ + if ( (newobj = newSHA256object())==NULL) + return NULL; + } else { + if ( (newobj = newSHA224object())==NULL) + return NULL; + } + + SHAcopy(self, newobj); + return (PyObject *)newobj; +} + +/*[clinic input] +SHA256Type.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +SHA256Type_digest_impl(SHAobject *self) +/*[clinic end generated code: output=46616a5e909fbc3d input=f1f4cfea5cbde35c]*/ +{ + unsigned char digest[SHA_DIGESTSIZE]; + SHAobject temp; + + SHAcopy(self, &temp); + sha_final(digest, &temp); + return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); +} + +/*[clinic input] +SHA256Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +SHA256Type_hexdigest_impl(SHAobject *self) +/*[clinic end generated code: output=725f8a7041ae97f3 input=0cc4c714693010d1]*/ +{ + unsigned char digest[SHA_DIGESTSIZE]; + SHAobject temp; + + /* Get the raw (binary) digest value */ + SHAcopy(self, &temp); + sha_final(digest, &temp); + + return _Py_strhex((const char *)digest, self->digestsize); +} + +/*[clinic input] +SHA256Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +SHA256Type_update(SHAobject *self, PyObject *obj) +/*[clinic end generated code: output=0967fb2860c66af7 input=b2d449d5b30f0f5a]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + + sha_update(self, buf.buf, buf.len); + + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyMethodDef SHA_methods[] = { + SHA256TYPE_COPY_METHODDEF + SHA256TYPE_DIGEST_METHODDEF + SHA256TYPE_HEXDIGEST_METHODDEF + SHA256TYPE_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +SHA256_get_block_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(SHA_BLOCKSIZE); +} + +static PyObject * +SHA256_get_name(PyObject *self, void *closure) +{ + if (((SHAobject *)self)->digestsize == 32) + return PyUnicode_FromStringAndSize("sha256", 6); + else + return PyUnicode_FromStringAndSize("sha224", 6); +} + +static PyGetSetDef SHA_getseters[] = { + {"block_size", + (getter)SHA256_get_block_size, NULL, + NULL, + NULL}, + {"name", + (getter)SHA256_get_name, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + +static PyMemberDef SHA_members[] = { + {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject SHA224type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_sha256.sha224", /*tp_name*/ + sizeof(SHAobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + SHA_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ -}; - -static PyTypeObject SHA256type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha256.sha256", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA_dealloc, /*tp_dealloc*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + SHA_methods, /* tp_methods */ + SHA_members, /* tp_members */ + SHA_getseters, /* tp_getset */ +}; + +static PyTypeObject SHA256type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_sha256.sha256", /*tp_name*/ + sizeof(SHAobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + SHA_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ -}; - - -/* The single module-level function: new() */ - -/*[clinic input] -_sha256.sha256 - - string: object(c_default="NULL") = b'' + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + SHA_methods, /* tp_methods */ + SHA_members, /* tp_members */ + SHA_getseters, /* tp_getset */ +}; + + +/* The single module-level function: new() */ + +/*[clinic input] +_sha256.sha256 + + string: object(c_default="NULL") = b'' * usedforsecurity: bool = True - -Return a new SHA-256 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * + +Return a new SHA-256 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * _sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=a1de327e8e1185cf input=9be86301aeb14ea5]*/ -{ - SHAobject *new; - Py_buffer buf; - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA256object()) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - -/*[clinic input] -_sha256.sha224 - - string: object(c_default="NULL") = b'' +{ + SHAobject *new; + Py_buffer buf; + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newSHA256object()) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + sha_init(new); + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + sha_update(new, buf.buf, buf.len); + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + +/*[clinic input] +_sha256.sha224 + + string: object(c_default="NULL") = b'' * usedforsecurity: bool = True - -Return a new SHA-224 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * + +Return a new SHA-224 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * _sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=08be6b36569bc69c input=9fcfb46e460860ac]*/ -{ - SHAobject *new; - Py_buffer buf; - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA224object()) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha224_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - - -/* List of functions exported by this module */ - -static struct PyMethodDef SHA_functions[] = { - _SHA256_SHA256_METHODDEF - _SHA256_SHA224_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ - -static struct PyModuleDef _sha256module = { - PyModuleDef_HEAD_INIT, - "_sha256", - NULL, - -1, - SHA_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__sha256(void) -{ - PyObject *m; - +{ + SHAobject *new; + Py_buffer buf; + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newSHA224object()) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + sha224_init(new); + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + sha_update(new, buf.buf, buf.len); + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + + +/* List of functions exported by this module */ + +static struct PyMethodDef SHA_functions[] = { + _SHA256_SHA256_METHODDEF + _SHA256_SHA224_METHODDEF + {NULL, NULL} /* Sentinel */ +}; + + +/* Initialize this module. */ + +static struct PyModuleDef _sha256module = { + PyModuleDef_HEAD_INIT, + "_sha256", + NULL, + -1, + SHA_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__sha256(void) +{ + PyObject *m; + Py_SET_TYPE(&SHA224type, &PyType_Type); if (PyType_Ready(&SHA224type) < 0) { - return NULL; + return NULL; } Py_SET_TYPE(&SHA256type, &PyType_Type); if (PyType_Ready(&SHA256type) < 0) { - return NULL; + return NULL; } - - m = PyModule_Create(&_sha256module); - if (m == NULL) - return NULL; - - Py_INCREF((PyObject *)&SHA224type); - PyModule_AddObject(m, "SHA224Type", (PyObject *)&SHA224type); - Py_INCREF((PyObject *)&SHA256type); - PyModule_AddObject(m, "SHA256Type", (PyObject *)&SHA256type); - return m; - -} + + m = PyModule_Create(&_sha256module); + if (m == NULL) + return NULL; + + Py_INCREF((PyObject *)&SHA224type); + PyModule_AddObject(m, "SHA224Type", (PyObject *)&SHA224type); + Py_INCREF((PyObject *)&SHA256type); + PyModule_AddObject(m, "SHA256Type", (PyObject *)&SHA256type); + return m; + +} diff --git a/contrib/tools/python3/src/Modules/sha512module.c b/contrib/tools/python3/src/Modules/sha512module.c index 831160c324d..fee3b46afb9 100644 --- a/contrib/tools/python3/src/Modules/sha512module.c +++ b/contrib/tools/python3/src/Modules/sha512module.c @@ -1,780 +1,780 @@ -/* SHA512 module */ - -/* This module provides an interface to NIST's SHA-512 and SHA-384 Algorithms */ - -/* See below for information about the original code this module was - based upon. Additional work performed by: - - Andrew Kuchling (amk@amk.ca) - Greg Stein (gstein@lyra.org) - Trevor Perrin (trevp@trevp.net) - - Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) - Licensed to PSF under a Contributor Agreement. - -*/ - -/* SHA objects */ - -#include "Python.h" +/* SHA512 module */ + +/* This module provides an interface to NIST's SHA-512 and SHA-384 Algorithms */ + +/* See below for information about the original code this module was + based upon. Additional work performed by: + + Andrew Kuchling (amk@amk.ca) + Greg Stein (gstein@lyra.org) + Trevor Perrin (trevp@trevp.net) + + Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) + Licensed to PSF under a Contributor Agreement. + +*/ + +/* SHA objects */ + +#include "Python.h" #include "pycore_byteswap.h" // _Py_bswap32() #include "structmember.h" // PyMemberDef -#include "hashlib.h" -#include "pystrhex.h" - -/*[clinic input] -module _sha512 -class SHA512Type "SHAobject *" "&PyType_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81a3ccde92bcfe8d]*/ - -/* Some useful types */ - -typedef unsigned char SHA_BYTE; +#include "hashlib.h" +#include "pystrhex.h" + +/*[clinic input] +module _sha512 +class SHA512Type "SHAobject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81a3ccde92bcfe8d]*/ + +/* Some useful types */ + +typedef unsigned char SHA_BYTE; typedef uint32_t SHA_INT32; /* 32-bit integer */ typedef uint64_t SHA_INT64; /* 64-bit integer */ - -/* The SHA block size and message digest sizes, in bytes */ - -#define SHA_BLOCKSIZE 128 -#define SHA_DIGESTSIZE 64 - -/* The structure for storing SHA info */ - -typedef struct { - PyObject_HEAD - SHA_INT64 digest[8]; /* Message digest */ - SHA_INT32 count_lo, count_hi; /* 64-bit bit count */ - SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ - int local; /* unprocessed amount in data */ - int digestsize; -} SHAobject; - -#include "clinic/sha512module.c.h" - -/* When run on a little-endian CPU we need to perform byte reversal on an - array of longwords. */ - -#if PY_LITTLE_ENDIAN -static void longReverse(SHA_INT64 *buffer, int byteCount) -{ - byteCount /= sizeof(*buffer); + +/* The SHA block size and message digest sizes, in bytes */ + +#define SHA_BLOCKSIZE 128 +#define SHA_DIGESTSIZE 64 + +/* The structure for storing SHA info */ + +typedef struct { + PyObject_HEAD + SHA_INT64 digest[8]; /* Message digest */ + SHA_INT32 count_lo, count_hi; /* 64-bit bit count */ + SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ + int local; /* unprocessed amount in data */ + int digestsize; +} SHAobject; + +#include "clinic/sha512module.c.h" + +/* When run on a little-endian CPU we need to perform byte reversal on an + array of longwords. */ + +#if PY_LITTLE_ENDIAN +static void longReverse(SHA_INT64 *buffer, int byteCount) +{ + byteCount /= sizeof(*buffer); for (; byteCount--; buffer++) { *buffer = _Py_bswap64(*buffer); - } -} -#endif - -static void SHAcopy(SHAobject *src, SHAobject *dest) -{ - dest->local = src->local; - dest->digestsize = src->digestsize; - dest->count_lo = src->count_lo; - dest->count_hi = src->count_hi; - memcpy(dest->digest, src->digest, sizeof(src->digest)); - memcpy(dest->data, src->data, sizeof(src->data)); -} - - -/* ------------------------------------------------------------------------ - * - * This code for the SHA-512 algorithm was noted as public domain. The - * original headers are pasted below. - * - * Several changes have been made to make it more compatible with the - * Python environment and desired interface. - * - */ - -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * + } +} +#endif + +static void SHAcopy(SHAobject *src, SHAobject *dest) +{ + dest->local = src->local; + dest->digestsize = src->digestsize; + dest->count_lo = src->count_lo; + dest->count_hi = src->count_hi; + memcpy(dest->digest, src->digest, sizeof(src->digest)); + memcpy(dest->data, src->data, sizeof(src->data)); +} + + +/* ------------------------------------------------------------------------ + * + * This code for the SHA-512 algorithm was noted as public domain. The + * original headers are pasted below. + * + * Several changes have been made to make it more compatible with the + * Python environment and desired interface. + * + */ + +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * * Tom St Denis, tomstdenis@iahu.ca, https://www.libtom.net - */ - - -/* SHA512 by Tom St Denis */ - -/* Various logical functions */ -#define ROR64(x, y) \ - ( ((((x) & 0xFFFFFFFFFFFFFFFFULL)>>((unsigned long long)(y) & 63)) | \ - ((x)<<((unsigned long long)(64-((y) & 63))))) & 0xFFFFFFFFFFFFFFFFULL) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) ROR64((x),(n)) -#define R(x, n) (((x) & 0xFFFFFFFFFFFFFFFFULL) >> ((unsigned long long)n)) -#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) -#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) -#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) -#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) - - -static void -sha512_transform(SHAobject *sha_info) -{ - int i; - SHA_INT64 S[8], W[80], t0, t1; - - memcpy(W, sha_info->data, sizeof(sha_info->data)); -#if PY_LITTLE_ENDIAN - longReverse(W, (int)sizeof(sha_info->data)); -#endif - - for (i = 16; i < 80; ++i) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } - for (i = 0; i < 8; ++i) { - S[i] = sha_info->digest[i]; - } - - /* Compress */ -#define RND(a,b,c,d,e,f,g,h,i,ki) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; - - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98d728ae22ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x7137449123ef65cdULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcfec4d3b2fULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba58189dbbcULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25bf348b538ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1b605d019ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4af194f9bULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5da6d8118ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98a3030242ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b0145706fbeULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be4ee4b28cULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3d5ffb4e2ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74f27b896fULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe3b1696b1ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a725c71235ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174cf692694ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c19ef14ad2ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786384f25e3ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc68b8cd5b5ULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc77ac9c65ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f592b0275ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa6ea6e483ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dcbd41fbd4ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da831153b5ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152ee66dfabULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d2db43210ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c898fb213fULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7beef0ee4ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf33da88fc2ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147930aa725ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351e003826fULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x142929670a0e6e70ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a8546d22ffcULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b21385c26c926ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc5ac42aedULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d139d95b3dfULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a73548baf63deULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb3c77b2a8ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e47edaee6ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c851482353bULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a14cf10364ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664bbc423001ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70d0f89791ULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a30654be30ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819d6ef5218ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd69906245565a910ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e35855771202aULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa07032bbd1b8ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116b8d2d0c8ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c085141ab53ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774cdf8eeb99ULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5e19b48a8ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3c5c95a63ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4ae3418acbULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f7763e373ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3d6b2b8a3ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee5defb2fcULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f43172f60ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814a1f0ab72ULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc702081a6439ecULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa23631e28ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506cebde82bde9ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7b2c67915ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2e372532bULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,0xca273eceea26619cULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,0xd186b8c721c0c207ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,0xeada7dd6cde0eb1eULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,0xf57d4f7fee6ed178ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,0x06f067aa72176fbaULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,0x0a637dc5a2c898a6ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,0x113f9804bef90daeULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,0x1b710b35131c471bULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,0x28db77f523047d84ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,0x32caab7b40c72493ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,0x3c9ebe0a15c9bebcULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,0x431d67c49c100d4cULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,0x4cc5d4becb3e42b6ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,0x597f299cfc657e2aULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,0x5fcb6fab3ad6faecULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,0x6c44198c4a475817ULL); - -#undef RND - - /* feedback */ - for (i = 0; i < 8; i++) { - sha_info->digest[i] = sha_info->digest[i] + S[i]; - } - -} - - - -/* initialize the SHA digest */ - -static void -sha512_init(SHAobject *sha_info) -{ - sha_info->digest[0] = Py_ULL(0x6a09e667f3bcc908); - sha_info->digest[1] = Py_ULL(0xbb67ae8584caa73b); - sha_info->digest[2] = Py_ULL(0x3c6ef372fe94f82b); - sha_info->digest[3] = Py_ULL(0xa54ff53a5f1d36f1); - sha_info->digest[4] = Py_ULL(0x510e527fade682d1); - sha_info->digest[5] = Py_ULL(0x9b05688c2b3e6c1f); - sha_info->digest[6] = Py_ULL(0x1f83d9abfb41bd6b); - sha_info->digest[7] = Py_ULL(0x5be0cd19137e2179); - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - sha_info->digestsize = 64; -} - -static void -sha384_init(SHAobject *sha_info) -{ - sha_info->digest[0] = Py_ULL(0xcbbb9d5dc1059ed8); - sha_info->digest[1] = Py_ULL(0x629a292a367cd507); - sha_info->digest[2] = Py_ULL(0x9159015a3070dd17); - sha_info->digest[3] = Py_ULL(0x152fecd8f70e5939); - sha_info->digest[4] = Py_ULL(0x67332667ffc00b31); - sha_info->digest[5] = Py_ULL(0x8eb44a8768581511); - sha_info->digest[6] = Py_ULL(0xdb0c2e0d64f98fa7); - sha_info->digest[7] = Py_ULL(0x47b5481dbefa4fa4); - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - sha_info->digestsize = 48; -} - - -/* update the SHA digest */ - -static void -sha512_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count) -{ - Py_ssize_t i; - SHA_INT32 clo; - - clo = sha_info->count_lo + ((SHA_INT32) count << 3); - if (clo < sha_info->count_lo) { - ++sha_info->count_hi; - } - sha_info->count_lo = clo; - sha_info->count_hi += (SHA_INT32) count >> 29; - if (sha_info->local) { - i = SHA_BLOCKSIZE - sha_info->local; - if (i > count) { - i = count; - } - memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i); - count -= i; - buffer += i; - sha_info->local += (int)i; - if (sha_info->local == SHA_BLOCKSIZE) { - sha512_transform(sha_info); - } - else { - return; - } - } - while (count >= SHA_BLOCKSIZE) { - memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); - buffer += SHA_BLOCKSIZE; - count -= SHA_BLOCKSIZE; - sha512_transform(sha_info); - } - memcpy(sha_info->data, buffer, count); - sha_info->local = (int)count; -} - -/* finish computing the SHA digest */ - -static void -sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) -{ - int count; - SHA_INT32 lo_bit_count, hi_bit_count; - - lo_bit_count = sha_info->count_lo; - hi_bit_count = sha_info->count_hi; - count = (int) ((lo_bit_count >> 3) & 0x7f); - ((SHA_BYTE *) sha_info->data)[count++] = 0x80; - if (count > SHA_BLOCKSIZE - 16) { - memset(((SHA_BYTE *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - count); - sha512_transform(sha_info); - memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 16); - } - else { - memset(((SHA_BYTE *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - 16 - count); - } - - /* GJS: note that we add the hi/lo in big-endian. sha512_transform will - swap these values into host-order. */ - sha_info->data[112] = 0; - sha_info->data[113] = 0; - sha_info->data[114] = 0; - sha_info->data[115] = 0; - sha_info->data[116] = 0; - sha_info->data[117] = 0; - sha_info->data[118] = 0; - sha_info->data[119] = 0; - sha_info->data[120] = (hi_bit_count >> 24) & 0xff; - sha_info->data[121] = (hi_bit_count >> 16) & 0xff; - sha_info->data[122] = (hi_bit_count >> 8) & 0xff; - sha_info->data[123] = (hi_bit_count >> 0) & 0xff; - sha_info->data[124] = (lo_bit_count >> 24) & 0xff; - sha_info->data[125] = (lo_bit_count >> 16) & 0xff; - sha_info->data[126] = (lo_bit_count >> 8) & 0xff; - sha_info->data[127] = (lo_bit_count >> 0) & 0xff; - sha512_transform(sha_info); - digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 56) & 0xff); - digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 48) & 0xff); - digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 40) & 0xff); - digest[ 3] = (unsigned char) ((sha_info->digest[0] >> 32) & 0xff); - digest[ 4] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); - digest[ 5] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); - digest[ 6] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); - digest[ 7] = (unsigned char) ((sha_info->digest[0] ) & 0xff); - digest[ 8] = (unsigned char) ((sha_info->digest[1] >> 56) & 0xff); - digest[ 9] = (unsigned char) ((sha_info->digest[1] >> 48) & 0xff); - digest[10] = (unsigned char) ((sha_info->digest[1] >> 40) & 0xff); - digest[11] = (unsigned char) ((sha_info->digest[1] >> 32) & 0xff); - digest[12] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); - digest[13] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); - digest[14] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); - digest[15] = (unsigned char) ((sha_info->digest[1] ) & 0xff); - digest[16] = (unsigned char) ((sha_info->digest[2] >> 56) & 0xff); - digest[17] = (unsigned char) ((sha_info->digest[2] >> 48) & 0xff); - digest[18] = (unsigned char) ((sha_info->digest[2] >> 40) & 0xff); - digest[19] = (unsigned char) ((sha_info->digest[2] >> 32) & 0xff); - digest[20] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); - digest[21] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); - digest[22] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); - digest[23] = (unsigned char) ((sha_info->digest[2] ) & 0xff); - digest[24] = (unsigned char) ((sha_info->digest[3] >> 56) & 0xff); - digest[25] = (unsigned char) ((sha_info->digest[3] >> 48) & 0xff); - digest[26] = (unsigned char) ((sha_info->digest[3] >> 40) & 0xff); - digest[27] = (unsigned char) ((sha_info->digest[3] >> 32) & 0xff); - digest[28] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); - digest[29] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); - digest[30] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); - digest[31] = (unsigned char) ((sha_info->digest[3] ) & 0xff); - digest[32] = (unsigned char) ((sha_info->digest[4] >> 56) & 0xff); - digest[33] = (unsigned char) ((sha_info->digest[4] >> 48) & 0xff); - digest[34] = (unsigned char) ((sha_info->digest[4] >> 40) & 0xff); - digest[35] = (unsigned char) ((sha_info->digest[4] >> 32) & 0xff); - digest[36] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); - digest[37] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); - digest[38] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); - digest[39] = (unsigned char) ((sha_info->digest[4] ) & 0xff); - digest[40] = (unsigned char) ((sha_info->digest[5] >> 56) & 0xff); - digest[41] = (unsigned char) ((sha_info->digest[5] >> 48) & 0xff); - digest[42] = (unsigned char) ((sha_info->digest[5] >> 40) & 0xff); - digest[43] = (unsigned char) ((sha_info->digest[5] >> 32) & 0xff); - digest[44] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff); - digest[45] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff); - digest[46] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff); - digest[47] = (unsigned char) ((sha_info->digest[5] ) & 0xff); - digest[48] = (unsigned char) ((sha_info->digest[6] >> 56) & 0xff); - digest[49] = (unsigned char) ((sha_info->digest[6] >> 48) & 0xff); - digest[50] = (unsigned char) ((sha_info->digest[6] >> 40) & 0xff); - digest[51] = (unsigned char) ((sha_info->digest[6] >> 32) & 0xff); - digest[52] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff); - digest[53] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff); - digest[54] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff); - digest[55] = (unsigned char) ((sha_info->digest[6] ) & 0xff); - digest[56] = (unsigned char) ((sha_info->digest[7] >> 56) & 0xff); - digest[57] = (unsigned char) ((sha_info->digest[7] >> 48) & 0xff); - digest[58] = (unsigned char) ((sha_info->digest[7] >> 40) & 0xff); - digest[59] = (unsigned char) ((sha_info->digest[7] >> 32) & 0xff); - digest[60] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff); - digest[61] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff); - digest[62] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff); - digest[63] = (unsigned char) ((sha_info->digest[7] ) & 0xff); -} - -/* - * End of copied SHA code. - * - * ------------------------------------------------------------------------ - */ - -static PyTypeObject SHA384type; -static PyTypeObject SHA512type; - - -static SHAobject * -newSHA384object(void) -{ - return (SHAobject *)PyObject_New(SHAobject, &SHA384type); -} - -static SHAobject * -newSHA512object(void) -{ - return (SHAobject *)PyObject_New(SHAobject, &SHA512type); -} - -/* Internal methods for a hash object */ - -static void -SHA512_dealloc(PyObject *ptr) -{ - PyObject_Del(ptr); -} - - -/* External methods for a hash object */ - -/*[clinic input] -SHA512Type.copy - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -SHA512Type_copy_impl(SHAobject *self) -/*[clinic end generated code: output=adea896ed3164821 input=9f5f31e6c457776a]*/ -{ - SHAobject *newobj; - + */ + + +/* SHA512 by Tom St Denis */ + +/* Various logical functions */ +#define ROR64(x, y) \ + ( ((((x) & 0xFFFFFFFFFFFFFFFFULL)>>((unsigned long long)(y) & 63)) | \ + ((x)<<((unsigned long long)(64-((y) & 63))))) & 0xFFFFFFFFFFFFFFFFULL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR64((x),(n)) +#define R(x, n) (((x) & 0xFFFFFFFFFFFFFFFFULL) >> ((unsigned long long)n)) +#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) +#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) +#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) +#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) + + +static void +sha512_transform(SHAobject *sha_info) +{ + int i; + SHA_INT64 S[8], W[80], t0, t1; + + memcpy(W, sha_info->data, sizeof(sha_info->data)); +#if PY_LITTLE_ENDIAN + longReverse(W, (int)sizeof(sha_info->data)); +#endif + + for (i = 16; i < 80; ++i) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + for (i = 0; i < 8; ++i) { + S[i] = sha_info->digest[i]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98d728ae22ULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x7137449123ef65cdULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcfec4d3b2fULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba58189dbbcULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25bf348b538ULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1b605d019ULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4af194f9bULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5da6d8118ULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98a3030242ULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b0145706fbeULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be4ee4b28cULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3d5ffb4e2ULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74f27b896fULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe3b1696b1ULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a725c71235ULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174cf692694ULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c19ef14ad2ULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786384f25e3ULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc68b8cd5b5ULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc77ac9c65ULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f592b0275ULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa6ea6e483ULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dcbd41fbd4ULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da831153b5ULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152ee66dfabULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d2db43210ULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c898fb213fULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7beef0ee4ULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf33da88fc2ULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147930aa725ULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351e003826fULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x142929670a0e6e70ULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a8546d22ffcULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b21385c26c926ULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc5ac42aedULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d139d95b3dfULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a73548baf63deULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb3c77b2a8ULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e47edaee6ULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c851482353bULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a14cf10364ULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664bbc423001ULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70d0f89791ULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a30654be30ULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819d6ef5218ULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd69906245565a910ULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e35855771202aULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa07032bbd1b8ULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116b8d2d0c8ULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c085141ab53ULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774cdf8eeb99ULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5e19b48a8ULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3c5c95a63ULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4ae3418acbULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f7763e373ULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3d6b2b8a3ULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee5defb2fcULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f43172f60ULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814a1f0ab72ULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc702081a6439ecULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa23631e28ULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506cebde82bde9ULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7b2c67915ULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2e372532bULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,0xca273eceea26619cULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,0xd186b8c721c0c207ULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,0xeada7dd6cde0eb1eULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,0xf57d4f7fee6ed178ULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,0x06f067aa72176fbaULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,0x0a637dc5a2c898a6ULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,0x113f9804bef90daeULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,0x1b710b35131c471bULL); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,0x28db77f523047d84ULL); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,0x32caab7b40c72493ULL); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,0x3c9ebe0a15c9bebcULL); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,0x431d67c49c100d4cULL); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,0x4cc5d4becb3e42b6ULL); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,0x597f299cfc657e2aULL); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,0x5fcb6fab3ad6faecULL); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,0x6c44198c4a475817ULL); + +#undef RND + + /* feedback */ + for (i = 0; i < 8; i++) { + sha_info->digest[i] = sha_info->digest[i] + S[i]; + } + +} + + + +/* initialize the SHA digest */ + +static void +sha512_init(SHAobject *sha_info) +{ + sha_info->digest[0] = Py_ULL(0x6a09e667f3bcc908); + sha_info->digest[1] = Py_ULL(0xbb67ae8584caa73b); + sha_info->digest[2] = Py_ULL(0x3c6ef372fe94f82b); + sha_info->digest[3] = Py_ULL(0xa54ff53a5f1d36f1); + sha_info->digest[4] = Py_ULL(0x510e527fade682d1); + sha_info->digest[5] = Py_ULL(0x9b05688c2b3e6c1f); + sha_info->digest[6] = Py_ULL(0x1f83d9abfb41bd6b); + sha_info->digest[7] = Py_ULL(0x5be0cd19137e2179); + sha_info->count_lo = 0L; + sha_info->count_hi = 0L; + sha_info->local = 0; + sha_info->digestsize = 64; +} + +static void +sha384_init(SHAobject *sha_info) +{ + sha_info->digest[0] = Py_ULL(0xcbbb9d5dc1059ed8); + sha_info->digest[1] = Py_ULL(0x629a292a367cd507); + sha_info->digest[2] = Py_ULL(0x9159015a3070dd17); + sha_info->digest[3] = Py_ULL(0x152fecd8f70e5939); + sha_info->digest[4] = Py_ULL(0x67332667ffc00b31); + sha_info->digest[5] = Py_ULL(0x8eb44a8768581511); + sha_info->digest[6] = Py_ULL(0xdb0c2e0d64f98fa7); + sha_info->digest[7] = Py_ULL(0x47b5481dbefa4fa4); + sha_info->count_lo = 0L; + sha_info->count_hi = 0L; + sha_info->local = 0; + sha_info->digestsize = 48; +} + + +/* update the SHA digest */ + +static void +sha512_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count) +{ + Py_ssize_t i; + SHA_INT32 clo; + + clo = sha_info->count_lo + ((SHA_INT32) count << 3); + if (clo < sha_info->count_lo) { + ++sha_info->count_hi; + } + sha_info->count_lo = clo; + sha_info->count_hi += (SHA_INT32) count >> 29; + if (sha_info->local) { + i = SHA_BLOCKSIZE - sha_info->local; + if (i > count) { + i = count; + } + memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i); + count -= i; + buffer += i; + sha_info->local += (int)i; + if (sha_info->local == SHA_BLOCKSIZE) { + sha512_transform(sha_info); + } + else { + return; + } + } + while (count >= SHA_BLOCKSIZE) { + memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); + buffer += SHA_BLOCKSIZE; + count -= SHA_BLOCKSIZE; + sha512_transform(sha_info); + } + memcpy(sha_info->data, buffer, count); + sha_info->local = (int)count; +} + +/* finish computing the SHA digest */ + +static void +sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) +{ + int count; + SHA_INT32 lo_bit_count, hi_bit_count; + + lo_bit_count = sha_info->count_lo; + hi_bit_count = sha_info->count_hi; + count = (int) ((lo_bit_count >> 3) & 0x7f); + ((SHA_BYTE *) sha_info->data)[count++] = 0x80; + if (count > SHA_BLOCKSIZE - 16) { + memset(((SHA_BYTE *) sha_info->data) + count, 0, + SHA_BLOCKSIZE - count); + sha512_transform(sha_info); + memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 16); + } + else { + memset(((SHA_BYTE *) sha_info->data) + count, 0, + SHA_BLOCKSIZE - 16 - count); + } + + /* GJS: note that we add the hi/lo in big-endian. sha512_transform will + swap these values into host-order. */ + sha_info->data[112] = 0; + sha_info->data[113] = 0; + sha_info->data[114] = 0; + sha_info->data[115] = 0; + sha_info->data[116] = 0; + sha_info->data[117] = 0; + sha_info->data[118] = 0; + sha_info->data[119] = 0; + sha_info->data[120] = (hi_bit_count >> 24) & 0xff; + sha_info->data[121] = (hi_bit_count >> 16) & 0xff; + sha_info->data[122] = (hi_bit_count >> 8) & 0xff; + sha_info->data[123] = (hi_bit_count >> 0) & 0xff; + sha_info->data[124] = (lo_bit_count >> 24) & 0xff; + sha_info->data[125] = (lo_bit_count >> 16) & 0xff; + sha_info->data[126] = (lo_bit_count >> 8) & 0xff; + sha_info->data[127] = (lo_bit_count >> 0) & 0xff; + sha512_transform(sha_info); + digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 56) & 0xff); + digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 48) & 0xff); + digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 40) & 0xff); + digest[ 3] = (unsigned char) ((sha_info->digest[0] >> 32) & 0xff); + digest[ 4] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); + digest[ 5] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); + digest[ 6] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); + digest[ 7] = (unsigned char) ((sha_info->digest[0] ) & 0xff); + digest[ 8] = (unsigned char) ((sha_info->digest[1] >> 56) & 0xff); + digest[ 9] = (unsigned char) ((sha_info->digest[1] >> 48) & 0xff); + digest[10] = (unsigned char) ((sha_info->digest[1] >> 40) & 0xff); + digest[11] = (unsigned char) ((sha_info->digest[1] >> 32) & 0xff); + digest[12] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); + digest[13] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); + digest[14] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); + digest[15] = (unsigned char) ((sha_info->digest[1] ) & 0xff); + digest[16] = (unsigned char) ((sha_info->digest[2] >> 56) & 0xff); + digest[17] = (unsigned char) ((sha_info->digest[2] >> 48) & 0xff); + digest[18] = (unsigned char) ((sha_info->digest[2] >> 40) & 0xff); + digest[19] = (unsigned char) ((sha_info->digest[2] >> 32) & 0xff); + digest[20] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); + digest[21] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); + digest[22] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); + digest[23] = (unsigned char) ((sha_info->digest[2] ) & 0xff); + digest[24] = (unsigned char) ((sha_info->digest[3] >> 56) & 0xff); + digest[25] = (unsigned char) ((sha_info->digest[3] >> 48) & 0xff); + digest[26] = (unsigned char) ((sha_info->digest[3] >> 40) & 0xff); + digest[27] = (unsigned char) ((sha_info->digest[3] >> 32) & 0xff); + digest[28] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); + digest[29] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); + digest[30] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); + digest[31] = (unsigned char) ((sha_info->digest[3] ) & 0xff); + digest[32] = (unsigned char) ((sha_info->digest[4] >> 56) & 0xff); + digest[33] = (unsigned char) ((sha_info->digest[4] >> 48) & 0xff); + digest[34] = (unsigned char) ((sha_info->digest[4] >> 40) & 0xff); + digest[35] = (unsigned char) ((sha_info->digest[4] >> 32) & 0xff); + digest[36] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); + digest[37] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); + digest[38] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); + digest[39] = (unsigned char) ((sha_info->digest[4] ) & 0xff); + digest[40] = (unsigned char) ((sha_info->digest[5] >> 56) & 0xff); + digest[41] = (unsigned char) ((sha_info->digest[5] >> 48) & 0xff); + digest[42] = (unsigned char) ((sha_info->digest[5] >> 40) & 0xff); + digest[43] = (unsigned char) ((sha_info->digest[5] >> 32) & 0xff); + digest[44] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff); + digest[45] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff); + digest[46] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff); + digest[47] = (unsigned char) ((sha_info->digest[5] ) & 0xff); + digest[48] = (unsigned char) ((sha_info->digest[6] >> 56) & 0xff); + digest[49] = (unsigned char) ((sha_info->digest[6] >> 48) & 0xff); + digest[50] = (unsigned char) ((sha_info->digest[6] >> 40) & 0xff); + digest[51] = (unsigned char) ((sha_info->digest[6] >> 32) & 0xff); + digest[52] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff); + digest[53] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff); + digest[54] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff); + digest[55] = (unsigned char) ((sha_info->digest[6] ) & 0xff); + digest[56] = (unsigned char) ((sha_info->digest[7] >> 56) & 0xff); + digest[57] = (unsigned char) ((sha_info->digest[7] >> 48) & 0xff); + digest[58] = (unsigned char) ((sha_info->digest[7] >> 40) & 0xff); + digest[59] = (unsigned char) ((sha_info->digest[7] >> 32) & 0xff); + digest[60] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff); + digest[61] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff); + digest[62] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff); + digest[63] = (unsigned char) ((sha_info->digest[7] ) & 0xff); +} + +/* + * End of copied SHA code. + * + * ------------------------------------------------------------------------ + */ + +static PyTypeObject SHA384type; +static PyTypeObject SHA512type; + + +static SHAobject * +newSHA384object(void) +{ + return (SHAobject *)PyObject_New(SHAobject, &SHA384type); +} + +static SHAobject * +newSHA512object(void) +{ + return (SHAobject *)PyObject_New(SHAobject, &SHA512type); +} + +/* Internal methods for a hash object */ + +static void +SHA512_dealloc(PyObject *ptr) +{ + PyObject_Del(ptr); +} + + +/* External methods for a hash object */ + +/*[clinic input] +SHA512Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +SHA512Type_copy_impl(SHAobject *self) +/*[clinic end generated code: output=adea896ed3164821 input=9f5f31e6c457776a]*/ +{ + SHAobject *newobj; + if (Py_IS_TYPE((PyObject*)self, &SHA512type)) { - if ( (newobj = newSHA512object())==NULL) - return NULL; - } else { - if ( (newobj = newSHA384object())==NULL) - return NULL; - } - - SHAcopy(self, newobj); - return (PyObject *)newobj; -} - -/*[clinic input] -SHA512Type.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -SHA512Type_digest_impl(SHAobject *self) -/*[clinic end generated code: output=1080bbeeef7dde1b input=f6470dd359071f4b]*/ -{ - unsigned char digest[SHA_DIGESTSIZE]; - SHAobject temp; - - SHAcopy(self, &temp); - sha512_final(digest, &temp); - return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); -} - -/*[clinic input] -SHA512Type.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -SHA512Type_hexdigest_impl(SHAobject *self) -/*[clinic end generated code: output=7373305b8601e18b input=498b877b25cbe0a2]*/ -{ - unsigned char digest[SHA_DIGESTSIZE]; - SHAobject temp; - - /* Get the raw (binary) digest value */ - SHAcopy(self, &temp); - sha512_final(digest, &temp); - - return _Py_strhex((const char *)digest, self->digestsize); -} - -/*[clinic input] -SHA512Type.update - - obj: object - / - -Update this hash object's state with the provided string. -[clinic start generated code]*/ - -static PyObject * -SHA512Type_update(SHAobject *self, PyObject *obj) -/*[clinic end generated code: output=1cf333e73995a79e input=ded2b46656566283]*/ -{ - Py_buffer buf; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - - sha512_update(self, buf.buf, buf.len); - - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyMethodDef SHA_methods[] = { - SHA512TYPE_COPY_METHODDEF - SHA512TYPE_DIGEST_METHODDEF - SHA512TYPE_HEXDIGEST_METHODDEF - SHA512TYPE_UPDATE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -SHA512_get_block_size(PyObject *self, void *closure) -{ - return PyLong_FromLong(SHA_BLOCKSIZE); -} - -static PyObject * -SHA512_get_name(PyObject *self, void *closure) -{ - if (((SHAobject *)self)->digestsize == 64) - return PyUnicode_FromStringAndSize("sha512", 6); - else - return PyUnicode_FromStringAndSize("sha384", 6); -} - -static PyGetSetDef SHA_getseters[] = { - {"block_size", - (getter)SHA512_get_block_size, NULL, - NULL, - NULL}, - {"name", - (getter)SHA512_get_name, NULL, - NULL, - NULL}, - {NULL} /* Sentinel */ -}; - -static PyMemberDef SHA_members[] = { - {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject SHA384type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha512.sha384", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA512_dealloc, /*tp_dealloc*/ + if ( (newobj = newSHA512object())==NULL) + return NULL; + } else { + if ( (newobj = newSHA384object())==NULL) + return NULL; + } + + SHAcopy(self, newobj); + return (PyObject *)newobj; +} + +/*[clinic input] +SHA512Type.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +SHA512Type_digest_impl(SHAobject *self) +/*[clinic end generated code: output=1080bbeeef7dde1b input=f6470dd359071f4b]*/ +{ + unsigned char digest[SHA_DIGESTSIZE]; + SHAobject temp; + + SHAcopy(self, &temp); + sha512_final(digest, &temp); + return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); +} + +/*[clinic input] +SHA512Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +SHA512Type_hexdigest_impl(SHAobject *self) +/*[clinic end generated code: output=7373305b8601e18b input=498b877b25cbe0a2]*/ +{ + unsigned char digest[SHA_DIGESTSIZE]; + SHAobject temp; + + /* Get the raw (binary) digest value */ + SHAcopy(self, &temp); + sha512_final(digest, &temp); + + return _Py_strhex((const char *)digest, self->digestsize); +} + +/*[clinic input] +SHA512Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +SHA512Type_update(SHAobject *self, PyObject *obj) +/*[clinic end generated code: output=1cf333e73995a79e input=ded2b46656566283]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + + sha512_update(self, buf.buf, buf.len); + + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyMethodDef SHA_methods[] = { + SHA512TYPE_COPY_METHODDEF + SHA512TYPE_DIGEST_METHODDEF + SHA512TYPE_HEXDIGEST_METHODDEF + SHA512TYPE_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +SHA512_get_block_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(SHA_BLOCKSIZE); +} + +static PyObject * +SHA512_get_name(PyObject *self, void *closure) +{ + if (((SHAobject *)self)->digestsize == 64) + return PyUnicode_FromStringAndSize("sha512", 6); + else + return PyUnicode_FromStringAndSize("sha384", 6); +} + +static PyGetSetDef SHA_getseters[] = { + {"block_size", + (getter)SHA512_get_block_size, NULL, + NULL, + NULL}, + {"name", + (getter)SHA512_get_name, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + +static PyMemberDef SHA_members[] = { + {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject SHA384type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_sha512.sha384", /*tp_name*/ + sizeof(SHAobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + SHA512_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ -}; - -static PyTypeObject SHA512type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha512.sha512", /*tp_name*/ - sizeof(SHAobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA512_dealloc, /*tp_dealloc*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + SHA_methods, /* tp_methods */ + SHA_members, /* tp_members */ + SHA_getseters, /* tp_getset */ +}; + +static PyTypeObject SHA512type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_sha512.sha512", /*tp_name*/ + sizeof(SHAobject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + SHA512_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ -}; - - -/* The single module-level function: new() */ - -/*[clinic input] -_sha512.sha512 - - string: object(c_default="NULL") = b'' + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + SHA_methods, /* tp_methods */ + SHA_members, /* tp_members */ + SHA_getseters, /* tp_getset */ +}; + + +/* The single module-level function: new() */ + +/*[clinic input] +_sha512.sha512 + + string: object(c_default="NULL") = b'' * usedforsecurity: bool = True - -Return a new SHA-512 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * + +Return a new SHA-512 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * _sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=a8d9e5f9e6a0831c input=23b4daebc2ebb9c9]*/ -{ - SHAobject *new; - Py_buffer buf; - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA512object()) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha512_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha512_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - -/*[clinic input] -_sha512.sha384 - - string: object(c_default="NULL") = b'' +{ + SHAobject *new; + Py_buffer buf; + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newSHA512object()) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + sha512_init(new); + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + sha512_update(new, buf.buf, buf.len); + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + +/*[clinic input] +_sha512.sha384 + + string: object(c_default="NULL") = b'' * usedforsecurity: bool = True - -Return a new SHA-384 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * + +Return a new SHA-384 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * _sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity) /*[clinic end generated code: output=da7d594a08027ac3 input=59ef72f039a6b431]*/ -{ - SHAobject *new; - Py_buffer buf; - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA384object()) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha384_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha512_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - - -/* List of functions exported by this module */ - -static struct PyMethodDef SHA_functions[] = { - _SHA512_SHA512_METHODDEF - _SHA512_SHA384_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ - -static struct PyModuleDef _sha512module = { - PyModuleDef_HEAD_INIT, - "_sha512", - NULL, - -1, - SHA_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__sha512(void) -{ - PyObject *m; - +{ + SHAobject *new; + Py_buffer buf; + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newSHA384object()) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + sha384_init(new); + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + sha512_update(new, buf.buf, buf.len); + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + + +/* List of functions exported by this module */ + +static struct PyMethodDef SHA_functions[] = { + _SHA512_SHA512_METHODDEF + _SHA512_SHA384_METHODDEF + {NULL, NULL} /* Sentinel */ +}; + + +/* Initialize this module. */ + +static struct PyModuleDef _sha512module = { + PyModuleDef_HEAD_INIT, + "_sha512", + NULL, + -1, + SHA_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__sha512(void) +{ + PyObject *m; + Py_SET_TYPE(&SHA384type, &PyType_Type); if (PyType_Ready(&SHA384type) < 0) { - return NULL; + return NULL; } Py_SET_TYPE(&SHA512type, &PyType_Type); if (PyType_Ready(&SHA512type) < 0) { - return NULL; + return NULL; } - - m = PyModule_Create(&_sha512module); + + m = PyModule_Create(&_sha512module); if (m == NULL) { - return NULL; + return NULL; } - - Py_INCREF((PyObject *)&SHA384type); - PyModule_AddObject(m, "SHA384Type", (PyObject *)&SHA384type); - Py_INCREF((PyObject *)&SHA512type); - PyModule_AddObject(m, "SHA512Type", (PyObject *)&SHA512type); - return m; -} + + Py_INCREF((PyObject *)&SHA384type); + PyModule_AddObject(m, "SHA384Type", (PyObject *)&SHA384type); + Py_INCREF((PyObject *)&SHA512type); + PyModule_AddObject(m, "SHA512Type", (PyObject *)&SHA512type); + return m; +} diff --git a/contrib/tools/python3/src/Modules/signalmodule.c b/contrib/tools/python3/src/Modules/signalmodule.c index e396a4ad8b4..b12ff780786 100644 --- a/contrib/tools/python3/src/Modules/signalmodule.c +++ b/contrib/tools/python3/src/Modules/signalmodule.c @@ -1,77 +1,77 @@ - -/* Signal module -- many thanks to Lance Ellinghaus */ - -/* XXX Signals should be recorded per thread, now we have thread state. */ - -#include "Python.h" + +/* Signal module -- many thanks to Lance Ellinghaus */ + +/* XXX Signals should be recorded per thread, now we have thread state. */ + +#include "Python.h" #include "pycore_atomic.h" #include "pycore_call.h" #include "pycore_ceval.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() -#ifndef MS_WINDOWS -#include "posixmodule.h" -#endif -#ifdef MS_WINDOWS -#include "socketmodule.h" /* needed for SOCKET_T */ -#endif - -#ifdef MS_WINDOWS -#include -#ifdef HAVE_PROCESS_H -#include -#endif -#endif - -#ifdef HAVE_SIGNAL_H -#include -#endif +#ifndef MS_WINDOWS +#include "posixmodule.h" +#endif +#ifdef MS_WINDOWS +#include "socketmodule.h" /* needed for SOCKET_T */ +#endif + +#ifdef MS_WINDOWS +#include +#ifdef HAVE_PROCESS_H +#include +#endif +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif #ifdef HAVE_SYS_SYSCALL_H #include #endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif - -#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) -# define PYPTHREAD_SIGMASK -#endif - -#if defined(PYPTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H) -# include -#endif - -#ifndef SIG_ERR -#define SIG_ERR ((PyOS_sighandler_t)(-1)) -#endif - -#ifndef NSIG -# if defined(_NSIG) -# define NSIG _NSIG /* For BSD/SysV */ -# elif defined(_SIGMAX) -# define NSIG (_SIGMAX + 1) /* For QNX */ -# elif defined(SIGMAX) -# define NSIG (SIGMAX + 1) /* For djgpp */ -# else -# define NSIG 64 /* Use a reasonable default value */ -# endif -#endif - -#include "clinic/signalmodule.c.h" - -/*[clinic input] -module signal -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/ - +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) +# define PYPTHREAD_SIGMASK +#endif + +#if defined(PYPTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H) +# include +#endif + +#ifndef SIG_ERR +#define SIG_ERR ((PyOS_sighandler_t)(-1)) +#endif + +#ifndef NSIG +# if defined(_NSIG) +# define NSIG _NSIG /* For BSD/SysV */ +# elif defined(_SIGMAX) +# define NSIG (_SIGMAX + 1) /* For QNX */ +# elif defined(SIGMAX) +# define NSIG (SIGMAX + 1) /* For djgpp */ +# else +# define NSIG 64 /* Use a reasonable default value */ +# endif +#endif + +#include "clinic/signalmodule.c.h" + +/*[clinic input] +module signal +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/ + #ifdef HAVE_SETSIG_T /*[python input] - + class sigset_t_converter(CConverter): type = 'sigset_t' converter = '_Py_Sigset_Converter' @@ -80,333 +80,333 @@ class sigset_t_converter(CConverter): /*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/ #endif -/* - NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS - +/* + NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS + We want the following semantics: - - - only the main thread can set a signal handler + + - only the main thread can set a signal handler - only the main thread runs the signal handler - signals can be delivered to any thread - - any thread can get a signal handler - - I.e. we don't support "synchronous signals" like SIGFPE (catching - this doesn't make much sense in Python anyway) nor do we support - signals as a means of inter-thread communication, since not all - thread implementations support that (at least our thread library - doesn't). - - We still have the problem that in some implementations signals - generated by the keyboard (e.g. SIGINT) are delivered to all - threads (e.g. SGI), while in others (e.g. Solaris) such signals are + - any thread can get a signal handler + + I.e. we don't support "synchronous signals" like SIGFPE (catching + this doesn't make much sense in Python anyway) nor do we support + signals as a means of inter-thread communication, since not all + thread implementations support that (at least our thread library + doesn't). + + We still have the problem that in some implementations signals + generated by the keyboard (e.g. SIGINT) are delivered to all + threads (e.g. SGI), while in others (e.g. Solaris) such signals are delivered to one random thread. On Linux, signals are delivered to the main thread (unless the main thread is blocking the signal, for example because it's already handling the same signal). Since we allow signals to be delivered to any thread, this works fine. The only oddity is that the thread executing the Python signal handler may not be the thread that received the signal. -*/ - -static volatile struct { - _Py_atomic_int tripped; - PyObject *func; -} Handlers[NSIG]; - -#ifdef MS_WINDOWS -#define INVALID_FD ((SOCKET_T)-1) - -static volatile struct { - SOCKET_T fd; - int warn_on_full_buffer; - int use_send; -} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0}; -#else -#define INVALID_FD (-1) -static volatile struct { - sig_atomic_t fd; - int warn_on_full_buffer; -} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1}; -#endif - -/* Speed up sigcheck() when none tripped */ -static _Py_atomic_int is_tripped; - -static PyObject *DefaultHandler; -static PyObject *IgnoreHandler; -static PyObject *IntHandler; - -#ifdef MS_WINDOWS -static HANDLE sigint_event = NULL; -#endif - -#ifdef HAVE_GETITIMER -static PyObject *ItimerError; - -/* auxiliary functions for setitimer */ -static int -timeval_from_double(PyObject *obj, struct timeval *tv) -{ - if (obj == NULL) { - tv->tv_sec = 0; - tv->tv_usec = 0; - return 0; - } - - _PyTime_t t; - if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_CEILING) < 0) { - return -1; - } - return _PyTime_AsTimeval(t, tv, _PyTime_ROUND_CEILING); -} - -Py_LOCAL_INLINE(double) -double_from_timeval(struct timeval *tv) -{ - return tv->tv_sec + (double)(tv->tv_usec / 1000000.0); -} - -static PyObject * -itimer_retval(struct itimerval *iv) -{ - PyObject *r, *v; - - r = PyTuple_New(2); - if (r == NULL) - return NULL; - - if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) { - Py_DECREF(r); - return NULL; - } - - PyTuple_SET_ITEM(r, 0, v); - - if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) { - Py_DECREF(r); - return NULL; - } - - PyTuple_SET_ITEM(r, 1, v); - - return r; -} -#endif - -static PyObject * -signal_default_int_handler(PyObject *self, PyObject *args) -{ - PyErr_SetNone(PyExc_KeyboardInterrupt); - return NULL; -} - -PyDoc_STRVAR(default_int_handler_doc, -"default_int_handler(...)\n\ -\n\ -The default handler for SIGINT installed by Python.\n\ -It raises KeyboardInterrupt."); - - -static int -report_wakeup_write_error(void *data) -{ +*/ + +static volatile struct { + _Py_atomic_int tripped; + PyObject *func; +} Handlers[NSIG]; + +#ifdef MS_WINDOWS +#define INVALID_FD ((SOCKET_T)-1) + +static volatile struct { + SOCKET_T fd; + int warn_on_full_buffer; + int use_send; +} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0}; +#else +#define INVALID_FD (-1) +static volatile struct { + sig_atomic_t fd; + int warn_on_full_buffer; +} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1}; +#endif + +/* Speed up sigcheck() when none tripped */ +static _Py_atomic_int is_tripped; + +static PyObject *DefaultHandler; +static PyObject *IgnoreHandler; +static PyObject *IntHandler; + +#ifdef MS_WINDOWS +static HANDLE sigint_event = NULL; +#endif + +#ifdef HAVE_GETITIMER +static PyObject *ItimerError; + +/* auxiliary functions for setitimer */ +static int +timeval_from_double(PyObject *obj, struct timeval *tv) +{ + if (obj == NULL) { + tv->tv_sec = 0; + tv->tv_usec = 0; + return 0; + } + + _PyTime_t t; + if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_CEILING) < 0) { + return -1; + } + return _PyTime_AsTimeval(t, tv, _PyTime_ROUND_CEILING); +} + +Py_LOCAL_INLINE(double) +double_from_timeval(struct timeval *tv) +{ + return tv->tv_sec + (double)(tv->tv_usec / 1000000.0); +} + +static PyObject * +itimer_retval(struct itimerval *iv) +{ + PyObject *r, *v; + + r = PyTuple_New(2); + if (r == NULL) + return NULL; + + if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) { + Py_DECREF(r); + return NULL; + } + + PyTuple_SET_ITEM(r, 0, v); + + if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) { + Py_DECREF(r); + return NULL; + } + + PyTuple_SET_ITEM(r, 1, v); + + return r; +} +#endif + +static PyObject * +signal_default_int_handler(PyObject *self, PyObject *args) +{ + PyErr_SetNone(PyExc_KeyboardInterrupt); + return NULL; +} + +PyDoc_STRVAR(default_int_handler_doc, +"default_int_handler(...)\n\ +\n\ +The default handler for SIGINT installed by Python.\n\ +It raises KeyboardInterrupt."); + + +static int +report_wakeup_write_error(void *data) +{ PyObject *exc, *val, *tb; - int save_errno = errno; - errno = (int) (intptr_t) data; + int save_errno = errno; + errno = (int) (intptr_t) data; PyErr_Fetch(&exc, &val, &tb); - PyErr_SetFromErrno(PyExc_OSError); - PySys_WriteStderr("Exception ignored when trying to write to the " - "signal wakeup fd:\n"); - PyErr_WriteUnraisable(NULL); + PyErr_SetFromErrno(PyExc_OSError); + PySys_WriteStderr("Exception ignored when trying to write to the " + "signal wakeup fd:\n"); + PyErr_WriteUnraisable(NULL); PyErr_Restore(exc, val, tb); - errno = save_errno; - return 0; -} - -#ifdef MS_WINDOWS -static int -report_wakeup_send_error(void* data) -{ + errno = save_errno; + return 0; +} + +#ifdef MS_WINDOWS +static int +report_wakeup_send_error(void* data) +{ PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); - /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which - recognizes the error codes used by both GetLastError() and - WSAGetLastError */ - PyErr_SetExcFromWindowsErr(PyExc_OSError, (int) (intptr_t) data); - PySys_WriteStderr("Exception ignored when trying to send to the " - "signal wakeup fd:\n"); - PyErr_WriteUnraisable(NULL); + /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which + recognizes the error codes used by both GetLastError() and + WSAGetLastError */ + PyErr_SetExcFromWindowsErr(PyExc_OSError, (int) (intptr_t) data); + PySys_WriteStderr("Exception ignored when trying to send to the " + "signal wakeup fd:\n"); + PyErr_WriteUnraisable(NULL); PyErr_Restore(exc, val, tb); - return 0; -} -#endif /* MS_WINDOWS */ - -static void -trip_signal(int sig_num) -{ - unsigned char byte; - int fd; - Py_ssize_t rc; - - _Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1); - - /* Set is_tripped after setting .tripped, as it gets - cleared in PyErr_CheckSignals() before .tripped. */ - _Py_atomic_store(&is_tripped, 1); - + return 0; +} +#endif /* MS_WINDOWS */ + +static void +trip_signal(int sig_num) +{ + unsigned char byte; + int fd; + Py_ssize_t rc; + + _Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1); + + /* Set is_tripped after setting .tripped, as it gets + cleared in PyErr_CheckSignals() before .tripped. */ + _Py_atomic_store(&is_tripped, 1); + /* Signals are always handled by the main interpreter */ PyInterpreterState *interp = _PyRuntime.interpreters.main; - /* Notify ceval.c */ + /* Notify ceval.c */ _PyEval_SignalReceived(interp); - - /* And then write to the wakeup fd *after* setting all the globals and - doing the _PyEval_SignalReceived. We used to write to the wakeup fd - and then set the flag, but this allowed the following sequence of events - (especially on windows, where trip_signal may run in a new thread): - - - main thread blocks on select([wakeup.fd], ...) - - signal arrives - - trip_signal writes to the wakeup fd - - the main thread wakes up - - the main thread checks the signal flags, sees that they're unset - - the main thread empties the wakeup fd - - the main thread goes back to sleep - - trip_signal sets the flags to request the Python-level signal handler - be run - - the main thread doesn't notice, because it's asleep - - See bpo-30038 for more details. - */ - -#ifdef MS_WINDOWS - fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); -#else - fd = wakeup.fd; -#endif - - if (fd != INVALID_FD) { - byte = (unsigned char)sig_num; -#ifdef MS_WINDOWS - if (wakeup.use_send) { - rc = send(fd, &byte, 1, 0); - - if (rc < 0) { - int last_error = GetLastError(); - if (wakeup.warn_on_full_buffer || - last_error != WSAEWOULDBLOCK) - { + + /* And then write to the wakeup fd *after* setting all the globals and + doing the _PyEval_SignalReceived. We used to write to the wakeup fd + and then set the flag, but this allowed the following sequence of events + (especially on windows, where trip_signal may run in a new thread): + + - main thread blocks on select([wakeup.fd], ...) + - signal arrives + - trip_signal writes to the wakeup fd + - the main thread wakes up + - the main thread checks the signal flags, sees that they're unset + - the main thread empties the wakeup fd + - the main thread goes back to sleep + - trip_signal sets the flags to request the Python-level signal handler + be run + - the main thread doesn't notice, because it's asleep + + See bpo-30038 for more details. + */ + +#ifdef MS_WINDOWS + fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); +#else + fd = wakeup.fd; +#endif + + if (fd != INVALID_FD) { + byte = (unsigned char)sig_num; +#ifdef MS_WINDOWS + if (wakeup.use_send) { + rc = send(fd, &byte, 1, 0); + + if (rc < 0) { + int last_error = GetLastError(); + if (wakeup.warn_on_full_buffer || + last_error != WSAEWOULDBLOCK) + { /* _PyEval_AddPendingCall() isn't signal-safe, but we - still use it for this exceptional case. */ + still use it for this exceptional case. */ _PyEval_AddPendingCall(interp, report_wakeup_send_error, (void *)(intptr_t) last_error); - } - } - } - else -#endif - { - /* _Py_write_noraise() retries write() if write() is interrupted by - a signal (fails with EINTR). */ - rc = _Py_write_noraise(fd, &byte, 1); - - if (rc < 0) { - if (wakeup.warn_on_full_buffer || - (errno != EWOULDBLOCK && errno != EAGAIN)) - { + } + } + } + else +#endif + { + /* _Py_write_noraise() retries write() if write() is interrupted by + a signal (fails with EINTR). */ + rc = _Py_write_noraise(fd, &byte, 1); + + if (rc < 0) { + if (wakeup.warn_on_full_buffer || + (errno != EWOULDBLOCK && errno != EAGAIN)) + { /* _PyEval_AddPendingCall() isn't signal-safe, but we - still use it for this exceptional case. */ + still use it for this exceptional case. */ _PyEval_AddPendingCall(interp, report_wakeup_write_error, (void *)(intptr_t)errno); - } - } - } - } -} - -static void -signal_handler(int sig_num) -{ - int save_errno = errno; - + } + } + } + } +} + +static void +signal_handler(int sig_num) +{ + int save_errno = errno; + trip_signal(sig_num); - -#ifndef HAVE_SIGACTION -#ifdef SIGCHLD - /* To avoid infinite recursion, this signal remains - reset until explicit re-instated. - Don't clear the 'func' field as it is our pointer - to the Python handler... */ - if (sig_num != SIGCHLD) -#endif - /* If the handler was not set up with sigaction, reinstall it. See - * Python/pylifecycle.c for the implementation of PyOS_setsig which - * makes this true. See also issue8354. */ - PyOS_setsig(sig_num, signal_handler); -#endif - - /* Issue #10311: asynchronously executing signal handlers should not - mutate errno under the feet of unsuspecting C code. */ - errno = save_errno; - -#ifdef MS_WINDOWS - if (sig_num == SIGINT) - SetEvent(sigint_event); -#endif -} - - -#ifdef HAVE_ALARM - -/*[clinic input] -signal.alarm -> long - - seconds: int - / - -Arrange for SIGALRM to arrive after the given number of seconds. -[clinic start generated code]*/ - -static long -signal_alarm_impl(PyObject *module, int seconds) -/*[clinic end generated code: output=144232290814c298 input=0d5e97e0e6f39e86]*/ -{ - /* alarm() returns the number of seconds remaining */ - return (long)alarm(seconds); -} - -#endif - -#ifdef HAVE_PAUSE - -/*[clinic input] -signal.pause - -Wait until a signal arrives. -[clinic start generated code]*/ - -static PyObject * -signal_pause_impl(PyObject *module) -/*[clinic end generated code: output=391656788b3c3929 input=f03de0f875752062]*/ -{ - Py_BEGIN_ALLOW_THREADS - (void)pause(); - Py_END_ALLOW_THREADS - /* make sure that any exceptions that got raised are propagated - * back into Python - */ - if (PyErr_CheckSignals()) - return NULL; - - Py_RETURN_NONE; -} - -#endif - + +#ifndef HAVE_SIGACTION +#ifdef SIGCHLD + /* To avoid infinite recursion, this signal remains + reset until explicit re-instated. + Don't clear the 'func' field as it is our pointer + to the Python handler... */ + if (sig_num != SIGCHLD) +#endif + /* If the handler was not set up with sigaction, reinstall it. See + * Python/pylifecycle.c for the implementation of PyOS_setsig which + * makes this true. See also issue8354. */ + PyOS_setsig(sig_num, signal_handler); +#endif + + /* Issue #10311: asynchronously executing signal handlers should not + mutate errno under the feet of unsuspecting C code. */ + errno = save_errno; + +#ifdef MS_WINDOWS + if (sig_num == SIGINT) + SetEvent(sigint_event); +#endif +} + + +#ifdef HAVE_ALARM + +/*[clinic input] +signal.alarm -> long + + seconds: int + / + +Arrange for SIGALRM to arrive after the given number of seconds. +[clinic start generated code]*/ + +static long +signal_alarm_impl(PyObject *module, int seconds) +/*[clinic end generated code: output=144232290814c298 input=0d5e97e0e6f39e86]*/ +{ + /* alarm() returns the number of seconds remaining */ + return (long)alarm(seconds); +} + +#endif + +#ifdef HAVE_PAUSE + +/*[clinic input] +signal.pause + +Wait until a signal arrives. +[clinic start generated code]*/ + +static PyObject * +signal_pause_impl(PyObject *module) +/*[clinic end generated code: output=391656788b3c3929 input=f03de0f875752062]*/ +{ + Py_BEGIN_ALLOW_THREADS + (void)pause(); + Py_END_ALLOW_THREADS + /* make sure that any exceptions that got raised are propagated + * back into Python + */ + if (PyErr_CheckSignals()) + return NULL; + + Py_RETURN_NONE; +} + +#endif + /*[clinic input] signal.raise_signal - + signalnum: int / @@ -430,134 +430,134 @@ signal_raise_signal_impl(PyObject *module, int signalnum) Py_RETURN_NONE; } -/*[clinic input] -signal.signal - - signalnum: int - handler: object - / - -Set the action for the given signal. - -The action can be SIG_DFL, SIG_IGN, or a callable Python object. -The previous action is returned. See getsignal() for possible return values. - -*** IMPORTANT NOTICE *** -A signal handler function is called with two arguments: -the first is the signal number, the second is the interrupted stack frame. -[clinic start generated code]*/ - -static PyObject * -signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) -/*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/ -{ - PyObject *old_handler; - void (*func)(int); -#ifdef MS_WINDOWS - /* Validate that signalnum is one of the allowable signals */ - switch (signalnum) { - case SIGABRT: break; -#ifdef SIGBREAK - /* Issue #10003: SIGBREAK is not documented as permitted, but works - and corresponds to CTRL_BREAK_EVENT. */ - case SIGBREAK: break; -#endif - case SIGFPE: break; - case SIGILL: break; - case SIGINT: break; - case SIGSEGV: break; - case SIGTERM: break; - default: - PyErr_SetString(PyExc_ValueError, "invalid signal value"); - return NULL; - } -#endif +/*[clinic input] +signal.signal + + signalnum: int + handler: object + / + +Set the action for the given signal. + +The action can be SIG_DFL, SIG_IGN, or a callable Python object. +The previous action is returned. See getsignal() for possible return values. + +*** IMPORTANT NOTICE *** +A signal handler function is called with two arguments: +the first is the signal number, the second is the interrupted stack frame. +[clinic start generated code]*/ + +static PyObject * +signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) +/*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/ +{ + PyObject *old_handler; + void (*func)(int); +#ifdef MS_WINDOWS + /* Validate that signalnum is one of the allowable signals */ + switch (signalnum) { + case SIGABRT: break; +#ifdef SIGBREAK + /* Issue #10003: SIGBREAK is not documented as permitted, but works + and corresponds to CTRL_BREAK_EVENT. */ + case SIGBREAK: break; +#endif + case SIGFPE: break; + case SIGILL: break; + case SIGINT: break; + case SIGSEGV: break; + case SIGTERM: break; + default: + PyErr_SetString(PyExc_ValueError, "invalid signal value"); + return NULL; + } +#endif PyThreadState *tstate = _PyThreadState_GET(); if (!_Py_ThreadCanHandleSignals(tstate->interp)) { _PyErr_SetString(tstate, PyExc_ValueError, "signal only works in main thread " "of the main interpreter"); - return NULL; - } - if (signalnum < 1 || signalnum >= NSIG) { + return NULL; + } + if (signalnum < 1 || signalnum >= NSIG) { _PyErr_SetString(tstate, PyExc_ValueError, "signal number out of range"); - return NULL; - } + return NULL; + } if (handler == IgnoreHandler) { - func = SIG_IGN; + func = SIG_IGN; } else if (handler == DefaultHandler) { - func = SIG_DFL; + func = SIG_DFL; } - else if (!PyCallable_Check(handler)) { + else if (!PyCallable_Check(handler)) { _PyErr_SetString(tstate, PyExc_TypeError, "signal handler must be signal.SIG_IGN, " "signal.SIG_DFL, or a callable object"); return NULL; - } + } else { - func = signal_handler; + func = signal_handler; } - /* Check for pending signals before changing signal handler */ + /* Check for pending signals before changing signal handler */ if (_PyErr_CheckSignalsTstate(tstate)) { - return NULL; - } - if (PyOS_setsig(signalnum, func) == SIG_ERR) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } + return NULL; + } + if (PyOS_setsig(signalnum, func) == SIG_ERR) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } - old_handler = Handlers[signalnum].func; - Py_INCREF(handler); - Handlers[signalnum].func = handler; + old_handler = Handlers[signalnum].func; + Py_INCREF(handler); + Handlers[signalnum].func = handler; if (old_handler != NULL) { - return old_handler; + return old_handler; } else { - Py_RETURN_NONE; + Py_RETURN_NONE; } -} - - -/*[clinic input] -signal.getsignal - - signalnum: int - / - -Return the current action for the given signal. - -The return value can be: - SIG_IGN -- if the signal is being ignored - SIG_DFL -- if the default action for the signal is in effect - None -- if an unknown handler is in effect - anything else -- the callable Python object used as a handler -[clinic start generated code]*/ - -static PyObject * -signal_getsignal_impl(PyObject *module, int signalnum) -/*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/ -{ - PyObject *old_handler; - if (signalnum < 1 || signalnum >= NSIG) { - PyErr_SetString(PyExc_ValueError, - "signal number out of range"); - return NULL; - } - old_handler = Handlers[signalnum].func; - if (old_handler != NULL) { - Py_INCREF(old_handler); - return old_handler; - } - else { - Py_RETURN_NONE; - } -} - +} + + +/*[clinic input] +signal.getsignal + + signalnum: int + / + +Return the current action for the given signal. + +The return value can be: + SIG_IGN -- if the signal is being ignored + SIG_DFL -- if the default action for the signal is in effect + None -- if an unknown handler is in effect + anything else -- the callable Python object used as a handler +[clinic start generated code]*/ + +static PyObject * +signal_getsignal_impl(PyObject *module, int signalnum) +/*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/ +{ + PyObject *old_handler; + if (signalnum < 1 || signalnum >= NSIG) { + PyErr_SetString(PyExc_ValueError, + "signal number out of range"); + return NULL; + } + old_handler = Handlers[signalnum].func; + if (old_handler != NULL) { + Py_INCREF(old_handler); + return old_handler; + } + else { + Py_RETURN_NONE; + } +} + /*[clinic input] signal.strsignal @@ -625,400 +625,400 @@ signal_strsignal_impl(PyObject *module, int signalnum) default: Py_RETURN_NONE; } -#else - errno = 0; - res = strsignal(signalnum); - - if (errno || res == NULL || strstr(res, "Unknown signal") != NULL) - Py_RETURN_NONE; -#endif - - return Py_BuildValue("s", res); -} - -#ifdef HAVE_SIGINTERRUPT - -/*[clinic input] -signal.siginterrupt - - signalnum: int - flag: int - / - -Change system call restart behaviour. - -If flag is False, system calls will be restarted when interrupted by -signal sig, else system calls will be interrupted. -[clinic start generated code]*/ - -static PyObject * -signal_siginterrupt_impl(PyObject *module, int signalnum, int flag) -/*[clinic end generated code: output=063816243d85dd19 input=4160acacca3e2099]*/ -{ - if (signalnum < 1 || signalnum >= NSIG) { - PyErr_SetString(PyExc_ValueError, - "signal number out of range"); - return NULL; - } - if (siginterrupt(signalnum, flag)<0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_RETURN_NONE; -} - -#endif - - -static PyObject* -signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds) -{ - struct _Py_stat_struct status; - static char *kwlist[] = { - "", "warn_on_full_buffer", NULL, - }; - int warn_on_full_buffer = 1; -#ifdef MS_WINDOWS - PyObject *fdobj; - SOCKET_T sockfd, old_sockfd; - int res; - int res_size = sizeof res; - PyObject *mod; - int is_socket; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|$p:set_wakeup_fd", kwlist, - &fdobj, &warn_on_full_buffer)) - return NULL; - - sockfd = PyLong_AsSocket_t(fdobj); - if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred()) - return NULL; -#else - int fd, old_fd; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|$p:set_wakeup_fd", kwlist, - &fd, &warn_on_full_buffer)) - return NULL; -#endif - - PyThreadState *tstate = _PyThreadState_GET(); - if (!_Py_ThreadCanHandleSignals(tstate->interp)) { - _PyErr_SetString(tstate, PyExc_ValueError, - "set_wakeup_fd only works in main thread " - "of the main interpreter"); - return NULL; - } - -#ifdef MS_WINDOWS - is_socket = 0; - if (sockfd != INVALID_FD) { - /* Import the _socket module to call WSAStartup() */ - mod = PyImport_ImportModuleNoBlock("_socket"); - if (mod == NULL) - return NULL; - Py_DECREF(mod); - - /* test the socket */ - if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, - (char *)&res, &res_size) != 0) { - int fd, err; - - err = WSAGetLastError(); - if (err != WSAENOTSOCK) { - PyErr_SetExcFromWindowsErr(PyExc_OSError, err); - return NULL; - } - - fd = (int)sockfd; - if ((SOCKET_T)fd != sockfd) { - _PyErr_SetString(tstate, PyExc_ValueError, "invalid fd"); - return NULL; - } - - if (_Py_fstat(fd, &status) != 0) { - return NULL; - } - - /* on Windows, a file cannot be set to non-blocking mode */ - } - else { - is_socket = 1; - - /* Windows does not provide a function to test if a socket - is in non-blocking mode */ - } - } - - old_sockfd = wakeup.fd; - wakeup.fd = sockfd; - wakeup.warn_on_full_buffer = warn_on_full_buffer; - wakeup.use_send = is_socket; - - if (old_sockfd != INVALID_FD) - return PyLong_FromSocket_t(old_sockfd); - else - return PyLong_FromLong(-1); -#else - if (fd != -1) { - int blocking; - - if (_Py_fstat(fd, &status) != 0) - return NULL; - - blocking = _Py_get_blocking(fd); - if (blocking < 0) - return NULL; - if (blocking) { - _PyErr_Format(tstate, PyExc_ValueError, - "the fd %i must be in non-blocking mode", - fd); - return NULL; - } - } - - old_fd = wakeup.fd; - wakeup.fd = fd; - wakeup.warn_on_full_buffer = warn_on_full_buffer; - - return PyLong_FromLong(old_fd); -#endif -} - -PyDoc_STRVAR(set_wakeup_fd_doc, -"set_wakeup_fd(fd, *, warn_on_full_buffer=True) -> fd\n\ -\n\ -Sets the fd to be written to (with the signal number) when a signal\n\ -comes in. A library can use this to wakeup select or poll.\n\ -The previous fd or -1 is returned.\n\ -\n\ -The fd must be non-blocking."); - -/* C API for the same, without all the error checking */ -int -PySignal_SetWakeupFd(int fd) -{ - int old_fd; - if (fd < 0) - fd = -1; - -#ifdef MS_WINDOWS - old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); -#else - old_fd = wakeup.fd; -#endif - wakeup.fd = fd; - wakeup.warn_on_full_buffer = 1; - return old_fd; -} - - -#ifdef HAVE_SETITIMER - -/*[clinic input] -signal.setitimer - - which: int - seconds: object - interval: object(c_default="NULL") = 0.0 - / - -Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF). - -The timer will fire after value seconds and after that every interval seconds. -The itimer can be cleared by setting seconds to zero. - -Returns old values as a tuple: (delay, interval). -[clinic start generated code]*/ - -static PyObject * -signal_setitimer_impl(PyObject *module, int which, PyObject *seconds, - PyObject *interval) -/*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/ -{ - struct itimerval new, old; - - if (timeval_from_double(seconds, &new.it_value) < 0) { - return NULL; - } - if (timeval_from_double(interval, &new.it_interval) < 0) { - return NULL; - } - - /* Let OS check "which" value */ - if (setitimer(which, &new, &old) != 0) { - PyErr_SetFromErrno(ItimerError); - return NULL; - } - - return itimer_retval(&old); -} - -#endif - - -#ifdef HAVE_GETITIMER - -/*[clinic input] -signal.getitimer - - which: int - / - -Returns current value of given itimer. -[clinic start generated code]*/ - -static PyObject * -signal_getitimer_impl(PyObject *module, int which) -/*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/ -{ - struct itimerval old; - - if (getitimer(which, &old) != 0) { - PyErr_SetFromErrno(ItimerError); - return NULL; - } - - return itimer_retval(&old); -} - -#endif - -#ifdef HAVE_SIGSET_T -#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING) -static PyObject* -sigset_to_set(sigset_t mask) -{ - PyObject *signum, *result; - int sig; - - result = PySet_New(0); - if (result == NULL) - return NULL; - - for (sig = 1; sig < NSIG; sig++) { - if (sigismember(&mask, sig) != 1) - continue; - - /* Handle the case where it is a member by adding the signal to - the result list. Ignore the other cases because they mean the - signal isn't a member of the mask or the signal was invalid, - and an invalid signal must have been our fault in constructing - the loop boundaries. */ - signum = PyLong_FromLong(sig); - if (signum == NULL) { - Py_DECREF(result); - return NULL; - } - if (PySet_Add(result, signum) == -1) { - Py_DECREF(signum); - Py_DECREF(result); - return NULL; - } - Py_DECREF(signum); - } - return result; -} -#endif - -#ifdef PYPTHREAD_SIGMASK - -/*[clinic input] -signal.pthread_sigmask - - how: int - mask: sigset_t - / - -Fetch and/or change the signal mask of the calling thread. -[clinic start generated code]*/ - -static PyObject * -signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask) -/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/ -{ - sigset_t previous; - int err; - - err = pthread_sigmask(how, &mask, &previous); - if (err != 0) { - errno = err; - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - /* if signals was unblocked, signal handlers have been called */ - if (PyErr_CheckSignals()) - return NULL; - - return sigset_to_set(previous); -} - -#endif /* #ifdef PYPTHREAD_SIGMASK */ - - -#ifdef HAVE_SIGPENDING - -/*[clinic input] -signal.sigpending - -Examine pending signals. - -Returns a set of signal numbers that are pending for delivery to -the calling thread. -[clinic start generated code]*/ - -static PyObject * -signal_sigpending_impl(PyObject *module) -/*[clinic end generated code: output=53375ffe89325022 input=e0036c016f874e29]*/ -{ - int err; - sigset_t mask; - err = sigpending(&mask); - if (err) - return PyErr_SetFromErrno(PyExc_OSError); - return sigset_to_set(mask); -} - -#endif /* #ifdef HAVE_SIGPENDING */ - - -#ifdef HAVE_SIGWAIT - -/*[clinic input] -signal.sigwait - - sigset: sigset_t - / - -Wait for a signal. - -Suspend execution of the calling thread until the delivery of one of the -signals specified in the signal set sigset. The function accepts the signal -and returns the signal number. -[clinic start generated code]*/ - -static PyObject * -signal_sigwait_impl(PyObject *module, sigset_t sigset) -/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/ -{ - int err, signum; - - Py_BEGIN_ALLOW_THREADS - err = sigwait(&sigset, &signum); - Py_END_ALLOW_THREADS - if (err) { - errno = err; - return PyErr_SetFromErrno(PyExc_OSError); - } +#else + errno = 0; + res = strsignal(signalnum); + + if (errno || res == NULL || strstr(res, "Unknown signal") != NULL) + Py_RETURN_NONE; +#endif - return PyLong_FromLong(signum); + return Py_BuildValue("s", res); } -#endif /* #ifdef HAVE_SIGWAIT */ +#ifdef HAVE_SIGINTERRUPT + +/*[clinic input] +signal.siginterrupt + + signalnum: int + flag: int + / + +Change system call restart behaviour. + +If flag is False, system calls will be restarted when interrupted by +signal sig, else system calls will be interrupted. +[clinic start generated code]*/ + +static PyObject * +signal_siginterrupt_impl(PyObject *module, int signalnum, int flag) +/*[clinic end generated code: output=063816243d85dd19 input=4160acacca3e2099]*/ +{ + if (signalnum < 1 || signalnum >= NSIG) { + PyErr_SetString(PyExc_ValueError, + "signal number out of range"); + return NULL; + } + if (siginterrupt(signalnum, flag)<0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} + +#endif + + +static PyObject* +signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds) +{ + struct _Py_stat_struct status; + static char *kwlist[] = { + "", "warn_on_full_buffer", NULL, + }; + int warn_on_full_buffer = 1; +#ifdef MS_WINDOWS + PyObject *fdobj; + SOCKET_T sockfd, old_sockfd; + int res; + int res_size = sizeof res; + PyObject *mod; + int is_socket; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|$p:set_wakeup_fd", kwlist, + &fdobj, &warn_on_full_buffer)) + return NULL; + + sockfd = PyLong_AsSocket_t(fdobj); + if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred()) + return NULL; +#else + int fd, old_fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|$p:set_wakeup_fd", kwlist, + &fd, &warn_on_full_buffer)) + return NULL; +#endif + + PyThreadState *tstate = _PyThreadState_GET(); + if (!_Py_ThreadCanHandleSignals(tstate->interp)) { + _PyErr_SetString(tstate, PyExc_ValueError, + "set_wakeup_fd only works in main thread " + "of the main interpreter"); + return NULL; + } + +#ifdef MS_WINDOWS + is_socket = 0; + if (sockfd != INVALID_FD) { + /* Import the _socket module to call WSAStartup() */ + mod = PyImport_ImportModuleNoBlock("_socket"); + if (mod == NULL) + return NULL; + Py_DECREF(mod); + + /* test the socket */ + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, + (char *)&res, &res_size) != 0) { + int fd, err; + + err = WSAGetLastError(); + if (err != WSAENOTSOCK) { + PyErr_SetExcFromWindowsErr(PyExc_OSError, err); + return NULL; + } + + fd = (int)sockfd; + if ((SOCKET_T)fd != sockfd) { + _PyErr_SetString(tstate, PyExc_ValueError, "invalid fd"); + return NULL; + } + + if (_Py_fstat(fd, &status) != 0) { + return NULL; + } + + /* on Windows, a file cannot be set to non-blocking mode */ + } + else { + is_socket = 1; + + /* Windows does not provide a function to test if a socket + is in non-blocking mode */ + } + } + + old_sockfd = wakeup.fd; + wakeup.fd = sockfd; + wakeup.warn_on_full_buffer = warn_on_full_buffer; + wakeup.use_send = is_socket; + + if (old_sockfd != INVALID_FD) + return PyLong_FromSocket_t(old_sockfd); + else + return PyLong_FromLong(-1); +#else + if (fd != -1) { + int blocking; + + if (_Py_fstat(fd, &status) != 0) + return NULL; + + blocking = _Py_get_blocking(fd); + if (blocking < 0) + return NULL; + if (blocking) { + _PyErr_Format(tstate, PyExc_ValueError, + "the fd %i must be in non-blocking mode", + fd); + return NULL; + } + } + + old_fd = wakeup.fd; + wakeup.fd = fd; + wakeup.warn_on_full_buffer = warn_on_full_buffer; + + return PyLong_FromLong(old_fd); +#endif +} + +PyDoc_STRVAR(set_wakeup_fd_doc, +"set_wakeup_fd(fd, *, warn_on_full_buffer=True) -> fd\n\ +\n\ +Sets the fd to be written to (with the signal number) when a signal\n\ +comes in. A library can use this to wakeup select or poll.\n\ +The previous fd or -1 is returned.\n\ +\n\ +The fd must be non-blocking."); + +/* C API for the same, without all the error checking */ +int +PySignal_SetWakeupFd(int fd) +{ + int old_fd; + if (fd < 0) + fd = -1; + +#ifdef MS_WINDOWS + old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); +#else + old_fd = wakeup.fd; +#endif + wakeup.fd = fd; + wakeup.warn_on_full_buffer = 1; + return old_fd; +} + + +#ifdef HAVE_SETITIMER + +/*[clinic input] +signal.setitimer + + which: int + seconds: object + interval: object(c_default="NULL") = 0.0 + / + +Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF). + +The timer will fire after value seconds and after that every interval seconds. +The itimer can be cleared by setting seconds to zero. + +Returns old values as a tuple: (delay, interval). +[clinic start generated code]*/ + +static PyObject * +signal_setitimer_impl(PyObject *module, int which, PyObject *seconds, + PyObject *interval) +/*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/ +{ + struct itimerval new, old; + + if (timeval_from_double(seconds, &new.it_value) < 0) { + return NULL; + } + if (timeval_from_double(interval, &new.it_interval) < 0) { + return NULL; + } + + /* Let OS check "which" value */ + if (setitimer(which, &new, &old) != 0) { + PyErr_SetFromErrno(ItimerError); + return NULL; + } + + return itimer_retval(&old); +} + +#endif + + +#ifdef HAVE_GETITIMER + +/*[clinic input] +signal.getitimer + + which: int + / + +Returns current value of given itimer. +[clinic start generated code]*/ + +static PyObject * +signal_getitimer_impl(PyObject *module, int which) +/*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/ +{ + struct itimerval old; + + if (getitimer(which, &old) != 0) { + PyErr_SetFromErrno(ItimerError); + return NULL; + } + + return itimer_retval(&old); +} + +#endif + +#ifdef HAVE_SIGSET_T +#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING) +static PyObject* +sigset_to_set(sigset_t mask) +{ + PyObject *signum, *result; + int sig; + + result = PySet_New(0); + if (result == NULL) + return NULL; + + for (sig = 1; sig < NSIG; sig++) { + if (sigismember(&mask, sig) != 1) + continue; + + /* Handle the case where it is a member by adding the signal to + the result list. Ignore the other cases because they mean the + signal isn't a member of the mask or the signal was invalid, + and an invalid signal must have been our fault in constructing + the loop boundaries. */ + signum = PyLong_FromLong(sig); + if (signum == NULL) { + Py_DECREF(result); + return NULL; + } + if (PySet_Add(result, signum) == -1) { + Py_DECREF(signum); + Py_DECREF(result); + return NULL; + } + Py_DECREF(signum); + } + return result; +} +#endif + +#ifdef PYPTHREAD_SIGMASK + +/*[clinic input] +signal.pthread_sigmask + + how: int + mask: sigset_t + / + +Fetch and/or change the signal mask of the calling thread. +[clinic start generated code]*/ + +static PyObject * +signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask) +/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/ +{ + sigset_t previous; + int err; + + err = pthread_sigmask(how, &mask, &previous); + if (err != 0) { + errno = err; + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + /* if signals was unblocked, signal handlers have been called */ + if (PyErr_CheckSignals()) + return NULL; + + return sigset_to_set(previous); +} + +#endif /* #ifdef PYPTHREAD_SIGMASK */ + + +#ifdef HAVE_SIGPENDING + +/*[clinic input] +signal.sigpending + +Examine pending signals. + +Returns a set of signal numbers that are pending for delivery to +the calling thread. +[clinic start generated code]*/ + +static PyObject * +signal_sigpending_impl(PyObject *module) +/*[clinic end generated code: output=53375ffe89325022 input=e0036c016f874e29]*/ +{ + int err; + sigset_t mask; + err = sigpending(&mask); + if (err) + return PyErr_SetFromErrno(PyExc_OSError); + return sigset_to_set(mask); +} + +#endif /* #ifdef HAVE_SIGPENDING */ + + +#ifdef HAVE_SIGWAIT + +/*[clinic input] +signal.sigwait + + sigset: sigset_t + / + +Wait for a signal. + +Suspend execution of the calling thread until the delivery of one of the +signals specified in the signal set sigset. The function accepts the signal +and returns the signal number. +[clinic start generated code]*/ + +static PyObject * +signal_sigwait_impl(PyObject *module, sigset_t sigset) +/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/ +{ + int err, signum; + + Py_BEGIN_ALLOW_THREADS + err = sigwait(&sigset, &signum); + Py_END_ALLOW_THREADS + if (err) { + errno = err; + return PyErr_SetFromErrno(PyExc_OSError); + } + + return PyLong_FromLong(signum); +} + +#endif /* #ifdef HAVE_SIGWAIT */ #endif /* #ifdef HAVE_SIGSET_T */ - + #if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS) - + /*[clinic input] signal.valid_signals @@ -1059,219 +1059,219 @@ signal_valid_signals_impl(PyObject *module) -#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) -static int initialized; -static PyStructSequence_Field struct_siginfo_fields[] = { - {"si_signo", "signal number"}, - {"si_code", "signal code"}, - {"si_errno", "errno associated with this signal"}, - {"si_pid", "sending process ID"}, - {"si_uid", "real user ID of sending process"}, - {"si_status", "exit value or signal"}, - {"si_band", "band event for SIGPOLL"}, - {0} -}; - -PyDoc_STRVAR(struct_siginfo__doc__, -"struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\ -This object may be accessed either as a tuple of\n\ -(si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\ -or via the attributes si_signo, si_code, and so on."); - -static PyStructSequence_Desc struct_siginfo_desc = { - "signal.struct_siginfo", /* name */ - struct_siginfo__doc__, /* doc */ - struct_siginfo_fields, /* fields */ - 7 /* n_in_sequence */ -}; - -static PyTypeObject SiginfoType; - -static PyObject * -fill_siginfo(siginfo_t *si) -{ - PyObject *result = PyStructSequence_New(&SiginfoType); - if (!result) - return NULL; - - PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo))); - PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code))); +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) +static int initialized; +static PyStructSequence_Field struct_siginfo_fields[] = { + {"si_signo", "signal number"}, + {"si_code", "signal code"}, + {"si_errno", "errno associated with this signal"}, + {"si_pid", "sending process ID"}, + {"si_uid", "real user ID of sending process"}, + {"si_status", "exit value or signal"}, + {"si_band", "band event for SIGPOLL"}, + {0} +}; + +PyDoc_STRVAR(struct_siginfo__doc__, +"struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\ +This object may be accessed either as a tuple of\n\ +(si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\ +or via the attributes si_signo, si_code, and so on."); + +static PyStructSequence_Desc struct_siginfo_desc = { + "signal.struct_siginfo", /* name */ + struct_siginfo__doc__, /* doc */ + struct_siginfo_fields, /* fields */ + 7 /* n_in_sequence */ +}; + +static PyTypeObject SiginfoType; + +static PyObject * +fill_siginfo(siginfo_t *si) +{ + PyObject *result = PyStructSequence_New(&SiginfoType); + if (!result) + return NULL; + + PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo))); + PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code))); #ifdef __VXWORKS__ PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(0L)); PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(0L)); PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(0L)); PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(0L)); #else - PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno))); - PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid)); - PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid)); - PyStructSequence_SET_ITEM(result, 5, - PyLong_FromLong((long)(si->si_status))); -#endif -#ifdef HAVE_SIGINFO_T_SI_BAND - PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band)); -#else - PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L)); -#endif - if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } - - return result; -} -#endif - + PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno))); + PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid)); + PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid)); + PyStructSequence_SET_ITEM(result, 5, + PyLong_FromLong((long)(si->si_status))); +#endif +#ifdef HAVE_SIGINFO_T_SI_BAND + PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band)); +#else + PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L)); +#endif + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } + + return result; +} +#endif + #ifdef HAVE_SIGSET_T -#ifdef HAVE_SIGWAITINFO - -/*[clinic input] -signal.sigwaitinfo - +#ifdef HAVE_SIGWAITINFO + +/*[clinic input] +signal.sigwaitinfo + sigset: sigset_t - / - -Wait synchronously until one of the signals in *sigset* is delivered. - -Returns a struct_siginfo containing information about the signal. -[clinic start generated code]*/ - -static PyObject * + / + +Wait synchronously until one of the signals in *sigset* is delivered. + +Returns a struct_siginfo containing information about the signal. +[clinic start generated code]*/ + +static PyObject * signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset) /*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/ -{ - siginfo_t si; - int err; - int async_err = 0; - - do { - Py_BEGIN_ALLOW_THREADS +{ + siginfo_t si; + int err; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS err = sigwaitinfo(&sigset, &si); - Py_END_ALLOW_THREADS - } while (err == -1 - && errno == EINTR && !(async_err = PyErr_CheckSignals())); - if (err == -1) - return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL; - - return fill_siginfo(&si); -} - -#endif /* #ifdef HAVE_SIGWAITINFO */ - -#ifdef HAVE_SIGTIMEDWAIT - -/*[clinic input] -signal.sigtimedwait - + Py_END_ALLOW_THREADS + } while (err == -1 + && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (err == -1) + return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL; + + return fill_siginfo(&si); +} + +#endif /* #ifdef HAVE_SIGWAITINFO */ + +#ifdef HAVE_SIGTIMEDWAIT + +/*[clinic input] +signal.sigtimedwait + sigset: sigset_t - timeout as timeout_obj: object - / - -Like sigwaitinfo(), but with a timeout. - -The timeout is specified in seconds, with floating point numbers allowed. -[clinic start generated code]*/ - -static PyObject * + timeout as timeout_obj: object + / + +Like sigwaitinfo(), but with a timeout. + +The timeout is specified in seconds, with floating point numbers allowed. +[clinic start generated code]*/ + +static PyObject * signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, - PyObject *timeout_obj) + PyObject *timeout_obj) /*[clinic end generated code: output=59c8971e8ae18a64 input=87fd39237cf0b7ba]*/ -{ - struct timespec ts; - siginfo_t si; - int res; - _PyTime_t timeout, deadline, monotonic; - - if (_PyTime_FromSecondsObject(&timeout, - timeout_obj, _PyTime_ROUND_CEILING) < 0) - return NULL; - - if (timeout < 0) { - PyErr_SetString(PyExc_ValueError, "timeout must be non-negative"); - return NULL; - } - - deadline = _PyTime_GetMonotonicClock() + timeout; - - do { - if (_PyTime_AsTimespec(timeout, &ts) < 0) - return NULL; - - Py_BEGIN_ALLOW_THREADS +{ + struct timespec ts; + siginfo_t si; + int res; + _PyTime_t timeout, deadline, monotonic; + + if (_PyTime_FromSecondsObject(&timeout, + timeout_obj, _PyTime_ROUND_CEILING) < 0) + return NULL; + + if (timeout < 0) { + PyErr_SetString(PyExc_ValueError, "timeout must be non-negative"); + return NULL; + } + + deadline = _PyTime_GetMonotonicClock() + timeout; + + do { + if (_PyTime_AsTimespec(timeout, &ts) < 0) + return NULL; + + Py_BEGIN_ALLOW_THREADS res = sigtimedwait(&sigset, &si, &ts); - Py_END_ALLOW_THREADS - - if (res != -1) - break; - - if (errno != EINTR) { - if (errno == EAGAIN) - Py_RETURN_NONE; - else - return PyErr_SetFromErrno(PyExc_OSError); - } - - /* sigtimedwait() was interrupted by a signal (EINTR) */ - if (PyErr_CheckSignals()) - return NULL; - - monotonic = _PyTime_GetMonotonicClock(); - timeout = deadline - monotonic; - if (timeout < 0) - break; - } while (1); - - return fill_siginfo(&si); -} - -#endif /* #ifdef HAVE_SIGTIMEDWAIT */ + Py_END_ALLOW_THREADS + + if (res != -1) + break; + + if (errno != EINTR) { + if (errno == EAGAIN) + Py_RETURN_NONE; + else + return PyErr_SetFromErrno(PyExc_OSError); + } + + /* sigtimedwait() was interrupted by a signal (EINTR) */ + if (PyErr_CheckSignals()) + return NULL; + + monotonic = _PyTime_GetMonotonicClock(); + timeout = deadline - monotonic; + if (timeout < 0) + break; + } while (1); + + return fill_siginfo(&si); +} + +#endif /* #ifdef HAVE_SIGTIMEDWAIT */ #endif /* #ifdef HAVE_SIGSET_T */ - - -#if defined(HAVE_PTHREAD_KILL) - -/*[clinic input] -signal.pthread_kill - - thread_id: unsigned_long(bitwise=True) - signalnum: int - / - -Send a signal to a thread. -[clinic start generated code]*/ - -static PyObject * -signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, - int signalnum) -/*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/ -{ - int err; - + + +#if defined(HAVE_PTHREAD_KILL) + +/*[clinic input] +signal.pthread_kill + + thread_id: unsigned_long(bitwise=True) + signalnum: int + / + +Send a signal to a thread. +[clinic start generated code]*/ + +static PyObject * +signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, + int signalnum) +/*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/ +{ + int err; + if (PySys_Audit("signal.pthread_kill", "ki", thread_id, signalnum) < 0) { return NULL; } - err = pthread_kill((pthread_t)thread_id, signalnum); - if (err != 0) { - errno = err; - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - /* the signal may have been send to the current thread */ - if (PyErr_CheckSignals()) - return NULL; - - Py_RETURN_NONE; -} - -#endif /* #if defined(HAVE_PTHREAD_KILL) */ - - + err = pthread_kill((pthread_t)thread_id, signalnum); + if (err != 0) { + errno = err; + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + /* the signal may have been send to the current thread */ + if (PyErr_CheckSignals()) + return NULL; + + Py_RETURN_NONE; +} + +#endif /* #if defined(HAVE_PTHREAD_KILL) */ + + #if defined(__linux__) && defined(__NR_pidfd_send_signal) /*[clinic input] signal.pidfd_send_signal - + pidfd: int signalnum: int siginfo: object = None @@ -1301,382 +1301,382 @@ signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum, -/* List of functions defined in the module -- some of the methoddefs are - defined to nothing if the corresponding C function is not available. */ -static PyMethodDef signal_methods[] = { - {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc}, - SIGNAL_ALARM_METHODDEF - SIGNAL_SETITIMER_METHODDEF - SIGNAL_GETITIMER_METHODDEF - SIGNAL_SIGNAL_METHODDEF +/* List of functions defined in the module -- some of the methoddefs are + defined to nothing if the corresponding C function is not available. */ +static PyMethodDef signal_methods[] = { + {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc}, + SIGNAL_ALARM_METHODDEF + SIGNAL_SETITIMER_METHODDEF + SIGNAL_GETITIMER_METHODDEF + SIGNAL_SIGNAL_METHODDEF SIGNAL_RAISE_SIGNAL_METHODDEF SIGNAL_STRSIGNAL_METHODDEF - SIGNAL_GETSIGNAL_METHODDEF + SIGNAL_GETSIGNAL_METHODDEF {"set_wakeup_fd", (PyCFunction)(void(*)(void))signal_set_wakeup_fd, METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc}, - SIGNAL_SIGINTERRUPT_METHODDEF - SIGNAL_PAUSE_METHODDEF + SIGNAL_SIGINTERRUPT_METHODDEF + SIGNAL_PAUSE_METHODDEF SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF - SIGNAL_PTHREAD_KILL_METHODDEF - SIGNAL_PTHREAD_SIGMASK_METHODDEF - SIGNAL_SIGPENDING_METHODDEF - SIGNAL_SIGWAIT_METHODDEF - SIGNAL_SIGWAITINFO_METHODDEF - SIGNAL_SIGTIMEDWAIT_METHODDEF + SIGNAL_PTHREAD_KILL_METHODDEF + SIGNAL_PTHREAD_SIGMASK_METHODDEF + SIGNAL_SIGPENDING_METHODDEF + SIGNAL_SIGWAIT_METHODDEF + SIGNAL_SIGWAITINFO_METHODDEF + SIGNAL_SIGTIMEDWAIT_METHODDEF #if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) SIGNAL_VALID_SIGNALS_METHODDEF #endif - {NULL, NULL} /* sentinel */ -}; - - -PyDoc_STRVAR(module_doc, -"This module provides mechanisms to use signal handlers in Python.\n\ -\n\ -Functions:\n\ -\n\ -alarm() -- cause SIGALRM after a specified time [Unix only]\n\ -setitimer() -- cause a signal (described below) after a specified\n\ - float time and the timer may restart then [Unix only]\n\ -getitimer() -- get current value of timer [Unix only]\n\ -signal() -- set the action for a given signal\n\ -getsignal() -- get the signal action for a given signal\n\ -pause() -- wait until a signal arrives [Unix only]\n\ -default_int_handler() -- default SIGINT handler\n\ -\n\ -signal constants:\n\ -SIG_DFL -- used to refer to the system default handler\n\ -SIG_IGN -- used to ignore the signal\n\ -NSIG -- number of defined signals\n\ -SIGINT, SIGTERM, etc. -- signal numbers\n\ -\n\ -itimer constants:\n\ -ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\ - expiration\n\ -ITIMER_VIRTUAL -- decrements only when the process is executing,\n\ - and delivers SIGVTALRM upon expiration\n\ -ITIMER_PROF -- decrements both when the process is executing and\n\ - when the system is executing on behalf of the process.\n\ - Coupled with ITIMER_VIRTUAL, this timer is usually\n\ - used to profile the time spent by the application\n\ - in user and kernel space. SIGPROF is delivered upon\n\ - expiration.\n\ -\n\n\ -*** IMPORTANT NOTICE ***\n\ -A signal handler function is called with two arguments:\n\ -the first is the signal number, the second is the interrupted stack frame."); - -static struct PyModuleDef signalmodule = { - PyModuleDef_HEAD_INIT, - "_signal", - module_doc, - -1, - signal_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__signal(void) -{ + {NULL, NULL} /* sentinel */ +}; + + +PyDoc_STRVAR(module_doc, +"This module provides mechanisms to use signal handlers in Python.\n\ +\n\ +Functions:\n\ +\n\ +alarm() -- cause SIGALRM after a specified time [Unix only]\n\ +setitimer() -- cause a signal (described below) after a specified\n\ + float time and the timer may restart then [Unix only]\n\ +getitimer() -- get current value of timer [Unix only]\n\ +signal() -- set the action for a given signal\n\ +getsignal() -- get the signal action for a given signal\n\ +pause() -- wait until a signal arrives [Unix only]\n\ +default_int_handler() -- default SIGINT handler\n\ +\n\ +signal constants:\n\ +SIG_DFL -- used to refer to the system default handler\n\ +SIG_IGN -- used to ignore the signal\n\ +NSIG -- number of defined signals\n\ +SIGINT, SIGTERM, etc. -- signal numbers\n\ +\n\ +itimer constants:\n\ +ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\ + expiration\n\ +ITIMER_VIRTUAL -- decrements only when the process is executing,\n\ + and delivers SIGVTALRM upon expiration\n\ +ITIMER_PROF -- decrements both when the process is executing and\n\ + when the system is executing on behalf of the process.\n\ + Coupled with ITIMER_VIRTUAL, this timer is usually\n\ + used to profile the time spent by the application\n\ + in user and kernel space. SIGPROF is delivered upon\n\ + expiration.\n\ +\n\n\ +*** IMPORTANT NOTICE ***\n\ +A signal handler function is called with two arguments:\n\ +the first is the signal number, the second is the interrupted stack frame."); + +static struct PyModuleDef signalmodule = { + PyModuleDef_HEAD_INIT, + "_signal", + module_doc, + -1, + signal_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__signal(void) +{ PyObject *m, *d; - int i; - - /* Create the module and add the functions */ - m = PyModule_Create(&signalmodule); - if (m == NULL) - return NULL; - -#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) - if (!initialized) { - if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) - return NULL; - } - Py_INCREF((PyObject*) &SiginfoType); - PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType); - initialized = 1; -#endif - - /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); - + int i; + + /* Create the module and add the functions */ + m = PyModule_Create(&signalmodule); + if (m == NULL) + return NULL; + +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) + if (!initialized) { + if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) + return NULL; + } + Py_INCREF((PyObject*) &SiginfoType); + PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType); + initialized = 1; +#endif + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); if (!DefaultHandler || PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) { - goto finally; + goto finally; } - + IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); if (!IgnoreHandler || PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) { - goto finally; + goto finally; } - + if (PyModule_AddIntMacro(m, NSIG)) - goto finally; - -#ifdef SIG_BLOCK - if (PyModule_AddIntMacro(m, SIG_BLOCK)) - goto finally; -#endif -#ifdef SIG_UNBLOCK - if (PyModule_AddIntMacro(m, SIG_UNBLOCK)) - goto finally; -#endif -#ifdef SIG_SETMASK - if (PyModule_AddIntMacro(m, SIG_SETMASK)) - goto finally; -#endif - + goto finally; + +#ifdef SIG_BLOCK + if (PyModule_AddIntMacro(m, SIG_BLOCK)) + goto finally; +#endif +#ifdef SIG_UNBLOCK + if (PyModule_AddIntMacro(m, SIG_UNBLOCK)) + goto finally; +#endif +#ifdef SIG_SETMASK + if (PyModule_AddIntMacro(m, SIG_SETMASK)) + goto finally; +#endif + IntHandler = PyDict_GetItemString(d, "default_int_handler"); if (!IntHandler) - goto finally; - Py_INCREF(IntHandler); - - _Py_atomic_store_relaxed(&Handlers[0].tripped, 0); - for (i = 1; i < NSIG; i++) { - void (*t)(int); - t = PyOS_getsig(i); - _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); - if (t == SIG_DFL) - Handlers[i].func = DefaultHandler; - else if (t == SIG_IGN) - Handlers[i].func = IgnoreHandler; - else - Handlers[i].func = Py_None; /* None of our business */ - Py_INCREF(Handlers[i].func); - } - if (Handlers[SIGINT].func == DefaultHandler) { - /* Install default int handler */ - Py_INCREF(IntHandler); - Py_SETREF(Handlers[SIGINT].func, IntHandler); - PyOS_setsig(SIGINT, signal_handler); - } - -#ifdef SIGHUP - if (PyModule_AddIntMacro(m, SIGHUP)) - goto finally; -#endif -#ifdef SIGINT - if (PyModule_AddIntMacro(m, SIGINT)) - goto finally; -#endif -#ifdef SIGBREAK - if (PyModule_AddIntMacro(m, SIGBREAK)) - goto finally; -#endif -#ifdef SIGQUIT - if (PyModule_AddIntMacro(m, SIGQUIT)) - goto finally; -#endif -#ifdef SIGILL - if (PyModule_AddIntMacro(m, SIGILL)) - goto finally; -#endif -#ifdef SIGTRAP - if (PyModule_AddIntMacro(m, SIGTRAP)) - goto finally; -#endif -#ifdef SIGIOT - if (PyModule_AddIntMacro(m, SIGIOT)) - goto finally; -#endif -#ifdef SIGABRT - if (PyModule_AddIntMacro(m, SIGABRT)) - goto finally; -#endif -#ifdef SIGEMT - if (PyModule_AddIntMacro(m, SIGEMT)) - goto finally; -#endif -#ifdef SIGFPE - if (PyModule_AddIntMacro(m, SIGFPE)) - goto finally; -#endif -#ifdef SIGKILL - if (PyModule_AddIntMacro(m, SIGKILL)) - goto finally; -#endif -#ifdef SIGBUS - if (PyModule_AddIntMacro(m, SIGBUS)) - goto finally; -#endif -#ifdef SIGSEGV - if (PyModule_AddIntMacro(m, SIGSEGV)) - goto finally; -#endif -#ifdef SIGSYS - if (PyModule_AddIntMacro(m, SIGSYS)) - goto finally; -#endif -#ifdef SIGPIPE - if (PyModule_AddIntMacro(m, SIGPIPE)) - goto finally; -#endif -#ifdef SIGALRM - if (PyModule_AddIntMacro(m, SIGALRM)) - goto finally; -#endif -#ifdef SIGTERM - if (PyModule_AddIntMacro(m, SIGTERM)) - goto finally; -#endif -#ifdef SIGUSR1 - if (PyModule_AddIntMacro(m, SIGUSR1)) - goto finally; -#endif -#ifdef SIGUSR2 - if (PyModule_AddIntMacro(m, SIGUSR2)) - goto finally; -#endif -#ifdef SIGCLD - if (PyModule_AddIntMacro(m, SIGCLD)) - goto finally; -#endif -#ifdef SIGCHLD - if (PyModule_AddIntMacro(m, SIGCHLD)) - goto finally; -#endif -#ifdef SIGPWR - if (PyModule_AddIntMacro(m, SIGPWR)) - goto finally; -#endif -#ifdef SIGIO - if (PyModule_AddIntMacro(m, SIGIO)) - goto finally; -#endif -#ifdef SIGURG - if (PyModule_AddIntMacro(m, SIGURG)) - goto finally; -#endif -#ifdef SIGWINCH - if (PyModule_AddIntMacro(m, SIGWINCH)) - goto finally; -#endif -#ifdef SIGPOLL - if (PyModule_AddIntMacro(m, SIGPOLL)) - goto finally; -#endif -#ifdef SIGSTOP - if (PyModule_AddIntMacro(m, SIGSTOP)) - goto finally; -#endif -#ifdef SIGTSTP - if (PyModule_AddIntMacro(m, SIGTSTP)) - goto finally; -#endif -#ifdef SIGCONT - if (PyModule_AddIntMacro(m, SIGCONT)) - goto finally; -#endif -#ifdef SIGTTIN - if (PyModule_AddIntMacro(m, SIGTTIN)) - goto finally; -#endif -#ifdef SIGTTOU - if (PyModule_AddIntMacro(m, SIGTTOU)) - goto finally; -#endif -#ifdef SIGVTALRM - if (PyModule_AddIntMacro(m, SIGVTALRM)) - goto finally; -#endif -#ifdef SIGPROF - if (PyModule_AddIntMacro(m, SIGPROF)) - goto finally; -#endif -#ifdef SIGXCPU - if (PyModule_AddIntMacro(m, SIGXCPU)) - goto finally; -#endif -#ifdef SIGXFSZ - if (PyModule_AddIntMacro(m, SIGXFSZ)) - goto finally; -#endif -#ifdef SIGRTMIN - if (PyModule_AddIntMacro(m, SIGRTMIN)) - goto finally; -#endif -#ifdef SIGRTMAX - if (PyModule_AddIntMacro(m, SIGRTMAX)) - goto finally; -#endif -#ifdef SIGINFO - if (PyModule_AddIntMacro(m, SIGINFO)) - goto finally; -#endif - -#ifdef ITIMER_REAL - if (PyModule_AddIntMacro(m, ITIMER_REAL)) - goto finally; -#endif -#ifdef ITIMER_VIRTUAL - if (PyModule_AddIntMacro(m, ITIMER_VIRTUAL)) - goto finally; -#endif -#ifdef ITIMER_PROF - if (PyModule_AddIntMacro(m, ITIMER_PROF)) - goto finally; -#endif - -#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) - ItimerError = PyErr_NewException("signal.ItimerError", - PyExc_OSError, NULL); + goto finally; + Py_INCREF(IntHandler); + + _Py_atomic_store_relaxed(&Handlers[0].tripped, 0); + for (i = 1; i < NSIG; i++) { + void (*t)(int); + t = PyOS_getsig(i); + _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); + if (t == SIG_DFL) + Handlers[i].func = DefaultHandler; + else if (t == SIG_IGN) + Handlers[i].func = IgnoreHandler; + else + Handlers[i].func = Py_None; /* None of our business */ + Py_INCREF(Handlers[i].func); + } + if (Handlers[SIGINT].func == DefaultHandler) { + /* Install default int handler */ + Py_INCREF(IntHandler); + Py_SETREF(Handlers[SIGINT].func, IntHandler); + PyOS_setsig(SIGINT, signal_handler); + } + +#ifdef SIGHUP + if (PyModule_AddIntMacro(m, SIGHUP)) + goto finally; +#endif +#ifdef SIGINT + if (PyModule_AddIntMacro(m, SIGINT)) + goto finally; +#endif +#ifdef SIGBREAK + if (PyModule_AddIntMacro(m, SIGBREAK)) + goto finally; +#endif +#ifdef SIGQUIT + if (PyModule_AddIntMacro(m, SIGQUIT)) + goto finally; +#endif +#ifdef SIGILL + if (PyModule_AddIntMacro(m, SIGILL)) + goto finally; +#endif +#ifdef SIGTRAP + if (PyModule_AddIntMacro(m, SIGTRAP)) + goto finally; +#endif +#ifdef SIGIOT + if (PyModule_AddIntMacro(m, SIGIOT)) + goto finally; +#endif +#ifdef SIGABRT + if (PyModule_AddIntMacro(m, SIGABRT)) + goto finally; +#endif +#ifdef SIGEMT + if (PyModule_AddIntMacro(m, SIGEMT)) + goto finally; +#endif +#ifdef SIGFPE + if (PyModule_AddIntMacro(m, SIGFPE)) + goto finally; +#endif +#ifdef SIGKILL + if (PyModule_AddIntMacro(m, SIGKILL)) + goto finally; +#endif +#ifdef SIGBUS + if (PyModule_AddIntMacro(m, SIGBUS)) + goto finally; +#endif +#ifdef SIGSEGV + if (PyModule_AddIntMacro(m, SIGSEGV)) + goto finally; +#endif +#ifdef SIGSYS + if (PyModule_AddIntMacro(m, SIGSYS)) + goto finally; +#endif +#ifdef SIGPIPE + if (PyModule_AddIntMacro(m, SIGPIPE)) + goto finally; +#endif +#ifdef SIGALRM + if (PyModule_AddIntMacro(m, SIGALRM)) + goto finally; +#endif +#ifdef SIGTERM + if (PyModule_AddIntMacro(m, SIGTERM)) + goto finally; +#endif +#ifdef SIGUSR1 + if (PyModule_AddIntMacro(m, SIGUSR1)) + goto finally; +#endif +#ifdef SIGUSR2 + if (PyModule_AddIntMacro(m, SIGUSR2)) + goto finally; +#endif +#ifdef SIGCLD + if (PyModule_AddIntMacro(m, SIGCLD)) + goto finally; +#endif +#ifdef SIGCHLD + if (PyModule_AddIntMacro(m, SIGCHLD)) + goto finally; +#endif +#ifdef SIGPWR + if (PyModule_AddIntMacro(m, SIGPWR)) + goto finally; +#endif +#ifdef SIGIO + if (PyModule_AddIntMacro(m, SIGIO)) + goto finally; +#endif +#ifdef SIGURG + if (PyModule_AddIntMacro(m, SIGURG)) + goto finally; +#endif +#ifdef SIGWINCH + if (PyModule_AddIntMacro(m, SIGWINCH)) + goto finally; +#endif +#ifdef SIGPOLL + if (PyModule_AddIntMacro(m, SIGPOLL)) + goto finally; +#endif +#ifdef SIGSTOP + if (PyModule_AddIntMacro(m, SIGSTOP)) + goto finally; +#endif +#ifdef SIGTSTP + if (PyModule_AddIntMacro(m, SIGTSTP)) + goto finally; +#endif +#ifdef SIGCONT + if (PyModule_AddIntMacro(m, SIGCONT)) + goto finally; +#endif +#ifdef SIGTTIN + if (PyModule_AddIntMacro(m, SIGTTIN)) + goto finally; +#endif +#ifdef SIGTTOU + if (PyModule_AddIntMacro(m, SIGTTOU)) + goto finally; +#endif +#ifdef SIGVTALRM + if (PyModule_AddIntMacro(m, SIGVTALRM)) + goto finally; +#endif +#ifdef SIGPROF + if (PyModule_AddIntMacro(m, SIGPROF)) + goto finally; +#endif +#ifdef SIGXCPU + if (PyModule_AddIntMacro(m, SIGXCPU)) + goto finally; +#endif +#ifdef SIGXFSZ + if (PyModule_AddIntMacro(m, SIGXFSZ)) + goto finally; +#endif +#ifdef SIGRTMIN + if (PyModule_AddIntMacro(m, SIGRTMIN)) + goto finally; +#endif +#ifdef SIGRTMAX + if (PyModule_AddIntMacro(m, SIGRTMAX)) + goto finally; +#endif +#ifdef SIGINFO + if (PyModule_AddIntMacro(m, SIGINFO)) + goto finally; +#endif + +#ifdef ITIMER_REAL + if (PyModule_AddIntMacro(m, ITIMER_REAL)) + goto finally; +#endif +#ifdef ITIMER_VIRTUAL + if (PyModule_AddIntMacro(m, ITIMER_VIRTUAL)) + goto finally; +#endif +#ifdef ITIMER_PROF + if (PyModule_AddIntMacro(m, ITIMER_PROF)) + goto finally; +#endif + +#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) + ItimerError = PyErr_NewException("signal.ItimerError", + PyExc_OSError, NULL); if (!ItimerError || PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) { goto finally; } -#endif - -#ifdef CTRL_C_EVENT - if (PyModule_AddIntMacro(m, CTRL_C_EVENT)) - goto finally; -#endif - -#ifdef CTRL_BREAK_EVENT - if (PyModule_AddIntMacro(m, CTRL_BREAK_EVENT)) - goto finally; -#endif - - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; - } - - finally: - return m; -} - -static void -finisignal(void) -{ - int i; - PyObject *func; - - for (i = 1; i < NSIG; i++) { - func = Handlers[i].func; - _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); - Handlers[i].func = NULL; - if (func != NULL && func != Py_None && - func != DefaultHandler && func != IgnoreHandler) - PyOS_setsig(i, SIG_DFL); - Py_XDECREF(func); - } - - Py_CLEAR(IntHandler); - Py_CLEAR(DefaultHandler); - Py_CLEAR(IgnoreHandler); +#endif + +#ifdef CTRL_C_EVENT + if (PyModule_AddIntMacro(m, CTRL_C_EVENT)) + goto finally; +#endif + +#ifdef CTRL_BREAK_EVENT + if (PyModule_AddIntMacro(m, CTRL_BREAK_EVENT)) + goto finally; +#endif + + if (PyErr_Occurred()) { + Py_DECREF(m); + m = NULL; + } + + finally: + return m; +} + +static void +finisignal(void) +{ + int i; + PyObject *func; + + for (i = 1; i < NSIG; i++) { + func = Handlers[i].func; + _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); + Handlers[i].func = NULL; + if (func != NULL && func != Py_None && + func != DefaultHandler && func != IgnoreHandler) + PyOS_setsig(i, SIG_DFL); + Py_XDECREF(func); + } + + Py_CLEAR(IntHandler); + Py_CLEAR(DefaultHandler); + Py_CLEAR(IgnoreHandler); #ifdef HAVE_GETITIMER Py_CLEAR(ItimerError); #endif -} - - -/* Declared in pyerrors.h */ -int -PyErr_CheckSignals(void) -{ +} + + +/* Declared in pyerrors.h */ +int +PyErr_CheckSignals(void) +{ PyThreadState *tstate = _PyThreadState_GET(); if (!_Py_ThreadCanHandleSignals(tstate->interp)) { return 0; @@ -1691,36 +1691,36 @@ int _PyErr_CheckSignalsTstate(PyThreadState *tstate) { if (!_Py_atomic_load(&is_tripped)) { - return 0; + return 0; } - - /* - * The is_tripped variable is meant to speed up the calls to - * PyErr_CheckSignals (both directly or via pending calls) when no - * signal has arrived. This variable is set to 1 when a signal arrives - * and it is set to 0 here, when we know some signals arrived. This way - * we can run the registered handlers with no signals blocked. - * - * NOTE: with this approach we can have a situation where is_tripped is - * 1 but we have no more signals to handle (Handlers[i].tripped - * is 0 for every signal i). This won't do us any harm (except - * we're gonna spent some cycles for nothing). This happens when - * we receive a signal i after we zero is_tripped and before we - * check Handlers[i].tripped. - */ - _Py_atomic_store(&is_tripped, 0); - + + /* + * The is_tripped variable is meant to speed up the calls to + * PyErr_CheckSignals (both directly or via pending calls) when no + * signal has arrived. This variable is set to 1 when a signal arrives + * and it is set to 0 here, when we know some signals arrived. This way + * we can run the registered handlers with no signals blocked. + * + * NOTE: with this approach we can have a situation where is_tripped is + * 1 but we have no more signals to handle (Handlers[i].tripped + * is 0 for every signal i). This won't do us any harm (except + * we're gonna spent some cycles for nothing). This happens when + * we receive a signal i after we zero is_tripped and before we + * check Handlers[i].tripped. + */ + _Py_atomic_store(&is_tripped, 0); + PyObject *frame = (PyObject *)tstate->frame; if (!frame) { frame = Py_None; } - + for (int i = 1; i < NSIG; i++) { if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) { continue; } _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); - + /* Signal handlers can be modified while a signal is received, * and therefore the fact that trip_signal() or PyErr_SetInterrupt() * was called doesn't guarantee that there is still a Python @@ -1759,14 +1759,14 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) _Py_atomic_store(&is_tripped, 1); return -1; } - + Py_DECREF(result); - } - - return 0; -} - - + } + + return 0; +} + + int _PyErr_CheckSignals(void) @@ -1781,24 +1781,24 @@ _PyErr_CheckSignals(void) raised. Missing signal handler for the SIGINT signal is silently ignored. */ -void -PyErr_SetInterrupt(void) -{ +void +PyErr_SetInterrupt(void) +{ if ((Handlers[SIGINT].func != IgnoreHandler) && (Handlers[SIGINT].func != DefaultHandler)) { trip_signal(SIGINT); } -} - -void -PyOS_InitInterrupts(void) -{ - PyObject *m = PyImport_ImportModule("_signal"); - if (m) { - Py_DECREF(m); - } -} - +} + +void +PyOS_InitInterrupts(void) +{ + PyObject *m = PyImport_ImportModule("_signal"); + if (m) { + Py_DECREF(m); + } +} + static int signal_install_handlers(void) @@ -1846,21 +1846,21 @@ _PySignal_Init(int install_signal_handlers) } -void -PyOS_FiniInterrupts(void) -{ - finisignal(); -} - +void +PyOS_FiniInterrupts(void) +{ + finisignal(); +} + // The caller doesn't have to hold the GIL -int +int _PyOS_InterruptOccurred(PyThreadState *tstate) -{ +{ _Py_EnsureTstateNotNULL(tstate); if (!_Py_ThreadCanHandleSignals(tstate->interp)) { return 0; - } + } if (!_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) { return 0; @@ -1868,8 +1868,8 @@ _PyOS_InterruptOccurred(PyThreadState *tstate) _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0); return 1; -} - +} + // The caller must to hold the GIL int @@ -1880,42 +1880,42 @@ PyOS_InterruptOccurred(void) } -static void -_clear_pending_signals(void) -{ - int i; - if (!_Py_atomic_load(&is_tripped)) - return; - _Py_atomic_store(&is_tripped, 0); - for (i = 1; i < NSIG; ++i) { - _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); - } -} - -void -_PySignal_AfterFork(void) -{ - /* Clear the signal flags after forking so that they aren't handled - * in both processes if they came in just before the fork() but before - * the interpreter had an opportunity to call the handlers. issue9535. */ - _clear_pending_signals(); -} - -int -_PyOS_IsMainThread(void) -{ +static void +_clear_pending_signals(void) +{ + int i; + if (!_Py_atomic_load(&is_tripped)) + return; + _Py_atomic_store(&is_tripped, 0); + for (i = 1; i < NSIG; ++i) { + _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); + } +} + +void +_PySignal_AfterFork(void) +{ + /* Clear the signal flags after forking so that they aren't handled + * in both processes if they came in just before the fork() but before + * the interpreter had an opportunity to call the handlers. issue9535. */ + _clear_pending_signals(); +} + +int +_PyOS_IsMainThread(void) +{ PyInterpreterState *interp = _PyInterpreterState_GET(); return _Py_ThreadCanHandleSignals(interp); -} - -#ifdef MS_WINDOWS -void *_PyOS_SigintEvent(void) -{ - /* Returns a manual-reset event which gets tripped whenever - SIGINT is received. - - Python.h does not include windows.h so we do cannot use HANDLE - as the return type of this function. We use void* instead. */ - return sigint_event; -} -#endif +} + +#ifdef MS_WINDOWS +void *_PyOS_SigintEvent(void) +{ + /* Returns a manual-reset event which gets tripped whenever + SIGINT is received. + + Python.h does not include windows.h so we do cannot use HANDLE + as the return type of this function. We use void* instead. */ + return sigint_event; +} +#endif diff --git a/contrib/tools/python3/src/Modules/socketmodule.c b/contrib/tools/python3/src/Modules/socketmodule.c index 5ac2ee510f6..0152b6af891 100644 --- a/contrib/tools/python3/src/Modules/socketmodule.c +++ b/contrib/tools/python3/src/Modules/socketmodule.c @@ -1,313 +1,313 @@ -/* Socket module */ - -/* - -This module provides an interface to Berkeley socket IPC. - -Limitations: - -- Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a +/* Socket module */ + +/* + +This module provides an interface to Berkeley socket IPC. + +Limitations: + +- Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a portable manner, though AF_PACKET, AF_NETLINK, AF_QIPCRTR and AF_TIPC are supported under Linux. -- No read/write operations (use sendall/recv or makefile instead). -- Additional restrictions apply on some non-Unix platforms (compensated - for by socket.py). - -Module interface: - -- socket.error: exception raised for socket specific errors, alias for OSError -- socket.gaierror: exception raised for getaddrinfo/getnameinfo errors, - a subclass of socket.error -- socket.herror: exception raised for gethostby* errors, - a subclass of socket.error -- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd') -- socket.gethostbyaddr(IP address) --> (hostname, [alias, ...], [IP addr, ...]) -- socket.gethostname() --> host name (string: 'spam' or 'spam.domain.com') -- socket.getprotobyname(protocolname) --> protocol number -- socket.getservbyname(servicename[, protocolname]) --> port number -- socket.getservbyport(portnumber[, protocolname]) --> service name -- socket.socket([family[, type [, proto, fileno]]]) --> new socket object - (fileno specifies a pre-existing socket file descriptor) -- socket.socketpair([family[, type [, proto]]]) --> (socket, socket) -- socket.ntohs(16 bit value) --> new int object -- socket.ntohl(32 bit value) --> new int object -- socket.htons(16 bit value) --> new int object -- socket.htonl(32 bit value) --> new int object -- socket.getaddrinfo(host, port [, family, type, proto, flags]) - --> List of (family, type, proto, canonname, sockaddr) -- socket.getnameinfo(sockaddr, flags) --> (host, port) -- socket.AF_INET, socket.SOCK_STREAM, etc.: constants from -- socket.has_ipv6: boolean value indicating if IPv6 is supported -- socket.inet_aton(IP address) -> 32-bit packed IP representation -- socket.inet_ntoa(packed IP) -> IP address string -- socket.getdefaulttimeout() -> None | float -- socket.setdefaulttimeout(None | float) -- socket.if_nameindex() -> list of tuples (if_index, if_name) -- socket.if_nametoindex(name) -> corresponding interface index -- socket.if_indextoname(index) -> corresponding interface name -- an Internet socket address is a pair (hostname, port) - where hostname can be anything recognized by gethostbyname() - (including the dd.dd.dd.dd notation) and port is in host byte order -- where a hostname is returned, the dd.dd.dd.dd notation is used -- a UNIX domain socket address is a string specifying the pathname -- an AF_PACKET socket address is a tuple containing a string - specifying the ethernet interface and an integer specifying - the Ethernet protocol number to be received. For example: - ("eth0",0x1234). Optional 3rd,4th,5th elements in the tuple - specify packet-type and ha-type/addr. +- No read/write operations (use sendall/recv or makefile instead). +- Additional restrictions apply on some non-Unix platforms (compensated + for by socket.py). + +Module interface: + +- socket.error: exception raised for socket specific errors, alias for OSError +- socket.gaierror: exception raised for getaddrinfo/getnameinfo errors, + a subclass of socket.error +- socket.herror: exception raised for gethostby* errors, + a subclass of socket.error +- socket.gethostbyname(hostname) --> host IP address (string: 'dd.dd.dd.dd') +- socket.gethostbyaddr(IP address) --> (hostname, [alias, ...], [IP addr, ...]) +- socket.gethostname() --> host name (string: 'spam' or 'spam.domain.com') +- socket.getprotobyname(protocolname) --> protocol number +- socket.getservbyname(servicename[, protocolname]) --> port number +- socket.getservbyport(portnumber[, protocolname]) --> service name +- socket.socket([family[, type [, proto, fileno]]]) --> new socket object + (fileno specifies a pre-existing socket file descriptor) +- socket.socketpair([family[, type [, proto]]]) --> (socket, socket) +- socket.ntohs(16 bit value) --> new int object +- socket.ntohl(32 bit value) --> new int object +- socket.htons(16 bit value) --> new int object +- socket.htonl(32 bit value) --> new int object +- socket.getaddrinfo(host, port [, family, type, proto, flags]) + --> List of (family, type, proto, canonname, sockaddr) +- socket.getnameinfo(sockaddr, flags) --> (host, port) +- socket.AF_INET, socket.SOCK_STREAM, etc.: constants from +- socket.has_ipv6: boolean value indicating if IPv6 is supported +- socket.inet_aton(IP address) -> 32-bit packed IP representation +- socket.inet_ntoa(packed IP) -> IP address string +- socket.getdefaulttimeout() -> None | float +- socket.setdefaulttimeout(None | float) +- socket.if_nameindex() -> list of tuples (if_index, if_name) +- socket.if_nametoindex(name) -> corresponding interface index +- socket.if_indextoname(index) -> corresponding interface name +- an Internet socket address is a pair (hostname, port) + where hostname can be anything recognized by gethostbyname() + (including the dd.dd.dd.dd notation) and port is in host byte order +- where a hostname is returned, the dd.dd.dd.dd notation is used +- a UNIX domain socket address is a string specifying the pathname +- an AF_PACKET socket address is a tuple containing a string + specifying the ethernet interface and an integer specifying + the Ethernet protocol number to be received. For example: + ("eth0",0x1234). Optional 3rd,4th,5th elements in the tuple + specify packet-type and ha-type/addr. - an AF_QIPCRTR socket address is a (node, port) tuple where the node and port are non-negative integers. -- an AF_TIPC socket address is expressed as - (addr_type, v1, v2, v3 [, scope]); where addr_type can be one of: - TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, and TIPC_ADDR_ID; - and scope can be one of: - TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and TIPC_NODE_SCOPE. - The meaning of v1, v2 and v3 depends on the value of addr_type: - if addr_type is TIPC_ADDR_NAME: - v1 is the server type - v2 is the port identifier - v3 is ignored - if addr_type is TIPC_ADDR_NAMESEQ: - v1 is the server type - v2 is the lower port number - v3 is the upper port number - if addr_type is TIPC_ADDR_ID: - v1 is the node - v2 is the ref - v3 is ignored - - -Local naming conventions: - -- names starting with sock_ are socket object methods -- names starting with socket_ are module-level functions -- names starting with PySocket are exported through socketmodule.h - -*/ - -#include -bool IsReusePortAvailable(); - -#if !defined(SO_REUSEPORT) && defined(__linux__) -#define SO_REUSEPORT 15 -#endif - -#ifdef __APPLE__ -#include -/* for getaddrinfo thread safety test on old versions of OS X */ -#ifndef MAC_OS_X_VERSION_10_5 -#define MAC_OS_X_VERSION_10_5 1050 -#endif - /* - * inet_aton is not available on OSX 10.3, yet we want to use a binary - * that was build on 10.4 or later to work on that release, weak linking - * comes to the rescue. - */ -# pragma weak inet_aton -#endif - +- an AF_TIPC socket address is expressed as + (addr_type, v1, v2, v3 [, scope]); where addr_type can be one of: + TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, and TIPC_ADDR_ID; + and scope can be one of: + TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and TIPC_NODE_SCOPE. + The meaning of v1, v2 and v3 depends on the value of addr_type: + if addr_type is TIPC_ADDR_NAME: + v1 is the server type + v2 is the port identifier + v3 is ignored + if addr_type is TIPC_ADDR_NAMESEQ: + v1 is the server type + v2 is the lower port number + v3 is the upper port number + if addr_type is TIPC_ADDR_ID: + v1 is the node + v2 is the ref + v3 is ignored + + +Local naming conventions: + +- names starting with sock_ are socket object methods +- names starting with socket_ are module-level functions +- names starting with PySocket are exported through socketmodule.h + +*/ + +#include +bool IsReusePortAvailable(); + +#if !defined(SO_REUSEPORT) && defined(__linux__) +#define SO_REUSEPORT 15 +#endif + +#ifdef __APPLE__ +#include +/* for getaddrinfo thread safety test on old versions of OS X */ +#ifndef MAC_OS_X_VERSION_10_5 +#define MAC_OS_X_VERSION_10_5 1050 +#endif + /* + * inet_aton is not available on OSX 10.3, yet we want to use a binary + * that was build on 10.4 or later to work on that release, weak linking + * comes to the rescue. + */ +# pragma weak inet_aton +#endif + #define PY_SSIZE_T_CLEAN -#include "Python.h" +#include "Python.h" #include "structmember.h" // PyMemberDef - -#ifdef _Py_MEMORY_SANITIZER -# include -#endif - -/* Socket object documentation */ -PyDoc_STRVAR(sock_doc, -"socket(family=AF_INET, type=SOCK_STREAM, proto=0) -> socket object\n\ -socket(family=-1, type=-1, proto=-1, fileno=None) -> socket object\n\ -\n\ -Open a socket of the given type. The family argument specifies the\n\ -address family; it defaults to AF_INET. The type argument specifies\n\ -whether this is a stream (SOCK_STREAM, this is the default)\n\ -or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,\n\ -specifying the default protocol. Keyword arguments are accepted.\n\ -The socket is created as non-inheritable.\n\ -\n\ -When a fileno is passed in, family, type and proto are auto-detected,\n\ -unless they are explicitly set.\n\ -\n\ -A socket object represents one endpoint of a network connection.\n\ -\n\ -Methods of socket objects (keyword arguments not allowed):\n\ -\n\ -_accept() -- accept connection, returning new socket fd and client address\n\ -bind(addr) -- bind the socket to a local address\n\ -close() -- close the socket\n\ -connect(addr) -- connect the socket to a remote address\n\ -connect_ex(addr) -- connect, return an error code instead of an exception\n\ -dup() -- return a new socket fd duplicated from fileno()\n\ -fileno() -- return underlying file descriptor\n\ -getpeername() -- return remote address [*]\n\ -getsockname() -- return local address\n\ -getsockopt(level, optname[, buflen]) -- get socket options\n\ -gettimeout() -- return timeout or None\n\ -listen([n]) -- start listening for incoming connections\n\ -recv(buflen[, flags]) -- receive data\n\ -recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\ -recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\ -recvfrom_into(buffer[, nbytes, [, flags])\n\ - -- receive data and sender\'s address (into a buffer)\n\ -sendall(data[, flags]) -- send all data\n\ -send(data[, flags]) -- send data, may not send all of it\n\ -sendto(data[, flags], addr) -- send data to a given address\n\ + +#ifdef _Py_MEMORY_SANITIZER +# include +#endif + +/* Socket object documentation */ +PyDoc_STRVAR(sock_doc, +"socket(family=AF_INET, type=SOCK_STREAM, proto=0) -> socket object\n\ +socket(family=-1, type=-1, proto=-1, fileno=None) -> socket object\n\ +\n\ +Open a socket of the given type. The family argument specifies the\n\ +address family; it defaults to AF_INET. The type argument specifies\n\ +whether this is a stream (SOCK_STREAM, this is the default)\n\ +or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,\n\ +specifying the default protocol. Keyword arguments are accepted.\n\ +The socket is created as non-inheritable.\n\ +\n\ +When a fileno is passed in, family, type and proto are auto-detected,\n\ +unless they are explicitly set.\n\ +\n\ +A socket object represents one endpoint of a network connection.\n\ +\n\ +Methods of socket objects (keyword arguments not allowed):\n\ +\n\ +_accept() -- accept connection, returning new socket fd and client address\n\ +bind(addr) -- bind the socket to a local address\n\ +close() -- close the socket\n\ +connect(addr) -- connect the socket to a remote address\n\ +connect_ex(addr) -- connect, return an error code instead of an exception\n\ +dup() -- return a new socket fd duplicated from fileno()\n\ +fileno() -- return underlying file descriptor\n\ +getpeername() -- return remote address [*]\n\ +getsockname() -- return local address\n\ +getsockopt(level, optname[, buflen]) -- get socket options\n\ +gettimeout() -- return timeout or None\n\ +listen([n]) -- start listening for incoming connections\n\ +recv(buflen[, flags]) -- receive data\n\ +recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\ +recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\ +recvfrom_into(buffer[, nbytes, [, flags])\n\ + -- receive data and sender\'s address (into a buffer)\n\ +sendall(data[, flags]) -- send all data\n\ +send(data[, flags]) -- send data, may not send all of it\n\ +sendto(data[, flags], addr) -- send data to a given address\n\ setblocking(bool) -- set or clear the blocking I/O flag\n\ -getblocking() -- return True if socket is blocking, False if non-blocking\n\ -setsockopt(level, optname, value[, optlen]) -- set socket options\n\ -settimeout(None | float) -- set or clear the timeout\n\ -shutdown(how) -- shut down traffic in one or both directions\n\ -\n\ - [*] not available on all platforms!"); - -/* XXX This is a terrible mess of platform-dependent preprocessor hacks. - I hope some day someone can clean this up please... */ - -/* Hacks for gethostbyname_r(). On some non-Linux platforms, the configure - script doesn't get this right, so we hardcode some platform checks below. - On the other hand, not all Linux versions agree, so there the settings - computed by the configure script are needed! */ - -#ifndef __linux__ -# undef HAVE_GETHOSTBYNAME_R_3_ARG -# undef HAVE_GETHOSTBYNAME_R_5_ARG -# undef HAVE_GETHOSTBYNAME_R_6_ARG -#endif - -#if defined(__OpenBSD__) -# include -#endif - -#if defined(__ANDROID__) && __ANDROID_API__ < 23 -# undef HAVE_GETHOSTBYNAME_R -#endif - -#ifdef HAVE_GETHOSTBYNAME_R -# if defined(_AIX) && !defined(_LINUX_SOURCE_COMPAT) -# define HAVE_GETHOSTBYNAME_R_3_ARG -# elif defined(__sun) || defined(__sgi) -# define HAVE_GETHOSTBYNAME_R_5_ARG -# elif defined(__linux__) -/* Rely on the configure script */ -# elif defined(_LINUX_SOURCE_COMPAT) /* Linux compatibility on AIX */ -# define HAVE_GETHOSTBYNAME_R_6_ARG -# else -# undef HAVE_GETHOSTBYNAME_R -# endif -#endif - -#if !defined(HAVE_GETHOSTBYNAME_R) && !defined(MS_WINDOWS) -# define USE_GETHOSTBYNAME_LOCK -#endif - -/* To use __FreeBSD_version, __OpenBSD__, and __NetBSD_Version__ */ -#ifdef HAVE_SYS_PARAM_H -#include -#endif -/* On systems on which getaddrinfo() is believed to not be thread-safe, - (this includes the getaddrinfo emulation) protect access with a lock. - - getaddrinfo is thread-safe on Mac OS X 10.5 and later. Originally it was - a mix of code including an unsafe implementation from an old BSD's - libresolv. In 10.5 Apple reimplemented it as a safe IPC call to the - mDNSResponder process. 10.5 is the first be UNIX '03 certified, which - includes the requirement that getaddrinfo be thread-safe. See issue #25924. - - It's thread-safe in OpenBSD starting with 5.4, released Nov 2013: - http://www.openbsd.org/plus54.html - - It's thread-safe in NetBSD starting with 4.0, released Dec 2007: - -http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82&r2=1.83 - */ -#if ((defined(__APPLE__) && \ - MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) || \ - (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \ - (defined(__OpenBSD__) && OpenBSD+0 < 201311) || \ - (defined(__NetBSD__) && __NetBSD_Version__+0 < 400000000) || \ - !defined(HAVE_GETADDRINFO)) -#define USE_GETADDRINFO_LOCK -#endif - -#ifdef USE_GETADDRINFO_LOCK -#define ACQUIRE_GETADDRINFO_LOCK PyThread_acquire_lock(netdb_lock, 1); -#define RELEASE_GETADDRINFO_LOCK PyThread_release_lock(netdb_lock); -#else -#define ACQUIRE_GETADDRINFO_LOCK -#define RELEASE_GETADDRINFO_LOCK -#endif - -#if defined(__APPLE__) || defined(__CYGWIN__) || defined(__NetBSD__) +getblocking() -- return True if socket is blocking, False if non-blocking\n\ +setsockopt(level, optname, value[, optlen]) -- set socket options\n\ +settimeout(None | float) -- set or clear the timeout\n\ +shutdown(how) -- shut down traffic in one or both directions\n\ +\n\ + [*] not available on all platforms!"); + +/* XXX This is a terrible mess of platform-dependent preprocessor hacks. + I hope some day someone can clean this up please... */ + +/* Hacks for gethostbyname_r(). On some non-Linux platforms, the configure + script doesn't get this right, so we hardcode some platform checks below. + On the other hand, not all Linux versions agree, so there the settings + computed by the configure script are needed! */ + +#ifndef __linux__ +# undef HAVE_GETHOSTBYNAME_R_3_ARG +# undef HAVE_GETHOSTBYNAME_R_5_ARG +# undef HAVE_GETHOSTBYNAME_R_6_ARG +#endif + +#if defined(__OpenBSD__) +# include +#endif + +#if defined(__ANDROID__) && __ANDROID_API__ < 23 +# undef HAVE_GETHOSTBYNAME_R +#endif + +#ifdef HAVE_GETHOSTBYNAME_R +# if defined(_AIX) && !defined(_LINUX_SOURCE_COMPAT) +# define HAVE_GETHOSTBYNAME_R_3_ARG +# elif defined(__sun) || defined(__sgi) +# define HAVE_GETHOSTBYNAME_R_5_ARG +# elif defined(__linux__) +/* Rely on the configure script */ +# elif defined(_LINUX_SOURCE_COMPAT) /* Linux compatibility on AIX */ +# define HAVE_GETHOSTBYNAME_R_6_ARG +# else +# undef HAVE_GETHOSTBYNAME_R +# endif +#endif + +#if !defined(HAVE_GETHOSTBYNAME_R) && !defined(MS_WINDOWS) +# define USE_GETHOSTBYNAME_LOCK +#endif + +/* To use __FreeBSD_version, __OpenBSD__, and __NetBSD_Version__ */ +#ifdef HAVE_SYS_PARAM_H +#include +#endif +/* On systems on which getaddrinfo() is believed to not be thread-safe, + (this includes the getaddrinfo emulation) protect access with a lock. + + getaddrinfo is thread-safe on Mac OS X 10.5 and later. Originally it was + a mix of code including an unsafe implementation from an old BSD's + libresolv. In 10.5 Apple reimplemented it as a safe IPC call to the + mDNSResponder process. 10.5 is the first be UNIX '03 certified, which + includes the requirement that getaddrinfo be thread-safe. See issue #25924. + + It's thread-safe in OpenBSD starting with 5.4, released Nov 2013: + http://www.openbsd.org/plus54.html + + It's thread-safe in NetBSD starting with 4.0, released Dec 2007: + +http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82&r2=1.83 + */ +#if ((defined(__APPLE__) && \ + MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) || \ + (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \ + (defined(__OpenBSD__) && OpenBSD+0 < 201311) || \ + (defined(__NetBSD__) && __NetBSD_Version__+0 < 400000000) || \ + !defined(HAVE_GETADDRINFO)) +#define USE_GETADDRINFO_LOCK +#endif + +#ifdef USE_GETADDRINFO_LOCK +#define ACQUIRE_GETADDRINFO_LOCK PyThread_acquire_lock(netdb_lock, 1); +#define RELEASE_GETADDRINFO_LOCK PyThread_release_lock(netdb_lock); +#else +#define ACQUIRE_GETADDRINFO_LOCK +#define RELEASE_GETADDRINFO_LOCK +#endif + +#if defined(__APPLE__) || defined(__CYGWIN__) || defined(__NetBSD__) # include -#endif - - -#if defined(__sgi) && _COMPILER_VERSION>700 && !_SGIAPI -/* make sure that the reentrant (gethostbyaddr_r etc) - functions are declared correctly if compiling with - MIPSPro 7.x in ANSI C mode (default) */ - -/* XXX Using _SGIAPI is the wrong thing, - but I don't know what the right thing is. */ -#undef _SGIAPI /* to avoid warning */ -#define _SGIAPI 1 - -#undef _XOPEN_SOURCE -#include -#include -#include -#ifdef _SS_ALIGNSIZE -#define HAVE_GETADDRINFO 1 -#define HAVE_GETNAMEINFO 1 -#endif - -#define HAVE_INET_PTON -#include -#endif - -/* Solaris fails to define this variable at all. */ -#if (defined(__sun) && defined(__SVR4)) && !defined(INET_ADDRSTRLEN) -#define INET_ADDRSTRLEN 16 -#endif - -/* Generic includes */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -#ifdef HAVE_NET_IF_H -#include -#endif - -/* Generic socket object definitions and includes */ -#define PySocket_BUILDING_SOCKET -#include "socketmodule.h" - -/* Addressing includes */ - -#ifndef MS_WINDOWS - -/* Non-MS WINDOWS includes */ -# include -# include - -/* Headers needed for inet_ntoa() and inet_addr() */ -# include - -# include - -#else - -/* MS_WINDOWS includes */ -# ifdef HAVE_FCNTL_H -# include -# endif - +#endif + + +#if defined(__sgi) && _COMPILER_VERSION>700 && !_SGIAPI +/* make sure that the reentrant (gethostbyaddr_r etc) + functions are declared correctly if compiling with + MIPSPro 7.x in ANSI C mode (default) */ + +/* XXX Using _SGIAPI is the wrong thing, + but I don't know what the right thing is. */ +#undef _SGIAPI /* to avoid warning */ +#define _SGIAPI 1 + +#undef _XOPEN_SOURCE +#include +#include +#include +#ifdef _SS_ALIGNSIZE +#define HAVE_GETADDRINFO 1 +#define HAVE_GETNAMEINFO 1 +#endif + +#define HAVE_INET_PTON +#include +#endif + +/* Solaris fails to define this variable at all. */ +#if (defined(__sun) && defined(__SVR4)) && !defined(INET_ADDRSTRLEN) +#define INET_ADDRSTRLEN 16 +#endif + +/* Generic includes */ +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_NET_IF_H +#include +#endif + +/* Generic socket object definitions and includes */ +#define PySocket_BUILDING_SOCKET +#include "socketmodule.h" + +/* Addressing includes */ + +#ifndef MS_WINDOWS + +/* Non-MS WINDOWS includes */ +# include +# include + +/* Headers needed for inet_ntoa() and inet_addr() */ +# include + +# include + +#else + +/* MS_WINDOWS includes */ +# ifdef HAVE_FCNTL_H +# include +# endif + /* Macros based on the IPPROTO enum, see: https://bugs.python.org/issue29515 */ #ifdef MS_WINDOWS #define IPPROTO_ICMP IPPROTO_ICMP @@ -342,182 +342,182 @@ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82& #define IPPROTO_SCTP IPPROTO_SCTP // WinSock2 only #endif /* MS_WINDOWS */ -/* Provides the IsWindows7SP1OrGreater() function */ -#include +/* Provides the IsWindows7SP1OrGreater() function */ +#include // For if_nametoindex() and if_indextoname() #include - -/* remove some flags on older version Windows during run-time. - https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596.aspx */ -typedef struct { - DWORD build_number; /* available starting with this Win10 BuildNumber */ - const char flag_name[20]; -} FlagRuntimeInfo; - -/* IMPORTANT: make sure the list ordered by descending build_number */ -static FlagRuntimeInfo win_runtime_flags[] = { - /* available starting with Windows 10 1709 */ - {16299, "TCP_KEEPIDLE"}, - {16299, "TCP_KEEPINTVL"}, - /* available starting with Windows 10 1703 */ - {15063, "TCP_KEEPCNT"}, - /* available starting with Windows 10 1607 */ - {14393, "TCP_FASTOPEN"} -}; - -static void -remove_unusable_flags(PyObject *m) -{ - PyObject *dict; - OSVERSIONINFOEX info; - DWORDLONG dwlConditionMask; - - dict = PyModule_GetDict(m); - if (dict == NULL) { - return; - } - - /* set to Windows 10, except BuildNumber. */ - memset(&info, 0, sizeof(info)); - info.dwOSVersionInfoSize = sizeof(info); - info.dwMajorVersion = 10; - info.dwMinorVersion = 0; - - /* set Condition Mask */ - dwlConditionMask = 0; - VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); - - for (int i=0; i - -#ifndef O_NONBLOCK -# define O_NONBLOCK O_NDELAY -#endif - -/* include Python's addrinfo.h unless it causes trouble */ -#if defined(__sgi) && _COMPILER_VERSION>700 && defined(_SS_ALIGNSIZE) - /* Do not include addinfo.h on some newer IRIX versions. - * _SS_ALIGNSIZE is defined in sys/socket.h by 6.5.21, - * for example, but not by 6.5.10. - */ -#elif defined(_MSC_VER) && _MSC_VER>1201 - /* Do not include addrinfo.h for MSVC7 or greater. 'addrinfo' and - * EAI_* constants are defined in (the already included) ws2tcpip.h. - */ -#else -# include "addrinfo.h" -#endif - -#ifdef __APPLE__ -/* On OS X, getaddrinfo returns no error indication of lookup - failure, so we must use the emulation instead of the libinfo - implementation. Unfortunately, performing an autoconf test - for this bug would require DNS access for the machine performing - the configuration, which is not acceptable. Therefore, we - determine the bug just by checking for __APPLE__. If this bug - gets ever fixed, perhaps checking for sys/version.h would be - appropriate, which is 10/0 on the system with the bug. */ -#ifndef HAVE_GETNAMEINFO -/* This bug seems to be fixed in Jaguar. The easiest way I could - Find to check for Jaguar is that it has getnameinfo(), which - older releases don't have */ -#undef HAVE_GETADDRINFO -#endif - -#ifdef HAVE_INET_ATON -#define USE_INET_ATON_WEAKLINK -#endif - -#endif - -/* I know this is a bad practice, but it is the easiest... */ -#if !defined(HAVE_GETADDRINFO) -/* avoid clashes with the C library definition of the symbol. */ -#define getaddrinfo fake_getaddrinfo -#define gai_strerror fake_gai_strerror -#define freeaddrinfo fake_freeaddrinfo -#include "getaddrinfo.c" -#endif -#if !defined(HAVE_GETNAMEINFO) -#define getnameinfo fake_getnameinfo -#include "getnameinfo.c" -#endif - -#ifdef MS_WINDOWS -#define SOCKETCLOSE closesocket -#endif - -#ifdef MS_WIN32 + Compatibility Mode will not cheat VerifyVersionInfo(...) */ + if (VerifyVersionInfo( + &info, + VER_MAJORVERSION|VER_MINORVERSION|VER_BUILDNUMBER, + dwlConditionMask)) { + break; + } + else { + if (PyDict_GetItemString( + dict, + win_runtime_flags[i].flag_name) != NULL) + { + if (PyDict_DelItemString( + dict, + win_runtime_flags[i].flag_name)) + { + PyErr_Clear(); + } + } + } + } +} + +#endif + +#include + +#ifndef O_NONBLOCK +# define O_NONBLOCK O_NDELAY +#endif + +/* include Python's addrinfo.h unless it causes trouble */ +#if defined(__sgi) && _COMPILER_VERSION>700 && defined(_SS_ALIGNSIZE) + /* Do not include addinfo.h on some newer IRIX versions. + * _SS_ALIGNSIZE is defined in sys/socket.h by 6.5.21, + * for example, but not by 6.5.10. + */ +#elif defined(_MSC_VER) && _MSC_VER>1201 + /* Do not include addrinfo.h for MSVC7 or greater. 'addrinfo' and + * EAI_* constants are defined in (the already included) ws2tcpip.h. + */ +#else +# include "addrinfo.h" +#endif + +#ifdef __APPLE__ +/* On OS X, getaddrinfo returns no error indication of lookup + failure, so we must use the emulation instead of the libinfo + implementation. Unfortunately, performing an autoconf test + for this bug would require DNS access for the machine performing + the configuration, which is not acceptable. Therefore, we + determine the bug just by checking for __APPLE__. If this bug + gets ever fixed, perhaps checking for sys/version.h would be + appropriate, which is 10/0 on the system with the bug. */ +#ifndef HAVE_GETNAMEINFO +/* This bug seems to be fixed in Jaguar. The easiest way I could + Find to check for Jaguar is that it has getnameinfo(), which + older releases don't have */ +#undef HAVE_GETADDRINFO +#endif + +#ifdef HAVE_INET_ATON +#define USE_INET_ATON_WEAKLINK +#endif + +#endif + +/* I know this is a bad practice, but it is the easiest... */ +#if !defined(HAVE_GETADDRINFO) +/* avoid clashes with the C library definition of the symbol. */ +#define getaddrinfo fake_getaddrinfo +#define gai_strerror fake_gai_strerror +#define freeaddrinfo fake_freeaddrinfo +#include "getaddrinfo.c" +#endif +#if !defined(HAVE_GETNAMEINFO) +#define getnameinfo fake_getnameinfo +#include "getnameinfo.c" +#endif + +#ifdef MS_WINDOWS +#define SOCKETCLOSE closesocket +#endif + +#ifdef MS_WIN32 # undef EAFNOSUPPORT # define EAFNOSUPPORT WSAEAFNOSUPPORT -#endif - -#ifndef SOCKETCLOSE +#endif + +#ifndef SOCKETCLOSE # define SOCKETCLOSE close -#endif - -#if (defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)) && !defined(__NetBSD__) && !defined(__DragonFly__) -#define USE_BLUETOOTH 1 -#if defined(__FreeBSD__) -#define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP -#define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM -#define BTPROTO_HCI BLUETOOTH_PROTO_HCI -#define SOL_HCI SOL_HCI_RAW -#define HCI_FILTER SO_HCI_RAW_FILTER -#define sockaddr_l2 sockaddr_l2cap -#define sockaddr_rc sockaddr_rfcomm -#define hci_dev hci_node -#define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb) -#define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb) -#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb) -#elif defined(__NetBSD__) || defined(__DragonFly__) -#define sockaddr_l2 sockaddr_bt -#define sockaddr_rc sockaddr_bt -#define sockaddr_hci sockaddr_bt -#define sockaddr_sco sockaddr_bt -#define SOL_HCI BTPROTO_HCI -#define HCI_DATA_DIR SO_HCI_DIRECTION -#define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb) -#define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb) -#define _BT_HCI_MEMB(sa, memb) ((sa)->bt_##memb) -#define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb) -#else -#define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb) -#define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb) -#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb) -#define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb) -#endif -#endif - +#endif + +#if (defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)) && !defined(__NetBSD__) && !defined(__DragonFly__) +#define USE_BLUETOOTH 1 +#if defined(__FreeBSD__) +#define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP +#define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM +#define BTPROTO_HCI BLUETOOTH_PROTO_HCI +#define SOL_HCI SOL_HCI_RAW +#define HCI_FILTER SO_HCI_RAW_FILTER +#define sockaddr_l2 sockaddr_l2cap +#define sockaddr_rc sockaddr_rfcomm +#define hci_dev hci_node +#define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb) +#define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb) +#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb) +#elif defined(__NetBSD__) || defined(__DragonFly__) +#define sockaddr_l2 sockaddr_bt +#define sockaddr_rc sockaddr_bt +#define sockaddr_hci sockaddr_bt +#define sockaddr_sco sockaddr_bt +#define SOL_HCI BTPROTO_HCI +#define HCI_DATA_DIR SO_HCI_DIRECTION +#define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb) +#define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb) +#define _BT_HCI_MEMB(sa, memb) ((sa)->bt_##memb) +#define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb) +#else +#define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb) +#define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb) +#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb) +#define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb) +#endif +#endif + #ifdef MS_WINDOWS #define sockaddr_rc SOCKADDR_BTH_REDEF @@ -527,266 +527,266 @@ remove_unusable_flags(PyObject *m) #define _BT_RC_MEMB(sa, memb) ((sa)->memb) #endif -/* Convert "sock_addr_t *" to "struct sockaddr *". */ -#define SAS2SA(x) (&((x)->sa)) - -/* - * Constants for getnameinfo() - */ -#if !defined(NI_MAXHOST) -#define NI_MAXHOST 1025 -#endif -#if !defined(NI_MAXSERV) -#define NI_MAXSERV 32 -#endif - -#ifndef INVALID_SOCKET /* MS defines this */ -#define INVALID_SOCKET (-1) -#endif - -#ifndef INADDR_NONE -#define INADDR_NONE (-1) -#endif - -/* XXX There's a problem here: *static* functions are not supposed to have - a Py prefix (or use CapitalizedWords). Later... */ - -/* Global variable holding the exception type for errors detected - by this module (but not argument type or memory errors, etc.). */ -static PyObject *socket_herror; -static PyObject *socket_gaierror; -static PyObject *socket_timeout; - -/* A forward reference to the socket type object. - The sock_type variable contains pointers to various functions, - some of which call new_sockobject(), which uses sock_type, so - there has to be a circular reference. */ -static PyTypeObject sock_type; - -#if defined(HAVE_POLL_H) -#include -#elif defined(HAVE_SYS_POLL_H) -#include -#endif - -/* Largest value to try to store in a socklen_t (used when handling - ancillary data). POSIX requires socklen_t to hold at least - (2**31)-1 and recommends against storing larger values, but - socklen_t was originally int in the BSD interface, so to be on the - safe side we use the smaller of (2**31)-1 and INT_MAX. */ -#if INT_MAX > 0x7fffffff -#define SOCKLEN_T_LIMIT 0x7fffffff -#else -#define SOCKLEN_T_LIMIT INT_MAX -#endif - -#ifdef HAVE_POLL -/* Instead of select(), we'll use poll() since poll() works on any fd. */ -#define IS_SELECTABLE(s) 1 -/* Can we call select() with this socket without a buffer overrun? */ -#else -/* If there's no timeout left, we don't have to call select, so it's a safe, - * little white lie. */ -#define IS_SELECTABLE(s) (_PyIsSelectable_fd((s)->sock_fd) || (s)->sock_timeout <= 0) -#endif - -static PyObject* -select_error(void) -{ - PyErr_SetString(PyExc_OSError, "unable to select on socket"); - return NULL; -} - -#ifdef MS_WINDOWS -#ifndef WSAEAGAIN -#define WSAEAGAIN WSAEWOULDBLOCK -#endif -#define CHECK_ERRNO(expected) \ - (WSAGetLastError() == WSA ## expected) -#else -#define CHECK_ERRNO(expected) \ - (errno == expected) -#endif - -#ifdef MS_WINDOWS -# define GET_SOCK_ERROR WSAGetLastError() -# define SET_SOCK_ERROR(err) WSASetLastError(err) -# define SOCK_TIMEOUT_ERR WSAEWOULDBLOCK -# define SOCK_INPROGRESS_ERR WSAEWOULDBLOCK -#else -# define GET_SOCK_ERROR errno -# define SET_SOCK_ERROR(err) do { errno = err; } while (0) -# define SOCK_TIMEOUT_ERR EWOULDBLOCK -# define SOCK_INPROGRESS_ERR EINPROGRESS -#endif - -#ifdef _MSC_VER -# define SUPPRESS_DEPRECATED_CALL __pragma(warning(suppress: 4996)) -#else -# define SUPPRESS_DEPRECATED_CALL -#endif - -#ifdef MS_WINDOWS -/* Does WSASocket() support the WSA_FLAG_NO_HANDLE_INHERIT flag? */ -static int support_wsa_no_inherit = -1; -#endif - -/* Convenience function to raise an error according to errno - and return a NULL pointer from a function. */ - -static PyObject * -set_error(void) -{ -#ifdef MS_WINDOWS - int err_no = WSAGetLastError(); - /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which - recognizes the error codes used by both GetLastError() and - WSAGetLastError */ - if (err_no) - return PyErr_SetExcFromWindowsErr(PyExc_OSError, err_no); -#endif - - return PyErr_SetFromErrno(PyExc_OSError); -} - - -static PyObject * -set_herror(int h_error) -{ - PyObject *v; - -#ifdef HAVE_HSTRERROR +/* Convert "sock_addr_t *" to "struct sockaddr *". */ +#define SAS2SA(x) (&((x)->sa)) + +/* + * Constants for getnameinfo() + */ +#if !defined(NI_MAXHOST) +#define NI_MAXHOST 1025 +#endif +#if !defined(NI_MAXSERV) +#define NI_MAXSERV 32 +#endif + +#ifndef INVALID_SOCKET /* MS defines this */ +#define INVALID_SOCKET (-1) +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE (-1) +#endif + +/* XXX There's a problem here: *static* functions are not supposed to have + a Py prefix (or use CapitalizedWords). Later... */ + +/* Global variable holding the exception type for errors detected + by this module (but not argument type or memory errors, etc.). */ +static PyObject *socket_herror; +static PyObject *socket_gaierror; +static PyObject *socket_timeout; + +/* A forward reference to the socket type object. + The sock_type variable contains pointers to various functions, + some of which call new_sockobject(), which uses sock_type, so + there has to be a circular reference. */ +static PyTypeObject sock_type; + +#if defined(HAVE_POLL_H) +#include +#elif defined(HAVE_SYS_POLL_H) +#include +#endif + +/* Largest value to try to store in a socklen_t (used when handling + ancillary data). POSIX requires socklen_t to hold at least + (2**31)-1 and recommends against storing larger values, but + socklen_t was originally int in the BSD interface, so to be on the + safe side we use the smaller of (2**31)-1 and INT_MAX. */ +#if INT_MAX > 0x7fffffff +#define SOCKLEN_T_LIMIT 0x7fffffff +#else +#define SOCKLEN_T_LIMIT INT_MAX +#endif + +#ifdef HAVE_POLL +/* Instead of select(), we'll use poll() since poll() works on any fd. */ +#define IS_SELECTABLE(s) 1 +/* Can we call select() with this socket without a buffer overrun? */ +#else +/* If there's no timeout left, we don't have to call select, so it's a safe, + * little white lie. */ +#define IS_SELECTABLE(s) (_PyIsSelectable_fd((s)->sock_fd) || (s)->sock_timeout <= 0) +#endif + +static PyObject* +select_error(void) +{ + PyErr_SetString(PyExc_OSError, "unable to select on socket"); + return NULL; +} + +#ifdef MS_WINDOWS +#ifndef WSAEAGAIN +#define WSAEAGAIN WSAEWOULDBLOCK +#endif +#define CHECK_ERRNO(expected) \ + (WSAGetLastError() == WSA ## expected) +#else +#define CHECK_ERRNO(expected) \ + (errno == expected) +#endif + +#ifdef MS_WINDOWS +# define GET_SOCK_ERROR WSAGetLastError() +# define SET_SOCK_ERROR(err) WSASetLastError(err) +# define SOCK_TIMEOUT_ERR WSAEWOULDBLOCK +# define SOCK_INPROGRESS_ERR WSAEWOULDBLOCK +#else +# define GET_SOCK_ERROR errno +# define SET_SOCK_ERROR(err) do { errno = err; } while (0) +# define SOCK_TIMEOUT_ERR EWOULDBLOCK +# define SOCK_INPROGRESS_ERR EINPROGRESS +#endif + +#ifdef _MSC_VER +# define SUPPRESS_DEPRECATED_CALL __pragma(warning(suppress: 4996)) +#else +# define SUPPRESS_DEPRECATED_CALL +#endif + +#ifdef MS_WINDOWS +/* Does WSASocket() support the WSA_FLAG_NO_HANDLE_INHERIT flag? */ +static int support_wsa_no_inherit = -1; +#endif + +/* Convenience function to raise an error according to errno + and return a NULL pointer from a function. */ + +static PyObject * +set_error(void) +{ +#ifdef MS_WINDOWS + int err_no = WSAGetLastError(); + /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which + recognizes the error codes used by both GetLastError() and + WSAGetLastError */ + if (err_no) + return PyErr_SetExcFromWindowsErr(PyExc_OSError, err_no); +#endif + + return PyErr_SetFromErrno(PyExc_OSError); +} + + +static PyObject * +set_herror(int h_error) +{ + PyObject *v; + +#ifdef HAVE_HSTRERROR v = Py_BuildValue("(is)", h_error, hstrerror(h_error)); -#else - v = Py_BuildValue("(is)", h_error, "host not found"); -#endif - if (v != NULL) { - PyErr_SetObject(socket_herror, v); - Py_DECREF(v); - } - - return NULL; -} - - -static PyObject * -set_gaierror(int error) -{ - PyObject *v; - -#ifdef EAI_SYSTEM - /* EAI_SYSTEM is not available on Windows XP. */ - if (error == EAI_SYSTEM) - return set_error(); -#endif - -#ifdef HAVE_GAI_STRERROR - v = Py_BuildValue("(is)", error, gai_strerror(error)); -#else - v = Py_BuildValue("(is)", error, "getaddrinfo failed"); -#endif - if (v != NULL) { - PyErr_SetObject(socket_gaierror, v); - Py_DECREF(v); - } - - return NULL; -} - -/* Function to perform the setting of socket blocking mode - internally. block = (1 | 0). */ -static int -internal_setblocking(PySocketSockObject *s, int block) -{ - int result = -1; -#ifdef MS_WINDOWS - u_long arg; -#endif -#if !defined(MS_WINDOWS) \ - && !((defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO))) - int delay_flag, new_delay_flag; -#endif - - Py_BEGIN_ALLOW_THREADS -#ifndef MS_WINDOWS -#if (defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)) - block = !block; - if (ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block) == -1) - goto done; -#else - delay_flag = fcntl(s->sock_fd, F_GETFL, 0); - if (delay_flag == -1) - goto done; - if (block) - new_delay_flag = delay_flag & (~O_NONBLOCK); - else - new_delay_flag = delay_flag | O_NONBLOCK; - if (new_delay_flag != delay_flag) - if (fcntl(s->sock_fd, F_SETFL, new_delay_flag) == -1) - goto done; -#endif -#else /* MS_WINDOWS */ - arg = !block; - if (ioctlsocket(s->sock_fd, FIONBIO, &arg) != 0) - goto done; -#endif /* MS_WINDOWS */ - - result = 0; - - done: - Py_END_ALLOW_THREADS - - if (result) { -#ifndef MS_WINDOWS - PyErr_SetFromErrno(PyExc_OSError); -#else - PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); -#endif - } - - return result; -} - -static int -internal_select(PySocketSockObject *s, int writing, _PyTime_t interval, - int connect) -{ - int n; -#ifdef HAVE_POLL - struct pollfd pollfd; - _PyTime_t ms; -#else - fd_set fds, efds; - struct timeval tv, *tvp; -#endif - - /* must be called with the GIL held */ - assert(PyGILState_Check()); - - /* Error condition is for output only */ - assert(!(connect && !writing)); - - /* Guard against closed socket */ - if (s->sock_fd == INVALID_SOCKET) - return 0; - - /* Prefer poll, if available, since you can poll() any fd - * which can't be done with select(). */ -#ifdef HAVE_POLL - pollfd.fd = s->sock_fd; - pollfd.events = writing ? POLLOUT : POLLIN; - if (connect) { - /* On Windows, the socket becomes writable on connection success, - but a connection failure is notified as an error. On POSIX, the - socket becomes writable on connection success or on connection - failure. */ - pollfd.events |= POLLERR; - } - - /* s->sock_timeout is in seconds, timeout in ms */ - ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING); - assert(ms <= INT_MAX); - +#else + v = Py_BuildValue("(is)", h_error, "host not found"); +#endif + if (v != NULL) { + PyErr_SetObject(socket_herror, v); + Py_DECREF(v); + } + + return NULL; +} + + +static PyObject * +set_gaierror(int error) +{ + PyObject *v; + +#ifdef EAI_SYSTEM + /* EAI_SYSTEM is not available on Windows XP. */ + if (error == EAI_SYSTEM) + return set_error(); +#endif + +#ifdef HAVE_GAI_STRERROR + v = Py_BuildValue("(is)", error, gai_strerror(error)); +#else + v = Py_BuildValue("(is)", error, "getaddrinfo failed"); +#endif + if (v != NULL) { + PyErr_SetObject(socket_gaierror, v); + Py_DECREF(v); + } + + return NULL; +} + +/* Function to perform the setting of socket blocking mode + internally. block = (1 | 0). */ +static int +internal_setblocking(PySocketSockObject *s, int block) +{ + int result = -1; +#ifdef MS_WINDOWS + u_long arg; +#endif +#if !defined(MS_WINDOWS) \ + && !((defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO))) + int delay_flag, new_delay_flag; +#endif + + Py_BEGIN_ALLOW_THREADS +#ifndef MS_WINDOWS +#if (defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)) + block = !block; + if (ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block) == -1) + goto done; +#else + delay_flag = fcntl(s->sock_fd, F_GETFL, 0); + if (delay_flag == -1) + goto done; + if (block) + new_delay_flag = delay_flag & (~O_NONBLOCK); + else + new_delay_flag = delay_flag | O_NONBLOCK; + if (new_delay_flag != delay_flag) + if (fcntl(s->sock_fd, F_SETFL, new_delay_flag) == -1) + goto done; +#endif +#else /* MS_WINDOWS */ + arg = !block; + if (ioctlsocket(s->sock_fd, FIONBIO, &arg) != 0) + goto done; +#endif /* MS_WINDOWS */ + + result = 0; + + done: + Py_END_ALLOW_THREADS + + if (result) { +#ifndef MS_WINDOWS + PyErr_SetFromErrno(PyExc_OSError); +#else + PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); +#endif + } + + return result; +} + +static int +internal_select(PySocketSockObject *s, int writing, _PyTime_t interval, + int connect) +{ + int n; +#ifdef HAVE_POLL + struct pollfd pollfd; + _PyTime_t ms; +#else + fd_set fds, efds; + struct timeval tv, *tvp; +#endif + + /* must be called with the GIL held */ + assert(PyGILState_Check()); + + /* Error condition is for output only */ + assert(!(connect && !writing)); + + /* Guard against closed socket */ + if (s->sock_fd == INVALID_SOCKET) + return 0; + + /* Prefer poll, if available, since you can poll() any fd + * which can't be done with select(). */ +#ifdef HAVE_POLL + pollfd.fd = s->sock_fd; + pollfd.events = writing ? POLLOUT : POLLIN; + if (connect) { + /* On Windows, the socket becomes writable on connection success, + but a connection failure is notified as an error. On POSIX, the + socket becomes writable on connection success or on connection + failure. */ + pollfd.events |= POLLERR; + } + + /* s->sock_timeout is in seconds, timeout in ms */ + ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING); + assert(ms <= INT_MAX); + /* On some OSes, typically BSD-based ones, the timeout parameter of the poll() syscall, when negative, must be exactly INFTIM, where defined, or -1. See issue 37811. */ @@ -798,767 +798,767 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval, #endif } - Py_BEGIN_ALLOW_THREADS; - n = poll(&pollfd, 1, (int)ms); - Py_END_ALLOW_THREADS; + Py_BEGIN_ALLOW_THREADS; + n = poll(&pollfd, 1, (int)ms); + Py_END_ALLOW_THREADS; +#else + if (interval >= 0) { + _PyTime_AsTimeval_noraise(interval, &tv, _PyTime_ROUND_CEILING); + tvp = &tv; + } + else + tvp = NULL; + + FD_ZERO(&fds); + FD_SET(s->sock_fd, &fds); + FD_ZERO(&efds); + if (connect) { + /* On Windows, the socket becomes writable on connection success, + but a connection failure is notified as an error. On POSIX, the + socket becomes writable on connection success or on connection + failure. */ + FD_SET(s->sock_fd, &efds); + } + + /* See if the socket is ready */ + Py_BEGIN_ALLOW_THREADS; + if (writing) + n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), + NULL, &fds, &efds, tvp); + else + n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), + &fds, NULL, &efds, tvp); + Py_END_ALLOW_THREADS; +#endif + + if (n < 0) + return -1; + if (n == 0) + return 1; + return 0; +} + +/* Call a socket function. + + On error, raise an exception and return -1 if err is set, or fill err and + return -1 otherwise. If a signal was received and the signal handler raised + an exception, return -1, and set err to -1 if err is set. + + On success, return 0, and set err to 0 if err is set. + + If the socket has a timeout, wait until the socket is ready before calling + the function: wait until the socket is writable if writing is nonzero, wait + until the socket received data otherwise. + + If the socket function is interrupted by a signal (failed with EINTR): retry + the function, except if the signal handler raised an exception (PEP 475). + + When the function is retried, recompute the timeout using a monotonic clock. + + sock_call_ex() must be called with the GIL held. The socket function is + called with the GIL released. */ +static int +sock_call_ex(PySocketSockObject *s, + int writing, + int (*sock_func) (PySocketSockObject *s, void *data), + void *data, + int connect, + int *err, + _PyTime_t timeout) +{ + int has_timeout = (timeout > 0); + _PyTime_t deadline = 0; + int deadline_initialized = 0; + int res; + + /* sock_call() must be called with the GIL held. */ + assert(PyGILState_Check()); + + /* outer loop to retry select() when select() is interrupted by a signal + or to retry select()+sock_func() on false positive (see above) */ + while (1) { + /* For connect(), poll even for blocking socket. The connection + runs asynchronously. */ + if (has_timeout || connect) { + if (has_timeout) { + _PyTime_t interval; + + if (deadline_initialized) { + /* recompute the timeout */ + interval = deadline - _PyTime_GetMonotonicClock(); + } + else { + deadline_initialized = 1; + deadline = _PyTime_GetMonotonicClock() + timeout; + interval = timeout; + } + + if (interval >= 0) + res = internal_select(s, writing, interval, connect); + else + res = 1; + } + else { + res = internal_select(s, writing, timeout, connect); + } + + if (res == -1) { + if (err) + *err = GET_SOCK_ERROR; + + if (CHECK_ERRNO(EINTR)) { + /* select() was interrupted by a signal */ + if (PyErr_CheckSignals()) { + if (err) + *err = -1; + return -1; + } + + /* retry select() */ + continue; + } + + /* select() failed */ + s->errorhandler(); + return -1; + } + + if (res == 1) { + if (err) + *err = SOCK_TIMEOUT_ERR; + else + PyErr_SetString(socket_timeout, "timed out"); + return -1; + } + + /* the socket is ready */ + } + + /* inner loop to retry sock_func() when sock_func() is interrupted + by a signal */ + while (1) { + Py_BEGIN_ALLOW_THREADS + res = sock_func(s, data); + Py_END_ALLOW_THREADS + + if (res) { + /* sock_func() succeeded */ + if (err) + *err = 0; + return 0; + } + + if (err) + *err = GET_SOCK_ERROR; + + if (!CHECK_ERRNO(EINTR)) + break; + + /* sock_func() was interrupted by a signal */ + if (PyErr_CheckSignals()) { + if (err) + *err = -1; + return -1; + } + + /* retry sock_func() */ + } + + if (s->sock_timeout > 0 + && (CHECK_ERRNO(EWOULDBLOCK) || CHECK_ERRNO(EAGAIN))) { + /* False positive: sock_func() failed with EWOULDBLOCK or EAGAIN. + + For example, select() could indicate a socket is ready for + reading, but the data then discarded by the OS because of a + wrong checksum. + + Loop on select() to recheck for socket readiness. */ + continue; + } + + /* sock_func() failed */ + if (!err) + s->errorhandler(); + /* else: err was already set before */ + return -1; + } +} + +static int +sock_call(PySocketSockObject *s, + int writing, + int (*func) (PySocketSockObject *s, void *data), + void *data) +{ + return sock_call_ex(s, writing, func, data, 0, NULL, s->sock_timeout); +} + + +/* Initialize a new socket object. */ + +/* Default timeout for new sockets */ +static _PyTime_t defaulttimeout = _PYTIME_FROMSECONDS(-1); + +static int +init_sockobject(PySocketSockObject *s, + SOCKET_T fd, int family, int type, int proto) +{ + s->sock_fd = fd; + s->sock_family = family; + + s->sock_type = type; + + /* It's possible to pass SOCK_NONBLOCK and SOCK_CLOEXEC bit flags + on some OSes as part of socket.type. We want to reset them here, + to make socket.type be set to the same value on all platforms. + Otherwise, simple code like 'if sock.type == SOCK_STREAM' is + not portable. + */ +#ifdef SOCK_NONBLOCK + s->sock_type = s->sock_type & ~SOCK_NONBLOCK; +#endif +#ifdef SOCK_CLOEXEC + s->sock_type = s->sock_type & ~SOCK_CLOEXEC; +#endif + + s->sock_proto = proto; + + s->errorhandler = &set_error; +#ifdef SOCK_NONBLOCK + if (type & SOCK_NONBLOCK) + s->sock_timeout = 0; + else +#endif + { + s->sock_timeout = defaulttimeout; + if (defaulttimeout >= 0) { + if (internal_setblocking(s, 0) == -1) { + return -1; + } + } + } + return 0; +} + + +/* Create a new socket object. + This just creates the object and initializes it. + If the creation fails, return NULL and set an exception (implicit + in NEWOBJ()). */ + +static PySocketSockObject * +new_sockobject(SOCKET_T fd, int family, int type, int proto) +{ + PySocketSockObject *s; + s = (PySocketSockObject *) + PyType_GenericNew(&sock_type, NULL, NULL); + if (s == NULL) + return NULL; + if (init_sockobject(s, fd, family, type, proto) == -1) { + Py_DECREF(s); + return NULL; + } + return s; +} + + +/* Lock to allow python interpreter to continue, but only allow one + thread to be in gethostbyname or getaddrinfo */ +#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) +static PyThread_type_lock netdb_lock; +#endif + + +/* Convert a string specifying a host name or one of a few symbolic + names to a numeric IP address. This usually calls gethostbyname() + to do the work; the names "" and "" are special. + Return the length (IPv4 should be 4 bytes), or negative if + an error occurred; then an exception is raised. */ + +static int +setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af) +{ + struct addrinfo hints, *res; + int error; + + memset((void *) addr_ret, '\0', sizeof(*addr_ret)); + if (name[0] == '\0') { + int siz; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_PASSIVE; + Py_BEGIN_ALLOW_THREADS + ACQUIRE_GETADDRINFO_LOCK + error = getaddrinfo(NULL, "0", &hints, &res); + Py_END_ALLOW_THREADS + /* We assume that those thread-unsafe getaddrinfo() versions + *are* safe regarding their return value, ie. that a + subsequent call to getaddrinfo() does not destroy the + outcome of the first call. */ + RELEASE_GETADDRINFO_LOCK + if (error) { + set_gaierror(error); + return -1; + } + switch (res->ai_family) { + case AF_INET: + siz = 4; + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + siz = 16; + break; +#endif + default: + freeaddrinfo(res); + PyErr_SetString(PyExc_OSError, + "unsupported address family"); + return -1; + } + if (res->ai_next) { + freeaddrinfo(res); + PyErr_SetString(PyExc_OSError, + "wildcard resolved to multiple address"); + return -1; + } + if (res->ai_addrlen < addr_ret_size) + addr_ret_size = res->ai_addrlen; + memcpy(addr_ret, res->ai_addr, addr_ret_size); + freeaddrinfo(res); + return siz; + } + /* special-case broadcast - inet_addr() below can return INADDR_NONE for + * this */ + if (strcmp(name, "255.255.255.255") == 0 || + strcmp(name, "") == 0) { + struct sockaddr_in *sin; + if (af != AF_INET && af != AF_UNSPEC) { + PyErr_SetString(PyExc_OSError, + "address family mismatched"); + return -1; + } + sin = (struct sockaddr_in *)addr_ret; + memset((void *) sin, '\0', sizeof(*sin)); + sin->sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(*sin); +#endif + sin->sin_addr.s_addr = INADDR_BROADCAST; + return sizeof(sin->sin_addr); + } + + /* avoid a name resolution in case of numeric address */ +#ifdef HAVE_INET_PTON + /* check for an IPv4 address */ + if (af == AF_UNSPEC || af == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in *)addr_ret; + memset(sin, 0, sizeof(*sin)); + if (inet_pton(AF_INET, name, &sin->sin_addr) > 0) { + sin->sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(*sin); +#endif + return 4; + } + } +#ifdef ENABLE_IPV6 + /* check for an IPv6 address - if the address contains a scope ID, we + * fallback to getaddrinfo(), which can handle translation from interface + * name to interface index */ + if ((af == AF_UNSPEC || af == AF_INET6) && !strchr(name, '%')) { + struct sockaddr_in6 *sin = (struct sockaddr_in6 *)addr_ret; + memset(sin, 0, sizeof(*sin)); + if (inet_pton(AF_INET6, name, &sin->sin6_addr) > 0) { + sin->sin6_family = AF_INET6; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin6_len = sizeof(*sin); +#endif + return 16; + } + } +#endif /* ENABLE_IPV6 */ +#else /* HAVE_INET_PTON */ + /* check for an IPv4 address */ + if (af == AF_INET || af == AF_UNSPEC) { + struct sockaddr_in *sin = (struct sockaddr_in *)addr_ret; + memset(sin, 0, sizeof(*sin)); + if ((sin->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) { + sin->sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(*sin); +#endif + return 4; + } + } +#endif /* HAVE_INET_PTON */ + + /* perform a name resolution */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + Py_BEGIN_ALLOW_THREADS + ACQUIRE_GETADDRINFO_LOCK + error = getaddrinfo(name, NULL, &hints, &res); +#if defined(__digital__) && defined(__unix__) + if (error == EAI_NONAME && af == AF_UNSPEC) { + /* On Tru64 V5.1, numeric-to-addr conversion fails + if no address family is given. Assume IPv4 for now.*/ + hints.ai_family = AF_INET; + error = getaddrinfo(name, NULL, &hints, &res); + } +#endif + Py_END_ALLOW_THREADS + RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ + if (error) { + set_gaierror(error); + return -1; + } + if (res->ai_addrlen < addr_ret_size) + addr_ret_size = res->ai_addrlen; + memcpy((char *) addr_ret, res->ai_addr, addr_ret_size); + freeaddrinfo(res); + switch (addr_ret->sa_family) { + case AF_INET: + return 4; +#ifdef ENABLE_IPV6 + case AF_INET6: + return 16; +#endif + default: + PyErr_SetString(PyExc_OSError, "unknown address family"); + return -1; + } +} + + +/* Convert IPv4 sockaddr to a Python str. */ + +static PyObject * +make_ipv4_addr(const struct sockaddr_in *addr) +{ + char buf[INET_ADDRSTRLEN]; + if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyUnicode_FromString(buf); +} + +#ifdef ENABLE_IPV6 +/* Convert IPv6 sockaddr to a Python str. */ + +static PyObject * +make_ipv6_addr(const struct sockaddr_in6 *addr) +{ + char buf[INET6_ADDRSTRLEN]; + if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyUnicode_FromString(buf); +} +#endif + +#ifdef USE_BLUETOOTH +/* Convert a string representation of a Bluetooth address into a numeric + address. Returns the length (6), or raises an exception and returns -1 if + an error occurred. */ + +static int +setbdaddr(const char *name, bdaddr_t *bdaddr) +{ + unsigned int b0, b1, b2, b3, b4, b5; + char ch; + int n; + + n = sscanf(name, "%X:%X:%X:%X:%X:%X%c", + &b5, &b4, &b3, &b2, &b1, &b0, &ch); + if (n == 6 && (b0 | b1 | b2 | b3 | b4 | b5) < 256) { + +#ifdef MS_WINDOWS + *bdaddr = (ULONGLONG)(b0 & 0xFF); + *bdaddr |= ((ULONGLONG)(b1 & 0xFF) << 8); + *bdaddr |= ((ULONGLONG)(b2 & 0xFF) << 16); + *bdaddr |= ((ULONGLONG)(b3 & 0xFF) << 24); + *bdaddr |= ((ULONGLONG)(b4 & 0xFF) << 32); + *bdaddr |= ((ULONGLONG)(b5 & 0xFF) << 40); #else - if (interval >= 0) { - _PyTime_AsTimeval_noraise(interval, &tv, _PyTime_ROUND_CEILING); - tvp = &tv; - } - else - tvp = NULL; + bdaddr->b[0] = b0; + bdaddr->b[1] = b1; + bdaddr->b[2] = b2; + bdaddr->b[3] = b3; + bdaddr->b[4] = b4; + bdaddr->b[5] = b5; +#endif + + return 6; + } else { + PyErr_SetString(PyExc_OSError, "bad bluetooth address"); + return -1; + } +} + +/* Create a string representation of the Bluetooth address. This is always a + string of the form 'XX:XX:XX:XX:XX:XX' where XX is a two digit hexadecimal + value (zero padded if necessary). */ + +static PyObject * +makebdaddr(bdaddr_t *bdaddr) +{ + char buf[(6 * 2) + 5 + 1]; + +#ifdef MS_WINDOWS + int i; + unsigned int octets[6]; - FD_ZERO(&fds); - FD_SET(s->sock_fd, &fds); - FD_ZERO(&efds); - if (connect) { - /* On Windows, the socket becomes writable on connection success, - but a connection failure is notified as an error. On POSIX, the - socket becomes writable on connection success or on connection - failure. */ - FD_SET(s->sock_fd, &efds); + for (i = 0; i < 6; ++i) { + octets[i] = ((*bdaddr) >> (8 * i)) & 0xFF; } - /* See if the socket is ready */ - Py_BEGIN_ALLOW_THREADS; - if (writing) - n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), - NULL, &fds, &efds, tvp); - else - n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), - &fds, NULL, &efds, tvp); - Py_END_ALLOW_THREADS; -#endif - - if (n < 0) - return -1; - if (n == 0) - return 1; - return 0; -} - -/* Call a socket function. - - On error, raise an exception and return -1 if err is set, or fill err and - return -1 otherwise. If a signal was received and the signal handler raised - an exception, return -1, and set err to -1 if err is set. - - On success, return 0, and set err to 0 if err is set. - - If the socket has a timeout, wait until the socket is ready before calling - the function: wait until the socket is writable if writing is nonzero, wait - until the socket received data otherwise. - - If the socket function is interrupted by a signal (failed with EINTR): retry - the function, except if the signal handler raised an exception (PEP 475). - - When the function is retried, recompute the timeout using a monotonic clock. - - sock_call_ex() must be called with the GIL held. The socket function is - called with the GIL released. */ -static int -sock_call_ex(PySocketSockObject *s, - int writing, - int (*sock_func) (PySocketSockObject *s, void *data), - void *data, - int connect, - int *err, - _PyTime_t timeout) -{ - int has_timeout = (timeout > 0); - _PyTime_t deadline = 0; - int deadline_initialized = 0; - int res; - - /* sock_call() must be called with the GIL held. */ - assert(PyGILState_Check()); - - /* outer loop to retry select() when select() is interrupted by a signal - or to retry select()+sock_func() on false positive (see above) */ - while (1) { - /* For connect(), poll even for blocking socket. The connection - runs asynchronously. */ - if (has_timeout || connect) { - if (has_timeout) { - _PyTime_t interval; - - if (deadline_initialized) { - /* recompute the timeout */ - interval = deadline - _PyTime_GetMonotonicClock(); - } - else { - deadline_initialized = 1; - deadline = _PyTime_GetMonotonicClock() + timeout; - interval = timeout; - } - - if (interval >= 0) - res = internal_select(s, writing, interval, connect); - else - res = 1; - } - else { - res = internal_select(s, writing, timeout, connect); - } - - if (res == -1) { - if (err) - *err = GET_SOCK_ERROR; - - if (CHECK_ERRNO(EINTR)) { - /* select() was interrupted by a signal */ - if (PyErr_CheckSignals()) { - if (err) - *err = -1; - return -1; - } - - /* retry select() */ - continue; - } - - /* select() failed */ - s->errorhandler(); - return -1; - } - - if (res == 1) { - if (err) - *err = SOCK_TIMEOUT_ERR; - else - PyErr_SetString(socket_timeout, "timed out"); - return -1; - } - - /* the socket is ready */ - } - - /* inner loop to retry sock_func() when sock_func() is interrupted - by a signal */ - while (1) { - Py_BEGIN_ALLOW_THREADS - res = sock_func(s, data); - Py_END_ALLOW_THREADS - - if (res) { - /* sock_func() succeeded */ - if (err) - *err = 0; - return 0; - } - - if (err) - *err = GET_SOCK_ERROR; + sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", + octets[5], octets[4], octets[3], + octets[2], octets[1], octets[0]); +#else + sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", + bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], + bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); +#endif + + return PyUnicode_FromString(buf); +} +#endif + + +/* Create an object representing the given socket address, + suitable for passing it back to bind(), connect() etc. + The family field of the sockaddr structure is inspected + to determine what kind of address it really is. */ + +/*ARGSUSED*/ +static PyObject * +makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) +{ + if (addrlen == 0) { + /* No address -- may be recvfrom() from known socket */ + Py_RETURN_NONE; + } + + switch (addr->sa_family) { + + case AF_INET: + { + const struct sockaddr_in *a = (const struct sockaddr_in *)addr; + PyObject *addrobj = make_ipv4_addr(a); + PyObject *ret = NULL; + if (addrobj) { + ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port)); + Py_DECREF(addrobj); + } + return ret; + } + +#if defined(AF_UNIX) + case AF_UNIX: + { + struct sockaddr_un *a = (struct sockaddr_un *) addr; +#ifdef __linux__ + size_t linuxaddrlen = addrlen - offsetof(struct sockaddr_un, sun_path); + if (linuxaddrlen > 0 && a->sun_path[0] == 0) { /* Linux abstract namespace */ + return PyBytes_FromStringAndSize(a->sun_path, linuxaddrlen); + } + else +#endif /* linux */ + { + /* regular NULL-terminated string */ + return PyUnicode_DecodeFSDefault(a->sun_path); + } + } +#endif /* AF_UNIX */ + +#if defined(AF_NETLINK) + case AF_NETLINK: + { + struct sockaddr_nl *a = (struct sockaddr_nl *) addr; + return Py_BuildValue("II", a->nl_pid, a->nl_groups); + } +#endif /* AF_NETLINK */ + +#if defined(AF_QIPCRTR) + case AF_QIPCRTR: + { + struct sockaddr_qrtr *a = (struct sockaddr_qrtr *) addr; + return Py_BuildValue("II", a->sq_node, a->sq_port); + } +#endif /* AF_QIPCRTR */ - if (!CHECK_ERRNO(EINTR)) - break; - - /* sock_func() was interrupted by a signal */ - if (PyErr_CheckSignals()) { - if (err) - *err = -1; - return -1; - } - - /* retry sock_func() */ - } - - if (s->sock_timeout > 0 - && (CHECK_ERRNO(EWOULDBLOCK) || CHECK_ERRNO(EAGAIN))) { - /* False positive: sock_func() failed with EWOULDBLOCK or EAGAIN. - - For example, select() could indicate a socket is ready for - reading, but the data then discarded by the OS because of a - wrong checksum. - - Loop on select() to recheck for socket readiness. */ - continue; - } - - /* sock_func() failed */ - if (!err) - s->errorhandler(); - /* else: err was already set before */ - return -1; - } -} - -static int -sock_call(PySocketSockObject *s, - int writing, - int (*func) (PySocketSockObject *s, void *data), - void *data) -{ - return sock_call_ex(s, writing, func, data, 0, NULL, s->sock_timeout); -} - - -/* Initialize a new socket object. */ - -/* Default timeout for new sockets */ -static _PyTime_t defaulttimeout = _PYTIME_FROMSECONDS(-1); - -static int -init_sockobject(PySocketSockObject *s, - SOCKET_T fd, int family, int type, int proto) -{ - s->sock_fd = fd; - s->sock_family = family; - - s->sock_type = type; - - /* It's possible to pass SOCK_NONBLOCK and SOCK_CLOEXEC bit flags - on some OSes as part of socket.type. We want to reset them here, - to make socket.type be set to the same value on all platforms. - Otherwise, simple code like 'if sock.type == SOCK_STREAM' is - not portable. - */ -#ifdef SOCK_NONBLOCK - s->sock_type = s->sock_type & ~SOCK_NONBLOCK; -#endif -#ifdef SOCK_CLOEXEC - s->sock_type = s->sock_type & ~SOCK_CLOEXEC; -#endif - - s->sock_proto = proto; - - s->errorhandler = &set_error; -#ifdef SOCK_NONBLOCK - if (type & SOCK_NONBLOCK) - s->sock_timeout = 0; - else -#endif - { - s->sock_timeout = defaulttimeout; - if (defaulttimeout >= 0) { - if (internal_setblocking(s, 0) == -1) { - return -1; - } - } - } - return 0; -} - - -/* Create a new socket object. - This just creates the object and initializes it. - If the creation fails, return NULL and set an exception (implicit - in NEWOBJ()). */ - -static PySocketSockObject * -new_sockobject(SOCKET_T fd, int family, int type, int proto) -{ - PySocketSockObject *s; - s = (PySocketSockObject *) - PyType_GenericNew(&sock_type, NULL, NULL); - if (s == NULL) - return NULL; - if (init_sockobject(s, fd, family, type, proto) == -1) { - Py_DECREF(s); - return NULL; - } - return s; -} - - -/* Lock to allow python interpreter to continue, but only allow one - thread to be in gethostbyname or getaddrinfo */ -#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) -static PyThread_type_lock netdb_lock; -#endif - - -/* Convert a string specifying a host name or one of a few symbolic - names to a numeric IP address. This usually calls gethostbyname() - to do the work; the names "" and "" are special. - Return the length (IPv4 should be 4 bytes), or negative if - an error occurred; then an exception is raised. */ - -static int -setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af) -{ - struct addrinfo hints, *res; - int error; - - memset((void *) addr_ret, '\0', sizeof(*addr_ret)); - if (name[0] == '\0') { - int siz; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = af; - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_flags = AI_PASSIVE; - Py_BEGIN_ALLOW_THREADS - ACQUIRE_GETADDRINFO_LOCK - error = getaddrinfo(NULL, "0", &hints, &res); - Py_END_ALLOW_THREADS - /* We assume that those thread-unsafe getaddrinfo() versions - *are* safe regarding their return value, ie. that a - subsequent call to getaddrinfo() does not destroy the - outcome of the first call. */ - RELEASE_GETADDRINFO_LOCK - if (error) { - set_gaierror(error); - return -1; - } - switch (res->ai_family) { - case AF_INET: - siz = 4; - break; -#ifdef ENABLE_IPV6 - case AF_INET6: - siz = 16; - break; -#endif - default: - freeaddrinfo(res); - PyErr_SetString(PyExc_OSError, - "unsupported address family"); - return -1; - } - if (res->ai_next) { - freeaddrinfo(res); - PyErr_SetString(PyExc_OSError, - "wildcard resolved to multiple address"); - return -1; - } - if (res->ai_addrlen < addr_ret_size) - addr_ret_size = res->ai_addrlen; - memcpy(addr_ret, res->ai_addr, addr_ret_size); - freeaddrinfo(res); - return siz; - } - /* special-case broadcast - inet_addr() below can return INADDR_NONE for - * this */ - if (strcmp(name, "255.255.255.255") == 0 || - strcmp(name, "") == 0) { - struct sockaddr_in *sin; - if (af != AF_INET && af != AF_UNSPEC) { - PyErr_SetString(PyExc_OSError, - "address family mismatched"); - return -1; - } - sin = (struct sockaddr_in *)addr_ret; - memset((void *) sin, '\0', sizeof(*sin)); - sin->sin_family = AF_INET; -#ifdef HAVE_SOCKADDR_SA_LEN - sin->sin_len = sizeof(*sin); -#endif - sin->sin_addr.s_addr = INADDR_BROADCAST; - return sizeof(sin->sin_addr); - } - - /* avoid a name resolution in case of numeric address */ -#ifdef HAVE_INET_PTON - /* check for an IPv4 address */ - if (af == AF_UNSPEC || af == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *)addr_ret; - memset(sin, 0, sizeof(*sin)); - if (inet_pton(AF_INET, name, &sin->sin_addr) > 0) { - sin->sin_family = AF_INET; -#ifdef HAVE_SOCKADDR_SA_LEN - sin->sin_len = sizeof(*sin); -#endif - return 4; - } - } -#ifdef ENABLE_IPV6 - /* check for an IPv6 address - if the address contains a scope ID, we - * fallback to getaddrinfo(), which can handle translation from interface - * name to interface index */ - if ((af == AF_UNSPEC || af == AF_INET6) && !strchr(name, '%')) { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)addr_ret; - memset(sin, 0, sizeof(*sin)); - if (inet_pton(AF_INET6, name, &sin->sin6_addr) > 0) { - sin->sin6_family = AF_INET6; -#ifdef HAVE_SOCKADDR_SA_LEN - sin->sin6_len = sizeof(*sin); -#endif - return 16; - } - } -#endif /* ENABLE_IPV6 */ -#else /* HAVE_INET_PTON */ - /* check for an IPv4 address */ - if (af == AF_INET || af == AF_UNSPEC) { - struct sockaddr_in *sin = (struct sockaddr_in *)addr_ret; - memset(sin, 0, sizeof(*sin)); - if ((sin->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) { - sin->sin_family = AF_INET; -#ifdef HAVE_SOCKADDR_SA_LEN - sin->sin_len = sizeof(*sin); -#endif - return 4; - } - } -#endif /* HAVE_INET_PTON */ - - /* perform a name resolution */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = af; - Py_BEGIN_ALLOW_THREADS - ACQUIRE_GETADDRINFO_LOCK - error = getaddrinfo(name, NULL, &hints, &res); -#if defined(__digital__) && defined(__unix__) - if (error == EAI_NONAME && af == AF_UNSPEC) { - /* On Tru64 V5.1, numeric-to-addr conversion fails - if no address family is given. Assume IPv4 for now.*/ - hints.ai_family = AF_INET; - error = getaddrinfo(name, NULL, &hints, &res); - } -#endif - Py_END_ALLOW_THREADS - RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ - if (error) { - set_gaierror(error); - return -1; - } - if (res->ai_addrlen < addr_ret_size) - addr_ret_size = res->ai_addrlen; - memcpy((char *) addr_ret, res->ai_addr, addr_ret_size); - freeaddrinfo(res); - switch (addr_ret->sa_family) { - case AF_INET: - return 4; -#ifdef ENABLE_IPV6 - case AF_INET6: - return 16; -#endif - default: - PyErr_SetString(PyExc_OSError, "unknown address family"); - return -1; - } -} - - -/* Convert IPv4 sockaddr to a Python str. */ - -static PyObject * -make_ipv4_addr(const struct sockaddr_in *addr) -{ - char buf[INET_ADDRSTRLEN]; - if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return PyUnicode_FromString(buf); -} - -#ifdef ENABLE_IPV6 -/* Convert IPv6 sockaddr to a Python str. */ - -static PyObject * -make_ipv6_addr(const struct sockaddr_in6 *addr) -{ - char buf[INET6_ADDRSTRLEN]; - if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return PyUnicode_FromString(buf); -} -#endif - -#ifdef USE_BLUETOOTH -/* Convert a string representation of a Bluetooth address into a numeric - address. Returns the length (6), or raises an exception and returns -1 if - an error occurred. */ - -static int -setbdaddr(const char *name, bdaddr_t *bdaddr) -{ - unsigned int b0, b1, b2, b3, b4, b5; - char ch; - int n; - - n = sscanf(name, "%X:%X:%X:%X:%X:%X%c", - &b5, &b4, &b3, &b2, &b1, &b0, &ch); - if (n == 6 && (b0 | b1 | b2 | b3 | b4 | b5) < 256) { - -#ifdef MS_WINDOWS - *bdaddr = (ULONGLONG)(b0 & 0xFF); - *bdaddr |= ((ULONGLONG)(b1 & 0xFF) << 8); - *bdaddr |= ((ULONGLONG)(b2 & 0xFF) << 16); - *bdaddr |= ((ULONGLONG)(b3 & 0xFF) << 24); - *bdaddr |= ((ULONGLONG)(b4 & 0xFF) << 32); - *bdaddr |= ((ULONGLONG)(b5 & 0xFF) << 40); -#else - bdaddr->b[0] = b0; - bdaddr->b[1] = b1; - bdaddr->b[2] = b2; - bdaddr->b[3] = b3; - bdaddr->b[4] = b4; - bdaddr->b[5] = b5; -#endif - - return 6; - } else { - PyErr_SetString(PyExc_OSError, "bad bluetooth address"); - return -1; - } -} - -/* Create a string representation of the Bluetooth address. This is always a - string of the form 'XX:XX:XX:XX:XX:XX' where XX is a two digit hexadecimal - value (zero padded if necessary). */ - -static PyObject * -makebdaddr(bdaddr_t *bdaddr) -{ - char buf[(6 * 2) + 5 + 1]; - -#ifdef MS_WINDOWS - int i; - unsigned int octets[6]; - - for (i = 0; i < 6; ++i) { - octets[i] = ((*bdaddr) >> (8 * i)) & 0xFF; - } - - sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", - octets[5], octets[4], octets[3], - octets[2], octets[1], octets[0]); -#else - sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); -#endif - - return PyUnicode_FromString(buf); -} -#endif - - -/* Create an object representing the given socket address, - suitable for passing it back to bind(), connect() etc. - The family field of the sockaddr structure is inspected - to determine what kind of address it really is. */ - -/*ARGSUSED*/ -static PyObject * -makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) -{ - if (addrlen == 0) { - /* No address -- may be recvfrom() from known socket */ - Py_RETURN_NONE; - } - - switch (addr->sa_family) { - - case AF_INET: - { - const struct sockaddr_in *a = (const struct sockaddr_in *)addr; - PyObject *addrobj = make_ipv4_addr(a); - PyObject *ret = NULL; - if (addrobj) { - ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port)); - Py_DECREF(addrobj); - } - return ret; - } - -#if defined(AF_UNIX) - case AF_UNIX: - { - struct sockaddr_un *a = (struct sockaddr_un *) addr; -#ifdef __linux__ - size_t linuxaddrlen = addrlen - offsetof(struct sockaddr_un, sun_path); - if (linuxaddrlen > 0 && a->sun_path[0] == 0) { /* Linux abstract namespace */ - return PyBytes_FromStringAndSize(a->sun_path, linuxaddrlen); - } - else -#endif /* linux */ - { - /* regular NULL-terminated string */ - return PyUnicode_DecodeFSDefault(a->sun_path); - } - } -#endif /* AF_UNIX */ - -#if defined(AF_NETLINK) - case AF_NETLINK: - { - struct sockaddr_nl *a = (struct sockaddr_nl *) addr; - return Py_BuildValue("II", a->nl_pid, a->nl_groups); - } -#endif /* AF_NETLINK */ - -#if defined(AF_QIPCRTR) - case AF_QIPCRTR: - { - struct sockaddr_qrtr *a = (struct sockaddr_qrtr *) addr; - return Py_BuildValue("II", a->sq_node, a->sq_port); - } -#endif /* AF_QIPCRTR */ - -#if defined(AF_VSOCK) - case AF_VSOCK: - { - struct sockaddr_vm *a = (struct sockaddr_vm *) addr; - return Py_BuildValue("II", a->svm_cid, a->svm_port); - } -#endif /* AF_VSOCK */ - -#ifdef ENABLE_IPV6 - case AF_INET6: - { - const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)addr; - PyObject *addrobj = make_ipv6_addr(a); - PyObject *ret = NULL; - if (addrobj) { - ret = Py_BuildValue("OiII", - addrobj, - ntohs(a->sin6_port), - ntohl(a->sin6_flowinfo), - a->sin6_scope_id); - Py_DECREF(addrobj); - } - return ret; - } -#endif /* ENABLE_IPV6 */ - -#ifdef USE_BLUETOOTH - case AF_BLUETOOTH: - switch (proto) { - -#ifdef BTPROTO_L2CAP - case BTPROTO_L2CAP: - { - struct sockaddr_l2 *a = (struct sockaddr_l2 *) addr; - PyObject *addrobj = makebdaddr(&_BT_L2_MEMB(a, bdaddr)); - PyObject *ret = NULL; - if (addrobj) { - ret = Py_BuildValue("Oi", - addrobj, - _BT_L2_MEMB(a, psm)); - Py_DECREF(addrobj); - } - return ret; - } - -#endif /* BTPROTO_L2CAP */ - - case BTPROTO_RFCOMM: - { - struct sockaddr_rc *a = (struct sockaddr_rc *) addr; - PyObject *addrobj = makebdaddr(&_BT_RC_MEMB(a, bdaddr)); - PyObject *ret = NULL; - if (addrobj) { - ret = Py_BuildValue("Oi", - addrobj, - _BT_RC_MEMB(a, channel)); - Py_DECREF(addrobj); - } - return ret; - } +#if defined(AF_VSOCK) + case AF_VSOCK: + { + struct sockaddr_vm *a = (struct sockaddr_vm *) addr; + return Py_BuildValue("II", a->svm_cid, a->svm_port); + } +#endif /* AF_VSOCK */ + +#ifdef ENABLE_IPV6 + case AF_INET6: + { + const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)addr; + PyObject *addrobj = make_ipv6_addr(a); + PyObject *ret = NULL; + if (addrobj) { + ret = Py_BuildValue("OiII", + addrobj, + ntohs(a->sin6_port), + ntohl(a->sin6_flowinfo), + a->sin6_scope_id); + Py_DECREF(addrobj); + } + return ret; + } +#endif /* ENABLE_IPV6 */ + +#ifdef USE_BLUETOOTH + case AF_BLUETOOTH: + switch (proto) { + +#ifdef BTPROTO_L2CAP + case BTPROTO_L2CAP: + { + struct sockaddr_l2 *a = (struct sockaddr_l2 *) addr; + PyObject *addrobj = makebdaddr(&_BT_L2_MEMB(a, bdaddr)); + PyObject *ret = NULL; + if (addrobj) { + ret = Py_BuildValue("Oi", + addrobj, + _BT_L2_MEMB(a, psm)); + Py_DECREF(addrobj); + } + return ret; + } + +#endif /* BTPROTO_L2CAP */ + case BTPROTO_RFCOMM: + { + struct sockaddr_rc *a = (struct sockaddr_rc *) addr; + PyObject *addrobj = makebdaddr(&_BT_RC_MEMB(a, bdaddr)); + PyObject *ret = NULL; + if (addrobj) { + ret = Py_BuildValue("Oi", + addrobj, + _BT_RC_MEMB(a, channel)); + Py_DECREF(addrobj); + } + return ret; + } + #ifdef BTPROTO_HCI - case BTPROTO_HCI: - { - struct sockaddr_hci *a = (struct sockaddr_hci *) addr; -#if defined(__NetBSD__) || defined(__DragonFly__) - return makebdaddr(&_BT_HCI_MEMB(a, bdaddr)); -#else /* __NetBSD__ || __DragonFly__ */ - PyObject *ret = NULL; - ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev)); - return ret; -#endif /* !(__NetBSD__ || __DragonFly__) */ - } - -#if !defined(__FreeBSD__) - case BTPROTO_SCO: - { - struct sockaddr_sco *a = (struct sockaddr_sco *) addr; - return makebdaddr(&_BT_SCO_MEMB(a, bdaddr)); - } -#endif /* !__FreeBSD__ */ + case BTPROTO_HCI: + { + struct sockaddr_hci *a = (struct sockaddr_hci *) addr; +#if defined(__NetBSD__) || defined(__DragonFly__) + return makebdaddr(&_BT_HCI_MEMB(a, bdaddr)); +#else /* __NetBSD__ || __DragonFly__ */ + PyObject *ret = NULL; + ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev)); + return ret; +#endif /* !(__NetBSD__ || __DragonFly__) */ + } + +#if !defined(__FreeBSD__) + case BTPROTO_SCO: + { + struct sockaddr_sco *a = (struct sockaddr_sco *) addr; + return makebdaddr(&_BT_SCO_MEMB(a, bdaddr)); + } +#endif /* !__FreeBSD__ */ #endif /* BTPROTO_HCI */ - - default: - PyErr_SetString(PyExc_ValueError, - "Unknown Bluetooth protocol"); - return NULL; - } -#endif /* USE_BLUETOOTH */ - -#if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFNAME) - case AF_PACKET: - { - struct sockaddr_ll *a = (struct sockaddr_ll *)addr; - const char *ifname = ""; - struct ifreq ifr; - /* need to look up interface name give index */ - if (a->sll_ifindex) { - ifr.ifr_ifindex = a->sll_ifindex; - if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0) - ifname = ifr.ifr_name; - } - return Py_BuildValue("shbhy#", - ifname, - ntohs(a->sll_protocol), - a->sll_pkttype, - a->sll_hatype, - a->sll_addr, + + default: + PyErr_SetString(PyExc_ValueError, + "Unknown Bluetooth protocol"); + return NULL; + } +#endif /* USE_BLUETOOTH */ + +#if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFNAME) + case AF_PACKET: + { + struct sockaddr_ll *a = (struct sockaddr_ll *)addr; + const char *ifname = ""; + struct ifreq ifr; + /* need to look up interface name give index */ + if (a->sll_ifindex) { + ifr.ifr_ifindex = a->sll_ifindex; + if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0) + ifname = ifr.ifr_name; + } + return Py_BuildValue("shbhy#", + ifname, + ntohs(a->sll_protocol), + a->sll_pkttype, + a->sll_hatype, + a->sll_addr, (Py_ssize_t)a->sll_halen); - } -#endif /* HAVE_NETPACKET_PACKET_H && SIOCGIFNAME */ - -#ifdef HAVE_LINUX_TIPC_H - case AF_TIPC: - { - struct sockaddr_tipc *a = (struct sockaddr_tipc *) addr; - if (a->addrtype == TIPC_ADDR_NAMESEQ) { - return Py_BuildValue("IIIII", - a->addrtype, - a->addr.nameseq.type, - a->addr.nameseq.lower, - a->addr.nameseq.upper, - a->scope); - } else if (a->addrtype == TIPC_ADDR_NAME) { - return Py_BuildValue("IIIII", - a->addrtype, - a->addr.name.name.type, - a->addr.name.name.instance, - a->addr.name.name.instance, - a->scope); - } else if (a->addrtype == TIPC_ADDR_ID) { - return Py_BuildValue("IIIII", - a->addrtype, - a->addr.id.node, - a->addr.id.ref, - 0, - a->scope); - } else { - PyErr_SetString(PyExc_ValueError, - "Invalid address type"); - return NULL; - } - } -#endif /* HAVE_LINUX_TIPC_H */ - -#if defined(AF_CAN) && defined(SIOCGIFNAME) - case AF_CAN: - { - struct sockaddr_can *a = (struct sockaddr_can *)addr; - const char *ifname = ""; - struct ifreq ifr; - /* need to look up interface name given index */ - if (a->can_ifindex) { - ifr.ifr_ifindex = a->can_ifindex; - if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0) - ifname = ifr.ifr_name; - } - - switch (proto) { -#ifdef CAN_ISOTP - case CAN_ISOTP: - { - return Py_BuildValue("O&kk", PyUnicode_DecodeFSDefault, - ifname, - a->can_addr.tp.rx_id, - a->can_addr.tp.tx_id); - } -#endif /* CAN_ISOTP */ + } +#endif /* HAVE_NETPACKET_PACKET_H && SIOCGIFNAME */ + +#ifdef HAVE_LINUX_TIPC_H + case AF_TIPC: + { + struct sockaddr_tipc *a = (struct sockaddr_tipc *) addr; + if (a->addrtype == TIPC_ADDR_NAMESEQ) { + return Py_BuildValue("IIIII", + a->addrtype, + a->addr.nameseq.type, + a->addr.nameseq.lower, + a->addr.nameseq.upper, + a->scope); + } else if (a->addrtype == TIPC_ADDR_NAME) { + return Py_BuildValue("IIIII", + a->addrtype, + a->addr.name.name.type, + a->addr.name.name.instance, + a->addr.name.name.instance, + a->scope); + } else if (a->addrtype == TIPC_ADDR_ID) { + return Py_BuildValue("IIIII", + a->addrtype, + a->addr.id.node, + a->addr.id.ref, + 0, + a->scope); + } else { + PyErr_SetString(PyExc_ValueError, + "Invalid address type"); + return NULL; + } + } +#endif /* HAVE_LINUX_TIPC_H */ + +#if defined(AF_CAN) && defined(SIOCGIFNAME) + case AF_CAN: + { + struct sockaddr_can *a = (struct sockaddr_can *)addr; + const char *ifname = ""; + struct ifreq ifr; + /* need to look up interface name given index */ + if (a->can_ifindex) { + ifr.ifr_ifindex = a->can_ifindex; + if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0) + ifname = ifr.ifr_name; + } + + switch (proto) { +#ifdef CAN_ISOTP + case CAN_ISOTP: + { + return Py_BuildValue("O&kk", PyUnicode_DecodeFSDefault, + ifname, + a->can_addr.tp.rx_id, + a->can_addr.tp.tx_id); + } +#endif /* CAN_ISOTP */ #ifdef CAN_J1939 case CAN_J1939: { @@ -1569,216 +1569,216 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) a->can_addr.j1939.addr); } #endif /* CAN_J1939 */ - default: - { + default: + { return Py_BuildValue("(O&)", PyUnicode_DecodeFSDefault, - ifname); - } - } - } -#endif /* AF_CAN && SIOCGIFNAME */ - -#ifdef PF_SYSTEM - case PF_SYSTEM: - switch(proto) { -#ifdef SYSPROTO_CONTROL - case SYSPROTO_CONTROL: - { - struct sockaddr_ctl *a = (struct sockaddr_ctl *)addr; - return Py_BuildValue("(II)", a->sc_id, a->sc_unit); - } -#endif /* SYSPROTO_CONTROL */ - default: - PyErr_SetString(PyExc_ValueError, - "Invalid address type"); - return 0; - } -#endif /* PF_SYSTEM */ - -#ifdef HAVE_SOCKADDR_ALG - case AF_ALG: - { - struct sockaddr_alg *a = (struct sockaddr_alg *)addr; - return Py_BuildValue("s#s#HH", - a->salg_type, - strnlen((const char*)a->salg_type, - sizeof(a->salg_type)), - a->salg_name, - strnlen((const char*)a->salg_name, - sizeof(a->salg_name)), - a->salg_feat, - a->salg_mask); - } -#endif /* HAVE_SOCKADDR_ALG */ - - /* More cases here... */ - - default: - /* If we don't know the address family, don't raise an - exception -- return it as an (int, bytes) tuple. */ - return Py_BuildValue("iy#", - addr->sa_family, - addr->sa_data, - sizeof(addr->sa_data)); - - } -} - -/* Helper for getsockaddrarg: bypass IDNA for ASCII-only host names - (in particular, numeric IP addresses). */ -struct maybe_idna { - PyObject *obj; - char *buf; -}; - -static void -idna_cleanup(struct maybe_idna *data) -{ - Py_CLEAR(data->obj); -} - -static int -idna_converter(PyObject *obj, struct maybe_idna *data) -{ - size_t len; - PyObject *obj2; - if (obj == NULL) { - idna_cleanup(data); - return 1; - } - data->obj = NULL; - len = -1; - if (PyBytes_Check(obj)) { - data->buf = PyBytes_AsString(obj); - len = PyBytes_Size(obj); - } - else if (PyByteArray_Check(obj)) { - data->buf = PyByteArray_AsString(obj); - len = PyByteArray_Size(obj); - } - else if (PyUnicode_Check(obj)) { - if (PyUnicode_READY(obj) == -1) { - return 0; - } - if (PyUnicode_IS_COMPACT_ASCII(obj)) { - data->buf = PyUnicode_DATA(obj); - len = PyUnicode_GET_LENGTH(obj); - } - else { - obj2 = PyUnicode_AsEncodedString(obj, "idna", NULL); - if (!obj2) { - PyErr_SetString(PyExc_TypeError, "encoding of hostname failed"); - return 0; - } - assert(PyBytes_Check(obj2)); - data->obj = obj2; - data->buf = PyBytes_AS_STRING(obj2); - len = PyBytes_GET_SIZE(obj2); - } - } - else { - PyErr_Format(PyExc_TypeError, "str, bytes or bytearray expected, not %s", + ifname); + } + } + } +#endif /* AF_CAN && SIOCGIFNAME */ + +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch(proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + { + struct sockaddr_ctl *a = (struct sockaddr_ctl *)addr; + return Py_BuildValue("(II)", a->sc_id, a->sc_unit); + } +#endif /* SYSPROTO_CONTROL */ + default: + PyErr_SetString(PyExc_ValueError, + "Invalid address type"); + return 0; + } +#endif /* PF_SYSTEM */ + +#ifdef HAVE_SOCKADDR_ALG + case AF_ALG: + { + struct sockaddr_alg *a = (struct sockaddr_alg *)addr; + return Py_BuildValue("s#s#HH", + a->salg_type, + strnlen((const char*)a->salg_type, + sizeof(a->salg_type)), + a->salg_name, + strnlen((const char*)a->salg_name, + sizeof(a->salg_name)), + a->salg_feat, + a->salg_mask); + } +#endif /* HAVE_SOCKADDR_ALG */ + + /* More cases here... */ + + default: + /* If we don't know the address family, don't raise an + exception -- return it as an (int, bytes) tuple. */ + return Py_BuildValue("iy#", + addr->sa_family, + addr->sa_data, + sizeof(addr->sa_data)); + + } +} + +/* Helper for getsockaddrarg: bypass IDNA for ASCII-only host names + (in particular, numeric IP addresses). */ +struct maybe_idna { + PyObject *obj; + char *buf; +}; + +static void +idna_cleanup(struct maybe_idna *data) +{ + Py_CLEAR(data->obj); +} + +static int +idna_converter(PyObject *obj, struct maybe_idna *data) +{ + size_t len; + PyObject *obj2; + if (obj == NULL) { + idna_cleanup(data); + return 1; + } + data->obj = NULL; + len = -1; + if (PyBytes_Check(obj)) { + data->buf = PyBytes_AsString(obj); + len = PyBytes_Size(obj); + } + else if (PyByteArray_Check(obj)) { + data->buf = PyByteArray_AsString(obj); + len = PyByteArray_Size(obj); + } + else if (PyUnicode_Check(obj)) { + if (PyUnicode_READY(obj) == -1) { + return 0; + } + if (PyUnicode_IS_COMPACT_ASCII(obj)) { + data->buf = PyUnicode_DATA(obj); + len = PyUnicode_GET_LENGTH(obj); + } + else { + obj2 = PyUnicode_AsEncodedString(obj, "idna", NULL); + if (!obj2) { + PyErr_SetString(PyExc_TypeError, "encoding of hostname failed"); + return 0; + } + assert(PyBytes_Check(obj2)); + data->obj = obj2; + data->buf = PyBytes_AS_STRING(obj2); + len = PyBytes_GET_SIZE(obj2); + } + } + else { + PyErr_Format(PyExc_TypeError, "str, bytes or bytearray expected, not %s", Py_TYPE(obj)->tp_name); - return 0; - } - if (strlen(data->buf) != len) { - Py_CLEAR(data->obj); - PyErr_SetString(PyExc_TypeError, "host name must not contain null character"); - return 0; - } - return Py_CLEANUP_SUPPORTED; -} - -/* Parse a socket address argument according to the socket object's - address family. Return 1 if the address was in the proper format, - 0 of not. The address is returned through addr_ret, its length - through len_ret. */ - -static int -getsockaddrarg(PySocketSockObject *s, PyObject *args, + return 0; + } + if (strlen(data->buf) != len) { + Py_CLEAR(data->obj); + PyErr_SetString(PyExc_TypeError, "host name must not contain null character"); + return 0; + } + return Py_CLEANUP_SUPPORTED; +} + +/* Parse a socket address argument according to the socket object's + address family. Return 1 if the address was in the proper format, + 0 of not. The address is returned through addr_ret, its length + through len_ret. */ + +static int +getsockaddrarg(PySocketSockObject *s, PyObject *args, sock_addr_t *addrbuf, int *len_ret, const char *caller) -{ - switch (s->sock_family) { - -#if defined(AF_UNIX) - case AF_UNIX: - { - Py_buffer path; - int retval = 0; - - /* PEP 383. Not using PyUnicode_FSConverter since we need to - allow embedded nulls on Linux. */ - if (PyUnicode_Check(args)) { - if ((args = PyUnicode_EncodeFSDefault(args)) == NULL) - return 0; - } - else - Py_INCREF(args); - if (!PyArg_Parse(args, "y*", &path)) { - Py_DECREF(args); - return retval; - } - assert(path.len >= 0); - +{ + switch (s->sock_family) { + +#if defined(AF_UNIX) + case AF_UNIX: + { + Py_buffer path; + int retval = 0; + + /* PEP 383. Not using PyUnicode_FSConverter since we need to + allow embedded nulls on Linux. */ + if (PyUnicode_Check(args)) { + if ((args = PyUnicode_EncodeFSDefault(args)) == NULL) + return 0; + } + else + Py_INCREF(args); + if (!PyArg_Parse(args, "y*", &path)) { + Py_DECREF(args); + return retval; + } + assert(path.len >= 0); + struct sockaddr_un* addr = &addrbuf->un; -#ifdef __linux__ - if (path.len > 0 && *(const char *)path.buf == 0) { - /* Linux abstract namespace extension */ - if ((size_t)path.len > sizeof addr->sun_path) { - PyErr_SetString(PyExc_OSError, - "AF_UNIX path too long"); - goto unix_out; - } - } - else -#endif /* linux */ - { - /* regular NULL-terminated string */ - if ((size_t)path.len >= sizeof addr->sun_path) { - PyErr_SetString(PyExc_OSError, - "AF_UNIX path too long"); - goto unix_out; - } - addr->sun_path[path.len] = 0; - } - addr->sun_family = s->sock_family; - memcpy(addr->sun_path, path.buf, path.len); - *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); - retval = 1; - unix_out: - PyBuffer_Release(&path); - Py_DECREF(args); - return retval; - } -#endif /* AF_UNIX */ - -#if defined(AF_NETLINK) - case AF_NETLINK: - { - int pid, groups; +#ifdef __linux__ + if (path.len > 0 && *(const char *)path.buf == 0) { + /* Linux abstract namespace extension */ + if ((size_t)path.len > sizeof addr->sun_path) { + PyErr_SetString(PyExc_OSError, + "AF_UNIX path too long"); + goto unix_out; + } + } + else +#endif /* linux */ + { + /* regular NULL-terminated string */ + if ((size_t)path.len >= sizeof addr->sun_path) { + PyErr_SetString(PyExc_OSError, + "AF_UNIX path too long"); + goto unix_out; + } + addr->sun_path[path.len] = 0; + } + addr->sun_family = s->sock_family; + memcpy(addr->sun_path, path.buf, path.len); + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); + retval = 1; + unix_out: + PyBuffer_Release(&path); + Py_DECREF(args); + return retval; + } +#endif /* AF_UNIX */ + +#if defined(AF_NETLINK) + case AF_NETLINK: + { + int pid, groups; struct sockaddr_nl* addr = &addrbuf->nl; - if (!PyTuple_Check(args)) { - PyErr_Format( - PyExc_TypeError, + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, "%s(): AF_NETLINK address must be tuple, not %.500s", caller, Py_TYPE(args)->tp_name); - return 0; - } + return 0; + } if (!PyArg_ParseTuple(args, "II;AF_NETLINK address must be a pair " "(pid, groups)", &pid, &groups)) { - return 0; - } - addr->nl_family = AF_NETLINK; - addr->nl_pid = pid; - addr->nl_groups = groups; - *len_ret = sizeof(*addr); - return 1; - } -#endif /* AF_NETLINK */ - + return 0; + } + addr->nl_family = AF_NETLINK; + addr->nl_pid = pid; + addr->nl_groups = groups; + *len_ret = sizeof(*addr); + return 1; + } +#endif /* AF_NETLINK */ + #if defined(AF_QIPCRTR) case AF_QIPCRTR: { @@ -1802,95 +1802,95 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } #endif /* AF_QIPCRTR */ -#if defined(AF_VSOCK) - case AF_VSOCK: - { +#if defined(AF_VSOCK) + case AF_VSOCK: + { struct sockaddr_vm* addr = &addrbuf->vm; - int port, cid; - memset(addr, 0, sizeof(struct sockaddr_vm)); - if (!PyTuple_Check(args)) { - PyErr_Format( - PyExc_TypeError, - "getsockaddrarg: " - "AF_VSOCK address must be tuple, not %.500s", - Py_TYPE(args)->tp_name); - return 0; - } - if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &cid, &port)) - return 0; - addr->svm_family = s->sock_family; - addr->svm_port = port; - addr->svm_cid = cid; - *len_ret = sizeof(*addr); - return 1; - } -#endif /* AF_VSOCK */ - - -#ifdef AF_RDS - case AF_RDS: - /* RDS sockets use sockaddr_in: fall-through */ -#endif /* AF_RDS */ - - case AF_INET: - { - struct maybe_idna host = {NULL, NULL}; - int port, result; - if (!PyTuple_Check(args)) { - PyErr_Format( - PyExc_TypeError, + int port, cid; + memset(addr, 0, sizeof(struct sockaddr_vm)); + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, + "getsockaddrarg: " + "AF_VSOCK address must be tuple, not %.500s", + Py_TYPE(args)->tp_name); + return 0; + } + if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &cid, &port)) + return 0; + addr->svm_family = s->sock_family; + addr->svm_port = port; + addr->svm_cid = cid; + *len_ret = sizeof(*addr); + return 1; + } +#endif /* AF_VSOCK */ + + +#ifdef AF_RDS + case AF_RDS: + /* RDS sockets use sockaddr_in: fall-through */ +#endif /* AF_RDS */ + + case AF_INET: + { + struct maybe_idna host = {NULL, NULL}; + int port, result; + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, "%s(): AF_INET address must be tuple, not %.500s", caller, Py_TYPE(args)->tp_name); - return 0; - } + return 0; + } if (!PyArg_ParseTuple(args, "O&i;AF_INET address must be a pair " "(host, port)", - idna_converter, &host, &port)) + idna_converter, &host, &port)) { assert(PyErr_Occurred()); if (PyErr_ExceptionMatches(PyExc_OverflowError)) { PyErr_Format(PyExc_OverflowError, "%s(): port must be 0-65535.", caller); } - return 0; + return 0; } struct sockaddr_in* addr = &addrbuf->in; - result = setipaddr(host.buf, (struct sockaddr *)addr, - sizeof(*addr), AF_INET); - idna_cleanup(&host); - if (result < 0) - return 0; - if (port < 0 || port > 0xffff) { + result = setipaddr(host.buf, (struct sockaddr *)addr, + sizeof(*addr), AF_INET); + idna_cleanup(&host); + if (result < 0) + return 0; + if (port < 0 || port > 0xffff) { PyErr_Format( - PyExc_OverflowError, + PyExc_OverflowError, "%s(): port must be 0-65535.", caller); - return 0; - } - addr->sin_family = AF_INET; - addr->sin_port = htons((short)port); - *len_ret = sizeof *addr; - return 1; - } - -#ifdef ENABLE_IPV6 - case AF_INET6: - { - struct maybe_idna host = {NULL, NULL}; - int port, result; - unsigned int flowinfo, scope_id; - flowinfo = scope_id = 0; - if (!PyTuple_Check(args)) { - PyErr_Format( - PyExc_TypeError, + return 0; + } + addr->sin_family = AF_INET; + addr->sin_port = htons((short)port); + *len_ret = sizeof *addr; + return 1; + } + +#ifdef ENABLE_IPV6 + case AF_INET6: + { + struct maybe_idna host = {NULL, NULL}; + int port, result; + unsigned int flowinfo, scope_id; + flowinfo = scope_id = 0; + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, "%s(): AF_INET6 address must be tuple, not %.500s", caller, Py_TYPE(args)->tp_name); - return 0; - } + return 0; + } if (!PyArg_ParseTuple(args, "O&i|II;AF_INET6 address must be a tuple " "(host, port[, flowinfo[, scopeid]])", - idna_converter, &host, &port, &flowinfo, + idna_converter, &host, &port, &flowinfo, &scope_id)) { assert(PyErr_Occurred()); @@ -1898,149 +1898,149 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyErr_Format(PyExc_OverflowError, "%s(): port must be 0-65535.", caller); } - return 0; - } + return 0; + } struct sockaddr_in6* addr = &addrbuf->in6; - result = setipaddr(host.buf, (struct sockaddr *)addr, - sizeof(*addr), AF_INET6); - idna_cleanup(&host); - if (result < 0) - return 0; - if (port < 0 || port > 0xffff) { + result = setipaddr(host.buf, (struct sockaddr *)addr, + sizeof(*addr), AF_INET6); + idna_cleanup(&host); + if (result < 0) + return 0; + if (port < 0 || port > 0xffff) { PyErr_Format( - PyExc_OverflowError, + PyExc_OverflowError, "%s(): port must be 0-65535.", caller); - return 0; - } - if (flowinfo > 0xfffff) { + return 0; + } + if (flowinfo > 0xfffff) { PyErr_Format( - PyExc_OverflowError, + PyExc_OverflowError, "%s(): flowinfo must be 0-1048575.", caller); - return 0; - } - addr->sin6_family = s->sock_family; - addr->sin6_port = htons((short)port); - addr->sin6_flowinfo = htonl(flowinfo); - addr->sin6_scope_id = scope_id; - *len_ret = sizeof *addr; - return 1; - } -#endif /* ENABLE_IPV6 */ - -#ifdef USE_BLUETOOTH - case AF_BLUETOOTH: - { - switch (s->sock_proto) { + return 0; + } + addr->sin6_family = s->sock_family; + addr->sin6_port = htons((short)port); + addr->sin6_flowinfo = htonl(flowinfo); + addr->sin6_scope_id = scope_id; + *len_ret = sizeof *addr; + return 1; + } +#endif /* ENABLE_IPV6 */ + +#ifdef USE_BLUETOOTH + case AF_BLUETOOTH: + { + switch (s->sock_proto) { #ifdef BTPROTO_L2CAP - case BTPROTO_L2CAP: - { - const char *straddr; - + case BTPROTO_L2CAP: + { + const char *straddr; + struct sockaddr_l2 *addr = &addrbuf->bt_l2; - memset(addr, 0, sizeof(struct sockaddr_l2)); - _BT_L2_MEMB(addr, family) = AF_BLUETOOTH; - if (!PyArg_ParseTuple(args, "si", &straddr, - &_BT_L2_MEMB(addr, psm))) { + memset(addr, 0, sizeof(struct sockaddr_l2)); + _BT_L2_MEMB(addr, family) = AF_BLUETOOTH; + if (!PyArg_ParseTuple(args, "si", &straddr, + &_BT_L2_MEMB(addr, psm))) { PyErr_Format(PyExc_OSError, "%s(): wrong format", caller); - return 0; - } - if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0) - return 0; - - *len_ret = sizeof *addr; - return 1; - } + return 0; + } + if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0) + return 0; + + *len_ret = sizeof *addr; + return 1; + } #endif /* BTPROTO_L2CAP */ - case BTPROTO_RFCOMM: - { - const char *straddr; + case BTPROTO_RFCOMM: + { + const char *straddr; struct sockaddr_rc *addr = &addrbuf->bt_rc; - _BT_RC_MEMB(addr, family) = AF_BLUETOOTH; - if (!PyArg_ParseTuple(args, "si", &straddr, - &_BT_RC_MEMB(addr, channel))) { + _BT_RC_MEMB(addr, family) = AF_BLUETOOTH; + if (!PyArg_ParseTuple(args, "si", &straddr, + &_BT_RC_MEMB(addr, channel))) { PyErr_Format(PyExc_OSError, "%s(): wrong format", caller); - return 0; - } - if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0) - return 0; - - *len_ret = sizeof *addr; - return 1; - } + return 0; + } + if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0) + return 0; + + *len_ret = sizeof *addr; + return 1; + } #ifdef BTPROTO_HCI - case BTPROTO_HCI: - { + case BTPROTO_HCI: + { struct sockaddr_hci *addr = &addrbuf->bt_hci; -#if defined(__NetBSD__) || defined(__DragonFly__) - const char *straddr; - _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH; - if (!PyBytes_Check(args)) { +#if defined(__NetBSD__) || defined(__DragonFly__) + const char *straddr; + _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH; + if (!PyBytes_Check(args)) { PyErr_Format(PyExc_OSError, "%s: " "wrong format", caller); - return 0; - } - straddr = PyBytes_AS_STRING(args); - if (setbdaddr(straddr, &_BT_HCI_MEMB(addr, bdaddr)) < 0) - return 0; -#else /* __NetBSD__ || __DragonFly__ */ - _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH; - if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) { + return 0; + } + straddr = PyBytes_AS_STRING(args); + if (setbdaddr(straddr, &_BT_HCI_MEMB(addr, bdaddr)) < 0) + return 0; +#else /* __NetBSD__ || __DragonFly__ */ + _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH; + if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) { PyErr_Format(PyExc_OSError, "%s(): wrong format", caller); - return 0; - } -#endif /* !(__NetBSD__ || __DragonFly__) */ - *len_ret = sizeof *addr; - return 1; - } -#if !defined(__FreeBSD__) - case BTPROTO_SCO: - { - const char *straddr; - + return 0; + } +#endif /* !(__NetBSD__ || __DragonFly__) */ + *len_ret = sizeof *addr; + return 1; + } +#if !defined(__FreeBSD__) + case BTPROTO_SCO: + { + const char *straddr; + struct sockaddr_sco *addr = &addrbuf->bt_sco; - _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH; - if (!PyBytes_Check(args)) { + _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH; + if (!PyBytes_Check(args)) { PyErr_Format(PyExc_OSError, "%s(): wrong format", caller); - return 0; - } - straddr = PyBytes_AS_STRING(args); - if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0) - return 0; - - *len_ret = sizeof *addr; - return 1; - } -#endif /* !__FreeBSD__ */ + return 0; + } + straddr = PyBytes_AS_STRING(args); + if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0) + return 0; + + *len_ret = sizeof *addr; + return 1; + } +#endif /* !__FreeBSD__ */ #endif /* BTPROTO_HCI */ - default: + default: PyErr_Format(PyExc_OSError, "%s(): unknown Bluetooth protocol", caller); - return 0; - } - } -#endif /* USE_BLUETOOTH */ - -#if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFINDEX) - case AF_PACKET: - { - struct ifreq ifr; - const char *interfaceName; - int protoNumber; - int hatype = 0; - int pkttype = PACKET_HOST; - Py_buffer haddr = {NULL, NULL}; - - if (!PyTuple_Check(args)) { - PyErr_Format( - PyExc_TypeError, + return 0; + } + } +#endif /* USE_BLUETOOTH */ + +#if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFINDEX) + case AF_PACKET: + { + struct ifreq ifr; + const char *interfaceName; + int protoNumber; + int hatype = 0; + int pkttype = PACKET_HOST; + Py_buffer haddr = {NULL, NULL}; + + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, "%s(): AF_PACKET address must be tuple, not %.500s", caller, Py_TYPE(args)->tp_name); - return 0; - } + return 0; + } /* XXX: improve the default error message according to the documentation of AF_PACKET, which would be added as part of bpo-25041. */ @@ -2048,126 +2048,126 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, "si|iiy*;AF_PACKET address must be a tuple of " "two to five elements", &interfaceName, &protoNumber, &pkttype, &hatype, - &haddr)) + &haddr)) { assert(PyErr_Occurred()); if (PyErr_ExceptionMatches(PyExc_OverflowError)) { PyErr_Format(PyExc_OverflowError, "%s(): address argument out of range", caller); } - return 0; - } - strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)); - ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; - if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { - s->errorhandler(); - PyBuffer_Release(&haddr); - return 0; - } - if (haddr.buf && haddr.len > 8) { - PyErr_SetString(PyExc_ValueError, - "Hardware address must be 8 bytes or less"); - PyBuffer_Release(&haddr); - return 0; - } - if (protoNumber < 0 || protoNumber > 0xffff) { + return 0; + } + strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)); + ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; + if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { + s->errorhandler(); + PyBuffer_Release(&haddr); + return 0; + } + if (haddr.buf && haddr.len > 8) { + PyErr_SetString(PyExc_ValueError, + "Hardware address must be 8 bytes or less"); + PyBuffer_Release(&haddr); + return 0; + } + if (protoNumber < 0 || protoNumber > 0xffff) { PyErr_Format( - PyExc_OverflowError, + PyExc_OverflowError, "%s(): proto must be 0-65535.", caller); - PyBuffer_Release(&haddr); - return 0; - } + PyBuffer_Release(&haddr); + return 0; + } struct sockaddr_ll* addr = &addrbuf->ll; - addr->sll_family = AF_PACKET; - addr->sll_protocol = htons((short)protoNumber); - addr->sll_ifindex = ifr.ifr_ifindex; - addr->sll_pkttype = pkttype; - addr->sll_hatype = hatype; - if (haddr.buf) { - memcpy(&addr->sll_addr, haddr.buf, haddr.len); - addr->sll_halen = haddr.len; - } - else - addr->sll_halen = 0; - *len_ret = sizeof *addr; - PyBuffer_Release(&haddr); - return 1; - } -#endif /* HAVE_NETPACKET_PACKET_H && SIOCGIFINDEX */ - -#ifdef HAVE_LINUX_TIPC_H - case AF_TIPC: - { - unsigned int atype, v1, v2, v3; - unsigned int scope = TIPC_CLUSTER_SCOPE; - - if (!PyTuple_Check(args)) { - PyErr_Format( - PyExc_TypeError, + addr->sll_family = AF_PACKET; + addr->sll_protocol = htons((short)protoNumber); + addr->sll_ifindex = ifr.ifr_ifindex; + addr->sll_pkttype = pkttype; + addr->sll_hatype = hatype; + if (haddr.buf) { + memcpy(&addr->sll_addr, haddr.buf, haddr.len); + addr->sll_halen = haddr.len; + } + else + addr->sll_halen = 0; + *len_ret = sizeof *addr; + PyBuffer_Release(&haddr); + return 1; + } +#endif /* HAVE_NETPACKET_PACKET_H && SIOCGIFINDEX */ + +#ifdef HAVE_LINUX_TIPC_H + case AF_TIPC: + { + unsigned int atype, v1, v2, v3; + unsigned int scope = TIPC_CLUSTER_SCOPE; + + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, "%s(): AF_TIPC address must be tuple, not %.500s", caller, Py_TYPE(args)->tp_name); - return 0; - } - - if (!PyArg_ParseTuple(args, + return 0; + } + + if (!PyArg_ParseTuple(args, "IIII|I;AF_TIPC address must be a tuple " "(addr_type, v1, v2, v3[, scope])", &atype, &v1, &v2, &v3, &scope)) { - return 0; + return 0; } - + struct sockaddr_tipc *addr = &addrbuf->tipc; - memset(addr, 0, sizeof(struct sockaddr_tipc)); - - addr->family = AF_TIPC; - addr->scope = scope; - addr->addrtype = atype; - - if (atype == TIPC_ADDR_NAMESEQ) { - addr->addr.nameseq.type = v1; - addr->addr.nameseq.lower = v2; - addr->addr.nameseq.upper = v3; - } else if (atype == TIPC_ADDR_NAME) { - addr->addr.name.name.type = v1; - addr->addr.name.name.instance = v2; - } else if (atype == TIPC_ADDR_ID) { - addr->addr.id.node = v1; - addr->addr.id.ref = v2; - } else { - /* Shouldn't happen */ - PyErr_SetString(PyExc_TypeError, "Invalid address type"); - return 0; - } - - *len_ret = sizeof(*addr); - - return 1; - } -#endif /* HAVE_LINUX_TIPC_H */ - -#if defined(AF_CAN) && defined(SIOCGIFINDEX) - case AF_CAN: - switch (s->sock_proto) { -#ifdef CAN_RAW - case CAN_RAW: - /* fall-through */ -#endif -#ifdef CAN_BCM - case CAN_BCM: -#endif -#if defined(CAN_RAW) || defined(CAN_BCM) - { - PyObject *interfaceName; - struct ifreq ifr; - Py_ssize_t len; + memset(addr, 0, sizeof(struct sockaddr_tipc)); + + addr->family = AF_TIPC; + addr->scope = scope; + addr->addrtype = atype; + + if (atype == TIPC_ADDR_NAMESEQ) { + addr->addr.nameseq.type = v1; + addr->addr.nameseq.lower = v2; + addr->addr.nameseq.upper = v3; + } else if (atype == TIPC_ADDR_NAME) { + addr->addr.name.name.type = v1; + addr->addr.name.name.instance = v2; + } else if (atype == TIPC_ADDR_ID) { + addr->addr.id.node = v1; + addr->addr.id.ref = v2; + } else { + /* Shouldn't happen */ + PyErr_SetString(PyExc_TypeError, "Invalid address type"); + return 0; + } + + *len_ret = sizeof(*addr); + + return 1; + } +#endif /* HAVE_LINUX_TIPC_H */ + +#if defined(AF_CAN) && defined(SIOCGIFINDEX) + case AF_CAN: + switch (s->sock_proto) { +#ifdef CAN_RAW + case CAN_RAW: + /* fall-through */ +#endif +#ifdef CAN_BCM + case CAN_BCM: +#endif +#if defined(CAN_RAW) || defined(CAN_BCM) + { + PyObject *interfaceName; + struct ifreq ifr; + Py_ssize_t len; struct sockaddr_can *addr = &addrbuf->can; - + if (!PyTuple_Check(args)) { PyErr_Format(PyExc_TypeError, "%s(): AF_CAN address must be tuple, not %.500s", caller, Py_TYPE(args)->tp_name); - return 0; + return 0; } if (!PyArg_ParseTuple(args, "O&;AF_CAN address must be a tuple " @@ -2176,80 +2176,80 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, { return 0; } - - len = PyBytes_GET_SIZE(interfaceName); - - if (len == 0) { - ifr.ifr_ifindex = 0; - } else if ((size_t)len < sizeof(ifr.ifr_name)) { - strncpy(ifr.ifr_name, PyBytes_AS_STRING(interfaceName), sizeof(ifr.ifr_name)); - ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; - if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { - s->errorhandler(); - Py_DECREF(interfaceName); - return 0; - } - } else { - PyErr_SetString(PyExc_OSError, - "AF_CAN interface name too long"); - Py_DECREF(interfaceName); - return 0; - } - - addr->can_family = AF_CAN; - addr->can_ifindex = ifr.ifr_ifindex; - - *len_ret = sizeof(*addr); - Py_DECREF(interfaceName); - return 1; - } -#endif /* CAN_RAW || CAN_BCM */ - -#ifdef CAN_ISOTP - case CAN_ISOTP: - { - PyObject *interfaceName; - struct ifreq ifr; - Py_ssize_t len; - unsigned long int rx_id, tx_id; - + + len = PyBytes_GET_SIZE(interfaceName); + + if (len == 0) { + ifr.ifr_ifindex = 0; + } else if ((size_t)len < sizeof(ifr.ifr_name)) { + strncpy(ifr.ifr_name, PyBytes_AS_STRING(interfaceName), sizeof(ifr.ifr_name)); + ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; + if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { + s->errorhandler(); + Py_DECREF(interfaceName); + return 0; + } + } else { + PyErr_SetString(PyExc_OSError, + "AF_CAN interface name too long"); + Py_DECREF(interfaceName); + return 0; + } + + addr->can_family = AF_CAN; + addr->can_ifindex = ifr.ifr_ifindex; + + *len_ret = sizeof(*addr); + Py_DECREF(interfaceName); + return 1; + } +#endif /* CAN_RAW || CAN_BCM */ + +#ifdef CAN_ISOTP + case CAN_ISOTP: + { + PyObject *interfaceName; + struct ifreq ifr; + Py_ssize_t len; + unsigned long int rx_id, tx_id; + struct sockaddr_can *addr = &addrbuf->can; - - if (!PyArg_ParseTuple(args, "O&kk", PyUnicode_FSConverter, - &interfaceName, - &rx_id, - &tx_id)) - return 0; - - len = PyBytes_GET_SIZE(interfaceName); - - if (len == 0) { - ifr.ifr_ifindex = 0; - } else if ((size_t)len < sizeof(ifr.ifr_name)) { - strncpy(ifr.ifr_name, PyBytes_AS_STRING(interfaceName), sizeof(ifr.ifr_name)); - ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; - if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { - s->errorhandler(); - Py_DECREF(interfaceName); - return 0; - } - } else { - PyErr_SetString(PyExc_OSError, - "AF_CAN interface name too long"); - Py_DECREF(interfaceName); - return 0; - } - - addr->can_family = AF_CAN; - addr->can_ifindex = ifr.ifr_ifindex; - addr->can_addr.tp.rx_id = rx_id; - addr->can_addr.tp.tx_id = tx_id; - - *len_ret = sizeof(*addr); - Py_DECREF(interfaceName); - return 1; - } -#endif /* CAN_ISOTP */ + + if (!PyArg_ParseTuple(args, "O&kk", PyUnicode_FSConverter, + &interfaceName, + &rx_id, + &tx_id)) + return 0; + + len = PyBytes_GET_SIZE(interfaceName); + + if (len == 0) { + ifr.ifr_ifindex = 0; + } else if ((size_t)len < sizeof(ifr.ifr_name)) { + strncpy(ifr.ifr_name, PyBytes_AS_STRING(interfaceName), sizeof(ifr.ifr_name)); + ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; + if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { + s->errorhandler(); + Py_DECREF(interfaceName); + return 0; + } + } else { + PyErr_SetString(PyExc_OSError, + "AF_CAN interface name too long"); + Py_DECREF(interfaceName); + return 0; + } + + addr->can_family = AF_CAN; + addr->can_ifindex = ifr.ifr_ifindex; + addr->can_addr.tp.rx_id = rx_id; + addr->can_addr.tp.tx_id = tx_id; + + *len_ret = sizeof(*addr); + Py_DECREF(interfaceName); + return 1; + } +#endif /* CAN_ISOTP */ #ifdef CAN_J1939 case CAN_J1939: { @@ -2299,78 +2299,78 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 1; } #endif /* CAN_J1939 */ - default: + default: PyErr_Format(PyExc_OSError, "%s(): unsupported CAN protocol", caller); - return 0; - } -#endif /* AF_CAN && SIOCGIFINDEX */ - -#ifdef PF_SYSTEM - case PF_SYSTEM: - switch (s->sock_proto) { -#ifdef SYSPROTO_CONTROL - case SYSPROTO_CONTROL: - { + return 0; + } +#endif /* AF_CAN && SIOCGIFINDEX */ + +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch (s->sock_proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + { struct sockaddr_ctl *addr = &addrbuf->ctl; - addr->sc_family = AF_SYSTEM; - addr->ss_sysaddr = AF_SYS_CONTROL; - - if (PyUnicode_Check(args)) { - struct ctl_info info; - PyObject *ctl_name; - - if (!PyArg_Parse(args, "O&", - PyUnicode_FSConverter, &ctl_name)) { - return 0; - } - - if (PyBytes_GET_SIZE(ctl_name) > (Py_ssize_t)sizeof(info.ctl_name)) { - PyErr_SetString(PyExc_ValueError, - "provided string is too long"); - Py_DECREF(ctl_name); - return 0; - } - strncpy(info.ctl_name, PyBytes_AS_STRING(ctl_name), - sizeof(info.ctl_name)); - Py_DECREF(ctl_name); - - if (ioctl(s->sock_fd, CTLIOCGINFO, &info)) { - PyErr_SetString(PyExc_OSError, - "cannot find kernel control with provided name"); - return 0; - } - - addr->sc_id = info.ctl_id; - addr->sc_unit = 0; - } else if (!PyArg_ParseTuple(args, "II", - &(addr->sc_id), &(addr->sc_unit))) { + addr->sc_family = AF_SYSTEM; + addr->ss_sysaddr = AF_SYS_CONTROL; + + if (PyUnicode_Check(args)) { + struct ctl_info info; + PyObject *ctl_name; + + if (!PyArg_Parse(args, "O&", + PyUnicode_FSConverter, &ctl_name)) { + return 0; + } + + if (PyBytes_GET_SIZE(ctl_name) > (Py_ssize_t)sizeof(info.ctl_name)) { + PyErr_SetString(PyExc_ValueError, + "provided string is too long"); + Py_DECREF(ctl_name); + return 0; + } + strncpy(info.ctl_name, PyBytes_AS_STRING(ctl_name), + sizeof(info.ctl_name)); + Py_DECREF(ctl_name); + + if (ioctl(s->sock_fd, CTLIOCGINFO, &info)) { + PyErr_SetString(PyExc_OSError, + "cannot find kernel control with provided name"); + return 0; + } + + addr->sc_id = info.ctl_id; + addr->sc_unit = 0; + } else if (!PyArg_ParseTuple(args, "II", + &(addr->sc_id), &(addr->sc_unit))) { PyErr_Format(PyExc_TypeError, "%s(): PF_SYSTEM address must be a str or " "a pair (id, unit)", caller); - return 0; - } - - *len_ret = sizeof(*addr); - return 1; - } -#endif /* SYSPROTO_CONTROL */ - default: + return 0; + } + + *len_ret = sizeof(*addr); + return 1; + } +#endif /* SYSPROTO_CONTROL */ + default: PyErr_Format(PyExc_OSError, "%s(): unsupported PF_SYSTEM protocol", caller); - return 0; - } -#endif /* PF_SYSTEM */ -#ifdef HAVE_SOCKADDR_ALG - case AF_ALG: - { - const char *type; - const char *name; + return 0; + } +#endif /* PF_SYSTEM */ +#ifdef HAVE_SOCKADDR_ALG + case AF_ALG: + { + const char *type; + const char *name; struct sockaddr_alg *sa = &addrbuf->alg; - - memset(sa, 0, sizeof(*sa)); - sa->salg_family = AF_ALG; - + + memset(sa, 0, sizeof(*sa)); + sa->salg_family = AF_ALG; + if (!PyTuple_Check(args)) { PyErr_Format(PyExc_TypeError, "%s(): AF_ALG address must be tuple, not %.500s", @@ -2381,63 +2381,63 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, "ss|HH;AF_ALG address must be a tuple " "(type, name[, feat[, mask]])", &type, &name, &sa->salg_feat, &sa->salg_mask)) - { - return 0; - } - /* sockaddr_alg has fixed-sized char arrays for type, and name - * both must be NULL terminated. - */ - if (strlen(type) >= sizeof(sa->salg_type)) { - PyErr_SetString(PyExc_ValueError, "AF_ALG type too long."); - return 0; - } - strncpy((char *)sa->salg_type, type, sizeof(sa->salg_type)); - if (strlen(name) >= sizeof(sa->salg_name)) { - PyErr_SetString(PyExc_ValueError, "AF_ALG name too long."); - return 0; - } - strncpy((char *)sa->salg_name, name, sizeof(sa->salg_name)); - - *len_ret = sizeof(*sa); - return 1; - } -#endif /* HAVE_SOCKADDR_ALG */ - - /* More cases here... */ - - default: + { + return 0; + } + /* sockaddr_alg has fixed-sized char arrays for type, and name + * both must be NULL terminated. + */ + if (strlen(type) >= sizeof(sa->salg_type)) { + PyErr_SetString(PyExc_ValueError, "AF_ALG type too long."); + return 0; + } + strncpy((char *)sa->salg_type, type, sizeof(sa->salg_type)); + if (strlen(name) >= sizeof(sa->salg_name)) { + PyErr_SetString(PyExc_ValueError, "AF_ALG name too long."); + return 0; + } + strncpy((char *)sa->salg_name, name, sizeof(sa->salg_name)); + + *len_ret = sizeof(*sa); + return 1; + } +#endif /* HAVE_SOCKADDR_ALG */ + + /* More cases here... */ + + default: PyErr_Format(PyExc_OSError, "%s(): bad family", caller); - return 0; - - } -} - - -/* Get the address length according to the socket object's address family. - Return 1 if the family is known, 0 otherwise. The length is returned - through len_ret. */ - -static int -getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) -{ - switch (s->sock_family) { - -#if defined(AF_UNIX) - case AF_UNIX: - { - *len_ret = sizeof (struct sockaddr_un); - return 1; - } -#endif /* AF_UNIX */ - -#if defined(AF_NETLINK) - case AF_NETLINK: - { - *len_ret = sizeof (struct sockaddr_nl); - return 1; - } -#endif /* AF_NETLINK */ - + return 0; + + } +} + + +/* Get the address length according to the socket object's address family. + Return 1 if the family is known, 0 otherwise. The length is returned + through len_ret. */ + +static int +getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) +{ + switch (s->sock_family) { + +#if defined(AF_UNIX) + case AF_UNIX: + { + *len_ret = sizeof (struct sockaddr_un); + return 1; + } +#endif /* AF_UNIX */ + +#if defined(AF_NETLINK) + case AF_NETLINK: + { + *len_ret = sizeof (struct sockaddr_nl); + return 1; + } +#endif /* AF_NETLINK */ + #if defined(AF_QIPCRTR) case AF_QIPCRTR: { @@ -2446,5343 +2446,5343 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) } #endif /* AF_QIPCRTR */ -#if defined(AF_VSOCK) - case AF_VSOCK: - { - *len_ret = sizeof (struct sockaddr_vm); - return 1; - } -#endif /* AF_VSOCK */ - -#ifdef AF_RDS - case AF_RDS: - /* RDS sockets use sockaddr_in: fall-through */ -#endif /* AF_RDS */ - - case AF_INET: - { - *len_ret = sizeof (struct sockaddr_in); - return 1; - } - -#ifdef ENABLE_IPV6 - case AF_INET6: - { - *len_ret = sizeof (struct sockaddr_in6); - return 1; - } -#endif /* ENABLE_IPV6 */ - -#ifdef USE_BLUETOOTH - case AF_BLUETOOTH: - { - switch(s->sock_proto) - { - +#if defined(AF_VSOCK) + case AF_VSOCK: + { + *len_ret = sizeof (struct sockaddr_vm); + return 1; + } +#endif /* AF_VSOCK */ + +#ifdef AF_RDS + case AF_RDS: + /* RDS sockets use sockaddr_in: fall-through */ +#endif /* AF_RDS */ + + case AF_INET: + { + *len_ret = sizeof (struct sockaddr_in); + return 1; + } + +#ifdef ENABLE_IPV6 + case AF_INET6: + { + *len_ret = sizeof (struct sockaddr_in6); + return 1; + } +#endif /* ENABLE_IPV6 */ + +#ifdef USE_BLUETOOTH + case AF_BLUETOOTH: + { + switch(s->sock_proto) + { + #ifdef BTPROTO_L2CAP - case BTPROTO_L2CAP: - *len_ret = sizeof (struct sockaddr_l2); - return 1; + case BTPROTO_L2CAP: + *len_ret = sizeof (struct sockaddr_l2); + return 1; #endif /* BTPROTO_L2CAP */ - case BTPROTO_RFCOMM: - *len_ret = sizeof (struct sockaddr_rc); - return 1; + case BTPROTO_RFCOMM: + *len_ret = sizeof (struct sockaddr_rc); + return 1; #ifdef BTPROTO_HCI - case BTPROTO_HCI: - *len_ret = sizeof (struct sockaddr_hci); - return 1; -#if !defined(__FreeBSD__) - case BTPROTO_SCO: - *len_ret = sizeof (struct sockaddr_sco); - return 1; -#endif /* !__FreeBSD__ */ + case BTPROTO_HCI: + *len_ret = sizeof (struct sockaddr_hci); + return 1; +#if !defined(__FreeBSD__) + case BTPROTO_SCO: + *len_ret = sizeof (struct sockaddr_sco); + return 1; +#endif /* !__FreeBSD__ */ #endif /* BTPROTO_HCI */ - default: - PyErr_SetString(PyExc_OSError, "getsockaddrlen: " - "unknown BT protocol"); - return 0; - - } - } -#endif /* USE_BLUETOOTH */ - -#ifdef HAVE_NETPACKET_PACKET_H - case AF_PACKET: - { - *len_ret = sizeof (struct sockaddr_ll); - return 1; + default: + PyErr_SetString(PyExc_OSError, "getsockaddrlen: " + "unknown BT protocol"); + return 0; + + } + } +#endif /* USE_BLUETOOTH */ + +#ifdef HAVE_NETPACKET_PACKET_H + case AF_PACKET: + { + *len_ret = sizeof (struct sockaddr_ll); + return 1; + } +#endif /* HAVE_NETPACKET_PACKET_H */ + +#ifdef HAVE_LINUX_TIPC_H + case AF_TIPC: + { + *len_ret = sizeof (struct sockaddr_tipc); + return 1; + } +#endif /* HAVE_LINUX_TIPC_H */ + +#ifdef AF_CAN + case AF_CAN: + { + *len_ret = sizeof (struct sockaddr_can); + return 1; + } +#endif /* AF_CAN */ + +#ifdef PF_SYSTEM + case PF_SYSTEM: + switch(s->sock_proto) { +#ifdef SYSPROTO_CONTROL + case SYSPROTO_CONTROL: + *len_ret = sizeof (struct sockaddr_ctl); + return 1; +#endif /* SYSPROTO_CONTROL */ + default: + PyErr_SetString(PyExc_OSError, "getsockaddrlen: " + "unknown PF_SYSTEM protocol"); + return 0; + } +#endif /* PF_SYSTEM */ +#ifdef HAVE_SOCKADDR_ALG + case AF_ALG: + { + *len_ret = sizeof (struct sockaddr_alg); + return 1; + } +#endif /* HAVE_SOCKADDR_ALG */ + + /* More cases here... */ + + default: + PyErr_SetString(PyExc_OSError, "getsockaddrlen: bad family"); + return 0; + + } +} + + +/* Support functions for the sendmsg() and recvmsg[_into]() methods. + Currently, these methods are only compiled if the RFC 2292/3542 + CMSG_LEN() macro is available. Older systems seem to have used + sizeof(struct cmsghdr) + (length) where CMSG_LEN() is used now, so + it may be possible to define CMSG_LEN() that way if it's not + provided. Some architectures might need extra padding after the + cmsghdr, however, and CMSG_LEN() would have to take account of + this. */ +#ifdef CMSG_LEN +/* If length is in range, set *result to CMSG_LEN(length) and return + true; otherwise, return false. */ +static int +get_CMSG_LEN(size_t length, size_t *result) +{ + size_t tmp; + + if (length > (SOCKLEN_T_LIMIT - CMSG_LEN(0))) + return 0; + tmp = CMSG_LEN(length); + if (tmp > SOCKLEN_T_LIMIT || tmp < length) + return 0; + *result = tmp; + return 1; +} + +#ifdef CMSG_SPACE +/* If length is in range, set *result to CMSG_SPACE(length) and return + true; otherwise, return false. */ +static int +get_CMSG_SPACE(size_t length, size_t *result) +{ + size_t tmp; + + /* Use CMSG_SPACE(1) here in order to take account of the padding + necessary before *and* after the data. */ + if (length > (SOCKLEN_T_LIMIT - CMSG_SPACE(1))) + return 0; + tmp = CMSG_SPACE(length); + if (tmp > SOCKLEN_T_LIMIT || tmp < length) + return 0; + *result = tmp; + return 1; +} +#endif + +/* Return true iff msg->msg_controllen is valid, cmsgh is a valid + pointer in msg->msg_control with at least "space" bytes after it, + and its cmsg_len member inside the buffer. */ +static int +cmsg_min_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t space) +{ + size_t cmsg_offset; + static const size_t cmsg_len_end = (offsetof(struct cmsghdr, cmsg_len) + + sizeof(cmsgh->cmsg_len)); + + /* Note that POSIX allows msg_controllen to be of signed type. */ + if (cmsgh == NULL || msg->msg_control == NULL) + return 0; + /* Note that POSIX allows msg_controllen to be of a signed type. This is + annoying under OS X as it's unsigned there and so it triggers a + tautological comparison warning under Clang when compared against 0. + Since the check is valid on other platforms, silence the warning under + Clang. */ + #ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wtautological-compare" + #endif + #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wtype-limits" + #endif + if (msg->msg_controllen < 0) + return 0; + #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) + #pragma GCC diagnostic pop + #endif + #ifdef __clang__ + #pragma clang diagnostic pop + #endif + if (space < cmsg_len_end) + space = cmsg_len_end; + cmsg_offset = (char *)cmsgh - (char *)msg->msg_control; + return (cmsg_offset <= (size_t)-1 - space && + cmsg_offset + space <= msg->msg_controllen); +} + +/* If pointer CMSG_DATA(cmsgh) is in buffer msg->msg_control, set + *space to number of bytes following it in the buffer and return + true; otherwise, return false. Assumes cmsgh, msg->msg_control and + msg->msg_controllen are valid. */ +static int +get_cmsg_data_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t *space) +{ + size_t data_offset; + char *data_ptr; + + if ((data_ptr = (char *)CMSG_DATA(cmsgh)) == NULL) + return 0; + data_offset = data_ptr - (char *)msg->msg_control; + if (data_offset > msg->msg_controllen) + return 0; + *space = msg->msg_controllen - data_offset; + return 1; +} + +/* If cmsgh is invalid or not contained in the buffer pointed to by + msg->msg_control, return -1. If cmsgh is valid and its associated + data is entirely contained in the buffer, set *data_len to the + length of the associated data and return 0. If only part of the + associated data is contained in the buffer but cmsgh is otherwise + valid, set *data_len to the length contained in the buffer and + return 1. */ +static int +get_cmsg_data_len(struct msghdr *msg, struct cmsghdr *cmsgh, size_t *data_len) +{ + size_t space, cmsg_data_len; + + if (!cmsg_min_space(msg, cmsgh, CMSG_LEN(0)) || + cmsgh->cmsg_len < CMSG_LEN(0)) + return -1; + cmsg_data_len = cmsgh->cmsg_len - CMSG_LEN(0); + if (!get_cmsg_data_space(msg, cmsgh, &space)) + return -1; + if (space >= cmsg_data_len) { + *data_len = cmsg_data_len; + return 0; + } + *data_len = space; + return 1; +} +#endif /* CMSG_LEN */ + + +struct sock_accept { + socklen_t *addrlen; + sock_addr_t *addrbuf; + SOCKET_T result; +}; + +#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) +/* accept4() is available on Linux 2.6.28+ and glibc 2.10 */ +static int accept4_works = -1; +#endif + +static int +sock_accept_impl(PySocketSockObject *s, void *data) +{ + struct sock_accept *ctx = data; + struct sockaddr *addr = SAS2SA(ctx->addrbuf); + socklen_t *paddrlen = ctx->addrlen; +#ifdef HAVE_SOCKADDR_ALG + /* AF_ALG does not support accept() with addr and raises + * ECONNABORTED instead. */ + if (s->sock_family == AF_ALG) { + addr = NULL; + paddrlen = NULL; + *ctx->addrlen = 0; + } +#endif + +#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) + if (accept4_works != 0) { + ctx->result = accept4(s->sock_fd, addr, paddrlen, + SOCK_CLOEXEC); + if (ctx->result == INVALID_SOCKET && accept4_works == -1) { + /* On Linux older than 2.6.28, accept4() fails with ENOSYS */ + accept4_works = (errno != ENOSYS); + } + } + if (accept4_works == 0) + ctx->result = accept(s->sock_fd, addr, paddrlen); +#else + ctx->result = accept(s->sock_fd, addr, paddrlen); +#endif + +#ifdef MS_WINDOWS + return (ctx->result != INVALID_SOCKET); +#else + return (ctx->result >= 0); +#endif +} + +/* s._accept() -> (fd, address) */ + +static PyObject * +sock_accept(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) +{ + sock_addr_t addrbuf; + SOCKET_T newfd; + socklen_t addrlen; + PyObject *sock = NULL; + PyObject *addr = NULL; + PyObject *res = NULL; + struct sock_accept ctx; + + if (!getsockaddrlen(s, &addrlen)) + return NULL; + memset(&addrbuf, 0, addrlen); + + if (!IS_SELECTABLE(s)) + return select_error(); + + ctx.addrlen = &addrlen; + ctx.addrbuf = &addrbuf; + if (sock_call(s, 0, sock_accept_impl, &ctx) < 0) + return NULL; + newfd = ctx.result; + +#ifdef MS_WINDOWS + if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { + PyErr_SetFromWindowsErr(0); + SOCKETCLOSE(newfd); + goto finally; + } +#else + +#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) + if (!accept4_works) +#endif + { + if (_Py_set_inheritable(newfd, 0, NULL) < 0) { + SOCKETCLOSE(newfd); + goto finally; + } + } +#endif + + sock = PyLong_FromSocket_t(newfd); + if (sock == NULL) { + SOCKETCLOSE(newfd); + goto finally; + } + + addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), + addrlen, s->sock_proto); + if (addr == NULL) + goto finally; + + res = PyTuple_Pack(2, sock, addr); + +finally: + Py_XDECREF(sock); + Py_XDECREF(addr); + return res; +} + +PyDoc_STRVAR(accept_doc, +"_accept() -> (integer, address info)\n\ +\n\ +Wait for an incoming connection. Return a new socket file descriptor\n\ +representing the connection, and the address of the client.\n\ +For IP sockets, the address info is a pair (hostaddr, port)."); + +/* s.setblocking(flag) method. Argument: + False -- non-blocking mode; same as settimeout(0) + True -- blocking mode; same as settimeout(None) +*/ + +static PyObject * +sock_setblocking(PySocketSockObject *s, PyObject *arg) +{ + long block; + + block = PyLong_AsLong(arg); + if (block == -1 && PyErr_Occurred()) + return NULL; + + s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); + if (internal_setblocking(s, block) == -1) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setblocking_doc, +"setblocking(flag)\n\ +\n\ +Set the socket to blocking (flag is true) or non-blocking (false).\n\ +setblocking(True) is equivalent to settimeout(None);\n\ +setblocking(False) is equivalent to settimeout(0.0)."); + +/* s.getblocking() method. + Returns True if socket is in blocking mode, + False if it is in non-blocking mode. +*/ +static PyObject * +sock_getblocking(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) +{ + if (s->sock_timeout) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +PyDoc_STRVAR(getblocking_doc, +"getblocking()\n\ +\n\ +Returns True if socket is in blocking mode, or False if it\n\ +is in non-blocking mode."); + +static int +socket_parse_timeout(_PyTime_t *timeout, PyObject *timeout_obj) +{ +#ifdef MS_WINDOWS + struct timeval tv; +#endif +#ifndef HAVE_POLL + _PyTime_t ms; +#endif + int overflow = 0; + + if (timeout_obj == Py_None) { + *timeout = _PyTime_FromSeconds(-1); + return 0; + } + + if (_PyTime_FromSecondsObject(timeout, + timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) + return -1; + + if (*timeout < 0) { + PyErr_SetString(PyExc_ValueError, "Timeout value out of range"); + return -1; + } + +#ifdef MS_WINDOWS + overflow |= (_PyTime_AsTimeval(*timeout, &tv, _PyTime_ROUND_TIMEOUT) < 0); +#endif +#ifndef HAVE_POLL + ms = _PyTime_AsMilliseconds(*timeout, _PyTime_ROUND_TIMEOUT); + overflow |= (ms > INT_MAX); +#endif + if (overflow) { + PyErr_SetString(PyExc_OverflowError, + "timeout doesn't fit into C timeval"); + return -1; + } + + return 0; +} + +/* s.settimeout(timeout) method. Argument: + None -- no timeout, blocking mode; same as setblocking(True) + 0.0 -- non-blocking mode; same as setblocking(False) + > 0 -- timeout mode; operations time out after timeout seconds + < 0 -- illegal; raises an exception +*/ +static PyObject * +sock_settimeout(PySocketSockObject *s, PyObject *arg) +{ + _PyTime_t timeout; + + if (socket_parse_timeout(&timeout, arg) < 0) + return NULL; + + s->sock_timeout = timeout; + + int block = timeout < 0; + /* Blocking mode for a Python socket object means that operations + like :meth:`recv` or :meth:`sendall` will block the execution of + the current thread until they are complete or aborted with a + `socket.timeout` or `socket.error` errors. When timeout is `None`, + the underlying FD is in a blocking mode. When timeout is a positive + number, the FD is in a non-blocking mode, and socket ops are + implemented with a `select()` call. + + When timeout is 0.0, the FD is in a non-blocking mode. + + This table summarizes all states in which the socket object and + its underlying FD can be: + + ==================== ===================== ============== + `gettimeout()` `getblocking()` FD + ==================== ===================== ============== + ``None`` ``True`` blocking + ``0.0`` ``False`` non-blocking + ``> 0`` ``True`` non-blocking + */ + + if (internal_setblocking(s, block) == -1) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(settimeout_doc, +"settimeout(timeout)\n\ +\n\ +Set a timeout on socket operations. 'timeout' can be a float,\n\ +giving in seconds, or None. Setting a timeout of None disables\n\ +the timeout feature and is equivalent to setblocking(1).\n\ +Setting a timeout of zero is the same as setblocking(0)."); + +/* s.gettimeout() method. + Returns the timeout associated with a socket. */ +static PyObject * +sock_gettimeout(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) +{ + if (s->sock_timeout < 0) { + Py_RETURN_NONE; + } + else { + double seconds = _PyTime_AsSecondsDouble(s->sock_timeout); + return PyFloat_FromDouble(seconds); + } +} + +PyDoc_STRVAR(gettimeout_doc, +"gettimeout() -> timeout\n\ +\n\ +Returns the timeout in seconds (float) associated with socket\n\ +operations. A timeout of None indicates that timeouts on socket\n\ +operations are disabled."); + +/* s.setsockopt() method. + With an integer third argument, sets an integer optval with optlen=4. + With None as third argument and an integer fourth argument, set + optval=NULL with unsigned int as optlen. + With a string third argument, sets an option from a buffer; + use optional built-in module 'struct' to encode the string. +*/ + +static PyObject * +sock_setsockopt(PySocketSockObject *s, PyObject *args) +{ + int level; + int optname; + int res; + Py_buffer optval; + int flag; + unsigned int optlen; + PyObject *none; + +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + uint64_t vflag; // Must be set width of 64 bits + /* setsockopt(level, opt, flag) */ + if (PyArg_ParseTuple(args, "iiK:setsockopt", + &level, &optname, &vflag)) { + // level should always be set to AF_VSOCK + res = setsockopt(s->sock_fd, level, optname, + (void*)&vflag, sizeof vflag); + goto done; + } + return NULL; + } +#endif + + /* setsockopt(level, opt, flag) */ + if (PyArg_ParseTuple(args, "iii:setsockopt", + &level, &optname, &flag)) { + res = setsockopt(s->sock_fd, level, optname, + (char*)&flag, sizeof flag); + goto done; + } + + PyErr_Clear(); + /* setsockopt(level, opt, None, flag) */ + if (PyArg_ParseTuple(args, "iiO!I:setsockopt", + &level, &optname, Py_TYPE(Py_None), &none, &optlen)) { + assert(sizeof(socklen_t) >= sizeof(unsigned int)); + res = setsockopt(s->sock_fd, level, optname, + NULL, (socklen_t)optlen); + goto done; + } + + PyErr_Clear(); + /* setsockopt(level, opt, buffer) */ + if (!PyArg_ParseTuple(args, "iiy*:setsockopt", + &level, &optname, &optval)) + return NULL; + +#ifdef MS_WINDOWS + if (optval.len > INT_MAX) { + PyBuffer_Release(&optval); + PyErr_Format(PyExc_OverflowError, + "socket option is larger than %i bytes", + INT_MAX); + return NULL; + } + res = setsockopt(s->sock_fd, level, optname, + optval.buf, (int)optval.len); +#else + res = setsockopt(s->sock_fd, level, optname, optval.buf, optval.len); +#endif + PyBuffer_Release(&optval); + +done: + if (res < 0) { + return s->errorhandler(); + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setsockopt_doc, +"setsockopt(level, option, value: int)\n\ +setsockopt(level, option, value: buffer)\n\ +setsockopt(level, option, None, optlen: int)\n\ +\n\ +Set a socket option. See the Unix manual for level and option.\n\ +The value argument can either be an integer, a string buffer, or\n\ +None, optlen."); + + +/* s.getsockopt() method. + With two arguments, retrieves an integer option. + With a third integer argument, retrieves a string buffer of that size; + use optional built-in module 'struct' to decode the string. */ + +static PyObject * +sock_getsockopt(PySocketSockObject *s, PyObject *args) +{ + int level; + int optname; + int res; + PyObject *buf; + socklen_t buflen = 0; + int flag = 0; + socklen_t flagsize; + + if (!PyArg_ParseTuple(args, "ii|i:getsockopt", + &level, &optname, &buflen)) + return NULL; + + if (buflen == 0) { +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + uint64_t vflag = 0; // Must be set width of 64 bits + flagsize = sizeof vflag; + res = getsockopt(s->sock_fd, level, optname, + (void *)&vflag, &flagsize); + if (res < 0) + return s->errorhandler(); + return PyLong_FromUnsignedLong(vflag); + } +#endif + flagsize = sizeof flag; + res = getsockopt(s->sock_fd, level, optname, + (void *)&flag, &flagsize); + if (res < 0) + return s->errorhandler(); + return PyLong_FromLong(flag); + } +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + PyErr_SetString(PyExc_OSError, + "getsockopt string buffer not allowed"); + return NULL; + } +#endif + if (buflen <= 0 || buflen > 1024) { + PyErr_SetString(PyExc_OSError, + "getsockopt buflen out of range"); + return NULL; + } + buf = PyBytes_FromStringAndSize((char *)NULL, buflen); + if (buf == NULL) + return NULL; + res = getsockopt(s->sock_fd, level, optname, + (void *)PyBytes_AS_STRING(buf), &buflen); + if (res < 0) { + Py_DECREF(buf); + return s->errorhandler(); + } + _PyBytes_Resize(&buf, buflen); + return buf; +} + +PyDoc_STRVAR(getsockopt_doc, +"getsockopt(level, option[, buffersize]) -> value\n\ +\n\ +Get a socket option. See the Unix manual for level and option.\n\ +If a nonzero buffersize argument is given, the return value is a\n\ +string of that length; otherwise it is an integer."); + + +/* s.bind(sockaddr) method */ + +static PyObject * +sock_bind(PySocketSockObject *s, PyObject *addro) +{ + sock_addr_t addrbuf; + int addrlen; + int res; + + if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "bind")) { + return NULL; } -#endif /* HAVE_NETPACKET_PACKET_H */ -#ifdef HAVE_LINUX_TIPC_H - case AF_TIPC: - { - *len_ret = sizeof (struct sockaddr_tipc); - return 1; + if (PySys_Audit("socket.bind", "OO", s, addro) < 0) { + return NULL; } -#endif /* HAVE_LINUX_TIPC_H */ -#ifdef AF_CAN - case AF_CAN: - { - *len_ret = sizeof (struct sockaddr_can); - return 1; + Py_BEGIN_ALLOW_THREADS + res = bind(s->sock_fd, SAS2SA(&addrbuf), addrlen); + Py_END_ALLOW_THREADS + if (res < 0) + return s->errorhandler(); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(bind_doc, +"bind(address)\n\ +\n\ +Bind the socket to a local address. For IP sockets, the address is a\n\ +pair (host, port); the host must refer to the local host. For raw packet\n\ +sockets the address is a tuple (ifname, proto [,pkttype [,hatype [,addr]]])"); + + +/* s.close() method. + Set the file descriptor to -1 so operations tried subsequently + will surely fail. */ + +static PyObject * +sock_close(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) +{ + SOCKET_T fd; + int res; + + fd = s->sock_fd; + if (fd != INVALID_SOCKET) { + s->sock_fd = INVALID_SOCKET; + + /* We do not want to retry upon EINTR: see + http://lwn.net/Articles/576478/ and + http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html + for more details. */ + Py_BEGIN_ALLOW_THREADS + res = SOCKETCLOSE(fd); + Py_END_ALLOW_THREADS + /* bpo-30319: The peer can already have closed the connection. + Python ignores ECONNRESET on close(). */ + if (res < 0 && errno != ECONNRESET) { + return s->errorhandler(); + } + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(sock_close_doc, +"close()\n\ +\n\ +Close the socket. It cannot be used after this call."); + +static PyObject * +sock_detach(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) +{ + SOCKET_T fd = s->sock_fd; + s->sock_fd = INVALID_SOCKET; + return PyLong_FromSocket_t(fd); +} + +PyDoc_STRVAR(detach_doc, +"detach()\n\ +\n\ +Close the socket object without closing the underlying file descriptor.\n\ +The object cannot be used after this call, but the file descriptor\n\ +can be reused for other purposes. The file descriptor is returned."); + +static int +sock_connect_impl(PySocketSockObject *s, void* Py_UNUSED(data)) +{ + int err; + socklen_t size = sizeof err; + + if (getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR, (void *)&err, &size)) { + /* getsockopt() failed */ + return 0; + } + + if (err == EISCONN) + return 1; + if (err != 0) { + /* sock_call_ex() uses GET_SOCK_ERROR() to get the error code */ + SET_SOCK_ERROR(err); + return 0; + } + return 1; +} + +static int +internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen, + int raise) +{ + int res, err, wait_connect; + + Py_BEGIN_ALLOW_THREADS + res = connect(s->sock_fd, addr, addrlen); + Py_END_ALLOW_THREADS + + if (!res) { + /* connect() succeeded, the socket is connected */ + return 0; + } + + /* connect() failed */ + + /* save error, PyErr_CheckSignals() can replace it */ + err = GET_SOCK_ERROR; + if (CHECK_ERRNO(EINTR)) { + if (PyErr_CheckSignals()) + return -1; + + /* Issue #23618: when connect() fails with EINTR, the connection is + running asynchronously. + + If the socket is blocking or has a timeout, wait until the + connection completes, fails or timed out using select(), and then + get the connection status using getsockopt(SO_ERROR). + + If the socket is non-blocking, raise InterruptedError. The caller is + responsible to wait until the connection completes, fails or timed + out (it's the case in asyncio for example). */ + wait_connect = (s->sock_timeout != 0 && IS_SELECTABLE(s)); + } + else { + wait_connect = (s->sock_timeout > 0 && err == SOCK_INPROGRESS_ERR + && IS_SELECTABLE(s)); + } + + if (!wait_connect) { + if (raise) { + /* restore error, maybe replaced by PyErr_CheckSignals() */ + SET_SOCK_ERROR(err); + s->errorhandler(); + return -1; + } + else + return err; + } + + if (raise) { + /* socket.connect() raises an exception on error */ + if (sock_call_ex(s, 1, sock_connect_impl, NULL, + 1, NULL, s->sock_timeout) < 0) + return -1; + } + else { + /* socket.connect_ex() returns the error code on error */ + if (sock_call_ex(s, 1, sock_connect_impl, NULL, + 1, &err, s->sock_timeout) < 0) + return err; + } + return 0; +} + +/* s.connect(sockaddr) method */ + +static PyObject * +sock_connect(PySocketSockObject *s, PyObject *addro) +{ + sock_addr_t addrbuf; + int addrlen; + int res; + + if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "connect")) { + return NULL; } -#endif /* AF_CAN */ - -#ifdef PF_SYSTEM - case PF_SYSTEM: - switch(s->sock_proto) { -#ifdef SYSPROTO_CONTROL - case SYSPROTO_CONTROL: - *len_ret = sizeof (struct sockaddr_ctl); - return 1; -#endif /* SYSPROTO_CONTROL */ - default: - PyErr_SetString(PyExc_OSError, "getsockaddrlen: " - "unknown PF_SYSTEM protocol"); - return 0; - } -#endif /* PF_SYSTEM */ -#ifdef HAVE_SOCKADDR_ALG - case AF_ALG: - { - *len_ret = sizeof (struct sockaddr_alg); - return 1; + + if (PySys_Audit("socket.connect", "OO", s, addro) < 0) { + return NULL; } -#endif /* HAVE_SOCKADDR_ALG */ - - /* More cases here... */ - - default: - PyErr_SetString(PyExc_OSError, "getsockaddrlen: bad family"); - return 0; + res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 1); + if (res < 0) + return NULL; + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(connect_doc, +"connect(address)\n\ +\n\ +Connect the socket to a remote address. For IP sockets, the address\n\ +is a pair (host, port)."); + + +/* s.connect_ex(sockaddr) method */ + +static PyObject * +sock_connect_ex(PySocketSockObject *s, PyObject *addro) +{ + sock_addr_t addrbuf; + int addrlen; + int res; + + if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "connect_ex")) { + return NULL; } -} - - -/* Support functions for the sendmsg() and recvmsg[_into]() methods. - Currently, these methods are only compiled if the RFC 2292/3542 - CMSG_LEN() macro is available. Older systems seem to have used - sizeof(struct cmsghdr) + (length) where CMSG_LEN() is used now, so - it may be possible to define CMSG_LEN() that way if it's not - provided. Some architectures might need extra padding after the - cmsghdr, however, and CMSG_LEN() would have to take account of - this. */ -#ifdef CMSG_LEN -/* If length is in range, set *result to CMSG_LEN(length) and return - true; otherwise, return false. */ -static int -get_CMSG_LEN(size_t length, size_t *result) -{ - size_t tmp; - - if (length > (SOCKLEN_T_LIMIT - CMSG_LEN(0))) - return 0; - tmp = CMSG_LEN(length); - if (tmp > SOCKLEN_T_LIMIT || tmp < length) - return 0; - *result = tmp; - return 1; -} - -#ifdef CMSG_SPACE -/* If length is in range, set *result to CMSG_SPACE(length) and return - true; otherwise, return false. */ -static int -get_CMSG_SPACE(size_t length, size_t *result) -{ - size_t tmp; - - /* Use CMSG_SPACE(1) here in order to take account of the padding - necessary before *and* after the data. */ - if (length > (SOCKLEN_T_LIMIT - CMSG_SPACE(1))) - return 0; - tmp = CMSG_SPACE(length); - if (tmp > SOCKLEN_T_LIMIT || tmp < length) - return 0; - *result = tmp; - return 1; -} -#endif - -/* Return true iff msg->msg_controllen is valid, cmsgh is a valid - pointer in msg->msg_control with at least "space" bytes after it, - and its cmsg_len member inside the buffer. */ -static int -cmsg_min_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t space) -{ - size_t cmsg_offset; - static const size_t cmsg_len_end = (offsetof(struct cmsghdr, cmsg_len) + - sizeof(cmsgh->cmsg_len)); - - /* Note that POSIX allows msg_controllen to be of signed type. */ - if (cmsgh == NULL || msg->msg_control == NULL) - return 0; - /* Note that POSIX allows msg_controllen to be of a signed type. This is - annoying under OS X as it's unsigned there and so it triggers a - tautological comparison warning under Clang when compared against 0. - Since the check is valid on other platforms, silence the warning under - Clang. */ - #ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wtautological-compare" - #endif - #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wtype-limits" - #endif - if (msg->msg_controllen < 0) - return 0; - #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) - #pragma GCC diagnostic pop - #endif - #ifdef __clang__ - #pragma clang diagnostic pop - #endif - if (space < cmsg_len_end) - space = cmsg_len_end; - cmsg_offset = (char *)cmsgh - (char *)msg->msg_control; - return (cmsg_offset <= (size_t)-1 - space && - cmsg_offset + space <= msg->msg_controllen); -} - -/* If pointer CMSG_DATA(cmsgh) is in buffer msg->msg_control, set - *space to number of bytes following it in the buffer and return - true; otherwise, return false. Assumes cmsgh, msg->msg_control and - msg->msg_controllen are valid. */ -static int -get_cmsg_data_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t *space) -{ - size_t data_offset; - char *data_ptr; - - if ((data_ptr = (char *)CMSG_DATA(cmsgh)) == NULL) - return 0; - data_offset = data_ptr - (char *)msg->msg_control; - if (data_offset > msg->msg_controllen) - return 0; - *space = msg->msg_controllen - data_offset; - return 1; -} - -/* If cmsgh is invalid or not contained in the buffer pointed to by - msg->msg_control, return -1. If cmsgh is valid and its associated - data is entirely contained in the buffer, set *data_len to the - length of the associated data and return 0. If only part of the - associated data is contained in the buffer but cmsgh is otherwise - valid, set *data_len to the length contained in the buffer and - return 1. */ -static int -get_cmsg_data_len(struct msghdr *msg, struct cmsghdr *cmsgh, size_t *data_len) -{ - size_t space, cmsg_data_len; - - if (!cmsg_min_space(msg, cmsgh, CMSG_LEN(0)) || - cmsgh->cmsg_len < CMSG_LEN(0)) - return -1; - cmsg_data_len = cmsgh->cmsg_len - CMSG_LEN(0); - if (!get_cmsg_data_space(msg, cmsgh, &space)) - return -1; - if (space >= cmsg_data_len) { - *data_len = cmsg_data_len; - return 0; + + if (PySys_Audit("socket.connect", "OO", s, addro) < 0) { + return NULL; } - *data_len = space; - return 1; -} -#endif /* CMSG_LEN */ - - -struct sock_accept { - socklen_t *addrlen; - sock_addr_t *addrbuf; - SOCKET_T result; -}; -#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) -/* accept4() is available on Linux 2.6.28+ and glibc 2.10 */ -static int accept4_works = -1; -#endif - -static int -sock_accept_impl(PySocketSockObject *s, void *data) -{ - struct sock_accept *ctx = data; - struct sockaddr *addr = SAS2SA(ctx->addrbuf); - socklen_t *paddrlen = ctx->addrlen; -#ifdef HAVE_SOCKADDR_ALG - /* AF_ALG does not support accept() with addr and raises - * ECONNABORTED instead. */ - if (s->sock_family == AF_ALG) { - addr = NULL; - paddrlen = NULL; - *ctx->addrlen = 0; + res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 0); + if (res < 0) + return NULL; + + return PyLong_FromLong((long) res); +} + +PyDoc_STRVAR(connect_ex_doc, +"connect_ex(address) -> errno\n\ +\n\ +This is like connect(address), but returns an error code (the errno value)\n\ +instead of raising an exception when an error occurs."); + + +/* s.fileno() method */ + +static PyObject * +sock_fileno(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) +{ + return PyLong_FromSocket_t(s->sock_fd); +} + +PyDoc_STRVAR(fileno_doc, +"fileno() -> integer\n\ +\n\ +Return the integer file descriptor of the socket."); + + +/* s.getsockname() method */ + +static PyObject * +sock_getsockname(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) +{ + sock_addr_t addrbuf; + int res; + socklen_t addrlen; + + if (!getsockaddrlen(s, &addrlen)) + return NULL; + memset(&addrbuf, 0, addrlen); + Py_BEGIN_ALLOW_THREADS + res = getsockname(s->sock_fd, SAS2SA(&addrbuf), &addrlen); + Py_END_ALLOW_THREADS + if (res < 0) + return s->errorhandler(); + return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, + s->sock_proto); +} + +PyDoc_STRVAR(getsockname_doc, +"getsockname() -> address info\n\ +\n\ +Return the address of the local endpoint. The format depends on the\n\ +address family. For IPv4 sockets, the address info is a pair\n\ +(hostaddr, port)."); + + +#ifdef HAVE_GETPEERNAME /* Cray APP doesn't have this :-( */ +/* s.getpeername() method */ + +static PyObject * +sock_getpeername(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) +{ + sock_addr_t addrbuf; + int res; + socklen_t addrlen; + + if (!getsockaddrlen(s, &addrlen)) + return NULL; + memset(&addrbuf, 0, addrlen); + Py_BEGIN_ALLOW_THREADS + res = getpeername(s->sock_fd, SAS2SA(&addrbuf), &addrlen); + Py_END_ALLOW_THREADS + if (res < 0) + return s->errorhandler(); + return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, + s->sock_proto); +} + +PyDoc_STRVAR(getpeername_doc, +"getpeername() -> address info\n\ +\n\ +Return the address of the remote endpoint. For IP sockets, the address\n\ +info is a pair (hostaddr, port)."); + +#endif /* HAVE_GETPEERNAME */ + + +/* s.listen(n) method */ + +static PyObject * +sock_listen(PySocketSockObject *s, PyObject *args) +{ + /* We try to choose a default backlog high enough to avoid connection drops + * for common workloads, yet not too high to limit resource usage. */ + int backlog = Py_MIN(SOMAXCONN, 128); + int res; + + if (!PyArg_ParseTuple(args, "|i:listen", &backlog)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + /* To avoid problems on systems that don't allow a negative backlog + * (which doesn't make sense anyway) we force a minimum value of 0. */ + if (backlog < 0) + backlog = 0; + res = listen(s->sock_fd, backlog); + Py_END_ALLOW_THREADS + if (res < 0) + return s->errorhandler(); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(listen_doc, +"listen([backlog])\n\ +\n\ +Enable a server to accept connections. If backlog is specified, it must be\n\ +at least 0 (if it is lower, it is set to 0); it specifies the number of\n\ +unaccepted connections that the system will allow before refusing new\n\ +connections. If not specified, a default reasonable value is chosen."); + +struct sock_recv { + char *cbuf; + Py_ssize_t len; + int flags; + Py_ssize_t result; +}; + +static int +sock_recv_impl(PySocketSockObject *s, void *data) +{ + struct sock_recv *ctx = data; + +#ifdef MS_WINDOWS + if (ctx->len > INT_MAX) + ctx->len = INT_MAX; + ctx->result = recv(s->sock_fd, ctx->cbuf, (int)ctx->len, ctx->flags); +#else + ctx->result = recv(s->sock_fd, ctx->cbuf, ctx->len, ctx->flags); +#endif + return (ctx->result >= 0); +} + + +/* + * This is the guts of the recv() and recv_into() methods, which reads into a + * char buffer. If you have any inc/dec ref to do to the objects that contain + * the buffer, do it in the caller. This function returns the number of bytes + * successfully read. If there was an error, it returns -1. Note that it is + * also possible that we return a number of bytes smaller than the request + * bytes. + */ + +static Py_ssize_t +sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags) +{ + struct sock_recv ctx; + + if (!IS_SELECTABLE(s)) { + select_error(); + return -1; + } + if (len == 0) { + /* If 0 bytes were requested, do nothing. */ + return 0; + } + + ctx.cbuf = cbuf; + ctx.len = len; + ctx.flags = flags; + if (sock_call(s, 0, sock_recv_impl, &ctx) < 0) + return -1; + + return ctx.result; +} + + +/* s.recv(nbytes [,flags]) method */ + +static PyObject * +sock_recv(PySocketSockObject *s, PyObject *args) +{ + Py_ssize_t recvlen, outlen; + int flags = 0; + PyObject *buf; + + if (!PyArg_ParseTuple(args, "n|i:recv", &recvlen, &flags)) + return NULL; + + if (recvlen < 0) { + PyErr_SetString(PyExc_ValueError, + "negative buffersize in recv"); + return NULL; + } + + /* Allocate a new string. */ + buf = PyBytes_FromStringAndSize((char *) 0, recvlen); + if (buf == NULL) + return NULL; + + /* Call the guts */ + outlen = sock_recv_guts(s, PyBytes_AS_STRING(buf), recvlen, flags); + if (outlen < 0) { + /* An error occurred, release the string and return an + error. */ + Py_DECREF(buf); + return NULL; + } + if (outlen != recvlen) { + /* We did not read as many bytes as we anticipated, resize the + string if possible and be successful. */ + _PyBytes_Resize(&buf, outlen); + } + + return buf; +} + +PyDoc_STRVAR(recv_doc, +"recv(buffersize[, flags]) -> data\n\ +\n\ +Receive up to buffersize bytes from the socket. For the optional flags\n\ +argument, see the Unix manual. When no data is available, block until\n\ +at least one byte is available or until the remote end is closed. When\n\ +the remote end is closed and all data is read, return the empty string."); + + +/* s.recv_into(buffer, [nbytes [,flags]]) method */ + +static PyObject* +sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"buffer", "nbytes", "flags", 0}; + + int flags = 0; + Py_buffer pbuf; + char *buf; + Py_ssize_t buflen, readlen, recvlen = 0; + + /* Get the buffer's memory */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recv_into", kwlist, + &pbuf, &recvlen, &flags)) + return NULL; + buf = pbuf.buf; + buflen = pbuf.len; + + if (recvlen < 0) { + PyBuffer_Release(&pbuf); + PyErr_SetString(PyExc_ValueError, + "negative buffersize in recv_into"); + return NULL; + } + if (recvlen == 0) { + /* If nbytes was not specified, use the buffer's length */ + recvlen = buflen; + } + + /* Check if the buffer is large enough */ + if (buflen < recvlen) { + PyBuffer_Release(&pbuf); + PyErr_SetString(PyExc_ValueError, + "buffer too small for requested bytes"); + return NULL; + } + + /* Call the guts */ + readlen = sock_recv_guts(s, buf, recvlen, flags); + if (readlen < 0) { + /* Return an error. */ + PyBuffer_Release(&pbuf); + return NULL; + } + + PyBuffer_Release(&pbuf); + /* Return the number of bytes read. Note that we do not do anything + special here in the case that readlen < recvlen. */ + return PyLong_FromSsize_t(readlen); +} + +PyDoc_STRVAR(recv_into_doc, +"recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\ +\n\ +A version of recv() that stores its data into a buffer rather than creating\n\ +a new string. Receive up to buffersize bytes from the socket. If buffersize\n\ +is not specified (or 0), receive up to the size available in the given buffer.\n\ +\n\ +See recv() for documentation about the flags."); + +struct sock_recvfrom { + char* cbuf; + Py_ssize_t len; + int flags; + socklen_t *addrlen; + sock_addr_t *addrbuf; + Py_ssize_t result; +}; + +static int +sock_recvfrom_impl(PySocketSockObject *s, void *data) +{ + struct sock_recvfrom *ctx = data; + + memset(ctx->addrbuf, 0, *ctx->addrlen); + +#ifdef MS_WINDOWS + if (ctx->len > INT_MAX) + ctx->len = INT_MAX; + ctx->result = recvfrom(s->sock_fd, ctx->cbuf, (int)ctx->len, ctx->flags, + SAS2SA(ctx->addrbuf), ctx->addrlen); +#else + ctx->result = recvfrom(s->sock_fd, ctx->cbuf, ctx->len, ctx->flags, + SAS2SA(ctx->addrbuf), ctx->addrlen); +#endif + return (ctx->result >= 0); +} + + +/* + * This is the guts of the recvfrom() and recvfrom_into() methods, which reads + * into a char buffer. If you have any inc/def ref to do to the objects that + * contain the buffer, do it in the caller. This function returns the number + * of bytes successfully read. If there was an error, it returns -1. Note + * that it is also possible that we return a number of bytes smaller than the + * request bytes. + * + * 'addr' is a return value for the address object. Note that you must decref + * it yourself. + */ +static Py_ssize_t +sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags, + PyObject** addr) +{ + sock_addr_t addrbuf; + socklen_t addrlen; + struct sock_recvfrom ctx; + + *addr = NULL; + + if (!getsockaddrlen(s, &addrlen)) + return -1; + + if (!IS_SELECTABLE(s)) { + select_error(); + return -1; + } + + ctx.cbuf = cbuf; + ctx.len = len; + ctx.flags = flags; + ctx.addrbuf = &addrbuf; + ctx.addrlen = &addrlen; + if (sock_call(s, 0, sock_recvfrom_impl, &ctx) < 0) + return -1; + + *addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, + s->sock_proto); + if (*addr == NULL) + return -1; + + return ctx.result; +} + +/* s.recvfrom(nbytes [,flags]) method */ + +static PyObject * +sock_recvfrom(PySocketSockObject *s, PyObject *args) +{ + PyObject *buf = NULL; + PyObject *addr = NULL; + PyObject *ret = NULL; + int flags = 0; + Py_ssize_t recvlen, outlen; + + if (!PyArg_ParseTuple(args, "n|i:recvfrom", &recvlen, &flags)) + return NULL; + + if (recvlen < 0) { + PyErr_SetString(PyExc_ValueError, + "negative buffersize in recvfrom"); + return NULL; + } + + buf = PyBytes_FromStringAndSize((char *) 0, recvlen); + if (buf == NULL) + return NULL; + + outlen = sock_recvfrom_guts(s, PyBytes_AS_STRING(buf), + recvlen, flags, &addr); + if (outlen < 0) { + goto finally; + } + + if (outlen != recvlen) { + /* We did not read as many bytes as we anticipated, resize the + string if possible and be successful. */ + if (_PyBytes_Resize(&buf, outlen) < 0) + /* Oopsy, not so successful after all. */ + goto finally; + } + + ret = PyTuple_Pack(2, buf, addr); + +finally: + Py_XDECREF(buf); + Py_XDECREF(addr); + return ret; +} + +PyDoc_STRVAR(recvfrom_doc, +"recvfrom(buffersize[, flags]) -> (data, address info)\n\ +\n\ +Like recv(buffersize, flags) but also return the sender's address info."); + + +/* s.recvfrom_into(buffer[, nbytes [,flags]]) method */ + +static PyObject * +sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds) +{ + static char *kwlist[] = {"buffer", "nbytes", "flags", 0}; + + int flags = 0; + Py_buffer pbuf; + char *buf; + Py_ssize_t readlen, buflen, recvlen = 0; + + PyObject *addr = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recvfrom_into", + kwlist, &pbuf, + &recvlen, &flags)) + return NULL; + buf = pbuf.buf; + buflen = pbuf.len; + + if (recvlen < 0) { + PyBuffer_Release(&pbuf); + PyErr_SetString(PyExc_ValueError, + "negative buffersize in recvfrom_into"); + return NULL; + } + if (recvlen == 0) { + /* If nbytes was not specified, use the buffer's length */ + recvlen = buflen; + } else if (recvlen > buflen) { + PyBuffer_Release(&pbuf); + PyErr_SetString(PyExc_ValueError, + "nbytes is greater than the length of the buffer"); + return NULL; + } + + readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr); + if (readlen < 0) { + PyBuffer_Release(&pbuf); + /* Return an error */ + Py_XDECREF(addr); + return NULL; + } + + PyBuffer_Release(&pbuf); + /* Return the number of bytes read and the address. Note that we do + not do anything special here in the case that readlen < recvlen. */ + return Py_BuildValue("nN", readlen, addr); +} + +PyDoc_STRVAR(recvfrom_into_doc, +"recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\ +\n\ +Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info."); + +/* The sendmsg() and recvmsg[_into]() methods require a working + CMSG_LEN(). See the comment near get_CMSG_LEN(). */ +#ifdef CMSG_LEN +struct sock_recvmsg { + struct msghdr *msg; + int flags; + ssize_t result; +}; + +static int +sock_recvmsg_impl(PySocketSockObject *s, void *data) +{ + struct sock_recvmsg *ctx = data; + + ctx->result = recvmsg(s->sock_fd, ctx->msg, ctx->flags); + return (ctx->result >= 0); +} + +/* + * Call recvmsg() with the supplied iovec structures, flags, and + * ancillary data buffer size (controllen). Returns the tuple return + * value for recvmsg() or recvmsg_into(), with the first item provided + * by the supplied makeval() function. makeval() will be called with + * the length read and makeval_data as arguments, and must return a + * new reference (which will be decrefed if there is a subsequent + * error). On error, closes any file descriptors received via + * SCM_RIGHTS. + */ +static PyObject * +sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen, + int flags, Py_ssize_t controllen, + PyObject *(*makeval)(ssize_t, void *), void *makeval_data) +{ + sock_addr_t addrbuf; + socklen_t addrbuflen; + struct msghdr msg = {0}; + PyObject *cmsg_list = NULL, *retval = NULL; + void *controlbuf = NULL; + struct cmsghdr *cmsgh; + size_t cmsgdatalen = 0; + int cmsg_status; + struct sock_recvmsg ctx; + + /* XXX: POSIX says that msg_name and msg_namelen "shall be + ignored" when the socket is connected (Linux fills them in + anyway for AF_UNIX sockets at least). Normally msg_namelen + seems to be set to 0 if there's no address, but try to + initialize msg_name to something that won't be mistaken for a + real address if that doesn't happen. */ + if (!getsockaddrlen(s, &addrbuflen)) + return NULL; + memset(&addrbuf, 0, addrbuflen); + SAS2SA(&addrbuf)->sa_family = AF_UNSPEC; + + if (controllen < 0 || controllen > SOCKLEN_T_LIMIT) { + PyErr_SetString(PyExc_ValueError, + "invalid ancillary data buffer length"); + return NULL; + } + if (controllen > 0 && (controlbuf = PyMem_Malloc(controllen)) == NULL) + return PyErr_NoMemory(); + + /* Make the system call. */ + if (!IS_SELECTABLE(s)) { + select_error(); + goto finally; + } + + msg.msg_name = SAS2SA(&addrbuf); + msg.msg_namelen = addrbuflen; + msg.msg_iov = iov; + msg.msg_iovlen = iovlen; + msg.msg_control = controlbuf; + msg.msg_controllen = controllen; + + ctx.msg = &msg; + ctx.flags = flags; + if (sock_call(s, 0, sock_recvmsg_impl, &ctx) < 0) + goto finally; + + /* Make list of (level, type, data) tuples from control messages. */ + if ((cmsg_list = PyList_New(0)) == NULL) + goto err_closefds; + /* Check for empty ancillary data as old CMSG_FIRSTHDR() + implementations didn't do so. */ + for (cmsgh = ((msg.msg_controllen > 0) ? CMSG_FIRSTHDR(&msg) : NULL); + cmsgh != NULL; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { + PyObject *bytes, *tuple; + int tmp; + + cmsg_status = get_cmsg_data_len(&msg, cmsgh, &cmsgdatalen); + if (cmsg_status != 0) { + if (PyErr_WarnEx(PyExc_RuntimeWarning, + "received malformed or improperly-truncated " + "ancillary data", 1) == -1) + goto err_closefds; + } + if (cmsg_status < 0) + break; + if (cmsgdatalen > PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OSError, "control message too long"); + goto err_closefds; + } + + bytes = PyBytes_FromStringAndSize((char *)CMSG_DATA(cmsgh), + cmsgdatalen); + tuple = Py_BuildValue("iiN", (int)cmsgh->cmsg_level, + (int)cmsgh->cmsg_type, bytes); + if (tuple == NULL) + goto err_closefds; + tmp = PyList_Append(cmsg_list, tuple); + Py_DECREF(tuple); + if (tmp != 0) + goto err_closefds; + + if (cmsg_status != 0) + break; + } + + retval = Py_BuildValue("NOiN", + (*makeval)(ctx.result, makeval_data), + cmsg_list, + (int)msg.msg_flags, + makesockaddr(s->sock_fd, SAS2SA(&addrbuf), + ((msg.msg_namelen > addrbuflen) ? + addrbuflen : msg.msg_namelen), + s->sock_proto)); + if (retval == NULL) + goto err_closefds; + +finally: + Py_XDECREF(cmsg_list); + PyMem_Free(controlbuf); + return retval; + +err_closefds: +#ifdef SCM_RIGHTS + /* Close all descriptors coming from SCM_RIGHTS, so they don't leak. */ + for (cmsgh = ((msg.msg_controllen > 0) ? CMSG_FIRSTHDR(&msg) : NULL); + cmsgh != NULL; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { + cmsg_status = get_cmsg_data_len(&msg, cmsgh, &cmsgdatalen); + if (cmsg_status < 0) + break; + if (cmsgh->cmsg_level == SOL_SOCKET && + cmsgh->cmsg_type == SCM_RIGHTS) { + size_t numfds; + int *fdp; + + numfds = cmsgdatalen / sizeof(int); + fdp = (int *)CMSG_DATA(cmsgh); + while (numfds-- > 0) + close(*fdp++); + } + if (cmsg_status != 0) + break; + } +#endif /* SCM_RIGHTS */ + goto finally; +} + + +static PyObject * +makeval_recvmsg(ssize_t received, void *data) +{ + PyObject **buf = data; + + if (received < PyBytes_GET_SIZE(*buf)) + _PyBytes_Resize(buf, received); + Py_XINCREF(*buf); + return *buf; +} + +/* s.recvmsg(bufsize[, ancbufsize[, flags]]) method */ + +static PyObject * +sock_recvmsg(PySocketSockObject *s, PyObject *args) +{ + Py_ssize_t bufsize, ancbufsize = 0; + int flags = 0; + struct iovec iov; + PyObject *buf = NULL, *retval = NULL; + + if (!PyArg_ParseTuple(args, "n|ni:recvmsg", &bufsize, &ancbufsize, &flags)) + return NULL; + + if (bufsize < 0) { + PyErr_SetString(PyExc_ValueError, "negative buffer size in recvmsg()"); + return NULL; + } + if ((buf = PyBytes_FromStringAndSize(NULL, bufsize)) == NULL) + return NULL; + iov.iov_base = PyBytes_AS_STRING(buf); + iov.iov_len = bufsize; + + /* Note that we're passing a pointer to *our pointer* to the bytes + object here (&buf); makeval_recvmsg() may incref the object, or + deallocate it and set our pointer to NULL. */ + retval = sock_recvmsg_guts(s, &iov, 1, flags, ancbufsize, + &makeval_recvmsg, &buf); + Py_XDECREF(buf); + return retval; +} + +PyDoc_STRVAR(recvmsg_doc, +"recvmsg(bufsize[, ancbufsize[, flags]]) -> (data, ancdata, msg_flags, address)\n\ +\n\ +Receive normal data (up to bufsize bytes) and ancillary data from the\n\ +socket. The ancbufsize argument sets the size in bytes of the\n\ +internal buffer used to receive the ancillary data; it defaults to 0,\n\ +meaning that no ancillary data will be received. Appropriate buffer\n\ +sizes for ancillary data can be calculated using CMSG_SPACE() or\n\ +CMSG_LEN(), and items which do not fit into the buffer might be\n\ +truncated or discarded. The flags argument defaults to 0 and has the\n\ +same meaning as for recv().\n\ +\n\ +The return value is a 4-tuple: (data, ancdata, msg_flags, address).\n\ +The data item is a bytes object holding the non-ancillary data\n\ +received. The ancdata item is a list of zero or more tuples\n\ +(cmsg_level, cmsg_type, cmsg_data) representing the ancillary data\n\ +(control messages) received: cmsg_level and cmsg_type are integers\n\ +specifying the protocol level and protocol-specific type respectively,\n\ +and cmsg_data is a bytes object holding the associated data. The\n\ +msg_flags item is the bitwise OR of various flags indicating\n\ +conditions on the received message; see your system documentation for\n\ +details. If the receiving socket is unconnected, address is the\n\ +address of the sending socket, if available; otherwise, its value is\n\ +unspecified.\n\ +\n\ +If recvmsg() raises an exception after the system call returns, it\n\ +will first attempt to close any file descriptors received via the\n\ +SCM_RIGHTS mechanism."); + + +static PyObject * +makeval_recvmsg_into(ssize_t received, void *data) +{ + return PyLong_FromSsize_t(received); +} + +/* s.recvmsg_into(buffers[, ancbufsize[, flags]]) method */ + +static PyObject * +sock_recvmsg_into(PySocketSockObject *s, PyObject *args) +{ + Py_ssize_t ancbufsize = 0; + int flags = 0; + struct iovec *iovs = NULL; + Py_ssize_t i, nitems, nbufs = 0; + Py_buffer *bufs = NULL; + PyObject *buffers_arg, *fast, *retval = NULL; + + if (!PyArg_ParseTuple(args, "O|ni:recvmsg_into", + &buffers_arg, &ancbufsize, &flags)) + return NULL; + + if ((fast = PySequence_Fast(buffers_arg, + "recvmsg_into() argument 1 must be an " + "iterable")) == NULL) + return NULL; + nitems = PySequence_Fast_GET_SIZE(fast); + if (nitems > INT_MAX) { + PyErr_SetString(PyExc_OSError, "recvmsg_into() argument 1 is too long"); + goto finally; + } + + /* Fill in an iovec for each item, and save the Py_buffer + structs to release afterwards. */ + if (nitems > 0 && ((iovs = PyMem_New(struct iovec, nitems)) == NULL || + (bufs = PyMem_New(Py_buffer, nitems)) == NULL)) { + PyErr_NoMemory(); + goto finally; + } + for (; nbufs < nitems; nbufs++) { + if (!PyArg_Parse(PySequence_Fast_GET_ITEM(fast, nbufs), + "w*;recvmsg_into() argument 1 must be an iterable " + "of single-segment read-write buffers", + &bufs[nbufs])) + goto finally; + iovs[nbufs].iov_base = bufs[nbufs].buf; + iovs[nbufs].iov_len = bufs[nbufs].len; + } + + retval = sock_recvmsg_guts(s, iovs, nitems, flags, ancbufsize, + &makeval_recvmsg_into, NULL); +finally: + for (i = 0; i < nbufs; i++) + PyBuffer_Release(&bufs[i]); + PyMem_Free(bufs); + PyMem_Free(iovs); + Py_DECREF(fast); + return retval; +} + +PyDoc_STRVAR(recvmsg_into_doc, +"recvmsg_into(buffers[, ancbufsize[, flags]]) -> (nbytes, ancdata, msg_flags, address)\n\ +\n\ +Receive normal data and ancillary data from the socket, scattering the\n\ +non-ancillary data into a series of buffers. The buffers argument\n\ +must be an iterable of objects that export writable buffers\n\ +(e.g. bytearray objects); these will be filled with successive chunks\n\ +of the non-ancillary data until it has all been written or there are\n\ +no more buffers. The ancbufsize argument sets the size in bytes of\n\ +the internal buffer used to receive the ancillary data; it defaults to\n\ +0, meaning that no ancillary data will be received. Appropriate\n\ +buffer sizes for ancillary data can be calculated using CMSG_SPACE()\n\ +or CMSG_LEN(), and items which do not fit into the buffer might be\n\ +truncated or discarded. The flags argument defaults to 0 and has the\n\ +same meaning as for recv().\n\ +\n\ +The return value is a 4-tuple: (nbytes, ancdata, msg_flags, address).\n\ +The nbytes item is the total number of bytes of non-ancillary data\n\ +written into the buffers. The ancdata item is a list of zero or more\n\ +tuples (cmsg_level, cmsg_type, cmsg_data) representing the ancillary\n\ +data (control messages) received: cmsg_level and cmsg_type are\n\ +integers specifying the protocol level and protocol-specific type\n\ +respectively, and cmsg_data is a bytes object holding the associated\n\ +data. The msg_flags item is the bitwise OR of various flags\n\ +indicating conditions on the received message; see your system\n\ +documentation for details. If the receiving socket is unconnected,\n\ +address is the address of the sending socket, if available; otherwise,\n\ +its value is unspecified.\n\ +\n\ +If recvmsg_into() raises an exception after the system call returns,\n\ +it will first attempt to close any file descriptors received via the\n\ +SCM_RIGHTS mechanism."); +#endif /* CMSG_LEN */ + + +struct sock_send { + char *buf; + Py_ssize_t len; + int flags; + Py_ssize_t result; +}; + +static int +sock_send_impl(PySocketSockObject *s, void *data) +{ + struct sock_send *ctx = data; + +#ifdef MS_WINDOWS + if (ctx->len > INT_MAX) + ctx->len = INT_MAX; + ctx->result = send(s->sock_fd, ctx->buf, (int)ctx->len, ctx->flags); +#else + ctx->result = send(s->sock_fd, ctx->buf, ctx->len, ctx->flags); +#endif + return (ctx->result >= 0); +} + +/* s.send(data [,flags]) method */ + +static PyObject * +sock_send(PySocketSockObject *s, PyObject *args) +{ + int flags = 0; + Py_buffer pbuf; + struct sock_send ctx; + + if (!PyArg_ParseTuple(args, "y*|i:send", &pbuf, &flags)) + return NULL; + + if (!IS_SELECTABLE(s)) { + PyBuffer_Release(&pbuf); + return select_error(); + } + ctx.buf = pbuf.buf; + ctx.len = pbuf.len; + ctx.flags = flags; + if (sock_call(s, 1, sock_send_impl, &ctx) < 0) { + PyBuffer_Release(&pbuf); + return NULL; + } + PyBuffer_Release(&pbuf); + + return PyLong_FromSsize_t(ctx.result); +} + +PyDoc_STRVAR(send_doc, +"send(data[, flags]) -> count\n\ +\n\ +Send a data string to the socket. For the optional flags\n\ +argument, see the Unix manual. Return the number of bytes\n\ +sent; this may be less than len(data) if the network is busy."); + + +/* s.sendall(data [,flags]) method */ + +static PyObject * +sock_sendall(PySocketSockObject *s, PyObject *args) +{ + char *buf; + Py_ssize_t len, n; + int flags = 0; + Py_buffer pbuf; + struct sock_send ctx; + int has_timeout = (s->sock_timeout > 0); + _PyTime_t interval = s->sock_timeout; + _PyTime_t deadline = 0; + int deadline_initialized = 0; + PyObject *res = NULL; + + if (!PyArg_ParseTuple(args, "y*|i:sendall", &pbuf, &flags)) + return NULL; + buf = pbuf.buf; + len = pbuf.len; + + if (!IS_SELECTABLE(s)) { + PyBuffer_Release(&pbuf); + return select_error(); + } + + do { + if (has_timeout) { + if (deadline_initialized) { + /* recompute the timeout */ + interval = deadline - _PyTime_GetMonotonicClock(); + } + else { + deadline_initialized = 1; + deadline = _PyTime_GetMonotonicClock() + s->sock_timeout; + } + + if (interval <= 0) { + PyErr_SetString(socket_timeout, "timed out"); + goto done; + } + } + + ctx.buf = buf; + ctx.len = len; + ctx.flags = flags; + if (sock_call_ex(s, 1, sock_send_impl, &ctx, 0, NULL, interval) < 0) + goto done; + n = ctx.result; + assert(n >= 0); + + buf += n; + len -= n; + + /* We must run our signal handlers before looping again. + send() can return a successful partial write when it is + interrupted, so we can't restrict ourselves to EINTR. */ + if (PyErr_CheckSignals()) + goto done; + } while (len > 0); + PyBuffer_Release(&pbuf); + + Py_INCREF(Py_None); + res = Py_None; + +done: + PyBuffer_Release(&pbuf); + return res; +} + +PyDoc_STRVAR(sendall_doc, +"sendall(data[, flags])\n\ +\n\ +Send a data string to the socket. For the optional flags\n\ +argument, see the Unix manual. This calls send() repeatedly\n\ +until all data is sent. If an error occurs, it's impossible\n\ +to tell how much data has been sent."); + + +struct sock_sendto { + char *buf; + Py_ssize_t len; + int flags; + int addrlen; + sock_addr_t *addrbuf; + Py_ssize_t result; +}; + +static int +sock_sendto_impl(PySocketSockObject *s, void *data) +{ + struct sock_sendto *ctx = data; + +#ifdef MS_WINDOWS + if (ctx->len > INT_MAX) + ctx->len = INT_MAX; + ctx->result = sendto(s->sock_fd, ctx->buf, (int)ctx->len, ctx->flags, + SAS2SA(ctx->addrbuf), ctx->addrlen); +#else + ctx->result = sendto(s->sock_fd, ctx->buf, ctx->len, ctx->flags, + SAS2SA(ctx->addrbuf), ctx->addrlen); +#endif + return (ctx->result >= 0); +} + +/* s.sendto(data, [flags,] sockaddr) method */ + +static PyObject * +sock_sendto(PySocketSockObject *s, PyObject *args) +{ + Py_buffer pbuf; + PyObject *addro; + Py_ssize_t arglen; + sock_addr_t addrbuf; + int addrlen, flags; + struct sock_sendto ctx; + + flags = 0; + arglen = PyTuple_Size(args); + switch (arglen) { + case 2: + if (!PyArg_ParseTuple(args, "y*O:sendto", &pbuf, &addro)) { + return NULL; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "y*iO:sendto", + &pbuf, &flags, &addro)) { + return NULL; + } + break; + default: + PyErr_Format(PyExc_TypeError, + "sendto() takes 2 or 3 arguments (%zd given)", + arglen); + return NULL; + } + + if (!IS_SELECTABLE(s)) { + PyBuffer_Release(&pbuf); + return select_error(); + } + + if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "sendto")) { + PyBuffer_Release(&pbuf); + return NULL; + } + + if (PySys_Audit("socket.sendto", "OO", s, addro) < 0) { + return NULL; } -#endif -#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) - if (accept4_works != 0) { - ctx->result = accept4(s->sock_fd, addr, paddrlen, - SOCK_CLOEXEC); - if (ctx->result == INVALID_SOCKET && accept4_works == -1) { - /* On Linux older than 2.6.28, accept4() fails with ENOSYS */ - accept4_works = (errno != ENOSYS); + ctx.buf = pbuf.buf; + ctx.len = pbuf.len; + ctx.flags = flags; + ctx.addrlen = addrlen; + ctx.addrbuf = &addrbuf; + if (sock_call(s, 1, sock_sendto_impl, &ctx) < 0) { + PyBuffer_Release(&pbuf); + return NULL; + } + PyBuffer_Release(&pbuf); + + return PyLong_FromSsize_t(ctx.result); +} + +PyDoc_STRVAR(sendto_doc, +"sendto(data[, flags], address) -> count\n\ +\n\ +Like send(data, flags) but allows specifying the destination address.\n\ +For IP sockets, the address is a pair (hostaddr, port)."); + + +/* The sendmsg() and recvmsg[_into]() methods require a working + CMSG_LEN(). See the comment near get_CMSG_LEN(). */ +#ifdef CMSG_LEN +struct sock_sendmsg { + struct msghdr *msg; + int flags; + ssize_t result; +}; + +static int +sock_sendmsg_iovec(PySocketSockObject *s, PyObject *data_arg, + struct msghdr *msg, + Py_buffer **databufsout, Py_ssize_t *ndatabufsout) { + Py_ssize_t ndataparts, ndatabufs = 0; + int result = -1; + struct iovec *iovs = NULL; + PyObject *data_fast = NULL; + Py_buffer *databufs = NULL; + + /* Fill in an iovec for each message part, and save the Py_buffer + structs to release afterwards. */ + data_fast = PySequence_Fast(data_arg, + "sendmsg() argument 1 must be an " + "iterable"); + if (data_fast == NULL) { + goto finally; + } + + ndataparts = PySequence_Fast_GET_SIZE(data_fast); + if (ndataparts > INT_MAX) { + PyErr_SetString(PyExc_OSError, "sendmsg() argument 1 is too long"); + goto finally; + } + + msg->msg_iovlen = ndataparts; + if (ndataparts > 0) { + iovs = PyMem_New(struct iovec, ndataparts); + if (iovs == NULL) { + PyErr_NoMemory(); + goto finally; + } + msg->msg_iov = iovs; + + databufs = PyMem_New(Py_buffer, ndataparts); + if (databufs == NULL) { + PyErr_NoMemory(); + goto finally; + } + } + for (; ndatabufs < ndataparts; ndatabufs++) { + if (!PyArg_Parse(PySequence_Fast_GET_ITEM(data_fast, ndatabufs), + "y*;sendmsg() argument 1 must be an iterable of " + "bytes-like objects", + &databufs[ndatabufs])) + goto finally; + iovs[ndatabufs].iov_base = databufs[ndatabufs].buf; + iovs[ndatabufs].iov_len = databufs[ndatabufs].len; + } + result = 0; + finally: + *databufsout = databufs; + *ndatabufsout = ndatabufs; + Py_XDECREF(data_fast); + return result; +} + +static int +sock_sendmsg_impl(PySocketSockObject *s, void *data) +{ + struct sock_sendmsg *ctx = data; + + ctx->result = sendmsg(s->sock_fd, ctx->msg, ctx->flags); + return (ctx->result >= 0); +} + +/* s.sendmsg(buffers[, ancdata[, flags[, address]]]) method */ + +static PyObject * +sock_sendmsg(PySocketSockObject *s, PyObject *args) +{ + Py_ssize_t i, ndatabufs = 0, ncmsgs, ncmsgbufs = 0; + Py_buffer *databufs = NULL; + sock_addr_t addrbuf; + struct msghdr msg; + struct cmsginfo { + int level; + int type; + Py_buffer data; + } *cmsgs = NULL; + void *controlbuf = NULL; + size_t controllen, controllen_last; + int addrlen, flags = 0; + PyObject *data_arg, *cmsg_arg = NULL, *addr_arg = NULL, + *cmsg_fast = NULL, *retval = NULL; + struct sock_sendmsg ctx; + + if (!PyArg_ParseTuple(args, "O|OiO:sendmsg", + &data_arg, &cmsg_arg, &flags, &addr_arg)) { + return NULL; + } + + memset(&msg, 0, sizeof(msg)); + + /* Parse destination address. */ + if (addr_arg != NULL && addr_arg != Py_None) { + if (!getsockaddrarg(s, addr_arg, &addrbuf, &addrlen, + "sendmsg")) + { + goto finally; } - } - if (accept4_works == 0) - ctx->result = accept(s->sock_fd, addr, paddrlen); -#else - ctx->result = accept(s->sock_fd, addr, paddrlen); -#endif - -#ifdef MS_WINDOWS - return (ctx->result != INVALID_SOCKET); -#else - return (ctx->result >= 0); -#endif -} - -/* s._accept() -> (fd, address) */ - -static PyObject * -sock_accept(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) -{ - sock_addr_t addrbuf; - SOCKET_T newfd; - socklen_t addrlen; - PyObject *sock = NULL; - PyObject *addr = NULL; - PyObject *res = NULL; - struct sock_accept ctx; - - if (!getsockaddrlen(s, &addrlen)) - return NULL; - memset(&addrbuf, 0, addrlen); - - if (!IS_SELECTABLE(s)) - return select_error(); - - ctx.addrlen = &addrlen; - ctx.addrbuf = &addrbuf; - if (sock_call(s, 0, sock_accept_impl, &ctx) < 0) - return NULL; - newfd = ctx.result; - + if (PySys_Audit("socket.sendmsg", "OO", s, addr_arg) < 0) { + return NULL; + } + msg.msg_name = &addrbuf; + msg.msg_namelen = addrlen; + } else { + if (PySys_Audit("socket.sendmsg", "OO", s, Py_None) < 0) { + return NULL; + } + } + + /* Fill in an iovec for each message part, and save the Py_buffer + structs to release afterwards. */ + if (sock_sendmsg_iovec(s, data_arg, &msg, &databufs, &ndatabufs) == -1) { + goto finally; + } + + if (cmsg_arg == NULL) + ncmsgs = 0; + else { + if ((cmsg_fast = PySequence_Fast(cmsg_arg, + "sendmsg() argument 2 must be an " + "iterable")) == NULL) + goto finally; + ncmsgs = PySequence_Fast_GET_SIZE(cmsg_fast); + } + +#ifndef CMSG_SPACE + if (ncmsgs > 1) { + PyErr_SetString(PyExc_OSError, + "sending multiple control messages is not supported " + "on this system"); + goto finally; + } +#endif + /* Save level, type and Py_buffer for each control message, + and calculate total size. */ + if (ncmsgs > 0 && (cmsgs = PyMem_New(struct cmsginfo, ncmsgs)) == NULL) { + PyErr_NoMemory(); + goto finally; + } + controllen = controllen_last = 0; + while (ncmsgbufs < ncmsgs) { + size_t bufsize, space; + + if (!PyArg_Parse(PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs), + "(iiy*):[sendmsg() ancillary data items]", + &cmsgs[ncmsgbufs].level, + &cmsgs[ncmsgbufs].type, + &cmsgs[ncmsgbufs].data)) + goto finally; + bufsize = cmsgs[ncmsgbufs++].data.len; + +#ifdef CMSG_SPACE + if (!get_CMSG_SPACE(bufsize, &space)) { +#else + if (!get_CMSG_LEN(bufsize, &space)) { +#endif + PyErr_SetString(PyExc_OSError, "ancillary data item too large"); + goto finally; + } + controllen += space; + if (controllen > SOCKLEN_T_LIMIT || controllen < controllen_last) { + PyErr_SetString(PyExc_OSError, "too much ancillary data"); + goto finally; + } + controllen_last = controllen; + } + + /* Construct ancillary data block from control message info. */ + if (ncmsgbufs > 0) { + struct cmsghdr *cmsgh = NULL; + + controlbuf = PyMem_Malloc(controllen); + if (controlbuf == NULL) { + PyErr_NoMemory(); + goto finally; + } + msg.msg_control = controlbuf; + + msg.msg_controllen = controllen; + + /* Need to zero out the buffer as a workaround for glibc's + CMSG_NXTHDR() implementation. After getting the pointer to + the next header, it checks its (uninitialized) cmsg_len + member to see if the "message" fits in the buffer, and + returns NULL if it doesn't. Zero-filling the buffer + ensures that this doesn't happen. */ + memset(controlbuf, 0, controllen); + + for (i = 0; i < ncmsgbufs; i++) { + size_t msg_len, data_len = cmsgs[i].data.len; + int enough_space = 0; + + cmsgh = (i == 0) ? CMSG_FIRSTHDR(&msg) : CMSG_NXTHDR(&msg, cmsgh); + if (cmsgh == NULL) { + PyErr_Format(PyExc_RuntimeError, + "unexpected NULL result from %s()", + (i == 0) ? "CMSG_FIRSTHDR" : "CMSG_NXTHDR"); + goto finally; + } + if (!get_CMSG_LEN(data_len, &msg_len)) { + PyErr_SetString(PyExc_RuntimeError, + "item size out of range for CMSG_LEN()"); + goto finally; + } + if (cmsg_min_space(&msg, cmsgh, msg_len)) { + size_t space; + + cmsgh->cmsg_len = msg_len; + if (get_cmsg_data_space(&msg, cmsgh, &space)) + enough_space = (space >= data_len); + } + if (!enough_space) { + PyErr_SetString(PyExc_RuntimeError, + "ancillary data does not fit in calculated " + "space"); + goto finally; + } + cmsgh->cmsg_level = cmsgs[i].level; + cmsgh->cmsg_type = cmsgs[i].type; + memcpy(CMSG_DATA(cmsgh), cmsgs[i].data.buf, data_len); + } + } + + /* Make the system call. */ + if (!IS_SELECTABLE(s)) { + select_error(); + goto finally; + } + + ctx.msg = &msg; + ctx.flags = flags; + if (sock_call(s, 1, sock_sendmsg_impl, &ctx) < 0) + goto finally; + + retval = PyLong_FromSsize_t(ctx.result); + +finally: + PyMem_Free(controlbuf); + for (i = 0; i < ncmsgbufs; i++) + PyBuffer_Release(&cmsgs[i].data); + PyMem_Free(cmsgs); + Py_XDECREF(cmsg_fast); + PyMem_Free(msg.msg_iov); + for (i = 0; i < ndatabufs; i++) { + PyBuffer_Release(&databufs[i]); + } + PyMem_Free(databufs); + return retval; +} + +PyDoc_STRVAR(sendmsg_doc, +"sendmsg(buffers[, ancdata[, flags[, address]]]) -> count\n\ +\n\ +Send normal and ancillary data to the socket, gathering the\n\ +non-ancillary data from a series of buffers and concatenating it into\n\ +a single message. The buffers argument specifies the non-ancillary\n\ +data as an iterable of bytes-like objects (e.g. bytes objects).\n\ +The ancdata argument specifies the ancillary data (control messages)\n\ +as an iterable of zero or more tuples (cmsg_level, cmsg_type,\n\ +cmsg_data), where cmsg_level and cmsg_type are integers specifying the\n\ +protocol level and protocol-specific type respectively, and cmsg_data\n\ +is a bytes-like object holding the associated data. The flags\n\ +argument defaults to 0 and has the same meaning as for send(). If\n\ +address is supplied and not None, it sets a destination address for\n\ +the message. The return value is the number of bytes of non-ancillary\n\ +data sent."); +#endif /* CMSG_LEN */ + +#ifdef HAVE_SOCKADDR_ALG +static PyObject* +sock_sendmsg_afalg(PySocketSockObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *retval = NULL; + + Py_ssize_t i, ndatabufs = 0; + Py_buffer *databufs = NULL; + PyObject *data_arg = NULL; + + Py_buffer iv = {NULL, NULL}; + + PyObject *opobj = NULL; + int op = -1; + + PyObject *assoclenobj = NULL; + int assoclen = -1; + + unsigned int *uiptr; + int flags = 0; + + struct msghdr msg; + struct cmsghdr *header = NULL; + struct af_alg_iv *alg_iv = NULL; + struct sock_sendmsg ctx; + Py_ssize_t controllen; + void *controlbuf = NULL; + static char *keywords[] = {"msg", "op", "iv", "assoclen", "flags", 0}; + + if (self->sock_family != AF_ALG) { + PyErr_SetString(PyExc_OSError, + "algset is only supported for AF_ALG"); + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "|O$O!y*O!i:sendmsg_afalg", keywords, + &data_arg, + &PyLong_Type, &opobj, &iv, + &PyLong_Type, &assoclenobj, &flags)) { + return NULL; + } + + memset(&msg, 0, sizeof(msg)); + + /* op is a required, keyword-only argument >= 0 */ + if (opobj != NULL) { + op = _PyLong_AsInt(opobj); + } + if (op < 0) { + /* override exception from _PyLong_AsInt() */ + PyErr_SetString(PyExc_TypeError, + "Invalid or missing argument 'op'"); + goto finally; + } + /* assoclen is optional but must be >= 0 */ + if (assoclenobj != NULL) { + assoclen = _PyLong_AsInt(assoclenobj); + if (assoclen == -1 && PyErr_Occurred()) { + goto finally; + } + if (assoclen < 0) { + PyErr_SetString(PyExc_TypeError, + "assoclen must be positive"); + goto finally; + } + } + + controllen = CMSG_SPACE(4); + if (iv.buf != NULL) { + controllen += CMSG_SPACE(sizeof(*alg_iv) + iv.len); + } + if (assoclen >= 0) { + controllen += CMSG_SPACE(4); + } + + controlbuf = PyMem_Malloc(controllen); + if (controlbuf == NULL) { + PyErr_NoMemory(); + goto finally; + } + memset(controlbuf, 0, controllen); + + msg.msg_controllen = controllen; + msg.msg_control = controlbuf; + + /* Fill in an iovec for each message part, and save the Py_buffer + structs to release afterwards. */ + if (data_arg != NULL) { + if (sock_sendmsg_iovec(self, data_arg, &msg, &databufs, &ndatabufs) == -1) { + goto finally; + } + } + + /* set operation to encrypt or decrypt */ + header = CMSG_FIRSTHDR(&msg); + if (header == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "unexpected NULL result from CMSG_FIRSTHDR"); + goto finally; + } + header->cmsg_level = SOL_ALG; + header->cmsg_type = ALG_SET_OP; + header->cmsg_len = CMSG_LEN(4); + uiptr = (void*)CMSG_DATA(header); + *uiptr = (unsigned int)op; + + /* set initialization vector */ + if (iv.buf != NULL) { + header = CMSG_NXTHDR(&msg, header); + if (header == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "unexpected NULL result from CMSG_NXTHDR(iv)"); + goto finally; + } + header->cmsg_level = SOL_ALG; + header->cmsg_type = ALG_SET_IV; + header->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv.len); + alg_iv = (void*)CMSG_DATA(header); + alg_iv->ivlen = iv.len; + memcpy(alg_iv->iv, iv.buf, iv.len); + } + + /* set length of associated data for AEAD */ + if (assoclen >= 0) { + header = CMSG_NXTHDR(&msg, header); + if (header == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "unexpected NULL result from CMSG_NXTHDR(assoc)"); + goto finally; + } + header->cmsg_level = SOL_ALG; + header->cmsg_type = ALG_SET_AEAD_ASSOCLEN; + header->cmsg_len = CMSG_LEN(4); + uiptr = (void*)CMSG_DATA(header); + *uiptr = (unsigned int)assoclen; + } + + ctx.msg = &msg; + ctx.flags = flags; + if (sock_call(self, 1, sock_sendmsg_impl, &ctx) < 0) { + goto finally; + } + + retval = PyLong_FromSsize_t(ctx.result); + + finally: + PyMem_Free(controlbuf); + if (iv.buf != NULL) { + PyBuffer_Release(&iv); + } + PyMem_Free(msg.msg_iov); + for (i = 0; i < ndatabufs; i++) { + PyBuffer_Release(&databufs[i]); + } + PyMem_Free(databufs); + return retval; +} + +PyDoc_STRVAR(sendmsg_afalg_doc, +"sendmsg_afalg([msg], *, op[, iv[, assoclen[, flags=MSG_MORE]]])\n\ +\n\ +Set operation mode, IV and length of associated data for an AF_ALG\n\ +operation socket."); +#endif + +/* s.shutdown(how) method */ + +static PyObject * +sock_shutdown(PySocketSockObject *s, PyObject *arg) +{ + int how; + int res; + + how = _PyLong_AsInt(arg); + if (how == -1 && PyErr_Occurred()) + return NULL; + Py_BEGIN_ALLOW_THREADS + res = shutdown(s->sock_fd, how); + Py_END_ALLOW_THREADS + if (res < 0) + return s->errorhandler(); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(shutdown_doc, +"shutdown(flag)\n\ +\n\ +Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\ +of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR)."); + +#if defined(MS_WINDOWS) && defined(SIO_RCVALL) +static PyObject* +sock_ioctl(PySocketSockObject *s, PyObject *arg) +{ + unsigned long cmd = SIO_RCVALL; + PyObject *argO; + DWORD recv; + + if (!PyArg_ParseTuple(arg, "kO:ioctl", &cmd, &argO)) + return NULL; + + switch (cmd) { + case SIO_RCVALL: { + unsigned int option = RCVALL_ON; + if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) + return NULL; + if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), + NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { + return set_error(); + } + return PyLong_FromUnsignedLong(recv); } + case SIO_KEEPALIVE_VALS: { + struct tcp_keepalive ka; + if (!PyArg_ParseTuple(arg, "k(kkk):ioctl", &cmd, + &ka.onoff, &ka.keepalivetime, &ka.keepaliveinterval)) + return NULL; + if (WSAIoctl(s->sock_fd, cmd, &ka, sizeof(ka), + NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { + return set_error(); + } + return PyLong_FromUnsignedLong(recv); } +#if defined(SIO_LOOPBACK_FAST_PATH) + case SIO_LOOPBACK_FAST_PATH: { + unsigned int option; + if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) + return NULL; + if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), + NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { + return set_error(); + } + return PyLong_FromUnsignedLong(recv); } +#endif + default: + PyErr_Format(PyExc_ValueError, "invalid ioctl command %lu", cmd); + return NULL; + } +} +PyDoc_STRVAR(sock_ioctl_doc, +"ioctl(cmd, option) -> long\n\ +\n\ +Control the socket with WSAIoctl syscall. Currently supported 'cmd' values are\n\ +SIO_RCVALL: 'option' must be one of the socket.RCVALL_* constants.\n\ +SIO_KEEPALIVE_VALS: 'option' is a tuple of (onoff, timeout, interval).\n\ +SIO_LOOPBACK_FAST_PATH: 'option' is a boolean value, and is disabled by default"); +#endif + +#if defined(MS_WINDOWS) +static PyObject* +sock_share(PySocketSockObject *s, PyObject *arg) +{ + WSAPROTOCOL_INFOW info; + DWORD processId; + int result; + + if (!PyArg_ParseTuple(arg, "I", &processId)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + result = WSADuplicateSocketW(s->sock_fd, processId, &info); + Py_END_ALLOW_THREADS + if (result == SOCKET_ERROR) + return set_error(); + return PyBytes_FromStringAndSize((const char*)&info, sizeof(info)); +} +PyDoc_STRVAR(sock_share_doc, +"share(process_id) -> bytes\n\ +\n\ +Share the socket with another process. The target process id\n\ +must be provided and the resulting bytes object passed to the target\n\ +process. There the shared socket can be instantiated by calling\n\ +socket.fromshare()."); + + +#endif + +/* List of methods for socket objects */ + +static PyMethodDef sock_methods[] = { + {"_accept", (PyCFunction)sock_accept, METH_NOARGS, + accept_doc}, + {"bind", (PyCFunction)sock_bind, METH_O, + bind_doc}, + {"close", (PyCFunction)sock_close, METH_NOARGS, + sock_close_doc}, + {"connect", (PyCFunction)sock_connect, METH_O, + connect_doc}, + {"connect_ex", (PyCFunction)sock_connect_ex, METH_O, + connect_ex_doc}, + {"detach", (PyCFunction)sock_detach, METH_NOARGS, + detach_doc}, + {"fileno", (PyCFunction)sock_fileno, METH_NOARGS, + fileno_doc}, +#ifdef HAVE_GETPEERNAME + {"getpeername", (PyCFunction)sock_getpeername, + METH_NOARGS, getpeername_doc}, +#endif + {"getsockname", (PyCFunction)sock_getsockname, + METH_NOARGS, getsockname_doc}, + {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS, + getsockopt_doc}, +#if defined(MS_WINDOWS) && defined(SIO_RCVALL) + {"ioctl", (PyCFunction)sock_ioctl, METH_VARARGS, + sock_ioctl_doc}, +#endif +#if defined(MS_WINDOWS) + {"share", (PyCFunction)sock_share, METH_VARARGS, + sock_share_doc}, +#endif + {"listen", (PyCFunction)sock_listen, METH_VARARGS, + listen_doc}, + {"recv", (PyCFunction)sock_recv, METH_VARARGS, + recv_doc}, + {"recv_into", (PyCFunction)(void(*)(void))sock_recv_into, METH_VARARGS | METH_KEYWORDS, + recv_into_doc}, + {"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS, + recvfrom_doc}, + {"recvfrom_into", (PyCFunction)(void(*)(void))sock_recvfrom_into, METH_VARARGS | METH_KEYWORDS, + recvfrom_into_doc}, + {"send", (PyCFunction)sock_send, METH_VARARGS, + send_doc}, + {"sendall", (PyCFunction)sock_sendall, METH_VARARGS, + sendall_doc}, + {"sendto", (PyCFunction)sock_sendto, METH_VARARGS, + sendto_doc}, + {"setblocking", (PyCFunction)sock_setblocking, METH_O, + setblocking_doc}, + {"getblocking", (PyCFunction)sock_getblocking, METH_NOARGS, + getblocking_doc}, + {"settimeout", (PyCFunction)sock_settimeout, METH_O, + settimeout_doc}, + {"gettimeout", (PyCFunction)sock_gettimeout, METH_NOARGS, + gettimeout_doc}, + {"setsockopt", (PyCFunction)sock_setsockopt, METH_VARARGS, + setsockopt_doc}, + {"shutdown", (PyCFunction)sock_shutdown, METH_O, + shutdown_doc}, +#ifdef CMSG_LEN + {"recvmsg", (PyCFunction)sock_recvmsg, METH_VARARGS, + recvmsg_doc}, + {"recvmsg_into", (PyCFunction)sock_recvmsg_into, METH_VARARGS, + recvmsg_into_doc,}, + {"sendmsg", (PyCFunction)sock_sendmsg, METH_VARARGS, + sendmsg_doc}, +#endif +#ifdef HAVE_SOCKADDR_ALG + {"sendmsg_afalg", (PyCFunction)(void(*)(void))sock_sendmsg_afalg, METH_VARARGS | METH_KEYWORDS, + sendmsg_afalg_doc}, +#endif + {NULL, NULL} /* sentinel */ +}; + +/* SockObject members */ +static PyMemberDef sock_memberlist[] = { + {"family", T_INT, offsetof(PySocketSockObject, sock_family), READONLY, "the socket family"}, + {"type", T_INT, offsetof(PySocketSockObject, sock_type), READONLY, "the socket type"}, + {"proto", T_INT, offsetof(PySocketSockObject, sock_proto), READONLY, "the socket protocol"}, + {0}, +}; + +static PyGetSetDef sock_getsetlist[] = { + {"timeout", (getter)sock_gettimeout, NULL, PyDoc_STR("the socket timeout")}, + {NULL} /* sentinel */ +}; + +/* Deallocate a socket object in response to the last Py_DECREF(). + First close the file description. */ + +static void +sock_finalize(PySocketSockObject *s) +{ + SOCKET_T fd; + PyObject *error_type, *error_value, *error_traceback; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + if (s->sock_fd != INVALID_SOCKET) { + if (PyErr_ResourceWarning((PyObject *)s, 1, "unclosed %R", s)) { + /* Spurious errors can appear at shutdown */ + if (PyErr_ExceptionMatches(PyExc_Warning)) { + PyErr_WriteUnraisable((PyObject *)s); + } + } + + /* Only close the socket *after* logging the ResourceWarning warning + to allow the logger to call socket methods like + socket.getsockname(). If the socket is closed before, socket + methods fails with the EBADF error. */ + fd = s->sock_fd; + s->sock_fd = INVALID_SOCKET; + + /* We do not want to retry upon EINTR: see sock_close() */ + Py_BEGIN_ALLOW_THREADS + (void) SOCKETCLOSE(fd); + Py_END_ALLOW_THREADS + } + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +static void +sock_dealloc(PySocketSockObject *s) +{ + if (PyObject_CallFinalizerFromDealloc((PyObject *)s) < 0) + return; + + Py_TYPE(s)->tp_free((PyObject *)s); +} + + +static PyObject * +sock_repr(PySocketSockObject *s) +{ + long sock_fd; + /* On Windows, this test is needed because SOCKET_T is unsigned */ + if (s->sock_fd == INVALID_SOCKET) { + sock_fd = -1; + } +#if SIZEOF_SOCKET_T > SIZEOF_LONG + else if (s->sock_fd > LONG_MAX) { + /* this can occur on Win64, and actually there is a special + ugly printf formatter for decimal pointer length integer + printing, only bother if necessary*/ + PyErr_SetString(PyExc_OverflowError, + "no printf formatter to display " + "the socket descriptor in decimal"); + return NULL; + } +#endif + else + sock_fd = (long)s->sock_fd; + return PyUnicode_FromFormat( + "", + sock_fd, s->sock_family, + s->sock_type, + s->sock_proto); +} + + +/* Create a new, uninitialized socket object. */ + +static PyObject * +sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *new; + + new = type->tp_alloc(type, 0); + if (new != NULL) { + ((PySocketSockObject *)new)->sock_fd = INVALID_SOCKET; + ((PySocketSockObject *)new)->sock_timeout = _PyTime_FromSeconds(-1); + ((PySocketSockObject *)new)->errorhandler = &set_error; + } + return new; +} + + +/* Initialize a new socket object. */ + +#ifdef SOCK_CLOEXEC +/* socket() and socketpair() fail with EINVAL on Linux kernel older + * than 2.6.27 if SOCK_CLOEXEC flag is set in the socket type. */ +static int sock_cloexec_works = -1; +#endif + +/*ARGSUSED*/ +static int +sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) +{ + PySocketSockObject *s = (PySocketSockObject *)self; + PyObject *fdobj = NULL; + SOCKET_T fd = INVALID_SOCKET; + int family = -1, type = -1, proto = -1; + static char *keywords[] = {"family", "type", "proto", "fileno", 0}; +#ifndef MS_WINDOWS +#ifdef SOCK_CLOEXEC + int *atomic_flag_works = &sock_cloexec_works; +#else + int *atomic_flag_works = NULL; +#endif +#endif + + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "|iiiO:socket", keywords, + &family, &type, &proto, &fdobj)) + return -1; + #ifdef MS_WINDOWS - if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { - PyErr_SetFromWindowsErr(0); - SOCKETCLOSE(newfd); - goto finally; - } -#else - -#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) - if (!accept4_works) + /* In this case, we don't use the family, type and proto args */ + if (fdobj == NULL || fdobj == Py_None) #endif { - if (_Py_set_inheritable(newfd, 0, NULL) < 0) { - SOCKETCLOSE(newfd); - goto finally; + if (PySys_Audit("socket.__new__", "Oiii", + s, family, type, proto) < 0) { + return -1; } } -#endif - - sock = PyLong_FromSocket_t(newfd); - if (sock == NULL) { - SOCKETCLOSE(newfd); - goto finally; - } - - addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), - addrlen, s->sock_proto); - if (addr == NULL) - goto finally; - - res = PyTuple_Pack(2, sock, addr); - -finally: - Py_XDECREF(sock); - Py_XDECREF(addr); - return res; -} - -PyDoc_STRVAR(accept_doc, -"_accept() -> (integer, address info)\n\ -\n\ -Wait for an incoming connection. Return a new socket file descriptor\n\ -representing the connection, and the address of the client.\n\ -For IP sockets, the address info is a pair (hostaddr, port)."); - -/* s.setblocking(flag) method. Argument: - False -- non-blocking mode; same as settimeout(0) - True -- blocking mode; same as settimeout(None) -*/ - -static PyObject * -sock_setblocking(PySocketSockObject *s, PyObject *arg) -{ - long block; - - block = PyLong_AsLong(arg); - if (block == -1 && PyErr_Occurred()) - return NULL; - - s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); - if (internal_setblocking(s, block) == -1) { - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(setblocking_doc, -"setblocking(flag)\n\ -\n\ -Set the socket to blocking (flag is true) or non-blocking (false).\n\ -setblocking(True) is equivalent to settimeout(None);\n\ -setblocking(False) is equivalent to settimeout(0.0)."); - -/* s.getblocking() method. - Returns True if socket is in blocking mode, - False if it is in non-blocking mode. -*/ -static PyObject * -sock_getblocking(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) -{ - if (s->sock_timeout) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -PyDoc_STRVAR(getblocking_doc, -"getblocking()\n\ -\n\ -Returns True if socket is in blocking mode, or False if it\n\ -is in non-blocking mode."); -static int -socket_parse_timeout(_PyTime_t *timeout, PyObject *timeout_obj) -{ -#ifdef MS_WINDOWS - struct timeval tv; -#endif -#ifndef HAVE_POLL - _PyTime_t ms; -#endif - int overflow = 0; + if (fdobj != NULL && fdobj != Py_None) { +#ifdef MS_WINDOWS + /* recreate a socket that was duplicated */ + if (PyBytes_Check(fdobj)) { + WSAPROTOCOL_INFOW info; + if (PyBytes_GET_SIZE(fdobj) != sizeof(info)) { + PyErr_Format(PyExc_ValueError, + "socket descriptor string has wrong size, " + "should be %zu bytes.", sizeof(info)); + return -1; + } + memcpy(&info, PyBytes_AS_STRING(fdobj), sizeof(info)); - if (timeout_obj == Py_None) { - *timeout = _PyTime_FromSeconds(-1); - return 0; - } + if (PySys_Audit("socket.__new__", "Oiii", s, + info.iAddressFamily, info.iSocketType, + info.iProtocol) < 0) { + return -1; + } - if (_PyTime_FromSecondsObject(timeout, - timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) - return -1; + Py_BEGIN_ALLOW_THREADS + fd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, &info, 0, WSA_FLAG_OVERLAPPED); + Py_END_ALLOW_THREADS + if (fd == INVALID_SOCKET) { + set_error(); + return -1; + } + family = info.iAddressFamily; + type = info.iSocketType; + proto = info.iProtocol; + } + else +#endif + { - if (*timeout < 0) { - PyErr_SetString(PyExc_ValueError, "Timeout value out of range"); - return -1; - } + if (PyFloat_Check(fdobj)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float"); + return -1; + } + fd = PyLong_AsSocket_t(fdobj); + if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) + return -1; #ifdef MS_WINDOWS - overflow |= (_PyTime_AsTimeval(*timeout, &tv, _PyTime_ROUND_TIMEOUT) < 0); -#endif -#ifndef HAVE_POLL - ms = _PyTime_AsMilliseconds(*timeout, _PyTime_ROUND_TIMEOUT); - overflow |= (ms > INT_MAX); + if (fd == INVALID_SOCKET) { +#else + if (fd < 0) { #endif - if (overflow) { - PyErr_SetString(PyExc_OverflowError, - "timeout doesn't fit into C timeval"); - return -1; - } - - return 0; -} - -/* s.settimeout(timeout) method. Argument: - None -- no timeout, blocking mode; same as setblocking(True) - 0.0 -- non-blocking mode; same as setblocking(False) - > 0 -- timeout mode; operations time out after timeout seconds - < 0 -- illegal; raises an exception -*/ -static PyObject * -sock_settimeout(PySocketSockObject *s, PyObject *arg) -{ - _PyTime_t timeout; - - if (socket_parse_timeout(&timeout, arg) < 0) + PyErr_SetString(PyExc_ValueError, "negative file descriptor"); + return -1; + } + + /* validate that passed file descriptor is valid and a socket. */ + sock_addr_t addrbuf; + socklen_t addrlen = sizeof(sock_addr_t); + + memset(&addrbuf, 0, addrlen); + if (getsockname(fd, SAS2SA(&addrbuf), &addrlen) == 0) { + if (family == -1) { + family = SAS2SA(&addrbuf)->sa_family; + } + } else { +#ifdef MS_WINDOWS + /* getsockname() on an unbound socket is an error on Windows. + Invalid descriptor and not a socket is same error code. + Error out if family must be resolved, or bad descriptor. */ + if (family == -1 || CHECK_ERRNO(ENOTSOCK)) { +#else + /* getsockname() is not supported for SOL_ALG on Linux. */ + if (family == -1 || CHECK_ERRNO(EBADF) || CHECK_ERRNO(ENOTSOCK)) { +#endif + set_error(); + return -1; + } + } +#ifdef SO_TYPE + if (type == -1) { + int tmp; + socklen_t slen = sizeof(tmp); + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, + (void *)&tmp, &slen) == 0) + { + type = tmp; + } else { + set_error(); + return -1; + } + } +#else + type = SOCK_STREAM; +#endif +#ifdef SO_PROTOCOL + if (proto == -1) { + int tmp; + socklen_t slen = sizeof(tmp); + if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, + (void *)&tmp, &slen) == 0) + { + proto = tmp; + } else { + set_error(); + return -1; + } + } +#else + proto = 0; +#endif + } + } + else { + /* No fd, default to AF_INET and SOCK_STREAM */ + if (family == -1) { + family = AF_INET; + } + if (type == -1) { + type = SOCK_STREAM; + } + if (proto == -1) { + proto = 0; + } +#ifdef MS_WINDOWS + /* Windows implementation */ +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 +#endif + + Py_BEGIN_ALLOW_THREADS + if (support_wsa_no_inherit) { + fd = WSASocketW(family, type, proto, + NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + if (fd == INVALID_SOCKET) { + /* Windows 7 or Windows 2008 R2 without SP1 or the hotfix */ + support_wsa_no_inherit = 0; + fd = socket(family, type, proto); + } + } + else { + fd = socket(family, type, proto); + } + Py_END_ALLOW_THREADS + + if (fd == INVALID_SOCKET) { + set_error(); + return -1; + } + + if (!support_wsa_no_inherit) { + if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0)) { + closesocket(fd); + PyErr_SetFromWindowsErr(0); + return -1; + } + } +#else + /* UNIX */ + Py_BEGIN_ALLOW_THREADS +#ifdef SOCK_CLOEXEC + if (sock_cloexec_works != 0) { + fd = socket(family, type | SOCK_CLOEXEC, proto); + if (sock_cloexec_works == -1) { + if (fd >= 0) { + sock_cloexec_works = 1; + } + else if (errno == EINVAL) { + /* Linux older than 2.6.27 does not support SOCK_CLOEXEC */ + sock_cloexec_works = 0; + fd = socket(family, type, proto); + } + } + } + else +#endif + { + fd = socket(family, type, proto); + } + Py_END_ALLOW_THREADS + + if (fd == INVALID_SOCKET) { + set_error(); + return -1; + } + + if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { + SOCKETCLOSE(fd); + return -1; + } +#endif + } + if (init_sockobject(s, fd, family, type, proto) == -1) { + SOCKETCLOSE(fd); + return -1; + } + + return 0; + +} + + +/* Type object for socket objects. */ + +static PyTypeObject sock_type = { + PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ + "_socket.socket", /* tp_name */ + sizeof(PySocketSockObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)sock_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + (reprfunc)sock_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + sock_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + sock_methods, /* tp_methods */ + sock_memberlist, /* tp_members */ + sock_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + sock_initobj, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + sock_new, /* tp_new */ + PyObject_Del, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + 0, /* tp_version_tag */ + (destructor)sock_finalize, /* tp_finalize */ +}; + + +/* Python interface to gethostname(). */ + +/*ARGSUSED*/ +static PyObject * +socket_gethostname(PyObject *self, PyObject *unused) +{ + if (PySys_Audit("socket.gethostname", NULL) < 0) { return NULL; + } - s->sock_timeout = timeout; - - int block = timeout < 0; - /* Blocking mode for a Python socket object means that operations - like :meth:`recv` or :meth:`sendall` will block the execution of - the current thread until they are complete or aborted with a - `socket.timeout` or `socket.error` errors. When timeout is `None`, - the underlying FD is in a blocking mode. When timeout is a positive - number, the FD is in a non-blocking mode, and socket ops are - implemented with a `select()` call. - - When timeout is 0.0, the FD is in a non-blocking mode. - - This table summarizes all states in which the socket object and - its underlying FD can be: - - ==================== ===================== ============== - `gettimeout()` `getblocking()` FD - ==================== ===================== ============== - ``None`` ``True`` blocking - ``0.0`` ``False`` non-blocking - ``> 0`` ``True`` non-blocking - */ +#ifdef MS_WINDOWS + /* Don't use winsock's gethostname, as this returns the ANSI + version of the hostname, whereas we need a Unicode string. + Otherwise, gethostname apparently also returns the DNS name. */ + wchar_t buf[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD size = Py_ARRAY_LENGTH(buf); + wchar_t *name; + PyObject *result; + + if (GetComputerNameExW(ComputerNamePhysicalDnsHostname, buf, &size)) + return PyUnicode_FromWideChar(buf, size); + + if (GetLastError() != ERROR_MORE_DATA) + return PyErr_SetFromWindowsErr(0); + + if (size == 0) + return PyUnicode_New(0, 0); + + /* MSDN says ERROR_MORE_DATA may occur because DNS allows longer + names */ + name = PyMem_New(wchar_t, size); + if (!name) { + PyErr_NoMemory(); + return NULL; + } + if (!GetComputerNameExW(ComputerNamePhysicalDnsHostname, + name, + &size)) + { + PyMem_Free(name); + return PyErr_SetFromWindowsErr(0); + } + + result = PyUnicode_FromWideChar(name, size); + PyMem_Free(name); + return result; +#else + char buf[1024]; + int res; + Py_BEGIN_ALLOW_THREADS + res = gethostname(buf, (int) sizeof buf - 1); + Py_END_ALLOW_THREADS + if (res < 0) + return set_error(); + buf[sizeof buf - 1] = '\0'; + return PyUnicode_DecodeFSDefault(buf); +#endif +} + +PyDoc_STRVAR(gethostname_doc, +"gethostname() -> string\n\ +\n\ +Return the current host name."); + +#ifdef HAVE_SETHOSTNAME +PyDoc_STRVAR(sethostname_doc, +"sethostname(name)\n\n\ +Sets the hostname to name."); + +static PyObject * +socket_sethostname(PyObject *self, PyObject *args) +{ + PyObject *hnobj; + Py_buffer buf; + int res, flag = 0; + +#ifdef _AIX +/* issue #18259, not declared in any useful header file */ +extern int sethostname(const char *, size_t); +#endif + + if (!PyArg_ParseTuple(args, "S:sethostname", &hnobj)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "O&:sethostname", + PyUnicode_FSConverter, &hnobj)) + return NULL; + flag = 1; + } - if (internal_setblocking(s, block) == -1) { + if (PySys_Audit("socket.sethostname", "(O)", hnobj) < 0) { return NULL; } - Py_RETURN_NONE; -} -PyDoc_STRVAR(settimeout_doc, -"settimeout(timeout)\n\ -\n\ -Set a timeout on socket operations. 'timeout' can be a float,\n\ -giving in seconds, or None. Setting a timeout of None disables\n\ -the timeout feature and is equivalent to setblocking(1).\n\ -Setting a timeout of zero is the same as setblocking(0)."); - -/* s.gettimeout() method. - Returns the timeout associated with a socket. */ -static PyObject * -sock_gettimeout(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) -{ - if (s->sock_timeout < 0) { - Py_RETURN_NONE; - } - else { - double seconds = _PyTime_AsSecondsDouble(s->sock_timeout); - return PyFloat_FromDouble(seconds); + res = PyObject_GetBuffer(hnobj, &buf, PyBUF_SIMPLE); + if (!res) { + res = sethostname(buf.buf, buf.len); + PyBuffer_Release(&buf); + } + if (flag) + Py_DECREF(hnobj); + if (res) + return set_error(); + Py_RETURN_NONE; +} +#endif + +/* Python interface to gethostbyname(name). */ + +/*ARGSUSED*/ +static PyObject * +socket_gethostbyname(PyObject *self, PyObject *args) +{ + char *name; + struct sockaddr_in addrbuf; + PyObject *ret = NULL; + + if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name)) + return NULL; + if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { + goto finally; } -} - -PyDoc_STRVAR(gettimeout_doc, -"gettimeout() -> timeout\n\ -\n\ -Returns the timeout in seconds (float) associated with socket\n\ -operations. A timeout of None indicates that timeouts on socket\n\ -operations are disabled."); - -/* s.setsockopt() method. - With an integer third argument, sets an integer optval with optlen=4. - With None as third argument and an integer fourth argument, set - optval=NULL with unsigned int as optlen. - With a string third argument, sets an option from a buffer; - use optional built-in module 'struct' to encode the string. -*/ - -static PyObject * -sock_setsockopt(PySocketSockObject *s, PyObject *args) -{ - int level; - int optname; - int res; - Py_buffer optval; - int flag; - unsigned int optlen; - PyObject *none; - -#ifdef AF_VSOCK - if (s->sock_family == AF_VSOCK) { - uint64_t vflag; // Must be set width of 64 bits - /* setsockopt(level, opt, flag) */ - if (PyArg_ParseTuple(args, "iiK:setsockopt", - &level, &optname, &vflag)) { - // level should always be set to AF_VSOCK - res = setsockopt(s->sock_fd, level, optname, - (void*)&vflag, sizeof vflag); - goto done; - } - return NULL; + if (setipaddr(name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET) < 0) + goto finally; + ret = make_ipv4_addr(&addrbuf); +finally: + PyMem_Free(name); + return ret; +} + +PyDoc_STRVAR(gethostbyname_doc, +"gethostbyname(host) -> address\n\ +\n\ +Return the IP address (a string of the form '255.255.255.255') for a host."); + + +static PyObject* +sock_decode_hostname(const char *name) +{ +#ifdef MS_WINDOWS + /* Issue #26227: gethostbyaddr() returns a string encoded + * to the ANSI code page */ + return PyUnicode_DecodeMBCS(name, strlen(name), "surrogatepass"); +#else + /* Decode from UTF-8 */ + return PyUnicode_FromString(name); +#endif +} + +/* Convenience function common to gethostbyname_ex and gethostbyaddr */ + +static PyObject * +gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) +{ + char **pch; + PyObject *rtn_tuple = (PyObject *)NULL; + PyObject *name_list = (PyObject *)NULL; + PyObject *addr_list = (PyObject *)NULL; + PyObject *tmp; + PyObject *name; + + if (h == NULL) { + /* Let's get real error message to return */ + set_herror(h_errno); + return NULL; + } + + if (h->h_addrtype != af) { + /* Let's get real error message to return */ + errno = EAFNOSUPPORT; + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + switch (af) { + + case AF_INET: + if (alen < sizeof(struct sockaddr_in)) + return NULL; + break; + +#ifdef ENABLE_IPV6 + case AF_INET6: + if (alen < sizeof(struct sockaddr_in6)) + return NULL; + break; +#endif + + } + + if ((name_list = PyList_New(0)) == NULL) + goto err; + + if ((addr_list = PyList_New(0)) == NULL) + goto err; + + /* SF #1511317: h_aliases can be NULL */ + if (h->h_aliases) { + for (pch = h->h_aliases; *pch != NULL; pch++) { + int status; + tmp = PyUnicode_FromString(*pch); + if (tmp == NULL) + goto err; + + status = PyList_Append(name_list, tmp); + Py_DECREF(tmp); + + if (status) + goto err; + } + } + + for (pch = h->h_addr_list; *pch != NULL; pch++) { + int status; + + switch (af) { + + case AF_INET: + { + struct sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + sin.sin_family = af; +#ifdef HAVE_SOCKADDR_SA_LEN + sin.sin_len = sizeof(sin); +#endif + memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr)); + tmp = make_ipv4_addr(&sin); + + if (pch == h->h_addr_list && alen >= sizeof(sin)) + memcpy((char *) addr, &sin, sizeof(sin)); + break; + } + +#ifdef ENABLE_IPV6 + case AF_INET6: + { + struct sockaddr_in6 sin6; + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = af; +#ifdef HAVE_SOCKADDR_SA_LEN + sin6.sin6_len = sizeof(sin6); +#endif + memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr)); + tmp = make_ipv6_addr(&sin6); + + if (pch == h->h_addr_list && alen >= sizeof(sin6)) + memcpy((char *) addr, &sin6, sizeof(sin6)); + break; + } +#endif + + default: /* can't happen */ + PyErr_SetString(PyExc_OSError, + "unsupported address family"); + return NULL; + } + + if (tmp == NULL) + goto err; + + status = PyList_Append(addr_list, tmp); + Py_DECREF(tmp); + + if (status) + goto err; + } + + name = sock_decode_hostname(h->h_name); + if (name == NULL) + goto err; + rtn_tuple = Py_BuildValue("NOO", name, name_list, addr_list); + + err: + Py_XDECREF(name_list); + Py_XDECREF(addr_list); + return rtn_tuple; +} + + +/* Python interface to gethostbyname_ex(name). */ + +/*ARGSUSED*/ +static PyObject * +socket_gethostbyname_ex(PyObject *self, PyObject *args) +{ + char *name; + struct hostent *h; + sock_addr_t addr; + struct sockaddr *sa; + PyObject *ret = NULL; +#ifdef HAVE_GETHOSTBYNAME_R + struct hostent hp_allocated; +#ifdef HAVE_GETHOSTBYNAME_R_3_ARG + struct hostent_data data; +#else + char buf[16384]; + int buf_len = (sizeof buf) - 1; + int errnop; +#endif +#ifdef HAVE_GETHOSTBYNAME_R_3_ARG + int result; +#endif +#endif /* HAVE_GETHOSTBYNAME_R */ + + if (!PyArg_ParseTuple(args, "et:gethostbyname_ex", "idna", &name)) + return NULL; + if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { + goto finally; } -#endif - - /* setsockopt(level, opt, flag) */ - if (PyArg_ParseTuple(args, "iii:setsockopt", - &level, &optname, &flag)) { - res = setsockopt(s->sock_fd, level, optname, - (char*)&flag, sizeof flag); - goto done; + if (setipaddr(name, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) + goto finally; + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_GETHOSTBYNAME_R +#if defined(HAVE_GETHOSTBYNAME_R_6_ARG) + gethostbyname_r(name, &hp_allocated, buf, buf_len, + &h, &errnop); +#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG) + h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop); +#else /* HAVE_GETHOSTBYNAME_R_3_ARG */ + memset((void *) &data, '\0', sizeof(data)); + result = gethostbyname_r(name, &hp_allocated, &data); + h = (result != 0) ? NULL : &hp_allocated; +#endif +#else /* not HAVE_GETHOSTBYNAME_R */ +#ifdef USE_GETHOSTBYNAME_LOCK + PyThread_acquire_lock(netdb_lock, 1); +#endif + SUPPRESS_DEPRECATED_CALL + h = gethostbyname(name); +#endif /* HAVE_GETHOSTBYNAME_R */ + Py_END_ALLOW_THREADS + /* Some C libraries would require addr.__ss_family instead of + addr.ss_family. + Therefore, we cast the sockaddr_storage into sockaddr to + access sa_family. */ + sa = SAS2SA(&addr); + ret = gethost_common(h, SAS2SA(&addr), sizeof(addr), + sa->sa_family); +#ifdef USE_GETHOSTBYNAME_LOCK + PyThread_release_lock(netdb_lock); +#endif +finally: + PyMem_Free(name); + return ret; +} + +PyDoc_STRVAR(ghbn_ex_doc, +"gethostbyname_ex(host) -> (name, aliaslist, addresslist)\n\ +\n\ +Return the true host name, a list of aliases, and a list of IP addresses,\n\ +for a host. The host argument is a string giving a host name or IP number."); + + +/* Python interface to gethostbyaddr(IP). */ + +/*ARGSUSED*/ +static PyObject * +socket_gethostbyaddr(PyObject *self, PyObject *args) +{ + sock_addr_t addr; + struct sockaddr *sa = SAS2SA(&addr); + char *ip_num; + struct hostent *h; + PyObject *ret = NULL; +#ifdef HAVE_GETHOSTBYNAME_R + struct hostent hp_allocated; +#ifdef HAVE_GETHOSTBYNAME_R_3_ARG + struct hostent_data data; +#else + /* glibcs up to 2.10 assume that the buf argument to + gethostbyaddr_r is 8-byte aligned, which at least llvm-gcc + does not ensure. The attribute below instructs the compiler + to maintain this alignment. */ + char buf[16384] Py_ALIGNED(8); + int buf_len = (sizeof buf) - 1; + int errnop; +#endif +#ifdef HAVE_GETHOSTBYNAME_R_3_ARG + int result; +#endif +#endif /* HAVE_GETHOSTBYNAME_R */ + const char *ap; + int al; + int af; + + if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num)) + return NULL; + if (PySys_Audit("socket.gethostbyaddr", "O", args) < 0) { + goto finally; } + af = AF_UNSPEC; + if (setipaddr(ip_num, sa, sizeof(addr), af) < 0) + goto finally; + af = sa->sa_family; + ap = NULL; + /* al = 0; */ + switch (af) { + case AF_INET: + ap = (char *)&((struct sockaddr_in *)sa)->sin_addr; + al = sizeof(((struct sockaddr_in *)sa)->sin_addr); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + ap = (char *)&((struct sockaddr_in6 *)sa)->sin6_addr; + al = sizeof(((struct sockaddr_in6 *)sa)->sin6_addr); + break; +#endif + default: + PyErr_SetString(PyExc_OSError, "unsupported address family"); + goto finally; + } + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_GETHOSTBYNAME_R +#if defined(HAVE_GETHOSTBYNAME_R_6_ARG) + gethostbyaddr_r(ap, al, af, + &hp_allocated, buf, buf_len, + &h, &errnop); +#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG) + h = gethostbyaddr_r(ap, al, af, + &hp_allocated, buf, buf_len, &errnop); +#else /* HAVE_GETHOSTBYNAME_R_3_ARG */ + memset((void *) &data, '\0', sizeof(data)); + result = gethostbyaddr_r(ap, al, af, &hp_allocated, &data); + h = (result != 0) ? NULL : &hp_allocated; +#endif +#else /* not HAVE_GETHOSTBYNAME_R */ +#ifdef USE_GETHOSTBYNAME_LOCK + PyThread_acquire_lock(netdb_lock, 1); +#endif + SUPPRESS_DEPRECATED_CALL + h = gethostbyaddr(ap, al, af); +#endif /* HAVE_GETHOSTBYNAME_R */ + Py_END_ALLOW_THREADS + ret = gethost_common(h, SAS2SA(&addr), sizeof(addr), af); +#ifdef USE_GETHOSTBYNAME_LOCK + PyThread_release_lock(netdb_lock); +#endif +finally: + PyMem_Free(ip_num); + return ret; +} + +PyDoc_STRVAR(gethostbyaddr_doc, +"gethostbyaddr(host) -> (name, aliaslist, addresslist)\n\ +\n\ +Return the true host name, a list of aliases, and a list of IP addresses,\n\ +for a host. The host argument is a string giving a host name or IP number."); + + +/* Python interface to getservbyname(name). + This only returns the port number, since the other info is already + known or not useful (like the list of aliases). */ + +/*ARGSUSED*/ +static PyObject * +socket_getservbyname(PyObject *self, PyObject *args) +{ + const char *name, *proto=NULL; + struct servent *sp; + if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto)) + return NULL; - PyErr_Clear(); - /* setsockopt(level, opt, None, flag) */ - if (PyArg_ParseTuple(args, "iiO!I:setsockopt", - &level, &optname, Py_TYPE(Py_None), &none, &optlen)) { - assert(sizeof(socklen_t) >= sizeof(unsigned int)); - res = setsockopt(s->sock_fd, level, optname, - NULL, (socklen_t)optlen); - goto done; + if (PySys_Audit("socket.getservbyname", "ss", name, proto) < 0) { + return NULL; } - PyErr_Clear(); - /* setsockopt(level, opt, buffer) */ - if (!PyArg_ParseTuple(args, "iiy*:setsockopt", - &level, &optname, &optval)) - return NULL; + Py_BEGIN_ALLOW_THREADS + sp = getservbyname(name, proto); + Py_END_ALLOW_THREADS + if (sp == NULL) { + PyErr_SetString(PyExc_OSError, "service/proto not found"); + return NULL; + } + return PyLong_FromLong((long) ntohs(sp->s_port)); +} + +PyDoc_STRVAR(getservbyname_doc, +"getservbyname(servicename[, protocolname]) -> integer\n\ +\n\ +Return a port number from a service name and protocol name.\n\ +The optional protocol name, if given, should be 'tcp' or 'udp',\n\ +otherwise any protocol will match."); + + +/* Python interface to getservbyport(port). + This only returns the service name, since the other info is already + known or not useful (like the list of aliases). */ + +/*ARGSUSED*/ +static PyObject * +socket_getservbyport(PyObject *self, PyObject *args) +{ + int port; + const char *proto=NULL; + struct servent *sp; + if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto)) + return NULL; + if (port < 0 || port > 0xffff) { + PyErr_SetString( + PyExc_OverflowError, + "getservbyport: port must be 0-65535."); + return NULL; + } -#ifdef MS_WINDOWS - if (optval.len > INT_MAX) { - PyBuffer_Release(&optval); - PyErr_Format(PyExc_OverflowError, - "socket option is larger than %i bytes", - INT_MAX); + if (PySys_Audit("socket.getservbyport", "is", port, proto) < 0) { return NULL; } - res = setsockopt(s->sock_fd, level, optname, - optval.buf, (int)optval.len); -#else - res = setsockopt(s->sock_fd, level, optname, optval.buf, optval.len); -#endif - PyBuffer_Release(&optval); - -done: - if (res < 0) { - return s->errorhandler(); - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(setsockopt_doc, -"setsockopt(level, option, value: int)\n\ -setsockopt(level, option, value: buffer)\n\ -setsockopt(level, option, None, optlen: int)\n\ -\n\ -Set a socket option. See the Unix manual for level and option.\n\ -The value argument can either be an integer, a string buffer, or\n\ -None, optlen."); - - -/* s.getsockopt() method. - With two arguments, retrieves an integer option. - With a third integer argument, retrieves a string buffer of that size; - use optional built-in module 'struct' to decode the string. */ -static PyObject * -sock_getsockopt(PySocketSockObject *s, PyObject *args) -{ - int level; - int optname; - int res; - PyObject *buf; - socklen_t buflen = 0; - int flag = 0; - socklen_t flagsize; - - if (!PyArg_ParseTuple(args, "ii|i:getsockopt", - &level, &optname, &buflen)) - return NULL; + Py_BEGIN_ALLOW_THREADS + sp = getservbyport(htons((short)port), proto); + Py_END_ALLOW_THREADS + if (sp == NULL) { + PyErr_SetString(PyExc_OSError, "port/proto not found"); + return NULL; + } + return PyUnicode_FromString(sp->s_name); +} + +PyDoc_STRVAR(getservbyport_doc, +"getservbyport(port[, protocolname]) -> string\n\ +\n\ +Return the service name from a port number and protocol name.\n\ +The optional protocol name, if given, should be 'tcp' or 'udp',\n\ +otherwise any protocol will match."); + +/* Python interface to getprotobyname(name). + This only returns the protocol number, since the other info is + already known or not useful (like the list of aliases). */ + +/*ARGSUSED*/ +static PyObject * +socket_getprotobyname(PyObject *self, PyObject *args) +{ + const char *name; + struct protoent *sp; + if (!PyArg_ParseTuple(args, "s:getprotobyname", &name)) + return NULL; + Py_BEGIN_ALLOW_THREADS + sp = getprotobyname(name); + Py_END_ALLOW_THREADS + if (sp == NULL) { + PyErr_SetString(PyExc_OSError, "protocol not found"); + return NULL; + } + return PyLong_FromLong((long) sp->p_proto); +} + +PyDoc_STRVAR(getprotobyname_doc, +"getprotobyname(name) -> integer\n\ +\n\ +Return the protocol number for the named protocol. (Rarely used.)"); + +static PyObject * +socket_close(PyObject *self, PyObject *fdobj) +{ + SOCKET_T fd; + int res; + + fd = PyLong_AsSocket_t(fdobj); + if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) + return NULL; + Py_BEGIN_ALLOW_THREADS + res = SOCKETCLOSE(fd); + Py_END_ALLOW_THREADS + /* bpo-30319: The peer can already have closed the connection. + Python ignores ECONNRESET on close(). */ + if (res < 0 && !CHECK_ERRNO(ECONNRESET)) { + return set_error(); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(close_doc, +"close(integer) -> None\n\ +\n\ +Close an integer socket file descriptor. This is like os.close(), but for\n\ +sockets; on some platforms os.close() won't work for socket file descriptors."); + +#ifndef NO_DUP +/* dup() function for socket fds */ + +static PyObject * +socket_dup(PyObject *self, PyObject *fdobj) +{ + SOCKET_T fd, newfd; + PyObject *newfdobj; +#ifdef MS_WINDOWS + WSAPROTOCOL_INFOW info; +#endif + + fd = PyLong_AsSocket_t(fdobj); + if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) + return NULL; + +#ifdef MS_WINDOWS + if (WSADuplicateSocketW(fd, GetCurrentProcessId(), &info)) + return set_error(); + + newfd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + &info, 0, WSA_FLAG_OVERLAPPED); + if (newfd == INVALID_SOCKET) + return set_error(); + + if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { + closesocket(newfd); + PyErr_SetFromWindowsErr(0); + return NULL; + } +#else + /* On UNIX, dup can be used to duplicate the file descriptor of a socket */ + newfd = _Py_dup(fd); + if (newfd == INVALID_SOCKET) + return NULL; +#endif + + newfdobj = PyLong_FromSocket_t(newfd); + if (newfdobj == NULL) + SOCKETCLOSE(newfd); + return newfdobj; +} + +PyDoc_STRVAR(dup_doc, +"dup(integer) -> integer\n\ +\n\ +Duplicate an integer socket file descriptor. This is like os.dup(), but for\n\ +sockets; on some platforms os.dup() won't work for socket file descriptors."); +#endif + + +#ifdef HAVE_SOCKETPAIR +/* Create a pair of sockets using the socketpair() function. + Arguments as for socket() except the default family is AF_UNIX if + defined on the platform; otherwise, the default is AF_INET. */ + +/*ARGSUSED*/ +static PyObject * +socket_socketpair(PyObject *self, PyObject *args) +{ + PySocketSockObject *s0 = NULL, *s1 = NULL; + SOCKET_T sv[2]; + int family, type = SOCK_STREAM, proto = 0; + PyObject *res = NULL; +#ifdef SOCK_CLOEXEC + int *atomic_flag_works = &sock_cloexec_works; +#else + int *atomic_flag_works = NULL; +#endif + int ret; + +#if defined(AF_UNIX) + family = AF_UNIX; +#else + family = AF_INET; +#endif + if (!PyArg_ParseTuple(args, "|iii:socketpair", + &family, &type, &proto)) + return NULL; + + /* Create a pair of socket fds */ + Py_BEGIN_ALLOW_THREADS +#ifdef SOCK_CLOEXEC + if (sock_cloexec_works != 0) { + ret = socketpair(family, type | SOCK_CLOEXEC, proto, sv); + if (sock_cloexec_works == -1) { + if (ret >= 0) { + sock_cloexec_works = 1; + } + else if (errno == EINVAL) { + /* Linux older than 2.6.27 does not support SOCK_CLOEXEC */ + sock_cloexec_works = 0; + ret = socketpair(family, type, proto, sv); + } + } + } + else +#endif + { + ret = socketpair(family, type, proto, sv); + } + Py_END_ALLOW_THREADS + + if (ret < 0) + return set_error(); + + if (_Py_set_inheritable(sv[0], 0, atomic_flag_works) < 0) + goto finally; + if (_Py_set_inheritable(sv[1], 0, atomic_flag_works) < 0) + goto finally; + + s0 = new_sockobject(sv[0], family, type, proto); + if (s0 == NULL) + goto finally; + s1 = new_sockobject(sv[1], family, type, proto); + if (s1 == NULL) + goto finally; + res = PyTuple_Pack(2, s0, s1); + +finally: + if (res == NULL) { + if (s0 == NULL) + SOCKETCLOSE(sv[0]); + if (s1 == NULL) + SOCKETCLOSE(sv[1]); + } + Py_XDECREF(s0); + Py_XDECREF(s1); + return res; +} + +PyDoc_STRVAR(socketpair_doc, +"socketpair([family[, type [, proto]]]) -> (socket object, socket object)\n\ +\n\ +Create a pair of socket objects from the sockets returned by the platform\n\ +socketpair() function.\n\ +The arguments are the same as for socket() except the default family is\n\ +AF_UNIX if defined on the platform; otherwise, the default is AF_INET."); + +#endif /* HAVE_SOCKETPAIR */ + + +static PyObject * +socket_ntohs(PyObject *self, PyObject *args) +{ + int x; + + if (!PyArg_ParseTuple(args, "i:ntohs", &x)) { + return NULL; + } + if (x < 0) { + PyErr_SetString(PyExc_OverflowError, + "ntohs: can't convert negative Python int to C " + "16-bit unsigned integer"); + return NULL; + } + if (x > 0xffff) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "ntohs: Python int too large to convert to C " + "16-bit unsigned integer (The silent truncation " + "is deprecated)", + 1)) { + return NULL; + } + } + return PyLong_FromUnsignedLong(ntohs((unsigned short)x)); +} + +PyDoc_STRVAR(ntohs_doc, +"ntohs(integer) -> integer\n\ +\n\ +Convert a 16-bit unsigned integer from network to host byte order.\n\ +Note that in case the received integer does not fit in 16-bit unsigned\n\ +integer, but does fit in a positive C int, it is silently truncated to\n\ +16-bit unsigned integer.\n\ +However, this silent truncation feature is deprecated, and will raise an\n\ +exception in future versions of Python."); + + +static PyObject * +socket_ntohl(PyObject *self, PyObject *arg) +{ + unsigned long x; + + if (PyLong_Check(arg)) { + x = PyLong_AsUnsignedLong(arg); + if (x == (unsigned long) -1 && PyErr_Occurred()) + return NULL; +#if SIZEOF_LONG > 4 + { + unsigned long y; + /* only want the trailing 32 bits */ + y = x & 0xFFFFFFFFUL; + if (y ^ x) + return PyErr_Format(PyExc_OverflowError, + "int larger than 32 bits"); + x = y; + } +#endif + } + else + return PyErr_Format(PyExc_TypeError, + "expected int, %s found", + Py_TYPE(arg)->tp_name); + return PyLong_FromUnsignedLong(ntohl(x)); +} + +PyDoc_STRVAR(ntohl_doc, +"ntohl(integer) -> integer\n\ +\n\ +Convert a 32-bit integer from network to host byte order."); + + +static PyObject * +socket_htons(PyObject *self, PyObject *args) +{ + int x; + + if (!PyArg_ParseTuple(args, "i:htons", &x)) { + return NULL; + } + if (x < 0) { + PyErr_SetString(PyExc_OverflowError, + "htons: can't convert negative Python int to C " + "16-bit unsigned integer"); + return NULL; + } + if (x > 0xffff) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "htons: Python int too large to convert to C " + "16-bit unsigned integer (The silent truncation " + "is deprecated)", + 1)) { + return NULL; + } + } + return PyLong_FromUnsignedLong(htons((unsigned short)x)); +} + +PyDoc_STRVAR(htons_doc, +"htons(integer) -> integer\n\ +\n\ +Convert a 16-bit unsigned integer from host to network byte order.\n\ +Note that in case the received integer does not fit in 16-bit unsigned\n\ +integer, but does fit in a positive C int, it is silently truncated to\n\ +16-bit unsigned integer.\n\ +However, this silent truncation feature is deprecated, and will raise an\n\ +exception in future versions of Python."); + + +static PyObject * +socket_htonl(PyObject *self, PyObject *arg) +{ + unsigned long x; + + if (PyLong_Check(arg)) { + x = PyLong_AsUnsignedLong(arg); + if (x == (unsigned long) -1 && PyErr_Occurred()) + return NULL; +#if SIZEOF_LONG > 4 + { + unsigned long y; + /* only want the trailing 32 bits */ + y = x & 0xFFFFFFFFUL; + if (y ^ x) + return PyErr_Format(PyExc_OverflowError, + "int larger than 32 bits"); + x = y; + } +#endif + } + else + return PyErr_Format(PyExc_TypeError, + "expected int, %s found", + Py_TYPE(arg)->tp_name); + return PyLong_FromUnsignedLong(htonl((unsigned long)x)); +} + +PyDoc_STRVAR(htonl_doc, +"htonl(integer) -> integer\n\ +\n\ +Convert a 32-bit integer from host to network byte order."); + +/* socket.inet_aton() and socket.inet_ntoa() functions. */ + +PyDoc_STRVAR(inet_aton_doc, +"inet_aton(string) -> bytes giving packed 32-bit IP representation\n\ +\n\ +Convert an IP address in string format (123.45.67.89) to the 32-bit packed\n\ +binary format used in low-level network functions."); + +static PyObject* +socket_inet_aton(PyObject *self, PyObject *args) +{ +#ifdef HAVE_INET_ATON + struct in_addr buf; +#endif + +#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK) +#if (SIZEOF_INT != 4) +#error "Not sure if in_addr_t exists and int is not 32-bits." +#endif + /* Have to use inet_addr() instead */ + unsigned int packed_addr; +#endif + const char *ip_addr; + + if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr)) + return NULL; + + +#ifdef HAVE_INET_ATON + +#ifdef USE_INET_ATON_WEAKLINK + if (inet_aton != NULL) { +#endif + if (inet_aton(ip_addr, &buf)) + return PyBytes_FromStringAndSize((char *)(&buf), + sizeof(buf)); + + PyErr_SetString(PyExc_OSError, + "illegal IP address string passed to inet_aton"); + return NULL; + +#ifdef USE_INET_ATON_WEAKLINK + } else { +#endif + +#endif + +#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK) + + /* special-case this address as inet_addr might return INADDR_NONE + * for this */ + if (strcmp(ip_addr, "255.255.255.255") == 0) { + packed_addr = INADDR_BROADCAST; + } else { + + SUPPRESS_DEPRECATED_CALL + packed_addr = inet_addr(ip_addr); + + if (packed_addr == INADDR_NONE) { /* invalid address */ + PyErr_SetString(PyExc_OSError, + "illegal IP address string passed to inet_aton"); + return NULL; + } + } + return PyBytes_FromStringAndSize((char *) &packed_addr, + sizeof(packed_addr)); + +#ifdef USE_INET_ATON_WEAKLINK + } +#endif + +#endif +} + +PyDoc_STRVAR(inet_ntoa_doc, +"inet_ntoa(packed_ip) -> ip_address_string\n\ +\n\ +Convert an IP address from 32-bit packed binary format to string format"); + +static PyObject* +socket_inet_ntoa(PyObject *self, PyObject *args) +{ + Py_buffer packed_ip; + struct in_addr packed_addr; + + if (!PyArg_ParseTuple(args, "y*:inet_ntoa", &packed_ip)) { + return NULL; + } + + if (packed_ip.len != sizeof(packed_addr)) { + PyErr_SetString(PyExc_OSError, + "packed IP wrong length for inet_ntoa"); + PyBuffer_Release(&packed_ip); + return NULL; + } + + memcpy(&packed_addr, packed_ip.buf, packed_ip.len); + PyBuffer_Release(&packed_ip); + + SUPPRESS_DEPRECATED_CALL + return PyUnicode_FromString(inet_ntoa(packed_addr)); +} + +#ifdef HAVE_INET_PTON + +PyDoc_STRVAR(inet_pton_doc, +"inet_pton(af, ip) -> packed IP address string\n\ +\n\ +Convert an IP address from string format to a packed string suitable\n\ +for use with low-level network functions."); + +static PyObject * +socket_inet_pton(PyObject *self, PyObject *args) +{ + int af; + const char* ip; + int retval; +#ifdef ENABLE_IPV6 + char packed[Py_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))]; +#else + char packed[sizeof(struct in_addr)]; +#endif + if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) { + return NULL; + } + +#if !defined(ENABLE_IPV6) && defined(AF_INET6) + if(af == AF_INET6) { + PyErr_SetString(PyExc_OSError, + "can't use AF_INET6, IPv6 is disabled"); + return NULL; + } +#endif + + retval = inet_pton(af, ip, packed); + if (retval < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } else if (retval == 0) { + PyErr_SetString(PyExc_OSError, + "illegal IP address string passed to inet_pton"); + return NULL; + } else if (af == AF_INET) { + return PyBytes_FromStringAndSize(packed, + sizeof(struct in_addr)); +#ifdef ENABLE_IPV6 + } else if (af == AF_INET6) { + return PyBytes_FromStringAndSize(packed, + sizeof(struct in6_addr)); +#endif + } else { + PyErr_SetString(PyExc_OSError, "unknown address family"); + return NULL; + } +} + +PyDoc_STRVAR(inet_ntop_doc, +"inet_ntop(af, packed_ip) -> string formatted IP address\n\ +\n\ +Convert a packed IP address of the given family to string format."); + +static PyObject * +socket_inet_ntop(PyObject *self, PyObject *args) +{ + int af; + Py_buffer packed_ip; + const char* retval; +#ifdef ENABLE_IPV6 + char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; +#else + char ip[INET_ADDRSTRLEN]; +#endif + + if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) { + return NULL; + } + + if (af == AF_INET) { + if (packed_ip.len != sizeof(struct in_addr)) { + PyErr_SetString(PyExc_ValueError, + "invalid length of packed IP address string"); + PyBuffer_Release(&packed_ip); + return NULL; + } +#ifdef ENABLE_IPV6 + } else if (af == AF_INET6) { + if (packed_ip.len != sizeof(struct in6_addr)) { + PyErr_SetString(PyExc_ValueError, + "invalid length of packed IP address string"); + PyBuffer_Release(&packed_ip); + return NULL; + } +#endif + } else { + PyErr_Format(PyExc_ValueError, + "unknown address family %d", af); + PyBuffer_Release(&packed_ip); + return NULL; + } + + /* inet_ntop guarantee NUL-termination of resulting string. */ + retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip)); + PyBuffer_Release(&packed_ip); + if (!retval) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } else { + return PyUnicode_FromString(retval); + } +} + +#endif /* HAVE_INET_PTON */ + +/* Python interface to getaddrinfo(host, port). */ + +/*ARGSUSED*/ +static PyObject * +socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) +{ + static char* kwnames[] = {"host", "port", "family", "type", "proto", + "flags", 0}; + struct addrinfo hints, *res; + struct addrinfo *res0 = NULL; + PyObject *hobj = NULL; + PyObject *pobj = (PyObject *)NULL; + char pbuf[30]; + const char *hptr, *pptr; + int family, socktype, protocol, flags; + int error; + PyObject *all = (PyObject *)NULL; + PyObject *idna = NULL; + + socktype = protocol = flags = 0; + family = AF_UNSPEC; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo", + kwnames, &hobj, &pobj, &family, &socktype, + &protocol, &flags)) { + return NULL; + } + if (hobj == Py_None) { + hptr = NULL; + } else if (PyUnicode_Check(hobj)) { + idna = PyUnicode_AsEncodedString(hobj, "idna", NULL); + if (!idna) + return NULL; + assert(PyBytes_Check(idna)); + hptr = PyBytes_AS_STRING(idna); + } else if (PyBytes_Check(hobj)) { + hptr = PyBytes_AsString(hobj); + } else { + PyErr_SetString(PyExc_TypeError, + "getaddrinfo() argument 1 must be string or None"); + return NULL; + } + if (PyLong_CheckExact(pobj)) { + long value = PyLong_AsLong(pobj); + if (value == -1 && PyErr_Occurred()) + goto err; + PyOS_snprintf(pbuf, sizeof(pbuf), "%ld", value); + pptr = pbuf; + } else if (PyUnicode_Check(pobj)) { + pptr = PyUnicode_AsUTF8(pobj); + if (pptr == NULL) + goto err; + } else if (PyBytes_Check(pobj)) { + pptr = PyBytes_AS_STRING(pobj); + } else if (pobj == Py_None) { + pptr = (char *)NULL; + } else { + PyErr_SetString(PyExc_OSError, "Int or String expected"); + goto err; + } +#if defined(__APPLE__) && defined(AI_NUMERICSERV) + if ((flags & AI_NUMERICSERV) && (pptr == NULL || (pptr[0] == '0' && pptr[1] == 0))) { + /* On OSX up to at least OSX 10.8 getaddrinfo crashes + * if AI_NUMERICSERV is set and the servname is NULL or "0". + * This workaround avoids a segfault in libsystem. + */ + pptr = "00"; + } +#endif - if (buflen == 0) { -#ifdef AF_VSOCK - if (s->sock_family == AF_VSOCK) { - uint64_t vflag = 0; // Must be set width of 64 bits - flagsize = sizeof vflag; - res = getsockopt(s->sock_fd, level, optname, - (void *)&vflag, &flagsize); - if (res < 0) - return s->errorhandler(); - return PyLong_FromUnsignedLong(vflag); - } -#endif - flagsize = sizeof flag; - res = getsockopt(s->sock_fd, level, optname, - (void *)&flag, &flagsize); - if (res < 0) - return s->errorhandler(); - return PyLong_FromLong(flag); - } -#ifdef AF_VSOCK - if (s->sock_family == AF_VSOCK) { - PyErr_SetString(PyExc_OSError, - "getsockopt string buffer not allowed"); - return NULL; - } -#endif - if (buflen <= 0 || buflen > 1024) { - PyErr_SetString(PyExc_OSError, - "getsockopt buflen out of range"); - return NULL; - } - buf = PyBytes_FromStringAndSize((char *)NULL, buflen); - if (buf == NULL) + if (PySys_Audit("socket.getaddrinfo", "OOiii", + hobj, pobj, family, socktype, protocol) < 0) { return NULL; - res = getsockopt(s->sock_fd, level, optname, - (void *)PyBytes_AS_STRING(buf), &buflen); - if (res < 0) { - Py_DECREF(buf); - return s->errorhandler(); } - _PyBytes_Resize(&buf, buflen); - return buf; -} - -PyDoc_STRVAR(getsockopt_doc, -"getsockopt(level, option[, buffersize]) -> value\n\ -\n\ -Get a socket option. See the Unix manual for level and option.\n\ -If a nonzero buffersize argument is given, the return value is a\n\ -string of that length; otherwise it is an integer."); - -/* s.bind(sockaddr) method */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = socktype; + hints.ai_protocol = protocol; + hints.ai_flags = flags; + Py_BEGIN_ALLOW_THREADS + ACQUIRE_GETADDRINFO_LOCK + error = getaddrinfo(hptr, pptr, &hints, &res0); + Py_END_ALLOW_THREADS + RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ + if (error) { + set_gaierror(error); + goto err; + } + + all = PyList_New(0); + if (all == NULL) + goto err; + for (res = res0; res; res = res->ai_next) { + PyObject *single; + PyObject *addr = + makesockaddr(-1, res->ai_addr, res->ai_addrlen, protocol); + if (addr == NULL) + goto err; + single = Py_BuildValue("iiisO", res->ai_family, + res->ai_socktype, res->ai_protocol, + res->ai_canonname ? res->ai_canonname : "", + addr); + Py_DECREF(addr); + if (single == NULL) + goto err; + + if (PyList_Append(all, single)) { + Py_DECREF(single); + goto err; + } + Py_DECREF(single); + } + Py_XDECREF(idna); + if (res0) + freeaddrinfo(res0); + return all; + err: + Py_XDECREF(all); + Py_XDECREF(idna); + if (res0) + freeaddrinfo(res0); + return (PyObject *)NULL; +} + +PyDoc_STRVAR(getaddrinfo_doc, +"getaddrinfo(host, port [, family, type, proto, flags])\n\ + -> list of (family, type, proto, canonname, sockaddr)\n\ +\n\ +Resolve host and port into addrinfo struct."); + +/* Python interface to getnameinfo(sa, flags). */ + +/*ARGSUSED*/ +static PyObject * +socket_getnameinfo(PyObject *self, PyObject *args) +{ + PyObject *sa = (PyObject *)NULL; + int flags; + const char *hostp; + int port; + unsigned int flowinfo, scope_id; + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + struct addrinfo hints, *res = NULL; + int error; + PyObject *ret = (PyObject *)NULL; + PyObject *name; + + flags = flowinfo = scope_id = 0; + if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags)) + return NULL; + if (!PyTuple_Check(sa)) { + PyErr_SetString(PyExc_TypeError, + "getnameinfo() argument 1 must be a tuple"); + return NULL; + } + if (!PyArg_ParseTuple(sa, "si|II;getnameinfo(): illegal sockaddr argument", + &hostp, &port, &flowinfo, &scope_id)) + { + return NULL; + } + if (flowinfo > 0xfffff) { + PyErr_SetString(PyExc_OverflowError, + "getnameinfo(): flowinfo must be 0-1048575."); + return NULL; + } -static PyObject * -sock_bind(PySocketSockObject *s, PyObject *addro) -{ - sock_addr_t addrbuf; - int addrlen; - int res; - - if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "bind")) { + if (PySys_Audit("socket.getnameinfo", "(O)", sa) < 0) { return NULL; } - if (PySys_Audit("socket.bind", "OO", s, addro) < 0) { + PyOS_snprintf(pbuf, sizeof(pbuf), "%d", port); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; /* make numeric port happy */ + hints.ai_flags = AI_NUMERICHOST; /* don't do any name resolution */ + Py_BEGIN_ALLOW_THREADS + ACQUIRE_GETADDRINFO_LOCK + error = getaddrinfo(hostp, pbuf, &hints, &res); + Py_END_ALLOW_THREADS + RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ + if (error) { + set_gaierror(error); + goto fail; + } + if (res->ai_next) { + PyErr_SetString(PyExc_OSError, + "sockaddr resolved to multiple addresses"); + goto fail; + } + switch (res->ai_family) { + case AF_INET: + { + if (PyTuple_GET_SIZE(sa) != 2) { + PyErr_SetString(PyExc_OSError, + "IPv4 sockaddr must be 2 tuple"); + goto fail; + } + break; + } +#ifdef ENABLE_IPV6 + case AF_INET6: + { + struct sockaddr_in6 *sin6; + sin6 = (struct sockaddr_in6 *)res->ai_addr; + sin6->sin6_flowinfo = htonl(flowinfo); + sin6->sin6_scope_id = scope_id; + break; + } +#endif + } + error = getnameinfo(res->ai_addr, (socklen_t) res->ai_addrlen, + hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), flags); + if (error) { + set_gaierror(error); + goto fail; + } + + name = sock_decode_hostname(hbuf); + if (name == NULL) + goto fail; + ret = Py_BuildValue("Ns", name, pbuf); + +fail: + if (res) + freeaddrinfo(res); + return ret; +} + +PyDoc_STRVAR(getnameinfo_doc, +"getnameinfo(sockaddr, flags) --> (host, port)\n\ +\n\ +Get host and port for a sockaddr."); + + +/* Python API to getting and setting the default timeout value. */ + +static PyObject * +socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + if (defaulttimeout < 0) { + Py_RETURN_NONE; + } + else { + double seconds = _PyTime_AsSecondsDouble(defaulttimeout); + return PyFloat_FromDouble(seconds); + } +} + +PyDoc_STRVAR(getdefaulttimeout_doc, +"getdefaulttimeout() -> timeout\n\ +\n\ +Returns the default timeout in seconds (float) for new socket objects.\n\ +A value of None indicates that new socket objects have no timeout.\n\ +When the socket module is first imported, the default is None."); + +static PyObject * +socket_setdefaulttimeout(PyObject *self, PyObject *arg) +{ + _PyTime_t timeout; + + if (socket_parse_timeout(&timeout, arg) < 0) + return NULL; + + defaulttimeout = timeout; + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(setdefaulttimeout_doc, +"setdefaulttimeout(timeout)\n\ +\n\ +Set the default timeout in seconds (float) for new socket objects.\n\ +A value of None indicates that new socket objects have no timeout.\n\ +When the socket module is first imported, the default is None."); + +#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) +/* Python API for getting interface indices and names */ + +static PyObject * +socket_if_nameindex(PyObject *self, PyObject *arg) +{ + PyObject *list = PyList_New(0); + if (list == NULL) { return NULL; } - - Py_BEGIN_ALLOW_THREADS - res = bind(s->sock_fd, SAS2SA(&addrbuf), addrlen); - Py_END_ALLOW_THREADS - if (res < 0) - return s->errorhandler(); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(bind_doc, -"bind(address)\n\ -\n\ -Bind the socket to a local address. For IP sockets, the address is a\n\ -pair (host, port); the host must refer to the local host. For raw packet\n\ -sockets the address is a tuple (ifname, proto [,pkttype [,hatype [,addr]]])"); - - -/* s.close() method. - Set the file descriptor to -1 so operations tried subsequently - will surely fail. */ - -static PyObject * -sock_close(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) -{ - SOCKET_T fd; - int res; - - fd = s->sock_fd; - if (fd != INVALID_SOCKET) { - s->sock_fd = INVALID_SOCKET; - - /* We do not want to retry upon EINTR: see - http://lwn.net/Articles/576478/ and - http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html - for more details. */ - Py_BEGIN_ALLOW_THREADS - res = SOCKETCLOSE(fd); - Py_END_ALLOW_THREADS - /* bpo-30319: The peer can already have closed the connection. - Python ignores ECONNRESET on close(). */ - if (res < 0 && errno != ECONNRESET) { - return s->errorhandler(); - } +#ifdef MS_WINDOWS + PMIB_IF_TABLE2 tbl; + int ret; + if ((ret = GetIfTable2Ex(MibIfTableRaw, &tbl)) != NO_ERROR) { + Py_DECREF(list); + // ret is used instead of GetLastError() + return PyErr_SetFromWindowsErr(ret); } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(sock_close_doc, -"close()\n\ -\n\ -Close the socket. It cannot be used after this call."); - -static PyObject * -sock_detach(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) -{ - SOCKET_T fd = s->sock_fd; - s->sock_fd = INVALID_SOCKET; - return PyLong_FromSocket_t(fd); -} - -PyDoc_STRVAR(detach_doc, -"detach()\n\ -\n\ -Close the socket object without closing the underlying file descriptor.\n\ -The object cannot be used after this call, but the file descriptor\n\ -can be reused for other purposes. The file descriptor is returned."); - -static int -sock_connect_impl(PySocketSockObject *s, void* Py_UNUSED(data)) -{ - int err; - socklen_t size = sizeof err; - - if (getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR, (void *)&err, &size)) { - /* getsockopt() failed */ - return 0; - } - - if (err == EISCONN) - return 1; - if (err != 0) { - /* sock_call_ex() uses GET_SOCK_ERROR() to get the error code */ - SET_SOCK_ERROR(err); - return 0; - } - return 1; -} - -static int -internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen, - int raise) -{ - int res, err, wait_connect; - - Py_BEGIN_ALLOW_THREADS - res = connect(s->sock_fd, addr, addrlen); - Py_END_ALLOW_THREADS - - if (!res) { - /* connect() succeeded, the socket is connected */ - return 0; - } - - /* connect() failed */ - - /* save error, PyErr_CheckSignals() can replace it */ - err = GET_SOCK_ERROR; - if (CHECK_ERRNO(EINTR)) { - if (PyErr_CheckSignals()) - return -1; - - /* Issue #23618: when connect() fails with EINTR, the connection is - running asynchronously. - - If the socket is blocking or has a timeout, wait until the - connection completes, fails or timed out using select(), and then - get the connection status using getsockopt(SO_ERROR). - - If the socket is non-blocking, raise InterruptedError. The caller is - responsible to wait until the connection completes, fails or timed - out (it's the case in asyncio for example). */ - wait_connect = (s->sock_timeout != 0 && IS_SELECTABLE(s)); - } - else { - wait_connect = (s->sock_timeout > 0 && err == SOCK_INPROGRESS_ERR - && IS_SELECTABLE(s)); - } - - if (!wait_connect) { - if (raise) { - /* restore error, maybe replaced by PyErr_CheckSignals() */ - SET_SOCK_ERROR(err); - s->errorhandler(); - return -1; - } - else - return err; - } - - if (raise) { - /* socket.connect() raises an exception on error */ - if (sock_call_ex(s, 1, sock_connect_impl, NULL, - 1, NULL, s->sock_timeout) < 0) - return -1; - } - else { - /* socket.connect_ex() returns the error code on error */ - if (sock_call_ex(s, 1, sock_connect_impl, NULL, - 1, &err, s->sock_timeout) < 0) - return err; - } - return 0; -} - -/* s.connect(sockaddr) method */ - -static PyObject * -sock_connect(PySocketSockObject *s, PyObject *addro) -{ - sock_addr_t addrbuf; - int addrlen; - int res; - - if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "connect")) { - return NULL; - } - - if (PySys_Audit("socket.connect", "OO", s, addro) < 0) { - return NULL; - } - - res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 1); - if (res < 0) - return NULL; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(connect_doc, -"connect(address)\n\ -\n\ -Connect the socket to a remote address. For IP sockets, the address\n\ -is a pair (host, port)."); - - -/* s.connect_ex(sockaddr) method */ - -static PyObject * -sock_connect_ex(PySocketSockObject *s, PyObject *addro) -{ - sock_addr_t addrbuf; - int addrlen; - int res; - - if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "connect_ex")) { - return NULL; - } - - if (PySys_Audit("socket.connect", "OO", s, addro) < 0) { - return NULL; - } - - res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 0); - if (res < 0) - return NULL; - - return PyLong_FromLong((long) res); -} - -PyDoc_STRVAR(connect_ex_doc, -"connect_ex(address) -> errno\n\ -\n\ -This is like connect(address), but returns an error code (the errno value)\n\ -instead of raising an exception when an error occurs."); - - -/* s.fileno() method */ - -static PyObject * -sock_fileno(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) -{ - return PyLong_FromSocket_t(s->sock_fd); -} - -PyDoc_STRVAR(fileno_doc, -"fileno() -> integer\n\ -\n\ -Return the integer file descriptor of the socket."); - - -/* s.getsockname() method */ - -static PyObject * -sock_getsockname(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) -{ - sock_addr_t addrbuf; - int res; - socklen_t addrlen; - - if (!getsockaddrlen(s, &addrlen)) - return NULL; - memset(&addrbuf, 0, addrlen); - Py_BEGIN_ALLOW_THREADS - res = getsockname(s->sock_fd, SAS2SA(&addrbuf), &addrlen); - Py_END_ALLOW_THREADS - if (res < 0) - return s->errorhandler(); - return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, - s->sock_proto); -} - -PyDoc_STRVAR(getsockname_doc, -"getsockname() -> address info\n\ -\n\ -Return the address of the local endpoint. The format depends on the\n\ -address family. For IPv4 sockets, the address info is a pair\n\ -(hostaddr, port)."); - - -#ifdef HAVE_GETPEERNAME /* Cray APP doesn't have this :-( */ -/* s.getpeername() method */ - -static PyObject * -sock_getpeername(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) -{ - sock_addr_t addrbuf; - int res; - socklen_t addrlen; - - if (!getsockaddrlen(s, &addrlen)) - return NULL; - memset(&addrbuf, 0, addrlen); - Py_BEGIN_ALLOW_THREADS - res = getpeername(s->sock_fd, SAS2SA(&addrbuf), &addrlen); - Py_END_ALLOW_THREADS - if (res < 0) - return s->errorhandler(); - return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, - s->sock_proto); -} - -PyDoc_STRVAR(getpeername_doc, -"getpeername() -> address info\n\ -\n\ -Return the address of the remote endpoint. For IP sockets, the address\n\ -info is a pair (hostaddr, port)."); - -#endif /* HAVE_GETPEERNAME */ - - -/* s.listen(n) method */ - -static PyObject * -sock_listen(PySocketSockObject *s, PyObject *args) -{ - /* We try to choose a default backlog high enough to avoid connection drops - * for common workloads, yet not too high to limit resource usage. */ - int backlog = Py_MIN(SOMAXCONN, 128); - int res; - - if (!PyArg_ParseTuple(args, "|i:listen", &backlog)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - /* To avoid problems on systems that don't allow a negative backlog - * (which doesn't make sense anyway) we force a minimum value of 0. */ - if (backlog < 0) - backlog = 0; - res = listen(s->sock_fd, backlog); - Py_END_ALLOW_THREADS - if (res < 0) - return s->errorhandler(); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(listen_doc, -"listen([backlog])\n\ -\n\ -Enable a server to accept connections. If backlog is specified, it must be\n\ -at least 0 (if it is lower, it is set to 0); it specifies the number of\n\ -unaccepted connections that the system will allow before refusing new\n\ -connections. If not specified, a default reasonable value is chosen."); - -struct sock_recv { - char *cbuf; - Py_ssize_t len; - int flags; - Py_ssize_t result; -}; - -static int -sock_recv_impl(PySocketSockObject *s, void *data) -{ - struct sock_recv *ctx = data; - -#ifdef MS_WINDOWS - if (ctx->len > INT_MAX) - ctx->len = INT_MAX; - ctx->result = recv(s->sock_fd, ctx->cbuf, (int)ctx->len, ctx->flags); -#else - ctx->result = recv(s->sock_fd, ctx->cbuf, ctx->len, ctx->flags); -#endif - return (ctx->result >= 0); -} - - -/* - * This is the guts of the recv() and recv_into() methods, which reads into a - * char buffer. If you have any inc/dec ref to do to the objects that contain - * the buffer, do it in the caller. This function returns the number of bytes - * successfully read. If there was an error, it returns -1. Note that it is - * also possible that we return a number of bytes smaller than the request - * bytes. - */ - -static Py_ssize_t -sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags) -{ - struct sock_recv ctx; - - if (!IS_SELECTABLE(s)) { - select_error(); - return -1; - } - if (len == 0) { - /* If 0 bytes were requested, do nothing. */ - return 0; - } - - ctx.cbuf = cbuf; - ctx.len = len; - ctx.flags = flags; - if (sock_call(s, 0, sock_recv_impl, &ctx) < 0) - return -1; - - return ctx.result; -} - - -/* s.recv(nbytes [,flags]) method */ - -static PyObject * -sock_recv(PySocketSockObject *s, PyObject *args) -{ - Py_ssize_t recvlen, outlen; - int flags = 0; - PyObject *buf; - - if (!PyArg_ParseTuple(args, "n|i:recv", &recvlen, &flags)) - return NULL; - - if (recvlen < 0) { - PyErr_SetString(PyExc_ValueError, - "negative buffersize in recv"); - return NULL; - } - - /* Allocate a new string. */ - buf = PyBytes_FromStringAndSize((char *) 0, recvlen); - if (buf == NULL) - return NULL; - - /* Call the guts */ - outlen = sock_recv_guts(s, PyBytes_AS_STRING(buf), recvlen, flags); - if (outlen < 0) { - /* An error occurred, release the string and return an - error. */ - Py_DECREF(buf); - return NULL; - } - if (outlen != recvlen) { - /* We did not read as many bytes as we anticipated, resize the - string if possible and be successful. */ - _PyBytes_Resize(&buf, outlen); - } - - return buf; -} - -PyDoc_STRVAR(recv_doc, -"recv(buffersize[, flags]) -> data\n\ -\n\ -Receive up to buffersize bytes from the socket. For the optional flags\n\ -argument, see the Unix manual. When no data is available, block until\n\ -at least one byte is available or until the remote end is closed. When\n\ -the remote end is closed and all data is read, return the empty string."); - - -/* s.recv_into(buffer, [nbytes [,flags]]) method */ - -static PyObject* -sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"buffer", "nbytes", "flags", 0}; - - int flags = 0; - Py_buffer pbuf; - char *buf; - Py_ssize_t buflen, readlen, recvlen = 0; - - /* Get the buffer's memory */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recv_into", kwlist, - &pbuf, &recvlen, &flags)) - return NULL; - buf = pbuf.buf; - buflen = pbuf.len; - - if (recvlen < 0) { - PyBuffer_Release(&pbuf); - PyErr_SetString(PyExc_ValueError, - "negative buffersize in recv_into"); - return NULL; - } - if (recvlen == 0) { - /* If nbytes was not specified, use the buffer's length */ - recvlen = buflen; - } - - /* Check if the buffer is large enough */ - if (buflen < recvlen) { - PyBuffer_Release(&pbuf); - PyErr_SetString(PyExc_ValueError, - "buffer too small for requested bytes"); - return NULL; - } - - /* Call the guts */ - readlen = sock_recv_guts(s, buf, recvlen, flags); - if (readlen < 0) { - /* Return an error. */ - PyBuffer_Release(&pbuf); - return NULL; - } - - PyBuffer_Release(&pbuf); - /* Return the number of bytes read. Note that we do not do anything - special here in the case that readlen < recvlen. */ - return PyLong_FromSsize_t(readlen); -} - -PyDoc_STRVAR(recv_into_doc, -"recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\ -\n\ -A version of recv() that stores its data into a buffer rather than creating\n\ -a new string. Receive up to buffersize bytes from the socket. If buffersize\n\ -is not specified (or 0), receive up to the size available in the given buffer.\n\ -\n\ -See recv() for documentation about the flags."); - -struct sock_recvfrom { - char* cbuf; - Py_ssize_t len; - int flags; - socklen_t *addrlen; - sock_addr_t *addrbuf; - Py_ssize_t result; -}; - -static int -sock_recvfrom_impl(PySocketSockObject *s, void *data) -{ - struct sock_recvfrom *ctx = data; - - memset(ctx->addrbuf, 0, *ctx->addrlen); - -#ifdef MS_WINDOWS - if (ctx->len > INT_MAX) - ctx->len = INT_MAX; - ctx->result = recvfrom(s->sock_fd, ctx->cbuf, (int)ctx->len, ctx->flags, - SAS2SA(ctx->addrbuf), ctx->addrlen); -#else - ctx->result = recvfrom(s->sock_fd, ctx->cbuf, ctx->len, ctx->flags, - SAS2SA(ctx->addrbuf), ctx->addrlen); -#endif - return (ctx->result >= 0); -} - - -/* - * This is the guts of the recvfrom() and recvfrom_into() methods, which reads - * into a char buffer. If you have any inc/def ref to do to the objects that - * contain the buffer, do it in the caller. This function returns the number - * of bytes successfully read. If there was an error, it returns -1. Note - * that it is also possible that we return a number of bytes smaller than the - * request bytes. - * - * 'addr' is a return value for the address object. Note that you must decref - * it yourself. - */ -static Py_ssize_t -sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags, - PyObject** addr) -{ - sock_addr_t addrbuf; - socklen_t addrlen; - struct sock_recvfrom ctx; - - *addr = NULL; - - if (!getsockaddrlen(s, &addrlen)) - return -1; - - if (!IS_SELECTABLE(s)) { - select_error(); - return -1; - } - - ctx.cbuf = cbuf; - ctx.len = len; - ctx.flags = flags; - ctx.addrbuf = &addrbuf; - ctx.addrlen = &addrlen; - if (sock_call(s, 0, sock_recvfrom_impl, &ctx) < 0) - return -1; - - *addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, - s->sock_proto); - if (*addr == NULL) - return -1; - - return ctx.result; -} - -/* s.recvfrom(nbytes [,flags]) method */ - -static PyObject * -sock_recvfrom(PySocketSockObject *s, PyObject *args) -{ - PyObject *buf = NULL; - PyObject *addr = NULL; - PyObject *ret = NULL; - int flags = 0; - Py_ssize_t recvlen, outlen; - - if (!PyArg_ParseTuple(args, "n|i:recvfrom", &recvlen, &flags)) - return NULL; - - if (recvlen < 0) { - PyErr_SetString(PyExc_ValueError, - "negative buffersize in recvfrom"); - return NULL; - } - - buf = PyBytes_FromStringAndSize((char *) 0, recvlen); - if (buf == NULL) - return NULL; - - outlen = sock_recvfrom_guts(s, PyBytes_AS_STRING(buf), - recvlen, flags, &addr); - if (outlen < 0) { - goto finally; - } - - if (outlen != recvlen) { - /* We did not read as many bytes as we anticipated, resize the - string if possible and be successful. */ - if (_PyBytes_Resize(&buf, outlen) < 0) - /* Oopsy, not so successful after all. */ - goto finally; - } - - ret = PyTuple_Pack(2, buf, addr); - -finally: - Py_XDECREF(buf); - Py_XDECREF(addr); - return ret; -} - -PyDoc_STRVAR(recvfrom_doc, -"recvfrom(buffersize[, flags]) -> (data, address info)\n\ -\n\ -Like recv(buffersize, flags) but also return the sender's address info."); - - -/* s.recvfrom_into(buffer[, nbytes [,flags]]) method */ - -static PyObject * -sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds) -{ - static char *kwlist[] = {"buffer", "nbytes", "flags", 0}; - - int flags = 0; - Py_buffer pbuf; - char *buf; - Py_ssize_t readlen, buflen, recvlen = 0; - - PyObject *addr = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "w*|ni:recvfrom_into", - kwlist, &pbuf, - &recvlen, &flags)) - return NULL; - buf = pbuf.buf; - buflen = pbuf.len; - - if (recvlen < 0) { - PyBuffer_Release(&pbuf); - PyErr_SetString(PyExc_ValueError, - "negative buffersize in recvfrom_into"); - return NULL; - } - if (recvlen == 0) { - /* If nbytes was not specified, use the buffer's length */ - recvlen = buflen; - } else if (recvlen > buflen) { - PyBuffer_Release(&pbuf); - PyErr_SetString(PyExc_ValueError, - "nbytes is greater than the length of the buffer"); - return NULL; - } - - readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr); - if (readlen < 0) { - PyBuffer_Release(&pbuf); - /* Return an error */ - Py_XDECREF(addr); - return NULL; - } - - PyBuffer_Release(&pbuf); - /* Return the number of bytes read and the address. Note that we do - not do anything special here in the case that readlen < recvlen. */ - return Py_BuildValue("nN", readlen, addr); -} - -PyDoc_STRVAR(recvfrom_into_doc, -"recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\ -\n\ -Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info."); - -/* The sendmsg() and recvmsg[_into]() methods require a working - CMSG_LEN(). See the comment near get_CMSG_LEN(). */ -#ifdef CMSG_LEN -struct sock_recvmsg { - struct msghdr *msg; - int flags; - ssize_t result; -}; - -static int -sock_recvmsg_impl(PySocketSockObject *s, void *data) -{ - struct sock_recvmsg *ctx = data; - - ctx->result = recvmsg(s->sock_fd, ctx->msg, ctx->flags); - return (ctx->result >= 0); -} - -/* - * Call recvmsg() with the supplied iovec structures, flags, and - * ancillary data buffer size (controllen). Returns the tuple return - * value for recvmsg() or recvmsg_into(), with the first item provided - * by the supplied makeval() function. makeval() will be called with - * the length read and makeval_data as arguments, and must return a - * new reference (which will be decrefed if there is a subsequent - * error). On error, closes any file descriptors received via - * SCM_RIGHTS. - */ -static PyObject * -sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen, - int flags, Py_ssize_t controllen, - PyObject *(*makeval)(ssize_t, void *), void *makeval_data) -{ - sock_addr_t addrbuf; - socklen_t addrbuflen; - struct msghdr msg = {0}; - PyObject *cmsg_list = NULL, *retval = NULL; - void *controlbuf = NULL; - struct cmsghdr *cmsgh; - size_t cmsgdatalen = 0; - int cmsg_status; - struct sock_recvmsg ctx; - - /* XXX: POSIX says that msg_name and msg_namelen "shall be - ignored" when the socket is connected (Linux fills them in - anyway for AF_UNIX sockets at least). Normally msg_namelen - seems to be set to 0 if there's no address, but try to - initialize msg_name to something that won't be mistaken for a - real address if that doesn't happen. */ - if (!getsockaddrlen(s, &addrbuflen)) - return NULL; - memset(&addrbuf, 0, addrbuflen); - SAS2SA(&addrbuf)->sa_family = AF_UNSPEC; - - if (controllen < 0 || controllen > SOCKLEN_T_LIMIT) { - PyErr_SetString(PyExc_ValueError, - "invalid ancillary data buffer length"); - return NULL; - } - if (controllen > 0 && (controlbuf = PyMem_Malloc(controllen)) == NULL) - return PyErr_NoMemory(); - - /* Make the system call. */ - if (!IS_SELECTABLE(s)) { - select_error(); - goto finally; - } - - msg.msg_name = SAS2SA(&addrbuf); - msg.msg_namelen = addrbuflen; - msg.msg_iov = iov; - msg.msg_iovlen = iovlen; - msg.msg_control = controlbuf; - msg.msg_controllen = controllen; - - ctx.msg = &msg; - ctx.flags = flags; - if (sock_call(s, 0, sock_recvmsg_impl, &ctx) < 0) - goto finally; - - /* Make list of (level, type, data) tuples from control messages. */ - if ((cmsg_list = PyList_New(0)) == NULL) - goto err_closefds; - /* Check for empty ancillary data as old CMSG_FIRSTHDR() - implementations didn't do so. */ - for (cmsgh = ((msg.msg_controllen > 0) ? CMSG_FIRSTHDR(&msg) : NULL); - cmsgh != NULL; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { - PyObject *bytes, *tuple; - int tmp; - - cmsg_status = get_cmsg_data_len(&msg, cmsgh, &cmsgdatalen); - if (cmsg_status != 0) { - if (PyErr_WarnEx(PyExc_RuntimeWarning, - "received malformed or improperly-truncated " - "ancillary data", 1) == -1) - goto err_closefds; - } - if (cmsg_status < 0) - break; - if (cmsgdatalen > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OSError, "control message too long"); - goto err_closefds; - } - - bytes = PyBytes_FromStringAndSize((char *)CMSG_DATA(cmsgh), - cmsgdatalen); - tuple = Py_BuildValue("iiN", (int)cmsgh->cmsg_level, - (int)cmsgh->cmsg_type, bytes); - if (tuple == NULL) - goto err_closefds; - tmp = PyList_Append(cmsg_list, tuple); - Py_DECREF(tuple); - if (tmp != 0) - goto err_closefds; - - if (cmsg_status != 0) - break; - } - - retval = Py_BuildValue("NOiN", - (*makeval)(ctx.result, makeval_data), - cmsg_list, - (int)msg.msg_flags, - makesockaddr(s->sock_fd, SAS2SA(&addrbuf), - ((msg.msg_namelen > addrbuflen) ? - addrbuflen : msg.msg_namelen), - s->sock_proto)); - if (retval == NULL) - goto err_closefds; - -finally: - Py_XDECREF(cmsg_list); - PyMem_Free(controlbuf); - return retval; - -err_closefds: -#ifdef SCM_RIGHTS - /* Close all descriptors coming from SCM_RIGHTS, so they don't leak. */ - for (cmsgh = ((msg.msg_controllen > 0) ? CMSG_FIRSTHDR(&msg) : NULL); - cmsgh != NULL; cmsgh = CMSG_NXTHDR(&msg, cmsgh)) { - cmsg_status = get_cmsg_data_len(&msg, cmsgh, &cmsgdatalen); - if (cmsg_status < 0) - break; - if (cmsgh->cmsg_level == SOL_SOCKET && - cmsgh->cmsg_type == SCM_RIGHTS) { - size_t numfds; - int *fdp; - - numfds = cmsgdatalen / sizeof(int); - fdp = (int *)CMSG_DATA(cmsgh); - while (numfds-- > 0) - close(*fdp++); - } - if (cmsg_status != 0) - break; - } -#endif /* SCM_RIGHTS */ - goto finally; -} - - -static PyObject * -makeval_recvmsg(ssize_t received, void *data) -{ - PyObject **buf = data; - - if (received < PyBytes_GET_SIZE(*buf)) - _PyBytes_Resize(buf, received); - Py_XINCREF(*buf); - return *buf; -} - -/* s.recvmsg(bufsize[, ancbufsize[, flags]]) method */ - -static PyObject * -sock_recvmsg(PySocketSockObject *s, PyObject *args) -{ - Py_ssize_t bufsize, ancbufsize = 0; - int flags = 0; - struct iovec iov; - PyObject *buf = NULL, *retval = NULL; - - if (!PyArg_ParseTuple(args, "n|ni:recvmsg", &bufsize, &ancbufsize, &flags)) - return NULL; - - if (bufsize < 0) { - PyErr_SetString(PyExc_ValueError, "negative buffer size in recvmsg()"); - return NULL; - } - if ((buf = PyBytes_FromStringAndSize(NULL, bufsize)) == NULL) - return NULL; - iov.iov_base = PyBytes_AS_STRING(buf); - iov.iov_len = bufsize; - - /* Note that we're passing a pointer to *our pointer* to the bytes - object here (&buf); makeval_recvmsg() may incref the object, or - deallocate it and set our pointer to NULL. */ - retval = sock_recvmsg_guts(s, &iov, 1, flags, ancbufsize, - &makeval_recvmsg, &buf); - Py_XDECREF(buf); - return retval; -} - -PyDoc_STRVAR(recvmsg_doc, -"recvmsg(bufsize[, ancbufsize[, flags]]) -> (data, ancdata, msg_flags, address)\n\ -\n\ -Receive normal data (up to bufsize bytes) and ancillary data from the\n\ -socket. The ancbufsize argument sets the size in bytes of the\n\ -internal buffer used to receive the ancillary data; it defaults to 0,\n\ -meaning that no ancillary data will be received. Appropriate buffer\n\ -sizes for ancillary data can be calculated using CMSG_SPACE() or\n\ -CMSG_LEN(), and items which do not fit into the buffer might be\n\ -truncated or discarded. The flags argument defaults to 0 and has the\n\ -same meaning as for recv().\n\ -\n\ -The return value is a 4-tuple: (data, ancdata, msg_flags, address).\n\ -The data item is a bytes object holding the non-ancillary data\n\ -received. The ancdata item is a list of zero or more tuples\n\ -(cmsg_level, cmsg_type, cmsg_data) representing the ancillary data\n\ -(control messages) received: cmsg_level and cmsg_type are integers\n\ -specifying the protocol level and protocol-specific type respectively,\n\ -and cmsg_data is a bytes object holding the associated data. The\n\ -msg_flags item is the bitwise OR of various flags indicating\n\ -conditions on the received message; see your system documentation for\n\ -details. If the receiving socket is unconnected, address is the\n\ -address of the sending socket, if available; otherwise, its value is\n\ -unspecified.\n\ -\n\ -If recvmsg() raises an exception after the system call returns, it\n\ -will first attempt to close any file descriptors received via the\n\ -SCM_RIGHTS mechanism."); - - -static PyObject * -makeval_recvmsg_into(ssize_t received, void *data) -{ - return PyLong_FromSsize_t(received); -} - -/* s.recvmsg_into(buffers[, ancbufsize[, flags]]) method */ - -static PyObject * -sock_recvmsg_into(PySocketSockObject *s, PyObject *args) -{ - Py_ssize_t ancbufsize = 0; - int flags = 0; - struct iovec *iovs = NULL; - Py_ssize_t i, nitems, nbufs = 0; - Py_buffer *bufs = NULL; - PyObject *buffers_arg, *fast, *retval = NULL; - - if (!PyArg_ParseTuple(args, "O|ni:recvmsg_into", - &buffers_arg, &ancbufsize, &flags)) - return NULL; - - if ((fast = PySequence_Fast(buffers_arg, - "recvmsg_into() argument 1 must be an " - "iterable")) == NULL) - return NULL; - nitems = PySequence_Fast_GET_SIZE(fast); - if (nitems > INT_MAX) { - PyErr_SetString(PyExc_OSError, "recvmsg_into() argument 1 is too long"); - goto finally; - } - - /* Fill in an iovec for each item, and save the Py_buffer - structs to release afterwards. */ - if (nitems > 0 && ((iovs = PyMem_New(struct iovec, nitems)) == NULL || - (bufs = PyMem_New(Py_buffer, nitems)) == NULL)) { - PyErr_NoMemory(); - goto finally; - } - for (; nbufs < nitems; nbufs++) { - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(fast, nbufs), - "w*;recvmsg_into() argument 1 must be an iterable " - "of single-segment read-write buffers", - &bufs[nbufs])) - goto finally; - iovs[nbufs].iov_base = bufs[nbufs].buf; - iovs[nbufs].iov_len = bufs[nbufs].len; - } - - retval = sock_recvmsg_guts(s, iovs, nitems, flags, ancbufsize, - &makeval_recvmsg_into, NULL); -finally: - for (i = 0; i < nbufs; i++) - PyBuffer_Release(&bufs[i]); - PyMem_Free(bufs); - PyMem_Free(iovs); - Py_DECREF(fast); - return retval; -} - -PyDoc_STRVAR(recvmsg_into_doc, -"recvmsg_into(buffers[, ancbufsize[, flags]]) -> (nbytes, ancdata, msg_flags, address)\n\ -\n\ -Receive normal data and ancillary data from the socket, scattering the\n\ -non-ancillary data into a series of buffers. The buffers argument\n\ -must be an iterable of objects that export writable buffers\n\ -(e.g. bytearray objects); these will be filled with successive chunks\n\ -of the non-ancillary data until it has all been written or there are\n\ -no more buffers. The ancbufsize argument sets the size in bytes of\n\ -the internal buffer used to receive the ancillary data; it defaults to\n\ -0, meaning that no ancillary data will be received. Appropriate\n\ -buffer sizes for ancillary data can be calculated using CMSG_SPACE()\n\ -or CMSG_LEN(), and items which do not fit into the buffer might be\n\ -truncated or discarded. The flags argument defaults to 0 and has the\n\ -same meaning as for recv().\n\ -\n\ -The return value is a 4-tuple: (nbytes, ancdata, msg_flags, address).\n\ -The nbytes item is the total number of bytes of non-ancillary data\n\ -written into the buffers. The ancdata item is a list of zero or more\n\ -tuples (cmsg_level, cmsg_type, cmsg_data) representing the ancillary\n\ -data (control messages) received: cmsg_level and cmsg_type are\n\ -integers specifying the protocol level and protocol-specific type\n\ -respectively, and cmsg_data is a bytes object holding the associated\n\ -data. The msg_flags item is the bitwise OR of various flags\n\ -indicating conditions on the received message; see your system\n\ -documentation for details. If the receiving socket is unconnected,\n\ -address is the address of the sending socket, if available; otherwise,\n\ -its value is unspecified.\n\ -\n\ -If recvmsg_into() raises an exception after the system call returns,\n\ -it will first attempt to close any file descriptors received via the\n\ -SCM_RIGHTS mechanism."); -#endif /* CMSG_LEN */ - - -struct sock_send { - char *buf; - Py_ssize_t len; - int flags; - Py_ssize_t result; -}; - -static int -sock_send_impl(PySocketSockObject *s, void *data) -{ - struct sock_send *ctx = data; - -#ifdef MS_WINDOWS - if (ctx->len > INT_MAX) - ctx->len = INT_MAX; - ctx->result = send(s->sock_fd, ctx->buf, (int)ctx->len, ctx->flags); -#else - ctx->result = send(s->sock_fd, ctx->buf, ctx->len, ctx->flags); -#endif - return (ctx->result >= 0); -} - -/* s.send(data [,flags]) method */ - -static PyObject * -sock_send(PySocketSockObject *s, PyObject *args) -{ - int flags = 0; - Py_buffer pbuf; - struct sock_send ctx; - - if (!PyArg_ParseTuple(args, "y*|i:send", &pbuf, &flags)) - return NULL; - - if (!IS_SELECTABLE(s)) { - PyBuffer_Release(&pbuf); - return select_error(); - } - ctx.buf = pbuf.buf; - ctx.len = pbuf.len; - ctx.flags = flags; - if (sock_call(s, 1, sock_send_impl, &ctx) < 0) { - PyBuffer_Release(&pbuf); - return NULL; - } - PyBuffer_Release(&pbuf); - - return PyLong_FromSsize_t(ctx.result); -} - -PyDoc_STRVAR(send_doc, -"send(data[, flags]) -> count\n\ -\n\ -Send a data string to the socket. For the optional flags\n\ -argument, see the Unix manual. Return the number of bytes\n\ -sent; this may be less than len(data) if the network is busy."); - - -/* s.sendall(data [,flags]) method */ - -static PyObject * -sock_sendall(PySocketSockObject *s, PyObject *args) -{ - char *buf; - Py_ssize_t len, n; - int flags = 0; - Py_buffer pbuf; - struct sock_send ctx; - int has_timeout = (s->sock_timeout > 0); - _PyTime_t interval = s->sock_timeout; - _PyTime_t deadline = 0; - int deadline_initialized = 0; - PyObject *res = NULL; - - if (!PyArg_ParseTuple(args, "y*|i:sendall", &pbuf, &flags)) - return NULL; - buf = pbuf.buf; - len = pbuf.len; - - if (!IS_SELECTABLE(s)) { - PyBuffer_Release(&pbuf); - return select_error(); - } - - do { - if (has_timeout) { - if (deadline_initialized) { - /* recompute the timeout */ - interval = deadline - _PyTime_GetMonotonicClock(); - } - else { - deadline_initialized = 1; - deadline = _PyTime_GetMonotonicClock() + s->sock_timeout; - } - - if (interval <= 0) { - PyErr_SetString(socket_timeout, "timed out"); - goto done; - } - } - - ctx.buf = buf; - ctx.len = len; - ctx.flags = flags; - if (sock_call_ex(s, 1, sock_send_impl, &ctx, 0, NULL, interval) < 0) - goto done; - n = ctx.result; - assert(n >= 0); - - buf += n; - len -= n; - - /* We must run our signal handlers before looping again. - send() can return a successful partial write when it is - interrupted, so we can't restrict ourselves to EINTR. */ - if (PyErr_CheckSignals()) - goto done; - } while (len > 0); - PyBuffer_Release(&pbuf); - - Py_INCREF(Py_None); - res = Py_None; - -done: - PyBuffer_Release(&pbuf); - return res; -} - -PyDoc_STRVAR(sendall_doc, -"sendall(data[, flags])\n\ -\n\ -Send a data string to the socket. For the optional flags\n\ -argument, see the Unix manual. This calls send() repeatedly\n\ -until all data is sent. If an error occurs, it's impossible\n\ -to tell how much data has been sent."); - - -struct sock_sendto { - char *buf; - Py_ssize_t len; - int flags; - int addrlen; - sock_addr_t *addrbuf; - Py_ssize_t result; -}; - -static int -sock_sendto_impl(PySocketSockObject *s, void *data) -{ - struct sock_sendto *ctx = data; - -#ifdef MS_WINDOWS - if (ctx->len > INT_MAX) - ctx->len = INT_MAX; - ctx->result = sendto(s->sock_fd, ctx->buf, (int)ctx->len, ctx->flags, - SAS2SA(ctx->addrbuf), ctx->addrlen); -#else - ctx->result = sendto(s->sock_fd, ctx->buf, ctx->len, ctx->flags, - SAS2SA(ctx->addrbuf), ctx->addrlen); -#endif - return (ctx->result >= 0); -} - -/* s.sendto(data, [flags,] sockaddr) method */ - -static PyObject * -sock_sendto(PySocketSockObject *s, PyObject *args) -{ - Py_buffer pbuf; - PyObject *addro; - Py_ssize_t arglen; - sock_addr_t addrbuf; - int addrlen, flags; - struct sock_sendto ctx; - - flags = 0; - arglen = PyTuple_Size(args); - switch (arglen) { - case 2: - if (!PyArg_ParseTuple(args, "y*O:sendto", &pbuf, &addro)) { - return NULL; - } - break; - case 3: - if (!PyArg_ParseTuple(args, "y*iO:sendto", - &pbuf, &flags, &addro)) { - return NULL; - } - break; - default: - PyErr_Format(PyExc_TypeError, - "sendto() takes 2 or 3 arguments (%zd given)", - arglen); - return NULL; - } - - if (!IS_SELECTABLE(s)) { - PyBuffer_Release(&pbuf); - return select_error(); - } - - if (!getsockaddrarg(s, addro, &addrbuf, &addrlen, "sendto")) { - PyBuffer_Release(&pbuf); - return NULL; - } - - if (PySys_Audit("socket.sendto", "OO", s, addro) < 0) { - return NULL; - } - - ctx.buf = pbuf.buf; - ctx.len = pbuf.len; - ctx.flags = flags; - ctx.addrlen = addrlen; - ctx.addrbuf = &addrbuf; - if (sock_call(s, 1, sock_sendto_impl, &ctx) < 0) { - PyBuffer_Release(&pbuf); - return NULL; - } - PyBuffer_Release(&pbuf); - - return PyLong_FromSsize_t(ctx.result); -} - -PyDoc_STRVAR(sendto_doc, -"sendto(data[, flags], address) -> count\n\ -\n\ -Like send(data, flags) but allows specifying the destination address.\n\ -For IP sockets, the address is a pair (hostaddr, port)."); - - -/* The sendmsg() and recvmsg[_into]() methods require a working - CMSG_LEN(). See the comment near get_CMSG_LEN(). */ -#ifdef CMSG_LEN -struct sock_sendmsg { - struct msghdr *msg; - int flags; - ssize_t result; -}; - -static int -sock_sendmsg_iovec(PySocketSockObject *s, PyObject *data_arg, - struct msghdr *msg, - Py_buffer **databufsout, Py_ssize_t *ndatabufsout) { - Py_ssize_t ndataparts, ndatabufs = 0; - int result = -1; - struct iovec *iovs = NULL; - PyObject *data_fast = NULL; - Py_buffer *databufs = NULL; - - /* Fill in an iovec for each message part, and save the Py_buffer - structs to release afterwards. */ - data_fast = PySequence_Fast(data_arg, - "sendmsg() argument 1 must be an " - "iterable"); - if (data_fast == NULL) { - goto finally; - } - - ndataparts = PySequence_Fast_GET_SIZE(data_fast); - if (ndataparts > INT_MAX) { - PyErr_SetString(PyExc_OSError, "sendmsg() argument 1 is too long"); - goto finally; - } - - msg->msg_iovlen = ndataparts; - if (ndataparts > 0) { - iovs = PyMem_New(struct iovec, ndataparts); - if (iovs == NULL) { - PyErr_NoMemory(); - goto finally; - } - msg->msg_iov = iovs; - - databufs = PyMem_New(Py_buffer, ndataparts); - if (databufs == NULL) { - PyErr_NoMemory(); - goto finally; - } - } - for (; ndatabufs < ndataparts; ndatabufs++) { - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(data_fast, ndatabufs), - "y*;sendmsg() argument 1 must be an iterable of " - "bytes-like objects", - &databufs[ndatabufs])) - goto finally; - iovs[ndatabufs].iov_base = databufs[ndatabufs].buf; - iovs[ndatabufs].iov_len = databufs[ndatabufs].len; - } - result = 0; - finally: - *databufsout = databufs; - *ndatabufsout = ndatabufs; - Py_XDECREF(data_fast); - return result; -} - -static int -sock_sendmsg_impl(PySocketSockObject *s, void *data) -{ - struct sock_sendmsg *ctx = data; - - ctx->result = sendmsg(s->sock_fd, ctx->msg, ctx->flags); - return (ctx->result >= 0); -} - -/* s.sendmsg(buffers[, ancdata[, flags[, address]]]) method */ - -static PyObject * -sock_sendmsg(PySocketSockObject *s, PyObject *args) -{ - Py_ssize_t i, ndatabufs = 0, ncmsgs, ncmsgbufs = 0; - Py_buffer *databufs = NULL; - sock_addr_t addrbuf; - struct msghdr msg; - struct cmsginfo { - int level; - int type; - Py_buffer data; - } *cmsgs = NULL; - void *controlbuf = NULL; - size_t controllen, controllen_last; - int addrlen, flags = 0; - PyObject *data_arg, *cmsg_arg = NULL, *addr_arg = NULL, - *cmsg_fast = NULL, *retval = NULL; - struct sock_sendmsg ctx; - - if (!PyArg_ParseTuple(args, "O|OiO:sendmsg", - &data_arg, &cmsg_arg, &flags, &addr_arg)) { - return NULL; - } - - memset(&msg, 0, sizeof(msg)); - - /* Parse destination address. */ - if (addr_arg != NULL && addr_arg != Py_None) { - if (!getsockaddrarg(s, addr_arg, &addrbuf, &addrlen, - "sendmsg")) - { - goto finally; - } - if (PySys_Audit("socket.sendmsg", "OO", s, addr_arg) < 0) { - return NULL; - } - msg.msg_name = &addrbuf; - msg.msg_namelen = addrlen; - } else { - if (PySys_Audit("socket.sendmsg", "OO", s, Py_None) < 0) { - return NULL; - } - } - - /* Fill in an iovec for each message part, and save the Py_buffer - structs to release afterwards. */ - if (sock_sendmsg_iovec(s, data_arg, &msg, &databufs, &ndatabufs) == -1) { - goto finally; - } - - if (cmsg_arg == NULL) - ncmsgs = 0; - else { - if ((cmsg_fast = PySequence_Fast(cmsg_arg, - "sendmsg() argument 2 must be an " - "iterable")) == NULL) - goto finally; - ncmsgs = PySequence_Fast_GET_SIZE(cmsg_fast); - } - -#ifndef CMSG_SPACE - if (ncmsgs > 1) { - PyErr_SetString(PyExc_OSError, - "sending multiple control messages is not supported " - "on this system"); - goto finally; - } -#endif - /* Save level, type and Py_buffer for each control message, - and calculate total size. */ - if (ncmsgs > 0 && (cmsgs = PyMem_New(struct cmsginfo, ncmsgs)) == NULL) { - PyErr_NoMemory(); - goto finally; - } - controllen = controllen_last = 0; - while (ncmsgbufs < ncmsgs) { - size_t bufsize, space; - - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs), - "(iiy*):[sendmsg() ancillary data items]", - &cmsgs[ncmsgbufs].level, - &cmsgs[ncmsgbufs].type, - &cmsgs[ncmsgbufs].data)) - goto finally; - bufsize = cmsgs[ncmsgbufs++].data.len; - -#ifdef CMSG_SPACE - if (!get_CMSG_SPACE(bufsize, &space)) { -#else - if (!get_CMSG_LEN(bufsize, &space)) { -#endif - PyErr_SetString(PyExc_OSError, "ancillary data item too large"); - goto finally; - } - controllen += space; - if (controllen > SOCKLEN_T_LIMIT || controllen < controllen_last) { - PyErr_SetString(PyExc_OSError, "too much ancillary data"); - goto finally; - } - controllen_last = controllen; - } - - /* Construct ancillary data block from control message info. */ - if (ncmsgbufs > 0) { - struct cmsghdr *cmsgh = NULL; - - controlbuf = PyMem_Malloc(controllen); - if (controlbuf == NULL) { - PyErr_NoMemory(); - goto finally; - } - msg.msg_control = controlbuf; - - msg.msg_controllen = controllen; - - /* Need to zero out the buffer as a workaround for glibc's - CMSG_NXTHDR() implementation. After getting the pointer to - the next header, it checks its (uninitialized) cmsg_len - member to see if the "message" fits in the buffer, and - returns NULL if it doesn't. Zero-filling the buffer - ensures that this doesn't happen. */ - memset(controlbuf, 0, controllen); - - for (i = 0; i < ncmsgbufs; i++) { - size_t msg_len, data_len = cmsgs[i].data.len; - int enough_space = 0; - - cmsgh = (i == 0) ? CMSG_FIRSTHDR(&msg) : CMSG_NXTHDR(&msg, cmsgh); - if (cmsgh == NULL) { - PyErr_Format(PyExc_RuntimeError, - "unexpected NULL result from %s()", - (i == 0) ? "CMSG_FIRSTHDR" : "CMSG_NXTHDR"); - goto finally; - } - if (!get_CMSG_LEN(data_len, &msg_len)) { - PyErr_SetString(PyExc_RuntimeError, - "item size out of range for CMSG_LEN()"); - goto finally; - } - if (cmsg_min_space(&msg, cmsgh, msg_len)) { - size_t space; - - cmsgh->cmsg_len = msg_len; - if (get_cmsg_data_space(&msg, cmsgh, &space)) - enough_space = (space >= data_len); - } - if (!enough_space) { - PyErr_SetString(PyExc_RuntimeError, - "ancillary data does not fit in calculated " - "space"); - goto finally; - } - cmsgh->cmsg_level = cmsgs[i].level; - cmsgh->cmsg_type = cmsgs[i].type; - memcpy(CMSG_DATA(cmsgh), cmsgs[i].data.buf, data_len); - } - } - - /* Make the system call. */ - if (!IS_SELECTABLE(s)) { - select_error(); - goto finally; - } - - ctx.msg = &msg; - ctx.flags = flags; - if (sock_call(s, 1, sock_sendmsg_impl, &ctx) < 0) - goto finally; - - retval = PyLong_FromSsize_t(ctx.result); - -finally: - PyMem_Free(controlbuf); - for (i = 0; i < ncmsgbufs; i++) - PyBuffer_Release(&cmsgs[i].data); - PyMem_Free(cmsgs); - Py_XDECREF(cmsg_fast); - PyMem_Free(msg.msg_iov); - for (i = 0; i < ndatabufs; i++) { - PyBuffer_Release(&databufs[i]); - } - PyMem_Free(databufs); - return retval; -} - -PyDoc_STRVAR(sendmsg_doc, -"sendmsg(buffers[, ancdata[, flags[, address]]]) -> count\n\ -\n\ -Send normal and ancillary data to the socket, gathering the\n\ -non-ancillary data from a series of buffers and concatenating it into\n\ -a single message. The buffers argument specifies the non-ancillary\n\ -data as an iterable of bytes-like objects (e.g. bytes objects).\n\ -The ancdata argument specifies the ancillary data (control messages)\n\ -as an iterable of zero or more tuples (cmsg_level, cmsg_type,\n\ -cmsg_data), where cmsg_level and cmsg_type are integers specifying the\n\ -protocol level and protocol-specific type respectively, and cmsg_data\n\ -is a bytes-like object holding the associated data. The flags\n\ -argument defaults to 0 and has the same meaning as for send(). If\n\ -address is supplied and not None, it sets a destination address for\n\ -the message. The return value is the number of bytes of non-ancillary\n\ -data sent."); -#endif /* CMSG_LEN */ - -#ifdef HAVE_SOCKADDR_ALG -static PyObject* -sock_sendmsg_afalg(PySocketSockObject *self, PyObject *args, PyObject *kwds) -{ - PyObject *retval = NULL; - - Py_ssize_t i, ndatabufs = 0; - Py_buffer *databufs = NULL; - PyObject *data_arg = NULL; - - Py_buffer iv = {NULL, NULL}; - - PyObject *opobj = NULL; - int op = -1; - - PyObject *assoclenobj = NULL; - int assoclen = -1; - - unsigned int *uiptr; - int flags = 0; - - struct msghdr msg; - struct cmsghdr *header = NULL; - struct af_alg_iv *alg_iv = NULL; - struct sock_sendmsg ctx; - Py_ssize_t controllen; - void *controlbuf = NULL; - static char *keywords[] = {"msg", "op", "iv", "assoclen", "flags", 0}; - - if (self->sock_family != AF_ALG) { - PyErr_SetString(PyExc_OSError, - "algset is only supported for AF_ALG"); - return NULL; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|O$O!y*O!i:sendmsg_afalg", keywords, - &data_arg, - &PyLong_Type, &opobj, &iv, - &PyLong_Type, &assoclenobj, &flags)) { - return NULL; - } - - memset(&msg, 0, sizeof(msg)); - - /* op is a required, keyword-only argument >= 0 */ - if (opobj != NULL) { - op = _PyLong_AsInt(opobj); - } - if (op < 0) { - /* override exception from _PyLong_AsInt() */ - PyErr_SetString(PyExc_TypeError, - "Invalid or missing argument 'op'"); - goto finally; - } - /* assoclen is optional but must be >= 0 */ - if (assoclenobj != NULL) { - assoclen = _PyLong_AsInt(assoclenobj); - if (assoclen == -1 && PyErr_Occurred()) { - goto finally; - } - if (assoclen < 0) { - PyErr_SetString(PyExc_TypeError, - "assoclen must be positive"); - goto finally; - } - } - - controllen = CMSG_SPACE(4); - if (iv.buf != NULL) { - controllen += CMSG_SPACE(sizeof(*alg_iv) + iv.len); - } - if (assoclen >= 0) { - controllen += CMSG_SPACE(4); - } - - controlbuf = PyMem_Malloc(controllen); - if (controlbuf == NULL) { - PyErr_NoMemory(); - goto finally; - } - memset(controlbuf, 0, controllen); - - msg.msg_controllen = controllen; - msg.msg_control = controlbuf; - - /* Fill in an iovec for each message part, and save the Py_buffer - structs to release afterwards. */ - if (data_arg != NULL) { - if (sock_sendmsg_iovec(self, data_arg, &msg, &databufs, &ndatabufs) == -1) { - goto finally; - } - } - - /* set operation to encrypt or decrypt */ - header = CMSG_FIRSTHDR(&msg); - if (header == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "unexpected NULL result from CMSG_FIRSTHDR"); - goto finally; - } - header->cmsg_level = SOL_ALG; - header->cmsg_type = ALG_SET_OP; - header->cmsg_len = CMSG_LEN(4); - uiptr = (void*)CMSG_DATA(header); - *uiptr = (unsigned int)op; - - /* set initialization vector */ - if (iv.buf != NULL) { - header = CMSG_NXTHDR(&msg, header); - if (header == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "unexpected NULL result from CMSG_NXTHDR(iv)"); - goto finally; - } - header->cmsg_level = SOL_ALG; - header->cmsg_type = ALG_SET_IV; - header->cmsg_len = CMSG_SPACE(sizeof(*alg_iv) + iv.len); - alg_iv = (void*)CMSG_DATA(header); - alg_iv->ivlen = iv.len; - memcpy(alg_iv->iv, iv.buf, iv.len); - } - - /* set length of associated data for AEAD */ - if (assoclen >= 0) { - header = CMSG_NXTHDR(&msg, header); - if (header == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "unexpected NULL result from CMSG_NXTHDR(assoc)"); - goto finally; - } - header->cmsg_level = SOL_ALG; - header->cmsg_type = ALG_SET_AEAD_ASSOCLEN; - header->cmsg_len = CMSG_LEN(4); - uiptr = (void*)CMSG_DATA(header); - *uiptr = (unsigned int)assoclen; - } - - ctx.msg = &msg; - ctx.flags = flags; - if (sock_call(self, 1, sock_sendmsg_impl, &ctx) < 0) { - goto finally; - } - - retval = PyLong_FromSsize_t(ctx.result); - - finally: - PyMem_Free(controlbuf); - if (iv.buf != NULL) { - PyBuffer_Release(&iv); - } - PyMem_Free(msg.msg_iov); - for (i = 0; i < ndatabufs; i++) { - PyBuffer_Release(&databufs[i]); - } - PyMem_Free(databufs); - return retval; -} - -PyDoc_STRVAR(sendmsg_afalg_doc, -"sendmsg_afalg([msg], *, op[, iv[, assoclen[, flags=MSG_MORE]]])\n\ -\n\ -Set operation mode, IV and length of associated data for an AF_ALG\n\ -operation socket."); -#endif - -/* s.shutdown(how) method */ - -static PyObject * -sock_shutdown(PySocketSockObject *s, PyObject *arg) -{ - int how; - int res; - - how = _PyLong_AsInt(arg); - if (how == -1 && PyErr_Occurred()) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = shutdown(s->sock_fd, how); - Py_END_ALLOW_THREADS - if (res < 0) - return s->errorhandler(); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(shutdown_doc, -"shutdown(flag)\n\ -\n\ -Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\ -of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR)."); - -#if defined(MS_WINDOWS) && defined(SIO_RCVALL) -static PyObject* -sock_ioctl(PySocketSockObject *s, PyObject *arg) -{ - unsigned long cmd = SIO_RCVALL; - PyObject *argO; - DWORD recv; - - if (!PyArg_ParseTuple(arg, "kO:ioctl", &cmd, &argO)) - return NULL; - - switch (cmd) { - case SIO_RCVALL: { - unsigned int option = RCVALL_ON; - if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) - return NULL; - if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), - NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { - return set_error(); - } - return PyLong_FromUnsignedLong(recv); } - case SIO_KEEPALIVE_VALS: { - struct tcp_keepalive ka; - if (!PyArg_ParseTuple(arg, "k(kkk):ioctl", &cmd, - &ka.onoff, &ka.keepalivetime, &ka.keepaliveinterval)) - return NULL; - if (WSAIoctl(s->sock_fd, cmd, &ka, sizeof(ka), - NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { - return set_error(); - } - return PyLong_FromUnsignedLong(recv); } -#if defined(SIO_LOOPBACK_FAST_PATH) - case SIO_LOOPBACK_FAST_PATH: { - unsigned int option; - if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option)) - return NULL; - if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option), - NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) { - return set_error(); - } - return PyLong_FromUnsignedLong(recv); } -#endif - default: - PyErr_Format(PyExc_ValueError, "invalid ioctl command %lu", cmd); - return NULL; - } -} -PyDoc_STRVAR(sock_ioctl_doc, -"ioctl(cmd, option) -> long\n\ -\n\ -Control the socket with WSAIoctl syscall. Currently supported 'cmd' values are\n\ -SIO_RCVALL: 'option' must be one of the socket.RCVALL_* constants.\n\ -SIO_KEEPALIVE_VALS: 'option' is a tuple of (onoff, timeout, interval).\n\ -SIO_LOOPBACK_FAST_PATH: 'option' is a boolean value, and is disabled by default"); -#endif - -#if defined(MS_WINDOWS) -static PyObject* -sock_share(PySocketSockObject *s, PyObject *arg) -{ - WSAPROTOCOL_INFOW info; - DWORD processId; - int result; - - if (!PyArg_ParseTuple(arg, "I", &processId)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - result = WSADuplicateSocketW(s->sock_fd, processId, &info); - Py_END_ALLOW_THREADS - if (result == SOCKET_ERROR) - return set_error(); - return PyBytes_FromStringAndSize((const char*)&info, sizeof(info)); -} -PyDoc_STRVAR(sock_share_doc, -"share(process_id) -> bytes\n\ -\n\ -Share the socket with another process. The target process id\n\ -must be provided and the resulting bytes object passed to the target\n\ -process. There the shared socket can be instantiated by calling\n\ -socket.fromshare()."); - - -#endif - -/* List of methods for socket objects */ - -static PyMethodDef sock_methods[] = { - {"_accept", (PyCFunction)sock_accept, METH_NOARGS, - accept_doc}, - {"bind", (PyCFunction)sock_bind, METH_O, - bind_doc}, - {"close", (PyCFunction)sock_close, METH_NOARGS, - sock_close_doc}, - {"connect", (PyCFunction)sock_connect, METH_O, - connect_doc}, - {"connect_ex", (PyCFunction)sock_connect_ex, METH_O, - connect_ex_doc}, - {"detach", (PyCFunction)sock_detach, METH_NOARGS, - detach_doc}, - {"fileno", (PyCFunction)sock_fileno, METH_NOARGS, - fileno_doc}, -#ifdef HAVE_GETPEERNAME - {"getpeername", (PyCFunction)sock_getpeername, - METH_NOARGS, getpeername_doc}, -#endif - {"getsockname", (PyCFunction)sock_getsockname, - METH_NOARGS, getsockname_doc}, - {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS, - getsockopt_doc}, -#if defined(MS_WINDOWS) && defined(SIO_RCVALL) - {"ioctl", (PyCFunction)sock_ioctl, METH_VARARGS, - sock_ioctl_doc}, -#endif -#if defined(MS_WINDOWS) - {"share", (PyCFunction)sock_share, METH_VARARGS, - sock_share_doc}, -#endif - {"listen", (PyCFunction)sock_listen, METH_VARARGS, - listen_doc}, - {"recv", (PyCFunction)sock_recv, METH_VARARGS, - recv_doc}, - {"recv_into", (PyCFunction)(void(*)(void))sock_recv_into, METH_VARARGS | METH_KEYWORDS, - recv_into_doc}, - {"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS, - recvfrom_doc}, - {"recvfrom_into", (PyCFunction)(void(*)(void))sock_recvfrom_into, METH_VARARGS | METH_KEYWORDS, - recvfrom_into_doc}, - {"send", (PyCFunction)sock_send, METH_VARARGS, - send_doc}, - {"sendall", (PyCFunction)sock_sendall, METH_VARARGS, - sendall_doc}, - {"sendto", (PyCFunction)sock_sendto, METH_VARARGS, - sendto_doc}, - {"setblocking", (PyCFunction)sock_setblocking, METH_O, - setblocking_doc}, - {"getblocking", (PyCFunction)sock_getblocking, METH_NOARGS, - getblocking_doc}, - {"settimeout", (PyCFunction)sock_settimeout, METH_O, - settimeout_doc}, - {"gettimeout", (PyCFunction)sock_gettimeout, METH_NOARGS, - gettimeout_doc}, - {"setsockopt", (PyCFunction)sock_setsockopt, METH_VARARGS, - setsockopt_doc}, - {"shutdown", (PyCFunction)sock_shutdown, METH_O, - shutdown_doc}, -#ifdef CMSG_LEN - {"recvmsg", (PyCFunction)sock_recvmsg, METH_VARARGS, - recvmsg_doc}, - {"recvmsg_into", (PyCFunction)sock_recvmsg_into, METH_VARARGS, - recvmsg_into_doc,}, - {"sendmsg", (PyCFunction)sock_sendmsg, METH_VARARGS, - sendmsg_doc}, -#endif -#ifdef HAVE_SOCKADDR_ALG - {"sendmsg_afalg", (PyCFunction)(void(*)(void))sock_sendmsg_afalg, METH_VARARGS | METH_KEYWORDS, - sendmsg_afalg_doc}, -#endif - {NULL, NULL} /* sentinel */ -}; - -/* SockObject members */ -static PyMemberDef sock_memberlist[] = { - {"family", T_INT, offsetof(PySocketSockObject, sock_family), READONLY, "the socket family"}, - {"type", T_INT, offsetof(PySocketSockObject, sock_type), READONLY, "the socket type"}, - {"proto", T_INT, offsetof(PySocketSockObject, sock_proto), READONLY, "the socket protocol"}, - {0}, -}; - -static PyGetSetDef sock_getsetlist[] = { - {"timeout", (getter)sock_gettimeout, NULL, PyDoc_STR("the socket timeout")}, - {NULL} /* sentinel */ -}; - -/* Deallocate a socket object in response to the last Py_DECREF(). - First close the file description. */ - -static void -sock_finalize(PySocketSockObject *s) -{ - SOCKET_T fd; - PyObject *error_type, *error_value, *error_traceback; - - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - if (s->sock_fd != INVALID_SOCKET) { - if (PyErr_ResourceWarning((PyObject *)s, 1, "unclosed %R", s)) { - /* Spurious errors can appear at shutdown */ - if (PyErr_ExceptionMatches(PyExc_Warning)) { - PyErr_WriteUnraisable((PyObject *)s); - } - } - - /* Only close the socket *after* logging the ResourceWarning warning - to allow the logger to call socket methods like - socket.getsockname(). If the socket is closed before, socket - methods fails with the EBADF error. */ - fd = s->sock_fd; - s->sock_fd = INVALID_SOCKET; - - /* We do not want to retry upon EINTR: see sock_close() */ - Py_BEGIN_ALLOW_THREADS - (void) SOCKETCLOSE(fd); - Py_END_ALLOW_THREADS - } - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); -} - -static void -sock_dealloc(PySocketSockObject *s) -{ - if (PyObject_CallFinalizerFromDealloc((PyObject *)s) < 0) - return; - - Py_TYPE(s)->tp_free((PyObject *)s); -} - - -static PyObject * -sock_repr(PySocketSockObject *s) -{ - long sock_fd; - /* On Windows, this test is needed because SOCKET_T is unsigned */ - if (s->sock_fd == INVALID_SOCKET) { - sock_fd = -1; - } -#if SIZEOF_SOCKET_T > SIZEOF_LONG - else if (s->sock_fd > LONG_MAX) { - /* this can occur on Win64, and actually there is a special - ugly printf formatter for decimal pointer length integer - printing, only bother if necessary*/ - PyErr_SetString(PyExc_OverflowError, - "no printf formatter to display " - "the socket descriptor in decimal"); - return NULL; - } -#endif - else - sock_fd = (long)s->sock_fd; - return PyUnicode_FromFormat( - "", - sock_fd, s->sock_family, - s->sock_type, - s->sock_proto); -} - - -/* Create a new, uninitialized socket object. */ - -static PyObject * -sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *new; - - new = type->tp_alloc(type, 0); - if (new != NULL) { - ((PySocketSockObject *)new)->sock_fd = INVALID_SOCKET; - ((PySocketSockObject *)new)->sock_timeout = _PyTime_FromSeconds(-1); - ((PySocketSockObject *)new)->errorhandler = &set_error; - } - return new; -} - - -/* Initialize a new socket object. */ - -#ifdef SOCK_CLOEXEC -/* socket() and socketpair() fail with EINVAL on Linux kernel older - * than 2.6.27 if SOCK_CLOEXEC flag is set in the socket type. */ -static int sock_cloexec_works = -1; -#endif - -/*ARGSUSED*/ -static int -sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) -{ - PySocketSockObject *s = (PySocketSockObject *)self; - PyObject *fdobj = NULL; - SOCKET_T fd = INVALID_SOCKET; - int family = -1, type = -1, proto = -1; - static char *keywords[] = {"family", "type", "proto", "fileno", 0}; -#ifndef MS_WINDOWS -#ifdef SOCK_CLOEXEC - int *atomic_flag_works = &sock_cloexec_works; -#else - int *atomic_flag_works = NULL; -#endif -#endif - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|iiiO:socket", keywords, - &family, &type, &proto, &fdobj)) - return -1; - -#ifdef MS_WINDOWS - /* In this case, we don't use the family, type and proto args */ - if (fdobj == NULL || fdobj == Py_None) -#endif - { - if (PySys_Audit("socket.__new__", "Oiii", - s, family, type, proto) < 0) { - return -1; - } - } - - if (fdobj != NULL && fdobj != Py_None) { -#ifdef MS_WINDOWS - /* recreate a socket that was duplicated */ - if (PyBytes_Check(fdobj)) { - WSAPROTOCOL_INFOW info; - if (PyBytes_GET_SIZE(fdobj) != sizeof(info)) { - PyErr_Format(PyExc_ValueError, - "socket descriptor string has wrong size, " - "should be %zu bytes.", sizeof(info)); - return -1; - } - memcpy(&info, PyBytes_AS_STRING(fdobj), sizeof(info)); - - if (PySys_Audit("socket.__new__", "Oiii", s, - info.iAddressFamily, info.iSocketType, - info.iProtocol) < 0) { - return -1; - } - - Py_BEGIN_ALLOW_THREADS - fd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, &info, 0, WSA_FLAG_OVERLAPPED); - Py_END_ALLOW_THREADS - if (fd == INVALID_SOCKET) { - set_error(); - return -1; - } - family = info.iAddressFamily; - type = info.iSocketType; - proto = info.iProtocol; - } - else -#endif - { - - if (PyFloat_Check(fdobj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); - return -1; - } - - fd = PyLong_AsSocket_t(fdobj); - if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) - return -1; -#ifdef MS_WINDOWS - if (fd == INVALID_SOCKET) { -#else - if (fd < 0) { -#endif - PyErr_SetString(PyExc_ValueError, "negative file descriptor"); - return -1; - } - - /* validate that passed file descriptor is valid and a socket. */ - sock_addr_t addrbuf; - socklen_t addrlen = sizeof(sock_addr_t); - - memset(&addrbuf, 0, addrlen); - if (getsockname(fd, SAS2SA(&addrbuf), &addrlen) == 0) { - if (family == -1) { - family = SAS2SA(&addrbuf)->sa_family; - } - } else { -#ifdef MS_WINDOWS - /* getsockname() on an unbound socket is an error on Windows. - Invalid descriptor and not a socket is same error code. - Error out if family must be resolved, or bad descriptor. */ - if (family == -1 || CHECK_ERRNO(ENOTSOCK)) { -#else - /* getsockname() is not supported for SOL_ALG on Linux. */ - if (family == -1 || CHECK_ERRNO(EBADF) || CHECK_ERRNO(ENOTSOCK)) { -#endif - set_error(); - return -1; - } - } -#ifdef SO_TYPE - if (type == -1) { - int tmp; - socklen_t slen = sizeof(tmp); - if (getsockopt(fd, SOL_SOCKET, SO_TYPE, - (void *)&tmp, &slen) == 0) - { - type = tmp; - } else { - set_error(); - return -1; - } - } -#else - type = SOCK_STREAM; -#endif -#ifdef SO_PROTOCOL - if (proto == -1) { - int tmp; - socklen_t slen = sizeof(tmp); - if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, - (void *)&tmp, &slen) == 0) - { - proto = tmp; - } else { - set_error(); - return -1; - } - } -#else - proto = 0; -#endif - } - } - else { - /* No fd, default to AF_INET and SOCK_STREAM */ - if (family == -1) { - family = AF_INET; - } - if (type == -1) { - type = SOCK_STREAM; - } - if (proto == -1) { - proto = 0; - } -#ifdef MS_WINDOWS - /* Windows implementation */ -#ifndef WSA_FLAG_NO_HANDLE_INHERIT -#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 -#endif - - Py_BEGIN_ALLOW_THREADS - if (support_wsa_no_inherit) { - fd = WSASocketW(family, type, proto, - NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); - if (fd == INVALID_SOCKET) { - /* Windows 7 or Windows 2008 R2 without SP1 or the hotfix */ - support_wsa_no_inherit = 0; - fd = socket(family, type, proto); - } - } - else { - fd = socket(family, type, proto); - } - Py_END_ALLOW_THREADS - - if (fd == INVALID_SOCKET) { - set_error(); - return -1; - } - - if (!support_wsa_no_inherit) { - if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0)) { - closesocket(fd); - PyErr_SetFromWindowsErr(0); - return -1; - } - } -#else - /* UNIX */ - Py_BEGIN_ALLOW_THREADS -#ifdef SOCK_CLOEXEC - if (sock_cloexec_works != 0) { - fd = socket(family, type | SOCK_CLOEXEC, proto); - if (sock_cloexec_works == -1) { - if (fd >= 0) { - sock_cloexec_works = 1; - } - else if (errno == EINVAL) { - /* Linux older than 2.6.27 does not support SOCK_CLOEXEC */ - sock_cloexec_works = 0; - fd = socket(family, type, proto); - } - } - } - else -#endif - { - fd = socket(family, type, proto); - } - Py_END_ALLOW_THREADS - - if (fd == INVALID_SOCKET) { - set_error(); - return -1; - } - - if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { - SOCKETCLOSE(fd); - return -1; - } -#endif - } - if (init_sockobject(s, fd, family, type, proto) == -1) { - SOCKETCLOSE(fd); - return -1; - } - - return 0; - -} - - -/* Type object for socket objects. */ - -static PyTypeObject sock_type = { - PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ - "_socket.socket", /* tp_name */ - sizeof(PySocketSockObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)sock_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)sock_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - sock_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - sock_methods, /* tp_methods */ - sock_memberlist, /* tp_members */ - sock_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - sock_initobj, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - sock_new, /* tp_new */ - PyObject_Del, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - (destructor)sock_finalize, /* tp_finalize */ -}; - - -/* Python interface to gethostname(). */ - -/*ARGSUSED*/ -static PyObject * -socket_gethostname(PyObject *self, PyObject *unused) -{ - if (PySys_Audit("socket.gethostname", NULL) < 0) { - return NULL; - } - -#ifdef MS_WINDOWS - /* Don't use winsock's gethostname, as this returns the ANSI - version of the hostname, whereas we need a Unicode string. - Otherwise, gethostname apparently also returns the DNS name. */ - wchar_t buf[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD size = Py_ARRAY_LENGTH(buf); - wchar_t *name; - PyObject *result; - - if (GetComputerNameExW(ComputerNamePhysicalDnsHostname, buf, &size)) - return PyUnicode_FromWideChar(buf, size); - - if (GetLastError() != ERROR_MORE_DATA) - return PyErr_SetFromWindowsErr(0); - - if (size == 0) - return PyUnicode_New(0, 0); - - /* MSDN says ERROR_MORE_DATA may occur because DNS allows longer - names */ - name = PyMem_New(wchar_t, size); - if (!name) { - PyErr_NoMemory(); - return NULL; - } - if (!GetComputerNameExW(ComputerNamePhysicalDnsHostname, - name, - &size)) - { - PyMem_Free(name); - return PyErr_SetFromWindowsErr(0); - } - - result = PyUnicode_FromWideChar(name, size); - PyMem_Free(name); - return result; -#else - char buf[1024]; - int res; - Py_BEGIN_ALLOW_THREADS - res = gethostname(buf, (int) sizeof buf - 1); - Py_END_ALLOW_THREADS - if (res < 0) - return set_error(); - buf[sizeof buf - 1] = '\0'; - return PyUnicode_DecodeFSDefault(buf); -#endif -} - -PyDoc_STRVAR(gethostname_doc, -"gethostname() -> string\n\ -\n\ -Return the current host name."); - -#ifdef HAVE_SETHOSTNAME -PyDoc_STRVAR(sethostname_doc, -"sethostname(name)\n\n\ -Sets the hostname to name."); - -static PyObject * -socket_sethostname(PyObject *self, PyObject *args) -{ - PyObject *hnobj; - Py_buffer buf; - int res, flag = 0; - -#ifdef _AIX -/* issue #18259, not declared in any useful header file */ -extern int sethostname(const char *, size_t); -#endif - - if (!PyArg_ParseTuple(args, "S:sethostname", &hnobj)) { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O&:sethostname", - PyUnicode_FSConverter, &hnobj)) - return NULL; - flag = 1; - } - - if (PySys_Audit("socket.sethostname", "(O)", hnobj) < 0) { - return NULL; - } - - res = PyObject_GetBuffer(hnobj, &buf, PyBUF_SIMPLE); - if (!res) { - res = sethostname(buf.buf, buf.len); - PyBuffer_Release(&buf); - } - if (flag) - Py_DECREF(hnobj); - if (res) - return set_error(); - Py_RETURN_NONE; -} -#endif - -/* Python interface to gethostbyname(name). */ - -/*ARGSUSED*/ -static PyObject * -socket_gethostbyname(PyObject *self, PyObject *args) -{ - char *name; - struct sockaddr_in addrbuf; - PyObject *ret = NULL; - - if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name)) - return NULL; - if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { - goto finally; - } - if (setipaddr(name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET) < 0) - goto finally; - ret = make_ipv4_addr(&addrbuf); -finally: - PyMem_Free(name); - return ret; -} - -PyDoc_STRVAR(gethostbyname_doc, -"gethostbyname(host) -> address\n\ -\n\ -Return the IP address (a string of the form '255.255.255.255') for a host."); - - -static PyObject* -sock_decode_hostname(const char *name) -{ -#ifdef MS_WINDOWS - /* Issue #26227: gethostbyaddr() returns a string encoded - * to the ANSI code page */ - return PyUnicode_DecodeMBCS(name, strlen(name), "surrogatepass"); -#else - /* Decode from UTF-8 */ - return PyUnicode_FromString(name); -#endif -} - -/* Convenience function common to gethostbyname_ex and gethostbyaddr */ - -static PyObject * -gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) -{ - char **pch; - PyObject *rtn_tuple = (PyObject *)NULL; - PyObject *name_list = (PyObject *)NULL; - PyObject *addr_list = (PyObject *)NULL; - PyObject *tmp; - PyObject *name; - - if (h == NULL) { - /* Let's get real error message to return */ - set_herror(h_errno); - return NULL; - } - - if (h->h_addrtype != af) { - /* Let's get real error message to return */ - errno = EAFNOSUPPORT; - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - switch (af) { - - case AF_INET: - if (alen < sizeof(struct sockaddr_in)) - return NULL; - break; - -#ifdef ENABLE_IPV6 - case AF_INET6: - if (alen < sizeof(struct sockaddr_in6)) - return NULL; - break; -#endif - - } - - if ((name_list = PyList_New(0)) == NULL) - goto err; - - if ((addr_list = PyList_New(0)) == NULL) - goto err; - - /* SF #1511317: h_aliases can be NULL */ - if (h->h_aliases) { - for (pch = h->h_aliases; *pch != NULL; pch++) { - int status; - tmp = PyUnicode_FromString(*pch); - if (tmp == NULL) - goto err; - - status = PyList_Append(name_list, tmp); - Py_DECREF(tmp); - - if (status) - goto err; - } - } - - for (pch = h->h_addr_list; *pch != NULL; pch++) { - int status; - - switch (af) { - - case AF_INET: - { - struct sockaddr_in sin; - memset(&sin, 0, sizeof(sin)); - sin.sin_family = af; -#ifdef HAVE_SOCKADDR_SA_LEN - sin.sin_len = sizeof(sin); -#endif - memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr)); - tmp = make_ipv4_addr(&sin); - - if (pch == h->h_addr_list && alen >= sizeof(sin)) - memcpy((char *) addr, &sin, sizeof(sin)); - break; - } - -#ifdef ENABLE_IPV6 - case AF_INET6: - { - struct sockaddr_in6 sin6; - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_family = af; -#ifdef HAVE_SOCKADDR_SA_LEN - sin6.sin6_len = sizeof(sin6); -#endif - memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr)); - tmp = make_ipv6_addr(&sin6); - - if (pch == h->h_addr_list && alen >= sizeof(sin6)) - memcpy((char *) addr, &sin6, sizeof(sin6)); - break; - } -#endif - - default: /* can't happen */ - PyErr_SetString(PyExc_OSError, - "unsupported address family"); - return NULL; - } - - if (tmp == NULL) - goto err; - - status = PyList_Append(addr_list, tmp); - Py_DECREF(tmp); - - if (status) - goto err; - } - - name = sock_decode_hostname(h->h_name); - if (name == NULL) - goto err; - rtn_tuple = Py_BuildValue("NOO", name, name_list, addr_list); - - err: - Py_XDECREF(name_list); - Py_XDECREF(addr_list); - return rtn_tuple; -} - - -/* Python interface to gethostbyname_ex(name). */ - -/*ARGSUSED*/ -static PyObject * -socket_gethostbyname_ex(PyObject *self, PyObject *args) -{ - char *name; - struct hostent *h; - sock_addr_t addr; - struct sockaddr *sa; - PyObject *ret = NULL; -#ifdef HAVE_GETHOSTBYNAME_R - struct hostent hp_allocated; -#ifdef HAVE_GETHOSTBYNAME_R_3_ARG - struct hostent_data data; -#else - char buf[16384]; - int buf_len = (sizeof buf) - 1; - int errnop; -#endif -#ifdef HAVE_GETHOSTBYNAME_R_3_ARG - int result; -#endif -#endif /* HAVE_GETHOSTBYNAME_R */ - - if (!PyArg_ParseTuple(args, "et:gethostbyname_ex", "idna", &name)) - return NULL; - if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { - goto finally; - } - if (setipaddr(name, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) - goto finally; - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_GETHOSTBYNAME_R -#if defined(HAVE_GETHOSTBYNAME_R_6_ARG) - gethostbyname_r(name, &hp_allocated, buf, buf_len, - &h, &errnop); -#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG) - h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop); -#else /* HAVE_GETHOSTBYNAME_R_3_ARG */ - memset((void *) &data, '\0', sizeof(data)); - result = gethostbyname_r(name, &hp_allocated, &data); - h = (result != 0) ? NULL : &hp_allocated; -#endif -#else /* not HAVE_GETHOSTBYNAME_R */ -#ifdef USE_GETHOSTBYNAME_LOCK - PyThread_acquire_lock(netdb_lock, 1); -#endif - SUPPRESS_DEPRECATED_CALL - h = gethostbyname(name); -#endif /* HAVE_GETHOSTBYNAME_R */ - Py_END_ALLOW_THREADS - /* Some C libraries would require addr.__ss_family instead of - addr.ss_family. - Therefore, we cast the sockaddr_storage into sockaddr to - access sa_family. */ - sa = SAS2SA(&addr); - ret = gethost_common(h, SAS2SA(&addr), sizeof(addr), - sa->sa_family); -#ifdef USE_GETHOSTBYNAME_LOCK - PyThread_release_lock(netdb_lock); -#endif -finally: - PyMem_Free(name); - return ret; -} - -PyDoc_STRVAR(ghbn_ex_doc, -"gethostbyname_ex(host) -> (name, aliaslist, addresslist)\n\ -\n\ -Return the true host name, a list of aliases, and a list of IP addresses,\n\ -for a host. The host argument is a string giving a host name or IP number."); - - -/* Python interface to gethostbyaddr(IP). */ - -/*ARGSUSED*/ -static PyObject * -socket_gethostbyaddr(PyObject *self, PyObject *args) -{ - sock_addr_t addr; - struct sockaddr *sa = SAS2SA(&addr); - char *ip_num; - struct hostent *h; - PyObject *ret = NULL; -#ifdef HAVE_GETHOSTBYNAME_R - struct hostent hp_allocated; -#ifdef HAVE_GETHOSTBYNAME_R_3_ARG - struct hostent_data data; -#else - /* glibcs up to 2.10 assume that the buf argument to - gethostbyaddr_r is 8-byte aligned, which at least llvm-gcc - does not ensure. The attribute below instructs the compiler - to maintain this alignment. */ - char buf[16384] Py_ALIGNED(8); - int buf_len = (sizeof buf) - 1; - int errnop; -#endif -#ifdef HAVE_GETHOSTBYNAME_R_3_ARG - int result; -#endif -#endif /* HAVE_GETHOSTBYNAME_R */ - const char *ap; - int al; - int af; - - if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num)) - return NULL; - if (PySys_Audit("socket.gethostbyaddr", "O", args) < 0) { - goto finally; - } - af = AF_UNSPEC; - if (setipaddr(ip_num, sa, sizeof(addr), af) < 0) - goto finally; - af = sa->sa_family; - ap = NULL; - /* al = 0; */ - switch (af) { - case AF_INET: - ap = (char *)&((struct sockaddr_in *)sa)->sin_addr; - al = sizeof(((struct sockaddr_in *)sa)->sin_addr); - break; -#ifdef ENABLE_IPV6 - case AF_INET6: - ap = (char *)&((struct sockaddr_in6 *)sa)->sin6_addr; - al = sizeof(((struct sockaddr_in6 *)sa)->sin6_addr); - break; -#endif - default: - PyErr_SetString(PyExc_OSError, "unsupported address family"); - goto finally; - } - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_GETHOSTBYNAME_R -#if defined(HAVE_GETHOSTBYNAME_R_6_ARG) - gethostbyaddr_r(ap, al, af, - &hp_allocated, buf, buf_len, - &h, &errnop); -#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG) - h = gethostbyaddr_r(ap, al, af, - &hp_allocated, buf, buf_len, &errnop); -#else /* HAVE_GETHOSTBYNAME_R_3_ARG */ - memset((void *) &data, '\0', sizeof(data)); - result = gethostbyaddr_r(ap, al, af, &hp_allocated, &data); - h = (result != 0) ? NULL : &hp_allocated; -#endif -#else /* not HAVE_GETHOSTBYNAME_R */ -#ifdef USE_GETHOSTBYNAME_LOCK - PyThread_acquire_lock(netdb_lock, 1); -#endif - SUPPRESS_DEPRECATED_CALL - h = gethostbyaddr(ap, al, af); -#endif /* HAVE_GETHOSTBYNAME_R */ - Py_END_ALLOW_THREADS - ret = gethost_common(h, SAS2SA(&addr), sizeof(addr), af); -#ifdef USE_GETHOSTBYNAME_LOCK - PyThread_release_lock(netdb_lock); -#endif -finally: - PyMem_Free(ip_num); - return ret; -} - -PyDoc_STRVAR(gethostbyaddr_doc, -"gethostbyaddr(host) -> (name, aliaslist, addresslist)\n\ -\n\ -Return the true host name, a list of aliases, and a list of IP addresses,\n\ -for a host. The host argument is a string giving a host name or IP number."); - - -/* Python interface to getservbyname(name). - This only returns the port number, since the other info is already - known or not useful (like the list of aliases). */ - -/*ARGSUSED*/ -static PyObject * -socket_getservbyname(PyObject *self, PyObject *args) -{ - const char *name, *proto=NULL; - struct servent *sp; - if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto)) - return NULL; - - if (PySys_Audit("socket.getservbyname", "ss", name, proto) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - sp = getservbyname(name, proto); - Py_END_ALLOW_THREADS - if (sp == NULL) { - PyErr_SetString(PyExc_OSError, "service/proto not found"); - return NULL; - } - return PyLong_FromLong((long) ntohs(sp->s_port)); -} - -PyDoc_STRVAR(getservbyname_doc, -"getservbyname(servicename[, protocolname]) -> integer\n\ -\n\ -Return a port number from a service name and protocol name.\n\ -The optional protocol name, if given, should be 'tcp' or 'udp',\n\ -otherwise any protocol will match."); - - -/* Python interface to getservbyport(port). - This only returns the service name, since the other info is already - known or not useful (like the list of aliases). */ - -/*ARGSUSED*/ -static PyObject * -socket_getservbyport(PyObject *self, PyObject *args) -{ - int port; - const char *proto=NULL; - struct servent *sp; - if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto)) - return NULL; - if (port < 0 || port > 0xffff) { - PyErr_SetString( - PyExc_OverflowError, - "getservbyport: port must be 0-65535."); - return NULL; - } - - if (PySys_Audit("socket.getservbyport", "is", port, proto) < 0) { - return NULL; - } - - Py_BEGIN_ALLOW_THREADS - sp = getservbyport(htons((short)port), proto); - Py_END_ALLOW_THREADS - if (sp == NULL) { - PyErr_SetString(PyExc_OSError, "port/proto not found"); - return NULL; - } - return PyUnicode_FromString(sp->s_name); -} - -PyDoc_STRVAR(getservbyport_doc, -"getservbyport(port[, protocolname]) -> string\n\ -\n\ -Return the service name from a port number and protocol name.\n\ -The optional protocol name, if given, should be 'tcp' or 'udp',\n\ -otherwise any protocol will match."); - -/* Python interface to getprotobyname(name). - This only returns the protocol number, since the other info is - already known or not useful (like the list of aliases). */ - -/*ARGSUSED*/ -static PyObject * -socket_getprotobyname(PyObject *self, PyObject *args) -{ - const char *name; - struct protoent *sp; - if (!PyArg_ParseTuple(args, "s:getprotobyname", &name)) - return NULL; - Py_BEGIN_ALLOW_THREADS - sp = getprotobyname(name); - Py_END_ALLOW_THREADS - if (sp == NULL) { - PyErr_SetString(PyExc_OSError, "protocol not found"); - return NULL; - } - return PyLong_FromLong((long) sp->p_proto); -} - -PyDoc_STRVAR(getprotobyname_doc, -"getprotobyname(name) -> integer\n\ -\n\ -Return the protocol number for the named protocol. (Rarely used.)"); - -static PyObject * -socket_close(PyObject *self, PyObject *fdobj) -{ - SOCKET_T fd; - int res; - - fd = PyLong_AsSocket_t(fdobj); - if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = SOCKETCLOSE(fd); - Py_END_ALLOW_THREADS - /* bpo-30319: The peer can already have closed the connection. - Python ignores ECONNRESET on close(). */ - if (res < 0 && !CHECK_ERRNO(ECONNRESET)) { - return set_error(); - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(close_doc, -"close(integer) -> None\n\ -\n\ -Close an integer socket file descriptor. This is like os.close(), but for\n\ -sockets; on some platforms os.close() won't work for socket file descriptors."); - -#ifndef NO_DUP -/* dup() function for socket fds */ - -static PyObject * -socket_dup(PyObject *self, PyObject *fdobj) -{ - SOCKET_T fd, newfd; - PyObject *newfdobj; -#ifdef MS_WINDOWS - WSAPROTOCOL_INFOW info; -#endif - - fd = PyLong_AsSocket_t(fdobj); - if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) - return NULL; - -#ifdef MS_WINDOWS - if (WSADuplicateSocketW(fd, GetCurrentProcessId(), &info)) - return set_error(); - - newfd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - &info, 0, WSA_FLAG_OVERLAPPED); - if (newfd == INVALID_SOCKET) - return set_error(); - - if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { - closesocket(newfd); - PyErr_SetFromWindowsErr(0); - return NULL; - } -#else - /* On UNIX, dup can be used to duplicate the file descriptor of a socket */ - newfd = _Py_dup(fd); - if (newfd == INVALID_SOCKET) - return NULL; -#endif - - newfdobj = PyLong_FromSocket_t(newfd); - if (newfdobj == NULL) - SOCKETCLOSE(newfd); - return newfdobj; -} - -PyDoc_STRVAR(dup_doc, -"dup(integer) -> integer\n\ -\n\ -Duplicate an integer socket file descriptor. This is like os.dup(), but for\n\ -sockets; on some platforms os.dup() won't work for socket file descriptors."); -#endif - - -#ifdef HAVE_SOCKETPAIR -/* Create a pair of sockets using the socketpair() function. - Arguments as for socket() except the default family is AF_UNIX if - defined on the platform; otherwise, the default is AF_INET. */ - -/*ARGSUSED*/ -static PyObject * -socket_socketpair(PyObject *self, PyObject *args) -{ - PySocketSockObject *s0 = NULL, *s1 = NULL; - SOCKET_T sv[2]; - int family, type = SOCK_STREAM, proto = 0; - PyObject *res = NULL; -#ifdef SOCK_CLOEXEC - int *atomic_flag_works = &sock_cloexec_works; -#else - int *atomic_flag_works = NULL; -#endif - int ret; - -#if defined(AF_UNIX) - family = AF_UNIX; -#else - family = AF_INET; -#endif - if (!PyArg_ParseTuple(args, "|iii:socketpair", - &family, &type, &proto)) - return NULL; - - /* Create a pair of socket fds */ - Py_BEGIN_ALLOW_THREADS -#ifdef SOCK_CLOEXEC - if (sock_cloexec_works != 0) { - ret = socketpair(family, type | SOCK_CLOEXEC, proto, sv); - if (sock_cloexec_works == -1) { - if (ret >= 0) { - sock_cloexec_works = 1; - } - else if (errno == EINVAL) { - /* Linux older than 2.6.27 does not support SOCK_CLOEXEC */ - sock_cloexec_works = 0; - ret = socketpair(family, type, proto, sv); - } - } - } - else -#endif - { - ret = socketpair(family, type, proto, sv); - } - Py_END_ALLOW_THREADS - - if (ret < 0) - return set_error(); - - if (_Py_set_inheritable(sv[0], 0, atomic_flag_works) < 0) - goto finally; - if (_Py_set_inheritable(sv[1], 0, atomic_flag_works) < 0) - goto finally; - - s0 = new_sockobject(sv[0], family, type, proto); - if (s0 == NULL) - goto finally; - s1 = new_sockobject(sv[1], family, type, proto); - if (s1 == NULL) - goto finally; - res = PyTuple_Pack(2, s0, s1); - -finally: - if (res == NULL) { - if (s0 == NULL) - SOCKETCLOSE(sv[0]); - if (s1 == NULL) - SOCKETCLOSE(sv[1]); - } - Py_XDECREF(s0); - Py_XDECREF(s1); - return res; -} - -PyDoc_STRVAR(socketpair_doc, -"socketpair([family[, type [, proto]]]) -> (socket object, socket object)\n\ -\n\ -Create a pair of socket objects from the sockets returned by the platform\n\ -socketpair() function.\n\ -The arguments are the same as for socket() except the default family is\n\ -AF_UNIX if defined on the platform; otherwise, the default is AF_INET."); - -#endif /* HAVE_SOCKETPAIR */ - - -static PyObject * -socket_ntohs(PyObject *self, PyObject *args) -{ - int x; - - if (!PyArg_ParseTuple(args, "i:ntohs", &x)) { - return NULL; - } - if (x < 0) { - PyErr_SetString(PyExc_OverflowError, - "ntohs: can't convert negative Python int to C " - "16-bit unsigned integer"); - return NULL; - } - if (x > 0xffff) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "ntohs: Python int too large to convert to C " - "16-bit unsigned integer (The silent truncation " - "is deprecated)", - 1)) { - return NULL; - } - } - return PyLong_FromUnsignedLong(ntohs((unsigned short)x)); -} - -PyDoc_STRVAR(ntohs_doc, -"ntohs(integer) -> integer\n\ -\n\ -Convert a 16-bit unsigned integer from network to host byte order.\n\ -Note that in case the received integer does not fit in 16-bit unsigned\n\ -integer, but does fit in a positive C int, it is silently truncated to\n\ -16-bit unsigned integer.\n\ -However, this silent truncation feature is deprecated, and will raise an\n\ -exception in future versions of Python."); - - -static PyObject * -socket_ntohl(PyObject *self, PyObject *arg) -{ - unsigned long x; - - if (PyLong_Check(arg)) { - x = PyLong_AsUnsignedLong(arg); - if (x == (unsigned long) -1 && PyErr_Occurred()) - return NULL; -#if SIZEOF_LONG > 4 - { - unsigned long y; - /* only want the trailing 32 bits */ - y = x & 0xFFFFFFFFUL; - if (y ^ x) - return PyErr_Format(PyExc_OverflowError, - "int larger than 32 bits"); - x = y; - } -#endif - } - else - return PyErr_Format(PyExc_TypeError, - "expected int, %s found", - Py_TYPE(arg)->tp_name); - return PyLong_FromUnsignedLong(ntohl(x)); -} - -PyDoc_STRVAR(ntohl_doc, -"ntohl(integer) -> integer\n\ -\n\ -Convert a 32-bit integer from network to host byte order."); - - -static PyObject * -socket_htons(PyObject *self, PyObject *args) -{ - int x; - - if (!PyArg_ParseTuple(args, "i:htons", &x)) { - return NULL; - } - if (x < 0) { - PyErr_SetString(PyExc_OverflowError, - "htons: can't convert negative Python int to C " - "16-bit unsigned integer"); - return NULL; - } - if (x > 0xffff) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "htons: Python int too large to convert to C " - "16-bit unsigned integer (The silent truncation " - "is deprecated)", - 1)) { - return NULL; - } - } - return PyLong_FromUnsignedLong(htons((unsigned short)x)); -} - -PyDoc_STRVAR(htons_doc, -"htons(integer) -> integer\n\ -\n\ -Convert a 16-bit unsigned integer from host to network byte order.\n\ -Note that in case the received integer does not fit in 16-bit unsigned\n\ -integer, but does fit in a positive C int, it is silently truncated to\n\ -16-bit unsigned integer.\n\ -However, this silent truncation feature is deprecated, and will raise an\n\ -exception in future versions of Python."); - - -static PyObject * -socket_htonl(PyObject *self, PyObject *arg) -{ - unsigned long x; - - if (PyLong_Check(arg)) { - x = PyLong_AsUnsignedLong(arg); - if (x == (unsigned long) -1 && PyErr_Occurred()) - return NULL; -#if SIZEOF_LONG > 4 - { - unsigned long y; - /* only want the trailing 32 bits */ - y = x & 0xFFFFFFFFUL; - if (y ^ x) - return PyErr_Format(PyExc_OverflowError, - "int larger than 32 bits"); - x = y; - } -#endif - } - else - return PyErr_Format(PyExc_TypeError, - "expected int, %s found", - Py_TYPE(arg)->tp_name); - return PyLong_FromUnsignedLong(htonl((unsigned long)x)); -} - -PyDoc_STRVAR(htonl_doc, -"htonl(integer) -> integer\n\ -\n\ -Convert a 32-bit integer from host to network byte order."); - -/* socket.inet_aton() and socket.inet_ntoa() functions. */ - -PyDoc_STRVAR(inet_aton_doc, -"inet_aton(string) -> bytes giving packed 32-bit IP representation\n\ -\n\ -Convert an IP address in string format (123.45.67.89) to the 32-bit packed\n\ -binary format used in low-level network functions."); - -static PyObject* -socket_inet_aton(PyObject *self, PyObject *args) -{ -#ifdef HAVE_INET_ATON - struct in_addr buf; -#endif - -#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK) -#if (SIZEOF_INT != 4) -#error "Not sure if in_addr_t exists and int is not 32-bits." -#endif - /* Have to use inet_addr() instead */ - unsigned int packed_addr; -#endif - const char *ip_addr; - - if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr)) - return NULL; - - -#ifdef HAVE_INET_ATON - -#ifdef USE_INET_ATON_WEAKLINK - if (inet_aton != NULL) { -#endif - if (inet_aton(ip_addr, &buf)) - return PyBytes_FromStringAndSize((char *)(&buf), - sizeof(buf)); - - PyErr_SetString(PyExc_OSError, - "illegal IP address string passed to inet_aton"); - return NULL; - -#ifdef USE_INET_ATON_WEAKLINK - } else { -#endif - -#endif - -#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK) - - /* special-case this address as inet_addr might return INADDR_NONE - * for this */ - if (strcmp(ip_addr, "255.255.255.255") == 0) { - packed_addr = INADDR_BROADCAST; - } else { - - SUPPRESS_DEPRECATED_CALL - packed_addr = inet_addr(ip_addr); - - if (packed_addr == INADDR_NONE) { /* invalid address */ - PyErr_SetString(PyExc_OSError, - "illegal IP address string passed to inet_aton"); - return NULL; - } - } - return PyBytes_FromStringAndSize((char *) &packed_addr, - sizeof(packed_addr)); - -#ifdef USE_INET_ATON_WEAKLINK - } -#endif - -#endif -} - -PyDoc_STRVAR(inet_ntoa_doc, -"inet_ntoa(packed_ip) -> ip_address_string\n\ -\n\ -Convert an IP address from 32-bit packed binary format to string format"); - -static PyObject* -socket_inet_ntoa(PyObject *self, PyObject *args) -{ - Py_buffer packed_ip; - struct in_addr packed_addr; - - if (!PyArg_ParseTuple(args, "y*:inet_ntoa", &packed_ip)) { - return NULL; - } - - if (packed_ip.len != sizeof(packed_addr)) { - PyErr_SetString(PyExc_OSError, - "packed IP wrong length for inet_ntoa"); - PyBuffer_Release(&packed_ip); - return NULL; - } - - memcpy(&packed_addr, packed_ip.buf, packed_ip.len); - PyBuffer_Release(&packed_ip); - - SUPPRESS_DEPRECATED_CALL - return PyUnicode_FromString(inet_ntoa(packed_addr)); -} - -#ifdef HAVE_INET_PTON - -PyDoc_STRVAR(inet_pton_doc, -"inet_pton(af, ip) -> packed IP address string\n\ -\n\ -Convert an IP address from string format to a packed string suitable\n\ -for use with low-level network functions."); - -static PyObject * -socket_inet_pton(PyObject *self, PyObject *args) -{ - int af; - const char* ip; - int retval; -#ifdef ENABLE_IPV6 - char packed[Py_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))]; -#else - char packed[sizeof(struct in_addr)]; -#endif - if (!PyArg_ParseTuple(args, "is:inet_pton", &af, &ip)) { - return NULL; - } - -#if !defined(ENABLE_IPV6) && defined(AF_INET6) - if(af == AF_INET6) { - PyErr_SetString(PyExc_OSError, - "can't use AF_INET6, IPv6 is disabled"); - return NULL; - } -#endif - - retval = inet_pton(af, ip, packed); - if (retval < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } else if (retval == 0) { - PyErr_SetString(PyExc_OSError, - "illegal IP address string passed to inet_pton"); - return NULL; - } else if (af == AF_INET) { - return PyBytes_FromStringAndSize(packed, - sizeof(struct in_addr)); -#ifdef ENABLE_IPV6 - } else if (af == AF_INET6) { - return PyBytes_FromStringAndSize(packed, - sizeof(struct in6_addr)); -#endif - } else { - PyErr_SetString(PyExc_OSError, "unknown address family"); - return NULL; - } -} - -PyDoc_STRVAR(inet_ntop_doc, -"inet_ntop(af, packed_ip) -> string formatted IP address\n\ -\n\ -Convert a packed IP address of the given family to string format."); - -static PyObject * -socket_inet_ntop(PyObject *self, PyObject *args) -{ - int af; - Py_buffer packed_ip; - const char* retval; -#ifdef ENABLE_IPV6 - char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; -#else - char ip[INET_ADDRSTRLEN]; -#endif - - if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) { - return NULL; - } - - if (af == AF_INET) { - if (packed_ip.len != sizeof(struct in_addr)) { - PyErr_SetString(PyExc_ValueError, - "invalid length of packed IP address string"); - PyBuffer_Release(&packed_ip); - return NULL; - } -#ifdef ENABLE_IPV6 - } else if (af == AF_INET6) { - if (packed_ip.len != sizeof(struct in6_addr)) { - PyErr_SetString(PyExc_ValueError, - "invalid length of packed IP address string"); - PyBuffer_Release(&packed_ip); - return NULL; - } -#endif - } else { - PyErr_Format(PyExc_ValueError, - "unknown address family %d", af); - PyBuffer_Release(&packed_ip); - return NULL; - } - - /* inet_ntop guarantee NUL-termination of resulting string. */ - retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip)); - PyBuffer_Release(&packed_ip); - if (!retval) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } else { - return PyUnicode_FromString(retval); - } -} - -#endif /* HAVE_INET_PTON */ - -/* Python interface to getaddrinfo(host, port). */ - -/*ARGSUSED*/ -static PyObject * -socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) -{ - static char* kwnames[] = {"host", "port", "family", "type", "proto", - "flags", 0}; - struct addrinfo hints, *res; - struct addrinfo *res0 = NULL; - PyObject *hobj = NULL; - PyObject *pobj = (PyObject *)NULL; - char pbuf[30]; - const char *hptr, *pptr; - int family, socktype, protocol, flags; - int error; - PyObject *all = (PyObject *)NULL; - PyObject *idna = NULL; - - socktype = protocol = flags = 0; - family = AF_UNSPEC; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo", - kwnames, &hobj, &pobj, &family, &socktype, - &protocol, &flags)) { - return NULL; - } - if (hobj == Py_None) { - hptr = NULL; - } else if (PyUnicode_Check(hobj)) { - idna = PyUnicode_AsEncodedString(hobj, "idna", NULL); - if (!idna) - return NULL; - assert(PyBytes_Check(idna)); - hptr = PyBytes_AS_STRING(idna); - } else if (PyBytes_Check(hobj)) { - hptr = PyBytes_AsString(hobj); - } else { - PyErr_SetString(PyExc_TypeError, - "getaddrinfo() argument 1 must be string or None"); - return NULL; - } - if (PyLong_CheckExact(pobj)) { - long value = PyLong_AsLong(pobj); - if (value == -1 && PyErr_Occurred()) - goto err; - PyOS_snprintf(pbuf, sizeof(pbuf), "%ld", value); - pptr = pbuf; - } else if (PyUnicode_Check(pobj)) { - pptr = PyUnicode_AsUTF8(pobj); - if (pptr == NULL) - goto err; - } else if (PyBytes_Check(pobj)) { - pptr = PyBytes_AS_STRING(pobj); - } else if (pobj == Py_None) { - pptr = (char *)NULL; - } else { - PyErr_SetString(PyExc_OSError, "Int or String expected"); - goto err; - } -#if defined(__APPLE__) && defined(AI_NUMERICSERV) - if ((flags & AI_NUMERICSERV) && (pptr == NULL || (pptr[0] == '0' && pptr[1] == 0))) { - /* On OSX up to at least OSX 10.8 getaddrinfo crashes - * if AI_NUMERICSERV is set and the servname is NULL or "0". - * This workaround avoids a segfault in libsystem. - */ - pptr = "00"; - } -#endif - - if (PySys_Audit("socket.getaddrinfo", "OOiii", - hobj, pobj, family, socktype, protocol) < 0) { - return NULL; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = socktype; - hints.ai_protocol = protocol; - hints.ai_flags = flags; - Py_BEGIN_ALLOW_THREADS - ACQUIRE_GETADDRINFO_LOCK - error = getaddrinfo(hptr, pptr, &hints, &res0); - Py_END_ALLOW_THREADS - RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ - if (error) { - set_gaierror(error); - goto err; - } - - all = PyList_New(0); - if (all == NULL) - goto err; - for (res = res0; res; res = res->ai_next) { - PyObject *single; - PyObject *addr = - makesockaddr(-1, res->ai_addr, res->ai_addrlen, protocol); - if (addr == NULL) - goto err; - single = Py_BuildValue("iiisO", res->ai_family, - res->ai_socktype, res->ai_protocol, - res->ai_canonname ? res->ai_canonname : "", - addr); - Py_DECREF(addr); - if (single == NULL) - goto err; - - if (PyList_Append(all, single)) { - Py_DECREF(single); - goto err; - } - Py_DECREF(single); - } - Py_XDECREF(idna); - if (res0) - freeaddrinfo(res0); - return all; - err: - Py_XDECREF(all); - Py_XDECREF(idna); - if (res0) - freeaddrinfo(res0); - return (PyObject *)NULL; -} - -PyDoc_STRVAR(getaddrinfo_doc, -"getaddrinfo(host, port [, family, type, proto, flags])\n\ - -> list of (family, type, proto, canonname, sockaddr)\n\ -\n\ -Resolve host and port into addrinfo struct."); - -/* Python interface to getnameinfo(sa, flags). */ - -/*ARGSUSED*/ -static PyObject * -socket_getnameinfo(PyObject *self, PyObject *args) -{ - PyObject *sa = (PyObject *)NULL; - int flags; - const char *hostp; - int port; - unsigned int flowinfo, scope_id; - char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; - struct addrinfo hints, *res = NULL; - int error; - PyObject *ret = (PyObject *)NULL; - PyObject *name; - - flags = flowinfo = scope_id = 0; - if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags)) - return NULL; - if (!PyTuple_Check(sa)) { - PyErr_SetString(PyExc_TypeError, - "getnameinfo() argument 1 must be a tuple"); - return NULL; - } - if (!PyArg_ParseTuple(sa, "si|II;getnameinfo(): illegal sockaddr argument", - &hostp, &port, &flowinfo, &scope_id)) - { - return NULL; - } - if (flowinfo > 0xfffff) { - PyErr_SetString(PyExc_OverflowError, - "getnameinfo(): flowinfo must be 0-1048575."); - return NULL; - } - - if (PySys_Audit("socket.getnameinfo", "(O)", sa) < 0) { - return NULL; - } - - PyOS_snprintf(pbuf, sizeof(pbuf), "%d", port); - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; /* make numeric port happy */ - hints.ai_flags = AI_NUMERICHOST; /* don't do any name resolution */ - Py_BEGIN_ALLOW_THREADS - ACQUIRE_GETADDRINFO_LOCK - error = getaddrinfo(hostp, pbuf, &hints, &res); - Py_END_ALLOW_THREADS - RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */ - if (error) { - set_gaierror(error); - goto fail; - } - if (res->ai_next) { - PyErr_SetString(PyExc_OSError, - "sockaddr resolved to multiple addresses"); - goto fail; - } - switch (res->ai_family) { - case AF_INET: - { - if (PyTuple_GET_SIZE(sa) != 2) { - PyErr_SetString(PyExc_OSError, - "IPv4 sockaddr must be 2 tuple"); - goto fail; - } - break; - } -#ifdef ENABLE_IPV6 - case AF_INET6: - { - struct sockaddr_in6 *sin6; - sin6 = (struct sockaddr_in6 *)res->ai_addr; - sin6->sin6_flowinfo = htonl(flowinfo); - sin6->sin6_scope_id = scope_id; - break; - } -#endif - } - error = getnameinfo(res->ai_addr, (socklen_t) res->ai_addrlen, - hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), flags); - if (error) { - set_gaierror(error); - goto fail; - } - - name = sock_decode_hostname(hbuf); - if (name == NULL) - goto fail; - ret = Py_BuildValue("Ns", name, pbuf); - -fail: - if (res) - freeaddrinfo(res); - return ret; -} - -PyDoc_STRVAR(getnameinfo_doc, -"getnameinfo(sockaddr, flags) --> (host, port)\n\ -\n\ -Get host and port for a sockaddr."); - - -/* Python API to getting and setting the default timeout value. */ - -static PyObject * -socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - if (defaulttimeout < 0) { - Py_RETURN_NONE; - } - else { - double seconds = _PyTime_AsSecondsDouble(defaulttimeout); - return PyFloat_FromDouble(seconds); - } -} - -PyDoc_STRVAR(getdefaulttimeout_doc, -"getdefaulttimeout() -> timeout\n\ -\n\ -Returns the default timeout in seconds (float) for new socket objects.\n\ -A value of None indicates that new socket objects have no timeout.\n\ -When the socket module is first imported, the default is None."); - -static PyObject * -socket_setdefaulttimeout(PyObject *self, PyObject *arg) -{ - _PyTime_t timeout; - - if (socket_parse_timeout(&timeout, arg) < 0) - return NULL; - - defaulttimeout = timeout; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(setdefaulttimeout_doc, -"setdefaulttimeout(timeout)\n\ -\n\ -Set the default timeout in seconds (float) for new socket objects.\n\ -A value of None indicates that new socket objects have no timeout.\n\ -When the socket module is first imported, the default is None."); - -#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) -/* Python API for getting interface indices and names */ - -static PyObject * -socket_if_nameindex(PyObject *self, PyObject *arg) -{ - PyObject *list = PyList_New(0); - if (list == NULL) { - return NULL; - } -#ifdef MS_WINDOWS - PMIB_IF_TABLE2 tbl; - int ret; - if ((ret = GetIfTable2Ex(MibIfTableRaw, &tbl)) != NO_ERROR) { - Py_DECREF(list); - // ret is used instead of GetLastError() - return PyErr_SetFromWindowsErr(ret); - } - for (ULONG i = 0; i < tbl->NumEntries; ++i) { - MIB_IF_ROW2 r = tbl->Table[i]; - WCHAR buf[NDIS_IF_MAX_STRING_SIZE + 1]; - if ((ret = ConvertInterfaceLuidToNameW(&r.InterfaceLuid, buf, - Py_ARRAY_LENGTH(buf)))) { - Py_DECREF(list); - FreeMibTable(tbl); - // ret is used instead of GetLastError() - return PyErr_SetFromWindowsErr(ret); - } - PyObject *tuple = Py_BuildValue("Iu", r.InterfaceIndex, buf); - if (tuple == NULL || PyList_Append(list, tuple) == -1) { - Py_XDECREF(tuple); - Py_DECREF(list); - FreeMibTable(tbl); - return NULL; - } - Py_DECREF(tuple); - } - FreeMibTable(tbl); - return list; -#else - int i; - struct if_nameindex *ni; - - ni = if_nameindex(); - if (ni == NULL) { - Py_DECREF(list); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - -#ifdef _Py_MEMORY_SANITIZER - __msan_unpoison(ni, sizeof(ni)); - __msan_unpoison(&ni[0], sizeof(ni[0])); -#endif - for (i = 0; ni[i].if_index != 0 && i < INT_MAX; i++) { -#ifdef _Py_MEMORY_SANITIZER - /* This one isn't the end sentinel, the next one must exist. */ - __msan_unpoison(&ni[i+1], sizeof(ni[0])); - /* Otherwise Py_BuildValue internals are flagged by MSan when - they access the not-msan-tracked if_name string data. */ - { - char *to_sanitize = ni[i].if_name; - do { - __msan_unpoison(to_sanitize, 1); - } while (*to_sanitize++ != '\0'); - } -#endif - PyObject *ni_tuple = Py_BuildValue("IO&", - ni[i].if_index, PyUnicode_DecodeFSDefault, ni[i].if_name); - - if (ni_tuple == NULL || PyList_Append(list, ni_tuple) == -1) { - Py_XDECREF(ni_tuple); - Py_DECREF(list); - if_freenameindex(ni); - return NULL; - } - Py_DECREF(ni_tuple); - } - - if_freenameindex(ni); - return list; -#endif -} - -PyDoc_STRVAR(if_nameindex_doc, -"if_nameindex()\n\ -\n\ -Returns a list of network interface information (index, name) tuples."); - -static PyObject * -socket_if_nametoindex(PyObject *self, PyObject *args) -{ - PyObject *oname; -#ifdef MS_WINDOWS - NET_IFINDEX index; -#else - unsigned long index; -#endif - if (!PyArg_ParseTuple(args, "O&:if_nametoindex", - PyUnicode_FSConverter, &oname)) - return NULL; - - index = if_nametoindex(PyBytes_AS_STRING(oname)); - Py_DECREF(oname); - if (index == 0) { - /* if_nametoindex() doesn't set errno */ - PyErr_SetString(PyExc_OSError, "no interface with this name"); - return NULL; - } - - return PyLong_FromUnsignedLong(index); -} - -PyDoc_STRVAR(if_nametoindex_doc, -"if_nametoindex(if_name)\n\ -\n\ -Returns the interface index corresponding to the interface name if_name."); - -static PyObject * -socket_if_indextoname(PyObject *self, PyObject *arg) -{ -#ifdef MS_WINDOWS - NET_IFINDEX index; -#else - unsigned long index; -#endif - char name[IF_NAMESIZE + 1]; - - index = PyLong_AsUnsignedLong(arg); - if (index == (unsigned long) -1) - return NULL; - - if (if_indextoname(index, name) == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - return PyUnicode_DecodeFSDefault(name); -} - -PyDoc_STRVAR(if_indextoname_doc, -"if_indextoname(if_index)\n\ -\n\ -Returns the interface name corresponding to the interface index if_index."); - -#endif // defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) - - -#ifdef CMSG_LEN -/* Python interface to CMSG_LEN(length). */ - -static PyObject * -socket_CMSG_LEN(PyObject *self, PyObject *args) -{ - Py_ssize_t length; - size_t result; - - if (!PyArg_ParseTuple(args, "n:CMSG_LEN", &length)) - return NULL; - if (length < 0 || !get_CMSG_LEN(length, &result)) { - PyErr_Format(PyExc_OverflowError, "CMSG_LEN() argument out of range"); - return NULL; - } - return PyLong_FromSize_t(result); -} - -PyDoc_STRVAR(CMSG_LEN_doc, -"CMSG_LEN(length) -> control message length\n\ -\n\ -Return the total length, without trailing padding, of an ancillary\n\ -data item with associated data of the given length. This value can\n\ -often be used as the buffer size for recvmsg() to receive a single\n\ -item of ancillary data, but RFC 3542 requires portable applications to\n\ -use CMSG_SPACE() and thus include space for padding, even when the\n\ -item will be the last in the buffer. Raises OverflowError if length\n\ -is outside the permissible range of values."); - - -#ifdef CMSG_SPACE -/* Python interface to CMSG_SPACE(length). */ - -static PyObject * -socket_CMSG_SPACE(PyObject *self, PyObject *args) -{ - Py_ssize_t length; - size_t result; - - if (!PyArg_ParseTuple(args, "n:CMSG_SPACE", &length)) - return NULL; - if (length < 0 || !get_CMSG_SPACE(length, &result)) { - PyErr_SetString(PyExc_OverflowError, - "CMSG_SPACE() argument out of range"); - return NULL; - } - return PyLong_FromSize_t(result); -} - -PyDoc_STRVAR(CMSG_SPACE_doc, -"CMSG_SPACE(length) -> buffer size\n\ -\n\ -Return the buffer size needed for recvmsg() to receive an ancillary\n\ -data item with associated data of the given length, along with any\n\ -trailing padding. The buffer space needed to receive multiple items\n\ -is the sum of the CMSG_SPACE() values for their associated data\n\ -lengths. Raises OverflowError if length is outside the permissible\n\ -range of values."); -#endif /* CMSG_SPACE */ -#endif /* CMSG_LEN */ - - -/* List of functions exported by this module. */ - -static PyMethodDef socket_methods[] = { - {"gethostbyname", socket_gethostbyname, - METH_VARARGS, gethostbyname_doc}, - {"gethostbyname_ex", socket_gethostbyname_ex, - METH_VARARGS, ghbn_ex_doc}, - {"gethostbyaddr", socket_gethostbyaddr, - METH_VARARGS, gethostbyaddr_doc}, - {"gethostname", socket_gethostname, - METH_NOARGS, gethostname_doc}, -#ifdef HAVE_SETHOSTNAME - {"sethostname", socket_sethostname, - METH_VARARGS, sethostname_doc}, -#endif - {"getservbyname", socket_getservbyname, - METH_VARARGS, getservbyname_doc}, - {"getservbyport", socket_getservbyport, - METH_VARARGS, getservbyport_doc}, - {"getprotobyname", socket_getprotobyname, - METH_VARARGS, getprotobyname_doc}, - {"close", socket_close, - METH_O, close_doc}, -#ifndef NO_DUP - {"dup", socket_dup, - METH_O, dup_doc}, -#endif -#ifdef HAVE_SOCKETPAIR - {"socketpair", socket_socketpair, - METH_VARARGS, socketpair_doc}, -#endif - {"ntohs", socket_ntohs, - METH_VARARGS, ntohs_doc}, - {"ntohl", socket_ntohl, - METH_O, ntohl_doc}, - {"htons", socket_htons, - METH_VARARGS, htons_doc}, - {"htonl", socket_htonl, - METH_O, htonl_doc}, - {"inet_aton", socket_inet_aton, - METH_VARARGS, inet_aton_doc}, - {"inet_ntoa", socket_inet_ntoa, - METH_VARARGS, inet_ntoa_doc}, -#ifdef HAVE_INET_PTON - {"inet_pton", socket_inet_pton, - METH_VARARGS, inet_pton_doc}, - {"inet_ntop", socket_inet_ntop, - METH_VARARGS, inet_ntop_doc}, -#endif - {"getaddrinfo", (PyCFunction)(void(*)(void))socket_getaddrinfo, - METH_VARARGS | METH_KEYWORDS, getaddrinfo_doc}, - {"getnameinfo", socket_getnameinfo, - METH_VARARGS, getnameinfo_doc}, - {"getdefaulttimeout", socket_getdefaulttimeout, - METH_NOARGS, getdefaulttimeout_doc}, - {"setdefaulttimeout", socket_setdefaulttimeout, - METH_O, setdefaulttimeout_doc}, -#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) - {"if_nameindex", socket_if_nameindex, - METH_NOARGS, if_nameindex_doc}, - {"if_nametoindex", socket_if_nametoindex, - METH_VARARGS, if_nametoindex_doc}, - {"if_indextoname", socket_if_indextoname, - METH_O, if_indextoname_doc}, -#endif -#ifdef CMSG_LEN - {"CMSG_LEN", socket_CMSG_LEN, - METH_VARARGS, CMSG_LEN_doc}, -#ifdef CMSG_SPACE - {"CMSG_SPACE", socket_CMSG_SPACE, - METH_VARARGS, CMSG_SPACE_doc}, -#endif -#endif - {NULL, NULL} /* Sentinel */ -}; - - -#ifdef MS_WINDOWS -#define OS_INIT_DEFINED - -/* Additional initialization and cleanup for Windows */ - -static void -os_cleanup(void) -{ - WSACleanup(); -} - -static int -os_init(void) -{ - WSADATA WSAData; - int ret; - ret = WSAStartup(0x0101, &WSAData); - switch (ret) { - case 0: /* No error */ - Py_AtExit(os_cleanup); - return 1; /* Success */ - case WSASYSNOTREADY: - PyErr_SetString(PyExc_ImportError, - "WSAStartup failed: network not ready"); - break; - case WSAVERNOTSUPPORTED: - case WSAEINVAL: - PyErr_SetString( - PyExc_ImportError, - "WSAStartup failed: requested version not supported"); - break; - default: - PyErr_Format(PyExc_ImportError, "WSAStartup failed: error code %d", ret); - break; - } - return 0; /* Failure */ -} - -#endif /* MS_WINDOWS */ - - - -#ifndef OS_INIT_DEFINED -static int -os_init(void) -{ - return 1; /* Success */ -} -#endif - - -/* C API table - always add new things to the end for binary - compatibility. */ -static -PySocketModule_APIObject PySocketModuleAPI = -{ - &sock_type, - NULL, - NULL -}; - - -/* Initialize the _socket module. - - This module is actually called "_socket", and there's a wrapper - "socket.py" which implements some additional functionality. - The import of "_socket" may fail with an ImportError exception if - os-specific initialization fails. On Windows, this does WINSOCK - initialization. When WINSOCK is initialized successfully, a call to - WSACleanup() is scheduled to be made at exit time. -*/ - -PyDoc_STRVAR(socket_doc, -"Implementation module for socket operations.\n\ -\n\ -See the socket module for documentation."); - -static struct PyModuleDef socketmodule = { - PyModuleDef_HEAD_INIT, - PySocket_MODULE_NAME, - socket_doc, - -1, - socket_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__socket(void) -{ - PyObject *m, *has_ipv6; - - if (!os_init()) - return NULL; - -#ifdef MS_WINDOWS - if (support_wsa_no_inherit == -1) { - support_wsa_no_inherit = IsWindows7SP1OrGreater(); - } -#endif - - Py_SET_TYPE(&sock_type, &PyType_Type); - m = PyModule_Create(&socketmodule); - if (m == NULL) - return NULL; - - Py_INCREF(PyExc_OSError); - PySocketModuleAPI.error = PyExc_OSError; - Py_INCREF(PyExc_OSError); - PyModule_AddObject(m, "error", PyExc_OSError); - socket_herror = PyErr_NewException("socket.herror", - PyExc_OSError, NULL); - if (socket_herror == NULL) - return NULL; - Py_INCREF(socket_herror); - PyModule_AddObject(m, "herror", socket_herror); - socket_gaierror = PyErr_NewException("socket.gaierror", PyExc_OSError, - NULL); - if (socket_gaierror == NULL) - return NULL; - Py_INCREF(socket_gaierror); - PyModule_AddObject(m, "gaierror", socket_gaierror); - socket_timeout = PyErr_NewException("socket.timeout", - PyExc_OSError, NULL); - if (socket_timeout == NULL) - return NULL; - PySocketModuleAPI.timeout_error = socket_timeout; - Py_INCREF(socket_timeout); - PyModule_AddObject(m, "timeout", socket_timeout); - Py_INCREF((PyObject *)&sock_type); - if (PyModule_AddObject(m, "SocketType", - (PyObject *)&sock_type) != 0) - return NULL; - Py_INCREF((PyObject *)&sock_type); - if (PyModule_AddObject(m, "socket", - (PyObject *)&sock_type) != 0) - return NULL; - -#ifdef ENABLE_IPV6 - has_ipv6 = Py_True; -#else - has_ipv6 = Py_False; -#endif - Py_INCREF(has_ipv6); - PyModule_AddObject(m, "has_ipv6", has_ipv6); - - /* Export C API */ - if (PyModule_AddObject(m, PySocket_CAPI_NAME, - PyCapsule_New(&PySocketModuleAPI, PySocket_CAPSULE_NAME, NULL) - ) != 0) - return NULL; - - /* Address families (we only support AF_INET and AF_UNIX) */ -#ifdef AF_UNSPEC - PyModule_AddIntMacro(m, AF_UNSPEC); -#endif - PyModule_AddIntMacro(m, AF_INET); -#if defined(AF_UNIX) - PyModule_AddIntMacro(m, AF_UNIX); -#endif /* AF_UNIX */ -#ifdef AF_AX25 - /* Amateur Radio AX.25 */ - PyModule_AddIntMacro(m, AF_AX25); -#endif -#ifdef AF_IPX - PyModule_AddIntMacro(m, AF_IPX); /* Novell IPX */ -#endif -#ifdef AF_APPLETALK - /* Appletalk DDP */ - PyModule_AddIntMacro(m, AF_APPLETALK); -#endif -#ifdef AF_NETROM - /* Amateur radio NetROM */ - PyModule_AddIntMacro(m, AF_NETROM); -#endif -#ifdef AF_BRIDGE - /* Multiprotocol bridge */ - PyModule_AddIntMacro(m, AF_BRIDGE); -#endif -#ifdef AF_ATMPVC - /* ATM PVCs */ - PyModule_AddIntMacro(m, AF_ATMPVC); -#endif -#ifdef AF_AAL5 - /* Reserved for Werner's ATM */ - PyModule_AddIntMacro(m, AF_AAL5); -#endif -#ifdef HAVE_SOCKADDR_ALG - PyModule_AddIntMacro(m, AF_ALG); /* Linux crypto */ -#endif -#ifdef AF_X25 - /* Reserved for X.25 project */ - PyModule_AddIntMacro(m, AF_X25); -#endif -#ifdef AF_INET6 - PyModule_AddIntMacro(m, AF_INET6); /* IP version 6 */ -#endif -#ifdef AF_ROSE - /* Amateur Radio X.25 PLP */ - PyModule_AddIntMacro(m, AF_ROSE); -#endif -#ifdef AF_DECnet - /* Reserved for DECnet project */ - PyModule_AddIntMacro(m, AF_DECnet); -#endif -#ifdef AF_NETBEUI - /* Reserved for 802.2LLC project */ - PyModule_AddIntMacro(m, AF_NETBEUI); -#endif -#ifdef AF_SECURITY - /* Security callback pseudo AF */ - PyModule_AddIntMacro(m, AF_SECURITY); -#endif -#ifdef AF_KEY - /* PF_KEY key management API */ - PyModule_AddIntMacro(m, AF_KEY); -#endif -#ifdef AF_NETLINK - /* */ - PyModule_AddIntMacro(m, AF_NETLINK); - PyModule_AddIntMacro(m, NETLINK_ROUTE); -#ifdef NETLINK_SKIP - PyModule_AddIntMacro(m, NETLINK_SKIP); -#endif -#ifdef NETLINK_W1 - PyModule_AddIntMacro(m, NETLINK_W1); -#endif - PyModule_AddIntMacro(m, NETLINK_USERSOCK); - PyModule_AddIntMacro(m, NETLINK_FIREWALL); -#ifdef NETLINK_TCPDIAG - PyModule_AddIntMacro(m, NETLINK_TCPDIAG); -#endif -#ifdef NETLINK_NFLOG - PyModule_AddIntMacro(m, NETLINK_NFLOG); -#endif -#ifdef NETLINK_XFRM - PyModule_AddIntMacro(m, NETLINK_XFRM); -#endif -#ifdef NETLINK_ARPD - PyModule_AddIntMacro(m, NETLINK_ARPD); -#endif -#ifdef NETLINK_ROUTE6 - PyModule_AddIntMacro(m, NETLINK_ROUTE6); -#endif - PyModule_AddIntMacro(m, NETLINK_IP6_FW); -#ifdef NETLINK_DNRTMSG - PyModule_AddIntMacro(m, NETLINK_DNRTMSG); -#endif -#ifdef NETLINK_TAPBASE - PyModule_AddIntMacro(m, NETLINK_TAPBASE); -#endif -#ifdef NETLINK_CRYPTO - PyModule_AddIntMacro(m, NETLINK_CRYPTO); -#endif -#endif /* AF_NETLINK */ - -#ifdef AF_QIPCRTR - /* Qualcomm IPCROUTER */ - PyModule_AddIntMacro(m, AF_QIPCRTR); -#endif - -#ifdef AF_VSOCK - PyModule_AddIntConstant(m, "AF_VSOCK", AF_VSOCK); - PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_SIZE", 0); - PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MIN_SIZE", 1); - PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MAX_SIZE", 2); - PyModule_AddIntConstant(m, "VMADDR_CID_ANY", 0xffffffff); - PyModule_AddIntConstant(m, "VMADDR_PORT_ANY", 0xffffffff); - PyModule_AddIntConstant(m, "VMADDR_CID_HOST", 2); - PyModule_AddIntConstant(m, "VM_SOCKETS_INVALID_VERSION", 0xffffffff); - PyModule_AddIntConstant(m, "IOCTL_VM_SOCKETS_GET_LOCAL_CID", _IO(7, 0xb9)); -#endif - -#ifdef AF_ROUTE - /* Alias to emulate 4.4BSD */ - PyModule_AddIntMacro(m, AF_ROUTE); -#endif -#ifdef AF_LINK - PyModule_AddIntMacro(m, AF_LINK); -#endif -#ifdef AF_ASH - /* Ash */ - PyModule_AddIntMacro(m, AF_ASH); -#endif -#ifdef AF_ECONET - /* Acorn Econet */ - PyModule_AddIntMacro(m, AF_ECONET); -#endif -#ifdef AF_ATMSVC - /* ATM SVCs */ - PyModule_AddIntMacro(m, AF_ATMSVC); -#endif -#ifdef AF_SNA - /* Linux SNA Project (nutters!) */ - PyModule_AddIntMacro(m, AF_SNA); -#endif -#ifdef AF_IRDA - /* IRDA sockets */ - PyModule_AddIntMacro(m, AF_IRDA); -#endif -#ifdef AF_PPPOX - /* PPPoX sockets */ - PyModule_AddIntMacro(m, AF_PPPOX); -#endif -#ifdef AF_WANPIPE - /* Wanpipe API Sockets */ - PyModule_AddIntMacro(m, AF_WANPIPE); -#endif -#ifdef AF_LLC - /* Linux LLC */ - PyModule_AddIntMacro(m, AF_LLC); -#endif - -#ifdef USE_BLUETOOTH - PyModule_AddIntMacro(m, AF_BLUETOOTH); -#ifdef BTPROTO_L2CAP - PyModule_AddIntMacro(m, BTPROTO_L2CAP); -#endif /* BTPROTO_L2CAP */ -#ifdef BTPROTO_HCI - PyModule_AddIntMacro(m, BTPROTO_HCI); - PyModule_AddIntMacro(m, SOL_HCI); -#if !defined(__NetBSD__) && !defined(__DragonFly__) - PyModule_AddIntMacro(m, HCI_FILTER); -#if !defined(__FreeBSD__) - PyModule_AddIntMacro(m, HCI_TIME_STAMP); - PyModule_AddIntMacro(m, HCI_DATA_DIR); -#endif /* !__FreeBSD__ */ -#endif /* !__NetBSD__ && !__DragonFly__ */ -#endif /* BTPROTO_HCI */ -#ifdef BTPROTO_RFCOMM - PyModule_AddIntMacro(m, BTPROTO_RFCOMM); -#endif /* BTPROTO_RFCOMM */ - PyModule_AddStringConstant(m, "BDADDR_ANY", "00:00:00:00:00:00"); - PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF"); -#ifdef BTPROTO_SCO - PyModule_AddIntMacro(m, BTPROTO_SCO); -#endif /* BTPROTO_SCO */ -#endif /* USE_BLUETOOTH */ - -#ifdef AF_CAN - /* Controller Area Network */ - PyModule_AddIntMacro(m, AF_CAN); -#endif -#ifdef PF_CAN - /* Controller Area Network */ - PyModule_AddIntMacro(m, PF_CAN); -#endif - -/* Reliable Datagram Sockets */ -#ifdef AF_RDS - PyModule_AddIntMacro(m, AF_RDS); -#endif -#ifdef PF_RDS - PyModule_AddIntMacro(m, PF_RDS); -#endif - -/* Kernel event messages */ -#ifdef PF_SYSTEM - PyModule_AddIntMacro(m, PF_SYSTEM); -#endif -#ifdef AF_SYSTEM - PyModule_AddIntMacro(m, AF_SYSTEM); -#endif - -#ifdef AF_PACKET - PyModule_AddIntMacro(m, AF_PACKET); -#endif -#ifdef PF_PACKET - PyModule_AddIntMacro(m, PF_PACKET); -#endif -#ifdef PACKET_HOST - PyModule_AddIntMacro(m, PACKET_HOST); -#endif -#ifdef PACKET_BROADCAST - PyModule_AddIntMacro(m, PACKET_BROADCAST); -#endif -#ifdef PACKET_MULTICAST - PyModule_AddIntMacro(m, PACKET_MULTICAST); -#endif -#ifdef PACKET_OTHERHOST - PyModule_AddIntMacro(m, PACKET_OTHERHOST); -#endif -#ifdef PACKET_OUTGOING - PyModule_AddIntMacro(m, PACKET_OUTGOING); -#endif -#ifdef PACKET_LOOPBACK - PyModule_AddIntMacro(m, PACKET_LOOPBACK); -#endif -#ifdef PACKET_FASTROUTE - PyModule_AddIntMacro(m, PACKET_FASTROUTE); -#endif - -#ifdef HAVE_LINUX_TIPC_H - PyModule_AddIntMacro(m, AF_TIPC); - - /* for addresses */ - PyModule_AddIntMacro(m, TIPC_ADDR_NAMESEQ); - PyModule_AddIntMacro(m, TIPC_ADDR_NAME); - PyModule_AddIntMacro(m, TIPC_ADDR_ID); - - PyModule_AddIntMacro(m, TIPC_ZONE_SCOPE); - PyModule_AddIntMacro(m, TIPC_CLUSTER_SCOPE); - PyModule_AddIntMacro(m, TIPC_NODE_SCOPE); - - /* for setsockopt() */ - PyModule_AddIntMacro(m, SOL_TIPC); - PyModule_AddIntMacro(m, TIPC_IMPORTANCE); - PyModule_AddIntMacro(m, TIPC_SRC_DROPPABLE); - PyModule_AddIntMacro(m, TIPC_DEST_DROPPABLE); - PyModule_AddIntMacro(m, TIPC_CONN_TIMEOUT); - - PyModule_AddIntMacro(m, TIPC_LOW_IMPORTANCE); - PyModule_AddIntMacro(m, TIPC_MEDIUM_IMPORTANCE); - PyModule_AddIntMacro(m, TIPC_HIGH_IMPORTANCE); - PyModule_AddIntMacro(m, TIPC_CRITICAL_IMPORTANCE); - - /* for subscriptions */ - PyModule_AddIntMacro(m, TIPC_SUB_PORTS); - PyModule_AddIntMacro(m, TIPC_SUB_SERVICE); -#ifdef TIPC_SUB_CANCEL - /* doesn't seem to be available everywhere */ - PyModule_AddIntMacro(m, TIPC_SUB_CANCEL); -#endif - PyModule_AddIntMacro(m, TIPC_WAIT_FOREVER); - PyModule_AddIntMacro(m, TIPC_PUBLISHED); - PyModule_AddIntMacro(m, TIPC_WITHDRAWN); - PyModule_AddIntMacro(m, TIPC_SUBSCR_TIMEOUT); - PyModule_AddIntMacro(m, TIPC_CFG_SRV); - PyModule_AddIntMacro(m, TIPC_TOP_SRV); -#endif - -#ifdef HAVE_SOCKADDR_ALG - /* Socket options */ - PyModule_AddIntMacro(m, ALG_SET_KEY); - PyModule_AddIntMacro(m, ALG_SET_IV); - PyModule_AddIntMacro(m, ALG_SET_OP); - PyModule_AddIntMacro(m, ALG_SET_AEAD_ASSOCLEN); - PyModule_AddIntMacro(m, ALG_SET_AEAD_AUTHSIZE); - PyModule_AddIntMacro(m, ALG_SET_PUBKEY); - - /* Operations */ - PyModule_AddIntMacro(m, ALG_OP_DECRYPT); - PyModule_AddIntMacro(m, ALG_OP_ENCRYPT); - PyModule_AddIntMacro(m, ALG_OP_SIGN); - PyModule_AddIntMacro(m, ALG_OP_VERIFY); -#endif - - /* Socket types */ - PyModule_AddIntMacro(m, SOCK_STREAM); - PyModule_AddIntMacro(m, SOCK_DGRAM); -/* We have incomplete socket support. */ -#ifdef SOCK_RAW - /* SOCK_RAW is marked as optional in the POSIX specification */ - PyModule_AddIntMacro(m, SOCK_RAW); -#endif - PyModule_AddIntMacro(m, SOCK_SEQPACKET); -#if defined(SOCK_RDM) - PyModule_AddIntMacro(m, SOCK_RDM); -#endif -#ifdef SOCK_CLOEXEC - PyModule_AddIntMacro(m, SOCK_CLOEXEC); -#endif -#ifdef SOCK_NONBLOCK - PyModule_AddIntMacro(m, SOCK_NONBLOCK); -#endif - -#ifdef SO_DEBUG - PyModule_AddIntMacro(m, SO_DEBUG); -#endif -#ifdef SO_ACCEPTCONN - PyModule_AddIntMacro(m, SO_ACCEPTCONN); -#endif -#ifdef SO_REUSEADDR - PyModule_AddIntMacro(m, SO_REUSEADDR); -#endif -#ifdef SO_EXCLUSIVEADDRUSE - PyModule_AddIntMacro(m, SO_EXCLUSIVEADDRUSE); -#endif - -#ifdef SO_KEEPALIVE - PyModule_AddIntMacro(m, SO_KEEPALIVE); -#endif -#ifdef SO_DONTROUTE - PyModule_AddIntMacro(m, SO_DONTROUTE); -#endif -#ifdef SO_BROADCAST - PyModule_AddIntMacro(m, SO_BROADCAST); -#endif -#ifdef SO_USELOOPBACK - PyModule_AddIntMacro(m, SO_USELOOPBACK); -#endif -#ifdef SO_LINGER - PyModule_AddIntMacro(m, SO_LINGER); -#endif -#ifdef SO_OOBINLINE - PyModule_AddIntMacro(m, SO_OOBINLINE); -#endif -#ifndef __GNU__ -#ifdef SO_REUSEPORT - if (IsReusePortAvailable()) - PyModule_AddIntMacro(m, SO_REUSEPORT); -#endif -#endif -#ifdef SO_SNDBUF - PyModule_AddIntMacro(m, SO_SNDBUF); -#endif -#ifdef SO_RCVBUF - PyModule_AddIntMacro(m, SO_RCVBUF); -#endif -#ifdef SO_SNDLOWAT - PyModule_AddIntMacro(m, SO_SNDLOWAT); -#endif -#ifdef SO_RCVLOWAT - PyModule_AddIntMacro(m, SO_RCVLOWAT); -#endif -#ifdef SO_SNDTIMEO - PyModule_AddIntMacro(m, SO_SNDTIMEO); -#endif -#ifdef SO_RCVTIMEO - PyModule_AddIntMacro(m, SO_RCVTIMEO); -#endif -#ifdef SO_ERROR - PyModule_AddIntMacro(m, SO_ERROR); -#endif -#ifdef SO_TYPE - PyModule_AddIntMacro(m, SO_TYPE); -#endif -#ifdef SO_SETFIB - PyModule_AddIntMacro(m, SO_SETFIB); -#endif -#ifdef SO_PASSCRED - PyModule_AddIntMacro(m, SO_PASSCRED); -#endif -#ifdef SO_PEERCRED - PyModule_AddIntMacro(m, SO_PEERCRED); -#endif -#ifdef LOCAL_PEERCRED - PyModule_AddIntMacro(m, LOCAL_PEERCRED); -#endif -#ifdef SO_PASSSEC - PyModule_AddIntMacro(m, SO_PASSSEC); -#endif -#ifdef SO_PEERSEC - PyModule_AddIntMacro(m, SO_PEERSEC); -#endif -#ifdef SO_BINDTODEVICE - PyModule_AddIntMacro(m, SO_BINDTODEVICE); -#endif -#ifdef SO_PRIORITY - PyModule_AddIntMacro(m, SO_PRIORITY); -#endif -#ifdef SO_MARK - PyModule_AddIntMacro(m, SO_MARK); -#endif -#ifdef SO_DOMAIN - PyModule_AddIntMacro(m, SO_DOMAIN); -#endif -#ifdef SO_PROTOCOL - PyModule_AddIntMacro(m, SO_PROTOCOL); -#endif - - /* Maximum number of connections for "listen" */ -#ifdef SOMAXCONN - PyModule_AddIntMacro(m, SOMAXCONN); -#else - PyModule_AddIntConstant(m, "SOMAXCONN", 5); /* Common value */ -#endif - - /* Ancillary message types */ -#ifdef SCM_RIGHTS - PyModule_AddIntMacro(m, SCM_RIGHTS); -#endif -#ifdef SCM_CREDENTIALS - PyModule_AddIntMacro(m, SCM_CREDENTIALS); -#endif -#ifdef SCM_CREDS - PyModule_AddIntMacro(m, SCM_CREDS); -#endif - - /* Flags for send, recv */ -#ifdef MSG_OOB - PyModule_AddIntMacro(m, MSG_OOB); -#endif -#ifdef MSG_PEEK - PyModule_AddIntMacro(m, MSG_PEEK); -#endif -#ifdef MSG_DONTROUTE - PyModule_AddIntMacro(m, MSG_DONTROUTE); -#endif -#ifdef MSG_DONTWAIT - PyModule_AddIntMacro(m, MSG_DONTWAIT); -#endif -#ifdef MSG_EOR - PyModule_AddIntMacro(m, MSG_EOR); -#endif -#ifdef MSG_TRUNC - PyModule_AddIntMacro(m, MSG_TRUNC); -#endif -#ifdef MSG_CTRUNC - PyModule_AddIntMacro(m, MSG_CTRUNC); -#endif -#ifdef MSG_WAITALL - PyModule_AddIntMacro(m, MSG_WAITALL); -#endif -#ifdef MSG_BTAG - PyModule_AddIntMacro(m, MSG_BTAG); -#endif -#ifdef MSG_ETAG - PyModule_AddIntMacro(m, MSG_ETAG); -#endif -#ifdef MSG_NOSIGNAL - PyModule_AddIntMacro(m, MSG_NOSIGNAL); -#endif -#ifdef MSG_NOTIFICATION - PyModule_AddIntMacro(m, MSG_NOTIFICATION); -#endif -#ifdef MSG_CMSG_CLOEXEC - PyModule_AddIntMacro(m, MSG_CMSG_CLOEXEC); -#endif -#ifdef MSG_ERRQUEUE - PyModule_AddIntMacro(m, MSG_ERRQUEUE); -#endif -#ifdef MSG_CONFIRM - PyModule_AddIntMacro(m, MSG_CONFIRM); -#endif -#ifdef MSG_MORE - PyModule_AddIntMacro(m, MSG_MORE); -#endif -#ifdef MSG_EOF - PyModule_AddIntMacro(m, MSG_EOF); -#endif -#ifdef MSG_BCAST - PyModule_AddIntMacro(m, MSG_BCAST); -#endif -#ifdef MSG_MCAST - PyModule_AddIntMacro(m, MSG_MCAST); -#endif -#ifdef MSG_FASTOPEN - PyModule_AddIntMacro(m, MSG_FASTOPEN); -#endif - - /* Protocol level and numbers, usable for [gs]etsockopt */ -#ifdef SOL_SOCKET - PyModule_AddIntMacro(m, SOL_SOCKET); -#endif -#ifdef SOL_IP - PyModule_AddIntMacro(m, SOL_IP); + for (ULONG i = 0; i < tbl->NumEntries; ++i) { + MIB_IF_ROW2 r = tbl->Table[i]; + WCHAR buf[NDIS_IF_MAX_STRING_SIZE + 1]; + if ((ret = ConvertInterfaceLuidToNameW(&r.InterfaceLuid, buf, + Py_ARRAY_LENGTH(buf)))) { + Py_DECREF(list); + FreeMibTable(tbl); + // ret is used instead of GetLastError() + return PyErr_SetFromWindowsErr(ret); + } + PyObject *tuple = Py_BuildValue("Iu", r.InterfaceIndex, buf); + if (tuple == NULL || PyList_Append(list, tuple) == -1) { + Py_XDECREF(tuple); + Py_DECREF(list); + FreeMibTable(tbl); + return NULL; + } + Py_DECREF(tuple); + } + FreeMibTable(tbl); + return list; #else - PyModule_AddIntConstant(m, "SOL_IP", 0); -#endif -#ifdef SOL_IPX - PyModule_AddIntMacro(m, SOL_IPX); -#endif -#ifdef SOL_AX25 - PyModule_AddIntMacro(m, SOL_AX25); -#endif -#ifdef SOL_ATALK - PyModule_AddIntMacro(m, SOL_ATALK); -#endif -#ifdef SOL_NETROM - PyModule_AddIntMacro(m, SOL_NETROM); -#endif -#ifdef SOL_ROSE - PyModule_AddIntMacro(m, SOL_ROSE); -#endif -#ifdef SOL_TCP - PyModule_AddIntMacro(m, SOL_TCP); + int i; + struct if_nameindex *ni; + + ni = if_nameindex(); + if (ni == NULL) { + Py_DECREF(list); + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + +#ifdef _Py_MEMORY_SANITIZER + __msan_unpoison(ni, sizeof(ni)); + __msan_unpoison(&ni[0], sizeof(ni[0])); +#endif + for (i = 0; ni[i].if_index != 0 && i < INT_MAX; i++) { +#ifdef _Py_MEMORY_SANITIZER + /* This one isn't the end sentinel, the next one must exist. */ + __msan_unpoison(&ni[i+1], sizeof(ni[0])); + /* Otherwise Py_BuildValue internals are flagged by MSan when + they access the not-msan-tracked if_name string data. */ + { + char *to_sanitize = ni[i].if_name; + do { + __msan_unpoison(to_sanitize, 1); + } while (*to_sanitize++ != '\0'); + } +#endif + PyObject *ni_tuple = Py_BuildValue("IO&", + ni[i].if_index, PyUnicode_DecodeFSDefault, ni[i].if_name); + + if (ni_tuple == NULL || PyList_Append(list, ni_tuple) == -1) { + Py_XDECREF(ni_tuple); + Py_DECREF(list); + if_freenameindex(ni); + return NULL; + } + Py_DECREF(ni_tuple); + } + + if_freenameindex(ni); + return list; +#endif +} + +PyDoc_STRVAR(if_nameindex_doc, +"if_nameindex()\n\ +\n\ +Returns a list of network interface information (index, name) tuples."); + +static PyObject * +socket_if_nametoindex(PyObject *self, PyObject *args) +{ + PyObject *oname; +#ifdef MS_WINDOWS + NET_IFINDEX index; #else - PyModule_AddIntConstant(m, "SOL_TCP", 6); -#endif -#ifdef SOL_UDP - PyModule_AddIntMacro(m, SOL_UDP); + unsigned long index; +#endif + if (!PyArg_ParseTuple(args, "O&:if_nametoindex", + PyUnicode_FSConverter, &oname)) + return NULL; + + index = if_nametoindex(PyBytes_AS_STRING(oname)); + Py_DECREF(oname); + if (index == 0) { + /* if_nametoindex() doesn't set errno */ + PyErr_SetString(PyExc_OSError, "no interface with this name"); + return NULL; + } + + return PyLong_FromUnsignedLong(index); +} + +PyDoc_STRVAR(if_nametoindex_doc, +"if_nametoindex(if_name)\n\ +\n\ +Returns the interface index corresponding to the interface name if_name."); + +static PyObject * +socket_if_indextoname(PyObject *self, PyObject *arg) +{ +#ifdef MS_WINDOWS + NET_IFINDEX index; #else - PyModule_AddIntConstant(m, "SOL_UDP", 17); -#endif -#ifdef SOL_CAN_BASE - PyModule_AddIntMacro(m, SOL_CAN_BASE); -#endif -#ifdef SOL_CAN_RAW - PyModule_AddIntMacro(m, SOL_CAN_RAW); - PyModule_AddIntMacro(m, CAN_RAW); + unsigned long index; +#endif + char name[IF_NAMESIZE + 1]; + + index = PyLong_AsUnsignedLong(arg); + if (index == (unsigned long) -1) + return NULL; + + if (if_indextoname(index, name) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + return PyUnicode_DecodeFSDefault(name); +} + +PyDoc_STRVAR(if_indextoname_doc, +"if_indextoname(if_index)\n\ +\n\ +Returns the interface name corresponding to the interface index if_index."); + +#endif // defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) + + +#ifdef CMSG_LEN +/* Python interface to CMSG_LEN(length). */ + +static PyObject * +socket_CMSG_LEN(PyObject *self, PyObject *args) +{ + Py_ssize_t length; + size_t result; + + if (!PyArg_ParseTuple(args, "n:CMSG_LEN", &length)) + return NULL; + if (length < 0 || !get_CMSG_LEN(length, &result)) { + PyErr_Format(PyExc_OverflowError, "CMSG_LEN() argument out of range"); + return NULL; + } + return PyLong_FromSize_t(result); +} + +PyDoc_STRVAR(CMSG_LEN_doc, +"CMSG_LEN(length) -> control message length\n\ +\n\ +Return the total length, without trailing padding, of an ancillary\n\ +data item with associated data of the given length. This value can\n\ +often be used as the buffer size for recvmsg() to receive a single\n\ +item of ancillary data, but RFC 3542 requires portable applications to\n\ +use CMSG_SPACE() and thus include space for padding, even when the\n\ +item will be the last in the buffer. Raises OverflowError if length\n\ +is outside the permissible range of values."); + + +#ifdef CMSG_SPACE +/* Python interface to CMSG_SPACE(length). */ + +static PyObject * +socket_CMSG_SPACE(PyObject *self, PyObject *args) +{ + Py_ssize_t length; + size_t result; + + if (!PyArg_ParseTuple(args, "n:CMSG_SPACE", &length)) + return NULL; + if (length < 0 || !get_CMSG_SPACE(length, &result)) { + PyErr_SetString(PyExc_OverflowError, + "CMSG_SPACE() argument out of range"); + return NULL; + } + return PyLong_FromSize_t(result); +} + +PyDoc_STRVAR(CMSG_SPACE_doc, +"CMSG_SPACE(length) -> buffer size\n\ +\n\ +Return the buffer size needed for recvmsg() to receive an ancillary\n\ +data item with associated data of the given length, along with any\n\ +trailing padding. The buffer space needed to receive multiple items\n\ +is the sum of the CMSG_SPACE() values for their associated data\n\ +lengths. Raises OverflowError if length is outside the permissible\n\ +range of values."); +#endif /* CMSG_SPACE */ +#endif /* CMSG_LEN */ + + +/* List of functions exported by this module. */ + +static PyMethodDef socket_methods[] = { + {"gethostbyname", socket_gethostbyname, + METH_VARARGS, gethostbyname_doc}, + {"gethostbyname_ex", socket_gethostbyname_ex, + METH_VARARGS, ghbn_ex_doc}, + {"gethostbyaddr", socket_gethostbyaddr, + METH_VARARGS, gethostbyaddr_doc}, + {"gethostname", socket_gethostname, + METH_NOARGS, gethostname_doc}, +#ifdef HAVE_SETHOSTNAME + {"sethostname", socket_sethostname, + METH_VARARGS, sethostname_doc}, +#endif + {"getservbyname", socket_getservbyname, + METH_VARARGS, getservbyname_doc}, + {"getservbyport", socket_getservbyport, + METH_VARARGS, getservbyport_doc}, + {"getprotobyname", socket_getprotobyname, + METH_VARARGS, getprotobyname_doc}, + {"close", socket_close, + METH_O, close_doc}, +#ifndef NO_DUP + {"dup", socket_dup, + METH_O, dup_doc}, +#endif +#ifdef HAVE_SOCKETPAIR + {"socketpair", socket_socketpair, + METH_VARARGS, socketpair_doc}, +#endif + {"ntohs", socket_ntohs, + METH_VARARGS, ntohs_doc}, + {"ntohl", socket_ntohl, + METH_O, ntohl_doc}, + {"htons", socket_htons, + METH_VARARGS, htons_doc}, + {"htonl", socket_htonl, + METH_O, htonl_doc}, + {"inet_aton", socket_inet_aton, + METH_VARARGS, inet_aton_doc}, + {"inet_ntoa", socket_inet_ntoa, + METH_VARARGS, inet_ntoa_doc}, +#ifdef HAVE_INET_PTON + {"inet_pton", socket_inet_pton, + METH_VARARGS, inet_pton_doc}, + {"inet_ntop", socket_inet_ntop, + METH_VARARGS, inet_ntop_doc}, +#endif + {"getaddrinfo", (PyCFunction)(void(*)(void))socket_getaddrinfo, + METH_VARARGS | METH_KEYWORDS, getaddrinfo_doc}, + {"getnameinfo", socket_getnameinfo, + METH_VARARGS, getnameinfo_doc}, + {"getdefaulttimeout", socket_getdefaulttimeout, + METH_NOARGS, getdefaulttimeout_doc}, + {"setdefaulttimeout", socket_setdefaulttimeout, + METH_O, setdefaulttimeout_doc}, +#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) + {"if_nameindex", socket_if_nameindex, + METH_NOARGS, if_nameindex_doc}, + {"if_nametoindex", socket_if_nametoindex, + METH_VARARGS, if_nametoindex_doc}, + {"if_indextoname", socket_if_indextoname, + METH_O, if_indextoname_doc}, +#endif +#ifdef CMSG_LEN + {"CMSG_LEN", socket_CMSG_LEN, + METH_VARARGS, CMSG_LEN_doc}, +#ifdef CMSG_SPACE + {"CMSG_SPACE", socket_CMSG_SPACE, + METH_VARARGS, CMSG_SPACE_doc}, +#endif +#endif + {NULL, NULL} /* Sentinel */ +}; + + +#ifdef MS_WINDOWS +#define OS_INIT_DEFINED + +/* Additional initialization and cleanup for Windows */ + +static void +os_cleanup(void) +{ + WSACleanup(); +} + +static int +os_init(void) +{ + WSADATA WSAData; + int ret; + ret = WSAStartup(0x0101, &WSAData); + switch (ret) { + case 0: /* No error */ + Py_AtExit(os_cleanup); + return 1; /* Success */ + case WSASYSNOTREADY: + PyErr_SetString(PyExc_ImportError, + "WSAStartup failed: network not ready"); + break; + case WSAVERNOTSUPPORTED: + case WSAEINVAL: + PyErr_SetString( + PyExc_ImportError, + "WSAStartup failed: requested version not supported"); + break; + default: + PyErr_Format(PyExc_ImportError, "WSAStartup failed: error code %d", ret); + break; + } + return 0; /* Failure */ +} + +#endif /* MS_WINDOWS */ + + + +#ifndef OS_INIT_DEFINED +static int +os_init(void) +{ + return 1; /* Success */ +} +#endif + + +/* C API table - always add new things to the end for binary + compatibility. */ +static +PySocketModule_APIObject PySocketModuleAPI = +{ + &sock_type, + NULL, + NULL +}; + + +/* Initialize the _socket module. + + This module is actually called "_socket", and there's a wrapper + "socket.py" which implements some additional functionality. + The import of "_socket" may fail with an ImportError exception if + os-specific initialization fails. On Windows, this does WINSOCK + initialization. When WINSOCK is initialized successfully, a call to + WSACleanup() is scheduled to be made at exit time. +*/ + +PyDoc_STRVAR(socket_doc, +"Implementation module for socket operations.\n\ +\n\ +See the socket module for documentation."); + +static struct PyModuleDef socketmodule = { + PyModuleDef_HEAD_INIT, + PySocket_MODULE_NAME, + socket_doc, + -1, + socket_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__socket(void) +{ + PyObject *m, *has_ipv6; + + if (!os_init()) + return NULL; + +#ifdef MS_WINDOWS + if (support_wsa_no_inherit == -1) { + support_wsa_no_inherit = IsWindows7SP1OrGreater(); + } +#endif + + Py_SET_TYPE(&sock_type, &PyType_Type); + m = PyModule_Create(&socketmodule); + if (m == NULL) + return NULL; + + Py_INCREF(PyExc_OSError); + PySocketModuleAPI.error = PyExc_OSError; + Py_INCREF(PyExc_OSError); + PyModule_AddObject(m, "error", PyExc_OSError); + socket_herror = PyErr_NewException("socket.herror", + PyExc_OSError, NULL); + if (socket_herror == NULL) + return NULL; + Py_INCREF(socket_herror); + PyModule_AddObject(m, "herror", socket_herror); + socket_gaierror = PyErr_NewException("socket.gaierror", PyExc_OSError, + NULL); + if (socket_gaierror == NULL) + return NULL; + Py_INCREF(socket_gaierror); + PyModule_AddObject(m, "gaierror", socket_gaierror); + socket_timeout = PyErr_NewException("socket.timeout", + PyExc_OSError, NULL); + if (socket_timeout == NULL) + return NULL; + PySocketModuleAPI.timeout_error = socket_timeout; + Py_INCREF(socket_timeout); + PyModule_AddObject(m, "timeout", socket_timeout); + Py_INCREF((PyObject *)&sock_type); + if (PyModule_AddObject(m, "SocketType", + (PyObject *)&sock_type) != 0) + return NULL; + Py_INCREF((PyObject *)&sock_type); + if (PyModule_AddObject(m, "socket", + (PyObject *)&sock_type) != 0) + return NULL; + +#ifdef ENABLE_IPV6 + has_ipv6 = Py_True; +#else + has_ipv6 = Py_False; +#endif + Py_INCREF(has_ipv6); + PyModule_AddObject(m, "has_ipv6", has_ipv6); + + /* Export C API */ + if (PyModule_AddObject(m, PySocket_CAPI_NAME, + PyCapsule_New(&PySocketModuleAPI, PySocket_CAPSULE_NAME, NULL) + ) != 0) + return NULL; + + /* Address families (we only support AF_INET and AF_UNIX) */ +#ifdef AF_UNSPEC + PyModule_AddIntMacro(m, AF_UNSPEC); +#endif + PyModule_AddIntMacro(m, AF_INET); +#if defined(AF_UNIX) + PyModule_AddIntMacro(m, AF_UNIX); +#endif /* AF_UNIX */ +#ifdef AF_AX25 + /* Amateur Radio AX.25 */ + PyModule_AddIntMacro(m, AF_AX25); +#endif +#ifdef AF_IPX + PyModule_AddIntMacro(m, AF_IPX); /* Novell IPX */ +#endif +#ifdef AF_APPLETALK + /* Appletalk DDP */ + PyModule_AddIntMacro(m, AF_APPLETALK); +#endif +#ifdef AF_NETROM + /* Amateur radio NetROM */ + PyModule_AddIntMacro(m, AF_NETROM); +#endif +#ifdef AF_BRIDGE + /* Multiprotocol bridge */ + PyModule_AddIntMacro(m, AF_BRIDGE); +#endif +#ifdef AF_ATMPVC + /* ATM PVCs */ + PyModule_AddIntMacro(m, AF_ATMPVC); +#endif +#ifdef AF_AAL5 + /* Reserved for Werner's ATM */ + PyModule_AddIntMacro(m, AF_AAL5); +#endif +#ifdef HAVE_SOCKADDR_ALG + PyModule_AddIntMacro(m, AF_ALG); /* Linux crypto */ +#endif +#ifdef AF_X25 + /* Reserved for X.25 project */ + PyModule_AddIntMacro(m, AF_X25); +#endif +#ifdef AF_INET6 + PyModule_AddIntMacro(m, AF_INET6); /* IP version 6 */ +#endif +#ifdef AF_ROSE + /* Amateur Radio X.25 PLP */ + PyModule_AddIntMacro(m, AF_ROSE); +#endif +#ifdef AF_DECnet + /* Reserved for DECnet project */ + PyModule_AddIntMacro(m, AF_DECnet); +#endif +#ifdef AF_NETBEUI + /* Reserved for 802.2LLC project */ + PyModule_AddIntMacro(m, AF_NETBEUI); +#endif +#ifdef AF_SECURITY + /* Security callback pseudo AF */ + PyModule_AddIntMacro(m, AF_SECURITY); +#endif +#ifdef AF_KEY + /* PF_KEY key management API */ + PyModule_AddIntMacro(m, AF_KEY); +#endif +#ifdef AF_NETLINK + /* */ + PyModule_AddIntMacro(m, AF_NETLINK); + PyModule_AddIntMacro(m, NETLINK_ROUTE); +#ifdef NETLINK_SKIP + PyModule_AddIntMacro(m, NETLINK_SKIP); +#endif +#ifdef NETLINK_W1 + PyModule_AddIntMacro(m, NETLINK_W1); +#endif + PyModule_AddIntMacro(m, NETLINK_USERSOCK); + PyModule_AddIntMacro(m, NETLINK_FIREWALL); +#ifdef NETLINK_TCPDIAG + PyModule_AddIntMacro(m, NETLINK_TCPDIAG); +#endif +#ifdef NETLINK_NFLOG + PyModule_AddIntMacro(m, NETLINK_NFLOG); +#endif +#ifdef NETLINK_XFRM + PyModule_AddIntMacro(m, NETLINK_XFRM); +#endif +#ifdef NETLINK_ARPD + PyModule_AddIntMacro(m, NETLINK_ARPD); +#endif +#ifdef NETLINK_ROUTE6 + PyModule_AddIntMacro(m, NETLINK_ROUTE6); +#endif + PyModule_AddIntMacro(m, NETLINK_IP6_FW); +#ifdef NETLINK_DNRTMSG + PyModule_AddIntMacro(m, NETLINK_DNRTMSG); +#endif +#ifdef NETLINK_TAPBASE + PyModule_AddIntMacro(m, NETLINK_TAPBASE); +#endif +#ifdef NETLINK_CRYPTO + PyModule_AddIntMacro(m, NETLINK_CRYPTO); +#endif +#endif /* AF_NETLINK */ + +#ifdef AF_QIPCRTR + /* Qualcomm IPCROUTER */ + PyModule_AddIntMacro(m, AF_QIPCRTR); #endif -#ifdef HAVE_LINUX_CAN_H - PyModule_AddIntMacro(m, CAN_EFF_FLAG); - PyModule_AddIntMacro(m, CAN_RTR_FLAG); - PyModule_AddIntMacro(m, CAN_ERR_FLAG); - PyModule_AddIntMacro(m, CAN_SFF_MASK); - PyModule_AddIntMacro(m, CAN_EFF_MASK); - PyModule_AddIntMacro(m, CAN_ERR_MASK); -#ifdef CAN_ISOTP - PyModule_AddIntMacro(m, CAN_ISOTP); -#endif +#ifdef AF_VSOCK + PyModule_AddIntConstant(m, "AF_VSOCK", AF_VSOCK); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_SIZE", 0); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MIN_SIZE", 1); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MAX_SIZE", 2); + PyModule_AddIntConstant(m, "VMADDR_CID_ANY", 0xffffffff); + PyModule_AddIntConstant(m, "VMADDR_PORT_ANY", 0xffffffff); + PyModule_AddIntConstant(m, "VMADDR_CID_HOST", 2); + PyModule_AddIntConstant(m, "VM_SOCKETS_INVALID_VERSION", 0xffffffff); + PyModule_AddIntConstant(m, "IOCTL_VM_SOCKETS_GET_LOCAL_CID", _IO(7, 0xb9)); +#endif + +#ifdef AF_ROUTE + /* Alias to emulate 4.4BSD */ + PyModule_AddIntMacro(m, AF_ROUTE); +#endif +#ifdef AF_LINK + PyModule_AddIntMacro(m, AF_LINK); +#endif +#ifdef AF_ASH + /* Ash */ + PyModule_AddIntMacro(m, AF_ASH); +#endif +#ifdef AF_ECONET + /* Acorn Econet */ + PyModule_AddIntMacro(m, AF_ECONET); +#endif +#ifdef AF_ATMSVC + /* ATM SVCs */ + PyModule_AddIntMacro(m, AF_ATMSVC); +#endif +#ifdef AF_SNA + /* Linux SNA Project (nutters!) */ + PyModule_AddIntMacro(m, AF_SNA); +#endif +#ifdef AF_IRDA + /* IRDA sockets */ + PyModule_AddIntMacro(m, AF_IRDA); +#endif +#ifdef AF_PPPOX + /* PPPoX sockets */ + PyModule_AddIntMacro(m, AF_PPPOX); +#endif +#ifdef AF_WANPIPE + /* Wanpipe API Sockets */ + PyModule_AddIntMacro(m, AF_WANPIPE); +#endif +#ifdef AF_LLC + /* Linux LLC */ + PyModule_AddIntMacro(m, AF_LLC); +#endif + +#ifdef USE_BLUETOOTH + PyModule_AddIntMacro(m, AF_BLUETOOTH); +#ifdef BTPROTO_L2CAP + PyModule_AddIntMacro(m, BTPROTO_L2CAP); +#endif /* BTPROTO_L2CAP */ +#ifdef BTPROTO_HCI + PyModule_AddIntMacro(m, BTPROTO_HCI); + PyModule_AddIntMacro(m, SOL_HCI); +#if !defined(__NetBSD__) && !defined(__DragonFly__) + PyModule_AddIntMacro(m, HCI_FILTER); +#if !defined(__FreeBSD__) + PyModule_AddIntMacro(m, HCI_TIME_STAMP); + PyModule_AddIntMacro(m, HCI_DATA_DIR); +#endif /* !__FreeBSD__ */ +#endif /* !__NetBSD__ && !__DragonFly__ */ +#endif /* BTPROTO_HCI */ +#ifdef BTPROTO_RFCOMM + PyModule_AddIntMacro(m, BTPROTO_RFCOMM); +#endif /* BTPROTO_RFCOMM */ + PyModule_AddStringConstant(m, "BDADDR_ANY", "00:00:00:00:00:00"); + PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF"); +#ifdef BTPROTO_SCO + PyModule_AddIntMacro(m, BTPROTO_SCO); +#endif /* BTPROTO_SCO */ +#endif /* USE_BLUETOOTH */ + +#ifdef AF_CAN + /* Controller Area Network */ + PyModule_AddIntMacro(m, AF_CAN); +#endif +#ifdef PF_CAN + /* Controller Area Network */ + PyModule_AddIntMacro(m, PF_CAN); +#endif + +/* Reliable Datagram Sockets */ +#ifdef AF_RDS + PyModule_AddIntMacro(m, AF_RDS); +#endif +#ifdef PF_RDS + PyModule_AddIntMacro(m, PF_RDS); +#endif + +/* Kernel event messages */ +#ifdef PF_SYSTEM + PyModule_AddIntMacro(m, PF_SYSTEM); +#endif +#ifdef AF_SYSTEM + PyModule_AddIntMacro(m, AF_SYSTEM); +#endif + +#ifdef AF_PACKET + PyModule_AddIntMacro(m, AF_PACKET); +#endif +#ifdef PF_PACKET + PyModule_AddIntMacro(m, PF_PACKET); +#endif +#ifdef PACKET_HOST + PyModule_AddIntMacro(m, PACKET_HOST); +#endif +#ifdef PACKET_BROADCAST + PyModule_AddIntMacro(m, PACKET_BROADCAST); +#endif +#ifdef PACKET_MULTICAST + PyModule_AddIntMacro(m, PACKET_MULTICAST); +#endif +#ifdef PACKET_OTHERHOST + PyModule_AddIntMacro(m, PACKET_OTHERHOST); +#endif +#ifdef PACKET_OUTGOING + PyModule_AddIntMacro(m, PACKET_OUTGOING); +#endif +#ifdef PACKET_LOOPBACK + PyModule_AddIntMacro(m, PACKET_LOOPBACK); +#endif +#ifdef PACKET_FASTROUTE + PyModule_AddIntMacro(m, PACKET_FASTROUTE); +#endif + +#ifdef HAVE_LINUX_TIPC_H + PyModule_AddIntMacro(m, AF_TIPC); + + /* for addresses */ + PyModule_AddIntMacro(m, TIPC_ADDR_NAMESEQ); + PyModule_AddIntMacro(m, TIPC_ADDR_NAME); + PyModule_AddIntMacro(m, TIPC_ADDR_ID); + + PyModule_AddIntMacro(m, TIPC_ZONE_SCOPE); + PyModule_AddIntMacro(m, TIPC_CLUSTER_SCOPE); + PyModule_AddIntMacro(m, TIPC_NODE_SCOPE); + + /* for setsockopt() */ + PyModule_AddIntMacro(m, SOL_TIPC); + PyModule_AddIntMacro(m, TIPC_IMPORTANCE); + PyModule_AddIntMacro(m, TIPC_SRC_DROPPABLE); + PyModule_AddIntMacro(m, TIPC_DEST_DROPPABLE); + PyModule_AddIntMacro(m, TIPC_CONN_TIMEOUT); + + PyModule_AddIntMacro(m, TIPC_LOW_IMPORTANCE); + PyModule_AddIntMacro(m, TIPC_MEDIUM_IMPORTANCE); + PyModule_AddIntMacro(m, TIPC_HIGH_IMPORTANCE); + PyModule_AddIntMacro(m, TIPC_CRITICAL_IMPORTANCE); + + /* for subscriptions */ + PyModule_AddIntMacro(m, TIPC_SUB_PORTS); + PyModule_AddIntMacro(m, TIPC_SUB_SERVICE); +#ifdef TIPC_SUB_CANCEL + /* doesn't seem to be available everywhere */ + PyModule_AddIntMacro(m, TIPC_SUB_CANCEL); +#endif + PyModule_AddIntMacro(m, TIPC_WAIT_FOREVER); + PyModule_AddIntMacro(m, TIPC_PUBLISHED); + PyModule_AddIntMacro(m, TIPC_WITHDRAWN); + PyModule_AddIntMacro(m, TIPC_SUBSCR_TIMEOUT); + PyModule_AddIntMacro(m, TIPC_CFG_SRV); + PyModule_AddIntMacro(m, TIPC_TOP_SRV); +#endif + +#ifdef HAVE_SOCKADDR_ALG + /* Socket options */ + PyModule_AddIntMacro(m, ALG_SET_KEY); + PyModule_AddIntMacro(m, ALG_SET_IV); + PyModule_AddIntMacro(m, ALG_SET_OP); + PyModule_AddIntMacro(m, ALG_SET_AEAD_ASSOCLEN); + PyModule_AddIntMacro(m, ALG_SET_AEAD_AUTHSIZE); + PyModule_AddIntMacro(m, ALG_SET_PUBKEY); + + /* Operations */ + PyModule_AddIntMacro(m, ALG_OP_DECRYPT); + PyModule_AddIntMacro(m, ALG_OP_ENCRYPT); + PyModule_AddIntMacro(m, ALG_OP_SIGN); + PyModule_AddIntMacro(m, ALG_OP_VERIFY); +#endif + + /* Socket types */ + PyModule_AddIntMacro(m, SOCK_STREAM); + PyModule_AddIntMacro(m, SOCK_DGRAM); +/* We have incomplete socket support. */ +#ifdef SOCK_RAW + /* SOCK_RAW is marked as optional in the POSIX specification */ + PyModule_AddIntMacro(m, SOCK_RAW); +#endif + PyModule_AddIntMacro(m, SOCK_SEQPACKET); +#if defined(SOCK_RDM) + PyModule_AddIntMacro(m, SOCK_RDM); +#endif +#ifdef SOCK_CLOEXEC + PyModule_AddIntMacro(m, SOCK_CLOEXEC); +#endif +#ifdef SOCK_NONBLOCK + PyModule_AddIntMacro(m, SOCK_NONBLOCK); +#endif + +#ifdef SO_DEBUG + PyModule_AddIntMacro(m, SO_DEBUG); +#endif +#ifdef SO_ACCEPTCONN + PyModule_AddIntMacro(m, SO_ACCEPTCONN); +#endif +#ifdef SO_REUSEADDR + PyModule_AddIntMacro(m, SO_REUSEADDR); +#endif +#ifdef SO_EXCLUSIVEADDRUSE + PyModule_AddIntMacro(m, SO_EXCLUSIVEADDRUSE); +#endif + +#ifdef SO_KEEPALIVE + PyModule_AddIntMacro(m, SO_KEEPALIVE); +#endif +#ifdef SO_DONTROUTE + PyModule_AddIntMacro(m, SO_DONTROUTE); +#endif +#ifdef SO_BROADCAST + PyModule_AddIntMacro(m, SO_BROADCAST); +#endif +#ifdef SO_USELOOPBACK + PyModule_AddIntMacro(m, SO_USELOOPBACK); +#endif +#ifdef SO_LINGER + PyModule_AddIntMacro(m, SO_LINGER); +#endif +#ifdef SO_OOBINLINE + PyModule_AddIntMacro(m, SO_OOBINLINE); +#endif +#ifndef __GNU__ +#ifdef SO_REUSEPORT + if (IsReusePortAvailable()) + PyModule_AddIntMacro(m, SO_REUSEPORT); +#endif +#endif +#ifdef SO_SNDBUF + PyModule_AddIntMacro(m, SO_SNDBUF); +#endif +#ifdef SO_RCVBUF + PyModule_AddIntMacro(m, SO_RCVBUF); +#endif +#ifdef SO_SNDLOWAT + PyModule_AddIntMacro(m, SO_SNDLOWAT); +#endif +#ifdef SO_RCVLOWAT + PyModule_AddIntMacro(m, SO_RCVLOWAT); +#endif +#ifdef SO_SNDTIMEO + PyModule_AddIntMacro(m, SO_SNDTIMEO); +#endif +#ifdef SO_RCVTIMEO + PyModule_AddIntMacro(m, SO_RCVTIMEO); +#endif +#ifdef SO_ERROR + PyModule_AddIntMacro(m, SO_ERROR); +#endif +#ifdef SO_TYPE + PyModule_AddIntMacro(m, SO_TYPE); +#endif +#ifdef SO_SETFIB + PyModule_AddIntMacro(m, SO_SETFIB); +#endif +#ifdef SO_PASSCRED + PyModule_AddIntMacro(m, SO_PASSCRED); +#endif +#ifdef SO_PEERCRED + PyModule_AddIntMacro(m, SO_PEERCRED); +#endif +#ifdef LOCAL_PEERCRED + PyModule_AddIntMacro(m, LOCAL_PEERCRED); +#endif +#ifdef SO_PASSSEC + PyModule_AddIntMacro(m, SO_PASSSEC); +#endif +#ifdef SO_PEERSEC + PyModule_AddIntMacro(m, SO_PEERSEC); +#endif +#ifdef SO_BINDTODEVICE + PyModule_AddIntMacro(m, SO_BINDTODEVICE); +#endif +#ifdef SO_PRIORITY + PyModule_AddIntMacro(m, SO_PRIORITY); +#endif +#ifdef SO_MARK + PyModule_AddIntMacro(m, SO_MARK); +#endif +#ifdef SO_DOMAIN + PyModule_AddIntMacro(m, SO_DOMAIN); +#endif +#ifdef SO_PROTOCOL + PyModule_AddIntMacro(m, SO_PROTOCOL); +#endif + + /* Maximum number of connections for "listen" */ +#ifdef SOMAXCONN + PyModule_AddIntMacro(m, SOMAXCONN); +#else + PyModule_AddIntConstant(m, "SOMAXCONN", 5); /* Common value */ +#endif + + /* Ancillary message types */ +#ifdef SCM_RIGHTS + PyModule_AddIntMacro(m, SCM_RIGHTS); +#endif +#ifdef SCM_CREDENTIALS + PyModule_AddIntMacro(m, SCM_CREDENTIALS); +#endif +#ifdef SCM_CREDS + PyModule_AddIntMacro(m, SCM_CREDS); +#endif + + /* Flags for send, recv */ +#ifdef MSG_OOB + PyModule_AddIntMacro(m, MSG_OOB); +#endif +#ifdef MSG_PEEK + PyModule_AddIntMacro(m, MSG_PEEK); +#endif +#ifdef MSG_DONTROUTE + PyModule_AddIntMacro(m, MSG_DONTROUTE); +#endif +#ifdef MSG_DONTWAIT + PyModule_AddIntMacro(m, MSG_DONTWAIT); +#endif +#ifdef MSG_EOR + PyModule_AddIntMacro(m, MSG_EOR); +#endif +#ifdef MSG_TRUNC + PyModule_AddIntMacro(m, MSG_TRUNC); +#endif +#ifdef MSG_CTRUNC + PyModule_AddIntMacro(m, MSG_CTRUNC); +#endif +#ifdef MSG_WAITALL + PyModule_AddIntMacro(m, MSG_WAITALL); +#endif +#ifdef MSG_BTAG + PyModule_AddIntMacro(m, MSG_BTAG); +#endif +#ifdef MSG_ETAG + PyModule_AddIntMacro(m, MSG_ETAG); +#endif +#ifdef MSG_NOSIGNAL + PyModule_AddIntMacro(m, MSG_NOSIGNAL); +#endif +#ifdef MSG_NOTIFICATION + PyModule_AddIntMacro(m, MSG_NOTIFICATION); +#endif +#ifdef MSG_CMSG_CLOEXEC + PyModule_AddIntMacro(m, MSG_CMSG_CLOEXEC); +#endif +#ifdef MSG_ERRQUEUE + PyModule_AddIntMacro(m, MSG_ERRQUEUE); +#endif +#ifdef MSG_CONFIRM + PyModule_AddIntMacro(m, MSG_CONFIRM); +#endif +#ifdef MSG_MORE + PyModule_AddIntMacro(m, MSG_MORE); +#endif +#ifdef MSG_EOF + PyModule_AddIntMacro(m, MSG_EOF); +#endif +#ifdef MSG_BCAST + PyModule_AddIntMacro(m, MSG_BCAST); +#endif +#ifdef MSG_MCAST + PyModule_AddIntMacro(m, MSG_MCAST); +#endif +#ifdef MSG_FASTOPEN + PyModule_AddIntMacro(m, MSG_FASTOPEN); +#endif + + /* Protocol level and numbers, usable for [gs]etsockopt */ +#ifdef SOL_SOCKET + PyModule_AddIntMacro(m, SOL_SOCKET); +#endif +#ifdef SOL_IP + PyModule_AddIntMacro(m, SOL_IP); +#else + PyModule_AddIntConstant(m, "SOL_IP", 0); +#endif +#ifdef SOL_IPX + PyModule_AddIntMacro(m, SOL_IPX); +#endif +#ifdef SOL_AX25 + PyModule_AddIntMacro(m, SOL_AX25); +#endif +#ifdef SOL_ATALK + PyModule_AddIntMacro(m, SOL_ATALK); +#endif +#ifdef SOL_NETROM + PyModule_AddIntMacro(m, SOL_NETROM); +#endif +#ifdef SOL_ROSE + PyModule_AddIntMacro(m, SOL_ROSE); +#endif +#ifdef SOL_TCP + PyModule_AddIntMacro(m, SOL_TCP); +#else + PyModule_AddIntConstant(m, "SOL_TCP", 6); +#endif +#ifdef SOL_UDP + PyModule_AddIntMacro(m, SOL_UDP); +#else + PyModule_AddIntConstant(m, "SOL_UDP", 17); +#endif +#ifdef SOL_CAN_BASE + PyModule_AddIntMacro(m, SOL_CAN_BASE); +#endif +#ifdef SOL_CAN_RAW + PyModule_AddIntMacro(m, SOL_CAN_RAW); + PyModule_AddIntMacro(m, CAN_RAW); +#endif +#ifdef HAVE_LINUX_CAN_H + PyModule_AddIntMacro(m, CAN_EFF_FLAG); + PyModule_AddIntMacro(m, CAN_RTR_FLAG); + PyModule_AddIntMacro(m, CAN_ERR_FLAG); + + PyModule_AddIntMacro(m, CAN_SFF_MASK); + PyModule_AddIntMacro(m, CAN_EFF_MASK); + PyModule_AddIntMacro(m, CAN_ERR_MASK); +#ifdef CAN_ISOTP + PyModule_AddIntMacro(m, CAN_ISOTP); +#endif #ifdef CAN_J1939 PyModule_AddIntMacro(m, CAN_J1939); -#endif -#endif -#ifdef HAVE_LINUX_CAN_RAW_H - PyModule_AddIntMacro(m, CAN_RAW_FILTER); - PyModule_AddIntMacro(m, CAN_RAW_ERR_FILTER); - PyModule_AddIntMacro(m, CAN_RAW_LOOPBACK); - PyModule_AddIntMacro(m, CAN_RAW_RECV_OWN_MSGS); -#endif -#ifdef HAVE_LINUX_CAN_RAW_FD_FRAMES - PyModule_AddIntMacro(m, CAN_RAW_FD_FRAMES); -#endif +#endif +#endif +#ifdef HAVE_LINUX_CAN_RAW_H + PyModule_AddIntMacro(m, CAN_RAW_FILTER); + PyModule_AddIntMacro(m, CAN_RAW_ERR_FILTER); + PyModule_AddIntMacro(m, CAN_RAW_LOOPBACK); + PyModule_AddIntMacro(m, CAN_RAW_RECV_OWN_MSGS); +#endif +#ifdef HAVE_LINUX_CAN_RAW_FD_FRAMES + PyModule_AddIntMacro(m, CAN_RAW_FD_FRAMES); +#endif #ifdef HAVE_LINUX_CAN_RAW_JOIN_FILTERS PyModule_AddIntMacro(m, CAN_RAW_JOIN_FILTERS); #endif -#ifdef HAVE_LINUX_CAN_BCM_H - PyModule_AddIntMacro(m, CAN_BCM); +#ifdef HAVE_LINUX_CAN_BCM_H + PyModule_AddIntMacro(m, CAN_BCM); /* BCM opcodes */ - PyModule_AddIntConstant(m, "CAN_BCM_TX_SETUP", TX_SETUP); - PyModule_AddIntConstant(m, "CAN_BCM_TX_DELETE", TX_DELETE); - PyModule_AddIntConstant(m, "CAN_BCM_TX_READ", TX_READ); - PyModule_AddIntConstant(m, "CAN_BCM_TX_SEND", TX_SEND); - PyModule_AddIntConstant(m, "CAN_BCM_RX_SETUP", RX_SETUP); - PyModule_AddIntConstant(m, "CAN_BCM_RX_DELETE", RX_DELETE); - PyModule_AddIntConstant(m, "CAN_BCM_RX_READ", RX_READ); - PyModule_AddIntConstant(m, "CAN_BCM_TX_STATUS", TX_STATUS); - PyModule_AddIntConstant(m, "CAN_BCM_TX_EXPIRED", TX_EXPIRED); - PyModule_AddIntConstant(m, "CAN_BCM_RX_STATUS", RX_STATUS); - PyModule_AddIntConstant(m, "CAN_BCM_RX_TIMEOUT", RX_TIMEOUT); - PyModule_AddIntConstant(m, "CAN_BCM_RX_CHANGED", RX_CHANGED); + PyModule_AddIntConstant(m, "CAN_BCM_TX_SETUP", TX_SETUP); + PyModule_AddIntConstant(m, "CAN_BCM_TX_DELETE", TX_DELETE); + PyModule_AddIntConstant(m, "CAN_BCM_TX_READ", TX_READ); + PyModule_AddIntConstant(m, "CAN_BCM_TX_SEND", TX_SEND); + PyModule_AddIntConstant(m, "CAN_BCM_RX_SETUP", RX_SETUP); + PyModule_AddIntConstant(m, "CAN_BCM_RX_DELETE", RX_DELETE); + PyModule_AddIntConstant(m, "CAN_BCM_RX_READ", RX_READ); + PyModule_AddIntConstant(m, "CAN_BCM_TX_STATUS", TX_STATUS); + PyModule_AddIntConstant(m, "CAN_BCM_TX_EXPIRED", TX_EXPIRED); + PyModule_AddIntConstant(m, "CAN_BCM_RX_STATUS", RX_STATUS); + PyModule_AddIntConstant(m, "CAN_BCM_RX_TIMEOUT", RX_TIMEOUT); + PyModule_AddIntConstant(m, "CAN_BCM_RX_CHANGED", RX_CHANGED); /* BCM flags */ PyModule_AddIntConstant(m, "CAN_BCM_SETTIMER", SETTIMER); @@ -7799,7 +7799,7 @@ PyInit__socket(void) #ifdef CAN_FD_FRAME /* CAN_FD_FRAME was only introduced in the 4.8.x kernel series */ PyModule_AddIntConstant(m, "CAN_BCM_CAN_FD_FRAME", CAN_FD_FRAME); -#endif +#endif #endif #ifdef HAVE_LINUX_CAN_J1939_H PyModule_AddIntMacro(m, J1939_MAX_UNICAST_ADDR); @@ -7832,74 +7832,74 @@ PyInit__socket(void) PyModule_AddIntMacro(m, J1939_FILTER_MAX); #endif -#ifdef SOL_RDS - PyModule_AddIntMacro(m, SOL_RDS); -#endif -#ifdef HAVE_SOCKADDR_ALG - PyModule_AddIntMacro(m, SOL_ALG); -#endif -#ifdef RDS_CANCEL_SENT_TO - PyModule_AddIntMacro(m, RDS_CANCEL_SENT_TO); -#endif -#ifdef RDS_GET_MR - PyModule_AddIntMacro(m, RDS_GET_MR); -#endif -#ifdef RDS_FREE_MR - PyModule_AddIntMacro(m, RDS_FREE_MR); -#endif -#ifdef RDS_RECVERR - PyModule_AddIntMacro(m, RDS_RECVERR); -#endif -#ifdef RDS_CONG_MONITOR - PyModule_AddIntMacro(m, RDS_CONG_MONITOR); -#endif -#ifdef RDS_GET_MR_FOR_DEST - PyModule_AddIntMacro(m, RDS_GET_MR_FOR_DEST); -#endif -#ifdef IPPROTO_IP - PyModule_AddIntMacro(m, IPPROTO_IP); -#else - PyModule_AddIntConstant(m, "IPPROTO_IP", 0); -#endif -#ifdef IPPROTO_HOPOPTS - PyModule_AddIntMacro(m, IPPROTO_HOPOPTS); -#endif -#ifdef IPPROTO_ICMP - PyModule_AddIntMacro(m, IPPROTO_ICMP); -#else - PyModule_AddIntConstant(m, "IPPROTO_ICMP", 1); -#endif -#ifdef IPPROTO_IGMP - PyModule_AddIntMacro(m, IPPROTO_IGMP); -#endif -#ifdef IPPROTO_GGP - PyModule_AddIntMacro(m, IPPROTO_GGP); -#endif -#ifdef IPPROTO_IPV4 - PyModule_AddIntMacro(m, IPPROTO_IPV4); -#endif -#ifdef IPPROTO_IPV6 - PyModule_AddIntMacro(m, IPPROTO_IPV6); -#endif -#ifdef IPPROTO_IPIP - PyModule_AddIntMacro(m, IPPROTO_IPIP); -#endif -#ifdef IPPROTO_TCP - PyModule_AddIntMacro(m, IPPROTO_TCP); -#else - PyModule_AddIntConstant(m, "IPPROTO_TCP", 6); -#endif -#ifdef IPPROTO_EGP - PyModule_AddIntMacro(m, IPPROTO_EGP); -#endif -#ifdef IPPROTO_PUP - PyModule_AddIntMacro(m, IPPROTO_PUP); -#endif -#ifdef IPPROTO_UDP - PyModule_AddIntMacro(m, IPPROTO_UDP); -#else - PyModule_AddIntConstant(m, "IPPROTO_UDP", 17); -#endif +#ifdef SOL_RDS + PyModule_AddIntMacro(m, SOL_RDS); +#endif +#ifdef HAVE_SOCKADDR_ALG + PyModule_AddIntMacro(m, SOL_ALG); +#endif +#ifdef RDS_CANCEL_SENT_TO + PyModule_AddIntMacro(m, RDS_CANCEL_SENT_TO); +#endif +#ifdef RDS_GET_MR + PyModule_AddIntMacro(m, RDS_GET_MR); +#endif +#ifdef RDS_FREE_MR + PyModule_AddIntMacro(m, RDS_FREE_MR); +#endif +#ifdef RDS_RECVERR + PyModule_AddIntMacro(m, RDS_RECVERR); +#endif +#ifdef RDS_CONG_MONITOR + PyModule_AddIntMacro(m, RDS_CONG_MONITOR); +#endif +#ifdef RDS_GET_MR_FOR_DEST + PyModule_AddIntMacro(m, RDS_GET_MR_FOR_DEST); +#endif +#ifdef IPPROTO_IP + PyModule_AddIntMacro(m, IPPROTO_IP); +#else + PyModule_AddIntConstant(m, "IPPROTO_IP", 0); +#endif +#ifdef IPPROTO_HOPOPTS + PyModule_AddIntMacro(m, IPPROTO_HOPOPTS); +#endif +#ifdef IPPROTO_ICMP + PyModule_AddIntMacro(m, IPPROTO_ICMP); +#else + PyModule_AddIntConstant(m, "IPPROTO_ICMP", 1); +#endif +#ifdef IPPROTO_IGMP + PyModule_AddIntMacro(m, IPPROTO_IGMP); +#endif +#ifdef IPPROTO_GGP + PyModule_AddIntMacro(m, IPPROTO_GGP); +#endif +#ifdef IPPROTO_IPV4 + PyModule_AddIntMacro(m, IPPROTO_IPV4); +#endif +#ifdef IPPROTO_IPV6 + PyModule_AddIntMacro(m, IPPROTO_IPV6); +#endif +#ifdef IPPROTO_IPIP + PyModule_AddIntMacro(m, IPPROTO_IPIP); +#endif +#ifdef IPPROTO_TCP + PyModule_AddIntMacro(m, IPPROTO_TCP); +#else + PyModule_AddIntConstant(m, "IPPROTO_TCP", 6); +#endif +#ifdef IPPROTO_EGP + PyModule_AddIntMacro(m, IPPROTO_EGP); +#endif +#ifdef IPPROTO_PUP + PyModule_AddIntMacro(m, IPPROTO_PUP); +#endif +#ifdef IPPROTO_UDP + PyModule_AddIntMacro(m, IPPROTO_UDP); +#else + PyModule_AddIntConstant(m, "IPPROTO_UDP", 17); +#endif #ifdef IPPROTO_UDPLITE PyModule_AddIntMacro(m, IPPROTO_UDPLITE); #ifndef UDPLITE_SEND_CSCOV @@ -7911,79 +7911,79 @@ PyInit__socket(void) #endif PyModule_AddIntMacro(m, UDPLITE_RECV_CSCOV); #endif -#ifdef IPPROTO_IDP - PyModule_AddIntMacro(m, IPPROTO_IDP); -#endif -#ifdef IPPROTO_HELLO - PyModule_AddIntMacro(m, IPPROTO_HELLO); -#endif -#ifdef IPPROTO_ND - PyModule_AddIntMacro(m, IPPROTO_ND); -#endif -#ifdef IPPROTO_TP - PyModule_AddIntMacro(m, IPPROTO_TP); -#endif -#ifdef IPPROTO_ROUTING - PyModule_AddIntMacro(m, IPPROTO_ROUTING); -#endif -#ifdef IPPROTO_FRAGMENT - PyModule_AddIntMacro(m, IPPROTO_FRAGMENT); -#endif -#ifdef IPPROTO_RSVP - PyModule_AddIntMacro(m, IPPROTO_RSVP); -#endif -#ifdef IPPROTO_GRE - PyModule_AddIntMacro(m, IPPROTO_GRE); -#endif -#ifdef IPPROTO_ESP - PyModule_AddIntMacro(m, IPPROTO_ESP); -#endif -#ifdef IPPROTO_AH - PyModule_AddIntMacro(m, IPPROTO_AH); -#endif -#ifdef IPPROTO_MOBILE - PyModule_AddIntMacro(m, IPPROTO_MOBILE); -#endif -#ifdef IPPROTO_ICMPV6 - PyModule_AddIntMacro(m, IPPROTO_ICMPV6); -#endif -#ifdef IPPROTO_NONE - PyModule_AddIntMacro(m, IPPROTO_NONE); -#endif -#ifdef IPPROTO_DSTOPTS - PyModule_AddIntMacro(m, IPPROTO_DSTOPTS); -#endif -#ifdef IPPROTO_XTP - PyModule_AddIntMacro(m, IPPROTO_XTP); -#endif -#ifdef IPPROTO_EON - PyModule_AddIntMacro(m, IPPROTO_EON); -#endif -#ifdef IPPROTO_PIM - PyModule_AddIntMacro(m, IPPROTO_PIM); -#endif -#ifdef IPPROTO_IPCOMP - PyModule_AddIntMacro(m, IPPROTO_IPCOMP); -#endif -#ifdef IPPROTO_VRRP - PyModule_AddIntMacro(m, IPPROTO_VRRP); -#endif -#ifdef IPPROTO_SCTP - PyModule_AddIntMacro(m, IPPROTO_SCTP); -#endif -#ifdef IPPROTO_BIP - PyModule_AddIntMacro(m, IPPROTO_BIP); -#endif -/**/ -#ifdef IPPROTO_RAW - PyModule_AddIntMacro(m, IPPROTO_RAW); -#else - PyModule_AddIntConstant(m, "IPPROTO_RAW", 255); -#endif -#ifdef IPPROTO_MAX - PyModule_AddIntMacro(m, IPPROTO_MAX); -#endif - +#ifdef IPPROTO_IDP + PyModule_AddIntMacro(m, IPPROTO_IDP); +#endif +#ifdef IPPROTO_HELLO + PyModule_AddIntMacro(m, IPPROTO_HELLO); +#endif +#ifdef IPPROTO_ND + PyModule_AddIntMacro(m, IPPROTO_ND); +#endif +#ifdef IPPROTO_TP + PyModule_AddIntMacro(m, IPPROTO_TP); +#endif +#ifdef IPPROTO_ROUTING + PyModule_AddIntMacro(m, IPPROTO_ROUTING); +#endif +#ifdef IPPROTO_FRAGMENT + PyModule_AddIntMacro(m, IPPROTO_FRAGMENT); +#endif +#ifdef IPPROTO_RSVP + PyModule_AddIntMacro(m, IPPROTO_RSVP); +#endif +#ifdef IPPROTO_GRE + PyModule_AddIntMacro(m, IPPROTO_GRE); +#endif +#ifdef IPPROTO_ESP + PyModule_AddIntMacro(m, IPPROTO_ESP); +#endif +#ifdef IPPROTO_AH + PyModule_AddIntMacro(m, IPPROTO_AH); +#endif +#ifdef IPPROTO_MOBILE + PyModule_AddIntMacro(m, IPPROTO_MOBILE); +#endif +#ifdef IPPROTO_ICMPV6 + PyModule_AddIntMacro(m, IPPROTO_ICMPV6); +#endif +#ifdef IPPROTO_NONE + PyModule_AddIntMacro(m, IPPROTO_NONE); +#endif +#ifdef IPPROTO_DSTOPTS + PyModule_AddIntMacro(m, IPPROTO_DSTOPTS); +#endif +#ifdef IPPROTO_XTP + PyModule_AddIntMacro(m, IPPROTO_XTP); +#endif +#ifdef IPPROTO_EON + PyModule_AddIntMacro(m, IPPROTO_EON); +#endif +#ifdef IPPROTO_PIM + PyModule_AddIntMacro(m, IPPROTO_PIM); +#endif +#ifdef IPPROTO_IPCOMP + PyModule_AddIntMacro(m, IPPROTO_IPCOMP); +#endif +#ifdef IPPROTO_VRRP + PyModule_AddIntMacro(m, IPPROTO_VRRP); +#endif +#ifdef IPPROTO_SCTP + PyModule_AddIntMacro(m, IPPROTO_SCTP); +#endif +#ifdef IPPROTO_BIP + PyModule_AddIntMacro(m, IPPROTO_BIP); +#endif +/**/ +#ifdef IPPROTO_RAW + PyModule_AddIntMacro(m, IPPROTO_RAW); +#else + PyModule_AddIntConstant(m, "IPPROTO_RAW", 255); +#endif +#ifdef IPPROTO_MAX + PyModule_AddIntMacro(m, IPPROTO_MAX); +#endif + #ifdef MS_WINDOWS PyModule_AddIntMacro(m, IPPROTO_ICLFXBM); PyModule_AddIntMacro(m, IPPROTO_ST); @@ -7995,453 +7995,453 @@ PyInit__socket(void) PyModule_AddIntMacro(m, IPPROTO_SCTP); #endif -#ifdef SYSPROTO_CONTROL - PyModule_AddIntMacro(m, SYSPROTO_CONTROL); -#endif - - /* Some port configuration */ -#ifdef IPPORT_RESERVED - PyModule_AddIntMacro(m, IPPORT_RESERVED); -#else - PyModule_AddIntConstant(m, "IPPORT_RESERVED", 1024); -#endif -#ifdef IPPORT_USERRESERVED - PyModule_AddIntMacro(m, IPPORT_USERRESERVED); -#else - PyModule_AddIntConstant(m, "IPPORT_USERRESERVED", 5000); -#endif - - /* Some reserved IP v.4 addresses */ -#ifdef INADDR_ANY - PyModule_AddIntMacro(m, INADDR_ANY); -#else - PyModule_AddIntConstant(m, "INADDR_ANY", 0x00000000); -#endif -#ifdef INADDR_BROADCAST - PyModule_AddIntMacro(m, INADDR_BROADCAST); -#else - PyModule_AddIntConstant(m, "INADDR_BROADCAST", 0xffffffff); -#endif -#ifdef INADDR_LOOPBACK - PyModule_AddIntMacro(m, INADDR_LOOPBACK); -#else - PyModule_AddIntConstant(m, "INADDR_LOOPBACK", 0x7F000001); -#endif -#ifdef INADDR_UNSPEC_GROUP - PyModule_AddIntMacro(m, INADDR_UNSPEC_GROUP); -#else - PyModule_AddIntConstant(m, "INADDR_UNSPEC_GROUP", 0xe0000000); -#endif -#ifdef INADDR_ALLHOSTS_GROUP - PyModule_AddIntConstant(m, "INADDR_ALLHOSTS_GROUP", - INADDR_ALLHOSTS_GROUP); -#else - PyModule_AddIntConstant(m, "INADDR_ALLHOSTS_GROUP", 0xe0000001); -#endif -#ifdef INADDR_MAX_LOCAL_GROUP - PyModule_AddIntMacro(m, INADDR_MAX_LOCAL_GROUP); -#else - PyModule_AddIntConstant(m, "INADDR_MAX_LOCAL_GROUP", 0xe00000ff); -#endif -#ifdef INADDR_NONE - PyModule_AddIntMacro(m, INADDR_NONE); -#else - PyModule_AddIntConstant(m, "INADDR_NONE", 0xffffffff); -#endif - - /* IPv4 [gs]etsockopt options */ -#ifdef IP_OPTIONS - PyModule_AddIntMacro(m, IP_OPTIONS); -#endif -#ifdef IP_HDRINCL - PyModule_AddIntMacro(m, IP_HDRINCL); -#endif -#ifdef IP_TOS - PyModule_AddIntMacro(m, IP_TOS); -#endif -#ifdef IP_TTL - PyModule_AddIntMacro(m, IP_TTL); -#endif -#ifdef IP_RECVOPTS - PyModule_AddIntMacro(m, IP_RECVOPTS); -#endif -#ifdef IP_RECVRETOPTS - PyModule_AddIntMacro(m, IP_RECVRETOPTS); -#endif -#ifdef IP_RECVDSTADDR - PyModule_AddIntMacro(m, IP_RECVDSTADDR); -#endif -#ifdef IP_RETOPTS - PyModule_AddIntMacro(m, IP_RETOPTS); -#endif -#ifdef IP_MULTICAST_IF - PyModule_AddIntMacro(m, IP_MULTICAST_IF); -#endif -#ifdef IP_MULTICAST_TTL - PyModule_AddIntMacro(m, IP_MULTICAST_TTL); -#endif -#ifdef IP_MULTICAST_LOOP - PyModule_AddIntMacro(m, IP_MULTICAST_LOOP); -#endif -#ifdef IP_ADD_MEMBERSHIP - PyModule_AddIntMacro(m, IP_ADD_MEMBERSHIP); -#endif -#ifdef IP_DROP_MEMBERSHIP - PyModule_AddIntMacro(m, IP_DROP_MEMBERSHIP); -#endif -#ifdef IP_DEFAULT_MULTICAST_TTL - PyModule_AddIntMacro(m, IP_DEFAULT_MULTICAST_TTL); -#endif -#ifdef IP_DEFAULT_MULTICAST_LOOP - PyModule_AddIntMacro(m, IP_DEFAULT_MULTICAST_LOOP); -#endif -#ifdef IP_MAX_MEMBERSHIPS - PyModule_AddIntMacro(m, IP_MAX_MEMBERSHIPS); -#endif -#ifdef IP_TRANSPARENT - PyModule_AddIntMacro(m, IP_TRANSPARENT); -#endif - - /* IPv6 [gs]etsockopt options, defined in RFC2553 */ -#ifdef IPV6_JOIN_GROUP - PyModule_AddIntMacro(m, IPV6_JOIN_GROUP); -#endif -#ifdef IPV6_LEAVE_GROUP - PyModule_AddIntMacro(m, IPV6_LEAVE_GROUP); -#endif -#ifdef IPV6_MULTICAST_HOPS - PyModule_AddIntMacro(m, IPV6_MULTICAST_HOPS); -#endif -#ifdef IPV6_MULTICAST_IF - PyModule_AddIntMacro(m, IPV6_MULTICAST_IF); -#endif -#ifdef IPV6_MULTICAST_LOOP - PyModule_AddIntMacro(m, IPV6_MULTICAST_LOOP); -#endif -#ifdef IPV6_UNICAST_HOPS - PyModule_AddIntMacro(m, IPV6_UNICAST_HOPS); -#endif - /* Additional IPV6 socket options, defined in RFC 3493 */ -#ifdef IPV6_V6ONLY - PyModule_AddIntMacro(m, IPV6_V6ONLY); -#endif - /* Advanced IPV6 socket options, from RFC 3542 */ -#ifdef IPV6_CHECKSUM - PyModule_AddIntMacro(m, IPV6_CHECKSUM); -#endif -#ifdef IPV6_DONTFRAG - PyModule_AddIntMacro(m, IPV6_DONTFRAG); -#endif -#ifdef IPV6_DSTOPTS - PyModule_AddIntMacro(m, IPV6_DSTOPTS); -#endif -#ifdef IPV6_HOPLIMIT - PyModule_AddIntMacro(m, IPV6_HOPLIMIT); -#endif -#ifdef IPV6_HOPOPTS - PyModule_AddIntMacro(m, IPV6_HOPOPTS); -#endif -#ifdef IPV6_NEXTHOP - PyModule_AddIntMacro(m, IPV6_NEXTHOP); -#endif -#ifdef IPV6_PATHMTU - PyModule_AddIntMacro(m, IPV6_PATHMTU); -#endif -#ifdef IPV6_PKTINFO - PyModule_AddIntMacro(m, IPV6_PKTINFO); -#endif -#ifdef IPV6_RECVDSTOPTS - PyModule_AddIntMacro(m, IPV6_RECVDSTOPTS); -#endif -#ifdef IPV6_RECVHOPLIMIT - PyModule_AddIntMacro(m, IPV6_RECVHOPLIMIT); -#endif -#ifdef IPV6_RECVHOPOPTS - PyModule_AddIntMacro(m, IPV6_RECVHOPOPTS); -#endif -#ifdef IPV6_RECVPKTINFO - PyModule_AddIntMacro(m, IPV6_RECVPKTINFO); -#endif -#ifdef IPV6_RECVRTHDR - PyModule_AddIntMacro(m, IPV6_RECVRTHDR); -#endif -#ifdef IPV6_RECVTCLASS - PyModule_AddIntMacro(m, IPV6_RECVTCLASS); -#endif -#ifdef IPV6_RTHDR - PyModule_AddIntMacro(m, IPV6_RTHDR); -#endif -#ifdef IPV6_RTHDRDSTOPTS - PyModule_AddIntMacro(m, IPV6_RTHDRDSTOPTS); -#endif -#ifdef IPV6_RTHDR_TYPE_0 - PyModule_AddIntMacro(m, IPV6_RTHDR_TYPE_0); -#endif -#ifdef IPV6_RECVPATHMTU - PyModule_AddIntMacro(m, IPV6_RECVPATHMTU); -#endif -#ifdef IPV6_TCLASS - PyModule_AddIntMacro(m, IPV6_TCLASS); -#endif -#ifdef IPV6_USE_MIN_MTU - PyModule_AddIntMacro(m, IPV6_USE_MIN_MTU); -#endif - - /* TCP options */ -#ifdef TCP_NODELAY - PyModule_AddIntMacro(m, TCP_NODELAY); -#endif -#ifdef TCP_MAXSEG - PyModule_AddIntMacro(m, TCP_MAXSEG); -#endif -#ifdef TCP_CORK - PyModule_AddIntMacro(m, TCP_CORK); -#endif -#ifdef TCP_KEEPIDLE - PyModule_AddIntMacro(m, TCP_KEEPIDLE); -#endif -#ifdef TCP_KEEPINTVL - PyModule_AddIntMacro(m, TCP_KEEPINTVL); -#endif -#ifdef TCP_KEEPCNT - PyModule_AddIntMacro(m, TCP_KEEPCNT); -#endif -#ifdef TCP_SYNCNT - PyModule_AddIntMacro(m, TCP_SYNCNT); -#endif -#ifdef TCP_LINGER2 - PyModule_AddIntMacro(m, TCP_LINGER2); -#endif -#ifdef TCP_DEFER_ACCEPT - PyModule_AddIntMacro(m, TCP_DEFER_ACCEPT); -#endif -#ifdef TCP_WINDOW_CLAMP - PyModule_AddIntMacro(m, TCP_WINDOW_CLAMP); -#endif -#ifdef TCP_INFO - PyModule_AddIntMacro(m, TCP_INFO); -#endif -#ifdef TCP_QUICKACK - PyModule_AddIntMacro(m, TCP_QUICKACK); -#endif -#ifdef TCP_FASTOPEN - PyModule_AddIntMacro(m, TCP_FASTOPEN); -#endif -#ifdef TCP_CONGESTION - PyModule_AddIntMacro(m, TCP_CONGESTION); -#endif -#ifdef TCP_USER_TIMEOUT - PyModule_AddIntMacro(m, TCP_USER_TIMEOUT); -#endif -#ifdef TCP_NOTSENT_LOWAT - PyModule_AddIntMacro(m, TCP_NOTSENT_LOWAT); -#endif - - /* IPX options */ -#ifdef IPX_TYPE - PyModule_AddIntMacro(m, IPX_TYPE); -#endif - -/* Reliable Datagram Sockets */ -#ifdef RDS_CMSG_RDMA_ARGS - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_ARGS); -#endif -#ifdef RDS_CMSG_RDMA_DEST - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_DEST); -#endif -#ifdef RDS_CMSG_RDMA_MAP - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_MAP); -#endif -#ifdef RDS_CMSG_RDMA_STATUS - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_STATUS); -#endif -#ifdef RDS_CMSG_RDMA_UPDATE - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_UPDATE); -#endif -#ifdef RDS_RDMA_READWRITE - PyModule_AddIntMacro(m, RDS_RDMA_READWRITE); -#endif -#ifdef RDS_RDMA_FENCE - PyModule_AddIntMacro(m, RDS_RDMA_FENCE); -#endif -#ifdef RDS_RDMA_INVALIDATE - PyModule_AddIntMacro(m, RDS_RDMA_INVALIDATE); -#endif -#ifdef RDS_RDMA_USE_ONCE - PyModule_AddIntMacro(m, RDS_RDMA_USE_ONCE); -#endif -#ifdef RDS_RDMA_DONTWAIT - PyModule_AddIntMacro(m, RDS_RDMA_DONTWAIT); -#endif -#ifdef RDS_RDMA_NOTIFY_ME - PyModule_AddIntMacro(m, RDS_RDMA_NOTIFY_ME); -#endif -#ifdef RDS_RDMA_SILENT - PyModule_AddIntMacro(m, RDS_RDMA_SILENT); -#endif - - /* get{addr,name}info parameters */ -#ifdef EAI_ADDRFAMILY - PyModule_AddIntMacro(m, EAI_ADDRFAMILY); -#endif -#ifdef EAI_AGAIN - PyModule_AddIntMacro(m, EAI_AGAIN); -#endif -#ifdef EAI_BADFLAGS - PyModule_AddIntMacro(m, EAI_BADFLAGS); -#endif -#ifdef EAI_FAIL - PyModule_AddIntMacro(m, EAI_FAIL); -#endif -#ifdef EAI_FAMILY - PyModule_AddIntMacro(m, EAI_FAMILY); -#endif -#ifdef EAI_MEMORY - PyModule_AddIntMacro(m, EAI_MEMORY); -#endif -#ifdef EAI_NODATA - PyModule_AddIntMacro(m, EAI_NODATA); -#endif -#ifdef EAI_NONAME - PyModule_AddIntMacro(m, EAI_NONAME); -#endif -#ifdef EAI_OVERFLOW - PyModule_AddIntMacro(m, EAI_OVERFLOW); -#endif -#ifdef EAI_SERVICE - PyModule_AddIntMacro(m, EAI_SERVICE); -#endif -#ifdef EAI_SOCKTYPE - PyModule_AddIntMacro(m, EAI_SOCKTYPE); -#endif -#ifdef EAI_SYSTEM - PyModule_AddIntMacro(m, EAI_SYSTEM); -#endif -#ifdef EAI_BADHINTS - PyModule_AddIntMacro(m, EAI_BADHINTS); -#endif -#ifdef EAI_PROTOCOL - PyModule_AddIntMacro(m, EAI_PROTOCOL); -#endif -#ifdef EAI_MAX - PyModule_AddIntMacro(m, EAI_MAX); -#endif -#ifdef AI_PASSIVE - PyModule_AddIntMacro(m, AI_PASSIVE); -#endif -#ifdef AI_CANONNAME - PyModule_AddIntMacro(m, AI_CANONNAME); -#endif -#ifdef AI_NUMERICHOST - PyModule_AddIntMacro(m, AI_NUMERICHOST); -#endif -#ifdef AI_NUMERICSERV - PyModule_AddIntMacro(m, AI_NUMERICSERV); -#endif -#ifdef AI_MASK - PyModule_AddIntMacro(m, AI_MASK); -#endif -#ifdef AI_ALL - PyModule_AddIntMacro(m, AI_ALL); -#endif -#ifdef AI_V4MAPPED_CFG - PyModule_AddIntMacro(m, AI_V4MAPPED_CFG); -#endif -#ifdef AI_ADDRCONFIG - PyModule_AddIntMacro(m, AI_ADDRCONFIG); -#endif -#ifdef AI_V4MAPPED - PyModule_AddIntMacro(m, AI_V4MAPPED); -#endif -#ifdef AI_DEFAULT - PyModule_AddIntMacro(m, AI_DEFAULT); -#endif -#ifdef NI_MAXHOST - PyModule_AddIntMacro(m, NI_MAXHOST); -#endif -#ifdef NI_MAXSERV - PyModule_AddIntMacro(m, NI_MAXSERV); -#endif -#ifdef NI_NOFQDN - PyModule_AddIntMacro(m, NI_NOFQDN); -#endif -#ifdef NI_NUMERICHOST - PyModule_AddIntMacro(m, NI_NUMERICHOST); -#endif -#ifdef NI_NAMEREQD - PyModule_AddIntMacro(m, NI_NAMEREQD); -#endif -#ifdef NI_NUMERICSERV - PyModule_AddIntMacro(m, NI_NUMERICSERV); -#endif -#ifdef NI_DGRAM - PyModule_AddIntMacro(m, NI_DGRAM); -#endif - - /* shutdown() parameters */ -#ifdef SHUT_RD - PyModule_AddIntMacro(m, SHUT_RD); -#elif defined(SD_RECEIVE) - PyModule_AddIntConstant(m, "SHUT_RD", SD_RECEIVE); -#else - PyModule_AddIntConstant(m, "SHUT_RD", 0); -#endif -#ifdef SHUT_WR - PyModule_AddIntMacro(m, SHUT_WR); -#elif defined(SD_SEND) - PyModule_AddIntConstant(m, "SHUT_WR", SD_SEND); -#else - PyModule_AddIntConstant(m, "SHUT_WR", 1); -#endif -#ifdef SHUT_RDWR - PyModule_AddIntMacro(m, SHUT_RDWR); -#elif defined(SD_BOTH) - PyModule_AddIntConstant(m, "SHUT_RDWR", SD_BOTH); -#else - PyModule_AddIntConstant(m, "SHUT_RDWR", 2); -#endif - -#ifdef SIO_RCVALL - { - DWORD codes[] = {SIO_RCVALL, SIO_KEEPALIVE_VALS, -#if defined(SIO_LOOPBACK_FAST_PATH) - SIO_LOOPBACK_FAST_PATH -#endif - }; - const char *names[] = {"SIO_RCVALL", "SIO_KEEPALIVE_VALS", -#if defined(SIO_LOOPBACK_FAST_PATH) - "SIO_LOOPBACK_FAST_PATH" -#endif - }; - int i; - for(i = 0; i -# else -# include -# endif -# include -# if !defined(__CYGWIN__) -# include -# endif - -#else /* MS_WINDOWS */ -# include +/* Socket module header file */ + +/* Includes needed for the sockaddr_* symbols below */ +#ifndef MS_WINDOWS +#ifdef __VMS +# include +# else +# include +# endif +# include +# if !defined(__CYGWIN__) +# include +# endif + +#else /* MS_WINDOWS */ +# include /* * If Windows has bluetooth support, include bluetooth constants. @@ -55,46 +55,46 @@ struct SOCKADDR_BTH_REDEF { # include #endif -/* Windows 'supports' CMSG_LEN, but does not follow the POSIX standard - * interface at all, so there is no point including the code that - * attempts to use it. - */ -# ifdef PySocket_BUILDING_SOCKET -# undef CMSG_LEN -# endif -# include -/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h - * Separate SDKs have all the functions we want, but older ones don't have - * any version information. - * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK. - */ -# ifdef SIO_GET_MULTICAST_FILTER -# include /* for SIO_RCVALL */ -# define HAVE_ADDRINFO -# define HAVE_SOCKADDR_STORAGE -# define HAVE_GETADDRINFO -# define HAVE_GETNAMEINFO -# define ENABLE_IPV6 -# else -typedef int socklen_t; -# endif /* IPPROTO_IPV6 */ -#endif /* MS_WINDOWS */ - -#ifdef HAVE_SYS_UN_H -# include -#else -# undef AF_UNIX -#endif - -#ifdef HAVE_LINUX_NETLINK_H -# ifdef HAVE_ASM_TYPES_H -# include -# endif -# include -#else -# undef AF_NETLINK -#endif - +/* Windows 'supports' CMSG_LEN, but does not follow the POSIX standard + * interface at all, so there is no point including the code that + * attempts to use it. + */ +# ifdef PySocket_BUILDING_SOCKET +# undef CMSG_LEN +# endif +# include +/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h + * Separate SDKs have all the functions we want, but older ones don't have + * any version information. + * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK. + */ +# ifdef SIO_GET_MULTICAST_FILTER +# include /* for SIO_RCVALL */ +# define HAVE_ADDRINFO +# define HAVE_SOCKADDR_STORAGE +# define HAVE_GETADDRINFO +# define HAVE_GETNAMEINFO +# define ENABLE_IPV6 +# else +typedef int socklen_t; +# endif /* IPPROTO_IPV6 */ +#endif /* MS_WINDOWS */ + +#ifdef HAVE_SYS_UN_H +# include +#else +# undef AF_UNIX +#endif + +#ifdef HAVE_LINUX_NETLINK_H +# ifdef HAVE_ASM_TYPES_H +# include +# endif +# include +#else +# undef AF_NETLINK +#endif + #ifdef HAVE_LINUX_QRTR_H # ifdef HAVE_ASM_TYPES_H # include @@ -104,254 +104,254 @@ typedef int socklen_t; # undef AF_QIPCRTR #endif -#ifdef HAVE_BLUETOOTH_BLUETOOTH_H -#include -#include -#include -#include -#include -#endif - -#ifdef HAVE_BLUETOOTH_H -#include -#endif - -#ifdef HAVE_NET_IF_H -# include -#endif - -#ifdef HAVE_NETPACKET_PACKET_H -# include -# include -#endif - -#ifdef HAVE_LINUX_TIPC_H -# include -#endif - -#ifdef HAVE_LINUX_CAN_H -# include -#else -# undef AF_CAN -# undef PF_CAN -#endif - -#ifdef HAVE_LINUX_CAN_RAW_H -#include -#endif - -#ifdef HAVE_LINUX_CAN_BCM_H -#include -#endif - +#ifdef HAVE_BLUETOOTH_BLUETOOTH_H +#include +#include +#include +#include +#include +#endif + +#ifdef HAVE_BLUETOOTH_H +#include +#endif + +#ifdef HAVE_NET_IF_H +# include +#endif + +#ifdef HAVE_NETPACKET_PACKET_H +# include +# include +#endif + +#ifdef HAVE_LINUX_TIPC_H +# include +#endif + +#ifdef HAVE_LINUX_CAN_H +# include +#else +# undef AF_CAN +# undef PF_CAN +#endif + +#ifdef HAVE_LINUX_CAN_RAW_H +#include +#endif + +#ifdef HAVE_LINUX_CAN_BCM_H +#include +#endif + #ifdef HAVE_LINUX_CAN_J1939_H #include #endif -#ifdef HAVE_SYS_SYS_DOMAIN_H -#include -#endif -#ifdef HAVE_SYS_KERN_CONTROL_H -#include -#endif - -#ifdef HAVE_LINUX_VM_SOCKETS_H -# include -#else -# undef AF_VSOCK -#endif - -#ifdef HAVE_SOCKADDR_ALG - -# include -# ifndef AF_ALG -# define AF_ALG 38 -# endif -# ifndef SOL_ALG -# define SOL_ALG 279 -# endif - -/* Linux 3.19 */ -# ifndef ALG_SET_AEAD_ASSOCLEN -# define ALG_SET_AEAD_ASSOCLEN 4 -# endif -# ifndef ALG_SET_AEAD_AUTHSIZE -# define ALG_SET_AEAD_AUTHSIZE 5 -# endif -/* Linux 4.8 */ -# ifndef ALG_SET_PUBKEY -# define ALG_SET_PUBKEY 6 -# endif - -# ifndef ALG_OP_SIGN -# define ALG_OP_SIGN 2 -# endif -# ifndef ALG_OP_VERIFY -# define ALG_OP_VERIFY 3 -# endif - -#endif /* HAVE_SOCKADDR_ALG */ - - -#ifndef Py__SOCKET_H -#define Py__SOCKET_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Python module and C API name */ -#define PySocket_MODULE_NAME "_socket" -#define PySocket_CAPI_NAME "CAPI" -#define PySocket_CAPSULE_NAME PySocket_MODULE_NAME "." PySocket_CAPI_NAME - -/* Abstract the socket file descriptor type */ -#ifdef MS_WINDOWS -typedef SOCKET SOCKET_T; -# ifdef MS_WIN64 -# define SIZEOF_SOCKET_T 8 -# else -# define SIZEOF_SOCKET_T 4 -# endif -#else -typedef int SOCKET_T; -# define SIZEOF_SOCKET_T SIZEOF_INT -#endif - -#if SIZEOF_SOCKET_T <= SIZEOF_LONG -#define PyLong_FromSocket_t(fd) PyLong_FromLong((SOCKET_T)(fd)) -#define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLong(fd) -#else -#define PyLong_FromSocket_t(fd) PyLong_FromLongLong((SOCKET_T)(fd)) -#define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd) -#endif - -/* Socket address */ -typedef union sock_addr { - struct sockaddr_in in; - struct sockaddr sa; -#ifdef AF_UNIX - struct sockaddr_un un; -#endif -#ifdef AF_NETLINK - struct sockaddr_nl nl; -#endif -#ifdef ENABLE_IPV6 - struct sockaddr_in6 in6; - struct sockaddr_storage storage; -#endif +#ifdef HAVE_SYS_SYS_DOMAIN_H +#include +#endif +#ifdef HAVE_SYS_KERN_CONTROL_H +#include +#endif + +#ifdef HAVE_LINUX_VM_SOCKETS_H +# include +#else +# undef AF_VSOCK +#endif + +#ifdef HAVE_SOCKADDR_ALG + +# include +# ifndef AF_ALG +# define AF_ALG 38 +# endif +# ifndef SOL_ALG +# define SOL_ALG 279 +# endif + +/* Linux 3.19 */ +# ifndef ALG_SET_AEAD_ASSOCLEN +# define ALG_SET_AEAD_ASSOCLEN 4 +# endif +# ifndef ALG_SET_AEAD_AUTHSIZE +# define ALG_SET_AEAD_AUTHSIZE 5 +# endif +/* Linux 4.8 */ +# ifndef ALG_SET_PUBKEY +# define ALG_SET_PUBKEY 6 +# endif + +# ifndef ALG_OP_SIGN +# define ALG_OP_SIGN 2 +# endif +# ifndef ALG_OP_VERIFY +# define ALG_OP_VERIFY 3 +# endif + +#endif /* HAVE_SOCKADDR_ALG */ + + +#ifndef Py__SOCKET_H +#define Py__SOCKET_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Python module and C API name */ +#define PySocket_MODULE_NAME "_socket" +#define PySocket_CAPI_NAME "CAPI" +#define PySocket_CAPSULE_NAME PySocket_MODULE_NAME "." PySocket_CAPI_NAME + +/* Abstract the socket file descriptor type */ +#ifdef MS_WINDOWS +typedef SOCKET SOCKET_T; +# ifdef MS_WIN64 +# define SIZEOF_SOCKET_T 8 +# else +# define SIZEOF_SOCKET_T 4 +# endif +#else +typedef int SOCKET_T; +# define SIZEOF_SOCKET_T SIZEOF_INT +#endif + +#if SIZEOF_SOCKET_T <= SIZEOF_LONG +#define PyLong_FromSocket_t(fd) PyLong_FromLong((SOCKET_T)(fd)) +#define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLong(fd) +#else +#define PyLong_FromSocket_t(fd) PyLong_FromLongLong((SOCKET_T)(fd)) +#define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd) +#endif + +/* Socket address */ +typedef union sock_addr { + struct sockaddr_in in; + struct sockaddr sa; +#ifdef AF_UNIX + struct sockaddr_un un; +#endif +#ifdef AF_NETLINK + struct sockaddr_nl nl; +#endif +#ifdef ENABLE_IPV6 + struct sockaddr_in6 in6; + struct sockaddr_storage storage; +#endif #if defined(HAVE_BLUETOOTH_H) && defined(__FreeBSD__) struct sockaddr_l2cap bt_l2; struct sockaddr_rfcomm bt_rc; struct sockaddr_sco bt_sco; struct sockaddr_hci bt_hci; #elif defined(HAVE_BLUETOOTH_BLUETOOTH_H) - struct sockaddr_l2 bt_l2; - struct sockaddr_rc bt_rc; - struct sockaddr_sco bt_sco; - struct sockaddr_hci bt_hci; + struct sockaddr_l2 bt_l2; + struct sockaddr_rc bt_rc; + struct sockaddr_sco bt_sco; + struct sockaddr_hci bt_hci; #elif defined(MS_WINDOWS) struct SOCKADDR_BTH_REDEF bt_rc; -#endif -#ifdef HAVE_NETPACKET_PACKET_H - struct sockaddr_ll ll; -#endif -#ifdef HAVE_LINUX_CAN_H - struct sockaddr_can can; -#endif -#ifdef HAVE_SYS_KERN_CONTROL_H - struct sockaddr_ctl ctl; -#endif -#ifdef HAVE_SOCKADDR_ALG - struct sockaddr_alg alg; -#endif +#endif +#ifdef HAVE_NETPACKET_PACKET_H + struct sockaddr_ll ll; +#endif +#ifdef HAVE_LINUX_CAN_H + struct sockaddr_can can; +#endif +#ifdef HAVE_SYS_KERN_CONTROL_H + struct sockaddr_ctl ctl; +#endif +#ifdef HAVE_SOCKADDR_ALG + struct sockaddr_alg alg; +#endif #ifdef AF_QIPCRTR struct sockaddr_qrtr sq; #endif -#ifdef AF_VSOCK - struct sockaddr_vm vm; -#endif +#ifdef AF_VSOCK + struct sockaddr_vm vm; +#endif #ifdef HAVE_LINUX_TIPC_H struct sockaddr_tipc tipc; #endif -} sock_addr_t; - -/* The object holding a socket. It holds some extra information, - like the address family, which is used to decode socket address - arguments properly. */ - -typedef struct { - PyObject_HEAD - SOCKET_T sock_fd; /* Socket file descriptor */ - int sock_family; /* Address family, e.g., AF_INET */ - int sock_type; /* Socket type, e.g., SOCK_STREAM */ - int sock_proto; /* Protocol type, usually 0 */ - PyObject *(*errorhandler)(void); /* Error handler; checks - errno, returns NULL and - sets a Python exception */ - _PyTime_t sock_timeout; /* Operation timeout in seconds; - 0.0 means non-blocking */ -} PySocketSockObject; - -/* --- C API ----------------------------------------------------*/ - -/* Short explanation of what this C API export mechanism does - and how it works: - - The _ssl module needs access to the type object defined in - the _socket module. Since cross-DLL linking introduces a lot of - problems on many platforms, the "trick" is to wrap the - C API of a module in a struct which then gets exported to - other modules via a PyCapsule. - - The code in socketmodule.c defines this struct (which currently - only contains the type object reference, but could very - well also include other C APIs needed by other modules) - and exports it as PyCapsule via the module dictionary - under the name "CAPI". - - Other modules can now include the socketmodule.h file - which defines the needed C APIs to import and set up - a static copy of this struct in the importing module. - - After initialization, the importing module can then - access the C APIs from the _socket module by simply - referring to the static struct, e.g. - - Load _socket module and its C API; this sets up the global - PySocketModule: - - if (PySocketModule_ImportModuleAndAPI()) - return; - - - Now use the C API as if it were defined in the using - module: - - if (!PyArg_ParseTuple(args, "O!|zz:ssl", - - PySocketModule.Sock_Type, - - (PyObject*)&Sock, - &key_file, &cert_file)) - return NULL; - - Support could easily be extended to export more C APIs/symbols - this way. Currently, only the type object is exported, - other candidates would be socket constructors and socket - access functions. - -*/ - -/* C API for usage by other Python modules */ -typedef struct { - PyTypeObject *Sock_Type; - PyObject *error; - PyObject *timeout_error; -} PySocketModule_APIObject; - -#define PySocketModule_ImportModuleAndAPI() PyCapsule_Import(PySocket_CAPSULE_NAME, 1) - -#ifdef __cplusplus -} -#endif -#endif /* !Py__SOCKET_H */ +} sock_addr_t; + +/* The object holding a socket. It holds some extra information, + like the address family, which is used to decode socket address + arguments properly. */ + +typedef struct { + PyObject_HEAD + SOCKET_T sock_fd; /* Socket file descriptor */ + int sock_family; /* Address family, e.g., AF_INET */ + int sock_type; /* Socket type, e.g., SOCK_STREAM */ + int sock_proto; /* Protocol type, usually 0 */ + PyObject *(*errorhandler)(void); /* Error handler; checks + errno, returns NULL and + sets a Python exception */ + _PyTime_t sock_timeout; /* Operation timeout in seconds; + 0.0 means non-blocking */ +} PySocketSockObject; + +/* --- C API ----------------------------------------------------*/ + +/* Short explanation of what this C API export mechanism does + and how it works: + + The _ssl module needs access to the type object defined in + the _socket module. Since cross-DLL linking introduces a lot of + problems on many platforms, the "trick" is to wrap the + C API of a module in a struct which then gets exported to + other modules via a PyCapsule. + + The code in socketmodule.c defines this struct (which currently + only contains the type object reference, but could very + well also include other C APIs needed by other modules) + and exports it as PyCapsule via the module dictionary + under the name "CAPI". + + Other modules can now include the socketmodule.h file + which defines the needed C APIs to import and set up + a static copy of this struct in the importing module. + + After initialization, the importing module can then + access the C APIs from the _socket module by simply + referring to the static struct, e.g. + + Load _socket module and its C API; this sets up the global + PySocketModule: + + if (PySocketModule_ImportModuleAndAPI()) + return; + + + Now use the C API as if it were defined in the using + module: + + if (!PyArg_ParseTuple(args, "O!|zz:ssl", + + PySocketModule.Sock_Type, + + (PyObject*)&Sock, + &key_file, &cert_file)) + return NULL; + + Support could easily be extended to export more C APIs/symbols + this way. Currently, only the type object is exported, + other candidates would be socket constructors and socket + access functions. + +*/ + +/* C API for usage by other Python modules */ +typedef struct { + PyTypeObject *Sock_Type; + PyObject *error; + PyObject *timeout_error; +} PySocketModule_APIObject; + +#define PySocketModule_ImportModuleAndAPI() PyCapsule_Import(PySocket_CAPSULE_NAME, 1) + +#ifdef __cplusplus +} +#endif +#endif /* !Py__SOCKET_H */ diff --git a/contrib/tools/python3/src/Modules/spwdmodule.c b/contrib/tools/python3/src/Modules/spwdmodule.c index 1601ec0f2fc..9f26af01cc1 100644 --- a/contrib/tools/python3/src/Modules/spwdmodule.c +++ b/contrib/tools/python3/src/Modules/spwdmodule.c @@ -1,230 +1,230 @@ - -/* UNIX shadow password file access module */ -/* A lot of code has been taken from pwdmodule.c */ -/* For info also see http://www.unixpapa.com/incnote/passwd.html */ - -#include "Python.h" - -#include -#ifdef HAVE_SHADOW_H -#include -#endif - -#include "clinic/spwdmodule.c.h" - -/*[clinic input] -module spwd -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c0b841b90a6a07ce]*/ - -PyDoc_STRVAR(spwd__doc__, -"This module provides access to the Unix shadow password database.\n\ -It is available on various Unix versions.\n\ -\n\ -Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\ -containing the following items from the password database (see `'):\n\ -sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\ -The sp_namp and sp_pwdp are strings, the rest are integers.\n\ -An exception is raised if the entry asked for cannot be found.\n\ -You have to be root to be able to use this module."); - - -#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT) - -static PyStructSequence_Field struct_spwd_type_fields[] = { - {"sp_namp", "login name"}, - {"sp_pwdp", "encrypted password"}, - {"sp_lstchg", "date of last change"}, - {"sp_min", "min #days between changes"}, - {"sp_max", "max #days between changes"}, - {"sp_warn", "#days before pw expires to warn user about it"}, - {"sp_inact", "#days after pw expires until account is disabled"}, - {"sp_expire", "#days since 1970-01-01 when account expires"}, - {"sp_flag", "reserved"}, - {"sp_nam", "login name; deprecated"}, /* Backward compatibility */ - {"sp_pwd", "encrypted password; deprecated"}, /* Backward compatibility */ - {0} -}; - -PyDoc_STRVAR(struct_spwd__doc__, -"spwd.struct_spwd: Results from getsp*() routines.\n\n\ -This object may be accessed either as a 9-tuple of\n\ - (sp_namp,sp_pwdp,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\ -or via the object attributes as named in the above tuple."); - -static PyStructSequence_Desc struct_spwd_type_desc = { - "spwd.struct_spwd", - struct_spwd__doc__, - struct_spwd_type_fields, - 9, -}; - -static int initialized; -static PyTypeObject StructSpwdType; - - -static void -sets(PyObject *v, int i, const char* val) -{ - if (val) { - PyObject *o = PyUnicode_DecodeFSDefault(val); - PyStructSequence_SET_ITEM(v, i, o); - } else { - PyStructSequence_SET_ITEM(v, i, Py_None); - Py_INCREF(Py_None); - } -} - -static PyObject *mkspent(struct spwd *p) -{ - int setIndex = 0; - PyObject *v = PyStructSequence_New(&StructSpwdType); - if (v == NULL) - return NULL; - -#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) -#define SETS(i,val) sets(v, i, val) - - SETS(setIndex++, p->sp_namp); - SETS(setIndex++, p->sp_pwdp); - SETI(setIndex++, p->sp_lstchg); - SETI(setIndex++, p->sp_min); - SETI(setIndex++, p->sp_max); - SETI(setIndex++, p->sp_warn); - SETI(setIndex++, p->sp_inact); - SETI(setIndex++, p->sp_expire); - SETI(setIndex++, p->sp_flag); - SETS(setIndex++, p->sp_namp); /* Backward compatibility for sp_nam */ - SETS(setIndex++, p->sp_pwdp); /* Backward compatibility for sp_pwd */ - -#undef SETS -#undef SETI - - if (PyErr_Occurred()) { - Py_DECREF(v); - return NULL; - } - - return v; -} - -#endif /* HAVE_GETSPNAM || HAVE_GETSPENT */ - - -#ifdef HAVE_GETSPNAM - -/*[clinic input] -spwd.getspnam - - arg: unicode - / - -Return the shadow password database entry for the given user name. - -See `help(spwd)` for more on shadow password database entries. -[clinic start generated code]*/ - -static PyObject * -spwd_getspnam_impl(PyObject *module, PyObject *arg) -/*[clinic end generated code: output=701250cf57dc6ebe input=dd89429e6167a00f]*/ -{ - char *name; - struct spwd *p; - PyObject *bytes, *retval = NULL; - - if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) - return NULL; - /* check for embedded null bytes */ - if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) - goto out; - if ((p = getspnam(name)) == NULL) { - if (errno != 0) - PyErr_SetFromErrno(PyExc_OSError); - else - PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); - goto out; - } - retval = mkspent(p); -out: - Py_DECREF(bytes); - return retval; -} - -#endif /* HAVE_GETSPNAM */ - -#ifdef HAVE_GETSPENT - -/*[clinic input] -spwd.getspall - -Return a list of all available shadow password database entries, in arbitrary order. - -See `help(spwd)` for more on shadow password database entries. -[clinic start generated code]*/ - -static PyObject * -spwd_getspall_impl(PyObject *module) -/*[clinic end generated code: output=4fda298d6bf6d057 input=b2c84b7857d622bd]*/ -{ - PyObject *d; - struct spwd *p; - if ((d = PyList_New(0)) == NULL) - return NULL; - setspent(); - while ((p = getspent()) != NULL) { - PyObject *v = mkspent(p); - if (v == NULL || PyList_Append(d, v) != 0) { - Py_XDECREF(v); - Py_DECREF(d); - endspent(); - return NULL; - } - Py_DECREF(v); - } - endspent(); - return d; -} - -#endif /* HAVE_GETSPENT */ - -static PyMethodDef spwd_methods[] = { -#ifdef HAVE_GETSPNAM - SPWD_GETSPNAM_METHODDEF -#endif -#ifdef HAVE_GETSPENT - SPWD_GETSPALL_METHODDEF -#endif - {NULL, NULL} /* sentinel */ -}; - - - -static struct PyModuleDef spwdmodule = { - PyModuleDef_HEAD_INIT, - "spwd", - spwd__doc__, - -1, - spwd_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_spwd(void) -{ - PyObject *m; - m=PyModule_Create(&spwdmodule); - if (m == NULL) - return NULL; - if (!initialized) { - if (PyStructSequence_InitType2(&StructSpwdType, - &struct_spwd_type_desc) < 0) - return NULL; - } - Py_INCREF((PyObject *) &StructSpwdType); - PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType); - initialized = 1; - return m; -} + +/* UNIX shadow password file access module */ +/* A lot of code has been taken from pwdmodule.c */ +/* For info also see http://www.unixpapa.com/incnote/passwd.html */ + +#include "Python.h" + +#include +#ifdef HAVE_SHADOW_H +#include +#endif + +#include "clinic/spwdmodule.c.h" + +/*[clinic input] +module spwd +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c0b841b90a6a07ce]*/ + +PyDoc_STRVAR(spwd__doc__, +"This module provides access to the Unix shadow password database.\n\ +It is available on various Unix versions.\n\ +\n\ +Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\ +containing the following items from the password database (see `'):\n\ +sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\ +The sp_namp and sp_pwdp are strings, the rest are integers.\n\ +An exception is raised if the entry asked for cannot be found.\n\ +You have to be root to be able to use this module."); + + +#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT) + +static PyStructSequence_Field struct_spwd_type_fields[] = { + {"sp_namp", "login name"}, + {"sp_pwdp", "encrypted password"}, + {"sp_lstchg", "date of last change"}, + {"sp_min", "min #days between changes"}, + {"sp_max", "max #days between changes"}, + {"sp_warn", "#days before pw expires to warn user about it"}, + {"sp_inact", "#days after pw expires until account is disabled"}, + {"sp_expire", "#days since 1970-01-01 when account expires"}, + {"sp_flag", "reserved"}, + {"sp_nam", "login name; deprecated"}, /* Backward compatibility */ + {"sp_pwd", "encrypted password; deprecated"}, /* Backward compatibility */ + {0} +}; + +PyDoc_STRVAR(struct_spwd__doc__, +"spwd.struct_spwd: Results from getsp*() routines.\n\n\ +This object may be accessed either as a 9-tuple of\n\ + (sp_namp,sp_pwdp,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\ +or via the object attributes as named in the above tuple."); + +static PyStructSequence_Desc struct_spwd_type_desc = { + "spwd.struct_spwd", + struct_spwd__doc__, + struct_spwd_type_fields, + 9, +}; + +static int initialized; +static PyTypeObject StructSpwdType; + + +static void +sets(PyObject *v, int i, const char* val) +{ + if (val) { + PyObject *o = PyUnicode_DecodeFSDefault(val); + PyStructSequence_SET_ITEM(v, i, o); + } else { + PyStructSequence_SET_ITEM(v, i, Py_None); + Py_INCREF(Py_None); + } +} + +static PyObject *mkspent(struct spwd *p) +{ + int setIndex = 0; + PyObject *v = PyStructSequence_New(&StructSpwdType); + if (v == NULL) + return NULL; + +#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) +#define SETS(i,val) sets(v, i, val) + + SETS(setIndex++, p->sp_namp); + SETS(setIndex++, p->sp_pwdp); + SETI(setIndex++, p->sp_lstchg); + SETI(setIndex++, p->sp_min); + SETI(setIndex++, p->sp_max); + SETI(setIndex++, p->sp_warn); + SETI(setIndex++, p->sp_inact); + SETI(setIndex++, p->sp_expire); + SETI(setIndex++, p->sp_flag); + SETS(setIndex++, p->sp_namp); /* Backward compatibility for sp_nam */ + SETS(setIndex++, p->sp_pwdp); /* Backward compatibility for sp_pwd */ + +#undef SETS +#undef SETI + + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + + return v; +} + +#endif /* HAVE_GETSPNAM || HAVE_GETSPENT */ + + +#ifdef HAVE_GETSPNAM + +/*[clinic input] +spwd.getspnam + + arg: unicode + / + +Return the shadow password database entry for the given user name. + +See `help(spwd)` for more on shadow password database entries. +[clinic start generated code]*/ + +static PyObject * +spwd_getspnam_impl(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=701250cf57dc6ebe input=dd89429e6167a00f]*/ +{ + char *name; + struct spwd *p; + PyObject *bytes, *retval = NULL; + + if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) + return NULL; + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) + goto out; + if ((p = getspnam(name)) == NULL) { + if (errno != 0) + PyErr_SetFromErrno(PyExc_OSError); + else + PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); + goto out; + } + retval = mkspent(p); +out: + Py_DECREF(bytes); + return retval; +} + +#endif /* HAVE_GETSPNAM */ + +#ifdef HAVE_GETSPENT + +/*[clinic input] +spwd.getspall + +Return a list of all available shadow password database entries, in arbitrary order. + +See `help(spwd)` for more on shadow password database entries. +[clinic start generated code]*/ + +static PyObject * +spwd_getspall_impl(PyObject *module) +/*[clinic end generated code: output=4fda298d6bf6d057 input=b2c84b7857d622bd]*/ +{ + PyObject *d; + struct spwd *p; + if ((d = PyList_New(0)) == NULL) + return NULL; + setspent(); + while ((p = getspent()) != NULL) { + PyObject *v = mkspent(p); + if (v == NULL || PyList_Append(d, v) != 0) { + Py_XDECREF(v); + Py_DECREF(d); + endspent(); + return NULL; + } + Py_DECREF(v); + } + endspent(); + return d; +} + +#endif /* HAVE_GETSPENT */ + +static PyMethodDef spwd_methods[] = { +#ifdef HAVE_GETSPNAM + SPWD_GETSPNAM_METHODDEF +#endif +#ifdef HAVE_GETSPENT + SPWD_GETSPALL_METHODDEF +#endif + {NULL, NULL} /* sentinel */ +}; + + + +static struct PyModuleDef spwdmodule = { + PyModuleDef_HEAD_INIT, + "spwd", + spwd__doc__, + -1, + spwd_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_spwd(void) +{ + PyObject *m; + m=PyModule_Create(&spwdmodule); + if (m == NULL) + return NULL; + if (!initialized) { + if (PyStructSequence_InitType2(&StructSpwdType, + &struct_spwd_type_desc) < 0) + return NULL; + } + Py_INCREF((PyObject *) &StructSpwdType); + PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType); + initialized = 1; + return m; +} diff --git a/contrib/tools/python3/src/Modules/sre.h b/contrib/tools/python3/src/Modules/sre.h index 9b0d8b19042..b086e9c3a90 100644 --- a/contrib/tools/python3/src/Modules/sre.h +++ b/contrib/tools/python3/src/Modules/sre.h @@ -1,94 +1,94 @@ -/* - * Secret Labs' Regular Expression Engine - * - * regular expression matching engine - * - * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. - * - * See the _sre.c file for information on usage and redistribution. - */ - -#ifndef SRE_INCLUDED -#define SRE_INCLUDED - -#include "sre_constants.h" - -/* size of a code word (must be unsigned short or larger, and - large enough to hold a UCS4 character) */ -#define SRE_CODE Py_UCS4 -#if SIZEOF_SIZE_T > 4 -# define SRE_MAXREPEAT (~(SRE_CODE)0) -# define SRE_MAXGROUPS ((~(SRE_CODE)0) / 2) -#else -# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX) -# define SRE_MAXGROUPS ((SRE_CODE)PY_SSIZE_T_MAX / SIZEOF_SIZE_T / 2) -#endif - -typedef struct { - PyObject_VAR_HEAD - Py_ssize_t groups; /* must be first! */ - PyObject* groupindex; /* dict */ - PyObject* indexgroup; /* tuple */ - /* compatibility */ - PyObject* pattern; /* pattern source (or None) */ - int flags; /* flags used when compiling pattern source */ - PyObject *weakreflist; /* List of weak references */ - int isbytes; /* pattern type (1 - bytes, 0 - string, -1 - None) */ - /* pattern code */ - Py_ssize_t codesize; - SRE_CODE code[1]; -} PatternObject; - -#define PatternObject_GetCode(o) (((PatternObject*)(o))->code) - -typedef struct { - PyObject_VAR_HEAD - PyObject* string; /* link to the target string (must be first) */ - PyObject* regs; /* cached list of matching spans */ - PatternObject* pattern; /* link to the regex (pattern) object */ - Py_ssize_t pos, endpos; /* current target slice */ - Py_ssize_t lastindex; /* last index marker seen by the engine (-1 if none) */ - Py_ssize_t groups; /* number of groups (start/end marks) */ - Py_ssize_t mark[1]; -} MatchObject; - -typedef struct SRE_REPEAT_T { - Py_ssize_t count; +/* + * Secret Labs' Regular Expression Engine + * + * regular expression matching engine + * + * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. + * + * See the _sre.c file for information on usage and redistribution. + */ + +#ifndef SRE_INCLUDED +#define SRE_INCLUDED + +#include "sre_constants.h" + +/* size of a code word (must be unsigned short or larger, and + large enough to hold a UCS4 character) */ +#define SRE_CODE Py_UCS4 +#if SIZEOF_SIZE_T > 4 +# define SRE_MAXREPEAT (~(SRE_CODE)0) +# define SRE_MAXGROUPS ((~(SRE_CODE)0) / 2) +#else +# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX) +# define SRE_MAXGROUPS ((SRE_CODE)PY_SSIZE_T_MAX / SIZEOF_SIZE_T / 2) +#endif + +typedef struct { + PyObject_VAR_HEAD + Py_ssize_t groups; /* must be first! */ + PyObject* groupindex; /* dict */ + PyObject* indexgroup; /* tuple */ + /* compatibility */ + PyObject* pattern; /* pattern source (or None) */ + int flags; /* flags used when compiling pattern source */ + PyObject *weakreflist; /* List of weak references */ + int isbytes; /* pattern type (1 - bytes, 0 - string, -1 - None) */ + /* pattern code */ + Py_ssize_t codesize; + SRE_CODE code[1]; +} PatternObject; + +#define PatternObject_GetCode(o) (((PatternObject*)(o))->code) + +typedef struct { + PyObject_VAR_HEAD + PyObject* string; /* link to the target string (must be first) */ + PyObject* regs; /* cached list of matching spans */ + PatternObject* pattern; /* link to the regex (pattern) object */ + Py_ssize_t pos, endpos; /* current target slice */ + Py_ssize_t lastindex; /* last index marker seen by the engine (-1 if none) */ + Py_ssize_t groups; /* number of groups (start/end marks) */ + Py_ssize_t mark[1]; +} MatchObject; + +typedef struct SRE_REPEAT_T { + Py_ssize_t count; const SRE_CODE* pattern; /* points to REPEAT operator arguments */ const void* last_ptr; /* helper to check for infinite loops */ - struct SRE_REPEAT_T *prev; /* points to previous repeat context */ -} SRE_REPEAT; - -typedef struct { - /* string pointers */ + struct SRE_REPEAT_T *prev; /* points to previous repeat context */ +} SRE_REPEAT; + +typedef struct { + /* string pointers */ const void* ptr; /* current position (also end of current slice) */ const void* beginning; /* start of original string */ const void* start; /* start of current slice */ const void* end; /* end of original string */ - /* attributes for the match object */ - PyObject* string; - Py_buffer buffer; - Py_ssize_t pos, endpos; - int isbytes; - int charsize; /* character size */ - /* registers */ - Py_ssize_t lastindex; - Py_ssize_t lastmark; + /* attributes for the match object */ + PyObject* string; + Py_buffer buffer; + Py_ssize_t pos, endpos; + int isbytes; + int charsize; /* character size */ + /* registers */ + Py_ssize_t lastindex; + Py_ssize_t lastmark; const void** mark; - int match_all; - int must_advance; - /* dynamically allocated stuff */ - char* data_stack; - size_t data_stack_size; - size_t data_stack_base; - /* current repeat context */ - SRE_REPEAT *repeat; -} SRE_STATE; - -typedef struct { - PyObject_HEAD - PyObject* pattern; - SRE_STATE state; -} ScannerObject; - -#endif + int match_all; + int must_advance; + /* dynamically allocated stuff */ + char* data_stack; + size_t data_stack_size; + size_t data_stack_base; + /* current repeat context */ + SRE_REPEAT *repeat; +} SRE_STATE; + +typedef struct { + PyObject_HEAD + PyObject* pattern; + SRE_STATE state; +} ScannerObject; + +#endif diff --git a/contrib/tools/python3/src/Modules/sre_constants.h b/contrib/tools/python3/src/Modules/sre_constants.h index c8ccb32d21d..248e91440df 100644 --- a/contrib/tools/python3/src/Modules/sre_constants.h +++ b/contrib/tools/python3/src/Modules/sre_constants.h @@ -1,97 +1,97 @@ -/* - * Secret Labs' Regular Expression Engine - * - * regular expression matching engine - * - * NOTE: This file is generated by sre_constants.py. If you need - * to change anything in here, edit sre_constants.py and run it. - * - * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. - * - * See the _sre.c file for information on usage and redistribution. - */ - -#define SRE_MAGIC 20171005 -#define SRE_OP_FAILURE 0 -#define SRE_OP_SUCCESS 1 -#define SRE_OP_ANY 2 -#define SRE_OP_ANY_ALL 3 -#define SRE_OP_ASSERT 4 -#define SRE_OP_ASSERT_NOT 5 -#define SRE_OP_AT 6 -#define SRE_OP_BRANCH 7 -#define SRE_OP_CALL 8 -#define SRE_OP_CATEGORY 9 -#define SRE_OP_CHARSET 10 -#define SRE_OP_BIGCHARSET 11 -#define SRE_OP_GROUPREF 12 -#define SRE_OP_GROUPREF_EXISTS 13 -#define SRE_OP_IN 14 -#define SRE_OP_INFO 15 -#define SRE_OP_JUMP 16 -#define SRE_OP_LITERAL 17 -#define SRE_OP_MARK 18 -#define SRE_OP_MAX_UNTIL 19 -#define SRE_OP_MIN_UNTIL 20 -#define SRE_OP_NOT_LITERAL 21 -#define SRE_OP_NEGATE 22 -#define SRE_OP_RANGE 23 -#define SRE_OP_REPEAT 24 -#define SRE_OP_REPEAT_ONE 25 -#define SRE_OP_SUBPATTERN 26 -#define SRE_OP_MIN_REPEAT_ONE 27 -#define SRE_OP_GROUPREF_IGNORE 28 -#define SRE_OP_IN_IGNORE 29 -#define SRE_OP_LITERAL_IGNORE 30 -#define SRE_OP_NOT_LITERAL_IGNORE 31 -#define SRE_OP_GROUPREF_LOC_IGNORE 32 -#define SRE_OP_IN_LOC_IGNORE 33 -#define SRE_OP_LITERAL_LOC_IGNORE 34 -#define SRE_OP_NOT_LITERAL_LOC_IGNORE 35 -#define SRE_OP_GROUPREF_UNI_IGNORE 36 -#define SRE_OP_IN_UNI_IGNORE 37 -#define SRE_OP_LITERAL_UNI_IGNORE 38 -#define SRE_OP_NOT_LITERAL_UNI_IGNORE 39 -#define SRE_OP_RANGE_UNI_IGNORE 40 -#define SRE_AT_BEGINNING 0 -#define SRE_AT_BEGINNING_LINE 1 -#define SRE_AT_BEGINNING_STRING 2 -#define SRE_AT_BOUNDARY 3 -#define SRE_AT_NON_BOUNDARY 4 -#define SRE_AT_END 5 -#define SRE_AT_END_LINE 6 -#define SRE_AT_END_STRING 7 -#define SRE_AT_LOC_BOUNDARY 8 -#define SRE_AT_LOC_NON_BOUNDARY 9 -#define SRE_AT_UNI_BOUNDARY 10 -#define SRE_AT_UNI_NON_BOUNDARY 11 -#define SRE_CATEGORY_DIGIT 0 -#define SRE_CATEGORY_NOT_DIGIT 1 -#define SRE_CATEGORY_SPACE 2 -#define SRE_CATEGORY_NOT_SPACE 3 -#define SRE_CATEGORY_WORD 4 -#define SRE_CATEGORY_NOT_WORD 5 -#define SRE_CATEGORY_LINEBREAK 6 -#define SRE_CATEGORY_NOT_LINEBREAK 7 -#define SRE_CATEGORY_LOC_WORD 8 -#define SRE_CATEGORY_LOC_NOT_WORD 9 -#define SRE_CATEGORY_UNI_DIGIT 10 -#define SRE_CATEGORY_UNI_NOT_DIGIT 11 -#define SRE_CATEGORY_UNI_SPACE 12 -#define SRE_CATEGORY_UNI_NOT_SPACE 13 -#define SRE_CATEGORY_UNI_WORD 14 -#define SRE_CATEGORY_UNI_NOT_WORD 15 -#define SRE_CATEGORY_UNI_LINEBREAK 16 -#define SRE_CATEGORY_UNI_NOT_LINEBREAK 17 -#define SRE_FLAG_TEMPLATE 1 -#define SRE_FLAG_IGNORECASE 2 -#define SRE_FLAG_LOCALE 4 -#define SRE_FLAG_MULTILINE 8 -#define SRE_FLAG_DOTALL 16 -#define SRE_FLAG_UNICODE 32 -#define SRE_FLAG_VERBOSE 64 -#define SRE_FLAG_DEBUG 128 -#define SRE_FLAG_ASCII 256 -#define SRE_INFO_PREFIX 1 -#define SRE_INFO_LITERAL 2 -#define SRE_INFO_CHARSET 4 +/* + * Secret Labs' Regular Expression Engine + * + * regular expression matching engine + * + * NOTE: This file is generated by sre_constants.py. If you need + * to change anything in here, edit sre_constants.py and run it. + * + * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. + * + * See the _sre.c file for information on usage and redistribution. + */ + +#define SRE_MAGIC 20171005 +#define SRE_OP_FAILURE 0 +#define SRE_OP_SUCCESS 1 +#define SRE_OP_ANY 2 +#define SRE_OP_ANY_ALL 3 +#define SRE_OP_ASSERT 4 +#define SRE_OP_ASSERT_NOT 5 +#define SRE_OP_AT 6 +#define SRE_OP_BRANCH 7 +#define SRE_OP_CALL 8 +#define SRE_OP_CATEGORY 9 +#define SRE_OP_CHARSET 10 +#define SRE_OP_BIGCHARSET 11 +#define SRE_OP_GROUPREF 12 +#define SRE_OP_GROUPREF_EXISTS 13 +#define SRE_OP_IN 14 +#define SRE_OP_INFO 15 +#define SRE_OP_JUMP 16 +#define SRE_OP_LITERAL 17 +#define SRE_OP_MARK 18 +#define SRE_OP_MAX_UNTIL 19 +#define SRE_OP_MIN_UNTIL 20 +#define SRE_OP_NOT_LITERAL 21 +#define SRE_OP_NEGATE 22 +#define SRE_OP_RANGE 23 +#define SRE_OP_REPEAT 24 +#define SRE_OP_REPEAT_ONE 25 +#define SRE_OP_SUBPATTERN 26 +#define SRE_OP_MIN_REPEAT_ONE 27 +#define SRE_OP_GROUPREF_IGNORE 28 +#define SRE_OP_IN_IGNORE 29 +#define SRE_OP_LITERAL_IGNORE 30 +#define SRE_OP_NOT_LITERAL_IGNORE 31 +#define SRE_OP_GROUPREF_LOC_IGNORE 32 +#define SRE_OP_IN_LOC_IGNORE 33 +#define SRE_OP_LITERAL_LOC_IGNORE 34 +#define SRE_OP_NOT_LITERAL_LOC_IGNORE 35 +#define SRE_OP_GROUPREF_UNI_IGNORE 36 +#define SRE_OP_IN_UNI_IGNORE 37 +#define SRE_OP_LITERAL_UNI_IGNORE 38 +#define SRE_OP_NOT_LITERAL_UNI_IGNORE 39 +#define SRE_OP_RANGE_UNI_IGNORE 40 +#define SRE_AT_BEGINNING 0 +#define SRE_AT_BEGINNING_LINE 1 +#define SRE_AT_BEGINNING_STRING 2 +#define SRE_AT_BOUNDARY 3 +#define SRE_AT_NON_BOUNDARY 4 +#define SRE_AT_END 5 +#define SRE_AT_END_LINE 6 +#define SRE_AT_END_STRING 7 +#define SRE_AT_LOC_BOUNDARY 8 +#define SRE_AT_LOC_NON_BOUNDARY 9 +#define SRE_AT_UNI_BOUNDARY 10 +#define SRE_AT_UNI_NON_BOUNDARY 11 +#define SRE_CATEGORY_DIGIT 0 +#define SRE_CATEGORY_NOT_DIGIT 1 +#define SRE_CATEGORY_SPACE 2 +#define SRE_CATEGORY_NOT_SPACE 3 +#define SRE_CATEGORY_WORD 4 +#define SRE_CATEGORY_NOT_WORD 5 +#define SRE_CATEGORY_LINEBREAK 6 +#define SRE_CATEGORY_NOT_LINEBREAK 7 +#define SRE_CATEGORY_LOC_WORD 8 +#define SRE_CATEGORY_LOC_NOT_WORD 9 +#define SRE_CATEGORY_UNI_DIGIT 10 +#define SRE_CATEGORY_UNI_NOT_DIGIT 11 +#define SRE_CATEGORY_UNI_SPACE 12 +#define SRE_CATEGORY_UNI_NOT_SPACE 13 +#define SRE_CATEGORY_UNI_WORD 14 +#define SRE_CATEGORY_UNI_NOT_WORD 15 +#define SRE_CATEGORY_UNI_LINEBREAK 16 +#define SRE_CATEGORY_UNI_NOT_LINEBREAK 17 +#define SRE_FLAG_TEMPLATE 1 +#define SRE_FLAG_IGNORECASE 2 +#define SRE_FLAG_LOCALE 4 +#define SRE_FLAG_MULTILINE 8 +#define SRE_FLAG_DOTALL 16 +#define SRE_FLAG_UNICODE 32 +#define SRE_FLAG_VERBOSE 64 +#define SRE_FLAG_DEBUG 128 +#define SRE_FLAG_ASCII 256 +#define SRE_INFO_PREFIX 1 +#define SRE_INFO_LITERAL 2 +#define SRE_INFO_CHARSET 4 diff --git a/contrib/tools/python3/src/Modules/sre_lib.h b/contrib/tools/python3/src/Modules/sre_lib.h index 2657d8d82c6..2f17995d6ce 100644 --- a/contrib/tools/python3/src/Modules/sre_lib.h +++ b/contrib/tools/python3/src/Modules/sre_lib.h @@ -1,1548 +1,1548 @@ -/* - * Secret Labs' Regular Expression Engine - * - * regular expression matching engine - * - * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. - * - * See the _sre.c file for information on usage and redistribution. - */ - -/* String matching engine */ - -/* This file is included three times, with different character settings */ - -LOCAL(int) +/* + * Secret Labs' Regular Expression Engine + * + * regular expression matching engine + * + * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. + * + * See the _sre.c file for information on usage and redistribution. + */ + +/* String matching engine */ + +/* This file is included three times, with different character settings */ + +LOCAL(int) SRE(at)(SRE_STATE* state, const SRE_CHAR* ptr, SRE_CODE at) -{ - /* check if pointer is at given position */ - - Py_ssize_t thisp, thatp; - - switch (at) { - - case SRE_AT_BEGINNING: - case SRE_AT_BEGINNING_STRING: - return ((void*) ptr == state->beginning); - - case SRE_AT_BEGINNING_LINE: - return ((void*) ptr == state->beginning || - SRE_IS_LINEBREAK((int) ptr[-1])); - - case SRE_AT_END: - return (((SRE_CHAR *)state->end - ptr == 1 && - SRE_IS_LINEBREAK((int) ptr[0])) || - ((void*) ptr == state->end)); - - case SRE_AT_END_LINE: - return ((void*) ptr == state->end || - SRE_IS_LINEBREAK((int) ptr[0])); - - case SRE_AT_END_STRING: - return ((void*) ptr == state->end); - - case SRE_AT_BOUNDARY: - if (state->beginning == state->end) - return 0; - thatp = ((void*) ptr > state->beginning) ? - SRE_IS_WORD((int) ptr[-1]) : 0; - thisp = ((void*) ptr < state->end) ? - SRE_IS_WORD((int) ptr[0]) : 0; - return thisp != thatp; - - case SRE_AT_NON_BOUNDARY: - if (state->beginning == state->end) - return 0; - thatp = ((void*) ptr > state->beginning) ? - SRE_IS_WORD((int) ptr[-1]) : 0; - thisp = ((void*) ptr < state->end) ? - SRE_IS_WORD((int) ptr[0]) : 0; - return thisp == thatp; - - case SRE_AT_LOC_BOUNDARY: - if (state->beginning == state->end) - return 0; - thatp = ((void*) ptr > state->beginning) ? - SRE_LOC_IS_WORD((int) ptr[-1]) : 0; - thisp = ((void*) ptr < state->end) ? - SRE_LOC_IS_WORD((int) ptr[0]) : 0; - return thisp != thatp; - - case SRE_AT_LOC_NON_BOUNDARY: - if (state->beginning == state->end) - return 0; - thatp = ((void*) ptr > state->beginning) ? - SRE_LOC_IS_WORD((int) ptr[-1]) : 0; - thisp = ((void*) ptr < state->end) ? - SRE_LOC_IS_WORD((int) ptr[0]) : 0; - return thisp == thatp; - - case SRE_AT_UNI_BOUNDARY: - if (state->beginning == state->end) - return 0; - thatp = ((void*) ptr > state->beginning) ? - SRE_UNI_IS_WORD((int) ptr[-1]) : 0; - thisp = ((void*) ptr < state->end) ? - SRE_UNI_IS_WORD((int) ptr[0]) : 0; - return thisp != thatp; - - case SRE_AT_UNI_NON_BOUNDARY: - if (state->beginning == state->end) - return 0; - thatp = ((void*) ptr > state->beginning) ? - SRE_UNI_IS_WORD((int) ptr[-1]) : 0; - thisp = ((void*) ptr < state->end) ? - SRE_UNI_IS_WORD((int) ptr[0]) : 0; - return thisp == thatp; - - } - - return 0; -} - -LOCAL(int) +{ + /* check if pointer is at given position */ + + Py_ssize_t thisp, thatp; + + switch (at) { + + case SRE_AT_BEGINNING: + case SRE_AT_BEGINNING_STRING: + return ((void*) ptr == state->beginning); + + case SRE_AT_BEGINNING_LINE: + return ((void*) ptr == state->beginning || + SRE_IS_LINEBREAK((int) ptr[-1])); + + case SRE_AT_END: + return (((SRE_CHAR *)state->end - ptr == 1 && + SRE_IS_LINEBREAK((int) ptr[0])) || + ((void*) ptr == state->end)); + + case SRE_AT_END_LINE: + return ((void*) ptr == state->end || + SRE_IS_LINEBREAK((int) ptr[0])); + + case SRE_AT_END_STRING: + return ((void*) ptr == state->end); + + case SRE_AT_BOUNDARY: + if (state->beginning == state->end) + return 0; + thatp = ((void*) ptr > state->beginning) ? + SRE_IS_WORD((int) ptr[-1]) : 0; + thisp = ((void*) ptr < state->end) ? + SRE_IS_WORD((int) ptr[0]) : 0; + return thisp != thatp; + + case SRE_AT_NON_BOUNDARY: + if (state->beginning == state->end) + return 0; + thatp = ((void*) ptr > state->beginning) ? + SRE_IS_WORD((int) ptr[-1]) : 0; + thisp = ((void*) ptr < state->end) ? + SRE_IS_WORD((int) ptr[0]) : 0; + return thisp == thatp; + + case SRE_AT_LOC_BOUNDARY: + if (state->beginning == state->end) + return 0; + thatp = ((void*) ptr > state->beginning) ? + SRE_LOC_IS_WORD((int) ptr[-1]) : 0; + thisp = ((void*) ptr < state->end) ? + SRE_LOC_IS_WORD((int) ptr[0]) : 0; + return thisp != thatp; + + case SRE_AT_LOC_NON_BOUNDARY: + if (state->beginning == state->end) + return 0; + thatp = ((void*) ptr > state->beginning) ? + SRE_LOC_IS_WORD((int) ptr[-1]) : 0; + thisp = ((void*) ptr < state->end) ? + SRE_LOC_IS_WORD((int) ptr[0]) : 0; + return thisp == thatp; + + case SRE_AT_UNI_BOUNDARY: + if (state->beginning == state->end) + return 0; + thatp = ((void*) ptr > state->beginning) ? + SRE_UNI_IS_WORD((int) ptr[-1]) : 0; + thisp = ((void*) ptr < state->end) ? + SRE_UNI_IS_WORD((int) ptr[0]) : 0; + return thisp != thatp; + + case SRE_AT_UNI_NON_BOUNDARY: + if (state->beginning == state->end) + return 0; + thatp = ((void*) ptr > state->beginning) ? + SRE_UNI_IS_WORD((int) ptr[-1]) : 0; + thisp = ((void*) ptr < state->end) ? + SRE_UNI_IS_WORD((int) ptr[0]) : 0; + return thisp == thatp; + + } + + return 0; +} + +LOCAL(int) SRE(charset)(SRE_STATE* state, const SRE_CODE* set, SRE_CODE ch) -{ - /* check if character is a member of the given set */ - - int ok = 1; - - for (;;) { - switch (*set++) { - - case SRE_OP_FAILURE: - return !ok; - - case SRE_OP_LITERAL: - /* */ - if (ch == set[0]) - return ok; - set++; - break; - - case SRE_OP_CATEGORY: - /* */ - if (sre_category(set[0], (int) ch)) - return ok; - set++; - break; - - case SRE_OP_CHARSET: - /* */ - if (ch < 256 && - (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1))))) - return ok; - set += 256/SRE_CODE_BITS; - break; - - case SRE_OP_RANGE: - /* */ - if (set[0] <= ch && ch <= set[1]) - return ok; - set += 2; - break; - - case SRE_OP_RANGE_UNI_IGNORE: - /* */ - { - SRE_CODE uch; - /* ch is already lower cased */ - if (set[0] <= ch && ch <= set[1]) - return ok; - uch = sre_upper_unicode(ch); - if (set[0] <= uch && uch <= set[1]) - return ok; - set += 2; - break; - } - - case SRE_OP_NEGATE: - ok = !ok; - break; - - case SRE_OP_BIGCHARSET: - /* <256 blockindices> */ - { - Py_ssize_t count, block; - count = *(set++); - - if (ch < 0x10000u) - block = ((unsigned char*)set)[ch >> 8]; - else - block = -1; - set += 256/sizeof(SRE_CODE); - if (block >=0 && - (set[(block * 256 + (ch & 255))/SRE_CODE_BITS] & - (1u << (ch & (SRE_CODE_BITS-1))))) - return ok; - set += count * (256/SRE_CODE_BITS); - break; - } - - default: - /* internal error -- there's not much we can do about it - here, so let's just pretend it didn't match... */ - return 0; - } - } -} - -LOCAL(int) +{ + /* check if character is a member of the given set */ + + int ok = 1; + + for (;;) { + switch (*set++) { + + case SRE_OP_FAILURE: + return !ok; + + case SRE_OP_LITERAL: + /* */ + if (ch == set[0]) + return ok; + set++; + break; + + case SRE_OP_CATEGORY: + /* */ + if (sre_category(set[0], (int) ch)) + return ok; + set++; + break; + + case SRE_OP_CHARSET: + /* */ + if (ch < 256 && + (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1))))) + return ok; + set += 256/SRE_CODE_BITS; + break; + + case SRE_OP_RANGE: + /* */ + if (set[0] <= ch && ch <= set[1]) + return ok; + set += 2; + break; + + case SRE_OP_RANGE_UNI_IGNORE: + /* */ + { + SRE_CODE uch; + /* ch is already lower cased */ + if (set[0] <= ch && ch <= set[1]) + return ok; + uch = sre_upper_unicode(ch); + if (set[0] <= uch && uch <= set[1]) + return ok; + set += 2; + break; + } + + case SRE_OP_NEGATE: + ok = !ok; + break; + + case SRE_OP_BIGCHARSET: + /* <256 blockindices> */ + { + Py_ssize_t count, block; + count = *(set++); + + if (ch < 0x10000u) + block = ((unsigned char*)set)[ch >> 8]; + else + block = -1; + set += 256/sizeof(SRE_CODE); + if (block >=0 && + (set[(block * 256 + (ch & 255))/SRE_CODE_BITS] & + (1u << (ch & (SRE_CODE_BITS-1))))) + return ok; + set += count * (256/SRE_CODE_BITS); + break; + } + + default: + /* internal error -- there's not much we can do about it + here, so let's just pretend it didn't match... */ + return 0; + } + } +} + +LOCAL(int) SRE(charset_loc_ignore)(SRE_STATE* state, const SRE_CODE* set, SRE_CODE ch) -{ - SRE_CODE lo, up; - lo = sre_lower_locale(ch); - if (SRE(charset)(state, set, lo)) - return 1; - - up = sre_upper_locale(ch); - return up != lo && SRE(charset)(state, set, up); -} - +{ + SRE_CODE lo, up; + lo = sre_lower_locale(ch); + if (SRE(charset)(state, set, lo)) + return 1; + + up = sre_upper_locale(ch); + return up != lo && SRE(charset)(state, set, up); +} + LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel); - -LOCAL(Py_ssize_t) + +LOCAL(Py_ssize_t) SRE(count)(SRE_STATE* state, const SRE_CODE* pattern, Py_ssize_t maxcount) -{ - SRE_CODE chr; - SRE_CHAR c; +{ + SRE_CODE chr; + SRE_CHAR c; const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr; const SRE_CHAR* end = (const SRE_CHAR *)state->end; - Py_ssize_t i; - - /* adjust end */ - if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT) - end = ptr + maxcount; - - switch (pattern[0]) { - - case SRE_OP_IN: - /* repeated set */ - TRACE(("|%p|%p|COUNT IN\n", pattern, ptr)); - while (ptr < end && SRE(charset)(state, pattern + 2, *ptr)) - ptr++; - break; - - case SRE_OP_ANY: - /* repeated dot wildcard. */ - TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr)); - while (ptr < end && !SRE_IS_LINEBREAK(*ptr)) - ptr++; - break; - - case SRE_OP_ANY_ALL: - /* repeated dot wildcard. skip to the end of the target - string, and backtrack from there */ - TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr)); - ptr = end; - break; - - case SRE_OP_LITERAL: - /* repeated literal */ - chr = pattern[1]; - TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr)); - c = (SRE_CHAR) chr; -#if SIZEOF_SRE_CHAR < 4 - if ((SRE_CODE) c != chr) - ; /* literal can't match: doesn't fit in char width */ - else -#endif - while (ptr < end && *ptr == c) - ptr++; - break; - - case SRE_OP_LITERAL_IGNORE: - /* repeated literal */ - chr = pattern[1]; - TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr)); - while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) == chr) - ptr++; - break; - - case SRE_OP_LITERAL_UNI_IGNORE: - /* repeated literal */ - chr = pattern[1]; - TRACE(("|%p|%p|COUNT LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr)); - while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) == chr) - ptr++; - break; - - case SRE_OP_LITERAL_LOC_IGNORE: - /* repeated literal */ - chr = pattern[1]; - TRACE(("|%p|%p|COUNT LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr)); - while (ptr < end && char_loc_ignore(chr, *ptr)) - ptr++; - break; - - case SRE_OP_NOT_LITERAL: - /* repeated non-literal */ - chr = pattern[1]; - TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr)); - c = (SRE_CHAR) chr; -#if SIZEOF_SRE_CHAR < 4 - if ((SRE_CODE) c != chr) - ptr = end; /* literal can't match: doesn't fit in char width */ - else -#endif - while (ptr < end && *ptr != c) - ptr++; - break; - - case SRE_OP_NOT_LITERAL_IGNORE: - /* repeated non-literal */ - chr = pattern[1]; - TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr)); - while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) != chr) - ptr++; - break; - - case SRE_OP_NOT_LITERAL_UNI_IGNORE: - /* repeated non-literal */ - chr = pattern[1]; - TRACE(("|%p|%p|COUNT NOT_LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr)); - while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) != chr) - ptr++; - break; - - case SRE_OP_NOT_LITERAL_LOC_IGNORE: - /* repeated non-literal */ - chr = pattern[1]; - TRACE(("|%p|%p|COUNT NOT_LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr)); - while (ptr < end && !char_loc_ignore(chr, *ptr)) - ptr++; - break; - - default: - /* repeated single character pattern */ - TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr)); - while ((SRE_CHAR*) state->ptr < end) { - i = SRE(match)(state, pattern, 0); - if (i < 0) - return i; - if (!i) - break; - } - TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr, - (SRE_CHAR*) state->ptr - ptr)); - return (SRE_CHAR*) state->ptr - ptr; - } - - TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr, - ptr - (SRE_CHAR*) state->ptr)); - return ptr - (SRE_CHAR*) state->ptr; -} - -#if 0 /* not used in this release */ -LOCAL(int) + Py_ssize_t i; + + /* adjust end */ + if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT) + end = ptr + maxcount; + + switch (pattern[0]) { + + case SRE_OP_IN: + /* repeated set */ + TRACE(("|%p|%p|COUNT IN\n", pattern, ptr)); + while (ptr < end && SRE(charset)(state, pattern + 2, *ptr)) + ptr++; + break; + + case SRE_OP_ANY: + /* repeated dot wildcard. */ + TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr)); + while (ptr < end && !SRE_IS_LINEBREAK(*ptr)) + ptr++; + break; + + case SRE_OP_ANY_ALL: + /* repeated dot wildcard. skip to the end of the target + string, and backtrack from there */ + TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr)); + ptr = end; + break; + + case SRE_OP_LITERAL: + /* repeated literal */ + chr = pattern[1]; + TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr)); + c = (SRE_CHAR) chr; +#if SIZEOF_SRE_CHAR < 4 + if ((SRE_CODE) c != chr) + ; /* literal can't match: doesn't fit in char width */ + else +#endif + while (ptr < end && *ptr == c) + ptr++; + break; + + case SRE_OP_LITERAL_IGNORE: + /* repeated literal */ + chr = pattern[1]; + TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr)); + while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) == chr) + ptr++; + break; + + case SRE_OP_LITERAL_UNI_IGNORE: + /* repeated literal */ + chr = pattern[1]; + TRACE(("|%p|%p|COUNT LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr)); + while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) == chr) + ptr++; + break; + + case SRE_OP_LITERAL_LOC_IGNORE: + /* repeated literal */ + chr = pattern[1]; + TRACE(("|%p|%p|COUNT LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr)); + while (ptr < end && char_loc_ignore(chr, *ptr)) + ptr++; + break; + + case SRE_OP_NOT_LITERAL: + /* repeated non-literal */ + chr = pattern[1]; + TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr)); + c = (SRE_CHAR) chr; +#if SIZEOF_SRE_CHAR < 4 + if ((SRE_CODE) c != chr) + ptr = end; /* literal can't match: doesn't fit in char width */ + else +#endif + while (ptr < end && *ptr != c) + ptr++; + break; + + case SRE_OP_NOT_LITERAL_IGNORE: + /* repeated non-literal */ + chr = pattern[1]; + TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr)); + while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) != chr) + ptr++; + break; + + case SRE_OP_NOT_LITERAL_UNI_IGNORE: + /* repeated non-literal */ + chr = pattern[1]; + TRACE(("|%p|%p|COUNT NOT_LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr)); + while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) != chr) + ptr++; + break; + + case SRE_OP_NOT_LITERAL_LOC_IGNORE: + /* repeated non-literal */ + chr = pattern[1]; + TRACE(("|%p|%p|COUNT NOT_LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr)); + while (ptr < end && !char_loc_ignore(chr, *ptr)) + ptr++; + break; + + default: + /* repeated single character pattern */ + TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr)); + while ((SRE_CHAR*) state->ptr < end) { + i = SRE(match)(state, pattern, 0); + if (i < 0) + return i; + if (!i) + break; + } + TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr, + (SRE_CHAR*) state->ptr - ptr)); + return (SRE_CHAR*) state->ptr - ptr; + } + + TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr, + ptr - (SRE_CHAR*) state->ptr)); + return ptr - (SRE_CHAR*) state->ptr; +} + +#if 0 /* not used in this release */ +LOCAL(int) SRE(info)(SRE_STATE* state, const SRE_CODE* pattern) -{ - /* check if an SRE_OP_INFO block matches at the current position. - returns the number of SRE_CODE objects to skip if successful, 0 - if no match */ - +{ + /* check if an SRE_OP_INFO block matches at the current position. + returns the number of SRE_CODE objects to skip if successful, 0 + if no match */ + const SRE_CHAR* end = (const SRE_CHAR*) state->end; const SRE_CHAR* ptr = (const SRE_CHAR*) state->ptr; - Py_ssize_t i; - - /* check minimal length */ - if (pattern[3] && end - ptr < pattern[3]) - return 0; - - /* check known prefix */ - if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) { - /* */ - for (i = 0; i < pattern[5]; i++) - if ((SRE_CODE) ptr[i] != pattern[7 + i]) - return 0; - return pattern[0] + 2 * pattern[6]; - } - return pattern[0]; -} -#endif - -/* The macros below should be used to protect recursive SRE(match)() - * calls that *failed* and do *not* return immediately (IOW, those - * that will backtrack). Explaining: - * - * - Recursive SRE(match)() returned true: that's usually a success - * (besides atypical cases like ASSERT_NOT), therefore there's no - * reason to restore lastmark; - * - * - Recursive SRE(match)() returned false but the current SRE(match)() - * is returning to the caller: If the current SRE(match)() is the - * top function of the recursion, returning false will be a matching - * failure, and it doesn't matter where lastmark is pointing to. - * If it's *not* the top function, it will be a recursive SRE(match)() - * failure by itself, and the calling SRE(match)() will have to deal - * with the failure by the same rules explained here (it will restore - * lastmark by itself if necessary); - * - * - Recursive SRE(match)() returned false, and will continue the - * outside 'for' loop: must be protected when breaking, since the next - * OP could potentially depend on lastmark; - * - * - Recursive SRE(match)() returned false, and will be called again - * inside a local for/while loop: must be protected between each - * loop iteration, since the recursive SRE(match)() could do anything, - * and could potentially depend on lastmark. - * - * For more information, check the discussion at SF patch #712900. - */ -#define LASTMARK_SAVE() \ - do { \ - ctx->lastmark = state->lastmark; \ - ctx->lastindex = state->lastindex; \ - } while (0) -#define LASTMARK_RESTORE() \ - do { \ - state->lastmark = ctx->lastmark; \ - state->lastindex = ctx->lastindex; \ - } while (0) - -#define RETURN_ERROR(i) do { return i; } while(0) -#define RETURN_FAILURE do { ret = 0; goto exit; } while(0) -#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0) - -#define RETURN_ON_ERROR(i) \ - do { if (i < 0) RETURN_ERROR(i); } while (0) -#define RETURN_ON_SUCCESS(i) \ - do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0) -#define RETURN_ON_FAILURE(i) \ - do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0) - -#define DATA_STACK_ALLOC(state, type, ptr) \ -do { \ - alloc_pos = state->data_stack_base; \ - TRACE(("allocating %s in %" PY_FORMAT_SIZE_T "d " \ - "(%" PY_FORMAT_SIZE_T "d)\n", \ - Py_STRINGIFY(type), alloc_pos, sizeof(type))); \ - if (sizeof(type) > state->data_stack_size - alloc_pos) { \ - int j = data_stack_grow(state, sizeof(type)); \ - if (j < 0) return j; \ - if (ctx_pos != -1) \ - DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \ - } \ - ptr = (type*)(state->data_stack+alloc_pos); \ - state->data_stack_base += sizeof(type); \ -} while (0) - -#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \ -do { \ - TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", Py_STRINGIFY(type), pos)); \ - ptr = (type*)(state->data_stack+pos); \ -} while (0) - -#define DATA_STACK_PUSH(state, data, size) \ -do { \ - TRACE(("copy data in %p to %" PY_FORMAT_SIZE_T "d " \ - "(%" PY_FORMAT_SIZE_T "d)\n", \ - data, state->data_stack_base, size)); \ - if (size > state->data_stack_size - state->data_stack_base) { \ - int j = data_stack_grow(state, size); \ - if (j < 0) return j; \ - if (ctx_pos != -1) \ - DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \ - } \ - memcpy(state->data_stack+state->data_stack_base, data, size); \ - state->data_stack_base += size; \ -} while (0) - + Py_ssize_t i; + + /* check minimal length */ + if (pattern[3] && end - ptr < pattern[3]) + return 0; + + /* check known prefix */ + if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) { + /* */ + for (i = 0; i < pattern[5]; i++) + if ((SRE_CODE) ptr[i] != pattern[7 + i]) + return 0; + return pattern[0] + 2 * pattern[6]; + } + return pattern[0]; +} +#endif + +/* The macros below should be used to protect recursive SRE(match)() + * calls that *failed* and do *not* return immediately (IOW, those + * that will backtrack). Explaining: + * + * - Recursive SRE(match)() returned true: that's usually a success + * (besides atypical cases like ASSERT_NOT), therefore there's no + * reason to restore lastmark; + * + * - Recursive SRE(match)() returned false but the current SRE(match)() + * is returning to the caller: If the current SRE(match)() is the + * top function of the recursion, returning false will be a matching + * failure, and it doesn't matter where lastmark is pointing to. + * If it's *not* the top function, it will be a recursive SRE(match)() + * failure by itself, and the calling SRE(match)() will have to deal + * with the failure by the same rules explained here (it will restore + * lastmark by itself if necessary); + * + * - Recursive SRE(match)() returned false, and will continue the + * outside 'for' loop: must be protected when breaking, since the next + * OP could potentially depend on lastmark; + * + * - Recursive SRE(match)() returned false, and will be called again + * inside a local for/while loop: must be protected between each + * loop iteration, since the recursive SRE(match)() could do anything, + * and could potentially depend on lastmark. + * + * For more information, check the discussion at SF patch #712900. + */ +#define LASTMARK_SAVE() \ + do { \ + ctx->lastmark = state->lastmark; \ + ctx->lastindex = state->lastindex; \ + } while (0) +#define LASTMARK_RESTORE() \ + do { \ + state->lastmark = ctx->lastmark; \ + state->lastindex = ctx->lastindex; \ + } while (0) + +#define RETURN_ERROR(i) do { return i; } while(0) +#define RETURN_FAILURE do { ret = 0; goto exit; } while(0) +#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0) + +#define RETURN_ON_ERROR(i) \ + do { if (i < 0) RETURN_ERROR(i); } while (0) +#define RETURN_ON_SUCCESS(i) \ + do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0) +#define RETURN_ON_FAILURE(i) \ + do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0) + +#define DATA_STACK_ALLOC(state, type, ptr) \ +do { \ + alloc_pos = state->data_stack_base; \ + TRACE(("allocating %s in %" PY_FORMAT_SIZE_T "d " \ + "(%" PY_FORMAT_SIZE_T "d)\n", \ + Py_STRINGIFY(type), alloc_pos, sizeof(type))); \ + if (sizeof(type) > state->data_stack_size - alloc_pos) { \ + int j = data_stack_grow(state, sizeof(type)); \ + if (j < 0) return j; \ + if (ctx_pos != -1) \ + DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \ + } \ + ptr = (type*)(state->data_stack+alloc_pos); \ + state->data_stack_base += sizeof(type); \ +} while (0) + +#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \ +do { \ + TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", Py_STRINGIFY(type), pos)); \ + ptr = (type*)(state->data_stack+pos); \ +} while (0) + +#define DATA_STACK_PUSH(state, data, size) \ +do { \ + TRACE(("copy data in %p to %" PY_FORMAT_SIZE_T "d " \ + "(%" PY_FORMAT_SIZE_T "d)\n", \ + data, state->data_stack_base, size)); \ + if (size > state->data_stack_size - state->data_stack_base) { \ + int j = data_stack_grow(state, size); \ + if (j < 0) return j; \ + if (ctx_pos != -1) \ + DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \ + } \ + memcpy(state->data_stack+state->data_stack_base, data, size); \ + state->data_stack_base += size; \ +} while (0) + /* We add an explicit cast to memcpy here because MSVC has a bug when compiling C code where it believes that `const void**` cannot be safely casted to `void*`, see bpo-39943 for details. */ -#define DATA_STACK_POP(state, data, size, discard) \ -do { \ - TRACE(("copy data to %p from %" PY_FORMAT_SIZE_T "d " \ - "(%" PY_FORMAT_SIZE_T "d)\n", \ - data, state->data_stack_base-size, size)); \ +#define DATA_STACK_POP(state, data, size, discard) \ +do { \ + TRACE(("copy data to %p from %" PY_FORMAT_SIZE_T "d " \ + "(%" PY_FORMAT_SIZE_T "d)\n", \ + data, state->data_stack_base-size, size)); \ memcpy((void*) data, state->data_stack+state->data_stack_base-size, size); \ - if (discard) \ - state->data_stack_base -= size; \ -} while (0) - -#define DATA_STACK_POP_DISCARD(state, size) \ -do { \ - TRACE(("discard data from %" PY_FORMAT_SIZE_T "d " \ - "(%" PY_FORMAT_SIZE_T "d)\n", \ - state->data_stack_base-size, size)); \ - state->data_stack_base -= size; \ -} while(0) - -#define DATA_PUSH(x) \ - DATA_STACK_PUSH(state, (x), sizeof(*(x))) -#define DATA_POP(x) \ - DATA_STACK_POP(state, (x), sizeof(*(x)), 1) -#define DATA_POP_DISCARD(x) \ - DATA_STACK_POP_DISCARD(state, sizeof(*(x))) -#define DATA_ALLOC(t,p) \ - DATA_STACK_ALLOC(state, t, p) -#define DATA_LOOKUP_AT(t,p,pos) \ - DATA_STACK_LOOKUP_AT(state,t,p,pos) - -#define MARK_PUSH(lastmark) \ - do if (lastmark > 0) { \ - i = lastmark; /* ctx->lastmark may change if reallocated */ \ - DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \ - } while (0) -#define MARK_POP(lastmark) \ - do if (lastmark > 0) { \ - DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \ - } while (0) -#define MARK_POP_KEEP(lastmark) \ - do if (lastmark > 0) { \ - DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \ - } while (0) -#define MARK_POP_DISCARD(lastmark) \ - do if (lastmark > 0) { \ - DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \ - } while (0) - -#define JUMP_NONE 0 -#define JUMP_MAX_UNTIL_1 1 -#define JUMP_MAX_UNTIL_2 2 -#define JUMP_MAX_UNTIL_3 3 -#define JUMP_MIN_UNTIL_1 4 -#define JUMP_MIN_UNTIL_2 5 -#define JUMP_MIN_UNTIL_3 6 -#define JUMP_REPEAT 7 -#define JUMP_REPEAT_ONE_1 8 -#define JUMP_REPEAT_ONE_2 9 -#define JUMP_MIN_REPEAT_ONE 10 -#define JUMP_BRANCH 11 -#define JUMP_ASSERT 12 -#define JUMP_ASSERT_NOT 13 - -#define DO_JUMPX(jumpvalue, jumplabel, nextpattern, toplevel_) \ - DATA_ALLOC(SRE(match_context), nextctx); \ - nextctx->last_ctx_pos = ctx_pos; \ - nextctx->jump = jumpvalue; \ - nextctx->pattern = nextpattern; \ - nextctx->toplevel = toplevel_; \ - ctx_pos = alloc_pos; \ - ctx = nextctx; \ - goto entrance; \ - jumplabel: \ - while (0) /* gcc doesn't like labels at end of scopes */ \ - -#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \ - DO_JUMPX(jumpvalue, jumplabel, nextpattern, ctx->toplevel) - -#define DO_JUMP0(jumpvalue, jumplabel, nextpattern) \ - DO_JUMPX(jumpvalue, jumplabel, nextpattern, 0) - -typedef struct { - Py_ssize_t last_ctx_pos; - Py_ssize_t jump; + if (discard) \ + state->data_stack_base -= size; \ +} while (0) + +#define DATA_STACK_POP_DISCARD(state, size) \ +do { \ + TRACE(("discard data from %" PY_FORMAT_SIZE_T "d " \ + "(%" PY_FORMAT_SIZE_T "d)\n", \ + state->data_stack_base-size, size)); \ + state->data_stack_base -= size; \ +} while(0) + +#define DATA_PUSH(x) \ + DATA_STACK_PUSH(state, (x), sizeof(*(x))) +#define DATA_POP(x) \ + DATA_STACK_POP(state, (x), sizeof(*(x)), 1) +#define DATA_POP_DISCARD(x) \ + DATA_STACK_POP_DISCARD(state, sizeof(*(x))) +#define DATA_ALLOC(t,p) \ + DATA_STACK_ALLOC(state, t, p) +#define DATA_LOOKUP_AT(t,p,pos) \ + DATA_STACK_LOOKUP_AT(state,t,p,pos) + +#define MARK_PUSH(lastmark) \ + do if (lastmark > 0) { \ + i = lastmark; /* ctx->lastmark may change if reallocated */ \ + DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \ + } while (0) +#define MARK_POP(lastmark) \ + do if (lastmark > 0) { \ + DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \ + } while (0) +#define MARK_POP_KEEP(lastmark) \ + do if (lastmark > 0) { \ + DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \ + } while (0) +#define MARK_POP_DISCARD(lastmark) \ + do if (lastmark > 0) { \ + DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \ + } while (0) + +#define JUMP_NONE 0 +#define JUMP_MAX_UNTIL_1 1 +#define JUMP_MAX_UNTIL_2 2 +#define JUMP_MAX_UNTIL_3 3 +#define JUMP_MIN_UNTIL_1 4 +#define JUMP_MIN_UNTIL_2 5 +#define JUMP_MIN_UNTIL_3 6 +#define JUMP_REPEAT 7 +#define JUMP_REPEAT_ONE_1 8 +#define JUMP_REPEAT_ONE_2 9 +#define JUMP_MIN_REPEAT_ONE 10 +#define JUMP_BRANCH 11 +#define JUMP_ASSERT 12 +#define JUMP_ASSERT_NOT 13 + +#define DO_JUMPX(jumpvalue, jumplabel, nextpattern, toplevel_) \ + DATA_ALLOC(SRE(match_context), nextctx); \ + nextctx->last_ctx_pos = ctx_pos; \ + nextctx->jump = jumpvalue; \ + nextctx->pattern = nextpattern; \ + nextctx->toplevel = toplevel_; \ + ctx_pos = alloc_pos; \ + ctx = nextctx; \ + goto entrance; \ + jumplabel: \ + while (0) /* gcc doesn't like labels at end of scopes */ \ + +#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \ + DO_JUMPX(jumpvalue, jumplabel, nextpattern, ctx->toplevel) + +#define DO_JUMP0(jumpvalue, jumplabel, nextpattern) \ + DO_JUMPX(jumpvalue, jumplabel, nextpattern, 0) + +typedef struct { + Py_ssize_t last_ctx_pos; + Py_ssize_t jump; const SRE_CHAR* ptr; const SRE_CODE* pattern; - Py_ssize_t count; - Py_ssize_t lastmark; - Py_ssize_t lastindex; - union { - SRE_CODE chr; - SRE_REPEAT* rep; - } u; - int toplevel; -} SRE(match_context); - -/* check if string matches the given pattern. returns <0 for - error, 0 for failure, and 1 for success */ -LOCAL(Py_ssize_t) + Py_ssize_t count; + Py_ssize_t lastmark; + Py_ssize_t lastindex; + union { + SRE_CODE chr; + SRE_REPEAT* rep; + } u; + int toplevel; +} SRE(match_context); + +/* check if string matches the given pattern. returns <0 for + error, 0 for failure, and 1 for success */ +LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) -{ +{ const SRE_CHAR* end = (const SRE_CHAR *)state->end; - Py_ssize_t alloc_pos, ctx_pos = -1; - Py_ssize_t i, ret = 0; - Py_ssize_t jump; - unsigned int sigcount=0; - - SRE(match_context)* ctx; - SRE(match_context)* nextctx; - - TRACE(("|%p|%p|ENTER\n", pattern, state->ptr)); - - DATA_ALLOC(SRE(match_context), ctx); - ctx->last_ctx_pos = -1; - ctx->jump = JUMP_NONE; - ctx->pattern = pattern; - ctx->toplevel = toplevel; - ctx_pos = alloc_pos; - -entrance: - - ctx->ptr = (SRE_CHAR *)state->ptr; - - if (ctx->pattern[0] == SRE_OP_INFO) { - /* optimization info block */ - /* <1=skip> <2=flags> <3=min> ... */ - if (ctx->pattern[3] && (uintptr_t)(end - ctx->ptr) < ctx->pattern[3]) { - TRACE(("reject (got %" PY_FORMAT_SIZE_T "d chars, " - "need %" PY_FORMAT_SIZE_T "d)\n", - end - ctx->ptr, (Py_ssize_t) ctx->pattern[3])); - RETURN_FAILURE; - } - ctx->pattern += ctx->pattern[1] + 1; - } - - for (;;) { - ++sigcount; - if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals()) - RETURN_ERROR(SRE_ERROR_INTERRUPTED); - - switch (*ctx->pattern++) { - - case SRE_OP_MARK: - /* set mark */ - /* */ - TRACE(("|%p|%p|MARK %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - if (i & 1) - state->lastindex = i/2 + 1; - if (i > state->lastmark) { - /* state->lastmark is the highest valid index in the - state->mark array. If it is increased by more than 1, - the intervening marks must be set to NULL to signal - that these marks have not been encountered. */ - Py_ssize_t j = state->lastmark + 1; - while (j < i) - state->mark[j++] = NULL; - state->lastmark = i; - } - state->mark[i] = ctx->ptr; - ctx->pattern++; - break; - - case SRE_OP_LITERAL: - /* match literal string */ - /* */ - TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern, - ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0]) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_NOT_LITERAL: - /* match anything that is not literal character */ - /* */ - TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern, - ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0]) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_SUCCESS: - /* end of pattern */ - TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr)); - if (ctx->toplevel && - ((state->match_all && ctx->ptr != state->end) || - (state->must_advance && ctx->ptr == state->start))) - { - RETURN_FAILURE; - } - state->ptr = ctx->ptr; - RETURN_SUCCESS; - - case SRE_OP_AT: - /* match at given position */ - /* */ - TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern)); - if (!SRE(at)(state, ctx->ptr, *ctx->pattern)) - RETURN_FAILURE; - ctx->pattern++; - break; - - case SRE_OP_CATEGORY: - /* match at given category */ - /* */ - TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern, - ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0])) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_ANY: - /* match anything (except a newline) */ - /* */ - TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0])) - RETURN_FAILURE; - ctx->ptr++; - break; - - case SRE_OP_ANY_ALL: - /* match anything */ - /* */ - TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end) - RETURN_FAILURE; - ctx->ptr++; - break; - - case SRE_OP_IN: - /* match set member (or non_member) */ - /* */ - TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end || - !SRE(charset)(state, ctx->pattern + 1, *ctx->ptr)) - RETURN_FAILURE; - ctx->pattern += ctx->pattern[0]; - ctx->ptr++; - break; - - case SRE_OP_LITERAL_IGNORE: - TRACE(("|%p|%p|LITERAL_IGNORE %d\n", - ctx->pattern, ctx->ptr, ctx->pattern[0])); - if (ctx->ptr >= end || - sre_lower_ascii(*ctx->ptr) != *ctx->pattern) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_LITERAL_UNI_IGNORE: - TRACE(("|%p|%p|LITERAL_UNI_IGNORE %d\n", - ctx->pattern, ctx->ptr, ctx->pattern[0])); - if (ctx->ptr >= end || - sre_lower_unicode(*ctx->ptr) != *ctx->pattern) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_LITERAL_LOC_IGNORE: - TRACE(("|%p|%p|LITERAL_LOC_IGNORE %d\n", - ctx->pattern, ctx->ptr, ctx->pattern[0])); - if (ctx->ptr >= end - || !char_loc_ignore(*ctx->pattern, *ctx->ptr)) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_NOT_LITERAL_IGNORE: - TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n", - ctx->pattern, ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || - sre_lower_ascii(*ctx->ptr) == *ctx->pattern) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_NOT_LITERAL_UNI_IGNORE: - TRACE(("|%p|%p|NOT_LITERAL_UNI_IGNORE %d\n", - ctx->pattern, ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || - sre_lower_unicode(*ctx->ptr) == *ctx->pattern) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_NOT_LITERAL_LOC_IGNORE: - TRACE(("|%p|%p|NOT_LITERAL_LOC_IGNORE %d\n", - ctx->pattern, ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end - || char_loc_ignore(*ctx->pattern, *ctx->ptr)) - RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; - - case SRE_OP_IN_IGNORE: - TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end - || !SRE(charset)(state, ctx->pattern+1, - (SRE_CODE)sre_lower_ascii(*ctx->ptr))) - RETURN_FAILURE; - ctx->pattern += ctx->pattern[0]; - ctx->ptr++; - break; - - case SRE_OP_IN_UNI_IGNORE: - TRACE(("|%p|%p|IN_UNI_IGNORE\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end - || !SRE(charset)(state, ctx->pattern+1, - (SRE_CODE)sre_lower_unicode(*ctx->ptr))) - RETURN_FAILURE; - ctx->pattern += ctx->pattern[0]; - ctx->ptr++; - break; - - case SRE_OP_IN_LOC_IGNORE: - TRACE(("|%p|%p|IN_LOC_IGNORE\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end - || !SRE(charset_loc_ignore)(state, ctx->pattern+1, *ctx->ptr)) - RETURN_FAILURE; - ctx->pattern += ctx->pattern[0]; - ctx->ptr++; - break; - - case SRE_OP_JUMP: - case SRE_OP_INFO: - /* jump forward */ - /* */ - TRACE(("|%p|%p|JUMP %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - ctx->pattern += ctx->pattern[0]; - break; - - case SRE_OP_BRANCH: - /* alternation */ - /* <0=skip> code ... */ - TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr)); - LASTMARK_SAVE(); - ctx->u.rep = state->repeat; - if (ctx->u.rep) - MARK_PUSH(ctx->lastmark); - for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) { - if (ctx->pattern[1] == SRE_OP_LITERAL && - (ctx->ptr >= end || - (SRE_CODE) *ctx->ptr != ctx->pattern[2])) - continue; - if (ctx->pattern[1] == SRE_OP_IN && - (ctx->ptr >= end || - !SRE(charset)(state, ctx->pattern + 3, - (SRE_CODE) *ctx->ptr))) - continue; - state->ptr = ctx->ptr; - DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1); - if (ret) { - if (ctx->u.rep) - MARK_POP_DISCARD(ctx->lastmark); - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - if (ctx->u.rep) - MARK_POP_KEEP(ctx->lastmark); - LASTMARK_RESTORE(); - } - if (ctx->u.rep) - MARK_POP_DISCARD(ctx->lastmark); - RETURN_FAILURE; - - case SRE_OP_REPEAT_ONE: - /* match repeated sequence (maximizing regexp) */ - - /* this operator only works if the repeated item is - exactly one character wide, and we're not already - collecting backtracking points. for other cases, - use the MAX_REPEAT operator */ - - /* <1=min> <2=max> item tail */ - - TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[1], ctx->pattern[2])); - - if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr) - RETURN_FAILURE; /* cannot match */ - - state->ptr = ctx->ptr; - - ret = SRE(count)(state, ctx->pattern+3, ctx->pattern[2]); - RETURN_ON_ERROR(ret); - DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); - ctx->count = ret; - ctx->ptr += ctx->count; - - /* when we arrive here, count contains the number of - matches, and ctx->ptr points to the tail of the target - string. check if the rest of the pattern matches, - and backtrack if not. */ - - if (ctx->count < (Py_ssize_t) ctx->pattern[1]) - RETURN_FAILURE; - - if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && - ctx->ptr == state->end && - !(ctx->toplevel && state->must_advance && ctx->ptr == state->start)) - { - /* tail is empty. we're finished */ - state->ptr = ctx->ptr; - RETURN_SUCCESS; - } - - LASTMARK_SAVE(); - - if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) { - /* tail starts with a literal. skip positions where - the rest of the pattern cannot possibly match */ - ctx->u.chr = ctx->pattern[ctx->pattern[0]+1]; - for (;;) { - while (ctx->count >= (Py_ssize_t) ctx->pattern[1] && - (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) { - ctx->ptr--; - ctx->count--; - } - if (ctx->count < (Py_ssize_t) ctx->pattern[1]) - break; - state->ptr = ctx->ptr; - DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1, - ctx->pattern+ctx->pattern[0]); - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - - LASTMARK_RESTORE(); - - ctx->ptr--; - ctx->count--; - } - - } else { - /* general case */ - while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) { - state->ptr = ctx->ptr; - DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2, - ctx->pattern+ctx->pattern[0]); - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - ctx->ptr--; - ctx->count--; - LASTMARK_RESTORE(); - } - } - RETURN_FAILURE; - - case SRE_OP_MIN_REPEAT_ONE: - /* match repeated sequence (minimizing regexp) */ - - /* this operator only works if the repeated item is - exactly one character wide, and we're not already - collecting backtracking points. for other cases, - use the MIN_REPEAT operator */ - - /* <1=min> <2=max> item tail */ - - TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[1], ctx->pattern[2])); - - if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr) - RETURN_FAILURE; /* cannot match */ - - state->ptr = ctx->ptr; - - if (ctx->pattern[1] == 0) - ctx->count = 0; - else { - /* count using pattern min as the maximum */ - ret = SRE(count)(state, ctx->pattern+3, ctx->pattern[1]); - RETURN_ON_ERROR(ret); - DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); - if (ret < (Py_ssize_t) ctx->pattern[1]) - /* didn't match minimum number of times */ - RETURN_FAILURE; - /* advance past minimum matches of repeat */ - ctx->count = ret; - ctx->ptr += ctx->count; - } - - if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && - !(ctx->toplevel && - ((state->match_all && ctx->ptr != state->end) || - (state->must_advance && ctx->ptr == state->start)))) - { - /* tail is empty. we're finished */ - state->ptr = ctx->ptr; - RETURN_SUCCESS; - - } else { - /* general case */ - LASTMARK_SAVE(); - while ((Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT - || ctx->count <= (Py_ssize_t)ctx->pattern[2]) { - state->ptr = ctx->ptr; - DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one, - ctx->pattern+ctx->pattern[0]); - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - state->ptr = ctx->ptr; - ret = SRE(count)(state, ctx->pattern+3, 1); - RETURN_ON_ERROR(ret); - DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); - if (ret == 0) - break; - assert(ret == 1); - ctx->ptr++; - ctx->count++; - LASTMARK_RESTORE(); - } - } - RETURN_FAILURE; - - case SRE_OP_REPEAT: - /* create repeat context. all the hard work is done - by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */ - /* <1=min> <2=max> item tail */ - TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[1], ctx->pattern[2])); - - /* install new repeat context */ - ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep)); - if (!ctx->u.rep) { - PyErr_NoMemory(); - RETURN_FAILURE; - } - ctx->u.rep->count = -1; - ctx->u.rep->pattern = ctx->pattern; - ctx->u.rep->prev = state->repeat; - ctx->u.rep->last_ptr = NULL; - state->repeat = ctx->u.rep; - - state->ptr = ctx->ptr; - DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]); - state->repeat = ctx->u.rep->prev; - PyObject_FREE(ctx->u.rep); - - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - RETURN_FAILURE; - - case SRE_OP_MAX_UNTIL: - /* maximizing repeat */ - /* <1=min> <2=max> item tail */ - - /* FIXME: we probably need to deal with zero-width - matches in here... */ - - ctx->u.rep = state->repeat; - if (!ctx->u.rep) - RETURN_ERROR(SRE_ERROR_STATE); - - state->ptr = ctx->ptr; - - ctx->count = ctx->u.rep->count+1; - - TRACE(("|%p|%p|MAX_UNTIL %" PY_FORMAT_SIZE_T "d\n", ctx->pattern, - ctx->ptr, ctx->count)); - - if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { - /* not enough matches */ - ctx->u.rep->count = ctx->count; - DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1, - ctx->u.rep->pattern+3); - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - ctx->u.rep->count = ctx->count-1; - state->ptr = ctx->ptr; - RETURN_FAILURE; - } - - if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] || - ctx->u.rep->pattern[2] == SRE_MAXREPEAT) && - state->ptr != ctx->u.rep->last_ptr) { - /* we may have enough matches, but if we can - match another item, do so */ - ctx->u.rep->count = ctx->count; - LASTMARK_SAVE(); - MARK_PUSH(ctx->lastmark); - /* zero-width match protection */ - DATA_PUSH(&ctx->u.rep->last_ptr); - ctx->u.rep->last_ptr = state->ptr; - DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2, - ctx->u.rep->pattern+3); - DATA_POP(&ctx->u.rep->last_ptr); - if (ret) { - MARK_POP_DISCARD(ctx->lastmark); - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - MARK_POP(ctx->lastmark); - LASTMARK_RESTORE(); - ctx->u.rep->count = ctx->count-1; - state->ptr = ctx->ptr; - } - - /* cannot match more repeated items here. make sure the - tail matches */ - state->repeat = ctx->u.rep->prev; - DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern); - RETURN_ON_SUCCESS(ret); - state->repeat = ctx->u.rep; - state->ptr = ctx->ptr; - RETURN_FAILURE; - - case SRE_OP_MIN_UNTIL: - /* minimizing repeat */ - /* <1=min> <2=max> item tail */ - - ctx->u.rep = state->repeat; - if (!ctx->u.rep) - RETURN_ERROR(SRE_ERROR_STATE); - - state->ptr = ctx->ptr; - - ctx->count = ctx->u.rep->count+1; - - TRACE(("|%p|%p|MIN_UNTIL %" PY_FORMAT_SIZE_T "d %p\n", ctx->pattern, - ctx->ptr, ctx->count, ctx->u.rep->pattern)); - - if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { - /* not enough matches */ - ctx->u.rep->count = ctx->count; - DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1, - ctx->u.rep->pattern+3); - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - ctx->u.rep->count = ctx->count-1; - state->ptr = ctx->ptr; - RETURN_FAILURE; - } - - LASTMARK_SAVE(); - - /* see if the tail matches */ - state->repeat = ctx->u.rep->prev; - DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern); - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - - state->repeat = ctx->u.rep; - state->ptr = ctx->ptr; - - LASTMARK_RESTORE(); - - if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2] - && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) || - state->ptr == ctx->u.rep->last_ptr) - RETURN_FAILURE; - - ctx->u.rep->count = ctx->count; - /* zero-width match protection */ - DATA_PUSH(&ctx->u.rep->last_ptr); - ctx->u.rep->last_ptr = state->ptr; - DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3, - ctx->u.rep->pattern+3); - DATA_POP(&ctx->u.rep->last_ptr); - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_SUCCESS; - } - ctx->u.rep->count = ctx->count-1; - state->ptr = ctx->ptr; - RETURN_FAILURE; - - case SRE_OP_GROUPREF: - /* match backreference */ - TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - RETURN_FAILURE; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) - RETURN_FAILURE; - while (p < e) { - if (ctx->ptr >= end || *ctx->ptr != *p) - RETURN_FAILURE; - p++; - ctx->ptr++; - } - } - } - ctx->pattern++; - break; - - case SRE_OP_GROUPREF_IGNORE: - /* match backreference */ - TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - RETURN_FAILURE; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) - RETURN_FAILURE; - while (p < e) { - if (ctx->ptr >= end || - sre_lower_ascii(*ctx->ptr) != sre_lower_ascii(*p)) - RETURN_FAILURE; - p++; - ctx->ptr++; - } - } - } - ctx->pattern++; - break; - - case SRE_OP_GROUPREF_UNI_IGNORE: - /* match backreference */ - TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - RETURN_FAILURE; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) - RETURN_FAILURE; - while (p < e) { - if (ctx->ptr >= end || - sre_lower_unicode(*ctx->ptr) != sre_lower_unicode(*p)) - RETURN_FAILURE; - p++; - ctx->ptr++; - } - } - } - ctx->pattern++; - break; - - case SRE_OP_GROUPREF_LOC_IGNORE: - /* match backreference */ - TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - RETURN_FAILURE; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) - RETURN_FAILURE; - while (p < e) { - if (ctx->ptr >= end || - sre_lower_locale(*ctx->ptr) != sre_lower_locale(*p)) - RETURN_FAILURE; - p++; - ctx->ptr++; - } - } - } - ctx->pattern++; - break; - - case SRE_OP_GROUPREF_EXISTS: - TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - /* codeyes codeno ... */ - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - ctx->pattern += ctx->pattern[1]; - break; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) { - ctx->pattern += ctx->pattern[1]; - break; - } - } - } - ctx->pattern += 2; - break; - - case SRE_OP_ASSERT: - /* assert subpattern */ - /* */ - TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[1])); - if (ctx->ptr - (SRE_CHAR *)state->beginning < (Py_ssize_t)ctx->pattern[1]) - RETURN_FAILURE; - state->ptr = ctx->ptr - ctx->pattern[1]; - DO_JUMP0(JUMP_ASSERT, jump_assert, ctx->pattern+2); - RETURN_ON_FAILURE(ret); - ctx->pattern += ctx->pattern[0]; - break; - - case SRE_OP_ASSERT_NOT: - /* assert not subpattern */ - /* */ - TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[1])); - if (ctx->ptr - (SRE_CHAR *)state->beginning >= (Py_ssize_t)ctx->pattern[1]) { - state->ptr = ctx->ptr - ctx->pattern[1]; - DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2); - if (ret) { - RETURN_ON_ERROR(ret); - RETURN_FAILURE; - } - } - ctx->pattern += ctx->pattern[0]; - break; - - case SRE_OP_FAILURE: - /* immediate failure */ - TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr)); - RETURN_FAILURE; - - default: - TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[-1])); - RETURN_ERROR(SRE_ERROR_ILLEGAL); - } - } - -exit: - ctx_pos = ctx->last_ctx_pos; - jump = ctx->jump; - DATA_POP_DISCARD(ctx); - if (ctx_pos == -1) - return ret; - DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); - - switch (jump) { - case JUMP_MAX_UNTIL_2: - TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr)); - goto jump_max_until_2; - case JUMP_MAX_UNTIL_3: - TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr)); - goto jump_max_until_3; - case JUMP_MIN_UNTIL_2: - TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr)); - goto jump_min_until_2; - case JUMP_MIN_UNTIL_3: - TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr)); - goto jump_min_until_3; - case JUMP_BRANCH: - TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr)); - goto jump_branch; - case JUMP_MAX_UNTIL_1: - TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr)); - goto jump_max_until_1; - case JUMP_MIN_UNTIL_1: - TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr)); - goto jump_min_until_1; - case JUMP_REPEAT: - TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr)); - goto jump_repeat; - case JUMP_REPEAT_ONE_1: - TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr)); - goto jump_repeat_one_1; - case JUMP_REPEAT_ONE_2: - TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr)); - goto jump_repeat_one_2; - case JUMP_MIN_REPEAT_ONE: - TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr)); - goto jump_min_repeat_one; - case JUMP_ASSERT: - TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr)); - goto jump_assert; - case JUMP_ASSERT_NOT: - TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr)); - goto jump_assert_not; - case JUMP_NONE: - TRACE(("|%p|%p|RETURN %" PY_FORMAT_SIZE_T "d\n", ctx->pattern, - ctx->ptr, ret)); - break; - } - - return ret; /* should never get here */ -} - -/* need to reset capturing groups between two SRE(match) callings in loops */ -#define RESET_CAPTURE_GROUP() \ - do { state->lastmark = state->lastindex = -1; } while (0) - -LOCAL(Py_ssize_t) -SRE(search)(SRE_STATE* state, SRE_CODE* pattern) -{ - SRE_CHAR* ptr = (SRE_CHAR *)state->start; - SRE_CHAR* end = (SRE_CHAR *)state->end; - Py_ssize_t status = 0; - Py_ssize_t prefix_len = 0; - Py_ssize_t prefix_skip = 0; - SRE_CODE* prefix = NULL; - SRE_CODE* charset = NULL; - SRE_CODE* overlap = NULL; - int flags = 0; - - if (ptr > end) - return 0; - - if (pattern[0] == SRE_OP_INFO) { - /* optimization info block */ - /* <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> */ - - flags = pattern[2]; - - if (pattern[3] && end - ptr < (Py_ssize_t)pattern[3]) { - TRACE(("reject (got %u chars, need %u)\n", - (unsigned int)(end - ptr), pattern[3])); - return 0; - } - if (pattern[3] > 1) { - /* adjust end point (but make sure we leave at least one - character in there, so literal search will work) */ - end -= pattern[3] - 1; - if (end <= ptr) - end = ptr; - } - - if (flags & SRE_INFO_PREFIX) { - /* pattern starts with a known prefix */ - /* */ - prefix_len = pattern[5]; - prefix_skip = pattern[6]; - prefix = pattern + 7; - overlap = prefix + prefix_len - 1; - } else if (flags & SRE_INFO_CHARSET) - /* pattern starts with a character from a known set */ - /* */ - charset = pattern + 5; - - pattern += 1 + pattern[1]; - } - - TRACE(("prefix = %p %" PY_FORMAT_SIZE_T "d %" PY_FORMAT_SIZE_T "d\n", - prefix, prefix_len, prefix_skip)); - TRACE(("charset = %p\n", charset)); - - if (prefix_len == 1) { - /* pattern starts with a literal character */ - SRE_CHAR c = (SRE_CHAR) prefix[0]; -#if SIZEOF_SRE_CHAR < 4 - if ((SRE_CODE) c != prefix[0]) - return 0; /* literal can't match: doesn't fit in char width */ -#endif - end = (SRE_CHAR *)state->end; - state->must_advance = 0; - while (ptr < end) { - while (*ptr != c) { - if (++ptr >= end) - return 0; - } - TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr)); - state->start = ptr; - state->ptr = ptr + prefix_skip; - if (flags & SRE_INFO_LITERAL) - return 1; /* we got all of it */ - status = SRE(match)(state, pattern + 2*prefix_skip, 0); - if (status != 0) - return status; - ++ptr; - RESET_CAPTURE_GROUP(); - } - return 0; - } - - if (prefix_len > 1) { - /* pattern starts with a known prefix. use the overlap - table to skip forward as fast as we possibly can */ - Py_ssize_t i = 0; - - end = (SRE_CHAR *)state->end; - if (prefix_len > end - ptr) - return 0; -#if SIZEOF_SRE_CHAR < 4 - for (i = 0; i < prefix_len; i++) - if ((SRE_CODE)(SRE_CHAR) prefix[i] != prefix[i]) - return 0; /* literal can't match: doesn't fit in char width */ -#endif - while (ptr < end) { - SRE_CHAR c = (SRE_CHAR) prefix[0]; - while (*ptr++ != c) { - if (ptr >= end) - return 0; - } - if (ptr >= end) - return 0; - - i = 1; - state->must_advance = 0; - do { - if (*ptr == (SRE_CHAR) prefix[i]) { - if (++i != prefix_len) { - if (++ptr >= end) - return 0; - continue; - } - /* found a potential match */ - TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr)); - state->start = ptr - (prefix_len - 1); - state->ptr = ptr - (prefix_len - prefix_skip - 1); - if (flags & SRE_INFO_LITERAL) - return 1; /* we got all of it */ - status = SRE(match)(state, pattern + 2*prefix_skip, 0); - if (status != 0) - return status; - /* close but no cigar -- try again */ - if (++ptr >= end) - return 0; - RESET_CAPTURE_GROUP(); - } - i = overlap[i]; - } while (i != 0); - } - return 0; - } - - if (charset) { - /* pattern starts with a character from a known set */ - end = (SRE_CHAR *)state->end; - state->must_advance = 0; - for (;;) { - while (ptr < end && !SRE(charset)(state, charset, *ptr)) - ptr++; - if (ptr >= end) - return 0; - TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr)); - state->start = ptr; - state->ptr = ptr; - status = SRE(match)(state, pattern, 0); - if (status != 0) - break; - ptr++; - RESET_CAPTURE_GROUP(); - } - } else { - /* general case */ - assert(ptr <= end); - TRACE(("|%p|%p|SEARCH\n", pattern, ptr)); - state->start = state->ptr = ptr; - status = SRE(match)(state, pattern, 1); - state->must_advance = 0; - while (status == 0 && ptr < end) { - ptr++; - RESET_CAPTURE_GROUP(); - TRACE(("|%p|%p|SEARCH\n", pattern, ptr)); - state->start = state->ptr = ptr; - status = SRE(match)(state, pattern, 0); - } - } - - return status; -} - -#undef SRE_CHAR -#undef SIZEOF_SRE_CHAR -#undef SRE - -/* vim:ts=4:sw=4:et -*/ + Py_ssize_t alloc_pos, ctx_pos = -1; + Py_ssize_t i, ret = 0; + Py_ssize_t jump; + unsigned int sigcount=0; + + SRE(match_context)* ctx; + SRE(match_context)* nextctx; + + TRACE(("|%p|%p|ENTER\n", pattern, state->ptr)); + + DATA_ALLOC(SRE(match_context), ctx); + ctx->last_ctx_pos = -1; + ctx->jump = JUMP_NONE; + ctx->pattern = pattern; + ctx->toplevel = toplevel; + ctx_pos = alloc_pos; + +entrance: + + ctx->ptr = (SRE_CHAR *)state->ptr; + + if (ctx->pattern[0] == SRE_OP_INFO) { + /* optimization info block */ + /* <1=skip> <2=flags> <3=min> ... */ + if (ctx->pattern[3] && (uintptr_t)(end - ctx->ptr) < ctx->pattern[3]) { + TRACE(("reject (got %" PY_FORMAT_SIZE_T "d chars, " + "need %" PY_FORMAT_SIZE_T "d)\n", + end - ctx->ptr, (Py_ssize_t) ctx->pattern[3])); + RETURN_FAILURE; + } + ctx->pattern += ctx->pattern[1] + 1; + } + + for (;;) { + ++sigcount; + if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals()) + RETURN_ERROR(SRE_ERROR_INTERRUPTED); + + switch (*ctx->pattern++) { + + case SRE_OP_MARK: + /* set mark */ + /* */ + TRACE(("|%p|%p|MARK %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[0])); + i = ctx->pattern[0]; + if (i & 1) + state->lastindex = i/2 + 1; + if (i > state->lastmark) { + /* state->lastmark is the highest valid index in the + state->mark array. If it is increased by more than 1, + the intervening marks must be set to NULL to signal + that these marks have not been encountered. */ + Py_ssize_t j = state->lastmark + 1; + while (j < i) + state->mark[j++] = NULL; + state->lastmark = i; + } + state->mark[i] = ctx->ptr; + ctx->pattern++; + break; + + case SRE_OP_LITERAL: + /* match literal string */ + /* */ + TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern, + ctx->ptr, *ctx->pattern)); + if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0]) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_NOT_LITERAL: + /* match anything that is not literal character */ + /* */ + TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern, + ctx->ptr, *ctx->pattern)); + if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0]) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_SUCCESS: + /* end of pattern */ + TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr)); + if (ctx->toplevel && + ((state->match_all && ctx->ptr != state->end) || + (state->must_advance && ctx->ptr == state->start))) + { + RETURN_FAILURE; + } + state->ptr = ctx->ptr; + RETURN_SUCCESS; + + case SRE_OP_AT: + /* match at given position */ + /* */ + TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern)); + if (!SRE(at)(state, ctx->ptr, *ctx->pattern)) + RETURN_FAILURE; + ctx->pattern++; + break; + + case SRE_OP_CATEGORY: + /* match at given category */ + /* */ + TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern, + ctx->ptr, *ctx->pattern)); + if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0])) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_ANY: + /* match anything (except a newline) */ + /* */ + TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr)); + if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0])) + RETURN_FAILURE; + ctx->ptr++; + break; + + case SRE_OP_ANY_ALL: + /* match anything */ + /* */ + TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr)); + if (ctx->ptr >= end) + RETURN_FAILURE; + ctx->ptr++; + break; + + case SRE_OP_IN: + /* match set member (or non_member) */ + /* */ + TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr)); + if (ctx->ptr >= end || + !SRE(charset)(state, ctx->pattern + 1, *ctx->ptr)) + RETURN_FAILURE; + ctx->pattern += ctx->pattern[0]; + ctx->ptr++; + break; + + case SRE_OP_LITERAL_IGNORE: + TRACE(("|%p|%p|LITERAL_IGNORE %d\n", + ctx->pattern, ctx->ptr, ctx->pattern[0])); + if (ctx->ptr >= end || + sre_lower_ascii(*ctx->ptr) != *ctx->pattern) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_LITERAL_UNI_IGNORE: + TRACE(("|%p|%p|LITERAL_UNI_IGNORE %d\n", + ctx->pattern, ctx->ptr, ctx->pattern[0])); + if (ctx->ptr >= end || + sre_lower_unicode(*ctx->ptr) != *ctx->pattern) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_LITERAL_LOC_IGNORE: + TRACE(("|%p|%p|LITERAL_LOC_IGNORE %d\n", + ctx->pattern, ctx->ptr, ctx->pattern[0])); + if (ctx->ptr >= end + || !char_loc_ignore(*ctx->pattern, *ctx->ptr)) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_NOT_LITERAL_IGNORE: + TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n", + ctx->pattern, ctx->ptr, *ctx->pattern)); + if (ctx->ptr >= end || + sre_lower_ascii(*ctx->ptr) == *ctx->pattern) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_NOT_LITERAL_UNI_IGNORE: + TRACE(("|%p|%p|NOT_LITERAL_UNI_IGNORE %d\n", + ctx->pattern, ctx->ptr, *ctx->pattern)); + if (ctx->ptr >= end || + sre_lower_unicode(*ctx->ptr) == *ctx->pattern) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_NOT_LITERAL_LOC_IGNORE: + TRACE(("|%p|%p|NOT_LITERAL_LOC_IGNORE %d\n", + ctx->pattern, ctx->ptr, *ctx->pattern)); + if (ctx->ptr >= end + || char_loc_ignore(*ctx->pattern, *ctx->ptr)) + RETURN_FAILURE; + ctx->pattern++; + ctx->ptr++; + break; + + case SRE_OP_IN_IGNORE: + TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr)); + if (ctx->ptr >= end + || !SRE(charset)(state, ctx->pattern+1, + (SRE_CODE)sre_lower_ascii(*ctx->ptr))) + RETURN_FAILURE; + ctx->pattern += ctx->pattern[0]; + ctx->ptr++; + break; + + case SRE_OP_IN_UNI_IGNORE: + TRACE(("|%p|%p|IN_UNI_IGNORE\n", ctx->pattern, ctx->ptr)); + if (ctx->ptr >= end + || !SRE(charset)(state, ctx->pattern+1, + (SRE_CODE)sre_lower_unicode(*ctx->ptr))) + RETURN_FAILURE; + ctx->pattern += ctx->pattern[0]; + ctx->ptr++; + break; + + case SRE_OP_IN_LOC_IGNORE: + TRACE(("|%p|%p|IN_LOC_IGNORE\n", ctx->pattern, ctx->ptr)); + if (ctx->ptr >= end + || !SRE(charset_loc_ignore)(state, ctx->pattern+1, *ctx->ptr)) + RETURN_FAILURE; + ctx->pattern += ctx->pattern[0]; + ctx->ptr++; + break; + + case SRE_OP_JUMP: + case SRE_OP_INFO: + /* jump forward */ + /* */ + TRACE(("|%p|%p|JUMP %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[0])); + ctx->pattern += ctx->pattern[0]; + break; + + case SRE_OP_BRANCH: + /* alternation */ + /* <0=skip> code ... */ + TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr)); + LASTMARK_SAVE(); + ctx->u.rep = state->repeat; + if (ctx->u.rep) + MARK_PUSH(ctx->lastmark); + for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) { + if (ctx->pattern[1] == SRE_OP_LITERAL && + (ctx->ptr >= end || + (SRE_CODE) *ctx->ptr != ctx->pattern[2])) + continue; + if (ctx->pattern[1] == SRE_OP_IN && + (ctx->ptr >= end || + !SRE(charset)(state, ctx->pattern + 3, + (SRE_CODE) *ctx->ptr))) + continue; + state->ptr = ctx->ptr; + DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1); + if (ret) { + if (ctx->u.rep) + MARK_POP_DISCARD(ctx->lastmark); + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + if (ctx->u.rep) + MARK_POP_KEEP(ctx->lastmark); + LASTMARK_RESTORE(); + } + if (ctx->u.rep) + MARK_POP_DISCARD(ctx->lastmark); + RETURN_FAILURE; + + case SRE_OP_REPEAT_ONE: + /* match repeated sequence (maximizing regexp) */ + + /* this operator only works if the repeated item is + exactly one character wide, and we're not already + collecting backtracking points. for other cases, + use the MAX_REPEAT operator */ + + /* <1=min> <2=max> item tail */ + + TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, + ctx->pattern[1], ctx->pattern[2])); + + if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr) + RETURN_FAILURE; /* cannot match */ + + state->ptr = ctx->ptr; + + ret = SRE(count)(state, ctx->pattern+3, ctx->pattern[2]); + RETURN_ON_ERROR(ret); + DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); + ctx->count = ret; + ctx->ptr += ctx->count; + + /* when we arrive here, count contains the number of + matches, and ctx->ptr points to the tail of the target + string. check if the rest of the pattern matches, + and backtrack if not. */ + + if (ctx->count < (Py_ssize_t) ctx->pattern[1]) + RETURN_FAILURE; + + if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && + ctx->ptr == state->end && + !(ctx->toplevel && state->must_advance && ctx->ptr == state->start)) + { + /* tail is empty. we're finished */ + state->ptr = ctx->ptr; + RETURN_SUCCESS; + } + + LASTMARK_SAVE(); + + if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) { + /* tail starts with a literal. skip positions where + the rest of the pattern cannot possibly match */ + ctx->u.chr = ctx->pattern[ctx->pattern[0]+1]; + for (;;) { + while (ctx->count >= (Py_ssize_t) ctx->pattern[1] && + (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) { + ctx->ptr--; + ctx->count--; + } + if (ctx->count < (Py_ssize_t) ctx->pattern[1]) + break; + state->ptr = ctx->ptr; + DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1, + ctx->pattern+ctx->pattern[0]); + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + + LASTMARK_RESTORE(); + + ctx->ptr--; + ctx->count--; + } + + } else { + /* general case */ + while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) { + state->ptr = ctx->ptr; + DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2, + ctx->pattern+ctx->pattern[0]); + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + ctx->ptr--; + ctx->count--; + LASTMARK_RESTORE(); + } + } + RETURN_FAILURE; + + case SRE_OP_MIN_REPEAT_ONE: + /* match repeated sequence (minimizing regexp) */ + + /* this operator only works if the repeated item is + exactly one character wide, and we're not already + collecting backtracking points. for other cases, + use the MIN_REPEAT operator */ + + /* <1=min> <2=max> item tail */ + + TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, + ctx->pattern[1], ctx->pattern[2])); + + if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr) + RETURN_FAILURE; /* cannot match */ + + state->ptr = ctx->ptr; + + if (ctx->pattern[1] == 0) + ctx->count = 0; + else { + /* count using pattern min as the maximum */ + ret = SRE(count)(state, ctx->pattern+3, ctx->pattern[1]); + RETURN_ON_ERROR(ret); + DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); + if (ret < (Py_ssize_t) ctx->pattern[1]) + /* didn't match minimum number of times */ + RETURN_FAILURE; + /* advance past minimum matches of repeat */ + ctx->count = ret; + ctx->ptr += ctx->count; + } + + if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && + !(ctx->toplevel && + ((state->match_all && ctx->ptr != state->end) || + (state->must_advance && ctx->ptr == state->start)))) + { + /* tail is empty. we're finished */ + state->ptr = ctx->ptr; + RETURN_SUCCESS; + + } else { + /* general case */ + LASTMARK_SAVE(); + while ((Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT + || ctx->count <= (Py_ssize_t)ctx->pattern[2]) { + state->ptr = ctx->ptr; + DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one, + ctx->pattern+ctx->pattern[0]); + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + state->ptr = ctx->ptr; + ret = SRE(count)(state, ctx->pattern+3, 1); + RETURN_ON_ERROR(ret); + DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); + if (ret == 0) + break; + assert(ret == 1); + ctx->ptr++; + ctx->count++; + LASTMARK_RESTORE(); + } + } + RETURN_FAILURE; + + case SRE_OP_REPEAT: + /* create repeat context. all the hard work is done + by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */ + /* <1=min> <2=max> item tail */ + TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr, + ctx->pattern[1], ctx->pattern[2])); + + /* install new repeat context */ + ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep)); + if (!ctx->u.rep) { + PyErr_NoMemory(); + RETURN_FAILURE; + } + ctx->u.rep->count = -1; + ctx->u.rep->pattern = ctx->pattern; + ctx->u.rep->prev = state->repeat; + ctx->u.rep->last_ptr = NULL; + state->repeat = ctx->u.rep; + + state->ptr = ctx->ptr; + DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]); + state->repeat = ctx->u.rep->prev; + PyObject_FREE(ctx->u.rep); + + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + RETURN_FAILURE; + + case SRE_OP_MAX_UNTIL: + /* maximizing repeat */ + /* <1=min> <2=max> item tail */ + + /* FIXME: we probably need to deal with zero-width + matches in here... */ + + ctx->u.rep = state->repeat; + if (!ctx->u.rep) + RETURN_ERROR(SRE_ERROR_STATE); + + state->ptr = ctx->ptr; + + ctx->count = ctx->u.rep->count+1; + + TRACE(("|%p|%p|MAX_UNTIL %" PY_FORMAT_SIZE_T "d\n", ctx->pattern, + ctx->ptr, ctx->count)); + + if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { + /* not enough matches */ + ctx->u.rep->count = ctx->count; + DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1, + ctx->u.rep->pattern+3); + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + ctx->u.rep->count = ctx->count-1; + state->ptr = ctx->ptr; + RETURN_FAILURE; + } + + if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] || + ctx->u.rep->pattern[2] == SRE_MAXREPEAT) && + state->ptr != ctx->u.rep->last_ptr) { + /* we may have enough matches, but if we can + match another item, do so */ + ctx->u.rep->count = ctx->count; + LASTMARK_SAVE(); + MARK_PUSH(ctx->lastmark); + /* zero-width match protection */ + DATA_PUSH(&ctx->u.rep->last_ptr); + ctx->u.rep->last_ptr = state->ptr; + DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2, + ctx->u.rep->pattern+3); + DATA_POP(&ctx->u.rep->last_ptr); + if (ret) { + MARK_POP_DISCARD(ctx->lastmark); + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + MARK_POP(ctx->lastmark); + LASTMARK_RESTORE(); + ctx->u.rep->count = ctx->count-1; + state->ptr = ctx->ptr; + } + + /* cannot match more repeated items here. make sure the + tail matches */ + state->repeat = ctx->u.rep->prev; + DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern); + RETURN_ON_SUCCESS(ret); + state->repeat = ctx->u.rep; + state->ptr = ctx->ptr; + RETURN_FAILURE; + + case SRE_OP_MIN_UNTIL: + /* minimizing repeat */ + /* <1=min> <2=max> item tail */ + + ctx->u.rep = state->repeat; + if (!ctx->u.rep) + RETURN_ERROR(SRE_ERROR_STATE); + + state->ptr = ctx->ptr; + + ctx->count = ctx->u.rep->count+1; + + TRACE(("|%p|%p|MIN_UNTIL %" PY_FORMAT_SIZE_T "d %p\n", ctx->pattern, + ctx->ptr, ctx->count, ctx->u.rep->pattern)); + + if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { + /* not enough matches */ + ctx->u.rep->count = ctx->count; + DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1, + ctx->u.rep->pattern+3); + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + ctx->u.rep->count = ctx->count-1; + state->ptr = ctx->ptr; + RETURN_FAILURE; + } + + LASTMARK_SAVE(); + + /* see if the tail matches */ + state->repeat = ctx->u.rep->prev; + DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern); + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + + state->repeat = ctx->u.rep; + state->ptr = ctx->ptr; + + LASTMARK_RESTORE(); + + if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2] + && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) || + state->ptr == ctx->u.rep->last_ptr) + RETURN_FAILURE; + + ctx->u.rep->count = ctx->count; + /* zero-width match protection */ + DATA_PUSH(&ctx->u.rep->last_ptr); + ctx->u.rep->last_ptr = state->ptr; + DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3, + ctx->u.rep->pattern+3); + DATA_POP(&ctx->u.rep->last_ptr); + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_SUCCESS; + } + ctx->u.rep->count = ctx->count-1; + state->ptr = ctx->ptr; + RETURN_FAILURE; + + case SRE_OP_GROUPREF: + /* match backreference */ + TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[0])); + i = ctx->pattern[0]; + { + Py_ssize_t groupref = i+i; + if (groupref >= state->lastmark) { + RETURN_FAILURE; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) + RETURN_FAILURE; + while (p < e) { + if (ctx->ptr >= end || *ctx->ptr != *p) + RETURN_FAILURE; + p++; + ctx->ptr++; + } + } + } + ctx->pattern++; + break; + + case SRE_OP_GROUPREF_IGNORE: + /* match backreference */ + TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[0])); + i = ctx->pattern[0]; + { + Py_ssize_t groupref = i+i; + if (groupref >= state->lastmark) { + RETURN_FAILURE; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) + RETURN_FAILURE; + while (p < e) { + if (ctx->ptr >= end || + sre_lower_ascii(*ctx->ptr) != sre_lower_ascii(*p)) + RETURN_FAILURE; + p++; + ctx->ptr++; + } + } + } + ctx->pattern++; + break; + + case SRE_OP_GROUPREF_UNI_IGNORE: + /* match backreference */ + TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[0])); + i = ctx->pattern[0]; + { + Py_ssize_t groupref = i+i; + if (groupref >= state->lastmark) { + RETURN_FAILURE; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) + RETURN_FAILURE; + while (p < e) { + if (ctx->ptr >= end || + sre_lower_unicode(*ctx->ptr) != sre_lower_unicode(*p)) + RETURN_FAILURE; + p++; + ctx->ptr++; + } + } + } + ctx->pattern++; + break; + + case SRE_OP_GROUPREF_LOC_IGNORE: + /* match backreference */ + TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[0])); + i = ctx->pattern[0]; + { + Py_ssize_t groupref = i+i; + if (groupref >= state->lastmark) { + RETURN_FAILURE; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) + RETURN_FAILURE; + while (p < e) { + if (ctx->ptr >= end || + sre_lower_locale(*ctx->ptr) != sre_lower_locale(*p)) + RETURN_FAILURE; + p++; + ctx->ptr++; + } + } + } + ctx->pattern++; + break; + + case SRE_OP_GROUPREF_EXISTS: + TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[0])); + /* codeyes codeno ... */ + i = ctx->pattern[0]; + { + Py_ssize_t groupref = i+i; + if (groupref >= state->lastmark) { + ctx->pattern += ctx->pattern[1]; + break; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) { + ctx->pattern += ctx->pattern[1]; + break; + } + } + } + ctx->pattern += 2; + break; + + case SRE_OP_ASSERT: + /* assert subpattern */ + /* */ + TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[1])); + if (ctx->ptr - (SRE_CHAR *)state->beginning < (Py_ssize_t)ctx->pattern[1]) + RETURN_FAILURE; + state->ptr = ctx->ptr - ctx->pattern[1]; + DO_JUMP0(JUMP_ASSERT, jump_assert, ctx->pattern+2); + RETURN_ON_FAILURE(ret); + ctx->pattern += ctx->pattern[0]; + break; + + case SRE_OP_ASSERT_NOT: + /* assert not subpattern */ + /* */ + TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[1])); + if (ctx->ptr - (SRE_CHAR *)state->beginning >= (Py_ssize_t)ctx->pattern[1]) { + state->ptr = ctx->ptr - ctx->pattern[1]; + DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2); + if (ret) { + RETURN_ON_ERROR(ret); + RETURN_FAILURE; + } + } + ctx->pattern += ctx->pattern[0]; + break; + + case SRE_OP_FAILURE: + /* immediate failure */ + TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr)); + RETURN_FAILURE; + + default: + TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr, + ctx->pattern[-1])); + RETURN_ERROR(SRE_ERROR_ILLEGAL); + } + } + +exit: + ctx_pos = ctx->last_ctx_pos; + jump = ctx->jump; + DATA_POP_DISCARD(ctx); + if (ctx_pos == -1) + return ret; + DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); + + switch (jump) { + case JUMP_MAX_UNTIL_2: + TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr)); + goto jump_max_until_2; + case JUMP_MAX_UNTIL_3: + TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr)); + goto jump_max_until_3; + case JUMP_MIN_UNTIL_2: + TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr)); + goto jump_min_until_2; + case JUMP_MIN_UNTIL_3: + TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr)); + goto jump_min_until_3; + case JUMP_BRANCH: + TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr)); + goto jump_branch; + case JUMP_MAX_UNTIL_1: + TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr)); + goto jump_max_until_1; + case JUMP_MIN_UNTIL_1: + TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr)); + goto jump_min_until_1; + case JUMP_REPEAT: + TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr)); + goto jump_repeat; + case JUMP_REPEAT_ONE_1: + TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr)); + goto jump_repeat_one_1; + case JUMP_REPEAT_ONE_2: + TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr)); + goto jump_repeat_one_2; + case JUMP_MIN_REPEAT_ONE: + TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr)); + goto jump_min_repeat_one; + case JUMP_ASSERT: + TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr)); + goto jump_assert; + case JUMP_ASSERT_NOT: + TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr)); + goto jump_assert_not; + case JUMP_NONE: + TRACE(("|%p|%p|RETURN %" PY_FORMAT_SIZE_T "d\n", ctx->pattern, + ctx->ptr, ret)); + break; + } + + return ret; /* should never get here */ +} + +/* need to reset capturing groups between two SRE(match) callings in loops */ +#define RESET_CAPTURE_GROUP() \ + do { state->lastmark = state->lastindex = -1; } while (0) + +LOCAL(Py_ssize_t) +SRE(search)(SRE_STATE* state, SRE_CODE* pattern) +{ + SRE_CHAR* ptr = (SRE_CHAR *)state->start; + SRE_CHAR* end = (SRE_CHAR *)state->end; + Py_ssize_t status = 0; + Py_ssize_t prefix_len = 0; + Py_ssize_t prefix_skip = 0; + SRE_CODE* prefix = NULL; + SRE_CODE* charset = NULL; + SRE_CODE* overlap = NULL; + int flags = 0; + + if (ptr > end) + return 0; + + if (pattern[0] == SRE_OP_INFO) { + /* optimization info block */ + /* <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> */ + + flags = pattern[2]; + + if (pattern[3] && end - ptr < (Py_ssize_t)pattern[3]) { + TRACE(("reject (got %u chars, need %u)\n", + (unsigned int)(end - ptr), pattern[3])); + return 0; + } + if (pattern[3] > 1) { + /* adjust end point (but make sure we leave at least one + character in there, so literal search will work) */ + end -= pattern[3] - 1; + if (end <= ptr) + end = ptr; + } + + if (flags & SRE_INFO_PREFIX) { + /* pattern starts with a known prefix */ + /* */ + prefix_len = pattern[5]; + prefix_skip = pattern[6]; + prefix = pattern + 7; + overlap = prefix + prefix_len - 1; + } else if (flags & SRE_INFO_CHARSET) + /* pattern starts with a character from a known set */ + /* */ + charset = pattern + 5; + + pattern += 1 + pattern[1]; + } + + TRACE(("prefix = %p %" PY_FORMAT_SIZE_T "d %" PY_FORMAT_SIZE_T "d\n", + prefix, prefix_len, prefix_skip)); + TRACE(("charset = %p\n", charset)); + + if (prefix_len == 1) { + /* pattern starts with a literal character */ + SRE_CHAR c = (SRE_CHAR) prefix[0]; +#if SIZEOF_SRE_CHAR < 4 + if ((SRE_CODE) c != prefix[0]) + return 0; /* literal can't match: doesn't fit in char width */ +#endif + end = (SRE_CHAR *)state->end; + state->must_advance = 0; + while (ptr < end) { + while (*ptr != c) { + if (++ptr >= end) + return 0; + } + TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr)); + state->start = ptr; + state->ptr = ptr + prefix_skip; + if (flags & SRE_INFO_LITERAL) + return 1; /* we got all of it */ + status = SRE(match)(state, pattern + 2*prefix_skip, 0); + if (status != 0) + return status; + ++ptr; + RESET_CAPTURE_GROUP(); + } + return 0; + } + + if (prefix_len > 1) { + /* pattern starts with a known prefix. use the overlap + table to skip forward as fast as we possibly can */ + Py_ssize_t i = 0; + + end = (SRE_CHAR *)state->end; + if (prefix_len > end - ptr) + return 0; +#if SIZEOF_SRE_CHAR < 4 + for (i = 0; i < prefix_len; i++) + if ((SRE_CODE)(SRE_CHAR) prefix[i] != prefix[i]) + return 0; /* literal can't match: doesn't fit in char width */ +#endif + while (ptr < end) { + SRE_CHAR c = (SRE_CHAR) prefix[0]; + while (*ptr++ != c) { + if (ptr >= end) + return 0; + } + if (ptr >= end) + return 0; + + i = 1; + state->must_advance = 0; + do { + if (*ptr == (SRE_CHAR) prefix[i]) { + if (++i != prefix_len) { + if (++ptr >= end) + return 0; + continue; + } + /* found a potential match */ + TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr)); + state->start = ptr - (prefix_len - 1); + state->ptr = ptr - (prefix_len - prefix_skip - 1); + if (flags & SRE_INFO_LITERAL) + return 1; /* we got all of it */ + status = SRE(match)(state, pattern + 2*prefix_skip, 0); + if (status != 0) + return status; + /* close but no cigar -- try again */ + if (++ptr >= end) + return 0; + RESET_CAPTURE_GROUP(); + } + i = overlap[i]; + } while (i != 0); + } + return 0; + } + + if (charset) { + /* pattern starts with a character from a known set */ + end = (SRE_CHAR *)state->end; + state->must_advance = 0; + for (;;) { + while (ptr < end && !SRE(charset)(state, charset, *ptr)) + ptr++; + if (ptr >= end) + return 0; + TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr)); + state->start = ptr; + state->ptr = ptr; + status = SRE(match)(state, pattern, 0); + if (status != 0) + break; + ptr++; + RESET_CAPTURE_GROUP(); + } + } else { + /* general case */ + assert(ptr <= end); + TRACE(("|%p|%p|SEARCH\n", pattern, ptr)); + state->start = state->ptr = ptr; + status = SRE(match)(state, pattern, 1); + state->must_advance = 0; + while (status == 0 && ptr < end) { + ptr++; + RESET_CAPTURE_GROUP(); + TRACE(("|%p|%p|SEARCH\n", pattern, ptr)); + state->start = state->ptr = ptr; + status = SRE(match)(state, pattern, 0); + } + } + + return status; +} + +#undef SRE_CHAR +#undef SIZEOF_SRE_CHAR +#undef SRE + +/* vim:ts=4:sw=4:et +*/ diff --git a/contrib/tools/python3/src/Modules/symtablemodule.c b/contrib/tools/python3/src/Modules/symtablemodule.c index 9180f185e1e..3b9dce104e8 100644 --- a/contrib/tools/python3/src/Modules/symtablemodule.c +++ b/contrib/tools/python3/src/Modules/symtablemodule.c @@ -1,38 +1,38 @@ -#include "Python.h" - -#include "code.h" -#include "Python-ast.h" -#include "symtable.h" - -#include "clinic/symtablemodule.c.h" -/*[clinic input] -module _symtable -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f4685845a7100605]*/ - - -/*[clinic input] -_symtable.symtable - +#include "Python.h" + +#include "code.h" +#include "Python-ast.h" +#include "symtable.h" + +#include "clinic/symtablemodule.c.h" +/*[clinic input] +module _symtable +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f4685845a7100605]*/ + + +/*[clinic input] +_symtable.symtable + source: object - filename: object(converter='PyUnicode_FSDecoder') - startstr: str - / - -Return symbol and scope dictionaries used internally by compiler. -[clinic start generated code]*/ - -static PyObject * + filename: object(converter='PyUnicode_FSDecoder') + startstr: str + / + +Return symbol and scope dictionaries used internally by compiler. +[clinic start generated code]*/ + +static PyObject * _symtable_symtable_impl(PyObject *module, PyObject *source, - PyObject *filename, const char *startstr) + PyObject *filename, const char *startstr) /*[clinic end generated code: output=59eb0d5fc7285ac4 input=9dd8a50c0c36a4d7]*/ -{ - struct symtable *st; - PyObject *t; - int start; +{ + struct symtable *st; + PyObject *t; + int start; PyCompilerFlags cf = _PyCompilerFlags_INIT; PyObject *source_copy = NULL; - + cf.cf_flags = PyCF_SOURCE_IS_UTF8; const char *str = _Py_SourceAsString(source, "symtable", "string or bytes", &cf, &source_copy); @@ -40,87 +40,87 @@ _symtable_symtable_impl(PyObject *module, PyObject *source, return NULL; } - if (strcmp(startstr, "exec") == 0) - start = Py_file_input; - else if (strcmp(startstr, "eval") == 0) - start = Py_eval_input; - else if (strcmp(startstr, "single") == 0) - start = Py_single_input; - else { - PyErr_SetString(PyExc_ValueError, - "symtable() arg 3 must be 'exec' or 'eval' or 'single'"); - Py_DECREF(filename); + if (strcmp(startstr, "exec") == 0) + start = Py_file_input; + else if (strcmp(startstr, "eval") == 0) + start = Py_eval_input; + else if (strcmp(startstr, "single") == 0) + start = Py_single_input; + else { + PyErr_SetString(PyExc_ValueError, + "symtable() arg 3 must be 'exec' or 'eval' or 'single'"); + Py_DECREF(filename); Py_XDECREF(source_copy); - return NULL; - } + return NULL; + } st = _Py_SymtableStringObjectFlags(str, filename, start, &cf); - Py_DECREF(filename); + Py_DECREF(filename); Py_XDECREF(source_copy); if (st == NULL) { - return NULL; + return NULL; } - t = (PyObject *)st->st_top; - Py_INCREF(t); - PyMem_Free((void *)st->st_future); - PySymtable_Free(st); - return t; -} - -static PyMethodDef symtable_methods[] = { - _SYMTABLE_SYMTABLE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static struct PyModuleDef symtablemodule = { - PyModuleDef_HEAD_INIT, - "_symtable", - NULL, - -1, - symtable_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__symtable(void) -{ - PyObject *m; - - if (PyType_Ready(&PySTEntry_Type) < 0) - return NULL; - - m = PyModule_Create(&symtablemodule); - if (m == NULL) - return NULL; - PyModule_AddIntMacro(m, USE); - PyModule_AddIntMacro(m, DEF_GLOBAL); + t = (PyObject *)st->st_top; + Py_INCREF(t); + PyMem_Free((void *)st->st_future); + PySymtable_Free(st); + return t; +} + +static PyMethodDef symtable_methods[] = { + _SYMTABLE_SYMTABLE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static struct PyModuleDef symtablemodule = { + PyModuleDef_HEAD_INIT, + "_symtable", + NULL, + -1, + symtable_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__symtable(void) +{ + PyObject *m; + + if (PyType_Ready(&PySTEntry_Type) < 0) + return NULL; + + m = PyModule_Create(&symtablemodule); + if (m == NULL) + return NULL; + PyModule_AddIntMacro(m, USE); + PyModule_AddIntMacro(m, DEF_GLOBAL); PyModule_AddIntMacro(m, DEF_NONLOCAL); - PyModule_AddIntMacro(m, DEF_LOCAL); - PyModule_AddIntMacro(m, DEF_PARAM); - PyModule_AddIntMacro(m, DEF_FREE); - PyModule_AddIntMacro(m, DEF_FREE_CLASS); - PyModule_AddIntMacro(m, DEF_IMPORT); - PyModule_AddIntMacro(m, DEF_BOUND); - PyModule_AddIntMacro(m, DEF_ANNOT); - - PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock); - PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock); - PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock); - - PyModule_AddIntMacro(m, LOCAL); - PyModule_AddIntMacro(m, GLOBAL_EXPLICIT); - PyModule_AddIntMacro(m, GLOBAL_IMPLICIT); - PyModule_AddIntMacro(m, FREE); - PyModule_AddIntMacro(m, CELL); - - PyModule_AddIntConstant(m, "SCOPE_OFF", SCOPE_OFFSET); - PyModule_AddIntMacro(m, SCOPE_MASK); - - if (PyErr_Occurred()) { - Py_DECREF(m); - m = 0; - } - return m; -} + PyModule_AddIntMacro(m, DEF_LOCAL); + PyModule_AddIntMacro(m, DEF_PARAM); + PyModule_AddIntMacro(m, DEF_FREE); + PyModule_AddIntMacro(m, DEF_FREE_CLASS); + PyModule_AddIntMacro(m, DEF_IMPORT); + PyModule_AddIntMacro(m, DEF_BOUND); + PyModule_AddIntMacro(m, DEF_ANNOT); + + PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock); + PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock); + PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock); + + PyModule_AddIntMacro(m, LOCAL); + PyModule_AddIntMacro(m, GLOBAL_EXPLICIT); + PyModule_AddIntMacro(m, GLOBAL_IMPLICIT); + PyModule_AddIntMacro(m, FREE); + PyModule_AddIntMacro(m, CELL); + + PyModule_AddIntConstant(m, "SCOPE_OFF", SCOPE_OFFSET); + PyModule_AddIntMacro(m, SCOPE_MASK); + + if (PyErr_Occurred()) { + Py_DECREF(m); + m = 0; + } + return m; +} diff --git a/contrib/tools/python3/src/Modules/syslogmodule.c b/contrib/tools/python3/src/Modules/syslogmodule.c index 0f2fea15b3a..849538e3b7b 100644 --- a/contrib/tools/python3/src/Modules/syslogmodule.c +++ b/contrib/tools/python3/src/Modules/syslogmodule.c @@ -1,277 +1,277 @@ -/*********************************************************** -Copyright 1994 by Lance Ellinghouse, -Cathedral City, California Republic, United States of America. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Lance Ellinghouse -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. - -LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL, -INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING -FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION -WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -******************************************************************/ - -/****************************************************************** - -Revision history: - -2010/04/20 (Sean Reifschneider) - - Use basename(sys.argv[0]) for the default "ident". - - Arguments to openlog() are now keyword args and are all optional. - - syslog() calls openlog() if it hasn't already been called. - -1998/04/28 (Sean Reifschneider) - - When facility not specified to syslog() method, use default from openlog() - (This is how it was claimed to work in the documentation) - - Potential resource leak of o_ident, now cleaned up in closelog() - - Minor comment accuracy fix. - -95/06/29 (Steve Clift) - - Changed arg parsing to use PyArg_ParseTuple. - - Added PyErr_Clear() call(s) where needed. - - Fix core dumps if user message contains format specifiers. - - Change openlog arg defaults to match normal syslog behavior. - - Plug memory leak in openlog(). - - Fix setlogmask() to return previous mask value. - -******************************************************************/ - -/* syslog module */ - -#include "Python.h" +/*********************************************************** +Copyright 1994 by Lance Ellinghouse, +Cathedral City, California Republic, United States of America. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Lance Ellinghouse +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + +LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL, +INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +/****************************************************************** + +Revision history: + +2010/04/20 (Sean Reifschneider) + - Use basename(sys.argv[0]) for the default "ident". + - Arguments to openlog() are now keyword args and are all optional. + - syslog() calls openlog() if it hasn't already been called. + +1998/04/28 (Sean Reifschneider) + - When facility not specified to syslog() method, use default from openlog() + (This is how it was claimed to work in the documentation) + - Potential resource leak of o_ident, now cleaned up in closelog() + - Minor comment accuracy fix. + +95/06/29 (Steve Clift) + - Changed arg parsing to use PyArg_ParseTuple. + - Added PyErr_Clear() call(s) where needed. + - Fix core dumps if user message contains format specifiers. + - Change openlog arg defaults to match normal syslog behavior. + - Plug memory leak in openlog(). + - Fix setlogmask() to return previous mask value. + +******************************************************************/ + +/* syslog module */ + +#include "Python.h" #include "osdefs.h" // SEP - -#include - -/* only one instance, only one syslog, so globals should be ok */ -static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */ -static char S_log_open = 0; - - -static PyObject * -syslog_get_argv(void) -{ - /* Figure out what to use for as the program "ident" for openlog(). - * This swallows exceptions and continues rather than failing out, - * because the syslog module can still be used because openlog(3) - * is optional. - */ - - Py_ssize_t argv_len, scriptlen; - PyObject *scriptobj; - Py_ssize_t slash; - PyObject *argv = PySys_GetObject("argv"); - - if (argv == NULL) { - return(NULL); - } - - argv_len = PyList_Size(argv); - if (argv_len == -1) { - PyErr_Clear(); - return(NULL); - } - if (argv_len == 0) { - return(NULL); - } - - scriptobj = PyList_GetItem(argv, 0); - if (!PyUnicode_Check(scriptobj)) { - return(NULL); - } - scriptlen = PyUnicode_GET_LENGTH(scriptobj); - if (scriptlen == 0) { - return(NULL); - } - - slash = PyUnicode_FindChar(scriptobj, SEP, 0, scriptlen, -1); - if (slash == -2) - return NULL; - if (slash != -1) { + +#include + +/* only one instance, only one syslog, so globals should be ok */ +static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */ +static char S_log_open = 0; + + +static PyObject * +syslog_get_argv(void) +{ + /* Figure out what to use for as the program "ident" for openlog(). + * This swallows exceptions and continues rather than failing out, + * because the syslog module can still be used because openlog(3) + * is optional. + */ + + Py_ssize_t argv_len, scriptlen; + PyObject *scriptobj; + Py_ssize_t slash; + PyObject *argv = PySys_GetObject("argv"); + + if (argv == NULL) { + return(NULL); + } + + argv_len = PyList_Size(argv); + if (argv_len == -1) { + PyErr_Clear(); + return(NULL); + } + if (argv_len == 0) { + return(NULL); + } + + scriptobj = PyList_GetItem(argv, 0); + if (!PyUnicode_Check(scriptobj)) { + return(NULL); + } + scriptlen = PyUnicode_GET_LENGTH(scriptobj); + if (scriptlen == 0) { + return(NULL); + } + + slash = PyUnicode_FindChar(scriptobj, SEP, 0, scriptlen, -1); + if (slash == -2) + return NULL; + if (slash != -1) { return PyUnicode_Substring(scriptobj, slash + 1, scriptlen); - } else { - Py_INCREF(scriptobj); - return(scriptobj); - } - - return(NULL); -} - - -static PyObject * -syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds) -{ - long logopt = 0; - long facility = LOG_USER; - PyObject *new_S_ident_o = NULL; - static char *keywords[] = {"ident", "logoption", "facility", 0}; - const char *ident = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|Ull:openlog", keywords, &new_S_ident_o, &logopt, &facility)) - return NULL; - - if (new_S_ident_o) { - Py_INCREF(new_S_ident_o); - } - - /* get sys.argv[0] or NULL if we can't for some reason */ - if (!new_S_ident_o) { - new_S_ident_o = syslog_get_argv(); - } - - Py_XDECREF(S_ident_o); - S_ident_o = new_S_ident_o; - - /* At this point, S_ident_o should be INCREF()ed. openlog(3) does not - * make a copy, and syslog(3) later uses it. We can't garbagecollect it - * If NULL, just let openlog figure it out (probably using C argv[0]). - */ - if (S_ident_o) { - ident = PyUnicode_AsUTF8(S_ident_o); - if (ident == NULL) - return NULL; - } - + } else { + Py_INCREF(scriptobj); + return(scriptobj); + } + + return(NULL); +} + + +static PyObject * +syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds) +{ + long logopt = 0; + long facility = LOG_USER; + PyObject *new_S_ident_o = NULL; + static char *keywords[] = {"ident", "logoption", "facility", 0}; + const char *ident = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "|Ull:openlog", keywords, &new_S_ident_o, &logopt, &facility)) + return NULL; + + if (new_S_ident_o) { + Py_INCREF(new_S_ident_o); + } + + /* get sys.argv[0] or NULL if we can't for some reason */ + if (!new_S_ident_o) { + new_S_ident_o = syslog_get_argv(); + } + + Py_XDECREF(S_ident_o); + S_ident_o = new_S_ident_o; + + /* At this point, S_ident_o should be INCREF()ed. openlog(3) does not + * make a copy, and syslog(3) later uses it. We can't garbagecollect it + * If NULL, just let openlog figure it out (probably using C argv[0]). + */ + if (S_ident_o) { + ident = PyUnicode_AsUTF8(S_ident_o); + if (ident == NULL) + return NULL; + } + if (PySys_Audit("syslog.openlog", "sll", ident, logopt, facility) < 0) { return NULL; } - openlog(ident, logopt, facility); - S_log_open = 1; - - Py_RETURN_NONE; -} - - -static PyObject * -syslog_syslog(PyObject * self, PyObject * args) -{ - PyObject *message_object; - const char *message; - int priority = LOG_INFO; - - if (!PyArg_ParseTuple(args, "iU;[priority,] message string", - &priority, &message_object)) { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "U;[priority,] message string", - &message_object)) - return NULL; - } - - message = PyUnicode_AsUTF8(message_object); - if (message == NULL) - return NULL; - + openlog(ident, logopt, facility); + S_log_open = 1; + + Py_RETURN_NONE; +} + + +static PyObject * +syslog_syslog(PyObject * self, PyObject * args) +{ + PyObject *message_object; + const char *message; + int priority = LOG_INFO; + + if (!PyArg_ParseTuple(args, "iU;[priority,] message string", + &priority, &message_object)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "U;[priority,] message string", + &message_object)) + return NULL; + } + + message = PyUnicode_AsUTF8(message_object); + if (message == NULL) + return NULL; + if (PySys_Audit("syslog.syslog", "is", priority, message) < 0) { return NULL; } - /* if log is not opened, open it now */ - if (!S_log_open) { - PyObject *openargs; - - /* Continue even if PyTuple_New fails, because openlog(3) is optional. + /* if log is not opened, open it now */ + if (!S_log_open) { + PyObject *openargs; + + /* Continue even if PyTuple_New fails, because openlog(3) is optional. * So, we can still do logging in the unlikely event things are so hosed - * that we can't do this tuple. - */ - if ((openargs = PyTuple_New(0))) { - PyObject *openlog_ret = syslog_openlog(self, openargs, NULL); - Py_XDECREF(openlog_ret); - Py_DECREF(openargs); - } - } - - Py_BEGIN_ALLOW_THREADS; - syslog(priority, "%s", message); - Py_END_ALLOW_THREADS; - Py_RETURN_NONE; -} - -static PyObject * -syslog_closelog(PyObject *self, PyObject *unused) -{ + * that we can't do this tuple. + */ + if ((openargs = PyTuple_New(0))) { + PyObject *openlog_ret = syslog_openlog(self, openargs, NULL); + Py_XDECREF(openlog_ret); + Py_DECREF(openargs); + } + } + + Py_BEGIN_ALLOW_THREADS; + syslog(priority, "%s", message); + Py_END_ALLOW_THREADS; + Py_RETURN_NONE; +} + +static PyObject * +syslog_closelog(PyObject *self, PyObject *unused) +{ if (PySys_Audit("syslog.closelog", NULL) < 0) { return NULL; } - if (S_log_open) { - closelog(); - Py_CLEAR(S_ident_o); - S_log_open = 0; - } - Py_RETURN_NONE; -} - -static PyObject * -syslog_setlogmask(PyObject *self, PyObject *args) -{ - long maskpri, omaskpri; - - if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri)) - return NULL; + if (S_log_open) { + closelog(); + Py_CLEAR(S_ident_o); + S_log_open = 0; + } + Py_RETURN_NONE; +} + +static PyObject * +syslog_setlogmask(PyObject *self, PyObject *args) +{ + long maskpri, omaskpri; + + if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri)) + return NULL; if (PySys_Audit("syslog.setlogmask", "(O)", args ? args : Py_None) < 0) { return NULL; } - omaskpri = setlogmask(maskpri); - return PyLong_FromLong(omaskpri); -} - -static PyObject * -syslog_log_mask(PyObject *self, PyObject *args) -{ - long mask; - long pri; - if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri)) - return NULL; - mask = LOG_MASK(pri); - return PyLong_FromLong(mask); -} - -static PyObject * -syslog_log_upto(PyObject *self, PyObject *args) -{ - long mask; - long pri; - if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri)) - return NULL; - mask = LOG_UPTO(pri); - return PyLong_FromLong(mask); -} - -/* List of functions defined in the module */ - -static PyMethodDef syslog_methods[] = { + omaskpri = setlogmask(maskpri); + return PyLong_FromLong(omaskpri); +} + +static PyObject * +syslog_log_mask(PyObject *self, PyObject *args) +{ + long mask; + long pri; + if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri)) + return NULL; + mask = LOG_MASK(pri); + return PyLong_FromLong(mask); +} + +static PyObject * +syslog_log_upto(PyObject *self, PyObject *args) +{ + long mask; + long pri; + if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri)) + return NULL; + mask = LOG_UPTO(pri); + return PyLong_FromLong(mask); +} + +/* List of functions defined in the module */ + +static PyMethodDef syslog_methods[] = { {"openlog", (PyCFunction)(void(*)(void)) syslog_openlog, METH_VARARGS | METH_KEYWORDS}, - {"closelog", syslog_closelog, METH_NOARGS}, - {"syslog", syslog_syslog, METH_VARARGS}, - {"setlogmask", syslog_setlogmask, METH_VARARGS}, - {"LOG_MASK", syslog_log_mask, METH_VARARGS}, - {"LOG_UPTO", syslog_log_upto, METH_VARARGS}, - {NULL, NULL, 0} -}; - - + {"closelog", syslog_closelog, METH_NOARGS}, + {"syslog", syslog_syslog, METH_VARARGS}, + {"setlogmask", syslog_setlogmask, METH_VARARGS}, + {"LOG_MASK", syslog_log_mask, METH_VARARGS}, + {"LOG_UPTO", syslog_log_upto, METH_VARARGS}, + {NULL, NULL, 0} +}; + + static int syslog_exec(PyObject *module) -{ +{ #define ADD_INT_MACRO(module, macro) \ do { \ if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \ return -1; \ } \ } while (0) - /* Priorities */ + /* Priorities */ ADD_INT_MACRO(module, LOG_EMERG); ADD_INT_MACRO(module, LOG_ALERT); ADD_INT_MACRO(module, LOG_CRIT); @@ -280,22 +280,22 @@ syslog_exec(PyObject *module) ADD_INT_MACRO(module, LOG_NOTICE); ADD_INT_MACRO(module, LOG_INFO); ADD_INT_MACRO(module, LOG_DEBUG); - - /* openlog() option flags */ + + /* openlog() option flags */ ADD_INT_MACRO(module, LOG_PID); ADD_INT_MACRO(module, LOG_CONS); ADD_INT_MACRO(module, LOG_NDELAY); -#ifdef LOG_ODELAY +#ifdef LOG_ODELAY ADD_INT_MACRO(module, LOG_ODELAY); -#endif -#ifdef LOG_NOWAIT +#endif +#ifdef LOG_NOWAIT ADD_INT_MACRO(module, LOG_NOWAIT); -#endif -#ifdef LOG_PERROR +#endif +#ifdef LOG_PERROR ADD_INT_MACRO(module, LOG_PERROR); -#endif - - /* Facilities */ +#endif + + /* Facilities */ ADD_INT_MACRO(module, LOG_KERN); ADD_INT_MACRO(module, LOG_USER); ADD_INT_MACRO(module, LOG_MAIL); @@ -310,31 +310,31 @@ syslog_exec(PyObject *module) ADD_INT_MACRO(module, LOG_LOCAL5); ADD_INT_MACRO(module, LOG_LOCAL6); ADD_INT_MACRO(module, LOG_LOCAL7); - -#ifndef LOG_SYSLOG -#define LOG_SYSLOG LOG_DAEMON -#endif -#ifndef LOG_NEWS -#define LOG_NEWS LOG_MAIL -#endif -#ifndef LOG_UUCP -#define LOG_UUCP LOG_MAIL -#endif -#ifndef LOG_CRON -#define LOG_CRON LOG_DAEMON -#endif - + +#ifndef LOG_SYSLOG +#define LOG_SYSLOG LOG_DAEMON +#endif +#ifndef LOG_NEWS +#define LOG_NEWS LOG_MAIL +#endif +#ifndef LOG_UUCP +#define LOG_UUCP LOG_MAIL +#endif +#ifndef LOG_CRON +#define LOG_CRON LOG_DAEMON +#endif + ADD_INT_MACRO(module, LOG_SYSLOG); ADD_INT_MACRO(module, LOG_CRON); ADD_INT_MACRO(module, LOG_UUCP); ADD_INT_MACRO(module, LOG_NEWS); - -#ifdef LOG_AUTHPRIV + +#ifdef LOG_AUTHPRIV ADD_INT_MACRO(module, LOG_AUTHPRIV); -#endif - +#endif + return 0; -} +} static PyModuleDef_Slot syslog_slots[] = { {Py_mod_exec, syslog_exec}, diff --git a/contrib/tools/python3/src/Modules/termios.c b/contrib/tools/python3/src/Modules/termios.c index 75e5e523206..adbdaf1a6f1 100644 --- a/contrib/tools/python3/src/Modules/termios.c +++ b/contrib/tools/python3/src/Modules/termios.c @@ -1,48 +1,48 @@ -/* termiosmodule.c -- POSIX terminal I/O module implementation. */ - -#include "Python.h" - -/* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE - is defined, so we define it here. */ -#if defined(__sgi) -#define CTRL(c) ((c)&037) -#endif - -#if defined(__sun) -/* We could do better. Check issue-32660 */ -#include -#include -#endif - -#include -#include - -/* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR, +/* termiosmodule.c -- POSIX terminal I/O module implementation. */ + +#include "Python.h" + +/* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE + is defined, so we define it here. */ +#if defined(__sgi) +#define CTRL(c) ((c)&037) +#endif + +#if defined(__sun) +/* We could do better. Check issue-32660 */ +#include +#include +#endif + +#include +#include + +/* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR, * MDTR, MRI, and MRTS (apparently used internally by some things - * defined as macros; these are not used here directly). - */ -#ifdef HAVE_SYS_MODEM_H -#include -#endif -/* HP-UX requires that this be included to pick up TIOCGPGRP and friends */ -#ifdef HAVE_SYS_BSDTTY_H -#include -#endif - -PyDoc_STRVAR(termios__doc__, -"This module provides an interface to the Posix calls for tty I/O control.\n\ -For a complete description of these calls, see the Posix or Unix manual\n\ -pages. It is only available for those Unix versions that support Posix\n\ -termios style tty I/O control.\n\ -\n\ -All functions in this module take a file descriptor fd as their first\n\ -argument. This can be an integer file descriptor, such as returned by\n\ -sys.stdin.fileno(), or a file object, such as sys.stdin itself."); - + * defined as macros; these are not used here directly). + */ +#ifdef HAVE_SYS_MODEM_H +#include +#endif +/* HP-UX requires that this be included to pick up TIOCGPGRP and friends */ +#ifdef HAVE_SYS_BSDTTY_H +#include +#endif + +PyDoc_STRVAR(termios__doc__, +"This module provides an interface to the Posix calls for tty I/O control.\n\ +For a complete description of these calls, see the Posix or Unix manual\n\ +pages. It is only available for those Unix versions that support Posix\n\ +termios style tty I/O control.\n\ +\n\ +All functions in this module take a file descriptor fd as their first\n\ +argument. This can be an integer file descriptor, such as returned by\n\ +sys.stdin.fileno(), or a file object, such as sys.stdin itself."); + typedef struct { PyObject *TermiosError; } termiosmodulestate; - + static inline termiosmodulestate* get_termios_state(PyObject *module) { @@ -53,574 +53,574 @@ get_termios_state(PyObject *module) #define modulestate_global get_termios_state(PyState_FindModule(&termiosmodule)) -static int fdconv(PyObject* obj, void* p) -{ - int fd; - - fd = PyObject_AsFileDescriptor(obj); - if (fd >= 0) { - *(int*)p = fd; - return 1; - } - return 0; -} - +static int fdconv(PyObject* obj, void* p) +{ + int fd; + + fd = PyObject_AsFileDescriptor(obj); + if (fd >= 0) { + *(int*)p = fd; + return 1; + } + return 0; +} + static struct PyModuleDef termiosmodule; -PyDoc_STRVAR(termios_tcgetattr__doc__, -"tcgetattr(fd) -> list_of_attrs\n\ -\n\ -Get the tty attributes for file descriptor fd, as follows:\n\ -[iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\ -of the tty special characters (each a string of length 1, except the items\n\ -with indices VMIN and VTIME, which are integers when these fields are\n\ -defined). The interpretation of the flags and the speeds as well as the\n\ -indexing in the cc array must be done using the symbolic constants defined\n\ -in this module."); - -static PyObject * -termios_tcgetattr(PyObject *self, PyObject *args) -{ - int fd; - struct termios mode; - PyObject *cc; - speed_t ispeed, ospeed; - PyObject *v; - int i; - char ch; - - if (!PyArg_ParseTuple(args, "O&:tcgetattr", - fdconv, (void*)&fd)) - return NULL; - - if (tcgetattr(fd, &mode) == -1) +PyDoc_STRVAR(termios_tcgetattr__doc__, +"tcgetattr(fd) -> list_of_attrs\n\ +\n\ +Get the tty attributes for file descriptor fd, as follows:\n\ +[iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\ +of the tty special characters (each a string of length 1, except the items\n\ +with indices VMIN and VTIME, which are integers when these fields are\n\ +defined). The interpretation of the flags and the speeds as well as the\n\ +indexing in the cc array must be done using the symbolic constants defined\n\ +in this module."); + +static PyObject * +termios_tcgetattr(PyObject *self, PyObject *args) +{ + int fd; + struct termios mode; + PyObject *cc; + speed_t ispeed, ospeed; + PyObject *v; + int i; + char ch; + + if (!PyArg_ParseTuple(args, "O&:tcgetattr", + fdconv, (void*)&fd)) + return NULL; + + if (tcgetattr(fd, &mode) == -1) return PyErr_SetFromErrno(modulestate_global->TermiosError); - - ispeed = cfgetispeed(&mode); - ospeed = cfgetospeed(&mode); - - cc = PyList_New(NCCS); - if (cc == NULL) - return NULL; - for (i = 0; i < NCCS; i++) { - ch = (char)mode.c_cc[i]; - v = PyBytes_FromStringAndSize(&ch, 1); - if (v == NULL) - goto err; - PyList_SetItem(cc, i, v); - } - - /* Convert the MIN and TIME slots to integer. On some systems, the - MIN and TIME slots are the same as the EOF and EOL slots. So we - only do this in noncanonical input mode. */ - if ((mode.c_lflag & ICANON) == 0) { - v = PyLong_FromLong((long)mode.c_cc[VMIN]); - if (v == NULL) - goto err; - PyList_SetItem(cc, VMIN, v); - v = PyLong_FromLong((long)mode.c_cc[VTIME]); - if (v == NULL) - goto err; - PyList_SetItem(cc, VTIME, v); - } - - if (!(v = PyList_New(7))) - goto err; - - PyList_SetItem(v, 0, PyLong_FromLong((long)mode.c_iflag)); - PyList_SetItem(v, 1, PyLong_FromLong((long)mode.c_oflag)); - PyList_SetItem(v, 2, PyLong_FromLong((long)mode.c_cflag)); - PyList_SetItem(v, 3, PyLong_FromLong((long)mode.c_lflag)); - PyList_SetItem(v, 4, PyLong_FromLong((long)ispeed)); - PyList_SetItem(v, 5, PyLong_FromLong((long)ospeed)); - if (PyErr_Occurred()) { - Py_DECREF(v); - goto err; - } - PyList_SetItem(v, 6, cc); - return v; - err: - Py_DECREF(cc); - return NULL; -} - -PyDoc_STRVAR(termios_tcsetattr__doc__, -"tcsetattr(fd, when, attributes) -> None\n\ -\n\ -Set the tty attributes for file descriptor fd.\n\ -The attributes to be set are taken from the attributes argument, which\n\ -is a list like the one returned by tcgetattr(). The when argument\n\ -determines when the attributes are changed: termios.TCSANOW to\n\ -change immediately, termios.TCSADRAIN to change after transmitting all\n\ -queued output, or termios.TCSAFLUSH to change after transmitting all\n\ -queued output and discarding all queued input. "); - -static PyObject * -termios_tcsetattr(PyObject *self, PyObject *args) -{ - int fd, when; - struct termios mode; - speed_t ispeed, ospeed; - PyObject *term, *cc, *v; - int i; - - if (!PyArg_ParseTuple(args, "O&iO:tcsetattr", - fdconv, &fd, &when, &term)) - return NULL; - if (!PyList_Check(term) || PyList_Size(term) != 7) { - PyErr_SetString(PyExc_TypeError, - "tcsetattr, arg 3: must be 7 element list"); - return NULL; - } - - /* Get the old mode, in case there are any hidden fields... */ + + ispeed = cfgetispeed(&mode); + ospeed = cfgetospeed(&mode); + + cc = PyList_New(NCCS); + if (cc == NULL) + return NULL; + for (i = 0; i < NCCS; i++) { + ch = (char)mode.c_cc[i]; + v = PyBytes_FromStringAndSize(&ch, 1); + if (v == NULL) + goto err; + PyList_SetItem(cc, i, v); + } + + /* Convert the MIN and TIME slots to integer. On some systems, the + MIN and TIME slots are the same as the EOF and EOL slots. So we + only do this in noncanonical input mode. */ + if ((mode.c_lflag & ICANON) == 0) { + v = PyLong_FromLong((long)mode.c_cc[VMIN]); + if (v == NULL) + goto err; + PyList_SetItem(cc, VMIN, v); + v = PyLong_FromLong((long)mode.c_cc[VTIME]); + if (v == NULL) + goto err; + PyList_SetItem(cc, VTIME, v); + } + + if (!(v = PyList_New(7))) + goto err; + + PyList_SetItem(v, 0, PyLong_FromLong((long)mode.c_iflag)); + PyList_SetItem(v, 1, PyLong_FromLong((long)mode.c_oflag)); + PyList_SetItem(v, 2, PyLong_FromLong((long)mode.c_cflag)); + PyList_SetItem(v, 3, PyLong_FromLong((long)mode.c_lflag)); + PyList_SetItem(v, 4, PyLong_FromLong((long)ispeed)); + PyList_SetItem(v, 5, PyLong_FromLong((long)ospeed)); + if (PyErr_Occurred()) { + Py_DECREF(v); + goto err; + } + PyList_SetItem(v, 6, cc); + return v; + err: + Py_DECREF(cc); + return NULL; +} + +PyDoc_STRVAR(termios_tcsetattr__doc__, +"tcsetattr(fd, when, attributes) -> None\n\ +\n\ +Set the tty attributes for file descriptor fd.\n\ +The attributes to be set are taken from the attributes argument, which\n\ +is a list like the one returned by tcgetattr(). The when argument\n\ +determines when the attributes are changed: termios.TCSANOW to\n\ +change immediately, termios.TCSADRAIN to change after transmitting all\n\ +queued output, or termios.TCSAFLUSH to change after transmitting all\n\ +queued output and discarding all queued input. "); + +static PyObject * +termios_tcsetattr(PyObject *self, PyObject *args) +{ + int fd, when; + struct termios mode; + speed_t ispeed, ospeed; + PyObject *term, *cc, *v; + int i; + + if (!PyArg_ParseTuple(args, "O&iO:tcsetattr", + fdconv, &fd, &when, &term)) + return NULL; + if (!PyList_Check(term) || PyList_Size(term) != 7) { + PyErr_SetString(PyExc_TypeError, + "tcsetattr, arg 3: must be 7 element list"); + return NULL; + } + + /* Get the old mode, in case there are any hidden fields... */ termiosmodulestate *state = modulestate_global; - if (tcgetattr(fd, &mode) == -1) + if (tcgetattr(fd, &mode) == -1) return PyErr_SetFromErrno(state->TermiosError); - mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0)); - mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1)); - mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2)); - mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3)); - ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4)); - ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5)); - cc = PyList_GetItem(term, 6); - if (PyErr_Occurred()) - return NULL; - - if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) { - PyErr_Format(PyExc_TypeError, - "tcsetattr: attributes[6] must be %d element list", - NCCS); - return NULL; - } - - for (i = 0; i < NCCS; i++) { - v = PyList_GetItem(cc, i); - - if (PyBytes_Check(v) && PyBytes_Size(v) == 1) - mode.c_cc[i] = (cc_t) * PyBytes_AsString(v); - else if (PyLong_Check(v)) - mode.c_cc[i] = (cc_t) PyLong_AsLong(v); - else { - PyErr_SetString(PyExc_TypeError, - "tcsetattr: elements of attributes must be characters or integers"); - return NULL; - } - } - - if (cfsetispeed(&mode, (speed_t) ispeed) == -1) + mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0)); + mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1)); + mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2)); + mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3)); + ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4)); + ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5)); + cc = PyList_GetItem(term, 6); + if (PyErr_Occurred()) + return NULL; + + if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) { + PyErr_Format(PyExc_TypeError, + "tcsetattr: attributes[6] must be %d element list", + NCCS); + return NULL; + } + + for (i = 0; i < NCCS; i++) { + v = PyList_GetItem(cc, i); + + if (PyBytes_Check(v) && PyBytes_Size(v) == 1) + mode.c_cc[i] = (cc_t) * PyBytes_AsString(v); + else if (PyLong_Check(v)) + mode.c_cc[i] = (cc_t) PyLong_AsLong(v); + else { + PyErr_SetString(PyExc_TypeError, + "tcsetattr: elements of attributes must be characters or integers"); + return NULL; + } + } + + if (cfsetispeed(&mode, (speed_t) ispeed) == -1) return PyErr_SetFromErrno(state->TermiosError); - if (cfsetospeed(&mode, (speed_t) ospeed) == -1) + if (cfsetospeed(&mode, (speed_t) ospeed) == -1) return PyErr_SetFromErrno(state->TermiosError); - if (tcsetattr(fd, when, &mode) == -1) + if (tcsetattr(fd, when, &mode) == -1) return PyErr_SetFromErrno(state->TermiosError); - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(termios_tcsendbreak__doc__, -"tcsendbreak(fd, duration) -> None\n\ -\n\ -Send a break on file descriptor fd.\n\ -A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\ -has a system dependent meaning."); - -static PyObject * -termios_tcsendbreak(PyObject *self, PyObject *args) -{ - int fd, duration; - - if (!PyArg_ParseTuple(args, "O&i:tcsendbreak", - fdconv, &fd, &duration)) - return NULL; - if (tcsendbreak(fd, duration) == -1) + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(termios_tcsendbreak__doc__, +"tcsendbreak(fd, duration) -> None\n\ +\n\ +Send a break on file descriptor fd.\n\ +A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\ +has a system dependent meaning."); + +static PyObject * +termios_tcsendbreak(PyObject *self, PyObject *args) +{ + int fd, duration; + + if (!PyArg_ParseTuple(args, "O&i:tcsendbreak", + fdconv, &fd, &duration)) + return NULL; + if (tcsendbreak(fd, duration) == -1) return PyErr_SetFromErrno(modulestate_global->TermiosError); - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(termios_tcdrain__doc__, -"tcdrain(fd) -> None\n\ -\n\ -Wait until all output written to file descriptor fd has been transmitted."); - -static PyObject * -termios_tcdrain(PyObject *self, PyObject *args) -{ - int fd; - - if (!PyArg_ParseTuple(args, "O&:tcdrain", - fdconv, &fd)) - return NULL; - if (tcdrain(fd) == -1) + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(termios_tcdrain__doc__, +"tcdrain(fd) -> None\n\ +\n\ +Wait until all output written to file descriptor fd has been transmitted."); + +static PyObject * +termios_tcdrain(PyObject *self, PyObject *args) +{ + int fd; + + if (!PyArg_ParseTuple(args, "O&:tcdrain", + fdconv, &fd)) + return NULL; + if (tcdrain(fd) == -1) return PyErr_SetFromErrno(modulestate_global->TermiosError); - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(termios_tcflush__doc__, -"tcflush(fd, queue) -> None\n\ -\n\ -Discard queued data on file descriptor fd.\n\ -The queue selector specifies which queue: termios.TCIFLUSH for the input\n\ -queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\ -both queues. "); - -static PyObject * -termios_tcflush(PyObject *self, PyObject *args) -{ - int fd, queue; - - if (!PyArg_ParseTuple(args, "O&i:tcflush", - fdconv, &fd, &queue)) - return NULL; - if (tcflush(fd, queue) == -1) + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(termios_tcflush__doc__, +"tcflush(fd, queue) -> None\n\ +\n\ +Discard queued data on file descriptor fd.\n\ +The queue selector specifies which queue: termios.TCIFLUSH for the input\n\ +queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\ +both queues. "); + +static PyObject * +termios_tcflush(PyObject *self, PyObject *args) +{ + int fd, queue; + + if (!PyArg_ParseTuple(args, "O&i:tcflush", + fdconv, &fd, &queue)) + return NULL; + if (tcflush(fd, queue) == -1) return PyErr_SetFromErrno(modulestate_global->TermiosError); - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(termios_tcflow__doc__, -"tcflow(fd, action) -> None\n\ -\n\ -Suspend or resume input or output on file descriptor fd.\n\ -The action argument can be termios.TCOOFF to suspend output,\n\ -termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\ -or termios.TCION to restart input."); - -static PyObject * -termios_tcflow(PyObject *self, PyObject *args) -{ - int fd, action; - - if (!PyArg_ParseTuple(args, "O&i:tcflow", - fdconv, &fd, &action)) - return NULL; - if (tcflow(fd, action) == -1) + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(termios_tcflow__doc__, +"tcflow(fd, action) -> None\n\ +\n\ +Suspend or resume input or output on file descriptor fd.\n\ +The action argument can be termios.TCOOFF to suspend output,\n\ +termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\ +or termios.TCION to restart input."); + +static PyObject * +termios_tcflow(PyObject *self, PyObject *args) +{ + int fd, action; + + if (!PyArg_ParseTuple(args, "O&i:tcflow", + fdconv, &fd, &action)) + return NULL; + if (tcflow(fd, action) == -1) return PyErr_SetFromErrno(modulestate_global->TermiosError); - - Py_RETURN_NONE; -} - -static PyMethodDef termios_methods[] = -{ - {"tcgetattr", termios_tcgetattr, - METH_VARARGS, termios_tcgetattr__doc__}, - {"tcsetattr", termios_tcsetattr, - METH_VARARGS, termios_tcsetattr__doc__}, - {"tcsendbreak", termios_tcsendbreak, - METH_VARARGS, termios_tcsendbreak__doc__}, - {"tcdrain", termios_tcdrain, - METH_VARARGS, termios_tcdrain__doc__}, - {"tcflush", termios_tcflush, - METH_VARARGS, termios_tcflush__doc__}, - {"tcflow", termios_tcflow, - METH_VARARGS, termios_tcflow__doc__}, - {NULL, NULL} -}; - - -#if defined(VSWTCH) && !defined(VSWTC) -#define VSWTC VSWTCH -#endif - -#if defined(VSWTC) && !defined(VSWTCH) -#define VSWTCH VSWTC -#endif - -static struct constant { - char *name; - long value; -} termios_constants[] = { - /* cfgetospeed(), cfsetospeed() constants */ - {"B0", B0}, - {"B50", B50}, - {"B75", B75}, - {"B110", B110}, - {"B134", B134}, - {"B150", B150}, - {"B200", B200}, - {"B300", B300}, - {"B600", B600}, - {"B1200", B1200}, - {"B1800", B1800}, - {"B2400", B2400}, - {"B4800", B4800}, - {"B9600", B9600}, - {"B19200", B19200}, - {"B38400", B38400}, -#ifdef B57600 - {"B57600", B57600}, -#endif -#ifdef B115200 - {"B115200", B115200}, -#endif -#ifdef B230400 - {"B230400", B230400}, -#endif -#ifdef B460800 - {"B460800", B460800}, -#endif -#ifdef B500000 - {"B500000", B500000}, -#endif -#ifdef B576000 - {"B576000", B576000}, -#endif -#ifdef B921600 - {"B921600", B921600}, -#endif -#ifdef B1000000 - {"B1000000", B1000000}, -#endif -#ifdef B1152000 - {"B1152000", B1152000}, -#endif -#ifdef B1500000 - {"B1500000", B1500000}, -#endif -#ifdef B2000000 - {"B2000000", B2000000}, -#endif -#ifdef B2500000 - {"B2500000", B2500000}, -#endif -#ifdef B3000000 - {"B3000000", B3000000}, -#endif -#ifdef B3500000 - {"B3500000", B3500000}, -#endif -#ifdef B4000000 - {"B4000000", B4000000}, -#endif - -#ifdef CBAUDEX - {"CBAUDEX", CBAUDEX}, -#endif - - /* tcsetattr() constants */ - {"TCSANOW", TCSANOW}, - {"TCSADRAIN", TCSADRAIN}, - {"TCSAFLUSH", TCSAFLUSH}, -#ifdef TCSASOFT - {"TCSASOFT", TCSASOFT}, -#endif - - /* tcflush() constants */ - {"TCIFLUSH", TCIFLUSH}, - {"TCOFLUSH", TCOFLUSH}, - {"TCIOFLUSH", TCIOFLUSH}, - - /* tcflow() constants */ - {"TCOOFF", TCOOFF}, - {"TCOON", TCOON}, - {"TCIOFF", TCIOFF}, - {"TCION", TCION}, - - /* struct termios.c_iflag constants */ - {"IGNBRK", IGNBRK}, - {"BRKINT", BRKINT}, - {"IGNPAR", IGNPAR}, - {"PARMRK", PARMRK}, - {"INPCK", INPCK}, - {"ISTRIP", ISTRIP}, - {"INLCR", INLCR}, - {"IGNCR", IGNCR}, - {"ICRNL", ICRNL}, -#ifdef IUCLC - {"IUCLC", IUCLC}, -#endif - {"IXON", IXON}, - {"IXANY", IXANY}, - {"IXOFF", IXOFF}, -#ifdef IMAXBEL - {"IMAXBEL", IMAXBEL}, -#endif - - /* struct termios.c_oflag constants */ - {"OPOST", OPOST}, -#ifdef OLCUC - {"OLCUC", OLCUC}, -#endif -#ifdef ONLCR - {"ONLCR", ONLCR}, -#endif -#ifdef OCRNL - {"OCRNL", OCRNL}, -#endif -#ifdef ONOCR - {"ONOCR", ONOCR}, -#endif -#ifdef ONLRET - {"ONLRET", ONLRET}, -#endif -#ifdef OFILL - {"OFILL", OFILL}, -#endif -#ifdef OFDEL - {"OFDEL", OFDEL}, -#endif -#ifdef NLDLY - {"NLDLY", NLDLY}, -#endif -#ifdef CRDLY - {"CRDLY", CRDLY}, -#endif -#ifdef TABDLY - {"TABDLY", TABDLY}, -#endif -#ifdef BSDLY - {"BSDLY", BSDLY}, -#endif -#ifdef VTDLY - {"VTDLY", VTDLY}, -#endif -#ifdef FFDLY - {"FFDLY", FFDLY}, -#endif - - /* struct termios.c_oflag-related values (delay mask) */ -#ifdef NL0 - {"NL0", NL0}, -#endif -#ifdef NL1 - {"NL1", NL1}, -#endif -#ifdef CR0 - {"CR0", CR0}, -#endif -#ifdef CR1 - {"CR1", CR1}, -#endif -#ifdef CR2 - {"CR2", CR2}, -#endif -#ifdef CR3 - {"CR3", CR3}, -#endif -#ifdef TAB0 - {"TAB0", TAB0}, -#endif -#ifdef TAB1 - {"TAB1", TAB1}, -#endif -#ifdef TAB2 - {"TAB2", TAB2}, -#endif -#ifdef TAB3 - {"TAB3", TAB3}, -#endif -#ifdef XTABS - {"XTABS", XTABS}, -#endif -#ifdef BS0 - {"BS0", BS0}, -#endif -#ifdef BS1 - {"BS1", BS1}, -#endif -#ifdef VT0 - {"VT0", VT0}, -#endif -#ifdef VT1 - {"VT1", VT1}, -#endif -#ifdef FF0 - {"FF0", FF0}, -#endif -#ifdef FF1 - {"FF1", FF1}, -#endif - - /* struct termios.c_cflag constants */ - {"CSIZE", CSIZE}, - {"CSTOPB", CSTOPB}, - {"CREAD", CREAD}, - {"PARENB", PARENB}, - {"PARODD", PARODD}, - {"HUPCL", HUPCL}, - {"CLOCAL", CLOCAL}, -#ifdef CIBAUD - {"CIBAUD", CIBAUD}, -#endif -#ifdef CRTSCTS - {"CRTSCTS", (long)CRTSCTS}, -#endif - - /* struct termios.c_cflag-related values (character size) */ - {"CS5", CS5}, - {"CS6", CS6}, - {"CS7", CS7}, - {"CS8", CS8}, - - /* struct termios.c_lflag constants */ - {"ISIG", ISIG}, - {"ICANON", ICANON}, -#ifdef XCASE - {"XCASE", XCASE}, -#endif - {"ECHO", ECHO}, - {"ECHOE", ECHOE}, - {"ECHOK", ECHOK}, - {"ECHONL", ECHONL}, -#ifdef ECHOCTL - {"ECHOCTL", ECHOCTL}, -#endif -#ifdef ECHOPRT - {"ECHOPRT", ECHOPRT}, -#endif -#ifdef ECHOKE - {"ECHOKE", ECHOKE}, -#endif -#ifdef FLUSHO - {"FLUSHO", FLUSHO}, -#endif - {"NOFLSH", NOFLSH}, - {"TOSTOP", TOSTOP}, -#ifdef PENDIN - {"PENDIN", PENDIN}, -#endif - {"IEXTEN", IEXTEN}, - - /* indexes into the control chars array returned by tcgetattr() */ - {"VINTR", VINTR}, - {"VQUIT", VQUIT}, - {"VERASE", VERASE}, - {"VKILL", VKILL}, - {"VEOF", VEOF}, - {"VTIME", VTIME}, - {"VMIN", VMIN}, -#ifdef VSWTC - /* The #defines above ensure that if either is defined, both are, - * but both may be omitted by the system headers. ;-( */ - {"VSWTC", VSWTC}, - {"VSWTCH", VSWTCH}, -#endif - {"VSTART", VSTART}, - {"VSTOP", VSTOP}, - {"VSUSP", VSUSP}, - {"VEOL", VEOL}, -#ifdef VREPRINT - {"VREPRINT", VREPRINT}, -#endif -#ifdef VDISCARD - {"VDISCARD", VDISCARD}, -#endif -#ifdef VWERASE - {"VWERASE", VWERASE}, -#endif -#ifdef VLNEXT - {"VLNEXT", VLNEXT}, -#endif -#ifdef VEOL2 - {"VEOL2", VEOL2}, -#endif - - -#ifdef B460800 - {"B460800", B460800}, -#endif + + Py_RETURN_NONE; +} + +static PyMethodDef termios_methods[] = +{ + {"tcgetattr", termios_tcgetattr, + METH_VARARGS, termios_tcgetattr__doc__}, + {"tcsetattr", termios_tcsetattr, + METH_VARARGS, termios_tcsetattr__doc__}, + {"tcsendbreak", termios_tcsendbreak, + METH_VARARGS, termios_tcsendbreak__doc__}, + {"tcdrain", termios_tcdrain, + METH_VARARGS, termios_tcdrain__doc__}, + {"tcflush", termios_tcflush, + METH_VARARGS, termios_tcflush__doc__}, + {"tcflow", termios_tcflow, + METH_VARARGS, termios_tcflow__doc__}, + {NULL, NULL} +}; + + +#if defined(VSWTCH) && !defined(VSWTC) +#define VSWTC VSWTCH +#endif + +#if defined(VSWTC) && !defined(VSWTCH) +#define VSWTCH VSWTC +#endif + +static struct constant { + char *name; + long value; +} termios_constants[] = { + /* cfgetospeed(), cfsetospeed() constants */ + {"B0", B0}, + {"B50", B50}, + {"B75", B75}, + {"B110", B110}, + {"B134", B134}, + {"B150", B150}, + {"B200", B200}, + {"B300", B300}, + {"B600", B600}, + {"B1200", B1200}, + {"B1800", B1800}, + {"B2400", B2400}, + {"B4800", B4800}, + {"B9600", B9600}, + {"B19200", B19200}, + {"B38400", B38400}, +#ifdef B57600 + {"B57600", B57600}, +#endif +#ifdef B115200 + {"B115200", B115200}, +#endif +#ifdef B230400 + {"B230400", B230400}, +#endif +#ifdef B460800 + {"B460800", B460800}, +#endif +#ifdef B500000 + {"B500000", B500000}, +#endif +#ifdef B576000 + {"B576000", B576000}, +#endif +#ifdef B921600 + {"B921600", B921600}, +#endif +#ifdef B1000000 + {"B1000000", B1000000}, +#endif +#ifdef B1152000 + {"B1152000", B1152000}, +#endif +#ifdef B1500000 + {"B1500000", B1500000}, +#endif +#ifdef B2000000 + {"B2000000", B2000000}, +#endif +#ifdef B2500000 + {"B2500000", B2500000}, +#endif +#ifdef B3000000 + {"B3000000", B3000000}, +#endif +#ifdef B3500000 + {"B3500000", B3500000}, +#endif +#ifdef B4000000 + {"B4000000", B4000000}, +#endif + +#ifdef CBAUDEX + {"CBAUDEX", CBAUDEX}, +#endif + + /* tcsetattr() constants */ + {"TCSANOW", TCSANOW}, + {"TCSADRAIN", TCSADRAIN}, + {"TCSAFLUSH", TCSAFLUSH}, +#ifdef TCSASOFT + {"TCSASOFT", TCSASOFT}, +#endif + + /* tcflush() constants */ + {"TCIFLUSH", TCIFLUSH}, + {"TCOFLUSH", TCOFLUSH}, + {"TCIOFLUSH", TCIOFLUSH}, + + /* tcflow() constants */ + {"TCOOFF", TCOOFF}, + {"TCOON", TCOON}, + {"TCIOFF", TCIOFF}, + {"TCION", TCION}, + + /* struct termios.c_iflag constants */ + {"IGNBRK", IGNBRK}, + {"BRKINT", BRKINT}, + {"IGNPAR", IGNPAR}, + {"PARMRK", PARMRK}, + {"INPCK", INPCK}, + {"ISTRIP", ISTRIP}, + {"INLCR", INLCR}, + {"IGNCR", IGNCR}, + {"ICRNL", ICRNL}, +#ifdef IUCLC + {"IUCLC", IUCLC}, +#endif + {"IXON", IXON}, + {"IXANY", IXANY}, + {"IXOFF", IXOFF}, +#ifdef IMAXBEL + {"IMAXBEL", IMAXBEL}, +#endif + + /* struct termios.c_oflag constants */ + {"OPOST", OPOST}, +#ifdef OLCUC + {"OLCUC", OLCUC}, +#endif +#ifdef ONLCR + {"ONLCR", ONLCR}, +#endif +#ifdef OCRNL + {"OCRNL", OCRNL}, +#endif +#ifdef ONOCR + {"ONOCR", ONOCR}, +#endif +#ifdef ONLRET + {"ONLRET", ONLRET}, +#endif +#ifdef OFILL + {"OFILL", OFILL}, +#endif +#ifdef OFDEL + {"OFDEL", OFDEL}, +#endif +#ifdef NLDLY + {"NLDLY", NLDLY}, +#endif +#ifdef CRDLY + {"CRDLY", CRDLY}, +#endif +#ifdef TABDLY + {"TABDLY", TABDLY}, +#endif +#ifdef BSDLY + {"BSDLY", BSDLY}, +#endif +#ifdef VTDLY + {"VTDLY", VTDLY}, +#endif +#ifdef FFDLY + {"FFDLY", FFDLY}, +#endif + + /* struct termios.c_oflag-related values (delay mask) */ +#ifdef NL0 + {"NL0", NL0}, +#endif +#ifdef NL1 + {"NL1", NL1}, +#endif +#ifdef CR0 + {"CR0", CR0}, +#endif +#ifdef CR1 + {"CR1", CR1}, +#endif +#ifdef CR2 + {"CR2", CR2}, +#endif +#ifdef CR3 + {"CR3", CR3}, +#endif +#ifdef TAB0 + {"TAB0", TAB0}, +#endif +#ifdef TAB1 + {"TAB1", TAB1}, +#endif +#ifdef TAB2 + {"TAB2", TAB2}, +#endif +#ifdef TAB3 + {"TAB3", TAB3}, +#endif +#ifdef XTABS + {"XTABS", XTABS}, +#endif +#ifdef BS0 + {"BS0", BS0}, +#endif +#ifdef BS1 + {"BS1", BS1}, +#endif +#ifdef VT0 + {"VT0", VT0}, +#endif +#ifdef VT1 + {"VT1", VT1}, +#endif +#ifdef FF0 + {"FF0", FF0}, +#endif +#ifdef FF1 + {"FF1", FF1}, +#endif + + /* struct termios.c_cflag constants */ + {"CSIZE", CSIZE}, + {"CSTOPB", CSTOPB}, + {"CREAD", CREAD}, + {"PARENB", PARENB}, + {"PARODD", PARODD}, + {"HUPCL", HUPCL}, + {"CLOCAL", CLOCAL}, +#ifdef CIBAUD + {"CIBAUD", CIBAUD}, +#endif +#ifdef CRTSCTS + {"CRTSCTS", (long)CRTSCTS}, +#endif + + /* struct termios.c_cflag-related values (character size) */ + {"CS5", CS5}, + {"CS6", CS6}, + {"CS7", CS7}, + {"CS8", CS8}, + + /* struct termios.c_lflag constants */ + {"ISIG", ISIG}, + {"ICANON", ICANON}, +#ifdef XCASE + {"XCASE", XCASE}, +#endif + {"ECHO", ECHO}, + {"ECHOE", ECHOE}, + {"ECHOK", ECHOK}, + {"ECHONL", ECHONL}, +#ifdef ECHOCTL + {"ECHOCTL", ECHOCTL}, +#endif +#ifdef ECHOPRT + {"ECHOPRT", ECHOPRT}, +#endif +#ifdef ECHOKE + {"ECHOKE", ECHOKE}, +#endif +#ifdef FLUSHO + {"FLUSHO", FLUSHO}, +#endif + {"NOFLSH", NOFLSH}, + {"TOSTOP", TOSTOP}, +#ifdef PENDIN + {"PENDIN", PENDIN}, +#endif + {"IEXTEN", IEXTEN}, + + /* indexes into the control chars array returned by tcgetattr() */ + {"VINTR", VINTR}, + {"VQUIT", VQUIT}, + {"VERASE", VERASE}, + {"VKILL", VKILL}, + {"VEOF", VEOF}, + {"VTIME", VTIME}, + {"VMIN", VMIN}, +#ifdef VSWTC + /* The #defines above ensure that if either is defined, both are, + * but both may be omitted by the system headers. ;-( */ + {"VSWTC", VSWTC}, + {"VSWTCH", VSWTCH}, +#endif + {"VSTART", VSTART}, + {"VSTOP", VSTOP}, + {"VSUSP", VSUSP}, + {"VEOL", VEOL}, +#ifdef VREPRINT + {"VREPRINT", VREPRINT}, +#endif +#ifdef VDISCARD + {"VDISCARD", VDISCARD}, +#endif +#ifdef VWERASE + {"VWERASE", VWERASE}, +#endif +#ifdef VLNEXT + {"VLNEXT", VLNEXT}, +#endif +#ifdef VEOL2 + {"VEOL2", VEOL2}, +#endif + + +#ifdef B460800 + {"B460800", B460800}, +#endif #ifdef B500000 {"B500000", B500000}, #endif @@ -654,340 +654,340 @@ static struct constant { #ifdef B4000000 { "B4000000", B4000000}, #endif -#ifdef CBAUD - {"CBAUD", CBAUD}, -#endif -#ifdef CDEL - {"CDEL", CDEL}, -#endif -#ifdef CDSUSP - {"CDSUSP", CDSUSP}, -#endif -#ifdef CEOF - {"CEOF", CEOF}, -#endif -#ifdef CEOL - {"CEOL", CEOL}, -#endif -#ifdef CEOL2 - {"CEOL2", CEOL2}, -#endif -#ifdef CEOT - {"CEOT", CEOT}, -#endif -#ifdef CERASE - {"CERASE", CERASE}, -#endif -#ifdef CESC - {"CESC", CESC}, -#endif -#ifdef CFLUSH - {"CFLUSH", CFLUSH}, -#endif -#ifdef CINTR - {"CINTR", CINTR}, -#endif -#ifdef CKILL - {"CKILL", CKILL}, -#endif -#ifdef CLNEXT - {"CLNEXT", CLNEXT}, -#endif -#ifdef CNUL - {"CNUL", CNUL}, -#endif -#ifdef COMMON - {"COMMON", COMMON}, -#endif -#ifdef CQUIT - {"CQUIT", CQUIT}, -#endif -#ifdef CRPRNT - {"CRPRNT", CRPRNT}, -#endif -#ifdef CSTART - {"CSTART", CSTART}, -#endif -#ifdef CSTOP - {"CSTOP", CSTOP}, -#endif -#ifdef CSUSP - {"CSUSP", CSUSP}, -#endif -#ifdef CSWTCH - {"CSWTCH", CSWTCH}, -#endif -#ifdef CWERASE - {"CWERASE", CWERASE}, -#endif -#ifdef EXTA - {"EXTA", EXTA}, -#endif -#ifdef EXTB - {"EXTB", EXTB}, -#endif -#ifdef FIOASYNC - {"FIOASYNC", FIOASYNC}, -#endif -#ifdef FIOCLEX - {"FIOCLEX", FIOCLEX}, -#endif -#ifdef FIONBIO - {"FIONBIO", FIONBIO}, -#endif -#ifdef FIONCLEX - {"FIONCLEX", FIONCLEX}, -#endif -#ifdef FIONREAD - {"FIONREAD", FIONREAD}, -#endif -#ifdef IBSHIFT - {"IBSHIFT", IBSHIFT}, -#endif -#ifdef INIT_C_CC - {"INIT_C_CC", INIT_C_CC}, -#endif -#ifdef IOCSIZE_MASK - {"IOCSIZE_MASK", IOCSIZE_MASK}, -#endif -#ifdef IOCSIZE_SHIFT - {"IOCSIZE_SHIFT", IOCSIZE_SHIFT}, -#endif -#ifdef NCC - {"NCC", NCC}, -#endif -#ifdef NCCS - {"NCCS", NCCS}, -#endif -#ifdef NSWTCH - {"NSWTCH", NSWTCH}, -#endif -#ifdef N_MOUSE - {"N_MOUSE", N_MOUSE}, -#endif -#ifdef N_PPP - {"N_PPP", N_PPP}, -#endif -#ifdef N_SLIP - {"N_SLIP", N_SLIP}, -#endif -#ifdef N_STRIP - {"N_STRIP", N_STRIP}, -#endif -#ifdef N_TTY - {"N_TTY", N_TTY}, -#endif -#ifdef TCFLSH - {"TCFLSH", TCFLSH}, -#endif -#ifdef TCGETA - {"TCGETA", TCGETA}, -#endif -#ifdef TCGETS - {"TCGETS", TCGETS}, -#endif -#ifdef TCSBRK - {"TCSBRK", TCSBRK}, -#endif -#ifdef TCSBRKP - {"TCSBRKP", TCSBRKP}, -#endif -#ifdef TCSETA - {"TCSETA", TCSETA}, -#endif -#ifdef TCSETAF - {"TCSETAF", TCSETAF}, -#endif -#ifdef TCSETAW - {"TCSETAW", TCSETAW}, -#endif -#ifdef TCSETS - {"TCSETS", TCSETS}, -#endif -#ifdef TCSETSF - {"TCSETSF", TCSETSF}, -#endif -#ifdef TCSETSW - {"TCSETSW", TCSETSW}, -#endif -#ifdef TCXONC - {"TCXONC", TCXONC}, -#endif -#ifdef TIOCCONS - {"TIOCCONS", TIOCCONS}, -#endif -#ifdef TIOCEXCL - {"TIOCEXCL", TIOCEXCL}, -#endif -#ifdef TIOCGETD - {"TIOCGETD", TIOCGETD}, -#endif -#ifdef TIOCGICOUNT - {"TIOCGICOUNT", TIOCGICOUNT}, -#endif -#ifdef TIOCGLCKTRMIOS - {"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS}, -#endif -#ifdef TIOCGPGRP - {"TIOCGPGRP", TIOCGPGRP}, -#endif -#ifdef TIOCGSERIAL - {"TIOCGSERIAL", TIOCGSERIAL}, -#endif -#ifdef TIOCGSOFTCAR - {"TIOCGSOFTCAR", TIOCGSOFTCAR}, -#endif -#ifdef TIOCGWINSZ - {"TIOCGWINSZ", TIOCGWINSZ}, -#endif -#ifdef TIOCINQ - {"TIOCINQ", TIOCINQ}, -#endif -#ifdef TIOCLINUX - {"TIOCLINUX", TIOCLINUX}, -#endif -#ifdef TIOCMBIC - {"TIOCMBIC", TIOCMBIC}, -#endif -#ifdef TIOCMBIS - {"TIOCMBIS", TIOCMBIS}, -#endif -#ifdef TIOCMGET - {"TIOCMGET", TIOCMGET}, -#endif -#ifdef TIOCMIWAIT - {"TIOCMIWAIT", TIOCMIWAIT}, -#endif -#ifdef TIOCMSET - {"TIOCMSET", TIOCMSET}, -#endif -#ifdef TIOCM_CAR - {"TIOCM_CAR", TIOCM_CAR}, -#endif -#ifdef TIOCM_CD - {"TIOCM_CD", TIOCM_CD}, -#endif -#ifdef TIOCM_CTS - {"TIOCM_CTS", TIOCM_CTS}, -#endif -#ifdef TIOCM_DSR - {"TIOCM_DSR", TIOCM_DSR}, -#endif -#ifdef TIOCM_DTR - {"TIOCM_DTR", TIOCM_DTR}, -#endif -#ifdef TIOCM_LE - {"TIOCM_LE", TIOCM_LE}, -#endif -#ifdef TIOCM_RI - {"TIOCM_RI", TIOCM_RI}, -#endif -#ifdef TIOCM_RNG - {"TIOCM_RNG", TIOCM_RNG}, -#endif -#ifdef TIOCM_RTS - {"TIOCM_RTS", TIOCM_RTS}, -#endif -#ifdef TIOCM_SR - {"TIOCM_SR", TIOCM_SR}, -#endif -#ifdef TIOCM_ST - {"TIOCM_ST", TIOCM_ST}, -#endif -#ifdef TIOCNOTTY - {"TIOCNOTTY", TIOCNOTTY}, -#endif -#ifdef TIOCNXCL - {"TIOCNXCL", TIOCNXCL}, -#endif -#ifdef TIOCOUTQ - {"TIOCOUTQ", TIOCOUTQ}, -#endif -#ifdef TIOCPKT - {"TIOCPKT", TIOCPKT}, -#endif -#ifdef TIOCPKT_DATA - {"TIOCPKT_DATA", TIOCPKT_DATA}, -#endif -#ifdef TIOCPKT_DOSTOP - {"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP}, -#endif -#ifdef TIOCPKT_FLUSHREAD - {"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD}, -#endif -#ifdef TIOCPKT_FLUSHWRITE - {"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE}, -#endif -#ifdef TIOCPKT_NOSTOP - {"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP}, -#endif -#ifdef TIOCPKT_START - {"TIOCPKT_START", TIOCPKT_START}, -#endif -#ifdef TIOCPKT_STOP - {"TIOCPKT_STOP", TIOCPKT_STOP}, -#endif -#ifdef TIOCSCTTY - {"TIOCSCTTY", TIOCSCTTY}, -#endif -#ifdef TIOCSERCONFIG - {"TIOCSERCONFIG", TIOCSERCONFIG}, -#endif -#ifdef TIOCSERGETLSR - {"TIOCSERGETLSR", TIOCSERGETLSR}, -#endif -#ifdef TIOCSERGETMULTI - {"TIOCSERGETMULTI", TIOCSERGETMULTI}, -#endif -#ifdef TIOCSERGSTRUCT - {"TIOCSERGSTRUCT", TIOCSERGSTRUCT}, -#endif -#ifdef TIOCSERGWILD - {"TIOCSERGWILD", TIOCSERGWILD}, -#endif -#ifdef TIOCSERSETMULTI - {"TIOCSERSETMULTI", TIOCSERSETMULTI}, -#endif -#ifdef TIOCSERSWILD - {"TIOCSERSWILD", TIOCSERSWILD}, -#endif -#ifdef TIOCSER_TEMT - {"TIOCSER_TEMT", TIOCSER_TEMT}, -#endif -#ifdef TIOCSETD - {"TIOCSETD", TIOCSETD}, -#endif -#ifdef TIOCSLCKTRMIOS - {"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS}, -#endif -#ifdef TIOCSPGRP - {"TIOCSPGRP", TIOCSPGRP}, -#endif -#ifdef TIOCSSERIAL - {"TIOCSSERIAL", TIOCSSERIAL}, -#endif -#ifdef TIOCSSOFTCAR - {"TIOCSSOFTCAR", TIOCSSOFTCAR}, -#endif -#ifdef TIOCSTI - {"TIOCSTI", TIOCSTI}, -#endif -#ifdef TIOCSWINSZ - {"TIOCSWINSZ", TIOCSWINSZ}, -#endif -#ifdef TIOCTTYGSTRUCT - {"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT}, -#endif - - /* sentinel */ - {NULL, 0} -}; - +#ifdef CBAUD + {"CBAUD", CBAUD}, +#endif +#ifdef CDEL + {"CDEL", CDEL}, +#endif +#ifdef CDSUSP + {"CDSUSP", CDSUSP}, +#endif +#ifdef CEOF + {"CEOF", CEOF}, +#endif +#ifdef CEOL + {"CEOL", CEOL}, +#endif +#ifdef CEOL2 + {"CEOL2", CEOL2}, +#endif +#ifdef CEOT + {"CEOT", CEOT}, +#endif +#ifdef CERASE + {"CERASE", CERASE}, +#endif +#ifdef CESC + {"CESC", CESC}, +#endif +#ifdef CFLUSH + {"CFLUSH", CFLUSH}, +#endif +#ifdef CINTR + {"CINTR", CINTR}, +#endif +#ifdef CKILL + {"CKILL", CKILL}, +#endif +#ifdef CLNEXT + {"CLNEXT", CLNEXT}, +#endif +#ifdef CNUL + {"CNUL", CNUL}, +#endif +#ifdef COMMON + {"COMMON", COMMON}, +#endif +#ifdef CQUIT + {"CQUIT", CQUIT}, +#endif +#ifdef CRPRNT + {"CRPRNT", CRPRNT}, +#endif +#ifdef CSTART + {"CSTART", CSTART}, +#endif +#ifdef CSTOP + {"CSTOP", CSTOP}, +#endif +#ifdef CSUSP + {"CSUSP", CSUSP}, +#endif +#ifdef CSWTCH + {"CSWTCH", CSWTCH}, +#endif +#ifdef CWERASE + {"CWERASE", CWERASE}, +#endif +#ifdef EXTA + {"EXTA", EXTA}, +#endif +#ifdef EXTB + {"EXTB", EXTB}, +#endif +#ifdef FIOASYNC + {"FIOASYNC", FIOASYNC}, +#endif +#ifdef FIOCLEX + {"FIOCLEX", FIOCLEX}, +#endif +#ifdef FIONBIO + {"FIONBIO", FIONBIO}, +#endif +#ifdef FIONCLEX + {"FIONCLEX", FIONCLEX}, +#endif +#ifdef FIONREAD + {"FIONREAD", FIONREAD}, +#endif +#ifdef IBSHIFT + {"IBSHIFT", IBSHIFT}, +#endif +#ifdef INIT_C_CC + {"INIT_C_CC", INIT_C_CC}, +#endif +#ifdef IOCSIZE_MASK + {"IOCSIZE_MASK", IOCSIZE_MASK}, +#endif +#ifdef IOCSIZE_SHIFT + {"IOCSIZE_SHIFT", IOCSIZE_SHIFT}, +#endif +#ifdef NCC + {"NCC", NCC}, +#endif +#ifdef NCCS + {"NCCS", NCCS}, +#endif +#ifdef NSWTCH + {"NSWTCH", NSWTCH}, +#endif +#ifdef N_MOUSE + {"N_MOUSE", N_MOUSE}, +#endif +#ifdef N_PPP + {"N_PPP", N_PPP}, +#endif +#ifdef N_SLIP + {"N_SLIP", N_SLIP}, +#endif +#ifdef N_STRIP + {"N_STRIP", N_STRIP}, +#endif +#ifdef N_TTY + {"N_TTY", N_TTY}, +#endif +#ifdef TCFLSH + {"TCFLSH", TCFLSH}, +#endif +#ifdef TCGETA + {"TCGETA", TCGETA}, +#endif +#ifdef TCGETS + {"TCGETS", TCGETS}, +#endif +#ifdef TCSBRK + {"TCSBRK", TCSBRK}, +#endif +#ifdef TCSBRKP + {"TCSBRKP", TCSBRKP}, +#endif +#ifdef TCSETA + {"TCSETA", TCSETA}, +#endif +#ifdef TCSETAF + {"TCSETAF", TCSETAF}, +#endif +#ifdef TCSETAW + {"TCSETAW", TCSETAW}, +#endif +#ifdef TCSETS + {"TCSETS", TCSETS}, +#endif +#ifdef TCSETSF + {"TCSETSF", TCSETSF}, +#endif +#ifdef TCSETSW + {"TCSETSW", TCSETSW}, +#endif +#ifdef TCXONC + {"TCXONC", TCXONC}, +#endif +#ifdef TIOCCONS + {"TIOCCONS", TIOCCONS}, +#endif +#ifdef TIOCEXCL + {"TIOCEXCL", TIOCEXCL}, +#endif +#ifdef TIOCGETD + {"TIOCGETD", TIOCGETD}, +#endif +#ifdef TIOCGICOUNT + {"TIOCGICOUNT", TIOCGICOUNT}, +#endif +#ifdef TIOCGLCKTRMIOS + {"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS}, +#endif +#ifdef TIOCGPGRP + {"TIOCGPGRP", TIOCGPGRP}, +#endif +#ifdef TIOCGSERIAL + {"TIOCGSERIAL", TIOCGSERIAL}, +#endif +#ifdef TIOCGSOFTCAR + {"TIOCGSOFTCAR", TIOCGSOFTCAR}, +#endif +#ifdef TIOCGWINSZ + {"TIOCGWINSZ", TIOCGWINSZ}, +#endif +#ifdef TIOCINQ + {"TIOCINQ", TIOCINQ}, +#endif +#ifdef TIOCLINUX + {"TIOCLINUX", TIOCLINUX}, +#endif +#ifdef TIOCMBIC + {"TIOCMBIC", TIOCMBIC}, +#endif +#ifdef TIOCMBIS + {"TIOCMBIS", TIOCMBIS}, +#endif +#ifdef TIOCMGET + {"TIOCMGET", TIOCMGET}, +#endif +#ifdef TIOCMIWAIT + {"TIOCMIWAIT", TIOCMIWAIT}, +#endif +#ifdef TIOCMSET + {"TIOCMSET", TIOCMSET}, +#endif +#ifdef TIOCM_CAR + {"TIOCM_CAR", TIOCM_CAR}, +#endif +#ifdef TIOCM_CD + {"TIOCM_CD", TIOCM_CD}, +#endif +#ifdef TIOCM_CTS + {"TIOCM_CTS", TIOCM_CTS}, +#endif +#ifdef TIOCM_DSR + {"TIOCM_DSR", TIOCM_DSR}, +#endif +#ifdef TIOCM_DTR + {"TIOCM_DTR", TIOCM_DTR}, +#endif +#ifdef TIOCM_LE + {"TIOCM_LE", TIOCM_LE}, +#endif +#ifdef TIOCM_RI + {"TIOCM_RI", TIOCM_RI}, +#endif +#ifdef TIOCM_RNG + {"TIOCM_RNG", TIOCM_RNG}, +#endif +#ifdef TIOCM_RTS + {"TIOCM_RTS", TIOCM_RTS}, +#endif +#ifdef TIOCM_SR + {"TIOCM_SR", TIOCM_SR}, +#endif +#ifdef TIOCM_ST + {"TIOCM_ST", TIOCM_ST}, +#endif +#ifdef TIOCNOTTY + {"TIOCNOTTY", TIOCNOTTY}, +#endif +#ifdef TIOCNXCL + {"TIOCNXCL", TIOCNXCL}, +#endif +#ifdef TIOCOUTQ + {"TIOCOUTQ", TIOCOUTQ}, +#endif +#ifdef TIOCPKT + {"TIOCPKT", TIOCPKT}, +#endif +#ifdef TIOCPKT_DATA + {"TIOCPKT_DATA", TIOCPKT_DATA}, +#endif +#ifdef TIOCPKT_DOSTOP + {"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP}, +#endif +#ifdef TIOCPKT_FLUSHREAD + {"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD}, +#endif +#ifdef TIOCPKT_FLUSHWRITE + {"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE}, +#endif +#ifdef TIOCPKT_NOSTOP + {"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP}, +#endif +#ifdef TIOCPKT_START + {"TIOCPKT_START", TIOCPKT_START}, +#endif +#ifdef TIOCPKT_STOP + {"TIOCPKT_STOP", TIOCPKT_STOP}, +#endif +#ifdef TIOCSCTTY + {"TIOCSCTTY", TIOCSCTTY}, +#endif +#ifdef TIOCSERCONFIG + {"TIOCSERCONFIG", TIOCSERCONFIG}, +#endif +#ifdef TIOCSERGETLSR + {"TIOCSERGETLSR", TIOCSERGETLSR}, +#endif +#ifdef TIOCSERGETMULTI + {"TIOCSERGETMULTI", TIOCSERGETMULTI}, +#endif +#ifdef TIOCSERGSTRUCT + {"TIOCSERGSTRUCT", TIOCSERGSTRUCT}, +#endif +#ifdef TIOCSERGWILD + {"TIOCSERGWILD", TIOCSERGWILD}, +#endif +#ifdef TIOCSERSETMULTI + {"TIOCSERSETMULTI", TIOCSERSETMULTI}, +#endif +#ifdef TIOCSERSWILD + {"TIOCSERSWILD", TIOCSERSWILD}, +#endif +#ifdef TIOCSER_TEMT + {"TIOCSER_TEMT", TIOCSER_TEMT}, +#endif +#ifdef TIOCSETD + {"TIOCSETD", TIOCSETD}, +#endif +#ifdef TIOCSLCKTRMIOS + {"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS}, +#endif +#ifdef TIOCSPGRP + {"TIOCSPGRP", TIOCSPGRP}, +#endif +#ifdef TIOCSSERIAL + {"TIOCSSERIAL", TIOCSSERIAL}, +#endif +#ifdef TIOCSSOFTCAR + {"TIOCSSOFTCAR", TIOCSSOFTCAR}, +#endif +#ifdef TIOCSTI + {"TIOCSTI", TIOCSTI}, +#endif +#ifdef TIOCSWINSZ + {"TIOCSWINSZ", TIOCSWINSZ}, +#endif +#ifdef TIOCTTYGSTRUCT + {"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT}, +#endif + + /* sentinel */ + {NULL, 0} +}; + static int termiosmodule_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(get_termios_state(m)->TermiosError); return 0; } - + static int termiosmodule_clear(PyObject *m) { Py_CLEAR(get_termios_state(m)->TermiosError); return 0; @@ -997,44 +997,44 @@ static void termiosmodule_free(void *m) { termiosmodule_clear((PyObject *)m); } -static struct PyModuleDef termiosmodule = { - PyModuleDef_HEAD_INIT, - "termios", - termios__doc__, +static struct PyModuleDef termiosmodule = { + PyModuleDef_HEAD_INIT, + "termios", + termios__doc__, sizeof(termiosmodulestate), - termios_methods, - NULL, + termios_methods, + NULL, termiosmodule_traverse, termiosmodule_clear, termiosmodule_free, -}; - -PyMODINIT_FUNC -PyInit_termios(void) -{ - PyObject *m; - struct constant *constant = termios_constants; - +}; + +PyMODINIT_FUNC +PyInit_termios(void) +{ + PyObject *m; + struct constant *constant = termios_constants; + if ((m = PyState_FindModule(&termiosmodule)) != NULL) { Py_INCREF(m); return m; } if ((m = PyModule_Create(&termiosmodule)) == NULL) { - return NULL; + return NULL; } - + termiosmodulestate *state = get_termios_state(m); state->TermiosError = PyErr_NewException("termios.error", NULL, NULL); if (state->TermiosError == NULL) { return NULL; - } + } Py_INCREF(state->TermiosError); PyModule_AddObject(m, "error", state->TermiosError); - - while (constant->name != NULL) { - PyModule_AddIntConstant(m, constant->name, constant->value); - ++constant; - } - return m; -} + + while (constant->name != NULL) { + PyModule_AddIntConstant(m, constant->name, constant->value); + ++constant; + } + return m; +} diff --git a/contrib/tools/python3/src/Modules/testcapi_long.h b/contrib/tools/python3/src/Modules/testcapi_long.h index 6bddad7bb5d..b060079bf8b 100644 --- a/contrib/tools/python3/src/Modules/testcapi_long.h +++ b/contrib/tools/python3/src/Modules/testcapi_long.h @@ -1,207 +1,207 @@ -/* Poor-man's template. Macros used: - TESTNAME name of the test (like test_long_api_inner) - TYPENAME the signed type (like long) - F_S_TO_PY convert signed to pylong; TYPENAME -> PyObject* - F_PY_TO_S convert pylong to signed; PyObject* -> TYPENAME - F_U_TO_PY convert unsigned to pylong; unsigned TYPENAME -> PyObject* - F_PY_TO_U convert pylong to unsigned; PyObject* -> unsigned TYPENAME -*/ - -static PyObject * -TESTNAME(PyObject *error(const char*)) -{ - const int NBITS = sizeof(TYPENAME) * 8; - unsigned TYPENAME base; - PyObject *pyresult; - int i; - - /* Note: This test lets PyObjects leak if an error is raised. Since - an error should never be raised, leaks are impossible . */ - - /* Test native -> PyLong -> native roundtrip identity. - * Generate all powers of 2, and test them and their negations, - * plus the numbers +-1 off from them. - */ - base = 1; - for (i = 0; - i < NBITS + 1; /* on last, base overflows to 0 */ - ++i, base <<= 1) - { - int j; - for (j = 0; j < 6; ++j) { - TYPENAME in, out; - unsigned TYPENAME uin, uout; - - /* For 0, 1, 2 use base; for 3, 4, 5 use -base */ - uin = j < 3 ? base : 0U - base; - - /* For 0 & 3, subtract 1. - * For 1 & 4, leave alone. - * For 2 & 5, add 1. - */ - uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1); - - pyresult = F_U_TO_PY(uin); - if (pyresult == NULL) - return error( - "unsigned unexpected null result"); - - uout = F_PY_TO_U(pyresult); - if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred()) - return error( - "unsigned unexpected -1 result"); - if (uout != uin) - return error( - "unsigned output != input"); - UNBIND(pyresult); - - in = (TYPENAME)uin; - pyresult = F_S_TO_PY(in); - if (pyresult == NULL) - return error( - "signed unexpected null result"); - - out = F_PY_TO_S(pyresult); - if (out == (TYPENAME)-1 && PyErr_Occurred()) - return error( - "signed unexpected -1 result"); - if (out != in) - return error( - "signed output != input"); - UNBIND(pyresult); - } - } - - /* Overflow tests. The loop above ensured that all limit cases that - * should not overflow don't overflow, so all we need to do here is - * provoke one-over-the-limit cases (not exhaustive, but sharp). - */ - { - PyObject *one, *x, *y; - TYPENAME out; - unsigned TYPENAME uout; - - one = PyLong_FromLong(1); - if (one == NULL) - return error( - "unexpected NULL from PyLong_FromLong"); - - /* Unsigned complains about -1? */ - x = PyNumber_Negative(one); - if (x == NULL) - return error( - "unexpected NULL from PyNumber_Negative"); - - uout = F_PY_TO_U(x); - if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) - return error( - "PyLong_AsUnsignedXXX(-1) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return error( - "PyLong_AsUnsignedXXX(-1) raised " - "something other than OverflowError"); - PyErr_Clear(); - UNBIND(x); - - /* Unsigned complains about 2**NBITS? */ - y = PyLong_FromLong((long)NBITS); - if (y == NULL) - return error( - "unexpected NULL from PyLong_FromLong"); - - x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */ - UNBIND(y); - if (x == NULL) - return error( - "unexpected NULL from PyNumber_Lshift"); - - uout = F_PY_TO_U(x); - if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) - return error( - "PyLong_AsUnsignedXXX(2**NBITS) didn't " - "complain"); - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return error( - "PyLong_AsUnsignedXXX(2**NBITS) raised " - "something other than OverflowError"); - PyErr_Clear(); - - /* Signed complains about 2**(NBITS-1)? - x still has 2**NBITS. */ - y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */ - UNBIND(x); - if (y == NULL) - return error( - "unexpected NULL from PyNumber_Rshift"); - - out = F_PY_TO_S(y); - if (out != (TYPENAME)-1 || !PyErr_Occurred()) - return error( - "PyLong_AsXXX(2**(NBITS-1)) didn't " - "complain"); - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return error( - "PyLong_AsXXX(2**(NBITS-1)) raised " - "something other than OverflowError"); - PyErr_Clear(); - - /* Signed complains about -2**(NBITS-1)-1?; - y still has 2**(NBITS-1). */ - x = PyNumber_Negative(y); /* -(2**(NBITS-1)) */ - UNBIND(y); - if (x == NULL) - return error( - "unexpected NULL from PyNumber_Negative"); - - y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */ - UNBIND(x); - if (y == NULL) - return error( - "unexpected NULL from PyNumber_Subtract"); - - out = F_PY_TO_S(y); - if (out != (TYPENAME)-1 || !PyErr_Occurred()) - return error( - "PyLong_AsXXX(-2**(NBITS-1)-1) didn't " - "complain"); - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return error( - "PyLong_AsXXX(-2**(NBITS-1)-1) raised " - "something other than OverflowError"); - PyErr_Clear(); - UNBIND(y); - - Py_XDECREF(x); - Py_XDECREF(y); - Py_DECREF(one); - } - - /* Test F_PY_TO_{S,U} on non-pylong input. This should raise a TypeError. */ - { - TYPENAME out; - unsigned TYPENAME uout; - - Py_INCREF(Py_None); - - out = F_PY_TO_S(Py_None); - if (out != (TYPENAME)-1 || !PyErr_Occurred()) - return error("PyLong_AsXXX(None) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return error("PyLong_AsXXX(None) raised " - "something other than TypeError"); - PyErr_Clear(); - - uout = F_PY_TO_U(Py_None); - if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) - return error("PyLong_AsXXX(None) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return error("PyLong_AsXXX(None) raised " - "something other than TypeError"); - PyErr_Clear(); - - Py_DECREF(Py_None); - } - - Py_INCREF(Py_None); - return Py_None; -} +/* Poor-man's template. Macros used: + TESTNAME name of the test (like test_long_api_inner) + TYPENAME the signed type (like long) + F_S_TO_PY convert signed to pylong; TYPENAME -> PyObject* + F_PY_TO_S convert pylong to signed; PyObject* -> TYPENAME + F_U_TO_PY convert unsigned to pylong; unsigned TYPENAME -> PyObject* + F_PY_TO_U convert pylong to unsigned; PyObject* -> unsigned TYPENAME +*/ + +static PyObject * +TESTNAME(PyObject *error(const char*)) +{ + const int NBITS = sizeof(TYPENAME) * 8; + unsigned TYPENAME base; + PyObject *pyresult; + int i; + + /* Note: This test lets PyObjects leak if an error is raised. Since + an error should never be raised, leaks are impossible . */ + + /* Test native -> PyLong -> native roundtrip identity. + * Generate all powers of 2, and test them and their negations, + * plus the numbers +-1 off from them. + */ + base = 1; + for (i = 0; + i < NBITS + 1; /* on last, base overflows to 0 */ + ++i, base <<= 1) + { + int j; + for (j = 0; j < 6; ++j) { + TYPENAME in, out; + unsigned TYPENAME uin, uout; + + /* For 0, 1, 2 use base; for 3, 4, 5 use -base */ + uin = j < 3 ? base : 0U - base; + + /* For 0 & 3, subtract 1. + * For 1 & 4, leave alone. + * For 2 & 5, add 1. + */ + uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1); + + pyresult = F_U_TO_PY(uin); + if (pyresult == NULL) + return error( + "unsigned unexpected null result"); + + uout = F_PY_TO_U(pyresult); + if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred()) + return error( + "unsigned unexpected -1 result"); + if (uout != uin) + return error( + "unsigned output != input"); + UNBIND(pyresult); + + in = (TYPENAME)uin; + pyresult = F_S_TO_PY(in); + if (pyresult == NULL) + return error( + "signed unexpected null result"); + + out = F_PY_TO_S(pyresult); + if (out == (TYPENAME)-1 && PyErr_Occurred()) + return error( + "signed unexpected -1 result"); + if (out != in) + return error( + "signed output != input"); + UNBIND(pyresult); + } + } + + /* Overflow tests. The loop above ensured that all limit cases that + * should not overflow don't overflow, so all we need to do here is + * provoke one-over-the-limit cases (not exhaustive, but sharp). + */ + { + PyObject *one, *x, *y; + TYPENAME out; + unsigned TYPENAME uout; + + one = PyLong_FromLong(1); + if (one == NULL) + return error( + "unexpected NULL from PyLong_FromLong"); + + /* Unsigned complains about -1? */ + x = PyNumber_Negative(one); + if (x == NULL) + return error( + "unexpected NULL from PyNumber_Negative"); + + uout = F_PY_TO_U(x); + if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) + return error( + "PyLong_AsUnsignedXXX(-1) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return error( + "PyLong_AsUnsignedXXX(-1) raised " + "something other than OverflowError"); + PyErr_Clear(); + UNBIND(x); + + /* Unsigned complains about 2**NBITS? */ + y = PyLong_FromLong((long)NBITS); + if (y == NULL) + return error( + "unexpected NULL from PyLong_FromLong"); + + x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */ + UNBIND(y); + if (x == NULL) + return error( + "unexpected NULL from PyNumber_Lshift"); + + uout = F_PY_TO_U(x); + if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) + return error( + "PyLong_AsUnsignedXXX(2**NBITS) didn't " + "complain"); + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return error( + "PyLong_AsUnsignedXXX(2**NBITS) raised " + "something other than OverflowError"); + PyErr_Clear(); + + /* Signed complains about 2**(NBITS-1)? + x still has 2**NBITS. */ + y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */ + UNBIND(x); + if (y == NULL) + return error( + "unexpected NULL from PyNumber_Rshift"); + + out = F_PY_TO_S(y); + if (out != (TYPENAME)-1 || !PyErr_Occurred()) + return error( + "PyLong_AsXXX(2**(NBITS-1)) didn't " + "complain"); + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return error( + "PyLong_AsXXX(2**(NBITS-1)) raised " + "something other than OverflowError"); + PyErr_Clear(); + + /* Signed complains about -2**(NBITS-1)-1?; + y still has 2**(NBITS-1). */ + x = PyNumber_Negative(y); /* -(2**(NBITS-1)) */ + UNBIND(y); + if (x == NULL) + return error( + "unexpected NULL from PyNumber_Negative"); + + y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */ + UNBIND(x); + if (y == NULL) + return error( + "unexpected NULL from PyNumber_Subtract"); + + out = F_PY_TO_S(y); + if (out != (TYPENAME)-1 || !PyErr_Occurred()) + return error( + "PyLong_AsXXX(-2**(NBITS-1)-1) didn't " + "complain"); + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return error( + "PyLong_AsXXX(-2**(NBITS-1)-1) raised " + "something other than OverflowError"); + PyErr_Clear(); + UNBIND(y); + + Py_XDECREF(x); + Py_XDECREF(y); + Py_DECREF(one); + } + + /* Test F_PY_TO_{S,U} on non-pylong input. This should raise a TypeError. */ + { + TYPENAME out; + unsigned TYPENAME uout; + + Py_INCREF(Py_None); + + out = F_PY_TO_S(Py_None); + if (out != (TYPENAME)-1 || !PyErr_Occurred()) + return error("PyLong_AsXXX(None) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return error("PyLong_AsXXX(None) raised " + "something other than TypeError"); + PyErr_Clear(); + + uout = F_PY_TO_U(Py_None); + if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred()) + return error("PyLong_AsXXX(None) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return error("PyLong_AsXXX(None) raised " + "something other than TypeError"); + PyErr_Clear(); + + Py_DECREF(Py_None); + } + + Py_INCREF(Py_None); + return Py_None; +} diff --git a/contrib/tools/python3/src/Modules/timemodule.c b/contrib/tools/python3/src/Modules/timemodule.c index df59f2aac5a..624597f12b2 100644 --- a/contrib/tools/python3/src/Modules/timemodule.c +++ b/contrib/tools/python3/src/Modules/timemodule.c @@ -1,56 +1,56 @@ -/* Time module */ - -#include "Python.h" - -#include - -#ifdef HAVE_SYS_TIMES_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#if defined(HAVE_SYS_RESOURCE_H) -#include -#endif - -#ifdef QUICKWIN -#include -#endif - -#if defined(HAVE_PTHREAD_H) -# include -#endif - +/* Time module */ + +#include "Python.h" + +#include + +#ifdef HAVE_SYS_TIMES_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#if defined(HAVE_SYS_RESOURCE_H) +#include +#endif + +#ifdef QUICKWIN +#include +#endif + +#if defined(HAVE_PTHREAD_H) +# include +#endif + #if defined(_AIX) # include #endif -#if defined(__WATCOMC__) && !defined(__QNX__) +#if defined(__WATCOMC__) && !defined(__QNX__) # include -#else +#else # ifdef MS_WINDOWS # define WIN32_LEAN_AND_MEAN # include # endif /* MS_WINDOWS */ -#endif /* !__WATCOMC__ || __QNX__ */ - -#ifdef _Py_MEMORY_SANITIZER -# include -#endif - -#ifdef _MSC_VER -#define _Py_timezone _timezone -#define _Py_daylight _daylight -#define _Py_tzname _tzname -#else -#define _Py_timezone timezone -#define _Py_daylight daylight -#define _Py_tzname tzname -#endif - +#endif /* !__WATCOMC__ || __QNX__ */ + +#ifdef _Py_MEMORY_SANITIZER +# include +#endif + +#ifdef _MSC_VER +#define _Py_timezone _timezone +#define _Py_daylight _daylight +#define _Py_tzname _tzname +#else +#define _Py_timezone timezone +#define _Py_daylight daylight +#define _Py_tzname tzname +#endif + #if defined(__APPLE__ ) && defined(__has_builtin) # if __has_builtin(__builtin_available) # define HAVE_CLOCK_GETTIME_RUNTIME __builtin_available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) @@ -60,104 +60,104 @@ # define HAVE_CLOCK_GETTIME_RUNTIME 1 #endif -#define SEC_TO_NS (1000 * 1000 * 1000) - -/* Forward declarations */ -static int pysleep(_PyTime_t); - - -static PyObject* -_PyFloat_FromPyTime(_PyTime_t t) -{ - double d = _PyTime_AsSecondsDouble(t); - return PyFloat_FromDouble(d); -} - - -static PyObject * -time_time(PyObject *self, PyObject *unused) -{ - _PyTime_t t = _PyTime_GetSystemClock(); - return _PyFloat_FromPyTime(t); -} - - -PyDoc_STRVAR(time_doc, -"time() -> floating point number\n\ -\n\ -Return the current time in seconds since the Epoch.\n\ -Fractions of a second may be present if the system clock provides them."); - -static PyObject * -time_time_ns(PyObject *self, PyObject *unused) -{ - _PyTime_t t = _PyTime_GetSystemClock(); - return _PyTime_AsNanosecondsObject(t); -} - -PyDoc_STRVAR(time_ns_doc, -"time_ns() -> int\n\ -\n\ -Return the current time in nanoseconds since the Epoch."); - -#if defined(HAVE_CLOCK) - -#ifndef CLOCKS_PER_SEC -# ifdef CLK_TCK -# define CLOCKS_PER_SEC CLK_TCK -# else -# define CLOCKS_PER_SEC 1000000 -# endif -#endif - -static int -_PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) -{ - static int initialized = 0; - clock_t ticks; - - if (!initialized) { - initialized = 1; - - /* must sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC) - above cannot overflow */ - if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) { - PyErr_SetString(PyExc_OverflowError, - "CLOCKS_PER_SEC is too large"); - return -1; - } - } - - if (info) { - info->implementation = "clock()"; - info->resolution = 1.0 / (double)CLOCKS_PER_SEC; - info->monotonic = 1; - info->adjustable = 0; - } - - ticks = clock(); - if (ticks == (clock_t)-1) { - PyErr_SetString(PyExc_RuntimeError, - "the processor time used is not available " - "or its value cannot be represented"); - return -1; - } - *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC); - return 0; -} -#endif /* HAVE_CLOCK */ - -static PyObject* -perf_counter(_Py_clock_info_t *info) -{ - _PyTime_t t; - if (_PyTime_GetPerfCounterWithInfo(&t, info) < 0) { - return NULL; - } - return _PyFloat_FromPyTime(t); -} - -#ifdef HAVE_CLOCK_GETTIME +#define SEC_TO_NS (1000 * 1000 * 1000) + +/* Forward declarations */ +static int pysleep(_PyTime_t); + + +static PyObject* +_PyFloat_FromPyTime(_PyTime_t t) +{ + double d = _PyTime_AsSecondsDouble(t); + return PyFloat_FromDouble(d); +} + + +static PyObject * +time_time(PyObject *self, PyObject *unused) +{ + _PyTime_t t = _PyTime_GetSystemClock(); + return _PyFloat_FromPyTime(t); +} + + +PyDoc_STRVAR(time_doc, +"time() -> floating point number\n\ +\n\ +Return the current time in seconds since the Epoch.\n\ +Fractions of a second may be present if the system clock provides them."); + +static PyObject * +time_time_ns(PyObject *self, PyObject *unused) +{ + _PyTime_t t = _PyTime_GetSystemClock(); + return _PyTime_AsNanosecondsObject(t); +} + +PyDoc_STRVAR(time_ns_doc, +"time_ns() -> int\n\ +\n\ +Return the current time in nanoseconds since the Epoch."); + +#if defined(HAVE_CLOCK) + +#ifndef CLOCKS_PER_SEC +# ifdef CLK_TCK +# define CLOCKS_PER_SEC CLK_TCK +# else +# define CLOCKS_PER_SEC 1000000 +# endif +#endif + +static int +_PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +{ + static int initialized = 0; + clock_t ticks; + + if (!initialized) { + initialized = 1; + + /* must sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC) + above cannot overflow */ + if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) { + PyErr_SetString(PyExc_OverflowError, + "CLOCKS_PER_SEC is too large"); + return -1; + } + } + + if (info) { + info->implementation = "clock()"; + info->resolution = 1.0 / (double)CLOCKS_PER_SEC; + info->monotonic = 1; + info->adjustable = 0; + } + + ticks = clock(); + if (ticks == (clock_t)-1) { + PyErr_SetString(PyExc_RuntimeError, + "the processor time used is not available " + "or its value cannot be represented"); + return -1; + } + *tp = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC); + return 0; +} +#endif /* HAVE_CLOCK */ + +static PyObject* +perf_counter(_Py_clock_info_t *info) +{ + _PyTime_t t; + if (_PyTime_GetPerfCounterWithInfo(&t, info) < 0) { + return NULL; + } + return _PyFloat_FromPyTime(t); +} + +#ifdef HAVE_CLOCK_GETTIME #ifdef __APPLE__ /* @@ -168,417 +168,417 @@ perf_counter(_Py_clock_info_t *info) #pragma clang diagnostic ignored "-Wunguarded-availability" #endif -static PyObject * -time_clock_gettime(PyObject *self, PyObject *args) -{ - int ret; - struct timespec tp; - +static PyObject * +time_clock_gettime(PyObject *self, PyObject *args) +{ + int ret; + struct timespec tp; + #if defined(_AIX) && (SIZEOF_LONG == 8) long clk_id; if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) { #else int clk_id; - if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { -#endif - return NULL; - } - - ret = clock_gettime((clockid_t)clk_id, &tp); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); -} - -PyDoc_STRVAR(clock_gettime_doc, -"clock_gettime(clk_id) -> float\n\ -\n\ -Return the time of the specified clock clk_id."); - -static PyObject * -time_clock_gettime_ns(PyObject *self, PyObject *args) -{ - int ret; - int clk_id; - struct timespec ts; - _PyTime_t t; - - if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { - return NULL; - } - - ret = clock_gettime((clockid_t)clk_id, &ts); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - if (_PyTime_FromTimespec(&t, &ts) < 0) { - return NULL; - } - return _PyTime_AsNanosecondsObject(t); -} - -PyDoc_STRVAR(clock_gettime_ns_doc, -"clock_gettime_ns(clk_id) -> int\n\ -\n\ -Return the time of the specified clock clk_id as nanoseconds."); -#endif /* HAVE_CLOCK_GETTIME */ - -#ifdef HAVE_CLOCK_SETTIME -static PyObject * -time_clock_settime(PyObject *self, PyObject *args) -{ - int clk_id; - PyObject *obj; - _PyTime_t t; - struct timespec tp; - int ret; - - if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) - return NULL; - - if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0) - return NULL; - - if (_PyTime_AsTimespec(t, &tp) == -1) - return NULL; - - ret = clock_settime((clockid_t)clk_id, &tp); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(clock_settime_doc, -"clock_settime(clk_id, time)\n\ -\n\ -Set the time of the specified clock clk_id."); - -static PyObject * -time_clock_settime_ns(PyObject *self, PyObject *args) -{ - int clk_id; - PyObject *obj; - _PyTime_t t; - struct timespec ts; - int ret; - - if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) { - return NULL; - } - - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - if (_PyTime_AsTimespec(t, &ts) == -1) { - return NULL; - } - - ret = clock_settime((clockid_t)clk_id, &ts); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(clock_settime_ns_doc, -"clock_settime_ns(clk_id, time)\n\ -\n\ -Set the time of the specified clock clk_id with nanoseconds."); -#endif /* HAVE_CLOCK_SETTIME */ - -#ifdef HAVE_CLOCK_GETRES -static PyObject * -time_clock_getres(PyObject *self, PyObject *args) -{ - int ret; - int clk_id; - struct timespec tp; - - if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id)) - return NULL; - - ret = clock_getres((clockid_t)clk_id, &tp); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); -} - -PyDoc_STRVAR(clock_getres_doc, -"clock_getres(clk_id) -> floating point number\n\ -\n\ -Return the resolution (precision) of the specified clock clk_id."); + if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { +#endif + return NULL; + } + + ret = clock_gettime((clockid_t)clk_id, &tp); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); +} + +PyDoc_STRVAR(clock_gettime_doc, +"clock_gettime(clk_id) -> float\n\ +\n\ +Return the time of the specified clock clk_id."); + +static PyObject * +time_clock_gettime_ns(PyObject *self, PyObject *args) +{ + int ret; + int clk_id; + struct timespec ts; + _PyTime_t t; + + if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { + return NULL; + } + + ret = clock_gettime((clockid_t)clk_id, &ts); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (_PyTime_FromTimespec(&t, &ts) < 0) { + return NULL; + } + return _PyTime_AsNanosecondsObject(t); +} + +PyDoc_STRVAR(clock_gettime_ns_doc, +"clock_gettime_ns(clk_id) -> int\n\ +\n\ +Return the time of the specified clock clk_id as nanoseconds."); +#endif /* HAVE_CLOCK_GETTIME */ + +#ifdef HAVE_CLOCK_SETTIME +static PyObject * +time_clock_settime(PyObject *self, PyObject *args) +{ + int clk_id; + PyObject *obj; + _PyTime_t t; + struct timespec tp; + int ret; + + if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) + return NULL; + + if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0) + return NULL; + + if (_PyTime_AsTimespec(t, &tp) == -1) + return NULL; + + ret = clock_settime((clockid_t)clk_id, &tp); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(clock_settime_doc, +"clock_settime(clk_id, time)\n\ +\n\ +Set the time of the specified clock clk_id."); + +static PyObject * +time_clock_settime_ns(PyObject *self, PyObject *args) +{ + int clk_id; + PyObject *obj; + _PyTime_t t; + struct timespec ts; + int ret; + + if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) { + return NULL; + } + + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + if (_PyTime_AsTimespec(t, &ts) == -1) { + return NULL; + } + + ret = clock_settime((clockid_t)clk_id, &ts); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(clock_settime_ns_doc, +"clock_settime_ns(clk_id, time)\n\ +\n\ +Set the time of the specified clock clk_id with nanoseconds."); +#endif /* HAVE_CLOCK_SETTIME */ + +#ifdef HAVE_CLOCK_GETRES +static PyObject * +time_clock_getres(PyObject *self, PyObject *args) +{ + int ret; + int clk_id; + struct timespec tp; + + if (!PyArg_ParseTuple(args, "i:clock_getres", &clk_id)) + return NULL; + + ret = clock_getres((clockid_t)clk_id, &tp); + if (ret != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); +} + +PyDoc_STRVAR(clock_getres_doc, +"clock_getres(clk_id) -> floating point number\n\ +\n\ +Return the resolution (precision) of the specified clock clk_id."); #ifdef __APPLE__ #pragma clang diagnostic pop #endif -#endif /* HAVE_CLOCK_GETRES */ - -#ifdef HAVE_PTHREAD_GETCPUCLOCKID -static PyObject * -time_pthread_getcpuclockid(PyObject *self, PyObject *args) -{ - unsigned long thread_id; - int err; - clockid_t clk_id; - if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) { - return NULL; - } - err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id); - if (err) { - errno = err; - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } -#ifdef _Py_MEMORY_SANITIZER - __msan_unpoison(&clk_id, sizeof(clk_id)); -#endif - return PyLong_FromLong(clk_id); -} - -PyDoc_STRVAR(pthread_getcpuclockid_doc, -"pthread_getcpuclockid(thread_id) -> int\n\ -\n\ -Return the clk_id of a thread's CPU time clock."); -#endif /* HAVE_PTHREAD_GETCPUCLOCKID */ - -static PyObject * -time_sleep(PyObject *self, PyObject *obj) -{ - _PyTime_t secs; - if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_TIMEOUT)) - return NULL; - if (secs < 0) { - PyErr_SetString(PyExc_ValueError, - "sleep length must be non-negative"); - return NULL; - } - if (pysleep(secs) != 0) - return NULL; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(sleep_doc, -"sleep(seconds)\n\ -\n\ -Delay execution for a given number of seconds. The argument may be\n\ -a floating point number for subsecond precision."); - -static PyStructSequence_Field struct_time_type_fields[] = { - {"tm_year", "year, for example, 1993"}, - {"tm_mon", "month of year, range [1, 12]"}, - {"tm_mday", "day of month, range [1, 31]"}, - {"tm_hour", "hours, range [0, 23]"}, - {"tm_min", "minutes, range [0, 59]"}, - {"tm_sec", "seconds, range [0, 61])"}, - {"tm_wday", "day of week, range [0, 6], Monday is 0"}, - {"tm_yday", "day of year, range [1, 366]"}, - {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"}, - {"tm_zone", "abbreviation of timezone name"}, - {"tm_gmtoff", "offset from UTC in seconds"}, - {0} -}; - -static PyStructSequence_Desc struct_time_type_desc = { - "time.struct_time", - "The time value as returned by gmtime(), localtime(), and strptime(), and\n" - " accepted by asctime(), mktime() and strftime(). May be considered as a\n" - " sequence of 9 integers.\n\n" - " Note that several fields' values are not the same as those defined by\n" - " the C language standard for struct tm. For example, the value of the\n" - " field tm_year is the actual year, not year - 1900. See individual\n" - " fields' descriptions for details.", - struct_time_type_fields, - 9, -}; - -static int initialized; -static PyTypeObject StructTimeType; - - -static PyObject * -tmtotuple(struct tm *p -#ifndef HAVE_STRUCT_TM_TM_ZONE - , const char *zone, time_t gmtoff -#endif -) -{ - PyObject *v = PyStructSequence_New(&StructTimeType); - if (v == NULL) - return NULL; - -#define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) - - SET(0, p->tm_year + 1900); - SET(1, p->tm_mon + 1); /* Want January == 1 */ - SET(2, p->tm_mday); - SET(3, p->tm_hour); - SET(4, p->tm_min); - SET(5, p->tm_sec); - SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */ - SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */ - SET(8, p->tm_isdst); -#ifdef HAVE_STRUCT_TM_TM_ZONE - PyStructSequence_SET_ITEM(v, 9, - PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape")); - SET(10, p->tm_gmtoff); -#else - PyStructSequence_SET_ITEM(v, 9, - PyUnicode_DecodeLocale(zone, "surrogateescape")); - PyStructSequence_SET_ITEM(v, 10, _PyLong_FromTime_t(gmtoff)); -#endif /* HAVE_STRUCT_TM_TM_ZONE */ -#undef SET - if (PyErr_Occurred()) { - Py_XDECREF(v); - return NULL; - } - - return v; -} - -/* Parse arg tuple that can contain an optional float-or-None value; - format needs to be "|O:name". - Returns non-zero on success (parallels PyArg_ParseTuple). -*/ -static int -parse_time_t_args(PyObject *args, const char *format, time_t *pwhen) -{ - PyObject *ot = NULL; - time_t whent; - - if (!PyArg_ParseTuple(args, format, &ot)) - return 0; - if (ot == NULL || ot == Py_None) { - whent = time(NULL); - } - else { - if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1) - return 0; - } - *pwhen = whent; - return 1; -} - -static PyObject * -time_gmtime(PyObject *self, PyObject *args) -{ - time_t when; - struct tm buf; - - if (!parse_time_t_args(args, "|O:gmtime", &when)) - return NULL; - - errno = 0; - if (_PyTime_gmtime(when, &buf) != 0) - return NULL; -#ifdef HAVE_STRUCT_TM_TM_ZONE - return tmtotuple(&buf); -#else - return tmtotuple(&buf, "UTC", 0); -#endif -} - -#ifndef HAVE_TIMEGM -static time_t -timegm(struct tm *p) -{ - /* XXX: the following implementation will not work for tm_year < 1970. - but it is likely that platforms that don't have timegm do not support - negative timestamps anyways. */ - return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 + - (p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 - - ((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400; -} -#endif - -PyDoc_STRVAR(gmtime_doc, -"gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\ - tm_sec, tm_wday, tm_yday, tm_isdst)\n\ -\n\ -Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\ -GMT). When 'seconds' is not passed in, convert the current time instead.\n\ -\n\ -If the platform supports the tm_gmtoff and tm_zone, they are available as\n\ -attributes only."); - -static PyObject * -time_localtime(PyObject *self, PyObject *args) -{ - time_t when; - struct tm buf; - - if (!parse_time_t_args(args, "|O:localtime", &when)) - return NULL; - if (_PyTime_localtime(when, &buf) != 0) - return NULL; -#ifdef HAVE_STRUCT_TM_TM_ZONE - return tmtotuple(&buf); -#else - { - struct tm local = buf; - char zone[100]; - time_t gmtoff; - strftime(zone, sizeof(zone), "%Z", &buf); - gmtoff = timegm(&buf) - when; - return tmtotuple(&local, zone, gmtoff); - } -#endif -} - +#endif /* HAVE_CLOCK_GETRES */ + +#ifdef HAVE_PTHREAD_GETCPUCLOCKID +static PyObject * +time_pthread_getcpuclockid(PyObject *self, PyObject *args) +{ + unsigned long thread_id; + int err; + clockid_t clk_id; + if (!PyArg_ParseTuple(args, "k:pthread_getcpuclockid", &thread_id)) { + return NULL; + } + err = pthread_getcpuclockid((pthread_t)thread_id, &clk_id); + if (err) { + errno = err; + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } +#ifdef _Py_MEMORY_SANITIZER + __msan_unpoison(&clk_id, sizeof(clk_id)); +#endif + return PyLong_FromLong(clk_id); +} + +PyDoc_STRVAR(pthread_getcpuclockid_doc, +"pthread_getcpuclockid(thread_id) -> int\n\ +\n\ +Return the clk_id of a thread's CPU time clock."); +#endif /* HAVE_PTHREAD_GETCPUCLOCKID */ + +static PyObject * +time_sleep(PyObject *self, PyObject *obj) +{ + _PyTime_t secs; + if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_TIMEOUT)) + return NULL; + if (secs < 0) { + PyErr_SetString(PyExc_ValueError, + "sleep length must be non-negative"); + return NULL; + } + if (pysleep(secs) != 0) + return NULL; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(sleep_doc, +"sleep(seconds)\n\ +\n\ +Delay execution for a given number of seconds. The argument may be\n\ +a floating point number for subsecond precision."); + +static PyStructSequence_Field struct_time_type_fields[] = { + {"tm_year", "year, for example, 1993"}, + {"tm_mon", "month of year, range [1, 12]"}, + {"tm_mday", "day of month, range [1, 31]"}, + {"tm_hour", "hours, range [0, 23]"}, + {"tm_min", "minutes, range [0, 59]"}, + {"tm_sec", "seconds, range [0, 61])"}, + {"tm_wday", "day of week, range [0, 6], Monday is 0"}, + {"tm_yday", "day of year, range [1, 366]"}, + {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"}, + {"tm_zone", "abbreviation of timezone name"}, + {"tm_gmtoff", "offset from UTC in seconds"}, + {0} +}; + +static PyStructSequence_Desc struct_time_type_desc = { + "time.struct_time", + "The time value as returned by gmtime(), localtime(), and strptime(), and\n" + " accepted by asctime(), mktime() and strftime(). May be considered as a\n" + " sequence of 9 integers.\n\n" + " Note that several fields' values are not the same as those defined by\n" + " the C language standard for struct tm. For example, the value of the\n" + " field tm_year is the actual year, not year - 1900. See individual\n" + " fields' descriptions for details.", + struct_time_type_fields, + 9, +}; + +static int initialized; +static PyTypeObject StructTimeType; + + +static PyObject * +tmtotuple(struct tm *p +#ifndef HAVE_STRUCT_TM_TM_ZONE + , const char *zone, time_t gmtoff +#endif +) +{ + PyObject *v = PyStructSequence_New(&StructTimeType); + if (v == NULL) + return NULL; + +#define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) + + SET(0, p->tm_year + 1900); + SET(1, p->tm_mon + 1); /* Want January == 1 */ + SET(2, p->tm_mday); + SET(3, p->tm_hour); + SET(4, p->tm_min); + SET(5, p->tm_sec); + SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */ + SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */ + SET(8, p->tm_isdst); +#ifdef HAVE_STRUCT_TM_TM_ZONE + PyStructSequence_SET_ITEM(v, 9, + PyUnicode_DecodeLocale(p->tm_zone, "surrogateescape")); + SET(10, p->tm_gmtoff); +#else + PyStructSequence_SET_ITEM(v, 9, + PyUnicode_DecodeLocale(zone, "surrogateescape")); + PyStructSequence_SET_ITEM(v, 10, _PyLong_FromTime_t(gmtoff)); +#endif /* HAVE_STRUCT_TM_TM_ZONE */ +#undef SET + if (PyErr_Occurred()) { + Py_XDECREF(v); + return NULL; + } + + return v; +} + +/* Parse arg tuple that can contain an optional float-or-None value; + format needs to be "|O:name". + Returns non-zero on success (parallels PyArg_ParseTuple). +*/ +static int +parse_time_t_args(PyObject *args, const char *format, time_t *pwhen) +{ + PyObject *ot = NULL; + time_t whent; + + if (!PyArg_ParseTuple(args, format, &ot)) + return 0; + if (ot == NULL || ot == Py_None) { + whent = time(NULL); + } + else { + if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1) + return 0; + } + *pwhen = whent; + return 1; +} + +static PyObject * +time_gmtime(PyObject *self, PyObject *args) +{ + time_t when; + struct tm buf; + + if (!parse_time_t_args(args, "|O:gmtime", &when)) + return NULL; + + errno = 0; + if (_PyTime_gmtime(when, &buf) != 0) + return NULL; +#ifdef HAVE_STRUCT_TM_TM_ZONE + return tmtotuple(&buf); +#else + return tmtotuple(&buf, "UTC", 0); +#endif +} + +#ifndef HAVE_TIMEGM +static time_t +timegm(struct tm *p) +{ + /* XXX: the following implementation will not work for tm_year < 1970. + but it is likely that platforms that don't have timegm do not support + negative timestamps anyways. */ + return p->tm_sec + p->tm_min*60 + p->tm_hour*3600 + p->tm_yday*86400 + + (p->tm_year-70)*31536000 + ((p->tm_year-69)/4)*86400 - + ((p->tm_year-1)/100)*86400 + ((p->tm_year+299)/400)*86400; +} +#endif + +PyDoc_STRVAR(gmtime_doc, +"gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min,\n\ + tm_sec, tm_wday, tm_yday, tm_isdst)\n\ +\n\ +Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\ +GMT). When 'seconds' is not passed in, convert the current time instead.\n\ +\n\ +If the platform supports the tm_gmtoff and tm_zone, they are available as\n\ +attributes only."); + +static PyObject * +time_localtime(PyObject *self, PyObject *args) +{ + time_t when; + struct tm buf; + + if (!parse_time_t_args(args, "|O:localtime", &when)) + return NULL; + if (_PyTime_localtime(when, &buf) != 0) + return NULL; +#ifdef HAVE_STRUCT_TM_TM_ZONE + return tmtotuple(&buf); +#else + { + struct tm local = buf; + char zone[100]; + time_t gmtoff; + strftime(zone, sizeof(zone), "%Z", &buf); + gmtoff = timegm(&buf) - when; + return tmtotuple(&local, zone, gmtoff); + } +#endif +} + #if defined(__linux__) && !defined(__GLIBC__) static const char *utc_string = NULL; #endif -PyDoc_STRVAR(localtime_doc, -"localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\ - tm_sec,tm_wday,tm_yday,tm_isdst)\n\ -\n\ -Convert seconds since the Epoch to a time tuple expressing local time.\n\ -When 'seconds' is not passed in, convert the current time instead."); - -/* Convert 9-item tuple to tm structure. Return 1 on success, set - * an exception and return 0 on error. - */ -static int -gettmarg(PyObject *args, struct tm *p, const char *format) -{ - int y; - - memset((void *) p, '\0', sizeof(struct tm)); - - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "Tuple or struct_time argument required"); - return 0; - } - - if (!PyArg_ParseTuple(args, format, - &y, &p->tm_mon, &p->tm_mday, - &p->tm_hour, &p->tm_min, &p->tm_sec, - &p->tm_wday, &p->tm_yday, &p->tm_isdst)) - return 0; - - if (y < INT_MIN + 1900) { - PyErr_SetString(PyExc_OverflowError, "year out of range"); - return 0; - } - - p->tm_year = y - 1900; - p->tm_mon--; - p->tm_wday = (p->tm_wday + 1) % 7; - p->tm_yday--; -#ifdef HAVE_STRUCT_TM_TM_ZONE +PyDoc_STRVAR(localtime_doc, +"localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n\ + tm_sec,tm_wday,tm_yday,tm_isdst)\n\ +\n\ +Convert seconds since the Epoch to a time tuple expressing local time.\n\ +When 'seconds' is not passed in, convert the current time instead."); + +/* Convert 9-item tuple to tm structure. Return 1 on success, set + * an exception and return 0 on error. + */ +static int +gettmarg(PyObject *args, struct tm *p, const char *format) +{ + int y; + + memset((void *) p, '\0', sizeof(struct tm)); + + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, + "Tuple or struct_time argument required"); + return 0; + } + + if (!PyArg_ParseTuple(args, format, + &y, &p->tm_mon, &p->tm_mday, + &p->tm_hour, &p->tm_min, &p->tm_sec, + &p->tm_wday, &p->tm_yday, &p->tm_isdst)) + return 0; + + if (y < INT_MIN + 1900) { + PyErr_SetString(PyExc_OverflowError, "year out of range"); + return 0; + } + + p->tm_year = y - 1900; + p->tm_mon--; + p->tm_wday = (p->tm_wday + 1) % 7; + p->tm_yday--; +#ifdef HAVE_STRUCT_TM_TM_ZONE if (Py_IS_TYPE(args, &StructTimeType)) { - PyObject *item; + PyObject *item; item = PyStructSequence_GET_ITEM(args, 9); if (item != Py_None) { p->tm_zone = (char *)PyUnicode_AsUTF8(item); @@ -606,389 +606,389 @@ gettmarg(PyObject *args, struct tm *p, const char *format) if (PyErr_Occurred()) return 0; } - } -#endif /* HAVE_STRUCT_TM_TM_ZONE */ - return 1; -} - -/* Check values of the struct tm fields before it is passed to strftime() and - * asctime(). Return 1 if all values are valid, otherwise set an exception - * and returns 0. - */ -static int -checktm(struct tm* buf) -{ - /* Checks added to make sure strftime() and asctime() does not crash Python by - indexing blindly into some array for a textual representation - by some bad index (fixes bug #897625 and #6608). - - Also support values of zero from Python code for arguments in which - that is out of range by forcing that value to the lowest value that - is valid (fixed bug #1520914). - - Valid ranges based on what is allowed in struct tm: - - - tm_year: [0, max(int)] (1) - - tm_mon: [0, 11] (2) - - tm_mday: [1, 31] - - tm_hour: [0, 23] - - tm_min: [0, 59] - - tm_sec: [0, 60] - - tm_wday: [0, 6] (1) - - tm_yday: [0, 365] (2) - - tm_isdst: [-max(int), max(int)] - - (1) gettmarg() handles bounds-checking. - (2) Python's acceptable range is one greater than the range in C, - thus need to check against automatic decrement by gettmarg(). - */ - if (buf->tm_mon == -1) - buf->tm_mon = 0; - else if (buf->tm_mon < 0 || buf->tm_mon > 11) { - PyErr_SetString(PyExc_ValueError, "month out of range"); - return 0; - } - if (buf->tm_mday == 0) - buf->tm_mday = 1; - else if (buf->tm_mday < 0 || buf->tm_mday > 31) { - PyErr_SetString(PyExc_ValueError, "day of month out of range"); - return 0; - } - if (buf->tm_hour < 0 || buf->tm_hour > 23) { - PyErr_SetString(PyExc_ValueError, "hour out of range"); - return 0; - } - if (buf->tm_min < 0 || buf->tm_min > 59) { - PyErr_SetString(PyExc_ValueError, "minute out of range"); - return 0; - } - if (buf->tm_sec < 0 || buf->tm_sec > 61) { - PyErr_SetString(PyExc_ValueError, "seconds out of range"); - return 0; - } - /* tm_wday does not need checking of its upper-bound since taking - ``% 7`` in gettmarg() automatically restricts the range. */ - if (buf->tm_wday < 0) { - PyErr_SetString(PyExc_ValueError, "day of week out of range"); - return 0; - } - if (buf->tm_yday == -1) - buf->tm_yday = 0; - else if (buf->tm_yday < 0 || buf->tm_yday > 365) { - PyErr_SetString(PyExc_ValueError, "day of year out of range"); - return 0; - } - return 1; -} - -#ifdef MS_WINDOWS - /* wcsftime() doesn't format correctly time zones, see issue #10653 */ -# undef HAVE_WCSFTIME -#endif -#define STRFTIME_FORMAT_CODES \ -"Commonly used format codes:\n\ -\n\ -%Y Year with century as a decimal number.\n\ -%m Month as a decimal number [01,12].\n\ -%d Day of the month as a decimal number [01,31].\n\ -%H Hour (24-hour clock) as a decimal number [00,23].\n\ -%M Minute as a decimal number [00,59].\n\ -%S Second as a decimal number [00,61].\n\ -%z Time zone offset from UTC.\n\ -%a Locale's abbreviated weekday name.\n\ -%A Locale's full weekday name.\n\ -%b Locale's abbreviated month name.\n\ -%B Locale's full month name.\n\ -%c Locale's appropriate date and time representation.\n\ -%I Hour (12-hour clock) as a decimal number [01,12].\n\ -%p Locale's equivalent of either AM or PM.\n\ -\n\ -Other codes may be available on your platform. See documentation for\n\ -the C library strftime function.\n" - -#ifdef HAVE_STRFTIME -#ifdef HAVE_WCSFTIME -#define time_char wchar_t -#define format_time wcsftime -#define time_strlen wcslen -#else -#define time_char char -#define format_time strftime -#define time_strlen strlen -#endif - -static PyObject * -time_strftime(PyObject *self, PyObject *args) -{ - PyObject *tup = NULL; - struct tm buf; - const time_char *fmt; -#ifdef HAVE_WCSFTIME - wchar_t *format; -#else - PyObject *format; -#endif - PyObject *format_arg; - size_t fmtlen, buflen; - time_char *outbuf = NULL; - size_t i; - PyObject *ret = NULL; - - memset((void *) &buf, '\0', sizeof(buf)); - - /* Will always expect a unicode string to be passed as format. - Given that there's no str type anymore in py3k this seems safe. - */ - if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup)) - return NULL; - - if (tup == NULL) { - time_t tt = time(NULL); - if (_PyTime_localtime(tt, &buf) != 0) - return NULL; - } - else if (!gettmarg(tup, &buf, - "iiiiiiiii;strftime(): illegal time tuple argument") || - !checktm(&buf)) - { - return NULL; - } - + } +#endif /* HAVE_STRUCT_TM_TM_ZONE */ + return 1; +} + +/* Check values of the struct tm fields before it is passed to strftime() and + * asctime(). Return 1 if all values are valid, otherwise set an exception + * and returns 0. + */ +static int +checktm(struct tm* buf) +{ + /* Checks added to make sure strftime() and asctime() does not crash Python by + indexing blindly into some array for a textual representation + by some bad index (fixes bug #897625 and #6608). + + Also support values of zero from Python code for arguments in which + that is out of range by forcing that value to the lowest value that + is valid (fixed bug #1520914). + + Valid ranges based on what is allowed in struct tm: + + - tm_year: [0, max(int)] (1) + - tm_mon: [0, 11] (2) + - tm_mday: [1, 31] + - tm_hour: [0, 23] + - tm_min: [0, 59] + - tm_sec: [0, 60] + - tm_wday: [0, 6] (1) + - tm_yday: [0, 365] (2) + - tm_isdst: [-max(int), max(int)] + + (1) gettmarg() handles bounds-checking. + (2) Python's acceptable range is one greater than the range in C, + thus need to check against automatic decrement by gettmarg(). + */ + if (buf->tm_mon == -1) + buf->tm_mon = 0; + else if (buf->tm_mon < 0 || buf->tm_mon > 11) { + PyErr_SetString(PyExc_ValueError, "month out of range"); + return 0; + } + if (buf->tm_mday == 0) + buf->tm_mday = 1; + else if (buf->tm_mday < 0 || buf->tm_mday > 31) { + PyErr_SetString(PyExc_ValueError, "day of month out of range"); + return 0; + } + if (buf->tm_hour < 0 || buf->tm_hour > 23) { + PyErr_SetString(PyExc_ValueError, "hour out of range"); + return 0; + } + if (buf->tm_min < 0 || buf->tm_min > 59) { + PyErr_SetString(PyExc_ValueError, "minute out of range"); + return 0; + } + if (buf->tm_sec < 0 || buf->tm_sec > 61) { + PyErr_SetString(PyExc_ValueError, "seconds out of range"); + return 0; + } + /* tm_wday does not need checking of its upper-bound since taking + ``% 7`` in gettmarg() automatically restricts the range. */ + if (buf->tm_wday < 0) { + PyErr_SetString(PyExc_ValueError, "day of week out of range"); + return 0; + } + if (buf->tm_yday == -1) + buf->tm_yday = 0; + else if (buf->tm_yday < 0 || buf->tm_yday > 365) { + PyErr_SetString(PyExc_ValueError, "day of year out of range"); + return 0; + } + return 1; +} + +#ifdef MS_WINDOWS + /* wcsftime() doesn't format correctly time zones, see issue #10653 */ +# undef HAVE_WCSFTIME +#endif +#define STRFTIME_FORMAT_CODES \ +"Commonly used format codes:\n\ +\n\ +%Y Year with century as a decimal number.\n\ +%m Month as a decimal number [01,12].\n\ +%d Day of the month as a decimal number [01,31].\n\ +%H Hour (24-hour clock) as a decimal number [00,23].\n\ +%M Minute as a decimal number [00,59].\n\ +%S Second as a decimal number [00,61].\n\ +%z Time zone offset from UTC.\n\ +%a Locale's abbreviated weekday name.\n\ +%A Locale's full weekday name.\n\ +%b Locale's abbreviated month name.\n\ +%B Locale's full month name.\n\ +%c Locale's appropriate date and time representation.\n\ +%I Hour (12-hour clock) as a decimal number [01,12].\n\ +%p Locale's equivalent of either AM or PM.\n\ +\n\ +Other codes may be available on your platform. See documentation for\n\ +the C library strftime function.\n" + +#ifdef HAVE_STRFTIME +#ifdef HAVE_WCSFTIME +#define time_char wchar_t +#define format_time wcsftime +#define time_strlen wcslen +#else +#define time_char char +#define format_time strftime +#define time_strlen strlen +#endif + +static PyObject * +time_strftime(PyObject *self, PyObject *args) +{ + PyObject *tup = NULL; + struct tm buf; + const time_char *fmt; +#ifdef HAVE_WCSFTIME + wchar_t *format; +#else + PyObject *format; +#endif + PyObject *format_arg; + size_t fmtlen, buflen; + time_char *outbuf = NULL; + size_t i; + PyObject *ret = NULL; + + memset((void *) &buf, '\0', sizeof(buf)); + + /* Will always expect a unicode string to be passed as format. + Given that there's no str type anymore in py3k this seems safe. + */ + if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup)) + return NULL; + + if (tup == NULL) { + time_t tt = time(NULL); + if (_PyTime_localtime(tt, &buf) != 0) + return NULL; + } + else if (!gettmarg(tup, &buf, + "iiiiiiiii;strftime(): illegal time tuple argument") || + !checktm(&buf)) + { + return NULL; + } + #if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__) - if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) { - PyErr_SetString(PyExc_ValueError, - "strftime() requires year in [1; 9999]"); - return NULL; - } -#endif - - /* Normalize tm_isdst just in case someone foolishly implements %Z - based on the assumption that tm_isdst falls within the range of - [-1, 1] */ - if (buf.tm_isdst < -1) - buf.tm_isdst = -1; - else if (buf.tm_isdst > 1) - buf.tm_isdst = 1; - -#ifdef HAVE_WCSFTIME - format = PyUnicode_AsWideCharString(format_arg, NULL); - if (format == NULL) - return NULL; - fmt = format; -#else - /* Convert the unicode string to an ascii one */ - format = PyUnicode_EncodeLocale(format_arg, "surrogateescape"); - if (format == NULL) - return NULL; - fmt = PyBytes_AS_STRING(format); -#endif - -#if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) - /* check that the format string contains only valid directives */ - for (outbuf = strchr(fmt, '%'); - outbuf != NULL; - outbuf = strchr(outbuf+2, '%')) - { - if (outbuf[1] == '#') - ++outbuf; /* not documented by python, */ - if (outbuf[1] == '\0') - break; - if ((outbuf[1] == 'y') && buf.tm_year < 0) { - PyErr_SetString(PyExc_ValueError, - "format %y requires year >= 1900 on Windows"); - Py_DECREF(format); - return NULL; - } - } -#elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME) - for (outbuf = wcschr(fmt, '%'); - outbuf != NULL; - outbuf = wcschr(outbuf+2, '%')) - { - if (outbuf[1] == L'\0') - break; - /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0)) - returns "0/" instead of "99" */ - if (outbuf[1] == L'y' && buf.tm_year < 0) { - PyErr_SetString(PyExc_ValueError, - "format %y requires year >= 1900 on AIX"); - PyMem_Free(format); - return NULL; - } - } -#endif - - fmtlen = time_strlen(fmt); - - /* I hate these functions that presume you know how big the output - * will be ahead of time... - */ - for (i = 1024; ; i += i) { - outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char)); - if (outbuf == NULL) { - PyErr_NoMemory(); - break; - } -#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) - errno = 0; -#endif - _Py_BEGIN_SUPPRESS_IPH - buflen = format_time(outbuf, i, fmt, &buf); - _Py_END_SUPPRESS_IPH -#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) - /* VisualStudio .NET 2005 does this properly */ - if (buflen == 0 && errno == EINVAL) { - PyErr_SetString(PyExc_ValueError, "Invalid format string"); - PyMem_Free(outbuf); - break; - } -#endif - if (buflen > 0 || i >= 256 * fmtlen) { - /* If the buffer is 256 times as long as the format, - it's probably not failing for lack of room! - More likely, the format yields an empty result, - e.g. an empty format, or %Z when the timezone - is unknown. */ -#ifdef HAVE_WCSFTIME - ret = PyUnicode_FromWideChar(outbuf, buflen); -#else - ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen, "surrogateescape"); -#endif - PyMem_Free(outbuf); - break; - } - PyMem_Free(outbuf); - } -#ifdef HAVE_WCSFTIME - PyMem_Free(format); -#else - Py_DECREF(format); -#endif - return ret; -} - -#undef time_char -#undef format_time -PyDoc_STRVAR(strftime_doc, -"strftime(format[, tuple]) -> string\n\ -\n\ -Convert a time tuple to a string according to a format specification.\n\ -See the library reference manual for formatting codes. When the time tuple\n\ -is not present, current time as returned by localtime() is used.\n\ -\n" STRFTIME_FORMAT_CODES); -#endif /* HAVE_STRFTIME */ - -static PyObject * -time_strptime(PyObject *self, PyObject *args) -{ - PyObject *module, *func, *result; - _Py_IDENTIFIER(_strptime_time); - - module = PyImport_ImportModuleNoBlock("_strptime"); - if (!module) - return NULL; - - func = _PyObject_GetAttrId(module, &PyId__strptime_time); - Py_DECREF(module); - if (!func) { - return NULL; - } - - result = PyObject_Call(func, args, NULL); - Py_DECREF(func); - return result; -} - - -PyDoc_STRVAR(strptime_doc, -"strptime(string, format) -> struct_time\n\ -\n\ -Parse a string to a time tuple according to a format specification.\n\ -See the library reference manual for formatting codes (same as\n\ -strftime()).\n\ -\n" STRFTIME_FORMAT_CODES); - -static PyObject * -_asctime(struct tm *timeptr) -{ - /* Inspired by Open Group reference implementation available at - * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */ - static const char wday_name[7][4] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - static const char mon_name[12][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - return PyUnicode_FromFormat( - "%s %s%3d %.2d:%.2d:%.2d %d", - wday_name[timeptr->tm_wday], - mon_name[timeptr->tm_mon], - timeptr->tm_mday, timeptr->tm_hour, - timeptr->tm_min, timeptr->tm_sec, - 1900 + timeptr->tm_year); -} - -static PyObject * -time_asctime(PyObject *self, PyObject *args) -{ - PyObject *tup = NULL; - struct tm buf; - - if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup)) - return NULL; - if (tup == NULL) { - time_t tt = time(NULL); - if (_PyTime_localtime(tt, &buf) != 0) - return NULL; - } - else if (!gettmarg(tup, &buf, - "iiiiiiiii;asctime(): illegal time tuple argument") || - !checktm(&buf)) - { - return NULL; - } - return _asctime(&buf); -} - -PyDoc_STRVAR(asctime_doc, -"asctime([tuple]) -> string\n\ -\n\ -Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\ -When the time tuple is not present, current time as returned by localtime()\n\ -is used."); - -static PyObject * -time_ctime(PyObject *self, PyObject *args) -{ - time_t tt; - struct tm buf; - if (!parse_time_t_args(args, "|O:ctime", &tt)) - return NULL; - if (_PyTime_localtime(tt, &buf) != 0) - return NULL; - return _asctime(&buf); -} - -PyDoc_STRVAR(ctime_doc, -"ctime(seconds) -> string\n\ -\n\ -Convert a time in seconds since the Epoch to a string in local time.\n\ -This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\ -not present, current time as returned by localtime() is used."); - -#ifdef HAVE_MKTIME -static PyObject * + if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) { + PyErr_SetString(PyExc_ValueError, + "strftime() requires year in [1; 9999]"); + return NULL; + } +#endif + + /* Normalize tm_isdst just in case someone foolishly implements %Z + based on the assumption that tm_isdst falls within the range of + [-1, 1] */ + if (buf.tm_isdst < -1) + buf.tm_isdst = -1; + else if (buf.tm_isdst > 1) + buf.tm_isdst = 1; + +#ifdef HAVE_WCSFTIME + format = PyUnicode_AsWideCharString(format_arg, NULL); + if (format == NULL) + return NULL; + fmt = format; +#else + /* Convert the unicode string to an ascii one */ + format = PyUnicode_EncodeLocale(format_arg, "surrogateescape"); + if (format == NULL) + return NULL; + fmt = PyBytes_AS_STRING(format); +#endif + +#if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) + /* check that the format string contains only valid directives */ + for (outbuf = strchr(fmt, '%'); + outbuf != NULL; + outbuf = strchr(outbuf+2, '%')) + { + if (outbuf[1] == '#') + ++outbuf; /* not documented by python, */ + if (outbuf[1] == '\0') + break; + if ((outbuf[1] == 'y') && buf.tm_year < 0) { + PyErr_SetString(PyExc_ValueError, + "format %y requires year >= 1900 on Windows"); + Py_DECREF(format); + return NULL; + } + } +#elif (defined(_AIX) || (defined(__sun) && defined(__SVR4))) && defined(HAVE_WCSFTIME) + for (outbuf = wcschr(fmt, '%'); + outbuf != NULL; + outbuf = wcschr(outbuf+2, '%')) + { + if (outbuf[1] == L'\0') + break; + /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0)) + returns "0/" instead of "99" */ + if (outbuf[1] == L'y' && buf.tm_year < 0) { + PyErr_SetString(PyExc_ValueError, + "format %y requires year >= 1900 on AIX"); + PyMem_Free(format); + return NULL; + } + } +#endif + + fmtlen = time_strlen(fmt); + + /* I hate these functions that presume you know how big the output + * will be ahead of time... + */ + for (i = 1024; ; i += i) { + outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char)); + if (outbuf == NULL) { + PyErr_NoMemory(); + break; + } +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) + errno = 0; +#endif + _Py_BEGIN_SUPPRESS_IPH + buflen = format_time(outbuf, i, fmt, &buf); + _Py_END_SUPPRESS_IPH +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) + /* VisualStudio .NET 2005 does this properly */ + if (buflen == 0 && errno == EINVAL) { + PyErr_SetString(PyExc_ValueError, "Invalid format string"); + PyMem_Free(outbuf); + break; + } +#endif + if (buflen > 0 || i >= 256 * fmtlen) { + /* If the buffer is 256 times as long as the format, + it's probably not failing for lack of room! + More likely, the format yields an empty result, + e.g. an empty format, or %Z when the timezone + is unknown. */ +#ifdef HAVE_WCSFTIME + ret = PyUnicode_FromWideChar(outbuf, buflen); +#else + ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen, "surrogateescape"); +#endif + PyMem_Free(outbuf); + break; + } + PyMem_Free(outbuf); + } +#ifdef HAVE_WCSFTIME + PyMem_Free(format); +#else + Py_DECREF(format); +#endif + return ret; +} + +#undef time_char +#undef format_time +PyDoc_STRVAR(strftime_doc, +"strftime(format[, tuple]) -> string\n\ +\n\ +Convert a time tuple to a string according to a format specification.\n\ +See the library reference manual for formatting codes. When the time tuple\n\ +is not present, current time as returned by localtime() is used.\n\ +\n" STRFTIME_FORMAT_CODES); +#endif /* HAVE_STRFTIME */ + +static PyObject * +time_strptime(PyObject *self, PyObject *args) +{ + PyObject *module, *func, *result; + _Py_IDENTIFIER(_strptime_time); + + module = PyImport_ImportModuleNoBlock("_strptime"); + if (!module) + return NULL; + + func = _PyObject_GetAttrId(module, &PyId__strptime_time); + Py_DECREF(module); + if (!func) { + return NULL; + } + + result = PyObject_Call(func, args, NULL); + Py_DECREF(func); + return result; +} + + +PyDoc_STRVAR(strptime_doc, +"strptime(string, format) -> struct_time\n\ +\n\ +Parse a string to a time tuple according to a format specification.\n\ +See the library reference manual for formatting codes (same as\n\ +strftime()).\n\ +\n" STRFTIME_FORMAT_CODES); + +static PyObject * +_asctime(struct tm *timeptr) +{ + /* Inspired by Open Group reference implementation available at + * http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html */ + static const char wday_name[7][4] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static const char mon_name[12][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + return PyUnicode_FromFormat( + "%s %s%3d %.2d:%.2d:%.2d %d", + wday_name[timeptr->tm_wday], + mon_name[timeptr->tm_mon], + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec, + 1900 + timeptr->tm_year); +} + +static PyObject * +time_asctime(PyObject *self, PyObject *args) +{ + PyObject *tup = NULL; + struct tm buf; + + if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup)) + return NULL; + if (tup == NULL) { + time_t tt = time(NULL); + if (_PyTime_localtime(tt, &buf) != 0) + return NULL; + } + else if (!gettmarg(tup, &buf, + "iiiiiiiii;asctime(): illegal time tuple argument") || + !checktm(&buf)) + { + return NULL; + } + return _asctime(&buf); +} + +PyDoc_STRVAR(asctime_doc, +"asctime([tuple]) -> string\n\ +\n\ +Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.\n\ +When the time tuple is not present, current time as returned by localtime()\n\ +is used."); + +static PyObject * +time_ctime(PyObject *self, PyObject *args) +{ + time_t tt; + struct tm buf; + if (!parse_time_t_args(args, "|O:ctime", &tt)) + return NULL; + if (_PyTime_localtime(tt, &buf) != 0) + return NULL; + return _asctime(&buf); +} + +PyDoc_STRVAR(ctime_doc, +"ctime(seconds) -> string\n\ +\n\ +Convert a time in seconds since the Epoch to a string in local time.\n\ +This is equivalent to asctime(localtime(seconds)). When the time tuple is\n\ +not present, current time as returned by localtime() is used."); + +#ifdef HAVE_MKTIME +static PyObject * time_mktime(PyObject *self, PyObject *tm_tuple) -{ +{ struct tm tm; - time_t tt; + time_t tt; if (!gettmarg(tm_tuple, &tm, - "iiiiiiiii;mktime(): illegal time tuple argument")) - { - return NULL; - } + "iiiiiiiii;mktime(): illegal time tuple argument")) + { + return NULL; + } #if defined(_AIX) || (defined(__VXWORKS__) && !defined(_WRS_CONFIG_LP64)) /* bpo-19748: AIX mktime() valid range is 00:00:00 UTC, January 1, 1970 @@ -998,11 +998,11 @@ time_mktime(PyObject *self, PyObject *tm_tuple) /* bpo-19748: On AIX, mktime() does not report overflow error for timestamp < -2^31 or timestamp > 2**31-1. VxWorks has the same issue when working in 32 bit mode. */ - PyErr_SetString(PyExc_OverflowError, - "mktime argument out of range"); - return NULL; - } -#endif + PyErr_SetString(PyExc_OverflowError, + "mktime argument out of range"); + return NULL; + } +#endif #ifdef _AIX /* bpo-34373: AIX mktime() has an integer overflow for years in range @@ -1022,181 +1022,181 @@ time_mktime(PyObject *self, PyObject *tm_tuple) tm.tm_wday = -1; /* sentinel; original value ignored */ tt = mktime(&tm); - /* Return value of -1 does not necessarily mean an error, but tm_wday - * cannot remain set to -1 if mktime succeeded. */ - if (tt == (time_t)(-1) - /* Return value of -1 does not necessarily mean an error, but - * tm_wday cannot remain set to -1 if mktime succeeded. */ + /* Return value of -1 does not necessarily mean an error, but tm_wday + * cannot remain set to -1 if mktime succeeded. */ + if (tt == (time_t)(-1) + /* Return value of -1 does not necessarily mean an error, but + * tm_wday cannot remain set to -1 if mktime succeeded. */ && tm.tm_wday == -1) - { - PyErr_SetString(PyExc_OverflowError, - "mktime argument out of range"); - return NULL; - } + { + PyErr_SetString(PyExc_OverflowError, + "mktime argument out of range"); + return NULL; + } #ifdef _AIX if (delta_days != 0) { tm.tm_year = orig_tm_year; if (tm.tm_wday != -1) { tm.tm_wday = (tm.tm_wday + delta_days) % 7; - } - tt += delta_days * (24 * 3600); - } -#endif - - return PyFloat_FromDouble((double)tt); -} - -PyDoc_STRVAR(mktime_doc, -"mktime(tuple) -> floating point number\n\ -\n\ -Convert a time tuple in local time to seconds since the Epoch.\n\ -Note that mktime(gmtime(0)) will not generally return zero for most\n\ -time zones; instead the returned value will either be equal to that\n\ -of the timezone or altzone attributes on the time module."); -#endif /* HAVE_MKTIME */ - -#ifdef HAVE_WORKING_TZSET -static int init_timezone(PyObject *module); - -static PyObject * -time_tzset(PyObject *self, PyObject *unused) -{ - PyObject* m; - - m = PyImport_ImportModuleNoBlock("time"); - if (m == NULL) { - return NULL; - } - - tzset(); - - /* Reset timezone, altzone, daylight and tzname */ - if (init_timezone(m) < 0) { - return NULL; - } - Py_DECREF(m); - if (PyErr_Occurred()) - return NULL; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(tzset_doc, -"tzset()\n\ -\n\ -Initialize, or reinitialize, the local timezone to the value stored in\n\ -os.environ['TZ']. The TZ environment variable should be specified in\n\ -standard Unix timezone format as documented in the tzset man page\n\ -(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\ -fall back to UTC. If the TZ environment variable is not set, the local\n\ -timezone is set to the systems best guess of wallclock time.\n\ -Changing the TZ environment variable without calling tzset *may* change\n\ -the local timezone used by methods such as localtime, but this behaviour\n\ -should not be relied on."); -#endif /* HAVE_WORKING_TZSET */ - -static PyObject * -time_monotonic(PyObject *self, PyObject *unused) -{ - _PyTime_t t = _PyTime_GetMonotonicClock(); - return _PyFloat_FromPyTime(t); -} - -PyDoc_STRVAR(monotonic_doc, -"monotonic() -> float\n\ -\n\ -Monotonic clock, cannot go backward."); - -static PyObject * -time_monotonic_ns(PyObject *self, PyObject *unused) -{ - _PyTime_t t = _PyTime_GetMonotonicClock(); - return _PyTime_AsNanosecondsObject(t); -} - -PyDoc_STRVAR(monotonic_ns_doc, -"monotonic_ns() -> int\n\ -\n\ -Monotonic clock, cannot go backward, as nanoseconds."); - -static PyObject * -time_perf_counter(PyObject *self, PyObject *unused) -{ - return perf_counter(NULL); -} - -PyDoc_STRVAR(perf_counter_doc, -"perf_counter() -> float\n\ -\n\ -Performance counter for benchmarking."); - -static PyObject * -time_perf_counter_ns(PyObject *self, PyObject *unused) -{ - _PyTime_t t = _PyTime_GetPerfCounter(); - return _PyTime_AsNanosecondsObject(t); -} - -PyDoc_STRVAR(perf_counter_ns_doc, -"perf_counter_ns() -> int\n\ -\n\ -Performance counter for benchmarking as nanoseconds."); - -static int -_PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) -{ -#if defined(MS_WINDOWS) - HANDLE process; - FILETIME creation_time, exit_time, kernel_time, user_time; - ULARGE_INTEGER large; - _PyTime_t ktime, utime, t; - BOOL ok; - - process = GetCurrentProcess(); - ok = GetProcessTimes(process, &creation_time, &exit_time, - &kernel_time, &user_time); - if (!ok) { - PyErr_SetFromWindowsErr(0); - return -1; - } - - if (info) { - info->implementation = "GetProcessTimes()"; - info->resolution = 1e-7; - info->monotonic = 1; - info->adjustable = 0; + } + tt += delta_days * (24 * 3600); } +#endif - large.u.LowPart = kernel_time.dwLowDateTime; - large.u.HighPart = kernel_time.dwHighDateTime; - ktime = large.QuadPart; - - large.u.LowPart = user_time.dwLowDateTime; - large.u.HighPart = user_time.dwHighDateTime; - utime = large.QuadPart; - - /* ktime and utime have a resolution of 100 nanoseconds */ - t = _PyTime_FromNanoseconds((ktime + utime) * 100); - *tp = t; - return 0; -#else - - /* clock_gettime */ -#if defined(HAVE_CLOCK_GETTIME) \ - && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF)) - struct timespec ts; + return PyFloat_FromDouble((double)tt); +} + +PyDoc_STRVAR(mktime_doc, +"mktime(tuple) -> floating point number\n\ +\n\ +Convert a time tuple in local time to seconds since the Epoch.\n\ +Note that mktime(gmtime(0)) will not generally return zero for most\n\ +time zones; instead the returned value will either be equal to that\n\ +of the timezone or altzone attributes on the time module."); +#endif /* HAVE_MKTIME */ + +#ifdef HAVE_WORKING_TZSET +static int init_timezone(PyObject *module); + +static PyObject * +time_tzset(PyObject *self, PyObject *unused) +{ + PyObject* m; + + m = PyImport_ImportModuleNoBlock("time"); + if (m == NULL) { + return NULL; + } + + tzset(); + + /* Reset timezone, altzone, daylight and tzname */ + if (init_timezone(m) < 0) { + return NULL; + } + Py_DECREF(m); + if (PyErr_Occurred()) + return NULL; + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(tzset_doc, +"tzset()\n\ +\n\ +Initialize, or reinitialize, the local timezone to the value stored in\n\ +os.environ['TZ']. The TZ environment variable should be specified in\n\ +standard Unix timezone format as documented in the tzset man page\n\ +(eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\ +fall back to UTC. If the TZ environment variable is not set, the local\n\ +timezone is set to the systems best guess of wallclock time.\n\ +Changing the TZ environment variable without calling tzset *may* change\n\ +the local timezone used by methods such as localtime, but this behaviour\n\ +should not be relied on."); +#endif /* HAVE_WORKING_TZSET */ + +static PyObject * +time_monotonic(PyObject *self, PyObject *unused) +{ + _PyTime_t t = _PyTime_GetMonotonicClock(); + return _PyFloat_FromPyTime(t); +} + +PyDoc_STRVAR(monotonic_doc, +"monotonic() -> float\n\ +\n\ +Monotonic clock, cannot go backward."); + +static PyObject * +time_monotonic_ns(PyObject *self, PyObject *unused) +{ + _PyTime_t t = _PyTime_GetMonotonicClock(); + return _PyTime_AsNanosecondsObject(t); +} + +PyDoc_STRVAR(monotonic_ns_doc, +"monotonic_ns() -> int\n\ +\n\ +Monotonic clock, cannot go backward, as nanoseconds."); + +static PyObject * +time_perf_counter(PyObject *self, PyObject *unused) +{ + return perf_counter(NULL); +} + +PyDoc_STRVAR(perf_counter_doc, +"perf_counter() -> float\n\ +\n\ +Performance counter for benchmarking."); + +static PyObject * +time_perf_counter_ns(PyObject *self, PyObject *unused) +{ + _PyTime_t t = _PyTime_GetPerfCounter(); + return _PyTime_AsNanosecondsObject(t); +} + +PyDoc_STRVAR(perf_counter_ns_doc, +"perf_counter_ns() -> int\n\ +\n\ +Performance counter for benchmarking as nanoseconds."); + +static int +_PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +{ +#if defined(MS_WINDOWS) + HANDLE process; + FILETIME creation_time, exit_time, kernel_time, user_time; + ULARGE_INTEGER large; + _PyTime_t ktime, utime, t; + BOOL ok; + + process = GetCurrentProcess(); + ok = GetProcessTimes(process, &creation_time, &exit_time, + &kernel_time, &user_time); + if (!ok) { + PyErr_SetFromWindowsErr(0); + return -1; + } + + if (info) { + info->implementation = "GetProcessTimes()"; + info->resolution = 1e-7; + info->monotonic = 1; + info->adjustable = 0; + } + + large.u.LowPart = kernel_time.dwLowDateTime; + large.u.HighPart = kernel_time.dwHighDateTime; + ktime = large.QuadPart; + + large.u.LowPart = user_time.dwLowDateTime; + large.u.HighPart = user_time.dwHighDateTime; + utime = large.QuadPart; + + /* ktime and utime have a resolution of 100 nanoseconds */ + t = _PyTime_FromNanoseconds((ktime + utime) * 100); + *tp = t; + return 0; +#else + + /* clock_gettime */ +#if defined(HAVE_CLOCK_GETTIME) \ + && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF)) + struct timespec ts; if (HAVE_CLOCK_GETTIME_RUNTIME) { -#ifdef CLOCK_PROF +#ifdef CLOCK_PROF const clockid_t clk_id = CLOCK_PROF; const char *function = "clock_gettime(CLOCK_PROF)"; -#else +#else const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID; const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)"; -#endif - +#endif + if (clock_gettime(clk_id, &ts) == 0) { if (info) { struct timespec res; @@ -1211,170 +1211,170 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) } if (_PyTime_FromTimespec(tp, &ts) < 0) { - return -1; - } + return -1; + } return 0; - } - } -#endif - - /* getrusage(RUSAGE_SELF) */ -#if defined(HAVE_SYS_RESOURCE_H) - struct rusage ru; - - if (getrusage(RUSAGE_SELF, &ru) == 0) { - _PyTime_t utime, stime; - - if (info) { - info->implementation = "getrusage(RUSAGE_SELF)"; - info->monotonic = 1; - info->adjustable = 0; - info->resolution = 1e-6; - } - - if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) { - return -1; - } - if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) { - return -1; - } - + } + } +#endif + + /* getrusage(RUSAGE_SELF) */ +#if defined(HAVE_SYS_RESOURCE_H) + struct rusage ru; + + if (getrusage(RUSAGE_SELF, &ru) == 0) { + _PyTime_t utime, stime; + + if (info) { + info->implementation = "getrusage(RUSAGE_SELF)"; + info->monotonic = 1; + info->adjustable = 0; + info->resolution = 1e-6; + } + + if (_PyTime_FromTimeval(&utime, &ru.ru_utime) < 0) { + return -1; + } + if (_PyTime_FromTimeval(&stime, &ru.ru_stime) < 0) { + return -1; + } + _PyTime_t total = utime + stime; - *tp = total; - return 0; - } -#endif - - /* times() */ -#ifdef HAVE_TIMES - struct tms t; - - if (times(&t) != (clock_t)-1) { - static long ticks_per_second = -1; - - if (ticks_per_second == -1) { - long freq; -#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) - freq = sysconf(_SC_CLK_TCK); - if (freq < 1) { - freq = -1; - } -#elif defined(HZ) - freq = HZ; -#else - freq = 60; /* magic fallback value; may be bogus */ -#endif - - if (freq != -1) { - /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) - cannot overflow below */ -#if LONG_MAX > _PyTime_MAX / SEC_TO_NS - if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) { - PyErr_SetString(PyExc_OverflowError, - "_SC_CLK_TCK is too large"); - return -1; - } -#endif - - ticks_per_second = freq; - } - } - - if (ticks_per_second != -1) { - if (info) { - info->implementation = "times()"; - info->monotonic = 1; - info->adjustable = 0; - info->resolution = 1.0 / (double)ticks_per_second; - } - - _PyTime_t total; - total = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second); - total += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second); - *tp = total; - return 0; - } - } -#endif - - /* clock */ - /* Currently, Python 3 requires clock() to build: see issue #22624 */ - return _PyTime_GetClockWithInfo(tp, info); -#endif -} - -static PyObject * -time_process_time(PyObject *self, PyObject *unused) -{ - _PyTime_t t; - if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) { - return NULL; - } - return _PyFloat_FromPyTime(t); -} - -PyDoc_STRVAR(process_time_doc, -"process_time() -> float\n\ -\n\ -Process time for profiling: sum of the kernel and user-space CPU time."); - -static PyObject * -time_process_time_ns(PyObject *self, PyObject *unused) -{ - _PyTime_t t; - if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) { - return NULL; - } - return _PyTime_AsNanosecondsObject(t); -} - -PyDoc_STRVAR(process_time_ns_doc, -"process_time() -> int\n\ -\n\ -Process time for profiling as nanoseconds:\n\ -sum of the kernel and user-space CPU time."); - - -#if defined(MS_WINDOWS) -#define HAVE_THREAD_TIME -static int -_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) -{ - HANDLE thread; - FILETIME creation_time, exit_time, kernel_time, user_time; - ULARGE_INTEGER large; - _PyTime_t ktime, utime, t; - BOOL ok; - - thread = GetCurrentThread(); - ok = GetThreadTimes(thread, &creation_time, &exit_time, - &kernel_time, &user_time); - if (!ok) { - PyErr_SetFromWindowsErr(0); - return -1; - } - - if (info) { - info->implementation = "GetThreadTimes()"; - info->resolution = 1e-7; - info->monotonic = 1; - info->adjustable = 0; - } - - large.u.LowPart = kernel_time.dwLowDateTime; - large.u.HighPart = kernel_time.dwHighDateTime; - ktime = large.QuadPart; - - large.u.LowPart = user_time.dwLowDateTime; - large.u.HighPart = user_time.dwHighDateTime; - utime = large.QuadPart; - - /* ktime and utime have a resolution of 100 nanoseconds */ - t = _PyTime_FromNanoseconds((ktime + utime) * 100); - *tp = t; - return 0; -} - + *tp = total; + return 0; + } +#endif + + /* times() */ +#ifdef HAVE_TIMES + struct tms t; + + if (times(&t) != (clock_t)-1) { + static long ticks_per_second = -1; + + if (ticks_per_second == -1) { + long freq; +#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) + freq = sysconf(_SC_CLK_TCK); + if (freq < 1) { + freq = -1; + } +#elif defined(HZ) + freq = HZ; +#else + freq = 60; /* magic fallback value; may be bogus */ +#endif + + if (freq != -1) { + /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) + cannot overflow below */ +#if LONG_MAX > _PyTime_MAX / SEC_TO_NS + if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) { + PyErr_SetString(PyExc_OverflowError, + "_SC_CLK_TCK is too large"); + return -1; + } +#endif + + ticks_per_second = freq; + } + } + + if (ticks_per_second != -1) { + if (info) { + info->implementation = "times()"; + info->monotonic = 1; + info->adjustable = 0; + info->resolution = 1.0 / (double)ticks_per_second; + } + + _PyTime_t total; + total = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second); + total += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second); + *tp = total; + return 0; + } + } +#endif + + /* clock */ + /* Currently, Python 3 requires clock() to build: see issue #22624 */ + return _PyTime_GetClockWithInfo(tp, info); +#endif +} + +static PyObject * +time_process_time(PyObject *self, PyObject *unused) +{ + _PyTime_t t; + if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) { + return NULL; + } + return _PyFloat_FromPyTime(t); +} + +PyDoc_STRVAR(process_time_doc, +"process_time() -> float\n\ +\n\ +Process time for profiling: sum of the kernel and user-space CPU time."); + +static PyObject * +time_process_time_ns(PyObject *self, PyObject *unused) +{ + _PyTime_t t; + if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) { + return NULL; + } + return _PyTime_AsNanosecondsObject(t); +} + +PyDoc_STRVAR(process_time_ns_doc, +"process_time() -> int\n\ +\n\ +Process time for profiling as nanoseconds:\n\ +sum of the kernel and user-space CPU time."); + + +#if defined(MS_WINDOWS) +#define HAVE_THREAD_TIME +static int +_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +{ + HANDLE thread; + FILETIME creation_time, exit_time, kernel_time, user_time; + ULARGE_INTEGER large; + _PyTime_t ktime, utime, t; + BOOL ok; + + thread = GetCurrentThread(); + ok = GetThreadTimes(thread, &creation_time, &exit_time, + &kernel_time, &user_time); + if (!ok) { + PyErr_SetFromWindowsErr(0); + return -1; + } + + if (info) { + info->implementation = "GetThreadTimes()"; + info->resolution = 1e-7; + info->monotonic = 1; + info->adjustable = 0; + } + + large.u.LowPart = kernel_time.dwLowDateTime; + large.u.HighPart = kernel_time.dwHighDateTime; + ktime = large.QuadPart; + + large.u.LowPart = user_time.dwLowDateTime; + large.u.HighPart = user_time.dwHighDateTime; + utime = large.QuadPart; + + /* ktime and utime have a resolution of 100 nanoseconds */ + t = _PyTime_FromNanoseconds((ktime + utime) * 100); + *tp = t; + return 0; +} + #elif defined(_AIX) #define HAVE_THREAD_TIME static int @@ -1416,11 +1416,11 @@ _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) return 0; } -#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) -#define HAVE_THREAD_TIME +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) +#define HAVE_THREAD_TIME #if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability) -static int +static int _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) __attribute__((availability(macos, introduced=10.12))) __attribute__((availability(ios, introduced=10.0))) @@ -1429,36 +1429,36 @@ _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) #endif static int -_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) -{ - struct timespec ts; - const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID; - const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)"; - - if (clock_gettime(clk_id, &ts)) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - if (info) { - struct timespec res; - info->implementation = function; - info->monotonic = 1; - info->adjustable = 0; - if (clock_getres(clk_id, &res)) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - } - - if (_PyTime_FromTimespec(tp, &ts) < 0) { - return -1; - } - return 0; -} -#endif - -#ifdef HAVE_THREAD_TIME +_PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +{ + struct timespec ts; + const clockid_t clk_id = CLOCK_THREAD_CPUTIME_ID; + const char *function = "clock_gettime(CLOCK_THREAD_CPUTIME_ID)"; + + if (clock_gettime(clk_id, &ts)) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + if (info) { + struct timespec res; + info->implementation = function; + info->monotonic = 1; + info->adjustable = 0; + if (clock_getres(clk_id, &res)) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + } + + if (_PyTime_FromTimespec(tp, &ts) < 0) { + return -1; + } + return 0; +} +#endif + +#ifdef HAVE_THREAD_TIME #ifdef __APPLE__ /* * The clock_* functions will be removed from the module @@ -1468,90 +1468,90 @@ _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) #pragma clang diagnostic ignored "-Wunguarded-availability" #endif -static PyObject * -time_thread_time(PyObject *self, PyObject *unused) -{ - _PyTime_t t; - if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) { - return NULL; - } - return _PyFloat_FromPyTime(t); -} - -PyDoc_STRVAR(thread_time_doc, -"thread_time() -> float\n\ -\n\ -Thread time for profiling: sum of the kernel and user-space CPU time."); - -static PyObject * -time_thread_time_ns(PyObject *self, PyObject *unused) -{ - _PyTime_t t; - if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) { - return NULL; - } - return _PyTime_AsNanosecondsObject(t); -} - -PyDoc_STRVAR(thread_time_ns_doc, -"thread_time() -> int\n\ -\n\ -Thread time for profiling as nanoseconds:\n\ -sum of the kernel and user-space CPU time."); +static PyObject * +time_thread_time(PyObject *self, PyObject *unused) +{ + _PyTime_t t; + if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) { + return NULL; + } + return _PyFloat_FromPyTime(t); +} + +PyDoc_STRVAR(thread_time_doc, +"thread_time() -> float\n\ +\n\ +Thread time for profiling: sum of the kernel and user-space CPU time."); + +static PyObject * +time_thread_time_ns(PyObject *self, PyObject *unused) +{ + _PyTime_t t; + if (_PyTime_GetThreadTimeWithInfo(&t, NULL) < 0) { + return NULL; + } + return _PyTime_AsNanosecondsObject(t); +} + +PyDoc_STRVAR(thread_time_ns_doc, +"thread_time() -> int\n\ +\n\ +Thread time for profiling as nanoseconds:\n\ +sum of the kernel and user-space CPU time."); #ifdef __APPLE__ #pragma clang diagnostic pop -#endif - -#endif - - -static PyObject * -time_get_clock_info(PyObject *self, PyObject *args) -{ - char *name; - _Py_clock_info_t info; - PyObject *obj = NULL, *dict, *ns; - _PyTime_t t; - - if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) { - return NULL; - } - -#ifdef Py_DEBUG - info.implementation = NULL; - info.monotonic = -1; - info.adjustable = -1; - info.resolution = -1.0; -#else - info.implementation = ""; - info.monotonic = 0; - info.adjustable = 0; - info.resolution = 1.0; -#endif - - if (strcmp(name, "time") == 0) { - if (_PyTime_GetSystemClockWithInfo(&t, &info) < 0) { - return NULL; - } - } - else if (strcmp(name, "monotonic") == 0) { - if (_PyTime_GetMonotonicClockWithInfo(&t, &info) < 0) { - return NULL; - } - } - else if (strcmp(name, "perf_counter") == 0) { - if (_PyTime_GetPerfCounterWithInfo(&t, &info) < 0) { - return NULL; - } - } - else if (strcmp(name, "process_time") == 0) { - if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) { - return NULL; - } - } -#ifdef HAVE_THREAD_TIME - else if (strcmp(name, "thread_time") == 0) { +#endif + +#endif + + +static PyObject * +time_get_clock_info(PyObject *self, PyObject *args) +{ + char *name; + _Py_clock_info_t info; + PyObject *obj = NULL, *dict, *ns; + _PyTime_t t; + + if (!PyArg_ParseTuple(args, "s:get_clock_info", &name)) { + return NULL; + } + +#ifdef Py_DEBUG + info.implementation = NULL; + info.monotonic = -1; + info.adjustable = -1; + info.resolution = -1.0; +#else + info.implementation = ""; + info.monotonic = 0; + info.adjustable = 0; + info.resolution = 1.0; +#endif + + if (strcmp(name, "time") == 0) { + if (_PyTime_GetSystemClockWithInfo(&t, &info) < 0) { + return NULL; + } + } + else if (strcmp(name, "monotonic") == 0) { + if (_PyTime_GetMonotonicClockWithInfo(&t, &info) < 0) { + return NULL; + } + } + else if (strcmp(name, "perf_counter") == 0) { + if (_PyTime_GetPerfCounterWithInfo(&t, &info) < 0) { + return NULL; + } + } + else if (strcmp(name, "process_time") == 0) { + if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) { + return NULL; + } + } +#ifdef HAVE_THREAD_TIME + else if (strcmp(name, "thread_time") == 0) { #ifdef __APPLE__ if (HAVE_CLOCK_GETTIME_RUNTIME) { @@ -1562,131 +1562,131 @@ time_get_clock_info(PyObject *self, PyObject *args) #ifdef __APPLE__ } else { PyErr_SetString(PyExc_ValueError, "unknown clock"); - return NULL; - } -#endif - } -#endif - else { - PyErr_SetString(PyExc_ValueError, "unknown clock"); - return NULL; - } - - dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - - assert(info.implementation != NULL); - obj = PyUnicode_FromString(info.implementation); - if (obj == NULL) { - goto error; - } - if (PyDict_SetItemString(dict, "implementation", obj) == -1) { - goto error; - } - Py_CLEAR(obj); - - assert(info.monotonic != -1); - obj = PyBool_FromLong(info.monotonic); - if (obj == NULL) { - goto error; - } - if (PyDict_SetItemString(dict, "monotonic", obj) == -1) { - goto error; - } - Py_CLEAR(obj); - - assert(info.adjustable != -1); - obj = PyBool_FromLong(info.adjustable); - if (obj == NULL) { - goto error; - } - if (PyDict_SetItemString(dict, "adjustable", obj) == -1) { - goto error; - } - Py_CLEAR(obj); - - assert(info.resolution > 0.0); - assert(info.resolution <= 1.0); - obj = PyFloat_FromDouble(info.resolution); - if (obj == NULL) { - goto error; - } - if (PyDict_SetItemString(dict, "resolution", obj) == -1) { - goto error; - } - Py_CLEAR(obj); - - ns = _PyNamespace_New(dict); - Py_DECREF(dict); - return ns; - -error: - Py_DECREF(dict); - Py_XDECREF(obj); - return NULL; -} - -PyDoc_STRVAR(get_clock_info_doc, -"get_clock_info(name: str) -> dict\n\ -\n\ -Get information of the specified clock."); - + return NULL; + } +#endif + } +#endif + else { + PyErr_SetString(PyExc_ValueError, "unknown clock"); + return NULL; + } + + dict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + + assert(info.implementation != NULL); + obj = PyUnicode_FromString(info.implementation); + if (obj == NULL) { + goto error; + } + if (PyDict_SetItemString(dict, "implementation", obj) == -1) { + goto error; + } + Py_CLEAR(obj); + + assert(info.monotonic != -1); + obj = PyBool_FromLong(info.monotonic); + if (obj == NULL) { + goto error; + } + if (PyDict_SetItemString(dict, "monotonic", obj) == -1) { + goto error; + } + Py_CLEAR(obj); + + assert(info.adjustable != -1); + obj = PyBool_FromLong(info.adjustable); + if (obj == NULL) { + goto error; + } + if (PyDict_SetItemString(dict, "adjustable", obj) == -1) { + goto error; + } + Py_CLEAR(obj); + + assert(info.resolution > 0.0); + assert(info.resolution <= 1.0); + obj = PyFloat_FromDouble(info.resolution); + if (obj == NULL) { + goto error; + } + if (PyDict_SetItemString(dict, "resolution", obj) == -1) { + goto error; + } + Py_CLEAR(obj); + + ns = _PyNamespace_New(dict); + Py_DECREF(dict); + return ns; + +error: + Py_DECREF(dict); + Py_XDECREF(obj); + return NULL; +} + +PyDoc_STRVAR(get_clock_info_doc, +"get_clock_info(name: str) -> dict\n\ +\n\ +Get information of the specified clock."); + #ifndef HAVE_DECL_TZNAME -static void -get_zone(char *zone, int n, struct tm *p) -{ -#ifdef HAVE_STRUCT_TM_TM_ZONE - strncpy(zone, p->tm_zone ? p->tm_zone : " ", n); -#else - tzset(); - strftime(zone, n, "%Z", p); -#endif -} - -static time_t -get_gmtoff(time_t t, struct tm *p) -{ -#ifdef HAVE_STRUCT_TM_TM_ZONE - return p->tm_gmtoff; -#else - return timegm(p) - t; -#endif -} +static void +get_zone(char *zone, int n, struct tm *p) +{ +#ifdef HAVE_STRUCT_TM_TM_ZONE + strncpy(zone, p->tm_zone ? p->tm_zone : " ", n); +#else + tzset(); + strftime(zone, n, "%Z", p); +#endif +} + +static time_t +get_gmtoff(time_t t, struct tm *p) +{ +#ifdef HAVE_STRUCT_TM_TM_ZONE + return p->tm_gmtoff; +#else + return timegm(p) - t; +#endif +} #endif // !HAVE_DECL_TZNAME - -static int -init_timezone(PyObject *m) -{ - assert(!PyErr_Occurred()); - - /* This code moved from PyInit_time wholesale to allow calling it from - time_tzset. In the future, some parts of it can be moved back - (for platforms that don't HAVE_WORKING_TZSET, when we know what they - are), and the extraneous calls to tzset(3) should be removed. - I haven't done this yet, as I don't want to change this code as - little as possible when introducing the time.tzset and time.tzsetwall - methods. This should simply be a method of doing the following once, - at the top of this function and removing the call to tzset() from - time_tzset(): - - #ifdef HAVE_TZSET - tzset() - #endif - - And I'm lazy and hate C so nyer. - */ + +static int +init_timezone(PyObject *m) +{ + assert(!PyErr_Occurred()); + + /* This code moved from PyInit_time wholesale to allow calling it from + time_tzset. In the future, some parts of it can be moved back + (for platforms that don't HAVE_WORKING_TZSET, when we know what they + are), and the extraneous calls to tzset(3) should be removed. + I haven't done this yet, as I don't want to change this code as + little as possible when introducing the time.tzset and time.tzsetwall + methods. This should simply be a method of doing the following once, + at the top of this function and removing the call to tzset() from + time_tzset(): + + #ifdef HAVE_TZSET + tzset() + #endif + + And I'm lazy and hate C so nyer. + */ #ifdef HAVE_DECL_TZNAME - PyObject *otz0, *otz1; - tzset(); - PyModule_AddIntConstant(m, "timezone", _Py_timezone); -#ifdef HAVE_ALTZONE - PyModule_AddIntConstant(m, "altzone", altzone); -#else - PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600); -#endif - PyModule_AddIntConstant(m, "daylight", _Py_daylight); + PyObject *otz0, *otz1; + tzset(); + PyModule_AddIntConstant(m, "timezone", _Py_timezone); +#ifdef HAVE_ALTZONE + PyModule_AddIntConstant(m, "altzone", altzone); +#else + PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600); +#endif + PyModule_AddIntConstant(m, "daylight", _Py_daylight); #ifdef MS_WINDOWS TIME_ZONE_INFORMATION tzinfo = {0}; GetTimeZoneInformation(&tzinfo); @@ -1700,21 +1700,21 @@ init_timezone(PyObject *m) return -1; } #else - otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape"); - if (otz0 == NULL) { - return -1; - } - otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape"); - if (otz1 == NULL) { - Py_DECREF(otz0); - return -1; - } + otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape"); + if (otz0 == NULL) { + return -1; + } + otz1 = PyUnicode_DecodeLocale(_Py_tzname[1], "surrogateescape"); + if (otz1 == NULL) { + Py_DECREF(otz0); + return -1; + } #endif // MS_WINDOWS - PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1); - if (tzname_obj == NULL) { - return -1; - } - PyModule_AddObject(m, "tzname", tzname_obj); + PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1); + if (tzname_obj == NULL) { + return -1; + } + PyModule_AddObject(m, "tzname", tzname_obj); #else // !HAVE_DECL_TZNAME static const time_t YEAR = (365 * 24 + 6) * 3600; time_t t; @@ -1731,10 +1731,10 @@ init_timezone(PyObject *m) get_zone(julyname, 9, &p); julyzone_t = -get_gmtoff(t, &p); julyname[9] = '\0'; - + /* Sanity check, don't check for the validity of timezones. In practice, it should be more in range -12 hours .. +14 hours. */ -#define MAX_TIMEZONE (48 * 3600) +#define MAX_TIMEZONE (48 * 3600) if (janzone_t < -MAX_TIMEZONE || janzone_t > MAX_TIMEZONE || julyzone_t < -MAX_TIMEZONE || julyzone_t > MAX_TIMEZONE) { @@ -1743,7 +1743,7 @@ init_timezone(PyObject *m) } int janzone = (int)janzone_t; int julyzone = (int)julyzone_t; - + PyObject *tzname_obj; if (janzone < julyzone) { /* DST is reversed in the southern hemisphere */ @@ -1756,92 +1756,92 @@ init_timezone(PyObject *m) PyModule_AddIntConstant(m, "altzone", julyzone); PyModule_AddIntConstant(m, "daylight", janzone != julyzone); tzname_obj = Py_BuildValue("(zz)", janname, julyname); - } + } if (tzname_obj == NULL) { return -1; } PyModule_AddObject(m, "tzname", tzname_obj); #endif // !HAVE_DECL_TZNAME - - if (PyErr_Occurred()) { - return -1; - } - return 0; -} - - -static PyMethodDef time_methods[] = { - {"time", time_time, METH_NOARGS, time_doc}, - {"time_ns", time_time_ns, METH_NOARGS, time_ns_doc}, -#ifdef HAVE_CLOCK_GETTIME - {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc}, - {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc}, -#endif -#ifdef HAVE_CLOCK_SETTIME - {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc}, - {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc}, -#endif -#ifdef HAVE_CLOCK_GETRES - {"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc}, -#endif -#ifdef HAVE_PTHREAD_GETCPUCLOCKID - {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc}, -#endif - {"sleep", time_sleep, METH_O, sleep_doc}, - {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc}, - {"localtime", time_localtime, METH_VARARGS, localtime_doc}, - {"asctime", time_asctime, METH_VARARGS, asctime_doc}, - {"ctime", time_ctime, METH_VARARGS, ctime_doc}, -#ifdef HAVE_MKTIME - {"mktime", time_mktime, METH_O, mktime_doc}, -#endif -#ifdef HAVE_STRFTIME - {"strftime", time_strftime, METH_VARARGS, strftime_doc}, -#endif - {"strptime", time_strptime, METH_VARARGS, strptime_doc}, -#ifdef HAVE_WORKING_TZSET - {"tzset", time_tzset, METH_NOARGS, tzset_doc}, -#endif - {"monotonic", time_monotonic, METH_NOARGS, monotonic_doc}, - {"monotonic_ns", time_monotonic_ns, METH_NOARGS, monotonic_ns_doc}, - {"process_time", time_process_time, METH_NOARGS, process_time_doc}, - {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc}, -#ifdef HAVE_THREAD_TIME - {"thread_time", time_thread_time, METH_NOARGS, thread_time_doc}, - {"thread_time_ns", time_thread_time_ns, METH_NOARGS, thread_time_ns_doc}, -#endif - {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc}, - {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc}, - {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc}, - {NULL, NULL} /* sentinel */ -}; - - -PyDoc_STRVAR(module_doc, -"This module provides various functions to manipulate time values.\n\ -\n\ -There are two standard representations of time. One is the number\n\ -of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\ -or a floating point number (to represent fractions of seconds).\n\ -The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\ -The actual value can be retrieved by calling gmtime(0).\n\ -\n\ -The other representation is a tuple of 9 integers giving local time.\n\ -The tuple items are:\n\ - year (including century, e.g. 1998)\n\ - month (1-12)\n\ - day (1-31)\n\ - hours (0-23)\n\ - minutes (0-59)\n\ - seconds (0-59)\n\ - weekday (0-6, Monday is 0)\n\ - Julian day (day in the year, 1-366)\n\ - DST (Daylight Savings Time) flag (-1, 0 or 1)\n\ -If the DST flag is 0, the time is given in the regular time zone;\n\ -if it is 1, the time is given in the DST time zone;\n\ -if it is -1, mktime() should guess based on the date and time.\n"); - - + + if (PyErr_Occurred()) { + return -1; + } + return 0; +} + + +static PyMethodDef time_methods[] = { + {"time", time_time, METH_NOARGS, time_doc}, + {"time_ns", time_time_ns, METH_NOARGS, time_ns_doc}, +#ifdef HAVE_CLOCK_GETTIME + {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc}, + {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc}, +#endif +#ifdef HAVE_CLOCK_SETTIME + {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc}, + {"clock_settime_ns",time_clock_settime_ns, METH_VARARGS, clock_settime_ns_doc}, +#endif +#ifdef HAVE_CLOCK_GETRES + {"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc}, +#endif +#ifdef HAVE_PTHREAD_GETCPUCLOCKID + {"pthread_getcpuclockid", time_pthread_getcpuclockid, METH_VARARGS, pthread_getcpuclockid_doc}, +#endif + {"sleep", time_sleep, METH_O, sleep_doc}, + {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc}, + {"localtime", time_localtime, METH_VARARGS, localtime_doc}, + {"asctime", time_asctime, METH_VARARGS, asctime_doc}, + {"ctime", time_ctime, METH_VARARGS, ctime_doc}, +#ifdef HAVE_MKTIME + {"mktime", time_mktime, METH_O, mktime_doc}, +#endif +#ifdef HAVE_STRFTIME + {"strftime", time_strftime, METH_VARARGS, strftime_doc}, +#endif + {"strptime", time_strptime, METH_VARARGS, strptime_doc}, +#ifdef HAVE_WORKING_TZSET + {"tzset", time_tzset, METH_NOARGS, tzset_doc}, +#endif + {"monotonic", time_monotonic, METH_NOARGS, monotonic_doc}, + {"monotonic_ns", time_monotonic_ns, METH_NOARGS, monotonic_ns_doc}, + {"process_time", time_process_time, METH_NOARGS, process_time_doc}, + {"process_time_ns", time_process_time_ns, METH_NOARGS, process_time_ns_doc}, +#ifdef HAVE_THREAD_TIME + {"thread_time", time_thread_time, METH_NOARGS, thread_time_doc}, + {"thread_time_ns", time_thread_time_ns, METH_NOARGS, thread_time_ns_doc}, +#endif + {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc}, + {"perf_counter_ns", time_perf_counter_ns, METH_NOARGS, perf_counter_ns_doc}, + {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc}, + {NULL, NULL} /* sentinel */ +}; + + +PyDoc_STRVAR(module_doc, +"This module provides various functions to manipulate time values.\n\ +\n\ +There are two standard representations of time. One is the number\n\ +of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\ +or a floating point number (to represent fractions of seconds).\n\ +The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\ +The actual value can be retrieved by calling gmtime(0).\n\ +\n\ +The other representation is a tuple of 9 integers giving local time.\n\ +The tuple items are:\n\ + year (including century, e.g. 1998)\n\ + month (1-12)\n\ + day (1-31)\n\ + hours (0-23)\n\ + minutes (0-59)\n\ + seconds (0-59)\n\ + weekday (0-6, Monday is 0)\n\ + Julian day (day in the year, 1-366)\n\ + DST (Daylight Savings Time) flag (-1, 0 or 1)\n\ +If the DST flag is 0, the time is given in the regular time zone;\n\ +if it is 1, the time is given in the DST time zone;\n\ +if it is -1, mktime() should guess based on the date and time.\n"); + + static int time_exec(PyObject *module) { @@ -1853,7 +1853,7 @@ time_exec(PyObject *module) if (dct == NULL) { return -1; } - + if (PyDict_DelItemString(dct, "clock_gettime") == -1) { PyErr_Clear(); } @@ -1876,7 +1876,7 @@ time_exec(PyObject *module) /* pass: ^^^ cannot use '!' here */ } else { PyObject* dct = PyModule_GetDict(module); - + if (PyDict_DelItemString(dct, "thread_time") == -1) { PyErr_Clear(); } @@ -1885,69 +1885,69 @@ time_exec(PyObject *module) } } #endif - /* Set, or reset, module variables like time.timezone */ + /* Set, or reset, module variables like time.timezone */ if (init_timezone(module) < 0) { return -1; - } - -#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) + } + +#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) if (HAVE_CLOCK_GETTIME_RUNTIME) { - -#ifdef CLOCK_REALTIME + +#ifdef CLOCK_REALTIME if (PyModule_AddIntMacro(module, CLOCK_REALTIME) < 0) { return -1; } -#endif +#endif -#ifdef CLOCK_MONOTONIC +#ifdef CLOCK_MONOTONIC if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC) < 0) { return -1; } -#endif -#ifdef CLOCK_MONOTONIC_RAW +#endif +#ifdef CLOCK_MONOTONIC_RAW if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW) < 0) { return -1; } -#endif +#endif -#ifdef CLOCK_HIGHRES +#ifdef CLOCK_HIGHRES if (PyModule_AddIntMacro(module, CLOCK_HIGHRES) < 0) { return -1; } -#endif -#ifdef CLOCK_PROCESS_CPUTIME_ID +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID if (PyModule_AddIntMacro(module, CLOCK_PROCESS_CPUTIME_ID) < 0) { return -1; } -#endif +#endif -#ifdef CLOCK_THREAD_CPUTIME_ID +#ifdef CLOCK_THREAD_CPUTIME_ID if (PyModule_AddIntMacro(module, CLOCK_THREAD_CPUTIME_ID) < 0) { return -1; } -#endif -#ifdef CLOCK_PROF +#endif +#ifdef CLOCK_PROF if (PyModule_AddIntMacro(module, CLOCK_PROF) < 0) { return -1; } -#endif -#ifdef CLOCK_BOOTTIME +#endif +#ifdef CLOCK_BOOTTIME if (PyModule_AddIntMacro(module, CLOCK_BOOTTIME) < 0) { return -1; } -#endif +#endif #ifdef CLOCK_TAI if (PyModule_AddIntMacro(module, CLOCK_TAI) < 0) { return -1; } #endif -#ifdef CLOCK_UPTIME +#ifdef CLOCK_UPTIME if (PyModule_AddIntMacro(module, CLOCK_UPTIME) < 0) { return -1; } -#endif +#endif #ifdef CLOCK_UPTIME_RAW if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW) < 0) { @@ -1955,25 +1955,25 @@ time_exec(PyObject *module) } #endif } - -#endif /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */ - - if (!initialized) { - if (PyStructSequence_InitType2(&StructTimeType, + +#endif /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */ + + if (!initialized) { + if (PyStructSequence_InitType2(&StructTimeType, &struct_time_type_desc) < 0) { return -1; } - } + } if (PyModule_AddIntConstant(module, "_STRUCT_TM_ITEMS", 11)) { return -1; } - Py_INCREF(&StructTimeType); + Py_INCREF(&StructTimeType); if (PyModule_AddObject(module, "struct_time", (PyObject*) &StructTimeType)) { Py_DECREF(&StructTimeType); return -1; } - initialized = 1; - + initialized = 1; + #if defined(__linux__) && !defined(__GLIBC__) struct tm tm; const time_t zero = 0; @@ -1982,8 +1982,8 @@ time_exec(PyObject *module) #endif return 0; -} - +} + static struct PyModuleDef_Slot time_slots[] = { {Py_mod_exec, time_exec}, {0, NULL} @@ -2007,82 +2007,82 @@ PyInit_time(void) return PyModuleDef_Init(&timemodule); } -/* Implement pysleep() for various platforms. - When interrupted (or when another error occurs), return -1 and - set an exception; else return 0. */ - -static int -pysleep(_PyTime_t secs) -{ - _PyTime_t deadline, monotonic; -#ifndef MS_WINDOWS - struct timeval timeout; - int err = 0; -#else - _PyTime_t millisecs; - unsigned long ul_millis; - DWORD rc; - HANDLE hInterruptEvent; -#endif - - deadline = _PyTime_GetMonotonicClock() + secs; - - do { -#ifndef MS_WINDOWS - if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0) - return -1; - - Py_BEGIN_ALLOW_THREADS - err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout); - Py_END_ALLOW_THREADS - - if (err == 0) - break; - - if (errno != EINTR) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } -#else - millisecs = _PyTime_AsMilliseconds(secs, _PyTime_ROUND_CEILING); - if (millisecs > (double)ULONG_MAX) { - PyErr_SetString(PyExc_OverflowError, - "sleep length is too large"); - return -1; - } - - /* Allow sleep(0) to maintain win32 semantics, and as decreed - * by Guido, only the main thread can be interrupted. - */ - ul_millis = (unsigned long)millisecs; - if (ul_millis == 0 || !_PyOS_IsMainThread()) { - Py_BEGIN_ALLOW_THREADS - Sleep(ul_millis); - Py_END_ALLOW_THREADS - break; - } - - hInterruptEvent = _PyOS_SigintEvent(); - ResetEvent(hInterruptEvent); - - Py_BEGIN_ALLOW_THREADS - rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE); - Py_END_ALLOW_THREADS - - if (rc != WAIT_OBJECT_0) - break; -#endif - - /* sleep was interrupted by SIGINT */ - if (PyErr_CheckSignals()) - return -1; - - monotonic = _PyTime_GetMonotonicClock(); - secs = deadline - monotonic; - if (secs < 0) - break; - /* retry with the recomputed delay */ - } while (1); - - return 0; -} +/* Implement pysleep() for various platforms. + When interrupted (or when another error occurs), return -1 and + set an exception; else return 0. */ + +static int +pysleep(_PyTime_t secs) +{ + _PyTime_t deadline, monotonic; +#ifndef MS_WINDOWS + struct timeval timeout; + int err = 0; +#else + _PyTime_t millisecs; + unsigned long ul_millis; + DWORD rc; + HANDLE hInterruptEvent; +#endif + + deadline = _PyTime_GetMonotonicClock() + secs; + + do { +#ifndef MS_WINDOWS + if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0) + return -1; + + Py_BEGIN_ALLOW_THREADS + err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout); + Py_END_ALLOW_THREADS + + if (err == 0) + break; + + if (errno != EINTR) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } +#else + millisecs = _PyTime_AsMilliseconds(secs, _PyTime_ROUND_CEILING); + if (millisecs > (double)ULONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "sleep length is too large"); + return -1; + } + + /* Allow sleep(0) to maintain win32 semantics, and as decreed + * by Guido, only the main thread can be interrupted. + */ + ul_millis = (unsigned long)millisecs; + if (ul_millis == 0 || !_PyOS_IsMainThread()) { + Py_BEGIN_ALLOW_THREADS + Sleep(ul_millis); + Py_END_ALLOW_THREADS + break; + } + + hInterruptEvent = _PyOS_SigintEvent(); + ResetEvent(hInterruptEvent); + + Py_BEGIN_ALLOW_THREADS + rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE); + Py_END_ALLOW_THREADS + + if (rc != WAIT_OBJECT_0) + break; +#endif + + /* sleep was interrupted by SIGINT */ + if (PyErr_CheckSignals()) + return -1; + + monotonic = _PyTime_GetMonotonicClock(); + secs = deadline - monotonic; + if (secs < 0) + break; + /* retry with the recomputed delay */ + } while (1); + + return 0; +} diff --git a/contrib/tools/python3/src/Modules/tkinter.h b/contrib/tools/python3/src/Modules/tkinter.h index cb5a806b0c4..d778a94941a 100644 --- a/contrib/tools/python3/src/Modules/tkinter.h +++ b/contrib/tools/python3/src/Modules/tkinter.h @@ -1,27 +1,27 @@ -#ifndef TKINTER_H -#define TKINTER_H - -/* This header is used to share some macros between _tkinter.c and - * tkappinit.c. - * Be sure to include tk.h before including this header so - * TK_HEX_VERSION is properly defined. */ - -/* TK_RELEASE_LEVEL is always one of the following: - * TCL_ALPHA_RELEASE 0 - * TCL_BETA_RELEASE 1 - * TCL_FINAL_RELEASE 2 - */ -#define TK_HEX_VERSION ((TK_MAJOR_VERSION << 24) | \ - (TK_MINOR_VERSION << 16) | \ - (TK_RELEASE_LEVEL << 8) | \ - (TK_RELEASE_SERIAL << 0)) - -/* Protect Tk 8.4.13 and older from a deadlock that happens when trying - * to load tk after a failed attempt. */ -#if TK_HEX_VERSION < 0x0804020e -#define TKINTER_PROTECT_LOADTK -#define TKINTER_LOADTK_ERRMSG \ - "Calling Tk_Init again after a previous call failed might deadlock" -#endif - -#endif /* !TKINTER_H */ +#ifndef TKINTER_H +#define TKINTER_H + +/* This header is used to share some macros between _tkinter.c and + * tkappinit.c. + * Be sure to include tk.h before including this header so + * TK_HEX_VERSION is properly defined. */ + +/* TK_RELEASE_LEVEL is always one of the following: + * TCL_ALPHA_RELEASE 0 + * TCL_BETA_RELEASE 1 + * TCL_FINAL_RELEASE 2 + */ +#define TK_HEX_VERSION ((TK_MAJOR_VERSION << 24) | \ + (TK_MINOR_VERSION << 16) | \ + (TK_RELEASE_LEVEL << 8) | \ + (TK_RELEASE_SERIAL << 0)) + +/* Protect Tk 8.4.13 and older from a deadlock that happens when trying + * to load tk after a failed attempt. */ +#if TK_HEX_VERSION < 0x0804020e +#define TKINTER_PROTECT_LOADTK +#define TKINTER_LOADTK_ERRMSG \ + "Calling Tk_Init again after a previous call failed might deadlock" +#endif + +#endif /* !TKINTER_H */ diff --git a/contrib/tools/python3/src/Modules/unicodedata.c b/contrib/tools/python3/src/Modules/unicodedata.c index 8a1198a2b71..613638e0a01 100644 --- a/contrib/tools/python3/src/Modules/unicodedata.c +++ b/contrib/tools/python3/src/Modules/unicodedata.c @@ -1,24 +1,24 @@ -/* ------------------------------------------------------------------------ - - unicodedata -- Provides access to the Unicode database. - - Data was extracted from the UnicodeData.txt file. - The current version number is reported in the unidata_version constant. - - Written by Marc-Andre Lemburg (mal@lemburg.com). - Modified for Python 2.0 by Fredrik Lundh (fredrik@pythonware.com) - Modified by Martin v. Löwis (martin@v.loewis.de) - - Copyright (c) Corporation for National Research Initiatives. - - ------------------------------------------------------------------------ */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" -#include "ucnhash.h" +/* ------------------------------------------------------------------------ + + unicodedata -- Provides access to the Unicode database. + + Data was extracted from the UnicodeData.txt file. + The current version number is reported in the unidata_version constant. + + Written by Marc-Andre Lemburg (mal@lemburg.com). + Modified for Python 2.0 by Fredrik Lundh (fredrik@pythonware.com) + Modified by Martin v. Löwis (martin@v.loewis.de) + + Copyright (c) Corporation for National Research Initiatives. + + ------------------------------------------------------------------------ */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" +#include "ucnhash.h" #include "structmember.h" // PyMemberDef - + #include _Py_IDENTIFIER(NFC); @@ -26,757 +26,757 @@ _Py_IDENTIFIER(NFD); _Py_IDENTIFIER(NFKC); _Py_IDENTIFIER(NFKD); -/*[clinic input] -module unicodedata -class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type' -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6dac153082d150bc]*/ - -/* character properties */ - -typedef struct { - const unsigned char category; /* index into - _PyUnicode_CategoryNames */ - const unsigned char combining; /* combining class value 0 - 255 */ - const unsigned char bidirectional; /* index into - _PyUnicode_BidirectionalNames */ - const unsigned char mirrored; /* true if mirrored in bidir mode */ - const unsigned char east_asian_width; /* index into - _PyUnicode_EastAsianWidth */ - const unsigned char normalization_quick_check; /* see is_normalized() */ -} _PyUnicode_DatabaseRecord; - -typedef struct change_record { - /* sequence of fields should be the same as in merge_old_version */ - const unsigned char bidir_changed; - const unsigned char category_changed; - const unsigned char decimal_changed; - const unsigned char mirrored_changed; - const unsigned char east_asian_width_changed; - const double numeric_changed; -} change_record; - -/* data file generated by Tools/unicode/makeunicodedata.py */ -#include "unicodedata_db.h" - -static const _PyUnicode_DatabaseRecord* -_getrecord_ex(Py_UCS4 code) -{ - int index; - if (code >= 0x110000) - index = 0; - else { - index = index1[(code>>SHIFT)]; - index = index2[(index<getrecord)(v)) - -static PyMemberDef DB_members[] = { - {"unidata_version", T_STRING, offsetof(PreviousDBVersion, name), READONLY}, - {NULL} -}; - -/* forward declaration */ -static PyTypeObject UCD_Type; +/*[clinic input] +module unicodedata +class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type' +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6dac153082d150bc]*/ + +/* character properties */ + +typedef struct { + const unsigned char category; /* index into + _PyUnicode_CategoryNames */ + const unsigned char combining; /* combining class value 0 - 255 */ + const unsigned char bidirectional; /* index into + _PyUnicode_BidirectionalNames */ + const unsigned char mirrored; /* true if mirrored in bidir mode */ + const unsigned char east_asian_width; /* index into + _PyUnicode_EastAsianWidth */ + const unsigned char normalization_quick_check; /* see is_normalized() */ +} _PyUnicode_DatabaseRecord; + +typedef struct change_record { + /* sequence of fields should be the same as in merge_old_version */ + const unsigned char bidir_changed; + const unsigned char category_changed; + const unsigned char decimal_changed; + const unsigned char mirrored_changed; + const unsigned char east_asian_width_changed; + const double numeric_changed; +} change_record; + +/* data file generated by Tools/unicode/makeunicodedata.py */ +#include "unicodedata_db.h" + +static const _PyUnicode_DatabaseRecord* +_getrecord_ex(Py_UCS4 code) +{ + int index; + if (code >= 0x110000) + index = 0; + else { + index = index1[(code>>SHIFT)]; + index = index2[(index<getrecord)(v)) + +static PyMemberDef DB_members[] = { + {"unidata_version", T_STRING, offsetof(PreviousDBVersion, name), READONLY}, + {NULL} +}; + +/* forward declaration */ +static PyTypeObject UCD_Type; #define UCD_Check(o) Py_IS_TYPE(o, &UCD_Type) - -static PyObject* -new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), - Py_UCS4 (*normalization)(Py_UCS4)) -{ - PreviousDBVersion *self; - self = PyObject_New(PreviousDBVersion, &UCD_Type); - if (self == NULL) - return NULL; - self->name = name; - self->getrecord = getrecord; - self->normalization = normalization; - return (PyObject*)self; -} - - -/* --- Module API --------------------------------------------------------- */ - -/*[clinic input] -unicodedata.UCD.decimal - - self: self - chr: int(accept={str}) - default: object=NULL - / - -Converts a Unicode character into its equivalent decimal value. - -Returns the decimal value assigned to the character chr as integer. -If no such value is defined, default is returned, or, if not given, -ValueError is raised. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_decimal_impl(PyObject *self, int chr, - PyObject *default_value) -/*[clinic end generated code: output=be23376e1a185231 input=933f8107993f23d0]*/ -{ - int have_old = 0; - long rc; - Py_UCS4 c = (Py_UCS4)chr; - - if (self && UCD_Check(self)) { - const change_record *old = get_old_record(self, c); - if (old->category_changed == 0) { - /* unassigned */ - have_old = 1; - rc = -1; - } - else if (old->decimal_changed != 0xFF) { - have_old = 1; - rc = old->decimal_changed; - } - } - - if (!have_old) - rc = Py_UNICODE_TODECIMAL(c); - if (rc < 0) { - if (default_value == NULL) { - PyErr_SetString(PyExc_ValueError, - "not a decimal"); - return NULL; - } - else { - Py_INCREF(default_value); - return default_value; - } - } - return PyLong_FromLong(rc); -} - -/*[clinic input] -unicodedata.UCD.digit - - self: self - chr: int(accept={str}) - default: object=NULL - / - -Converts a Unicode character into its equivalent digit value. - -Returns the digit value assigned to the character chr as integer. -If no such value is defined, default is returned, or, if not given, -ValueError is raised. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value) -/*[clinic end generated code: output=96e18c950171fd2f input=e27d6e4565cd29f2]*/ -{ - long rc; - Py_UCS4 c = (Py_UCS4)chr; - rc = Py_UNICODE_TODIGIT(c); - if (rc < 0) { - if (default_value == NULL) { - PyErr_SetString(PyExc_ValueError, "not a digit"); - return NULL; - } - else { - Py_INCREF(default_value); - return default_value; - } - } - return PyLong_FromLong(rc); -} - -/*[clinic input] -unicodedata.UCD.numeric - - self: self - chr: int(accept={str}) - default: object=NULL - / - -Converts a Unicode character into its equivalent numeric value. - -Returns the numeric value assigned to the character chr as float. -If no such value is defined, default is returned, or, if not given, -ValueError is raised. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_numeric_impl(PyObject *self, int chr, - PyObject *default_value) -/*[clinic end generated code: output=53ce281fe85b10c4 input=fdf5871a5542893c]*/ -{ - int have_old = 0; - double rc; - Py_UCS4 c = (Py_UCS4)chr; - - if (self && UCD_Check(self)) { - const change_record *old = get_old_record(self, c); - if (old->category_changed == 0) { - /* unassigned */ - have_old = 1; - rc = -1.0; - } - else if (old->decimal_changed != 0xFF) { - have_old = 1; - rc = old->decimal_changed; - } - } - - if (!have_old) - rc = Py_UNICODE_TONUMERIC(c); - if (rc == -1.0) { - if (default_value == NULL) { - PyErr_SetString(PyExc_ValueError, "not a numeric character"); - return NULL; - } - else { - Py_INCREF(default_value); - return default_value; - } - } - return PyFloat_FromDouble(rc); -} - -/*[clinic input] -unicodedata.UCD.category - - self: self - chr: int(accept={str}) - / - -Returns the general category assigned to the character chr as string. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_category_impl(PyObject *self, int chr) -/*[clinic end generated code: output=8571539ee2e6783a input=27d6f3d85050bc06]*/ -{ - int index; - Py_UCS4 c = (Py_UCS4)chr; - index = (int) _getrecord_ex(c)->category; - if (self && UCD_Check(self)) { - const change_record *old = get_old_record(self, c); - if (old->category_changed != 0xFF) - index = old->category_changed; - } - return PyUnicode_FromString(_PyUnicode_CategoryNames[index]); -} - -/*[clinic input] -unicodedata.UCD.bidirectional - - self: self - chr: int(accept={str}) - / - -Returns the bidirectional class assigned to the character chr as string. - -If no such value is defined, an empty string is returned. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) -/*[clinic end generated code: output=d36310ce2039bb92 input=b3d8f42cebfcf475]*/ -{ - int index; - Py_UCS4 c = (Py_UCS4)chr; - index = (int) _getrecord_ex(c)->bidirectional; - if (self && UCD_Check(self)) { - const change_record *old = get_old_record(self, c); - if (old->category_changed == 0) - index = 0; /* unassigned */ - else if (old->bidir_changed != 0xFF) - index = old->bidir_changed; - } - return PyUnicode_FromString(_PyUnicode_BidirectionalNames[index]); -} - -/*[clinic input] -unicodedata.UCD.combining -> int - - self: self - chr: int(accept={str}) - / - -Returns the canonical combining class assigned to the character chr as integer. - -Returns 0 if no combining class is defined. -[clinic start generated code]*/ - -static int -unicodedata_UCD_combining_impl(PyObject *self, int chr) -/*[clinic end generated code: output=cad056d0cb6a5920 input=9f2d6b2a95d0a22a]*/ -{ - int index; - Py_UCS4 c = (Py_UCS4)chr; - index = (int) _getrecord_ex(c)->combining; - if (self && UCD_Check(self)) { - const change_record *old = get_old_record(self, c); - if (old->category_changed == 0) - index = 0; /* unassigned */ - } - return index; -} - -/*[clinic input] -unicodedata.UCD.mirrored -> int - - self: self - chr: int(accept={str}) - / - -Returns the mirrored property assigned to the character chr as integer. - -Returns 1 if the character has been identified as a "mirrored" -character in bidirectional text, 0 otherwise. -[clinic start generated code]*/ - -static int -unicodedata_UCD_mirrored_impl(PyObject *self, int chr) -/*[clinic end generated code: output=2532dbf8121b50e6 input=5dd400d351ae6f3b]*/ -{ - int index; - Py_UCS4 c = (Py_UCS4)chr; - index = (int) _getrecord_ex(c)->mirrored; - if (self && UCD_Check(self)) { - const change_record *old = get_old_record(self, c); - if (old->category_changed == 0) - index = 0; /* unassigned */ - else if (old->mirrored_changed != 0xFF) - index = old->mirrored_changed; - } - return index; -} - -/*[clinic input] -unicodedata.UCD.east_asian_width - - self: self - chr: int(accept={str}) - / - -Returns the east asian width assigned to the character chr as string. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) -/*[clinic end generated code: output=484e8537d9ee8197 input=c4854798aab026e0]*/ -{ - int index; - Py_UCS4 c = (Py_UCS4)chr; - index = (int) _getrecord_ex(c)->east_asian_width; - if (self && UCD_Check(self)) { - const change_record *old = get_old_record(self, c); - if (old->category_changed == 0) - index = 0; /* unassigned */ - else if (old->east_asian_width_changed != 0xFF) - index = old->east_asian_width_changed; - } - return PyUnicode_FromString(_PyUnicode_EastAsianWidthNames[index]); -} - -/*[clinic input] -unicodedata.UCD.decomposition - - self: self - chr: int(accept={str}) - / - -Returns the character decomposition mapping assigned to the character chr as string. - -An empty string is returned in case no such mapping is defined. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_decomposition_impl(PyObject *self, int chr) -/*[clinic end generated code: output=7d699f3ec7565d27 input=e4c12459ad68507b]*/ -{ - char decomp[256]; - int code, index, count; - size_t i; - unsigned int prefix_index; - Py_UCS4 c = (Py_UCS4)chr; - - code = (int)c; - - if (self && UCD_Check(self)) { - const change_record *old = get_old_record(self, c); - if (old->category_changed == 0) - return PyUnicode_FromString(""); /* unassigned */ - } - - if (code < 0 || code >= 0x110000) - index = 0; - else { - index = decomp_index1[(code>>DECOMP_SHIFT)]; - index = decomp_index2[(index<> 8; - - /* XXX: could allocate the PyString up front instead - (strlen(prefix) + 5 * count + 1 bytes) */ - - /* Based on how index is calculated above and decomp_data is generated - from Tools/unicode/makeunicodedata.py, it should not be possible - to overflow decomp_prefix. */ - prefix_index = decomp_data[index] & 255; - assert(prefix_index < Py_ARRAY_LENGTH(decomp_prefix)); - - /* copy prefix */ - i = strlen(decomp_prefix[prefix_index]); - memcpy(decomp, decomp_prefix[prefix_index], i); - - while (count-- > 0) { - if (i) - decomp[i++] = ' '; - assert(i < sizeof(decomp)); - PyOS_snprintf(decomp + i, sizeof(decomp) - i, "%04X", - decomp_data[++index]); - i += strlen(decomp + i); - } - return PyUnicode_FromStringAndSize(decomp, i); -} - -static void -get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *count) -{ - if (code >= 0x110000) { - *index = 0; - } else if (self && UCD_Check(self) && - get_old_record(self, code)->category_changed==0) { - /* unassigned in old version */ - *index = 0; - } - else { - *index = decomp_index1[(code>>DECOMP_SHIFT)]; - *index = decomp_index2[(*index<> 8; - *prefix = decomp_data[*index] & 255; - - (*index)++; -} - -#define SBase 0xAC00 -#define LBase 0x1100 -#define VBase 0x1161 -#define TBase 0x11A7 -#define LCount 19 -#define VCount 21 -#define TCount 28 -#define NCount (VCount*TCount) -#define SCount (LCount*NCount) - -static PyObject* -nfd_nfkd(PyObject *self, PyObject *input, int k) -{ - PyObject *result; - Py_UCS4 *output; - Py_ssize_t i, o, osize; - int kind; + +static PyObject* +new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), + Py_UCS4 (*normalization)(Py_UCS4)) +{ + PreviousDBVersion *self; + self = PyObject_New(PreviousDBVersion, &UCD_Type); + if (self == NULL) + return NULL; + self->name = name; + self->getrecord = getrecord; + self->normalization = normalization; + return (PyObject*)self; +} + + +/* --- Module API --------------------------------------------------------- */ + +/*[clinic input] +unicodedata.UCD.decimal + + self: self + chr: int(accept={str}) + default: object=NULL + / + +Converts a Unicode character into its equivalent decimal value. + +Returns the decimal value assigned to the character chr as integer. +If no such value is defined, default is returned, or, if not given, +ValueError is raised. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_decimal_impl(PyObject *self, int chr, + PyObject *default_value) +/*[clinic end generated code: output=be23376e1a185231 input=933f8107993f23d0]*/ +{ + int have_old = 0; + long rc; + Py_UCS4 c = (Py_UCS4)chr; + + if (self && UCD_Check(self)) { + const change_record *old = get_old_record(self, c); + if (old->category_changed == 0) { + /* unassigned */ + have_old = 1; + rc = -1; + } + else if (old->decimal_changed != 0xFF) { + have_old = 1; + rc = old->decimal_changed; + } + } + + if (!have_old) + rc = Py_UNICODE_TODECIMAL(c); + if (rc < 0) { + if (default_value == NULL) { + PyErr_SetString(PyExc_ValueError, + "not a decimal"); + return NULL; + } + else { + Py_INCREF(default_value); + return default_value; + } + } + return PyLong_FromLong(rc); +} + +/*[clinic input] +unicodedata.UCD.digit + + self: self + chr: int(accept={str}) + default: object=NULL + / + +Converts a Unicode character into its equivalent digit value. + +Returns the digit value assigned to the character chr as integer. +If no such value is defined, default is returned, or, if not given, +ValueError is raised. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value) +/*[clinic end generated code: output=96e18c950171fd2f input=e27d6e4565cd29f2]*/ +{ + long rc; + Py_UCS4 c = (Py_UCS4)chr; + rc = Py_UNICODE_TODIGIT(c); + if (rc < 0) { + if (default_value == NULL) { + PyErr_SetString(PyExc_ValueError, "not a digit"); + return NULL; + } + else { + Py_INCREF(default_value); + return default_value; + } + } + return PyLong_FromLong(rc); +} + +/*[clinic input] +unicodedata.UCD.numeric + + self: self + chr: int(accept={str}) + default: object=NULL + / + +Converts a Unicode character into its equivalent numeric value. + +Returns the numeric value assigned to the character chr as float. +If no such value is defined, default is returned, or, if not given, +ValueError is raised. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_numeric_impl(PyObject *self, int chr, + PyObject *default_value) +/*[clinic end generated code: output=53ce281fe85b10c4 input=fdf5871a5542893c]*/ +{ + int have_old = 0; + double rc; + Py_UCS4 c = (Py_UCS4)chr; + + if (self && UCD_Check(self)) { + const change_record *old = get_old_record(self, c); + if (old->category_changed == 0) { + /* unassigned */ + have_old = 1; + rc = -1.0; + } + else if (old->decimal_changed != 0xFF) { + have_old = 1; + rc = old->decimal_changed; + } + } + + if (!have_old) + rc = Py_UNICODE_TONUMERIC(c); + if (rc == -1.0) { + if (default_value == NULL) { + PyErr_SetString(PyExc_ValueError, "not a numeric character"); + return NULL; + } + else { + Py_INCREF(default_value); + return default_value; + } + } + return PyFloat_FromDouble(rc); +} + +/*[clinic input] +unicodedata.UCD.category + + self: self + chr: int(accept={str}) + / + +Returns the general category assigned to the character chr as string. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_category_impl(PyObject *self, int chr) +/*[clinic end generated code: output=8571539ee2e6783a input=27d6f3d85050bc06]*/ +{ + int index; + Py_UCS4 c = (Py_UCS4)chr; + index = (int) _getrecord_ex(c)->category; + if (self && UCD_Check(self)) { + const change_record *old = get_old_record(self, c); + if (old->category_changed != 0xFF) + index = old->category_changed; + } + return PyUnicode_FromString(_PyUnicode_CategoryNames[index]); +} + +/*[clinic input] +unicodedata.UCD.bidirectional + + self: self + chr: int(accept={str}) + / + +Returns the bidirectional class assigned to the character chr as string. + +If no such value is defined, an empty string is returned. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) +/*[clinic end generated code: output=d36310ce2039bb92 input=b3d8f42cebfcf475]*/ +{ + int index; + Py_UCS4 c = (Py_UCS4)chr; + index = (int) _getrecord_ex(c)->bidirectional; + if (self && UCD_Check(self)) { + const change_record *old = get_old_record(self, c); + if (old->category_changed == 0) + index = 0; /* unassigned */ + else if (old->bidir_changed != 0xFF) + index = old->bidir_changed; + } + return PyUnicode_FromString(_PyUnicode_BidirectionalNames[index]); +} + +/*[clinic input] +unicodedata.UCD.combining -> int + + self: self + chr: int(accept={str}) + / + +Returns the canonical combining class assigned to the character chr as integer. + +Returns 0 if no combining class is defined. +[clinic start generated code]*/ + +static int +unicodedata_UCD_combining_impl(PyObject *self, int chr) +/*[clinic end generated code: output=cad056d0cb6a5920 input=9f2d6b2a95d0a22a]*/ +{ + int index; + Py_UCS4 c = (Py_UCS4)chr; + index = (int) _getrecord_ex(c)->combining; + if (self && UCD_Check(self)) { + const change_record *old = get_old_record(self, c); + if (old->category_changed == 0) + index = 0; /* unassigned */ + } + return index; +} + +/*[clinic input] +unicodedata.UCD.mirrored -> int + + self: self + chr: int(accept={str}) + / + +Returns the mirrored property assigned to the character chr as integer. + +Returns 1 if the character has been identified as a "mirrored" +character in bidirectional text, 0 otherwise. +[clinic start generated code]*/ + +static int +unicodedata_UCD_mirrored_impl(PyObject *self, int chr) +/*[clinic end generated code: output=2532dbf8121b50e6 input=5dd400d351ae6f3b]*/ +{ + int index; + Py_UCS4 c = (Py_UCS4)chr; + index = (int) _getrecord_ex(c)->mirrored; + if (self && UCD_Check(self)) { + const change_record *old = get_old_record(self, c); + if (old->category_changed == 0) + index = 0; /* unassigned */ + else if (old->mirrored_changed != 0xFF) + index = old->mirrored_changed; + } + return index; +} + +/*[clinic input] +unicodedata.UCD.east_asian_width + + self: self + chr: int(accept={str}) + / + +Returns the east asian width assigned to the character chr as string. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) +/*[clinic end generated code: output=484e8537d9ee8197 input=c4854798aab026e0]*/ +{ + int index; + Py_UCS4 c = (Py_UCS4)chr; + index = (int) _getrecord_ex(c)->east_asian_width; + if (self && UCD_Check(self)) { + const change_record *old = get_old_record(self, c); + if (old->category_changed == 0) + index = 0; /* unassigned */ + else if (old->east_asian_width_changed != 0xFF) + index = old->east_asian_width_changed; + } + return PyUnicode_FromString(_PyUnicode_EastAsianWidthNames[index]); +} + +/*[clinic input] +unicodedata.UCD.decomposition + + self: self + chr: int(accept={str}) + / + +Returns the character decomposition mapping assigned to the character chr as string. + +An empty string is returned in case no such mapping is defined. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_decomposition_impl(PyObject *self, int chr) +/*[clinic end generated code: output=7d699f3ec7565d27 input=e4c12459ad68507b]*/ +{ + char decomp[256]; + int code, index, count; + size_t i; + unsigned int prefix_index; + Py_UCS4 c = (Py_UCS4)chr; + + code = (int)c; + + if (self && UCD_Check(self)) { + const change_record *old = get_old_record(self, c); + if (old->category_changed == 0) + return PyUnicode_FromString(""); /* unassigned */ + } + + if (code < 0 || code >= 0x110000) + index = 0; + else { + index = decomp_index1[(code>>DECOMP_SHIFT)]; + index = decomp_index2[(index<> 8; + + /* XXX: could allocate the PyString up front instead + (strlen(prefix) + 5 * count + 1 bytes) */ + + /* Based on how index is calculated above and decomp_data is generated + from Tools/unicode/makeunicodedata.py, it should not be possible + to overflow decomp_prefix. */ + prefix_index = decomp_data[index] & 255; + assert(prefix_index < Py_ARRAY_LENGTH(decomp_prefix)); + + /* copy prefix */ + i = strlen(decomp_prefix[prefix_index]); + memcpy(decomp, decomp_prefix[prefix_index], i); + + while (count-- > 0) { + if (i) + decomp[i++] = ' '; + assert(i < sizeof(decomp)); + PyOS_snprintf(decomp + i, sizeof(decomp) - i, "%04X", + decomp_data[++index]); + i += strlen(decomp + i); + } + return PyUnicode_FromStringAndSize(decomp, i); +} + +static void +get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *count) +{ + if (code >= 0x110000) { + *index = 0; + } else if (self && UCD_Check(self) && + get_old_record(self, code)->category_changed==0) { + /* unassigned in old version */ + *index = 0; + } + else { + *index = decomp_index1[(code>>DECOMP_SHIFT)]; + *index = decomp_index2[(*index<> 8; + *prefix = decomp_data[*index] & 255; + + (*index)++; +} + +#define SBase 0xAC00 +#define LBase 0x1100 +#define VBase 0x1161 +#define TBase 0x11A7 +#define LCount 19 +#define VCount 21 +#define TCount 28 +#define NCount (VCount*TCount) +#define SCount (LCount*NCount) + +static PyObject* +nfd_nfkd(PyObject *self, PyObject *input, int k) +{ + PyObject *result; + Py_UCS4 *output; + Py_ssize_t i, o, osize; + int kind; const void *data; - /* Longest decomposition in Unicode 3.2: U+FDFA */ - Py_UCS4 stack[20]; - Py_ssize_t space, isize; - int index, prefix, count, stackptr; - unsigned char prev, cur; - - stackptr = 0; - isize = PyUnicode_GET_LENGTH(input); - space = isize; - /* Overallocate at most 10 characters. */ - if (space > 10) { - if (space <= PY_SSIZE_T_MAX - 10) - space += 10; - } - else { - space *= 2; - } - osize = space; - output = PyMem_NEW(Py_UCS4, space); - if (!output) { - PyErr_NoMemory(); - return NULL; - } - i = o = 0; - kind = PyUnicode_KIND(input); - data = PyUnicode_DATA(input); - - while (i < isize) { - stack[stackptr++] = PyUnicode_READ(kind, data, i++); - while(stackptr) { - Py_UCS4 code = stack[--stackptr]; - /* Hangul Decomposition adds three characters in - a single step, so we need at least that much room. */ - if (space < 3) { - Py_UCS4 *new_output; - osize += 10; - space += 10; - new_output = PyMem_Realloc(output, osize*sizeof(Py_UCS4)); - if (new_output == NULL) { - PyMem_Free(output); - PyErr_NoMemory(); - return NULL; - } - output = new_output; - } - /* Hangul Decomposition. */ - if (SBase <= code && code < (SBase+SCount)) { - int SIndex = code - SBase; - int L = LBase + SIndex / NCount; - int V = VBase + (SIndex % NCount) / TCount; - int T = TBase + SIndex % TCount; - output[o++] = L; - output[o++] = V; - space -= 2; - if (T != TBase) { - output[o++] = T; - space --; - } - continue; - } - /* normalization changes */ - if (self && UCD_Check(self)) { - Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code); - if (value != 0) { - stack[stackptr++] = value; - continue; - } - } - - /* Other decompositions. */ - get_decomp_record(self, code, &index, &prefix, &count); - - /* Copy character if it is not decomposable, or has a - compatibility decomposition, but we do NFD. */ - if (!count || (prefix && !k)) { - output[o++] = code; - space--; - continue; - } - /* Copy decomposition onto the stack, in reverse - order. */ - while(count) { - code = decomp_data[index + (--count)]; - stack[stackptr++] = code; - } - } - } - - result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, - output, o); - PyMem_Free(output); - if (!result) - return NULL; - /* result is guaranteed to be ready, as it is compact. */ - kind = PyUnicode_KIND(result); - data = PyUnicode_DATA(result); - - /* Sort canonically. */ - i = 0; - prev = _getrecord_ex(PyUnicode_READ(kind, data, i))->combining; - for (i++; i < PyUnicode_GET_LENGTH(result); i++) { - cur = _getrecord_ex(PyUnicode_READ(kind, data, i))->combining; - if (prev == 0 || cur == 0 || prev <= cur) { - prev = cur; - continue; - } - /* Non-canonical order. Need to switch *i with previous. */ - o = i - 1; - while (1) { - Py_UCS4 tmp = PyUnicode_READ(kind, data, o+1); - PyUnicode_WRITE(kind, data, o+1, - PyUnicode_READ(kind, data, o)); - PyUnicode_WRITE(kind, data, o, tmp); - o--; - if (o < 0) - break; - prev = _getrecord_ex(PyUnicode_READ(kind, data, o))->combining; - if (prev == 0 || prev <= cur) - break; - } - prev = _getrecord_ex(PyUnicode_READ(kind, data, i))->combining; - } - return result; -} - -static int + /* Longest decomposition in Unicode 3.2: U+FDFA */ + Py_UCS4 stack[20]; + Py_ssize_t space, isize; + int index, prefix, count, stackptr; + unsigned char prev, cur; + + stackptr = 0; + isize = PyUnicode_GET_LENGTH(input); + space = isize; + /* Overallocate at most 10 characters. */ + if (space > 10) { + if (space <= PY_SSIZE_T_MAX - 10) + space += 10; + } + else { + space *= 2; + } + osize = space; + output = PyMem_NEW(Py_UCS4, space); + if (!output) { + PyErr_NoMemory(); + return NULL; + } + i = o = 0; + kind = PyUnicode_KIND(input); + data = PyUnicode_DATA(input); + + while (i < isize) { + stack[stackptr++] = PyUnicode_READ(kind, data, i++); + while(stackptr) { + Py_UCS4 code = stack[--stackptr]; + /* Hangul Decomposition adds three characters in + a single step, so we need at least that much room. */ + if (space < 3) { + Py_UCS4 *new_output; + osize += 10; + space += 10; + new_output = PyMem_Realloc(output, osize*sizeof(Py_UCS4)); + if (new_output == NULL) { + PyMem_Free(output); + PyErr_NoMemory(); + return NULL; + } + output = new_output; + } + /* Hangul Decomposition. */ + if (SBase <= code && code < (SBase+SCount)) { + int SIndex = code - SBase; + int L = LBase + SIndex / NCount; + int V = VBase + (SIndex % NCount) / TCount; + int T = TBase + SIndex % TCount; + output[o++] = L; + output[o++] = V; + space -= 2; + if (T != TBase) { + output[o++] = T; + space --; + } + continue; + } + /* normalization changes */ + if (self && UCD_Check(self)) { + Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code); + if (value != 0) { + stack[stackptr++] = value; + continue; + } + } + + /* Other decompositions. */ + get_decomp_record(self, code, &index, &prefix, &count); + + /* Copy character if it is not decomposable, or has a + compatibility decomposition, but we do NFD. */ + if (!count || (prefix && !k)) { + output[o++] = code; + space--; + continue; + } + /* Copy decomposition onto the stack, in reverse + order. */ + while(count) { + code = decomp_data[index + (--count)]; + stack[stackptr++] = code; + } + } + } + + result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, + output, o); + PyMem_Free(output); + if (!result) + return NULL; + /* result is guaranteed to be ready, as it is compact. */ + kind = PyUnicode_KIND(result); + data = PyUnicode_DATA(result); + + /* Sort canonically. */ + i = 0; + prev = _getrecord_ex(PyUnicode_READ(kind, data, i))->combining; + for (i++; i < PyUnicode_GET_LENGTH(result); i++) { + cur = _getrecord_ex(PyUnicode_READ(kind, data, i))->combining; + if (prev == 0 || cur == 0 || prev <= cur) { + prev = cur; + continue; + } + /* Non-canonical order. Need to switch *i with previous. */ + o = i - 1; + while (1) { + Py_UCS4 tmp = PyUnicode_READ(kind, data, o+1); + PyUnicode_WRITE(kind, data, o+1, + PyUnicode_READ(kind, data, o)); + PyUnicode_WRITE(kind, data, o, tmp); + o--; + if (o < 0) + break; + prev = _getrecord_ex(PyUnicode_READ(kind, data, o))->combining; + if (prev == 0 || prev <= cur) + break; + } + prev = _getrecord_ex(PyUnicode_READ(kind, data, i))->combining; + } + return result; +} + +static int find_nfc_index(const struct reindex* nfc, Py_UCS4 code) -{ - unsigned int index; - for (index = 0; nfc[index].start; index++) { - unsigned int start = nfc[index].start; - if (code < start) - return -1; - if (code <= start + nfc[index].count) { - unsigned int delta = code - start; - return nfc[index].index + delta; - } - } - return -1; -} - -static PyObject* -nfc_nfkc(PyObject *self, PyObject *input, int k) -{ - PyObject *result; - int kind; +{ + unsigned int index; + for (index = 0; nfc[index].start; index++) { + unsigned int start = nfc[index].start; + if (code < start) + return -1; + if (code <= start + nfc[index].count) { + unsigned int delta = code - start; + return nfc[index].index + delta; + } + } + return -1; +} + +static PyObject* +nfc_nfkc(PyObject *self, PyObject *input, int k) +{ + PyObject *result; + int kind; const void *data; - Py_UCS4 *output; - Py_ssize_t i, i1, o, len; - int f,l,index,index1,comb; - Py_UCS4 code; - Py_ssize_t skipped[20]; - int cskipped = 0; - - result = nfd_nfkd(self, input, k); - if (!result) - return NULL; - /* result will be "ready". */ - kind = PyUnicode_KIND(result); - data = PyUnicode_DATA(result); - len = PyUnicode_GET_LENGTH(result); - - /* We allocate a buffer for the output. - If we find that we made no changes, we still return - the NFD result. */ - output = PyMem_NEW(Py_UCS4, len); - if (!output) { - PyErr_NoMemory(); - Py_DECREF(result); - return 0; - } - i = o = 0; - - again: - while (i < len) { - for (index = 0; index < cskipped; index++) { - if (skipped[index] == i) { - /* *i character is skipped. - Remove from list. */ - skipped[index] = skipped[cskipped-1]; - cskipped--; - i++; - goto again; /* continue while */ - } - } - /* Hangul Composition. We don't need to check for - pairs, since we always have decomposed data. */ - code = PyUnicode_READ(kind, data, i); - if (LBase <= code && code < (LBase+LCount) && - i + 1 < len && - VBase <= PyUnicode_READ(kind, data, i+1) && - PyUnicode_READ(kind, data, i+1) < (VBase+VCount)) { - /* check L character is a modern leading consonant (0x1100 ~ 0x1112) - and V character is a modern vowel (0x1161 ~ 0x1175). */ - int LIndex, VIndex; - LIndex = code - LBase; - VIndex = PyUnicode_READ(kind, data, i+1) - VBase; - code = SBase + (LIndex*VCount+VIndex)*TCount; - i+=2; - if (i < len && - TBase < PyUnicode_READ(kind, data, i) && - PyUnicode_READ(kind, data, i) < (TBase+TCount)) { - /* check T character is a modern trailing consonant - (0x11A8 ~ 0x11C2). */ - code += PyUnicode_READ(kind, data, i)-TBase; - i++; - } - output[o++] = code; - continue; - } - - /* code is still input[i] here */ + Py_UCS4 *output; + Py_ssize_t i, i1, o, len; + int f,l,index,index1,comb; + Py_UCS4 code; + Py_ssize_t skipped[20]; + int cskipped = 0; + + result = nfd_nfkd(self, input, k); + if (!result) + return NULL; + /* result will be "ready". */ + kind = PyUnicode_KIND(result); + data = PyUnicode_DATA(result); + len = PyUnicode_GET_LENGTH(result); + + /* We allocate a buffer for the output. + If we find that we made no changes, we still return + the NFD result. */ + output = PyMem_NEW(Py_UCS4, len); + if (!output) { + PyErr_NoMemory(); + Py_DECREF(result); + return 0; + } + i = o = 0; + + again: + while (i < len) { + for (index = 0; index < cskipped; index++) { + if (skipped[index] == i) { + /* *i character is skipped. + Remove from list. */ + skipped[index] = skipped[cskipped-1]; + cskipped--; + i++; + goto again; /* continue while */ + } + } + /* Hangul Composition. We don't need to check for + pairs, since we always have decomposed data. */ + code = PyUnicode_READ(kind, data, i); + if (LBase <= code && code < (LBase+LCount) && + i + 1 < len && + VBase <= PyUnicode_READ(kind, data, i+1) && + PyUnicode_READ(kind, data, i+1) < (VBase+VCount)) { + /* check L character is a modern leading consonant (0x1100 ~ 0x1112) + and V character is a modern vowel (0x1161 ~ 0x1175). */ + int LIndex, VIndex; + LIndex = code - LBase; + VIndex = PyUnicode_READ(kind, data, i+1) - VBase; + code = SBase + (LIndex*VCount+VIndex)*TCount; + i+=2; + if (i < len && + TBase < PyUnicode_READ(kind, data, i) && + PyUnicode_READ(kind, data, i) < (TBase+TCount)) { + /* check T character is a modern trailing consonant + (0x11A8 ~ 0x11C2). */ + code += PyUnicode_READ(kind, data, i)-TBase; + i++; + } + output[o++] = code; + continue; + } + + /* code is still input[i] here */ f = find_nfc_index(nfc_first, code); - if (f == -1) { - output[o++] = code; - i++; - continue; - } - /* Find next unblocked character. */ - i1 = i+1; - comb = 0; - /* output base character for now; might be updated later. */ - output[o] = PyUnicode_READ(kind, data, i); - while (i1 < len) { - Py_UCS4 code1 = PyUnicode_READ(kind, data, i1); - int comb1 = _getrecord_ex(code1)->combining; - if (comb) { - if (comb1 == 0) - break; - if (comb >= comb1) { - /* Character is blocked. */ - i1++; - continue; - } - } + if (f == -1) { + output[o++] = code; + i++; + continue; + } + /* Find next unblocked character. */ + i1 = i+1; + comb = 0; + /* output base character for now; might be updated later. */ + output[o] = PyUnicode_READ(kind, data, i); + while (i1 < len) { + Py_UCS4 code1 = PyUnicode_READ(kind, data, i1); + int comb1 = _getrecord_ex(code1)->combining; + if (comb) { + if (comb1 == 0) + break; + if (comb >= comb1) { + /* Character is blocked. */ + i1++; + continue; + } + } l = find_nfc_index(nfc_last, code1); - /* i1 cannot be combined with i. If i1 - is a starter, we don't need to look further. - Otherwise, record the combining class. */ - if (l == -1) { - not_combinable: - if (comb1 == 0) - break; - comb = comb1; - i1++; - continue; - } - index = f*TOTAL_LAST + l; - index1 = comp_index[index >> COMP_SHIFT]; - code = comp_data[(index1<> COMP_SHIFT]; + code = comp_data[(index1<combining; - if (combining && prev_combining > combining) + + i = 0; + kind = PyUnicode_KIND(input); + data = PyUnicode_DATA(input); + len = PyUnicode_GET_LENGTH(input); + while (i < len) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i++); + const _PyUnicode_DatabaseRecord *record = _getrecord_ex(ch); + + unsigned char combining = record->combining; + if (combining && prev_combining > combining) return NO; /* non-canonical sort order, not normalized */ - prev_combining = combining; + prev_combining = combining; unsigned char quickcheck_whole = record->normalization_quick_check; if (yes_only) { @@ -837,11 +837,11 @@ is_normalized_quickcheck(PyObject *self, PyObject *input, result = MAYBE; /* this string might need normalization */ } } - } + } return result; -} - -/*[clinic input] +} + +/*[clinic input] unicodedata.UCD.is_normalized self: self @@ -915,572 +915,572 @@ unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, /*[clinic input] -unicodedata.UCD.normalize - - self: self +unicodedata.UCD.normalize + + self: self form: unicode - unistr as input: unicode - / - -Return the normal form 'form' for the Unicode string unistr. - -Valid values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'. -[clinic start generated code]*/ - -static PyObject * + unistr as input: unicode + / + +Return the normal form 'form' for the Unicode string unistr. + +Valid values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'. +[clinic start generated code]*/ + +static PyObject * unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, - PyObject *input) + PyObject *input) /*[clinic end generated code: output=05ca4385a2ad6983 input=3a5206c0ad2833fb]*/ -{ - if (PyUnicode_GET_LENGTH(input) == 0) { - /* Special case empty input strings, since resizing - them later would cause internal errors. */ - Py_INCREF(input); - return input; - } - +{ + if (PyUnicode_GET_LENGTH(input) == 0) { + /* Special case empty input strings, since resizing + them later would cause internal errors. */ + Py_INCREF(input); + return input; + } + if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) { if (is_normalized_quickcheck(self, input, true, false, true) == YES) { - Py_INCREF(input); - return input; - } - return nfc_nfkc(self, input, 0); - } + Py_INCREF(input); + return input; + } + return nfc_nfkc(self, input, 0); + } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { if (is_normalized_quickcheck(self, input, true, true, true) == YES) { - Py_INCREF(input); - return input; - } - return nfc_nfkc(self, input, 1); - } + Py_INCREF(input); + return input; + } + return nfc_nfkc(self, input, 1); + } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { if (is_normalized_quickcheck(self, input, false, false, true) == YES) { - Py_INCREF(input); - return input; - } - return nfd_nfkd(self, input, 0); - } + Py_INCREF(input); + return input; + } + return nfd_nfkd(self, input, 0); + } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { if (is_normalized_quickcheck(self, input, false, true, true) == YES) { - Py_INCREF(input); - return input; - } - return nfd_nfkd(self, input, 1); - } - PyErr_SetString(PyExc_ValueError, "invalid normalization form"); - return NULL; -} - -/* -------------------------------------------------------------------- */ -/* unicode character name tables */ - -/* data file generated by Tools/unicode/makeunicodedata.py */ -#include "unicodename_db.h" - -/* -------------------------------------------------------------------- */ -/* database code (cut and pasted from the unidb package) */ - -static unsigned long -_gethash(const char *s, int len, int scale) -{ - int i; - unsigned long h = 0; - unsigned long ix; - for (i = 0; i < len; i++) { + Py_INCREF(input); + return input; + } + return nfd_nfkd(self, input, 1); + } + PyErr_SetString(PyExc_ValueError, "invalid normalization form"); + return NULL; +} + +/* -------------------------------------------------------------------- */ +/* unicode character name tables */ + +/* data file generated by Tools/unicode/makeunicodedata.py */ +#include "unicodename_db.h" + +/* -------------------------------------------------------------------- */ +/* database code (cut and pasted from the unidb package) */ + +static unsigned long +_gethash(const char *s, int len, int scale) +{ + int i; + unsigned long h = 0; + unsigned long ix; + for (i = 0; i < len; i++) { h = (h * scale) + (unsigned char) Py_TOUPPER(s[i]); - ix = h & 0xff000000; - if (ix) - h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff; - } - return h; -} - -static const char * const hangul_syllables[][3] = { - { "G", "A", "" }, - { "GG", "AE", "G" }, - { "N", "YA", "GG" }, - { "D", "YAE", "GS" }, - { "DD", "EO", "N", }, - { "R", "E", "NJ" }, - { "M", "YEO", "NH" }, - { "B", "YE", "D" }, - { "BB", "O", "L" }, - { "S", "WA", "LG" }, - { "SS", "WAE", "LM" }, - { "", "OE", "LB" }, - { "J", "YO", "LS" }, - { "JJ", "U", "LT" }, - { "C", "WEO", "LP" }, - { "K", "WE", "LH" }, - { "T", "WI", "M" }, - { "P", "YU", "B" }, - { "H", "EU", "BS" }, - { 0, "YI", "S" }, - { 0, "I", "SS" }, - { 0, 0, "NG" }, - { 0, 0, "J" }, - { 0, 0, "C" }, - { 0, 0, "K" }, - { 0, 0, "T" }, - { 0, 0, "P" }, - { 0, 0, "H" } -}; - -/* These ranges need to match makeunicodedata.py:cjk_ranges. */ -static int -is_unified_ideograph(Py_UCS4 code) -{ - return + ix = h & 0xff000000; + if (ix) + h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff; + } + return h; +} + +static const char * const hangul_syllables[][3] = { + { "G", "A", "" }, + { "GG", "AE", "G" }, + { "N", "YA", "GG" }, + { "D", "YAE", "GS" }, + { "DD", "EO", "N", }, + { "R", "E", "NJ" }, + { "M", "YEO", "NH" }, + { "B", "YE", "D" }, + { "BB", "O", "L" }, + { "S", "WA", "LG" }, + { "SS", "WAE", "LM" }, + { "", "OE", "LB" }, + { "J", "YO", "LS" }, + { "JJ", "U", "LT" }, + { "C", "WEO", "LP" }, + { "K", "WE", "LH" }, + { "T", "WI", "M" }, + { "P", "YU", "B" }, + { "H", "EU", "BS" }, + { 0, "YI", "S" }, + { 0, "I", "SS" }, + { 0, 0, "NG" }, + { 0, 0, "J" }, + { 0, 0, "C" }, + { 0, 0, "K" }, + { 0, 0, "T" }, + { 0, 0, "P" }, + { 0, 0, "H" } +}; + +/* These ranges need to match makeunicodedata.py:cjk_ranges. */ +static int +is_unified_ideograph(Py_UCS4 code) +{ + return (0x3400 <= code && code <= 0x4DBF) || /* CJK Ideograph Extension A */ (0x4E00 <= code && code <= 0x9FFC) || /* CJK Ideograph */ (0x20000 <= code && code <= 0x2A6DD) || /* CJK Ideograph Extension B */ - (0x2A700 <= code && code <= 0x2B734) || /* CJK Ideograph Extension C */ - (0x2B740 <= code && code <= 0x2B81D) || /* CJK Ideograph Extension D */ - (0x2B820 <= code && code <= 0x2CEA1) || /* CJK Ideograph Extension E */ + (0x2A700 <= code && code <= 0x2B734) || /* CJK Ideograph Extension C */ + (0x2B740 <= code && code <= 0x2B81D) || /* CJK Ideograph Extension D */ + (0x2B820 <= code && code <= 0x2CEA1) || /* CJK Ideograph Extension E */ (0x2CEB0 <= code && code <= 0x2EBE0) || /* CJK Ideograph Extension F */ (0x30000 <= code && code <= 0x3134A); /* CJK Ideograph Extension G */ -} - -/* macros used to determine if the given code point is in the PUA range that - * we are using to store aliases and named sequences */ -#define IS_ALIAS(cp) ((cp >= aliases_start) && (cp < aliases_end)) -#define IS_NAMED_SEQ(cp) ((cp >= named_sequences_start) && \ - (cp < named_sequences_end)) - -static int -_getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, - int with_alias_and_seq) -{ - /* Find the name associated with the given code point. - * If with_alias_and_seq is 1, check for names in the Private Use Area 15 - * that we are using for aliases and named sequences. */ - int offset; - int i; - int word; +} + +/* macros used to determine if the given code point is in the PUA range that + * we are using to store aliases and named sequences */ +#define IS_ALIAS(cp) ((cp >= aliases_start) && (cp < aliases_end)) +#define IS_NAMED_SEQ(cp) ((cp >= named_sequences_start) && \ + (cp < named_sequences_end)) + +static int +_getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, + int with_alias_and_seq) +{ + /* Find the name associated with the given code point. + * If with_alias_and_seq is 1, check for names in the Private Use Area 15 + * that we are using for aliases and named sequences. */ + int offset; + int i; + int word; const unsigned char* w; - - if (code >= 0x110000) - return 0; - - /* XXX should we just skip all the code points in the PUAs here? */ - if (!with_alias_and_seq && (IS_ALIAS(code) || IS_NAMED_SEQ(code))) - return 0; - - if (self && UCD_Check(self)) { - /* in 3.2.0 there are no aliases and named sequences */ - const change_record *old; - if (IS_ALIAS(code) || IS_NAMED_SEQ(code)) - return 0; - old = get_old_record(self, code); - if (old->category_changed == 0) { - /* unassigned */ - return 0; - } - } - - if (SBase <= code && code < SBase+SCount) { - /* Hangul syllable. */ - int SIndex = code - SBase; - int L = SIndex / NCount; - int V = (SIndex % NCount) / TCount; - int T = SIndex % TCount; - - if (buflen < 27) - /* Worst case: HANGUL SYLLABLE <10chars>. */ - return 0; - strcpy(buffer, "HANGUL SYLLABLE "); - buffer += 16; - strcpy(buffer, hangul_syllables[L][0]); - buffer += strlen(hangul_syllables[L][0]); - strcpy(buffer, hangul_syllables[V][1]); - buffer += strlen(hangul_syllables[V][1]); - strcpy(buffer, hangul_syllables[T][2]); - buffer += strlen(hangul_syllables[T][2]); - *buffer = '\0'; - return 1; - } - - if (is_unified_ideograph(code)) { - if (buflen < 28) - /* Worst case: CJK UNIFIED IDEOGRAPH-20000 */ - return 0; - sprintf(buffer, "CJK UNIFIED IDEOGRAPH-%X", code); - return 1; - } - - /* get offset into phrasebook */ - offset = phrasebook_offset1[(code>>phrasebook_shift)]; - offset = phrasebook_offset2[(offset<= 0) { - word = (word << 8) + phrasebook[offset+1]; - offset += 2; - } else - word = phrasebook[offset++]; - if (i) { - if (i > buflen) - return 0; /* buffer overflow */ - buffer[i++] = ' '; - } - /* copy word string from lexicon. the last character in the - word has bit 7 set. the last word in a string ends with - 0x80 */ - w = lexicon + lexicon_offset[word]; - while (*w < 128) { - if (i >= buflen) - return 0; /* buffer overflow */ - buffer[i++] = *w++; - } - if (i >= buflen) - return 0; /* buffer overflow */ - buffer[i++] = *w & 127; - if (*w == 128) - break; /* end of word */ - } - - return 1; -} - -static int -_cmpname(PyObject *self, int code, const char* name, int namelen) -{ - /* check if code corresponds to the given name */ - int i; - char buffer[NAME_MAXLEN+1]; - if (!_getucname(self, code, buffer, NAME_MAXLEN, 1)) - return 0; - for (i = 0; i < namelen; i++) { + + if (code >= 0x110000) + return 0; + + /* XXX should we just skip all the code points in the PUAs here? */ + if (!with_alias_and_seq && (IS_ALIAS(code) || IS_NAMED_SEQ(code))) + return 0; + + if (self && UCD_Check(self)) { + /* in 3.2.0 there are no aliases and named sequences */ + const change_record *old; + if (IS_ALIAS(code) || IS_NAMED_SEQ(code)) + return 0; + old = get_old_record(self, code); + if (old->category_changed == 0) { + /* unassigned */ + return 0; + } + } + + if (SBase <= code && code < SBase+SCount) { + /* Hangul syllable. */ + int SIndex = code - SBase; + int L = SIndex / NCount; + int V = (SIndex % NCount) / TCount; + int T = SIndex % TCount; + + if (buflen < 27) + /* Worst case: HANGUL SYLLABLE <10chars>. */ + return 0; + strcpy(buffer, "HANGUL SYLLABLE "); + buffer += 16; + strcpy(buffer, hangul_syllables[L][0]); + buffer += strlen(hangul_syllables[L][0]); + strcpy(buffer, hangul_syllables[V][1]); + buffer += strlen(hangul_syllables[V][1]); + strcpy(buffer, hangul_syllables[T][2]); + buffer += strlen(hangul_syllables[T][2]); + *buffer = '\0'; + return 1; + } + + if (is_unified_ideograph(code)) { + if (buflen < 28) + /* Worst case: CJK UNIFIED IDEOGRAPH-20000 */ + return 0; + sprintf(buffer, "CJK UNIFIED IDEOGRAPH-%X", code); + return 1; + } + + /* get offset into phrasebook */ + offset = phrasebook_offset1[(code>>phrasebook_shift)]; + offset = phrasebook_offset2[(offset<= 0) { + word = (word << 8) + phrasebook[offset+1]; + offset += 2; + } else + word = phrasebook[offset++]; + if (i) { + if (i > buflen) + return 0; /* buffer overflow */ + buffer[i++] = ' '; + } + /* copy word string from lexicon. the last character in the + word has bit 7 set. the last word in a string ends with + 0x80 */ + w = lexicon + lexicon_offset[word]; + while (*w < 128) { + if (i >= buflen) + return 0; /* buffer overflow */ + buffer[i++] = *w++; + } + if (i >= buflen) + return 0; /* buffer overflow */ + buffer[i++] = *w & 127; + if (*w == 128) + break; /* end of word */ + } + + return 1; +} + +static int +_cmpname(PyObject *self, int code, const char* name, int namelen) +{ + /* check if code corresponds to the given name */ + int i; + char buffer[NAME_MAXLEN+1]; + if (!_getucname(self, code, buffer, NAME_MAXLEN, 1)) + return 0; + for (i = 0; i < namelen; i++) { if (Py_TOUPPER(name[i]) != buffer[i]) - return 0; - } - return buffer[namelen] == '\0'; -} - -static void -find_syllable(const char *str, int *len, int *pos, int count, int column) -{ - int i, len1; - *len = -1; - for (i = 0; i < count; i++) { - const char *s = hangul_syllables[i][column]; - len1 = Py_SAFE_DOWNCAST(strlen(s), size_t, int); - if (len1 <= *len) - continue; - if (strncmp(str, s, len1) == 0) { - *len = len1; - *pos = i; - } - } - if (*len == -1) { - *len = 0; - } -} - -static int -_check_alias_and_seq(unsigned int cp, Py_UCS4* code, int with_named_seq) -{ - /* check if named sequences are allowed */ - if (!with_named_seq && IS_NAMED_SEQ(cp)) - return 0; - /* if the code point is in the PUA range that we use for aliases, - * convert it to obtain the right code point */ - if (IS_ALIAS(cp)) - *code = name_aliases[cp-aliases_start]; - else - *code = cp; - return 1; -} - -static int -_getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, - int with_named_seq) -{ - /* Return the code point associated with the given name. - * Named aliases are resolved too (unless self != NULL (i.e. we are using - * 3.2.0)). If with_named_seq is 1, returns the PUA code point that we are - * using for the named sequence, and the caller must then convert it. */ - unsigned int h, v; - unsigned int mask = code_size-1; - unsigned int i, incr; - - /* Check for hangul syllables. */ - if (strncmp(name, "HANGUL SYLLABLE ", 16) == 0) { - int len, L = -1, V = -1, T = -1; - const char *pos = name + 16; - find_syllable(pos, &len, &L, LCount, 0); - pos += len; - find_syllable(pos, &len, &V, VCount, 1); - pos += len; - find_syllable(pos, &len, &T, TCount, 2); - pos += len; - if (L != -1 && V != -1 && T != -1 && pos-name == namelen) { - *code = SBase + (L*VCount+V)*TCount + T; - return 1; - } - /* Otherwise, it's an illegal syllable name. */ - return 0; - } - - /* Check for unified ideographs. */ - if (strncmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) { - /* Four or five hexdigits must follow. */ - v = 0; - name += 22; - namelen -= 22; - if (namelen != 4 && namelen != 5) - return 0; - while (namelen--) { - v *= 16; - if (*name >= '0' && *name <= '9') - v += *name - '0'; - else if (*name >= 'A' && *name <= 'F') - v += *name - 'A' + 10; - else - return 0; - name++; - } - if (!is_unified_ideograph(v)) - return 0; - *code = v; - return 1; - } - - /* the following is the same as python's dictionary lookup, with - only minor changes. see the makeunicodedata script for more - details */ - - h = (unsigned int) _gethash(name, namelen, code_magic); - i = (~h) & mask; - v = code_hash[i]; - if (!v) - return 0; - if (_cmpname(self, v, name, namelen)) - return _check_alias_and_seq(v, code, with_named_seq); - incr = (h ^ (h >> 3)) & mask; - if (!incr) - incr = mask; - for (;;) { - i = (i + incr) & mask; - v = code_hash[i]; - if (!v) - return 0; - if (_cmpname(self, v, name, namelen)) - return _check_alias_and_seq(v, code, with_named_seq); - incr = incr << 1; - if (incr > mask) - incr = incr ^ code_poly; - } -} - -static const _PyUnicode_Name_CAPI hashAPI = -{ - sizeof(_PyUnicode_Name_CAPI), - _getucname, - _getcode -}; - -/* -------------------------------------------------------------------- */ -/* Python bindings */ - -/*[clinic input] -unicodedata.UCD.name - - self: self - chr: int(accept={str}) - default: object=NULL - / - -Returns the name assigned to the character chr as a string. - -If no name is defined, default is returned, or, if not given, -ValueError is raised. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value) -/*[clinic end generated code: output=6bbb37a326407707 input=3e0367f534de56d9]*/ -{ - char name[NAME_MAXLEN+1]; - Py_UCS4 c = (Py_UCS4)chr; - - if (!_getucname(self, c, name, NAME_MAXLEN, 0)) { - if (default_value == NULL) { - PyErr_SetString(PyExc_ValueError, "no such name"); - return NULL; - } - else { - Py_INCREF(default_value); - return default_value; - } - } - - return PyUnicode_FromString(name); -} - -/*[clinic input] -unicodedata.UCD.lookup - - self: self - name: str(accept={str, robuffer}, zeroes=True) - / - -Look up character by name. - -If a character with the given name is found, return the -corresponding character. If not found, KeyError is raised. -[clinic start generated code]*/ - -static PyObject * -unicodedata_UCD_lookup_impl(PyObject *self, const char *name, - Py_ssize_clean_t name_length) -/*[clinic end generated code: output=765cb8186788e6be input=a557be0f8607a0d6]*/ -{ - Py_UCS4 code; - unsigned int index; - if (name_length > NAME_MAXLEN) { - PyErr_SetString(PyExc_KeyError, "name too long"); - return NULL; - } - - if (!_getcode(self, name, (int)name_length, &code, 1)) { - PyErr_Format(PyExc_KeyError, "undefined character name '%s'", name); - return NULL; - } - /* check if code is in the PUA range that we use for named sequences - and convert it */ - if (IS_NAMED_SEQ(code)) { - index = code-named_sequences_start; - return PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, - named_sequences[index].seq, - named_sequences[index].seqlen); - } - return PyUnicode_FromOrdinal(code); -} - -/* XXX Add doc strings. */ - -static PyMethodDef unicodedata_functions[] = { - UNICODEDATA_UCD_DECIMAL_METHODDEF - UNICODEDATA_UCD_DIGIT_METHODDEF - UNICODEDATA_UCD_NUMERIC_METHODDEF - UNICODEDATA_UCD_CATEGORY_METHODDEF - UNICODEDATA_UCD_BIDIRECTIONAL_METHODDEF - UNICODEDATA_UCD_COMBINING_METHODDEF - UNICODEDATA_UCD_MIRRORED_METHODDEF - UNICODEDATA_UCD_EAST_ASIAN_WIDTH_METHODDEF - UNICODEDATA_UCD_DECOMPOSITION_METHODDEF - UNICODEDATA_UCD_NAME_METHODDEF - UNICODEDATA_UCD_LOOKUP_METHODDEF + return 0; + } + return buffer[namelen] == '\0'; +} + +static void +find_syllable(const char *str, int *len, int *pos, int count, int column) +{ + int i, len1; + *len = -1; + for (i = 0; i < count; i++) { + const char *s = hangul_syllables[i][column]; + len1 = Py_SAFE_DOWNCAST(strlen(s), size_t, int); + if (len1 <= *len) + continue; + if (strncmp(str, s, len1) == 0) { + *len = len1; + *pos = i; + } + } + if (*len == -1) { + *len = 0; + } +} + +static int +_check_alias_and_seq(unsigned int cp, Py_UCS4* code, int with_named_seq) +{ + /* check if named sequences are allowed */ + if (!with_named_seq && IS_NAMED_SEQ(cp)) + return 0; + /* if the code point is in the PUA range that we use for aliases, + * convert it to obtain the right code point */ + if (IS_ALIAS(cp)) + *code = name_aliases[cp-aliases_start]; + else + *code = cp; + return 1; +} + +static int +_getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, + int with_named_seq) +{ + /* Return the code point associated with the given name. + * Named aliases are resolved too (unless self != NULL (i.e. we are using + * 3.2.0)). If with_named_seq is 1, returns the PUA code point that we are + * using for the named sequence, and the caller must then convert it. */ + unsigned int h, v; + unsigned int mask = code_size-1; + unsigned int i, incr; + + /* Check for hangul syllables. */ + if (strncmp(name, "HANGUL SYLLABLE ", 16) == 0) { + int len, L = -1, V = -1, T = -1; + const char *pos = name + 16; + find_syllable(pos, &len, &L, LCount, 0); + pos += len; + find_syllable(pos, &len, &V, VCount, 1); + pos += len; + find_syllable(pos, &len, &T, TCount, 2); + pos += len; + if (L != -1 && V != -1 && T != -1 && pos-name == namelen) { + *code = SBase + (L*VCount+V)*TCount + T; + return 1; + } + /* Otherwise, it's an illegal syllable name. */ + return 0; + } + + /* Check for unified ideographs. */ + if (strncmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) { + /* Four or five hexdigits must follow. */ + v = 0; + name += 22; + namelen -= 22; + if (namelen != 4 && namelen != 5) + return 0; + while (namelen--) { + v *= 16; + if (*name >= '0' && *name <= '9') + v += *name - '0'; + else if (*name >= 'A' && *name <= 'F') + v += *name - 'A' + 10; + else + return 0; + name++; + } + if (!is_unified_ideograph(v)) + return 0; + *code = v; + return 1; + } + + /* the following is the same as python's dictionary lookup, with + only minor changes. see the makeunicodedata script for more + details */ + + h = (unsigned int) _gethash(name, namelen, code_magic); + i = (~h) & mask; + v = code_hash[i]; + if (!v) + return 0; + if (_cmpname(self, v, name, namelen)) + return _check_alias_and_seq(v, code, with_named_seq); + incr = (h ^ (h >> 3)) & mask; + if (!incr) + incr = mask; + for (;;) { + i = (i + incr) & mask; + v = code_hash[i]; + if (!v) + return 0; + if (_cmpname(self, v, name, namelen)) + return _check_alias_and_seq(v, code, with_named_seq); + incr = incr << 1; + if (incr > mask) + incr = incr ^ code_poly; + } +} + +static const _PyUnicode_Name_CAPI hashAPI = +{ + sizeof(_PyUnicode_Name_CAPI), + _getucname, + _getcode +}; + +/* -------------------------------------------------------------------- */ +/* Python bindings */ + +/*[clinic input] +unicodedata.UCD.name + + self: self + chr: int(accept={str}) + default: object=NULL + / + +Returns the name assigned to the character chr as a string. + +If no name is defined, default is returned, or, if not given, +ValueError is raised. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value) +/*[clinic end generated code: output=6bbb37a326407707 input=3e0367f534de56d9]*/ +{ + char name[NAME_MAXLEN+1]; + Py_UCS4 c = (Py_UCS4)chr; + + if (!_getucname(self, c, name, NAME_MAXLEN, 0)) { + if (default_value == NULL) { + PyErr_SetString(PyExc_ValueError, "no such name"); + return NULL; + } + else { + Py_INCREF(default_value); + return default_value; + } + } + + return PyUnicode_FromString(name); +} + +/*[clinic input] +unicodedata.UCD.lookup + + self: self + name: str(accept={str, robuffer}, zeroes=True) + / + +Look up character by name. + +If a character with the given name is found, return the +corresponding character. If not found, KeyError is raised. +[clinic start generated code]*/ + +static PyObject * +unicodedata_UCD_lookup_impl(PyObject *self, const char *name, + Py_ssize_clean_t name_length) +/*[clinic end generated code: output=765cb8186788e6be input=a557be0f8607a0d6]*/ +{ + Py_UCS4 code; + unsigned int index; + if (name_length > NAME_MAXLEN) { + PyErr_SetString(PyExc_KeyError, "name too long"); + return NULL; + } + + if (!_getcode(self, name, (int)name_length, &code, 1)) { + PyErr_Format(PyExc_KeyError, "undefined character name '%s'", name); + return NULL; + } + /* check if code is in the PUA range that we use for named sequences + and convert it */ + if (IS_NAMED_SEQ(code)) { + index = code-named_sequences_start; + return PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, + named_sequences[index].seq, + named_sequences[index].seqlen); + } + return PyUnicode_FromOrdinal(code); +} + +/* XXX Add doc strings. */ + +static PyMethodDef unicodedata_functions[] = { + UNICODEDATA_UCD_DECIMAL_METHODDEF + UNICODEDATA_UCD_DIGIT_METHODDEF + UNICODEDATA_UCD_NUMERIC_METHODDEF + UNICODEDATA_UCD_CATEGORY_METHODDEF + UNICODEDATA_UCD_BIDIRECTIONAL_METHODDEF + UNICODEDATA_UCD_COMBINING_METHODDEF + UNICODEDATA_UCD_MIRRORED_METHODDEF + UNICODEDATA_UCD_EAST_ASIAN_WIDTH_METHODDEF + UNICODEDATA_UCD_DECOMPOSITION_METHODDEF + UNICODEDATA_UCD_NAME_METHODDEF + UNICODEDATA_UCD_LOOKUP_METHODDEF UNICODEDATA_UCD_IS_NORMALIZED_METHODDEF - UNICODEDATA_UCD_NORMALIZE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyTypeObject UCD_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(NULL, 0) - "unicodedata.UCD", /*tp_name*/ - sizeof(PreviousDBVersion), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PyObject_Del, /*tp_dealloc*/ + UNICODEDATA_UCD_NORMALIZE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject UCD_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(NULL, 0) + "unicodedata.UCD", /*tp_name*/ + sizeof(PreviousDBVersion), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PyObject_Del, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - PyObject_GenericGetAttr,/*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - unicodedata_functions, /*tp_methods*/ - DB_members, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - 0, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ -}; - -PyDoc_STRVAR(unicodedata_docstring, -"This module provides access to the Unicode Character Database which\n\ -defines character properties for all Unicode characters. The data in\n\ -this database is based on the UnicodeData.txt file version\n\ -" UNIDATA_VERSION " which is publicly available from ftp://ftp.unicode.org/.\n\ -\n\ -The module uses the same names and symbols as defined by the\n\ -UnicodeData File Format " UNIDATA_VERSION "."); - -static struct PyModuleDef unicodedatamodule = { - PyModuleDef_HEAD_INIT, - "unicodedata", - unicodedata_docstring, - -1, - unicodedata_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_unicodedata(void) -{ - PyObject *m, *v; - + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr,/*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + unicodedata_functions, /*tp_methods*/ + DB_members, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +PyDoc_STRVAR(unicodedata_docstring, +"This module provides access to the Unicode Character Database which\n\ +defines character properties for all Unicode characters. The data in\n\ +this database is based on the UnicodeData.txt file version\n\ +" UNIDATA_VERSION " which is publicly available from ftp://ftp.unicode.org/.\n\ +\n\ +The module uses the same names and symbols as defined by the\n\ +UnicodeData File Format " UNIDATA_VERSION "."); + +static struct PyModuleDef unicodedatamodule = { + PyModuleDef_HEAD_INIT, + "unicodedata", + unicodedata_docstring, + -1, + unicodedata_functions, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_unicodedata(void) +{ + PyObject *m, *v; + Py_SET_TYPE(&UCD_Type, &PyType_Type); - - m = PyModule_Create(&unicodedatamodule); - if (!m) - return NULL; - - PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION); - Py_INCREF(&UCD_Type); - PyModule_AddObject(m, "UCD", (PyObject*)&UCD_Type); - - /* Previous versions */ - v = new_previous_version("3.2.0", get_change_3_2_0, normalization_3_2_0); - if (v != NULL) - PyModule_AddObject(m, "ucd_3_2_0", v); - - /* Export C API */ - v = PyCapsule_New((void *)&hashAPI, PyUnicodeData_CAPSULE_NAME, NULL); - if (v != NULL) - PyModule_AddObject(m, "ucnhash_CAPI", v); - return m; -} - -/* -Local variables: -c-basic-offset: 4 -indent-tabs-mode: nil -End: -*/ + + m = PyModule_Create(&unicodedatamodule); + if (!m) + return NULL; + + PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION); + Py_INCREF(&UCD_Type); + PyModule_AddObject(m, "UCD", (PyObject*)&UCD_Type); + + /* Previous versions */ + v = new_previous_version("3.2.0", get_change_3_2_0, normalization_3_2_0); + if (v != NULL) + PyModule_AddObject(m, "ucd_3_2_0", v); + + /* Export C API */ + v = PyCapsule_New((void *)&hashAPI, PyUnicodeData_CAPSULE_NAME, NULL); + if (v != NULL) + PyModule_AddObject(m, "ucnhash_CAPI", v); + return m; +} + +/* +Local variables: +c-basic-offset: 4 +indent-tabs-mode: nil +End: +*/ diff --git a/contrib/tools/python3/src/Modules/unicodedata_db.h b/contrib/tools/python3/src/Modules/unicodedata_db.h index da938761563..6596c938813 100644 --- a/contrib/tools/python3/src/Modules/unicodedata_db.h +++ b/contrib/tools/python3/src/Modules/unicodedata_db.h @@ -1,772 +1,772 @@ /* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ - + #define UNIDATA_VERSION "13.0.0" -/* a list of unique database records */ -const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { - {0, 0, 0, 0, 0, 0}, - {13, 0, 15, 0, 5, 0}, - {13, 0, 17, 0, 5, 0}, - {13, 0, 16, 0, 5, 0}, - {13, 0, 18, 0, 5, 0}, - {10, 0, 18, 0, 3, 0}, - {26, 0, 19, 0, 3, 0}, - {26, 0, 11, 0, 3, 0}, - {28, 0, 11, 0, 3, 0}, - {22, 0, 19, 1, 3, 0}, - {23, 0, 19, 1, 3, 0}, - {27, 0, 10, 0, 3, 0}, - {26, 0, 13, 0, 3, 0}, - {21, 0, 10, 0, 3, 0}, - {7, 0, 9, 0, 3, 0}, - {27, 0, 19, 1, 3, 0}, - {27, 0, 19, 0, 3, 0}, - {1, 0, 1, 0, 3, 0}, - {29, 0, 19, 0, 3, 0}, - {20, 0, 19, 0, 3, 0}, - {2, 0, 1, 0, 3, 0}, - {10, 0, 13, 0, 5, 136}, - {26, 0, 19, 0, 4, 0}, - {28, 0, 11, 0, 4, 0}, - {30, 0, 19, 0, 3, 0}, - {29, 0, 19, 0, 4, 136}, - {30, 0, 19, 0, 5, 0}, - {19, 0, 1, 0, 4, 136}, - {24, 0, 19, 1, 5, 0}, - {14, 0, 15, 0, 4, 0}, - {30, 0, 19, 0, 4, 0}, - {29, 0, 19, 0, 3, 136}, - {30, 0, 11, 0, 4, 0}, - {27, 0, 11, 0, 4, 0}, - {9, 0, 9, 0, 4, 136}, - {2, 0, 1, 0, 5, 136}, - {25, 0, 19, 1, 5, 0}, - {9, 0, 19, 0, 4, 136}, - {1, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 4, 0}, - {27, 0, 19, 0, 4, 0}, - {2, 0, 1, 0, 4, 0}, - {2, 0, 1, 0, 4, 10}, - {2, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 5, 0}, - {1, 0, 1, 0, 4, 136}, - {2, 0, 1, 0, 4, 136}, - {2, 0, 1, 0, 5, 0}, - {19, 0, 1, 0, 5, 0}, - {1, 0, 1, 0, 5, 136}, - {3, 0, 1, 0, 5, 136}, - {18, 0, 1, 0, 5, 136}, - {18, 0, 19, 0, 5, 0}, - {18, 0, 1, 0, 5, 0}, - {29, 0, 19, 0, 5, 0}, - {29, 0, 19, 0, 4, 0}, - {18, 0, 19, 0, 4, 0}, - {18, 0, 1, 0, 4, 0}, - {29, 0, 19, 0, 5, 136}, - {4, 230, 14, 0, 4, 80}, - {4, 230, 14, 0, 4, 0}, - {4, 232, 14, 0, 4, 0}, - {4, 220, 14, 0, 4, 0}, - {4, 216, 14, 0, 4, 80}, - {4, 202, 14, 0, 4, 0}, - {4, 220, 14, 0, 4, 80}, - {4, 202, 14, 0, 4, 80}, - {4, 1, 14, 0, 4, 0}, - {4, 1, 14, 0, 4, 80}, - {4, 230, 14, 0, 4, 170}, - {4, 240, 14, 0, 4, 80}, - {4, 0, 14, 0, 4, 0}, - {4, 233, 14, 0, 4, 0}, - {4, 234, 14, 0, 4, 0}, - {18, 0, 19, 0, 5, 170}, - {26, 0, 19, 0, 5, 170}, - {29, 0, 19, 0, 5, 138}, - {1, 0, 1, 0, 5, 138}, - {27, 0, 19, 0, 5, 0}, - {1, 0, 1, 0, 4, 10}, - {30, 0, 1, 0, 5, 0}, - {4, 230, 14, 0, 5, 0}, - {6, 0, 14, 0, 5, 0}, - {26, 0, 1, 0, 5, 0}, - {21, 0, 19, 0, 5, 0}, - {28, 0, 11, 0, 5, 0}, - {4, 220, 14, 0, 5, 0}, - {4, 222, 14, 0, 5, 0}, - {4, 228, 14, 0, 5, 0}, - {4, 10, 14, 0, 5, 0}, - {4, 11, 14, 0, 5, 0}, - {4, 12, 14, 0, 5, 0}, - {4, 13, 14, 0, 5, 0}, - {4, 14, 14, 0, 5, 0}, - {4, 15, 14, 0, 5, 0}, - {4, 16, 14, 0, 5, 0}, - {4, 17, 14, 0, 5, 0}, - {4, 18, 14, 0, 5, 0}, - {4, 19, 14, 0, 5, 0}, - {4, 20, 14, 0, 5, 0}, - {4, 21, 14, 0, 5, 0}, - {4, 22, 14, 0, 5, 0}, - {21, 0, 4, 0, 5, 0}, - {4, 23, 14, 0, 5, 0}, - {26, 0, 4, 0, 5, 0}, - {4, 24, 14, 0, 5, 0}, - {4, 25, 14, 0, 5, 0}, - {19, 0, 4, 0, 5, 0}, - {14, 0, 12, 0, 5, 0}, - {27, 0, 5, 0, 5, 0}, - {26, 0, 11, 0, 5, 0}, - {28, 0, 5, 0, 5, 0}, - {26, 0, 13, 0, 5, 0}, - {26, 0, 5, 0, 5, 0}, - {4, 30, 14, 0, 5, 0}, - {4, 31, 14, 0, 5, 0}, - {4, 32, 14, 0, 5, 0}, - {14, 0, 5, 0, 5, 0}, - {19, 0, 5, 0, 5, 0}, - {19, 0, 5, 0, 5, 10}, - {18, 0, 5, 0, 5, 0}, - {4, 27, 14, 0, 5, 0}, - {4, 28, 14, 0, 5, 0}, - {4, 29, 14, 0, 5, 0}, - {4, 33, 14, 0, 5, 0}, - {4, 34, 14, 0, 5, 0}, - {4, 230, 14, 0, 5, 80}, - {4, 220, 14, 0, 5, 80}, - {7, 0, 12, 0, 5, 0}, - {26, 0, 12, 0, 5, 0}, - {4, 35, 14, 0, 5, 0}, - {19, 0, 5, 0, 5, 136}, - {7, 0, 9, 0, 5, 0}, - {30, 0, 5, 0, 5, 0}, - {4, 36, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 0}, - {7, 0, 4, 0, 5, 0}, - {18, 0, 4, 0, 5, 0}, - {26, 0, 19, 0, 5, 0}, - {28, 0, 4, 0, 5, 0}, - {5, 0, 1, 0, 5, 0}, - {19, 0, 1, 0, 5, 10}, - {4, 7, 14, 0, 5, 80}, - {4, 9, 14, 0, 5, 0}, - {19, 0, 1, 0, 5, 170}, - {7, 0, 1, 0, 5, 0}, - {4, 7, 14, 0, 5, 0}, - {5, 0, 1, 0, 5, 80}, - {5, 0, 1, 0, 5, 10}, - {9, 0, 1, 0, 5, 0}, - {4, 0, 14, 0, 5, 80}, - {4, 0, 14, 0, 5, 10}, - {4, 84, 14, 0, 5, 0}, - {4, 91, 14, 0, 5, 80}, - {9, 0, 19, 0, 5, 0}, - {4, 0, 1, 0, 5, 0}, - {4, 9, 14, 0, 5, 80}, - {19, 0, 1, 0, 5, 136}, - {4, 103, 14, 0, 5, 0}, - {4, 107, 14, 0, 5, 0}, - {4, 118, 14, 0, 5, 0}, - {4, 122, 14, 0, 5, 0}, - {26, 0, 1, 0, 5, 136}, - {4, 216, 14, 0, 5, 0}, - {22, 0, 19, 1, 5, 0}, - {23, 0, 19, 1, 5, 0}, - {4, 129, 14, 0, 5, 0}, - {4, 130, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 170}, - {4, 132, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 136}, - {19, 0, 1, 0, 2, 0}, - {19, 0, 1, 0, 5, 80}, - {10, 0, 18, 0, 5, 0}, - {8, 0, 1, 0, 5, 0}, - {14, 0, 15, 0, 5, 0}, - {5, 9, 1, 0, 5, 0}, - {4, 1, 14, 0, 5, 0}, - {4, 234, 14, 0, 5, 0}, - {4, 214, 14, 0, 5, 0}, - {4, 202, 14, 0, 5, 0}, - {4, 232, 14, 0, 5, 0}, - {4, 233, 14, 0, 5, 0}, - {2, 0, 1, 0, 5, 138}, - {2, 0, 1, 0, 5, 170}, - {3, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 5, 170}, - {29, 0, 19, 0, 5, 170}, - {10, 0, 18, 0, 5, 170}, - {10, 0, 18, 0, 5, 136}, - {14, 0, 1, 0, 5, 0}, - {14, 0, 4, 0, 5, 0}, - {21, 0, 19, 0, 4, 0}, - {21, 0, 19, 0, 5, 136}, - {26, 0, 19, 0, 5, 136}, - {24, 0, 19, 0, 4, 0}, - {25, 0, 19, 0, 4, 0}, - {22, 0, 19, 0, 5, 0}, - {24, 0, 19, 0, 5, 0}, - {26, 0, 19, 0, 4, 136}, - {11, 0, 18, 0, 5, 0}, - {12, 0, 16, 0, 5, 0}, - {14, 0, 2, 0, 5, 0}, - {14, 0, 6, 0, 5, 0}, - {14, 0, 8, 0, 5, 0}, - {14, 0, 3, 0, 5, 0}, - {14, 0, 7, 0, 5, 0}, - {26, 0, 11, 0, 4, 0}, - {26, 0, 11, 0, 4, 136}, - {26, 0, 11, 0, 5, 136}, - {20, 0, 19, 0, 5, 0}, - {27, 0, 13, 0, 5, 0}, - {14, 0, 20, 0, 5, 0}, - {14, 0, 21, 0, 5, 0}, - {14, 0, 22, 0, 5, 0}, - {14, 0, 23, 0, 5, 0}, - {9, 0, 9, 0, 5, 136}, - {27, 0, 10, 0, 5, 136}, - {27, 0, 19, 0, 5, 136}, - {22, 0, 19, 1, 5, 136}, - {23, 0, 19, 1, 5, 136}, - {18, 0, 1, 0, 4, 136}, - {28, 0, 11, 0, 5, 136}, - {28, 0, 11, 0, 1, 0}, - {30, 0, 19, 0, 5, 136}, - {30, 0, 19, 0, 4, 136}, - {1, 0, 1, 0, 4, 170}, - {30, 0, 11, 0, 5, 0}, - {27, 0, 19, 1, 5, 136}, - {9, 0, 19, 0, 5, 136}, - {8, 0, 1, 0, 4, 136}, - {8, 0, 1, 0, 5, 136}, - {27, 0, 19, 0, 5, 10}, - {30, 0, 19, 0, 5, 10}, - {27, 0, 19, 1, 5, 0}, - {27, 0, 19, 1, 4, 0}, - {27, 0, 19, 1, 5, 10}, - {27, 0, 10, 0, 5, 0}, - {27, 0, 11, 0, 5, 0}, - {27, 0, 19, 1, 4, 136}, - {27, 0, 19, 1, 4, 10}, - {30, 0, 19, 0, 2, 0}, - {22, 0, 19, 1, 2, 170}, - {23, 0, 19, 1, 2, 170}, - {30, 0, 1, 0, 4, 136}, - {9, 0, 19, 0, 4, 0}, - {27, 0, 19, 0, 2, 0}, - {27, 0, 19, 1, 5, 170}, - {30, 0, 19, 1, 5, 0}, - {30, 0, 19, 0, 2, 136}, - {10, 0, 18, 0, 0, 136}, - {26, 0, 19, 0, 2, 0}, - {18, 0, 1, 0, 2, 0}, - {8, 0, 1, 0, 2, 0}, - {22, 0, 19, 1, 2, 0}, - {23, 0, 19, 1, 2, 0}, - {21, 0, 19, 0, 2, 0}, - {22, 0, 19, 0, 2, 0}, - {23, 0, 19, 0, 2, 0}, - {4, 218, 14, 0, 2, 0}, - {4, 228, 14, 0, 2, 0}, - {4, 232, 14, 0, 2, 0}, - {4, 222, 14, 0, 2, 0}, - {5, 224, 1, 0, 2, 0}, - {8, 0, 1, 0, 2, 136}, - {19, 0, 1, 0, 2, 10}, - {4, 8, 14, 0, 2, 80}, - {29, 0, 19, 0, 2, 136}, - {18, 0, 1, 0, 2, 10}, - {19, 0, 1, 0, 2, 136}, - {30, 0, 1, 0, 2, 0}, - {9, 0, 1, 0, 2, 136}, - {30, 0, 1, 0, 2, 136}, - {9, 0, 1, 0, 4, 0}, - {9, 0, 19, 0, 2, 136}, - {29, 0, 1, 0, 5, 0}, - {15, 0, 1, 0, 5, 0}, - {16, 0, 1, 0, 4, 0}, - {19, 0, 1, 0, 2, 170}, - {19, 0, 4, 0, 5, 170}, - {4, 26, 14, 0, 5, 0}, - {19, 0, 4, 0, 5, 136}, - {29, 0, 5, 0, 5, 0}, - {23, 0, 19, 0, 5, 0}, - {28, 0, 5, 0, 5, 136}, - {26, 0, 19, 0, 2, 136}, - {22, 0, 19, 0, 2, 136}, - {23, 0, 19, 0, 2, 136}, - {21, 0, 19, 0, 2, 136}, - {20, 0, 19, 0, 2, 136}, - {26, 0, 13, 0, 2, 136}, - {22, 0, 19, 1, 2, 136}, - {23, 0, 19, 1, 2, 136}, - {26, 0, 11, 0, 2, 136}, - {27, 0, 10, 0, 2, 136}, - {21, 0, 10, 0, 2, 136}, - {27, 0, 19, 1, 2, 136}, - {27, 0, 19, 0, 2, 136}, - {28, 0, 11, 0, 2, 136}, - {26, 0, 19, 0, 0, 136}, - {26, 0, 11, 0, 0, 136}, - {28, 0, 11, 0, 0, 136}, - {22, 0, 19, 1, 0, 136}, - {23, 0, 19, 1, 0, 136}, - {27, 0, 10, 0, 0, 136}, - {26, 0, 13, 0, 0, 136}, - {21, 0, 10, 0, 0, 136}, - {7, 0, 9, 0, 0, 136}, - {27, 0, 19, 1, 0, 136}, - {27, 0, 19, 0, 0, 136}, - {1, 0, 1, 0, 0, 136}, - {29, 0, 19, 0, 0, 136}, - {20, 0, 19, 0, 0, 136}, - {2, 0, 1, 0, 0, 136}, - {26, 0, 19, 0, 1, 136}, - {22, 0, 19, 1, 1, 136}, - {23, 0, 19, 1, 1, 136}, - {19, 0, 1, 0, 1, 136}, - {18, 0, 1, 0, 1, 136}, - {30, 0, 19, 0, 0, 136}, - {30, 0, 19, 0, 1, 136}, - {27, 0, 19, 0, 1, 136}, - {14, 0, 19, 0, 5, 0}, - {8, 0, 19, 0, 5, 0}, - {9, 0, 9, 0, 5, 0}, - {9, 0, 4, 0, 5, 0}, - {30, 0, 4, 0, 5, 0}, - {1, 0, 4, 0, 5, 0}, - {2, 0, 4, 0, 5, 0}, - {9, 0, 12, 0, 5, 0}, - {9, 0, 5, 0, 5, 0}, - {4, 9, 1, 0, 5, 0}, +/* a list of unique database records */ +const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { + {0, 0, 0, 0, 0, 0}, + {13, 0, 15, 0, 5, 0}, + {13, 0, 17, 0, 5, 0}, + {13, 0, 16, 0, 5, 0}, + {13, 0, 18, 0, 5, 0}, + {10, 0, 18, 0, 3, 0}, + {26, 0, 19, 0, 3, 0}, + {26, 0, 11, 0, 3, 0}, + {28, 0, 11, 0, 3, 0}, + {22, 0, 19, 1, 3, 0}, + {23, 0, 19, 1, 3, 0}, + {27, 0, 10, 0, 3, 0}, + {26, 0, 13, 0, 3, 0}, + {21, 0, 10, 0, 3, 0}, + {7, 0, 9, 0, 3, 0}, + {27, 0, 19, 1, 3, 0}, + {27, 0, 19, 0, 3, 0}, + {1, 0, 1, 0, 3, 0}, + {29, 0, 19, 0, 3, 0}, + {20, 0, 19, 0, 3, 0}, + {2, 0, 1, 0, 3, 0}, + {10, 0, 13, 0, 5, 136}, + {26, 0, 19, 0, 4, 0}, + {28, 0, 11, 0, 4, 0}, + {30, 0, 19, 0, 3, 0}, + {29, 0, 19, 0, 4, 136}, + {30, 0, 19, 0, 5, 0}, + {19, 0, 1, 0, 4, 136}, + {24, 0, 19, 1, 5, 0}, + {14, 0, 15, 0, 4, 0}, + {30, 0, 19, 0, 4, 0}, + {29, 0, 19, 0, 3, 136}, + {30, 0, 11, 0, 4, 0}, + {27, 0, 11, 0, 4, 0}, + {9, 0, 9, 0, 4, 136}, + {2, 0, 1, 0, 5, 136}, + {25, 0, 19, 1, 5, 0}, + {9, 0, 19, 0, 4, 136}, + {1, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 4, 0}, + {27, 0, 19, 0, 4, 0}, + {2, 0, 1, 0, 4, 0}, + {2, 0, 1, 0, 4, 10}, + {2, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 5, 0}, + {1, 0, 1, 0, 4, 136}, + {2, 0, 1, 0, 4, 136}, + {2, 0, 1, 0, 5, 0}, + {19, 0, 1, 0, 5, 0}, + {1, 0, 1, 0, 5, 136}, + {3, 0, 1, 0, 5, 136}, + {18, 0, 1, 0, 5, 136}, + {18, 0, 19, 0, 5, 0}, + {18, 0, 1, 0, 5, 0}, + {29, 0, 19, 0, 5, 0}, + {29, 0, 19, 0, 4, 0}, + {18, 0, 19, 0, 4, 0}, + {18, 0, 1, 0, 4, 0}, + {29, 0, 19, 0, 5, 136}, + {4, 230, 14, 0, 4, 80}, + {4, 230, 14, 0, 4, 0}, + {4, 232, 14, 0, 4, 0}, + {4, 220, 14, 0, 4, 0}, + {4, 216, 14, 0, 4, 80}, + {4, 202, 14, 0, 4, 0}, + {4, 220, 14, 0, 4, 80}, + {4, 202, 14, 0, 4, 80}, + {4, 1, 14, 0, 4, 0}, + {4, 1, 14, 0, 4, 80}, + {4, 230, 14, 0, 4, 170}, + {4, 240, 14, 0, 4, 80}, + {4, 0, 14, 0, 4, 0}, + {4, 233, 14, 0, 4, 0}, + {4, 234, 14, 0, 4, 0}, + {18, 0, 19, 0, 5, 170}, + {26, 0, 19, 0, 5, 170}, + {29, 0, 19, 0, 5, 138}, + {1, 0, 1, 0, 5, 138}, + {27, 0, 19, 0, 5, 0}, + {1, 0, 1, 0, 4, 10}, + {30, 0, 1, 0, 5, 0}, + {4, 230, 14, 0, 5, 0}, + {6, 0, 14, 0, 5, 0}, + {26, 0, 1, 0, 5, 0}, + {21, 0, 19, 0, 5, 0}, + {28, 0, 11, 0, 5, 0}, + {4, 220, 14, 0, 5, 0}, + {4, 222, 14, 0, 5, 0}, + {4, 228, 14, 0, 5, 0}, + {4, 10, 14, 0, 5, 0}, + {4, 11, 14, 0, 5, 0}, + {4, 12, 14, 0, 5, 0}, + {4, 13, 14, 0, 5, 0}, + {4, 14, 14, 0, 5, 0}, + {4, 15, 14, 0, 5, 0}, + {4, 16, 14, 0, 5, 0}, + {4, 17, 14, 0, 5, 0}, + {4, 18, 14, 0, 5, 0}, + {4, 19, 14, 0, 5, 0}, + {4, 20, 14, 0, 5, 0}, + {4, 21, 14, 0, 5, 0}, + {4, 22, 14, 0, 5, 0}, + {21, 0, 4, 0, 5, 0}, + {4, 23, 14, 0, 5, 0}, + {26, 0, 4, 0, 5, 0}, + {4, 24, 14, 0, 5, 0}, + {4, 25, 14, 0, 5, 0}, + {19, 0, 4, 0, 5, 0}, + {14, 0, 12, 0, 5, 0}, + {27, 0, 5, 0, 5, 0}, + {26, 0, 11, 0, 5, 0}, + {28, 0, 5, 0, 5, 0}, + {26, 0, 13, 0, 5, 0}, + {26, 0, 5, 0, 5, 0}, + {4, 30, 14, 0, 5, 0}, + {4, 31, 14, 0, 5, 0}, + {4, 32, 14, 0, 5, 0}, + {14, 0, 5, 0, 5, 0}, + {19, 0, 5, 0, 5, 0}, + {19, 0, 5, 0, 5, 10}, + {18, 0, 5, 0, 5, 0}, + {4, 27, 14, 0, 5, 0}, + {4, 28, 14, 0, 5, 0}, + {4, 29, 14, 0, 5, 0}, + {4, 33, 14, 0, 5, 0}, + {4, 34, 14, 0, 5, 0}, + {4, 230, 14, 0, 5, 80}, + {4, 220, 14, 0, 5, 80}, + {7, 0, 12, 0, 5, 0}, + {26, 0, 12, 0, 5, 0}, + {4, 35, 14, 0, 5, 0}, + {19, 0, 5, 0, 5, 136}, + {7, 0, 9, 0, 5, 0}, + {30, 0, 5, 0, 5, 0}, + {4, 36, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 0}, + {7, 0, 4, 0, 5, 0}, + {18, 0, 4, 0, 5, 0}, + {26, 0, 19, 0, 5, 0}, + {28, 0, 4, 0, 5, 0}, + {5, 0, 1, 0, 5, 0}, + {19, 0, 1, 0, 5, 10}, + {4, 7, 14, 0, 5, 80}, + {4, 9, 14, 0, 5, 0}, + {19, 0, 1, 0, 5, 170}, + {7, 0, 1, 0, 5, 0}, + {4, 7, 14, 0, 5, 0}, + {5, 0, 1, 0, 5, 80}, + {5, 0, 1, 0, 5, 10}, + {9, 0, 1, 0, 5, 0}, + {4, 0, 14, 0, 5, 80}, + {4, 0, 14, 0, 5, 10}, + {4, 84, 14, 0, 5, 0}, + {4, 91, 14, 0, 5, 80}, + {9, 0, 19, 0, 5, 0}, + {4, 0, 1, 0, 5, 0}, + {4, 9, 14, 0, 5, 80}, + {19, 0, 1, 0, 5, 136}, + {4, 103, 14, 0, 5, 0}, + {4, 107, 14, 0, 5, 0}, + {4, 118, 14, 0, 5, 0}, + {4, 122, 14, 0, 5, 0}, + {26, 0, 1, 0, 5, 136}, + {4, 216, 14, 0, 5, 0}, + {22, 0, 19, 1, 5, 0}, + {23, 0, 19, 1, 5, 0}, + {4, 129, 14, 0, 5, 0}, + {4, 130, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 170}, + {4, 132, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 136}, + {19, 0, 1, 0, 2, 0}, + {19, 0, 1, 0, 5, 80}, + {10, 0, 18, 0, 5, 0}, + {8, 0, 1, 0, 5, 0}, + {14, 0, 15, 0, 5, 0}, + {5, 9, 1, 0, 5, 0}, + {4, 1, 14, 0, 5, 0}, + {4, 234, 14, 0, 5, 0}, + {4, 214, 14, 0, 5, 0}, + {4, 202, 14, 0, 5, 0}, + {4, 232, 14, 0, 5, 0}, + {4, 233, 14, 0, 5, 0}, + {2, 0, 1, 0, 5, 138}, + {2, 0, 1, 0, 5, 170}, + {3, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 5, 170}, + {29, 0, 19, 0, 5, 170}, + {10, 0, 18, 0, 5, 170}, + {10, 0, 18, 0, 5, 136}, + {14, 0, 1, 0, 5, 0}, + {14, 0, 4, 0, 5, 0}, + {21, 0, 19, 0, 4, 0}, + {21, 0, 19, 0, 5, 136}, + {26, 0, 19, 0, 5, 136}, + {24, 0, 19, 0, 4, 0}, + {25, 0, 19, 0, 4, 0}, + {22, 0, 19, 0, 5, 0}, + {24, 0, 19, 0, 5, 0}, + {26, 0, 19, 0, 4, 136}, + {11, 0, 18, 0, 5, 0}, + {12, 0, 16, 0, 5, 0}, + {14, 0, 2, 0, 5, 0}, + {14, 0, 6, 0, 5, 0}, + {14, 0, 8, 0, 5, 0}, + {14, 0, 3, 0, 5, 0}, + {14, 0, 7, 0, 5, 0}, + {26, 0, 11, 0, 4, 0}, + {26, 0, 11, 0, 4, 136}, + {26, 0, 11, 0, 5, 136}, + {20, 0, 19, 0, 5, 0}, + {27, 0, 13, 0, 5, 0}, + {14, 0, 20, 0, 5, 0}, + {14, 0, 21, 0, 5, 0}, + {14, 0, 22, 0, 5, 0}, + {14, 0, 23, 0, 5, 0}, + {9, 0, 9, 0, 5, 136}, + {27, 0, 10, 0, 5, 136}, + {27, 0, 19, 0, 5, 136}, + {22, 0, 19, 1, 5, 136}, + {23, 0, 19, 1, 5, 136}, + {18, 0, 1, 0, 4, 136}, + {28, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 1, 0}, + {30, 0, 19, 0, 5, 136}, + {30, 0, 19, 0, 4, 136}, + {1, 0, 1, 0, 4, 170}, + {30, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 5, 136}, + {9, 0, 19, 0, 5, 136}, + {8, 0, 1, 0, 4, 136}, + {8, 0, 1, 0, 5, 136}, + {27, 0, 19, 0, 5, 10}, + {30, 0, 19, 0, 5, 10}, + {27, 0, 19, 1, 5, 0}, + {27, 0, 19, 1, 4, 0}, + {27, 0, 19, 1, 5, 10}, + {27, 0, 10, 0, 5, 0}, + {27, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 4, 136}, + {27, 0, 19, 1, 4, 10}, + {30, 0, 19, 0, 2, 0}, + {22, 0, 19, 1, 2, 170}, + {23, 0, 19, 1, 2, 170}, + {30, 0, 1, 0, 4, 136}, + {9, 0, 19, 0, 4, 0}, + {27, 0, 19, 0, 2, 0}, + {27, 0, 19, 1, 5, 170}, + {30, 0, 19, 1, 5, 0}, + {30, 0, 19, 0, 2, 136}, + {10, 0, 18, 0, 0, 136}, + {26, 0, 19, 0, 2, 0}, + {18, 0, 1, 0, 2, 0}, + {8, 0, 1, 0, 2, 0}, + {22, 0, 19, 1, 2, 0}, + {23, 0, 19, 1, 2, 0}, + {21, 0, 19, 0, 2, 0}, + {22, 0, 19, 0, 2, 0}, + {23, 0, 19, 0, 2, 0}, + {4, 218, 14, 0, 2, 0}, + {4, 228, 14, 0, 2, 0}, + {4, 232, 14, 0, 2, 0}, + {4, 222, 14, 0, 2, 0}, + {5, 224, 1, 0, 2, 0}, + {8, 0, 1, 0, 2, 136}, + {19, 0, 1, 0, 2, 10}, + {4, 8, 14, 0, 2, 80}, + {29, 0, 19, 0, 2, 136}, + {18, 0, 1, 0, 2, 10}, + {19, 0, 1, 0, 2, 136}, + {30, 0, 1, 0, 2, 0}, + {9, 0, 1, 0, 2, 136}, + {30, 0, 1, 0, 2, 136}, + {9, 0, 1, 0, 4, 0}, + {9, 0, 19, 0, 2, 136}, + {29, 0, 1, 0, 5, 0}, + {15, 0, 1, 0, 5, 0}, + {16, 0, 1, 0, 4, 0}, + {19, 0, 1, 0, 2, 170}, + {19, 0, 4, 0, 5, 170}, + {4, 26, 14, 0, 5, 0}, + {19, 0, 4, 0, 5, 136}, + {29, 0, 5, 0, 5, 0}, + {23, 0, 19, 0, 5, 0}, + {28, 0, 5, 0, 5, 136}, + {26, 0, 19, 0, 2, 136}, + {22, 0, 19, 0, 2, 136}, + {23, 0, 19, 0, 2, 136}, + {21, 0, 19, 0, 2, 136}, + {20, 0, 19, 0, 2, 136}, + {26, 0, 13, 0, 2, 136}, + {22, 0, 19, 1, 2, 136}, + {23, 0, 19, 1, 2, 136}, + {26, 0, 11, 0, 2, 136}, + {27, 0, 10, 0, 2, 136}, + {21, 0, 10, 0, 2, 136}, + {27, 0, 19, 1, 2, 136}, + {27, 0, 19, 0, 2, 136}, + {28, 0, 11, 0, 2, 136}, + {26, 0, 19, 0, 0, 136}, + {26, 0, 11, 0, 0, 136}, + {28, 0, 11, 0, 0, 136}, + {22, 0, 19, 1, 0, 136}, + {23, 0, 19, 1, 0, 136}, + {27, 0, 10, 0, 0, 136}, + {26, 0, 13, 0, 0, 136}, + {21, 0, 10, 0, 0, 136}, + {7, 0, 9, 0, 0, 136}, + {27, 0, 19, 1, 0, 136}, + {27, 0, 19, 0, 0, 136}, + {1, 0, 1, 0, 0, 136}, + {29, 0, 19, 0, 0, 136}, + {20, 0, 19, 0, 0, 136}, + {2, 0, 1, 0, 0, 136}, + {26, 0, 19, 0, 1, 136}, + {22, 0, 19, 1, 1, 136}, + {23, 0, 19, 1, 1, 136}, + {19, 0, 1, 0, 1, 136}, + {18, 0, 1, 0, 1, 136}, + {30, 0, 19, 0, 0, 136}, + {30, 0, 19, 0, 1, 136}, + {27, 0, 19, 0, 1, 136}, + {14, 0, 19, 0, 5, 0}, + {8, 0, 19, 0, 5, 0}, + {9, 0, 9, 0, 5, 0}, + {9, 0, 4, 0, 5, 0}, + {30, 0, 4, 0, 5, 0}, + {1, 0, 4, 0, 5, 0}, + {2, 0, 4, 0, 5, 0}, + {9, 0, 12, 0, 5, 0}, + {9, 0, 5, 0, 5, 0}, + {4, 9, 1, 0, 5, 0}, {4, 0, 14, 0, 2, 0}, {5, 6, 1, 0, 2, 0}, - {30, 0, 1, 0, 5, 170}, - {5, 216, 1, 0, 5, 0}, - {5, 226, 1, 0, 5, 0}, - {27, 0, 1, 0, 5, 136}, - {7, 0, 9, 0, 5, 136}, - {30, 0, 1, 0, 5, 136}, - {30, 0, 1, 0, 4, 0}, - {29, 0, 19, 0, 2, 0}, -}; - -/* Reindexing of NFC first characters. */ + {30, 0, 1, 0, 5, 170}, + {5, 216, 1, 0, 5, 0}, + {5, 226, 1, 0, 5, 0}, + {27, 0, 1, 0, 5, 136}, + {7, 0, 9, 0, 5, 136}, + {30, 0, 1, 0, 5, 136}, + {30, 0, 1, 0, 4, 0}, + {29, 0, 19, 0, 2, 0}, +}; + +/* Reindexing of NFC first characters. */ #define TOTAL_FIRST 377 #define TOTAL_LAST 63 -struct reindex{int start;short count,index;}; -static struct reindex nfc_first[] = { - { 60, 2, 0}, - { 65, 15, 3}, - { 82, 8, 19}, - { 97, 15, 28}, - { 114, 8, 44}, - { 168, 0, 53}, - { 194, 0, 54}, - { 196, 3, 55}, - { 202, 0, 59}, - { 207, 0, 60}, - { 212, 2, 61}, - { 216, 0, 64}, - { 220, 0, 65}, - { 226, 0, 66}, - { 228, 3, 67}, - { 234, 0, 71}, - { 239, 0, 72}, - { 244, 2, 73}, - { 248, 0, 76}, - { 252, 0, 77}, - { 258, 1, 78}, - { 274, 1, 80}, - { 332, 1, 82}, - { 346, 1, 84}, - { 352, 1, 86}, - { 360, 3, 88}, - { 383, 0, 92}, - { 416, 1, 93}, - { 431, 1, 95}, - { 439, 0, 97}, - { 490, 1, 98}, - { 550, 3, 100}, - { 558, 1, 104}, - { 658, 0, 106}, - { 913, 0, 107}, - { 917, 0, 108}, - { 919, 0, 109}, - { 921, 0, 110}, - { 927, 0, 111}, - { 929, 0, 112}, - { 933, 0, 113}, - { 937, 0, 114}, - { 940, 0, 115}, - { 942, 0, 116}, - { 945, 0, 117}, - { 949, 0, 118}, - { 951, 0, 119}, - { 953, 0, 120}, - { 959, 0, 121}, - { 961, 0, 122}, - { 965, 0, 123}, - { 969, 2, 124}, - { 974, 0, 127}, - { 978, 0, 128}, - { 1030, 0, 129}, - { 1040, 0, 130}, - { 1043, 0, 131}, - { 1045, 3, 132}, - { 1050, 0, 136}, - { 1054, 0, 137}, - { 1059, 0, 138}, - { 1063, 0, 139}, - { 1067, 0, 140}, - { 1069, 0, 141}, - { 1072, 0, 142}, - { 1075, 0, 143}, - { 1077, 3, 144}, - { 1082, 0, 148}, - { 1086, 0, 149}, - { 1091, 0, 150}, - { 1095, 0, 151}, - { 1099, 0, 152}, - { 1101, 0, 153}, - { 1110, 0, 154}, - { 1140, 1, 155}, - { 1240, 1, 157}, - { 1256, 1, 159}, - { 1575, 0, 161}, - { 1608, 0, 162}, - { 1610, 0, 163}, - { 1729, 0, 164}, - { 1746, 0, 165}, - { 1749, 0, 166}, - { 2344, 0, 167}, - { 2352, 0, 168}, - { 2355, 0, 169}, - { 2503, 0, 170}, - { 2887, 0, 171}, - { 2962, 0, 172}, - { 3014, 1, 173}, - { 3142, 0, 175}, - { 3263, 0, 176}, - { 3270, 0, 177}, - { 3274, 0, 178}, - { 3398, 1, 179}, - { 3545, 0, 181}, - { 3548, 0, 182}, - { 4133, 0, 183}, - { 6917, 0, 184}, - { 6919, 0, 185}, - { 6921, 0, 186}, - { 6923, 0, 187}, - { 6925, 0, 188}, - { 6929, 0, 189}, - { 6970, 0, 190}, - { 6972, 0, 191}, - { 6974, 1, 192}, - { 6978, 0, 194}, - { 7734, 1, 195}, - { 7770, 1, 197}, - { 7778, 1, 199}, - { 7840, 1, 201}, - { 7864, 1, 203}, - { 7884, 1, 205}, - { 7936, 17, 207}, - { 7960, 1, 225}, - { 7968, 17, 227}, - { 7992, 1, 245}, - { 8000, 1, 247}, - { 8008, 1, 249}, - { 8016, 1, 251}, - { 8025, 0, 253}, - { 8032, 16, 254}, - { 8052, 0, 271}, - { 8060, 0, 272}, - { 8118, 0, 273}, - { 8127, 0, 274}, - { 8134, 0, 275}, - { 8182, 0, 276}, - { 8190, 0, 277}, - { 8592, 0, 278}, - { 8594, 0, 279}, - { 8596, 0, 280}, - { 8656, 0, 281}, - { 8658, 0, 282}, - { 8660, 0, 283}, - { 8707, 0, 284}, - { 8712, 0, 285}, - { 8715, 0, 286}, - { 8739, 0, 287}, - { 8741, 0, 288}, - { 8764, 0, 289}, - { 8771, 0, 290}, - { 8773, 0, 291}, - { 8776, 0, 292}, - { 8781, 0, 293}, - { 8801, 0, 294}, - { 8804, 1, 295}, - { 8818, 1, 297}, - { 8822, 1, 299}, - { 8826, 3, 301}, - { 8834, 1, 305}, - { 8838, 1, 307}, - { 8849, 1, 309}, - { 8866, 0, 311}, - { 8872, 1, 312}, - { 8875, 0, 314}, - { 8882, 3, 315}, - { 12358, 0, 319}, - { 12363, 0, 320}, - { 12365, 0, 321}, - { 12367, 0, 322}, - { 12369, 0, 323}, - { 12371, 0, 324}, - { 12373, 0, 325}, - { 12375, 0, 326}, - { 12377, 0, 327}, - { 12379, 0, 328}, - { 12381, 0, 329}, - { 12383, 0, 330}, - { 12385, 0, 331}, - { 12388, 0, 332}, - { 12390, 0, 333}, - { 12392, 0, 334}, - { 12399, 0, 335}, - { 12402, 0, 336}, - { 12405, 0, 337}, - { 12408, 0, 338}, - { 12411, 0, 339}, - { 12445, 0, 340}, - { 12454, 0, 341}, - { 12459, 0, 342}, - { 12461, 0, 343}, - { 12463, 0, 344}, - { 12465, 0, 345}, - { 12467, 0, 346}, - { 12469, 0, 347}, - { 12471, 0, 348}, - { 12473, 0, 349}, - { 12475, 0, 350}, - { 12477, 0, 351}, - { 12479, 0, 352}, - { 12481, 0, 353}, - { 12484, 0, 354}, - { 12486, 0, 355}, - { 12488, 0, 356}, - { 12495, 0, 357}, - { 12498, 0, 358}, - { 12501, 0, 359}, - { 12504, 0, 360}, - { 12507, 0, 361}, - { 12527, 3, 362}, - { 12541, 0, 366}, - { 69785, 0, 367}, - { 69787, 0, 368}, - { 69797, 0, 369}, - { 69937, 1, 370}, - { 70471, 0, 372}, - { 70841, 0, 373}, - { 71096, 1, 374}, +struct reindex{int start;short count,index;}; +static struct reindex nfc_first[] = { + { 60, 2, 0}, + { 65, 15, 3}, + { 82, 8, 19}, + { 97, 15, 28}, + { 114, 8, 44}, + { 168, 0, 53}, + { 194, 0, 54}, + { 196, 3, 55}, + { 202, 0, 59}, + { 207, 0, 60}, + { 212, 2, 61}, + { 216, 0, 64}, + { 220, 0, 65}, + { 226, 0, 66}, + { 228, 3, 67}, + { 234, 0, 71}, + { 239, 0, 72}, + { 244, 2, 73}, + { 248, 0, 76}, + { 252, 0, 77}, + { 258, 1, 78}, + { 274, 1, 80}, + { 332, 1, 82}, + { 346, 1, 84}, + { 352, 1, 86}, + { 360, 3, 88}, + { 383, 0, 92}, + { 416, 1, 93}, + { 431, 1, 95}, + { 439, 0, 97}, + { 490, 1, 98}, + { 550, 3, 100}, + { 558, 1, 104}, + { 658, 0, 106}, + { 913, 0, 107}, + { 917, 0, 108}, + { 919, 0, 109}, + { 921, 0, 110}, + { 927, 0, 111}, + { 929, 0, 112}, + { 933, 0, 113}, + { 937, 0, 114}, + { 940, 0, 115}, + { 942, 0, 116}, + { 945, 0, 117}, + { 949, 0, 118}, + { 951, 0, 119}, + { 953, 0, 120}, + { 959, 0, 121}, + { 961, 0, 122}, + { 965, 0, 123}, + { 969, 2, 124}, + { 974, 0, 127}, + { 978, 0, 128}, + { 1030, 0, 129}, + { 1040, 0, 130}, + { 1043, 0, 131}, + { 1045, 3, 132}, + { 1050, 0, 136}, + { 1054, 0, 137}, + { 1059, 0, 138}, + { 1063, 0, 139}, + { 1067, 0, 140}, + { 1069, 0, 141}, + { 1072, 0, 142}, + { 1075, 0, 143}, + { 1077, 3, 144}, + { 1082, 0, 148}, + { 1086, 0, 149}, + { 1091, 0, 150}, + { 1095, 0, 151}, + { 1099, 0, 152}, + { 1101, 0, 153}, + { 1110, 0, 154}, + { 1140, 1, 155}, + { 1240, 1, 157}, + { 1256, 1, 159}, + { 1575, 0, 161}, + { 1608, 0, 162}, + { 1610, 0, 163}, + { 1729, 0, 164}, + { 1746, 0, 165}, + { 1749, 0, 166}, + { 2344, 0, 167}, + { 2352, 0, 168}, + { 2355, 0, 169}, + { 2503, 0, 170}, + { 2887, 0, 171}, + { 2962, 0, 172}, + { 3014, 1, 173}, + { 3142, 0, 175}, + { 3263, 0, 176}, + { 3270, 0, 177}, + { 3274, 0, 178}, + { 3398, 1, 179}, + { 3545, 0, 181}, + { 3548, 0, 182}, + { 4133, 0, 183}, + { 6917, 0, 184}, + { 6919, 0, 185}, + { 6921, 0, 186}, + { 6923, 0, 187}, + { 6925, 0, 188}, + { 6929, 0, 189}, + { 6970, 0, 190}, + { 6972, 0, 191}, + { 6974, 1, 192}, + { 6978, 0, 194}, + { 7734, 1, 195}, + { 7770, 1, 197}, + { 7778, 1, 199}, + { 7840, 1, 201}, + { 7864, 1, 203}, + { 7884, 1, 205}, + { 7936, 17, 207}, + { 7960, 1, 225}, + { 7968, 17, 227}, + { 7992, 1, 245}, + { 8000, 1, 247}, + { 8008, 1, 249}, + { 8016, 1, 251}, + { 8025, 0, 253}, + { 8032, 16, 254}, + { 8052, 0, 271}, + { 8060, 0, 272}, + { 8118, 0, 273}, + { 8127, 0, 274}, + { 8134, 0, 275}, + { 8182, 0, 276}, + { 8190, 0, 277}, + { 8592, 0, 278}, + { 8594, 0, 279}, + { 8596, 0, 280}, + { 8656, 0, 281}, + { 8658, 0, 282}, + { 8660, 0, 283}, + { 8707, 0, 284}, + { 8712, 0, 285}, + { 8715, 0, 286}, + { 8739, 0, 287}, + { 8741, 0, 288}, + { 8764, 0, 289}, + { 8771, 0, 290}, + { 8773, 0, 291}, + { 8776, 0, 292}, + { 8781, 0, 293}, + { 8801, 0, 294}, + { 8804, 1, 295}, + { 8818, 1, 297}, + { 8822, 1, 299}, + { 8826, 3, 301}, + { 8834, 1, 305}, + { 8838, 1, 307}, + { 8849, 1, 309}, + { 8866, 0, 311}, + { 8872, 1, 312}, + { 8875, 0, 314}, + { 8882, 3, 315}, + { 12358, 0, 319}, + { 12363, 0, 320}, + { 12365, 0, 321}, + { 12367, 0, 322}, + { 12369, 0, 323}, + { 12371, 0, 324}, + { 12373, 0, 325}, + { 12375, 0, 326}, + { 12377, 0, 327}, + { 12379, 0, 328}, + { 12381, 0, 329}, + { 12383, 0, 330}, + { 12385, 0, 331}, + { 12388, 0, 332}, + { 12390, 0, 333}, + { 12392, 0, 334}, + { 12399, 0, 335}, + { 12402, 0, 336}, + { 12405, 0, 337}, + { 12408, 0, 338}, + { 12411, 0, 339}, + { 12445, 0, 340}, + { 12454, 0, 341}, + { 12459, 0, 342}, + { 12461, 0, 343}, + { 12463, 0, 344}, + { 12465, 0, 345}, + { 12467, 0, 346}, + { 12469, 0, 347}, + { 12471, 0, 348}, + { 12473, 0, 349}, + { 12475, 0, 350}, + { 12477, 0, 351}, + { 12479, 0, 352}, + { 12481, 0, 353}, + { 12484, 0, 354}, + { 12486, 0, 355}, + { 12488, 0, 356}, + { 12495, 0, 357}, + { 12498, 0, 358}, + { 12501, 0, 359}, + { 12504, 0, 360}, + { 12507, 0, 361}, + { 12527, 3, 362}, + { 12541, 0, 366}, + { 69785, 0, 367}, + { 69787, 0, 368}, + { 69797, 0, 369}, + { 69937, 1, 370}, + { 70471, 0, 372}, + { 70841, 0, 373}, + { 71096, 1, 374}, { 71989, 0, 376}, - {0,0,0} -}; - -static struct reindex nfc_last[] = { - { 768, 4, 0}, - { 774, 6, 5}, - { 783, 0, 12}, - { 785, 0, 13}, - { 787, 1, 14}, - { 795, 0, 16}, - { 803, 5, 17}, - { 813, 1, 23}, - { 816, 1, 25}, - { 824, 0, 27}, - { 834, 0, 28}, - { 837, 0, 29}, - { 1619, 2, 30}, - { 2364, 0, 33}, - { 2494, 0, 34}, - { 2519, 0, 35}, - { 2878, 0, 36}, - { 2902, 1, 37}, - { 3006, 0, 39}, - { 3031, 0, 40}, - { 3158, 0, 41}, - { 3266, 0, 42}, - { 3285, 1, 43}, - { 3390, 0, 45}, - { 3415, 0, 46}, - { 3530, 0, 47}, - { 3535, 0, 48}, - { 3551, 0, 49}, - { 4142, 0, 50}, - { 6965, 0, 51}, - { 12441, 1, 52}, - { 69818, 0, 54}, - { 69927, 0, 55}, - { 70462, 0, 56}, - { 70487, 0, 57}, - { 70832, 0, 58}, - { 70842, 0, 59}, - { 70845, 0, 60}, - { 71087, 0, 61}, + {0,0,0} +}; + +static struct reindex nfc_last[] = { + { 768, 4, 0}, + { 774, 6, 5}, + { 783, 0, 12}, + { 785, 0, 13}, + { 787, 1, 14}, + { 795, 0, 16}, + { 803, 5, 17}, + { 813, 1, 23}, + { 816, 1, 25}, + { 824, 0, 27}, + { 834, 0, 28}, + { 837, 0, 29}, + { 1619, 2, 30}, + { 2364, 0, 33}, + { 2494, 0, 34}, + { 2519, 0, 35}, + { 2878, 0, 36}, + { 2902, 1, 37}, + { 3006, 0, 39}, + { 3031, 0, 40}, + { 3158, 0, 41}, + { 3266, 0, 42}, + { 3285, 1, 43}, + { 3390, 0, 45}, + { 3415, 0, 46}, + { 3530, 0, 47}, + { 3535, 0, 48}, + { 3551, 0, 49}, + { 4142, 0, 50}, + { 6965, 0, 51}, + { 12441, 1, 52}, + { 69818, 0, 54}, + { 69927, 0, 55}, + { 70462, 0, 56}, + { 70487, 0, 57}, + { 70832, 0, 58}, + { 70842, 0, 59}, + { 70845, 0, 60}, + { 71087, 0, 61}, { 71984, 0, 62}, - {0,0,0} -}; - -/* string literals */ -const char *_PyUnicode_CategoryNames[] = { - "Cn", - "Lu", - "Ll", - "Lt", - "Mn", - "Mc", - "Me", - "Nd", - "Nl", - "No", - "Zs", - "Zl", - "Zp", - "Cc", - "Cf", - "Cs", - "Co", - "Cn", - "Lm", - "Lo", - "Pc", - "Pd", - "Ps", - "Pe", - "Pi", - "Pf", - "Po", - "Sm", - "Sc", - "Sk", - "So", - NULL -}; -const char *_PyUnicode_BidirectionalNames[] = { - "", - "L", - "LRE", - "LRO", - "R", - "AL", - "RLE", - "RLO", - "PDF", - "EN", - "ES", - "ET", - "AN", - "CS", - "NSM", - "BN", - "B", - "S", - "WS", - "ON", - "LRI", - "RLI", - "FSI", - "PDI", - NULL -}; -const char *_PyUnicode_EastAsianWidthNames[] = { - "F", - "H", - "W", - "Na", - "A", - "N", - NULL -}; -static const char *decomp_prefix[] = { - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - NULL -}; -/* index tables for the database records */ -#define SHIFT 7 + {0,0,0} +}; + +/* string literals */ +const char *_PyUnicode_CategoryNames[] = { + "Cn", + "Lu", + "Ll", + "Lt", + "Mn", + "Mc", + "Me", + "Nd", + "Nl", + "No", + "Zs", + "Zl", + "Zp", + "Cc", + "Cf", + "Cs", + "Co", + "Cn", + "Lm", + "Lo", + "Pc", + "Pd", + "Ps", + "Pe", + "Pi", + "Pf", + "Po", + "Sm", + "Sc", + "Sk", + "So", + NULL +}; +const char *_PyUnicode_BidirectionalNames[] = { + "", + "L", + "LRE", + "LRO", + "R", + "AL", + "RLE", + "RLO", + "PDF", + "EN", + "ES", + "ET", + "AN", + "CS", + "NSM", + "BN", + "B", + "S", + "WS", + "ON", + "LRI", + "RLI", + "FSI", + "PDI", + NULL +}; +const char *_PyUnicode_EastAsianWidthNames[] = { + "F", + "H", + "W", + "Na", + "A", + "N", + NULL +}; +static const char *decomp_prefix[] = { + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + NULL +}; +/* index tables for the database records */ +#define SHIFT 7 static const unsigned short 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, 37, 38, - 39, 40, 41, 41, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 102, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 103, 104, 101, 101, 101, 101, 101, 101, 101, 101, 105, 41, 41, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 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, 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, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 122, 122, 123, 124, - 125, 126, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 138, 41, 41, 145, 138, 146, 147, 148, + 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, 37, 38, + 39, 40, 41, 41, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 102, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 103, 104, 101, 101, 101, 101, 101, 101, 101, 101, 105, 41, 41, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 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, 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, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 122, 122, 123, 124, + 125, 126, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 138, 41, 41, 145, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 138, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 138, 168, 169, 138, 170, 171, 172, 173, 138, 174, 175, 176, 177, 178, 179, 138, 138, 180, 181, 182, 183, 138, 184, 138, 185, 41, 41, 41, 41, 41, 41, 41, 186, 187, 41, 188, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 41, 41, 41, 41, 41, 41, 41, 41, 189, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 41, 41, 41, 41, 190, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 41, 41, 41, 41, 191, 192, 193, 194, 138, 138, 138, 138, 195, 196, 197, 198, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 199, 101, 101, 101, 101, 101, 101, 101, 101, 101, 200, 201, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 101, 101, 202, 101, 101, 203, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 204, 205, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 78, 206, 207, 208, 209, 210, 211, 138, 212, 213, 214, 215, 216, 217, 218, 219, 78, 78, 78, 78, 220, 221, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, @@ -774,694 +774,694 @@ static const unsigned short index1[] = { 138, 138, 225, 226, 227, 138, 138, 138, 138, 138, 228, 229, 230, 138, 231, 232, 138, 138, 233, 234, 235, 236, 237, 138, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 138, 138, 138, 138, 138, 138, 138, 138, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 138, 138, 138, 138, 138, 138, 138, 138, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 256, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 257, 101, 258, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 259, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 260, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 122, 122, 122, 122, 261, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 262, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 263, 138, 264, 265, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 266, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 266, -}; - +}; + static const unsigned short index2[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 3, 2, 5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12, - 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 9, 6, 10, 18, 19, 18, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 9, 16, 10, 16, 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, 21, 22, 8, 8, 23, 8, 24, - 22, 25, 26, 27, 28, 16, 29, 30, 31, 32, 33, 34, 34, 25, 35, 22, 22, 25, - 34, 27, 36, 37, 37, 37, 22, 38, 38, 38, 38, 38, 38, 39, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 39, 38, 38, 38, 38, 38, 38, 40, 39, 38, 38, 38, 38, - 38, 39, 41, 42, 42, 43, 43, 43, 43, 41, 43, 42, 42, 42, 43, 42, 42, 43, - 43, 41, 43, 42, 42, 43, 43, 43, 40, 41, 42, 42, 43, 42, 43, 41, 43, 38, - 42, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 41, 38, - 42, 38, 43, 38, 43, 38, 43, 38, 42, 38, 43, 38, 43, 38, 43, 38, 43, 38, - 43, 39, 41, 38, 43, 38, 42, 38, 43, 38, 43, 38, 41, 45, 46, 38, 43, 38, - 43, 41, 38, 43, 38, 43, 38, 43, 45, 46, 39, 41, 38, 42, 38, 43, 38, 42, - 46, 39, 41, 38, 42, 38, 43, 38, 43, 39, 41, 38, 43, 38, 43, 38, 43, 38, - 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 39, 41, 38, 43, 38, 42, 38, - 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 38, 43, 38, 43, 38, 43, - 35, 47, 44, 44, 47, 44, 47, 44, 44, 47, 44, 44, 44, 47, 47, 44, 44, 44, - 44, 47, 44, 44, 47, 44, 44, 44, 47, 47, 47, 44, 44, 47, 44, 38, 43, 44, - 47, 44, 47, 44, 44, 47, 44, 47, 47, 44, 47, 44, 38, 43, 44, 44, 44, 47, - 44, 47, 44, 44, 47, 47, 48, 44, 47, 47, 47, 48, 48, 48, 48, 49, 50, 35, - 49, 50, 35, 49, 50, 35, 38, 42, 38, 42, 38, 42, 38, 42, 38, 42, 38, 42, - 38, 42, 38, 42, 47, 38, 43, 38, 43, 38, 43, 44, 47, 38, 43, 38, 43, 38, - 43, 38, 43, 38, 43, 43, 49, 50, 35, 38, 43, 44, 44, 38, 43, 38, 43, 38, - 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, - 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 47, 38, 43, 44, - 47, 44, 47, 44, 47, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, - 43, 47, 47, 47, 47, 47, 47, 44, 44, 47, 44, 44, 47, 47, 44, 47, 44, 44, - 44, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 47, 41, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 41, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 53, 53, 53, 53, 53, 53, 53, 54, - 54, 55, 54, 52, 56, 52, 56, 56, 56, 52, 56, 52, 52, 57, 53, 54, 54, 54, - 54, 54, 54, 25, 25, 25, 25, 58, 25, 54, 55, 51, 51, 51, 51, 51, 54, 54, - 54, 54, 54, 54, 54, 52, 54, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 59, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, - 59, 59, 60, 60, 59, 60, 59, 60, 59, 59, 61, 62, 62, 62, 62, 61, 63, 62, - 62, 62, 62, 62, 64, 64, 65, 65, 65, 65, 66, 66, 62, 62, 62, 62, 65, 65, - 62, 65, 65, 62, 62, 67, 67, 67, 67, 68, 62, 62, 62, 62, 60, 60, 60, 69, - 69, 59, 69, 69, 70, 60, 62, 62, 62, 60, 60, 60, 62, 62, 71, 60, 60, 60, - 62, 62, 62, 62, 60, 61, 62, 62, 60, 72, 73, 73, 72, 73, 73, 72, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 44, 47, 44, 47, 74, 54, 44, - 47, 0, 0, 51, 47, 47, 47, 75, 44, 0, 0, 0, 0, 58, 76, 38, 75, 38, 38, 38, - 0, 38, 0, 38, 38, 43, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 38, 38, 43, 43, 43, 43, - 43, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 47, 41, 41, 41, 41, 41, 41, 41, 43, 43, 43, 43, 43, 44, 35, 35, 49, 77, - 77, 35, 35, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 35, 35, 35, 47, 49, 35, 78, 44, - 47, 49, 44, 47, 47, 44, 44, 44, 38, 79, 44, 38, 44, 44, 44, 38, 44, 44, - 44, 44, 38, 38, 38, 44, 39, 39, 39, 39, 39, 39, 39, 39, 39, 79, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 43, 42, - 47, 43, 47, 47, 47, 43, 47, 47, 47, 47, 43, 43, 43, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 38, 43, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 80, 81, 81, 81, 81, 81, - 82, 82, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 38, 43, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 47, - 38, 43, 38, 43, 44, 47, 38, 43, 44, 47, 38, 43, 38, 43, 38, 43, 44, 47, - 38, 43, 38, 43, 38, 43, 44, 47, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 44, 47, 38, 43, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 53, 83, 83, 83, 83, 83, 83, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 35, 47, 83, 84, 0, 0, 26, 26, 85, 0, 86, 81, 81, 81, 81, 86, 81, - 81, 81, 87, 86, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 81, 81, - 86, 81, 81, 87, 88, 81, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 104, 81, 86, 104, 97, 0, 0, 0, 0, 0, - 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, - 0, 0, 0, 107, 107, 107, 107, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 108, 108, 108, 108, 108, 108, 78, 78, 109, 110, 110, 111, 112, 113, 26, - 26, 81, 81, 81, 81, 81, 81, 81, 81, 114, 115, 116, 113, 117, 0, 113, 113, - 118, 118, 119, 119, 119, 119, 119, 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, 120, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 121, 122, 123, 114, 115, 116, 124, 125, 126, 126, 127, 86, 81, 81, - 81, 81, 81, 86, 81, 81, 86, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 110, 129, 129, 113, 118, 118, 130, 118, 118, 118, 118, 131, 131, - 131, 131, 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, 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, 119, 118, 119, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 119, 113, 118, 81, 81, 81, 81, - 81, 81, 81, 108, 26, 81, 81, 81, 81, 86, 81, 120, 120, 81, 81, 26, 86, - 81, 81, 86, 118, 118, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 118, 118, 118, 133, 133, 118, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 0, 117, 118, 134, 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, 81, 86, 81, 81, - 86, 81, 81, 86, 86, 86, 81, 86, 86, 81, 86, 81, 81, 81, 86, 81, 86, 81, - 86, 81, 86, 81, 81, 0, 0, 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, 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, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 81, 81, 81, 81, 81, 81, 81, 86, 81, 137, 137, 26, 138, 138, - 138, 137, 0, 0, 86, 139, 139, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, - 81, 81, 81, 137, 81, 81, 81, 81, 81, 81, 81, 81, 81, 137, 81, 81, 81, - 137, 81, 81, 81, 81, 81, 0, 0, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 0, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 86, 86, 86, 0, 0, 104, 0, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 3, 2, 5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12, + 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 9, 6, 10, 18, 19, 18, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 9, 16, 10, 16, 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, 21, 22, 8, 8, 23, 8, 24, + 22, 25, 26, 27, 28, 16, 29, 30, 31, 32, 33, 34, 34, 25, 35, 22, 22, 25, + 34, 27, 36, 37, 37, 37, 22, 38, 38, 38, 38, 38, 38, 39, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 39, 38, 38, 38, 38, 38, 38, 40, 39, 38, 38, 38, 38, + 38, 39, 41, 42, 42, 43, 43, 43, 43, 41, 43, 42, 42, 42, 43, 42, 42, 43, + 43, 41, 43, 42, 42, 43, 43, 43, 40, 41, 42, 42, 43, 42, 43, 41, 43, 38, + 42, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 41, 38, + 42, 38, 43, 38, 43, 38, 43, 38, 42, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 39, 41, 38, 43, 38, 42, 38, 43, 38, 43, 38, 41, 45, 46, 38, 43, 38, + 43, 41, 38, 43, 38, 43, 38, 43, 45, 46, 39, 41, 38, 42, 38, 43, 38, 42, + 46, 39, 41, 38, 42, 38, 43, 38, 43, 39, 41, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 39, 41, 38, 43, 38, 42, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 38, 43, 38, 43, 38, 43, + 35, 47, 44, 44, 47, 44, 47, 44, 44, 47, 44, 44, 44, 47, 47, 44, 44, 44, + 44, 47, 44, 44, 47, 44, 44, 44, 47, 47, 47, 44, 44, 47, 44, 38, 43, 44, + 47, 44, 47, 44, 44, 47, 44, 47, 47, 44, 47, 44, 38, 43, 44, 44, 44, 47, + 44, 47, 44, 44, 47, 47, 48, 44, 47, 47, 47, 48, 48, 48, 48, 49, 50, 35, + 49, 50, 35, 49, 50, 35, 38, 42, 38, 42, 38, 42, 38, 42, 38, 42, 38, 42, + 38, 42, 38, 42, 47, 38, 43, 38, 43, 38, 43, 44, 47, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 43, 49, 50, 35, 38, 43, 44, 44, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 47, 38, 43, 44, + 47, 44, 47, 44, 47, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 47, 47, 47, 47, 47, 47, 44, 44, 47, 44, 44, 47, 47, 44, 47, 44, 44, + 44, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 47, 41, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 41, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 53, 53, 53, 53, 53, 53, 53, 54, + 54, 55, 54, 52, 56, 52, 56, 56, 56, 52, 56, 52, 52, 57, 53, 54, 54, 54, + 54, 54, 54, 25, 25, 25, 25, 58, 25, 54, 55, 51, 51, 51, 51, 51, 54, 54, + 54, 54, 54, 54, 54, 52, 54, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 59, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, + 59, 59, 60, 60, 59, 60, 59, 60, 59, 59, 61, 62, 62, 62, 62, 61, 63, 62, + 62, 62, 62, 62, 64, 64, 65, 65, 65, 65, 66, 66, 62, 62, 62, 62, 65, 65, + 62, 65, 65, 62, 62, 67, 67, 67, 67, 68, 62, 62, 62, 62, 60, 60, 60, 69, + 69, 59, 69, 69, 70, 60, 62, 62, 62, 60, 60, 60, 62, 62, 71, 60, 60, 60, + 62, 62, 62, 62, 60, 61, 62, 62, 60, 72, 73, 73, 72, 73, 73, 72, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 44, 47, 44, 47, 74, 54, 44, + 47, 0, 0, 51, 47, 47, 47, 75, 44, 0, 0, 0, 0, 58, 76, 38, 75, 38, 38, 38, + 0, 38, 0, 38, 38, 43, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 38, 38, 43, 43, 43, 43, + 43, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 47, 41, 41, 41, 41, 41, 41, 41, 43, 43, 43, 43, 43, 44, 35, 35, 49, 77, + 77, 35, 35, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 35, 35, 35, 47, 49, 35, 78, 44, + 47, 49, 44, 47, 47, 44, 44, 44, 38, 79, 44, 38, 44, 44, 44, 38, 44, 44, + 44, 44, 38, 38, 38, 44, 39, 39, 39, 39, 39, 39, 39, 39, 39, 79, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 43, 42, + 47, 43, 47, 47, 47, 43, 47, 47, 47, 47, 43, 43, 43, 47, 44, 47, 44, 47, + 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 38, 43, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 80, 81, 81, 81, 81, 81, + 82, 82, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 44, 47, 44, 38, 43, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 47, + 38, 43, 38, 43, 44, 47, 38, 43, 44, 47, 38, 43, 38, 43, 38, 43, 44, 47, + 38, 43, 38, 43, 38, 43, 44, 47, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 44, 47, 38, 43, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 44, 47, 44, 47, 44, 47, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 53, 83, 83, 83, 83, 83, 83, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 35, 47, 83, 84, 0, 0, 26, 26, 85, 0, 86, 81, 81, 81, 81, 86, 81, + 81, 81, 87, 86, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 81, 81, + 86, 81, 81, 87, 88, 81, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 104, 81, 86, 104, 97, 0, 0, 0, 0, 0, + 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, + 0, 0, 0, 107, 107, 107, 107, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 108, 108, 108, 108, 108, 78, 78, 109, 110, 110, 111, 112, 113, 26, + 26, 81, 81, 81, 81, 81, 81, 81, 81, 114, 115, 116, 113, 117, 0, 113, 113, + 118, 118, 119, 119, 119, 119, 119, 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, 120, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 121, 122, 123, 114, 115, 116, 124, 125, 126, 126, 127, 86, 81, 81, + 81, 81, 81, 86, 81, 81, 86, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 110, 129, 129, 113, 118, 118, 130, 118, 118, 118, 118, 131, 131, + 131, 131, 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, 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, 119, 118, 119, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 119, 113, 118, 81, 81, 81, 81, + 81, 81, 81, 108, 26, 81, 81, 81, 81, 86, 81, 120, 120, 81, 81, 26, 86, + 81, 81, 86, 118, 118, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 118, 118, 118, 133, 133, 118, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 0, 117, 118, 134, 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, 81, 86, 81, 81, + 86, 81, 81, 86, 86, 86, 81, 86, 86, 81, 86, 81, 81, 81, 86, 81, 86, 81, + 86, 81, 86, 81, 81, 0, 0, 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, 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, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 81, 81, 81, 81, 81, 81, 81, 86, 81, 137, 137, 26, 138, 138, + 138, 137, 0, 0, 86, 139, 139, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, + 81, 81, 81, 137, 81, 81, 81, 81, 81, 81, 81, 81, 81, 137, 81, 81, 81, + 137, 81, 81, 81, 81, 81, 0, 0, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 0, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 86, 86, 86, 0, 0, 104, 0, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 0, 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, 0, 86, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 108, 86, 81, 81, 86, 81, 81, 86, 81, 81, 81, 86, 86, 86, 121, 122, 123, 81, 81, 81, 86, 81, 81, 86, 86, 81, 81, 81, 81, 81, 135, 135, 135, 140, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 48, 48, 48, 48, 48, 48, 48, 141, 48, 48, 141, 48, 48, 48, 48, 48, 135, 140, 142, 48, 140, 140, 140, 135, 135, 135, 135, 135, 135, 135, 135, 140, 140, 140, @@ -1519,7 +1519,7 @@ static const unsigned short index2[] = { 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 140, 140, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 143, 143, 48, 147, 140, 140, 135, 135, 135, 135, 0, 140, 140, 140, 0, 148, 148, 148, 143, 48, 80, 0, 0, 0, 0, 48, 48, 48, 147, 149, 149, 149, 149, 149, 149, 149, 48, 48, 48, 135, @@ -1532,8 +1532,8 @@ static const unsigned short index2[] = { 0, 0, 147, 140, 140, 135, 135, 135, 0, 135, 0, 140, 140, 148, 140, 148, 148, 148, 147, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 140, 140, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 48, 157, 135, 135, 135, 135, 158, 158, 143, 0, 0, 0, 0, 85, 48, 48, 48, 48, 48, 48, 53, 135, 159, 159, 159, 159, 135, 135, 135, 83, 145, 145, 145, 145, 145, 145, 145, 145, 145, @@ -1561,7 +1561,7 @@ static const unsigned short index2[] = { 80, 80, 80, 80, 80, 0, 80, 80, 83, 83, 83, 83, 83, 80, 80, 80, 80, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 48, 48, 48, 48, 140, 140, 135, 150, 135, 135, 140, 135, 135, 135, 135, 135, 146, 140, 143, 143, 140, 140, 135, 135, 48, 145, 145, 145, 145, 145, 145, 145, 145, 145, @@ -1571,82 +1571,82 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 135, 140, 140, 135, 135, 140, 140, 140, 140, 140, 140, 86, 48, 140, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 140, 140, 140, 135, 80, 80, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 0, 0, 0, 0, 0, 44, 0, 0, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 83, 51, 47, 47, 47, 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, 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, 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, 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, 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, 48, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 81, 81, 81, 83, 83, 83, 83, 83, 83, 83, 83, 83, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 84, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 80, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 164, 165, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 83, 83, 83, 174, 174, 174, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 135, 135, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1655,8 +1655,8 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 140, 135, 135, 135, 135, 135, 135, 135, 140, 140, 140, 140, 140, 140, 140, 140, 135, 140, 140, 135, 135, 135, 135, 135, 135, 135, 135, 135, @@ -1665,36 +1665,36 @@ static const unsigned short index2[] = { 154, 154, 154, 154, 154, 154, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138, 138, 138, 84, 138, 138, 138, 138, 135, 135, 135, 175, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 88, 48, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 135, 135, 135, 140, 140, 140, 140, 135, 135, 140, 140, 140, 0, 0, 0, 0, 140, 140, 135, 140, 140, 140, 140, 140, 140, 87, 81, 86, 0, 0, 0, 0, 26, 0, 0, 0, 138, 138, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 149, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 86, 140, 140, 135, 0, 0, 83, 83, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 135, 140, 135, 135, 135, 135, 135, 135, 135, 0, 143, 140, 135, 140, 140, 135, 135, 135, 135, 135, 135, 135, 135, 140, 140, 140, 140, 140, 140, 135, 135, 81, @@ -1703,21 +1703,21 @@ static const unsigned short index2[] = { 145, 145, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, 83, 83, 83, 53, 83, 83, 83, 83, 83, 83, 0, 0, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 81, 81, 86, 82, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 140, 48, 141, 48, 141, 48, 141, 48, 141, 48, 141, 48, 48, 48, 141, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 146, 147, 135, 135, 135, 135, 135, 148, 135, 148, 140, 140, 148, 148, 135, 148, 176, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 86, 81, 81, 81, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 135, 135, 140, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 135, 135, 135, 135, 140, 140, 135, 135, 176, 143, 135, 135, 48, 48, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 146, 140, 135, 135, 140, 140, 140, 135, 140, 135, 135, 135, 176, 176, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -1729,25 +1729,25 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 53, 53, 53, 53, 53, 83, 83, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 44, 44, 44, 83, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 83, 177, 86, 86, 86, 86, 86, 81, 81, 86, 86, 86, 86, 81, 140, 177, 177, 177, 177, 177, 177, 177, 48, 48, 48, 48, 86, 48, 48, 48, 48, 48, 48, 81, 48, 48, 140, 81, 81, 48, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, 51, 51, 53, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 53, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 53, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 81, 81, 86, 81, 81, 81, 81, 81, 81, 81, 86, 81, 81, 178, 179, 86, 180, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 181, 88, 88, 86, 0, 81, 182, 86, 81, 86, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, @@ -1828,36 +1828,36 @@ static const unsigned short index2[] = { 164, 165, 164, 165, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 241, 241, 26, 26, 26, 26, 234, 234, 26, 26, 26, 26, 26, 26, 26, 242, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 26, 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 26, 26, 26, 26, 26, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 78, 78, 78, 78, 78, 78, 26, 26, 26, 26, 26, 26, 26, 241, 241, 241, 241, 26, 26, 26, 241, 26, 26, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 229, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, @@ -1870,7 +1870,7 @@ static const unsigned short index2[] = { 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 78, 78, 78, 78, 78, 246, 246, 78, 26, 26, 26, 26, 26, 30, 30, 26, 26, 30, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 241, 241, 26, 26, 26, 26, 26, 26, 30, 26, 30, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 30, 26, 26, 26, 26, 26, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 30, 30, 30, @@ -1885,33 +1885,33 @@ static const unsigned short index2[] = { 241, 30, 241, 30, 30, 30, 30, 241, 30, 30, 241, 30, 30, 26, 26, 26, 26, 26, 241, 26, 26, 26, 26, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 26, 241, 26, 26, 26, 26, 241, 241, 241, 26, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 164, 165, 164, 165, 164, 165, 164, 165, 164, 165, 164, 165, 164, 165, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 26, 241, 241, 241, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 234, 78, 78, 234, 234, 164, 165, 78, 234, 234, 78, 234, 234, 234, 78, 78, 78, 78, 78, 234, 234, 234, 234, 78, 78, 78, 78, 78, 234, 234, 234, 78, 78, 78, 234, 234, 234, 234, 9, 10, 9, 10, 9, 10, 9, 10, 164, 165, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 164, 165, 9, 10, 164, 165, 164, 165, 164, 165, 164, 165, 164, 165, 164, 165, 164, 165, 164, 165, 164, 165, 78, 78, 234, 234, 234, 234, 234, 234, 78, 234, 234, 234, 234, 234, 234, 234, 234, @@ -1928,33 +1928,33 @@ static const unsigned short index2[] = { 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 234, 234, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 234, 234, 78, 78, 78, 78, 234, 234, 234, 234, 78, 234, 234, 78, 78, 234, 228, 218, 218, 78, 78, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 78, 78, 234, 234, 234, 234, 234, 234, 234, 234, 78, 234, 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 78, 78, 78, 78, 78, 247, 78, 234, 78, 78, 78, 234, 234, 234, 234, 234, 78, 78, 78, 78, 78, 234, 234, 234, 78, 78, 78, 78, 234, 78, 78, 78, 234, 234, 234, 234, 234, 78, 234, 78, 78, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 26, 26, 78, 78, 78, 78, 78, 78, 26, 26, 26, 241, 26, 26, 26, 26, 241, 30, 30, 30, 30, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 248, 26, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 44, 47, 44, 44, 44, 47, 47, 44, 47, 44, 47, 44, 47, 44, 44, 44, 44, 47, 44, 47, 47, 44, 47, 47, 47, 47, 47, 47, 51, 51, 44, 44, @@ -1966,10 +1966,10 @@ static const unsigned short index2[] = { 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 47, 26, 26, 26, 26, 26, 26, 44, 47, 44, 47, 81, 81, 81, 44, 47, 0, 0, 0, 0, 0, 138, 138, 138, 138, 154, 138, 138, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0, 0, 0, 47, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 51, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -1977,38 +1977,38 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 138, 138, 28, 36, 28, 36, 138, 138, 138, 28, 36, 138, 28, 36, 138, 138, 138, 138, 138, 138, 138, 138, 138, 84, 138, 138, 84, 138, 28, 36, 138, 138, 28, 36, 164, 165, 164, 165, 164, 165, 164, 165, 138, 138, 138, 138, 138, 52, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 84, 84, 138, 138, 138, 138, 84, 138, 197, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 26, 26, 138, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 0, 241, 241, 241, 241, 249, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 0, 0, 0, 0, 250, @@ -2018,115 +2018,115 @@ static const unsigned short index2[] = { 260, 261, 262, 263, 263, 256, 252, 252, 252, 252, 252, 249, 241, 264, 264, 264, 252, 171, 251, 241, 26, 0, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, - 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, + 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 171, 265, 171, 265, 171, 265, 171, 171, 171, 171, 171, 171, 265, 265, 171, 265, 265, 171, 265, 265, 171, 265, 265, 171, 265, 265, 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, 265, 171, 171, 0, 0, 266, 266, 267, 267, 252, 268, 269, 256, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 265, 171, 171, 265, 171, 265, 171, 265, 171, 171, 171, 171, 171, 171, 265, 265, 171, 265, 265, 171, 265, 265, 171, 265, 265, 171, 265, 265, 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, 265, 171, 171, 265, 265, 265, 265, 251, 252, 252, 268, 269, 0, 0, 0, 0, 0, 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, 171, 171, 171, 171, 171, 0, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 0, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 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, 171, 171, 171, 171, 171, 171, 171, 171, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 249, 249, 0, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 249, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 249, 249, 249, 270, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 249, 249, 249, 249, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 249, 249, 249, 249, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 249, 249, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 249, 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, 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, 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, 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, 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, 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, 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, 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, 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, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 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, 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, 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, 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, + 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, 171, 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 252, - 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, 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, 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, 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, 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, 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, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 53, 53, 53, 53, 53, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 138, 138, 138, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, @@ -2137,8 +2137,8 @@ static const unsigned short index2[] = { 81, 81, 81, 81, 81, 81, 81, 138, 52, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 51, 51, 81, 81, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 81, 81, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, @@ -2153,18 +2153,18 @@ static const unsigned short index2[] = { 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 44, 44, 44, 44, 47, 44, 44, 44, 44, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 0, 0, 44, 47, 44, 44, 44, 44, 47, 44, 47, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 47, 48, 51, 51, 47, 48, 48, 48, 48, 48, 48, 48, 135, 48, 48, 48, 143, 48, 48, 48, 48, 135, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 135, 135, 140, 26, 26, 26, 26, 143, 0, 0, 0, 149, 149, 149, 149, 149, 149, 80, 80, 85, 227, 0, 0, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 138, 138, 138, 138, 0, 0, 0, 0, 0, 0, 0, 0, 140, 140, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 135, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 81, 81, @@ -2176,24 +2176,24 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 140, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 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, 171, 171, 171, 171, 171, 0, 0, 0, 135, 135, 135, 140, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 146, 140, 140, 135, 135, 135, 135, 140, 140, 135, 135, 140, 140, 176, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 0, 53, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 83, 83, 48, 48, 48, 48, 48, 135, 53, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 48, 48, 48, 48, 48, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 140, 140, 135, 135, 140, 140, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 135, 48, 48, 48, 48, 48, 48, 48, 48, 135, 140, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 83, 83, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 48, 48, 48, 48, 48, 48, 80, 80, 80, 48, 140, 135, 140, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 48, 81, 81, 86, 48, 48, 81, 81, 48, 48, 48, 48, 48, 81, 81, 48, 81, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, @@ -2202,75 +2202,75 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 275, 51, 51, 51, 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, 54, 54, 0, 0, 0, 0, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 135, 140, 140, 135, 140, 140, 83, 140, 143, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 171, 171, 278, 171, 278, 171, 171, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 171, 278, 171, 278, 171, 171, 278, 278, 171, 171, 171, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 0, 0, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2279,42 +2279,42 @@ static const unsigned short index2[] = { 281, 281, 281, 217, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 0, 279, 279, 279, 279, 279, 0, 279, 0, 279, 279, 0, 279, 279, 0, 279, 279, 279, 279, 279, 279, 279, 279, 279, 281, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 283, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 284, 26, 0, 0, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 285, 285, 285, 285, 285, 285, 285, 286, 287, 285, 0, 0, 0, 0, @@ -2324,210 +2324,210 @@ static const unsigned short index2[] = { 285, 289, 289, 289, 290, 285, 290, 0, 285, 290, 285, 285, 288, 291, 292, 291, 292, 291, 292, 293, 285, 285, 294, 295, 296, 296, 297, 0, 285, 298, 293, 285, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 175, 0, 299, 299, 300, 301, 300, 299, 299, 302, 303, 299, 304, 305, 306, 305, 305, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 305, 299, 308, 309, 308, 299, 299, 310, 310, 310, - 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, + 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 302, 299, 303, 311, 312, 311, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 302, 309, 303, 309, 302, 303, 314, 315, 316, 314, 314, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 318, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 318, 318, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 0, 0, 0, 317, 317, 317, 317, 317, 317, 0, 0, 317, 317, 317, 317, 317, 317, 0, 0, 317, 317, 317, 317, 317, 317, 0, 0, 317, 317, 317, 0, 0, 0, 301, 301, 309, 311, 319, 301, 301, 0, 320, 321, 321, 321, 321, 320, 320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 322, 322, 322, 26, 30, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 323, 323, 323, 323, 323, 323, - 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 154, 154, 154, 154, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 154, 154, 26, 80, 80, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 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, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 149, 149, 149, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 174, 48, 48, 48, 48, 48, 48, 48, 48, 174, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 83, 174, 174, 174, 174, 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 0, 0, 107, 0, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 107, 0, 0, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 104, 325, 325, 325, 325, 325, 325, 325, 325, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 326, 326, 325, 325, 325, 325, 325, 325, 325, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 325, 325, 325, 325, 325, 325, 325, 325, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 0, 0, 325, 325, 325, 325, 325, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 325, 325, 325, 325, 325, 325, 0, 0, 0, 138, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 325, 325, 107, 107, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 0, 0, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 107, 135, 135, 135, 0, 135, 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, 107, 107, 107, 0, 107, 107, 107, 0, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 81, 177, 86, 0, 0, 0, 0, 143, 325, 325, 325, 325, 325, 325, 325, 325, 325, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 325, 325, 104, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 325, 325, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, - 107, 107, 107, 107, 107, 107, 326, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 81, 86, 0, 0, 0, 0, 325, 325, 325, - 325, 325, 104, 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 138, - 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, - 0, 325, 325, 325, 325, 325, 325, 325, 325, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, - 0, 0, 325, 325, 325, 325, 325, 325, 325, 325, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, - 0, 0, 0, 0, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, - 325, 325, 325, 325, 325, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, - 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, - 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, - 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 0, 0, 0, - 0, 0, 0, 0, 325, 325, 325, 325, 325, 325, 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, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, - 128, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 0, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 325, 325, 104, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 325, 325, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, + 107, 107, 107, 107, 107, 107, 326, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 81, 86, 0, 0, 0, 0, 325, 325, 325, + 325, 325, 104, 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 138, + 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, + 0, 325, 325, 325, 325, 325, 325, 325, 325, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, + 0, 0, 325, 325, 325, 325, 325, 325, 325, 325, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, + 0, 0, 0, 0, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, + 325, 325, 325, 325, 325, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 0, 0, 0, + 0, 0, 0, 0, 325, 325, 325, 325, 325, 325, 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, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 128, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 0, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 81, 81, 102, 0, 0, 107, 107, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, @@ -2545,8 +2545,8 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 135, 140, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 143, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, @@ -2560,15 +2560,15 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 81, 81, 81, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 150, 135, 135, 135, 135, 140, 135, 151, 151, 135, 135, 135, 143, 143, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 83, 83, 83, 83, 48, 140, 140, 48, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 146, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 140, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 135, 135, 135, 135, 135, 135, 135, 135, 135, 140, 176, 48, 48, 48, 48, 83, 83, 83, 83, 135, 146, 135, 135, 83, 140, 135, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 48, 83, 48, 83, 83, 83, @@ -2578,13 +2578,13 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 135, 135, 135, 140, 140, 135, 176, 146, 135, 83, 83, 83, 83, 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 83, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 140, 140, 140, 135, 135, 135, 135, 135, 135, 146, 143, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 135, 135, 140, 140, 0, 48, 48, 48, 48, 48, 48, 48, @@ -2595,57 +2595,57 @@ static const unsigned short index2[] = { 0, 147, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 140, 140, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 135, 135, 135, 135, 135, 135, 135, 135, 140, 140, 143, 135, 135, 140, 146, 48, 48, 48, 48, 83, 83, 83, 83, 83, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 83, 83, 0, 83, 81, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 147, 140, 140, 135, 135, 135, 135, 135, 135, 140, 150, 148, 148, 147, 148, 135, 135, 140, 143, 146, 48, 48, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 147, 140, 140, 135, 135, 135, 135, 0, 0, 140, 140, 148, 148, 135, 135, 140, 143, 146, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 48, 48, 48, 48, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 135, 135, 135, 135, 135, 135, 135, 135, 140, 140, 135, 140, 143, 135, 83, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 140, 135, 140, 140, 135, 135, 135, 135, 135, 135, 176, 146, 48, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 135, 135, 135, 140, 140, 135, 135, 135, 135, 140, 135, 135, 135, 135, 143, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 149, 149, 83, 83, 83, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 135, 135, 135, 135, 135, 135, 135, 135, 135, 140, 143, 146, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 149, 149, 149, 149, 149, 149, 149, 149, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 0, 0, 48, 48, 48, @@ -2657,24 +2657,24 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 135, 135, 135, 135, 0, 0, 135, 135, 140, 140, 140, 140, 143, 48, 83, 48, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 135, 135, 135, 135, 135, 135, 155, 155, 135, 135, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 143, 135, 135, 135, 135, 140, 48, 135, 135, 135, 135, 83, 83, 83, 83, 83, 83, 83, 83, 143, 0, 0, 0, 0, 0, 0, 0, 0, 48, 135, 135, 135, 135, 135, 135, 140, 140, 135, 135, 135, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 140, 135, 143, 83, 83, 83, 48, 83, 83, 83, 83, 83, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -2687,8 +2687,8 @@ static const unsigned short index2[] = { 48, 0, 0, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 0, 140, 135, 135, 135, 135, 135, 135, 135, 140, 135, 135, 140, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -2700,16 +2700,16 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, 0, 135, 135, 0, 140, 140, 135, 140, 143, 48, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 140, 140, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 26, 26, 26, 26, 26, 26, @@ -2717,103 +2717,103 @@ static const unsigned short index2[] = { 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, + 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, 174, 174, 174, 174, 174, 174, 174, 174, 174, 0, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 190, 190, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 177, 177, 177, 177, 177, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 81, 81, 83, 83, 83, 83, 83, 80, 80, 80, 80, 53, 53, 53, 53, 83, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 149, 149, 149, 149, 149, 149, 149, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 135, 48, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 252, 251, 252, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 171, 171, 171, 171, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 171, 171, 171, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 0, @@ -2822,79 +2822,79 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 171, 171, 171, 171, 171, 171, 171, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 171, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 171, 171, 171, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 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, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 80, 135, 177, 83, 175, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 334, 334, 334, 334, 334, 334, 334, 335, 335, 177, 177, 177, 80, 80, 80, 336, 335, 335, 335, 335, 335, 175, 175, 175, 175, 175, 175, 175, 175, 86, 86, 86, 86, 86, 86, 86, 86, 80, 80, 81, 81, 81, 81, 81, 86, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 334, 334, 334, 334, 334, 334, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 81, 81, 81, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 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, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, @@ -2911,7 +2911,7 @@ static const unsigned short index2[] = { 35, 35, 49, 49, 0, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 0, 49, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, @@ -2919,20 +2919,20 @@ static const unsigned short index2[] = { 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 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, 337, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 228, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 337, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 228, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, @@ -2940,34 +2940,34 @@ static const unsigned short index2[] = { 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 228, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 337, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 228, 35, - 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 228, 35, + 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 337, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 228, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 80, 80, 80, 80, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 80, 80, 80, 80, 80, 80, 80, 80, 135, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 135, 80, 80, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 135, 0, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 81, 81, 0, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -2982,52 +2982,52 @@ static const unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 0, 0, 0, 0, 0, 85, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 325, 325, 325, 325, 325, 325, 325, 325, 325, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 327, 327, 327, - 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 81, 81, 81, 81, 81, 81, 146, 137, 0, 0, 0, 0, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 0, 0, 0, 0, 104, 104, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 133, 330, 330, 330, 111, 330, 330, 330, 330, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 133, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, 0, 131, 0, 0, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 131, 0, 131, 0, 131, 0, 131, 131, 131, 0, 131, @@ -3038,27 +3038,27 @@ static const unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 131, 131, 131, 0, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 241, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 0, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 154, 154, 26, 26, 26, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 339, 26, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 224, 224, 224, 26, 26, 26, 340, 340, @@ -3067,122 +3067,122 @@ static const unsigned short index2[] = { 270, 340, 244, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 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, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 272, 272, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 0, 0, 0, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 0, 0, 0, 0, 0, 0, 272, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, 26, 241, 241, 241, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, 241, 26, 26, 26, 241, 241, 241, 341, 341, 341, 341, 341, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 241, 26, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 241, 241, 26, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 26, 26, 26, 26, 26, 241, 26, 26, 26, 241, 241, 241, 26, 26, 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, 241, 0, 0, 0, 26, 26, 26, 26, 241, 241, 241, 241, 241, 241, 241, 241, 241, 0, 0, 0, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 26, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 0, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 0, 241, 241, 241, 241, 241, 241, 241, 241, @@ -3201,7 +3201,7 @@ static const unsigned short index2[] = { 241, 241, 241, 241, 241, 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 241, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, @@ -3214,57 +3214,57 @@ static const unsigned short index2[] = { 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 0, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, + 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, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 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, 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, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, @@ -3275,445 +3275,445 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 0, 0, -}; - -/* decomposition data */ +}; + +/* decomposition data */ static const unsigned int decomp_data[] = { - 0, 257, 32, 514, 32, 776, 259, 97, 514, 32, 772, 259, 50, 259, 51, 514, - 32, 769, 258, 956, 514, 32, 807, 259, 49, 259, 111, 772, 49, 8260, 52, - 772, 49, 8260, 50, 772, 51, 8260, 52, 512, 65, 768, 512, 65, 769, 512, - 65, 770, 512, 65, 771, 512, 65, 776, 512, 65, 778, 512, 67, 807, 512, 69, - 768, 512, 69, 769, 512, 69, 770, 512, 69, 776, 512, 73, 768, 512, 73, - 769, 512, 73, 770, 512, 73, 776, 512, 78, 771, 512, 79, 768, 512, 79, - 769, 512, 79, 770, 512, 79, 771, 512, 79, 776, 512, 85, 768, 512, 85, - 769, 512, 85, 770, 512, 85, 776, 512, 89, 769, 512, 97, 768, 512, 97, - 769, 512, 97, 770, 512, 97, 771, 512, 97, 776, 512, 97, 778, 512, 99, - 807, 512, 101, 768, 512, 101, 769, 512, 101, 770, 512, 101, 776, 512, - 105, 768, 512, 105, 769, 512, 105, 770, 512, 105, 776, 512, 110, 771, - 512, 111, 768, 512, 111, 769, 512, 111, 770, 512, 111, 771, 512, 111, - 776, 512, 117, 768, 512, 117, 769, 512, 117, 770, 512, 117, 776, 512, - 121, 769, 512, 121, 776, 512, 65, 772, 512, 97, 772, 512, 65, 774, 512, - 97, 774, 512, 65, 808, 512, 97, 808, 512, 67, 769, 512, 99, 769, 512, 67, - 770, 512, 99, 770, 512, 67, 775, 512, 99, 775, 512, 67, 780, 512, 99, - 780, 512, 68, 780, 512, 100, 780, 512, 69, 772, 512, 101, 772, 512, 69, - 774, 512, 101, 774, 512, 69, 775, 512, 101, 775, 512, 69, 808, 512, 101, - 808, 512, 69, 780, 512, 101, 780, 512, 71, 770, 512, 103, 770, 512, 71, - 774, 512, 103, 774, 512, 71, 775, 512, 103, 775, 512, 71, 807, 512, 103, - 807, 512, 72, 770, 512, 104, 770, 512, 73, 771, 512, 105, 771, 512, 73, - 772, 512, 105, 772, 512, 73, 774, 512, 105, 774, 512, 73, 808, 512, 105, - 808, 512, 73, 775, 514, 73, 74, 514, 105, 106, 512, 74, 770, 512, 106, - 770, 512, 75, 807, 512, 107, 807, 512, 76, 769, 512, 108, 769, 512, 76, - 807, 512, 108, 807, 512, 76, 780, 512, 108, 780, 514, 76, 183, 514, 108, - 183, 512, 78, 769, 512, 110, 769, 512, 78, 807, 512, 110, 807, 512, 78, - 780, 512, 110, 780, 514, 700, 110, 512, 79, 772, 512, 111, 772, 512, 79, - 774, 512, 111, 774, 512, 79, 779, 512, 111, 779, 512, 82, 769, 512, 114, - 769, 512, 82, 807, 512, 114, 807, 512, 82, 780, 512, 114, 780, 512, 83, - 769, 512, 115, 769, 512, 83, 770, 512, 115, 770, 512, 83, 807, 512, 115, - 807, 512, 83, 780, 512, 115, 780, 512, 84, 807, 512, 116, 807, 512, 84, - 780, 512, 116, 780, 512, 85, 771, 512, 117, 771, 512, 85, 772, 512, 117, - 772, 512, 85, 774, 512, 117, 774, 512, 85, 778, 512, 117, 778, 512, 85, - 779, 512, 117, 779, 512, 85, 808, 512, 117, 808, 512, 87, 770, 512, 119, - 770, 512, 89, 770, 512, 121, 770, 512, 89, 776, 512, 90, 769, 512, 122, - 769, 512, 90, 775, 512, 122, 775, 512, 90, 780, 512, 122, 780, 258, 115, - 512, 79, 795, 512, 111, 795, 512, 85, 795, 512, 117, 795, 514, 68, 381, - 514, 68, 382, 514, 100, 382, 514, 76, 74, 514, 76, 106, 514, 108, 106, - 514, 78, 74, 514, 78, 106, 514, 110, 106, 512, 65, 780, 512, 97, 780, - 512, 73, 780, 512, 105, 780, 512, 79, 780, 512, 111, 780, 512, 85, 780, - 512, 117, 780, 512, 220, 772, 512, 252, 772, 512, 220, 769, 512, 252, - 769, 512, 220, 780, 512, 252, 780, 512, 220, 768, 512, 252, 768, 512, - 196, 772, 512, 228, 772, 512, 550, 772, 512, 551, 772, 512, 198, 772, - 512, 230, 772, 512, 71, 780, 512, 103, 780, 512, 75, 780, 512, 107, 780, - 512, 79, 808, 512, 111, 808, 512, 490, 772, 512, 491, 772, 512, 439, 780, - 512, 658, 780, 512, 106, 780, 514, 68, 90, 514, 68, 122, 514, 100, 122, - 512, 71, 769, 512, 103, 769, 512, 78, 768, 512, 110, 768, 512, 197, 769, - 512, 229, 769, 512, 198, 769, 512, 230, 769, 512, 216, 769, 512, 248, - 769, 512, 65, 783, 512, 97, 783, 512, 65, 785, 512, 97, 785, 512, 69, - 783, 512, 101, 783, 512, 69, 785, 512, 101, 785, 512, 73, 783, 512, 105, - 783, 512, 73, 785, 512, 105, 785, 512, 79, 783, 512, 111, 783, 512, 79, - 785, 512, 111, 785, 512, 82, 783, 512, 114, 783, 512, 82, 785, 512, 114, - 785, 512, 85, 783, 512, 117, 783, 512, 85, 785, 512, 117, 785, 512, 83, - 806, 512, 115, 806, 512, 84, 806, 512, 116, 806, 512, 72, 780, 512, 104, - 780, 512, 65, 775, 512, 97, 775, 512, 69, 807, 512, 101, 807, 512, 214, - 772, 512, 246, 772, 512, 213, 772, 512, 245, 772, 512, 79, 775, 512, 111, - 775, 512, 558, 772, 512, 559, 772, 512, 89, 772, 512, 121, 772, 259, 104, - 259, 614, 259, 106, 259, 114, 259, 633, 259, 635, 259, 641, 259, 119, - 259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514, - 32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661, - 256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256, - 59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, - 512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, - 769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, - 949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, - 512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, - 258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, - 258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, - 768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, - 1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, - 768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, - 1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, - 774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, - 1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, - 776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, - 1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, - 776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, - 1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, - 776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, - 1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, - 1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, - 514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, - 1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, - 2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, - 512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, - 2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, - 2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, - 512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, - 2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, - 3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, - 512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, - 3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, - 3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, - 514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, - 4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, - 512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, - 4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, - 4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, - 512, 4133, 4142, 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, - 6965, 512, 6923, 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, - 512, 6972, 6965, 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, - 65, 259, 198, 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, - 73, 259, 74, 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, - 80, 259, 82, 259, 84, 259, 85, 259, 87, 259, 97, 259, 592, 259, 593, 259, - 7426, 259, 98, 259, 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, - 103, 259, 107, 259, 109, 259, 331, 259, 111, 259, 596, 259, 7446, 259, - 7447, 259, 112, 259, 116, 259, 117, 259, 7453, 259, 623, 259, 118, 259, - 7461, 259, 946, 259, 947, 259, 948, 259, 966, 259, 967, 261, 105, 261, - 114, 261, 117, 261, 118, 261, 946, 261, 947, 261, 961, 261, 966, 261, - 967, 259, 1085, 259, 594, 259, 99, 259, 597, 259, 240, 259, 604, 259, - 102, 259, 607, 259, 609, 259, 613, 259, 616, 259, 617, 259, 618, 259, - 7547, 259, 669, 259, 621, 259, 7557, 259, 671, 259, 625, 259, 624, 259, - 626, 259, 627, 259, 628, 259, 629, 259, 632, 259, 642, 259, 643, 259, - 427, 259, 649, 259, 650, 259, 7452, 259, 651, 259, 652, 259, 122, 259, - 656, 259, 657, 259, 658, 259, 952, 512, 65, 805, 512, 97, 805, 512, 66, - 775, 512, 98, 775, 512, 66, 803, 512, 98, 803, 512, 66, 817, 512, 98, - 817, 512, 199, 769, 512, 231, 769, 512, 68, 775, 512, 100, 775, 512, 68, - 803, 512, 100, 803, 512, 68, 817, 512, 100, 817, 512, 68, 807, 512, 100, - 807, 512, 68, 813, 512, 100, 813, 512, 274, 768, 512, 275, 768, 512, 274, - 769, 512, 275, 769, 512, 69, 813, 512, 101, 813, 512, 69, 816, 512, 101, - 816, 512, 552, 774, 512, 553, 774, 512, 70, 775, 512, 102, 775, 512, 71, - 772, 512, 103, 772, 512, 72, 775, 512, 104, 775, 512, 72, 803, 512, 104, - 803, 512, 72, 776, 512, 104, 776, 512, 72, 807, 512, 104, 807, 512, 72, - 814, 512, 104, 814, 512, 73, 816, 512, 105, 816, 512, 207, 769, 512, 239, - 769, 512, 75, 769, 512, 107, 769, 512, 75, 803, 512, 107, 803, 512, 75, - 817, 512, 107, 817, 512, 76, 803, 512, 108, 803, 512, 7734, 772, 512, - 7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, 813, 512, 108, 813, 512, - 77, 769, 512, 109, 769, 512, 77, 775, 512, 109, 775, 512, 77, 803, 512, - 109, 803, 512, 78, 775, 512, 110, 775, 512, 78, 803, 512, 110, 803, 512, - 78, 817, 512, 110, 817, 512, 78, 813, 512, 110, 813, 512, 213, 769, 512, - 245, 769, 512, 213, 776, 512, 245, 776, 512, 332, 768, 512, 333, 768, - 512, 332, 769, 512, 333, 769, 512, 80, 769, 512, 112, 769, 512, 80, 775, - 512, 112, 775, 512, 82, 775, 512, 114, 775, 512, 82, 803, 512, 114, 803, - 512, 7770, 772, 512, 7771, 772, 512, 82, 817, 512, 114, 817, 512, 83, - 775, 512, 115, 775, 512, 83, 803, 512, 115, 803, 512, 346, 775, 512, 347, - 775, 512, 352, 775, 512, 353, 775, 512, 7778, 775, 512, 7779, 775, 512, - 84, 775, 512, 116, 775, 512, 84, 803, 512, 116, 803, 512, 84, 817, 512, - 116, 817, 512, 84, 813, 512, 116, 813, 512, 85, 804, 512, 117, 804, 512, - 85, 816, 512, 117, 816, 512, 85, 813, 512, 117, 813, 512, 360, 769, 512, - 361, 769, 512, 362, 776, 512, 363, 776, 512, 86, 771, 512, 118, 771, 512, - 86, 803, 512, 118, 803, 512, 87, 768, 512, 119, 768, 512, 87, 769, 512, - 119, 769, 512, 87, 776, 512, 119, 776, 512, 87, 775, 512, 119, 775, 512, - 87, 803, 512, 119, 803, 512, 88, 775, 512, 120, 775, 512, 88, 776, 512, - 120, 776, 512, 89, 775, 512, 121, 775, 512, 90, 770, 512, 122, 770, 512, - 90, 803, 512, 122, 803, 512, 90, 817, 512, 122, 817, 512, 104, 817, 512, - 116, 776, 512, 119, 778, 512, 121, 778, 514, 97, 702, 512, 383, 775, 512, - 65, 803, 512, 97, 803, 512, 65, 777, 512, 97, 777, 512, 194, 769, 512, - 226, 769, 512, 194, 768, 512, 226, 768, 512, 194, 777, 512, 226, 777, - 512, 194, 771, 512, 226, 771, 512, 7840, 770, 512, 7841, 770, 512, 258, - 769, 512, 259, 769, 512, 258, 768, 512, 259, 768, 512, 258, 777, 512, - 259, 777, 512, 258, 771, 512, 259, 771, 512, 7840, 774, 512, 7841, 774, - 512, 69, 803, 512, 101, 803, 512, 69, 777, 512, 101, 777, 512, 69, 771, - 512, 101, 771, 512, 202, 769, 512, 234, 769, 512, 202, 768, 512, 234, - 768, 512, 202, 777, 512, 234, 777, 512, 202, 771, 512, 234, 771, 512, - 7864, 770, 512, 7865, 770, 512, 73, 777, 512, 105, 777, 512, 73, 803, - 512, 105, 803, 512, 79, 803, 512, 111, 803, 512, 79, 777, 512, 111, 777, - 512, 212, 769, 512, 244, 769, 512, 212, 768, 512, 244, 768, 512, 212, - 777, 512, 244, 777, 512, 212, 771, 512, 244, 771, 512, 7884, 770, 512, - 7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, 768, 512, 417, 768, - 512, 416, 777, 512, 417, 777, 512, 416, 771, 512, 417, 771, 512, 416, - 803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, 85, 777, 512, 117, - 777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, 432, 768, 512, - 431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, 512, 431, 803, - 512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, 512, 121, 803, - 512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, 512, 945, 787, - 512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, 769, 512, 7937, - 769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, 913, 788, 512, - 7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, 512, 7944, - 834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, 768, 512, - 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, 917, 788, - 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, 512, 951, - 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, 769, 512, - 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, 919, 788, - 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, 512, - 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, 768, - 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, - 7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768, 512, 7993, 768, - 512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512, 7993, 834, 512, 959, - 787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768, 512, 8000, 769, 512, - 8001, 769, 512, 927, 787, 512, 927, 788, 512, 8008, 768, 512, 8009, 768, - 512, 8008, 769, 512, 8009, 769, 512, 965, 787, 512, 965, 788, 512, 8016, - 768, 512, 8017, 768, 512, 8016, 769, 512, 8017, 769, 512, 8016, 834, 512, - 8017, 834, 512, 933, 788, 512, 8025, 768, 512, 8025, 769, 512, 8025, 834, - 512, 969, 787, 512, 969, 788, 512, 8032, 768, 512, 8033, 768, 512, 8032, - 769, 512, 8033, 769, 512, 8032, 834, 512, 8033, 834, 512, 937, 787, 512, - 937, 788, 512, 8040, 768, 512, 8041, 768, 512, 8040, 769, 512, 8041, 769, - 512, 8040, 834, 512, 8041, 834, 512, 945, 768, 256, 940, 512, 949, 768, - 256, 941, 512, 951, 768, 256, 942, 512, 953, 768, 256, 943, 512, 959, - 768, 256, 972, 512, 965, 768, 256, 973, 512, 969, 768, 256, 974, 512, - 7936, 837, 512, 7937, 837, 512, 7938, 837, 512, 7939, 837, 512, 7940, - 837, 512, 7941, 837, 512, 7942, 837, 512, 7943, 837, 512, 7944, 837, 512, - 7945, 837, 512, 7946, 837, 512, 7947, 837, 512, 7948, 837, 512, 7949, - 837, 512, 7950, 837, 512, 7951, 837, 512, 7968, 837, 512, 7969, 837, 512, - 7970, 837, 512, 7971, 837, 512, 7972, 837, 512, 7973, 837, 512, 7974, - 837, 512, 7975, 837, 512, 7976, 837, 512, 7977, 837, 512, 7978, 837, 512, - 7979, 837, 512, 7980, 837, 512, 7981, 837, 512, 7982, 837, 512, 7983, - 837, 512, 8032, 837, 512, 8033, 837, 512, 8034, 837, 512, 8035, 837, 512, - 8036, 837, 512, 8037, 837, 512, 8038, 837, 512, 8039, 837, 512, 8040, - 837, 512, 8041, 837, 512, 8042, 837, 512, 8043, 837, 512, 8044, 837, 512, - 8045, 837, 512, 8046, 837, 512, 8047, 837, 512, 945, 774, 512, 945, 772, - 512, 8048, 837, 512, 945, 837, 512, 940, 837, 512, 945, 834, 512, 8118, - 837, 512, 913, 774, 512, 913, 772, 512, 913, 768, 256, 902, 512, 913, - 837, 514, 32, 787, 256, 953, 514, 32, 787, 514, 32, 834, 512, 168, 834, - 512, 8052, 837, 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, - 837, 512, 917, 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, - 512, 8127, 768, 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, - 772, 512, 970, 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, - 774, 512, 921, 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, - 769, 512, 8190, 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, - 944, 512, 961, 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, - 933, 774, 512, 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, - 168, 768, 256, 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, - 837, 512, 969, 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, - 768, 256, 911, 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, - 8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32, 257, 32, 258, 32, 258, - 32, 258, 32, 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, - 46, 257, 32, 514, 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, - 770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, - 33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258, 32, 259, 48, 259, - 105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, - 8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48, 261, 49, 261, 50, - 261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56, 261, 57, 261, 43, - 261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261, 101, 261, 111, 261, - 120, 261, 601, 261, 104, 261, 107, 261, 108, 261, 109, 261, 110, 261, - 112, 261, 115, 261, 116, 514, 82, 115, 770, 97, 47, 99, 770, 97, 47, 115, - 262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117, 258, 400, 514, - 176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104, 262, 295, 262, - 73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, 80, 262, 81, - 262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, - 262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66, 262, 67, 262, - 101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258, 1489, 258, - 1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262, 947, 262, 915, - 262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262, 105, 262, 106, - 772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, 49, 48, 772, 49, - 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, 8260, 53, 772, - 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, 53, 8260, 54, - 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, 772, 55, 8260, - 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, 514, 73, 86, - 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, 514, 73, 88, - 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, 258, 68, 258, - 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, 118, 258, 118, - 514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, 105, 514, 105, - 120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, 108, 258, 99, 258, - 100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, 8594, 824, 512, - 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512, 8707, - 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741, 824, 514, - 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750, 8750, - 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776, 824, - 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62, 824, - 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512, - 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834, - 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512, - 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829, - 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512, - 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263, - 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48, - 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49, - 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41, - 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770, - 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40, - 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51, - 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41, - 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026, - 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514, - 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48, - 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46, - 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770, - 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40, - 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40, - 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40, - 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40, - 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40, - 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40, - 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65, - 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73, - 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81, - 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89, - 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263, - 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263, - 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263, - 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026, - 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61, - 512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, 40863, - 258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101, - 258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843, - 258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992, - 258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313, - 258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475, - 258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805, - 258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567, - 258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037, - 258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308, - 258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435, - 258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908, - 258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085, - 258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513, - 258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668, - 258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247, - 258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577, - 258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000, - 258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399, - 258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160, - 258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992, - 258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780, - 258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258, - 258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390, - 258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892, - 258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895, - 258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208, - 258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789, - 258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263, - 258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737, - 258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899, - 258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321, - 258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727, - 258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575, - 258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697, - 258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778, - 258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258, - 21313, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, - 12367, 12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441, - 512, 12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381, - 12441, 512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512, - 12390, 12441, 512, 12392, 12441, 512, 12399, 12441, 512, 12399, 12442, - 512, 12402, 12441, 512, 12402, 12442, 512, 12405, 12441, 512, 12405, - 12442, 512, 12408, 12441, 512, 12408, 12442, 512, 12411, 12441, 512, - 12411, 12442, 512, 12358, 12441, 514, 32, 12441, 514, 32, 12442, 512, - 12445, 12441, 521, 12424, 12426, 512, 12459, 12441, 512, 12461, 12441, - 512, 12463, 12441, 512, 12465, 12441, 512, 12467, 12441, 512, 12469, - 12441, 512, 12471, 12441, 512, 12473, 12441, 512, 12475, 12441, 512, - 12477, 12441, 512, 12479, 12441, 512, 12481, 12441, 512, 12484, 12441, - 512, 12486, 12441, 512, 12488, 12441, 512, 12495, 12441, 512, 12495, - 12442, 512, 12498, 12441, 512, 12498, 12442, 512, 12501, 12441, 512, - 12501, 12442, 512, 12504, 12441, 512, 12504, 12442, 512, 12507, 12441, - 512, 12507, 12442, 512, 12454, 12441, 512, 12527, 12441, 512, 12528, - 12441, 512, 12529, 12441, 512, 12530, 12441, 512, 12541, 12441, 521, - 12467, 12488, 258, 4352, 258, 4353, 258, 4522, 258, 4354, 258, 4524, 258, - 4525, 258, 4355, 258, 4356, 258, 4357, 258, 4528, 258, 4529, 258, 4530, - 258, 4531, 258, 4532, 258, 4533, 258, 4378, 258, 4358, 258, 4359, 258, - 4360, 258, 4385, 258, 4361, 258, 4362, 258, 4363, 258, 4364, 258, 4365, - 258, 4366, 258, 4367, 258, 4368, 258, 4369, 258, 4370, 258, 4449, 258, - 4450, 258, 4451, 258, 4452, 258, 4453, 258, 4454, 258, 4455, 258, 4456, - 258, 4457, 258, 4458, 258, 4459, 258, 4460, 258, 4461, 258, 4462, 258, - 4463, 258, 4464, 258, 4465, 258, 4466, 258, 4467, 258, 4468, 258, 4469, - 258, 4448, 258, 4372, 258, 4373, 258, 4551, 258, 4552, 258, 4556, 258, - 4558, 258, 4563, 258, 4567, 258, 4569, 258, 4380, 258, 4573, 258, 4575, - 258, 4381, 258, 4382, 258, 4384, 258, 4386, 258, 4387, 258, 4391, 258, - 4393, 258, 4395, 258, 4396, 258, 4397, 258, 4398, 258, 4399, 258, 4402, - 258, 4406, 258, 4416, 258, 4423, 258, 4428, 258, 4593, 258, 4594, 258, - 4439, 258, 4440, 258, 4441, 258, 4484, 258, 4485, 258, 4488, 258, 4497, - 258, 4498, 258, 4500, 258, 4510, 258, 4513, 259, 19968, 259, 20108, 259, - 19977, 259, 22235, 259, 19978, 259, 20013, 259, 19979, 259, 30002, 259, - 20057, 259, 19993, 259, 19969, 259, 22825, 259, 22320, 259, 20154, 770, - 40, 4352, 41, 770, 40, 4354, 41, 770, 40, 4355, 41, 770, 40, 4357, 41, - 770, 40, 4358, 41, 770, 40, 4359, 41, 770, 40, 4361, 41, 770, 40, 4363, - 41, 770, 40, 4364, 41, 770, 40, 4366, 41, 770, 40, 4367, 41, 770, 40, - 4368, 41, 770, 40, 4369, 41, 770, 40, 4370, 41, 1026, 40, 4352, 4449, 41, - 1026, 40, 4354, 4449, 41, 1026, 40, 4355, 4449, 41, 1026, 40, 4357, 4449, - 41, 1026, 40, 4358, 4449, 41, 1026, 40, 4359, 4449, 41, 1026, 40, 4361, - 4449, 41, 1026, 40, 4363, 4449, 41, 1026, 40, 4364, 4449, 41, 1026, 40, - 4366, 4449, 41, 1026, 40, 4367, 4449, 41, 1026, 40, 4368, 4449, 41, 1026, - 40, 4369, 4449, 41, 1026, 40, 4370, 4449, 41, 1026, 40, 4364, 4462, 41, - 1794, 40, 4363, 4457, 4364, 4453, 4523, 41, 1538, 40, 4363, 4457, 4370, - 4462, 41, 770, 40, 19968, 41, 770, 40, 20108, 41, 770, 40, 19977, 41, - 770, 40, 22235, 41, 770, 40, 20116, 41, 770, 40, 20845, 41, 770, 40, - 19971, 41, 770, 40, 20843, 41, 770, 40, 20061, 41, 770, 40, 21313, 41, - 770, 40, 26376, 41, 770, 40, 28779, 41, 770, 40, 27700, 41, 770, 40, - 26408, 41, 770, 40, 37329, 41, 770, 40, 22303, 41, 770, 40, 26085, 41, - 770, 40, 26666, 41, 770, 40, 26377, 41, 770, 40, 31038, 41, 770, 40, - 21517, 41, 770, 40, 29305, 41, 770, 40, 36001, 41, 770, 40, 31069, 41, - 770, 40, 21172, 41, 770, 40, 20195, 41, 770, 40, 21628, 41, 770, 40, - 23398, 41, 770, 40, 30435, 41, 770, 40, 20225, 41, 770, 40, 36039, 41, - 770, 40, 21332, 41, 770, 40, 31085, 41, 770, 40, 20241, 41, 770, 40, - 33258, 41, 770, 40, 33267, 41, 263, 21839, 263, 24188, 263, 25991, 263, - 31631, 778, 80, 84, 69, 519, 50, 49, 519, 50, 50, 519, 50, 51, 519, 50, - 52, 519, 50, 53, 519, 50, 54, 519, 50, 55, 519, 50, 56, 519, 50, 57, 519, - 51, 48, 519, 51, 49, 519, 51, 50, 519, 51, 51, 519, 51, 52, 519, 51, 53, - 263, 4352, 263, 4354, 263, 4355, 263, 4357, 263, 4358, 263, 4359, 263, - 4361, 263, 4363, 263, 4364, 263, 4366, 263, 4367, 263, 4368, 263, 4369, - 263, 4370, 519, 4352, 4449, 519, 4354, 4449, 519, 4355, 4449, 519, 4357, - 4449, 519, 4358, 4449, 519, 4359, 4449, 519, 4361, 4449, 519, 4363, 4449, - 519, 4364, 4449, 519, 4366, 4449, 519, 4367, 4449, 519, 4368, 4449, 519, - 4369, 4449, 519, 4370, 4449, 1287, 4366, 4449, 4535, 4352, 4457, 1031, - 4364, 4462, 4363, 4468, 519, 4363, 4462, 263, 19968, 263, 20108, 263, - 19977, 263, 22235, 263, 20116, 263, 20845, 263, 19971, 263, 20843, 263, - 20061, 263, 21313, 263, 26376, 263, 28779, 263, 27700, 263, 26408, 263, - 37329, 263, 22303, 263, 26085, 263, 26666, 263, 26377, 263, 31038, 263, - 21517, 263, 29305, 263, 36001, 263, 31069, 263, 21172, 263, 31192, 263, - 30007, 263, 22899, 263, 36969, 263, 20778, 263, 21360, 263, 27880, 263, - 38917, 263, 20241, 263, 20889, 263, 27491, 263, 19978, 263, 20013, 263, - 19979, 263, 24038, 263, 21491, 263, 21307, 263, 23447, 263, 23398, 263, - 30435, 263, 20225, 263, 36039, 263, 21332, 263, 22812, 519, 51, 54, 519, - 51, 55, 519, 51, 56, 519, 51, 57, 519, 52, 48, 519, 52, 49, 519, 52, 50, - 519, 52, 51, 519, 52, 52, 519, 52, 53, 519, 52, 54, 519, 52, 55, 519, 52, - 56, 519, 52, 57, 519, 53, 48, 514, 49, 26376, 514, 50, 26376, 514, 51, - 26376, 514, 52, 26376, 514, 53, 26376, 514, 54, 26376, 514, 55, 26376, - 514, 56, 26376, 514, 57, 26376, 770, 49, 48, 26376, 770, 49, 49, 26376, - 770, 49, 50, 26376, 522, 72, 103, 778, 101, 114, 103, 522, 101, 86, 778, - 76, 84, 68, 263, 12450, 263, 12452, 263, 12454, 263, 12456, 263, 12458, - 263, 12459, 263, 12461, 263, 12463, 263, 12465, 263, 12467, 263, 12469, - 263, 12471, 263, 12473, 263, 12475, 263, 12477, 263, 12479, 263, 12481, - 263, 12484, 263, 12486, 263, 12488, 263, 12490, 263, 12491, 263, 12492, - 263, 12493, 263, 12494, 263, 12495, 263, 12498, 263, 12501, 263, 12504, - 263, 12507, 263, 12510, 263, 12511, 263, 12512, 263, 12513, 263, 12514, - 263, 12516, 263, 12518, 263, 12520, 263, 12521, 263, 12522, 263, 12523, - 263, 12524, 263, 12525, 263, 12527, 263, 12528, 263, 12529, 263, 12530, + 0, 257, 32, 514, 32, 776, 259, 97, 514, 32, 772, 259, 50, 259, 51, 514, + 32, 769, 258, 956, 514, 32, 807, 259, 49, 259, 111, 772, 49, 8260, 52, + 772, 49, 8260, 50, 772, 51, 8260, 52, 512, 65, 768, 512, 65, 769, 512, + 65, 770, 512, 65, 771, 512, 65, 776, 512, 65, 778, 512, 67, 807, 512, 69, + 768, 512, 69, 769, 512, 69, 770, 512, 69, 776, 512, 73, 768, 512, 73, + 769, 512, 73, 770, 512, 73, 776, 512, 78, 771, 512, 79, 768, 512, 79, + 769, 512, 79, 770, 512, 79, 771, 512, 79, 776, 512, 85, 768, 512, 85, + 769, 512, 85, 770, 512, 85, 776, 512, 89, 769, 512, 97, 768, 512, 97, + 769, 512, 97, 770, 512, 97, 771, 512, 97, 776, 512, 97, 778, 512, 99, + 807, 512, 101, 768, 512, 101, 769, 512, 101, 770, 512, 101, 776, 512, + 105, 768, 512, 105, 769, 512, 105, 770, 512, 105, 776, 512, 110, 771, + 512, 111, 768, 512, 111, 769, 512, 111, 770, 512, 111, 771, 512, 111, + 776, 512, 117, 768, 512, 117, 769, 512, 117, 770, 512, 117, 776, 512, + 121, 769, 512, 121, 776, 512, 65, 772, 512, 97, 772, 512, 65, 774, 512, + 97, 774, 512, 65, 808, 512, 97, 808, 512, 67, 769, 512, 99, 769, 512, 67, + 770, 512, 99, 770, 512, 67, 775, 512, 99, 775, 512, 67, 780, 512, 99, + 780, 512, 68, 780, 512, 100, 780, 512, 69, 772, 512, 101, 772, 512, 69, + 774, 512, 101, 774, 512, 69, 775, 512, 101, 775, 512, 69, 808, 512, 101, + 808, 512, 69, 780, 512, 101, 780, 512, 71, 770, 512, 103, 770, 512, 71, + 774, 512, 103, 774, 512, 71, 775, 512, 103, 775, 512, 71, 807, 512, 103, + 807, 512, 72, 770, 512, 104, 770, 512, 73, 771, 512, 105, 771, 512, 73, + 772, 512, 105, 772, 512, 73, 774, 512, 105, 774, 512, 73, 808, 512, 105, + 808, 512, 73, 775, 514, 73, 74, 514, 105, 106, 512, 74, 770, 512, 106, + 770, 512, 75, 807, 512, 107, 807, 512, 76, 769, 512, 108, 769, 512, 76, + 807, 512, 108, 807, 512, 76, 780, 512, 108, 780, 514, 76, 183, 514, 108, + 183, 512, 78, 769, 512, 110, 769, 512, 78, 807, 512, 110, 807, 512, 78, + 780, 512, 110, 780, 514, 700, 110, 512, 79, 772, 512, 111, 772, 512, 79, + 774, 512, 111, 774, 512, 79, 779, 512, 111, 779, 512, 82, 769, 512, 114, + 769, 512, 82, 807, 512, 114, 807, 512, 82, 780, 512, 114, 780, 512, 83, + 769, 512, 115, 769, 512, 83, 770, 512, 115, 770, 512, 83, 807, 512, 115, + 807, 512, 83, 780, 512, 115, 780, 512, 84, 807, 512, 116, 807, 512, 84, + 780, 512, 116, 780, 512, 85, 771, 512, 117, 771, 512, 85, 772, 512, 117, + 772, 512, 85, 774, 512, 117, 774, 512, 85, 778, 512, 117, 778, 512, 85, + 779, 512, 117, 779, 512, 85, 808, 512, 117, 808, 512, 87, 770, 512, 119, + 770, 512, 89, 770, 512, 121, 770, 512, 89, 776, 512, 90, 769, 512, 122, + 769, 512, 90, 775, 512, 122, 775, 512, 90, 780, 512, 122, 780, 258, 115, + 512, 79, 795, 512, 111, 795, 512, 85, 795, 512, 117, 795, 514, 68, 381, + 514, 68, 382, 514, 100, 382, 514, 76, 74, 514, 76, 106, 514, 108, 106, + 514, 78, 74, 514, 78, 106, 514, 110, 106, 512, 65, 780, 512, 97, 780, + 512, 73, 780, 512, 105, 780, 512, 79, 780, 512, 111, 780, 512, 85, 780, + 512, 117, 780, 512, 220, 772, 512, 252, 772, 512, 220, 769, 512, 252, + 769, 512, 220, 780, 512, 252, 780, 512, 220, 768, 512, 252, 768, 512, + 196, 772, 512, 228, 772, 512, 550, 772, 512, 551, 772, 512, 198, 772, + 512, 230, 772, 512, 71, 780, 512, 103, 780, 512, 75, 780, 512, 107, 780, + 512, 79, 808, 512, 111, 808, 512, 490, 772, 512, 491, 772, 512, 439, 780, + 512, 658, 780, 512, 106, 780, 514, 68, 90, 514, 68, 122, 514, 100, 122, + 512, 71, 769, 512, 103, 769, 512, 78, 768, 512, 110, 768, 512, 197, 769, + 512, 229, 769, 512, 198, 769, 512, 230, 769, 512, 216, 769, 512, 248, + 769, 512, 65, 783, 512, 97, 783, 512, 65, 785, 512, 97, 785, 512, 69, + 783, 512, 101, 783, 512, 69, 785, 512, 101, 785, 512, 73, 783, 512, 105, + 783, 512, 73, 785, 512, 105, 785, 512, 79, 783, 512, 111, 783, 512, 79, + 785, 512, 111, 785, 512, 82, 783, 512, 114, 783, 512, 82, 785, 512, 114, + 785, 512, 85, 783, 512, 117, 783, 512, 85, 785, 512, 117, 785, 512, 83, + 806, 512, 115, 806, 512, 84, 806, 512, 116, 806, 512, 72, 780, 512, 104, + 780, 512, 65, 775, 512, 97, 775, 512, 69, 807, 512, 101, 807, 512, 214, + 772, 512, 246, 772, 512, 213, 772, 512, 245, 772, 512, 79, 775, 512, 111, + 775, 512, 558, 772, 512, 559, 772, 512, 89, 772, 512, 121, 772, 259, 104, + 259, 614, 259, 106, 259, 114, 259, 633, 259, 635, 259, 641, 259, 119, + 259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514, + 32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661, + 256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256, + 59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, + 512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, + 769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, + 949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, + 512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, + 258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, + 258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, + 768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, + 1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, + 768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, + 1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, + 774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, + 1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, + 776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, + 1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, + 776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, + 1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, + 776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, + 1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, + 1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, + 514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, + 1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, + 2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, + 512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, + 2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, + 2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, + 512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, + 2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, + 3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, + 512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, + 3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, + 3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, + 514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, + 4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, + 512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, + 4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, + 4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, + 512, 4133, 4142, 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, + 6965, 512, 6923, 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, + 512, 6972, 6965, 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, + 65, 259, 198, 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, + 73, 259, 74, 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, + 80, 259, 82, 259, 84, 259, 85, 259, 87, 259, 97, 259, 592, 259, 593, 259, + 7426, 259, 98, 259, 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, + 103, 259, 107, 259, 109, 259, 331, 259, 111, 259, 596, 259, 7446, 259, + 7447, 259, 112, 259, 116, 259, 117, 259, 7453, 259, 623, 259, 118, 259, + 7461, 259, 946, 259, 947, 259, 948, 259, 966, 259, 967, 261, 105, 261, + 114, 261, 117, 261, 118, 261, 946, 261, 947, 261, 961, 261, 966, 261, + 967, 259, 1085, 259, 594, 259, 99, 259, 597, 259, 240, 259, 604, 259, + 102, 259, 607, 259, 609, 259, 613, 259, 616, 259, 617, 259, 618, 259, + 7547, 259, 669, 259, 621, 259, 7557, 259, 671, 259, 625, 259, 624, 259, + 626, 259, 627, 259, 628, 259, 629, 259, 632, 259, 642, 259, 643, 259, + 427, 259, 649, 259, 650, 259, 7452, 259, 651, 259, 652, 259, 122, 259, + 656, 259, 657, 259, 658, 259, 952, 512, 65, 805, 512, 97, 805, 512, 66, + 775, 512, 98, 775, 512, 66, 803, 512, 98, 803, 512, 66, 817, 512, 98, + 817, 512, 199, 769, 512, 231, 769, 512, 68, 775, 512, 100, 775, 512, 68, + 803, 512, 100, 803, 512, 68, 817, 512, 100, 817, 512, 68, 807, 512, 100, + 807, 512, 68, 813, 512, 100, 813, 512, 274, 768, 512, 275, 768, 512, 274, + 769, 512, 275, 769, 512, 69, 813, 512, 101, 813, 512, 69, 816, 512, 101, + 816, 512, 552, 774, 512, 553, 774, 512, 70, 775, 512, 102, 775, 512, 71, + 772, 512, 103, 772, 512, 72, 775, 512, 104, 775, 512, 72, 803, 512, 104, + 803, 512, 72, 776, 512, 104, 776, 512, 72, 807, 512, 104, 807, 512, 72, + 814, 512, 104, 814, 512, 73, 816, 512, 105, 816, 512, 207, 769, 512, 239, + 769, 512, 75, 769, 512, 107, 769, 512, 75, 803, 512, 107, 803, 512, 75, + 817, 512, 107, 817, 512, 76, 803, 512, 108, 803, 512, 7734, 772, 512, + 7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, 813, 512, 108, 813, 512, + 77, 769, 512, 109, 769, 512, 77, 775, 512, 109, 775, 512, 77, 803, 512, + 109, 803, 512, 78, 775, 512, 110, 775, 512, 78, 803, 512, 110, 803, 512, + 78, 817, 512, 110, 817, 512, 78, 813, 512, 110, 813, 512, 213, 769, 512, + 245, 769, 512, 213, 776, 512, 245, 776, 512, 332, 768, 512, 333, 768, + 512, 332, 769, 512, 333, 769, 512, 80, 769, 512, 112, 769, 512, 80, 775, + 512, 112, 775, 512, 82, 775, 512, 114, 775, 512, 82, 803, 512, 114, 803, + 512, 7770, 772, 512, 7771, 772, 512, 82, 817, 512, 114, 817, 512, 83, + 775, 512, 115, 775, 512, 83, 803, 512, 115, 803, 512, 346, 775, 512, 347, + 775, 512, 352, 775, 512, 353, 775, 512, 7778, 775, 512, 7779, 775, 512, + 84, 775, 512, 116, 775, 512, 84, 803, 512, 116, 803, 512, 84, 817, 512, + 116, 817, 512, 84, 813, 512, 116, 813, 512, 85, 804, 512, 117, 804, 512, + 85, 816, 512, 117, 816, 512, 85, 813, 512, 117, 813, 512, 360, 769, 512, + 361, 769, 512, 362, 776, 512, 363, 776, 512, 86, 771, 512, 118, 771, 512, + 86, 803, 512, 118, 803, 512, 87, 768, 512, 119, 768, 512, 87, 769, 512, + 119, 769, 512, 87, 776, 512, 119, 776, 512, 87, 775, 512, 119, 775, 512, + 87, 803, 512, 119, 803, 512, 88, 775, 512, 120, 775, 512, 88, 776, 512, + 120, 776, 512, 89, 775, 512, 121, 775, 512, 90, 770, 512, 122, 770, 512, + 90, 803, 512, 122, 803, 512, 90, 817, 512, 122, 817, 512, 104, 817, 512, + 116, 776, 512, 119, 778, 512, 121, 778, 514, 97, 702, 512, 383, 775, 512, + 65, 803, 512, 97, 803, 512, 65, 777, 512, 97, 777, 512, 194, 769, 512, + 226, 769, 512, 194, 768, 512, 226, 768, 512, 194, 777, 512, 226, 777, + 512, 194, 771, 512, 226, 771, 512, 7840, 770, 512, 7841, 770, 512, 258, + 769, 512, 259, 769, 512, 258, 768, 512, 259, 768, 512, 258, 777, 512, + 259, 777, 512, 258, 771, 512, 259, 771, 512, 7840, 774, 512, 7841, 774, + 512, 69, 803, 512, 101, 803, 512, 69, 777, 512, 101, 777, 512, 69, 771, + 512, 101, 771, 512, 202, 769, 512, 234, 769, 512, 202, 768, 512, 234, + 768, 512, 202, 777, 512, 234, 777, 512, 202, 771, 512, 234, 771, 512, + 7864, 770, 512, 7865, 770, 512, 73, 777, 512, 105, 777, 512, 73, 803, + 512, 105, 803, 512, 79, 803, 512, 111, 803, 512, 79, 777, 512, 111, 777, + 512, 212, 769, 512, 244, 769, 512, 212, 768, 512, 244, 768, 512, 212, + 777, 512, 244, 777, 512, 212, 771, 512, 244, 771, 512, 7884, 770, 512, + 7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, 768, 512, 417, 768, + 512, 416, 777, 512, 417, 777, 512, 416, 771, 512, 417, 771, 512, 416, + 803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, 85, 777, 512, 117, + 777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, 432, 768, 512, + 431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, 512, 431, 803, + 512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, 512, 121, 803, + 512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, 512, 945, 787, + 512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, 769, 512, 7937, + 769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, 913, 788, 512, + 7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, 512, 7944, + 834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, 768, 512, + 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, 917, 788, + 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, 512, 951, + 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, 769, 512, + 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, 919, 788, + 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, 512, + 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, 768, + 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, + 7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768, 512, 7993, 768, + 512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512, 7993, 834, 512, 959, + 787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768, 512, 8000, 769, 512, + 8001, 769, 512, 927, 787, 512, 927, 788, 512, 8008, 768, 512, 8009, 768, + 512, 8008, 769, 512, 8009, 769, 512, 965, 787, 512, 965, 788, 512, 8016, + 768, 512, 8017, 768, 512, 8016, 769, 512, 8017, 769, 512, 8016, 834, 512, + 8017, 834, 512, 933, 788, 512, 8025, 768, 512, 8025, 769, 512, 8025, 834, + 512, 969, 787, 512, 969, 788, 512, 8032, 768, 512, 8033, 768, 512, 8032, + 769, 512, 8033, 769, 512, 8032, 834, 512, 8033, 834, 512, 937, 787, 512, + 937, 788, 512, 8040, 768, 512, 8041, 768, 512, 8040, 769, 512, 8041, 769, + 512, 8040, 834, 512, 8041, 834, 512, 945, 768, 256, 940, 512, 949, 768, + 256, 941, 512, 951, 768, 256, 942, 512, 953, 768, 256, 943, 512, 959, + 768, 256, 972, 512, 965, 768, 256, 973, 512, 969, 768, 256, 974, 512, + 7936, 837, 512, 7937, 837, 512, 7938, 837, 512, 7939, 837, 512, 7940, + 837, 512, 7941, 837, 512, 7942, 837, 512, 7943, 837, 512, 7944, 837, 512, + 7945, 837, 512, 7946, 837, 512, 7947, 837, 512, 7948, 837, 512, 7949, + 837, 512, 7950, 837, 512, 7951, 837, 512, 7968, 837, 512, 7969, 837, 512, + 7970, 837, 512, 7971, 837, 512, 7972, 837, 512, 7973, 837, 512, 7974, + 837, 512, 7975, 837, 512, 7976, 837, 512, 7977, 837, 512, 7978, 837, 512, + 7979, 837, 512, 7980, 837, 512, 7981, 837, 512, 7982, 837, 512, 7983, + 837, 512, 8032, 837, 512, 8033, 837, 512, 8034, 837, 512, 8035, 837, 512, + 8036, 837, 512, 8037, 837, 512, 8038, 837, 512, 8039, 837, 512, 8040, + 837, 512, 8041, 837, 512, 8042, 837, 512, 8043, 837, 512, 8044, 837, 512, + 8045, 837, 512, 8046, 837, 512, 8047, 837, 512, 945, 774, 512, 945, 772, + 512, 8048, 837, 512, 945, 837, 512, 940, 837, 512, 945, 834, 512, 8118, + 837, 512, 913, 774, 512, 913, 772, 512, 913, 768, 256, 902, 512, 913, + 837, 514, 32, 787, 256, 953, 514, 32, 787, 514, 32, 834, 512, 168, 834, + 512, 8052, 837, 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, + 837, 512, 917, 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, + 512, 8127, 768, 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, + 772, 512, 970, 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, + 774, 512, 921, 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, + 769, 512, 8190, 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, + 944, 512, 961, 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, + 933, 774, 512, 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, + 168, 768, 256, 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, + 837, 512, 969, 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, + 768, 256, 911, 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, + 8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32, 257, 32, 258, 32, 258, + 32, 258, 32, 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, + 46, 257, 32, 514, 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, + 770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, + 33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258, 32, 259, 48, 259, + 105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, + 8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48, 261, 49, 261, 50, + 261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56, 261, 57, 261, 43, + 261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261, 101, 261, 111, 261, + 120, 261, 601, 261, 104, 261, 107, 261, 108, 261, 109, 261, 110, 261, + 112, 261, 115, 261, 116, 514, 82, 115, 770, 97, 47, 99, 770, 97, 47, 115, + 262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117, 258, 400, 514, + 176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104, 262, 295, 262, + 73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, 80, 262, 81, + 262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, + 262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66, 262, 67, 262, + 101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258, 1489, 258, + 1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262, 947, 262, 915, + 262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262, 105, 262, 106, + 772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, 49, 48, 772, 49, + 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, 8260, 53, 772, + 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, 53, 8260, 54, + 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, 772, 55, 8260, + 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, 514, 73, 86, + 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, 514, 73, 88, + 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, 258, 68, 258, + 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, 118, 258, 118, + 514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, 105, 514, 105, + 120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, 108, 258, 99, 258, + 100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, 8594, 824, 512, + 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512, 8707, + 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741, 824, 514, + 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750, 8750, + 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776, 824, + 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62, 824, + 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512, + 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834, + 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512, + 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829, + 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512, + 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263, + 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48, + 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49, + 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41, + 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770, + 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40, + 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51, + 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41, + 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026, + 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514, + 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48, + 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46, + 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770, + 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40, + 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40, + 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40, + 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40, + 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40, + 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40, + 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65, + 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73, + 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81, + 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89, + 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263, + 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263, + 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263, + 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026, + 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61, + 512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, 40863, + 258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101, + 258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843, + 258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992, + 258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313, + 258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475, + 258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805, + 258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567, + 258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037, + 258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308, + 258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435, + 258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908, + 258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085, + 258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513, + 258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668, + 258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247, + 258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577, + 258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000, + 258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399, + 258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160, + 258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992, + 258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780, + 258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258, + 258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390, + 258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892, + 258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895, + 258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208, + 258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789, + 258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263, + 258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737, + 258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899, + 258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321, + 258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727, + 258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575, + 258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697, + 258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778, + 258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258, + 21313, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, + 12367, 12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441, + 512, 12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381, + 12441, 512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512, + 12390, 12441, 512, 12392, 12441, 512, 12399, 12441, 512, 12399, 12442, + 512, 12402, 12441, 512, 12402, 12442, 512, 12405, 12441, 512, 12405, + 12442, 512, 12408, 12441, 512, 12408, 12442, 512, 12411, 12441, 512, + 12411, 12442, 512, 12358, 12441, 514, 32, 12441, 514, 32, 12442, 512, + 12445, 12441, 521, 12424, 12426, 512, 12459, 12441, 512, 12461, 12441, + 512, 12463, 12441, 512, 12465, 12441, 512, 12467, 12441, 512, 12469, + 12441, 512, 12471, 12441, 512, 12473, 12441, 512, 12475, 12441, 512, + 12477, 12441, 512, 12479, 12441, 512, 12481, 12441, 512, 12484, 12441, + 512, 12486, 12441, 512, 12488, 12441, 512, 12495, 12441, 512, 12495, + 12442, 512, 12498, 12441, 512, 12498, 12442, 512, 12501, 12441, 512, + 12501, 12442, 512, 12504, 12441, 512, 12504, 12442, 512, 12507, 12441, + 512, 12507, 12442, 512, 12454, 12441, 512, 12527, 12441, 512, 12528, + 12441, 512, 12529, 12441, 512, 12530, 12441, 512, 12541, 12441, 521, + 12467, 12488, 258, 4352, 258, 4353, 258, 4522, 258, 4354, 258, 4524, 258, + 4525, 258, 4355, 258, 4356, 258, 4357, 258, 4528, 258, 4529, 258, 4530, + 258, 4531, 258, 4532, 258, 4533, 258, 4378, 258, 4358, 258, 4359, 258, + 4360, 258, 4385, 258, 4361, 258, 4362, 258, 4363, 258, 4364, 258, 4365, + 258, 4366, 258, 4367, 258, 4368, 258, 4369, 258, 4370, 258, 4449, 258, + 4450, 258, 4451, 258, 4452, 258, 4453, 258, 4454, 258, 4455, 258, 4456, + 258, 4457, 258, 4458, 258, 4459, 258, 4460, 258, 4461, 258, 4462, 258, + 4463, 258, 4464, 258, 4465, 258, 4466, 258, 4467, 258, 4468, 258, 4469, + 258, 4448, 258, 4372, 258, 4373, 258, 4551, 258, 4552, 258, 4556, 258, + 4558, 258, 4563, 258, 4567, 258, 4569, 258, 4380, 258, 4573, 258, 4575, + 258, 4381, 258, 4382, 258, 4384, 258, 4386, 258, 4387, 258, 4391, 258, + 4393, 258, 4395, 258, 4396, 258, 4397, 258, 4398, 258, 4399, 258, 4402, + 258, 4406, 258, 4416, 258, 4423, 258, 4428, 258, 4593, 258, 4594, 258, + 4439, 258, 4440, 258, 4441, 258, 4484, 258, 4485, 258, 4488, 258, 4497, + 258, 4498, 258, 4500, 258, 4510, 258, 4513, 259, 19968, 259, 20108, 259, + 19977, 259, 22235, 259, 19978, 259, 20013, 259, 19979, 259, 30002, 259, + 20057, 259, 19993, 259, 19969, 259, 22825, 259, 22320, 259, 20154, 770, + 40, 4352, 41, 770, 40, 4354, 41, 770, 40, 4355, 41, 770, 40, 4357, 41, + 770, 40, 4358, 41, 770, 40, 4359, 41, 770, 40, 4361, 41, 770, 40, 4363, + 41, 770, 40, 4364, 41, 770, 40, 4366, 41, 770, 40, 4367, 41, 770, 40, + 4368, 41, 770, 40, 4369, 41, 770, 40, 4370, 41, 1026, 40, 4352, 4449, 41, + 1026, 40, 4354, 4449, 41, 1026, 40, 4355, 4449, 41, 1026, 40, 4357, 4449, + 41, 1026, 40, 4358, 4449, 41, 1026, 40, 4359, 4449, 41, 1026, 40, 4361, + 4449, 41, 1026, 40, 4363, 4449, 41, 1026, 40, 4364, 4449, 41, 1026, 40, + 4366, 4449, 41, 1026, 40, 4367, 4449, 41, 1026, 40, 4368, 4449, 41, 1026, + 40, 4369, 4449, 41, 1026, 40, 4370, 4449, 41, 1026, 40, 4364, 4462, 41, + 1794, 40, 4363, 4457, 4364, 4453, 4523, 41, 1538, 40, 4363, 4457, 4370, + 4462, 41, 770, 40, 19968, 41, 770, 40, 20108, 41, 770, 40, 19977, 41, + 770, 40, 22235, 41, 770, 40, 20116, 41, 770, 40, 20845, 41, 770, 40, + 19971, 41, 770, 40, 20843, 41, 770, 40, 20061, 41, 770, 40, 21313, 41, + 770, 40, 26376, 41, 770, 40, 28779, 41, 770, 40, 27700, 41, 770, 40, + 26408, 41, 770, 40, 37329, 41, 770, 40, 22303, 41, 770, 40, 26085, 41, + 770, 40, 26666, 41, 770, 40, 26377, 41, 770, 40, 31038, 41, 770, 40, + 21517, 41, 770, 40, 29305, 41, 770, 40, 36001, 41, 770, 40, 31069, 41, + 770, 40, 21172, 41, 770, 40, 20195, 41, 770, 40, 21628, 41, 770, 40, + 23398, 41, 770, 40, 30435, 41, 770, 40, 20225, 41, 770, 40, 36039, 41, + 770, 40, 21332, 41, 770, 40, 31085, 41, 770, 40, 20241, 41, 770, 40, + 33258, 41, 770, 40, 33267, 41, 263, 21839, 263, 24188, 263, 25991, 263, + 31631, 778, 80, 84, 69, 519, 50, 49, 519, 50, 50, 519, 50, 51, 519, 50, + 52, 519, 50, 53, 519, 50, 54, 519, 50, 55, 519, 50, 56, 519, 50, 57, 519, + 51, 48, 519, 51, 49, 519, 51, 50, 519, 51, 51, 519, 51, 52, 519, 51, 53, + 263, 4352, 263, 4354, 263, 4355, 263, 4357, 263, 4358, 263, 4359, 263, + 4361, 263, 4363, 263, 4364, 263, 4366, 263, 4367, 263, 4368, 263, 4369, + 263, 4370, 519, 4352, 4449, 519, 4354, 4449, 519, 4355, 4449, 519, 4357, + 4449, 519, 4358, 4449, 519, 4359, 4449, 519, 4361, 4449, 519, 4363, 4449, + 519, 4364, 4449, 519, 4366, 4449, 519, 4367, 4449, 519, 4368, 4449, 519, + 4369, 4449, 519, 4370, 4449, 1287, 4366, 4449, 4535, 4352, 4457, 1031, + 4364, 4462, 4363, 4468, 519, 4363, 4462, 263, 19968, 263, 20108, 263, + 19977, 263, 22235, 263, 20116, 263, 20845, 263, 19971, 263, 20843, 263, + 20061, 263, 21313, 263, 26376, 263, 28779, 263, 27700, 263, 26408, 263, + 37329, 263, 22303, 263, 26085, 263, 26666, 263, 26377, 263, 31038, 263, + 21517, 263, 29305, 263, 36001, 263, 31069, 263, 21172, 263, 31192, 263, + 30007, 263, 22899, 263, 36969, 263, 20778, 263, 21360, 263, 27880, 263, + 38917, 263, 20241, 263, 20889, 263, 27491, 263, 19978, 263, 20013, 263, + 19979, 263, 24038, 263, 21491, 263, 21307, 263, 23447, 263, 23398, 263, + 30435, 263, 20225, 263, 36039, 263, 21332, 263, 22812, 519, 51, 54, 519, + 51, 55, 519, 51, 56, 519, 51, 57, 519, 52, 48, 519, 52, 49, 519, 52, 50, + 519, 52, 51, 519, 52, 52, 519, 52, 53, 519, 52, 54, 519, 52, 55, 519, 52, + 56, 519, 52, 57, 519, 53, 48, 514, 49, 26376, 514, 50, 26376, 514, 51, + 26376, 514, 52, 26376, 514, 53, 26376, 514, 54, 26376, 514, 55, 26376, + 514, 56, 26376, 514, 57, 26376, 770, 49, 48, 26376, 770, 49, 49, 26376, + 770, 49, 50, 26376, 522, 72, 103, 778, 101, 114, 103, 522, 101, 86, 778, + 76, 84, 68, 263, 12450, 263, 12452, 263, 12454, 263, 12456, 263, 12458, + 263, 12459, 263, 12461, 263, 12463, 263, 12465, 263, 12467, 263, 12469, + 263, 12471, 263, 12473, 263, 12475, 263, 12477, 263, 12479, 263, 12481, + 263, 12484, 263, 12486, 263, 12488, 263, 12490, 263, 12491, 263, 12492, + 263, 12493, 263, 12494, 263, 12495, 263, 12498, 263, 12501, 263, 12504, + 263, 12507, 263, 12510, 263, 12511, 263, 12512, 263, 12513, 263, 12514, + 263, 12516, 263, 12518, 263, 12520, 263, 12521, 263, 12522, 263, 12523, + 263, 12524, 263, 12525, 263, 12527, 263, 12528, 263, 12529, 263, 12530, 522, 20196, 21644, 1034, 12450, 12497, 12540, 12488, 1034, 12450, 12523, 12501, 12449, 1034, 12450, 12531, 12506, 12450, 778, 12450, 12540, 12523, 1034, 12452, 12491, 12531, 12464, 778, 12452, 12531, 12481, 778, 12454, @@ -4129,40 +4129,40 @@ static const unsigned int decomp_data[] = { 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, + 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, + 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, - 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, - 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, - 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, + 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, + 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, + 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, - 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, - 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, - 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, - 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, - 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, - 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, - 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, - 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, - 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, - 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, - 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, - 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, - 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, - 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, + 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, + 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, + 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, + 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, + 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, + 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, + 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, + 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, + 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, + 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, + 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, + 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, + 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, + 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, + 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, + 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, + 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, + 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, + 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, + 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, @@ -4194,21 +4194,21 @@ static const unsigned int decomp_data[] = { 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, - 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, - 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, - 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, - 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, - 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, - 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, - 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, - 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, - 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, - 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, - 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, - 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, - 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, - 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, - 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, + 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, + 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, + 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, + 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, + 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, + 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, + 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, + 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, + 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, + 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, + 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, + 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, + 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, + 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, + 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, @@ -4373,2900 +4373,2900 @@ static const unsigned int decomp_data[] = { 19662, 256, 19693, 256, 40295, 256, 172238, 256, 19704, 256, 172293, 256, 172558, 256, 172689, 256, 40635, 256, 19798, 256, 40697, 256, 40702, 256, 40709, 256, 40719, 256, 40726, 256, 40763, 256, 173568, -}; - -/* index tables for the decomposition data */ -#define DECOMP_SHIFT 7 +}; + +/* index tables for the decomposition data */ +#define DECOMP_SHIFT 7 static const unsigned char decomp_index1[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 0, 0, 0, 0, 13, 14, 15, 0, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, - 45, 0, 0, 46, 0, 47, 0, 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 60, 61, 0, 0, 0, 0, 0, 0, 62, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 80, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 0, 0, 0, 0, 13, 14, 15, 0, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, + 45, 0, 0, 46, 0, 47, 0, 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 60, 61, 0, 0, 0, 0, 0, 0, 62, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 80, 0, 81, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 0, 0, 0, 0, 85, 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 94, 0, 0, 0, 0, 95, 96, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 100, 101, 102, 103, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const unsigned short decomp_index2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 3, 0, 6, 0, 0, 0, 0, 8, 0, 0, 11, 13, 15, 18, 0, 0, 20, 23, 25, 0, 27, + 31, 35, 0, 39, 42, 45, 48, 51, 54, 0, 57, 60, 63, 66, 69, 72, 75, 78, 81, + 0, 84, 87, 90, 93, 96, 99, 0, 0, 102, 105, 108, 111, 114, 0, 0, 117, 120, + 123, 126, 129, 132, 0, 135, 138, 141, 144, 147, 150, 153, 156, 159, 0, + 162, 165, 168, 171, 174, 177, 0, 0, 180, 183, 186, 189, 192, 0, 195, 198, + 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, + 243, 0, 0, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279, + 282, 285, 288, 291, 294, 297, 300, 303, 0, 0, 306, 309, 312, 315, 318, + 321, 324, 327, 330, 0, 333, 336, 339, 342, 345, 348, 0, 351, 354, 357, + 360, 363, 366, 369, 372, 0, 0, 375, 378, 381, 384, 387, 390, 393, 0, 0, + 396, 399, 402, 405, 408, 411, 0, 0, 414, 417, 420, 423, 426, 429, 432, + 435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 0, 0, 468, 471, + 474, 477, 480, 483, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513, + 516, 519, 522, 525, 528, 531, 534, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 539, 542, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 548, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 554, 557, 560, 563, 566, 569, 572, + 575, 578, 581, 584, 587, 590, 593, 596, 599, 602, 605, 608, 611, 614, + 617, 620, 623, 0, 626, 629, 632, 635, 638, 641, 0, 0, 644, 647, 650, 653, + 656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 0, 0, 692, + 695, 698, 701, 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, 734, + 737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, + 779, 782, 785, 788, 791, 794, 797, 0, 0, 800, 803, 0, 0, 0, 0, 0, 0, 806, + 809, 812, 815, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 848, 850, 852, 854, 856, 858, 860, 862, 864, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 866, + 869, 872, 875, 878, 881, 0, 0, 884, 886, 888, 890, 892, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, + 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, + 0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, + 969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0, + 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0, + 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, + 0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087, + 1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0, + 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, + 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174, 1177, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, + 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, + 1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, + 0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1285, 1288, 1291, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 1306, 1309, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1347, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, 0, 0, 1359, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1365, 0, + 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, 1398, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1407, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 1421, 0, 0, + 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1427, 0, 1430, + 0, 0, 1433, 1436, 0, 1439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1442, 1444, 1446, 0, + 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, 0, + 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, + 1494, 1496, 1498, 1500, 1502, 1504, 0, 1506, 1508, 1510, 1512, 1514, + 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1530, 1532, 1534, 1536, 1538, + 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1558, 1560, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, + 1588, 1590, 1592, 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, + 1612, 1614, 1616, 1618, 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, + 1636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1638, 1641, 1644, + 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680, + 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, + 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, + 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, + 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, + 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, + 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896, + 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, + 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968, + 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004, + 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040, + 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076, + 2079, 2082, 2085, 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106, + 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142, + 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178, + 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214, + 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250, + 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286, + 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322, + 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358, + 2361, 2364, 2367, 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385, + 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421, + 2424, 2427, 2430, 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454, + 2457, 0, 0, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487, + 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523, + 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559, + 2562, 2565, 2568, 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0, + 2592, 2595, 2598, 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0, + 2622, 0, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652, + 2655, 2658, 2661, 2664, 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686, + 2689, 2691, 2694, 2696, 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714, + 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750, + 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, + 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822, + 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858, + 2861, 2864, 2867, 0, 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890, + 2893, 2895, 2898, 2901, 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922, + 2924, 2927, 2929, 2932, 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952, + 2955, 2958, 2961, 2964, 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984, + 2987, 2989, 2992, 2995, 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018, + 3020, 0, 0, 3022, 3025, 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045, + 3047, 3050, 3052, 0, 3055, 3057, 3059, 3061, 3063, 3065, 3067, 3069, + 3071, 3073, 3075, 0, 0, 0, 0, 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0, + 3091, 0, 0, 0, 3093, 3096, 0, 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0, + 0, 0, 0, 0, 0, 0, 0, 3113, 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3122, 0, 0, 0, 0, 0, 0, 0, 3127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3129, 3131, 0, 0, 3133, 3135, 3137, 3139, 3141, 3143, + 3145, 3147, 3149, 3151, 3153, 3155, 3157, 3159, 3161, 3163, 3165, 3167, + 3169, 3171, 3173, 3175, 3177, 3179, 3181, 3183, 3185, 0, 3187, 3189, + 3191, 3193, 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3216, 3220, 3224, 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244, + 3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0, + 3267, 3269, 3271, 3273, 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289, + 0, 3291, 0, 3293, 3295, 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309, + 3311, 3313, 3315, 3317, 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0, + 0, 0, 0, 3335, 3337, 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349, + 3353, 3358, 3362, 3366, 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398, + 3402, 3406, 3409, 3411, 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438, + 3440, 3443, 3447, 3449, 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469, + 3472, 3476, 3481, 3484, 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3505, 3508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3514, 3517, 3520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3523, 0, 0, 0, 0, 3526, + 0, 0, 3529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3532, 0, 3535, 0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, + 0, 3561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3564, 0, 3567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579, + 3582, 0, 0, 3585, 3588, 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600, + 0, 0, 3603, 3606, 0, 0, 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3615, + 3618, 3621, 3624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3627, 3630, 3633, 3636, 0, 0, 0, 0, 0, 0, 3639, 3642, + 3645, 3648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3651, 3653, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 3669, + 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 3703, + 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747, 3752, + 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803, 3806, + 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844, 3848, + 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892, 3896, + 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940, 3944, + 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980, 3982, + 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, + 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028, 4030, + 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052, 4054, + 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4083, 4087, 4090, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 4099, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4107, + 4109, 4111, 4113, 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, + 4133, 4135, 4137, 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, + 4157, 4159, 4161, 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, + 4181, 4183, 4185, 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, + 4205, 4207, 4209, 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, + 4229, 4231, 4233, 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, + 4253, 4255, 4257, 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, + 4277, 4279, 4281, 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, + 4301, 4303, 4305, 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, + 4325, 4327, 4329, 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, + 4349, 4351, 4353, 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, + 4373, 4375, 4377, 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, + 4397, 4399, 4401, 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, + 4421, 4423, 4425, 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, + 4445, 4447, 4449, 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, + 4469, 4471, 4473, 4475, 4477, 4479, 4481, 4483, 4485, 4487, 4489, 4491, + 4493, 4495, 4497, 4499, 4501, 4503, 4505, 4507, 4509, 4511, 4513, 4515, + 4517, 4519, 4521, 4523, 4525, 4527, 4529, 4531, 4533, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, + 4541, 4543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, + 4548, 0, 4551, 0, 4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, + 4572, 0, 4575, 0, 4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, + 4590, 4593, 0, 4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4620, + 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0, 4653, 0, + 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674, 0, 4677, + 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0, 4698, + 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716, 4719, 4722, 0, 0, 0, 4725, 4728, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4731, 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, + 4753, 4755, 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, + 4777, 4779, 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, + 4801, 4803, 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, + 4825, 4827, 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, + 4849, 4851, 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, + 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 4895, + 4897, 4899, 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, 4917, 0, 0, + 0, 4919, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, + 4941, 4943, 4945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4947, 4951, 4955, 4959, 4963, 4967, 4971, 4975, 4979, + 4983, 4987, 4991, 4995, 4999, 5003, 5008, 5013, 5018, 5023, 5028, 5033, + 5038, 5043, 5048, 5053, 5058, 5063, 5068, 5073, 5078, 5086, 0, 5093, + 5097, 5101, 5105, 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, + 5145, 5149, 5153, 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5189, + 5193, 5197, 5201, 5205, 5209, 5213, 5217, 5221, 5225, 5229, 5233, 5237, + 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0, 5245, 5249, 5252, 5255, 5258, + 5261, 5264, 5267, 5270, 5273, 5276, 5279, 5282, 5285, 5288, 5291, 5294, + 5296, 5298, 5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, + 5320, 5322, 5325, 5328, 5331, 5334, 5337, 5340, 5343, 5346, 5349, 5352, + 5355, 5358, 5361, 5364, 5370, 5375, 0, 5378, 5380, 5382, 5384, 5386, + 5388, 5390, 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, + 5412, 5414, 5416, 5418, 5420, 5422, 5424, 5426, 5428, 5430, 5432, 5434, + 5436, 5438, 5440, 5442, 5444, 5446, 5448, 5450, 5452, 5454, 5456, 5458, + 5460, 5462, 5464, 5466, 5468, 5470, 5472, 5474, 5476, 5479, 5482, 5485, + 5488, 5491, 5494, 5497, 5500, 5503, 5506, 5509, 5512, 5515, 5518, 5521, + 5524, 5527, 5530, 5533, 5536, 5539, 5542, 5545, 5548, 5552, 5556, 5560, + 5563, 5567, 5570, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, + 5592, 5594, 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, + 5616, 5618, 5620, 5622, 5624, 5626, 5628, 5630, 5632, 5634, 5636, 5638, + 5640, 5642, 5644, 5646, 5648, 5650, 5652, 5654, 5656, 5658, 5660, 5662, + 5664, 5666, 5668, 5671, 5676, 5681, 5686, 5690, 5695, 5699, 5703, 5709, + 5714, 5718, 5722, 5726, 5731, 5736, 5740, 5744, 5747, 5751, 5756, 5761, + 5764, 5770, 5777, 5783, 5787, 5793, 5799, 5804, 5808, 5812, 5816, 5821, + 5827, 5832, 5836, 5840, 5844, 5847, 5850, 5853, 5856, 5860, 5864, 5870, + 5874, 5879, 5885, 5889, 5892, 5895, 5901, 5906, 5912, 5916, 5922, 5925, + 5929, 5933, 5937, 5941, 5945, 5950, 5954, 5957, 5961, 5965, 5969, 5974, + 5978, 5982, 5986, 5992, 5997, 6000, 6006, 6009, 6014, 6019, 6023, 6027, + 6031, 6036, 6039, 6043, 6048, 6051, 6057, 6061, 6064, 6067, 6070, 6073, + 6076, 6079, 6082, 6085, 6088, 6091, 6095, 6099, 6103, 6107, 6111, 6115, + 6119, 6123, 6127, 6131, 6135, 6139, 6143, 6147, 6151, 6155, 6158, 6161, + 6165, 6168, 6171, 6174, 6178, 6182, 6185, 6188, 6191, 6194, 6197, 6202, + 6205, 6208, 6211, 6214, 6217, 6220, 6223, 6226, 6230, 6235, 6238, 6241, + 6244, 6247, 6250, 6253, 6256, 6260, 6264, 6268, 6272, 6275, 6278, 6281, + 6284, 6287, 6290, 6293, 6296, 6299, 6302, 6306, 6310, 6313, 6317, 6321, + 6325, 6328, 6332, 6336, 6341, 6344, 6348, 6352, 6356, 6360, 6366, 6373, + 6376, 6379, 6382, 6385, 6388, 6391, 6394, 6397, 6400, 6403, 6406, 6409, + 6412, 6415, 6418, 6421, 6424, 6427, 6432, 6435, 6438, 6441, 6446, 6450, + 6453, 6456, 6459, 6462, 6465, 6468, 6471, 6474, 6477, 6480, 6484, 6487, + 6490, 6494, 6498, 6501, 6506, 6510, 6513, 6516, 6519, 6522, 6526, 6530, + 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6557, 6561, 6565, 6569, + 6573, 6577, 6581, 6585, 6589, 6593, 6597, 6601, 6605, 6609, 6613, 6617, + 6621, 6625, 6629, 6633, 6637, 6641, 6645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6649, 6651, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6653, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6655, 6657, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6659, 6661, 6663, 6665, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6669, 6671, 6673, 6675, 6677, 6679, 6681, 6683, + 6685, 6687, 6689, 6691, 6693, 6695, 6697, 6699, 6701, 6703, 6705, 6707, + 6709, 6711, 6713, 6715, 6717, 6719, 6721, 6723, 6725, 6727, 6729, 6731, + 6733, 6735, 6737, 6739, 6741, 6743, 6745, 6747, 6749, 6751, 6753, 6755, + 6757, 6759, 6761, 6763, 6765, 6767, 6769, 6771, 6773, 6775, 6777, 6779, + 6781, 6783, 6785, 6787, 6789, 6791, 6793, 6795, 6797, 6799, 6801, 6803, + 6805, 6807, 6809, 6811, 6813, 6815, 6817, 6819, 6821, 6823, 6825, 6827, + 6829, 6831, 6833, 6835, 6837, 6839, 6841, 6843, 6845, 6847, 6849, 6851, + 6853, 6855, 6857, 6859, 6861, 6863, 6865, 6867, 6869, 6871, 6873, 6875, + 6877, 6879, 6881, 6883, 6885, 6887, 6889, 6891, 6893, 6895, 6897, 6899, + 6901, 6903, 6905, 6907, 6909, 6911, 6913, 6915, 6917, 6919, 6921, 6923, + 6925, 6927, 6929, 6931, 6933, 6935, 6937, 6939, 6941, 6943, 6945, 6947, + 6949, 6951, 6953, 6955, 6957, 6959, 6961, 6963, 6965, 6967, 6969, 6971, + 6973, 6975, 6977, 6979, 6981, 6983, 6985, 6987, 6989, 6991, 6993, 6995, + 6997, 6999, 7001, 7003, 7005, 7007, 7009, 7011, 7013, 7015, 7017, 7019, + 7021, 7023, 7025, 7027, 7029, 7031, 7033, 7035, 7037, 7039, 7041, 7043, + 7045, 7047, 7049, 7051, 7053, 7055, 7057, 7059, 7061, 7063, 7065, 7067, + 7069, 7071, 7073, 7075, 7077, 7079, 7081, 7083, 7085, 7087, 7089, 7091, + 7093, 7095, 7097, 7099, 7101, 7103, 7105, 7107, 7109, 7111, 7113, 7115, + 7117, 7119, 7121, 7123, 7125, 7127, 7129, 7131, 7133, 7135, 7137, 7139, + 7141, 7143, 7145, 7147, 7149, 7151, 7153, 7155, 7157, 7159, 7161, 7163, + 7165, 7167, 7169, 7171, 7173, 7175, 7177, 7179, 7181, 7183, 7185, 7187, + 7189, 7191, 7193, 7195, 7197, 7199, 7201, 7203, 7205, 7207, 0, 0, 7209, + 0, 7211, 0, 0, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 7229, + 7231, 0, 7233, 0, 7235, 0, 0, 7237, 7239, 0, 0, 0, 7241, 7243, 7245, + 7247, 7249, 7251, 7253, 7255, 7257, 7259, 7261, 7263, 7265, 7267, 7269, + 7271, 7273, 7275, 7277, 7279, 7281, 7283, 7285, 7287, 7289, 7291, 7293, + 7295, 7297, 7299, 7301, 7303, 7305, 7307, 7309, 7311, 7313, 7315, 7317, + 7319, 7321, 7323, 7325, 7327, 7329, 7331, 7333, 7335, 7337, 7339, 7341, + 7343, 7345, 7347, 7349, 7351, 7353, 7355, 7357, 7359, 7361, 7363, 7365, + 7367, 7369, 7371, 7373, 7375, 0, 0, 7377, 7379, 7381, 7383, 7385, 7387, + 7389, 7391, 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, + 7413, 7415, 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, + 7437, 7439, 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, + 7461, 7463, 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, + 7485, 7487, 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, + 7509, 7511, 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, + 7533, 7535, 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7553, 7555, + 7557, 7559, 7561, 7563, 7565, 7567, 7569, 7571, 7573, 7575, 7577, 7579, + 7581, 7583, 7585, 7587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7589, + 7592, 7595, 7598, 7602, 7606, 7609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7612, 7615, 7618, 7621, 7624, 0, 0, 0, 0, 0, 7627, 0, 7630, 7633, 7635, + 7637, 7639, 7641, 7643, 7645, 7647, 7649, 7651, 7653, 7656, 7659, 7662, + 7665, 7668, 7671, 7674, 7677, 7680, 7683, 7686, 7689, 0, 7692, 7695, + 7698, 7701, 7704, 0, 7707, 0, 7710, 7713, 0, 7716, 7719, 0, 7722, 7725, + 7728, 7731, 7734, 7737, 7740, 7743, 7746, 7749, 7752, 7754, 7756, 7758, + 7760, 7762, 7764, 7766, 7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782, + 7784, 7786, 7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, 7804, 7806, + 7808, 7810, 7812, 7814, 7816, 7818, 7820, 7822, 7824, 7826, 7828, 7830, + 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, + 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, + 7880, 7882, 7884, 7886, 7888, 7890, 7892, 7894, 7896, 7898, 7900, 7902, + 7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, 7924, 7926, + 7928, 7930, 7932, 7934, 7936, 7938, 7940, 7942, 7944, 7946, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7948, 7950, 7952, 7954, 7956, 7958, 7960, 7962, 7964, + 7966, 7968, 7970, 7972, 7974, 7976, 7978, 7980, 7982, 7984, 7986, 7988, + 7990, 7992, 7994, 7997, 8000, 8003, 8006, 8009, 8012, 8015, 8018, 8021, + 8024, 8027, 8030, 8033, 8036, 8039, 8042, 8045, 8048, 8050, 8052, 8054, + 8056, 8059, 8062, 8065, 8068, 8071, 8074, 8077, 8080, 8083, 8086, 8089, + 8092, 8095, 8098, 8101, 8104, 8107, 8110, 8113, 8116, 8119, 8122, 8125, + 8128, 8131, 8134, 8137, 8140, 8143, 8146, 8149, 8152, 8155, 8158, 8161, + 8164, 8167, 8170, 8173, 8176, 8179, 8182, 8185, 8188, 8191, 8194, 8197, + 8200, 8203, 8206, 8209, 8212, 8215, 8218, 8221, 8224, 8227, 8230, 8233, + 8236, 8239, 8242, 8245, 8248, 8251, 8254, 8257, 8260, 8263, 8266, 8269, + 8272, 8275, 8278, 8281, 8284, 8287, 8290, 8293, 8296, 8299, 8302, 8305, + 8308, 8311, 8314, 8317, 8320, 8323, 8326, 8329, 8332, 8335, 8338, 8342, + 8346, 8350, 8354, 8358, 8362, 8365, 8368, 8371, 8374, 8377, 8380, 8383, + 8386, 8389, 8392, 8395, 8398, 8401, 8404, 8407, 8410, 8413, 8416, 8419, + 8422, 8425, 8428, 8431, 8434, 8437, 8440, 8443, 8446, 8449, 8452, 8455, + 8458, 8461, 8464, 8467, 8470, 8473, 8476, 8479, 8482, 8485, 8488, 8491, + 8494, 8497, 8500, 8503, 8506, 8509, 8512, 8515, 8518, 8521, 8524, 8527, + 8530, 8533, 8536, 8539, 8542, 8545, 8548, 8551, 8554, 8557, 8560, 8563, + 8566, 8569, 8572, 8575, 8578, 8581, 8584, 8587, 8590, 8593, 8596, 8599, + 8602, 8605, 8608, 8611, 8614, 8617, 8620, 8623, 8626, 8629, 8632, 8635, + 8638, 8641, 8644, 8647, 8650, 8653, 8656, 8659, 8662, 8665, 8668, 8671, + 8674, 8677, 8680, 8683, 8686, 8689, 8692, 8695, 8698, 8701, 8704, 8707, + 8710, 8713, 8716, 8719, 8722, 8725, 8728, 8731, 8734, 8737, 8740, 8743, + 8746, 8749, 8752, 8755, 8758, 8761, 8764, 8767, 8770, 8773, 8776, 8779, + 8782, 8785, 8788, 8792, 8796, 8800, 8803, 8806, 8809, 8812, 8815, 8818, + 8821, 8824, 8827, 8830, 8833, 8836, 8839, 8842, 8845, 8848, 8851, 8854, + 8857, 8860, 8863, 8866, 8869, 8872, 8875, 8878, 8881, 8884, 8887, 8890, + 8893, 8896, 8899, 8902, 8905, 8908, 8911, 8914, 8917, 8920, 8923, 8926, + 8929, 8932, 8935, 8938, 8941, 8944, 8947, 8950, 8953, 8956, 8959, 8962, + 8965, 8968, 8971, 8974, 8977, 8980, 8983, 8986, 8989, 8992, 8995, 8998, + 9001, 9004, 9007, 9010, 9013, 9016, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9019, 9023, 9027, 9031, 9035, 9039, 9043, 9047, 9051, + 9055, 9059, 9063, 9067, 9071, 9075, 9079, 9083, 9087, 9091, 9095, 9099, + 9103, 9107, 9111, 9115, 9119, 9123, 9127, 9131, 9135, 9139, 9143, 9147, + 9151, 9155, 9159, 9163, 9167, 9171, 9175, 9179, 9183, 9187, 9191, 9195, + 9199, 9203, 9207, 9211, 9215, 9219, 9223, 9227, 9231, 9235, 9239, 9243, + 9247, 9251, 9255, 9259, 9263, 9267, 9271, 0, 0, 9275, 9279, 9283, 9287, + 9291, 9295, 9299, 9303, 9307, 9311, 9315, 9319, 9323, 9327, 9331, 9335, + 9339, 9343, 9347, 9351, 9355, 9359, 9363, 9367, 9371, 9375, 9379, 9383, + 9387, 9391, 9395, 9399, 9403, 9407, 9411, 9415, 9419, 9423, 9427, 9431, + 9435, 9439, 9443, 9447, 9451, 9455, 9459, 9463, 9467, 9471, 9475, 9479, + 9483, 9487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9491, 9495, + 9499, 9504, 9509, 9514, 9519, 9524, 9529, 9534, 9538, 9557, 9566, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9571, 9573, 9575, + 9577, 9579, 9581, 9583, 9585, 9587, 9589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9591, 9593, 9595, 9597, 9599, 9601, + 9603, 9605, 9607, 9609, 9611, 9613, 9615, 9617, 9619, 9621, 9623, 9625, + 9627, 9629, 9631, 0, 0, 9633, 9635, 9637, 9639, 9641, 9643, 9645, 9647, + 9649, 9651, 9653, 9655, 0, 9657, 9659, 9661, 9663, 9665, 9667, 9669, + 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, 9693, + 0, 9695, 9697, 9699, 9701, 0, 0, 0, 0, 9703, 9706, 9709, 0, 9712, 0, + 9715, 9718, 9721, 9724, 9727, 9730, 9733, 9736, 9739, 9742, 9745, 9747, + 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763, 9765, 9767, 9769, 9771, + 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787, 9789, 9791, 9793, 9795, + 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811, 9813, 9815, 9817, 9819, + 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835, 9837, 9839, 9841, 9843, + 9845, 9847, 9849, 9851, 9853, 9855, 9857, 9859, 9861, 9863, 9865, 9867, + 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, 9887, 9889, 9891, + 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, 9911, 9913, 9915, + 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, 9935, 9937, 9939, + 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, 9959, 9961, 9963, + 9965, 9967, 9969, 9971, 9973, 9975, 9977, 9979, 9982, 9985, 9988, 9991, + 9994, 9997, 10000, 0, 0, 0, 0, 10003, 10005, 10007, 10009, 10011, 10013, + 10015, 10017, 10019, 10021, 10023, 10025, 10027, 10029, 10031, 10033, + 10035, 10037, 10039, 10041, 10043, 10045, 10047, 10049, 10051, 10053, + 10055, 10057, 10059, 10061, 10063, 10065, 10067, 10069, 10071, 10073, + 10075, 10077, 10079, 10081, 10083, 10085, 10087, 10089, 10091, 10093, + 10095, 10097, 10099, 10101, 10103, 10105, 10107, 10109, 10111, 10113, + 10115, 10117, 10119, 10121, 10123, 10125, 10127, 10129, 10131, 10133, + 10135, 10137, 10139, 10141, 10143, 10145, 10147, 10149, 10151, 10153, + 10155, 10157, 10159, 10161, 10163, 10165, 10167, 10169, 10171, 10173, + 10175, 10177, 10179, 10181, 10183, 10185, 10187, 10189, 10191, 10193, + 10195, 10197, 10199, 10201, 10203, 10205, 10207, 10209, 10211, 10213, + 10215, 10217, 10219, 10221, 10223, 10225, 10227, 10229, 10231, 10233, + 10235, 10237, 10239, 10241, 10243, 10245, 10247, 10249, 10251, 10253, + 10255, 10257, 10259, 10261, 10263, 10265, 10267, 10269, 10271, 10273, + 10275, 10277, 10279, 10281, 10283, 10285, 10287, 10289, 10291, 10293, + 10295, 10297, 10299, 10301, 10303, 10305, 10307, 10309, 10311, 10313, + 10315, 10317, 10319, 10321, 10323, 10325, 10327, 10329, 10331, 10333, + 10335, 10337, 10339, 10341, 10343, 10345, 10347, 10349, 10351, 10353, + 10355, 10357, 10359, 10361, 10363, 10365, 10367, 10369, 10371, 10373, + 10375, 10377, 10379, 10381, 0, 0, 0, 10383, 10385, 10387, 10389, 10391, + 10393, 0, 0, 10395, 10397, 10399, 10401, 10403, 10405, 0, 0, 10407, + 10409, 10411, 10413, 10415, 10417, 0, 0, 10419, 10421, 10423, 0, 0, 0, + 10425, 10427, 10429, 10431, 10433, 10435, 10437, 0, 10439, 10441, 10443, + 10445, 10447, 10449, 10451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10453, 0, 10456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10459, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10462, 10465, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10468, 10471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10474, + 10477, 0, 10480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10483, 10486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10489, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10492, 10495, 10498, 10501, + 10504, 10507, 10510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10513, + 10516, 10519, 10522, 10525, 10528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10531, 10533, 10535, 10537, 10539, 10541, 10543, 10545, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10569, 10571, 10573, 10575, 10577, 10579, 10581, 10583, 10585, 10587, + 10589, 10591, 10593, 10595, 10597, 10599, 10601, 10603, 10605, 10607, + 10609, 10611, 10613, 10615, 10617, 10619, 10621, 10623, 10625, 10627, + 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, + 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, + 10669, 10671, 10673, 10675, 10677, 10679, 10681, 10683, 10685, 10687, + 10689, 10691, 10693, 10695, 10697, 10699, 0, 10701, 10703, 10705, 10707, + 10709, 10711, 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, + 10729, 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, + 10749, 10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, + 10769, 10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, + 10789, 10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, + 10809, 10811, 10813, 10815, 10817, 10819, 10821, 10823, 10825, 10827, + 10829, 10831, 10833, 10835, 10837, 10839, 10841, 0, 10843, 10845, 0, 0, + 10847, 0, 0, 10849, 10851, 0, 0, 10853, 10855, 10857, 10859, 0, 10861, + 10863, 10865, 10867, 10869, 10871, 10873, 10875, 10877, 10879, 10881, + 10883, 0, 10885, 0, 10887, 10889, 10891, 10893, 10895, 10897, 10899, 0, + 10901, 10903, 10905, 10907, 10909, 10911, 10913, 10915, 10917, 10919, + 10921, 10923, 10925, 10927, 10929, 10931, 10933, 10935, 10937, 10939, + 10941, 10943, 10945, 10947, 10949, 10951, 10953, 10955, 10957, 10959, + 10961, 10963, 10965, 10967, 10969, 10971, 10973, 10975, 10977, 10979, + 10981, 10983, 10985, 10987, 10989, 10991, 10993, 10995, 10997, 10999, + 11001, 11003, 11005, 11007, 11009, 11011, 11013, 11015, 11017, 11019, + 11021, 11023, 11025, 11027, 11029, 0, 11031, 11033, 11035, 11037, 0, 0, + 11039, 11041, 11043, 11045, 11047, 11049, 11051, 11053, 0, 11055, 11057, + 11059, 11061, 11063, 11065, 11067, 0, 11069, 11071, 11073, 11075, 11077, + 11079, 11081, 11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, + 11099, 11101, 11103, 11105, 11107, 11109, 11111, 11113, 11115, 11117, + 11119, 11121, 11123, 0, 11125, 11127, 11129, 11131, 0, 11133, 11135, + 11137, 11139, 11141, 0, 11143, 0, 0, 0, 11145, 11147, 11149, 11151, + 11153, 11155, 11157, 0, 11159, 11161, 11163, 11165, 11167, 11169, 11171, + 11173, 11175, 11177, 11179, 11181, 11183, 11185, 11187, 11189, 11191, + 11193, 11195, 11197, 11199, 11201, 11203, 11205, 11207, 11209, 11211, + 11213, 11215, 11217, 11219, 11221, 11223, 11225, 11227, 11229, 11231, + 11233, 11235, 11237, 11239, 11241, 11243, 11245, 11247, 11249, 11251, + 11253, 11255, 11257, 11259, 11261, 11263, 11265, 11267, 11269, 11271, + 11273, 11275, 11277, 11279, 11281, 11283, 11285, 11287, 11289, 11291, + 11293, 11295, 11297, 11299, 11301, 11303, 11305, 11307, 11309, 11311, + 11313, 11315, 11317, 11319, 11321, 11323, 11325, 11327, 11329, 11331, + 11333, 11335, 11337, 11339, 11341, 11343, 11345, 11347, 11349, 11351, + 11353, 11355, 11357, 11359, 11361, 11363, 11365, 11367, 11369, 11371, + 11373, 11375, 11377, 11379, 11381, 11383, 11385, 11387, 11389, 11391, + 11393, 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, + 11413, 11415, 11417, 11419, 11421, 11423, 11425, 11427, 11429, 11431, + 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, + 11453, 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, + 11473, 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, + 11493, 11495, 11497, 11499, 11501, 11503, 11505, 11507, 11509, 11511, + 11513, 11515, 11517, 11519, 11521, 11523, 11525, 11527, 11529, 11531, + 11533, 11535, 11537, 11539, 11541, 11543, 11545, 11547, 11549, 11551, + 11553, 11555, 11557, 11559, 11561, 11563, 11565, 11567, 11569, 11571, + 11573, 11575, 11577, 11579, 11581, 11583, 11585, 11587, 11589, 11591, + 11593, 11595, 11597, 11599, 11601, 11603, 11605, 11607, 11609, 11611, + 11613, 11615, 11617, 11619, 11621, 11623, 11625, 11627, 11629, 11631, + 11633, 11635, 11637, 11639, 11641, 11643, 11645, 11647, 11649, 11651, + 11653, 11655, 11657, 11659, 11661, 11663, 11665, 11667, 11669, 11671, + 11673, 11675, 11677, 11679, 11681, 11683, 11685, 11687, 11689, 11691, + 11693, 11695, 11697, 11699, 11701, 11703, 11705, 11707, 11709, 11711, + 11713, 11715, 11717, 11719, 11721, 11723, 11725, 11727, 11729, 11731, + 11733, 11735, 11737, 11739, 11741, 11743, 11745, 11747, 11749, 11751, + 11753, 11755, 11757, 11759, 11761, 11763, 11765, 11767, 11769, 11771, + 11773, 11775, 11777, 11779, 11781, 11783, 11785, 11787, 11789, 11791, + 11793, 11795, 11797, 11799, 11801, 11803, 11805, 11807, 11809, 11811, + 11813, 11815, 11817, 11819, 11821, 11823, 11825, 11827, 11829, 11831, + 11833, 11835, 11837, 0, 0, 11839, 11841, 11843, 11845, 11847, 11849, + 11851, 11853, 11855, 11857, 11859, 11861, 11863, 11865, 11867, 11869, + 11871, 11873, 11875, 11877, 11879, 11881, 11883, 11885, 11887, 11889, + 11891, 11893, 11895, 11897, 11899, 11901, 11903, 11905, 11907, 11909, + 11911, 11913, 11915, 11917, 11919, 11921, 11923, 11925, 11927, 11929, + 11931, 11933, 11935, 11937, 11939, 11941, 11943, 11945, 11947, 11949, + 11951, 11953, 11955, 11957, 11959, 11961, 11963, 11965, 11967, 11969, + 11971, 11973, 11975, 11977, 11979, 11981, 11983, 11985, 11987, 11989, + 11991, 11993, 11995, 11997, 11999, 12001, 12003, 12005, 12007, 12009, + 12011, 12013, 12015, 12017, 12019, 12021, 12023, 12025, 12027, 12029, + 12031, 12033, 12035, 12037, 12039, 12041, 12043, 12045, 12047, 12049, + 12051, 12053, 12055, 12057, 12059, 12061, 12063, 12065, 12067, 12069, + 12071, 12073, 12075, 12077, 12079, 12081, 12083, 12085, 12087, 12089, + 12091, 12093, 12095, 12097, 12099, 12101, 12103, 12105, 12107, 12109, + 12111, 12113, 12115, 12117, 12119, 12121, 12123, 12125, 12127, 12129, + 12131, 12133, 12135, 12137, 12139, 12141, 12143, 12145, 12147, 12149, + 12151, 12153, 12155, 12157, 12159, 12161, 12163, 12165, 12167, 12169, + 12171, 12173, 12175, 12177, 12179, 12181, 12183, 12185, 12187, 12189, + 12191, 12193, 12195, 12197, 12199, 12201, 12203, 12205, 12207, 12209, + 12211, 12213, 12215, 12217, 12219, 12221, 12223, 12225, 12227, 12229, + 12231, 12233, 12235, 12237, 12239, 12241, 12243, 12245, 12247, 12249, + 12251, 12253, 12255, 12257, 12259, 12261, 12263, 12265, 12267, 12269, + 12271, 12273, 12275, 12277, 12279, 12281, 12283, 12285, 12287, 12289, + 12291, 12293, 12295, 12297, 12299, 12301, 12303, 12305, 12307, 12309, + 12311, 12313, 12315, 12317, 12319, 12321, 12323, 12325, 12327, 12329, + 12331, 12333, 12335, 12337, 12339, 12341, 12343, 12345, 12347, 12349, + 12351, 12353, 12355, 12357, 12359, 12361, 12363, 12365, 12367, 12369, + 12371, 12373, 12375, 12377, 12379, 12381, 12383, 12385, 12387, 12389, + 12391, 12393, 12395, 12397, 12399, 12401, 12403, 12405, 12407, 12409, + 12411, 12413, 12415, 12417, 12419, 12421, 0, 0, 12423, 12425, 12427, + 12429, 12431, 12433, 12435, 12437, 12439, 12441, 12443, 12445, 12447, + 12449, 12451, 12453, 12455, 12457, 12459, 12461, 12463, 12465, 12467, + 12469, 12471, 12473, 12475, 12477, 12479, 12481, 12483, 12485, 12487, + 12489, 12491, 12493, 12495, 12497, 12499, 12501, 12503, 12505, 12507, + 12509, 12511, 12513, 12515, 12517, 12519, 12521, 12523, 12525, 12527, + 12529, 0, 12531, 12533, 12535, 12537, 12539, 12541, 12543, 12545, 12547, + 12549, 12551, 12553, 12555, 12557, 12559, 12561, 12563, 12565, 12567, + 12569, 12571, 12573, 12575, 12577, 12579, 12581, 12583, 0, 12585, 12587, + 0, 12589, 0, 0, 12591, 0, 12593, 12595, 12597, 12599, 12601, 12603, + 12605, 12607, 12609, 12611, 0, 12613, 12615, 12617, 12619, 0, 12621, 0, + 12623, 0, 0, 0, 0, 0, 0, 12625, 0, 0, 0, 0, 12627, 0, 12629, 0, 12631, 0, + 12633, 12635, 12637, 0, 12639, 12641, 0, 12643, 0, 0, 12645, 0, 12647, 0, + 12649, 0, 12651, 0, 12653, 0, 12655, 12657, 0, 12659, 0, 0, 12661, 12663, + 12665, 12667, 0, 12669, 12671, 12673, 12675, 12677, 12679, 12681, 0, + 12683, 12685, 12687, 12689, 0, 12691, 12693, 12695, 12697, 0, 12699, 0, + 12701, 12703, 12705, 12707, 12709, 12711, 12713, 12715, 12717, 12719, 0, + 12721, 12723, 12725, 12727, 12729, 12731, 12733, 12735, 12737, 12739, + 12741, 12743, 12745, 12747, 12749, 12751, 12753, 0, 0, 0, 0, 0, 12755, + 12757, 12759, 0, 12761, 12763, 12765, 12767, 12769, 0, 12771, 12773, + 12775, 12777, 12779, 12781, 12783, 12785, 12787, 12789, 12791, 12793, + 12795, 12797, 12799, 12801, 12803, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12805, 12808, 12811, 12814, 12817, 12820, 12823, + 12826, 12829, 12832, 12835, 0, 0, 0, 0, 0, 12838, 12842, 12846, 12850, + 12854, 12858, 12862, 12866, 12870, 12874, 12878, 12882, 12886, 12890, + 12894, 12898, 12902, 12906, 12910, 12914, 12918, 12922, 12926, 12930, + 12934, 12938, 12942, 12946, 12948, 12950, 12953, 0, 12956, 12958, 12960, + 12962, 12964, 12966, 12968, 12970, 12972, 12974, 12976, 12978, 12980, + 12982, 12984, 12986, 12988, 12990, 12992, 12994, 12996, 12998, 13000, + 13002, 13004, 13006, 13008, 13011, 13014, 13017, 13020, 13024, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13027, 13030, 13033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13036, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13039, 13042, 13045, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 13047, 13049, 13051, 13053, 13055, 13057, 13059, + 13061, 13063, 13065, 13067, 13069, 13071, 13073, 13075, 13077, 13079, + 13081, 13083, 13085, 13087, 13089, 13091, 13093, 13095, 13097, 13099, + 13101, 13103, 13105, 13107, 13109, 13111, 13113, 13115, 13117, 13119, + 13121, 13123, 13125, 13127, 13129, 13131, 13133, 0, 0, 0, 0, 13135, + 13139, 13143, 13147, 13151, 13155, 13159, 13163, 13167, 0, 0, 0, 0, 0, 0, + 0, 13171, 13173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13175, 13177, + 13179, 13181, 13183, 13185, 13187, 13189, 13191, 13193, 0, 0, 0, 0, 0, 0, + 13195, 13197, 13199, 13201, 13203, 13205, 13207, 13209, 13211, 13213, + 13215, 13217, 13219, 13221, 13223, 13225, 13227, 13229, 13231, 13233, + 13235, 13237, 13239, 13241, 13243, 13245, 13247, 13249, 13251, 13253, + 13255, 13257, 13259, 13261, 13263, 13265, 13267, 13269, 13271, 13273, + 13275, 13277, 13279, 13281, 13283, 13285, 13287, 13289, 13291, 13293, + 13295, 13297, 13299, 13301, 13303, 13305, 13307, 13309, 13311, 13313, + 13315, 13317, 13319, 13321, 13323, 13325, 13327, 13329, 13331, 13333, + 13335, 13337, 13339, 13341, 13343, 13345, 13347, 13349, 13351, 13353, + 13355, 13357, 13359, 13361, 13363, 13365, 13367, 13369, 13371, 13373, + 13375, 13377, 13379, 13381, 13383, 13385, 13387, 13389, 13391, 13393, + 13395, 13397, 13399, 13401, 13403, 13405, 13407, 13409, 13411, 13413, + 13415, 13417, 13419, 13421, 13423, 13425, 13427, 13429, 13431, 13433, + 13435, 13437, 13439, 13441, 13443, 13445, 13447, 13449, 13451, 13453, + 13455, 13457, 13459, 13461, 13463, 13465, 13467, 13469, 13471, 13473, + 13475, 13477, 13479, 13481, 13483, 13485, 13487, 13489, 13491, 13493, + 13495, 13497, 13499, 13501, 13503, 13505, 13507, 13509, 13511, 13513, + 13515, 13517, 13519, 13521, 13523, 13525, 13527, 13529, 13531, 13533, + 13535, 13537, 13539, 13541, 13543, 13545, 13547, 13549, 13551, 13553, + 13555, 13557, 13559, 13561, 13563, 13565, 13567, 13569, 13571, 13573, + 13575, 13577, 13579, 13581, 13583, 13585, 13587, 13589, 13591, 13593, + 13595, 13597, 13599, 13601, 13603, 13605, 13607, 13609, 13611, 13613, + 13615, 13617, 13619, 13621, 13623, 13625, 13627, 13629, 13631, 13633, + 13635, 13637, 13639, 13641, 13643, 13645, 13647, 13649, 13651, 13653, + 13655, 13657, 13659, 13661, 13663, 13665, 13667, 13669, 13671, 13673, + 13675, 13677, 13679, 13681, 13683, 13685, 13687, 13689, 13691, 13693, + 13695, 13697, 13699, 13701, 13703, 13705, 13707, 13709, 13711, 13713, + 13715, 13717, 13719, 13721, 13723, 13725, 13727, 13729, 13731, 13733, + 13735, 13737, 13739, 13741, 13743, 13745, 13747, 13749, 13751, 13753, + 13755, 13757, 13759, 13761, 13763, 13765, 13767, 13769, 13771, 13773, + 13775, 13777, 13779, 13781, 13783, 13785, 13787, 13789, 13791, 13793, + 13795, 13797, 13799, 13801, 13803, 13805, 13807, 13809, 13811, 13813, + 13815, 13817, 13819, 13821, 13823, 13825, 13827, 13829, 13831, 13833, + 13835, 13837, 13839, 13841, 13843, 13845, 13847, 13849, 13851, 13853, + 13855, 13857, 13859, 13861, 13863, 13865, 13867, 13869, 13871, 13873, + 13875, 13877, 13879, 13881, 13883, 13885, 13887, 13889, 13891, 13893, + 13895, 13897, 13899, 13901, 13903, 13905, 13907, 13909, 13911, 13913, + 13915, 13917, 13919, 13921, 13923, 13925, 13927, 13929, 13931, 13933, + 13935, 13937, 13939, 13941, 13943, 13945, 13947, 13949, 13951, 13953, + 13955, 13957, 13959, 13961, 13963, 13965, 13967, 13969, 13971, 13973, + 13975, 13977, 13979, 13981, 13983, 13985, 13987, 13989, 13991, 13993, + 13995, 13997, 13999, 14001, 14003, 14005, 14007, 14009, 14011, 14013, + 14015, 14017, 14019, 14021, 14023, 14025, 14027, 14029, 14031, 14033, + 14035, 14037, 14039, 14041, 14043, 14045, 14047, 14049, 14051, 14053, + 14055, 14057, 14059, 14061, 14063, 14065, 14067, 14069, 14071, 14073, + 14075, 14077, 14079, 14081, 14083, 14085, 14087, 14089, 14091, 14093, + 14095, 14097, 14099, 14101, 14103, 14105, 14107, 14109, 14111, 14113, + 14115, 14117, 14119, 14121, 14123, 14125, 14127, 14129, 14131, 14133, + 14135, 14137, 14139, 14141, 14143, 14145, 14147, 14149, 14151, 14153, + 14155, 14157, 14159, 14161, 14163, 14165, 14167, 14169, 14171, 14173, + 14175, 14177, 14179, 14181, 14183, 14185, 14187, 14189, 14191, 14193, + 14195, 14197, 14199, 14201, 14203, 14205, 14207, 14209, 14211, 14213, + 14215, 14217, 14219, 14221, 14223, 14225, 14227, 14229, 14231, 14233, + 14235, 14237, 14239, 14241, 14243, 14245, 14247, 14249, 14251, 14253, + 14255, 14257, 14259, 14261, 14263, 14265, 14267, 14269, 14271, 14273, + 14275, 14277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const unsigned short decomp_index2[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, - 3, 0, 6, 0, 0, 0, 0, 8, 0, 0, 11, 13, 15, 18, 0, 0, 20, 23, 25, 0, 27, - 31, 35, 0, 39, 42, 45, 48, 51, 54, 0, 57, 60, 63, 66, 69, 72, 75, 78, 81, - 0, 84, 87, 90, 93, 96, 99, 0, 0, 102, 105, 108, 111, 114, 0, 0, 117, 120, - 123, 126, 129, 132, 0, 135, 138, 141, 144, 147, 150, 153, 156, 159, 0, - 162, 165, 168, 171, 174, 177, 0, 0, 180, 183, 186, 189, 192, 0, 195, 198, - 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, - 243, 0, 0, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279, - 282, 285, 288, 291, 294, 297, 300, 303, 0, 0, 306, 309, 312, 315, 318, - 321, 324, 327, 330, 0, 333, 336, 339, 342, 345, 348, 0, 351, 354, 357, - 360, 363, 366, 369, 372, 0, 0, 375, 378, 381, 384, 387, 390, 393, 0, 0, - 396, 399, 402, 405, 408, 411, 0, 0, 414, 417, 420, 423, 426, 429, 432, - 435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 0, 0, 468, 471, - 474, 477, 480, 483, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513, - 516, 519, 522, 525, 528, 531, 534, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 539, 542, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 548, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 554, 557, 560, 563, 566, 569, 572, - 575, 578, 581, 584, 587, 590, 593, 596, 599, 602, 605, 608, 611, 614, - 617, 620, 623, 0, 626, 629, 632, 635, 638, 641, 0, 0, 644, 647, 650, 653, - 656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 0, 0, 692, - 695, 698, 701, 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, 734, - 737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, - 779, 782, 785, 788, 791, 794, 797, 0, 0, 800, 803, 0, 0, 0, 0, 0, 0, 806, - 809, 812, 815, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 848, 850, 852, 854, 856, 858, 860, 862, 864, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 866, - 869, 872, 875, 878, 881, 0, 0, 884, 886, 888, 890, 892, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, - 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, - 0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, - 969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0, - 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0, - 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, - 0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087, - 1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0, - 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, - 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174, 1177, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, - 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, - 1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, - 0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1285, 1288, 1291, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 1306, 1309, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1347, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, 0, 0, 1359, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1365, 0, - 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, 1398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1407, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 1421, 0, 0, - 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1427, 0, 1430, - 0, 0, 1433, 1436, 0, 1439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1442, 1444, 1446, 0, - 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, 0, - 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, - 1494, 1496, 1498, 1500, 1502, 1504, 0, 1506, 1508, 1510, 1512, 1514, - 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1530, 1532, 1534, 1536, 1538, - 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1558, 1560, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, - 1588, 1590, 1592, 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, - 1612, 1614, 1616, 1618, 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, - 1636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1638, 1641, 1644, - 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680, - 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, - 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, - 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, - 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, - 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, - 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896, - 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, - 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968, - 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004, - 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040, - 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076, - 2079, 2082, 2085, 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106, - 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142, - 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178, - 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214, - 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250, - 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286, - 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322, - 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358, - 2361, 2364, 2367, 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385, - 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421, - 2424, 2427, 2430, 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454, - 2457, 0, 0, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487, - 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523, - 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559, - 2562, 2565, 2568, 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0, - 2592, 2595, 2598, 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0, - 2622, 0, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652, - 2655, 2658, 2661, 2664, 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686, - 2689, 2691, 2694, 2696, 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714, - 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750, - 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, - 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822, - 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858, - 2861, 2864, 2867, 0, 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890, - 2893, 2895, 2898, 2901, 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922, - 2924, 2927, 2929, 2932, 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952, - 2955, 2958, 2961, 2964, 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984, - 2987, 2989, 2992, 2995, 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018, - 3020, 0, 0, 3022, 3025, 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045, - 3047, 3050, 3052, 0, 3055, 3057, 3059, 3061, 3063, 3065, 3067, 3069, - 3071, 3073, 3075, 0, 0, 0, 0, 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0, - 3091, 0, 0, 0, 3093, 3096, 0, 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0, - 0, 0, 0, 0, 0, 0, 0, 3113, 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3122, 0, 0, 0, 0, 0, 0, 0, 3127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3129, 3131, 0, 0, 3133, 3135, 3137, 3139, 3141, 3143, - 3145, 3147, 3149, 3151, 3153, 3155, 3157, 3159, 3161, 3163, 3165, 3167, - 3169, 3171, 3173, 3175, 3177, 3179, 3181, 3183, 3185, 0, 3187, 3189, - 3191, 3193, 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3216, 3220, 3224, 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244, - 3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0, - 3267, 3269, 3271, 3273, 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289, - 0, 3291, 0, 3293, 3295, 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309, - 3311, 3313, 3315, 3317, 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0, - 0, 0, 0, 3335, 3337, 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349, - 3353, 3358, 3362, 3366, 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398, - 3402, 3406, 3409, 3411, 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438, - 3440, 3443, 3447, 3449, 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469, - 3472, 3476, 3481, 3484, 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3505, 3508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3514, 3517, 3520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3523, 0, 0, 0, 0, 3526, - 0, 0, 3529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3532, 0, 3535, 0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, - 0, 3561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3564, 0, 3567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579, - 3582, 0, 0, 3585, 3588, 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600, - 0, 0, 3603, 3606, 0, 0, 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3615, - 3618, 3621, 3624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3627, 3630, 3633, 3636, 0, 0, 0, 0, 0, 0, 3639, 3642, - 3645, 3648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3651, 3653, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 3669, - 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 3703, - 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747, 3752, - 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803, 3806, - 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844, 3848, - 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892, 3896, - 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940, 3944, - 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980, 3982, - 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, - 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028, 4030, - 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052, 4054, - 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4083, 4087, 4090, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 4099, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4101, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4107, - 4109, 4111, 4113, 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, - 4133, 4135, 4137, 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, - 4157, 4159, 4161, 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, - 4181, 4183, 4185, 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, - 4205, 4207, 4209, 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, - 4229, 4231, 4233, 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, - 4253, 4255, 4257, 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, - 4277, 4279, 4281, 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, - 4301, 4303, 4305, 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, - 4325, 4327, 4329, 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, - 4349, 4351, 4353, 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, - 4373, 4375, 4377, 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, - 4397, 4399, 4401, 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, - 4421, 4423, 4425, 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, - 4445, 4447, 4449, 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, - 4469, 4471, 4473, 4475, 4477, 4479, 4481, 4483, 4485, 4487, 4489, 4491, - 4493, 4495, 4497, 4499, 4501, 4503, 4505, 4507, 4509, 4511, 4513, 4515, - 4517, 4519, 4521, 4523, 4525, 4527, 4529, 4531, 4533, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, - 4541, 4543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, - 4548, 0, 4551, 0, 4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, - 4572, 0, 4575, 0, 4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, - 4590, 4593, 0, 4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4620, - 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0, 4653, 0, - 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674, 0, 4677, - 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0, 4698, - 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716, 4719, 4722, 0, 0, 0, 4725, 4728, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4731, 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, - 4753, 4755, 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, - 4777, 4779, 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, - 4801, 4803, 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, - 4825, 4827, 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, - 4849, 4851, 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, - 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 4895, - 4897, 4899, 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, 4917, 0, 0, - 0, 4919, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4947, 4951, 4955, 4959, 4963, 4967, 4971, 4975, 4979, - 4983, 4987, 4991, 4995, 4999, 5003, 5008, 5013, 5018, 5023, 5028, 5033, - 5038, 5043, 5048, 5053, 5058, 5063, 5068, 5073, 5078, 5086, 0, 5093, - 5097, 5101, 5105, 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, - 5145, 5149, 5153, 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5189, - 5193, 5197, 5201, 5205, 5209, 5213, 5217, 5221, 5225, 5229, 5233, 5237, - 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0, 5245, 5249, 5252, 5255, 5258, - 5261, 5264, 5267, 5270, 5273, 5276, 5279, 5282, 5285, 5288, 5291, 5294, - 5296, 5298, 5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, - 5320, 5322, 5325, 5328, 5331, 5334, 5337, 5340, 5343, 5346, 5349, 5352, - 5355, 5358, 5361, 5364, 5370, 5375, 0, 5378, 5380, 5382, 5384, 5386, - 5388, 5390, 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, - 5412, 5414, 5416, 5418, 5420, 5422, 5424, 5426, 5428, 5430, 5432, 5434, - 5436, 5438, 5440, 5442, 5444, 5446, 5448, 5450, 5452, 5454, 5456, 5458, - 5460, 5462, 5464, 5466, 5468, 5470, 5472, 5474, 5476, 5479, 5482, 5485, - 5488, 5491, 5494, 5497, 5500, 5503, 5506, 5509, 5512, 5515, 5518, 5521, - 5524, 5527, 5530, 5533, 5536, 5539, 5542, 5545, 5548, 5552, 5556, 5560, - 5563, 5567, 5570, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, - 5592, 5594, 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, - 5616, 5618, 5620, 5622, 5624, 5626, 5628, 5630, 5632, 5634, 5636, 5638, - 5640, 5642, 5644, 5646, 5648, 5650, 5652, 5654, 5656, 5658, 5660, 5662, - 5664, 5666, 5668, 5671, 5676, 5681, 5686, 5690, 5695, 5699, 5703, 5709, - 5714, 5718, 5722, 5726, 5731, 5736, 5740, 5744, 5747, 5751, 5756, 5761, - 5764, 5770, 5777, 5783, 5787, 5793, 5799, 5804, 5808, 5812, 5816, 5821, - 5827, 5832, 5836, 5840, 5844, 5847, 5850, 5853, 5856, 5860, 5864, 5870, - 5874, 5879, 5885, 5889, 5892, 5895, 5901, 5906, 5912, 5916, 5922, 5925, - 5929, 5933, 5937, 5941, 5945, 5950, 5954, 5957, 5961, 5965, 5969, 5974, - 5978, 5982, 5986, 5992, 5997, 6000, 6006, 6009, 6014, 6019, 6023, 6027, - 6031, 6036, 6039, 6043, 6048, 6051, 6057, 6061, 6064, 6067, 6070, 6073, - 6076, 6079, 6082, 6085, 6088, 6091, 6095, 6099, 6103, 6107, 6111, 6115, - 6119, 6123, 6127, 6131, 6135, 6139, 6143, 6147, 6151, 6155, 6158, 6161, - 6165, 6168, 6171, 6174, 6178, 6182, 6185, 6188, 6191, 6194, 6197, 6202, - 6205, 6208, 6211, 6214, 6217, 6220, 6223, 6226, 6230, 6235, 6238, 6241, - 6244, 6247, 6250, 6253, 6256, 6260, 6264, 6268, 6272, 6275, 6278, 6281, - 6284, 6287, 6290, 6293, 6296, 6299, 6302, 6306, 6310, 6313, 6317, 6321, - 6325, 6328, 6332, 6336, 6341, 6344, 6348, 6352, 6356, 6360, 6366, 6373, - 6376, 6379, 6382, 6385, 6388, 6391, 6394, 6397, 6400, 6403, 6406, 6409, - 6412, 6415, 6418, 6421, 6424, 6427, 6432, 6435, 6438, 6441, 6446, 6450, - 6453, 6456, 6459, 6462, 6465, 6468, 6471, 6474, 6477, 6480, 6484, 6487, - 6490, 6494, 6498, 6501, 6506, 6510, 6513, 6516, 6519, 6522, 6526, 6530, - 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6557, 6561, 6565, 6569, - 6573, 6577, 6581, 6585, 6589, 6593, 6597, 6601, 6605, 6609, 6613, 6617, - 6621, 6625, 6629, 6633, 6637, 6641, 6645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6649, 6651, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6653, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6655, 6657, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6659, 6661, 6663, 6665, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 6667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 6669, 6671, 6673, 6675, 6677, 6679, 6681, 6683, - 6685, 6687, 6689, 6691, 6693, 6695, 6697, 6699, 6701, 6703, 6705, 6707, - 6709, 6711, 6713, 6715, 6717, 6719, 6721, 6723, 6725, 6727, 6729, 6731, - 6733, 6735, 6737, 6739, 6741, 6743, 6745, 6747, 6749, 6751, 6753, 6755, - 6757, 6759, 6761, 6763, 6765, 6767, 6769, 6771, 6773, 6775, 6777, 6779, - 6781, 6783, 6785, 6787, 6789, 6791, 6793, 6795, 6797, 6799, 6801, 6803, - 6805, 6807, 6809, 6811, 6813, 6815, 6817, 6819, 6821, 6823, 6825, 6827, - 6829, 6831, 6833, 6835, 6837, 6839, 6841, 6843, 6845, 6847, 6849, 6851, - 6853, 6855, 6857, 6859, 6861, 6863, 6865, 6867, 6869, 6871, 6873, 6875, - 6877, 6879, 6881, 6883, 6885, 6887, 6889, 6891, 6893, 6895, 6897, 6899, - 6901, 6903, 6905, 6907, 6909, 6911, 6913, 6915, 6917, 6919, 6921, 6923, - 6925, 6927, 6929, 6931, 6933, 6935, 6937, 6939, 6941, 6943, 6945, 6947, - 6949, 6951, 6953, 6955, 6957, 6959, 6961, 6963, 6965, 6967, 6969, 6971, - 6973, 6975, 6977, 6979, 6981, 6983, 6985, 6987, 6989, 6991, 6993, 6995, - 6997, 6999, 7001, 7003, 7005, 7007, 7009, 7011, 7013, 7015, 7017, 7019, - 7021, 7023, 7025, 7027, 7029, 7031, 7033, 7035, 7037, 7039, 7041, 7043, - 7045, 7047, 7049, 7051, 7053, 7055, 7057, 7059, 7061, 7063, 7065, 7067, - 7069, 7071, 7073, 7075, 7077, 7079, 7081, 7083, 7085, 7087, 7089, 7091, - 7093, 7095, 7097, 7099, 7101, 7103, 7105, 7107, 7109, 7111, 7113, 7115, - 7117, 7119, 7121, 7123, 7125, 7127, 7129, 7131, 7133, 7135, 7137, 7139, - 7141, 7143, 7145, 7147, 7149, 7151, 7153, 7155, 7157, 7159, 7161, 7163, - 7165, 7167, 7169, 7171, 7173, 7175, 7177, 7179, 7181, 7183, 7185, 7187, - 7189, 7191, 7193, 7195, 7197, 7199, 7201, 7203, 7205, 7207, 0, 0, 7209, - 0, 7211, 0, 0, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 7229, - 7231, 0, 7233, 0, 7235, 0, 0, 7237, 7239, 0, 0, 0, 7241, 7243, 7245, - 7247, 7249, 7251, 7253, 7255, 7257, 7259, 7261, 7263, 7265, 7267, 7269, - 7271, 7273, 7275, 7277, 7279, 7281, 7283, 7285, 7287, 7289, 7291, 7293, - 7295, 7297, 7299, 7301, 7303, 7305, 7307, 7309, 7311, 7313, 7315, 7317, - 7319, 7321, 7323, 7325, 7327, 7329, 7331, 7333, 7335, 7337, 7339, 7341, - 7343, 7345, 7347, 7349, 7351, 7353, 7355, 7357, 7359, 7361, 7363, 7365, - 7367, 7369, 7371, 7373, 7375, 0, 0, 7377, 7379, 7381, 7383, 7385, 7387, - 7389, 7391, 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, - 7413, 7415, 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, - 7437, 7439, 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, - 7461, 7463, 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, - 7485, 7487, 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, - 7509, 7511, 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, - 7533, 7535, 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7553, 7555, - 7557, 7559, 7561, 7563, 7565, 7567, 7569, 7571, 7573, 7575, 7577, 7579, - 7581, 7583, 7585, 7587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7589, - 7592, 7595, 7598, 7602, 7606, 7609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7612, 7615, 7618, 7621, 7624, 0, 0, 0, 0, 0, 7627, 0, 7630, 7633, 7635, - 7637, 7639, 7641, 7643, 7645, 7647, 7649, 7651, 7653, 7656, 7659, 7662, - 7665, 7668, 7671, 7674, 7677, 7680, 7683, 7686, 7689, 0, 7692, 7695, - 7698, 7701, 7704, 0, 7707, 0, 7710, 7713, 0, 7716, 7719, 0, 7722, 7725, - 7728, 7731, 7734, 7737, 7740, 7743, 7746, 7749, 7752, 7754, 7756, 7758, - 7760, 7762, 7764, 7766, 7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782, - 7784, 7786, 7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, 7804, 7806, - 7808, 7810, 7812, 7814, 7816, 7818, 7820, 7822, 7824, 7826, 7828, 7830, - 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, - 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, - 7880, 7882, 7884, 7886, 7888, 7890, 7892, 7894, 7896, 7898, 7900, 7902, - 7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, 7924, 7926, - 7928, 7930, 7932, 7934, 7936, 7938, 7940, 7942, 7944, 7946, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7948, 7950, 7952, 7954, 7956, 7958, 7960, 7962, 7964, - 7966, 7968, 7970, 7972, 7974, 7976, 7978, 7980, 7982, 7984, 7986, 7988, - 7990, 7992, 7994, 7997, 8000, 8003, 8006, 8009, 8012, 8015, 8018, 8021, - 8024, 8027, 8030, 8033, 8036, 8039, 8042, 8045, 8048, 8050, 8052, 8054, - 8056, 8059, 8062, 8065, 8068, 8071, 8074, 8077, 8080, 8083, 8086, 8089, - 8092, 8095, 8098, 8101, 8104, 8107, 8110, 8113, 8116, 8119, 8122, 8125, - 8128, 8131, 8134, 8137, 8140, 8143, 8146, 8149, 8152, 8155, 8158, 8161, - 8164, 8167, 8170, 8173, 8176, 8179, 8182, 8185, 8188, 8191, 8194, 8197, - 8200, 8203, 8206, 8209, 8212, 8215, 8218, 8221, 8224, 8227, 8230, 8233, - 8236, 8239, 8242, 8245, 8248, 8251, 8254, 8257, 8260, 8263, 8266, 8269, - 8272, 8275, 8278, 8281, 8284, 8287, 8290, 8293, 8296, 8299, 8302, 8305, - 8308, 8311, 8314, 8317, 8320, 8323, 8326, 8329, 8332, 8335, 8338, 8342, - 8346, 8350, 8354, 8358, 8362, 8365, 8368, 8371, 8374, 8377, 8380, 8383, - 8386, 8389, 8392, 8395, 8398, 8401, 8404, 8407, 8410, 8413, 8416, 8419, - 8422, 8425, 8428, 8431, 8434, 8437, 8440, 8443, 8446, 8449, 8452, 8455, - 8458, 8461, 8464, 8467, 8470, 8473, 8476, 8479, 8482, 8485, 8488, 8491, - 8494, 8497, 8500, 8503, 8506, 8509, 8512, 8515, 8518, 8521, 8524, 8527, - 8530, 8533, 8536, 8539, 8542, 8545, 8548, 8551, 8554, 8557, 8560, 8563, - 8566, 8569, 8572, 8575, 8578, 8581, 8584, 8587, 8590, 8593, 8596, 8599, - 8602, 8605, 8608, 8611, 8614, 8617, 8620, 8623, 8626, 8629, 8632, 8635, - 8638, 8641, 8644, 8647, 8650, 8653, 8656, 8659, 8662, 8665, 8668, 8671, - 8674, 8677, 8680, 8683, 8686, 8689, 8692, 8695, 8698, 8701, 8704, 8707, - 8710, 8713, 8716, 8719, 8722, 8725, 8728, 8731, 8734, 8737, 8740, 8743, - 8746, 8749, 8752, 8755, 8758, 8761, 8764, 8767, 8770, 8773, 8776, 8779, - 8782, 8785, 8788, 8792, 8796, 8800, 8803, 8806, 8809, 8812, 8815, 8818, - 8821, 8824, 8827, 8830, 8833, 8836, 8839, 8842, 8845, 8848, 8851, 8854, - 8857, 8860, 8863, 8866, 8869, 8872, 8875, 8878, 8881, 8884, 8887, 8890, - 8893, 8896, 8899, 8902, 8905, 8908, 8911, 8914, 8917, 8920, 8923, 8926, - 8929, 8932, 8935, 8938, 8941, 8944, 8947, 8950, 8953, 8956, 8959, 8962, - 8965, 8968, 8971, 8974, 8977, 8980, 8983, 8986, 8989, 8992, 8995, 8998, - 9001, 9004, 9007, 9010, 9013, 9016, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9019, 9023, 9027, 9031, 9035, 9039, 9043, 9047, 9051, - 9055, 9059, 9063, 9067, 9071, 9075, 9079, 9083, 9087, 9091, 9095, 9099, - 9103, 9107, 9111, 9115, 9119, 9123, 9127, 9131, 9135, 9139, 9143, 9147, - 9151, 9155, 9159, 9163, 9167, 9171, 9175, 9179, 9183, 9187, 9191, 9195, - 9199, 9203, 9207, 9211, 9215, 9219, 9223, 9227, 9231, 9235, 9239, 9243, - 9247, 9251, 9255, 9259, 9263, 9267, 9271, 0, 0, 9275, 9279, 9283, 9287, - 9291, 9295, 9299, 9303, 9307, 9311, 9315, 9319, 9323, 9327, 9331, 9335, - 9339, 9343, 9347, 9351, 9355, 9359, 9363, 9367, 9371, 9375, 9379, 9383, - 9387, 9391, 9395, 9399, 9403, 9407, 9411, 9415, 9419, 9423, 9427, 9431, - 9435, 9439, 9443, 9447, 9451, 9455, 9459, 9463, 9467, 9471, 9475, 9479, - 9483, 9487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9491, 9495, - 9499, 9504, 9509, 9514, 9519, 9524, 9529, 9534, 9538, 9557, 9566, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9571, 9573, 9575, - 9577, 9579, 9581, 9583, 9585, 9587, 9589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9591, 9593, 9595, 9597, 9599, 9601, - 9603, 9605, 9607, 9609, 9611, 9613, 9615, 9617, 9619, 9621, 9623, 9625, - 9627, 9629, 9631, 0, 0, 9633, 9635, 9637, 9639, 9641, 9643, 9645, 9647, - 9649, 9651, 9653, 9655, 0, 9657, 9659, 9661, 9663, 9665, 9667, 9669, - 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, 9693, - 0, 9695, 9697, 9699, 9701, 0, 0, 0, 0, 9703, 9706, 9709, 0, 9712, 0, - 9715, 9718, 9721, 9724, 9727, 9730, 9733, 9736, 9739, 9742, 9745, 9747, - 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763, 9765, 9767, 9769, 9771, - 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787, 9789, 9791, 9793, 9795, - 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811, 9813, 9815, 9817, 9819, - 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835, 9837, 9839, 9841, 9843, - 9845, 9847, 9849, 9851, 9853, 9855, 9857, 9859, 9861, 9863, 9865, 9867, - 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, 9887, 9889, 9891, - 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, 9911, 9913, 9915, - 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, 9935, 9937, 9939, - 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, 9959, 9961, 9963, - 9965, 9967, 9969, 9971, 9973, 9975, 9977, 9979, 9982, 9985, 9988, 9991, - 9994, 9997, 10000, 0, 0, 0, 0, 10003, 10005, 10007, 10009, 10011, 10013, - 10015, 10017, 10019, 10021, 10023, 10025, 10027, 10029, 10031, 10033, - 10035, 10037, 10039, 10041, 10043, 10045, 10047, 10049, 10051, 10053, - 10055, 10057, 10059, 10061, 10063, 10065, 10067, 10069, 10071, 10073, - 10075, 10077, 10079, 10081, 10083, 10085, 10087, 10089, 10091, 10093, - 10095, 10097, 10099, 10101, 10103, 10105, 10107, 10109, 10111, 10113, - 10115, 10117, 10119, 10121, 10123, 10125, 10127, 10129, 10131, 10133, - 10135, 10137, 10139, 10141, 10143, 10145, 10147, 10149, 10151, 10153, - 10155, 10157, 10159, 10161, 10163, 10165, 10167, 10169, 10171, 10173, - 10175, 10177, 10179, 10181, 10183, 10185, 10187, 10189, 10191, 10193, - 10195, 10197, 10199, 10201, 10203, 10205, 10207, 10209, 10211, 10213, - 10215, 10217, 10219, 10221, 10223, 10225, 10227, 10229, 10231, 10233, - 10235, 10237, 10239, 10241, 10243, 10245, 10247, 10249, 10251, 10253, - 10255, 10257, 10259, 10261, 10263, 10265, 10267, 10269, 10271, 10273, - 10275, 10277, 10279, 10281, 10283, 10285, 10287, 10289, 10291, 10293, - 10295, 10297, 10299, 10301, 10303, 10305, 10307, 10309, 10311, 10313, - 10315, 10317, 10319, 10321, 10323, 10325, 10327, 10329, 10331, 10333, - 10335, 10337, 10339, 10341, 10343, 10345, 10347, 10349, 10351, 10353, - 10355, 10357, 10359, 10361, 10363, 10365, 10367, 10369, 10371, 10373, - 10375, 10377, 10379, 10381, 0, 0, 0, 10383, 10385, 10387, 10389, 10391, - 10393, 0, 0, 10395, 10397, 10399, 10401, 10403, 10405, 0, 0, 10407, - 10409, 10411, 10413, 10415, 10417, 0, 0, 10419, 10421, 10423, 0, 0, 0, - 10425, 10427, 10429, 10431, 10433, 10435, 10437, 0, 10439, 10441, 10443, - 10445, 10447, 10449, 10451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10453, 0, 10456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10459, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10462, 10465, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10468, 10471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10474, - 10477, 0, 10480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 10483, 10486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10489, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10492, 10495, 10498, 10501, - 10504, 10507, 10510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10513, - 10516, 10519, 10522, 10525, 10528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 10531, 10533, 10535, 10537, 10539, 10541, 10543, 10545, 10547, - 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, - 10569, 10571, 10573, 10575, 10577, 10579, 10581, 10583, 10585, 10587, - 10589, 10591, 10593, 10595, 10597, 10599, 10601, 10603, 10605, 10607, - 10609, 10611, 10613, 10615, 10617, 10619, 10621, 10623, 10625, 10627, - 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, - 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, - 10669, 10671, 10673, 10675, 10677, 10679, 10681, 10683, 10685, 10687, - 10689, 10691, 10693, 10695, 10697, 10699, 0, 10701, 10703, 10705, 10707, - 10709, 10711, 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, - 10729, 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, - 10749, 10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, - 10769, 10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, - 10789, 10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, - 10809, 10811, 10813, 10815, 10817, 10819, 10821, 10823, 10825, 10827, - 10829, 10831, 10833, 10835, 10837, 10839, 10841, 0, 10843, 10845, 0, 0, - 10847, 0, 0, 10849, 10851, 0, 0, 10853, 10855, 10857, 10859, 0, 10861, - 10863, 10865, 10867, 10869, 10871, 10873, 10875, 10877, 10879, 10881, - 10883, 0, 10885, 0, 10887, 10889, 10891, 10893, 10895, 10897, 10899, 0, - 10901, 10903, 10905, 10907, 10909, 10911, 10913, 10915, 10917, 10919, - 10921, 10923, 10925, 10927, 10929, 10931, 10933, 10935, 10937, 10939, - 10941, 10943, 10945, 10947, 10949, 10951, 10953, 10955, 10957, 10959, - 10961, 10963, 10965, 10967, 10969, 10971, 10973, 10975, 10977, 10979, - 10981, 10983, 10985, 10987, 10989, 10991, 10993, 10995, 10997, 10999, - 11001, 11003, 11005, 11007, 11009, 11011, 11013, 11015, 11017, 11019, - 11021, 11023, 11025, 11027, 11029, 0, 11031, 11033, 11035, 11037, 0, 0, - 11039, 11041, 11043, 11045, 11047, 11049, 11051, 11053, 0, 11055, 11057, - 11059, 11061, 11063, 11065, 11067, 0, 11069, 11071, 11073, 11075, 11077, - 11079, 11081, 11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, - 11099, 11101, 11103, 11105, 11107, 11109, 11111, 11113, 11115, 11117, - 11119, 11121, 11123, 0, 11125, 11127, 11129, 11131, 0, 11133, 11135, - 11137, 11139, 11141, 0, 11143, 0, 0, 0, 11145, 11147, 11149, 11151, - 11153, 11155, 11157, 0, 11159, 11161, 11163, 11165, 11167, 11169, 11171, - 11173, 11175, 11177, 11179, 11181, 11183, 11185, 11187, 11189, 11191, - 11193, 11195, 11197, 11199, 11201, 11203, 11205, 11207, 11209, 11211, - 11213, 11215, 11217, 11219, 11221, 11223, 11225, 11227, 11229, 11231, - 11233, 11235, 11237, 11239, 11241, 11243, 11245, 11247, 11249, 11251, - 11253, 11255, 11257, 11259, 11261, 11263, 11265, 11267, 11269, 11271, - 11273, 11275, 11277, 11279, 11281, 11283, 11285, 11287, 11289, 11291, - 11293, 11295, 11297, 11299, 11301, 11303, 11305, 11307, 11309, 11311, - 11313, 11315, 11317, 11319, 11321, 11323, 11325, 11327, 11329, 11331, - 11333, 11335, 11337, 11339, 11341, 11343, 11345, 11347, 11349, 11351, - 11353, 11355, 11357, 11359, 11361, 11363, 11365, 11367, 11369, 11371, - 11373, 11375, 11377, 11379, 11381, 11383, 11385, 11387, 11389, 11391, - 11393, 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, - 11413, 11415, 11417, 11419, 11421, 11423, 11425, 11427, 11429, 11431, - 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, - 11453, 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, - 11473, 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, - 11493, 11495, 11497, 11499, 11501, 11503, 11505, 11507, 11509, 11511, - 11513, 11515, 11517, 11519, 11521, 11523, 11525, 11527, 11529, 11531, - 11533, 11535, 11537, 11539, 11541, 11543, 11545, 11547, 11549, 11551, - 11553, 11555, 11557, 11559, 11561, 11563, 11565, 11567, 11569, 11571, - 11573, 11575, 11577, 11579, 11581, 11583, 11585, 11587, 11589, 11591, - 11593, 11595, 11597, 11599, 11601, 11603, 11605, 11607, 11609, 11611, - 11613, 11615, 11617, 11619, 11621, 11623, 11625, 11627, 11629, 11631, - 11633, 11635, 11637, 11639, 11641, 11643, 11645, 11647, 11649, 11651, - 11653, 11655, 11657, 11659, 11661, 11663, 11665, 11667, 11669, 11671, - 11673, 11675, 11677, 11679, 11681, 11683, 11685, 11687, 11689, 11691, - 11693, 11695, 11697, 11699, 11701, 11703, 11705, 11707, 11709, 11711, - 11713, 11715, 11717, 11719, 11721, 11723, 11725, 11727, 11729, 11731, - 11733, 11735, 11737, 11739, 11741, 11743, 11745, 11747, 11749, 11751, - 11753, 11755, 11757, 11759, 11761, 11763, 11765, 11767, 11769, 11771, - 11773, 11775, 11777, 11779, 11781, 11783, 11785, 11787, 11789, 11791, - 11793, 11795, 11797, 11799, 11801, 11803, 11805, 11807, 11809, 11811, - 11813, 11815, 11817, 11819, 11821, 11823, 11825, 11827, 11829, 11831, - 11833, 11835, 11837, 0, 0, 11839, 11841, 11843, 11845, 11847, 11849, - 11851, 11853, 11855, 11857, 11859, 11861, 11863, 11865, 11867, 11869, - 11871, 11873, 11875, 11877, 11879, 11881, 11883, 11885, 11887, 11889, - 11891, 11893, 11895, 11897, 11899, 11901, 11903, 11905, 11907, 11909, - 11911, 11913, 11915, 11917, 11919, 11921, 11923, 11925, 11927, 11929, - 11931, 11933, 11935, 11937, 11939, 11941, 11943, 11945, 11947, 11949, - 11951, 11953, 11955, 11957, 11959, 11961, 11963, 11965, 11967, 11969, - 11971, 11973, 11975, 11977, 11979, 11981, 11983, 11985, 11987, 11989, - 11991, 11993, 11995, 11997, 11999, 12001, 12003, 12005, 12007, 12009, - 12011, 12013, 12015, 12017, 12019, 12021, 12023, 12025, 12027, 12029, - 12031, 12033, 12035, 12037, 12039, 12041, 12043, 12045, 12047, 12049, - 12051, 12053, 12055, 12057, 12059, 12061, 12063, 12065, 12067, 12069, - 12071, 12073, 12075, 12077, 12079, 12081, 12083, 12085, 12087, 12089, - 12091, 12093, 12095, 12097, 12099, 12101, 12103, 12105, 12107, 12109, - 12111, 12113, 12115, 12117, 12119, 12121, 12123, 12125, 12127, 12129, - 12131, 12133, 12135, 12137, 12139, 12141, 12143, 12145, 12147, 12149, - 12151, 12153, 12155, 12157, 12159, 12161, 12163, 12165, 12167, 12169, - 12171, 12173, 12175, 12177, 12179, 12181, 12183, 12185, 12187, 12189, - 12191, 12193, 12195, 12197, 12199, 12201, 12203, 12205, 12207, 12209, - 12211, 12213, 12215, 12217, 12219, 12221, 12223, 12225, 12227, 12229, - 12231, 12233, 12235, 12237, 12239, 12241, 12243, 12245, 12247, 12249, - 12251, 12253, 12255, 12257, 12259, 12261, 12263, 12265, 12267, 12269, - 12271, 12273, 12275, 12277, 12279, 12281, 12283, 12285, 12287, 12289, - 12291, 12293, 12295, 12297, 12299, 12301, 12303, 12305, 12307, 12309, - 12311, 12313, 12315, 12317, 12319, 12321, 12323, 12325, 12327, 12329, - 12331, 12333, 12335, 12337, 12339, 12341, 12343, 12345, 12347, 12349, - 12351, 12353, 12355, 12357, 12359, 12361, 12363, 12365, 12367, 12369, - 12371, 12373, 12375, 12377, 12379, 12381, 12383, 12385, 12387, 12389, - 12391, 12393, 12395, 12397, 12399, 12401, 12403, 12405, 12407, 12409, - 12411, 12413, 12415, 12417, 12419, 12421, 0, 0, 12423, 12425, 12427, - 12429, 12431, 12433, 12435, 12437, 12439, 12441, 12443, 12445, 12447, - 12449, 12451, 12453, 12455, 12457, 12459, 12461, 12463, 12465, 12467, - 12469, 12471, 12473, 12475, 12477, 12479, 12481, 12483, 12485, 12487, - 12489, 12491, 12493, 12495, 12497, 12499, 12501, 12503, 12505, 12507, - 12509, 12511, 12513, 12515, 12517, 12519, 12521, 12523, 12525, 12527, - 12529, 0, 12531, 12533, 12535, 12537, 12539, 12541, 12543, 12545, 12547, - 12549, 12551, 12553, 12555, 12557, 12559, 12561, 12563, 12565, 12567, - 12569, 12571, 12573, 12575, 12577, 12579, 12581, 12583, 0, 12585, 12587, - 0, 12589, 0, 0, 12591, 0, 12593, 12595, 12597, 12599, 12601, 12603, - 12605, 12607, 12609, 12611, 0, 12613, 12615, 12617, 12619, 0, 12621, 0, - 12623, 0, 0, 0, 0, 0, 0, 12625, 0, 0, 0, 0, 12627, 0, 12629, 0, 12631, 0, - 12633, 12635, 12637, 0, 12639, 12641, 0, 12643, 0, 0, 12645, 0, 12647, 0, - 12649, 0, 12651, 0, 12653, 0, 12655, 12657, 0, 12659, 0, 0, 12661, 12663, - 12665, 12667, 0, 12669, 12671, 12673, 12675, 12677, 12679, 12681, 0, - 12683, 12685, 12687, 12689, 0, 12691, 12693, 12695, 12697, 0, 12699, 0, - 12701, 12703, 12705, 12707, 12709, 12711, 12713, 12715, 12717, 12719, 0, - 12721, 12723, 12725, 12727, 12729, 12731, 12733, 12735, 12737, 12739, - 12741, 12743, 12745, 12747, 12749, 12751, 12753, 0, 0, 0, 0, 0, 12755, - 12757, 12759, 0, 12761, 12763, 12765, 12767, 12769, 0, 12771, 12773, - 12775, 12777, 12779, 12781, 12783, 12785, 12787, 12789, 12791, 12793, - 12795, 12797, 12799, 12801, 12803, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 12805, 12808, 12811, 12814, 12817, 12820, 12823, - 12826, 12829, 12832, 12835, 0, 0, 0, 0, 0, 12838, 12842, 12846, 12850, - 12854, 12858, 12862, 12866, 12870, 12874, 12878, 12882, 12886, 12890, - 12894, 12898, 12902, 12906, 12910, 12914, 12918, 12922, 12926, 12930, - 12934, 12938, 12942, 12946, 12948, 12950, 12953, 0, 12956, 12958, 12960, - 12962, 12964, 12966, 12968, 12970, 12972, 12974, 12976, 12978, 12980, - 12982, 12984, 12986, 12988, 12990, 12992, 12994, 12996, 12998, 13000, - 13002, 13004, 13006, 13008, 13011, 13014, 13017, 13020, 13024, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 13027, 13030, 13033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13036, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13039, 13042, 13045, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 13047, 13049, 13051, 13053, 13055, 13057, 13059, - 13061, 13063, 13065, 13067, 13069, 13071, 13073, 13075, 13077, 13079, - 13081, 13083, 13085, 13087, 13089, 13091, 13093, 13095, 13097, 13099, - 13101, 13103, 13105, 13107, 13109, 13111, 13113, 13115, 13117, 13119, - 13121, 13123, 13125, 13127, 13129, 13131, 13133, 0, 0, 0, 0, 13135, - 13139, 13143, 13147, 13151, 13155, 13159, 13163, 13167, 0, 0, 0, 0, 0, 0, - 0, 13171, 13173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13175, 13177, - 13179, 13181, 13183, 13185, 13187, 13189, 13191, 13193, 0, 0, 0, 0, 0, 0, - 13195, 13197, 13199, 13201, 13203, 13205, 13207, 13209, 13211, 13213, - 13215, 13217, 13219, 13221, 13223, 13225, 13227, 13229, 13231, 13233, - 13235, 13237, 13239, 13241, 13243, 13245, 13247, 13249, 13251, 13253, - 13255, 13257, 13259, 13261, 13263, 13265, 13267, 13269, 13271, 13273, - 13275, 13277, 13279, 13281, 13283, 13285, 13287, 13289, 13291, 13293, - 13295, 13297, 13299, 13301, 13303, 13305, 13307, 13309, 13311, 13313, - 13315, 13317, 13319, 13321, 13323, 13325, 13327, 13329, 13331, 13333, - 13335, 13337, 13339, 13341, 13343, 13345, 13347, 13349, 13351, 13353, - 13355, 13357, 13359, 13361, 13363, 13365, 13367, 13369, 13371, 13373, - 13375, 13377, 13379, 13381, 13383, 13385, 13387, 13389, 13391, 13393, - 13395, 13397, 13399, 13401, 13403, 13405, 13407, 13409, 13411, 13413, - 13415, 13417, 13419, 13421, 13423, 13425, 13427, 13429, 13431, 13433, - 13435, 13437, 13439, 13441, 13443, 13445, 13447, 13449, 13451, 13453, - 13455, 13457, 13459, 13461, 13463, 13465, 13467, 13469, 13471, 13473, - 13475, 13477, 13479, 13481, 13483, 13485, 13487, 13489, 13491, 13493, - 13495, 13497, 13499, 13501, 13503, 13505, 13507, 13509, 13511, 13513, - 13515, 13517, 13519, 13521, 13523, 13525, 13527, 13529, 13531, 13533, - 13535, 13537, 13539, 13541, 13543, 13545, 13547, 13549, 13551, 13553, - 13555, 13557, 13559, 13561, 13563, 13565, 13567, 13569, 13571, 13573, - 13575, 13577, 13579, 13581, 13583, 13585, 13587, 13589, 13591, 13593, - 13595, 13597, 13599, 13601, 13603, 13605, 13607, 13609, 13611, 13613, - 13615, 13617, 13619, 13621, 13623, 13625, 13627, 13629, 13631, 13633, - 13635, 13637, 13639, 13641, 13643, 13645, 13647, 13649, 13651, 13653, - 13655, 13657, 13659, 13661, 13663, 13665, 13667, 13669, 13671, 13673, - 13675, 13677, 13679, 13681, 13683, 13685, 13687, 13689, 13691, 13693, - 13695, 13697, 13699, 13701, 13703, 13705, 13707, 13709, 13711, 13713, - 13715, 13717, 13719, 13721, 13723, 13725, 13727, 13729, 13731, 13733, - 13735, 13737, 13739, 13741, 13743, 13745, 13747, 13749, 13751, 13753, - 13755, 13757, 13759, 13761, 13763, 13765, 13767, 13769, 13771, 13773, - 13775, 13777, 13779, 13781, 13783, 13785, 13787, 13789, 13791, 13793, - 13795, 13797, 13799, 13801, 13803, 13805, 13807, 13809, 13811, 13813, - 13815, 13817, 13819, 13821, 13823, 13825, 13827, 13829, 13831, 13833, - 13835, 13837, 13839, 13841, 13843, 13845, 13847, 13849, 13851, 13853, - 13855, 13857, 13859, 13861, 13863, 13865, 13867, 13869, 13871, 13873, - 13875, 13877, 13879, 13881, 13883, 13885, 13887, 13889, 13891, 13893, - 13895, 13897, 13899, 13901, 13903, 13905, 13907, 13909, 13911, 13913, - 13915, 13917, 13919, 13921, 13923, 13925, 13927, 13929, 13931, 13933, - 13935, 13937, 13939, 13941, 13943, 13945, 13947, 13949, 13951, 13953, - 13955, 13957, 13959, 13961, 13963, 13965, 13967, 13969, 13971, 13973, - 13975, 13977, 13979, 13981, 13983, 13985, 13987, 13989, 13991, 13993, - 13995, 13997, 13999, 14001, 14003, 14005, 14007, 14009, 14011, 14013, - 14015, 14017, 14019, 14021, 14023, 14025, 14027, 14029, 14031, 14033, - 14035, 14037, 14039, 14041, 14043, 14045, 14047, 14049, 14051, 14053, - 14055, 14057, 14059, 14061, 14063, 14065, 14067, 14069, 14071, 14073, - 14075, 14077, 14079, 14081, 14083, 14085, 14087, 14089, 14091, 14093, - 14095, 14097, 14099, 14101, 14103, 14105, 14107, 14109, 14111, 14113, - 14115, 14117, 14119, 14121, 14123, 14125, 14127, 14129, 14131, 14133, - 14135, 14137, 14139, 14141, 14143, 14145, 14147, 14149, 14151, 14153, - 14155, 14157, 14159, 14161, 14163, 14165, 14167, 14169, 14171, 14173, - 14175, 14177, 14179, 14181, 14183, 14185, 14187, 14189, 14191, 14193, - 14195, 14197, 14199, 14201, 14203, 14205, 14207, 14209, 14211, 14213, - 14215, 14217, 14219, 14221, 14223, 14225, 14227, 14229, 14231, 14233, - 14235, 14237, 14239, 14241, 14243, 14245, 14247, 14249, 14251, 14253, - 14255, 14257, 14259, 14261, 14263, 14265, 14267, 14269, 14271, 14273, - 14275, 14277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -}; - -/* NFC pairs */ -#define COMP_SHIFT 2 -static const unsigned short comp_index[] = { - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, - 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 0, 12, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, - 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 32, 33, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 36, - 37, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 44, 45, 46, 47, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 0, 50, 0, 51, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 55, 56, 57, - 58, 59, 0, 0, 0, 0, 0, 0, 0, 0, 60, 61, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63, 64, 65, 0, 66, 67, 68, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 71, - 72, 73, 74, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 77, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 78, 79, 0, 80, 81, 82, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 84, 85, 86, 0, 87, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 90, 0, 91, - 92, 93, 0, 0, 0, 0, 0, 0, 0, 0, 94, 95, 96, 97, 98, 99, 100, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 101, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, - 104, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 107, 108, 109, 0, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 111, 112, 0, 113, 114, 0, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 117, - 118, 119, 120, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 123, 0, - 124, 0, 0, 0, 0, 0, 0, 0, 0, 125, 126, 127, 128, 0, 129, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 130, 0, 131, 132, 133, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 135, 136, 137, 138, 139, 140, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 144, 145, 146, 0, 147, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 148, 149, 150, 151, 152, 153, 154, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 155, 156, 157, 158, 159, 160, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 162, 0, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 165, 166, - 167, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 169, 0, 0, 170, 171, 172, 173, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 174, 175, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 177, 178, 179, 180, 0, 181, 182, 183, 0, 0, 0, 0, 0, 0, 0, 0, 184, 185, - 186, 187, 188, 0, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 191, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, 194, 195, 196, 197, 198, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 199, 200, 201, 0, 202, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 204, 205, 206, 207, 208, 209, 0, 0, 0, 0, 0, 0, 0, 0, 210, 211, - 212, 213, 214, 215, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 218, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 220, 221, 222, 0, 223, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 226, - 227, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, 0, 232, 0, - 233, 0, 0, 0, 0, 0, 0, 0, 0, 234, 235, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 245, 246, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, - 249, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 252, 253, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 257, 0, 258, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 260, 261, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, - 267, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 271, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 273, 274, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 278, 279, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 282, - 283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 284, 285, 286, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 288, 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 299, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 301, 302, 303, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 306, - 307, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 310, 311, 0, 312, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 314, 0, 315, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 326, 327, - 0, 328, 329, 0, 0, 330, 0, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 332, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 0, 0, 335, 0, 0, 0, 336, 0, 0, 0, 0, 0, - 0, 0, 337, 338, 339, 0, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 341, 0, 0, - 342, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 345, 346, 347, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 349, 0, 0, 0, 350, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, - 0, 0, 354, 355, 356, 0, 357, 0, 0, 358, 359, 0, 0, 0, 0, 0, 0, 0, 360, 0, - 0, 0, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 362, 0, 0, 363, 364, 0, 0, - 365, 0, 0, 0, 0, 0, 0, 0, 0, 366, 367, 0, 368, 0, 0, 0, 369, 0, 0, 0, 0, - 0, 0, 0, 370, 371, 0, 0, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, 375, 376, 377, 378, 0, 0, - 379, 0, 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 381, 0, 0, 0, 382, 0, 0, 0, 0, 0, - 0, 0, 383, 384, 0, 0, 0, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0, 0, 386, 0, 0, 0, - 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, 0, - 0, 0, 0, 0, 0, 389, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 392, 393, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 395, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 399, 400, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 404, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 407, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 413, 414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 418, 419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 421, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422, 423, 424, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 426, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 429, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 430, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 433, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 439, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 442, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 445, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 448, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 449, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 452, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 455, 456, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 462, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 465, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 468, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 469, 0, 0, 0, 470, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 476, 477, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 480, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 483, 0, 0, 0, 0, - 0, 0, 484, 0, 0, 0, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 486, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 489, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 492, 0, 0, 0, - 0, 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, 0, 494, 0, 0, 0, 0, 0, 0, 0, 0, 495, - 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 497, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 500, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, 0, 0, 0, 0, 503, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 505, 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 507, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 508, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, - 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 0, 0, 518, 0, 0, - 0, 0, 0, 0, 519, 0, 0, 0, 0, 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, 0, 521, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 522, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 524, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 525, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 527, 0, - 0, 0, 0, 0, 0, 0, 0, 528, 0, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, - 530, 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 0, 532, 533, 0, 0, 0, 0, 0, - 534, 0, 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, 0, 0, - 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 539, 540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 542, 0, 0, - 0, 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 0, 545, 0, - 0, 0, 0, 0, 0, 0, 546, 547, 0, 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, 0, 0, 0, - 549, 0, 0, 0, 0, 0, 0, 550, 0, 0, 0, 0, 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, - 0, 552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 553, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 556, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 558, 0, 0, 0, 0, 0, 0, 0, 559, 0, 0, 0, 0, 0, 0, 560, 0, 0, 0, 0, - 0, 0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 564, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 565, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 566, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 570, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 572, 0, 0, 0, 0, 0, 0, 0, 573, 0, 0, 0, 0, 0, 0, 574, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 575, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 576, 0, 0, 0, 0, 0, 0, 0, 577, 578, 0, 0, 0, 0, 0, 579, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 580, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 582, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 583, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 586, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 589, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 590, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 591, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 592, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 594, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 595, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 598, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 601, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 604, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 606, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 607, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 610, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 613, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 614, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 617, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 619, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 621, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 623, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 626, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 629, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 632, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 635, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 638, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 639, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 642, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 644, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 645, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 647, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 648, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 651, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 654, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 657, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 660, 661, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 662, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 665, 666, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 675, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 678, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 681, -}; - -static const unsigned int comp_data[] = { - 0, 0, 0, 0, 0, 0, 0, 8814, 0, 0, 8800, 0, 0, 8815, 0, 0, 0, 192, 193, - 194, 195, 256, 258, 550, 196, 7842, 197, 0, 461, 512, 514, 0, 0, 0, 7840, - 0, 7680, 0, 0, 260, 0, 0, 7682, 0, 0, 7684, 0, 0, 0, 0, 7686, 0, 262, - 264, 0, 0, 0, 266, 0, 0, 0, 0, 268, 0, 199, 0, 0, 0, 7690, 0, 0, 0, 0, - 270, 0, 0, 0, 0, 0, 7692, 0, 0, 0, 7696, 0, 7698, 0, 0, 7694, 0, 0, 0, 0, - 200, 201, 202, 7868, 274, 276, 278, 203, 7866, 0, 0, 282, 516, 518, 0, 0, - 0, 7864, 0, 0, 0, 552, 280, 7704, 0, 7706, 0, 0, 0, 7710, 0, 500, 284, 0, - 7712, 286, 288, 0, 0, 0, 0, 486, 0, 290, 0, 0, 0, 292, 0, 0, 0, 7714, - 7718, 0, 0, 0, 542, 0, 0, 0, 0, 0, 7716, 0, 0, 0, 7720, 0, 0, 7722, 0, 0, - 204, 205, 206, 296, 298, 300, 304, 207, 7880, 0, 0, 463, 520, 522, 0, 0, - 0, 7882, 0, 0, 0, 0, 302, 0, 0, 7724, 0, 0, 0, 308, 0, 7728, 0, 0, 0, 0, - 0, 488, 0, 7730, 0, 0, 0, 310, 0, 0, 0, 0, 7732, 0, 0, 0, 0, 0, 313, 0, - 317, 0, 0, 0, 0, 0, 7734, 0, 0, 0, 315, 0, 7740, 0, 0, 7738, 0, 0, 0, 0, - 0, 7742, 0, 0, 0, 0, 7744, 0, 0, 7746, 0, 504, 323, 0, 209, 0, 0, 7748, - 0, 0, 0, 0, 327, 0, 7750, 0, 0, 0, 325, 0, 7754, 0, 0, 7752, 0, 0, 0, 0, - 210, 211, 212, 213, 332, 334, 558, 214, 7886, 0, 336, 465, 524, 526, 0, - 0, 416, 7884, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 7764, 7766, 0, 0, 0, 0, 0, - 340, 0, 0, 0, 0, 7768, 344, 528, 530, 0, 0, 0, 7770, 0, 0, 0, 342, 0, 0, - 0, 0, 7774, 0, 346, 348, 0, 0, 0, 7776, 0, 0, 0, 0, 352, 0, 7778, 0, 0, - 536, 350, 0, 0, 0, 7786, 0, 0, 0, 0, 356, 0, 7788, 0, 0, 538, 354, 0, - 7792, 0, 0, 7790, 0, 0, 0, 0, 217, 218, 219, 360, 362, 364, 0, 220, 7910, - 366, 368, 467, 532, 534, 0, 0, 431, 7908, 7794, 0, 0, 0, 370, 7798, 0, - 7796, 7804, 0, 0, 0, 0, 0, 7806, 0, 7808, 7810, 372, 0, 0, 0, 7814, 7812, - 0, 7816, 0, 0, 0, 7818, 7820, 0, 0, 0, 7922, 221, 374, 7928, 562, 0, - 7822, 376, 7926, 0, 0, 0, 0, 7924, 0, 0, 377, 7824, 0, 0, 0, 379, 381, 0, - 0, 0, 0, 0, 7826, 0, 0, 0, 0, 7828, 224, 225, 226, 227, 257, 259, 551, - 228, 7843, 229, 0, 462, 513, 515, 0, 0, 0, 7841, 0, 7681, 0, 0, 261, 0, - 0, 7683, 0, 0, 7685, 0, 0, 0, 0, 7687, 0, 0, 0, 0, 0, 263, 265, 0, 0, 0, - 267, 0, 0, 0, 0, 269, 0, 0, 0, 0, 0, 231, 0, 0, 0, 7691, 271, 0, 0, 0, 0, - 0, 7693, 0, 0, 0, 7697, 0, 7699, 0, 0, 7695, 232, 233, 234, 7869, 275, - 277, 279, 235, 7867, 0, 0, 283, 517, 519, 0, 0, 0, 7865, 0, 0, 0, 553, - 281, 7705, 0, 7707, 0, 0, 0, 7711, 0, 0, 0, 0, 0, 501, 285, 0, 7713, 287, - 289, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 291, 0, 0, 0, 293, 0, 0, 0, 7715, - 7719, 0, 0, 0, 543, 0, 0, 0, 0, 0, 7717, 0, 0, 0, 7721, 0, 0, 7723, 0, - 7830, 236, 237, 238, 297, 299, 301, 0, 239, 7881, 0, 0, 464, 521, 523, 0, - 0, 0, 7883, 0, 0, 0, 0, 303, 0, 0, 7725, 0, 0, 0, 309, 0, 0, 0, 0, 496, - 0, 0, 0, 0, 7729, 0, 489, 0, 0, 0, 0, 0, 7731, 0, 0, 0, 311, 7733, 0, 0, - 0, 0, 0, 314, 0, 318, 0, 0, 0, 0, 0, 7735, 0, 0, 0, 316, 0, 7741, 0, 0, - 7739, 0, 7743, 0, 0, 0, 0, 7745, 0, 0, 7747, 0, 0, 0, 0, 0, 505, 324, 0, - 241, 0, 0, 7749, 0, 0, 0, 0, 328, 0, 7751, 0, 0, 0, 326, 0, 7755, 0, 0, - 7753, 0, 0, 0, 0, 242, 243, 244, 245, 333, 335, 559, 246, 7887, 0, 337, - 466, 525, 527, 0, 0, 417, 7885, 491, 0, 0, 0, 0, 0, 7765, 0, 0, 0, 0, - 7767, 0, 341, 0, 0, 0, 0, 7769, 0, 0, 0, 0, 345, 529, 531, 0, 0, 0, 7771, - 0, 0, 0, 343, 0, 0, 0, 0, 7775, 0, 347, 349, 0, 0, 0, 7777, 0, 0, 0, 0, - 353, 0, 7779, 0, 0, 537, 351, 0, 0, 0, 7787, 7831, 0, 0, 0, 357, 0, 0, 0, - 0, 0, 7789, 0, 0, 539, 355, 0, 7793, 0, 0, 7791, 0, 0, 0, 0, 249, 250, - 251, 361, 363, 365, 0, 252, 7911, 367, 369, 468, 533, 535, 0, 0, 432, - 7909, 7795, 0, 0, 0, 371, 7799, 0, 7797, 0, 0, 0, 0, 7805, 0, 7807, 0, 0, - 0, 0, 0, 7809, 7811, 373, 0, 0, 0, 7815, 7813, 0, 7832, 0, 0, 0, 7817, 0, - 0, 0, 7819, 7821, 0, 0, 0, 7923, 253, 375, 7929, 563, 0, 7823, 255, 7927, - 7833, 0, 0, 0, 7925, 0, 0, 378, 7825, 0, 0, 0, 380, 0, 0, 0, 0, 382, 0, - 7827, 0, 0, 0, 0, 7829, 0, 0, 0, 0, 8173, 901, 0, 0, 0, 0, 0, 0, 8129, 0, - 0, 7846, 7844, 0, 7850, 0, 0, 0, 0, 7848, 0, 0, 478, 0, 0, 0, 506, 0, 0, - 508, 0, 0, 482, 0, 0, 0, 7688, 0, 7872, 7870, 0, 7876, 0, 0, 0, 0, 7874, - 0, 0, 0, 7726, 0, 0, 0, 0, 0, 7890, 7888, 0, 7894, 0, 0, 0, 0, 7892, 0, - 0, 0, 7756, 0, 0, 556, 0, 0, 7758, 0, 0, 0, 554, 0, 0, 0, 510, 0, 0, 0, - 0, 0, 475, 471, 0, 0, 469, 0, 0, 473, 0, 0, 0, 7847, 7845, 0, 7851, 0, 0, - 0, 0, 7849, 0, 0, 479, 0, 0, 0, 507, 0, 0, 509, 0, 0, 483, 0, 0, 0, 7689, - 0, 7873, 7871, 0, 7877, 0, 0, 0, 0, 7875, 0, 0, 0, 7727, 0, 0, 0, 0, 0, - 7891, 7889, 0, 7895, 0, 0, 0, 0, 7893, 0, 0, 0, 7757, 0, 0, 557, 0, 0, - 7759, 0, 0, 0, 555, 0, 0, 0, 511, 0, 0, 0, 0, 0, 476, 472, 0, 0, 470, 0, - 0, 474, 0, 0, 0, 7856, 7854, 0, 7860, 0, 0, 0, 0, 7858, 0, 0, 7857, 7855, - 0, 7861, 0, 0, 0, 0, 7859, 0, 0, 7700, 7702, 0, 0, 0, 0, 0, 7701, 7703, - 0, 0, 0, 0, 0, 7760, 7762, 0, 7761, 7763, 0, 0, 0, 7780, 0, 0, 7781, 0, - 0, 7782, 0, 0, 0, 0, 0, 0, 7783, 0, 7800, 0, 0, 7801, 0, 0, 0, 0, 7802, - 0, 0, 7803, 0, 0, 0, 0, 0, 7835, 0, 0, 0, 0, 7900, 7898, 0, 7904, 0, 0, - 0, 0, 7902, 7906, 0, 0, 0, 0, 0, 7901, 7899, 0, 7905, 0, 0, 0, 0, 7903, - 0, 0, 0, 0, 7907, 0, 7914, 7912, 0, 7918, 0, 0, 0, 0, 7916, 0, 0, 0, 0, - 7920, 0, 7915, 7913, 0, 7919, 7917, 0, 0, 0, 0, 7921, 0, 0, 0, 0, 494, 0, - 0, 0, 492, 0, 0, 493, 0, 0, 480, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 7708, 0, - 0, 7709, 0, 560, 0, 0, 0, 0, 0, 0, 561, 0, 495, 0, 0, 0, 8122, 902, 0, 0, - 8121, 8120, 0, 0, 0, 0, 7944, 7945, 0, 0, 0, 0, 0, 8124, 0, 8136, 904, 0, - 0, 0, 0, 7960, 7961, 0, 0, 0, 8138, 905, 0, 0, 0, 0, 7976, 7977, 0, 8140, - 0, 0, 0, 0, 0, 8154, 906, 0, 0, 8153, 8152, 0, 938, 0, 0, 7992, 7993, 0, - 0, 0, 8184, 908, 0, 0, 0, 0, 8008, 8009, 0, 0, 0, 0, 0, 0, 8172, 0, 0, 0, - 8170, 910, 0, 0, 8169, 8168, 0, 939, 0, 0, 0, 8025, 0, 0, 0, 8186, 911, - 8040, 8041, 0, 0, 0, 0, 0, 8188, 0, 0, 8116, 0, 0, 8132, 0, 0, 0, 0, 0, - 8048, 940, 0, 0, 8113, 8112, 0, 0, 0, 0, 7936, 7937, 0, 0, 0, 0, 8118, - 8115, 0, 0, 0, 0, 0, 8050, 941, 7952, 7953, 0, 0, 0, 8052, 942, 0, 0, 0, - 0, 7968, 7969, 0, 0, 0, 0, 8134, 8131, 0, 8054, 943, 0, 0, 8145, 8144, 0, - 970, 0, 0, 7984, 7985, 8150, 0, 0, 0, 0, 0, 0, 8056, 972, 0, 0, 0, 0, - 8000, 8001, 0, 8164, 8165, 0, 0, 0, 8058, 973, 0, 0, 8161, 8160, 0, 971, - 0, 0, 0, 0, 0, 0, 8016, 8017, 0, 0, 0, 0, 8166, 0, 0, 8060, 974, 0, 0, 0, - 0, 8032, 8033, 8182, 8179, 0, 0, 0, 0, 0, 8146, 912, 0, 0, 0, 0, 0, 0, - 8151, 0, 0, 8162, 944, 0, 0, 8167, 0, 0, 0, 8180, 0, 0, 979, 0, 0, 0, 0, - 0, 980, 0, 0, 1031, 0, 0, 0, 0, 1232, 0, 1234, 0, 0, 0, 0, 1027, 0, 1024, - 0, 0, 0, 0, 1238, 0, 1025, 1217, 0, 1244, 0, 0, 1246, 0, 0, 0, 1037, 0, - 0, 0, 1250, 1049, 0, 1252, 0, 0, 0, 0, 1036, 0, 0, 0, 0, 1254, 0, 0, 0, - 1262, 1038, 0, 1264, 0, 0, 1266, 0, 0, 0, 1268, 0, 0, 0, 0, 0, 0, 1272, - 0, 0, 1260, 0, 0, 0, 0, 1233, 0, 1235, 0, 0, 0, 0, 1107, 0, 1104, 0, 0, - 0, 0, 1239, 0, 1105, 1218, 0, 1245, 0, 0, 1247, 0, 0, 0, 1117, 0, 0, 0, - 1251, 1081, 0, 1253, 0, 0, 0, 0, 1116, 0, 0, 0, 0, 1255, 0, 0, 0, 1263, - 1118, 0, 1265, 0, 0, 1267, 0, 0, 0, 1269, 0, 0, 0, 0, 0, 0, 1273, 0, 0, - 1261, 0, 0, 1111, 0, 0, 0, 1142, 0, 0, 1143, 0, 0, 0, 0, 0, 1242, 0, 0, - 1243, 0, 0, 1258, 0, 0, 0, 0, 0, 0, 1259, 0, 1570, 1571, 1573, 0, 1572, - 0, 0, 1574, 0, 0, 0, 0, 0, 0, 1730, 0, 0, 1747, 0, 0, 1728, 0, 0, 0, 0, - 2345, 0, 0, 2353, 0, 0, 2356, 0, 0, 0, 2507, 2508, 0, 0, 0, 2891, 2888, - 2892, 2964, 0, 0, 0, 0, 0, 3018, 3020, 0, 3019, 0, 0, 0, 0, 3144, 0, 0, - 0, 0, 3264, 0, 3274, 3271, 3272, 0, 3275, 0, 0, 0, 0, 3402, 3404, 0, - 3403, 0, 0, 0, 0, 3546, 3548, 3550, 0, 0, 0, 0, 3549, 0, 0, 0, 0, 0, - 4134, 0, 0, 0, 6918, 0, 0, 6920, 0, 0, 6922, 0, 0, 6924, 0, 0, 0, 0, 0, - 0, 6926, 0, 0, 6930, 0, 0, 6971, 0, 0, 6973, 0, 0, 0, 0, 0, 0, 6976, 0, - 0, 6977, 0, 0, 6979, 0, 0, 0, 7736, 0, 0, 7737, 0, 0, 0, 0, 0, 0, 7772, - 0, 0, 7773, 0, 0, 0, 0, 7784, 0, 0, 7785, 0, 0, 7852, 0, 0, 7862, 0, 0, - 0, 7853, 0, 0, 7863, 0, 0, 0, 7878, 0, 0, 7879, 0, 0, 7896, 0, 0, 7897, - 0, 0, 0, 0, 7938, 7940, 0, 0, 7942, 8064, 0, 7939, 7941, 0, 0, 7943, - 8065, 0, 0, 8066, 0, 0, 0, 0, 0, 0, 8067, 0, 0, 8068, 0, 0, 8069, 0, 0, - 8070, 0, 0, 0, 0, 0, 0, 8071, 0, 7946, 7948, 0, 0, 7950, 8072, 0, 7947, - 7949, 0, 0, 7951, 8073, 0, 0, 8074, 0, 0, 0, 0, 0, 0, 8075, 0, 0, 8076, - 0, 0, 8077, 0, 0, 8078, 0, 0, 0, 0, 0, 0, 8079, 0, 7954, 7956, 0, 7955, - 7957, 0, 0, 0, 0, 0, 7962, 7964, 0, 0, 0, 0, 0, 7963, 7965, 0, 7970, - 7972, 0, 0, 7974, 8080, 0, 7971, 7973, 0, 0, 7975, 8081, 0, 0, 8082, 0, - 0, 0, 0, 0, 0, 8083, 0, 0, 8084, 0, 0, 8085, 0, 0, 8086, 0, 0, 0, 0, 0, - 0, 8087, 0, 7978, 7980, 0, 0, 7982, 8088, 0, 7979, 7981, 0, 0, 7983, - 8089, 0, 0, 8090, 0, 0, 0, 0, 0, 0, 8091, 0, 0, 8092, 0, 0, 8093, 0, 0, - 8094, 0, 0, 0, 0, 0, 0, 8095, 0, 7986, 7988, 0, 0, 7990, 0, 0, 7987, - 7989, 0, 0, 7991, 0, 0, 0, 0, 0, 0, 7994, 7996, 0, 0, 0, 0, 0, 0, 7998, - 0, 0, 7995, 7997, 0, 0, 7999, 0, 0, 8002, 8004, 0, 8003, 8005, 0, 0, 0, - 0, 0, 8010, 8012, 0, 0, 0, 0, 0, 8011, 8013, 0, 8018, 8020, 0, 0, 8022, - 0, 0, 8019, 8021, 0, 0, 8023, 0, 0, 0, 0, 0, 0, 8027, 8029, 0, 0, 0, 0, - 0, 0, 8031, 0, 0, 8034, 8036, 0, 0, 8038, 8096, 0, 8035, 8037, 0, 0, - 8039, 8097, 0, 0, 8098, 0, 0, 8099, 0, 0, 0, 0, 0, 0, 8100, 0, 0, 8101, - 0, 0, 8102, 0, 0, 8103, 0, 0, 0, 0, 0, 8042, 8044, 0, 0, 8046, 8104, 0, - 8043, 8045, 0, 0, 8047, 8105, 0, 0, 8106, 0, 0, 8107, 0, 0, 0, 0, 0, 0, - 8108, 0, 0, 8109, 0, 0, 8110, 0, 0, 8111, 0, 0, 0, 0, 0, 0, 8114, 0, 0, - 8130, 0, 0, 8178, 0, 0, 8119, 0, 0, 0, 0, 0, 8141, 8142, 0, 0, 8143, 0, - 0, 0, 8135, 0, 0, 8183, 0, 0, 0, 0, 0, 8157, 8158, 0, 0, 0, 0, 0, 0, - 8159, 0, 8602, 0, 0, 8603, 0, 0, 0, 0, 0, 0, 8622, 0, 0, 8653, 0, 0, - 8655, 0, 0, 8654, 0, 0, 0, 0, 0, 0, 8708, 0, 0, 8713, 0, 0, 8716, 0, 0, - 8740, 0, 0, 0, 0, 0, 0, 8742, 0, 0, 8769, 0, 0, 8772, 0, 0, 8775, 0, 0, - 0, 0, 0, 0, 8777, 0, 0, 8813, 0, 0, 8802, 0, 0, 8816, 0, 0, 0, 0, 0, 0, - 8817, 0, 0, 8820, 0, 0, 8821, 0, 0, 8824, 0, 0, 0, 0, 0, 0, 8825, 0, 0, - 8832, 0, 0, 8833, 0, 0, 8928, 0, 0, 0, 0, 0, 0, 8929, 0, 0, 8836, 0, 0, - 8837, 0, 0, 8840, 0, 0, 0, 0, 0, 0, 8841, 0, 0, 8930, 0, 0, 8931, 0, 0, - 8876, 0, 0, 0, 0, 0, 0, 8877, 0, 0, 8878, 0, 0, 8879, 0, 0, 8938, 0, 0, - 0, 0, 0, 0, 8939, 0, 0, 8940, 0, 0, 8941, 0, 0, 0, 12436, 0, 0, 12364, 0, - 0, 0, 0, 0, 0, 12366, 0, 0, 12368, 0, 0, 12370, 0, 0, 12372, 0, 0, 0, 0, - 0, 0, 12374, 0, 0, 12376, 0, 0, 12378, 0, 0, 12380, 0, 0, 0, 0, 0, 0, - 12382, 0, 0, 12384, 0, 0, 12386, 0, 0, 12389, 0, 0, 0, 0, 0, 0, 12391, 0, - 0, 12393, 0, 0, 12400, 12401, 0, 12403, 12404, 0, 0, 0, 0, 0, 12406, - 12407, 0, 0, 0, 0, 0, 12409, 12410, 0, 12412, 12413, 0, 12446, 0, 0, 0, - 0, 0, 0, 12532, 0, 0, 12460, 0, 0, 12462, 0, 0, 12464, 0, 0, 0, 0, 0, 0, - 12466, 0, 0, 12468, 0, 0, 12470, 0, 0, 12472, 0, 0, 0, 0, 0, 0, 12474, 0, - 0, 12476, 0, 0, 12478, 0, 0, 12480, 0, 0, 0, 0, 0, 0, 12482, 0, 0, 12485, - 0, 0, 12487, 0, 0, 12489, 0, 0, 0, 0, 0, 0, 12496, 12497, 0, 0, 0, 0, 0, - 12499, 12500, 0, 12502, 12503, 0, 12505, 12506, 0, 0, 0, 0, 0, 12508, - 12509, 0, 0, 0, 0, 0, 12535, 0, 0, 12536, 0, 0, 12537, 0, 0, 0, 0, 0, 0, - 12538, 0, 0, 12542, 0, 0, 0, 0, 69786, 0, 0, 69788, 0, 0, 69803, 0, 0, 0, - 69934, 0, 0, 69935, 0, 0, 0, 70475, 70476, 0, 0, 0, 70844, 70843, 70846, - 0, 0, 0, 71098, 0, 0, 71099, 0, 0, 0, 71992, -}; - -static const change_record change_records_3_2_0[] = { - { 255, 255, 255, 255, 255, 0 }, - { 11, 255, 255, 255, 255, 0 }, - { 10, 255, 255, 255, 255, 0 }, - { 255, 30, 255, 255, 255, 0 }, - { 255, 2, 255, 255, 255, 0 }, - { 19, 21, 255, 255, 255, 0 }, - { 255, 255, 2, 255, 255, 0 }, - { 255, 255, 3, 255, 255, 0 }, - { 255, 255, 1, 255, 255, 0 }, - { 255, 0, 255, 255, 255, 0 }, - { 255, 29, 255, 255, 255, 0 }, - { 255, 26, 255, 255, 255, 0 }, - { 5, 255, 255, 255, 255, 0 }, - { 14, 6, 255, 255, 255, 0 }, - { 15, 255, 255, 255, 255, 0 }, - { 255, 255, 255, 255, 255, 1.0 }, - { 255, 255, 255, 255, 255, 2.0 }, - { 255, 255, 255, 255, 255, 3.0 }, - { 255, 255, 255, 255, 255, 4.0 }, - { 255, 255, 255, 255, 255, -1 }, - { 14, 255, 255, 255, 255, 0 }, - { 255, 255, 255, 0, 255, 0 }, - { 255, 19, 255, 255, 255, 0 }, - { 255, 7, 1, 255, 255, 0 }, - { 255, 7, 2, 255, 255, 0 }, - { 255, 7, 3, 255, 255, 0 }, - { 255, 7, 4, 255, 255, 0 }, - { 255, 7, 5, 255, 255, 0 }, - { 255, 7, 6, 255, 255, 0 }, - { 255, 7, 7, 255, 255, 0 }, - { 255, 7, 8, 255, 255, 0 }, - { 255, 7, 9, 255, 255, 0 }, - { 1, 5, 255, 255, 255, 0 }, - { 1, 19, 255, 255, 255, 0 }, - { 255, 10, 255, 255, 255, 0 }, - { 18, 255, 255, 255, 255, 0 }, - { 19, 255, 255, 255, 255, 0 }, - { 255, 255, 0, 255, 255, 0 }, - { 255, 255, 4, 255, 255, 0 }, - { 255, 255, 5, 255, 255, 0 }, - { 255, 255, 6, 255, 255, 0 }, - { 255, 255, 7, 255, 255, 0 }, - { 255, 255, 8, 255, 255, 0 }, - { 255, 255, 9, 255, 255, 0 }, - { 19, 30, 255, 255, 255, 0 }, - { 255, 8, 255, 255, 255, 0 }, - { 255, 27, 255, 255, 255, 0 }, - { 255, 255, 255, 255, 5, 0 }, - { 255, 22, 255, 255, 255, 0 }, - { 255, 23, 255, 255, 255, 0 }, - { 9, 255, 255, 255, 255, 0 }, - { 255, 255, 255, 1, 255, 0 }, - { 14, 4, 255, 255, 255, 0 }, - { 255, 20, 255, 255, 255, 0 }, - { 255, 255, 255, 255, 255, 1e+16 }, - { 255, 255, 255, 255, 255, 1e+20 }, - { 255, 19, 255, 255, 255, -1 }, - { 1, 255, 255, 0, 255, 0 }, -}; -static const unsigned char changes_3_2_0_index[] = { - 0, 1, 2, 2, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 2, 2, 2, 38, 39, 2, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 2, 53, 2, 2, 54, 55, 56, 57, 58, 2, 59, 60, 61, 62, 2, 63, 64, - 65, 66, 67, 68, 68, 2, 69, 2, 2, 70, 71, 72, 73, 74, 75, 76, 2, 2, 2, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 2, 2, 2, 2, 2, 2, 87, 2, 2, 2, 2, 2, - 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 89, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, - 91, 92, 2, 2, 2, 2, 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, - 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 100, 2, 2, 2, 2, 2, 2, 2, 2, 101, 51, - 51, 102, 103, 51, 104, 105, 106, 107, 108, 109, 110, 111, 112, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 114, 115, 116, 117, 118, 119, 2, 2, 120, 121, 122, - 2, 123, 124, 125, 126, 127, 128, 2, 129, 130, 131, 132, 133, 134, 2, 51, - 51, 135, 2, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 2, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 2, 158, 159, 2, - 160, 161, 162, 163, 2, 164, 165, 166, 167, 168, 169, 2, 2, 170, 171, 172, - 173, 2, 174, 2, 175, 51, 51, 51, 51, 51, 51, 51, 176, 177, 51, 178, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 51, 51, 51, - 51, 51, 51, 51, 179, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 51, 51, 51, 180, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 51, 51, 51, 181, 182, - 183, 184, 2, 2, 2, 2, 185, 186, 187, 188, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 103, 51, 51, 51, 51, 51, 51, 51, 51, 51, 189, 190, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 51, 191, 51, - 51, 192, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 193, 194, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 195, 196, 197, 198, 199, - 2, 2, 200, 2, 2, 2, 201, 202, 203, 51, 51, 51, 51, 51, 204, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 205, 2, 206, 2, 2, 207, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 51, 208, 209, 2, 2, 2, 2, 2, 210, 211, 212, 2, 213, 214, 2, 2, 215, 216, - 51, 217, 218, 2, 51, 51, 51, 51, 51, 51, 51, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 51, 228, 2, 2, 2, 2, 2, 2, 2, 2, 229, 230, 98, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 87, 231, 2, 232, 233, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 234, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 235, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 236, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 237, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 238, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 239, 51, 240, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 241, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 242, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 234, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 243, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 244, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -}; - -static const unsigned char changes_3_2_0_data[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, - 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 6, 7, 0, 0, 3, 0, 0, 8, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 10, 0, 9, 9, 0, 0, 0, 9, 9, - 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 9, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 17, 18, 19, 0, 0, 9, - 9, 9, 9, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 20, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 9, 9, 9, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 9, 9, 0, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 9, 0, - 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 33, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 37, 4, 0, 0, 38, 39, - 40, 41, 42, 43, 1, 1, 0, 0, 0, 4, 37, 8, 6, 7, 38, 39, 40, 41, 42, 43, 1, - 1, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 45, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 52, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, - 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 19, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 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, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 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, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 0, 0, 0, 1, 1, 21, 21, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 14, 14, 14, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +}; + +/* NFC pairs */ +#define COMP_SHIFT 2 +static const unsigned short comp_index[] = { + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 0, 12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, + 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 32, 33, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 36, + 37, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 44, 45, 46, 47, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 49, 0, 50, 0, 51, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 55, 56, 57, + 58, 59, 0, 0, 0, 0, 0, 0, 0, 0, 60, 61, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 63, 64, 65, 0, 66, 67, 68, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 71, + 72, 73, 74, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 77, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 78, 79, 0, 80, 81, 82, 83, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 85, 86, 0, 87, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 90, 0, 91, + 92, 93, 0, 0, 0, 0, 0, 0, 0, 0, 94, 95, 96, 97, 98, 99, 100, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 101, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, + 104, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 107, 108, 109, 0, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 111, 112, 0, 113, 114, 0, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 117, + 118, 119, 120, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 123, 0, + 124, 0, 0, 0, 0, 0, 0, 0, 0, 125, 126, 127, 128, 0, 129, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 130, 0, 131, 132, 133, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 135, 136, 137, 138, 139, 140, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 144, 145, 146, 0, 147, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 148, 149, 150, 151, 152, 153, 154, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 155, 156, 157, 158, 159, 160, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 162, 0, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 165, 166, + 167, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 169, 0, 0, 170, 171, 172, 173, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 174, 175, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 177, 178, 179, 180, 0, 181, 182, 183, 0, 0, 0, 0, 0, 0, 0, 0, 184, 185, + 186, 187, 188, 0, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, 194, 195, 196, 197, 198, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 199, 200, 201, 0, 202, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 204, 205, 206, 207, 208, 209, 0, 0, 0, 0, 0, 0, 0, 0, 210, 211, + 212, 213, 214, 215, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 218, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 220, 221, 222, 0, 223, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 226, + 227, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, 0, 232, 0, + 233, 0, 0, 0, 0, 0, 0, 0, 0, 234, 235, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 245, 246, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, + 249, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 252, 253, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 257, 0, 258, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 260, 261, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 266, + 267, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 270, 271, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 273, 274, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 279, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 282, + 283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 284, 285, 286, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 288, 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 299, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 301, 302, 303, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 306, + 307, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 310, 311, 0, 312, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 314, 0, 315, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 326, 327, + 0, 328, 329, 0, 0, 330, 0, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 332, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 333, 334, 0, 0, 335, 0, 0, 0, 336, 0, 0, 0, 0, 0, + 0, 0, 337, 338, 339, 0, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 341, 0, 0, + 342, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 345, 346, 347, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 349, 0, 0, 0, 350, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, + 0, 0, 354, 355, 356, 0, 357, 0, 0, 358, 359, 0, 0, 0, 0, 0, 0, 0, 360, 0, + 0, 0, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 362, 0, 0, 363, 364, 0, 0, + 365, 0, 0, 0, 0, 0, 0, 0, 0, 366, 367, 0, 368, 0, 0, 0, 369, 0, 0, 0, 0, + 0, 0, 0, 370, 371, 0, 0, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, 375, 376, 377, 378, 0, 0, + 379, 0, 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 381, 0, 0, 0, 382, 0, 0, 0, 0, 0, + 0, 0, 383, 384, 0, 0, 0, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0, 0, 386, 0, 0, 0, + 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, 0, + 0, 0, 0, 0, 0, 389, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 392, 393, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 395, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 399, 400, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 404, 405, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 407, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 413, 414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 417, 418, 419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 421, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422, 423, 424, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 426, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 429, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 430, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 433, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 439, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 442, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 445, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 448, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 449, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 452, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 455, 456, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 462, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 465, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 468, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 469, 0, 0, 0, 470, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 476, 477, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 480, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 483, 0, 0, 0, 0, + 0, 0, 484, 0, 0, 0, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 486, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 489, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 492, 0, 0, 0, + 0, 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, 0, 494, 0, 0, 0, 0, 0, 0, 0, 0, 495, + 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 497, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 500, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, 0, 0, 0, 0, 503, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 505, 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 507, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 508, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, + 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 0, 0, 518, 0, 0, + 0, 0, 0, 0, 519, 0, 0, 0, 0, 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, 0, 521, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 522, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 524, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 525, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 527, 0, + 0, 0, 0, 0, 0, 0, 0, 528, 0, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 530, 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 0, 532, 533, 0, 0, 0, 0, 0, + 534, 0, 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, 0, 0, + 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 539, 540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 542, 0, 0, + 0, 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 0, 545, 0, + 0, 0, 0, 0, 0, 0, 546, 547, 0, 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, 0, 0, 0, + 549, 0, 0, 0, 0, 0, 0, 550, 0, 0, 0, 0, 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, + 0, 552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 553, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 556, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 558, 0, 0, 0, 0, 0, 0, 0, 559, 0, 0, 0, 0, 0, 0, 560, 0, 0, 0, 0, + 0, 0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 564, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 565, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 566, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 567, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 570, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 572, 0, 0, 0, 0, 0, 0, 0, 573, 0, 0, 0, 0, 0, 0, 574, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 575, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 576, 0, 0, 0, 0, 0, 0, 0, 577, 578, 0, 0, 0, 0, 0, 579, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 580, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 582, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 583, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 586, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 589, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 590, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 591, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 592, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 594, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 595, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 598, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 601, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 604, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 606, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 607, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 610, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 613, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 614, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 617, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 619, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 621, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 623, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 626, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 629, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 632, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 635, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 638, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 639, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 642, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 644, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 645, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 647, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 648, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 651, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 654, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 657, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 660, 661, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 662, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 664, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 665, 666, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 675, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 678, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 681, +}; + +static const unsigned int comp_data[] = { + 0, 0, 0, 0, 0, 0, 0, 8814, 0, 0, 8800, 0, 0, 8815, 0, 0, 0, 192, 193, + 194, 195, 256, 258, 550, 196, 7842, 197, 0, 461, 512, 514, 0, 0, 0, 7840, + 0, 7680, 0, 0, 260, 0, 0, 7682, 0, 0, 7684, 0, 0, 0, 0, 7686, 0, 262, + 264, 0, 0, 0, 266, 0, 0, 0, 0, 268, 0, 199, 0, 0, 0, 7690, 0, 0, 0, 0, + 270, 0, 0, 0, 0, 0, 7692, 0, 0, 0, 7696, 0, 7698, 0, 0, 7694, 0, 0, 0, 0, + 200, 201, 202, 7868, 274, 276, 278, 203, 7866, 0, 0, 282, 516, 518, 0, 0, + 0, 7864, 0, 0, 0, 552, 280, 7704, 0, 7706, 0, 0, 0, 7710, 0, 500, 284, 0, + 7712, 286, 288, 0, 0, 0, 0, 486, 0, 290, 0, 0, 0, 292, 0, 0, 0, 7714, + 7718, 0, 0, 0, 542, 0, 0, 0, 0, 0, 7716, 0, 0, 0, 7720, 0, 0, 7722, 0, 0, + 204, 205, 206, 296, 298, 300, 304, 207, 7880, 0, 0, 463, 520, 522, 0, 0, + 0, 7882, 0, 0, 0, 0, 302, 0, 0, 7724, 0, 0, 0, 308, 0, 7728, 0, 0, 0, 0, + 0, 488, 0, 7730, 0, 0, 0, 310, 0, 0, 0, 0, 7732, 0, 0, 0, 0, 0, 313, 0, + 317, 0, 0, 0, 0, 0, 7734, 0, 0, 0, 315, 0, 7740, 0, 0, 7738, 0, 0, 0, 0, + 0, 7742, 0, 0, 0, 0, 7744, 0, 0, 7746, 0, 504, 323, 0, 209, 0, 0, 7748, + 0, 0, 0, 0, 327, 0, 7750, 0, 0, 0, 325, 0, 7754, 0, 0, 7752, 0, 0, 0, 0, + 210, 211, 212, 213, 332, 334, 558, 214, 7886, 0, 336, 465, 524, 526, 0, + 0, 416, 7884, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 7764, 7766, 0, 0, 0, 0, 0, + 340, 0, 0, 0, 0, 7768, 344, 528, 530, 0, 0, 0, 7770, 0, 0, 0, 342, 0, 0, + 0, 0, 7774, 0, 346, 348, 0, 0, 0, 7776, 0, 0, 0, 0, 352, 0, 7778, 0, 0, + 536, 350, 0, 0, 0, 7786, 0, 0, 0, 0, 356, 0, 7788, 0, 0, 538, 354, 0, + 7792, 0, 0, 7790, 0, 0, 0, 0, 217, 218, 219, 360, 362, 364, 0, 220, 7910, + 366, 368, 467, 532, 534, 0, 0, 431, 7908, 7794, 0, 0, 0, 370, 7798, 0, + 7796, 7804, 0, 0, 0, 0, 0, 7806, 0, 7808, 7810, 372, 0, 0, 0, 7814, 7812, + 0, 7816, 0, 0, 0, 7818, 7820, 0, 0, 0, 7922, 221, 374, 7928, 562, 0, + 7822, 376, 7926, 0, 0, 0, 0, 7924, 0, 0, 377, 7824, 0, 0, 0, 379, 381, 0, + 0, 0, 0, 0, 7826, 0, 0, 0, 0, 7828, 224, 225, 226, 227, 257, 259, 551, + 228, 7843, 229, 0, 462, 513, 515, 0, 0, 0, 7841, 0, 7681, 0, 0, 261, 0, + 0, 7683, 0, 0, 7685, 0, 0, 0, 0, 7687, 0, 0, 0, 0, 0, 263, 265, 0, 0, 0, + 267, 0, 0, 0, 0, 269, 0, 0, 0, 0, 0, 231, 0, 0, 0, 7691, 271, 0, 0, 0, 0, + 0, 7693, 0, 0, 0, 7697, 0, 7699, 0, 0, 7695, 232, 233, 234, 7869, 275, + 277, 279, 235, 7867, 0, 0, 283, 517, 519, 0, 0, 0, 7865, 0, 0, 0, 553, + 281, 7705, 0, 7707, 0, 0, 0, 7711, 0, 0, 0, 0, 0, 501, 285, 0, 7713, 287, + 289, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 291, 0, 0, 0, 293, 0, 0, 0, 7715, + 7719, 0, 0, 0, 543, 0, 0, 0, 0, 0, 7717, 0, 0, 0, 7721, 0, 0, 7723, 0, + 7830, 236, 237, 238, 297, 299, 301, 0, 239, 7881, 0, 0, 464, 521, 523, 0, + 0, 0, 7883, 0, 0, 0, 0, 303, 0, 0, 7725, 0, 0, 0, 309, 0, 0, 0, 0, 496, + 0, 0, 0, 0, 7729, 0, 489, 0, 0, 0, 0, 0, 7731, 0, 0, 0, 311, 7733, 0, 0, + 0, 0, 0, 314, 0, 318, 0, 0, 0, 0, 0, 7735, 0, 0, 0, 316, 0, 7741, 0, 0, + 7739, 0, 7743, 0, 0, 0, 0, 7745, 0, 0, 7747, 0, 0, 0, 0, 0, 505, 324, 0, + 241, 0, 0, 7749, 0, 0, 0, 0, 328, 0, 7751, 0, 0, 0, 326, 0, 7755, 0, 0, + 7753, 0, 0, 0, 0, 242, 243, 244, 245, 333, 335, 559, 246, 7887, 0, 337, + 466, 525, 527, 0, 0, 417, 7885, 491, 0, 0, 0, 0, 0, 7765, 0, 0, 0, 0, + 7767, 0, 341, 0, 0, 0, 0, 7769, 0, 0, 0, 0, 345, 529, 531, 0, 0, 0, 7771, + 0, 0, 0, 343, 0, 0, 0, 0, 7775, 0, 347, 349, 0, 0, 0, 7777, 0, 0, 0, 0, + 353, 0, 7779, 0, 0, 537, 351, 0, 0, 0, 7787, 7831, 0, 0, 0, 357, 0, 0, 0, + 0, 0, 7789, 0, 0, 539, 355, 0, 7793, 0, 0, 7791, 0, 0, 0, 0, 249, 250, + 251, 361, 363, 365, 0, 252, 7911, 367, 369, 468, 533, 535, 0, 0, 432, + 7909, 7795, 0, 0, 0, 371, 7799, 0, 7797, 0, 0, 0, 0, 7805, 0, 7807, 0, 0, + 0, 0, 0, 7809, 7811, 373, 0, 0, 0, 7815, 7813, 0, 7832, 0, 0, 0, 7817, 0, + 0, 0, 7819, 7821, 0, 0, 0, 7923, 253, 375, 7929, 563, 0, 7823, 255, 7927, + 7833, 0, 0, 0, 7925, 0, 0, 378, 7825, 0, 0, 0, 380, 0, 0, 0, 0, 382, 0, + 7827, 0, 0, 0, 0, 7829, 0, 0, 0, 0, 8173, 901, 0, 0, 0, 0, 0, 0, 8129, 0, + 0, 7846, 7844, 0, 7850, 0, 0, 0, 0, 7848, 0, 0, 478, 0, 0, 0, 506, 0, 0, + 508, 0, 0, 482, 0, 0, 0, 7688, 0, 7872, 7870, 0, 7876, 0, 0, 0, 0, 7874, + 0, 0, 0, 7726, 0, 0, 0, 0, 0, 7890, 7888, 0, 7894, 0, 0, 0, 0, 7892, 0, + 0, 0, 7756, 0, 0, 556, 0, 0, 7758, 0, 0, 0, 554, 0, 0, 0, 510, 0, 0, 0, + 0, 0, 475, 471, 0, 0, 469, 0, 0, 473, 0, 0, 0, 7847, 7845, 0, 7851, 0, 0, + 0, 0, 7849, 0, 0, 479, 0, 0, 0, 507, 0, 0, 509, 0, 0, 483, 0, 0, 0, 7689, + 0, 7873, 7871, 0, 7877, 0, 0, 0, 0, 7875, 0, 0, 0, 7727, 0, 0, 0, 0, 0, + 7891, 7889, 0, 7895, 0, 0, 0, 0, 7893, 0, 0, 0, 7757, 0, 0, 557, 0, 0, + 7759, 0, 0, 0, 555, 0, 0, 0, 511, 0, 0, 0, 0, 0, 476, 472, 0, 0, 470, 0, + 0, 474, 0, 0, 0, 7856, 7854, 0, 7860, 0, 0, 0, 0, 7858, 0, 0, 7857, 7855, + 0, 7861, 0, 0, 0, 0, 7859, 0, 0, 7700, 7702, 0, 0, 0, 0, 0, 7701, 7703, + 0, 0, 0, 0, 0, 7760, 7762, 0, 7761, 7763, 0, 0, 0, 7780, 0, 0, 7781, 0, + 0, 7782, 0, 0, 0, 0, 0, 0, 7783, 0, 7800, 0, 0, 7801, 0, 0, 0, 0, 7802, + 0, 0, 7803, 0, 0, 0, 0, 0, 7835, 0, 0, 0, 0, 7900, 7898, 0, 7904, 0, 0, + 0, 0, 7902, 7906, 0, 0, 0, 0, 0, 7901, 7899, 0, 7905, 0, 0, 0, 0, 7903, + 0, 0, 0, 0, 7907, 0, 7914, 7912, 0, 7918, 0, 0, 0, 0, 7916, 0, 0, 0, 0, + 7920, 0, 7915, 7913, 0, 7919, 7917, 0, 0, 0, 0, 7921, 0, 0, 0, 0, 494, 0, + 0, 0, 492, 0, 0, 493, 0, 0, 480, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 7708, 0, + 0, 7709, 0, 560, 0, 0, 0, 0, 0, 0, 561, 0, 495, 0, 0, 0, 8122, 902, 0, 0, + 8121, 8120, 0, 0, 0, 0, 7944, 7945, 0, 0, 0, 0, 0, 8124, 0, 8136, 904, 0, + 0, 0, 0, 7960, 7961, 0, 0, 0, 8138, 905, 0, 0, 0, 0, 7976, 7977, 0, 8140, + 0, 0, 0, 0, 0, 8154, 906, 0, 0, 8153, 8152, 0, 938, 0, 0, 7992, 7993, 0, + 0, 0, 8184, 908, 0, 0, 0, 0, 8008, 8009, 0, 0, 0, 0, 0, 0, 8172, 0, 0, 0, + 8170, 910, 0, 0, 8169, 8168, 0, 939, 0, 0, 0, 8025, 0, 0, 0, 8186, 911, + 8040, 8041, 0, 0, 0, 0, 0, 8188, 0, 0, 8116, 0, 0, 8132, 0, 0, 0, 0, 0, + 8048, 940, 0, 0, 8113, 8112, 0, 0, 0, 0, 7936, 7937, 0, 0, 0, 0, 8118, + 8115, 0, 0, 0, 0, 0, 8050, 941, 7952, 7953, 0, 0, 0, 8052, 942, 0, 0, 0, + 0, 7968, 7969, 0, 0, 0, 0, 8134, 8131, 0, 8054, 943, 0, 0, 8145, 8144, 0, + 970, 0, 0, 7984, 7985, 8150, 0, 0, 0, 0, 0, 0, 8056, 972, 0, 0, 0, 0, + 8000, 8001, 0, 8164, 8165, 0, 0, 0, 8058, 973, 0, 0, 8161, 8160, 0, 971, + 0, 0, 0, 0, 0, 0, 8016, 8017, 0, 0, 0, 0, 8166, 0, 0, 8060, 974, 0, 0, 0, + 0, 8032, 8033, 8182, 8179, 0, 0, 0, 0, 0, 8146, 912, 0, 0, 0, 0, 0, 0, + 8151, 0, 0, 8162, 944, 0, 0, 8167, 0, 0, 0, 8180, 0, 0, 979, 0, 0, 0, 0, + 0, 980, 0, 0, 1031, 0, 0, 0, 0, 1232, 0, 1234, 0, 0, 0, 0, 1027, 0, 1024, + 0, 0, 0, 0, 1238, 0, 1025, 1217, 0, 1244, 0, 0, 1246, 0, 0, 0, 1037, 0, + 0, 0, 1250, 1049, 0, 1252, 0, 0, 0, 0, 1036, 0, 0, 0, 0, 1254, 0, 0, 0, + 1262, 1038, 0, 1264, 0, 0, 1266, 0, 0, 0, 1268, 0, 0, 0, 0, 0, 0, 1272, + 0, 0, 1260, 0, 0, 0, 0, 1233, 0, 1235, 0, 0, 0, 0, 1107, 0, 1104, 0, 0, + 0, 0, 1239, 0, 1105, 1218, 0, 1245, 0, 0, 1247, 0, 0, 0, 1117, 0, 0, 0, + 1251, 1081, 0, 1253, 0, 0, 0, 0, 1116, 0, 0, 0, 0, 1255, 0, 0, 0, 1263, + 1118, 0, 1265, 0, 0, 1267, 0, 0, 0, 1269, 0, 0, 0, 0, 0, 0, 1273, 0, 0, + 1261, 0, 0, 1111, 0, 0, 0, 1142, 0, 0, 1143, 0, 0, 0, 0, 0, 1242, 0, 0, + 1243, 0, 0, 1258, 0, 0, 0, 0, 0, 0, 1259, 0, 1570, 1571, 1573, 0, 1572, + 0, 0, 1574, 0, 0, 0, 0, 0, 0, 1730, 0, 0, 1747, 0, 0, 1728, 0, 0, 0, 0, + 2345, 0, 0, 2353, 0, 0, 2356, 0, 0, 0, 2507, 2508, 0, 0, 0, 2891, 2888, + 2892, 2964, 0, 0, 0, 0, 0, 3018, 3020, 0, 3019, 0, 0, 0, 0, 3144, 0, 0, + 0, 0, 3264, 0, 3274, 3271, 3272, 0, 3275, 0, 0, 0, 0, 3402, 3404, 0, + 3403, 0, 0, 0, 0, 3546, 3548, 3550, 0, 0, 0, 0, 3549, 0, 0, 0, 0, 0, + 4134, 0, 0, 0, 6918, 0, 0, 6920, 0, 0, 6922, 0, 0, 6924, 0, 0, 0, 0, 0, + 0, 6926, 0, 0, 6930, 0, 0, 6971, 0, 0, 6973, 0, 0, 0, 0, 0, 0, 6976, 0, + 0, 6977, 0, 0, 6979, 0, 0, 0, 7736, 0, 0, 7737, 0, 0, 0, 0, 0, 0, 7772, + 0, 0, 7773, 0, 0, 0, 0, 7784, 0, 0, 7785, 0, 0, 7852, 0, 0, 7862, 0, 0, + 0, 7853, 0, 0, 7863, 0, 0, 0, 7878, 0, 0, 7879, 0, 0, 7896, 0, 0, 7897, + 0, 0, 0, 0, 7938, 7940, 0, 0, 7942, 8064, 0, 7939, 7941, 0, 0, 7943, + 8065, 0, 0, 8066, 0, 0, 0, 0, 0, 0, 8067, 0, 0, 8068, 0, 0, 8069, 0, 0, + 8070, 0, 0, 0, 0, 0, 0, 8071, 0, 7946, 7948, 0, 0, 7950, 8072, 0, 7947, + 7949, 0, 0, 7951, 8073, 0, 0, 8074, 0, 0, 0, 0, 0, 0, 8075, 0, 0, 8076, + 0, 0, 8077, 0, 0, 8078, 0, 0, 0, 0, 0, 0, 8079, 0, 7954, 7956, 0, 7955, + 7957, 0, 0, 0, 0, 0, 7962, 7964, 0, 0, 0, 0, 0, 7963, 7965, 0, 7970, + 7972, 0, 0, 7974, 8080, 0, 7971, 7973, 0, 0, 7975, 8081, 0, 0, 8082, 0, + 0, 0, 0, 0, 0, 8083, 0, 0, 8084, 0, 0, 8085, 0, 0, 8086, 0, 0, 0, 0, 0, + 0, 8087, 0, 7978, 7980, 0, 0, 7982, 8088, 0, 7979, 7981, 0, 0, 7983, + 8089, 0, 0, 8090, 0, 0, 0, 0, 0, 0, 8091, 0, 0, 8092, 0, 0, 8093, 0, 0, + 8094, 0, 0, 0, 0, 0, 0, 8095, 0, 7986, 7988, 0, 0, 7990, 0, 0, 7987, + 7989, 0, 0, 7991, 0, 0, 0, 0, 0, 0, 7994, 7996, 0, 0, 0, 0, 0, 0, 7998, + 0, 0, 7995, 7997, 0, 0, 7999, 0, 0, 8002, 8004, 0, 8003, 8005, 0, 0, 0, + 0, 0, 8010, 8012, 0, 0, 0, 0, 0, 8011, 8013, 0, 8018, 8020, 0, 0, 8022, + 0, 0, 8019, 8021, 0, 0, 8023, 0, 0, 0, 0, 0, 0, 8027, 8029, 0, 0, 0, 0, + 0, 0, 8031, 0, 0, 8034, 8036, 0, 0, 8038, 8096, 0, 8035, 8037, 0, 0, + 8039, 8097, 0, 0, 8098, 0, 0, 8099, 0, 0, 0, 0, 0, 0, 8100, 0, 0, 8101, + 0, 0, 8102, 0, 0, 8103, 0, 0, 0, 0, 0, 8042, 8044, 0, 0, 8046, 8104, 0, + 8043, 8045, 0, 0, 8047, 8105, 0, 0, 8106, 0, 0, 8107, 0, 0, 0, 0, 0, 0, + 8108, 0, 0, 8109, 0, 0, 8110, 0, 0, 8111, 0, 0, 0, 0, 0, 0, 8114, 0, 0, + 8130, 0, 0, 8178, 0, 0, 8119, 0, 0, 0, 0, 0, 8141, 8142, 0, 0, 8143, 0, + 0, 0, 8135, 0, 0, 8183, 0, 0, 0, 0, 0, 8157, 8158, 0, 0, 0, 0, 0, 0, + 8159, 0, 8602, 0, 0, 8603, 0, 0, 0, 0, 0, 0, 8622, 0, 0, 8653, 0, 0, + 8655, 0, 0, 8654, 0, 0, 0, 0, 0, 0, 8708, 0, 0, 8713, 0, 0, 8716, 0, 0, + 8740, 0, 0, 0, 0, 0, 0, 8742, 0, 0, 8769, 0, 0, 8772, 0, 0, 8775, 0, 0, + 0, 0, 0, 0, 8777, 0, 0, 8813, 0, 0, 8802, 0, 0, 8816, 0, 0, 0, 0, 0, 0, + 8817, 0, 0, 8820, 0, 0, 8821, 0, 0, 8824, 0, 0, 0, 0, 0, 0, 8825, 0, 0, + 8832, 0, 0, 8833, 0, 0, 8928, 0, 0, 0, 0, 0, 0, 8929, 0, 0, 8836, 0, 0, + 8837, 0, 0, 8840, 0, 0, 0, 0, 0, 0, 8841, 0, 0, 8930, 0, 0, 8931, 0, 0, + 8876, 0, 0, 0, 0, 0, 0, 8877, 0, 0, 8878, 0, 0, 8879, 0, 0, 8938, 0, 0, + 0, 0, 0, 0, 8939, 0, 0, 8940, 0, 0, 8941, 0, 0, 0, 12436, 0, 0, 12364, 0, + 0, 0, 0, 0, 0, 12366, 0, 0, 12368, 0, 0, 12370, 0, 0, 12372, 0, 0, 0, 0, + 0, 0, 12374, 0, 0, 12376, 0, 0, 12378, 0, 0, 12380, 0, 0, 0, 0, 0, 0, + 12382, 0, 0, 12384, 0, 0, 12386, 0, 0, 12389, 0, 0, 0, 0, 0, 0, 12391, 0, + 0, 12393, 0, 0, 12400, 12401, 0, 12403, 12404, 0, 0, 0, 0, 0, 12406, + 12407, 0, 0, 0, 0, 0, 12409, 12410, 0, 12412, 12413, 0, 12446, 0, 0, 0, + 0, 0, 0, 12532, 0, 0, 12460, 0, 0, 12462, 0, 0, 12464, 0, 0, 0, 0, 0, 0, + 12466, 0, 0, 12468, 0, 0, 12470, 0, 0, 12472, 0, 0, 0, 0, 0, 0, 12474, 0, + 0, 12476, 0, 0, 12478, 0, 0, 12480, 0, 0, 0, 0, 0, 0, 12482, 0, 0, 12485, + 0, 0, 12487, 0, 0, 12489, 0, 0, 0, 0, 0, 0, 12496, 12497, 0, 0, 0, 0, 0, + 12499, 12500, 0, 12502, 12503, 0, 12505, 12506, 0, 0, 0, 0, 0, 12508, + 12509, 0, 0, 0, 0, 0, 12535, 0, 0, 12536, 0, 0, 12537, 0, 0, 0, 0, 0, 0, + 12538, 0, 0, 12542, 0, 0, 0, 0, 69786, 0, 0, 69788, 0, 0, 69803, 0, 0, 0, + 69934, 0, 0, 69935, 0, 0, 0, 70475, 70476, 0, 0, 0, 70844, 70843, 70846, + 0, 0, 0, 71098, 0, 0, 71099, 0, 0, 0, 71992, +}; + +static const change_record change_records_3_2_0[] = { + { 255, 255, 255, 255, 255, 0 }, + { 11, 255, 255, 255, 255, 0 }, + { 10, 255, 255, 255, 255, 0 }, + { 255, 30, 255, 255, 255, 0 }, + { 255, 2, 255, 255, 255, 0 }, + { 19, 21, 255, 255, 255, 0 }, + { 255, 255, 2, 255, 255, 0 }, + { 255, 255, 3, 255, 255, 0 }, + { 255, 255, 1, 255, 255, 0 }, + { 255, 0, 255, 255, 255, 0 }, + { 255, 29, 255, 255, 255, 0 }, + { 255, 26, 255, 255, 255, 0 }, + { 5, 255, 255, 255, 255, 0 }, + { 14, 6, 255, 255, 255, 0 }, + { 15, 255, 255, 255, 255, 0 }, + { 255, 255, 255, 255, 255, 1.0 }, + { 255, 255, 255, 255, 255, 2.0 }, + { 255, 255, 255, 255, 255, 3.0 }, + { 255, 255, 255, 255, 255, 4.0 }, + { 255, 255, 255, 255, 255, -1 }, + { 14, 255, 255, 255, 255, 0 }, + { 255, 255, 255, 0, 255, 0 }, + { 255, 19, 255, 255, 255, 0 }, + { 255, 7, 1, 255, 255, 0 }, + { 255, 7, 2, 255, 255, 0 }, + { 255, 7, 3, 255, 255, 0 }, + { 255, 7, 4, 255, 255, 0 }, + { 255, 7, 5, 255, 255, 0 }, + { 255, 7, 6, 255, 255, 0 }, + { 255, 7, 7, 255, 255, 0 }, + { 255, 7, 8, 255, 255, 0 }, + { 255, 7, 9, 255, 255, 0 }, + { 1, 5, 255, 255, 255, 0 }, + { 1, 19, 255, 255, 255, 0 }, + { 255, 10, 255, 255, 255, 0 }, + { 18, 255, 255, 255, 255, 0 }, + { 19, 255, 255, 255, 255, 0 }, + { 255, 255, 0, 255, 255, 0 }, + { 255, 255, 4, 255, 255, 0 }, + { 255, 255, 5, 255, 255, 0 }, + { 255, 255, 6, 255, 255, 0 }, + { 255, 255, 7, 255, 255, 0 }, + { 255, 255, 8, 255, 255, 0 }, + { 255, 255, 9, 255, 255, 0 }, + { 19, 30, 255, 255, 255, 0 }, + { 255, 8, 255, 255, 255, 0 }, + { 255, 27, 255, 255, 255, 0 }, + { 255, 255, 255, 255, 5, 0 }, + { 255, 22, 255, 255, 255, 0 }, + { 255, 23, 255, 255, 255, 0 }, + { 9, 255, 255, 255, 255, 0 }, + { 255, 255, 255, 1, 255, 0 }, + { 14, 4, 255, 255, 255, 0 }, + { 255, 20, 255, 255, 255, 0 }, + { 255, 255, 255, 255, 255, 1e+16 }, + { 255, 255, 255, 255, 255, 1e+20 }, + { 255, 19, 255, 255, 255, -1 }, + { 1, 255, 255, 0, 255, 0 }, +}; +static const unsigned char changes_3_2_0_index[] = { + 0, 1, 2, 2, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 2, 2, 2, 38, 39, 2, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 2, 53, 2, 2, 54, 55, 56, 57, 58, 2, 59, 60, 61, 62, 2, 63, 64, + 65, 66, 67, 68, 68, 2, 69, 2, 2, 70, 71, 72, 73, 74, 75, 76, 2, 2, 2, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 2, 2, 2, 2, 2, 2, 87, 2, 2, 2, 2, 2, + 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 89, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, + 91, 92, 2, 2, 2, 2, 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, + 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 100, 2, 2, 2, 2, 2, 2, 2, 2, 101, 51, + 51, 102, 103, 51, 104, 105, 106, 107, 108, 109, 110, 111, 112, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 114, 115, 116, 117, 118, 119, 2, 2, 120, 121, 122, + 2, 123, 124, 125, 126, 127, 128, 2, 129, 130, 131, 132, 133, 134, 2, 51, + 51, 135, 2, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 2, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 2, 158, 159, 2, + 160, 161, 162, 163, 2, 164, 165, 166, 167, 168, 169, 2, 2, 170, 171, 172, + 173, 2, 174, 2, 175, 51, 51, 51, 51, 51, 51, 51, 176, 177, 51, 178, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 51, 51, 51, + 51, 51, 51, 51, 179, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 51, 51, 51, 180, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 51, 51, 51, 181, 182, + 183, 184, 2, 2, 2, 2, 185, 186, 187, 188, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 103, 51, 51, 51, 51, 51, 51, 51, 51, 51, 189, 190, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 51, 191, 51, + 51, 192, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 193, 194, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 195, 196, 197, 198, 199, + 2, 2, 200, 2, 2, 2, 201, 202, 203, 51, 51, 51, 51, 51, 204, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 205, 2, 206, 2, 2, 207, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 51, 208, 209, 2, 2, 2, 2, 2, 210, 211, 212, 2, 213, 214, 2, 2, 215, 216, + 51, 217, 218, 2, 51, 51, 51, 51, 51, 51, 51, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 51, 228, 2, 2, 2, 2, 2, 2, 2, 2, 229, 230, 98, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 87, 231, 2, 232, 233, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 234, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 235, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 236, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 237, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 238, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 239, 51, 240, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 241, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 242, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 234, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 243, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 244, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +}; + +static const unsigned char changes_3_2_0_data[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 6, 7, 0, 0, 3, 0, 0, 8, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 10, 0, 9, 9, 0, 0, 0, 9, 9, + 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 9, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 17, 18, 19, 0, 0, 9, + 9, 9, 9, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 20, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 9, 9, 0, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 9, 0, + 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 33, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 9, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, - 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 37, 4, 0, 0, 38, 39, + 40, 41, 42, 43, 1, 1, 0, 0, 0, 4, 37, 8, 6, 7, 38, 39, 40, 41, 42, 43, 1, + 1, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 52, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, + 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 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, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 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, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 0, 0, 0, 1, 1, 21, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 14, 14, 14, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, + 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 9, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, + 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, @@ -7274,22 +7274,22 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 0, 0, 9, 9, 0, 0, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, @@ -7298,7 +7298,7 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7306,142 +7306,142 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7454,70 +7454,70 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, @@ -7527,45 +7527,45 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7578,57 +7578,57 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7653,113 +7653,113 @@ static const unsigned char changes_3_2_0_data[] = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const change_record* get_change_3_2_0(Py_UCS4 n) -{ - int index; - if (n >= 0x110000) index = 0; - else { - index = changes_3_2_0_index[n>>7]; - index = changes_3_2_0_data[(index<<7)+(n & 127)]; - } - return change_records_3_2_0+index; -} - -static Py_UCS4 normalization_3_2_0(Py_UCS4 n) -{ - switch(n) { - case 0x2f868: return 0x2136A; - case 0x2f874: return 0x5F33; - case 0x2f91f: return 0x43AB; - case 0x2f95f: return 0x7AAE; - case 0x2f9bf: return 0x4D57; - default: return 0; - } -} - + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const change_record* get_change_3_2_0(Py_UCS4 n) +{ + int index; + if (n >= 0x110000) index = 0; + else { + index = changes_3_2_0_index[n>>7]; + index = changes_3_2_0_data[(index<<7)+(n & 127)]; + } + return change_records_3_2_0+index; +} + +static Py_UCS4 normalization_3_2_0(Py_UCS4 n) +{ + switch(n) { + case 0x2f868: return 0x2136A; + case 0x2f874: return 0x5F33; + case 0x2f91f: return 0x43AB; + case 0x2f95f: return 0x7AAE; + case 0x2f9bf: return 0x4D57; + default: return 0; + } +} + diff --git a/contrib/tools/python3/src/Modules/unicodename_db.h b/contrib/tools/python3/src/Modules/unicodename_db.h index 793d5109ee8..a45c5ca5df3 100644 --- a/contrib/tools/python3/src/Modules/unicodename_db.h +++ b/contrib/tools/python3/src/Modules/unicodename_db.h @@ -1,18 +1,18 @@ /* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ - -#define NAME_MAXLEN 256 - -/* lexicon */ + +#define NAME_MAXLEN 256 + +/* lexicon */ static const unsigned char lexicon[] = { 76, 69, 84, 84, 69, 210, 83, 77, 65, 76, 204, 83, 73, 71, 206, 87, 73, 84, 200, 83, 89, 76, 76, 65, 66, 76, 197, 67, 65, 80, 73, 84, 65, 204, - 72, 73, 69, 82, 79, 71, 76, 89, 80, 200, 76, 65, 84, 73, 206, 65, 82, 65, - 66, 73, 195, 67, 85, 78, 69, 73, 70, 79, 82, 205, 89, 201, 67, 74, 203, - 77, 65, 84, 72, 69, 77, 65, 84, 73, 67, 65, 204, 69, 71, 89, 80, 84, 73, - 65, 206, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84, 217, 83, 89, 77, - 66, 79, 204, 68, 73, 71, 73, 212, 86, 79, 87, 69, 204, 84, 65, 78, 71, - 85, 212, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68, 73, 65, 206, 83, 89, - 76, 76, 65, 66, 73, 67, 211, 83, 73, 71, 78, 87, 82, 73, 84, 73, 78, 199, + 72, 73, 69, 82, 79, 71, 76, 89, 80, 200, 76, 65, 84, 73, 206, 65, 82, 65, + 66, 73, 195, 67, 85, 78, 69, 73, 70, 79, 82, 205, 89, 201, 67, 74, 203, + 77, 65, 84, 72, 69, 77, 65, 84, 73, 67, 65, 204, 69, 71, 89, 80, 84, 73, + 65, 206, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84, 217, 83, 89, 77, + 66, 79, 204, 68, 73, 71, 73, 212, 86, 79, 87, 69, 204, 84, 65, 78, 71, + 85, 212, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68, 73, 65, 206, 83, 89, + 76, 76, 65, 66, 73, 67, 211, 83, 73, 71, 78, 87, 82, 73, 84, 73, 78, 199, 84, 73, 77, 69, 211, 66, 65, 77, 85, 205, 65, 78, 196, 83, 67, 82, 73, 80, 212, 66, 79, 76, 196, 65, 78, 65, 84, 79, 76, 73, 65, 206, 72, 65, 78, 71, 85, 204, 78, 85, 77, 66, 69, 210, 76, 73, 78, 69, 65, 210, 71, @@ -580,8 +580,8 @@ static const unsigned char lexicon[] = { 82, 73, 68, 79, 128, 84, 86, 73, 77, 65, 68, 85, 210, 84, 85, 88, 69, 68, 79, 128, 84, 85, 88, 128, 84, 85, 85, 77, 85, 128, 84, 85, 85, 128, 84, 85, 84, 84, 89, 128, 84, 85, 84, 69, 89, 65, 83, 65, 84, 128, 84, 85, 84, - 128, 84, 85, 82, 88, 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, 69, - 128, 84, 85, 82, 79, 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 128, + 128, 84, 85, 82, 88, 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, 69, + 128, 84, 85, 82, 79, 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 128, 84, 85, 82, 206, 84, 85, 82, 75, 73, 83, 200, 84, 85, 82, 75, 73, 195, 84, 85, 82, 75, 69, 89, 128, 84, 85, 82, 66, 65, 78, 128, 84, 85, 82, 128, 84, 85, 210, 84, 85, 80, 78, 73, 128, 84, 85, 80, 128, 84, 85, 79, @@ -966,50 +966,50 @@ static const unsigned char lexicon[] = { 84, 65, 78, 68, 73, 78, 199, 83, 84, 65, 78, 68, 65, 82, 196, 83, 84, 65, 78, 68, 128, 83, 84, 65, 78, 128, 83, 84, 65, 77, 80, 69, 196, 83, 84, 65, 76, 76, 73, 79, 78, 128, 83, 84, 65, 70, 70, 128, 83, 84, 65, 70, - 198, 83, 84, 65, 68, 73, 85, 77, 128, 83, 84, 65, 67, 75, 69, 196, 83, - 84, 65, 67, 67, 65, 84, 79, 128, 83, 84, 65, 67, 67, 65, 84, 73, 83, 83, - 73, 77, 79, 128, 83, 84, 50, 128, 83, 83, 89, 88, 128, 83, 83, 89, 84, - 128, 83, 83, 89, 82, 88, 128, 83, 83, 89, 82, 128, 83, 83, 89, 80, 128, - 83, 83, 89, 128, 83, 83, 85, 88, 128, 83, 83, 85, 85, 128, 83, 83, 85, - 84, 128, 83, 83, 85, 80, 128, 83, 83, 79, 88, 128, 83, 83, 79, 84, 128, - 83, 83, 79, 80, 128, 83, 83, 79, 79, 128, 83, 83, 79, 128, 83, 83, 73, - 88, 128, 83, 83, 73, 84, 128, 83, 83, 73, 80, 128, 83, 83, 73, 73, 128, - 83, 83, 73, 69, 88, 128, 83, 83, 73, 69, 80, 128, 83, 83, 73, 69, 128, - 83, 83, 72, 73, 78, 128, 83, 83, 72, 69, 128, 83, 83, 69, 88, 128, 83, - 83, 69, 80, 128, 83, 83, 69, 69, 128, 83, 83, 65, 88, 128, 83, 83, 65, - 85, 128, 83, 83, 65, 84, 128, 83, 83, 65, 80, 128, 83, 83, 65, 78, 71, - 89, 69, 83, 73, 69, 85, 78, 71, 128, 83, 83, 65, 78, 71, 89, 69, 79, 82, - 73, 78, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, - 84, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, - 84, 128, 83, 83, 65, 78, 71, 84, 72, 73, 69, 85, 84, 72, 128, 83, 83, 65, - 78, 71, 83, 73, 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, - 71, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 83, - 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 83, 83, 65, 78, 71, 83, 73, - 79, 83, 128, 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, - 85, 75, 72, 128, 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 128, 83, 83, 65, - 78, 71, 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, - 128, 83, 83, 65, 78, 71, 77, 73, 69, 85, 77, 128, 83, 83, 65, 78, 71, 73, - 69, 85, 78, 71, 128, 83, 83, 65, 78, 71, 72, 73, 69, 85, 72, 128, 83, 83, - 65, 78, 71, 67, 73, 69, 85, 67, 45, 72, 73, 69, 85, 72, 128, 83, 83, 65, - 78, 71, 67, 73, 69, 85, 67, 128, 83, 83, 65, 78, 71, 65, 82, 65, 69, 65, - 128, 83, 83, 65, 73, 128, 83, 83, 65, 65, 128, 83, 83, 51, 128, 83, 83, - 50, 128, 83, 82, 128, 83, 81, 85, 73, 83, 200, 83, 81, 85, 73, 82, 82, - 69, 204, 83, 81, 85, 73, 71, 71, 76, 197, 83, 81, 85, 73, 68, 128, 83, - 81, 85, 69, 69, 90, 69, 68, 128, 83, 81, 85, 69, 69, 90, 197, 83, 81, 85, - 65, 212, 83, 81, 85, 65, 82, 69, 83, 128, 83, 81, 85, 65, 82, 69, 68, - 128, 83, 81, 85, 65, 82, 69, 128, 83, 80, 89, 128, 83, 80, 87, 65, 128, - 83, 80, 85, 78, 71, 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, - 71, 83, 128, 83, 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, - 83, 65, 78, 199, 83, 80, 82, 69, 65, 68, 128, 83, 80, 82, 69, 65, 196, - 83, 80, 79, 85, 84, 73, 78, 199, 83, 80, 79, 84, 128, 83, 80, 79, 82, 84, - 211, 83, 80, 79, 79, 78, 128, 83, 80, 79, 79, 204, 83, 80, 79, 78, 71, - 69, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, 76, 73, 84, 128, - 83, 80, 76, 73, 212, 83, 80, 76, 65, 89, 69, 68, 128, 83, 80, 76, 65, 83, - 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, 80, 73, 82, 73, 84, - 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, 84, 128, 83, 80, - 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, 73, 78, 69, 128, - 83, 80, 73, 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, 128, 83, 80, 73, 68, - 69, 210, 83, 80, 73, 67, 69, 128, 83, 80, 72, 69, 82, 73, 67, 65, 204, + 198, 83, 84, 65, 68, 73, 85, 77, 128, 83, 84, 65, 67, 75, 69, 196, 83, + 84, 65, 67, 67, 65, 84, 79, 128, 83, 84, 65, 67, 67, 65, 84, 73, 83, 83, + 73, 77, 79, 128, 83, 84, 50, 128, 83, 83, 89, 88, 128, 83, 83, 89, 84, + 128, 83, 83, 89, 82, 88, 128, 83, 83, 89, 82, 128, 83, 83, 89, 80, 128, + 83, 83, 89, 128, 83, 83, 85, 88, 128, 83, 83, 85, 85, 128, 83, 83, 85, + 84, 128, 83, 83, 85, 80, 128, 83, 83, 79, 88, 128, 83, 83, 79, 84, 128, + 83, 83, 79, 80, 128, 83, 83, 79, 79, 128, 83, 83, 79, 128, 83, 83, 73, + 88, 128, 83, 83, 73, 84, 128, 83, 83, 73, 80, 128, 83, 83, 73, 73, 128, + 83, 83, 73, 69, 88, 128, 83, 83, 73, 69, 80, 128, 83, 83, 73, 69, 128, + 83, 83, 72, 73, 78, 128, 83, 83, 72, 69, 128, 83, 83, 69, 88, 128, 83, + 83, 69, 80, 128, 83, 83, 69, 69, 128, 83, 83, 65, 88, 128, 83, 83, 65, + 85, 128, 83, 83, 65, 84, 128, 83, 83, 65, 80, 128, 83, 83, 65, 78, 71, + 89, 69, 83, 73, 69, 85, 78, 71, 128, 83, 83, 65, 78, 71, 89, 69, 79, 82, + 73, 78, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, + 84, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, + 84, 128, 83, 83, 65, 78, 71, 84, 72, 73, 69, 85, 84, 72, 128, 83, 83, 65, + 78, 71, 83, 73, 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, + 71, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 83, + 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 83, 83, 65, 78, 71, 83, 73, + 79, 83, 128, 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, + 85, 75, 72, 128, 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 128, 83, 83, 65, + 78, 71, 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, + 128, 83, 83, 65, 78, 71, 77, 73, 69, 85, 77, 128, 83, 83, 65, 78, 71, 73, + 69, 85, 78, 71, 128, 83, 83, 65, 78, 71, 72, 73, 69, 85, 72, 128, 83, 83, + 65, 78, 71, 67, 73, 69, 85, 67, 45, 72, 73, 69, 85, 72, 128, 83, 83, 65, + 78, 71, 67, 73, 69, 85, 67, 128, 83, 83, 65, 78, 71, 65, 82, 65, 69, 65, + 128, 83, 83, 65, 73, 128, 83, 83, 65, 65, 128, 83, 83, 51, 128, 83, 83, + 50, 128, 83, 82, 128, 83, 81, 85, 73, 83, 200, 83, 81, 85, 73, 82, 82, + 69, 204, 83, 81, 85, 73, 71, 71, 76, 197, 83, 81, 85, 73, 68, 128, 83, + 81, 85, 69, 69, 90, 69, 68, 128, 83, 81, 85, 69, 69, 90, 197, 83, 81, 85, + 65, 212, 83, 81, 85, 65, 82, 69, 83, 128, 83, 81, 85, 65, 82, 69, 68, + 128, 83, 81, 85, 65, 82, 69, 128, 83, 80, 89, 128, 83, 80, 87, 65, 128, + 83, 80, 85, 78, 71, 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, + 71, 83, 128, 83, 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, + 83, 65, 78, 199, 83, 80, 82, 69, 65, 68, 128, 83, 80, 82, 69, 65, 196, + 83, 80, 79, 85, 84, 73, 78, 199, 83, 80, 79, 84, 128, 83, 80, 79, 82, 84, + 211, 83, 80, 79, 79, 78, 128, 83, 80, 79, 79, 204, 83, 80, 79, 78, 71, + 69, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, 76, 73, 84, 128, + 83, 80, 76, 73, 212, 83, 80, 76, 65, 89, 69, 68, 128, 83, 80, 76, 65, 83, + 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, 80, 73, 82, 73, 84, + 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, 84, 128, 83, 80, + 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, 73, 78, 69, 128, + 83, 80, 73, 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, 128, 83, 80, 73, 68, + 69, 210, 83, 80, 73, 67, 69, 128, 83, 80, 72, 69, 82, 73, 67, 65, 204, 83, 80, 69, 83, 77, 73, 76, 207, 83, 80, 69, 78, 212, 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, 83, 80, 69, 69, 67, 72, 128, 83, 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, 65, 76, 128, 83, 80, 69, 65, 82, 128, 83, 80, @@ -4123,17 +4123,17 @@ static const unsigned char lexicon[] = { 82, 73, 195, 71, 69, 78, 84, 76, 197, 71, 69, 78, 73, 84, 73, 86, 69, 128, 71, 69, 78, 73, 75, 201, 71, 69, 78, 73, 69, 128, 71, 69, 78, 69, 82, 73, 195, 71, 69, 78, 69, 82, 65, 76, 128, 71, 69, 77, 73, 78, 73, - 128, 71, 69, 77, 73, 78, 65, 84, 73, 79, 206, 71, 69, 77, 73, 78, 65, 84, - 197, 71, 69, 205, 71, 69, 69, 77, 128, 71, 69, 68, 79, 76, 65, 128, 71, - 69, 68, 69, 128, 71, 69, 66, 207, 71, 69, 66, 193, 71, 69, 65, 82, 128, - 71, 69, 65, 210, 71, 69, 50, 50, 128, 71, 68, 65, 78, 128, 71, 67, 73, - 71, 128, 71, 67, 65, 206, 71, 66, 79, 78, 128, 71, 66, 73, 69, 197, 71, - 66, 69, 85, 88, 128, 71, 66, 69, 84, 128, 71, 66, 65, 89, 73, 128, 71, - 66, 65, 75, 85, 82, 85, 78, 69, 78, 128, 71, 66, 128, 71, 65, 89, 65, 78, - 85, 75, 73, 84, 84, 65, 128, 71, 65, 89, 65, 78, 78, 65, 128, 71, 65, 89, - 128, 71, 65, 85, 78, 84, 76, 69, 84, 128, 71, 65, 84, 72, 69, 82, 73, 78, - 71, 128, 71, 65, 84, 72, 69, 82, 73, 78, 199, 71, 65, 84, 69, 128, 71, - 65, 83, 72, 65, 78, 128, 71, 65, 82, 83, 72, 85, 78, 73, 128, 71, 65, 82, + 128, 71, 69, 77, 73, 78, 65, 84, 73, 79, 206, 71, 69, 77, 73, 78, 65, 84, + 197, 71, 69, 205, 71, 69, 69, 77, 128, 71, 69, 68, 79, 76, 65, 128, 71, + 69, 68, 69, 128, 71, 69, 66, 207, 71, 69, 66, 193, 71, 69, 65, 82, 128, + 71, 69, 65, 210, 71, 69, 50, 50, 128, 71, 68, 65, 78, 128, 71, 67, 73, + 71, 128, 71, 67, 65, 206, 71, 66, 79, 78, 128, 71, 66, 73, 69, 197, 71, + 66, 69, 85, 88, 128, 71, 66, 69, 84, 128, 71, 66, 65, 89, 73, 128, 71, + 66, 65, 75, 85, 82, 85, 78, 69, 78, 128, 71, 66, 128, 71, 65, 89, 65, 78, + 85, 75, 73, 84, 84, 65, 128, 71, 65, 89, 65, 78, 78, 65, 128, 71, 65, 89, + 128, 71, 65, 85, 78, 84, 76, 69, 84, 128, 71, 65, 84, 72, 69, 82, 73, 78, + 71, 128, 71, 65, 84, 72, 69, 82, 73, 78, 199, 71, 65, 84, 69, 128, 71, + 65, 83, 72, 65, 78, 128, 71, 65, 82, 83, 72, 85, 78, 73, 128, 71, 65, 82, 79, 78, 128, 71, 65, 82, 77, 69, 78, 84, 128, 71, 65, 82, 76, 73, 67, 128, 71, 65, 82, 68, 69, 78, 128, 71, 65, 82, 51, 128, 71, 65, 80, 80, 69, 196, 71, 65, 208, 71, 65, 78, 77, 65, 128, 71, 65, 78, 71, 73, 65, @@ -4365,34 +4365,34 @@ static const unsigned char lexicon[] = { 69, 73, 83, 128, 69, 73, 71, 72, 84, 89, 128, 69, 73, 71, 72, 84, 217, 69, 73, 71, 72, 84, 73, 69, 84, 72, 83, 128, 69, 73, 71, 72, 84, 73, 69, 84, 72, 128, 69, 73, 71, 72, 84, 72, 83, 128, 69, 73, 71, 72, 84, 72, - 211, 69, 73, 71, 72, 84, 72, 128, 69, 73, 71, 72, 84, 69, 69, 78, 128, - 69, 73, 71, 72, 84, 69, 69, 206, 69, 73, 71, 72, 84, 45, 84, 72, 73, 82, - 84, 89, 128, 69, 73, 69, 128, 69, 72, 87, 65, 218, 69, 72, 84, 83, 65, - 128, 69, 72, 84, 65, 128, 69, 72, 80, 65, 128, 69, 72, 75, 65, 128, 69, - 72, 67, 72, 65, 128, 69, 71, 89, 80, 84, 79, 76, 79, 71, 73, 67, 65, 204, - 69, 71, 89, 128, 69, 71, 73, 82, 128, 69, 71, 71, 128, 69, 69, 89, 65, - 78, 78, 65, 128, 69, 69, 75, 65, 65, 128, 69, 69, 72, 128, 69, 69, 66, - 69, 69, 70, 73, 76, 73, 128, 69, 68, 73, 84, 79, 82, 73, 65, 204, 69, 68, - 73, 78, 128, 69, 68, 68, 128, 69, 67, 83, 128, 69, 66, 69, 70, 73, 76, - 73, 128, 69, 65, 83, 84, 69, 82, 206, 69, 65, 83, 84, 128, 69, 65, 83, - 212, 69, 65, 82, 84, 72, 76, 217, 69, 65, 82, 84, 72, 128, 69, 65, 82, - 84, 200, 69, 65, 82, 83, 128, 69, 65, 82, 76, 217, 69, 65, 77, 72, 65, - 78, 67, 72, 79, 76, 76, 128, 69, 65, 71, 76, 69, 128, 69, 65, 68, 72, 65, - 68, 72, 128, 69, 65, 66, 72, 65, 68, 72, 128, 69, 178, 69, 48, 51, 56, - 128, 69, 48, 51, 55, 128, 69, 48, 51, 54, 128, 69, 48, 51, 52, 65, 128, - 69, 48, 51, 52, 128, 69, 48, 51, 51, 128, 69, 48, 51, 50, 128, 69, 48, - 51, 49, 128, 69, 48, 51, 48, 128, 69, 48, 50, 57, 128, 69, 48, 50, 56, - 65, 128, 69, 48, 50, 56, 128, 69, 48, 50, 55, 128, 69, 48, 50, 54, 128, - 69, 48, 50, 53, 128, 69, 48, 50, 52, 128, 69, 48, 50, 51, 128, 69, 48, - 50, 50, 128, 69, 48, 50, 49, 128, 69, 48, 50, 48, 65, 128, 69, 48, 50, - 48, 128, 69, 48, 49, 57, 128, 69, 48, 49, 56, 128, 69, 48, 49, 55, 65, - 128, 69, 48, 49, 55, 128, 69, 48, 49, 54, 65, 128, 69, 48, 49, 54, 128, - 69, 48, 49, 53, 128, 69, 48, 49, 52, 128, 69, 48, 49, 51, 128, 69, 48, - 49, 50, 128, 69, 48, 49, 49, 128, 69, 48, 49, 48, 128, 69, 48, 48, 57, - 65, 128, 69, 48, 48, 57, 128, 69, 48, 48, 56, 65, 128, 69, 48, 48, 56, - 128, 69, 48, 48, 55, 128, 69, 48, 48, 54, 128, 69, 48, 48, 53, 128, 69, - 48, 48, 52, 128, 69, 48, 48, 51, 128, 69, 48, 48, 50, 128, 69, 48, 48, - 49, 128, 69, 45, 77, 65, 73, 204, 68, 90, 90, 72, 69, 128, 68, 90, 90, + 211, 69, 73, 71, 72, 84, 72, 128, 69, 73, 71, 72, 84, 69, 69, 78, 128, + 69, 73, 71, 72, 84, 69, 69, 206, 69, 73, 71, 72, 84, 45, 84, 72, 73, 82, + 84, 89, 128, 69, 73, 69, 128, 69, 72, 87, 65, 218, 69, 72, 84, 83, 65, + 128, 69, 72, 84, 65, 128, 69, 72, 80, 65, 128, 69, 72, 75, 65, 128, 69, + 72, 67, 72, 65, 128, 69, 71, 89, 80, 84, 79, 76, 79, 71, 73, 67, 65, 204, + 69, 71, 89, 128, 69, 71, 73, 82, 128, 69, 71, 71, 128, 69, 69, 89, 65, + 78, 78, 65, 128, 69, 69, 75, 65, 65, 128, 69, 69, 72, 128, 69, 69, 66, + 69, 69, 70, 73, 76, 73, 128, 69, 68, 73, 84, 79, 82, 73, 65, 204, 69, 68, + 73, 78, 128, 69, 68, 68, 128, 69, 67, 83, 128, 69, 66, 69, 70, 73, 76, + 73, 128, 69, 65, 83, 84, 69, 82, 206, 69, 65, 83, 84, 128, 69, 65, 83, + 212, 69, 65, 82, 84, 72, 76, 217, 69, 65, 82, 84, 72, 128, 69, 65, 82, + 84, 200, 69, 65, 82, 83, 128, 69, 65, 82, 76, 217, 69, 65, 77, 72, 65, + 78, 67, 72, 79, 76, 76, 128, 69, 65, 71, 76, 69, 128, 69, 65, 68, 72, 65, + 68, 72, 128, 69, 65, 66, 72, 65, 68, 72, 128, 69, 178, 69, 48, 51, 56, + 128, 69, 48, 51, 55, 128, 69, 48, 51, 54, 128, 69, 48, 51, 52, 65, 128, + 69, 48, 51, 52, 128, 69, 48, 51, 51, 128, 69, 48, 51, 50, 128, 69, 48, + 51, 49, 128, 69, 48, 51, 48, 128, 69, 48, 50, 57, 128, 69, 48, 50, 56, + 65, 128, 69, 48, 50, 56, 128, 69, 48, 50, 55, 128, 69, 48, 50, 54, 128, + 69, 48, 50, 53, 128, 69, 48, 50, 52, 128, 69, 48, 50, 51, 128, 69, 48, + 50, 50, 128, 69, 48, 50, 49, 128, 69, 48, 50, 48, 65, 128, 69, 48, 50, + 48, 128, 69, 48, 49, 57, 128, 69, 48, 49, 56, 128, 69, 48, 49, 55, 65, + 128, 69, 48, 49, 55, 128, 69, 48, 49, 54, 65, 128, 69, 48, 49, 54, 128, + 69, 48, 49, 53, 128, 69, 48, 49, 52, 128, 69, 48, 49, 51, 128, 69, 48, + 49, 50, 128, 69, 48, 49, 49, 128, 69, 48, 49, 48, 128, 69, 48, 48, 57, + 65, 128, 69, 48, 48, 57, 128, 69, 48, 48, 56, 65, 128, 69, 48, 48, 56, + 128, 69, 48, 48, 55, 128, 69, 48, 48, 54, 128, 69, 48, 48, 53, 128, 69, + 48, 48, 52, 128, 69, 48, 48, 51, 128, 69, 48, 48, 50, 128, 69, 48, 48, + 49, 128, 69, 45, 77, 65, 73, 204, 68, 90, 90, 72, 69, 128, 68, 90, 90, 69, 128, 68, 90, 90, 65, 128, 68, 90, 89, 73, 128, 68, 90, 89, 65, 89, 128, 68, 90, 87, 69, 128, 68, 90, 85, 128, 68, 90, 79, 128, 68, 90, 74, 69, 128, 68, 90, 73, 84, 65, 128, 68, 90, 73, 128, 68, 90, 72, 79, 73, @@ -4775,9 +4775,9 @@ static const unsigned char lexicon[] = { 79, 86, 69, 82, 128, 67, 79, 85, 80, 76, 197, 67, 79, 85, 78, 84, 73, 78, 199, 67, 79, 85, 78, 84, 69, 82, 83, 73, 78, 75, 128, 67, 79, 85, 78, 84, 69, 82, 66, 79, 82, 69, 128, 67, 79, 85, 78, 67, 73, 204, 67, 79, 85, 67, - 200, 67, 79, 84, 128, 67, 79, 82, 82, 69, 83, 80, 79, 78, 68, 211, 67, - 79, 82, 82, 69, 67, 84, 128, 67, 79, 82, 80, 83, 69, 128, 67, 79, 82, 80, - 79, 82, 65, 84, 73, 79, 78, 128, 67, 79, 82, 79, 78, 73, 83, 128, 67, 79, + 200, 67, 79, 84, 128, 67, 79, 82, 82, 69, 83, 80, 79, 78, 68, 211, 67, + 79, 82, 82, 69, 67, 84, 128, 67, 79, 82, 80, 83, 69, 128, 67, 79, 82, 80, + 79, 82, 65, 84, 73, 79, 78, 128, 67, 79, 82, 79, 78, 73, 83, 128, 67, 79, 82, 78, 73, 83, 200, 67, 79, 82, 78, 69, 82, 83, 128, 67, 79, 82, 78, 69, 82, 128, 67, 79, 82, 78, 69, 210, 67, 79, 82, 75, 128, 67, 79, 80, 89, 82, 73, 71, 72, 84, 128, 67, 79, 80, 89, 82, 73, 71, 72, 212, 67, 79, 80, @@ -5479,369 +5479,369 @@ static const unsigned char lexicon[] = { 73, 77, 128, 67, 72, 72, 65, 128, 67, 72, 69, 88, 128, 67, 72, 69, 86, 82, 79, 78, 128, 67, 72, 69, 86, 82, 79, 206, 67, 72, 69, 84, 128, 67, 72, 69, 83, 84, 78, 85, 84, 128, 67, 72, 69, 83, 84, 128, 67, 72, 69, 83, - 211, 67, 72, 69, 82, 89, 128, 67, 72, 69, 82, 82, 217, 67, 72, 69, 82, - 82, 73, 69, 83, 128, 67, 72, 69, 81, 85, 69, 82, 69, 196, 67, 72, 69, 80, - 128, 67, 72, 69, 73, 78, 65, 80, 128, 67, 72, 69, 73, 75, 72, 69, 73, - 128, 67, 72, 69, 73, 75, 72, 65, 78, 128, 67, 72, 69, 69, 83, 197, 67, - 72, 69, 69, 82, 73, 78, 199, 67, 72, 69, 69, 77, 128, 67, 72, 69, 69, 75, - 211, 67, 72, 69, 69, 75, 128, 67, 72, 69, 69, 128, 67, 72, 69, 67, 75, - 69, 210, 67, 72, 69, 67, 75, 128, 67, 72, 69, 67, 203, 67, 72, 197, 67, - 72, 65, 88, 128, 67, 72, 65, 86, 73, 89, 65, 78, 73, 128, 67, 72, 65, 84, - 84, 65, 87, 65, 128, 67, 72, 65, 84, 128, 67, 72, 65, 82, 84, 128, 67, - 72, 65, 82, 212, 67, 72, 65, 82, 73, 79, 84, 128, 67, 72, 65, 82, 73, 79, - 212, 67, 72, 65, 82, 65, 67, 84, 69, 82, 83, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, - 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 54, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 53, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 52, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 51, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, - 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 68, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 67, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 66, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 65, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, - 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 52, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 51, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 50, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 49, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, - 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 66, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 65, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 57, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 56, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, - 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 50, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 49, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 48, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 70, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, - 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 57, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 56, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 55, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 54, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, - 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 48, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 70, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 69, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 68, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, - 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 55, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 54, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 53, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 52, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, - 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 69, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 68, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 67, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 66, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, - 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 53, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 52, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 51, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 50, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, - 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 67, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 66, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 65, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 57, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, - 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 51, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 50, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 49, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 48, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, - 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 65, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 57, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 56, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 55, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, - 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 49, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 48, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 70, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 69, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, - 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 56, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 55, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 54, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 53, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, - 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 70, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 69, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 68, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 67, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, - 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 54, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 53, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 52, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 51, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, - 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 68, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 67, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 66, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 65, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, - 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 52, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 51, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 50, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 49, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, - 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 66, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 65, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 57, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 56, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, - 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 50, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 49, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 48, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 70, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, - 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 57, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 56, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 55, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 54, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, - 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 48, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 70, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 69, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 68, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, - 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 55, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 54, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 53, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 52, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, - 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 69, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 68, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 67, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 66, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, - 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 53, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 52, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 51, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 50, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, - 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 67, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 66, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 65, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 57, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 50, 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 50, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 50, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 50, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, - 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 51, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 50, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 49, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 48, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 70, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 70, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 70, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, - 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 65, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 57, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 56, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 55, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 70, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, - 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 49, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 48, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 70, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 69, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 69, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, - 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 56, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 55, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 54, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 53, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 69, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, - 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 70, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 69, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 68, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 67, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 68, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, - 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 54, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 53, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 52, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 51, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, - 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 68, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 67, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 66, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 65, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, - 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 52, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 51, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 50, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 49, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, - 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 66, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 65, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 57, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 56, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, - 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 50, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 49, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 48, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 70, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, - 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 57, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 56, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 55, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 54, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, - 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 48, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 70, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 69, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 68, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, - 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 55, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 54, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 53, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 52, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, - 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 69, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 68, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 67, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 66, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, - 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 53, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 52, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 51, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 50, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, - 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 67, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 66, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 65, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 57, 128, 67, 72, 65, 82, 65, 67, - 84, 69, 82, 45, 49, 66, 49, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, - 82, 45, 49, 66, 49, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, - 49, 66, 49, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, - 49, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, - 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 51, 128, - 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 50, 128, 67, 72, - 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 49, 128, 67, 72, 65, 82, - 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 48, 128, 67, 72, 65, 82, 65, 67, + 211, 67, 72, 69, 82, 89, 128, 67, 72, 69, 82, 82, 217, 67, 72, 69, 82, + 82, 73, 69, 83, 128, 67, 72, 69, 81, 85, 69, 82, 69, 196, 67, 72, 69, 80, + 128, 67, 72, 69, 73, 78, 65, 80, 128, 67, 72, 69, 73, 75, 72, 69, 73, + 128, 67, 72, 69, 73, 75, 72, 65, 78, 128, 67, 72, 69, 69, 83, 197, 67, + 72, 69, 69, 82, 73, 78, 199, 67, 72, 69, 69, 77, 128, 67, 72, 69, 69, 75, + 211, 67, 72, 69, 69, 75, 128, 67, 72, 69, 69, 128, 67, 72, 69, 67, 75, + 69, 210, 67, 72, 69, 67, 75, 128, 67, 72, 69, 67, 203, 67, 72, 197, 67, + 72, 65, 88, 128, 67, 72, 65, 86, 73, 89, 65, 78, 73, 128, 67, 72, 65, 84, + 84, 65, 87, 65, 128, 67, 72, 65, 84, 128, 67, 72, 65, 82, 84, 128, 67, + 72, 65, 82, 212, 67, 72, 65, 82, 73, 79, 84, 128, 67, 72, 65, 82, 73, 79, + 212, 67, 72, 65, 82, 65, 67, 84, 69, 82, 83, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, + 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 54, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 53, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 52, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 51, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, + 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 68, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 67, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 66, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 65, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, + 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 52, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 51, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 50, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 49, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, + 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 66, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 65, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 57, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 56, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, + 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 50, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 49, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 48, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 70, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, + 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 57, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 56, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 55, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 54, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, + 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 48, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 70, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 69, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 68, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, + 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 55, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 54, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 53, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 52, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, + 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 69, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 68, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 67, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 66, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, + 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 53, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 52, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 51, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 50, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, + 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 67, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 66, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 65, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 57, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, + 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 51, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 50, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 49, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 48, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, + 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 65, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 57, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 56, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 55, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, + 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 49, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 48, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 70, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 69, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, + 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 56, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 55, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 54, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 53, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, + 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 70, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 69, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 68, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 67, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, + 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 54, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 53, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 52, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 51, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, + 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 68, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 67, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 66, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 65, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, + 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 52, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 51, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 50, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 49, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, + 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 66, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 65, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 57, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 56, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, + 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 50, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 49, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 48, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 70, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, + 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 57, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 56, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 55, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 54, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, + 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 48, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 70, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 69, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 68, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, + 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 55, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 54, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 53, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 52, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, + 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 69, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 68, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 67, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 66, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, + 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 53, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 52, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 51, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 50, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, + 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 67, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 66, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 65, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 57, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 50, 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 50, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 50, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 50, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, + 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 51, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 50, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 49, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 48, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 70, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 70, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 70, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, + 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 65, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 57, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 56, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 55, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 70, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, + 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 49, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 48, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 70, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 69, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 69, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, + 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 56, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 55, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 54, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 53, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 69, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, + 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 70, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 69, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 68, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 67, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 68, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, + 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 54, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 53, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 52, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 51, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, + 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 68, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 67, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 66, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 65, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, + 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 52, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 51, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 50, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 49, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, + 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 66, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 65, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 57, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 56, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, + 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 50, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 49, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 48, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 70, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, + 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 57, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 56, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 55, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 54, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, + 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 48, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 70, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 69, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 68, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, + 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 55, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 54, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 53, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 52, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, + 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 69, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 68, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 67, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 66, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, + 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 53, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 52, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 51, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 50, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, + 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 67, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 66, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 65, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 57, 128, 67, 72, 65, 82, 65, 67, + 84, 69, 82, 45, 49, 66, 49, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 45, 49, 66, 49, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, + 49, 66, 49, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 49, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, + 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 51, 128, + 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 50, 128, 67, 72, + 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 49, 128, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, @@ -6939,8 +6939,8 @@ static const unsigned char lexicon[] = { 65, 45, 87, 79, 128, 65, 45, 69, 85, 128, 45, 85, 205, 45, 80, 72, 82, 85, 128, 45, 75, 72, 89, 85, 196, 45, 75, 72, 89, 73, 76, 128, 45, 68, 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, 72, 65, 76, 128, -}; - +}; + static const unsigned int lexicon_offset[] = { 0, 0, 6, 11, 15, 19, 27, 34, 44, 49, 55, 64, 66, 69, 81, 89, 102, 108, 113, 118, 124, 129, 137, 146, 157, 162, 167, 170, 176, 180, 189, 195, @@ -8576,9 +8576,9 @@ static const unsigned int lexicon_offset[] = { 121918, 118098, 118104, 118110, 118130, 121924, 121930, 118136, 121936, 118142, 118148, 118154, 118160, 118166, 121942, 3236, 3241, 121947, 3256, 3261, 3266, 121952, 121955, 121961, 121967, 121974, 121979, 121984, 2285, -}; - -/* code->name phrasebook */ +}; + +/* code->name phrasebook */ #define phrasebook_shift 8 #define phrasebook_short 191 static const unsigned char phrasebook[] = { @@ -20014,11 +20014,11 @@ static const unsigned char phrasebook[] = { 251, 55, 246, 158, 75, 1, 251, 55, 198, 45, 75, 1, 251, 55, 155, 75, 1, 251, 55, 211, 93, 73, 1, 233, 188, 233, 187, 238, 247, 158, 161, 73, 1, 233, 187, 233, 188, 238, 247, 158, 161, -}; - +}; + static const unsigned char phrasebook_offset1[] = { - 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, 37, 38, + 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, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, @@ -20260,19 +20260,19 @@ static const unsigned char phrasebook_offset1[] = { 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, -}; - +}; + static const unsigned int phrasebook_offset2[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 6, 9, 11, 14, 17, 19, 21, 24, 27, 29, 31, - 33, 35, 39, 41, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 69, 72, - 75, 78, 82, 86, 91, 96, 101, 105, 110, 115, 120, 124, 129, 134, 138, 143, - 148, 152, 157, 162, 166, 171, 176, 180, 185, 190, 195, 200, 205, 208, - 212, 215, 219, 222, 226, 230, 235, 240, 245, 249, 254, 259, 264, 268, - 273, 278, 282, 287, 292, 296, 301, 306, 310, 315, 320, 324, 329, 334, - 339, 344, 349, 353, 356, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 362, 366, 371, - 374, 377, 380, 383, 386, 389, 391, 394, 400, 408, 411, 415, 418, 420, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 6, 9, 11, 14, 17, 19, 21, 24, 27, 29, 31, + 33, 35, 39, 41, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 69, 72, + 75, 78, 82, 86, 91, 96, 101, 105, 110, 115, 120, 124, 129, 134, 138, 143, + 148, 152, 157, 162, 166, 171, 176, 180, 185, 190, 195, 200, 205, 208, + 212, 215, 219, 222, 226, 230, 235, 240, 245, 249, 254, 259, 264, 268, + 273, 278, 282, 287, 292, 296, 301, 306, 310, 315, 320, 324, 329, 334, + 339, 344, 349, 353, 356, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 362, 366, 371, + 374, 377, 380, 383, 386, 389, 391, 394, 400, 408, 411, 415, 418, 420, 423, 426, 429, 432, 436, 439, 442, 445, 447, 450, 456, 464, 471, 478, 485, 490, 497, 504, 511, 518, 525, 533, 538, 546, 554, 562, 570, 578, 586, 594, 602, 610, 615, 623, 630, 637, 644, 651, 658, 661, 667, 674, @@ -20441,8 +20441,8 @@ static const unsigned int phrasebook_offset2[] = { 12386, 12391, 12396, 12401, 12406, 12411, 12416, 12421, 12426, 12431, 12436, 12441, 12446, 12451, 12456, 12461, 0, 0, 12466, 0, 12470, 12476, 12482, 12488, 12494, 12500, 12506, 12512, 12517, 12523, 12529, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12535, 12544, 12552, 12561, 12570, 12583, 12590, 12597, 12605, 12618, 12630, 12637, 12645, 12651, 12656, 12665, 12674, 12682, 12688, 12698, 12707, 0, 12714, 12722, 12730, 12739, 12748, 12762, 12768, 12774, @@ -20569,7 +20569,7 @@ static const unsigned int phrasebook_offset2[] = { 0, 0, 0, 18203, 18210, 18217, 18225, 18232, 18242, 18252, 18258, 18264, 18270, 18278, 18286, 18294, 18302, 18308, 18314, 18320, 18326, 18331, 18335, 18339, 18343, 18347, 18351, 18355, 18359, 18363, 18367, 18373, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18379, 18384, 0, 18391, 0, 18398, 18405, 18410, 18415, 18422, 0, 18429, 18436, 18441, 18448, 18455, 18462, 18469, 18476, 18483, 18488, 18492, 18499, 18506, 18513, 18518, 18523, @@ -20602,7 +20602,7 @@ static const unsigned int phrasebook_offset2[] = { 19934, 19941, 19954, 19961, 19968, 19976, 19984, 19990, 19996, 20002, 20012, 20017, 20023, 20033, 20043, 0, 20053, 20063, 20071, 20083, 20095, 20101, 20115, 20130, 20135, 20140, 20148, 20156, 20164, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20172, 20175, 20179, 20183, 20187, 20191, 20195, 20199, 20203, 20207, 20211, 20215, 20219, 20223, 20227, 20231, 20235, 20238, 20242, 20246, 20250, 20253, 20256, 20260, 20264, 20268, 20271, @@ -20867,7 +20867,7 @@ static const unsigned int phrasebook_offset2[] = { 32738, 32743, 32748, 32753, 0, 0, 32758, 32765, 32768, 32771, 32775, 32780, 32784, 32790, 32795, 32801, 32808, 32816, 32820, 32825, 32829, 32834, 32841, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32849, 32855, 32861, 32865, 32869, 32873, 32877, 32883, 32887, 32893, 32897, 32903, 32909, 32917, 32923, 32931, 32935, 32939, 32943, 32949, 32952, 32958, @@ -21351,7 +21351,7 @@ static const unsigned int phrasebook_offset2[] = { 62087, 62093, 62098, 62103, 62105, 62108, 62112, 62118, 62124, 62128, 62133, 62142, 62145, 62151, 62156, 62160, 62164, 62168, 62171, 62176, 62182, 62190, 62198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62204, 62208, 62212, 62217, 62222, 62227, 62231, 62235, 62239, 62244, 62249, 62253, 62257, 62261, 62265, 62270, 62275, 62280, 62285, 62289, 62293, 62298, 62303, 62308, 62313, 62317, 0, 62321, 62325, @@ -21489,24 +21489,24 @@ static const unsigned int phrasebook_offset2[] = { 68216, 68224, 68232, 68240, 68248, 68256, 68265, 68274, 68283, 68292, 68301, 68310, 68319, 68328, 68337, 68346, 68355, 68364, 68373, 68382, 68391, 68400, 68409, 68418, 68427, 68436, 68445, 68454, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68457, 68466, 68475, 68486, 68493, 68498, 68503, 68510, 68517, 68523, 68528, 68533, 68538, 68543, 68550, 68555, 68560, 68565, 68576, 68581, 68586, 68593, 68598, 68605, 68610, 68615, @@ -21711,7 +21711,7 @@ static const unsigned int phrasebook_offset2[] = { 77362, 77368, 77374, 77380, 77388, 77393, 77398, 77403, 77408, 77413, 77419, 77425, 77431, 77437, 77443, 77449, 77455, 0, 0, 77461, 77468, 77475, 77484, 77491, 77500, 77512, 77524, 77536, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77548, 77556, 77564, 77571, 77578, 77584, 77591, 77599, 77607, 77615, 77623, 77631, 77637, 77643, 77650, 77656, 77662, 77668, 77675, 77682, 77689, 77696, 77703, 77710, 77717, 77724, @@ -21808,13 +21808,13 @@ static const unsigned int phrasebook_offset2[] = { 82621, 82630, 82639, 82648, 82657, 82666, 82675, 82684, 82693, 82701, 82709, 82717, 82725, 82733, 82741, 82749, 82757, 82763, 82771, 0, 0, 82779, 82786, 82792, 82798, 82804, 82810, 82816, 82822, 82828, 82834, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82840, 82845, 82850, 82855, 82860, 82865, 82870, 82875, 82880, 82885, 82890, 82895, 82900, 82905, 82910, 82915, 82920, 82925, 82930, 82935, 82940, 82945, 82950, 0, 0, 0, 0, @@ -21940,7 +21940,7 @@ static const unsigned int phrasebook_offset2[] = { 90392, 90403, 90413, 90422, 90432, 90441, 90450, 90460, 90470, 90480, 90490, 90500, 90510, 90521, 90531, 90542, 90552, 90563, 90574, 90584, 90594, 90604, 90614, 90624, 90634, 90645, 90655, 90666, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90677, 90692, 90707, 90713, 90719, 90725, 90731, 90737, 90743, 90749, 90755, 90763, 90767, 90770, 0, 0, 90778, 90781, 90784, 90787, 90790, 90793, 90796, 90799, 90802, 90805, 90808, @@ -22030,17 +22030,17 @@ static const unsigned int phrasebook_offset2[] = { 95654, 95658, 95662, 95666, 95670, 95674, 95678, 95684, 95688, 95693, 95697, 95701, 0, 95704, 95709, 95714, 95719, 95724, 95731, 95736, 95741, 95746, 95751, 95756, 95761, 95766, 0, 0, 0, 95769, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95775, 95782, 95791, 95800, 95807, 95814, 95821, 95828, 95835, 95842, 95848, 95855, 95862, 95869, 95876, 95883, 95890, 95897, 95904, 95913, 95920, 95927, 95934, 95941, 95948, 95955, 95962, 95969, 95978, 95985, 95992, 95999, 96006, 96013, 96020, 96029, 96036, 96043, 96050, 96057, 96066, 96073, 96080, 96087, 96095, 96104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96113, 96117, 96121, 96126, 96131, 96136, 96141, 96145, 96150, 96155, 96160, 96165, 96170, 96175, 96179, 96184, 96189, 96194, 96199, 96203, 96208, 96213, 96217, @@ -22073,7 +22073,7 @@ static const unsigned int phrasebook_offset2[] = { 97531, 97536, 97542, 97548, 97553, 97559, 97565, 97570, 97576, 97581, 97586, 97592, 97598, 97604, 0, 0, 0, 0, 97609, 97615, 97621, 97627, 97633, 97639, 97645, 97651, 97657, 97664, 97669, 97674, 97680, 97686, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97692, 97698, 97704, 97710, 97717, 97723, 97730, 97737, 97744, 97751, 97759, 97766, 97774, 97780, 97786, 97792, 97798, 97804, 97810, 97816, 97822, 97828, 97834, @@ -22110,11 +22110,11 @@ static const unsigned int phrasebook_offset2[] = { 99444, 99451, 99458, 99465, 99472, 99479, 99486, 99493, 99500, 99507, 99514, 99521, 99528, 99535, 99542, 99549, 99556, 99563, 99570, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99584, 99589, 99594, 99599, 99604, 99609, 99614, 99619, 99624, 99629, 99634, 99639, 99644, 99649, 99654, 99659, 99664, 99669, 99674, 99679, 99684, 99689, 99694, 99699, 99704, 99709, @@ -22154,11 +22154,11 @@ static const unsigned int phrasebook_offset2[] = { 101234, 101241, 101248, 101255, 101262, 101269, 101276, 101283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101290, 101295, 101300, 101305, 101310, 101315, 101320, 101325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101330, 101334, 101338, 101342, 101346, 101350, 0, 0, 101355, 0, 101360, 101364, 101369, 101374, 101379, 101384, 101388, 101393, 101398, 101403, 101408, 101412, 101417, 101422, @@ -22178,7 +22178,7 @@ static const unsigned int phrasebook_offset2[] = { 102056, 102061, 102067, 102072, 102078, 102083, 102088, 102093, 102098, 102103, 102108, 102113, 102119, 102124, 0, 0, 0, 0, 0, 0, 0, 0, 102129, 102133, 102137, 102141, 102145, 102151, 102155, 102160, 102165, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102171, 102176, 102181, 102186, 102191, 102196, 102201, 102206, 102211, 102216, 102221, 102226, 102231, 102236, 102241, 102246, 102251, 102256, 102261, @@ -22190,8 +22190,8 @@ static const unsigned int phrasebook_offset2[] = { 102472, 102476, 102481, 102486, 102490, 102495, 102500, 102504, 102508, 102513, 102518, 102522, 102527, 102532, 102537, 102542, 102547, 102552, 102557, 102562, 0, 0, 0, 0, 0, 102567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102572, 102577, 102582, 102587, 102592, 102597, 102603, 102609, 102615, 102620, 102625, 102630, 102636, 102642, 102648, 102653, 102659, 102664, 102670, 102676, 102681, 102687, 102693, 102698, 102704, @@ -22248,8 +22248,8 @@ static const unsigned int phrasebook_offset2[] = { 105273, 105280, 105287, 105294, 0, 0, 0, 0, 0, 0, 0, 105301, 105308, 105316, 105327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105338, 105344, 105350, 105356, 105362, 105369, 105376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105384, 105391, 105398, 105406, 105413, 105420, 105427, 105434, 105442, 105450, 105458, 105466, 105474, 105482, 105490, 105498, 105506, 105514, 105522, @@ -22259,8 +22259,8 @@ static const unsigned int phrasebook_offset2[] = { 105746, 105754, 105762, 105770, 105778, 105786, 105794, 105802, 105810, 105818, 105826, 105834, 105842, 105850, 105858, 105866, 105874, 105882, 105890, 105898, 105906, 105914, 105922, 105930, 105938, 105946, 105954, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105962, 105967, 105973, 105979, 105985, 105991, 105997, 106003, 106009, 106015, 106020, 106027, 106033, 106039, 106045, 106051, 106057, 106062, 106068, 106074, 106080, 106086, 106092, 106098, @@ -22281,17 +22281,17 @@ static const unsigned int phrasebook_offset2[] = { 106842, 106849, 106858, 106865, 106872, 106879, 0, 0, 0, 0, 0, 0, 0, 0, 106886, 106893, 106899, 106905, 106911, 106917, 106923, 106929, 106935, 106941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106947, 106951, 106955, 106959, 106963, 106967, 106971, 106975, 106979, 106983, 106988, 106993, 106998, 107003, 107008, 107013, 107018, 107023, 107028, 107034, 107040, 107046, 107053, 107060, @@ -22972,13 +22972,13 @@ static const unsigned int phrasebook_offset2[] = { 134273, 134277, 134281, 134285, 134289, 134293, 134297, 134301, 134305, 134309, 134313, 134317, 134321, 134325, 134329, 134333, 134337, 134341, 134345, 134349, 134353, 134357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134361, 134369, 134377, 134387, 134397, 134405, 134411, 134419, 134427, 134437, 134449, 134461, 134467, 134475, 134481, 134487, 134493, 134499, 134505, 134511, 134517, 134523, 134529, 134535, 134541, 134549, @@ -23048,9 +23048,9 @@ static const unsigned int phrasebook_offset2[] = { 137758, 137763, 137768, 137773, 137777, 137782, 137787, 137791, 137796, 137801, 0, 137806, 137811, 137815, 137819, 137823, 137827, 137831, 137835, 137839, 137843, 0, 0, 0, 0, 137847, 137851, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137856, 137863, 137869, 137876, 137883, 137890, 137897, 137904, 137911, 137918, 137925, 137932, 137939, 137946, 137953, 137960, 137967, 137974, 137980, 137987, @@ -23072,12 +23072,12 @@ static const unsigned int phrasebook_offset2[] = { 0, 0, 138728, 138735, 138742, 138749, 138756, 138763, 138770, 138777, 138784, 138791, 138798, 138805, 138812, 138819, 138826, 138833, 138840, 138847, 138854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138861, 138867, 138873, 138879, 138885, 138891, 138897, 138903, 138909, 138915, 138921, 138927, 138932, 138938, 138943, 138949, 138954, 138960, 138966, 138971, 138977, 138982, @@ -23089,9 +23089,9 @@ static const unsigned int phrasebook_offset2[] = { 139244, 139248, 139252, 139256, 139260, 139264, 139268, 139272, 139277, 139282, 139287, 139292, 139297, 139302, 139307, 139312, 139317, 139322, 139329, 139336, 139343, 139347, 139353, 139358, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139364, 139367, 139371, 139375, 139379, 139382, 139386, 139391, 139395, 139399, 139403, 139406, 139410, 139415, 139419, 139423, 139427, 139430, 139434, @@ -23110,8 +23110,8 @@ static const unsigned int phrasebook_offset2[] = { 139918, 139923, 139928, 139933, 139938, 139943, 139948, 0, 0, 0, 0, 0, 0, 0, 139953, 139957, 139963, 139966, 139969, 139973, 139977, 139981, 139985, 139989, 139993, 139997, 140003, 140009, 140015, 140021, 140027, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140033, 140037, 140041, 140047, 140053, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140058, 140067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140076, 140079, 140082, 140085, 140088, @@ -23252,7 +23252,7 @@ static const unsigned int phrasebook_offset2[] = { 144595, 144600, 144605, 144610, 144615, 144620, 144625, 144630, 144635, 144640, 144645, 144650, 144655, 144660, 144665, 144670, 144675, 144680, 144685, 144690, 144695, 144700, 144705, 144710, 144715, 144720, 144725, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144730, 144735, 144742, 144746, 144750, 144754, 144758, 144762, 144766, 144770, 144774, 144778, 144782, 144786, 144790, 144794, 144798, 144802, 144806, 144810, @@ -23286,7 +23286,7 @@ static const unsigned int phrasebook_offset2[] = { 145786, 145790, 145794, 145798, 145802, 145806, 145810, 145814, 145818, 145822, 145826, 145830, 145834, 145838, 145842, 145846, 145850, 145854, 145858, 145862, 145866, 145870, 145874, 145878, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145882, 145888, 145894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145900, 145905, 145910, 145915, 0, 0, 0, 0, 0, 0, 0, 0, 145920, 145923, 145926, @@ -23351,9 +23351,9 @@ static const unsigned int phrasebook_offset2[] = { 147796, 147802, 147808, 147814, 147820, 0, 0, 0, 0, 0, 0, 0, 147826, 147832, 147840, 147846, 147853, 147859, 147865, 147871, 147877, 147883, 0, 0, 147888, 147894, 147900, 147903, 147912, 147919, 147927, 147934, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147941, 147946, 147951, 147956, 147963, 147970, 147977, 147984, 147989, 147994, 147999, 148004, 148011, 148016, 148023, 148030, 148035, 148040, 148045, 148052, @@ -23418,11 +23418,11 @@ static const unsigned int phrasebook_offset2[] = { 151521, 151528, 151535, 151542, 151549, 151556, 151563, 151570, 151577, 151584, 151591, 151598, 151605, 151612, 151619, 151626, 151631, 151636, 151641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151645, 151651, 151656, 151661, 151666, 151671, 151676, 151681, 151686, 151691, 151696, 151702, 151708, 151714, 151720, 151726, 151732, 151738, 151744, 151750, 0, 0, 0, 0, 0, 0, @@ -23439,11 +23439,11 @@ static const unsigned int phrasebook_offset2[] = { 0, 0, 0, 0, 0, 0, 152231, 152239, 152247, 152255, 152263, 152271, 152279, 152287, 152295, 152303, 152311, 152319, 152327, 152335, 152343, 152351, 152359, 152367, 152375, 152380, 152385, 152390, 152395, 152400, 152404, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152408, 152412, 152417, 152422, 152427, 152431, 152436, 152441, 152446, 152450, 152455, 152460, 152464, 152469, 152474, 152478, 152483, 152488, 152492, 152497, 152502, @@ -23633,22 +23633,22 @@ static const unsigned int phrasebook_offset2[] = { 0, 0, 0, 0, 163001, 163006, 163011, 163016, 163021, 0, 163026, 163031, 163036, 163041, 163046, 163051, 163056, 163061, 163066, 163071, 163076, 163081, 163086, 163091, 163096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163101, 163106, 163111, 163116, 163121, 163126, 163131, 0, 163136, 163141, 163146, 163152, 163156, 163161, 163166, 163171, 163176, 163181, 163186, 163191, 163196, 163201, 163206, 163211, 163216, 0, 0, 163221, 163226, 163231, 163236, 163241, 163246, 163251, 0, 163256, 163261, 0, 163267, 163272, 163280, 163287, 163296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163301, 163308, 163316, 163324, 163331, 163338, 163345, 163353, 163361, 163369, 163376, 163383, 163391, 163399, 163407, 163414, 163422, 163430, 163438, 163446, 163454, 163462, 163470, 163477, 163485, @@ -23658,20 +23658,20 @@ static const unsigned int phrasebook_offset2[] = { 163688, 163695, 163704, 163713, 163722, 163731, 163740, 163750, 0, 0, 163758, 163766, 163773, 163780, 163787, 163794, 163801, 163808, 163815, 163822, 0, 0, 0, 0, 163829, 163838, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163846, 163851, 163855, 163860, 163865, 163870, 163875, 163879, 163884, 163888, 163892, 163896, 163900, 163905, 163910, 163914, 163919, 163924, 163929, @@ -24296,11 +24296,11 @@ static const unsigned int phrasebook_offset2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -/* name->code dictionary */ +}; + +/* name->code dictionary */ static const unsigned int code_hash[] = { - 74224, 4851, 0, 0, 0, 0, 7929, 0, 0, 0, 0, 127931, 0, 42833, 983091, + 74224, 4851, 0, 0, 0, 0, 7929, 0, 0, 0, 0, 127931, 0, 42833, 983091, 12064, 110752, 129548, 194597, 69850, 65842, 0, 0, 0, 78159, 68476, 72392, 1373, 0, 0, 5816, 0, 0, 4231, 0, 0, 4233, 4234, 4232, 68885, 70351, 0, 7404, 72393, 0, 0, 0, 0, 0, 41601, 8874, 0, 0, 0, 0, 0, 0, @@ -24518,18 +24518,18 @@ static const unsigned int code_hash[] = { 0, 0, 194878, 7715, 0, 0, 194777, 194780, 0, 0, 0, 194787, 0, 0, 0, 0, 0, 66289, 127109, 3889, 129561, 194800, 0, 0, 0, 0, 121226, 12999, 0, 120902, 0, 0, 0, 0, 0, 64802, 42210, 4597, 0, 0, 0, 12371, 67164, 0, - 67163, 10805, 0, 0, 0, 0, 0, 12367, 0, 0, 92557, 12363, 0, 0, 128611, 0, + 67163, 10805, 0, 0, 0, 0, 0, 12367, 0, 0, 92557, 12363, 0, 0, 128611, 0, 0, 0, 8005, 12365, 0, 0, 3756, 12369, 10649, 0, 70095, 0, 0, 0, 42923, 0, 0, 0, 0, 0, 0, 66659, 0, 0, 0, 0, 5268, 4954, 0, 0, 5266, 126980, 5272, - 92294, 0, 42230, 983961, 0, 9128, 0, 0, 0, 0, 6928, 9803, 42282, 9110, - 1505, 0, 0, 5276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8722, 120805, 0, 0, 66695, - 0, 0, 4383, 8900, 0, 0, 74930, 64297, 0, 0, 0, 0, 3419, 42229, 0, 0, - 8911, 0, 42353, 0, 0, 0, 0, 0, 0, 0, 100629, 41576, 42215, 122888, 0, 0, - 8578, 68178, 7573, 41575, 74789, 92310, 0, 73863, 0, 2670, 0, 0, 11723, + 92294, 0, 42230, 983961, 0, 9128, 0, 0, 0, 0, 6928, 9803, 42282, 9110, + 1505, 0, 0, 5276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8722, 120805, 0, 0, 66695, + 0, 0, 4383, 8900, 0, 0, 74930, 64297, 0, 0, 0, 0, 3419, 42229, 0, 0, + 8911, 0, 42353, 0, 0, 0, 0, 0, 0, 0, 100629, 41576, 42215, 122888, 0, 0, + 8578, 68178, 7573, 41575, 74789, 92310, 0, 73863, 0, 2670, 0, 0, 11723, 0, 0, 0, 0, 0, 43414, 0, 0, 65675, 0, 67179, 67168, 12413, 129746, 67177, 0, 0, 0, 0, 12302, 0, 5250, 12407, 12245, 4404, 9189, 12401, 42007, 0, - 42005, 65806, 43997, 122922, 42002, 12404, 0, 74928, 4940, 12410, 0, - 128761, 0, 64567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11956, 0, 0, 122882, 0, + 42005, 65806, 43997, 122922, 42002, 12404, 0, 74928, 4940, 12410, 0, + 128761, 0, 64567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11956, 0, 0, 122882, 0, 6631, 128923, 0, 74583, 42218, 0, 0, 70094, 0, 0, 0, 71058, 0, 0, 0, 127341, 0, 0, 0, 0, 0, 43370, 0, 5016, 121052, 0, 0, 9491, 0, 0, 0, 0, 64922, 0, 0, 0, 0, 92198, 0, 0, 0, 74619, 0, 0, 70422, 983669, 10565, 0, @@ -24735,16 +24735,16 @@ static const unsigned int code_hash[] = { 374, 0, 41933, 120975, 0, 0, 41934, 7465, 0, 128168, 70666, 11151, 6101, 0, 41936, 100476, 4879, 0, 65446, 0, 0, 0, 0, 5374, 0, 128059, 127390, 0, 126618, 983575, 129146, 0, 0, 1929, 0, 12142, 0, 0, 0, 121472, 0, 12982, - 0, 5378, 0, 128679, 0, 0, 127869, 0, 0, 0, 0, 0, 78832, 74481, 0, 43262, - 100511, 2421, 0, 2324, 828, 3611, 121055, 0, 64314, 0, 0, 0, 0, 0, 0, - 7999, 0, 11217, 983261, 10634, 10942, 0, 2348, 0, 0, 0, 0, 119044, 9982, - 64324, 41240, 0, 100470, 78462, 1810, 0, 92566, 71299, 0, 0, 0, 0, 0, - 100515, 0, 0, 0, 43912, 128385, 0, 0, 0, 917850, 0, 7485, 0, 129382, - 74576, 44019, 128171, 917851, 3967, 129335, 0, 0, 0, 0, 119096, 0, 0, - 8699, 723, 83084, 966, 0, 0, 0, 128428, 78778, 2320, 0, 65740, 4968, 0, + 0, 5378, 0, 128679, 0, 0, 127869, 0, 0, 0, 0, 0, 78832, 74481, 0, 43262, + 100511, 2421, 0, 2324, 828, 3611, 121055, 0, 64314, 0, 0, 0, 0, 0, 0, + 7999, 0, 11217, 983261, 10634, 10942, 0, 2348, 0, 0, 0, 0, 119044, 9982, + 64324, 41240, 0, 100470, 78462, 1810, 0, 92566, 71299, 0, 0, 0, 0, 0, + 100515, 0, 0, 0, 43912, 128385, 0, 0, 0, 917850, 0, 7485, 0, 129382, + 74576, 44019, 128171, 917851, 3967, 129335, 0, 0, 0, 0, 119096, 0, 0, + 8699, 723, 83084, 966, 0, 0, 0, 128428, 78778, 2320, 0, 65740, 4968, 0, 0, 8075, 55276, 123589, 8047, 0, 78827, 12634, 0, 78782, 71322, 0, 12174, - 42610, 0, 0, 0, 1584, 0, 6045, 0, 0, 65218, 11559, 0, 0, 0, 124991, 0, 0, - 64418, 0, 0, 0, 0, 0, 0, 67821, 0, 13092, 0, 128365, 0, 0, 0, 0, 0, + 42610, 0, 0, 0, 1584, 0, 6045, 0, 0, 65218, 11559, 0, 0, 0, 124991, 0, 0, + 64418, 0, 0, 0, 0, 0, 0, 67821, 0, 13092, 0, 128365, 0, 0, 0, 0, 0, 11414, 0, 2531, 13034, 0, 0, 0, 13036, 0, 70866, 70198, 10394, 129979, 13037, 0, 129956, 0, 0, 100496, 120640, 41129, 0, 42850, 13035, 0, 0, 5466, 0, 0, 0, 129439, 4535, 0, 4271, 0, 0, 6769, 0, 0, 67350, 6767, 0, @@ -24972,24 +24972,24 @@ static const unsigned int code_hash[] = { 983386, 0, 120869, 3612, 0, 64376, 0, 5389, 129469, 0, 0, 2839, 9621, 582, 0, 0, 3749, 0, 7569, 0, 0, 129472, 6956, 4403, 0, 0, 3299, 0, 0, 119127, 65676, 0, 74372, 0, 983492, 7598, 69819, 42469, 42242, 1918, - 9542, 480, 7716, 0, 0, 0, 0, 0, 69918, 0, 8328, 0, 118894, 0, 0, 0, 0, - 11132, 0, 66743, 74185, 100531, 2854, 66747, 0, 65755, 0, 67120, 67119, - 65835, 67117, 66736, 67123, 67122, 67121, 9881, 100481, 65757, 100538, - 100459, 67116, 8648, 128377, 6741, 43047, 0, 13180, 0, 100487, 66754, 0, - 128946, 0, 0, 41752, 0, 8641, 100490, 125185, 100489, 100462, 100541, - 6942, 0, 1024, 42849, 41751, 0, 8941, 101034, 11121, 0, 9023, 40973, - 121476, 9928, 67109, 66865, 0, 67114, 67113, 67112, 67111, 0, 41206, - 120724, 9049, 67108, 43166, 0, 41200, 128201, 125142, 126537, 0, 0, - 41188, 119553, 0, 101007, 917548, 74585, 78626, 0, 0, 11466, 0, 120797, - 0, 125067, 2261, 0, 2860, 0, 0, 70828, 127925, 92357, 67106, 12065, - 42872, 0, 43875, 67103, 43856, 0, 67102, 67105, 7531, 40981, 2413, - 100522, 67404, 100521, 0, 67101, 41196, 100523, 0, 0, 983727, 43117, - 100495, 0, 0, 0, 0, 69876, 0, 7173, 496, 0, 4313, 64607, 0, 0, 0, 2065, - 42793, 2842, 0, 83152, 13132, 798, 0, 12801, 67098, 10686, 0, 128143, 0, - 8054, 9174, 67087, 67086, 67097, 67096, 41611, 67095, 74504, 78854, - 42512, 0, 78857, 42089, 74613, 78856, 0, 101029, 100468, 42079, 100467, - 0, 0, 100474, 0, 0, 0, 68338, 69958, 0, 0, 0, 0, 0, 78859, 42093, 128951, - 100504, 0, 0, 0, 4580, 0, 0, 0, 92167, 0, 3021, 42004, 0, 0, 42317, + 9542, 480, 7716, 0, 0, 0, 0, 0, 69918, 0, 8328, 0, 118894, 0, 0, 0, 0, + 11132, 0, 66743, 74185, 100531, 2854, 66747, 0, 65755, 0, 67120, 67119, + 65835, 67117, 66736, 67123, 67122, 67121, 9881, 100481, 65757, 100538, + 100459, 67116, 8648, 128377, 6741, 43047, 0, 13180, 0, 100487, 66754, 0, + 128946, 0, 0, 41752, 0, 8641, 100490, 125185, 100489, 100462, 100541, + 6942, 0, 1024, 42849, 41751, 0, 8941, 101034, 11121, 0, 9023, 40973, + 121476, 9928, 67109, 66865, 0, 67114, 67113, 67112, 67111, 0, 41206, + 120724, 9049, 67108, 43166, 0, 41200, 128201, 125142, 126537, 0, 0, + 41188, 119553, 0, 101007, 917548, 74585, 78626, 0, 0, 11466, 0, 120797, + 0, 125067, 2261, 0, 2860, 0, 0, 70828, 127925, 92357, 67106, 12065, + 42872, 0, 43875, 67103, 43856, 0, 67102, 67105, 7531, 40981, 2413, + 100522, 67404, 100521, 0, 67101, 41196, 100523, 0, 0, 983727, 43117, + 100495, 0, 0, 0, 0, 69876, 0, 7173, 496, 0, 4313, 64607, 0, 0, 0, 2065, + 42793, 2842, 0, 83152, 13132, 798, 0, 12801, 67098, 10686, 0, 128143, 0, + 8054, 9174, 67087, 67086, 67097, 67096, 41611, 67095, 74504, 78854, + 42512, 0, 78857, 42089, 74613, 78856, 0, 101029, 100468, 42079, 100467, + 0, 0, 100474, 0, 0, 0, 68338, 69958, 0, 0, 0, 0, 0, 78859, 42093, 128951, + 100504, 0, 0, 0, 4580, 0, 0, 0, 92167, 0, 3021, 42004, 0, 0, 42317, 41998, 0, 6946, 77920, 0, 123610, 0, 0, 0, 121442, 42690, 9880, 0, 0, 64589, 0, 0, 127880, 68035, 0, 11360, 0, 0, 72242, 0, 0, 0, 0, 0, 64941, 0, 0, 0, 0, 65671, 11244, 73706, 6959, 41994, 42907, 0, 0, 122902, 8617, @@ -25036,11 +25036,11 @@ static const unsigned int code_hash[] = { 0, 0, 0, 8856, 0, 0, 69891, 0, 120404, 120405, 120402, 120403, 120400, 120401, 12853, 43269, 7263, 120244, 6536, 120238, 120239, 65516, 12321, 120391, 120388, 55287, 2237, 120246, 9588, 120248, 120382, 120383, - 120380, 120381, 0, 0, 3561, 0, 0, 10613, 0, 0, 0, 0, 0, 128689, 5006, + 120380, 120381, 0, 0, 3561, 0, 0, 10613, 0, 0, 0, 0, 0, 128689, 5006, 64328, 68219, 917894, 0, 8825, 129880, 0, 0, 0, 128616, 0, 119177, 0, 0, - 128641, 120225, 71366, 120227, 120228, 438, 4510, 41707, 8721, 120233, - 120234, 120235, 12840, 120229, 10845, 120231, 8096, 0, 120935, 0, 0, - 65589, 8733, 0, 0, 0, 0, 0, 0, 93984, 11262, 73747, 128522, 0, 64591, + 128641, 120225, 71366, 120227, 120228, 438, 4510, 41707, 8721, 120233, + 120234, 120235, 12840, 120229, 10845, 120231, 8096, 0, 120935, 0, 0, + 65589, 8733, 0, 0, 0, 0, 0, 0, 93984, 11262, 73747, 128522, 0, 64591, 42405, 0, 0, 1632, 127982, 128326, 0, 0, 121327, 121477, 42444, 0, 0, 215, 41258, 128494, 64494, 1953, 10185, 0, 1256, 3910, 41260, 917903, 0, 0, 41257, 0, 8675, 10700, 0, 124951, 0, 9333, 0, 121471, 0, 0, 0, 0, 0, @@ -25093,9 +25093,9 @@ static const unsigned int code_hash[] = { 42256, 0, 0, 417, 0, 111347, 41565, 74965, 0, 111355, 0, 0, 0, 2284, 0, 0, 983257, 0, 0, 0, 0, 0, 0, 42273, 0, 69430, 121041, 0, 126643, 0, 65910, 0, 10246, 0, 68224, 12169, 128858, 4552, 0, 0, 0, 1375, 66705, - 128412, 0, 3329, 0, 42811, 74251, 74192, 120794, 7840, 0, 0, 65374, 0, 0, - 71072, 0, 4396, 0, 126608, 0, 10331, 125224, 0, 11543, 0, 8944, 0, 0, 0, - 0, 0, 19965, 43025, 10299, 128436, 68845, 0, 69724, 67412, 92952, 0, + 128412, 0, 3329, 0, 42811, 74251, 74192, 120794, 7840, 0, 0, 65374, 0, 0, + 71072, 0, 4396, 0, 126608, 0, 10331, 125224, 0, 11543, 0, 8944, 0, 0, 0, + 0, 0, 19965, 43025, 10299, 128436, 68845, 0, 69724, 67412, 92952, 0, 43811, 0, 128924, 0, 11062, 128748, 0, 0, 0, 69276, 2901, 7865, 0, 78354, 0, 78347, 0, 126123, 0, 66363, 0, 0, 0, 74967, 7414, 0, 0, 92691, 0, 128507, 885, 64772, 65180, 0, 71267, 852, 0, 0, 0, 78614, 121174, 129092, @@ -25403,8 +25403,8 @@ static const unsigned int code_hash[] = { 128554, 0, 0, 64258, 0, 0, 69677, 74983, 65103, 0, 125008, 42625, 0, 72022, 0, 0, 64905, 0, 9512, 0, 119076, 6443, 983262, 0, 9135, 0, 0, 123202, 0, 0, 983863, 93788, 0, 0, 0, 93767, 64256, 0, 11669, 0, 0, 4524, - 0, 129182, 128390, 0, 74266, 0, 0, 0, 70119, 78410, 69809, 121031, 55219, - 69815, 93765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2986, 0, 93763, 3437, 0, + 0, 129182, 128390, 0, 74266, 0, 0, 0, 70119, 78410, 69809, 121031, 55219, + 69815, 93765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2986, 0, 93763, 3437, 0, 6203, 4247, 0, 11920, 8274, 68240, 129694, 1657, 0, 121276, 0, 0, 2954, 43506, 42837, 0, 0, 71179, 0, 0, 0, 66476, 68450, 0, 0, 0, 43362, 983134, 129596, 11705, 0, 0, 0, 127354, 0, 11710, 0, 0, 0, 0, 74429, 0, 0, 1058, @@ -25998,21 +25998,21 @@ static const unsigned int code_hash[] = { 3208, 0, 0, 0, 0, 0, 0, 129402, 0, 0, 0, 2033, 0, 0, 0, 55254, 7740, 0, 0, 0, 128197, 0, 93988, 0, 67612, 0, 0, 41689, 129380, 0, 0, 6646, 0, 0, 0, 983945, 0, 0, 4573, 0, 0, 0, 0, 0, 92961, 0, 128222, 41688, 0, 0, 0, - 8314, 0, 0, 0, 0, 0, 66721, 0, 0, 121033, 0, 128226, 0, 0, 0, 13164, 0, - 66237, 983963, 0, 0, 0, 3257, 0, 0, 1845, 0, 0, 0, 0, 128783, 0, 0, 0, 0, - 3499, 8609, 0, 7145, 0, 0, 0, 0, 74829, 983988, 983291, 0, 0, 0, 7591, 0, + 8314, 0, 0, 0, 0, 0, 66721, 0, 0, 121033, 0, 128226, 0, 0, 0, 13164, 0, + 66237, 983963, 0, 0, 0, 3257, 0, 0, 1845, 0, 0, 0, 0, 128783, 0, 0, 0, 0, + 3499, 8609, 0, 7145, 0, 0, 0, 0, 74829, 983988, 983291, 0, 0, 0, 7591, 0, 0, 0, 73778, 70132, 128167, 0, 0, 0, 0, 119261, 0, 0, 0, 13083, 0, 0, 0, - 0, 66177, 983269, 5429, 0, 0, 68168, 66181, 0, 0, 983253, 0, 0, 5433, - 67659, 0, 42776, 1547, 66176, 92428, 0, 5425, 4977, 9999, 0, 5423, 64560, - 125094, 0, 0, 0, 74122, 0, 0, 0, 128003, 4418, 66199, 0, 92300, 0, 0, 0, - 92224, 124995, 0, 11908, 0, 9360, 125101, 983202, 0, 66187, 12837, - 983288, 0, 11112, 0, 92321, 43318, 0, 0, 0, 0, 126518, 120604, 0, 983286, + 0, 66177, 983269, 5429, 0, 0, 68168, 66181, 0, 0, 983253, 0, 0, 5433, + 67659, 0, 42776, 1547, 66176, 92428, 0, 5425, 4977, 9999, 0, 5423, 64560, + 125094, 0, 0, 0, 74122, 0, 0, 0, 128003, 4418, 66199, 0, 92300, 0, 0, 0, + 92224, 124995, 0, 11908, 0, 9360, 125101, 983202, 0, 66187, 12837, + 983288, 0, 11112, 0, 92321, 43318, 0, 0, 0, 0, 126518, 120604, 0, 983286, 0, 129595, 0, 983782, 0, 9958, 0, 125108, 0, 0, 0, 2433, 128602, 0, 3352, - 0, 0, 0, 0, 0, 0, 305, 567, 67662, 0, 69979, 65242, 0, 41695, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 305, 567, 67662, 0, 69979, 65242, 0, 41695, 0, 0, 0, 7837, 917625, 129002, 5337, 917622, 7325, 43312, 917619, 68742, 917617, - 74086, 68777, 917614, 917613, 10973, 917611, 1372, 128768, 917608, - 917607, 1254, 917605, 917604, 93967, 917602, 65228, 113753, 0, 67723, - 8068, 0, 0, 983951, 0, 3245, 64393, 119069, 0, 0, 0, 0, 0, 0, 0, 983279, + 74086, 68777, 917614, 917613, 10973, 917611, 1372, 128768, 917608, + 917607, 1254, 917605, 917604, 93967, 917602, 65228, 113753, 0, 67723, + 8068, 0, 0, 983951, 0, 3245, 64393, 119069, 0, 0, 0, 0, 0, 0, 0, 983279, 0, 119563, 129935, 78865, 0, 126638, 0, 0, 43322, 0, 0, 0, 0, 92698, 3226, 67695, 0, 0, 983939, 10200, 0, 128779, 101143, 0, 65610, 0, 0, 0, 3585, 250, 101142, 43320, 0, 0, 0, 0, 1152, 129849, 1688, 0, 0, 0, 0, 0, @@ -26045,12 +26045,12 @@ static const unsigned int code_hash[] = { 4667, 0, 983944, 8828, 0, 0, 0, 4746, 0, 129840, 2269, 4749, 0, 100598, 65192, 4744, 7345, 0, 242, 100595, 0, 8217, 0, 68919, 0, 2245, 0, 0, 66790, 10850, 0, 0, 0, 0, 0, 129853, 64680, 0, 0, 120562, 0, 127324, 0, - 100551, 128721, 0, 7316, 0, 983610, 100552, 74157, 1646, 0, 0, 73995, - 120857, 129047, 0, 7350, 0, 0, 0, 9099, 4107, 3441, 0, 2975, 194701, 0, - 983947, 55220, 10084, 73943, 120845, 0, 0, 0, 3399, 0, 0, 11909, 0, 0, - 7687, 0, 6789, 0, 0, 72739, 71367, 0, 0, 92589, 9151, 1137, 0, 749, - 129320, 125076, 5385, 0, 69387, 0, 0, 41298, 0, 69461, 0, 0, 0, 0, 0, 0, - 128455, 0, 519, 0, 64547, 5766, 0, 0, 0, 8848, 0, 41297, 0, 0, 0, 41300, + 100551, 128721, 0, 7316, 0, 983610, 100552, 74157, 1646, 0, 0, 73995, + 120857, 129047, 0, 7350, 0, 0, 0, 9099, 4107, 3441, 0, 2975, 194701, 0, + 983947, 55220, 10084, 73943, 120845, 0, 0, 0, 3399, 0, 0, 11909, 0, 0, + 7687, 0, 6789, 0, 0, 72739, 71367, 0, 0, 92589, 9151, 1137, 0, 749, + 129320, 125076, 5385, 0, 69387, 0, 0, 41298, 0, 69461, 0, 0, 0, 0, 0, 0, + 128455, 0, 519, 0, 64547, 5766, 0, 0, 0, 8848, 0, 41297, 0, 0, 0, 41300, 74468, 65160, 0, 129839, 127511, 0, 0, 6558, 0, 0, 128686, 92775, 0, 71450, 41302, 127927, 0, 0, 128646, 68762, 11729, 8719, 9060, 0, 128796, 0, 0, 0, 129682, 0, 11734, 93011, 11730, 73450, 9593, 5757, 2403, 0, @@ -26401,8 +26401,8 @@ static const unsigned int code_hash[] = { 83451, 83452, 65100, 120508, 8224, 917873, 917874, 917879, 917880, 917877, 917878, 128929, 0, 917881, 917882, 5365, 67836, 8901, 0, 0, 129951, 0, 69257, 5925, 83436, 64330, 128400, 83431, 83432, 83433, 83434, - 83427, 83428, 83429, 83430, 64928, 10543, 0, 0, 83446, 414, 0, 0, 83442, - 6456, 83444, 83445, 11905, 83439, 66284, 83441, 0, 68337, 0, 83437, + 83427, 83428, 83429, 83430, 64928, 10543, 0, 0, 83446, 414, 0, 0, 83442, + 6456, 83444, 83445, 11905, 83439, 66284, 83441, 0, 68337, 0, 83437, 43832, 983139, 9751, 0, 128085, 11770, 0, 0, 69600, 65061, 0, 0, 0, 0, 0, 0, 121087, 0, 0, 69924, 0, 0, 0, 69913, 0, 121387, 101513, 101504, 101512, 42038, 387, 0, 12737, 0, 0, 43368, 0, 0, 0, 0, 129713, 129449, @@ -26583,9 +26583,9 @@ static const unsigned int code_hash[] = { 194819, 5297, 194821, 13284, 6112, 93964, 93010, 73927, 42947, 0, 65746, 0, 0, 194827, 194826, 4342, 42839, 194831, 1677, 0, 72135, 0, 0, 0, 11011, 66399, 0, 0, 0, 10160, 0, 0, 0, 0, 2052, 4308, 92174, 43000, 0, - 543, 64916, 0, 0, 0, 119170, 0, 118922, 2064, 0, 43158, 0, 0, 69984, 0, - 0, 129187, 0, 0, 0, 0, 41631, 92728, 0, 0, 6228, 0, 0, 0, 0, 0, 0, 506, - 0, 0, 65735, 2055, 43255, 121407, 0, 0, 0, 0, 0, 0, 194666, 2063, 0, 0, + 543, 64916, 0, 0, 0, 119170, 0, 118922, 2064, 0, 43158, 0, 0, 69984, 0, + 0, 129187, 0, 0, 0, 0, 41631, 92728, 0, 0, 6228, 0, 0, 0, 0, 0, 0, 506, + 0, 0, 65735, 2055, 43255, 121407, 0, 0, 0, 0, 0, 0, 194666, 2063, 0, 0, 0, 0, 72136, 0, 74333, 194912, 11827, 74308, 194913, 194916, 194915, 64564, 194917, 67986, 194919, 0, 11037, 0, 121102, 0, 0, 10560, 0, 120756, 194922, 113737, 194924, 194927, 120495, 1931, 0, 0, 0, 128228, 0, @@ -26595,13 +26595,13 @@ static const unsigned int code_hash[] = { 6914, 93013, 0, 119569, 0, 65188, 0, 67611, 4337, 0, 194897, 194896, 78516, 194898, 7681, 194900, 194903, 67596, 194905, 194904, 2477, 93974, 0, 0, 0, 67604, 70705, 0, 194882, 194881, 194884, 194883, 194886, 128914, - 194888, 67599, 0, 194889, 0, 0, 0, 0, 3357, 0, 78852, 4207, 1288, 78842, - 78839, 78840, 78837, 78838, 66354, 194872, 0, 128432, 0, 67618, 92664, 0, + 194888, 67599, 0, 194889, 0, 0, 0, 0, 3357, 0, 78852, 4207, 1288, 78842, + 78839, 78840, 78837, 78838, 66354, 194872, 0, 128432, 0, 67618, 92664, 0, 42788, 0, 64612, 129897, 10774, 194877, 0, 194879, 0, 0, 0, 997, 194901, - 0, 92577, 0, 11440, 11379, 42000, 13139, 0, 0, 74030, 72293, 73796, 0, 0, + 0, 92577, 0, 11440, 11379, 42000, 13139, 0, 0, 74030, 72293, 73796, 0, 0, 0, 0, 2818, 0, 0, 73793, 0, 4172, 93028, 126523, 124981, 0, 129896, 0, 0, - 129522, 69706, 0, 6834, 0, 0, 194865, 126982, 121211, 194866, 194869, - 194868, 766, 1257, 0, 0, 0, 3265, 66617, 3274, 0, 0, 94042, 0, 8373, + 129522, 69706, 0, 6834, 0, 0, 194865, 126982, 121211, 194866, 194869, + 194868, 766, 1257, 0, 0, 0, 3265, 66617, 3274, 0, 0, 94042, 0, 8373, 41989, 0, 73460, 3418, 3263, 0, 0, 0, 3270, 64539, 11489, 0, 118945, 126220, 0, 127795, 0, 94031, 0, 0, 0, 0, 0, 70512, 983964, 186, 0, 119156, 5770, 13179, 0, 12612, 12949, 64856, 12800, 0, 0, 983151, 11507, @@ -27155,11 +27155,11 @@ static const unsigned int code_hash[] = { 70752, 101097, 101096, 0, 0, 0, 64448, 0, 43920, 70677, 0, 6232, 101101, 101104, 101103, 43608, 101105, 101108, 6538, 4335, 0, 3941, 74986, 11061, 0, 74988, 74987, 0, 12155, 128278, 0, 0, 0, 0, 74578, 0, 65832, 0, - 129459, 70789, 0, 125050, 0, 0, 350, 10951, 101081, 509, 101083, 101086, - 101085, 0, 0, 0, 917540, 0, 100905, 110970, 12162, 64741, 0, 9354, 0, - 70802, 100901, 2496, 11516, 944, 128238, 0, 0, 1438, 0, 0, 120185, 70785, - 1220, 917952, 93844, 0, 0, 5008, 42630, 70787, 101087, 101090, 68206, - 564, 0, 312, 0, 0, 0, 70797, 8877, 269, 0, 128065, 9617, 0, 0, 100910, 0, + 129459, 70789, 0, 125050, 0, 0, 350, 10951, 101081, 509, 101083, 101086, + 101085, 0, 0, 0, 917540, 0, 100905, 110970, 12162, 64741, 0, 9354, 0, + 70802, 100901, 2496, 11516, 944, 128238, 0, 0, 1438, 0, 0, 120185, 70785, + 1220, 917952, 93844, 0, 0, 5008, 42630, 70787, 101087, 101090, 68206, + 564, 0, 312, 0, 0, 0, 70797, 8877, 269, 0, 128065, 9617, 0, 0, 100910, 0, 0, 10862, 0, 0, 41416, 0, 4173, 0, 0, 0, 1906, 983835, 41418, 74073, 101068, 101067, 41415, 69622, 9582, 0, 64287, 0, 0, 11428, 1730, 0, 0, 19918, 10469, 101076, 101079, 68088, 0, 101080, 72342, 0, 129692, 0, @@ -27196,13 +27196,13 @@ static const unsigned int code_hash[] = { 128515, 0, 9677, 0, 70867, 74175, 0, 74070, 0, 0, 365, 0, 43027, 0, 0, 128236, 0, 119574, 70284, 13151, 0, 0, 127935, 127950, 544, 13249, 119018, 0, 120846, 0, 0, 73671, 65339, 73000, 2211, 0, 0, 0, 0, 0, 0, 0, - 0, 128037, 0, 0, 0, 0, 0, 0, 0, 127188, 0, 69708, 9638, 0, 100878, 0, 0, - 0, 74545, 128820, 128819, 75062, 128963, 0, 0, 0, 11264, 43994, 0, 0, 0, - 1311, 0, 0, 0, 0, 13068, 0, 0, 78164, 78155, 0, 949, 0, 0, 0, 78176, + 0, 128037, 0, 0, 0, 0, 0, 0, 0, 127188, 0, 69708, 9638, 0, 100878, 0, 0, + 0, 74545, 128820, 128819, 75062, 128963, 0, 0, 0, 11264, 43994, 0, 0, 0, + 1311, 0, 0, 0, 0, 13068, 0, 0, 78164, 78155, 0, 949, 0, 0, 0, 78176, 69709, 78177, 63828, 0, 0, 0, 70282, 0, 0, 0, 64822, 0, 6530, 983270, 0, 70493, 0, 129325, 0, 0, 4431, 118839, 127490, 983741, 73667, 127986, 0, - 10336, 10400, 0, 0, 92959, 0, 0, 0, 42270, 128880, 6428, 0, 0, 0, 0, - 43455, 0, 43526, 100888, 12835, 129501, 9493, 0, 0, 11793, 0, 127897, + 10336, 10400, 0, 0, 92959, 0, 0, 0, 42270, 128880, 6428, 0, 0, 0, 0, + 43455, 0, 43526, 100888, 12835, 129501, 9493, 0, 0, 11793, 0, 127897, 74394, 0, 10653, 0, 0, 0, 0, 6560, 7016, 74274, 983627, 43556, 3929, 123615, 6614, 2768, 0, 65609, 0, 11811, 129696, 0, 0, 127513, 0, 6554, 0, 6305, 66283, 4675, 118826, 78552, 0, 0, 74361, 0, 0, 68108, 0, 0, 92232, @@ -27316,10 +27316,10 @@ static const unsigned int code_hash[] = { 68843, 0, 68850, 0, 92388, 92267, 128536, 65577, 92213, 0, 127518, 11650, 5013, 92663, 68810, 92568, 118914, 6613, 74371, 0, 0, 0, 0, 64714, 71479, 0, 983778, 12120, 0, 0, 43124, 0, 0, 78037, 69263, 0, 126219, 0, 0, 1837, - 125086, 0, 0, 0, 127210, 4952, 65718, 64405, 5504, 65720, 65714, 65715, + 125086, 0, 0, 0, 127210, 4952, 65718, 64405, 5504, 65720, 65714, 65715, 65716, 10403, 127005, 0, 41449, 0, 74028, 72019, 0, 119234, 1127, 455, 0, 0, 72860, 3483, 0, 1989, 0, 69678, 9104, 0, 65375, 0, 0, 0, 1864, 0, - 72810, 8107, 2540, 0, 0, 11257, 128807, 119576, 0, 120999, 0, 0, 8604, 0, + 72810, 8107, 2540, 0, 0, 11257, 128807, 119576, 0, 120999, 0, 0, 8604, 0, 0, 0, 0, 128270, 0, 0, 3115, 0, 10106, 127862, 118842, 101136, 0, 9631, 0, 0, 0, 0, 0, 0, 0, 258, 129079, 0, 0, 0, 92292, 0, 70699, 0, 11478, 0, 129640, 11522, 0, 8549, 0, 128430, 0, 0, 0, 0, 0, 0, 123140, 0, 0, 0, @@ -27394,13 +27394,13 @@ static const unsigned int code_hash[] = { 73700, 12747, 0, 0, 128064, 43153, 74640, 0, 0, 43150, 0, 983090, 983088, 66779, 66777, 10813, 2592, 43139, 0, 0, 118870, 0, 0, 71891, 0, 0, 0, 0, 0, 0, 71697, 0, 128825, 1596, 0, 0, 0, 0, 6838, 66572, 0, 126574, 120627, - 8092, 12805, 41928, 0, 78406, 78409, 0, 0, 0, 9931, 0, 0, 0, 0, 0, - 983759, 6107, 0, 0, 0, 0, 128745, 0, 335, 127003, 64689, 0, 0, 5765, 0, - 0, 119227, 6092, 118851, 0, 8876, 83465, 74947, 83455, 129186, 83454, - 70713, 0, 0, 126606, 70121, 41602, 0, 92308, 74831, 0, 11783, 68482, 0, - 0, 0, 0, 0, 0, 843, 0, 71099, 0, 0, 41935, 0, 0, 0, 0, 1371, 0, 43818, - 43159, 8069, 9579, 41938, 41608, 0, 92444, 6242, 0, 0, 128595, 128244, 0, - 92499, 8805, 1742, 113722, 0, 8202, 72399, 0, 983197, 0, 0, 73882, + 8092, 12805, 41928, 0, 78406, 78409, 0, 0, 0, 9931, 0, 0, 0, 0, 0, + 983759, 6107, 0, 0, 0, 0, 128745, 0, 335, 127003, 64689, 0, 0, 5765, 0, + 0, 119227, 6092, 118851, 0, 8876, 83465, 74947, 83455, 129186, 83454, + 70713, 0, 0, 126606, 70121, 41602, 0, 92308, 74831, 0, 11783, 68482, 0, + 0, 0, 0, 0, 0, 843, 0, 71099, 0, 0, 41935, 0, 0, 0, 0, 1371, 0, 43818, + 43159, 8069, 9579, 41938, 41608, 0, 92444, 6242, 0, 0, 128595, 128244, 0, + 92499, 8805, 1742, 113722, 0, 8202, 72399, 0, 983197, 0, 0, 73882, 100809, 0, 43467, 123636, 55290, 0, 1712, 5932, 0, 41762, 71982, 0, 11967, 1775, 0, 75009, 0, 120398, 120387, 9458, 0, 126614, 0, 0, 43176, 101032, 101031, 42782, 101033, 101036, 101035, 101038, 101037, 101040, @@ -27471,14 +27471,14 @@ static const unsigned int code_hash[] = { 0, 0, 0, 127906, 0, 64944, 0, 0, 0, 0, 5924, 5920, 129508, 6921, 78081, 74007, 78078, 8418, 11681, 43169, 10176, 0, 0, 0, 78087, 10772, 65276, 5937, 1914, 78084, 11682, 0, 0, 0, 11685, 0, 100513, 7772, 11680, 100514, - 100517, 100516, 100519, 7417, 718, 100520, 70083, 100500, 120718, 3235, - 0, 43164, 0, 8018, 0, 0, 128708, 6937, 67672, 128508, 0, 10067, 120849, - 0, 0, 0, 0, 0, 100491, 0, 100493, 100492, 13116, 100494, 100497, 9945, - 100499, 100498, 0, 0, 0, 0, 2059, 0, 100502, 100501, 1431, 100503, 66565, - 100505, 100508, 12804, 100510, 100509, 78090, 3307, 78088, 78089, 0, - 4544, 71228, 0, 0, 0, 78097, 11110, 66810, 12882, 64511, 78094, 78100, - 78102, 71226, 10141, 0, 78280, 65298, 4476, 78109, 94005, 71216, 8907, - 78105, 78106, 78103, 78104, 120898, 0, 10665, 64616, 128944, 0, 127545, + 100517, 100516, 100519, 7417, 718, 100520, 70083, 100500, 120718, 3235, + 0, 43164, 0, 8018, 0, 0, 128708, 6937, 67672, 128508, 0, 10067, 120849, + 0, 0, 0, 0, 0, 100491, 0, 100493, 100492, 13116, 100494, 100497, 9945, + 100499, 100498, 0, 0, 0, 0, 2059, 0, 100502, 100501, 1431, 100503, 66565, + 100505, 100508, 12804, 100510, 100509, 78090, 3307, 78088, 78089, 0, + 4544, 71228, 0, 0, 0, 78097, 11110, 66810, 12882, 64511, 78094, 78100, + 78102, 71226, 10141, 0, 78280, 65298, 4476, 78109, 94005, 71216, 8907, + 78105, 78106, 78103, 78104, 120898, 0, 10665, 64616, 128944, 0, 127545, 69605, 83159, 83160, 4554, 0, 83155, 83156, 83157, 83158, 0, 125123, 0, 72258, 129831, 0, 129815, 0, 43179, 0, 0, 0, 717, 10754, 83168, 83169, 83162, 83163, 83164, 83165, 78282, 0, 0, 83161, 68848, 10611, 72859, @@ -27677,10 +27677,10 @@ static const unsigned int code_hash[] = { 11036, 65252, 120795, 129488, 0, 0, 0, 0, 0, 0, 8887, 0, 7295, 71203, 0, 127221, 0, 0, 0, 0, 8755, 0, 0, 8147, 73127, 0, 0, 121348, 0, 129377, 0, 74499, 0, 0, 0, 4619, 0, 6654, 123192, 0, 0, 0, 65689, 10128, 0, 129612, - 0, 0, 92651, 0, 2401, 0, 8792, 0, 0, 74980, 0, 92246, 0, 0, 0, 12886, 0, - 66624, 0, 0, 74133, 65170, 0, 74135, 0, 0, 9984, 73867, 3010, 0, 70349, - 10698, 41475, 0, 119151, 0, 119152, 0, 0, 9100, 0, 0, 0, 78116, 64780, - 2001, 0, 55230, 0, 4052, 0, 7626, 78080, 0, 0, 0, 41477, 0, 0, 0, 43707, + 0, 0, 92651, 0, 2401, 0, 8792, 0, 0, 74980, 0, 92246, 0, 0, 0, 12886, 0, + 66624, 0, 0, 74133, 65170, 0, 74135, 0, 0, 9984, 73867, 3010, 0, 70349, + 10698, 41475, 0, 119151, 0, 119152, 0, 0, 9100, 0, 0, 0, 78116, 64780, + 2001, 0, 55230, 0, 4052, 0, 7626, 78080, 0, 0, 0, 41477, 0, 0, 0, 43707, 74127, 0, 0, 0, 78086, 73758, 2335, 10663, 0, 0, 129872, 119602, 0, 0, 70325, 0, 41443, 0, 0, 0, 9711, 1523, 0, 0, 41445, 0, 0, 8567, 41442, 12821, 0, 0, 118978, 0, 65274, 0, 94082, 0, 127515, 0, 0, 43446, 0, 0, 0, @@ -27894,7 +27894,7 @@ static const unsigned int code_hash[] = { 0, 0, 101499, 72282, 126991, 71113, 0, 0, 129340, 9489, 0, 70843, 0, 0, 0, 0, 128030, 13295, 43191, 0, 0, 1154, 0, 1205, 0, 0, 0, 12958, 0, 0, 0, 70846, 0, 10592, 0, 495, 0, 41712, 7983, 0, 0, 0, 6347, 69465, 7654, - 41710, 4196, 0, 0, 41709, 73772, 70832, 0, 9465, 983764, 0, 0, 917612, 0, + 41710, 4196, 0, 0, 41709, 73772, 70832, 0, 9465, 983764, 0, 0, 917612, 0, 0, 41714, 0, 0, 0, 6343, 0, 0, 43996, 0, 8044, 0, 0, 41789, 0, 10809, 71953, 0, 0, 0, 8146, 11025, 0, 120513, 642, 0, 0, 0, 12875, 0, 0, 13229, 71950, 41788, 0, 0, 0, 41791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8428, 6569, @@ -28085,9 +28085,9 @@ static const unsigned int code_hash[] = { 118979, 126075, 2434, 94018, 0, 120579, 0, 4631, 0, 0, 6407, 0, 19931, 0, 0, 0, 0, 3192, 0, 8414, 0, 0, 0, 0, 0, 9164, 66612, 93959, 8228, 0, 0, 0, 0, 78624, 0, 0, 9993, 0, 0, 129350, 78631, 78632, 78629, 78630, 78627, - 78628, 78625, 2399, 0, 92399, 71202, 41208, 0, 0, 8178, 2149, 3367, 0, - 78640, 78641, 78636, 78638, 78634, 6337, 0, 92342, 0, 0, 11068, 0, 9331, - 0, 74798, 9181, 0, 0, 8017, 0, 0, 0, 0, 0, 0, 0, 12126, 129184, 129306, + 78628, 78625, 2399, 0, 92399, 71202, 41208, 0, 0, 8178, 2149, 3367, 0, + 78640, 78641, 78636, 78638, 78634, 6337, 0, 92342, 0, 0, 11068, 0, 9331, + 0, 74798, 9181, 0, 0, 8017, 0, 0, 0, 0, 0, 0, 0, 12126, 129184, 129306, 0, 0, 69650, 0, 0, 0, 43436, 983725, 0, 0, 0, 0, 66845, 69249, 0, 0, 5398, 0, 127386, 93953, 0, 0, 0, 0, 0, 9476, 68899, 0, 12763, 0, 74788, 0, 42114, 11181, 92502, 0, 0, 0, 3469, 42107, 42116, 0, 0, 0, 0, 9853, @@ -28709,8 +28709,8 @@ static const unsigned int code_hash[] = { 4786, 127991, 4185, 0, 128742, 0, 983193, 73978, 0, 4593, 0, 120584, 0, 0, 110715, 10532, 110713, 110714, 110711, 110712, 64759, 1325, 5166, 9888, 0, 5148, 0, 0, 78205, 78206, 64140, 78204, 64131, 3119, 917814, 0, - 983433, 917820, 12095, 0, 0, 636, 128002, 0, 983464, 0, 78531, 7836, - 42741, 64137, 0, 118969, 0, 92431, 0, 0, 0, 0, 0, 8618, 0, 41384, 0, 0, + 983433, 917820, 12095, 0, 0, 636, 128002, 0, 983464, 0, 78531, 7836, + 42741, 64137, 0, 118969, 0, 92431, 0, 0, 0, 0, 0, 8618, 0, 41384, 0, 0, 0, 3937, 12312, 128261, 0, 0, 0, 912, 6349, 4536, 71964, 0, 126594, 0, 0, 0, 3935, 120665, 0, 0, 0, 0, 118859, 0, 121116, 0, 0, 12046, 12599, 0, 0, 0, 0, 7227, 0, 0, 0, 983066, 0, 0, 0, 113817, 0, 78246, 0, 0, 0, 0, 0, @@ -28982,933 +28982,933 @@ static const unsigned int code_hash[] = { 70459, 0, 124975, 0, 3059, 0, 0, 43491, 983814, 0, 0, 127993, 4100, 920, 1811, 1355, 0, 0, 64383, 10078, 69398, 0, 0, 0, 65870, 0, 129565, 0, 72400, 42918, 0, 66789, 0, 12865, 0, 73938, -}; - -#define code_magic 47 -#define code_size 65536 -#define code_poly 65581 - -static const unsigned int aliases_start = 0xf0000; -static const unsigned int aliases_end = 0xf01d4; -static const unsigned int name_aliases[] = { - 0x0000, - 0x0000, - 0x0001, - 0x0001, - 0x0002, - 0x0002, - 0x0003, - 0x0003, - 0x0004, - 0x0004, - 0x0005, - 0x0005, - 0x0006, - 0x0006, - 0x0007, - 0x0007, - 0x0008, - 0x0008, - 0x0009, - 0x0009, - 0x0009, - 0x0009, - 0x000A, - 0x000A, - 0x000A, - 0x000A, - 0x000A, - 0x000A, - 0x000B, - 0x000B, - 0x000B, - 0x000C, - 0x000C, - 0x000D, - 0x000D, - 0x000E, - 0x000E, - 0x000E, - 0x000F, - 0x000F, - 0x000F, - 0x0010, - 0x0010, - 0x0011, - 0x0011, - 0x0012, - 0x0012, - 0x0013, - 0x0013, - 0x0014, - 0x0014, - 0x0015, - 0x0015, - 0x0016, - 0x0016, - 0x0017, - 0x0017, - 0x0018, - 0x0018, - 0x0019, - 0x0019, - 0x001A, - 0x001A, - 0x001B, - 0x001B, - 0x001C, - 0x001C, - 0x001C, - 0x001D, - 0x001D, - 0x001D, - 0x001E, - 0x001E, - 0x001E, - 0x001F, - 0x001F, - 0x001F, - 0x0020, - 0x007F, - 0x007F, - 0x0080, - 0x0080, - 0x0081, - 0x0081, - 0x0082, - 0x0082, - 0x0083, - 0x0083, - 0x0084, - 0x0084, - 0x0085, - 0x0085, - 0x0086, - 0x0086, - 0x0087, - 0x0087, - 0x0088, - 0x0088, - 0x0088, - 0x0089, - 0x0089, - 0x0089, - 0x008A, - 0x008A, - 0x008A, - 0x008B, - 0x008B, - 0x008B, - 0x008C, - 0x008C, - 0x008C, - 0x008D, - 0x008D, - 0x008D, - 0x008E, - 0x008E, - 0x008E, - 0x008F, - 0x008F, - 0x008F, - 0x0090, - 0x0090, - 0x0091, - 0x0091, - 0x0091, - 0x0092, - 0x0092, - 0x0092, - 0x0093, - 0x0093, - 0x0094, - 0x0094, - 0x0095, - 0x0095, - 0x0096, - 0x0096, - 0x0096, - 0x0097, - 0x0097, - 0x0097, - 0x0098, - 0x0098, - 0x0099, - 0x0099, - 0x009A, - 0x009A, - 0x009B, - 0x009B, - 0x009C, - 0x009C, - 0x009D, - 0x009D, - 0x009E, - 0x009E, - 0x009F, - 0x009F, - 0x00A0, - 0x00AD, - 0x01A2, - 0x01A3, - 0x034F, - 0x061C, - 0x0709, - 0x0CDE, - 0x0E9D, - 0x0E9F, - 0x0EA3, - 0x0EA5, - 0x0FD0, - 0x11EC, - 0x11ED, - 0x11EE, - 0x11EF, - 0x180B, - 0x180C, - 0x180D, - 0x180E, - 0x200B, - 0x200C, - 0x200D, - 0x200E, - 0x200F, - 0x202A, - 0x202B, - 0x202C, - 0x202D, - 0x202E, - 0x202F, - 0x205F, - 0x2060, - 0x2066, - 0x2067, - 0x2068, - 0x2069, - 0x2118, - 0x2448, - 0x2449, - 0x2B7A, - 0x2B7C, - 0xA015, - 0xFE00, - 0xFE01, - 0xFE02, - 0xFE03, - 0xFE04, - 0xFE05, - 0xFE06, - 0xFE07, - 0xFE08, - 0xFE09, - 0xFE0A, - 0xFE0B, - 0xFE0C, - 0xFE0D, - 0xFE0E, - 0xFE0F, - 0xFE18, - 0xFEFF, - 0xFEFF, - 0xFEFF, - 0x122D4, - 0x122D5, - 0x16E56, - 0x16E57, - 0x16E76, - 0x16E77, - 0x1B001, - 0x1D0C5, - 0xE0100, - 0xE0101, - 0xE0102, - 0xE0103, - 0xE0104, - 0xE0105, - 0xE0106, - 0xE0107, - 0xE0108, - 0xE0109, - 0xE010A, - 0xE010B, - 0xE010C, - 0xE010D, - 0xE010E, - 0xE010F, - 0xE0110, - 0xE0111, - 0xE0112, - 0xE0113, - 0xE0114, - 0xE0115, - 0xE0116, - 0xE0117, - 0xE0118, - 0xE0119, - 0xE011A, - 0xE011B, - 0xE011C, - 0xE011D, - 0xE011E, - 0xE011F, - 0xE0120, - 0xE0121, - 0xE0122, - 0xE0123, - 0xE0124, - 0xE0125, - 0xE0126, - 0xE0127, - 0xE0128, - 0xE0129, - 0xE012A, - 0xE012B, - 0xE012C, - 0xE012D, - 0xE012E, - 0xE012F, - 0xE0130, - 0xE0131, - 0xE0132, - 0xE0133, - 0xE0134, - 0xE0135, - 0xE0136, - 0xE0137, - 0xE0138, - 0xE0139, - 0xE013A, - 0xE013B, - 0xE013C, - 0xE013D, - 0xE013E, - 0xE013F, - 0xE0140, - 0xE0141, - 0xE0142, - 0xE0143, - 0xE0144, - 0xE0145, - 0xE0146, - 0xE0147, - 0xE0148, - 0xE0149, - 0xE014A, - 0xE014B, - 0xE014C, - 0xE014D, - 0xE014E, - 0xE014F, - 0xE0150, - 0xE0151, - 0xE0152, - 0xE0153, - 0xE0154, - 0xE0155, - 0xE0156, - 0xE0157, - 0xE0158, - 0xE0159, - 0xE015A, - 0xE015B, - 0xE015C, - 0xE015D, - 0xE015E, - 0xE015F, - 0xE0160, - 0xE0161, - 0xE0162, - 0xE0163, - 0xE0164, - 0xE0165, - 0xE0166, - 0xE0167, - 0xE0168, - 0xE0169, - 0xE016A, - 0xE016B, - 0xE016C, - 0xE016D, - 0xE016E, - 0xE016F, - 0xE0170, - 0xE0171, - 0xE0172, - 0xE0173, - 0xE0174, - 0xE0175, - 0xE0176, - 0xE0177, - 0xE0178, - 0xE0179, - 0xE017A, - 0xE017B, - 0xE017C, - 0xE017D, - 0xE017E, - 0xE017F, - 0xE0180, - 0xE0181, - 0xE0182, - 0xE0183, - 0xE0184, - 0xE0185, - 0xE0186, - 0xE0187, - 0xE0188, - 0xE0189, - 0xE018A, - 0xE018B, - 0xE018C, - 0xE018D, - 0xE018E, - 0xE018F, - 0xE0190, - 0xE0191, - 0xE0192, - 0xE0193, - 0xE0194, - 0xE0195, - 0xE0196, - 0xE0197, - 0xE0198, - 0xE0199, - 0xE019A, - 0xE019B, - 0xE019C, - 0xE019D, - 0xE019E, - 0xE019F, - 0xE01A0, - 0xE01A1, - 0xE01A2, - 0xE01A3, - 0xE01A4, - 0xE01A5, - 0xE01A6, - 0xE01A7, - 0xE01A8, - 0xE01A9, - 0xE01AA, - 0xE01AB, - 0xE01AC, - 0xE01AD, - 0xE01AE, - 0xE01AF, - 0xE01B0, - 0xE01B1, - 0xE01B2, - 0xE01B3, - 0xE01B4, - 0xE01B5, - 0xE01B6, - 0xE01B7, - 0xE01B8, - 0xE01B9, - 0xE01BA, - 0xE01BB, - 0xE01BC, - 0xE01BD, - 0xE01BE, - 0xE01BF, - 0xE01C0, - 0xE01C1, - 0xE01C2, - 0xE01C3, - 0xE01C4, - 0xE01C5, - 0xE01C6, - 0xE01C7, - 0xE01C8, - 0xE01C9, - 0xE01CA, - 0xE01CB, - 0xE01CC, - 0xE01CD, - 0xE01CE, - 0xE01CF, - 0xE01D0, - 0xE01D1, - 0xE01D2, - 0xE01D3, - 0xE01D4, - 0xE01D5, - 0xE01D6, - 0xE01D7, - 0xE01D8, - 0xE01D9, - 0xE01DA, - 0xE01DB, - 0xE01DC, - 0xE01DD, - 0xE01DE, - 0xE01DF, - 0xE01E0, - 0xE01E1, - 0xE01E2, - 0xE01E3, - 0xE01E4, - 0xE01E5, - 0xE01E6, - 0xE01E7, - 0xE01E8, - 0xE01E9, - 0xE01EA, - 0xE01EB, - 0xE01EC, - 0xE01ED, - 0xE01EE, - 0xE01EF, -}; - -typedef struct NamedSequence { - int seqlen; - Py_UCS2 seq[4]; -} named_sequence; - -static const unsigned int named_sequences_start = 0xf0200; -static const unsigned int named_sequences_end = 0xf03ba; -static const named_sequence named_sequences[] = { - {3, {0x0023, 0xFE0F, 0x20E3}}, - {3, {0x002A, 0xFE0F, 0x20E3}}, - {3, {0x0030, 0xFE0F, 0x20E3}}, - {3, {0x0031, 0xFE0F, 0x20E3}}, - {3, {0x0032, 0xFE0F, 0x20E3}}, - {3, {0x0033, 0xFE0F, 0x20E3}}, - {3, {0x0034, 0xFE0F, 0x20E3}}, - {3, {0x0035, 0xFE0F, 0x20E3}}, - {3, {0x0036, 0xFE0F, 0x20E3}}, - {3, {0x0037, 0xFE0F, 0x20E3}}, - {3, {0x0038, 0xFE0F, 0x20E3}}, - {3, {0x0039, 0xFE0F, 0x20E3}}, - {2, {0x0100, 0x0300}}, - {2, {0x0101, 0x0300}}, +}; + +#define code_magic 47 +#define code_size 65536 +#define code_poly 65581 + +static const unsigned int aliases_start = 0xf0000; +static const unsigned int aliases_end = 0xf01d4; +static const unsigned int name_aliases[] = { + 0x0000, + 0x0000, + 0x0001, + 0x0001, + 0x0002, + 0x0002, + 0x0003, + 0x0003, + 0x0004, + 0x0004, + 0x0005, + 0x0005, + 0x0006, + 0x0006, + 0x0007, + 0x0007, + 0x0008, + 0x0008, + 0x0009, + 0x0009, + 0x0009, + 0x0009, + 0x000A, + 0x000A, + 0x000A, + 0x000A, + 0x000A, + 0x000A, + 0x000B, + 0x000B, + 0x000B, + 0x000C, + 0x000C, + 0x000D, + 0x000D, + 0x000E, + 0x000E, + 0x000E, + 0x000F, + 0x000F, + 0x000F, + 0x0010, + 0x0010, + 0x0011, + 0x0011, + 0x0012, + 0x0012, + 0x0013, + 0x0013, + 0x0014, + 0x0014, + 0x0015, + 0x0015, + 0x0016, + 0x0016, + 0x0017, + 0x0017, + 0x0018, + 0x0018, + 0x0019, + 0x0019, + 0x001A, + 0x001A, + 0x001B, + 0x001B, + 0x001C, + 0x001C, + 0x001C, + 0x001D, + 0x001D, + 0x001D, + 0x001E, + 0x001E, + 0x001E, + 0x001F, + 0x001F, + 0x001F, + 0x0020, + 0x007F, + 0x007F, + 0x0080, + 0x0080, + 0x0081, + 0x0081, + 0x0082, + 0x0082, + 0x0083, + 0x0083, + 0x0084, + 0x0084, + 0x0085, + 0x0085, + 0x0086, + 0x0086, + 0x0087, + 0x0087, + 0x0088, + 0x0088, + 0x0088, + 0x0089, + 0x0089, + 0x0089, + 0x008A, + 0x008A, + 0x008A, + 0x008B, + 0x008B, + 0x008B, + 0x008C, + 0x008C, + 0x008C, + 0x008D, + 0x008D, + 0x008D, + 0x008E, + 0x008E, + 0x008E, + 0x008F, + 0x008F, + 0x008F, + 0x0090, + 0x0090, + 0x0091, + 0x0091, + 0x0091, + 0x0092, + 0x0092, + 0x0092, + 0x0093, + 0x0093, + 0x0094, + 0x0094, + 0x0095, + 0x0095, + 0x0096, + 0x0096, + 0x0096, + 0x0097, + 0x0097, + 0x0097, + 0x0098, + 0x0098, + 0x0099, + 0x0099, + 0x009A, + 0x009A, + 0x009B, + 0x009B, + 0x009C, + 0x009C, + 0x009D, + 0x009D, + 0x009E, + 0x009E, + 0x009F, + 0x009F, + 0x00A0, + 0x00AD, + 0x01A2, + 0x01A3, + 0x034F, + 0x061C, + 0x0709, + 0x0CDE, + 0x0E9D, + 0x0E9F, + 0x0EA3, + 0x0EA5, + 0x0FD0, + 0x11EC, + 0x11ED, + 0x11EE, + 0x11EF, + 0x180B, + 0x180C, + 0x180D, + 0x180E, + 0x200B, + 0x200C, + 0x200D, + 0x200E, + 0x200F, + 0x202A, + 0x202B, + 0x202C, + 0x202D, + 0x202E, + 0x202F, + 0x205F, + 0x2060, + 0x2066, + 0x2067, + 0x2068, + 0x2069, + 0x2118, + 0x2448, + 0x2449, + 0x2B7A, + 0x2B7C, + 0xA015, + 0xFE00, + 0xFE01, + 0xFE02, + 0xFE03, + 0xFE04, + 0xFE05, + 0xFE06, + 0xFE07, + 0xFE08, + 0xFE09, + 0xFE0A, + 0xFE0B, + 0xFE0C, + 0xFE0D, + 0xFE0E, + 0xFE0F, + 0xFE18, + 0xFEFF, + 0xFEFF, + 0xFEFF, + 0x122D4, + 0x122D5, + 0x16E56, + 0x16E57, + 0x16E76, + 0x16E77, + 0x1B001, + 0x1D0C5, + 0xE0100, + 0xE0101, + 0xE0102, + 0xE0103, + 0xE0104, + 0xE0105, + 0xE0106, + 0xE0107, + 0xE0108, + 0xE0109, + 0xE010A, + 0xE010B, + 0xE010C, + 0xE010D, + 0xE010E, + 0xE010F, + 0xE0110, + 0xE0111, + 0xE0112, + 0xE0113, + 0xE0114, + 0xE0115, + 0xE0116, + 0xE0117, + 0xE0118, + 0xE0119, + 0xE011A, + 0xE011B, + 0xE011C, + 0xE011D, + 0xE011E, + 0xE011F, + 0xE0120, + 0xE0121, + 0xE0122, + 0xE0123, + 0xE0124, + 0xE0125, + 0xE0126, + 0xE0127, + 0xE0128, + 0xE0129, + 0xE012A, + 0xE012B, + 0xE012C, + 0xE012D, + 0xE012E, + 0xE012F, + 0xE0130, + 0xE0131, + 0xE0132, + 0xE0133, + 0xE0134, + 0xE0135, + 0xE0136, + 0xE0137, + 0xE0138, + 0xE0139, + 0xE013A, + 0xE013B, + 0xE013C, + 0xE013D, + 0xE013E, + 0xE013F, + 0xE0140, + 0xE0141, + 0xE0142, + 0xE0143, + 0xE0144, + 0xE0145, + 0xE0146, + 0xE0147, + 0xE0148, + 0xE0149, + 0xE014A, + 0xE014B, + 0xE014C, + 0xE014D, + 0xE014E, + 0xE014F, + 0xE0150, + 0xE0151, + 0xE0152, + 0xE0153, + 0xE0154, + 0xE0155, + 0xE0156, + 0xE0157, + 0xE0158, + 0xE0159, + 0xE015A, + 0xE015B, + 0xE015C, + 0xE015D, + 0xE015E, + 0xE015F, + 0xE0160, + 0xE0161, + 0xE0162, + 0xE0163, + 0xE0164, + 0xE0165, + 0xE0166, + 0xE0167, + 0xE0168, + 0xE0169, + 0xE016A, + 0xE016B, + 0xE016C, + 0xE016D, + 0xE016E, + 0xE016F, + 0xE0170, + 0xE0171, + 0xE0172, + 0xE0173, + 0xE0174, + 0xE0175, + 0xE0176, + 0xE0177, + 0xE0178, + 0xE0179, + 0xE017A, + 0xE017B, + 0xE017C, + 0xE017D, + 0xE017E, + 0xE017F, + 0xE0180, + 0xE0181, + 0xE0182, + 0xE0183, + 0xE0184, + 0xE0185, + 0xE0186, + 0xE0187, + 0xE0188, + 0xE0189, + 0xE018A, + 0xE018B, + 0xE018C, + 0xE018D, + 0xE018E, + 0xE018F, + 0xE0190, + 0xE0191, + 0xE0192, + 0xE0193, + 0xE0194, + 0xE0195, + 0xE0196, + 0xE0197, + 0xE0198, + 0xE0199, + 0xE019A, + 0xE019B, + 0xE019C, + 0xE019D, + 0xE019E, + 0xE019F, + 0xE01A0, + 0xE01A1, + 0xE01A2, + 0xE01A3, + 0xE01A4, + 0xE01A5, + 0xE01A6, + 0xE01A7, + 0xE01A8, + 0xE01A9, + 0xE01AA, + 0xE01AB, + 0xE01AC, + 0xE01AD, + 0xE01AE, + 0xE01AF, + 0xE01B0, + 0xE01B1, + 0xE01B2, + 0xE01B3, + 0xE01B4, + 0xE01B5, + 0xE01B6, + 0xE01B7, + 0xE01B8, + 0xE01B9, + 0xE01BA, + 0xE01BB, + 0xE01BC, + 0xE01BD, + 0xE01BE, + 0xE01BF, + 0xE01C0, + 0xE01C1, + 0xE01C2, + 0xE01C3, + 0xE01C4, + 0xE01C5, + 0xE01C6, + 0xE01C7, + 0xE01C8, + 0xE01C9, + 0xE01CA, + 0xE01CB, + 0xE01CC, + 0xE01CD, + 0xE01CE, + 0xE01CF, + 0xE01D0, + 0xE01D1, + 0xE01D2, + 0xE01D3, + 0xE01D4, + 0xE01D5, + 0xE01D6, + 0xE01D7, + 0xE01D8, + 0xE01D9, + 0xE01DA, + 0xE01DB, + 0xE01DC, + 0xE01DD, + 0xE01DE, + 0xE01DF, + 0xE01E0, + 0xE01E1, + 0xE01E2, + 0xE01E3, + 0xE01E4, + 0xE01E5, + 0xE01E6, + 0xE01E7, + 0xE01E8, + 0xE01E9, + 0xE01EA, + 0xE01EB, + 0xE01EC, + 0xE01ED, + 0xE01EE, + 0xE01EF, +}; + +typedef struct NamedSequence { + int seqlen; + Py_UCS2 seq[4]; +} named_sequence; + +static const unsigned int named_sequences_start = 0xf0200; +static const unsigned int named_sequences_end = 0xf03ba; +static const named_sequence named_sequences[] = { + {3, {0x0023, 0xFE0F, 0x20E3}}, + {3, {0x002A, 0xFE0F, 0x20E3}}, + {3, {0x0030, 0xFE0F, 0x20E3}}, + {3, {0x0031, 0xFE0F, 0x20E3}}, + {3, {0x0032, 0xFE0F, 0x20E3}}, + {3, {0x0033, 0xFE0F, 0x20E3}}, + {3, {0x0034, 0xFE0F, 0x20E3}}, + {3, {0x0035, 0xFE0F, 0x20E3}}, + {3, {0x0036, 0xFE0F, 0x20E3}}, + {3, {0x0037, 0xFE0F, 0x20E3}}, + {3, {0x0038, 0xFE0F, 0x20E3}}, + {3, {0x0039, 0xFE0F, 0x20E3}}, + {2, {0x0100, 0x0300}}, + {2, {0x0101, 0x0300}}, {2, {0x012A, 0x0300}}, {2, {0x012B, 0x0300}}, {2, {0x016A, 0x0300}}, {2, {0x016B, 0x0300}}, - {2, {0x0045, 0x0329}}, - {2, {0x0065, 0x0329}}, - {2, {0x00C8, 0x0329}}, - {2, {0x00E8, 0x0329}}, - {2, {0x00C9, 0x0329}}, - {2, {0x00E9, 0x0329}}, - {2, {0x004F, 0x0329}}, - {2, {0x006F, 0x0329}}, - {2, {0x00D2, 0x0329}}, - {2, {0x00F2, 0x0329}}, - {2, {0x00D3, 0x0329}}, - {2, {0x00F3, 0x0329}}, - {2, {0x0053, 0x0329}}, - {2, {0x0073, 0x0329}}, + {2, {0x0045, 0x0329}}, + {2, {0x0065, 0x0329}}, + {2, {0x00C8, 0x0329}}, + {2, {0x00E8, 0x0329}}, + {2, {0x00C9, 0x0329}}, + {2, {0x00E9, 0x0329}}, + {2, {0x004F, 0x0329}}, + {2, {0x006F, 0x0329}}, + {2, {0x00D2, 0x0329}}, + {2, {0x00F2, 0x0329}}, + {2, {0x00D3, 0x0329}}, + {2, {0x00F3, 0x0329}}, + {2, {0x0053, 0x0329}}, + {2, {0x0073, 0x0329}}, {2, {0x00CA, 0x0304}}, {2, {0x00EA, 0x0304}}, {2, {0x00CA, 0x030C}}, {2, {0x00EA, 0x030C}}, {3, {0x0069, 0x0307, 0x0301}}, {3, {0x006E, 0x0360, 0x0067}}, - {2, {0x0104, 0x0301}}, - {2, {0x0105, 0x0301}}, - {2, {0x0104, 0x0303}}, - {2, {0x0105, 0x0303}}, - {2, {0x0118, 0x0301}}, - {2, {0x0119, 0x0301}}, - {2, {0x0118, 0x0303}}, - {2, {0x0119, 0x0303}}, - {2, {0x0116, 0x0301}}, - {2, {0x0117, 0x0301}}, - {2, {0x0116, 0x0303}}, - {2, {0x0117, 0x0303}}, - {3, {0x0069, 0x0307, 0x0300}}, - {3, {0x0069, 0x0307, 0x0303}}, - {2, {0x012E, 0x0301}}, - {3, {0x012F, 0x0307, 0x0301}}, - {2, {0x012E, 0x0303}}, - {3, {0x012F, 0x0307, 0x0303}}, - {2, {0x004A, 0x0303}}, - {3, {0x006A, 0x0307, 0x0303}}, - {2, {0x004C, 0x0303}}, - {2, {0x006C, 0x0303}}, - {2, {0x004D, 0x0303}}, - {2, {0x006D, 0x0303}}, - {2, {0x0052, 0x0303}}, - {2, {0x0072, 0x0303}}, - {2, {0x0172, 0x0301}}, - {2, {0x0173, 0x0301}}, - {2, {0x0172, 0x0303}}, - {2, {0x0173, 0x0303}}, - {2, {0x016A, 0x0301}}, - {2, {0x016B, 0x0301}}, - {2, {0x016A, 0x0303}}, - {2, {0x016B, 0x0303}}, - {2, {0x00E6, 0x0300}}, - {2, {0x0254, 0x0300}}, - {2, {0x0254, 0x0301}}, - {2, {0x028C, 0x0300}}, - {2, {0x028C, 0x0301}}, - {2, {0x0259, 0x0300}}, - {2, {0x0259, 0x0301}}, - {2, {0x025A, 0x0300}}, - {2, {0x025A, 0x0301}}, - {2, {0x0626, 0x0627}}, - {2, {0x0626, 0x0648}}, - {2, {0x0626, 0x0649}}, - {2, {0x0626, 0x06C6}}, - {2, {0x0626, 0x06C7}}, - {2, {0x0626, 0x06C8}}, - {2, {0x0626, 0x06D0}}, - {2, {0x0626, 0x06D5}}, - {2, {0x0646, 0x06A9}}, - {3, {0x0995, 0x09CD, 0x09B7}}, - {2, {0x0B95, 0x0BCD}}, - {2, {0x0B99, 0x0BCD}}, - {2, {0x0B9A, 0x0BCD}}, - {2, {0x0B9E, 0x0BCD}}, - {2, {0x0B9F, 0x0BCD}}, - {2, {0x0BA3, 0x0BCD}}, - {2, {0x0BA4, 0x0BCD}}, - {2, {0x0BA8, 0x0BCD}}, - {2, {0x0BAA, 0x0BCD}}, - {2, {0x0BAE, 0x0BCD}}, - {2, {0x0BAF, 0x0BCD}}, - {2, {0x0BB0, 0x0BCD}}, - {2, {0x0BB2, 0x0BCD}}, - {2, {0x0BB5, 0x0BCD}}, - {2, {0x0BB4, 0x0BCD}}, - {2, {0x0BB3, 0x0BCD}}, - {2, {0x0BB1, 0x0BCD}}, - {2, {0x0BA9, 0x0BCD}}, - {2, {0x0B9C, 0x0BCD}}, - {2, {0x0BB6, 0x0BCD}}, - {2, {0x0BB7, 0x0BCD}}, - {2, {0x0BB8, 0x0BCD}}, - {2, {0x0BB9, 0x0BCD}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BCD}}, - {2, {0x0B95, 0x0BBE}}, - {2, {0x0B95, 0x0BBF}}, - {2, {0x0B95, 0x0BC0}}, - {2, {0x0B95, 0x0BC1}}, - {2, {0x0B95, 0x0BC2}}, - {2, {0x0B95, 0x0BC6}}, - {2, {0x0B95, 0x0BC7}}, - {2, {0x0B95, 0x0BC8}}, - {2, {0x0B95, 0x0BCA}}, - {2, {0x0B95, 0x0BCB}}, - {2, {0x0B95, 0x0BCC}}, - {2, {0x0B99, 0x0BBE}}, - {2, {0x0B99, 0x0BBF}}, - {2, {0x0B99, 0x0BC0}}, - {2, {0x0B99, 0x0BC1}}, - {2, {0x0B99, 0x0BC2}}, - {2, {0x0B99, 0x0BC6}}, - {2, {0x0B99, 0x0BC7}}, - {2, {0x0B99, 0x0BC8}}, - {2, {0x0B99, 0x0BCA}}, - {2, {0x0B99, 0x0BCB}}, - {2, {0x0B99, 0x0BCC}}, - {2, {0x0B9A, 0x0BBE}}, - {2, {0x0B9A, 0x0BBF}}, - {2, {0x0B9A, 0x0BC0}}, - {2, {0x0B9A, 0x0BC1}}, - {2, {0x0B9A, 0x0BC2}}, - {2, {0x0B9A, 0x0BC6}}, - {2, {0x0B9A, 0x0BC7}}, - {2, {0x0B9A, 0x0BC8}}, - {2, {0x0B9A, 0x0BCA}}, - {2, {0x0B9A, 0x0BCB}}, - {2, {0x0B9A, 0x0BCC}}, - {2, {0x0B9E, 0x0BBE}}, - {2, {0x0B9E, 0x0BBF}}, - {2, {0x0B9E, 0x0BC0}}, - {2, {0x0B9E, 0x0BC1}}, - {2, {0x0B9E, 0x0BC2}}, - {2, {0x0B9E, 0x0BC6}}, - {2, {0x0B9E, 0x0BC7}}, - {2, {0x0B9E, 0x0BC8}}, - {2, {0x0B9E, 0x0BCA}}, - {2, {0x0B9E, 0x0BCB}}, - {2, {0x0B9E, 0x0BCC}}, - {2, {0x0B9F, 0x0BBE}}, - {2, {0x0B9F, 0x0BBF}}, - {2, {0x0B9F, 0x0BC0}}, - {2, {0x0B9F, 0x0BC1}}, - {2, {0x0B9F, 0x0BC2}}, - {2, {0x0B9F, 0x0BC6}}, - {2, {0x0B9F, 0x0BC7}}, - {2, {0x0B9F, 0x0BC8}}, - {2, {0x0B9F, 0x0BCA}}, - {2, {0x0B9F, 0x0BCB}}, - {2, {0x0B9F, 0x0BCC}}, - {2, {0x0BA3, 0x0BBE}}, - {2, {0x0BA3, 0x0BBF}}, - {2, {0x0BA3, 0x0BC0}}, - {2, {0x0BA3, 0x0BC1}}, - {2, {0x0BA3, 0x0BC2}}, - {2, {0x0BA3, 0x0BC6}}, - {2, {0x0BA3, 0x0BC7}}, - {2, {0x0BA3, 0x0BC8}}, - {2, {0x0BA3, 0x0BCA}}, - {2, {0x0BA3, 0x0BCB}}, - {2, {0x0BA3, 0x0BCC}}, - {2, {0x0BA4, 0x0BBE}}, - {2, {0x0BA4, 0x0BBF}}, - {2, {0x0BA4, 0x0BC0}}, - {2, {0x0BA4, 0x0BC1}}, - {2, {0x0BA4, 0x0BC2}}, - {2, {0x0BA4, 0x0BC6}}, - {2, {0x0BA4, 0x0BC7}}, - {2, {0x0BA4, 0x0BC8}}, - {2, {0x0BA4, 0x0BCA}}, - {2, {0x0BA4, 0x0BCB}}, - {2, {0x0BA4, 0x0BCC}}, - {2, {0x0BA8, 0x0BBE}}, - {2, {0x0BA8, 0x0BBF}}, - {2, {0x0BA8, 0x0BC0}}, - {2, {0x0BA8, 0x0BC1}}, - {2, {0x0BA8, 0x0BC2}}, - {2, {0x0BA8, 0x0BC6}}, - {2, {0x0BA8, 0x0BC7}}, - {2, {0x0BA8, 0x0BC8}}, - {2, {0x0BA8, 0x0BCA}}, - {2, {0x0BA8, 0x0BCB}}, - {2, {0x0BA8, 0x0BCC}}, - {2, {0x0BAA, 0x0BBE}}, - {2, {0x0BAA, 0x0BBF}}, - {2, {0x0BAA, 0x0BC0}}, - {2, {0x0BAA, 0x0BC1}}, - {2, {0x0BAA, 0x0BC2}}, - {2, {0x0BAA, 0x0BC6}}, - {2, {0x0BAA, 0x0BC7}}, - {2, {0x0BAA, 0x0BC8}}, - {2, {0x0BAA, 0x0BCA}}, - {2, {0x0BAA, 0x0BCB}}, - {2, {0x0BAA, 0x0BCC}}, - {2, {0x0BAE, 0x0BBE}}, - {2, {0x0BAE, 0x0BBF}}, - {2, {0x0BAE, 0x0BC0}}, - {2, {0x0BAE, 0x0BC1}}, - {2, {0x0BAE, 0x0BC2}}, - {2, {0x0BAE, 0x0BC6}}, - {2, {0x0BAE, 0x0BC7}}, - {2, {0x0BAE, 0x0BC8}}, - {2, {0x0BAE, 0x0BCA}}, - {2, {0x0BAE, 0x0BCB}}, - {2, {0x0BAE, 0x0BCC}}, - {2, {0x0BAF, 0x0BBE}}, - {2, {0x0BAF, 0x0BBF}}, - {2, {0x0BAF, 0x0BC0}}, - {2, {0x0BAF, 0x0BC1}}, - {2, {0x0BAF, 0x0BC2}}, - {2, {0x0BAF, 0x0BC6}}, - {2, {0x0BAF, 0x0BC7}}, - {2, {0x0BAF, 0x0BC8}}, - {2, {0x0BAF, 0x0BCA}}, - {2, {0x0BAF, 0x0BCB}}, - {2, {0x0BAF, 0x0BCC}}, - {2, {0x0BB0, 0x0BBE}}, - {2, {0x0BB0, 0x0BBF}}, - {2, {0x0BB0, 0x0BC0}}, - {2, {0x0BB0, 0x0BC1}}, - {2, {0x0BB0, 0x0BC2}}, - {2, {0x0BB0, 0x0BC6}}, - {2, {0x0BB0, 0x0BC7}}, - {2, {0x0BB0, 0x0BC8}}, - {2, {0x0BB0, 0x0BCA}}, - {2, {0x0BB0, 0x0BCB}}, - {2, {0x0BB0, 0x0BCC}}, - {2, {0x0BB2, 0x0BBE}}, - {2, {0x0BB2, 0x0BBF}}, - {2, {0x0BB2, 0x0BC0}}, - {2, {0x0BB2, 0x0BC1}}, - {2, {0x0BB2, 0x0BC2}}, - {2, {0x0BB2, 0x0BC6}}, - {2, {0x0BB2, 0x0BC7}}, - {2, {0x0BB2, 0x0BC8}}, - {2, {0x0BB2, 0x0BCA}}, - {2, {0x0BB2, 0x0BCB}}, - {2, {0x0BB2, 0x0BCC}}, - {2, {0x0BB5, 0x0BBE}}, - {2, {0x0BB5, 0x0BBF}}, - {2, {0x0BB5, 0x0BC0}}, - {2, {0x0BB5, 0x0BC1}}, - {2, {0x0BB5, 0x0BC2}}, - {2, {0x0BB5, 0x0BC6}}, - {2, {0x0BB5, 0x0BC7}}, - {2, {0x0BB5, 0x0BC8}}, - {2, {0x0BB5, 0x0BCA}}, - {2, {0x0BB5, 0x0BCB}}, - {2, {0x0BB5, 0x0BCC}}, - {2, {0x0BB4, 0x0BBE}}, - {2, {0x0BB4, 0x0BBF}}, - {2, {0x0BB4, 0x0BC0}}, - {2, {0x0BB4, 0x0BC1}}, - {2, {0x0BB4, 0x0BC2}}, - {2, {0x0BB4, 0x0BC6}}, - {2, {0x0BB4, 0x0BC7}}, - {2, {0x0BB4, 0x0BC8}}, - {2, {0x0BB4, 0x0BCA}}, - {2, {0x0BB4, 0x0BCB}}, - {2, {0x0BB4, 0x0BCC}}, - {2, {0x0BB3, 0x0BBE}}, - {2, {0x0BB3, 0x0BBF}}, - {2, {0x0BB3, 0x0BC0}}, - {2, {0x0BB3, 0x0BC1}}, - {2, {0x0BB3, 0x0BC2}}, - {2, {0x0BB3, 0x0BC6}}, - {2, {0x0BB3, 0x0BC7}}, - {2, {0x0BB3, 0x0BC8}}, - {2, {0x0BB3, 0x0BCA}}, - {2, {0x0BB3, 0x0BCB}}, - {2, {0x0BB3, 0x0BCC}}, - {2, {0x0BB1, 0x0BBE}}, - {2, {0x0BB1, 0x0BBF}}, - {2, {0x0BB1, 0x0BC0}}, - {2, {0x0BB1, 0x0BC1}}, - {2, {0x0BB1, 0x0BC2}}, - {2, {0x0BB1, 0x0BC6}}, - {2, {0x0BB1, 0x0BC7}}, - {2, {0x0BB1, 0x0BC8}}, - {2, {0x0BB1, 0x0BCA}}, - {2, {0x0BB1, 0x0BCB}}, - {2, {0x0BB1, 0x0BCC}}, - {2, {0x0BA9, 0x0BBE}}, - {2, {0x0BA9, 0x0BBF}}, - {2, {0x0BA9, 0x0BC0}}, - {2, {0x0BA9, 0x0BC1}}, - {2, {0x0BA9, 0x0BC2}}, - {2, {0x0BA9, 0x0BC6}}, - {2, {0x0BA9, 0x0BC7}}, - {2, {0x0BA9, 0x0BC8}}, - {2, {0x0BA9, 0x0BCA}}, - {2, {0x0BA9, 0x0BCB}}, - {2, {0x0BA9, 0x0BCC}}, - {2, {0x0B9C, 0x0BBE}}, - {2, {0x0B9C, 0x0BBF}}, - {2, {0x0B9C, 0x0BC0}}, - {2, {0x0B9C, 0x0BC1}}, - {2, {0x0B9C, 0x0BC2}}, - {2, {0x0B9C, 0x0BC6}}, - {2, {0x0B9C, 0x0BC7}}, - {2, {0x0B9C, 0x0BC8}}, - {2, {0x0B9C, 0x0BCA}}, - {2, {0x0B9C, 0x0BCB}}, - {2, {0x0B9C, 0x0BCC}}, - {2, {0x0BB6, 0x0BBE}}, - {2, {0x0BB6, 0x0BBF}}, - {2, {0x0BB6, 0x0BC0}}, - {2, {0x0BB6, 0x0BC1}}, - {2, {0x0BB6, 0x0BC2}}, - {2, {0x0BB6, 0x0BC6}}, - {2, {0x0BB6, 0x0BC7}}, - {2, {0x0BB6, 0x0BC8}}, - {2, {0x0BB6, 0x0BCA}}, - {2, {0x0BB6, 0x0BCB}}, - {2, {0x0BB6, 0x0BCC}}, - {2, {0x0BB7, 0x0BBE}}, - {2, {0x0BB7, 0x0BBF}}, - {2, {0x0BB7, 0x0BC0}}, - {2, {0x0BB7, 0x0BC1}}, - {2, {0x0BB7, 0x0BC2}}, - {2, {0x0BB7, 0x0BC6}}, - {2, {0x0BB7, 0x0BC7}}, - {2, {0x0BB7, 0x0BC8}}, - {2, {0x0BB7, 0x0BCA}}, - {2, {0x0BB7, 0x0BCB}}, - {2, {0x0BB7, 0x0BCC}}, - {2, {0x0BB8, 0x0BBE}}, - {2, {0x0BB8, 0x0BBF}}, - {2, {0x0BB8, 0x0BC0}}, - {2, {0x0BB8, 0x0BC1}}, - {2, {0x0BB8, 0x0BC2}}, - {2, {0x0BB8, 0x0BC6}}, - {2, {0x0BB8, 0x0BC7}}, - {2, {0x0BB8, 0x0BC8}}, - {2, {0x0BB8, 0x0BCA}}, - {2, {0x0BB8, 0x0BCB}}, - {2, {0x0BB8, 0x0BCC}}, - {2, {0x0BB9, 0x0BBE}}, - {2, {0x0BB9, 0x0BBF}}, - {2, {0x0BB9, 0x0BC0}}, - {2, {0x0BB9, 0x0BC1}}, - {2, {0x0BB9, 0x0BC2}}, - {2, {0x0BB9, 0x0BC6}}, - {2, {0x0BB9, 0x0BC7}}, - {2, {0x0BB9, 0x0BC8}}, - {2, {0x0BB9, 0x0BCA}}, - {2, {0x0BB9, 0x0BCB}}, - {2, {0x0BB9, 0x0BCC}}, - {3, {0x0B95, 0x0BCD, 0x0BB7}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BBE}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BBF}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC0}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC1}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC2}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC6}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC7}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC8}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BCA}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BCB}}, - {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BCC}}, - {4, {0x0BB6, 0x0BCD, 0x0BB0, 0x0BC0}}, - {3, {0x0DCA, 0x200D, 0x0DBA}}, - {3, {0x0DCA, 0x200D, 0x0DBB}}, - {3, {0x0DBB, 0x0DCA, 0x200D}}, - {2, {0x10E3, 0x0302}}, - {2, {0x17D2, 0x1780}}, - {2, {0x17D2, 0x1781}}, - {2, {0x17D2, 0x1782}}, - {2, {0x17D2, 0x1783}}, - {2, {0x17D2, 0x1784}}, - {2, {0x17D2, 0x1785}}, - {2, {0x17D2, 0x1786}}, - {2, {0x17D2, 0x1787}}, - {2, {0x17D2, 0x1788}}, - {2, {0x17D2, 0x1789}}, - {2, {0x17D2, 0x178A}}, - {2, {0x17D2, 0x178B}}, - {2, {0x17D2, 0x178C}}, - {2, {0x17D2, 0x178D}}, - {2, {0x17D2, 0x178E}}, - {2, {0x17D2, 0x178F}}, - {2, {0x17D2, 0x1790}}, - {2, {0x17D2, 0x1791}}, - {2, {0x17D2, 0x1792}}, - {2, {0x17D2, 0x1793}}, - {2, {0x17D2, 0x1794}}, - {2, {0x17D2, 0x1795}}, - {2, {0x17D2, 0x1796}}, - {2, {0x17D2, 0x1797}}, - {2, {0x17D2, 0x1798}}, - {2, {0x17D2, 0x1799}}, - {2, {0x17D2, 0x179A}}, - {2, {0x17D2, 0x179B}}, - {2, {0x17D2, 0x179C}}, - {2, {0x17D2, 0x179D}}, - {2, {0x17D2, 0x179E}}, - {2, {0x17D2, 0x179F}}, - {2, {0x17D2, 0x17A0}}, - {2, {0x17D2, 0x17A1}}, - {2, {0x17D2, 0x17A2}}, - {2, {0x17D2, 0x17A7}}, - {2, {0x17D2, 0x17AB}}, - {2, {0x17D2, 0x17AC}}, - {2, {0x17D2, 0x17AF}}, - {2, {0x17BB, 0x17C6}}, - {2, {0x17B6, 0x17C6}}, - {2, {0x304B, 0x309A}}, - {2, {0x304D, 0x309A}}, - {2, {0x304F, 0x309A}}, - {2, {0x3051, 0x309A}}, - {2, {0x3053, 0x309A}}, - {2, {0x30AB, 0x309A}}, - {2, {0x30AD, 0x309A}}, - {2, {0x30AF, 0x309A}}, - {2, {0x30B1, 0x309A}}, - {2, {0x30B3, 0x309A}}, - {2, {0x30BB, 0x309A}}, - {2, {0x30C4, 0x309A}}, - {2, {0x30C8, 0x309A}}, - {2, {0x31F7, 0x309A}}, - {2, {0x02E5, 0x02E9}}, - {2, {0x02E9, 0x02E5}}, -}; + {2, {0x0104, 0x0301}}, + {2, {0x0105, 0x0301}}, + {2, {0x0104, 0x0303}}, + {2, {0x0105, 0x0303}}, + {2, {0x0118, 0x0301}}, + {2, {0x0119, 0x0301}}, + {2, {0x0118, 0x0303}}, + {2, {0x0119, 0x0303}}, + {2, {0x0116, 0x0301}}, + {2, {0x0117, 0x0301}}, + {2, {0x0116, 0x0303}}, + {2, {0x0117, 0x0303}}, + {3, {0x0069, 0x0307, 0x0300}}, + {3, {0x0069, 0x0307, 0x0303}}, + {2, {0x012E, 0x0301}}, + {3, {0x012F, 0x0307, 0x0301}}, + {2, {0x012E, 0x0303}}, + {3, {0x012F, 0x0307, 0x0303}}, + {2, {0x004A, 0x0303}}, + {3, {0x006A, 0x0307, 0x0303}}, + {2, {0x004C, 0x0303}}, + {2, {0x006C, 0x0303}}, + {2, {0x004D, 0x0303}}, + {2, {0x006D, 0x0303}}, + {2, {0x0052, 0x0303}}, + {2, {0x0072, 0x0303}}, + {2, {0x0172, 0x0301}}, + {2, {0x0173, 0x0301}}, + {2, {0x0172, 0x0303}}, + {2, {0x0173, 0x0303}}, + {2, {0x016A, 0x0301}}, + {2, {0x016B, 0x0301}}, + {2, {0x016A, 0x0303}}, + {2, {0x016B, 0x0303}}, + {2, {0x00E6, 0x0300}}, + {2, {0x0254, 0x0300}}, + {2, {0x0254, 0x0301}}, + {2, {0x028C, 0x0300}}, + {2, {0x028C, 0x0301}}, + {2, {0x0259, 0x0300}}, + {2, {0x0259, 0x0301}}, + {2, {0x025A, 0x0300}}, + {2, {0x025A, 0x0301}}, + {2, {0x0626, 0x0627}}, + {2, {0x0626, 0x0648}}, + {2, {0x0626, 0x0649}}, + {2, {0x0626, 0x06C6}}, + {2, {0x0626, 0x06C7}}, + {2, {0x0626, 0x06C8}}, + {2, {0x0626, 0x06D0}}, + {2, {0x0626, 0x06D5}}, + {2, {0x0646, 0x06A9}}, + {3, {0x0995, 0x09CD, 0x09B7}}, + {2, {0x0B95, 0x0BCD}}, + {2, {0x0B99, 0x0BCD}}, + {2, {0x0B9A, 0x0BCD}}, + {2, {0x0B9E, 0x0BCD}}, + {2, {0x0B9F, 0x0BCD}}, + {2, {0x0BA3, 0x0BCD}}, + {2, {0x0BA4, 0x0BCD}}, + {2, {0x0BA8, 0x0BCD}}, + {2, {0x0BAA, 0x0BCD}}, + {2, {0x0BAE, 0x0BCD}}, + {2, {0x0BAF, 0x0BCD}}, + {2, {0x0BB0, 0x0BCD}}, + {2, {0x0BB2, 0x0BCD}}, + {2, {0x0BB5, 0x0BCD}}, + {2, {0x0BB4, 0x0BCD}}, + {2, {0x0BB3, 0x0BCD}}, + {2, {0x0BB1, 0x0BCD}}, + {2, {0x0BA9, 0x0BCD}}, + {2, {0x0B9C, 0x0BCD}}, + {2, {0x0BB6, 0x0BCD}}, + {2, {0x0BB7, 0x0BCD}}, + {2, {0x0BB8, 0x0BCD}}, + {2, {0x0BB9, 0x0BCD}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BCD}}, + {2, {0x0B95, 0x0BBE}}, + {2, {0x0B95, 0x0BBF}}, + {2, {0x0B95, 0x0BC0}}, + {2, {0x0B95, 0x0BC1}}, + {2, {0x0B95, 0x0BC2}}, + {2, {0x0B95, 0x0BC6}}, + {2, {0x0B95, 0x0BC7}}, + {2, {0x0B95, 0x0BC8}}, + {2, {0x0B95, 0x0BCA}}, + {2, {0x0B95, 0x0BCB}}, + {2, {0x0B95, 0x0BCC}}, + {2, {0x0B99, 0x0BBE}}, + {2, {0x0B99, 0x0BBF}}, + {2, {0x0B99, 0x0BC0}}, + {2, {0x0B99, 0x0BC1}}, + {2, {0x0B99, 0x0BC2}}, + {2, {0x0B99, 0x0BC6}}, + {2, {0x0B99, 0x0BC7}}, + {2, {0x0B99, 0x0BC8}}, + {2, {0x0B99, 0x0BCA}}, + {2, {0x0B99, 0x0BCB}}, + {2, {0x0B99, 0x0BCC}}, + {2, {0x0B9A, 0x0BBE}}, + {2, {0x0B9A, 0x0BBF}}, + {2, {0x0B9A, 0x0BC0}}, + {2, {0x0B9A, 0x0BC1}}, + {2, {0x0B9A, 0x0BC2}}, + {2, {0x0B9A, 0x0BC6}}, + {2, {0x0B9A, 0x0BC7}}, + {2, {0x0B9A, 0x0BC8}}, + {2, {0x0B9A, 0x0BCA}}, + {2, {0x0B9A, 0x0BCB}}, + {2, {0x0B9A, 0x0BCC}}, + {2, {0x0B9E, 0x0BBE}}, + {2, {0x0B9E, 0x0BBF}}, + {2, {0x0B9E, 0x0BC0}}, + {2, {0x0B9E, 0x0BC1}}, + {2, {0x0B9E, 0x0BC2}}, + {2, {0x0B9E, 0x0BC6}}, + {2, {0x0B9E, 0x0BC7}}, + {2, {0x0B9E, 0x0BC8}}, + {2, {0x0B9E, 0x0BCA}}, + {2, {0x0B9E, 0x0BCB}}, + {2, {0x0B9E, 0x0BCC}}, + {2, {0x0B9F, 0x0BBE}}, + {2, {0x0B9F, 0x0BBF}}, + {2, {0x0B9F, 0x0BC0}}, + {2, {0x0B9F, 0x0BC1}}, + {2, {0x0B9F, 0x0BC2}}, + {2, {0x0B9F, 0x0BC6}}, + {2, {0x0B9F, 0x0BC7}}, + {2, {0x0B9F, 0x0BC8}}, + {2, {0x0B9F, 0x0BCA}}, + {2, {0x0B9F, 0x0BCB}}, + {2, {0x0B9F, 0x0BCC}}, + {2, {0x0BA3, 0x0BBE}}, + {2, {0x0BA3, 0x0BBF}}, + {2, {0x0BA3, 0x0BC0}}, + {2, {0x0BA3, 0x0BC1}}, + {2, {0x0BA3, 0x0BC2}}, + {2, {0x0BA3, 0x0BC6}}, + {2, {0x0BA3, 0x0BC7}}, + {2, {0x0BA3, 0x0BC8}}, + {2, {0x0BA3, 0x0BCA}}, + {2, {0x0BA3, 0x0BCB}}, + {2, {0x0BA3, 0x0BCC}}, + {2, {0x0BA4, 0x0BBE}}, + {2, {0x0BA4, 0x0BBF}}, + {2, {0x0BA4, 0x0BC0}}, + {2, {0x0BA4, 0x0BC1}}, + {2, {0x0BA4, 0x0BC2}}, + {2, {0x0BA4, 0x0BC6}}, + {2, {0x0BA4, 0x0BC7}}, + {2, {0x0BA4, 0x0BC8}}, + {2, {0x0BA4, 0x0BCA}}, + {2, {0x0BA4, 0x0BCB}}, + {2, {0x0BA4, 0x0BCC}}, + {2, {0x0BA8, 0x0BBE}}, + {2, {0x0BA8, 0x0BBF}}, + {2, {0x0BA8, 0x0BC0}}, + {2, {0x0BA8, 0x0BC1}}, + {2, {0x0BA8, 0x0BC2}}, + {2, {0x0BA8, 0x0BC6}}, + {2, {0x0BA8, 0x0BC7}}, + {2, {0x0BA8, 0x0BC8}}, + {2, {0x0BA8, 0x0BCA}}, + {2, {0x0BA8, 0x0BCB}}, + {2, {0x0BA8, 0x0BCC}}, + {2, {0x0BAA, 0x0BBE}}, + {2, {0x0BAA, 0x0BBF}}, + {2, {0x0BAA, 0x0BC0}}, + {2, {0x0BAA, 0x0BC1}}, + {2, {0x0BAA, 0x0BC2}}, + {2, {0x0BAA, 0x0BC6}}, + {2, {0x0BAA, 0x0BC7}}, + {2, {0x0BAA, 0x0BC8}}, + {2, {0x0BAA, 0x0BCA}}, + {2, {0x0BAA, 0x0BCB}}, + {2, {0x0BAA, 0x0BCC}}, + {2, {0x0BAE, 0x0BBE}}, + {2, {0x0BAE, 0x0BBF}}, + {2, {0x0BAE, 0x0BC0}}, + {2, {0x0BAE, 0x0BC1}}, + {2, {0x0BAE, 0x0BC2}}, + {2, {0x0BAE, 0x0BC6}}, + {2, {0x0BAE, 0x0BC7}}, + {2, {0x0BAE, 0x0BC8}}, + {2, {0x0BAE, 0x0BCA}}, + {2, {0x0BAE, 0x0BCB}}, + {2, {0x0BAE, 0x0BCC}}, + {2, {0x0BAF, 0x0BBE}}, + {2, {0x0BAF, 0x0BBF}}, + {2, {0x0BAF, 0x0BC0}}, + {2, {0x0BAF, 0x0BC1}}, + {2, {0x0BAF, 0x0BC2}}, + {2, {0x0BAF, 0x0BC6}}, + {2, {0x0BAF, 0x0BC7}}, + {2, {0x0BAF, 0x0BC8}}, + {2, {0x0BAF, 0x0BCA}}, + {2, {0x0BAF, 0x0BCB}}, + {2, {0x0BAF, 0x0BCC}}, + {2, {0x0BB0, 0x0BBE}}, + {2, {0x0BB0, 0x0BBF}}, + {2, {0x0BB0, 0x0BC0}}, + {2, {0x0BB0, 0x0BC1}}, + {2, {0x0BB0, 0x0BC2}}, + {2, {0x0BB0, 0x0BC6}}, + {2, {0x0BB0, 0x0BC7}}, + {2, {0x0BB0, 0x0BC8}}, + {2, {0x0BB0, 0x0BCA}}, + {2, {0x0BB0, 0x0BCB}}, + {2, {0x0BB0, 0x0BCC}}, + {2, {0x0BB2, 0x0BBE}}, + {2, {0x0BB2, 0x0BBF}}, + {2, {0x0BB2, 0x0BC0}}, + {2, {0x0BB2, 0x0BC1}}, + {2, {0x0BB2, 0x0BC2}}, + {2, {0x0BB2, 0x0BC6}}, + {2, {0x0BB2, 0x0BC7}}, + {2, {0x0BB2, 0x0BC8}}, + {2, {0x0BB2, 0x0BCA}}, + {2, {0x0BB2, 0x0BCB}}, + {2, {0x0BB2, 0x0BCC}}, + {2, {0x0BB5, 0x0BBE}}, + {2, {0x0BB5, 0x0BBF}}, + {2, {0x0BB5, 0x0BC0}}, + {2, {0x0BB5, 0x0BC1}}, + {2, {0x0BB5, 0x0BC2}}, + {2, {0x0BB5, 0x0BC6}}, + {2, {0x0BB5, 0x0BC7}}, + {2, {0x0BB5, 0x0BC8}}, + {2, {0x0BB5, 0x0BCA}}, + {2, {0x0BB5, 0x0BCB}}, + {2, {0x0BB5, 0x0BCC}}, + {2, {0x0BB4, 0x0BBE}}, + {2, {0x0BB4, 0x0BBF}}, + {2, {0x0BB4, 0x0BC0}}, + {2, {0x0BB4, 0x0BC1}}, + {2, {0x0BB4, 0x0BC2}}, + {2, {0x0BB4, 0x0BC6}}, + {2, {0x0BB4, 0x0BC7}}, + {2, {0x0BB4, 0x0BC8}}, + {2, {0x0BB4, 0x0BCA}}, + {2, {0x0BB4, 0x0BCB}}, + {2, {0x0BB4, 0x0BCC}}, + {2, {0x0BB3, 0x0BBE}}, + {2, {0x0BB3, 0x0BBF}}, + {2, {0x0BB3, 0x0BC0}}, + {2, {0x0BB3, 0x0BC1}}, + {2, {0x0BB3, 0x0BC2}}, + {2, {0x0BB3, 0x0BC6}}, + {2, {0x0BB3, 0x0BC7}}, + {2, {0x0BB3, 0x0BC8}}, + {2, {0x0BB3, 0x0BCA}}, + {2, {0x0BB3, 0x0BCB}}, + {2, {0x0BB3, 0x0BCC}}, + {2, {0x0BB1, 0x0BBE}}, + {2, {0x0BB1, 0x0BBF}}, + {2, {0x0BB1, 0x0BC0}}, + {2, {0x0BB1, 0x0BC1}}, + {2, {0x0BB1, 0x0BC2}}, + {2, {0x0BB1, 0x0BC6}}, + {2, {0x0BB1, 0x0BC7}}, + {2, {0x0BB1, 0x0BC8}}, + {2, {0x0BB1, 0x0BCA}}, + {2, {0x0BB1, 0x0BCB}}, + {2, {0x0BB1, 0x0BCC}}, + {2, {0x0BA9, 0x0BBE}}, + {2, {0x0BA9, 0x0BBF}}, + {2, {0x0BA9, 0x0BC0}}, + {2, {0x0BA9, 0x0BC1}}, + {2, {0x0BA9, 0x0BC2}}, + {2, {0x0BA9, 0x0BC6}}, + {2, {0x0BA9, 0x0BC7}}, + {2, {0x0BA9, 0x0BC8}}, + {2, {0x0BA9, 0x0BCA}}, + {2, {0x0BA9, 0x0BCB}}, + {2, {0x0BA9, 0x0BCC}}, + {2, {0x0B9C, 0x0BBE}}, + {2, {0x0B9C, 0x0BBF}}, + {2, {0x0B9C, 0x0BC0}}, + {2, {0x0B9C, 0x0BC1}}, + {2, {0x0B9C, 0x0BC2}}, + {2, {0x0B9C, 0x0BC6}}, + {2, {0x0B9C, 0x0BC7}}, + {2, {0x0B9C, 0x0BC8}}, + {2, {0x0B9C, 0x0BCA}}, + {2, {0x0B9C, 0x0BCB}}, + {2, {0x0B9C, 0x0BCC}}, + {2, {0x0BB6, 0x0BBE}}, + {2, {0x0BB6, 0x0BBF}}, + {2, {0x0BB6, 0x0BC0}}, + {2, {0x0BB6, 0x0BC1}}, + {2, {0x0BB6, 0x0BC2}}, + {2, {0x0BB6, 0x0BC6}}, + {2, {0x0BB6, 0x0BC7}}, + {2, {0x0BB6, 0x0BC8}}, + {2, {0x0BB6, 0x0BCA}}, + {2, {0x0BB6, 0x0BCB}}, + {2, {0x0BB6, 0x0BCC}}, + {2, {0x0BB7, 0x0BBE}}, + {2, {0x0BB7, 0x0BBF}}, + {2, {0x0BB7, 0x0BC0}}, + {2, {0x0BB7, 0x0BC1}}, + {2, {0x0BB7, 0x0BC2}}, + {2, {0x0BB7, 0x0BC6}}, + {2, {0x0BB7, 0x0BC7}}, + {2, {0x0BB7, 0x0BC8}}, + {2, {0x0BB7, 0x0BCA}}, + {2, {0x0BB7, 0x0BCB}}, + {2, {0x0BB7, 0x0BCC}}, + {2, {0x0BB8, 0x0BBE}}, + {2, {0x0BB8, 0x0BBF}}, + {2, {0x0BB8, 0x0BC0}}, + {2, {0x0BB8, 0x0BC1}}, + {2, {0x0BB8, 0x0BC2}}, + {2, {0x0BB8, 0x0BC6}}, + {2, {0x0BB8, 0x0BC7}}, + {2, {0x0BB8, 0x0BC8}}, + {2, {0x0BB8, 0x0BCA}}, + {2, {0x0BB8, 0x0BCB}}, + {2, {0x0BB8, 0x0BCC}}, + {2, {0x0BB9, 0x0BBE}}, + {2, {0x0BB9, 0x0BBF}}, + {2, {0x0BB9, 0x0BC0}}, + {2, {0x0BB9, 0x0BC1}}, + {2, {0x0BB9, 0x0BC2}}, + {2, {0x0BB9, 0x0BC6}}, + {2, {0x0BB9, 0x0BC7}}, + {2, {0x0BB9, 0x0BC8}}, + {2, {0x0BB9, 0x0BCA}}, + {2, {0x0BB9, 0x0BCB}}, + {2, {0x0BB9, 0x0BCC}}, + {3, {0x0B95, 0x0BCD, 0x0BB7}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BBE}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BBF}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC0}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC1}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC2}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC6}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC7}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BC8}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BCA}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BCB}}, + {4, {0x0B95, 0x0BCD, 0x0BB7, 0x0BCC}}, + {4, {0x0BB6, 0x0BCD, 0x0BB0, 0x0BC0}}, + {3, {0x0DCA, 0x200D, 0x0DBA}}, + {3, {0x0DCA, 0x200D, 0x0DBB}}, + {3, {0x0DBB, 0x0DCA, 0x200D}}, + {2, {0x10E3, 0x0302}}, + {2, {0x17D2, 0x1780}}, + {2, {0x17D2, 0x1781}}, + {2, {0x17D2, 0x1782}}, + {2, {0x17D2, 0x1783}}, + {2, {0x17D2, 0x1784}}, + {2, {0x17D2, 0x1785}}, + {2, {0x17D2, 0x1786}}, + {2, {0x17D2, 0x1787}}, + {2, {0x17D2, 0x1788}}, + {2, {0x17D2, 0x1789}}, + {2, {0x17D2, 0x178A}}, + {2, {0x17D2, 0x178B}}, + {2, {0x17D2, 0x178C}}, + {2, {0x17D2, 0x178D}}, + {2, {0x17D2, 0x178E}}, + {2, {0x17D2, 0x178F}}, + {2, {0x17D2, 0x1790}}, + {2, {0x17D2, 0x1791}}, + {2, {0x17D2, 0x1792}}, + {2, {0x17D2, 0x1793}}, + {2, {0x17D2, 0x1794}}, + {2, {0x17D2, 0x1795}}, + {2, {0x17D2, 0x1796}}, + {2, {0x17D2, 0x1797}}, + {2, {0x17D2, 0x1798}}, + {2, {0x17D2, 0x1799}}, + {2, {0x17D2, 0x179A}}, + {2, {0x17D2, 0x179B}}, + {2, {0x17D2, 0x179C}}, + {2, {0x17D2, 0x179D}}, + {2, {0x17D2, 0x179E}}, + {2, {0x17D2, 0x179F}}, + {2, {0x17D2, 0x17A0}}, + {2, {0x17D2, 0x17A1}}, + {2, {0x17D2, 0x17A2}}, + {2, {0x17D2, 0x17A7}}, + {2, {0x17D2, 0x17AB}}, + {2, {0x17D2, 0x17AC}}, + {2, {0x17D2, 0x17AF}}, + {2, {0x17BB, 0x17C6}}, + {2, {0x17B6, 0x17C6}}, + {2, {0x304B, 0x309A}}, + {2, {0x304D, 0x309A}}, + {2, {0x304F, 0x309A}}, + {2, {0x3051, 0x309A}}, + {2, {0x3053, 0x309A}}, + {2, {0x30AB, 0x309A}}, + {2, {0x30AD, 0x309A}}, + {2, {0x30AF, 0x309A}}, + {2, {0x30B1, 0x309A}}, + {2, {0x30B3, 0x309A}}, + {2, {0x30BB, 0x309A}}, + {2, {0x30C4, 0x309A}}, + {2, {0x30C8, 0x309A}}, + {2, {0x31F7, 0x309A}}, + {2, {0x02E5, 0x02E9}}, + {2, {0x02E9, 0x02E5}}, +}; diff --git a/contrib/tools/python3/src/Modules/winreparse.h b/contrib/tools/python3/src/Modules/winreparse.h index f06f701f999..77aa4f77b86 100644 --- a/contrib/tools/python3/src/Modules/winreparse.h +++ b/contrib/tools/python3/src/Modules/winreparse.h @@ -1,59 +1,59 @@ -#ifndef Py_WINREPARSE_H -#define Py_WINREPARSE_H - -#ifdef MS_WINDOWS -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* The following structure was copied from - http://msdn.microsoft.com/en-us/library/ff552012.aspx as the required - include km\ntifs.h isn't present in the Windows SDK (at least as included - with Visual Studio Express). Use unique names to avoid conflicting with - the structure as defined by Min GW. */ -typedef struct { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - }; -} _Py_REPARSE_DATA_BUFFER, *_Py_PREPARSE_DATA_BUFFER; - -#define _Py_REPARSE_DATA_BUFFER_HEADER_SIZE \ - FIELD_OFFSET(_Py_REPARSE_DATA_BUFFER, GenericReparseBuffer) -#define _Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) - +#ifndef Py_WINREPARSE_H +#define Py_WINREPARSE_H + +#ifdef MS_WINDOWS +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following structure was copied from + http://msdn.microsoft.com/en-us/library/ff552012.aspx as the required + include km\ntifs.h isn't present in the Windows SDK (at least as included + with Visual Studio Express). Use unique names to avoid conflicting with + the structure as defined by Min GW. */ +typedef struct { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + }; +} _Py_REPARSE_DATA_BUFFER, *_Py_PREPARSE_DATA_BUFFER; + +#define _Py_REPARSE_DATA_BUFFER_HEADER_SIZE \ + FIELD_OFFSET(_Py_REPARSE_DATA_BUFFER, GenericReparseBuffer) +#define _Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) + // Defined in WinBase.h in 'recent' versions of Windows 10 SDK #ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE #define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2 #endif -#ifdef __cplusplus -} -#endif - -#endif /* MS_WINDOWS */ - -#endif /* !Py_WINREPARSE_H */ +#ifdef __cplusplus +} +#endif + +#endif /* MS_WINDOWS */ + +#endif /* !Py_WINREPARSE_H */ diff --git a/contrib/tools/python3/src/Modules/ya.make b/contrib/tools/python3/src/Modules/ya.make index 47e38bca511..43dde002d1b 100644 --- a/contrib/tools/python3/src/Modules/ya.make +++ b/contrib/tools/python3/src/Modules/ya.make @@ -1,157 +1,157 @@ -LIBRARY() - -OWNER(g:contrib orivej) - -LICENSE(Python-2.0) - -PEERDIR( - ADDINCL contrib/libs/expat - ADDINCL contrib/libs/libbz2 - ADDINCL contrib/libs/openssl - ADDINCL contrib/libs/zlib - contrib/libs/xz/liblzma +LIBRARY() + +OWNER(g:contrib orivej) + +LICENSE(Python-2.0) + +PEERDIR( + ADDINCL contrib/libs/expat + ADDINCL contrib/libs/libbz2 + ADDINCL contrib/libs/openssl + ADDINCL contrib/libs/zlib + contrib/libs/xz/liblzma contrib/restricted/libffi -) - -ADDINCL( +) + +ADDINCL( contrib/restricted/libffi/include - contrib/tools/python3/src/Include + contrib/tools/python3/src/Include contrib/tools/python3/src/Include/internal - contrib/tools/python3/src/Modules - contrib/tools/python3/src/Modules/_decimal/libmpdec - contrib/tools/python3/src/PC -) - + contrib/tools/python3/src/Modules + contrib/tools/python3/src/Modules/_decimal/libmpdec + contrib/tools/python3/src/PC +) + CFLAGS( -DPy_BUILD_CORE_MODULE ) -NO_COMPILER_WARNINGS() - -NO_RUNTIME() - -SRCS( - _abc.c - _asynciomodule.c - _bisectmodule.c - _blake2/blake2b_impl.c - _blake2/blake2module.c - _blake2/blake2s_impl.c - _bz2module.c - _codecsmodule.c - _collectionsmodule.c - _contextvarsmodule.c - _csv.c - _ctypes/_ctypes.c - _ctypes/callbacks.c - _ctypes/callproc.c - _ctypes/cfield.c - _ctypes/stgdict.c - _datetimemodule.c - _decimal/_decimal.c - _decimal/libmpdec/basearith.c - _decimal/libmpdec/constants.c - _decimal/libmpdec/context.c - _decimal/libmpdec/convolute.c - _decimal/libmpdec/crt.c - _decimal/libmpdec/difradix2.c - _decimal/libmpdec/fnt.c - _decimal/libmpdec/fourstep.c - _decimal/libmpdec/io.c +NO_COMPILER_WARNINGS() + +NO_RUNTIME() + +SRCS( + _abc.c + _asynciomodule.c + _bisectmodule.c + _blake2/blake2b_impl.c + _blake2/blake2module.c + _blake2/blake2s_impl.c + _bz2module.c + _codecsmodule.c + _collectionsmodule.c + _contextvarsmodule.c + _csv.c + _ctypes/_ctypes.c + _ctypes/callbacks.c + _ctypes/callproc.c + _ctypes/cfield.c + _ctypes/stgdict.c + _datetimemodule.c + _decimal/_decimal.c + _decimal/libmpdec/basearith.c + _decimal/libmpdec/constants.c + _decimal/libmpdec/context.c + _decimal/libmpdec/convolute.c + _decimal/libmpdec/crt.c + _decimal/libmpdec/difradix2.c + _decimal/libmpdec/fnt.c + _decimal/libmpdec/fourstep.c + _decimal/libmpdec/io.c _decimal/libmpdec/mpalloc.c - _decimal/libmpdec/mpdecimal.c - _decimal/libmpdec/numbertheory.c - _decimal/libmpdec/sixstep.c - _decimal/libmpdec/transpose.c - _elementtree.c - _hashopenssl.c - _heapqmodule.c - _json.c - _localemodule.c - _lsprof.c - _lzmamodule.c - _math.c - _multiprocessing/multiprocessing.c + _decimal/libmpdec/mpdecimal.c + _decimal/libmpdec/numbertheory.c + _decimal/libmpdec/sixstep.c + _decimal/libmpdec/transpose.c + _elementtree.c + _hashopenssl.c + _heapqmodule.c + _json.c + _localemodule.c + _lsprof.c + _lzmamodule.c + _math.c + _multiprocessing/multiprocessing.c _multiprocessing/posixshmem.c - _multiprocessing/semaphore.c - _opcode.c - _operator.c + _multiprocessing/semaphore.c + _opcode.c + _operator.c _peg_parser.c - _pickle.c - _queuemodule.c - _randommodule.c - _sha3/sha3module.c - _sre.c - _ssl.c - _stat.c + _pickle.c + _queuemodule.c + _randommodule.c + _sha3/sha3module.c + _sre.c + _ssl.c + _stat.c _statisticsmodule.c - _struct.c - _tracemalloc.c - _weakref.c + _struct.c + _tracemalloc.c + _weakref.c _xxsubinterpretersmodule.c - _xxtestfuzz/_xxtestfuzz.c - _xxtestfuzz/fuzzer.c + _xxtestfuzz/_xxtestfuzz.c + _xxtestfuzz/fuzzer.c _zoneinfo.c - arraymodule.c - atexitmodule.c - audioop.c - binascii.c - cjkcodecs/_codecs_cn.c - cjkcodecs/_codecs_hk.c - cjkcodecs/_codecs_iso2022.c - cjkcodecs/_codecs_jp.c - cjkcodecs/_codecs_kr.c - cjkcodecs/_codecs_tw.c - cjkcodecs/multibytecodec.c - cmathmodule.c - errnomodule.c - faulthandler.c - getbuildinfo.c - itertoolsmodule.c - mathmodule.c - md5module.c - parsermodule.c - pyexpat.c - rotatingtree.c - selectmodule.c - sha1module.c - sha256module.c - sha512module.c - socketmodule.c - symtablemodule.c - unicodedata.c - zlibmodule.c -) - -IF (OS_WINDOWS) - SRCS( - _winapi.c - overlapped.c - ) -ELSE() - SRCS( + arraymodule.c + atexitmodule.c + audioop.c + binascii.c + cjkcodecs/_codecs_cn.c + cjkcodecs/_codecs_hk.c + cjkcodecs/_codecs_iso2022.c + cjkcodecs/_codecs_jp.c + cjkcodecs/_codecs_kr.c + cjkcodecs/_codecs_tw.c + cjkcodecs/multibytecodec.c + cmathmodule.c + errnomodule.c + faulthandler.c + getbuildinfo.c + itertoolsmodule.c + mathmodule.c + md5module.c + parsermodule.c + pyexpat.c + rotatingtree.c + selectmodule.c + sha1module.c + sha256module.c + sha512module.c + socketmodule.c + symtablemodule.c + unicodedata.c + zlibmodule.c +) + +IF (OS_WINDOWS) + SRCS( + _winapi.c + overlapped.c + ) +ELSE() + SRCS( _cryptmodule.c - _posixsubprocess.c - fcntlmodule.c - grpmodule.c - pwdmodule.c - resource.c - syslogmodule.c - termios.c - ) - IF (OS_LINUX) + _posixsubprocess.c + fcntlmodule.c + grpmodule.c + pwdmodule.c + resource.c + syslogmodule.c + termios.c + ) + IF (OS_LINUX) IF (NOT MUSL) EXTRALIBS(crypt) ENDIF() - SRCS( - spwdmodule.c - ) - ELSEIF (OS_DARWIN) - SRCS( - _ctypes/darwin/dlfcn_simple.c - _scproxy.c - ) - ENDIF() -ENDIF() - -END() + SRCS( + spwdmodule.c + ) + ELSEIF (OS_DARWIN) + SRCS( + _ctypes/darwin/dlfcn_simple.c + _scproxy.c + ) + ENDIF() +ENDIF() + +END() diff --git a/contrib/tools/python3/src/Modules/zlibmodule.c b/contrib/tools/python3/src/Modules/zlibmodule.c index 4dfd4ae6722..755d0613cca 100644 --- a/contrib/tools/python3/src/Modules/zlibmodule.c +++ b/contrib/tools/python3/src/Modules/zlibmodule.c @@ -1,44 +1,44 @@ -/* zlibmodule.c -- gzip-compatible data compression */ -/* See http://zlib.net/ */ - -/* Windows users: read Python's PCbuild\readme.txt */ - -#define PY_SSIZE_T_CLEAN - -#include "Python.h" +/* zlibmodule.c -- gzip-compatible data compression */ +/* See http://zlib.net/ */ + +/* Windows users: read Python's PCbuild\readme.txt */ + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" #include "structmember.h" // PyMemberDef -#include "zlib.h" - - -#define ENTER_ZLIB(obj) \ - Py_BEGIN_ALLOW_THREADS; \ - PyThread_acquire_lock((obj)->lock, 1); \ - Py_END_ALLOW_THREADS; -#define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock); - -#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221 -# define AT_LEAST_ZLIB_1_2_2_1 -#endif - -/* The following parameters are copied from zutil.h, version 0.95 */ -#define DEFLATED 8 -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* Initial buffer size. */ -#define DEF_BUF_SIZE (16*1024) - +#include "zlib.h" + + +#define ENTER_ZLIB(obj) \ + Py_BEGIN_ALLOW_THREADS; \ + PyThread_acquire_lock((obj)->lock, 1); \ + Py_END_ALLOW_THREADS; +#define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock); + +#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221 +# define AT_LEAST_ZLIB_1_2_2_1 +#endif + +/* The following parameters are copied from zutil.h, version 0.95 */ +#define DEFLATED 8 +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* Initial buffer size. */ +#define DEF_BUF_SIZE (16*1024) + static PyModuleDef zlibmodule; - + typedef struct { PyTypeObject *Comptype; PyTypeObject *Decomptype; PyObject *ZlibError; } _zlibstate; - + static inline _zlibstate* get_zlib_state(PyObject *module) { @@ -49,958 +49,958 @@ get_zlib_state(PyObject *module) #define _zlibstate_global ((_zlibstate *)PyModule_GetState(PyState_FindModule(&zlibmodule))) -typedef struct -{ - PyObject_HEAD - z_stream zst; - PyObject *unused_data; - PyObject *unconsumed_tail; - char eof; - int is_initialised; - PyObject *zdict; - PyThread_type_lock lock; -} compobject; - -static void -zlib_error(z_stream zst, int err, const char *msg) -{ - const char *zmsg = Z_NULL; - /* In case of a version mismatch, zst.msg won't be initialized. - Check for this case first, before looking at zst.msg. */ - if (err == Z_VERSION_ERROR) - zmsg = "library version mismatch"; - if (zmsg == Z_NULL) - zmsg = zst.msg; - if (zmsg == Z_NULL) { - switch (err) { - case Z_BUF_ERROR: - zmsg = "incomplete or truncated stream"; - break; - case Z_STREAM_ERROR: - zmsg = "inconsistent stream state"; - break; - case Z_DATA_ERROR: - zmsg = "invalid input data"; - break; - } - } - if (zmsg == Z_NULL) +typedef struct +{ + PyObject_HEAD + z_stream zst; + PyObject *unused_data; + PyObject *unconsumed_tail; + char eof; + int is_initialised; + PyObject *zdict; + PyThread_type_lock lock; +} compobject; + +static void +zlib_error(z_stream zst, int err, const char *msg) +{ + const char *zmsg = Z_NULL; + /* In case of a version mismatch, zst.msg won't be initialized. + Check for this case first, before looking at zst.msg. */ + if (err == Z_VERSION_ERROR) + zmsg = "library version mismatch"; + if (zmsg == Z_NULL) + zmsg = zst.msg; + if (zmsg == Z_NULL) { + switch (err) { + case Z_BUF_ERROR: + zmsg = "incomplete or truncated stream"; + break; + case Z_STREAM_ERROR: + zmsg = "inconsistent stream state"; + break; + case Z_DATA_ERROR: + zmsg = "invalid input data"; + break; + } + } + if (zmsg == Z_NULL) PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s", err, msg); - else + else PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s: %.200s", err, msg, zmsg); -} - -/*[clinic input] -module zlib -class zlib.Compress "compobject *" "&Comptype" -class zlib.Decompress "compobject *" "&Decomptype" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=093935115c3e3158]*/ - -static compobject * -newcompobject(PyTypeObject *type) -{ - compobject *self; - self = PyObject_New(compobject, type); - if (self == NULL) - return NULL; - self->eof = 0; - self->is_initialised = 0; - self->zdict = NULL; - self->unused_data = PyBytes_FromStringAndSize("", 0); - if (self->unused_data == NULL) { - Py_DECREF(self); - return NULL; - } - self->unconsumed_tail = PyBytes_FromStringAndSize("", 0); - if (self->unconsumed_tail == NULL) { - Py_DECREF(self); - return NULL; - } - self->lock = PyThread_allocate_lock(); - if (self->lock == NULL) { - Py_DECREF(self); - PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return NULL; - } - return self; -} - -static void* -PyZlib_Malloc(voidpf ctx, uInt items, uInt size) -{ - if (size != 0 && items > (size_t)PY_SSIZE_T_MAX / size) - return NULL; - /* PyMem_Malloc() cannot be used: the GIL is not held when - inflate() and deflate() are called */ - return PyMem_RawMalloc((size_t)items * (size_t)size); -} - -static void -PyZlib_Free(voidpf ctx, void *ptr) -{ - PyMem_RawFree(ptr); -} - -static void -arrange_input_buffer(z_stream *zst, Py_ssize_t *remains) -{ - zst->avail_in = (uInt)Py_MIN((size_t)*remains, UINT_MAX); - *remains -= zst->avail_in; -} - -static Py_ssize_t -arrange_output_buffer_with_maximum(z_stream *zst, PyObject **buffer, - Py_ssize_t length, - Py_ssize_t max_length) -{ - Py_ssize_t occupied; - - if (*buffer == NULL) { - if (!(*buffer = PyBytes_FromStringAndSize(NULL, length))) - return -1; - occupied = 0; - } - else { - occupied = zst->next_out - (Byte *)PyBytes_AS_STRING(*buffer); - - if (length == occupied) { - Py_ssize_t new_length; - assert(length <= max_length); - /* can not scale the buffer over max_length */ - if (length == max_length) - return -2; - if (length <= (max_length >> 1)) - new_length = length << 1; - else - new_length = max_length; - if (_PyBytes_Resize(buffer, new_length) < 0) - return -1; - length = new_length; - } - } - - zst->avail_out = (uInt)Py_MIN((size_t)(length - occupied), UINT_MAX); - zst->next_out = (Byte *)PyBytes_AS_STRING(*buffer) + occupied; - - return length; -} - -static Py_ssize_t -arrange_output_buffer(z_stream *zst, PyObject **buffer, Py_ssize_t length) -{ - Py_ssize_t ret; - - ret = arrange_output_buffer_with_maximum(zst, buffer, length, - PY_SSIZE_T_MAX); - if (ret == -2) - PyErr_NoMemory(); - - return ret; -} - -/*[clinic input] -zlib.compress - - data: Py_buffer - Binary data to be compressed. - / - level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION - Compression level, in 0-9 or -1. - -Returns a bytes object containing compressed data. -[clinic start generated code]*/ - -static PyObject * -zlib_compress_impl(PyObject *module, Py_buffer *data, int level) -/*[clinic end generated code: output=d80906d73f6294c8 input=638d54b6315dbed3]*/ -{ - PyObject *RetVal = NULL; - Byte *ibuf; - Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE; - int err, flush; - z_stream zst; - - ibuf = data->buf; - ibuflen = data->len; - - zst.opaque = NULL; - zst.zalloc = PyZlib_Malloc; - zst.zfree = PyZlib_Free; - zst.next_in = ibuf; - err = deflateInit(&zst, level); - - switch (err) { - case Z_OK: - break; - case Z_MEM_ERROR: - PyErr_SetString(PyExc_MemoryError, - "Out of memory while compressing data"); - goto error; - case Z_STREAM_ERROR: +} + +/*[clinic input] +module zlib +class zlib.Compress "compobject *" "&Comptype" +class zlib.Decompress "compobject *" "&Decomptype" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=093935115c3e3158]*/ + +static compobject * +newcompobject(PyTypeObject *type) +{ + compobject *self; + self = PyObject_New(compobject, type); + if (self == NULL) + return NULL; + self->eof = 0; + self->is_initialised = 0; + self->zdict = NULL; + self->unused_data = PyBytes_FromStringAndSize("", 0); + if (self->unused_data == NULL) { + Py_DECREF(self); + return NULL; + } + self->unconsumed_tail = PyBytes_FromStringAndSize("", 0); + if (self->unconsumed_tail == NULL) { + Py_DECREF(self); + return NULL; + } + self->lock = PyThread_allocate_lock(); + if (self->lock == NULL) { + Py_DECREF(self); + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + return NULL; + } + return self; +} + +static void* +PyZlib_Malloc(voidpf ctx, uInt items, uInt size) +{ + if (size != 0 && items > (size_t)PY_SSIZE_T_MAX / size) + return NULL; + /* PyMem_Malloc() cannot be used: the GIL is not held when + inflate() and deflate() are called */ + return PyMem_RawMalloc((size_t)items * (size_t)size); +} + +static void +PyZlib_Free(voidpf ctx, void *ptr) +{ + PyMem_RawFree(ptr); +} + +static void +arrange_input_buffer(z_stream *zst, Py_ssize_t *remains) +{ + zst->avail_in = (uInt)Py_MIN((size_t)*remains, UINT_MAX); + *remains -= zst->avail_in; +} + +static Py_ssize_t +arrange_output_buffer_with_maximum(z_stream *zst, PyObject **buffer, + Py_ssize_t length, + Py_ssize_t max_length) +{ + Py_ssize_t occupied; + + if (*buffer == NULL) { + if (!(*buffer = PyBytes_FromStringAndSize(NULL, length))) + return -1; + occupied = 0; + } + else { + occupied = zst->next_out - (Byte *)PyBytes_AS_STRING(*buffer); + + if (length == occupied) { + Py_ssize_t new_length; + assert(length <= max_length); + /* can not scale the buffer over max_length */ + if (length == max_length) + return -2; + if (length <= (max_length >> 1)) + new_length = length << 1; + else + new_length = max_length; + if (_PyBytes_Resize(buffer, new_length) < 0) + return -1; + length = new_length; + } + } + + zst->avail_out = (uInt)Py_MIN((size_t)(length - occupied), UINT_MAX); + zst->next_out = (Byte *)PyBytes_AS_STRING(*buffer) + occupied; + + return length; +} + +static Py_ssize_t +arrange_output_buffer(z_stream *zst, PyObject **buffer, Py_ssize_t length) +{ + Py_ssize_t ret; + + ret = arrange_output_buffer_with_maximum(zst, buffer, length, + PY_SSIZE_T_MAX); + if (ret == -2) + PyErr_NoMemory(); + + return ret; +} + +/*[clinic input] +zlib.compress + + data: Py_buffer + Binary data to be compressed. + / + level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION + Compression level, in 0-9 or -1. + +Returns a bytes object containing compressed data. +[clinic start generated code]*/ + +static PyObject * +zlib_compress_impl(PyObject *module, Py_buffer *data, int level) +/*[clinic end generated code: output=d80906d73f6294c8 input=638d54b6315dbed3]*/ +{ + PyObject *RetVal = NULL; + Byte *ibuf; + Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE; + int err, flush; + z_stream zst; + + ibuf = data->buf; + ibuflen = data->len; + + zst.opaque = NULL; + zst.zalloc = PyZlib_Malloc; + zst.zfree = PyZlib_Free; + zst.next_in = ibuf; + err = deflateInit(&zst, level); + + switch (err) { + case Z_OK: + break; + case Z_MEM_ERROR: + PyErr_SetString(PyExc_MemoryError, + "Out of memory while compressing data"); + goto error; + case Z_STREAM_ERROR: PyErr_SetString(_zlibstate_global->ZlibError, "Bad compression level"); - goto error; - default: - deflateEnd(&zst); - zlib_error(zst, err, "while compressing data"); - goto error; - } - - do { - arrange_input_buffer(&zst, &ibuflen); - flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; - - do { - obuflen = arrange_output_buffer(&zst, &RetVal, obuflen); - if (obuflen < 0) { - deflateEnd(&zst); - goto error; - } - - Py_BEGIN_ALLOW_THREADS - err = deflate(&zst, flush); - Py_END_ALLOW_THREADS - - if (err == Z_STREAM_ERROR) { - deflateEnd(&zst); - zlib_error(zst, err, "while compressing data"); - goto error; - } - - } while (zst.avail_out == 0); - assert(zst.avail_in == 0); - - } while (flush != Z_FINISH); - assert(err == Z_STREAM_END); - - err = deflateEnd(&zst); - if (err == Z_OK) { - if (_PyBytes_Resize(&RetVal, zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) < 0) - goto error; - return RetVal; - } - else - zlib_error(zst, err, "while finishing compression"); - error: - Py_XDECREF(RetVal); - return NULL; -} - -/*[python input] - -class ssize_t_converter(CConverter): - type = 'Py_ssize_t' - converter = 'ssize_t_converter' - c_ignored_default = "0" - -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=5f34ba1b394cb8e7]*/ - -static int -ssize_t_converter(PyObject *obj, void *ptr) -{ - PyObject *long_obj; - Py_ssize_t val; - + goto error; + default: + deflateEnd(&zst); + zlib_error(zst, err, "while compressing data"); + goto error; + } + + do { + arrange_input_buffer(&zst, &ibuflen); + flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; + + do { + obuflen = arrange_output_buffer(&zst, &RetVal, obuflen); + if (obuflen < 0) { + deflateEnd(&zst); + goto error; + } + + Py_BEGIN_ALLOW_THREADS + err = deflate(&zst, flush); + Py_END_ALLOW_THREADS + + if (err == Z_STREAM_ERROR) { + deflateEnd(&zst); + zlib_error(zst, err, "while compressing data"); + goto error; + } + + } while (zst.avail_out == 0); + assert(zst.avail_in == 0); + + } while (flush != Z_FINISH); + assert(err == Z_STREAM_END); + + err = deflateEnd(&zst); + if (err == Z_OK) { + if (_PyBytes_Resize(&RetVal, zst.next_out - + (Byte *)PyBytes_AS_STRING(RetVal)) < 0) + goto error; + return RetVal; + } + else + zlib_error(zst, err, "while finishing compression"); + error: + Py_XDECREF(RetVal); + return NULL; +} + +/*[python input] + +class ssize_t_converter(CConverter): + type = 'Py_ssize_t' + converter = 'ssize_t_converter' + c_ignored_default = "0" + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=5f34ba1b394cb8e7]*/ + +static int +ssize_t_converter(PyObject *obj, void *ptr) +{ + PyObject *long_obj; + Py_ssize_t val; + /* XXX Should be replaced with PyNumber_AsSsize_t after the end of the deprecation period. */ long_obj = _PyLong_FromNbIndexOrNbInt(obj); - if (long_obj == NULL) { - return 0; - } - val = PyLong_AsSsize_t(long_obj); - Py_DECREF(long_obj); - if (val == -1 && PyErr_Occurred()) { - return 0; - } - *(Py_ssize_t *)ptr = val; - return 1; -} - -/*[clinic input] -zlib.decompress - - data: Py_buffer - Compressed data. - / - wbits: int(c_default="MAX_WBITS") = MAX_WBITS - The window buffer size and container format. - bufsize: ssize_t(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE - The initial output buffer size. - -Returns a bytes object containing the uncompressed data. -[clinic start generated code]*/ - -static PyObject * -zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, - Py_ssize_t bufsize) -/*[clinic end generated code: output=77c7e35111dc8c42 input=21960936208e9a5b]*/ -{ - PyObject *RetVal = NULL; - Byte *ibuf; - Py_ssize_t ibuflen; - int err, flush; - z_stream zst; - - if (bufsize < 0) { - PyErr_SetString(PyExc_ValueError, "bufsize must be non-negative"); - return NULL; - } else if (bufsize == 0) { - bufsize = 1; - } - - ibuf = data->buf; - ibuflen = data->len; - - zst.opaque = NULL; - zst.zalloc = PyZlib_Malloc; - zst.zfree = PyZlib_Free; - zst.avail_in = 0; - zst.next_in = ibuf; - err = inflateInit2(&zst, wbits); - - switch (err) { - case Z_OK: - break; - case Z_MEM_ERROR: - PyErr_SetString(PyExc_MemoryError, - "Out of memory while decompressing data"); - goto error; - default: - inflateEnd(&zst); - zlib_error(zst, err, "while preparing to decompress data"); - goto error; - } - - do { - arrange_input_buffer(&zst, &ibuflen); - flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; - - do { - bufsize = arrange_output_buffer(&zst, &RetVal, bufsize); - if (bufsize < 0) { - inflateEnd(&zst); - goto error; - } - - Py_BEGIN_ALLOW_THREADS - err = inflate(&zst, flush); - Py_END_ALLOW_THREADS - - switch (err) { - case Z_OK: /* fall through */ - case Z_BUF_ERROR: /* fall through */ - case Z_STREAM_END: - break; - case Z_MEM_ERROR: - inflateEnd(&zst); - PyErr_SetString(PyExc_MemoryError, - "Out of memory while decompressing data"); - goto error; - default: - inflateEnd(&zst); - zlib_error(zst, err, "while decompressing data"); - goto error; - } - - } while (zst.avail_out == 0); - - } while (err != Z_STREAM_END && ibuflen != 0); - - - if (err != Z_STREAM_END) { - inflateEnd(&zst); - zlib_error(zst, err, "while decompressing data"); - goto error; - } - - err = inflateEnd(&zst); - if (err != Z_OK) { - zlib_error(zst, err, "while finishing decompression"); - goto error; - } - - if (_PyBytes_Resize(&RetVal, zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) < 0) - goto error; - - return RetVal; - - error: - Py_XDECREF(RetVal); - return NULL; -} - -/*[clinic input] -zlib.compressobj - - level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION - The compression level (an integer in the range 0-9 or -1; default is - currently equivalent to 6). Higher compression levels are slower, - but produce smaller results. - method: int(c_default="DEFLATED") = DEFLATED - The compression algorithm. If given, this must be DEFLATED. - wbits: int(c_default="MAX_WBITS") = MAX_WBITS - +9 to +15: The base-two logarithm of the window size. Include a zlib - container. - -9 to -15: Generate a raw stream. - +25 to +31: Include a gzip container. - memLevel: int(c_default="DEF_MEM_LEVEL") = DEF_MEM_LEVEL - Controls the amount of memory used for internal compression state. - Valid values range from 1 to 9. Higher values result in higher memory - usage, faster compression, and smaller output. - strategy: int(c_default="Z_DEFAULT_STRATEGY") = Z_DEFAULT_STRATEGY - Used to tune the compression algorithm. Possible values are - Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY. - zdict: Py_buffer = None - The predefined compression dictionary - a sequence of bytes - containing subsequences that are likely to occur in the input data. - -Return a compressor object. -[clinic start generated code]*/ - -static PyObject * -zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, - int memLevel, int strategy, Py_buffer *zdict) -/*[clinic end generated code: output=8b5bed9c8fc3814d input=2fa3d026f90ab8d5]*/ -{ - compobject *self = NULL; - int err; - - if (zdict->buf != NULL && (size_t)zdict->len > UINT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "zdict length does not fit in an unsigned int"); - goto error; - } - + if (long_obj == NULL) { + return 0; + } + val = PyLong_AsSsize_t(long_obj); + Py_DECREF(long_obj); + if (val == -1 && PyErr_Occurred()) { + return 0; + } + *(Py_ssize_t *)ptr = val; + return 1; +} + +/*[clinic input] +zlib.decompress + + data: Py_buffer + Compressed data. + / + wbits: int(c_default="MAX_WBITS") = MAX_WBITS + The window buffer size and container format. + bufsize: ssize_t(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE + The initial output buffer size. + +Returns a bytes object containing the uncompressed data. +[clinic start generated code]*/ + +static PyObject * +zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, + Py_ssize_t bufsize) +/*[clinic end generated code: output=77c7e35111dc8c42 input=21960936208e9a5b]*/ +{ + PyObject *RetVal = NULL; + Byte *ibuf; + Py_ssize_t ibuflen; + int err, flush; + z_stream zst; + + if (bufsize < 0) { + PyErr_SetString(PyExc_ValueError, "bufsize must be non-negative"); + return NULL; + } else if (bufsize == 0) { + bufsize = 1; + } + + ibuf = data->buf; + ibuflen = data->len; + + zst.opaque = NULL; + zst.zalloc = PyZlib_Malloc; + zst.zfree = PyZlib_Free; + zst.avail_in = 0; + zst.next_in = ibuf; + err = inflateInit2(&zst, wbits); + + switch (err) { + case Z_OK: + break; + case Z_MEM_ERROR: + PyErr_SetString(PyExc_MemoryError, + "Out of memory while decompressing data"); + goto error; + default: + inflateEnd(&zst); + zlib_error(zst, err, "while preparing to decompress data"); + goto error; + } + + do { + arrange_input_buffer(&zst, &ibuflen); + flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; + + do { + bufsize = arrange_output_buffer(&zst, &RetVal, bufsize); + if (bufsize < 0) { + inflateEnd(&zst); + goto error; + } + + Py_BEGIN_ALLOW_THREADS + err = inflate(&zst, flush); + Py_END_ALLOW_THREADS + + switch (err) { + case Z_OK: /* fall through */ + case Z_BUF_ERROR: /* fall through */ + case Z_STREAM_END: + break; + case Z_MEM_ERROR: + inflateEnd(&zst); + PyErr_SetString(PyExc_MemoryError, + "Out of memory while decompressing data"); + goto error; + default: + inflateEnd(&zst); + zlib_error(zst, err, "while decompressing data"); + goto error; + } + + } while (zst.avail_out == 0); + + } while (err != Z_STREAM_END && ibuflen != 0); + + + if (err != Z_STREAM_END) { + inflateEnd(&zst); + zlib_error(zst, err, "while decompressing data"); + goto error; + } + + err = inflateEnd(&zst); + if (err != Z_OK) { + zlib_error(zst, err, "while finishing decompression"); + goto error; + } + + if (_PyBytes_Resize(&RetVal, zst.next_out - + (Byte *)PyBytes_AS_STRING(RetVal)) < 0) + goto error; + + return RetVal; + + error: + Py_XDECREF(RetVal); + return NULL; +} + +/*[clinic input] +zlib.compressobj + + level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION + The compression level (an integer in the range 0-9 or -1; default is + currently equivalent to 6). Higher compression levels are slower, + but produce smaller results. + method: int(c_default="DEFLATED") = DEFLATED + The compression algorithm. If given, this must be DEFLATED. + wbits: int(c_default="MAX_WBITS") = MAX_WBITS + +9 to +15: The base-two logarithm of the window size. Include a zlib + container. + -9 to -15: Generate a raw stream. + +25 to +31: Include a gzip container. + memLevel: int(c_default="DEF_MEM_LEVEL") = DEF_MEM_LEVEL + Controls the amount of memory used for internal compression state. + Valid values range from 1 to 9. Higher values result in higher memory + usage, faster compression, and smaller output. + strategy: int(c_default="Z_DEFAULT_STRATEGY") = Z_DEFAULT_STRATEGY + Used to tune the compression algorithm. Possible values are + Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY. + zdict: Py_buffer = None + The predefined compression dictionary - a sequence of bytes + containing subsequences that are likely to occur in the input data. + +Return a compressor object. +[clinic start generated code]*/ + +static PyObject * +zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, + int memLevel, int strategy, Py_buffer *zdict) +/*[clinic end generated code: output=8b5bed9c8fc3814d input=2fa3d026f90ab8d5]*/ +{ + compobject *self = NULL; + int err; + + if (zdict->buf != NULL && (size_t)zdict->len > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "zdict length does not fit in an unsigned int"); + goto error; + } + self = newcompobject(_zlibstate_global->Comptype); - if (self == NULL) - goto error; - self->zst.opaque = NULL; - self->zst.zalloc = PyZlib_Malloc; - self->zst.zfree = PyZlib_Free; - self->zst.next_in = NULL; - self->zst.avail_in = 0; - err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); - switch (err) { - case Z_OK: - self->is_initialised = 1; - if (zdict->buf == NULL) { - goto success; - } else { - err = deflateSetDictionary(&self->zst, - zdict->buf, (unsigned int)zdict->len); - switch (err) { - case Z_OK: - goto success; - case Z_STREAM_ERROR: - PyErr_SetString(PyExc_ValueError, "Invalid dictionary"); - goto error; - default: - PyErr_SetString(PyExc_ValueError, "deflateSetDictionary()"); - goto error; - } - } - case Z_MEM_ERROR: - PyErr_SetString(PyExc_MemoryError, - "Can't allocate memory for compression object"); - goto error; - case Z_STREAM_ERROR: - PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); - goto error; - default: - zlib_error(self->zst, err, "while creating compression object"); - goto error; - } - - error: - Py_CLEAR(self); - success: - return (PyObject *)self; -} - -static int -set_inflate_zdict(compobject *self) -{ - Py_buffer zdict_buf; - int err; - - if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) { - return -1; - } - if ((size_t)zdict_buf.len > UINT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "zdict length does not fit in an unsigned int"); - PyBuffer_Release(&zdict_buf); - return -1; - } - err = inflateSetDictionary(&self->zst, - zdict_buf.buf, (unsigned int)zdict_buf.len); - PyBuffer_Release(&zdict_buf); - if (err != Z_OK) { - zlib_error(self->zst, err, "while setting zdict"); - return -1; - } - return 0; -} - -/*[clinic input] -zlib.decompressobj - - wbits: int(c_default="MAX_WBITS") = MAX_WBITS - The window buffer size and container format. - zdict: object(c_default="NULL") = b'' - The predefined compression dictionary. This must be the same - dictionary as used by the compressor that produced the input data. - -Return a decompressor object. -[clinic start generated code]*/ - -static PyObject * -zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) -/*[clinic end generated code: output=3069b99994f36906 input=d3832b8511fc977b]*/ -{ - int err; - compobject *self; - - if (zdict != NULL && !PyObject_CheckBuffer(zdict)) { - PyErr_SetString(PyExc_TypeError, - "zdict argument must support the buffer protocol"); - return NULL; - } - + if (self == NULL) + goto error; + self->zst.opaque = NULL; + self->zst.zalloc = PyZlib_Malloc; + self->zst.zfree = PyZlib_Free; + self->zst.next_in = NULL; + self->zst.avail_in = 0; + err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); + switch (err) { + case Z_OK: + self->is_initialised = 1; + if (zdict->buf == NULL) { + goto success; + } else { + err = deflateSetDictionary(&self->zst, + zdict->buf, (unsigned int)zdict->len); + switch (err) { + case Z_OK: + goto success; + case Z_STREAM_ERROR: + PyErr_SetString(PyExc_ValueError, "Invalid dictionary"); + goto error; + default: + PyErr_SetString(PyExc_ValueError, "deflateSetDictionary()"); + goto error; + } + } + case Z_MEM_ERROR: + PyErr_SetString(PyExc_MemoryError, + "Can't allocate memory for compression object"); + goto error; + case Z_STREAM_ERROR: + PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); + goto error; + default: + zlib_error(self->zst, err, "while creating compression object"); + goto error; + } + + error: + Py_CLEAR(self); + success: + return (PyObject *)self; +} + +static int +set_inflate_zdict(compobject *self) +{ + Py_buffer zdict_buf; + int err; + + if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) { + return -1; + } + if ((size_t)zdict_buf.len > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "zdict length does not fit in an unsigned int"); + PyBuffer_Release(&zdict_buf); + return -1; + } + err = inflateSetDictionary(&self->zst, + zdict_buf.buf, (unsigned int)zdict_buf.len); + PyBuffer_Release(&zdict_buf); + if (err != Z_OK) { + zlib_error(self->zst, err, "while setting zdict"); + return -1; + } + return 0; +} + +/*[clinic input] +zlib.decompressobj + + wbits: int(c_default="MAX_WBITS") = MAX_WBITS + The window buffer size and container format. + zdict: object(c_default="NULL") = b'' + The predefined compression dictionary. This must be the same + dictionary as used by the compressor that produced the input data. + +Return a decompressor object. +[clinic start generated code]*/ + +static PyObject * +zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) +/*[clinic end generated code: output=3069b99994f36906 input=d3832b8511fc977b]*/ +{ + int err; + compobject *self; + + if (zdict != NULL && !PyObject_CheckBuffer(zdict)) { + PyErr_SetString(PyExc_TypeError, + "zdict argument must support the buffer protocol"); + return NULL; + } + self = newcompobject(_zlibstate_global->Decomptype); - if (self == NULL) - return NULL; - self->zst.opaque = NULL; - self->zst.zalloc = PyZlib_Malloc; - self->zst.zfree = PyZlib_Free; - self->zst.next_in = NULL; - self->zst.avail_in = 0; - if (zdict != NULL) { - Py_INCREF(zdict); - self->zdict = zdict; - } - err = inflateInit2(&self->zst, wbits); - switch (err) { - case Z_OK: - self->is_initialised = 1; - if (self->zdict != NULL && wbits < 0) { -#ifdef AT_LEAST_ZLIB_1_2_2_1 - if (set_inflate_zdict(self) < 0) { - Py_DECREF(self); - return NULL; - } -#else + if (self == NULL) + return NULL; + self->zst.opaque = NULL; + self->zst.zalloc = PyZlib_Malloc; + self->zst.zfree = PyZlib_Free; + self->zst.next_in = NULL; + self->zst.avail_in = 0; + if (zdict != NULL) { + Py_INCREF(zdict); + self->zdict = zdict; + } + err = inflateInit2(&self->zst, wbits); + switch (err) { + case Z_OK: + self->is_initialised = 1; + if (self->zdict != NULL && wbits < 0) { +#ifdef AT_LEAST_ZLIB_1_2_2_1 + if (set_inflate_zdict(self) < 0) { + Py_DECREF(self); + return NULL; + } +#else PyErr_Format(_zlibstate_global->ZlibError, - "zlib version %s does not allow raw inflate with dictionary", - ZLIB_VERSION); - Py_DECREF(self); - return NULL; -#endif - } - return (PyObject *)self; - case Z_STREAM_ERROR: - Py_DECREF(self); - PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); - return NULL; - case Z_MEM_ERROR: - Py_DECREF(self); - PyErr_SetString(PyExc_MemoryError, - "Can't allocate memory for decompression object"); - return NULL; - default: - zlib_error(self->zst, err, "while creating decompression object"); - Py_DECREF(self); - return NULL; - } -} - -static void -Dealloc(compobject *self) -{ + "zlib version %s does not allow raw inflate with dictionary", + ZLIB_VERSION); + Py_DECREF(self); + return NULL; +#endif + } + return (PyObject *)self; + case Z_STREAM_ERROR: + Py_DECREF(self); + PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); + return NULL; + case Z_MEM_ERROR: + Py_DECREF(self); + PyErr_SetString(PyExc_MemoryError, + "Can't allocate memory for decompression object"); + return NULL; + default: + zlib_error(self->zst, err, "while creating decompression object"); + Py_DECREF(self); + return NULL; + } +} + +static void +Dealloc(compobject *self) +{ PyObject *type = (PyObject *)Py_TYPE(self); - PyThread_free_lock(self->lock); - Py_XDECREF(self->unused_data); - Py_XDECREF(self->unconsumed_tail); - Py_XDECREF(self->zdict); - PyObject_Del(self); + PyThread_free_lock(self->lock); + Py_XDECREF(self->unused_data); + Py_XDECREF(self->unconsumed_tail); + Py_XDECREF(self->zdict); + PyObject_Del(self); Py_DECREF(type); -} - -static void -Comp_dealloc(compobject *self) -{ - if (self->is_initialised) - deflateEnd(&self->zst); - Dealloc(self); -} - -static void -Decomp_dealloc(compobject *self) -{ - if (self->is_initialised) - inflateEnd(&self->zst); - Dealloc(self); -} - -/*[clinic input] -zlib.Compress.compress - - data: Py_buffer - Binary data to be compressed. - / - -Returns a bytes object containing compressed data. - -After calling this function, some of the input data may still -be stored in internal buffers for later processing. -Call the flush() method to clear these buffers. -[clinic start generated code]*/ - -static PyObject * -zlib_Compress_compress_impl(compobject *self, Py_buffer *data) -/*[clinic end generated code: output=5d5cd791cbc6a7f4 input=0d95908d6e64fab8]*/ -{ - PyObject *RetVal = NULL; - Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE; - int err; - - ENTER_ZLIB(self); - - self->zst.next_in = data->buf; - ibuflen = data->len; - - do { - arrange_input_buffer(&self->zst, &ibuflen); - - do { - obuflen = arrange_output_buffer(&self->zst, &RetVal, obuflen); - if (obuflen < 0) - goto error; - - Py_BEGIN_ALLOW_THREADS - err = deflate(&self->zst, Z_NO_FLUSH); - Py_END_ALLOW_THREADS - - if (err == Z_STREAM_ERROR) { - zlib_error(self->zst, err, "while compressing data"); - goto error; - } - - } while (self->zst.avail_out == 0); - assert(self->zst.avail_in == 0); - - } while (ibuflen != 0); - - if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) == 0) - goto success; - - error: - Py_CLEAR(RetVal); - success: - LEAVE_ZLIB(self); - return RetVal; -} - -/* Helper for objdecompress() and flush(). Saves any unconsumed input data in - self->unused_data or self->unconsumed_tail, as appropriate. */ -static int -save_unconsumed_input(compobject *self, Py_buffer *data, int err) -{ - if (err == Z_STREAM_END) { - /* The end of the compressed data has been reached. Store the leftover - input data in self->unused_data. */ - if (self->zst.avail_in > 0) { - Py_ssize_t old_size = PyBytes_GET_SIZE(self->unused_data); - Py_ssize_t new_size, left_size; - PyObject *new_data; - left_size = (Byte *)data->buf + data->len - self->zst.next_in; - if (left_size > (PY_SSIZE_T_MAX - old_size)) { - PyErr_NoMemory(); - return -1; - } - new_size = old_size + left_size; - new_data = PyBytes_FromStringAndSize(NULL, new_size); - if (new_data == NULL) - return -1; - memcpy(PyBytes_AS_STRING(new_data), - PyBytes_AS_STRING(self->unused_data), old_size); - memcpy(PyBytes_AS_STRING(new_data) + old_size, - self->zst.next_in, left_size); - Py_SETREF(self->unused_data, new_data); - self->zst.avail_in = 0; - } - } - - if (self->zst.avail_in > 0 || PyBytes_GET_SIZE(self->unconsumed_tail)) { - /* This code handles two distinct cases: - 1. Output limit was reached. Save leftover input in unconsumed_tail. - 2. All input data was consumed. Clear unconsumed_tail. */ - Py_ssize_t left_size = (Byte *)data->buf + data->len - self->zst.next_in; - PyObject *new_data = PyBytes_FromStringAndSize( - (char *)self->zst.next_in, left_size); - if (new_data == NULL) - return -1; - Py_SETREF(self->unconsumed_tail, new_data); - } - - return 0; -} - -/*[clinic input] -zlib.Decompress.decompress - - data: Py_buffer - The binary data to decompress. - / - max_length: ssize_t = 0 - The maximum allowable length of the decompressed data. - Unconsumed input data will be stored in - the unconsumed_tail attribute. - -Return a bytes object containing the decompressed version of the data. - -After calling this function, some of the input data may still be stored in -internal buffers for later processing. -Call the flush() method to clear these buffers. -[clinic start generated code]*/ - -static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, - Py_ssize_t max_length) -/*[clinic end generated code: output=6e5173c74e710352 input=b85a212a012b770a]*/ -{ - int err = Z_OK; - Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE, hard_limit; - PyObject *RetVal = NULL; - - if (max_length < 0) { - PyErr_SetString(PyExc_ValueError, "max_length must be non-negative"); - return NULL; - } else if (max_length == 0) - hard_limit = PY_SSIZE_T_MAX; - else - hard_limit = max_length; - +} + +static void +Comp_dealloc(compobject *self) +{ + if (self->is_initialised) + deflateEnd(&self->zst); + Dealloc(self); +} + +static void +Decomp_dealloc(compobject *self) +{ + if (self->is_initialised) + inflateEnd(&self->zst); + Dealloc(self); +} + +/*[clinic input] +zlib.Compress.compress + + data: Py_buffer + Binary data to be compressed. + / + +Returns a bytes object containing compressed data. + +After calling this function, some of the input data may still +be stored in internal buffers for later processing. +Call the flush() method to clear these buffers. +[clinic start generated code]*/ + +static PyObject * +zlib_Compress_compress_impl(compobject *self, Py_buffer *data) +/*[clinic end generated code: output=5d5cd791cbc6a7f4 input=0d95908d6e64fab8]*/ +{ + PyObject *RetVal = NULL; + Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE; + int err; + ENTER_ZLIB(self); - self->zst.next_in = data->buf; - ibuflen = data->len; - - /* limit amount of data allocated to max_length */ - if (max_length && obuflen > max_length) - obuflen = max_length; - - do { - arrange_input_buffer(&self->zst, &ibuflen); - - do { - obuflen = arrange_output_buffer_with_maximum(&self->zst, &RetVal, - obuflen, hard_limit); - if (obuflen == -2) { - if (max_length > 0) { - goto save; - } - PyErr_NoMemory(); - } - if (obuflen < 0) { - goto abort; - } - - Py_BEGIN_ALLOW_THREADS - err = inflate(&self->zst, Z_SYNC_FLUSH); - Py_END_ALLOW_THREADS - - switch (err) { - case Z_OK: /* fall through */ - case Z_BUF_ERROR: /* fall through */ - case Z_STREAM_END: - break; - default: - if (err == Z_NEED_DICT && self->zdict != NULL) { - if (set_inflate_zdict(self) < 0) - goto abort; - else - break; - } - goto save; - } - - } while (self->zst.avail_out == 0 || err == Z_NEED_DICT); - - } while (err != Z_STREAM_END && ibuflen != 0); - - save: - if (save_unconsumed_input(self, data, err) < 0) - goto abort; - - if (err == Z_STREAM_END) { - /* This is the logical place to call inflateEnd, but the old behaviour - of only calling it on flush() is preserved. */ - self->eof = 1; - } else if (err != Z_OK && err != Z_BUF_ERROR) { - /* We will only get Z_BUF_ERROR if the output buffer was full - but there wasn't more output when we tried again, so it is - not an error condition. - */ - zlib_error(self->zst, err, "while decompressing data"); - goto abort; - } - - if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) == 0) - goto success; - - abort: - Py_CLEAR(RetVal); - success: - LEAVE_ZLIB(self); - return RetVal; -} - -/*[clinic input] -zlib.Compress.flush - - mode: int(c_default="Z_FINISH") = zlib.Z_FINISH - One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH. - If mode == Z_FINISH, the compressor object can no longer be - used after calling the flush() method. Otherwise, more data - can still be compressed. - / - -Return a bytes object containing any remaining compressed data. -[clinic start generated code]*/ - -static PyObject * -zlib_Compress_flush_impl(compobject *self, int mode) -/*[clinic end generated code: output=a203f4cefc9de727 input=73ed066794bd15bc]*/ -{ - int err; - Py_ssize_t length = DEF_BUF_SIZE; - PyObject *RetVal = NULL; - - /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in - doing any work at all; just return an empty string. */ - if (mode == Z_NO_FLUSH) { - return PyBytes_FromStringAndSize(NULL, 0); - } - + self->zst.next_in = data->buf; + ibuflen = data->len; + + do { + arrange_input_buffer(&self->zst, &ibuflen); + + do { + obuflen = arrange_output_buffer(&self->zst, &RetVal, obuflen); + if (obuflen < 0) + goto error; + + Py_BEGIN_ALLOW_THREADS + err = deflate(&self->zst, Z_NO_FLUSH); + Py_END_ALLOW_THREADS + + if (err == Z_STREAM_ERROR) { + zlib_error(self->zst, err, "while compressing data"); + goto error; + } + + } while (self->zst.avail_out == 0); + assert(self->zst.avail_in == 0); + + } while (ibuflen != 0); + + if (_PyBytes_Resize(&RetVal, self->zst.next_out - + (Byte *)PyBytes_AS_STRING(RetVal)) == 0) + goto success; + + error: + Py_CLEAR(RetVal); + success: + LEAVE_ZLIB(self); + return RetVal; +} + +/* Helper for objdecompress() and flush(). Saves any unconsumed input data in + self->unused_data or self->unconsumed_tail, as appropriate. */ +static int +save_unconsumed_input(compobject *self, Py_buffer *data, int err) +{ + if (err == Z_STREAM_END) { + /* The end of the compressed data has been reached. Store the leftover + input data in self->unused_data. */ + if (self->zst.avail_in > 0) { + Py_ssize_t old_size = PyBytes_GET_SIZE(self->unused_data); + Py_ssize_t new_size, left_size; + PyObject *new_data; + left_size = (Byte *)data->buf + data->len - self->zst.next_in; + if (left_size > (PY_SSIZE_T_MAX - old_size)) { + PyErr_NoMemory(); + return -1; + } + new_size = old_size + left_size; + new_data = PyBytes_FromStringAndSize(NULL, new_size); + if (new_data == NULL) + return -1; + memcpy(PyBytes_AS_STRING(new_data), + PyBytes_AS_STRING(self->unused_data), old_size); + memcpy(PyBytes_AS_STRING(new_data) + old_size, + self->zst.next_in, left_size); + Py_SETREF(self->unused_data, new_data); + self->zst.avail_in = 0; + } + } + + if (self->zst.avail_in > 0 || PyBytes_GET_SIZE(self->unconsumed_tail)) { + /* This code handles two distinct cases: + 1. Output limit was reached. Save leftover input in unconsumed_tail. + 2. All input data was consumed. Clear unconsumed_tail. */ + Py_ssize_t left_size = (Byte *)data->buf + data->len - self->zst.next_in; + PyObject *new_data = PyBytes_FromStringAndSize( + (char *)self->zst.next_in, left_size); + if (new_data == NULL) + return -1; + Py_SETREF(self->unconsumed_tail, new_data); + } + + return 0; +} + +/*[clinic input] +zlib.Decompress.decompress + + data: Py_buffer + The binary data to decompress. + / + max_length: ssize_t = 0 + The maximum allowable length of the decompressed data. + Unconsumed input data will be stored in + the unconsumed_tail attribute. + +Return a bytes object containing the decompressed version of the data. + +After calling this function, some of the input data may still be stored in +internal buffers for later processing. +Call the flush() method to clear these buffers. +[clinic start generated code]*/ + +static PyObject * +zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, + Py_ssize_t max_length) +/*[clinic end generated code: output=6e5173c74e710352 input=b85a212a012b770a]*/ +{ + int err = Z_OK; + Py_ssize_t ibuflen, obuflen = DEF_BUF_SIZE, hard_limit; + PyObject *RetVal = NULL; + + if (max_length < 0) { + PyErr_SetString(PyExc_ValueError, "max_length must be non-negative"); + return NULL; + } else if (max_length == 0) + hard_limit = PY_SSIZE_T_MAX; + else + hard_limit = max_length; + ENTER_ZLIB(self); - self->zst.avail_in = 0; - - do { - length = arrange_output_buffer(&self->zst, &RetVal, length); - if (length < 0) { - Py_CLEAR(RetVal); - goto error; - } - - Py_BEGIN_ALLOW_THREADS - err = deflate(&self->zst, mode); - Py_END_ALLOW_THREADS - - if (err == Z_STREAM_ERROR) { - zlib_error(self->zst, err, "while flushing"); - Py_CLEAR(RetVal); - goto error; - } - } while (self->zst.avail_out == 0); - assert(self->zst.avail_in == 0); - - /* If mode is Z_FINISH, we also have to call deflateEnd() to free - various data structures. Note we should only get Z_STREAM_END when - mode is Z_FINISH, but checking both for safety*/ - if (err == Z_STREAM_END && mode == Z_FINISH) { - err = deflateEnd(&self->zst); - if (err != Z_OK) { - zlib_error(self->zst, err, "while finishing compression"); - Py_CLEAR(RetVal); - goto error; - } - else - self->is_initialised = 0; - - /* We will only get Z_BUF_ERROR if the output buffer was full - but there wasn't more output when we tried again, so it is - not an error condition. - */ - } else if (err != Z_OK && err != Z_BUF_ERROR) { - zlib_error(self->zst, err, "while flushing"); - Py_CLEAR(RetVal); - goto error; - } - - if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) < 0) - Py_CLEAR(RetVal); - - error: - LEAVE_ZLIB(self); - return RetVal; -} - -#ifdef HAVE_ZLIB_COPY - -/*[clinic input] -zlib.Compress.copy - -Return a copy of the compression object. -[clinic start generated code]*/ - -static PyObject * -zlib_Compress_copy_impl(compobject *self) -/*[clinic end generated code: output=5144aa153c21e805 input=c656351f94b82718]*/ -{ - compobject *retval = NULL; - int err; - + self->zst.next_in = data->buf; + ibuflen = data->len; + + /* limit amount of data allocated to max_length */ + if (max_length && obuflen > max_length) + obuflen = max_length; + + do { + arrange_input_buffer(&self->zst, &ibuflen); + + do { + obuflen = arrange_output_buffer_with_maximum(&self->zst, &RetVal, + obuflen, hard_limit); + if (obuflen == -2) { + if (max_length > 0) { + goto save; + } + PyErr_NoMemory(); + } + if (obuflen < 0) { + goto abort; + } + + Py_BEGIN_ALLOW_THREADS + err = inflate(&self->zst, Z_SYNC_FLUSH); + Py_END_ALLOW_THREADS + + switch (err) { + case Z_OK: /* fall through */ + case Z_BUF_ERROR: /* fall through */ + case Z_STREAM_END: + break; + default: + if (err == Z_NEED_DICT && self->zdict != NULL) { + if (set_inflate_zdict(self) < 0) + goto abort; + else + break; + } + goto save; + } + + } while (self->zst.avail_out == 0 || err == Z_NEED_DICT); + + } while (err != Z_STREAM_END && ibuflen != 0); + + save: + if (save_unconsumed_input(self, data, err) < 0) + goto abort; + + if (err == Z_STREAM_END) { + /* This is the logical place to call inflateEnd, but the old behaviour + of only calling it on flush() is preserved. */ + self->eof = 1; + } else if (err != Z_OK && err != Z_BUF_ERROR) { + /* We will only get Z_BUF_ERROR if the output buffer was full + but there wasn't more output when we tried again, so it is + not an error condition. + */ + zlib_error(self->zst, err, "while decompressing data"); + goto abort; + } + + if (_PyBytes_Resize(&RetVal, self->zst.next_out - + (Byte *)PyBytes_AS_STRING(RetVal)) == 0) + goto success; + + abort: + Py_CLEAR(RetVal); + success: + LEAVE_ZLIB(self); + return RetVal; +} + +/*[clinic input] +zlib.Compress.flush + + mode: int(c_default="Z_FINISH") = zlib.Z_FINISH + One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH. + If mode == Z_FINISH, the compressor object can no longer be + used after calling the flush() method. Otherwise, more data + can still be compressed. + / + +Return a bytes object containing any remaining compressed data. +[clinic start generated code]*/ + +static PyObject * +zlib_Compress_flush_impl(compobject *self, int mode) +/*[clinic end generated code: output=a203f4cefc9de727 input=73ed066794bd15bc]*/ +{ + int err; + Py_ssize_t length = DEF_BUF_SIZE; + PyObject *RetVal = NULL; + + /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in + doing any work at all; just return an empty string. */ + if (mode == Z_NO_FLUSH) { + return PyBytes_FromStringAndSize(NULL, 0); + } + + ENTER_ZLIB(self); + + self->zst.avail_in = 0; + + do { + length = arrange_output_buffer(&self->zst, &RetVal, length); + if (length < 0) { + Py_CLEAR(RetVal); + goto error; + } + + Py_BEGIN_ALLOW_THREADS + err = deflate(&self->zst, mode); + Py_END_ALLOW_THREADS + + if (err == Z_STREAM_ERROR) { + zlib_error(self->zst, err, "while flushing"); + Py_CLEAR(RetVal); + goto error; + } + } while (self->zst.avail_out == 0); + assert(self->zst.avail_in == 0); + + /* If mode is Z_FINISH, we also have to call deflateEnd() to free + various data structures. Note we should only get Z_STREAM_END when + mode is Z_FINISH, but checking both for safety*/ + if (err == Z_STREAM_END && mode == Z_FINISH) { + err = deflateEnd(&self->zst); + if (err != Z_OK) { + zlib_error(self->zst, err, "while finishing compression"); + Py_CLEAR(RetVal); + goto error; + } + else + self->is_initialised = 0; + + /* We will only get Z_BUF_ERROR if the output buffer was full + but there wasn't more output when we tried again, so it is + not an error condition. + */ + } else if (err != Z_OK && err != Z_BUF_ERROR) { + zlib_error(self->zst, err, "while flushing"); + Py_CLEAR(RetVal); + goto error; + } + + if (_PyBytes_Resize(&RetVal, self->zst.next_out - + (Byte *)PyBytes_AS_STRING(RetVal)) < 0) + Py_CLEAR(RetVal); + + error: + LEAVE_ZLIB(self); + return RetVal; +} + +#ifdef HAVE_ZLIB_COPY + +/*[clinic input] +zlib.Compress.copy + +Return a copy of the compression object. +[clinic start generated code]*/ + +static PyObject * +zlib_Compress_copy_impl(compobject *self) +/*[clinic end generated code: output=5144aa153c21e805 input=c656351f94b82718]*/ +{ + compobject *retval = NULL; + int err; + retval = newcompobject(_zlibstate_global->Comptype); - if (!retval) return NULL; - - /* Copy the zstream state - * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe - */ - ENTER_ZLIB(self); - err = deflateCopy(&retval->zst, &self->zst); - switch (err) { - case Z_OK: - break; - case Z_STREAM_ERROR: - PyErr_SetString(PyExc_ValueError, "Inconsistent stream state"); - goto error; - case Z_MEM_ERROR: - PyErr_SetString(PyExc_MemoryError, - "Can't allocate memory for compression object"); - goto error; - default: - zlib_error(self->zst, err, "while copying compression object"); - goto error; - } - Py_INCREF(self->unused_data); - Py_XSETREF(retval->unused_data, self->unused_data); - Py_INCREF(self->unconsumed_tail); - Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); - Py_XINCREF(self->zdict); - Py_XSETREF(retval->zdict, self->zdict); - retval->eof = self->eof; - - /* Mark it as being initialized */ - retval->is_initialised = 1; - - LEAVE_ZLIB(self); - return (PyObject *)retval; - -error: - LEAVE_ZLIB(self); - Py_XDECREF(retval); - return NULL; -} - -/*[clinic input] + if (!retval) return NULL; + + /* Copy the zstream state + * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe + */ + ENTER_ZLIB(self); + err = deflateCopy(&retval->zst, &self->zst); + switch (err) { + case Z_OK: + break; + case Z_STREAM_ERROR: + PyErr_SetString(PyExc_ValueError, "Inconsistent stream state"); + goto error; + case Z_MEM_ERROR: + PyErr_SetString(PyExc_MemoryError, + "Can't allocate memory for compression object"); + goto error; + default: + zlib_error(self->zst, err, "while copying compression object"); + goto error; + } + Py_INCREF(self->unused_data); + Py_XSETREF(retval->unused_data, self->unused_data); + Py_INCREF(self->unconsumed_tail); + Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); + Py_XINCREF(self->zdict); + Py_XSETREF(retval->zdict, self->zdict); + retval->eof = self->eof; + + /* Mark it as being initialized */ + retval->is_initialised = 1; + + LEAVE_ZLIB(self); + return (PyObject *)retval; + +error: + LEAVE_ZLIB(self); + Py_XDECREF(retval); + return NULL; +} + +/*[clinic input] zlib.Compress.__copy__ [clinic start generated code]*/ @@ -1027,60 +1027,60 @@ zlib_Compress___deepcopy__(compobject *self, PyObject *memo) } /*[clinic input] -zlib.Decompress.copy - -Return a copy of the decompression object. -[clinic start generated code]*/ - -static PyObject * -zlib_Decompress_copy_impl(compobject *self) -/*[clinic end generated code: output=02a883a2a510c8cc input=ba6c3e96712a596b]*/ -{ - compobject *retval = NULL; - int err; - +zlib.Decompress.copy + +Return a copy of the decompression object. +[clinic start generated code]*/ + +static PyObject * +zlib_Decompress_copy_impl(compobject *self) +/*[clinic end generated code: output=02a883a2a510c8cc input=ba6c3e96712a596b]*/ +{ + compobject *retval = NULL; + int err; + retval = newcompobject(_zlibstate_global->Decomptype); - if (!retval) return NULL; - - /* Copy the zstream state - * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe - */ - ENTER_ZLIB(self); - err = inflateCopy(&retval->zst, &self->zst); - switch (err) { - case Z_OK: - break; - case Z_STREAM_ERROR: - PyErr_SetString(PyExc_ValueError, "Inconsistent stream state"); - goto error; - case Z_MEM_ERROR: - PyErr_SetString(PyExc_MemoryError, - "Can't allocate memory for decompression object"); - goto error; - default: - zlib_error(self->zst, err, "while copying decompression object"); - goto error; - } - - Py_INCREF(self->unused_data); - Py_XSETREF(retval->unused_data, self->unused_data); - Py_INCREF(self->unconsumed_tail); - Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); - Py_XINCREF(self->zdict); - Py_XSETREF(retval->zdict, self->zdict); - retval->eof = self->eof; - - /* Mark it as being initialized */ - retval->is_initialised = 1; - - LEAVE_ZLIB(self); - return (PyObject *)retval; - -error: - LEAVE_ZLIB(self); - Py_XDECREF(retval); - return NULL; -} + if (!retval) return NULL; + + /* Copy the zstream state + * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe + */ + ENTER_ZLIB(self); + err = inflateCopy(&retval->zst, &self->zst); + switch (err) { + case Z_OK: + break; + case Z_STREAM_ERROR: + PyErr_SetString(PyExc_ValueError, "Inconsistent stream state"); + goto error; + case Z_MEM_ERROR: + PyErr_SetString(PyExc_MemoryError, + "Can't allocate memory for decompression object"); + goto error; + default: + zlib_error(self->zst, err, "while copying decompression object"); + goto error; + } + + Py_INCREF(self->unused_data); + Py_XSETREF(retval->unused_data, self->unused_data); + Py_INCREF(self->unconsumed_tail); + Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); + Py_XINCREF(self->zdict); + Py_XSETREF(retval->zdict, self->zdict); + retval->eof = self->eof; + + /* Mark it as being initialized */ + retval->is_initialised = 1; + + LEAVE_ZLIB(self); + return (PyObject *)retval; + +error: + LEAVE_ZLIB(self); + Py_XDECREF(retval); + return NULL; +} /*[clinic input] zlib.Decompress.__copy__ @@ -1108,223 +1108,223 @@ zlib_Decompress___deepcopy__(compobject *self, PyObject *memo) return zlib_Decompress_copy_impl(self); } -#endif - -/*[clinic input] -zlib.Decompress.flush - - length: ssize_t(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE - the initial size of the output buffer. - / - -Return a bytes object containing any remaining decompressed data. -[clinic start generated code]*/ - -static PyObject * -zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) -/*[clinic end generated code: output=68c75ea127cbe654 input=aa4ec37f3aef4da0]*/ -{ - int err, flush; - Py_buffer data; - PyObject *RetVal = NULL; - Py_ssize_t ibuflen; - - if (length <= 0) { - PyErr_SetString(PyExc_ValueError, "length must be greater than zero"); - return NULL; - } - +#endif + +/*[clinic input] +zlib.Decompress.flush + + length: ssize_t(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE + the initial size of the output buffer. + / + +Return a bytes object containing any remaining decompressed data. +[clinic start generated code]*/ + +static PyObject * +zlib_Decompress_flush_impl(compobject *self, Py_ssize_t length) +/*[clinic end generated code: output=68c75ea127cbe654 input=aa4ec37f3aef4da0]*/ +{ + int err, flush; + Py_buffer data; + PyObject *RetVal = NULL; + Py_ssize_t ibuflen; + + if (length <= 0) { + PyErr_SetString(PyExc_ValueError, "length must be greater than zero"); + return NULL; + } + ENTER_ZLIB(self); if (PyObject_GetBuffer(self->unconsumed_tail, &data, PyBUF_SIMPLE) == -1) { LEAVE_ZLIB(self); - return NULL; - } - - self->zst.next_in = data.buf; - ibuflen = data.len; - - do { - arrange_input_buffer(&self->zst, &ibuflen); - flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; - - do { - length = arrange_output_buffer(&self->zst, &RetVal, length); - if (length < 0) - goto abort; - - Py_BEGIN_ALLOW_THREADS - err = inflate(&self->zst, flush); - Py_END_ALLOW_THREADS - - switch (err) { - case Z_OK: /* fall through */ - case Z_BUF_ERROR: /* fall through */ - case Z_STREAM_END: - break; - default: - if (err == Z_NEED_DICT && self->zdict != NULL) { - if (set_inflate_zdict(self) < 0) - goto abort; - else - break; - } - goto save; - } - - } while (self->zst.avail_out == 0 || err == Z_NEED_DICT); - - } while (err != Z_STREAM_END && ibuflen != 0); - - save: - if (save_unconsumed_input(self, &data, err) < 0) - goto abort; - - /* If at end of stream, clean up any memory allocated by zlib. */ - if (err == Z_STREAM_END) { - self->eof = 1; - self->is_initialised = 0; - err = inflateEnd(&self->zst); - if (err != Z_OK) { - zlib_error(self->zst, err, "while finishing decompression"); - goto abort; - } + return NULL; } - - if (_PyBytes_Resize(&RetVal, self->zst.next_out - - (Byte *)PyBytes_AS_STRING(RetVal)) == 0) - goto success; - - abort: - Py_CLEAR(RetVal); - success: - PyBuffer_Release(&data); - LEAVE_ZLIB(self); - return RetVal; -} - -#include "clinic/zlibmodule.c.h" - -static PyMethodDef comp_methods[] = -{ - ZLIB_COMPRESS_COMPRESS_METHODDEF - ZLIB_COMPRESS_FLUSH_METHODDEF - ZLIB_COMPRESS_COPY_METHODDEF + + self->zst.next_in = data.buf; + ibuflen = data.len; + + do { + arrange_input_buffer(&self->zst, &ibuflen); + flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; + + do { + length = arrange_output_buffer(&self->zst, &RetVal, length); + if (length < 0) + goto abort; + + Py_BEGIN_ALLOW_THREADS + err = inflate(&self->zst, flush); + Py_END_ALLOW_THREADS + + switch (err) { + case Z_OK: /* fall through */ + case Z_BUF_ERROR: /* fall through */ + case Z_STREAM_END: + break; + default: + if (err == Z_NEED_DICT && self->zdict != NULL) { + if (set_inflate_zdict(self) < 0) + goto abort; + else + break; + } + goto save; + } + + } while (self->zst.avail_out == 0 || err == Z_NEED_DICT); + + } while (err != Z_STREAM_END && ibuflen != 0); + + save: + if (save_unconsumed_input(self, &data, err) < 0) + goto abort; + + /* If at end of stream, clean up any memory allocated by zlib. */ + if (err == Z_STREAM_END) { + self->eof = 1; + self->is_initialised = 0; + err = inflateEnd(&self->zst); + if (err != Z_OK) { + zlib_error(self->zst, err, "while finishing decompression"); + goto abort; + } + } + + if (_PyBytes_Resize(&RetVal, self->zst.next_out - + (Byte *)PyBytes_AS_STRING(RetVal)) == 0) + goto success; + + abort: + Py_CLEAR(RetVal); + success: + PyBuffer_Release(&data); + LEAVE_ZLIB(self); + return RetVal; +} + +#include "clinic/zlibmodule.c.h" + +static PyMethodDef comp_methods[] = +{ + ZLIB_COMPRESS_COMPRESS_METHODDEF + ZLIB_COMPRESS_FLUSH_METHODDEF + ZLIB_COMPRESS_COPY_METHODDEF ZLIB_COMPRESS___COPY___METHODDEF ZLIB_COMPRESS___DEEPCOPY___METHODDEF - {NULL, NULL} -}; - -static PyMethodDef Decomp_methods[] = -{ - ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF - ZLIB_DECOMPRESS_FLUSH_METHODDEF - ZLIB_DECOMPRESS_COPY_METHODDEF + {NULL, NULL} +}; + +static PyMethodDef Decomp_methods[] = +{ + ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF + ZLIB_DECOMPRESS_FLUSH_METHODDEF + ZLIB_DECOMPRESS_COPY_METHODDEF ZLIB_DECOMPRESS___COPY___METHODDEF ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF - {NULL, NULL} -}; - -#define COMP_OFF(x) offsetof(compobject, x) -static PyMemberDef Decomp_members[] = { - {"unused_data", T_OBJECT, COMP_OFF(unused_data), READONLY}, - {"unconsumed_tail", T_OBJECT, COMP_OFF(unconsumed_tail), READONLY}, - {"eof", T_BOOL, COMP_OFF(eof), READONLY}, - {NULL}, -}; - -/*[clinic input] -zlib.adler32 - - data: Py_buffer - value: unsigned_int(bitwise=True) = 1 - Starting value of the checksum. - / - -Compute an Adler-32 checksum of data. - -The returned checksum is an integer. -[clinic start generated code]*/ - -static PyObject * -zlib_adler32_impl(PyObject *module, Py_buffer *data, unsigned int value) -/*[clinic end generated code: output=422106f5ca8c92c0 input=6ff4557872160e88]*/ -{ - /* Releasing the GIL for very small buffers is inefficient - and may lower performance */ - if (data->len > 1024*5) { - unsigned char *buf = data->buf; - Py_ssize_t len = data->len; - - Py_BEGIN_ALLOW_THREADS - /* Avoid truncation of length for very large buffers. adler32() takes - length as an unsigned int, which may be narrower than Py_ssize_t. */ - while ((size_t)len > UINT_MAX) { - value = adler32(value, buf, UINT_MAX); - buf += (size_t) UINT_MAX; - len -= (size_t) UINT_MAX; - } - value = adler32(value, buf, (unsigned int)len); - Py_END_ALLOW_THREADS - } else { - value = adler32(value, data->buf, (unsigned int)data->len); - } - return PyLong_FromUnsignedLong(value & 0xffffffffU); -} - -/*[clinic input] -zlib.crc32 - - data: Py_buffer - value: unsigned_int(bitwise=True) = 0 - Starting value of the checksum. - / - -Compute a CRC-32 checksum of data. - -The returned checksum is an integer. -[clinic start generated code]*/ - -static PyObject * -zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) -/*[clinic end generated code: output=63499fa20af7ea25 input=26c3ed430fa00b4c]*/ -{ - int signed_val; - - /* Releasing the GIL for very small buffers is inefficient - and may lower performance */ - if (data->len > 1024*5) { - unsigned char *buf = data->buf; - Py_ssize_t len = data->len; - - Py_BEGIN_ALLOW_THREADS - /* Avoid truncation of length for very large buffers. crc32() takes - length as an unsigned int, which may be narrower than Py_ssize_t. */ - while ((size_t)len > UINT_MAX) { - value = crc32(value, buf, UINT_MAX); - buf += (size_t) UINT_MAX; - len -= (size_t) UINT_MAX; - } - signed_val = crc32(value, buf, (unsigned int)len); - Py_END_ALLOW_THREADS - } else { - signed_val = crc32(value, data->buf, (unsigned int)data->len); - } - return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); -} - - -static PyMethodDef zlib_methods[] = -{ - ZLIB_ADLER32_METHODDEF - ZLIB_COMPRESS_METHODDEF - ZLIB_COMPRESSOBJ_METHODDEF - ZLIB_CRC32_METHODDEF - ZLIB_DECOMPRESS_METHODDEF - ZLIB_DECOMPRESSOBJ_METHODDEF - {NULL, NULL} -}; - + {NULL, NULL} +}; + +#define COMP_OFF(x) offsetof(compobject, x) +static PyMemberDef Decomp_members[] = { + {"unused_data", T_OBJECT, COMP_OFF(unused_data), READONLY}, + {"unconsumed_tail", T_OBJECT, COMP_OFF(unconsumed_tail), READONLY}, + {"eof", T_BOOL, COMP_OFF(eof), READONLY}, + {NULL}, +}; + +/*[clinic input] +zlib.adler32 + + data: Py_buffer + value: unsigned_int(bitwise=True) = 1 + Starting value of the checksum. + / + +Compute an Adler-32 checksum of data. + +The returned checksum is an integer. +[clinic start generated code]*/ + +static PyObject * +zlib_adler32_impl(PyObject *module, Py_buffer *data, unsigned int value) +/*[clinic end generated code: output=422106f5ca8c92c0 input=6ff4557872160e88]*/ +{ + /* Releasing the GIL for very small buffers is inefficient + and may lower performance */ + if (data->len > 1024*5) { + unsigned char *buf = data->buf; + Py_ssize_t len = data->len; + + Py_BEGIN_ALLOW_THREADS + /* Avoid truncation of length for very large buffers. adler32() takes + length as an unsigned int, which may be narrower than Py_ssize_t. */ + while ((size_t)len > UINT_MAX) { + value = adler32(value, buf, UINT_MAX); + buf += (size_t) UINT_MAX; + len -= (size_t) UINT_MAX; + } + value = adler32(value, buf, (unsigned int)len); + Py_END_ALLOW_THREADS + } else { + value = adler32(value, data->buf, (unsigned int)data->len); + } + return PyLong_FromUnsignedLong(value & 0xffffffffU); +} + +/*[clinic input] +zlib.crc32 + + data: Py_buffer + value: unsigned_int(bitwise=True) = 0 + Starting value of the checksum. + / + +Compute a CRC-32 checksum of data. + +The returned checksum is an integer. +[clinic start generated code]*/ + +static PyObject * +zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) +/*[clinic end generated code: output=63499fa20af7ea25 input=26c3ed430fa00b4c]*/ +{ + int signed_val; + + /* Releasing the GIL for very small buffers is inefficient + and may lower performance */ + if (data->len > 1024*5) { + unsigned char *buf = data->buf; + Py_ssize_t len = data->len; + + Py_BEGIN_ALLOW_THREADS + /* Avoid truncation of length for very large buffers. crc32() takes + length as an unsigned int, which may be narrower than Py_ssize_t. */ + while ((size_t)len > UINT_MAX) { + value = crc32(value, buf, UINT_MAX); + buf += (size_t) UINT_MAX; + len -= (size_t) UINT_MAX; + } + signed_val = crc32(value, buf, (unsigned int)len); + Py_END_ALLOW_THREADS + } else { + signed_val = crc32(value, data->buf, (unsigned int)data->len); + } + return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); +} + + +static PyMethodDef zlib_methods[] = +{ + ZLIB_ADLER32_METHODDEF + ZLIB_COMPRESS_METHODDEF + ZLIB_COMPRESSOBJ_METHODDEF + ZLIB_CRC32_METHODDEF + ZLIB_DECOMPRESS_METHODDEF + ZLIB_DECOMPRESSOBJ_METHODDEF + {NULL, NULL} +}; + static PyType_Slot Comptype_slots[] = { {Py_tp_dealloc, Comp_dealloc}, {Py_tp_methods, comp_methods}, @@ -1332,13 +1332,13 @@ static PyType_Slot Comptype_slots[] = { }; static PyType_Spec Comptype_spec = { - "zlib.Compress", - sizeof(compobject), - 0, + "zlib.Compress", + sizeof(compobject), + 0, Py_TPFLAGS_DEFAULT, Comptype_slots -}; - +}; + static PyType_Slot Decomptype_slots[] = { {Py_tp_dealloc, Decomp_dealloc}, {Py_tp_methods, Decomp_methods}, @@ -1347,28 +1347,28 @@ static PyType_Slot Decomptype_slots[] = { }; static PyType_Spec Decomptype_spec = { - "zlib.Decompress", - sizeof(compobject), - 0, + "zlib.Decompress", + sizeof(compobject), + 0, Py_TPFLAGS_DEFAULT, Decomptype_slots -}; - -PyDoc_STRVAR(zlib_module_documentation, -"The functions in this module allow compression and decompression using the\n" -"zlib library, which is based on GNU zip.\n" -"\n" -"adler32(string[, start]) -- Compute an Adler-32 checksum.\n" -"compress(data[, level]) -- Compress data, with compression level 0-9 or -1.\n" -"compressobj([level[, ...]]) -- Return a compressor object.\n" -"crc32(string[, start]) -- Compute a CRC-32 checksum.\n" -"decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n" +}; + +PyDoc_STRVAR(zlib_module_documentation, +"The functions in this module allow compression and decompression using the\n" +"zlib library, which is based on GNU zip.\n" +"\n" +"adler32(string[, start]) -- Compute an Adler-32 checksum.\n" +"compress(data[, level]) -- Compress data, with compression level 0-9 or -1.\n" +"compressobj([level[, ...]]) -- Return a compressor object.\n" +"crc32(string[, start]) -- Compute a CRC-32 checksum.\n" +"decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n" "decompressobj([wbits[, zdict]]) -- Return a decompressor object.\n" -"\n" -"'wbits' is window buffer size and container format.\n" -"Compressor objects support compress() and flush() methods; decompressor\n" -"objects support decompress() and flush()."); - +"\n" +"'wbits' is window buffer size and container format.\n" +"Compressor objects support compress() and flush() methods; decompressor\n" +"objects support decompress() and flush()."); + static int zlib_clear(PyObject *m) { @@ -1395,31 +1395,31 @@ zlib_free(void *m) zlib_clear((PyObject *)m); } -static struct PyModuleDef zlibmodule = { - PyModuleDef_HEAD_INIT, - "zlib", - zlib_module_documentation, +static struct PyModuleDef zlibmodule = { + PyModuleDef_HEAD_INIT, + "zlib", + zlib_module_documentation, sizeof(_zlibstate), - zlib_methods, - NULL, + zlib_methods, + NULL, zlib_traverse, zlib_clear, zlib_free, -}; - -PyMODINIT_FUNC -PyInit_zlib(void) -{ - PyObject *m, *ver; +}; + +PyMODINIT_FUNC +PyInit_zlib(void) +{ + PyObject *m, *ver; m = PyState_FindModule(&zlibmodule); if (m != NULL) { Py_INCREF(m); return m; } - m = PyModule_Create(&zlibmodule); - if (m == NULL) - return NULL; - + m = PyModule_Create(&zlibmodule); + if (m == NULL) + return NULL; + PyTypeObject *Comptype = (PyTypeObject *)PyType_FromSpec(&Comptype_spec); if (Comptype == NULL) return NULL; @@ -1431,52 +1431,52 @@ PyInit_zlib(void) get_zlib_state(m)->Decomptype = Decomptype; PyObject *ZlibError = PyErr_NewException("zlib.error", NULL, NULL); - if (ZlibError != NULL) { - Py_INCREF(ZlibError); - PyModule_AddObject(m, "error", ZlibError); + if (ZlibError != NULL) { + Py_INCREF(ZlibError); + PyModule_AddObject(m, "error", ZlibError); get_zlib_state(m)->ZlibError = ZlibError; - } - PyModule_AddIntMacro(m, MAX_WBITS); - PyModule_AddIntMacro(m, DEFLATED); - PyModule_AddIntMacro(m, DEF_MEM_LEVEL); - PyModule_AddIntMacro(m, DEF_BUF_SIZE); - // compression levels - PyModule_AddIntMacro(m, Z_NO_COMPRESSION); - PyModule_AddIntMacro(m, Z_BEST_SPEED); - PyModule_AddIntMacro(m, Z_BEST_COMPRESSION); - PyModule_AddIntMacro(m, Z_DEFAULT_COMPRESSION); - // compression strategies - PyModule_AddIntMacro(m, Z_FILTERED); - PyModule_AddIntMacro(m, Z_HUFFMAN_ONLY); -#ifdef Z_RLE // 1.2.0.1 - PyModule_AddIntMacro(m, Z_RLE); -#endif -#ifdef Z_FIXED // 1.2.2.2 - PyModule_AddIntMacro(m, Z_FIXED); -#endif - PyModule_AddIntMacro(m, Z_DEFAULT_STRATEGY); - // allowed flush values - PyModule_AddIntMacro(m, Z_NO_FLUSH); - PyModule_AddIntMacro(m, Z_PARTIAL_FLUSH); - PyModule_AddIntMacro(m, Z_SYNC_FLUSH); - PyModule_AddIntMacro(m, Z_FULL_FLUSH); - PyModule_AddIntMacro(m, Z_FINISH); -#ifdef Z_BLOCK // 1.2.0.5 for inflate, 1.2.3.4 for deflate - PyModule_AddIntMacro(m, Z_BLOCK); -#endif -#ifdef Z_TREES // 1.2.3.4, only for inflate - PyModule_AddIntMacro(m, Z_TREES); -#endif - ver = PyUnicode_FromString(ZLIB_VERSION); - if (ver != NULL) - PyModule_AddObject(m, "ZLIB_VERSION", ver); - - ver = PyUnicode_FromString(zlibVersion()); - if (ver != NULL) - PyModule_AddObject(m, "ZLIB_RUNTIME_VERSION", ver); - - PyModule_AddStringConstant(m, "__version__", "1.0"); - + } + PyModule_AddIntMacro(m, MAX_WBITS); + PyModule_AddIntMacro(m, DEFLATED); + PyModule_AddIntMacro(m, DEF_MEM_LEVEL); + PyModule_AddIntMacro(m, DEF_BUF_SIZE); + // compression levels + PyModule_AddIntMacro(m, Z_NO_COMPRESSION); + PyModule_AddIntMacro(m, Z_BEST_SPEED); + PyModule_AddIntMacro(m, Z_BEST_COMPRESSION); + PyModule_AddIntMacro(m, Z_DEFAULT_COMPRESSION); + // compression strategies + PyModule_AddIntMacro(m, Z_FILTERED); + PyModule_AddIntMacro(m, Z_HUFFMAN_ONLY); +#ifdef Z_RLE // 1.2.0.1 + PyModule_AddIntMacro(m, Z_RLE); +#endif +#ifdef Z_FIXED // 1.2.2.2 + PyModule_AddIntMacro(m, Z_FIXED); +#endif + PyModule_AddIntMacro(m, Z_DEFAULT_STRATEGY); + // allowed flush values + PyModule_AddIntMacro(m, Z_NO_FLUSH); + PyModule_AddIntMacro(m, Z_PARTIAL_FLUSH); + PyModule_AddIntMacro(m, Z_SYNC_FLUSH); + PyModule_AddIntMacro(m, Z_FULL_FLUSH); + PyModule_AddIntMacro(m, Z_FINISH); +#ifdef Z_BLOCK // 1.2.0.5 for inflate, 1.2.3.4 for deflate + PyModule_AddIntMacro(m, Z_BLOCK); +#endif +#ifdef Z_TREES // 1.2.3.4, only for inflate + PyModule_AddIntMacro(m, Z_TREES); +#endif + ver = PyUnicode_FromString(ZLIB_VERSION); + if (ver != NULL) + PyModule_AddObject(m, "ZLIB_VERSION", ver); + + ver = PyUnicode_FromString(zlibVersion()); + if (ver != NULL) + PyModule_AddObject(m, "ZLIB_RUNTIME_VERSION", ver); + + PyModule_AddStringConstant(m, "__version__", "1.0"); + PyState_AddModule(m, &zlibmodule); - return m; -} + return m; +} -- cgit v1.3